From 3d0826849e976b344912a7fc04e17577efd45e3c Mon Sep 17 00:00:00 2001 From: sjunges Date: Fri, 12 Feb 2016 18:00:42 +0100 Subject: [PATCH 1/3] glpk 4.57 for the winners Former-commit-id: 568dad7ba4f48564d0b74ffa096430255fad12f4 --- CMakeLists.txt | 8 +- resources/3rdparty/CMakeLists.txt | 13 +- resources/3rdparty/glpk-4.57/AUTHORS | 33 + resources/3rdparty/glpk-4.57/COPYING | 674 + resources/3rdparty/glpk-4.57/ChangeLog | 2932 ++++ resources/3rdparty/glpk-4.57/INSTALL | 209 + resources/3rdparty/glpk-4.57/Makefile.am | 7 + resources/3rdparty/glpk-4.57/Makefile.in | 759 + resources/3rdparty/glpk-4.57/NEWS | 1841 ++ resources/3rdparty/glpk-4.57/README | 39 + resources/3rdparty/glpk-4.57/THANKS | 223 + resources/3rdparty/glpk-4.57/aclocal.m4 | 949 ++ resources/3rdparty/glpk-4.57/config.guess | 1537 ++ resources/3rdparty/glpk-4.57/config.h.in | 27 + resources/3rdparty/glpk-4.57/config.sub | 1789 ++ resources/3rdparty/glpk-4.57/configure | 13840 ++++++++++++++++ resources/3rdparty/glpk-4.57/configure.ac | 148 + resources/3rdparty/glpk-4.57/depcomp | 787 + resources/3rdparty/glpk-4.57/doc/cnfsat.pdf | Bin 0 -> 59926 bytes resources/3rdparty/glpk-4.57/doc/cnfsat.tex | 413 + resources/3rdparty/glpk-4.57/doc/glpk.pdf | Bin 0 -> 478810 bytes resources/3rdparty/glpk-4.57/doc/glpk.tex | 168 + resources/3rdparty/glpk-4.57/doc/glpk01.tex | 343 + resources/3rdparty/glpk-4.57/doc/glpk02.tex | 3470 ++++ resources/3rdparty/glpk-4.57/doc/glpk03.tex | 1572 ++ resources/3rdparty/glpk-4.57/doc/glpk04.tex | 1387 ++ resources/3rdparty/glpk-4.57/doc/glpk05.tex | 1090 ++ resources/3rdparty/glpk-4.57/doc/glpk06.tex | 462 + resources/3rdparty/glpk-4.57/doc/glpk07.tex | 258 + resources/3rdparty/glpk-4.57/doc/glpk08.tex | 738 + resources/3rdparty/glpk-4.57/doc/glpk09.tex | 424 + resources/3rdparty/glpk-4.57/doc/glpk10.tex | 165 + resources/3rdparty/glpk-4.57/doc/glpk11.tex | 203 + resources/3rdparty/glpk-4.57/doc/glpk12.tex | 707 + resources/3rdparty/glpk-4.57/doc/gmpl.pdf | Bin 0 -> 216194 bytes resources/3rdparty/glpk-4.57/doc/gmpl.tex | 4295 +++++ resources/3rdparty/glpk-4.57/doc/gmpl_es.pdf | Bin 0 -> 255373 bytes resources/3rdparty/glpk-4.57/doc/gmpl_es.tex | 3233 ++++ resources/3rdparty/glpk-4.57/doc/graphs.pdf | Bin 0 -> 214470 bytes resources/3rdparty/glpk-4.57/doc/graphs.tex | 4150 +++++ resources/3rdparty/glpk-4.57/doc/miplib2.txt | 135 + resources/3rdparty/glpk-4.57/doc/miplib3.txt | 143 + resources/3rdparty/glpk-4.57/doc/netlib.txt | 103 + .../3rdparty/glpk-4.57/doc/notes/dfeas.pdf | Bin 0 -> 63866 bytes .../3rdparty/glpk-4.57/doc/notes/gomory.pdf | Bin 0 -> 75445 bytes .../3rdparty/glpk-4.57/doc/notes/keller.pdf | Bin 0 -> 85985 bytes .../3rdparty/glpk-4.57/doc/notes/scf.pdf | Bin 0 -> 123131 bytes .../3rdparty/glpk-4.57/doc/notes/simplex1.pdf | Bin 0 -> 398510 bytes .../3rdparty/glpk-4.57/doc/notes/simplex2.pdf | Bin 0 -> 209721 bytes resources/3rdparty/glpk-4.57/examples/INDEX | 58 + .../3rdparty/glpk-4.57/examples/Makefile.am | 15 + .../3rdparty/glpk-4.57/examples/Makefile.in | 558 + .../3rdparty/glpk-4.57/examples/alloy.mps | 282 + .../3rdparty/glpk-4.57/examples/assign.mod | 77 + resources/3rdparty/glpk-4.57/examples/bpp.mod | 83 + resources/3rdparty/glpk-4.57/examples/cal.mod | 49 + .../3rdparty/glpk-4.57/examples/cf12a.mod | 81 + .../3rdparty/glpk-4.57/examples/cf12b.mod | 88 + .../3rdparty/glpk-4.57/examples/cflsq.mod | 51 + .../3rdparty/glpk-4.57/examples/color.mod | 113 + .../3rdparty/glpk-4.57/examples/cplex/README | 44 + .../glpk-4.57/examples/cplex/concorde.txt | 121 + .../3rdparty/glpk-4.57/examples/cplex/cplex.c | 2130 +++ .../3rdparty/glpk-4.57/examples/cplex/cplex.h | 301 + resources/3rdparty/glpk-4.57/examples/cpp.mod | 67 + .../3rdparty/glpk-4.57/examples/crypto.mod | 84 + .../glpk-4.57/examples/csv/distances.csv | 7 + .../glpk-4.57/examples/csv/markets.csv | 4 + .../glpk-4.57/examples/csv/parameters.csv | 2 + .../glpk-4.57/examples/csv/plants.csv | 3 + .../glpk-4.57/examples/csv/transp_csv.mod | 70 + .../dbf/ForestMgt_Model_I_GIS_dbf.mod | 226 + .../glpk-4.57/examples/dbf/Forest_Cost.dbf | Bin 0 -> 1458 bytes .../glpk-4.57/examples/dbf/NetRev_Table.dbf | Bin 0 -> 11786 bytes .../3rdparty/glpk-4.57/examples/dbf/README | 2 + .../glpk-4.57/examples/dbf/TCost_Table.dbf | Bin 0 -> 11786 bytes .../examples/dbf/Yield_Table_Vol.dbf | Bin 0 -> 11786 bytes .../glpk-4.57/examples/dbf/cultural_pres.dbf | Bin 0 -> 96 bytes .../glpk-4.57/examples/dbf/mgt_year.dbf | Bin 0 -> 106 bytes .../glpk-4.57/examples/dbf/stands.dbf | Bin 0 -> 4323 bytes .../glpk-4.57/examples/dbf/standtype.dbf | Bin 0 -> 96 bytes resources/3rdparty/glpk-4.57/examples/dea.mod | 222 + .../3rdparty/glpk-4.57/examples/diet.mod | 99 + .../3rdparty/glpk-4.57/examples/dist.mod | 565 + .../3rdparty/glpk-4.57/examples/egypt.mod | 519 + .../3rdparty/glpk-4.57/examples/fctp.mod | 93 + .../3rdparty/glpk-4.57/examples/food.mod | 127 + .../3rdparty/glpk-4.57/examples/food2.mod | 150 + .../3rdparty/glpk-4.57/examples/furnace.mps | 164 + resources/3rdparty/glpk-4.57/examples/gap.mod | 79 + .../3rdparty/glpk-4.57/examples/glpsol.c | 10 + .../3rdparty/glpk-4.57/examples/graph.mod | 98 + .../3rdparty/glpk-4.57/examples/hashi.mod | 168 + .../3rdparty/glpk-4.57/examples/huge.mod | 25 + .../3rdparty/glpk-4.57/examples/icecream.mps | 345 + .../3rdparty/glpk-4.57/examples/iptsamp.c | 17 + .../3rdparty/glpk-4.57/examples/jssp.mod | 114 + .../3rdparty/glpk-4.57/examples/magic.mod | 54 + .../3rdparty/glpk-4.57/examples/maxcut.mod | 85 + .../3rdparty/glpk-4.57/examples/maxflow.mod | 83 + .../3rdparty/glpk-4.57/examples/mfasp.mod | 62 + .../3rdparty/glpk-4.57/examples/mfvsp.mod | 62 + .../3rdparty/glpk-4.57/examples/min01ks.mod | 111 + .../3rdparty/glpk-4.57/examples/misp.mod | 665 + .../3rdparty/glpk-4.57/examples/misp1.dat | 1489 ++ .../3rdparty/glpk-4.57/examples/misp2.dat | 3857 +++++ .../3rdparty/glpk-4.57/examples/money.mod | 62 + .../3rdparty/glpk-4.57/examples/mplsamp1.c | 32 + .../3rdparty/glpk-4.57/examples/mplsamp2.c | 39 + .../3rdparty/glpk-4.57/examples/murtagh.mps | 600 + .../3rdparty/glpk-4.57/examples/mvcp.mod | 43 + .../3rdparty/glpk-4.57/examples/netgen.c | 141 + .../3rdparty/glpk-4.57/examples/numbrix.mod | 84 + .../3rdparty/glpk-4.57/examples/oldapi/README | 11 + .../3rdparty/glpk-4.57/examples/oldapi/lpx.c | 1505 ++ .../3rdparty/glpk-4.57/examples/oldapi/lpx.h | 565 + .../glpk-4.57/examples/oldapi/lpxsamp.c | 51 + .../3rdparty/glpk-4.57/examples/pbn/9dom.dat | 65 + .../3rdparty/glpk-4.57/examples/pbn/README | 6 + .../3rdparty/glpk-4.57/examples/pbn/bucks.dat | 77 + .../3rdparty/glpk-4.57/examples/pbn/cat.dat | 67 + .../glpk-4.57/examples/pbn/dancer.dat | 42 + .../glpk-4.57/examples/pbn/disney.dat | 115 + .../glpk-4.57/examples/pbn/dragon.dat | 61 + .../3rdparty/glpk-4.57/examples/pbn/edge.dat | 48 + .../glpk-4.57/examples/pbn/forever.dat | 77 + .../3rdparty/glpk-4.57/examples/pbn/knot.dat | 95 + .../3rdparty/glpk-4.57/examples/pbn/light.dat | 122 + .../3rdparty/glpk-4.57/examples/pbn/mum.dat | 101 + .../3rdparty/glpk-4.57/examples/pbn/pbn.mod | 268 + .../3rdparty/glpk-4.57/examples/pbn/pbn.pdf | Bin 0 -> 43620 bytes .../3rdparty/glpk-4.57/examples/pbn/pbn.tex | 279 + .../3rdparty/glpk-4.57/examples/pbn/petro.dat | 102 + .../3rdparty/glpk-4.57/examples/pbn/skid.dat | 66 + .../3rdparty/glpk-4.57/examples/pbn/swing.dat | 117 + resources/3rdparty/glpk-4.57/examples/plan.lp | 39 + .../3rdparty/glpk-4.57/examples/plan.mod | 39 + .../3rdparty/glpk-4.57/examples/plan.mps | 54 + .../3rdparty/glpk-4.57/examples/prod.mod | 331 + .../3rdparty/glpk-4.57/examples/qfit.mod | 49 + .../3rdparty/glpk-4.57/examples/queens.mod | 41 + .../3rdparty/glpk-4.57/examples/samp1.mps | 29 + .../3rdparty/glpk-4.57/examples/samp2.mps | 27 + .../3rdparty/glpk-4.57/examples/sample.asn | 40 + .../3rdparty/glpk-4.57/examples/sample.c | 52 + .../3rdparty/glpk-4.57/examples/sample.clq | 30 + .../3rdparty/glpk-4.57/examples/sample.cnf | 12 + .../3rdparty/glpk-4.57/examples/sample.col | 30 + .../3rdparty/glpk-4.57/examples/sample.max | 26 + .../3rdparty/glpk-4.57/examples/sample.min | 26 + resources/3rdparty/glpk-4.57/examples/sat.mod | 201 + .../3rdparty/glpk-4.57/examples/shiftcov.mod | 244 + .../3rdparty/glpk-4.57/examples/shikaku.mod | 107 + .../3rdparty/glpk-4.57/examples/sorting.mod | 67 + resources/3rdparty/glpk-4.57/examples/spp.mod | 67 + .../3rdparty/glpk-4.57/examples/spxsamp1.c | 18 + .../3rdparty/glpk-4.57/examples/spxsamp2.c | 20 + .../3rdparty/glpk-4.57/examples/sql/README | 5 + .../glpk-4.57/examples/sql/mysql_setup.sh | 6 + .../glpk-4.57/examples/sql/sudoku.sql | 101 + .../glpk-4.57/examples/sql/sudoku_mysql.mod | 113 + .../glpk-4.57/examples/sql/sudoku_odbc.mod | 111 + .../glpk-4.57/examples/sql/transp.sql | 45 + .../glpk-4.57/examples/sql/transp_mysql.mod | 71 + .../glpk-4.57/examples/sql/transp_odbc.mod | 72 + .../3rdparty/glpk-4.57/examples/stigler.mod | 411 + .../3rdparty/glpk-4.57/examples/sudoku.dat | 16 + .../3rdparty/glpk-4.57/examples/sudoku.mod | 84 + resources/3rdparty/glpk-4.57/examples/t1.cs | 99 + resources/3rdparty/glpk-4.57/examples/tas.mod | 486 + .../3rdparty/glpk-4.57/examples/todd.mod | 36 + .../3rdparty/glpk-4.57/examples/train.mod | 281 + .../3rdparty/glpk-4.57/examples/transp.mod | 63 + .../3rdparty/glpk-4.57/examples/trick.mod | 72 + resources/3rdparty/glpk-4.57/examples/tsp.mod | 335 + .../3rdparty/glpk-4.57/examples/tsp/README | 37 + .../3rdparty/glpk-4.57/examples/tsp/bench.txt | 56 + .../3rdparty/glpk-4.57/examples/tsp/build.sh | 8 + .../glpk-4.57/examples/tsp/dantzig42.tsp | 103 + .../3rdparty/glpk-4.57/examples/tsp/gr120.tsp | 534 + .../3rdparty/glpk-4.57/examples/tsp/main.c | 535 + .../3rdparty/glpk-4.57/examples/tsp/maxflow.c | 170 + .../3rdparty/glpk-4.57/examples/tsp/maxflow.h | 20 + .../3rdparty/glpk-4.57/examples/tsp/mincut.c | 392 + .../3rdparty/glpk-4.57/examples/tsp/mincut.h | 23 + .../3rdparty/glpk-4.57/examples/tsp/misc.c | 159 + .../3rdparty/glpk-4.57/examples/tsp/misc.h | 24 + .../glpk-4.57/examples/tsp/moscow.tsp | 200 + .../glpk-4.57/examples/tsp/sample.tsp | 16 + .../3rdparty/glpk-4.57/examples/tsp/tsplib.c | 730 + .../3rdparty/glpk-4.57/examples/tsp/tsplib.h | 80 + .../glpk-4.57/examples/tsp/ulysses16.tsp | 24 + .../glpk-4.57/examples/tsp/ulysses22.tsp | 30 + .../3rdparty/glpk-4.57/examples/xyacfs.mod | 56 + .../3rdparty/glpk-4.57/examples/yacfs.mod | 48 + .../3rdparty/glpk-4.57/examples/zebra.mod | 151 + resources/3rdparty/glpk-4.57/install-sh | 527 + resources/3rdparty/glpk-4.57/ltmain.sh | 9687 +++++++++++ resources/3rdparty/glpk-4.57/m4/libtool.m4 | 7831 +++++++++ resources/3rdparty/glpk-4.57/m4/ltoptions.m4 | 369 + resources/3rdparty/glpk-4.57/m4/ltsugar.m4 | 123 + resources/3rdparty/glpk-4.57/m4/ltversion.m4 | 23 + .../3rdparty/glpk-4.57/m4/lt~obsolete.m4 | 98 + resources/3rdparty/glpk-4.57/missing | 330 + resources/3rdparty/glpk-4.57/src/Makefile.am | 178 + resources/3rdparty/glpk-4.57/src/Makefile.in | 2045 +++ resources/3rdparty/glpk-4.57/src/amd/COPYING | 502 + resources/3rdparty/glpk-4.57/src/amd/README | 58 + resources/3rdparty/glpk-4.57/src/amd/amd.h | 67 + resources/3rdparty/glpk-4.57/src/amd/amd_1.c | 181 + resources/3rdparty/glpk-4.57/src/amd/amd_2.c | 1842 ++ .../3rdparty/glpk-4.57/src/amd/amd_aat.c | 185 + .../3rdparty/glpk-4.57/src/amd/amd_control.c | 64 + .../3rdparty/glpk-4.57/src/amd/amd_defaults.c | 38 + .../3rdparty/glpk-4.57/src/amd/amd_dump.c | 180 + .../3rdparty/glpk-4.57/src/amd/amd_info.c | 120 + .../3rdparty/glpk-4.57/src/amd/amd_internal.h | 117 + .../3rdparty/glpk-4.57/src/amd/amd_order.c | 200 + .../glpk-4.57/src/amd/amd_post_tree.c | 121 + .../glpk-4.57/src/amd/amd_postorder.c | 207 + .../glpk-4.57/src/amd/amd_preprocess.c | 119 + .../3rdparty/glpk-4.57/src/amd/amd_valid.c | 93 + resources/3rdparty/glpk-4.57/src/avl.c | 406 + resources/3rdparty/glpk-4.57/src/avl.h | 74 + resources/3rdparty/glpk-4.57/src/bfd.c | 508 + resources/3rdparty/glpk-4.57/src/bfd.h | 91 + resources/3rdparty/glpk-4.57/src/bflib/btf.c | 569 + resources/3rdparty/glpk-4.57/src/bflib/btf.h | 207 + .../3rdparty/glpk-4.57/src/bflib/btfint.c | 407 + .../3rdparty/glpk-4.57/src/bflib/btfint.h | 73 + resources/3rdparty/glpk-4.57/src/bflib/fhv.c | 586 + resources/3rdparty/glpk-4.57/src/bflib/fhv.h | 114 + .../3rdparty/glpk-4.57/src/bflib/fhvint.c | 168 + .../3rdparty/glpk-4.57/src/bflib/fhvint.h | 78 + resources/3rdparty/glpk-4.57/src/bflib/ifu.c | 392 + resources/3rdparty/glpk-4.57/src/bflib/ifu.h | 99 + resources/3rdparty/glpk-4.57/src/bflib/luf.c | 713 + resources/3rdparty/glpk-4.57/src/bflib/luf.h | 227 + .../3rdparty/glpk-4.57/src/bflib/lufint.c | 182 + .../3rdparty/glpk-4.57/src/bflib/lufint.h | 73 + resources/3rdparty/glpk-4.57/src/bflib/scf.c | 523 + resources/3rdparty/glpk-4.57/src/bflib/scf.h | 211 + .../3rdparty/glpk-4.57/src/bflib/scfint.c | 255 + .../3rdparty/glpk-4.57/src/bflib/scfint.h | 89 + resources/3rdparty/glpk-4.57/src/bflib/sgf.c | 1430 ++ resources/3rdparty/glpk-4.57/src/bflib/sgf.h | 203 + resources/3rdparty/glpk-4.57/src/bflib/sva.c | 572 + resources/3rdparty/glpk-4.57/src/bflib/sva.h | 161 + resources/3rdparty/glpk-4.57/src/bfx.c | 89 + resources/3rdparty/glpk-4.57/src/bfx.h | 67 + resources/3rdparty/glpk-4.57/src/cglib/cfg.c | 409 + resources/3rdparty/glpk-4.57/src/cglib/cfg.h | 130 + resources/3rdparty/glpk-4.57/src/cglib/cfg1.c | 703 + .../3rdparty/glpk-4.57/src/colamd/COPYING | 502 + .../3rdparty/glpk-4.57/src/colamd/README | 98 + .../3rdparty/glpk-4.57/src/colamd/colamd.c | 3622 ++++ .../3rdparty/glpk-4.57/src/colamd/colamd.h | 69 + resources/3rdparty/glpk-4.57/src/draft.h | 32 + resources/3rdparty/glpk-4.57/src/env/alloc.c | 252 + resources/3rdparty/glpk-4.57/src/env/dlsup.c | 167 + resources/3rdparty/glpk-4.57/src/env/env.c | 237 + resources/3rdparty/glpk-4.57/src/env/env.h | 262 + resources/3rdparty/glpk-4.57/src/env/error.c | 200 + resources/3rdparty/glpk-4.57/src/env/stdc.h | 42 + resources/3rdparty/glpk-4.57/src/env/stdout.c | 262 + resources/3rdparty/glpk-4.57/src/env/stream.c | 485 + resources/3rdparty/glpk-4.57/src/env/time.c | 159 + resources/3rdparty/glpk-4.57/src/env/tls.c | 72 + resources/3rdparty/glpk-4.57/src/glpapi01.c | 1579 ++ resources/3rdparty/glpk-4.57/src/glpapi02.c | 492 + resources/3rdparty/glpk-4.57/src/glpapi03.c | 167 + resources/3rdparty/glpk-4.57/src/glpapi04.c | 157 + resources/3rdparty/glpk-4.57/src/glpapi05.c | 169 + resources/3rdparty/glpk-4.57/src/glpapi06.c | 831 + resources/3rdparty/glpk-4.57/src/glpapi07.c | 456 + resources/3rdparty/glpk-4.57/src/glpapi08.c | 388 + resources/3rdparty/glpk-4.57/src/glpapi09.c | 785 + resources/3rdparty/glpk-4.57/src/glpapi10.c | 305 + resources/3rdparty/glpk-4.57/src/glpapi11.c | 1235 ++ resources/3rdparty/glpk-4.57/src/glpapi12.c | 2181 +++ resources/3rdparty/glpk-4.57/src/glpapi13.c | 706 + resources/3rdparty/glpk-4.57/src/glpapi14.c | 272 + resources/3rdparty/glpk-4.57/src/glpapi15.c | 615 + resources/3rdparty/glpk-4.57/src/glpapi16.c | 330 + resources/3rdparty/glpk-4.57/src/glpapi17.c | 1269 ++ resources/3rdparty/glpk-4.57/src/glpapi18.c | 123 + resources/3rdparty/glpk-4.57/src/glpapi19.c | 141 + resources/3rdparty/glpk-4.57/src/glpapi20.c | 257 + resources/3rdparty/glpk-4.57/src/glpapi21.c | 1462 ++ resources/3rdparty/glpk-4.57/src/glpcpx.c | 1262 ++ resources/3rdparty/glpk-4.57/src/glpdmx.c | 1693 ++ resources/3rdparty/glpk-4.57/src/glpgmp.c | 1116 ++ resources/3rdparty/glpk-4.57/src/glpgmp.h | 190 + resources/3rdparty/glpk-4.57/src/glphbm.c | 529 + resources/3rdparty/glpk-4.57/src/glphbm.h | 127 + resources/3rdparty/glpk-4.57/src/glpini01.c | 155 + resources/3rdparty/glpk-4.57/src/glpini02.c | 270 + resources/3rdparty/glpk-4.57/src/glpios.h | 620 + resources/3rdparty/glpk-4.57/src/glpios01.c | 1602 ++ resources/3rdparty/glpk-4.57/src/glpios02.c | 826 + resources/3rdparty/glpk-4.57/src/glpios03.c | 1372 ++ resources/3rdparty/glpk-4.57/src/glpios04.c | 304 + resources/3rdparty/glpk-4.57/src/glpios05.c | 282 + resources/3rdparty/glpk-4.57/src/glpios06.c | 1448 ++ resources/3rdparty/glpk-4.57/src/glpios07.c | 551 + resources/3rdparty/glpk-4.57/src/glpios08.c | 147 + resources/3rdparty/glpk-4.57/src/glpios09.c | 664 + resources/3rdparty/glpk-4.57/src/glpios10.c | 355 + resources/3rdparty/glpk-4.57/src/glpios11.c | 282 + resources/3rdparty/glpk-4.57/src/glpios12.c | 177 + resources/3rdparty/glpk-4.57/src/glpipm.c | 1144 ++ resources/3rdparty/glpk-4.57/src/glpipm.h | 36 + resources/3rdparty/glpk-4.57/src/glpk.h | 1080 ++ resources/3rdparty/glpk-4.57/src/glpmat.c | 924 ++ resources/3rdparty/glpk-4.57/src/glpmat.h | 198 + resources/3rdparty/glpk-4.57/src/glpmpl.h | 2594 +++ resources/3rdparty/glpk-4.57/src/glpmpl01.c | 4715 ++++++ resources/3rdparty/glpk-4.57/src/glpmpl02.c | 1203 ++ resources/3rdparty/glpk-4.57/src/glpmpl03.c | 6085 +++++++ resources/3rdparty/glpk-4.57/src/glpmpl04.c | 1427 ++ resources/3rdparty/glpk-4.57/src/glpmpl05.c | 563 + resources/3rdparty/glpk-4.57/src/glpmpl06.c | 1000 ++ resources/3rdparty/glpk-4.57/src/glpmps.c | 1433 ++ resources/3rdparty/glpk-4.57/src/glpnet03.c | 1020 ++ resources/3rdparty/glpk-4.57/src/glpnet04.c | 769 + resources/3rdparty/glpk-4.57/src/glpnet05.c | 368 + resources/3rdparty/glpk-4.57/src/glpnpp.h | 638 + resources/3rdparty/glpk-4.57/src/glpnpp01.c | 938 ++ resources/3rdparty/glpk-4.57/src/glpnpp02.c | 1434 ++ resources/3rdparty/glpk-4.57/src/glpnpp03.c | 2862 ++++ resources/3rdparty/glpk-4.57/src/glpnpp04.c | 1415 ++ resources/3rdparty/glpk-4.57/src/glpnpp05.c | 810 + resources/3rdparty/glpk-4.57/src/glpnpp06.c | 1501 ++ resources/3rdparty/glpk-4.57/src/glprgr.c | 165 + resources/3rdparty/glpk-4.57/src/glprgr.h | 34 + resources/3rdparty/glpk-4.57/src/glpscl.c | 478 + resources/3rdparty/glpk-4.57/src/glpsdf.c | 259 + resources/3rdparty/glpk-4.57/src/glpsdf.h | 63 + resources/3rdparty/glpk-4.57/src/glpspm.c | 847 + resources/3rdparty/glpk-4.57/src/glpspm.h | 165 + resources/3rdparty/glpk-4.57/src/glpsql.c | 1641 ++ resources/3rdparty/glpk-4.57/src/glpsql.h | 64 + resources/3rdparty/glpk-4.57/src/glpssx.h | 426 + resources/3rdparty/glpk-4.57/src/glpssx01.c | 839 + resources/3rdparty/glpk-4.57/src/glpssx02.c | 479 + resources/3rdparty/glpk-4.57/src/lux.c | 1030 ++ resources/3rdparty/glpk-4.57/src/lux.h | 220 + .../3rdparty/glpk-4.57/src/minisat/LICENSE | 20 + .../3rdparty/glpk-4.57/src/minisat/README | 22 + .../3rdparty/glpk-4.57/src/minisat/minisat.c | 1299 ++ .../3rdparty/glpk-4.57/src/minisat/minisat.h | 230 + .../3rdparty/glpk-4.57/src/misc/bignum.c | 286 + .../3rdparty/glpk-4.57/src/misc/bignum.h | 37 + resources/3rdparty/glpk-4.57/src/misc/dmp.c | 243 + resources/3rdparty/glpk-4.57/src/misc/dmp.h | 63 + resources/3rdparty/glpk-4.57/src/misc/ffalg.c | 221 + resources/3rdparty/glpk-4.57/src/misc/ffalg.h | 34 + .../3rdparty/glpk-4.57/src/misc/fp2rat.c | 164 + resources/3rdparty/glpk-4.57/src/misc/gcd.c | 102 + resources/3rdparty/glpk-4.57/src/misc/jd.c | 152 + resources/3rdparty/glpk-4.57/src/misc/jd.h | 32 + .../3rdparty/glpk-4.57/src/misc/keller.c | 235 + .../3rdparty/glpk-4.57/src/misc/keller.h | 34 + resources/3rdparty/glpk-4.57/src/misc/mc13d.c | 314 + resources/3rdparty/glpk-4.57/src/misc/mc13d.h | 34 + resources/3rdparty/glpk-4.57/src/misc/mc21a.c | 301 + resources/3rdparty/glpk-4.57/src/misc/mc21a.h | 34 + resources/3rdparty/glpk-4.57/src/misc/misc.h | 61 + resources/3rdparty/glpk-4.57/src/misc/okalg.c | 382 + resources/3rdparty/glpk-4.57/src/misc/okalg.h | 35 + resources/3rdparty/glpk-4.57/src/misc/qmd.c | 584 + resources/3rdparty/glpk-4.57/src/misc/qmd.h | 58 + .../3rdparty/glpk-4.57/src/misc/relax4.c | 2850 ++++ .../3rdparty/glpk-4.57/src/misc/relax4.h | 102 + resources/3rdparty/glpk-4.57/src/misc/rng.c | 227 + resources/3rdparty/glpk-4.57/src/misc/rng.h | 67 + resources/3rdparty/glpk-4.57/src/misc/rng1.c | 73 + .../3rdparty/glpk-4.57/src/misc/round2n.c | 64 + .../3rdparty/glpk-4.57/src/misc/str2int.c | 92 + .../3rdparty/glpk-4.57/src/misc/str2num.c | 110 + .../3rdparty/glpk-4.57/src/misc/strspx.c | 60 + .../3rdparty/glpk-4.57/src/misc/strtrim.c | 62 + .../3rdparty/glpk-4.57/src/misc/triang.c | 311 + .../3rdparty/glpk-4.57/src/misc/triang.h | 34 + .../3rdparty/glpk-4.57/src/misc/wclique.c | 242 + .../3rdparty/glpk-4.57/src/misc/wclique.h | 33 + .../3rdparty/glpk-4.57/src/misc/wclique1.c | 317 + .../3rdparty/glpk-4.57/src/misc/wclique1.h | 34 + resources/3rdparty/glpk-4.57/src/prob.h | 280 + resources/3rdparty/glpk-4.57/src/proxy/main.c | 87 + .../3rdparty/glpk-4.57/src/proxy/proxy.c | 1061 ++ .../3rdparty/glpk-4.57/src/proxy/proxy.h | 36 + .../3rdparty/glpk-4.57/src/proxy/proxy1.c | 58 + .../3rdparty/glpk-4.57/src/simplex/simplex.h | 39 + .../3rdparty/glpk-4.57/src/simplex/spxat.c | 265 + .../3rdparty/glpk-4.57/src/simplex/spxat.h | 80 + .../3rdparty/glpk-4.57/src/simplex/spxchuzc.c | 381 + .../3rdparty/glpk-4.57/src/simplex/spxchuzc.h | 85 + .../3rdparty/glpk-4.57/src/simplex/spxchuzr.c | 388 + .../3rdparty/glpk-4.57/src/simplex/spxchuzr.h | 43 + .../3rdparty/glpk-4.57/src/simplex/spxlp.c | 674 + .../3rdparty/glpk-4.57/src/simplex/spxlp.h | 214 + .../3rdparty/glpk-4.57/src/simplex/spxnt.c | 260 + .../3rdparty/glpk-4.57/src/simplex/spxnt.h | 89 + .../3rdparty/glpk-4.57/src/simplex/spxprim.c | 1139 ++ .../3rdparty/glpk-4.57/src/simplex/spxprob.c | 679 + .../3rdparty/glpk-4.57/src/simplex/spxprob.h | 64 + .../3rdparty/glpk-4.57/src/simplex/spychuzc.c | 222 + .../3rdparty/glpk-4.57/src/simplex/spychuzc.h | 43 + .../3rdparty/glpk-4.57/src/simplex/spychuzr.c | 406 + .../3rdparty/glpk-4.57/src/simplex/spychuzr.h | 86 + .../3rdparty/glpk-4.57/src/simplex/spydual.c | 1221 ++ resources/3rdparty/glpk-4.57/src/zlib/README | 45 + .../3rdparty/glpk-4.57/src/zlib/adler32.c | 169 + .../3rdparty/glpk-4.57/src/zlib/compress.c | 80 + resources/3rdparty/glpk-4.57/src/zlib/crc32.c | 442 + resources/3rdparty/glpk-4.57/src/zlib/crc32.h | 441 + .../3rdparty/glpk-4.57/src/zlib/deflate.c | 1834 ++ .../3rdparty/glpk-4.57/src/zlib/deflate.h | 342 + .../3rdparty/glpk-4.57/src/zlib/gzclose.c | 25 + .../3rdparty/glpk-4.57/src/zlib/gzguts.h | 74 + resources/3rdparty/glpk-4.57/src/zlib/gzlib.c | 537 + .../3rdparty/glpk-4.57/src/zlib/gzread.c | 653 + .../3rdparty/glpk-4.57/src/zlib/gzwrite.c | 531 + .../3rdparty/glpk-4.57/src/zlib/inffast.c | 340 + .../3rdparty/glpk-4.57/src/zlib/inffast.h | 11 + .../3rdparty/glpk-4.57/src/zlib/inffixed.h | 94 + .../3rdparty/glpk-4.57/src/zlib/inflate.c | 1480 ++ .../3rdparty/glpk-4.57/src/zlib/inflate.h | 122 + .../3rdparty/glpk-4.57/src/zlib/inftrees.c | 330 + .../3rdparty/glpk-4.57/src/zlib/inftrees.h | 62 + resources/3rdparty/glpk-4.57/src/zlib/trees.c | 1244 ++ resources/3rdparty/glpk-4.57/src/zlib/trees.h | 128 + .../3rdparty/glpk-4.57/src/zlib/uncompr.c | 59 + resources/3rdparty/glpk-4.57/src/zlib/zconf.h | 168 + resources/3rdparty/glpk-4.57/src/zlib/zio.c | 92 + resources/3rdparty/glpk-4.57/src/zlib/zio.h | 37 + resources/3rdparty/glpk-4.57/src/zlib/zlib.h | 1613 ++ resources/3rdparty/glpk-4.57/src/zlib/zutil.c | 318 + resources/3rdparty/glpk-4.57/src/zlib/zutil.h | 93 + .../glpk-4.57/w32/Build_GLPK_with_VC10.bat | 11 + .../w32/Build_GLPK_with_VC10_DLL.bat | 11 + .../glpk-4.57/w32/Build_GLPK_with_VC14.bat | 11 + .../w32/Build_GLPK_with_VC14_DLL.bat | 11 + .../glpk-4.57/w32/Build_GLPK_with_VC9.bat | 11 + .../glpk-4.57/w32/Build_GLPK_with_VC9_DLL.bat | 11 + resources/3rdparty/glpk-4.57/w32/Makefile_VC | 204 + .../3rdparty/glpk-4.57/w32/Makefile_VC_DLL | 205 + resources/3rdparty/glpk-4.57/w32/config_VC | 13 + .../3rdparty/glpk-4.57/w32/glpk_4_57.def | 223 + resources/3rdparty/glpk-4.57/w32/readme.txt | 24 + .../glpk-4.57/w64/Build_GLPK_with_VC10.bat | 11 + .../w64/Build_GLPK_with_VC10_DLL.bat | 11 + .../glpk-4.57/w64/Build_GLPK_with_VC14.bat | 11 + .../w64/Build_GLPK_with_VC14_DLL.bat | 11 + .../glpk-4.57/w64/Build_GLPK_with_VC9.bat | 11 + .../glpk-4.57/w64/Build_GLPK_with_VC9_DLL.bat | 11 + resources/3rdparty/glpk-4.57/w64/config_VC | 13 + .../3rdparty/glpk-4.57/w64/glpk_4_57.def | 223 + resources/3rdparty/glpk-4.57/w64/makefile_VC | 204 + .../3rdparty/glpk-4.57/w64/makefile_VC_DLL | 205 + resources/3rdparty/glpk-4.57/w64/readme.txt | 24 + src/CMakeLists.txt | 1 + 463 files changed, 215966 insertions(+), 4 deletions(-) create mode 100644 resources/3rdparty/glpk-4.57/AUTHORS create mode 100644 resources/3rdparty/glpk-4.57/COPYING create mode 100644 resources/3rdparty/glpk-4.57/ChangeLog create mode 100644 resources/3rdparty/glpk-4.57/INSTALL create mode 100644 resources/3rdparty/glpk-4.57/Makefile.am create mode 100644 resources/3rdparty/glpk-4.57/Makefile.in create mode 100644 resources/3rdparty/glpk-4.57/NEWS create mode 100644 resources/3rdparty/glpk-4.57/README create mode 100644 resources/3rdparty/glpk-4.57/THANKS create mode 100644 resources/3rdparty/glpk-4.57/aclocal.m4 create mode 100755 resources/3rdparty/glpk-4.57/config.guess create mode 100644 resources/3rdparty/glpk-4.57/config.h.in create mode 100755 resources/3rdparty/glpk-4.57/config.sub create mode 100755 resources/3rdparty/glpk-4.57/configure create mode 100644 resources/3rdparty/glpk-4.57/configure.ac create mode 100755 resources/3rdparty/glpk-4.57/depcomp create mode 100644 resources/3rdparty/glpk-4.57/doc/cnfsat.pdf create mode 100644 resources/3rdparty/glpk-4.57/doc/cnfsat.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/glpk.pdf create mode 100644 resources/3rdparty/glpk-4.57/doc/glpk.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/glpk01.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/glpk02.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/glpk03.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/glpk04.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/glpk05.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/glpk06.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/glpk07.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/glpk08.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/glpk09.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/glpk10.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/glpk11.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/glpk12.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/gmpl.pdf create mode 100644 resources/3rdparty/glpk-4.57/doc/gmpl.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/gmpl_es.pdf create mode 100644 resources/3rdparty/glpk-4.57/doc/gmpl_es.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/graphs.pdf create mode 100644 resources/3rdparty/glpk-4.57/doc/graphs.tex create mode 100644 resources/3rdparty/glpk-4.57/doc/miplib2.txt create mode 100644 resources/3rdparty/glpk-4.57/doc/miplib3.txt create mode 100644 resources/3rdparty/glpk-4.57/doc/netlib.txt create mode 100644 resources/3rdparty/glpk-4.57/doc/notes/dfeas.pdf create mode 100644 resources/3rdparty/glpk-4.57/doc/notes/gomory.pdf create mode 100644 resources/3rdparty/glpk-4.57/doc/notes/keller.pdf create mode 100644 resources/3rdparty/glpk-4.57/doc/notes/scf.pdf create mode 100644 resources/3rdparty/glpk-4.57/doc/notes/simplex1.pdf create mode 100644 resources/3rdparty/glpk-4.57/doc/notes/simplex2.pdf create mode 100644 resources/3rdparty/glpk-4.57/examples/INDEX create mode 100644 resources/3rdparty/glpk-4.57/examples/Makefile.am create mode 100644 resources/3rdparty/glpk-4.57/examples/Makefile.in create mode 100644 resources/3rdparty/glpk-4.57/examples/alloy.mps create mode 100644 resources/3rdparty/glpk-4.57/examples/assign.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/bpp.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/cal.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/cf12a.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/cf12b.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/cflsq.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/color.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/cplex/README create mode 100644 resources/3rdparty/glpk-4.57/examples/cplex/concorde.txt create mode 100644 resources/3rdparty/glpk-4.57/examples/cplex/cplex.c create mode 100644 resources/3rdparty/glpk-4.57/examples/cplex/cplex.h create mode 100644 resources/3rdparty/glpk-4.57/examples/cpp.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/crypto.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/csv/distances.csv create mode 100644 resources/3rdparty/glpk-4.57/examples/csv/markets.csv create mode 100644 resources/3rdparty/glpk-4.57/examples/csv/parameters.csv create mode 100644 resources/3rdparty/glpk-4.57/examples/csv/plants.csv create mode 100644 resources/3rdparty/glpk-4.57/examples/csv/transp_csv.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/dbf/ForestMgt_Model_I_GIS_dbf.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/dbf/Forest_Cost.dbf create mode 100644 resources/3rdparty/glpk-4.57/examples/dbf/NetRev_Table.dbf create mode 100644 resources/3rdparty/glpk-4.57/examples/dbf/README create mode 100644 resources/3rdparty/glpk-4.57/examples/dbf/TCost_Table.dbf create mode 100644 resources/3rdparty/glpk-4.57/examples/dbf/Yield_Table_Vol.dbf create mode 100644 resources/3rdparty/glpk-4.57/examples/dbf/cultural_pres.dbf create mode 100644 resources/3rdparty/glpk-4.57/examples/dbf/mgt_year.dbf create mode 100644 resources/3rdparty/glpk-4.57/examples/dbf/stands.dbf create mode 100644 resources/3rdparty/glpk-4.57/examples/dbf/standtype.dbf create mode 100644 resources/3rdparty/glpk-4.57/examples/dea.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/diet.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/dist.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/egypt.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/fctp.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/food.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/food2.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/furnace.mps create mode 100644 resources/3rdparty/glpk-4.57/examples/gap.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/glpsol.c create mode 100644 resources/3rdparty/glpk-4.57/examples/graph.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/hashi.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/huge.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/icecream.mps create mode 100644 resources/3rdparty/glpk-4.57/examples/iptsamp.c create mode 100644 resources/3rdparty/glpk-4.57/examples/jssp.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/magic.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/maxcut.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/maxflow.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/mfasp.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/mfvsp.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/min01ks.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/misp.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/misp1.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/misp2.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/money.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/mplsamp1.c create mode 100644 resources/3rdparty/glpk-4.57/examples/mplsamp2.c create mode 100644 resources/3rdparty/glpk-4.57/examples/murtagh.mps create mode 100644 resources/3rdparty/glpk-4.57/examples/mvcp.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/netgen.c create mode 100644 resources/3rdparty/glpk-4.57/examples/numbrix.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/oldapi/README create mode 100644 resources/3rdparty/glpk-4.57/examples/oldapi/lpx.c create mode 100644 resources/3rdparty/glpk-4.57/examples/oldapi/lpx.h create mode 100644 resources/3rdparty/glpk-4.57/examples/oldapi/lpxsamp.c create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/9dom.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/README create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/bucks.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/cat.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/dancer.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/disney.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/dragon.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/edge.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/forever.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/knot.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/light.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/mum.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/pbn.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/pbn.pdf create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/pbn.tex create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/petro.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/skid.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/pbn/swing.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/plan.lp create mode 100644 resources/3rdparty/glpk-4.57/examples/plan.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/plan.mps create mode 100644 resources/3rdparty/glpk-4.57/examples/prod.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/qfit.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/queens.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/samp1.mps create mode 100644 resources/3rdparty/glpk-4.57/examples/samp2.mps create mode 100644 resources/3rdparty/glpk-4.57/examples/sample.asn create mode 100644 resources/3rdparty/glpk-4.57/examples/sample.c create mode 100644 resources/3rdparty/glpk-4.57/examples/sample.clq create mode 100644 resources/3rdparty/glpk-4.57/examples/sample.cnf create mode 100644 resources/3rdparty/glpk-4.57/examples/sample.col create mode 100644 resources/3rdparty/glpk-4.57/examples/sample.max create mode 100644 resources/3rdparty/glpk-4.57/examples/sample.min create mode 100644 resources/3rdparty/glpk-4.57/examples/sat.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/shiftcov.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/shikaku.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/sorting.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/spp.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/spxsamp1.c create mode 100644 resources/3rdparty/glpk-4.57/examples/spxsamp2.c create mode 100644 resources/3rdparty/glpk-4.57/examples/sql/README create mode 100755 resources/3rdparty/glpk-4.57/examples/sql/mysql_setup.sh create mode 100644 resources/3rdparty/glpk-4.57/examples/sql/sudoku.sql create mode 100644 resources/3rdparty/glpk-4.57/examples/sql/sudoku_mysql.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/sql/sudoku_odbc.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/sql/transp.sql create mode 100644 resources/3rdparty/glpk-4.57/examples/sql/transp_mysql.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/sql/transp_odbc.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/stigler.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/sudoku.dat create mode 100644 resources/3rdparty/glpk-4.57/examples/sudoku.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/t1.cs create mode 100644 resources/3rdparty/glpk-4.57/examples/tas.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/todd.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/train.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/transp.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/trick.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/README create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/bench.txt create mode 100755 resources/3rdparty/glpk-4.57/examples/tsp/build.sh create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/dantzig42.tsp create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/gr120.tsp create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/main.c create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/maxflow.c create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/maxflow.h create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/mincut.c create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/mincut.h create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/misc.c create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/misc.h create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/moscow.tsp create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/sample.tsp create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/tsplib.c create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/tsplib.h create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/ulysses16.tsp create mode 100644 resources/3rdparty/glpk-4.57/examples/tsp/ulysses22.tsp create mode 100644 resources/3rdparty/glpk-4.57/examples/xyacfs.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/yacfs.mod create mode 100644 resources/3rdparty/glpk-4.57/examples/zebra.mod create mode 100755 resources/3rdparty/glpk-4.57/install-sh create mode 100755 resources/3rdparty/glpk-4.57/ltmain.sh create mode 100644 resources/3rdparty/glpk-4.57/m4/libtool.m4 create mode 100644 resources/3rdparty/glpk-4.57/m4/ltoptions.m4 create mode 100644 resources/3rdparty/glpk-4.57/m4/ltsugar.m4 create mode 100644 resources/3rdparty/glpk-4.57/m4/ltversion.m4 create mode 100644 resources/3rdparty/glpk-4.57/m4/lt~obsolete.m4 create mode 100755 resources/3rdparty/glpk-4.57/missing create mode 100644 resources/3rdparty/glpk-4.57/src/Makefile.am create mode 100644 resources/3rdparty/glpk-4.57/src/Makefile.in create mode 100644 resources/3rdparty/glpk-4.57/src/amd/COPYING create mode 100644 resources/3rdparty/glpk-4.57/src/amd/README create mode 100644 resources/3rdparty/glpk-4.57/src/amd/amd.h create mode 100644 resources/3rdparty/glpk-4.57/src/amd/amd_1.c create mode 100644 resources/3rdparty/glpk-4.57/src/amd/amd_2.c create mode 100644 resources/3rdparty/glpk-4.57/src/amd/amd_aat.c create mode 100644 resources/3rdparty/glpk-4.57/src/amd/amd_control.c create mode 100644 resources/3rdparty/glpk-4.57/src/amd/amd_defaults.c create mode 100644 resources/3rdparty/glpk-4.57/src/amd/amd_dump.c create mode 100644 resources/3rdparty/glpk-4.57/src/amd/amd_info.c create mode 100644 resources/3rdparty/glpk-4.57/src/amd/amd_internal.h create mode 100644 resources/3rdparty/glpk-4.57/src/amd/amd_order.c create mode 100644 resources/3rdparty/glpk-4.57/src/amd/amd_post_tree.c create mode 100644 resources/3rdparty/glpk-4.57/src/amd/amd_postorder.c create mode 100644 resources/3rdparty/glpk-4.57/src/amd/amd_preprocess.c create mode 100644 resources/3rdparty/glpk-4.57/src/amd/amd_valid.c create mode 100644 resources/3rdparty/glpk-4.57/src/avl.c create mode 100644 resources/3rdparty/glpk-4.57/src/avl.h create mode 100644 resources/3rdparty/glpk-4.57/src/bfd.c create mode 100644 resources/3rdparty/glpk-4.57/src/bfd.h create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/btf.c create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/btf.h create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/btfint.c create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/btfint.h create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/fhv.c create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/fhv.h create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/fhvint.c create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/fhvint.h create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/ifu.c create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/ifu.h create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/luf.c create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/luf.h create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/lufint.c create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/lufint.h create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/scf.c create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/scf.h create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/scfint.c create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/scfint.h create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/sgf.c create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/sgf.h create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/sva.c create mode 100644 resources/3rdparty/glpk-4.57/src/bflib/sva.h create mode 100644 resources/3rdparty/glpk-4.57/src/bfx.c create mode 100644 resources/3rdparty/glpk-4.57/src/bfx.h create mode 100644 resources/3rdparty/glpk-4.57/src/cglib/cfg.c create mode 100644 resources/3rdparty/glpk-4.57/src/cglib/cfg.h create mode 100644 resources/3rdparty/glpk-4.57/src/cglib/cfg1.c create mode 100644 resources/3rdparty/glpk-4.57/src/colamd/COPYING create mode 100644 resources/3rdparty/glpk-4.57/src/colamd/README create mode 100644 resources/3rdparty/glpk-4.57/src/colamd/colamd.c create mode 100644 resources/3rdparty/glpk-4.57/src/colamd/colamd.h create mode 100644 resources/3rdparty/glpk-4.57/src/draft.h create mode 100644 resources/3rdparty/glpk-4.57/src/env/alloc.c create mode 100644 resources/3rdparty/glpk-4.57/src/env/dlsup.c create mode 100644 resources/3rdparty/glpk-4.57/src/env/env.c create mode 100644 resources/3rdparty/glpk-4.57/src/env/env.h create mode 100644 resources/3rdparty/glpk-4.57/src/env/error.c create mode 100644 resources/3rdparty/glpk-4.57/src/env/stdc.h create mode 100644 resources/3rdparty/glpk-4.57/src/env/stdout.c create mode 100644 resources/3rdparty/glpk-4.57/src/env/stream.c create mode 100644 resources/3rdparty/glpk-4.57/src/env/time.c create mode 100644 resources/3rdparty/glpk-4.57/src/env/tls.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi01.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi02.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi03.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi04.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi05.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi06.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi07.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi08.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi09.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi10.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi11.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi12.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi13.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi14.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi15.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi16.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi17.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi18.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi19.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi20.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpapi21.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpcpx.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpdmx.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpgmp.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpgmp.h create mode 100644 resources/3rdparty/glpk-4.57/src/glphbm.c create mode 100644 resources/3rdparty/glpk-4.57/src/glphbm.h create mode 100644 resources/3rdparty/glpk-4.57/src/glpini01.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpini02.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpios.h create mode 100644 resources/3rdparty/glpk-4.57/src/glpios01.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpios02.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpios03.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpios04.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpios05.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpios06.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpios07.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpios08.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpios09.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpios10.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpios11.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpios12.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpipm.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpipm.h create mode 100644 resources/3rdparty/glpk-4.57/src/glpk.h create mode 100644 resources/3rdparty/glpk-4.57/src/glpmat.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpmat.h create mode 100644 resources/3rdparty/glpk-4.57/src/glpmpl.h create mode 100644 resources/3rdparty/glpk-4.57/src/glpmpl01.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpmpl02.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpmpl03.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpmpl04.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpmpl05.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpmpl06.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpmps.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpnet03.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpnet04.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpnet05.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpnpp.h create mode 100644 resources/3rdparty/glpk-4.57/src/glpnpp01.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpnpp02.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpnpp03.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpnpp04.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpnpp05.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpnpp06.c create mode 100644 resources/3rdparty/glpk-4.57/src/glprgr.c create mode 100644 resources/3rdparty/glpk-4.57/src/glprgr.h create mode 100644 resources/3rdparty/glpk-4.57/src/glpscl.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpsdf.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpsdf.h create mode 100644 resources/3rdparty/glpk-4.57/src/glpspm.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpspm.h create mode 100644 resources/3rdparty/glpk-4.57/src/glpsql.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpsql.h create mode 100644 resources/3rdparty/glpk-4.57/src/glpssx.h create mode 100644 resources/3rdparty/glpk-4.57/src/glpssx01.c create mode 100644 resources/3rdparty/glpk-4.57/src/glpssx02.c create mode 100644 resources/3rdparty/glpk-4.57/src/lux.c create mode 100644 resources/3rdparty/glpk-4.57/src/lux.h create mode 100644 resources/3rdparty/glpk-4.57/src/minisat/LICENSE create mode 100644 resources/3rdparty/glpk-4.57/src/minisat/README create mode 100644 resources/3rdparty/glpk-4.57/src/minisat/minisat.c create mode 100644 resources/3rdparty/glpk-4.57/src/minisat/minisat.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/bignum.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/bignum.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/dmp.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/dmp.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/ffalg.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/ffalg.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/fp2rat.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/gcd.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/jd.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/jd.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/keller.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/keller.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/mc13d.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/mc13d.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/mc21a.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/mc21a.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/misc.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/okalg.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/okalg.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/qmd.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/qmd.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/relax4.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/relax4.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/rng.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/rng.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/rng1.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/round2n.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/str2int.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/str2num.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/strspx.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/strtrim.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/triang.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/triang.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/wclique.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/wclique.h create mode 100644 resources/3rdparty/glpk-4.57/src/misc/wclique1.c create mode 100644 resources/3rdparty/glpk-4.57/src/misc/wclique1.h create mode 100644 resources/3rdparty/glpk-4.57/src/prob.h create mode 100644 resources/3rdparty/glpk-4.57/src/proxy/main.c create mode 100644 resources/3rdparty/glpk-4.57/src/proxy/proxy.c create mode 100644 resources/3rdparty/glpk-4.57/src/proxy/proxy.h create mode 100644 resources/3rdparty/glpk-4.57/src/proxy/proxy1.c create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/simplex.h create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spxat.c create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spxat.h create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spxchuzc.c create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spxchuzc.h create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spxchuzr.c create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spxchuzr.h create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spxlp.c create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spxlp.h create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spxnt.c create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spxnt.h create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spxprim.c create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spxprob.c create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spxprob.h create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spychuzc.c create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spychuzc.h create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spychuzr.c create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spychuzr.h create mode 100644 resources/3rdparty/glpk-4.57/src/simplex/spydual.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/README create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/adler32.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/compress.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/crc32.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/crc32.h create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/deflate.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/deflate.h create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/gzclose.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/gzguts.h create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/gzlib.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/gzread.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/gzwrite.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/inffast.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/inffast.h create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/inffixed.h create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/inflate.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/inflate.h create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/inftrees.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/inftrees.h create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/trees.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/trees.h create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/uncompr.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/zconf.h create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/zio.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/zio.h create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/zlib.h create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/zutil.c create mode 100644 resources/3rdparty/glpk-4.57/src/zlib/zutil.h create mode 100755 resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC10.bat create mode 100755 resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC10_DLL.bat create mode 100755 resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC14.bat create mode 100755 resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC14_DLL.bat create mode 100755 resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC9.bat create mode 100755 resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC9_DLL.bat create mode 100644 resources/3rdparty/glpk-4.57/w32/Makefile_VC create mode 100644 resources/3rdparty/glpk-4.57/w32/Makefile_VC_DLL create mode 100644 resources/3rdparty/glpk-4.57/w32/config_VC create mode 100644 resources/3rdparty/glpk-4.57/w32/glpk_4_57.def create mode 100644 resources/3rdparty/glpk-4.57/w32/readme.txt create mode 100755 resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC10.bat create mode 100755 resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC10_DLL.bat create mode 100755 resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC14.bat create mode 100755 resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC14_DLL.bat create mode 100755 resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC9.bat create mode 100755 resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC9_DLL.bat create mode 100644 resources/3rdparty/glpk-4.57/w64/config_VC create mode 100644 resources/3rdparty/glpk-4.57/w64/glpk_4_57.def create mode 100644 resources/3rdparty/glpk-4.57/w64/makefile_VC create mode 100644 resources/3rdparty/glpk-4.57/w64/makefile_VC_DLL create mode 100644 resources/3rdparty/glpk-4.57/w64/readme.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 76d554806..e985841e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -239,9 +239,11 @@ endif(STORM_HAVE_Z3) set(STORM_HAVE_GLPK 1) message (STATUS "StoRM - Linking with glpk") -add_subdirectory("${PROJECT_SOURCE_DIR}/resources/3rdparty/glpk-4.53") -include_directories("${PROJECT_SOURCE_DIR}/resources/3rdparty/glpk-4.53/src") -list(APPEND STORM_LINK_LIBRARIES "glpk") + +set(GLPK_LIBRARIES ${CMAKE_BINARY_DIR}/resources/3rdparty/glpk-4.57/lib/libglpk.a) +set(GLPK_INCLUDE_DIR ${CMAKE_BINARY_DIR}/resources/3rdparty/glpk-4.57/include) +include_directories(${GLPK_INCLUDE_DIR}) +list(APPEND STORM_LINK_LIBRARIES ${GLPK_LIBRARIES}) diff --git a/resources/3rdparty/CMakeLists.txt b/resources/3rdparty/CMakeLists.txt index c360fa366..4cc396d80 100644 --- a/resources/3rdparty/CMakeLists.txt +++ b/resources/3rdparty/CMakeLists.txt @@ -6,4 +6,15 @@ ExternalProject_Add( PREFIX ${CMAKE_CURRENT_BINARY_DIR}/xercesc-3.1.2 BUILD_COMMAND make BUILD_IN_SOURCE 0 -) \ No newline at end of file +) + +ExternalProject_Add( + glpk + DOWNLOAD_COMMAND "" + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/glpk-4.57 + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/glpk-4.57 + CONFIGURE_COMMAND CC=${CMAKE_C_COMPILER} ${CMAKE_CURRENT_SOURCE_DIR}/glpk-4.57/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/glpk-4.57 + BUILD_COMMAND make + INSTALL_COMMAND make install + BUILD_IN_SOURCE 0 +) diff --git a/resources/3rdparty/glpk-4.57/AUTHORS b/resources/3rdparty/glpk-4.57/AUTHORS new file mode 100644 index 000000000..8771f0d86 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/AUTHORS @@ -0,0 +1,33 @@ +The GLPK package was developed and programmed by Andrew Makhorin, +Department for Applied Informatics, Moscow Aviation Institute, Moscow, +Russia. + +E-mail: + +Paper mail: 125871, Russia, Moscow, Volokolamskoye sh., 4, + Moscow Aviation Institute, Andrew O. Makhorin + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.2.2 (MingW32) + +mQGiBD8UdT8RBAC6yWYxoa1b7U973J0jBuQpgZnhXlGJJpMZgAW9efDBD17vhkJm +hPVOQBKRUeOOLcW3/a7NMoNLMdmF1Rgz1FPVy3RgBDsYj4Sp4RBCsX/o0xXh+jxe +gncr4bdN0Ruk03pezVtLi9oYygdxfI51SsjZ2vwYP6BhMwv+xrIgcnc4qwCgoCit +26mTd0FoGOmsQuipo6X5LaUD/1l7NqFIjiGdWthyG3TqsiK5Ew7xF3fLEABXKPjb +PMRTMucX8XXHmW8RUD1vP1uGDnEn6s+fjc3/RtaqKjqGMdLt4XgHQkImaVguNpSS +IxN3LaK600BgAbwSd1bomRqWNlczAM7469VvGG9ASpCBveUUrqwerHZcUbvngL62 +pIcqA/41dO0xYrOTqMRhuguYMgHL2xbwB2Aj2TqRwBm697DIS25B9nE+8UsbjGRx +q3EmeuHeZ5kN5RbESXkGUB8whIcYxvH16HRNmM1ZjmFoBVL2Z6S2gpa2ZUqsq7BZ +s+hriElm3dfOQCt79/o852uKWu5bSjw2yiemVA2T8tG4OoN6DrQjQW5kcmV3IE1h +a2hvcmluIDxtYW9AbWFpMi5yY25ldC5ydT6IWwQTEQIAGwUCPxR1PwYLCQgHAwID +FQIDAxYCAQIeAQIXgAAKCRDRe/IwWYHoGKpHAJ44MmzWKr8OiTc0Bb6/RD56aekp +3wCdGznQMCfWFkehQPbeNaB5yFIs+8a5AQ0EPxR1UBAEAO3U3H5M0iYv06C4kKty +6ReWyYH4CzMAfp2lPVUKzRSjPtoAJ6SkrBSKMT+U+DahxZ4K4HbinvHq3uvlwWax +xw0wKxJl4oY6EGE1Jqn3B//Ak47RaNMnrs9V739WT1YNRpQvh4wOCeMekBzksf43 +hm4dSV4PMQkLmrEeG2+BYaZnAAMFA/4tVHhjGRkxzcTcfHCB+Yo3PXeIQMuIs00c +VKCrNReLni/3BWZC0w9tFzZSdz+URXefPWDGuAC16vLCVOD06NcIQGutPe189dUn +Kf9Bl6qc9DyWsxSTdF/PbLqcLfEe9g7fHhIwdY+w/hSq2n3NEURMzHiMT1U3CvHd +As5IzV/yD4hGBBgRAgAGBQI/FHVQAAoJENF78jBZgegYRZEAmwReJkMSrbs0EQs2 +wjyTCMd5KDh3AKCR2/RvVad9RT3ShYnUiPPYTL2/Nw== +=OfLQ +-----END PGP PUBLIC KEY BLOCK----- diff --git a/resources/3rdparty/glpk-4.57/COPYING b/resources/3rdparty/glpk-4.57/COPYING new file mode 100644 index 000000000..94a9ed024 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/resources/3rdparty/glpk-4.57/ChangeLog b/resources/3rdparty/glpk-4.57/ChangeLog new file mode 100644 index 000000000..acf5867be --- /dev/null +++ b/resources/3rdparty/glpk-4.57/ChangeLog @@ -0,0 +1,2932 @@ +Sun Nov 08 12:00:00 2015 Andrew Makhorin + + * GLPK 4.57 (38:0:2) has been released. + + * src/simplex/spy*.* + New, more efficient implementation of the dual simplex method + was included in the package. + + * src/simplex/spxprim.c + Incorrect directive #ifdef USE_AT was changed to #if USE_AT. + + * src/simplex/simplex.h + New header for simplex-based drivers was added. + + * src/glpspx02.c + Old implementation of the dual simplex method was removed from + the package. + + * src/glpspx.h + Old header for simplex-based drivers was removed. + + * src/glpapi06.c + Call to spx_dual was changed to spy_dual. + tol_piv = 1e-10 in glp_init_smcp was changed to 1e-9 (this new + tolerance seems to be more adequate for new implementations of + the primal and dual simplex methods). + + * src/glpk.h, src/glpapi09.c, src/glpios03.c + Option iocp.sr_heur to enable/disable simple rounding heuristic + was added. Thanks to Chris Matrakidis for + suggestion. + + * src/env/env.h src/env/error.c + API routine glp_at_error was added and documented. Thanks to + Jeroen Demeyer for suggestion. + + * src/glpapi19.c + Translation of MiniSat solver (src/minisat) from C++ to C is + made by a non-skilled programmer who converts pointers to ints + and vice versa, so MiniSat works on 32-bit platforms only. + Fixing this portability issue would require rewriting the code, + so currently to prevent crashing the API routine glp_minisat1 + was changed just to report failure if 64-bit version of GLPK is + used. Thanks to Heinrich Schuchardt for + bug report. + + * doc/glpk.tex, doc/gmpl.tex + Some material was added according to changes in GLPK API. + Also some minor typos were corrected. Thanks to Anton Voropaev + for typo report. + + * w32/makefiles, w64/makefiles + Option /Zi was added to pass to MSVC compiler. + + examples/tsp/*.* + An example application program TSPSOL was added. This program + is intended to solve the Symmetric Traveling Salesman Problem. + For more details see examples/tsp/README. + +Thu Oct 01 12:00:00 2015 Andrew Makhorin + + * GLPK 4.56 (37:3:1) has been released. + + * src/simplex/*.c, *.h + New, more efficient and robust implementation of the primal + simplex method was included in the package. + + * src/glpspx01.c + Old implementation of the primal simplex method was removed + from the package. + + * src/bflib/sgf.c + A bug was fixed in routine sgf_reduce_nuc. (The bug appeared if + the basis matrix was structurally singular.) Thanks to Martin + Jacob for bug report. + + * w32/*.*, w64/*.* + Scripts to build GLPK with Microsoft Visual Studio 2015 were + added. Thanks to Xypron for contribution + and testing. + +Fri Aug 22 12:00:00 2014 Andrew Makhorin + + * GLPK 4.55 (37:2:1) has been released. + + * src/bflib/luf.c, src/bflib/luf.h + Two routines luf_vt_solve1 and luf_estimate_norm were added to + estimate 1-norm of matrix inverse. + + * src/bflib/btf.c, src/bflib/btf.h + Two routines btf_at_solve1 and btf_estimate_norm were added to + estimate 1-norm of block triangular matrix inverse. + + * src/bflib/fhvint.c, src/bflib/fhvint.h + The routine fhvint_estimate was added to estimate 1-norm of the + basis matrix inverse (FHV-factorization). + + * src/bflib/scfint.c, src/bflib/scfint.h + The routine scfint_estimate was added to estimate 1-norm of the + basis matrix inverse (Schur-complement-based factorization). + + * src/bfd.c, src/bfd.c + The routine bfd_condest was added to estimate the condition of + the basis matrix. + + * src/bflib/scfint.h + The prefix '_glp' was added to keep the namespace clean. + + * src/env/stream.c + Two open modes "a" and "ab" were added. Thanks to Pedro P. Wong + for bug report. + + * src/glpapi21.c (glpsol) + Minor bug was fixed (command-line options --btf, --cbg, --cgr + didn't work properly). + + * src/bflib/sgf.c + A serious bug was fixed in a basis factorization routine used + on the dense phase. (The bug might appear only if the number of + rows exceeded sqrt(2**31) ~= 46,340 and caused access violtaion + exception because of integer overflow.) Thanks to Mark Meketon + for bug report. + + * doc/glpk.tex + Two API routines glp_alloc and glp_realloc were documented. + Thanks to Brian Gladman for suggestion. + + * doc/gmpl_es.tex, doc/gmpl_es.pdf + Translation of the document "Modeling Language GNU MathProg" + to Spanish was included (in LaTeX and pdf formats). Thanks to + Pablo Yapura for contribution. + +Fri Mar 28 12:00:00 2014 Andrew Makhorin + + * GLPK 4.54 (37:1:1) has been released. + + * src/bflib/fhvint.h, fhvint.c + Some technical changes were made. + + * src/bflib/btf.h, btf.c, btfint.h, btfint.c + The module BTF was added to the package. It implements sparse + block triangular factorization of a square non-singular matrix + and is based on LU-factorization (see the LUF module). + + * src/bflib/scf.h, scf.c, scfint.h, scfint.c + The module SCF was added to the package. It implements sparse + factorization of a square non-singular matrix based on Schur + complement and LU-factorization (plain or block triangular; see + the LUF and BTF modules). + + * src/bfd.c + LP basis factorization driver was changed to use most recent + versions of the FHV and SCF modules. + + * src/glplpf.h, glplpf.c + Old version of the Schur-complement-based factorization module + was removed from the package. + + * src/glpk.h + New flags GLP_BF_LUF, GLP_BF_BTF were added for glp_bfcp. + + * src/glpapi12.c + The API routines glp_get_bfcp, glp_set_bfcp were replaced due + to new version of the BFD module. + + * src/glpapi21.c + New command-line options --luf, --btf, --ft, --cbg, and --cgr + were added for the glpsol solver. + + * src/* + According to a new version of the GNU Coding Standards in all + messages a grave accent character (`) was replaced by a single + apostrophe character ('). + + * src/glpapi09.c mip status bug was fixed. Thanks to Remy Roy + for bug report. + + * doc/glpk.tex + Some comments about invalidating the basis factorization were + added. Thanks to Xypron for suggestion. + + * configure.ac + "iodbc-config --cflags" was added to detect iodbc flags. Thanks + to Sebastien Villemot for patch. + +Thu Feb 13 12:00:00 2014 Andrew Makhorin + + * GLPK 4.53 (37:0:1) has been released. + + * src/glpmps.c (glp_read_mps) + The code was changed to remove free rows at the end. + + * src/glpcpx.c (glp_read_lp) + A bug was fixed (explicit bounds for binaries not set). Thanks + to Gabriel Hackebeil for bug report. + + * src/glpenv07.c (z_fgetc) + A bug was fixed (Z_STREAM_END -> Z_OK). Thanks to Achim Gaedke + for bug report. + + * src/glpenv07.c + Replaced by src/env/stream.c. + + * src/glpenv08.c + Replaced by src/env/dlsup.c. + + * src/bflib/ifu.h, src/bflib/ifu.c + Re-implemented. + + * src/glpscf.h, src/glpscf.c + Replaced by IFU. + + * src/glplpf.h, src/glplpf.c + Changed due to IFU. + + * src/glpbfd.c + Changed due to LPF. + + * src/glpapi06.c + Two API routines glp_get_it_cnt and glp_set_it_cnt were added. + Thanks to Joey Rios for suggestion. + + * src/glplpx.h, src/glplpx01.c, src/glplpx02.c, src/glplpx03.c + All obsolete API routines were completely removed. + + * examples/oldapi/lpx.h, examples/oldapi/lpx.c + A set of routines that simulate the old GLPK API (as defined + in 4.48) were added. Thanks to Jan Engelhardt + for suggestion. + + * src/zlib/* + zlib 1.2.7 was downgraded to zlib 1.2.5 (from glpk 4.50) due to + bugs detected in zlib 1.2.7 on some 64-bit platforms. Thanks to + Carlo Baldassi for bug report. + + * src/glpsql.c + Alignment bug was fixed. Thanks to Xypron + for suggestion. + + * src/glpsql.c + #include and #include were commented + out to fix a namespace bug on compiling with MariaDB. Thanks to + Xypron for suggestion. + +Sun Jul 28 12:00:00 2013 Andrew Makhorin + + * GLPK 4.52.1 (36:1:0) has been released. + + * src/Makefile.am + Version information bug was fixed. Thanks to Sebastien Villemot + for bug report. + + * src/proxy/proxy.c + A minor bug (incorrect use of glp_term_out) was fixed. + + * src/glpios03.c + The simple rounding heuristic routine was changed to check only + global constraints. + + * src/glpcpx.c + The code was changed to issue the warning message 'lower/upper + bound redefined' only once. + +Thu Jul 18 12:00:00 2013 Andrew Makhorin + + * GLPK 4.52 (36:0:1) has been released. + + * src/misc/wclique1.h, src/misc/wclique1.c + Greedy heuristic to find maximum weight clique was implemented. + + * src/cglib/cfg.h, src/cglib/cfg.c, src/cglib/cfg1.c + Conflict graph routines (used to generate clique cuts) were + implemented. + + * src/glpios08.c + New version of the clique cut generator was implemented. Now it + is able to efficiently process very large and/or dense conflict + graphs. Old rudimentary version was removed from the package. + + * examples/misp1.dat, examples/misp2.dat + Two data files for the maximum independent set problem (MISP) + were added to illustrate efficiency of using the clique cuts. + + * src/glpios03.c + Simple rounding heuristic applied for every node subproblem was + implemented. + + * proxy/proxy.c + Some bugs were fixed in the proximity search heuristic routine. + Thanks to Giorgio Sartor <0gioker0@gmail.com>. + + * src/glpapi21.c + New command-line option '--proxy [nnn]' was added to glpsol to + enable using the proximity search heuristic. + + * src/glpspx02.c + A feature was added to switch to the primal simplex in case of + stalling due to dual degeneracy (for GLP_DUALP only). + + * src/glpmps.c + A bug (incorrect processing of LI column indicator) was fixed + in the mps format reading routine. Thanks to Charles Brixko for + bug report. + +Wed Jun 19 12:00:00 2013 Andrew Makhorin + + * GLPK 4.51 (36:0:0) has been released. + + * src/bflib/sgf.c, src/bflib/sgf.h + Singleton and dense phases of sparse Gaussian factorizer were + implemented. + + * src/bflib/lufint.c, src/bflib/lufint.h + Interface routines to LU-factorization were added. + + * src/bflib/fhvint.c, src/bflib/fhvint.h + Interface routines to FHV-factorization were changed to use + lufint.c routines. + + * src/glplpf.c, src/glplpf.h + Routines implementing Schur-complement version of the LP basis + factorization were changed to use lufint.c routines. + + * src/glpbfd.c, src/glpbfd.h + Interface routines to the LP basis factorization were changed + due to changes in glplpf.c routines. + + * src/glpluf.c, src/glpluf.c + Old version of LU-factorization was removed from the package. + (This old version was used for 10 years since 3.0.6.) + + * src/misc/triang.c, src/misc/triang.h + Routine to find maximal triangular part of rectangular matrix + was added. + + * src/glpini01.c + The API routine glp_adv_basis that constructs advanced initial + LP basis was replaced by an improved version, which (unlike the + old version) takes into account numerical values of constraint + coefficients. + + * src/proxy/* + Routines that implement the proximity search heuristic for MIP + were added. Thanks to Giorgio Sartor <0gioker0@gmail.com> for + contribution. + + * src/glpk.h + iocp.ps_heur was added to enable/disable proxy heuristic. + + * glpsol + --proxy command-line option was added. + + * src/zlib/*.* + zlib general purpose compression library, version 1.2.7, + was ANSIfied and modified according to GLPK requirements and + included in the distribution as an external software module. + This version replaced the old one (1.2.5). For details please + see src/zlib/README. + + * src/glpk.h, src/env/time.c + The API routine glp_time was changed to return double rather + than glp_long. + + * src/glplib02.c + Routines that implement glp_long type (64-bit arithmetic) were + removed from the package. + + * src/glpk.h, src/env/alloc.c + New API routine glp_alloc was added. It makes obsolete two + API routines glp_malloc and glp_calloc which were replaced by + macros to use glp_alloc (hence 36:0:0). + + * src/glpios10.c + A bug was fixed that caused numerical instability in the FPUMP + heuristic (the bug was introduced in glpk 4.40). + +Fri May 24 12:00:00 2013 Andrew Makhorin + + * GLPK 4.50 (35:0:0) has been released + + * src/Makefile.am + Though API was not changed since 4.49, symbols _glp_lpx_* were + removed from the export list, hence 35:0:0. + + * src/glpfhv.h, src/glpfhv.c + Old routines for FHV-factorization were removed. + + * src/bflib/*.h, src/bflib/*.c + New version of basis factorization routines, including routines + for FHV-factorization, were added. + + * src/glpbfd.c + LP basis factorization driver was changed according to the new + routines for FHV-factorization. + + * doc/glpk.tex + Some clarifications about using the name index routines were + added. Thanks to Xypron for suggestion. + + * doc/gmpl.tex + Some typos were corrected. + Thanks to Jeffrey Kantor for report. + + * src/glprlx.c + A serious bug was *tentatively* fixed. This bug is inherited + from the original Fortran version of the RELAX-IV code. + Unfortunately, the code is very intricate, so this bug is still + under investigation. Thanks to Sylvain Fournier for bug report. + + RELAX-IV bug details + -------------------- + In the original RELAX-IV code there are four similar fragments + in subroutines ascnt1 and ascnt2 like this: + + C + C DECREASE THE PRICES OF THE SCANNED NODES BY DELPRC. + C ADJUST FLOW TO MAINTAIN COMPLEMENTARY SLACKNESS WITH + C THE PRICES. + C + NB = 0 + DO 6 I=1,NSAVE + . . . + IF (RC(ARC).EQ.0) THEN + DELX=DELX+U(ARC) + NB = NB + 1 + PRDCSR(NB) = ARC + END IF + . . . + + On some instances the variable NB becomes greater than N (the + number of nodes) that leads to indexing error, because the + array PRDCSR is declared as array of N elements (more + precisely, as array of MAXNN elements, however, NB becomes even + much greater than MAXNN). + +Tue Apr 16 12:00:00 2013 Andrew Makhorin + + * GLPK 4.49 (34:0:0) has been released + + * glprlx.c, glprlx.h + C version of the Fortran code RELAX-IV (relaxation method of + Bertsekas and Tseng) was added. + + * glpapi17.c + API routine glp_mincost_relax4, which is a driver to RELAX-IV + code, was added and documented. + + * glpnet03.c + API routine glp_netgen_prob (Klingman's standard network + problems) was added and documented. + + * glpapi12.c + A bug (wrong dual feasibility test) was fixed in API routine + glp_warm_up. Thanks to David T. Price + for bug report. + + * glpapi10.c + Obsolete API routine lpx_check_kkt was replaced by API routine + glp_check_kkt. + + * glpk.h + All old API routines whose names begin with 'lpx_' were removed + from API and no more available. + + * glpk.tex, graphs.tex + These documents were essentially reformatted. + +Mon Jan 28 12:00:00 2013 Andrew Makhorin + + * GLPK 4.48 (33:0:0) has been released + + * src/glpmps.c + A bug in glp_write_mps was fixed. Thanks to Raniere Gaia Costa + da Silva for bug report. + + * glpk.h + glp_prob declaration changed (now it is incomplete struct); + glp_tree declaration changed (now it is incomplete struct); + glp_tran declaration changed (now it is incomplete struct); + glp_long declaration removed; + glp_time declaration removed; + glp_difftime removed from API; + glp_data removed from API; + glp_sdf_* removed from API; + glp_mem_usage declaration changed (glp_long -> size_t); + glp_realloc declaration added (not documented yet). + + * glpenv.h, glpenv05.c + Dynamic memory allocation routines were reimplemented. + + * glpk.h, glpnet03.c + Routine glp_netgen_prob was added (not documented yet). + + * configure.ac + Check for gmp.h was added. Thanks to Heinrich Schuchardt for + suggestion. + + * w32/glpk.def, w64/glpk.def + Changes were made to export only API symbols. + +Fri Sep 09 12:00:00 2011 Andrew Makhorin + + * GLPK 4.47 (32:0:32) has been released + + * src/glpapi20.c + New API routine glp_infeas1 to solve 0-1 feasibility problem + was added and documented (see doc/cnfsat.pdf). + + * src/glpnpp06.c + Some new preprocessor routines for SAT-CNF encoding, which are + used by the routine glp_intfeas1, were added. + + * src/glpnpp.h + The header was modified due to additions. + + * src/glpapi21.c + The glpsol solver was modified to bypass model postprocessing + if the solution reported is neither optimal nor feasible. + + * src/glpapi21.c + New glpsol options (--minisat and --objbnd) were added. + + * examples/pbn/*.* + The paint-by-numbers puzzle model (pbn.mod) was modified to + print solution in PostScript format and to check for multiple + solutions. Some benchmark examples from encoded + in MathProg were included in the distribution. For more details + see examples/pbn/README and examples/pbn/pbn.pdf. + + * examples/Makefile.am + A minor bug was fixed to correctly build glpk in a separate + directory. Thanks to Marco Atzeri for + bug report. + +Tue Aug 09 12:00:00 2011 Andrew Makhorin + + * GLPK 4.46 (31:0:31) has been released + + * src/glpk.h, src/Makefile + glpk.h was relocated from 'include' to 'src', and 'include' + subdir was removed; src/Makefile.am was changed appropriately. + + * src/zlib/*.* + zlib general purpose compression library, version 1.2.5, + was ANSIfied and modified according to GLPK requirements and + included in the distribution as an external software module. + + For details see src/zlib/README. + + * src/glpdmx.c + The following new API routines were added: + glp_read_cnfsat - read CNF-SAT problem data in DIMACS format + glp_check_cnfsat - check for CNF-SAT problem instance + glp_write_cnfsat - write CNF-SAT problem data in DIMACS format + + * src/minisat/*.* + MiniSat, a CNF-SAT solver, version 1.14.1, was ANSIfied and + modified according to GLPK requirements and included in the + distribution as an external software module. + + For details see minisat/README and minisat/LICENSE. + + * src/glpapi19.c + The API routine glp_minisat1, which is a driver to the MiniSat + solver, was included in the package. + + * doc/satcnf.* + The document "CNF Satisfiability Problem" was included in the + package. It is a supplement to the GLPK Reference Manual. + + * src/glpapi20.c + New glpsol options (--cnf, --wcnf, and --minisat) was added. + + * glpsql.c + Some bugs were fixed. Thanks to Xypron . + +Sun Dec 05 12:00:00 2010 Andrew Makhorin + + * GLPK 4.45 (30:0:30) has been released + + * glplpx01.c + A bug (it_cnt) in routine reset_parms was fixed. + Thanks to Ali Baharev for report. + + * glpmpl03.c + A bug (print "text\") was fixed. + Thanks to Xypron for report. + + * glpsql.c + A precision bug was fixed. + Thanks to Xypron . + + * glpk.tex + Some typos were corrected. + Thanks to Robbie Morrison . + +Thu Jun 03 12:00:00 2010 Andrew Makhorin + + * GLPK 4.44 (29:0:29) has been released + + * glpapi14.c glpmpl.h glpmpl01.c glpmpl03.c glpmpl04.c + Implemented suffixes for variables and constraints. + + * glpmpl06.c + Made changes to allow comment records in CSV files. + + * glpapi17.c + Added and documented new API routine glp_cpp to solve Critical + Path Problem. + +Sat Feb 20 12:00:00 2010 Andrew Makhorin + + * GLPK 4.43 (28:0:28) has been released + + * glplib.h, glplib.c, glpenv.h, glpenv.c + The module glpenv was split into two modules glpenv and glplib. + + * glpenv01.c, glpenv03.c, glpenv04.c, glpenv06.c + The following new API routines were added and documented: + glp_init_env, glp_free_env, glp_open_tee, glp_close_tee, + glp_error (macro), glp_difftime. + + * glpapi16.c + New API routine glp_top_sort (topological sorting of ayclic + digraph) was added and documented. + + * glpapi17.c + A serious bug was fixed in the routine glp_asn_prob_hall. + + * glpnpp05.c + A bug was fixed in the LP/MIP preprocessor (hidden covering + inequalities). + + * glpsql.c + Some improvements were made in the table driver (NULL data). + Thanks to Xypron for contribution. + + * configure.ac + Changes were made to use .dylib rather than .so under Mac OS. + Thanks to Noli Sicad for testing + +Wed Jan 13 12:00:00 2010 Andrew Makhorin + + * GLPK 4.42 (27:0:27) has been released + + * glpapi01.c, glpapi11.c, glpapi12.c, glpdmx.c + The following new API routines were added and documented: + glp_check_dup (check for duplicate elements in sparse matrix); + glp_sort_matrix (sort elements of the constraint matrix); + glp_read_prob (read problem data in GLPK format); + glp_write_prob (write problem data in GLPK format); + glp_analyze_bound (analyze active bound of non-basic variable); + glp_analyze_coef (analyze obj. coefficient at basic variable); + glp_print_ranges (print sensitivity analysis report; replaces + lpx_print_sens_bnds). + + * glpapi20.c + New command-line options were added to glpsol: + --glp (read problem data in GLPK format); + --wglp (write problem data in GLPK format); + --lp (replaces --cpxlp); + --wlp (replaces --wcpxlp); + --ranges (print sensitivity analysis report). + + * glpapi06.c + In the routine glp_init_smcp default value of the parameter + out_frq was changed to 500 (it was 200). + + * glpipp.h, glpipp01.c, glpipp02.c + The old MIP preprocessor module was removed. + + * glpapi09.c + Now the MIP solver uses the new MIP preprocessor (NPP). + + * glplpx03.c + lpx_write_opb was disabled due to replacing IPP with NPP. + + * glpnet09.c + Kellerman's heuristic to cover edges by cliques was added. + + * glplib08.c + Recognition of special filenames "/dev/stdin", "/dev/stdout", + and "/dev/stderr" was added. + + * glpk.tex + Chapter "Graph and network routines" was carried out from the + reference manual as a separate document. + +Mon Dec 21 12:00:00 2009 Andrew Makhorin + + * GLPK 4.41 (26:0:26) has been released + + * glpapi12.c + The following new API routines were added: + glp_transform_row (replaces lpx_transform_row); + glp_transform_col (replaces lpx_transform_col); + glp_prim_rtest (replaces lpx_prim_ratio_test); + glp_dual_rtest (replaces lpx_dual_ratio_test). + Note that values returned by glp_prim_rtest and glp_dual_rtest + differ from the ones retutned by the deprecated routines. + + * glpnpp*.* + The LP/MIP preprocessor was essentially re-implemented. + + * glpios03.c + The feature to remove inactive cuts from the active subproblem + was implemented. + + * glpios11.c + The feature processing cuts stored in the cut pool was improved + (now it uses estimation of objective degradation). + + * glpscg.* + Obsolete implemetation of the conflict graph was removed. + + * glpmpl.h, glpmpl03.c, glpmpl04.c + FILE was replaced by XFILE to allow using GLPK I/O routines. + + * glpsql.c, examples/sql, doc/tables.tex + The SQL table driver was changed to allow multiple arguments + separated by semicolon in SQL statements. Thanks to Xypron + . + + * glpk.h, glpapi14.c + New API routine glp_time was added (not documented yet). + + * glpapi20.c + Two new options were added to glpsol: --seed value (initialize + pseudo-random number generator used in MathProg model with + specified seed value), and --ini filename (use as initial basis + previously saved with -w option). + + * examples/xyacfs.mod + Thanks to Nigel Galloway for + contribution. + + * examples/dbf/*.* + Thanks to Noli Sicad for contribution. + + * w32/*.*, w64/*.* + Scripts to build GLPK with Microsoft Visual Studio 2010 were + added. Thanks to Xypron for contribution + and testing. + +Tue Nov 03 12:00:00 2009 Andrew Makhorin + + * GLPK 4.40 (25:0:25) has been released + + * glpdmx.c + Two new API routines were added: + glp_read_ccdata (read graph in DIMACS clique/coloring format); + glp_write_ccdata (write graph in DIMACS clique/coloring format). + Also an example file examples/sample.col was added. + + * glpapi19.c, glpnet08.c + New API routine glp_wclique_exact was added. It is intended to + find a maximum weight clique with the exact algorithm developed + by Prof. P. Ostergard. + + * glpnpp02.c + A bug was fixed in the LP preprocessor (routine npp_empty_col). + Thanks to Stefan Vigerske for the + bug report. + + * glpios10.c + A bug was fixed and some improvements were made in the FPUMP + heuristic module. Thanks to Xypron . + + * glpapi12.c + A bug was fixed in the API routine glp_warm_up (dual + feasibility test was incorrect in maximization case). Thanks to + Uday Venkatadri for the bug report. + + * glpapi16.c + Two new API routines were added: + glp_del_vertices (remove vertices from graph); + glp_del_arc (remove arc from graph). + + * glpios09.c + The hybrid pseudocost branching heuristic was included in the + MIP solver. It is available on API level (iocp.br_tech should + be set to GLP_BR_PCH) and in the stand-alone solver glpsol + (via the command-line option --pcost). This heuristic may be + useful on solving hard MIP instances. + + * glpios03.c + The branching heuristic by Driebeck and Tomlin (used in the + MIP solver by default) was changed to switch to branching on + most fractional variable if an lower bound of degradation of + the objective is close to zero for all branching candidates. + +Sun Jul 26 12:00:00 2009 Andrew Makhorin + + * GLPK 4.39 (24:0:24) has been released + + * glpsdf.c + New API routines to read plain data files were added. + + * glpcpx.h, glpini.h, glpscl.h + These headers were removed. + + * glpcpx.c + API routines glp_read_lp and glp_write_lp to read/write files + in CPLEX LP format were re-implemented. Now glp_write_lp + correctly writes double-bounded (ranged) rows by introducing + slack variables rather than by duplicating the rows. The data + structure glp_cpxcp and routine glp_init_cpxcp were added. + + * amd/* + The 'xfree(NULL)' bug was fixed in the AMD routines. Thanks to + Niels Klitgord for the bug report. + + * glpapi16.c + New API routines glp_set_vertex_name, glp_create_v_index, + glp_find_vertex, and glp_delete_v_index were added. + + * glpdmx.c + New API routines glp_read_asnprob, glp_write_asnprob, + glp_read_ccformat, and glp_write_ccformat were added (the two + latter routines are not documented yet). + + * glpapi18.c + New API routines glp_check_asnprob, glp_asnprob_lp, + glp_asnprob_okalg, and glp_asnprob_hall were added. + + * glpini01.c, glpini02.c + The message "Crashing..." was changed to "Constructing initial + basis..." due to suggestion by Thomas Kahle . + + * glpapi14.c + New API routines glp_printf, glp_vprintf, glp_malloc, + glp_calloc, glp_free, and glp_assert were added. + + * glplpp.h, glplpp01.c, glplpp02.c + Old LP presolver routines were removed. Now glp_simplex uses + new preprocessing routines (see glpnpp). + + * glpapi12.c + New API routine glp_warm_up was added; it replaces the routine + lpx_warm_up. + +Sat May 02 12:00:00 2009 Andrew Makhorin + + * GLPK 4.38 (23:0:23) has been released + + * glpmps.c + API routines to read/write MPS files were re-implemented. + + * glpspx02.c + Some improvements were made in the dual simplex routine. + + * glpk.h + New structure glp_iptcp was added. + + * glpnpp.h, glpnpp01.c, glpnpp02.c + New LP/MIP preprocessor. Currently it includes only some basic + routines and used only in the interior-point solver. + + * glpapi08.c + API routine glp_interior was replaced by an improved version + (new LP/MIP preprocessor, new ordering algorithms). + + New API routine glp_init_iptcp was added. + + API routine glp_ipt_status may return two new statuses due to + changes in glp_interior. + + * glpsol.c + New command-line options were added (ordering algorithm used in + the interior-point solver). + + * amd/*.*, colamd/*.* + Two external software modules AMD and COLAMD/SYMAMD used in the + interior-point solver were included in the distribution. + + For details see amd/README and colamd/README. + + * glpnet03.c, glpnet04.c, glpnet05.c + A minor bug was fixed (_G => G_). Thanks to Nelson H. F. Beebe + for bug report. + +Sun Mar 29 12:00:00 2009 Andrew Makhorin + + * GLPK 4.37 (22:0:22) has been released + + * glpk.h + iocp.fp_heur was added to enable/disable fpump heuristic. + + * glpios10.c + ios_feas_pump was added (feasibility pump heuristic). + + * glpsol.c + --fpump command-line option was added. + + * glpsds.c + Plain data set routines were added to facilitate reading plain + data in application programs. Currently these routines are not + in API, though declared in glpk.h. + + * glpapi08.c + A bug was fixed in the internal routine restore. (Due to this + bug dual solution components were computed incorrectly if the + problem was scaled.) + + * glpapi10.c, glpapi11.c + The following new API routines were added: + glp_print_sol (replaces lpx_print_sol); + glp_print_ipt (replaces lpx_print_ips); + glp_print_mip (replaces lpx_print_mip); + _glp_check_kkt (replaces lpx_check_kkt, lpx_check_int). + Now the routine lpx_print_prob (deprecated) is equivalent to + the routine glp_write_lp. + + * glpapi18.c, glpapi19.c + The following new API routines were added: + glp_read_graph (read graph from plain text file); + glp_write_graph (write graph to plain text file); + glp_weak_comp (find all weakly connected components); + glp_strong_comp (find all strongly connected components). + + * configure.ac, Makefile.am + Changes were made: (a) to allow using autoreconf/autoheader; + (b) to allow building glpk in a directory other than its source + directory. Thanks to Marco Atzeri for + bug report. + + * examples/shiftcover.mod + An example model in MathProg was added. + Thanks to Larry D'Agostino + for contribution. + +Fri Feb 06 12:00:00 2009 Andrew Makhorin + + * GLPK 4.36 (21:0:21) has been released + + * glpnet06.c, glpnet07.c, glpapi19.c + The following new API routines were added: + glp_mincost_okalg find minimum-cost flow with out-of-kilter + algorithm + glp_maxflow_ffalg find maximal flow with Ford-Fulkerson + algorithm + + * glpsol.c + Two new command-line options were added: + --mincost read min-cost flow data in DIMACS format + --maxflow read maximum flow data in DIMACS format + + * doc/glpk.* + New edition of the reference manual was included. + + * glpk.h + Duplicate symbols were removed to allow using swig. + Thanks to Kelly Westbrooks and + Nigel Galloway for suggestion. + + * glpcpx.c + A minor defect was fixed in the routine glp_write_lp. + Thanks to Sebastien Briais for bug report. + + * glpsql.c + A minor bug was fixed. Thanks to Xypron + for patch. + + * examples/hashi.mod, examples/shikaku.mod + Two example models in MathProg were added. Thanks to Sebastian + Nowozin for contribution. + + * examples/qfit.mod, examples/yacfs.mod + Two example models in MathProg were added. Thanks to Nigel + Galloway for contribution. + +Fri Jan 09 12:00:00 2009 Andrew Makhorin + + * GLPK 4.35 (20:0:20) has been released + + * glpk.h, glpapi.c, glpnet.c + The following new API routines were added: + glp_create_graph create graph + glp_set_graph_name assign (change) graph name + glp_add_vertices add new vertices to graph + glp_add_arc add new arc to graph + glp_erase_graph erase graph content + glp_delete_graph delete graph + glp_read_mincost read minimum cost flow problem data in + DIMACS format + glp_write_mincost write minimum cost flow problem data in + DIMACS format + glp_mincost_lp convert minimum cost flow problem to LP + glp_netgen Klingman's network problem generator + glp_gridgen grid-like network problem generator + glp_read_maxflow read maximum flow problem data in DIMACS + format + glp_write_maxflow write maximum flow problem data in DIMACS + format + glp_maxflow_lp convert maximum flow problem to LP + glp_rmfgen Goldfarb's maximum flow problem generator + + * doc/glpk.* + New edition of the reference manual was included. + + * examples/sample.min, examples/sample.max + Two example data files in DIMACS format were added. + + * glplib04.c + The statement "if (c = '\n') fflush(stdout)" was added to the + internal routine xputc to provide "real-time" terminal output. + Thanks to Luiz Bettoni for + suggestion. + + * glpmpl05.c + A minor bug was fixed in the internal routine mpl_fn_time2str. + Thanks to Stefan Vigerske for bug report. + + * w32/makefile, w64/makefile + The flag -O2 (/O2) was added to some makefiles. + +Thu Dec 04 12:00:00 2008 Andrew Makhorin + + * GLPK 4.34 (19:0:19) has been released + + * src/glpios03.c + A bug was fixed in the internal routine branch_on. Thanks to + Nigel Galloway for bug report. + + * src/glpmpl05.c + Three new MathProg functions were included: + gmtime obtaining current calendar time + str2time converting character string to calendar time + time2str converting calendar time to character string + Thanks to Xypron . + + * doc/glpk.*, doc/gmpl.* + A new edition of the GLPK reference manual and GNU MathProg + language description were included. + +Thu Oct 30 12:00:00 2008 Andrew Makhorin + + * GLPK 4.33 (18:0:18) has been released + + * glpapi*.* + The following new API routines were added: + glp_copy_prob copy problem object content + glp_exact solve LP in exact arithmetic + (makes lpx_exact deprecated) + glp_get_unbnd_ray determine variable causing unboundedness + (makes lpx_get_ray_info deprecated) + glp_interior solve LP with interior-point method + (makes lpx_interior deprecated) + + * glpapi*.* + The following new API routines for processing models written in + the GNU Mathprog language were added to the package: + glp_mpl_alloc_wksp allocate the translator workspace + glp_mpl_read_model read and translate model section + glp_mpl_read_data read and translate data section + glp_mpl_generate generate the model + glp_mpl_build_prob build LP/MIP instance from the model + glp_mpl_postsolve postsolve the model + glp_mpl_free_wksp deallocate the translator workspace + (These routines make lpx_read_model deprecated.) + + * src/glpapi17.c, examples/glpsol.c + The stand-alone solver glpsol was re-implemented with new API + routines. + + * src/glpsql.c + Some bugs were fixed in the SQL table driver. Thanks to Xypron + . + + * examples/cplex/*.* + A crude implementation of CPLEX-like interface to GLPK API was + added to the package. See examples/cplex/README. + +Fri Oct 03 12:00:00 2008 Andrew Makhorin + + * GLPK 4.32 (17:0:17) has been released + + * glpmpl01.c + A bug was fixed. Due to this bug iterated expressions having + an indexing expression whose dummy indices are bound to some + values, i.e. like sum{(i+1,j,k-1) in E} x[i,j,k] are evaluated + incorrectly. Namely, current value of such expressions is not + invalidated when corresponding dummy indices (like i and k in + the example above) are changed, that erroneously results in the + same value evaluated for the first time. + + * glpios03.c + Euclidean reduction of the local objective bound was added in + the routine glpios03.c. + + * glpapi11.c + The following new branch-and-cut API routines were added: + glp_ios_row_attr determine additional row attributes; + glp_ios_pool_size determine current size of the cut pool; + glp_ios_add_row add constraint to the cut pool; + glp_ios_del_row delete constraint from the cut pool; + glp_ios_clear_pool delete all constraints from the cut pool. + + * glpapi08.c + The following new features were included in the branch-and-cut + solver (the API routine glp_intopt): + MIP presolver; + mixed cover cut generator; + clique cut generator. + Due to the MIP presolver glp_intopt may additionally return + GLP_ENOPFS and GLP_ENODFS, if primal or dual infeasibility of + LP relaxation is detected by the presolver. Also the return + code GLP_EMIPGAP was introduced to correctly indicate that the + mip gap tolerance is reached. + + * glplpx01.c + Now the obsolete API routines lpx_integer and lpx_intopt are + completely superseded by the API routine glp_intopt that makes + them deprecated. + + * glpmpl05.c + Now the table driver name "iODBC" can be specified as "ODBC". + + * glpmpl03.c + A bug fixed in the routine free_dca. + Thanks to Xypron . + + * glpsql.c + A bug was fixed in the SQL table driver. + Thanks to Xypron . + + * examples/glpsol.c + Changes were made to allow multiple MathProg data files. + + * doc/glpk.* + A new edition of the GLPK reference manual was included. + + * doc/tables.* + A new edition of the supplement "Using data tables in the GNU + MathProg language" was included. + +Tue Sep 02 12:00:00 2008 Andrew Makhorin + + * GLPK 4.31 (16:0:16) has been released + + * glpspx.h, glpspx01.c, glpspx02.c, glpapi06.c + The dual simplex solver (spx_dual_opt) was replaced by a new + implementation of the two-phase dual simplex method (spx_dual). + Old simplex method routines (spx_prim_opt, spx_prim_feas, and + spx_dual_opt) were removed from the package. + + * glpk.h, glpscl.h, glpscl.c, glpapi04.c + New API routine glp_scale_prob was added. It replaces routine + lpx_scale_prob which is deprecated. + + * glpk.h, glpini.h, glpini01.c, glpini02.c, glpapi05.c + New API routines glp_std_basis, glp_adv_basis, glp_cpx_basis + were added. They replace routines lpx_std_basis, lpx_adv_basis, + lpx_cpx_basis which are deprecated. + + * glpdmp.c + 8-byte data alignment was added to the module (sufficient for + both ILP32 and LP64 environments). + + * glplib07.c + 16-byte data alignment was added to the module to provide + compatibility with LP64 environment (8-byte is not sufficient + due to jmp_buf; thanks to Xypron for investigation). + + * glplpx16.c + New version of the routine lpx_write_pb was added. Thanks to + Oscar Gustafsson for the contribution. + + * w32/VC9, w64/VC9 + Makefiles and batch files were added to build GLPK under 32- + and 64-bit Windows with Microsoft Visual Studio Express 2008. + Thanks to Heinrich Schuchardt for + the contribution and testing. + + * w32/DM, w32/OWC + Makefiles and batch files were added to build GLPK with Digital + Mars C/C++ 8.50 and Open Watcom C/C++ 1.6 (32-bit Windows). + +Wed Aug 13 12:00:00 2008 Andrew Makhorin + + * GLPK 4.30 (15:0:15) has been released + + * glpspx.h, glpspx03.c, glpapi06.c + The primal simplex solver (spx_prim_opt, spx_prim_feas) was + replaced by a new implementation (spx_primal), which currently + provides the same features as the old version. + + * glpmpl01.c, glpmpl03.c + Some changes were made in the MathProg translator to allow <, + <=, >=, and > on comparing symbolic values. Thanks to Heinrich + Schuchardt for patches. + + * glplpx10.c + Internal routine set_d_eps in the exact LP solver was changed + to prevent approximation errors in case of integral data. + Thanks to Markus Pilz for bug report. + +XXX XXX XX 12:00:00 2008 Andrew Makhorin + + * GLPK 4.29 (14:0:14) has been released + + * configure.ac + The configure script was changed to disable optional features + by default. For details see file INSTALL. + + * glpipp02.c + A bug was fixed in the internal routine reduce_bounds. Thanks + to Anne-Laurence Putz for + the bug report. + + * glpapi01.c + New API routine glp_erase_prob was added. + + * glpapi13.c + New API routines glp_read_mps and glp_write_mps were added. + They replace API routines lpx_read_mps, lpx_read_freemps, + lpx_write_mps, and lpx_write_freemps, which are deprecated. + + * glpapi14.c + New API routines glp_read_lp and glp_write_lp were added. They + replace API routines lpx_read_cpxlp and lpx_write_cpxlp, which + are deprecated. + + * glpsql.c + Minor bug was fixed. Thanks to Xypron for + the bug report. + +Tue Mar 25 12:00:00 2008 Andrew Makhorin + + * GLPK 4.28 (13:0:13) has been released + + * glplib.h, glplib.c + Three wrapper routines xdlopen, xdlsym, and xdlclose, which + provide the shared library support, were added. A particular + version of these routines depends on the option --enable-dl + passed to the configure script (see file INSTALL for details). + Thanks to Rafael Laboissiere for useful + advices concerning the shared library support. + + * glpsql.c + A static linking to iODBC and MySQL libraries used in the + MathProg table drivers was replaced by a dynamic linking to + corresponding shared libraries. + Many thanks to Heinrich Schuchardt + for the contribution and to Vijay Patil + for testing this feature under Windows XP. + + * glpgmp.h, glpgmp.c + A bug (which appeared only on 64-bit platforms) was fixed. + Thanks to Axel Simon for the bug report. + + * glpapi.c + A bug was fixed in the api routine glp_add_cols. (If the basis + is valid, adding column keeps it valid, however, col->bind was + set to -1 rather to 0.) + Thanks to Cedric[FR] for the bug report. + + * glplib.c + 64-bit unsigned int type glp_ulong and corresponding routines + were replaced by 64-bit signed int type xlong_t. + + * glpk.h, glpapi.c + The type glp_ulong was replaced by glp_long. This affects only + the api routine glp_mem_usage. + + * glplib.c + Compressed data file support was added. This feature requires + the zlib data compression libraries and allows compressing and + decompressing .gz files "on the fly". + + * glpcli.h, glpcli.c + Command-line interface routines were added. (This feature is + incomplete so far.) + +Sun Mar 02 12:00:00 2008 Andrew Makhorin + + * GLPK 4.27 (12:0:12) has been released + + * glpsql.h, glpsql.c + Two MathProg table drivers for iODBC and MySQL contributed by + Heinrich Schuchardt were added to + the package. + + * glpmpl05.c + Mathprog table driver for xBASE was added to the package. + + * glpmpl03.c + A minor was fixed in the MathProg translator (if some field + specified in the table statement is missing in corresponding + input table, the bug causes abnormal termination). Thanks to + Heinrich Schuchardt for the bug + report. + + * glpmpl.h, glpmpl.c + STRING data type was replaced by plain character strings. + +Sun Feb 17 12:00:00 2008 Andrew Makhorin + + * GLPK 4.26 (11:0:11) has been released + + * glpmpl.h, glpmpl01.c, glpmpl03.c, glpmpl05.c + The table statement was implemented. Description of this new + feature is given in file doc/tables.txt. + + * glpios03.c + A bug causing zero divide error on computing euclidean norm of + the cut coefficient vector was fixed. + +Wed Dec 19 12:00:00 2007 Andrew Makhorin + + * GLPK 4.25 (10:0:10) has been released + + * glpapi10.c + Routines lpx_eval_tab_row and lpx_eval_tab_col were replaced by + glp_eval_tab_row and glp_eval_tab_col. + + * glpios03.c, glpios05.c + Gomory's mixed integer cuts were implemented. + + * glpscs.h, glpscs.c + Segmented character string routines are no longer used and were + removed from the package. + +Wed Nov 21 12:00:00 2007 Andrew Makhorin + + * GLPK 4.24 (9:0:9) has been released + + * src/glplpx16.c + A bug was fixed in the routine lpx_write_cpxlp. If a variable + x has upper bound and no lower bound, it should appear in the + bounds section as "-inf <= x <= u", not as "x <= u". Thanks to + Enric Rodriguez for the bug report. + + * src/glpios03.c, src/glpios04.c, src/glpios05.c + MIR (mixed integer rounding) cuts were implemented. + +Sun Oct 28 12:00:00 2007 Andrew Makhorin + + * GLPK 4.23 (8:0:8) has been released + + * src/glplib05.c, configure.ac + Check for vsnprintf was added. + + * include/glppds.h, src/glppds.c + A module to scan plain data was added. + + * src/glpapi09.c + The following new API routines were added: + glp_read_sol read basic solution from text file; + glp_write_sol write basic solution to text file; + glp_read_ipt read interior-point solution from text file; + glp_write_ipt write interior-point solution to text file; + glp_read_mip read MIP solution from text file; + glp_write_mip write MIP solution to text file. + + * src/glpapi12.c + Advanced API routine glp_free_env was added. + + * examples/glpsol.c + The following three command-line options were added: + --mipgap tol set relative MIP gap tolerance + -r filename read solution from filename + -w filename write solution to filename + +Wed Sep 19 12:00:00 2007 Andrew Makhorin + + * GLPK 4.22 (7:0:7) has been released + + * src/glpios02.c + A bug was fixed in the MIP preprocessor (ios_preprocess_node). + Thanks to Roberto Bagnara (Department of + Mathematics, University of Parma, Italy) for the bug report. + + * src/glpios02.c + A bug was fixed in the MIP preprocessor (col_implied_bounds), + due to which constraint coefficients with small magnitude could + lead to wrong implied bounds of structural variables. + + * src/glpipp02.c + A similar bug was fixed in the routine reduce_bounds. + + * src/glpapi01.c + A bug was fixed in the routines glp_set_mat_row and + glp_set_mat_col. (The bug appeared due to incorrect removing + zero elements from the row/column lists.) + + * src/glplpx14.c + A bug was fixed in the API routines lpx_read_mps and + lpx_read_freemps, due to which bounds of type LI specified in + BOUNDS section were incorrectly processed. + + * src/glplib05.c + A call to standard function vsprintf was replaced by a call to + vsnprintf for security reasons. Many thanks to Peter T. Breuer + and Rafael Laboissiere . + +Tue Aug 28 12:00:00 2007 Andrew Makhorin + + * GLPK 4.21 (6:0:6) has been released + + * glpscg.h, glpscg.c + Routines to maintain sparse cliqued graph were added. + + * glpios02.c + MIP preprocessing routines were added. + + * glpk.h, glpios.h, glpios03.c + New reasons for calling the callback routine were introduced + in the MIP solver. + + * glpapi08.c + Default backtracking strategy was changed to best local bound. + + * glpapi11.c + New API routine glp_term_out to enable/disable terminal output + was added. + + * glprng.h, glprng02.c + Two routines to generate uniformly distributed pseudo-random + floating-point numbers were added. + +Thu Jul 26 12:00:00 2007 Andrew Makhorin + + * GLPK 4.20 (5:0:5) has been released + + * glpk.h, glpapi08.c + The routine lpx_integer was replaced by an equivalent routine + glp_intopt. Also new API routine glp_init_iocp was added. + + * glpiet.h, glpiet.c + Routines implementing the implicit enumeration tree are + no longer used and therefore were removed from the package. + + * glpios.h, glpios01.c, glpios02, glpios03 + Routines implementing the integer optimization suite being + replaced by a new version were removed from the package. + + * glpmip.h, glpmip01.c, glpmip02.c + + Routines implementing the B&B method being replaced by a new + version were removed from the package. + + * glpios.h, glpios01.c, glpios02.c + + Routines implementing a new version of the integer optimization + suite (IOS) based on the B&B method were added to the package. + + * glpk.h, glpapi10.c + Branch-and-bound interface routines were added to the package. + + * examples/tspsol.c + The TSP solver based on old version of the integer optimization + suite is no more supported and was removed from the package. + + * glpipp02.c + An error in the routine reduce_bounds was fixed; thanks to + Graham Rockwell for the bug report. + + * glpk.latex + A new edition of the reference manual was included. + +Thu Jul 05 12:00:00 2007 Andrew Makhorin + + * GLPK 4.19 (4:0:4) has been released + + The principal change is upgrading to GPLv3. + + * glpapi01.c + A serious bug in the routine glp_del_cols was fixed; thanks to + Cedric[FR] for the bug report. The bug + appeared because on deleting non-basic columns the basis header + remained valid, however, contained invalid (old) column ordinal + numbers. + + * glpapi10.c + A new advanced API routine glp_mem_limit was added. + + * glplpx01.c + The case GLP_EBOUND was added to the routine lpx_simplex. + Thanks to Cameron Kellough for the + bug report. + + * glplpx19.c + An API routine lpx_write_pb to write the problem instance in + OPB (pseudo boolean) format format was added. Thanks to Oscar + Gustafsson for the contribution. + + * glpsol.c + Two new options --wpb and --wnpb were added to glpsol to write + the problem instance in OPB format. + +Mon Jun 25 12:00:00 2007 Andrew Makhorin + + * GLPK 4.18 (3:0:3) has been released + + * glplib.h + Type names ulong_t and uldiv_t were changed to glp_ulong and + glp_uldiv to avoid conflicts with standard type names on some + platforms. Thanks to Boris Wirtz + for the bug report. + + * glpbfd.*, glpfhv.*, glplpf.* + LP basis factorization routines were made tidy. + + * glpk.h, glpapi04.c + The following API routines were added: + glp_set_rii, glp_set_sjj, glp_get_rii, glp_get_sjj. + + * glpk.h, glpapi06.c + The routine lpx_simplex was replaced by an equivalent routine + glp_simplex. Also new API routine glp_init_smcp was added. + + * glpk.h, glpapi09.c + The following advanced API routines were added: + glp_bf_exists, glp_factorize, glp_bf_updated, glp_get_bfcp, + glp_set_bfcp, glp_get_bhead, glp_get_row_bind, glp_get_col_bind, + glp_ftran, glp_btran. + + * glpk.latex + A new edition of the reference manual was included. + + * examples/dea.mod, examples/food.mod, examples/food2.mod + Three examples in the MathProg language were added. + Thanks to Sebastian Nowozin . + +Sat May 26 12:00:00 2007 Andrew Makhorin + + * GLPK 4.17 (2:0:2) has been released + + * glpdmp.h, glpdmp.c + Memory pool routines were replaced by a new version. + + * glpscs.h, glpscs.c + Segmented string routines were replaced by a new version. + + * glplpx08.c, glplpx09.c + Now the MIP problem may have no integer columns. + + * glpapi01.c + The routines glp_set_mat_row, glp_set_mat_col, and glp_load_mat + were modified to allow zero elements (which are not stored in + the constraint matrix). + + * glpscf.h, glpscf.c + Schur complement factorization routines were implemented. + + * glplpf.h, glplpf.c + LP basis factorization routines based on LU-factorization and + Schur complement were implemented. + + * glplpx02.c, glplpx03.c + New control parameter LPX_K_BFTYPE was introduced to choose the + basis factorization type used by the simplex method routines. + + * glpsol.c + Three new command-line options were added to choose the basis + factorization type used by the simplex method routines: --luf, + --cbg, and --cgr. + + * glpk.latex + A new edition of the reference manual was included. + +Sat May 05 12:00:00 2007 Andrew Makhorin + + * GLPK 4.16 (1:0:1) has been released + + * glpk.h, glpapi.c, glplpx01.c, glplpx02.c + Names of a number basic api routines were changed and now have + the prefix 'glp_'. To keep backward compatibility these routines + are also available via their old names prefixed with 'lpx_'. + + * glplpx19.c + Three new api routines were added: glp_version, glp_term_hook, + and glp_mem_usage. + + * glpk.latex, gmpl.texi + A new edition of the reference manuals was included. + + * lpglpk40.c + This example program is no longer supported and therefore was + removed from the package. + +Sun Feb 18 12:00:00 2007 Andrew Makhorin + + * GLPK 4.15 (0:0:0) has been released + + * configure.ac, Makefile.am + Autotools specification files were changed to use GNU Libtool + that allows building the static as well as shared GLPK library. + Thanks to Rafael Laboissiere . + +Mon Feb 05 08:00:00 2007 Andrew Makhorin + + * GLPK 4.14 has been released + Now GLPK conforms to ILP32, LLP64, and LP64 programming models + (the latter seems to be the ultimate choice regarding 64-bit + architectures). Note that GLPK itself is a 32-bit application, + and the conformity only means that the package works correctly + on all these arenae. Nevertheless, on 64-bit platforms it is + possible to use more than 4GB of memory, if necessary. + + * Makefile + Starting from this release only the header glpk.h is needed to + be installed. + + * glplib01.c + Two routines bigmul and bigdiv which performs multiplication + and division of unsigned integers of arbitrary precision were + added. + + * glplib02.c + A set of 64-bit arithmetic routines were added. + + * glplib04.c + Some low-level library routines were improved and renamed. + + * glpcfg.h + The macro GLP_TM_SPEC were introduced to specify a version of + the time routine depending on the host environment. + +Mon Nov 13 12:00:00 2006 Andrew Makhorin + + * GLPK 4.13 has been released + + * configure.in + '-lm' bug was fixed. + + * glpbfx.h, glpbfx.c + Basis factorization interface routines based on exact (bignum) + arithmetic were implemented. + + * glpssx.h, glpssx1.c, glpssx2.c + Simplex method routines based on exact (bignum) arithmetic were + implemented. + + * glplpx6e.c + The routine lpx_exact, which is an easy-to-use driver to the + exact simplex method, was added. + + * glpsol.c + Two command-line options were added: '--exact' and '--xcheck'. + +Wed Nov 08 12:00:00 2006 Andrew Makhorin + + * GLPK 4.12 has been released + + * glpcfg.h + The package configuration file was added. + + * glplib2.c + Alternative version of the routines umalloc, ucalloc, and ufree + was provided. It does not limit the amount of allocated memory + to INT_MAX bytes and therefore can be used on platforms where + sizeof(void *) > sizeof(int). To enable this version one should + define the preprocessor variable GLP_HUGE_MEM. + + * glprng.c + The routine rng_create_rand was changed to initialize the + generator using seed = 1, not 0, to conform ISO C requirements. + + * glpgmp.h, glpgmp.c + A set of bignum arithmetic routines implementing operations on + integers and rationals was added. These routines are compatible + with the GNU MP library. + + NOTE: To attain a much better performance it is recommended to + use, if possible, the original GNU MP library rather than the + GLPK version, by defining the preprocessor variable GLP_USE_GMP. + + * glplux.h, glplux.c + A tentative implementation of sparse LU-factorization based on + exact (bignum) arithmetic was added. + + * glpssx.h, glpssx.c + A tentative implementation of some simplex method routines based + on exact (bignum) arithmetic was added. + + * glplpx6f.c + A preliminary implementation of the routine lpx_exact_check was + added. This routine checks the current basis for primal and dual + feasibility using exact (bignum) arithmetic. + + * examples/glpsol.c + The command-line option '--xcheck' was introduced to check the + current basis for feasibility using exact (bignum) arithmetic. + +Tue Jul 25 12:00:00 2006 Andrew Makhorin + + * GLPK 4.11 has been released. + + * include/glpbfi.h, src/glpbfi.c + Basis factorization interface routines were added. + + * include/glpluf.h, src/glpluf1.c + Hypersparse solution routines were added. + + * include/glpinv.h, src/glpinv1.c + Hypersparse solution routines (fake version) were added. + + * include/glpmpl.h, src/glpmpl.c + Built-in functions card, length, and substr were implemented. + Output redirection in the printf statement was implemented. + + * examples/graph.mod, examples/crypto.mod + Two example models illustrating new features of the modeling + language were included. + +Thu May 11 12:00:00 2006 Andrew Makhorin + + * GLPK 4.10 has been released. + + * src/glplpx8a.c + A fragment was added to the routines lpx_read_mps and + lpx_read_freemps to accept LI bound type (it is similar to LO, + however, additionally marks the column as integer). + + * include/glpbfi.h, src/glpbfi.c + The module glpbfi which implements the basis factorization + interface (BFI) was added. + + * src/glplpx7a.c + The routine lpx_cover_cut to generate mixed cover cuts was + added. + + * src/glplpx7b.c + The routine lpx_clique_cut to generate clique cuts and related + routines to maintain the conflict graph were added. + + * include/glplpx.h, src/glplpx5.c + The routine lpx_cpx_basis implementing Bixby's algorithm to + construct an initial LP basis was added. + + * examples/glpsol.c + Command-line option '--bib' was added which allows building + an initial LP basis using Bixby's algorithm. + Default command-line option '--mps' was changed to '--freemps'. + + * examples/cf12a.mod, examples/cf12b.mod + Two examples in MathProg (curve fitting problem) were added. + Thanks to Dr. Harley Mackenzie . + +Tue Jan 17 12:00:00 2006 Andrew Makhorin + + * GLPK 4.9 has been released. + + * glpipp.h, glpipp1.c, glpipp2.c + A MIP presolver were implemented (currently incomplete). It is + used internally in the routine lpx_intopt (see below). + + * glplpx6d.c, glplpx7a.c + An advanced branch-and-bound solver (the routine lpx_intopt) + were implemented. + + * glplpx6c.c + The routine lpx_check_int to check MIP feasibility conditions + was added. + + * glplpx8a.c + The routine lpx_print_mip was changed to print MIP feasibility + conditions. + + * glpmpl.h, glpmpl1.c, glpmpl3.c + The built-in functions sin, cos, atan, and atan2 were added to + the MathProg language. + + * doc/lang.* + Some typos were fixed. + Thanks to Minh Ha Duong (CIRED, CNRS). + +Wed Jan 12 12:00:00 2005 Andrew Makhorin + + * GLPK 4.8 has been released. + + * glpspx.h, glpspx1.c, glpspx2.c, glplpx6a.c + Simplex method routines were changed due to a new format of the + constraint matrix. + + * glpmat.h, glpmat.c + Sparse matrix routines were re-implemented using storage-by-rows + format. + + * glpipm.h, glpipm.c, glplpx6b.c + Interior-point method routines were changed due to a new format + of sparse matrices. + + * glpchol.h, glpchol.c + Old version of Cholesky factorization routines being replaced by + a new one (see glpmat.c) was removed from the package. + + * glplpx8c.c + Minor bug was fixed in api routine lpx_read_cpxlp. + +Mon Aug 23 12:00:00 2004 Andrew Makhorin + + * GLPK 4.7 has been released. + + * glplpx.h, glplpx1.c + New core API routines were added (but not documented yet): + lpx_order_matrix, lpx_create_index, lpx_find_row, lpx_find_col, + lpx_delete_index. + + * glplpx8a.c + API routine lpx_read_mps was re-implemented, and two new API + routines lpx_read_freemps and lpx_write_freemps were added to + support free MPS format. + + * glplpx8c.c + Two API routines lpx_read_cpxlp and lpx_write_cpxlp (formerly + named lpx_read_lpt and lpx_write_lpt) were re-implemented. + + * glpmps.h, glpmps.c + This module formerly used in lpx_read_mps was removed from the + package. + + * glplpt.h, glplpt.c + This module formerly used in lpx_read_lpt was removed from the + package. + + * glpmip.h, glpmip1.h, glpmip2.h + New MIP routines mip_best_node and mip_relative_gap were added + due to suggestion of Brady Hunsaker . + + * glpsol.c + The following new command-options were added: + --freemps to read problem data in free MPS format + --wfreemps to write problem data in free MPS format + --cpxlp to read problem data in CPLEX LP format + --wcpxlp to write problem data in CPLEX LP format + --bas to read LP basis from a text file in MPS format + --wbas to write LP basis to a text file in MPS format + --mostf to use "most fractional" branching heuristic + --bestb to use "best bound" backtracking heuristic + + * contrib/deli/*.* + GLPK Delphi interface module was temporarily removed from the + distribution due to licensing problems. + + * contrib/glpkmex/*.* + GLPK Matlab interface module was temporarily removed from the + distribution due to licensing problems. + + * contrib/jni/*.* + GLPK Java interface module was temporarily removed from the + distribution due to licensing problems. + +Wed Aug 04 12:00:00 2004 Andrew Makhorin + + * GLPK 4.6 has been released. + + * glpmpl.h, glpmpl1.c, glpmpl2.c, glpmpl3.c, glpmpl4.c + Three new statements were implemented in the GNU MathProg + language: solve, printf, and for. Also some bugs were fixed. + + * glplpx.h, glplpx8e.c + Two API routines were added: lpx_read_prob and lpx_write_prob, + which allow reading and writing problem data in GNU LP format. + + * glpsol.c + Three new command-line options were added: --glp (to read + problem data in GNU LP format), --wglp (to write problem data + in GNU LP format), and --name (to change problem name). + + * glprng.h, glprng.c + A portable pseudo-random number generator was implemented as a + separate module. + + * glplib4.c + The old implementation of a pseudo-random number generator was + removed from the package. + + * doc/lang.*, doc/refman.* + New edition of the GLPK documentation was included. + + * contrib/glpkmex/*.* + A new version of GLPKMEX was included in the distribution. For + more details see contrib/glpkmex/ChangeLog. + +Mon Jul 19 12:00:00 2004 Andrew Makhorin + + * GLPK 4.5 has been released. + + * glpmip.h, glpmip1.c, glpmip2.c, glplpx6c.c + New implementation of the branch-and-bound method was added. + It replaces the old implementation, which was removed from the + package. + + * glpies.h, glpies1.c, glpies2.c, glpies3.c + Modules used in the old implementation of the branch-and-bound + method were removed from the package. + + * glplib2.c + Now if the preprocessor variable GLPHUGEMEM is defined, other + version of the routines umalloc, ucalloc, and ufree is used on + compiling the package. This allows avoiding memory allocation + problems on platforms where sizeof(void *) > sizeof(int), for + example, where addresses are 64-bit while integers are 32-bit. + The modification was made due to a bug report provided by Karel + Zimmermann and Christophe Caron + . + +Sat Jan 17 12:00:00 2004 Andrew Makhorin + + * GLPK 4.4 has been released. + + * glplpx.h, glplpx*.c + All API routines were re-implemented using new data structures. + Some new API routines were added and some existing API routines + became obsolete as shown below: + + Obsolete API routine Equivalent new API routine + lpx_check_name (no more supported) + lpx_set_obj_c0 lpx_set_obj_coef + lpx_set_row_coef (no more supported) + lpx_set_col_coef lpx_set_obj_coef + lpx_load_mat (no more supported) + lpx_load_mat3 lpx_load_matrix + lpx_unmark_all (no more supported) + lpx_mark_row (no more supported) + lpx_mark_col (no more supported) + lpx_clear_mat (no more supported) + lpx_del_items lpx_del_rows, lpx_del_cols + lpx_get_row_bnds lpx_get_row_type, lpx_get_row_lb, + lpx_get_row_ub + lpx_get_col_bnds lpx_get_col_type, lpx_get_col_lb, + lpx_get_col_ub + lpx_get_obj_c0 lpx_get_obj_coef + lpx_get_row_coef (no more supported) + lpx_get_col_coef lpx_get_obj_coef + lpx_get_row_mark (no more supported) + lpx_get_col_mark (no more supported) + lpx_get_row_info lpx_get_row_stat, lpx_get_row_prim, + lpx_get_row_dual + lpx_get_col_info lpx_get_col_stat, lpx_get_col_prim, + lpx_get_col_dual + lpx_get_ips_stat lpx_ipt_status + lpx_get_ips_row lpx_ipt_row_prim, lpx_ipt_row_dual + lpx_get_ips_col lpx_ipt_col_prim, lpx_ipt_col_dual + lpx_get_ips_obj lpx_ipt_obj_val + lpx_get_mip_stat lpx_mip_status + lpx_get_mip_row lpx_mip_row_val + lpx_get_mip_col lpx_mip_col_val + lpx_get_mip_obj lpx_mip_obj_val + + Obsolete API routines were kept for backward compatibility, + however, they will be removed in the future. + + * doc/refman.* + New edition of the GLPK reference manual containing description + of all new API routines was included. + + * contrib/glpkmex/*.* + GLPKMEX, a Matlab MEX interface to GLPK package, contributed by + Nicolo Giorgetti was included. + + * doc/GLPK_FAQ.txt + GLPK FAQ contributed by Harley Mackenzie was + included. + +Fri Dec 12 12:00:00 2003 Andrew Makhorin + + * GLPK 4.3 has been released. + + * configure.in + The bug, due to which the standard math library is not linked on + some platforms, was fixed. + + * glpmpl3.c + The bug (0 ** y) was fixed in the routine fp_power. + + * glpmpl.h, glpmpl1.c, glpmpl3.c + Some new built-in functions (round, trunc, Irand224, Uniform01, + Uniform, Normal01, Normal) were added to the MathProg language. + + * glpmpl1.c + The MathProg syntax was changed to allow writing 'subj to'. + + * glplpx.h, glplpx1.c, glplpx2.c + The new api routine lpx_get_ray_info was added. + + * glplpx8a.c + The api routine lpx_print_sol was changed to print the number of + non-basic variable, which causes primal unboundness. + + * glpmps.c + The code was changed to avoid errors on compiling the package on + Mac OS X. Thanks to Andre Girard for + the bug report. + + * doc/lang.*, doc/refman.* + Several typos were fixed and some new material was added in the + glpk documentation. + +Fri Nov 14 12:00:00 2003 Andrew Makhorin + + * GLPK 4.2 has been released. + + * glpiet.h, glpiet.c, glpios.h, glpios1.c, glpios2.c, glpios3.c + A preliminary implementation of the Integer Optimization Suite + (IOS) was included in the package. Eventually IOS will replace + the Implicit Enumeration Suite (IES). + + * glplpx.h, glplpx6d.c + A dummy version of the integer optimization routine lpx_intopt + was included in the package. Later this routine will replace the + routine lpx_integer. + + * examples/glpsol.c + A new command-line option --int-opt was added to the solver to + call lpx_intopt rather than lpx_integer. + + * glpbcs.h, glpbcs1.c, glpbcs2.c + Being replaced by IOS routines (see above) the Branch-and-Cut + Framework (BCS) routines were removed from the package. + + * examples/tspsol.c + Stand-alone Symmetric TSP solver was completely re-programmed + using IOS routines. + + * glplib.h, glplib2.c, glplib4.c + The random-number generator was implemented. It is based on the + module GB_FLIB from the Stanford GraphBase originally developed + by Donald Knuth. + + * glphbsm.c, glplpx8a.c, glpmps.c + All calls to fopen/fclose were replaced by corresponding calls + to ufopen/ufclose due to bug reports provided by Morten Welinder + and . + + * glpmps.c + The code was made re-entrant. + + * glplpx8b.c + API routine lpx_print_sens_bnds for bounds sensitivity analysis + contributed by Brady Hunsaker was added + to the package. This feature is also available in glpsol via the + command-line option --bounds. + + * contrib/jni/*.* + New version of GLPK JNI (Java Native Interface) contributed by + Chris Rosebrugh was added to the package. + + * contrib/deli/*.* + GLPK DELI (Delphi Interface) contributed by Ivo van Baren + was added to the package. + + * glplpx3.c + Default method to scale the problem was changed to equilibration + scaling (lp->scale = 1 in lpx_reset_parms). + + * glplpx6a.c + Two minor (non-critical) typos were fixed due to report provided + by Andrew Hamilton-Wright . + + * glplpp2.c + An untested case (line 941) had been tested due to bug report + provided by Jiri Spitz . + + * w32bc5.mak, w32vc6.mak, w32vc6d.mak, d32dmc.mak + Several makefiles were added to allow building GLPK library for + some non-GNU 32-bit platforms. + +Sat Aug 23 12:00:00 2003 Andrew Makhorin + + * GLPK 4.1 has been released. + + * glpmpl1.c, glpmpl3.c + Some bugs were fixed in the MathProg translator due to the bug + reports provided by Giles Thompson : + conditional set expressions were incorrectly parsed; + dimen attribute was not set by default when a set was used + recursively in its own declaration; + logical expressions ... in if ... then ... else ... did not + work; + displaying set expressions did not free memory allocated for + temporary results. + + * glpmpl3.c (reduce_terms) + Implementation of summation of linear forms over domain was + improved to reduce complexity of that operation from O(n*n) to + O(n*log n). The improvement was made due to a report provided + by Sebastien de Menten . + + * glplpx6a.c (line 1056), glpmip1.c (line 641) + Two minor bugs were fixed due to the bug report provided by + Kendall Demaree . + + * glplpx.h, glplpx6a.c + The method of one artificial variable implemented in the routine + lpx_prim_art and used on the phase I in the glpk simplex solver + has a serious defect: for some lp instances it erroneously + reports that the problem has no primal feasible solution. This + error appears when the column of the artificial variable, which + enters the basis to make it primal feasible, has large + constraint coefficients, that leads to small reduced costs of + non-basic variables and premature termination of the search, + i.e. to wrong conclusion that the problem has no primal feasible + solution. To avoid this defect the routine lpx_prim_feas was + included. It implements the method of implicit artifical + variables (based on minimization of the sum of infeasibilities), + which is a bit slower but much more robust. The routine + lpx_prim_feas having the same functionality now is used instead + the routine lpx_prim_art. + + * glpinv.h, glpinv.c + The test used in the routine inv_update to detect low accuracy + after updating LU-factorization of the basis matrix was replaced + by a new, more robust test. + + * glplpx6c.c + Selecting an active node to be solved next in the routine + btrack_bestp was changed. Now, if any integer feasible solution + has not been found yet, the routine chooses an active node which + has the minimal sum of integer infeasibilities. + + * glpmip.h, glpmip1.c + The additional flag int_obj was included in the structure + MIPTREE used by the branch-and-bound. This flag is set in the + routine mip_create_tree and used in the routine is_better. It + means that the objective is integral, i.e. depends only on + integer variables with integer objective coefficients. The test + used in the routine check_integrality was also replaced by a + new, more reasonable one. + + * glplpx1.c + A minor bug was fixed in the routine lpx_check_name. + + * glpmpl.h, glpmpl4.c, glplpx8d.c + The flag skip_data was added to the parameter list of the + routine mpl_read_model. If this flag is set, the data section + in the model file is ignored. Corresponding change was made in + the routine lpx_read_model. Now, if both model and data files + are specified, the data section in the model file is ignored. + + * glplpx8c.c + A minor bug (wrong format used for writing free columns) in the + routine lpx_write_lpt was fixed due to the bug report provided + by Bernhard Schmidt + + * sample/glpsol.c + The command-line parameter --tmlim, which allows limiting the + solution time, was added. + + * doc/lang.*, doc/refman.* + New edition of the GLPK documentation was included. + + * java-binding/*.* + New version of the GLPK JNI (Java Native Interface) package was + included in the distribution. + + * sample/lpglpk40.c + A non-trivial example was added. It allows using GLPK as a base + LP solver for Concorde, a program for solving Traveling Salesman + Problem (TSP). For details see comments in lpglpk40.c. + + * sample/*.mod + Some examples of LP and MIP models written in GNU MathProg were + added. + +Tue May 06 12:00:00 2003 Andrew Makhorin + + * GLPK 4.0 has been released. + + * glpmpl.h, glpmpl1.c, glpmpl2.c, glpmpl3.c, glpmpl4.c + The model translator for the GNU MathProg modeling language was + implemented and included in the package. + + * glplpx.h, glplpx8d.c + The api routine lpx_read_model, which is an interface to the + MathProg translator, was included in the package. + + * glplpx.h, glplpx8a.c + The api routine lpx_print_prob for writing LP/MIP problem data + in plain text format was included in the package. + + * sample/glpsol.c + New version of the GLPK stand-alone LP/MIP solver that supports + the GNU MathProg modeling language was implemented. + + * doc/lang.latex, doc/lang.dvi, doc/lang.ps + The document "GLPK: Modeling Language GNU MathProg" was included + in the package. + + * doc/refman.latex, doc/refman.dvi, doc/refman.ps + New edition of the GLPK Reference Manual was included in the + package. + + * glplpx8c.c + A bug in the api routine lpx_write_lpt was fixed. Due to that + bug an addressing error occured in the routine if the objective + function has the non-zero constant term. + + * glplan.h, glplan1.c, glplan2.c, glplan3.c, glplan4.c, + * glplan5.c, glplan6.c, glplan7.c, glplan8.c, glplpx8b.c + All modules of the translator for the GLPK/L modeling language + were removed from the package, because GLPK/L being completely + superseded by GNU MathProg is no more supported. + +Tue Mar 25 12:00:00 2003 Andrew Makhorin + + * GLPK 3.3 has been released. + + * glplpp.h, glplpp1.c, glplpp2.c + An implementation of the built-in LP presolver was added to the + package. + + * glplpx.h + The flag presol was added to the structure LPX. This flag tells + the lpx_simplex whether the built-in LP presolver should be used + or not. By default this flag is off. Also three macros (namely + LPX_E_NOPFS, LPX_E_NODFS, and LPX_K_PRESOL) that concern using + the LP presolver were introduced. + + * glplpx3.c, glplpx6a.c + These modules was changed to use the built-in LP presolver. + + * sample/glpsol.c + Command line options --presol and --nopresol that concern using + the LP presolver were added to the stand-alone LP/MIP solver. + + * glplan1.c + This module was changed to allow declaring sets like A[1:10] in + the models written in the GLPK/L modeling language. + + * doc/refman.latex, doc/lang.latex + New editions of the documents "GLPK User's Guide" and "GLPK/L + Modeling Language" were included in the distribution. + + * java-binding/*.* + The package GLPK JNI (Java Native Interface) implementing Java + binding for GLPK was included in the distribution. This package + was developed and programmed by Yuri Victorovich . + +Tue Feb 18 12:00:00 2003 Andrew Makhorin + + * GLPK 3.2.4 has been released. + + * glplpx6b.c + The code was changed to allow auxiliary variables have non-zero + objective coefficients. + + Also a minor bug was fixed (the constant term was not considered + on displaying the objective function value). + + * sample/glpsol.c + The code was changed to fix a bug (the command-line option 'bfs' + was not recognized). The bug was fixed due to report provided by + Olivier . + + * glplpt.c + The code was changed to fix a bug (binary variables were treated + erroneously as integer ones). + + * glplpx6b.c + The code was changed to fix a bug (variables that have no lower + bounds were incorrectly processed on converting to the standard + formulation). The bug was fixed due to report kindly provided by + Kjell Eikland . + +Mon Nov 11 12:00:00 2002 Andrew Makhorin + + * GLPK 3.2.3 has been released. + + * glpmip.h, glpmip1.c + A preliminary implementation of the branch-and-bound driver + based on the implicit enumeration suite (glpies) was added to + the package. This module is not documented yet. + + * glplpx6c.c + A new implementation of the api routine lpx_integer which now + is based on the b&b driver (see glpmip above) was included in + the package. This new implementation has exactly the same + functionality as the old version and therefore all changes are + transparent to the api user. + + * glpbbm.h, glpbbm.c + * glprsm.h, glprsm1.c, glprsm2.c + * glplp.h, glplp.c + These modules were removed from the package, because they were + used only in the old version of the routine lpx_integer, which + was replaced by the new version (see glplpx6c above). + + * glplpx.h, glplpx6a.c + The api routine lpx_check_kkt was included in the package and + its description was added in the reference manual. This routine + allows checking Karush-Kuhn-Tucker optimality conditions for an + LP solution. + + * glplpx.h, glplpx8a.c + Now the api routine lpx_print_sol also prints information about + "solution quality" obtained via the api routine lpx_check_kkt. + + * glplpx.h, glplpx8a.c + New api routines lpx_read_bas and lpx_write_bas were included + in the package and documented. The routine lpx_write_bas allows + writing a current basis from an LP object to a text file in the + MPS format. The routine lpx_read_bas allows reading a basis + prepared in the MPS format from a text file into an LP object. + + * glplpt.c + The parsing routine which reads LP problem data prepared in the + CPLEX LP format was modified to allow specifying lower bounds + of variables also in the form 'variable >= lower bound' (in the + bounds section). This modification was made due to a notice + provided by Ivan Luzzi . + + * glplpx.h, glplpx8c.c + The api routine lpx_write_lpt which allows writing LP problem + data from an LP object to a text file using the CPLEX LP format + was included in the package and documented. + + * glplpx.h, glplpx3.c + The control parameter LPX_K_LPTORIG that affects the behavior + of the api routine lpx_write_lpt was introduced. + + * glplan6.c + The semantics of the language GLPK/L was changed to allow + selection in case when not all mute letters of a predicate (the + operand that follows the keyword 'where') are presented in a + parameter (the operand that precedes the keyword 'where'), i.e. + to allow writing something like this: + y[j] := sum(i, x[i] where p[i,j]); + The paragraph "Selection" in the langauge description (page 25) + was also correspondingly changed. This change of the language + semantics was undertaken due to a notice provided by Peter Lee + . + + * sample/hwd.lpm + A nice example of LP model written in GLPK/L and contributed by + Peter Lee was included in the package. + + * glplpx6b.c + The api routine lpx_interior was modified: a) to compute dual + values for all structural as well as auxiliary variables; b) to + allow specifying non-zero objective coefficients at auxiliary + variables. + + * sample/glpsol.c + Three new command-line options were added to the solver, which + are: --plain, --orig, and --wrlpt. + +Mon Oct 14 12:00:00 2002 Andrew Makhorin + + * GLPK 3.2.2 has been released. + + * glplpt.h, glplpt.c + A module that reads LP/MIP problem data in CPLEX LP format was + implemented. + + * glplpx8c.c + An api routine lpx_read_lpt that reads LP/MIP problem data in + CPLEX LP format was implemented. + + * sample/glpsol.c, sample/plan.lpt + A new command-line option '--lpt' that allows reading LP/MIP + problem data in CPLEX LP format was added to the solver. + + * doc/refman.latex, doc/refman.dvi, doc/refman.ps + A new edition of the Reference Manual was included. + + * source/*.c + Casting to (unsigned char) was added in some calls to the + classification functions (isalpha, etc.). The bug was fixed due + to report provided by Morten Welinder . + + * glplpx8a.c + The local routine mps_numb used in the routine lpx_write_mps + was modified to correctly format floating-point numbers that + have two digits in the decimal exponent. The bug was fixed due + to report provided by Vlahos Kiriakos . + + * glplan.h, glplan1.c, ..., glplan8.c + Several serious bugs were fixed in the language processor due + to reports provided by : + (a) a static search tree used to find sparse array elements was + sometimes overwritten that caused the message 'assertion failed' + to appear; the bug was fixed by creating separate search trees + in parsing routines; (b) a variable declared using the + predicate-controlled variable declaration statement had wrong + order of domain sets, because the variable array was built as + a copy of the predicate array; the bug was fixed by using the + internal routine transpose that coordinates mute letters (and + therefore domain sets) on copying sparse arrays; (c) sometimes + assignment statements like x[#a,#b,#c] := ... was incorrectly + processed; the bug was fixed by including an appropriate check + into the internal routine assign_stmt. + + * glp_simplex.c + An additional check to see if all lower bounds are not greater + than corresponding upper bounds was included in the routine to + prevent wrong results to appear. Such incorrectness sometimes + was not detected, namely, when variables with such bounds were + non-basic and never entered the basis. + + * glpspx1.c + Maximal number of simplex iterations before reinversion was + decreased from 100 to 50. This allowed to improve accuracy and, + that is more important, to reduce the solution time for many + serial lp problems approximately 1.5--2 times. + + * glpspx2.c + A check to see if all elements in the column chosen to enter + the basis are close to zero in the routine spx_prim_chuzr was + temporarily removed because this check gave wrong conclusion in + case when the corresponding non-basic variable had zero column + in the constraint matrix. An analogous check to see if all + elements in the row chosen to leave the basis are close to zero + in the routine spx_dual_chuzc was also temporarily removed on + the same reason. The bug was fixed due to reports provided by + Flavio Keidi Miyazawa and Vlahos Kiriakos + . + +Mon Aug 12 12:00:00 2002 Andrew Makhorin + + * GLPK 3.2.1 has been released. + + * glpbcs.h, glpbcs1.c, glpbcs2.c + * glpies.h, glpies1.c, glpies2.c, glpies3.c + A preliminary implementation of the branch-and-cut framework + was included in the package. + + * doc/brcut.txt + The document "GLPK: A Preliminary Implementation of the + Branch-And-Cut Framework" was included in the distribution. + + * sample/tspsol.c + An illustrative program for solving symmetric TSP based on the + branch-and-cut method was included in the package. + + * glpdmp.h, glpdmp.c + A new, re-enterable version of routines for managing dynamic + memory pools was included in the package. + + * glpavl.h, glpavl.c + A new, re-enterable version of routines for managing AVL search + trees was included in the package. + + * glplib.h, glplib2.c + Two new low-level routines ufopen and ufclose were included in + the package. + + * glplpx.h, glplpx7.c + The following new api routines were added: lpx_eval_activity, + lpx_eval_red_cost, lpx_reduce_form, lpx_mixed_gomory. + + * glptsp.h, glptsp.c + A module for reading TSP data using TSPLIB format was included + in the package. + +Mon Jul 15 12:00:00 2002 Andrew Makhorin + + * GLPK 3.2 has been released. + + * glplpx.h, glplpx1.c, glplpx2.c + The identifier 'class' (used as a member name in the structure + LPX and as an argument name in the routine lpx_set_class) was + changed to 'clss' in order to avoid conflicts with C++ reserved + words. + + * glpk.h, glplpx.h, glplpx1.c, glplpx2.c, glplpx6a.c, + * glplpx6b.c, glplpx6c.c, glplpx7.c, glplpx8.c + The following new api routines were added: lpx_set_obj_name, + lpx_get_obj_name, lpx_get_row_mark, lpx_get_col_mark, + lpx_transform_row, lpx_transform_col, lpx_prim_ratio_test, + lpx_dual_ratio_test, lpx_interior, lpx_get_ips_stat, + lpx_get_ips_row, lpx_get_ips_col, lpx_get_ips_obj, lpx_read_lpm, + lpx_write_mps, lpx_print_ips. + + * glpsol.c + The solver was completely re-programmed using new api routines. + + * lang.latex, lang.dvi, lang.ps + New edition of the document "GLPK: Modeling Language GLPK/L" + was included in the distribution. + + * refman.latex, refman.dvi, refman.ps + New edition of the document "GLPK: Reference Manual" (which + contains descriptions of all new api routines) was included in + the distribution. + + * glpapi.h, glpapi1.c, glpapi2.c, glpapi3.c, glpapi4.c + These files (which contain old api routines) were removed from + the package. + + * glpipm1.c, glpipm2.c + The file glpipm1.c was renamed to glpipm.c. The file glpipm2.c + was used only by old api routines and therefore was removed from + the package. + + * language.texinfo + Old version of the document "GLPK: Modeling Language GLPK/L" was + removed from the distribution. + +Mon May 27 12:00:00 2002 Andrew Makhorin + + * GLPK 3.1 has been released. + + * glplpx.h, glplpx1.c, glplpx2.c, glplpx3.c, glplpx4.c, + * glplpx5.c, glplpx6.c, glplpx7.c, glplpx8.c + A preliminary implementation of new API routines was completed. + + * refman.latex, refman.dvi, refman.ps + A draft edition of the document "GLPK Reference Manual", which + describes new API routines, was included. + + * glplib3.c + A bug in measuring long time intervals was fixed up. + + * glprsm3.c + This module contains some obsolete routines not longer used and + therefore it was removed from the package (into the subdirectory + 'oldsrc'). + + * glprsm.h + Some declarations related to the module 'glprsm3.c' (see above) + were removed. + + * guide.texinfo + The document "GLPK User's Guide" describing old API routines was + removed from the package (into the subdirectory 'oldsrc'). + + * newapi.txt + The document "New GLPK API Routines" was removed at all, because + it is superseded by the new reference manual (see above). + +Mon May 13 12:00:00 2002 Andrew Makhorin + + * GLPK 3.0.8 has been released. + + * glplpx.h, glplpx1.c, glplpx2.c, glplpx3.c, glplpx4.c, + * glplpx5.c, glplpx6.c, glplpx7.c + A preliminary (currently incomplete) implementation of new api + routines was included. + + * sample/newsamp.c + A sample program for the new api routines was included. + + * newapi.txt + A draft of the document "New GLPK API Routines" was included. + + * glpapi2.c, glpapi5.c, glpapi6.c + These modules (which contain the api routines glp_call_rsm1, + glp_simplex1, glp_pivot_in, glp_pivot_out) were removed from the + package (to the subdirectory 'oldsrc') since these routines are + functionally superseded by the new api routines. + + * glpk.h, glpapi2.c, glpapi3.c, glpapi4.c + The api routines glp_simplex2, glp_call_ipm1, glp_call_bbm1 were + renamed to glp_simplex, glp_interior, glp_integer, respectively. + + * sample/glpsol.c + Some command-line options (which got obsolete due to the recent + changes in api) were excluded. + + * doc/guide.texinfo + New edition of the document "GLPK User's Guide" was included in + the distribution to reflect the changes in some api routines. + + * doc/libref.texinfo + This document was removed from the package (to the subdirectory + 'oldsrc') since it describes the library routines, most of which + got obsolete and no longer used. + + * Makefile.in + A minor bug was fixed up due to bug report from Hans Schwengeler + . + +Mon Apr 22 12:00:00 2002 Andrew Makhorin + + * GLPK 3.0.7 has been released. + + * glpduff.h, glpduff.c, glpspx.h, glpspx1.c, glpspx2.c, + * glpapi7.c + These modules were replaced by a new implementation of the + simplex method and therefore they were removed from the package + (however they still can be found in the subdirectory 'oldsrc'). + + * glprsm1.c + The routine crash_aa was replaced by a new implementation and + therefore it was removed from the file 'glprsm1.c'. + + * glplpx.h, glplpx.c, glpspx.h, glpspx1.c, glpspx2.c, glpspx3.c, + * glpspx4.c, glpapi7.c + New (currently incomplete) implementation of the simplex method + components was included in the package. + +Thu Mar 28 12:00:00 2002 Andrew Makhorin + + * GLPK 3.0.6 has been released. + + * glpluf.h, glpluf.c, glpinv.h, glpinv.c + New version of LU-factorization and basis maintenance routines + (based on Forrest-Tomlin updating technique) was implemented. + + * glpeta.h, glpeta.c, glpfhv.h, glpfhv.c, glpgel.h, glpgel.c, + * glppfi.h, glppfi.c, glprfi.h, glprfi.c + These routines implement some other forms of the basis matrix. + Now they became obsolete being functionally superseded by the + new version of basis maintenance routines (see above) and were + removed from the package (however they still can be found in the + subdirectory 'oldsrc'). + + * glpbbm.c, glprsm.h, glprsm1.h, glprsm2.h, glpspx.h, glpspx2.c, + * glprsm2.c, glpsol.c + Necessary changes were made in order to use the new version of + basis maintenance routines. + +Tue Jan 29 12:00:00 2002 Andrew Makhorin + + * GLPK 3.0.5 has been released. + Structure of the package was re-organized in order to simplify + its maintenance. + + * doc/guide.texinfo + New edition of the document "GLPK User's Guide" was included in + the distribution. Now the document includes descriptions of some + additional API routines recently added to the package. + + * doc/newapi.txt + The document "Additional GLPK API Routines" was removed from the + distribution, because the corresponding material was included in + the user's guide (see above). + +Mon Dec 10 12:00:00 2001 Andrew Makhorin + + * GLPK 3.0.4 has been released. + + * glpspx.h, glpspx1.c, glpspx2.c, glpapi/glp_simplex2.h + A new, more efficient version of the two-phase primal simplex + method was implemented (advanced initial basis, projected + steepest edge, recursive computations of solution components). + + * glpapi/glp_call_bbm1.c + Now LP relaxation can be solved either using rsm1_driver(), or + using glp_simplex2(). The choice is controlled by the parameter + 'meth' (a member of struct bbm1). + + * sample/glpsol.c + The new implementation of the simplex method is now used by + default. The old version is available via --old-sim option. + + * glpmat/gm_scaling.c + Now this routine displays only two lines: an initial "quality" + and a final "quality". + + * glplp/prepro_lp.c + Identifiers 'fmin' and 'fmax' renamed to 'f_min' and 'f_max' in + order to avoid conflict with . The bug was fixed due to + report provided by Sami Farin . + +Wed Oct 03 12:00:00 2001 Andrew Makhorin + + * GLPK 3.0.3 has been released. + + * glprsm/harris_row.c, glprsm/harris_col.c + The relative tolerance used on the first pass of the two-pass + ratio test was replaced by the absolute tolerance. + + * glprsm/rsm_primal.c, glprsm/rsm_feas.c, glprsm/rsm_dual.c + The absolute tolerance passed to the two-pass ratio test routine + was decaresed (for both primal and dual simplex). + + These changes were made in order to improve numerical stability + of the simplex method. + + * glprsm/glp_call_rsm1.c, glprsm/glp_call_bbm1.c, + * glprsm/glp_simplex1, glprsm/glp_pivoting.c + Default form of the inverse was changed from RFI to AFI. + +Mon Sep 24 12:00:00 2001 Andrew Makhorin + + * GLPK 3.0.2 has been released. + + * glpfhv.h, glpfhv.c + New version of the basis maintaining routines was implemented. + These routines, which are based on so called FHV-factorization + (a variety of LU-factorization) and Gustavson's data structures, + perform the main operations on the basis matrix faster at the + expense of some worsening numerical accuracy. + + * glprsm.h, glprsm/afi.c + The routines, which implement AFI (Advanced Form of the + Inverse) based on FHV-factorization, were added to the package. + This new form is available via the parameter form = 3 (on API + level) or via the option --afi (in GLPSOL solver). + + * EFI was renamed to PFI + In order to correct terminology the acronym EFI (Elimination + Form of the Inverse) was replaced by PFI (Product Form of the + Inverse) everywhere in the source code and the documentation. + + * glpset/umalloc.c, glpset/ucalloc.c + * glpset/get_atom.c, glpset/get_atomv.c + These memory management routines were changed in order *not* to + clear allocated memory blocks by binary zeros. + +Wed Aug 01 12:00:00 2001 Andrew Makhorin + + * GLPK 3.0.1 has been released. + + * glpapi/old_api.c, glplp/extract_lp.c, store_lpsol.c + Old API routines were deleted from the package. + + * include/glpk.h, include/glpapi.h, include/glplp.h + Specifications of old API routines and data structures were + removed from the headers. + + * sample/glpsol.c + New version of the stand-alone solver GLPSOL that now uses new + API routines was implemented. + + * glpapi/glp_set_row_fctr.c, glpapi/glp_set_col_fctr.c, + * glpapi/glp_get_row_fctr.c, glpapi/glp_get_col_fctr.c, + * glpapi/glp_scale_prob.c + Scaling routines were added. + + * glpapi/glp_write_mps.c + The routine for writing problem data in MPS format was added. + + * glpapi/glp_simplex1.c + Comprehensive driver to the simplex method was added. + + * glpapi/glp_pivoting.c + The routines glp_pivot_in() and glp_pivot_out() intended for + basis maintaining were added. + + * glprsm/create_rsm.c, glprsm/delete_rsm.c, glprsm/scale_rsm.c, + * glprsm/build_basis.c + Additional low level routines related to the simplex method + were added. + + * glpk.h, glpapi.h, glprsm.h + Additional specifications for new routines and data structures + were added. + + * sample/lpglpk30.c + A non-trivial example was added. It allows using GLPK as a base + LP solver for Concorde, a program for solving Traveling Salesman + Problem (TSP). For details see comments in 'lpglpk30.c'. + + * doc/newapi.txt + The document "Additional GLPK API Routines" that describes some + new API routines was included. + +Thu Jul 19 12:00:00 2001 Andrew Makhorin + + * GLPK 3.0 has been released. + + Now GLPK is provided with new API, which is intended for using + the package in more complex algorithmic schemes. + + * glpapi/old_api.c + All routines related to old API were gathered in one file named + 'old_api.c'. + + * glpapi/*.c + These routines that implement new API were added to the package. + + * include/glpk.h, include/glpapi.h + Specifications of new API routines and data structures were + added to these headers. Specifications of old API routines and + data structures were locked by #ifdef GLP_OLD_API directive. + + * doc/guide.texinfo + New edition of the document "GLPK User's Guide" that correspond + to new API was included. + +Thu Jun 14 12:00:00 2001 Andrew Makhorin + + * GLPK 2.4.1 has been released. + + * doc/glpk_ml.texinfo + The new document "Modeling Language GLPK/L" was included. + + * doc/glpk_ug.texinfo + New edition of the document "GLPK User's Guide" was included. + + * doc/language.txt + The preliminary document "GLPK/L Modeling Language: A Brief + description" was removed from the distribution, because it has + been replaced by the new document "Modeling Language GLPK/L". + + * glplang/l_spar.c + The routine comparison() was re-programmed in order to + implement the relation operation as specified in the language + description. + + * glpmip.h, glpmip/*.c + The partition 'glpmip' was renamed to 'glpbbm'. + +Thu May 10 12:00:00 2001 Andrew Makhorin + + * GLPK 2.4 has been released. + + Now GLPK includes an implementation of a preliminary version of + the GLPK/L modeling language. + + * glplang.h, glplang/*.c + The header 'glplang.h' and a set of routines that implements + the GLPK/L language processor (the partition 'glplang') were + added to the package. + + * doc/language.txt + The document "GLPK/L Modeling Language: A Brief Description + (Supplement to GLPK User's Guide)" in plain text format was + included in the package (see the file 'language.txt' in the + subdirectory 'doc' of the distribution). + + * ex/model1.lpm, ex/model2.lpm + Two examples of model descriptions written in GLPK/L were added + to the package. + + * sample/glpsol.c + This program was modified in order: a) to allow processing + model description written in GLPK/L; b) to allow solving pure + LP problem using the interior point method. + + * sample/glpipm.c + This program was removed from the package, because its function + was passed to the GLPSOL solver. + + * Makefile.in + This file was changed in order to install the GLPSOL solver + executable. + +Mon Apr 09 12:00:00 2001 Andrew Makhorin + + * GLPK 2.3 has been released. + + * glpmip.h, glpmip/*.c + These routines (that implement the branch-and-bound method) were + re-programmed in order to improve robustness of implementation. + In particular, heuristic routines were carried out from the main + driver routine. + + Additional GLPK API routines were documented. + + New edition of the document "GLPK User's Guide" was included in + the package. + + The preliminary document "Mixed Integer Programming Using GLPK + Version 2.2 (Supplement to GLPK User's Guide)" was removed from + the package, because this material was included in GLPK User's + Guide. + +Thu Mar 15 12:00:00 2001 Andrew Makhorin + + * GLPK 2.2 has been released. + + Now GLPK includes a tentative implementation of the + branch-and-bound procedure based on the dual simplex method for + mixed integer linear programming (MIP). + + The preliminary document "Mixed Integer Programming Using GLPK + Version 2.2 (Supplement to GLPK User's Guide)" was included into + the package in plain text format (see the file 'mip.txt' in the + subdirectory 'doc' of the distribution). + + * glpmip.h, glpmip/*.c, glpapi/glp_integer.c + These routines (that implement the branch-and-bound method) were + added to the package. + + * sample/glpsol.c + This program was modified in order to allow solving LP and MIP + problems. + + * glprsm/rsm_primal.c, glprsm/rsm_dual.c, glprsm/rsm_feas.c, + * glprsm/rsm1_driver.c + These routines (which are drivers to basic components of the + revised simplex method) were added to the package. + +Mon Feb 19 12:00:00 2001 Andrew Makhorin + + * GLPK 2.1 has been released. + + * glprsm.h, glprsm/*.c + These routines (that implement components of the revised simplex + method) were re-programmed and documented. + + The document "GLPK Implementation of the Revised Simplex Method" + was included into the package. + +Thu Jan 25 12:00:00 2001 Andrew Makhorin + + * GLPK 2.0 has been released. + + Now GLPK includes a tentative implementation of the primal-dual + interior point method for large-scale linear programming (for + more details see the file `NEWS' in the distribution). A number + of routines related to the interior point method were added to + the package. + + * insist.c + The routine `insist' and the macro of the same name were + introduced into the package in order to replace the standard + macro `assert'. Some routines require the expression specified + in the `assert' macro to be evaluated, but compiling the package + with NDEBUG option prevents from that. This bug was fixed due to + bug report provided by Peter A. Huegler . + + * Makefile.in + Minor bug was fixed due to a patch provided by Alexandre Oliva + . + +Wed Jan 10 12:00:00 2001 Andrew Makhorin + + * GLPK 1.1.2 has been released. + + * umalloc.c, ufree.c, create_pool.c, get_atom.c, get_atomv.c + These routines were changed in order to fix a bug due to + report provided by Andrew Hood . Because of + this bug data alignment error occured on the Sparc computer. + +Tue Dec 14 12:00:00 2000 Andrew Makhorin + + * GLPK 1.1.1 has been released. + + Minor bug was fixed in `Makefile.in'. + + GLPK Library Reference was included. + +Mon Nov 27 12:00:00 2000 Andrew Makhorin + + * GLPK 1.1 has been released. + + Minor changes were made in order to co-ordinate GLPK routines + and their descriptions. + + GLPK User's Guide was included. + +Fri Oct 20 12:00:00 2000 Andrew Makhorin + + * GLPK 1.0 has been released. diff --git a/resources/3rdparty/glpk-4.57/INSTALL b/resources/3rdparty/glpk-4.57/INSTALL new file mode 100644 index 000000000..749f33d0a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/INSTALL @@ -0,0 +1,209 @@ +INSTALLING GLPK ON YOUR COMPUTER +******************************** + +Unpacking the distribution file +------------------------------- +The GLPK package (like all other GNU software) is distributed in the +form of a packed archive. It is one file named `glpk-X.Y.tar.gz', where +`X' is the major version number and `Y' is the minor version number; +for example, the archive name might be `glpk-4.15.tar.gz'. + +In order to prepare the distribution for installation you should: + +1. Copy the GLPK distribution file to a working directory. + +2. Unpack the distribution file with the following command: + + gzip -d glpk-X.Y.tar.gz + + After unpacking the distribution file is automatically renamed to + `glpk-X.Y.tar'. + +3. Unarchive the distribution file with the following command: + + tar -x < glpk-X.Y.tar + + It automatically creates the subdirectory `glpk-X.Y' containing the + GLPK distribution. + +Configuring the package +----------------------- +After unpacking and unarchiving the GLPK distribution you should +configure the package, i.e. automatically tune it for your platform. + +Normally, you should just `cd' to the directory `glpk-X.Y' and run the +`configure' script, e.g. + + ./configure + +The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It also creates file `config.h' containing platform-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + +Running `configure' takes about a few seconds. While it is running, it +displays some messages that tell you what it is doing. If you don't want +to see the messages, run `configure' with its standard output redirected +to `dev/null'; for example, `./configure > /dev/null'. + +By default both static and shared versions of the GLPK library will be +compiled. Compilation of the shared librariy can be turned off by +specifying the `--disable-shared' option to `configure', e.g. + + ./configure --disable-shared + +If you encounter problems building the library try using the above +option, because some platforms do not support shared libraries. + +The GLPK package has some optional features listed below. By default +all these features are disabled. To enable a feature the corresponding +option should be passed to the configure script. + +--with-gmp Enable using the GNU MP bignum library + + This feature allows the exact simplex solver to use the GNU MP + bignum library. If it is disabled, the exact simplex solver uses the + GLPK bignum module, which provides the same functionality as GNU MP, + however, it is much less efficient. + + For details about the GNU MP bignum library see its web page at + . + +--with-zlib Enable using the zlib data compression library + + This feature allows GLPK API routines and the stand-alone solver to + read and write compressed data files performing compression and + decompression "on the fly" (compressed data files are recognized by + suffix `.gz' in the file name). It may be useful in case of large + MPS files to save the disk space. + + For details about the zlib compression library see its web page at + . + +--enable-dl The same as --enable-dl=ltdl +--enable-dl=ltdl Enable shared library support (GNU) +--enable-dl=dlfcn Enable shared library support (POSIX) + + Currently this feature is only needed to provide dynamic linking to + ODBC and MySQL shared libraries (see below). + + For details about the GNU shared library support see the manual at + . + +--enable-odbc Enable using ODBC table driver (libiodbc) +--enable-odbc=unix Enable using ODBC table driver (libodbc) + + This feature allows transmitting data between MathProg model objects + and relational databases accessed through ODBC. + + For more details about this feature see the supplement "Using Data + Tables in the GNU MathProg Modeling Language" (doc/tables.*). + +--enable-mysql Enable using MySQL table driver (libmysql) + + This feature allows transmitting data between MathProg model objects + and MySQL relational databases. + + For more details about this feature see the supplement "Using Data + Tables in the GNU MathProg Modeling Language" (doc/tables.*). + +Compiling the package +--------------------- +Normally, you can compile (build) the package by typing the command: + + make + +It reads `Makefile' generated by `configure' and performs all necessary +jobs. + +If you want, you can override the `make' variables CFLAGS and LDFLAGS +like this: + + make CFLAGS=-O2 LDFLAGS=-s + +To compile the package in a different directory from the one containing +the source code, you must use a version of `make' that supports `VPATH' +variable, such as GNU `make'. `cd' to the directory where you want the +object files and executables to go and run the `configure' script. +`configure' automatically checks for the source code in the directory +that `configure' is in and in `..'. If for some reason `configure' is +not in the source code directory that you are configuring, then it will +report that it can't find the source code. In that case, run `configure' +with the option `--srcdir=DIR', where DIR is the directory that contains +the source code. + +Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Here are the `make' variables that you might want to override with +environment variables when running `configure'. + +For these variables, any value given in the environment overrides the +value that `configure' would choose: + +CC: C compiler program. The default is `cc'. + +INSTALL: Program used to install files. The default value is `install' + if you have it, otherwise `cp'. + +For these variables, any value given in the environment is added to the +value that `configure' chooses: + +DEFS: Configuration options, in the form `-Dfoo -Dbar ...'. + +LIBS: Libraries to link with, in the form `-lfoo -lbar ...'. + +Checking the package +-------------------- +To check the package, i.e. to run some tests included in the package, +you can use the following command: + + make check + +Installing the package +---------------------- +Normally, to install the GLPK package you should type the following +command: + + make install + +By default, `make install' will install the package's files in +`usr/local/bin', `usr/local/lib', etc. You can specify an installation +prefix other than `/usr/local' by giving `configure' the option +`--prefix=PATH'. Alternately, you can do so by consistently giving a +value for the `prefix' variable when you run `make', e.g. + + make prefix=/usr/gnu + make prefix=/usr/gnu install + +After installing you can remove the program binaries and object files +from the source directory by typing `make clean'. To remove all files +that `configure' created (`Makefile', `config.status', etc.), just type +`make distclean'. + +The file `configure.ac' is used to create `configure' by a program +called `autoconf'. You only need it if you want to remake `configure' +using a newer version of `autoconf'. + +Uninstalling the package +------------------------ +To uninstall the GLPK package, i.e. to remove all the package's files +from the system places, you can use the following command: + + make uninstall + +======================================================================== diff --git a/resources/3rdparty/glpk-4.57/Makefile.am b/resources/3rdparty/glpk-4.57/Makefile.am new file mode 100644 index 000000000..5a040f49a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/Makefile.am @@ -0,0 +1,7 @@ +## Process this file with automake to produce Makefile.in ## + +ACLOCAL_AMFLAGS=-I m4 + +SUBDIRS = src examples + +## eof ## diff --git a/resources/3rdparty/glpk-4.57/Makefile.in b/resources/3rdparty/glpk-4.57/Makefile.in new file mode 100644 index 000000000..5ae9553c6 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/Makefile.in @@ -0,0 +1,759 @@ +# Makefile.in generated by automake 1.12.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ + THANKS config.guess config.sub install-sh ltmain.sh missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + cscope distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I m4 +SUBDIRS = src examples +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then rm -f stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done +cscopelist-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) + +clean-cscope: + -rm -f cscope.files + +cscope.files: clean-cscope cscopelist-recursive cscopelist + +cscopelist: cscopelist-recursive $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile config.h +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ + cscopelist-recursive ctags-recursive install-am install-strip \ + tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-cscope \ + clean-generic clean-libtool cscope cscopelist \ + cscopelist-recursive ctags ctags-recursive dist dist-all \ + dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ dist-xz \ + dist-zip distcheck distclean distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-recursive uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/resources/3rdparty/glpk-4.57/NEWS b/resources/3rdparty/glpk-4.57/NEWS new file mode 100644 index 000000000..608086d1b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/NEWS @@ -0,0 +1,1841 @@ +GLPK 4.57 (release date: Nov 08, 2015) + + A new, more efficient implementation of the dual simplex method + was included in the package. This new implementation replaces + the old one, which was removed. + + Option sr_heur was added to struct glp_iocp to enable/disable + the simple rounding heuristic used by the MIP solver. Thanks to + Chris Matrakidis for suggestion. + + New API routine glp_at_error was added and documented. Thanks + to Jeroen Demeyer for suggestion. + + Some minor typos were corrected in the GLPK documentation. + Thanks to Anton Voropaev for typo + report. + + An example application program TSPSOL was added. It uses the + GLPK MIP optimizer to solve the Symmetric Traveling Salesman + Problem and illustrates "lazy" constraints generation. For more + details please see glpk/examples/tsp/README. + +GLPK 4.56 (release date: Oct 01, 2015) + + A new, more efficient and more robust implementation of the + primal simplex method was included in the package. This new + implementation replaces the old one, which was removed. + + A bug was fixed in a basis factorization routine. (The bug + appeared if the basis matrix was structurally singular having + duplicate row and/or column singletons.) Thanks to Martin Jacob + for bug report. + + Scripts to build GLPK with Microsoft Visual Studio 2015 were + added. Thanks to Xypron for contribution + and testing. + +GLPK 4.55 (release date: Aug 22, 2014) + + Some internal (non-API) routines to estimate the condition of + the basis matrix were added. These routines are mainly intended + to be used by the simplex-based solvers. + + Two open modes "a" and "ab" were added to GLPK I/O routines. + Thanks to Pedro P. Wong for bug report. + + Minor bug was fixed in the solver glpsol (command-line options + --btf, --cbg, and --cgr didn't work properly). + + A serious bug was fixed in a basis factorization routine used + on the dense phase. (The bug might appear only if the number of + rows exceeded sqrt(2**31) ~= 46,340 and caused access violation + exception because of integer overflow.) Thanks to Mark Meketon + for bug report. + + Two API routines glp_alloc and glp_realloc were documented. + Thanks to Brian Gladman for suggestion. + + Translation of the document "Modeling Language GNU MathProg" + to Spanish was included (in LaTeX and pdf formats). Thanks to + Pablo Yapura for contribution. + +GLPK 4.54 (release date: Mar 28, 2014) + + Block-triangular LU-factorization was implemented to be used + on computing an initial factorization of the basis matrix. + + A new version of the Schur-complement-based factorization + module was included in the package. Now it can be used along + with plain as well as with block-triangular LU-factorization. + + Currently the following flags can be used to specify the type + of the basis matrix factorization (glp_bfcp.type): + + GLP_BF_LUF + GLP_BF_FT LUF, Forrest-Tomlin update (default) + GLP_BF_LUF + GLP_BF_BG LUF, Schur complement, Bartels-Golub + update + GLP_BF_LUF + GLP_BF_GR LUF, Schur complement, Givens rotation + update + GLP_BF_BTF + GLP_BF_BG BTF, Schur complement, Bartels-Golub + update + GLP_BF_BTF + GLP_BF_GR BTF, Schur complement, Givens rotation + update + + In case of GLP_BF_FT the update is applied to matrix U, while + in cases of GLP_BF_BG and GLP_BF_GR the update is applied to + the Schur complement. + + Corresponding new options --luf and --btf were added to glpsol. + + For more details please see a new edition of the GLPK reference + manual included in the distribution. + + A minor bug (in reporting the mip solution status) was fixed. + Thanks to Remy Roy for bug report. + + A call to "iodbc-config --cflags" was added in configure.ac + to correctly detect iodbc flags. Thanks to Sebastien Villemot + for patch. + +GLPK 4.53 (release date: Feb 13, 2014) + + The API routine glp_read_mps was changed to remove free rows. + + A bug was fixed in the API routine glp_read_lp. Thanks to + Gabriel Hackebeil for bug report. + + The zlib compression library used by some GLPK routines and + included in the package was downgraded from 1.2.7 to 1.2.5 (as + in GLPK 4.50) because of addressability bugs on some 64-bit + platforms. Thanks to Carlo Baldassi + for bug report. + + A bug was fixed in a routine that reads gzipped files. Thanks + to Achim Gaedke for bug report. + + Two API routines glp_get_it_cnt and glp_set_it_cnt were added. + Thanks to Joey Rios for suggestion. + + All obsolete GLPK API routines (prefixed with lpx) were removed + from the package. + + A set of routines that simulate the old GLPK API (as defined + in 4.48) were added; see examples/oldapi/api/lpx.c. Thanks to + Jan Engelhardt for suggestion. + + A namespace bug was fixed in the SQL table drive module. Thanks + to Dennis Schridde for bug report. + +GLPK 4.52.1 (release date: Jul 28, 2013) + + This is a bug-fix release. + + A version information bug in Makefile.am was fixed. Thanks to + Sebastien Villemot for bug report. + +GLPK 4.52 (release date: Jul 18, 2013) + + The clique cut generator was essentially reimplemented, and now + it is able to process very large and/or dense conflict graphs. + + A simple rounding heuristic was added to the MIP optimizer. + + Some bugs were fixed in the proximity search heuristic routine. + Thanks to Giorgio Sartor <0gioker0@gmail.com>. + + New command-line option '--proxy [nnn]' was added to glpsol to + enable using the proximity search heuristic. + + A bug (incorrect processing of LI column indicator) was fixed + in the mps format reading routine. Thanks to Charles Brixko for + bug report. + +GLPK 4.51 (release date: Jun 19, 2013) + + Singleton and dense phases were implemented on computing + LU-factorization with Gaussian elimination. The singleton phase + is a feature that allows processing row and column singletons + on initial elimination steps more efficiently. The dense phase + is a feature used on final elimination steps when the active + submatrix becomes relatively dense. It significantly reduces + the time needed, especially if the active submatrix fits in CPU + cache, and improves numerical accuracy due to full pivoting. + + The API routine glp_adv_basis that constructs advanced initial + LP basis was replaced by an improved version, which (unlike the + old version) takes into account numerical values of constraint + coefficients. + + The proximity search heuristic for MIP was included in the GLPK + integer optimizer glp_intopt. On API level the heuristic can be + enabled by setting the parameter ps_heur in glp_iocp to GLP_ON. + This feature is also available in the solver glpsol through + command-line option '--proxy'. Many thanks to Giorgio Sartor + <0gioker0@gmail.com> for contribution. + + A bug was fixed that caused numerical instability in the FPUMP + heuristic. + +GLPK 4.50 (release date: May 24, 2013) + + A new version of LU-factorization routines were added. + Currently this version provides the same functionality as the + old one, however, the new version allows further improving. + + Old routines for FHV-factorization used to update the basis + factorization were replaced by a new version conforming to the + new version of LU-factorization. + + Some clarifications about using the name index routines were + added. Thanks to Xypron for suggestion. + + Some typos were corrected in the MathProg language reference. + Thanks to Jeffrey Kantor for report. + + A serious bug (out-of-range indexing error) was *tentatively* + fixed in the routine glp_relax4. Unfortunatly, this bug is + inherited from the original Fortran version of the RELAX-IV + code (for details please see ChangeLog), and since the code is + very intricate, the bug is still under investigation. Thanks to + Sylvain Fournier for bug report. + +GLPK 4.49 (release date: Apr 16, 2013) + + The new API routine glp_mincost_relax4, which is a driver to + relaxation method of Bertsekas and Tseng (RELAX-IV), was added + to the package. RELAX-IV is a code for solving minimum cost + flow problems. On large instances it is 100-1000 times faster + than the standard primal simplex method. Prof. Bertsekas, the + author of the original RELAX-IV Fortran code, kindly permitted + to include a C translation of his code in GLPK under GPLv3. + + A bug (wrong dual feasibility test) was fixed in API routine + glp_warm_up. Thanks to David T. Price + for bug report. + + Obsolete API routine lpx_check_kkt was replaced by new routine + glp_check_kkt. + + IMPORTANT: All old API routines whose names begin with 'lpx_' + were removed from API level and NO MORE AVAILABLE. + +GLPK 4.48 (release date: Jan 28, 2013) + + This is a maintainer release. + + Some minor changes in API (glpk.h) were made. For details + please see ChangeLog. + + Some bugs/typos were fixed. Thanks to + Raniere Gaia Costa da Silva, + Heinrich Schuchardt , and + Robbie Morrison for reports. + +GLPK 4.47 (release date: Sep 09, 2011) + + The new API routine glp_intfeas1 was added to the package. + This routine is a tentative implementation of the integer (0-1) + feasibility solver based on the CNF-SAT solver (which currently + is MiniSat). It may be used in the same way as glp_intopt to + find either any integer feasible solution or a solution, for + which the objective function is not worse than the specified + value. Detailed description of this routine can be found in the + document "CNF Satisfiability Problem", which is included in the + distribution (see doc/cnfsat.pdf). + + The following two options were added to glpsol: + + --minisat translate 0-1 feasibility problem to CNF-SAT + problem and solve it with glp_intfeas1/MiniSat + (if the problem instance is already in CNF-SAT + format, no translation is performed) + + --objbnd bound add inequality obj <= bound (minimization) or + obj >= bound (maximization) to 0-1 feasibility + problem (this option assumes --minisat) + + The paint-by-numbers puzzle model (pbn.mod) included in the + distribution is a nice example of the 0-1 feasibility problem, + which can be efficiently solved with glp_intfeas1/MiniSat. This + model along with a brief instruction (pbn.pdf) and benchmark + examples from encoded in GNU MathProg (*.dat) can + be found in subdirectory examples/pbn/. + + The glpsol lp/mip solver was modified to bypass postprocessing + of MathProg models if the solution reported is neither optimal + nor feasible. + + A minor bug in examples/Makefile.am was fixed to correctly + build glpk in a separate directory. Thanks to Marco Atzeri + for bug report and patch. + +GLPK 4.46 (release date: Aug 09, 2011) + + The following new API routines were added: + + glp_read_cnfsat read CNF-SAT problem data in DIMACS format + glp_check_cnfsat check for CNF-SAT problem instance + glp_write_cnfsat write CNF-SAT problem data in DIMACS format + glp_minisat1 solve CNF-SAT problem instance with MiniSat + + The routine glp_minisat1 is a driver to MiniSat, a CNF-SAT + solver developed by Niklas Een and Niklas Sorensson, Chalmers + University of Technology, Sweden. This routine is similar to + the routine glp_intopt, however, it is intended to solve a 0-1 + programming problem instance, which is the MIP translation of + a CNF-SAT problem instance. + + Detailed description of these new API routines can be found in + the document "CNF Satisfiability Problem", which is included in + the distribution (see files doc/cnfsat.tex and doc/cnfsat.pdf). + + The following new glpsol command-line options were added: + + --cnf filename read CNF-SAT problem instance in DIMACS + format from filename and translate it to MIP + --wcnf filename write CNF-SAT problem instance in DIMACS + format to filename + --minisat solve CNF-SAT problem instance with MiniSat + solver + + The zlib compression library (version 1.2.5) was ANSIfied, + modified according to GLPK requirements and included in the + distribution as an external software module. Thus, now this + feature is platform independent. + + Some bugs were fixed in the SQL table driver. Thanks to Xypron + . + +GLPK 4.45 (release date: Dec 05, 2010) + + This is a bug-fix release. + + Several bugs/typos were fixed. Thanks to + Xypron , + Robbie Morrison , and + Ali Baharev for reports. + + Some glpk documents was re-formatted and merged into a single + document. Now the glpk documentation consists of the following + three main documents (all included in the distribution): + + GLPK: Reference Manual + + GLPK: Graph and Network Routines + + Modeling Language GNU MathProg: Language Reference + +GLPK 4.44 (release date: Jun 03, 2010) + + The following suffixes for variables and constraints were + implemented in the MathProg language: + + .lb (lower bound), + .ub (upper bound), + .status (status in the solution), + .val (primal value), and + .dual (dual value). + + Thanks to Xypron for draft implementation + and testing. + + Now the MathProg language allows comment records (marked by + '#' in the very first position) in CSV data files read with the + table statements. Note that the comment records may appear only + in the beginning of a CSV data file. + + The API routine glp_cpp to solve the Critical Path Problem was + added and documented. + +GLPK 4.43 (release date: Feb 20, 2010) + + This is a maintainer release. + + `configure.ac' was changed to allow building the package under + Mac OS and Darwin with ODBC support. + Thanks to Xypron for suggestions and Noli + Sicad for testing. + + The SQL table driver was improved to process NULL data. Thanks + to Xypron . + + Some bugs were fixed in the LP/MIP preprocessor. + +GLPK 4.42 (release date: Jan 13, 2010) + + The following new API routines were added: + + glp_check_dup check for duplicate elements in sparse + matrix + glp_sort_matrix sort elements of the constraint matrix + glp_read_prob read problem data in GLPK format + glp_write_prob write problem data in GLPK format + glp_analyze_bound analyze active bound of non-basic variable + glp_analyze_coef analyze objective coefficient at basic + variable + glp_print_ranges print sensitivity analysis report (this + routine replaces lpx_print_sens_bnds and + makes it deprecated) + + For description of these new routines and the GLPK LP/MIP + format see a new edition of the reference manual included in + the distribution. (Chapter "Graph and network API routines" was + carried out from the main reference manual and included in the + distribution as a separate document.) + + The following new command-line options were added to the stand- + alone solver glpsol: + --glp filename read problem data in GLPK format + --wglp filename write problem data in GLPK format + --ranges filename print sensitivity analysis report (this + option replaces --bounds) + + Now all GLPK routines performing file I/O support special + filenames "/dev/stdin", "/dev/stdout", and "/dev/stderr", which + can be specified in the same way as regular filenames. This + feature is plaform-independent. + +GLPK 4.41 (release date: Dec 21, 2009) + + The following new API routies were added: + + glp_transform_row transform explicitly specified row + glp_transform_col transform explicitly specified column + glp_prim_rtest perform primal ratio test + glp_dual_rtest perform dual ratio test + + For description of these new routines see a new edition of the + reference manual included in the distribution. + + The following API routines are deprecated: lpx_transform_row, + lpx_transform_col, lpx_prim_ratio_test, lpx_dual_ratio_test. + + Some improvements were made in the MIP solver (glp_intopt). + + The SQL table driver used to read/write data in MathProg models + was changed to allow multiple arguments separated by semicolon + in SQL statements. Thanks to Xypron . + + Two new options were added to the glpsol stand-alone solver: + --seed value (to initialize the pseudo-random number generator + used in MathProg models with specified value), and + --ini filename (to use a basis previously saved with -w option + as an initial basis on solving similar LP's). + + Two new MathProg example models were included. Thanks to + Nigel Galloway and Noli Sicad + for contribution. + + Scripts to build GLPK with Microsoft Visual Studio 2010 for + both 32-bit and 64-bit Windows were included. Thanks to Xypron + for contribution and testing. + +GLPK 4.40 (release date: Nov 03, 2009) + + The following new API routines were added: + + glp_del_vertices remove vertices from graph + glp_del_arc remove arc from graph + glp_wclique_exact find maximum weight clique with the exact + algorithm developed by Prof. P. Ostergard + glp_read_ccdata read graph in DIMACS clique/coloring + format + glp_write_ccdata write graph in DIMACS clique/coloring + format + + For description of these new routines see a new edition of the + reference manual included in the distribution. + + The hybrid pseudocost branching heuristic was included in the + MIP solver. It is available on API level (iocp.br_tech should + be set to GLP_BR_PCH) and in the stand-alone solver glpsol + (via the command-line option --pcost). This heuristic may be + useful on solving hard MIP instances. + + The branching heuristic by Driebeck and Tomlin (used in the + MIP solver by default) was changed to switch to branching on + most fractional variable if an lower bound of degradation of + the objective is close to zero for all branching candidates. + + A bug was fixed in the LP preprocessor (routine npp_empty_col). + Thanks to Stefan Vigerske for the + bug report. + + A bug was fixed and some improvements were made in the FPUMP + heuristic module. Thanks to Xypron . + + A bug was fixed in the API routine glp_warm_up (dual + feasibility test was incorrect in maximization case). Thanks to + Uday Venkatadri for the bug report. + +GLPK 4.39 (release date: Jul 26, 2009) + + The following new API routines were added: + + glp_warm_up "warm up" LP basis + glp_set_vertex_name assign (change) vertex name + glp_create_v_index create vertex name index + glp_find_vertex find vertex by its name + glp_delete_v_index delete vertex name index + glp_read_asnprob read assignment problem data in DIMACS + format + glp_write_asnprob write assignment problem data in DIMACS + format + glp_check_asnprob check correctness of assignment problem + data + glp_asnprob_lp convert assignment problem to LP + glp_asnprob_okalg solve assignment problem with the + out-of-kilter algorithm + glp_asnprob_hall find bipartite matching of maxumum + cardinality with Hall's algorithm + + Also were added some API routines to read plain data files. + + The API routines glp_read_lp and glp_write_lp to read/write + files in CPLEX LP format were re-implemented. Now glp_write_lp + correctly writes double-bounded (ranged) rows by introducing + slack variables rather than by duplicating the rows. + + For description of these new routines see a new edition of the + reference manual included in the distribution. + + The 'xfree(NULL)' bug was fixed in the AMD routines. Thanks to + Niels Klitgord for bug report. + + The message "Crashing..." was changed to "Constructing initial + basis..." due to suggestion by Thomas Kahle . + + Some typos were corrected in glpsol output messages. Thanks to + Xypron for patch. + +GLPK 4.38 (release date: May 02, 2009) + + API routines glp_read_mps and glp_write_mps were improved. + + Some improvements were made in the dual simplex routines. + + Two external software modules AMD and COLAMD were included in + the distribution (for more details please see src/amd/README + and src/colamd/README). Now they are used in the interior-point + solver to reorder the matrix prior to Cholesky factorization. + + API routine glp_ipt_status may return two new statuses due to + changes in the routine glp_interior. For details please see the + reference manual included in the distribution. + + A minor bug was fixed in the graph/network routines. Thanks to + Nelson H. F. Beebe for bug report. + +GLPK 4.37 (release date: Mar 29, 2009) + + The 0-1 Feasibility Pump heuristic was included in the GLPK + integer optimizer glp_intopt. On API level the heuristic can be + enabled by setting the parameter fp_heur in glp_iocp to GLP_ON. + This feature is also available in the solver glpsol through + command-line option '--fpump'. For more details please see the + reference manual included in the distribution. + + The following new API routines were added: + + glp_print_sol write basic solution in printable format + glp_print_ipt write interior-point solution in printable + format + glp_print_mip write MIP solution in printable format + glp_read_graph read (di)graph from plain text file + glp_write_graph write (di)graph to plain text file + glp_weak_comp find all weakly connected components + glp_strong_comp find all strongly connected components + + The following API routines are deprecated: lpx_print_sol, + lpx_print_ips, lpx_print_mip, lpx_print_prob (the latter is + equivalent to glp_write_lp). + + A bug was fixed in the interior-point solver (glp_interior) to + correctly compute dual solution components when the problem is + scaled. + + The files configure.ac and Makefile.am were changed: + (a) to allow using autoreconf/autoheader; + (b) to allow building the package in a directory other than its + source directory. + Thanks to Marco Atzeri for bug report. + + An example model in the GNU MathProg language was added. + Thanks to Larry D'Agostino for + contribution. + +GLPK 4.36 (release date: Feb 06, 2009) + + The following new API routines were added to the package: + + glp_mincost_okalg find minimum-cost flow with out-of-kilter + algorithm + glp_maxflow_ffalg find maximal flow with Ford-Fulkerson + algorithm + + For detailed description of these new routines and related data + structures see chapter "Graph and Network API Routines" in a new + edition of the reference manual included in the distribution. + + The following two new command-line options were added to the + solver glpsol: + + --mincost read min-cost flow data in DIMACS format + --maxflow read maximum flow data in DIMACS format + + Duplicate symbols in the header glpk.h were removed to allow + using swig. + Thanks to Kelly Westbrooks and + Nigel Galloway for suggestion. + + A minor defect was fixed in the routine glp_write_lp. + Thanks to Sebastien Briais for bug report. + + A minor bug was fixed in the SQL module. + Thanks to Xypron for patch. + + Some new example models in the GNU MathProg modeling language + were added. Thanks to Sebastian Nowozin and + Nigel Galloway for contribution. + +GLPK 4.35 (release date: Jan 09, 2009) + + The following new API routines were added to the package: + + glp_create_graph create graph + glp_set_graph_name assign (change) graph name + glp_add_vertices add new vertices to graph + glp_add_arc add new arc to graph + glp_erase_graph erase graph content + glp_delete_graph delete graph + glp_read_mincost read minimum cost flow problem data in + DIMACS format + glp_write_mincost write minimum cost flow problem data in + DIMACS format + glp_mincost_lp convert minimum cost flow problem to LP + glp_netgen Klingman's network problem generator + glp_gridgen grid-like network problem generator + glp_read_maxflow read maximum flow problem data in DIMACS + format + glp_write_maxflow write maximum flow problem data in DIMACS + format + glp_maxflow_lp convert maximum flow problem to LP + glp_rmfgen Goldfarb's maximum flow problem generator + + For detailed description of these new routines and related data + structures see chapter "Graph and Network API Routines" in a new + edition of the reference manual included in the distribution. + + A minor change were made in the internal routine xputc. Thanks + to Luiz Bettoni for suggestion. + + A minor bug was fixed in the internal routine mpl_fn_time2str. + Thanks to Stefan Vigerske for bug report. + +GLPK 4.34 (release date: Dec 04, 2008) + + The GNU MathProg modeling language was supplemented with three + new built-in functions: + + gmtime obtaining current calendar time + str2time converting character string to calendar time + time2str converting calendar time to character string + + (Thanks to Xypron .) + + For detailed description of these functions see Appendix A in + the document "Modeling Language GNU MathProg", a new edition of + which was included in the distribution. + + A bug was fixed in the MIP solver. Thanks to Nigel Galloway + for bug report. + + A new makefile was added to build the GLPK DLL with Microsoft + Visual Studio Express 2008 for 64-bit Windows. Thanks to Xypron + for contribution and testing. + +GLPK 4.33 (release date: Oct 30, 2008) + + The following new API routines were added to the package: + glp_copy_prob copy problem object content + glp_exact solve LP in exact arithmetic + (makes lpx_exact deprecated) + glp_get_unbnd_ray determine variable causing unboundedness + (makes lpx_get_ray_info deprecated) + glp_interior solve LP with interior-point method + (makes lpx_interior deprecated) + + The following new API routines for processing models written in + the GNU Mathprog language were added to the package: + glp_mpl_alloc_wksp allocate the translator workspace + glp_mpl_read_model read and translate model section + glp_mpl_read_data read and translate data section + glp_mpl_generate generate the model + glp_mpl_build_prob build LP/MIP instance from the model + glp_mpl_postsolve postsolve the model + glp_mpl_free_wksp deallocate the translator workspace + (These routines make lpx_read_model deprecated.) + + For description of all these new API routines see the reference + manual included in the distribution. + + A crude implementation of CPLEX-like interface to GLPK API was + added to the package. Currently it allows using GLPK as a core + LP solver for Concorde, a well known computer code for solving + the symmetric TSP. For details see examples/cplex/README. + + Some bugs were fixed in the SQL table driver. Thanks to Xypron + . + +GLPK 4.32 (release date: Oct 03, 2008) + + The following new features were included in the MIP solver + (the API routine glp_intopt): + + * MIP presolver + * mixed cover cut generator + * clique cut generator + * Euclidean reduction of the objective value + + Due to changes the routine glp_intopt may additionally return + GLP_ENOPFS, GLP_ENODFS, and GLP_EMIPGAP. + + The API routines lpx_integer are lpx_intopt are deprecated, + since they are completely superseded by glp_intopt. + + The following new branch-and-cut API routines were added: + glp_ios_row_attr determine additional row attributes + glp_ios_pool_size determine current size of the cut pool + glp_ios_add_row add constraint to the cut pool + glp_ios_del_row delete constraint from the cut pool + glp_ios_clear_pool delete all constraints from the cut pool + + For description of these new routines see the reference manual + included in the distribution. + + The stand-alone solver glpsol was changed to allow multiple + data files. + + A new edition of the supplement "Using Data Tables in the GNU + MathProg Modeling Language" was included. + + As usual, some bugs were fixed (in the MathProg translator). + Thanks to Xypron . + +GLPK 4.31 (release date: Sep 02, 2008) + + The core LP solver based on the dual simplex method was + re-implemented and now it provides both phases I and II. + + The following new API routines were added: + glp_scale_prob automatic scaling of problem data + glp_std_basis construct standard initial LP basis + glp_adv_basis construct advanced initial LP basis + glp_cpx_basis construct Bixby's initial LP basis + + For description of these new routines see the reference manual + included in the distribution. + + The following API routines are deprecated: + lpx_scale_prob, lpx_std_basis, lpx_adv_basis, lpx_cpx_basis. + + Necessary changes were made in memory allocation routines to + resolve portability issues for 64-bit platforms. + + New version of the routine lpx_write_pb to write problem data + in OPB (pseudo boolean format) was added to the package. Thanks + to Oscar Gustafsson for the contribution. + + Two new makefiles were added to build the package for 32- and + 64-bit Windows with Microsoft Visual Studio Express 2008. + Thanks to Heinrich Schuchardt (aka + Xypron) for the contribution and testing. + + Two new makefiles were added to build the package with Digital + Mars C/C++ 8.50 and Open Watcom C/C++ 1.6 (for 32-bit Windows). + +GLPK 4.30 (release date: Aug 13, 2008) + + The core LP solver based on the primal simplex method was + re-implemented to allow its further improvements. Currently the + new version provides the same features as the old one, however, + it is a bit faster and more numerically stable. + + Some changes were made in the MathProg translator to allow <, + <=, >=, and > on comparing symbolic values. Thanks to Heinrich + Schuchardt for patches. + + Internal routine set_d_eps in the exact LP solver was changed + to prevent approximation errors in case of integral data. + Thanks to Markus Pilz for bug report. + +GLPK 4.29 (release date: Jul 06, 2008) + + The configure script was changed to disable all optional + features by default. For details please see file INSTALL. + + The following new API routines were added: + glp_erase_prob erase problem object content + glp_read_mps read problem data in MPS format + glp_write_mps write problem data in MPS format + glp_read_lp read problem data in CPLEX LP format + glp_write_lp write problem data in CPLEX LP format + + For description of these new routines see the reference manual + included in the distribution. + + The following API routines are deprecated: + lpx_read_mps, lpx_read_freemps, lpx_write_mps, + lpx_write_freemps, lpx_read_cpxlp, and lpx_write_cpxlp. + + Two bugs were fixed. Thanks to + Anne-Laurence Putz and + Xypron for bug report. + +GLPK 4.28 (release date: Mar 25, 2008) + + The iODBC and MySQL table drivers, which allows transmitting + data between MathProg model objects and relational databases, + were re-implemented to replace a static linking by a dynamic + linking to corresponding shared libraries. + Many thanks to Heinrich Schuchardt + for the contribution, Rafael Laboissiere + for useful advices concerning the shared library support under + GNU/Linux, and Vijay Patil for testing + this feature under Windows XP. + + A new optional feature was added to the package. This feature + is based on the zlib data compression library and allows GLPK + API routines and the stand-alone solver to read and write + compressed data files performing compression/decompression "on + the fly" (compressed data files are recognized by suffix `.gz' + in the file name). It may be useful in case of large MPS files + to save the disk space (up to ten times). + + The `configure' script was re-implemented. Now it supports the + following specific options: + + --with-gmp Enable using the GNU MP bignum library + --without-gmp Disable using the GNU MP bignum library + --with-zlib Enable using the zlib data compression + library + --without-zlib Disable using the zlib data compression + library + --enable-dl Enable shared library support (auto check) + --enable-dl=ltdl Enable shared library support (GNU) + --enable-dl=dlfcn Enable shared library support (POSIX) + --disable-dl Disable shared library support + --enable-odbc Enable using ODBC table driver + --disable-odbc Disable using ODBC table driver + --enable-mysql Enable using MySQL table driver + --disable-mysql Disable using MySQL table driver + + For more details please see file INSTALL. + +GLPK 4.27 (release date: Mar 02, 2008) + + Three new table drivers were added to the MathProg translator: + + xBASE built-in table driver, which allows reading and writing + data in .dbf format (only C and N fields are supported); + + MySQL table driver, which provides connection to a MySQL + database; + + iODBC table driver, which provides connection to a database + through ODBC. + + The MySQL and iODBC table drivers were contributed to GLPK by + Heinrich Schuchardt . + + The table driver is a program module which allows transmitting + data between MathProg model objects and external data tables. + + For detailed description of the table statement and table + drivers see the document "Using Data Tables in the GNU MathProg + Modeling Language" (file doc/tables.txt) included in the + distribution. Some examples which demonstrate using MySQL and + iODBC table drivers can be found in subdirectory examples/sql. + +GLPK 4.26 (release date: Feb 17, 2008) + + The table statement was implemented in the GNU MathProg + modeling language. This new feature allows reading data from + external tables into model objects such as sets and parameters + as well as writing results of computations to external tables. + + A table is a (unordered) set of records, where each record + consists of the same number of fields, and each field is + provided with a unique symbolic name called the field name. + + Currently the GLPK package has the only built-in table driver, + which supports tables in the CSV (comma-separated values) file + format. This format is very simple and supported by almost all + spreadsheets and database management systems. + + Detailed description of the table statement and CSV format can + be found in file doc/tables.txt, included in the distribution. + +GLPK 4.25 (release date: Dec 19, 2007) + + A tentative implementation of Gomory's mixed integer cuts was + included in the branch-and-cut solver. To enable generating + Gomory's cuts the control parameter gmi_cuts passed to the + routine glp_intopt should be set to GLP_ON. This feature is + also available in the solver glpsol through command-line option + '--gomory'. For more details please see the reference manual + included in the distribution. + +GLPK 4.24 (release date: Nov 21, 2007) + + A tentative implementation of MIR (mixed integer rounding) cuts + was included in the MIP solver. To enable generating MIR cuts + the control parameter mir_cuts passed to the routine glp_intopt + should be set to GLP_ON. This feature is also available in the + stand-alone solver glpsol via command-line option '--mir'. For + more details please see the reference manual included in the + distribution. + + The implementation is mainly based on the following two papers: + + 1. H. Marchand and L. A. Wolsey. Aggregation and mixed integer + rounding to solve MIPs. CORE discussion paper 9839, CORE, + Universite catholique de Louvain, June 1998. + + 2. G. Andreello, A. Caprara, and M. Fischetti. Embedding cuts + in a Branch&Cut framework. Preliminary draft, October 2003. + + MIR cuts can be generated on any level of the search tree that + makes the GLPK MIP solver to be a real branch-and-cut solver. + + A bug was fixed in the routine lpx_write_cpxlp. If a variable + x has upper bound and no lower bound, it should appear in the + bounds section as "-inf <= x <= u", not as "x <= u". Thanks to + Enric Rodriguez for the bug report. + +GLPK 4.23 (release date: Oct 28, 2007) + + The following new API routines were added: + + glp_read_sol read basic solution from text file + glp_write_sol write basic solution to text file + glp_read_ipt read interior-point solution from text file + glp_write_ipt write interior-point solution to text file + glp_read_mip read MIP solution from text file + glp_write_mip write MIP solution to text file + + For description of these routines and corresponding file + formats see Chapter "API Routines", Section "Utility routines" + in the reference manual included in the distribution. + + Advanced API routine glp_free_env was added. It may be used by + the application program to free all resources allocated by GLPK + routines. + + The following three new command-line options were added to the + solver glpsol: + + --mipgap tol set relative MIP gap tolerance + -r filename read solution from filename + -w filename write solution to filename + +GLPK 4.22 (release date: Sep 19, 2007) + + This is a maintainer release. + + A bug was fixed in the MIP preprocessor (ios_preprocess_node). + Thanks to Roberto Bagnara (Department of + Mathematics, University of Parma, Italy) for the bug report. + + A bug was fixed in the MIP preprocessor (col_implied_bounds), + due to which constraint coefficients with small magnitude could + lead to wrong implied bounds of structural variables. + + A similar bug was fixed in the routine reduce_bounds. + + A bug was fixed in the routines glp_set_mat_row and + glp_set_mat_col. (The bug appeared due to incorrect removing + zero elements from the row/column lists.) + + A bug was fixed in the API routines lpx_read_mps and + lpx_read_freemps, due to which bounds of type LI specified in + BOUNDS section were incorrectly processed. + + A call to standard function vsprintf was replaced by a call to + vsnprintf for security reasons. Many thanks to Peter T. Breuer + and Rafael Laboissiere . + +GLPK 4.21 (release date: Aug 28, 2007) + + Additional reasons for calling the callback routine used in the + MIP solver (glp_intopt) were introduced. Currently the following + reasons are supported: + + * request for subproblem selection + * request for preprocessing + * request for row generation + * request for heuristic solution + * request for cut generation + * request for branching + * better integer solution found + + A basic preprocessing component used to improve subproblem + formulations by tightening bounds of variables was included in + the MIP solver. Depending on the control parameter pp_tech + passed to the routine glp_intopt the preprocessing can be + performed either on the root level or on all levels (default) + or can be disabled. + + Backtracking heuristic used by default in the MIP solver was + changed to the "best local bound". + + For more details see Chapter "Advanced API routines", Section + "Branch-and-bound interface routines" in a new edition of the + reference manual included in the distribution. + +GLPK 4.20 (release date: Jul 26, 2007) + + API routine lpx_integer was replaced by API routine glp_intopt, + which provides equivalent functionality and additionally allows + the application to control the solution process by means of the + user-written callback routine, which is called by the solver at + various points of the branch-and-bound algorithm. Besides, the + new MIP solver allows generating "lazy" constraints and cutting + planes on all levels of the branch-and-bound tree, not only on + the root level. The routine lpx_integer is also still available + for the backward compatibility. + + The following new advanced API routines, which may be called + from the B&B callback routine, were included in the package: + + glp_ios_reason determine reason for calling callback + routine + glp_ios_get_prob access the problem object + glp_ios_tree_size determine size of the branch-and-bound tree + glp_ios_curr_node determine current active subproblem + glp_ios_next_node determine next active subproblem + glp_ios_prev_node determine previous active subproblem + glp_ios_up_node determine parent subproblem + glp_ios_node_level determine subproblem level + glp_ios_node_bound determine subproblem local bound + glp_ios_mip_gap compute relative MIP gap + glp_ios_heur_sol provide solution found by heuristic + glp_ios_terminate terminate the solution process + + For description of these routines see Chapter "Advanced API + routines", Section "Branch-and-bound interface routines" in a + new edition of the reference manual, which was included in the + distribution. + + Old version of the integer optimization suite (IOS) as well as + TSP solver tspsol based on it are no longer supported and were + removed from the package. + + A minor error in the MIP presolver was fixed; thanks to Graham + Rockwell for the bug report. + +GLPK 4.19 (release date: Jul 05, 2007) + + The principal change is upgrading to GPLv3. + + A serious bug in the routine glp_del_cols was fixed; thanks to + Cedric[FR] for the bug report. The bug + appeared because on deleting non-basic columns the basis header + remained valid, however, contained invalid (old) column ordinal + numbers. + + A new advanced API routine glp_mem_limit was added. + + The case GLP_EBOUND was added to the routine lpx_simplex. + Thanks to Cameron Kellough for the + bug report. + + An API routine lpx_write_pb to write the problem instance in + OPB (pseudo boolean) format format was added. Thanks to Oscar + Gustafsson for the contribution. + + Two new options --wpb and --wnpb were added to glpsol to write + the problem instance in OPB format. + +GLPK 4.18 (release date: Jun 25, 2007) + + The following new API routines were added: + + glp_set_rii set (change) row scale factor + glp_set_sjj set (change) column scale factor + glp_get_rii retrieve row scale factor + glp_get_sjj retrieve column scale factor + glp_simplex solve LP problem with the simplex method + (this routine replaces lpx_simplex, which is + also available for backward compatibility) + glp_init_smcp initialize simplex method control params + glp_bf_exists check if the basis factorization exists + glp_factorize compute the basis factorization + glp_bf_updated check if the basis factorization has been + updated + glp_get_bfcp retrieve basis factorization control params + glp_set_bfcp change basis factorization control params + glp_get_bhead retrieve the basis header information + glp_get_row_bind retrieve row index in the basis header + glp_get_col_bind retrieve column index in the basis header + glp_ftran perform forward transformation + glp_btran perform backward transformation + + For description of all these routines see a new edition of the + reference manual included in the distribution. + + Type names ulong_t and uldiv_t were changed to glp_ulong and + glp_uldiv to avoid conflicts with standard type names on some + platforms. Thanks to Boris Wirtz + for the bug report. + + Some new examples in the MathProg language were added. Thanks + to Sebastian Nowozin . + +GLPK 4.17 (release date: May 26, 2007) + + API routines glp_set_mat_row, glp_set_mat_col, and glp_load_mat + were modified to allow zero constraint coefficients (which are + not stored in the constraint matrix). Note that constraint + coefficients with duplicate row/column indices are not allowed. + + Another form of LP basis factorization was implemented in the + package. It is based on LU-factorization of an initial basis + and Schur complement to reflect changes in the basis. Currently + the implementation is incomplete and provides only updating the + factorization on replacing a column of the basis matrix. On API + level the user can set the control parameter LPX_K_BFTYPE to + choose between the folloiwng forms of LP basis factorization to + be used in the simplex method routines: + 1) LU + Forrest-Tomlin update; + 2) LU + Schur complement + Bartels-Golub update; + 3) LU + Schur complement + Givens rotation update. + The GLPK implementation is similar to LUSOL/LUMOD developed by + Michael A. Saunders. + + The user can choose the form of LP basis factorzation used by + the simplex method routines by specifying the folloiwng options + of glpsol: --luf, --cbg, --cgr. + +GLPK 4.16 (release date: May 05, 2007) + + A number of basic GLPK API routines, which now are in the + stable stable, were renamed to be prefixed with 'glp_'. Note + that all these routines are available via their old names + prefixed with 'lpx_' that keeps the downward compatibility with + older versions of the package. + + Three new GLPK API routines were added to the package: + glp_version, glp_term_hook, and glp_mem_usage; for more details + see a new edition of the GLPK reference manual included in the + distribution. The routine glp_version reports the actual version + of the GLPK library and also can be used (along with the header + glpk.h) in Autotools specification files to check if the GLPK + library has been installed. + + The header glpk.h was changed to conform to C++ environment. + +GLPK 4.15 (release date: Feb 18, 2007) + + Autotools specification files (configure.ac, Makefile.am) were + changed to use GNU Libtool. This allows building the static as + well as shared GLPK library. + +GLPK 4.14 (release date: Feb 05, 2007) + + Now GLPK conforms to ILP32, LLP64, and LP64 programming models + (the latter seems to be the ultimate choice regarding 64-bit + architectures). Note that GLPK itself is a 32-bit application, + and the conformity only means that the package works correctly + on all these arenae. Nevertheless, on 64-bit platforms it is + possible to use more than 4GB of memory, if necessary. + +GLPK 4.13 (release date: Nov 13, 2006) + + A tentative implementation of the "exact" simplex method based + on bignum (rational) arithmetic was included in the package. + + On API level this new feature is available through the routine + lpx_exact, which is similar to the routine lpx_simplex. + + In the solver glpsol this feature is available through two new + command-line options: --exact and --xcheck. If the '--exact' + option is specified, glpsol solves LP instance using the exact + simplex method; in case of MIP it is used to obtain optimal + solution of LP relaxation. If the --xcheck option is specified, + LP instance (or LP relaxation) is solved using the standard + (floating-point) simplex method, however, then glpsol calls the + exact simplex routine to make sure that the final LP basis is + exactly optimal, and if it is not, to perform some additional + simplex iterations in exact arithmetic. + +GLPK 4.12 (release date: Nov 08, 2006) + + A tentative implementation of some simplex method routines + based on exact (bignum) arithmetic was included in the package. + Currently these routines provide computing LU-factorization of + the basis matrix and computing components of basic solution. + + These routines were used to implement a routine, which checks + primal and dual feasibility of basic solution exactly, i.e. in + rational numbers, without round-off errors. In glpsol this + feature is available through the command-line option --xcheck. + + GLPK has its own low-level routines implementing operations on + integer and rational numbers that makes it independent on other + software packages. However, to attain a much better performance + it is highly recommended to install (before configuring GLPK) + the GNU Multiple Precision Arithmetic Library (GMP). Using GMP + makes computations 100-200 times faster. + +GLPK 4.11 (release date: Jul 25, 2006) + + Three new built-in functions in the modeling language were + implemented: card (cardinality of set), length (length of + character string), and substr (substring of character string). + Another improvement concerns the printf statement which now + allows redirecting its output to a specified file. These new + features are illustrated in example models crypto.mod and + graph.mod included in the distribution. For more details see + the document "Modeling Language GNU MathProg". + + Four batch files (along with corresponding makefiles) were + included in the distribution to simplify building GLPK under + MS Windows; see them in subdirectory 'w32'. + +GLPK 4.10 (release date: May 11, 2006) + + Cutting planes of two new classes were implemented: mixed cover + cuts and clique cuts. On API level this feature can be enabled + by setting control parameter LPX_K_USECUTS passed to the routine + lpx_intopt. In glpsol this feature is available through the + command-line options --cover and --clique. For more details see + the reference manual. + + Now the routines lpx_read_mps and lpx_read_freemps support LI + bound type. It is similar to LO, however, indicates the column + as of integer kind. + +GLPK 4.9 (release date: Jan 17, 2006) + + An advanced MIP solver was implemented. It includes: + + - basic presolving technique (removing free, singleton and + redundant rows, improving bounds of columns, removing fixed + columns, reducing constraint coefficents); + + - generating cutting planes to improve LP relaxation (currently + only Gomory's mixed integer cuts are implemented); + + - using the branch-and-bound method to solve resultant MIP; + + - recovering solution of the original MIP. + + The solver is available on API level via the routine lpx_intopt + (see the reference manual). It is similar to the routine + lpx_integer, however, does not require initial solution of LP + relaxation. + + The solver is also available in the command-line utility glpsol + via two options: --intopt (only presolving) and --cuts (assumes + --intopt plus generating cuts). + + Note that efficiency of the MIP solver strongly depends on the + internal structure of the problem to be solved. For some hard + instances it is very efficient, but for other instances it may + be significantly worse than the standard branch-and-bound. + + For some comparative benchmarks see doc/bench1.txt. + + Well, what else... + + Three built-in functions were added to MathProg: sin, cos, and + atan (the latter allows one or two arguments). + + Some bugs were fixed. + + Several new examples in MathProg were included: color.mod + (graph coloring problem), tsp.mod (traveling salesman problem), + and pbn.mod (paint-by-numbers puzzle). + +GLPK 4.8 (release date: Jan 12, 2005) + + Core simplex method and interior-point method routines were + re-implemented and now they use a new, "storage-by-rows" sparse + matrix format (unlike previous versions where linked lists were + used to represent sparse matrices). For details see ChangeLog. + + Also a minor bug was fixed in API routine lpx_read_cpxlp. + +GLPK 4.7 (release date: Aug 23, 2004) + + Now GLPK supports free MPS format. Two new API routines + lpx_read_freemps (to read problem data in free MPS format) and + lpx_write_freemps (to write problem data in free MPS format) + were added. This feature is also available in the solver glpsol + via new command-line options --freemps and --wfreemps. For more + details see the GLPK reference manual. + + API routines lpx_read_cpxlp and lpx_write_cpxlp for reading and + writing problem data in CPLEX LP format were re-implemented to + allow long symbolic names (up to 255 characters). + + The following three modules were temporarily removed from the + GLPK distribution due to licensing problems: DELI (an interface + module to Delphi), GLPKMEX (an interface module to Matlab), and + JNI (an interface module to Java). + +GLPK 4.6 (release date: Aug 04, 2004) + + Three new statements were implemented in the GNU MathProg + language: solve, printf, and for. Their detailed description can + be found in the GLPK documentation included in the distribution. + (See also a sample model, examples/queens.mod, which illustrates + using these new statements.) + + Two new API routines were added to the package: lpx_read_prob + and lpx_write_prob. They allow reading/writing problem data in + GNU LP low-level text format. + + Three new command-line options were implemented in the LP/MIP + solver glpsol: --glp (to read problem data in GNU LP format), + --wglp (to write problem data in GNU LP format), and --name (to + change problem name). Now glpsol also supports processing models + where the new statements (see above) are used. + + A new version of GLPKMEX, a Matlab MEX interface to GLPK, was + included. For more details see contrib/glpkmex/ChangeLog. + +GLPK 4.5 (release date: Jul 19, 2004) + + The branch-and-bound solver was completely re-implemented. + + Some modifications were made in memory allocation routines that + allows using the package on 64-bit platforms. + + For more details see ChangeLog. + +GLPK 4.4 (release date: Jan 17, 2004) + + All API routines were re-implemented using new data structures. + The new implementation provides the same specifications and + functionality of API routines as the old one, however, it has + some important advantages, in particular: + * linked lists are used everywhere that allows creating and + modifying the problem object as efficiently as possible + * all data stored in the problem object are non-scaled (even if + the internal scaling is used) that prevents distortion of the + original problem data + * solution components obtained by the solver remain available + even if the problem object has been modified + * no solver-specific data are used in the new data structures + that allows attaching any external lp/mip solver using GLPK + API as an uniform interface + Note that some API routines became obsolete being replaced by + new, more convenient routines. These obsolete routines are kept + for backward compatibility, however, they will be removed in + the future. For more details please see ChangeLog and the GLPK + Reference Manual. + + New edition of the GLPK Reference Manual was included in the + distribution. + + GLPKMEX, a Matlab MEX interface to GLPK package, contributed by + Nicolo Giorgetti was included in the + distribution. + + GLPK FAQ contributed by Harley Mackenzie was + included in the distribution. + +GLPK 4.3 (release date: Dec 12, 2003) + + The bug, due to which the standard math library is not linked + on building the package on some platforms, was fixed. + + The following new built-in functions were added to the MathProg + language: round, trunc, Irand224, Uniform01, Uniform, Normal01, + Normal. For details see the language description. + + The MathProg syntax was changed to allow writing 'subj to' that + means 'subject to'. + + The new api routine lpx_get_ray_info was added. It is intended + to determine which (non-basic) variable causes unboundness. For + details see the reference manual. + + The module glpmps.c was changed to avoid compilation errors on + building the package on Mac OS X. + + Several typos was fixed and some new material was added to the + GLPK documentation. + +GLPK 4.2 (release date: Nov 14, 2003) + + A preliminary implementation of the Integer Optimization Suite + (IOS) was included in the package. The Branch-and-Cut Framework + being completely superseded by IOS was removed from the package. + + New API routine lpx_print_sens_bnds intended for bounds + sensitivity analysis was contributed to GLPK by Brady Hunsaker + . This function is also available in + the solver glpsol (via command-line option --bounds). + + An improved version of GLPK JNI (Java Native Interface) was + contributed by Chris Rosebrugh . + + GLPK DELI (Delphi Interface) was contributed by Ivo van Baren + . + + Several makefiles were added to allow compiling GLPK on some + non-GNU 32-bit platforms: + * Windows single-threaded static library, Visual C++ 6.0 + * Windows multi-threaded dynamic library, Visual C++ 6.0 + * Windows single-threaded static library, Borland C++ 5.2 + * DOS single-threaded static library, Digital Mars C++ 7.50 + + And, of course, some bugs were fixed. + + For more details see ChangeLog. + +GLPK 4.1 (release date: Aug 23, 2003) + + Some improvements were made in the lp/mip solver routines and + several bugs were fixed in the model translator. + + For more details see ChangeLog. + +GLPK 4.0 (release date: May 06, 2003) + + Now GLPK supports the GNU MathProg modeling language, which is + a subset of the AMPL modeling language. + + The document "GLPK: Modeling Language GNU MathProg" included in + the distribution is a complete description of GNU MathProg. (See + the files lang.latex, lang.dvi, and lang.ps in the subdirectory + 'doc'. See also some examples in the subdirectory 'sample'.) + + New version of the solver glpsol, which supports models written + in GNU MathProg, was implemented. (Brief instructions how to use + glpsol can be found in the GNU MathProg documentation.) + + The GLPK/L modeling language is no more supported. The reason is + that GNU MathProg being much more powerful completely supersedes + all features of GLPK/L. + +GLPK 3.3 (release date: Mar 25, 2003) + + LP PRESOLVER + ------------ + + Now the routine lpx_simplex (which is a driver to the simplex + method for solving LP) is provided with the built-in LP + presolver, which is a program that transforms the original LP + problem to an equivalent LP problem, which may be easier for + solving with the simplex method than the original one. Once the + transformed LP has been solver, the presolver transforms its + basic solution back to a corresponding basic solution of the + original problem. For details about this feature please see the + GLPK reference manual. + + Currently the LP presolver implements the following features: + * removing empty rows; + * removing empty columns; + * removing free rows; + * removing fixed columns; + * removing row singletons, which have the form of equations; + * removing row singletons, which have the form of inequalities; + * removing column singletons, which are implied slack variables; + * fixing and removing column singletons, which are implied free + variables; + * removing forcing rows that involves fixing and removing the + corresponding columns; + * checking for primal and dual infeasibilities. + + The LP presolver is also used by default in the stand-alone + program glpsol. In order *not* to use it, the option --nopresol + should be specified in the command-line. + + CHANGES IN GLPK/L + ----------------- + + The syntax and semantics of the GLPK/L modeling language was + changed to allow declaration of "interval" sets. This means that + now the user can declare a set, for example, as: + + set task = [8:11]; + + that is exactly equivalent to the following declaration: + + set task = (task_8, task_9, task_10, task_11); + + For details see the language description. + + JAVA INTERFACE + -------------- + + Now GLPK includes the package GLPK JNI (Java Native Interface) + that implements Java binding for GLPK. It allows Java programs + to utilize GLPK in solving LP and MIP problems. For details see + a brief user's guide in the subdirectory contrib/java-binding. + This package was developed and programmed by Yuri Victorovich + , who contributed it to GLPK. + +GLPK 3.2.4 (release date: Feb 18, 2003) + + This is a bug-fix release. For details see ChangeLog. + +GLPK 3.2.3 (release date: Nov 11, 2002) + + A new implementation of the api routine lpx_integer which now + is based on the b&b driver (which is based on the implicit + enumeration suite) was included in the package. This new + implementation has exactly the same functionality as the old + version, so all changes are transparent to the api user. + + Four new api routines were included in the package: + lpx_check_kkt checks Karush-Kuhn-Tucker optmality conditions; + lpx_read_bas reads predifined basis in MPS format; + lpx_write_bas writes current basis in MPS format; + lpx_write_lpt writes problem data in CPLEX LP format. + + Also other minor improvements were made (for details see the + file 'ChangeLog'). + +GLPK 3.2.2 (release date: Oct 14, 2002) + + The api routine lpx_read_lpt was included in the package. It + is similar to the routine lpx_read_mps and intended to read + LP/MIP data prepared in CPLEX LP format. Description of this + format is given in the GLPK reference manual, a new edition of + which was also included in the distribution (see the files + 'refman.latex', 'refman.dvi', 'refman.ps' in the subdirectory + 'doc'). In order to use data files in CPLEX LP format with the + solver glpsol the option '--lpt' should be specified in the + command line. + + Several bugs were fixed and some minor improvements were made + (for details see the file 'ChangeLog'). + +GLPK 3.2.1 (release date: Aug 12, 2002) + + Now GLPK includes a preliminary implementation of the + branch-and-cut framework, which is a set of data structures and + routines intended for developing branch-and-cut methods for + solving mixed-integer and combinatorial optimization problems. + + Detailed decsription of the branch-and-cut framework is given in + the document "GLPK: A Preliminary Implementation of the + Branch-And-Cut Framework" included in the distribution (see the + file 'brcut.txt' in the subdirectory 'doc'). + + In order to illustrate how the GLPK branch-and-cut framework + can be used for solving a particular optimization problem there + is an example included in the package. This is a stand-alone + program, TSPSOL, which is intended for solving to optimality the + symmetric Traveling Salesman Problem (TSP), a classical problem + of the combinatorial optimization (see the file 'tspsol.c' in + the subdirectory 'sample'). + +GLPK 3.2 (release date: Jul 15, 2002) + + New edition of the document "GLPK: Reference Manual" was + included (see the files 'refman.latex', 'refman.dvi', and + 'refman.ps' in the subdirectory 'doc'). + + New edition of the document "GLPK: Modeling Language GLPK/L" was + included (see the files 'lang.latex', 'lang.dvi', and 'lang.ps' + in the subdirectory 'doc'). + + The following new API routines were added to the package: + + lpx_transform_row (transform explicitly specified row); + lpx_transform_col (transform explicitly specified column); + lpx_prim_ratio_test (perform primal ratio test); + lpx_dual_ratio_test (perform dual ratio test); + lpx_interior (solve LP problem using interior point method); + lpx_get_ips_stat (query status of interior point solution); + lpx_get_ips_row (obtain row interior point solution); + lpx_get_ips_col (obtain column interior point solution); + lpx_get_ips_obj (obtain interior point value of obj.func.); + lpx_read_lpm (read LP/MIP model written in GLPK/L); + lpx_write_mps (write problem data using MPS format); + lpx_print_ips (print interior point solution). + + Detailed description of all these new API routines are given in + the new edition of the reference manual. + + New version of the stand-alone solver glpsol (which is based on + the new API) was implemented. + + So long as the new API (introduced in glpk 3.0) now provides + all the functions, which were provided by the old API, the old + API routines were removed from the package at all. + +GLPK 3.1 (release date: May 27, 2002) + + A preliminary implementation of new API routines was completed + and included in the package. + + These new API routines provide much more flexible interaction + between the application program, LP/MIP problem instances, and + solver routines. Based on completely changed data structures + they are, however, similar to the API routines and provide the + same functionality. Please note that three routines, namely, + solving LPs using interior point method, reading model written + in the GLPK/L modeling language, and writing problem data in + the MPS format, are not implemented in the new API, however, + these routines are planned to be implemented in the next version + of the package. + + A description of the new API routines is given in the document + "GLPK Reference Manual", a draft edition of which is included + in the package (see the files 'refman.latex', 'refman.dvi', and + 'refman.ps' in the subdirectory 'doc'). + + Although the old API routines are kept in the package, they are + no longer supported and will be removed in the future. + +GLPK 3.0.8 (release date: May 13, 2002) + + A preliminary implementation of new API routines was included + in the package. These new API routines are intended to provide + much more flexible interaction between the application program, + LP/MIP problem and solver routines. See the document "New GLPK + API Routines" (the file 'newapi.txt' in the subdirectory 'doc') + also included in the package. + + The api routines glp_simplex2, glp_call_ipm1, glp_call_bbm1 were + renamed, respectively, to glp_simplex, glp_interior, glp_integer + in order to reflect changes in implementation. The api routines + glp_call_rsm1, glp_simplex1, glp_pivot_in, glp_pivout_out were + removed from the package since they are completely supreseded by + the new API routines (however, these routines still can be found + in the subdirectory 'oldsrc'). Please consult a new edition of + the document "GLPK User's Guide" about all these changes in the + existing api routines. + + The document "GLPK Library Reference" was removed from the + package (into the subdirectory 'oldsrc') since it describes the + obsolete library routines, most of which are no longer used. + +GLPK 3.0.7 (release date: Apr 22, 2002) + + A new, more efficient implementation of the primal/dual simplex + method was included in the package. Due to some improvements the + simplex-based solver allows solving many LP problems faster and + provides more reliable results. Note that the new implementation + is currently incomplete and available only via the api routine + glp_simplex2. + + All the changes are transparent on API level. + +GLPK 3.0.6 (release date: Mar 28, 2002) + + New version of LU-factorization and basis maintenance routines + (based on Forrest-Tomlin updating technique) was implemented. + Since these new routines functionally supersede some routines + (which implement other forms of the basis matrix) and make them + obsolete, the latter were removed from the package (they still + can be found in the subdirectory 'oldsrc'). + + All the changes are transparent on API level. + +GLPK 3.0.5 (release date: Jan 29, 2002) + + New edition of the document "GLPK User's Guide" was included in + the distribution. Now it describes all additional API routines, + which were recently added to the package. + + Structure of the package was re-organized in order to make its + maintenance easier (all small files in the subdurectory 'source' + were merged in bigger units). These changes are transparent for + the user. + +GLPK 3.0.4 (release date: Dec 10, 2001) + + A new, more efficient implementation of the two-phase primal + simplex method was included in the package. Due to some new + features (an advanced initial basis, projected steepest edge, + recursive updating values and reduced costs) the new LP solver + is faster and numerically more stable than the old one. + + The new LP solver is available as API routine glp_simplex2 and + has the same purpose as API routine glp_call_rsm1. For detailed + specification see the file 'newapi.txt' in the directory 'doc'. + + Now the new LP solver is also used by default to solve an + initial LP problem in the branch-and-bound routine glp_call_bbm1 + instead the routine rsm1_driver. Note that the branch-and-bound + procedure itself is still based on rsm1_driver. + + The new LP solver is also used as default solver in GLPSOL for + solving LP and MIP problems. In order to choose the old solver + the option '--old-sim' can be specified in the command line. + +GLPK 3.0.3 (release date: Oct 03, 2001) + + Some minor changes were made in the simplex method routines in + order to improve numerical stability of the method. + +GLPK 3.0.2 (release date: Sep 24, 2001) + + A new implementation of the basis maintaining routines was + included in the package. These routines, which are based on so + called FHV-factorization (a variety of LU-factorization) of the + basis matrix and Gustavson's data structures, allows performing + the main operations faster at the expense of some worsening + numerical accuracy. + + AFI (Advanced Form of the Inverse), which is the form of the + basis matrix based on FHV-factorization, is available via the + parameter form = 3 (on API level) or via the option --afi (in + GLPSOL solver). + +GLPK 3.0.1 (release date: Aug 01, 2001) + + Old GLPK API routines have been removed from the package. + + New GLPK API routines were added: + + - scaling routines; + + - a routine for writing problem data in MPS format; + + - a comprehensive driver to the simplex method; + + - basis maintaining routines. + + A description of the new API routines is given in the document + "Additional GLPK API Routines". This document is included into + the distribution in plain text format (see the file 'newapi.txt' + in the subdirectory 'doc'). + + Now the distribution includes a non-trivial example of using + GLPK as a base LP solver for Concorde, a well known program that + solves Traveling Salesman Problem (TSP). For further details see + comments in the file 'sample/lpglpk30.c'. + +GLPK 3.0 (release date: Jul 19, 2001) + + Now GLPK is provided with new API, which being more flexible + can be used in more complex algorithmic schemes. + + New edition of the document "GLPK User's Guide" is included in + the distribution. Now it completely corresponds to the new GLPK + API routines. + + Old API routines are not removed yet from the package, however + they became obsolete and therefore should not be used. Since now + the header glpk.h corresponds to new API, in order to compile + existing programs that use old GLPK API routines the statement + + #define GLP_OLD_API + + should be inserted before the statement + + #include "glpk.h" + +GLPK 2.4.1 (release date: Jun 14, 2001) + + The document "Modeling language GLPK/L" is included into the + distribution in texinfo format. + + New edition of the document "GLPK User's Guide" is included in + the distribution. Now it describes all additional API routines + which were recently added to the package. + +GLPK 2.4 (release date: May 10, 2001) + + Now GLPK includes an implementation of a preliminary version + of the GLPK/L modeling language. This language is intended for + writing mathematcal programming models. The name GLPK/L is + derived from GNU Linear Programming Kit Language. + + A brief description of the GLPK/L language is given in the + document "GLPK/L Modeling Language: A Brief Description". This + document is included into the distribution in plain text format + (see the file 'language.txt' in the subdirectory 'doc'). + + The language processor (which is a program that analyzes model + description written in GLPK/L and translates it to internal data + structures) is available as the GLPK API routine. + + The stand-alone solver GLPSOL now is able: a) to process model + descriptions written in the GLPK/L language; b) to solve pure LP + problems using the interior point method (therefore the program + GLPIPM was removed from the package). + +GLPK 2.3 (release date: Apr 09, 2001) + + New edition of the document "GLPK User's Guide" is included in + the distribution. Now it describes all additional API routines + which were recently added to the package. + + The MIP solver was fully re-programmed in order to improve its + robustness and performance. In particular, a basis recovering + procedure was implemented (this procedure allows switching to + the primal simplex method in case when the dual simplex method + fails). + +GLPK 2.2 (release date: Mar 15, 2001) + + Now GLPK includes a tentative implementation of the + branch-and-bound procedure based on the dual simplex method for + mixed integer linear programming (MIP). + + Complete description of this new feature of the package is given + in the preliminary document "Mixed Integer Linear Programming + Using GLPK Version 2.2 (Supplement to GLPK User's Guide)". This + document is included into the distribution in plain text format + (see the file 'mip.txt' in the subdirectory 'doc'). + + The MIP solver (glp_integer) can be used as GLPK API routine in + the same way as the pure LP solver (glp_simplex). + + The stand-alone program 'glpsol' is now able to solve LP as well + as MIP problems. + + Note that the current version of GLPK MIP solver is based on + easiest heuristics for branching and backtrackng. Therefore the + solver is fit mainly for MIP problems which are not very hard + and have few integer variables. + +GLPK 2.1 (release date: Feb 19, 2001) + + The document "GLPK Implementation of the Revised Simplex Method" + is included into the distribution. This document describes most + of routines related to the revised simplex method. + +GLPK 2.0 (release date: Jan 25, 2001) + + Now GLPK includes a tentative implementation of the primal-dual + interior point method for large-scale linear programming. + + The interior point solver can be used as GLPK API routine in the + same manner as the simplex method solver (glp_simplex): + + ret = glp_interior(); + + Note that currently the interior point solver implemented in + GLPK doesn't include many important features, in particular: + + * it can't process dense columns; therefore if the problem has + dense columns, the solving will be extremely inefficient; + + * it has no special features against numerical unstability; + some problems may cause premature termination of the solving + when the matrix A*D*A' becomes ill-conditioned; + + * it computes only values of primal (auxiliary and structural) + variables and doesn't compute values of dual variables (i.e. + reduced costs) which are just set to zero; + + * it doesn't identify optimal basis corresponding to the found + interior point solution; all variables in the found solution + are just marked as basic variables. + + GLPK also includes a stand-alone program 'glpipm' which is a + demo based on the interior point method. It may be used in the + same way as the program 'glpsol' that is based on the simplex + method. diff --git a/resources/3rdparty/glpk-4.57/README b/resources/3rdparty/glpk-4.57/README new file mode 100644 index 000000000..23550ef14 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/README @@ -0,0 +1,39 @@ + Olga K. gewidmet + +GLPK (GNU Linear Programming Kit) Version 4.57 + +Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +2009, 2010, 2011, 2013, 2014, 2015 Andrew Makhorin, Department for +Applied Informatics, Moscow Aviation Institute, Moscow, Russia. All +rights reserved. E-mail: . + +GLPK is part of the GNU Project released under the aegis of GNU. + +GLPK is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +See the file COPYING for the GNU General Public License. + +See the file INSTALL for compilation and installation instructions. + +The GLPK package is a set of routines written in ANSI C and organized +in the form of a callable library. This package is intended for solving +large-scale linear programming (LP), mixed integer linear programming +(MIP), and other related problems. + +The GLPK package includes the following main components: + +* implementation of the simplex method; +* implementation of the exact simplex method based on bignum (rational) + arithmetic; +* implementation of the primal-dual interior-point method; +* implementation of the branch-and-cut method; +* application program interface (API); +* GNU MathProg modeling language (a subset of AMPL); +* GLPSOL, a stand-alone LP/MIP solver. + +See GLPK webpage . + +Please report bugs to . diff --git a/resources/3rdparty/glpk-4.57/THANKS b/resources/3rdparty/glpk-4.57/THANKS new file mode 100644 index 000000000..fc6fd047d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/THANKS @@ -0,0 +1,223 @@ +Achim Gaedke for bug report. + +Alexandre Oliva for bug report. + +Andre Girard for bug report. + +Andrew Hamilton-Wright for bug report. + +Andrew Hood for bug report. + +Anne-Laurence Putz for bug +report. + +Anton Voropaev for bug and typo report. + +Axel Simon for bug report. + +Bernhard Schmidt for bug report. + +Boris Wirtz for bug report. + +Brady Hunsaker for contribution of a routine +for bounds sensitivity analysis. + +Brady Hunsaker for some suggestions concerning +MIP routines. + +Brian Gladman for suggestion. + +Cameron Kellough for bug report. + +Carlo Baldassi for bug report. + +Cedric[FR] for bug report. + +Charles Brixko for bug report. + +Chris Matrakidis for suggestion. + +Chris Rosebrugh for contribution of a new version of +GLPK JNI (Java Native Interface). + +Christophe Caron for bug report. + +David T. Price for bug report. + +Dennis Schridde for bug report. + +Enric Rodriguez for bug report. + +Flavio Keidi Miyazawa for bug report. + +Gabriel Hackebeil for bug report. + +Giles Thompson for bug report. + +Giorgio Sartor <0gioker0@gmail.com> for contribution of routines that +implement the proximity search heuristic for MIP. + +Graham Rockwell for bug report. + +Hans Schwengeler for bug report. + +Harley Mackenzie for contribution of GLPK FAQ. + +Dr. Harley Mackenzie for two example MathProg +models (curve fitting problem). + +Heinrich Schuchardt for contribution of +makefiles and testing the package under 64-bit Windows. + +Heinrich Schuchardt for contribution of +two MathProg table drivers for iODBC and MySQL. + +Heinrich Schuchardt for some patches for +the MathProg translator. + +Heinrich Schuchardt for testing the package on +32- and 64-bit MS Windows platforms. + +Ivan Luzzi for comments concerning CPLEX LP format. + +Ivo van Baren for contribution of GLPK DELI +(Delphi Interface). + +Jan Engelhardt for some suggestions. + +Jeffrey Kantor for reporting typos in the MathProg +language reference. + +Jeroen Demeyer for suggestion. + +Jiri Spitz for bug report. + +Joey Rios for some suggestions. + +Jonathan Senning for bug report. + +Karel Zimmermann for bug report. + +Kelly Westbrooks for suggestions. + +Kendall Demaree for bug report. + +Kjell Eikland for bug report. + +Larry D'Agostino for example model in +MathProg. + +Luiz Bettoni for some suggestions. + +Marco Atzeri for bug report. + +Marco Atzeri for bug report. + +Mark Meketon for bug report. + +Markus Pilz for bug report. + +Martin Jacob for bug report. + +Minh Ha Duong for fixing doc typos. + +Morten Welinder for bug report. + +Morten Welinder for bug report. + +Nelson H. F. Beebe for bug report. + +Nicolo Giorgetti for contribution of GLPKMEX, +a Matlab MEX interface. + +Niels Klitgord for bug report. + +Nigel Galloway for an example MathProg +model. + +Nigel Galloway for an example program +in C#. + +Nigel Galloway for bug report. + +Nigel Galloway for example models in +MathProg. + +Noli Sicad for testing glpk under Mac OS. + +Noli Sicad for example model in MathProg. + +Olivier for bug report. + +Oscar Gustafsson for contribution of a routine to +write data in OPB (pseudo boolean) format. + +Pablo Yapura for translation the document +"Modeling Language GNU MathProg" to Spanish. + +Pedro P. Wong for bug report. + +Peter T. Breuer for bug report. + +Peter A. Huegler for bug report. + +Peter Ingerfeld for bug report. + +Peter Lee for example LP model and bug report. + +Pietro Scionti for report typos found in +the reference manual. + +Rafael Laboissiere for useful advices concerning +shared library support under GNU/Linux. + +Raniere Gaia Costa da Silva for bug report. + +Remy Roy for bug report. + +Robbie Morrison for correcting the glpk manual. + +Robert Wood for example model in MathProg. + +Roberto Bagnara (Department of Mathematics, +University of Parma, Italy) for bug report. + +Sami Farin for bug report. + +Sebastian Nowozin for example models in MathProg. + +Sebastien Briais for bug report. + +Sebastien de Menten for bug report. + +Sebastien Villemot for bug report. + +Stefan Vigerske for bug report. + +Stefan Vigerske for bug report. + +Sylvain Fournier for bug report. + +Thomas Kahle for some suggestions. + +Uday Venkatadri for bug report. + +Vijay Patil for testing the package under +Windows XP. + +Vlahos Kiriakos for bug report. + +Xypron for bug fixing and some improvments in the +FPUMP module. + +Xypron for bug patch. + +Xypron for contribution and testing batch scripts +to build Glpk with MS Visual Studio 2010. + +Xypron for improving the SQL table driver. + +Xypron for testing GLPK on 64-bit platforms and +for maintaining Windows versions of the package. + +Yuri Victorovich for contribution of GLPK Java binding. diff --git a/resources/3rdparty/glpk-4.57/aclocal.m4 b/resources/3rdparty/glpk-4.57/aclocal.m4 new file mode 100644 index 000000000..636b7ac2f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/aclocal.m4 @@ -0,0 +1,949 @@ +# generated automatically by aclocal 1.12.5 -*- Autoconf -*- + +# Copyright (C) 1996-2012 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# Copyright (C) 2002-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.12' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.12.5], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.12.5])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], +[$0: two- and three-arguments forms are deprecated. For more info, see: +http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_INIT_AUTOMAKE-invocation]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +dnl Support for Objective C++ was only introduced in Autoconf 2.65, +dnl but we still cater to Autoconf 2.62. +m4_ifdef([AC_PROG_OBJCXX], +[AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The 'parallel-tests' driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of '-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) diff --git a/resources/3rdparty/glpk-4.57/config.guess b/resources/3rdparty/glpk-4.57/config.guess new file mode 100755 index 000000000..872b96a16 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/config.guess @@ -0,0 +1,1537 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-09-25' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/resources/3rdparty/glpk-4.57/config.h.in b/resources/3rdparty/glpk-4.57/config.h.in new file mode 100644 index 000000000..2849bf9c4 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/config.h.in @@ -0,0 +1,27 @@ +/* config.h.in (GLPK configuration template file) */ + +#undef HAVE_SYS_TIME_H +/* defined if the header can be used */ + +#undef HAVE_GETTIMEOFDAY +/* defined if the gettimeofday function can be used */ + +#undef HAVE_GMP +/* defined if the GNU MP bignum library is available */ +/* requires and -lgmp */ + +#undef HAVE_LTDL +/* defined if the GNU Libtool shared library support is enabled */ +/* requires and -lltdl */ + +#undef HAVE_DLFCN +/* defined if the POSIX shared library support is enabled */ +/* requires */ + +#undef ODBC_DLNAME +/* ODBC shared library name if this feature is enabled */ + +#undef MYSQL_DLNAME +/* MySQL shared library name if this feature is enabled */ + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/config.sub b/resources/3rdparty/glpk-4.57/config.sub new file mode 100755 index 000000000..89b128630 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/config.sub @@ -0,0 +1,1789 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-10-10' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/resources/3rdparty/glpk-4.57/configure b/resources/3rdparty/glpk-4.57/configure new file mode 100755 index 000000000..b6b02927c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/configure @@ -0,0 +1,13840 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for GLPK 4.57. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and bug-glpk@gnu.org +$0: about your system, including any error possibly output +$0: before this message. Then install a modern shell, or +$0: manually run the script under such a shell if you do +$0: have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='GLPK' +PACKAGE_TARNAME='glpk' +PACKAGE_VERSION='4.57' +PACKAGE_STRING='GLPK 4.57' +PACKAGE_BUGREPORT='bug-glpk@gnu.org' +PACKAGE_URL='' + +ac_unique_file="src/glpk.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +CPP +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBTOOL +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +with_gmp +enable_dl +enable_odbc +enable_mysql +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +with_sysroot +enable_libtool_lock +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures GLPK 4.57 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/glpk] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of GLPK 4.57:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-dl enable shared library support [[default=no]] + --enable-odbc enable MathProg ODBC support [[default=no]] + --enable-mysql enable MathProg MySQL support [[default=no]] + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-gmp use GNU MP bignum library [[default=no]] + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +GLPK configure 4.57 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ------------------------------- ## +## Report this to bug-glpk@gnu.org ## +## ------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by GLPK $as_me 4.57, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + +am__api_version='1.12' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='glpk' + VERSION='4.57' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +ac_config_headers="$ac_config_headers config.h" + + + +# Check whether --with-gmp was given. +if test "${with_gmp+set}" = set; then : + withval=$with_gmp; case $withval in + yes | no) ;; + *) as_fn_error $? "invalid value \`$withval' for --with-gmp" "$LINENO" 5;; + esac +else + with_gmp=no +fi + + +# Check whether --enable-dl was given. +if test "${enable_dl+set}" = set; then : + enableval=$enable_dl; case $enableval in + yes | ltdl | dlfcn | no) ;; + *) as_fn_error $? "invalid value \`$enableval' for --enable-dl" "$LINENO" 5;; + esac +else + enable_dl=no +fi + + +# Check whether --enable-odbc was given. +if test "${enable_odbc+set}" = set; then : + enableval=$enable_odbc; case $enableval in + yes | unix | no) ;; + *) as_fn_error $? "invalid value \`$enableval' for --enable-odbc" "$LINENO" 5;; + esac +else + enable_odbc=no +fi + + +# Check whether --enable-mysql was given. +if test "${enable_mysql+set}" = set; then : + enableval=$enable_mysql; case $enableval in + yes | no) ;; + *) as_fn_error $? "invalid value \`$enableval' for --enable-mysql" "$LINENO" 5;; + esac +else + enable_mysql=no +fi + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4' +macro_revision='1.3294' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + lt_prog_compiler_pic='-Xcompiler -fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld='-rpath $libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for exp in -lm" >&5 +$as_echo_n "checking for exp in -lm... " >&6; } +if ${ac_cv_lib_m_exp+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char exp (); +int +main () +{ +return exp (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_m_exp=yes +else + ac_cv_lib_m_exp=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_exp" >&5 +$as_echo "$ac_cv_lib_m_exp" >&6; } +if test "x$ac_cv_lib_m_exp" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBM 1 +_ACEOF + + LIBS="-lm $LIBS" + +fi + + +ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_time_h" = xyes; then : + +$as_echo "#define HAVE_SYS_TIME_H 1" >>confdefs.h + +fi + + + +ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" +if test "x$ac_cv_func_gettimeofday" = xyes; then : + +$as_echo "#define HAVE_GETTIMEOFDAY 1" >>confdefs.h + +fi + + +if test "$with_gmp" = "yes"; then + ac_fn_c_check_header_mongrel "$LINENO" "gmp.h" "ac_cv_header_gmp_h" "$ac_includes_default" +if test "x$ac_cv_header_gmp_h" = xyes; then : + +else + as_fn_error $? "gmp.h header not found" "$LINENO" 5 +fi + + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use GNU MP bignum library" >&5 +$as_echo_n "checking whether to use GNU MP bignum library... " >&6; } +if test "$with_gmp" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_GMP 1" >>confdefs.h + + LIBS="-lgmp $LIBS" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable shared library support" >&5 +$as_echo_n "checking whether to enable shared library support... " >&6; } +if test "$enable_dl" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ltdl" >&5 +$as_echo "ltdl" >&6; } + +$as_echo "#define HAVE_LTDL 1" >>confdefs.h + + LIBS="-lltdl $LIBS" +elif test "$enable_dl" = "ltdl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ltdl" >&5 +$as_echo "ltdl" >&6; } + +$as_echo "#define HAVE_LTDL 1" >>confdefs.h + + LIBS="-lltdl $LIBS" +elif test "$enable_dl" = "dlfcn"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: dlfcn" >&5 +$as_echo "dlfcn" >&6; } + +$as_echo "#define HAVE_DLFCN 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +case $host_os in + darwin* | macosx*) + LIBIODBC="libiodbc.dylib" + LIBODBC="libodbc.dylib" + LIBMYSQL="libmysqlclient.dylib" + ;; + *) + LIBIODBC="libiodbc.so" + LIBODBC="libodbc.so" + LIBMYSQL="libmysqlclient.so" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable MathProg ODBC support" >&5 +$as_echo_n "checking whether to enable MathProg ODBC support... " >&6; } +if test "$enable_odbc" = "yes"; then + if test "$enable_dl" = "no"; then + as_fn_error $? "--enable-odbc requires --enable-dl" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$(iodbc-config --cflags) $CFLAGS" + +cat >>confdefs.h <<_ACEOF +#define ODBC_DLNAME "$LIBIODBC" +_ACEOF + +elif test "$enable_odbc" = "unix"; then + if test "$enable_dl" = "no"; then + as_fn_error $? "--enable-odbc requires --enable-dl" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unix" >&5 +$as_echo "unix" >&6; } + +cat >>confdefs.h <<_ACEOF +#define ODBC_DLNAME "$LIBODBC" +_ACEOF + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable MathProg MySQL support" >&5 +$as_echo_n "checking whether to enable MathProg MySQL support... " >&6; } +if test "$enable_mysql" = "yes"; then + if test "$enable_dl" = "no"; then + as_fn_error $? "--enable-mysql requires --enable-dl" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CPPFLAGS="-I/usr/include/mysql $CPPFLAGS" + +cat >>confdefs.h <<_ACEOF +#define MYSQL_DLNAME "$LIBMYSQL" +_ACEOF + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +ac_config_files="$ac_config_files src/Makefile examples/Makefile Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by GLPK $as_me 4.57, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +GLPK config.status 4.57 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_flag_spec_ld \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="" + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + diff --git a/resources/3rdparty/glpk-4.57/configure.ac b/resources/3rdparty/glpk-4.57/configure.ac new file mode 100644 index 000000000..e0e06cf49 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/configure.ac @@ -0,0 +1,148 @@ +dnl Process this file with autoconf to produce a configure script + +AC_INIT([GLPK], [4.57], [bug-glpk@gnu.org]) + +AC_CONFIG_SRCDIR([src/glpk.h]) + +AC_CONFIG_MACRO_DIR([m4]) + +AM_INIT_AUTOMAKE + +AC_CONFIG_HEADERS([config.h]) + +AC_ARG_WITH(gmp, +AC_HELP_STRING([--with-gmp], + [use GNU MP bignum library [[default=no]]]), + [case $withval in + yes | no) ;; + *) AC_MSG_ERROR([invalid value `$withval' for --with-gmp]);; + esac], + [with_gmp=no]) + +AC_ARG_ENABLE(dl, +AC_HELP_STRING([--enable-dl], + [enable shared library support [[default=no]]]), + [case $enableval in + yes | ltdl | dlfcn | no) ;; + *) AC_MSG_ERROR([invalid value `$enableval' for --enable-dl]);; + esac], + [enable_dl=no]) + +AC_ARG_ENABLE(odbc, +AC_HELP_STRING([--enable-odbc], + [enable MathProg ODBC support [[default=no]]]), + [case $enableval in + yes | unix | no) ;; + *) AC_MSG_ERROR([invalid value `$enableval' for --enable-odbc]);; + esac], + [enable_odbc=no]) + +AC_ARG_ENABLE(mysql, +AC_HELP_STRING([--enable-mysql], + [enable MathProg MySQL support [[default=no]]]), + [case $enableval in + yes | no) ;; + *) AC_MSG_ERROR([invalid value `$enableval' for --enable-mysql]);; + esac], + [enable_mysql=no]) + +dnl Disable unnecessary libtool tests +define([AC_LIBTOOL_LANG_CXX_CONFIG], [:]) +define([AC_LIBTOOL_LANG_F77_CONFIG], [:]) +define([AC_LIBTOOL_LANG_GCJ_CONFIG], [:]) + +dnl Check for programs +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_LIBTOOL + +dnl Check for math library +AC_CHECK_LIB([m], [exp]) + +dnl Check for header +AC_CHECK_HEADER([sys/time.h], + AC_DEFINE([HAVE_SYS_TIME_H], [1], [N/A])) + +dnl Check for gettimeofday function +AC_CHECK_FUNC([gettimeofday], + AC_DEFINE([HAVE_GETTIMEOFDAY], [1], [N/A])) + +dnl Check for header +if test "$with_gmp" = "yes"; then + AC_CHECK_HEADER([gmp.h], [], + [AC_MSG_ERROR([gmp.h header not found])]) +fi + +AC_MSG_CHECKING([whether to use GNU MP bignum library]) +if test "$with_gmp" = "yes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_GMP], [1], [N/A]) + LIBS="-lgmp $LIBS" +else + AC_MSG_RESULT([no]) +fi + +AC_MSG_CHECKING([whether to enable shared library support]) +if test "$enable_dl" = "yes"; then + AC_MSG_RESULT([ltdl]) + AC_DEFINE([HAVE_LTDL], [1], [N/A]) + LIBS="-lltdl $LIBS" +elif test "$enable_dl" = "ltdl"; then + AC_MSG_RESULT([ltdl]) + AC_DEFINE([HAVE_LTDL], [1], [N/A]) + LIBS="-lltdl $LIBS" +elif test "$enable_dl" = "dlfcn"; then + AC_MSG_RESULT([dlfcn]) + AC_DEFINE([HAVE_DLFCN], [1], [N/A]) +else + AC_MSG_RESULT([no]) +fi + +case $host_os in + darwin* | macosx*) + LIBIODBC="libiodbc.dylib" + LIBODBC="libodbc.dylib" + LIBMYSQL="libmysqlclient.dylib" + ;; + *) + LIBIODBC="libiodbc.so" + LIBODBC="libodbc.so" + LIBMYSQL="libmysqlclient.so" + ;; +esac + +AC_MSG_CHECKING([whether to enable MathProg ODBC support]) +if test "$enable_odbc" = "yes"; then + if test "$enable_dl" = "no"; then + AC_MSG_ERROR([--enable-odbc requires --enable-dl]) + fi + AC_MSG_RESULT([yes]) + CFLAGS="$(iodbc-config --cflags) $CFLAGS" + AC_DEFINE_UNQUOTED([ODBC_DLNAME], ["$LIBIODBC"], [N/A]) +elif test "$enable_odbc" = "unix"; then + if test "$enable_dl" = "no"; then + AC_MSG_ERROR([--enable-odbc requires --enable-dl]) + fi + AC_MSG_RESULT([unix]) + AC_DEFINE_UNQUOTED([ODBC_DLNAME], ["$LIBODBC"], [N/A]) +else + AC_MSG_RESULT([no]) +fi + +AC_MSG_CHECKING([whether to enable MathProg MySQL support]) +if test "$enable_mysql" = "yes"; then + if test "$enable_dl" = "no"; then + AC_MSG_ERROR([--enable-mysql requires --enable-dl]) + fi + AC_MSG_RESULT([yes]) + CPPFLAGS="-I/usr/include/mysql $CPPFLAGS" + AC_DEFINE_UNQUOTED([MYSQL_DLNAME], ["$LIBMYSQL"], [N/A]) +else + AC_MSG_RESULT([no]) +fi + +AC_CONFIG_FILES( + [src/Makefile examples/Makefile Makefile]) +AC_OUTPUT + +dnl eof diff --git a/resources/3rdparty/glpk-4.57/depcomp b/resources/3rdparty/glpk-4.57/depcomp new file mode 100755 index 000000000..e1f51f482 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/depcomp @@ -0,0 +1,787 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2012-07-12.20; # UTC + +# Copyright (C) 1999-2012 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' "$nl" < "$tmpdepfile" | +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependent.h'. + # Do two passes, one to just change these to + # '$object: dependent.h' and one to simply 'dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'. + # However on + # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\': + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + # tcc 0.9.26 (FIXME still under development at the moment of writing) + # will emit a similar output, but also prepend the continuation lines + # with horizontal tabulation characters. + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form 'foo.o: dependent.h', + # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'. + # Do two passes, one to just change these to + # '$object: dependent.h' and one to simply 'dependent.h:'. + sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \ + < "$tmpdepfile" > "$depfile" + sed ' + s/[ '"$tab"'][ '"$tab"']*/ /g + s/^ *// + s/ *\\*$// + s/^[^:]*: *// + /^$/d + /:$/d + s/$/ :/ + ' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + base=`echo "$source" | sed -e 's|^.*/||' -e 's/\.[-_a-zA-Z0-9]*$//'` + tmpdepfile="$base.d" + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir="$base.d-lock" + trap "echo '$0: caught signal, cleaning up...' >&2; rm -rf $lockdir" 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0 ; do + # mkdir is a portable test-and-set. + if mkdir $lockdir 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rm -rf $lockdir + break + else + ## the lock is being held by a different process, + ## wait until the winning process is done or we timeout + while test -d $lockdir && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test "$stat" = 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' "$nl" < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/resources/3rdparty/glpk-4.57/doc/cnfsat.pdf b/resources/3rdparty/glpk-4.57/doc/cnfsat.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d7ff1932fe4de6ed4e0831b6c1b9c47db02e85a8 GIT binary patch literal 59926 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 CJ^;)B literal 0 HcmV?d00001 diff --git a/resources/3rdparty/glpk-4.57/doc/cnfsat.tex b/resources/3rdparty/glpk-4.57/doc/cnfsat.tex new file mode 100644 index 000000000..4a2c3bbab --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/cnfsat.tex @@ -0,0 +1,413 @@ +%* cnfsat.tex *% + +\documentclass[11pt,draft]{article} +\usepackage{amssymb} +\usepackage{indentfirst} + +\setlength{\textwidth}{6.5in} +\setlength{\textheight}{8.5in} +\setlength{\oddsidemargin}{0in} +\setlength{\topmargin}{0in} +\setlength{\headheight}{0in} +\setlength{\headsep}{0in} +\setlength{\footskip}{0.5in} +\setlength{\parindent}{16pt} +\setlength{\parskip}{5pt} +\setlength{\topsep}{0pt} +\setlength{\partopsep}{0pt} +\setlength{\itemsep}{\parskip} +\setlength{\parsep}{0pt} +\setlength{\leftmargini}{\parindent} +\renewcommand{\labelitemi}{---} + +\def\para#1{\noindent{\bf#1}} +\def\synopsis{\para{Synopsis}} +\def\description{\para{Description}} +\def\returns{\para{Returns}} + +\newenvironment{retlist} +{ \def\arraystretch{1.5} + \noindent + \begin{tabular}{@{}p{1in}@{}p{5.5in}@{}} +} +{\end{tabular}} + +\begin{document} + +\title{\bf CNF Satisfiability Problem} + +\author{Andrew Makhorin {\tt}} + +\date{August 2011} + +\maketitle + +\section{Introduction} + +The {\it Satisfiability Problem (SAT)} is a classic combinatorial +problem. Given a Boolean formula of $n$ variables +$$f(x_1,x_2,\dots,x_n),\eqno(1.1)$$ +this problem is to find such values of the variables, on which the +formula takes on the value {\it true}. + +The {\it CNF Satisfiability Problem (CNF-SAT)} is a version of the +Satisfiability Problem, where the Boolean formula (1.1) is specified +in the {\it Conjunctive Normal Form (CNF)}, that means that it is a +conjunction of {\it clauses}, where a clause is a disjunction of +{\it literals}, and a literal is a variable or its negation. +For example: +$$(x_1\vee x_2)\;\&\;(\neg x_2\vee x_3\vee\neg x_4)\;\&\;(\neg +x_1\vee x_4).\eqno(1.2)$$ +Here $x_1$, $x_2$, $x_3$, $x_4$ are Boolean variables to be assigned, +$\neg$ means +negation (logical {\it not}), $\vee$ means disjunction (logical +{\it or}), and $\&$ means conjunction (logical {\it and}). One may +note that the formula (1.2) is {\it satisfiable}, because on +$x_1$ = {\it true}, $x_2$ = {\it false}, $x_3$ = {\it false}, and +$x_4$ = {\it true} it takes on the value {\it true}. If a formula +is not satisfiable, it is called {\it unsatisfiable}, that means that +it takes on the value {\it false} on any values of its variables. + +Any CNF-SAT problem can be easily translated to a 0-1 programming +problem as follows.\linebreak A Boolean variable $x$ can be modeled by +a binary variable in a natural way: $x=1$ means that $x$ takes on the +value {\it true}, and $x=0$ means that $x$ takes on the value +{\it false}. Then, if a literal is a negated variable, i.e. $t=\neg x$, +it can be expressed as $t=1-x$. Since a formula in CNF is a conjunction +of clauses, to provide its satisfiability we should require all its +clauses to take on the value {\it true}. A particular clause is +a disjunction of literals: +$$t\vee t'\vee t''\dots ,\eqno(1.3)$$ +so it takes on the value {\it true} iff at least one of its literals +takes on the value {\it true}, that can be expressed as the following +inequality constraint: +$$t+t'+t''+\dots\geq 1.\eqno(1.4)$$ +Note that no objective function is used in this case, because only +a feasible solution needs to be found. + +For example, the formula (1.2) can be translated to the following +constraints: +$$\begin{array}{c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c} +x_1&+&x_2&&&&&\geq&1\\ +&&(1-x_2)&+&x_3&+&(1-x_4)&\geq&1\\ +(1-x_1)&&&&&+&x_4&\geq&1\\ +\end{array}$$ +$$x_1, x_2, x_3, x_4\in\{0,1\}$$ +Carrying out all constant terms to the right-hand side gives +corresponding 0-1 programming problem in the standard format: +$$\begin{array}{r@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }r} +x_1&+&x_2&&&&&\geq&1\\ +&-&x_2&+&x_3&-&x_4&\geq&-1\\ +-x_1&&&&&+&x_4&\geq&0\\ +\end{array}$$ +$$x_1, x_2, x_3, x_4\in\{0,1\}$$ + +In general case translation of a CNF-SAT problem results in the +following 0-1 programming problem: +$$\sum_{j\in J^+_i}x_j-\sum_{j\in J^-_i}x_j\geq 1-|J^-_i|, +\ \ \ i=1,\dots,m\eqno(1.5)$$ +$$x_j\in\{0,1\},\ \ \ j=1,\dots,n\eqno(1.6)$$ +where $n$ is the number of variables, $m$ is the number of clauses +(inequality constraints),\linebreak $J^+_i\subseteq\{1,\dots,n\}$ is +a subset of variables, whose literals in $i$-th clause do not have +negation, and $J^-_i\subseteq\{1,\dots,n\}$ is a subset of variables, +whose literals in $i$-th clause are negations of that variables. It is +assumed that $J^+_i\cap J^-_i=\varnothing$ for all $i$. + +\section{GLPK API Routines} + +\subsection{glp\_read\_cnfsat --- read CNF-SAT problem data in DIMACS +format} + +\synopsis + +\begin{verbatim} + int glp_read_cnfsat(glp_prob *P, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_read_cnfsat| reads the CNF-SAT problem data from +a text file in DIMACS format and automatically translates the data to +corresponding 0-1 programming problem instance (1.5)--(1.6). + +The parameter \verb|P| specifies the problem object, to which the +0-1 programming problem instance should be stored. Note that before +reading data the current content of the problem object is completely +erased with the routine \verb|glp_erase_prob|. + +The character string \verb|fname| specifies the name of a text file +to be read in. (If the file name ends with the suffix `\verb|.gz|', +the file is assumed to be compressed, in which case the routine +decompresses it ``on the fly''.) + +\newpage + +\returns + +If the operation was successful, the routine returns zero. Otherwise, +it prints an error message and returns non-zero. + +\para{DIMACS CNF-SAT problem format}\footnote{This material is based on +the paper ``Satisfiability Suggested Format'', which is publicly +available at {\tt http://dimacs.rutgers.edu/}.} + +The DIMACS input file is a plain ASCII text file. It contains lines of +several types described below. A line is terminated with an end-of-line +character. Fields in each line are separated by at least one blank +space. + +\para{Comment lines.} Comment lines give human-readable information +about the file and are ignored by programs. Comment lines can appear +anywhere in the file. Each comment line begins with a lower-case +character \verb|c|. + +\begin{verbatim} + c This is a comment line +\end{verbatim} + +\para{Problem line.} There is one problem line per data file. The +problem line must appear before any clause lines. It has the following +format: + +\begin{verbatim} + p cnf VARIABLES CLAUSES +\end{verbatim} + +\noindent +The lower-case character \verb|p| signifies that this is a problem +line. The three character problem designator \verb|cnf| identifies the +file as containing specification information for the CNF-SAT problem. +The \verb|VARIABLES| field contains an integer value specifying $n$, +the number of variables in the instance. The \verb|CLAUSES| field +contains an integer value specifying $m$, the number of clauses in the +instance. + +\para{Clauses.} The clauses appear immediately after the problem +line. The variables are assumed to be numbered from 1 up to $n$. It is +not necessary that every variable appears in the instance. Each clause +is represented by a sequence of numbers separated by either a space, +tab, or new-line character. The non-negated version of a variable $j$ +is represented by $j$; the negated version is represented by $-j$. Each +clause is terminated by the value 0. Unlike many formats that represent +the end of a clause by a new-line character, this format allows clauses +to be on multiple lines. + +\para{Example.} Below here is an example of the data file in DIMACS +format corresponding to the CNF-SAT problem (1.2). + +\begin{footnotesize} +\begin{verbatim} +c sample.cnf +c +c This is an example of the CNF-SAT problem data +c in DIMACS format. +c +p cnf 4 3 +1 2 0 +-4 3 +-2 0 +-1 4 0 +c +c eof +\end{verbatim} +\end{footnotesize} + +\newpage + +\subsection{glp\_check\_cnfsat --- check for CNF-SAT problem instance} + +\synopsis + +\begin{verbatim} + int glp_check_cnfsat(glp\_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_check_cnfsat| checks if the specified problem +object \verb|P| contains a 0-1 programming problem instance in the +format (1.5)--(1.6) and therefore encodes a CNF-SAT problem instance. + +\returns + +If the specified problem object has the format (1.5)--(1.6), the +routine returns zero, otherwise non-zero. + +\subsection{glp\_write\_cnfsat --- write CNF-SAT problem data in DIMACS +format} + +\synopsis + +\begin{verbatim} + int glp_write_cnfsat(glp_prob *P, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_write_cnfsat| automatically translates the +specified 0-1 programming problem instance (1.5)--(1.6) to a CNF-SAT +problem instance and writes the problem data to a text file in DIMACS +format. + +The parameter \verb|P| is the problem object, which should specify +a 0-1 programming problem instance in the format (1.5)--(1.6). + +The character string \verb|fname| specifies a name of the output text +file to be written. (If the file name ends with suffix `\verb|.gz|', +the file is assumed to be compressed, in which case the routine +performs automatic compression on writing that file.) + +\returns + +If the operation was successful, the routine returns zero. Otherwise, +it prints an error message and returns non-zero. + +\subsection{glp\_minisat1 --- solve CNF-SAT problem instance with +MiniSat solver} + +\synopsis + +\begin{verbatim} + int glp_minisat1(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_minisat1| is a driver to MiniSat, a CNF-SAT +solver developed by Niklas E\'en and Niklas S\"orensson, Chalmers +University of Technology, Sweden.\footnote{The MiniSat software module +is {\it not} part of GLPK, but is used with GLPK and included in the +distribution.} + +\newpage + +It is assumed that the specified problem object \verb|P| contains +a 0-1 programming problem instance in the format (1.5)--(1.6) and +therefore encodes a CNF-SAT problem instance. + +If the problem instance has been successfully solved to the end, the +routine \verb|glp_minisat1| returns 0. In this case the routine +\verb|glp_mip_status| can be used to determine the solution status: + +\begin{itemize} +\item {\tt GLP\_OPT} means that the solver found an integer feasible +solution and therefore the corresponding CNF-SAT instance is +satisfiable; + +\item {\tt GLP\_NOFEAS} means that no integer feasible solution exists +and therefore the corresponding CNF-SAT instance is unsatisfiable. +\end{itemize} + +If an integer feasible solution was found, corresponding values of +binary variables can be retrieved with the routine +\verb|glp_mip_col_val|. + +\returns + +\begin{retlist} +0 & The MIP problem instance has been successfully solved. (This code +does {\it not} necessarily mean that the solver has found feasible +solution. It only means that the solution process was successful.)\\ + +{\tt GLP\_EDATA} & The specified problem object contains a MIP +instance which does {\it not} have the format (1.5)--(1.6).\\ + +{\tt GLP\_EFAIL} & The solution process was unsuccessful because of +the solver failure.\\ +\end{retlist} + +\subsection{glp\_intfeas1 --- solve integer feasibility problem} + +\synopsis + +\begin{verbatim} + int glp_intfeas1(glp_prob *P, int use_bound, int obj_bound); +\end{verbatim} + +\description + +The routine \verb|glp_intfeas1| is a tentative implementation of +an integer feasibility solver based on a CNF-SAT solver (currently +it is MiniSat; see Subsection 2.4). + +If the parameter \verb|use_bound| is zero, the routine searches for +{\it any} integer feasibile solution to the specified integer +programming problem. Note that in this case the objective function is +ignored. + +If the parameter \verb|use_bound| is non-zero, the routine searches for +an integer feasible solution, which provides a value of the objective +function not worse than \verb|obj_bound|. In other word, the parameter +\verb|obj_bound| specifies an upper (in case of minimization) or lower +(in case of maximization) bound to the objective function. + +If the specified problem has been successfully solved to the end, the +routine \verb|glp_intfeas1| returns 0. In this case the routine +\verb|glp_mip_status| can be used to determine the solution status: + +\begin{itemize} +\item {\tt GLP\_FEAS} means that the solver found an integer feasible +solution; + +\item {\tt GLP\_NOFEAS} means that the problem has no integer feasible +solution (if {\tt use\_bound} is zero) or it has no integer feasible +solution, which is not worse than {\tt obj\_bound} (if {\tt use\_bound} +is non-zero). +\end{itemize} + +\newpage + +If an integer feasible solution was found, corresponding values of +variables (columns) can be retrieved with the routine +\verb|glp_mip_col_val|. + +\para{Usage Notes} + +The integer programming problem specified by the parameter \verb|P| +should satisfy to the following requirements: + +\begin{enumerate} +\item All variables (columns) should be either binary ({\tt GLP\_BV}) +or fixed at integer values ({\tt GLP\_FX}). + +\item All constraint and objective coefficients should be integer +numbers in the range\linebreak $[-2^{31},\ +2^{31}-1]$. +\end{enumerate} + +Though there are no special requirements to the constraints, +currently the routine \verb|glp_intfeas1| is efficient mainly for +problems, where most constraints (rows) fall into the following three +classes: + +\begin{enumerate} +\item Covering inequalities +$$\sum_{j}t_j\geq 1,$$ +where $t_j=x_j$ or $t_j=1-x_j$, $x_j$ is a binary variable. + +\item Packing inequalities +$$\sum_{j}t_j\leq 1.$$ + +\item Partitioning equalities (SOS1 constraints) +$$\sum_{j}t_j=1.$$ +\end{enumerate} + +\returns + +\begin{retlist} +0 & The problem has been successfully solved. (This code does +{\it not} necessarily mean that the solver has found an integer +feasible solution. It only means that the solution process was +successful.) \\ + +{\tt GLP\_EDATA} & The specified problem object does not satisfy +to the requirements listed in Paragraph `Usage Notes'. \\ + +{\tt GLP\_ERANGE} & An integer overflow occured on translating the +specified problem to a CNF-SAT problem. \\ + +{\tt GLP\_EFAIL} & The solution process was unsuccessful because of +the solver failure. \\ +\end{retlist} + +\end{document} diff --git a/resources/3rdparty/glpk-4.57/doc/glpk.pdf b/resources/3rdparty/glpk-4.57/doc/glpk.pdf new file mode 100644 index 0000000000000000000000000000000000000000..51f0a4a3d6a97d8385872fdafd84d06d886e7758 GIT binary patch literal 478810 zcma&NW0WY(vL@W!yKVPw+qP}nHg?;#ZQHhO8@p}W*7SSstTp$3=bKsQN35#Ih;N5n;Ppp1_ZlM0)7ugj|Exr#QjvX|9Bdw& zGSMFR{mZ8%7LD0+Eob^GC=Xvi{v3R)N}suJ2DqvuOljdWr~z0+kP>JhOVl9f-a4bE z6`a=Z>(%0!vO|$NhVKrBY)MXNFCJL|z4Nb#obs{hN#aAr z{8*NYys7O=k12@DqNanU`Lwf3k?8KHIESXys^jyp0>d)TC&O$I$iNu478qz;Ytco$3OHFh%uDd&EN~MzGXCA|d2F-&pO}cgKQ0 z;W{{)j`66g5FOm~Xm4SHy&J-O20vY#rIM2=7I&`%VgHdo-O zbWO`$-D9T4HS?(@a~8fIBf>ax_eY^rIwkP%_z=gQ5M_zP;r$UP;bTO_NO&2IuSBRw zxtWbiMAf3cI|V9IbA!kNeBe@U%E)#)e2VjIGlJ!EQxs(q&8HX@IP%piRa`icOW15; ze~CRRY+Xs0^uMwCT!s;y9e7$Wzyd?yuuo*?Put;KY@~HDJD-2|bD7a)Soc25bVMlP zXhWa)bJL6fMz?u)Jai@B8YCH`uQyV|WDG;Nfgq|aQNH_PEO8C^X9x$S@=afx9DA}6 z1vc_Sr3RwoWz0B=kHcwW(}vl%<;vlh8oO9Jp?$O&)178}IGze)q>S=zE9_x%A8af}W1uC5rjNFgIR~ zZJ+CEc*ALzJqEi7tbdk!49jg||AW%Gzu(_;MK{PP-x^^F;nnOt3)ha0#0I?lxU^0= zu-=hwZR*RckN<*vniO;X3xcr*%fr!W1az0nlur#>yBE4JuU}_&I}xq1&(&>Hmr2iO zZl{8B#b#dNE;subZH9FJj~P>CtP}|Rp*g*V?DHq;{*oN0P9`%3!T<&^QWbxW;Ii3q z7ngaJPlfq-h@O6bDLQCDN7wP@wxUp^rH5cVr0H&H1KTyZ?DUHZA=DJ@&?40mNJKoz879LB#G)ta2e>jQzHeFOeBs6w639rr z{5D4M3IIJ=R`mg>HRBEXcmHLk`%nCro}G#PzdP`yrl!L>3##|FZlCB`pV}TQ7fY5k zDd%chV9YtdwZ-fWq4Bj#Hnf6p6i$ZZ!IfYY;MNY$v< z5K8e$S;Z=srHb>j8XqJSeK87k?d^13-BVBqd2O37Z68k95Noyz)$g{ij=BUC>saf? z79?nSuJzreB$7^V?n<(1xP{hshMJ6#$2{B+w=0+Bt^1hmch-fhdl-83gl z$`_#&VUryN%CsdC2#c=X2)9a~`;Us%M8jwrU-0q0?)wJuOrivXNRLFHf41RVqKgN- zOt)*_^0aG0D}6NVh1gUR>@{bjORXAl41{|`9qD0sR5wa3+Oe(#ZA2+M^i{EFj zaGHaWOn$e=%8P+&E!#7I^COBfgp%&B+da?P9GB{=ef5~q6+ce=28@^pN6!O7KtRvS zj${42S(pqV$a&E8iSh$ddEug#)es@TAkt1JtTy#rx_WOCR|)^S-RX6?^})u2^Om>X zlj{TwTT4dmB*Y-3)tRuu;k^yBxoE9jrA=7zYY zzYm$kMDJN<&W_O=&JzG?**r{+At2q+og)R#hVyi3y4(rN5UfHp}$|CtUn3QCwD4jMo_U}D9 z5qQHuR32hQo7M2MDOs+NZu^FT!2FtlvQ#L6SYau+)8}L7C7YunuZ$`jWkXll$d=a; zE9tNvxbbJxB$8F&%TF*Sa>Ndf&A3y#(EIP7yD_9sKOh^S%*VU ztMsh^-dK~SRqxgqmjVc6Wt+Ek-F@>%PUU1YtmLQpJRnU~x6vz@9+k z4L@0P6RyTKi7C_Ca1Xk1i3EIJ5dkcdC4C_a4RVJ}^u&Qog5mjqtTW^I>>F4y7m>a& zgAzekerH_C9rWfUiRQfW`jt%P1GrMe6|1}I9qxuWF9W)z4K{2)y9B(SXmf8vci4n< zTy2gooe++-tqR=D$Z+t19M12;7?69+0-dI!1Dn9HPK%MYsVB(S3R)}C$Xl(}xd0nGt? zO$ZZ`&697}0?nnOBOYP0PKT1TsUu7GM%(`vE^Yb=!KnT!NbMaB%co-@`g;%$O=^f> z&-wQIESFXJu%I`X!$u>wIhA}sA}bQ-^YzukVMb9{z#13NLQ z;ya&k|8TSEl)oTl3{MnG{`NJt13sbUhy2xS7u@9^hJr_Zu2bXeOe;HS-g^;{8#S5k zyhiabLFCvPOwC2aSL;lC-Zph2UOiC_w7vvoA>EkuPdoCJ7wSmTZ1seZ%^SO|oQK-< z`I%^QJ`MVXPWnv^NQX4jwP`)P$xqib^Bt2iA)$-dkCeW=BsR!1e(}5t7APA`~Aqs z_zYomkPEU{VOuj|C`QExc>C#kFugzzF3mn7)*fQj5nW#Qmq0D1MfR)M0CjlrNe<&^ujDJ>bROchF$g*|SBpKI zFe^~-zMme6Xm*Nga+KsvO(_cOXNd{~i*Qh;`C>KJhC)X=Rz{hIqj4@lR%#W@Na;{K zL@JpjLb|O6q|(lc<#%WiXsj=nA|x+|rt$09|Ex=i_>9YyY|iQ3P;-Fjsb;=#ERIG4 z`i{v8SZkOmoEcKz-{;rYBbTCWQu;H<-;MfkC%fu0VGt0Sz90_FBu}KgABQgQl(H=U zzQwb%{U=*IBON>A|JdTSBpoo@5W0_5Z&1(ljBc{q+9|}9DMB`*Y;JLe55y#Ege+cf zcr1K8effWFB8vi)CQ;92)K`dwM%9?!c$qQL^-g-H->UC_-KL>j`7mm3Ol@^%d|u*O z3}gOf-n`g+l(H*+xQO}=NbA!4a-m5z($ejsmzc7#zOL!^d9GRA-k$PKr(bPq$T7t> zU5iAiOxv8|7}7wAXleMK?B;&-W7#pZBVK!j3wW=+$Cc%>?Ms_I@rN2}BzwUV*)ei! z?Qth8%KXOR$z(;!Y@RNAPe|3ZY2IZu_2|%ec<)17@@&Pv3U2CY|D;i?{=1v9>D99d zlQ*y3vt8}o=5E-O-cZ5XZa)3yyABKO^(^~R-<7r_rg_vYAJ3%n%xr^0{FfC<)Id5; zO_krChz0q6Fh6F~q=WY`K~h#r;Amr01|t18ptGg5!0Czg$5Sjl`?gld%qJY*vO&Yv zWlNXg{HY$USyXB#!Us7P4^mwqk)mX!rMjSdB{d=?^&jyVm?5sZ6GQfm?7KBbDRJN< zEjmqrXch?9j@!ad=*^4g*@?^+eYi&XU+g_w)>r*4@0UjbgxI5BI~d!Oys%KBmg{Mz z`*#hq(xnx}nhqvnyw(wp9gyJ<`*M>DQ9SmJqI$UuP?0PEohutx(d~2!RUa`S9Zu2a zD5-yY8|N=6i&AHe|B$n+4Vf0UQYu&`;=&;g<)xPV_M&2W_9pspBGA&rO+n&7gITZw zH&&--8^RZ3O=8qsci6;gMs zRUZ#zMtaH8FF&%;N;zx8$Z+5$LM>=JIxtF2g{Ry3C)9p2jm31h*;){bKXdw}RO_<^ zrD&VgadFiFy*T->Vi_Of$>NrWB=l+dd9CXtM~9M}1rdRq$43hVMHkA3$cq@(<>ns{ zQW5~joQ>iu764$2?u7yNAAb1nbjU6w-Gs@z5aluPaV5^mGt|Bv+zZA2ebm4Fs#gc2 z1h6=$Sb&qr)8QF^nJL9p&%;#}oMl5E2LZ{;s0<`7akK<659f)145fv zYA!5z|2(sP)Qm~Da{?vEdxlx=!c}`bM?ydl>I#=iAS$FFD&%C<%l98P;OE=HufXw@ zt{>ecAq2o__!`(8{Cz~zi)g$0mRA9Q69uqQgWF{Oc_P0#_{X*x_rq~vN+Wt1fjb)A z&XSVG!Yl%)EG02X%200}rQDvG2u3PTYZj$_OoGyYbk(S@3?&!sF^Nm)@_-wj@&-Po ziGh8-^&%7LceOXU7kYpHdx~^Zv&MvLd~#W=%AbwV@NtX?5Pf1?b!|XfL@8MGC<3NR zN!ieFMtz7*q%<0BHVomH@I-PQ{@7)+ZSi-@3LRRKibc@JazyC?Xb~#S*?M(WQgFvLx|aBZ7!}DFxeAI;)7C!SNFf^B^@L2kWKP32kCLR-fSF){F&W z@g|h`z3`JU6i5S!7j^2WTycV!0z@QVYGE?p;Ms%#5hUL&j|1K7O*T*@W@Yr^+PxQ# z<**uKVo1zm=&&{#D|$;O6buJuCK$~;Ejf%I8&DgNk{kca1}G_9Lc)jt*ueIEHx&CI5tQU8BetGxHJ5f>Uu&g!lLqPH|P3nrAQ{F%_Gmo14E@x2LJNfX> zZ;T;9>w1HT6>$-DTMLjA_B!GlvH~u)I-r|9GjWt;(1}ym;vwNG z_c#?cK`m-i>@cHxDjL;+`9|JEs67Ezbvxk;q6{jwrnB)lDnHTHgT62nU)*T~RqMh= z6|LaHo2{bKWTleNr&JbT)e6vo-L;u2AX%z(o&M;yqnJT5j0s%+B7#m2M(4=sD z`bhibps>RL(O@B$ys!7*j3JBMcdvc#Ydcz7S)Wz7bxzT!*&IzF*PKU!cw9Nyd#M%O`yB)KnSxKn76Tsv(D4ci{_m|5U+L4mWJ?C!Haf`D0 zes2fr$A}BU;dgF9NdY=(Aca>U-x_>zK7V_D$rF-_qR=d*c#skmU+-nv-1kd}^nA$y z40$2ap9ZE)4<)G^OL&9H+rD4Sc|=^UcsV}mj}RRFKUkvGb!=hcC}8k~Py3{2WQkB5 zKQ_V^z9@{PV$&dgsEkH*R}#bFRws7M3Da+8D#A~vw$eMv;OL0=m*?;%nu-VowUHTL ztBO%@@@|C7pR0Yo<-9Po-+GU{(SK^ie6wQf2Js*OSw%V>4(8qN7M+h(P+(O{21|rfaWA{F11!@iJZ5Zk_>eehojayFgnmyrZImSfK2N z>1|mO7lyOqnaC19SSs9s(L6;qUJy0P$DOK%c*NoaKXZK3Z#s%6)HjS^U}&=AL%t1U znKGgmS0LgT*{a^YQ!{?q@1DLyS*S+|>D^K3@?;vFvN4KA){!{Crav;5>E$O@~*oFt@n2;nmC?jOrHwQV# z>s^^LFvs+%1S8=@i$<8;%iG+K{-HSy9UPD@G`1wigcWG-=i`{52_d;+7exstQ#I+x zMrP@srq}f;kP$JHJcfkqcS%qI=Tf1<7>$s(2M}bDgc~A<@Dq!G+s7yf3`naR{#o_7 zB7q+bTSVYt{yRthU?7&Ej6}0dlLm67Y$rQ^%rKCD;su~1Qo7ff70wk@{z%K8!`(8J zot(@&QZ8I<0G+4zE!=yXp5_hg^?V($wWt~(LH?mJVBG@q(+rPc`_m=vu_^t}P(-cr z2?(wfeT}S<5|y1DA@I5V({~(yST`>41dUq9L)*TrqLrxU4ni6&LZS&iHlXbT?A78fO7{BM_u@`cXD&|oqKGu z^?|TCAZ|hZ+7;8ePH*@^i@RXdV!ln``DIS z{-d~7ZQA!shCQs6nkn*T^#ARCg42L z)))gE{9D!N<3Y=R@-v2B+^2L&N{=d+fO8zCTB+FiDh~3*9@m#>^_K^9U2g4;_CMP{ z1!mZCZWyFHjg@&cD0lF3{ZeySMm^tCz5&H_usZ%dwV-EW{?Bp?*8h=P9R8o&LJS)i zZY#hre$A5oR>jS*ghF{0i_D&CD!m3<;m@^-x2JDkK?VVcZ#b2t-KC1WG;24>tnRa3 zJ3Zs8u>fh*XN(L}!#8WftHoW(bAqZ50@51%Lh9H%98x*BYJ%i*PsK-&cw9%*P| zg{WU_S(PLru_{7#>~5^Dw=1A0z?hsDC*LnW8N%y1$il*OnC071)$^P4iWYT8((>!# zwatg_dj`#yM^8HSXG%t&4~_LF>)z}vU_qk!cM5ZG8@Nixa3`^JK9~L>^HF*u-YbE8 zYtzALkFKmMMwF3n7+-;H5Q^ur#wj2`Qi-2sffI>iIXaW?NS0bIB^#@;A^>zn8;3(& z_6icS9iNsy9h|l&{cVQEH9k6>SAREm2<#t76}CNZa#S0%-;Sr|b=a$7Xr&8!f@$>) z9=jK*=f;xiFC;2x<;~pbug8rDj>keVvl2l>Byd)>v!e6b2>kKQtV0=y&E)382*IGy z+dpSrSZb9gZ$>)VI(0~*Z3hvghn9E5(p9;Ip$Vl(qDvV>FMLISL_1TD!Bl^+ocsA5|M$l&9(!y)xR3i}%xBLI3dQjt_O4HD z=)xJGDVHHIIUi#e^Z5WApv)GaUk>O#$Iw++ho+~uOolp&LS>YOqK9N`-zrWHFvCjf zd@h9)ZR^Hpy>;IzPrjp~1zL5wu1q#JRH0Xq)8{l}Isj%%Hu(t+WG+J_AzwL(&*{I9 ze0T^H(JPfKhQJv|1Qp!`z!Nouf7u^WtI+O&b2#E%EgZgE@u<%O_n2{$ytcs-c zuy2CPBB?7EC`zQRH{Xa*G9MswB~B2u2t3PBPAGbDlz_A-RLjn8-~rG{2#4k|qP?_e zY~pMf_76tBoCKmUMH>Q8Q6V1Mo2eejNO2%`T0Gc@2H>Z&C74zf+6W75+5S3F^7^adn7ZFyjmzn4zMQfS#On&H7M3o$IM96f~2u8;#jhbl39Ct?Szh zrVm<==JHUeomd5SPwwpdiu8u7-|HkZk{hA*701D;^$Cl7wXFvPM1i06(^P2L%KATM zZaOS3*GPL*8@D#W!<`rSXqq1F*b)&JA8V^7bcUSPGAhqnLNIcGWo zG*+cnt`e~JRusNUZpAxLp(`*2*qtCGtk6)uy4__(1K5Q|9r?oZf|vJ^DIS(Cst24*rgdEuo11 z-HL#9ScZq@3T#r(6}}Qjpl(@+T-(4Uu@Z;xW?M)+Rj@=iG|~Q)x2kGOu~@>U8aTXh zfYB3QcMA7;Yz^2_^JLQ45#3UxMa%O`g_J<_>kmK zr4$q27Tlu^zF*H|c@wE0R6k~}Oyb8e4+ByqB5|gRQD);*_`X+a&_bFTXpp77)2Fd% zZA{M3uSz1+*!*0d2%`{b!{zDj8GjeGQr44-Bw-d<3k9&E>Cn(YP9C(wLvTK!-R-DF zgeho3^$Jdu1N?Z|3qszVDo70tvCr!mgGE98C`a63+4LuUcs?aR4 z1dtym@v3a!s+P%avu1AY)y(O;L;aaG`0y`~@S$yeWiQ+cOxT<~w)PWuh4zM+_B*Lz zMO(-tFVK?6Lj(!c!{Rbbe!KP`NJTx8iL%hFmH2-kyGF~5@au_xf({6j>ep_kRF|!h zWV9@*0n5ix$gd<|FP>9~;)-%v`_SMHZK?ctDuuBqIWle#c3EO0lE7z^jv1#1Z&&Tr z`3?+|^EOOZ2X;+bn&Xxd4!5dZ-7{p=^i}i<8D<15740O|tmqK{y`?TKH7B}+%WdMD zm5hl3!z%FWl(*a{(krWd?UI$XtM{bOV|;5&Se#<6i#3Si9Hz|Ki^Ov0%1xRyRIG}L z=q5rYj$-r!f5X1X^6l)K3K;RI+OjTr=6c|t@Ws)1t8mu2KFoOwtOTj^u$YiH9 z;t`w^gog-XtNGM`-N$~{kOJim%BapOdU4Q4#r7BSOQEa59Kxa~AZd zDa24Mj`EXeEPjoZ)}(#g)tzj5<3AzfQqi2SK5XTW+(A**m0#^cEg)w3=cphrZ-R#z zZchZQfH69_(6^orXSBwUjwdg2D}$<(dicOoruAv`O^?KcxMX&}Y(^dNzMXu|PC0)n z_cT6BJdJ!jS#Wvz~)*#%| z?fqz8`^9!u7&hWF*Y6N%-)PYORtH6n>7qqU||oP&q9wF7LD*&w5}m*j(~ z2<$RrkJcBb0HAB-;xazeFcik>D10{P;{IO>e44#$It$f^2J5_@^X_JC7e+A{^U=bCv}ml zvrKT<+1W8e;on=bQV08~iIod*Pk**i5Ym7&Pdd??-zDm{g~+`r>mfsTIosW@S2-aw z0Yb9p$-Ga+uYlb_n|NrRP$rOoSaXVICcAYiy*>L|Z!gkc zD576grPn^R@j+R66maP7H=`yiU*BieWS97Iz@Nw>U#K?U)x4Ee- zdwlMnY(ln-blZEMeV1?gq$sr}`zaZeeiQ76;(p)g{xT9G{{P7%*ctwlJc5Cpp6&nh zjUr*41+n|OM(a*2CekSAEygIm+()=s&6KxuviqHMMl5bwIIF93hHb2E)cOI; z_{skDJ@Sx<_Lw!$md8Ww^61;`wdMkswt=@kb4mG$rb3)%ye@#M!Aa%5bFaE>+Y5v2ub3hFf=B*`i*u^SH?Eou!&C^+P;-%#dovCa(kcYgo)YY z$mVe8*UQ3X&(!u+%V#_K;=9K5-D?zCxa_Bas15krqv(6FPin5%s8*MtU?Q{QGB+tl z9D}I^4fza6U8lm31^?;A@}>R>%jH(2dekDc`qb1%uu6k)$F@rb*!^-&#_pq4Pg7M> zomw;HQXAFz3=^{~*9@JhGD4OqCU5096dErRDT}v`H0L(^m^J{Sp zLxylt#**P&w&}}GlfQne!(DG(xR7buAJo&UC(Hydvv|RJHLTX8_Z31XsW)}Dbora1 zju$2#oIU~xR;ZQhNW>w9>Yy%5jyX|0xzkV8>hy|=(Za5XbI*| zJOU%?P!m+6F6F`JqAoyJfOrNT?D=LP`j3u|3h*{&G`D!lKezVcGPo-2q^1;lKUKh| z28EX(%0kAeX1^42CymBDDYc`oE3)I_?_t;OGlfP*K|gHfX-XSGGE2Rrb10TdNf_>o zmU66By9uM)l&mv%iLb*=ndmPQJ%2i5&tj>P=sMdR4LkVpEPAK#o5Vr@$#a8Cz%*mW zfww|f4C;G)1?;Sh=U)#$_Br!jv{bY>JU+20UWhp3e7nW>oVl~4;NpR%CO|FrF3xX6 zoZ-cx4x0!;Zi&i4pspxl2@H#XzIEG>T5w8Hvmi8T7{^k8Mn#?#OocBmo}9Bm zVO`6&ZWV|%iXsSTRakt`QO0R(;dd_X(U-``}>guPiL^r_}o!eG8;PJP{O=mUtF> z)pujK+(@|LpK%(M47nRe1Xi7cA#ZDB)F(UU#7PaiQIBN3xh8(uxAq+HdZEnUN|K5U z(sQR4T&K(DPVBJ9E?asNE5W@Ce`v_q-};QezFj-}bwUsbBLe#&nD4f-raHm;>^b4j z6$5=Wk|V=G9o`uzCQG(>f`cX8ZWZDtYP}b>;bAMzaRH>Mj=O2iHqs-#WVLPej@g0L zk|TZSw~wVO5M5&XH8h6C;phjb!jPud?{M}iO;%M38>+PwN_T!6K)#W?wur?C0u|vd zL40rpp77uwIbGK2&&bSsR4!qXGOi`?LV_&k2ym#r z;&oo*F=0M{h9@MX+f6%V^t2xF%;v1t5r+GuiM%)+b5a9tR>t>qapsN}m`Y|0H=}}e z(Z*V$DdLxDR@x{fr=*=;Ogb>zof_;%{HD%kyjpmvh3WCTwSDQKdyW1QvA7uLd{U=f7VZZYpcWb{(rOg3ryE55Y&W_q$=k z8Xkyq6+E4t8f*G1re-Ons&SiiNyioqM+*3=iuCW^ug*GW@S2TpyGnDb&n>hMn4m5I z1G-W;UiA9a?S45L#U{Yaw{4%+1;3pHUh>qrk?a@Sh+Jo-qw{VDh(*X6i!P^t@;!{4%>c!(ca{`lubvS|*7&@+e$8n0$r_Xox zufFVfXcOgOS_?}bP|E4(SQthx->rGENbl)!JFU^)*zbm~!mebepJTzVGlps}JHAW5dZm)$ z)_65gU%Q{A%6^zT10n>d9gOFx?h-s_hvau2?D~ifJeH>VL&x%$$-^qVSEjwPxANxN z7B*_yU2U6^uI|hNN>l>!Sc$uqE>)1PG#mIVw}eth?Irlo4vARZz|#RpUtN;$bxZn$ z3zEy85=X+yul=@AZ!b$@?hU7m)ZmSj-wCY@Hrww3!woS`CG_&4CCCVoibZoq2&Wbx z2VsHtpql}ET>5JW2!0v4p;*l+qW^lJA?Lk*k|g$loyyUmNPj{~sO((a!|&RsVUMWvyhn*b0{=Plk_J0nuRvrXH42! zmQO@&8{yMz$R}t@Tr*U$IM4h+%5ugWS})}L3R*tlisMT%SRyvB9pR9EO?4Z296WJ%Fc*^ zTZQ)}O3bi7EeW3;ZVnnaNgtFIiuvr~bAi;v5&3_+qDVG2AGX^ctq*Z<_CJG=JpKOg6;8Le)>q9T|#{p(o$(|eLUY&h_bjrF(pBDsy z2=)l6S?m?U-4}kZ`k&#?3a&O2_5-on>9d3BFz~~zjJJbBP84vC1tzPc8li*<=z`c%NRXAC7GujJwBABBj^Q>(GuY!i#Hf^o zw)Lt!Xo2!W2?|=hd$*jSZq~jnY+*D&O$wLTK(^I)f+@hsJA+^iz$;G@J7_VuL`0To zk1TUbWRgp9_S3hD@2t4pT!3inRaj7@%Dxzre%vvBwCAENDXM79mLfBbHA!)>#bl?qq*LI=gKT8RWNGLwM?&x}$qNp>^=D9m&y~_|4W_e?oo`v)yZ{ zf%Q14KnwZ$!TOsH(?UbB#lyJIK}Q|mv*Z5N4mo#B$&Fe9u!$6+=yG5D{m|z7*Vo+} z-@hN$+5gW`UCGVXm{!)nLebHRRtArOj_#*c!rs9VkDiT=<^NGO!AQ@>{NK;To`H%-wo zD=Zv5dzxdva{8EzPe{Bd89b3Di`Z>Y*pi(p`0h4ZDEO%Ammo*?G?n#$N({at$0)ir zZg#`VK)_I(m51p4mRP6w{?_S>ZJZSYnVo0!=fh5*kU)>r0k-e{R!j`u2Q^ErqRVr} z8j#0!Vibt!)-OL(gAFLFdJiTp!}dn+=G}>5<}<GN2 zav1McAVlw0!1$UMi{M)|ZAv=W;`Cl{TslBK>H%P>U}M&Skc?hntX`BqFe8vidZg1} zlf(4IJ8vzZNVQ+KOCVo6LTyLwkI-h7oZWjmwv!HF2~kBi(Tr;-vux&@08t73T1FMk-pmFCp1ixY$T15Jfqea zS@7+DPeBlYhj$lIj=;Yn_qin@r^QzhiX1Fw`6~bDS0fLN(*x?MAEnOLPu6YL_tO^{ z2N`~N7h8c-tBFV%!BXv4I<-VP;Ctwy^A-%U0PD?dG90GPGVK56?p^KW+`LaUl$pph z%u2QcJ-qP860}}m_?o#^B~HSV(o1uwoM$*rov%;EHB#hM4PbM!WscQOO{wTxTI^rK z!z{C9W=r_{iG4|54Rr^dY^U9Nw$@4mF1Rx4gr5&v4RzT(>12nv**(m~NutFGOl4Up z+F>ja<2nq#`vPqb$1+a~TEM&(F&iA!X!xvW>wSP{dGH(?R2w%EsgaVU3uYyxb9uap zlBUQOeX;wm0ZL4qAk2d#)BCp(yb!jp#_)Ma}UZ4tLQeQ#HOz!h80hu z+wJ-4^j(*S=lkXE^tj}@=k@8dB*n+m{q3rzg}2M|)AjZ2_HGk*yX$?*6p29<7l~f= zJ0;Eg?RZ-!yZhs2cfX_r_uKn>uz>gDbwD?}`|V}oJw?}hI+gMJ_VhewVt*>-Wjsc< z=lf-0q{PNM!w0MpS0|hI({diM0SPe6-Z)RN$UMG21t9YdeOio4%!HUc-(#dMyHX4w zdXlZF$ZvGpPHEu=!&lK1YfkCiPjOds4gf35PC`bk6->swtOI0cC9t4?_-_t2=|Bsj z-#(*EOWEuSMCIpJ9A@6hJ2ZzLIz)Hm6LG z4T8CQhQ5UCSEvPwBtGdePk~Xaj8AMdDw_&Hr(3q|8QIubfMacg*bzeEz4x#=URJ<{ zMTiZtzoU)`)^Z_O+Y;#fE%>}!mK}8A0&bxqOm|SM<`^UVO8TQK7?9>NyfdZ4YZ=hm zDco8a%2rb7D2>Bs+0GyK7nm#)L>mM?2f%)7E_N0lPPt$gV*j0SEx%b3(kED8L^>Ad zq8~8?BJS8*z+Pcr2O@uwaW%g|_8npS(4TR9)6ywA3UN3Wc8kwWF;9$1HfL}lFj+?;ixJN8 z&D47>@Vz#)wz1S1U}0?wPr-Kq(#|soCC}J=F*>3CH}lp97|nEvkA>&p)STyHm%nL2IdMn&=fiq{UdW9IR7;Y z+L`cQoQAZsrC?>it_Jw5)?Vq&6&~!2fW1?-b#e67ms~|9$t6D1vpqhcIL2#i#jJG< zhJZs2+S|0)5-gsbg#?28lGY|Px64e3UQl+&GJLLm9+5cWg5WN?xI1vp-!^3P^RN^F zXFSKvDv?>OEXlZbVx6oNzx2X+LbK}WBJjK{E?hnlViNzOv!FFqkMXA+MGCdH5CH8_ zulz8yZJc_PrBra9s!M^^ar2eD7?g2(1SZw@pyI{(y1DsEaY26%8lfFO$1@bO_V-Y{ zcK43hYWuyQ^N_+tg(djhAH{>R*SxsAb8A9>`SYNY66RZqIl<0xai+i%8YSM&c3cYe z#{)tlR2m~*%M-UMcd+>M@L>4OpsNv>E?j#o4oFM{zI0k9;!advCgO5>gvfFSdPM7! zPkzVwvJoNptnnb%Am<`1iZsR8Fg%W~+0WLz=U<~_qdy{@6YrJTXZtf%GgSeDU4f^4 z?=Ln%plt#<8YW)LqYNwp^!6|l1g;VXe2R_97D1v3TWZmp%qOTz$g1#BeDXZyy4WI2 zw0K08hfDs_#X1Stwng^ke1Gh&G5mOT4HPKA_SnzX0-F%A;v1Tf!Ka{$5bUmT{CMRD zO4NP_w0c~Zhf4qfN%}8pi|@DLfFyyWZYsp`2d6kWW49kN{-JuY()xC>QU+}zr8H{9 z@<}uZ<-e#u^mAp|(kZQ9C&(MWiU_3e&>>PiR*r_(3@QK{)(DIQ&7l`$4e( zL1?2!DBoBHSKj(T*!n@>`MG*)5-GiU{pij7p!oFsD5w0O^w1!dYy3bq)r*u`)C-ha zIJMig;f=eqKN8wjh|J0^Kz)KgINWFfI!u7yj?z37#A*D9j=kg%_`LIQ{k%UGWB7RS zxt3{|c#;kdf0*k3V!GeTexxF!n|Ej!x^+f}tz!~=)oWk-aH`W8IVu$5m(6107SF;G z3LZLzL`}~TiG@$~KP@#sH`!?9;$2h<@$En4u3bpv^bdJ>5SP6Z5SO+5bh-Xf;z1=B z|NOx?`v=442jlS{jISSzvwtw?za3TiH%zH~TLis#*l4^tmbkIAo&ak8g1@2Xq~wJs zTxkj?!f-xj^=&T*11#wRGV^Q`n)5tj$NmAIfywfNH{O)-0((H}cNj3iqjQ-m>HcM3 zh48@W2}+TR%lU{sD=SvPy#@_@luX!6nW||4{29puI0o>!Qg-d@E#PV$i4HzFHIl^j z@Groqb?AeiZbm7fZ>RX3wmE*i8|*o6u%k`EA9t^ApydZ0irexJ1_*4|rdXZP_oj~Q zL7`y##snPX?8>~?LKbF&0>2-f?vAYz3pKO-wuHpnlh9A36ALpY`E2ruHjfM*SS04H zXhduZ{>6M(|6J;y{?+#9pEe%aKg3BRj9tAWAy@w634%DtwwOq1ZGIW=OmMWy@^* zl|#fMs>b}Maj+W__32l;n56r3L}TIc-L{4JHxRCYaO}UQGz^UYEvfmxmwPkPG5n7@ z=F6Y|m=2o%sganBbNHR^3Xd0~uDZ8IRIR}|PCo6Io<~HoXe(vksPl8o0oYqwlmjST z3sLGYR*j-te@W-_F=N8u-uP(e&ye~EVZn;{ZkYP=zCW_K-~1_mG&WC5%BaYI5hkBv z<$MKM*TVkFnoTS=>ktf`KWOH*`gVA1nbNIh>9JN&K+Sm0KrCX<;IM6O+fHPnE;Vn? z@Uix8U)(inj6PFq!u779twlf}X!|7^So|Ao)-N`=XX}biw*CILb`wD$p7#K(Nu%Vt z{BwoNGAPx0=6$xXLw*~#WB;lhBfZOl$I=0Ck#)(5lEXec!Lehaf$B;yMiu?=82179 z^U`14KCyl^6Ms%NhiQ@=Bl_`AxKWvKj5++vSW=w-$m*|+)P(Q=M#dNPXET2%632}2d;o?`J~u4?n@ z90B#~BL4Q3L?)@t+ga;2V&cYS`M&=1r#ftT?^w=uSCUWc!SNLr%ZNKT7xto{d0IXY zgm&Wse6)W9 zli{$=-}CQ3X3;GcX;CijVV4!nUDZ$XiQkIb58;{yVX+?-Sx&5elqOwdioq9^n9r4{ zj3z%nE0qjUWvVT0IeRf~ZA#*b=3wzR7PuENUXsAOimU#~v^VOH(+XtzA}+-r2m{Hd<{^)zrZdo9`xr zEHuBiRR>?Ok-cv?cCAM|!b(rVO4B-QB5# zRqx(GG?Ewyftlbl?+8l!B-CM+*q(T{6|rHXqz06#>`2eT94#y_GS2VGT!b@^X+yZI zJ;6tg1?Gex1aUCppi#KNZ$#U%#X>lkdG6FK1)+G^66a5zr_AXWBqTy*#KzU&vBiF# z{)}mVs=I?1f+Q8YqUs3ZFYb1?qP=2I=FRd!WN+>A4MYUMCVK&wzijHb*W#^s(=ShZ zi%w65m1J@qTT7!KNw#2z#`;4?e{a>%n<1(lIJj0*Is9U9dv8LNhxLe4dqvlI2} z3|$5xr^sse`%X_g;Qz(gI|hpqEZu_Jwr$(CZQHi3vu)e9ZQHi(eYQR4y@-i<-^`te z`=kFyMSfo9iEIu9o6bC7aApTsiKv?MpATS$?J`kq0B=moO)&e_I z3a5!&B2o}4gd=l7AM)Y@Tz+!=V#wl@%09tL3#csaqpsx{VPd|>V;z2|N`u=t<(~|S zBe2#`rVfZ=T4N6oW05eJPMj4uhEb~rq)`EFDvySOWT3vPxo;rtaNG(Za-!i;K^KCO z`LNm?&&(tkTaCZ-I8UjhAhRD}R$Lw%(0kSsA@EWXe8$YtOw#>~ew=V)aLU1v3&(~X zJk=O4D2UgHyumX#-YVSvcx9u~_%FQjV^*oy@MRv*m6I$ypK=CC6n~=*F%Z{&k7-EnSZDC?9Lcw!)f2cp7B` z3KcO0375bxGb=DiBUks=LVqd-p9zHsUe>D+a0wL_8y1E7L7X};f)ds&mp9+scXkO>km#*=s@Zhn&T z(Mi%ktIk7^Fl9_F-0F(P91PzlTJhi0t+@*IHX16d(uR)iIeQCs9mmyZ+1{k+5*6&s z^X<=-qWh?sI=z#=<-VNF+BQvvv_g8u-;dj*ZIZ|xDz_L!mB~eF-e<-QmyJJvSWCBl zSizRxR?|n=s>a~qN?1NbVoR#QM-cQ*nI{Q&;ur6QAH8p+(>nawRRfFqg7S~)ZozrD;zv@0-)j=s*m*(soYGg(}{=*rWHwvB;_fRvLcTnt-!|*mpwL&>S>X? z_vI!F@vrtqM~tZk5%h2bOix(>>`QQXWUSY>@-WTAy}&eTrezLM6G2V!f4zP&iye)% zhp9VoyfEglKZ9{{m*- z@&vytA-sq}7>)graOuD}P?^mqln`mnaUgo-979-vQy8vza2hty{`4NmNfza&*V!HS z@&FoOl-ESqg3vra5xFoUme}&x#Uc{K1%R^VC<5QWvqB_Mja*npb+ARs zOO}F$TtA+}z`{EHkHw_)RCf4u*EJyBhYE8)cG>V0c8m?=!JkkeEN#tZywMS1706uN z1fG$CurML5A*Wz;K*S>(SQ&XK+2l&;)Q$U&w(No$cK}i+^+_p-*D9RIfG>E z8!WMtAPKjLvEmIAc$nFNPF#azB2C<^-740;|Q(4~g3eHsa=v&N#wrzY@lys1{;Zzszh@22&%&fWiO zb@-QV4P@9S2)YPzr;0%50#Zf#f1^lzeffR4e_h{6SL{A+`BH6A`m#5*7<>>jMIS5s zEpNZnL_XwR2R&=}rtA}*x+27VKeI-(!3!3$Eg z?K)l#eO594VqThv(HsV3yki?@c4aWXoB`u!8|t;&y40vjHWTEVl!lE)Gt63d;2Fy( zo_Ml($pPd4I@;NLHhor1NqgRT=*@+K9ovYzJ03bx$B7D4_PyEwEM*x**xWca!Xz>d zOE2d}F92R2R9U*S%#J->r@?UznWAtCi&n@bLJDvb0@HptHcT~5`pB$o0jx8`kW~@+ z3O8&&uDkC(DK&`Mp-cni9KA;zXt)*>{E=+~E_Jt3L2Jgx+Jk?SSY%uCUGZmV(OI;= z;=?(s`>}yJHI8Y(_{Z9V>9!v*rv{q@F(o!2jq-2OKnkjlerBos%IJ1@Z-?qLJ1sT(kG!MhzEHFF(u9Y*Yf%yV_^&J_n47cI7tkD?44T>iox~F{^y_HKuy7 z>-_1(8r$rizv9WAjgt?ql#=f~A`qwFrm;J>zE%ofZ*O*sXy;GiWooyrbnB;+n;8;k zgBdsu!5)qA4KdVUOUcC^648;K#Dl@faoMuR$QP5l2pT$G;@+g;7_{*E&BVu*vV5CO zzlTT0m})$|gPSp!%raL4bt{YRj;u$8K}&GxU?ww)9bO%@V0>=yK9~3Z;79EnKKu_k z0SC+fQ|S2r&k2|q82_g}|v22;i8y|2~Mw_vfs`<1#w){h1L*2AiC2Q6T&@&rA4ROc=I>q%}sp2EdQ$;MagZS zhv6;9MFqQR-;hV@k#@01xFeFROQ1`_9NHx^q0idYjl(Y>y%^@q?NFd+LQHMJ*Z{Kh zA`q;tZ#7qE0;eHfSY(HdSuK@9{q*yV*=cK>i<(13l6C)7kl_Xolc}NbXNyqjAD&q2 z@e1y_BAPXauuA8Z*A))Tnx-;TZ>l^Lm(P{JciRHxi}%&}A+vLqdy|>@e>0u8#vPF4 zjIC*RHp`-mO=EA?LaD~o0go|;)%#8ng zb+=$OA1uu`LG-+2SXlqoKwF25OEfL-==ffp zp_eLZ<*@P;1rb34-Y z*!rtTk_!udD#9_H4Bgn+T859=AcXOs z16N8qku`A`N*WMumkpG|6kke-_SHes_S3DUTlUB@Q};sY3>h{*TZ^;o)kc~I2A@oa zG6YCW3psech}HOb20|6KT(hXdKER@D;t-o-mES@%QSm{ibRm;ZcVF=^BsIsvtc(hT z)n&vMxT7*|%7&Ds-d;m$T0y9tN`r#pp=`fu8+BZY&Y+o9oa|mJ5GGTw606uQ_@fuF zQi3Sa-=L#8$aWm2m0aga`Lb+TaYZwDb<_!lhN=M}Mek_0v?Q zX3(j^*`V6dBIuqXwnf3KH+IyW7gZG;(D7AC$E=SuiKUZ4n{Sfx8%3QP!IO=T-5X*= zT+vOBqlf3KVc;UCUAqk*N39bs2$>>U2U@OqA3sU6ST{?~Nt({DSSZdUZS`_Z)OC=T zB8+pT5`OWR9)H~;p{8m?L9tCTaM6Flanjza`*x?{lxWOH_(PEB@nb`0pb>PyB;xf zCNZsH!9oZ@n_7Ji@aXS8O7R zdG*(~+}ib4DD1;SrS<|rxUB53!7A@cOF*RCMWF4>1Qi^u^>i2mFV9*|#hGiV8Q4cQ{u1H2x{d|cw)(l5YW8cpjhlk>^_~X2fI2OLW689+L+*IWuxOCv*V9Z^-Di|YeE2Ekkxr)xgVn*aI(`R{{osS_Gf8B$J zPtqDOQ_)tjk7}j6A?hTPaYbCN?|{|oxq&|_I{7^i8{utO^a=)trF1CZ0J4Rwm=)9a zQJlE9btsArZ;N(fg(XaOE17V+B>bhZ8com!|EBPs0s8l4Q!dny8+*HL_9JaFtOAv1 zVB0Q;ISUQ5?}z9mm8y!Ixu}^a501W`Y8T1{Cz8Xj;NyE_*?WVej1EZ&z4$mbj^of#ijW&ckf4N8Vd2Icml*b z4%f z_yXSl5Gio}S0aeatp7tS@+L)B{tp96=-oGJj}85~*Cud?G(VYQnA{j$^n($84xu30 z23pKNZI2KE7C)J!ooN9lsR?M_yQL-JTnGe1dIGIY?f3~|PASPV6=Vb+Bt%K`mzFj^ z2nnv9BHdF z-xwmv%yZ~QaX@1Jk{{M4wvP+ocm`YFwDA@3QC5477xB3I&onKw`)nKiOAy{;cHWQJ z_<}?7Gy2w7UW&6{B-D)q7M8ZJ-`~_3IR{qR;I#gc)c2grEkST=*10h^oK=JV2wkA- z^=~lyU0~Q^tPgKa=UOHLNU*AjXH**=jt=PzsiUqPn>l zc#9j?b_!&gP8W8cSDa&ROp>F{8#m2B!EPmzHfK7$&JPcyZ`ApMApR`jm|x-pUdTS~ zh(3?Nuo@!ChXW(1F7(JgkaTqZ@OgX1ZMJIksX7($bU*EHkYZHI;}-uY_6`lWm&R%dfIyQ?w%LH60D~w7Dy3A-Jy!w zDVr;UP7~PBdRG3K)h#zGDYoTRwV(jo>0KmFH>3QFBcs*9W7k6 zF=SJEaFY?uMjWP|IB1rhJ0)uwzS2|DKJ$jE`emj+gk8-yp~PQWvGe|_E7)5m$0PE# zWB)L>Pqqi=sP9``HGA|d&=W?O(wMy#xFe&n;FB=tW+x>lCGpKSR+Wc4YI0XFHh;ZIqTzurZEE9w;toI$15UK(a2n_ECY z{ouXquokCMcBG*jEKA_`wICO-h;=~^~uIr@#l6|bHZZx}Io`#K5!wNeZdfhNjeAnJGmpzZD zN7J!H-;+Z%xHh?@MUXi1m>rJD9qs!Ilme(8E~y%Nt0W{_H|NLb}JfpPT=x#pPwZ(^0!x`_VX4f>3l*I{TnUfi2xsupgc*Qn z4k&g#$14rVSUT44VTR6{WrEROi(_Am+LbU;HjR&*F+syrVs7ZoC6Gt%?UNmyqb~MN z$&3RM8hHF0?z5yue+X$}r-#xt{Yn+o`=qP>zk!6@o6OSDgW)A07T5hWnaLu zcYAEZKWGzF@8{9t1k}_33MP!x8o=iamANvG_^MH7d1bfb=Bkx#*K2}Z(%W+mq8`x7 zZLi}}5nk?*9efk&S3PLeC7Rkd^e1XM7gNWzgcEq174yR&c+OHxTS~{E!h?`E&PXU z3PDJC+LJNUl>^w>hz{Q2eQ43K<@JeWI8OOXS$xE2TE)^Oa>GZMSOGcq{LfbK_SnH~ z)Ete9T)b#Jt;~7x;X@xHoVl<`b@;=DcXF9gEPI~m>v)j@?sXjo+(S;9OvCQZ#)o|4 z?L5qpKkhvztSBT0Zw7#Lc!s6x;?SicUN6}j@8&bd$Y|M+hF-b$fS0!~t72i?1DwrZ zyR)UkJBkL01oQQ8E!O?!ML<$>Ycr)2v#W0kEGfQ&Ti_cdXVF=sr`6+^CUMPoSaDVg zB9DISYw;4ACd&Y8+GV;&Z-TX~N(Y3hy5=#eT} zLeFffLXPgq_Kroh&`S z-z3&VeC(vwL~PH5zkYKbPK&Is<8##Fru{et-*iuW>|$DZ6b%#b^*k~<5>RLetd%&4 zC$e0I{d|nVKOQp7}Bk#QtWnfSRW6 zYSj3H_po6_Z~ z73ejJ;odqL5&AR)dX>ztW*XZWdMm4@v%z`2YpdyIt69?ys-M|Q-x8E-I--{1nlo@L zU;IShl)#&m5Z=PfDzz`*za$5d*$+0>%YAj_3g3eIwSicVJPQkJwh0Kj5N>NJB`g9y_eh8GErz2DLGn-S*BARo z2ej$avuvw&lez7!D+gebHwOkHbOykl>hKTSL>k{ATnfk?r2$5y0MdINsVbo(1h{LXb>C*e&?DyPIYIDC{b~eon;!Eh%C;;` z@BaGpFkT6Vp61JhTb4O=mNP}|aqF(?jM18kiZekDs;{t2IiC>QvxDm5wwY(Din~eW z8hk=vZP4i!7CBNcSth0sKs{4~;}uh1saAB?F+8yAK$iQqT@@0CZ9B7jN&Mr4x(#ct zF-Q8!I#@9dq9J74@m;5-G`YzvU>>{WjPDb@5~&4w!fSURO;YOI{Qgm;t--T1wDpxu zU}}xLx~#GxgOCv=kEl;?E?s@~IInHab)%Ondo}6=O7Ltg+H@0mEB+>yNb!Q|i_uxk+_%&HxT^dvfdQQb!E*emD zBiN!dLX`@CHv(Uyt60sdrAA!7MtJh-PIDlUBFDEK%Unum<(dD*a#fUU^YN5Fpo+E zgs2=KM8M|`l~LbMEF{ISPZ1N9XmKAbV0x`@GzZ5+Y4ip~F@w+8PIZ^+A%IX4I0cPK z1Pytg`+ulWmWGY{5m2(Tav%<~;>;+(#x1X!AxKnj5Xkkz6zP$~evnV$!XWKgWgy7w z)qni{I^cCxMHxYx1>J{?qpN!ckkYQgx3K?2$?R zz3xw7H~paNPCGUb-T4D#kUon)(U+KEMOVedGM=4s^K>{`DJ!A3F`k2fgWDanRi_d}rhqDxac1g1B@!>2s_}U#JXZfU&I#Txt z+6AmnW>@1e#aC~L(P{7DjxZOZ5*R9CM^tY4w<+- zqT#^c&aVt5H|O3EYVT}8#|U+_zh6TC95?o(4AeB zK7b@*+ul0{C+KLC{8pLCfYO{D0tn*1NO&t;flbQRE&|F|G#JG)N~BvFh|J@`Ye^Vg zb)l=K)~0KFW!bbAVXxsK_TFaFLJ!9BWww8uSqsI2uxjGh;6)$$semm+ht2&3;9lj;&Y zrzVf4@#zmA{`g<~Bd_oLtLKhdc&#<@hJQMBoK`Zz{=fb2!LjOl^A7{=haR@L{BDq{ zRD-(dV54|tjikQ6L%-G>Wt;!u5@-DHQg?RN|DiQCgJEgE#rE{+7ZUHAuqlNqsVE)? zsJno=qeY<0n=haX(pWP*X)>{}P`u;!wR==#vQdCsG!;ZBHhlE3;{#p;9i_?l#Yla4 z|5)=r`Qd5A`$Jlven;wOBr8Xo;9+Rc(T<>%G(!IAl(CX=1T}EeOyPjAu8%``(>%MR znZVjkVvxF!UoF)(J-f*Edw4%Sn?0AL9|-m+E`p%|*?#i3AG)~EY2^=~vmO$m!nvaf z$c7+9Dd91M{IO^OtALCz9qYUX(J0S^pbf}_?6!nS&`Tay?UOGuJI%d-HMZN^ZxpVf z897%tZtFeAS=c0i9~ zlYQgdRBW$?7ydL!dO>@nT#~S2_EC(O`wwT^EfhPtV+=hIIm zB4`9mvRwrbNuS0B6OaJSjA7E_%?#$P#dc1(lsiRLL^r9N_f^-{KANc_p*(wRaw)jD z`1WUHQEF7ZQtJNNpL*j#&>tJm_G0QVyqHw;-g91ZHD){*ImG^)?;+3!cOn{5>w##q z2US2zA;1S>n7dgV^E`=o5Z4%pL}gh{;A(Bdy(~n+rAlL11akTeA2ecYh}D+@Qwt~a z&7IO_Alaoahy;!ab4>7ZwX;no)(;4gO)=1)f=eK5TV)7XU+Jflw6Bn~Aw-eptaWJ(4AfxUHl_g*HmMN?~uI9zJgd1L`Znv=c^*b@DyNGtdRJPircrbG7G!a^=U9Z^S>{Xb(_gJa<6}kWdkPdgt(H?~39Lo>Op&%Rf15u?ZI-asEjkCfziJ!nTR0ziz{XluT@%VG0T8-= zT((lBZ_Es>#1s`$Ex>0)QQEm447GBLsLALm8w&1?0`X;Cn4|0KTmAD9ji)Czc{bk< zIc_-6-mgIZpa72_0GP-y3=9#c%0IyG2e86dzfQ5@>6|V3IdIg=9?X;F0QzpMHydS_ zfcVu^s(YN$_GM{7G_dRhZ;&wOMj(uQtl9A64AMrJlSUg@ou87ksbA^C=vrI!34M(T zgtE^m2x_ef)qVgmW!xzM+$~0Z!}C3iCuH=>&tDkwXn1hp$`na+?|r)TM!Z?fj8X@W}P&R%?Q}r7SiuFZ6W`v3EiX)JLhb$_5I9 z^_{r!J^?diT~u*qRvyihR|w$s;CLr0j{9ulSeAh=j}DF86%^3kStEU7Qn%5;Chb8l zLHvrhJB*Bkxts=8LLr<#_8A1K&u=TN0n^(BAgU)Kj_#!%1HYfBFJr`kKWYMyCNg)# z3qEREoW?JHd$_1QL%bnRe021DL71Qtf1fb=t`YR?rE?q=yZ8@+hoL7?M2)lvWf6#e zvKm?xaUA^P;D@M z$%JW68z%1T)=#yV+m|8s=hRVK9p7R-c{IGYrL^^OqvUgcrJ_LW@)!N5y3*pns9iFT zXZE~vbr#wsV-oof8T%?ofK>mp)#{;e304^}1<7`$3Vd3GU)4y=PnS?e7w3;Y5*r0J zRt&qoDIH&c8}&0l)cp<93W|$v{l=waU-6vjE}doZKL%gA3NnaKIb=62_(ml*;l8ky z`%u94p9j3BZ}?w;>ouII|8zh8S6Ylr3~c{HL#0I1`d^ZZ_TAez2%(??#}oaAvQdby zWzf`b`mBvfs;JM@GqcVO(=a8uk-8U{ypkjOo6*=x3*X3-}Qc`!jT14x5pb4bm%L>k&8ZLj8XNa z0AdvG-OG`H&TKRcq&$(9Ihk{B6Ih|wp5CHDSD*Zny2vTL0wjI$i>Z=GSHBEx-lSBY zrgUomVDI(}e-!PJoimZ;09M8$%OKU)MqH=YDQf?4YLoKq^G*d80TMq>Q#=8KNsu5K zKb|H~2uQ*OZOJ4IF5!Ym@=6&%v1*JOQo$nj>t~Hv0Jn7y97a_4|<7WLu z$VD;}dEPk}NsT0O1S|7J=UgZ$Jcp_5{V?=h0c7lL@2MHx{W#q%85ss2;>f@(OL9c` zHZoRV_$SLk^lsz8G~e(b^eqkleQBdEEgqJk+d$t5BvZE+!bpmQh-POUd0SDjeK9b> zr~Q=Xjy@oP$ZT>IL@N62rvh51*OaoGPUUMefYCEI-Qd1%0Y=^mg&5;xK+d_^5-`Bzy{ z?e$-TvAYpBOYo%KzF`DDxyoDBNd5Tzlk`mkH)bc>c)X;wI1IUFhNUi)Cm=NzL3FFs z%FYvoJ*!N@WX}f1rsLzd66Fi?DN*Po2JcO4PX2bL#k^lUR`m| z)DC3^+?6oJ8bZPuM>I=^orIXoXb%&EIpiYNK@p^^P2K*8mHAOYT}4EuT?*kX9#Xcc zyCH%iSpq#;OGi!JZRaL>gt9tYC?t+O1t{oyJt_Roc{jOf3klUPMu3w^A_fTMhqSA$~GQ5+U0nneHN{1A~mK zRB4*#WY=cx3&a|tys+Gv_{)H7l4(dY&44w*@DFS~n~&T`F+}n@|Nf6XY<>b%*rg|4 zY+$gC3e)|KryNa*dFUQZaVosu>xy+1VJ3mH+MM(4K(}luoS$B`WAP9~aaiph+`bPX z;d}&YGrUDrh7qBNwbkkd(iRTFz)(#?1$J_f{j74KGY^~zo?eIjy|`8SYPrQ^j9ui^ zOCpg;L>H9#_Iwsjs6xa_32EjfwkylPk+%6BwkG_cQEezFFtu1v6jU|*O zal&5*PAfrTIghPE`RGFf%;Q1rV98#PGp3-O(sJ+Zw5=_a{^!}P@aY?k8?ZBM&NHcS z)HLpzf~H69y>*7;j~AhY2ijZVO%~WcMqmRRxm1Zf;)D(={#+h@O?-w6%uu-aXEHV@ z!C-m9XEumWy=ToFZihj}_LFlI!QL)fk|dachd3eqTQDI3R(CDPxfKeCCeZF>?6crI zz!ClBu7#%v31IhhIjxKwf=}0h7yk-BAN8z&W2#(4ur*2jiXO?HUgIZ?xzI>+vlcH5 zS$NxvyA-^e*rF)jp*#@68lcCH-(+HV8~cjlcxsNjnln9sYE`%_+Xdjx?DcJ=?O@C< zZCKbXj@5+qZk3L3O%ujc^v|$}dUR&w+1gFHEsRm z{YysLULa%PMOfeYhhO z6UD_Hbx)j@8IoqX8O6;u#NVR8U^vW@$SMUHl2~Smu_Fc%=42kMq7c^JW{E$e0Dl@D zNv6Hcf>0fI`=LtsSmlp_^!={@{(*bjC74`Jkag$vO;)qmJVu)ml7Z2c+Vgfhbt>s`7EIiV+5QF7M$k%ZNdw<0`*m{~sCU)V z;uq^E;#su;b(K|BbD~ASg&s=Re}Ky})^wHU+V^N&WYulgj!pHa>&JhtEzazdkWfDy zq?cW4zB_^#MZ^?YV`qfMtkidEU7xA5zYaI|QB6Bb-A-1EIpk^CN)w6pE=l2Ut?LJF z8(NvZ|0wLFA0AiGa$q#M4M^{@bgX_+>aoK};ukaZ#h-8$z0Gg8JOQ>TqJo<=<%UCS zUF1RMijFfSf53gG>+^(Xd1uIawsT?H^WsL9Zl8KrT_0g_@b2+%{Hg8nzBp^O%Pi#G z{0mq#4X>ji%M9+_cGNFby$z{D%M!`N$e_Hd&Cx`pppGQg%Uz)r)C+Odz*V(2XFas7DVs!b`&Mi-`BT} zhqhOXj$XGM^hxuOG~xxmMV%cS<@%Ae*4#M*r`ds$utw*v{|hn9gQW=0_oqXCc(IMd z*l*BWNh7j`F4C+6iP2%poFlxa^K!F$`ZQe}(wY1&@~EqD@uKUG-PPAobT)?pWZUvw zpevFW{>wWW>t2!s&tCj|_qHl){bW@lnwzWZIjVKF)lKj0wZdA9m>PTxVh<9N0ilLe zBLM@EbE9I5jwI!|o08O>hI$qe_r8edidhE~&|RF(7SmAZpINB(VVd~RsVk@s9|9)^ zG&mvpm73CpU5W=kN~1Xlh;G=+Gt+${W>NJJy{r{YDH$iNatpI(s4=e)}{Jy-0__P!ztnvQq}u;ON#cZ%v6Fm8d8hdUoSDHS^lq_k>dZ2adzWCZQR=g5*) zY1;Qq-0B*eT-1%P(gISo{*L3!|a0E?y`w5j_}iIOq3#KW}7bz{a-G#7T(v zgP!}M+3&!&!!Q6IgGSN{wpux9qepz6+pn!F2kR{u{2WDH=sBqRHx?UQQ}|V}0+2E6 zq$J6;+l8J8V1hzoxj5M(3e4`v8WjXa3^ocLw$iM7qO$7JWD%X!tX@pcMVZ7MRKOe+oT6wjcd#!bksx1VS@@H^t zGsHM-0eY3!0^|}{7HU#`rKhEcA43U~H0o>DjI!FMtCFHzf|Y(c;%;qO*r6r7z!pLm z9#IgD98BMk3}y0BpGKW09H@T{|L!3u5TZNHZN|L!({#>fuU05`!o@ihiQS&}*KLCw zjlqopkv118=4A9Ipx|wSC=JZexb5V`sZP`j#C6?YB&hx&rc@0QV7rA1 z13$DMocJUXUkDLrLV|RtQrd#Z5rU%#CU{*vgt$o`sFRABT|-mOJ!G&!d~)36jz4g7 zk?f@KBd=aKjl!z@3OW*mnm94Y(R4EBA`T&|uG%R1f1N-3_}oa+VHvR3_XGKoDWULY zNrWYw?srI!54*>wy5v6-O|-}r~~5vAR5}lSU|`;f?3b|HwTac6EgF1=9zKtpwi0PwC*Zhv7W(z(v!{3 zqU$Q_qo5A2i|W}$(aoI3A4y*$fXzX$Lf|j*W`LkFKR>1et7BssTsSNm1&G5ft5F$N z!lLSojQOD&oJ}vLw+E7UFbUJD?6ba*ln_?v=l~kNC>n3cCP{n2@Tpj|m}#G3Bj=Nd zdS#ZP4oqACa!haatPDN;9z1JvIls4Sw@9s$Kht|HrwJ}WkK`IWke2Lq-K2t1f7(p* zuDgvgQqK-kHk%>SrDi)Xq`~Mi0?7*+E2sfbf!=@!$#tNCpnHuUn2b9u&sGY+CJQfx zdJ?k|Fyj2hYQ!;p(ZTub_f&^;xGf_ZubM5Bh zs>Y?@mgmHc(BiA@G1N(ZL8_Vm#jpJcrNQ(3{>vMD0u*i(gKMA!NW0#zNotFm+b z`~yh0BWM`wso-uLk zy@acE#cL+t3jpH|!Cdw2=}}BgD3J+OHrNsbjIfp%IC_k&F^gv}I-v9mZN&v+P+dS$ z>R5&&9Jt@`q4Fn-vqC_d+5y6ljdu*bX!?HHh+4Z(@Soig%5AV3lNuwGwjvrz?^GENjZmqWP}O6f(&&Exn@Aae{zJII^k3mASy}%F89PN~ zDmIG&W#^T;`y8ma;ZMv=QCGz#W<`!D_hjwOAR$~nfLQu?4jx9Xc=&Izr+b=B!wXf9+VeApddPuryAW&I~ zw>d61ZX*ka`@Y=f4s{s2t2>M)Qu)BgG{7Ie6xBE5&k2{(i%QlaNJ(erK-(C6opCP? zDv4uY7ygybu0T3)-hhH!(=GPPo$N11=ucgj0?Go+K^k(NJm?Yg03$^iE9yHe#@75OZ482ODpa^ef*wdLC{J34g?B{_bH-5DC>u9oq|0Z2hQa zwnH~@-2b(G-rvpY$u!xC-j^^C&Lg|8vk2)jcElveKH)u{Y8YE1F)3I7SJ&GEeiSR5 z%O!lX;@RakruhA`yQd&+5a5`T0E*iAnQV<%bBb<;fv(EN<~OR)TgoaU={T3={B?f~ zP71GS8V?~_ZHP8i`{p>nTt?@6y2{E^h1X*JPsYafUm-&OasU5M$+8$VY5OBKgx*(m zh;vb})k=v=O%zbKs2idiyw)0fTli?%F`*|1NlWG5&)FzH5sak5_$ zs)+-6(w0#DT$`}tA+q;d^OSR*Dyk%#7ls}?$9Nkz|5AS3YezS~7B{r*lV zmxL8r+Er2*t;Qb%;WpE)SN&Us@}<2p(_1lgi<>dnyET%^aT&!3@ErDx)ng%Zs}?mW z^b2x!E_?5LrL+q-EOj#ZzS?N1o$%i?J1qMgsw9e(7E{cgOf0d5syEuDxt*T2pJ6}v z*;@kM*(wQ@+!oKME7gn^&^L;vMnd#EZ-|nB7=GWMztmEh&LS(bv#F|&Qfn6%?OH?N zPGmW_?lf;2P+BHE#?Q0gDOE-;Mk_Igm;37qMkJ(KFLH;f&#L_jGt~?6>|mes`1nmj z)RveO-lSq1R=QbiJy{#B95T{xTS*G^2gxJ6Lrqvs;r~Km5DZtYRbi*6?fz?FO)w1&`npB)D*J7q?21Rj$=O5 zBbqhR09)`rNc_E!D$428IsuiS<@h~iDu|^41-;n#Kky27FX`^SwF1s`_Qbl7K>`Wj z-0Z@b!1T`bSLdaq_c-WX1H^eeYTBs?hl*UA2pEvC{a_1oeh|Io&11%UwzMzQb2#74 zW+sx?X~LfOZUK+7GArtC(z z1#ld7?+A^ffWx%0DGU?LhRKn5i{aY~bp-Ia0AIKA?_9GGut+%a0Y*cg)KOa;S8R#i zZ$I^iqfPDe;I`3aCT}e*oGH32;q}>G?sR)d{OgHwUP3p%Z|a&aoq3zVH(n~pqh z_jlQ(9f!I9Zh;%3QV1(--fUxS%ORg;97Q^6%3f+JiqbF_b<`_il{A9Pci3)qP}o*TI_CK&JY#mls4QuiU-q2*}+$9_05q1~aEf%Q&w0O)8g`0);XYOt^(b zsmY^P)_~DDnk=?p>vj}YI95%cP!fAWacm4s3Wos#{c<$$sBQE(qHlp*7$sV-6h+YR zxLkG{GMJP`&FdI4Zo%j^o9Hq`HD4CYe5~JUFqD#xk4QLQ1}4y5`sH*-y^^X+$5*Vj zcSf)h&RxIWoBb&2?&;-5Jt+;gCo>+$ti0#>EuT_#GWrPE5VVZZEjxY<$Ks6@ypnEQ z?B-dF)~4Y21Z3t-isn9ewM1h&5#VD8MB^~cK+@uV5ZMGVPmiF;9w}JXqkl(gA!b{D zv%I>OZ#xj8J+F(^es;OUSUq^lxgAo6{oF(s^(#n0mF4>;>lXkES1|HFI9KNXu4d1{ z&h~#g*Axxu{{_7J=Um??%B;nT%hjXsl=5L0OGjFtY2l!1hFel53#lg~l#j>ULxnFB zC>s9g3b2G_W6mCB5vu>zzEK79_ez0&g;o7+|8VT``e2Sz%WmR{Ro@cNxAz$TYtmAq z2O8u^wuU_`ioM@Rb3*~GwV4OO&A~sATN1L_h z>Q0jh<}St*fCzWE|33ApZ~1in1G>QFdwZpZnaSq6@XSJ^&?x~tW*l$l&+GOfG4+P) zt9|q0nFu44xej`%RGCEl3NEVRtYt5PR^Heed04=9i^F4NfyEJaakbPz>7`l#>!E-q zma&sr!|s?3x+QFD@lzhTnoouakLN0$bg6_RALF$2T_Av}gt#0h!v0Zi@q`9nIf>_% z=;+DOV25%_le$m7eBNmC6Cbg?&|-?$=^WH7*7EsNKg=GXnb~1`!?ZP=@XaY7!nlhT zLI?}c|8x2B1b|9>%d zPEDEsTeEJPZ`-zQ+qR8q+qP}@v~AnAZEKp-JoDY19kDO=UHyQH%8Fc>&*FD*!_i%R z?X0!54uMV#2=0=1A64?os)F~8-)zrR-ogYHuP?4)GHxtzC*Hg~I?1)ZJS~UFSS-u&jQR#bO_!DI z>RYs^a)N6|7e$o#OZTnY@4Bs0lx_<#$plS`guk;$tCEMAIWGsM}g1RmF&`r zV=98rS3uW|_yg)It=h5;?y$;}#q{hiEpVIjd&jG-S80-sq{kAP7fOw_pytae8XO)t zoY(Cc37HYqIYKK65xJHu?bpid>=c+59Cr=S&%5A!w+h= zU3=y*Ggc{Q#*!>6u0o@YIpXkuilboY&{ z*NcR^<$>QF0_2YdLL^ft-9yy>z}ia95<4xkY()rScO(mjDIW|p2W3F-27D{;1zTPGQn#&PD54|Iv>6`>&fcDiAu zId{H%>ZOSj6=4~M&Kyv-#Rw2I?U8Izq#MD+q%b4SeYe}o`G&Yfgw>wRnE+1o$pkV0 zebop4qwZXPz6@=Wc-|DiDU_{|KCi{);pwS>d3bQzhVh!m)f{45q01K`D8o+!2^lV| zp+Jq2_Mz>4gzRfZE!k0dp8H;UH*4m9n`0CHm3pUYal!(FP+4ws2QsWTZq`(uzt07G zQob*6U0(gx#vYOwWUkAco)8m#^&KNp&d_X)PTa*7*}#T#GEJ>>5@9PgY_fpv zEuhnevzB|@&zpIQ@KjFc$__BR7%-xYvt`{6D1eke_cCSP4eV#c8Xiwe6Bgsk&Dvan z>@s1+Qk)UW&yIqsA@06Ar*KhZrL?gyQA2W&;yNsXWEQmGr}JAqJ#1nRzdrgyo-DJc zBF_wtrQr&R-}-{Q+s(*_3r-I0>8Re;oWKJoPVM@=X@bD+t{j5ym;e`rLvdLg0l@T8 zg>*EsMdvZE7uYn0h9|->y*GvK9BK&l>xw%#-ORa2vJ4iL9?m5j=Y~&(^P48ZB`=_1 zYq`*i(-Dk6hN3oE?2=(BNZKU8TlWJ4Yf3RwE>I_mzL@+uXp+(U%Bjw+;7xRQm(zvo zxsF{7D?to>fcj)BQf^ljzSbf7a|6)(t%CV8}q(8wFP1s}aIkzjBskI361j^t@RMX${pQ$~lZEWIP-e_;QfTG;anf3IT< z3do_nE4ODKG|T`rn>6OZ>Xw|0{Fls5PJ9j4-~^hKzeJ}NG_Y0t33cLZYK6i37{?E2 z4{f^of0O3_&C_T8PgHY{mR#~tD{{}7#<`?gjUfO`aGrld&C%L90>#@d6PFWJ{7{?} z&Cf%;;`7a=7#OguNOLpNqC*yBQxG_MwT756Ob!TPfQs4MHU`~G}dU{0jPD75-$+>yfaWjay(>OIjiZS7)} zD_&~|7HuJ{58tp|}Xb{BFjCg^?in}dju>LWHXtXn^v(evLitJXM8L06Ixaf`v zzUb>i0WQ(Z<3kVJXuf$-Q^^@mhab{Bx;D~rVChtF&#@i=!bIfCmHUv1%^R2Su9QCW zi<);%Q4ASvidK~A)0KW#bYVcd)^#s@4X@=S_~Il(@T2W4!j)YUu)nJzisV9hS2~t& z1?}v}p;GkQt;=OXXtJZAE9U`$uho>eS-;Mm@!;RmFir4dU2i*@nwZbh>;9BL<{OLj z;P`-4A2%6Yg4E#L;^xh$rG_TPEubTMD_dx1y+_j5x=tZ#!`Rr%^~h@YT&T&k_0FhM zpb`|?QsVZ1b;ftmA$?`oQ72EF0xtxPG5KmtWs>c5_Z3OkW-c)TyViEumo{}gwj5^l z2BpEE4)?jeR{^-5uDFy^*=iTtawI};ZYUP!lAyHiSQ(0qahkH2QM*AZTvDrezXvr9 z`~^`)DYb#hOmQpn^Mm}AV-2q*E+cbjXe-QAxV`D8snunu-9G12(+Age2Pi4Jd!Q)J zuXqOiTBgBYOtHER11gVR50*Nk7k=VR#$a6)2{O2bI2Z~B-Up)mJ0@136)ia3=z|s5 zR_v(beL^>r`J|~EZ4MA!T3bM*$&*_xO$J*EwA{oh0lLH!lIst1L>8`bZ>nHf5-wQ2mZ1RxVJuhjIcnjRSWqDt=r?)@bb! zLPxT~=fj%`?r%nBENYMwz=7mfg| zgbv3ClOakjJAGltQkU}9UL%Y#=O8xc6&w51$)l;gYZ?J3A?;KK;Dv6=s~^MTo8tyt zID;M9(S|oP9rSE$*rD-eygouV7i@TgoXD0KmBVNRI!ai?jx8iQDt^ppZe0FClR7i_ zImGWA8oNv#D<5&wwMwF6W+_Ry$*}EJqdd%8)H5h1yTp%A4eo%v}m?4HQHqX!ukB@j}}( zp1{-)*4^gAytecj804RufIHO%Xeyq2JZFGiQK{5*YzbT1rhbw!jyA5xKS(qZFt*l7&Gr4&(Kn?-Z9 ziWb%Bk>Bef=|@_<(zBoQm)ly&n#u4$n+=re-vW(y^WVLv8ttr<*CW;yv6=F2YSk!GSyltzU$tu73~5x+_ZY%bQK zR-x_!aAV-Z(+<4Qh;UtCas;s2o`t3&cZ>q;E!=Bu1?$NhHTh)ka3@&-7W43+iC6X| zuPGKDm-=sg3U^kOwimEoM)WtTxFWZjJ|e8-q(TYQ7_a!}+fJ-Lb(D%c0-N1h?x|Xo z$EBc04mntONDbaqUQLzSr3{KNvtnxsZ8VbeU-0s8B~0x*W{Nq7a05B2`iSzTtG4?fNag~aaWtBfleyI5suvM?m~5wd){wS)w?n^ zXq3>C*FF~*V3pC%5Io|nCt<>?j$|=*^EdQzPHSBR`kddM-tKA22-*|l=bYGhvvAX2 zxh6b6(zU)|=(V9tSR|$L-ry`?+z2QrA`fuQ8UgXY^=QiI-9~fQW_ki`3p7LKDnjgdnQ391Lkh(_Re#I&L=GTCP5h_5@V&5oQq! z)UWk`%A5LHf-_%ODa%F}C-Qb-^F7rz37j4dOc|_Td3*J9wjaEk-CMdhaNJE`6~M^6 zM?qA&(Ca;Uu-iTrZBpq>CH}34Dr3Ryew6}1fx9Q_-U!f-$^0$F>s9NkvZ04;H)2<5 zq@7No{h@X{;3cn>SMyNqarFb$m2(d~tF658q*LXy1r1_8G=2eD&>K8H?eZ=b2Ue4OYu5!Z?tZq@wa*LxA^B6~*lent(y zqbPRkG-3>osc94vh)1{Uo`;D`|=NUBAlALQ!HNPcUFC) zUS!H^fgA$B{tj0oj6+5>J zz354_>xI*U$`#;)L@9sc1v-s@AgAdi=*_*MbWP;>Y>3Pf;g&qfMW8&+?tZkC_Xz*_ zkcj>VG)sy+g~=4V#UY7w!9b0Rb1-pM2Jowt@eSY^w4n9mM#!x5YOA@TLY+v?J@kcJ z9mI4JDnk56Tyx%P3lRq~SAlB$cf+%Vlhd0qkOLP8@G0soW>UXjShYgu& zX(}QoDIs#d^>tYHFRskNPHgGGDE$(KN8R^D;c$=eWmJij`30`hkT`a_2PCnOr%(XG zSIu=HOrh$yww#s$!Z|H7s5^0W3@xXq=`0qO2EiKi``yR~f5HbT=!YRrud}B^OVf_U zE+XxFVOI(gNdGtmNoLTX69P*;#G?y>qp|1&X92MYj1?xFbX6_2g-{UBjbDA7GOAB# z6y%gy&zqG@i}Gb^N`h#zB5jlGuqs`uqHrCDvT&}~R&~p8hP!PW@X#;8wE_L>rkwcq zE|n1+js)_@N>S1c=TkLed2#QUIF4ou3^0MELpq`qifTAjEq^IH=b*XQnW7oonc06Zznh2E`g>l zz<&kw`a=>(XQjS_W|mO3;KX0yOd3{Fv) zQ(73Kjkz9fheGe}Vt#R(GjUFfC6mA)NH*<4-JE4I3Xe#!8j9wlb}|u{s9^i=F*_W}G;$#(>;f>9U zNrRCT&jyJwUe?jy4{u;-NB|4hMsIDS2X((iCSj0@`$(XZ!`jSwSvg{4I3ol4P3K2^Y-Q?-5dOgu>|Fax;*<^a2ICN3E2K9My(v#Vi0BEge&C z`j2Ga(J@PG;qcS$pZ?~uzzUf75U!W|OXzw$9%CyU0Op6aF@PE~a(IJ_G*U-RsRDPy zPMQ9*5$boJ?<>QfYnZbCregnF8=i^zKhk_R>T>^Q%J;l#An{F%WFhxG1@1<%3q}`6 zV!x_l1kx_GqPHHW9^1e_jk%8(l3Hv0A_E6GMp_TxT%OK8AUTUX4rBxj#wTVB36TDc z{A?z!)29fLqBa#(=ke$=*#Oki8no-I}mqD%~taDvOKf$l5-agz{ z9Y}`UGIqZ)SX}|NCet{f?5jxIo_*Dq{lFrm=}$fEGK?sTEIKEgMgYUaq)zCk>F z>`~KP@k6wzL*3)5`s1amEZkos>x6VXRt;4$^!Klp>RGvm5IKQ}krXo1Ovxx@!9z$| zN#GIzOq8jHrmKAuHJi0)0*WOPRGD%B`jy4bv8$t9bfwGp;#{>QweRZ+@G5P``D{Qm zRw|C;`cJKVT|M+CD{FsYTQK~f#T(^wG1hpXvB`QWjm!hy^f;vlFY4c*u>s(rs7A}^ zYme?C{{z9bU%uRJqj&E;@Tx*WY%Q*IS}BUq5>e3B2*9W=5E*J@k(u`0H^tR2G&cmZejdAPjZ24+Zskjha zax+CNCPI>=j~n?=d2Fk#o@HSE; z1np{GG+a6}YG|L*q;c^5unhM7=~k}eO$-7#g$uyUsTcFsfn6LlM#sbHZar8$n;vqxh*W-B() zH;P}Cd-=#eSF^`T^2;8mIfY5d>_r?6Ugu+yvkble+C-e=xCL&qol+Yu!q0 znri_TOLkj$_c9(6QjzE2=3rp!^>c`wrp1{r71mpEh_szQ<941QI(B7xJlP$3uS6y; zqWtDyQTC5tNxd+JNw0sXPfyT5AZ*!2W9kv0?arx#xI4PRx!XAvy@`$nzJ_-cm3Bp% z7)yL0wjLe#^J_|XpOLh+>-$6R=*{fV&ReHDLB7MMr6Z89!82>vUkyqoE00gbQ0(F# zP*QKynO!%)7XQ6Lp{Q8=KC$4BORVVp)k$-cvV#)XRmRJj_H|X(iO!NQtTygwQ0Sz|R{|IQbXl&VSi6i;mX(0I$!#WT3JS_6ESt|dwjQ#x} z5?IM-X=TQeng%2F7w~k%)712vGP4mERUE|9os%a$H?wJMAUyyQ`twMLeBU21y*7{? zy}!ak4?3$==<3iAa>t~gnFxUq-6uRis-iUAF@NxEjq>ID@az7C_zl3Qbv&R~0GmeR zPAC)XnjoEK@#Ti*1H&)RxlZLtQFDQhHOrOkWx=^7ds+r}m(qRkP93F!?B{2iOOX|s z=$VHqo6{_?_y+-94P}H`<)H7aSdZL}3HB^eb})NUKU+(b`?<7gb!Dxw%34O-VSCzr zOKZ^8^CrmmnI3jtPPyQy{gsw=Df993Vqi79)%s(Za`S;Gj|oAd*&G_Lqozs>^;hLF zS%{aGfp2dJrn!8*)qUsvBO<}9rP4+mdO2!OUQA5)eU8;d_ovOKr;4qv`tQ0?AuILr zhWC-!NaI8cBNh9uNo;>}1{BLiQ9*;EZ=rJ(dZ&4HeH>OD*8I+(h!mJbV==|`=h;`8 z;3Oq0hbtM8t9s)wu?Bz`XLieI>#4WBxm2Ge257Wr)P!`{*U^X4)jf-LZ>%VKkT;cC z`?mJklq<~jRGQxw{3h&7H^|Q0`I`0sBQbN2U2yNLXl zYQXOlGo#`b2cA2Bqp$2H?b_F3Zq>qIn`qmrYBeqxu*6NxR@;?~*b-5LVQ%4%iR#g_ zD)1UFEeL6HkW4H~zNl<={!(E?kL_nM=f&AzKp%}rZIRH~cU2%C-){23iH6%5&EU}~ z#v)ql$t~`f4UQ7ExFj=$GViht8hqQ{Q#wGK#Rf|j;hwNy0GhqD8e zehz3e9r-9ovis;hyJ)!VB$Qy3D?nLi^Yma@V&d_S0olcz%J^yUoq={#8t#+~B=^tz z{4lcHe}m`ftDDCpkub0N2<7j59}pxvD>rZ9wg3PwRwa(;$uycIZLq@|>>UwysI%Dk zAl!g4?|QY3D?WyBtMx1|eylQH3AI;kI;atR*EyUcI2!to-;P$&+)_LoLG74;VR+*7 zj}|qJ)T$Lw+w@qbc4ftj8X6`uHG8^@F=HNsRqswJokjL5xwAqQ$4>smejPz@cW=t| zI|2jS{5AT=tXqIKMXtu^>t>>i2hVRB*Gptb^bEVpOK3i~lk5h4oNljJydysw+asq> z)L+NYls%QS%YQf7I4N((e8rzh00kW{I|ol$qi?5mx!`y9-Uc<5jh>uIe{8{w(&W?z zedfF5p`Ui^I(I@yttT#iQVWGtviC zq;0t5SmpGyZ__2nv3tSnxIiG_+JP{MiYtK>grhKJf!tXgUx)57(MwqHI~~Um#zu*l-%!q%%UCn)H!xhkm`wx_1nvhHfyWD@Xk;V z!8yUFd3zI+b3jP^A<8oPD9aQD+wu-kgC0cW5A1x5?e^#VJ+oBK^V|iEmvV?1xB z%5TR1MNHTj|2HvV`Hw)#iKdMGKQZ|iNV%6pTMhd-Ebc**3qTiIAib@ihKnk)DMhWg zN0t!s_pxvbUtTN~qqr%dv=N*-xaMejd<*;iI&h>9Q*ydBTai;he3T#&8jrikMr)b+uc~|s-N~t$Byz{O?%fAq_Uy zoBFPsT)wMsavHt7%I_^^gD=M~7Ti#I(#+LUQJwjiPu?m-E>6mlKT9zFCHdxh56BAH zM=kdp->r@-#FEiWI|V{mT)cr0}AFACn#rk|tWdD+$1z`b@+b5!SXlS`m-Pyi&V>b{rug!nfmld%gadxn6M11znv@DK3{%p2_rQ@H` z4)A$%E@wqYj7$PSk!v+;JJYj{ny$YLm@r57cq>qpTe*cy@^}=QI+{Tm;VvMx0=Jl?9VNL)8ay>H9$4o>PmLhZ15 z^RI$0N4G+E2MX@7K7YY)Zev2PM)dsL)M>aWsp8Q|CakE*6kXHXO70j|_vX9iZe!xy zk9E&v9a^sMcYINgjQE9a%KTocyInB1A*>w)EyUT-)@k znIg`14txxG0Dgk*A~wxpW#?~eeJ}nRK}aKh2whcAD1=2aGMwwSl4}X@RLo|f53Gkc z8i_HRDI(&(x}8-HS&RZNoI+NNGCcId1hM+5pp0(jicP5wLpFg7W~@HB@BL$?dZHEh z8Tu5`Mv$yVbxEU}Zr9<&v2&%Fx&2*8`-? zvD)zIaLs5=am6TWmXW2AQaSKZ=x`H9ZaecC+LGBvIpk<5&J%}vHd%!KFd+Hm0=%0E*f_dV9IeF+?Ii7l= zRW&`5%w^*ZKemhKaWp2L5s?iOQ2Ga*6(8&NJa*t;IWVoIM;c5dL|T%5n`XW_N+9J& z=GS6G>@_$CzDd{=J%QUuMAxU|KT3cOnf!}T{kvv1ReC%`{=9RKc@J&t`=@4|Ur`cY z;m@D-CFILLlpuwMFrY|~<0}b#mK7e|ZgT>jc>KR6U`=#3_Yu~arh`q9w-$(PJRI^T za@fuIf*uLYt+960NIa&u&DlA1yKbG~bxs<=C1PoL&)BR{UCK=48})XM)^M8W+gJwu zK9eA-_QHzk5W8hyMd5n%fP{mp(i%nG7sk2>zu9(g5|4!8) zO2$m&Om<9zD0;)SsV?tmAlDp}Ij=hSMl|dS#HIK89m5ArP5x~@P0N(h^NBrQ6>QJFaaj8S}arZiMcpes^_gS zEHzlrXr^rTWi#h5xl8`&B-PlwBQJKv{)72iBO=D2W~}J@IJ37eQd3m1jIh$$_91n~@{1yxNVn~0KpAVqPwT>oxt&Ayi2Z(%cE&p{$( zBm&S?p@k~8KDj@ROe}iABs@o<@^AUZ25+8@BL<8#a@*jZhk8l`*$dl?5B#r*_1?Y= zNx-UB=_>I7?RFZ>a>uADa0ZjW7%Ix4jT#{#^D}@6xa6e@fn_bRpMECcGyEZ}^ zsvG2pX%vd)!#yS@39a`&)T7lP*a5;e4-ko=%3sciuTrEdhxziI)0?*w#)o# zb_TQ*Wf4#Rc|YIBayyrD*nP<)m2uG+vw28dJQpKC!TdCmkI6H&qo z<3gu8KwrsGCs$KC@< zP?8_r-b3QK)70`XoawRjN~MnJ9K4YnV~$QGNI96lc3=*w+nn+xqUz~F6Ni+)M{Q?KW_BpoWV0Xdxt^+PE*p8G`Ux{bUCrgL1{*4~ zxNxUr%%4a%x}#g#YV}cj3uJTO=@vT~w(K0Og~s)pk?|dQ5a7viXo`X2dy<1zrffr` zWzR%DQ$ATd5xgeTlXi?`!beb%2nk9i+|s;o z3-pf#wRG$?^lDl>O8m_rz?68E=agJQl!M5qD6$?NdNv517o6g}>;{bIrD7rP26hZL z^o-*fY+2X!Qt1FOV?|glv?CQSJfdQcf355&$CM1WJ?l{<9#*cB%~a;jv-d_JaM&MZ z#9DBP8>&Uc<|G*xm(ZM>Xb zgSrymswey1pBXI?(t(Pap_2tygr|~|->(f*@g!vTj>#9W%LO_xA<4;|cvMwe_H0n+ z>q>DXJA?U)w^3TplMXBloEcqPV~S=4ZTuZUB<325QiB=$R~#1R3F$RhKI{3G?%C6` zbgs#kqa)ia9l3Mld!D|dcE%3D=~_+Yk8;@>B?5eLJ*UbPoaHL6Ew+z~TTy>Z&%uCt zY3>7Q>Q`2L9FCR7MwB!Ff{jd73LY zx`Ldl{W4sxIbfx7oX+JyK$6VX)+zn}>{%w)g5>{o;cS~Z9B(PK&r=-6xieEt zCu;&4Xdz)&TG8Qe3H4M%bEBDQD;B;ys-twFVgAOzq@5&oRl%X8<#CJ}DuN@%5=hik zAYDyQ*1V1!_9AY`ldS&9A9mVI8#8Jco@ac+p^6!!MQ@2!RWKI9X__;79!|z~@lD76 zg)Rw?3i~_HyChF+0Y5bKq~OBNEy!_r7}`x30I6BBSXiIovA>&pY*c^*lBh(&v|QPQ zT!@-W$iL6M)CM~ifyn#^S&<7jlx$mB(?het-aobc>vy9ts1{flv5VOHbvFwwi2;YjPEt_zwa)X$P7O6;*Nd&($`S+ z?YHL`{y@kOKJpm#aFWD*j|~36lOb+P?aChub&W}OQ^S;cvy|nu7kkZPsDF4}J?L~r zuRCCvYGBXYSngvdF6sp!VPE1FvWSFieq-bH#R#bDAvMN~RhQ78~odXhBg)Tc$&+ORazsUWp?i~fF_ zb&!l~G~?>Qj{>U~ML65f$uHU?#wWWUE2a(oSG9UwIBQ#ouIq^4wCGS?xZ%65^Bi=- z+p#kkr9z2$T*-P=9kF+duhMAS6F1lq?-P?fCijYJHkaN)$&7nZN~=Gx#rVSg;v_LF zaAfYR6fpS(C)1c{n-_$>_7*1^=jhy~eZ}hMJ(_z|7{GU?k@`X!=ekk78Z@@T_i0M~ z9qcy`_^6MZN|iheKfEv9tagw?*i^NlaT$ohiJEb||ac z>|whaS+;6BW_+h^ zplEGoXKT$&Wyk({(j+=;|C>T!dtSu%{NkWSXPtelOHXX><@j<*%S?)$Ll&CmW2%y7 z>%E~aJGeN#urlg|nY7QhpJrKWn|-X8U-fo+m>*t$hOjj8d$|A$tHW5E%ZczNLZFjn zW;{3dxop)@VKLUVT6wpjqBRa2#Kp!MWDF!auQkd~evS2D+JWNhCdMsF=y36+)1Po> z(%gNUKr&fw`}w9pcdHnQf{TSqH^UHf$e~=Ibp$~&G-9tt@T8~))?wLvMEw_)*(cTw zUS(OJ?U11hJN_)iVN>0MZHJNrPpy zFF3M*y9F~-%!f?J{xYjsN1wX5I|)%n5-(h-{XAzXSHmQ2G#k~D`G5-7(x9zQbfBYC zuzXT65JAh!2za*BKO9);jf~MKcWNKQfla{8g$sQO`-;t@PrSpTfBOAaL*TmwcOip5Ws0UNd&D720NNN9$EFQ zup}&;NbFheBey42GP&ZWvX%au*2-jQ+Of>CIWE}l0xSSR)0R6Ky}f3&@Xr%W2=-^k zlGmaEJ6brtRTY$1ynp_`bEiWpTMRxW# z0-oz40~new3*9^MX#0lRM^l<`>e)1!L3>zPb3bQ=OgFa=6@rdeJvRQUnoj!qtwZD{ zo(r>#OpUA%Q)>+ZG{lx;8;C1)r;WrOAM04IiNA#SeDw3m>Ms#l_t+a-v%rOwnGTDa z8thvblDxhw$CLzF%QLEROz5IQ9cN79YlTyPJ9COC++PaJk^$A($-o0i?{;BroMTjG zk%*Yn&C#9ag|!=^Qod>$Sd#4pRjMY2JXi_5{PjK>TfUlD2e0|~mFU}K$-MHo5@@F| z3Jpxi|8o438zItT*%ViXxQ56wodWfRS({wLn?fL+K`U*VAPE@NckYvzLjVXq(z zoNyXB^P%GoIQrCDKF>ednL&0SCgshiSx1|+j2{|QwGs&%XfjvH^bZk?075Y8M~skD z`gpi!4R0V1nQ|PI*`DL+=vL*Gy75?tUR0e;Gpr_d(+*MJ&C#u65aN zsXrL?_dg%ZK(`fo%b(li9XsJ8boLZcM3yUD%x?LB(spU>w6pTvq={7LTq4Ne8!4xV z9EGQBtZWsH`REQZD`MBfBWQ~2jxl?XGJ&Q!)=g=WBQ*t>LChkQ=o;ZEa_!1!nj79a z4xrrr~kC%?gCTv*dvbN&A^X|M2*uo?)qfs2$!Ud%Mv5~ zF1*rz zll}i`p*k}Y%YO{*X0-n8*=a@iC;RusW$Q{dSH@LB2AfMDWt34WE+322#P?p^TK2pz z%P*uGho5grMLu|*rBV!(ZopTZGmG2+{O0$Q^>Cf~ft)Dji88XSM~HpRqr zK;CC|Zro2@a-^)}(^u5C*sO#kwr#lLKSeg#Mj*{2L?)U8z@d}3Y2WTZ0ggj6tZ`P! z_3OXt^Yy326xn?x_I23X-h>i&i0p1TOKL8p&{v%5Zb=$H%y zI_RcH6?7fo8^%oP^YG3oyquh<7*o-7Tq#b8%_0zoYoeL{fT+F2+H#t#839z=wIE~S zk}tTL6Q-J7)D@f@1POXAy*vc9J-e*!ZOQAkeR5GaubPYOBv#a%1*r8ysw;VTFKqdq zElHOM;vR+z#jS7LVDRJ%kV24fsu!#DHq%it367T;I!}-B9!68_^u%ZhCYg`}WTsi+ zhK(>I(l3sa27}isNc2RHJHC<()n-xXyZsShoUW4BM zN+)X`3gxuUf3!KhXg`0BB$9ZSHvh``(Js;M*;)qZ!eZYMTrILo(C!Bgfb5%gaMRA+ z5+=!#n}Z7QX*?s#S-M>;u^Gv>VjnS$&s>7IQC_SX9Qhd}59eZWvOn|5`G5D}Sfi>* z#8S7Bm~TZ-5c|5iivU6JKgqa#yob11Y+5~D+O>IJbVeqO$&Odpe^J;s zm2zU={ROS{kl`#Ns?X^xn$$Ba?4L7<28-@;ijZVg;Zr0sllhdoB6jHS#fOJFjknsu zz7Jv_Mf^mFUMiJx+-X8tAx7w3Hc?OPoF!mhIC_qKtfozK`@Y}?T~~=HzulG{48k{F z8Xd5v`7J!e35q&QS)0Pw5~VkeP;6OVr*i3aHJHBL-S~TRnkOf2}GdfJmIvCKo0naFM^D$^ux9V$t>p2bCCOQ zq^XNH2ai-VcCtZ-La+jv{E--wcB4;aL&ZNfL!4H=z9Ky@4g9IzMfgFLnVel-xNH0$IM?HJciG%1E&5abH^lQiN8Jx2OxMh-d@-$NOl zU@D8dc)Ok3WSEaJ41sb*pYtPNaD>-?yF(12(4WEmjNjpU(w{1HtspoSY#ii}VImkk zk3v{$wE+4H(BWW`3QHn89|5Z-_;JMve@_T(?wkpqP?gmRfzjnip~o@+3F}bAmC3`^2a`#W z+8`}z0K962;mVqitjQK|=eO*t+_%%*RxyYbQ!Qn|$X}ON@Jjt~yLYZXTm%a`Dd^$l zGJ=QPAy4F6zTl~;j&PxnSWpL%QM!usQ|B=W0g%7m8yg@-44DS3kpRVs<(GnMI-CzS}JD4W5F4^FY~C-btMQlgY{-r~P7aSw7ct*+r# z;#kn#L`-fXf<63|2*7tJ>3?dy9A`Q~d^>be2~_C)jQxt1$Brp9fos)sgPH{Oq?Jk~ zzS~g$tvYx{iJr}5TQ5RsX{F?Lbfe_9l2g#q(X@h4ZcvB#Q)N~FMKWC-&a9}<01D0= z5zajC#*iL}!n6?<{%vB%Z$D=m0&KyX1qB_P;pnM0Ey)hGnIEURvEk)FzrO6Ap^(8< zKnL8%tplq~IU-z7CJkD`xD@2xl4jk*eeK?)j86|cRFVr9nkfUD&@hHUqbpxWmv#LLYUd+Hx?eA(`L zZlzRsGP=cTI3;hn^wih@=Zb}A)b46nYQ{94brhg9KMZK-@*qsrv~!8Kl4t@i3J!>I z!~aN(0b#W?MJ~9&f-Vwl_mE&F+Byb6;h+aC;v3hjI5V9hRn6;YDq`G!TtZN8ARPqCpZ}7FPlAD4fCtM0vwUZ z5fWt#%Ru%XGHD}vLbd+bB+_L7ggo(xVO?N!#tq;y@^))1Ol{+qH!=4sZJ76nT4*EP z)t~U|p=l3TLLgB7zkE&Dng6E|FefYH|IZ|7(cJmx-6Q$$85Bx*Mr%o>P(p*hFxr5! z!+mK!u7U;9PBma_IgxS6hkreE9pRC68s!*iEfgG%J=}T_^zm$dT!-od{RlI}?las^ z=DseKyk4%Y!-6J4cDQ#u42m8%v<-uw=+z3mr*B#R1J|6s?if{XSv&gv<;j6oxk`u% zN$JPBu+RRI>!_LR%6>MQ8*U9?#Yilqi%#>XL!Y92Y$@0lfLqB*d-dIU{)ZZER-JFA z%?d-G9&JB4vUrLy#0*O-lGCWRcNLqt$}6fDoF5P}2H9+9E|u1Um_=JC*#E{A+E z90I#WlqaE7sl;(dey5}?GIY6NeiYdydXX}x$%No7$c6PoTZfkl2H7&r8&9Pe?v&C; zHxzwUR=A-#5`gWE^m+ktTM#E|p9xew%(n#}O$wre6ECU;?uKg`!De(#d&%_Gz4)@# z?;BTlrLA5KYK0c4f|oW+b%+*%NcET6J2^gm6mJt>P+{_vY%EBvMG1UP~uuI%(28eBo`Qb zJV=0$pwg{+jOdqEVgjL*W8u?dtf*iD{d060)(KXP-X&V5(q#_U1)GG&F$0FQLgh`a z%q^}+$)g{s^r{i7N!ds_tIsL2Ko`m$MpUjM1hb}TId0JRD8;~8qZGpGOy_*Qd(%@q zz7o-*b12iTSsCEX;E79^Y;hjD_)2N^ebKzqi$Z%#jh~drQl%sQZ;Ngph4}JvcKOgM$mSXN z%H^8*9e371XCXFz!JAH09gDCZy*djouXnZRb$Zsays>D0wPB5QuhJ62d-z91+lmBbkGX8_*D4ecLf5tmsTXua92wULL1}_-dgeOl}!T1J9`6WNn<|gw&e$I>Ie6(e!O?NTI#0J zmK#z2ZkS>>LK)aFk4GZ!XRw3d9j6styG>VIt*I%5Y#gKWs=}GABxyMOVrGu%Xts7W zxxwn;wX&cucmts_=qGO2(7HVI4O*&7xOCa4fGuLB_=d{R_M2U9Bk7V^udlqGT2>Srl#K)q=QV=p^ zW7Z`WVnlWT^m7NHwf-F3{C?V6&%X#;f0Suc?kt~;#tkV zfHGVRe|o*ve|UV+326u~=7H|u+A;^%cBEhNp+?R(1C9#^>era2S=^K;xe5&#uZj2w z!zbUVq5dCZ{}3fgv~=O3W!tuG>|ORQ+qP}nwr$(CZQHi%)_)ss+%w*3oMv`2bF7G1 zG3Pf8vQTUPcp#9idxt&e=9xIZR5@~<+g0sW0*ikJ)KB}AVDU3W> z=ULni7_B;o7+>YCvkRMrng<+Z6;nJ(=-cw_83uk6c;saaScJ$K(G;51(T6tmX44hL zFf~AzggRb#$^iwYONdxqTzL7yJ#Q!*o_xsca7I7Pl*GLi7M?=xg>?D*EgleNX)rZXKm8>`ZSCwFBpQkdqzpwMepsZK~|*QD@bQj~#SQ_(Oy zF1<10zL`&(gxYvNmK&5M>%s6u{4M@H{3-P+;e`p)TjO}2*^m#B{`DEz#!MJBF7ug) z7(^64lS-4rX$jrAiX#>lHd0Qi)Ml>BLXK2HQ-hv?XdiG(7cQK+%4i%?o9UBZpP)W$ zQiUKM^u>4UAFFg0;V)hGpl1**)3c+h8yG8#3mdwqz%nEwl5l7m&Y50FALOTPetPVG zzY&~m^f@Z=rQ~;&rM-c21cCIkkN;(huB|lN4!lC4qP)j%PEZ|nW9NNTW4={$P=kMb z6w+EDBdCRd3MP;!D0Kyvtc`ANop?z?9ga$jI6h$5eRJ^8x+`>w)jTmEHd-p5S+7 z&iel?yT5kG|8pJuDz8o{(0@@tVsQd~c;U_wX#D8}9uoe1784!6EAzNRFO;vltUXyI z+y&=!qM_f8uyYjCJ5%nFa$gR}hie|l`(NX_2=A5v$6_1)g_%V|o+slwp=rcjJrGGme&T$b>L7`Y|Z(%ibif00}DsG7(=HJ>Z0 z*I|`5INZ-PDpl#c?lU|%_~X)AEnWnd5~ELaGsbIS3}DZ`yg&~vrkRe!#(25IR~iCj z(K#VJ21>hk_$~JBmAYhFX;xVNzQKb(za~E6YtR&l9q_h0EupZ|vP0(`e4+j9>`Q7o z8}7wVL_(U%2j_t%H(`f{vOML3feA`n(PH`opFP(WCw+Hsty~b7vurO7g@=;3Mjf9o z%U41@3gQ1zjthI!oE!NR+!az7o1a9~iZfm14k2!mVvDZ!r($6qUI4H|n59Z!4I) znq@Exz-L{nl;Q(&dr z+{Df3p8{(;)aE$YW%%Vq#poo(SerG%gC}?mua}JRNHpg;$KPNE4veYdpkxtKy?3`; zFlgE}+AO!Sk3FbK&e2~om(My)Rq6KA)HBIPg_60SW?NGo^JP%zWLp)qEub zxKxx`#EgOtY*2P+y$0H=Or0#5K;Ade?+nQCza;t)c&3}A>yGV$uXp$kx)g-SVpyDM zuxROqC*<#+xBIHYx*kJ+cv>v!$5-J9_8T+UTSwX83M;~ywR zZ`GyeboLxYK7p5&FrI(#%gFxg7iqN5E0jIb4Uf0`xUXh7$UQR}>S2KpRmU7sz=0V3 zytp9LK=L4y)zPBZ%2w2JO#%KfRYdGKo~ntG>b&l#uTTlbx7-7D0;5WsQ|^75C3zzZ zVs5AjYM(Kl{#EPyQe0Z$q_9o)?qnXi;#CC02U#Tv*Z)-G^tmoQUn-%n$Ek=SG~b-Og4Ou32S zAe)-YEJy`9A(}*|Gp$-31E(|2wT+7VieblkOgE-Zb)~-pWc534`sZ1x4uLIb7 z`s<>-PCHpd{tf!d)gC8ZnozBm`TetDja$IX3;@@gLkEcM9t`!pAi~-=m@uiAASG>N{kPU4S z@{ErJ>WEEodv>P`k;Qv2{qXIQ%rU{6W3eSNu<`pZ_oyvrTaC!H1S&=6*>}Ex|9yVQ z{I^>9Ke2gO{&PYNQkbyLVnFx>;2N8iGxXWWx+rA`t3>rzhY^iC*_Qzz=SC4d9bBNd zkaWp|#*bt(pJdhz--4h(y~xc@et|XudsgnX@Gc zDSyRyhKN5dSoWB3uK0gGM{GU{Tqbm3?hhZJkn>7*fU&2jU~$RFxgC2J7$X(IEwa-W zWF=d#b&CG|AS#bbj+F=#rg<~!5KNwM&3Ks`?{cxjhRavW@&0*Y`>Cw;zsKXpf!k6-)N?3gP|S7}BSRBHQo`^wHUBc=$N{3nmtJ`74q zQ#$36J&zZY?yWy7F`Ns(gUuivhnp|f>4BZqftjQJEmLrqlqpVVL9^RTGfx+i!Ke+n zcI(t>nG|v@LN*y%B3H$MV3t!{kZNz{1`t1K3Wq^^L{XaUT6swp_ zHiVI#7lqtzf2s>z%gC)x^P*z-c99fAYNc~!YU`MdBS&a#-3F;8_#Dg)U%j>?Ea4Ij zTn4-!liO8Z%bNhvE`;yW6ro$_uBq)0yR$A&TJCYkgMN)|{s;eHp}wyx9d9Am+FX|X zZzrW~F2fJqzWCLe`r`417`M8nnWMU~h)TF`?eF8SMwa|Uw?rh=5#^*1p;F}}*(&Uh zjS#_&ivZEo`0cR>)HqF--SG_%f5f!L82D|En=2vT?J=-5mBG`gTYhak!%p?OZTk%@5hGoAs&qi>%8KRDIXjo<(c@T-`yPR}e?)h5}z+kB;H zeI$vh&u;}eymL=Q!WLvHh#>Z)%v8LL`qB(tM8PPwjz%Vz9saguhI$K0gQz_fRsJti z?rN33im}W{9z!%{++D3@oQnMB?oBCDvha@T3EWPvLB+pwmO1?2b^?k1Zp9Y7)AmH6 z@*w6WpVS%Q(Q*AjA>V*>^Yjlyp-4SrR12$##jLcGO%`o;3Akfoo zKN4a7B>?jwWxy?eFo%hFeF_WeuIJY`QHso@F8=JGtyMJ%e4-b8TX8owVWBw6;^0vt z$^Bio`EG4brw~KggT_X;k0Vi}n7<1XdLZe8>m(0z%Ow1Ve+cwXT~9DF1lMFKOzgAZ+BS16^3MK>v#NL1gM5&9AUO-0U z86PLXk%#Dn#CH=Mfsz@ACaS)*;1%0_Pcv82r`Pm&|r}9bV1oB6<>ILC?w~LN?sb0O$lV*m`PAV>*ZhE@YTy@}d@Qrs| za*Beso-QBqJ;qcN2+@iUIELYUzGE=Xc(o!YW_QC#2rqK`a%?rlk%-b9w3%icz>9gN zi;xv6tYQRHiZn{3+j@sQHf1t1Fg7{wQIx@AjDa7mwL;4WF-qLAaJQC=r$A_G#Skfz z?3Nr9@QtdbNw_3e>2pP4a-hdc&g5`jF3P!!V8AyYJ`*=>i`@+4rzvmslnMyK;Dc&aLAaw?8B( z(#d7Q4%?o=_M9Vqq5Ee5iIzKgeN35H2&vKixAX0P^Pe*@{)hj3>;Gryyp5xpgnbdA z%V^1Uis(1Z5(0!;3?h_h6b>Ll)y~Hl9We=R=oHHr#x$GD7uzLmYcQGCo}R0GnA?kn z|7k^rdcFBO5%pkv-PwLPzn3Yj{`bM-^rdwszc;Ps+YwYja)xU<$QghB>aymoW?IJK zq+r0%Ff*%w*jSO7046gES4Jg;lp@73#Yt{(O)}70n0t!Z(x0If@-{NV zH?9>DW7b;WfpM&~O8xo>O@m#VjGag2F1+3DXg(D#Wh5ZfOp|2nwicktSgq*;gPyv% zM=L}=0kJ%9N!>PhSyu=FZcyY#!TjPOGhQRYs>u1_tC8GbllzTw9yJP5aM4%%# zL^^$px0s7ihKk-BG|0+zdBy$`^EZ!4AKGFdsW}jFiod$%|He3>Fh5 zD3>mZGmB({3b@mK7P{x*3Tp>Q%Nxf_DRHVX#SWJquhw>~v{VF|eYV3!qp;rES;u5l zX$`b!U!^OWiEbIyWr7*ViSydAD6-s-+*(w-Kl&=Ri%$UQAHi=6y8{f+KEZl(HSkY7 z7b>*(6R;BYeUgsBdVn#^uori{hN`p|KRJ4UkG+73x1D;zaal(PoWY=Cj)$`~x!rEV zHHm~h{ew|Ejt8e{mr!_E9sbTamKG{h=OHi7MURvn_e9eIJeu(~&orPm0#4aR#oW-M zujMZ^A3S?%0bJx<6$4~{(|xZ4Xzmr$mijiBOn`h4jF1&We;SLhCnV0RzWjVF_KJ4p ziJxAJz$%i@%|2|F)z2H9K=lh}1;!1!Q5o{!y`b-?#RDf`!iS88Ct#lXw2VotQ1+!> z3|Waoj`b*q5*)OD|JSP-=D*)h#p96jbx4cl**Zv8@xA!Ou00xP+ zcr?{}-l4>agMIp6FOdYn@ou4vdkq<$e}6h(iC?V{Jz)`~3~v!`LH-q!hjO$+>xUQG zPI0|rbmAkJf~&=4G_FI_KqBSC(io7G?6VnIuGXh6m_FB{V~IlcYgnYAx^a#5d8ssHtKqXI(Z7EjbPeS#3x zH0_Fs$_f6E7v?Ec(z14Trg`|XO=R#n-A9{bkk+#}r`jlVmNr3Tev};qEK`Tp zmE=t^M{U;NgH4LoQ%=2^qjtiyvZ!&~vq4lnE_$AMTot>~7)>AYrzLGP*aT7=W~E=K^hOyOv2sC|`W`qE3SjN{YOOi&7hd+2v2OR!o!z6u^P(E+; z5F)v$h?S%m*<`8dKnPAC4O4dhZcM}=7DO6sQi0DRYpW{4JbX1`Dy~wtk$WJ!W2fH? z*xmA;o{Ez7omge#z2aUij4sqmJCoQ#DNF8u+9{%NG_m10!F)rEo?4|!#-5Hu<0AH5 zBQ<50ZT3R^=>G_XsR%z zLDMx47w`D-=UJ5$MwjTjL=*H-Syg0Oc!sQ;x+_qUd&_1zC`ao z*52+P2YSuRh+kZ=+awhnoER(E#q)zy+PhQPm$6*C@t6?g*HU;t9w6L&rixDp7vTNo zz0E4x)on)FUoSp&+HcpcX-3J_TpjEKK^39`tsWh_Zmv{^7Gy*zw15BA2gS}yj$~0+ zp{3u*REV@`Vsofg2e(1Ck%v%n=6KQcQ8q!z|M#^SxD`TP=W-)%;TsQ}C@9tDaAn^K z|6CgOr^)&lb1H&UGvPl-{T$T)LIla|3X$Hu*~Z`(`{Gt7NH>p==$^%ZUq0UzU^x|` zk%i6_;-Oy>BFb5u?Dwis@a%}O+3gfy6F|)ExRhWOG943OlfUd!<<^o1`sqWQz&hFZ zEx!}4ETC7~v6NkuSS$ay=R8tTI`f=S_R-1DqYauL*MZ(O@SJ_g1&X0kN2YPIqjcom z_`HL=HdC4Xmj;vLe=~Wr{bzvCkgC=HZTP>tbqFsLI)`XU$@Q9e^egh;idE6G#jcX0sEA zws&TZiIVPkUuA}@)>@R_?8rcb1JEdp7#OBPNy`?dW1Myt?L}xjoWELM0s* zSzX3kiKv#wx4p|Vv{am|S%>+2kR%`{^4sJC(D67M!}E$?wt9b0;IPM@o- zuBT32dUVoa%CDzJK87wsa`i+YCv0=%#_)}LY%Zq9#dq+8?av~#d3U>QFk@l4d4>VF&kx6S4|rkNWqW`m#Z7cbkb*)L)dB_aBmp+9+Y zRpS;hIdAY`678N*+2UJ?NYkc@40SBWGf&dOJRppW3|g%wtW6Ftl$3fh@)Uoq1>TSq zbZo2A2Qkc~2l-V{w|~q-Oh4Mv`U*uqf#b@W3W5{|m)3nvKWv+!l`lOh{w%1m7Z0%G zecU)fN3GbJ2ikQnEvyIZa;zGdD^ol{_4wRcDz1!=`fRQ?-vSWCIfjEz4G z#s(j^_msP7ad|pX2>+Nl=O`tlTd^bJ&Sx>uZ;eiP`-dxP6`f0#rMZi2Egm!Y3If(B zBb!@xk~7iFSY@wZ9k+$_=qFNc&dfv*EzM#UA+Q0Yzh@&TAxX&TT3N^n83KTxMH`lk z%Au7^y%6C6zh0*YC%wxfc{QO%;})$FPZ*JKMl(!lE89-fJT;+qS=JUi1YAEg18FKV zu5S~;Bimdk!~maZClZ)0^fE-l<%%hPWk(bx7ygGbrG3~fgmY38&f}VQOwC|W<*-r` zbgbTX+P}Y}*)6kLqC6qm-O0h??^pbZL0wy$m-%=PMTe2b)orAk`}%=)j?72ke&Il4 zO9c!nQ=+WOsN;ly3HPfWqaky48j)16r?eDLi3z=RygsC5%wvh>rerRFoFq6@{n)=; zfHQ~qF@yYAib#Z4J8_iNzX+ggomjn&C{3sr?_hL3!1_z+GAte$h1bu zR!xI&Ml~TBU2%b=Y$CP>;r&K_ezs@T#g-^F)~i;!HbEprbr}^keVm%B$29-ozeyR; zWcwECP=G-*>fy>_`DB&LG4Q0}>@f7MH~S1onpnLfUhtvRq@bWkg0u}*=Qg5M5`j}s) z3`;|_`xW#SqVlI5O{zbz(o-}Ag4v=*Kjv2owLC7$5x@l^gT-PYH#tV(w zWuy^hKzoqMZ8~PDaKi)lzFKb6NOv2q5;2v~mX& zRD#6T)lG3dnhGlUj@Gt7*o!3hLt4*ye>^Nz_zFz_n;ypDcT%!qz{mG((v`uNe5pUJ zggnqtW$O-tYxp7fWaZU!(Ak=o_;N{cGu`7Y^sKXZV>!n%KR%+$k_wxl5f-f zhJN!prS{({*Z<}#XJGwLJc;r@n@u*9|944_iZ-B>82hUSk_8c7kd(n2h-Gc06`T;7 zcTLad<%w}$WMX!_)OLsDVxYXgns~wRgj40)ivdj^hyfGE{cMEX{wfC+`6tq#>j1w} z_a){(b^Yga0VbsStRQ2`hL23eP%=&u=y$Th_{SbY7A~AWP|XcvWPk&&F(FMcM`>F7 z2*33G+y~R*#IxyqHCI41B{q!fbOHkiYsQgV&QdA)z`*s+VpOXTjb7>rXWCDuQO%br z-5-yEG$dZl!h*Q6m)HDrlb=eScXpfKHR6QLW`+D?(C&=A7gi=|CDIKDjP5`iwv0f- zpNNH;95rJ)9ELVsIB!r-R9etLXh3@y|@&Tg6~oY{*G!is;&e;$j>UcAZJC+5vhWk9uHT1ouh$2(jBI~0RaV$HPPEo zr#1iuyTLF7+yDlQC!jIb5nqIP@`E~0W!;wZ3Ls-;ba=xj(GbNw@7W7E%)}5_Q^Fhx z7zZFNlbPzq^_}W;M>${z?KR9JwVj@Sf&JeO~D+DHRI1N#!LJ!iaaa9QbBldnTRdN z3!WCq!{Qy&(VBnd=~ZK4V>Y!*=B{JP!t&kAaX^YuLjX=%Fh>niv1Q#tWvSOOF~to^ zg2G~1LQU27t<>^_Z7t*pJ~~Lkjm$z7~3d6 zt)tOT6En%YV~FuPi+Oa9_}XSVI@tmu7Su#oxj^HK*gcH}6c6XoZq#dV@&S z$}N438n57}m%U4Et9LLbFU_ulq7>=rJ9d8FZ~F>j9pdYXL@V3t`O`*30q7uhi1EXOw?Atam5;_Sau{ebPelfDh5t?U6VN0G@9&GJ%_CyUfyCpD$^VJ-3#W zG^mN|P+z!;?zD~Qy}3leAh8*zmqAxSUKuBo;jNpO9sq1qf}>JCwmP&RsONu#g(S-O z@5_=-(4!t{qqW($DnV9l67{!1==jbbB=E34j>Sv|s&Mp?98aGfq58u6fa9|_@hn`( zV<1J|EAWv+{xP3-yLGAAQrxOwMM+?x!ABg+GFhDWFKyY`=$`Fc+u9V#0v7GF6%!+A zE*_-9mHbPgFN>Kx(Z=r_k0&vs_JV4{RF0N&axd5@2|}eSD0}fX@{z*jH1B%k&L1=@ zdtVN`ynS7Xjw$El5nQ96)a)s~WBx(v7}&K6^elJ=Wd*Pqc0qXmZDNNXdU8`rk$*A^;K ziD;Q)Le1+jjzT-Cj_}Fo$rC70uV$P|JZPDiIG;YS$*u)Ei1GI2*2q9-tP@$gMC6$< zQdh+{a&OFSfflf$=gyVKN_1Nn2vj|8nJ|>^si0%A_MIancnUtjk}5`$Sus8*b8S}x zhLJWV2#b5Y;pap7)^ zPiY)F0wzO*K{q{jVJFv0KP8Mree%6QTC~(opc1J%<4yuJfi*Dz0LCr=;{kmhd!aO6 z;T5DZ)wHzLnJ#9K4VDYOtYk8?LdJ?!BzB4~s&gU_RHb+5`RfoO3F#I%pmz#%g(oQ! zEbu++QUNpv1L2Vr5>h*LGZ24#uejN;L92wXS)nqEc!?rt6NHJJ*%}s!RZ9Kfi%g)S zu`yAi>3KlMS9Jl>xcOUd8}R=*dJcev?UK05%nObG1CC7q<2(O{(ApRoS0N_)%@HUH zT$Fdx87L+SV};4jn2He;_1+)BW+Wo<0zP{f*qUdXCL%Cq5!KL$jTNUxbtq08V%rdg z5_Ug|CuLwA+jadK&h-hubTOj|>U7vB3@R~#?zIP=Vw=@^UWxudY$~J7{WRI?j~W24 zJL`_(Yt5^>>Tu~OYAA!K;cIdHJydg`uoEuxuUk%aCzRQQInc6As3p|umprmkfDr!I zh?{B}Ek?k$fsb_7W#V#!YS9Lr`JIF*&ah>kZgr~Y?xuMfxbg6dm zxDZ{%owyxhDXFj`$_@4aPx?TVqkKXXa!rQTcY|pH99l zJu~XbE6vi`od}{&Oma+gU3*Bmz)euy70k=fBpj6W5SR0L;aWd9dP- zg$?0{pf((d6=Z3{&A@=tQ`i;XVp(g)ipYOOUhcfKzAcA6B z4;j%hjpW?hqI83gg*b5A*Qm^vCi4O71p^+C`8DSavE$(M*nMdpBq6GgI}20|aTGxB zgSEIra5;X>Cc_rcC{S4Q4>mDW#d(j--3w57Xb9gk65nI#D=IzM9)U-u>qjJ0n$IcX zyh#D4OqJFK!Lp@{4#y}N9ss?-LePR+vznU`5_xIu?wl^#BW!jd?)7H6>aT^v&N9gi zIDeTc=z$4&UTGo)tz2|VBh(%$#7hkt3-$Sd2%WzR?oGx-{w9|npmwE;5$T0JU zeXXgkgMX|R-1l$ep{*FfgY?(8co*#T>TG)zI)Zu}nuvMdrF;*xC2licAMI(bhdi*) zpM5!4odBQUvJl;3-y22S{z7twW9H$ICnQCXL6>YWj9S6haTJhzBq_0Pvk#za=-s4` zwmD_0Q!m`{*5fZ+XvSfiUUzUW21}HI1){s_Wl%>-6ycs$d_M7^`b&cTTMzUa}QlKJIhZmCQ+X!mpdZ?@P&zYsys{=;C{e;+c(w zA(sf^gJI9gb$0y3jo@3|M=`|rhr|&D*odFgzF7%x`{-vfh$JN%HU+;07AYPXE`6dJ zDbCYKV@w!6&R*^JsPrVnP~S(%R*Tyc$j`~Q`Vx_A#5<^?>8-}q98Q4xt&K%&7E3-( zHEbI3E3lp@M+&4o|0n0x$` z5wJ0$fQpBujFTh+A9k$&Sj2_x~_l&_sTq)^TswIWg#64 zFU9Rz!OBshpbH)wh{C-)t(|Lv-PAR=>a1aW&$GeC$pV>zV_sRu3q^z1?HAI+PG^w5 ziu1Rhva=Aj#C2nFB(T$?2C+q2ZsA~@pdDo@_lJ%`CKP&Hs}6oB#lKV#GS<a8p*}o{;hz?lR(bA&c-85bv?#L!+A+8AFkdS_0PS25#*`10+ zr)SbG&zX5WGwh#~5#gGUP){Tu9C8}80?B+p-uLzdy$h0FaK2jPk*G=JwsCMz7WjK# z@s?sO%vWZHkEj;Ymg2~Et=7AyhG83)9{V{mcT7`IWY4$*zBOrSK7#aye) zeo2egi8Z5b4VkA(Tf}`RJ$V;sQQ_#FdEJ9+hrgdyU9wFCtf{S?Gj!(6ZbSP8m^F6X zi9>J$)QOl+%KqG6RuFkB#~)j7*esopq9-YPzfe0&&7RMD`Z7KG|3-)9{GXI5OpJ{G zX$@4f`t>LveS7x^;2#N2hVEC$Kl-9rg=@oyG_Kif<;xmgRkJl8irGH{ZN}Wdgd`e< zG^4|YgRu(3nQ++5z_g8x1d?NZjvyxt^w5+!kGZgqO|Y}=#Y2`QWc*dteuzY6*#1mD zmaJLMJYn+MaJgxD`bETw6bUL>XFO-~yk9f0S#ei-_q@5>55U?T676N8in}E<8MH&t zV7f>uy=$pefynS~0>?NXV03yCBPZsdwkA+3j~ZrC7guh4DRiix2xou4=Ctr0h!q|P zUa_M^M5#B>fcLeUlq!dpIPTL6LySQkP`Ws+!I9*WT-TP-d8A``sCHevYjLt^Nn9Lx z|K@^6k)IwDxA8AE0biQ0D_PGYp14AFd>s2^&)S$ee{>6`%T#O@7s9KGH3;<9=$eXf zXfyZk1tOFkxU4RD0Y~?iae;z)=z?{8)Rlpwb@G3IKZ)|5-gNm8fXUi4GGeWfSQMm^ z);zc|Uq5INc~jCLJ2qk~V#YKJT5Xkny8>jyxGv7HEW94X_`OzdSo7Ot@%Y(jyPeo} zpeXV+LZHV7?~}V`m_XM%MFRr;uow1SsM6RaJKUVw7)bi^1*N_@HL;ytxaiJ3W7 zWD+%&bV)s6bN~@&Q)mzEM;rCiKWw13X;Lvzl*Z}Z?vMZ4%tcYrJdeFa)XK<=2uGnf zj1|pp4Rsa4{5_%IhF}80AQDjgVi47WkN%{I@ujfxL2_bykFCuYYVB;YSN+~W@<_pE z7A(3Vau>6?#_wj9_N#MA?CmyxOIQIy-4``W3B~d(u@Mb0pb}l_+%=@zhQlbSY^#Im zfz#HRjeksUj7!G)QHKD|4P!PJD1jKjV{(!h4)X(#(SRcKjU(HyK+)J+KJPiBHaQbw zzz=()D-aAk=0rxlI!v!ZAm9ZX%niNuZ^u+L)tk`_(o9S_6=*n&opM5DL{)dqH93o{ zh>EPZv$bbO{yy%dL|z9gwQygm&zz$XXpS{rW+06p&38*EPDB}TrOlqx6sB3kCeL_7 zjR(57CeQD!<$JdZ+CaGXjPl+RmPr;35OcLiLbkk3jYC0@Ujl%LAcZ=Y!Qn@3)BtCG zxCR8><>7GulOVY>pGqg~&d;_-d~7&)KFwH(7e};?_+A zXR%^m^z*Y$`JxhIZdioDu`Aw0o1_T+69(bT#)heazO*9kWvA_h5oSolsS))iT#6<^ zDHSQ&Yi_rsL~gj14bqt{Eeic3&Y+bVyFBPtG+SA0lvFpP3G(cyT}jsJo8ci z0*En+C?69Dy#8$2)SM}(u?EwP{p`x(mv*yMmP6xJ=+gb-`SnaL9%c0f39tG=x8{;P zKSnTb{}G5n>b#x9Js>5;N0`fqi*M>^dcu-$R*W;j%=b2(65LF?Wuc z70R&_)+_cP>?*@vYS6f!O1UCoOXDnKJ|(ZN)LeMr5f1f9F`tKL)_h^+Pta<4leMRt z_Xtu14Fu8*v|qC32IdsNFG!M6Ttkgc*2)A(SQ(2Q2d&*h)gB|43ei5Pn>i{=c>RGy zEo58<(`WOK*Wt-Grfd@{5^KGpHbJ=5ftnpy}&&081K}(;|JLC zQ54^X_Q|tM)%78CBmV(vGI%7lr`Q_9BerSR-!pz~Ek1X8_DY~5ma=$>X}}XHOpUvJ z=q=HPJ@0tai7*AuAf)9WoQFHSHi8~l07VsIV1e&C2aK<+_R65YcV$c=AIg~Y3gG0L zPuTLU|AoyhZExCeroJu!XBPI@&L1n?_w`oMhiGw z!SDznrsW!#*+2RF?HLp{-T4uix9$w?=B|)qII6-%pZrN55&hr!%aiQWl=t}3X+%Fv z!L=|UyKrc?DqFA9+WASbGMko=xu@uu)v+hitr=fQZYLweGaP?EaR^Qer94BL4{j{F zBu(tobtFNQR`AVJfs#+V!mklx)Ug`7B<4EWG41Iu5Z6m6=ma1#E(OFb`0xfy2_2W> zJH)6bXH8LaC^=!x&{O9yuKbkSRZq>~lfZOPXSVAHNPE8rKdLM6D9_)TGjWcdr0*!R zs#izBPo}E9*_DNN#`xvdJ9G7jp3LR=3<wlMGa44{EOb_H zJ0G;U&1@t{d3DTDL)d?Vw3}hYH%3ThARqJ>tSLxgIGwm%)W}uA7qWRx;Ot5Ow2Ktk zGVoslMrUx?!WZkPujS)?O@yy}e9Yfl*ndW{$&P!ZT2%sv0s?7#H$u#!+SxH^swbDV z(y~;4-hmBXj)5H=N-lW$PC3BZP`5`Jq0eETHK4Fal?PZw)Zt#j%4;U{kfPw<7OUg8 zAMiEF=v=qCxE^cniNtPnX2W|P#60bOcE8OTW(Ah6og|Tq_N6284s)kL0^8XPN z`Mmm<-f2#Nz}sc2+B?pj=!;1#TZ=yZBWd98THedz#L>`YGvXi94%=#lauVs zs~?wk^uD~;W`Mugq^r&xmF)?3P4~k7@fV$c5pkf4p9najRk_Gp zb_|BtgzHqrao=^$<_@(K4t3C&ZXGh^ycOt4UT#chjm^>)rmfPQoD3McJPWu{FiA@F z|NRjf6|i#D+*En$rd1Egk&TM6o#McO6hxbilk!q6$d8qD2W{yADoru2wK->{{kr`I z?Ltv9(V;`HDP~ZEJdbq>($Qs=)5FC+R~8sV=qmI6eiF>&?gL z?{75+;3DJ+SIxhg9`*+~>z{#>N>G7De8ZLEFbFs%Hh9pDRHh=!;%EURLQm?g*AMgU zs12=V3WL}N84TTM@DhqM_NxsqE);|LtFG2G=PKHD?Z5RD7IDCjLd#&H9Q#p9PNUmF;MA%4Ia z4(C2?w>Z`e!bQJsbxzvS(!$I#b$(x4Vfw^Lb3`MVJtALCIy_;(0$TdO()HD2N=2|e zJNt5T;JXf{1C#-_#Q1Udp zVvbAY4rDPryTX}kU?~poeqHb^OjkapkX&}{t@3e>jyg*p-|g)wFn-$9xb|O%V>pEL z;lmjv5?l(SN%!KAF+qu+t}5ruj8&R;%L7gk#wY17JZaTMSc^NYgo<-Q;Z}u2gbTM; z#xztAjZ=Pu!O9oC18r&0+x_%hYaJC6R!&h)3mGKRA@kD9ANT;dA@Y(*0aq_t#v&Qg z3vSKd0?KO%9Dq}8TmdiAGGC-k!ptX!?Tqf`-guk}%RH>&X;@If2&3~R^~bj{wRdq8 zptOd~x`8@m83DU^C3WZetjl4wvIj%eUlh)s3k`6MvC7n0%DKMb2@bS+udyK&;@yy+ ztd&}F1>iUz3{ZPn*yKGVzX|zhV+kLHQRbcCY4~8Q8(E6gj(ryKJ zb#H`HA_wGZgLhj;tFz7hlSgo?pUTnpLkfT2E^}-B-z;u*(U?jlt%hKXYe!)GdL~7fa<=?2) zkLk6pR!>vNd(yjGFa57~>T4ml^OnX)1H&pn@$joSOi+%80 z!SpeR@c6VQb>86-U9wd(RFZ)v+1F623;;Y9X`-1d2$`E>viORGlHh?lC8>(l=e^OL z-AF2>SUa{iKmTM476Ble9fV3k!^5tgl)z57Z*qQnov&u2(Qe&zmV4MPtJBKN7>G7TA+AAk@R2Wi2b;2LsP*;L3Ypnn%OWBpzk1JYvYY z6+Em6S5q2U#H?c5g++;72SX7n56Dd`cgW0q-KB(0Y}^tiNK)SL>E}iAqVxOv1mI`x zWF5WmsIr+`;q03UmWCsp_Vw@G5%9d%R*By9@FZ%R5+2q-xZuiLyK=xo)iX2PipRuA zUr6$O{c*$r88ShW{yxA}0wL?wf<_gIzwQCqBoh)TTp+Pz=`whnuR__Lt&#kF;0WQW zBDYzg_Jz(Gyq+)kBDJK8|Nj+%h2eiv1u!xGr=D#}P0i-8714X$)?r9O^w|t- zjD`%8#@OJ55)P(4qq(V|Kvez%;(4SbT=?A7V&s`F7KDueZ>U^9PU#8t?>p8Vg&!}T z5zu#nsfy?gef|y4A)<<8IZJ!1-x;lpD&W-@uR&k^RI)?fzDy3gM%vly`lFG|l-BR| z+hr5h$U%Zw%Of!Qiv6ek)#5P)T7TMTkdwOcc~hx>p2*f@^KRwNqhUh~&!-I(Z)%(I z^*SJ2HmR^TNwYyfSR*fOdh0wwitfOcZKcNF`Q8OOtiL860dI`IEt?45!;i@I*_*y-4|osMnWwr$(CZM$RJ_CL1mbduBW zx%le5Up*I3)vkTFuU74~=9+Vi-*_-7yPX0k9?aJ{tYBSSP7FYC{o72ICRya&u(A)0 zHB-yHiAT#emiW#-aJiLr?JQtyYK@jsPdb~vuwu}d{o0#z$%-RY4pwqBXEHUU&f6re zH^GbrPqF3Lqw!Ls0Hevl6I*Nb>i4qRs&w?;0hfO%`pEKl`vQ5)wYWAM=GAZK)ZG}I z`=0f?VI2N)Tg|e+ePy9C4pqhw@b?IbEwKUg6N5>Jd!5BPD9l59fya7wBUoP^{a$e# zzyY#lQ^qdi>eV0dKVem4Lj#sC+)sb++<5J|to_G`^7?d%Ap*ot<0yo%I);=cL!;RY z+7WGsF>TZM;N(by_PjCH^Q_5-F?ssoQ%@W{g=wiOB7Nw~*o4*jxP*Yewc;Ex_yR|# zC3}j-ny@X}pSRp?U2C%aI60zN#{ipb<30`E1mY;OEgBF?)6!+6Tro5ol&V5ty)i?H zWX6J0jww$G%6>2mKL1nPpxl-#kM7N# z(e$uUhG4jltCnVqGLIlw+xN4FvrV^OD4I3xls0sXCdIO!q97x4>3F_L-CnK9rSB>R zgF9X88|*@aI`zm&kT;G|3M&NHtO{4hRBA3@?u4JT^P3L|^d2lH1lt&uZOkTC1a*>b zCI$+{xIlpl7b*{2F0c#E0oVJ9FvpWJoIA@AGB(ydpMP-+BrQ+G3fjTtX%%qc0A6rW zWld0rC||>24=kVw_Ll`@#q>^{%g_ob3B)+UZr2F+sU06a$y?@xI0&f0^p}G_!k&C^ zX&};O2R;N`VHD?qQ#GO^lB7+ z8#nD$8DUcIVI|3o25*VuTi9^}B(}p?SnU0}PCa!WB8Wy~J0)`3`36ze*B9D^m))5R zQ)&5f*oI+Rql0)IpMxj4>pN)J$Ex`jD#I7gMn+ZBXDTTTN}4l+*_!Pg;s-a+C>p8) zBfb-?_kceqs(sD)mKdotM@33I-~^@$BbOaRro0^@?zgkGpUpkFB;~zN2}VTHeKk?O z%O7qo%;xxGfnroiLkrpxo$^|!BEtq$WZaf8)UAA4Xbhk%muDc~93PZ{^s;MbisC|&K( zjK0fh0rxQ9=FLc=t;^1JoP^4q;7PLHaPP30z&BE!w7^4 zPw09V`QSnzWu(g7(_53S5n8U{YrpO^jP!2rf38X-)GT4l8Mdv^I*#P4{A=5!FjZUNDy5;qRA0fk>hT@F&unkQ9ww1x-4U90;PGk#-K@&EQ!MjYw6RF3vdg5lum*W zOi|RemDNH7oCc!Ss*9aHqh{b@S+OAyXj=l2mDhCO#CIiu&2{<`4hQR?GAtq{c1QDA z-4!Ip-anvORhkAG);ukT?uCDj!)ENbYUJJFuut>U-(=$tKv|TZLZT<(*Ezxuu!D0m z(toN}{wr}2({I-Q1^QX}|3E)byc43+5hWGkujnmQT416n6ef zm-w&Qn&O(w7H))*@DKSf>G!y>!yWGp{MV5I{f@xneaE};KCka+@i3=U$}<~p`k$0) zaU6i!_Zc)IQ@5G}d%UX}zCw_#-%Y^&@4E@s`yFp;Q%MW-;l#FA;)$enU$vb-uVw@N zisRVlF8snj@adGpLUO4HEdj9|?^VT_m4HCONmwzpUttkAFlF zVg|cyzI@0)fB33zpWH%?iM*JvtZATV!e=>N{+eDDP7;ceSeuJdmKhlze>B?t(%tA_ z9B)1+#%K8@NHYSW^)R0@VpUsVz`nNvkJ%?!tj*$Nk*%HebMwsNMRl2{x08pEVOm`+ zYCgdzpOG|rhtN3%c$iO@wLKoH%#SMFSMhPKCnAWv1DKsnX#svy42b6Jr-|M_8r1lA z-loMwCWKDb4SPjoTr6Y;k#5~ibUr;6+PcPq@XoA1WK5W~9igcQl@40@cNyq4YHXgn z`pYZEaRcqN8I<5X_*t-Q7Fc6}#~6E&4#9_;>QEh<+h%U7wM3WPvA9Tw`MGP<4jAU9 z0|LT33l_BD4iZVJcrbZPY+KiQ>@Ywjk@Uf`Ad|xO&YUX_KmBESIG}TYkqr*&{?4H)te_|IpE7$VP-`dEAs8G%q z+$x5L-72o|hYihfcEtgt$t&QoI35G(i+rD>e7R}+0RZCr!qt<{RhuNUif9@RT3odo zIkh{Kt^lT0K3h-`RHAb3CJTu5=*wa)U7q5t=T}qlOdJG+?sT`d3wL43u8zUrw2WYg zN5p<1H*gFYF*e)u=+5WtPOlaSYwgLJC03BrbeU~#bJ}%Wrt6j#ArOZMO;7#rU|&;r ztf6cxgv1mYh>HS%N008g(UQb?_xX4%c5dxiWr*O^Xi)E zzR)uxKHXlj@{5i0lewG)coU}!zY-zdboTIk9gVMMB*)f{P>2)d@1axoil7S}^yo1o zjLUMaGA`p}o=j+-+O*SO?JdnNUv1xkD#!9-L5;~2aA^XATeIFet+lc)bANI}?;E>t zIK&nW6D)^~r!7lg(a#xs1om8ZmO3(yPtAF>3!BC`V&r_sfScv_&R?**%~VCJoA!k@ zQ#C&&4g*dLjVZ)Xm4GAlBgg&aacPD!FmbEKpV!QeZi^FDd{K@&hrA_O`dg z+7TkPe3#o#&??oAvXfFr@Qi%fM`iSrA2$-eZPM4x6-E%2*vP+tVJtCM$&R3dG4JPy z;yYt_i0-~kocx=1F%ry;C}{9c#zARWbI;`Z)7mS%Q?Om*$BX#_c`SH9oU~5EB0+?F z$v+Y%7z7CR7-JZ=z4}Y#3+LY9&DBlax7B+NMDCN-aogQTQ6#W+^@B=6LKi?t3nSs; z-BU8G_TC#;B8nt`8*Hk84(qD!uMi^6KF@Arfn+L%v%iQ?%X}S4=!q4?atF%mNd@qV z+>9DVHH+Ybq0n2BFwE!L5y17(M*x%!9C9GXAo2PzHGk}Y_8d({2~lqQ4v*5cag~ZEbzC z;~L%h6tTRe?Q|};2&k`7bG5i_qsse;NHc<5QIUJ6mLq%LPwcTul;{4#dBXHxxw+Wc z|Cb~_ROMg%Gb5but~!)=CeLz}sdQR5?;maMn)OoIpdMP`eNwrDfwoP#Y>>~l$f7G! zjX)w`i^On@#BgGSkmUZq9EyeSkS3Z*Q&^mR=pm5*Y^}`NDD;}d5eQKk(`x+ZqNneL zO01#_X4`dV``Sx>*@evY4}9{l%YGfA$HdnUzf=J(PzOg`-a=D6dq(-S3ZG|^f=g`j z7@}r@jn4BeOhQYYmrlmcjntNmEI_iZ=Q z0fiJU>v;C8ab~fJyzbFw`}EGXw~Lq6W|)6_al7g9uZ$onvXn6a^_%WA&1U!2Q~&j| zh#Yg5S(=g7QtR%kXF7XYVzsnD%G3h%S2C4>R3S?8xWTxKTP9JB@UXa)IovQa##gtk zLU<<|LE2Na+4R??N!x@)A)Tn&!GN2@;x3j98mhc!A8&|b7ZUak?zNbf&Bf}TlnyM4 zgNE=pa8;=J1K*Il1O;4)K(EH1xU+VFw>ufWj(@Z86FYp8G)fz<7-3{+l(!cVNPCAZ zTn_|5Iv8VKl0&TqM_#-qLnKzoBAeGZSdD>EMnVpRxQ)#8--C4{V{&-YL!b%vz>`dC zb2=Na)2FDy;cTmROPM)=@-v_B4jUOjGYoByZ!j_bUPHfSRK9Mc9wK8i=s(oHg@+{sX7u@fJv3T&CPAG`8?drZn&0?$n z^f&!iy(AV!rvEivxW>`_CvkZA@(U&S)1E=$CsCsGv=5>ah)chQzR?EoRixWX z=|AXW6{b9lH9LlqR=J^LA|u6p`rPU8Z^%myrVNrmBEr2V6*H7N9B|>`l*^pju4oDi zS`y<#{h}@;K4KQEPyA6@RWE{lP4hu(XOu@jStL{t2eJNPr_Fjy>|T6>tx?LjP^58_ z71YnA)2^bZZO^BL3ieT-Ux5?W4L}8?XL%=+M$LTGpZ=lKU zr2e_Q3J_IDB%x?nal|{*RI*8Wd zALD0xv{Y21o6$y6w4^$>dFwQhHa_i&VZn=AwenVBCkVGund{lg+jq*w^5}5 zLn{*=N^u!B)+Cu7HR#rY-lqYGeghAnKuasLufgACv-Q;)#!p^5{PKC?GNaBlkbhEH zgjOFc_QB}S7=feyb+`hX)cMt^vxi=H?ws4jA^;^IrT%QDOagdqkp>C@d0ZsgYYaE6 z3qeyO%0xn+t1l!OV?G>z<70(glX-S|0rYeJT3UzqVd*zWTXft5hKsV~#38gRLPQ@4 zagyMB{xT9sGGZW}pdIc5m4J(Wwg~_VsV)E|${ zki4Pvg=Uw|QY!qHV^uBOSfalcoJr$zVikWx9RMt_oXn)2V`LYx*nyZ+Xmvn~5-)mP zy+;r8hzUu8_l~`a0%MrN7j23=Sp4;M$TJR*`EhgsZxHcEmmX#xN-{6{S9%N$3~g#7 z`B$avikC*zmnaSAQy)i=$yX{ZM$=06`lb?p8&I2G2s_kH7~`hEFtU^3BZTIm{>U2( zR9B{y2KjKf<{3_ChD|UmTLFh5;Q3U)DiId@wT24*f^K>VkLSjU*bxQBl?w>FcdEAk(Sm;^C9NHvQpXlwUz}1p1175h{ zL@rUJCzY0U<&6mVD-rpsG(SCsIDC8?5&1ylmm5TICk&8PU4IiCDHP&T%l{Hqs{k9B z_~Q5;B3Ve^z|VjcBYj|coktJMC>x)z;hPh!7tcLlo-O$( z>fbWSs+>Dh`v-6&3I3w2a`o(W-h#y;=|`7lj0Jd34}h2MmTd^9`xH-ST_rnA z&TUIhUNhcl3Aor7v2(_Cm)BL@P!6$TFdK?})JeC^GL4L|q%R;frUQn|vfV<|(%niB zrWfwBt9Khx*wi5t-pgt$vztV|b25;fn(J{{edFG#z{Y+X97swqi+n_~gT-);$Zn+4 zf1!PzGTbher!cofE|DDWjO7>;9DEC5zB>-T{F6Qd|-sjJuz$)c_M70Z{MG2=V4AoBfkz& ziW~G)r_nuMuN{{a@MZZoH)|RkA`go_b84flFk&Aa_%@zR5+T5SZN{h*g}`l#)(@^o?nKWMu zY;8Wq$K7Simm@6(_`5WqW3;UCHUZhMp+*Kq_$il6+vRyL8jbebYgU9>yHguf$|qU)j~>Le zaPIz<&=}k6D7<<(-qx|MeR;RDeJQC<+%T+FIV8sj$nCEF7FqvRM>{xBRD%%z;T;mVR?1=zq}ua!%;Lpp>$2^MpbOWVV!NuLf{B-FER3dZvDnSB6} zjgvB5%qX`(pgVz_Ec;;^hF@)?uF`)e}Gml(NX{}sX7lg|B~rb=26Ukc1F z8PRN8gLzkQHT%_5keJ+aurNbBvVaeP-|*QO*RIDT3{NIz%QlYu=~K=dqcO5tcRp5^ z)1E+BMJr2#x(01n*v!@S)#;Lt@}4?xefQ$$9jTr{fS%W2hkX<=W>A`s3|Ke;L?$fM zZz~c8032Ihpb{QcKE8!11~jrY_`&YYT1mpytFIbSr0bVvEcWZ8U^o zEikOFMAyOSh(rq+uC%w}I==O*6W)T&=tk*0;~8m^m<@L6LYTIOy(G>JJu!?z0!rX{m62Hs1bH0;ck1PgVjBT(M$g;ruxL**pngQWxxfQJ0ukC>?emtFDWy*g9=LtT!r(^+7fU=Api| zmFRIt5PYXiL=;|-7wQIjMDpMi-ty16a9@RX1Iy{08g~a64amnSaZ_be;~Z*LW>#nW3ooZTm2{`>H6Md;Htc$aE=r0Vv zZoBd$zx!j0$i5s8SZ$j-)_gM`pB(W-<8Gwjr}w0;jym^in;`Jl_y*r9Nyfr^;Is^o z40Lux7on4aQ2(NA0@S?Vv98h8CP9h2S z-sTx!F?9}+=Hv!tKF&5!OQ{fC#gMT!4r}t{FfS1-6^~rX?7f2AKJws`%GF(4D^Y8Xuz(31{G$ z229JBI+T~Lsn!yoHhtK7$RHWUkc(t$06K(k3OOoh^Kaob!Lnl&&c*FgkW=;bvtEGI z9BDg_u~OTq!Oz13ahy`9appaTn?7Y5>@9<0?pAkuyAOfeb^5^SAA<#OUDWN@{QE@8 zMlw4U1t@p3`EDmcH@Jovj4PtHXmx^i3y%gVojcKGikX~FBI?)Oli{vF_Az2~+WF*k z=P)E(E*W2NXYz}ZE0&q~;Og7us)m58F#Ag0!3jBVA#AsVUU|7#s8A`26gad3Sjq_7 zyLu{MU68vZTb|&iZpmeM9bOA*W=KZ)mmU{QEIFv20&Gg8K!D>ipfH~b$YaJlBL$-@ zLRUsS|HRBx*febGsH^&WEhIVjOA%|;O+D=7aDQB3?wy(rHD2P$a}pN+AlQcg1s9A! zva1QpW8cK{e{AK832t>H=)d_by1DCkVtfXIq-Yj`<&B4{O^A@*-6?WP!*&`9`z*N0 zae&W8HK@pkWWaKV8#%)820MtLtIY(~4o!*)Rf-v791;1WQ{G!#o#+As^m1eXT|jei z9%bMdy4MdE670R&sFCczDy{!&QX+^hO&(=S9wm6Ooq=HNzR-rcm0D5iTnNbbR>SP5 ze5Rdlmg1E6mJku(9qp&hx|ikA87 zYHrZV5KK=+6Lv%nXA3;-NSsrG?XV(rEl~p5vp`3ahlgi2Ixk!b=dHJI_OS?WRSU*Z1h{M%<2=qC=aJN)EYBM! zPQ&38D~TQcd_1Ebj=ydkN~-UPwnmxDg9eCf-zKSkBp;ImEZ6}SD18%XI`Us#ppM*4F0x;pXiPU3hC|^{XyN=)DWB$$(BNZ|(&h|Co-=H`~aZK{#n9fKL2Yuj=4$ zK!gs|BLRfU>Jvr;cTt0?S?z9jr(6V|5mBsU>C=!Q|SxVpipQXX9~y2pwLwToE#g)$?xwiO%st^|;j z5o=axB}m}B2U1|3{5IRE{Y{gDtdoy}lKNX~-Q55{oHhngjLSeTzmt@f8055AXPqsE zzF~&f*wAOdQWae)oxg|KAycGD=swDo$gs0*e-dWr#hfCo8+gC)29zx^->&cP%i+xH ztvx-sB+ZF^Y|D}#xhsy!Oz;harV&lp?+Au1<-WsE@73ZE2Axa;GV^=*b%a-^u@3c* zOpnEbHyye`devwq)#%fWREDyC$$ESssLG}{<+>n^h)d&GCe5>Jk6_r%4(;&$)rCVA zFsp4tU2@3qQ2Ae)>|&{le3*mY?-2MfHFC zd;ay)j5<}dDHHGiR2IH?q&~zLl6Z|pK^W#Sf_54W`OA+kI5-bK#@jXJ^Y1lR<85aJt})K z7VDRpBnwDiA|03Cp!xQGy*)vo$9T>_vfDWdjn+H|Kn3Q%6h5iBR(hK>VIZQ1S^3Mo zH=c546`X*_P%_p&-i6XNR_AvMmu=nygJ&J28&C1b^1!(lo0Ak>n!wcIc#c}YK>;C# zZZddwyL(xKM|iy-$dW*Qvaz+`mcRjxPHHX-<;ms?|$FqzXE=?e}GB~MWMSqL|pxs0l5!8mEhb^t3gWbD)Q-W z*cHSHMQoIx^-2TNS(pK3Q8kX>q~1j^yMKDD3Vt-MkB<4y<>TsG|DQwaoBALF%d9}# ztbtNXkmp6#;JZauP~)ui3b{q*G+^0Q8jEqEP9hh5cj2jbzO9{}&+{qv7~#_|JpVb} zPlZbq_o_02hcZOu6Buk+Yl~`>4WbqVi^_&1Z(r^B1C4n=vY`>TQx#}D{2HXS#>mcw z?q%m-bE=a-&~ZNFJwn@$M=Vf(R3rjprzX&RBNz}VEf6L-aKHN2KUv0e;C!cF%Iw-0 zJi=eRy7)i!^2#ew6AbnKuHO94#^gTSYR?VT385Aeo`wP6ij>fU>-=9#CGxjp;*#)7ifYujP6&7q%?AE|9ib%ADN=6FM|)rm{lH zK&FTbmSA%*R(2kRgS;E0lA4+AYL}hc!N9<3q9Uzw!6#xfmZzWIR4o`<;ti_JoI?xs{R^xJ!^Wtc2@wFU} z@b?}dRXQ8!!GV{GCSu$skkl10?0siEQY|*EMroN4Ezpf?!jgn;J$Ks^ z{UgK=Qs=+6RRk3c-!8sZl=0Tt9zx7Io7g{=d?Qe0#)8ruE(N=iM=Bxvl~b(2*jfoi zI=eWQiU>t7cMeFt12M{Mj<3!ZfSC_2RIBmjLD|du1-I-27E`#w`}o300uZjY%-#k) z>)NB&R#rbIOv48@PJf&1Aftqp{VO;)!L5MCAy9{Q_ zg8>l2(dHmaaOg*&h~ESlyCFsz2E}|A*Vucya1~o{bA&#xvXN>3ru&@syEfbz=#-Xl zZ@ltwGZWK=CC+?_vmc`nGult&V1ELz;7x_MLZHY>BK;UL(>0+GT zGC@+m(?YD6&5#zR@7w+Hb#x4vIzRZ*&lJn3h1Shm&*!x_^pXfGBs61`s)ZedJAvQw z;xb~3q!XN*7Mq)v@~l|nd$g|;VZkuV5p=o&5u7MhL<89hY50M5beHG0lTEM(q#39H`Plxx7Id=T)7`wjyo zinl=dfR;l-2^uS#$c<u_2hWT3-?($bZbP&UlBiL5t9(c`Uro-U8O<-ZBfrXg@ zN3$c#?3EUX^ih%MC2Ef~r%_M|M{ZjO4CeX2T;C0~{QMG8EUx9C6!YRFh>1)OhC=Gi zB~M(L2Q{^RKman71V{yTx(pi}6%B~OiLQC`TMV$T1*A}l3@T<=UON_RT|@jWDE}T#(H+)n!oZwp-y0nX$Qw6P+?-F(e*k=luC=WZ zBRs}m`!mj?Wy?@%@S&X?&>C(6FF~!FaqEFz^486oQ?UGOAf~MOj|CHb-JvOkrf5$k+`4MSf8P9sZG*xrAw5skf~Z~5Yo6h=t(;uNNrf8-A_4zFdzuP z=0Mh7ve$1*DQIMc%BS1KCnq%rCVoZ&eX_*W8G=)j{8?k2A+Wq#6~DEO3+zn8c{&@j@NKrw-1}}?)DFR<&CA1e?-4xbd1M85l9zm)9$s+IV)AyWu zMp=_*?}8dmB)9REeSCI1^;T$ZL+BGyge~`(%0E3d&opGwlj-g5b}+t8G40r`)0mT! z%bq!f{z8w7URr)PrK5rMWoL!PaA-A4YA`29^&bi!j>x5png%uL_Hiz;VhpoFbQDE| zR8C=xUGuz4&B_$Os$og2V?x3qr@x|%5vtkkKe$wM#t?LFG`JSU89T+Wy}HISzDo;w z3{2k#E&M84eiGGFrhQ5Y@tfm$5e!zy#iuV=QjeeU`-C^wyab5^VP{(t?eSM6Y-iB? zW8M!Zj~3Wq-Y>(S=Mi=gZqCbhpfRTJ8UMH(QmU%!2p_*h8~4uBj-a30!#7)YFbYFN ztr>!t>cu8us-_c!CD+_YChsTEf6fHwTjh1aFhapF>`?KH{|aFLyLCV1m3r6_$uJ1A z>lw&%3&yg&wIzO*Uxk8Nvrp^$Q_*a$x_t_T&e(K)|!GY5AUC%K?4;2 zZOVmm*K#5lp_8B?4Q$&kMw+RM(nV88<&t27`YvDKL1mi_U**r=f3B@C=vDGpmt4nL;;9*pihEV^o9G6q;l)6 zxj(HRgpdsqIg%79zhrZ%>6E!(QfcpciclT1hGNg2?xP{PIiG1($;k;P-G)-{`tr3_ zpO&jk-=$^`9ZrwlLeg5>OdNplqHd)tP~M!v^F>q7{xi%^=>w8OmyAZlHbg)a2lJ<{6!Fnz$F#%3~M@}|L5+yi&dqK?!{m%jBNap?RAA6{x z>9T}Xi=bOPIH(}T>_?W`O-zc?_9zq!I~j?WL$J@y1pHB|NbzvPzROU@R6<+{&HxV6yzqfSO_T}XsKx_9Gl zx;m(vt`G0Mmq#?$Tpn%Ccn(cEko96~8^mz^q_u9i%uxV0aM6gxVYe;$eiq!iRXslFQRuWH$NijuQ(ZuMf#0LL?Z-<`=G6|%=J2*jc!UshA87j#y}h#R#J z_4CYFFDai*ufbjui1sBz8$1Xck9wZ@KPxK8t;>t%2PH9^Q)~larI-Q%p!t%Cg)TL9 zmt}qX0MlD)WUylrEGH%yha93DZy?+dSW)%106k+i{|Qa76gqb+I>V2FlqD-ev%&bGqQHqEvYo#Yt;! z5dV7W#uTehOyMc!kMEvJl*YxnrrMUtd{WKQt6I=yTg)d;0H1Fm*PU;tx|wO0>iQM{ zo=z%qJ#W1T#d@Qr144{?8|a$Kzndq`cF_$dertFrzEWyr^!&Wy)lL z0%^DXI$j3DIBJmR`iQHD$@8(J+Jrk*%$p!T<%_X<;pBNiAhcUh*}U(M6|bXK{E7RH z=L&QW`RJ)1iCFP6;7jU&uT7Wj&7;w(8l3NOnNtGm!gAVc?S))??ge2pt|o8|T2p+! zoY|k2%8B6sZ&(2iCEi*ALuOu%oh3Ju1bb>z^td#1A`Uaha3;=JIp?-we>}YK&)R|BQfjcP&!7Jk9inFK zecc)Punr(^5w;oArr!AbGb8GtzTbTycqLuAdkNo7CN(F!oSV869d+Y2yHw@}Jr@wq z;9^30{b<*W2UuIc-2wd#x#L8dV3Hl8jwVm3*t4p7CfwLLx@3^0Z zHR1_6k8HW(2bRmllmO7$CL49JN=7XASoKrlbzAf4?AshOYAOPAWe_F8+5_7f2W}ry zDzGezub?bzR&t5=7{j_FPP^3|DX1l7n#Mdyy`Lxc$ep5p|I_*K-zC_xu>UVQ%u2@p z#mbNE-YTD!#;nx56_nqsM9~X}*H|iIU^c)78!a?4YdXezPKB2~`{8DD5uPUO6<_2V0SH4nSCqH<4b&rK4wwvw*uiEM5vcxqD= z+#>lzrCI3!x?0A}NnjMwBD-5&QOyLp8O)Ze(w22rt=Izyfr90rNwYei=t7&n%Zk2<4(U`gu z2<1(G5+8*+ZvZUD$M9s`tS`QF)fnl=MlL8X*&`@fSjHzl@(z`}!2}(}gC(Osxd{T? zqo2#D^!9?Mi+w5t9rG8X$|?kS#eB!k8OS9g3XGCcT?IiPIJs);#>oc)x2n)q2(?v5 zpwQmPa^hvB=+O&p_Fcke9?OW{R$sB1Cs#cprxbt zW~%AGGnbbn?4JEt2#|3P0*wLr&n@hiI$!sI{81lxtoUCOa0XYrz+LoAr}8Z0ffJ<> z+dKdh^5nciNhvwj%qVURk6qvSDQrzR9a&#B*+!8Wkk*u>8vt4+!0&H^{@LdJrk~2@ z`LLC#=unb_q4FuJdmw3*c3Oy^TES;*p3(1>DLgAP$Dg2vW;@9gt%p$~I3D{Z;!0On zi;85tYk8dg+RsX>R3@5;r`fEQ%_nPjg4T4=ZwiU{F7j z%jA-_I5(*L7Z(dN-7n-tep^K=o4U}e2xQW%w-PX;5y}%I0%y4lSjTw=j((r{_?lmg z7<4C}a!4n4PWaBIAk$Gl6epUBD2IseMBENZqy6nbAw0lmZ&6emspaEX8ql3k{he|; zV8bH`eZFlRW;$Xgw$R2s}CstvqNy{ZjKC9hq?r>#?W0@Z@ikE(<|l<-oQBI9PlFXv9!5@U^S!(4H)ScowJz0!)671 zr{Kf~COZ*AgC?E!1wA9BQ57T2O(ti*pY#)_%F(i?DY1-#!Zv)C+xc* zax@>>lFuB;BW5MaUcz&S znh-&Crpj|r7Rk6>9bMnLiqC`WQGVi>f zB1@OVjH$l&^U@2xT-(m&cJAGn4#x6@Sc0loV;4LzT*>AO0*}E>+^mwT9|Pn}f&~!i zqzCOK1pP1gm?UER|Fl8>SDjiWR%Yh^cb;9VuIc=b>GzMEu~&jnx(GGsOKNMLb&}B% zS34~Aso<)k6+~NxTA7e?UAFYI0}dRe$8eFgfNdcyS4`@6_=UthNFpy?j3 z`-gJ%S+YF@Z*p7@3`EbZC48%_tp$s@U2MDj}G{;Ci(6TI$@>KRQYnNn^R{5 zC`m|5vnkOm_Kja>Myd?zf9%=KtH-975~?qocU%Xd{aFhu49Dy5c!$ND%_B}ipu_tB z`>d5HyALUK&*m6dyM!Tb*W6Fod0xIM-5;sdy2~Ta;@p)>+BgokOnY0! zp+qPTv{5+H(cist5UYGx7#_aOwb57V#4IDAsjo{Yw~tRrZ?OB?)1*_k3;tHhRB>up z-lj1u&F%A87#Gtok@jhtN}hjCmDIE;sbe+s58W#xP}cF+fg6l9@RC*KwL&!L5xVDl4a$eh|CP}oeX!JG|tJOs^|<^ zrr=-#!2pKfk9m}UgN`7QKs$)fHO@hHyfKpCiAX*$&Iz&_BuhL1D;Jb<+A~2oBvrxP zAKsHLeEu;8MDL%?00`#(61jLfz8F589BfHt_#Q}(RAHdI#&83I&yXJ(Xa zc83&x)!rJmU+{}YVBu|Zt|Xw;!Dxzz2xs=(m@k+<(JzA$2YG?-h}1b1?(st|M)=%w zJ!ovKAcznf0!b5w%X)-&N`=_4oANB}TMOufF0T!NEH1qva`$bUUF8>Py# zt6J(4bp$$V3#Z-yZtgcN0?iv}XrumSdVlo;M(Xk@aljFSx0&(r@teKgT^Iv?DD7E` zin_5(rUGgFH?i%lU*THiUwXCJqy=Hzxw}U{91K03C(%D{s(*mG$)5g0BnIohjx%qHWI(jO1X?a^e3l_6}X5MN5=!+IHqi z+qP}nwr$(CZQHhOTPJPSsn@Fe#%Qjl>)IHXIomOlhwTUO>V)jsP z^_pMv1J^|fRgLh8REfKEvPX$u`8PXuc}Vj84mOPgZ%mzK`AWnSoA!W|3u_yLt8#HV zI1Vw_=RcoD(xxKVDh@RCkfh&4tYDz|?>?QhWCQ2Zo4$P5JAHqA{tcraH)3oqPHfnn z2hfygaoPm*9uA4i!yUU1#BYPwujKR8_(^(RTx^$VZgpYkVG8AQ1EgoRZDsF&F9gMJ z3dG&OVt`kiTs8wdx+B}n*f^o64lR|8Q<1lx2L#T4c%~CbQ;xhF(uQziE@iGaldA69 z?NL+P52Ix=bXHP&m-GQig^x>+Xa1r%4byx}X9 z+2oFPTemRL&lFHM5>}Xt_S_<#NCeNtMYTfJQsW}8@;W$$cVziSnN;Ky#!-LRiif zPsHH&2l#pt>R!YWh zRVqIyRi+QY0(lu@Dk{^9ct%OA&r(YAau_wxT}hEc z6@*Bk?hnFg#5AMW*hMVr+LfrGQI&$iR$Rub;8(pEb39LeC_+IYF@{jYs+6@+7JD_a zKTRlJ&ls21LolG0PRYkn2NMzhUAMFoT|mYJO|e`Qwmeq}e!K}TByHSkt*lo|{uCxr z)gFQ_sxrkajBMpenWUnWi((AUD20I*;1uRq1ZoorVM{CLrGfhQLPi;9HA)5Ii`+8l z4`EDR8cKvS=^<$U(44V9lpSe(!)rtsskjOO5vPJyJ3EATx#tT@JvcFYy`zt=kb2RYoYb>{Fio@>3`EB*qQ$0Fd+tGEOtxuDYtGv0V>tV(R4jN z2?yP}-t}6Y*917IRFsO8nsExPA1_bMl(^EE$lXBJ%ba>rw!y|BKeE!zXN#%Rk!Gr53sf^evb)pZ9cCxtgv>K zseMgrB6=}dqtPl7(Y@|jp5i3a3D)`-lj_413*TSMu3H6I*~-(GUoy#&uXasx} zn)s+qjJ-%FTAGAr-uI7VRJzGJT+{wxrQ4d}HVbTRQF^oY=8&Qp;i!n-HldAmtwt*? zXu5OnQ6jZx`%|!$(j~roGDa&{pQrrg#3=f4@%wIu*#dBiQsCf{gw3G7jDF021xtU_ zqgTEKO?yc+S+wZqerm1WyR{zOjBgm}jaN`wMndM{!%LuBvkdFo!31B%>GhXn+8_W- zMWVqHB7+Cx`163k`UZwp2=ut$`^?}VetA=CRX zbf)lljzZ!aL>?F7O9@xfVE+MSaI^U~j`+(Bq(fiw&qn{GGlLK>1BEc~6to484OK5X zGp8O}j`dlAUG_u0gzrYJ%*-}S>y+bIYm_k2^IO=er4NDuPS?&Erbk97p)H8nx2oa< zRx?R0yihw!5OAItd%gaJjzp7OL_B-CL5*m@*!F}6w!8>u79U_XDL)?GF9;-#1D zlB^i9sL)EM;I1wJO1`;xhkDGa>rEubTxwEoKqpxv-Ob3H*4650*tS;9D0xNgcjsXNeV^&g)KVt^t z0g^Xj_UpCF+E4vR9{$~0cXm#91Fvn%CcZ@nP+wlT9ILg@s{r;M*x(?#k<{J&7!$7MWjm&wk7=PQ4|~yZd)n>TjPP``E%SaY$yDXLHwDN>W|p3_5}N_Kc%{SB z)kBeBr~>b!O*A}%yHD^`F4XpQNeG_n90jWDgp3EP7MK=8VX=2Ouek%`q9x^UTFuaG zzuS6<|cp_sf68xD(Vd44&0o^hJg%)QrSq2h1fvJW?hs2BopR}kE^ z-aIgz>($-W?)%kqWwwlq5&ByYTd^QVuI$kCw*e>EHW-Nq1F$o_)G}(JdVcBgZaf*J zu_0>5-#-gVcQXLELQu^=hjurAzHD|H&{%Ud%!4{c!=R;S9&73~ZM?2Hn}h78NCPl% zCg2Og2fr`S^>;j_gr=#v9ILBw@i0+_`lNfT|8GMu8IT~JzKameZBr4c*H0bz5NM3- zSdf|{z0SVM!WQ7AuK?ux#H<>=lt1tz$l>0?G%#4J5c&%;tHH>&*}#%d9%vXmzcF9_ zy}$X!4(O#5vKFPYvqW93$c<--%br2Bh%4!Eh>d5iyBVy#S_=(BoLMq^(Qqm=JNcW_ zm`!AsJ*KM(RCWMLT^NoD}hiZ|TUU{6ig5EWs9`)K`MluD`vaP8PTtqFbN-xldqYOB0K-d;Q)y z#^5ROuCHZO`M9~O^~ zr42>V>TW!MhQd;ZVb5aD#+!)_qyc~@{0sq-eegl8cI^*Qx_bp4{o{2rqE)wg`a}>V zlMYxuauAE>yEhD{*WY!n)BR|C<6_qZ(g8*)A#Q_Fiv(uEaznZbAQ27psDqphltKFI zP6QmA>|(2=WO^B{ewtv0^gZrbF0Q5Sa2NR6Ke!RanZdPf(H)({0dC`lh zgGi0a59^R;jwEjA>jgHY*#|=tZ4UJx&TS^_j2wO^qt6nfg^!FLCn#TW?y+_7#;lYH z!DC2X$osey2?-%#uc~YvmpFTg+A;;07t%qU$6@CH>|>9tU%V`+p#c+0w@1-SKOy=S zk+~!7?jBpocQjmS{Oz_%+3pVyR;&NQ8Rb-2^;kSZb(YbUD17`FWp5vbA&Pyri{3vp zpR;`wB^q|XwmoLGiW-H|Lyr#CSda{vo((d`@vuR1nm1M5np{Ei4SAH5i;k-z14Ex2 ze{uJWvaH<1mX|v%$(bru6mX`6z&$?9WtPujtSimz)M2xsAsCI0GsGs_)miXj1MQB6 z6rjcgL$o~sVV2+@5WFR*GDz8CCl6Qr+~RY_v0X$(FRw*Y3?9nfMrY@s%(VKU^f$cKA{^sQrDp-~gz za^EoGWt^YOCkpK1A>v&W=xF{?7u;N1Ng*n3@?b3--Pcpp>sI8+j41bQgQr&zlxH?B z+#P`gA*X0isx9e?WZ4#kYFij`xd$H@!y85TO*rkWv9hRRly=SlETLr*b<$dK1@NK) zw^(ao3py*R7IVze6HXtziZjx2a*l`YX!15b%nAOTY#}O_-q^EIK|y7AtlE_sxxjDl z`*Co6zqe*VED?_5R{E-6{cQ42=9-pVOV;`4zB2~5I)U4txTia#6WEr-(Zh)$N`A;>~&y&f>FQoGJPN$c72Asva%D+(< zUbllK-EDtm3uFr+S_hLA{3+JxL8}&v<@9>N3=`3QCKa-!nO~{yrFbux&zYukp znHm14;z-ZT@&6Xb9@T$IE$j$Bdv*Io%GK%$C=wQ*%Z5iIw2@CpuNFP@C|Ri1W7VfhL@lNdL(1hf{e1XCszXX~)1#C`Fj-up*AZ5`7?_j;) z#KRO~kI#L&!N}9!{_)`+Y$L0`c0cf)=|yx9OUwdX!;0C%rh)tCa1N2k3$W16A-vHD z*Fo45G1jvFNf6Kt;IizprS_i~;9a&&{{%+WK;+JU0TZV86z2lTz;#*G_rR3tuQNZ& zjTMd_w@dR$A2Qa0o14BWe?G04Gs>>2XVqRBR7JLqE13=TWpr>$*xbT81Qq^?@?iP;_RQ?@?@ zh`Ci*ICr8wWyb!YJ-eB`0B%3xY?=0z+Auvu+b~U=6;>DuPbIlKCeaBZPBzVho*K5I7In9BZaUIDb4qsjvW()XPZI$)MXjmvh4~Q?JjRzXjsNz3 zc|3W%0|U|S@#yha#D+KrtM(UAzsIl1#K2R1j%N|E8(M5;HKntf@dy=rxw#%edg0!2 zAI$Nzvg|>g`@{>ax(pEAzATpt#d6^7Biqa;fdr9{+1~>9K5xG{RNXl9`+QW$I25|xc1Mc*C6PJ zcdKZrG(HjCu)K`)z^9rgTJbm<`DMu_YOvq3f^skR>@}ZAu1znw2o|9zt*%Kh>X3PY z8GLd&97S+q-f=6C@wCze{C}^kP3BGRN?-)cCg2W8!jn0KFT@^T+Qh60@DDYxW70$g z`vk8Hgo-rc-K|%)d=>9|=<+!?JMOENWX~%{GRKFnDpukdOkkWoN@6@Hq(e5C1Y!R~ z1LHMy$=U1Iu@Q@DL~J#DI(s3Yd#L`f43pQNw@~<@{%m{7!k!nF_JwzTQy%P|Ywe zZ`9TO&fO|G>Oh%&?QN_96E#Z-#BaZ9h=r~7Bo+hjSA7p@So`SV{M?J#n?~eC+A>2@|WBGC;)bn&VTp(5^bv;?aA9L-ohWhEoERXT7P#=YwQ(v&JUB zrhXj)`3y2Eht66_;_MvyTJ3n|0b2Y?tXwDd%%OsLGhulkKahVE zOyp)yQM(&dfh1uA zBzlSQt#Xm<-7B)9%hlXTQc2{ISc;Q$=ppCdn#wktjgJs@hXZUv`hXIrSY$2}omcoj@&kXZv;;%bWO}qL z5uqQaS}X9bANBTrO~Fl8ItC11Oyx652#}mC&3|Y+dn+{2rvyc?sn9}a`7(>i#U=Mr zQuN*z7#RbRp`Ohw4~3rr!VcBN(RbNN_zB=EQXz{oow6*4bon-|&Q6ZM*Bq5jXV|=; z52z=z7}+kC^gXs#o7htpDyO>)ZH8P;ULDLq;|a^P;M5{rcKjP1`8gn7uc86TOOr1R zB}AHs#_Zmg)0Hi5-OUn>hch)oJxt4tfhM(y-|W3Arr`x*P3N4fCN!gmtYLii_~9NovgP@BHSwC*l=aUxGgi9B~ENeNfHf7#B?e}zNFI_ zIW8ALlz8_QlRE#oh&@jg^X)4_70wk%3q_O=t=eEK_3`&6jo5t^cR zT1KUH*XyXC-S+aKZpYfn)K&-1#XI%Xz~Bz)*X`Bk?ZwA0;e*?!bspADqvnc1x<7*t zn^K1D*V7ePR9W=~6t`1o*|ytg_4nsYl`9BYZecwg-07#{)6%D<)lXMgt8XXsdlSk? zG`(GBedq5WZdPG^k;t-|r`TF|#sST0DM3JL{egDP>5nT*RB(M=@5fMfj2mWYzD<)* znnYPwbgtlf?^OHNJuUKlv~vbe;}stAyg>30?iHh#ecy;&ewYE=uHTlHB0U98pEe zsa-t0p*}l5c;6maUQlf_3wyZ3^euPygy8`SagaRMv3;96Q=xw0Ba?2o9i~=`Q5n{z z8RoVRl3u0+GwtOuvuKhBano5vtlY^ob-HryTc13m7iE#^!SytF6Twr=;ngRB zxz|@eKM)wy9oKNzUf}9C2t&5)9@dv$oxk^Ue>9U-#G>H4?#^V)iA77zjZq%cu0BdF zd1^EW8@ZXJ7Po*ig(X*)ebiKoE~!|oM+a5|2@ipuL!)7qS#rDY#laAF7wbQ;HHA_` zYxKEP9mj^o&rx)*KL`It)Ru4Aq91BDd<4vL3RbIcvG@R9uSsVyiXjtG(?{pGFO>rv zPHeTp5v9}@PIn1JvR-SuhSBsSrITf-9S?;Trjl*yiS+}zQ{ZWM;~=MTR5Rt0Iw57* zi5t2jkvX9)y@W95j%ZIEB|N4Vt!ez~3+wbpSO%+NKid+R&-&}}z$$)n?yjzL*{Q`NJjR%^qyG!Zo>E!Ri4WK!uNYFAo~ z!&F+=FX|@q^TfUITh+}<*pa%{aC~o~D@WcI3^B1ZH7tsW11Y6}Dros!CSPK1q26VR zLY<0Acyg~!z-tS2NP7R8{z6Vvh9~aG<%xM&1o)W)Z-Q8vjuTIa+kL}bKUT_Z;K6Ur zA`qbrC91g!qL+FIVgy2u{JL4#WS5wa>p z8jpP8R?lveq8qK=**j1lr?G)}*|>99#(3SX=O#QIqN&18uej?+5ofZ?jd%ndmOtIS ziEQy+UlEL`Jwc`EpPIzr2V{oPWZ?{Io%p+V8onxP-i9GgE9O!uLnOE3a?)(Tzcp=AJQ`M{1ff9TsE4t_hW`#e^z`CUDs zk8+!|Y7y7y9#2zJYZa9NGgIgv%mm!V!;`y{&UtfH>^G3sL7zOd0^Uvi+UT~UWBq8F zhIyulS;#Y_bU8>I%%NYg#1~^^gq5wEC=7pQJ?5_Z1*ZPpUpl2?K+s+J!^{TWHY#cn zHh@(dYIVg~f?yxYx&@D}zFBAYS(j83;-YM7C7HWEdsMFhM)ViI>%&05V*wplSSjxo zpdPA@{Oep_AV`HiKB?tF1HA9pc$(QnJto1CcB=sDuxuL`Q2}i5kkBjT$(#940zp=U zw->(#@ZAwi{rU`ioW~mM3FNBC?#EKn)HgFls-#O;x0VW253Nj?cP0H14Jd0Z9yY*h z%XmNdEn;C=t?R)@lKF*5iDEMLNGPdUmFOZH-xoC3sVwV%so5<5Q=lj#(|;z4?r3T` z6}O}QGxVN!FSLjXpo2`S;*zRJSTa4i~>gxA?fx%u2z_Y3A^ zOoj5tgdIFaf>f1Y3gXN%_m+~1qm&#Yn2`#FcIVkJn2J;x70Xb>^jh$*Sh=s~()0^<8!bhcP3O8m!44Y0OeFhy}_H(3&F9 zX6HOeXLlRj02&_MJpi1mUclCtm-X2v>GsvcMQ+t#+T<>72#n0T|8sg$rbfF24HxBa zQD*&m^1JQph<0~G`F3)MrgPa@6V-b)%V!~7Tb#!dnq!7}K4nZ=kkC%@s|jdr*=)1RzN^jZ z5hO7wNW=%ZcVJ6VfNYScFtO}R`R=(1izcah0r1pW3vEA+sat6#IlW-RDFTzJDG3A>W6wyriKenDqx>Jf}n|xeo;KLOfE14ZjbeKFstw zyvI!#J(V!hC=S8rk_8gshl;O|4@Z35>Dy>kgrIE&={1%4AZ`8xSGhFf0w1IMSrP^^ z>6~~aQ47zuph;v9UZjj!V$cLnYrKHz`mzc%#dPtaDAK1;*^R(oeBw|w+9UL z^uYo*y(0&GFFklk(IbH`!LlySp<$^q2Z8Suv_r-Ry}bxO1ZnUgePrWofraFV_3+oG zik-nQhKecCso=#otjVofcsdd1-9z~M9(kl)WICoK2$=t71#swdYr-V?kR0QO$CQW) zokulC1WD^V1v|YkE!bJSP;01PKb&_o?FRo{MGl{nM?FcDr4UcsxGHg!06#Fy5#0K zvGXLc&+>@v5mXG{{9E{luDbYiv|s{XPt-1OpH3LX`LPBpKz|8YNUtTw)3oEUI|r+G zsJ^6Z>Sep6G~wyS`3O;1@&r|?WXQwNIpYmUjn{~OttLF11kvYgCWinUhu+~x`*56M3Nz#ki*sC_O|?0@ zuD&spRMUvjyR0)WNV>NK1pE5*0uX})v>*Wy(!zplJHz)yX}6#JWf**Eep5cpZKUfV z%K)F&XR9FBdTEsm_-^mv`k9Ur@9S~?)WYLt(TmToX1};mD+4@BNO;yW-CNX&08i`0 zXB+aS{l{?yMOQ8TEe|&xTK7rNWV-w%V_bx)r)O=-?Cdege#_-g3tJNsv6AU!ur&Sh5X0rCSs!oe zc@E1}jT{b|$lK|I;AOGWrTuu>whbYl*L51AX+RIi{WEu-32_(3##HP$u4SA5bp+9+ zlkzsQmE3q0w(14^2Vm7>*DqeTM79~6&S*C=QT0miMkAoAUPau73LVUSoXR(p( zX$>@{HAP&<24Yn_-H2(d;f!Gtu91*geZo|O1h{qi$mrA#Kv&F9U_Zqb(qtz(H&&3Y z&xiLdd`@u3T?FV|&h14q?-x>XJpvyDZh73r`4*&}tr;tm@U`|kyBT;}F4Z4>5#Caj z%S=4KDY)+EpadgVrqNLrV5vk3CV=_-!&8Zi8D%m=xT)N`!{lNg-A%8@#G0%F2AM^O zNT+EkV~6N0x-c)F@hqXwyT`C0q36eE&XY^0c;>fbUoZte*Aw2o6dc_zLmL-0PGV`l z`9p7*0BtIUY^p1cw36`DCfH>t^{hN?fdTRKuDD;i6@$zXAvW7aMv^Hgv zX)0MADa8B}?OW2rN}+2=MD&6lD!>YfC~#Xq!6fX?jb|UGh(}k) zLh?_5`;5=EW8-9yr4JrF{LB^ON5fJJfBy#7q|#A%#DhvOMejsj9P9PJ#A1t|gFt=_+qh~k&KHoY(w(KvShKvQ`QO^H|4G(kWTpR)MCudF4ae=# zdmg=plr(*0nqUt5lsxJ!M~0Dc$Kf}UEXRO#0?0pOP~a3LU-uWeH-KQo;#3|o8Yd&u zPtLDTJ2N|DIqM>KdFv%eKO$X?8$BJHJ-$_Lgiw#Xh1B=6?yqYC9Ms`hocYjAC?(A10+ui z=9y?Q?G7_Dcy2JahICX4J#X(OC@~@%u;lH&^w*~c$)8ym0zXtx8c>MpD<8uRt3{R1 z%{ZyK{8l}~))($S@Cf9)E21gIDhe9TVm8vN9v_oa3};xmGJcSL z-8I}LjsZ#;xf-QV8RGT;+%gp>R6Fo_Wd*=j>`$rpf;Ta@FCbt3e@Xg%>VH@S_w23)Mgn?R%;; zQn~eCq;pi>p~aVWQUY#jqE_5S!4JyR0T8dpTuMR{D9UuH*i{|;}Q;|+| zf1C`eIqIiqfW3&FxnC~_3as6X`n~Lo{*Gz5%%Z$0^^|Fl4#9%a`4^q}s|P-tkvP^M z_&`fm0TzhZSUj*|4(OijG}{M^BRd)Vrt9d9u13c)F@G?_g`igOwK8~$uyOgsW{AGV zz1>zzSf{1TLeXdv3U&&h=m$+yDsOE~(jU#~n`m3qvjHKN-318&zE`iRiU31D>m@iy zf>#?^spu2pP`6V95Oc(deYxun6zxNDb{lc}C8^dXNXiz-NPc)tQiIGlG)eADX2?k7 ziIq&C>QBg=HDAq*GK;$^pB#>($qW?iG^M?{4HUUtWrzB(U~3X^_tPvGb^rr(2*lPa zf=lYO05;QN@DP8h-Lx zpoaS%s|xF6T5?IcDo4z&$x2pUJ5S+kgYb91nM(axw-J89u2w;&*6zR)8Mc-(HDA-< znT-+lqjb9}2Azw=yd3$|@@ZtPH@P4>cOhMUEy&N}vn}*31v~b#=#0uw?q`xG8&Xq7bv+a<}ByDnmpUQeQyOl|{4~uI@Bsz*D)(1QM zgTH2+fItX{a&L*_GQHV7Dxk_1HOvZhTMTMx<${o3(lvv`!(Yu)A*n&!f7aDPaR<(# zPzMi{qd^4{l@8IJpj-gNN*Wty9xf()%99uH6Zg@TV(ZMyf>DN&F%s0pxVX=AJ$v?q z$UB@9a5-QLu||O$SE)FQ9Kc))jnpCO)qq8N^+=#5+HDO7-nt>(9uC#Pv zzb5k>0auB3xm;NLGsA`%;=Q4ZV$6)_7t!N?!r7HsWr6R+$OZ}mY>SnjqAB-Y-ba=e zAR1K|;;h8CUSBA#jv{GHrGS6TJnt;kX--y@mYA4LR*;-jdA~tsLMeUPK(R3@2&!&1 zQPy9%(RNyby~ zyBjd2RT!*kLwB5@MFF7~FT6d)3Dk}7ypYc1sEiujJR*q(LmAT&(lUKY31(;(WR?+h zy)-|4^65OCV?an4iJUOzRRmOn2Y)+O!0-g4m2HCeetK3>|fqivu9|(@nURLSV+0_n+X7lcBLu%69!=9jW7F5;kzZ!m?b4 zo|Qcid&i)EX^WnIDD^pv>obIJ2%YD!LcIQW^3RdZzuzaHd3|1=&m$+MsJB|fNry3= zPH*P#b12M8o*24m{SHgBqMb5&G*5fqcQbN(eZ&4V!_sq1nFXyiuS47o_njYFLXYSo zCZIpL+G7TDgLJ5qBP%B(d%A{~K!!Iv6FPv3hQ^PchEMO#6p!wNTNduzZPelNh-6r#XFJ_yIQ!`xfCXs zXm`u_egutB%xmr8mSk(n*~L^UjsODq1%Ra8qj#?Y;pdGC{RXerW%+!z_3vmtT8-P- zBE8o3mA-obzNd4>59Vi4Ii+GP5!|Qk=iq&L`g}ki7atf5-i3@OIf31LQX>hMI^>aJah)}GjQ}7QNZLwC@3jtd$Ro?!BlXl z&RA08;HGi*_$nruu|MSgRm;gdt9RySeZkGnb^K8t{Z=kiL)5R!<@9Y$t#)BINq{{) zyrf~pA(=6ynw8PSzz|*O$T<6~lzLsnsnn3`Bu~ap9%g-s;Hsj9tEEQC>>aWTg+gMI z{p~XA_E$g|R3UmZLW0X-ekr?_f^Waf!a`8Ck`c$DGHaJLct_;gp5s@W7HzPf^DsE(h4`J6(9Vxg-#D5ZUP#wcr{RtYE}`SDQf?KOvDH5$ME+2g`yg3c;`UR9 za>B+y>FrjRaNB0fEok|zy)?W?22E~Kc-WtIy?Dj|9h4vJ#=%?hPiPyk9vQ_?j63Xj zB%fld4em}j5%=SSS6NaDQdb!6 z964{k(kiYSpCI)sA~~-Zz+{}|W|Zh!rDB!FlJ;43@zvd31&X*LV9)XW~-<}6-%r3`v3 zbzXNKU-sjEnU@s47Y%RUhkN|?MJ8x16J#OjWD6Enp`PG)|3KOGE0Z~DIX zm1+H_5u~vOVHtSp(yVwZ-XWccLrUTsxvepA|3(SN*_1L*2CKsLQmO?Wn`9Ut7OI2i z&BIAY0DPq9V%tY4754H6aOMWZd?fP&moei^+}HI5nbVK}bfdFYPk>LwXE$oETr?oY(`m8`0~A1FNH-U*G=X!Ez2BTq#Rks%#PxVF;g0U_W#; zh}mKufr3>7E)OtYQa{#-a?OB}4x^P_>Z&AQ=4JyBDs>&n;)Y=Z6C(3hK-4T7{%BZ> zqJV1dcKgiv5+tm6k@MZ^^~Yh*81eL0-sKMYcj~M_Qwn3&o>g?nESRth^ z?j0FLndF5xG!}dfFi$pkQ0}NVR!2A)Mye?4IdTB;vApT$9 z5yA>Jc>QFEcRS*2g#02+NF2fkAF&S4rjG;0RY-^_$B;26zqWk<%z>aeG!OuQv55|> z+VgjfKkRD$rWQb&G3SO)?~10vV|d9p;UugSk7?6t(AfP3-4q_o=~khD%nM0p89!?AoN!We~tDT-vi3=A|`c zRA&>3dV>N*5JWSCnW6QaFk~KZW#*8w&HZL_1{QyyT8K&V4q){f8lD34{Z`>-ONBvCZ~ zPLihUfWNDGLvUW&gJT}C$!ZO`(A@1ai96b&BC%iFyPQp}LZhONI9kgrE{~8*gTH>K zlbUiapDuD{S3RgBFZOUpaCfSWCxk=W()MLZJ_vUCG|H*lIU1jE*7|XPa0fI9#eW;T z;o84(eY=$I%T#9Y9xEU`hWoN|4Z^Yv0@~EzaFH-8uL#7)qT_@?0b4=5=|n(HdksDiPp%$)$w&I;$H+ArXncQqD{v9mu2wewPt zdZzpWUgyZwW5*`i?~q&xogL2J<*+65(rI(q{n+8%S>7Yi2Ouh?3E3d0n7Ci;C|A{A zWI#1FG!%_g0k*|S5NngJUTg2|aG&3bQ6W){)kR{1aq~(n^&_990oU$yR5QQ+tu!r0 ztJ#B@x(deqhkA&L4ofhqq-`^1WjIlLs45PD)n%j%bt+0m!wQFpCPW09%DFZp8dxA% zC!~;Q&EUmroCleA891_;M(%hf#I*x76xrD{`%Dx-gc}ASIKA!(HDS@?P)?QbRVfxr z?Qshy%XkQ5ZtdTRC{A107j8 zkJZCLA>A{f^ptexji=i)(-`Y65Y-#waU*_o(nh$p5ih6s@^Mgmq*vJxSyu(&`~*Od4)R&sQphutMxCpGm_oy7aNhU zwbP1I?gyv`cfPIhwT1pg{?H7%ukk~vECP!EkAK_Gph5_0@PR8;Rq6k z7sR-(K(n~N!~4C_oimSI{Ff$;^?w4@F);uCu8Gw&?6ySzZ3YZNoAr7qs9!50`(0DC ziS3uW&GasKs7=FoWb_rPckbaJTW!+bbejpoLF>jiW0thXdAbVqkv6m7YSLbvACRhB zzoi$oV*rma?(KRVn*~n>C+_XrDq}5cyYr0jvQ&m|u!uR72$C75k9MFunY&@lBlx!CbSoO9k2JI=>mPyb`hz!8`?8X3)%vrnl1-xB&S_f*3gRqjoh`OH+y@J@ zU1hD|j58Osg2@04(+eaIq9%Y5OHUfLr!T?pJLqR3rqn}7Q~H`(&aq^XL^P|-Ig!|W zV&5p?R?*GX@#;Stv{`5%^B3zwNiG90X+wZT1XtCa5>=)eG1*0COmiyE)-V>Aorq2C z3@2z#L$S0p{aLw386G`1>ale(b6`gb=G&OLbNGj)fM(f$Iu5j^U!EA5YNMf{hHx-> z63(2F7#+9@tBe}v6*_70YgHYxSn9-PUJ>HS`Ld_+C@i|NMHK2v{(_y?0$akBC+C)_ z;o%y6;vNB;^BE5qoaagk;N@gTm+16gi+AZ400=4Qf`%6j^$V&Hdpm{0ITk0_xbS^=GF<_)D>bM_F~3R=i`#sB*f9t zA)R`%Ho!%Ac?%(u~25`;nd5VcKLo{-Q5TMT~M=W4U)Nq z9`7_+CDnpnG7Pa~wy2n$-@)ohukZPYHg=#$^3kvs<8}J}=UVyT$0bUUlOdU1{gooL zLtWwU?r_RE&ji|1rdgGnGZ@MZipx(wK&n> zzb?6^ZrtB48={!Om`e}BQ8+kK{_4v7ww)?dNeWu&EWfi@o76g~5}__d&}`}7k?viB zD;D+~UL~1I{>&S4jWVZra;{O?&Q+=X?fHRcAvErTxUm3Exak^da{R_STP4kHCk%qw zJ5vB|q7h-Vu7kePo-)S1|Hc~X0J&r&yQMfRA@dpk{qZ>_ecUV_)fo|0GEe16OTE=I z*4#gG@g*rW;wh0urE$t*!^$bdlM8`k=K>uWBtfX=lJjJ?gNC#o63p2gjalQ5OHH zO%!YuRVRt|3Vcl_&gK=t14~$7X&ElnT8#GUxOxvd7Aw1Sa?-H_s81N5#%!aT8?er7r-lbsT>+*Q>_IJ+m>N+h6`T3(zE(qOA zU|^Vb*i&A3T?($J%KR>IajEY-$fz$}*x1nOz&lwQ>RcSuK=aAxW8BS;kCzxn66n?{ z2p?+}ynkPdb(Jk0Rxo_+uO~Z}I~YnL{17g-bU*jH-?S()+nNx z{n+V1{>?&U?p9}5RP7B1_x38!w)SWwid|Yl#haRm7O_ydybhDWkuiQ|fLof*^HTqImViX+cdr3Mn)y)+Yi&6$2LPv#F- z5ivH2@>xaQX2O}(VwBwv;Fh)O?tiQI{}YUefsy?`)<7}oTaN#(yF+h3QM#kDRjKRy z594L&vYY=8WAD^nS+s>)$F}W?ZQEwWuCSsNr()Z-ZQHhO+xC}puFihGeX;++x|pkv zIs16u)~*WjMQzF&FrCb#wHqcxQPkqXHhDdT{C-oSY7E{*5YZzLI)8%;l6{l&8ea9I z!e3?o;z&O@BzgT3CeJ8LTKxk^x09`uExH6vq)qac(>pr9gL^pmvZ4l)y}F~el`&FY zxNOc?aM|j5L{Dqq5U{$ z%$vbW&P&f#njUpOM^$Dtj;dtA+2{JsO4CZ+Oa*MUsYCBL{RvV&Ni+U6jddjeJiD-z&=>yL{nXuc_Z_t3MdS=n`T7|AQAEXm=-KHq@flf;4P;wA_Ws7B(4*v_ z-$u3kKKXQ$;V{$HLf1S$?WVTWPf&ZVq-pa`f1h5bwbV7}iJ8=-%H;y)T5fdcKg*t} z`_|^7x!rL*kaTaUte+{S5!__e9^vQmIE3b%v^XqM0)oT~XV}0E-^|-D0flC4)_@^)WiijM@Fk1LMM(^K~`8 z6(%7g+i{!Wy`u_I$Hqo(mm)Y`SJNt;qW|CKw2NFV_RZL+(-oSo!0)EggMOiv@GY@r zLWFyJOXpijc&OY)kaX|yn_xZr_B|Q4pb0h9sR_c#@mNiSiE=9!tEQ^QgxlKS4YZJ!?rML4|EZVOU8Q9lwk;@?edCWQJ=p-Ye1Oe2~$Sa%x{< z-2%Yn{|V8e4jXOcp-F4Nj7vxj{Ibo|9BO3iyBn{LG(1fJEpcZ1)wx&&RL~sLr>q;% zc~DGW8vR>!iLh7PoLY=tsfFz^pzFop!l!Gkq6aJOp%qW#)Gb4XQXR;kV7x$v(hrt9 z+DPY_whtUYFG04kCw82F0+G~k!$j|azKa5&C(n_SnzA@#2^+T^rJh0$&yN5YmQ@N{ zse6QtI|Bw>#X$xK^8o{#$;xZ3vM}=JGRit$@nQD4+XWyxVLN+$ZTB^Ej(D+qchJTA zZNpH>Q4YCA^n~b?+)>UuF@pRsVdLkpLo_rTV97H%o3$|!q|PkAZ|6mEO@CNk(J$jD zIzU=&x+o`{AcH@6v-Fp^?aOT6d}`8`l*W?*g{zph`{bzeEk&J~Qlf!DD*DqYeXWcY z67<19{N%!YtUZu0SVbD4<9tpO#UA~Ly}MOfP#wPmd+1RvY>D~FmAGJc0?*?auXGqY zsjzTd|D`MqiUWh4opz+&!)aS$`hwOBDJd;|{T~3{eE^IdRhkTS!V@cIajVbK+`bd~ z12ny3@#(ydpaXQ;IM|1YJODeK6%zp>%1$b6oFHmWBANVteDIv(xcBk4t4Qpd0s`)CR>!Pdh+>aGEY$vZ&#o-L0UiE#XjHl4LeRxLCC18 z)V@C8(RgvY>y_|l5lH*rCh7mQ-eh9_Pfls4`t}bo3CU|)KUcynL{kZks?2jO=FbXa z!Ra0!U109YU7ui+j&xXhp7)0G1~%Gn`QbTF5;9O5l@?=7u#rc3#+6Z0BQ&oPaK_gyYcpjv@m{xg zgSGXkCl{M5Vku~E%4N%i6@=JsU^#-{$4I=vnC2-NVCtnmr7^kWtyD6rSd4QU%v@ct z-GPWCfo2zkV7PW`10C-hsG16?(?R#C-rUV)OCE|c;)$GZnKU@Jdhie!n|~UW*wIkq z0=Sgt>!ZQMcvF;#0W5zXcxf=#tbQNymJmKN*~N)^KCX5`Yfz?Chqo!GPh75oPDQf+ z!8*AX!M`EGh7M4|I>uj>Y7iS~%I1XDcQ4Kp$7C*15@}!CrytH5hay6x14Tmh=4Oh15o@UUJ1|J3efgB1hj_Hl_QDD|Is+1G&wK8d0i2~J0Ka_ge7pcT|u4eACuB8PoC zXGv`<>4R!Ywn;5^kW}vh^J@OuhOsUlWQ?tWpC5{+D-thN|KJ2t!J^&{6WgdY(B1TW zqIF-rC=n!j-!G@nU$@ndF_S?7NTv&luPzPVVcc{KPx3Y=id-5;AFI}a`EpGkj9`Dm zsu1ivJF+^d%KAKBmMp$tM7#BM^*-$Hi*goB6AKI5#_QF0+TLF5b<+C^!yNqQev42R zjdM>TD-hz}*H@QSjLpOSeItq+Nixg_1O?*PUSKValESUuJNOxDuSac*TRk^qSntrz zv+?3_<@j2RnNNelqo72zpOkYEMx*W%Pd=xqWU6VIM9=7(wiv`ReiLh}!mKN1xU`>J z#VBPq6Ye~Qq*aD)*3(+1lXzM(ToD{aTYP;3+$mo)hN%!*HVyGeT;{{)lQxh;9%tB% zDM9jsg;{k;o11&Y9AIZ)_dd$DXloP&J=M(dGHAV5meE#D^TOhQO1h}1`Snz5{Ka*Z zxZDa#{&~rxsr_9~91pq7N~*7f9Xa0=luM0jzxGjHw~liA`MH=qf80H10YboGJvlwa z=_dTDZ0KUy)s)BQkkn!IA)+6vVRM5v2#irOXK;|#?uA%jGoiT*&aqt-v%u1`{q}aE-}xx_Q?`{Vrv0zy(anpr^F1D;O7AJUxp{g z|Ad?4VE>PfVPlf6Z8{@b(DgHo2lTvMZDeibrkoaob7NJjc2NkqV<8FgVZLVJ=L^2E zNJaoi`tL?%E6!uS>dgBGG(KWK;TK{_#TWS5f8qReGmC77|F>Tl?(Rw$gH(=1$G*)M zh933lgEZEe{krvC`{KvXFoW7BE9EGtV~E`dO(Oo|6QC7qo}8s?!=|)@s}rm9^dzQ* zCV!x$pf;zJke9-!?I4rpvad zkhdfZg|Rlt^tBotntUL)_OHDSL$W+bdKtP+IKh~HO}Lq%-ALa=%>~7HN{$2sH56nD zV6MzA=8)_UZPV3?u5(vLi$HT}xXQnpJecYB{dEpmKjPe|OZyq^za)!I!enNhYHP8X z&^|UKUPT(Eb`V5Q@Q^8ra#c`T|HE;KHy$81#nVz8&Tc0t$>oenfoG_UZwlzN(BON| zNKX%{yh+jvQn`SPRgI~&SUMdVs0=UDdo$JDNS|(V$YAZRsoT_>TvL(u$WbhJV?&b{EO^L4PNZ8L_*0n$=+!HDbx<-ZJd zh)bQTaiR>zrW6sU#Y>v>f;lqIWJ=??j9LI#Q;b6BHSL=j6Q^wwq)q;>ghcQ7FkE zS2YtPd<6|p9^VRRLN#fWfVymSCm0&sWGv@5-f0V%%546gq98?+VH-Q{ z@O^joKw%!DctAS__2}Za>p$^Rpfs$;`7NluFe}x!-?QjV@#YH)`0V+$Km<1p*LSl6 zwyXExxEJ)6@ol`vKb6rU!r9K1F!uD_#L28XpoaPH{t6LtYHR1e{eAv7CK)r+e;{}- z)#YsW*^xS*)lVqVk=4n>q%O9aE-~oVjGCeUS%eAJqHDJ|9V|-B0ln|@^yl(lFe-VR zR7wKLEZlSwn{nEnc;2>P_7XlT1AoUhueo1Wb#Pp>L=Vdjg}OLFW{VIo!B3xed-S@Z z1!RP;d{=%HYe448ChGt8jrgcqL4!va_{uHikn7q`UJRm5Yr7sRGxzVV_PX`zAi<#L zn@asXHaCDQ^B~#ZLah8{>Vj3|d7HA3`n>ZCS|v0U`LFGDA)|xqx?A#=1Z1zdG1pq2 zJ4m_-tu%!Oyw}aIjnNU1>a$H$0|E>3#ej*{00x;E7Mk$S){3QuL46Bj0Q%AHn!X`Y zlUpNI6=)r>!keeq_N1)i`Q-aTzmGT$RiE$ADZ<5x)*$`wU`aZwN$=P5;(sX37hQbdaQh*k*Bnk@A z?z;(roOQ;N3>))68;|i2@2^_x_=4xG?T2G*eX?G4s;;|zz=P9@m~eMrG-2y9xT7GC zj9@~B#1J6b)6gG?=ZCbx@cYndz}R8TJ|F9;W_uFIt+`O{+gIlfr?|0; zgq!1Kq@)2e8e%In#=&FePIvfuYt6&S{g#Z_fYls=Ts;h3Gt1hUx#?3gNvvGs?sDC# z(||z{8-Z)}u*8&zrWj?2^#Vwc<`_IyRYB@eqs7@51C6a!eV#9$b#+$fC@LF>=~F@l zw(+=B|0^WlxWc6qBZK;fcAQrNMlMDJPOw0jtuumX%C2aF*(P!(P{Jd#K{Nv>VMn2E zE_|DDKgePMJUGh30VeP+h47(fWF!o0FD`c_wm|7rNs3jp@w!kI!DEQchH3`b;|SAz zW%)>9cH+OGt<7M3^>r)qw*hK}r*Ih}E^)VF53Q+z-g((_vuq}S=sC>{(lpS!)jTTF zDY8lIUx-eo4q296zlpyo1;NXn7SAY|Z}YfKWy4dsZ7>#?OivBAG!)>#(L-d{e0Jis zVcE=tJ81)r=mVknf3pknB?;qkB?@Q6YByh<;U@(Qc$;r(k)h#1e05`F=8H`?y^|OV z%LmGIaeIEJ<0;~H^FE?DJx4;pzt!#U{ zXJ?-KSwE3&^igX)>%|I9^sXr>cH{J$c z{OA{O72=8p)UJS)Oq&{#IR66~uhP*H_aoVR$E(%9FgE;;j!bG{;aD>vtl_!u&MT|+ zS?l|#wL}|jE%#+^bDoC||7bWS>yb7Dw1Ny8X5qSAM4Ix&Dt*l2MPu2){XT$)?nn%+ ztkK*I8IG)g*F6KZKjVMXL~#61j3{Q7|HLx>Uti=1{7=11@i0_6vgN{G{m{COr&P*x zcne=aZ*M_0+){HwxgcrSwIh*`Fvs`E(89!aRqYHEJ_ol4(x+Ts-3YxmTjM9soUaDZ z>FoS*Ys;4;A{i14m$&m>*ovYZjh@*&Uke5?E}cgrF(VL^&A$n_d~1B#HNQEbm+@-z zRmG7-pt_LA{T^1s3EZ#H^3?it6zY-eXC|=n9%3IC$yBg%Kp#5$)rE@8Qnf4%)_)t( z8lyxxFrX`mANKO=iG}*8o9_Hkypa2a@M}Qm?|V~&{xUTTt@Q#Y1iWB0T}977nS#kI zFW*3mY;zsfMY{@~;wzWyIdqsXd$i8mIupF1()iEQQX6^Q)z|UZu6q#@c(JCn0RYx) zY~9szddkHMIKih3A6~Z)$g|Dv0=xFw*ZAe^8$LqQ8_hP0Jc}QJJw=tot%u}G-#0*az6yGg9Cw?wNi?e)?K^1X2sC4lmI~&`ZH@2pDjH}#-`bZ?HM#%h zFLjDW#*I1w3>y*^!>k`D6Mha6~LDVWk@#UD$oP|^J4ApJZ)bg94aEbJ1!ysY$}b@?st}wja=}ozqZ}4 zXC4BQabdDa+HkX#x}DE<4!pD-U9Bk*2ZDhe5Pm#3v0>omtS0MG-}4)g{1CDtS^&0c z{Rybr4j19cOeu3?;bW>Pe&A-R)RsSGs)VCVD(sCdk2l(eh&AA^x-*mf9xvXvnxQgV7KN#7~v6}+x0Io3BH1)vm={!!aIdDX3Gkm=0P7z5=zF?EC{>K?})gb z40$z8MuQy?0}4v7g3w_qykw`<VmWxWUPWw)CYx9E5s}TnX#KXaAD;mWunD)L$~Wss|q zkb@B-+lKhU57UlWqTt?oabd;PtHEwDzGucT?;Gm|DFL*u$dGn=U8bfy(nl!hP;j2vsgm_qL`f~pmk&qrb!H}L@CvyuBS{(xlJHHx; z?sUT|=hw-F9tAj3ZK@(V%tOtff?oW1hfY;T#>N&+;u=NgE4DX#a|TVeyx_sQ{Ue_z3+3&hNA4+zHlC`f^M{q*A4x=Xc#l zFWMt+jGO{YP`W+EAH=#zsxkK5&CfALH z%XDC(zmp4KNSYW+o=^<1#%i1g1GP0pQO`_Flz~Cn8ECO8T=}+(oR8Id3P4sj;apKU z4`ekCjXduf7)rn`-{E7ivP3D)Xql2Bc00JPZ;(!0(5Q6Km5%nG9!Cxfn{~nGa(}t; z@~lM%5y`(re}w{DN+#Ue^7wlBEL7e1+^cu#RCRCw>YYz-@_x$A2Tds2aSUvF$~lbp zc@MJxBi?QbRFr-i9_PIZ*)~e1JPF=q?C0)ae-C=TlcTK0K>a!!M484RQDP7sRyj zHnRS8D-=0>7SvrS@3;AHU{su&|K5c|gqAb$7$36m?R1QV%Y z-|A6_NMsS;2U!eY=u$WqiN;VzK@CfgDr>r4-tI_343EmBF$#E3$;?d6Y{uY#_1^6j z@J6P2xyLyF+!g*k19gF1D}-UWBAc7{qDsV7TI7 zcIc0FFI-PWOqjfMJuE-oCF$uDoMY{R>Cv# z{vMv>;znr@Wue>e)@qf7Y*E>t87HRe#56Pl*}Q~*WQ?T!xC(b~B&kCKaIug$ZW=d$ zh#WxwiUlfPO<)v8@sK9PnNP$?ix@&LRS!W{C;2rTJ2>7YX#E=^va3T$?VpXcBYv*6 zi`L2&X*set>m9B}nD-1ay8>U_6$}=-1qgw97h1)V^dzGLHz7m77g+eBgf$qC z^w?u!8L?z&T)@Bq3VAuORxj4o&5pBKR>w1Acvi^t-NLUk8+n1_o-|#+7SZx}<}bpj z&t<0q4kd)<7ZF?BM#ji#qy-PWl7QJ5fy(aB%fpK`Z+ORrMQM97F5)$OMiaoN32Oz@ z@B|!%q3Ys+*Z!z85=PkQyv80F4G_}7Dz69wA&Q?weeU5MH_Fs>LAW6#GGx91 z(pVaZs4uSTr6r#;a%?+N8;n?|Xf^JUIPxSvE59x+!rNO?{gCLC7xS5~>#ZWxj;!(q z-u=fAc54ff>t;B<;FI*?N!U#?WV{;FfTA>j zZ4My>6q2~pM9JFCUfYp}fC-l|Wgb|xhGVme+<4>?de6kenQSt|uOnrB-2{XLS$aaZ zNgx42+qj zWD;q}0fml z@pH0n0frZ48bC@*r5GlXs)S83GaFWQ#;dpDhTX!RdJP%0e*8X&ocp4f9)ZsLj%T~} z&g)dL_+3L7_O)jET#ajS2-A^YS!fIxlt7U6B%fB63F=@@nh*#pj-4#oV`R5F0!Y8X zt5ah`sH+PoybNWm-femfN>h&NYv%9RR3}}@emo8RdxfzFi!hBNC5t1qTR3X2 zvNLrEIEJvV6eur_wQu|vl?IY?4Que5L_gGFo%t(@Ay21p7nvH!7SbP2-FV`MFfR=q0c`L6N!%yrNICCW9<)B@kI%4b~ih*|=(oF<`Zh?yXz?FjA@ z6*PRIr@*L$=shP;`@Jm|*M43oa(>Kdh_No)Wi@wS##k|Vd7kKvr5=Z?ntn>yz9j%5#(I`agq&!06_`^#8B!cF=>x0-+AsSTTPu&u(yEI_jH-^X#fI&f_#%*S4f zGu1v=tEn;cc8WBLKbn^aA4_~~Y;NA}1e>aV5A?skyAvo*hWXPR+i`kK@297ycNNS; zpDtfcu|iZu^lW~aO}UwGtNpw+I63^oZ0`zu2^##}Q1M|@5Ic{N0<=|Ii$?SZne1xT z9q;+XY9OC|#JBhe`p($W=+2We(M%ET5zXY|l!dnlGoN31X`V;==$#%I#3pL-Uyg^d z=b)mEfljy?H`ofqywI35ZtUC{Q7U`CouPRU@k0!%#ib#vRsZ?Q*}yd>K1JZ*q0&6a zGDkw?+!SB!nlHG;$n^0eG1MmIKjn{8$&V2;8UTl?4a(FDfRbuLcR2smos{G9vF1u+ zFwn6MoaGo*NWJ0LQ+oNY)5PZxyh!{`5{t+O^3IdbVo+GpGA!(CF9265C+uTZ^ zk&;YSDhRhuX_e>T>H(XnU4(zfaT%&7G_=0L0efM!ban0ocZ&lHltTK!4k@%vUx~AN zMo&6^hOnY=G(kgh*HZ)%h|4DO$WAN|SU^nr2Q90gePTeY4O0!}IT zLoj@_lh0Pj>NY=)jfqkVa?=Zn@y&Bu53(>0c^bsw0WWL%fDx3l}D?vD5f*bgW8IJZe)n*jYP~gOMMtbg?8Ct zX!~7c`Z5{EjzHdht0HRyom`gGFs)lHt3|38MV23SSi{816LDDxo-}_Yb{C?AX-1C zynUCAV~3E@WZ2U2;N;1!i=^fZt1G(oh3&DzJ1>%p7_Z1HVvf)DdN{u zSe(81TMRsb<4!!Q-dc7E;J%i8^pnqE&1|Rijav=-KGZ4Y>#%uygcTR#ixA{yyeS-+ z6cAk9_$7haml+``aI!eXojA)EbHPul=$`SppA5hNfX`eu{gC#c9 zYAD*8d(2}pt9*1I5GO?=X=o&aNp?J)yMa08-!06gF8opsb6gVY{3#XHHeS#*9B)e5foGH4wzYhbD)ZHr=mK7q8Fs z&Rq33;$y*lyfief9L!BijGK6f#6-yZd;J>-Q9Wb(zg*IA{!he(pMc1JKnpuHR)0Xv zXr9^CGx-lhQ5cr#{E_J`nL-#G$ZyQpSaqVqY38uM3ZZ7A32n5j<`Xv{gg`VJ7_PaJ zd5_Z??kZBkguY}4>qokC2U_c(61S7HjBtn;L4Iw-MLTiZB{IHBd}?5%S(m}nv&c1j z%2blz9hL~SEPcU$ldJ5Sm!0|mQMVle4I9t*>uUYwZjfcaMwVENLPS*^=G-)IJ1mt9 z5Y-$aGy<_~1wqsLdGsI~ut-t%OXZ%%MAmSAee^f%R8Jz@2A_BT{>Y`T$K-}K%sI{4 zEq$)$!gs(iNgApk*G({7>j7wBg9}m2G+CD)CUrAM=`}MRL^4TmM=|ape*XDcDZDJB z`#vt#NzU!Xc4y}!XY-@dg-n@(&vKkWGy~>QfV#ksT;DHxK6Qqdy!QxsA+)alwQXW&;ZN zf7Ae!A@Lnu-;Nn8PCk4GPM$k*NBDlOTLRTpf1>VuupI~g3TN2>K~>ni_0)1vs4mau zD?;juQ4NCQk^Iy-OLAxd_= zq7+!CU+&(_5rnYpSK#AFX<1PflGBApsW)RG;=CYpSUNjwU*LLNIQe6b!buiCgdE_H z$dU{dvu;bY_8e>@!iTvqkGDJeZq42C%}-6Ess`6&o$p<7wxiD2wkbI;Lj-YUb|RkF z>jz{jtZWO^34kTBB%Omuh{+Ciqk`0&^wn{MJ+z{G=2n#89dUU9n)T?r$H=6zCTht- zU*J&pv?u}L`L2qYm0jit0806MxgdF0KNH>?u-+egY_^y!NSFG@qs~o-hr3-X8rcrd z!d`>TNNpfIhvTsR>pi%9ET{Ou1MTC0$?Wr(BB@y`^Yq*vuT6QhLn{+AZU#ACYnf7d z!av$2ScHS#Xeh}kg7hO*9+H-x=U`{DA=Jx|7~r7quFDd$wZ~NGG7*hwC*&+E2@&U6 zv!c3ZLy@QQ!RhAwkjJcIhrkT0U7@>Mt@Uxq`xXAq~(%b0qCdsJ*ea|nd4;WOCsQj;B4dV~7b@fH6 zb&=sBm?cf^PPp1k}e#E$9ng38A9+;8*-A6W%jbGSB$nNF(_P)tepzhT&BF1go- z`0zFPKiL#rhy{pRoiX1Io4tG+Z6qu?s=G)8UI5EKB%$nkpF*dv--Ksd#PH% z0c4`@OY)xa^7G@Hua&2cj6+T2A9g?##}?l&RWUtwL&P@rfDG)FMaxI2cZ)*sO;SId z7vuw#7Z;_3yzJwX&4`zf7EU`*R(;|=K+lXS4Okk(x1;KBxuOhvv&PI1wr}`PZi#0o zcVE%y5PvmA+;@<|5SED!aoHKO2Y`W(e=NQM>UG%KeLME~ijprEXv^BclIBpkU9zfx zR)3bn5Yz6`-RCuj1SRzSKSt>LY~Olg6JM{CNeDX>Le$lrj0FglJ~9k`-d{(0o6PBw z)1m#!bgFq}(1}xC%#Xa&t5ixmleaEdS z;GWL5<0=;jU`ZD}Hl$HCJU6xDTS=Sn6G6=i`&N}&IShu+akCx-H6i4x zoVcWfST+=fbF;anDPy)R#Z6}P(}hn}2S%ock~z|4VRIZjop*ZY z(US9}GN;TEM{^obkzn}&*AS)D@=A-K1N2;qi({m!i@y^(=+v|e z;2|Y)oF{3QFclx)$hb;X4%)3O`Uee~mesR+rcK;nvFIgNw@!|;DwV$M!YU_BRuUnb zwA=zJ*TTk{P5y>A6smx{A9#g11l@(aA@bUzSG4wA0B+ceIS_P!G zdlrTGXO>5dAHZo8I+#3h3+NcKgVxyY2V_p)W%90EZUb4&7yMcjQ9f~i_`@(J(%*qG zR3W9`Qkv{J!>a1#x0cJYT%Hm*}QFE=L7&pxQuSG9)we?V#u`4H%3%EOX86Kw%ARJ*nR2_ z1*ybBlX24xVyYI>#rfP9XWPBQ0+ijz%hV>a<^i1*wHe1Pdj!fST4t!V&eB@;w_ww_ zm2}b~+BDP-Zg?QZ_x1A0KcV2OCdZr>^^xoL;><^He?r2jxM%&BvB&j4?OmC;*#2Ye zHEL)^@3W))q>G6!;(4)XP^5H6=gHC$$Wv&fAfajyKs58(Q)7QcM`eM&?>C33#r@LW zx*~YU!>!Sv#R#vcrspQi=(*ixurmVw?ux(8yspl)t@2xe_F#BaIsSJHmYYm%78x+o zO8<3<;nYp{Xo(*-b9rX}c>Fj$6}>zKIUH}X=iz8{T9_mdmC=bhoTb`d{ zGT@$4R&U?ks*K9M>keHOfrr~X(_X>QZkq}qR}9ocVlvBF-i>1fwydj2%+!a>y$;3l zLS;yBJ{oMQ9Pjd%xj zQn>T<1)eTVwOMv`BT{>%>68zEGiwt&9kCxtv#REavBnliyK1`PNuzO0PDQx}mheq}#;IaRe`Fk=bloM%#K|Taw(0zCo1?`eKfdE||L_F8D~rg`Qt-D?m5C z{LOu$S!rT%F$WJ2LYmsa5Cz@108{GugWOA3Yv)e|%aKAt+bhu-cn-VS?Zl7i)eMuE zp2&wNH+VrRYslz(`e#|`0k5bBm{C`J8?HH)Y(pH5ADs#_L3EKDmYK}aNA#!?B8z$9Do zn4dU%isI?Wj_L!1_R|i<+rmR12!dV+vSSoM;RvJam|+CQh(S_*Q<$n_H&k0Ee^m@e z3r-VCf?nn3;Rab#m(Jt?3(f(lU+*d;my~!`Nzy|~^5E($h@bq0UI4WjT>DQixiVWI z34Mwo;;O_2UHjl{HyGHx?(ZZz&$^Ac7&+FkVWYI5tbR`E7e_|myAyMGmNQe^vWofs zzE~wQ_}vXs^)7-yf0PEA=yN)sR%VWl8j8grM!*qfJxvd*y`uowhuvOMe7_CZcI1{} zBai;UkaNqc_=UL2~x~h%gB1n>}}Q{8n)> z{qC3j-Ypua-Tdb-aY6q+ze$=3^brC(&?5IK$&!#J4igKl%w@G%`n56r2GpS~77;Om zg~lD?T+Cv-uaRL`+@a(tfn8~fc-{NmQ8@IsF7I4HD0v1I>1l=Hdw?wFCE)(i>DieGA;B(H1)o#Ep8GzVU=2ha@bRSZhW&RS$m0UX#fMk&nv1^QD zf1%M|^z%7gO4M-G3MXi6h9?^|Fq*|c;TyZ}Lx*U;X}^Kx*W2Pls{1PW{6$z3OVS6% z-WN3d+yl`{)+}YGt^l6i)9sT!5WawIgR)@+%mKovEC?d%4s1iVCqAJ1zPkZ!lK>Ue z0ThqAv2%mRA&Czl&GP}RuKAU4q=rF<{EO1SBG;TcTxHT+TBY}ah%ywFG8Ee{K>OO% zmFu)7#s?qcOP)pz&)CqVu8Hkkq*P!QsOlhTP7WZ;&+;@ZbYH~|Zs@SjKi+J15`h9Y z{x?vblB{ z^)t2?e{nuO;wv0H7e-h82Z_i-!SKJa^lkmle+E8@zI_~_q4^(@A?7s|KtG&_jR?+A zQfAu;U?k|7M7DF`d`#7*gWyrTuo7$b4iF-B&>q%B`$yu0YbikVSM4$4+qIMFc`+wW zL&#=Dju%2$pI<^Ygy|oAn0nLX!wT+aHakhF&XW_p4@x5I=}`p;^%M)ssjC;QGUF-3|QeOd}X&fM^gHUj zN4>`0HoLY0!XAk%Vr{?sMrv}(<4)%LdnH877FySi!BOpF zE0se>U1{swJQQLhbxLy(#yw^+D@q8g2MgiwSQj-!;!mvxZL6yY*7^eLBVOJPd7`)+_n7hx zl$-?Hz1(x9c*cC{KOdha`G^k%8X~LeZYy(ar?bJ59$#&kc4A&s#4v1)gyQ=e^z*|w zQfAjo2rf`@S4b0AJoD@fJ`V}M!43Tb$^P3R|G#aBSU5TU-^HWT1$BT2XSKF=Aebm-t)KmL=Tq7Ph8I=iZRTU$ z3D3uOW}N7n!E-ao&?VxpiS26bdDU&#ns#~oVV=nK2hrUd*s&Zk$MO5)ybeFijT;m5 zi{elRAGZKP-s+6!sdmkoe6)NocLx@Km4dDjh>R>`jSwtEQ!m=dJDN6=*~GRd3}tC` zLWOObX4^%KZc_E-Mbye99-Q{hyh`JIEnPlW!?QAoWZ`BjDe=X@Hs$q1j`OUZAds(C zZ+9MtNXfU-gTEhgmbgw8VUc;GkZR>cC0IIc~>PH%8)l|{8n_?|xMqYi(^KfjRhA9m)D`=<9@Z&ZMYk+Cat5tmSG ziNOL+gU?)%)ui^))q_awzIFZ~&YR%A7kHv`XfUI3=0Q^o?w>Q36q{`QWc zb{rB|b1R%M5UiRQ=%)D7eAp4usp90Eh&7utUl1VZ4URv^=5GzwK_RCyi&qo!>Ji31 ztZN_2ErG?im88ps`%^I(I#IM&O{*#16MGpr;Hqwkf#eu#j^ z6O{YLI-IXB;IxAFd{^V}VHW@aKOL46lp_RQW->e*7xyha4l%i746#mKt2Y~i5+Kh` zBoq-Crp%E;@L!k4tCw7jAs$rel#AthjR`WCQSN+_!OV>X7F8~srl36!A4jG5x~5Yc zlN(L*@SALdDQtfSH_8J5N5OqwNw1ip%mO$AYgMNly4#fdSB_^_e|*w2XC|3b;6z9Q zXUnm2Sc>|=z(-gIn6c(2O6j<|=cifJQbM3r3YSx1q6cP2RCztKN@-bw@01GwIi7iOf^akveI^l#Fr1N zr)6`LZ!1$z?3i19NxRSM%eF^p5Hnff7W0BJ2M6RU+YJLwc7%;EqN?SW9^=B))7nYx zhu%h?72`0ajF^k+f~{`%{qJtHQkI6u#Ky>dLnJMO0{}np0p~JvnUkj)jgW!Oc^Wsv zBkJ-9D02qx-@PZf+q)}3bTlEnZ)HxMHDoBy&}kMc&>Npf1Qx>ZQ&{-M<&dwzLFhb4 z%qZ5pSgen*daS-xX`X;T-!|@7);xR}D#0M(K$ob%tGe%Q3R`7)xy-kB;raJZm&b&M zyn-=W)J{3jZ@xc=*ud}&Ih+lOYB@`_4*O}bcI0X6T~@WQQra#zfC9-2|^np!lThtGcSTas{phFZ5<~vH+29w~C=A5^+M+Ik^>6)9sFLpdYRUy;I~_ z8cH2Ro82HjC#h0;Rm1YDW3_2Goc23rA$?HSFA^W^&2*@`@=QJN4sXh`@7j&gzlZcO zW`|KsQ;Y2%3xC<*2Ece9ijdvnSDc0|1c(@)BZAd|q>XxY^=;)t8(HAU^JUnxkERMf zVOa(mBuU;v6Uh8e+JEZv*1A>%|7~LbPa-0Amj6h@G$xGNtTUpCJ%7T`7v}xj<;`ga zfu8{Zj~i+)VnjoX1kto-U4fs8W}upDx)_OVr?e6*aC5ufM~$9kA%R*)6bf5o5U)pn zV--?g4j>lpf$}AnY0pA}6VDs{kPz*S+z&va&eMP8{^EKK<5!qr0WoD=BcT!+u?dbd z4@3+4q?K?vaV9dThQ=_>!+fI`95tx9|}rbx|i*A zhyIG3Bq_^1lfEW;L`U z^v0{0C`N+!bE4YDl+#9cnz{250)e}hp@^q0WN&6>|f<3q}Y zm&9LCqb!hF84!NCa-O$8&7Q3CYxvAO)YR&1DTTYEmT3=i@@u2t4=6KFDx5UBGFh*1 z!=p}<29XWmuJh#vr^HA?{fnH2r0woafjUKrWt=|Pv&mGhos_u9gyH#azYpn@y55us zj<@ZrVw4J8i7}RMA90dfzFNM(Kf_i>o`S0*K_;Eq;ooyw9ziXx< z=E!^y_HS+V5?0gH$Wn-JE&*C!0fvXBRFf*6V@Vu1u?&z+;tM)A&!CtjT#;<*3Y%&{qRHhsLxY<*?wnj+pQe}3U!)$~Y& zkQE_T*njzF1P)32K5)elV)Cf`@0}{a(kxN(%GO7f=k&6@d(r=d`2YX>vN8T|QWi$e z|0oU}YRWjQi=%X1R|{T3Pox=7;7ZDuH+CL!mQvPQGK?p{kPt)D#KZv4#KnEQI4U3# zkOe1Pj9HIY?eXGl^63khp?QY6CiDmpXaax7o3}5hukY zy%TDpEI?r_d|0@#=@igI_)t%So}}ubdtmLR_S=LbUh3nat?PQs>8gm=izLmYlUNYC zclp{XpoIckI`i2m(3IQBNPyq^?7iut^fe*lZxYpuB(o|`h`{opCHwMl4u&kSZ8{Sv z5LCWq+S5E0f(kOJ5;c?+=N<7#s;SXIM&U%sF=w=B77I`Z)Y+uT&_V#8x?kZD*B9#l z$JjeH3l?p`n%lN*+qP}nwr$&XZL_v*+qP}{R!2v7+!Jvg&cpfx>tT+JF*3iTqTlPO zs6)U-_5TMhF`#0{h27}b&=-<^Z&vN@u7tw!PeupFk^+{?i^G!old(T*$x--#Rr@&V zODlAcqC%7Shl7+>c@~JN@Zms;hkz+x+D>Dntd<22bI%ISb&t&yt7nV^n9?96h1N-QwZ`(Ae^~wqt zZ%}Zp#qf{Q6cEoeSq*k46oVtKoM&-C)(iC|loU&7L&o&j{CPz!pO3N-9tX~3~y%RRgFkxKOl z3W(P7n6;U?ww&F^8 z+x*&~pR`pC_mRCM%xu@@ZRNNq#e^ zUUU^;d^^cczTbx@hjLsvU6Se$ehxn$(;@ZKic>J*y)<`t=-2%2I^Wf6J29rmI z%WQYb=J#Q2SC1mNiWAe&&>6=}PVGlK8mh=4;VL{|(#s{!mN#R?or{XM)gP{+Q+=F4 zq*LRhqGa&Yh%oC~%8SO9@RH(u^d)sjNOu8}VtP8;Xg34>lUrg~{o`>+XJe<&Tl^_|wH znQ@X*V29P(yS1^v2b1*|0$<+yj5if0whA$rV~?;q&?1Fjs$#?^6T z;&z2IPy>UWXq=jA+wGG1(=O9wjSRdMGK{_1cM~D!RvjGO)^(%3?<#oxpdqr|^tA0M zr+m7ySy?37Ai)a~pbWnYTrmG~A|&p50`{Qm3_lfUz5OnRQ#*VP*RteGZ?@Y*fsM;< z-J$JY+0{k8m)k@ExNcQ+g1dSu4^bxc(PucayE6?GGZevIkOLqjj=UAg22xw z0_rkn{O&8NB0Xo{O*m0s^ftZG_`wtGF_z8bp1uW{&n&-oDx1ZdvQ1l9yFWl#R^aX{ z?utU@3RDVQ#iDPTT3X(xN|EbZXqxrQJc$!{A<_MAS`NkrEc$RwyjA@O_Sw%OsOwrs zO%);nEVg23VkA>9Fzve^IIE)?sIPw;(kV(ge3gGiW}@_-%^Q zaaTks)J5P8Q^7O@<xDr^D1n~6j=wFIYU*s)7Fvp|_=IH(~U7N{T9pGF1;V9f)-fKg-cZ5(q` zQ&1E0%Pf72k^KgBleI6LvTrTKNm4A18Mb8)s;Cxe@KPKN<+EP)?H|J75O?!p#9U%# zMApU)op!@lCqJ+)Dk60bF1F4{Vi3M4|CXRJoDVsu0;7K4qyBe|+8}@%-u3D;A~+bp z;fX8kQ@_@Q;$9*+^1hf71z%>L>2cgx_)l6U`Xh9_vzbNDXV~?Z1FPFU)){R5{+Gskn46s%$J@iR<5CVXGz#kDNbB z!j40^dP_@gi{KN=^>KAVKc$OkxxKKi`D+w&e98Va-T=ng?cAz*|4ytol}R*V za6wtM%mT~oN7ll${J}FA5+TYMJx>o%j1Dm+F1tmOu2sP~A#>C`cp*H?W0`;Xbp0BH zS1%OxNbCbf^hMSHsZL*?<@fdfSK%&A$U+q*c1&`5`uPtRbZK4?g?!+&7+s;be<@&O zByhwA7829h4VgoZELG*Vy70P9>r3}K`&>%5iH^lb`@loD+0nJG;#Oh}!KAbA?B4Bx z--JlbFd$EvnEPC**2r~K9Go)`$oG2fw|u+lgse2s7Gf<}I+euJN~eF#_G!yphMKT0 z0gIVSp0s&OQ6qsW84drpP_U@MZqACgC;7hRYV(6rlcr>f5WbCbXJ^##`D;y0R~@%@ zO)dY$Roj-@fBdKC>fE_~eQwZL+rA${%(y~9M1Eg*wbY>PbK5WY9Q4G^RNuXop5@H_ zjk*T>?oxVHUE9lYDsI7VBR#vr-4b%;ktMu6Et0s^y8o-CrwaR!#^d`?{^_NDJJ3Lz zA#u#)Yc_1Bc49^fV6s53qE6{qr?wAF2YdMA({_248tZjr>%TIM#ZNELL@KijsS@G#F!`nZF=`rl%}7=vM`$=GvQphJaoBr5J&) zQ1=dfp;hrvqSKm(`~i1tX^R%0adDX2T5F7DGKNy#+927{Zh1z7ky9;0Og%fe;7_ES z!efn2jlts+sw@eAe{d{WmfdqPy(|0QK@5=~*Jp_|o0aW)DzhRwnzCi+SQ!%(OPz(k zH4GoNG3ja9#EWta1>&FXPjN4(ytmxWDnx1!HH@}rN?lrf3je(A7s%teinvAO7OD3et_Oa<20wCr>Rb!_@kx6h!F zAv;U4gh?7lX17|x$|}5>T7jprXy3+YjWM6uyx2^=)fI;+4<1Hr%(20P6>OUWbzeg) zi->mBZ9A>S!>b|(O^Y&5?~?xE&FhNf6_Zf8K5*)RE(kb+IaIWmHpF<2A*r`KkiU_> zWmsQKO!K3vJ8AQQUydyY))C~S$Ccv~>gTf&R0;k$^lkM|B%%UE3_^{l`%|J7&W>xL zs^iNZMJ}bw><1O2547I>pjRS|b3NU={PG--YmJBu`7-m*EebeB4}`}KrNL%l4mg2l zm3dkL^Q{R6+UBSbK{;@_VfL=|raZUF8%_7L+jYObe2BBwlk;&II1z_|@9_ctyKyHDE`aDZ>aQ(Qqg>^>>u`?FF zt-VMhEiG*1(MO{pTF1s|RdUva{zB1FKH2m_xS5vIsYI`h$teWZYQcJb&Vqt^#Ch9H zU1u8yn?j~rFo<^Wfxwh9{((jLLGv6g{4Mo)5#;j>h|d6mvSefGa79IG(cfRu>-_5r z@zSM$Q_L6BKQo9SO-2fW_C@i5DfY6-*3^I07Pym39g(F#tBhj2z#E$S7rHPho==77 zTOnIq%7bXe7)C1hZ|hLhv{D9K4kP|ALQJp|4T53RA!Ke|9DUrdHy3uv9mx`UbvsFay{(TUVlO~ za4;XO)4o9x14D`-Oo=)2VM(F}+}^zl`#mFn&V)Mox`&Qd)wGg;E-ZPbr9~+1A=ia` zVO@De|5}&9Wu$IT$jQG#9fs561vc3BxYziWTYF0x4=ADokDH??t&FYb{kuJEj&ct= z1lX?yr(2N#HJ|47y8SldM1{`!Zp^G2hT_ZbzfiW9}hr`i2-K~t~jx#%jeLHPIjVlB z8L5!LxzUBF-SDM^zGQ%%11hqF^u7wIPSv&;j0-cfqD2+dU)kQtgoA_ZRwvV~!d)n} z#_c8>jExGU;Ivgsiea<_Ng#|ZJc#d+lkAC}HP6>FvXzg}aqGXgKgJD1NsNmr*|elH zX#KdRcV6R0zdx>SxlC2OcT8LdO&cyu_LG8W9B8oGQDu}gr8GDc^Zy?A?qWYN z{kNUe|AZuEVq^c0rE0g9baKuZ;=dkW2NR>^=I3I82I4NbTdo(!yV?_zczBp;8RA6- zAT8#Ow^r`P%7CKIGdo@(!ceTr2E6xUZp9})Bg9aCngyJnh4M9V|IXN+UrDi;q!_dL zYvCc3ag(P0K$4E_AMT#*RCa7a5uU3`J8S&tmUT7ZWwtk}!-KF(5A^|gtY7qBO5AN; zIiDeOxXEokU2lxa(kAJupXX_RJO4mqWoNo{5k}`5<8=G!rB{B&3ta>X4=5di>0X@v zAV9G;r$>KCTL6$K?jWMSfn;8Kz580D?)BZqQb?GNMYIgR(6&AMB(nGV;!nbR0V#hI z13R-FkrN=sS>%BI{{>ImU~`iaLPWD8PvW4^ILL`r+MIi!fdJ*F5N&or*w*e;kj8x~ zcy1?ZVQk4L5>JbTBJl+4yaG_0hAcq%nqJwlQ-^LRjLP{6CNdmx`Ejyk|+DS&=#pM+&jFj08MY>F^4 zXRl}Z@H;Ms_vepge@!&3KNqq##Ym6>w;2ReSh!(oMEm=}%e#1vr_pM*f)=0tDw`_y z*PHMR?*VnMv)vobz(cX8VID+wn6b$u0<6$ zNGb`^PD`+jJ1t8!hGvneDSb#tHY+RP{-y=n+u-HWyhyl~hhJ3u6M5GRR}Y3La;vF- zVz9}L=s>WV5bLuyIsF~xAyH7aIo;v&8fbB5pxC!tAKh83#qmj#*D%RFe;5c z90nAjOu;*Y(euQGSGT+Vorn=n-OXcnM?a5>3#wbbj!Z{j4PS~d;q+C5qp+93SS80D zRZfEwwx*nUMDvcmOv0Hl=;wBajO6Ut8I!O0hV68ND9|kk`+||~sbI)6B}V>&Lzp#o zg86LiH)<}0_)6;6V~Y!Or~)payKx&wL?U5G_T>O`gXyHM4?esO2LB2dX8W=Y+Lx2 zoVgaFK-t)ChQo(MCli=(0C18na8joSvzY*c2Fp%gz1K1rOzMJxT*=|c+4PiA?nBl& zzrJ`EdDoqklb@XSrvB=u7?hotwh`uqgg+Afxs8u`XEF=3B5LxAUr} z+e4-IV0v5bd~d5tF)j;&hg54K9K9BeM^GYtmiR!RMJOaJaRCYgx+Nu}EGbBXxLXDQxk;J0qgM4!OpvI@qL-K&<=hU_JNo8blQg6=aOPnh=;n|nkl2-OUWdXOMag_C!||9ai!P-rk6 zBGasZppK+N$YwMrwRj)nK!(_6>n@!Q65NNI0DMhV5zHuz7DJ*TRCJqg=`j&kY`@Kx zt@`28KuxR8jrw*AJr`;HAilU$MUo{s=m#8{o~K(#3Ni8JKaib`3xut&I-8EKlLe}S z)(X?p3;MG@*aw3H*q{fhKhWF>HflXU^&*d78qgC1zDDtp5z55m(xNXgY+_deek#RB zYf#eft&=)_KPF1PJ?EDMDa@Mln{SwCwk*R|@k zTXkuqIL`D_P044lLWoiRnmj5%Q-^yvpxR$0)0&Lqa39E8Z;D77cdVGQVYnbfe1>cid)mn?G& zc4(%NaX)@hFp!Oij%r~K1&rDB>?r>_w)BKYad%ujfSmo7`h=KJnxg3)0>tjrI84;S zOGb!qiJ8xu6UAh9q;0}z9}!oU8NA(E?Q{2>VoTcU@A&v@ztVO>pylT)0uk+Y;@M4* zvk{PQu5vfjE~!9G%PpqyP$4;?X1i`)&x6BC zSSFU2*0;RWx8kx~k4VQJo<`l{AlunB%`R#Nh4$V`au9Z^%!RT*1!1mwGbYWEu zr1Apq)~U9C}OS3Ybsy^3s8JrqG?Yv!C%;hD1G!EhFd1@gtKzoht-ca^-ZEA z9?{;1gt?irtrrtq?2rR03~9RH?c*kjUh^PQ5i&l}6Shb{hqh0AL`2emP9sb!C@WG^ zNG6MXhbS!qa=B*v}&6z^kOogAM0gUC)^?g#Mc!ebH#UiyQw=D)zR@H!$ zY~GiBsu$aNma{_2T|Ov$8gvp^I^8^x6|O*(^UnQlgW7*|U~q*#oh?(e=-d>bLs7*l zj#bUOAR~PTJ)+Ww$cpCZcKK7i2kM1;6xXJt1a4>)$&Q_Xt({)SRh$HGuB6%@qn*&x zLDF+my}hm<61GSQ@&tT@D(O?Z+9*8p2cTqvIP!>Rke@QJOPG_O5HbQ}L}!5W`p}Fp z(oIn|L(mLYQ8~LoieW!6##4=csY6EO?=PZ%x&P2KKLdEuatHpWFrK+r1P1=~3=jG=E0Hi{k-CHk? zIklL_R1yUu2mrz-fa?w6jv&mRM*{R~xc>#i#~=6WhMsAUaq^I-Z3kSZUIz>j?rhKN z)!DI4MF)SR3PV)`#m)c##J(!;Fup0t=wA^~M z&`K&x>zRdPYI4cdo7BZapS5*Y_xtg~o`7%`jp!sN5=LYxMw-~jto(prLX&K241Y^v zK;)w+@k;ewC+m47_AclAh?@STL)*1fpR>$_3)*RziOHwARm4gXrBMcunq+OraVi&n z7@8>YFGszI{rEi}Cl?0}jXZ2s3@KL1v{KSTcf9I|lEzMA*K;H-21Chk&%HzrW9H_n zp5c9*b`U$>PnM;v{ve}O*Jo;@lG`b^YWeD;@5D3PbJz54@{Ex%#yv<2Kok z7{N$3+jmw;P++3DUTc#^V!GRWdB^B(1d`A%JPExlXb`krfg13DX6_fACv{9>WAS{v z5NArsA)Q&p=5Y2}cD*Y~etu}9u)y8Io2q-g!nCt|6HNl2Z`_FudMFyI-;B_z@o==* zeg=lI@9#!$)>_y}d+`;y$2==+FRQKxe#7u`#qYEFRbEt{@pX=GIq!jZDAJWyyX<#4 zmJUS*E^qW*K+@o_aC-TI0A-r)zszg;tK`7B44}Mw^Sd0nVRROexo?E*5Yw6WKGH(E zTk>&A4|!fKBOGbv@fy3MqZIcl2wGcq*Ybu|LHE?8L4h^9NZ!X5}pnp|OlGR&#Ass`(Y4!Y|?M{zCy<2LU! zY}&xtc7M|H&bj0OG?*G%qZg(V{D}LA2sS#DXK7>A#UPBe4X@(MMju*KL==~63)_;q zn0_>IOTh`F3QDZ0J}#lmdWHI;%&oPYDR!hdLFvi&#T5X0Yn7#p5Qy8}r?PLx?tY#P0wRk{V*4KzTVfZkL z$}z(enfK;JP)^BYb5zd;5~|;spm$Y8N9Jk+x2U+LZ3AbohxDfDMt>v#eX5Ocj+m_q z+a+eqYWol;j!K9F=Ew9n3>=W`wT<6TnOHtygb8no z$U!sotPHH%ZGe$XA@K}pJ=}q_*xTjmk2tnrPqzmat`oeuP< z^sweA((0^h1kk6`3Ys_+kmY%1YmNrpdmj7#v-t)VvvaJ0xR|^{n~#l8(EKfuGYz8{ zaG_GHU16h8#~nBQRjkcUAD>W*mMhkIp`7m01w`N#MVGvE}ksMkHc(AcV-I4q-nN z4c}cUsN@fubRZrA9)J~*#M=&$h)I%ZChonPD!eZE!=?$9#~4I_7ql0nsETbuOgNsE zQPvb&;?WvIEg?7;kr6=tiq_edDkBwWt?SZiYJZOkE}r%d6||KBUX@0$A>ZsWF1HhBSGR0?0TnsN9^mR z#jKwoc>rfHj4nwK@UYI`Cb0lYdg^>Rz4t_68mYx@^cX2(lz)hGO`rIva@F-JyE?91 zhCd4`b4qs4zSCZ&8l=UEpR%{Og9oiHFV8d!uRbo>rj?0$1x$*XL5N6q>4H}_kGZr4 zL8XyXG+PWL&B^XCZ;od2GCA)bJR31uda6He4)XlBI2iAjvyRYMT7c*k02H9hqA9Bn zzzZe`BZo5^3~fb^7=jxXLH42=8IrII-v9tpPV{Zk>D_o!MsYtJHn!&|9EM#2W^&H~EslagYZ&0ASDEmwJ z*|vuTk-!cS4*IgRILr060&Xov|PEr zB8tF*l4b;K)IuhszLi*mjQoYVqs0s8@~1(Ett47F?^5h7p<;FzU8_p1#9be9jrkXl zCI38C7r%;%a{^1WnnaP#DxjU5HeuMB8{b}Y=ZXUM`esAWcuPAO0UPOMPMm2n)GgN% z^R}>MIi3}Ysh6B4y*0|Q4Bgfa3V(Z(ED}Orsz-#H*oOJ~HtP1?sJhe7%=dnw2#-$qTCYcQWU)hBkIs;2Fxaild+&JP_$J^xMrNoY+smG{#aB@Mv0 zO~GlOP8tXNClPa-!sc0;llaG>{SWA=#Xib^5lD>xqraW;KQQm9YMTF!!2eIV+}=}( z%BToLfcay};CQjCGPzn_W!z*^!gQPmNHG<6GXAbE4S^!lsN+Z;;@>UrUft@~^+P=f z|1D|IuW-F}5Bl_-M)oaaLTRLP+SNPGvHJtsD*kWvR#AScZU~d4H>dm62lYKU9>jVU zXy5I+L^AI; zjG5*;Gttgzq9lnUdWWP*f^#=L_qAQ{%xq*jD{x$&0-Q%0QIQWgN{If-?;(>^_8);o zzg}Z7xgYOK%e3D=ex9P?u4UOqP0g~rcnv&L^BQ~A!!$E7^;MrOm*F2IgUXnBOnHG4 zWEv6(m79);Ln#N=Pd8XPdYRZ>61#pqJbwoBytiZ0RNSr^6ag1Z?Mps{*v&^Wc}$t^ zf#@`4JToOyTSHrbE?X>?tnPj2wBRga3U_#n>sh$;stT7}`B!wUL5nQQ87Je{(p#+% zMG)NunwZ4jB|(<(9U{IKL#EE;Njs2l2w4&yd^P__tThl}PDY_9tC6fVU>#_=!zw}( z#a!5t3{V}-i`9!JkhS+ZF(%+WQSLFa2k;fISf(j`JPY)uN}{SLoAgv(v5REIe4+C$ zNf-B6Rej6|hM&xhw!ReDL&%Im%4veU1tac*4NeAgNX#bBvr+X5oMZTr$^yl~m{~?_hG-fV*zFe`eLS9;$6R&#OJT zwq3ViR}H?<>dFDATq80fhmLVTZ}WKno*x*|!Sp+!S4?Z72qlleCyxmC4y_p&pp#zX z3Sf!F+JD7(;$^8XwSdjMV16Ry5pmkaJ(Y8|VMe_fAH@#a$)ZdU;7xT6Ax}#iVRIMZ zE`Xzd0t}vZgw|t?qs%?ssO$?)FVV@2_0L2>q!s#bxw=1lboNcX526((b9a&a>^gf! zGM^BcvFo4g&^^i^kIFOP6C3UaedOAg<2i;m8DX@*8UaRPup_-X64zg4;mvWDPn;2B z9E5M%%8HT}HegiaS~GZFb*Bg&xV;yHGbeb?49zR6R&;B(1X^)Fs8O?D+GLAhxcmJ6 z!Cr;Wdwt!Gh`}_QfSHM50&obzQxW+aO?kgwLfu$MRIz1cTZWB9azmMsqc{(b2>VlN z6s`+bZe|(v?XPOt%`gaumC|2c3VLHm z*l-s>$JS{@`gOGaR&F5DJgB@vb5Sz%taRb-W^is)3=U(#Jyq&C9N@f`Mk-*?y}d_8 zFc5r3j2O*eO5}M^Nd^aKjU8G4C3-#s6S(yY9CM+|OK}KHP5>kgKRCVDA0bdSUyBLh zp=HWeld-Td{Q)-6?`p=ia6H6P(0;uUFeRVGifrx>DAZEuq*ThZ5D{upWiA1K4>Nb? zk&+Qj=b5n~unwJjT<#+_C_WIL$lYkLNS{9n4O@R>^xn8M9q^21sjEYM(5*9GJq;XP zT5o8QBbnJhQ!iZI>gM__IzLDmdVhGpI1Q{FaBjT{W)KM+n;?y5R@w(Jh(b6%GW&=IaFg^gVagEmvoAdDY4x;8Ju=$;Qd_$q>cAB3h!RQWGuAe!TSq zGJBfg$_e)2z8@in9g(E+1QgvBYQDlvQ$z?1PrkKe>5dU??ice4$X(V?5&qG!;PS-_`O3WgW ziTkuk#YdqVlyYDu)=y?OlQ_r};~R`@6l((quA@$?Op!zlZ;b#R4T}^D9F^XPbdr+O zNV(V=elK!Lro8T;cm8&g-q=`S4UyKKt(9E?k)$GzAsYhS zg^hCM6Brgui`Sy7thV|OLork@y1vx6!AGbMMRwqwBy6BK6kf<)<;6OIWq3(iTdudU zot2mO9#XNSYxoF(1(>2%f+DhXnOfo`LX6?F9W8*TNEv>)5H-8$*4iJ?hu+1*_c;l@Sk0~t zG2fzrQf>{bGKty8oy z(+h_F+O8geRlSpytvLq1_%$;gdSqBw5ZvN4sHk3@5r_{}7Ph`x8S@85DSNYlHU6_mGFZ17piNtmD|lHOCw z%9C-7uX36vm)FO|4>%oZ3V8q!q`+5k5_j>Mh{(n>9;KWJbRuQ}_VhXe@Y3=6v;1bE z^eyfzbd>CL*VK1?=VSMHIlpzK#3k`E;uHCCbI&>MgKhN6oNN+DyfI>PlUEiX z)XZ2Fe5?-8%E0;G2_X6EvbK`6xwy$Gcq7FmuEt5%D~!k$`Ug56g4;~ztB0agHlyHV zmf)pN^T5e_2~GjEb7#eq_nx8@Q$F!0ApqmVWu%3#BF?$E=y`ohc%LfY)g%TlhX?)| z-}-%4pp8pF;FW-C)FBD4eO9ahVe|u5<02=67enF8P=e6B5Nd}|hOB(tWvSEjYfcV} zKDFoT+3@j7pM%#811usDRsboZ4pSq+OIlfU?f@0c`vk1jU=q3GmJ+!_=KN9R%J7Pl z6b%6E*n4~p^fga_ismeGd!vAggC`J*lM%>8V#B;5v8ND<=0*q}@`b6215F+ZCBx+p zvaK{;saoLC*K6PmbI3bOC#w@E$rC7JDJPH+q+`87YznMFdk!-L zxl3?xZOv<}vETgw>=u|Dy`2S+O zhF6n0g^IM}4K`PcdK*QXHJvT&27OFhJfrQ832PPCS2t1rlDtJG)RFYTTiO^S zdXRIjIGz=jaH>>wr|*?O-ni8=t$*nxOh4H*YpJ^Y^!4*_Fl^t{)mD63Y02(sf8g_@ z1b#*`F?YGuff_|=yVc`go^7k{s+Re=p;Hf|oW_KTeO!5C?)ebS{RW{zwmu3^L z=1Q>|;!9!vJ?LlQoS{;D1*1>E^fmam@t5GlXIS3r+Mcdfd^E)PRnqKf<%)q&PM8sv zQz?efYg)_}I*>yyxg>BOE_fv&0^IR5GVcJW#IWNelTyq5_iH!l2QSTSZi~4g@7D>s z4eZL^eB}PZNe3H>v|^O0Hf(mee@b8Ze5ceLBNU?bUG|-FX1UP0w&C%nFix?dHI~*a zMZ1vY@Bl(MgD`+epqYM?66G8tQEE`4K>9Glin_goz! zU>`{H`a{=x)w8>}Zrip|TN}G&;AvsK0}b_HynUSfv`T_A7J2^wN=%ZnRACYE*)^4E!c3N7e$6d?R3uu_kHTz@FiQd zu}Jupj_QI@M=@U0Qdpkeci_oWe}gQL66hLZl(FgXGIjen=A$%h?UZLG1HrFRC|s~W zsAOMvdG~+{x)b+G?&kb>Rx-dergP$NcD(YUd_0!EAV1&~B}dbFkZ`N2cth8v8#V|? z&))w1p@Rns+O!!o!u3Q+y*Tl-h@ZBgY4Ti1-5}BJRb2mmWF$2)M*I4r*o_X5Ai~Bh z{tC`V$uQ(9;@hL{ZeLSyhD@f;nuoN)wheS4@etm#>TQSL??$8#K`(XT>ctIZdMqG_ zJPkn`9Cq{!+btzh!nPs*5w4|MXHfvdzrh*Dj~J^hZz3<^WfS0xp4JDQtD^0Vbog$( z&K6;k8QL4L_)>czg$x|tlrVwTfg-(?O$$X9o12hn#Iz0Uve{AC9C)|~@oJv@q$3P_ zQJRF@yEmRPAVF zjF-!{lQ&SRudDN~BS3`P-=hXE@r-cv!$7N8V>-psb*Q9{vCBGUN@3{|l8LjtZslF} zwU;w5_VAG+@902f5@=EJuILVrdH!;E&DQJP+{v=OeB^E@a}UYNmq3Smr8 zGbsr7^AhZIF&8@~-sDqxEJ1LTc(sjhFf7Da_?{3O3l3Ahp76Y$kShzW=H-vg*uSR_ z45f?_`G}@0vUt|=39oEF=kEY+8DRXs_*nheA#lu_gowbj16D$8 z4w&B6Rp6|utsUU?Ta3K}%i$;M)i6_bN+fRpQhs7qypNa_;FS{#4)yUVdW5U*WV*AF+$E2TbD;PM%?N0AhJu`aW}+j;?CjNy6$G zMr1EKv}wZEaObLUdi?8I_Sko9*(h$A__B$8e60!+z!7m8h^H$WV8(X<#d_<_q#HjJ zg8WLv2Z`W&K_OrP|4j}eL91G5)E`|mHYjBh7C3X=!95NB1e`U*l)+dYt{K9DuS~Zh zxVuBqAwArf^HHcoF=AGuWOU^LO&Y#%=!>a-a_*BL0_^sJ8Mrosk*q*z z?I?d%4wB%#z9d0V(QV>jO%aKZ9%82QM3^io$&9#hyeMbx^s;dS9!aocViSkoQ!}d% z(#Xj5v$cwz?*o1jW6z)eGUJ&4x8Nun1MB~N>+IINv_EP={N3p_>UBkLHjymWTP^5Y z9xqwlp*9Bw)Iz7IIrd6jG?rf&ahv1kW6miQsX2aR6@bFl;0qh{{4(PxR?Ao4rwZtG zNEN%oua5G1UaeYwuW~^J^TRu;s=}4=UXxT)-}JBP^?%&Q$CfuS`aT(a-(1Bn@3!vL zg3b2V|HfUBGPlL}Y!7+P#D{MDv8pqaB%md>h>ZzaV`4fqmG6xz?eYD7IVO`@MNijL z_1h3x&*GfN+P(VOM!kHz_qKCsEmnl!`tXbr60Nv%u74<6lR}k?cEqK3M2%$H4<=H) zne?e0b48etN{%rVHXhu8;-^H(r*bJzDe?F8y!Sc`l&Xs*z`I3*;*XoQ3+@poGi0y@ zzb>+!BLcpo%+|)Lnh<+kvT=Xfyv$FOajz^21nh(dUqckj^r-qQqPCAg@sc*)s?sX% zePqu=8UHwLf^U{OVK}R$!)BekaPU=!^UhmmuCQy->wKKjQekm$rEy5_zEAa13*s#KC@5w2rQ4K4k%uzJT;TP46Id} zCO>gd2xTJ*xx7Vz6cbr=v&q?PIJb;?7L~-K2JiG>1`Sjav3Pz!vsuaN(SWD@0eWf8 z($T)bi%7De5DQIQb0yyYjr5Q<3eKK6%OObvZ-NoqOJ5T$xp1idHIJZ8wydiWwES@`N5IN zrF%*nOb~(6Nd!{*@G@4w*}Mx?1QKGvA~pB}qQ+`4CKgyoxnV8_sq?3e8t@+3edm*R z%5BkNc1t5yd~UrNRh)pZe+aNm-s}!h6a*Y` z|nX@-P50-d^ZY-Nf#D0Q>_~vJzK0#W4f6bTKO zWnkAckO?MoUDJwZBp7T66BuI~1`q?Q5CI^}5SXArH`|Mo@~Hz_Ru5(Y@^RdP-8mi* zl+JuaNj`f{=V|8Aj9o*Iym?(NK}WNN5l-7f#Z8u#1XZ|DAOy)$uWbBc=w3@C=$@G>I;1V0PrZ9_`r52EAq zJYVIMGga#*LwhSUMzmB0wHIh7eIVQk;0IU@7`gx_=q96{y$Fvxh^j-4edH9hZhYi|u zLZW@}m4ao%cQGPcrH+;r(357h1d!NelY~Rr{zxd63ZuPXwbtCqOT_Z(ljpFGYbJyP zmkBr5b`nh#89ofs-~!_DnEcBJJ!hCy6q64%e(H2kVIVk|UO1R~R~E3jqH@nK2&e=? zT?z^92tnY*l&3uQ@8VCm;cN-kMZaXjA zEdpaOOb6iv%IKd}%p50ng& zka(>LHXG&_gKDFFdIn9{$eLMBP61P;lTX%MjQlHe<;-p zcb!?)`)XhZ5J_@ykdidLtIE#=Khhw$M#wZe&{=_E7(sZxlw5? zq1pjH5|JL_uDKTn~>cy>s;&C-k=C1SS^ zH(x0whrfGu`Q*L7@GV-2Z8=(sPSc+sX@BHXZQeUo8*)Dv7zZ!xYiw}q=dGY2iHD9{ zw5E>QlV`+Po#@0(5!wt>jZGD@%xQBpB{t2UR02Wim8PoLHD+A~pLU9{vmnn$IbVTV z_e2%qOGb;d52iQ;1;M;@G!9ZfGrxeS1@<*uQ{q_5Ez%0{$>>zl;p-T)LcKjWXSF8N zv(C%k2AIiDT)ZgU3G-%lX)zAM%=!oAgXY^tx?0Grz1eT%8xhO$kzr=^#@#0CjiGOT znI`2P$yP7_)RU|u%v99uY;=M_Td>FKn(wd1)&s!=5$HH^qG&82`5HqqrOQU>Fv;Yc zaGFFyw&@78;76vAMvchRIiMYcPRN%-y;(-aK7n4@NZ#NxOHyR}CQ4pRIv71nBSi@k zYb*a)_B&wu?L+3w3Xx9+SCD)^CN*|Tkocvw(be@#94Bn?;j5~`9R^2x=y)4C4utRf zr*+W{NOoNkM5XIhk%9iU-4X5&Bf*HoxR;$866A*pK6v*N_#uJD;hq46D~D{+U`TyP zvOTh>pysRh1VoSEj=1E2`k~ZZsAiP-vAk3*A76me@f#^{$}>Yr=u43RxfDOv#ffAG z_&$;_HbLsC?u}p-Ko|!_D}7?JXzS}JW+y%}QYx{h%@7}^4ns-P1AI9D(NV2VK z8!g+mZL7<+ZQHhO+qT)|sxBK{wr%s&{?5(+M(m3nk&zLZv2x{DGjonP*BB3Y!!i9u zw2Os^HS}(@Gp=Ea+f4fRS4H)zI9b_9jKN@MDR4rK;1Q zZSshseHY9Qt;Fbm_lrHy!uYyXQV>#|WPv6}zxD7BbX(f8Dx`<|Z=e2&SMD}Uz$`mg z%c9ZEA`&!I0DSJMER(Gx@0u9(XJ*{wIHupYm$D5ND@_x3bivY^$N##amUcrZ`nNsjf8!7{{;&7cl!ivq zek(^*?Mc4?@8q#^Fv)U>4SQny?%)P**K3RVQ)JYDntdlu}+Vw))xeHSN_2~|kOY{Y#}8`GGz9og=R zY4VoY9x0KeIjE4P}B>VBYF$PY$~v8jXm~j+kY~CY99n+U<`E^QVE@^=RsGD?0T0Hkh2ecxqY{vHey4 zJb8NloH;hVye`H;KulL;7>-G9qT0gP?{Mcdh3@G`S(y-IE#G8ujogz~^>^fxg zYYw)g4$I1-Yz6cxA2~37(%$h#CXQ{YlkxM zE82c_c`ZWQ;8h`0C8RPQ!Mip|6ub{WnviKQ=ER4^rZ)&;B5HFU3{c6WBl(vbTUeq) z4+V|Rk(;^$a#KRA7Z!jmA6=(((w4?t_5JF@EDtv z=HuR|QP-HM3W?A*Yb*5%^q~gh@ZUL$g3}5Nb&$Awed&efr+_P^@<+kyN5@_xDRZpWT>*r+7_Si<4vM^q0s( z^d{8{X5V?<{i^5H4$O^~KUS?>U44<8?{Zv+hD+Ro(w#@@ldDjo?|Gf0H$7|CRa;NX zgYs?#>sjQ9w~H1iG(1ksT@aO9U`nj=0I(B}^(VS2 z*&U7WfG{Z7vs_hE1WurE1;Gj^p*e-Kw!cONRfO>095Le{E`e)iyZaHH7z2Vk{Lb9e zsl-!OX!xXuM0^SnWtqDo$LlOe7m)?A4&?%xOkQe>4T=WEd=`S2sOm#|x=@;feKgIh z0yKmAahQ2{33$HY^7%zc)&#IV-dJDJBKHfpY|f!gW=tliwVcnxA<=3qJWai3Xh(Y3 zcrGhE$ZWK8juJZ*man=9!KFOtsZLreQ8TagAjB zt$J5sxb9p#vB!^Ft3;WG7}=vMxjtUs>glLc){e$EagV`vhH{*(d*?+&R~l zqD-&1c$W*{;c-n2Ys%PXr@x^cxPgPKHZ}3rV5WR-Ro`e^$O>VAadMP2^e1OlCCRa& zy^AQ2(c9w|T$3ujt0K73R%^wB*#8C${1(jBwNXPDUGW51lmdwEe^)482BaX78kZ|I zEkj=OGR7l?=A|{#=wVRf>YY-{R?`ln@ft!xCs0}@q~?_34JiLp{A`S`uclA+unm4> zro7AS`!x?Jl-ZvZMIX-3E!k0e0ASWY2DN-}ldpPKy+<*V-dDINtv^$b}EDi8^xloq zM|<}>*#rqy81dF`oEopb=9JHRGMwnXhlv>ZGb}IjYY=SCk8{p%9OX)~_heF9?5zT2 zm3nV0*>@6iKJE`|+TkXOXTulJl$iv7rH^3tb_I`(>|^J6ri});?BBf4rsL>}23DAq zr*Uc;p(u*y@Qi!TR)Q``gh1{%D}Ty$yqy$sfHzGZXq|;V5?}7tfJqqMF`acD4 z6>D&Bt3W+c+SntbM3dcj0>hHC1;B{%!m5-`YCtOdS7j$?H;G&+Z4k=C@tO@I(U4NF7;B z;UcFo2ehcTCr?r0taa-w_UVP^qnh$0IuYWWo!xieP*j_p z{q6f<*6a2%9}w`>rk;GF{fnO{2=j9tyJe4lw8*+=?&yg@u5p4T+C-ttd*!*Zkp`?u z1ZDw{uqbCN{sd&wQ+szFy??i6Dm&w0rO4K1>B&RnU}dwHiC^iBxyHWAPj-+}nMz_| zYD+XPSu;`Ea&s{t%~dse(U3qGgU42> zK&VSYoWb2MsWps;Z3njNY4kuPRV0apIkc0n3tw$=9q={02S8%5$nJRz^xRWn*Jf!} z1nyl_p2`MQPVlPG9OeyZI0RUOEZ&Ez?{d(W9h!d}kpdf=_UPJMW$(j}=POMxgGmIB zB6Q%vEvl<|up7J=19_l9Br#BZqr%^o3~@yW&y+2gyMSD+pHj^G@Da~OU`dhC5ogc` z1ySSx_EPw%DIH8kjl;AL;PHiWR~JAWm*G=(#rEPv#0eom;zz{}fexIzdl*kLBkP6A z1CrxXr8<$KPnFDudKQC`zYD3kAYSXlQyUF$+5^uuH92rFF<>G!1%0*(H)C6vmF22b z+i7Qa)UH$)77Ex*um+xBW*LU@7tY_PyH3BXm4X$t-u#VAjZjj_ElA`FIw&16ZF;ap zPwSl`++)(msI6UT2fSQZ$JxZCjURjYus@bt+hx`p{}`y<`gwe{g9Us*IK;!?oE=9s zzION;aPE;<_q`g+3oKh?CgT~BDTHV;^mWb!Np(5v71E1N-PF;^6DJmP$bRy~;dE+` zlK7-Zzzb-(WumqH0m^TwjP0X<7j?q+J=_`Nyxu%2M+Y@^X!KI8{rqCLnY$Luyz2I1yq?UxeZV z9y~l}Bo!nTHL0fc9V0V;4`=A(LK;}|X7VY;k`~g_-~U{TEvU$S@WrV8^<&e;bW5wH zufLl1bTcD%J5~}x!#~riklPe@In1Y>hfL!i`$BqZ{_6kDp%9z?(Tl888XF3vN z=kQujbxUc)(^EgQ5XlR>z<=l13cI}a?DmsoG2RYIr=R?p4l`yv2sm0UEUO?6TUv)2 zcDTc>`nsIg70+foE~A3n@gdPwF_?1f0zQ+{?6n`}$z%8N@JAh1#GjOG&!y@|XMIr*hFES;EPX8O+2 z7@aFe;r+rgeOYFFI>+!D#_$620KX8n2pv|z6UvJT#UCyS;(=C$iOtDxtrwTJmiS}%#cKKuQeW-it zO2h~fnj4GPkR}$&18t-Y%!lPybGMvZha7tck&HxQ#>nEU4e9Z2Ya-uY)!$GRfvCY| z3p%97wN(c`YLHcpd`*so=^HLl&~zrw7C@JXwwU+!M-5ynwJu_WvY%EfzGMs%WW0(9 zz%E5^sq%bb{2w<*X?X}GrCV;EaOA-9U>QIwK)oX4h=`Q9r*+#O(23T*;QzJ^{wJ0j zBQx9obbeAYbbgjWl+f#E>R=sCbkkP{I6k@sI@(4~jYtmQNKW_U_9~L#$DOb0OZXKSw`8ihf_^puDBf=c7w)PidTv|HaoE+U^w`*6u&$HK) z>%(h6aNunIBLV_iA=HG4nHqvj`!UzfUx}ViKKD0rUXn9Q-MGzTvgT?Pr`jP!TPhr} zwSwy%P-5Lx;o-G=uVo`e9nDRTQ>ER$pUKm_epkV{s=nRm;^=(7n?7r`J{Jq#+pt3j zM(nCJ{)%J#=JdTke2Z;vJJ-$g^YgR@m3S^>**qO>*Xt44kMY8fF{Y^`|KZSzIftEg z1Gub?-O1uHC|rKXCL3#qBQ0kyeI+ABU^dCv(pN&ARUP*R4&J=#SN6XjE?w4wZFZ%m_r3b(I}voO`SVa ze~Tq>B!DVb{^sS#QJp0e5}|g!HMu24>eROCv?W}*xeeVKDmF!3*s$k~KD)l|p2W3u zQq#-9w_Jn7QE+U8n7gdIVdD;_CIrFKmoi0~wk{jE5n92*uGD)d?H9z9qkEBZRsVI^B z+oOz8iSni>kz%M98J5II_xD|ql0v14US(ku=`o1(3|wjvKD8X5=60c`?snlPhj@Y4%sGOP=vd9)n^APEr2927dv z4>%u3X2bbe+kKc3ShEnBg*>AbG_%+|(CTOrAngW3)_#Zu#Xa%>aJ`F~my96_JuTTPS*!X=CU?e|DQ-*NyMfrCwLTQ@3W-JzKdrV-W*Lzqb(oXKtoCW z!eoLZn_iL9$b{#AzJp-{T8J#U?Slx}@Zg^V0!;-`(&^pCA2umnqPu2f7iAqcl_COY{>B*Z1Y{<%O!tI~$PWYnsfMwj=6&WTOfe>a60bfX{nP$F2_ynCq)f^C>AL5e zh#&3nb1jh(eTx))t-g!^xc661$S6w0Nv%H-X|bkbxc?KcC^ICe>68&d`~UxPi9v(^ zX!|rde$;5^pMbe0g6SBnT9Hv0Z~qA

s9~sOg9j!esLQhJIC6J-~v>7FC(?{-2>v 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%0AFaKB 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 z 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

a(kEEArK5%{j-9m&PM67w$jNg|yh2 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öhG$tF>!89d$+$;J2ew_krMRZ2*V5RA`>Uw9XMqF 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

T7^^|zgghqWanB#-vH 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 AzyJUM literal 0 HcmV?d00001 diff --git a/resources/3rdparty/glpk-4.57/doc/graphs.tex b/resources/3rdparty/glpk-4.57/doc/graphs.tex new file mode 100644 index 000000000..cddb7518e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/graphs.tex @@ -0,0 +1,4150 @@ +%* graphs.tex *% + +%*********************************************************************** +% This code is part of GLPK (GNU Linear Programming Kit). +% +% Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +% 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +% Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +% reserved. E-mail: . +% +% GLPK is free software: you can redistribute it and/or modify it +% under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% GLPK is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +% License for more details. +% +% You should have received a copy of the GNU General Public License +% along with GLPK. If not, see . +%*********************************************************************** + +\documentclass[11pt]{report} +\usepackage{amssymb} +\usepackage[dvipdfm,linktocpage,colorlinks,linkcolor=blue, +urlcolor=blue]{hyperref} +\usepackage{indentfirst} +\usepackage[all]{xy} + +\setlength{\textwidth}{6.5in} +\setlength{\textheight}{8.5in} +\setlength{\oddsidemargin}{0in} +\setlength{\topmargin}{0in} +\setlength{\headheight}{0in} +\setlength{\headsep}{0in} +\setlength{\footskip}{0.5in} +\setlength{\parindent}{16pt} +\setlength{\parskip}{5pt} +\setlength{\topsep}{0pt} +\setlength{\partopsep}{0pt} +\setlength{\itemsep}{\parskip} +\setlength{\parsep}{0pt} +\setlength{\leftmargini}{\parindent} +\renewcommand{\labelitemi}{---} + +\def\para#1{\noindent{\bf#1}} +\def\synopsis{\para{Synopsis}} +\def\description{\para{Description}} +\def\returns{\para{Returns}} + +\renewcommand\contentsname{\sf\bfseries Contents} +\renewcommand\chaptername{\sf\bfseries Chapter} +\renewcommand\appendixname{\sf\bfseries Appendix} + +\newenvironment{retlist} +{ \def\arraystretch{1.5} + \noindent + \begin{tabular}{@{}p{1in}@{}p{5.5in}@{}} +} +{\end{tabular}} + +\begin{document} + +\thispagestyle{empty} + +\begin{center} + +\vspace*{1.5in} + +\begin{huge} +\sf\bfseries GNU Linear Programming Kit +\end{huge} + +\vspace{0.5in} + +\begin{LARGE} +\sf Graph and Network Routines +\end{LARGE} + +\vspace{0.5in} + +\begin{LARGE} +\sf for GLPK Version 4.49 +\end{LARGE} + +\vspace{0.5in} +\begin{Large} +\sf (DRAFT, April 2013) +\end{Large} +\end{center} + +\newpage + +\vspace*{1in} + +\vfill + +\noindent +The GLPK package is part of the GNU Project released under the aegis of +GNU. + +\noindent +Copyright \copyright{} 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, +2008, 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +reserved. + +\noindent +Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +02110-1301, USA. + +\noindent +Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + +\noindent +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +entire resulting derived work is distributed under the terms of +a permission notice identical to this one. + +\noindent +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +{\setlength{\parskip}{0pt} +\tableofcontents +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Basic Graph API Routines} + +\section{Graph program object} + +In GLPK the base program object used to represent graphs and networks +is a directed graph (digraph). + +Formally, {\it digraph} (or simply, {\it graph}) is a pair $G=(V,A)$, +where $V$ is a set of {\it vertices}, and $A$ is a set +{\it arcs}.\footnote{$A$ may be a multiset.} Each arc $a\in A$ is an +ordered pair of vertices $a=(x,y)$, where $x\in V$ is called {\it tail +vertex} of arc $a$, and $y\in V$ is called its {\it head vertex}. + +Representation of a graph in the program includes three structs defined +by typedef in the header \verb|glpk.h|: + +\vspace*{-8pt} + +\begin{itemize} +\item \verb|glp_graph|, which represents the graph in a whole, + +\item \verb|glp_vertex|, which represents a vertex of the graph, and + +\item \verb|glp_arc|, which represents an arc of the graph. +\end{itemize} + +\vspace*{-8pt} + +All these three structs are ``semi-opaque'', i.e. the application +program can directly access their fields through pointers, however, +changing the fields directly is not allowed --- all changes should be +performed only with appropriate GLPK API routines. + +\newenvironment{comment} +{\addtolength{\leftskip}{16pt}\noindent} +{\par\addtolength{\leftskip}{-16pt}} + +\para{\bf glp\_graph.} The struct \verb|glp_graph| has the following +fields available to the application program: + +\noindent +\verb|char *name;| + +\begin{comment}Symbolic name assigned to the graph. It is a pointer to +a null terminated character string of length from 1 to 255 characters. +If no name is assigned to the graph, this field contains \verb|NULL|. +\end{comment} + +\noindent +\verb|int nv;| + +\begin{comment}The number of vertices in the graph, $nv\geq 0$. +\end{comment} + +\noindent +\verb|int na;| + +\begin{comment}The number of arcs in the graph, $na\geq 0$. +\end{comment} + +\newpage + +\noindent +\verb|glp_vertex **v;| + +\begin{comment}Pointer to an array containing the list of vertices. +Element $v[0]$ is not used. Element $v[i]$, $1\leq i\leq nv$, is a +pointer to $i$-th vertex of the graph. Note that on adding new vertices +to the graph the field $v$ may be altered due to reallocation. However, +pointers $v[i]$ are not changed while corresponding vertices exist in +the graph. +\end{comment} + +\noindent +\verb|int v_size;| + +\begin{comment}Size of vertex data blocks, in bytes, +$0\leq v\_size\leq 256$. (See also the field \verb|data| in the struct +\verb|glp_vertex|.) +\end{comment} + +\noindent +\verb|int a_size;| + +\begin{comment}Size of arc data blocks, in bytes, +$0\leq v\_size\leq 256$. (See also the field \verb|data| in the struct +\verb|glp_arc|.) +\end{comment} + +\para{\bf glp\_vertex.} The struct \verb|glp_vertex| has the following +fields available to the application program: + +\noindent +\verb|int i;| + +\begin{comment}Ordinal number of the vertex, $1\leq i\leq nv$. Note +that element $v[i]$ in the struct \verb|glp_graph| points to the vertex, +whose ordinal number is $i$. +\end{comment} + +\noindent +\verb|char *name;| + +\begin{comment}Symbolic name assigned to the vertex. It is a pointer to +a null terminated character string of length from 1 to 255 characters. +If no name is assigned to the vertex, this field contains \verb|NULL|. +\end{comment} + +\noindent +\verb|void *data;| + +\begin{comment}Pointer to a data block associated with the vertex. This +data block is automatically allocated on creating a new vertex and freed +on deleting the vertex. If $v\_size=0$, the block is not allocated, and +this field contains \verb|NULL|. +\end{comment} + +\noindent +\verb|void *temp;| + +\begin{comment}Working pointer, which may be used freely for any +purposes. The application program can change this field directly. +\end{comment} + +\noindent +\verb|glp_arc *in;| + +\begin{comment}Pointer to the (unordered) list of incoming arcs. If the +vertex has no incoming arcs, this field contains \verb|NULL|. +\end{comment} + +\noindent +\verb|glp_arc *out;| + +\begin{comment}Pointer to the (unordered) list of outgoing arcs. If the +vertex has no outgoing arcs, this field contains \verb|NULL|. +\end{comment} + +\para{\bf glp\_arc.} The struct \verb|glp_arc| has the following fields +available to the application program: + +\noindent +\verb|glp_vertex *tail;| + +\begin{comment}Pointer to a vertex, which is tail endpoint of the arc. +\end{comment} + +\noindent +\verb|glp_vertex *head;| + +\begin{comment}Pointer to a vertex, which is head endpoint of the arc. +\end{comment} + +\newpage + +\noindent +\verb|void *data;| + +\begin{comment}Pointer to a data block associated with the arc. This +data block is automatically allocated on creating a new arc and freed on +deleting the arc. If $v\_size=0$, the block is not allocated, and this +field contains \verb|NULL|. +\end{comment} + +\noindent +\verb|void *temp;| + +\begin{comment}Working pointer, which may be used freely for any +purposes. The application program can change this field directly. +\end{comment} + +\noindent +\verb|glp_arc *t_next;| + +\begin{comment}Pointer to another arc, which has the same tail endpoint +as this one. \verb|NULL| in this field indicates the end of the list of +outgoing arcs. +\end{comment} + +\noindent +\verb|glp_arc *h_next;| + +\begin{comment}Pointer to another arc, which has the same head endpoint +as this one. \verb|NULL| in this field indicates the end of the list of +incoming arcs. +\end{comment} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Graph creating and modifying routines} + +\subsection{glp\_create\_graph --- create graph} + +\synopsis + +\begin{verbatim} + glp_graph *glp_create_graph(int v_size, int a_size); +\end{verbatim} + +\description + +The routine \verb|glp_create_graph| creates a new graph, which +initially is empty, i.e. has no vertices and arcs. + +The parameter \verb|v_size| specifies the size of vertex data blocks, +in bytes, $0\leq v\_size\leq 256$. + +The parameter \verb|a_size| specifies the size of arc data blocks, in +bytes, $0\leq a\_size\leq 256$. + +\returns + +The routine returns a pointer to the graph object created. + +\subsection{glp\_set\_graph\_name --- assign (change) graph name} + +\synopsis + +\begin{verbatim} + void glp_set_graph_name(glp_graph *G, const char *name); +\end{verbatim} + +\description + +The routine \verb|glp_set_graph_name| assigns a symbolic name specified +by the character string \verb|name| (1 to 255 chars) to the graph. + +If the parameter \verb|name| is \verb|NULL| or an empty string, the +routine erases the existing symbolic name of the graph. + +\subsection{glp\_add\_vertices --- add new vertices to graph} + +\synopsis + +\begin{verbatim} + int glp_add_vertices(glp_graph *G, int nadd); +\end{verbatim} + +\description + +The routine \verb|glp_add_vertices| adds \verb|nadd| vertices to the +specified graph. New vertices are always added to the end of the vertex +list, so ordinal numbers of existing vertices remain unchanged. Note +that this operation may change the field \verb|v| in the struct +\verb|glp_graph| (pointer to the vertex array) due to reallocation. + +Being added each new vertex is isolated, i.e. has no incident arcs. + +If the size of vertex data blocks specified on creating the graph is +non-zero, the routine also allocates a memory block of that size for +each new vertex added, fills it by binary zeros, and stores a pointer +to it in the field \verb|data| of the struct \verb|glp_vertex|. +Otherwise, if the block size is zero, the field \verb|data| is set to +\verb|NULL|. + +\returns + +The routine \verb|glp_add_vertices| returns the ordinal number of the +first new vertex added to the graph. + +\subsection{glp\_set\_vertex\_name --- assign (change) vertex name} + +\synopsis + +\begin{verbatim} + void glp_set_vertex_name(glp_graph *G, int i, const char *name); +\end{verbatim} + +\description + +The routine \verb|glp_set_vertex_name| assigns a given symbolic name +(1 up to 255 characters) to \verb|i|-th vertex of the specified graph. + +If the parameter \verb|name| is \verb|NULL| or empty string, the +routine erases an existing name of \verb|i|-th vertex. + +\subsection{glp\_add\_arc --- add new arc to graph} + +\synopsis + +\begin{verbatim} + glp_arc *glp_add_arc(glp_graph *G, int i, int j); +\end{verbatim} + +\description + +The routine \verb|glp_add_arc| adds one new arc to the specified graph. + +The parameters \verb|i| and \verb|j| specify the ordinal numbers of, +resp., tail and head endpoints (vertices) of the arc. Note that +self-loops and multiple arcs are allowed. + +If the size of arc data blocks specified on creating the graph is +non-zero, the routine also allocates a memory block of that size, fills +it by binary zeros, and stores a pointer to it in the field \verb|data| +of the struct \verb|glp_arc|. Otherwise, if the block size is zero, the +field \verb|data| is set to \verb|NULL|. + +\subsection{glp\_del\_vertices --- delete vertices from graph} + +\synopsis + +\begin{verbatim} + void glp_del_vertices(glp_graph *G, int ndel, const int num[]); +\end{verbatim} + +\description + +The routine \verb|glp_del_vertices| deletes vertices along with all +incident arcs from the specified graph. Ordinal numbers of vertices to +be deleted should be placed in locations \verb|num[1]|, \dots, +\verb|num[ndel]|, \verb|ndel| $>0$. + +Note that deleting vertices involves changing ordinal numbers of other +vertices remaining in the graph. New ordinal numbers of the remaining +vertices are assigned under the assumption that the original order of +vertices is not changed. + +\newpage + +\subsection{glp\_del\_arc --- delete arc from graph} + +\synopsis + +\begin{verbatim} + void glp_del_arc(glp_graph *G, glp_arc *a); +\end{verbatim} + +\description + +The routine \verb|glp_del_arc| deletes an arc from the specified graph. +The arc to be deleted must exist. + +\subsection{glp\_erase\_graph --- erase graph content} + +\synopsis + +\begin{verbatim} + void glp_erase_graph(glp_graph *G, int v_size, int a_size); +\end{verbatim} + +\description + +The routine \verb|glp_erase_graph| erases the content of the specified +graph. The effect of this operation is the same as if the graph would +be deleted with the routine \verb|glp_delete_graph| and then created +anew with the routine \verb|glp_create_graph|, with exception that the +pointer to the graph remains valid. + +The parameters \verb|v_size| and \verb|a_size| have the same meaning as +for \verb|glp_create_graph|. + +\subsection{glp\_delete\_graph --- delete graph} + +\synopsis + +\begin{verbatim} + void glp_delete_graph(glp_graph *G); +\end{verbatim} + +\description + +The routine \verb|glp_delete_graph| deletes the specified graph and +frees all the memory allocated to this program object. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Graph searching routines} + +\subsection{glp\_create\_v\_index --- create vertex name index} + +\synopsis + +\begin{verbatim} + void glp_create_v_index(glp_graph *G); +\end{verbatim} + +\description + +The routine \verb|glp_create_v_index| creates the name index for the +specified graph. The name index is an auxiliary data structure, which +is intended to quickly (i.e. for logarithmic time) find vertices by +their names. + +This routine can be called at any time. If the name index already +exists, the routine does nothing. + +\subsection{glp\_find\_vertex --- find vertex by its name} + +\synopsis + +\begin{verbatim} + int glp_find_vertex(glp_graph *G, const char *name); +\end{verbatim} + +\returns + +The routine \verb|glp_find_vertex| returns the ordinal number of +a vertex, which is assigned (by the routine \verb|glp_set_vertex_name|) +the specified symbolic \verb|name|. If no such vertex exists, the +routine returns 0. + +\subsection{glp\_delete\_v\_index --- delete vertex name index} + +\synopsis + +\begin{verbatim} + void glp_delete_v_index(glp_graph *G); +\end{verbatim} + +\description + +The routine \verb|glp_delete_v_index| deletes the name index previously +created by the routine \verb|glp_create_v_index| and frees the memory +allocated to this auxiliary data structure. + +This routine can be called at any time. If the name index does not +exist, the routine does nothing. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Graph reading/writing routines} + +\subsection{glp\_read\_graph --- read graph from plain text file} + +\synopsis + +\begin{verbatim} + int glp_read_graph(glp_graph *G, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_read_graph| reads a graph from a plain text file, +whose name is specified by the parameter \verb|fname|. Note that before +reading data the current content of the graph object is completely +erased with the routine \verb|glp_erase_graph|. + +For the file format see description of the routine +\verb|glp_write_graph|. + +\returns + +If the operation was successful, the routine returns zero. Otherwise +it prints an error message and returns non-zero. + +\subsection{glp\_write\_graph --- write graph to plain text file} + +\synopsis + +\begin{verbatim} + int glp_write_graph(glp_graph *G, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_write_graph| writes the graph to a plain text +file, whose name is specified by the parameter \verb|fname|. + +\returns + +If the operation was successful, the routine returns zero. Otherwise +it prints an error message and returns non-zero. + +\para{File format} + +The file created by the routine \verb|glp_write_graph| is a plain text +file, which contains the following information: + +\begin{verbatim} + nv na + i[1] j[1] + i[2] j[2] + . . . + i[na] j[na] +\end{verbatim} + +\noindent +where: \verb|nv| is the number of vertices (nodes); \verb|na| is the +number of arcs; \verb|i[k]|, $k=1,\dots,na$, is the index of tail +vertex of arc $k$; \verb|j[k]|, $k=1,\dots,na$, is the index of head +vertex of arc $k$. + +\newpage + +\subsection{glp\_read\_ccdata --- read graph from text file in DIMACS +clique/coloring\\format} + +\synopsis + +\begin{verbatim} + int glp_read_ccdata(glp_graph *G, int v_wgt, const char *fname); +\end{verbatim} + +\description + +The routine {\tt glp\_read\_ccdata} reads a graph from a text file in +DIMACS clique/coloring format. (Though this format is originally +designed to represent data for the minimal vertex coloring and maximal +clique problems, it may be used to represent general undirected and +directed graphs, because the routine allows reading self-loops and +multiple edges/arcs keeping the order of vertices specified for each +edge/arc of the graph.) + +The parameter {\tt G} specifies the graph object to be read in. Note +that before reading data the current content of the graph object is +completely erased with the routine {\tt glp\_erase\_graph}. + +The parameter {\tt v\_wgt} specifies an offset of the field of type +{\tt double} in the vertex data block, to which the routine stores the +vertex weight. If {\tt v\_wgt} $<0$, the vertex weights are not stored. + +The character string {\tt fname} specifies the name of a text file to +be read in. (If the file name ends with the suffix `\verb|.gz|', the +file is assumed to be compressed, in which case the routine +decompresses it ``on the fly''.) + +\returns + +If the operation was successful, the routine returns zero. Otherwise, +it prints an error message and returns non-zero. + +\para{DIMACS clique/coloring format\footnote{This material is +based on the paper ``Clique and Coloring Problems Graph Format'', which +is publically available at \url{http://dimacs.rutgers.edu/Challenges}.}} + +The DIMACS input file is a plain ASCII text file. It contains +{\it lines} of several types described below. A line is terminated with +an end-of-line character. Fields in each line are separated by at least +one blank space. Each line begins with a one-character designator to +identify the line type. + +Note that DIMACS requires all numerical quantities to be integers in +the range $[-2^{31},2^{31}-1]$ while GLPK allows the quantities to be +floating-point numbers. + +\para{Comment lines.} Comment lines give human-readable information +about the file and are ignored by programs. Comment lines can appear +anywhere in the file. Each comment line begins with a lower-case +character \verb|c|. + +\begin{verbatim} + c This is a comment line +\end{verbatim} + +\para{Problem line.} There is one problem line per data file. +The problem line must appear before any node or edge descriptor lines. +It has the following format: + +\begin{verbatim} + p edge NODES EDGES +\end{verbatim} + +\noindent +The lower-case letter \verb|p| signifies that this is a problem line. +The four-character problem designator \verb|edge| identifies the file +as containing data for the minimal vertex coloring or maximal clique +problem. The \verb|NODES| field contains an integer value specifying +the number of vertices in the graph. The \verb|EDGES| field contains an +integer value specifying the number of edges (arcs) in the graph. + +\para{Vertex descriptors.} These lines give the weight assigned to +a vertex of the graph. There is one vertex descriptor line for each +vertex, with the following format. Vertices without a descriptor take +on a default value of 1. + +\begin{verbatim} + n ID VALUE +\end{verbatim} + +\noindent +The lower-case character \verb|n| signifies that this is a vertex +descriptor line. The \verb|ID| field gives a vertex identification +number, an integer between 1 and $n$, where $n$ is the number of +vertices in the graph. The \verb|VALUE| field gives a vertex weight, +which can either positive or negative (or zero). + +\para{Edge descriptors.} There is one edge descriptor line for each +edge (arc) of the graph, each with the following format: + +\begin{verbatim} + e I J +\end{verbatim} + +\noindent +The lower-case character \verb|e| signifies that this is an edge +descriptor line. For an edge (arc) $(i,j)$ the fields \verb|I| and +\verb|J| specify its endpoints. + +\para{Example.} The following example of an undirected graph: + +\bigskip + +\noindent\hfil +\xymatrix %@C=32pt +{&{v_1}\ar@{-}[ldd]\ar@{-}[dd]\ar@{-}[rd]\ar@{-}[rr]&&{v_2}\ar@{-}[ld] +\ar@{-}[dd]\ar@{-}[rdd]&\\ +&&{v_7}\ar@{-}[ld]\ar@{-}[rd]&&\\ +{v_6}\ar@{-}[r]\ar@{-}[rdd]&{v_{10}}\ar@{-}[rr]\ar@{-}[rd]\ar@{-}[dd]&& +{v_8}\ar@{-}[ld]\ar@{-}[dd]\ar@{-}[r]&{v_3}\ar@{-}[ldd]\\ +&&{v_9}\ar@{-}[ld]\ar@{-}[rd]&&\\ +&{v_5}\ar@{-}[rr]&&{v_4}&\\ +} + +\bigskip + +\noindent +might be coded in DIMACS clique/coloring format as follows: + +\begin{footnotesize} +\begin{verbatim} +c sample.col +c +c This is an example of the vertex coloring problem data +c in DIMACS format. +c +p edge 10 21 +c +e 1 2 +e 1 6 +e 1 7 +e 1 10 +e 2 3 +e 2 7 +e 2 8 +e 3 4 +e 3 8 +e 4 5 +e 4 8 +e 4 9 +e 5 6 +e 5 9 +e 5 10 +e 6 10 +e 7 8 +e 7 10 +e 8 9 +e 8 10 +e 9 10 +c +c eof +\end{verbatim} +\end{footnotesize} + +\subsection{glp\_write\_ccdata --- write graph to text file in DIMACS +clique/coloring\\format} + +\synopsis + +\begin{verbatim} + int glp_write_ccdata(glp_graph *G, int v_wgt, const char *fname); +\end{verbatim} + +\description + +The routine {\tt glp\_write\_ccdata} writes the graph object specified +by the parameter {\tt G} to a text file in DIMACS clique/coloring +format. (Though this format is originally designed to represent data +for the minimal vertex coloring and maximal clique problems, it may be +used to represent general undirected and directed graphs, because the +routine allows writing self-loops and multiple edges/arcs keeping the +order of vertices specified for each edge/arc of the graph.) + +The parameter {\tt v\_wgt} specifies an offset of the field of type +{\tt double} in the vertex data block, which contains the vertex +weight. If {\tt v\_wgt} $<0$, it is assumed that the weight of each +vertex is 1. + +The character string {\tt fname} specifies a name of the text file to +be written out. (If the file name ends with suffix `\verb|.gz|', the +file is assumed to be compressed, in which case the routine performs +automatic compression on writing it.) + +\returns + +If the operation was successful, the routine returns zero. Otherwise, +it prints an error message and returns non-zero. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Graph analysis routines} + +\subsection{glp\_weak\_comp --- find all weakly connected components of +graph} + +\synopsis + +\begin{verbatim} + int glp_weak_comp(glp_graph *G, int v_num); +\end{verbatim} + +\description + +The routine \verb|glp_weak_comp| finds all weakly connected components +of the specified graph. + +The parameter \verb|v_num| specifies an offset of the field of type +\verb|int| in the vertex data block, to which the routine stores the +number of a weakly connected component containing that vertex. If +\verb|v_num| $<0$, no component numbers are stored. + +The components are numbered in arbitrary order from 1 to \verb|nc|, +where \verb|nc| is the total number of components found, +$0\leq$ \verb|nc| $\leq|V|$. + +\returns + +The routine returns \verb|nc|, the total number of components found. + +\subsection{glp\_strong\_comp --- find all strongly connected +components of graph} + +\synopsis + +\begin{verbatim} + int glp_strong_comp(glp_graph *G, int v_num); +\end{verbatim} + +\description + +The routine \verb|glp_strong_comp| finds all strongly connected +components of the specified graph. + +The parameter \verb|v_num| specifies an offset of the field of type +\verb|int| in the vertex data block, to which the routine stores the +number of a strongly connected component containing that vertex. If +\verb|v_num| $<0$, no component numbers are stored. + +The components are numbered in arbitrary order from 1 to \verb|nc|, +where \verb|nc| is the total number of components found, +$0\leq$ \verb|nc| $\leq|V|$. However, the component numbering has the +property that for every arc $(i\rightarrow j)$ in the graph the +condition $num(i)\geq num(j)$ holds. + +\returns + +The routine returns \verb|nc|, the total number of components found. + +\para{References} + +I.~S.~Duff, J.~K.~Reid, Algorithm 529: Permutations to block triangular +form, ACM Trans. on Math. Softw. 4 (1978), 189-92. + +\newpage + +\para{Example} + +The following program reads a graph from a plain text file +`\verb|graph.txt|' and finds all its strongly connected components. + +\begin{footnotesize} +\begin{verbatim} +#include +#include +#include +#include + +typedef struct { int num; } v_data; + +#define vertex(v) ((v_data *)((v)->data)) + +int main(void) +{ glp_graph *G; + int i, nc; + G = glp_create_graph(sizeof(v_data), 0); + glp_read_graph(G, "graph.txt"); + nc = glp_strong_comp(G, offsetof(v_data, num)); + printf("nc = %d\n", nc); + for (i = 1; i <= G->nv; i++) + printf("num[%d] = %d\n", i, vertex(G->v[i])->num); + glp_delete_graph(G); + return 0; +} +\end{verbatim} +\end{footnotesize} + +\noindent +If the file `\verb|graph.txt|' contains the following graph: + +\medskip + +\noindent\hfil +\xymatrix +{1\ar[r]&2\ar[r]&3\ar[r]\ar[dd]&4\ar[dd]\\ +5\ar[u]&6\ar[l]\\ +7\ar[u]&&8\ar[lu]\ar[ll]\ar[r]&9\ar[r]&10\ar[r]\ar[d]&11\ar[d]\\ +12\ar[u]\ar[rru]\ar@/_/[rr]&&13\ar[ll]\ar[u]\ar[rr]&&14\ar[lu]&15\ar[l] +\\ +} + +\medskip\medskip + +\noindent +the program output may look like follows: + +\begin{footnotesize} +\begin{verbatim} +Reading graph from `graph.txt'... +Graph has 15 vertices and 30 arcs +31 lines were read +nc = 4 +num[1] = 3 +num[2] = 3 +num[3] = 3 +num[4] = 2 +num[5] = 3 +num[6] = 3 +num[7] = 3 +num[8] = 3 +num[9] = 1 +num[10] = 1 +num[11] = 1 +num[12] = 4 +num[13] = 4 +num[14] = 1 +num[15] = 1 +\end{verbatim} +\end{footnotesize} + +\subsection{glp\_top\_sort --- topological sorting of acyclic digraph} + +\synopsis + +\begin{verbatim} + int glp_top_sort(glp_graph *G, int v_num); +\end{verbatim} + +\description + +The routine \verb|glp_top_sort| performs topological sorting of +vertices of the specified acyclic digraph. + +The parameter \verb|v_num| specifies an offset of the field of type +\verb|int| in the vertex data block, to which the routine stores the +vertex number assigned. If \verb|v_num| $<0$, vertex numbers are not +stored. + +The vertices are numbered from 1 to $n$, where $n$ is the total number +of vertices in the graph. The vertex numbering has the property that +for every arc $(i\rightarrow j)$ in the graph the condition +$num(i) +#include +#include +#include + +typedef struct { int num; } v_data; + +#define vertex(v) ((v_data *)((v)->data)) + +int main(void) +{ glp_graph *G; + int i, cnt; + G = glp_create_graph(sizeof(v_data), 0); + glp_read_graph(G, "graph.txt"); + cnt = glp_top_sort(G, offsetof(v_data, num)); + printf("cnt = %d\n", cnt); + for (i = 1; i <= G->nv; i++) + printf("num[%d] = %d\n", i, vertex(G->v[i])->num); + glp_delete_graph(G); + return 0; +} +\end{verbatim} +\end{footnotesize} + +\noindent +If the file `\verb|graph.txt|' contains the following graph: + +\medskip + +\noindent\hfil +\xymatrix @=20pt +{ +1\ar[rrr]&&&2\ar[r]\ar[rddd]&3\ar[rd]&&&&\\ +&&&4\ar[ru]&&5\ar[r]&6\ar[rd]\ar[dd]&&\\ +7\ar[r]&8\ar[r]&9\ar[ruu]\ar[ru]\ar[r]\ar[rd]&10\ar[rr]\ar[rru]&& +11\ar[ru]&&12\ar[r]&13\\ +&&&14\ar[r]&15\ar[rrru]\ar[rr]&&16\ar[rru]\ar[rr]&&17\\ +} + +\medskip\medskip + +\noindent +the program output may look like follows: + +\begin{footnotesize} +\begin{verbatim} +Reading graph from `graph.txt'... +Graph has 17 vertices and 23 arcs +24 lines were read +cnt = 0 +num[1] = 8 +num[2] = 9 +num[3] = 10 +num[4] = 4 +num[5] = 11 +num[6] = 12 +num[7] = 1 +num[8] = 2 +num[9] = 3 +num[10] = 5 +num[11] = 6 +num[12] = 14 +num[13] = 16 +num[14] = 7 +num[15] = 13 +num[16] = 15 +num[17] = 17 +\end{verbatim} +\end{footnotesize} + +\noindent +The output corresponds to the following vertex numbering: + +\medskip + +\noindent\hfil +\xymatrix @=20pt +{ +8\ar[rrr]&&&9\ar[r]\ar[rddd]&10\ar[rd]&&&&\\ +&&&4\ar[ru]&&11\ar[r]&12\ar[rd]\ar[dd]&&\\ +1\ar[r]&2\ar[r]&3\ar[ruu]\ar[ru]\ar[r]\ar[rd]&5\ar[rr]\ar[rru]&& +6\ar[ru]&&14\ar[r]&16\\ +&&&7\ar[r]&13\ar[rrru]\ar[rr]&&15\ar[rru]\ar[rr]&&17\\ +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Network optimization API routines} + +\section{Minimum cost flow problem} + +\subsection{Background} + +The {\it minimum cost flow problem} (MCFP) is stated as follows. Let +there be given a directed graph (flow network) $G=(V,A)$, where $V$ is +a set of vertices (nodes), and $A\subseteq V\times V$ is a set of arcs. +Let for each node $i\in V$ there be given a quantity $b_i$ having the +following meaning: + +if $b_i>0$, then $|b_i|$ is a {\it supply} at node $i$, which shows +how many flow units are {\it generated} at node $i$ (or, equivalently, +entering the network through node $i$ from outside); + +if $b_i<0$, then $|b_i|$ is a {\it demand} at node $i$, which shows how +many flow units are {\it lost} at node $i$ (or, equivalently, leaving +the network through node $i$ to outside); + +if $b_i=0$, then $i$ is a {\it transshipment} node, at which the flow +is conserved, i.e. neither generated nor lost. + +Let also for each arc $a=(i,j)\in A$ there be given the following three +quantities: + +$l_{ij}$, a (non-negative) lower bound to the flow through arc $(i,j)$; + +$u_{ij}$, an upper bound to the flow through arc $(i,j)$, which is the +{\it arc capacity}; + +$c_{ij}$, a per-unit cost of the flow through arc $(i,j)$. + +The problem is to find flows $x_{ij}$ through every arc of the network, +which satisfy the specified bounds and the conservation constraints at +all nodes, and minimize the total flow cost. Here the conservation +constraint at a node means that the total flow entering this node +through its incoming arcs plus the supply at this node must be equal to +the total flow leaving this node through its outgoing arcs plus the +demand at this node. + +An example of the minimum cost flow problem is shown on Fig.~1. + +\newpage + +\noindent\hfil +\xymatrix @C=48pt +{_{20}\ar@{~>}[d]& +v_2\ar[r]|{_{0,10,\$2}}\ar[dd]|{_{0,9,\$3}}& +v_3\ar[dd]|{_{2,12,\$1}}\ar[r]|{_{0,18,\$0}}& +v_8\ar[rd]|{_{0,20,\$9}}&\\ +v_1\ar[ru]|{_{0,14,\$0}}\ar[rd]|{_{0,23,\$0}}&&& +v_6\ar[d]|{_{0,7,\$0}}\ar[u]|{_{4,8,\$0}}& +v_9\ar@{~>}[d]\\ +&v_4\ar[r]|{_{0,26,\$0}}& +v_5\ar[luu]|{_{0,11,\$1}}\ar[ru]|{_{0,25,\$5}}\ar[r]|{_{0,4,\$7}}& +v_7\ar[ru]|{_{0,15,\$3}}&_{20}\\ +} + +\noindent\hfil +\begin{tabular}{ccc} +\xymatrix @C=48pt{v_i\ar[r]|{\ l,u,\$c\ }&v_j\\}& +\xymatrix{\hbox{\footnotesize supply}\ar@{~>}[r]&v_i\\}& +\xymatrix{v_i\ar@{~>}[r]&\hbox{\footnotesize demand}\\}\\ +\end{tabular} + +\noindent\hfil +Fig.~1. An example of the minimum cost flow problem. + +\medskip + +The minimum cost flow problem can be naturally formulated as the +following LP problem: + +\noindent +\hspace{1in}minimize +$$z=\sum_{(i,j)\in A}c_{ij}x_{ij}\eqno(1)$$ +\hspace{1in}subject to +$$\sum_{(i,j)\in A}x_{ij}-\sum_{(j,i)\in A}x_{ji}=b_i\ \ \ \hbox +{for all}\ i\in V\eqno(2)$$ +$$l_{ij}\leq x_{ij}\leq u_{ij}\ \ \ \hbox{for all}\ (i,j)\in A +\eqno(3)$$ + +\subsection{glp\_read\_mincost --- read minimum cost flow problem data +in DIMACS\\format} + +\synopsis + +\begin{verbatim} + int glp_read_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, + int a_cost, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_read_mincost| reads the minimum cost flow problem +data from a text file in DIMACS format. + +The parameter \verb|G| specifies the graph object, to which the problem +data have to be stored. Note that before reading data the current +content of the graph object is completely erased with the routine +\verb|glp_erase_graph|. + +The parameter \verb|v_rhs| specifies an offset of the field of type +\verb|double| in the vertex data block, to which the routine stores +$b_i$, the supply/demand value. If \verb|v_rhs| $<0$, the value is not +stored. + +The parameter \verb|a_low| specifies an offset of the field of type +\verb|double| in the arc data block, to which the routine stores +$l_{ij}$, the lower bound to the arc flow. If \verb|a_low| $<0$, the +lower bound is not stored. + +The parameter \verb|a_cap| specifies an offset of the field of type +\verb|double| in the arc data block, to which the routine stores +$u_{ij}$, the upper bound to the arc flow (the arc capacity). If +\verb|a_cap| $<0$, the upper bound is not stored. + +The parameter \verb|a_cost| specifies an offset of the field of type +\verb|double| in the arc data block, to which the routine stores +$c_{ij}$, the per-unit cost of the arc flow. If \verb|a_cost| $<0$, the +cost is not stored. + +The character string \verb|fname| specifies the name of a text file to +be read in. (If the file name name ends with the suffix `\verb|.gz|', +the file is assumed to be compressed, in which case the routine +decompresses it ``on the fly''.) + +\returns + +If the operation was successful, the routine returns zero. Otherwise, +it prints an error message and returns non-zero. + +\para{Example} + +\begin{footnotesize} +\begin{verbatim} +typedef struct +{ /* vertex data block */ + ... + double rhs; + ... +} v_data; + +typedef struct +{ /* arc data block */ + ... + double low, cap, cost; + ... +} a_data; + +int main(void) +{ glp_graph *G; + int ret; + G = glp_create_graph(sizeof(v_data), sizeof(a_data)); + ret = glp_read_mincost(G, offsetof(v_data, rhs), + offsetof(a_data, low), offsetof(a_data, cap), + offsetof(a_data, cost), "sample.min"); + if (ret != 0) goto ... + ... +} +\end{verbatim} +\end{footnotesize} + +\para{DIMACS minimum cost flow problem format\footnote{This +material is based on the paper ``The First DIMACS International +Algorithm Implementation Challenge: Problem Definitions and +Specifications'', which is publically available at +\url{http://dimacs.rutgers.edu/Challenges}.}} +\label{subsecmincost} + +The DIMACS input file is a plain ASCII text file. It contains +{\it lines} of several types described below. A line is terminated with +an end-of-line character. Fields in each line are separated by at least +one blank space. Each line begins with a one-character designator to +identify the line type. + +Note that DIMACS requires all numerical quantities to be integers in +the range $[-2^{31},\ 2^{31}-1]$ while GLPK allows the quantities to be +floating-point numbers. + +\para{Comment lines.} Comment lines give human-readable information +about the file and are ignored by programs. Comment lines can appear +anywhere in the file. Each comment line begins with a lower-case +character \verb|c|. + +\begin{verbatim} + c This is a comment line +\end{verbatim} + +\newpage + +\para{Problem line.} There is one problem line per data file. The +problem line must appear before any node or arc descriptor lines. It +has the following format: + +\begin{verbatim} + p min NODES ARCS +\end{verbatim} + +\noindent +The lower-case character \verb|p| signifies that this is a problem line. +The three-character problem designator \verb|min| identifies the file as +containing specification information for the minimum cost flow problem. +The \verb|NODES| field contains an integer value specifying the number +of nodes in the network. The \verb|ARCS| field contains an integer value +specifying the number of arcs in the network. + +\para{Node descriptors.} All node descriptor lines must appear before +all arc descriptor lines. The node descriptor lines describe supply and +demand nodes, but not transshipment nodes. That is, only nodes with +non-zero node supply/demand values appear. There is one node descriptor +line for each such node, with the following format: + +\begin{verbatim} + n ID FLOW +\end{verbatim} + +\noindent +The lower-case character \verb|n| signifies that this is a node +descriptor line. The \verb|ID| field gives a node identification +number, an integer between 1 and \verb|NODES|. The \verb|FLOW| field +gives the amount of supply (if positive) or demand (if negative) at +node \verb|ID|. + +\para{Arc descriptors.} There is one arc descriptor line for each arc +in the network. Arc descriptor lines are of the following format: + +\begin{verbatim} + a SRC DST LOW CAP COST +\end{verbatim} + +\noindent +The lower-case character \verb|a| signifies that this is an arc +descriptor line. For a directed arc $(i,j)$ the \verb|SRC| field gives +the identification number $i$ for the tail endpoint, and the \verb|DST| +field gives the identification number $j$ for the head endpoint. +Identification numbers are integers between 1 and \verb|NODES|. The +\verb|LOW| field specifies the minimum amount of flow that can be sent +along arc $(i,j)$, and the \verb|CAP| field gives the maximum amount of +flow that can be sent along arc $(i,j)$ in a feasible flow. The +\verb|COST| field contains the per-unit cost of flow sent along arc +$(i,j)$. + +\para{Example.} Below here is an example of the data file in DIMACS +format corresponding to the minimum cost flow problem shown on Fig~1. + +\begin{footnotesize} +\begin{verbatim} +c sample.min +c +c This is an example of the minimum cost flow problem data +c in DIMACS format. +c +p min 9 14 +c +n 1 20 +n 9 -20 +c +a 1 2 0 14 0 +a 1 4 0 23 0 +a 2 3 0 10 2 +a 2 4 0 9 3 +a 3 5 2 12 1 +a 3 8 0 18 0 +a 4 5 0 26 0 +a 5 2 0 11 1 +a 5 6 0 25 5 +a 5 7 0 4 7 +a 6 7 0 7 0 +a 6 8 4 8 0 +a 7 9 0 15 3 +a 8 9 0 20 9 +c +c eof +\end{verbatim} +\end{footnotesize} + +\subsection{glp\_write\_mincost --- write minimum cost flow problem +data in DIMACS\\format} + +\synopsis + +\begin{verbatim} + int glp_write_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, + int a_cost, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_write_mincost| writes the minimum cost flow +problem data to a text file in DIMACS format. + +The parameter \verb|G| is the graph (network) program object, which +specifies the minimum cost flow problem instance. + +The parameter \verb|v_rhs| specifies an offset of the field of type +\verb|double| in the vertex data block, which contains $b_i$, the +supply/demand value. If \verb|v_rhs| $<0$, it is assumed that $b_i=0$ +for all nodes. + +The parameter \verb|a_low| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $l_{ij}$, the lower +bound to the arc flow. If \verb|a_low| $<0$, it is assumed that +$l_{ij}=0$ for all arcs. + +The parameter \verb|a_cap| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $u_{ij}$, the upper +bound to the arc flow (the arc capacity). If the upper bound is +specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e. +the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that +$u_{ij}=1$ for all arcs. + +The parameter \verb|a_cost| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $c_{ij}$, the +per-unit cost of the arc flow. If \verb|a_cost| $<0$, it is assumed +that $c_{ij}=0$ for all arcs. + +The character string \verb|fname| specifies a name of the text file to +be written out. (If the file name ends with suffix `\verb|.gz|', the +file is assumed to be compressed, in which case the routine performs +automatic compression on writing it.) + +\returns + +If the operation was successful, the routine returns zero. Otherwise, +it prints an error message and returns non-zero. + +\newpage + +\subsection{glp\_mincost\_lp --- convert minimum cost flow problem +to LP} + +\synopsis + +\begin{verbatim} + void glp_mincost_lp(glp_prob *P, glp_graph *G, int names, int v_rhs, + int a_low, int a_cap, int a_cost); +\end{verbatim} + +\description + +The routine \verb|glp_mincost_lp| builds LP problem (1)---(3), which +corresponds to the specified minimum cost flow problem. + +The parameter \verb|P| is the resultant LP problem object to be built. +Note that on entry its current content is erased with the routine +\verb|glp_erase_prob|. + +The parameter \verb|G| is the graph (network) program object, which +specifies the minimum cost flow problem instance. + +The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, the +routine uses symbolic names of the graph object components to assign +symbolic names to the LP problem object components. If the flag is +\verb|GLP_OFF|, no symbolic names are assigned. + +The parameter \verb|v_rhs| specifies an offset of the field of type +\verb|double| in the vertex data block, which contains $b_i$, the +supply/demand value. If \verb|v_rhs| $<0$, it is assumed that $b_i=0$ +for all nodes. + +The parameter \verb|a_low| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $l_{ij}$, the lower +bound to the arc flow. If \verb|a_low| $<0$, it is assumed that +$l_{ij}=0$ for all arcs. + +The parameter \verb|a_cap| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $u_{ij}$, the upper +bound to the arc flow (the arc capacity). If the upper bound is +specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e. +the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that +$u_{ij}=1$ for all arcs. + +The parameter \verb|a_cost| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $c_{ij}$, the +per-unit cost of the arc flow. If \verb|a_cost| $<0$, it is assumed that +$c_{ij}=0$ for all arcs. + +\para{Example} + +The example program below reads the minimum cost problem instance in +DIMACS format from file `\verb|sample.min|', converts the instance to +LP, and then writes the resultant LP in CPLEX format to file +`\verb|mincost.lp|'. + +\begin{footnotesize} +\begin{verbatim} +#include +#include + +typedef struct { double rhs; } v_data; +typedef struct { double low, cap, cost; } a_data; + +int main(void) +{ glp_graph *G; + glp_prob *P; + G = glp_create_graph(sizeof(v_data), sizeof(a_data)); + glp_read_mincost(G, offsetof(v_data, rhs), + offsetof(a_data, low), offsetof(a_data, cap), + offsetof(a_data, cost), "sample.min"); + P = glp_create_prob(); + glp_mincost_lp(P, G, GLP_ON, offsetof(v_data, rhs), + offsetof(a_data, low), offsetof(a_data, cap), + offsetof(a_data, cost)); + glp_delete_graph(G); + glp_write_lp(P, NULL, "mincost.lp"); + glp_delete_prob(P); + return 0; +} +\end{verbatim} +\end{footnotesize} + +If `\verb|sample.min|' is the example data file from the subsection +describing \verb|glp_read_mincost|, file `\verb|mincost.lp|' may look +like follows: + +\begin{footnotesize} +\begin{verbatim} +Minimize + obj: + 3 x(2,4) + 2 x(2,3) + x(3,5) + 7 x(5,7) + 5 x(5,6) + + x(5,2) + 3 x(7,9) + 9 x(8,9) + +Subject To + r_1: + x(1,2) + x(1,4) = 20 + r_2: - x(5,2) + x(2,3) + x(2,4) - x(1,2) = 0 + r_3: + x(3,5) + x(3,8) - x(2,3) = 0 + r_4: + x(4,5) - x(2,4) - x(1,4) = 0 + r_5: + x(5,2) + x(5,6) + x(5,7) - x(4,5) - x(3,5) = 0 + r_6: + x(6,7) + x(6,8) - x(5,6) = 0 + r_7: + x(7,9) - x(6,7) - x(5,7) = 0 + r_8: + x(8,9) - x(6,8) - x(3,8) = 0 + r_9: - x(8,9) - x(7,9) = -20 + +Bounds + 0 <= x(1,4) <= 23 + 0 <= x(1,2) <= 14 + 0 <= x(2,4) <= 9 + 0 <= x(2,3) <= 10 + 0 <= x(3,8) <= 18 + 2 <= x(3,5) <= 12 + 0 <= x(4,5) <= 26 + 0 <= x(5,7) <= 4 + 0 <= x(5,6) <= 25 + 0 <= x(5,2) <= 11 + 4 <= x(6,8) <= 8 + 0 <= x(6,7) <= 7 + 0 <= x(7,9) <= 15 + 0 <= x(8,9) <= 20 + +End +\end{verbatim} +\end{footnotesize} + +\newpage + +\subsection{glp\_mincost\_okalg --- solve minimum cost flow problem +with out-of-kilter\\algorithm} + +\synopsis + +\begin{verbatim} + int glp_mincost_okalg(glp_graph *G, int v_rhs, int a_low, int a_cap, + int a_cost, double *sol, int a_x, int v_pi); +\end{verbatim} + +\description + +The routine \verb|glp_mincost_okalg| finds optimal solution to the +minimum cost flow problem with the out-of-kilter +algorithm.\footnote{GLPK implementation of the out-of-kilter algorithm +is based on the following book: L.~R.~Ford,~Jr., and D.~R.~Fulkerson, +``Flows in Networks,'' The RAND Corp., Report R-375-PR (August 1962), +Chap. III ``Minimal Cost Flow Problems,'' pp.~113-26.} Note that this +routine requires all the problem data to be integer-valued. + +The parameter \verb|G| is a graph (network) program object which +specifies the minimum cost flow problem instance to be solved. + +The parameter \verb|v_rhs| specifies an offset of the field of type +\verb|double| in the vertex data block, which contains $b_i$, the +supply/demand value. This value must be integer in the range +[$-$\verb|INT_MAX|, $+$\verb|INT_MAX|]. If \verb|v_rhs| $<0$, it is +assumed that $b_i=0$ for all nodes. + +The parameter \verb|a_low| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $l_{ij}$, the lower +bound to the arc flow. This bound must be integer in the range +[$0$, \verb|INT_MAX|]. If \verb|a_low| $<0$, it is assumed that +$l_{ij}=0$ for all arcs. + +The parameter \verb|a_cap| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $u_{ij}$, the upper +bound to the arc flow (the arc capacity). This bound must be integer in +the range [$l_{ij}$, \verb|INT_MAX|]. If \verb|a_cap| $<0$, it is +assumed that $u_{ij}=1$ for all arcs. + +The parameter \verb|a_cost| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $c_{ij}$, the +per-unit cost of the arc flow. This value must be integer in the range +[$-$\verb|INT_MAX|, $+$\verb|INT_MAX|]. If \verb|a_cost| $<0$, it is +assumed that $c_{ij}=0$ for all arcs. + +The parameter \verb|sol| specifies a location, to which the routine +stores the objective value (that is, the total cost) found. If +\verb|sol| is NULL, the objective value is not stored. + +The parameter \verb|a_x| specifies an offset of the field of type +\verb|double| in the arc data block, to which the routine stores +$x_{ij}$, the arc flow found. If \verb|a_x| $<0$, the arc flow value is +not stored. + +The parameter \verb|v_pi| specifies an offset of the field of type +\verb|double| in the vertex data block, to which the routine stores +$\pi_i$, the node potential, which is the Lagrange multiplier for the +corresponding flow conservation equality constraint (see (2) in +Subsection ``Background''). If necessary, the application program may +use the node potentials to compute $\lambda_{ij}$, reduced costs of the +arc flows $x_{ij}$, which are the Lagrange multipliers for the arc flow +bound constraints (see (3) ibid.), using the following formula: +$$\lambda_{ij}=c_{ij}-(\pi_i-\pi_j),$$ +where $c_{ij}$ is the per-unit cost for arc $(i,j)$. + +\newpage + +Note that all solution components (the objective value, arc flows, and +node potentials) computed by the routine are always integer-valued. + +\returns + +\begin{retlist} +0 & Optimal solution found.\\ + +\verb|GLP_ENOPFS| & No (primal) feasible solution exists.\\ + +\verb|GLP_EDATA| & Unable to start the search, because some problem +data are either not integer-valued or out of range. This code is also +returned if the total supply, which is the sum of $b_i$ over all source +nodes (nodes with $b_i>0$), exceeds \verb|INT_MAX|.\\ + +\verb|GLP_ERANGE| & The search was prematurely terminated because of +integer overflow.\\ + +\verb|GLP_EFAIL| & An error has been detected in the program logic. +(If this code is returned for your problem instance, please report to +\verb||.)\\ +\end{retlist} + +\para{Comments} + +By design the out-of-kilter algorithm is applicable only to networks, +where $b_i=0$ for {\it all} nodes, i.e. actually this algorithm finds a +minimal cost {\it circulation}. Due to this requirement the routine +\verb|glp_mincost_okalg| converts the original network to a network +suitable for the out-of-kilter algorithm in the following +way:\footnote{The conversion is performed internally and does not change +the original network program object passed to the routine.} + +1) it adds two auxiliary nodes $s$ and $t$; + +2) for each original node $i$ with $b_i>0$ the routine adds auxiliary +supply arc $(s\rightarrow i)$, flow $x_{si}$ through which is costless +($c_{si}=0$) and fixed to $+b_i$ ($l_{si}=u_{si}=+b_i$); + +3) for each original node $i$ with $b_i<0$ the routine adds auxiliary +demand arc $(i\rightarrow t)$, flow $x_{it}$ through which is costless +($c_{it}=0$) and fixed to $-b_i$ ($l_{it}=u_{it}=-b_i$); + +4) finally, the routine adds auxiliary feedback arc $(t\rightarrow s)$, +flow $x_{ts}$ through which is also costless ($c_{ts}=0$) and fixed to +$F$ ($l_{ts}=u_{ts}=F$), where $\displaystyle F=\sum_{b_i>0}b_i$ is the +total supply. + +\para{Example} + +The example program below reads the minimum cost problem instance in +DIMACS format from file `\verb|sample.min|', solves it by using the +routine \verb|glp_mincost_okalg|, and writes the solution found on the +standard output. + +\begin{footnotesize} +\begin{verbatim} +#include +#include +#include +#include + +typedef struct { double rhs, pi; } v_data; +typedef struct { double low, cap, cost, x; } a_data; + +#define node(v) ((v_data *)((v)->data)) +#define arc(a) ((a_data *)((a)->data)) + +int main(void) +{ glp_graph *G; + glp_vertex *v, *w; + glp_arc *a; + int i, ret; + double sol; + G = glp_create_graph(sizeof(v_data), sizeof(a_data)); + glp_read_mincost(G, offsetof(v_data, rhs), + offsetof(a_data, low), offsetof(a_data, cap), + offsetof(a_data, cost), "sample.min"); + ret = glp_mincost_okalg(G, offsetof(v_data, rhs), + offsetof(a_data, low), offsetof(a_data, cap), + offsetof(a_data, cost), &sol, offsetof(a_data, x), + offsetof(v_data, pi)); + printf("ret = %d; sol = %5g\n", ret, sol); + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + printf("node %d: pi = %5g\n", i, node(v)->pi); + for (a = v->out; a != NULL; a = a->t_next) + { w = a->head; + printf("arc %d->%d: x = %5g; lambda = %5g\n", + v->i, w->i, arc(a)->x, + arc(a)->cost - (node(v)->pi - node(w)->pi)); + } + } + glp_delete_graph(G); + return 0; +} +\end{verbatim} +\end{footnotesize} + +If `\verb|sample.min|' is the example data file from the subsection +describing \verb|glp_read_mincost|, the output may look like follows: + +\begin{footnotesize} +\begin{verbatim} +Reading min-cost flow problem data from `sample.min'... +Flow network has 9 nodes and 14 arcs +24 lines were read +ret = 0; sol = 213 +node 1: pi = -12 +arc 1->4: x = 13; lambda = 0 +arc 1->2: x = 7; lambda = 0 +node 2: pi = -12 +arc 2->4: x = 0; lambda = 3 +arc 2->3: x = 7; lambda = 0 +node 3: pi = -14 +arc 3->8: x = 5; lambda = 0 +arc 3->5: x = 2; lambda = 3 +node 4: pi = -12 +arc 4->5: x = 13; lambda = 0 +node 5: pi = -12 +arc 5->7: x = 4; lambda = -1 +arc 5->6: x = 11; lambda = 0 +arc 5->2: x = 0; lambda = 1 +node 6: pi = -17 +arc 6->8: x = 4; lambda = 3 +arc 6->7: x = 7; lambda = -3 +node 7: pi = -20 +arc 7->9: x = 11; lambda = 0 +node 8: pi = -14 +arc 8->9: x = 9; lambda = 0 +node 9: pi = -23 +\end{verbatim} +\end{footnotesize} + +\subsection{glp\_mincost\_relax4 --- solve minimum cost flow problem +with relaxation\\method of Bertsekas and Tseng (RELAX-IV)} + +\synopsis + +\begin{verbatim} + int glp_mincost_relax4(glp_graph *G, int v_rhs, int a_low, int a_cap, + int a_cost, int crash, double *sol, int a_x, int a_rc); +\end{verbatim} + +\description + +The routine \verb|glp_mincost_relax4| finds optimal solution to the +minimum cost flow problem with the relaxation method RELAX-IV developed +by Bertsekas and Tseng.\footnote{GLPK implementation of this method is +based on a C translation of the original Fortran code {\tt RELAX4} +written by Dimitri P. Bertsekas and Paul Tseng, with a contribution by +Jonathan Eckstein in the phase II initialization.} This method is one +of most efficient methods for network optimization. + +Note that this routine requires all the problem data to be +integer-valued. + +The parameter \verb|G| is a graph (network) program object which +specifies the minimum cost flow problem instance to be solved. + +The parameter \verb|v_rhs| specifies an offset of the field of type +\verb|double| in the vertex data block, which contains $b_i$, the +supply/demand value. This value must be integer in the range +[$-$\verb|INT_MAX|/4, $+$\verb|INT_MAX|/4]. If \verb|v_rhs| $<0$, it is +assumed that $b_i=0$ for all nodes. + +The parameter \verb|a_low| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $l_{ij}$, the lower +bound to the arc flow. This bound must be integer in the range +{\linebreak} [$0$, \verb|INT_MAX|/4]. If \verb|a_low| $<0$, it is +assumed that $l_{ij}=0$ for all arcs. + +The parameter \verb|a_cap| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $u_{ij}$, the upper +bound to the arc flow (the arc capacity). This bound must be integer in +the range [$l_{ij}$, \verb|INT_MAX|/4]. If \verb|a_cap| $<0$, it is +assumed that $u_{ij}=1$ for all arcs. + +The parameter \verb|a_cost| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $c_{ij}$, the +per-unit cost of the arc flow. This value must be integer in the range +[$-$\verb|INT_MAX|/4, $+$\verb|INT_MAX|/4]. If \verb|a_cost| $<0$, it +is assumed that $c_{ij}=0$ for all arcs. + +The parameter \verb|crash| is option specifying initialization method: + +0 --- default initialization is used; + +1 --- auction initialization is used. + +\noindent +If \verb|crash| = 1, initialization is performed with a special crash +procedure based on an auction/shorest path method. This option is +recommended for difficult problems where the default initialization +results in long running times. + +The parameter \verb|sol| specifies a location, to which the routine +stores the objective value (that is, the total cost) found. If +\verb|sol| is NULL, the objective value is not stored. + +\newpage + +The parameter \verb|a_x| specifies an offset of the field of type +\verb|double| in the arc data block, to which the routine stores +$x_{ij}$, the arc flow found. If \verb|a_x| $<0$, the arc flow value is +not stored. + +The parameter \verb|a_rc| specifies an offset of the field of type +\verb|double| in the arc data block, to which the routine stores +the reduced cost for corresponding arc flow (see (3) in Subsection +``Background''). If \verb|a_rc| $<0$, the reduced cost is not stored. + +Note that all solution components (the objective value, arc flows, and +node potentials) computed by the routine are always integer-valued. + +\returns + +\begin{retlist} +0 & Optimal solution found.\\ + +\verb|GLP_ENOPFS| & No (primal) feasible solution exists.\\ + +\verb|GLP_EDATA| & Unable to start the search, because some problem +data are either not integer-valued or out of range.\\ + +\verb|GLP_ERANGE| & Unable to start the search because of integer +overflow.\\ +\end{retlist} + +\para{Example} + +The example program below reads the minimum cost problem instance in +DIMACS format from file `\verb|sample.min|', solves it by using the +routine \verb|glp_mincost_relax4|, and writes the solution found on the +standard output. + +\begin{footnotesize} +\begin{verbatim} +#include +#include +#include +#include + +typedef struct { double rhs; } v_data; +typedef struct { double low, cap, cost, x, rc; } a_data; + +#define node(v) ((v_data *)((v)->data)) +#define arc(a) ((a_data *)((a)->data)) + +int main(void) +{ glp_graph *G; + glp_vertex *v, *w; + glp_arc *a; + int i, ret; + double sol; + G = glp_create_graph(sizeof(v_data), sizeof(a_data)); + glp_read_mincost(G, offsetof(v_data, rhs), + offsetof(a_data, low), offsetof(a_data, cap), + offsetof(a_data, cost), "sample.min"); + ret = glp_mincost_relax4(G, offsetof(v_data, rhs), + offsetof(a_data, low), offsetof(a_data, cap), + offsetof(a_data, cost), 0, &sol, offsetof(a_data, x), + offsetof(a_data, rc)); + printf("ret = %d; sol = %5g\n", ret, sol); + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { w = a->head; + printf("arc %d->%d: x = %5g; rc = %5g\n", + v->i, w->i, arc(a)->x, arc(a)->rc); + } + } + glp_delete_graph(G); + return 0; +} +\end{verbatim} +\end{footnotesize} + +If `\verb|sample.min|' is the example data file from the subsection +describing \verb|glp_read_mincost|, the output may look like follows: + +\begin{footnotesize} +\begin{verbatim} +Reading min-cost flow problem data from `sample.min'... +Flow network has 9 nodes and 14 arcs +24 lines were read +ret = 0; sol = 213 +arc 1->4: x = 13; rc = 0 +arc 1->2: x = 7; rc = 0 +arc 2->4: x = 0; rc = 3 +arc 2->3: x = 7; rc = 0 +arc 3->8: x = 5; rc = 0 +arc 3->5: x = 2; rc = 3 +arc 4->5: x = 13; rc = 0 +arc 5->7: x = 4; rc = -1 +arc 5->6: x = 11; rc = 0 +arc 5->2: x = 0; rc = 1 +arc 6->8: x = 4; rc = 3 +arc 6->7: x = 7; rc = -3 +arc 7->9: x = 11; rc = 0 +arc 8->9: x = 9; rc = 0 +\end{verbatim} +\end{footnotesize} + +\subsection{glp\_netgen --- Klingman's network problem generator} + +\synopsis + +\begin{verbatim} + int glp_netgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, + const int parm[1+15]); +\end{verbatim} + +\description + +The routine \verb|glp_netgen| is a GLPK version of the network problem +generator developed by Dr.~Darwin~Klingman.\footnote{D.~Klingman, +A.~Napier, and J.~Stutz. NETGEN: A program for generating large scale +capacitated assignment, transportation, and minimum cost flow networks. +Management Science 20 (1974), 814-20.} It can create capacitated and +uncapacitated minimum cost flow (or transshipment), transportation, and +assignment problems. + +The parameter \verb|G| specifies the graph object, to which the +generated problem data have to be stored. Note that on entry the graph +object is erased with the routine \verb|glp_erase_graph|. + +The parameter \verb|v_rhs| specifies an offset of the field of type +\verb|double| in the vertex data block, to which the routine stores the +supply or demand value. If \verb|v_rhs| $<0$, the value is not stored. + +The parameter \verb|a_cap| specifies an offset of the field of type +\verb|double| in the arc data block, to which the routine stores the +arc capacity. If \verb|a_cap| $<0$, the capacity is not stored. + +\newpage + +The parameter \verb|a_cost| specifies an offset of the field of type +\verb|double| in the arc data block, to which the routine stores the +per-unit cost if the arc flow. If \verb|a_cost| $<0$, the cost is not +stored. + +The array \verb|parm| contains description of the network to be +generated: + +\begin{tabular}{@{}lll@{}} +\verb|parm[0] |& ¬ used\\ +\verb|parm[1] |&\verb|iseed |&8-digit positive random number seed\\ +\verb|parm[2] |&\verb|nprob |&8-digit problem id number\\ +\verb|parm[3] |&\verb|nodes |&total number of nodes\\ +\verb|parm[4] |&\verb|nsorc |&total number of source nodes +(including transshipment nodes)\\ +\verb|parm[5] |&\verb|nsink |&total number of sink nodes +(including transshipment nodes)\\ +\verb|parm[6] |&\verb|iarcs |&number of arc\\ +\verb|parm[7] |&\verb|mincst|&minimum cost for arcs\\ +\verb|parm[8] |&\verb|maxcst|&maximum cost for arcs\\ +\verb|parm[9] |&\verb|itsup |&total supply\\ +\verb|parm[10]|&\verb|ntsorc|&number of transshipment source nodes\\ +\verb|parm[11]|&\verb|ntsink|&number of transshipment sink nodes\\ +\verb|parm[12]|&\verb|iphic |&percentage of skeleton arcs to be given +the maximum cost\\ +\verb|parm[13]|&\verb|ipcap |&percentage of arcs to be capacitated\\ +\verb|parm[14]|&\verb|mincap|&minimum upper bound for capacitated arcs\\ +\verb|parm[15]|&\verb|maxcap|&maximum upper bound for capacitated arcs\\ +\end{tabular} + +\returns + +If the instance was successfully generated, the routine +\verb|glp_netgen| returns zero; otherwise, if specified parameters are +inconsistent, the routine returns a non-zero error code. + +\para{Notes} + +1. The routine generates a transportation problem if: +$${\tt nsorc}+{\tt nsink}={\tt nodes}, +\ {\tt ntsorc}=0,\ \mbox{and}\ {\tt ntsink}=0.$$ + +2. The routine generates an assignment problem if the requirements for +a transportation problem are met and: +$${\tt nsorc}={\tt nsink}\ \mbox{and}\ {\tt itsup}={\tt nsorc}.$$ + +3. The routine always generates connected graphs. So, if the number of +requested arcs has been reached and the generated instance is not fully +connected, the routine generates a few remaining arcs to ensure +connectedness. Thus, the actual number of arcs generated by the routine +may be greater than the requested number of arcs. + +\subsection{glp\_netgen\_prob --- Klingman's standard network problem +instance} + +\synopsis + +\begin{verbatim} + void glp_netgen_prob(int nprob, int parm[1+15]); +\end{verbatim} + +\description + +The routine \verb|glp_netgen_prob| provides the set of parameters for +Klingman's network problem generator (see the routine +\verb|glp_netgen|), which describe a standard network problem instance. + +The parameter \verb|nprob| ($101\leq$ \verb|nprob| $\leq 150$) +specifies the problem instance number. + +The array \verb|parm| contains description of the network, provided by +the routine. (For detailed description of these parameters see comments +to the routine \verb|glp_netgen|.) + +\para{Problem characteristics} + +The table below shows characteristics of Klingman's standard network +problem instances. +$$ +\begin{array}{crrr} +{\rm Problem} & {\rm Nodes} & {\rm Arcs} & {\rm Optimum} \\ +\hline +101 & 5000 & 25336 & 6191726 \\ +102 & 5000 & 25387 & 72337144 \\ +103 & 5000 & 25355 & 218947553 \\ +104 & 5000 & 25344 & -19100371 \\ +105 & 5000 & 25332 & 31192578 \\ +106 & 5000 & 12870 & 4314276 \\ +107 & 5000 & 37832 & 7393769 \\ +108 & 5000 & 50309 & 8405738 \\ +109 & 5000 & 75299 & 9190300 \\ +110 & 5000 & 12825 & 8975048 \\ +111 & 5000 & 37828 & 4747532 \\ +112 & 5000 & 50325 & 4012671 \\ +113 & 5000 & 75318 & 2979725 \\ +114 & 5000 & 26514 & 5821181 \\ +115 & 5000 & 25962 & 6353310 \\ +116 & 5000 & 25304 & 5915426 \\ +117 & 5000 & 12816 & 4420560 \\ +118 & 5000 & 37797 & 7045842 \\ +119 & 5000 & 50301 & 7724179 \\ +120 & 5000 & 75330 & 8455200 \\ +121 & 5000 & 25000 & 66366360 \\ +122 & 5000 & 25000 & 30997529 \\ +123 & 5000 & 25000 & 23388777 \\ +124 & 5000 & 25000 & 17803443 \\ +125 & 5000 & 25000 & 14119622 \\ +\end{array} +\hspace{.5in} +\begin{array}{crrr} +{\rm Problem} & {\rm Nodes} & {\rm Arcs} & {\rm Optimum} \\ +\hline +126 & 5000 & 12500 & 18802218 \\ +127 & 5000 & 37500 & 27674647 \\ +128 & 5000 & 50000 & 30906194 \\ +129 & 5000 & 75000 & 40905209 \\ +130 & 5000 & 12500 & 38939608 \\ +131 & 5000 & 37500 & 16752978 \\ +132 & 5000 & 50000 & 13302951 \\ +133 & 5000 & 75000 & 9830268 \\ +134 & 1000 & 25000 & 3804874 \\ +135 & 2500 & 25000 & 11729616 \\ +136 & 7500 & 25000 & 33318101 \\ +137 & 10000 & 25000 & 46426030 \\ +138 & 5000 & 25000 & 60710879 \\ +139 & 5000 & 25000 & 32729682 \\ +140 & 5000 & 25000 & 27183831 \\ +141 & 5000 & 25000 & 19963286 \\ +142 & 5000 & 25000 & 20243457 \\ +143 & 5000 & 25000 & 18586777 \\ +144 & 5000 & 25000 & 2504591 \\ +145 & 5000 & 25000 & 215956138 \\ +146 & 5000 & 25000 & 2253113811 \\ +147 & 5000 & 25000 & -427908373 \\ +148 & 5000 & 25000 & -92965318 \\ +149 & 5000 & 25000 & 86051224 \\ +150 & 5000 & 25000 & 619314919 \\ +\end{array} +$$ + +\subsection{glp\_gridgen --- grid-like network problem generator} + +\synopsis + +\begin{verbatim} + int glp_gridgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, + const int parm[1+14]); +\end{verbatim} + +\description + +The routine \verb|glp_gridgen| is a GLPK version of the grid-like +network problem generator developed by Yusin Lee and Jim +Orlin.\footnote{Y.~Lee and J.~Orlin. GRIDGEN generator., 1991. The +original code is publically available from +\url{ftp://dimacs.rutgers.edu/pub/netflow/generators/network/gridgen}.} + +\newpage + +The parameter \verb|G| specifies the graph object, to which the +generated problem data have to be stored. Note that on entry the graph +object is erased with the routine \verb|glp_erase_graph|. + +The parameter \verb|v_rhs| specifies an offset of the field of type +\verb|double| in the vertex data block, to which the routine stores the +supply or demand value. If \verb|v_rhs| $<0$, the value is not stored. + +The parameter \verb|a_cap| specifies an offset of the field of type +\verb|double| in the arc data block, to which the routine stores the +arc capacity. If \verb|a_cap| $<0$, the capacity is not stored. + +The parameter \verb|a_cost| specifies an offset of the field of type +\verb|double| in the arc data block, to which the routine stores the +per-unit cost if the arc flow. If \verb|a_cost| $<0$, the cost is not +stored. + +The array \verb|parm| contains parameters of the network to be +generated: + +\begin{tabular}{@{}ll@{}} +\verb|parm[0] |¬ used\\ +\verb|parm[1] |&two-ways arcs indicator:\\ + &1 --- if links in both direction should be generated\\ + &0 --- otherwise\\ +\verb|parm[2] |&random number seed (a positive integer)\\ +\verb|parm[3] |&number of nodes (the number of nodes generated might +be slightly different to\\&make the network a grid)\\ +\verb|parm[4] |&grid width\\ +\verb|parm[5] |&number of sources\\ +\verb|parm[6] |&number of sinks\\ +\verb|parm[7] |&average degree\\ +\verb|parm[8] |&total flow\\ +\verb|parm[9] |&distribution of arc costs: +1 --- uniform, 2 --- exponential\\ +\verb|parm[10]|&lower bound for arc cost (uniform), +$100\lambda$ (exponential)\\ +\verb|parm[11]|&upper bound for arc cost (uniform), +not used (exponential)\\ +\verb|parm[12]|&distribution of arc capacities: +1 --- uniform, 2 --- exponential\\ +\verb|parm[13]|&lower bound for arc capacity (uniform), +$100\lambda$ (exponential)\\ +\verb|parm[14]|&upper bound for arc capacity (uniform), +not used (exponential)\\ +\end{tabular} + +\returns + +If the instance was successfully generated, the routine +\verb|glp_gridgen| returns zero; otherwise, if specified parameters are +inconsistent, the routine returns a non-zero error code. + +\para{Comments\footnote{This material is based on comments +to the original version of GRIDGEN.}} + +This network generator generates a grid-like network plus a super node. +In additional to the arcs connecting the nodes in the grid, there is an +arc from each supply node to the super node and from the super node to +each demand node to guarantee feasiblity. These arcs have very high +costs and very big capacities. + +The idea of this network generator is as follows: First, a grid of +$n_1\times n_2$ is generated. For example, $5\times 3$. The nodes are +numbered as 1 to 15, and the supernode is numbered as +$n_1\times n_2+1$. Then arcs between adjacent nodes are generated. +For these arcs, the user is allowed to specify either to generate +two-way arcs or one-way arcs. If two-way arcs are to be generated, two +arcs, one in each direction, will be generated between each adjacent +node pairs. Otherwise, only one arc will be generated. If this is the +case, the arcs will be generated in alterntive directions as shown +below. + +\medskip + +\noindent\hfil +\xymatrix +{1\ar[r]\ar[d]&2\ar[r]&3\ar[r]\ar[d]&4\ar[r]&5\ar[d]\\ +6\ar[d]&7\ar[l]\ar[u]&8\ar[l]\ar[d]&9\ar[l]\ar[u]&10\ar[l]\ar[d]\\ +11\ar[r]&12\ar[r]\ar[u]&13\ar[r]&14\ar[r]\ar[u]&15\\ +} + +\medskip + +Then the arcs between the super node and the source/sink nodes are +added as mentioned before. If the number of arcs still doesn't reach +the requirement, additional arcs will be added by uniformly picking +random node pairs. There is no checking to prevent multiple arcs +between any pair of nodes. However, there will be no self-arcs (arcs +that poins back to its tail node) in the network. + +The source and sink nodes are selected uniformly in the network, and +the imbalances of each source/sink node are also assigned by uniform +distribution. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Maximum flow problem} + +\subsection{Background} + +The {\it maximum flow problem} (MAXFLOW) is stated as follows. Let +there be given a directed graph (flow network) $G=(V,A)$, where $V$ is +a set of vertices (nodes), and $A\subseteq V\times V$ is a set of arcs. +Let also for each arc $a=(i,j)\in A$ there be given its capacity +$u_{ij}$. The problem is, for given {\it source} node $s\in V$ and +{\it sink} node $t\in V$, to find flows $x_{ij}$ through every arc of +the network, which satisfy the specified arc capacities and the +conservation constraints at all nodes, and maximize the total flow $F$ +through the network from $s$ to $t$. Here the conservation constraint +at a node means that the total flow entering this node through its +incoming arcs (plus $F$, if it is the source node) must be equal to the +total flow leaving this node through its outgoing arcs (plus $F$, if it +is the sink node). An example of the maximum flow problem, +where $s=v_1$ and $t=v_9$, is shown on Fig.~2. + +\medskip + +\noindent\hfil +\xymatrix @C=48pt +{_{F}\ar@{~>}[d]& +v_2\ar[r]|{_{10}}\ar[dd]|{_{9}}& +v_3\ar[dd]|{_{12}}\ar[r]|{_{18}}& +v_8\ar[rd]|{_{20}}&\\ +v_1\ar[ru]|{_{14}}\ar[rd]|{_{23}}&&& +v_6\ar[d]|{_{7}}\ar[u]|{_{8}}& +v_9\ar@{~>}[d]\\ +&v_4\ar[r]|{_{26}}& +v_5\ar[luu]|{_{11}}\ar[ru]|{_{25}}\ar[r]|{_{4}}& +v_7\ar[ru]|{_{15}}&_{F}\\ +} + +\medskip + +\noindent\hfil +Fig.~2. An example of the maximum flow problem. + +\medskip + +The maximum flow problem can be naturally formulated as the following +LP problem: + +\noindent +\hspace{1in}maximize +$$F\eqno(4)$$ +\hspace{1in}subject to +$$\sum_{(i,j)\in A}x_{ij}-\sum_{(j,i)\in A}x_{ji}=\left\{ +\begin{array}{@{\ }rl} ++F,&\hbox{for}\ i=s\\ + 0,&\hbox{for all}\ i\in V\backslash\{s,t\}\\ +-F,&\hbox{for}\ i=t\\ +\end{array} +\right.\eqno(5) +$$ +$$0\leq x_{ij}\leq u_{ij}\ \ \ \hbox{for all}\ (i,j)\in A +\eqno(6)$$ + +\noindent +where $F\geq 0$ is an additional variable playing the role of the +objective. + +Another LP formulation of the maximum flow problem, which does not +include the variable $F$, is the following: + +\noindent +\hspace{1in}maximize +$$z=\sum_{(s,j)\in A}x_{sj}-\sum_{(j,s)\in A}x_{js}\ (=F)\eqno(7)$$ +\hspace{1in}subject to +$$\sum_{(i,j)\in A}x_{ij}-\sum_{(j,i)\in A}x_{ji}\left\{ +\begin{array}{@{\ }rl} +\geq 0,&\hbox{for}\ i=s\\ +=0,&\hbox{for all}\ i\in V\backslash\{s,t\}\\ +\leq 0,&\hbox{for}\ i=t\\ +\end{array} +\right.\eqno(8) +$$ +$$0\leq x_{ij}\leq u_{ij}\ \ \ \hbox{for all}\ (i,j)\in A +\eqno(9)$$ + +\subsection{glp\_read\_maxflow --- read maximum flow problem data in +DIMACS\\format} + +\synopsis + +\begin{verbatim} + int glp_read_maxflow(glp_graph *G, int *s, int *t, int a_cap, + const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_read_maxflow| reads the maximum flow problem +data from a text file in DIMACS format. + +The parameter \verb|G| specifies the graph object, to which the problem +data have to be stored. Note that before reading data the current +content of the graph object is completely erased with the routine +\verb|glp_erase_graph|. + +The pointer \verb|s| specifies a location, to which the routine stores +the ordinal number of the source node. If \verb|s| is \verb|NULL|, the +source node number is not stored. + +The pointer \verb|t| specifies a location, to which the routine stores +the ordinal number of the sink node. If \verb|t| is \verb|NULL|, the +sink node number is not stored. + +The parameter \verb|a_cap| specifies an offset of the field of type +\verb|double| in the arc data block, to which the routine stores +$u_{ij}$, the arc capacity. If \verb|a_cap| $<0$, the arc capacity is +not stored. + +The character string \verb|fname| specifies the name of a text file to +be read in. (If the file name name ends with the suffix `\verb|.gz|', +the file is assumed to be compressed, in which case the routine +decompresses it ``on the fly''.) + +\returns + +If the operation was successful, the routine returns zero. Otherwise, +it prints an error message and returns non-zero. + +\para{Example} + +\begin{footnotesize} +\begin{verbatim} +typedef struct +{ /* arc data block */ + ... + double cap; + ... +} a_data; + +int main(void) +{ glp_graph *G; + int s, t, ret; + G = glp_create_graph(..., sizeof(a_data)); + ret = glp_read_maxflow(G, &s, &t, offsetof(a_data, cap), + "sample.max"); + if (ret != 0) goto ... + ... +} +\end{verbatim} +\end{footnotesize} + +\newpage + +\para{DIMACS maximum flow problem format\footnote{This material is +based on the paper ``The First DIMACS International Algorithm +Implementation Challenge: Problem Definitions and Specifications'', +which is publically available at +\url{http://dimacs.rutgers.edu/Challenges/}.}} +\label{subsecmaxflow} + +The DIMACS input file is a plain ASCII text file. It contains +{\it lines} of several types described below. A line is terminated with +an end-of-line character. Fields in each line are separated by at least +one blank space. Each line begins with a one-character designator to +identify the line type. + +Note that DIMACS requires all numerical quantities to be integers in +the range $[-2^{31},\ 2^{31}-1]$ while GLPK allows the quantities to be +floating-point numbers. + +\para{Comment lines.} Comment lines give human-readable information +about the file and are ignored by programs. Comment lines can appear +anywhere in the file. Each comment line begins with a lower-case +character \verb|c|. + +\begin{verbatim} + c This is a comment line +\end{verbatim} + +\para{Problem line.} There is one problem line per data file. The +problem line must appear before any node or arc descriptor lines. +It has the following format: + +\begin{verbatim} + p max NODES ARCS +\end{verbatim} + +\noindent +The lower-case character \verb|p| signifies that this is a problem line. +The three-character problem designator \verb|max| identifies the file as +containing specification information for the maximum flow problem. The +\verb|NODES| field contains an integer value specifying the number of +nodes in the network. The \verb|ARCS| field contains an integer value +specifying the number of arcs in the network. + +\para{Node descriptors.} Two node descriptor lines for the source and +sink nodes must appear before all arc descriptor lines. They may appear +in either order, each with the following format: + +\begin{verbatim} + n ID WHICH +\end{verbatim} + +\noindent +The lower-case character \verb|n| signifies that this a node descriptor +line. The \verb|ID| field gives a node identification number, +an integer between 1 and \verb|NODES|. The \verb|WHICH| field gives +either a lower-case \verb|s| or \verb|t|, designating the source and +sink, respectively. + +\para{Arc descriptors.} There is one arc descriptor line for each arc +in the network. Arc descriptor lines are of the following format: + +\begin{verbatim} + a SRC DST CAP +\end{verbatim} + +\noindent +The lower-case character \verb|a| signifies that this is an arc +descriptor line. For a directed arc $(i,j)$ the \verb|SRC| field gives +the identification number $i$ for the tail endpoint, and the \verb|DST| +field gives the identification number $j$ for the head endpoint. +Identification numbers are integers between 1 and \verb|NODES|. The +\verb|CAP| field gives the arc capacity, i.e. maximum amount of flow +that can be sent along arc $(i,j)$ in a feasible flow. + +\para{Example.} Below here is an example of the data file in DIMACS +format corresponding to the maximum flow problem shown on Fig~2. + +\begin{footnotesize} +\begin{verbatim} +c sample.max +c +c This is an example of the maximum flow problem data +c in DIMACS format. +c +p max 9 14 +c +n 1 s +n 9 t +c +a 1 2 14 +a 1 4 23 +a 2 3 10 +a 2 4 9 +a 3 5 12 +a 3 8 18 +a 4 5 26 +a 5 2 11 +a 5 6 25 +a 5 7 4 +a 6 7 7 +a 6 8 8 +a 7 9 15 +a 8 9 20 +c +c eof +\end{verbatim} +\end{footnotesize} + +\subsection{glp\_write\_maxflow --- write maximum flow problem data in +DIMACS\\format} + +\synopsis + +\begin{verbatim} + int glp_write_maxflow(glp_graph *G, int s, int t, int a_cap, + const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_write_maxflow| writes the maximum flow problem +data to a text file in DIMACS format. + +The parameter \verb|G| is the graph (network) program object, which +specifies the maximum flow problem instance. + +The parameter \verb|s| specifies the ordinal number of the source node. + +The parameter \verb|t| specifies the ordinal number of the sink node. + +The parameter \verb|a_cap| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $u_{ij}$, the upper +bound to the arc flow (the arc capacity). If the upper bound is +specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e. +the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that +$u_{ij}=1$ for all arcs. + +The character string \verb|fname| specifies a name of the text file to +be written out. (If the file name ends with suffix `\verb|.gz|', the +file is assumed to be compressed, in which case the routine performs +automatic compression on writing it.) + +\returns + +If the operation was successful, the routine returns zero. Otherwise, +it prints an error message and returns non-zero. + +\newpage + +\subsection{glp\_maxflow\_lp --- convert maximum flow problem to LP} + +\synopsis + +\begin{verbatim} + void glp_maxflow_lp(glp_prob *P, glp_graph *G, int names, int s, int t, + int a_cap); +\end{verbatim} + +\description + +The routine \verb|glp_maxflow_lp| builds LP problem (7)---(9), which +corresponds to the specified maximum flow problem. + +The parameter \verb|P| is the resultant LP problem object to be built. +Note that on entry its current content is erased with the routine +\verb|glp_erase_prob|. + +The parameter \verb|G| is the graph (network) program object, which +specifies the maximum flow problem instance. + +The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, the +routine uses symbolic names of the graph object components to assign +symbolic names to the LP problem object components. If the flag is +\verb|GLP_OFF|, no symbolic names are assigned. + +The parameter \verb|s| specifies the ordinal number of the source node. + +The parameter \verb|t| specifies the ordinal number of the sink node. + +The parameter \verb|a_cap| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $u_{ij}$, the upper +bound to the arc flow (the arc capacity). If the upper bound is +specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e. +the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that +$u_{ij}=1$ for all arcs. + +\para{Example} + +The example program below reads the maximum flow problem in DIMACS +format from file `\verb|sample.max|', converts the instance to LP, and +then writes the resultant LP in CPLEX format to file +`\verb|maxflow.lp|'. + +\begin{footnotesize} +\begin{verbatim} +#include +#include + +int main(void) +{ glp_graph *G; + glp_prob *P; + int s, t; + G = glp_create_graph(0, sizeof(double)); + glp_read_maxflow(G, &s, &t, 0, "sample.max"); + P = glp_create_prob(); + glp_maxflow_lp(P, G, GLP_ON, s, t, 0); + glp_delete_graph(G); + glp_write_lp(P, NULL, "maxflow.lp"); + glp_delete_prob(P); + return 0; +} +\end{verbatim} +\end{footnotesize} + +If `\verb|sample.max|' is the example data file from the previous +subsection, the output `\verb|maxflow.lp|' may look like follows: + +\newpage + +\begin{footnotesize} +\begin{verbatim} +Maximize + obj: + x(1,4) + x(1,2) + +Subject To + r_1: + x(1,2) + x(1,4) >= 0 + r_2: - x(5,2) + x(2,3) + x(2,4) - x(1,2) = 0 + r_3: + x(3,5) + x(3,8) - x(2,3) = 0 + r_4: + x(4,5) - x(2,4) - x(1,4) = 0 + r_5: + x(5,2) + x(5,6) + x(5,7) - x(4,5) - x(3,5) = 0 + r_6: + x(6,7) + x(6,8) - x(5,6) = 0 + r_7: + x(7,9) - x(6,7) - x(5,7) = 0 + r_8: + x(8,9) - x(6,8) - x(3,8) = 0 + r_9: - x(8,9) - x(7,9) <= 0 + +Bounds + 0 <= x(1,4) <= 23 + 0 <= x(1,2) <= 14 + 0 <= x(2,4) <= 9 + 0 <= x(2,3) <= 10 + 0 <= x(3,8) <= 18 + 0 <= x(3,5) <= 12 + 0 <= x(4,5) <= 26 + 0 <= x(5,7) <= 4 + 0 <= x(5,6) <= 25 + 0 <= x(5,2) <= 11 + 0 <= x(6,8) <= 8 + 0 <= x(6,7) <= 7 + 0 <= x(7,9) <= 15 + 0 <= x(8,9) <= 20 + +End +\end{verbatim} +\end{footnotesize} + +\subsection{glp\_maxflow\_ffalg --- solve maximum flow problem with +Ford-Fulkerson\\algorithm} + +\synopsis + +\begin{verbatim} + int glp_maxflow_ffalg(glp_graph *G, int s, int t, int a_cap, double *sol, + int a_x, int v_cut); +\end{verbatim} + +\description + +The routine \verb|glp_mincost_ffalg| finds optimal solution to the +maximum flow problem with the Ford-Fulkerson algorithm.\footnote{GLPK +implementation of the Ford-Fulkerson algorithm is based on the +following book: L.~R.~Ford,~Jr., and D.~R.~Fulkerson, ``Flows in +Networks,'' The RAND Corp., Report R-375-PR (August 1962), Chap. I +``Static Maximal Flow,'' pp.~30-33.} Note that this routine requires +all the problem data to be integer-valued. + +The parameter \verb|G| is a graph (network) program object which +specifies the maximum flow problem instance to be solved. + +The parameter $s$ specifies the ordinal number of the source node. + +\newpage + +The parameter $t$ specifies the ordinal number of the sink node. + +The parameter \verb|a_cap| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $u_{ij}$, the upper +bound to the arc flow (the arc capacity). This bound must be integer in +the range [0, \verb|INT_MAX|]. If \verb|a_cap| $<0$, it is assumed that +$u_{ij}=1$ for all arcs. + +The parameter \verb|sol| specifies a location, to which the routine +stores the objective value (that is, the total flow from $s$ to $t$) +found. If \verb|sol| is NULL, the objective value is not stored. + +The parameter \verb|a_x| specifies an offset of the field of type +\verb|double| in the arc data block, to which the routine stores +$x_{ij}$, the arc flow found. If \verb|a_x| $<0$, the arc flow values +are not stored. + +The parameter \verb|v_cut| specifies an offset of the field of type +\verb|int| in the vertex data block, to which the routine stores node +flags corresponding to the optimal solution found: if the node flag is +1, the node is labelled, and if the node flag is 0, the node is +unlabelled. The calling program may use these node flags to determine +the {\it minimal cut}, which is a subset of arcs whose one endpoint is +labelled and other is not. If \verb|v_cut| $<0$, the node flags are not +stored. + +Note that all solution components (the objective value and arc flows) +computed by the routine are always integer-valued. + +\returns + +\begin{retlist} +0 & Optimal solution found.\\ + +\verb|GLP_EDATA| & Unable to start the search, because some problem +data are either not integer-valued or out of range.\\ +\end{retlist} + +\para{Example} + +The example program shown below reads the maximum flow problem instance +in DIMACS format from file `\verb|sample.max|', solves it using the +routine \verb|glp_maxflow_ffalg|, and write the solution found to the +standard output. + +\begin{footnotesize} +\begin{verbatim} +#include +#include +#include +#include + +typedef struct { int cut; } v_data; +typedef struct { double cap, x; } a_data; + +#define node(v) ((v_data *)((v)->data)) +#define arc(a) ((a_data *)((a)->data)) + +int main(void) +{ glp_graph *G; + glp_vertex *v, *w; + glp_arc *a; + int i, s, t, ret; + double sol; + G = glp_create_graph(sizeof(v_data), sizeof(a_data)); + glp_read_maxflow(G, &s, &t, offsetof(a_data, cap), + "sample.max"); + ret = glp_maxflow_ffalg(G, s, t, offsetof(a_data, cap), + &sol, offsetof(a_data, x), offsetof(v_data, cut)); + printf("ret = %d; sol = %5g\n", ret, sol); + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { w = a->head; + printf("x[%d->%d] = %5g (%d)\n", v->i, w->i, + arc(a)->x, node(v)->cut ^ node(w)->cut); + } + } + glp_delete_graph(G); + return 0; +} +\end{verbatim} +\end{footnotesize} + +If `\verb|sample.max|' is the example data file from the subsection +describing \verb|glp_read_maxflow|, the output may look like follows: + +\begin{footnotesize} +\begin{verbatim} +Reading maximum flow problem data from `sample.max'... +Flow network has 9 nodes and 14 arcs +24 lines were read +ret = 0; sol = 29 +x[1->4] = 19 (0) +x[1->2] = 10 (0) +x[2->4] = 0 (0) +x[2->3] = 10 (1) +x[3->8] = 10 (0) +x[3->5] = 0 (1) +x[4->5] = 19 (0) +x[5->7] = 4 (1) +x[5->6] = 15 (0) +x[5->2] = 0 (0) +x[6->8] = 8 (1) +x[6->7] = 7 (1) +x[7->9] = 11 (0) +x[8->9] = 18 (0) +\end{verbatim} +\end{footnotesize} + +\subsection{glp\_rmfgen --- Goldfarb's maximum flow problem generator} + +\synopsis + +\begin{verbatim} + int glp_rmfgen(glp_graph *G, int *s, int *t, int a_cap, const int parm[1+5]); +\end{verbatim} + +\description + +The routine \verb|glp_rmfgen| is a GLPK version of the maximum flow +problem generator developed by D.~Goldfarb and +M.~Grigoriadis.\footnote{D.~Goldfarb and M.~D.~Grigoriadis, +``A computational comparison of the Dinic and network simplex methods +for maximum flow.'' Annals of Op. Res. 13 (1988), +pp.~83-123.}$^{,}$\footnote{U.~Derigs and W.~Meier, ``Implementing +Goldberg's max-flow algorithm: A computational investigation.'' +Zeitschrift f\"ur Operations Research 33 (1989), +pp.~383-403.}$^{,}$\footnote{The original code of RMFGEN implemented by +Tamas Badics is publically available from +\url{ftp://dimacs.rutgers.edu/pub/netflow/generators/network/genrmf}.} + +The parameter \verb|G| specifies the graph object, to which the +generated problem data have to be stored. Note that on entry the graph +object is erased with the routine \verb|glp_erase_graph|. + +\newpage + +The pointers \verb|s| and \verb|t| specify locations, to which the +routine stores the source and sink node numbers, respectively. If +\verb|s| or \verb|t| is \verb|NULL|, corresponding node number is not +stored. + +The parameter \verb|a_cap| specifies an offset of the field of type +\verb|double| in the arc data block, to which the routine stores the arc +capacity. If \verb|a_cap| $<0$, the capacity is not stored. + +The array \verb|parm| contains description of the network to be +generated: + +\begin{tabular}{@{}lll@{}} +\verb|parm[0]|& ¬ used\\ +\verb|parm[1]|&\verb|seed|&random number seed (a positive integer)\\ +\verb|parm[2]|&\verb|a |&frame size\\ +\verb|parm[3]|&\verb|b |&depth\\ +\verb|parm[4]|&\verb|c1 |&minimal arc capacity\\ +\verb|parm[5]|&\verb|c2 |&maximal arc capacity\\ +\end{tabular} + +\returns + +If the instance was successfully generated, the routine +\verb|glp_netgen| returns zero; otherwise, if specified parameters are +inconsistent, the routine returns a non-zero error code. + +\para{Comments\footnote{This material is based on comments to the +original version of RMFGEN.}} + +The generated network is as follows. It has $b$ pieces of frames of +size $a\times a$. (So alltogether the number of vertices is +$a\times a\times b$.) + +In each frame all the vertices are connected with their neighbours +(forth and back). In addition the vertices of a frame are connected +one to one with the vertices of next frame using a random permutation +of those vertices. + +The source is the lower left vertex of the first frame, the sink is +the upper right vertex of the $b$-th frame. + +\begin{verbatim} + t + +-------+ + | .| + | . | + / | / | + +-------+/ -+ b + | | |/. + a | -v- |/ + | | |/ + +-------+ 1 + s a +\end{verbatim} + +The capacities are randomly chosen integers from the range of +$[c_1,c_2]$ in the case of interconnecting edges, and $c_2\cdot a^2$ +for the in-frame edges. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Assignment problem} + +\subsection{Background} + +Let there be given an undirected bipartite graph $G=(R\cup S,E)$, where +$R$ and $S$ are disjoint sets of vertices (nodes), and +$E\subseteq R\times S$ is a set of edges. Let also for each edge +$e=(i,j)\in E$ there be given its cost $c_{ij}$. A {\it matching} +(which in case of bipartite graph is also called {\it assignment}) +$M\subseteq E$ in $G$ is a set of pairwise non-adjacent edges, that is, +no two edges in $M$ share a common vertex. A matching, which matches +all vertices of the graph, is called a {\it perfect matching}. +Obviously, a perfect matching in bipartite graph $G=(R\cup S,E)$ +defines some bijection $R\leftrightarrow S$. + +The {\it assignment problem} has two different variants. In the first +variant the problem is to find matching (assignment) $M$, which +maximizes the sum: +$$\sum_{(i,j)\in M}c_{ij}\eqno(10)$$ +(so this variant is also called the {\it maximum weighted bipartite +matching problem} or, if all $c_{ij}=1$, the {\it maximum cardinality +bipartite matching problem}). In the second, classic variant the +problem is to find {\it perfect} matching (assignment) $M$, which +minimizes or maximizes the sum (10). + +An example of the assignment problem, which is the maximum weighted +bipartite matching problem, is shown on Fig. 3. + +The maximum weighted bipartite matching problem can be naturally +formulated as the following LP problem: + +\noindent +\hspace{1in}maximize +$$z=\sum_{(i,j)\in E}c_{ij}x_{ij}\eqno(11)$$ +\hspace{1in}subject to +$$\sum_{(i,j)\in E}x_{ij}\leq 1\ \ \ \hbox{for all}\ i\in R\eqno(12)$$ +$$\sum_{(i,j)\in E}x_{ij}\leq 1\ \ \ \hbox{for all}\ j\in S\eqno(13)$$ +$$\ \ \ \ \ \ \ \ 0\leq x_{ij}\leq 1\ \ \ \hbox{for all}\ (i,j)\in E +\eqno(14)$$ + +\noindent +where $x_{ij}=1$ means that $(i,j)\in M$, and $x_{ij}=0$ means that +$(i,j)\notin M$.\footnote{The constraint matrix of LP formulation +(11)---(14) is totally unimodular, due to which $x_{ij}\in\{0,1\}$ for +any basic solution.} + +\newpage + +\noindent\hfil +\xymatrix @C=48pt +{v_1\ar@{-}[rr]|{_{13}}\ar@{-}[rrd]|{_{21}}\ar@{-}[rrddd]|(.2){_{20}}&& +v_9\\ +v_2\ar@{-}[rr]|{_{12}}\ar@{-}[rrdd]|(.3){_{8}} +\ar@{-}[rrddd]|(.4){_{26}}&&v_{10}\\ +v_3\ar@{-}[rr]|(.2){_{22}}\ar@{-}[rrdd]|(.3){_{11}}&&v_{11}\\ +v_4\ar@{-}[rruuu]|(.6){_{12}}\ar@{-}[rr]|(.2){_{36}} +\ar@{-}[rrdd]|(.7){_{25}}&&v_{12}\\ +v_5\ar@{-}[rruu]|(.42){_{41}}\ar@{-}[rru]|(.4){_{40}} +\ar@{-}[rr]|(.75){_{11}}\ar@{-}[rrd]|(.6){_{4}}\ar@{-}[rrdd]|{_{8}} +\ar@{-}[rrddd]|{_{35}}\ar@{-}[rrdddd]|{_{32}}&&v_{13}\\ +v_6\ar@{-}[rruuuuu]|(.7){_{13}}&&v_{14}\\ +v_7\ar@{-}[rruuuuu]|(.15){_{19}}&&v_{15}\\ +v_8\ar@{-}[rruuuuuu]|(.25){_{39}}\ar@{-}[rruuuuu]|(.65){_{15}}&& +v_{16}\\ +&&v_{17}\\ +} + +\medskip + +\noindent\hfil +Fig.~3. An example of the assignment problem. + +\medskip + +Similarly, the perfect assignment problem can be naturally formulated +as the following LP problem: + +\noindent +\hspace{1in}minimize (or maximize) +$$z=\sum_{(i,j)\in E}c_{ij}x_{ij}\eqno(15)$$ +\hspace{1in}subject to +$$\sum_{(i,j)\in E}x_{ij}=1\ \ \ \hbox{for all}\ i\in R\eqno(16)$$ +$$\sum_{(i,j)\in E}x_{ij}=1\ \ \ \hbox{for all}\ j\in S\eqno(17)$$ +$$\ \ \ \ \ \ \ \ 0\leq x_{ij}\leq 1\ \ \ \hbox{for all}\ (i,j)\in E +\eqno(18)$$ + +\noindent +where variables $x_{ij}$ have the same meaning as for (11)---(14) +above. + +In GLPK an undirected bipartite graph $G=(R\cup S,E)$ is represented as +directed graph $\overline{G}=(V,A)$, where $V=R\cup S$ and +$A=\{(i,j):(i,j)\in E\}$, i.e. every edge $(i,j)\in E$ in $G$ +corresponds to arc $(i\rightarrow j)\in A$ in $\overline{G}$. + +\subsection{glp\_read\_asnprob --- read assignment problem data in +DIMACS format} + +\synopsis + +\begin{verbatim} + int glp_read_asnprob(glp_graph *G, int v_set, int a_cost, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_read_asnprob| reads the assignment problem data +from a text file in DIMACS format. + +The parameter \verb|G| specifies the graph object, to which the problem +data have to be stored. Note that before reading data the current +content of the graph object is completely erased with the routine +\verb|glp_erase_graph|. + +The parameter \verb|v_set| specifies an offset of the field of type +\verb|int| in the vertex data block, to which the routine stores the +node set indicator: + +0 --- the node is in set $R$; + +1 --- the node is in set $S$. + +\noindent +If \verb|v_set| $<0$, the node set indicator is not stored. + +The parameter \verb|a_cost| specifies an offset of the field of type +\verb|double| in the arc data block, to which the routine stores the +edge cost $c_{ij}$. If \verb|a_cost| $<0$, the edge cost is not stored. + +The character string \verb|fname| specifies the name of a text file to +be read in. (If the file name name ends with the suffix `\verb|.gz|', +the file is assumed to be compressed, in which case the routine +decompresses it ``on the fly''.) + +\returns + +If the operation was successful, the routine returns zero. Otherwise, +it prints an error message and returns non-zero. + +\para{Example.} Below here is an example program that read the +assignment problem data in DIMACS format from a text file +`\verb|sample.asn|'. + +\begin{footnotesize} +\begin{verbatim} +typedef struct +{ /* vertex data block */ + ... + int set; + ... +} v_data; + +typedef struct +{ /* arc data block */ + ... + double cost; + ... +} a_data; + +int main(void) +{ glp_graph *G; + int ret; + G = glp_create_graph(sizeof(v_data), sizeof(a_data)); + ret = glp_read_asnprob(G, offsetof(v_data, set), + offsetof(a_data, cost), "sample.asn"); + if (ret != 0) goto ... + ... +} +\end{verbatim} +\end{footnotesize} + +\para{DIMACS assignment problem format\footnote{This material is based +on the paper ``The First DIMACS International Algorithm Implementation +Challenge: Problem Definitions and Specifications'', which is +publically available at \url{http://dimacs.rutgers.edu/Challenges/}.}} +\label{subsecasnprob} + +The DIMACS input file is a plain ASCII text file. It contains +{\it lines} of several types described below. A line is terminated with +an end-of-line character. Fields in each line are separated by at least +one blank space. Each line begins with a one-character designator to +identify the line type. + +Note that DIMACS requires all numerical quantities to be integers in +the range $[-2^{31},\ 2^{31}-1]$ while GLPK allows the quantities to be +floating-point numbers. + +\para{Comment lines.} Comment lines give human-readable information +about the file and are ignored by programs. Comment lines can appear +anywhere in the file. Each comment line begins with a lower-case +character \verb|c|. + +\begin{verbatim} + c This is a comment line +\end{verbatim} + +\para{Problem line.} There is one problem line per data file. The +problem line must appear before any node or arc descriptor lines. It +has the following format: + +\begin{verbatim} + p asn NODES EDGES +\end{verbatim} + +\noindent +The lower-case character \verb|p| signifies that this is a problem line. +The three-character problem designator \verb|asn| identifies the file as +containing specification information for the assignment problem. +The \verb|NODES| field contains an integer value specifying the total +number of nodes in the graph (i.e. in both sets $R$ and $S$). The +\verb|EDGES| field contains an integer value specifying the number of +edges in the graph. + +\para{Node descriptors.} All node descriptor lines must appear before +all edge descriptor lines. The node descriptor lines lists the nodes in +set $R$ only, and all other nodes are assumed to be in set $S$. There +is one node descriptor line for each such node, with the following +format: + +\begin{verbatim} + n ID +\end{verbatim} + +\noindent +The lower-case character \verb|n| signifies that this is a node +descriptor line. The \verb|ID| field gives a node identification number, +an integer between 1 and \verb|NODES|. + +\para{Edge descriptors.} There is one edge descriptor line for each +edge in the graph. Edge descriptor lines are of the following format: + +\begin{verbatim} + a SRC DST COST +\end{verbatim} + +\noindent +The lower-case character \verb|a| signifies that this is an edge +descriptor line. For each edge $(i,j)$, where $i\in R$ and $j\in S$, +the \verb|SRC| field gives the identification number of vertex $i$, and +the \verb|DST| field gives the identification number of vertex $j$. +Identification numbers are integers between 1 and \verb|NODES|. The +\verb|COST| field contains the cost of edge $(i,j)$. + +\para{Example.} Below here is an example of the data file in DIMACS +format corresponding to the assignment problem shown on Fig~3. + +\begin{footnotesize} +\begin{verbatim} +c sample.asn +c +c This is an example of the assignment problem data +c in DIMACS format. +c +p asn 17 22 +c +n 1 +n 2 +n 3 +n 4 +n 5 +n 6 +n 7 +n 8 +c +a 1 9 13 +a 1 10 21 +a 1 12 20 +a 2 10 12 +a 2 12 8 +a 2 13 26 +a 3 11 22 +a 3 13 11 +a 4 9 12 +a 4 12 36 +a 4 14 25 +a 5 11 41 +a 5 12 40 +a 5 13 11 +a 5 14 4 +a 5 15 8 +a 5 16 35 +a 5 17 32 +a 6 9 13 +a 7 10 19 +a 8 10 39 +a 8 11 15 +c +c eof +\end{verbatim} +\end{footnotesize} + +\newpage + +\subsection{glp\_write\_asnprob --- write assignment problem data in +DIMACS format} + +\synopsis + +\begin{verbatim} + int glp_write_asnprob(glp_graph *G, int v_set, int a_cost, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_write_asnprob| writes the assignment problem data +to a text file in DIMACS format. + +The parameter \verb|G| is the graph program object, which specifies the +assignment problem instance. + +The parameter \verb|v_set| specifies an offset of the field of type +\verb|int| in the vertex data block, which contains the node set +indicator: + +0 --- the node is in set $R$; + +1 --- the node is in set $S$. + +\noindent +If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs +is in set $R$, and a node having no outgoing arcs is in set $S$. + +The parameter \verb|a_cost| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $c_{ij}$, the edge +cost. If \verb|a_cost| $<0$, it is assumed that $c_{ij}=1$ for all +edges. + +The character string \verb|fname| specifies a name of the text file to +be written out. (If the file name ends with suffix `\verb|.gz|', the +file is assumed to be compressed, in which case the routine performs +automatic compression on writing it.) + +\para{Note} + +The routine \verb|glp_write_asnprob| does not check that the specified +graph object correctly represents a bipartite graph. To make sure that +the problem data are correct, use the routine \verb|glp_check_asnprob|. + +\returns + +If the operation was successful, the routine returns zero. Otherwise, +it prints an error message and returns non-zero. + +\vspace*{-4pt} + +\subsection{glp\_check\_asnprob --- check correctness of assignment +problem data} + +\synopsis + +\begin{verbatim} + int glp_check_asnprob(glp_graph *G, int v_set); +\end{verbatim} + +\description + +The routine \verb|glp_check_asnprob| checks that the specified graph +object \verb|G| correctly represents a bipartite graph. + +The parameter \verb|v_set| specifies an offset of the field of type +\verb|int| in the vertex data block, which contains the node set +indicator: + +0 --- the node is in set $R$; + +1 --- the node is in set $S$. + +\noindent +If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs +is in set $R$, and a node having no outgoing arcs is in set $S$. + +\returns + +0 --- the data are correct; + +1 --- the set indicator of some node is 0, however, that node has one +or more incoming arcs; + +2 --- the set indicator of some node is 1, however, that node has one +or more outgoing arcs; + +3 --- the set indicator of some node is invalid (neither 0 nor 1); + +4 --- some node has both incoming and outgoing arcs. + +\subsection{glp\_asnprob\_lp --- convert assignment problem to LP} + +\synopsis + +\begin{verbatim} + int glp_asnprob_lp(glp_prob *P, int form, glp_graph *G, int names, int v_set, + int a_cost); +\end{verbatim} + +\description + +The routine \verb|glp_asnprob_lp| builds LP problem, which corresponds +to the specified assignment problem. + +The parameter \verb|P| is the resultant LP problem object to be built. +Note that on entry its current content is erased with the routine +\verb|glp_erase_prob|. + +The parameter \verb|form| defines which LP formulation should be used: + +\verb|GLP_ASN_MIN| --- perfect matching (15)---(18), minimization; + +\verb|GLP_ASN_MAX| --- perfect matching (15)---(18), maximization; + +\verb|GLP_ASN_MMP| --- maximum weighted matching (11)---(14). + +The parameter \verb|G| is the graph program object, which specifies the +assignment problem instance. + +The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, the +routine uses symbolic names of the graph object components to assign +symbolic names to the LP problem object components. If the \verb|flag| +is \verb|GLP_OFF|, no symbolic names are assigned. + +The parameter \verb|v_set| specifies an offset of the field of type +\verb|int| in the vertex data block, which contains the node set +indicator: + +0 --- the node is in set $R$; + +1 --- the node is in set $S$. + +\noindent +If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs +is in set $R$, and a node having no outgoing arcs is in set $S$. + +The parameter \verb|a_cost| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $c_{ij}$, the edge +cost. If \verb|a_cost| $<0$, it is assumed that $c_{ij}=1$ for all +edges. + +\newpage + +\returns + +If the LP problem has been successfully built, the routine +\verb|glp_asnprob_lp| returns zero, otherwise, non-zero (see the +routine \verb|glp_check_asnprob|). + +\para{Example} + +The example program below reads the assignment problem instance in +DIMACS format from file `\verb|sample.asn|', converts the instance to +LP (11)---(14), and writes the resultant LP in CPLEX format to file +`\verb|matching.lp|'. + +\begin{footnotesize} +\begin{verbatim} +#include +#include + +typedef struct { int set; } v_data; +typedef struct { double cost; } a_data; + +int main(void) +{ glp_graph *G; + glp_prob *P; + G = glp_create_graph(sizeof(v_data), sizeof(a_data)); + glp_read_asnprob(G, offsetof(v_data, set), + offsetof(a_data, cost), "sample.asn"); + P = glp_create_prob(); + glp_asnprob_lp(P, GLP_ASN_MMP, G, GLP_ON, + offsetof(v_data, set), offsetof(a_data, cost)); + glp_delete_graph(G); + glp_write_lp(P, NULL, "matching.lp"); + glp_delete_prob(P); + return 0; +} +\end{verbatim} +\end{footnotesize} + +If `\verb|sample.asn|' is the example data file from the subsection +describing \verb|glp_read_asnprob|, file `\verb|matching.lp|' may look +like follows: + +\begin{footnotesize} +\begin{verbatim} +Maximize + obj: + 20 x(1,12) + 21 x(1,10) + 13 x(1,9) + 26 x(2,13) + 8 x(2,12) + + 12 x(2,10) + 11 x(3,13) + 22 x(3,11) + 25 x(4,14) + 36 x(4,12) + + 12 x(4,9) + 32 x(5,17) + 35 x(5,16) + 8 x(5,15) + 4 x(5,14) + + 11 x(5,13) + 40 x(5,12) + 41 x(5,11) + 13 x(6,9) + 19 x(7,10) + + 15 x(8,11) + 39 x(8,10) + +Subject To + r_1: + x(1,9) + x(1,10) + x(1,12) <= 1 + r_2: + x(2,10) + x(2,12) + x(2,13) <= 1 + r_3: + x(3,11) + x(3,13) <= 1 + r_4: + x(4,9) + x(4,12) + x(4,14) <= 1 + r_5: + x(5,11) + x(5,12) + x(5,13) + x(5,14) + x(5,15) + x(5,16) + + x(5,17) <= 1 + r_6: + x(6,9) <= 1 + r_7: + x(7,10) <= 1 + r_8: + x(8,10) + x(8,11) <= 1 + r_9: + x(6,9) + x(4,9) + x(1,9) <= 1 + r_10: + x(8,10) + x(7,10) + x(2,10) + x(1,10) <= 1 + r_11: + x(8,11) + x(5,11) + x(3,11) <= 1 + r_12: + x(5,12) + x(4,12) + x(2,12) + x(1,12) <= 1 + r_13: + x(5,13) + x(3,13) + x(2,13) <= 1 + r_14: + x(5,14) + x(4,14) <= 1 + r_15: + x(5,15) <= 1 + r_16: + x(5,16) <= 1 + r_17: + x(5,17) <= 1 + +Bounds + 0 <= x(1,12) <= 1 + 0 <= x(1,10) <= 1 + 0 <= x(1,9) <= 1 + 0 <= x(2,13) <= 1 + 0 <= x(2,12) <= 1 + 0 <= x(2,10) <= 1 + 0 <= x(3,13) <= 1 + 0 <= x(3,11) <= 1 + 0 <= x(4,14) <= 1 + 0 <= x(4,12) <= 1 + 0 <= x(4,9) <= 1 + 0 <= x(5,17) <= 1 + 0 <= x(5,16) <= 1 + 0 <= x(5,15) <= 1 + 0 <= x(5,14) <= 1 + 0 <= x(5,13) <= 1 + 0 <= x(5,12) <= 1 + 0 <= x(5,11) <= 1 + 0 <= x(6,9) <= 1 + 0 <= x(7,10) <= 1 + 0 <= x(8,11) <= 1 + 0 <= x(8,10) <= 1 + +End +\end{verbatim} +\end{footnotesize} + +\subsection{glp\_asnprob\_okalg --- solve assignment problem with +out-of-kilter\\algorithm} + +\synopsis + +\begin{verbatim} + int glp_asnprob_okalg(int form, glp_graph *G, int v_set, int a_cost, + double *sol, int a_x); +\end{verbatim} + +\description + +The routine \verb|glp_mincost_okalg| finds optimal solution to the +assignment problem with the out-of-kilter +algorithm.\footnote{GLPK implementation of the out-of-kilter algorithm +is based on the following book: L.~R.~Ford,~Jr., and D.~R.~Fulkerson, +``Flows in Networks,'' The RAND Corp., Report R-375-PR (August 1962), +Chap. III ``Minimal Cost Flow Problems,'' pp.~113-26.} Note that this +routine requires all the problem data to be integer-valued. + +The parameter \verb|form| defines which LP formulation should be used: + +\verb|GLP_ASN_MIN| --- perfect matching (15)---(18), minimization; + +\verb|GLP_ASN_MAX| --- perfect matching (15)---(18), maximization; + +\verb|GLP_ASN_MMP| --- maximum weighted matching (11)---(14). + +\newpage + +The parameter \verb|G| is the graph program object, which specifies the +assignment problem instance. + +The parameter \verb|v_set| specifies an offset of the field of type +\verb|int| in the vertex data block, which contains the node set +indicator: + +0 --- the node is in set $R$; + +1 --- the node is in set $S$. + +\noindent +If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs +is in set $R$, and a node having no outgoing arcs is in set $S$. + +The parameter \verb|a_cost| specifies an offset of the field of type +\verb|double| in the arc data block, which contains $c_{ij}$, the edge +cost. This value must be integer in the range [\verb|-INT_MAX|, +\verb|+INT_MAX|]. If \verb|a_cost| $<0$, it is assumed that $c_{ij}=1$ +for all edges. + +The parameter \verb|sol| specifies a location, to which the routine +stores the objective value (that is, the total cost) found. +If \verb|sol| is \verb|NULL|, the objective value is not stored. + +The parameter \verb|a_x| specifies an offset of the field of type +\verb|int| in the arc data block, to which the routine stores $x_{ij}$. +If \verb|a_x| $<0$, this value is not stored. + +\returns + +\begin{retlist} +0 & Optimal solution found.\\ + +\verb|GLP_ENOPFS| & No (primal) feasible solution exists.\\ + +\verb|GLP_EDATA| & Unable to start the search, because the assignment +problem data are either incorrect (this error is detected by the +routine \verb|glp_check_asnprob|), not integer-valued or out of range.\\ + +\verb|GLP_ERANGE| & The search was prematurely terminated because of +integer overflow.\\ + +\verb|GLP_EFAIL| & An error has been detected in the program logic. +(If this code is returned for your problem instance, please report to +\verb||.)\\ +\end{retlist} + +\para{Comments} + +Since the out-of-kilter algorithm is designed to find a minimal cost +circulation, the routine \verb|glp_asnprob_okalg| converts the original +graph to a network suitable for this algorithm in the following +way:\footnote{The conversion is performed internally and does not +change the original graph program object passed to the routine.} + +1) it replaces each edge $(i,j)$ by arc $(i\rightarrow j)$, +flow $x_{ij}$ through which has zero lower bound ($l_{ij}=0$), unity +upper bound ($u_{ij}=1$), and per-unit cost $+c_{ij}$ (in case of +\verb|GLP_ASN_MIN|), or $-c_{ij}$ (in case of \verb|GLP_ASN_MAX| and +\verb|GLP_ASN_MMP|); + +2) then it adds one auxiliary feedback node $k$; + +3) for each original node $i\in R$ the routine adds auxiliary supply +arc $(k\rightarrow i)$, flow $x_{ki}$ through which is costless +($c_{ki}=0$) and either fixed at 1 ($l_{ki}=u_{ki}=1$, in case of +\verb|GLP_ASN_MIN| and \verb|GLP_ASN_MAX|) or has zero lower bound and +unity upper bound ($l_{ij}=0$, $u_{ij}=1$, in case of +\verb|GLP_ASN_MMP|); + +\newpage + +4) similarly, for each original node $j\in S$ the routine adds +auxiliary demand arc $(j\rightarrow k)$, flow $x_{jk}$ through which is +costless ($c_{jk}=0$) and either fixed at 1 ($l_{jk}=u_{jk}=1$, in case +of \verb|GLP_ASN_MIN| and \verb|GLP_ASN_MAX|) or has zero lower bound +and unity upper bound ($l_{jk}=0$, $u_{jk}=1$, in case of +\verb|GLP_ASN_MMP|). + +\para{Example} + +The example program shown below reads the assignment problem instance +in DIMACS format from file `\verb|sample.asn|', solves it by using the +routine \verb|glp_asnprob_okalg|, and writes the solution found to the +standard output. + +\begin{footnotesize} +\begin{verbatim} +#include +#include +#include +#include + +typedef struct { int set; } v_data; +typedef struct { double cost; int x; } e_data; + +#define node(v) ((v_data *)((v)->data)) +#define edge(e) ((e_data *)((e)->data)) + +int main(void) +{ glp_graph *G; + glp_vertex *v; + glp_arc *e; + int i, ret; + double sol; + G = glp_create_graph(sizeof(v_data), sizeof(e_data)); + glp_read_asnprob(G, offsetof(v_data, set), + offsetof(e_data, cost), "sample.asn"); + ret = glp_asnprob_okalg(GLP_ASN_MMP, G, + offsetof(v_data, set), offsetof(e_data, cost), &sol, + offsetof(e_data, x)); + printf("ret = %d; sol = %5g\n", ret, sol); + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (e = v->out; e != NULL; e = e->t_next) + printf("edge %2d %2d: x = %d; c = %g\n", + e->tail->i, e->head->i, edge(e)->x, edge(e)->cost); + } + glp_delete_graph(G); + return 0; +} +\end{verbatim} +\end{footnotesize} + +If `\verb|sample.asn|' is the example data file from the subsection +describing \verb|glp_read_asnprob|, the output may look like follows: + +\begin{footnotesize} +\begin{verbatim} +Reading assignment problem data from `sample.asn'... +Assignment problem has 8 + 9 = 17 nodes and 22 arcs +38 lines were read +ret = 0; sol = 180 +edge 1 12: x = 1; c = 20 +edge 1 10: x = 0; c = 21 +edge 1 9: x = 0; c = 13 +edge 2 13: x = 1; c = 26 +edge 2 12: x = 0; c = 8 +edge 2 10: x = 0; c = 12 +edge 3 13: x = 0; c = 11 +edge 3 11: x = 1; c = 22 +edge 4 14: x = 1; c = 25 +edge 4 12: x = 0; c = 36 +edge 4 9: x = 0; c = 12 +edge 5 17: x = 0; c = 32 +edge 5 16: x = 1; c = 35 +edge 5 15: x = 0; c = 8 +edge 5 14: x = 0; c = 4 +edge 5 13: x = 0; c = 11 +edge 5 12: x = 0; c = 40 +edge 5 11: x = 0; c = 41 +edge 6 9: x = 1; c = 13 +edge 7 10: x = 0; c = 19 +edge 8 11: x = 0; c = 15 +edge 8 10: x = 1; c = 39 +\end{verbatim} +\end{footnotesize} + +\subsection{glp\_asnprob\_hall --- find bipartite matching of maximum +cardinality} + +\synopsis + +\begin{verbatim} + int glp_asnprob_hall(glp_graph *G, int v_set, int a_x); +\end{verbatim} + +\description + +The routine \verb|glp_asnprob_hall| finds a matching of maximal +cardinality in the specified bipartite graph. It uses a version of the +Fortran routine \verb|MC21A| developed by +I.~S.~Duff\footnote{I.~S.~Duff, Algorithm 575: Permutations for +zero-free diagonal, ACM Trans. on Math. Softw. 7 (1981),\linebreak +pp.~387-390.}, which implements Hall's algorithm.\footnote{M.~Hall, +``An Algorithm for Distinct Representatives,'' Am. Math. Monthly 63 +(1956), pp.~716-717.} + +The parameter \verb|G| is a pointer to the graph program object. + +The parameter \verb|v_set| specifies an offset of the field of type +\verb|int| in the vertex data block, which contains the node set +indicator: + +0 --- the node is in set $R$; + +1 --- the node is in set $S$. + +\noindent +If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs +is in set $R$, and a node having no outgoing arcs is in set $S$. + +The parameter \verb|a_x| specifies an offset of the field of type +\verb|int| in the arc data block, to which the routine stores $x_{ij}$. +If \verb|a_x| $<0$, this value is not stored. + +\returns + +The routine \verb|glp_asnprob_hall| returns the cardinality of the +matching found. However, if the specified graph is incorrect (as +detected by the routine \verb|glp_check_asnprob|), this routine returns +a negative value. + +\newpage + +\para{Comments} + +The same solution may be obtained with the routine +\verb|glp_asnprob_okalg| (for LP formulation \verb|GLP_ASN_MMP| and +all edge costs equal to 1). However, the routine +\verb|glp_asnprob_hall| is much faster. + +\para{Example} + +The example program shown below reads the assignment problem instance +in DIMACS format from file `\verb|sample.asn|', finds a bipartite +matching of maximal cardinality by using the routine +\verb|glp_asnprob_hall|, and writes the solution found to the standard +output. + +\begin{footnotesize} +\begin{verbatim} +#include +#include +#include +#include + +typedef struct { int set; } v_data; +typedef struct { int x; } e_data; + +#define node(v) ((v_data *)((v)->data)) +#define edge(e) ((e_data *)((e)->data)) + +int main(void) +{ glp_graph *G; + glp_vertex *v; + glp_arc *e; + int i, card; + G = glp_create_graph(sizeof(v_data), sizeof(e_data)); + glp_read_asnprob(G, offsetof(v_data, set), -1, + "sample.asn"); + card = glp_asnprob_hall(G, offsetof(v_data, set), + offsetof(e_data, x)); + printf("card = %d\n", card); + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (e = v->out; e != NULL; e = e->t_next) + printf("edge %2d %2d: x = %d\n", + e->tail->i, e->head->i, edge(e)->x); + } + glp_delete_graph(G); + return 0; +} +\end{verbatim} +\end{footnotesize} + +If `\verb|sample.asn|' is the example data file from the subsection +describing \verb|glp_read_asnprob|, the output may look like follows: + +\begin{footnotesize} +\begin{verbatim} +Reading assignment problem data from `sample.asn'... +Assignment problem has 8 + 9 = 17 nodes and 22 arcs +38 lines were read +card = 7 +edge 1 12: x = 1 +edge 1 10: x = 0 +edge 1 9: x = 0 +edge 2 13: x = 1 +edge 2 12: x = 0 +edge 2 10: x = 0 +edge 3 13: x = 0 +edge 3 11: x = 1 +edge 4 14: x = 1 +edge 4 12: x = 0 +edge 4 9: x = 0 +edge 5 17: x = 1 +edge 5 16: x = 0 +edge 5 15: x = 0 +edge 5 14: x = 0 +edge 5 13: x = 0 +edge 5 12: x = 0 +edge 5 11: x = 0 +edge 6 9: x = 1 +edge 7 10: x = 1 +edge 8 11: x = 0 +edge 8 10: x = 0 +\end{verbatim} +\end{footnotesize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Critical path problem} + +\subsection{Background} + +The {\it critical path problem} (CPP) is stated as follows. Let there +be given a project $J$, which is a set of jobs (tasks, activities, +etc.). Performing each job $i\in J$ requires time $t_i\geq 0$. Besides, +over the set $J$ there is given a precedence relation +$R\subseteq J\times J$, where $(i,j)\in R$ means that job $i$ +immediately precedes job $j$, i.e. performing job $j$ cannot start +until job $i$ has been completely performed. The problem is to find +starting times $x_i$ for each job $i\in J$, which satisfy to the +precedence relation and minimize the total duration (makespan) of the +project. + +The following is an example of the critical path problem: + +\bigskip + +\begin{center} +\begin{tabular}{|c|l|c|c|} +\hline +Job&Desription&Time&Predecessors\\ +\hline +A&Excavate&3&---\\ +B&Lay foundation&4&A\\ +C&Rough plumbing&3&B\\ +D&Frame&10&B\\ +E&Finish exterior&8&D\\ +F&Install HVAC&4&D\\ +G&Rough electric&6&D\\ +H&Sheet rock&8&C, E, F, G\\ +I&Install cabinets&5&H\\ +J&Paint&5&H\\ +K&Final plumbing&4&I\\ +L&Final electric&2&J\\ +M&Install flooring&4&K, L\\ +\hline +\end{tabular} +\end{center} + +\bigskip + +Obviously, the project along with the precedence relation can be +represented as a directed graph $G=(J,R)$ called {\it project network}, +where each node $i\in J$ corresponds to a job, and arc +$(i\rightarrow j)\in R$ means that job $i$ immediately precedes job +$j$.\footnote{There exists another network representation of the +critical path problem, where jobs correspond to arcs while nodes +correspond to events introduced to express the precedence relation. +That representation, however, is much less convenient than the one, +where jobs are represented as nodes of the network.} The project network +for the example above is shown on Fig.~4. + +May note that the project network must be acyclic; otherwise, it would +be impossible to satisfy to the precedence relation for any job that +belongs to a cycle. + +\newpage + +\hspace*{.5in} +\xymatrix +{&&&C|3\ar[rd]&&I|5\ar[r]&K|4\ar[rd]&\\ +A|3\ar[r]&B|4\ar[rru]\ar[rd]&&E|8\ar[r]&H|8\ar[ru]\ar[rd]&&&M|4\\ +&&D|10\ar[ru]\ar[r]\ar[rd]&F|4\ar[ru]&&J|5\ar[r]&L|2\ar[ru]&\\ +&&&G|6\ar[ruu]&&&&\\ +} + +\medskip + +\noindent\hfil +Fig.~4. An example of the project network. + +\medskip + +The critical path problem can be naturally formulated as the following +LP problem: + +\medskip + +\noindent +\hspace{.5in}minimize +$$z\eqno(19)$$ +\hspace{.5in}subject to +$$x_i+t_i\leq z\ \ \ \hbox{for all}\ i\in J\ \ \ \ \eqno(20)$$ +$$x_i+t_i\leq x_j\ \ \ \hbox{for all}\ (i,j)\in R\eqno(21)$$ +$$x_i\geq 0\ \ \ \ \ \ \ \hbox{for all}\ i\in J\ \ \eqno(22)$$ + +The inequality constraints (21), which are active in the optimal +solution, define so called {\it critical path} having the following +property: the minimal project duration $z$ can be decreased only by +decreasing the times $t_j$ for jobs on the critical path, and delaying +any critical job delays the entire project. + +\subsection{glp\_cpp --- solve critical path problem} + +\synopsis + +\begin{verbatim} + double glp_cpp(glp_graph *G, int v_t, int v_es, int v_ls); +\end{verbatim} + +\description + +The routine \verb|glp_cpp| solves the critical path problem represented +in the form of the project network. + +The parameter \verb|G| is a pointer to the graph object, which +specifies the project network. This graph must be acyclic. Multiple +arcs are allowed being considered as single arcs. + +The parameter \verb|v_t| specifies an offset of the field of type +\verb|double| in the vertex data block, which contains time $t_i\geq 0$ +needed to perform corresponding job $j\in J$. If \verb|v_t| $<0$, it is +assumed that $t_i=1$ for all jobs. + +The parameter \verb|v_es| specifies an offset of the field of type +\verb|double| in the vertex data block, to which the routine stores +the {\it earliest start time} for corresponding job. If \verb|v_es| +$<0$, this time is not stored. + +\newpage + +The parameter \verb|v_ls| specifies an offset of the field of type +\verb|double| in the vertex data block, to which the routine stores +the {\it latest start time} for corresponding job. If \verb|v_ls| +$<0$, this time is not stored. + +The difference between the latest and earliest start times of some job +is called its {\it time reserve}. Delaying a job within its time +reserve does not affect the project duration, so if the time reserve is +zero, the corresponding job is critical. + +\para{Returns} + +The routine \verb|glp_cpp| returns the minimal project duration, i.e. +minimal time needed to perform all jobs in the project. + +\para{Example} + +The example program below solves the critical path problem shown on +Fig.~4 by using the routine \verb|glp_cpp| and writes the solution +found on the standard output. + +\begin{footnotesize} +\begin{verbatim} +#include +#include +#include +#include + +typedef struct { double t, es, ls; } v_data; + +#define node(v) ((v_data *)((v)->data)) + +int main(void) +{ glp_graph *G; + int i; + double t, es, ef, ls, lf, total; + G = glp_create_graph(sizeof(v_data), 0); + glp_add_vertices(G, 13); + node(G->v[1])->t = 3; /* A: Excavate */ + node(G->v[2])->t = 4; /* B: Lay foundation */ + node(G->v[3])->t = 3; /* C: Rough plumbing */ + node(G->v[4])->t = 10; /* D: Frame */ + node(G->v[5])->t = 8; /* E: Finish exterior */ + node(G->v[6])->t = 4; /* F: Install HVAC */ + node(G->v[7])->t = 6; /* G: Rough elecrtic */ + node(G->v[8])->t = 8; /* H: Sheet rock */ + node(G->v[9])->t = 5; /* I: Install cabinets */ + node(G->v[10])->t = 5; /* J: Paint */ + node(G->v[11])->t = 4; /* K: Final plumbing */ + node(G->v[12])->t = 2; /* L: Final electric */ + node(G->v[13])->t = 4; /* M: Install flooring */ + glp_add_arc(G, 1, 2); /* A precedes B */ + glp_add_arc(G, 2, 3); /* B precedes C */ + glp_add_arc(G, 2, 4); /* B precedes D */ + glp_add_arc(G, 4, 5); /* D precedes E */ + glp_add_arc(G, 4, 6); /* D precedes F */ + glp_add_arc(G, 4, 7); /* D precedes G */ + glp_add_arc(G, 3, 8); /* C precedes H */ + glp_add_arc(G, 5, 8); /* E precedes H */ + glp_add_arc(G, 6, 8); /* F precedes H */ + glp_add_arc(G, 7, 8); /* G precedes H */ + glp_add_arc(G, 8, 9); /* H precedes I */ + glp_add_arc(G, 8, 10); /* H precedes J */ + glp_add_arc(G, 9, 11); /* I precedes K */ + glp_add_arc(G, 10, 12); /* J precedes L */ + glp_add_arc(G, 11, 13); /* K precedes M */ + glp_add_arc(G, 12, 13); /* L precedes M */ + total = glp_cpp(G, offsetof(v_data, t), offsetof(v_data, es), + offsetof(v_data, ls)); + printf("Minimal project duration is %.2f\n\n", total); + printf("Job Time ES EF LS LF\n"); + printf("--- ------ ------ ------ ------ ------\n"); + for (i = 1; i <= G->nv; i++) + { t = node(G->v[i])->t; + es = node(G->v[i])->es; + ef = es + node(G->v[i])->t; + ls = node(G->v[i])->ls; + lf = ls + node(G->v[i])->t; + printf("%3d %6.2f %s %6.2f %6.2f %6.2f %6.2f\n", + i, t, ls - es < 0.001 ? "*" : " ", es, ef, ls, lf); + } + glp_delete_graph(G); + return 0; +} +\end{verbatim} +\end{footnotesize} + +The output from the example program shown below includes job number, +the time needed to perform a job, earliest start time (\verb|ES|), +earliest finish time (\verb|EF|), latest start time (\verb|LS|), and +latest finish time (\verb|LF|) for each job in the project. Critical +jobs are marked by asterisks. + +\begin{footnotesize} +\begin{verbatim} +Minimal project duration is 46.00 + +Job Time ES EF LS LF +--- ------ ------ ------ ------ ------ + 1 3.00 * 0.00 3.00 0.00 3.00 + 2 4.00 * 3.00 7.00 3.00 7.00 + 3 3.00 7.00 10.00 22.00 25.00 + 4 10.00 * 7.00 17.00 7.00 17.00 + 5 8.00 * 17.00 25.00 17.00 25.00 + 6 4.00 17.00 21.00 21.00 25.00 + 7 6.00 17.00 23.00 19.00 25.00 + 8 8.00 * 25.00 33.00 25.00 33.00 + 9 5.00 * 33.00 38.00 33.00 38.00 + 10 5.00 33.00 38.00 35.00 40.00 + 11 4.00 * 38.00 42.00 38.00 42.00 + 12 2.00 38.00 40.00 40.00 42.00 + 13 4.00 * 42.00 46.00 42.00 46.00 +\end{verbatim} +\end{footnotesize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Graph Optimization API Routines} + +\section{Maximum clique problem} + +\subsection{Background} + +The {\it maximum clique problem (MCP)} is a classic combinatorial +optimization problem. Given an undirected graph $G=(V,E)$, where $V$ is +a set of vertices, and $E$ is a set of edges, this problem is to find +the largest {\it clique} $C\subseteq G$, i.e. the largest induced +complete subgraph. A generalization of this problem is the {\it maximum +weight clique problem (MWCP)}, which is to find a clique $C\subseteq G$ +of the largest weight $\displaystyle\sum_{v\in C}w(v)\rightarrow\max$, +where $w(v)$ is a weight of vertex $v\in V$. + +An example of the maximum weight clique problem is shown on Fig.~5. + +\begin{figure} +\noindent\hfil +\begin{tabular}{c} +{\xymatrix %@C=16pt +{&&&{v_1}\ar@{-}[lllddd]\ar@{-}[llddddd]\ar@{-}[dddddd] +\ar@{-}[rrrddd]&&&\\ +&{v_2}\ar@{-}[rrrr]\ar@{-}[rrrrdddd]\ar@{-}[rrddddd]\ar@{-}[dddd]&&&& +{v_3}\ar@{-}[llllldd]\ar@{-}[lllldddd]\ar@{-}[dddd]&\\ +&&&&&&\\ +{v_4}\ar@{-}[rrrrrr]\ar@{-}[rrrddd]&&&&&&{v_5}\ar@{-}[lllddd] +\ar@{-}[ldd]\\ +&&&&&&\\ +&{v_6}\ar@{-}[rrrr]&&&&{v_7}&\\ +&&&{v_8}&&&\\ +}} +\end{tabular} +\begin{tabular}{r@{\ }c@{\ }l} +$w(v_1)$&=&3\\$w(v_2)$&=&4\\$w(v_3)$&=&8\\$w(v_4)$&=&1\\ +$w(v_5)$&=&5\\$w(v_6)$&=&2\\$w(v_7)$&=&1\\$w(v_8)$&=&3\\ +\end{tabular} + +\bigskip + +\begin{center} +Fig.~5. An example of the maximum weight clique problem. +\end{center} +\end{figure} + +\subsection{glp\_wclique\_exact --- find maximum weight clique with +exact algorithm} + +\synopsis + +\begin{verbatim} + int glp_wclique_exact(glp_graph *G, int v_wgt, double *sol, int v_set); +\end{verbatim} + +\description + +The routine {\tt glp\_wclique\_exact} finds a maximum weight clique in +the specified undirected graph with the exact algorithm developed by +Patric \"Osterg{\aa}rd.\footnote{P.~R.~J.~\"Osterg{\aa}rd, A new +algorithm for the maximum-weight clique problem, Nordic J. of +Computing, Vol.~8, No.~4, 2001, pp.~424--36.} + +The parameter {\tt G} is the program object, which specifies +an undirected graph. Each arc $(x\rightarrow y)$ in {\tt G} is +considered as edge $(x,y)$, self-loops are ignored, and multiple edges, +if present, are replaced (internally) by simple edges. + +The parameter {\tt v\_wgt} specifies an offset of the field of type +{\tt double} in the vertex data block, which contains a weight of +corresponding vertex. Vertex weights must be integer-valued in the +range $[0,$ {\tt INT\_MAX}$]$. If {\tt v\_wgt} $<0$, it is assumed that +all vertices of the graph have the weight 1. + +\newpage + +The parameter {\tt sol} specifies a location, to which the routine +stores the weight of the clique found (the clique weight is the sum +of weights of all vertices included in the clique.) If {\tt sol} is +{\tt NULL}, the solution is not stored. + +The parameter {\tt v\_set} specifies an offset of the field of type +{\tt int} in the vertex data block, to which the routines stores a +vertex flag: 1 means that the corresponding vertex is included in the +clique found, and 0 otherwise. If {\tt v\_set} $<0$, vertex flags are +not stored. + +\returns + +\begin{retlist} +0 & Optimal solution found.\\ + +\verb|GLP_EDATA| & Unable to start the search, because some vertex +weights are either not integer-valued or out of range. This code is +also returned if the sum of weights of all vertices exceeds +{\tt INT\_MAX}. \\ +\end{retlist} + +\para{Notes} + +1. The routine {\it glp\_wclique\_exact} finds exact solution. Since +both MCP and MWCP problems are NP-complete, the algorithm may require +exponential time in worst cases. + +2. Internally the specified graph is converted to an adjacency matrix +in {\it dense} format. This requires about $|V|^2/16$ bytes of memory, +where $|V|$ is the number of vertices in the graph. + +\para{Example} + +The example program shown below reads a MWCP instance in DIMACS +clique/coloring format from file `\verb|sample.clq|', finds the clique +of largest weight, and writes the solution found on the standard +output. + +\newpage + +\begin{footnotesize} +\begin{verbatim} +#include +#include +#include +#include + +typedef struct { double wgt; int set; } v_data; + +#define vertex(v) ((v_data *)((v)->data)) + +int main(void) +{ glp_graph *G; + glp_vertex *v; + int i, ret; + double sol; + G = glp_create_graph(sizeof(v_data), 0); + glp_read_ccdata(G, offsetof(v_data, wgt), "sample.clq"); + ret = glp_wclique_exact(G, offsetof(v_data, wgt), &sol, + offsetof(v_data, set)); + printf("ret = %d; sol = %g\n", ret, sol); + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + printf("vertex %d: weight = %g, flag = %d\n", + i, vertex(v)->wgt, vertex(v)->set); + } + glp_delete_graph(G); + return 0; +} +\end{verbatim} +\end{footnotesize} + +For the example shown on Fig.~5 the data file may look like follows: + +\begin{footnotesize} +\begin{verbatim} +c sample.clq +c +c This is an example of the maximum weight clique +c problem in DIMACS clique/coloring format. +c +p edge 8 16 +n 1 3 +n 2 4 +n 3 8 +n 5 5 +n 6 2 +n 8 3 +e 1 4 +e 1 5 +e 1 6 +e 1 8 +e 2 3 +e 2 6 +e 2 7 +e 2 8 +e 3 4 +e 3 6 +e 3 7 +e 4 5 +e 4 8 +e 5 7 +e 5 8 +e 6 7 +c +c eof +\end{verbatim} +\end{footnotesize} + +The corresponding output from the example program is the following: + +\begin{footnotesize} +\begin{verbatim} +Reading graph from `sample.clq'... +Graph has 8 vertices and 16 edges +28 lines were read +ret = 0; sol = 15 +vertex 1: weight = 3, flag = 0 +vertex 2: weight = 4, flag = 1 +vertex 3: weight = 8, flag = 1 +vertex 4: weight = 1, flag = 0 +vertex 5: weight = 5, flag = 0 +vertex 6: weight = 2, flag = 1 +vertex 7: weight = 1, flag = 1 +vertex 8: weight = 3, flag = 0 +\end{verbatim} +\end{footnotesize} + +\end{document} diff --git a/resources/3rdparty/glpk-4.57/doc/miplib2.txt b/resources/3rdparty/glpk-4.57/doc/miplib2.txt new file mode 100644 index 000000000..762c83f89 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/miplib2.txt @@ -0,0 +1,135 @@ +Solver: GLPSOL 4.40 (options used: --pcost) +Computer: Intel Pentium 4, 3.0 GHz +Platform: Cygwin 1.5.25 +Compiler: GCC 3.4.4 (options used: -O3) +Test set: MIPLIB 2.0 + +Problem Optimal Solution Cuts Used Nodes Iters Time,s Mem,MB +-------- ---------------- --------- -------- ------ ------ ------ +air01 +6.796000000e+03 3 41 < 1 1.2 +air02 +7.810000000e+03 43 201 6 13.8 +air03 +3.401600000e+05 33 414 12 21.0 +air04 +5.613700000e+04 1901 109800 396 32.4 +air05 +2.637400000e+04 6445 201649 452 45.0 +air06 +4.964900000e+04 11 6868 31 18.1 +bell3a +8.784303160e+05 --gomory 7965 42363 17 6.1 +bell3b +1.178616062e+07 --gomory 6031 30467 19 3.2 +bell4 +1.854148420e+07 --gomory 7203 25019 16 2.9 +bell5 +8.966406492e+06 --gomory 5605 18555 8 1.5 +bm23 +3.400000000e+01 373 878 < 1 0.2 +cracpb1 +2.219900000e+04 47 5258 2 1.3 +dcmulti +1.881820000e+05 743 3366 2 1.1 +diamond infeasible 3 4 < 1 0.1 +dsbmip -3.051981750e+02 --mir 217 46088 24 4.5 +egout +5.681007000e+02 91 137 < 1 0.3 +enigma +0.000000000e+00 16419 55071 6 3.2 +fixnet3 +5.197300000e+04 81 380 < 1 1.4 +fixnet4 +8.936000000e+03 211 1095 1 1.4 +fixnet6 +3.983000000e+03 1031 3136 2 1.7 +flugpl +1.201500000e+06 397 231 < 1 0.1 +gen +1.123133627e+05 195 3991 1 1.7 +khb05250 +1.069402260e+08 2163 14498 5 2.8 +l152lav +4.722000000e+03 7419 95299 68 12.0 +lp4l +2.967000000e+03 173 1331 2 1.7 +lseu +1.120000000e+03 10821 31954 5 2.5 +misc01 +5.635000000e+02 769 4593 1 0.5 +misc02 +1.690000000e+03 29 282 < 1 0.2 +misc03 +3.360000000e+03 957 6742 2 1.1 +misc04 +2.666699247e+03 17 2052 1 7.0 +misc05 +2.984500000e+03 293 2520 1 1.1 +misc06 +1.285086074e+04 57 941 < 1 2.7 +misc07 +2.810000000e+03 --mir 66075 579129 424 33.4 +mod008 +3.070000000e+02 8185 24245 8 2.3 +mod010 +6.548000000e+03 315 6283 7 5.3 +mod011 +mod013 +2.809500000e+02 545 1155 < 1 0.3 +modglob +2.074050809e+07 --mir 5197 31985 20 2.8 +noswot +p0033 +3.089000000e+03 305 955 < 1 0.2 +p0040 +6.202700000e+04 17 66 < 1 0.1 +p0201 +7.615000000e+03 521 3660 1 0.9 +p0282 +2.584110000e+05 623 1204 1 0.8 +p0291 +5.223749000e+03 71 154 < 1 0.7 +p0548 +8.691000000e+03 7617 23556 9 2.9 +p2756 +3.124000000e+03 --mir 3911 15157 57 10.9 +p6000 -2.451377000e+06 19209 40906 570 15.8 +pipex +7.882630000e+02 1569 2469 < 1 0.4 +qiu -1.328731369e+02 80473 1918742 1174 69.2 +rentacar +3.035676098e+07 43 1649 3 12.1 +rgn +8.219999924e+01 3325 18700 2 1.2 +sample2 +3.750000000e+02 163 347 < 1 0.2 +sentoy -7.772000000e+03 335 723 < 1 0.4 +set1al +1.586975000e+04 --mir 17 532 < 1 1.5 +set1ch +set1cl +6.484250000e+03 --mir 1 502 < 1 1.1 +stein15 +9.000000000e+00 87 375 < 1 0.2 +stein27 +1.800000000e+01 3255 15327 2 1.0 +stein45 +3.000000000e+01 52301 389140 139 19.2 +stein9 +5.000000000e+00 17 45 < 1 0.1 +vpm1 +2.000000000e+01 --mir 9 836 < 1 0.9 + +PROBLEM CHARACTERISTICS + +Problem Rows Cols ( Int 0/1) Nonz Best Solution +-------- ------ ---------------------- ------ -------------------------- +air01 24 771 ( all all) 4986 6796 (opt) +air02 51 6774 ( all all) 68329 7810 (opt) +air03 125 10757 ( all all) 101785 340160 (opt) +air04 824 8904 ( all all) 81869 56138 (opt) +air05 427 7195 ( all all) 59316 26402 (not opt) +air06 826 8627 ( all all) 79433 49649 (opt) +bell3a 124 133 ( 71 39) 441 878430.32 (opt) +bell3b 124 133 ( 71 39) 441 11786160.62 (opt) +bell4 106 117 ( 64 34) 385 18541484.20 (opt) +bell5 92 104 ( 58 30) 340 8966406.49 (opt) +bm23 21 27 ( all all) 505 34 (opt) +cracpb1 144 572 ( all all) 4730 22199 (opt) +dcmulti 291 548 ( 75 all) 1833 188182.0000 (opt) +diamond 5 2 ( all all) 9 integer infeasible +dsbmip 1855 1886 ( 192 160) 9768 -305.198 (opt) +egout 99 141 ( 55 all) 392 568.101 (opt) +enigma 22 100 ( all all) 298 0.0 (opt) +fixnet3 479 878 ( 378 all) 2631 51973 (opt) +fixnet4 479 878 ( 378 all) 2621 8936 (opt) +fixnet6 479 878 ( 378 all) 2550 3983 (opt) +flugpl 19 18 ( 11 none) 64 1201500 (opt) +gen 781 870 ( 150 144) 3174 112313 (opt) +khb05250 102 1350 ( 24 all) 3973 106940226 (opt) +l152lav 98 1989 ( all all) 11911 4750 (not opt) +lp4l 86 1086 ( all all) 5763 2967 (opt) +lseu 29 89 ( all all) 394 1120 (opt) +misc01 55 83 ( 82 all) 746 563.5 (opt) +misc02 40 59 ( 58 all) 414 1690 (opt) +misc03 97 160 ( 159 all) 2054 3360 (opt) +misc04 1726 4897 ( 30 all) 17253 2666.699 (opt) +misc05 301 136 ( 74 all) 2946 2984.5 (opt) +misc06 821 1808 ( 112 all) 5860 12850.8607 (opt) +misc07 213 260 ( 259 all) 8620 2810 (not opt) +mod008 7 319 ( all all) 1562 307 (opt) +mod010 147 2655 ( all all) 13858 6548 (opt) +mod011 4482 10958 ( 96 all) 37425 -54558535 (opt) +mod013 63 96 ( 48 all) 288 280.95 (opt) +modglob 292 422 ( 98 all) 1390 20740508 (opt) +noswot 183 128 ( 100 75) 760 -43 (opt) +p0033 17 33 ( all all) 131 3089 (opt) +p0040 24 40 ( all all) 150 62027 (opt) +p0201 134 201 ( all all) 2124 7615 (opt) +p0282 242 282 ( all all) 2248 258411 (opt) +p0291 253 291 ( all all) 349 5223.7490 (opt) +p0548 177 548 ( all all) 2127 8691 (opt) +p2756 756 2756 ( all all) 11103 3124 (opt) +p6000 2177 6000 ( all all) 54238 -2451377 (opt) +pipex 26 48 ( all all) 240 788.263 (opt) +qiu 1193 840 ( 48 all) 3432 -132.873137 (opt) +rentacar 6804 9557 ( 55 all) 42019 30356761 (opt) +rgn 25 180 ( 100 all) 540 82.1999 (opt) +sample2 46 67 ( 21 all) 179 375 (opt) +sentoy 31 60 ( all all) 1860 -7772 (opt) +set1al 493 712 ( 240 all) 1884 15869.7 (opt) +set1ch 493 712 ( 240 all) 1884 54537.7 (opt) +set1cl 493 712 ( 240 all) 1884 6484.25 (opt) +stein15 37 15 ( all all) 135 9 (opt) +stein27 119 27 ( all all) 405 18 (opt) +stein45 332 45 ( all all) 1079 30 (opt) +stein9 14 9 ( all all) 54 5 (opt) +vpm1 235 378 ( 168 all) 917 20 (opt) diff --git a/resources/3rdparty/glpk-4.57/doc/miplib3.txt b/resources/3rdparty/glpk-4.57/doc/miplib3.txt new file mode 100644 index 000000000..ad7884bb2 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/miplib3.txt @@ -0,0 +1,143 @@ +Solver: GLPSOL 4.40 +Computer: Intel Pentium 4, 3.0 GHz +Platform: Cygwin 1.5.25 +Compiler: GCC 3.4.4 (options used: -O3) +Test set: MIPLIB 3.0 + +Problem Optimal Solution Options Used Nodes Iters Time,s Mem,MB +-------- ---------------- ---------------- -------- ------ ------ ------ +10teams +9.240000000e+02 --pcost --gomory 6013 349276 207 12.7 +air03 +3.401600000e+05 --pcost 33 414 12 21.0 +air04 +5.613700000e+04 --pcost 1901 109800 396 32.4 +air05 +2.637400000e+04 --pcost 6445 201649 452 45.0 +arki001 +bell3a +8.784303160e+05 --pcost --gomory 7965 42363 17 6.1 +bell5 +8.966406492e+06 --pcost --gomory 5605 18555 8 1.5 +blend2 +7.598985000e+00 --pcost 7185 24256 7 2.1 +cap6000 -2.451377000e+06 --pcost 19209 40906 569 15.8 +dano3mip +danoint +dcmulti +1.881820000e+05 --pcost 743 3366 2 1.1 +dsbmip -3.051981750e+02 --pcost --mir 217 46088 24 4.5 +egout +5.681007000e+02 --pcost 91 137 < 1 0.3 +enigma +0.000000000e+00 --pcost 16419 55071 6 3.2 +fast0507 +fiber +4.059351800e+05 --pcost --mir 407 3108 4 2.4 +fixnet6 +3.983000000e+03 --pcost 1031 3136 2 1.7 +flugpl +1.201500000e+06 --pcost 397 231 < 1 0.1 +gen +1.123133627e+05 --pcost 195 3991 1 1.7 +gesa2 +2.577985637e+07 --pcost --mir 59 2723 4 4.1 +gesa2_o +2.577985637e+07 --pcost --mir 69 2588 5 3.7 +gesa3 +2.799104265e+07 --pcost --mir 93 2774 5 3.7 +gesa3_o +2.799104265e+07 --pcost --mir 117 3271 6 3.6 +gt2 +2.116600000e+04 --pcost 5613 26115 2 1.2 +harp2 +khb05250 +1.069402260e+08 --pcost 2163 14498 5 2.8 +l152lav +4.722000000e+03 --pcost 7419 95299 68 12.0 +lseu +1.120000000e+03 --pcost 10821 31954 5 2.5 +marksh1 +marksh2 +mas74 +mas76 +misc03 +3.360000000e+03 --pcost 957 6742 2 1.1 +misc06 +1.285086074e+04 --pcost 57 941 < 1 2.7 +misc07 +2.810000000e+03 --pcost --mir 66075 579129 424 33.4 +mitre +mkc +mod008 +3.070000000e+02 --pcost 8185 24245 8 2.3 +mod010 +6.548000000e+03 --pcost 315 6283 7 5.3 +mod011 +modglob +2.074050809e+07 --pcost --mir 5197 31985 20 2.8 +noswot +nw04 +1.686200000e+04 (none) 361 5544 345 138.3 +p0033 +3.089000000e+03 --pcost 305 955 < 1 0.2 +p0201 +7.615000000e+03 --pcost 521 3660 1 0.9 +p0282 +2.584110000e+05 --pcost 623 1204 1 0.8 +p0548 +8.691000000e+03 --pcost 7617 23556 9 2.9 +p2756 +3.124000000e+03 --pcost --mir 3911 15157 57 10.9 +pk1 +pp08a +7.350000000e+03 --pcost --mir 663 9196 4 1.3 +pp08acut +7.350000000e+03 --pcost --mir 17233 260160 154 21.1 +qiu -1.328731369e+02 --pcost 80473 1918742 1174 69.2 +qnet1 +1.602969268e+04 --pcost --mir 183 20352 16 3.6 +qnet1_o +1.602969268e+04 --pcost --mir 75 7645 9 3.3 +rentacar +3.035676098e+07 --pcost 43 1649 3 12.1 +rgn +8.219999924e+01 --pcost 3325 18700 2 1.2 +rout +set1ch +seymour +stein27 +1.800000000e+01 --pcost 3255 15327 2 1.0 +stein45 +3.000000000e+01 --pcost 52301 389140 139 19.2 +swath +vpm1 +2.000000000e+01 --pcost --mir 9 836 < 1 0.9 +vpm2 +1.375000000e+01 --pcost --mir 11729 164856 91 9.2 + +PROBLEM CHARACTERISTICS + +Problem Rows Cols ( Int 0/1) Nonz Best Solution +-------- ------ ---------------------- ------ -------------------------- +10teams 230 2025 ( 1800 all) 12150 924 (opt) +air03 125 10757 ( all all) 101785 340160 (opt) +air04 824 8904 ( all all) 81869 56138 (opt) +air05 427 7195 ( all all) 59316 26402 (not opt) +arki001 1048 1388 ( 538 415) 20439 7580813.0459 (not opt) +bell3a 124 133 ( 71 39) 441 878430.32 (opt) +bell5 92 104 ( 58 30) 340 8966406.49 (opt) +blend2 274 353 ( 264 231) 1409 7.598985 (opt) +cap6000 2176 6000 ( all all) 48249 -2451377 (opt) +dano3mip 3202 13873 ( 552 all) 79655 728.1111 (not opt) +danoint 664 521 ( 56 all) 3232 65.67 (opt) +dcmulti 291 548 ( 75 all) 1833 188182.0000 (opt) +dsbmip 1855 1886 ( 192 160) 9768 -305.198 (opt) +egout 99 141 ( 55 all) 392 568.101 (opt) +enigma 22 100 ( all all) 298 0.0 (opt) +fast0507 507 63009 ( all all) 409439 174 (opt) +fiber 363 1298 ( 1254 all) 2944 405935.18000 (opt) +fixnet6 479 878 ( 378 all) 2550 3983 (opt) +flugpl 19 18 ( 11 none) 64 1201500 (opt) +gen 781 870 ( 150 144) 3174 112313 (opt) +gesa2 1392 1224 ( 408 240) 5064 25779856.372 (opt) +gesa2_o 1248 1224 ( 720 384) 3672 25779856.372 (opt) +gesa3 1368 1152 ( 384 216) 4944 27991042.648 (opt) +gesa3_o 1224 1152 ( 672 336) 3624 27991042.648 (opt) +gt2 29 188 ( all 24) 376 21166.000 (opt) +harp2 112 2993 ( all all) 5840 -73899798.00 (opt) +khb05250 102 1350 ( 24 all) 3973 106940226 (opt) +l152lav 98 1989 ( all all) 11911 4750 (not opt) +lseu 29 89 ( all all) 394 1120 (opt) +marksh1 7 62 ( 50 all) 324 +marksh2 8 74 ( 60 all) 448 +mas74 13 151 ( 150 all) 1705 11801.1857 (opt) +mas76 12 151 ( 150 all) 1639 40005.0541 (opt) +misc03 97 160 ( 159 all) 2054 3360 (opt) +misc06 821 1808 ( 112 all) 5860 12850.8607 (opt) +misc07 213 260 ( 259 all) 8620 2810 (not opt) +mitre 2054 10724 ( all all) 39704 115155 (opt) +mkc 3412 5325 ( 5323 all) 20621 +mod008 7 319 ( all all) 1562 307 (opt) +mod010 147 2655 ( all all) 13858 6548 (opt) +mod011 4482 10958 ( 96 all) 37425 -54558535 (opt) +modglob 292 422 ( 98 all) 1390 20740508 (opt) +noswot 183 128 ( 100 75) 760 -43 (opt) +nw04 36 87482 ( all all) 636666 16862 (opt) +p0033 17 33 ( all all) 131 3089 (opt) +p0201 134 201 ( all all) 2124 7615 (opt) +p0282 242 282 ( all all) 2248 258411 (opt) +p0548 177 548 ( all all) 2127 8691 (opt) +p2756 756 2756 ( all all) 11103 3124 (opt) +pk1 45 86 ( 55 all) 915 11 (opt) +pp08a 136 240 ( 64 all) 480 7350 (opt) +pp08acut 246 240 ( 64 all) 839 7350 (opt) +qiu 1193 840 ( 48 all) 3432 -132.873137 (opt) +qnet1 503 1541 ( 1417 1288) 4622 16029.692681 (opt) +qnet1_o 456 1541 ( 1417 1288) 4214 16029.692681 (opt) +rentacar 6804 9557 ( 55 all) 42019 30356761 (opt) +rgn 25 180 ( 100 all) 540 82.1999 (opt) +rout 291 556 ( 315 300) 2431 1077.56 (opt) +set1ch 493 712 ( 240 all) 1884 54537.7 (opt) +seymour 4944 1372 ( all all) 33549 423 (not opt) +stein27 119 27 ( all all) 405 18 (opt) +stein45 332 45 ( all all) 1079 30 (opt) +swath 885 6805 ( 6724 all) 34966 +vpm1 235 378 ( 168 all) 917 20 (opt) +vpm2 234 378 ( 168 all) 917 13.75 (opt) diff --git a/resources/3rdparty/glpk-4.57/doc/netlib.txt b/resources/3rdparty/glpk-4.57/doc/netlib.txt new file mode 100644 index 000000000..a5c01ca80 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/netlib.txt @@ -0,0 +1,103 @@ +Solver: GLPSOL 4.40 (default options used) +Computer: Intel Pentium 4, 3.0 GHz +Platform: Cygwin 1.5.25 +Compiler: GCC 3.4.4 (options used: -O3) +Test set: Netlib LP collection + +Problem Rows Cols Nonz Optimum Iters Time,s Mem,MB +-------- ----- ----- ------ ---------------- ------ ------ ------ +25fv47 822 1571 11127 +5.501845888e+03 1651 < 1 2.1 +80bau3b 2263 9799 29063 +9.872241924e+05 5358 3 6.4 +adlittle 57 97 465 +2.254949632e+05 71 < 1 0.1 +afiro 28 32 88 -4.647531429e+02 10 < 1 0.1 +agg 489 163 2541 -3.599176729e+07 100 < 1 0.5 +agg2 517 302 4515 -2.023925236e+07 178 < 1 0.8 +agg3 517 302 4531 +1.031211594e+07 182 < 1 0.8 +bandm 306 472 2659 -1.586280185e+02 252 < 1 0.6 +beaconfd 174 262 3476 +3.359248581e+04 61 < 1 0.4 +blend 75 83 521 -3.081214985e+01 41 < 1 0.1 +bnl1 644 1175 6129 +1.977629562e+03 581 < 1 1.4 +bnl2 2325 3489 16124 +1.811236540e+03 1730 1 3.7 +boeing1 351 384 3865 -3.352135675e+02 419 < 1 0.7 +boeing2 167 143 1339 -3.150187280e+02 161 < 1 0.3 +bore3d 234 315 1525 +1.373080394e+03 38 < 1 0.3 +brandy 221 249 2150 +1.518509896e+03 191 < 1 0.5 +capri 272 353 1786 +2.690012914e+03 203 < 1 0.4 +cycle 1904 2857 21322 -5.226393025e+00 953 < 1 3.5 +czprob 930 3523 14173 +2.185196699e+06 754 < 1 2.6 +d2q06c 2172 5167 35674 +1.227842108e+05 5368 7 6.2 +d6cube 416 6184 43888 +3.154916667e+02 6596 6 6.0 +degen2 445 534 4449 -1.435178000e+03 506 < 1 1.0 +degen3 1504 1818 26230 -9.872940000e+02 2205 2 4.1 +dfl001 6072 12230 41873 +1.126639605e+07 39863 117 11.0 +e226 224 282 2767 -2.586492907e+01 206 < 1 0.5 +etamacro 401 688 2489 -7.557152333e+02 444 < 1 0.7 +fffff800 525 854 6235 +5.556795648e+05 167 < 1 1.0 +finnis 498 614 2714 +1.727910656e+05 338 < 1 0.6 +fit1d 25 1026 14430 -9.146378092e+03 488 < 1 1.7 +fit1p 628 1677 10894 +9.146378092e+03 1379 < 1 1.9 +fit2d 26 10500 138018 -6.846429329e+04 5751 16 15.8 +fit2p 3001 13525 60784 +6.846429329e+04 11960 17 11.3 +forplan 162 421 4916 -6.642189613e+02 170 < 1 0.7 +ganges 1310 1681 7021 -1.095857361e+05 724 < 1 1.9 +gfrd-pnc 617 1092 3467 +6.902236000e+06 416 < 1 1.0 +greenbea 2393 5405 31499 -7.255524813e+07 3012 3 5.8 +greenbeb 2393 5405 31499 -4.302260261e+06 2153 2 5.8 +grow15 301 645 5665 -1.068709413e+08 358 < 1 1.1 +grow22 441 946 8318 -1.608343365e+08 606 < 1 1.6 +grow7 141 301 2633 -4.778781181e+07 159 < 1 0.5 +israel 175 142 2358 -8.966448219e+05 123 < 1 0.4 +kb2 44 41 291 -1.749900130e+03 38 < 1 0.1 +lotfi 154 308 1086 -2.526470606e+01 104 < 1 0.3 +maros 847 1443 10006 -5.806374370e+04 703 < 1 1.8 +maros-r7 3137 9408 151120 +1.497185166e+06 2340 5 16.7 +modszk1 688 1620 4158 +3.206197291e+02 705 < 1 1.4 +nesm 663 2923 13988 +1.407603649e+07 2240 1 2.4 +perold 626 1376 6026 -9.380755278e+03 1103 < 1 1.5 +pilot 1442 3652 43220 -5.574831533e+02 5726 11 7.8 +pilot-ja 941 1988 14706 -6.113136466e+03 1697 1 2.5 +pilot-we 723 2789 9218 -2.720107533e+06 1382 1 2.3 +pilot4 411 1000 5145 -2.581139259e+03 532 < 1 1.3 +pilot87 2031 4883 73804 +3.017103744e+02 7573 28 12.2 +pilotnov 976 2172 13129 -4.497276188e+03 988 1 2.5 +recipe 92 180 752 -2.666160000e+02 17 < 1 0.2 +sc105 106 103 281 -5.220206121e+01 51 < 1 0.2 +sc205 206 203 552 -5.220206121e+01 124 < 1 0.3 +sc50a 51 48 131 -6.457507706e+01 25 < 1 0.1 +sc50b 51 48 119 -7.000000000e+01 30 < 1 0.1 +scagr25 472 500 2029 -1.475343306e+07 352 < 1 0.7 +scagr7 130 140 553 -2.331389824e+06 94 < 1 0.2 +scfxm1 331 457 2612 +1.841675903e+04 281 < 1 0.6 +scfxm2 661 914 5229 +3.666026156e+04 587 < 1 1.1 +scfxm3 991 1371 7846 +5.490125455e+04 881 < 1 1.7 +scorpion 389 358 1708 +1.878124823e+03 146 < 1 0.4 +scrs8 491 1169 4029 +9.042969538e+02 545 < 1 1.1 +scsd1 78 760 3148 +8.666666674e+00 91 < 1 0.6 +scsd6 148 1350 5666 +5.050000008e+01 182 < 1 1.0 +scsd8 398 2750 11334 +9.049999999e+02 397 < 1 2.1 +sctap1 301 480 2052 +1.412250000e+03 196 < 1 0.5 +sctap2 1091 1880 8124 +1.724807143e+03 425 < 1 1.7 +sctap3 1481 2480 10734 +1.424000000e+03 729 < 1 2.4 +seba 516 1028 4874 +1.571160000e+04 883 < 1 1.0 +share1b 118 225 1182 -7.658931858e+04 167 < 1 0.3 +share2b 97 79 730 -4.157322407e+02 87 < 1 0.2 +shell 537 1775 4900 +1.208825346e+09 467 < 1 1.2 +ship04l 403 2118 8450 +1.793324538e+06 373 < 1 1.5 +ship04s 403 1458 5810 +1.798714700e+06 262 < 1 1.0 +ship08l 779 4283 17085 +1.909055211e+06 516 < 1 2.9 +ship08s 779 2387 9501 +1.920098211e+06 274 < 1 1.7 +ship12l 1152 5427 21597 +1.470187919e+06 686 < 1 3.7 +ship12s 1152 2763 10941 +1.489236134e+06 383 < 1 2.0 +sierra 1228 2036 9252 +1.539436218e+07 857 < 1 2.1 +stair 357 467 3857 -2.512669512e+02 399 < 1 1.0 +standata 360 1075 3038 +1.257699500e+03 140 < 1 0.7 +standgub 362 1184 3147 +1.257699500e+03 140 < 1 0.8 +standmps 468 1075 3686 +1.406017500e+03 299 < 1 0.9 +stocfor1 118 111 474 -4.113197622e+04 24 < 1 0.2 +stocfor2 2158 2031 9492 -3.902440854e+04 499 < 1 2.6 +stocfor3 16676 15695 74004 -3.997678394e+04 4456 11 19.7 +truss 1001 8806 36642 +4.588158472e+05 4744 4 6.5 +tuff 334 587 4523 +2.921477651e-01 61 < 1 0.8 +vtp-base 199 203 914 +1.298314625e+05 69 < 1 0.2 +wood1p 245 2594 70216 +1.442902412e+00 326 < 1 7.1 +woodw 1099 8405 37478 +1.304476333e+00 1093 < 1 6.0 diff --git a/resources/3rdparty/glpk-4.57/doc/notes/dfeas.pdf b/resources/3rdparty/glpk-4.57/doc/notes/dfeas.pdf new file mode 100644 index 0000000000000000000000000000000000000000..35f5d3aa5c71ec885b00186fc93c3c608bc6b9d0 GIT binary patch literal 63866 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

H2o_h;BuI(gM| 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 Yc|v_X!FIT!LSkZ~xNL07+A6sJ3*O;Z_W%F@ literal 0 HcmV?d00001 diff --git a/resources/3rdparty/glpk-4.57/doc/notes/keller.pdf b/resources/3rdparty/glpk-4.57/doc/notes/keller.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3aa69388b23722a2de031d594cec1fca03cc68f7 GIT binary patch literal 85985 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�)t%lZ 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 literal 0 HcmV?d00001 diff --git a/resources/3rdparty/glpk-4.57/doc/notes/scf.pdf b/resources/3rdparty/glpk-4.57/doc/notes/scf.pdf new file mode 100644 index 0000000000000000000000000000000000000000..da324f27f178217b471ad70e6e3dbf2641131ba6 GIT binary patch literal 123131 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 ZdL#V2;r7JBA|m2K!o-}Ms=8{#{{>UztBwEw literal 0 HcmV?d00001 diff --git a/resources/3rdparty/glpk-4.57/doc/notes/simplex1.pdf b/resources/3rdparty/glpk-4.57/doc/notes/simplex1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..828ad997066fd906b5575ade09a565c18c2e2570 GIT binary patch literal 398510 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

)| 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 p4*QB>QO&pT(UtASe07}>{7w~h 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 z�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 @QqW%oL7zX`*h~?ha;aJq(7Ve1~c9t!~bb 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 z

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 bIsMMG4IUDA~d0%}yk} zle<62hSAEZ7R^D}^B~w5t*y>_N17dGjHa4_r#YD20(5#XHoL5kaCG;t+_Bu?;5<}+jgX0(#fi zn6;P-<_Xe6^6u|xyLeuO5B;wyT{$*ZUiU7Z{NR4|3-mTZUu6-?Nia^}PvK++<|uEI z|3TUKu(4WD6>@AeKHCm;(6j^HeK;mU2mJN4wZ1qU6ZpY0zz}ap3%Yq;-|Sx~LwNem zv{c;F`!_U|b(ck#O|M7d6kJnB)3b>R(!Ja?LjeP3jB>QSz-g=Jg)c>Xvn$<5z>GO_ z!r>!N0S!Yd4RBG3vL}%HK4GbUosG8mN0NNtvv~TuTeTDQ8Iy+&LSww%T?4!;@=;IG z(jf4C04^)qosyTg2t2n1W2;%^Gd(lQP7wdY**P_77IoP=ZL89@ZB?Suwr$(CZQGfZ zwr%T8+qO@gtL~2Y;zY-}**{>#-ZAEwdyVn%yPa_mXU!BgpI^7}ifz^}eD*ae-pggJ zjNnyB)RB#Awr$!vYHYHTHpM?$A+FDZ9f8;7MD71$5o`d!NkO60oR~!Shj9*94DYaY zAOIrEEy0V?a=YOkhP9X#i?dNWOm0(H!mbkqZrHf*=Jl^gUJv-G+q2&kq}upY5<6J+ z#0)7wS_A0)t0scD0vFqFwm>04Gv%wN?97((8%ylUzp(`ESnN*=-~qTc+RwiK}sm8^*p%v5klj?1Yuze?O$dVEnaZ2O6o#xO{K_ic+? zM3Xm<*g-Rcd9Cpw1(lOcEH7i(iPw{w;0%l^zG6cAzEM~)*nWsp&H{ZaqB)4+BENWn z=5@p9^-Ugmt-fHCviCtS>+_T>YH&OIR>euk=gb*7Q6^{rc~Ho!Y$rs}$2mmf(JjZSR=$kbO0!_9T&OPZs2aCpwBxvcxrKj)L(1DoQ z(6S!kQ3I;vKzL*x*s^bUFyV~w26@!FQ`GI|0&_nwiDAaVQj!rw~}- zo9cUiRzXJ}9&WGv)kt+X)b7U(*_0i%l}L_+#6!;~|UzDj0A=!+c%3Mq_+7HgW6-HnmyrlrOgEog$?cE;M zAX{2Ho>(hoaxHb&>qiIa=cIW^g;lWuZTI`KvoC#1LOuXC!F>*uQlD8XrgFM6j3Xi0 zNS`e1)@m_zTps@`7iuPsF~{j#r|53Z4K6u$rPZ9ZDhJ&7Mc^4=4pd1QYoFF{WBo zJEuOJ+(@mXSH3v%1V>v}8P&%n1CO=oxA~43b8vXQop;j%J}hj}62iG!)(1mDIt^oE zAcsB9n;hrOc?&6D2at#TA&sLpIvbknyK4>t4?dpOCol*>B+z;!`@-*PwmLy>&C+LL zkT_SZo0n1qPj@j*s@Bm~{1k$BPz7!7I9S$!du;32+RC|k^!4`jBVM?;2>`}a2D|X} ztj=y88#l$Dh7$eRLVdH#Cw%m}-|Msyh5RZOHyBdO z9WJ#2bNgm%R2+5C=N95;bFT!DOQN>R*0i)n~mn1G+Y z0IsnW@O_oPUFKv7iQgW1*nCZkzWpk~3FVj@sDmCRNk>8M$)btubvthq00GRasPRN~ zkG42lQe7US`SPb^q!5Qm3LQ5d5H~JSGD($4Y1($;X%^rEf*kZHK_tR0NECS*6k@LE zWUO|Awx-fpv?ThPz^ZmdmCyGy!) z3U#GH0pvDOJsP@{49Vz~Riq{IArl>~_$A#-9<#TQ^FgkygYdS=Ci~cdX*Cc}p`jEJ z-6|bG4w>71{=H=ng5G|gg65=55Jl!*8@0`kJZ+Ms_2MOSvBtV3zv#N=D#FLi z_eQmS8$jOU0(!A0MZIV#aEK5|J)!%@ODdK}PX&Zt!s-`y55rmSGsQco!zg*Ikn=H| z0qNxvp5m6YQiA}fXW7moI{|j?>RYp<<6dIQleXC@)q-G zNqG_v^IeSG^@IK$Cv=&lKlAB{s&j-UuSgyU%sX7%^%t{8tg@W$VN9{EAOd;=hZQNL7CiVwqk7tMwsc4z@;s8s%Q^-6^li3t&yW z>5&~?Co%|KWeijKnwlKrCn(FEI^j@$X3C;EDuG69_Y_I-#zcn#tf_157?iGUacBd} z@{L+7S=PD4GM};+_8?mq&k(O7e1$+ruT#db%sE=KNN4|A)T@}y2VhVQ0HCh&7ZA*P zTR%)_e~s#Hy{u>u6qG`XXC43~uw=Q9fL{oPIdG@nMlT9=#oQ?1^2?ctt5la*d7bLd zO8mYqKRKM`^?5rhX*iTGtfJ#@J>JHKi1w9@@U|r*G-MYb6+coU0_Fr~BbvY7U@>ZZ z!y%qMKR++}j`N4*Qfdn&6eFnI92)sM`6Q(od14;KIgd=j1;(co8>{`NQL{9iYe>E9 zB!3YU?F0%FxZ=6BWozqyKy8yP_br&qi$`9tA6_Wrl<=$$ zn^3vhp6P4vkLs@TRO%shF3O?XxIZJ4XV*%RYlsX!o7fD0YiQ_A~!jF7(z8s5IozclF zP|&2saljv;>P>3_S{5vsFQ9JN+-b9efqb^zPjatD5r8E}FU~Q|Sz2*6+Ci$d%hFpX z1pfiqlkrR9K>J^M(XK6LX^CnL2HA-7HZJZwM;7;uAY<`3?T5~s9oPCy9J4IgmQxJj!+s&P3!L4w5VKkkV1R{GNZOyO@|VZ3O4cm?@AQ|2oeFTxS|Liyc@& zI|X%Y!M(aLImx$(HFSE6&ZhYiHySI>u?LZFUaLG|z@bH>aZTaV2ikxzt~8CMTtuy) zSGjW)IJ87c8r)tu8I8o;f!lB%(>nGDij73%l8odh5^b zU5T}zULa8p$RH<=H0`AptQd@!6BS?VmHw4EfBNyG;rK}oTN~C6(G+lu5DQl`3U&ME zp-6ZwoG1qmakwa1QYO&>HeyQ_L?dpuCf?3;pot9}zRnA6EykNs&) zDYlSGEgkN@J4{%j5ql3iK%IdG8AoA{b*?E(jBhB@hs^#6BQODJ@I4CD`2JSe@dJ*NFqmg75I^Z*eO#uv-3ib$xuz8=@0` z?npC|6D-{Zs<%_an2g9OwQ*H-f=9n7QP@uTlwF(b+_bL*6@YU4&gR1M9Q1|St zG0tXkflCqb?kjoq9CQwufv}d{gi1m)ttUBYIZV;dN9M4lowJ8?ZZ$`i+UQBTLO}yM zL>`68Yh4@$V6f)msK2B38gSsgX!{x5iqkkTuJG*y}3X}z|g;Lo)j&Fnu;x&cp z^yiKZD`t(u9EXRuJ7XriF)108k3`x5D$DqN@+cW18Y3!mF`L|^6)okwks68*v^gSw z(^6G^VrI(BPvym#p67zA99T5YBz%oXj2-9F!snwzE26ddc8C5eQ$K^WlV}E`cn#h) zqq#YWRN8I`XMpP!e2T)aZipsm+^ESL4HQ3~gP;(Q+fNk4I3^d?Wx` zf?^NoPwTJ^tnd28(zU_Eh8vtKlWvLKqALR(G;5cUb%-P z?waW}aqeDOAipB?lPl=pw)C>UV^ZN8g6llqw+$GM;EB2WS5j#f~ep85$gT z#r>8Hj#GM9b&9GtLG4UbhND6=G2sKPPiFL6P!-3F6+|OOa1P#ghB74B>jL{_#qL-+ z;EhP6rA;$6NYvQ_F2gt`u_9r&kTVoGW$N%6PW5G~+H^dGSjTb7()lEfm8=1EgZ7@4 zKfi5Eu`Y?(vL^G-X-`xyGAh}kmUXm!Lf}DEv1Bt|G&sJ_>(Akwr*> z`#D$m8s<|`C0g@|^O+^IiLI7<5r0QEeO>c-ibjC-m9Qe#bQdSEa?SHCAHwBt!~tV&`QKehuQnNG|A~c#a`Ch-o8x z`;1UL+aiX@H zZJ=Gktc+qbp3-`8=#K4b_}2{t@}(F0x#;e1RxH`a3X1VZqp;w0mZfEMi zZ!|&b3p{dp>2&M7mZH9Lyq>qZKH^K`5_;{%?0j(wpDTx{7_exJV4b$nLYvW`^$v8bb zNR}C}LvWfX%>*v_ZJ=OE_vNR)j%MaLlqp>A(zfIcncY-D1W=Qh~ed%(q5P8<)!fwOapGMF;k5CqEab_Xis6kIv89& zf+~2)AUTVt0cu>HWD(WApdi_^NKy3D|LtT;dF&(t>?wG;NofH?@z#GAs1tT4TOx{N zv@kZuA4PfWAU1I;VDyj`Fb*f_Xedbo5X5S92nw!%F#pT3mXM6n!37Yu&R@)uVCJiQ zGV4dskp7o^F*XJF+A_&nTZ5Q>0%ISeEE>5s^DlNXBh)hX9*iC0N>r0bAX*kbea__5 z?0|}-&C18e&VJI)8Yxyx%AAe|M}`#1VNx{sZM)mT_0S+}ZSKVCfU3%~>(0J%hhWhz}~6RY#cpBdJ?*OuIl%+U%A%F!C)_v$$2y45~-M2f9~!YD1LYFz+kC275nH+PK=0#+6G!zio^!T_B%YDD0<^~8EwIyyB19*mpI1y&z>A| z2N$<^W1GD(Fvrtq)y;|~!V?b;GBj9efSKET1bj)0?_%B~ek|0(Rv_+dBHxW{9nvtk z9HApwkFtTbmt4#KvWLtXfb9sU`#Hj8kAvMAy>S}YjhWzC*8}pRp~ddGu>yrru0KON=sUydeZ7~hHS~KM=*plgwVT%1M*mx+_Sz3 z5@WvC688PO7uHT1mv_(6i`NzLw;+G_tRU(EWlU(|0J>HlcvCZ}&)v?wxf!$}G!SjVfM#CnX0Lu3GhlQ~lt{A+=w4XYe9W zsHu_F;+3|Vij4{hJB3Vl>s~k4BZzuS*Skj5xHU2O3iV$cA8v-%{+)xzP%l)zabq*( z>`3@O@4zuP*6Qx7)UL2zcuI(D$U5(k-PB&e6&bIc9PB!1-&YI-5uRTALC~UtGwJ1; zjUB+}bNf+jb@O(8zk+yXAPsdDS-7~&_3mP)fk{8_%Q7jF^C680%lr&!j=LBIixzhD(ItC_GgIo`we9@DA zZul;`<5-Kt@uz%{>Oh4^EGJN{8*A$GtYYl>R0gvDKkR(m3)|Qy&PZCaS z|CtdqJ&i?4KEFD^^y^vM`1Q}=p)G@i0@sU*!8GeCHjw$@iOs`y1Fpa> zeY#G%Yu#}9c`C|I<)7wMJ)xCnuG9tAz0W$gQX3=rFA*|LWaUx& zp=3<=^mpS-Uq6$bS7gtNw@qysaWQ!dgSJXn};k35iV=N~J9 z+b-GsPhkZ{>2CyQsjrZrMa8eL;KzK+B*8Q@Nq>8nSzJjVUzC8hYRmnI9bB{Z$>eDI ziCsFlg$E^9=v&O8|1J_Y_7%Wk2?dvQKz4r_r4#*S_ZkereRyhSI90q-4~{D}g=zI} z5?fmQg%@c-VxuxK@eWX526Mtk=$ZEctX`4l6Ez6<=9{^BH{GmJ=J&`8#H%&!OzR5Wq?Ao)Nfjut|4MF3K+jJUvk@i5H|D)BEbZK@iz7cN;nhsf*Lq!WSf ze%bwF&=s#G-Ma|?;+E%B7PkvYg|N^u(LJDEryf@v&MvExI3{UFbTKE+A;{VcwYEY74o6HYUDPc16rqf+S@ zxDH`NQn9@?8dx`~E7ike^NZ)G`fjW5zzdNA0-@LEw%f=ql$#_6 zSoW2X<2*B3#^jRE&?&59kep(hQu?=o-`np4FQj)?SJF~9S$;~I1LthcEqJdk(Mb)}7JP#C zG+7~mgF{-noiLb_`C8m+Ze@#XUqpkC@aW-%ak?8LkTJvLE9w-~O_-$oTksTu;!*l! zhP&Xjh4T9F+Czh5+2aA)3E!rB zKb3vgc}7Us8z+B`G-J@Nk>v+@q0e`r8z^fi`&dU5g3btTqBP{OJe{8WT!x zDd|MJQT_MpGCwx==53U>%U(Qs%IUp-RzXTKar9U zwWzBmWjZStzK{J*wAO}LZ*>*g zvIS(=Fx(gfg8ckCa7XU3oXetYfcua{sExmPYcUXizA-hk!jb zD`+e9o-9VCgLu2@n6U0$jDFPi|1>ubWKYa>r2@4nbv626ZgK0_S?_Od*HMm}M16Ve z3f3CR`6cJnO40IGb&k1K38OV=-cWOZGjpXL27T3~My*A>p6K$MjT0SglV2Zr@JG{F`^0~NWJ58#;T z8?Q}69Ss_+XN@knvfN)k((PqKr@^*69N+zoM3Md2EWNy*J!QuX$HloUC{u_Lsqf^Y zv*^TtHX8srf4?WjUmDlnn4M~uJ8G@Nj4 z)P}HG-`~l*yx?nMR+P1(dbUi-^!Xc;W3cF$#+X1Z2c~)LTG}Gms-TunvuZa(cPZaY zsTna(Hh4@zN$8LK6YfU&Hj4K;g2*=}5rc@a%($jb)1Z7-^|-tsN>;rqfyZ@t|K3d! zopZqi`Eh5nzk3(KQU>u=OUQ-V#L`gkDP}9pIAEnT7q&{#0Lz_|z!{+xM_3xu!XciO z#h$$kzwlw;#@*c5*im=M+67G^_mbn{aB`88OvDY8Y#QS&ymyc8FG)snXubH|WM>bg zNAzz``@RcLXupL-3Cn_=U?z!yP`j1d_mlvbo4 z4sMnZl|ay)O{y=*L0Dk0u9F)bE`M4ctg5hxWUIfbtu;Ag-<-8V^CZ9oz7nE5;5eNt zW)oyB6+6t~ULT+%pbkP)@JuC|t71nUPGHfkN`MEHHo5ok7%tqoZzi4*(V0RG(ZXsS ziqdp0G70UO%y}nhN!=@}^L!A#q+=%9&mKlwAx`NP!)K4Hi*>Psy0)q05nn{I;~|Ed zr1D5%E~P~M?}1P%Yn8lfCf=4*JLANe(G39)jHUvf9DK;3@nln)x?C-^dH2sHN<~DS zk3e9pVQnL?^&koeJXvT-A1Ectv#_RT-me)dBGsTIDQk4mzldJLahM~m;!S;Gb<`)S{n@w;LvGb(bO9zk7_GFL1Ns3MFEZmd2(I zm-JF7A6EorZ4*Lznzz|;m_>2*`sF%pyCfyN_Ek)cZ)qgGn#9JI6I09%{hjY_; zARJh!1=>=Je?GZJmX)rwx_6EXc>3oLqJ!NYv$=*mP~5hPD~mLh7E?F6Kyt-kV^ezm zG`u7vRKuIS+CC-ai(2{2cF;a3%TW z1nuuDN843&LwdI&FDPZ{64W5OT2858qhiO#dXbes{&txQUkCJld@=id_4EXpXVj$J zSfa98EAskYCK`Hzy=H~aR)n&?MtOkD=_V#SGD^JF`G*_`-i0kyt}3t%qcsY8< z;=x+pTGbSEnbh7EyJ}6i!SXQc_L<;%(jvUOF(NT;YK9*ZGKj1F*hsZ zMqvAAGI8C4XVVR)wL3THt4-;U;1rjr?cV*%9=RLI^4J;8)UGT8%5+%WEcpHOv;tk{{c03oYRtZoIPGdkm z%cE^SuocXzf`~&lzkV~H&HI5cxAwBa2i178#-5dlGS0x6IWey7$4CAkEP?FSffTO; zV+-Szp|9Eqy~UPvxe z&B?3rv0{IK<5kkFU$JI(P|OtFW%PW?rbNev3;okVfW--ODs8BkO+E3Xv zv#d%)DXDM#M)EBPe?$s#R=#>;g`_6!Mzyaw9ifUC<@n>XD*|&%F!3C4xuk+lZ*#9j zG#79ff*anm3%6pw`%jP3nJ|6PCNax6t7!39Iy(D|o0KO9ZYea@H?6CCCfr4iX9srR zCOjBbdS|r)CbaCUnBH*icrO0D!#MN2tVl{L8W4viZClp+Pab7@gZMX4vo_Hw1gw@?~DSjyL?I(n`tpWHaoHzkJMa5lDm&gGnSd zps%;L-yBa(jp=eR44owZo9U(c@eDpMzzC%7QAK&B?hb}gp#w<^!AbGs5cY1);^B;~1-nBhu}{>VgRDh;8_sZGhs=Hk?eD^e$+!@5uxm9~l3jnVHf zQR^U6#7{@6gc`;~(x?rURC3j_k}=I2){~;0Nkc;zjR&6H!9;~B(Wq8RQx|D8|4y)& zbBfF+&XGip%ti`?3#x63R>DGG4~3^L(iNx9kf0QO7<>Cy0hjCSq_H|Q@v)L~ENu9h1H{ga_S17x6snJJw7qPa;}S7H zZv^++j5Yp@HBQ-iP`C{!=yth4DtE_jnYFKsv2D4AHyiRs5Q8>sy+!4CJVTXkZovBX zf#S=?7G>R5$(#^#+P$h$YW-=rO6E?`szmoRcvAOWG{)Jegf3Ubij3~rYi`?@K+{<1 z%hJO8XwTGR%oOvB{k|%%i!-oI49!yL0<)}W`KG!Xu;m2pTR30N(K|e^p8D^&Ih(6i zoCfaRLfG_;d^jMnXF$HB2wiG%ON-0)pl~CMZrjvs(B;AZWTr`ZQ_@&B7B4h7#n?<< z=UDuOH_xVm=G(Z_A7W~#!O`ItDnLFE7z%zH`AL&78&TAsG-E?nqRv59#Qwy7)=Zqf|bXUuI=YXm_7ZHQoMaLV3 z<`G5IH9r}lfg)WF9R3vlz#cY*wcqt^(tg}EN&Ytn=V8BiwJEL`_%MoMA=w69prf*U zp}b%@*nFsQII+Tz49w93117=A^0~l1dxg)jkqrJ06UJ;GSF|eNW&9e1%T;0(pifnm zlH1@Ga4?oON9ruxVSE#ya1_i+0sS$L3kUhS2&Hz5jGnJi zi5K*g|G-q7)R|8lnY*TFx~k{ZE`9&jTkD5~7mmA6jXn2a&l1FyW0N|!*bDECZBgGD3&FHCu!Sh z{1O2ZYvrB4H2Yz)Xan+oyR8PNC;PKp#!AS4%F{71|5u*w|AC%m`ycewf9P4uU`C{W z=-K185;UV?TSQ`K9WdBVx(j-#I3_Hcd~%|ZAV0mBhA{kp_m#Umx;PXR@MvmyMf7IE zvH6-LrNV-+aswe)bWEbi9VIa?76(mx7j~fML{p`??&btawMdA~wNG;|RUh-WM>wv?J7i5*pV3I>GGrLGR^|y~Kesi0g28Z)4Ab5Gjg)M#Gkb44|jkBl@k+o3sMW5fMSq?`nvWxV9$y z@7-_3;|VZ!g))I&5AU1ncUPu0$z<18+NfS+*Do*3cTJ(LIqjTD`|A@ste^QjYrN$o z@P?c7z|(uYx6S{ga;_fxHy#CJeqf)r zK%5lKxbcO$@h2ngiCJ_$Xh(WO_+hc-7-vWkHe!7G9fK{e^n~vxM@_YMr|rt-y05?U zrI+3Q3Hv&}zGP)AgEf1849{A@0vj%SVhGE0w({6C=v)5SobhxT!bP~q;<>3;RjG=D ztJO14MMs#TVjxIpCe`&agFG4=5x zD6HA}kR=dH=;mbI-^+`T=6EKA$~mO2!LAGR0GS8YIedWBhq*v=TxCJ!8PF31UU5&3 z=)5w!iil0V?R?egJgvrx7qO}{MJLUNE<%=*tTq*UxF6BC=6%QRgdBX~GpUc5VBr$+ z5)mmsEaEAG@QPQ;w&UP3H-kUM9-d=VZ;>`!Qzn0g{< zA`<(kMUyyVRIreO@!6s5=?s@R40=Q}9*4 z?vLE(ec#qb(aoSsTcJnqo#tS3C{7=5_UCN?uA51mde^mcDt^z=&)EH&SW@1^LmBr% zWKMb}iR4!TrE6zp`^vV8lEDrbuTjMBbUYy9xc&pZ?|1r%cFc#5E~G&D*4Zl$FQD1Z zfr8~)%o{7n5nJFW+|2};lbuK_G3*^HLsNvP4dxd5yDU|O;x;*C}IXGx= zKO~q?5g{OWDYwsUM`fqNbD`y3dVTwA?CcPydgDZKJz_DGwukkjUhNNs>Vss1Les)4 zYDUTz)MU{SA;nk`b>dMJcbWDRmt&pg$4#*$y#ic)e4UT$g~C=Y`q#X$IWf@61I;2D)mvJe|;N$ zRAY?J!HVC5YYGxl=4C7@GU*2C4a^=KxpV!)V*QDg%)6r*b_doU|Ap}gl7y(9l%6T~ zoTzOdspzC=vS2Sjv^E;t@xiSD+tz`Xv&ds=YWytg7(hRQ-|$$^bPF#0CEc?-&=V{# zKwB;WGEIk!{mZmC-uuNZ908oy_y=sfJSas6Y(mGID+p0SUx0NP&wR<@8lxx7jk^FR z7OWtx_pECPY3rad5gQ(En*+|}2cNb;<1zkB3oG)uEZ((1Hc8*{>)I_3`R9{;1;KIj z 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 E0A%V=P5=M^ literal 0 HcmV?d00001 diff --git a/resources/3rdparty/glpk-4.57/doc/notes/simplex2.pdf b/resources/3rdparty/glpk-4.57/doc/notes/simplex2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a9c2878d68c99b9c93405024c80d94cacd51f8ee GIT binary patch literal 209721 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/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = glpsol$(EXEEXT) +subdir = examples +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am_glpsol_OBJECTS = glpsol.$(OBJEXT) +glpsol_OBJECTS = $(am_glpsol_OBJECTS) +glpsol_LDADD = $(LDADD) +glpsol_DEPENDENCIES = ../src/libglpk.la +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(glpsol_SOURCES) +DIST_SOURCES = $(glpsol_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(srcdir)/../src +LDADD = ../src/libglpk.la +glpsol_SOURCES = glpsol.c +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu examples/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +glpsol$(EXEEXT): $(glpsol_OBJECTS) $(glpsol_DEPENDENCIES) $(EXTRA_glpsol_DEPENDENCIES) + @rm -f glpsol$(EXEEXT) + $(LINK) $(glpsol_OBJECTS) $(glpsol_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glpsol.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +cscopelist: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool cscopelist ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-binPROGRAMS install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS + + +check: glpsol$(EXEEXT) + ./glpsol$(EXEEXT) --version + ./glpsol$(EXEEXT) --mps $(srcdir)/plan.mps + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/resources/3rdparty/glpk-4.57/examples/alloy.mps b/resources/3rdparty/glpk-4.57/examples/alloy.mps new file mode 100644 index 000000000..9f774f165 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/alloy.mps @@ -0,0 +1,282 @@ +*NAME: ALLOY +*ROWS: 22 +*COLUMNS: 20 +*NONZERO: 203 +*OPT SOLN: 2149.247891 +*SOURCE: Linear Programming--Aluminium Alloy Blending +* Data Processing Application. N.Y.: IBM Corp. +*APPLICATION: Aluminium Alloy Blending +*COMMENTS: fixed MPS format +* encoded by Andrew Makhorin +* +NAME ALLOY +ROWS + N COST $ Cost $ + G ZN $ Zinc Minimum lbs + L ZX $ Zinc Maximum lbs + G CN $ Copper Minimum lbs + L CX $ Copper Maximum lbs + G MN $ Magnesium Minimum lbs + L MX $ Magnesium Maximum lbs + G CHN $ Chromium Minimum lbs + L CHX $ Chromium Maximum lbs + G BN $ Beryllium Minimum lbs + L BX $ Beryllium Maximum lbs + L IX $ Iron Maximum lbs + L SX $ Silicon Maximum lbs + L MGX $ Manganese Maximum lbs + L NX $ Nickel Maximum lbs + L TX $ Titanium Maximum lbs + L LX $ Lead Maximum lbs + L TNX $ Tin Maximum lbs + L BIX $ Bismuth Maximum lbs + L GX $ General Impurities lbs + L SCX $ Scrap 1 Limit lbs + G FL $ Furnance Load lbs +COLUMNS +* Pure Aluminium 1 + A1 COST .28 + IX .0004 + SX .0005 + FL 1.0 +* Pure Aluminium 2 + A2 COST .26 + IX .0006 + SX .0006 + FL 1.0 +* Pure Aluminium 3 + A3 COST .25 + IX .0011 + SX .0007 + FL 1.0 +* Pure Aluminium 4 + A4 COST .23 + IX .0026 + SX .0012 + FL 1.0 +* Pure Copper + C COST .31 + CN 1.00 + CX 1.00 + FL 1.0 +* Pure Magnesium + M COST .38 + MN 1.00 + MX 1.00 + FL 1.0 +* Beryllium/Aluminium Alloy + B/A COST 3.60 + BN 0.0600 + BX 0.0600 + FL 1.0 +* Pure Zinc + Z COST .22 + ZN .95 + ZX .95 + FL 1.0 +* Chromium Aluminium Alloy + C/A COST .27 + CHN .0300 + CHX .0300 + FL 1.0 +* Scrap 1 + SC1 COST .21 + ZN .0009 + ZX .0009 + CN .0444 + CX .0444 + MN .0042 + MX .0042 + CHN .0001 + CHX .0001 + IX .0024 + SX .0101 + MGX .0079 + NX .0001 + TX .0004 + LX .0001 + TNX .0001 + GX .0001 + SCX 1.00 + FL 1.0 +* Scrap 2 + SC2 COST .20 + ZN .0012 + ZX .0012 + CN .0026 + CX .0026 + MN .0060 + MX .0060 + CHN .0018 + CHX .0018 + IX .0026 + SX .0106 + MGX .0003 + NX .0002 + TX .0004 + LX .0001 + TNX .0001 + GX .0002 + FL 1.0 +* Scrap 3 + SC3 COST .21 + ZN .0568 + ZX .0568 + CN .0152 + CX .0152 + MN .0248 + MX .0248 + CHN .0020 + CHX .0020 + IX .0016 + SX .0013 + MGX .0005 + TX .0004 + LX .0003 + TNX .0003 + FL 1.0 +* Scrap 4 + SC4 COST .20 + ZN .0563 + ZX .0563 + CN .0149 + CX .0149 + MN .0238 + MX .0238 + CHN .0019 + CHX .0019 + IX .0019 + SX .0011 + MGX .0004 + TX .0004 + LX .0003 + TNX .0003 + FL 1.0 +* Scrap 5 + SC5 COST .21 + ZN .0460 + ZX .0460 + CN .0071 + CX .0071 + MN .0343 + MX .0343 + CHN .0013 + CHX .0013 + IX .0017 + SX .0013 + MGX .0018 + TX .0002 + LX .0002 + TNX .0002 + FL 1.0 +* Scrap 6 + SC6 COST .20 + ZN .0455 + ZX .0455 + CN .0071 + CX .0071 + MN .0343 + MX .0343 + IX .0016 + SX .0011 + MGX .0017 + TX .0002 + LX .0002 + TNX .0002 + FL 1.0 +* Scrap 7 + SC7 COST .21 + ZN .0009 + ZX .0009 + CN .0447 + CX .0447 + MN .0143 + MX .0143 + IX .0026 + SX .0013 + MGX .0052 + TX .0003 + LX .0001 + TNX .0001 + FL 1.0 +* Scrap 8 + SC8 COST .20 + ZN .0006 + ZX .0006 + CN .0623 + CX .0623 + IX .0017 + SX .0010 + MGX .0025 + TX .0005 + LX .0001 + TNX .0001 + GX .0025 + FL 1.0 +* Scrap 9 + SC9 COST .21 + ZN .0009 + ZX .0009 + CN .0034 + CX .0034 + MN .0093 + MX .0093 + CHN .0019 + CHX .0019 + IX .0030 + SX .0062 + MGX .0002 + TX .0003 + BIX .0005 + FL 1.0 +* Scrap 10 + SC10 COST .20 + ZN .0008 + ZX .0008 + CN .0003 + CX .0003 + MN .0249 + MX .0249 + CHN .0016 + CHX .0016 + IX .0015 + SX .0011 + MGX .0002 + FL 1.0 +* Scrap 11 + SC11 COST .21 + ZN .0675 + ZX .0675 + CN .0195 + CX .0195 + MN .0265 + MX .0265 + CHN .0020 + CHX .0020 + IX .0014 + SX .0008 + MGX .0002 + FL 1.0 +RHS + ZN 555. + ZX 590. + CN 140.0 + CX 190.0 + MN 245.0 + MX 275.0 + CHN 19.0 + CHX 22.0 + BN 2.0 + BX 4.0 + IX 15.0 + SX 10.0 + MGX 3.0 + NX 2.0 + TX 2.0 + LX 2.0 + TNX 2.0 + BIX 8.0 + GX 8.0 + SCX 900.0 + FL 10000. +ENDATA diff --git a/resources/3rdparty/glpk-4.57/examples/assign.mod b/resources/3rdparty/glpk-4.57/examples/assign.mod new file mode 100644 index 000000000..6f700bb16 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/assign.mod @@ -0,0 +1,77 @@ +/* ASSIGN, Assignment Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* The assignment problem is one of the fundamental combinatorial + optimization problems. + + In its most general form, the problem is as follows: + + There are a number of agents and a number of tasks. Any agent can be + assigned to perform any task, incurring some cost that may vary + depending on the agent-task assignment. It is required to perform all + tasks by assigning exactly one agent to each task in such a way that + the total cost of the assignment is minimized. + + (From Wikipedia, the free encyclopedia.) */ + +param m, integer, > 0; +/* number of agents */ + +param n, integer, > 0; +/* number of tasks */ + +set I := 1..m; +/* set of agents */ + +set J := 1..n; +/* set of tasks */ + +param c{i in I, j in J}, >= 0; +/* cost of allocating task j to agent i */ + +var x{i in I, j in J}, >= 0; +/* x[i,j] = 1 means task j is assigned to agent i + note that variables x[i,j] are binary, however, there is no need to + declare them so due to the totally unimodular constraint matrix */ + +s.t. phi{i in I}: sum{j in J} x[i,j] <= 1; +/* each agent can perform at most one task */ + +s.t. psi{j in J}: sum{i in I} x[i,j] = 1; +/* each task must be assigned exactly to one agent */ + +minimize obj: sum{i in I, j in J} c[i,j] * x[i,j]; +/* the objective is to find a cheapest assignment */ + +solve; + +printf "\n"; +printf "Agent Task Cost\n"; +printf{i in I} "%5d %5d %10g\n", i, sum{j in J} j * x[i,j], + sum{j in J} c[i,j] * x[i,j]; +printf "----------------------\n"; +printf " Total: %10g\n", sum{i in I, j in J} c[i,j] * x[i,j]; +printf "\n"; + +data; + +/* These data correspond to an example from [Christofides]. */ + +/* Optimal solution is 76 */ + +param m := 8; + +param n := 8; + +param c : 1 2 3 4 5 6 7 8 := + 1 13 21 20 12 8 26 22 11 + 2 12 36 25 41 40 11 4 8 + 3 35 32 13 36 26 21 13 37 + 4 34 54 7 8 12 22 11 40 + 5 21 6 45 18 24 34 12 48 + 6 42 19 39 15 14 16 28 46 + 7 16 34 38 3 34 40 22 24 + 8 26 20 5 17 45 31 37 43 ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/bpp.mod b/resources/3rdparty/glpk-4.57/examples/bpp.mod new file mode 100644 index 000000000..8dd354ed8 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/bpp.mod @@ -0,0 +1,83 @@ +/* BPP, Bin Packing Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* Given a set of items I = {1,...,m} with weight w[i] > 0, the Bin + Packing Problem (BPP) is to pack the items into bins of capacity c + in such a way that the number of bins used is minimal. */ + +param m, integer, > 0; +/* number of items */ + +set I := 1..m; +/* set of items */ + +param w{i in 1..m}, > 0; +/* w[i] is weight of item i */ + +param c, > 0; +/* bin capacity */ + +/* We need to estimate an upper bound of the number of bins sufficient + to contain all items. The number of items m can be used, however, it + is not a good idea. To obtain a more suitable estimation an easy + heuristic is used: we put items into a bin while it is possible, and + if the bin is full, we use another bin. The number of bins used in + this way gives us a more appropriate estimation. */ + +param z{i in I, j in 1..m} := +/* z[i,j] = 1 if item i is in bin j, otherwise z[i,j] = 0 */ + + if i = 1 and j = 1 then 1 + /* put item 1 into bin 1 */ + + else if exists{jj in 1..j-1} z[i,jj] then 0 + /* if item i is already in some bin, do not put it into bin j */ + + else if sum{ii in 1..i-1} w[ii] * z[ii,j] + w[i] > c then 0 + /* if item i does not fit into bin j, do not put it into bin j */ + + else 1; + /* otherwise put item i into bin j */ + +check{i in I}: sum{j in 1..m} z[i,j] = 1; +/* each item must be exactly in one bin */ + +check{j in 1..m}: sum{i in I} w[i] * z[i,j] <= c; +/* no bin must be overflowed */ + +param n := sum{j in 1..m} if exists{i in I} z[i,j] then 1; +/* determine the number of bins used by the heuristic; obviously it is + an upper bound of the optimal solution */ + +display n; + +set J := 1..n; +/* set of bins */ + +var x{i in I, j in J}, binary; +/* x[i,j] = 1 means item i is in bin j */ + +var used{j in J}, binary; +/* used[j] = 1 means bin j contains at least one item */ + +s.t. one{i in I}: sum{j in J} x[i,j] = 1; +/* each item must be exactly in one bin */ + +s.t. lim{j in J}: sum{i in I} w[i] * x[i,j] <= c * used[j]; +/* if bin j is used, it must not be overflowed */ + +minimize obj: sum{j in J} used[j]; +/* objective is to minimize the number of bins used */ + +data; + +/* The optimal solution is 3 bins */ + +param m := 6; + +param w := 1 50, 2 60, 3 30, 4 70, 5 50, 6 40; + +param c := 100; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/cal.mod b/resources/3rdparty/glpk-4.57/examples/cal.mod new file mode 100644 index 000000000..2555182e0 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/cal.mod @@ -0,0 +1,49 @@ +/* cal.mod - print an ASCII calendar of the given year */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +param year, integer, >= 0001, <= 3999, default 2010; + +param first_day{m in 1..12}, integer, >= 0, <= 6, := + time2str(str2time(year & "-" & m & "-01", "%Y-%m-%d"), "%w"); + +param days_in_month{m in 1..12}, integer, >= 28, <= 31, := + (str2time(year + (if m < 12 then 0 else 1) & "-" & + (if m < 12 then m+1 else 1) & "-01", "%Y-%m-%d") - + str2time(year & "-" & m & "-01", "%Y-%m-%d")) / 86400; + +param foo{m in 1..12, k in 0..5, d in 0..6}, integer, := + 7 * k + d + 1 - first_day[m]; + +param cal{m in 1..12, k in 0..5, d in 0..6}, integer, := + if 1 <= foo[m,k,d] and foo[m,k,d] <= days_in_month[m] then + foo[m,k,d]; + +printf "\n"; +printf "%33s%04d\n", "", year; +printf "\n"; +for {t in 1..12 by 3} +{ for {m in t..t+2} + { printf "%7s%-14s", "", time2str(str2time(m, "%m"), "%B"); + printf{0..0: m < t+2} " "; + } + printf "\n"; + for {m in t..t+2} + { printf " S M Tu W Th F S"; + printf{0..0: m < t+2} " "; + } + printf "\n"; + for {k in 0..5} + { for {m in t..t+2} + { for {d in 0..6} + { printf{0..0: cal[m,k,d] = 0} " "; + printf{0..0: cal[m,k,d] != 0} " %2d", cal[m,k,d]; + } + printf{0..0: m < t+2} " "; + } + printf "\n"; + } +} +printf "\n"; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/cf12a.mod b/resources/3rdparty/glpk-4.57/examples/cf12a.mod new file mode 100644 index 000000000..61a76c050 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/cf12a.mod @@ -0,0 +1,81 @@ +/* + + Curve fitting problem 12.11(a) H P Williams "Model Building in Mathematical Programming" + + Dr. H J Mackenzie + HARD software + hjm@hardsoftware.com + + 2006-01-05 + + */ + +# set of points + +set I; + +# independent variable + +param x {i in I}; + +# dependent variable + +param y {i in I}; + +# output input values + +printf {i in I} "x = %.1f; y = %.1f\n", x[i], y[i]; + +# define equation variables + +var a; + +var b; + +var u {i in I}, >= 0; + +var v {i in I}, >= 0; + +# define objective function + +minimize error: sum {i in I} u[i] + sum {i in I} v[i]; + +# define equation constraint + +s.t. equation {i in I} : b * x[i] + a + u[i] - v[i] = y[i]; + +solve; + +printf "y = %.4fx + %.4f\n", b, a; + +/* + * + * DATA section + * + */ + +data; + +param : I : x y := + 1 0 1 + 2 0.5 0.9 + 3 1 0.7 + 4 1.5 1.5 + 5 1.9 2 + 6 2.5 2.4 + 7 3 3.2 + 8 3.5 2 + 9 4 2.7 + 10 4.5 3.5 + 11 5 1 + 12 5.5 4 + 13 6 3.6 + 14 6.6 2.7 + 15 7 5.7 + 16 7.6 4.6 + 17 8.5 6 + 18 9 6.8 + 19 10 7.3 +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/cf12b.mod b/resources/3rdparty/glpk-4.57/examples/cf12b.mod new file mode 100644 index 000000000..56f1ba106 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/cf12b.mod @@ -0,0 +1,88 @@ +/* + + Curve fitting problem 12.11(b) H P Williams "Model Building in Mathematical Programming" + + Dr. H J Mackenzie + HARD software + hjm@hardsoftware.com + + 2006-01-23 + + */ + +# set of points + +set I; + +# independent variable + +param x {i in I}; + +# dependent variable + +param y {i in I}; + +# output input values + +printf {i in I} "x = %.1f; y = %.1f\n", x[i], y[i]; + +# define equation variables + +var a; + +var b; + +var u {i in I}, >= 0; + +var v {i in I}, >= 0; + +var z; + +# define objective function + +minimize deviation: z; + +# define equation constraint + +s.t. equation {i in I} : b * x[i] + a + u[i] - v[i] = y[i]; + +# define deviation constrains + +s.t. u_deviation {i in I} : z - u[i] >= 0; +s.t. v_deviation {i in I} : z - v[i] >= 0; + +solve; + +printf "y = %.4fx + %.4f Max deviation = %.4f\n", b, a, z; + +/* + * + * DATA section + * + */ + +data; + +param : I : x y := + 1 0 1 + 2 0.5 0.9 + 3 1 0.7 + 4 1.5 1.5 + 5 1.9 2 + 6 2.5 2.4 + 7 3 3.2 + 8 3.5 2 + 9 4 2.7 + 10 4.5 3.5 + 11 5 1 + 12 5.5 4 + 13 6 3.6 + 14 6.6 2.7 + 15 7 5.7 + 16 7.6 4.6 + 17 8.5 6 + 18 9 6.8 + 19 10 7.3 +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/cflsq.mod b/resources/3rdparty/glpk-4.57/examples/cflsq.mod new file mode 100644 index 000000000..4af4d029b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/cflsq.mod @@ -0,0 +1,51 @@ +/*Curve fitting problem by Least Squares + Nigel_Galloway@operamail.com + October 1st., 2007 +*/ +set Sample; +param Sx {z in Sample}; +param Sy {z in Sample}; + +var X; +var Y; +var Ex{z in Sample}; +var Ey{z in Sample}; + +/* sum of variances is zero for Sx*/ +variencesX{z in Sample}: X + Ex[z] = Sx[z]; +zumVariancesX: sum{z in Sample} Ex[z] = 0; +/* sum of variances is zero for Sy*/ +variencesY{z in Sample}: Y + Ey[z] = Sy[z]; +zumVariancesY: sum{z in Sample} Ey[z] = 0; + +solve; + +param b1 := (sum{z in Sample} Ex[z]*Ey[z])/(sum{z in Sample} Ex[z]*Ex[z]); +printf "\nbest linear fit is:\n\ty = %f %s %fx\n\n", Y-b1*X, if b1 < 0 then "-" else "+", abs(b1); + +data; + +param: +Sample: Sx Sy := + 1 0 1 + 2 0.5 0.9 + 3 1 0.7 + 4 1.5 1.5 + 5 1.9 2 + 6 2.5 2.4 + 7 3 3.2 + 8 3.5 2 + 9 4 2.7 + 10 4.5 3.5 + 11 5 1 + 12 5.5 4 + 13 6 3.6 + 14 6.6 2.7 + 15 7 5.7 + 16 7.6 4.6 + 17 8.5 6 + 18 9 6.8 + 19 10 7.3 +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/color.mod b/resources/3rdparty/glpk-4.57/examples/color.mod new file mode 100644 index 000000000..9a279c387 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/color.mod @@ -0,0 +1,113 @@ +/* COLOR, Graph Coloring Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* Given an undirected loopless graph G = (V, E), where V is a set of + nodes, E <= V x V is a set of arcs, the Graph Coloring Problem is to + find a mapping (coloring) F: V -> C, where C = {1, 2, ... } is a set + of colors whose cardinality is as small as possible, such that + F(i) != F(j) for every arc (i,j) in E, that is adjacent nodes must + be assigned different colors. */ + +param n, integer, >= 2; +/* number of nodes */ + +set V := {1..n}; +/* set of nodes */ + +set E, within V cross V; +/* set of arcs */ + +check{(i,j) in E}: i != j; +/* there must be no loops */ + +/* We need to estimate an upper bound of the number of colors |C|. + The number of nodes |V| can be used, however, for sparse graphs such + bound is not very good. To obtain a more suitable estimation we use + an easy "greedy" heuristic. Let nodes 1, ..., i-1 are already + assigned some colors. To assign a color to node i we see if there is + an existing color not used for coloring nodes adjacent to node i. If + so, we use this color, otherwise we introduce a new color. */ + +set EE := setof{(i,j) in E} (i,j) union setof{(i,j) in E} (j,i); +/* symmetrisized set of arcs */ + +param z{i in V, case in 0..1} := +/* z[i,0] = color index assigned to node i + z[i,1] = maximal color index used for nodes 1, 2, ..., i-1 which are + adjacent to node i */ +( if case = 0 then + ( /* compute z[i,0] */ + min{c in 1..z[i,1]} + ( if not exists{j in V: j < i and (i,j) in EE} z[j,0] = c then + c + else + z[i,1] + 1 + ) + ) + else + ( /* compute z[i,1] */ + if not exists{j in V: j < i} (i,j) in EE then + 1 + else + max{j in V: j < i and (i,j) in EE} z[j,0] + ) +); + +check{(i,j) in E}: z[i,0] != z[j,0]; +/* check that all adjacent nodes are assigned distinct colors */ + +param nc := max{i in V} z[i,0]; +/* number of colors used by the heuristic; obviously, it is an upper + bound of the optimal solution */ + +display nc; + +var x{i in V, c in 1..nc}, binary; +/* x[i,c] = 1 means that node i is assigned color c */ + +var u{c in 1..nc}, binary; +/* u[c] = 1 means that color c is used, i.e. assigned to some node */ + +s.t. map{i in V}: sum{c in 1..nc} x[i,c] = 1; +/* each node must be assigned exactly one color */ + +s.t. arc{(i,j) in E, c in 1..nc}: x[i,c] + x[j,c] <= u[c]; +/* adjacent nodes cannot be assigned the same color */ + +minimize obj: sum{c in 1..nc} u[c]; +/* objective is to minimize the number of colors used */ + +data; + +/* These data correspond to the instance myciel3.col from: + http://mat.gsia.cmu.edu/COLOR/instances.html */ + +/* The optimal solution is 4 */ + +param n := 11; + +set E := + 1 2 + 1 4 + 1 7 + 1 9 + 2 3 + 2 6 + 2 8 + 3 5 + 3 7 + 3 10 + 4 5 + 4 6 + 4 10 + 5 8 + 5 9 + 6 11 + 7 11 + 8 11 + 9 11 + 10 11 +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/cplex/README b/resources/3rdparty/glpk-4.57/examples/cplex/README new file mode 100644 index 000000000..38bb8b4d3 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/cplex/README @@ -0,0 +1,44 @@ +The program module in this subdirectory is a crude implementation of +CPLEX-like interface to GLPK API. It consists of two files: cplex.c and +cplex.h. + +NOTE that this module is NOT a clean room implementation of the CPLEX +callable library. It only implements a CPLEX-like interface to the GLPK +API routines, and its main purpose is to provide possibility to build +and run applications which normally use the CPLEX callable library. + +This module approximately corresponds to CPLEX 9.0. + +Currently this module can be used as a linear programming solver for +Concorde, the state-of-the-art computer code for solving the symmetric +traveling salesman problem (TSP) developed by David Applegate, Robert +Bixby, Vasek Chvatal, and William Cook. For details about Concorde see +its web page at http://www.tsp.gatech.edu/concorde.html. + +To build Concorde along with GLPK you need to do the following: + +1. Configure, build, and install GLPK. + +2. Download the Concorde tarball co031219.tgz (version Dec 19, 2003), + unpack and unarchive it. + +3. Copy files cplex.h and cplex.c to subdirectory concorde/LP/. + +4. Create file named lpglpk.c in subdirectory concorde/LP/. This file + must contain the following two lines: + + #include "cplex.c" + #include "lpcplex8.c" + +5. Configure Concorde in usual way (./configure) and then build it with + the following command: + + make CPPFLAGS=-I. LPSOLVER_INTERFACE=lpglpk.c LPSOLVER_LIB=-lglpk + + The Concorde executable can be found in subdirectory concorde/TSP/. + +Please note that currently this GLPK interface module does not support +some important features (namely, CPXgetijdiv, CPXmdleave, CPXpivotin, +CPXpivotout, and CPXstrongbranch), so large (more than 1000 nodes) TSP +instances cannot be solved in a reasonable time, and some instances may +cause abnormal termination of Concorde (if CPXgetijdiv is called). diff --git a/resources/3rdparty/glpk-4.57/examples/cplex/concorde.txt b/resources/3rdparty/glpk-4.57/examples/cplex/concorde.txt new file mode 100644 index 000000000..c6f7aec9b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/cplex/concorde.txt @@ -0,0 +1,121 @@ +Solver: Concorde-03.12.19 (options used: -s 99) + http://www.tsp.gatech.edu/concorde.html +LP Solver: GLPK 4.34 (CPLEX-like interface module examples/cplex) +Computer: Intel Pentium 4 CPU 3GHz, 2GB of RAM +Platform: Cygwin 1.5.24 (Windows XP 5.1 Build 2600 Service Pack 4) +Compiler: GCC 3.4.4 (options used: -O2) +Test set: http://www.iwr.uni-heidelberg.de/groups/comopt/software/ + TSPLIB95/ + +Problem Solution B&B Time, s +--------- -------- --- ------- +a280 2579 1 3.09 +ali535 202339 1 21.88 +att48 10628 1 0.20 +att532 27686 7 74.31 +bayg29 1610 1 0.08 +bays29 2020 1 0.08 +berlin52 7542 1 0.11 +bier127 118282 1 0.62 +brazil58 25395 1 0.23 +brd14051 +brg180 1950 1 0.34 +burma14 3323 1 0.06 +ch130 6110 1 0.92 +ch150 6528 1 1.69 +d1291 +d15112 +d1655 +d18512 +d198 15780 3 4.92 +d2103 +d493 35002 5 123.89 +d657 48913 11 148.17 +dantzig42 699 1 0.08 +dsj1000 18660188 13 251.00 +eil101 (failed due to CPXgetijdiv) +eil51 426 1 0.17 +eil76 538 1 0.11 +fl1400 +fl1577 +fl3795 +fl417 11861 1 47.20 +fnl4461 +fri26 937 1 0.05 +gil262 2378 3 10.39 +gr120 6942 1 0.66 +gr137 69853 1 2.09 +gr17 2085 1 0.03 +gr202 40160 1 3.97 +gr21 2707 1 0.03 +gr229 134602 7 19.45 +gr24 1272 1 0.03 +gr431 171414 9 40.67 +gr48 5046 1 0.22 +gr666 294358 3 40.23 +gr96 55209 1 1.22 +hk48 11461 1 0.08 +kroA100 21282 1 0.41 +kroA150 26524 1 2.09 +kroA200 29368 1 2.44 +kroB100 22141 1 1.20 +kroB150 26130 1 1.66 +kroB200 29437 1 1.41 +kroC100 20749 1 0.42 +kroD100 21294 1 0.50 +kroE100 22068 1 0.94 +lin105 14379 1 0.23 +lin318 42029 1 4.28 +nrw1379 +p654 34643 1 17.08 +pa561 2763 15 370.70 +pcb1173 56892 11 370.30 +pcb3038 +pcb442 59778 13 35.86 +pla33810 +pla7397 +pla85900 +pr1002 259045 1 23.08 +pr107 44303 1 0.38 +pr124 59030 1 1.23 +pr136 96772 1 2.19 +pr144 58537 1 0.89 +pr152 73682 1 2.73 +pr226 80369 1 2.72 +pr2392 +pr264 49135 1 1.61 +pr299 48191 3 14.52 +pr439 107217 15 117.75 +pr76 108159 1 0.95 +rat195 2323 5 12.91 +rat575 6773 19 202.52 +rat783 8806 1 37.92 +rat99 1211 1 0.50 +rd100 7910 1 0.28 +rd400 15281 11 74.41 +rl11849 +rl1304 +rl1323 +rl1889 +rl5915 +rl5934 +si1032 92650 1 82.09 +si175 21407 3 8.97 +si535 48450 1 71.28 +st70 675 1 0.20 +swiss42 1273 1 0.06 +ts225 126643 1 21.25 +tsp225 3916 1 10.14 +u1060 224094 13 507.44 +u1432 +u159 42080 1 0.41 +u1817 +u2152 +u2319 +u574 36905 1 32.84 +u724 41910 19 238.42 +ulysses16 6859 1 0.19 +ulysses22 7013 1 0.47 +usa13509 +vm1084 239297 9 543.38 +vm1748 diff --git a/resources/3rdparty/glpk-4.57/examples/cplex/cplex.c b/resources/3rdparty/glpk-4.57/examples/cplex/cplex.c new file mode 100644 index 000000000..ef9e2dffe --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/cplex/cplex.c @@ -0,0 +1,2130 @@ +/* cplex.c (CPLEX-like interface to GLPK API) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "cplex.h" + +struct CPXENV +{ /* environment block */ + CPXLP *list; + /* linked list of problem objects */ + int *intparam; /* int intparam[]; */ + /* integer control parameters */ + double *dblparam; /* double dblparam[]; */ + /* floating-point control parameters */ +}; + +struct CPXLP +{ /* problem object */ + CPXENV *env; + /* pointer to environment block */ + glp_prob *prob; + /* pointer to underlying GLPK problem object */ + int rflen; + /* length of the array rflag */ + char *rflag; /* char rflag[rflen]; */ + /* rflag[i], i = 0,...,nrows-1, is a flag of i-th row: */ +#define RF_NOT_RANGED 0 /* not ranged */ +#define RF_RANGED_POS 1 /* ranged, RHS = lower bound */ +#define RF_RANGED_NEG 2 /* ranged, RHS = upper bound */ + int stat; + /* solution status reported by CPXgetstat; zero means no solution + exists */ + int meth; + /* method indicator reported by CPXgetmethod */ + int iwlen; + /* length of the working array */ + int *iwork; /* int iwork[iwlen] */ + /* working array initialized by binary zeros */ + CPXLP *link; + /* pointer to another problem object */ +}; + +struct intparam +{ int which; + int defv; + int minv; + int maxv; +}; + +struct dblparam +{ int which; + double defv; + double minv; + double maxv; +}; + +struct errstring +{ int code; + const char *string; +}; + +#define BIGINT 2100000000 +#define BIGDBL 1e75 + +static const struct intparam intparam[] = +{ {CPX_PARAM_ADVIND, 0, 0, 2}, + {CPX_PARAM_AGGIND, -1, -1, BIGINT}, + {CPX_PARAM_DATACHECK, CPX_OFF, CPX_OFF, CPX_ON}, + {CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO, CPX_DPRIIND_AUTO, + CPX_DPRIIND_DEVEX}, + {CPX_PARAM_FASTMIP, CPX_OFF, CPX_OFF, CPX_ON}, /* ??? */ + {CPX_PARAM_ITLIM, BIGINT, 0, BIGINT}, + {CPX_PARAM_PERIND, CPX_OFF, CPX_OFF, CPX_ON}, + {CPX_PARAM_PPRIIND, CPX_PPRIIND_AUTO, CPX_PPRIIND_PARTIAL, + CPX_PPRIIND_FULL}, + {CPX_PARAM_PREIND, CPX_ON, CPX_OFF, CPX_ON}, + {CPX_PARAM_REINV, 0, 0, 10000}, + {CPX_PARAM_SCRIND, CPX_OFF, CPX_OFF, CPX_ON}, + {CPX_PARAM_SIMDISPLAY, 1, 0, 2}, +}; + +static const struct dblparam dblparam[] = +{ {CPX_PARAM_EPOPT, 1e-6, 1e-9, 1e-1}, + {CPX_PARAM_EPPER, 1e-6, 1e-8, BIGDBL}, + {CPX_PARAM_EPRHS, 1e-6, 1e-9, 1e-1}, + {CPX_PARAM_OBJLLIM, -BIGDBL, -BIGDBL, +BIGDBL}, + {CPX_PARAM_OBJULIM, +BIGDBL, -BIGDBL, +BIGDBL}, +}; + +static const struct errstring errstring[] = +{ {CPXERR_ARRAY_NOT_ASCENDING, "Array entry %d not ascending"}, + {CPXERR_BAD_ARGUMENT, "Invalid argument"}, + {CPXERR_BAD_CTYPE, "Invalid ctype entry %d"}, + {CPXERR_BAD_FILETYPE, "Invalid filetype"}, + {CPXERR_BAD_LUB, "Invalid bound change indicator entry %d"}, + {CPXERR_BAD_PARAM_NUM, "Invalid parameter number"}, + {CPXERR_BAD_SENSE, "Invalid sense entry %d"}, + {CPXERR_BAD_STATUS, "Invalid status entry %d for basis specificat" + "ion"}, + {CPXERR_COL_INDEX_RANGE, "Column index %d out of range"}, + {CPXERR_COUNT_RANGE, "Count entry %d negative or larger than allo" + "wed"}, + {CPXERR_DUP_ENTRY, "Duplicate entry"}, + {CPXERR_FAIL_OPEN_WRITE, "Could not open file '%s' for writing"}, + {CPXERR_INDEX_RANGE, "Index is outside range of valid values"}, + {CPXERR_NEGATIVE_SURPLUS, "Insufficient array length"}, + {CPXERR_NO_BASIC_SOLN, "No basic solution exists"}, + {CPXERR_NO_ENVIRONMENT, "No environment exists"}, + {CPXERR_NO_FILENAME, "File name not specified"}, + {CPXERR_NO_MEMORY, "Out of memory"}, + {CPXERR_NO_PROBLEM, "No problem exists"}, + {CPXERR_NO_SOLN, "No solution exists"}, + {CPXERR_NOT_FIXED, "Only fixed variables are pivoted out"}, + {CPXERR_NULL_NAME, "Null pointer %d in name array"}, + {CPXERR_NULL_POINTER, "Null pointer for required data"}, + {CPXERR_PARAM_TOO_BIG, "Parameter value too big"}, + {CPXERR_PARAM_TOO_SMALL, "Parameter value too small"}, + {CPXERR_ROW_INDEX_RANGE, "Row index %d out of range"}, +}; + +/**********************************************************************/ + +#define xassert glp_assert +#define xprintf glp_printf +#define xmalloc glp_malloc +#define xcalloc glp_calloc +#define xfree glp_free + +/**********************************************************************/ + +static int findintparam(int whichparam) +{ int k, card; + card = sizeof(intparam) / sizeof(struct intparam); + for (k = 0; k < card; k++) + if (intparam[k].which == whichparam) return k; + return -1; +} + +static int getintparam(CPXENV *env, int whichparam) +{ int k; + xassert(env != NULL); + k = findintparam(whichparam); + xassert(k >= 0); + return env->intparam[k]; +} + +static int finddblparam(int whichparam) +{ int k, card; + card = sizeof(dblparam) / sizeof(struct dblparam); + for (k = 0; k < card; k++) + if (dblparam[k].which == whichparam) return k; + return -1; +} + +static double getdblparam(CPXENV *env, int whichparam) +{ int k; + xassert(env != NULL); + k = finddblparam(whichparam); + xassert(k >= 0); + return env->dblparam[k]; +} + +static const char *finderrstring(int errcode) +{ int k, card; + card = sizeof(errstring) / sizeof(struct errstring); + for (k = 0; k < card; k++) + { if (errstring[k].code == errcode) + return errstring[k].string; + } + return NULL; +} + +static int error(CPXENV *env, int errcode, ...) +{ va_list arg; + char buffer[510]; + xassert(env != NULL); + if (getintparam(env, CPX_PARAM_SCRIND) == CPX_ON) + { xassert(CPXgeterrorstring(env, errcode, buffer) == buffer); + va_start(arg, errcode); + vprintf(buffer, arg); + va_end(arg); + } + return errcode; +} + +static int checkenv(CPXENV *env) +{ int errcode; + if (env == NULL) + errcode = CPXERR_NO_ENVIRONMENT; + else + errcode = 0; + return errcode; +} + +static checklp(CPXENV *env, CPXLP *lp) +{ int errcode; + errcode = checkenv(env); + if (errcode) goto done; + if (lp == NULL) + errcode = error(env, CPXERR_NO_PROBLEM); +done: return errcode; +} + +static void invalidate(CPXLP *lp) +{ lp->stat = 0; + lp->meth = CPX_ALG_NONE; + return; +} + +static void enlargerflag(CPXLP *lp) +{ int m; + xassert(lp != NULL); + m = glp_get_num_rows(lp->prob); + if (lp->rflen < m) + { int rflen = lp->rflen; + char *rflag = lp->rflag; + while (lp->rflen < m) + { lp->rflen += lp->rflen; + xassert(lp->rflen > 0); + } + lp->rflag = xcalloc(lp->rflen, sizeof(char)); + memcpy(lp->rflag, rflag, rflen); + xfree(rflag); + } + return; +} + +static void enlargeiwork(CPXLP *lp, int len) +{ xassert(len >= 0); + if (lp->iwlen < len) + { xfree(lp->iwork); + while (lp->iwlen < len) + { lp->iwlen += lp->iwlen; + xassert(lp->iwlen > 0); + } + lp->iwork = xcalloc(lp->iwlen, sizeof(int)); + memset(lp->iwork, 0, lp->iwlen * sizeof(int)); + } + return; +} + +/**********************************************************************/ + +int CPXaddcols(CPXENV *env, CPXLP *lp, int ccnt, int nzcnt, + const double obj[], const int cmatbeg[], const int cmatind[], + const double cmatval[], const double lb[], const double ub[], + char *colname[]) +{ int j, k, m, n, beg, end, type, errcode; + double lbnd, ubnd; + errcode = checklp(env, lp); + if (errcode) goto done; + if (ccnt < 0 || nzcnt < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (ccnt > 0) + { if (cmatbeg == NULL || cmatind == NULL || cmatval == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + } + m = glp_get_num_rows(lp->prob); + n = glp_get_num_cols(lp->prob); + enlargeiwork(lp, m); + for (j = 0; j < ccnt; j++) + { beg = cmatbeg[j]; + if (j > 0 && !(cmatbeg[j-1] <= beg)) + { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, j); + goto done; + } + if (!(0 <= beg && beg <= nzcnt)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + end = (j < ccnt-1 ? cmatbeg[j+1] : nzcnt); + for (k = beg; k < end; k++) + { if (!(0 <= cmatind[k] && cmatind[k] < m)) + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, k); + goto done; + } + } + errcode = 0; + for (k = beg; k < end; k++) + { if (lp->iwork[cmatind[k]]) + { errcode = error(env, CPXERR_DUP_ENTRY); + break; + } + lp->iwork[cmatind[k]] = 1; + } + for (k = beg; k < end; k++) + lp->iwork[cmatind[k]] = 0; + if (errcode) goto done; + if (colname != NULL) + { if (colname[j] == NULL) + { errcode = error(env, CPXERR_NULL_NAME, j); + goto done; + } + } + } + errcode = 0; + invalidate(lp); + if (ccnt > 0) + glp_add_cols(lp->prob, ccnt); + for (j = 0; j < ccnt; j++) + { if (colname != NULL) + glp_set_col_name(lp->prob, n+j+1, colname[j]); + lbnd = (lb == NULL ? 0.0 : lb[j]); + ubnd = (ub == NULL ? +CPX_INFBOUND : ub[j]); + if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) + type = GLP_FR; + else if (ubnd >= +CPX_INFBOUND) + type = GLP_LO; + else if (lbnd <= -CPX_INFBOUND) + type = GLP_UP; + else if (lbnd != ubnd) + type = GLP_DB; + else + type = GLP_FX; + glp_set_col_bnds(lp->prob, n+j+1, type, lbnd, ubnd); + if (obj != NULL) + glp_set_obj_coef(lp->prob, n+j+1, obj[j]); + beg = cmatbeg[j]; + end = (j < ccnt-1 ? cmatbeg[j+1] : nzcnt); + for (k = beg; k < end; k++) + lp->iwork[k-beg] = cmatind[k]+1; + glp_set_mat_col(lp->prob, n+j+1, end-beg, lp->iwork-1, + cmatval+beg-1); + for (k = beg; k < end; k++) + lp->iwork[k-beg] = 0; + } +done: return errcode; +} + +int CPXaddrows(CPXENV *env, CPXLP *lp, int ccnt, int rcnt, int nzcnt, + const double rhs[], const char sense[], const int rmatbeg[], + const int rmatind[], const double rmatval[], char *colname[], + char *rowname[]) +{ int i, j, k, m, n, beg, end, type, errcode; + double temp; + errcode = checklp(env, lp); + if (errcode) goto done; + if (ccnt < 0 || rcnt < 0 || nzcnt < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (rcnt > 0) + { if (rmatbeg == NULL || rmatind == NULL || rmatval == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + } + m = glp_get_num_rows(lp->prob); + n = glp_get_num_cols(lp->prob); + enlargeiwork(lp, n+ccnt); + for (i = 0; i < rcnt; i++) + { if (sense != NULL) + { if (!(sense[i] == 'L' || sense[i] == 'E' || + sense[i] == 'G' || sense[i] == 'R')) + { errcode = error(env, CPXERR_BAD_SENSE, i); + goto done; + } + } + beg = rmatbeg[i]; + if (i > 0 && !(rmatbeg[i-1] <= beg)) + { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, i); + goto done; + } + if (!(0 <= beg && beg <= nzcnt)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + end = (i < rcnt-1 ? rmatbeg[i+1] : nzcnt); + for (k = beg; k < end; k++) + { if (!(0 <= rmatind[k] && rmatind[k] < n+ccnt)) + { errcode = error(env, CPXERR_COL_INDEX_RANGE, k); + goto done; + } + } + errcode = 0; + for (k = beg; k < end; k++) + { if (lp->iwork[rmatind[k]]) + { errcode = error(env, CPXERR_DUP_ENTRY); + break; + } + lp->iwork[rmatind[k]] = 1; + } + for (k = beg; k < end; k++) + lp->iwork[rmatind[k]] = 0; + if (errcode) goto done; + if (rowname != NULL) + { if (rowname[i] == NULL) + { errcode = error(env, CPXERR_NULL_NAME, i); + goto done; + } + } + } + for (j = 0; j < ccnt; j++) + { if (colname != NULL) + { if (colname[j] == NULL) + { errcode = error(env, CPXERR_NULL_NAME, j); + goto done; + } + } + } + errcode = 0; + invalidate(lp); + if (rcnt > 0) + glp_add_rows(lp->prob, rcnt); + if (ccnt > 0) + glp_add_cols(lp->prob, ccnt); + enlargerflag(lp); + for (i = 0; i < rcnt; i++) + { if (rowname != NULL) + glp_set_row_name(lp->prob, m+i+1, rowname[i]); + temp = (rhs == NULL ? 0.0 : rhs[i]); + if (sense == NULL || sense[i] == 'E') + { lp->rflag[m+i] = RF_NOT_RANGED; + type = GLP_FX; + } + else if (sense[i] == 'L') + { lp->rflag[m+i] = RF_NOT_RANGED; + type = GLP_UP; + } + else if (sense[i] == 'G') + { lp->rflag[m+i] = RF_NOT_RANGED; + type = GLP_LO; + } + else if (sense[i] == 'R') + { lp->rflag[m+i] = RF_RANGED_POS; + type = GLP_FX; + } + else + xassert(sense != sense); + glp_set_row_bnds(lp->prob, m+i+1, type, temp, temp); + beg = rmatbeg[i]; + end = (i < rcnt-1 ? rmatbeg[i+1] : nzcnt); + for (k = beg; k < end; k++) + lp->iwork[k-beg] = rmatind[k]+1; + glp_set_mat_row(lp->prob, m+i+1, end-beg, lp->iwork-1, + rmatval+beg-1); + for (k = beg; k < end; k++) + lp->iwork[k-beg] = 0; + } + for (j = 0; j < ccnt; j++) + { if (colname != NULL) + glp_set_col_name(lp->prob, n+j+1, colname[j]); + glp_set_col_bnds(lp->prob, n+j+1, GLP_LO, 0.0, 0.0); + } +done: return errcode; +} + +int CPXbaropt(CPXENV *env, CPXLP *lp) +{ xassert(env == env); + xassert(lp == lp); + xprintf("CPXbaropt: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXbinvrow(CPXENV *env, CPXLP *lp, int i, double y[]) +{ xassert(env == env); + xassert(lp == lp); + xassert(i == i); + xassert(y == y); + xprintf("CPXbinvrow: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXchgbds(CPXENV *env, CPXLP *lp, int cnt, const int indices[], + const char lu[], const double bd[]) +{ int j, n, type, errcode; + double lbnd, ubnd; + errcode = checklp(env, lp); + if (errcode) goto done; + if (cnt < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (cnt > 0) + { if (indices == NULL || lu == NULL || bd == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + } + n = glp_get_num_cols(lp->prob); + for (j = 0; j < cnt; j++) + { if (!(0 <= indices[j] && indices[j] < n)) + { errcode = error(env, CPXERR_COL_INDEX_RANGE, j); + goto done; + } + if (!(lu[j] == 'L' || lu[j] == 'U' || lu[j] == 'B')) + { errcode = error(env, CPXERR_BAD_LUB, j); + goto done; + } + } + errcode = 0; + invalidate(lp); + for (j = 0; j < cnt; j++) + { type = glp_get_col_type(lp->prob, indices[j]+1); + lbnd = glp_get_col_lb(lp->prob, indices[j]+1); + ubnd = glp_get_col_ub(lp->prob, indices[j]+1); + if (type == GLP_FR || type == GLP_UP) + lbnd = -CPX_INFBOUND; + if (type == GLP_FR || type == GLP_LO) + ubnd = +CPX_INFBOUND; + if (lu[j] == 'L') + lbnd = bd[j]; + else if (lu[j] == 'U') + ubnd = bd[j]; + else if (lu[j] == 'B') + lbnd = ubnd = bd[j]; + else + xassert(lu != lu); + if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) + type = GLP_FR; + else if (ubnd >= +CPX_INFBOUND) + type = GLP_LO; + else if (lbnd <= -CPX_INFBOUND) + type = GLP_UP; + else if (lbnd != ubnd) + type = GLP_DB; + else + type = GLP_FX; + glp_set_col_bnds(lp->prob, indices[j]+1, type, lbnd, ubnd); + } +done: return errcode; +} + +int CPXchgcoeflist(CPXENV *env, CPXLP *lp, int numcoefs, + const int rowlist[], const int collist[], const double vallist[]) +{ int i, j, k, m, n, rcnt, ccnt, len, ptr, errcode; + int *head, *next, *ind; + double *val; + errcode = checklp(env, lp); + if (errcode) goto done; + if (numcoefs < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (numcoefs == 0) + { errcode = 0; + goto done; + } + if (rowlist == NULL || collist == NULL || vallist == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + /* check triplets and determine the number of rows and columns + to be changed */ + m = glp_get_num_rows(lp->prob); + n = glp_get_num_cols(lp->prob); + enlargeiwork(lp, m); + enlargeiwork(lp, n); + rcnt = ccnt = 0; + for (k = 0; k < numcoefs; k++) + { i = rowlist[k]; + if (!(0 <= i && i < m)) + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i); + goto done; + } + if (!(lp->iwork[i] & 0x01)) + rcnt++, lp->iwork[i] |= 0x01; + j = collist[k]; + if (!(0 <= j && j < n)) + { errcode = error(env, CPXERR_COL_INDEX_RANGE, j); + goto done; + } + if (!(lp->iwork[j] & 0x02)) + ccnt++, lp->iwork[j] |= 0x02; + } + memset(lp->iwork, 0, m * sizeof(int)); + memset(lp->iwork, 0, n * sizeof(int)); + errcode = 0; + invalidate(lp); + if (rcnt <= ccnt) + { /* change the matrix by rows */ + /* build the linked list of triplets: + head[i] is a pointer to first triplet for row i + next[k] is a pointer to next triplet for the same row */ + head = xcalloc(m, sizeof(int)); + for (i = 0; i < m; i++) + head[i] = -1; + next = xcalloc(numcoefs, sizeof(int)); + for (k = 0; k < numcoefs; k++) + { i = rowlist[k]; + next[k] = head[i]; + head[i] = k; + } + /* check duplicate columns */ + for (i = 0; i < m; i++) + { for (k = head[i]; k >= 0; k = next[k]) + { j = collist[k]; + if (lp->iwork[j]) + { xfree(head); + xfree(next); + errcode = error(env, CPXERR_DUP_ENTRY); + goto done; + } + lp->iwork[j] = 1; + } + for (k = head[i]; k >= 0; k = next[k]) + lp->iwork[collist[k]] = 0; + } + /* perform operation */ + ind = xcalloc(1+n, sizeof(int)); + val = xcalloc(1+n, sizeof(double)); + for (i = 0; i < m; i++) + { if (head[i] < 0) continue; + len = glp_get_mat_row(lp->prob, i+1, ind, val); + for (ptr = 1; ptr <= len; ptr++) + { j = ind[ptr]-1; + xassert(lp->iwork[j] == 0); + lp->iwork[j] = ptr; + } + for (k = head[i]; k >= 0; k = next[k]) + { j = collist[k]; + if (lp->iwork[j] == 0) + lp->iwork[j] = ++len; + ptr = lp->iwork[j]; + ind[ptr] = j+1, val[ptr] = vallist[k]; + } + glp_set_mat_row(lp->prob, i+1, len, ind, val); + for (ptr = 1; ptr <= len; ptr++) + lp->iwork[ind[ptr]-1] = 0; + } + } + else + { /* change the matrix by columns */ + /* build the linked lists of triplets: + head[j] is a pointer to first triplet for column j + next[k] is a pointer to next triplet for the same column */ + head = xcalloc(n, sizeof(int)); + for (j = 0; j < n; j++) + head[j] = -1; + next = xcalloc(numcoefs, sizeof(int)); + for (k = 0; k < numcoefs; k++) + { j = collist[k]; + next[k] = head[j]; + head[j] = k; + } + /* check duplicate rows */ + for (j = 0; j < n; j++) + { for (k = head[j]; k >= 0; k = next[k]) + { i = rowlist[k]; + if (lp->iwork[i]) + { xfree(head); + xfree(next); + errcode = error(env, CPXERR_DUP_ENTRY); + goto done; + } + lp->iwork[i] = 1; + } + for (k = head[j]; k >= 0; k = next[k]) + lp->iwork[rowlist[k]] = 0; + } + /* perform operation */ + ind = xcalloc(1+m, sizeof(int)); + val = xcalloc(1+m, sizeof(double)); + for (j = 0; j < n; j++) + { if (head[j] < 0) continue; + len = glp_get_mat_col(lp->prob, j+1, ind, val); + for (ptr = 1; ptr <= len; ptr++) + { i = ind[ptr]-1; + xassert(lp->iwork[i] == 0); + lp->iwork[i] = ptr; + } + for (k = head[j]; k >= 0; k = next[k]) + { i = rowlist[k]; + if (lp->iwork[i] == 0) + lp->iwork[i] = ++len; + ptr = lp->iwork[i]; + ind[ptr] = i+1, val[ptr] = vallist[k]; + } + glp_set_mat_col(lp->prob, j+1, len, ind, val); + for (ptr = 1; ptr <= len; ptr++) + lp->iwork[ind[ptr]-1] = 0; + } + } + xfree(head); + xfree(next); + xfree(ind); + xfree(val); +done: return errcode; +} + +void CPXchgobjsen(CPXENV *env, CPXLP *lp, int maxormin) +{ int errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + if (!(maxormin == CPX_MIN || maxormin == CPX_MAX)) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + errcode = 0; + invalidate(lp); + if (maxormin == CPX_MIN) + glp_set_obj_dir(lp->prob, GLP_MIN); + else + glp_set_obj_dir(lp->prob, GLP_MAX); +done: xassert(errcode == errcode); + return; +} + +int CPXchgsense(CPXENV *env, CPXLP *lp, int cnt, const int indices[], + const char sense[]) +{ int i, m, type, errcode; + double rhs; + errcode = checklp(env, lp); + if (errcode) goto done; + if (cnt < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (cnt > 0 && (indices == NULL || sense == NULL)) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + m = glp_get_num_rows(lp->prob); + for (i = 0; i < cnt; i++) + { if (!(0 <= indices[i] && indices[i] < m)) + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i); + goto done; + } + if (!(sense[i] == 'L' || sense[i] == 'E' || sense[i] == 'G' || + sense[i] == 'R')) + { errcode = error(env, CPXERR_BAD_SENSE, i); + goto done; + } + } + errcode = 0; + invalidate(lp); + for (i = 0; i < cnt; i++) + { type = glp_get_row_type(lp->prob, indices[i]+1); + if (lp->rflag[indices[i]] == RF_NOT_RANGED) + { if (type == GLP_LO || type == GLP_FX) + rhs = glp_get_row_lb(lp->prob, indices[i]+1); + else if (type == GLP_UP) + rhs = glp_get_row_ub(lp->prob, indices[i]+1); + else + xassert(type != type); + } + else if (lp->rflag[indices[i]] == RF_RANGED_POS) + { xassert(type == GLP_DB || type == GLP_FX); + rhs = glp_get_row_lb(lp->prob, indices[i]+1); + } + else if (lp->rflag[indices[i]] == RF_RANGED_NEG) + { xassert(type == GLP_DB); + rhs = glp_get_row_ub(lp->prob, indices[i]+1); + } + else + xassert(lp != lp); + if (sense[i] == 'L') + { lp->rflag[indices[i]] = RF_NOT_RANGED; + type = GLP_UP; + } + else if (sense[i] == 'E') + { lp->rflag[indices[i]] = RF_NOT_RANGED; + type = GLP_FX; + } + else if (sense[i] == 'G') + { lp->rflag[indices[i]] = RF_NOT_RANGED; + type = GLP_LO; + } + else if (sense[i] == 'R') + { lp->rflag[indices[i]] = RF_RANGED_POS; + type = GLP_FX; + } + else + xassert(sense != sense); + glp_set_row_bnds(lp->prob, indices[i]+1, type, rhs, rhs); + } +done: return errcode; +} + +int CPXcloseCPLEX(CPXENV **_env) +{ CPXENV *env; + CPXLP *lp; + int errcode; + if (_env == NULL) + { errcode = CPXERR_NULL_POINTER; + goto done; + } + env = *_env; + errcode = checkenv(env); + if (errcode) goto done; + while (env->list != NULL) + { lp = env->list; + errcode = CPXfreeprob(env, &lp); + xassert(!errcode); + } + xfree(env->intparam); + xfree(env->dblparam); + xfree(env); + *_env = NULL; + errcode = 0; +done: return errcode; +} + +int CPXcopybase(CPXENV *env, CPXLP *lp, const int cstat[], + const int rstat[]) +{ int i, j, m, n, stat, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + m = glp_get_num_rows(lp->prob); + n = glp_get_num_cols(lp->prob); + if (m > 0 && rstat == NULL || n > 0 && cstat == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + for (i = 0; i < m; i++) + { if (!(rstat[i] == CPX_AT_LOWER || rstat[i] == CPX_BASIC || + rstat[i] == CPX_AT_UPPER)) + { errcode = error(env, CPXERR_BAD_STATUS, i); + goto done; + } + } + for (j = 0; j < n; j++) + { if (!(cstat[j] == CPX_AT_LOWER || cstat[j] == CPX_BASIC || + cstat[j] == CPX_AT_UPPER || cstat[j] == CPX_FREE_SUPER)) + { errcode = error(env, CPXERR_BAD_STATUS, j); + goto done; + } + } + errcode = 0; + invalidate(lp); + for (i = 0; i < m; i++) + { if (rstat[i] == CPX_AT_LOWER) + stat = GLP_NL; + else if (rstat[i] == CPX_BASIC) + stat = GLP_BS; + else if (rstat[i] == CPX_AT_UPPER) + stat = GLP_NU; + else + xassert(rstat != rstat); + glp_set_row_stat(lp->prob, i+1, stat); + } + for (j = 0; j < n; j++) + { if (cstat[j] == CPX_AT_LOWER) + stat = GLP_NL; + else if (cstat[j] == CPX_BASIC) + stat = GLP_BS; + else if (cstat[j] == CPX_AT_UPPER) + stat = GLP_NU; + else if (cstat[j] == CPX_FREE_SUPER) + stat = GLP_NF; + else + xassert(cstat != cstat); + glp_set_col_stat(lp->prob, j+1, stat); + } +done: return errcode; +} + +int CPXcopybasednorms(CPXENV *env, CPXLP *lp, const int cstat[], + const int rstat[], const double dnorm[]) +{ int errcode; + errcode = CPXcopybase(env, lp, cstat, rstat); + xassert(dnorm == dnorm); + return errcode; +} + +int CPXcopylp(CPXENV *env, CPXLP *lp, int numcols, int numrows, + int objsen, const double obj[], const double rhs[], + const char sense[], const int matbeg[], const int matcnt[], + const int matind[], const double matval[], const double lb[], + const double ub[], const double rngval[]) +{ int errcode; + errcode = CPXcopylpwnames(env, lp, numcols, numrows, objsen, obj, + rhs, sense, matbeg, matcnt, matind, matval, lb, ub, rngval, + NULL, NULL); + return errcode; +} + +int CPXcopylpwnames(CPXENV *env, CPXLP *lp, int numcols, int numrows, + int objsen, const double obj[], const double rhs[], + const char sense[], const int matbeg[], const int matcnt[], + const int matind[], const double matval[], const double lb[], + const double ub[], const double rngval[], char *colname[], + char *rowname[]) +{ int i, j, k, beg, end, type, errcode; + double lbnd, ubnd; + char name[255+1]; + errcode = checklp(env, lp); + if (errcode) goto done; + if (numcols < 0 || numrows < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (!(objsen == CPX_MIN || objsen == CPX_MAX)) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (numcols > 0) + { if (matbeg == NULL || matcnt == NULL || matind == NULL || + matval == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + } + for (i = 0; i < numrows; i++) + { if (sense != NULL) + { if (!(sense[i] == 'L' || sense[i] == 'E' || + sense[i] == 'G' || sense[i] == 'R')) + { errcode = error(env, CPXERR_BAD_SENSE, i); + goto done; + } + } + if (rowname != NULL) + { if (rowname[i] == NULL) + { errcode = error(env, CPXERR_NULL_NAME, i); + goto done; + } + } + } + enlargeiwork(lp, numrows); + for (j = 0; j < numcols; j++) + { beg = matbeg[j]; + if (j > 0 && !(matbeg[j-1] <= beg)) + { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, j); + goto done; + } + if (beg < 0) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + end = beg + matcnt[j]; + if (!(beg <= end) || j < numcols-1 && !(end <= matbeg[j+1])) + { errcode = error(env, CPXERR_COUNT_RANGE, j); + goto done; + } + for (k = beg; k < end; k++) + { if (!(0 <= matind[k] && matind[k] < numrows)) + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, k); + goto done; + } + } + errcode = 0; + for (k = beg; k < end; k++) + { if (lp->iwork[matind[k]]) + { errcode = error(env, CPXERR_DUP_ENTRY); + break; + } + lp->iwork[matind[k]] = 1; + } + for (k = beg; k < end; k++) + lp->iwork[matind[k]] = 0; + if (errcode) goto done; + if (colname != NULL) + { if (colname[j] != NULL) + { errcode = error(env, CPXERR_NULL_NAME, j); + goto done; + } + } + } + errcode = 0; + invalidate(lp); + if (glp_get_prob_name(lp->prob) == NULL) + name[0] = '\0'; + else + strcpy(name, glp_get_prob_name(lp->prob)); + glp_erase_prob(lp->prob); + glp_set_prob_name(lp->prob, name); + if (objsen == CPX_MIN) + glp_set_obj_dir(lp->prob, GLP_MIN); + else if (objsen == CPX_MAX) + glp_set_obj_dir(lp->prob, GLP_MAX); + else + xassert(objsen != objsen); + if (numrows > 0) + glp_add_rows(lp->prob, numrows); + enlargerflag(lp); + for (i = 0; i < numrows; i++) + { if (rowname != NULL) + glp_set_row_name(lp->prob, i+1, rowname[i]); + lbnd = ubnd = (rhs == NULL ? 0.0 : rhs[i]); + if (sense == NULL || sense[i] == 'E') + { lp->rflag[i] = RF_NOT_RANGED; + type = GLP_FX; + } + else if (sense[i] == 'L') + { lp->rflag[i] = RF_NOT_RANGED; + type = GLP_UP; + } + else if (sense[i] == 'G') + { lp->rflag[i] = RF_NOT_RANGED; + type = GLP_LO; + } + else if (sense[i] == 'R') + { if (rngval == NULL || rngval[i] == 0.0) + { lp->rflag[i] = RF_RANGED_POS; + type = GLP_FX; + } + else if (rngval[i] > 0.0) + { lp->rflag[i] = RF_RANGED_POS; + type = GLP_DB; + ubnd += rngval[i]; + } + else /* rngval[i] < 0.0 */ + { lp->rflag[i] = RF_RANGED_NEG; + type = GLP_DB; + lbnd += rngval[i]; + } + } + else + xassert(sense != sense); + glp_set_row_bnds(lp->prob, i+1, type, lbnd, ubnd); + } + if (numcols > 0) + glp_add_cols(lp->prob, numcols); + for (j = 0; j < numcols; j++) + { if (colname != NULL) + glp_set_col_name(lp->prob, j+1, colname[j]); + lbnd = (lb == NULL ? 0.0 : lb[j]); + ubnd = (ub == NULL ? +CPX_INFBOUND : ub[j]); + if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) + type = GLP_FR; + else if (ubnd >= +CPX_INFBOUND) + type = GLP_LO; + else if (lbnd <= -CPX_INFBOUND) + type = GLP_UP; + else if (lbnd != ubnd) + type = GLP_DB; + else + type = GLP_FX; + glp_set_col_bnds(lp->prob, j+1, type, lbnd, ubnd); + if (obj != NULL) + glp_set_obj_coef(lp->prob, j+1, obj[j]); + beg = matbeg[j]; + end = beg + matcnt[j]; + for (k = beg; k < end; k++) + lp->iwork[k-beg] = matind[k]+1; + glp_set_mat_col(lp->prob, j+1, end-beg, lp->iwork-1, + matval+beg-1); + for (k = beg; k < end; k++) + lp->iwork[k-beg] = 0; + } +done: return errcode; +} + +CPXLP *CPXcreateprob(CPXENV *env, int *status, const char *probname) +{ CPXLP *lp = NULL; + int errcode; + errcode = checkenv(env); + if (errcode) goto done; + lp = xmalloc(sizeof(struct CPXLP)); + lp->env = env; + lp->prob = glp_create_prob(); + glp_set_prob_name(lp->prob, probname); + lp->rflen = 100; + lp->rflag = xcalloc(lp->rflen, sizeof(char)); + lp->iwlen = 100; + lp->iwork = xcalloc(lp->iwlen, sizeof(int)); + memset(lp->iwork, 0, lp->iwlen * sizeof(int)); + lp->link = env->list; + env->list = lp; + invalidate(lp); +done: if (status != NULL) *status = errcode; + return lp; +} + +int CPXdelcols(CPXENV *env, CPXLP *lp, int begin, int end) +{ int j, n, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + n = glp_get_num_cols(lp->prob); + if (!(0 <= begin && begin <= end && end < n)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + errcode = 0; + invalidate(lp); + enlargeiwork(lp, end-begin+1); + for (j = begin; j <= end; j++) + lp->iwork[j-begin] = j+1; + glp_del_cols(lp->prob, end-begin+1, lp->iwork-1); + for (j = begin; j <= end; j++) + lp->iwork[j-begin] = 0; +done: return errcode; +} + +int CPXdelrows(CPXENV *env, CPXLP *lp, int begin, int end) +{ int i, m, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + m = glp_get_num_rows(lp->prob); + if (!(0 <= begin && begin <= end && end < m)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + errcode = 0; + invalidate(lp); + enlargeiwork(lp, end-begin+1); + for (i = begin; i <= end; i++) + lp->iwork[i-begin] = i+1; + glp_del_rows(lp->prob, end-begin+1, lp->iwork-1); + for (i = begin; i <= end; i++) + lp->iwork[i-begin] = 0; + for (i = end+1; i < m; i++) + lp->rflag[i-(end-begin+1)] = lp->rflag[i]; +done: return errcode; +} + +int CPXdelsetcols(CPXENV *env, CPXLP *lp, int delstat[]) +{ xassert(env == env); + xassert(lp == lp); + xassert(delstat == delstat); + xprintf("CPXdelsetcols: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXdelsetrows(CPXENV *env, CPXLP *lp, int delstat[]) +{ int i, m, cnt, ind, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + m = glp_get_num_rows(lp->prob); + if (m > 0 && delstat == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + errcode = 0; + invalidate(lp); + enlargeiwork(lp, m); + cnt = ind = 0; + for (i = 0; i < m; i++) + { if (delstat[i] == 1) + { delstat[i] = -1; + lp->iwork[cnt++] = i+1; + } + else + { delstat[i] = ind; + lp->rflag[ind++] = lp->rflag[i]; + } + } + if (cnt > 0) + glp_del_rows(lp->prob, cnt, lp->iwork-1); + for (i = 0; i < cnt; i++) + lp->iwork[i] = 0; +done: return errcode; +} + +int CPXdualopt(CPXENV *env, CPXLP *lp); + +int CPXfreeprob(CPXENV *env, CPXLP **_lp) +{ CPXLP *lp; + int errcode; + errcode = checkenv(env); + if (errcode) goto done; + if (_lp == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + lp = *_lp; + errcode = checklp(env, lp); + if (errcode) goto done; + errcode = 0; + env = lp->env; + if (env->list == lp) + env->list = lp->link; + else + { CPXLP *pp; + for (pp = env->list; pp != NULL; pp = pp->link) + if (pp->link == lp) break; + xassert(pp != NULL); + pp->link = lp->link; + } + glp_delete_prob(lp->prob); + xfree(lp->rflag); + xfree(lp->iwork); + xfree(lp); + *_lp = NULL; +done: return errcode; +} + +int CPXgetbase(CPXENV *env, CPXLP *lp, int cstat[], int rstat[]) +{ int i, j, m, n, stat, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + if (!lp->stat) + { errcode = error(env, CPXERR_NO_SOLN); + goto done; + } + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + ; + else + { errcode = error(env, CPXERR_NO_BASIC_SOLN); + goto done; + } + errcode = 0; + if (rstat != NULL) + { m = glp_get_num_rows(lp->prob); + for (i = 0; i < m; i++) + { stat = glp_get_row_stat(lp->prob, i+1); + if (stat == GLP_BS) + rstat[i] = CPX_BASIC; + else if (lp->rflag[i] == RF_NOT_RANGED || stat != GLP_NU) + rstat[i] = CPX_AT_LOWER; + else + rstat[i] = CPX_AT_UPPER; + } + } + if (cstat != NULL) + { n = glp_get_num_cols(lp->prob); + for (j = 0; j < n; j++) + { stat = glp_get_col_stat(lp->prob, j+1); + if (stat == GLP_BS) + cstat[j] = CPX_BASIC; + else if (stat == GLP_NU) + cstat[j] = CPX_AT_UPPER; + else if (stat == GLP_NF) + cstat[j] = CPX_FREE_SUPER; + else + cstat[j] = CPX_AT_LOWER; + } + } +done: return errcode; +} + +int CPXgetbasednorms(CPXENV *env, CPXLP *lp, int cstat[], int rstat[], + double dnorm[]) +{ int i, m, errcode; + errcode = CPXgetbase(env, lp, cstat, rstat); + if (errcode) goto done; + if (dnorm != NULL) + { m = glp_get_num_rows(lp->prob); + for (i = 0; i < m; i++) dnorm[i] = 1.0; + } +done: return errcode; +} + +int CPXgetbhead(CPXENV *env, CPXLP *lp, int head[], double x[]) +{ xassert(env == env); + xassert(lp == lp); + xassert(head == head); + xassert(x == x); + xprintf("CPXgetbhead: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXgetdblparam(CPXENV *env, int whichparam, double *value) +{ int k, errcode; + errcode = checkenv(env); + if (errcode) goto done; + k = finddblparam(whichparam); + if (k < 0) + { errcode = error(env, CPXERR_BAD_PARAM_NUM); + goto done; + } + errcode = 0; + if (value != NULL) + *value = env->dblparam[k]; +done: return errcode; +} + +int CPXgetdj(CPXENV *env, CPXLP *lp, double dj[], int begin, int end) +{ int j, n, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + n = glp_get_num_cols(lp->prob); + if (!(0 <= begin && begin <= end && end < n)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + if (!lp->stat) + { errcode = error(env, CPXERR_NO_SOLN); + goto done; + } + errcode = 0; + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + { if (dj != NULL) + { for (j = begin; j <= end; j++) + dj[j-begin] = glp_get_col_dual(lp->prob, j+1); + } + } + else + xassert(lp != lp); +done: return errcode; +} + +char *CPXgeterrorstring(CPXENV *env, int errcode, char *buffer) +{ const char *string; + xassert(env == env); + string = finderrstring(errcode); + if (string == NULL) + buffer = NULL; + else + sprintf(buffer, "CPLEX Error %5d: %s.\n", errcode, string); + return buffer; +} + +int CPXgetijdiv(CPXENV *env, CPXLP *lp, int *idiv, int *jdiv) +{ xassert(env == env); + xassert(lp == lp); + xassert(idiv == idiv); + xassert(jdiv == jdiv); + xprintf("CPXgetijdiv: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXgetintparam(CPXENV *env, int whichparam, int *value) +{ int k, errcode; + errcode = checkenv(env); + if (errcode) goto done; + k = findintparam(whichparam); + if (k < 0) + { errcode = error(env, CPXERR_BAD_PARAM_NUM); + goto done; + } + errcode = 0; + if (value != NULL) + *value = env->intparam[k]; +done: return errcode; +} + +int CPXgetlb(CPXENV *env, CPXLP *lp, double lb[], int begin, int end) +{ xassert(env == env); + xassert(lp == lp); + xassert(lb == lb); + xassert(begin == begin); + xassert(end == end); + xprintf("CPXgetlb: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXgetmethod(CPXENV *env, CPXLP *lp) +{ int method; + if (checklp(env, lp)) + method = CPX_ALG_NONE; + else + method = lp->meth; + return method; +} + +int CPXgetnumcols(CPXENV *env, CPXLP *lp) +{ int numcols; + if (checklp(env, lp)) + numcols = 0; + else + numcols = glp_get_num_cols(lp->prob); + return numcols; +} + +int CPXgetnumnz(CPXENV *env, CPXLP *lp) +{ int numnz; + if (checklp(env, lp)) + numnz = 0; + else + numnz = glp_get_num_nz(lp->prob); + return numnz; +} + +int CPXgetnumrows(CPXENV *env, CPXLP *lp) +{ int numrows; + if (checklp(env, lp)) + numrows = 0; + else + numrows = glp_get_num_rows(lp->prob); + return numrows; +} + +int CPXgetobjval(CPXENV *env, CPXLP *lp, double *objval) +{ int errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + if (!lp->stat) + { errcode = error(env, CPXERR_NO_SOLN); + goto done; + } + errcode = 0; + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + { if (objval != NULL) + *objval = glp_get_obj_val(lp->prob); + } + else + xassert(lp != lp); +done: return errcode; +} + +int CPXgetpi(CPXENV *env, CPXLP *lp, double pi[], int begin, int end) +{ int i, m, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + m = glp_get_num_rows(lp->prob); + if (!(0 <= begin && begin <= end && end < m)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + if (!lp->stat) + { errcode = error(env, CPXERR_NO_SOLN); + goto done; + } + errcode = 0; + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + { if (pi != NULL) + { for (i = begin; i <= end; i++) + pi[i-begin] = glp_get_row_dual(lp->prob, i+1); + } + } + else + xassert(lp != lp); +done: return errcode; +} + +int CPXgetsense(CPXENV *env, CPXLP *lp, char sense[], int begin, + int end) +{ xassert(env == env); + xassert(lp == lp); + xassert(sense == sense); + xassert(begin == begin); + xassert(end == end); + xprintf("CPXgetsense: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXgetslack(CPXENV *env, CPXLP *lp, double slack[], int begin, + int end) +{ int i, m, type, errcode; + double temp; + errcode = checklp(env, lp); + if (errcode) goto done; + m = glp_get_num_rows(lp->prob); + if (!(0 <= begin && begin <= end && end < m)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + if (!lp->stat) + { errcode = error(env, CPXERR_NO_SOLN); + goto done; + } + errcode = 0; + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + { if (slack != NULL) + { for (i = begin; i <= end; i++) + { type = glp_get_row_type(lp->prob, i+1); + temp = glp_get_row_prim(lp->prob, i+1); + if (lp->rflag[i] == RF_NOT_RANGED) + { if (type == GLP_LO || type == GLP_FX) + slack[i-begin] = + glp_get_row_lb(lp->prob, i+1) - temp; + else if (type == GLP_UP) + slack[i-begin] = + glp_get_row_ub(lp->prob, i+1) - temp; + else + xassert(type != type); + } + else if (lp->rflag[i] == RF_RANGED_POS) + { xassert(type == GLP_DB || type == GLP_FX); + slack[i-begin] = + temp - glp_get_row_lb(lp->prob, i+1); + } + else if (lp->rflag[i] == RF_RANGED_NEG) + { xassert(type == GLP_DB); + slack[i-begin] = + temp - glp_get_row_ub(lp->prob, i+1); + } + else + xassert(lp != lp); + } + } + } + else + xassert(lp != lp); +done: return errcode; +} + +int CPXgetstat(CPXENV *env, CPXLP *lp) +{ int stat; + if (checklp(env, lp)) + stat = 0; + else + stat = lp->stat; + return stat; +} + +int CPXgetub(CPXENV *env, CPXLP *lp, double ub[], int begin, int end) +{ xassert(env == env); + xassert(lp == lp); + xassert(ub == ub); + xassert(begin == begin); + xassert(end == end); + xprintf("CPXgetub: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXgetweight(CPXENV *env, CPXLP *lp, int rcnt, const int rmatbeg[], + const int rmatind[], const double rmatval[], double weight[], + int dpriind) +{ xassert(env == env); + xassert(lp == lp); + xassert(rcnt == rcnt); + xassert(rmatbeg == rmatbeg); + xassert(rmatind == rmatind); + xassert(rmatval == rmatval); + xassert(weight == weight); + xassert(dpriind == dpriind); + xprintf("CPXgetweight: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXgetx(CPXENV *env, CPXLP *lp, double x[], int begin, int end) +{ int j, n, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + n = glp_get_num_cols(lp->prob); + if (!(0 <= begin && begin <= end && end < n)) + { errcode = error(env, CPXERR_INDEX_RANGE); + goto done; + } + if (!lp->stat) + { errcode = error(env, CPXERR_NO_SOLN); + goto done; + } + errcode = 0; + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + { if (x != NULL) + { for (j = begin; j <= end; j++) + x[j-begin] = glp_get_col_prim(lp->prob, j+1); + } + } + else + xassert(lp != lp); +done: return errcode; +} + +int CPXinfodblparam(CPXENV *env, int whichparam, double *defvalue, + double *minvalue, double *maxvalue) +{ int k, errcode; + errcode = checkenv(env); + if (errcode) goto done; + k = finddblparam(whichparam); + if (k < 0) + { errcode = error(env, CPXERR_BAD_PARAM_NUM); + goto done; + } + errcode = 0; + if (defvalue != NULL) + *defvalue = dblparam[k].defv; + if (minvalue != NULL) + *minvalue = dblparam[k].minv; + if (maxvalue != NULL) + *maxvalue = dblparam[k].maxv; +done: return errcode; +} + +int CPXinfointparam(CPXENV *env, int whichparam, int *defvalue, + int *minvalue, int *maxvalue) +{ int k, errcode; + errcode = checkenv(env); + if (errcode) goto done; + k = findintparam(whichparam); + if (k < 0) + { errcode = error(env, CPXERR_BAD_PARAM_NUM); + goto done; + } + errcode = 0; + if (defvalue != NULL) + *defvalue = intparam[k].defv; + if (minvalue != NULL) + *minvalue = intparam[k].minv; + if (maxvalue != NULL) + *maxvalue = intparam[k].maxv; +done: return errcode; +} + +int CPXmdleave(const CPXENV *env, CPXLP *lp, const int goodlist[], + int goodlen, double downratio[], double upratio[]) +{ int k; + xassert(env == env); + xassert(lp == lp); + xassert(goodlist == goodlist); + xassert(goodlen >= 0); + xassert(downratio != NULL); + xassert(upratio != NULL); + /* not implemented yet */ + for (k = 0; k < goodlen; k++) + downratio[k] = upratio[k] = 0.0; + return 0; +} + +int CPXnewcols(CPXENV *env, CPXLP *lp, int ccnt, const double obj[], + const double lb[], const double ub[], const char ctype[], + char *colname[]) +{ int j, n, kind, type, errcode; + double lbnd, ubnd; + errcode = checklp(env, lp); + if (errcode) goto done; + if (ccnt < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + for (j = 0; j < ccnt; j++) + { if (ctype != NULL) + { if (!(ctype[j] == 'C' || ctype[j] == 'B' || + ctype[j] == 'I')) + { errcode = error(env, CPXERR_BAD_CTYPE, j); + goto done; + } + } + if (colname != NULL) + { if (colname[j] == NULL) + { errcode = error(env, CPXERR_NULL_NAME, j); + goto done; + } + } + } + errcode = 0; + invalidate(lp); + n = glp_get_num_cols(lp->prob); + if (ccnt > 0) + glp_add_cols(lp->prob, ccnt); + for (j = 0; j < ccnt; j++) + { if (colname != NULL) + glp_set_col_name(lp->prob, n+j+1, colname[j]); + if (obj != NULL) + glp_set_obj_coef(lp->prob, n+j+1, obj[j]); + lbnd = (lb == NULL ? 0.0 : lb[j]); + ubnd = (ub == NULL ? 0.0 : ub[j]); + if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) + type = GLP_FR; + else if (ubnd >= +CPX_INFBOUND) + type = GLP_LO; + else if (lbnd <= -CPX_INFBOUND) + type = GLP_UP; + else if (lbnd != ubnd) + type = GLP_DB; + else + type = GLP_FX; + glp_set_col_bnds(lp->prob, n+j+1, type, lbnd, ubnd); + if (ctype != NULL) + { if (ctype[j] == 'C') + kind = GLP_CV; + else if (ctype[j] == 'B') + kind = GLP_BV; + else if (ctype[j] == 'I') + kind = GLP_IV; + else + xassert(ctype != ctype); + glp_set_col_kind(lp->prob, n+j+1, kind); + } + } +done: return errcode; +} + +int CPXnewrows(CPXENV *env, CPXLP *lp, int rcnt, const double rhs[], + const char sense[], const double rngval[], char *rowname[]) +{ int i, m, type, errcode; + double lbnd, ubnd; + errcode = checklp(env, lp); + if (errcode) goto done; + if (rcnt < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + for (i = 0; i < rcnt; i++) + { if (sense != NULL) + { if (!(sense[i] == 'L' || sense[i] == 'E' || + sense[i] == 'G' || sense[i] == 'R')) + { errcode = error(env, CPXERR_BAD_SENSE, i); + goto done; + } + } + if (rowname != NULL) + { if (rowname[i] == NULL) + { errcode = error(env, CPXERR_NULL_NAME, i); + goto done; + } + } + } + errcode = 0; + invalidate(lp); + m = glp_get_num_rows(lp->prob); + if (rcnt > 0) + glp_add_rows(lp->prob, rcnt); + enlargerflag(lp); + for (i = 0; i < rcnt; i++) + { if (rowname != NULL) + glp_set_row_name(lp->prob, m+i+1, rowname[i]); + lbnd = ubnd = (rhs == NULL ? 0.0 : rhs[i]); + if (sense == NULL || sense[i] == 'E') + { lp->rflag[m+i] = RF_NOT_RANGED; + type = GLP_FX; + } + else if (sense[i] == 'L') + { lp->rflag[m+i] = RF_NOT_RANGED; + type = GLP_UP; + } + else if (sense[i] == 'G') + { lp->rflag[m+i] = RF_NOT_RANGED; + type = GLP_LO; + } + else if (sense[i] == 'R') + { if (rngval == NULL || rngval[i] == 0.0) + { lp->rflag[m+i] = RF_RANGED_POS; + type = GLP_FX; + } + else if (rngval[i] > 0.0) + { lp->rflag[m+i] = RF_RANGED_POS; + type = GLP_DB; + ubnd += rngval[i]; + } + else /* rngval[i] < 0.0 */ + { lp->rflag[m+i] = RF_RANGED_NEG; + type = GLP_DB; + lbnd += rngval[i]; + } + } + else + xassert(sense != sense); + glp_set_row_bnds(lp->prob, m+i+1, type, lbnd, ubnd); + } +done: return errcode; +} + +CPXENV *CPXopenCPLEX(int *status) +{ CPXENV *env; + int k, card; + env = xmalloc(sizeof(CPXENV)); + env->list = NULL; + card = sizeof(intparam) / sizeof(struct intparam); + env->intparam = xcalloc(card, sizeof(int)); + for (k = 0; k < card; k++) + env->intparam[k] = intparam[k].defv; + card = sizeof(dblparam) / sizeof(struct dblparam); + env->dblparam = xcalloc(card, sizeof(double)); + for (k = 0; k < card; k++) + env->dblparam[k] = dblparam[k].defv; + if (status != NULL) *status = 0; + return env; +} + +int CPXpivotin(CPXENV *env, CPXLP *lp, const int rlist[], int rlen) +{ int i, m, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + if (rlen < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (rlen > 0 && rlist == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + m = glp_get_num_rows(lp->prob); + for (i = 0; i < rlen; i++) + { if (!(0 <= rlist[i] && rlist[i] < m)) + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i); + goto done; + } + } + errcode = 0; + for (i = 0; i < rlen; i++) + { if (glp_get_row_type(lp->prob, rlist[i]+1) != GLP_FX) + { if (glp_get_row_stat(lp->prob, rlist[i]+1) != GLP_BS) + { /* not implemented yet */ + break; + } + } + } +done: return errcode; +} + +int CPXpivotout(CPXENV *env, CPXLP *lp, const int clist[], int clen) +{ int j, n, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + if (clen < 0) + { errcode = error(env, CPXERR_BAD_ARGUMENT); + goto done; + } + if (clen > 0 && clist == NULL) + { errcode = error(env, CPXERR_NULL_POINTER); + goto done; + } + n = glp_get_num_cols(lp->prob); + for (j = 0; j < clen; j++) + { if (!(0 <= clist[j] && clist[j] < n)) + { errcode = error(env, CPXERR_COL_INDEX_RANGE, j); + goto done; + } + if (glp_get_col_type(lp->prob, clist[j]+1) != GLP_FX) + { errcode = error(env, CPXERR_NOT_FIXED); + goto done; + } + } + errcode = 0; + for (j = 0; j < clen; j++) + { if (glp_get_col_stat(lp->prob, clist[j]+1) == GLP_BS) + { /* not implemented yet */ + break; + } + } +done: return errcode; +} + +int CPXprimopt(CPXENV *env, CPXLP *lp); + +int CPXsavwrite(CPXENV *env, CPXLP *lp, const char *filename) +{ xassert(env == env); + xassert(lp == lp); + xassert(filename == filename); + xprintf("CPXsavwrite: not implemented yet\n"); + exit(EXIT_FAILURE); + return -1; +} + +int CPXsetdblparam(CPXENV *env, int whichparam, double newvalue) +{ int k, errcode; + errcode = checkenv(env); + if (errcode) goto done; + k = finddblparam(whichparam); + if (k < 0) + { errcode = error(env, CPXERR_BAD_PARAM_NUM); + goto done; + } + if (newvalue < dblparam[k].minv) + { errcode = error(env, CPXERR_PARAM_TOO_SMALL); + goto done; + } + if (newvalue > dblparam[k].maxv) + { errcode = error(env, CPXERR_PARAM_TOO_BIG); + goto done; + } + errcode = 0; + env->dblparam[k] = newvalue; +done: return errcode; +} + +int CPXsetintparam(CPXENV *env, int whichparam, int newvalue) +{ int k, errcode; + errcode = checkenv(env); + if (errcode) goto done; + k = findintparam(whichparam); + if (k < 0) + { errcode = error(env, CPXERR_BAD_PARAM_NUM); + goto done; + } + if (newvalue < intparam[k].minv) + { errcode = error(env, CPXERR_PARAM_TOO_SMALL); + goto done; + } + if (newvalue > intparam[k].maxv) + { errcode = error(env, CPXERR_PARAM_TOO_BIG); + goto done; + } + errcode = 0; + env->intparam[k] = newvalue; +done: return errcode; +} + +int CPXsolninfo(CPXENV *env, CPXLP *lp, int *solnmethod, int *solntype, + int *pfeasind, int *dfeasind) +{ int type, pfeas, dfeas, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + errcode = 0; + if (!lp->stat) + type = CPX_NO_SOLN, pfeas = dfeas = 0; + else if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + { type = CPX_BASIC_SOLN; + pfeas = (glp_get_prim_stat(lp->prob) == GLP_FEAS); + dfeas = (glp_get_dual_stat(lp->prob) == GLP_FEAS); + } + else + xassert(lp != lp); + if (solnmethod != NULL) + *solnmethod = lp->meth; + if (solntype != NULL) + *solntype = type; + if (pfeasind != NULL) + *pfeasind = pfeas; + if (dfeasind != NULL) + *dfeasind = dfeas; +done: return errcode; +} + +int CPXsolution(CPXENV *env, CPXLP *lp, int *lpstat, double *objval, + double x[], double pi[], double slack[], double dj[]) +{ int m, n, errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + if (!lp->stat) + { errcode = error(env, CPXERR_NO_SOLN); + goto done; + } + errcode = 0; + m = glp_get_num_rows(lp->prob); + n = glp_get_num_cols(lp->prob); + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) + { if (lpstat != NULL) + *lpstat = CPXgetstat(env, lp); + if (objval != NULL) + xassert(CPXgetobjval(env, lp, objval) == 0); + if (x != NULL) + xassert(CPXgetx(env, lp, x, 0, n-1) == 0); + if (pi != NULL) + xassert(CPXgetpi(env, lp, pi, 0, m-1) == 0); + if (slack != NULL) + xassert(CPXgetslack(env, lp, slack, 0, m-1) == 0); + if (dj != NULL) + xassert(CPXgetdj(env, lp, dj, 0, n-1) == 0); + } + else + xassert(lp != lp); +done: return errcode; +} + +int CPXstrongbranch(CPXENV *env, CPXLP *lp, const int goodlist[], + int goodlen, double downpen[], double uppen[], int itlim) +{ int k; + xassert(env == env); + xassert(lp == lp); + xassert(goodlist == goodlist); + xassert(goodlen >= 0); + xassert(downpen != NULL); + xassert(uppen != NULL); + xassert(itlim == itlim); + /* not implemented yet */ + for (k = 0; k < goodlen; k++) + downpen[k] = uppen[k] = 0.0; + return 0; +} + +static int xstrcasecmp(const char *s1, const char *s2) +{ int c1, c2; + for (;;) + { c1 = toupper((unsigned char)*s1++); + c2 = toupper((unsigned char)*s2++); + if (c1 == '\0' || c1 != c2) break; + } + return c1 - c2; +} + +static void getfiletype(const char *filename, char type[3+1]) +{ /* determine filetype from filename */ + int beg, end; + beg = end = strlen(filename); + while (beg > 0 && filename[beg-1] != '.' && end - beg < 3) + beg--; + if (beg > 0 && filename[beg-1] == '.' && + xstrcasecmp(&filename[beg], "gz") == 0) + { end = --beg; + while (beg > 0 && filename[beg-1] != '.' && end - beg < 3) + beg--; + } + if (beg > 0 && filename[beg-1] == '.') + { memcpy(type, &filename[beg], end - beg); + type[end - beg] = '\0'; + } + else + type[0] = '\0'; + return; +} + +int CPXwriteprob(CPXENV *env, CPXLP *lp, const char *filename, + const char *filetype) +{ glp_prob *copy; + int errcode; + char type[3+1]; + errcode = checklp(env, lp); + if (errcode) goto done; + if (filename == NULL) + { errcode = error(env, CPXERR_NO_FILENAME); + goto done; + } + if (filetype == NULL) + getfiletype(filename, type), filetype = type; + if (xstrcasecmp(filetype, "MPS") == 0) + { glp_term_out(GLP_OFF); + errcode = glp_write_mps(lp->prob, GLP_MPS_FILE, NULL, filename) + ; + glp_term_out(GLP_ON); + } + else if (xstrcasecmp(filetype, "LP") == 0) + { glp_term_out(GLP_OFF); + errcode = glp_write_lp(lp->prob, NULL, filename); + glp_term_out(GLP_ON); + } + else if (xstrcasecmp(filetype, "RMP") == 0 || + xstrcasecmp(filetype, "REW") == 0) + { copy = glp_create_prob(); + glp_copy_prob(copy, lp->prob, GLP_OFF); + glp_term_out(GLP_OFF); + errcode = glp_write_mps(copy, GLP_MPS_DECK, NULL, filename); + glp_term_out(GLP_ON); + glp_delete_prob(copy); + } + else if (xstrcasecmp(filetype, "RLP") == 0) + { copy = glp_create_prob(); + glp_copy_prob(copy, lp->prob, GLP_OFF); + glp_term_out(GLP_OFF); + errcode = glp_write_lp(copy, NULL, filename); + glp_term_out(GLP_ON); + glp_delete_prob(copy); + } + else + { errcode = error(env, CPXERR_BAD_FILETYPE); + goto done; + } + if (errcode) + errcode = error(env, CPXERR_FAIL_OPEN_WRITE, filename); +done: return errcode; +} + +/**********************************************************************/ + +static int solvelp(CPXENV *env, CPXLP *lp, int meth) +{ glp_smcp parm; + int errcode; + errcode = checklp(env, lp); + if (errcode) goto done; + errcode = 0; + invalidate(lp); + glp_init_smcp(&parm); + switch (meth) + { case CPX_ALG_PRIMAL: + parm.meth = GLP_PRIMAL; + break; + case CPX_ALG_DUAL: + parm.meth = GLP_DUAL; + break; + default: + xassert(meth != meth); + } + switch (getintparam(env, CPX_PARAM_SIMDISPLAY)) + { case 0: + parm.msg_lev = GLP_MSG_OFF; + break; + case 1: + parm.msg_lev = GLP_MSG_ALL; + break; + case 2: + parm.msg_lev = GLP_MSG_ALL; + parm.out_frq = 1; + break; + default: + xassert(env != env); + } + xassert(getdblparam == getdblparam); + switch (getintparam(env, CPX_PARAM_ADVIND)) + { case 0: + glp_term_out(GLP_OFF); + glp_adv_basis(lp->prob, 0); + glp_term_out(GLP_ON); + break; + case 1: + case 2: + break; + default: + xassert(env != env); + } + if (!glp_bf_exists(lp->prob)) + { if (glp_factorize(lp->prob) != 0) + { glp_term_out(GLP_OFF); + glp_adv_basis(lp->prob, 0); + glp_term_out(GLP_ON); + if (glp_factorize(lp->prob) != 0) + glp_std_basis(lp->prob); + } + } + xassert(glp_simplex(lp->prob, &parm) == 0); + switch (glp_get_status(lp->prob)) + { case GLP_OPT: + lp->stat = CPX_STAT_OPTIMAL; + lp->meth = meth; + break; + case GLP_NOFEAS: + lp->stat = CPX_STAT_INFEASIBLE; + lp->meth = meth; + break; + case GLP_UNBND: + lp->stat = CPX_STAT_UNBOUNDED; + lp->meth = meth; + break; + default: + xassert(lp != lp); + } +done: return errcode; +} + +int CPXprimopt(CPXENV *env, CPXLP *lp) +{ int errcode; + errcode = solvelp(env, lp, CPX_ALG_PRIMAL); + return errcode; +} + +int CPXdualopt(CPXENV *env, CPXLP *lp) +{ int errcode; + errcode = solvelp(env, lp, CPX_ALG_DUAL); + return errcode; +} + +int CPXlpopt(CPXENV *env, CPXLP *lp) +{ int errcode; + errcode = solvelp(env, lp, CPX_ALG_PRIMAL); + return errcode; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/cplex/cplex.h b/resources/3rdparty/glpk-4.57/examples/cplex/cplex.h new file mode 100644 index 000000000..94c3b204c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/cplex/cplex.h @@ -0,0 +1,301 @@ +/* cplex.h (CPLEX-like interface to GLPK API) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef _CPLEX_H +#define _CPLEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct CPXENV CPXENV, *CPXENVptr; +typedef struct CPXLP CPXLP, *CPXLPptr; + +#define CPX_VERSION 900 + +#define CPX_OFF 0 +#define CPX_ON 1 + +#define CPX_INFBOUND 1e20 + +/* error codes: */ +#define CPXERR_NO_MEMORY 1001 +#define CPXERR_NO_ENVIRONMENT 1002 +#define CPXERR_BAD_ARGUMENT 1003 +#define CPXERR_NULL_POINTER 1004 +#define CPXERR_NO_PROBLEM 1009 +#define CPXERR_BAD_PARAM_NUM 1013 +#define CPXERR_PARAM_TOO_SMALL 1014 +#define CPXERR_PARAM_TOO_BIG 1015 +#define CPXERR_INDEX_RANGE 1200 +#define CPXERR_COL_INDEX_RANGE 1201 +#define CPXERR_ROW_INDEX_RANGE 1203 +#define CPXERR_NEGATIVE_SURPLUS 1207 +#define CPXERR_BAD_SENSE 1215 +#define CPXERR_NO_SOLN 1217 +#define CPXERR_NOT_FIXED 1221 +#define CPXERR_DUP_ENTRY 1222 +#define CPXERR_NULL_NAME 1224 +#define CPXERR_ARRAY_NOT_ASCENDING 1226 +#define CPXERR_COUNT_RANGE 1227 +#define CPXERR_BAD_LUB 1229 +#define CPXERR_BAD_STATUS 1253 +#define CPXERR_NO_BASIC_SOLN 1261 +#define CPXERR_NO_FILENAME 1421 +#define CPXERR_FAIL_OPEN_WRITE 1422 +#define CPXERR_BAD_FILETYPE 1424 +#define CPXERR_BAD_CTYPE 3021 + +/* control parameters: */ +#define CPX_PARAM_ADVIND 1001 +#define CPX_PARAM_AGGIND 1003 +#define CPX_PARAM_DPRIIND 1009 +#define CPX_PARAM_EPOPT 1014 +#define CPX_PARAM_EPPER 1015 +#define CPX_PARAM_EPRHS 1016 +#define CPX_PARAM_FASTMIP 1017 /* ??? */ +#define CPX_PARAM_SIMDISPLAY 1019 +#define CPX_PARAM_ITLIM 1020 +#define CPX_PARAM_OBJLLIM 1025 +#define CPX_PARAM_OBJULIM 1026 +#define CPX_PARAM_PERIND 1027 +#define CPX_PARAM_PPRIIND 1029 +#define CPX_PARAM_PREIND 1030 +#define CPX_PARAM_REINV 1031 +#define CPX_PARAM_SCRIND 1035 +#define CPX_PARAM_DATACHECK 1056 + +/* CPX_PARAM_DPRIIND: */ +#define CPX_DPRIIND_AUTO 0 +#define CPX_DPRIIND_FULL 1 +#define CPX_DPRIIND_STEEP 2 +#define CPX_DPRIIND_FULL_STEEP 3 +#define CPX_DPRIIND_STEEPQSTART 4 +#define CPX_DPRIIND_DEVEX 5 + +/* CPX_PARAM_PPRIIND: */ +#define CPX_PPRIIND_PARTIAL (-1) +#define CPX_PPRIIND_AUTO 0 +#define CPX_PPRIIND_DEVEX 1 +#define CPX_PPRIIND_STEEP 2 +#define CPX_PPRIIND_STEEPQSTART 3 +#define CPX_PPRIIND_FULL 4 + +/* CPXgetprobtype: */ +#define CPXPROB_LP 0 +#define CPXPROB_MIP 1 +#define CPXPROB_RELAXED 2 +#define CPXPROB_FIXED 3 +#define CPXPROB_QP 5 +#define CPXPROB_ZEROEDQP 6 + +/* CPXgetobjsen: */ +#define CPX_MIN 1 +#define CPX_MAX (-1) + +/* CPXgetbase: */ +#define CPX_AT_LOWER 0 +#define CPX_BASIC 1 +#define CPX_AT_UPPER 2 +#define CPX_FREE_SUPER 3 + +/* CPXgetstat: */ +#define CPX_STAT_OPTIMAL 1 +#define CPX_STAT_UNBOUNDED 2 +#define CPX_STAT_INFEASIBLE 3 +#define CPX_STAT_INForUNBD 4 +#define CPX_STAT_OPTIMAL_INFEAS 5 +#define CPX_STAT_ABORT_IT_LIM 10 +#define CPX_STAT_ABORT_OBJ_LIM 12 + +/* CPXgetmethod: */ +#define CPX_ALG_NONE 0 +#define CPX_ALG_PRIMAL 1 +#define CPX_ALG_DUAL 2 +#define CPX_ALG_BARRIER 4 + +/* CPXsolninfo: */ +#define CPX_NO_SOLN 0 +#define CPX_BASIC_SOLN 1 +#define CPX_NONBASIC_SOLN 2 +#define CPX_PRIMAL_SOLN 3 + +int CPXaddcols(CPXENV *env, CPXLP *lp, int ccnt, int nzcnt, + const double obj[], const int cmatbeg[], const int cmatind[], + const double cmatval[], const double lb[], const double ub[], + char *colname[]); + +int CPXaddrows(CPXENV *env, CPXLP *lp, int ccnt, int rcnt, int nzcnt, + const double rhs[], const char sense[], const int rmatbeg[], + const int rmatind[], const double rmatval[], char *colname[], + char *rowname[]); + +int CPXbaropt(CPXENV *env, CPXLP *lp); + +int CPXbinvrow(CPXENV *env, CPXLP *lp, int i, double y[]); + +int CPXchgbds(CPXENV *env, CPXLP *lp, int cnt, const int indices[], + const char lu[], const double bd[]); + +int CPXchgcoeflist(CPXENV *env, CPXLP *lp, int numcoefs, + const int rowlist[], const int collist[], const double vallist[]); + +void CPXchgobjsen(CPXENV *env, CPXLP *lp, int maxormin); + +int CPXchgsense(CPXENV *env, CPXLP *lp, int cnt, const int indices[], + const char sense[]); + +int CPXcloseCPLEX(CPXENV **env); + +int CPXcopybase(CPXENV *env, CPXLP *lp, const int cstat[], + const int rstat[]); + +int CPXcopybasednorms(CPXENV *env, CPXLP *lp, const int cstat[], + const int rstat[], const double dnorm[]); + +int CPXcopylp(CPXENV *env, CPXLP *lp, int numcols, int numrows, + int objsen, const double obj[], const double rhs[], + const char sense[], const int matbeg[], const int matcnt[], + const int matind[], const double matval[], const double lb[], + const double ub[], const double rngval[]); + +int CPXcopylpwnames(CPXENV *env, CPXLP *lp, int numcols, int numrows, + int objsen, const double obj[], const double rhs[], + const char sense[], const int matbeg[], const int matcnt[], + const int matind[], const double matval[], const double lb[], + const double ub[], const double rngval[], char *colname[], + char *rowname[]); + +CPXLP *CPXcreateprob(CPXENV *env, int *status, const char *probname); + +int CPXdelcols(CPXENV *env, CPXLP *lp, int begin, int end); + +int CPXdelrows(CPXENV *env, CPXLP *lp, int begin, int end); + +int CPXdelsetcols(CPXENV *env, CPXLP *lp, int delstat[]); + +int CPXdelsetrows(CPXENV *env, CPXLP *lp, int delstat[]); + +int CPXdualopt(CPXENV *env, CPXLP *lp); + +int CPXfreeprob(CPXENV *env, CPXLP **lp); + +int CPXgetbase(CPXENV *env, CPXLP *lp, int cstat[], int rstat[]); + +int CPXgetbasednorms(CPXENV *env, CPXLP *lp, int cstat[], int rstat[], + double dnorm[]); + +int CPXgetbhead(CPXENV *env, CPXLP *lp, int head[], double x[]); + +int CPXgetdblparam(CPXENV *env, int whichparam, double *value); + +int CPXgetdj(CPXENV *env, CPXLP *lp, double dj[], int begin, int end); + +char *CPXgeterrorstring(CPXENV *env, int errcode, char *buffer); + +int CPXgetijdiv(CPXENV *env, CPXLP *lp, int *idiv, int *jdiv); + +int CPXgetintparam(CPXENV *env, int whichparam, int *value); + +int CPXgetlb(CPXENV *env, CPXLP *lp, double lb[], int begin, int end); + +int CPXgetmethod(CPXENV *env, CPXLP *lp); + +int CPXgetnumcols(CPXENV *env, CPXLP *lp); + +int CPXgetnumnz(CPXENV *env, CPXLP *lp); + +int CPXgetnumrows(CPXENV *env, CPXLP *lp); + +int CPXgetobjval(CPXENV *env, CPXLP *lp, double *objval); + +int CPXgetpi(CPXENV *env, CPXLP *lp, double pi[], int begin, int end); + +int CPXgetsense(CPXENV *env, CPXLP *lp, char sense[], int begin, + int end); + +int CPXgetslack(CPXENV *env, CPXLP *lp, double slack[], int begin, + int end); + +int CPXgetstat(CPXENV *env, CPXLP *lp); + +int CPXgetub(CPXENV *env, CPXLP *lp, double ub[], int begin, int end); + +int CPXgetweight(CPXENV *env, CPXLP *lp, int rcnt, const int rmatbeg[], + const int rmatind[], const double rmatval[], double weight[], + int dpriind); + +int CPXgetx(CPXENV *env, CPXLP *lp, double x[], int begin, int end); + +int CPXinfodblparam(CPXENV *env, int whichparam, double *defvalue, + double *minvalue, double *maxvalue); + +int CPXinfointparam(CPXENV *env, int whichparam, int *defvalue, + int *minvalue, int *maxvalue); + +int CPXlpopt(CPXENV *env, CPXLP *lp); + +int CPXmdleave(const CPXENV *env, CPXLP *lp, const int goodlist[], + int goodlen, double downratio[], double upratio[]); + +int CPXnewcols(CPXENV *env, CPXLP *lp, int ccnt, const double obj[], + const double lb[], const double ub[], const char ctype[], + char *colname[]); + +int CPXnewrows(CPXENV *env, CPXLP *lp, int rcnt, const double rhs[], + const char sense[], const double rngval[], char *rowname[]); + +CPXENV *CPXopenCPLEX(int *status); + +int CPXpivotin(CPXENV *env, CPXLP *lp, const int rlist[], int rlen); + +int CPXpivotout(CPXENV *env, CPXLP *lp, const int clist[], int clen); + +int CPXprimopt(CPXENV *env, CPXLP *lp); + +int CPXsavwrite(CPXENV *env, CPXLP *lp, const char *filename); + +int CPXsetdblparam(CPXENV *env, int whichparam, double newvalue); + +int CPXsetintparam(CPXENV *env, int whichparam, int newvalue); + +int CPXsolninfo(CPXENV *env, CPXLP *lp, int *solnmethod, int *solntype, + int *pfeasind, int *dfeasind); + +int CPXsolution(CPXENV *env, CPXLP *lp, int *lpstat, double *objval, + double x[], double pi[], double slack[], double dj[]); + +int CPXstrongbranch(CPXENV *env, CPXLP *lp, const int goodlist[], + int goodlen, double downpen[], double uppen[], int itlim); + +int CPXwriteprob(CPXENV *env, CPXLP *lp, const char *filename, + const char *filetype); + +#ifdef __cplusplus +} +#endif + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/cpp.mod b/resources/3rdparty/glpk-4.57/examples/cpp.mod new file mode 100644 index 000000000..af3f1208b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/cpp.mod @@ -0,0 +1,67 @@ +/* CPP, Critical Path Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* Note: Reduced costs of auxiliary variables phi[j,k] (see below) + can be only zero or one. The critical path is defined by the + constraints, whose reduced cost is one. */ + +set J; +/* set of jobs (activities) */ + +set P{j in J}, in J, default {}; +/* P[j] is a subset of jobs that immediately precede job j */ + +param t{j in J}, >= 0; +/* duration required to perform job j */ + +var x{j in J}, >= 0; +/* starting time of job j */ + +s.t. phi{j in J, k in P[j]}: x[j] >= x[k] + t[k]; +/* job j can start only after all immediately preceding jobs have been + completely performed */ + +var z; +/* project makespan */ + +s.t. fin{j in J}: z >= x[j] + t[j]; +/* which is the maximum of the completion times of all the jobs */ + +minimize obj: z; +/* the objective is make z as small as possible */ + +data; + +/* The optimal solution is 46 */ + +param : J : t := + A 3 /* Excavate */ + B 4 /* Lay foundation */ + C 3 /* Rough plumbing */ + D 10 /* Frame */ + E 8 /* Finish exterior */ + F 4 /* Install HVAC */ + G 6 /* Rough electric */ + H 8 /* Sheet rock */ + I 5 /* Install cabinets */ + J 5 /* Paint */ + K 4 /* Final plumbing */ + L 2 /* Final electric */ + M 4 /* Install flooring */ +; + +set P[B] := A; +set P[C] := B; +set P[D] := B; +set P[E] := D; +set P[F] := D; +set P[G] := D; +set P[H] := C E F G; +set P[I] := H; +set P[J] := H; +set P[K] := I; +set P[L] := J; +set P[M] := K L; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/crypto.mod b/resources/3rdparty/glpk-4.57/examples/crypto.mod new file mode 100644 index 000000000..bad50325f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/crypto.mod @@ -0,0 +1,84 @@ +/* CRYPTO, a crypto-arithmetic puzzle */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* This problem comes from the newsgroup rec.puzzle. + The numbers from 1 to 26 are assigned to the letters of the alphabet. + The numbers beside each word are the total of the values assigned to + the letters in the word (e.g. for LYRE: L, Y, R, E might be to equal + 5, 9, 20 and 13, or any other combination that add up to 47). + Find the value of each letter under the equations: + + BALLET 45 GLEE 66 POLKA 59 SONG 61 + CELLO 43 JAZZ 58 QUARTET 50 SOPRANO 82 + CONCERT 74 LYRE 47 SAXOPHONE 134 THEME 72 + FLUTE 30 OBOE 53 SCALE 51 VIOLIN 100 + FUGUE 50 OPERA 65 SOLO 37 WALTZ 34 + + Solution: + A, B,C, D, E,F, G, H, I, J, K,L,M, N, O, P,Q, R, S,T,U, V,W, X, Y, Z + 5,13,9,16,20,4,24,21,25,17,23,2,8,12,10,19,7,11,15,3,1,26,6,22,14,18 + + Reference: + Koalog Constraint Solver , + Simple problems, the crypto-arithmetic puzzle ALPHACIPHER. */ + +set LETTERS := +{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' +}; +/* set of letters */ + +set VALUES := 1..card(LETTERS); +/* set of values assigned to the letters */ + +set WORDS; +/* set of words */ + +param total{word in WORDS}; +/* total[word] is the total of the values assigned to the letters in + the word */ + +var x{i in LETTERS, j in VALUES}, binary; +/* x[i,j] = 1 means that letter i is assigned value j */ + +s.t. phi{i in LETTERS}: sum{j in VALUES} x[i,j] = 1; + +s.t. psi{j in VALUES}: sum{i in LETTERS} x[i,j] = 1; + +s.t. eqn{word in WORDS}: sum{k in 1..length(word), j in VALUES} + j * x[substr(word,k,1), j] = total[word]; + +solve; + +printf{i in LETTERS} " %s", i; +printf "\n"; + +printf{i in LETTERS} " %2d", sum{j in VALUES} j * x[i,j]; +printf "\n"; + +data; + +param : WORDS : total := + BALLET 45 + CELLO 43 + CONCERT 74 + FLUTE 30 + FUGUE 50 + GLEE 66 + JAZZ 58 + LYRE 47 + OBOE 53 + OPERA 65 + POLKA 59 + QUARTET 50 + SAXOPHONE 134 + SCALE 51 + SOLO 37 + SONG 61 + SOPRANO 82 + THEME 72 + VIOLIN 100 + WALTZ 34 ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/csv/distances.csv b/resources/3rdparty/glpk-4.57/examples/csv/distances.csv new file mode 100644 index 000000000..8c7b419de --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/csv/distances.csv @@ -0,0 +1,7 @@ +plant,market,distance +"Seattle","New York",2.5 +"Seattle","Chicago",1.7 +"Seattle","Topeka",1.8 +"San Diego","New York",2.5 +"San Diego","Chicago",1.8 +"San Diego","Topeka",1.4 diff --git a/resources/3rdparty/glpk-4.57/examples/csv/markets.csv b/resources/3rdparty/glpk-4.57/examples/csv/markets.csv new file mode 100644 index 000000000..d04dec82c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/csv/markets.csv @@ -0,0 +1,4 @@ +market,demand +"New York",325. +"Chicago",300. +"Topeka",275. diff --git a/resources/3rdparty/glpk-4.57/examples/csv/parameters.csv b/resources/3rdparty/glpk-4.57/examples/csv/parameters.csv new file mode 100644 index 000000000..c7c37e9af --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/csv/parameters.csv @@ -0,0 +1,2 @@ +parameter,value +"transport cost",90. diff --git a/resources/3rdparty/glpk-4.57/examples/csv/plants.csv b/resources/3rdparty/glpk-4.57/examples/csv/plants.csv new file mode 100644 index 000000000..292f45f12 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/csv/plants.csv @@ -0,0 +1,3 @@ +plant,capacity +"Seattle",350. +"San Diego",600. diff --git a/resources/3rdparty/glpk-4.57/examples/csv/transp_csv.mod b/resources/3rdparty/glpk-4.57/examples/csv/transp_csv.mod new file mode 100644 index 000000000..d970bf61b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/csv/transp_csv.mod @@ -0,0 +1,70 @@ +# A TRANSPORTATION PROBLEM +# +# This problem finds a least cost shipping schedule that meets +# requirements at markets and supplies at factories. +# +# References: +# Dantzig G B, "Linear Programming and Extensions." +# Princeton University Press, Princeton, New Jersey, 1963, +# Chapter 3-3. + +set I; +/* canning plants */ + +set J; +/* markets */ + +set K dimen 2; +/* transportation lane */ + +set L; +/* parameters */ + +param a{i in I}; +/* capacity of plant i in cases */ + +param b{j in J}; +/* demand at market j in cases */ + +param d{i in I, j in J}; +/* distance in thousands of miles */ + +param e{l in L}; +/* parameters */ + +param f; +/* freight in dollars per case per thousand miles */ + +table tab_plant IN "CSV" "plants.csv" : + I <- [plant], a ~ capacity; + +table tab_market IN "CSV" "markets.csv" : + J <- [market], b ~ demand; + +table tab_distance IN "CSV" "distances.csv" : + K <- [plant, market], d ~ distance; + +table tab_parameter IN "CSV" "parameters.csv" : + L <- [parameter], e ~ value ; + +param c{i in I, j in J} := e['transport cost'] * d[i,j] / 1000; +/* transport cost in thousands of dollars per case */ + +var x{(i,j) in K} >= 0; +/* shipment quantities in cases */ + +minimize cost: sum{(i,j) in K} c[i,j] * x[i,j]; +/* total transportation costs in thousands of dollars */ + +s.t. supply{i in I}: sum{(i,j) in K} x[i,j] <= a[i]; +/* observe supply limit at plant i */ + +s.t. demand{j in J}: sum{(i,j) in K} x[i,j] >= b[j]; +/* satisfy demand at market j */ + +solve; + +table tab_result{(i,j) in K} OUT "CSV" "result.csv" : + i ~ plant, j ~ market, x[i,j] ~ shipment; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/dbf/ForestMgt_Model_I_GIS_dbf.mod b/resources/3rdparty/glpk-4.57/examples/dbf/ForestMgt_Model_I_GIS_dbf.mod new file mode 100644 index 000000000..204846763 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/dbf/ForestMgt_Model_I_GIS_dbf.mod @@ -0,0 +1,226 @@ +# Model I Forest Estate Modelling using GLPK/MathProg +# Reading and writing dbf files + +# by Noli Sicad --- nsicad@gmail.com +# 18 December 2009 + +# Forest Management 4th Edition +# by Lawrence Davis, K. Norman Johnson, Pete Bettinger, Theodore Howard +# Chapter 11 - Daniel Pickett +# http://warnell.forestry.uga.edu/Warnell/Bettinger/mgtbook/index.htm + +# Model I Formulation + +/* Note: This is not the full LP model mentioned in the book. +Some of the constraints are deliberately omitted in this model for the purpose of clarity. + +The features of MathProg in this example are: +* reading and writing dbf from regular dbf files, +* reading dbf file (database of shapefile (stands.shp)) (e.g. area parameter), +* using the area data in the constraints and +* writing dbf file from result of LP model. + +Model I - Harvest Scheduling formulation for Sustainable Forest Management (SFM) + +Features are: +* Net Present Value for the objective function (Revenue - Cost) +* Harvest Constraints by period - Sustainable Yield per Period +* Even-Flow Constraint / Volume - Harvest Flow Constraint - Alpha (1-Apha) +* Even-Flow Constraint / Volume - Harvest Flow Constraint - Beta (1 +Beta) +* Forest / Land Constraint -- Total Area of the forest +* Forest Stand Constraint -- Individual stands + +What is next? -- Forest Mgt Carbon Accounting for Climate Change + +Note: The model file that the data containing in +the dbf files is public domain material (so it is compatible with the +GNU GPL) and data can be found in +http://warnell.forestry.uga.edu/Warnell/Bettinger/mgtbook/index.htm + +# Noli Sicad --- nsicad@gmail.com + +*/ + +set G_STAND_TYPE; # A, B, C + +set I_CULTURAL_PRES; +set J_MGT_YEAR; + +param K_PERIOD; +param Forest_Cost{G_STAND_TYPE,I_CULTURAL_PRES, J_MGT_YEAR}; # cost + +param Yield_Table_Vol{G_STAND_TYPE, I_CULTURAL_PRES, J_MGT_YEAR, 1..K_PERIOD} >= 0; + + +param Alpha >= 0; +param Beta >= 0; + +param TCost_Table{G_STAND_TYPE, I_CULTURAL_PRES, J_MGT_YEAR, 1..K_PERIOD} >= 0; + +param NetRev_Table{G_STAND_TYPE, I_CULTURAL_PRES, J_MGT_YEAR, 1..K_PERIOD}; + + +var XForestLand{g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} >= 0; + + +#reading dbf tables +table tab IN "xBASE" "standtype.dbf": G_STAND_TYPE <- [STAND]; +display G_STAND_TYPE; + + +table tab2 IN "xBASE" "cultural_pres.dbf": I_CULTURAL_PRES <- [CUL_PRES]; +display I_CULTURAL_PRES; + +table tab3 IN "xBASE" "mgt_year.dbf": J_MGT_YEAR <- [MGT_YEAR]; +display J_MGT_YEAR; + +/* +param Forest_Cost{G_STAND_TYPE,I_CULTURAL_PRES, J_MGT_YEAR} default 0; # cost +*/ + +set S1, dimen 3; +table tab4 IN "xBASE" "Forest_Cost.dbf": S1 <- [STAND, CUL_PRES, MGT_YEAR],Forest_Cost ~FCOST; +display Forest_Cost; + +set S2, dimen 4; +table tab5 IN "xBASE" "Yield_Table_Vol.dbf": S2 <- [STAND, CUL_PRES, MGT_YEAR, PERIOD],Yield_Table_Vol ~YIELD; +display Yield_Table_Vol; + +set S3, dimen 4; +table tab5 IN "xBASE" "TCost_Table.dbf": S3 <- [STAND, CUL_PRES, MGT_YEAR, PERIOD],TCost_Table ~TCOST; +display TCost_Table; + + +set S4, dimen 4; +table tab5 IN "xBASE" "NetRev_Table.dbf": S4 <- [STAND, CUL_PRES, MGT_YEAR, PERIOD],NetRev_Table ~NETREV; +display NetRev_Table; + + +param MGT; + +param Area_Stand_Indi{g in G_STAND_TYPE, m in 1..MGT} default 0; + +set ST, dimen 2; +table tab5 IN "xBASE" "stands.dbf": ST <- [VEG_TYPE, MGT], Area_Stand_Indi ~ACRES; +display Area_Stand_Indi; + +param Area_Stand_Type{g in G_STAND_TYPE}:= sum {m in 1..MGT } Area_Stand_Indi[g,m]; +display Area_Stand_Type; + + +param Total_Area := sum {g in G_STAND_TYPE, m in 1..MGT } Area_Stand_Indi[g,m]; +display Total_Area; + +param Harvest_Min_Vol_Period; + + +var NetPresentValue; + +# Objective function +maximize Net_Present_Value: NetPresentValue; + +subject to NPV: + NetPresentValue = sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Forest_Cost[g,i,j] * XForestLand[g,i,j]; + +# Harvest Constraint by Period +subject to Harvest_Period_H {k in 1..K_PERIOD}: + sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] >= Harvest_Min_Vol_Period; + + +#Even-Flow Constraint / Volume - Harvest Flow Constraint - Alpha +subject to Even_Flow_Constaints_Alpha {k in 6..K_PERIOD-1}: + (1 - Alpha) * sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] - + sum {g in G_STAND_TYPE,i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k+1] * XForestLand[g,i,j] <= 0; + +# Even-Flow Constraint / Volume - Harvest Flow Constraint - Beta +subject to Even_Flow_Constaints_Beta {k in 6..K_PERIOD-1}: + (1 + Beta) * sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] - + sum {g in G_STAND_TYPE,i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k+1] * XForestLand[g,i,j] >= 0; + +# Forest / Land Constraints +subject to Total_Area_Constraint: + sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} XForestLand[g,i,j] <= Total_Area; +display Total_Area; + +# Forest / Land Constraints for A B C +subject to Area {g in G_STAND_TYPE}: + sum {i in I_CULTURAL_PRES,j in J_MGT_YEAR} XForestLand[g,i,j] = Area_Stand_Type[g]; + + + +solve; +#RESULT SECTION +printf '#################################\n'; +printf 'Forest Management Model I - Noli Sicad\n'; +printf '\n'; +printf 'Net Present Value = %.2f\n', NetPresentValue; +printf '\n'; + +printf '\n'; +printf 'Variables\n'; +printf 'Stand_Type Age_Class Mgt_Presc Sign Value \n'; +printf{g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR}:'%5s %10s %11s = %10.2f\n', g,i,j, XForestLand[g,i,j]; +printf '\n'; + +printf 'Constraints\n'; +printf 'Period Harvest Sign \n'; +for {k in 1..K_PERIOD} { + printf '%5s %10.2f >= %.3f\n', k, sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j], Harvest_Min_Vol_Period; + } + +# xbase (dbf) output +table Harvest{k in 1..K_PERIOD} OUT "xBASE" "HarvestArea1.dbf" "N(5)N(15,2)" : k ~ Period, (sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j]) ~ H_Area; + +# xbase (dbf) read +set S, dimen 2; +table tab2 IN "xBASE" "HarvestArea1.dbf": S <- [Period, H_Area]; +display S; + + + + +printf '\n'; +printf 'Constraint\n'; +printf 'Harvest Period\n'; +printf 'Type AgeClass PrescMgt Period Value\n'; +printf{g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR, k in 1..K_PERIOD}:'%5s %11s %11s %5s %10.2f\n', g,i,j, k, (Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j]); + + +printf 'Even_Flow_Constaint_Alpha (1-Alpha)\n'; +printf 'Period Sign \n'; +for {k in 6..K_PERIOD-1} { + printf "%s %10.2f <= %s\n", k, ((1 - Alpha) * sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] - sum {g in G_STAND_TYPE,i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k+1] * XForestLand[g,i,j]),0; + } +printf '\n'; + + +# Forest / Land Constraints +printf '\n'; +printf 'Total Area Constraint\n'; +printf 'Type AgeClass PrescMgt Value Sign Total_Area \n'; +printf '%5s <= %.3f\n',sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} XForestLand[g,i,j], Total_Area; + +printf 'Area\n'; +printf 'Area Value Sign Areas_Stand\n'; +for {g in G_STAND_TYPE} { + printf '%5s %10.2f <= %.3f\n', g, sum {i in I_CULTURAL_PRES,j in J_MGT_YEAR} XForestLand[g,i,j], Area_Stand_Type[g]; + } + + +#DATA SECTION + +data; + +# Most of the data has been moved to dbf format + +param MGT:=31; + +param K_PERIOD:= 7; + +param Alpha:= 0.20; +param Beta:= 0.20; + +param Harvest_Min_Vol_Period:= 12000; + +end; + diff --git a/resources/3rdparty/glpk-4.57/examples/dbf/Forest_Cost.dbf b/resources/3rdparty/glpk-4.57/examples/dbf/Forest_Cost.dbf new file mode 100644 index 0000000000000000000000000000000000000000..acb8dcb19300f8c5d1b4a5e7a63db53daadf93d1 GIT binary patch literal 1458 zcmaKrF;9gs6oq*j7Zc;|#Neud(o#AizUQJ(^T5H0(aFTYKjc3ZS|FUmwH+XoueV?C zf%C&|cbg>1Z!%uDqwVVBW0-En+XW%b`*Z(x+PA~>QF{OK)b$_x`ZT=r>n~~jp?Ph) zFz44_pCNFS*6B3zug{$~OShX%R(E@(ET9?e zRKj$P=G`ImUB^oa${^EbFja{e-0!X<-<(?+WZDdNDnVZvgG^&j@sVe`M)MrcsybeL zD}zj%!Bm%KursSTw=#%IGX|Mf2AM`(v2UhpG|&5Re%JBhTNz~940e1oZ3Z{KFJ80` zMs(j`ME4Cwv~`iHyKgYc-8UG~${;L^=U~arbd9#_U_>i}HJdt%quge2vkpeIGRT#f z!Oe^$clDcTHn=69{M97|;om1Ybwtqd}ax?$1~W7aW@s49&@dR&zAt}AouQRM&h4Yfw;!J-WsqrQkZEO* zX=Tt?stq!&3^MKOiVQOCBTXxVKHD@YgG_G>ekg12$<}ZkJd~%SAq|7?%CqZ`hQSPN zUCh^s+%TBQ4TBll40bAk1zrc^+)N`n91hFx5RE~MFS(ULrp@4#sl*JXEc zM7E_%GuZLXbl+gPGsW*&Z1DM7Z0BV}!(fJn!3^!YSg$0*N?tLo5Wsq|#gG?)fOe=$aW@v*<`#nVlnf8&Ul|i3vnv_ANl|iPJL0_ph z$h0!Zw67~N$h40%tql5XejSX@2B!N4qh~;@itYLx(J+{yVK76Ziwq5e85(miL&IQ9 z!@~GVl6o$-RWqVtus!k-4TBjP1~W7aW@s3UY2VlAEG}I#?d|iK7SVoNO)G;w+h`q( zDp3YGw=(D})drbX2ATGCMFyGnk*3ug^w~!1VDZiL#^Bv@wl1&nbMe0X13aW*@Ogz8 z(lD5z(M5(fgY_w6SPAA}Cbt>vgslRi*qw=(dmzp^*ODn+s4yZR4wN7|hgd22)+aV5V*ujA>VC z!XVSiAk#3Esl>LOuisytA9ho7ENy)C4TG87${^?N8;qWGF$bTo+*Wr)!(fJn!3^!Y zSg$0*N?~I)GU&4f_k+#RVOkkvS{d|}YJ*HGgG~FnB7;o(NYiQ#`fS1dVB?$VzQJ<$=vO{( zuw9WO8U`~o3}$F_k)dHQLt_qRXc&xXSXeG<-X|aVVvuPcX&MIGH8#o(gBcnIGc*il zXc&xX-eiXf%>Fw^!S8_7b)0C*>&7{P;ZM7yo5 zJH|^5&LGoaFjYwyOm*oDawTD~Qwj8yFvv9ANg8B2qTR8aRWV+CJA+Jz!Bm%Fu;ZI^ zJA+VZ!XVSmAk$En^v!fcyORX%3`Vx{bi!cAH`8Ho<$L?6bx_fLgNj}Zwkw;Wp^L_# zqQhXS%P^Rt!{DUr1`ESESnFmwqSZR6=*3{W+ADf7n5jDqu4a|W9R^eMVo=u&eI*Ps z9R@p4;YAVD%m2 z#rI-R`(}DEsC_dX23Pase6$Xx=)OUfyKhj@&_&~0(S3u8UJSOr73~ay1)hTw?_+Cj zrZMs~7);~_g9#c8CTK92puwP|u`k+DCunDob7Q1@2JA+uMH^{Uz z$TZfa3^I+8r=3B}HcieT(<_5-%hLPs#*Ws(<4rv`3~4a9EnN<2FqojDi=(py4F(f5 z7);P%uu}uW;&wn`R?T5?+}f_7%vaa8Du&PPE(?iFqrDn8RSaBV5bu3D`Ajn zxRdOX>4>(c=gN1C7vIhx(_t{xWf<)E=G@L8RGKizv@^&w)Fpj09ntpWRILy(UVJ-) zOozdaZ>GcG%6HwF!r!ylVEq=yd#PwJn4rO6g2pb`psEB6CUS$p1RVzVepDrBL41oF zgG^)Ob322WP3&fdl{kZ(+Zklq8N|N4L8kFe${^DidD_iE%r;HVAk)qu)6O7P>J2jO z3^I*%DT7R73#qlf^4F;PPSjHF}F{mrSF5e$y0<*LvC+#B8H=P*vg# za&Bi3EA4F(grVGbtfFxaUCEbuxgb2A;$d@gRfjPdf&oI$3;;CyZv<_?3YE}cQH zBn);cfxZ$3nT9(_-%Lj|pNktOFZ6&2&Wb zxw!Eir7v)PbtON`ua)ZGH9R~N$ zN>zdu#J9Mqn`w-EZf6j)iF5I=5@(QeJA+I+gV>ih$TZ$b8DttGPrEsY*~EUZ@y)a| z$h0$vm3o6rJA+JPUCJQS7+kf$TUVgPZSLX6S=`)f(C;L8Vn|AFeqv4i{@a0b_O{&M#?vi vkG>@J=`igKGVKg9?F{0x_6C`D2ARgXltHF3^0YIE*+%PNeL76H24DRHrn}G@ literal 0 HcmV?d00001 diff --git a/resources/3rdparty/glpk-4.57/examples/dbf/Yield_Table_Vol.dbf b/resources/3rdparty/glpk-4.57/examples/dbf/Yield_Table_Vol.dbf new file mode 100644 index 0000000000000000000000000000000000000000..b0d051ba77e25f794cf00870bc2205d85e781817 GIT binary patch literal 11786 zcmb7}v2N8s5Jdxs1_{wqy)TI3gd|Xg5D*ds6ri9=Nrgng5At6WI9?#2`u5`8-}5i)Pws1i$GfxL-_P{@+t2GC)4y=} zjp*oj|KOme4{_{4q>t`IKf9$5Ph#%lTY8r(Ik^*kdQ00%XkoX5L0gH^h>lK8msp>x zNCuUL!3~wb;D#=fL9GM^Z6)k08&sNSa#vnyL`To}k5}`J_1Skas5A_2=n@94Z_S+y zveIl&>10r8*5!OFjp$jXlR;#guMP}a-%7(^=lk$Z`=F!81|3at#7S_23_6kD;rdrXUe&8 zY_|`#F0tMj%(-dM`PSSpXniXUgVs0imTXYzWKe0=<(w#usM`mdZ>-P0X)x!eLFZd@ z!(iw8MZFJhpvMMX?y*5fvkP_N=&?aZ(_qe>4AMe1gRK&!8M#WhUOf-G+{vKkP6m}u z29-_*IT_iY(mazhs5GNYCxgsZ-No(dD4h%{oeZ+lY*6WBP-)iX3@Xhi(`g2ot$H48 zzLj1Xd^vBt%O|`SPtR}O(@J_}u%uT8OB!8Fhq02C!7}%121^r!b%(~0qo^$iAugZzWKe0=<$NoRXj;B!>#h#gXWz-7(lBU!D-DC4@AhQM@3Sg{jvgCy z^w^-I*@gOc^w^-I#|9k@gPre2(?T|=G$Yp~*Uj_b|EY47B!ike8B{tMR5}^tWMqR% z^Gwd5(u^{l3^H4F7q_dUbTX)PGRR7^L8X&HrCFCVs5GNYrx|26^E}wy4N8vgN_~>bTqrjm5dF# z++%}|hQZEvqiLaaprgkI9X&Sa zXm+6n9X&Sa=10spWKij3Q0ZillaUQ7%`-WJN;ArI tGRSPzKG?2~(#fFG$sjAu29-_*m1bSepwf&ooo0~Ps(rBeR=PL%^be03!(;#e literal 0 HcmV?d00001 diff --git a/resources/3rdparty/glpk-4.57/examples/dbf/cultural_pres.dbf b/resources/3rdparty/glpk-4.57/examples/dbf/cultural_pres.dbf new file mode 100644 index 0000000000000000000000000000000000000000..76c8dfab5a64567d2c045041e7e8c94922c090a4 GIT binary patch literal 96 xcmZS13NU|?`$-~y7Ez&X?>J|M_77%1ZhlI28G!m9uShA@VL5u9Zy1pqn72h#um literal 0 HcmV?d00001 diff --git a/resources/3rdparty/glpk-4.57/examples/dbf/mgt_year.dbf b/resources/3rdparty/glpk-4.57/examples/dbf/mgt_year.dbf new file mode 100644 index 0000000000000000000000000000000000000000..043ba5a0d7cf4c384ad401cdf102bd7509eaeb15 GIT binary patch literal 106 zcmZS13IU|?`$-~y7Ez}Gz_KGM}O2q@zWlI28G!mE&*UJ_qmr~m|DmJys~3}=}D GSyBKKG!E_n literal 0 HcmV?d00001 diff --git a/resources/3rdparty/glpk-4.57/examples/dbf/stands.dbf b/resources/3rdparty/glpk-4.57/examples/dbf/stands.dbf new file mode 100644 index 0000000000000000000000000000000000000000..5ecfd2429cbfd621346f6d951d07ce3c443ab339 GIT binary patch literal 4323 zcmb_fOK&4Z5YB4hwg|+L3-b#~T~+-&I>AIMZB|hdkoM#wrW6JQ_QaBD z*)u)UkFV?XRn7aaAAbD#=H}*~cYovhx^14eoBsB*-9Nnl@0`c&)5nMH%l7H!=H&S1 z?rHnnmYf{_eS5!q`SQ5MlslXDeVe<#-u?Dz_t>_m>*w)@`i9R~sox)Ne;se?__y!IW4k}UY(D?ex+nL?`No2i`+v7AOH5gP zB4x$HqLMO|;HLu;rl|6CpXN{gTTmtWpK@WW~E5@*>e+6$V@Rt%&0Zg3N}33vB3u@zzb^%h~fFM*#`+fk$d9{(VO&T(T~ zfg=Sq-y6zj&N)&}rA}oLL_xej`nPRAdA^u{FmZt4Jp!*u&u|uKLYwp~p28cR-;{sO z_QUf%HG%dDs9_G2kRUGI$A8;&?oy~Uud?w%QtubcGUHL{A$;<72&52GU-7~IN1zd0hHp4$lNWZfY-1Ne?lXNSEl?X{Y*Ph zyipHB?8te*M=j=Vwh9fJ;9RbSuhLHuV$N+Eut3jnvCeuaGb7`5RU!SrFRp;ECN?wE zWF7_rLnGk$R9N@Ydq9fsX9ZbG@&60_WP3r(n~5ca?A##TC2K_7Tew;a8Oiq=_=D{y z>BVf1BdLS69jcm^a#D(UFP zkLB+C_R!$kU?bgA#gC(8~Hu0jGH_2YQg?uzG{^>RsYenP=z11PlN?WOiB zeDH55ze+z_wqvmsTRtGdX_{e0pb3e})Pi0E#J2-5}i@5d~swYz^=@-a34ndHTv$?KJo)LMr3o2wp@oa(u7#I3vwO zqeN>Z5;EWw@aDrf0!SU5<7SGtaxlqJ5pb+1%{jp4QAKAP~kAi&~L#)94*d>Q@ZzNn4oem#Xz193NU|?`$-~y7EAUMR)&jljv45B#El<+DzD!_mfjG^ERV@Ux30vrbK literal 0 HcmV?d00001 diff --git a/resources/3rdparty/glpk-4.57/examples/dea.mod b/resources/3rdparty/glpk-4.57/examples/dea.mod new file mode 100644 index 000000000..ba610735a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/dea.mod @@ -0,0 +1,222 @@ +/* Data Envelopment Analysis (DEA) + * + * DEA quantifies the relative efficiency of decision making units (DMUs) by + * finding the efficient frontier in multiple input multiple output data. The + * inputs are resources (eg. number of employees, available machines, ...), + * the outputs are productive outputs (eg. contracts made, total sales, ...). + * The method is non-parametric. More details are available in the paper + * below. + * + * Models according to: Seiford, Threall, "Recent developments in DEA", 1990. + * + * Implementation: Sebastian Nowozin + */ + +### SETS ### + +set dmus; # Decision Making Units (DMU) +set inputs; # Input parameters +set outputs; # Output parameters + + +### PARAMETERS ### + +param input_data{dmus,inputs} >= 0; +param output_data{dmus,outputs} >= 0; + + +### PROGRAM ### + +var theta{dmus} >= 0; +var lambda{dmus,dmus} >= 0; + +minimize inefficiency: sum{td in dmus} theta[td]; + +s.t. output_lower_limit{o in outputs, td in dmus}: + sum{d in dmus} lambda[d,td]*output_data[d,o] >= output_data[td,o]; +s.t. input_upper_limit{i in inputs, td in dmus}: + sum{d in dmus} lambda[d,td]*input_data[d,i] <= theta[td]*input_data[td,i]; + + s.t. PI1{td in dmus}: + sum{d in dmus} lambda[d,td] = 1; +/* +possibilities: + i) (no constraint) + ii) s.t. PI1{td in dmus}: + sum{d in dmus} lambda[d,td] <= 1; + iii) s.t. PI1{td in dmus}: + sum{d in dmus} lambda[d,td] >= 1; +*/ + + +### SOLVE AND PRINT SOLUTION ### + +solve; + +printf "DMU\tEfficiency\n"; +for {td in dmus} { + printf "%s\t%1.4f\n", td, theta[td]; +} + +### DATA ### + +data; + +set dmus := 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 + 61 62 63 64 65 66 67 68 69 ; +set inputs := AvgInventory LaborCost OperatingCost Population ; +set outputs := PrescrVol kDollarValue ; + +param input_data default 0.0 : + + AvgInventory LaborCost OperatingCost Population := + +1 8000 17030 1280 1410 +2 9000 25890 2779 1523 +3 13694 29076 2372 1354 +4 4250 17506 1385 822 +5 6500 23208 639 746 +6 7000 12946 802 1281 +7 4500 18001 1130 1016 +8 5000 14473 1097 1070 +9 27000 31760 5559 1694 +10 21560 50972 15010 1910 +11 15000 39523 4799 1745 +12 8500 13076 3489 1353 +13 35000 35427 1704 500 +14 18000 27554 2882 1016 +15 59750 53848 14208 2500 +16 19200 38253 1480 2293 +17 40000 109404 83016 2718 +18 8466 18198 1278 2877 +19 16000 40891 7599 4150 +20 10000 45444 5556 4421 +21 25000 35623 2121 3883 +22 14000 20192 5515 3519 +23 12500 34973 10475 32366 +24 17260 32284 14498 3393 +25 7000 17920 7585 4489 +26 14000 42094 3742 2217 +27 16400 35422 14236 4641 +28 13000 19100 3529 5968 +29 30000 72167 8656 8715 +30 12530 19970 1714 5968 +31 31500 39183 4919 5607 +32 10000 32048 3483 7324 +33 22000 68877 12279 8685 +34 10000 29812 3332 8685 +35 16000 47686 2507 5420 +36 10000 33415 4738 7703 +37 9000 12359 4603 4665 +38 16439 23614 2989 6317 +39 14500 36069 1793 31839 +40 39000 76307 9539 15619 +41 24927 40706 12661 30213 +42 13858 39267 4609 34719 +43 33375 29509 11323 31839 +44 29044 44482 5542 34719 +45 32257 61365 20550 32366 +46 8800 49671 3306 43561 +47 47000 40425 10396 31263 +48 12000 33034 4915 31263 +49 28000 69163 4688 15173 +50 13300 28931 16735 73064 +51 13500 29758 4260 62309 +52 24000 40927 8285 23166 +53 16000 40403 2131 99836 +54 17000 38730 2539 60348 +55 25000 35978 2502 99836 +56 16000 37509 6278 99836 +57 20000 46950 10715 85925 +58 14000 35966 3144 85925 +59 22000 68318 8015 108987 +60 21879 69537 7778 108987 +61 15000 25425 2812 201404 +62 10000 19508 2454 201404 +63 20000 28191 3367 201404 +64 18000 37073 8624 108987 +65 19051 23763 3496 201404 +66 15000 28642 3366 201404 +67 10000 35919 3868 201404 +68 24000 54653 26494 108987 +69 1800 6276 3413 60348 + ; + +param output_data default 0.0 : + + PrescrVol kDollarValue := + +1 12293 61.00 +2 18400 92.00 +3 16789 92.65 +4 10700 45.00 +5 9800 50.00 +6 6500 29.00 +7 8200 56.00 +8 8680 45.00 +9 33800 183.00 +10 23710 156.00 +11 24000 120.00 +12 17500 75.00 +13 25000 130.00 +14 26000 122.00 +15 26830 178.513 +16 16600 106.00 +17 90000 450.00 +18 11140 73.624 +19 25868 136.00 +20 32700 191.295 +21 29117 152.864 +22 18000 100.00 +23 11100 60.00 +24 23030 137.778 +25 10656 58.00 +26 24682 152.095 +27 26908 120.00 +28 16464 80.00 +29 57000 321.00 +30 17532 94.747 +31 30035 168.00 +32 16000 100.00 +33 63700 277.00 +34 18000 90.00 +35 27339 139.134 +36 19500 116.00 +37 13000 80.00 +38 15370 102.00 +39 18446 90.00 +40 56000 260.00 +41 73845 364.951 +42 28600 145.00 +43 27000 243.00 +44 52423 279.816 +45 73759 363.388 +46 20500 80.00 +47 27100 115.00 +48 15000 110.00 +49 50895 277.852 +50 19707 128.00 +51 17994 78.80 +52 36135 167.222 +53 30000 153.00 +54 26195 125.00 +55 28000 216.00 +56 24658 152.551 +57 36850 190.00 +58 29250 183.69 +59 50000 250.00 +60 40078 265.443 +61 20200 110.00 +62 12500 75.00 +63 30890 195.00 +64 31000 175.00 +65 31277 192.992 +66 11500 75.00 +67 30000 175.668 +68 38383 190.00 +69 2075 8.650 + ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/diet.mod b/resources/3rdparty/glpk-4.57/examples/diet.mod new file mode 100644 index 000000000..6d36391af --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/diet.mod @@ -0,0 +1,99 @@ +# STIGLER'S NUTRITION MODEL +# +# This model determines a least cost diet which meets the daily +# allowances of nutrients for a moderately active man weighing 154 lbs. +# +# References: +# Dantzig G B, "Linear Programming and Extensions." +# Princeton University Press, Princeton, New Jersey, 1963, +# Chapter 27-1. + +set N; +/* nutrients */ + +set F; +/* foods */ + +param b{N}; +/* required daily allowances of nutrients */ + +param a{F,N}; +/* nutritive value of foods (per dollar spent) */ + +var x{f in F} >= 0; +/* dollars of food f to be purchased daily */ + +s.t. nb{n in N}: sum{f in F} a[f,n] * x[f] = b[n]; +/* nutrient balance (units) */ + +minimize cost: sum{f in F} x[f]; +/* total food bill (dollars) */ + +data; + +param : N : b := + Calorie 3 /* thousands */ + Protein 70 /* grams */ + Calcium 0.8 /* grams */ + Iron 12 /* milligrams */ + Vitamin-A 5 /* thousands IUs */ + Vitamin-B1 1.8 /* milligrams */ + Vitamin-B2 2.7 /* milligrams */ + Niacin 18 /* milligrams */ + Vitamin-C 75 /* milligrams */ ; + +set F := Wheat Cornmeal Cannedmilk Margarine Cheese Peanut-B Lard + Liver Porkroast Salmon Greenbeans Cabbage Onions Potatoes + Spinach Sweet-Pot Peaches Prunes Limabeans Navybeans; + +param a default 0 + +: Calorie Protein Calcium Iron Vitamin-A Vitamin-B1 := +# (1000) (g) (g) (mg) (1000IU) (mg) + +Wheat 44.7 1411 2.0 365 . 55.4 +Cornmeal 36 897 1.7 99 30.9 17.4 +Cannedmilk 8.4 422 15.1 9 26 3 +Margarine 20.6 17 .6 6 55.8 .2 +Cheese 7.4 448 16.4 19 28.1 .8 +Peanut-B 15.7 661 1 48 . 9.6 +Lard 41.7 . . . .2 . +Liver 2.2 333 .2 139 169.2 6.4 +Porkroast 4.4 249 .3 37 . 18.2 +Salmon 5.8 705 6.8 45 3.5 1 +Greenbeans 2.4 138 3.7 80 69 4.3 +Cabbage 2.6 125 4 36 7.2 9 +Onions 5.8 166 3.8 59 16.6 4.7 +Potatoes 14.3 336 1.8 118 6.7 29.4 +Spinach 1.1 106 . 138 918.4 5.7 +Sweet-Pot 9.6 138 2.7 54 290.7 8.4 +Peaches 8.5 87 1.7 173 86.8 1.2 +Prunes 12.8 99 2.5 154 85.7 3.9 +Limabeans 17.4 1055 3.7 459 5.1 26.9 +Navybeans 26.9 1691 11.4 792 . 38.4 + +: Vitamin-B2 Niacin Vitamin-C := +# (mg) (mg) (mg) + +Wheat 33.3 441 . +Cornmeal 7.9 106 . +Cannedmilk 23.5 11 60 +Margarine . . . +Cheese 10.3 4 . +Peanut-B 8.1 471 . +Lard .5 5 . +Liver 50.8 316 525 +Porkroast 3.6 79 . +Salmon 4.9 209 . +Greenbeans 5.8 37 862 +Cabbage 4.5 26 5369 +Onions 5.9 21 1184 +Potatoes 7.1 198 2522 +Spinach 13.8 33 2755 +Sweet-Pot 5.4 83 1912 +Peaches 4.3 55 57 +Prunes 4.3 65 257 +Limabeans 38.2 93 . +Navybeans 24.6 217 . ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/dist.mod b/resources/3rdparty/glpk-4.57/examples/dist.mod new file mode 100644 index 000000000..f3d66b513 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/dist.mod @@ -0,0 +1,565 @@ +# DIST, a product distribution model +# +# References: +# Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language +# for Mathematical Programming." Management Science 36 (1990) 519-554. + +### SHIPPING SETS AND PARAMETERS ### + +set whse 'warehouses'; # Locations from which demand is satisfied + +set dctr 'distribution centers' within whse; + + # Locations from which product may be shipped + +param sc 'shipping cost' {dctr,whse} >= 0; + + # Shipping costs, to whse from dctr, in $ / 100 lb + +param huge 'largest shipping cost' > 0; + + # Largest cost allowed for a usable shipping route + +param msr 'minimum size restriction' {dctr,whse} logical; + + # True indicates a minimum-size restriction on + # direct shipments using this dctr --> whse route + +param dsr 'direct shipment requirement' {dctr} >= 0; + + # Minimum total demand, in pallets, needed to + # allow shipment on routes subject to the + # minimum size restriction + +### PLANT SETS AND PARAMETERS ### + +set fact 'factories' within dctr; + + # Locations where product is manufactured + +param rtmin 'regular-time total minimum' >= 0; + + # Lower limit on (average) total regular-time + # crews employed at all factories + +param rtmax 'regular-time total maximum' >= rtmin; + + # Upper limit on (average) total regular-time + # crews employed at all factories + +param otmin 'overtime total minimum' >= 0; + + # Lower limit on total overtime hours at all factories + +param otmax 'overtime total maximum' >= otmin; + + # Upper limit on total overtime hours at all factories + +param rmin 'regular-time minimums' {fact} >= 0; + + # Lower limits on (average) regular-time crews + +param rmax 'regular-time maximums' {f in fact} >= rmin[f]; + + # Upper limits on (average) regular-time crews + +param omin 'overtime minimums' {fact} >= 0; + + # Lower limits on overtime hours + +param omax 'overtime maximums' {f in fact} >= omin[f]; + + # Upper limits on overtime hours + +param hd 'hours per day' {fact} >= 0; + + # Regular-time hours per working day + +param dp 'days in period' {fact} > 0; + + # Working days in the current planning period + +### PRODUCT SETS AND PARAMETERS ### + +set prd 'products'; # Elements of the product group + +param wt 'weight' {prd} > 0; + + # Weight in 100 lb / 1000 cases + +param cpp 'cases per pallet' {prd} > 0; + + # Cases of product per shipping pallet + +param tc 'transshipment cost' {prd} >= 0; + + # Transshipment cost in $ / 1000 cases + +param pt 'production time' {prd,fact} >= 0; + + # Crew-hours to produce 1000 cases + +param rpc 'regular-time production cost' {prd,fact} >= 0; + + # Cost of production on regular time, + # in $ / 1000 cases + +param opc 'overtime production cost' {prd,fact} >= 0; + + # Cost of production on overtime, in $ / 1000 cases + +### DEMAND SETS AND PARAMETERS ### + +param dt 'total demand' {prd} >= 0; + + # Total demands for products, in 1000s + +param ds 'demand shares' {prd,whse} >= 0.0, <= 1.0; + + # Historical demand data, from which each + # warehouse's share of total demand is deduced + +param dstot {p in prd} := sum {w in whse} ds[p,w]; + + # Total of demand shares; should be 1, but often isn't + +param dem 'demand' {p in prd, w in whse} := dt[p] * ds[p,w] / dstot[p]; + + # Projected demands to be satisfied, in 1000s + +set rt 'shipping routes available' := + + {d in dctr, w in whse: + d <> w and sc[d,w] < huge and + (w in dctr or sum {p in prd} dem[p,w] > 0) and + not (msr[d,w] and sum {p in prd} 1000*dem[p,w]/cpp[p] < dsr[d]) }; + + # List of ordered pairs that represent routes + # on which shipments are allowed + +### VARIABLES ### + +var Rprd 'regular-time production' {prd,fact} >= 0; + + # Regular-time production of each product + # at each factory, in 1000s of cases + +var Oprd 'overtime production' {prd,fact} >= 0; + + # Overtime production of each product + # at each factory, in 1000s of cases + +var Ship 'shipments' {prd,rt} >= 0; + + # Shipments of each product on each allowed route, + # in 1000s of cases + +var Trans 'transshipments' {prd,dctr} >= 0; + + # Transshipments of each product at each + # distribution center, in 1000s of cases + +### OBJECTIVE ### + +minimize cost: sum {p in prd, f in fact} rpc[p,f] * Rprd[p,f] + + sum {p in prd, f in fact} opc[p,f] * Oprd[p,f] + + sum {p in prd, (d,w) in rt} sc[d,w] * wt[p] * Ship[p,d,w] + + sum {p in prd, d in dctr} tc[p] * Trans[p,d]; + + # Total cost: regular production, overtime + # production, shipping, and transshipment + +### CONSTRAINTS ### + +rtlim 'regular-time total limits': + + rtmin <= sum {p in prd, f in fact} + (pt[p,f] * Rprd[p,f]) / (dp[f] * hd[f]) <= rtmax; + + # Total crews must lie between limits + +otlim 'overtime total limits': + + otmin <= sum {p in prd, f in fact} pt[p,f] * Oprd[p,f] <= otmax; + + # Total overtime must lie between limits + +rlim 'regular-time limits' {f in fact}: + + rmin[f] <= sum {p in prd} + (pt[p,f] * Rprd[p,f]) / (dp[f] * hd[f]) <= rmax[f]; + + # Crews at each factory must lie between limits + +olim 'overtime limits' {f in fact}: + + omin[f] <= sum {p in prd} pt[p,f] * Oprd[p,f] <= omax[f]; + + # Overtime at each factory must lie between limits + +noRprd 'no regular production' {p in prd, f in fact: rpc[p,f] = 0}: + + Rprd[p,f] = 0; + +noOprd 'no overtime production' {p in prd, f in fact: opc[p,f] = 0}: + + Oprd[p,f] = 0; # Do not produce where specified cost is zero + +bal 'material balance' {p in prd, w in whse}: + + sum {(v,w) in rt} + Ship [p,v,w] + (if w in fact then Rprd[p,w] + Oprd[p,w]) = + + dem[p,w] + (if w in dctr then sum {(w,v) in rt} Ship[p,w,v]); + + # Demand is satisfied by shipment into warehouse + # plus production (if it is a factory) + # minus shipment out (if it is a distn. center) + +trdef 'transshipment definition' {p in prd, d in dctr}: + + Trans[p,d] >= sum {(d,w) in rt} Ship [p,d,w] - + (if d in fact then Rprd[p,d] + Oprd[p,d]); + + # Transshipment at a distribution center is + # shipments out less production (if any) + +### DATA -- 3 PRODUCTS ### + +data; + +set prd := 18REG 24REG 24PRO ; + +set whse := w01 w02 w03 w04 w05 w06 w08 w09 w12 w14 w15 w17 + w18 w19 w20 w21 w24 w25 w26 w27 w28 w29 w30 w31 + w32 w33 w34 w35 w36 w37 w38 w39 w40 w41 w42 w43 + w44 w45 w46 w47 w48 w49 w50 w51 w53 w54 w55 w56 + w57 w59 w60 w61 w62 w63 w64 w65 w66 w68 w69 w71 + w72 w73 w74 w75 w76 w77 w78 w79 w80 w81 w82 w83 + w84 w85 w86 w87 w89 w90 w91 w92 w93 w94 w95 w96 + w98 x22 x23 ; + +set dctr := w01 w02 w03 w04 w05 w62 w76 w96 ; + +set fact := w01 w05 w96 ; + +param huge := 99. ; + +param rtmin := 0.0 ; +param rtmax := 8.0 ; + +param otmin := 0.0 ; +param otmax := 96.0 ; + +param rmin := w01 0.00 w05 0.00 w96 0.00 ; +param rmax := w01 3.00 w05 2.00 w96 3.00 ; + +param omin := w01 0.0 w05 0.0 w96 0.0 ; +param omax := w01 48.0 w05 0.0 w96 48.0 ; + +param hd := w01 8.0 w05 8.0 w96 8.0 ; + +param dp := w01 19.0 w05 19.0 w96 19.0 ; + +param wt := 18REG 47.3 24REG 63.0 24PRO 63.0 ; + +param tc := 18REG 40.00 24REG 45.00 24PRO 45.00 ; + +param dt := 18REG 376.0 24REG 172.4 24PRO 316.3 ; + +param cpp := 18REG 102. 24REG 91. 24PRO 91. ; + +param dsr := w01 96. w02 96. w03 96. w04 96. w05 96. + w62 96. w76 96. w96 96. ; + +param pt (tr) : + + 18REG 24REG 24PRO := + +w01 1.194 1.429 1.429 +w05 1.194 1.509 1.509 +w96 0.000 1.600 1.600 ; + +param rpc (tr) : + + 18REG 24REG 24PRO := + +w01 2119. 2653. 2617. +w05 2489. 3182. 3176. +w96 0. 2925. 2918. ; + +param opc (tr) : + + 18REG 24REG 24PRO := + +w01 2903. 3585. 3579. +w05 0. 0. 0. +w96 0. 3629. 3622. ; + +param sc default 99.99 (tr) : + + w01 w02 w03 w04 w05 w62 w76 w96 := + +w01 . 2.97 1.14 2.08 2.37 1.26 2.42 1.43 +w02 4.74 . 4.17 6.12 7.41 3.78 7.04 5.21 +w03 2.45 4.74 . 3.67 2.84 0.90 2.41 2.55 +w04 1.74 5.03 2.43 . 3.19 2.45 2.69 0.58 +w05 2.70 5.16 2.84 2.85 . 3.26 3.34 2.71 +w06 1.99 4.17 2.13 2.19 2.52 2.06 2.00 1.51 +w08 0.21 2.92 1.24 2.07 2.29 1.25 2.32 1.55 +w09 0.66 3.76 1.41 2.47 1.82 1.66 . 1.87 +w12 1.38 3.83 1.68 2.53 2.39 . 1.96 1.94 +w14 2.47 1.58 2.40 3.59 3.85 2.25 . 3.05 +w15 1.06 4.95 2.48 1.39 3.41 1.96 . 1.02 +w17 0.88 3.39 1.46 2.00 2.67 1.45 . 1.46 +w18 7.90 6.57 7.79 9.59 10.81 . . 6.70 +w19 1.42 4.12 1.96 1.99 3.52 1.88 . 1.26 +w20 3.03 1.59 2.34 4.76 3.98 1.88 . 3.73 +w24 1.58 2.80 2.27 2.87 3.19 1.31 . 2.05 +w25 1.51 5.05 2.74 0.57 2.98 . 2.95 0.27 +w26 1.75 3.61 2.70 1.54 4.07 3.52 . 1.03 +w27 2.48 6.87 3.17 1.59 2.08 3.45 . 0.99 +w28 2.05 6.83 2.97 1.13 2.91 . . 1.26 +w29 4.03 3.68 4.46 3.20 5.50 . . 3.20 +w30 2.48 5.78 2.99 2.24 1.79 3.10 . 1.39 +w31 2.34 5.41 2.87 1.67 1.66 . . 1.39 +w32 14.36 . . . . . . . +w33 3.87 4.27 5.11 3.48 5.66 4.03 . 3.05 +w34 3.26 4.80 3.21 2.70 4.14 . . 1.77 +w35 2.34 2.84 2.89 3.35 3.78 2.68 . 2.52 +w36 2.43 5.69 2.96 2.95 1.02 2.61 1.07 2.54 +w37 2.23 4.64 2.41 1.99 4.30 2.61 . 1.44 +w38 4.66 4.36 5.23 3.04 4.46 . . 3.82 +w39 1.11 3.51 1.10 2.53 3.07 1.12 . 2.23 +w40 2.99 4.78 4.23 1.57 3.92 . . 1.80 +w41 4.93 4.00 5.43 4.45 6.31 . . 3.81 +w42 3.86 6.55 5.03 2.11 4.41 . . 2.63 +w43 4.61 4.45 3.77 1.22 4.31 . . 2.35 +w44 2.05 4.48 1.06 3.70 3.46 1.10 . 3.21 +w45 0.92 3.42 1.58 3.04 1.82 1.94 . 2.52 +w46 1.36 2.44 0.95 3.08 2.78 0.39 2.16 2.37 +w47 1.30 3.39 1.60 2.49 4.29 2.04 . 1.68 +w48 1.65 3.78 1.03 2.97 2.21 1.31 . 2.74 +w49 1.96 3.00 1.50 3.24 3.68 1.00 . 2.99 +w50 0.90 4.14 1.60 1.95 3.61 1.61 . 1.52 +w51 1.59 3.95 0.25 2.96 2.58 1.00 2.41 2.71 +w53 1.59 3.79 1.28 3.12 3.10 0.89 . 2.98 +w54 1.72 4.36 1.61 2.92 2.34 1.91 1.97 3.05 +w55 2.45 2.73 2.21 4.47 4.30 2.57 . 4.48 +w56 1.10 3.73 1.59 2.74 2.33 1.45 . 2.44 +w57 0.95 3.39 1.37 2.30 2.47 1.15 . 1.95 +w59 3.29 5.35 3.32 3.81 1.52 3.38 1.34 4.08 +w60 2.41 6.12 2.46 3.65 2.35 . 1.37 4.06 +w61 3.32 5.50 3.41 3.38 1.23 . 0.99 4.28 +w62 1.12 3.00 0.82 3.22 2.95 . 3.33 2.53 +w63 3.59 6.36 3.25 4.12 1.84 3.59 1.46 4.03 +w64 1.85 4.45 2.17 3.43 2.13 2.03 . 4.02 +w65 2.78 4.79 2.81 2.94 1.54 2.90 1.07 2.94 +w66 3.90 5.79 3.05 3.65 1.36 3.39 1.22 3.57 +w68 2.61 5.20 2.90 2.34 1.68 3.19 1.48 2.31 +w69 2.94 5.21 2.78 3.43 0.21 3.26 0.68 2.54 +w71 2.06 4.98 2.38 2.44 1.59 2.97 1.05 2.55 +w72 2.61 5.50 2.83 3.12 1.35 3.23 0.88 2.99 +w73 8.52 6.16 8.03 8.83 10.44 7.38 10.26 . +w74 6.11 5.46 9.07 9.38 10.80 . . 8.25 +w75 2.66 4.94 2.87 3.69 1.52 3.15 1.24 4.00 +w76 1.99 5.26 2.23 3.36 0.58 3.17 . 2.50 +w77 4.32 3.07 5.05 3.88 6.04 . . 4.15 +w78 5.60 2.59 5.78 5.56 7.10 . . 5.60 +w79 4.25 2.32 4.93 4.57 6.04 . . 4.58 +w80 5.94 4.00 5.60 7.02 9.46 . . 7.51 +w81 5.39 2.21 5.10 6.22 6.46 . . 6.58 +w82 8.80 5.69 9.29 9.88 11.69 8.63 11.52 . +w83 4.40 . 5.24 5.21 5.81 3.91 7.04 5.33 +w84 5.87 5.43 6.17 5.70 7.63 . . 5.70 +w85 3.90 3.65 3.38 4.57 5.64 3.05 . 5.04 +w86 5.48 2.10 5.70 6.37 7.33 . . 6.19 +w87 8.88 5.54 9.50 9.71 11.64 8.85 11.68 . +w89 4.62 4.01 4.03 6.30 6.30 3.81 . 7.77 +w90 4.35 2.72 4.61 4.01 5.60 . . 3.20 +w91 7.61 4.42 7.83 6.85 8.79 . . 7.66 +w92 7.15 2.69 6.91 7.20 . . . 7.06 +w93 3.17 3.95 4.37 3.74 5.05 . . 2.40 +w94 1.21 3.07 0.90 2.74 3.17 . 2.63 2.39 +w95 5.82 3.29 6.55 7.06 11.47 . . 7.83 +w96 1.77 5.20 2.72 0.59 3.47 2.48 . . +w98 3.04 1.92 3.64 3.70 4.90 3.05 . 3.88 +x22 4.08 6.25 4.15 4.30 1.77 . 1.77 . +x23 3.39 5.74 3.55 4.08 1.69 . 1.47 . ; + +param msr (tr) : + + w01 w02 w03 w04 w05 w62 w76 w96 := + +w01 0 0 0 0 0 0 1 0 +w02 0 0 0 0 0 0 1 0 +w03 0 0 0 0 0 0 1 0 +w04 0 0 0 0 0 0 1 0 +w05 0 0 0 0 0 0 0 0 +w06 0 1 1 1 1 1 1 1 +w08 0 1 1 1 1 1 1 1 +w09 0 1 1 1 1 1 0 1 +w12 0 1 1 1 1 0 1 1 +w14 1 1 1 1 1 0 0 1 +w15 0 1 1 1 1 1 0 1 +w17 0 1 1 1 1 1 0 1 +w18 0 1 1 1 1 0 0 1 +w19 0 1 1 1 1 0 0 1 +w20 1 1 1 1 1 0 0 1 +w24 0 1 1 1 1 0 0 1 +w25 0 1 1 1 1 0 1 0 +w26 1 1 1 0 1 1 0 1 +w27 1 1 1 0 1 1 0 1 +w28 1 1 1 0 1 0 0 1 +w29 0 1 1 1 1 0 0 1 +w30 1 1 1 0 1 1 0 1 +w31 1 1 1 0 1 0 0 1 +w32 0 0 0 0 0 0 0 0 +w33 1 0 1 1 1 1 0 1 +w34 1 1 1 0 1 0 0 1 +w35 1 1 1 1 1 0 0 1 +w36 0 1 1 1 0 1 1 1 +w37 1 1 1 0 1 1 0 1 +w38 1 1 1 0 1 0 0 1 +w39 0 1 1 1 1 1 0 1 +w40 1 1 1 0 1 0 0 1 +w41 1 0 1 1 1 0 0 1 +w42 1 1 1 0 1 0 0 1 +w43 1 1 1 0 1 0 0 1 +w44 1 1 1 1 1 0 0 1 +w45 0 1 1 1 1 1 0 1 +w46 0 1 1 1 1 0 1 1 +w47 0 1 1 1 1 1 0 1 +w48 0 1 1 1 1 0 0 1 +w49 1 1 1 1 1 0 0 1 +w50 0 1 1 1 1 1 0 1 +w51 0 1 1 1 1 0 1 1 +w53 1 1 1 1 1 0 0 1 +w54 0 1 1 1 1 1 1 1 +w55 0 1 1 1 1 0 0 1 +w56 0 1 1 1 1 1 0 1 +w57 0 1 1 1 1 1 0 1 +w59 0 1 1 1 0 1 1 1 +w60 0 1 1 1 1 0 1 1 +w61 0 1 1 1 0 0 1 1 +w62 0 0 0 0 0 0 1 0 +w63 0 1 1 1 0 1 1 1 +w64 0 1 1 1 1 1 0 1 +w65 0 1 1 1 0 1 1 1 +w66 0 1 1 1 0 1 1 1 +w68 0 1 1 1 0 1 1 1 +w69 0 1 1 1 0 1 1 1 +w71 0 1 1 1 0 1 1 1 +w72 0 1 1 1 0 1 1 1 +w73 0 1 1 1 0 1 1 0 +w74 0 1 1 1 0 0 0 1 +w75 0 1 1 1 0 1 1 1 +w76 0 0 0 0 0 0 0 0 +w77 1 0 1 1 1 0 0 1 +w78 1 0 1 1 1 0 0 1 +w79 1 0 1 1 1 0 0 1 +w80 1 0 1 1 1 0 0 1 +w81 1 0 1 1 1 0 0 1 +w82 1 0 1 1 1 1 1 0 +w83 1 0 1 1 1 0 1 1 +w84 1 0 1 1 1 0 0 1 +w85 1 1 1 1 1 0 0 1 +w86 1 0 1 1 1 0 0 1 +w87 1 0 1 1 1 1 1 0 +w89 1 0 1 1 1 1 0 1 +w90 0 1 1 1 1 0 0 1 +w91 1 0 1 1 1 0 0 1 +w92 1 0 1 1 1 0 0 1 +w93 1 1 1 0 1 0 0 1 +w94 0 0 1 1 1 0 1 1 +w95 1 0 1 1 1 0 0 1 +w96 0 0 0 0 0 0 0 0 +w98 1 0 1 1 1 1 0 1 +x22 1 1 1 1 0 0 1 0 +x23 1 1 1 1 0 0 1 0 ; + +param ds default 0.000 (tr) : + + 18REG 24REG 24PRO := + +w01 0.000 0.000 0.008 +w02 0.004 0.000 0.000 +w03 0.000 0.000 0.000 +w04 0.010 0.002 0.000 +w05 0.000 0.000 0.000 +w06 0.010 0.008 0.008 +w08 0.030 0.024 0.024 +w09 0.014 0.018 0.020 +w12 0.014 0.012 0.010 +w14 0.007 0.007 0.012 +w15 0.010 0.019 0.018 +w17 0.013 0.010 0.011 +w19 0.015 0.012 0.009 +w20 0.012 0.021 0.022 +w21 0.000 0.000 0.000 +w24 0.012 0.022 0.018 +w25 0.019 0.025 0.020 +w26 0.006 0.015 0.021 +w27 0.008 0.010 0.015 +w28 0.011 0.016 0.019 +w29 0.008 0.020 0.013 +w30 0.011 0.013 0.015 +w31 0.011 0.013 0.017 +w32 0.006 0.000 0.000 +w33 0.000 0.015 0.014 +w34 0.008 0.007 0.005 +w35 0.002 0.006 0.014 +w36 0.015 0.013 0.005 +w37 0.017 0.016 0.015 +w38 0.015 0.009 0.012 +w39 0.007 0.017 0.022 +w40 0.009 0.014 0.020 +w41 0.003 0.014 0.011 +w42 0.017 0.011 0.012 +w43 0.009 0.013 0.011 +w44 0.002 0.012 0.012 +w45 0.016 0.025 0.028 +w46 0.038 0.062 0.040 +w47 0.007 0.010 0.010 +w48 0.003 0.015 0.016 +w49 0.005 0.016 0.017 +w50 0.011 0.008 0.007 +w51 0.010 0.022 0.021 +w53 0.004 0.026 0.020 +w54 0.020 0.017 0.025 +w55 0.004 0.019 0.028 +w56 0.004 0.010 0.008 +w57 0.014 0.020 0.018 +w59 0.012 0.006 0.007 +w60 0.019 0.010 0.009 +w61 0.028 0.010 0.012 +w62 0.000 0.000 0.000 +w63 0.070 0.027 0.037 +w64 0.009 0.004 0.005 +w65 0.022 0.015 0.016 +w66 0.046 0.017 0.020 +w68 0.005 0.012 0.016 +w69 0.085 0.036 0.039 +w71 0.011 0.013 0.010 +w72 0.089 0.031 0.034 +w75 0.026 0.012 0.010 +w77 0.001 0.004 0.002 +w78 0.002 0.004 0.002 +w79 0.001 0.004 0.002 +w80 0.001 0.001 0.002 +w81 0.001 0.003 0.002 +w83 0.009 0.010 0.008 +w84 0.001 0.002 0.002 +w85 0.001 0.004 0.005 +w86 0.001 0.002 0.002 +w87 0.002 0.003 0.000 +w89 0.001 0.001 0.002 +w90 0.006 0.017 0.013 +w91 0.002 0.010 0.013 +w92 0.000 0.003 0.002 +w93 0.002 0.006 0.007 +w95 0.001 0.007 0.007 +w96 0.000 0.000 0.000 +w98 0.006 0.005 0.002 ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/egypt.mod b/resources/3rdparty/glpk-4.57/examples/egypt.mod new file mode 100644 index 000000000..b051d4a73 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/egypt.mod @@ -0,0 +1,519 @@ +# EGYPT, a static model of fertilizer production +# +# References: +# Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language +# for Mathematical Programming." Management Science 36 (1990) 519-554. + +### SETS ### + +set center; # Locations from which final product may be shipped +set port within center; # Locations at which imports can be received +set plant within center; # Locations of plants + +set region; # Demand regions + +set unit; # Productive units +set proc; # Processes + +set nutr; # Nutrients + +set c_final; # Final products (fertilizers) +set c_inter; # Intermediate products +set c_ship within c_inter; # Intermediates for shipment +set c_raw; # Domestic raw materials and miscellaneous inputs + +set commod := c_final union c_inter union c_raw; + + # All commodities + +### PARAMETERS ### + +param cf75 {region,c_final} >= 0; + + # Consumption of fertilizer 1974-75 (1000 tpy) + +param fn {c_final,nutr} >= 0; + + # Nutrient content of fertilizers + +param cn75 {r in region, n in nutr} := sum {c in c_final} cf75[r,c] * fn[c,n]; + + # Consumption of nutrients 1974-75 (1000 tpy) + +param road {region,center} >= 0; + + # Road distances + +param rail_half {plant,plant} >= 0; +param rail {p1 in plant, p2 in plant} := + if rail_half[p1,p2] > 0 then rail_half[p1,p2] else rail_half[p2,p1]; + + # Interplant rail distances (kms) + +param impd_barg {plant} >= 0; +param impd_road {plant} >= 0; + + # Import distances (kms) by barge and road + +param tran_final {pl in plant, r in region} := + if road[r,pl] > 0 then .5 + .0144 * road[r,pl] else 0; + +param tran_import {r in region, po in port} := + if road[r,po] > 0 then .5 + .0144 * road[r,po] else 0; + +param tran_inter {p1 in plant, p2 in plant} := + if rail[p1,p2] > 0 then 3.5 + .03 * rail[p1,p2] else 0; + +param tran_raw {pl in plant} := + (if impd_barg[pl] > 0 then 1.0 + .0030 * impd_barg[pl] else 0) + + (if impd_road[pl] > 0 then 0.5 + .0144 * impd_road[pl] else 0); + + # Transport cost (le per ton) for: + # final products, imported final products, + # interplant shipment, imported raw materials + +param io {commod,proc}; # Input-output coefficients + +param util {unit,proc} >= 0; + + # Capacity utilization coefficients + +param p_imp {commod} >= 0; # Import Price (cif US$ per ton 1975) + +param p_r {c_raw} >= 0; +param p_pr {plant,c_raw} >= 0; + +param p_dom {pl in plant, c in c_raw} := + if p_r[c] > 0 then p_r[c] else p_pr[pl,c]; + + # Domestic raw material prices + +param dcap {plant,unit} >= 0; + + # Design capacity of plants (t/day) + +param icap {u in unit, pl in plant} := 0.33 * dcap[pl,u]; + + # Initial capacity of plants (t/day) + +param exch := 0.4; # Exchange rate + +param util_pct := 0.85; # Utilization percent for initial capacity + +### DERIVED SETS OF "POSSIBILITIES" ### + +set m_pos {pl in plant} := {u in unit: icap[u,pl] > 0}; + + # At each plant, set of units for which there is + # initial capacity + +set p_cap {pl in plant} := + {pr in proc: forall {u in unit: util[u,pr] > 0} u in m_pos[pl] }; + + # At each plant, set of processes for which + # all necessary units have some initial capacity + +set p_except {plant} within proc; + + # At each plant, list of processes that are + # arbitrarily ruled out + +set p_pos {pl in plant} := p_cap[pl] diff p_except[pl]; + + # At each plant, set of possible processes + +set cp_pos {c in commod} := {pl in plant: sum {pr in p_pos[pl]} io[c,pr] > 0}; + +set cc_pos {c in commod} := {pl in plant: sum {pr in p_pos[pl]} io[c,pr] < 0}; + +set c_pos {c in commod} := cp_pos[c] union cc_pos[c]; + + # For each commodity, set of plants that can + # produce it (cp_pos) or consume it (cc_pos), + # and their union (c_pos) + +### VARIABLES ### + +var Z {pl in plant, p_pos[pl]} >= 0; + + # Z[pl,pr] is level of process pr at plant pl + +var Xf {c in c_final, cp_pos[c], region} >= 0; + + # Xf[c,pl,r] is amount of final product c + # shipped from plant pl to region r + +var Xi {c in c_ship, cp_pos[c], cc_pos[c]} >= 0; + + # Xi[c,p1,p2] is amount of intermediate c + # shipped from plant p1 to plant p2 + +var Vf {c_final,region,port} >= 0; + + # Vf[c,r,po] is amount of final product c + # imported by region r from port po + +var Vr {c in c_raw, cc_pos[c]} >= 0; + + # Vr[c,pl] is amount of raw material c + # imported for use at plant pl + +var U {c in c_raw, cc_pos[c]} >= 0; + + # U[c,pl] is amount of raw material c + # purchased domestically for use at plant pl + +var Psip; # Domestic recurrent cost +var Psil; # Transport cost +var Psii; # Import cost + +### OBJECTIVE ### + +minimize Psi: Psip + Psil + Psii; + +### CONSTRAINTS ### + +subject to mbd {n in nutr, r in region}: + + sum {c in c_final} fn[c,n] * + (sum {po in port} Vf[c,r,po] + + sum {pl in cp_pos[c]} Xf[c,pl,r]) >= cn75[r,n]; + + # Total nutrients supplied to a region by all + # final products (sum of imports plus internal + # shipments from plants) must meet requirements + +subject to mbdb {c in c_final, r in region: cf75[r,c] > 0}: + + sum {po in port} Vf[c,r,po] + + sum {pl in cp_pos[c]} Xf[c,pl,r] >= cf75[r,c]; + + # Total of each final product supplied to each + # region (as in previous constraint) must meet + # requirements + +subject to mb {c in commod, pl in plant}: + + sum {pr in p_pos[pl]} io[c,pr] * Z[pl,pr] + + + ( if c in c_ship then + ( if pl in cp_pos[c] then sum {p2 in cc_pos[c]} Xi[c,pl,p2] ) + - ( if pl in cc_pos[c] then sum {p2 in cp_pos[c]} Xi[c,p2,pl] )) + + + ( if (c in c_raw and pl in cc_pos[c]) then + (( if p_imp[c] > 0 then Vr[c,pl] ) + + ( if p_dom[pl,c] > 0 then U[c,pl] ))) + + >= if (c in c_final and pl in cp_pos[c]) then sum {r in region} Xf[c,pl,r]; + + # For each commodity at each plant: sum of + # (1) production or consumption at plant, + # (2) inter-plant shipments in or out, + # (3) import and domestic purchases (raw only) + # is >= 0 for raw materials and intermediates; + # is >= the total shipped for final products + +subject to cc {pl in plant, u in m_pos[pl]}: + + sum {pr in p_pos[pl]} util[u,pr] * Z[pl,pr] <= util_pct * icap[u,pl]; + + # For each productive unit at each plant, + # total utilization by all processes + # may not exceed the unit's capacity + +subject to ap: + + Psip = sum {c in c_raw, pl in cc_pos[c]} p_dom[pl,c] * U[c,pl]; + + # Psip is the cost of domestic raw materials, + # summed over all plants that consume them + +subject to al: + + Psil = sum {c in c_final} ( + + sum {pl in cp_pos[c], r in region} + tran_final[pl,r] * Xf[c,pl,r] + + + sum {po in port, r in region} tran_import[r,po] * Vf[c,r,po] ) + + + sum {c in c_ship, p1 in cp_pos[c], p2 in cc_pos[c]} + tran_inter[p1,p2] * Xi[c,p1,p2] + + + sum {c in c_raw, pl in cc_pos[c]: p_imp[c] > 0} + tran_raw[pl] * Vr[c,pl]; + + # Total transport cost is sum of shipping costs for + # (1) all final products from all plants, + # (2) all imports of final products, + # (3) all intermediates shipped between plants, + # (4) all imports of raw materials + +subject to ai: + + Psii / exch = sum {c in c_final, r in region, po in port} + p_imp[c] * Vf[c,r,po] + + + sum {c in c_raw, pl in cc_pos[c]} p_imp[c] * Vr[c,pl]; + + # Total import cost -- at exchange rate -- + # is sum of import costs for final products + # in each region and raw materials at each plant + +### DATA ### + +data; + +set center := ASWAN HELWAN ASSIOUT KAFR_EL_ZT ABU_ZAABAL ABU_KIR TALKHA SUEZ ; + +set port := ABU_KIR ; + +set plant := ASWAN HELWAN ASSIOUT KAFR_EL_ZT ABU_ZAABAL ; + +set region := ALEXANDRIA BEHERA GHARBIA KAFR_EL_SH DAKAHLIA DAMIETTA + SHARKIA ISMAILIA SUEZ MENOUFIA KALUBIA GIZA BENI_SUEF FAYOUM + MINIA ASSIOUT NEW_VALLEY SOHAG QUENA ASWAN ; + +set unit := SULF_A_S SULF_A_P NITR_ACID AMM_ELEC AMM_C_GAS C_AMM_NITR + AMM_SULF SSP ; + +set proc := SULF_A_S SULF_A_P NITR_ACID AMM_ELEC AMM_C_GAS CAN_310 CAN_335 + AMM_SULF SSP_155 ; + +set nutr := N P205 ; + +set c_final := UREA CAN_260 CAN_310 CAN_335 AMM_SULF DAP SSP_155 C_250_55 + C_300_100 ; + +set c_inter := AMMONIA NITR_ACID SULF_ACID ; + +set c_ship := AMMONIA SULF_ACID ; + +set c_raw := EL_ASWAN COKE_GAS PHOS_ROCK LIMESTONE EL_SULFUR PYRITES + ELECTRIC BF_GAS WATER STEAM BAGS ; + +set p_except[ASWAN] := CAN_335 ; +set p_except[HELWAN] := CAN_310 ; +set p_except[ASSIOUT] := ; +set p_except[KAFR_EL_ZT] := ; +set p_except[ABU_ZAABAL] := ; + +param cf75 default 0.0 : + + CAN_260 CAN_310 CAN_335 AMM_SULF UREA := + +ALEXANDRIA . . 5.0 3.0 1.0 +ASSIOUT 1.0 20.0 26.0 1.0 27.0 +ASWAN . 40.0 . . . +BEHERA 1.0 . 25.0 90.0 35.0 +BENI_SUEF 1.0 . 15.0 1.0 20.0 +DAKAHLIA 1.0 . 26.0 60.0 20.0 +DAMIETTA . . 2.0 15.0 8.0 +FAYOUM 1.0 . 20.0 6.0 20.0 +GHARBIA . . 17.0 60.0 28.0 +GIZA . . 40.0 6.0 2.0 +ISMAILIA . . 4.0 6.0 2.0 +KAFR_EL_SH 1.0 . 10.0 45.0 22.0 +KALUBIA . . 25.0 16.0 7.0 +MENOUFIA 1.0 . 24.0 21.0 30.0 +MINIA 2.0 15.0 35.0 1.0 41.0 +NEW_VALLEY . . . . 1.0 +QUENA . 95.0 2.0 . 3.0 +SHARKIA 1.0 . 31.0 50.0 28.0 +SOHAG . 65.0 3.0 . 7.0 +SUEZ . . 1.0 . . + + : SSP_155 C_250_55 C_300_100 DAP := + +ALEXANDRIA 8.0 . . . +ASSIOUT 35.0 5.0 .1 . +ASWAN 8.0 . . . +BEHERA 64.0 1.0 .1 .1 +BENI_SUEF 13.0 3.0 . . +DAKAHLIA 52.0 1.0 . . +DAMIETTA 5.0 . . . +FAYOUM 17.0 1.0 . . +GHARBIA 57.0 1.0 .2 .1 +GIZA 14.0 1.0 .1 . +ISMAILIA 4.0 . . . +KAFR_EL_SH 25.0 2.0 .1 . +KALUBIA 22.0 1.0 . .1 +MENOUFIA 33.0 2.0 .1 .1 +MINIA 50.0 3.0 .2 .1 +NEW_VALLEY 1.0 . . . +QUENA 8.0 . . . +SHARKIA 43.0 1.0 .1 . +SOHAG 20.0 1.0 . . +SUEZ 1.0 . . . ; + +param fn default 0.0 : N P205 := + + AMM_SULF .206 . + CAN_260 .26 . + CAN_310 .31 . + CAN_335 .335 . + C_250_55 .25 .055 + C_300_100 .30 .10 + DAP .18 .46 + SSP_155 . .15 + UREA .46 . ; + +param road default 0.0 : + + ABU_KIR ABU_ZAABAL ASSIOUT ASWAN HELWAN KAFR_EL_ZT SUEZ TALKHA := + +ALEXANDRIA 16 210 607 1135 244 119 362 187 +ASSIOUT 616 420 . 518 362 504 527 518 +ASWAN 1134 938 518 . 880 1022 1045 1036 +BEHERA 76 50 547 1065 184 42 288 120 +BENI_SUEF 359 163 257 775 105 248 270 261 +DAKAHLIA 208 138 515 1033 152 58 219 3 +DAMIETTA 267 216 596 1114 233 131 286 66 +FAYOUM 341 145 308 826 88 230 252 243 +GHARBIA 150 65 485 1003 122 20 226 55 +GIZA 287 48 372 890 .9 133 169 146 +ISMAILIA 365 142 536 1054 173 241 89 146 +KAFR_EL_SH 145 105 525 1043 162 20 266 35 +KALUBIA 190 97 439 957 76 66 180 81 +MENOUFIA 157 154 472 990 109 33 213 90 +MINIA 384 288 132 650 230 372 394 386 +NEW_VALLEY 815 619 199 519 561 703 726 717 +QUENA 858 662 242 276 604 746 769 760 +SHARKIA 240 60 473 991 110 78 214 58 +SOHAG 715 519 99 419 461 603 626 617 +SUEZ 370 224 541 1059 178 246 . 298 ; + +param rail_half default 0 : + + KAFR_EL_ZT ABU_ZAABAL HELWAN ASSIOUT := + +ABU_ZAABAL 85 . . . +HELWAN 142 57 . . +ASSIOUT 504 420 362 . +ASWAN 1022 938 880 518 ; + +param : impd_barg impd_road := + +ABU_ZAABAL 210 .1 +ASSIOUT 583 0 +ASWAN 1087 10 +HELWAN 183 0 +KAFR_EL_ZT 104 6 ; + +param io default 0.0 := + + [*,AMM_C_GAS] AMMONIA 1.0 + BF_GAS -609. + COKE_GAS -2.0 + ELECTRIC -1960. + STEAM -4. + WATER -700. + + [*,AMM_ELEC] AMMONIA 1.0 + EL_ASWAN -12.0 + + [*,AMM_SULF] AMMONIA -.26 + AMM_SULF 1.0 + BAGS -22. + ELECTRIC -19. + SULF_ACID -.76 + WATER -17. + + [*,CAN_310] AMMONIA -.20 + BAGS -23. + CAN_310 1.0 + LIMESTONE -.12 + NITR_ACID -.71 + STEAM -.4 + WATER -49. + + [*,CAN_335] AMMONIA -.21 + BAGS -23. + CAN_335 1.0 + LIMESTONE -.04 + NITR_ACID -.76 + STEAM -.4 + WATER -49. + + [*,NITR_ACID] AMMONIA -.292 + ELECTRIC -231. + NITR_ACID 1.0 + WATER -.6 + + [*,SSP_155] BAGS -22. + ELECTRIC -14. + PHOS_ROCK -.62 + SSP_155 1.0 + SULF_ACID -.41 + WATER -6. + + [*,SULF_A_P] ELECTRIC -75. + PYRITES -.826 + SULF_ACID 1.0 + WATER -60. + + [*,SULF_A_S] ELECTRIC -50. + EL_SULFUR -.334 + SULF_ACID 1.0 + WATER -20. ; + +param util default 0 := + + [*,*] SULF_A_S SULF_A_S 1 SULF_A_P SULF_A_P 1 + NITR_ACID NITR_ACID 1 AMM_ELEC AMM_ELEC 1 + AMM_C_GAS AMM_C_GAS 1 SSP SSP_155 1 + C_AMM_NITR CAN_310 1 C_AMM_NITR CAN_335 1 + AMM_SULF AMM_SULF 1 ; + +param p_imp default 0.0 := + + PYRITES 17.5 AMM_SULF 75. + EL_SULFUR 55. DAP 175. + UREA 150. SSP_155 80. + CAN_260 75. C_250_55 100. + CAN_310 90. C_300_100 130. + CAN_335 100. ; + +param p_r default 0.0 := + + ELECTRIC .007 + BF_GAS .007 + WATER .031 + STEAM 1.25 + BAGS .28 ; + +param p_pr default 0.0 := + + [HELWAN,COKE_GAS] 16.0 + [ASWAN,EL_ASWAN] 1.0 + + [*,LIMESTONE] ASWAN 1.2 + HELWAN 1.2 + + [*,PHOS_ROCK] ABU_ZAABAL 4.0 + ASSIOUT 3.5 + KAFR_EL_ZT 5.0 ; + +param dcap default 0.0 := + + [ABU_ZAABAL,*] SSP 600 + SULF_A_P 227 + SULF_A_S 242 + + [ASSIOUT,*] SSP 600 + SULF_A_S 250 + + [ASWAN,*] AMM_ELEC 450 + C_AMM_NITR 1100 + NITR_ACID 800 + + [HELWAN,*] AMM_C_GAS 172 + AMM_SULF 24 + C_AMM_NITR 364 + NITR_ACID 282 + + [KAFR_EL_ZT,*] SSP 600 + SULF_A_P 50 + SULF_A_S 200 ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/fctp.mod b/resources/3rdparty/glpk-4.57/examples/fctp.mod new file mode 100644 index 000000000..9d6382da6 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/fctp.mod @@ -0,0 +1,93 @@ +/* FCTP, Fixed-Charge Transportation Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* The Fixed-Charge Transportation Problem (FCTP) is obtained from + classical transportation problem by imposing a fixed cost on each + transportation link if there is a positive flow on that link. */ + +param m, integer, > 0; +/* number of sources */ + +param n, integer, > 0; +/* number of customers */ + +set I := 1..m; +/* set of sources */ + +set J := 1..n; +/* set of customers */ + +param supply{i in I}, >= 0; +/* supply at source i */ + +param demand{j in J}, >= 0; +/* demand at customer j */ + +param varcost{i in I, j in J}, >= 0; +/* variable cost (a cost per one unit shipped from i to j) */ + +param fixcost{i in I, j in J}, >= 0; +/* fixed cost (a cost for shipping any amount from i to j) */ + +var x{i in I, j in J}, >= 0; +/* amount shipped from source i to customer j */ + +s.t. f{i in I}: sum{j in J} x[i,j] = supply[i]; +/* observe supply at source i */ + +s.t. g{j in J}: sum{i in I} x[i,j] = demand[j]; +/* satisfy demand at customer j */ + +var y{i in I, j in J}, binary; +/* y[i,j] = 1 means some amount is shipped from i to j */ + +s.t. h{i in I, j in J}: x[i,j] <= min(supply[i], demand[j]) * y[i,j]; +/* if y[i,j] is 0, force x[i,j] to be 0 (may note that supply[i] and + demand[j] are implicit upper bounds for x[i,j] as follows from the + constraints f[i] and g[j]) */ + +minimize cost: sum{i in I, j in J} varcost[i,j] * x[i,j] + + sum{i in I, j in J} fixcost[i,j] * y[i,j]; +/* total transportation costs */ + +data; + +/* These data correspond to the instance bal8x12 from [Balinski]. */ + +/* The optimal solution is 471.55 */ + +param m := 8; + +param n := 12; + +param supply := 1 15.00, 2 20.00, 3 45.00, 4 35.00, + 5 25.00, 6 35.00, 7 10.00, 8 25.00; + +param demand := 1 20.00, 2 15.00, 3 20.00, 4 15.00, + 5 5.00, 6 20.00, 7 30.00, 8 10.00, + 9 35.00, 10 25.00, 11 10.00, 12 5.00; + +param varcost + : 1 2 3 4 5 6 7 8 9 10 11 12 := + 1 0.69 0.64 0.71 0.79 1.70 2.83 2.02 5.64 5.94 5.94 5.94 7.68 + 2 1.01 0.75 0.88 0.59 1.50 2.63 2.26 5.64 5.85 5.62 5.85 4.94 + 3 1.05 1.06 1.08 0.64 1.22 2.37 1.66 5.64 5.91 5.62 5.91 4.94 + 4 1.94 1.50 1.56 1.22 1.98 1.98 1.36 6.99 6.99 6.99 6.99 3.68 + 5 1.61 1.40 1.61 1.33 1.68 2.83 1.54 4.26 4.26 4.26 4.26 2.99 + 6 5.29 5.94 6.08 5.29 5.96 6.77 5.08 0.31 0.21 0.17 0.31 1.53 + 7 5.29 5.94 6.08 5.29 5.96 6.77 5.08 0.55 0.35 0.40 0.19 1.53 + 8 5.29 6.08 6.08 5.29 5.96 6.45 5.08 2.43 2.30 2.33 1.81 2.50 ; + +param fixcost + : 1 2 3 4 5 6 7 8 9 10 11 12 := + 1 11.0 16.0 18.0 17.0 10.0 20.0 17.0 13.0 15.0 12.0 14.0 14.0 + 2 14.0 17.0 17.0 13.0 15.0 13.0 16.0 11.0 20.0 11.0 15.0 10.0 + 3 12.0 13.0 20.0 17.0 13.0 15.0 16.0 13.0 12.0 13.0 10.0 18.0 + 4 16.0 19.0 16.0 11.0 15.0 12.0 18.0 12.0 18.0 13.0 13.0 14.0 + 5 19.0 18.0 15.0 16.0 12.0 14.0 20.0 19.0 11.0 17.0 16.0 18.0 + 6 13.0 20.0 20.0 17.0 15.0 12.0 14.0 11.0 12.0 19.0 15.0 16.0 + 7 11.0 12.0 15.0 10.0 17.0 11.0 11.0 16.0 10.0 18.0 17.0 12.0 + 8 17.0 10.0 20.0 12.0 17.0 20.0 16.0 15.0 10.0 12.0 16.0 18.0 ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/food.mod b/resources/3rdparty/glpk-4.57/examples/food.mod new file mode 100644 index 000000000..cb1aa05ad --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/food.mod @@ -0,0 +1,127 @@ +/* Food Manufacture 1, section 12.1 in + * Williams, "Model Building in Mathematical Programming" + * + * Sebastian Nowozin + */ + +set oils; +set month; + +/* Buying prices of the raw oils in the next six month. */ +param buyingprices{month,oils}; + +/* Actual amount bought in each month. */ +var buys{month,oils} >= 0; + +/* Stock for each oil. */ +var stock{month,oils} >= 0; + +/* Price of the produced product */ +param productprice >= 0; +param storagecost; + +param oilhardness{oils} >= 0; + +/* Actual amount of output oil produced in each month */ +var production{m in month} >= 0; +var useoil{m in month, o in oils} >= 0; + +maximize totalprofit: + sum{m in month} productprice*production[m] + - sum{m in month, o in oils} buyingprices[m,o]*buys[m,o] + - sum{m in month, o in oils} storagecost*stock[m,o]; + +/* Constraints */ + +/* 1. Starting stock */ +s.t. startstock{o in oils}: + stock[1,o] = 500; +s.t. endstock{o in oils}: + stock[6,o] + buys[6,o] - useoil[6,o] >= 500; + +/* 2. Stock constraints */ +s.t. stocklimit{m in month, o in oils}: + stock[m,o] <= 1000; + +s.t. production1{m in month, o in oils}: + useoil[m,o] <= stock[m,o] + buys[m,o]; +s.t. production2{m1 in month, m2 in month, o in oils : m2 = m1+1}: + stock[m2,o] = stock[m1,o] + buys[m1,o] - useoil[m1,o]; + +s.t. production3a{m in month}: + sum{o in oils} oilhardness[o]*useoil[m,o] >= 3*production[m]; +s.t. production3b{m in month}: + sum{o in oils} oilhardness[o]*useoil[m,o] <= 6*production[m]; + +s.t. production4{m in month}: + production[m] = sum{o in oils} useoil[m,o]; + +/* 3. Refining constraints */ +s.t. refine1{m in month}: + useoil[m,"VEG1"]+useoil[m,"VEG2"] <= 200; +s.t. refine2{m in month}: + useoil[m,"OIL1"]+useoil[m,"OIL2"]+useoil[m,"OIL3"] <= 250; + +solve; + +for {m in month} { + printf "Month %d\n", m; + printf "PRODUCE %4.2f tons, hardness %4.2f\n", production[m], + (sum{o in oils} oilhardness[o]*useoil[m,o]) / (sum{o in oils} useoil[m,o]); + + printf "\tVEG1\tVEG2\tOIL1\tOIL2\tOIL3\n"; + printf "STOCK"; + printf "%d", m; + for {o in oils} { + printf "\t%4.2f", stock[m,o]; + } + printf "\nBUY"; + for {o in oils} { + printf "\t%4.2f", buys[m,o]; + } + printf "\nUSE"; + printf "%d", m; + for {o in oils} { + printf "\t%4.2f", useoil[m,o]; + } + printf "\n"; + printf "\n"; +} +printf "Total profit: %4.2f\n", + (sum{m in month} productprice*production[m] + - sum{m in month, o in oils} buyingprices[m,o]*buys[m,o] + - sum{m in month, o in oils} storagecost*stock[m,o]); +printf " turnover: %4.2f\n", + sum{m in month} productprice*production[m]; +printf " buying costs: %4.2f\n", + sum{m in month, o in oils} buyingprices[m,o]*buys[m,o]; +printf " storage costs: %4.2f\n", + sum{m in month, o in oils} storagecost*stock[m,o]; + + +data; + +param : oils : oilhardness := + VEG1 8.8 + VEG2 6.1 + OIL1 2.0 + OIL2 4.2 + OIL3 5.0 ; + +set month := 1 2 3 4 5 6; + +param buyingprices + +: VEG1 VEG2 OIL1 OIL2 OIL3 := + +1 110 120 130 110 115 +2 130 130 110 90 115 +3 110 140 130 100 95 +4 120 110 120 120 125 +5 100 120 150 110 105 +6 90 100 140 80 135 ; + +param productprice := 150; +param storagecost := 5; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/food2.mod b/resources/3rdparty/glpk-4.57/examples/food2.mod new file mode 100644 index 000000000..694b59462 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/food2.mod @@ -0,0 +1,150 @@ +/* Food Manufacture 2, section 12.2 in + * Williams, "Model Building in Mathematical Programming" + * + * Sebastian Nowozin + */ + +set oils; +set month; + +/* Buying prices of the raw oils in the next six month. */ +param buyingprices{month,oils}; + +/* Actual amount bought in each month. */ +var buys{month,oils} >= 0; + +/* Stock for each oil. */ +var stock{month,oils} >= 0; + +/* Price of the produced product */ +param productprice >= 0; +param storagecost; + +param oilhardness{oils} >= 0; +param M >= 0; + +/* Actual amount of output oil produced in each month */ +var production{m in month} >= 0; +var useoil{m in month, o in oils} >= 0, <= M; +var useoilb{m in month, o in oils}, binary; + +maximize totalprofit: + sum{m in month} productprice*production[m] + - sum{m in month, o in oils} buyingprices[m,o]*buys[m,o] + - sum{m in month, o in oils} storagecost*stock[m,o]; + +/* Constraints */ + +/* 1. Starting stock */ +s.t. startstock{o in oils}: + stock[1,o] = 500; +s.t. endstock{o in oils}: + stock[6,o] + buys[6,o] - useoil[6,o] >= 500; + +/* 2. Stock constraints */ +s.t. stocklimit{m in month, o in oils}: + stock[m,o] <= 1000; + +s.t. production1{m in month, o in oils}: + useoil[m,o] <= stock[m,o] + buys[m,o]; +s.t. production2{m1 in month, m2 in month, o in oils : m2 = m1+1}: + stock[m2,o] = stock[m1,o] + buys[m1,o] - useoil[m1,o]; + +s.t. production3a{m in month}: + sum{o in oils} oilhardness[o]*useoil[m,o] >= 3*production[m]; +s.t. production3b{m in month}: + sum{o in oils} oilhardness[o]*useoil[m,o] <= 6*production[m]; + +s.t. production4{m in month}: + production[m] = sum{o in oils} useoil[m,o]; + +/* 3. Refining constraints */ +s.t. refine1{m in month}: + useoil[m,"VEG1"]+useoil[m,"VEG2"] <= 200; +s.t. refine2{m in month}: + useoil[m,"OIL1"]+useoil[m,"OIL2"]+useoil[m,"OIL3"] <= 250; + +/* 4. Additional conditions: + * i) The food may never be made up of more than three oils every month + */ +s.t. useoilb_calc{m in month, o in oils}: + M*useoilb[m,o] >= useoil[m,o]; +s.t. useoilb_limit{m in month}: + sum{o in oils} useoilb[m,o] <= 3; + +/* ii) If an oil is used in a month, at least 20 tons must be used. + */ +s.t. useminimum{m in month, o in oils}: + 20*useoilb[m,o] <= useoil[m,o]; + +/* iii) If either of VEG1 or VEG2 is used in a month, OIL2 must also be used + */ +s.t. use_oil2a{m in month}: + useoilb[m,"VEG1"] <= useoilb[m,"OIL3"]; +s.t. use_oil2b{m in month}: + useoilb[m,"VEG2"] <= useoilb[m,"OIL3"]; + +solve; + +for {m in month} { + printf "Month %d\n", m; + printf "PRODUCE %4.2f tons, hardness %4.2f\n", production[m], + (sum{o in oils} oilhardness[o]*useoil[m,o]) / (sum{o in oils} useoil[m,o]); + + printf "\tVEG1\tVEG2\tOIL1\tOIL2\tOIL3\n"; + printf "STOCK"; + printf "%d", m; + for {o in oils} { + printf "\t%4.2f", stock[m,o]; + } + printf "\nBUY"; + for {o in oils} { + printf "\t%4.2f", buys[m,o]; + } + printf "\nUSE"; + printf "%d", m; + for {o in oils} { + printf "\t%4.2f", useoil[m,o]; + } + printf "\n"; + printf "\n"; +} +printf "Total profit: %4.2f\n", + (sum{m in month} productprice*production[m] + - sum{m in month, o in oils} buyingprices[m,o]*buys[m,o] + - sum{m in month, o in oils} storagecost*stock[m,o]); +printf " turnover: %4.2f\n", + sum{m in month} productprice*production[m]; +printf " buying costs: %4.2f\n", + sum{m in month, o in oils} buyingprices[m,o]*buys[m,o]; +printf " storage costs: %4.2f\n", + sum{m in month, o in oils} storagecost*stock[m,o]; + + +data; + +param : oils : oilhardness := + VEG1 8.8 + VEG2 6.1 + OIL1 2.0 + OIL2 4.2 + OIL3 5.0 ; + +set month := 1 2 3 4 5 6; + +param buyingprices + +: VEG1 VEG2 OIL1 OIL2 OIL3 := + +1 110 120 130 110 115 +2 130 130 110 90 115 +3 110 140 130 100 95 +4 120 110 120 120 125 +5 100 120 150 110 105 +6 90 100 140 80 135 ; + +param productprice := 150; +param storagecost := 5; +param M := 1000; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/furnace.mps b/resources/3rdparty/glpk-4.57/examples/furnace.mps new file mode 100644 index 000000000..b89b7acbd --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/furnace.mps @@ -0,0 +1,164 @@ +*NAME: FURNACE +*ROWS: 18 +*COLUMNS: 18 +*NONZERO: 90 +*OPT SOLN: 2141.923551 +*SOURCE: Linear Programming--Electric-Arc Furnace Steelmaking +* Data Processing Application. N.Y.: IBM Corp. +*APPLICATION: Electric-Arc Furnace Steelmaking +*COMMENTS: fixed MPS format +* encoded by Andrew Makhorin +* +NAME FURNACE +ROWS + N VALUE $ Price per pound (of initial charge materials) + E CR $ Chromium + E MN $ Manganese + E SI $ Silicon + E C $ Carbon + E FE $ Iron + E TOTCHG $ Total elements charged + E CRSLAG $ Chromium-oxidized-to-slag relationship + E TOTCRS $ Total modified chromium specification constraint + E MN/CR $ Total manganese specification constraint + E FESLAG $ Iron-oxidized-to-slag relationship + G ENDFE $ Total iron specification constraint + L CSPEC $ Total carbon specification constraint + E BASE $ Basicity relationship + L SISPEC $ Total silicon specification constraint + G TOTAL $ Total end metal + L TOTRS4 $ Inventory limitation on 430 grade scrap + L TOTRCF $ Inventory limitation on low-carbon ferrochrome +COLUMNS +* Steel scrap + STSCP VALUE .02 + CR 0 + MN .01 + SI .002 + C .006 + FE .982 +* 430 grade scrap + SP430 VALUE .075 + CR .16 + MN .01 + SI .0095 + C .0012 + FE .8143 + TOTRS4 1 +* High-carbon ferrochrome + HCFCR VALUE .27 + CR .556 + MN 0 + SI .02 + C .08 + FE .334 +* Low-carbon ferrochrome + LCFCR VALUE .40 + CR .65 + MN 0 + SI .01 + C .0009 + FE .3391 + TOTRCF 1 +* Chromium initially charged + CRIT VALUE 0 + CR -1 + TOTCHG 1 + CRSLAG 1 +* Manganese initially charged + MNIT VALUE 0 + MN -1 + TOTCHG 1 + CRSLAG 1 + MN/CR .98 +* Silicon initially charged + SIIT VALUE 0 + SI -1 + TOTCHG 1 + CSPEC -5 + BASE 2.14 + TOTAL -1 +* Carbon initially charged + CEIT VALUE 0 + C -1 + TOTCHG 1 + TOTAL -1 +* Iron initially charged + FEIT VALUE 0 + FE -1 + TOTCHG 1 + ENDFE 1 +* Total initial charge weight + TICW VALUE 0 + TOTCHG -1 + CRSLAG -.074 + TOTCRS .074 + FESLAG .075 + CSPEC 5 + TOTAL 1 +* Modified chromium in the slag + ISCR VALUE 0 + CRSLAG -1 + TOTCRS .95 + FESLAG -1 + CSPEC -.25 + SISPEC -.395 + TOTAL -.05 +* Chrome silicide additive at refining stage + CRSI VALUE .27 + TOTCRS .39 + ENDFE .18 + BASE 2.7606 + SISPEC .43 + TOTAL .57 +* 430 grade scrap at refining stage + RS430 VALUE .075 + TOTCRS .17 + MN/CR .01 + ENDFE .8143 + CSPEC 12 + SISPEC .0095 + TOTAL 1 + TOTRS4 1 +* Low-carbon ferrochrome at refining stage + RCFCR VALUE .40 + TOTCRS .65 + ENDFE .3391 + CSPEC 9 + SISPEC .01 + TOTAL 1 + TOTRCF 1 +* Iron in the slag + ISFE VALUE 0 + FESLAG -1 + ENDFE -.05 + CSPEC -.25 + SISPEC -.238 + TOTAL -.05 +* Lime at refining stage + LIME VALUE .01 + BASE -2 +* Low-carbon ferrochrome at finishing stage + FCFCR VALUE .40 + TOTCRS .65 + ENDFE .3391 + CSPEC 9 + SISPEC .01 + TOTAL 1 + TOTRCF 1 +* Slack in the chromium and manganese specifications + SIS VALUE 0 + TOTCRS 1 + MN/CR 1 +RHS + TOTCRS 3400 + MN/CR 200 + ENDFE 16200 + CSPEC 100000 + SISPEC 200 + TOTAL 20000 + TOTRS4 2000 + TOTRCF 2000 +BOUNDS + UP HCFCR 2000 +ENDATA diff --git a/resources/3rdparty/glpk-4.57/examples/gap.mod b/resources/3rdparty/glpk-4.57/examples/gap.mod new file mode 100644 index 000000000..22cdefa9f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/gap.mod @@ -0,0 +1,79 @@ +/* GAP, Generalized Assignment Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* The Generalized Assignment Problem (GAP) is to assign a set of jobs + to a set of agents subject to the constraints that each job must be + assigned exactly to one agent and the total resources consumed by all + jobs assigned to an agent must not exceed the agent's capacity. */ + +param m, integer, > 0; +/* number of agents */ + +param n, integer, > 0; +/* number of jobs */ + +set I := 1..m; +/* set of agents */ + +set J := 1..n; +/* set of jobs */ + +param a{i in I, j in J}, >= 0; +/* resource consumed in allocating job j to agent i */ + +param b{i in I}, >= 0; +/* resource capacity of agent i */ + +param c{i in I, j in J}, >= 0; +/* cost of allocating job j to agent i */ + +var x{i in I, j in J}, binary; +/* x[i,j] = 1 means job j is assigned to agent i */ + +s.t. one{j in J}: sum{i in I} x[i,j] = 1; +/* job j must be assigned exactly to one agent */ + +s.t. lim{i in I}: sum{j in J} a[i,j] * x[i,j] <= b[i]; +/* total amount of resources consumed by all jobs assigned to agent i + must not exceed the agent's capacity */ + +minimize obj: sum{i in I, j in J} c[i,j] * x[i,j]; +/* the objective is to find cheapest assignment (note that gap can also + be formulated as maximization problem) */ + +data; + +/* These data correspond to the instance c515-1 (gap1) from: + + I.H. Osman, "Heuristics for the Generalised Assignment Problem: + Simulated Annealing and Tabu Search Approaches", OR Spektrum, Volume + 17, 211-225, 1995 + + D. Cattrysse, M. Salomon and L.N. Van Wassenhove, "A set partitioning + heuristic for the generalized assignment problem", European Journal + of Operational Research, Volume 72, 167-174, 1994 */ + +/* The optimal solution is 261 (minimization) or 336 (maximization) */ + +param m := 5; + +param n := 15; + +param a : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 := + 1 8 15 14 23 8 16 8 25 9 17 25 15 10 8 24 + 2 15 7 23 22 11 11 12 10 17 16 7 16 10 18 22 + 3 21 20 6 22 24 10 24 9 21 14 11 14 11 19 16 + 4 20 11 8 14 9 5 6 19 19 7 6 6 13 9 18 + 5 8 13 13 13 10 20 25 16 16 17 10 10 5 12 23 ; + +param b := 1 36, 2 34, 3 38, 4 27, 5 33; + +param c : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 := + 1 17 21 22 18 24 15 20 18 19 18 16 22 24 24 16 + 2 23 16 21 16 17 16 19 25 18 21 17 15 25 17 24 + 3 16 20 16 25 24 16 17 19 19 18 20 16 17 21 24 + 4 19 19 22 22 20 16 19 17 21 19 25 23 25 25 25 + 5 18 19 15 15 21 25 16 16 23 15 22 17 19 22 24 ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/glpsol.c b/resources/3rdparty/glpk-4.57/examples/glpsol.c new file mode 100644 index 000000000..b1014500e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/glpsol.c @@ -0,0 +1,10 @@ +/* glpsol.c */ + +#include + +int main(int argc, const char *argv[]) +{ /* stand-alone LP/MIP solver */ + return glp_main(argc, argv); +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/graph.mod b/resources/3rdparty/glpk-4.57/examples/graph.mod new file mode 100644 index 000000000..bdcc969ac --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/graph.mod @@ -0,0 +1,98 @@ +/* graph.mod - graph visualization */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* This model creates a picture in EPS format to visualize a graph. */ + +param file, symbolic, default "graph.eps"; +/* output file to write the picture */ + +param R, default 2; +/* radius to draw vertices, in mm */ + +param n, integer, > 0; +/* number of vertices */ + +set V, default 1..n; +/* set of vertices */ + +set E, within V cross V; +/* set of edges */ + +param x{i in V}, default 50 * cos((i - 1) / card(V) * 8 * atan(1)); +param y{i in V}, default 50 * sin((i - 1) / card(V) * 8 * atan(1)); +/* x[i] and y[i] are coordinates of node i, in mm */ + +param x0 := (min{i in V} x[i]) - R - 3.0; +param y0 := (min{i in V} y[i]) - R - 3.0; +param x1 := (max{i in V} x[i]) + R + 3.0; +param y1 := (max{i in V} y[i]) + R + 3.0; + +printf "%%!PS-Adobe-3.0 EPSF-3.0\n" > file; +printf "%%%%BoundingBox: 0 0 %d %d\n", + (72 / 25.4) * (x1 - x0), (72 / 25.4) * (y1 - y0) >> file; +printf "/Helvetica findfont 6 scalefont setfont\n" >> file; +printf "/mm { 72 mul 25.4 div } def\n" >> file; + +for {(i,j) in E} +{ printf "newpath\n" >> file; + printf "%g mm %g mm moveto\n", x[i] - x0, y[i] - y0 >> file; + printf "%g mm %g mm lineto\n", x[j] - x0, y[j] - y0 >> file; + printf "closepath\n" >> file; + printf "stroke\n" >> file; +} + +for {i in V} +{ printf "newpath\n" >> file; + printf "%g mm %g mm %g mm 0 360 arc\n", + x[i] - x0, y[i] - y0, R >> file; + printf "closepath\n" >> file; + printf "gsave 1 1 1 setrgbcolor fill grestore\n" >> file; + printf "stroke\n" >> file; + printf "%g mm %g mm moveto\n", + x[i] - (if i <= 9 then 1.2 else 1.8) - x0, + y[i] - 0.8 - y0 >> file; + printf "( %d ) show\n", i >> file; +} + +printf "showpage\n" >> file; +printf "%%%%EOF\n" >> file; + +data; + +param +: V : x y := + 1 0 40 + 2 38 12 + 3 24 -32 + 4 -24 -32 + 5 -38 12 + 6 -19 26 + 7 19 26 + 8 31 -10 + 9 0 -32 + 10 -31 -10 + 11 -9 12 + 12 9 12 + 13 14 -5 + 14 0 -15 + 15 -14 -5 + 16 0 0 ; + +set E := + (1,*) 6 10 16 12 7 + (2,*) 7 6 16 13 8 + (3,*) 8 7 16 14 9 + (4,*) 9 8 16 15 10 + (5,*) 10 9 16 11 6 + (6,*) 14 + (7,*) 15 + (8,*) 11 + (9,*) 12 + (10,*) 13 + (11,*) 12 15 + (12,*) 13 + (13,*) 14 + (14,*) 15 ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/hashi.mod b/resources/3rdparty/glpk-4.57/examples/hashi.mod new file mode 100644 index 000000000..48e8d9f7f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/hashi.mod @@ -0,0 +1,168 @@ +/* A solver for the Japanese number-puzzle Hashiwokakero + * (http://en.wikipedia.org/wiki/Hashiwokakero) + * + * Sebastian Nowozin , 13th January 2009 + */ + +param n := 25; +set rows := 1..n; +set cols := 1..n; +param givens{rows, cols}, integer, >= 0, <= 8, default 0; + +/* Set of vertices as (row,col) coordinates */ +set V := { (i,j) in { rows, cols }: givens[i,j] != 0 }; + +/* Set of feasible horizontal edges from (i,j) to (k,l) rightwards */ +set Eh := { (i,j,k,l) in { V, V }: + i = k and j < l and # Same row and left to right + card({ (s,t) in V: s = i and t > j and t < l }) = 0 # No vertex inbetween + }; + +/* Set of feasible vertical edges from (i,j) to (k,l) downwards */ +set Ev := { (i,j,k,l) in { V, V }: + j = l and i < k and # Same column and top to bottom + card({ (s,t) in V: t = j and s > i and s < k }) = 0 # No vertex inbetween + }; + +set E := Eh union Ev; + +/* Indicators: use edge once/twice */ +var xe1{E}, binary; +var xe2{E}, binary; + +/* Constraint: Do not use edge or do use once or do use twice */ +s.t. edge_sel{(i,j,k,l) in E}: + xe1[i,j,k,l] + xe2[i,j,k,l] <= 1; + +/* Constraint: There must be as many edges used as the node value */ +s.t. satisfy_vertex_demand{(s,t) in V}: + sum{(i,j,k,l) in E: (i = s and j = t) or (k = s and l = t)} + (xe1[i,j,k,l] + 2.0*xe2[i,j,k,l]) = givens[s,t]; + +/* Constraint: No crossings */ +s.t. no_crossing1{(i,j,k,l) in Eh, (s,t,u,v) in Ev: + s < i and u > i and j < t and l > t}: + xe1[i,j,k,l] + xe1[s,t,u,v] <= 1; +s.t. no_crossing2{(i,j,k,l) in Eh, (s,t,u,v) in Ev: + s < i and u > i and j < t and l > t}: + xe1[i,j,k,l] + xe2[s,t,u,v] <= 1; +s.t. no_crossing3{(i,j,k,l) in Eh, (s,t,u,v) in Ev: + s < i and u > i and j < t and l > t}: + xe2[i,j,k,l] + xe1[s,t,u,v] <= 1; +s.t. no_crossing4{(i,j,k,l) in Eh, (s,t,u,v) in Ev: + s < i and u > i and j < t and l > t}: + xe2[i,j,k,l] + xe2[s,t,u,v] <= 1; + + +/* Model connectivity by auxiliary network flow problem: + * One vertex becomes a target node and all other vertices send a unit flow + * to it. The edge selection variables xe1/xe2 are VUB constraints and + * therefore xe1/xe2 select the feasible graph for the max-flow problems. + */ +set node_target := { (s,t) in V: + card({ (i,j) in V: i < s or (i = s and j < t) }) = 0}; +set node_sources := { (s,t) in V: (s,t) not in node_target }; + +var flow_forward{ E }, >= 0; +var flow_backward{ E }, >= 0; +s.t. flow_conservation{ (s,t) in node_target, (p,q) in V }: + /* All incoming flows */ + - sum{(i,j,k,l) in E: k = p and l = q} flow_forward[i,j,k,l] + - sum{(i,j,k,l) in E: i = p and j = q} flow_backward[i,j,k,l] + /* All outgoing flows */ + + sum{(i,j,k,l) in E: k = p and l = q} flow_backward[i,j,k,l] + + sum{(i,j,k,l) in E: i = p and j = q} flow_forward[i,j,k,l] + = 0 + (if (p = s and q = t) then card(node_sources) else -1); + +/* Variable-Upper-Bound (VUB) constraints: xe1/xe2 bound the flows. + */ +s.t. connectivity_vub1{(i,j,k,l) in E}: + flow_forward[i,j,k,l] <= card(node_sources)*(xe1[i,j,k,l] + xe2[i,j,k,l]); +s.t. connectivity_vub2{(i,j,k,l) in E}: + flow_backward[i,j,k,l] <= card(node_sources)*(xe1[i,j,k,l] + xe2[i,j,k,l]); + +/* A feasible solution is enough + */ +minimize cost: 0; + +solve; + +/* Output solution graphically */ +printf "\nSolution:\n"; +for { row in rows } { + for { col in cols } { + /* First print this cell information: givens or space */ + printf{0..0: givens[row,col] != 0} "%d", givens[row,col]; + printf{0..0: givens[row,col] = 0 and + card({(i,j,k,l) in Eh: i = row and col >= j and col < l and + xe1[i,j,k,l] = 1}) = 1} "-"; + printf{0..0: givens[row,col] = 0 and + card({(i,j,k,l) in Eh: i = row and col >= j and col < l and + xe2[i,j,k,l] = 1}) = 1} "="; + printf{0..0: givens[row,col] = 0 + and card({(i,j,k,l) in Ev: j = col and row >= i and row < k and + xe1[i,j,k,l] = 1}) = 1} "|"; + printf{0..0: givens[row,col] = 0 + and card({(i,j,k,l) in Ev: j = col and row >= i and row < k and + xe2[i,j,k,l] = 1}) = 1} '"'; + printf{0..0: givens[row,col] = 0 + and card({(i,j,k,l) in Eh: i = row and col >= j and col < l and + (xe1[i,j,k,l] = 1 or xe2[i,j,k,l] = 1)}) = 0 + and card({(i,j,k,l) in Ev: j = col and row >= i and row < k and + (xe1[i,j,k,l] = 1 or xe2[i,j,k,l] = 1)}) = 0} " "; + + /* Now print any edges */ + printf{(i,j,k,l) in Eh: i = row and col >= j and col < l and xe1[i,j,k,l] = 1} "-"; + printf{(i,j,k,l) in Eh: i = row and col >= j and col < l and xe2[i,j,k,l] = 1} "="; + + printf{(i,j,k,l) in Eh: i = row and col >= j and col < l and + xe1[i,j,k,l] = 0 and xe2[i,j,k,l] = 0} " "; + printf{0..0: card({(i,j,k,l) in Eh: i = row and col >= j and col < l}) = 0} " "; + } + printf "\n"; + for { col in cols } { + printf{(i,j,k,l) in Ev: j = col and row >= i and row < k and xe1[i,j,k,l] = 1} "|"; + printf{(i,j,k,l) in Ev: j = col and row >= i and row < k and xe2[i,j,k,l] = 1} '"'; + printf{(i,j,k,l) in Ev: j = col and row >= i and row < k and + xe1[i,j,k,l] = 0 and xe2[i,j,k,l] = 0} " "; + /* No vertical edges: skip also a field */ + printf{0..0: card({(i,j,k,l) in Ev: j = col and row >= i and row < k}) = 0} " "; + printf " "; + } + printf "\n"; +} + +data; + +/* This is a difficult 25x25 Hashiwokakero. + */ +param givens : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 +25 := + 1 2 . 2 . 2 . . 2 . 2 . . 2 . . . . 2 . 2 . 2 . 2 . + 2 . 1 . . . . 2 . . . 4 . . 5 . 2 . . 1 . 2 . 2 . 1 + 3 2 . . 5 . 4 . . 3 . . . . . 1 . . 4 . 5 . 1 . 1 . + 4 . . . . . . . . . . . 1 . 3 . . 1 . . . . . . . . + 5 2 . . 6 . 6 . . 8 . 5 . 2 . . 3 . 5 . 7 . . 2 . . + 6 . 1 . . . . . . . . . 1 . . 2 . . . . . 1 . . . 3 + 7 2 . . . . 5 . . 6 . 4 . . 2 . . . 2 . 5 . 4 . 2 . + 8 . 2 . 2 . . . . . . . . . . . 3 . . 3 . . . 1 . 2 + 9 . . . . . . . . . . 4 . 2 . 2 . . 1 . . . 3 . 1 . + 10 2 . 3 . . 6 . . 2 . . . . . . . . . . 3 . . . . . + 11 . . . . 1 . . 2 . . 5 . . 1 . 4 . 3 . . . . 2 . 4 + 12 . . 2 . . 1 . . . . . . 5 . 4 . . . . 4 . 3 . . . + 13 2 . . . 3 . 1 . . . . . . . . 3 . . 5 . 5 . . 2 . + 14 . . . . . 2 . 5 . . 7 . 5 . 3 . 1 . . 1 . . 1 . 4 + 15 2 . 5 . 3 . . . . 1 . 2 . 1 . . . . 2 . 4 . . 2 . + 16 . . . . . 1 . . . . . . . . . . 2 . . 2 . 1 . . 3 + 17 2 . 6 . 6 . . 2 . . 2 . 2 . 5 . . . . . 2 . . . . + 18 . . . . . 1 . . . 3 . . . . . 1 . . 1 . . 4 . 3 . + 19 . . 4 . 5 . . 2 . . . 2 . . 6 . 6 . . 3 . . . . 3 + 20 2 . . . . . . . . . 2 . . 1 . . . . . . 1 . . 1 . + 21 . . 3 . . 3 . 5 . 5 . . 4 . 6 . 7 . . 4 . 6 . . 4 + 22 2 . . . 3 . 5 . 2 . 1 . . . . . . . . . . . . . . + 23 . . . . . . . . . 1 . . . . . . 3 . 2 . . 5 . . 5 + 24 2 . 3 . 3 . 5 . 4 . 3 . 3 . 4 . . 2 . 2 . . . 1 . + 25 . 1 . 2 . 2 . . . 2 . 2 . . . 2 . . . . 2 . 2 . 2 + ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/huge.mod b/resources/3rdparty/glpk-4.57/examples/huge.mod new file mode 100644 index 000000000..a7d17e4c5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/huge.mod @@ -0,0 +1,25 @@ +/*Arithmetic Mean of a large number of Integers + - or - solve a very large constraint matrix + over 1 million rows and columns + Nigel_Galloway@operamail.com + March 18th., 2008. +*/ + +param e := 20; +/* set Sample := {-2**e..2**e-1}; */ +set Sample := {1..2**e-1}; + +var Mean; +var E{z in Sample}; + +/* sum of variances is zero */ +zumVariance: sum{z in Sample} E[z] = 0; + +/* Mean + variance[n] = Sample[n] */ +variances{z in Sample}: Mean + E[z] = z; + +solve; + +printf "The arithmetic mean of the integers from 1 to %d is %f\n", 2**e-1, Mean; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/icecream.mps b/resources/3rdparty/glpk-4.57/examples/icecream.mps new file mode 100644 index 000000000..5d741306d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/icecream.mps @@ -0,0 +1,345 @@ +*NAME: ICECREAM +*ROWS: 17 +*COLUMNS: 27 +*NONZERO: 264 +*OPT SOLN: 962.8214691 +*SOURCE: Linear Programming--Ice Cream Blending +* Data Processing Application. N.Y.: IBM Corp. +*APPLICATION: Ice Cream Blending +*COMMENTS: fixed MPS format +* encoded by Andrew Makhorin +* +NAME ICECREAM +ROWS + N COST $ Minimum cost $ + G MIN.BF $ Butterfat lbs + L MAX.BF + G MIN.MSNF $ Milk solids (nonfat) lbs + L MAX.MSNF + G MIN.TMS $ Total milk solids lbs + L MAX.TMS + G MIN.SUG $ Sweetness lbs + L MAX.SUG + L CSS $ Corn syrup solids lbs + G MIN.TS $ Total solids lbs + L MAX.TS + G MIN.H2O $ Water lbs + L MAX.H2O + E STAB $ Stabilizer lbs + E EMUL $ Emulsifier lbs + E YIELD $ Amount to be made lbs +COLUMNS +* Cream (40%) + I1 COST 27.9 + MIN.BF .40 + MAX.BF .40 + MIN.MSNF .054 + MAX.MSNF .054 + MIN.TMS .454 + MAX.TMS .454 + MIN.TS .454 + MAX.TS .454 + MIN.H2O .546 + MAX.H2O .546 + YIELD 1 +* Cream (38%) + I2 COST 26.3 + MIN.BF .38 + MAX.BF .38 + MIN.MSNF .056 + MAX.MSNF .056 + MIN.TMS .436 + MAX.TMS .436 + MIN.TS .436 + MAX.TS .436 + MIN.H2O .564 + MAX.H2O .564 + YIELD 1 +* Milk (3.2%) + I3 COST 3.2 + MIN.BF .032 + MAX.BF .032 + MIN.MSNF .087 + MAX.MSNF .087 + MIN.TMS .119 + MAX.TMS .119 + MIN.TS .119 + MAX.TS .119 + MIN.H2O .881 + MAX.H2O .881 + YIELD 1 +* Milk (3.4%) + I4 COST 3.2 + MIN.BF .034 + MAX.BF .034 + MIN.MSNF .087 + MAX.MSNF .087 + MIN.TMS .121 + MAX.TMS .121 + MIN.TS .121 + MAX.TS .121 + MIN.H2O .879 + MAX.H2O .879 + YIELD 1 +* Milk (3.5%) + I5 COST 3.3 + MIN.BF .035 + MAX.BF .035 + MIN.MSNF .087 + MAX.MSNF .087 + MIN.TMS .122 + MAX.TMS .122 + MIN.TS .122 + MAX.TS .122 + MIN.H2O .879 + MAX.H2O .879 + YIELD 1 +* Milk (3.6%) + I6 COST 3.3 + MIN.BF .036 + MAX.BF .036 + MIN.MSNF .087 + MAX.MSNF .087 + MIN.TMS .123 + MAX.TMS .123 + MIN.TS .123 + MAX.TS .123 + MIN.H2O .877 + MAX.H2O .877 + YIELD 1 +* Milk (3.7%) + I7 COST 3.4 + MIN.BF .037 + MAX.BF .037 + MIN.MSNF .087 + MAX.MSNF .087 + MIN.TMS .124 + MAX.TMS .124 + MIN.TS .124 + MAX.TS .124 + MIN.H2O .876 + MAX.H2O .876 + YIELD 1 +* Milk (3.8%) + I8 COST 3.5 + MIN.BF .038 + MAX.BF .038 + MIN.MSNF .087 + MAX.MSNF .087 + MIN.TMS .125 + MAX.TMS .125 + MIN.TS .125 + MAX.TS .125 + MIN.H2O .875 + MAX.H2O .875 + YIELD 1 +* Milk (3.9%) + I9 COST 3.5 + MIN.BF .039 + MAX.BF .039 + MIN.MSNF .086 + MAX.MSNF .086 + MIN.TMS .125 + MAX.TMS .125 + MIN.TS .125 + MAX.TS .125 + MIN.H2O .875 + MAX.H2O .875 + YIELD 1 +* Milk (4.0%) + I10 COST 3.6 + MIN.BF .040 + MAX.BF .040 + MIN.MSNF .086 + MAX.MSNF .086 + MIN.TMS .126 + MAX.TMS .126 + MIN.TS .126 + MAX.TS .126 + MIN.H2O .874 + MAX.H2O .874 + YIELD 1 +* Milk (4.2%) + I11 COST 3.7 + MIN.BF .042 + MAX.BF .042 + MIN.MSNF .086 + MAX.MSNF .086 + MIN.TMS .128 + MAX.TMS .128 + MIN.TS .128 + MAX.TS .128 + MIN.H2O .872 + MAX.H2O .872 + YIELD 1 +* Skim Milk + I12 COST 1.8 + MIN.MSNF .09 + MAX.MSNF .09 + MIN.TMS .09 + MAX.TMS .09 + MIN.TS .09 + MAX.TS .09 + MIN.H2O .91 + MAX.H2O .91 + YIELD 1 +* Condensed Whole Milk + I13 COST 7.6 + MIN.BF .08 + MAX.BF .08 + MIN.MSNF .2 + MAX.MSNF .2 + MIN.TMS .28 + MAX.TMS .28 + MIN.TS .28 + MAX.TS .28 + MIN.H2O .72 + MAX.H2O .72 + YIELD 1 +* Condensed Skim Milk (28%) + I14 COST 3.9 + MIN.MSNF .28 + MAX.MSNF .28 + MIN.TMS .28 + MAX.TMS .28 + MIN.TS .28 + MAX.TS .28 + MIN.H2O .72 + MAX.H2O .72 + YIELD 1 +* Condensed Skim Milk (30%) + I15 COST 4.9 + MIN.MSNF .3 + MAX.MSNF .3 + MIN.TMS .3 + MAX.TMS .3 + MIN.TS .3 + MAX.TS .3 + MIN.H2O .7 + MAX.H2O .7 + YIELD 1 +* Condensed Skim Milk (32%) + I16 COST 4.5 + MIN.MSNF .32 + MAX.MSNF .32 + MIN.TMS .32 + MAX.TMS .32 + MIN.TS .32 + MAX.TS .32 + MIN.H2O .68 + MAX.H2O .68 + YIELD 1 +* Dry Skim Milk + I17 COST 14.8 + MIN.BF .01 + MAX.BF .01 + MIN.MSNF .96 + MAX.MSNF .96 + MIN.TMS .97 + MAX.TMS .97 + MIN.TS .97 + MAX.TS .97 + MIN.H2O .03 + MAX.H2O .03 + YIELD 1 +* Dry Buttermilk + I18 COST 15.0 + MIN.BF .05 + MAX.BF .05 + MIN.MSNF .92 + MAX.MSNF .92 + MIN.TMS .97 + MAX.TMS .97 + MIN.TS .97 + MAX.TS .97 + MIN.H2O .03 + MAX.H2O .03 + YIELD 1 +* Dry Whey Solids + I19 COST 10.7 + MIN.MSNF .95 + MAX.MSNF .95 + MIN.TMS .95 + MAX.TMS .95 + MIN.TS .95 + MAX.TS .95 + MIN.H2O .05 + MAX.H2O .05 + YIELD 1 +* Dry Sucrose + I20 COST 10.2 + MIN.SUG 1.0 + MAX.SUG 1.0 + MIN.TS 1.0 + MAX.TS 1.0 + YIELD 1 +* Cane Syrup + I21 COST 9.9 + MIN.SUG .67 + MAX.SUG .67 + MIN.TS .67 + MAX.TS .67 + MIN.H2O .33 + MAX.H2O .33 + YIELD 1 +* Corn Sgr. Solids (50% Sweetness) + I22 COST 7.0 + MIN.SUG .5 + MAX.SUG .5 + CSS 1.0 + MIN.TS 1.0 + MAX.TS 1.0 + YIELD 1 +* Corn Sgr. Solids (45% Sweetness) + I23 COST 9.0 + MIN.SUG .45 + MAX.SUG .45 + CSS 1.0 + MIN.TS 1.0 + MAX.TS 1.0 + YIELD 1 +* Corn Syrup + I24 COST 6.6 + MIN.SUG .4 + MAX.SUG .4 + CSS .8 + MIN.TS .8 + MAX.TS .8 + MIN.H2O .2 + MAX.H2O .2 + YIELD 1 +* Stabilizer + I25 COST 55.0 + STAB 1.0 + YIELD 1 +* Emulsifier + I26 COST 78.0 + EMUL 1.0 + YIELD 1 +* Water + I27 COST 0 + MIN.H2O 1.0 + MAX.H2O 1.0 + YIELD 1 +RHS + MIN.BF 10 + MAX.BF 16 + MIN.MSNF 10.5 + MAX.MSNF 13 + MIN.TMS 20.5 + MAX.TMS 25 + MIN.SUG 11 + MAX.SUG 17 + CSS 6 + MIN.TS 37.5 + MAX.TS 41.5 + MIN.H2O 58.5 + MAX.H2O 62.5 + STAB .37 + EMUL .01 + YIELD 100 +BOUNDS + UP I1 10 + LO I6 40 + UP I19 4 +ENDATA diff --git a/resources/3rdparty/glpk-4.57/examples/iptsamp.c b/resources/3rdparty/glpk-4.57/examples/iptsamp.c new file mode 100644 index 000000000..d622d7361 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/iptsamp.c @@ -0,0 +1,17 @@ +/* iptsamp.c */ + +#include +#include +#include + +int main(void) +{ glp_prob *P; + P = glp_create_prob(); + glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); + glp_interior(P, NULL); + glp_print_ipt(P, "25fv47.txt"); + glp_delete_prob(P); + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/jssp.mod b/resources/3rdparty/glpk-4.57/examples/jssp.mod new file mode 100644 index 000000000..7ee51b989 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/jssp.mod @@ -0,0 +1,114 @@ +/* JSSP, Job-Shop Scheduling Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* The Job-Shop Scheduling Problem (JSSP) is to schedule a set of jobs + on a set of machines, subject to the constraint that each machine can + handle at most one job at a time and the fact that each job has a + specified processing order through the machines. The objective is to + schedule the jobs so as to minimize the maximum of their completion + times. + + Reference: + D. Applegate and W. Cook, "A Computational Study of the Job-Shop + Scheduling Problem", ORSA J. On Comput., Vol. 3, No. 2, Spring 1991, + pp. 149-156. */ + +param n, integer, > 0; +/* number of jobs */ + +param m, integer, > 0; +/* number of machines */ + +set J := 1..n; +/* set of jobs */ + +set M := 1..m; +/* set of machines */ + +param sigma{j in J, t in 1..m}, in M; +/* permutation of the machines, which represents the processing order + of j through the machines: j must be processed first on sigma[j,1], + then on sigma[j,2], etc. */ + +check{j in J, t1 in 1..m, t2 in 1..m: t1 <> t2}: + sigma[j,t1] != sigma[j,t2]; +/* sigma must be permutation */ + +param p{j in J, a in M}, >= 0; +/* processing time of j on a */ + +var x{j in J, a in M}, >= 0; +/* starting time of j on a */ + +s.t. ord{j in J, t in 2..m}: + x[j, sigma[j,t]] >= x[j, sigma[j,t-1]] + p[j, sigma[j,t-1]]; +/* j can be processed on sigma[j,t] only after it has been completely + processed on sigma[j,t-1] */ + +/* The disjunctive condition that each machine can handle at most one + job at a time is the following: + + x[i,a] >= x[j,a] + p[j,a] or x[j,a] >= x[i,a] + p[i,a] + + for all i, j in J, a in M. This condition is modeled through binary + variables Y as shown below. */ + +var Y{i in J, j in J, a in M}, binary; +/* Y[i,j,a] is 1 if i scheduled before j on machine a, and 0 if j is + scheduled before i */ + +param K := sum{j in J, a in M} p[j,a]; +/* some large constant */ + +display K; + +s.t. phi{i in J, j in J, a in M: i <> j}: + x[i,a] >= x[j,a] + p[j,a] - K * Y[i,j,a]; +/* x[i,a] >= x[j,a] + p[j,a] iff Y[i,j,a] is 0 */ + +s.t. psi{i in J, j in J, a in M: i <> j}: + x[j,a] >= x[i,a] + p[i,a] - K * (1 - Y[i,j,a]); +/* x[j,a] >= x[i,a] + p[i,a] iff Y[i,j,a] is 1 */ + +var z; +/* so-called makespan */ + +s.t. fin{j in J}: z >= x[j, sigma[j,m]] + p[j, sigma[j,m]]; +/* which is the maximum of the completion times of all the jobs */ + +minimize obj: z; +/* the objective is to make z as small as possible */ + +data; + +/* These data correspond to the instance ft06 (mt06) from: + + H. Fisher, G.L. Thompson (1963), Probabilistic learning combinations + of local job-shop scheduling rules, J.F. Muth, G.L. Thompson (eds.), + Industrial Scheduling, Prentice Hall, Englewood Cliffs, New Jersey, + 225-251 */ + +/* The optimal solution is 55 */ + +param n := 6; + +param m := 6; + +param sigma : 1 2 3 4 5 6 := + 1 3 1 2 4 6 5 + 2 2 3 5 6 1 4 + 3 3 4 6 1 2 5 + 4 2 1 3 4 5 6 + 5 3 2 5 6 1 4 + 6 2 4 6 1 5 3 ; + +param p : 1 2 3 4 5 6 := + 1 3 6 1 7 6 3 + 2 10 8 5 4 10 10 + 3 9 1 5 4 7 8 + 4 5 5 5 3 8 9 + 5 3 3 9 1 5 4 + 6 10 3 1 3 4 9 ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/magic.mod b/resources/3rdparty/glpk-4.57/examples/magic.mod new file mode 100644 index 000000000..d1e64d018 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/magic.mod @@ -0,0 +1,54 @@ +/* MAGIC, Magic Square */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* In recreational mathematics, a magic square of order n is an + arrangement of n^2 numbers, usually distinct integers, in a square, + such that n numbers in all rows, all columns, and both diagonals sum + to the same constant. A normal magic square contains the integers + from 1 to n^2. + + (From Wikipedia, the free encyclopedia.) */ + +param n, integer, > 0, default 4; +/* square order */ + +set N := 1..n^2; +/* integers to be placed */ + +var x{i in 1..n, j in 1..n, k in N}, binary; +/* x[i,j,k] = 1 means that cell (i,j) contains integer k */ + +s.t. a{i in 1..n, j in 1..n}: sum{k in N} x[i,j,k] = 1; +/* each cell must be assigned exactly one integer */ + +s.t. b{k in N}: sum{i in 1..n, j in 1..n} x[i,j,k] = 1; +/* each integer must be assigned exactly to one cell */ + +var s; +/* the magic sum */ + +s.t. r{i in 1..n}: sum{j in 1..n, k in N} k * x[i,j,k] = s; +/* the sum in each row must be the magic sum */ + +s.t. c{j in 1..n}: sum{i in 1..n, k in N} k * x[i,j,k] = s; +/* the sum in each column must be the magic sum */ + +s.t. d: sum{i in 1..n, k in N} k * x[i,i,k] = s; +/* the sum in the diagonal must be the magic sum */ + +s.t. e: sum{i in 1..n, k in N} k * x[i,n-i+1,k] = s; +/* the sum in the co-diagonal must be the magic sum */ + +solve; + +printf "\n"; +printf "Magic sum is %d\n", s; +printf "\n"; +for{i in 1..n} +{ printf{j in 1..n} "%3d", sum{k in N} k * x[i,j,k]; + printf "\n"; +} +printf "\n"; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/maxcut.mod b/resources/3rdparty/glpk-4.57/examples/maxcut.mod new file mode 100644 index 000000000..db30b92e5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/maxcut.mod @@ -0,0 +1,85 @@ +/* MAXCUT, Maximum Cut Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* The Maximum Cut Problem in a network G = (V, E), where V is a set + of nodes, E is a set of edges, is to find the partition of V into + disjoint sets V1 and V2, which maximizes the sum of edge weights + w(e), where edge e has one endpoint in V1 and other endpoint in V2. + + Reference: + Garey, M.R., and Johnson, D.S. (1979), Computers and Intractability: + A guide to the theory of NP-completeness [Network design, Cuts and + Connectivity, Maximum Cut, ND16]. */ + +set E, dimen 2; +/* set of edges */ + +param w{(i,j) in E}, >= 0, default 1; +/* w[i,j] is weight of edge (i,j) */ + +set V := (setof{(i,j) in E} i) union (setof{(i,j) in E} j); +/* set of nodes */ + +var x{i in V}, binary; +/* x[i] = 0 means that node i is in set V1 + x[i] = 1 means that node i is in set V2 */ + +/* We need to include in the objective function only that edges (i,j) + from E, for which x[i] != x[j]. This can be modeled through binary + variables s[i,j] as follows: + + s[i,j] = x[i] xor x[j] = (x[i] + x[j]) mod 2, (1) + + where s[i,j] = 1 iff x[i] != x[j], that leads to the following + objective function: + + z = sum{(i,j) in E} w[i,j] * s[i,j]. (2) + + To describe "exclusive or" (1) we could think that s[i,j] is a minor + bit of the sum x[i] + x[j]. Then introducing binary variables t[i,j], + which represent a major bit of the sum x[i] + x[j], we can write: + + x[i] + x[j] = s[i,j] + 2 * t[i,j]. (3) + + An easy check shows that conditions (1) and (3) are equivalent. + + Note that condition (3) can be simplified by eliminating variables + s[i,j]. Indeed, from (3) it follows that: + + s[i,j] = x[i] + x[j] - 2 * t[i,j]. (4) + + Since the expression in the right-hand side of (4) is integral, this + condition can be rewritten in the equivalent form: + + 0 <= x[i] + x[j] - 2 * t[i,j] <= 1. (5) + + (One might note that (5) means t[i,j] = x[i] and x[j].) + + Substituting s[i,j] from (4) to (2) leads to the following objective + function: + + z = sum{(i,j) in E} w[i,j] * (x[i] + x[j] - 2 * t[i,j]), (6) + + which does not include variables s[i,j]. */ + +var t{(i,j) in E}, binary; +/* t[i,j] = x[i] and x[j] = (x[i] + x[j]) div 2 */ + +s.t. xor{(i,j) in E}: 0 <= x[i] + x[j] - 2 * t[i,j] <= 1; +/* see (4) */ + +maximize z: sum{(i,j) in E} w[i,j] * (x[i] + x[j] - 2 * t[i,j]); +/* see (6) */ + +data; + +/* In this example the network has 15 nodes and 22 edges. */ + +/* Optimal solution is 20 */ + +set E := + 1 2, 1 5, 2 3, 2 6, 3 4, 3 8, 4 9, 5 6, 5 7, 6 8, 7 8, 7 12, 8 9, + 8 12, 9 10, 9 14, 10 11, 10 14, 11 15, 12 13, 13 14, 14 15; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/maxflow.mod b/resources/3rdparty/glpk-4.57/examples/maxflow.mod new file mode 100644 index 000000000..20dfc3ee2 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/maxflow.mod @@ -0,0 +1,83 @@ +/* MAXFLOW, Maximum Flow Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* The Maximum Flow Problem in a network G = (V, E), where V is a set + of nodes, E within V x V is a set of arcs, is to maximize the flow + from one given node s (source) to another given node t (sink) subject + to conservation of flow constraints at each node and flow capacities + on each arc. */ + +param n, integer, >= 2; +/* number of nodes */ + +set V, default {1..n}; +/* set of nodes */ + +set E, within V cross V; +/* set of arcs */ + +param a{(i,j) in E}, > 0; +/* a[i,j] is capacity of arc (i,j) */ + +param s, symbolic, in V, default 1; +/* source node */ + +param t, symbolic, in V, != s, default n; +/* sink node */ + +var x{(i,j) in E}, >= 0, <= a[i,j]; +/* x[i,j] is elementary flow through arc (i,j) to be found */ + +var flow, >= 0; +/* total flow from s to t */ + +s.t. node{i in V}: +/* node[i] is conservation constraint for node i */ + + sum{(j,i) in E} x[j,i] + (if i = s then flow) + /* summary flow into node i through all ingoing arcs */ + + = /* must be equal to */ + + sum{(i,j) in E} x[i,j] + (if i = t then flow); + /* summary flow from node i through all outgoing arcs */ + +maximize obj: flow; +/* objective is to maximize the total flow through the network */ + +solve; + +printf{1..56} "="; printf "\n"; +printf "Maximum flow from node %s to node %s is %g\n\n", s, t, flow; +printf "Starting node Ending node Arc capacity Flow in arc\n"; +printf "------------- ----------- ------------ -----------\n"; +printf{(i,j) in E: x[i,j] != 0}: "%13s %11s %12g %11g\n", i, j, + a[i,j], x[i,j]; +printf{1..56} "="; printf "\n"; + +data; + +/* These data correspond to an example from [Christofides]. */ + +/* Optimal solution is 29 */ + +param n := 9; + +param : E : a := + 1 2 14 + 1 4 23 + 2 3 10 + 2 4 9 + 3 5 12 + 3 8 18 + 4 5 26 + 5 2 11 + 5 6 25 + 5 7 4 + 6 7 7 + 6 8 8 + 7 9 15 + 8 9 20; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/mfasp.mod b/resources/3rdparty/glpk-4.57/examples/mfasp.mod new file mode 100644 index 000000000..b4382818a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/mfasp.mod @@ -0,0 +1,62 @@ +/* MFASP, Minimum Feedback Arc Set Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* The Minimum Feedback Arc Set Problem for a given directed graph + G = (V, E), where V is a set of vertices and E is a set of arcs, is + to find a minimal subset of arcs, which being removed from the graph + make it acyclic. + + Reference: + Garey, M.R., and Johnson, D.S. (1979), Computers and Intractability: + A guide to the theory of NP-completeness [Graph Theory, Covering and + Partitioning, Minimum Feedback Arc Set, GT9]. */ + +param n, integer, >= 0; +/* number of vertices */ + +set V, default 1..n; +/* set of vertices */ + +set E, within V cross V, +default setof{i in V, j in V: i <> j and Uniform(0,1) <= 0.15} (i,j); +/* set of arcs */ + +printf "Graph has %d vertices and %d arcs\n", card(V), card(E); + +var x{(i,j) in E}, binary; +/* x[i,j] = 1 means that (i->j) is a feedback arc */ + +/* It is known that a digraph G = (V, E) is acyclic if and only if its + vertices can be assigned numbers from 1 to |V| in such a way that + k[i] + 1 <= k[j] for every arc (i->j) in E, where k[i] is a number + assigned to vertex i. We may use this condition to require that the + digraph G = (V, E \ E'), where E' is a subset of feedback arcs, is + acyclic. */ + +var k{i in V}, >= 1, <= card(V); +/* k[i] is a number assigned to vertex i */ + +s.t. r{(i,j) in E}: k[j] - k[i] >= 1 - card(V) * x[i,j]; +/* note that x[i,j] = 1 leads to a redundant constraint */ + +minimize obj: sum{(i,j) in E} x[i,j]; +/* the objective is to minimize the cardinality of a subset of feedback + arcs */ + +solve; + +printf "Minimum feedback arc set:\n"; +printf{(i,j) in E: x[i,j]} "%d %d\n", i, j; + +data; + +/* The optimal solution is 3 */ + +param n := 15; + +set E := 1 2, 2 3, 3 4, 3 8, 4 9, 5 1, 6 5, 7 5, 8 6, 8 7, 8 9, 9 10, + 10 11, 10 14, 11 15, 12 7, 12 8, 12 13, 13 8, 13 12, 13 14, + 14 9, 15 14; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/mfvsp.mod b/resources/3rdparty/glpk-4.57/examples/mfvsp.mod new file mode 100644 index 000000000..a03009dea --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/mfvsp.mod @@ -0,0 +1,62 @@ +/* MFVSP, Minimum Feedback Vertex Set Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* The Minimum Feedback Vertex Set Problem for a given directed graph + G = (V, E), where V is a set of vertices and E is a set of arcs, is + to find a minimal subset of vertices, which being removed from the + graph make it acyclic. + + Reference: + Garey, M.R., and Johnson, D.S. (1979), Computers and Intractability: + A guide to the theory of NP-completeness [Graph Theory, Covering and + Partitioning, Minimum Feedback Vertex Set, GT8]. */ + +param n, integer, >= 0; +/* number of vertices */ + +set V, default 1..n; +/* set of vertices */ + +set E, within V cross V, +default setof{i in V, j in V: i <> j and Uniform(0,1) <= 0.15} (i,j); +/* set of arcs */ + +printf "Graph has %d vertices and %d arcs\n", card(V), card(E); + +var x{i in V}, binary; +/* x[i] = 1 means that i is a feedback vertex */ + +/* It is known that a digraph G = (V, E) is acyclic if and only if its + vertices can be assigned numbers from 1 to |V| in such a way that + k[i] + 1 <= k[j] for every arc (i->j) in E, where k[i] is a number + assigned to vertex i. We may use this condition to require that the + digraph G = (V, E \ E'), where E' is a subset of feedback arcs, is + acyclic. */ + +var k{i in V}, >= 1, <= card(V); +/* k[i] is a number assigned to vertex i */ + +s.t. r{(i,j) in E}: k[j] - k[i] >= 1 - card(V) * (x[i] + x[j]); +/* note that x[i] = 1 or x[j] = 1 leads to a redundant constraint */ + +minimize obj: sum{i in V} x[i]; +/* the objective is to minimize the cardinality of a subset of feedback + vertices */ + +solve; + +printf "Minimum feedback vertex set:\n"; +printf{i in V: x[i]} "%d\n", i; + +data; + +/* The optimal solution is 3 */ + +param n := 15; + +set E := 1 2, 2 3, 3 4, 3 8, 4 9, 5 1, 6 5, 7 5, 8 6, 8 7, 8 9, 9 10, + 10 11, 10 14, 11 15, 12 7, 12 8, 12 13, 13 8, 13 12, 13 14, + 14 9, 15 14; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/min01ks.mod b/resources/3rdparty/glpk-4.57/examples/min01ks.mod new file mode 100644 index 000000000..4baa3f406 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/min01ks.mod @@ -0,0 +1,111 @@ +/* min01ks.mod - finding minimal equivalent 0-1 knapsack inequality */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* It is obvious that for a given 0-1 knapsack inequality + + a[1] x[1] + ... + a[n] x[n] <= b, x[j] in {0, 1} (1) + + there exist infinitely many equivalent inequalities with exactly the + same feasible solutions. + + Given a[j]'s and b this model allows to find an inequality + + alfa[1] x[1] + ... + alfa[n] x[n] <= beta, x[j] in {0, 1}, (2) + + which is equivalent to (1) and where alfa[j]'s and beta are smallest + non-negative integers. + + This model has the following formulation: + + minimize + + z = |alfa[1]| + ... + |alfa[n]| + |beta| = (3) + + = alfa[1] + ... + alfa[n] + beta + + subject to + + alfa[1] x[1] + ... + alfa[n] x[n] <= beta (4) + + for all x satisfying to (1) + + alfa[1] x[1] + ... + alfa[n] x[n] >= beta + 1 (5) + + for all x not satisfying to (1) + + alfa[1], ..., alfa[n], beta are non-negative integers. + + Note that this model has n+1 variables and 2^n constraints. + + It is interesting, as noticed in [1] and explained in [2], that + in most cases LP relaxation of the MIP formulation above has integer + optimal solution. + + References + + 1. G.H.Bradley, P.L.Hammer, L.Wolsey, "Coefficient Reduction for + Inequalities in 0-1 Variables", Math.Prog.7 (1974), 263-282. + + 2. G.J.Koehler, "A Study on Coefficient Reduction of Binary Knapsack + Inequalities", University of Florida, 2001. */ + +param n, integer, > 0; +/* number of variables in the knapsack inequality */ + +set N := 1..n; +/* set of knapsack items */ + +/* all binary n-vectors are numbered by 0, 1, ..., 2^n-1, where vector + 0 is 00...00, vector 1 is 00...01, etc. */ + +set U := 0..2^n-1; +/* set of numbers of all binary n-vectors */ + +param x{i in U, j in N}, binary, := (i div 2^(j-1)) mod 2; +/* x[i,j] is j-th component of i-th binary n-vector */ + +param a{j in N}, >= 0; +/* original coefficients */ + +param b, >= 0; +/* original right-hand side */ + +set D := setof{i in U: sum{j in N} a[j] * x[i,j] <= b} i; +/* set of numbers of binary n-vectors, which (vectors) are feasible, + i.e. satisfy to the original knapsack inequality (1) */ + +var alfa{j in N}, integer, >= 0; +/* coefficients to be found */ + +var beta, integer, >= 0; +/* right-hand side to be found */ + +minimize z: sum{j in N} alfa[j] + beta; /* (3) */ + +phi{i in D}: sum{j in N} alfa[j] * x[i,j] <= beta; /* (4) */ + +psi{i in U diff D}: sum{j in N} alfa[j] * x[i,j] >= beta + 1; /* (5) */ + +solve; + +printf "\nOriginal 0-1 knapsack inequality:\n"; +for {j in 1..n} printf (if j = 1 then "" else " + ") & "%g x%d", + a[j], j; +printf " <= %g\n", b; +printf "\nMinimized equivalent inequality:\n"; +for {j in 1..n} printf (if j = 1 then "" else " + ") & "%g x%d", + alfa[j], j; +printf " <= %g\n\n", beta; + +data; + +/* These data correspond to the very first example from [1]. */ + +param n := 8; + +param a := [1]65, [2]64, [3]41, [4]22, [5]13, [6]12, [7]8, [8]2; + +param b := 80; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/misp.mod b/resources/3rdparty/glpk-4.57/examples/misp.mod new file mode 100644 index 000000000..b2b1f6b94 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/misp.mod @@ -0,0 +1,665 @@ +/* MISP, Maximum Independent Set Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* Let G = (V,E) be an undirected graph with vertex set V and edge set + * E. Vertices u, v in V are non-adjacent if (u,v) not in E. A subset + * of the vertices S within V is independent if all vertices in S are + * pairwise non-adjacent. The Maximum Independent Set Problem (MISP) is + * to find an independent set having the largest cardinality. */ + +param n, integer, > 0; +/* number of vertices */ + +set V := 1..n; +/* set of vertices */ + +set E within V cross V; +/* set of edges */ + +var x{i in V}, binary; +/* x[i] = 1 means vertex i belongs to independent set */ + +s.t. edge{(i,j) in E}: x[i] + x[j] <= 1; +/* if there is edge (i,j), vertices i and j cannot belong to the same + independent set */ + +maximize obj: sum{i in V} x[i]; +/* the objective is to maximize the cardinality of independent set */ + +data; + +/* These data corresponds to the test instance from: + * + * M.G.C. Resende, T.A.Feo, S.H.Smith, "Algorithm 787 -- FORTRAN + * subroutines for approximate solution of the maximum independent set + * problem using GRASP," Trans. on Math. Softw., Vol. 24, No. 4, + * December 1998, pp. 386-394. */ + +/* The optimal solution is 7. */ + +param n := 50; + +set E := + 1 2 + 1 3 + 1 5 + 1 7 + 1 8 + 1 12 + 1 15 + 1 16 + 1 19 + 1 20 + 1 21 + 1 22 + 1 28 + 1 30 + 1 34 + 1 35 + 1 37 + 1 41 + 1 42 + 1 47 + 1 50 + 2 3 + 2 5 + 2 6 + 2 7 + 2 8 + 2 9 + 2 10 + 2 13 + 2 17 + 2 19 + 2 20 + 2 21 + 2 23 + 2 25 + 2 26 + 2 29 + 2 31 + 2 35 + 2 36 + 2 44 + 2 45 + 2 46 + 2 50 + 3 5 + 3 6 + 3 8 + 3 9 + 3 10 + 3 11 + 3 14 + 3 16 + 3 23 + 3 24 + 3 26 + 3 27 + 3 28 + 3 29 + 3 30 + 3 31 + 3 34 + 3 35 + 3 36 + 3 39 + 3 41 + 3 42 + 3 43 + 3 44 + 3 50 + 4 6 + 4 7 + 4 9 + 4 10 + 4 11 + 4 13 + 4 14 + 4 15 + 4 17 + 4 21 + 4 22 + 4 23 + 4 24 + 4 25 + 4 27 + 4 28 + 4 30 + 4 31 + 4 33 + 4 34 + 4 35 + 4 36 + 4 37 + 4 38 + 4 40 + 4 41 + 4 42 + 4 46 + 4 49 + 5 6 + 5 11 + 5 14 + 5 21 + 5 24 + 5 25 + 5 28 + 5 35 + 5 38 + 5 39 + 5 41 + 5 44 + 5 49 + 5 50 + 6 8 + 6 9 + 6 10 + 6 13 + 6 14 + 6 16 + 6 17 + 6 19 + 6 22 + 6 23 + 6 26 + 6 27 + 6 30 + 6 34 + 6 35 + 6 38 + 6 39 + 6 40 + 6 41 + 6 44 + 6 45 + 6 47 + 6 50 + 7 8 + 7 9 + 7 10 + 7 11 + 7 13 + 7 15 + 7 16 + 7 18 + 7 20 + 7 22 + 7 23 + 7 24 + 7 25 + 7 33 + 7 35 + 7 36 + 7 38 + 7 43 + 7 45 + 7 46 + 7 47 + 8 10 + 8 11 + 8 13 + 8 16 + 8 17 + 8 18 + 8 19 + 8 20 + 8 21 + 8 22 + 8 23 + 8 24 + 8 25 + 8 26 + 8 33 + 8 35 + 8 36 + 8 39 + 8 42 + 8 44 + 8 48 + 8 49 + 9 12 + 9 14 + 9 17 + 9 19 + 9 20 + 9 23 + 9 28 + 9 30 + 9 31 + 9 32 + 9 33 + 9 34 + 9 38 + 9 39 + 9 42 + 9 44 + 9 45 + 9 46 + 10 11 + 10 13 + 10 15 + 10 16 + 10 17 + 10 20 + 10 21 + 10 22 + 10 23 + 10 25 + 10 26 + 10 27 + 10 28 + 10 30 + 10 31 + 10 32 + 10 37 + 10 38 + 10 41 + 10 43 + 10 44 + 10 45 + 10 50 + 11 12 + 11 14 + 11 15 + 11 18 + 11 21 + 11 24 + 11 25 + 11 26 + 11 29 + 11 32 + 11 33 + 11 35 + 11 36 + 11 37 + 11 39 + 11 40 + 11 42 + 11 43 + 11 45 + 11 47 + 11 49 + 11 50 + 12 13 + 12 16 + 12 17 + 12 19 + 12 24 + 12 25 + 12 26 + 12 30 + 12 31 + 12 32 + 12 34 + 12 36 + 12 37 + 12 39 + 12 41 + 12 44 + 12 47 + 12 48 + 12 49 + 13 15 + 13 16 + 13 18 + 13 19 + 13 20 + 13 22 + 13 23 + 13 24 + 13 27 + 13 28 + 13 29 + 13 31 + 13 33 + 13 35 + 13 36 + 13 37 + 13 44 + 13 47 + 13 49 + 13 50 + 14 15 + 14 16 + 14 17 + 14 18 + 14 19 + 14 20 + 14 21 + 14 26 + 14 28 + 14 29 + 14 30 + 14 31 + 14 32 + 14 34 + 14 35 + 14 36 + 14 38 + 14 39 + 14 41 + 14 44 + 14 46 + 14 47 + 14 48 + 15 18 + 15 21 + 15 22 + 15 23 + 15 25 + 15 28 + 15 29 + 15 30 + 15 33 + 15 34 + 15 36 + 15 37 + 15 38 + 15 39 + 15 40 + 15 43 + 15 44 + 15 46 + 15 50 + 16 17 + 16 19 + 16 20 + 16 25 + 16 26 + 16 29 + 16 35 + 16 38 + 16 39 + 16 40 + 16 41 + 16 42 + 16 44 + 17 18 + 17 19 + 17 21 + 17 22 + 17 23 + 17 25 + 17 26 + 17 28 + 17 29 + 17 33 + 17 37 + 17 44 + 17 45 + 17 48 + 18 20 + 18 24 + 18 27 + 18 28 + 18 31 + 18 32 + 18 34 + 18 35 + 18 36 + 18 37 + 18 38 + 18 45 + 18 48 + 18 49 + 18 50 + 19 22 + 19 24 + 19 28 + 19 29 + 19 36 + 19 37 + 19 39 + 19 41 + 19 43 + 19 45 + 19 48 + 19 49 + 20 21 + 20 22 + 20 24 + 20 25 + 20 26 + 20 27 + 20 29 + 20 30 + 20 31 + 20 33 + 20 34 + 20 35 + 20 38 + 20 39 + 20 41 + 20 42 + 20 43 + 20 44 + 20 45 + 20 46 + 20 48 + 20 49 + 21 22 + 21 23 + 21 29 + 21 31 + 21 35 + 21 38 + 21 42 + 21 46 + 21 47 + 22 23 + 22 26 + 22 27 + 22 28 + 22 29 + 22 30 + 22 39 + 22 40 + 22 41 + 22 42 + 22 44 + 22 45 + 22 46 + 22 47 + 22 49 + 22 50 + 23 28 + 23 31 + 23 32 + 23 33 + 23 34 + 23 35 + 23 36 + 23 39 + 23 40 + 23 41 + 23 42 + 23 44 + 23 45 + 23 48 + 23 49 + 23 50 + 24 25 + 24 27 + 24 29 + 24 30 + 24 31 + 24 33 + 24 34 + 24 38 + 24 42 + 24 43 + 24 44 + 24 49 + 24 50 + 25 26 + 25 27 + 25 29 + 25 30 + 25 33 + 25 34 + 25 36 + 25 38 + 25 40 + 25 41 + 25 42 + 25 44 + 25 46 + 25 47 + 25 48 + 25 49 + 26 28 + 26 31 + 26 32 + 26 33 + 26 37 + 26 38 + 26 39 + 26 40 + 26 41 + 26 42 + 26 45 + 26 47 + 26 48 + 26 49 + 27 29 + 27 30 + 27 33 + 27 34 + 27 35 + 27 39 + 27 40 + 27 46 + 27 48 + 28 29 + 28 37 + 28 40 + 28 42 + 28 44 + 28 46 + 28 47 + 28 50 + 29 35 + 29 38 + 29 39 + 29 41 + 29 42 + 29 48 + 30 31 + 30 32 + 30 35 + 30 37 + 30 38 + 30 40 + 30 43 + 30 45 + 30 46 + 30 47 + 30 48 + 31 33 + 31 35 + 31 38 + 31 40 + 31 41 + 31 42 + 31 44 + 31 46 + 31 47 + 31 50 + 32 33 + 32 35 + 32 39 + 32 40 + 32 46 + 32 49 + 32 50 + 33 34 + 33 36 + 33 37 + 33 40 + 33 42 + 33 43 + 33 44 + 33 45 + 33 50 + 34 35 + 34 36 + 34 37 + 34 38 + 34 40 + 34 43 + 34 44 + 34 49 + 34 50 + 35 36 + 35 38 + 35 41 + 35 42 + 35 43 + 35 45 + 35 46 + 35 47 + 35 49 + 35 50 + 36 37 + 36 39 + 36 40 + 36 41 + 36 42 + 36 43 + 36 48 + 36 50 + 37 38 + 37 41 + 37 43 + 37 46 + 37 47 + 37 48 + 37 49 + 37 50 + 38 41 + 38 45 + 38 46 + 38 48 + 38 49 + 38 50 + 39 43 + 39 46 + 39 47 + 39 48 + 39 49 + 40 43 + 40 45 + 40 48 + 40 50 + 41 42 + 41 43 + 41 44 + 41 45 + 41 46 + 41 48 + 41 49 + 42 43 + 42 44 + 42 46 + 42 48 + 42 49 + 43 45 + 43 46 + 43 48 + 43 50 + 44 45 + 44 48 + 45 46 + 45 47 + 45 48 + 46 49 + 47 49 + 47 50 + 48 49 + 48 50 + 49 50 +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/misp1.dat b/resources/3rdparty/glpk-4.57/examples/misp1.dat new file mode 100644 index 000000000..2c2ed1ba5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/misp1.dat @@ -0,0 +1,1489 @@ +/* misp1.dat (data for misp.mod to illustrate clique cuts) */ + +/* These data corresponds to the test instance 1dc.128 (graphs from + * single-deletion-correcting codes) from: + * + * N.J.A.Sloane, "Challenge Problems: Independent Sets In Graphs." + * http://neilsloane.com/doc/graphs.html (June 2013). */ + +/* Optimal solution is 16. */ + +data; + +param n := 128; + +set E := /* 1471 edges */ + 1 2 + 1 3 + 1 5 + 1 9 + 1 17 + 1 33 + 1 65 + 2 3 + 2 4 + 2 5 + 2 6 + 2 9 + 2 10 + 2 17 + 2 18 + 2 33 + 2 34 + 2 65 + 2 66 + 3 4 + 3 5 + 3 6 + 3 7 + 3 9 + 3 10 + 3 11 + 3 17 + 3 18 + 3 19 + 3 33 + 3 34 + 3 35 + 3 65 + 3 66 + 3 67 + 4 6 + 4 7 + 4 8 + 4 10 + 4 12 + 4 18 + 4 20 + 4 34 + 4 36 + 4 66 + 4 68 + 5 6 + 5 7 + 5 9 + 5 10 + 5 11 + 5 13 + 5 17 + 5 19 + 5 21 + 5 33 + 5 35 + 5 37 + 5 65 + 5 67 + 5 69 + 6 7 + 6 8 + 6 10 + 6 11 + 6 12 + 6 14 + 6 18 + 6 19 + 6 20 + 6 22 + 6 34 + 6 35 + 6 36 + 6 38 + 6 66 + 6 67 + 6 68 + 6 70 + 7 8 + 7 11 + 7 12 + 7 13 + 7 14 + 7 15 + 7 19 + 7 20 + 7 23 + 7 35 + 7 36 + 7 39 + 7 67 + 7 68 + 7 71 + 8 12 + 8 14 + 8 15 + 8 16 + 8 20 + 8 24 + 8 36 + 8 40 + 8 68 + 8 72 + 9 10 + 9 11 + 9 13 + 9 17 + 9 18 + 9 19 + 9 21 + 9 25 + 9 33 + 9 37 + 9 41 + 9 65 + 9 69 + 9 73 + 10 11 + 10 12 + 10 13 + 10 14 + 10 18 + 10 19 + 10 20 + 10 21 + 10 22 + 10 26 + 10 34 + 10 37 + 10 38 + 10 42 + 10 66 + 10 69 + 10 70 + 10 74 + 11 12 + 11 13 + 11 14 + 11 15 + 11 19 + 11 21 + 11 22 + 11 23 + 11 27 + 11 35 + 11 37 + 11 38 + 11 39 + 11 43 + 11 67 + 11 69 + 11 70 + 11 71 + 11 75 + 12 14 + 12 15 + 12 16 + 12 20 + 12 22 + 12 23 + 12 24 + 12 28 + 12 36 + 12 38 + 12 40 + 12 44 + 12 68 + 12 70 + 12 72 + 12 76 + 13 14 + 13 15 + 13 21 + 13 23 + 13 25 + 13 26 + 13 27 + 13 29 + 13 37 + 13 39 + 13 45 + 13 69 + 13 71 + 13 77 + 14 15 + 14 16 + 14 22 + 14 23 + 14 24 + 14 26 + 14 27 + 14 28 + 14 30 + 14 38 + 14 39 + 14 40 + 14 46 + 14 70 + 14 71 + 14 72 + 14 78 + 15 16 + 15 23 + 15 24 + 15 27 + 15 29 + 15 30 + 15 31 + 15 39 + 15 40 + 15 47 + 15 71 + 15 72 + 15 79 + 16 24 + 16 28 + 16 30 + 16 31 + 16 32 + 16 40 + 16 48 + 16 72 + 16 80 + 17 18 + 17 19 + 17 21 + 17 25 + 17 33 + 17 34 + 17 35 + 17 37 + 17 41 + 17 49 + 17 65 + 17 73 + 17 81 + 18 19 + 18 20 + 18 21 + 18 22 + 18 25 + 18 26 + 18 34 + 18 35 + 18 36 + 18 38 + 18 41 + 18 42 + 18 50 + 18 66 + 18 73 + 18 74 + 18 82 + 19 20 + 19 21 + 19 22 + 19 23 + 19 25 + 19 26 + 19 27 + 19 35 + 19 37 + 19 38 + 19 39 + 19 41 + 19 42 + 19 43 + 19 51 + 19 67 + 19 73 + 19 74 + 19 75 + 19 83 + 20 22 + 20 23 + 20 24 + 20 26 + 20 28 + 20 36 + 20 38 + 20 39 + 20 40 + 20 42 + 20 44 + 20 52 + 20 68 + 20 74 + 20 76 + 20 84 + 21 22 + 21 23 + 21 25 + 21 26 + 21 27 + 21 29 + 21 37 + 21 41 + 21 42 + 21 43 + 21 45 + 21 53 + 21 69 + 21 73 + 21 75 + 21 77 + 21 85 + 22 23 + 22 24 + 22 26 + 22 27 + 22 28 + 22 30 + 22 38 + 22 42 + 22 43 + 22 44 + 22 46 + 22 54 + 22 70 + 22 74 + 22 75 + 22 76 + 22 78 + 22 86 + 23 24 + 23 27 + 23 28 + 23 29 + 23 30 + 23 31 + 23 39 + 23 43 + 23 44 + 23 45 + 23 46 + 23 47 + 23 55 + 23 71 + 23 75 + 23 76 + 23 79 + 23 87 + 24 28 + 24 30 + 24 31 + 24 32 + 24 40 + 24 44 + 24 46 + 24 47 + 24 48 + 24 56 + 24 72 + 24 76 + 24 80 + 24 88 + 25 26 + 25 27 + 25 29 + 25 41 + 25 45 + 25 49 + 25 50 + 25 51 + 25 53 + 25 57 + 25 73 + 25 77 + 25 89 + 26 27 + 26 28 + 26 29 + 26 30 + 26 42 + 26 45 + 26 46 + 26 50 + 26 51 + 26 52 + 26 54 + 26 58 + 26 74 + 26 77 + 26 78 + 26 90 + 27 28 + 27 29 + 27 30 + 27 31 + 27 43 + 27 45 + 27 46 + 27 47 + 27 51 + 27 53 + 27 54 + 27 55 + 27 59 + 27 75 + 27 77 + 27 78 + 27 79 + 27 91 + 28 30 + 28 31 + 28 32 + 28 44 + 28 46 + 28 48 + 28 52 + 28 54 + 28 55 + 28 56 + 28 60 + 28 76 + 28 78 + 28 80 + 28 92 + 29 30 + 29 31 + 29 45 + 29 47 + 29 53 + 29 57 + 29 58 + 29 59 + 29 61 + 29 77 + 29 79 + 29 93 + 30 31 + 30 32 + 30 46 + 30 47 + 30 48 + 30 54 + 30 58 + 30 59 + 30 60 + 30 62 + 30 78 + 30 79 + 30 80 + 30 94 + 31 32 + 31 47 + 31 48 + 31 55 + 31 59 + 31 61 + 31 62 + 31 63 + 31 79 + 31 80 + 31 95 + 32 48 + 32 56 + 32 60 + 32 62 + 32 63 + 32 64 + 32 80 + 32 96 + 33 34 + 33 35 + 33 37 + 33 41 + 33 49 + 33 65 + 33 66 + 33 67 + 33 69 + 33 73 + 33 81 + 33 97 + 34 35 + 34 36 + 34 37 + 34 38 + 34 41 + 34 42 + 34 49 + 34 50 + 34 66 + 34 67 + 34 68 + 34 70 + 34 74 + 34 81 + 34 82 + 34 98 + 35 36 + 35 37 + 35 38 + 35 39 + 35 41 + 35 42 + 35 43 + 35 49 + 35 50 + 35 51 + 35 67 + 35 69 + 35 70 + 35 71 + 35 75 + 35 81 + 35 82 + 35 83 + 35 99 + 36 38 + 36 39 + 36 40 + 36 42 + 36 44 + 36 50 + 36 52 + 36 68 + 36 70 + 36 71 + 36 72 + 36 76 + 36 82 + 36 84 + 36 100 + 37 38 + 37 39 + 37 41 + 37 42 + 37 43 + 37 45 + 37 49 + 37 51 + 37 53 + 37 69 + 37 73 + 37 74 + 37 75 + 37 77 + 37 81 + 37 83 + 37 85 + 37 101 + 38 39 + 38 40 + 38 42 + 38 43 + 38 44 + 38 46 + 38 50 + 38 51 + 38 52 + 38 54 + 38 70 + 38 74 + 38 75 + 38 76 + 38 78 + 38 82 + 38 83 + 38 84 + 38 86 + 38 102 + 39 40 + 39 43 + 39 44 + 39 45 + 39 46 + 39 47 + 39 51 + 39 52 + 39 55 + 39 71 + 39 75 + 39 77 + 39 78 + 39 79 + 39 83 + 39 84 + 39 87 + 39 103 + 40 44 + 40 46 + 40 47 + 40 48 + 40 52 + 40 56 + 40 72 + 40 76 + 40 78 + 40 79 + 40 80 + 40 84 + 40 88 + 40 104 + 41 42 + 41 43 + 41 45 + 41 49 + 41 50 + 41 51 + 41 53 + 41 57 + 41 73 + 41 81 + 41 82 + 41 83 + 41 85 + 41 89 + 41 105 + 42 43 + 42 44 + 42 45 + 42 46 + 42 50 + 42 51 + 42 52 + 42 53 + 42 54 + 42 58 + 42 74 + 42 82 + 42 83 + 42 84 + 42 85 + 42 86 + 42 90 + 42 106 + 43 44 + 43 45 + 43 46 + 43 47 + 43 51 + 43 53 + 43 54 + 43 55 + 43 59 + 43 75 + 43 83 + 43 85 + 43 86 + 43 87 + 43 91 + 43 107 + 44 46 + 44 47 + 44 48 + 44 52 + 44 54 + 44 55 + 44 56 + 44 60 + 44 76 + 44 84 + 44 86 + 44 87 + 44 88 + 44 92 + 44 108 + 45 46 + 45 47 + 45 53 + 45 55 + 45 57 + 45 58 + 45 59 + 45 61 + 45 77 + 45 85 + 45 87 + 45 89 + 45 90 + 45 91 + 45 93 + 45 109 + 46 47 + 46 48 + 46 54 + 46 55 + 46 56 + 46 58 + 46 59 + 46 60 + 46 62 + 46 78 + 46 86 + 46 87 + 46 88 + 46 90 + 46 91 + 46 92 + 46 94 + 46 110 + 47 48 + 47 55 + 47 56 + 47 59 + 47 61 + 47 62 + 47 63 + 47 79 + 47 87 + 47 88 + 47 91 + 47 93 + 47 94 + 47 95 + 47 111 + 48 56 + 48 60 + 48 62 + 48 63 + 48 64 + 48 80 + 48 88 + 48 92 + 48 94 + 48 95 + 48 96 + 48 112 + 49 50 + 49 51 + 49 53 + 49 57 + 49 81 + 49 89 + 49 97 + 49 98 + 49 99 + 49 101 + 49 105 + 49 113 + 50 51 + 50 52 + 50 53 + 50 54 + 50 57 + 50 58 + 50 82 + 50 89 + 50 90 + 50 98 + 50 99 + 50 100 + 50 102 + 50 106 + 50 114 + 51 52 + 51 53 + 51 54 + 51 55 + 51 57 + 51 58 + 51 59 + 51 83 + 51 89 + 51 90 + 51 91 + 51 99 + 51 101 + 51 102 + 51 103 + 51 107 + 51 115 + 52 54 + 52 55 + 52 56 + 52 58 + 52 60 + 52 84 + 52 90 + 52 92 + 52 100 + 52 102 + 52 103 + 52 104 + 52 108 + 52 116 + 53 54 + 53 55 + 53 57 + 53 58 + 53 59 + 53 61 + 53 85 + 53 89 + 53 91 + 53 93 + 53 101 + 53 105 + 53 106 + 53 107 + 53 109 + 53 117 + 54 55 + 54 56 + 54 58 + 54 59 + 54 60 + 54 62 + 54 86 + 54 90 + 54 91 + 54 92 + 54 94 + 54 102 + 54 106 + 54 107 + 54 108 + 54 110 + 54 118 + 55 56 + 55 59 + 55 60 + 55 61 + 55 62 + 55 63 + 55 87 + 55 91 + 55 92 + 55 95 + 55 103 + 55 107 + 55 109 + 55 110 + 55 111 + 55 119 + 56 60 + 56 62 + 56 63 + 56 64 + 56 88 + 56 92 + 56 96 + 56 104 + 56 108 + 56 110 + 56 111 + 56 112 + 56 120 + 57 58 + 57 59 + 57 61 + 57 89 + 57 93 + 57 105 + 57 113 + 57 114 + 57 115 + 57 117 + 57 121 + 58 59 + 58 60 + 58 61 + 58 62 + 58 90 + 58 93 + 58 94 + 58 106 + 58 114 + 58 115 + 58 116 + 58 118 + 58 122 + 59 60 + 59 61 + 59 62 + 59 63 + 59 91 + 59 93 + 59 94 + 59 95 + 59 107 + 59 115 + 59 117 + 59 118 + 59 119 + 59 123 + 60 62 + 60 63 + 60 64 + 60 92 + 60 94 + 60 96 + 60 108 + 60 116 + 60 118 + 60 119 + 60 120 + 60 124 + 61 62 + 61 63 + 61 93 + 61 95 + 61 109 + 61 117 + 61 121 + 61 122 + 61 123 + 61 125 + 62 63 + 62 64 + 62 94 + 62 95 + 62 96 + 62 110 + 62 118 + 62 122 + 62 123 + 62 124 + 62 126 + 63 64 + 63 95 + 63 96 + 63 111 + 63 119 + 63 123 + 63 125 + 63 126 + 63 127 + 64 96 + 64 112 + 64 120 + 64 124 + 64 126 + 64 127 + 64 128 + 65 66 + 65 67 + 65 69 + 65 73 + 65 81 + 65 97 + 66 67 + 66 68 + 66 69 + 66 70 + 66 73 + 66 74 + 66 81 + 66 82 + 66 97 + 66 98 + 67 68 + 67 69 + 67 70 + 67 71 + 67 73 + 67 74 + 67 75 + 67 81 + 67 82 + 67 83 + 67 97 + 67 98 + 67 99 + 68 70 + 68 71 + 68 72 + 68 74 + 68 76 + 68 82 + 68 84 + 68 98 + 68 100 + 69 70 + 69 71 + 69 73 + 69 74 + 69 75 + 69 77 + 69 81 + 69 83 + 69 85 + 69 97 + 69 99 + 69 101 + 70 71 + 70 72 + 70 74 + 70 75 + 70 76 + 70 78 + 70 82 + 70 83 + 70 84 + 70 86 + 70 98 + 70 99 + 70 100 + 70 102 + 71 72 + 71 75 + 71 76 + 71 77 + 71 78 + 71 79 + 71 83 + 71 84 + 71 87 + 71 99 + 71 100 + 71 103 + 72 76 + 72 78 + 72 79 + 72 80 + 72 84 + 72 88 + 72 100 + 72 104 + 73 74 + 73 75 + 73 77 + 73 81 + 73 82 + 73 83 + 73 85 + 73 89 + 73 97 + 73 101 + 73 105 + 74 75 + 74 76 + 74 77 + 74 78 + 74 82 + 74 83 + 74 84 + 74 85 + 74 86 + 74 90 + 74 98 + 74 101 + 74 102 + 74 106 + 75 76 + 75 77 + 75 78 + 75 79 + 75 83 + 75 85 + 75 86 + 75 87 + 75 91 + 75 99 + 75 101 + 75 102 + 75 103 + 75 107 + 76 78 + 76 79 + 76 80 + 76 84 + 76 86 + 76 87 + 76 88 + 76 92 + 76 100 + 76 102 + 76 104 + 76 108 + 77 78 + 77 79 + 77 85 + 77 87 + 77 89 + 77 90 + 77 91 + 77 93 + 77 101 + 77 103 + 77 109 + 78 79 + 78 80 + 78 86 + 78 87 + 78 88 + 78 90 + 78 91 + 78 92 + 78 94 + 78 102 + 78 103 + 78 104 + 78 110 + 79 80 + 79 87 + 79 88 + 79 91 + 79 93 + 79 94 + 79 95 + 79 103 + 79 104 + 79 111 + 80 88 + 80 92 + 80 94 + 80 95 + 80 96 + 80 104 + 80 112 + 81 82 + 81 83 + 81 85 + 81 89 + 81 97 + 81 98 + 81 99 + 81 101 + 81 105 + 81 113 + 82 83 + 82 84 + 82 85 + 82 86 + 82 89 + 82 90 + 82 98 + 82 99 + 82 100 + 82 102 + 82 105 + 82 106 + 82 114 + 83 84 + 83 85 + 83 86 + 83 87 + 83 89 + 83 90 + 83 91 + 83 99 + 83 101 + 83 102 + 83 103 + 83 105 + 83 106 + 83 107 + 83 115 + 84 86 + 84 87 + 84 88 + 84 90 + 84 92 + 84 100 + 84 102 + 84 103 + 84 104 + 84 106 + 84 108 + 84 116 + 85 86 + 85 87 + 85 89 + 85 90 + 85 91 + 85 93 + 85 101 + 85 105 + 85 106 + 85 107 + 85 109 + 85 117 + 86 87 + 86 88 + 86 90 + 86 91 + 86 92 + 86 94 + 86 102 + 86 106 + 86 107 + 86 108 + 86 110 + 86 118 + 87 88 + 87 91 + 87 92 + 87 93 + 87 94 + 87 95 + 87 103 + 87 107 + 87 108 + 87 109 + 87 110 + 87 111 + 87 119 + 88 92 + 88 94 + 88 95 + 88 96 + 88 104 + 88 108 + 88 110 + 88 111 + 88 112 + 88 120 + 89 90 + 89 91 + 89 93 + 89 105 + 89 109 + 89 113 + 89 114 + 89 115 + 89 117 + 89 121 + 90 91 + 90 92 + 90 93 + 90 94 + 90 106 + 90 109 + 90 110 + 90 114 + 90 115 + 90 116 + 90 118 + 90 122 + 91 92 + 91 93 + 91 94 + 91 95 + 91 107 + 91 109 + 91 110 + 91 111 + 91 115 + 91 117 + 91 118 + 91 119 + 91 123 + 92 94 + 92 95 + 92 96 + 92 108 + 92 110 + 92 112 + 92 116 + 92 118 + 92 119 + 92 120 + 92 124 + 93 94 + 93 95 + 93 109 + 93 111 + 93 117 + 93 121 + 93 122 + 93 123 + 93 125 + 94 95 + 94 96 + 94 110 + 94 111 + 94 112 + 94 118 + 94 122 + 94 123 + 94 124 + 94 126 + 95 96 + 95 111 + 95 112 + 95 119 + 95 123 + 95 125 + 95 126 + 95 127 + 96 112 + 96 120 + 96 124 + 96 126 + 96 127 + 96 128 + 97 98 + 97 99 + 97 101 + 97 105 + 97 113 + 98 99 + 98 100 + 98 101 + 98 102 + 98 105 + 98 106 + 98 113 + 98 114 + 99 100 + 99 101 + 99 102 + 99 103 + 99 105 + 99 106 + 99 107 + 99 113 + 99 114 + 99 115 + 100 102 + 100 103 + 100 104 + 100 106 + 100 108 + 100 114 + 100 116 + 101 102 + 101 103 + 101 105 + 101 106 + 101 107 + 101 109 + 101 113 + 101 115 + 101 117 + 102 103 + 102 104 + 102 106 + 102 107 + 102 108 + 102 110 + 102 114 + 102 115 + 102 116 + 102 118 + 103 104 + 103 107 + 103 108 + 103 109 + 103 110 + 103 111 + 103 115 + 103 116 + 103 119 + 104 108 + 104 110 + 104 111 + 104 112 + 104 116 + 104 120 + 105 106 + 105 107 + 105 109 + 105 113 + 105 114 + 105 115 + 105 117 + 105 121 + 106 107 + 106 108 + 106 109 + 106 110 + 106 114 + 106 115 + 106 116 + 106 117 + 106 118 + 106 122 + 107 108 + 107 109 + 107 110 + 107 111 + 107 115 + 107 117 + 107 118 + 107 119 + 107 123 + 108 110 + 108 111 + 108 112 + 108 116 + 108 118 + 108 119 + 108 120 + 108 124 + 109 110 + 109 111 + 109 117 + 109 119 + 109 121 + 109 122 + 109 123 + 109 125 + 110 111 + 110 112 + 110 118 + 110 119 + 110 120 + 110 122 + 110 123 + 110 124 + 110 126 + 111 112 + 111 119 + 111 120 + 111 123 + 111 125 + 111 126 + 111 127 + 112 120 + 112 124 + 112 126 + 112 127 + 112 128 + 113 114 + 113 115 + 113 117 + 113 121 + 114 115 + 114 116 + 114 117 + 114 118 + 114 121 + 114 122 + 115 116 + 115 117 + 115 118 + 115 119 + 115 121 + 115 122 + 115 123 + 116 118 + 116 119 + 116 120 + 116 122 + 116 124 + 117 118 + 117 119 + 117 121 + 117 122 + 117 123 + 117 125 + 118 119 + 118 120 + 118 122 + 118 123 + 118 124 + 118 126 + 119 120 + 119 123 + 119 124 + 119 125 + 119 126 + 119 127 + 120 124 + 120 126 + 120 127 + 120 128 + 121 122 + 121 123 + 121 125 + 122 123 + 122 124 + 122 125 + 122 126 + 123 124 + 123 125 + 123 126 + 123 127 + 124 126 + 124 127 + 124 128 + 125 126 + 125 127 + 126 127 + 126 128 + 127 128 +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/misp2.dat b/resources/3rdparty/glpk-4.57/examples/misp2.dat new file mode 100644 index 000000000..c9a61161e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/misp2.dat @@ -0,0 +1,3857 @@ +/* misp2.dat (data for misp.mod to illustrate clique cuts) */ + +/* These data corresponds to the test instance 1dc.256 (graphs from + * single-deletion-correcting codes) from: + * + * N.J.A.Sloane, "Challenge Problems: Independent Sets In Graphs." + * http://neilsloane.com/doc/graphs.html (June 2013). */ + +/* Optimal solution is 30. */ + +data; + +param n := 256; + +set E := /* 3839 edges */ + 1 2 + 1 3 + 1 5 + 1 9 + 1 17 + 1 33 + 1 65 + 1 129 + 2 3 + 2 4 + 2 5 + 2 6 + 2 9 + 2 10 + 2 17 + 2 18 + 2 33 + 2 34 + 2 65 + 2 66 + 2 129 + 2 130 + 3 4 + 3 5 + 3 6 + 3 7 + 3 9 + 3 10 + 3 11 + 3 17 + 3 18 + 3 19 + 3 33 + 3 34 + 3 35 + 3 65 + 3 66 + 3 67 + 3 129 + 3 130 + 3 131 + 4 6 + 4 7 + 4 8 + 4 10 + 4 12 + 4 18 + 4 20 + 4 34 + 4 36 + 4 66 + 4 68 + 4 130 + 4 132 + 5 6 + 5 7 + 5 9 + 5 10 + 5 11 + 5 13 + 5 17 + 5 19 + 5 21 + 5 33 + 5 35 + 5 37 + 5 65 + 5 67 + 5 69 + 5 129 + 5 131 + 5 133 + 6 7 + 6 8 + 6 10 + 6 11 + 6 12 + 6 14 + 6 18 + 6 19 + 6 20 + 6 22 + 6 34 + 6 35 + 6 36 + 6 38 + 6 66 + 6 67 + 6 68 + 6 70 + 6 130 + 6 131 + 6 132 + 6 134 + 7 8 + 7 11 + 7 12 + 7 13 + 7 14 + 7 15 + 7 19 + 7 20 + 7 23 + 7 35 + 7 36 + 7 39 + 7 67 + 7 68 + 7 71 + 7 131 + 7 132 + 7 135 + 8 12 + 8 14 + 8 15 + 8 16 + 8 20 + 8 24 + 8 36 + 8 40 + 8 68 + 8 72 + 8 132 + 8 136 + 9 10 + 9 11 + 9 13 + 9 17 + 9 18 + 9 19 + 9 21 + 9 25 + 9 33 + 9 37 + 9 41 + 9 65 + 9 69 + 9 73 + 9 129 + 9 133 + 9 137 + 10 11 + 10 12 + 10 13 + 10 14 + 10 18 + 10 19 + 10 20 + 10 21 + 10 22 + 10 26 + 10 34 + 10 37 + 10 38 + 10 42 + 10 66 + 10 69 + 10 70 + 10 74 + 10 130 + 10 133 + 10 134 + 10 138 + 11 12 + 11 13 + 11 14 + 11 15 + 11 19 + 11 21 + 11 22 + 11 23 + 11 27 + 11 35 + 11 37 + 11 38 + 11 39 + 11 43 + 11 67 + 11 69 + 11 70 + 11 71 + 11 75 + 11 131 + 11 133 + 11 134 + 11 135 + 11 139 + 12 14 + 12 15 + 12 16 + 12 20 + 12 22 + 12 23 + 12 24 + 12 28 + 12 36 + 12 38 + 12 40 + 12 44 + 12 68 + 12 70 + 12 72 + 12 76 + 12 132 + 12 134 + 12 136 + 12 140 + 13 14 + 13 15 + 13 21 + 13 23 + 13 25 + 13 26 + 13 27 + 13 29 + 13 37 + 13 39 + 13 45 + 13 69 + 13 71 + 13 77 + 13 133 + 13 135 + 13 141 + 14 15 + 14 16 + 14 22 + 14 23 + 14 24 + 14 26 + 14 27 + 14 28 + 14 30 + 14 38 + 14 39 + 14 40 + 14 46 + 14 70 + 14 71 + 14 72 + 14 78 + 14 134 + 14 135 + 14 136 + 14 142 + 15 16 + 15 23 + 15 24 + 15 27 + 15 29 + 15 30 + 15 31 + 15 39 + 15 40 + 15 47 + 15 71 + 15 72 + 15 79 + 15 135 + 15 136 + 15 143 + 16 24 + 16 28 + 16 30 + 16 31 + 16 32 + 16 40 + 16 48 + 16 72 + 16 80 + 16 136 + 16 144 + 17 18 + 17 19 + 17 21 + 17 25 + 17 33 + 17 34 + 17 35 + 17 37 + 17 41 + 17 49 + 17 65 + 17 73 + 17 81 + 17 129 + 17 137 + 17 145 + 18 19 + 18 20 + 18 21 + 18 22 + 18 25 + 18 26 + 18 34 + 18 35 + 18 36 + 18 38 + 18 41 + 18 42 + 18 50 + 18 66 + 18 73 + 18 74 + 18 82 + 18 130 + 18 137 + 18 138 + 18 146 + 19 20 + 19 21 + 19 22 + 19 23 + 19 25 + 19 26 + 19 27 + 19 35 + 19 37 + 19 38 + 19 39 + 19 41 + 19 42 + 19 43 + 19 51 + 19 67 + 19 73 + 19 74 + 19 75 + 19 83 + 19 131 + 19 137 + 19 138 + 19 139 + 19 147 + 20 22 + 20 23 + 20 24 + 20 26 + 20 28 + 20 36 + 20 38 + 20 39 + 20 40 + 20 42 + 20 44 + 20 52 + 20 68 + 20 74 + 20 76 + 20 84 + 20 132 + 20 138 + 20 140 + 20 148 + 21 22 + 21 23 + 21 25 + 21 26 + 21 27 + 21 29 + 21 37 + 21 41 + 21 42 + 21 43 + 21 45 + 21 53 + 21 69 + 21 73 + 21 75 + 21 77 + 21 85 + 21 133 + 21 137 + 21 139 + 21 141 + 21 149 + 22 23 + 22 24 + 22 26 + 22 27 + 22 28 + 22 30 + 22 38 + 22 42 + 22 43 + 22 44 + 22 46 + 22 54 + 22 70 + 22 74 + 22 75 + 22 76 + 22 78 + 22 86 + 22 134 + 22 138 + 22 139 + 22 140 + 22 142 + 22 150 + 23 24 + 23 27 + 23 28 + 23 29 + 23 30 + 23 31 + 23 39 + 23 43 + 23 44 + 23 45 + 23 46 + 23 47 + 23 55 + 23 71 + 23 75 + 23 76 + 23 79 + 23 87 + 23 135 + 23 139 + 23 140 + 23 143 + 23 151 + 24 28 + 24 30 + 24 31 + 24 32 + 24 40 + 24 44 + 24 46 + 24 47 + 24 48 + 24 56 + 24 72 + 24 76 + 24 80 + 24 88 + 24 136 + 24 140 + 24 144 + 24 152 + 25 26 + 25 27 + 25 29 + 25 41 + 25 45 + 25 49 + 25 50 + 25 51 + 25 53 + 25 57 + 25 73 + 25 77 + 25 89 + 25 137 + 25 141 + 25 153 + 26 27 + 26 28 + 26 29 + 26 30 + 26 42 + 26 45 + 26 46 + 26 50 + 26 51 + 26 52 + 26 54 + 26 58 + 26 74 + 26 77 + 26 78 + 26 90 + 26 138 + 26 141 + 26 142 + 26 154 + 27 28 + 27 29 + 27 30 + 27 31 + 27 43 + 27 45 + 27 46 + 27 47 + 27 51 + 27 53 + 27 54 + 27 55 + 27 59 + 27 75 + 27 77 + 27 78 + 27 79 + 27 91 + 27 139 + 27 141 + 27 142 + 27 143 + 27 155 + 28 30 + 28 31 + 28 32 + 28 44 + 28 46 + 28 48 + 28 52 + 28 54 + 28 55 + 28 56 + 28 60 + 28 76 + 28 78 + 28 80 + 28 92 + 28 140 + 28 142 + 28 144 + 28 156 + 29 30 + 29 31 + 29 45 + 29 47 + 29 53 + 29 57 + 29 58 + 29 59 + 29 61 + 29 77 + 29 79 + 29 93 + 29 141 + 29 143 + 29 157 + 30 31 + 30 32 + 30 46 + 30 47 + 30 48 + 30 54 + 30 58 + 30 59 + 30 60 + 30 62 + 30 78 + 30 79 + 30 80 + 30 94 + 30 142 + 30 143 + 30 144 + 30 158 + 31 32 + 31 47 + 31 48 + 31 55 + 31 59 + 31 61 + 31 62 + 31 63 + 31 79 + 31 80 + 31 95 + 31 143 + 31 144 + 31 159 + 32 48 + 32 56 + 32 60 + 32 62 + 32 63 + 32 64 + 32 80 + 32 96 + 32 144 + 32 160 + 33 34 + 33 35 + 33 37 + 33 41 + 33 49 + 33 65 + 33 66 + 33 67 + 33 69 + 33 73 + 33 81 + 33 97 + 33 129 + 33 145 + 33 161 + 34 35 + 34 36 + 34 37 + 34 38 + 34 41 + 34 42 + 34 49 + 34 50 + 34 66 + 34 67 + 34 68 + 34 70 + 34 74 + 34 81 + 34 82 + 34 98 + 34 130 + 34 145 + 34 146 + 34 162 + 35 36 + 35 37 + 35 38 + 35 39 + 35 41 + 35 42 + 35 43 + 35 49 + 35 50 + 35 51 + 35 67 + 35 69 + 35 70 + 35 71 + 35 75 + 35 81 + 35 82 + 35 83 + 35 99 + 35 131 + 35 145 + 35 146 + 35 147 + 35 163 + 36 38 + 36 39 + 36 40 + 36 42 + 36 44 + 36 50 + 36 52 + 36 68 + 36 70 + 36 71 + 36 72 + 36 76 + 36 82 + 36 84 + 36 100 + 36 132 + 36 146 + 36 148 + 36 164 + 37 38 + 37 39 + 37 41 + 37 42 + 37 43 + 37 45 + 37 49 + 37 51 + 37 53 + 37 69 + 37 73 + 37 74 + 37 75 + 37 77 + 37 81 + 37 83 + 37 85 + 37 101 + 37 133 + 37 145 + 37 147 + 37 149 + 37 165 + 38 39 + 38 40 + 38 42 + 38 43 + 38 44 + 38 46 + 38 50 + 38 51 + 38 52 + 38 54 + 38 70 + 38 74 + 38 75 + 38 76 + 38 78 + 38 82 + 38 83 + 38 84 + 38 86 + 38 102 + 38 134 + 38 146 + 38 147 + 38 148 + 38 150 + 38 166 + 39 40 + 39 43 + 39 44 + 39 45 + 39 46 + 39 47 + 39 51 + 39 52 + 39 55 + 39 71 + 39 75 + 39 77 + 39 78 + 39 79 + 39 83 + 39 84 + 39 87 + 39 103 + 39 135 + 39 147 + 39 148 + 39 151 + 39 167 + 40 44 + 40 46 + 40 47 + 40 48 + 40 52 + 40 56 + 40 72 + 40 76 + 40 78 + 40 79 + 40 80 + 40 84 + 40 88 + 40 104 + 40 136 + 40 148 + 40 152 + 40 168 + 41 42 + 41 43 + 41 45 + 41 49 + 41 50 + 41 51 + 41 53 + 41 57 + 41 73 + 41 81 + 41 82 + 41 83 + 41 85 + 41 89 + 41 105 + 41 137 + 41 145 + 41 149 + 41 153 + 41 169 + 42 43 + 42 44 + 42 45 + 42 46 + 42 50 + 42 51 + 42 52 + 42 53 + 42 54 + 42 58 + 42 74 + 42 82 + 42 83 + 42 84 + 42 85 + 42 86 + 42 90 + 42 106 + 42 138 + 42 146 + 42 149 + 42 150 + 42 154 + 42 170 + 43 44 + 43 45 + 43 46 + 43 47 + 43 51 + 43 53 + 43 54 + 43 55 + 43 59 + 43 75 + 43 83 + 43 85 + 43 86 + 43 87 + 43 91 + 43 107 + 43 139 + 43 147 + 43 149 + 43 150 + 43 151 + 43 155 + 43 171 + 44 46 + 44 47 + 44 48 + 44 52 + 44 54 + 44 55 + 44 56 + 44 60 + 44 76 + 44 84 + 44 86 + 44 87 + 44 88 + 44 92 + 44 108 + 44 140 + 44 148 + 44 150 + 44 152 + 44 156 + 44 172 + 45 46 + 45 47 + 45 53 + 45 55 + 45 57 + 45 58 + 45 59 + 45 61 + 45 77 + 45 85 + 45 87 + 45 89 + 45 90 + 45 91 + 45 93 + 45 109 + 45 141 + 45 149 + 45 151 + 45 157 + 45 173 + 46 47 + 46 48 + 46 54 + 46 55 + 46 56 + 46 58 + 46 59 + 46 60 + 46 62 + 46 78 + 46 86 + 46 87 + 46 88 + 46 90 + 46 91 + 46 92 + 46 94 + 46 110 + 46 142 + 46 150 + 46 151 + 46 152 + 46 158 + 46 174 + 47 48 + 47 55 + 47 56 + 47 59 + 47 61 + 47 62 + 47 63 + 47 79 + 47 87 + 47 88 + 47 91 + 47 93 + 47 94 + 47 95 + 47 111 + 47 143 + 47 151 + 47 152 + 47 159 + 47 175 + 48 56 + 48 60 + 48 62 + 48 63 + 48 64 + 48 80 + 48 88 + 48 92 + 48 94 + 48 95 + 48 96 + 48 112 + 48 144 + 48 152 + 48 160 + 48 176 + 49 50 + 49 51 + 49 53 + 49 57 + 49 81 + 49 89 + 49 97 + 49 98 + 49 99 + 49 101 + 49 105 + 49 113 + 49 145 + 49 153 + 49 177 + 50 51 + 50 52 + 50 53 + 50 54 + 50 57 + 50 58 + 50 82 + 50 89 + 50 90 + 50 98 + 50 99 + 50 100 + 50 102 + 50 106 + 50 114 + 50 146 + 50 153 + 50 154 + 50 178 + 51 52 + 51 53 + 51 54 + 51 55 + 51 57 + 51 58 + 51 59 + 51 83 + 51 89 + 51 90 + 51 91 + 51 99 + 51 101 + 51 102 + 51 103 + 51 107 + 51 115 + 51 147 + 51 153 + 51 154 + 51 155 + 51 179 + 52 54 + 52 55 + 52 56 + 52 58 + 52 60 + 52 84 + 52 90 + 52 92 + 52 100 + 52 102 + 52 103 + 52 104 + 52 108 + 52 116 + 52 148 + 52 154 + 52 156 + 52 180 + 53 54 + 53 55 + 53 57 + 53 58 + 53 59 + 53 61 + 53 85 + 53 89 + 53 91 + 53 93 + 53 101 + 53 105 + 53 106 + 53 107 + 53 109 + 53 117 + 53 149 + 53 153 + 53 155 + 53 157 + 53 181 + 54 55 + 54 56 + 54 58 + 54 59 + 54 60 + 54 62 + 54 86 + 54 90 + 54 91 + 54 92 + 54 94 + 54 102 + 54 106 + 54 107 + 54 108 + 54 110 + 54 118 + 54 150 + 54 154 + 54 155 + 54 156 + 54 158 + 54 182 + 55 56 + 55 59 + 55 60 + 55 61 + 55 62 + 55 63 + 55 87 + 55 91 + 55 92 + 55 95 + 55 103 + 55 107 + 55 109 + 55 110 + 55 111 + 55 119 + 55 151 + 55 155 + 55 156 + 55 159 + 55 183 + 56 60 + 56 62 + 56 63 + 56 64 + 56 88 + 56 92 + 56 96 + 56 104 + 56 108 + 56 110 + 56 111 + 56 112 + 56 120 + 56 152 + 56 156 + 56 160 + 56 184 + 57 58 + 57 59 + 57 61 + 57 89 + 57 93 + 57 105 + 57 113 + 57 114 + 57 115 + 57 117 + 57 121 + 57 153 + 57 157 + 57 185 + 58 59 + 58 60 + 58 61 + 58 62 + 58 90 + 58 93 + 58 94 + 58 106 + 58 114 + 58 115 + 58 116 + 58 118 + 58 122 + 58 154 + 58 157 + 58 158 + 58 186 + 59 60 + 59 61 + 59 62 + 59 63 + 59 91 + 59 93 + 59 94 + 59 95 + 59 107 + 59 115 + 59 117 + 59 118 + 59 119 + 59 123 + 59 155 + 59 157 + 59 158 + 59 159 + 59 187 + 60 62 + 60 63 + 60 64 + 60 92 + 60 94 + 60 96 + 60 108 + 60 116 + 60 118 + 60 119 + 60 120 + 60 124 + 60 156 + 60 158 + 60 160 + 60 188 + 61 62 + 61 63 + 61 93 + 61 95 + 61 109 + 61 117 + 61 121 + 61 122 + 61 123 + 61 125 + 61 157 + 61 159 + 61 189 + 62 63 + 62 64 + 62 94 + 62 95 + 62 96 + 62 110 + 62 118 + 62 122 + 62 123 + 62 124 + 62 126 + 62 158 + 62 159 + 62 160 + 62 190 + 63 64 + 63 95 + 63 96 + 63 111 + 63 119 + 63 123 + 63 125 + 63 126 + 63 127 + 63 159 + 63 160 + 63 191 + 64 96 + 64 112 + 64 120 + 64 124 + 64 126 + 64 127 + 64 128 + 64 160 + 64 192 + 65 66 + 65 67 + 65 69 + 65 73 + 65 81 + 65 97 + 65 129 + 65 130 + 65 131 + 65 133 + 65 137 + 65 145 + 65 161 + 65 193 + 66 67 + 66 68 + 66 69 + 66 70 + 66 73 + 66 74 + 66 81 + 66 82 + 66 97 + 66 98 + 66 130 + 66 131 + 66 132 + 66 134 + 66 138 + 66 146 + 66 161 + 66 162 + 66 194 + 67 68 + 67 69 + 67 70 + 67 71 + 67 73 + 67 74 + 67 75 + 67 81 + 67 82 + 67 83 + 67 97 + 67 98 + 67 99 + 67 131 + 67 133 + 67 134 + 67 135 + 67 139 + 67 147 + 67 161 + 67 162 + 67 163 + 67 195 + 68 70 + 68 71 + 68 72 + 68 74 + 68 76 + 68 82 + 68 84 + 68 98 + 68 100 + 68 132 + 68 134 + 68 135 + 68 136 + 68 140 + 68 148 + 68 162 + 68 164 + 68 196 + 69 70 + 69 71 + 69 73 + 69 74 + 69 75 + 69 77 + 69 81 + 69 83 + 69 85 + 69 97 + 69 99 + 69 101 + 69 133 + 69 137 + 69 138 + 69 139 + 69 141 + 69 149 + 69 161 + 69 163 + 69 165 + 69 197 + 70 71 + 70 72 + 70 74 + 70 75 + 70 76 + 70 78 + 70 82 + 70 83 + 70 84 + 70 86 + 70 98 + 70 99 + 70 100 + 70 102 + 70 134 + 70 138 + 70 139 + 70 140 + 70 142 + 70 150 + 70 162 + 70 163 + 70 164 + 70 166 + 70 198 + 71 72 + 71 75 + 71 76 + 71 77 + 71 78 + 71 79 + 71 83 + 71 84 + 71 87 + 71 99 + 71 100 + 71 103 + 71 135 + 71 139 + 71 141 + 71 142 + 71 143 + 71 151 + 71 163 + 71 164 + 71 167 + 71 199 + 72 76 + 72 78 + 72 79 + 72 80 + 72 84 + 72 88 + 72 100 + 72 104 + 72 136 + 72 140 + 72 142 + 72 143 + 72 144 + 72 152 + 72 164 + 72 168 + 72 200 + 73 74 + 73 75 + 73 77 + 73 81 + 73 82 + 73 83 + 73 85 + 73 89 + 73 97 + 73 101 + 73 105 + 73 137 + 73 145 + 73 146 + 73 147 + 73 149 + 73 153 + 73 161 + 73 165 + 73 169 + 73 201 + 74 75 + 74 76 + 74 77 + 74 78 + 74 82 + 74 83 + 74 84 + 74 85 + 74 86 + 74 90 + 74 98 + 74 101 + 74 102 + 74 106 + 74 138 + 74 146 + 74 147 + 74 148 + 74 150 + 74 154 + 74 162 + 74 165 + 74 166 + 74 170 + 74 202 + 75 76 + 75 77 + 75 78 + 75 79 + 75 83 + 75 85 + 75 86 + 75 87 + 75 91 + 75 99 + 75 101 + 75 102 + 75 103 + 75 107 + 75 139 + 75 147 + 75 149 + 75 150 + 75 151 + 75 155 + 75 163 + 75 165 + 75 166 + 75 167 + 75 171 + 75 203 + 76 78 + 76 79 + 76 80 + 76 84 + 76 86 + 76 87 + 76 88 + 76 92 + 76 100 + 76 102 + 76 104 + 76 108 + 76 140 + 76 148 + 76 150 + 76 151 + 76 152 + 76 156 + 76 164 + 76 166 + 76 168 + 76 172 + 76 204 + 77 78 + 77 79 + 77 85 + 77 87 + 77 89 + 77 90 + 77 91 + 77 93 + 77 101 + 77 103 + 77 109 + 77 141 + 77 149 + 77 153 + 77 154 + 77 155 + 77 157 + 77 165 + 77 167 + 77 173 + 77 205 + 78 79 + 78 80 + 78 86 + 78 87 + 78 88 + 78 90 + 78 91 + 78 92 + 78 94 + 78 102 + 78 103 + 78 104 + 78 110 + 78 142 + 78 150 + 78 154 + 78 155 + 78 156 + 78 158 + 78 166 + 78 167 + 78 168 + 78 174 + 78 206 + 79 80 + 79 87 + 79 88 + 79 91 + 79 93 + 79 94 + 79 95 + 79 103 + 79 104 + 79 111 + 79 143 + 79 151 + 79 155 + 79 157 + 79 158 + 79 159 + 79 167 + 79 168 + 79 175 + 79 207 + 80 88 + 80 92 + 80 94 + 80 95 + 80 96 + 80 104 + 80 112 + 80 144 + 80 152 + 80 156 + 80 158 + 80 159 + 80 160 + 80 168 + 80 176 + 80 208 + 81 82 + 81 83 + 81 85 + 81 89 + 81 97 + 81 98 + 81 99 + 81 101 + 81 105 + 81 113 + 81 145 + 81 161 + 81 162 + 81 163 + 81 165 + 81 169 + 81 177 + 81 209 + 82 83 + 82 84 + 82 85 + 82 86 + 82 89 + 82 90 + 82 98 + 82 99 + 82 100 + 82 102 + 82 105 + 82 106 + 82 114 + 82 146 + 82 162 + 82 163 + 82 164 + 82 166 + 82 169 + 82 170 + 82 178 + 82 210 + 83 84 + 83 85 + 83 86 + 83 87 + 83 89 + 83 90 + 83 91 + 83 99 + 83 101 + 83 102 + 83 103 + 83 105 + 83 106 + 83 107 + 83 115 + 83 147 + 83 163 + 83 165 + 83 166 + 83 167 + 83 169 + 83 170 + 83 171 + 83 179 + 83 211 + 84 86 + 84 87 + 84 88 + 84 90 + 84 92 + 84 100 + 84 102 + 84 103 + 84 104 + 84 106 + 84 108 + 84 116 + 84 148 + 84 164 + 84 166 + 84 167 + 84 168 + 84 170 + 84 172 + 84 180 + 84 212 + 85 86 + 85 87 + 85 89 + 85 90 + 85 91 + 85 93 + 85 101 + 85 105 + 85 106 + 85 107 + 85 109 + 85 117 + 85 149 + 85 165 + 85 169 + 85 170 + 85 171 + 85 173 + 85 181 + 85 213 + 86 87 + 86 88 + 86 90 + 86 91 + 86 92 + 86 94 + 86 102 + 86 106 + 86 107 + 86 108 + 86 110 + 86 118 + 86 150 + 86 166 + 86 170 + 86 171 + 86 172 + 86 174 + 86 182 + 86 214 + 87 88 + 87 91 + 87 92 + 87 93 + 87 94 + 87 95 + 87 103 + 87 107 + 87 108 + 87 109 + 87 110 + 87 111 + 87 119 + 87 151 + 87 167 + 87 171 + 87 172 + 87 173 + 87 174 + 87 175 + 87 183 + 87 215 + 88 92 + 88 94 + 88 95 + 88 96 + 88 104 + 88 108 + 88 110 + 88 111 + 88 112 + 88 120 + 88 152 + 88 168 + 88 172 + 88 174 + 88 175 + 88 176 + 88 184 + 88 216 + 89 90 + 89 91 + 89 93 + 89 105 + 89 109 + 89 113 + 89 114 + 89 115 + 89 117 + 89 121 + 89 153 + 89 169 + 89 173 + 89 177 + 89 178 + 89 179 + 89 181 + 89 185 + 89 217 + 90 91 + 90 92 + 90 93 + 90 94 + 90 106 + 90 109 + 90 110 + 90 114 + 90 115 + 90 116 + 90 118 + 90 122 + 90 154 + 90 170 + 90 173 + 90 174 + 90 178 + 90 179 + 90 180 + 90 182 + 90 186 + 90 218 + 91 92 + 91 93 + 91 94 + 91 95 + 91 107 + 91 109 + 91 110 + 91 111 + 91 115 + 91 117 + 91 118 + 91 119 + 91 123 + 91 155 + 91 171 + 91 173 + 91 174 + 91 175 + 91 179 + 91 181 + 91 182 + 91 183 + 91 187 + 91 219 + 92 94 + 92 95 + 92 96 + 92 108 + 92 110 + 92 112 + 92 116 + 92 118 + 92 119 + 92 120 + 92 124 + 92 156 + 92 172 + 92 174 + 92 176 + 92 180 + 92 182 + 92 183 + 92 184 + 92 188 + 92 220 + 93 94 + 93 95 + 93 109 + 93 111 + 93 117 + 93 121 + 93 122 + 93 123 + 93 125 + 93 157 + 93 173 + 93 175 + 93 181 + 93 185 + 93 186 + 93 187 + 93 189 + 93 221 + 94 95 + 94 96 + 94 110 + 94 111 + 94 112 + 94 118 + 94 122 + 94 123 + 94 124 + 94 126 + 94 158 + 94 174 + 94 175 + 94 176 + 94 182 + 94 186 + 94 187 + 94 188 + 94 190 + 94 222 + 95 96 + 95 111 + 95 112 + 95 119 + 95 123 + 95 125 + 95 126 + 95 127 + 95 159 + 95 175 + 95 176 + 95 183 + 95 187 + 95 189 + 95 190 + 95 191 + 95 223 + 96 112 + 96 120 + 96 124 + 96 126 + 96 127 + 96 128 + 96 160 + 96 176 + 96 184 + 96 188 + 96 190 + 96 191 + 96 192 + 96 224 + 97 98 + 97 99 + 97 101 + 97 105 + 97 113 + 97 161 + 97 177 + 97 193 + 97 194 + 97 195 + 97 197 + 97 201 + 97 209 + 97 225 + 98 99 + 98 100 + 98 101 + 98 102 + 98 105 + 98 106 + 98 113 + 98 114 + 98 162 + 98 177 + 98 178 + 98 194 + 98 195 + 98 196 + 98 198 + 98 202 + 98 210 + 98 226 + 99 100 + 99 101 + 99 102 + 99 103 + 99 105 + 99 106 + 99 107 + 99 113 + 99 114 + 99 115 + 99 163 + 99 177 + 99 178 + 99 179 + 99 195 + 99 197 + 99 198 + 99 199 + 99 203 + 99 211 + 99 227 + 100 102 + 100 103 + 100 104 + 100 106 + 100 108 + 100 114 + 100 116 + 100 164 + 100 178 + 100 180 + 100 196 + 100 198 + 100 199 + 100 200 + 100 204 + 100 212 + 100 228 + 101 102 + 101 103 + 101 105 + 101 106 + 101 107 + 101 109 + 101 113 + 101 115 + 101 117 + 101 165 + 101 177 + 101 179 + 101 181 + 101 197 + 101 201 + 101 202 + 101 203 + 101 205 + 101 213 + 101 229 + 102 103 + 102 104 + 102 106 + 102 107 + 102 108 + 102 110 + 102 114 + 102 115 + 102 116 + 102 118 + 102 166 + 102 178 + 102 179 + 102 180 + 102 182 + 102 198 + 102 202 + 102 203 + 102 204 + 102 206 + 102 214 + 102 230 + 103 104 + 103 107 + 103 108 + 103 109 + 103 110 + 103 111 + 103 115 + 103 116 + 103 119 + 103 167 + 103 179 + 103 180 + 103 183 + 103 199 + 103 203 + 103 205 + 103 206 + 103 207 + 103 215 + 103 231 + 104 108 + 104 110 + 104 111 + 104 112 + 104 116 + 104 120 + 104 168 + 104 180 + 104 184 + 104 200 + 104 204 + 104 206 + 104 207 + 104 208 + 104 216 + 104 232 + 105 106 + 105 107 + 105 109 + 105 113 + 105 114 + 105 115 + 105 117 + 105 121 + 105 169 + 105 177 + 105 181 + 105 185 + 105 201 + 105 209 + 105 210 + 105 211 + 105 213 + 105 217 + 105 233 + 106 107 + 106 108 + 106 109 + 106 110 + 106 114 + 106 115 + 106 116 + 106 117 + 106 118 + 106 122 + 106 170 + 106 178 + 106 181 + 106 182 + 106 186 + 106 202 + 106 210 + 106 211 + 106 212 + 106 214 + 106 218 + 106 234 + 107 108 + 107 109 + 107 110 + 107 111 + 107 115 + 107 117 + 107 118 + 107 119 + 107 123 + 107 171 + 107 179 + 107 181 + 107 182 + 107 183 + 107 187 + 107 203 + 107 211 + 107 213 + 107 214 + 107 215 + 107 219 + 107 235 + 108 110 + 108 111 + 108 112 + 108 116 + 108 118 + 108 119 + 108 120 + 108 124 + 108 172 + 108 180 + 108 182 + 108 184 + 108 188 + 108 204 + 108 212 + 108 214 + 108 215 + 108 216 + 108 220 + 108 236 + 109 110 + 109 111 + 109 117 + 109 119 + 109 121 + 109 122 + 109 123 + 109 125 + 109 173 + 109 181 + 109 183 + 109 189 + 109 205 + 109 213 + 109 217 + 109 218 + 109 219 + 109 221 + 109 237 + 110 111 + 110 112 + 110 118 + 110 119 + 110 120 + 110 122 + 110 123 + 110 124 + 110 126 + 110 174 + 110 182 + 110 183 + 110 184 + 110 190 + 110 206 + 110 214 + 110 218 + 110 219 + 110 220 + 110 222 + 110 238 + 111 112 + 111 119 + 111 120 + 111 123 + 111 125 + 111 126 + 111 127 + 111 175 + 111 183 + 111 184 + 111 191 + 111 207 + 111 215 + 111 219 + 111 221 + 111 222 + 111 223 + 111 239 + 112 120 + 112 124 + 112 126 + 112 127 + 112 128 + 112 176 + 112 184 + 112 192 + 112 208 + 112 216 + 112 220 + 112 222 + 112 223 + 112 224 + 112 240 + 113 114 + 113 115 + 113 117 + 113 121 + 113 177 + 113 185 + 113 209 + 113 225 + 113 226 + 113 227 + 113 229 + 113 233 + 113 241 + 114 115 + 114 116 + 114 117 + 114 118 + 114 121 + 114 122 + 114 178 + 114 185 + 114 186 + 114 210 + 114 226 + 114 227 + 114 228 + 114 230 + 114 234 + 114 242 + 115 116 + 115 117 + 115 118 + 115 119 + 115 121 + 115 122 + 115 123 + 115 179 + 115 185 + 115 186 + 115 187 + 115 211 + 115 227 + 115 229 + 115 230 + 115 231 + 115 235 + 115 243 + 116 118 + 116 119 + 116 120 + 116 122 + 116 124 + 116 180 + 116 186 + 116 188 + 116 212 + 116 228 + 116 230 + 116 231 + 116 232 + 116 236 + 116 244 + 117 118 + 117 119 + 117 121 + 117 122 + 117 123 + 117 125 + 117 181 + 117 185 + 117 187 + 117 189 + 117 213 + 117 229 + 117 233 + 117 234 + 117 235 + 117 237 + 117 245 + 118 119 + 118 120 + 118 122 + 118 123 + 118 124 + 118 126 + 118 182 + 118 186 + 118 187 + 118 188 + 118 190 + 118 214 + 118 230 + 118 234 + 118 235 + 118 236 + 118 238 + 118 246 + 119 120 + 119 123 + 119 124 + 119 125 + 119 126 + 119 127 + 119 183 + 119 187 + 119 188 + 119 191 + 119 215 + 119 231 + 119 235 + 119 237 + 119 238 + 119 239 + 119 247 + 120 124 + 120 126 + 120 127 + 120 128 + 120 184 + 120 188 + 120 192 + 120 216 + 120 232 + 120 236 + 120 238 + 120 239 + 120 240 + 120 248 + 121 122 + 121 123 + 121 125 + 121 185 + 121 189 + 121 217 + 121 233 + 121 241 + 121 242 + 121 243 + 121 245 + 121 249 + 122 123 + 122 124 + 122 125 + 122 126 + 122 186 + 122 189 + 122 190 + 122 218 + 122 234 + 122 242 + 122 243 + 122 244 + 122 246 + 122 250 + 123 124 + 123 125 + 123 126 + 123 127 + 123 187 + 123 189 + 123 190 + 123 191 + 123 219 + 123 235 + 123 243 + 123 245 + 123 246 + 123 247 + 123 251 + 124 126 + 124 127 + 124 128 + 124 188 + 124 190 + 124 192 + 124 220 + 124 236 + 124 244 + 124 246 + 124 247 + 124 248 + 124 252 + 125 126 + 125 127 + 125 189 + 125 191 + 125 221 + 125 237 + 125 245 + 125 249 + 125 250 + 125 251 + 125 253 + 126 127 + 126 128 + 126 190 + 126 191 + 126 192 + 126 222 + 126 238 + 126 246 + 126 250 + 126 251 + 126 252 + 126 254 + 127 128 + 127 191 + 127 192 + 127 223 + 127 239 + 127 247 + 127 251 + 127 253 + 127 254 + 127 255 + 128 192 + 128 224 + 128 240 + 128 248 + 128 252 + 128 254 + 128 255 + 128 256 + 129 130 + 129 131 + 129 133 + 129 137 + 129 145 + 129 161 + 129 193 + 130 131 + 130 132 + 130 133 + 130 134 + 130 137 + 130 138 + 130 145 + 130 146 + 130 161 + 130 162 + 130 193 + 130 194 + 131 132 + 131 133 + 131 134 + 131 135 + 131 137 + 131 138 + 131 139 + 131 145 + 131 146 + 131 147 + 131 161 + 131 162 + 131 163 + 131 193 + 131 194 + 131 195 + 132 134 + 132 135 + 132 136 + 132 138 + 132 140 + 132 146 + 132 148 + 132 162 + 132 164 + 132 194 + 132 196 + 133 134 + 133 135 + 133 137 + 133 138 + 133 139 + 133 141 + 133 145 + 133 147 + 133 149 + 133 161 + 133 163 + 133 165 + 133 193 + 133 195 + 133 197 + 134 135 + 134 136 + 134 138 + 134 139 + 134 140 + 134 142 + 134 146 + 134 147 + 134 148 + 134 150 + 134 162 + 134 163 + 134 164 + 134 166 + 134 194 + 134 195 + 134 196 + 134 198 + 135 136 + 135 139 + 135 140 + 135 141 + 135 142 + 135 143 + 135 147 + 135 148 + 135 151 + 135 163 + 135 164 + 135 167 + 135 195 + 135 196 + 135 199 + 136 140 + 136 142 + 136 143 + 136 144 + 136 148 + 136 152 + 136 164 + 136 168 + 136 196 + 136 200 + 137 138 + 137 139 + 137 141 + 137 145 + 137 146 + 137 147 + 137 149 + 137 153 + 137 161 + 137 165 + 137 169 + 137 193 + 137 197 + 137 201 + 138 139 + 138 140 + 138 141 + 138 142 + 138 146 + 138 147 + 138 148 + 138 149 + 138 150 + 138 154 + 138 162 + 138 165 + 138 166 + 138 170 + 138 194 + 138 197 + 138 198 + 138 202 + 139 140 + 139 141 + 139 142 + 139 143 + 139 147 + 139 149 + 139 150 + 139 151 + 139 155 + 139 163 + 139 165 + 139 166 + 139 167 + 139 171 + 139 195 + 139 197 + 139 198 + 139 199 + 139 203 + 140 142 + 140 143 + 140 144 + 140 148 + 140 150 + 140 151 + 140 152 + 140 156 + 140 164 + 140 166 + 140 168 + 140 172 + 140 196 + 140 198 + 140 200 + 140 204 + 141 142 + 141 143 + 141 149 + 141 151 + 141 153 + 141 154 + 141 155 + 141 157 + 141 165 + 141 167 + 141 173 + 141 197 + 141 199 + 141 205 + 142 143 + 142 144 + 142 150 + 142 151 + 142 152 + 142 154 + 142 155 + 142 156 + 142 158 + 142 166 + 142 167 + 142 168 + 142 174 + 142 198 + 142 199 + 142 200 + 142 206 + 143 144 + 143 151 + 143 152 + 143 155 + 143 157 + 143 158 + 143 159 + 143 167 + 143 168 + 143 175 + 143 199 + 143 200 + 143 207 + 144 152 + 144 156 + 144 158 + 144 159 + 144 160 + 144 168 + 144 176 + 144 200 + 144 208 + 145 146 + 145 147 + 145 149 + 145 153 + 145 161 + 145 162 + 145 163 + 145 165 + 145 169 + 145 177 + 145 193 + 145 201 + 145 209 + 146 147 + 146 148 + 146 149 + 146 150 + 146 153 + 146 154 + 146 162 + 146 163 + 146 164 + 146 166 + 146 169 + 146 170 + 146 178 + 146 194 + 146 201 + 146 202 + 146 210 + 147 148 + 147 149 + 147 150 + 147 151 + 147 153 + 147 154 + 147 155 + 147 163 + 147 165 + 147 166 + 147 167 + 147 169 + 147 170 + 147 171 + 147 179 + 147 195 + 147 201 + 147 202 + 147 203 + 147 211 + 148 150 + 148 151 + 148 152 + 148 154 + 148 156 + 148 164 + 148 166 + 148 167 + 148 168 + 148 170 + 148 172 + 148 180 + 148 196 + 148 202 + 148 204 + 148 212 + 149 150 + 149 151 + 149 153 + 149 154 + 149 155 + 149 157 + 149 165 + 149 169 + 149 170 + 149 171 + 149 173 + 149 181 + 149 197 + 149 201 + 149 203 + 149 205 + 149 213 + 150 151 + 150 152 + 150 154 + 150 155 + 150 156 + 150 158 + 150 166 + 150 170 + 150 171 + 150 172 + 150 174 + 150 182 + 150 198 + 150 202 + 150 203 + 150 204 + 150 206 + 150 214 + 151 152 + 151 155 + 151 156 + 151 157 + 151 158 + 151 159 + 151 167 + 151 171 + 151 172 + 151 173 + 151 174 + 151 175 + 151 183 + 151 199 + 151 203 + 151 204 + 151 207 + 151 215 + 152 156 + 152 158 + 152 159 + 152 160 + 152 168 + 152 172 + 152 174 + 152 175 + 152 176 + 152 184 + 152 200 + 152 204 + 152 208 + 152 216 + 153 154 + 153 155 + 153 157 + 153 169 + 153 173 + 153 177 + 153 178 + 153 179 + 153 181 + 153 185 + 153 201 + 153 205 + 153 217 + 154 155 + 154 156 + 154 157 + 154 158 + 154 170 + 154 173 + 154 174 + 154 178 + 154 179 + 154 180 + 154 182 + 154 186 + 154 202 + 154 205 + 154 206 + 154 218 + 155 156 + 155 157 + 155 158 + 155 159 + 155 171 + 155 173 + 155 174 + 155 175 + 155 179 + 155 181 + 155 182 + 155 183 + 155 187 + 155 203 + 155 205 + 155 206 + 155 207 + 155 219 + 156 158 + 156 159 + 156 160 + 156 172 + 156 174 + 156 176 + 156 180 + 156 182 + 156 183 + 156 184 + 156 188 + 156 204 + 156 206 + 156 208 + 156 220 + 157 158 + 157 159 + 157 173 + 157 175 + 157 181 + 157 185 + 157 186 + 157 187 + 157 189 + 157 205 + 157 207 + 157 221 + 158 159 + 158 160 + 158 174 + 158 175 + 158 176 + 158 182 + 158 186 + 158 187 + 158 188 + 158 190 + 158 206 + 158 207 + 158 208 + 158 222 + 159 160 + 159 175 + 159 176 + 159 183 + 159 187 + 159 189 + 159 190 + 159 191 + 159 207 + 159 208 + 159 223 + 160 176 + 160 184 + 160 188 + 160 190 + 160 191 + 160 192 + 160 208 + 160 224 + 161 162 + 161 163 + 161 165 + 161 169 + 161 177 + 161 193 + 161 194 + 161 195 + 161 197 + 161 201 + 161 209 + 161 225 + 162 163 + 162 164 + 162 165 + 162 166 + 162 169 + 162 170 + 162 177 + 162 178 + 162 194 + 162 195 + 162 196 + 162 198 + 162 202 + 162 209 + 162 210 + 162 226 + 163 164 + 163 165 + 163 166 + 163 167 + 163 169 + 163 170 + 163 171 + 163 177 + 163 178 + 163 179 + 163 195 + 163 197 + 163 198 + 163 199 + 163 203 + 163 209 + 163 210 + 163 211 + 163 227 + 164 166 + 164 167 + 164 168 + 164 170 + 164 172 + 164 178 + 164 180 + 164 196 + 164 198 + 164 199 + 164 200 + 164 204 + 164 210 + 164 212 + 164 228 + 165 166 + 165 167 + 165 169 + 165 170 + 165 171 + 165 173 + 165 177 + 165 179 + 165 181 + 165 197 + 165 201 + 165 202 + 165 203 + 165 205 + 165 209 + 165 211 + 165 213 + 165 229 + 166 167 + 166 168 + 166 170 + 166 171 + 166 172 + 166 174 + 166 178 + 166 179 + 166 180 + 166 182 + 166 198 + 166 202 + 166 203 + 166 204 + 166 206 + 166 210 + 166 211 + 166 212 + 166 214 + 166 230 + 167 168 + 167 171 + 167 172 + 167 173 + 167 174 + 167 175 + 167 179 + 167 180 + 167 183 + 167 199 + 167 203 + 167 205 + 167 206 + 167 207 + 167 211 + 167 212 + 167 215 + 167 231 + 168 172 + 168 174 + 168 175 + 168 176 + 168 180 + 168 184 + 168 200 + 168 204 + 168 206 + 168 207 + 168 208 + 168 212 + 168 216 + 168 232 + 169 170 + 169 171 + 169 173 + 169 177 + 169 178 + 169 179 + 169 181 + 169 185 + 169 201 + 169 209 + 169 210 + 169 211 + 169 213 + 169 217 + 169 233 + 170 171 + 170 172 + 170 173 + 170 174 + 170 178 + 170 179 + 170 180 + 170 181 + 170 182 + 170 186 + 170 202 + 170 210 + 170 211 + 170 212 + 170 213 + 170 214 + 170 218 + 170 234 + 171 172 + 171 173 + 171 174 + 171 175 + 171 179 + 171 181 + 171 182 + 171 183 + 171 187 + 171 203 + 171 211 + 171 213 + 171 214 + 171 215 + 171 219 + 171 235 + 172 174 + 172 175 + 172 176 + 172 180 + 172 182 + 172 183 + 172 184 + 172 188 + 172 204 + 172 212 + 172 214 + 172 215 + 172 216 + 172 220 + 172 236 + 173 174 + 173 175 + 173 181 + 173 183 + 173 185 + 173 186 + 173 187 + 173 189 + 173 205 + 173 213 + 173 215 + 173 217 + 173 218 + 173 219 + 173 221 + 173 237 + 174 175 + 174 176 + 174 182 + 174 183 + 174 184 + 174 186 + 174 187 + 174 188 + 174 190 + 174 206 + 174 214 + 174 215 + 174 216 + 174 218 + 174 219 + 174 220 + 174 222 + 174 238 + 175 176 + 175 183 + 175 184 + 175 187 + 175 189 + 175 190 + 175 191 + 175 207 + 175 215 + 175 216 + 175 219 + 175 221 + 175 222 + 175 223 + 175 239 + 176 184 + 176 188 + 176 190 + 176 191 + 176 192 + 176 208 + 176 216 + 176 220 + 176 222 + 176 223 + 176 224 + 176 240 + 177 178 + 177 179 + 177 181 + 177 185 + 177 209 + 177 217 + 177 225 + 177 226 + 177 227 + 177 229 + 177 233 + 177 241 + 178 179 + 178 180 + 178 181 + 178 182 + 178 185 + 178 186 + 178 210 + 178 217 + 178 218 + 178 226 + 178 227 + 178 228 + 178 230 + 178 234 + 178 242 + 179 180 + 179 181 + 179 182 + 179 183 + 179 185 + 179 186 + 179 187 + 179 211 + 179 217 + 179 218 + 179 219 + 179 227 + 179 229 + 179 230 + 179 231 + 179 235 + 179 243 + 180 182 + 180 183 + 180 184 + 180 186 + 180 188 + 180 212 + 180 218 + 180 220 + 180 228 + 180 230 + 180 231 + 180 232 + 180 236 + 180 244 + 181 182 + 181 183 + 181 185 + 181 186 + 181 187 + 181 189 + 181 213 + 181 217 + 181 219 + 181 221 + 181 229 + 181 233 + 181 234 + 181 235 + 181 237 + 181 245 + 182 183 + 182 184 + 182 186 + 182 187 + 182 188 + 182 190 + 182 214 + 182 218 + 182 219 + 182 220 + 182 222 + 182 230 + 182 234 + 182 235 + 182 236 + 182 238 + 182 246 + 183 184 + 183 187 + 183 188 + 183 189 + 183 190 + 183 191 + 183 215 + 183 219 + 183 220 + 183 223 + 183 231 + 183 235 + 183 237 + 183 238 + 183 239 + 183 247 + 184 188 + 184 190 + 184 191 + 184 192 + 184 216 + 184 220 + 184 224 + 184 232 + 184 236 + 184 238 + 184 239 + 184 240 + 184 248 + 185 186 + 185 187 + 185 189 + 185 217 + 185 221 + 185 233 + 185 241 + 185 242 + 185 243 + 185 245 + 185 249 + 186 187 + 186 188 + 186 189 + 186 190 + 186 218 + 186 221 + 186 222 + 186 234 + 186 242 + 186 243 + 186 244 + 186 246 + 186 250 + 187 188 + 187 189 + 187 190 + 187 191 + 187 219 + 187 221 + 187 222 + 187 223 + 187 235 + 187 243 + 187 245 + 187 246 + 187 247 + 187 251 + 188 190 + 188 191 + 188 192 + 188 220 + 188 222 + 188 224 + 188 236 + 188 244 + 188 246 + 188 247 + 188 248 + 188 252 + 189 190 + 189 191 + 189 221 + 189 223 + 189 237 + 189 245 + 189 249 + 189 250 + 189 251 + 189 253 + 190 191 + 190 192 + 190 222 + 190 223 + 190 224 + 190 238 + 190 246 + 190 250 + 190 251 + 190 252 + 190 254 + 191 192 + 191 223 + 191 224 + 191 239 + 191 247 + 191 251 + 191 253 + 191 254 + 191 255 + 192 224 + 192 240 + 192 248 + 192 252 + 192 254 + 192 255 + 192 256 + 193 194 + 193 195 + 193 197 + 193 201 + 193 209 + 193 225 + 194 195 + 194 196 + 194 197 + 194 198 + 194 201 + 194 202 + 194 209 + 194 210 + 194 225 + 194 226 + 195 196 + 195 197 + 195 198 + 195 199 + 195 201 + 195 202 + 195 203 + 195 209 + 195 210 + 195 211 + 195 225 + 195 226 + 195 227 + 196 198 + 196 199 + 196 200 + 196 202 + 196 204 + 196 210 + 196 212 + 196 226 + 196 228 + 197 198 + 197 199 + 197 201 + 197 202 + 197 203 + 197 205 + 197 209 + 197 211 + 197 213 + 197 225 + 197 227 + 197 229 + 198 199 + 198 200 + 198 202 + 198 203 + 198 204 + 198 206 + 198 210 + 198 211 + 198 212 + 198 214 + 198 226 + 198 227 + 198 228 + 198 230 + 199 200 + 199 203 + 199 204 + 199 205 + 199 206 + 199 207 + 199 211 + 199 212 + 199 215 + 199 227 + 199 228 + 199 231 + 200 204 + 200 206 + 200 207 + 200 208 + 200 212 + 200 216 + 200 228 + 200 232 + 201 202 + 201 203 + 201 205 + 201 209 + 201 210 + 201 211 + 201 213 + 201 217 + 201 225 + 201 229 + 201 233 + 202 203 + 202 204 + 202 205 + 202 206 + 202 210 + 202 211 + 202 212 + 202 213 + 202 214 + 202 218 + 202 226 + 202 229 + 202 230 + 202 234 + 203 204 + 203 205 + 203 206 + 203 207 + 203 211 + 203 213 + 203 214 + 203 215 + 203 219 + 203 227 + 203 229 + 203 230 + 203 231 + 203 235 + 204 206 + 204 207 + 204 208 + 204 212 + 204 214 + 204 215 + 204 216 + 204 220 + 204 228 + 204 230 + 204 232 + 204 236 + 205 206 + 205 207 + 205 213 + 205 215 + 205 217 + 205 218 + 205 219 + 205 221 + 205 229 + 205 231 + 205 237 + 206 207 + 206 208 + 206 214 + 206 215 + 206 216 + 206 218 + 206 219 + 206 220 + 206 222 + 206 230 + 206 231 + 206 232 + 206 238 + 207 208 + 207 215 + 207 216 + 207 219 + 207 221 + 207 222 + 207 223 + 207 231 + 207 232 + 207 239 + 208 216 + 208 220 + 208 222 + 208 223 + 208 224 + 208 232 + 208 240 + 209 210 + 209 211 + 209 213 + 209 217 + 209 225 + 209 226 + 209 227 + 209 229 + 209 233 + 209 241 + 210 211 + 210 212 + 210 213 + 210 214 + 210 217 + 210 218 + 210 226 + 210 227 + 210 228 + 210 230 + 210 233 + 210 234 + 210 242 + 211 212 + 211 213 + 211 214 + 211 215 + 211 217 + 211 218 + 211 219 + 211 227 + 211 229 + 211 230 + 211 231 + 211 233 + 211 234 + 211 235 + 211 243 + 212 214 + 212 215 + 212 216 + 212 218 + 212 220 + 212 228 + 212 230 + 212 231 + 212 232 + 212 234 + 212 236 + 212 244 + 213 214 + 213 215 + 213 217 + 213 218 + 213 219 + 213 221 + 213 229 + 213 233 + 213 234 + 213 235 + 213 237 + 213 245 + 214 215 + 214 216 + 214 218 + 214 219 + 214 220 + 214 222 + 214 230 + 214 234 + 214 235 + 214 236 + 214 238 + 214 246 + 215 216 + 215 219 + 215 220 + 215 221 + 215 222 + 215 223 + 215 231 + 215 235 + 215 236 + 215 237 + 215 238 + 215 239 + 215 247 + 216 220 + 216 222 + 216 223 + 216 224 + 216 232 + 216 236 + 216 238 + 216 239 + 216 240 + 216 248 + 217 218 + 217 219 + 217 221 + 217 233 + 217 237 + 217 241 + 217 242 + 217 243 + 217 245 + 217 249 + 218 219 + 218 220 + 218 221 + 218 222 + 218 234 + 218 237 + 218 238 + 218 242 + 218 243 + 218 244 + 218 246 + 218 250 + 219 220 + 219 221 + 219 222 + 219 223 + 219 235 + 219 237 + 219 238 + 219 239 + 219 243 + 219 245 + 219 246 + 219 247 + 219 251 + 220 222 + 220 223 + 220 224 + 220 236 + 220 238 + 220 240 + 220 244 + 220 246 + 220 247 + 220 248 + 220 252 + 221 222 + 221 223 + 221 237 + 221 239 + 221 245 + 221 249 + 221 250 + 221 251 + 221 253 + 222 223 + 222 224 + 222 238 + 222 239 + 222 240 + 222 246 + 222 250 + 222 251 + 222 252 + 222 254 + 223 224 + 223 239 + 223 240 + 223 247 + 223 251 + 223 253 + 223 254 + 223 255 + 224 240 + 224 248 + 224 252 + 224 254 + 224 255 + 224 256 + 225 226 + 225 227 + 225 229 + 225 233 + 225 241 + 226 227 + 226 228 + 226 229 + 226 230 + 226 233 + 226 234 + 226 241 + 226 242 + 227 228 + 227 229 + 227 230 + 227 231 + 227 233 + 227 234 + 227 235 + 227 241 + 227 242 + 227 243 + 228 230 + 228 231 + 228 232 + 228 234 + 228 236 + 228 242 + 228 244 + 229 230 + 229 231 + 229 233 + 229 234 + 229 235 + 229 237 + 229 241 + 229 243 + 229 245 + 230 231 + 230 232 + 230 234 + 230 235 + 230 236 + 230 238 + 230 242 + 230 243 + 230 244 + 230 246 + 231 232 + 231 235 + 231 236 + 231 237 + 231 238 + 231 239 + 231 243 + 231 244 + 231 247 + 232 236 + 232 238 + 232 239 + 232 240 + 232 244 + 232 248 + 233 234 + 233 235 + 233 237 + 233 241 + 233 242 + 233 243 + 233 245 + 233 249 + 234 235 + 234 236 + 234 237 + 234 238 + 234 242 + 234 243 + 234 244 + 234 245 + 234 246 + 234 250 + 235 236 + 235 237 + 235 238 + 235 239 + 235 243 + 235 245 + 235 246 + 235 247 + 235 251 + 236 238 + 236 239 + 236 240 + 236 244 + 236 246 + 236 247 + 236 248 + 236 252 + 237 238 + 237 239 + 237 245 + 237 247 + 237 249 + 237 250 + 237 251 + 237 253 + 238 239 + 238 240 + 238 246 + 238 247 + 238 248 + 238 250 + 238 251 + 238 252 + 238 254 + 239 240 + 239 247 + 239 248 + 239 251 + 239 253 + 239 254 + 239 255 + 240 248 + 240 252 + 240 254 + 240 255 + 240 256 + 241 242 + 241 243 + 241 245 + 241 249 + 242 243 + 242 244 + 242 245 + 242 246 + 242 249 + 242 250 + 243 244 + 243 245 + 243 246 + 243 247 + 243 249 + 243 250 + 243 251 + 244 246 + 244 247 + 244 248 + 244 250 + 244 252 + 245 246 + 245 247 + 245 249 + 245 250 + 245 251 + 245 253 + 246 247 + 246 248 + 246 250 + 246 251 + 246 252 + 246 254 + 247 248 + 247 251 + 247 252 + 247 253 + 247 254 + 247 255 + 248 252 + 248 254 + 248 255 + 248 256 + 249 250 + 249 251 + 249 253 + 250 251 + 250 252 + 250 253 + 250 254 + 251 252 + 251 253 + 251 254 + 251 255 + 252 254 + 252 255 + 252 256 + 253 254 + 253 255 + 254 255 + 254 256 + 255 256 +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/money.mod b/resources/3rdparty/glpk-4.57/examples/money.mod new file mode 100644 index 000000000..e43ef390b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/money.mod @@ -0,0 +1,62 @@ +/* MONEY, a crypto-arithmetic puzzle */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* This is the classic example of a crypto-arithmetic puzzle published + in the Strand Magazine by Henry Dudeney: + + S E N D + + + M O R E + --------- + M O N E Y + + In this puzzle the same letters mean the same digits. The question + is: how to replace all the letters with the respective digits that + makes the calculation correct? + + The solution to this puzzle is: + O = 0, M = 1, Y = 2, E = 5, N = 6, D = 7, R = 8, and S = 9. + + References: + H. E. Dudeney, in Strand Magazine vol. 68 (July 1924), pp. 97, 214. + + (From Wikipedia, the free encyclopedia.) */ + +set LETTERS := { 'D', 'E', 'M', 'N', 'O', 'R', 'S', 'Y' }; +/* set of letters */ + +set DIGITS := 0..9; +/* set of digits */ + +var x{i in LETTERS, d in DIGITS}, binary; +/* x[i,d] = 1 means that letter i is digit d */ + +s.t. one{i in LETTERS}: sum{d in DIGITS} x[i,d] = 1; +/* each letter must correspond exactly to one digit */ + +s.t. alldiff{d in DIGITS}: sum{i in LETTERS} x[i,d] <= 1; +/* different letters must correspond to different digits; note that + some digits may not correspond to any letters at all */ + +var dig{i in LETTERS}; +/* dig[i] is a digit corresponding to letter i */ + +s.t. map{i in LETTERS}: dig[i] = sum{d in DIGITS} d * x[i,d]; + +var carry{1..3}, binary; +/* carry bits */ + +s.t. sum1: dig['D'] + dig['E'] = dig['Y'] + 10 * carry[1]; +s.t. sum2: dig['N'] + dig['R'] + carry[1] = dig['E'] + 10 * carry[2]; +s.t. sum3: dig['E'] + dig['O'] + carry[2] = dig['N'] + 10 * carry[3]; +s.t. sum4: dig['S'] + dig['M'] + carry[3] = dig['O'] + 10 * dig['M']; +s.t. note: dig['M'] >= 1; /* M must not be 0 */ + +solve; +/* solve the puzzle */ + +display dig; +/* and display its solution */ + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/mplsamp1.c b/resources/3rdparty/glpk-4.57/examples/mplsamp1.c new file mode 100644 index 000000000..7c5e47d4d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/mplsamp1.c @@ -0,0 +1,32 @@ +/* mplsamp1.c */ + +#include +#include +#include + +int main(void) +{ glp_prob *lp; + glp_tran *tran; + int ret; + lp = glp_create_prob(); + tran = glp_mpl_alloc_wksp(); + ret = glp_mpl_read_model(tran, "egypt.mod", 0); + if (ret != 0) + { fprintf(stderr, "Error on translating model\n"); + goto skip; + } + ret = glp_mpl_generate(tran, NULL); + if (ret != 0) + { fprintf(stderr, "Error on generating model\n"); + goto skip; + } + glp_mpl_build_prob(tran, lp); + ret = glp_write_mps(lp, GLP_MPS_FILE, NULL, "egypt.mps"); + if (ret != 0) + fprintf(stderr, "Error on writing MPS file\n"); +skip: glp_mpl_free_wksp(tran); + glp_delete_prob(lp); + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/mplsamp2.c b/resources/3rdparty/glpk-4.57/examples/mplsamp2.c new file mode 100644 index 000000000..0ff6ad0ff --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/mplsamp2.c @@ -0,0 +1,39 @@ +/* mplsamp2.c */ + +#include +#include +#include + +int main(void) +{ glp_prob *mip; + glp_tran *tran; + int ret; + mip = glp_create_prob(); + tran = glp_mpl_alloc_wksp(); + ret = glp_mpl_read_model(tran, "sudoku.mod", 1); + if (ret != 0) + { fprintf(stderr, "Error on translating model\n"); + goto skip; + } + ret = glp_mpl_read_data(tran, "sudoku.dat"); + if (ret != 0) + { fprintf(stderr, "Error on translating data\n"); + goto skip; + } + ret = glp_mpl_generate(tran, NULL); + if (ret != 0) + { fprintf(stderr, "Error on generating model\n"); + goto skip; + } + glp_mpl_build_prob(tran, mip); + glp_simplex(mip, NULL); + glp_intopt(mip, NULL); + ret = glp_mpl_postsolve(tran, mip, GLP_MIP); + if (ret != 0) + fprintf(stderr, "Error on postsolving model\n"); +skip: glp_mpl_free_wksp(tran); + glp_delete_prob(mip); + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/murtagh.mps b/resources/3rdparty/glpk-4.57/examples/murtagh.mps new file mode 100644 index 000000000..c03741b51 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/murtagh.mps @@ -0,0 +1,600 @@ +*NAME: OIL +*ROWS: 74 +*COLUMNS: 81 +*NONZERO: 504 +*OPT SOLN: 126.057 +*SOURCE: Bruce Murtagh, "Advanced Linear Programming" +*APPLICATION: oil refinery model +*COMMENTS: problem is maximization +* +NAME OIL REFINERY EXAMPLE +ROWS + N PROFIT + L MVOLBOL + L MVOLCOL + E MVOLLNC + E MVOLLNB + E MVOLSRK + E MVOLSRD + E MVOLVBB + E MVOLVBC + E MVOLRCR + E MVOLHVO + E UBALKWH + E UBALH2O + E UBALSTM + E UBALFUL + E MVOLB95 + E MVOLB90 + E MVOLLHG + E MVOLC3S + E MVOLNC4 + E MVOLLSR + E MVOLHSR + E MVOLIC4 + L VCAPSGP + E MVOLRFG + E MSCFHYL + E MVOLR90 + E MVOLR95 + E MVOLF90 + E MVOLF95 + L VCAPRFG + E MVOLLCO + E MVOLHHG + E MVOLHCD + L VCAPHVO + L VCAPHOL + E MVOLC3U + E MVOLC4U + E MVOLFCG + E MVOLSLR + L VCAPCCU + E MVOLLA3 + E MVOLLA4 + L VCAPALK + L XLPRPRE + L XHPRPRE + L XTELPRE + L XRVPPRE + L X200PRE + L X230PRE + E EVOLPRE + L XPSCPRE + L XRSCREG + L XLPRINT + L XHPRINT + L XTELINT + L XRVPINT + L X200INT + L X230INT + E EVOLINT + L XLPRREG + L XHPRREG + L XTELREG + L XRVPREG + L X200REG + L X230REG + E EVOLREG + E EVOLLPG + E EVOLJP4 + L XRVXJP4 + L XRVNJP4 + E EVOLDSL + E EVOLRSD + L XVISRSD +COLUMNS + VCRDBOL MVOLBOL 1.0 + VCRDBOL MVOLLNB -.537 + VCRDBOL MVOLSRK -.131 + VCRDBOL MVOLSRD -.1155 + VCRDBOL MVOLVBB -.037 + VCRDBOL MVOLRCR -.0365 + VCRDBOL MVOLHVO -.143 + VCRDBOL UBALKWH .302 + VCRDBOL UBALH2O .150 + VCRDBOL UBALSTM .003 + VCRDBOL UBALFUL .0587 + VCRDBOL PROFIT -12.8 + VCRDCOL MVOLCOL 1. + VCRDCOL MVOLLNC -.2931 + VCRDCOL MVOLSRK -.1170 + VCRDCOL MVOLSRD -.0649 + VCRDCOL MVOLVBC -.18 + VCRDCOL MVOLRCR -.1233 + VCRDCOL MVOLHVO -.2217 + VCRDCOL UBALKWH .384 + VCRDCOL UBALH2O .185 + VCRDCOL UBALSTM .003 + VCRDCOL UBALFUL .1053 + VCRDCOL PROFIT -11.48 + VSGPLNC MVOLLNC 1. + VSGPLNC MVOLC3S -.0112 + VSGPLNC MVOLNC4 -.0378 + VSGPLNC MVOLLSR -.1502 + VSGPLNC MVOLHSR -.7953 + VSGPLNC MVOLIC4 -.0099 + VSGPLNC UBALKWH .721 + VSGPLNC UBALH2O .185 + VSGPLNC UBALSTM .013 + VSGPLNC UBALFUL .0488 + VSGPLNC VCAPSGP 1. + VSGPLNB MVOLLNB 1. + VSGPLNB MVOLC3S -.0277 + VSGPLNB MVOLNC4 -.0563 + VSGPLNB MVOLLSR -.199 + VSGPLNB MVOLHSR -.6873 + VSGPLNB MVOLIC4 -.017 + VSGPLNB UBALKWH .495 + VSGPLNB UBALH2O .209 + VSGPLNB UBALSTM .013 + VSGPLNB UBALFUL .0506 + VSGPLNB VCAPSGP 1. + VSGPLHG MVOLLHG 1.0 + VSGPLHG MVOLC3S -.175 + VSGPLHG MVOLNC4 -.27 + VSGPLHG MVOLLSR -.028 + VSGPLHG MVOLIC4 -.455 + VSGPLHG UBALKWH .495 + VSGPLHG UBALH2O .209 + VSGPLHG UBALSTM .013 + VSGPLHG UBALFUL .0448 + VSGPB95 MVOLB95 1. + VSGPB95 MVOLC3S -.2836 + VSGPB95 MVOLNC4 -.3285 + VSGPB95 MVOLLSR -.0241 + VSGPB95 MVOLIC4 -.2502 + VSGPB95 UBALKWH .495 + VSGPB95 UBALH2O .209 + VSGPB95 UBALSTM .013 + VSGPB95 UBALFUL .0506 + VSGPB90 MVOLB90 1. + VSGPB90 MVOLC3S -.271 + VSGPB90 MVOLNC4 -.3289 + VSGPB90 MVOLLSR -.0255 + VSGPB90 MVOLIC4 -.2656 + VSGPB90 UBALKWH .495 + VSGPB90 UBALH2O .209 + VSGPB90 UBALSTM .013 + VSGPB90 UBALFUL .0506 + VH2RHSR MVOLHSR 1. + VH2RHSR MVOLRFG -1. + VH2RHSR MSCFHYL .0327 + VH2RHSR UBALKWH .793 + VH2RHSR UBALH2O .045 + VH2RHSR UBALFUL .094 + VH2RHSR PROFIT -.0176 + VRFFRF1 MVOLRFG 1.0 + VRFFRF1 MVOLR90 -1.0 + VRFFRF2 MVOLRFG 1.0 + VRFFRF2 MVOLR95 -1.0 + VRFFHH1 MVOLR90 -1.0 + VRFFHH1 MVOLHHG 1.0 + VRFFHH2 MVOLR95 -1.0 + VRFFHH2 MVOLHHG 1.0 + VRFGR90 MVOLR90 1.0 + VRFGR90 MVOLB90 -.0404 + VRFGR90 MVOLF90 -0.8564 + VRFGR90 MSCFHYL -0.8239 + VRFGR90 UBALKWH .792 + VRFGR90 UBALH2O .297 + VRFGR90 UBALSTM 0.0063 + VRFGR90 UBALFUL -0.156 + VRFGR90 VCAPRFG 1.0 + VRFGR90 PROFIT -0.1512 + VRFGR95 MVOLR95 1.0 + VRFGR95 MVOLB95 -0.0588 + VRFGR95 MVOLF95 -0.8145 + VRFGR95 MSCFHYL -.7689 + VRFGR95 UBALKWH 1.03 + VRFGR95 UBALH2O .387 + VRFGR95 UBALSTM 0.008 + VRFGR95 UBALFUL -.2112 + VRFGR95 VCAPRFG 1.3 + VRFGR95 PROFIT -0.304 + VHOLLCO MVOLLCO 1.0 + VHOLLCO MVOLHHG -.6627 + VHOLLCO MVOLLHG -0.2414 + VHOLLCO MVOLHCD -.2930 + VHOLLCO MSCFHYL 2.3 + VHOLLCO UBALFUL -.2054 + VHOLLCO UBALH2O 0.826 + VHOLLCO UBALKWH 14.61 + VHOLLCO VCAPHOL 1.0 + VHOLLCO PROFIT -0.2112 + VHOLSRD MVOLSRD 1.0 + VHOLSRD MVOLHHG -.6627 + VHOLSRD MVOLLHG -0.2414 + VHOLSRD MVOLHCD -.2930 + VHOLSRD MSCFHYL 2.3 + VHOLSRD UBALFUL -.2054 + VHOLSRD UBALH2O 0.826 + VHOLSRD UBALKWH 14.61 + VHOLSRD VCAPHOL 1.0 + VHOLSRD PROFIT -0.2112 + VHOLRCR MVOLRCR 1.0 + VHOLRCR MVOLHHG -.5875 + VHOLRCR MVOLLHG -0.3321 + VHOLRCR MVOLHCD -.3620 + VHOLRCR MSCFHYL 2.3 + VHOLRCR UBALFUL -.2054 + VHOLRCR UBALH2O 0.826 + VHOLRCR UBALKWH 14.61 + VHOLRCR VCAPHOL 1.0 + VHOLRCR PROFIT -0.2112 + VHOLHVO MVOLHVO 1.0 + VHOLHVO MVOLHHG -.5875 + VHOLHVO MVOLLHG -0.3321 + VHOLHVO MVOLHCD -.3620 + VHOLHVO MSCFHYL 2.3 + VHOLHVO UBALFUL -.2054 + VHOLHVO UBALH2O 0.826 + VHOLHVO UBALKWH 14.61 + VHOLHVO VCAPHVO 1.0 + VHOLHVO VCAPHOL 1.0 + VHOLHVO PROFIT -0.2112 + VCCUSRK MVOLSRK 1.0 + VCCUSRK MVOLNC4 -0.0184 + VCCUSRK MVOLC3S -0.0303 + VCCUSRK MVOLIC4 -0.0564 + VCCUSRK MVOLC3U -0.0655 + VCCUSRK MVOLC4U -0.0780 + VCCUSRK MVOLFCG -0.4750 + VCCUSRK MVOLLCO -0.3050 + VCCUSRK UBALSTM -.0654 + VCCUSRK UBALFUL -.2703 + VCCUSRK UBALH2O .632 + VCCUSRK UBALKWH .6807 + VCCUSRK VCAPCCU 1. + VCCUSRK PROFIT -.2112 + VCCUSRD MVOLSRD 1. + VCCUSRD MVOLNC4 -.0184 + VCCUSRD MVOLC3S -.0303 + VCCUSRD MVOLIC4 -.0564 + VCCUSRD MVOLC3U -.0655 + VCCUSRD MVOLC4U -.0780 + VCCUSRD MVOLFCG -.4750 + VCCUSRD MVOLLCO -.3050 + VCCUSRD UBALSTM -.0654 + VCCUSRD UBALFUL -.2703 + VCCUSRD UBALH2O 0.632 + VCCUSRD UBALKWH .6807 + VCCUSRD VCAPCCU 1. + VCCUSRD PROFIT -.2112 + VCCURCR MVOLRCR 1.0 + VCCURCR MVOLNC4 -.0185 + VCCURCR MVOLC3S -.0328 + VCCURCR MVOLIC4 -.0568 + VCCURCR MVOLC3U -.0658 + VCCURCR MVOLC4U -.0806 + VCCURCR MVOLFCG -.4934 + VCCURCR MVOLLCO -.2922 + VCCURCR MVOLSLR -.0096 + VCCURCR UBALSTM -.0654 + VCCURCR UBALFUL -.2703 + VCCURCR UBALH2O 0.632 + VCCURCR UBALKWH .6807 + VCCURCR VCAPCCU 1. + VCCURCR PROFIT -.2112 + VCCUHVO MVOLHVO 1.0 + VCCUHVO MVOLNC4 -.0185 + VCCUHVO MVOLC3S -.0328 + VCCUHVO MVOLIC4 -.0568 + VCCUHVO MVOLC3U -.0658 + VCCUHVO MVOLC4U -.0806 + VCCUHVO MVOLFCG -.4934 + VCCUHVO MVOLLCO -.2922 + VCCUHVO MVOLSLR -.0096 + VCCUHVO UBALSTM -.0654 + VCCUHVO UBALFUL -.2703 + VCCUHVO UBALH2O 0.632 + VCCUHVO UBALKWH .6807 + VCCUHVO VCAPHVO 1. + VCCUHVO VCAPCCU 1. + VCCUHVO PROFIT -.2112 + VALKLA3 MVOLIC4 .7600 + VALKLA3 MVOLC3U .5714 + VALKLA3 MVOLLA3 -1.0 + VALKLA3 UBALSTM .1869 + VALKLA3 UBALFUL .2796 + VALKLA3 UBALH2O 2.241 + VALKLA3 UBALKWH 2.766 + VALKLA3 VCAPALK 1.0 + VALKLA3 PROFIT -.512 + VALKLA4 MVOLIC4 .6571 + VALKLA4 MVOLC4U .5714 + VALKLA4 MVOLC3S -.0571 + VALKLA4 MVOLNC4 -.0114 + VALKLA4 MVOLLA4 -1.0 + VALKLA4 UBALSTM .1724 + VALKLA4 UBALFUL .2579 + VALKLA4 UBALH2O 2.067 + VALKLA4 UBALKWH 2.552 + VALKLA4 VCAPALK 1.0 + VALKLA4 PROFIT -.472 + VALKIC4 MVOLIC4 1.0 + VALKIC4 MVOLNC4 -1.0 + VALKC3U MVOLC3U 1.0 + VALKC3U MVOLC3S -1.0 + VALKC4U MVOLC4U 1.0 + VALKC4U MVOLNC4 -1.0 + UTILC3S MVOLC3S 1. + UTILC3S UBALFUL -3.814 + UTILNC4 MVOLNC4 1. + UTILNC4 UBALFUL -4.316 + UTILIC4 MVOLIC4 1. + UTILIC4 UBALFUL -4.153 + UTILC3U MVOLC3U 1. + UTILC3U UBALFUL -3.808 + UTILC4U MVOLC4U 1. + UTILC4U UBALFUL -4.44 + UTILHYL MSCFHYL 1. + UTILHYL UBALFUL -.305 + UTILSTM UBALSTM -1. + UTILSTM UBALFUL 1.42 + UTILSTM PROFIT -.16 + PURCPC4 MVOLIC4 -.5 + PURCPC4 MVOLNC4 -.5 + PURCPC4 PROFIT -12. + PURCH2O UBALH2O -1. + PURCH2O PROFIT -.0528 + PURCKWH UBALKWH -1. + PURCKWH PROFIT -.04 + PURCFUL UBALFUL -1. + PURCFUL PROFIT -1.6 + PURCFLR UBALFUL 1. + BLPGC3S MVOLC3S 1.0 + BLPGC3S EVOLLPG -1.0 + BLPGNC4 MVOLNC4 1.0 + BLPGNC4 EVOLLPG -1.0 + SELLLPG EVOLLPG 1.0 + SELLLPG PROFIT 11.0 + BUP4LSR MVOLLSR 1.0 + BUP4LSR EVOLJP4 -1.0 + BUP4LSR XRVXJP4 14.0 + BUP4LSR XRVNJP4 -14.0 + BUP4HSR MVOLHSR 1.0 + BUP4HSR EVOLJP4 -1.0 + BUP4HSR XRVXJP4 0.8 + BUP4HSR XRVNJP4 -0.8 + SELLJP4 EVOLJP4 1.0 + SELLJP4 XRVXJP4 -3.0 + SELLJP4 XRVNJP4 2.0 + SELLJP4 PROFIT 16.8 + BDSLSRK MVOLSRK 1.0 + BDSLSRK EVOLDSL -1.0 + BDSLSRD MVOLSRD 1.0 + BDSLSRD EVOLDSL -1.0 + SELLDSL EVOLDSL 1.0 + SELLDSL PROFIT 14.4 + BPRELSR MVOLLSR 1. + BPRELSR XLPRPRE -7.95 + BPRELSR XHPRPRE -8.70 + BPRELSR XTELPRE -3.00 + BPRELSR XRVPPRE 14.00 + BPRELSR X200PRE 1. + BPRELSR X230PRE -1. + BPRELSR EVOLPRE -1. + BPREHCD MVOLHCD 1.0 + BPREHCD XLPRPRE -8.84 + BPREHCD XHPRPRE -9.45 + BPREHCD XTELPRE -3.00 + BPREHCD XRVPPRE 12.00 + BPREHCD X200PRE 1. + BPREHCD X230PRE -1. + BPREHCD EVOLPRE -1. + BPREF95 MVOLF95 1.0 + BPREF95 XLPRPRE -9.43 + BPREF95 XHPRPRE -9.57 + BPREF95 XTELPRE -3. + BPREF95 XRVPPRE 3.5 + BPREF95 X200PRE .233 + BPREF95 X230PRE -.358 + BPREF95 EVOLPRE -1. + BPREF90 MVOLF90 1.0 + BPREF90 XLPRPRE -9.03 + BPREF90 XHPRPRE -9.32 + BPREF90 XTELPRE -3.0 + BPREF90 XRVPPRE 3.5 + BPREF90 X200PRE .205 + BPREF90 X230PRE -.333 + BPREF90 EVOLPRE -1. + BPREFCG MVOLFCG 1.0 + BPREFCG XLPRPRE -9.23 + BPREFCG XHPRPRE -9.22 + BPREFCG XTELPRE -3. + BPREFCG XRVPPRE 6. + BPREFCG X200PRE .381 + BPREFCG X230PRE -.509 + BPREFCG EVOLPRE -1. + BPRELA3 MVOLLA3 1.0 + BPRELA3 XLPRPRE -9.4 + BPRELA3 XHPRPRE -9.85 + BPRELA3 XTELPRE -3.0 + BPRELA3 XRVPPRE 2.5 + BPRELA3 X200PRE 0.39 + BPRELA3 X230PRE -0.77 + BPRELA3 EVOLPRE -1.0 + BPRELA4 MVOLLA4 1.0 + BPRELA4 XLPRPRE -9.74 + BPRELA4 XHPRPRE -10.1 + BPRELA4 XTELPRE -3.0 + BPRELA4 XRVPPRE 3.3 + BPRELA4 X200PRE 0.233 + BPRELA4 X230PRE -0.58 + BPRELA4 EVOLPRE -1.0 + BPRENC4 MVOLNC4 1.0 + BPRENC4 XLPRPRE -9.74 + BPRENC4 XHPRPRE -9.9 + BPRENC4 XTELPRE -3.0 + BPRENC4 XRVPPRE 66.0 + BPRENC4 X200PRE 1.0 + BPRENC4 X230PRE -1.0 + BPRENC4 EVOLPRE -1.0 + BPRETEL XLPRPRE -0.493 + BPRETEL XHPRPRE -0.165 + BPRETEL XTELPRE 1.0 + BPRETEL PROFIT -0.3696 + SELLPRE XLPRPRE 10.03 + SELLPRE XHPRPRE 10.03 + SELLPRE XRVPPRE -9.5 + SELLPRE X200PRE -0.5 + SELLPRE X230PRE 0.5 + SELLPRE XPSCPRE 0.64 + SELLPRE XRSCREG 0.35 + SELLPRE EVOLPRE 1.0 + SELLPRE PROFIT 21.44 + BINTLSR MVOLLSR 1.0 + BINTLSR XLPRINT -7.98 + BINTLSR XHPRINT -8.58 + BINTLSR XTELINT -3.0 + BINTLSR XRVPINT 14.0 + BINTLSR X200INT 1.0 + BINTLSR X230INT -1.0 + BINTLSR EVOLINT -1.0 + BINTHCD MVOLHCD 1. + BINTHCD XLPRINT -8.87 + BINTHCD XHPRINT -9.33 + BINTHCD XTELINT -3.0 + BINTHCD XRVPINT 12.0 + BINTHCD X200INT 1.0 + BINTHCD X230INT -1. + BINTHCD EVOLINT -1.0 + BINTF95 MVOLF95 1. + BINTF95 XLPRINT -9.46 + BINTF95 XHPRINT -9.45 + BINTF95 XTELINT -3.0 + BINTF95 XRVPINT 3.5 + BINTF95 X200INT .233 + BINTF95 X230INT -.358 + BINTF95 EVOLINT -1.0 + BINTF90 MVOLF90 1. + BINTF90 XLPRINT -9.06 + BINTF90 XHPRINT -9.20 + BINTF90 XTELINT -3.0 + BINTF90 XRVPINT 3.5 + BINTF90 X200INT .205 + BINTF90 X230INT -.333 + BINTF90 EVOLINT -1.0 + BINTFCG MVOLFCG 1. + BINTFCG XLPRINT -9.26 + BINTFCG XHPRINT -9.13 + BINTFCG XTELINT -3.0 + BINTFCG XRVPINT 6. + BINTFCG X200INT .318 + BINTFCG X230INT -.509 + BINTFCG EVOLINT -1.0 + BINTNC4 MVOLNC4 1. + BINTNC4 XLPRINT -9.77 + BINTNC4 XHPRINT -9.78 + BINTNC4 XTELINT -3.0 + BINTNC4 XRVPINT 66. + BINTNC4 X200INT 1.0 + BINTNC4 X230INT -1. + BINTNC4 EVOLINT -1.0 + BINTTEL XLPRINT -.435 + BINTTEL XHPRINT -.208 + BINTTEL XTELINT 1. + BINTTEL PROFIT -.3696 + SELLINT XLPRINT 9.65 + SELLINT XHPRINT 9.65 + SELLINT XRVPINT -9.5 + SELLINT X200INT -0.5 + SELLINT X230INT 0.5 + SELLINT XPSCPRE -.36 + SELLINT XRSCREG 0.35 + SELLINT EVOLINT 1.0 + SELLINT PROFIT 20.32 + BREGLSR MVOLLSR 1.0 + BREGLSR XLPRREG -7.99 + BREGLSR XHPRREG -8.59 + BREGLSR XTELREG -3.0 + BREGLSR XRVPREG 14.0 + BREGLSR X200REG 1.0 + BREGLSR X230REG -1.0 + BREGLSR EVOLREG -1.0 + BREGHCD MVOLHCD 1.0 + BREGHCD XLPRREG -8.88 + BREGHCD XHPRREG -9.34 + BREGHCD XTELREG -3.0 + BREGHCD XRVPREG 12.0 + BREGHCD X200REG 1.0 + BREGHCD X230REG -1.0 + BREGHCD EVOLREG -1.0 + BREGF95 MVOLF95 1.0 + BREGF95 XLPRREG -9.47 + BREGF95 XHPRREG -9.46 + BREGF95 XTELREG -3.0 + BREGF95 XRVPREG 3.5 + BREGF95 X200REG .233 + BREGF95 X230REG -0.358 + BREGF95 EVOLREG -1.0 + BREGF90 MVOLF90 1.0 + BREGF90 XLPRREG -9.07 + BREGF90 XHPRREG -9.21 + BREGF90 XTELREG -3.0 + BREGF90 XRVPREG 3.5 + BREGF90 X200REG .205 + BREGF90 X230REG -0.333 + BREGF90 EVOLREG -1.0 + BREGFCG MVOLFCG 1.0 + BREGFCG XLPRREG -9.27 + BREGFCG XHPRREG -9.14 + BREGFCG XTELREG -3.0 + BREGFCG XRVPREG 6.0 + BREGFCG X200REG 0.318 + BREGFCG X230REG -0.509 + BREGFCG EVOLREG -1.0 + BREGNC4 MVOLNC4 1.0 + BREGNC4 XLPRREG -9.78 + BREGNC4 XHPRREG -9.79 + BREGNC4 XTELREG -3.0 + BREGNC4 XRVPREG 66.0 + BREGNC4 X200REG 1.0 + BREGNC4 X230REG -1.0 + BREGNC4 EVOLREG -1.0 + BREGTEL XLPRREG -0.426 + BREGTEL XHPRREG -.204 + BREGTEL XTELREG 1.0 + BREGTEL PROFIT -0.3696 + SELLREG XLPRREG 9.05 + SELLREG XHPRREG 9.05 + SELLREG XRVPREG -9.5 + SELLREG X200REG -0.5 + SELLREG X230REG 0.5 + SELLREG XPSCPRE -0.36 + SELLREG XRSCREG -0.65 + SELLREG EVOLREG 1.0 + SELLREG PROFIT 18.04 + BRSDVBB MVOLVBB 1.0 + BRSDVBB EVOLRSD -1.0 + BRSDVBB XVISRSD 10.1 + BRSDVBC MVOLVBC 1.0 + BRSDVBC EVOLRSD -1.0 + BRSDVBC XVISRSD 12.63 + BRSDRCR MVOLRCR 1.0 + BRSDRCR EVOLRSD -1.0 + BRSDRCR XVISRSD 6.9 + BRSDHVO MVOLHVO 1.0 + BRSDHVO EVOLRSD -1.0 + BRSDHVO XVISRSD 8.05 + BRSDHVO VCAPHVO 1.0 + BRSDSLR MVOLSLR 1.0 + BRSDSLR EVOLRSD -1.0 + BRSDSLR XVISRSD 8.05 + BRSDLCO MVOLLCO 1.0 + BRSDLCO EVOLRSD -1.0 + BRSDLCO XVISRSD 4.4 + SELLRSD EVOLRSD 1.0 + SELLRSD XVISRSD -10.1 + SELLRSD PROFIT 8.00 +RHS + LIMITMAX MVOLBOL 26.316 + LIMITMAX MVOLCOL 21.052 + LIMITMAX VCAPSGP 23.25 + LIMITMAX VCAPHVO 5.25 + LIMITMAX VCAPRFG 13.455 + LIMITMAX VCAPHOL 3.87 + LIMITMAX VCAPCCU 7.26 + LIMITMAX VCAPALK 10. +ENDATA diff --git a/resources/3rdparty/glpk-4.57/examples/mvcp.mod b/resources/3rdparty/glpk-4.57/examples/mvcp.mod new file mode 100644 index 000000000..e016bda28 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/mvcp.mod @@ -0,0 +1,43 @@ +/* MVCP, Minimum Vertex Cover Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* The Minimum Vertex Cover Problem in a network G = (V, E), where V + is a set of nodes, E is a set of arcs, is to find a subset V' within + V such that each edge (i,j) in E has at least one its endpoint in V' + and which minimizes the sum of node weights w(i) over V'. + + Reference: + Garey, M.R., and Johnson, D.S. (1979), Computers and Intractability: + A guide to the theory of NP-completeness [Graph Theory, Covering and + Partitioning, Minimum Vertex Cover, GT1]. */ + +set E, dimen 2; +/* set of edges */ + +set V := (setof{(i,j) in E} i) union (setof{(i,j) in E} j); +/* set of nodes */ + +param w{i in V}, >= 0, default 1; +/* w[i] is weight of vertex i */ + +var x{i in V}, binary; +/* x[i] = 1 means that node i is included into V' */ + +s.t. cov{(i,j) in E}: x[i] + x[j] >= 1; +/* each edge (i,j) must have node i or j (or both) in V' */ + +minimize z: sum{i in V} w[i] * x[i]; +/* we need to minimize the sum of node weights over V' */ + +data; + +/* These data correspond to an example from [Papadimitriou]. */ + +/* Optimal solution is 6 (greedy heuristic gives 13) */ + +set E := a1 b1, b1 c1, a1 b2, b2 c2, a2 b3, b3 c3, a2 b4, b4 c4, a3 b5, + b5 c5, a3 b6, b6 c6, a4 b1, a4 b2, a4 b3, a5 b4, a5 b5, a5 b6, + a6 b1, a6 b2, a6 b3, a6 b4, a7 b2, a7 b3, a7 b4, a7 b5, a7 b6; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/netgen.c b/resources/3rdparty/glpk-4.57/examples/netgen.c new file mode 100644 index 000000000..eebb2c867 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/netgen.c @@ -0,0 +1,141 @@ +/* netgen.c */ + +/* This main program generates 50 original NETGEN instances of the + minimum cost flow problem and writes them in DIMACS format to the + current directory. */ + +#include +#include +#include +#include + +static int parm[50][15] = +{ {13502460, 101, + 5000, 2500, 2500, 25000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, + },{4281922, 102, + 5000, 2500, 2500, 25000, 1, 100, 2500000, 0, 0, 0, 100, 1, 1000, + },{44820113, 103, + 5000, 2500, 2500, 25000, 1, 100, 6250000, 0, 0, 0, 100, 1, 1000, + },{13450451, 104, + 5000, 2500, 2500, 25000, -100, -1, 250000, 0, 0, 0, 100, 1, 1000, + },{14719436, 105, + 5000, 2500, 2500, 25000, 101, 200, 250000, 0, 0, 0, 100, 1, 1000, + },{17365786, 106, + 5000, 2500, 2500, 12500, 1, 100, 125000, 0, 0, 0, 100, 1, 1000, + },{19540113, 107, + 5000, 2500, 2500, 37500, 1, 100, 375000, 0, 0, 0, 100, 1, 1000, + },{19560313, 108, + 5000, 2500, 2500, 50000, 1, 100, 500000, 0, 0, 0, 100, 1, 1000, + },{2403509, 109, + 5000, 2500, 2500, 75000, 1, 100, 750000, 0, 0, 0, 100, 1, 1000, + },{92480414, 110, + 5000, 2500, 2500, 12500, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, + },{4230140, 111, + 5000, 2500, 2500, 37500, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, + },{10032490, 112, + 5000, 2500, 2500, 50000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, + },{17307474, 113, + 5000, 2500, 2500, 75000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, + },{4925114, 114, + 5000, 500, 4500, 25000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, + },{19842704, 115, + 5000, 1500, 3500, 25000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, + },{88392060, 116, + 5000, 2500, 2500, 25000, 1, 100, 250000, 0, 0, 0, 0, 1, 1000, + },{12904407, 117, + 5000, 2500, 2500, 12500, 1, 100, 125000, 0, 0, 0, 0, 1, 1000, + },{11811811, 118, + 5000, 2500, 2500, 37500, 1, 100, 375000, 0, 0, 0, 0, 1, 1000, + },{90023593, 119, + 5000, 2500, 2500, 50000, 1, 100, 500000, 0, 0, 0, 0, 1, 1000, + },{93028922, 120, + 5000, 2500, 2500, 75000, 1, 100, 750000, 0, 0, 0, 0, 1, 1000, + },{72707401, 121, + 5000, 50, 50, 25000, 1, 100, 250000, 50, 50, 0, 100, 1, 1000, + },{93040771, 122, + 5000, 250, 250, 25000, 1, 100, 250000, 250, 250, 0, 100, 1, 1000, + },{70220611, 123, + 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{52774811, 124, + 5000, 1000, 1000, 25000, 1, 100, 250000, 1000, 1000, 0, 100, 1, + 1000, + },{22492311, 125, + 5000, 1500, 1500, 25000, 1, 100, 250000, 1500, 1500, 0, 100, 1, + 1000, + },{35269337, 126, + 5000, 500, 500, 12500, 1, 100, 125000, 500, 500, 0, 100, 1, 1000, + },{30140502, 127, + 5000, 500, 500, 37500, 1, 100, 375000, 500, 500, 0, 100, 1, 1000, + },{49205455, 128, + 5000, 500, 500, 50000, 1, 100, 500000, 500, 500, 0, 100, 1, 1000, + },{42958341, 129, + 5000, 500, 500, 75000, 1, 100, 750000, 500, 500, 0, 100, 1, 1000, + },{25440925, 130, + 5000, 500, 500, 12500, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{75294924, 131, + 5000, 500, 500, 37500, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{4463965, 132, + 5000, 500, 500, 50000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{13390427, 133, + 5000, 500, 500, 75000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{95250971, 134, + 1000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{54830522, 135, + 2500, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{520593, 136, + 7500, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{52900925, 137, + 10000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, + },{22603395, 138, + 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 50, + },{55253099, 139, + 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 250, + },{75357001, 140, + 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 500, + },{10072459, 141, + 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 2500, + },{55728492, 142, + 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 5000, + },{593043, 143, + 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 0, 1, 1000, + },{94236572, 144, + 5000, 500, 500, 25000, 1, 10, 250000, 500, 500, 0, 100, 1, 1000, + },{94882955, 145, + 5000, 500, 500, 25000, 1, 1000, 250000, 500, 500, 0, 100, 1, 1000, + },{48489922, 146, + 5000, 500, 500, 25000, 1, 10000, 250000, 500, 500, 0, 100, 1, + 1000, + },{75578374, 147, + 5000, 500, 500, 25000, -100, -1, 250000, 500, 500, 0, 100, 1, + 1000, + },{44821152, 148, + 5000, 500, 500, 25000, -50, 49, 250000, 500, 500, 0, 100, 1, 1000, + },{45224103, 149, + 5000, 500, 500, 25000, 101, 200, 250000, 500, 500, 0, 100, 1, + 1000, + },{63491741, 150, + 5000, 500, 500, 25000, 1001, 1100, 250000, 500, 500, 0, 100, 1, + 1000, + } +}; + +typedef struct { double rhs; } v_data; +typedef struct { double cap, cost; } a_data; + +int main(void) +{ glp_graph *G; + int k; + char fname[100+1]; + G = glp_create_graph(sizeof(v_data), sizeof(a_data)); + for (k = 1; k <= 50; k++) + { sprintf(fname, "netgn%03d.min", parm[k-1][1]); + glp_netgen(G, offsetof(v_data, rhs), offsetof(a_data, cap), + offsetof(a_data, cost), &parm[k-1][-1]); + glp_write_mincost(G, offsetof(v_data, rhs), -1, + offsetof(a_data, cap), offsetof(a_data, cost), fname); + } + glp_delete_graph(G); + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/numbrix.mod b/resources/3rdparty/glpk-4.57/examples/numbrix.mod new file mode 100644 index 000000000..b36fbfd04 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/numbrix.mod @@ -0,0 +1,84 @@ +/* Numbrix, Number Placement Puzzle */ + +/* Written in GNU MathProg by Robert Wood */ + +/* Numbrix is a logic-based number-placement puzzle.[1] + * The objective is to fill the grid so that each cell contains + * digits in sequential order taking a horizontal or vertical + * path; diagonal paths are not allowed. The puzzle setter + * provides a grid often with the outer most cells completed. + * + * Completed Numbrix puzzles are usually a square of numbers + * in order from 1 to 64 (8x8 grid) or from 1 to 81 (9x9 grid), + * following a continuous path in sequence. + * + * The modern puzzle was invented by Marilyn vos Savant in 2008 + * and published by Parade Magazine under the name "Numbrix", + * near her weekly Ask Marilyn article. + * + * http://en.wikipedia.org/wiki/Numbrix */ + +set I := {1..9}; +set J := {1..9}; +set VALS := {1..81}; + +param givens{I, J}, integer, >= 0, <= 81, default 0; +/* the "givens" */ + +param neighbors{i in I,j in J, i2 in I, j2 in J} , binary := +(if abs(i - i2) + abs(j -j2) == 1 then + 1 + else + 0 +); +/* defines which spots are the boards are neighbors */ + +var x{i in I, j in J, k in VALS}, binary; +/* x[i,j,k] = 1 means cell [i,j] is assigned number k */ + +s.t. fa{i in I, j in J, k in VALS: givens[i,j] != 0}: + x[i,j,k] = (if givens[i,j] = k then 1 else 0); +/* assign pre-defined numbers using the "givens" */ + +s.t. fb{i in I, j in J}: sum{k in VALS} x[i,j,k] = 1; +/* each cell must be assigned exactly one number */ + +s.t. singleNum {k in VALS}: sum{i in I, j in J} x[i,j,k] = 1; +/* a value can only occur once */ + +s.t. neighborContraint {i in I, j in J, k in 1..80}: + x[i,j,k] <= sum{i2 in I, j2 in J} x[i2,j2,k+1] * neighbors[i,j,i2,j2]; +/* each cell must have a neighbor with the next higher value */ + + +/* there is no need for an objective function here */ + + +solve; + +for {i in I} +{ for {0..0: i = 1 or i = 4 or i = 7} + printf " +----------+----------+----------+\n"; + for {j in J} + { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); + printf " %2d", sum{k in VALS} x[i,j,k] * k; + for {0..0: j = 9} printf(" |\n"); + } + for {0..0: i = 9} + printf " +----------+----------+----------+\n"; +} + +data; + +param givens : 1 2 3 4 5 6 7 8 9 := + 1 . . . . . . . . . + 2 . 11 12 15 18 21 62 61 . + 3 . 6 . . . . . 60 . + 4 . 33 . . . . . 57 . + 5 . 32 . . . . . 56 . + 6 . 37 . . . . . 73 . + 7 . 38 . . . . . 72 . + 8 . 43 44 47 48 51 76 77 . + 9 . . . . . . . . . ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/oldapi/README b/resources/3rdparty/glpk-4.57/examples/oldapi/README new file mode 100644 index 000000000..e52ee2c09 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/oldapi/README @@ -0,0 +1,11 @@ +The program module in this subdirectory contains an implementation of +the old GLPK API as it was defined in GLPK 4.48. + +To compile an existing project using the old GLPK API you need to add +to the project two files lpx.h and lpx.c. + +Please note that you may mix calls to old and new GLPK API routines in +the same project (except calls to glp_create_prob and glp_delete_prob). + +The file lpxsamp.c is an example that illustrates using the old GLPK +API routines. diff --git a/resources/3rdparty/glpk-4.57/examples/oldapi/lpx.c b/resources/3rdparty/glpk-4.57/examples/oldapi/lpx.c new file mode 100644 index 000000000..c508306b0 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/oldapi/lpx.c @@ -0,0 +1,1505 @@ +/* lpx.c (old GLPK API) */ + +/* Written by Andrew Makhorin , August 2013. */ + +/* This file contains routines that implement the old GLPK API as it +* was defined in GLPK 4.48. +* +* To compile an existing project using these routines you need to add +* to the project this file and the header lpx.h. +* +* Please note that you may mix calls to old and new GLPK API routines +* (except calls to glp_create_prob and glp_delete_prob). */ + +#include +#include +#include "lpx.h" + +#define xassert glp_assert +#define xerror glp_error + +struct CPS +{ /* control parameters */ + LPX *lp; + /* pointer to corresponding problem object */ + int msg_lev; + /* level of messages output by the solver: + 0 - no output + 1 - error messages only + 2 - normal output + 3 - full output (includes informational messages) */ + int scale; + /* scaling option: + 0 - no scaling + 1 - equilibration scaling + 2 - geometric mean scaling + 3 - geometric mean scaling, then equilibration scaling */ + int dual; + /* dual simplex option: + 0 - use primal simplex + 1 - use dual simplex */ + int price; + /* pricing option (for both primal and dual simplex): + 0 - textbook pricing + 1 - steepest edge pricing */ + double relax; + /* relaxation parameter used in the ratio test; if it is zero, + the textbook ratio test is used; if it is non-zero (should be + positive), Harris' two-pass ratio test is used; in the latter + case on the first pass basic variables (in the case of primal + simplex) or reduced costs of non-basic variables (in the case + of dual simplex) are allowed to slightly violate their bounds, + but not more than (relax * tol_bnd) or (relax * tol_dj) (thus, + relax is a percentage of tol_bnd or tol_dj) */ + double tol_bnd; + /* relative tolerance used to check if the current basic solution + is primal feasible */ + double tol_dj; + /* absolute tolerance used to check if the current basic solution + is dual feasible */ + double tol_piv; + /* relative tolerance used to choose eligible pivotal elements of + the simplex table in the ratio test */ + int round; + /* solution rounding option: + 0 - report all computed values and reduced costs "as is" + 1 - if possible (allowed by the tolerances), replace computed + values and reduced costs which are close to zero by exact + zeros */ + double obj_ll; + /* lower limit of the objective function; if on the phase II the + objective function reaches this limit and continues decreasing, + the solver stops the search */ + double obj_ul; + /* upper limit of the objective function; if on the phase II the + objective function reaches this limit and continues increasing, + the solver stops the search */ + int it_lim; + /* simplex iterations limit; if this value is positive, it is + decreased by one each time when one simplex iteration has been + performed, and reaching zero value signals the solver to stop + the search; negative value means no iterations limit */ + double tm_lim; + /* searching time limit, in seconds; if this value is positive, + it is decreased each time when one simplex iteration has been + performed by the amount of time spent for the iteration, and + reaching zero value signals the solver to stop the search; + negative value means no time limit */ + int out_frq; + /* output frequency, in iterations; this parameter specifies how + frequently the solver sends information about the solution to + the standard output */ + double out_dly; + /* output delay, in seconds; this parameter specifies how long + the solver should delay sending information about the solution + to the standard output; zero value means no delay */ + int branch; /* MIP */ + /* branching heuristic: + 0 - branch on first variable + 1 - branch on last variable + 2 - branch using heuristic by Driebeck and Tomlin + 3 - branch on most fractional variable */ + int btrack; /* MIP */ + /* backtracking heuristic: + 0 - select most recent node (depth first search) + 1 - select earliest node (breadth first search) + 2 - select node using the best projection heuristic + 3 - select node with best local bound */ + double tol_int; /* MIP */ + /* absolute tolerance used to check if the current basic solution + is integer feasible */ + double tol_obj; /* MIP */ + /* relative tolerance used to check if the value of the objective + function is not better than in the best known integer feasible + solution */ + int mps_info; /* lpx_write_mps */ + /* if this flag is set, the routine lpx_write_mps outputs several + comment cards that contains some information about the problem; + otherwise the routine outputs no comment cards */ + int mps_obj; /* lpx_write_mps */ + /* this parameter tells the routine lpx_write_mps how to output + the objective function row: + 0 - never output objective function row + 1 - always output objective function row + 2 - output objective function row if and only if the problem + has no free rows */ + int mps_orig; /* lpx_write_mps */ + /* if this flag is set, the routine lpx_write_mps uses original + row and column symbolic names; otherwise the routine generates + plain names using ordinal numbers of rows and columns */ + int mps_wide; /* lpx_write_mps */ + /* if this flag is set, the routine lpx_write_mps uses all data + fields; otherwise the routine keeps fields 5 and 6 empty */ + int mps_free; /* lpx_write_mps */ + /* if this flag is set, the routine lpx_write_mps omits column + and vector names everytime if possible (free style); otherwise + the routine never omits these names (pedantic style) */ + int mps_skip; /* lpx_write_mps */ + /* if this flag is set, the routine lpx_write_mps skips empty + columns (i.e. which has no constraint coefficients); otherwise + the routine outputs all columns */ + int lpt_orig; /* lpx_write_lpt */ + /* if this flag is set, the routine lpx_write_lpt uses original + row and column symbolic names; otherwise the routine generates + plain names using ordinal numbers of rows and columns */ + int presol; /* lpx_simplex */ + /* LP presolver option: + 0 - do not use LP presolver + 1 - use LP presolver */ + int binarize; /* lpx_intopt */ + /* if this flag is set, the routine lpx_intopt replaces integer + columns by binary ones */ + int use_cuts; /* lpx_intopt */ + /* if this flag is set, the routine lpx_intopt tries generating + cutting planes: + LPX_C_COVER - mixed cover cuts + LPX_C_CLIQUE - clique cuts + LPX_C_GOMORY - Gomory's mixed integer cuts + LPX_C_ALL - all cuts */ + double mip_gap; /* MIP */ + /* relative MIP gap tolerance */ + struct CPS *link; + /* pointer to CPS for another problem object */ +}; + +static struct CPS *cps_ptr = NULL; +/* initial pointer to CPS linked list */ + +static struct CPS *find_cps(LPX *lp) +{ /* find CPS for specified problem object */ + struct CPS *cps; + for (cps = cps_ptr; cps != NULL; cps = cps->link) + if (cps->lp == lp) break; + /* if cps is NULL (not found), the problem object was created + with glp_create_prob rather than with lpx_create_prob */ + xassert(cps != NULL); + return cps; +} + +static void reset_cps(struct CPS *cps) +{ /* reset control parameters to default values */ + cps->msg_lev = 3; + cps->scale = 1; + cps->dual = 0; + cps->price = 1; + cps->relax = 0.07; + cps->tol_bnd = 1e-7; + cps->tol_dj = 1e-7; + cps->tol_piv = 1e-9; + cps->round = 0; + cps->obj_ll = -DBL_MAX; + cps->obj_ul = +DBL_MAX; + cps->it_lim = -1; + cps->tm_lim = -1.0; + cps->out_frq = 200; + cps->out_dly = 0.0; + cps->branch = 2; + cps->btrack = 3; + cps->tol_int = 1e-5; + cps->tol_obj = 1e-7; + cps->mps_info = 1; + cps->mps_obj = 2; + cps->mps_orig = 0; + cps->mps_wide = 1; + cps->mps_free = 0; + cps->mps_skip = 0; + cps->lpt_orig = 0; + cps->presol = 0; + cps->binarize = 0; + cps->use_cuts = 0; + cps->mip_gap = 0.0; + return; +} + +LPX *lpx_create_prob(void) +{ /* create problem object */ + LPX *lp; + struct CPS *cps; + lp = glp_create_prob(); + cps = glp_alloc(1, sizeof(struct CPS)); + cps->lp = lp; + reset_cps(cps); + cps->link = cps_ptr; + cps_ptr = cps; + return lp; +} + +void lpx_set_prob_name(LPX *lp, const char *name) +{ /* assign (change) problem name */ + glp_set_prob_name(lp, name); + return; +} + +void lpx_set_obj_name(LPX *lp, const char *name) +{ /* assign (change) objective function name */ + glp_set_obj_name(lp, name); + return; +} + +void lpx_set_obj_dir(LPX *lp, int dir) +{ /* set (change) optimization direction flag */ + glp_set_obj_dir(lp, dir - LPX_MIN + GLP_MIN); + return; +} + +int lpx_add_rows(LPX *lp, int nrs) +{ /* add new rows to problem object */ + return glp_add_rows(lp, nrs); +} + +int lpx_add_cols(LPX *lp, int ncs) +{ /* add new columns to problem object */ + return glp_add_cols(lp, ncs); +} + +void lpx_set_row_name(LPX *lp, int i, const char *name) +{ /* assign (change) row name */ + glp_set_row_name(lp, i, name); + return; +} + +void lpx_set_col_name(LPX *lp, int j, const char *name) +{ /* assign (change) column name */ + glp_set_col_name(lp, j, name); + return; +} + +void lpx_set_row_bnds(LPX *lp, int i, int type, double lb, double ub) +{ /* set (change) row bounds */ + glp_set_row_bnds(lp, i, type - LPX_FR + GLP_FR, lb, ub); + return; +} + +void lpx_set_col_bnds(LPX *lp, int j, int type, double lb, double ub) +{ /* set (change) column bounds */ + glp_set_col_bnds(lp, j, type - LPX_FR + GLP_FR, lb, ub); + return; +} + +void lpx_set_obj_coef(glp_prob *lp, int j, double coef) +{ /* set (change) obj. coefficient or constant term */ + glp_set_obj_coef(lp, j, coef); + return; +} + +void lpx_set_mat_row(LPX *lp, int i, int len, const int ind[], + const double val[]) +{ /* set (replace) row of the constraint matrix */ + glp_set_mat_row(lp, i, len, ind, val); + return; +} + +void lpx_set_mat_col(LPX *lp, int j, int len, const int ind[], + const double val[]) +{ /* set (replace) column of the constraint matrix */ + glp_set_mat_col(lp, j, len, ind, val); + return; +} + +void lpx_load_matrix(LPX *lp, int ne, const int ia[], const int ja[], + const double ar[]) +{ /* load (replace) the whole constraint matrix */ + glp_load_matrix(lp, ne, ia, ja, ar); + return; +} + +void lpx_del_rows(LPX *lp, int nrs, const int num[]) +{ /* delete specified rows from problem object */ + glp_del_rows(lp, nrs, num); + return; +} + +void lpx_del_cols(LPX *lp, int ncs, const int num[]) +{ /* delete specified columns from problem object */ + glp_del_cols(lp, ncs, num); + return; +} + +void lpx_delete_prob(LPX *lp) +{ /* delete problem object */ + struct CPS *cps = find_cps(lp); + if (cps_ptr == cps) + cps_ptr = cps->link; + else + { struct CPS *prev; + for (prev = cps_ptr; prev != NULL; prev = prev->link) + if (prev->link == cps) break; + xassert(prev != NULL); + prev->link = cps->link; + } + glp_free(cps); + glp_delete_prob(lp); + return; +} + +const char *lpx_get_prob_name(LPX *lp) +{ /* retrieve problem name */ + return glp_get_prob_name(lp); +} + +const char *lpx_get_obj_name(LPX *lp) +{ /* retrieve objective function name */ + return glp_get_obj_name(lp); +} + +int lpx_get_obj_dir(LPX *lp) +{ /* retrieve optimization direction flag */ + return glp_get_obj_dir(lp) - GLP_MIN + LPX_MIN; +} + +int lpx_get_num_rows(LPX *lp) +{ /* retrieve number of rows */ + return glp_get_num_rows(lp); +} + +int lpx_get_num_cols(LPX *lp) +{ /* retrieve number of columns */ + return glp_get_num_cols(lp); +} + +const char *lpx_get_row_name(LPX *lp, int i) +{ /* retrieve row name */ + return glp_get_row_name(lp, i); +} + +const char *lpx_get_col_name(LPX *lp, int j) +{ /* retrieve column name */ + return glp_get_col_name(lp, j); +} + +int lpx_get_row_type(LPX *lp, int i) +{ /* retrieve row type */ + return glp_get_row_type(lp, i) - GLP_FR + LPX_FR; +} + +double lpx_get_row_lb(glp_prob *lp, int i) +{ /* retrieve row lower bound */ + double lb; + lb = glp_get_row_lb(lp, i); + if (lb == -DBL_MAX) lb = 0.0; + return lb; +} + +double lpx_get_row_ub(glp_prob *lp, int i) +{ /* retrieve row upper bound */ + double ub; + ub = glp_get_row_ub(lp, i); + if (ub == +DBL_MAX) ub = 0.0; + return ub; +} + +void lpx_get_row_bnds(glp_prob *lp, int i, int *typx, double *lb, + double *ub) +{ /* retrieve row bounds */ + if (typx != NULL) *typx = lpx_get_row_type(lp, i); + if (lb != NULL) *lb = lpx_get_row_lb(lp, i); + if (ub != NULL) *ub = lpx_get_row_ub(lp, i); + return; +} + +int lpx_get_col_type(LPX *lp, int j) +{ /* retrieve column type */ + return glp_get_col_type(lp, j) - GLP_FR + LPX_FR; +} + +double lpx_get_col_lb(glp_prob *lp, int j) +{ /* retrieve column lower bound */ + double lb; + lb = glp_get_col_lb(lp, j); + if (lb == -DBL_MAX) lb = 0.0; + return lb; +} + +double lpx_get_col_ub(glp_prob *lp, int j) +{ /* retrieve column upper bound */ + double ub; + ub = glp_get_col_ub(lp, j); + if (ub == +DBL_MAX) ub = 0.0; + return ub; +} + +void lpx_get_col_bnds(glp_prob *lp, int j, int *typx, double *lb, + double *ub) +{ /* retrieve column bounds */ + if (typx != NULL) *typx = lpx_get_col_type(lp, j); + if (lb != NULL) *lb = lpx_get_col_lb(lp, j); + if (ub != NULL) *ub = lpx_get_col_ub(lp, j); + return; +} + +double lpx_get_obj_coef(LPX *lp, int j) +{ /* retrieve obj. coefficient or constant term */ + return glp_get_obj_coef(lp, j); +} + +int lpx_get_num_nz(LPX *lp) +{ /* retrieve number of constraint coefficients */ + return glp_get_num_nz(lp); +} + +int lpx_get_mat_row(LPX *lp, int i, int ind[], double val[]) +{ /* retrieve row of the constraint matrix */ + return glp_get_mat_row(lp, i, ind, val); +} + +int lpx_get_mat_col(LPX *lp, int j, int ind[], double val[]) +{ /* retrieve column of the constraint matrix */ + return glp_get_mat_col(lp, j, ind, val); +} + +void lpx_create_index(LPX *lp) +{ /* create the name index */ + glp_create_index(lp); + return; +} + +int lpx_find_row(LPX *lp, const char *name) +{ /* find row by its name */ + return glp_find_row(lp, name); +} + +int lpx_find_col(LPX *lp, const char *name) +{ /* find column by its name */ + return glp_find_col(lp, name); +} + +void lpx_delete_index(LPX *lp) +{ /* delete the name index */ + glp_delete_index(lp); + return; +} + +void lpx_scale_prob(LPX *lp) +{ /* scale problem data */ + switch (lpx_get_int_parm(lp, LPX_K_SCALE)) + { case 0: + /* no scaling */ + glp_unscale_prob(lp); + break; + case 1: + /* equilibration scaling */ + glp_scale_prob(lp, GLP_SF_EQ); + break; + case 2: + /* geometric mean scaling */ + glp_scale_prob(lp, GLP_SF_GM); + break; + case 3: + /* geometric mean scaling, then equilibration scaling */ + glp_scale_prob(lp, GLP_SF_GM | GLP_SF_EQ); + break; + default: + xassert(lp != lp); + } + return; +} + +void lpx_unscale_prob(LPX *lp) +{ /* unscale problem data */ + glp_unscale_prob(lp); + return; +} + +void lpx_set_row_stat(LPX *lp, int i, int stat) +{ /* set (change) row status */ + glp_set_row_stat(lp, i, stat - LPX_BS + GLP_BS); + return; +} + +void lpx_set_col_stat(LPX *lp, int j, int stat) +{ /* set (change) column status */ + glp_set_col_stat(lp, j, stat - LPX_BS + GLP_BS); + return; +} + +void lpx_std_basis(LPX *lp) +{ /* construct standard initial LP basis */ + glp_std_basis(lp); + return; +} + +void lpx_adv_basis(LPX *lp) +{ /* construct advanced initial LP basis */ + glp_adv_basis(lp, 0); + return; +} + +void lpx_cpx_basis(LPX *lp) +{ /* construct Bixby's initial LP basis */ + glp_cpx_basis(lp); + return; +} + +static void fill_smcp(LPX *lp, glp_smcp *parm) +{ glp_init_smcp(parm); + switch (lpx_get_int_parm(lp, LPX_K_MSGLEV)) + { case 0: parm->msg_lev = GLP_MSG_OFF; break; + case 1: parm->msg_lev = GLP_MSG_ERR; break; + case 2: parm->msg_lev = GLP_MSG_ON; break; + case 3: parm->msg_lev = GLP_MSG_ALL; break; + default: xassert(lp != lp); + } + switch (lpx_get_int_parm(lp, LPX_K_DUAL)) + { case 0: parm->meth = GLP_PRIMAL; break; + case 1: parm->meth = GLP_DUAL; break; + default: xassert(lp != lp); + } + switch (lpx_get_int_parm(lp, LPX_K_PRICE)) + { case 0: parm->pricing = GLP_PT_STD; break; + case 1: parm->pricing = GLP_PT_PSE; break; + default: xassert(lp != lp); + } + if (lpx_get_real_parm(lp, LPX_K_RELAX) == 0.0) + parm->r_test = GLP_RT_STD; + else + parm->r_test = GLP_RT_HAR; + parm->tol_bnd = lpx_get_real_parm(lp, LPX_K_TOLBND); + parm->tol_dj = lpx_get_real_parm(lp, LPX_K_TOLDJ); + parm->tol_piv = lpx_get_real_parm(lp, LPX_K_TOLPIV); + parm->obj_ll = lpx_get_real_parm(lp, LPX_K_OBJLL); + parm->obj_ul = lpx_get_real_parm(lp, LPX_K_OBJUL); + if (lpx_get_int_parm(lp, LPX_K_ITLIM) < 0) + parm->it_lim = INT_MAX; + else + parm->it_lim = lpx_get_int_parm(lp, LPX_K_ITLIM); + if (lpx_get_real_parm(lp, LPX_K_TMLIM) < 0.0) + parm->tm_lim = INT_MAX; + else + parm->tm_lim = + (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_TMLIM)); + parm->out_frq = lpx_get_int_parm(lp, LPX_K_OUTFRQ); + parm->out_dly = + (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_OUTDLY)); + switch (lpx_get_int_parm(lp, LPX_K_PRESOL)) + { case 0: parm->presolve = GLP_OFF; break; + case 1: parm->presolve = GLP_ON; break; + default: xassert(lp != lp); + } + return; +} + +int lpx_simplex(LPX *lp) +{ /* easy-to-use driver to the simplex method */ + glp_smcp parm; + int ret; + fill_smcp(lp, &parm); + ret = glp_simplex(lp, &parm); + switch (ret) + { case 0: ret = LPX_E_OK; break; + case GLP_EBADB: + case GLP_ESING: + case GLP_ECOND: + case GLP_EBOUND: ret = LPX_E_FAULT; break; + case GLP_EFAIL: ret = LPX_E_SING; break; + case GLP_EOBJLL: ret = LPX_E_OBJLL; break; + case GLP_EOBJUL: ret = LPX_E_OBJUL; break; + case GLP_EITLIM: ret = LPX_E_ITLIM; break; + case GLP_ETMLIM: ret = LPX_E_TMLIM; break; + case GLP_ENOPFS: ret = LPX_E_NOPFS; break; + case GLP_ENODFS: ret = LPX_E_NODFS; break; + default: xassert(ret != ret); + } + return ret; +} + +int lpx_exact(LPX *lp) +{ /* easy-to-use driver to the exact simplex method */ + glp_smcp parm; + int ret; + fill_smcp(lp, &parm); + ret = glp_exact(lp, &parm); + switch (ret) + { case 0: ret = LPX_E_OK; break; + case GLP_EBADB: + case GLP_ESING: + case GLP_EBOUND: + case GLP_EFAIL: ret = LPX_E_FAULT; break; + case GLP_EITLIM: ret = LPX_E_ITLIM; break; + case GLP_ETMLIM: ret = LPX_E_TMLIM; break; + default: xassert(ret != ret); + } + return ret; +} + +int lpx_get_status(glp_prob *lp) +{ /* retrieve generic status of basic solution */ + int status; + switch (glp_get_status(lp)) + { case GLP_OPT: status = LPX_OPT; break; + case GLP_FEAS: status = LPX_FEAS; break; + case GLP_INFEAS: status = LPX_INFEAS; break; + case GLP_NOFEAS: status = LPX_NOFEAS; break; + case GLP_UNBND: status = LPX_UNBND; break; + case GLP_UNDEF: status = LPX_UNDEF; break; + default: xassert(lp != lp); + } + return status; +} + +int lpx_get_prim_stat(glp_prob *lp) +{ /* retrieve status of primal basic solution */ + return glp_get_prim_stat(lp) - GLP_UNDEF + LPX_P_UNDEF; +} + +int lpx_get_dual_stat(glp_prob *lp) +{ /* retrieve status of dual basic solution */ + return glp_get_dual_stat(lp) - GLP_UNDEF + LPX_D_UNDEF; +} + +double lpx_get_obj_val(LPX *lp) +{ /* retrieve objective value (basic solution) */ + return glp_get_obj_val(lp); +} + +int lpx_get_row_stat(LPX *lp, int i) +{ /* retrieve row status (basic solution) */ + return glp_get_row_stat(lp, i) - GLP_BS + LPX_BS; +} + +double lpx_get_row_prim(LPX *lp, int i) +{ /* retrieve row primal value (basic solution) */ + return glp_get_row_prim(lp, i); +} + +double lpx_get_row_dual(LPX *lp, int i) +{ /* retrieve row dual value (basic solution) */ + return glp_get_row_dual(lp, i); +} + +void lpx_get_row_info(glp_prob *lp, int i, int *tagx, double *vx, + double *dx) +{ /* obtain row solution information */ + if (tagx != NULL) *tagx = lpx_get_row_stat(lp, i); + if (vx != NULL) *vx = lpx_get_row_prim(lp, i); + if (dx != NULL) *dx = lpx_get_row_dual(lp, i); + return; +} + +int lpx_get_col_stat(LPX *lp, int j) +{ /* retrieve column status (basic solution) */ + return glp_get_col_stat(lp, j) - GLP_BS + LPX_BS; +} + +double lpx_get_col_prim(LPX *lp, int j) +{ /* retrieve column primal value (basic solution) */ + return glp_get_col_prim(lp, j); +} + +double lpx_get_col_dual(glp_prob *lp, int j) +{ /* retrieve column dual value (basic solution) */ + return glp_get_col_dual(lp, j); +} + +void lpx_get_col_info(glp_prob *lp, int j, int *tagx, double *vx, + double *dx) +{ /* obtain column solution information */ + if (tagx != NULL) *tagx = lpx_get_col_stat(lp, j); + if (vx != NULL) *vx = lpx_get_col_prim(lp, j); + if (dx != NULL) *dx = lpx_get_col_dual(lp, j); + return; +} + +int lpx_get_ray_info(LPX *lp) +{ /* determine what causes primal unboundness */ + return glp_get_unbnd_ray(lp); +} + +void lpx_check_kkt(LPX *lp, int scaled, LPXKKT *kkt) +{ /* check Karush-Kuhn-Tucker conditions */ + int m = glp_get_num_rows(lp); + int ae_ind, re_ind; + double ae_max, re_max; + xassert(scaled == scaled); + glp_check_kkt(lp, GLP_SOL, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, + &re_ind); + kkt->pe_ae_max = ae_max; + kkt->pe_ae_row = ae_ind; + kkt->pe_re_max = re_max; + kkt->pe_re_row = re_ind; + if (re_max <= 1e-9) + kkt->pe_quality = 'H'; + else if (re_max <= 1e-6) + kkt->pe_quality = 'M'; + else if (re_max <= 1e-3) + kkt->pe_quality = 'L'; + else + kkt->pe_quality = '?'; + glp_check_kkt(lp, GLP_SOL, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, + &re_ind); + kkt->pb_ae_max = ae_max; + kkt->pb_ae_ind = ae_ind; + kkt->pb_re_max = re_max; + kkt->pb_re_ind = re_ind; + if (re_max <= 1e-9) + kkt->pb_quality = 'H'; + else if (re_max <= 1e-6) + kkt->pb_quality = 'M'; + else if (re_max <= 1e-3) + kkt->pb_quality = 'L'; + else + kkt->pb_quality = '?'; + glp_check_kkt(lp, GLP_SOL, GLP_KKT_DE, &ae_max, &ae_ind, &re_max, + &re_ind); + kkt->de_ae_max = ae_max; + if (ae_ind == 0) + kkt->de_ae_col = 0; + else + kkt->de_ae_col = ae_ind - m; + kkt->de_re_max = re_max; + if (re_ind == 0) + kkt->de_re_col = 0; + else + kkt->de_re_col = ae_ind - m; + if (re_max <= 1e-9) + kkt->de_quality = 'H'; + else if (re_max <= 1e-6) + kkt->de_quality = 'M'; + else if (re_max <= 1e-3) + kkt->de_quality = 'L'; + else + kkt->de_quality = '?'; + glp_check_kkt(lp, GLP_SOL, GLP_KKT_DB, &ae_max, &ae_ind, &re_max, + &re_ind); + kkt->db_ae_max = ae_max; + kkt->db_ae_ind = ae_ind; + kkt->db_re_max = re_max; + kkt->db_re_ind = re_ind; + if (re_max <= 1e-9) + kkt->db_quality = 'H'; + else if (re_max <= 1e-6) + kkt->db_quality = 'M'; + else if (re_max <= 1e-3) + kkt->db_quality = 'L'; + else + kkt->db_quality = '?'; + kkt->cs_ae_max = 0.0, kkt->cs_ae_ind = 0; + kkt->cs_re_max = 0.0, kkt->cs_re_ind = 0; + kkt->cs_quality = 'H'; + return; +} + +int lpx_warm_up(LPX *lp) +{ /* "warm up" LP basis */ + int ret; + ret = glp_warm_up(lp); + if (ret == 0) + ret = LPX_E_OK; + else if (ret == GLP_EBADB) + ret = LPX_E_BADB; + else if (ret == GLP_ESING) + ret = LPX_E_SING; + else if (ret == GLP_ECOND) + ret = LPX_E_SING; + else + xassert(ret != ret); + return ret; +} + +int lpx_eval_tab_row(LPX *lp, int k, int ind[], double val[]) +{ /* compute row of the simplex tableau */ + return glp_eval_tab_row(lp, k, ind, val); +} + +int lpx_eval_tab_col(LPX *lp, int k, int ind[], double val[]) +{ /* compute column of the simplex tableau */ + return glp_eval_tab_col(lp, k, ind, val); +} + +int lpx_transform_row(LPX *lp, int len, int ind[], double val[]) +{ /* transform explicitly specified row */ + return glp_transform_row(lp, len, ind, val); +} + +int lpx_transform_col(LPX *lp, int len, int ind[], double val[]) +{ /* transform explicitly specified column */ + return glp_transform_col(lp, len, ind, val); +} + +int lpx_prim_ratio_test(LPX *lp, int len, const int ind[], + const double val[], int how, double tol) +{ /* perform primal ratio test */ + int piv; + piv = glp_prim_rtest(lp, len, ind, val, how, tol); + xassert(0 <= piv && piv <= len); + return piv == 0 ? 0 : ind[piv]; +} + +int lpx_dual_ratio_test(LPX *lp, int len, const int ind[], + const double val[], int how, double tol) +{ /* perform dual ratio test */ + int piv; + piv = glp_dual_rtest(lp, len, ind, val, how, tol); + xassert(0 <= piv && piv <= len); + return piv == 0 ? 0 : ind[piv]; +} + +int lpx_interior(LPX *lp) +{ /* easy-to-use driver to the interior-point method */ + int ret; + ret = glp_interior(lp, NULL); + switch (ret) + { case 0: ret = LPX_E_OK; break; + case GLP_EFAIL: ret = LPX_E_FAULT; break; + case GLP_ENOFEAS: ret = LPX_E_NOFEAS; break; + case GLP_ENOCVG: ret = LPX_E_NOCONV; break; + case GLP_EITLIM: ret = LPX_E_ITLIM; break; + case GLP_EINSTAB: ret = LPX_E_INSTAB; break; + default: xassert(ret != ret); + } + return ret; +} + +int lpx_ipt_status(glp_prob *lp) +{ /* retrieve status of interior-point solution */ + int status; + switch (glp_ipt_status(lp)) + { case GLP_UNDEF: status = LPX_T_UNDEF; break; + case GLP_OPT: status = LPX_T_OPT; break; + default: xassert(lp != lp); + } + return status; +} + +double lpx_ipt_obj_val(LPX *lp) +{ /* retrieve objective value (interior point) */ + return glp_ipt_obj_val(lp); +} + +double lpx_ipt_row_prim(LPX *lp, int i) +{ /* retrieve row primal value (interior point) */ + return glp_ipt_row_prim(lp, i); +} + +double lpx_ipt_row_dual(LPX *lp, int i) +{ /* retrieve row dual value (interior point) */ + return glp_ipt_row_dual(lp, i); +} + +double lpx_ipt_col_prim(LPX *lp, int j) +{ /* retrieve column primal value (interior point) */ + return glp_ipt_col_prim(lp, j); +} + +double lpx_ipt_col_dual(LPX *lp, int j) +{ /* retrieve column dual value (interior point) */ + return glp_ipt_col_dual(lp, j); +} + +void lpx_set_class(LPX *lp, int klass) +{ /* set problem class */ + xassert(lp == lp); + if (!(klass == LPX_LP || klass == LPX_MIP)) + xerror("lpx_set_class: invalid problem class\n"); + return; +} + +int lpx_get_class(LPX *lp) +{ /* determine problem klass */ + return glp_get_num_int(lp) == 0 ? LPX_LP : LPX_MIP; +} + +void lpx_set_col_kind(LPX *lp, int j, int kind) +{ /* set (change) column kind */ + glp_set_col_kind(lp, j, kind - LPX_CV + GLP_CV); + return; +} + +int lpx_get_col_kind(LPX *lp, int j) +{ /* retrieve column kind */ + return glp_get_col_kind(lp, j) == GLP_CV ? LPX_CV : LPX_IV; +} + +int lpx_get_num_int(LPX *lp) +{ /* retrieve number of integer columns */ + return glp_get_num_int(lp); +} + +int lpx_get_num_bin(LPX *lp) +{ /* retrieve number of binary columns */ + return glp_get_num_bin(lp); +} + +static int solve_mip(LPX *lp, int presolve) +{ glp_iocp parm; + int ret; + glp_init_iocp(&parm); + switch (lpx_get_int_parm(lp, LPX_K_MSGLEV)) + { case 0: parm.msg_lev = GLP_MSG_OFF; break; + case 1: parm.msg_lev = GLP_MSG_ERR; break; + case 2: parm.msg_lev = GLP_MSG_ON; break; + case 3: parm.msg_lev = GLP_MSG_ALL; break; + default: xassert(lp != lp); + } + switch (lpx_get_int_parm(lp, LPX_K_BRANCH)) + { case 0: parm.br_tech = GLP_BR_FFV; break; + case 1: parm.br_tech = GLP_BR_LFV; break; + case 2: parm.br_tech = GLP_BR_DTH; break; + case 3: parm.br_tech = GLP_BR_MFV; break; + default: xassert(lp != lp); + } + switch (lpx_get_int_parm(lp, LPX_K_BTRACK)) + { case 0: parm.bt_tech = GLP_BT_DFS; break; + case 1: parm.bt_tech = GLP_BT_BFS; break; + case 2: parm.bt_tech = GLP_BT_BPH; break; + case 3: parm.bt_tech = GLP_BT_BLB; break; + default: xassert(lp != lp); + } + parm.tol_int = lpx_get_real_parm(lp, LPX_K_TOLINT); + parm.tol_obj = lpx_get_real_parm(lp, LPX_K_TOLOBJ); + if (lpx_get_real_parm(lp, LPX_K_TMLIM) < 0.0 || + lpx_get_real_parm(lp, LPX_K_TMLIM) > 1e6) + parm.tm_lim = INT_MAX; + else + parm.tm_lim = + (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_TMLIM)); + parm.mip_gap = lpx_get_real_parm(lp, LPX_K_MIPGAP); + if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_GOMORY) + parm.gmi_cuts = GLP_ON; + else + parm.gmi_cuts = GLP_OFF; + if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_MIR) + parm.mir_cuts = GLP_ON; + else + parm.mir_cuts = GLP_OFF; + if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_COVER) + parm.cov_cuts = GLP_ON; + else + parm.cov_cuts = GLP_OFF; + if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_CLIQUE) + parm.clq_cuts = GLP_ON; + else + parm.clq_cuts = GLP_OFF; + parm.presolve = presolve; + if (lpx_get_int_parm(lp, LPX_K_BINARIZE)) + parm.binarize = GLP_ON; + ret = glp_intopt(lp, &parm); + switch (ret) + { case 0: ret = LPX_E_OK; break; + case GLP_ENOPFS: ret = LPX_E_NOPFS; break; + case GLP_ENODFS: ret = LPX_E_NODFS; break; + case GLP_EBOUND: + case GLP_EROOT: ret = LPX_E_FAULT; break; + case GLP_EFAIL: ret = LPX_E_SING; break; + case GLP_EMIPGAP: ret = LPX_E_MIPGAP; break; + case GLP_ETMLIM: ret = LPX_E_TMLIM; break; + default: xassert(ret != ret); + } + return ret; +} + +int lpx_integer(LPX *lp) +{ /* easy-to-use driver to the branch-and-bound method */ + return solve_mip(lp, GLP_OFF); +} + +int lpx_intopt(LPX *lp) +{ /* easy-to-use driver to the branch-and-bound method */ + return solve_mip(lp, GLP_ON); +} + +int lpx_mip_status(glp_prob *lp) +{ /* retrieve status of MIP solution */ + int status; + switch (glp_mip_status(lp)) + { case GLP_UNDEF: status = LPX_I_UNDEF; break; + case GLP_OPT: status = LPX_I_OPT; break; + case GLP_FEAS: status = LPX_I_FEAS; break; + case GLP_NOFEAS: status = LPX_I_NOFEAS; break; + default: xassert(lp != lp); + } + return status; +} + +double lpx_mip_obj_val(LPX *lp) +{ /* retrieve objective value (MIP solution) */ + return glp_mip_obj_val(lp); +} + +double lpx_mip_row_val(LPX *lp, int i) +{ /* retrieve row value (MIP solution) */ + return glp_mip_row_val(lp, i); +} + +double lpx_mip_col_val(LPX *lp, int j) +{ /* retrieve column value (MIP solution) */ + return glp_mip_col_val(lp, j); +} + +void lpx_check_int(LPX *lp, LPXKKT *kkt) +{ /* check integer feasibility conditions */ + int ae_ind, re_ind; + double ae_max, re_max; + glp_check_kkt(lp, GLP_MIP, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, + &re_ind); + kkt->pe_ae_max = ae_max; + kkt->pe_ae_row = ae_ind; + kkt->pe_re_max = re_max; + kkt->pe_re_row = re_ind; + if (re_max <= 1e-9) + kkt->pe_quality = 'H'; + else if (re_max <= 1e-6) + kkt->pe_quality = 'M'; + else if (re_max <= 1e-3) + kkt->pe_quality = 'L'; + else + kkt->pe_quality = '?'; + glp_check_kkt(lp, GLP_MIP, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, + &re_ind); + kkt->pb_ae_max = ae_max; + kkt->pb_ae_ind = ae_ind; + kkt->pb_re_max = re_max; + kkt->pb_re_ind = re_ind; + if (re_max <= 1e-9) + kkt->pb_quality = 'H'; + else if (re_max <= 1e-6) + kkt->pb_quality = 'M'; + else if (re_max <= 1e-3) + kkt->pb_quality = 'L'; + else + kkt->pb_quality = '?'; + return; +} + +void lpx_reset_parms(LPX *lp) +{ /* reset control parameters to default values */ + struct CPS *cps = find_cps(lp); + reset_cps(cps); + return; +} + +void lpx_set_int_parm(LPX *lp, int parm, int val) +{ /* set (change) integer control parameter */ + struct CPS *cps = find_cps(lp); + switch (parm) + { case LPX_K_MSGLEV: + if (!(0 <= val && val <= 3)) + xerror("lpx_set_int_parm: MSGLEV = %d; invalid value\n", + val); + cps->msg_lev = val; + break; + case LPX_K_SCALE: + if (!(0 <= val && val <= 3)) + xerror("lpx_set_int_parm: SCALE = %d; invalid value\n", + val); + cps->scale = val; + break; + case LPX_K_DUAL: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: DUAL = %d; invalid value\n", + val); + cps->dual = val; + break; + case LPX_K_PRICE: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: PRICE = %d; invalid value\n", + val); + cps->price = val; + break; + case LPX_K_ROUND: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: ROUND = %d; invalid value\n", + val); + cps->round = val; + break; + case LPX_K_ITLIM: + cps->it_lim = val; + break; + case LPX_K_ITCNT: + glp_set_it_cnt(lp, val); + break; + case LPX_K_OUTFRQ: + if (!(val > 0)) + xerror("lpx_set_int_parm: OUTFRQ = %d; invalid value\n", + val); + cps->out_frq = val; + break; + case LPX_K_BRANCH: + if (!(val == 0 || val == 1 || val == 2 || val == 3)) + xerror("lpx_set_int_parm: BRANCH = %d; invalid value\n", + val); + cps->branch = val; + break; + case LPX_K_BTRACK: + if (!(val == 0 || val == 1 || val == 2 || val == 3)) + xerror("lpx_set_int_parm: BTRACK = %d; invalid value\n", + val); + cps->btrack = val; + break; + case LPX_K_MPSINFO: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: MPSINFO = %d; invalid value\n", + val); + cps->mps_info = val; + break; + case LPX_K_MPSOBJ: + if (!(val == 0 || val == 1 || val == 2)) + xerror("lpx_set_int_parm: MPSOBJ = %d; invalid value\n", + val); + cps->mps_obj = val; + break; + case LPX_K_MPSORIG: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: MPSORIG = %d; invalid value\n", + val); + cps->mps_orig = val; + break; + case LPX_K_MPSWIDE: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: MPSWIDE = %d; invalid value\n", + val); + cps->mps_wide = val; + break; + case LPX_K_MPSFREE: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: MPSFREE = %d; invalid value\n", + val); + cps->mps_free = val; + break; + case LPX_K_MPSSKIP: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: MPSSKIP = %d; invalid value\n", + val); + cps->mps_skip = val; + break; + case LPX_K_LPTORIG: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: LPTORIG = %d; invalid value\n", + val); + cps->lpt_orig = val; + break; + case LPX_K_PRESOL: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: PRESOL = %d; invalid value\n", + val); + cps->presol = val; + break; + case LPX_K_BINARIZE: + if (!(val == 0 || val == 1)) + xerror("lpx_set_int_parm: BINARIZE = %d; invalid value\n" + , val); + cps->binarize = val; + break; + case LPX_K_USECUTS: + if (val & ~LPX_C_ALL) + xerror("lpx_set_int_parm: USECUTS = 0x%X; invalid value\n", + val); + cps->use_cuts = val; + break; + case LPX_K_BFTYPE: + { glp_bfcp parm; + glp_get_bfcp(lp, &parm); + switch (val) + { case 1: + parm.type = GLP_BF_FT; break; + case 2: + parm.type = GLP_BF_BG; break; + case 3: + parm.type = GLP_BF_GR; break; + default: + xerror("lpx_set_int_parm: BFTYPE = %d; invalid val" + "ue\n", val); + } + glp_set_bfcp(lp, &parm); + } + break; + default: + xerror("lpx_set_int_parm: parm = %d; invalid parameter\n", + parm); + } + return; +} + +int lpx_get_int_parm(LPX *lp, int parm) +{ /* query integer control parameter */ + struct CPS *cps = find_cps(lp); + int val = 0; + switch (parm) + { case LPX_K_MSGLEV: + val = cps->msg_lev; break; + case LPX_K_SCALE: + val = cps->scale; break; + case LPX_K_DUAL: + val = cps->dual; break; + case LPX_K_PRICE: + val = cps->price; break; + case LPX_K_ROUND: + val = cps->round; break; + case LPX_K_ITLIM: + val = cps->it_lim; break; + case LPX_K_ITCNT: + val = glp_get_it_cnt(lp); break; + case LPX_K_OUTFRQ: + val = cps->out_frq; break; + case LPX_K_BRANCH: + val = cps->branch; break; + case LPX_K_BTRACK: + val = cps->btrack; break; + case LPX_K_MPSINFO: + val = cps->mps_info; break; + case LPX_K_MPSOBJ: + val = cps->mps_obj; break; + case LPX_K_MPSORIG: + val = cps->mps_orig; break; + case LPX_K_MPSWIDE: + val = cps->mps_wide; break; + case LPX_K_MPSFREE: + val = cps->mps_free; break; + case LPX_K_MPSSKIP: + val = cps->mps_skip; break; + case LPX_K_LPTORIG: + val = cps->lpt_orig; break; + case LPX_K_PRESOL: + val = cps->presol; break; + case LPX_K_BINARIZE: + val = cps->binarize; break; + case LPX_K_USECUTS: + val = cps->use_cuts; break; + case LPX_K_BFTYPE: + { glp_bfcp parm; + glp_get_bfcp(lp, &parm); + switch (parm.type) + { case GLP_BF_FT: + val = 1; break; + case GLP_BF_BG: + val = 2; break; + case GLP_BF_GR: + val = 3; break; + default: + xassert(lp != lp); + } + } + break; + default: + xerror("lpx_get_int_parm: parm = %d; invalid parameter\n", + parm); + } + return val; +} + +void lpx_set_real_parm(LPX *lp, int parm, double val) +{ /* set (change) real control parameter */ + struct CPS *cps = find_cps(lp); + switch (parm) + { case LPX_K_RELAX: + if (!(0.0 <= val && val <= 1.0)) + xerror("lpx_set_real_parm: RELAX = %g; invalid value\n", + val); + cps->relax = val; + break; + case LPX_K_TOLBND: + if (!(DBL_EPSILON <= val && val <= 0.001)) + xerror("lpx_set_real_parm: TOLBND = %g; invalid value\n", + val); + cps->tol_bnd = val; + break; + case LPX_K_TOLDJ: + if (!(DBL_EPSILON <= val && val <= 0.001)) + xerror("lpx_set_real_parm: TOLDJ = %g; invalid value\n", + val); + cps->tol_dj = val; + break; + case LPX_K_TOLPIV: + if (!(DBL_EPSILON <= val && val <= 0.001)) + xerror("lpx_set_real_parm: TOLPIV = %g; invalid value\n", + val); + cps->tol_piv = val; + break; + case LPX_K_OBJLL: + cps->obj_ll = val; + break; + case LPX_K_OBJUL: + cps->obj_ul = val; + break; + case LPX_K_TMLIM: + cps->tm_lim = val; + break; + case LPX_K_OUTDLY: + cps->out_dly = val; + break; + case LPX_K_TOLINT: + if (!(DBL_EPSILON <= val && val <= 0.001)) + xerror("lpx_set_real_parm: TOLINT = %g; invalid value\n", + val); + cps->tol_int = val; + break; + case LPX_K_TOLOBJ: + if (!(DBL_EPSILON <= val && val <= 0.001)) + xerror("lpx_set_real_parm: TOLOBJ = %g; invalid value\n", + val); + cps->tol_obj = val; + break; + case LPX_K_MIPGAP: + if (val < 0.0) + xerror("lpx_set_real_parm: MIPGAP = %g; invalid value\n", + val); + cps->mip_gap = val; + break; + default: + xerror("lpx_set_real_parm: parm = %d; invalid parameter\n", + parm); + } + return; +} + +double lpx_get_real_parm(LPX *lp, int parm) +{ /* query real control parameter */ + struct CPS *cps = find_cps(lp); + double val = 0.0; + switch (parm) + { case LPX_K_RELAX: + val = cps->relax; + break; + case LPX_K_TOLBND: + val = cps->tol_bnd; + break; + case LPX_K_TOLDJ: + val = cps->tol_dj; + break; + case LPX_K_TOLPIV: + val = cps->tol_piv; + break; + case LPX_K_OBJLL: + val = cps->obj_ll; + break; + case LPX_K_OBJUL: + val = cps->obj_ul; + break; + case LPX_K_TMLIM: + val = cps->tm_lim; + break; + case LPX_K_OUTDLY: + val = cps->out_dly; + break; + case LPX_K_TOLINT: + val = cps->tol_int; + break; + case LPX_K_TOLOBJ: + val = cps->tol_obj; + break; + case LPX_K_MIPGAP: + val = cps->mip_gap; + break; + default: + xerror("lpx_get_real_parm: parm = %d; invalid parameter\n", + parm); + } + return val; +} + +LPX *lpx_read_mps(const char *fname) +{ /* read problem data in fixed MPS format */ + LPX *lp = lpx_create_prob(); + if (glp_read_mps(lp, GLP_MPS_DECK, NULL, fname)) + lpx_delete_prob(lp), lp = NULL; + return lp; +} + +int lpx_write_mps(LPX *lp, const char *fname) +{ /* write problem data in fixed MPS format */ + return glp_write_mps(lp, GLP_MPS_DECK, NULL, fname); +} + +int lpx_read_bas(LPX *lp, const char *fname) +{ /* read LP basis in fixed MPS format */ + xassert(lp == lp); + xassert(fname == fname); + xerror("lpx_read_bas: operation not supported\n"); + return 0; +} + +int lpx_write_bas(LPX *lp, const char *fname) +{ /* write LP basis in fixed MPS format */ + xassert(lp == lp); + xassert(fname == fname); + xerror("lpx_write_bas: operation not supported\n"); + return 0; +} + +LPX *lpx_read_freemps(const char *fname) +{ /* read problem data in free MPS format */ + LPX *lp = lpx_create_prob(); + if (glp_read_mps(lp, GLP_MPS_FILE, NULL, fname)) + lpx_delete_prob(lp), lp = NULL; + return lp; +} + +int lpx_write_freemps(LPX *lp, const char *fname) +{ /* write problem data in free MPS format */ + return glp_write_mps(lp, GLP_MPS_FILE, NULL, fname); +} + +LPX *lpx_read_cpxlp(const char *fname) +{ /* read problem data in CPLEX LP format */ + LPX *lp; + lp = lpx_create_prob(); + if (glp_read_lp(lp, NULL, fname)) + lpx_delete_prob(lp), lp = NULL; + return lp; +} + +int lpx_write_cpxlp(LPX *lp, const char *fname) +{ /* write problem data in CPLEX LP format */ + return glp_write_lp(lp, NULL, fname); +} + +LPX *lpx_read_model(const char *model, const char *data, const char + *output) +{ /* read LP/MIP model written in GNU MathProg language */ + LPX *lp = NULL; + glp_tran *tran; + /* allocate the translator workspace */ + tran = glp_mpl_alloc_wksp(); + /* read model section and optional data section */ + if (glp_mpl_read_model(tran, model, data != NULL)) goto done; + /* read separate data section, if required */ + if (data != NULL) + if (glp_mpl_read_data(tran, data)) goto done; + /* generate the model */ + if (glp_mpl_generate(tran, output)) goto done; + /* build the problem instance from the model */ + lp = lpx_create_prob(); + glp_mpl_build_prob(tran, lp); +done: /* free the translator workspace */ + glp_mpl_free_wksp(tran); + /* bring the problem object to the calling program */ + return lp; +} + +int lpx_print_prob(LPX *lp, const char *fname) +{ /* write problem data in plain text format */ + return glp_write_lp(lp, NULL, fname); +} + +int lpx_print_sol(LPX *lp, const char *fname) +{ /* write LP problem solution in printable format */ + return glp_print_sol(lp, fname); +} + +int lpx_print_sens_bnds(LPX *lp, const char *fname) +{ /* write bounds sensitivity information */ + if (glp_get_status(lp) == GLP_OPT && !glp_bf_exists(lp)) + glp_factorize(lp); + return glp_print_ranges(lp, 0, NULL, 0, fname); +} + +int lpx_print_ips(LPX *lp, const char *fname) +{ /* write interior point solution in printable format */ + return glp_print_ipt(lp, fname); +} + +int lpx_print_mip(LPX *lp, const char *fname) +{ /* write MIP problem solution in printable format */ + return glp_print_mip(lp, fname); +} + +int lpx_is_b_avail(glp_prob *lp) +{ /* check if LP basis is available */ + return glp_bf_exists(lp); +} + +int lpx_main(int argc, const char *argv[]) +{ /* stand-alone LP/MIP solver */ + return glp_main(argc, argv); +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/oldapi/lpx.h b/resources/3rdparty/glpk-4.57/examples/oldapi/lpx.h new file mode 100644 index 000000000..54af27eec --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/oldapi/lpx.h @@ -0,0 +1,565 @@ +/* lpx.h (old GLPK API) */ + +/* Written by Andrew Makhorin , August 2013. */ + +#ifndef LPX_H +#define LPX_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define LPX glp_prob + +/* problem class: */ +#define LPX_LP 100 /* linear programming (LP) */ +#define LPX_MIP 101 /* mixed integer programming (MIP) */ + +/* type of auxiliary/structural variable: */ +#define LPX_FR 110 /* free variable */ +#define LPX_LO 111 /* variable with lower bound */ +#define LPX_UP 112 /* variable with upper bound */ +#define LPX_DB 113 /* double-bounded variable */ +#define LPX_FX 114 /* fixed variable */ + +/* optimization direction flag: */ +#define LPX_MIN 120 /* minimization */ +#define LPX_MAX 121 /* maximization */ + +/* status of primal basic solution: */ +#define LPX_P_UNDEF 132 /* primal solution is undefined */ +#define LPX_P_FEAS 133 /* solution is primal feasible */ +#define LPX_P_INFEAS 134 /* solution is primal infeasible */ +#define LPX_P_NOFEAS 135 /* no primal feasible solution exists */ + +/* status of dual basic solution: */ +#define LPX_D_UNDEF 136 /* dual solution is undefined */ +#define LPX_D_FEAS 137 /* solution is dual feasible */ +#define LPX_D_INFEAS 138 /* solution is dual infeasible */ +#define LPX_D_NOFEAS 139 /* no dual feasible solution exists */ + +/* status of auxiliary/structural variable: */ +#define LPX_BS 140 /* basic variable */ +#define LPX_NL 141 /* non-basic variable on lower bound */ +#define LPX_NU 142 /* non-basic variable on upper bound */ +#define LPX_NF 143 /* non-basic free variable */ +#define LPX_NS 144 /* non-basic fixed variable */ + +/* status of interior-point solution: */ +#define LPX_T_UNDEF 150 /* interior solution is undefined */ +#define LPX_T_OPT 151 /* interior solution is optimal */ + +/* kind of structural variable: */ +#define LPX_CV 160 /* continuous variable */ +#define LPX_IV 161 /* integer variable */ + +/* status of integer solution: */ +#define LPX_I_UNDEF 170 /* integer solution is undefined */ +#define LPX_I_OPT 171 /* integer solution is optimal */ +#define LPX_I_FEAS 172 /* integer solution is feasible */ +#define LPX_I_NOFEAS 173 /* no integer solution exists */ + +/* status codes reported by the routine lpx_get_status: */ +#define LPX_OPT 180 /* optimal */ +#define LPX_FEAS 181 /* feasible */ +#define LPX_INFEAS 182 /* infeasible */ +#define LPX_NOFEAS 183 /* no feasible */ +#define LPX_UNBND 184 /* unbounded */ +#define LPX_UNDEF 185 /* undefined */ + +/* exit codes returned by solver routines: */ +#define LPX_E_OK 200 /* success */ +#define LPX_E_EMPTY 201 /* empty problem */ +#define LPX_E_BADB 202 /* invalid initial basis */ +#define LPX_E_INFEAS 203 /* infeasible initial solution */ +#define LPX_E_FAULT 204 /* unable to start the search */ +#define LPX_E_OBJLL 205 /* objective lower limit reached */ +#define LPX_E_OBJUL 206 /* objective upper limit reached */ +#define LPX_E_ITLIM 207 /* iterations limit exhausted */ +#define LPX_E_TMLIM 208 /* time limit exhausted */ +#define LPX_E_NOFEAS 209 /* no feasible solution */ +#define LPX_E_INSTAB 210 /* numerical instability */ +#define LPX_E_SING 211 /* problems with basis matrix */ +#define LPX_E_NOCONV 212 /* no convergence (interior) */ +#define LPX_E_NOPFS 213 /* no primal feas. sol. (LP presolver) */ +#define LPX_E_NODFS 214 /* no dual feas. sol. (LP presolver) */ +#define LPX_E_MIPGAP 215 /* relative mip gap tolerance reached */ + +/* control parameter identifiers: */ +#define LPX_K_MSGLEV 300 /* lp->msg_lev */ +#define LPX_K_SCALE 301 /* lp->scale */ +#define LPX_K_DUAL 302 /* lp->dual */ +#define LPX_K_PRICE 303 /* lp->price */ +#define LPX_K_RELAX 304 /* lp->relax */ +#define LPX_K_TOLBND 305 /* lp->tol_bnd */ +#define LPX_K_TOLDJ 306 /* lp->tol_dj */ +#define LPX_K_TOLPIV 307 /* lp->tol_piv */ +#define LPX_K_ROUND 308 /* lp->round */ +#define LPX_K_OBJLL 309 /* lp->obj_ll */ +#define LPX_K_OBJUL 310 /* lp->obj_ul */ +#define LPX_K_ITLIM 311 /* lp->it_lim */ +#define LPX_K_ITCNT 312 /* lp->it_cnt */ +#define LPX_K_TMLIM 313 /* lp->tm_lim */ +#define LPX_K_OUTFRQ 314 /* lp->out_frq */ +#define LPX_K_OUTDLY 315 /* lp->out_dly */ +#define LPX_K_BRANCH 316 /* lp->branch */ +#define LPX_K_BTRACK 317 /* lp->btrack */ +#define LPX_K_TOLINT 318 /* lp->tol_int */ +#define LPX_K_TOLOBJ 319 /* lp->tol_obj */ +#define LPX_K_MPSINFO 320 /* lp->mps_info */ +#define LPX_K_MPSOBJ 321 /* lp->mps_obj */ +#define LPX_K_MPSORIG 322 /* lp->mps_orig */ +#define LPX_K_MPSWIDE 323 /* lp->mps_wide */ +#define LPX_K_MPSFREE 324 /* lp->mps_free */ +#define LPX_K_MPSSKIP 325 /* lp->mps_skip */ +#define LPX_K_LPTORIG 326 /* lp->lpt_orig */ +#define LPX_K_PRESOL 327 /* lp->presol */ +#define LPX_K_BINARIZE 328 /* lp->binarize */ +#define LPX_K_USECUTS 329 /* lp->use_cuts */ +#define LPX_K_BFTYPE 330 /* lp->bfcp->type */ +#define LPX_K_MIPGAP 331 /* lp->mip_gap */ + +#define LPX_C_COVER 0x01 /* mixed cover cuts */ +#define LPX_C_CLIQUE 0x02 /* clique cuts */ +#define LPX_C_GOMORY 0x04 /* Gomory's mixed integer cuts */ +#define LPX_C_MIR 0x08 /* mixed integer rounding cuts */ +#define LPX_C_ALL 0xFF /* all cuts */ + +typedef struct +{ /* this structure contains results reported by the routines which + checks Karush-Kuhn-Tucker conditions (for details see comments + to those routines) */ + /*--------------------------------------------------------------*/ + /* xR - A * xS = 0 (KKT.PE) */ + double pe_ae_max; + /* largest absolute error */ + int pe_ae_row; + /* number of row with largest absolute error */ + double pe_re_max; + /* largest relative error */ + int pe_re_row; + /* number of row with largest relative error */ + int pe_quality; + /* quality of primal solution: + 'H' - high + 'M' - medium + 'L' - low + '?' - primal solution is wrong */ + /*--------------------------------------------------------------*/ + /* l[k] <= x[k] <= u[k] (KKT.PB) */ + double pb_ae_max; + /* largest absolute error */ + int pb_ae_ind; + /* number of variable with largest absolute error */ + double pb_re_max; + /* largest relative error */ + int pb_re_ind; + /* number of variable with largest relative error */ + int pb_quality; + /* quality of primal feasibility: + 'H' - high + 'M' - medium + 'L' - low + '?' - primal solution is infeasible */ + /*--------------------------------------------------------------*/ + /* A' * (dR - cR) + (dS - cS) = 0 (KKT.DE) */ + double de_ae_max; + /* largest absolute error */ + int de_ae_col; + /* number of column with largest absolute error */ + double de_re_max; + /* largest relative error */ + int de_re_col; + /* number of column with largest relative error */ + int de_quality; + /* quality of dual solution: + 'H' - high + 'M' - medium + 'L' - low + '?' - dual solution is wrong */ + /*--------------------------------------------------------------*/ + /* d[k] >= 0 or d[k] <= 0 (KKT.DB) */ + double db_ae_max; + /* largest absolute error */ + int db_ae_ind; + /* number of variable with largest absolute error */ + double db_re_max; + /* largest relative error */ + int db_re_ind; + /* number of variable with largest relative error */ + int db_quality; + /* quality of dual feasibility: + 'H' - high + 'M' - medium + 'L' - low + '?' - dual solution is infeasible */ + /*--------------------------------------------------------------*/ + /* (x[k] - bound of x[k]) * d[k] = 0 (KKT.CS) */ + double cs_ae_max; + /* largest absolute error */ + int cs_ae_ind; + /* number of variable with largest absolute error */ + double cs_re_max; + /* largest relative error */ + int cs_re_ind; + /* number of variable with largest relative error */ + int cs_quality; + /* quality of complementary slackness: + 'H' - high + 'M' - medium + 'L' - low + '?' - primal and dual solutions are not complementary */ +} LPXKKT; + +LPX *lpx_create_prob(void); +/* create problem object */ + +void lpx_set_prob_name(LPX *lp, const char *name); +/* assign (change) problem name */ + +void lpx_set_obj_name(LPX *lp, const char *name); +/* assign (change) objective function name */ + +void lpx_set_obj_dir(LPX *lp, int dir); +/* set (change) optimization direction flag */ + +int lpx_add_rows(LPX *lp, int nrs); +/* add new rows to problem object */ + +int lpx_add_cols(LPX *lp, int ncs); +/* add new columns to problem object */ + +void lpx_set_row_name(LPX *lp, int i, const char *name); +/* assign (change) row name */ + +void lpx_set_col_name(LPX *lp, int j, const char *name); +/* assign (change) column name */ + +void lpx_set_row_bnds(LPX *lp, int i, int type, double lb, double ub); +/* set (change) row bounds */ + +void lpx_set_col_bnds(LPX *lp, int j, int type, double lb, double ub); +/* set (change) column bounds */ + +void lpx_set_obj_coef(glp_prob *lp, int j, double coef); +/* set (change) obj. coefficient or constant term */ + +void lpx_set_mat_row(LPX *lp, int i, int len, const int ind[], + const double val[]); +/* set (replace) row of the constraint matrix */ + +void lpx_set_mat_col(LPX *lp, int j, int len, const int ind[], + const double val[]); +/* set (replace) column of the constraint matrix */ + +void lpx_load_matrix(LPX *lp, int ne, const int ia[], const int ja[], + const double ar[]); +/* load (replace) the whole constraint matrix */ + +void lpx_del_rows(LPX *lp, int nrs, const int num[]); +/* delete specified rows from problem object */ + +void lpx_del_cols(LPX *lp, int ncs, const int num[]); +/* delete specified columns from problem object */ + +void lpx_delete_prob(LPX *lp); +/* delete problem object */ + +const char *lpx_get_prob_name(LPX *lp); +/* retrieve problem name */ + +const char *lpx_get_obj_name(LPX *lp); +/* retrieve objective function name */ + +int lpx_get_obj_dir(LPX *lp); +/* retrieve optimization direction flag */ + +int lpx_get_num_rows(LPX *lp); +/* retrieve number of rows */ + +int lpx_get_num_cols(LPX *lp); +/* retrieve number of columns */ + +const char *lpx_get_row_name(LPX *lp, int i); +/* retrieve row name */ + +const char *lpx_get_col_name(LPX *lp, int j); +/* retrieve column name */ + +int lpx_get_row_type(LPX *lp, int i); +/* retrieve row type */ + +double lpx_get_row_lb(LPX *lp, int i); +/* retrieve row lower bound */ + +double lpx_get_row_ub(LPX *lp, int i); +/* retrieve row upper bound */ + +void lpx_get_row_bnds(LPX *lp, int i, int *typx, double *lb, + double *ub); +/* retrieve row bounds */ + +int lpx_get_col_type(LPX *lp, int j); +/* retrieve column type */ + +double lpx_get_col_lb(LPX *lp, int j); +/* retrieve column lower bound */ + +double lpx_get_col_ub(LPX *lp, int j); +/* retrieve column upper bound */ + +void lpx_get_col_bnds(LPX *lp, int j, int *typx, double *lb, + double *ub); +/* retrieve column bounds */ + +double lpx_get_obj_coef(LPX *lp, int j); +/* retrieve obj. coefficient or constant term */ + +int lpx_get_num_nz(LPX *lp); +/* retrieve number of constraint coefficients */ + +int lpx_get_mat_row(LPX *lp, int i, int ind[], double val[]); +/* retrieve row of the constraint matrix */ + +int lpx_get_mat_col(LPX *lp, int j, int ind[], double val[]); +/* retrieve column of the constraint matrix */ + +void lpx_create_index(LPX *lp); +/* create the name index */ + +int lpx_find_row(LPX *lp, const char *name); +/* find row by its name */ + +int lpx_find_col(LPX *lp, const char *name); +/* find column by its name */ + +void lpx_delete_index(LPX *lp); +/* delete the name index */ + +void lpx_scale_prob(LPX *lp); +/* scale problem data */ + +void lpx_unscale_prob(LPX *lp); +/* unscale problem data */ + +void lpx_set_row_stat(LPX *lp, int i, int stat); +/* set (change) row status */ + +void lpx_set_col_stat(LPX *lp, int j, int stat); +/* set (change) column status */ + +void lpx_std_basis(LPX *lp); +/* construct standard initial LP basis */ + +void lpx_adv_basis(LPX *lp); +/* construct advanced initial LP basis */ + +void lpx_cpx_basis(LPX *lp); +/* construct Bixby's initial LP basis */ + +int lpx_simplex(LPX *lp); +/* easy-to-use driver to the simplex method */ + +int lpx_exact(LPX *lp); +/* easy-to-use driver to the exact simplex method */ + +int lpx_get_status(LPX *lp); +/* retrieve generic status of basic solution */ + +int lpx_get_prim_stat(LPX *lp); +/* retrieve primal status of basic solution */ + +int lpx_get_dual_stat(LPX *lp); +/* retrieve dual status of basic solution */ + +double lpx_get_obj_val(LPX *lp); +/* retrieve objective value (basic solution) */ + +int lpx_get_row_stat(LPX *lp, int i); +/* retrieve row status (basic solution) */ + +double lpx_get_row_prim(LPX *lp, int i); +/* retrieve row primal value (basic solution) */ + +double lpx_get_row_dual(LPX *lp, int i); +/* retrieve row dual value (basic solution) */ + +void lpx_get_row_info(LPX *lp, int i, int *tagx, double *vx, + double *dx); +/* obtain row solution information */ + +int lpx_get_col_stat(LPX *lp, int j); +/* retrieve column status (basic solution) */ + +double lpx_get_col_prim(LPX *lp, int j); +/* retrieve column primal value (basic solution) */ + +double lpx_get_col_dual(glp_prob *lp, int j); +/* retrieve column dual value (basic solution) */ + +void lpx_get_col_info(LPX *lp, int j, int *tagx, double *vx, + double *dx); +/* obtain column solution information (obsolete) */ + +int lpx_get_ray_info(LPX *lp); +/* determine what causes primal unboundness */ + +void lpx_check_kkt(LPX *lp, int scaled, LPXKKT *kkt); +/* check Karush-Kuhn-Tucker conditions */ + +int lpx_warm_up(LPX *lp); +/* "warm up" LP basis */ + +int lpx_eval_tab_row(LPX *lp, int k, int ind[], double val[]); +/* compute row of the simplex table */ + +int lpx_eval_tab_col(LPX *lp, int k, int ind[], double val[]); +/* compute column of the simplex table */ + +int lpx_transform_row(LPX *lp, int len, int ind[], double val[]); +/* transform explicitly specified row */ + +int lpx_transform_col(LPX *lp, int len, int ind[], double val[]); +/* transform explicitly specified column */ + +int lpx_prim_ratio_test(LPX *lp, int len, const int ind[], + const double val[], int how, double tol); +/* perform primal ratio test */ + +int lpx_dual_ratio_test(LPX *lp, int len, const int ind[], + const double val[], int how, double tol); +/* perform dual ratio test */ + +int lpx_interior(LPX *lp); +/* easy-to-use driver to the interior point method */ + +int lpx_ipt_status(LPX *lp); +/* retrieve status of interior-point solution */ + +double lpx_ipt_obj_val(LPX *lp); +/* retrieve objective value (interior point) */ + +double lpx_ipt_row_prim(LPX *lp, int i); +/* retrieve row primal value (interior point) */ + +double lpx_ipt_row_dual(LPX *lp, int i); +/* retrieve row dual value (interior point) */ + +double lpx_ipt_col_prim(LPX *lp, int j); +/* retrieve column primal value (interior point) */ + +double lpx_ipt_col_dual(LPX *lp, int j); +/* retrieve column dual value (interior point) */ + +void lpx_set_class(LPX *lp, int klass); +/* set problem class */ + +int lpx_get_class(LPX *lp); +/* determine problem klass */ + +void lpx_set_col_kind(LPX *lp, int j, int kind); +/* set (change) column kind */ + +int lpx_get_col_kind(LPX *lp, int j); +/* retrieve column kind */ + +int lpx_get_num_int(LPX *lp); +/* retrieve number of integer columns */ + +int lpx_get_num_bin(LPX *lp); +/* retrieve number of binary columns */ + +int lpx_integer(LPX *lp); +/* easy-to-use driver to the branch-and-bound method */ + +int lpx_intopt(LPX *lp); +/* easy-to-use driver to the branch-and-bound method */ + +int lpx_mip_status(LPX *lp); +/* retrieve status of MIP solution */ + +double lpx_mip_obj_val(LPX *lp); +/* retrieve objective value (MIP solution) */ + +double lpx_mip_row_val(LPX *lp, int i); +/* retrieve row value (MIP solution) */ + +double lpx_mip_col_val(LPX *lp, int j); +/* retrieve column value (MIP solution) */ + +void lpx_check_int(LPX *lp, LPXKKT *kkt); +/* check integer feasibility conditions */ + +void lpx_reset_parms(LPX *lp); +/* reset control parameters to default values */ + +void lpx_set_int_parm(LPX *lp, int parm, int val); +/* set (change) integer control parameter */ + +int lpx_get_int_parm(LPX *lp, int parm); +/* query integer control parameter */ + +void lpx_set_real_parm(LPX *lp, int parm, double val); +/* set (change) real control parameter */ + +double lpx_get_real_parm(LPX *lp, int parm); +/* query real control parameter */ + +LPX *lpx_read_mps(const char *fname); +/* read problem data in fixed MPS format */ + +int lpx_write_mps(LPX *lp, const char *fname); +/* write problem data in fixed MPS format */ + +int lpx_read_bas(LPX *lp, const char *fname); +/* read LP basis in fixed MPS format */ + +int lpx_write_bas(LPX *lp, const char *fname); +/* write LP basis in fixed MPS format */ + +LPX *lpx_read_freemps(const char *fname); +/* read problem data in free MPS format */ + +int lpx_write_freemps(LPX *lp, const char *fname); +/* write problem data in free MPS format */ + +LPX *lpx_read_cpxlp(const char *fname); +/* read problem data in CPLEX LP format */ + +int lpx_write_cpxlp(LPX *lp, const char *fname); +/* write problem data in CPLEX LP format */ + +LPX *lpx_read_model(const char *model, const char *data, + const char *output); +/* read LP/MIP model written in GNU MathProg language */ + +int lpx_print_prob(LPX *lp, const char *fname); +/* write problem data in plain text format */ + +int lpx_print_sol(LPX *lp, const char *fname); +/* write LP problem solution in printable format */ + +int lpx_print_sens_bnds(LPX *lp, const char *fname); +/* write bounds sensitivity information */ + +int lpx_print_ips(LPX *lp, const char *fname); +/* write interior point solution in printable format */ + +int lpx_print_mip(LPX *lp, const char *fname); +/* write MIP problem solution in printable format */ + +int lpx_is_b_avail(LPX *lp); +/* check if LP basis is available */ + +int lpx_main(int argc, const char *argv[]); +/* stand-alone LP/MIP solver */ + +#ifdef __cplusplus +} +#endif + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/oldapi/lpxsamp.c b/resources/3rdparty/glpk-4.57/examples/oldapi/lpxsamp.c new file mode 100644 index 000000000..dd081482f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/oldapi/lpxsamp.c @@ -0,0 +1,51 @@ +/* lpxsamp.c */ + +#include +#include +#include "lpx.h" + +int main(void) +{ LPX *lp; + int ia[1+1000], ja[1+1000]; + double ar[1+1000], Z, x1, x2, x3; +s1: lp = lpx_create_prob(); +s2: lpx_set_prob_name(lp, "sample"); +s3: lpx_set_obj_dir(lp, LPX_MAX); +s4: lpx_add_rows(lp, 3); +s5: lpx_set_row_name(lp, 1, "p"); +s6: lpx_set_row_bnds(lp, 1, LPX_UP, 0.0, 100.0); +s7: lpx_set_row_name(lp, 2, "q"); +s8: lpx_set_row_bnds(lp, 2, LPX_UP, 0.0, 600.0); +s9: lpx_set_row_name(lp, 3, "r"); +s10: lpx_set_row_bnds(lp, 3, LPX_UP, 0.0, 300.0); +s11: lpx_add_cols(lp, 3); +s12: lpx_set_col_name(lp, 1, "x1"); +s13: lpx_set_col_bnds(lp, 1, LPX_LO, 0.0, 0.0); +s14: lpx_set_obj_coef(lp, 1, 10.0); +s15: lpx_set_col_name(lp, 2, "x2"); +s16: lpx_set_col_bnds(lp, 2, LPX_LO, 0.0, 0.0); +s17: lpx_set_obj_coef(lp, 2, 6.0); +s18: lpx_set_col_name(lp, 3, "x3"); +s19: lpx_set_col_bnds(lp, 3, LPX_LO, 0.0, 0.0); +s20: lpx_set_obj_coef(lp, 3, 4.0); +s21: ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */ +s22: ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */ +s23: ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */ +s24: ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */ +s25: ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */ +s26: ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */ +s27: ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */ +s28: ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */ +s29: ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */ +s30: lpx_load_matrix(lp, 9, ia, ja, ar); +s31: lpx_simplex(lp); +s32: Z = lpx_get_obj_val(lp); +s33: x1 = lpx_get_col_prim(lp, 1); +s34: x2 = lpx_get_col_prim(lp, 2); +s35: x3 = lpx_get_col_prim(lp, 3); +s36: printf("\nZ = %g; x1 = %g; x2 = %g; x3 = %g\n", Z, x1, x2, x3); +s37: lpx_delete_prob(lp); + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/9dom.dat b/resources/3rdparty/glpk-4.57/examples/pbn/9dom.dat new file mode 100644 index 000000000..80ece7af5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/9dom.dat @@ -0,0 +1,65 @@ +/* 9dom.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #8098 from . +* Copyright (C) 2010 by Josh Greifer. Used by permission. +* +* Domino Logic III (Abstract pattern) +* +* created by Josh Greifer +* Apr 5, 2010 +* +* Encoded in GNU MathProg by Andrew Makhorin . +***********************************************************************/ + +data; + +param m := 19; + +param n := 19; + +param row : 1 2 := + 1 3 . + 2 1 . + 3 3 1 + 4 1 . + 5 3 1 + 6 1 . + 7 3 1 + 8 1 . + 9 3 1 + 10 1 . + 11 3 1 + 12 1 . + 13 3 1 + 14 1 . + 15 3 1 + 16 1 . + 17 3 1 + 18 1 . + 19 1 . +; + +param col : 1 2 := + 1 1 . + 2 1 . + 3 1 3 + 4 1 . + 5 1 3 + 6 1 . + 7 1 3 + 8 1 . + 9 1 3 + 10 1 . + 11 1 3 + 12 1 . + 13 1 3 + 14 1 . + 15 1 3 + 16 1 . + 17 1 3 + 18 1 . + 19 3 . +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/README b/resources/3rdparty/glpk-4.57/examples/pbn/README new file mode 100644 index 000000000..43dc82ce3 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/README @@ -0,0 +1,6 @@ +This subdirectory contains examples, which illustrate how to use +GLPK and the GNU MathProg modeling language for practical solving the +paint-by-numbers puzzle. + +For details please see the document "Solving Paint-By-Numbers Puzzles +with GLPK" included in this subdirectory (file pbn.pdf). diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/bucks.dat b/resources/3rdparty/glpk-4.57/examples/pbn/bucks.dat new file mode 100644 index 000000000..5dfc4f100 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/bucks.dat @@ -0,0 +1,77 @@ +/* bucks.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #27 from . +* Copyright (C) 2004 by Jan Wolter. Used by permission. +* +* Party at the Right [Political] +* +* created by Jan Wolter +* Apr 6, 2004 +* +* Encoded in GNU MathProg by Andrew Makhorin . +***********************************************************************/ + +data; + +param m := 23; + +param n := 27; + +param row : 1 2 3 4 5 6 7 8 := + 1 11 . . . . . . . + 2 17 . . . . . . . + 3 3 5 5 3 . . . . + 4 2 2 2 1 . . . . + 5 2 1 3 1 3 1 4 . + 6 3 3 3 3 . . . . + 7 5 1 3 1 3 1 3 . + 8 3 2 2 4 . . . . + 9 5 5 5 5 . . . . + 10 23 . . . . . . . + 11 . . . . . . . . + 12 23 . . . . . . . + 13 1 1 . . . . . . + 14 1 1 . . . . . . + 15 1 2 1 . . . . . + 16 1 1 1 1 . . . . + 17 1 1 1 1 . . . . + 18 1 10 1 2 1 . . . + 19 1 1 1 1 1 1 3 . + 20 1 1 1 1 1 1 1 1 + 21 1 1 1 1 1 1 1 . + 22 1 1 1 1 2 2 . . + 23 5 5 3 . . . . . +; + +param col : 1 2 3 4 5 6 := + 1 4 12 . . . . + 2 6 1 1 . . . + 3 8 1 1 . . . + 4 3 2 2 1 1 . + 5 2 1 1 2 1 6 + 6 1 1 1 1 . . + 7 3 1 1 2 1 1 + 8 3 2 3 1 1 . + 9 10 1 1 . . . + 10 4 2 2 1 1 . + 11 3 1 1 2 1 1 + 12 2 1 1 1 . . + 13 3 1 1 2 1 1 + 14 3 2 3 1 6 . + 15 10 1 1 . . . + 16 4 2 2 1 1 . + 17 3 1 1 2 1 1 + 18 1 1 1 9 . . + 19 2 1 1 2 1 1 + 20 2 2 3 1 3 . + 21 8 1 5 . . . + 22 6 1 1 . . . + 23 4 9 1 . . . + 24 1 1 . . . . + 25 2 1 . . . . + 26 1 1 . . . . + 27 4 . . . . . +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/cat.dat b/resources/3rdparty/glpk-4.57/examples/pbn/cat.dat new file mode 100644 index 000000000..a6554117d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/cat.dat @@ -0,0 +1,67 @@ +/* cat.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #6 from . +* Copyright (C) 2004 by Jan Wolter. Used by permission. +* +* Scardy Cat +* +* created by Jan Wolter +* Mar 24, 2004 +* +* Encoded in GNU MathProg by Andrew Makhorin . +***********************************************************************/ + +data; + +param m := 20; + +param n := 20; + +param row : 1 2 3 4 := + 1 2 . . . + 2 2 . . . + 3 1 . . . + 4 1 . . . + 5 1 3 . . + 6 2 5 . . + 7 1 7 1 1 + 8 1 8 2 2 + 9 1 9 5 . + 10 2 16 . . + 11 1 17 . . + 12 7 11 . . + 13 5 5 3 . + 14 5 4 . . + 15 3 3 . . + 16 2 2 . . + 17 2 1 . . + 18 1 1 . . + 19 2 2 . . + 20 2 2 . . +; + +param col : 1 2 3 := + 1 5 . . + 2 5 3 . + 3 2 3 4 + 4 1 7 2 + 5 8 . . + 6 9 . . + 7 9 . . + 8 8 . . + 9 7 . . + 10 8 . . + 11 9 . . + 12 10 . . + 13 13 . . + 14 6 2 . + 15 4 . . + 16 6 . . + 17 6 . . + 18 5 . . + 19 6 . . + 20 6 . . +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/dancer.dat b/resources/3rdparty/glpk-4.57/examples/pbn/dancer.dat new file mode 100644 index 000000000..42e3057a4 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/dancer.dat @@ -0,0 +1,42 @@ +/* dancer.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #1 from . +* Copyright (C) 2004 by Jan Wolter. Used by permission. +* +* Demo Puzzle from Front Page +* +* created by Jan Wolter +* Mar 24, 2004 +* +* Encoded in GNU MathProg by Andrew Makhorin . +***********************************************************************/ + +data; + +param m := 10; + +param n := 5; + +param row : 1 2 3 := + 1 2 . . + 2 2 1 . + 3 1 1 . + 4 3 . . + 5 1 1 . + 6 1 1 . + 7 2 . . + 8 1 1 . + 9 1 2 . + 10 2 . . +; + +param col : 1 2 3 := + 1 2 1 . + 2 2 1 3 + 3 7 . . + 4 1 3 . + 5 2 1 . +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/disney.dat b/resources/3rdparty/glpk-4.57/examples/pbn/disney.dat new file mode 100644 index 000000000..2eab1fe2d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/disney.dat @@ -0,0 +1,115 @@ +/* disney.dat */ + +data; + +param m := 50; + +param n := 50; + +param row : 1 2 3 4 5 6 7 := + 1 8 . . . . . . + 2 7 15 . . . . . + 3 2 2 19 . . . . + 4 1 2 16 1 2 . . + 5 1 5 14 1 . . . + 6 2 4 13 1 1 . . + 7 6 12 5 . . . . + 8 1 5 6 11 . . . + 9 1 4 5 4 8 . . + 10 1 4 1 18 . . . + 11 1 5 2 11 4 . . + 12 1 8 2 6 3 . . + 13 1 7 1 3 2 . . + 14 1 13 2 . . . . + 15 1 12 1 . . . . + 16 1 2 7 4 2 . . + 17 2 3 4 2 . . . + 18 5 4 3 1 . . . + 19 8 4 3 1 . . . + 20 10 3 2 1 . . . + 21 12 1 1 . . . . + 22 13 1 1 1 . . . + 23 15 1 1 3 . . . + 24 3 5 5 1 2 1 . + 25 4 5 5 2 4 2 . + 26 3 3 5 1 1 2 1 + 27 3 3 2 4 2 2 . + 28 2 3 2 3 3 2 . + 29 2 4 3 3 5 . . + 30 2 7 4 1 4 3 . + 31 3 13 1 4 5 . . + 32 9 4 1 4 7 6 1 + 33 8 1 1 2 1 15 . + 34 6 6 3 1 1 6 6 + 35 6 3 8 1 2 6 6 + 36 2 5 13 3 1 . . + 37 5 1 11 3 4 . . + 38 9 8 4 3 . . . + 39 9 6 3 10 3 . . + 40 10 5 3 2 2 3 . + 41 10 6 3 2 10 . . + 42 10 4 2 1 9 . . + 43 11 3 2 2 4 . . + 44 11 2 2 1 1 2 3 + 45 8 2 2 2 8 . . + 46 5 1 2 2 4 4 . + 47 6 2 2 2 3 4 . + 48 8 2 2 2 3 3 . + 49 10 2 4 3 1 5 4 + 50 12 7 7 4 7 . . +; + +param col : 1 2 3 4 5 6 7 8 9 10 := + 1 14 . . . . . . . . . + 2 9 15 . . . . . . . . + 3 28 . . . . . . . . . + 4 7 5 14 . . . . . . . + 5 6 4 14 . . . . . . . + 6 5 5 8 4 . . . . . . + 7 7 6 8 3 . . . . . . + 8 19 8 3 . . . . . . . + 9 16 9 2 . . . . . . . + 10 15 2 5 2 . . . . . . + 11 8 3 1 3 1 . . . . . + 12 4 7 2 2 3 1 . . . . + 13 2 12 6 3 1 2 . . . . + 14 1 1 12 1 2 . . . . . + 15 1 4 9 2 1 2 . . . . + 16 1 6 5 6 1 . . . . . + 17 1 7 5 3 5 1 1 . . . + 18 1 8 8 6 2 1 . . . . + 19 2 1 7 5 9 1 . . . . + 20 2 2 7 6 9 1 . . . . + 21 6 15 9 2 . . . . . . + 22 7 5 4 14 1 . . . . . + 23 8 4 4 3 6 1 1 . . . + 24 9 5 2 7 3 2 3 . . . + 25 9 7 4 10 1 2 1 . . . + 26 8 2 4 2 5 2 2 2 1 . + 27 7 2 6 2 3 5 2 1 . . + 28 7 4 4 2 5 2 2 1 . . + 29 7 3 4 1 1 2 1 . . . + 30 7 3 4 1 2 2 2 . . . + 31 8 6 1 1 2 1 . . . . + 32 6 1 3 1 2 1 2 . . . + 33 4 1 3 2 2 1 2 2 . . + 34 4 1 3 1 3 1 2 2 2 . + 35 3 5 1 1 1 2 1 1 1 2 + 36 2 6 1 1 3 1 1 3 . . + 37 2 5 1 5 6 1 3 . . . + 38 2 6 2 6 3 2 . . . . + 39 1 4 2 6 2 2 1 . . . + 40 2 5 3 4 1 2 2 . . . + 41 3 7 3 1 10 . . . . . + 42 5 2 1 9 . . . . . . + 43 3 2 2 2 6 . . . . . + 44 2 1 1 2 3 2 . . . . + 45 4 2 2 2 1 . . . . . + 46 4 1 2 3 1 . . . . . + 47 4 1 1 2 3 2 . . . . + 48 6 4 6 . . . . . . . + 49 3 3 5 . . . . . . . + 50 3 2 3 . . . . . . . +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/dragon.dat b/resources/3rdparty/glpk-4.57/examples/pbn/dragon.dat new file mode 100644 index 000000000..d2b8b14de --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/dragon.dat @@ -0,0 +1,61 @@ +/* dragon.dat */ + +/*********************************************************************** +* Hard 20x20 paint-by-numbers puzzle designed by Won Yoon Jo +* from the article "Painting by Numbers" by Robert A. Bosch (2000), +* . +* +* Encoded in GNU MathProg by Andrew Makhorin . +***********************************************************************/ + +data; + +param m := 20; + +param n := 20; + +param row : 1 2 3 4 5 := + 1 7 1 . . . + 2 1 1 2 . . + 3 2 1 2 . . + 4 1 2 2 . . + 5 4 2 3 . . + 6 3 1 4 . . + 7 3 1 3 . . + 8 2 1 4 . . + 9 2 9 . . . + 10 2 1 5 . . + 11 2 7 . . . + 12 14 . . . . + 13 8 2 . . . + 14 6 2 2 . . + 15 2 8 1 3 . + 16 1 5 5 2 . + 17 1 3 2 4 1 + 18 3 1 2 4 1 + 19 1 1 3 1 3 + 20 2 1 1 2 . ; + +param col : 1 2 3 4 5 := + 1 1 1 1 2 . + 2 3 1 2 1 1 + 3 1 4 2 1 1 + 4 1 3 2 4 . + 5 1 4 6 1 . + 6 1 11 1 . . + 7 5 1 6 2 . + 8 14 . . . . + 9 7 2 . . . + 10 7 2 . . . + 11 6 1 1 . . + 12 9 2 . . . + 13 3 1 1 1 . + 14 3 1 3 . . + 15 2 1 3 . . + 16 2 1 5 . . + 17 3 2 2 . . + 18 3 3 2 . . + 19 2 3 2 . . + 20 2 6 . . . ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/edge.dat b/resources/3rdparty/glpk-4.57/examples/pbn/edge.dat new file mode 100644 index 000000000..cdd1864e9 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/edge.dat @@ -0,0 +1,48 @@ +/* edge.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #23 from . +* Copyright (C) 2004 by Jan Wolter. Used by permission. +* +* Nonrepresentational Test Pattern +* +* created by Jan Wolter +* Apr 5, 2004 +* +* Encoded in GNU MathProg by Andrew Makhorin . +***********************************************************************/ + +data; + +param m := 11; + +param n := 10; + +param row : 1 := + 1 1 + 2 3 + 3 1 + 4 2 + 5 1 + 6 3 + 7 3 + 8 1 + 9 2 + 10 2 + 11 4 +; + +param col : 1 2 := + 1 1 . + 2 3 . + 3 1 . + 4 2 2 + 5 2 . + 6 4 . + 7 1 . + 8 3 . + 9 3 . + 10 1 . +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/forever.dat b/resources/3rdparty/glpk-4.57/examples/pbn/forever.dat new file mode 100644 index 000000000..e3bebf75f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/forever.dat @@ -0,0 +1,77 @@ +/* forever.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #6574 from . +* Copyright (C) 2009 by Gator. Used by permission. +* +* Lasts Forever +* +* created by Gator +* Aug 24, 2009 +* +* Encoded in GNU MathProg by Andrew Makhorin . +***********************************************************************/ + +data; + +param m := 25; + +param n := 25; + +param row : 1 2 3 4 5 6 7 8 := + 1 1 2 2 2 2 2 1 . + 2 1 2 2 2 2 2 1 1 + 3 1 1 . . . . . . + 4 1 1 . . . . . . + 5 1 3 1 . . . . . + 6 1 13 1 . . . . . + 7 1 13 1 . . . . . + 8 1 13 1 . . . . . + 9 1 4 4 1 . . . . + 10 1 4 3 4 1 . . . + 11 1 4 5 4 1 . . . + 12 1 7 1 . . . . . + 13 1 7 1 . . . . . + 14 1 7 1 . . . . . + 15 1 7 1 . . . . . + 16 1 1 5 1 . . . . + 17 1 2 6 1 . . . . + 18 1 4 6 1 . . . . + 19 1 6 6 1 . . . . + 20 1 3 1 . . . . . + 21 1 1 1 . . . . . + 22 1 1 . . . . . . + 23 1 1 . . . . . . + 24 1 1 2 2 2 2 2 1 + 25 1 2 2 2 2 2 1 . +; + +param col : 1 2 3 4 5 6 7 8 := + 1 1 2 2 2 2 2 1 . + 2 1 1 2 2 2 2 2 1 + 3 1 1 . . . . . . + 4 1 1 . . . . . . + 5 1 1 . . . . . . + 6 1 2 1 . . . . . + 7 1 6 1 1 . . . . + 8 1 6 2 1 . . . . + 9 1 6 3 1 . . . . + 10 1 4 8 1 . . . . + 11 1 3 5 2 1 . . . + 12 1 4 8 2 1 . . . + 13 1 4 9 2 1 . . . + 14 1 4 11 1 . . . . + 15 1 3 9 1 . . . . + 16 1 4 8 1 . . . . + 17 1 6 3 1 . . . . + 18 1 6 2 1 . . . . + 19 1 6 1 1 . . . . + 20 1 2 1 . . . . . + 21 1 1 . . . . . . + 22 1 1 . . . . . . + 23 1 1 . . . . . . + 24 1 2 2 2 2 2 1 1 + 25 1 2 2 2 2 2 1 . +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/knot.dat b/resources/3rdparty/glpk-4.57/examples/pbn/knot.dat new file mode 100644 index 000000000..b9e12d796 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/knot.dat @@ -0,0 +1,95 @@ +/* knot.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #16 from . +* Copyright (C) 2004 by Jan Wolter. Used by permission. +* +* Probably Not +* +* created by Jan Wolter +* Mar 27, 2004 +* +* Encoded in GNU MathProg by Andrew Makhorin . +***********************************************************************/ + +data; + +param m := 34; + +param n := 34; + +param row : 1 2 3 4 5 6 7 8 := + 1 1 1 . . . . . . + 2 2 2 . . . . . . + 3 3 3 . . . . . . + 4 2 1 1 2 . . . . + 5 2 1 1 2 . . . . + 6 1 1 1 1 . . . . + 7 1 1 1 1 . . . . + 8 18 . . . . . . . + 9 2 1 1 1 1 2 . . + 10 1 1 1 1 1 1 . . + 11 1 1 1 1 1 1 . . + 12 26 . . . . . . . + 13 2 1 1 1 1 1 1 2 + 14 2 1 1 2 2 1 1 2 + 15 2 1 1 2 2 1 1 2 + 16 14 14 . . . . . . + 17 1 1 1 1 . . . . + 18 1 1 1 1 . . . . + 19 14 14 . . . . . . + 20 2 1 1 2 2 1 1 2 + 21 2 1 1 2 2 1 1 2 + 22 2 1 1 1 1 1 1 2 + 23 26 . . . . . . . + 24 1 1 1 1 1 1 . . + 25 1 1 1 1 1 1 . . + 26 2 1 1 1 1 2 . . + 27 18 . . . . . . . + 28 1 1 1 1 . . . . + 29 1 1 1 1 . . . . + 30 2 1 1 2 . . . . + 31 2 1 1 2 . . . . + 32 3 3 . . . . . . + 33 2 2 . . . . . . + 34 1 1 . . . . . . +; + +param col : 1 2 3 4 5 6 7 8 := + 1 1 1 . . . . . . + 2 2 2 . . . . . . + 3 3 3 . . . . . . + 4 2 1 1 2 . . . . + 5 2 1 1 2 . . . . + 6 1 1 1 1 . . . . + 7 1 1 1 1 . . . . + 8 18 . . . . . . . + 9 2 1 1 1 1 2 . . + 10 1 1 1 1 1 1 . . + 11 1 1 1 1 1 1 . . + 12 26 . . . . . . . + 13 2 1 1 1 1 1 1 2 + 14 2 1 1 2 2 1 1 2 + 15 2 1 1 2 2 1 1 2 + 16 14 14 . . . . . . + 17 1 1 1 1 . . . . + 18 1 1 1 1 . . . . + 19 14 14 . . . . . . + 20 2 1 1 2 2 1 1 2 + 21 2 1 1 2 2 1 1 2 + 22 2 1 1 1 1 1 1 2 + 23 26 . . . . . . . + 24 1 1 1 1 1 1 . . + 25 1 1 1 1 1 1 . . + 26 2 1 1 1 1 2 . . + 27 18 . . . . . . . + 28 1 1 1 1 . . . . + 29 1 1 1 1 . . . . + 30 2 1 1 2 . . . . + 31 2 1 1 2 . . . . + 32 3 3 . . . . . . + 33 2 2 . . . . . . + 34 1 1 . . . . . . +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/light.dat b/resources/3rdparty/glpk-4.57/examples/pbn/light.dat new file mode 100644 index 000000000..1ffc5d460 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/light.dat @@ -0,0 +1,122 @@ +/* light.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #803 from . +* Copyright (C) 2007 by Robert Kummerfeldt. Used by permission. +* +* You light up my life +* +* created by Robert Kummerfeldt +* Mar 15, 2007 +* +* Encoded in GNU MathProg by Andrew Makhorin . +***********************************************************************/ + +data; + +param m := 45; + +param n := 50; + +param row : 1 2 3 4 := + 1 . . . . + 2 1 . . . + 3 1 . . . + 4 3 . . . + 5 2 2 . . + 6 1 1 . . + 7 7 . . . + 8 1 1 . . + 9 1 3 1 . + 10 1 3 1 . + 11 1 1 . . + 12 11 . . . + 13 1 1 . . + 14 1 1 . . + 15 2 2 . . + 16 1 1 . . + 17 1 1 . . + 18 1 1 . . + 19 1 1 . . + 20 2 2 . . + 21 1 1 . . + 22 1 1 . . + 23 1 1 . . + 24 1 1 . . + 25 1 1 . . + 26 1 1 . . + 27 1 1 . . + 28 1 1 . . + 29 1 1 . . + 30 1 1 . . + 31 2 2 . . + 32 1 1 . . + 33 1 1 . . + 34 1 1 . . + 35 1 1 . . + 36 1 1 . . + 37 1 4 1 . + 38 1 1 1 1 + 39 1 1 1 1 + 40 1 1 1 1 + 41 1 1 1 1 + 42 25 . . . + 43 6 5 . . + 44 5 6 . . + 45 4 5 . . +; + +param col : 1 2 3 4 5 := + 1 1 . . . . + 2 1 . . . . + 3 1 . . . . + 4 2 . . . . + 5 1 . . . . + 6 1 . . . . + 7 1 . . . . + 8 2 . . . . + 9 1 . . . . + 10 1 . . . . + 11 1 . . . . + 12 1 . . . . + 13 2 . . . . + 14 1 . . . . + 15 1 . . . . + 16 1 . . . . + 17 5 . . . . + 18 7 1 . . . + 19 6 1 . . . + 20 6 1 . . . + 21 1 6 1 . . + 22 4 1 . . . + 23 7 1 . . . + 24 1 1 1 1 . + 25 2 1 2 1 1 + 26 3 1 2 1 1 + 27 2 1 2 1 1 + 28 1 1 1 1 . + 29 7 6 . . . + 30 4 1 1 . . + 31 1 6 1 1 . + 32 6 6 . . . + 33 6 1 . . . + 34 5 1 . . . + 35 7 . . . . + 36 1 . . . . + 37 2 . . . . + 38 1 . . . . + 39 1 . . . . + 40 1 . . . . + 41 2 . . . . + 42 1 . . . . + 43 1 . . . . + 44 1 . . . . + 45 1 . . . . + 46 2 . . . . + 47 1 . . . . + 48 1 . . . . + 49 1 . . . . + 50 1 . . . . +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/mum.dat b/resources/3rdparty/glpk-4.57/examples/pbn/mum.dat new file mode 100644 index 000000000..a1baf5090 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/mum.dat @@ -0,0 +1,101 @@ +/* mum.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #65 from . +* Copyright (C) 2004 by Jan Wolter. Used by permission. +* +* Mum's the Word [has only one solution] +* +* created by Jan Wolter +* Jul 10, 2004 +* +* Encoded in GNU MathProg by Andrew Makhorin . +***********************************************************************/ + +data; + +param m := 40; + +param n := 34; + +param row : 1 2 3 4 5 6 7 8 9 := + 1 12 . . . . . . . . + 2 5 2 5 . . . . . . + 3 5 2 2 5 . . . . . + 4 1 2 2 2 2 2 1 . . + 5 4 2 2 4 2 2 4 . . + 6 4 2 2 4 2 2 4 . . + 7 1 2 2 2 2 2 1 . . + 8 6 2 2 2 2 2 6 . . + 9 6 2 2 2 2 2 6 . . + 10 1 14 1 . . . . . . + 11 10 10 . . . . . . . + 12 8 3 3 8 . . . . . + 13 1 1 2 1 1 2 1 1 . + 14 9 2 2 2 2 9 . . . + 15 9 9 . . . . . . . + 16 1 1 1 1 1 1 . . . + 17 12 2 12 . . . . . . + 18 12 12 . . . . . . . + 19 1 1 4 1 1 . . . . + 20 14 14 . . . . . . . + 21 12 12 . . . . . . . + 22 2 1 4 1 2 . . . . + 23 9 4 9 . . . . . . + 24 1 7 4 7 1 . . . . + 25 1 1 1 4 1 1 1 . . + 26 1 7 4 7 1 . . . . + 27 1 7 4 7 1 . . . . + 28 1 2 1 2 1 2 1 . . + 29 1 7 2 7 1 . . . . + 30 1 1 6 2 6 1 1 . . + 31 1 1 1 1 2 1 1 1 1 + 32 1 1 6 2 6 1 1 . . + 33 1 1 5 5 1 1 . . . + 34 1 1 1 8 1 1 1 . . + 35 1 1 4 4 1 1 . . . + 36 1 2 6 2 1 . . . . + 37 2 4 4 2 . . . . . + 38 2 6 2 . . . . . . + 39 4 4 . . . . . . . + 40 6 . . . . . . . . +; + +param col : 1 2 3 4 5 6 7 8 9 10 11 12 := + 1 5 . . . . . . . . . . . + 2 3 2 1 . . . . . . . . . + 3 3 2 2 1 . . . . . . . . + 4 3 2 2 2 2 . . . . . . . + 5 3 2 2 2 2 3 . . . . . . + 6 1 2 2 2 2 2 16 . . . . . + 7 1 2 2 2 2 2 2 1 2 . . . + 8 1 2 2 2 2 2 2 13 1 . . . + 9 3 2 2 2 2 2 2 4 1 1 . . + 10 6 5 2 2 2 2 6 1 1 . . . + 11 1 7 3 2 2 2 2 2 1 1 1 . + 12 3 4 1 2 2 2 2 2 2 1 1 1 + 13 6 1 2 3 2 2 2 2 1 1 1 . + 14 1 7 2 16 1 1 . . . . . . + 15 1 4 1 1 1 1 1 1 1 1 1 . + 16 1 2 1 3 1 1 6 1 1 1 1 . + 17 2 7 1 1 11 1 1 1 1 . . . + 18 2 7 1 1 11 1 1 1 1 . . . + 19 1 2 1 3 1 1 6 1 1 1 1 . + 20 1 4 1 1 1 1 1 1 1 1 1 . + 21 1 7 2 16 1 1 . . . . . . + 22 6 1 2 3 2 2 2 2 1 1 1 . + 23 3 4 1 2 2 2 2 2 2 1 1 1 + 24 1 7 3 2 2 2 2 2 1 1 1 . + 25 6 5 2 2 2 2 6 1 1 . . . + 26 3 2 2 2 2 2 2 4 1 1 . . + 27 1 2 2 2 2 2 2 13 1 . . . + 28 1 2 2 2 2 2 2 1 2 . . . + 29 1 2 2 2 2 2 16 . . . . . + 30 3 2 2 2 2 3 . . . . . . + 31 3 2 2 2 2 . . . . . . . + 32 3 2 2 1 . . . . . . . . + 33 3 2 1 . . . . . . . . . + 34 5 . . . . . . . . . . . +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/pbn.mod b/resources/3rdparty/glpk-4.57/examples/pbn/pbn.mod new file mode 100644 index 000000000..f9616f104 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/pbn.mod @@ -0,0 +1,268 @@ +/* PBN, Paint-By-Numbers Puzzle */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* NOTE: See also the document "Solving Paint-By-Numbers Puzzles with + GLPK", which is included in the GLPK distribution. */ + +/* A paint-by-numbers puzzle consists of an m*n grid of pixels (the + canvas) together with m+n cluster-size sequences, one for each row + and column. The goal is to paint the canvas with a picture that + satisfies the following constraints: + + 1. Each pixel must be blank or white. + + 2. If a row or column has cluster-size sequence s1, s2, ..., sk, + then it must contain k clusters of black pixels - the first with + s1 black pixels, the second with s2 black pixels, and so on. + + It should be noted that "first" means "leftmost" for rows and + "topmost" for columns, and that rows and columns need not begin or + end with black pixels. + + Example: + 1 1 + 1 1 + 2 1 1 1 1 1 2 3 + 3 2 1 2 1 2 3 4 8 9 + + 3 6 # # # . # # # # # # + 1 4 # . . . . . # # # # + 1 1 3 . . # . # . . # # # + 2 . . . . . . . . # # + 3 3 . . # # # . . # # # + 1 4 # . . . . . # # # # + 2 5 # # . . . # # # # # + 2 5 # # . . . # # # # # + 1 1 . . . # . . . . . # + 3 . . # # # . . . . . + + (In Russia such puzzles are known as "Japanese crosswords".) + + References: + Robert A. Bosch, "Painting by Numbers", 2000. + */ + +/*--------------------------------------------------------------------*/ +/* Main part based on the formulation proposed by Robert Bosch. */ + +param m, integer, >= 1; +/* the number of rows */ + +param n, integer, >= 1; +/* the number of columns */ + +param row{i in 1..m, 1..n div 2}, integer, >= 0, default 0; +/* the cluster-size sequence for row i (raw data) */ + +param col{j in 1..n, 1..m div 2}, integer, >= 0, default 0; +/* the cluster-size sequence for column j (raw data) */ + +param kr{i in 1..m} := sum{t in 1..n div 2: row[i,t] > 0} 1; +/* the number of clusters in row i */ + +param kc{j in 1..n} := sum{t in 1..m div 2: col[j,t] > 0} 1; +/* the number of clusters in column j */ + +param sr{i in 1..m, t in 1..kr[i]} := row[i,t], integer, >= 1; +/* the cluster-size sequence for row i */ + +param sc{j in 1..n, t in 1..kc[j]} := col[j,t], integer, >= 1; +/* the cluster-size sequence for column j */ + +check{i in 1..m}: sum{t in 1..kr[i]} sr[i,t] <= n - (kr[i] - 1); +/* check that the sum of the cluster sizes in each row is valid */ + +check{j in 1..n}: sum{t in 1..kc[j]} sc[j,t] <= m - (kc[j] - 1); +/* check that the sum of the cluster sizes in each column is valid */ + +check: sum{i in 1..m, t in 1..kr[i]} sr[i,t] = + sum{j in 1..n, t in 1..kc[j]} sc[j,t]; +/* check that the sum of the cluster sizes in all rows is equal to the + sum of the cluster sizes in all columns */ + +param er{i in 1..m, t in 1..kr[i]} := + if t = 1 then 1 else er[i,t-1] + sr[i,t-1] + 1; +/* the smallest value of j such that row i's t-th cluster can be + placed in row i with its leftmost pixel occupying pixel j */ + +param lr{i in 1..m, t in 1..kr[i]} := + if t = kr[i] then n + 1 - sr[i,t] else lr[i,t+1] - sr[i,t] - 1; +/* the largest value of j such that row i's t-th cluster can be + placed in row i with its leftmost pixel occupying pixel j */ + +param ec{j in 1..n, t in 1..kc[j]} := + if t = 1 then 1 else ec[j,t-1] + sc[j,t-1] + 1; +/* the smallest value of i such that column j's t-th cluster can be + placed in column j with its topmost pixel occupying pixel i */ + +param lc{j in 1..n, t in 1..kc[j]} := + if t = kc[j] then m + 1 - sc[j,t] else lc[j,t+1] - sc[j,t] - 1; +/* the largest value of i such that column j's t-th cluster can be + placed in column j with its topmost pixel occupying pixel i */ + +var z{i in 1..m, j in 1..n}, binary; +/* z[i,j] = 1, if row i's j-th pixel is painted black + z[i,j] = 0, if row i's j-th pixel is painted white */ + +var y{i in 1..m, t in 1..kr[i], j in er[i,t]..lr[i,t]}, binary; +/* y[i,t,j] = 1, if row i's t-th cluster is placed in row i with its + leftmost pixel occupying pixel j + y[i,t,j] = 0, if not */ + +var x{j in 1..n, t in 1..kc[j], i in ec[j,t]..lc[j,t]}, binary; +/* x[j,t,i] = 1, if column j's t-th cluster is placed in column j with + its topmost pixel occupying pixel i + x[j,t,i] = 0, if not */ + +s.t. fa{i in 1..m, t in 1..kr[i]}: + sum{j in er[i,t]..lr[i,t]} y[i,t,j] = 1; +/* row i's t-th cluster must appear in row i exactly once */ + +s.t. fb{i in 1..m, t in 1..kr[i]-1, j in er[i,t]..lr[i,t]}: + y[i,t,j] <= sum{jp in j+sr[i,t]+1..lr[i,t+1]} y[i,t+1,jp]; +/* row i's (t+1)-th cluster must be placed to the right of its t-th + cluster */ + +s.t. fc{j in 1..n, t in 1..kc[j]}: + sum{i in ec[j,t]..lc[j,t]} x[j,t,i] = 1; +/* column j's t-th cluster must appear in column j exactly once */ + +s.t. fd{j in 1..n, t in 1..kc[j]-1, i in ec[j,t]..lc[j,t]}: + x[j,t,i] <= sum{ip in i+sc[j,t]+1..lc[j,t+1]} x[j,t+1,ip]; +/* column j's (t+1)-th cluster must be placed below its t-th cluster */ + +s.t. fe{i in 1..m, j in 1..n}: + z[i,j] <= sum{t in 1..kr[i], jp in er[i,t]..lr[i,t]: + j-sr[i,t]+1 <= jp and jp <= j} y[i,t,jp]; +/* the double coverage constraint stating that if row i's j-th pixel + is painted black, then at least one of row i's clusters must be + placed in such a way that it covers row i's j-th pixel */ + +s.t. ff{i in 1..m, j in 1..n}: + z[i,j] <= sum{t in 1..kc[j], ip in ec[j,t]..lc[j,t]: + i-sc[j,t]+1 <= ip and ip <= i} x[j,t,ip]; +/* the double coverage constraint making sure that if row i's j-th + pixel is painted black, then at least one of column j's clusters + covers it */ + +s.t. fg{i in 1..m, j in 1..n, t in 1..kr[i], jp in er[i,t]..lr[i,t]: + j-sr[i,t]+1 <= jp and jp <= j}: z[i,j] >= y[i,t,jp]; +/* the constraint to prevent white pixels from being covered by the + row clusters */ + +s.t. fh{i in 1..m, j in 1..n, t in 1..kc[j], ip in ec[j,t]..lc[j,t]: + i-sc[j,t]+1 <= ip and ip <= i}: z[i,j] >= x[j,t,ip]; +/* the constraint to prevent white pixels from being covered by the + column clusters */ + +/* this is a feasibility problem, so no objective is needed */ + +/*--------------------------------------------------------------------*/ +/* The following part is used only to check for multiple solutions. */ + +param zz{i in 1..m, j in 1..n}, binary, default 0; +/* zz[i,j] is z[i,j] for a previously found solution */ + +s.t. fz{1..1 : sum{i in 1..m, j in 1..n} zz[i,j] > 0}: + sum{i in 1..m, j in 1..n} + (if zz[i,j] then (1 - z[i,j]) else z[i,j]) >= 1; +/* the constraint to forbid finding a solution, which is identical to + the previously found one; this constraint is included in the model + only if the previously found solution specified by the parameter zz + is provided in the data section */ + +solve; + +/*--------------------------------------------------------------------*/ +/* Print solution to the standard output. */ + +for {i in 1..m} +{ printf{j in 1..n} " %s", if z[i,j] then "#" else "."; + printf "\n"; +} + +/*--------------------------------------------------------------------*/ +/* Write solution to a text file in PostScript format. */ + +param ps, symbolic, default "solution.ps"; + +printf "%%!PS-Adobe-3.0\n" > ps; +printf "%%%%Creator: GLPK (pbn.mod)\n" >> ps; +printf "%%%%BoundingBox: 0 0 %d %d\n", + 6 * (n + 2), 6 * (m + 2) >> ps; +printf "%%%%EndComments\n" >> ps; +printf "<> setpagedevice\n", + 6 * (n + 2), 6 * (m + 2) >> ps; +printf "0.1 setlinewidth\n" >> ps; +printf "/A { 2 copy 2 copy 2 copy newpath moveto exch 6 add exch line" & + "to\n" >> ps; +printf "exch 6 add exch 6 add lineto 6 add lineto closepath } bind de" & + "f\n" >> ps; +printf "/W { A stroke } def\n" >> ps; +printf "/B { A fill } def\n" >> ps; +printf {i in 1..m, j in 1..n} "%d %d %s\n", + (j - 1) * 6 + 6, (m - i) * 6 + 6, + if z[i,j] then "B" else "W" >> ps; +printf "%%%%EOF\n" >> ps; + +printf "Solution has been written to file %s\n", ps; + +/*--------------------------------------------------------------------*/ +/* Write solution to a text file in the form of MathProg data section, + which can be used later to check for multiple solutions. */ + +param dat, symbolic, default "solution.dat"; + +printf "data;\n" > dat; +printf "\n" >> dat; +printf "param zz :" >> dat; +printf {j in 1..n} " %d", j >> dat; +printf " :=\n" >> dat; +for {i in 1..m} +{ printf " %2d", i >> dat; + printf {j in 1..n} " %s", if z[i,j] then "1" else "." >> dat; + printf "\n" >> dat; +} +printf ";\n" >> dat; +printf "\n" >> dat; +printf "end;\n" >> dat; + +printf "Solution has also been written to file %s\n", dat; + +/*--------------------------------------------------------------------*/ +/* The following data correspond to the example above. */ + +data; + +param m := 10; + +param n := 10; + +param row : 1 2 3 := + 1 3 6 . + 2 1 4 . + 3 1 1 3 + 4 2 . . + 5 3 3 . + 6 1 4 . + 7 2 5 . + 8 2 5 . + 9 1 1 . + 10 3 . . +; + +param col : 1 2 3 4 := + 1 2 3 . . + 2 1 2 . . + 3 1 1 1 1 + 4 1 2 . . + 5 1 1 1 1 + 6 1 2 . . + 7 2 3 . . + 8 3 4 . . + 9 8 . . . + 10 9 . . . +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/pbn.pdf b/resources/3rdparty/glpk-4.57/examples/pbn/pbn.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8342189cf63c09063f6184a909e0d4a4379e8c80 GIT binary patch literal 43620 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

sLks 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%0AC8O*BPVKd0LQcjSrmh7K!76nm@;p4kL%9f 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 bxw!*e-Mw5bED<=^S$S9y{xQFlr4arX?90%$ literal 0 HcmV?d00001 diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/pbn.tex b/resources/3rdparty/glpk-4.57/examples/pbn/pbn.tex new file mode 100644 index 000000000..c73a441b0 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/pbn.tex @@ -0,0 +1,279 @@ +%* pbn.tex *% + +\documentclass[11pt,draft]{article} +\usepackage{amssymb} + +\begin{document} + +\title{Solving Paint-By-Numbers Puzzles with GLPK} + +\author{Andrew Makhorin {\tt}} + +\date{August 2011} + +\maketitle + +\section{Introduction$^1$} + +\footnotetext[1]{This section is based on the material from [1].} + +A {\it paint-by-numbers} puzzle consists of an $m\times n$ grid of +pixels (the {\it canvas}) together with $m+n$ {\it cluster-size +sequences}, one for each row and column. The goal is to paint the canvas +with a picture that satisfies the following constraints: + +1. Each pixel must be blank or white. + +2. If a row or column has cluster-size sequence $s_1$, $s_2$, \dots, +$s_k$, then it must contain $k$ clusters of black pixels---the first +with $s_1$ black pixels, the second with $s_2$ black pixels, and so on. + +It should be noted that ``first'' means ``leftmost'' for rows and +``topmost'' for columns, and that rows and columns need not begin or end +with black pixels. + +\subsubsection*{Example} + +\def\arraystretch{.8} + +\begin{center} +\begin{tabular}{*{3}{@{$\;\;$}c}c*{10}{@{\ }c}@{}} + & & && & &1& &1& & & & & \\ + & & && & &1& &1& & & & & \\ + & & &&2&1&1&1&1&1&2&3& & \\ + & & &&3&2&1&2&1&2&3&4&8&9\\ +\\ + &3&6&&$\blacksquare$&$\blacksquare$&$\blacksquare$&$\square$& +$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$& +$\blacksquare$&$\blacksquare$\\ + &1&4&&$\blacksquare$&$\square$&$\square$&$\square$&$\square$& +$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$\\ +1&1&3&&$\square$&$\square$&$\blacksquare$&$\square$&$\blacksquare$& +$\square$&$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$\\ + & &2&&$\square$&$\square$&$\square$&$\square$&$\square$&$\square$& +$\square$&$\square$&$\blacksquare$&$\blacksquare$\\ + &3&3&&$\square$&$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$& +$\square$&$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$\\ + &1&4&&$\blacksquare$&$\square$&$\square$&$\square$&$\square$&$\square$& +$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$\\ + &2&5&&$\blacksquare$&$\blacksquare$&$\square$&$\square$&$\square$& +$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$& +$\blacksquare$\\ + &2&5&&$\blacksquare$&$\blacksquare$&$\square$&$\square$&$\square$& +$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$& +$\blacksquare$\\ + &1&1&&$\square$&$\square$&$\square$&$\blacksquare$&$\square$&$\square$& +$\square$&$\square$&$\square$&$\blacksquare$\\ + & &3&&$\square$&$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$& +$\square$&$\square$&$\square$&$\square$&$\square$\\ +\end{tabular} +\end{center} + +\def\arraystretch{1} + +\section{Solving a puzzle} + +The Paint-By-Numbers puzzle can be formulated as a 0-1 integer +feasibility problem. The formulation used in GLPK was proposed in [1]. + +For solving puzzles there are used two components, which both are +coded in the GNU MathProg modeling language [2]: the model section and +the data section. The model section is common for all puzzles and +placed in file \verb|pbn.mod|. This file is included in the GLPK +distribution and can be found in subdirectory \verb|examples/pbn|. + +To solve a particular puzzle the user only needs to prepare the data +section, which defines input data to the puzzle. The data section for +the example puzzle from the previous section may look like follows +(here \verb|m| is the number of rows, and \verb|n| is the number of +columns): + +\begin{footnotesize} +\begin{verbatim} +data; + +param m := 10; + +param n := 10; + +param row : 1 2 3 := + 1 3 6 . + 2 1 4 . + 3 1 1 3 + 4 2 . . + 5 3 3 . + 6 1 4 . + 7 2 5 . + 8 2 5 . + 9 1 1 . + 10 3 . . +; + +param col : 1 2 3 4 := + 1 2 3 . . + 2 1 2 . . + 3 1 1 1 1 + 4 1 2 . . + 5 1 1 1 1 + 6 1 2 . . + 7 2 3 . . + 8 3 4 . . + 9 8 . . . + 10 9 . . . +; + +end; +\end{verbatim} +\end{footnotesize} + +\newpage + +Let the data section for a puzzle be placed in file \verb|foo.dat|. +Then to solve the puzzle the user should enter the following command: + +\begin{verbatim} + glpsol --minisat -m pbn.mod -d foo.dat +\end{verbatim} + +\noindent +This command invokes \verb|glpsol|, the GLPK LP/MIP stand-alone solver, +which reads the model section from file \verb|pbn.mod|, the data section +from file \verb|foo.dat|, translates them to an internal representation, +and solves the resulting 0-1 integer feasibility problem. The option +\verb|--minisat| tells \verb|glpsol| to translate the feasibility +problem to a CNF satisfiability problem and then use the MiniSat solver +[3] to solve it. + +If a solution to the puzzle has been found, that is indicated by the +message \verb|SATISFIABLE|, \verb|glpsol| prints the solution to the +standard output (terminal), writes it to file \verb|solution.ps| in the +PostScript format, and also writes it to file \verb|solution.dat| in the +form of MathProg data section, which can be used later to check for +multiple solutions, if necessary (for details see the next section). +The message \verb|UNSATISFIABLE| means that the puzzle has no solution. + +Usually the time taken to solve a puzzle of moderate size (up to 50 rows +and columns) varies from several seconds to several minutes. However, +hard or large puzzles may require much more time. + +Data sections for some example puzzles included in the GLPK distribution +can be found in subdirectory \verb|examples/pbn|. + +\section{Checking for multiple solutions} + +Sometimes the user may be interested to know if the puzzle has exactly +one (unique) solution or it has multiple solutions. To check that the +user should solve the puzzle as explained above in the previous section +and then enter the following command: + +\begin{verbatim} + glpsol --minisat -m pbn.mod -d foo.dat -d solution.dat +\end{verbatim} + +\noindent +In this case \verb|glpsol| reads an additional data section from file +\verb|solution.dat|, which contains the previously found solution, +activates an additional constraint in the model section to forbid +finding the solution specified in the additional data section, and +attempts to find another solution. The message \verb|UNSATISFIABLE| +reported by \verb|glpsol| will mean that the puzzle has a unique +solution, while the message \verb|SATISFIABLE| will mean that the puzzle +has at least two different solutions. + +\newpage + +\section{Solution times} + +The table on the next page shows solution times on a sample set of +the paint-by-numbers puzzles from the \verb|| website. +This sample set was used in the survey [4] to compare efficiency of +existing PBN solvers. + +The authors of some puzzles from the sample set have given permission +for their puzzles to be freely redistributed as long as the original +attribution and copyright statement are retained. In the table these +puzzles are marked by an asterisk (*). The files containing the +MathProg data sections for these puzzles are included in the GLPK +distribution and can be found in subdirectory \verb|examples/pbn|. + +All runs were performed on Intel Pentium 4 (CPU 3GHz, 2GB of RAM). +The C compiler used was GCC 3.4.4 with default optimization options. + +The column `Sol.Time' shows the time, in seconds, taken by the +\verb|glpsol| solver to find a solution to corresponding puzzle. The +column `Chk.Time' shows the time, in seconds, taken by \verb|glpsol| to +check for multiple solutions, i.e. either to prove that the puzzle has +a unique solution or find another solution to the puzzle. Both these +times do not include the time used to translate the MathProg model and +data sections into an internal MIP representation, but include the time +used to translate the 0-1 feasibility problem to a CNF satisfiability +problem. + +\begin{thebibliography}{10} + +\bibitem{1} +Robert A. Bosch, ``Painting by Numbers'', 2000.\\ +\verb||. + +\bibitem{2} +GLPK: Modeling Language GNU MathProg. Language Reference. (This +document is included in the GLPK distribution and can be found in +subdirectory \verb|doc|.) + +\bibitem{3} +Niklas E\'en, Niklas S\"orensson, ``An Extensible SAT-solver'', +Chalmers University of Technology, Sweden. \verb||. + +\bibitem{4} +Jan Wolter, ``Survey of Paint-by-Number Puzzle Solvers''.\\ +\verb||. + +\end{thebibliography} + +\newpage + +\begin{table} +\caption{Solution times on the sample set of puzzles from [4]} +\begin{center} +\begin{tabular}{@{}lllcrr@{}} +\hline +\multicolumn{2}{c}{Puzzle}&Size&Notes&Sol.Time, s&Chk.Time, s\\ +\hline +\#1&Dancer* &$10\times 5$&L&$<1$&$<1$\\ +\#6&Cat* &$20\times 20$&L&$<1$&$<1$\\ +\#21&Skid* &$25\times 14$&L, B&$<1$&$<1$\\ +\#27&Bucks* &$23\times 27$&B&$<1$&$<1$\\ +\#23&Edge* &$11\times 10$&&$<1$&$<1$\\ +\#2413&Smoke &$20\times 20$&&$<1$&$<1$\\ +\#16&Knot* &$34\times 34$&L&1&1\\ +\#529&Swing* &$45\times 45$&L&1&1\\ +\#65&Mum* &$40\times 34$&&1&1\\ +\#7604&DiCap &$55\times 55$&&10&10\\ +\#1694&Tragic &$50\times 45$&&3&3\\ +\#1611&Merka &$60\times 55$&B&4&4\\ +\#436&Petro* &$35\times 40$&&1&1\\ +\#4645&M\&M &$70\times 50$&B&5&6\\ +\#3541&Signed &$50\times 60$&&7&7\\ +\#803&Light* &$45\times 50$&B&1&1\\ +\#6574&Forever*&$25\times 25$&&1&1\\ +\#2040&Hot &$60\times 55$&&6&6\\ +\#6739&Karate &$40\times 40$&M&2&2\\ +\#8098&9-Dom* &$19\times 19$&&1&2\\ +\#2556&Flag &$45\times 65$&M, B&2&2\\ +\#2712&Lion &$47\times 47$&M&11&12\\ +\#10088&Marley &$63\times 52$&M&135&226\\ +\#9892&Nature &$40\times 50$&M&850&1053\\ +\hline +\end{tabular} + +\begin{tabular}{@{}lp{102mm}@{}} +*&Puzzle designer has given permission to redistribute the puzzle.\\ +L&Puzzle is line solvable. That is, it can be solved one line at a +time.\\ +B&Puzzle contains blank rows or columns.\\ +M&Puzzle has multiple solutions.\\ +\end{tabular} +\end{center} +\end{table} + +\end{document} diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/petro.dat b/resources/3rdparty/glpk-4.57/examples/pbn/petro.dat new file mode 100644 index 000000000..15ccc4a16 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/petro.dat @@ -0,0 +1,102 @@ +/* petro.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #436 from . +* Copyright (C) 2006 by Jan Wolter. Used by permission. +* +* Old Stone Face +* +* created by Jan Wolter +* Jun 17, 2006 +* +* Encoded in GNU MathProg by Andrew Makhorin . +***********************************************************************/ + +data; + +param m := 35; + +param n := 40; + +param row : 1 2 3 4 5 6 7 8 9 := + 1 2 2 . . . . . . . + 2 2 3 2 . . . . . . + 3 3 3 3 2 . . . . . + 4 3 3 3 3 . . . . . + 5 2 3 3 3 3 2 . . . + 6 3 3 3 3 3 3 . . . + 7 4 2 3 2 2 4 . . . + 8 4 2 2 2 2 3 1 . . + 9 3 1 2 2 2 3 3 . . + 10 3 2 2 2 2 2 4 . . + 11 3 2 15 2 4 . . . . + 12 5 19 4 . . . . . . + 13 6 4 3 3 . . . . . + 14 6 4 4 . . . . . . + 15 2 4 6 2 . . . . . + 16 2 2 3 3 3 2 . . . + 17 9 2 2 2 3 9 . . . + 18 10 2 2 2 2 2 10 . . + 19 4 2 3 3 2 2 3 2 5 + 20 2 5 2 4 2 . . . . + 21 5 3 2 2 5 . . . . + 22 6 3 2 3 7 . . . . + 23 6 8 9 7 . . . . . + 24 4 8 7 5 . . . . . + 25 4 . . . . . . . . + 26 2 . . . . . . . . + 27 2 . . . . . . . . + 28 14 . . . . . . . . + 29 16 . . . . . . . . + 30 3 3 . . . . . . . + 31 2 2 . . . . . . . + 32 2 2 . . . . . . . + 33 4 4 . . . . . . . + 34 16 . . . . . . . . + 35 12 . . . . . . . . +; + +param col : 1 2 3 4 5 6 7 := + 1 1 . . . . . . + 2 3 2 . . . . . + 3 2 3 3 . . . . + 4 3 3 3 . . . . + 5 3 3 3 3 . . . + 6 4 2 2 2 . . . + 7 3 3 2 3 . . . + 8 3 2 2 2 . . . + 9 3 2 6 . . . . + 10 2 9 . . . . . + 11 2 3 3 . . . . + 12 4 4 3 2 4 . . + 13 7 2 5 2 6 . . + 14 12 2 3 2 3 2 . + 15 3 1 2 2 2 3 . + 16 2 2 3 2 2 2 . + 17 6 2 6 2 2 2 . + 18 12 4 3 2 2 . . + 19 12 2 2 2 . . . + 20 2 6 2 . . . . + 21 2 6 5 2 . . . + 22 10 9 2 2 . . . + 23 12 3 3 2 2 . . + 24 6 2 2 2 2 2 2 + 25 2 2 3 2 2 2 . + 26 4 3 2 2 2 3 . + 27 7 3 3 2 3 2 . + 28 5 3 5 2 6 . . + 29 4 3 3 3 4 . . + 30 3 5 3 . . . . + 31 3 9 . . . . . + 32 4 2 6 . . . . + 33 4 2 2 2 . . . + 34 4 2 2 3 . . . + 35 3 2 2 3 . . . + 36 3 3 3 . . . . + 37 3 3 3 . . . . + 38 4 3 3 . . . . + 39 2 3 3 . . . . + 40 2 1 . . . . . +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/skid.dat b/resources/3rdparty/glpk-4.57/examples/pbn/skid.dat new file mode 100644 index 000000000..865c73b37 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/skid.dat @@ -0,0 +1,66 @@ +/* skid.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #21 from . +* Copyright (C) 2004 by Jan Wolter. Used by permission. +* +* Slippery Conditions +* +* created by Jan Wolter +* Apr 4, 2004 +* +* Encoded in GNU MathProg by Andrew Makhorin . +***********************************************************************/ + +data; + +param m := 25; + +param n := 14; + +param row : 1 2 3 := + 1 9 . . + 2 1 1 . + 3 1 1 1 + 4 1 3 1 + 5 13 . . + 6 13 . . + 7 13 . . + 8 13 . . + 9 2 2 . + 10 2 2 . + 11 . . . + 12 2 2 . + 13 2 2 . + 14 2 2 . + 15 2 2 . + 16 2 2 . + 17 2 2 . + 18 2 2 . + 19 2 2 . + 20 2 2 . + 21 2 2 . + 22 2 2 . + 23 2 2 . + 24 2 2 . + 25 2 2 . +; + +param col : 1 2 3 4 5 := + 1 2 . . . . + 2 4 6 . . . + 3 9 4 4 2 . + 4 1 6 2 6 . + 5 1 5 2 . . + 6 1 6 . . . + 7 1 5 . . . + 8 1 4 . . . + 9 1 4 . . . + 10 1 4 2 . . + 11 1 4 6 . . + 12 1 6 4 4 2 + 13 9 2 6 . . + 14 4 2 . . . +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/pbn/swing.dat b/resources/3rdparty/glpk-4.57/examples/pbn/swing.dat new file mode 100644 index 000000000..547e0dbd8 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/pbn/swing.dat @@ -0,0 +1,117 @@ +/* swing.dat */ + +/*********************************************************************** +* Web Paint-by-Number Puzzle #529 from . +* Copyright (C) 2006 by Jan Wolter. Used by permission. +* +* Swing +* +* created by Jan Wolter +* Sep 28, 2006 +* +* Encoded in GNU MathProg by Andrew Makhorin . +***********************************************************************/ + +data; + +param m := 45; + +param n := 45; + +param row : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 := + 1 7 1 1 1 1 1 . . . . . . . . + 2 3 1 3 1 4 1 4 1 5 1 5 1 2 . + 3 1 1 1 3 1 4 1 4 1 5 1 5 1 2 + 4 2 1 2 1 1 1 1 6 2 . . . . . + 5 3 30 1 5 . . . . . . . . . . + 6 1 5 8 1 1 7 1 1 3 . . . . . + 7 3 4 8 1 5 1 2 . . . . . . . + 8 3 20 6 6 . . . . . . . . . . + 9 3 3 7 2 5 1 . . . . . . . . + 10 3 3 1 1 9 1 1 5 6 . . . . . + 11 2 3 8 1 3 4 2 . . . . . . . + 12 5 3 1 10 4 5 2 . . . . . . . + 13 1 2 3 8 4 6 . . . . . . . . + 14 2 2 3 11 10 . . . . . . . . . + 15 2 2 3 10 7 . . . . . . . . . + 16 2 3 1 7 12 2 . . . . . . . . + 17 2 3 1 4 11 2 . . . . . . . . + 18 4 1 2 1 11 2 . . . . . . . . + 19 9 1 2 9 . . . . . . . . . . + 20 6 2 1 4 11 . . . . . . . . . + 21 2 5 1 2 6 6 . . . . . . . . + 22 6 2 4 8 4 . . . . . . . . . + 23 4 2 16 1 . . . . . . . . . . + 24 2 2 15 2 . . . . . . . . . . + 25 3 2 15 4 . . . . . . . . . . + 26 3 3 13 4 . . . . . . . . . . + 27 4 12 9 . . . . . . . . . . . + 28 1 9 10 . . . . . . . . . . . + 29 2 1 17 7 2 . . . . . . . . . + 30 2 2 8 3 8 2 . . . . . . . . + 31 2 3 6 3 8 2 . . . . . . . . + 32 2 4 5 4 7 2 . . . . . . . . + 33 2 5 5 4 6 . . . . . . . . . + 34 4 4 5 4 9 . . . . . . . . . + 35 1 4 6 4 4 . . . . . . . . . + 36 4 3 6 4 3 2 . . . . . . . . + 37 2 1 2 7 4 4 2 . . . . . . . + 38 2 2 2 9 5 5 2 . . . . . . . + 39 2 2 2 10 6 6 . . . . . . . . + 40 3 2 1 9 18 . . . . . . . . . + 41 8 4 23 . . . . . . . . . . . + 42 1 2 1 2 2 1 1 1 2 . . . . . + 43 2 1 4 2 1 4 1 5 1 3 1 2 . . + 44 2 1 5 4 4 1 5 1 3 1 2 . . . + 45 1 10 1 1 1 . . . . . . . . . +; + +param col : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 := + 1 7 1 1 1 1 1 . . . . . . . . + 2 2 2 4 1 4 1 5 1 4 1 4 1 2 . + 3 3 1 4 1 4 1 14 4 1 2 . . . . + 4 1 1 5 1 2 3 4 1 . . . . . . + 5 3 13 1 10 . . . . . . . . . . + 6 1 9 4 . . . . . . . . . . . + 7 6 7 2 2 . . . . . . . . . . + 8 8 4 1 4 . . . . . . . . . . + 9 2 8 3 2 5 3 . . . . . . . . + 10 10 1 3 7 2 . . . . . . . . . + 11 8 6 2 8 1 2 . . . . . . . . + 12 1 1 2 2 8 1 1 . . . . . . . + 13 2 1 1 1 2 1 3 1 3 3 1 . . . + 14 2 1 1 1 5 4 2 1 . . . . . . + 15 2 1 1 1 1 7 2 1 . . . . . . + 16 2 1 1 2 9 1 2 1 . . . . . . + 17 4 6 12 1 3 . . . . . . . . . + 18 16 13 3 2 . . . . . . . . . . + 19 12 21 2 . . . . . . . . . . . + 20 2 13 23 . . . . . . . . . . . + 21 2 14 19 . . . . . . . . . . . + 22 2 14 20 2 . . . . . . . . . . + 23 2 13 7 2 8 2 . . . . . . . . + 24 12 8 1 7 2 . . . . . . . . . + 25 5 1 1 1 2 8 1 5 2 . . . . . + 26 2 1 1 1 9 1 1 4 . . . . . . + 27 2 1 1 1 6 1 3 5 . . . . . . + 28 2 2 1 5 6 2 . . . . . . . . + 29 2 1 3 1 3 7 3 2 . . . . . . + 30 2 3 2 1 1 2 4 4 2 . . . . . + 31 2 2 1 1 2 3 1 8 2 . . . . . + 32 9 3 1 7 2 . . . . . . . . . + 33 12 4 1 6 2 . . . . . . . . . + 34 7 4 1 2 5 . . . . . . . . . + 35 2 6 6 5 6 . . . . . . . . . + 36 8 8 6 3 . . . . . . . . . . + 37 3 10 8 4 2 . . . . . . . . . + 38 5 11 9 5 2 . . . . . . . . . + 39 3 1 12 16 2 . . . . . . . . . + 40 3 1 12 16 . . . . . . . . . . + 41 5 2 13 21 . . . . . . . . . . + 42 6 1 3 3 1 1 . . . . . . . . + 43 5 1 3 1 3 1 1 2 1 4 1 3 1 3 + 44 5 1 3 1 3 1 4 1 4 1 3 1 3 . + 45 1 1 1 1 1 1 . . . . . . . . +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/plan.lp b/resources/3rdparty/glpk-4.57/examples/plan.lp new file mode 100644 index 000000000..cab649449 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/plan.lp @@ -0,0 +1,39 @@ +\* plan.lp *\ + +Minimize + value: .03 bin1 + .08 bin2 + .17 bin3 + .12 bin4 + .15 bin5 + + .21 alum + .38 silicon + +Subject To + yield: bin1 + bin2 + bin3 + bin4 + bin5 + + alum + silicon = 2000 + + fe: .15 bin1 + .04 bin2 + .02 bin3 + .04 bin4 + .02 bin5 + + .01 alum + .03 silicon <= 60 + + cu: .03 bin1 + .05 bin2 + .08 bin3 + .02 bin4 + .06 bin5 + + .01 alum <= 100 + + mn: .02 bin1 + .04 bin2 + .01 bin3 + .02 bin4 + .02 bin5 <= 40 + + mg: .02 bin1 + .03 bin2 + .01 bin5 <= 30 + + al: .70 bin1 + .75 bin2 + .80 bin3 + .75 bin4 + .80 bin5 + + .97 alum >= 1500 + + si1: .02 bin1 + .06 bin2 + .08 bin3 + .12 bin4 + .02 bin5 + + .01 alum + .97 silicon >= 250 + + si2: .02 bin1 + .06 bin2 + .08 bin3 + .12 bin4 + .02 bin5 + + .01 alum + .97 silicon <= 300 + +Bounds + bin1 <= 200 + bin2 <= 2500 + 400 <= bin3 <= 800 + 100 <= bin4 <= 700 + bin5 <= 1500 + +End + +\* eof *\ diff --git a/resources/3rdparty/glpk-4.57/examples/plan.mod b/resources/3rdparty/glpk-4.57/examples/plan.mod new file mode 100644 index 000000000..effe8383c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/plan.mod @@ -0,0 +1,39 @@ +/* plan.mod */ + +var bin1, >= 0, <= 200; +var bin2, >= 0, <= 2500; +var bin3, >= 400, <= 800; +var bin4, >= 100, <= 700; +var bin5, >= 0, <= 1500; +var alum, >= 0; +var silicon, >= 0; + +minimize + +value: .03 * bin1 + .08 * bin2 + .17 * bin3 + .12 * bin4 + .15 * bin5 + + .21 * alum + .38 * silicon; + +subject to + +yield: bin1 + bin2 + bin3 + bin4 + bin5 + alum + silicon = 2000; + +fe: .15 * bin1 + .04 * bin2 + .02 * bin3 + .04 * bin4 + .02 * bin5 + + .01 * alum + .03 * silicon <= 60; + +cu: .03 * bin1 + .05 * bin2 + .08 * bin3 + .02 * bin4 + .06 * bin5 + + .01 * alum <= 100; + +mn: .02 * bin1 + .04 * bin2 + .01 * bin3 + .02 * bin4 + .02 * bin5 + <= 40; + +mg: .02 * bin1 + .03 * bin2 + .01 * bin5 <= 30; + +al: .70 * bin1 + .75 * bin2 + .80 * bin3 + .75 * bin4 + .80 * bin5 + + .97 * alum >= 1500; + +si: 250 <= .02 * bin1 + .06 * bin2 + .08 * bin3 + .12 * bin4 + + .02 * bin5 + .01 * alum + .97 * silicon <= 300; + +end; + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/plan.mps b/resources/3rdparty/glpk-4.57/examples/plan.mps new file mode 100644 index 000000000..b6bb09458 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/plan.mps @@ -0,0 +1,54 @@ +*000000001111111111222222222233333333334444444444555555555566 +*234567890123456789012345678901234567890123456789012345678901 +NAME PLAN +ROWS + N VALUE + E YIELD + L FE + L CU + L MN + L MG + G AL + L SI +COLUMNS + BIN1 VALUE .03000 YIELD 1.00000 + FE .15000 CU .03000 + MN .02000 MG .02000 + AL .70000 SI .02000 + BIN2 VALUE .08000 YIELD 1.00000 + FE .04000 CU .05000 + MN .04000 MG .03000 + AL .75000 SI .06000 + BIN3 VALUE .17000 YIELD 1.00000 + FE .02000 CU .08000 + MN .01000 AL .80000 + SI .08000 + BIN4 VALUE .12000 YIELD 1.00000 + FE .04000 CU .02000 + MN .02000 AL .75000 + SI .12000 + BIN5 VALUE .15000 YIELD 1.00000 + FE .02000 CU .06000 + MN .02000 MG .01000 + AL .80000 SI .02000 + ALUM VALUE .21000 YIELD 1.00000 + FE .01000 CU .01000 + AL .97000 SI .01000 + SILICON VALUE .38000 YIELD 1.00000 + FE .03000 SI .97000 +RHS + RHS1 YIELD 2000.00000 FE 60.00000 + CU 100.00000 MN 40.00000 + SI 300.00000 + MG 30.00000 AL 1500.00000 +RANGES + RNG1 SI 50.00000 +BOUNDS + UP BND1 BIN1 200.00000 + UP BIN2 2500.00000 + LO BIN3 400.00000 + UP BIN3 800.00000 + LO BIN4 100.00000 + UP BIN4 700.00000 + UP BIN5 1500.00000 +ENDATA diff --git a/resources/3rdparty/glpk-4.57/examples/prod.mod b/resources/3rdparty/glpk-4.57/examples/prod.mod new file mode 100644 index 000000000..aa793f76e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/prod.mod @@ -0,0 +1,331 @@ +# PROD, a multiperiod production model +# +# References: +# Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language +# for Mathematical Programming." Management Science 36 (1990) 519-554. + +### PRODUCTION SETS AND PARAMETERS ### + +set prd 'products'; # Members of the product group + +param pt 'production time' {prd} > 0; + + # Crew-hours to produce 1000 units + +param pc 'production cost' {prd} > 0; + + # Nominal production cost per 1000, used + # to compute inventory and shortage costs + +### TIME PERIOD SETS AND PARAMETERS ### + +param first > 0 integer; + # Index of first production period to be modeled + +param last > first integer; + + # Index of last production period to be modeled + +set time 'planning horizon' := first..last; + +### EMPLOYMENT PARAMETERS ### + +param cs 'crew size' > 0 integer; + + # Workers per crew + +param sl 'shift length' > 0; + + # Regular-time hours per shift + +param rtr 'regular time rate' > 0; + + # Wage per hour for regular-time labor + +param otr 'overtime rate' > rtr; + + # Wage per hour for overtime labor + +param iw 'initial workforce' >= 0 integer; + + # Crews employed at start of first period + +param dpp 'days per period' {time} > 0; + + # Regular working days in a production period + +param ol 'overtime limit' {time} >= 0; + + # Maximum crew-hours of overtime in a period + +param cmin 'crew minimum' {time} >= 0; + + # Lower limit on average employment in a period + +param cmax 'crew maximum' {t in time} >= cmin[t]; + + # Upper limit on average employment in a period + +param hc 'hiring cost' {time} >= 0; + + # Penalty cost of hiring a crew + +param lc 'layoff cost' {time} >= 0; + + # Penalty cost of laying off a crew + +### DEMAND PARAMETERS ### + +param dem 'demand' {prd,first..last+1} >= 0; + + # Requirements (in 1000s) + # to be met from current production and inventory + +param pro 'promoted' {prd,first..last+1} logical; + + # true if product will be the subject + # of a special promotion in the period + +### INVENTORY AND SHORTAGE PARAMETERS ### + +param rir 'regular inventory ratio' >= 0; + + # Proportion of non-promoted demand + # that must be in inventory the previous period + +param pir 'promotional inventory ratio' >= 0; + + # Proportion of promoted demand + # that must be in inventory the previous period + +param life 'inventory lifetime' > 0 integer; + + # Upper limit on number of periods that + # any product may sit in inventory + +param cri 'inventory cost ratio' {prd} > 0; + + # Inventory cost per 1000 units is + # cri times nominal production cost + +param crs 'shortage cost ratio' {prd} > 0; + + # Shortage cost per 1000 units is + # crs times nominal production cost + +param iinv 'initial inventory' {prd} >= 0; + + # Inventory at start of first period; age unknown + +param iil 'initial inventory left' {p in prd, t in time} + := iinv[p] less sum {v in first..t} dem[p,v]; + + # Initial inventory still available for allocation + # at end of period t + +param minv 'minimum inventory' {p in prd, t in time} + := dem[p,t+1] * (if pro[p,t+1] then pir else rir); + + # Lower limit on inventory at end of period t + +### VARIABLES ### + +var Crews{first-1..last} >= 0; + + # Average number of crews employed in each period + +var Hire{time} >= 0; # Crews hired from previous to current period + +var Layoff{time} >= 0; # Crews laid off from previous to current period + +var Rprd 'regular production' {prd,time} >= 0; + + # Production using regular-time labor, in 1000s + +var Oprd 'overtime production' {prd,time} >= 0; + + # Production using overtime labor, in 1000s + +var Inv 'inventory' {prd,time,1..life} >= 0; + + # Inv[p,t,a] is the amount of product p that is + # a periods old -- produced in period (t+1)-a -- + # and still in storage at the end of period t + +var Short 'shortage' {prd,time} >= 0; + + # Accumulated unsatisfied demand at the end of period t + +### OBJECTIVE ### + +minimize cost: + + sum {t in time} rtr * sl * dpp[t] * cs * Crews[t] + + sum {t in time} hc[t] * Hire[t] + + sum {t in time} lc[t] * Layoff[t] + + sum {t in time, p in prd} otr * cs * pt[p] * Oprd[p,t] + + sum {t in time, p in prd, a in 1..life} cri[p] * pc[p] * Inv[p,t,a] + + sum {t in time, p in prd} crs[p] * pc[p] * Short[p,t]; + + # Full regular wages for all crews employed, plus + # penalties for hiring and layoffs, plus + # wages for any overtime worked, plus + # inventory and shortage costs + + # (All other production costs are assumed + # to depend on initial inventory and on demands, + # and so are not included explicitly.) + +### CONSTRAINTS ### + +rlim 'regular-time limit' {t in time}: + + sum {p in prd} pt[p] * Rprd[p,t] <= sl * dpp[t] * Crews[t]; + + # Hours needed to accomplish all regular-time + # production in a period must not exceed + # hours available on all shifts + +olim 'overtime limit' {t in time}: + + sum {p in prd} pt[p] * Oprd[p,t] <= ol[t]; + + # Hours needed to accomplish all overtime + # production in a period must not exceed + # the specified overtime limit + +empl0 'initial crew level': Crews[first-1] = iw; + + # Use given initial workforce + +empl 'crew levels' {t in time}: Crews[t] = Crews[t-1] + Hire[t] - Layoff[t]; + + # Workforce changes by hiring or layoffs + +emplbnd 'crew limits' {t in time}: cmin[t] <= Crews[t] <= cmax[t]; + + # Workforce must remain within specified bounds + +dreq1 'first demand requirement' {p in prd}: + + Rprd[p,first] + Oprd[p,first] + Short[p,first] + - Inv[p,first,1] = dem[p,first] less iinv[p]; + +dreq 'demand requirements' {p in prd, t in first+1..last}: + + Rprd[p,t] + Oprd[p,t] + Short[p,t] - Short[p,t-1] + + sum {a in 1..life} (Inv[p,t-1,a] - Inv[p,t,a]) + = dem[p,t] less iil[p,t-1]; + + # Production plus increase in shortage plus + # decrease in inventory must equal demand + +ireq 'inventory requirements' {p in prd, t in time}: + + sum {a in 1..life} Inv[p,t,a] + iil[p,t] >= minv[p,t]; + + # Inventory in storage at end of period t + # must meet specified minimum + +izero 'impossible inventories' {p in prd, v in 1..life-1, a in v+1..life}: + + Inv[p,first+v-1,a] = 0; + + # In the vth period (starting from first) + # no inventory may be more than v periods old + # (initial inventories are handled separately) + +ilim1 'new-inventory limits' {p in prd, t in time}: + + Inv[p,t,1] <= Rprd[p,t] + Oprd[p,t]; + + # New inventory cannot exceed + # production in the most recent period + +ilim 'inventory limits' {p in prd, t in first+1..last, a in 2..life}: + + Inv[p,t,a] <= Inv[p,t-1,a-1]; + + # Inventory left from period (t+1)-p + # can only decrease as time goes on + +### DATA ### + +data; + +set prd := 18REG 24REG 24PRO ; + +param first := 1 ; +param last := 13 ; +param life := 2 ; + +param cs := 18 ; +param sl := 8 ; +param iw := 8 ; + +param rtr := 16.00 ; +param otr := 43.85 ; +param rir := 0.75 ; +param pir := 0.80 ; + +param : pt pc cri crs iinv := + + 18REG 1.194 2304. 0.015 1.100 82.0 + 24REG 1.509 2920. 0.015 1.100 792.2 + 24PRO 1.509 2910. 0.015 1.100 0.0 ; + +param : dpp ol cmin cmax hc lc := + + 1 19.5 96.0 0.0 8.0 7500 7500 + 2 19.0 96.0 0.0 8.0 7500 7500 + 3 20.0 96.0 0.0 8.0 7500 7500 + 4 19.0 96.0 0.0 8.0 7500 7500 + 5 19.5 96.0 0.0 8.0 15000 15000 + 6 19.0 96.0 0.0 8.0 15000 15000 + 7 19.0 96.0 0.0 8.0 15000 15000 + 8 20.0 96.0 0.0 8.0 15000 15000 + 9 19.0 96.0 0.0 8.0 15000 15000 + 10 20.0 96.0 0.0 8.0 15000 15000 + 11 20.0 96.0 0.0 8.0 7500 7500 + 12 18.0 96.0 0.0 8.0 7500 7500 + 13 18.0 96.0 0.0 8.0 7500 7500 ; + +param dem (tr) : + + 18REG 24REG 24PRO := + + 1 63.8 1212.0 0.0 + 2 76.0 306.2 0.0 + 3 88.4 319.0 0.0 + 4 913.8 208.4 0.0 + 5 115.0 298.0 0.0 + 6 133.8 328.2 0.0 + 7 79.6 959.6 0.0 + 8 111.0 257.6 0.0 + 9 121.6 335.6 0.0 + 10 470.0 118.0 1102.0 + 11 78.4 284.8 0.0 + 12 99.4 970.0 0.0 + 13 140.4 343.8 0.0 + 14 63.8 1212.0 0.0 ; + +param pro (tr) : + + 18REG 24REG 24PRO := + + 1 0 1 0 + 2 0 0 0 + 3 0 0 0 + 4 1 0 0 + 5 0 0 0 + 6 0 0 0 + 7 0 1 0 + 8 0 0 0 + 9 0 0 0 + 10 1 0 1 + 11 0 0 0 + 12 0 0 0 + 13 0 1 0 + 14 0 1 0 ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/qfit.mod b/resources/3rdparty/glpk-4.57/examples/qfit.mod new file mode 100644 index 000000000..f168c4b52 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/qfit.mod @@ -0,0 +1,49 @@ +/*Quadratic Curve Fitting Solution + + Find a plausable quadratic fit to a sample of points + + Nigel_Galloway@operamail.com + February 1st., 2009 +*/ +set Sample; +param Sx {z in Sample}; +param Sy {z in Sample}; + +var a; +var b; +var c; + +equalz1 :sum{z in Sample} a*Sx[z]*Sx[z]*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z]*Sx[z]*Sx[z] + sum{z in Sample} c*Sx[z]*Sx[z] = sum{z in Sample} Sy[z]*Sx[z]*Sx[z]; +equalz2 :sum{z in Sample} a*Sx[z]*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z]*Sx[z] + sum{z in Sample} c*Sx[z] = sum{z in Sample} Sy[z]*Sx[z]; +equalz3 :sum{z in Sample} a*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z] + sum{z in Sample} c = sum{z in Sample} Sy[z]; + +solve; + +printf "\nbest quadratic fit is:\n\ty = %f %s %fx %s %fx^2\n\n", c, if b < 0 then "-" else "+", abs(b), if a < 0 then "-" else "+", abs(a); + +data; + +param: +Sample: Sx Sy := + 1 0 1 + 2 0.5 0.9 + 3 1 0.7 + 4 1.5 1.5 + 5 1.9 2 + 6 2.5 2.4 + 7 3 3.2 + 8 3.5 2 + 9 4 2.7 + 10 4.5 3.5 + 11 5 1 + 12 5.5 4 + 13 6 3.6 + 14 6.6 2.7 + 15 7 5.7 + 16 7.6 4.6 + 17 8.5 6 + 18 9 6.8 + 19 10 7.3 +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/queens.mod b/resources/3rdparty/glpk-4.57/examples/queens.mod new file mode 100644 index 000000000..3f446ce4c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/queens.mod @@ -0,0 +1,41 @@ +/* QUEENS, a classic combinatorial optimization problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* The Queens Problem is to place as many queens as possible on the 8x8 + (or more generally, nxn) chess board in a way that they do not fight + each other. This problem is probably as old as the chess game itself, + and thus its origin is not known, but it is known that Gauss studied + this problem. */ + +param n, integer, > 0, default 8; +/* size of the chess board */ + +var x{1..n, 1..n}, binary; +/* x[i,j] = 1 means that a queen is placed in square [i,j] */ + +s.t. a{i in 1..n}: sum{j in 1..n} x[i,j] <= 1; +/* at most one queen can be placed in each row */ + +s.t. b{j in 1..n}: sum{i in 1..n} x[i,j] <= 1; +/* at most one queen can be placed in each column */ + +s.t. c{k in 2-n..n-2}: sum{i in 1..n, j in 1..n: i-j == k} x[i,j] <= 1; +/* at most one queen can be placed in each "\"-diagonal */ + +s.t. d{k in 3..n+n-1}: sum{i in 1..n, j in 1..n: i+j == k} x[i,j] <= 1; +/* at most one queen can be placed in each "/"-diagonal */ + +maximize obj: sum{i in 1..n, j in 1..n} x[i,j]; +/* objective is to place as many queens as possible */ + +/* solve the problem */ +solve; + +/* and print its optimal solution */ +for {i in 1..n} +{ for {j in 1..n} printf " %s", if x[i,j] then "Q" else "."; + printf("\n"); +} + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/samp1.mps b/resources/3rdparty/glpk-4.57/examples/samp1.mps new file mode 100644 index 000000000..dd60d1843 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/samp1.mps @@ -0,0 +1,29 @@ +NAME SAMP1 +ROWS + N Z + G R1 + G R2 + G R3 +COLUMNS + X1 R1 2.0 R2 1.0 + X1 R3 5.0 Z 3.0 + MARK0001 'MARKER' 'INTORG' + X2 R1 -1.0 R2 -1.0 + X2 R3 3.0 Z 7.0 + X3 R1 1.0 R2 -6.0 + X3 Z -1.0 + MARK0002 'MARKER' 'INTEND' + X4 R1 -1.0 R2 4.0 + X4 R3 1.0 Z 1.0 +RHS + RHS1 R1 1.0 + RHS1 R2 8.0 + RHS1 R3 5.0 +BOUNDS + UP BND1 X1 4.0 + LO BND1 X2 2.0 + UP BND1 X2 5.0 + UP BND1 X3 1.0 + LO BND1 X4 3.0 + UP BND1 X4 8.0 +ENDATA diff --git a/resources/3rdparty/glpk-4.57/examples/samp2.mps b/resources/3rdparty/glpk-4.57/examples/samp2.mps new file mode 100644 index 000000000..d2da1a31d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/samp2.mps @@ -0,0 +1,27 @@ +NAME SAMP2 +ROWS + N Z + G R1 + G R2 + G R3 +COLUMNS + X1 R1 2.0 R2 1.0 + X1 R3 5.0 Z 3.0 + X2 R1 -1.0 R2 -1.0 + X2 R3 3.0 Z 7.0 + X3 R1 1.0 R2 -6.0 + X3 Z -1.0 + X4 R1 -1.0 R2 4.0 + X4 R3 1.0 Z 1.0 +RHS + RHS1 R1 1.0 + RHS1 R2 8.0 + RHS1 R3 5.0 +BOUNDS + UP BND1 X1 4.0 + LO BND1 X2 2.0 + UI BND1 X2 5.0 + BV BND1 X3 + LO BND1 X4 3.0 + UP BND1 X4 8.0 +ENDATA diff --git a/resources/3rdparty/glpk-4.57/examples/sample.asn b/resources/3rdparty/glpk-4.57/examples/sample.asn new file mode 100644 index 000000000..edb0aafd9 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sample.asn @@ -0,0 +1,40 @@ +c sample.asn +c +c This is an example of the assignment problem data +c in DIMACS format. +c +p asn 17 22 +c +n 1 +n 2 +n 3 +n 4 +n 5 +n 6 +n 7 +n 8 +c +a 1 9 13 +a 1 10 21 +a 1 12 20 +a 2 10 12 +a 2 12 8 +a 2 13 26 +a 3 11 22 +a 3 13 11 +a 4 9 12 +a 4 12 36 +a 4 14 25 +a 5 11 41 +a 5 12 40 +a 5 13 11 +a 5 14 4 +a 5 15 8 +a 5 16 35 +a 5 17 32 +a 6 9 13 +a 7 10 19 +a 8 10 39 +a 8 11 15 +c +c eof diff --git a/resources/3rdparty/glpk-4.57/examples/sample.c b/resources/3rdparty/glpk-4.57/examples/sample.c new file mode 100644 index 000000000..468a6a354 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sample.c @@ -0,0 +1,52 @@ +/* sample.c */ + +#include +#include +#include + +int main(void) +{ glp_prob *lp; + int ia[1+1000], ja[1+1000]; + double ar[1+1000], z, x1, x2, x3; +s1: lp = glp_create_prob(); +s2: glp_set_prob_name(lp, "sample"); +s3: glp_set_obj_dir(lp, GLP_MAX); +s4: glp_add_rows(lp, 3); +s5: glp_set_row_name(lp, 1, "p"); +s6: glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 100.0); +s7: glp_set_row_name(lp, 2, "q"); +s8: glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 600.0); +s9: glp_set_row_name(lp, 3, "r"); +s10: glp_set_row_bnds(lp, 3, GLP_UP, 0.0, 300.0); +s11: glp_add_cols(lp, 3); +s12: glp_set_col_name(lp, 1, "x1"); +s13: glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0); +s14: glp_set_obj_coef(lp, 1, 10.0); +s15: glp_set_col_name(lp, 2, "x2"); +s16: glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0); +s17: glp_set_obj_coef(lp, 2, 6.0); +s18: glp_set_col_name(lp, 3, "x3"); +s19: glp_set_col_bnds(lp, 3, GLP_LO, 0.0, 0.0); +s20: glp_set_obj_coef(lp, 3, 4.0); +s21: ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */ +s22: ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */ +s23: ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */ +s24: ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */ +s25: ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */ +s26: ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */ +s27: ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */ +s28: ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */ +s29: ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */ +s30: glp_load_matrix(lp, 9, ia, ja, ar); +s31: glp_simplex(lp, NULL); +s32: z = glp_get_obj_val(lp); +s33: x1 = glp_get_col_prim(lp, 1); +s34: x2 = glp_get_col_prim(lp, 2); +s35: x3 = glp_get_col_prim(lp, 3); +s36: printf("\nz = %g; x1 = %g; x2 = %g; x3 = %g\n", + z, x1, x2, x3); +s37: glp_delete_prob(lp); + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/sample.clq b/resources/3rdparty/glpk-4.57/examples/sample.clq new file mode 100644 index 000000000..741f71272 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sample.clq @@ -0,0 +1,30 @@ +c sample.clq +c +c This is an example of the Maximum Weight Clique +c Problem in DIMACS clique/coloring format. +c +p edge 8 16 +n 1 3 +n 2 4 +n 3 8 +n 5 5 +n 6 2 +n 8 3 +e 1 4 +e 1 5 +e 1 6 +e 1 8 +e 2 3 +e 2 6 +e 2 7 +e 2 8 +e 3 4 +e 3 6 +e 3 7 +e 4 5 +e 4 8 +e 5 7 +e 5 8 +e 6 7 +c +c eof diff --git a/resources/3rdparty/glpk-4.57/examples/sample.cnf b/resources/3rdparty/glpk-4.57/examples/sample.cnf new file mode 100644 index 000000000..508f15046 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sample.cnf @@ -0,0 +1,12 @@ +c sample.cnf +c +c This is an example of the CNF-SAT problem data +c in DIMACS format. +c +p cnf 4 3 +1 2 0 +-4 3 +-2 0 +-1 4 0 +c +c eof diff --git a/resources/3rdparty/glpk-4.57/examples/sample.col b/resources/3rdparty/glpk-4.57/examples/sample.col new file mode 100644 index 000000000..132f6e578 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sample.col @@ -0,0 +1,30 @@ +c sample.col +c +c This is an example of the vertex coloring problem data +c in DIMACS format. +c +p edge 10 21 +c +e 1 2 +e 1 6 +e 1 7 +e 1 10 +e 2 3 +e 2 7 +e 2 8 +e 3 4 +e 3 8 +e 4 5 +e 4 8 +e 4 9 +e 5 6 +e 5 9 +e 5 10 +e 6 10 +e 7 8 +e 7 10 +e 8 9 +e 8 10 +e 9 10 +c +c eof diff --git a/resources/3rdparty/glpk-4.57/examples/sample.max b/resources/3rdparty/glpk-4.57/examples/sample.max new file mode 100644 index 000000000..6b8042297 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sample.max @@ -0,0 +1,26 @@ +c sample.max +c +c This is an example of the maximum flow problem data +c in DIMACS format. +c +p max 9 14 +c +n 1 s +n 9 t +c +a 1 2 14 +a 1 4 23 +a 2 3 10 +a 2 4 9 +a 3 5 12 +a 3 8 18 +a 4 5 26 +a 5 2 11 +a 5 6 25 +a 5 7 4 +a 6 7 7 +a 6 8 8 +a 7 9 15 +a 8 9 20 +c +c eof diff --git a/resources/3rdparty/glpk-4.57/examples/sample.min b/resources/3rdparty/glpk-4.57/examples/sample.min new file mode 100644 index 000000000..5ebf58b1f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sample.min @@ -0,0 +1,26 @@ +c sample.min +c +c This is an example of the minimum cost flow problem data +c in DIMACS format. +c +p min 9 14 +c +n 1 20 +n 9 -20 +c +a 1 2 0 14 0 +a 1 4 0 23 0 +a 2 3 0 10 2 +a 2 4 0 9 3 +a 3 5 2 12 1 +a 3 8 0 18 0 +a 4 5 0 26 0 +a 5 2 0 11 1 +a 5 6 0 25 5 +a 5 7 0 4 7 +a 6 7 0 7 0 +a 6 8 4 8 0 +a 7 9 0 15 3 +a 8 9 0 20 9 +c +c eof diff --git a/resources/3rdparty/glpk-4.57/examples/sat.mod b/resources/3rdparty/glpk-4.57/examples/sat.mod new file mode 100644 index 000000000..84ba95249 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sat.mod @@ -0,0 +1,201 @@ +/* SAT, Satisfiability Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +param m, integer, > 0; +/* number of clauses */ + +param n, integer, > 0; +/* number of variables */ + +set C{1..m}; +/* clauses; each clause C[i], i = 1, ..., m, is disjunction of some + variables or their negations; in the data section each clause is + coded as a set of indices of corresponding variables, where negative + indices mean negation; for example, the clause (x3 or not x7 or x11) + is coded as the set { 3, -7, 11 } */ + +var x{1..n}, binary; +/* main variables */ + +/* To solve the satisfiability problem means to determine all variables + x[j] such that conjunction of all clauses C[1] and ... and C[m] takes + on the value true, i.e. all clauses are satisfied. + + Let the clause C[i] be (t or t' or ... or t''), where t, t', ..., t'' + are either variables or their negations. The condition of satisfying + C[i] can be most naturally written as: + + t + t' + ... + t'' >= 1, (1) + + where t, t', t'' have to be replaced by either x[j] or (1 - x[j]). + The formulation (1) leads to the mip problem with no objective, i.e. + to a feasibility problem. + + Another, more practical way is to write the condition for C[i] as: + + t + t' + ... + t'' + y[i] >= 1, (2) + + where y[i] is an auxiliary binary variable, and minimize the sum of + y[i]. If the sum is zero, all y[i] are also zero, and therefore all + clauses are satisfied. If the sum is minimal but non-zero, its value + shows the number of clauses which cannot be satisfied. */ + +var y{1..m}, binary, >= 0; +/* auxiliary variables */ + +s.t. c{i in 1..m}: + sum{j in C[i]} (if j > 0 then x[j] else (1 - x[-j])) + y[i] >= 1; +/* the condition (2) */ + +minimize unsat: sum{i in 1..m} y[i]; +/* number of unsatisfied clauses */ + +data; + +/* These data correspond to the instance hole6 (pigeon hole problem for + 6 holes) from SATLIB, the Satisfiability Library, which is part of + the collection at the Forschungsinstitut fuer anwendungsorientierte + Wissensverarbeitung in Ulm Germany */ + +/* The optimal solution is 1 (one clause cannot be satisfied) */ + +param m := 133; + +param n := 42; + +set C[1] := -1 -7; +set C[2] := -1 -13; +set C[3] := -1 -19; +set C[4] := -1 -25; +set C[5] := -1 -31; +set C[6] := -1 -37; +set C[7] := -7 -13; +set C[8] := -7 -19; +set C[9] := -7 -25; +set C[10] := -7 -31; +set C[11] := -7 -37; +set C[12] := -13 -19; +set C[13] := -13 -25; +set C[14] := -13 -31; +set C[15] := -13 -37; +set C[16] := -19 -25; +set C[17] := -19 -31; +set C[18] := -19 -37; +set C[19] := -25 -31; +set C[20] := -25 -37; +set C[21] := -31 -37; +set C[22] := -2 -8; +set C[23] := -2 -14; +set C[24] := -2 -20; +set C[25] := -2 -26; +set C[26] := -2 -32; +set C[27] := -2 -38; +set C[28] := -8 -14; +set C[29] := -8 -20; +set C[30] := -8 -26; +set C[31] := -8 -32; +set C[32] := -8 -38; +set C[33] := -14 -20; +set C[34] := -14 -26; +set C[35] := -14 -32; +set C[36] := -14 -38; +set C[37] := -20 -26; +set C[38] := -20 -32; +set C[39] := -20 -38; +set C[40] := -26 -32; +set C[41] := -26 -38; +set C[42] := -32 -38; +set C[43] := -3 -9; +set C[44] := -3 -15; +set C[45] := -3 -21; +set C[46] := -3 -27; +set C[47] := -3 -33; +set C[48] := -3 -39; +set C[49] := -9 -15; +set C[50] := -9 -21; +set C[51] := -9 -27; +set C[52] := -9 -33; +set C[53] := -9 -39; +set C[54] := -15 -21; +set C[55] := -15 -27; +set C[56] := -15 -33; +set C[57] := -15 -39; +set C[58] := -21 -27; +set C[59] := -21 -33; +set C[60] := -21 -39; +set C[61] := -27 -33; +set C[62] := -27 -39; +set C[63] := -33 -39; +set C[64] := -4 -10; +set C[65] := -4 -16; +set C[66] := -4 -22; +set C[67] := -4 -28; +set C[68] := -4 -34; +set C[69] := -4 -40; +set C[70] := -10 -16; +set C[71] := -10 -22; +set C[72] := -10 -28; +set C[73] := -10 -34; +set C[74] := -10 -40; +set C[75] := -16 -22; +set C[76] := -16 -28; +set C[77] := -16 -34; +set C[78] := -16 -40; +set C[79] := -22 -28; +set C[80] := -22 -34; +set C[81] := -22 -40; +set C[82] := -28 -34; +set C[83] := -28 -40; +set C[84] := -34 -40; +set C[85] := -5 -11; +set C[86] := -5 -17; +set C[87] := -5 -23; +set C[88] := -5 -29; +set C[89] := -5 -35; +set C[90] := -5 -41; +set C[91] := -11 -17; +set C[92] := -11 -23; +set C[93] := -11 -29; +set C[94] := -11 -35; +set C[95] := -11 -41; +set C[96] := -17 -23; +set C[97] := -17 -29; +set C[98] := -17 -35; +set C[99] := -17 -41; +set C[100] := -23 -29; +set C[101] := -23 -35; +set C[102] := -23 -41; +set C[103] := -29 -35; +set C[104] := -29 -41; +set C[105] := -35 -41; +set C[106] := -6 -12; +set C[107] := -6 -18; +set C[108] := -6 -24; +set C[109] := -6 -30; +set C[110] := -6 -36; +set C[111] := -6 -42; +set C[112] := -12 -18; +set C[113] := -12 -24; +set C[114] := -12 -30; +set C[115] := -12 -36; +set C[116] := -12 -42; +set C[117] := -18 -24; +set C[118] := -18 -30; +set C[119] := -18 -36; +set C[120] := -18 -42; +set C[121] := -24 -30; +set C[122] := -24 -36; +set C[123] := -24 -42; +set C[124] := -30 -36; +set C[125] := -30 -42; +set C[126] := -36 -42; +set C[127] := 6 5 4 3 2 1; +set C[128] := 12 11 10 9 8 7; +set C[129] := 18 17 16 15 14 13; +set C[130] := 24 23 22 21 20 19; +set C[131] := 30 29 28 27 26 25; +set C[132] := 36 35 34 33 32 31; +set C[133] := 42 41 40 39 38 37; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/shiftcov.mod b/resources/3rdparty/glpk-4.57/examples/shiftcov.mod new file mode 100644 index 000000000..1e036c8a2 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/shiftcov.mod @@ -0,0 +1,244 @@ +/* File: shiftcover.mod */ + +/* WORKFORCE SHIFT COVERAGE assignment problem */ + +/* Written by Larry D'Agostino + + Maximize Productivity with Industrial Engineer and Operations Research Tools + http://industrialengineertools.blogspot.com + + +/* The WORKFORCE SHIFT COVERAGE is an assigment problem that determines + the schedule of crew given available time and shifts. + + The objective is to cover the available time given hourly demand with the minimum + number of crew members. + + This is a set covering problem that is very common among finding crew + and shift allocations. Notice in the data section the workforce shift allocation + per day of the week.*/ + + +/* ----- Model PARAMTERS and SETS -----*/ + +param numhrs; +/* number of hours of operations in a given day */ + +param dys; +/* number of days in a week */ + +set S; +/* set of crew shifts */ + +set H := 1..numhrs; +/* set of hours of a day*/ + +set D; +/* set of days of a week*/ + +param dmnd{h in H, d in D}; +/* demand for crew members given h hour and d day */ + +param shifts{d in D, h in H, s in S}; +/* shifts to assign to crew members given d day, h hour, and s shift schedule + +/*----- Model VARIABLES -----*/ + +var crew{s in S}, integer, >=0; +/* number of crew assigned to shift S */ + + +/*----- Model CONSTRAINTS -----*/ + +s.t. Coverage{h in H, d in D}: sum{s in S} crew[s]*shifts[d,h,s] >= dmnd[h,d]; +/* number of crew to cover with a shift given hourly demand and day */ + + +/*----- Model OBJECTIVE -----*/ + +minimize obj: sum{s in S} crew[s]; +/* minimize number of crew to cover demand*/ + +solve; +display crew; + +printf "\n"; +printf "Total Crew: %3d\n\n", sum{s in S} crew[s]; + + + +printf "\n\n"; +printf "Weekly Crew Schedule\n\n"; +printf "Hour "; +printf{d in D} " %s ", d; +printf "\n"; +for {h in H} { + printf " %2s ",h; + printf{d in D} " %3d ", sum{s in S} crew[s]*shifts[d,h,s]; + printf "\n"; +} +printf"\n"; + + + +data; + +param numhrs := 16; + +set D := SUN, MON, TUE, WED, THU, FRI, SAT; + +set S := Sh1, Sh2, Sh3, Sh4, Sh5, Sh6, Sh7, Sh8, Sh9; + +param dmnd : SUN MON TUE WED THU FRI SAT := +1 0 3 3 4 3 2 0 +2 0 14 14 16 14 12 12 +3 0 24 24 27 24 20 15 +4 0 28 28 32 28 23 15 +5 0 33 33 37 33 24 16 +6 0 34 34 38 34 24 15 +7 0 35 35 39 35 25 11 +8 0 35 35 40 35 27 0 +9 0 34 34 39 34 25 0 +10 0 31 31 35 31 24 0 +11 2 24 24 27 24 25 0 +12 3 19 19 21 19 21 0 +13 2 24 24 27 24 13 0 +14 2 16 16 18 16 0 0 +15 0 7 7 7 7 0 0 +16 0 5 5 5 5 0 0; + + +param shifts := +['SUN',*,*]: + Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := +1 0 0 0 0 0 0 0 0 0 +2 0 0 0 0 0 0 0 0 0 +3 0 0 0 0 0 0 0 0 0 +4 0 0 0 0 0 0 0 0 0 +5 0 0 0 0 0 0 0 0 0 +6 0 0 0 0 0 0 0 0 0 +7 0 0 0 0 0 0 0 0 0 +8 0 0 0 0 0 0 0 0 0 +9 0 0 0 0 0 0 0 0 0 +10 0 0 0 0 0 0 0 0 0 +11 0 0 0 0 0 0 0 0 1 +12 0 0 0 0 0 0 0 0 1 +13 0 0 0 0 0 0 0 0 1 +14 0 0 0 0 0 0 0 0 1 +15 0 0 0 0 0 0 0 0 0 +16 0 0 0 0 0 0 0 0 0 + + +['MON',*,*]: + Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := +1 1 0 0 0 0 0 0 0 0 +2 1 1 0 0 0 0 0 0 0 +3 1 1 1 0 0 0 0 0 0 +4 1 1 1 1 0 0 0 0 0 +5 0 1 1 1 1 0 0 0 0 +6 1 0 1 1 1 1 0 0 1 +7 1 1 0 1 1 1 1 0 1 +8 1 1 1 0 1 1 1 1 1 +9 1 1 1 1 0 1 1 1 1 +10 0 1 1 1 1 0 1 1 1 +11 0 0 1 1 1 1 0 1 0 +12 0 0 0 1 1 1 1 0 1 +13 0 0 0 0 1 1 1 1 1 +14 0 0 0 0 0 1 1 1 1 +15 0 0 0 0 0 0 1 1 1 +16 0 0 0 0 0 0 0 1 1 + +['TUE',*,*]: + Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := +1 1 0 0 0 0 0 0 0 0 +2 1 1 0 0 0 0 0 0 0 +3 1 1 1 0 0 0 0 0 0 +4 1 1 1 1 0 0 0 0 0 +5 0 1 1 1 1 0 0 0 0 +6 1 0 1 1 1 1 0 0 1 +7 1 1 0 1 1 1 1 0 1 +8 1 1 1 0 1 1 1 1 1 +9 1 1 1 1 0 1 1 1 1 +10 0 1 1 1 1 0 1 1 1 +11 0 0 1 1 1 1 0 1 0 +12 0 0 0 1 1 1 1 0 1 +13 0 0 0 0 1 1 1 1 1 +14 0 0 0 0 0 1 1 1 1 +15 0 0 0 0 0 0 1 1 1 +16 0 0 0 0 0 0 0 1 1 + +['WED',*,*]: + Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := +1 1 0 0 0 0 0 0 0 0 +2 1 1 0 0 0 0 0 0 0 +3 1 1 1 0 0 0 0 0 0 +4 1 1 1 1 0 0 0 0 0 +5 0 1 1 1 1 0 0 0 0 +6 1 0 1 1 1 1 0 0 1 +7 1 1 0 1 1 1 1 0 1 +8 1 1 1 0 1 1 1 1 1 +9 1 1 1 1 0 1 1 1 1 +10 0 1 1 1 1 0 1 1 1 +11 0 0 1 1 1 1 0 1 0 +12 0 0 0 1 1 1 1 0 1 +13 0 0 0 0 1 1 1 1 1 +14 0 0 0 0 0 1 1 1 1 +15 0 0 0 0 0 0 1 1 1 +16 0 0 0 0 0 0 0 1 1 + +['THU',*,*]: + Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := +1 1 0 0 0 0 0 0 0 0 +2 1 1 0 0 0 0 0 0 0 +3 1 1 1 0 0 0 0 0 0 +4 1 1 1 1 0 0 0 0 0 +5 0 1 1 1 1 0 0 0 0 +6 1 0 1 1 1 1 0 0 0 +7 1 1 0 1 1 1 1 0 0 +8 1 1 1 0 1 1 1 1 0 +9 1 1 1 1 0 1 1 1 0 +10 0 1 1 1 1 0 1 1 0 +11 0 0 1 1 1 1 0 1 0 +12 0 0 0 1 1 1 1 0 0 +13 0 0 0 0 1 1 1 1 0 +14 0 0 0 0 0 1 1 1 0 +15 0 0 0 0 0 0 1 1 0 +16 0 0 0 0 0 0 0 1 0 + +['FRI',*,*]: + Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := +1 1 0 0 0 0 0 0 0 0 +2 1 1 0 0 0 0 0 0 0 +3 1 1 1 0 0 0 0 0 0 +4 1 1 1 1 0 0 0 0 0 +5 0 1 1 1 1 0 0 0 0 +6 1 0 1 1 1 1 0 0 0 +7 1 1 0 1 1 1 1 0 0 +8 1 1 1 0 1 1 1 1 0 +9 1 1 1 1 0 1 1 1 0 +10 0 1 1 1 1 0 1 1 0 +11 0 0 1 1 1 1 0 1 0 +12 0 0 0 1 1 1 1 0 0 +13 0 0 0 0 1 1 1 1 0 +14 0 0 0 0 0 1 1 1 0 +15 0 0 0 0 0 0 1 1 0 +16 0 0 0 0 0 0 0 1 0 + +['SAT',*,*]: + Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := +1 0 0 0 0 0 0 0 0 0 +2 0 0 0 0 0 0 0 0 1 +3 0 0 0 0 0 0 0 0 1 +4 0 0 0 0 0 0 0 0 1 +5 0 0 0 0 0 0 0 0 1 +6 0 0 0 0 0 0 0 0 1 +7 0 0 0 0 0 0 0 0 1 +8 0 0 0 0 0 0 0 0 0 +9 0 0 0 0 0 0 0 0 0 +10 0 0 0 0 0 0 0 0 0 +11 0 0 0 0 0 0 0 0 0 +12 0 0 0 0 0 0 0 0 0 +13 0 0 0 0 0 0 0 0 0 +14 0 0 0 0 0 0 0 0 0 +15 0 0 0 0 0 0 0 0 0 +16 0 0 0 0 0 0 0 0 0; diff --git a/resources/3rdparty/glpk-4.57/examples/shikaku.mod b/resources/3rdparty/glpk-4.57/examples/shikaku.mod new file mode 100644 index 000000000..19cf5ddbe --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/shikaku.mod @@ -0,0 +1,107 @@ +/* A solver for the Japanese number-puzzle Shikaku + * http://en.wikipedia.org/wiki/Shikaku + * + * Sebastian Nowozin , 27th January 2009 + */ + +param ndim := 10; +set rows := 1..ndim; +set rows1 := 1..(ndim+1); +set cols := 1..ndim; +set cols1 := 1..(ndim+1); +param givens{rows, cols}, integer, >= 0, default 0; + +/* Set of vertices as (row,col) coordinates */ +set V := { (i,j) in { rows, cols }: givens[i,j] != 0 }; + +/* Set of all feasible boxes of the right size: only this boxes are possible. + * The box contains (i,j) and ranges from (k,l) to (m,n) + */ +set B := { (i,j,k,l,m,n) in { V, rows, cols, rows1, cols1 }: + i >= k and i < m and j >= l and j < n and /* Contains (i,j) */ + ((m-k)*(n-l)) = givens[i,j] and /* Right size */ + card({ (s,t) in V: s >= k and s < m and t >= l and t < n }) = 1 + /* Contains only (i,j), no other number */ +}; + +var x{B}, binary; + +/* Cover each square exactly once */ +s.t. cover_once{ (s,t) in { rows, cols } }: + sum{(i,j,k,l,m,n) in B: s >= k and s < m and t >= l and t < n} + x[i,j,k,l,m,n] = 1; + +minimize cost: 0; + +solve; + +/* Output solution graphically */ +printf "\nSolution:\n"; +for { row in rows1 } { + for { col in cols1 } { + printf{0..0: card({(i,j,k,l,m,n) in B: + col >= l and col <= n and (row = k or row = m) and + x[i,j,k,l,m,n] = 1}) > 0 and + card({(i,j,k,l,m,n) in B: + row >= k and row <= m and (col = l or col = n) and + x[i,j,k,l,m,n] = 1}) > 0} "+"; + printf{0..0: card({(i,j,k,l,m,n) in B: + col >= l and col <= n and (row = k or row = m) and + x[i,j,k,l,m,n] = 1}) = 0 and + card({(i,j,k,l,m,n) in B: + row >= k and row <= m and (col = l or col = n) and + x[i,j,k,l,m,n] = 1}) > 0} "|"; + printf{0..0: card({(i,j,k,l,m,n) in B: + row >= k and row <= m and (col = l or col = n) and + x[i,j,k,l,m,n] = 1}) = 0 and + card({(i,j,k,l,m,n) in B: + col >= l and col <= n and (row = k or row = m) and + x[i,j,k,l,m,n] = 1}) > 0} "-"; + printf{0..0: card({(i,j,k,l,m,n) in B: + row >= k and row <= m and (col = l or col = n) and + x[i,j,k,l,m,n] = 1}) = 0 and + card({(i,j,k,l,m,n) in B: + col >= l and col <= n and (row = k or row = m) and + x[i,j,k,l,m,n] = 1}) = 0} " "; + + printf{0..0: card({(i,j,k,l,m,n) in B: + col >= l and col < n and (row = k or row = m) and + x[i,j,k,l,m,n] = 1}) > 0} "---"; + printf{0..0: card({(i,j,k,l,m,n) in B: + col >= l and col < n and (row = k or row = m) and + x[i,j,k,l,m,n] = 1}) = 0} " "; + } + printf "\n"; + + for { (col,p) in { cols, 1 }: card({ s in rows: s = row }) = 1 } { + printf{0..0: card({(i,j,k,l,m,n) in B: + row >= k and row < m and (col = l or col = n) and + x[i,j,k,l,m,n] = 1}) > 0} "|"; + printf{0..0: card({(i,j,k,l,m,n) in B: + row >= k and row < m and (col = l or col = n) and + x[i,j,k,l,m,n] = 1}) = 0} " "; + printf{0..0: card({ (i,j) in V: i = row and j = col}) > 0} " %2d", givens[row,col]; + printf{0..0: card({ (i,j) in V: i = row and j = col}) = 0} " ."; + } + printf{0..0: card({ r in rows: r = row }) = 1} "|\n"; +} + +data; + +/* This Shikaku is from + * http://www.emn.fr/x-info/sdemasse/gccat/KShikaku.html#uid5449 + */ +param givens : 1 2 3 4 5 6 7 8 9 10 := + 1 9 . . . 12 . . 5 . . + 2 . . . . . . . . . . + 3 . . . . . . . . . 6 + 4 8 . 6 . 8 . . . . . + 5 . . . . . . . . . . + 6 . . . . . . . . . . + 7 . . . . . 6 . 8 . 12 + 8 4 . . . . . . . . . + 9 . . . . . . . . . . + 10 . . 3 . . 9 . . . 4 + ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/sorting.mod b/resources/3rdparty/glpk-4.57/examples/sorting.mod new file mode 100644 index 000000000..8f82b1fc5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sorting.mod @@ -0,0 +1,67 @@ +/* sorting.mod - how to sort arrays in MathProg */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +# Sometimes it is necessary to print parameters or variables in the +# order of ascending or descending their values. Suppose, for example, +# that we have the following subscripted parameter: + +set I := 1..12; + +param a{i in I} := Uniform(2, 7); + +# If we print all its members: + +printf{i in I} "a[%d] = %g\n", i, a[i]; + +# the output may look like follows: +# +# a[1] = 2.64156 +# a[2] = 2.04798 +# a[3] = 2.14843 +# a[4] = 4.76896 +# a[5] = 6.09132 +# a[6] = 3.27780 +# a[7] = 4.06113 +# a[8] = 4.05898 +# a[9] = 6.63120 +# a[10] = 6.50318 +# a[11] = 3.46065 +# a[12] = 4.69845 +# +# However, we would like the parameter members to appear in the order +# of ascending their values. +# +# Introduce the following auxiliary parameter: + +param pos{i in I} := + 1 + card({j in I: a[j] < a[i] or a[j] = a[i] and j < i}); + +# where pos[i] = k means that in the sorted list member a[i] would +# have k-th position, 1 <= k <= |I|. Then introduce another auxiliary +# parameter: + +param ind{k in 1..card(I)} := sum{i in I: pos[i] = k} i; + +# where ind[k] = i iff pos[k] = i. +# +# Now, the following statement: + +printf{k in 1..card(I)} "a[%d] = %g\n", ind[k], a[ind[k]]; + +# prints the parameter members in the desired order: +# +# a[2] = 2.04798 +# a[3] = 2.14843 +# a[1] = 2.64156 +# a[6] = 3.27780 +# a[11] = 3.46065 +# a[8] = 4.05898 +# a[7] = 4.06113 +# a[12] = 4.69845 +# a[4] = 4.76896 +# a[5] = 6.09132 +# a[10] = 6.50318 +# a[9] = 6.63120 + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/spp.mod b/resources/3rdparty/glpk-4.57/examples/spp.mod new file mode 100644 index 000000000..53008f62c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/spp.mod @@ -0,0 +1,67 @@ +/* SPP, Shortest Path Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* Given a directed graph G = (V,E), its edge lengths c(i,j) for all + (i,j) in E, and two nodes s, t in V, the Shortest Path Problem (SPP) + is to find a directed path from s to t whose length is minimal. */ + +param n, integer, > 0; +/* number of nodes */ + +set E, within {i in 1..n, j in 1..n}; +/* set of edges */ + +param c{(i,j) in E}; +/* c[i,j] is length of edge (i,j); note that edge lengths are allowed + to be of any sign (positive, negative, or zero) */ + +param s, in {1..n}; +/* source node */ + +param t, in {1..n}; +/* target node */ + +var x{(i,j) in E}, >= 0; +/* x[i,j] = 1 means that edge (i,j) belong to shortest path; + x[i,j] = 0 means that edge (i,j) does not belong to shortest path; + note that variables x[i,j] are binary, however, there is no need to + declare them so due to the totally unimodular constraint matrix */ + +s.t. r{i in 1..n}: sum{(j,i) in E} x[j,i] + (if i = s then 1) = + sum{(i,j) in E} x[i,j] + (if i = t then 1); +/* conservation conditions for unity flow from s to t; every feasible + solution is a path from s to t */ + +minimize Z: sum{(i,j) in E} c[i,j] * x[i,j]; +/* objective function is the path length to be minimized */ + +data; + +/* Optimal solution is 20 that corresponds to the following shortest + path: s = 1 -> 2 -> 4 -> 8 -> 6 = t */ + +param n := 8; + +param s := 1; + +param t := 6; + +param : E : c := + 1 2 1 + 1 4 8 + 1 7 6 + 2 4 2 + 3 2 14 + 3 4 10 + 3 5 6 + 3 6 19 + 4 5 8 + 4 8 13 + 5 8 12 + 6 5 7 + 7 4 5 + 8 6 4 + 8 7 10; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/spxsamp1.c b/resources/3rdparty/glpk-4.57/examples/spxsamp1.c new file mode 100644 index 000000000..715642341 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/spxsamp1.c @@ -0,0 +1,18 @@ +/* spxsamp1.c */ + +#include +#include +#include + +int main(void) +{ glp_prob *P; + P = glp_create_prob(); + glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); + glp_adv_basis(P, 0); + glp_simplex(P, NULL); + glp_print_sol(P, "25fv47.txt"); + glp_delete_prob(P); + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/spxsamp2.c b/resources/3rdparty/glpk-4.57/examples/spxsamp2.c new file mode 100644 index 000000000..f952e740e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/spxsamp2.c @@ -0,0 +1,20 @@ +/* spxsamp2.c */ + +#include +#include +#include + +int main(void) +{ glp_prob *P; + glp_smcp parm; + P = glp_create_prob(); + glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); + glp_init_smcp(&parm); + parm.meth = GLP_DUAL; + glp_simplex(P, &parm); + glp_print_sol(P, "25fv47.txt"); + glp_delete_prob(P); + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/sql/README b/resources/3rdparty/glpk-4.57/examples/sql/README new file mode 100644 index 000000000..f78ec1574 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sql/README @@ -0,0 +1,5 @@ +This subdirectory contains files which demonstrate using data tables +in MathProg models for MySQL and iODBC. + +Script mysql_setup.sh is used to load the data from the *.sql files to +a MySQL database. Change the username, if necessary. diff --git a/resources/3rdparty/glpk-4.57/examples/sql/mysql_setup.sh b/resources/3rdparty/glpk-4.57/examples/sql/mysql_setup.sh new file mode 100755 index 000000000..1dce8edd9 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sql/mysql_setup.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# This file can be used to create database glpk in MySQL. +echo MySQL is called for user root. +mysql -f -u root -p < sudoku.sql +echo MySQL is called for user root. +mysql -f -u root -p < transp.sql diff --git a/resources/3rdparty/glpk-4.57/examples/sql/sudoku.sql b/resources/3rdparty/glpk-4.57/examples/sql/sudoku.sql new file mode 100644 index 000000000..2fe40d777 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sql/sudoku.sql @@ -0,0 +1,101 @@ +CREATE DATABASE glpk; +CREATE USER glpk@localhost IDENTIFIED BY 'gnu'; +GRANT ALL PRIVILEGES ON glpk.* TO glpk@localhost; +USE glpk; +DROP TABLE sudoku; +CREATE TABLE sudoku ( + ID INT , + COL INT , + LIN INT , + VAL INT , + PRIMARY KEY ( ID, COL, LIN ) + ); +DROP TABLE sudoku_solution; +CREATE TABLE sudoku_solution ( + ID INT , + COL INT , + LIN INT , + VAL INT , + PRIMARY KEY ( ID, COL, LIN ) + ); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 1, 5); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 2, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 3, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 4, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 5, 4); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 6, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 7, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 8, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 9, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 1, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 2, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 3, 3); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 4, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 5, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 6, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 7, 6); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 8, 2); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 9, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 1, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 2, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 3, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 4, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 5, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 6, 9); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 7, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 8, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 9, 4); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 1, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 2, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 3, 6); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 4, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 5, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 6, 7); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 7, 2); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 8, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 9, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 1, 8); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 2, 1); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 3, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 4, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 5, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 6, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 7, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 8, 4); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 9, 3); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 1, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 2, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 3, 9); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 4, 1); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 5, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 6, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 7, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 8, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 9, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 1, 7); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 2, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 3, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 4, 5); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 5, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 6, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 7, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 8, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 9, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 1, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 2, 9); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 3, 2); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 4, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 5, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 6, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 7, 8); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 8, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 9, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 1, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 2, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 3, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 4, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 5, 3); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 6, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 7, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 8, 0); +INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 9, 6); diff --git a/resources/3rdparty/glpk-4.57/examples/sql/sudoku_mysql.mod b/resources/3rdparty/glpk-4.57/examples/sql/sudoku_mysql.mod new file mode 100644 index 000000000..6e56f2c6d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sql/sudoku_mysql.mod @@ -0,0 +1,113 @@ +/* SUDOKU, Number Placement Puzzle */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* This example shows how to use the table statement. + The sudoku to be solves is read from file sudoku_in.csv. + The solution is written to sudoku_out.csv. + The file format is CSV as defined in + RFC 4180 - Common Format and MIME Type for + Comma-Separated Values (CSV) Files */ + +/* Sudoku, also known as Number Place, is a logic-based placement + puzzle. The aim of the canonical puzzle is to enter a numerical + digit from 1 through 9 in each cell of a 9x9 grid made up of 3x3 + subgrids (called "regions"), starting with various digits given in + some cells (the "givens"). Each row, column, and region must contain + only one instance of each numeral. + + Example: + + +-------+-------+-------+ + | 5 3 . | . 7 . | . . . | + | 6 . . | 1 9 5 | . . . | + | . 9 8 | . . . | . 6 . | + +-------+-------+-------+ + | 8 . . | . 6 . | . . 3 | + | 4 . . | 8 . 3 | . . 1 | + | 7 . . | . 2 . | . . 6 | + +-------+-------+-------+ + | . 6 . | . . . | 2 8 . | + | . . . | 4 1 9 | . . 5 | + | . . . | . 8 . | . 7 9 | + +-------+-------+-------+ + + (From Wikipedia, the free encyclopedia.) */ +set fields dimen 2; + +param id; + +param givens{1..9, 1..9}, integer, >= 0, <= 9, default 0; +/* the "givens" */ + +/* +table ti IN 'MySQL' 'Database=glpk;UID=glpk;PWD=gnu' + 'sudoku' : + fields <- [COL, LIN], givens ~ VAL; +*/ +table ti IN 'MySQL' 'Database=glpk;UID=glpk;PWD=gnu' + 'SELECT * FROM sudoku WHERE ID = ' & id : + fields <- [COL, LIN], givens ~ VAL; + +var x{i in 1..9, j in 1..9, k in 1..9}, binary; +/* x[i,j,k] = 1 means cell [i,j] is assigned number k */ + +s.t. fa{i in 1..9, j in 1..9, k in 1..9: givens[i,j] != 0}: + x[i,j,k] = (if givens[i,j] = k then 1 else 0); +/* assign pre-defined numbers using the "givens" */ + +s.t. fb{i in 1..9, j in 1..9}: sum{k in 1..9} x[i,j,k] = 1; +/* each cell must be assigned exactly one number */ + +s.t. fc{i in 1..9, k in 1..9}: sum{j in 1..9} x[i,j,k] = 1; +/* cells in the same row must be assigned distinct numbers */ + +s.t. fd{j in 1..9, k in 1..9}: sum{i in 1..9} x[i,j,k] = 1; +/* cells in the same column must be assigned distinct numbers */ + +s.t. fe{I in 1..9 by 3, J in 1..9 by 3, k in 1..9}: + sum{i in I..I+2, j in J..J+2} x[i,j,k] = 1; +/* cells in the same region must be assigned distinct numbers */ + +/* there is no need for an objective function here */ + +solve; + +table ta{(i,j) in fields} OUT + 'MySQL' 'Database=glpk;UID=glpk;PWD=gnu' + 'DELETE FROM sudoku_solution' + 'WHERE ID = ' & id & ';' + 'INSERT INTO sudoku_solution' + '(ID, COL, LIN, VAL)' + 'VALUES(?, ?, ?, ?);' : + id ~ ID, i ~ COL, j ~ LIN, (sum{k in 1..9} x[i,j,k] * k) ~ VAL; + +printf "\nSudoku to be solved\n"; +for {i in 1..9} +{ for {0..0: i = 1 or i = 4 or i = 7} + printf " +-------+-------+-------+\n"; + for {j in 1..9} + { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); + printf " %d", givens[i,j]; + for {0..0: j = 9} printf(" |\n"); + } + for {0..0: i = 9} + printf " +-------+-------+-------+\n"; + } +printf "\nSolution\n"; +for {i in 1..9} +{ for {0..0: i = 1 or i = 4 or i = 7} + printf " +-------+-------+-------+\n"; + for {j in 1..9} + { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); + printf " %d", sum{k in 1..9} x[i,j,k] * k; + for {0..0: j = 9} printf(" |\n"); + } + for {0..0: i = 9} + printf " +-------+-------+-------+\n"; +} + +data; + +param id := 1; +end; diff --git a/resources/3rdparty/glpk-4.57/examples/sql/sudoku_odbc.mod b/resources/3rdparty/glpk-4.57/examples/sql/sudoku_odbc.mod new file mode 100644 index 000000000..9ffa3ab06 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sql/sudoku_odbc.mod @@ -0,0 +1,111 @@ +/* SUDOKU, Number Placement Puzzle */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* This example shows how to use the table statement. + The sudoku to be solves is read from file sudoku_in.csv. + The solution is written to sudoku_out.csv. + The file format is CSV as defined in + RFC 4180 - Common Format and MIME Type for + Comma-Separated Values (CSV) Files */ + +/* Sudoku, also known as Number Place, is a logic-based placement + puzzle. The aim of the canonical puzzle is to enter a numerical + digit from 1 through 9 in each cell of a 9x9 grid made up of 3x3 + subgrids (called "regions"), starting with various digits given in + some cells (the "givens"). Each row, column, and region must contain + only one instance of each numeral. + + Example: + + +-------+-------+-------+ + | 5 3 . | . 7 . | . . . | + | 6 . . | 1 9 5 | . . . | + | . 9 8 | . . . | . 6 . | + +-------+-------+-------+ + | 8 . . | . 6 . | . . 3 | + | 4 . . | 8 . 3 | . . 1 | + | 7 . . | . 2 . | . . 6 | + +-------+-------+-------+ + | . 6 . | . . . | 2 8 . | + | . . . | 4 1 9 | . . 5 | + | . . . | . 8 . | . 7 9 | + +-------+-------+-------+ + + (From Wikipedia, the free encyclopedia.) */ +set fields dimen 2; + +param id; + +param givens{1..9, 1..9}, integer, >= 0, <= 9, default 0; +/* the "givens" */ + +table ti IN 'iODBC' + 'DSN=glpk;UID=glpk;PWD=gnu' + 'SELECT * FROM sudoku' + 'WHERE ID = ' & id : + fields <- [COL, LIN], givens ~ VAL; + +var x{i in 1..9, j in 1..9, k in 1..9}, binary; +/* x[i,j,k] = 1 means cell [i,j] is assigned number k */ + +s.t. fa{i in 1..9, j in 1..9, k in 1..9: givens[i,j] != 0}: + x[i,j,k] = (if givens[i,j] = k then 1 else 0); +/* assign pre-defined numbers using the "givens" */ + +s.t. fb{i in 1..9, j in 1..9}: sum{k in 1..9} x[i,j,k] = 1; +/* each cell must be assigned exactly one number */ + +s.t. fc{i in 1..9, k in 1..9}: sum{j in 1..9} x[i,j,k] = 1; +/* cells in the same row must be assigned distinct numbers */ + +s.t. fd{j in 1..9, k in 1..9}: sum{i in 1..9} x[i,j,k] = 1; +/* cells in the same column must be assigned distinct numbers */ + +s.t. fe{I in 1..9 by 3, J in 1..9 by 3, k in 1..9}: + sum{i in I..I+2, j in J..J+2} x[i,j,k] = 1; +/* cells in the same region must be assigned distinct numbers */ + +/* there is no need for an objective function here */ + + +solve; + +table ta {(i, j) in {i1 in 1..9} cross {i2 in 1..9}} OUT + 'iODBC' 'DSN=glpk;UID=glpk;PWD=gnu' + 'DELETE FROM sudoku_solution' + 'WHERE ID = ' & id & ';' + 'INSERT INTO sudoku_solution' + '(ID, COL, LIN, VAL)' + 'VALUES(?, ?, ?, ?);' : + id ~ ID, i ~ COL, j ~ LIN, (sum{k in 1..9} x[i,j,k] * k) ~ VAL; + +printf "\nSudoku to be solved\n"; +for {i in 1..9} +{ for {0..0: i = 1 or i = 4 or i = 7} + printf " +-------+-------+-------+\n"; + for {j in 1..9} + { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); + printf " %d", givens[i,j]; + for {0..0: j = 9} printf(" |\n"); + } + for {0..0: i = 9} + printf " +-------+-------+-------+\n"; + } +printf "\nSolution\n"; +for {i in 1..9} +{ for {0..0: i = 1 or i = 4 or i = 7} + printf " +-------+-------+-------+\n"; + for {j in 1..9} + { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); + printf " %d", sum{k in 1..9} x[i,j,k] * k; + for {0..0: j = 9} printf(" |\n"); + } + for {0..0: i = 9} + printf " +-------+-------+-------+\n"; +} + +data; + +param id := 1; +end; diff --git a/resources/3rdparty/glpk-4.57/examples/sql/transp.sql b/resources/3rdparty/glpk-4.57/examples/sql/transp.sql new file mode 100644 index 000000000..873733303 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sql/transp.sql @@ -0,0 +1,45 @@ +CREATE DATABASE glpk; +CREATE USER glpk@localhost IDENTIFIED BY 'gnu'; +GRANT ALL PRIVILEGES ON glpk.* TO glpk@localhost; +USE glpk; +# production capacity +DROP TABLE transp_capa; +CREATE TABLE transp_capa ( + PLANT TEXT(127), + CAPA REAL, + PRIMARY KEY ( PLANT(127) ) + ); +INSERT INTO transp_capa ( PLANT, CAPA ) VALUES ( 'Seattle', 350 ); +INSERT INTO transp_capa ( PLANT, CAPA ) VALUES ( 'San Diego', 600 ); +# demand +DROP TABLE transp_demand; +CREATE TABLE transp_demand ( + MARKET TEXT(127), + DEMAND REAL, + PRIMARY KEY ( MARKET(127) ) + ); +INSERT INTO transp_demand ( MARKET, DEMAND ) VALUES ( 'New York', 325 ); +INSERT INTO transp_demand ( MARKET, DEMAND ) VALUES ( 'Chicago', 300 ); +INSERT INTO transp_demand ( MARKET, DEMAND ) VALUES ( 'Topeka', 275 ); +# distance +DROP TABLE transp_dist; +CREATE TABLE transp_dist ( + LOC1 TEXT(127), + LOC2 TEXT(127), + DIST REAL, + PRIMARY KEY ( LOC1(127), LOC2(127) ) + ); +INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'Seattle', 'New York', 2.5 ); +INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'Seattle', 'Chicago', 1.7 ); +INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'Seattle', 'Topeka', 1.8 ); +INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'San Diego', 'New York', 2.5 ); +INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'San Diego', 'Chicago', 1.8 ); +INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'San Diego', 'Topeka', 1.4 ); +# result +DROP TABLE transp_result; +CREATE TABLE transp_result ( + LOC1 TEXT(127), + LOC2 TEXT(127), + QUANTITY REAL, + PRIMARY KEY ( LOC1(127), LOC2(127) ) + ); diff --git a/resources/3rdparty/glpk-4.57/examples/sql/transp_mysql.mod b/resources/3rdparty/glpk-4.57/examples/sql/transp_mysql.mod new file mode 100644 index 000000000..f375fa395 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sql/transp_mysql.mod @@ -0,0 +1,71 @@ +# A TRANSPORTATION PROBLEM +# +# This problem finds a least cost shipping schedule that meets +# requirements at markets and supplies at factories. +# +# References: +# Dantzig G B, "Linear Programming and Extensions." +# Princeton University Press, Princeton, New Jersey, 1963, +# Chapter 3-3. + +set I; +/* canning plants */ + +param a{i in I}; +/* capacity of plant i in cases */ + +table plants IN "MySQL" + 'Database=glpk;UID=glpk;PWD=gnu' + 'SELECT PLANT, CAPA AS CAPACITY FROM transp_capa' : + I <- [ PLANT ], a ~ CAPACITY; + +set J; +/* markets */ + +param b{j in J}; +/* demand at market j in cases */ + +table markets IN "MySQL" + 'Database=glpk;UID=glpk;PWD=gnu' + 'transp_demand' : + J <- [ MARKET ], b ~ DEMAND; + +param d{i in I, j in J}; +/* distance in thousands of miles */ + +table dist IN "MySQL" + 'Database=glpk;UID=glpk;PWD=gnu' + 'transp_dist' : + [ LOC1, LOC2 ], d ~ DIST; + +param f; +/* freight in dollars per case per thousand miles */ + +param c{i in I, j in J} := f * d[i,j] / 1000; +/* transport cost in thousands of dollars per case */ + +var x{i in I, j in J} >= 0; +/* shipment quantities in cases */ + +minimize cost: sum{i in I, j in J} c[i,j] * x[i,j]; +/* total transportation costs in thousands of dollars */ + +s.t. supply{i in I}: sum{j in J} x[i,j] <= a[i]; +/* observe supply limit at plant i */ + +s.t. demand{j in J}: sum{i in I} x[i,j] >= b[j]; +/* satisfy demand at market j */ + +solve; + +table result{i in I, j in J: x[i,j]} OUT "MySQL" + 'Database=glpk;UID=glpk;PWD=gnu' + 'DELETE FROM transp_result;' + 'INSERT INTO transp_result VALUES (?,?,?)' : + i ~ LOC1, j ~ LOC2, x[i,j] ~ QUANTITY; + +data; + +param f := 90; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/sql/transp_odbc.mod b/resources/3rdparty/glpk-4.57/examples/sql/transp_odbc.mod new file mode 100644 index 000000000..36d807e41 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sql/transp_odbc.mod @@ -0,0 +1,72 @@ +# A TRANSPORTATION PROBLEM +# +# This problem finds a least cost shipping schedule that meets +# requirements at markets and supplies at factories. +# +# References: +# Dantzig G B, "Linear Programming and Extensions." +# Princeton University Press, Princeton, New Jersey, 1963, +# Chapter 3-3. + +set I; +/* canning plants */ + +param a{i in I}; +/* capacity of plant i in cases */ + +table plants IN "iODBC" + 'DSN=glpk;UID=glpk;PWD=gnu' + 'SELECT PLANT, CAPA AS CAPACITY' + 'FROM transp_capa' : + I <- [ PLANT ], a ~ CAPACITY; + +set J; +/* markets */ + +param b{j in J}; +/* demand at market j in cases */ + +table markets IN "iODBC" + 'DSN=glpk;UID=glpk;PWD=gnu' + 'transp_demand' : + J <- [ MARKET ], b ~ DEMAND; + +param d{i in I, j in J}; +/* distance in thousands of miles */ + +table dist IN "iODBC" + 'DSN=glpk;UID=glpk;PWD=gnu' + 'transp_dist' : + [ LOC1, LOC2 ], d ~ DIST; + +param f; +/* freight in dollars per case per thousand miles */ + +param c{i in I, j in J} := f * d[i,j] / 1000; +/* transport cost in thousands of dollars per case */ + +var x{i in I, j in J} >= 0; +/* shipment quantities in cases */ + +minimize cost: sum{i in I, j in J} c[i,j] * x[i,j]; +/* total transportation costs in thousands of dollars */ + +s.t. supply{i in I}: sum{j in J} x[i,j] <= a[i]; +/* observe supply limit at plant i */ + +s.t. demand{j in J}: sum{i in I} x[i,j] >= b[j]; +/* satisfy demand at market j */ + +solve; + +table result{i in I, j in J: x[i,j]} OUT "iODBC" + 'DSN=glpk;UID=glpk;PWD=gnu' + 'DELETE FROM transp_result;' + 'INSERT INTO transp_result VALUES (?,?,?)' : + i ~ LOC1, j ~ LOC2, x[i,j] ~ QUANTITY; + +data; + +param f := 90; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/stigler.mod b/resources/3rdparty/glpk-4.57/examples/stigler.mod new file mode 100644 index 000000000..20c5d9d13 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/stigler.mod @@ -0,0 +1,411 @@ +/* STIGLER, original Stigler's 1939 diet problem */ + +/* The Stigler Diet is an optimization problem named for George Stigler, + a 1982 Nobel Laureate in economics, who posed the following problem: + For a moderately active man weighing 154 pounds, how much of each of + 77 foods should be eaten on a daily basis so that the man's intake of + nine nutrients will be at least equal to the recommended dietary + allowances (RDSs) suggested by the National Research Council in 1943, + with the cost of the diet being minimal? + + The nutrient RDAs required to be met in Stigler's experiment were + calories, protein, calcium, iron, vitamin A, thiamine, riboflavin, + niacin, and ascorbic acid. The result was an annual budget allocated + to foods such as evaporated milk, cabbage, dried navy beans, and beef + liver at a cost of approximately $0.11 a day in 1939 U.S. dollars. + + While the name "Stigler Diet" was applied after the experiment by + outsiders, according to Stigler, "No one recommends these diets for + anyone, let alone everyone." The Stigler diet has been much ridiculed + for its lack of variety and palatability, however his methodology has + received praise and is considered to be some of the earliest work in + linear programming. + + The Stigler diet question is a linear programming problem. Lacking + any sophisticated method of solving such a problem, Stigler was + forced to utilize heuristic methods in order to find a solution. The + diet question originally asked in which quantities a 154 pound male + would have to consume 77 different foods in order to fulfill the + recommended intake of 9 different nutrients while keeping expense at + a minimum. Through "trial and error, mathematical insight and + agility," Stigler was able to eliminate 62 of the foods from the + original 77 (these foods were removed based because they lacked + nutrients in comparison to the remaining 15). From the reduced list, + Stigler calculated the required amounts of each of the remaining 15 + foods to arrive at a cost-minimizing solution to his question. + According to Stigler's calculations, the annual cost of his solution + was $39.93 in 1939 dollars. When corrected for inflation using the + consumer price index, the cost of the diet in 2005 dollars is + $561.43. The specific combination of foods and quantities is as + follows: + + Stigler's 1939 Diet + + Food Annual Quantities Annual Cost + ---------------- ----------------- ----------- + Wheat Flour 370 lb. $13.33 + Evaporated Milk 57 cans 3.84 + Cabbage 111 lb. 4.11 + Spinach 23 lb. 1.85 + Dried Navy Beans 285 lb. 16.80 + ---------------------------------------------- + Total Annual Cost $39.93 + + The 9 nutrients that Stigler's diet took into consideration and their + respective recommended daily amounts were: + + Table of nutrients considered in Stigler's diet + + Nutrient Daily Recommended Intake + ------------------------- ------------------------ + Calories 3,000 Calories + Protein 70 grams + Calcium .8 grams + Iron 12 milligrams + Vitamin A 5,000 IU + Thiamine (Vitamin B1) 1.8 milligrams + Riboflavin (Vitamin B2) 2.7 milligrams + Niacin 18 milligrams + Ascorbic Acid (Vitamin C) 75 milligrams + + Seven years after Stigler made his initial estimates, the development + of George Dantzig's Simplex algorithm made it possible to solve the + problem without relying on heuristic methods. The exact value was + determined to be $39.69 (using the original 1939 data). Dantzig's + algorithm describes a method of traversing the vertices of a polytope + of N+1 dimensions in order to find the optimal solution to a specific + situation. + + (From Wikipedia, the free encyclopedia.) */ + +/* Translated from GAMS by Andrew Makhorin . + + For the original GAMS model stigler1939.gms see [3]. + + References: + + 1. George J. Stigler, "The Cost of Subsistence," J. Farm Econ. 27, + 1945, pp. 303-14. + + 2. National Research Council, "Recommended Daily Allowances," Reprint + and Circular Series No. 115, January, 1943. + + 3. Erwin Kalvelagen, "Model building with GAMS," Chapter 2, "Building + linear programming models," pp. 128-34. */ + +set C; +/* commodities */ + +check card(C) = 77; +/* there must be 77 commodities */ + +set N; +/* nutrients */ + +param data{c in C, {"price", "weight"} union N}; +/* nutritive values per dollar of expenditure */ + +param allowance{n in N}; +/* recommended daily allowance for a moderately active man */ + +var x{c in C}, >= 0; +/* dollars of food to be purchased daily */ + +s.t. nb{n in N}: sum{c in C} data[c,n] * x[c] >= allowance[n]; +/* nutrient balance */ + +minimize cost: sum{c in C} x[c]; +/* total food bill */ + +solve; + +param days := 365.25; +/* days in a year */ + +param commodity{c in C}, symbolic; + +param unit{c in C}, symbolic; + +printf "\n"; +printf "MINIMUM COST ANNUAL DIET\n"; +printf "\n"; +printf " Commodity Unit Quantity Cost \n"; +printf "------------------------- ---------- ---------- ----------\n"; +printf{c in C: x[c] != 0} "%-25s %10s %10.2f $%7.2f\n", commodity[c], + unit[c], 100 * days * x[c] / data[c,"price"], days * x[c]; +printf " -----------------\n"; +printf " Total: $%7.2f\n", + days * sum{c in C} x[c]; +printf "\n"; + +data; + +param : C : commodity unit := +flour "Wheat Flour (Enriched)" "10 lb." +macaroni "Macaroni" "1 lb." +cereal "Wheat Cereal (Enriched)" "28 oz." +cornflakes "Corn Flakes" "8 oz." +cornmeal "Corn Meal" "1 lb." +grits "Hominy Grits" "24 oz." +rice "Rice" "1 lb." +oats "Rolled Oats" "1 lb." +whitebread "White Bread (Enriched)" "1 lb." +wheatbread "Whole Wheat Bread" "1 lb." +ryebread "Rye Bread" "1 lb." +poundcake "Pound Cake" "1 lb." +crackers "Soda Crackers" "1 lb." +milk "Milk" "1 qt." +evapmild "Evaporated Milk (can)" "14.5 oz." +butter "Butter" "1 lb." +margarine "Oleomargarine" "1 lb." +eggs "Eggs" "1 doz." +cheese "Cheese (Cheddar)" "1 lb." +cream "Cream" "1/2 pt." +peanutbutter "Peanut Butter" "1 lb." +mayonnaise "Mayonnaise" "1/2 pt." +crisco "Crisco" "1 lb." +lard "Lard" "1 lb." +sirloinsteak "Sirloin Steak" "1 lb." +roundsteak "Round Steak" "1 lb." +ribroast "Rib Roast" "1 lb." +chuckroast "Chuck Roast" "1 lb." +plate "Plate" "1 lb." +liver "Liver (Beef)" "1 lb." +lambleg "Leg of Lamb" "1 lb." +lambchops "Lamb Chops (Rib)" "1 lb." +porkchops "Pork Chops" "1 lb." +porkroast "Pork Loin Roast" "1 lb." +bacon "Bacon" "1 lb." +ham "Ham - smoked" "1 lb." +saltpork "Salt Pork" "1 lb." +chicken "Roasting Chicken" "1 lb." +veal "Veal Cutlets" "1 lb." +salmon "Salmon, Pink (can)" "16 oz." +apples "Apples" "1 lb." +bananas "Bananas" "1 lb." +lemons "Lemons" "1 doz." +oranges "Oranges" "1 doz." +greenbeans "Green Beans" "1 lb." +cabbage "Cabbage" "1 lb." +carrots "Carrots" "1 bunch" +celery "Celery" "1 stalk" +lettuce "Lettuce" "1 head" +onions "Onions" "1 lb." +potatoes "Potatoes" "15 lb." +spinach "Spinach" "1 lb." +sweetpotato "Sweet Potatoes" "1 lb." +peaches "Peaches (can)" "No. 2 1/2" +pears "Pears (can)" "No. 2 1/2" +pineapple "Pineapple (can)" "No. 2 1/2" +asparagus "Asparagus (can)" "No. 2" +cannedgrbn "Grean Beans (can)" "No. 2" +porkbeans "Pork and Beans (can)" "16 oz." +corn "Corn (can)" "No. 2" +peas "Peas (can)" "No. 2" +tomatoes "Tomatoes (can)" "No. 2" +tomatosoup "Tomato Soup (can)" "10 1/2 oz." +driedpeach "Peaches, Dried" "1 lb." +prunes "Prunes, Dried" "1 lb." +raisins "Raisins, Dried" "15 oz." +driedpeas "Peas, Dried" "1 lb." +limabeans "Lima Beans, Dried" "1 lb." +navybeans "Navy Beans, Dried" "1 lb." +coffee "Coffee" "1 lb." +tea "Tea" "1/4 lb." +cocoa "Cocoa" "8 oz." +chocolate "Chocolate" "8 oz." +sugar "Sugar" "10 lb." +cornsirup "Corn Sirup" "24 oz." +molasses "Molasses" "18 oz." +strawberry "Strawberry Preserve" "1 lb." +; + +set N := +calories /* Calories, unit = 1000 */ +protein /* Protein, unit = grams */ +calcium /* Calcium, unit = grams */ +iron /* Iron, unit = milligrams */ +vitaminA /* Vitamin A, unit = 1000 International Units */ +thiamine /* Thiamine, Vit. B1, unit = milligrams */ +riboflavin /* Riboflavin, Vit. B2, unit = milligrams */ +niacin /* Niacin (Nicotinic Acid), unit = milligrams */ +ascorbicAcid /* Ascorbic Acid, Vit. C, unit = milligrams */ +; + +param data +: price weight calories protein calcium iron := +# aug. 15 edible +# 1939 per $1 +# (cents) (grams) (1000) (grams) (grams) (mg.) +flour 36.0 12600 44.7 1411 2.0 365 +macaroni 14.1 3217 11.6 418 .7 54 +cereal 24.2 3280 11.8 377 14.4 175 +cornflakes 7.1 3194 11.4 252 .1 56 +cornmeal 4.6 9861 36.0 897 1.7 99 +grits 8.5 8005 28.6 680 .8 80 +rice 7.5 6048 21.2 460 .6 41 +oats 7.1 6389 25.3 907 5.1 341 +whitebread 7.9 5742 15.6 488 2.5 115 +wheatbread 9.1 4985 12.2 484 2.7 125 +ryebread 9.2 4930 12.4 439 1.1 82 +poundcake 24.8 1829 8.0 130 .4 31 +crackers 15.1 3004 12.5 288 .5 50 +milk 11.0 8867 6.1 310 10.5 18 +evapmild 6.7 6035 8.4 422 15.1 9 +butter 20.8 1473 10.8 9 .2 3 +margarine 16.1 2817 20.6 17 .6 6 +eggs 32.6 1857 2.9 238 1.0 52 +cheese 24.2 1874 7.4 448 16.4 19 +cream 14.1 1689 3.5 49 1.7 3 +peanutbutter 17.9 2534 15.7 661 1.0 48 +mayonnaise 16.7 1198 8.6 18 .2 8 +crisco 20.3 2234 20.1 0 .0 0 +lard 9.8 4628 41.7 0 .0 0 +sirloinsteak 39.6 1145 2.9 166 .1 34 +roundsteak 36.4 1246 2.2 214 .1 32 +ribroast 29.2 1553 3.4 213 .1 33 +chuckroast 22.6 2007 3.6 309 .2 46 +plate 14.6 3107 8.5 404 .2 62 +liver 26.8 1692 2.2 333 .2 139 +lambleg 27.6 1643 3.1 245 .1 20 +lambchops 36.6 1239 3.3 140 .1 15 +porkchops 30.7 1477 3.5 196 .2 80 +porkroast 24.2 1874 4.4 249 .3 37 +bacon 25.6 1772 10.4 152 .2 23 +ham 27.4 1655 6.7 212 .2 31 +saltpork 16.0 2835 18.8 164 .1 26 +chicken 30.3 1497 1.8 184 .1 30 +veal 42.3 1072 1.7 156 .1 24 +salmon 13.0 3489 5.8 705 6.8 45 +apples 4.4 9072 5.8 27 .5 36 +bananas 6.1 4982 4.9 60 .4 30 +lemons 26.0 2380 1.0 21 .5 14 +oranges 30.9 4439 2.2 40 1.1 18 +greenbeans 7.1 5750 2.4 138 3.7 80 +cabbage 3.7 8949 2.6 125 4.0 36 +carrots 4.7 6080 2.7 73 2.8 43 +celery 7.3 3915 .9 51 3.0 23 +lettuce 8.2 2247 .4 27 1.1 22 +onions 3.6 11844 5.8 166 3.8 59 +potatoes 34.0 16810 14.3 336 1.8 118 +spinach 8.1 4592 1.1 106 .0 138 +sweetpotato 5.1 7649 9.6 138 2.7 54 +peaches 16.8 4894 3.7 20 .4 10 +pears 20.4 4030 3.0 8 .3 8 +pineapple 21.3 3993 2.4 16 .4 8 +asparagus 27.7 1945 .4 33 .3 12 +cannedgrbn 10.0 5386 1.0 54 2.0 65 +porkbeans 7.1 6389 7.5 364 4.0 134 +corn 10.4 5452 5.2 136 .2 16 +peas 13.8 4109 2.3 136 .6 45 +tomatoes 8.6 6263 1.3 63 .7 38 +tomatosoup 7.6 3917 1.6 71 .6 43 +driedpeach 15.7 2889 8.5 87 1.7 173 +prunes 9.0 4284 12.8 99 2.5 154 +raisins 9.4 4524 13.5 104 2.5 136 +driedpeas 7.9 5742 20.0 1367 4.2 345 +limabeans 8.9 5097 17.4 1055 3.7 459 +navybeans 5.9 7688 26.9 1691 11.4 792 +coffee 22.4 2025 .0 0 .0 0 +tea 17.4 652 .0 0 .0 0 +cocoa 8.6 2637 8.7 237 3.0 72 +chocolate 16.2 1400 8.0 77 1.3 39 +sugar 51.7 8773 34.9 0 .0 0 +cornsirup 13.7 4996 14.7 0 .5 74 +molasses 13.6 3752 9.0 0 10.3 244 +strawberry 20.5 2213 6.4 11 .4 7 + +: vitaminA thiamine riboflavin niacin ascorbicAcid := +# (1000 IU) (mg.) (mg.) (mg.) (mg.) +flour .0 55.4 33.3 441 0 +macaroni .0 3.2 1.9 68 0 +cereal .0 14.4 8.8 114 0 +cornflakes .0 13.5 2.3 68 0 +cornmeal 30.9 17.4 7.9 106 0 +grits .0 10.6 1.6 110 0 +rice .0 2.0 4.8 60 0 +oats .0 37.1 8.9 64 0 +whitebread .0 13.8 8.5 126 0 +wheatbread .0 13.9 6.4 160 0 +ryebread .0 9.9 3.0 66 0 +poundcake 18.9 2.8 3.0 17 0 +crackers .0 .0 .0 0 0 +milk 16.8 4.0 16.0 7 177 +evapmild 26.0 3.0 23.5 11 60 +butter 44.2 .0 .2 2 0 +margarine 55.8 .2 .0 0 0 +eggs 18.6 2.8 6.5 1 0 +cheese 28.1 .8 10.3 4 0 +cream 16.9 .6 2.5 0 17 +peanutbutter .0 9.6 8.1 471 0 +mayonnaise 2.7 .4 .5 0 0 +crisco .0 .0 .0 0 0 +lard .2 .0 .5 5 0 +sirloinsteak .2 2.1 2.9 69 0 +roundsteak .4 2.5 2.4 87 0 +ribroast .0 .0 2.0 0 0 +chuckroast .4 1.0 4.0 120 0 +plate .0 .9 .0 0 0 +liver 169.2 6.4 50.8 316 525 +lambleg .0 2.8 3.0 86 0 +lambchops .0 1.7 2.7 54 0 +porkchops .0 17.4 2.7 60 0 +porkroast .0 18.2 3.6 79 0 +bacon .0 1.8 1.8 71 0 +ham .0 9.9 3.3 50 0 +saltpork .0 1.4 1.8 0 0 +chicken .1 .9 1.8 68 46 +veal .0 1.4 2.4 57 0 +salmon 3.5 1.0 4.9 209 0 +apples 7.3 3.6 2.7 5 544 +bananas 17.4 2.5 3.5 28 498 +lemons .0 .5 .0 4 952 +oranges 11.1 3.6 1.3 10 1993 +greenbeans 69.0 4.3 5.8 37 862 +cabbage 7.2 9.0 4.5 26 5369 +carrots 188.5 6.1 4.3 89 608 +celery .9 1.4 1.4 9 313 +lettuce 112.4 1.8 3.4 11 449 +onions 16.6 4.7 5.9 21 1184 +potatoes 6.7 29.4 7.1 198 2522 +spinach 918.4 5.7 13.8 33 2755 +sweetpotato 290.7 8.4 5.4 83 1912 +peaches 21.5 .5 1.0 31 196 +pears .8 .8 .8 5 81 +pineapple 2.0 2.8 .8 7 399 +asparagus 16.3 1.4 2.1 17 272 +cannedgrbn 53.9 1.6 4.3 32 431 +porkbeans 3.5 8.3 7.7 56 0 +corn 12.0 1.6 2.7 42 218 +peas 34.9 4.9 2.5 37 370 +tomatoes 53.2 3.4 2.5 36 1253 +tomatosoup 57.9 3.5 2.4 67 862 +driedpeach 86.8 1.2 4.3 55 57 +prunes 85.7 3.9 4.3 65 257 +raisins 4.5 6.3 1.4 24 136 +driedpeas 2.9 28.7 18.4 162 0 +limabeans 5.1 26.9 38.2 93 0 +navybeans .0 38.4 24.6 217 0 +coffee .0 4.0 5.1 50 0 +tea .0 .0 2.3 42 0 +cocoa .0 2.0 11.9 40 0 +chocolate .0 .9 3.4 14 0 +sugar .0 .0 .0 0 0 +cornsirup .0 .0 .0 5 0 +molasses .0 1.9 7.5 146 0 +strawberry .2 .2 .4 3 0 +; + +param allowance := +calories 3 +protein 70 +calcium .8 +iron 12 +vitaminA 5 +thiamine 1.8 +riboflavin 2.7 +niacin 18 +ascorbicAcid 75 +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/sudoku.dat b/resources/3rdparty/glpk-4.57/examples/sudoku.dat new file mode 100644 index 000000000..074ff4f8f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sudoku.dat @@ -0,0 +1,16 @@ +/* sudoku.dat, a hard Sudoku puzzle which causes branching */ + +data; + +param givens : 1 2 3 4 5 6 7 8 9 := + 1 1 . . . . . 7 . . + 2 . 2 . . . . 5 . . + 3 6 . . 3 8 . . . . + 4 . 7 8 . . . . . . + 5 . . . 6 . 9 . . . + 6 . . . . . . 1 4 . + 7 . . . . 2 5 . . 9 + 8 . . 3 . . . . 6 . + 9 . . 4 . . . . . 2 ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/sudoku.mod b/resources/3rdparty/glpk-4.57/examples/sudoku.mod new file mode 100644 index 000000000..61f2fe2bf --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/sudoku.mod @@ -0,0 +1,84 @@ +/* SUDOKU, Number Placement Puzzle */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* Sudoku, also known as Number Place, is a logic-based placement + puzzle. The aim of the canonical puzzle is to enter a numerical + digit from 1 through 9 in each cell of a 9x9 grid made up of 3x3 + subgrids (called "regions"), starting with various digits given in + some cells (the "givens"). Each row, column, and region must contain + only one instance of each numeral. + + Example: + + +-------+-------+-------+ + | 5 3 . | . 7 . | . . . | + | 6 . . | 1 9 5 | . . . | + | . 9 8 | . . . | . 6 . | + +-------+-------+-------+ + | 8 . . | . 6 . | . . 3 | + | 4 . . | 8 . 3 | . . 1 | + | 7 . . | . 2 . | . . 6 | + +-------+-------+-------+ + | . 6 . | . . . | 2 8 . | + | . . . | 4 1 9 | . . 5 | + | . . . | . 8 . | . 7 9 | + +-------+-------+-------+ + + (From Wikipedia, the free encyclopedia.) */ + +param givens{1..9, 1..9}, integer, >= 0, <= 9, default 0; +/* the "givens" */ + +var x{i in 1..9, j in 1..9, k in 1..9}, binary; +/* x[i,j,k] = 1 means cell [i,j] is assigned number k */ + +s.t. fa{i in 1..9, j in 1..9, k in 1..9: givens[i,j] != 0}: + x[i,j,k] = (if givens[i,j] = k then 1 else 0); +/* assign pre-defined numbers using the "givens" */ + +s.t. fb{i in 1..9, j in 1..9}: sum{k in 1..9} x[i,j,k] = 1; +/* each cell must be assigned exactly one number */ + +s.t. fc{i in 1..9, k in 1..9}: sum{j in 1..9} x[i,j,k] = 1; +/* cells in the same row must be assigned distinct numbers */ + +s.t. fd{j in 1..9, k in 1..9}: sum{i in 1..9} x[i,j,k] = 1; +/* cells in the same column must be assigned distinct numbers */ + +s.t. fe{I in 1..9 by 3, J in 1..9 by 3, k in 1..9}: + sum{i in I..I+2, j in J..J+2} x[i,j,k] = 1; +/* cells in the same region must be assigned distinct numbers */ + +/* there is no need for an objective function here */ + +solve; + +for {i in 1..9} +{ for {0..0: i = 1 or i = 4 or i = 7} + printf " +-------+-------+-------+\n"; + for {j in 1..9} + { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); + printf " %d", sum{k in 1..9} x[i,j,k] * k; + for {0..0: j = 9} printf(" |\n"); + } + for {0..0: i = 9} + printf " +-------+-------+-------+\n"; +} + +data; + +/* These data correspond to the example above. */ + +param givens : 1 2 3 4 5 6 7 8 9 := + 1 5 3 . . 7 . . . . + 2 6 . . 1 9 5 . . . + 3 . 9 8 . . . . 6 . + 4 8 . . . 6 . . . 3 + 5 4 . . 8 . 3 . . 1 + 6 7 . . . 2 . . . 6 + 7 . 6 . . . . 2 8 . + 8 . . . 4 1 9 . . 5 + 9 . . . . 8 . . 7 9 ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/t1.cs b/resources/3rdparty/glpk-4.57/examples/t1.cs new file mode 100644 index 000000000..d07780f4e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/t1.cs @@ -0,0 +1,99 @@ +/*Find the minimum value which satisfies the linear inequality: + a*x + b*y >= 1 {a,b,x,y Integers} {a,b > 0} {a,b entered on command line} + + Nigel_Galloway@operamail.com + February 2008 +*/ +using System; +using System.Runtime.InteropServices; + +unsafe class GLPK{ + double *lp; + public int a; + public int b; + + const string glpkLibrary = "libglpk.so"; + readonly int GLP_FR = 1; + readonly int GLP_IV = 2; + readonly int GLP_DB = 4; + struct ConstraintMatrix{ + public fixed int ia[3]; + public fixed int ja[3]; + public fixed double ar[3]; + } + [DllImport(glpkLibrary, SetLastError=true)] + static extern double* glp_create_prob(); + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_add_rows(double* lp, int rows); + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_add_cols(double* lp, int cols); + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_set_col_bnds(double* lp, int col, int bound_type, double lower_bound, double upper_bound); + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_set_col_kind(double* lp, int col, int kind); + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_load_matrix(double* lp, int elements, int* ia, int* ja, double* ar); + public GLPK(int a, int b){ + this.a = a; + this.b = b; + lp = glp_create_prob(); + //Col 1 is x, Col 2 is y + glp_add_rows(lp, 1); + glp_add_cols(lp, 2); + glp_set_col_bnds(lp, 1, GLP_FR, 0.0, 0.0); + glp_set_col_bnds(lp, 2, GLP_FR, 0.0, 0.0); + glp_set_col_kind(lp, 1, GLP_IV); + glp_set_col_kind(lp, 2, GLP_IV); + //Row 1 is a*x + b*y + ConstraintMatrix CM = new ConstraintMatrix(); + CM.ia[1]=1; CM.ja[1]=1; CM.ar[1]=a; + CM.ia[2]=1; CM.ja[2]=2; CM.ar[2]=b; + glp_load_matrix(lp, 2, CM.ia, CM.ja, CM.ar); + Console.WriteLine("Hello Nigel"); + } + + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_set_row_bnds(double* lp, int row, int bound_type, double lower_bound, double upper_bound); + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_simplex(double* lp, void* options); + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_intopt(double* lp, void* options); + [DllImport(glpkLibrary, SetLastError=true)] + static extern double glp_mip_col_val(double* lp, int col); + public int betterGuess(int upper_bound){ + //Find a new guess less than the old guess: 1 <= (a*x + b*y) <= (old guess - 1) + glp_set_row_bnds(lp, 1, GLP_DB, 1.0, ((double)upper_bound)-0.5); + glp_simplex(lp, null); + glp_intopt(lp, null); + int x = (int)glp_mip_col_val(lp, 1); + int y = (int)glp_mip_col_val(lp, 2); + int nextGuess = a*x + b*y; + Console.WriteLine("x = {0}, y = {1}, a*x + b*y = {2}",x,y,nextGuess); + return nextGuess; + } + + [DllImport(glpkLibrary, SetLastError=true)] + static extern void glp_delete_prob(double* lp); + ~GLPK(){ + glp_delete_prob(lp); + Console.WriteLine("Goodbye Nigel"); + } + +} + +class test{ + static bool isMinimum(int a, int b, int guess){ + Console.WriteLine("Trying {0}",guess); + if (a%guess > 0) return false; + if (b%guess > 0) return false; + Console.WriteLine("Solution is {0}",guess); + return true; + } + + public static void Main(string[] args){ + Console.WriteLine("a = {0}, b = {1}",args[0], args[1]); + GLPK lp = new GLPK(Int32.Parse(args[0]),Int32.Parse(args[1])); + int guess = (lp.a > lp.b) ? lp.b : lp.a; + while (!isMinimum(lp.a,lp.b,guess)) guess = lp.betterGuess(guess); + } +} diff --git a/resources/3rdparty/glpk-4.57/examples/tas.mod b/resources/3rdparty/glpk-4.57/examples/tas.mod new file mode 100644 index 000000000..dbb5ac2da --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tas.mod @@ -0,0 +1,486 @@ +/* TAS, Tail Assignment Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* The Tail Assignment Problem (TAS) is to construct rosters for a set + of aircrafts (tails), which cover all flights for a given scheduling + period. + + This model includes only flight connection constraints while other + constraints (for example, maintenance constraints) are ignored. Such + simplification allows using a single commodity network to model the + problem, where commodity corresponds to the set of aircrafts. + + Nodes of the network are activities. They include all flights plus + two dummy nodes (activities): source node, s, corresponding to + initial activity of each aircraft, and sink node t, corresponding to + final activity of each aircraft. Arc v->v' exists in the network if + and only if the same aircraft is able to operate activity v and then + immediately activity v'. In partucular, arcs s->f and f->t exist for + all flights f. Arcs f->f', where f and f' are some flights, exist + only if the connection time (which is the difference between the + departure time of f' and the arrival time of f) is not less than a + given minimal connection time. + + Reference: + M. Groenkvist, "The Tail Assignment Problem," Dept. of Comp. Sci. + and Eng., Chalmers University of Technology and Goeteborg University, + Goeteborg, Sweden, August 2005. */ + +######################################################################## + +param nf, integer, > 0; +/* number of flights */ + +set F := 1..nf; +/* set of flights (for a given period from timetable) */ + +param hub{f in F}, in {1, 2}; +/* hub[f] = 1: Sheremetyevo-1 + hub[f] = 2: Sheremetyevo-2 */ + +param dest{f in F}, symbolic; +/* destination airport (IATA code) */ + +param fno1{f in F}, integer; +/* first leg flight number */ + +param dep1{f in F}, integer, >= 0; +/* departure time from Sheremetyevo airport, in minutes */ + +check{f in F: f < nf}: dep1[f] <= dep1[f+1]; +/* all flights must be ordered by ascending of the departure time */ + +param arr1{f in F}, integer, >= 0; +/* arrival time to destination airport, in minutes */ + +param fno2{f in F}, integer; +/* second leg flight number */ + +param dep2{f in F}, integer, >= 0; +/* departure time from destination airport, in minutes */ + +param arr2{f in F}, integer, >= 0; +/* arrival time to Sheremetyevo airport, in minutes */ + +param mct1, integer, >= 0, default 80; +/* minimal connection time (within SVO1 or SVO2), in minutes */ + +param mct2, integer, >= 0, default 150; +/* minimal connection time (between SVO1 and SVO2), in minutes */ + +set E := setof{f in F, ff in F: arr2[f] + (if hub[f] = hub[ff] then + mct1 else mct2) <= dep1[ff]} (f, ff); +/* connection network; arc f->ff is in E, iff the same aircraft can be + assigned to flight f and then immediately to flight ff */ + +var s{f in F}, >= 0; +/* s[f] is a flow from source node to node f */ + +var x{(f,ff) in E}, >= 0; +/* x[f,ff] is a flow from node f to node ff */ + +var t{f in F}, >= 0; +/* t[f] is a flow from node f to sink node */ + +s.t. into{f in F}: s[f] + sum{(ff,f) in E} x[ff,f] = 1; +/* exactly one aircraft must come into each node f */ + +s.t. from{f in F}: t[f] + sum{(f,ff) in E} x[f,ff] = 1; +/* exactly one aircraft must come from each node f */ + +minimize obj: sum{f in F} s[f]; +/* minimize the number aircrafts sufficient to cover all flights */ + +solve; + +######################################################################## + +param na := floor(sum{f in F} s[f] + .5); +/* minimal number of aircrafts found */ + +printf "At least %d aircrafts needed\n", na; + +set A := 1..na; +/* set of aircrafts */ + +printf "Building rosters...\n"; + +param tail{f in F}, in A, := +/* tail[f] is the number of an aircraft assigned to flight f */ + + if f = 1 then 1 + /* assign aircraft 1 to the earliest flight */ + + else if s[f] >= 0.9 then (max{ff in 1..f-1} tail[ff]) + 1 + /* if f is the first flight in a roster, assign to it a next + aircraft */ + + else sum{(ff,f) in E} tail[ff] * (if x[ff,f] >= 0.9 then 1); + /* otherwise, assign to flight f the same aircraft, which is + assigned to a preceding flight in the roster */ + +######################################################################## + +param file, symbolic, default "tas.ps"; +/* file to output the assignment chart in postscript format */ + +param title, symbolic, default "(no title)"; +/* chart title */ + +param left, default 25; +/* left margin, in mm */ + +param top, default 25; +/* top margin, in mm */ + +param right, default 20; +/* right margin, in mm */ + +param bottom, default 15; +/* bottom margin, in mm */ + +param sx := 297 - left - right; +/* chart area horizontal size, in mm */ + +param sy := 210 - top - bottom; +/* chart area vertical size, in mm */ + +param gap, default sy / (na - 1); +/* gap between rosters, in mm */ + +printf "Writing assignment chart to %s...\n", file; + +printf "%%!PS-Adobe-3.0\n" > file; +printf "%%%%Title: Tail Assignment Chart\n" >> file; +printf "%%%%Creator: GLPK MathProg\n" >> file; +printf "%%%%BoundingBox: 0 0 595 842\n" >> file; +printf "%%%%EndComments\n" >> file; +printf "<> setpagedevice\n" >> file; +printf "72 25.4 div dup scale\n" >> file; +printf "210 %.3f sub %.3f translate\n", bottom, left >> file; +printf "90 rotate\n" >> file; + +printf "/HelveticaBold findfont 5 scalefont setfont\n" >> file; +printf "%.3f %.3f moveto (%s) dup show\n", 0, sy + 5, title >> file; + +param period := floor((max{f in F} arr2[f]) / 60. + .5); +/* period duration, in hours */ + +/* vertical bars */ +printf ".8 .8 .8 setrgbcolor\n" >> file; +for {tt in 0..period} +{ printf "%s setlinewidth\n", + if tt mod 24 = 0 then ".5" else "0" >> file; + printf "newpath %.3f %.3f moveto %.3f %.3f lineto stroke\n", + tt * (sx / period), 0, tt * (sx / period), + sy + (if tt mod 24 = 0 then 2) >> file; +} + +/* rosters */ +for {a in A} +{ printf "0 0 0 setrgbcolor\n" >> file; + printf "0 setlinewidth\n" >> file; + printf "newpath %.3f %.3f moveto %.3f %.3f lineto stroke\n", + 0, sy - gap * (a - 1), sx, sy - gap * (a - 1) >> file; + printf "/Dingbats findfont 4 scalefont setfont\n" >> file; + printf "%.3f %.3f moveto <28> dup show\n", + -4, sy - gap * (a - 1) - 1.4, a >> file; + printf "/Helvetica findfont 3 scalefont setfont\n" >> file; + printf "%.3f %.3f moveto (%2d) dup show\n", + -9, sy - gap * (a - 1) - 1.2, a >> file; + for {f in F: tail[f] == a} + { printf "0 0 %s setrgbcolor\n", + if hub[f] = 1 then "0" else ".8" >> file; + printf "1 setlinewidth\n" >> file; + printf "newpath %.3f %.3f moveto %.3f %.3f lineto stroke\n", + dep1[f] / 60 * (sx / period), sy - gap * (a - 1), + arr2[f] / 60 * (sx / period), sy - gap * (a - 1) >> file; + printf "/Helvetica findfont 1.8 scalefont setfont\n" >> file; + printf "%.3f %.3f moveto (%02d:%02d %s) dup show\n", + dep1[f] / 60 * (sx / period), sy - gap * (a - 1) + .8, + (dep1[f] mod 1440) div 60, (dep1[f] mod 1440) mod 60, + dest[f] >> file; + printf "%.3f %.3f moveto (%d %02d:%02d) dup show\n", + dep1[f] / 60 * (sx / period), sy - gap * (a - 1) - 2.1, + fno1[f], + (arr2[f] mod 1440) div 60, (arr2[f] mod 1440) mod 60 >> file; + } +} + +printf "showpage\n" >> file; +printf "%%%%EOF\n" >> file; + +######################################################################## + +data; + +param title := "Tu-154 [from 2008-08-18 to 2008-08-24]"; + +param nf := 261; + +param : hub dest fno1 dep1 arr1 fno2 dep2 arr2 := + 1 1 IKT 743 195 520 744 610 970 + 2 1 OMS 815 205 405 816 485 700 + 3 1 CEK 897 205 360 898 430 595 + 4 1 KRR 763 260 400 764 480 610 + 5 2 SIP 133 280 420 134 500 620 + 6 2 BUD 131 290 450 132 520 675 + 7 1 AAQ 701 305 440 702 510 640 + 8 1 MRV 785 310 440 786 520 650 + 9 2 WAW 101 355 475 102 540 660 + 10 2 GYD 147 370 550 148 675 860 + 11 1 AER 869 385 530 870 655 795 + 12 1 KRR 765 430 560 766 630 760 + 13 1 AAQ 703 520 660 704 740 850 + 14 1 LED 845 530 620 846 690 775 + 15 1 KRR 767 540 675 768 765 895 + 16 2 KBP 183 665 760 184 850 940 + 17 1 MRV 787 755 905 788 985 1135 + 18 1 KRR 771 810 940 772 1030 1165 + 19 1 LED 849 825 900 850 960 1095 + 20 2 IST 209 880 1050 210 1120 1280 + 21 1 AER 873 885 1030 874 1760 1900 + 22 1 ASF 711 995 1145 712 1640 1795 + 23 2 ULN 563 995 1335 564 1415 1815 + 24 2 OTP 151 1020 1175 152 1800 1940 + 25 2 BEY 509 1025 1265 510 1350 1580 + 26 2 OSL 211 1060 1220 212 1860 2015 + 27 1 IKT 739 1085 1420 740 1510 1870 + 28 1 KRR 773 1095 1240 774 1620 1765 + 29 1 SGC 877 1120 1315 878 1395 1625 + 30 1 LED 857 1150 1230 858 1610 1690 + 31 1 CEK 899 1230 1385 900 1455 1620 + 32 1 PEE 821 1235 1390 822 1450 1600 + 33 2 TBS 197 1240 1405 198 1560 1715 + 34 1 UFA 891 1275 1405 892 1475 1610 + 35 1 KJA 781 1300 1570 782 1680 1990 + 36 1 IKT 743 1635 1960 744 2050 2410 + 37 1 OMS 815 1645 1845 816 1925 2140 + 38 1 CEK 897 1645 1800 898 1870 2035 + 39 1 KRR 763 1700 1840 764 1920 2050 + 40 2 SIP 133 1720 1860 134 1940 2060 + 41 2 BUD 131 1730 1890 132 1960 2115 + 42 1 AAQ 701 1745 1880 702 1950 2080 + 43 1 MRV 785 1750 1880 786 1960 2090 + 44 2 WAW 101 1795 1915 102 1980 2100 + 45 2 GYD 147 1810 1990 148 2115 2300 + 46 1 AER 869 1825 1970 870 2095 2235 + 47 2 EVN 193 1850 2030 194 2105 2275 + 48 1 KRR 765 1870 2000 766 2070 2200 + 49 1 AAQ 703 1960 2100 704 2180 2290 + 50 1 LED 845 1970 2060 846 2130 2215 + 51 1 KRR 767 1980 2115 768 2205 2335 + 52 2 KBP 183 2105 2200 184 2290 2380 + 53 1 MRV 787 2195 2345 788 2425 2575 + 54 1 KRR 771 2250 2380 772 2470 2605 + 55 1 LED 849 2265 2340 850 2400 2535 + 56 2 IST 209 2320 2490 210 2560 2720 + 57 1 AER 873 2325 2470 874 3200 3340 + 58 2 ULN 563 2435 2775 564 2855 3255 + 59 1 ASF 711 2435 2585 712 3080 3235 + 60 2 DAM 517 2465 2705 518 2790 3020 + 61 2 OSL 211 2500 2660 212 3300 3455 + 62 2 KBP 185 2510 2610 186 3160 3250 + 63 1 IKT 739 2525 2860 740 2950 3310 + 64 1 KRR 773 2535 2680 774 3060 3205 + 65 1 SGC 877 2560 2755 878 2835 3065 + 66 1 LED 857 2590 2670 858 3050 3130 + 67 1 CEK 899 2670 2825 900 2895 3060 + 68 1 PEE 821 2675 2830 822 2890 3040 + 69 2 TBS 197 2680 2845 198 3000 3155 + 70 1 UFA 891 2715 2845 892 2915 3050 + 71 1 KJA 781 2740 3010 782 3120 3430 + 72 1 IKT 743 3075 3400 744 3490 3850 + 73 1 CEK 897 3085 3240 898 3310 3475 + 74 1 OMS 815 3085 3285 816 3365 3580 + 75 1 KRR 763 3140 3280 764 3360 3490 + 76 2 SIP 133 3160 3300 134 3380 3500 + 77 2 BUD 131 3170 3330 132 3400 3555 + 78 1 AAQ 701 3185 3320 702 3390 3520 + 79 1 MRV 785 3190 3320 786 3400 3530 + 80 2 WAW 101 3235 3355 102 3420 3540 + 81 2 FRU 181 3245 3495 182 3590 3860 + 82 2 GYD 147 3250 3430 148 3555 3740 + 83 1 AER 869 3265 3410 870 3535 3675 + 84 1 KRR 765 3310 3440 766 3510 3640 + 85 1 AAQ 703 3400 3540 704 3620 3730 + 86 1 LED 845 3410 3500 846 3570 3655 + 87 1 KRR 767 3420 3555 768 3645 3775 + 88 2 KBP 183 3545 3640 184 3730 3820 + 89 1 MRV 787 3635 3785 788 3865 4015 + 90 1 KRR 771 3690 3820 772 3910 4045 + 91 1 LED 849 3705 3780 850 3840 3975 + 92 2 IST 209 3760 3930 210 4000 4160 + 93 1 AER 873 3765 3910 874 4640 4780 + 94 2 ULN 563 3875 4215 564 4295 4695 + 95 1 ASF 711 3875 4025 712 4520 4675 + 96 2 OTP 151 3900 4055 152 4680 4820 + 97 2 BEY 509 3905 4145 510 4230 4460 + 98 2 OSL 211 3940 4100 212 4740 4895 + 99 2 KBP 185 3950 4050 186 4600 4690 + 100 1 IKT 739 3965 4300 740 4390 4750 + 101 1 KRR 773 3975 4120 774 4500 4645 + 102 1 SGC 877 4000 4195 878 4275 4505 + 103 1 LED 857 4030 4110 858 4490 4570 + 104 1 CEK 899 4110 4265 900 4335 4500 + 105 1 PEE 821 4115 4270 822 4330 4480 + 106 2 TBS 197 4120 4285 198 4440 4595 + 107 1 UFA 891 4155 4285 892 4355 4490 + 108 1 KJA 781 4180 4450 782 4560 4870 + 109 1 IKT 743 4515 4840 744 4930 5290 + 110 1 OMS 815 4525 4725 816 4805 5020 + 111 1 CEK 897 4525 4680 898 4750 4915 + 112 1 KRR 763 4580 4720 764 4800 4930 + 113 2 SIP 133 4600 4740 134 4820 4940 + 114 2 BUD 131 4610 4770 132 4840 4995 + 115 1 AAQ 701 4625 4760 702 4830 4960 + 116 1 MRV 785 4630 4760 786 4840 4970 + 117 2 WAW 101 4675 4795 102 4860 4980 + 118 2 GYD 147 4690 4870 148 4995 5180 + 119 1 AER 869 4705 4850 870 4975 5115 + 120 2 EVN 193 4730 4910 194 4985 5155 + 121 1 KRR 765 4750 4880 766 4950 5080 + 122 1 AAQ 703 4840 4980 704 5060 5170 + 123 1 LED 845 4850 4940 846 5010 5095 + 124 1 KRR 767 4860 4995 768 5085 5215 + 125 2 KBP 183 4985 5080 184 5170 5260 + 126 1 MRV 787 5075 5225 788 5305 5455 + 127 1 KRR 771 5130 5260 772 5350 5485 + 128 1 LED 849 5145 5220 850 5280 5415 + 129 2 IST 209 5200 5370 210 5440 5600 + 130 1 AER 873 5205 5350 874 6080 6220 + 131 1 ASF 711 5315 5465 712 5960 6115 + 132 2 ULN 563 5315 5655 564 5735 6135 + 133 2 DAM 517 5345 5585 518 5670 5900 + 134 2 OSL 211 5380 5540 212 6180 6335 + 135 2 KBP 185 5390 5490 186 6040 6130 + 136 1 IKT 739 5405 5740 740 5830 6190 + 137 1 KRR 773 5415 5560 774 5940 6085 + 138 1 SGC 877 5440 5635 878 5715 5945 + 139 1 LED 857 5470 5550 858 5930 6010 + 140 1 CEK 899 5550 5705 900 5775 5940 + 141 1 PEE 821 5555 5710 822 5770 5920 + 142 2 TBS 197 5560 5725 198 5880 6035 + 143 1 UFA 891 5595 5725 892 5795 5930 + 144 1 KJA 781 5620 5890 782 6000 6310 + 145 1 IKT 743 5955 6280 744 6370 6730 + 146 1 OMS 815 5965 6165 816 6245 6460 + 147 1 CEK 897 5965 6120 898 6190 6355 + 148 1 KRR 763 6020 6160 764 6240 6370 + 149 2 SIP 133 6040 6180 134 6260 6380 + 150 2 BUD 131 6050 6210 132 6280 6435 + 151 1 AAQ 701 6065 6200 702 6270 6400 + 152 1 MRV 785 6070 6200 786 6280 6410 + 153 2 WAW 101 6115 6235 102 6300 6420 + 154 2 FRU 181 6125 6375 182 6470 6740 + 155 2 GYD 147 6130 6310 148 6435 6620 + 156 1 AER 869 6145 6290 870 6415 6555 + 157 2 EVN 193 6170 6350 194 6425 6595 + 158 1 KRR 765 6190 6320 766 6390 6520 + 159 1 AAQ 703 6280 6420 704 6500 6610 + 160 1 LED 845 6290 6380 846 6450 6535 + 161 1 KRR 767 6300 6435 768 6525 6655 + 162 2 KBP 183 6425 6520 184 6610 6700 + 163 2 AYT 223 6500 6690 224 6750 6940 + 164 1 AER 867 6510 6660 868 6730 6880 + 165 1 MRV 787 6515 6665 788 6745 6895 + 166 1 KRR 771 6570 6700 772 6790 6925 + 167 1 LED 849 6585 6660 850 6720 6855 + 168 2 IST 209 6640 6810 210 6880 7040 + 169 1 AER 873 6645 6790 874 7520 7660 + 170 1 ASF 711 6755 6905 712 7400 7555 + 171 2 ULN 563 6755 7095 564 7175 7575 + 172 2 OTP 151 6780 6935 152 7560 7700 + 173 2 BEY 509 6785 7025 510 7110 7340 + 174 2 OSL 211 6820 6980 212 7620 7775 + 175 2 KBP 185 6830 6930 186 7480 7570 + 176 1 IKT 739 6845 7180 740 7270 7630 + 177 1 KRR 773 6855 7000 774 7380 7525 + 178 1 SGC 877 6880 7075 878 7155 7385 + 179 1 LED 857 6910 6990 858 7370 7450 + 180 1 CEK 899 6990 7145 900 7215 7380 + 181 1 PEE 821 6995 7150 822 7210 7360 + 182 2 TBS 197 7000 7165 198 7320 7475 + 183 1 UFA 891 7035 7165 892 7235 7370 + 184 1 KJA 781 7060 7330 782 7440 7750 + 185 1 IKT 743 7395 7720 744 7810 8170 + 186 1 CEK 897 7405 7560 898 7630 7795 + 187 1 KRR 763 7460 7600 764 7680 7810 + 188 2 SIP 133 7480 7620 134 7700 7820 + 189 2 BUD 131 7490 7650 132 7720 7875 + 190 1 AAQ 701 7505 7640 702 7710 7840 + 191 1 MRV 785 7510 7640 786 7720 7850 + 192 2 IST 207 7545 7720 208 7795 7985 + 193 2 WAW 101 7555 7675 102 7740 7860 + 194 2 GYD 147 7570 7750 148 7875 8060 + 195 1 AER 869 7585 7730 870 7855 7995 + 196 2 AYT 221 7610 7800 222 7895 8085 + 197 2 EVN 193 7610 7790 194 7865 8035 + 198 1 KRR 765 7630 7760 766 7830 7960 + 199 1 AAQ 703 7720 7860 704 7940 8050 + 200 1 LED 845 7730 7820 846 7890 7975 + 201 1 KRR 767 7740 7875 768 7965 8095 + 202 2 KBP 183 7865 7960 184 8050 8140 + 203 2 AYT 223 7940 8130 224 8190 8380 + 204 1 MRV 787 7955 8105 788 8185 8335 + 205 1 KRR 771 8010 8140 772 8230 8365 + 206 1 LED 849 8025 8100 850 8160 8295 + 207 2 IST 209 8080 8250 210 8320 8480 + 208 1 AER 873 8085 8230 874 8960 9100 + 209 1 ASF 711 8195 8345 712 8840 8995 + 210 2 ULN 563 8195 8535 564 8615 9015 + 211 1 KJA 779 8230 8500 780 8575 8870 + 212 2 OSL 211 8260 8420 212 9060 9215 + 213 2 KBP 185 8270 8370 186 8920 9010 + 214 1 IKT 739 8285 8620 740 8710 9070 + 215 1 KRR 773 8295 8440 774 8820 8965 + 216 1 SGC 877 8320 8515 878 8595 8825 + 217 1 LED 857 8350 8430 858 8810 8890 + 218 1 CEK 899 8430 8585 900 8655 8820 + 219 1 PEE 821 8435 8590 822 8650 8800 + 220 2 TBS 197 8440 8605 198 8760 8915 + 221 1 UFA 891 8475 8605 892 8675 8810 + 222 1 KJA 781 8500 8770 782 8880 9190 + 223 1 IKT 743 8835 9160 744 9250 9610 + 224 1 OMS 815 8845 9045 816 9125 9340 + 225 1 CEK 897 8845 9000 898 9070 9235 + 226 1 KRR 763 8900 9040 764 9120 9250 + 227 2 SIP 133 8920 9060 134 9140 9260 + 228 2 BUD 131 8930 9090 132 9160 9315 + 229 1 AAQ 701 8945 9080 702 9150 9280 + 230 1 MRV 785 8950 9080 786 9160 9290 + 231 2 IST 207 8985 9160 208 9235 9425 + 232 2 WAW 101 8995 9115 102 9180 9300 + 233 2 FRU 181 9005 9255 182 9350 9620 + 234 2 GYD 147 9010 9190 148 9315 9500 + 235 1 AER 869 9025 9170 870 9295 9435 + 236 2 EVN 193 9050 9230 194 9305 9475 + 237 1 KRR 765 9070 9200 766 9270 9400 + 238 1 AAQ 703 9160 9300 704 9380 9490 + 239 1 LED 845 9170 9260 846 9330 9415 + 240 1 KRR 767 9180 9315 768 9405 9535 + 241 2 KBP 183 9305 9400 184 9490 9580 + 242 2 AYT 223 9380 9570 224 9630 9820 + 243 1 MRV 787 9395 9545 788 9625 9775 + 244 1 KRR 771 9450 9580 772 9670 9805 + 245 1 LED 849 9465 9540 850 9600 9735 + 246 2 IST 209 9520 9690 210 9760 9920 + 247 1 AER 873 9525 9670 874 10400 10540 + 248 1 ASF 711 9635 9785 712 10280 10435 + 249 2 ULN 563 9635 9975 564 10055 10455 + 250 2 OTP 151 9660 9815 152 10440 10580 + 251 2 DAM 517 9665 9905 518 9990 10220 + 252 2 OSL 211 9700 9860 212 10500 10655 + 253 2 KBP 185 9710 9810 186 10360 10450 + 254 1 IKT 739 9725 10060 740 10150 10510 + 255 1 KRR 773 9735 9880 774 10260 10405 + 256 1 SGC 877 9760 9955 878 10035 10265 + 257 1 LED 857 9790 9870 858 10250 10330 + 258 1 CEK 899 9870 10025 900 10095 10260 + 259 1 PEE 821 9875 10030 822 10090 10240 + 260 1 UFA 891 9915 10045 892 10115 10250 + 261 1 KJA 781 9940 10210 782 10320 10630 +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/todd.mod b/resources/3rdparty/glpk-4.57/examples/todd.mod new file mode 100644 index 000000000..c0ef44b4c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/todd.mod @@ -0,0 +1,36 @@ +/* TODD, a class of hard instances of zero-one knapsack problems */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* Chvatal describes a class of instances of zero-one knapsack problems + due to Todd. He shows that a wide class of algorithms - including all + based on branch and bound or dynamic programming - find it difficult + to solve problems in the Todd class. More exactly, the time required + by these algorithms to solve instances of problems that belong to the + Todd class grows as an exponential function of the problem size. + + Reference: + Chvatal V. (1980), Hard knapsack problems, Op. Res. 28, 1402-1411. */ + +param n > 0 integer; + +param log2_n := log(n) / log(2); + +param k := floor(log2_n); + +param a{j in 1..n} := 2 ** (k + n + 1) + 2 ** (k + n + 1 - j) + 1; + +param b := 0.5 * floor(sum{j in 1..n} a[j]); + +var x{1..n} binary; + +maximize obj: sum{j in 1..n} a[j] * x[j]; + +s.t. cap: sum{j in 1..n} a[j] * x[j] <= b; + +data; + +param n := 15; +/* change this parameter to choose a particular instance */ + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/train.mod b/resources/3rdparty/glpk-4.57/examples/train.mod new file mode 100644 index 000000000..a17520ea1 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/train.mod @@ -0,0 +1,281 @@ +# TRAIN, a model of railroad passenger car allocation +# +# References: +# Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language +# for Mathematical Programming." Management Science 36 (1990) 519-554. + +### SCHEDULE SETS AND PARAMETERS ### + +set cities; + +set links within {c1 in cities, c2 in cities: c1 <> c2}; + + # Set of cities, and set of intercity links + +param last > 0 integer; # Number of time intervals in a day + +set times := 1..last; # Set of time intervals in a day + +set schedule within + {c1 in cities, t1 in times, + c2 in cities, t2 in times: (c1,c2) in links}; + + # Member (c1,t1,c2,t2) of this set represents + # a train that leaves city c1 at time t1 + # and arrives in city c2 at time t2 + +### DEMAND PARAMETERS ### + +param section > 0 integer; + + # Maximum number of cars in one section of a train + +param demand {schedule} > 0; + + # For each scheduled train: + # the smallest number of cars that + # can meet demand for the train + +param low {(c1,t1,c2,t2) in schedule} := ceil(demand[c1,t1,c2,t2]); + + # Minimum number of cars needed to meet demand + +param high {(c1,t1,c2,t2) in schedule} + + := max (2, min (ceil(2*demand[c1,t1,c2,t2]), + section*ceil(demand[c1,t1,c2,t2]/section) )); + + # Maximum number of cars allowed on a train: + # 2 if demand is for less than one car; + # otherwise, lesser of + # number of cars needed to hold twice the demand, and + # number of cars in minimum number of sections needed + +### DISTANCE PARAMETERS ### + +param dist_table {links} >= 0 default 0.0; + +param distance {(c1,c2) in links} > 0 + := if dist_table[c1,c2] > 0 then dist_table[c1,c2] else dist_table[c2,c1]; + + # Inter-city distances: distance[c1,c2] is miles + # between city c1 and city c2 + +### VARIABLES ### + +var U 'cars stored' {cities,times} >= 0; + + # u[c,t] is the number of unused cars stored + # at city c in the interval beginning at time t + +var X 'cars in train' {schedule} >= 0; + + # x[c1,t1,c2,t2] is the number of cars assigned to + # the scheduled train that leaves c1 at t1 and + # arrives in c2 at t2 + +### OBJECTIVES ### + +minimize cars: + sum {c in cities} U[c,last] + + sum {(c1,t1,c2,t2) in schedule: t2 < t1} X[c1,t1,c2,t2]; + + # Number of cars in the system: + # sum of unused cars and cars in trains during + # the last time interval of the day + +minimize miles: + sum {(c1,t1,c2,t2) in schedule} distance[c1,c2] * X[c1,t1,c2,t2]; + + # Total car-miles run by all scheduled trains in a day + +### CONSTRAINTS ### + +account {c in cities, t in times}: + + U[c,t] = U[c, if t > 1 then t-1 else last] + + + sum {(c1,t1,c,t) in schedule} X[c1,t1,c,t] - + sum {(c,t,c2,t2) in schedule} X[c,t,c2,t2]; + + # For every city and time: + # unused cars in the present interval must equal + # unused cars in the previous interval, + # plus cars just arriving in trains, + # minus cars just leaving in trains + +satisfy {(c1,t1,c2,t2) in schedule}: + + low[c1,t1,c2,t2] <= X[c1,t1,c2,t2] <= high[c1,t1,c2,t2]; + + # For each scheduled train: + # number of cars must meet demand, + # but must not be so great that unnecessary + # sections are run + +### DATA ### + +data; + +set cities := BO NY PH WA ; + +set links := (BO,NY) (NY,PH) (PH,WA) + (NY,BO) (PH,NY) (WA,PH) ; + +param dist_table := [*,*] BO NY 232 + NY PH 90 + PH WA 135 ; + +param last := 48 ; + +param section := 14 ; + +set schedule := + + (WA,*,PH,*) 2 5 6 9 8 11 10 13 + 12 15 13 16 14 17 15 18 + 16 19 17 20 18 21 19 22 + 20 23 21 24 22 25 23 26 + 24 27 25 28 26 29 27 30 + 28 31 29 32 30 33 31 34 + 32 35 33 36 34 37 35 38 + 36 39 37 40 38 41 39 42 + 40 43 41 44 42 45 44 47 + 46 1 + + (PH,*,NY,*) 1 3 5 7 9 11 11 13 + 13 15 14 16 15 17 16 18 + 17 19 18 20 19 21 20 22 + 21 23 22 24 23 25 24 26 + 25 27 26 28 27 29 28 30 + 29 31 30 32 31 33 32 34 + 33 35 34 36 35 37 36 38 + 37 39 38 40 39 41 40 42 + 41 43 42 44 43 45 44 46 + 45 47 47 1 + + (NY,*,BO,*) 10 16 12 18 14 20 15 21 + 16 22 17 23 18 24 19 25 + 20 26 21 27 22 28 23 29 + 24 30 25 31 26 32 27 33 + 28 34 29 35 30 36 31 37 + 32 38 33 39 34 40 35 41 + 36 42 37 43 38 44 39 45 + 40 46 41 47 42 48 43 1 + 44 2 45 3 46 4 48 6 + + (BO,*,NY,*) 7 13 9 15 11 17 12 18 + 13 19 14 20 15 21 16 22 + 17 23 18 24 19 25 20 26 + 21 27 22 28 23 29 24 30 + 25 31 26 32 27 33 28 34 + 29 35 30 36 31 37 32 38 + 33 39 34 40 35 41 36 42 + 37 43 38 44 39 45 40 46 + 41 47 43 1 45 3 47 5 + + (NY,*,PH,*) 1 3 12 14 13 15 14 16 + 15 17 16 18 17 19 18 20 + 19 21 20 22 21 23 22 24 + 23 25 24 26 25 27 26 28 + 27 29 28 30 29 31 30 32 + 31 33 32 34 33 35 34 36 + 35 37 36 38 37 39 38 40 + 39 41 40 42 41 43 42 44 + 43 45 44 46 45 47 46 48 + 47 1 + + (PH,*,WA,*) 1 4 14 17 15 18 16 19 + 17 20 18 21 19 22 20 23 + 21 24 22 25 23 26 24 27 + 25 28 26 29 27 30 28 31 + 29 32 30 33 31 34 32 35 + 33 36 34 37 35 38 36 39 + 37 40 38 41 39 42 40 43 + 41 44 42 45 43 46 44 47 + 45 48 46 1 47 2 ; + +param demand := + + [WA,*,PH,*] 2 5 .55 6 9 .01 8 11 .01 + 10 13 .13 12 15 1.59 13 16 1.69 + 14 17 5.19 15 18 3.55 16 19 6.29 + 17 20 4.00 18 21 5.80 19 22 3.40 + 20 23 4.88 21 24 2.92 22 25 4.37 + 23 26 2.80 24 27 4.23 25 28 2.88 + 26 29 4.33 27 30 3.11 28 31 4.64 + 29 32 3.44 30 33 4.95 31 34 3.73 + 32 35 5.27 33 36 3.77 34 37 4.80 + 35 38 3.31 36 39 3.89 37 40 2.65 + 38 41 3.01 39 42 2.04 40 43 2.31 + 41 44 1.52 42 45 1.75 44 47 1.88 + 46 1 1.05 + + [PH,*,NY,*] 1 3 1.05 5 7 .43 9 11 .20 + 11 13 .21 13 15 .40 14 16 6.49 + 15 17 16.40 16 18 9.48 17 19 17.15 + 18 20 9.31 19 21 15.20 20 22 8.21 + 21 23 13.32 22 24 7.35 23 25 11.83 + 24 26 6.61 25 27 10.61 26 28 6.05 + 27 29 9.65 28 30 5.61 29 31 9.25 + 30 32 5.40 31 33 8.24 32 34 4.84 + 33 35 7.44 34 36 4.44 35 37 6.80 + 36 38 4.11 37 39 6.25 38 40 3.69 + 39 41 5.55 40 42 3.29 41 43 4.77 + 42 44 2.91 43 45 4.19 44 46 2.53 + 45 47 4.00 47 1 1.65 + + [NY,*,BO,*] 10 16 1.23 12 18 3.84 14 20 4.08 + 15 21 1.47 16 22 2.96 17 23 1.60 + 18 24 2.95 19 25 1.71 20 26 2.81 + 21 27 1.77 22 28 2.87 23 29 1.84 + 24 30 2.95 25 31 1.91 26 32 3.12 + 27 33 1.93 28 34 3.31 29 35 2.00 + 30 36 3.40 31 37 2.08 32 38 3.41 + 33 39 2.69 34 40 4.45 35 41 2.32 + 36 42 3.40 37 43 1.80 38 44 2.63 + 39 45 1.52 40 46 2.23 41 47 1.25 + 42 48 1.79 43 1 .97 44 2 1.28 + 45 3 .48 46 4 .68 48 6 .08 + + [BO,*,NY,*] 7 13 .03 9 15 1.29 11 17 4.59 + 12 18 2.56 13 19 3.92 14 20 2.37 + 15 21 3.81 16 22 2.24 17 23 3.51 + 18 24 2.13 19 25 3.28 20 26 2.05 + 21 27 3.15 22 28 1.99 23 29 3.09 + 24 30 1.93 25 31 3.19 26 32 1.91 + 27 33 3.21 28 34 1.85 29 35 3.21 + 30 36 1.71 31 37 3.04 32 38 2.08 + 33 39 3.13 34 40 1.96 35 41 2.53 + 36 42 1.43 37 43 2.04 38 44 1.12 + 39 45 1.71 40 46 .91 41 47 1.32 + 43 1 1.80 45 3 1.13 47 5 .23 + + [NY,*,PH,*] 1 3 .04 12 14 4.68 13 15 5.61 + 14 16 3.56 15 17 5.81 16 18 3.81 + 17 19 6.31 18 20 4.07 19 21 7.33 + 20 22 4.55 21 23 7.37 22 24 4.73 + 23 25 7.61 24 26 4.92 25 27 7.91 + 26 28 5.19 27 29 8.40 28 30 5.53 + 29 31 9.32 30 32 5.51 31 33 10.33 + 32 34 9.21 33 35 18.95 34 36 11.23 + 35 37 16.85 36 38 7.29 37 39 10.89 + 38 40 5.41 39 41 8.21 40 42 4.52 + 41 43 6.99 42 44 3.92 43 45 6.21 + 44 46 3.44 45 47 5.17 46 48 2.55 + 47 1 1.24 + + [PH,*,WA,*] 1 4 .20 14 17 4.49 15 18 3.53 + 16 19 2.67 17 20 3.83 18 21 3.01 + 19 22 4.12 20 23 3.15 21 24 4.67 + 22 25 3.20 23 26 4.23 24 27 2.87 + 25 28 3.84 26 29 2.60 27 30 3.80 + 28 31 2.77 29 32 4.31 30 33 3.16 + 31 34 4.88 32 35 3.45 33 36 5.55 + 34 37 3.52 35 38 6.11 36 39 3.32 + 37 40 5.53 38 41 3.03 39 42 4.51 + 40 43 2.53 41 44 3.39 42 45 1.93 + 43 46 2.52 44 47 1.20 45 48 1.75 + 46 1 .88 47 2 .87 ; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/transp.mod b/resources/3rdparty/glpk-4.57/examples/transp.mod new file mode 100644 index 000000000..a7cb939ae --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/transp.mod @@ -0,0 +1,63 @@ +# A TRANSPORTATION PROBLEM +# +# This problem finds a least cost shipping schedule that meets +# requirements at markets and supplies at factories. +# +# References: +# Dantzig G B, "Linear Programming and Extensions." +# Princeton University Press, Princeton, New Jersey, 1963, +# Chapter 3-3. + +set I; +/* canning plants */ + +set J; +/* markets */ + +param a{i in I}; +/* capacity of plant i in cases */ + +param b{j in J}; +/* demand at market j in cases */ + +param d{i in I, j in J}; +/* distance in thousands of miles */ + +param f; +/* freight in dollars per case per thousand miles */ + +param c{i in I, j in J} := f * d[i,j] / 1000; +/* transport cost in thousands of dollars per case */ + +var x{i in I, j in J} >= 0; +/* shipment quantities in cases */ + +minimize cost: sum{i in I, j in J} c[i,j] * x[i,j]; +/* total transportation costs in thousands of dollars */ + +s.t. supply{i in I}: sum{j in J} x[i,j] <= a[i]; +/* observe supply limit at plant i */ + +s.t. demand{j in J}: sum{i in I} x[i,j] >= b[j]; +/* satisfy demand at market j */ + +data; + +set I := Seattle San-Diego; + +set J := New-York Chicago Topeka; + +param a := Seattle 350 + San-Diego 600; + +param b := New-York 325 + Chicago 300 + Topeka 275; + +param d : New-York Chicago Topeka := + Seattle 2.5 1.7 1.8 + San-Diego 2.5 1.8 1.4 ; + +param f := 90; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/trick.mod b/resources/3rdparty/glpk-4.57/examples/trick.mod new file mode 100644 index 000000000..df5717b8a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/trick.mod @@ -0,0 +1,72 @@ +/* TRICK, A Transportation Design Problem */ + +/* Translated from the Mosel modeling language to GNU MathProg by + Andrew Makhorin */ + +/* This example model is described in the article "Formulations and + Reformulations in Integer Programming" by Michael Trick (it is + publicly available at http://mat.gsia.cmu.edu/trick/formul04.pdf). + + This model demonstrates an amazing effect when including in the + formulation an additional constraint, which is redundant even for + LP relaxation, makes the model easy for solving with the B&B. */ + +set TRUCKS := 1..10; + +set PACKAGES := 1..20; + +param capacity{TRUCKS}; + +param size{PACKAGES}; + +param cost{TRUCKS}; + +param can_use{PACKAGES, TRUCKS}; + +var x{PACKAGES, TRUCKS}, binary; + +var y{TRUCKS}, binary; + +minimize total: sum{i in TRUCKS} cost[i] * y[i]; + +f1{i in TRUCKS}: + sum{j in PACKAGES} size[j] * x[j,i] <= capacity[i] * y[i]; + +f2{i in TRUCKS, j in PACKAGES}: + x[j,i] <= y[i]; + +f3{j in PACKAGES}: + sum{i in TRUCKS} can_use[j,i] * x[j,i] = 1; + +redundant_constraint: + sum{i in TRUCKS} capacity[i] * y[i] >= sum{j in PACKAGES} size[j]; + +data; + +param capacity := + [1] 100 [2] 200 [3] 100 [4] 200 [5] 100 [6] 200 [7] 100 [8] 200 + [9] 100 [10] 200; + +param size := + [1] 17 [2] 21 [3] 54 [4] 45 [5] 87 [6] 34 [7] 23 [8] 45 [9] 12 + [10] 43 [11] 54 [12] 39 [13] 31 [14] 26 [15] 75 [16] 48 [17] 16 + [18] 32 [19] 45 [20] 55; + +param cost := + [1] 1 [2] 1.8 [3] 1 [4] 1.8 [5] 1 [6] 1.8 [7] 1 [8] 1.8 [9] 1 + [10] 1.8; + +param can_use (tr): + 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 := + 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 + 2 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 0 0 0 + 3 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 + 4 0 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 + 5 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 0 + 6 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 0 0 0 0 + 7 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 0 0 + 8 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 + 9 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 + 10 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/tsp.mod b/resources/3rdparty/glpk-4.57/examples/tsp.mod new file mode 100644 index 000000000..358245dae --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp.mod @@ -0,0 +1,335 @@ +/* TSP, Traveling Salesman Problem */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +/* The Traveling Salesman Problem (TSP) is stated as follows. + Let a directed graph G = (V, E) be given, where V = {1, ..., n} is + a set of nodes, E <= V x V is a set of arcs. Let also each arc + e = (i,j) be assigned a number c[i,j], which is the length of the + arc e. The problem is to find a closed path of minimal length going + through each node of G exactly once. */ + +param n, integer, >= 3; +/* number of nodes */ + +set V := 1..n; +/* set of nodes */ + +set E, within V cross V; +/* set of arcs */ + +param c{(i,j) in E}; +/* distance from node i to node j */ + +var x{(i,j) in E}, binary; +/* x[i,j] = 1 means that the salesman goes from node i to node j */ + +minimize total: sum{(i,j) in E} c[i,j] * x[i,j]; +/* the objective is to make the path length as small as possible */ + +s.t. leave{i in V}: sum{(i,j) in E} x[i,j] = 1; +/* the salesman leaves each node i exactly once */ + +s.t. enter{j in V}: sum{(i,j) in E} x[i,j] = 1; +/* the salesman enters each node j exactly once */ + +/* Constraints above are not sufficient to describe valid tours, so we + need to add constraints to eliminate subtours, i.e. tours which have + disconnected components. Although there are many known ways to do + that, I invented yet another way. The general idea is the following. + Let the salesman sell, say, cars, starting the travel from node 1, + where he has n cars. If we require the salesman to sell exactly one + car in each node, he will need to go through all nodes to satisfy + this requirement, thus, all subtours will be eliminated. */ + +var y{(i,j) in E}, >= 0; +/* y[i,j] is the number of cars, which the salesman has after leaving + node i and before entering node j; in terms of the network analysis, + y[i,j] is a flow through arc (i,j) */ + +s.t. cap{(i,j) in E}: y[i,j] <= (n-1) * x[i,j]; +/* if arc (i,j) does not belong to the salesman's tour, its capacity + must be zero; it is obvious that on leaving a node, it is sufficient + to have not more than n-1 cars */ + +s.t. node{i in V}: +/* node[i] is a conservation constraint for node i */ + + sum{(j,i) in E} y[j,i] + /* summary flow into node i through all ingoing arcs */ + + + (if i = 1 then n) + /* plus n cars which the salesman has at starting node */ + + = /* must be equal to */ + + sum{(i,j) in E} y[i,j] + /* summary flow from node i through all outgoing arcs */ + + + 1; + /* plus one car which the salesman sells at node i */ + +solve; + +printf "Optimal tour has length %d\n", + sum{(i,j) in E} c[i,j] * x[i,j]; +printf("From node To node Distance\n"); +printf{(i,j) in E: x[i,j]} " %3d %3d %8g\n", + i, j, c[i,j]; + +data; + +/* These data correspond to the symmetric instance ulysses16 from: + + Reinelt, G.: TSPLIB - A travelling salesman problem library. + ORSA-Journal of the Computing 3 (1991) 376-84; + http://elib.zib.de/pub/Packages/mp-testdata/tsp/tsplib */ + +/* The optimal solution is 6859 */ + +param n := 16; + +param : E : c := + 1 2 509 + 1 3 501 + 1 4 312 + 1 5 1019 + 1 6 736 + 1 7 656 + 1 8 60 + 1 9 1039 + 1 10 726 + 1 11 2314 + 1 12 479 + 1 13 448 + 1 14 479 + 1 15 619 + 1 16 150 + 2 1 509 + 2 3 126 + 2 4 474 + 2 5 1526 + 2 6 1226 + 2 7 1133 + 2 8 532 + 2 9 1449 + 2 10 1122 + 2 11 2789 + 2 12 958 + 2 13 941 + 2 14 978 + 2 15 1127 + 2 16 542 + 3 1 501 + 3 2 126 + 3 4 541 + 3 5 1516 + 3 6 1184 + 3 7 1084 + 3 8 536 + 3 9 1371 + 3 10 1045 + 3 11 2728 + 3 12 913 + 3 13 904 + 3 14 946 + 3 15 1115 + 3 16 499 + 4 1 312 + 4 2 474 + 4 3 541 + 4 5 1157 + 4 6 980 + 4 7 919 + 4 8 271 + 4 9 1333 + 4 10 1029 + 4 11 2553 + 4 12 751 + 4 13 704 + 4 14 720 + 4 15 783 + 4 16 455 + 5 1 1019 + 5 2 1526 + 5 3 1516 + 5 4 1157 + 5 6 478 + 5 7 583 + 5 8 996 + 5 9 858 + 5 10 855 + 5 11 1504 + 5 12 677 + 5 13 651 + 5 14 600 + 5 15 401 + 5 16 1033 + 6 1 736 + 6 2 1226 + 6 3 1184 + 6 4 980 + 6 5 478 + 6 7 115 + 6 8 740 + 6 9 470 + 6 10 379 + 6 11 1581 + 6 12 271 + 6 13 289 + 6 14 261 + 6 15 308 + 6 16 687 + 7 1 656 + 7 2 1133 + 7 3 1084 + 7 4 919 + 7 5 583 + 7 6 115 + 7 8 667 + 7 9 455 + 7 10 288 + 7 11 1661 + 7 12 177 + 7 13 216 + 7 14 207 + 7 15 343 + 7 16 592 + 8 1 60 + 8 2 532 + 8 3 536 + 8 4 271 + 8 5 996 + 8 6 740 + 8 7 667 + 8 9 1066 + 8 10 759 + 8 11 2320 + 8 12 493 + 8 13 454 + 8 14 479 + 8 15 598 + 8 16 206 + 9 1 1039 + 9 2 1449 + 9 3 1371 + 9 4 1333 + 9 5 858 + 9 6 470 + 9 7 455 + 9 8 1066 + 9 10 328 + 9 11 1387 + 9 12 591 + 9 13 650 + 9 14 656 + 9 15 776 + 9 16 933 + 10 1 726 + 10 2 1122 + 10 3 1045 + 10 4 1029 + 10 5 855 + 10 6 379 + 10 7 288 + 10 8 759 + 10 9 328 + 10 11 1697 + 10 12 333 + 10 13 400 + 10 14 427 + 10 15 622 + 10 16 610 + 11 1 2314 + 11 2 2789 + 11 3 2728 + 11 4 2553 + 11 5 1504 + 11 6 1581 + 11 7 1661 + 11 8 2320 + 11 9 1387 + 11 10 1697 + 11 12 1838 + 11 13 1868 + 11 14 1841 + 11 15 1789 + 11 16 2248 + 12 1 479 + 12 2 958 + 12 3 913 + 12 4 751 + 12 5 677 + 12 6 271 + 12 7 177 + 12 8 493 + 12 9 591 + 12 10 333 + 12 11 1838 + 12 13 68 + 12 14 105 + 12 15 336 + 12 16 417 + 13 1 448 + 13 2 941 + 13 3 904 + 13 4 704 + 13 5 651 + 13 6 289 + 13 7 216 + 13 8 454 + 13 9 650 + 13 10 400 + 13 11 1868 + 13 12 68 + 13 14 52 + 13 15 287 + 13 16 406 + 14 1 479 + 14 2 978 + 14 3 946 + 14 4 720 + 14 5 600 + 14 6 261 + 14 7 207 + 14 8 479 + 14 9 656 + 14 10 427 + 14 11 1841 + 14 12 105 + 14 13 52 + 14 15 237 + 14 16 449 + 15 1 619 + 15 2 1127 + 15 3 1115 + 15 4 783 + 15 5 401 + 15 6 308 + 15 7 343 + 15 8 598 + 15 9 776 + 15 10 622 + 15 11 1789 + 15 12 336 + 15 13 287 + 15 14 237 + 15 16 636 + 16 1 150 + 16 2 542 + 16 3 499 + 16 4 455 + 16 5 1033 + 16 6 687 + 16 7 592 + 16 8 206 + 16 9 933 + 16 10 610 + 16 11 2248 + 16 12 417 + 16 13 406 + 16 14 449 + 16 15 636 +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/README b/resources/3rdparty/glpk-4.57/examples/tsp/README new file mode 100644 index 000000000..7d497e58f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/README @@ -0,0 +1,37 @@ +This subdirectory contains an example application program, TSPSOL, +which is a stand-alone solver intended to solve the Symmetric Traveling +Salesman Problem (TSP) with the GLPK integer optimizer. + +Please note that this program is only an illustrative example that +illustrates generating "lazy" constraints during the branch-and-bound +search. It is *not* a state-of-the-art code, so only small-sized TSP +instances (perhaps, having up to 150-200 nodes) can be solved with this +program in a reasonable time. For more details see comments in the +source code. + +To build TSPSOL executable you need to run 'build.sh' script. Note that +you should have the GLPK library properly installed. + +To run the TSPSOL program use the following command: + + tspsol tsp-file + +where tsp-file specifies an input text file containing TSP data in +TSPLIB 95 format. + +Detailed description of the input format recognized by TSPSOL is given +in the report: Gerhard Reinelt, "TSPLIB 95". This report as well as +TSPLIB, a library of sample TSP instances, are freely available for +research purposes; see: +. + +This subdirectory also includes the following example TSP instances: + +dantzig42.tsp 42 cities (Dantzig) [from TSPLIB] +gr120.tsp 120 cities in Germany (Groetschel) [from TSPLIB] +moscow.tsp 68 cities in Moscow region (Makhorin) +sample.tsp small example from D.Phillips and A.Garcia-Diaz +ulysses16.tsp Odyssey of Ulysses (Groetschel/Padberg) [from TSPLIB] +ulysses22.tsp Odyssey of Ulysses (Groetschel/Padberg) [from TSPLIB] + +Please send comments to the mailing list. diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/bench.txt b/resources/3rdparty/glpk-4.57/examples/tsp/bench.txt new file mode 100644 index 000000000..4596b2e39 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/bench.txt @@ -0,0 +1,56 @@ +Solver: TSPSOL for GLPK 4.56 +Computer: Intel Celeron J1800 2.41 GHz +OS: Debian GNU/Linux 8.1.0 "Jessie" +Compiler: GCC 4.7.2 (options used: -O2) +Test set: TSPLIB 95 + +Instance N Solution Lower Bound Nodes Iters Time,s Mem,MB +------------ --- ------------ ------------ -------- ------- ------ ------ +att48 48 10628 opt 1 336 < 1 1.2 +bayg29 29 1610 opt 1 173 < 1 0.3 +bays29 29 2020 opt 1 166 < 1 0.3 +berlin52 52 7542 opt 1 253 < 1 0.7 +bier127 127 118282 opt 29 1330 14 19.1 +brazil58 58 25395 opt 1 458 1 2.0 +brg180 180 1950 opt 131 20012 83 52.0 +burma14 14 3323 opt 1 55 < 1 0.1 +ch130 130 6110 opt 45 2212 38 24.2 +ch150 150 6528 opt 271 4967 138 27.5 +d198 98 15780 opt 259 11371 719 92.3 +dantzig42 42 699 opt 1 171 < 1 0.8 +eil51 51 426 opt 115 1368 2 2.4 +eil76 76 538 opt 1 517 < 1 2.2 +eil101 101 629 opt 1 838 4 9.9 +fri26 26 937 opt 1 125 < 1 0.2 +gr17 17 2085 opt 1 93 < 1 0.1 +gr21 21 2707 opt 1 82 < 1 0.1 +gr24 24 1272 opt 1 137 < 1 0.2 +gr48 48 5046 opt 3 407 1 2.3 +gr96 96 55209 opt 367 5564 63 12.4 +gr120 120 6942 opt 121 2940 46 14.7 +gr137 137 69853 opt 97 1934 27 16.2 +gr202 202 40160 opt 183 4176 287 88.4 +hk48 48 11461 opt 1 322 < 1 1.1 +kroA100 100 21282 opt 57 2227 23 13.2 +kroB100 100 22141 opt 71 1891 27 15.6 +kroC100 100 20749 opt 9 1035 5 9.4 +kroD100 100 21294 opt 9 1203 10 12.3 +kroE100 100 22068 opt 323 5055 100 13.4 +kroA150 150 26524 opt 431 8069 487 50.2 +kroB150 150 26130 opt 309 12599 610 43.1 +lin105 105 14379 opt 5 910 4 7.3 +lin318 318 42029 opt 1527 25885 4972 286.4 +pr76 76 108159 opt 20537 636616 9218 128.7 * +pr107 107 44303 opt 1 3692 38 33.2 +pr124 124 59030 opt 19 1306 23 25.6 +pr136 136 96772 opt 93 2799 60 27.7 +pr144 144 58537 opt 11 1948 37 32.2 +pr152 152 73682 opt 125 3269 99 46.0 +pr226 226 80369 opt 1 6699 240 163.8 +rat99 99 1211 opt 11 467 2 5,6 +rd100 100 7910 opt 1 868 3 7.2 +st70 70 675 opt 1 688 1 3.2 +swiss42 42 1273 opt 1 231 < 1 0.8 +u159 159 42080 opt 9 1356 15 30.0 +ulysses16 16 6859 opt 1 72 < 1 0.1 +ulysses22 22 7013 opt 1 110 < 1 0.2 diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/build.sh b/resources/3rdparty/glpk-4.57/examples/tsp/build.sh new file mode 100755 index 000000000..ab6abc1fb --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/build.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# +# Run this script to build TSPSOL executable. +# +# NOTE: you need to have GLPK properly installed. +# +gcc -O2 -otspsol main.c maxflow.c mincut.c misc.c tsplib.c -lglpk -lm +./tspsol sample.tsp diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/dantzig42.tsp b/resources/3rdparty/glpk-4.57/examples/tsp/dantzig42.tsp new file mode 100644 index 000000000..15567bff1 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/dantzig42.tsp @@ -0,0 +1,103 @@ +NAME : dantzig42 +TYPE : TSP +COMMENT : 42 cities (Dantzig) +DIMENSION : 42 +EDGE_WEIGHT_TYPE : EXPLICIT +EDGE_WEIGHT_FORMAT : LOWER_DIAG_ROW +DISPLAY_DATA_TYPE : TWOD_DISPLAY +EDGE_WEIGHT_SECTION + 0 8 0 39 45 0 37 47 9 0 50 49 21 15 0 61 62 21 + 20 17 0 58 60 16 17 18 6 0 59 60 15 20 26 17 10 0 + 62 66 20 25 31 22 15 5 0 81 81 40 44 50 41 35 24 20 + 0 103 107 62 67 72 63 57 46 41 23 0 108 117 66 71 77 68 + 61 51 46 26 11 0 145 149 104 108 114 106 99 88 84 63 49 40 + 0 181 185 140 144 150 142 135 124 120 99 85 76 35 0 187 191 146 + 150 156 142 137 130 125 105 90 81 41 10 0 161 170 120 124 130 115 + 110 104 105 90 72 62 34 31 27 0 142 146 101 104 111 97 91 85 + 86 75 51 59 29 53 48 21 0 174 178 133 138 143 129 123 117 118 + 107 83 84 54 46 35 26 31 0 185 186 142 143 140 130 126 124 128 + 118 93 101 72 69 58 58 43 26 0 164 165 120 123 124 106 106 105 + 110 104 86 97 71 93 82 62 42 45 22 0 137 139 94 96 94 80 + 78 77 84 77 56 64 65 90 87 58 36 68 50 30 0 117 122 77 + 80 83 68 62 60 61 50 34 42 49 82 77 60 30 62 70 49 21 + 0 114 118 73 78 84 69 63 57 59 48 28 36 43 77 72 45 27 + 59 69 55 27 5 0 85 89 44 48 53 41 34 28 29 22 23 35 + 69 105 102 74 56 88 99 81 54 32 29 0 77 80 36 40 46 34 + 27 19 21 14 29 40 77 114 111 84 64 96 107 87 60 40 37 8 + 0 87 89 44 46 46 30 28 29 32 27 36 47 78 116 112 84 66 + 98 95 75 47 36 39 12 11 0 91 93 48 50 48 34 32 33 36 + 30 34 45 77 115 110 83 63 97 91 72 44 32 36 9 15 3 0 + 105 106 62 63 64 47 46 49 54 48 46 59 85 119 115 88 66 98 + 79 59 31 36 42 28 33 21 20 0 111 113 69 71 66 51 53 56 + 61 57 59 71 96 130 126 98 75 98 85 62 38 47 53 39 42 29 + 30 12 0 91 92 50 51 46 30 34 38 43 49 60 71 103 141 136 + 109 90 115 99 81 53 61 62 36 34 24 28 20 20 0 83 85 42 + 43 38 22 26 32 36 51 63 75 106 142 140 112 93 126 108 88 60 + 64 66 39 36 27 31 28 28 8 0 89 91 55 55 50 34 39 44 + 49 63 76 87 120 155 150 123 100 123 109 86 62 71 78 52 49 39 + 44 35 24 15 12 0 95 97 64 63 56 42 49 56 60 75 86 97 + 126 160 155 128 104 128 113 90 67 76 82 62 59 49 53 40 29 25 + 23 11 0 74 81 44 43 35 23 30 39 44 62 78 89 121 159 155 + 127 108 136 124 101 75 79 81 54 50 42 46 43 39 23 14 14 21 + 0 67 69 42 41 31 25 32 41 46 64 83 90 130 164 160 133 114 + 146 134 111 85 84 86 59 52 47 51 53 49 32 24 24 30 9 0 + 74 76 61 60 42 44 51 60 66 83 102 110 147 185 179 155 133 159 + 146 122 98 105 107 79 71 66 70 70 60 48 40 36 33 25 18 0 + 57 59 46 41 25 30 36 47 52 71 93 98 136 172 172 148 126 158 + 147 124 121 97 99 71 65 59 63 67 62 46 38 37 43 23 13 17 + 0 45 46 41 34 20 34 38 48 53 73 96 99 137 176 178 151 131 + 163 159 135 108 102 103 73 67 64 69 75 72 54 46 49 54 34 24 + 29 12 0 35 37 35 26 18 34 36 46 51 70 93 97 134 171 176 + 151 129 161 163 139 118 102 101 71 65 65 70 84 78 58 50 56 62 + 41 32 38 21 9 0 29 33 30 21 18 35 33 40 45 65 87 91 + 117 166 171 144 125 157 156 139 113 95 97 67 60 62 67 79 82 62 + 53 59 66 45 38 45 27 15 6 0 3 11 41 37 47 57 55 58 + 63 83 105 109 147 186 188 164 144 176 182 161 134 119 116 86 78 84 + 88 101 108 88 80 86 92 71 64 71 54 41 32 25 0 5 12 55 + 41 53 64 61 61 66 84 111 113 150 186 192 166 147 180 188 167 140 + 124 119 90 87 90 94 107 114 77 86 92 98 80 74 77 60 48 38 + 32 6 0 +DISPLAY_DATA_SECTION + 1 170.0 85.0 + 2 166.0 88.0 + 3 133.0 73.0 + 4 140.0 70.0 + 5 142.0 55.0 + 6 126.0 53.0 + 7 125.0 60.0 + 8 119.0 68.0 + 9 117.0 74.0 + 10 99.0 83.0 + 11 73.0 79.0 + 12 72.0 91.0 + 13 37.0 94.0 + 14 6.0 106.0 + 15 3.0 97.0 + 16 21.0 82.0 + 17 33.0 67.0 + 18 4.0 66.0 + 19 3.0 42.0 + 20 27.0 33.0 + 21 52.0 41.0 + 22 57.0 59.0 + 23 58.0 66.0 + 24 88.0 65.0 + 25 99.0 67.0 + 26 95.0 55.0 + 27 89.0 55.0 + 28 83.0 38.0 + 29 85.0 25.0 + 30 104.0 35.0 + 31 112.0 37.0 + 32 112.0 24.0 + 33 113.0 13.0 + 34 125.0 30.0 + 35 135.0 32.0 + 36 147.0 18.0 + 37 147.5 36.0 + 38 154.5 45.0 + 39 157.0 54.0 + 40 158.0 61.0 + 41 172.0 82.0 + 42 174.0 87.0 +EOF diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/gr120.tsp b/resources/3rdparty/glpk-4.57/examples/tsp/gr120.tsp new file mode 100644 index 000000000..632248922 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/gr120.tsp @@ -0,0 +1,534 @@ +NAME: gr120 +TYPE: TSP +COMMENT: 120 cities in Germany (Groetschel) +DIMENSION: 120 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: LOWER_DIAG_ROW +DISPLAY_DATA_TYPE: TWOD_DISPLAY +EDGE_WEIGHT_SECTION + 0 534 0 434 107 0 294 241 148 0 593 190 137 374 0 409 351 240 + 190 258 0 332 320 232 139 494 310 0 232 354 261 113 372 188 208 0 + 464 124 88 171 202 328 188 284 0 566 508 397 347 331 171 467 345 485 + 0 552 80 127 259 234 365 249 372 61 522 0 802 316 336 509 222 470 + 588 584 392 502 386 0 633 432 479 552 586 723 417 621 411 874 354 738 + 0 257 641 541 407 706 522 184 391 372 679 433 915 390 0 187 577 477 + 337 636 452 375 321 507 609 595 845 572 196 0 91 450 357 210 509 325 + 248 141 380 482 468 718 661 228 158 0 412 624 531 384 690 506 210 408 + 398 663 459 892 227 169 351 383 0 400 752 659 512 818 634 338 536 526 + 791 587 1020 524 151 270 371 167 0 472 805 712 565 871 687 391 589 579 + 844 640 1073 413 257 342 443 220 57 0 389 665 572 425 731 547 251 449 + 439 704 500 933 274 146 328 360 53 112 165 0 610 76 183 317 192 442 + 396 430 202 515 141 233 492 723 653 526 700 828 881 741 0 340 730 630 + 490 789 605 394 474 582 762 643 998 444 125 185 311 223 67 139 168 806 + 0 510 152 134 217 248 370 175 330 46 527 72 438 380 359 553 426 385 + 513 566 426 213 569 0 153 447 354 207 470 280 246 113 377 437 465 715 + 659 345 275 98 500 488 560 477 523 428 423 0 511 844 751 604 910 726 + 430 628 618 883 679 1112 407 296 381 482 259 96 39 204 920 178 605 599 + 0 269 283 190 42 332 148 169 63 213 305 301 544 582 382 312 185 365 + 493 546 406 359 465 259 170 585 0 525 157 95 232 42 257 316 355 160 + 330 167 254 521 638 568 441 615 743 796 656 188 721 206 438 835 274 0 + 150 539 446 299 598 414 279 283 469 571 557 807 488 112 96 120 267 255 + 327 244 615 195 515 237 366 274 530 0 80 507 414 267 566 382 305 251 + 437 539 525 775 572 196 88 77 351 339 411 328 583 279 483 205 450 242 + 498 63 0 130 520 427 280 579 395 318 264 450 552 538 788 543 167 59 + 101 322 310 382 299 596 250 496 218 412 255 511 56 25 0 401 791 691 + 551 850 666 474 535 662 823 723 1059 524 238 238 372 303 138 126 248 867 + 101 649 489 165 526 782 256 340 311 0 134 524 431 284 583 399 314 268 + 454 556 542 792 530 154 63 105 309 297 369 286 600 237 500 222 408 259 + 515 34 29 22 298 0 666 942 849 702 1008 824 528 726 716 981 777 1210 + 446 423 605 637 357 280 217 279 1018 336 703 754 194 683 933 521 605 576 + 416 563 0 259 281 188 40 364 180 142 72 211 337 299 549 555 372 302 + 175 338 466 519 379 357 455 257 172 558 27 272 264 232 245 516 249 656 + 0 505 447 336 286 354 110 406 284 424 70 461 566 819 618 548 421 602 + 730 783 643 538 701 466 376 822 244 353 509 478 491 762 494 920 276 0 + 453 358 247 234 265 59 354 232 335 182 372 477 767 566 496 369 550 678 + 731 591 449 649 377 324 770 192 264 458 426 439 710 443 868 224 95 0 + 627 334 251 408 168 239 528 406 300 166 348 331 700 740 670 504 724 852 + 905 765 360 823 346 504 944 366 179 632 600 613 884 617 1042 398 162 177 + 0 339 275 187 94 313 281 45 184 143 438 204 543 458 229 382 250 255 + 350 436 296 351 439 130 248 475 136 271 286 312 325 519 321 573 102 377 + 325 425 0 710 283 254 491 117 375 611 489 319 354 351 202 679 823 753 + 626 807 935 988 848 272 906 365 587 1027 449 159 715 683 696 967 700 1125 + 481 345 337 183 430 0 243 353 260 113 419 235 89 133 283 392 368 621 + 502 209 286 159 285 413 466 326 429 439 226 157 505 94 344 190 216 229 + 500 225 603 67 331 279 453 96 536 0 376 520 427 280 586 402 106 300 + 294 559 355 788 340 146 322 306 112 240 293 153 596 296 281 338 332 261 + 511 220 322 293 376 253 430 234 498 446 620 151 703 181 0 449 594 501 + 354 660 476 180 378 368 633 429 862 256 206 388 420 45 204 257 101 670 + 260 355 537 296 335 585 304 388 359 340 346 394 308 572 520 694 225 777 + 255 82 0 505 781 688 541 847 663 367 565 555 820 616 1049 289 262 444 + 476 196 119 136 118 857 175 542 593 129 522 772 360 444 415 255 402 161 + 495 759 707 881 412 964 442 269 233 0 322 611 518 371 677 493 197 395 + 372 650 446 879 359 69 261 293 94 142 224 84 687 146 372 410 263 352 + 602 177 261 232 247 219 361 325 589 537 711 242 794 272 99 106 200 0 + 185 575 482 335 634 450 231 319 419 607 480 843 462 86 124 156 241 226 + 298 218 651 166 406 273 337 310 566 40 124 95 227 82 495 300 546 494 + 668 276 751 207 212 278 334 151 0 353 638 545 398 704 520 224 422 412 + 677 473 906 282 110 292 324 61 125 178 38 714 181 399 441 217 379 629 + 208 292 263 261 250 315 352 616 564 738 269 821 299 126 82 154 46 182 + 0 324 314 191 106 275 91 225 104 244 248 332 487 638 437 367 240 421 + 549 602 462 390 520 290 238 641 64 227 329 297 310 581 314 739 95 187 + 135 309 196 392 150 317 391 578 408 365 435 0 388 234 127 124 219 113 + 289 168 215 270 254 431 606 501 431 304 485 613 666 526 310 584 232 302 + 705 128 163 393 361 374 645 378 803 159 209 120 219 229 336 214 381 455 + 642 472 429 499 64 0 447 664 571 424 730 546 250 448 438 703 499 932 + 188 204 386 418 36 202 255 88 740 258 425 535 294 405 655 302 386 357 + 338 344 392 378 642 590 764 295 847 325 152 68 231 130 276 96 461 525 + 0 360 606 513 366 672 488 192 390 380 645 441 874 273 117 299 331 46 + 150 203 63 682 206 367 448 242 347 597 215 299 270 286 257 340 320 584 + 532 706 237 789 267 94 58 179 48 189 31 403 467 82 0 605 133 180 + 312 287 418 264 425 112 575 55 439 313 448 648 520 474 602 655 515 193 + 658 89 517 694 354 220 610 577 591 738 595 792 352 514 425 401 219 404 + 421 370 444 631 461 495 488 385 307 514 456 0 656 932 839 692 998 814 + 518 716 706 971 767 1200 444 413 595 627 347 270 200 269 1008 326 693 744 + 177 673 923 511 595 566 406 553 42 646 910 858 1032 563 1115 593 420 384 + 151 351 485 305 729 793 382 330 782 0 573 113 101 280 79 329 359 403 + 163 402 157 235 509 686 616 489 663 791 844 704 131 769 209 486 883 322 + 57 578 546 559 830 563 981 320 425 336 236 314 176 392 559 633 820 650 + 614 677 353 220 603 645 210 971 0 293 384 274 143 319 129 262 60 314 + 286 402 531 675 451 381 201 458 586 639 499 460 534 360 151 678 101 318 + 343 311 324 595 328 776 132 225 173 353 233 436 187 354 428 615 445 379 + 472 83 147 498 440 455 766 375 0 372 283 199 153 229 39 273 151 324 + 196 324 441 686 485 415 288 469 597 650 510 413 568 370 241 689 111 228 + 377 345 358 629 362 787 143 135 83 263 244 346 198 365 439 626 456 413 + 483 54 72 509 451 377 777 300 90 0 330 479 386 239 545 361 65 259 + 253 518 314 747 378 119 276 260 150 278 331 191 555 334 240 297 370 220 + 470 174 276 247 414 207 468 193 457 405 579 110 662 140 46 120 307 126 + 166 164 276 340 190 132 329 458 518 313 324 0 610 297 234 391 107 275 + 511 389 322 248 331 254 693 723 653 526 707 835 888 748 302 806 368 487 + 927 349 149 615 583 596 867 600 1025 381 239 231 77 408 106 436 603 677 + 864 694 651 721 292 236 747 689 384 1015 186 336 246 562 0 598 874 781 + 634 940 756 460 658 648 913 709 1142 370 355 537 569 289 212 197 211 950 + 268 635 686 157 615 865 453 537 508 348 495 84 588 852 800 974 505 1057 + 535 362 326 93 293 427 247 671 735 324 272 724 85 913 708 719 400 957 + 0 214 604 504 364 663 479 402 348 534 636 622 872 599 223 49 185 378 + 319 391 355 680 234 580 302 430 339 595 123 115 86 287 90 632 329 575 + 523 697 409 780 313 349 415 471 288 151 319 394 458 413 326 675 622 643 + 408 442 303 680 564 0 154 401 308 161 460 276 199 78 331 433 419 669 + 612 298 228 63 453 441 513 430 477 381 377 47 552 136 392 190 158 171 + 442 175 707 126 372 320 494 201 577 110 291 490 546 363 226 396 191 255 + 488 401 471 697 440 138 239 250 477 639 255 0 70 464 371 224 523 339 + 262 208 394 496 482 732 567 191 121 27 346 334 406 323 540 274 440 162 + 445 199 455 83 47 64 335 68 600 189 435 383 557 269 640 173 295 383 + 439 256 119 287 254 378 381 294 534 590 503 268 302 249 540 532 148 115 + 0 606 349 266 387 183 216 507 385 354 147 363 357 715 719 649 522 703 + 831 884 744 375 802 400 483 923 345 194 611 579 592 863 596 1021 377 139 + 154 22 447 209 432 599 673 860 690 647 717 288 232 743 685 416 1011 262 + 332 242 558 103 953 676 473 536 0 631 228 175 412 38 296 532 410 240 + 306 272 210 640 744 674 547 728 856 909 769 233 827 286 508 948 370 80 + 636 604 617 888 621 1046 402 293 261 138 351 79 457 624 698 885 715 672 + 742 313 257 768 710 325 1036 117 357 267 583 69 978 701 498 561 153 0 + 642 129 176 349 121 369 428 472 232 428 226 187 578 755 685 558 732 860 + 913 773 98 838 278 555 952 391 132 647 615 628 899 632 1050 389 465 376 + 260 383 161 461 628 702 889 719 683 746 422 330 772 714 279 1040 75 430 + 340 587 191 982 712 509 572 275 122 0 503 779 686 539 845 661 365 563 + 553 818 614 1047 245 260 442 474 141 151 168 116 855 207 540 591 162 520 + 770 358 442 413 287 400 201 493 757 705 879 410 962 440 267 231 44 198 + 332 152 576 640 174 177 629 199 818 613 624 305 862 125 469 544 437 858 + 883 887 0 372 762 662 522 821 637 456 506 644 794 705 1030 506 209 209 + 343 285 120 108 230 838 72 631 460 147 497 753 227 311 282 29 269 398 + 487 733 681 855 501 938 471 354 322 237 218 198 243 552 616 320 268 720 + 388 801 566 600 396 838 330 258 413 306 834 859 870 269 0 641 348 265 + 422 152 262 542 420 314 189 362 313 714 754 684 557 738 866 919 779 344 + 837 360 518 958 380 193 646 614 627 898 631 1056 412 185 200 23 439 165 + 467 634 708 895 725 682 752 323 233 778 720 415 1046 231 367 277 593 59 + 988 711 508 571 45 122 244 893 869 0 561 837 744 597 903 719 423 621 + 611 876 672 1105 311 318 500 532 252 175 192 174 913 231 598 649 186 578 + 828 416 500 471 311 458 154 551 815 763 937 468 1020 498 325 289 65 256 + 390 210 634 698 287 235 687 152 876 671 682 363 920 77 527 602 495 916 + 941 945 66 293 951 0 478 754 661 514 820 636 340 538 528 793 589 1022 + 261 235 417 449 116 132 149 91 830 188 515 566 159 495 745 333 417 388 + 268 375 226 468 732 680 854 385 937 415 242 206 55 173 307 127 551 615 + 149 152 604 224 793 588 599 280 837 150 444 519 412 833 858 862 25 250 + 868 91 0 247 316 223 76 360 176 170 39 246 333 334 572 583 360 290 + 163 366 494 547 407 392 443 292 133 586 37 307 252 220 233 504 237 684 + 34 272 220 394 146 477 95 262 336 523 353 288 380 92 156 406 348 387 + 674 355 83 139 221 377 616 317 92 177 373 398 424 521 475 408 579 496 + 0 317 336 212 95 289 105 218 79 266 262 354 501 631 430 360 233 414 + 542 595 455 412 513 312 213 634 53 248 397 290 378 574 382 732 88 201 + 149 323 189 406 143 310 384 571 401 358 428 21 85 454 396 407 722 375 + 62 68 269 306 664 387 184 247 302 327 444 569 545 337 627 544 70 0 + 272 382 289 142 448 264 84 162 234 421 295 650 497 180 315 188 280 408 + 461 321 458 464 221 186 500 123 373 193 245 258 544 228 598 96 360 308 + 482 91 565 29 142 250 437 267 159 294 179 243 320 262 310 588 421 216 + 227 96 465 530 342 139 209 461 486 490 435 526 496 493 410 124 172 0 + 575 276 199 356 86 240 476 354 287 250 296 266 672 688 618 491 672 800 + 853 713 289 771 333 452 892 314 127 580 548 561 832 565 990 346 237 205 + 82 373 141 401 568 642 829 659 616 686 257 201 712 654 349 980 165 301 + 211 527 35 922 645 442 505 97 56 178 827 803 66 885 802 342 271 430 + 0 219 479 386 239 545 361 167 259 317 518 378 747 474 83 172 149 253 + 235 339 230 555 228 304 263 378 220 470 79 139 134 289 112 507 193 457 + 405 579 174 662 126 154 290 346 136 621 194 276 340 288 201 393 497 518 + 313 324 108 562 439 199 216 153 558 583 587 344 260 593 402 319 221 269 + 97 527 0 293 683 583 443 742 558 238 427 426 715 487 951 352 50 232 + 264 131 101 174 108 759 105 413 381 213 418 674 148 232 203 206 190 385 + 408 654 602 776 283 859 248 140 168 224 41 122 72 473 537 166 89 502 + 375 722 487 521 167 759 317 259 334 227 755 780 791 222 177 790 280 197 + 396 466 219 724 134 0 54 529 429 289 588 404 327 273 459 561 547 797 + 595 219 92 82 374 362 434 351 605 302 505 227 473 264 520 119 31 43 + 363 58 628 254 500 448 622 334 705 238 327 411 467 284 147 315 319 383 + 409 322 600 618 568 333 367 281 605 560 84 180 53 601 626 637 465 334 + 636 523 440 242 312 267 570 170 255 0 648 188 182 355 68 316 434 430 + 238 362 232 154 584 761 691 564 738 866 919 779 177 844 284 561 958 390 + 100 653 621 634 905 638 1056 395 412 323 194 389 95 467 634 708 895 725 + 689 752 333 277 778 720 285 1046 81 377 287 593 125 988 718 515 578 209 + 56 66 893 876 178 951 868 418 347 496 112 593 797 643 0 211 601 501 + 361 660 476 231 345 479 633 480 869 466 74 81 182 243 189 261 220 677 + 129 406 299 300 336 592 105 150 121 190 108 497 326 572 520 694 276 777 + 310 204 280 336 143 37 184 391 455 278 191 495 487 640 405 439 166 677 + 429 160 252 145 673 698 709 334 161 708 392 309 314 384 196 642 99 125 + 173 715 0 568 844 751 604 910 726 430 628 618 883 679 1112 348 325 507 + 539 259 182 150 181 920 238 605 656 127 585 835 423 507 478 318 465 98 + 558 822 770 944 475 1027 505 332 296 63 263 397 217 641 705 294 242 694 + 96 883 678 689 370 927 30 534 609 502 923 948 952 103 300 958 56 120 + 586 634 500 892 409 287 530 958 399 0 497 150 67 204 70 257 288 327 + 155 335 164 282 516 610 540 413 587 715 768 628 216 693 201 410 807 246 + 28 502 470 483 754 487 905 244 353 264 184 243 187 316 483 557 744 574 + 538 601 199 135 627 569 217 895 85 292 228 442 167 837 567 364 427 199 + 108 160 742 725 198 800 717 279 220 345 132 442 646 492 128 564 807 0 + 290 680 580 440 739 555 317 424 505 712 566 948 506 139 98 261 285 155 + 227 229 756 88 492 378 266 415 671 144 176 164 140 136 424 405 651 599 + 773 362 856 389 290 322 263 195 116 226 470 534 320 243 581 414 719 484 + 518 252 756 356 147 331 224 752 777 788 295 111 787 319 276 393 463 275 + 721 178 154 190 794 79 326 643 0 475 65 42 182 137 282 261 295 65 + 439 85 321 437 588 518 391 565 693 746 606 141 671 111 388 785 224 95 + 480 448 461 732 465 883 222 378 289 272 216 254 294 461 535 722 552 516 + 579 255 169 605 547 138 873 92 325 241 420 255 815 545 342 405 287 175 + 161 720 703 286 778 695 257 277 323 220 420 624 470 167 542 785 88 621 + 0 654 341 278 435 151 319 555 433 366 266 375 298 755 767 697 570 751 + 879 932 792 346 850 412 531 971 393 193 659 627 640 911 644 1069 425 262 + 254 100 452 103 480 647 721 908 738 695 765 336 280 791 733 428 1059 230 + 380 290 606 44 1001 724 521 584 122 113 235 906 882 77 964 881 421 350 + 509 79 606 803 649 169 721 971 211 800 299 0 445 387 276 226 294 50 + 346 224 364 125 410 506 759 558 488 361 542 670 723 583 478 641 406 316 + 762 184 293 450 418 431 702 435 860 216 64 57 193 317 411 271 438 512 + 699 529 486 556 127 149 582 524 454 850 365 165 75 397 311 792 515 312 + 375 170 332 405 697 673 216 755 672 212 141 300 276 397 594 440 352 512 + 762 293 591 318 355 0 375 765 665 525 824 640 384 509 572 797 633 1033 + 434 160 245 346 213 48 59 158 841 42 559 463 98 500 756 230 314 285 + 90 272 326 490 736 684 858 429 941 474 286 250 165 169 201 171 555 619 + 248 196 648 316 804 569 603 324 841 258 294 416 309 837 862 873 197 72 + 872 221 178 478 548 454 832 263 128 337 879 164 228 728 130 706 885 676 + 0 268 658 558 418 717 533 231 402 419 690 480 926 420 53 138 239 199 + 132 204 202 734 72 406 356 243 393 649 123 207 178 185 165 401 383 629 + 577 751 276 834 367 204 236 240 109 86 140 448 512 234 157 495 391 697 + 462 496 166 734 333 187 309 202 730 755 766 272 156 765 296 253 371 441 + 227 699 130 68 230 772 57 303 627 86 599 778 569 107 0 261 519 426 + 279 585 401 141 299 329 558 390 787 422 43 200 232 211 183 294 178 595 + 162 316 342 333 260 510 98 200 171 275 131 455 233 497 445 619 186 702 + 166 114 248 294 67 90 142 316 380 246 159 405 445 558 353 364 76 602 + 387 227 295 195 598 623 627 292 246 633 350 267 261 309 137 567 69 82 + 223 633 90 357 482 176 460 646 437 197 90 0 710 184 271 417 239 487 + 496 530 300 546 249 168 616 823 753 626 800 928 981 841 108 906 321 623 +1020 459 241 715 683 696 967 700 1118 457 583 494 378 451 279 529 696 770 + 957 787 751 814 490 448 840 782 310 1108 184 560 458 655 309 1050 780 577 + 640 393 240 118 955 938 362 1013 930 492 512 558 296 655 859 705 179 777 +1020 269 856 229 353 523 941 834 695 0 396 291 180 177 198 53 297 175 + 268 218 305 410 710 509 439 312 493 621 674 534 382 592 310 273 713 135 + 197 401 369 382 653 386 811 167 157 67 215 268 315 222 389 463 650 480 + 437 507 78 53 533 475 358 801 269 122 32 348 215 743 466 263 326 206 + 236 309 648 624 238 706 623 163 92 251 180 348 545 391 256 463 713 197 + 542 222 259 97 627 520 388 427 0 295 424 278 183 308 118 302 100 354 + 275 442 520 715 491 421 241 498 626 679 539 500 574 400 191 718 141 307 + 383 351 364 635 368 816 172 214 162 342 273 425 227 394 468 655 485 419 + 512 114 151 538 480 495 806 364 40 79 353 325 748 448 178 308 321 346 + 419 653 606 356 711 628 123 93 256 290 353 527 373 366 445 718 281 524 + 365 369 154 609 502 393 537 111 0 651 927 834 687 993 809 513 711 701 + 966 762 1195 407 408 590 622 342 265 282 264 1003 321 688 739 276 668 918 + 506 590 561 401 548 174 641 905 853 1027 558 1110 588 415 379 155 346 480 + 300 724 788 377 325 777 173 966 761 772 453 1010 90 617 692 585 1006 1031 +1035 162 383 1041 96 187 669 717 583 975 492 370 613 1041 482 112 890 409 + 868 1054 845 311 386 440 1103 796 801 0 175 565 472 325 624 440 311 309 + 495 597 583 833 504 128 76 146 283 271 343 260 641 211 541 263 382 300 + 556 32 76 47 272 30 537 290 536 484 658 318 741 222 256 320 376 193 + 56 224 355 419 318 231 636 527 604 369 403 210 641 469 103 216 109 637 + 662 673 374 243 672 432 349 278 423 225 606 104 164 99 679 57 439 528 + 112 506 685 476 246 114 134 741 427 409 522 0 585 67 146 292 135 385 + 371 405 175 458 147 249 499 698 628 501 675 803 856 716 57 781 221 498 + 895 334 131 590 558 571 842 575 993 332 481 392 303 326 215 404 571 645 + 832 662 626 689 365 261 715 657 200 983 74 435 356 530 245 925 655 452 + 515 318 176 62 830 813 287 888 805 367 387 433 232 530 734 580 120 652 + 895 159 731 104 289 421 816 709 570 121 325 438 978 616 0 250 640 540 + 400 699 515 277 384 465 672 526 908 466 99 89 221 245 178 250 220 716 + 96 452 338 289 375 631 105 189 160 151 147 447 365 611 559 733 322 816 + 349 250 282 286 155 76 186 430 494 280 203 541 437 679 444 478 212 716 + 379 138 291 184 712 737 748 318 122 747 342 299 353 423 235 681 138 114 + 212 754 39 349 603 40 581 760 551 138 46 136 816 502 484 432 96 691 + 0 717 221 251 424 137 385 503 499 307 417 301 95 653 830 760 633 807 + 935 988 848 190 913 353 631 1027 459 169 722 690 703 974 707 1125 464 481 + 392 246 458 117 536 703 777 964 794 758 821 402 346 847 789 354 1115 150 + 446 356 662 169 1057 787 584 647 272 125 92 962 945 228 1020 937 487 416 + 565 181 662 866 712 69 784 1027 197 863 236 213 421 948 841 702 162 325 + 435 1110 748 154 823 0 246 454 361 213 373 183 332 130 384 340 472 585 + 745 472 402 237 528 656 709 569 530 555 430 167 748 171 372 364 332 345 + 616 349 846 202 279 227 407 303 490 257 424 498 685 515 400 542 157 221 + 568 510 525 836 429 70 144 383 390 778 429 174 289 386 411 484 683 587 + 421 741 658 153 132 286 355 383 508 354 431 426 748 346 505 395 434 219 + 590 483 423 630 176 65 831 390 505 465 500 0 788 302 322 495 208 456 + 574 570 378 488 372 23 724 901 831 704 818 1006 1059 919 203 984 424 701 +1098 530 240 793 761 774 1045 778 1196 535 552 463 317 529 188 607 774 848 +1035 865 829 892 473 417 918 860 425 1186 221 517 427 733 240 1128 858 655 + 718 343 196 173 1033 1016 299 1091 1008 558 487 636 252 733 937 783 154 855 +1098 268 934 307 284 492 1019 912 773 138 396 506 1181 819 235 894 81 571 + 0 426 596 503 356 662 478 182 380 370 635 431 864 253 183 365 397 27 + 181 234 82 672 237 357 514 273 337 587 281 365 336 317 323 371 310 574 + 522 696 227 779 257 84 19 210 83 255 67 393 457 65 35 446 361 635 + 430 441 122 679 303 392 467 360 675 700 704 208 299 710 266 183 338 386 + 252 644 267 145 388 710 257 273 559 299 537 723 514 227 213 225 772 465 + 470 355 297 647 259 779 500 850 0 596 575 330 377 237 179 497 375 552 + 100 589 407 941 709 639 512 693 821 874 734 421 792 460 467 913 335 236 + 601 569 582 853 586 1011 367 91 117 72 468 259 422 589 663 850 680 637 + 707 278 221 733 675 642 1001 308 316 212 548 153 943 666 463 526 47 212 + 334 848 824 95 906 823 363 292 451 156 548 745 591 268 663 913 241 742 + 506 172 133 827 720 588 452 185 305 996 627 364 702 322 370 393 665 0 + 634 910 817 670 976 792 496 694 684 949 745 1178 414 391 573 605 325 248 + 185 247 986 304 671 722 162 651 901 489 573 544 384 531 32 624 888 836 +1010 541 1093 571 398 362 129 329 463 283 707 771 360 308 760 33 949 744 + 755 436 983 52 600 675 568 989 1014 1018 169 366 1024 122 194 652 700 566 + 958 475 353 596 1024 465 66 873 392 851 1037 828 294 369 423 1086 779 784 + 142 505 961 415 1003 814 1164 339 979 0 507 209 111 201 139 172 408 286 + 213 329 223 351 575 620 550 423 604 732 785 645 275 703 259 384 824 202 + 87 512 480 493 764 497 922 278 268 141 173 252 256 333 500 574 761 591 + 548 618 138 74 644 586 276 912 144 233 143 459 156 854 577 374 437 208 + 177 219 759 735 187 817 734 274 159 362 121 459 656 502 197 574 824 59 + 653 147 200 208 738 631 499 328 112 222 907 538 218 613 266 287 337 576 + 208 890 0 463 186 79 155 157 161 251 216 167 318 206 369 558 576 506 + 379 553 681 734 594 262 659 213 376 773 176 115 468 436 449 720 453 871 + 210 257 168 219 206 274 282 449 523 710 540 504 567 112 48 593 535 259 + 861 172 195 120 408 202 803 533 330 393 254 195 247 708 691 233 766 683 + 204 133 311 167 408 612 458 215 530 773 87 609 121 246 197 694 587 448 + 350 101 199 856 494 225 569 284 269 355 525 251 839 46 0 408 169 105 + 116 242 298 131 229 57 455 118 437 468 315 451 325 341 469 522 382 245 + 525 72 322 561 158 200 413 382 394 605 398 659 155 394 305 344 86 359 + 228 237 311 498 328 362 355 188 160 381 323 169 649 208 259 269 196 327 + 591 478 276 339 391 280 277 496 587 358 554 471 191 211 177 292 260 369 + 403 283 362 561 172 448 110 371 334 515 362 272 345 238 299 644 439 220 + 408 352 329 423 313 388 627 183 137 0 529 389 278 310 236 127 430 308 + 366 125 403 447 755 642 572 445 626 754 807 667 420 725 408 400 846 268 + 235 534 502 515 786 519 944 300 80 68 112 401 299 355 522 596 783 613 + 570 640 211 169 666 608 456 934 307 249 225 481 193 876 599 396 459 89 + 231 353 781 757 135 839 756 296 225 384 175 481 678 524 287 596 846 240 + 675 320 212 84 760 653 521 471 133 238 929 560 363 635 362 303 433 598 + 52 912 156 199 336 0 192 412 319 172 477 293 160 154 342 450 430 680 + 573 228 235 108 383 371 443 360 488 311 388 167 482 153 403 119 165 178 + 372 154 637 126 389 337 511 162 594 71 207 420 476 232 136 324 209 273 + 418 331 482 627 451 246 256 161 494 569 262 120 110 490 515 590 474 343 + 525 532 449 127 202 74 459 96 264 187 526 182 539 375 261 353 538 329 + 346 239 165 588 280 286 622 151 463 221 595 294 666 397 480 605 391 341 + 287 413 0 529 286 231 310 177 165 430 308 319 182 328 379 680 642 572 + 445 626 754 807 667 344 725 365 406 846 268 159 534 502 515 786 519 944 + 300 137 106 75 370 231 355 522 596 783 613 570 640 211 155 666 608 381 + 934 231 255 165 481 125 876 599 396 459 77 155 247 781 757 89 839 756 + 296 225 384 99 481 678 524 211 596 846 164 675 252 148 168 760 653 521 + 365 137 244 929 560 287 635 294 309 365 598 80 912 131 177 314 87 413 + 0 434 710 617 470 776 592 296 494 484 749 545 978 346 191 373 405 125 + 82 142 47 786 145 471 522 145 451 701 289 373 344 225 331 238 424 688 + 636 810 341 893 371 198 162 77 129 263 83 507 571 160 108 560 228 749 + 544 555 236 793 170 400 475 368 789 814 818 76 207 824 133 51 452 500 + 366 758 275 153 396 824 265 140 673 233 651 837 628 135 210 223 886 579 + 584 223 305 761 241 893 614 964 139 779 206 690 639 427 712 405 712 0 + 535 811 718 571 877 693 397 595 585 850 646 1079 336 292 474 506 226 94 + 76 129 887 154 572 623 75 552 802 390 474 445 202 432 175 525 789 737 + 911 442 994 472 299 263 58 230 364 184 608 672 261 209 661 160 850 645 + 656 337 894 140 501 576 469 890 915 919 91 184 925 113 88 553 601 467 + 859 376 176 497 925 276 110 774 242 752 938 729 123 219 324 987 680 685 + 205 406 862 265 994 715 1065 240 880 143 791 740 528 813 506 813 82 0 + 630 108 191 337 165 424 416 450 220 483 188 190 540 743 673 546 720 848 + 901 761 43 826 266 543 940 379 161 635 603 616 887 620 1038 877 520 431 + 315 371 216 449 616 690 877 707 671 734 410 306 760 702 241 1028 104 480 + 395 575 246 970 700 497 560 348 177 55 875 858 299 933 850 412 432 478 + 233 575 779 625 121 697 940 189 776 149 290 460 861 754 615 80 364 474 +1023 661 41 736 147 550 160 692 394 1006 248 270 265 393 508 317 806 907 + 0 446 252 145 227 162 111 347 225 233 268 272 374 624 559 489 362 543 + 671 724 584 346 642 279 323 763 185 161 451 419 432 703 436 861 217 207 + 141 162 272 279 272 439 513 700 530 487 557 128 50 583 525 325 851 233 + 172 82 398 179 793 516 313 376 175 200 273 698 674 176 756 673 213 142 + 301 144 398 595 441 220 513 763 108 592 187 223 147 677 570 438 391 51 + 161 846 477 289 552 289 226 360 515 167 829 49 66 203 115 330 98 629 + 730 319 0 166 518 425 277 437 247 336 114 448 404 536 649 749 435 365 + 150 590 578 650 567 594 518 494 90 689 235 436 402 295 383 579 387 844 + 189 343 291 471 295 554 247 428 627 683 500 363 531 221 285 625 538 589 + 834 493 134 208 372 454 776 392 137 252 450 475 548 681 550 485 739 656 + 150 196 276 419 353 471 317 495 389 746 410 468 459 498 283 553 446 432 + 694 240 129 829 353 569 428 564 80 635 604 434 812 351 333 393 367 257 + 373 612 713 614 290 0 471 313 202 252 166 99 372 250 290 210 358 378 + 679 584 514 387 568 696 749 609 350 667 332 348 788 210 165 476 444 457 + 728 461 886 242 156 61 135 311 276 297 464 538 725 555 512 582 153 93 + 608 550 380 876 237 197 107 423 170 818 541 338 401 147 191 277 723 699 + 149 781 698 238 167 326 135 423 620 466 224 538 788 139 617 244 214 118 + 702 595 462 395 67 186 871 502 293 577 293 251 364 540 128 854 80 123 + 260 76 355 70 654 755 323 39 315 0 442 718 625 478 784 600 304 502 + 492 757 553 986 300 199 381 413 81 137 184 53 794 209 479 530 194 459 + 709 297 381 352 285 339 261 432 696 644 818 349 901 379 206 126 90 137 + 271 91 515 579 111 116 568 259 757 552 563 244 801 185 408 483 376 797 + 822 826 60 267 832 126 35 460 508 374 766 283 161 404 832 273 155 681 + 293 659 845 636 195 270 231 894 587 592 222 313 769 301 901 622 972 108 + 787 229 698 647 435 720 413 720 55 123 814 637 620 662 0 523 230 147 + 304 81 188 424 302 235 255 174 293 596 636 566 439 620 748 801 661 265 + 719 281 400 840 262 75 528 496 509 780 513 938 294 284 195 104 321 193 + 349 516 590 777 607 564 634 205 149 660 602 297 928 147 249 159 475 87 + 870 593 390 453 119 108 192 775 751 118 833 750 290 219 378 52 475 672 + 518 139 590 840 80 669 168 131 224 754 647 515 310 128 238 923 554 208 + 629 208 303 279 592 161 906 69 115 240 160 407 84 706 807 238 92 367 + 87 714 0 566 45 139 273 228 383 352 386 121 540 60 314 411 679 609 + 482 656 784 837 697 81 762 132 479 876 315 189 571 539 552 823 556 974 + 313 479 390 366 307 308 385 552 626 813 643 607 670 346 266 696 638 112 + 964 158 416 342 511 335 906 636 433 496 381 266 155 811 794 380 869 786 + 348 368 414 314 511 715 561 213 633 876 182 712 97 379 419 797 690 551 + 189 323 456 959 597 93 672 247 486 284 628 607 942 244 218 178 421 444 + 346 742 843 124 284 550 345 750 262 0 235 313 220 73 371 187 168 43 + 243 344 331 583 581 348 278 151 364 492 545 405 389 431 289 137 584 48 + 304 240 208 221 492 225 682 32 283 231 405 144 488 93 260 334 521 351 + 276 378 103 167 404 346 384 672 352 95 150 219 388 614 305 94 165 384 + 409 421 519 463 419 577 494 12 92 122 353 219 384 230 429 302 584 276 + 381 254 432 223 466 359 259 489 174 135 667 266 364 341 498 165 569 336 + 374 650 285 215 188 307 115 307 450 551 409 224 154 249 458 301 345 0 + 432 822 722 582 881 697 441 566 629 854 690 1090 491 217 302 403 270 105 + 69 215 898 99 616 520 108 557 813 287 371 342 77 329 383 547 793 741 + 915 486 998 531 343 307 222 226 258 228 612 676 305 253 705 373 861 626 + 660 381 898 315 351 473 366 894 919 930 254 66 929 278 235 535 605 511 + 863 320 185 394 936 221 285 785 177 763 942 733 57 164 254 998 684 666 + 368 303 873 195 1005 647 1076 284 884 351 795 751 572 817 403 817 192 145 + 819 734 610 759 252 811 854 523 0 435 653 560 413 719 535 239 437 427 + 692 488 921 220 192 374 406 29 190 243 64 729 246 414 523 282 394 644 + 290 374 345 326 332 380 367 631 579 753 284 836 314 141 78 219 123 264 + 84 450 514 34 75 503 370 692 487 498 179 736 312 401 476 369 732 757 + 761 137 308 767 275 112 395 443 309 701 276 154 397 767 266 282 616 308 + 594 780 571 236 222 234 829 522 527 365 306 704 268 836 557 907 56 722 + 348 633 582 370 655 406 655 148 249 749 572 613 597 77 649 685 393 293 + 0 369 167 79 77 205 259 153 190 97 416 185 435 537 482 412 286 459 + 587 640 500 243 555 111 283 679 119 163 375 343 356 626 360 777 116 355 + 266 305 108 322 189 356 429 616 446 411 473 149 121 499 441 238 767 206 + 220 230 315 288 709 439 237 300 352 243 275 614 587 319 672 589 152 172 + 218 253 315 518 364 281 436 679 135 515 108 332 295 600 493 355 343 199 + 260 762 401 218 475 350 290 421 431 349 745 144 98 39 297 248 275 545 + 646 263 164 354 221 553 201 199 149 657 488 0 121 511 418 271 570 386 + 309 255 441 543 529 779 518 142 99 84 297 285 357 274 587 225 487 209 + 396 246 502 35 29 42 286 36 551 236 482 430 604 316 687 220 268 334 + 390 207 70 238 301 365 332 245 581 541 550 315 349 222 587 483 126 162 + 55 583 608 619 388 257 618 446 363 224 294 249 552 104 178 60 625 96 + 453 474 175 452 631 422 260 153 146 687 373 355 536 47 562 135 694 336 + 765 311 573 519 484 440 386 506 169 506 319 520 607 423 299 448 327 500 + 543 212 317 320 347 0 +DISPLAY_DATA_SECTION + 1 8.0 124.0 + 2 125.0 80.0 + 3 97.0 74.0 + 4 69.0 96.0 + 5 106.0 46.0 + 6 49.0 57.0 + 7 80.0 125.0 + 8 42.0 93.0 + 9 104.0 94.0 + 10 35.0 17.0 + 11 118.0 96.0 + 12 151.0 22.0 + 13 154.0 182.0 + 14 57.0 165.0 + 15 18.0 159.0 + 16 27.0 123.0 + 17 96.0 170.0 + 18 63.0 198.0 + 19 59.0 211.0 + 20 88.0 182.0 + 21 142.0 72.0 + 22 48.0 190.0 + 23 106.0 106.0 + 24 28.0 102.0 + 25 63.0 224.0 + 26 58.0 93.0 + 27 103.0 56.0 + 28 38.0 149.0 + 29 23.0 138.0 + 30 22.0 146.0 + 31 32.0 208.0 + 32 27.0 144.0 + 33 75.0 258.0 + 34 59.0 101.0 + 35 41.0 32.0 + 36 53.0 46.0 + 37 76.0 19.0 + 38 79.0 115.0 + 39 109.0 13.0 + 40 59.0 118.0 + 41 84.0 147.0 + 42 95.0 160.0 + 43 87.0 213.0 + 44 73.0 166.0 + 45 43.0 153.0 + 46 81.0 175.0 + 47 59.0 77.0 + 48 70.0 68.0 + 49 106.0 169.0 + 50 86.0 168.0 + 51 127.0 109.0 + 52 68.0 243.0 + 53 116.0 57.0 + 54 39.0 78.0 + 55 54.0 65.0 + 56 77.0 141.0 + 57 95.0 24.0 + 58 89.0 238.0 + 59 9.0 158.0 + 60 39.0 109.0 + 61 25.0 129.0 + 62 69.0 20.0 + 63 104.0 34.0 + 64 132.0 51.0 + 65 98.0 207.0 + 66 37.0 203.0 + 67 80.0 16.0 + 68 103.0 224.0 + 69 94.0 202.0 + 70 49.0 96.0 + 71 55.0 80.0 + 72 62.0 123.0 + 73 91.0 31.0 + 74 51.0 142.0 + 75 64.0 172.0 + 76 14.0 138.0 + 77 120.0 37.0 + 78 38.0 160.0 + 79 86.0 230.0 + 80 96.0 59.0 + 81 33.0 177.0 + 82 108.0 78.0 + 83 93.0 12.0 + 84 43.0 47.0 + 85 52.0 200.0 + 86 48.0 171.0 + 87 62.0 153.0 + 88 159.0 53.0 + 89 60.0 60.0 + 90 36.0 73.0 + 91 111.0 243.0 + 92 31.0 150.0 + 93 130.0 67.0 + 94 36.0 172.0 + 95 132.0 28.0 + 96 29.0 73.0 + 97 150.0 28.0 + 98 89.0 166.0 + 99 58.0 21.0 + 100 78.0 244.0 + 101 82.0 58.0 + 102 81.0 68.0 + 103 92.0 98.0 + 104 56.0 33.0 + 105 47.0 126.0 + 106 70.0 34.0 + 107 78.0 195.0 + 108 77.0 215.0 + 109 140.0 62.0 + 110 70.0 57.0 + 111 16.0 89.0 + 112 66.0 50.0 + 113 98.0 194.0 + 114 87.0 45.0 + 115 132.0 87.0 + 116 52.0 99.0 + 117 50.0 212.0 + 118 103.0 176.0 + 119 84.0 91.0 + 120 31.0 140.0 +EOF diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/main.c b/resources/3rdparty/glpk-4.57/examples/tsp/main.c new file mode 100644 index 000000000..822af324a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/main.c @@ -0,0 +1,535 @@ +/* main.c */ + +/* Written by Andrew Makhorin , October 2015. */ + +/*********************************************************************** +* This program is a stand-alone solver intended for solving Symmetric +* Traveling Salesman Problem (TSP) with the branch-and-bound method. +* +* Please note that this program is only an illustrative example. It is +* *not* a state-of-the-art code, so only small TSP instances (perhaps, +* having up to 150-200 nodes) can be solved with this code. +* +* To run this program use the following command: +* +* tspsol tsp-file +* +* where tsp-file specifies an input text file containing TSP data in +* TSPLIB 95 format. +* +* Detailed description of the input format recognized by this program +* is given in the report: Gerhard Reinelt, "TSPLIB 95". This report as +* well as TSPLIB, a library of sample TSP instances (and other related +* problems), are freely available for research purposes at the webpage +* . +* +* Symmetric Traveling Salesman Problem +* ------------------------------------ +* Let a complete undirected graph be given: +* +* K = (V, E), (1) +* +* where V = {1, ..., n} is a set of nodes, E = V cross V is a set of +* edges. Let also each edge e = (i,j) be assigned a positive number +* c[i,j], which is the length of e. The Symmetric Traveling Salesman +* Problem (TSP) is to find a tour in K of minimal length. +* +* Integer programming formulation of TSP +* -------------------------------------- +* For a set of nodes W within V introduce the following notation: +* +* d(W) = {(i,j):i in W and j not in W or i not in W and j in W}, (2) +* +* i.e. d(W) is the set of edges which have exactly one endnode in W. +* If W = {v}, i.e. W consists of the only node, we write simply d(v). +* +* The integer programming formulation of TSP is the following: +* +* minimize sum c[i,j] * x[i,j] (3) +* i,j +* +* subject to sum x[i,j] = 2 for all v in V (4) +* (i,j) in d(v) +* +* sum x[i,j] >= 2 for all W within V, (5) +* (i,j) in d(W) W != empty, W != V +* +* x[i,j] in {0, 1} for all i, j (6) +* +* The binary variables x[i,j] have conventional meaning: if x[i,j] = 1, +* the edge (i,j) is included in the tour, otherwise, if x[i,j] = 0, the +* edge is not included in the tour. +* +* The constraints (4) are called degree constraints. They require that +* for each node v in V there must be exactly two edges included in the +* tour which are incident to v. +* +* The constraints (5) are called subtour elimination constraints. They +* are used to forbid subtours. Note that the number of the subtour +* elimination constraints grows exponentially on the size of the TSP +* instance, so these constraints are not included explicitly in the +* IP, but generated dynamically during the B&B search. +***********************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include "maxflow.h" +#include "mincut.h" +#include "misc.h" +#include "tsplib.h" + +int n; +/* number of nodes in the problem, n >= 2 */ + +int *c; /* int c[1+n*(n-1)/2]; */ +/* upper triangle (without diagonal entries) of the (symmetric) matrix + * C = (c[i,j]) in row-wise format, where c[i,j] specifies a length of + * edge e = (i,j), 1 <= i < j <= n */ + +int *tour; /* int tour[1+n]; */ +/* solution to TSP, which is a tour specified by the list of node + * numbers tour[1] -> ... -> tour[nn] -> tour[1] in the order the nodes + * are visited; note that any tour is a permutation of node numbers */ + +glp_prob *P; +/* integer programming problem object */ + +/*********************************************************************** +* loc - determine reduced index of element of symmetric matrix +* +* Given indices i and j of an element of a symmetric nxn-matrix, +* 1 <= i, j <= n, i != j, this routine returns the index of that +* element in an array, which is the upper triangle (without diagonal +* entries) of the matrix in row-wise format. */ + +int loc(int i, int j) +{ xassert(1 <= i && i <= n); + xassert(1 <= j && j <= n); + xassert(i != j); + if (i < j) + return ((n - 1) + (n - i + 1)) * (i - 1) / 2 + (j - i); + else + return loc(j, i); +} + +/*********************************************************************** +* read_data - read TSP data +* +* This routine reads TSP data from a specified text file in TSPLIB 95 +* format. */ + +void read_data(const char *fname) +{ TSP *tsp; + int i, j; + tsp = tsp_read_data(fname); + if (tsp == NULL) + { xprintf("TSP data file processing error\n"); + exit(EXIT_FAILURE); + } + if (tsp->type != TSP_TSP) + { xprintf("Invalid TSP data type\n"); + exit(EXIT_FAILURE); + } + n = tsp->dimension; + xassert(n >= 2); + if (n > 32768) + { xprintf("TSP instance too large\n"); + exit(EXIT_FAILURE); + } + c = xalloc(1+loc(n-1, n), sizeof(int)); + for (i = 1; i <= n; i++) + { for (j = i+1; j <= n; j++) + c[loc(i, j)] = tsp_distance(tsp, i, j); + } + tsp_free_data(tsp); + return; +} + +/*********************************************************************** +* build_prob - build initial integer programming problem +* +* This routine builds the initial integer programming problem, which +* includes all variables (6), objective (3) and all degree constraints +* (4). Subtour elimination constraints (5) are considered "lazy" and +* not included in the initial problem. */ + +void build_prob(void) +{ int i, j, k, *ind; + double *val; + char name[50]; + /* create problem object */ + P = glp_create_prob(); + /* add all binary variables (6) */ + for (i = 1; i <= n; i++) + { for (j = i+1; j <= n; j++) + { k = glp_add_cols(P, 1); + xassert(k == loc(i,j)); + sprintf(name, "x[%d,%d]", i, j); + glp_set_col_name(P, k, name); + glp_set_col_kind(P, k, GLP_BV); + /* set objective coefficient (3) */ + glp_set_obj_coef(P, k, c[k]); + } + } + /* add all degree constraints (4) */ + ind = xalloc(1+n, sizeof(int)); + val = xalloc(1+n, sizeof(double)); + for (i = 1; i <= n; i++) + { k = glp_add_rows(P, 1); + xassert(k == i); + sprintf(name, "v[%d]", i); + glp_set_row_name(P, i, name); + glp_set_row_bnds(P, i, GLP_FX, 2, 2); + k = 0; + for (j = 1; j <= n; j++) + { if (i != j) + k++, ind[k] = loc(i,j), val[k] = 1; + } + xassert(k == n-1); + glp_set_mat_row(P, i, n-1, ind, val); + } + xfree(ind); + xfree(val); + return; +} + +/*********************************************************************** +* build_tour - build tour for corresponding solution to IP +* +* Given a feasible solution to IP (3)-(6) this routine builds the +* corresponding solution to TSP, which is a tour specified by the list +* of node numbers tour[1] -> ... -> tour[nn] -> tour[1] in the order +* the nodes are to be visited */ + +void build_tour(void) +{ int i, j, k, kk, *beg, *end; + /* solution to MIP should be feasible */ + switch (glp_mip_status(P)) + { case GLP_FEAS: + case GLP_OPT: + break; + default: + xassert(P != P); + } + /* build the list of edges included in the tour */ + beg = xalloc(1+n, sizeof(int)); + end = xalloc(1+n, sizeof(int)); + k = 0; + for (i = 1; i <= n; i++) + { for (j = i+1; j <= n; j++) + { double x; + x = glp_mip_col_val(P, loc(i,j)); + xassert(x == 0 || x == 1); + if (x) + { k++; + xassert(k <= n); + beg[k] = i, end[k] = j; + } + } + } + xassert(k == n); + /* reorder edges in the list as they follow in the tour */ + for (k = 1; k <= n; k++) + { /* find k-th edge of the tour */ + j = (k == 1 ? 1 : end[k-1]); + for (kk = k; kk <= n; kk++) + { if (beg[kk] == j) + break; + if (end[kk] == j) + { end[kk] = beg[kk], beg[kk] = j; + break; + } + } + xassert(kk <= n); + /* put the edge to k-th position in the list */ + i = beg[k], beg[k] = beg[kk], beg[kk] = i; + j = end[k], end[k] = end[kk], end[kk] = j; + } + /* build the tour starting from node 1 */ + xassert(beg[1] == 1); + for (k = 1; k <= n; k++) + { if (k > 1) + xassert(end[k-1] == beg[k]); + tour[k] = beg[k]; + } + xassert(end[n] == 1); + xfree(beg); + xfree(end); + return; +} + +/*********************************************************************** +* tour_length - calculate tour length +* +* This routine calculates the length of the specified tour, which is +* a sum of corresponding edge length. */ + +int tour_length(const int tour[/*1+n*/]) +{ int i, j, sum; + sum = 0; + for (i = 1; i <= n; i++) + { j = (i < n ? i+1 : 1); + sum += c[loc(tour[i], tour[j])]; + } + return sum; +} + +/*********************************************************************** +* write_tour - write tour to text file in TSPLIB format +* +* This routine writes the specified tour to a text file in TSPLIB +* format. */ + +void write_tour(const char *fname, const int tour[/*1+n*/]) +{ FILE *fp; + int i; + xprintf("Writing TSP solution to '%s'...\n", fname); + fp = fopen(fname, "w"); + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, + strerror(errno)); + return; + } + fprintf(fp, "NAME : %s\n", fname); + fprintf(fp, "COMMENT : Tour length is %d\n", tour_length(tour)); + fprintf(fp, "TYPE : TOUR\n"); + fprintf(fp, "DIMENSION : %d\n", n); + fprintf(fp, "TOUR_SECTION\n"); + for (i = 1; i <= n; i++) + fprintf(fp, "%d\n", tour[i]); + fprintf(fp, "-1\n"); + fprintf(fp, "EOF\n"); + fclose(fp); + return; +} + +/*********************************************************************** +* gen_subt_row - generate violated subtour elimination constraint +* +* This routine is called from the MIP solver to generate a violated +* subtour elimination constraint (5). +* +* Constraints of this class has the form: +* +* sum x[i,j] >= 2, i in W, j in V \ W, +* +* for all W, where W is a proper nonempty subset of V, V is the set of +* nodes of the given graph. +* +* In order to find a violated constraint of this class this routine +* finds a min cut in a capacitated network, which has the same sets of +* nodes and edges as the original graph, and where capacities of edges +* are values of variables x[i,j] in a basic solution to LP relaxation +* of the current subproblem. */ + +void gen_subt(glp_tree *T) +{ int i, j, ne, nz, *beg, *end, *cap, *cut, *ind; + double sum, *val; + /* MIP preprocessor should not be used */ + xassert(glp_ios_get_prob(T) == P); + /* if some variable x[i,j] is zero in basic solution, then the + * capacity of corresponding edge in the associated network is + * zero, so we may not include such edge in the network */ + /* count number of edges having non-zero capacity */ + ne = 0; + for (i = 1; i <= n; i++) + { for (j = i+1; j <= n; j++) + { if (glp_get_col_prim(P, loc(i,j)) >= .001) + ne++; + } + } + /* build the capacitated network */ + beg = xalloc(1+ne, sizeof(int)); + end = xalloc(1+ne, sizeof(int)); + cap = xalloc(1+ne, sizeof(int)); + nz = 0; + for (i = 1; i <= n; i++) + { for (j = i+1; j <= n; j++) + { if (glp_get_col_prim(P, loc(i,j)) >= .001) + { nz++; + xassert(nz <= ne); + beg[nz] = i, end[nz] = j; + /* scale all edge capacities to make them integral */ + cap[nz] = ceil(1000 * glp_get_col_prim(P, loc(i,j))); + } + } + } + xassert(nz == ne); + /* find minimal cut in the capacitated network */ + cut = xalloc(1+n, sizeof(int)); + min_cut(n, ne, beg, end, cap, cut); + /* determine the number of non-zero coefficients in the subtour + * elimination constraint and calculate its left-hand side which + * is the (unscaled) capacity of corresponding min cut */ + ne = 0, sum = 0; + for (i = 1; i <= n; i++) + { for (j = i+1; j <= n; j++) + { if (cut[i] && !cut[j] || !cut[i] && cut[j]) + { ne++; + sum += glp_get_col_prim(P, loc(i,j)); + } + } + } + /* if the (unscaled) capacity of min cut is less than 2, the + * corresponding subtour elimination constraint is violated */ + if (sum <= 1.999) + { /* build the list of non-zero coefficients */ + ind = xalloc(1+ne, sizeof(int)); + val = xalloc(1+ne, sizeof(double)); + nz = 0; + for (i = 1; i <= n; i++) + { for (j = i+1; j <= n; j++) + { if (cut[i] && !cut[j] || !cut[i] && cut[j]) + { nz++; + xassert(nz <= ne); + ind[nz] = loc(i,j); + val[nz] = 1; + } + } + } + xassert(nz == ne); + /* add violated tour elimination constraint to the current + * subproblem */ + i = glp_add_rows(P, 1); + glp_set_row_bnds(P, i, GLP_LO, 2, 0); + glp_set_mat_row(P, i, nz, ind, val); + xfree(ind); + xfree(val); + } + /* free working arrays */ + xfree(beg); + xfree(end); + xfree(cap); + xfree(cut); + return; +} + +/*********************************************************************** +* cb_func - application callback routine +* +* This routine is called from the MIP solver at various points of +* the branch-and-cut algorithm. */ + +void cb_func(glp_tree *T, void *info) +{ xassert(info == info); + switch (glp_ios_reason(T)) + { case GLP_IROWGEN: + /* generate one violated subtour elimination constraint */ + gen_subt(T); + break; + } + return; +} + +/*********************************************************************** +* main - TSP solver main program +* +* This main program parses command-line arguments, reads specified TSP +* instance from a text file, and calls the MIP solver to solve it. */ + +int main(int argc, char *argv[]) +{ int j; + char *in_file = NULL, *out_file = NULL; + time_t start; + glp_iocp iocp; + /* parse command-line arguments */ +# define p(str) (strcmp(argv[j], str) == 0) + for (j = 1; j < argc; j++) + { if (p("--output") || p("-o")) + { j++; + if (j == argc || argv[j][0] == '\0' || argv[j][0] == '-') + { xprintf("No solution output file specified\n"); + exit(EXIT_FAILURE); + } + if (out_file != NULL) + { xprintf("Only one solution output file allowed\n"); + exit(EXIT_FAILURE); + } + out_file = argv[j]; + } + else if (p("--help") || p("-h")) + { xprintf("Usage: %s [options...] tsp-file\n", argv[0]); + xprintf("\n"); + xprintf("Options:\n"); + xprintf(" -o filename, --output filename\n"); + xprintf(" write solution to filename\n") + ; + xprintf(" -h, --help display this help information" + " and exit\n"); + exit(EXIT_SUCCESS); + } + else if (argv[j][0] == '-' || + (argv[j][0] == '-' && argv[j][1] == '-')) + { xprintf("Invalid option '%s'; try %s --help\n", argv[j], + argv[0]); + exit(EXIT_FAILURE); + } + else + { if (in_file != NULL) + { xprintf("Only one input file allowed\n"); + exit(EXIT_FAILURE); + } + in_file = argv[j]; + } + } + if (in_file == NULL) + { xprintf("No input file specified; try %s --help\n", argv[0]); + exit(EXIT_FAILURE); + } +# undef p + /* display program banner */ + xprintf("TSP Solver for GLPK %s\n", glp_version()); + /* remove output solution file specified in command-line */ + if (out_file != NULL) + remove(out_file); + /* read TSP instance from input data file */ + read_data(in_file); + /* build initial IP problem */ + start = time(NULL); + build_prob(); + tour = xalloc(1+n, sizeof(int)); + /* solve LP relaxation of initial IP problem */ + xprintf("Solving initial LP relaxation...\n"); + xassert(glp_simplex(P, NULL) == 0); + xassert(glp_get_status(P) == GLP_OPT); + /* solve IP problem with "lazy" constraints */ + glp_init_iocp(&iocp); + iocp.br_tech = GLP_BR_MFV; /* most fractional variable */ + iocp.bt_tech = GLP_BT_BLB; /* best local bound */ + iocp.sr_heur = GLP_OFF; /* disable simple rounding heuristic */ + iocp.gmi_cuts = GLP_ON; /* enable Gomory cuts */ + iocp.cb_func = cb_func; + glp_intopt(P, &iocp); + build_tour(); + /* display some statistics */ + xprintf("Time used: %.1f secs\n", difftime(time(NULL), start)); + { size_t tpeak; + glp_mem_usage(NULL, NULL, NULL, &tpeak); + xprintf("Memory used: %.1f Mb (%.0f bytes)\n", + (double)tpeak / 1048576.0, (double)tpeak); + } + /* write solution to output file, if required */ + if (out_file != NULL) + write_tour(out_file, tour); + /* deallocate working objects */ + xfree(c); + xfree(tour); + glp_delete_prob(P); + /* check that no memory blocks are still allocated */ + { int count; + size_t total; + glp_mem_usage(&count, NULL, &total, NULL); + if (count != 0) + xerror("Error: %d memory block(s) were lost\n", count); + xassert(total == 0); + } + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/maxflow.c b/resources/3rdparty/glpk-4.57/examples/tsp/maxflow.c new file mode 100644 index 000000000..c28f5274d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/maxflow.c @@ -0,0 +1,170 @@ +/* maxflow.c */ + +/* Written by Andrew Makhorin , October 2015. */ + +#include + +#include +#include "maxflow.h" +#include "misc.h" + +/*********************************************************************** +* NAME +* +* max_flow - find max flow in undirected capacitated network +* +* SYNOPSIS +* +* #include "maxflow.h" +* int max_flow(int nn, int ne, const int beg[], const int end[], +* const int cap[], int s, int t, int x[]); +* +* DESCRIPTION +* +* This routine finds max flow in a given undirected network. +* +* The undirected capacitated network is specified by the parameters +* nn, ne, beg, end, and cap. The parameter nn specifies the number of +* vertices (nodes), nn >= 2, and the parameter ne specifies the number +* of edges, ne >= 0. The network edges are specified by triplets +* (beg[k], end[k], cap[k]) for k = 1, ..., ne, where beg[k] < end[k] +* are numbers of the first and second nodes of k-th edge, and +* cap[k] > 0 is a capacity of k-th edge. Loops and multiple edges are +* not allowed. +* +* The parameter s is the number of a source node, and the parameter t +* is the number of a sink node, s != t. +* +* On exit the routine computes elementary flows thru edges and stores +* their values to locations x[1], ..., x[ne]. Positive value of x[k] +* means that the elementary flow goes from node beg[k] to node end[k], +* and negative value means that the flow goes in opposite direction. +* +* RETURNS +* +* The routine returns the total maximum flow through the network. */ + +int max_flow(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t, + int x[/*1+ne*/]) +{ int k; + /* sanity checks */ + xassert(nn >= 2); + xassert(ne >= 0); + xassert(1 <= s && s <= nn); + xassert(1 <= t && t <= nn); + xassert(s != t); + for (k = 1; k <= ne; k++) + { xassert(1 <= beg[k] && beg[k] < end[k] && end[k] <= nn); + xassert(cap[k] > 0); + } + /* find max flow */ + return max_flow_lp(nn, ne, beg, end, cap, s, t, x); +} + +/*********************************************************************** +* NAME +* +* max_flow_lp - find max flow with simplex method +* +* SYNOPSIS +* +* #include "maxflow.h" +* int max_flow_lp(int nn, int ne, const int beg[], const int end[], +* const int cap[], int s, int t, int x[]); +* +* DESCRIPTION +* +* This routine finds max flow in a given undirected network with the +* simplex method. +* +* Parameters of this routine have the same meaning as for the routine +* max_flow (see above). +* +* RETURNS +* +* The routine returns the total maximum flow through the network. */ + +int max_flow_lp(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t, + int x[/*1+ne*/]) +{ glp_prob *lp; + glp_smcp smcp; + int i, k, nz, flow, *rn, *cn; + double temp, *aa; + /* create LP problem instance */ + lp = glp_create_prob(); + /* create LP rows; i-th row is the conservation condition of the + * flow at i-th node, i = 1, ..., nn */ + glp_add_rows(lp, nn); + for (i = 1; i <= nn; i++) + glp_set_row_bnds(lp, i, GLP_FX, 0.0, 0.0); + /* create LP columns; k-th column is the elementary flow thru + * k-th edge, k = 1, ..., ne; the last column with the number + * ne+1 is the total flow through the network, which goes along + * a dummy feedback edge from the sink to the source */ + glp_add_cols(lp, ne+1); + for (k = 1; k <= ne; k++) + { xassert(cap[k] > 0); + glp_set_col_bnds(lp, k, GLP_DB, -cap[k], +cap[k]); + } + glp_set_col_bnds(lp, ne+1, GLP_FR, 0.0, 0.0); + /* build the constraint matrix; structurally this matrix is the + * incidence matrix of the network, so each its column (including + * the last column for the dummy edge) has exactly two non-zero + * entries */ + rn = xalloc(1+2*(ne+1), sizeof(int)); + cn = xalloc(1+2*(ne+1), sizeof(int)); + aa = xalloc(1+2*(ne+1), sizeof(double)); + nz = 0; + for (k = 1; k <= ne; k++) + { /* x[k] > 0 means the elementary flow thru k-th edge goes from + * node beg[k] to node end[k] */ + nz++, rn[nz] = beg[k], cn[nz] = k, aa[nz] = -1.0; + nz++, rn[nz] = end[k], cn[nz] = k, aa[nz] = +1.0; + } + /* total flow thru the network goes from the sink to the source + * along the dummy feedback edge */ + nz++, rn[nz] = t, cn[nz] = ne+1, aa[nz] = -1.0; + nz++, rn[nz] = s, cn[nz] = ne+1, aa[nz] = +1.0; + /* check the number of non-zero entries */ + xassert(nz == 2*(ne+1)); + /* load the constraint matrix into the LP problem object */ + glp_load_matrix(lp, nz, rn, cn, aa); + xfree(rn); + xfree(cn); + xfree(aa); + /* objective function is the total flow through the network to + * be maximized */ + glp_set_obj_dir(lp, GLP_MAX); + glp_set_obj_coef(lp, ne + 1, 1.0); + /* solve LP instance with the (primal) simplex method */ + glp_term_out(0); + glp_adv_basis(lp, 0); + glp_term_out(1); + glp_init_smcp(&smcp); + smcp.msg_lev = GLP_MSG_ON; + smcp.out_dly = 5000; + xassert(glp_simplex(lp, &smcp) == 0); + xassert(glp_get_status(lp) == GLP_OPT); + /* obtain optimal elementary flows thru edges of the network */ + /* (note that the constraint matrix is unimodular and the data + * are integral, so all elementary flows in basic solution should + * also be integral) */ + for (k = 1; k <= ne; k++) + { temp = glp_get_col_prim(lp, k); + x[k] = (int)floor(temp + .5); + xassert(fabs(x[k] - temp) <= 1e-6); + } + /* obtain the maximum flow thru the original network which is the + * flow thru the dummy feedback edge */ + temp = glp_get_col_prim(lp, ne+1); + flow = (int)floor(temp + .5); + xassert(fabs(flow - temp) <= 1e-6); + /* delete LP problem instance */ + glp_delete_prob(lp); + /* return to the calling program */ + return flow; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/maxflow.h b/resources/3rdparty/glpk-4.57/examples/tsp/maxflow.h new file mode 100644 index 000000000..245c5ec12 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/maxflow.h @@ -0,0 +1,20 @@ +/* maxflow.h */ + +/* Written by Andrew Makhorin , October 2015. */ + +#ifndef MAXFLOW_H +#define MAXFLOW_H + +int max_flow(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t, + int x[/*1+ne*/]); +/* find max flow in undirected capacitated network */ + +int max_flow_lp(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t, + int x[/*1+ne*/]); +/* find max flow with simplex method */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/mincut.c b/resources/3rdparty/glpk-4.57/examples/tsp/mincut.c new file mode 100644 index 000000000..46905aa0e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/mincut.c @@ -0,0 +1,392 @@ +/* mincut.c */ + +/* Written by Andrew Makhorin , October 2015. */ + +#include + +#include "maxflow.h" +#include "mincut.h" +#include "misc.h" + +/*********************************************************************** +* NAME +* +* min_cut - find min cut in undirected capacitated network +* +* SYNOPSIS +* +* #include "mincut.h" +* int min_cut(int nn, int ne, const int beg[], const int end[], +* const cap[], int cut[]); +* +* DESCRIPTION +* +* This routine find min cut in a given undirected network. +* +* The undirected capacitated network is specified by the parameters +* nn, ne, beg, end, and cap. The parameter nn specifies the number of +* vertices (nodes), nn >= 2, and the parameter ne specifies the number +* of edges, ne >= 0. The network edges are specified by triplets +* (beg[k], end[k], cap[k]) for k = 1, ..., ne, where beg[k] < end[k] +* are numbers of the first and second nodes of k-th edge, and +* cap[k] > 0 is a capacity of k-th edge. Loops and multiple edges are +* not allowed. +* +* Let V be the set of nodes of the network and let W be an arbitrary +* non-empty proper subset of V. A cut associated with the subset W is +* a subset of all the edges, one node of which belongs to W and other +* node belongs to V \ W. The capacity of a cut (W, V \ W) is the sum +* of the capacities of all the edges, which belong to the cut. Minimal +* cut is a cut, whose capacity is minimal. +* +* On exit the routine stores flags of nodes v[i], i = 1, ..., nn, to +* locations cut[i], where cut[i] = 1 means that v[i] belongs to W and +* cut[i] = 0 means that v[i] belongs to V \ W, where W corresponds to +* the minimal cut found. +* +* RETURNS +* +* The routine returns the capacity of the min cut found. */ + +int min_cut(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const cap[/*1+ne*/], int cut[/*1+nn*/]) +{ int k; + /* sanity checks */ + xassert(nn >= 2); + xassert(ne >= 0); + for (k = 1; k <= ne; k++) + { xassert(1 <= beg[k] && beg[k] < end[k] && end[k] <= nn); + xassert(cap[k] > 0); + } + /* find min cut */ + return min_cut_sw(nn, ne, beg, end, cap, cut); +} + +/*********************************************************************** +* NAME +* +* min_st_cut - find min (s,t)-cut for known max flow +* +* SYNOPSIS +* +* #include "mincut.h" +* +* DESCRIPTION +* +* This routine finds min (s,t)-cut in a given undirected network that +* corresponds to a known max flow from s to t in the network. +* +* Parameters nn, ne, beg, end, and cap specify the network in the same +* way as for the routine min_cut (see above). +* +* Parameters s and t specify, resp., the number of the source node +* and the number of the sink node, s != t, for which the min (s,t)-cut +* has to be found. +* +* Parameter x specifies the known max flow from s to t in the network, +* where locations x[1], ..., x[ne] contains elementary flow thru edges +* of the network (positive value of x[k] means that the elementary +* flow goes from node beg[k] to node end[k], and negative value means +* that the flow goes in opposite direction). +* +* This routine splits the set of nodes V of the network into two +* non-empty subsets V(s) and V(t) = V \ V(s), where the source node s +* belongs to V(s), the sink node t belongs to V(t), and all edges, one +* node of which belongs to V(s) and other one belongs to V(t), are +* saturated (that is, x[k] = +cap[k] or x[k] = -cap[k]). +* +* On exit the routine stores flags of the nodes v[i], i = 1, ..., nn, +* to locations cut[i], where cut[i] = 1 means that v[i] belongs to V(s) +* and cut[i] = 0 means that v[i] belongs to V(t) = V \ V(s). +* +* RETURNS +* +* The routine returns the capacity of min (s,t)-cut, which is the sum +* of the capacities of all the edges, which belong to the cut. (Note +* that due to theorem by Ford and Fulkerson this value is always equal +* to corresponding max flow.) +* +* ALGORITHM +* +* To determine the set V(s) the routine simply finds all nodes, which +* can be reached from the source node s via non-saturated edges. The +* set V(t) is determined as the complement V \ V(s). */ + +int min_st_cut(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t, + const int x[/*1+ne*/], int cut[/*1+nn*/]) +{ int i, j, k, p, q, temp, *head1, *next1, *head2, *next2, *list; + /* head1[i] points to the first edge with beg[k] = i + * next1[k] points to the next edge with the same beg[k] + * head2[i] points to the first edge with end[k] = i + * next2[k] points to the next edge with the same end[k] */ + head1 = xalloc(1+nn, sizeof(int)); + head2 = xalloc(1+nn, sizeof(int)); + next1 = xalloc(1+ne, sizeof(int)); + next2 = xalloc(1+ne, sizeof(int)); + for (i = 1; i <= nn; i++) + head1[i] = head2[i] = 0; + for (k = 1; k <= ne; k++) + { i = beg[k], next1[k] = head1[i], head1[i] = k; + j = end[k], next2[k] = head2[j], head2[j] = k; + } + /* on constructing the set V(s) list[1], ..., list[p-1] contain + * nodes, which can be reached from source node and have been + * visited, and list[p], ..., list[q] contain nodes, which can be + * reached from source node but havn't been visited yet */ + list = xalloc(1+nn, sizeof(int)); + for (i = 1; i <= nn; i++) + cut[i] = 0; + p = q = 1, list[1] = s, cut[s] = 1; + while (p <= q) + { /* pick next node, which is reachable from the source node and + * has not visited yet, and visit it */ + i = list[p++]; + /* walk through edges with beg[k] = i */ + for (k = head1[i]; k != 0; k = next1[k]) + { j = end[k]; + xassert(beg[k] == i); + /* from v[i] we can reach v[j], if the elementary flow from + * v[i] to v[j] is non-saturated */ + if (cut[j] == 0 && x[k] < +cap[k]) + list[++q] = j, cut[j] = 1; + } + /* walk through edges with end[k] = i */ + for (k = head2[i]; k != 0; k = next2[k]) + { j = beg[k]; + xassert(end[k] == i); + /* from v[i] we can reach v[j], if the elementary flow from + * v[i] to v[j] is non-saturated */ + if (cut[j] == 0 && x[k] > -cap[k]) + list[++q] = j, cut[j] = 1; + } + } + /* sink cannot belong to V(s) */ + xassert(!cut[t]); + /* free working arrays */ + xfree(head1); + xfree(head2); + xfree(next1); + xfree(next2); + xfree(list); + /* compute capacity of the minimal (s,t)-cut found */ + temp = 0; + for (k = 1; k <= ne; k++) + { i = beg[k], j = end[k]; + if (cut[i] && !cut[j] || !cut[i] && cut[j]) + temp += cap[k]; + } + /* return to the calling program */ + return temp; +} + +/*********************************************************************** +* NAME +* +* min_cut_sw - find min cut with Stoer and Wagner algorithm +* +* SYNOPSIS +* +* #include "mincut.h" +* int min_cut_sw(int nn, int ne, const int beg[], const int end[], +* const cap[], int cut[]); +* +* DESCRIPTION +* +* This routine find min cut in a given undirected network with the +* algorithm proposed by Stoer and Wagner (see references below). +* +* Parameters of this routine have the same meaning as for the routine +* min_cut (see above). +* +* RETURNS +* +* The routine returns the capacity of the min cut found. +* +* ALGORITHM +* +* The basic idea of Stoer&Wagner algorithm is the following. Let G be +* a capacitated network, and G(s,t) be a network, in which the nodes s +* and t are merged into one new node, loops are deleted, but multuple +* edges are retained. It is obvious that a minimum cut in G is the +* minimum of two quantities: the minimum cut in G(s,t) and a minimum +* cut that separates s and t. This allows to find a minimum cut in the +* original network solving at most nn max flow problems. +* +* REFERENCES +* +* M. Stoer, F. Wagner. A Simple Min Cut Algorithm. Algorithms, ESA'94 +* LNCS 855 (1994), pp. 141-47. +* +* J. Cheriyan, R. Ravi. Approximation Algorithms for Network Problems. +* Univ. of Waterloo (1998), p. 147. */ + +int min_cut_sw(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const cap[/*1+ne*/], int cut[/*1+nn*/]) +{ int i, j, k, min_cut, flow, temp, *head1, *next1, *head2, *next2; + int I, J, K, S, T, DEG, NV, NE, *HEAD, *NEXT, *NUMB, *BEG, *END, + *CAP, *X, *ADJ, *SUM, *CUT; + /* head1[i] points to the first edge with beg[k] = i + * next1[k] points to the next edge with the same beg[k] + * head2[i] points to the first edge with end[k] = i + * next2[k] points to the next edge with the same end[k] */ + head1 = xalloc(1+nn, sizeof(int)); + head2 = xalloc(1+nn, sizeof(int)); + next1 = xalloc(1+ne, sizeof(int)); + next2 = xalloc(1+ne, sizeof(int)); + for (i = 1; i <= nn; i++) + head1[i] = head2[i] = 0; + for (k = 1; k <= ne; k++) + { i = beg[k], next1[k] = head1[i], head1[i] = k; + j = end[k], next2[k] = head2[j], head2[j] = k; + } + /* an auxiliary network used in the algorithm is resulted from + * the original network by merging some nodes into one supernode; + * all variables and arrays related to this auxiliary network are + * denoted in CAPS */ + /* HEAD[I] points to the first node of the original network that + * belongs to the I-th supernode + * NEXT[i] points to the next node of the original network that + * belongs to the same supernode as the i-th node + * NUMB[i] is a supernode, which the i-th node belongs to */ + /* initially the auxiliary network is equivalent to the original + * network, i.e. each supernode consists of one node */ + NV = nn; + HEAD = xalloc(1+nn, sizeof(int)); + NEXT = xalloc(1+nn, sizeof(int)); + NUMB = xalloc(1+nn, sizeof(int)); + for (i = 1; i <= nn; i++) + HEAD[i] = i, NEXT[i] = 0, NUMB[i] = i; + /* number of edges in the auxiliary network is never greater than + * in the original one */ + BEG = xalloc(1+ne, sizeof(int)); + END = xalloc(1+ne, sizeof(int)); + CAP = xalloc(1+ne, sizeof(int)); + X = xalloc(1+ne, sizeof(int)); + /* allocate some auxiliary arrays */ + ADJ = xalloc(1+nn, sizeof(int)); + SUM = xalloc(1+nn, sizeof(int)); + CUT = xalloc(1+nn, sizeof(int)); + /* currently no min cut is found so far */ + min_cut = INT_MAX; + /* main loop starts here */ + while (NV > 1) + { /* build the set of edges of the auxiliary network */ + NE = 0; + /* multiple edges are not allowed in the max flow algorithm, + * so we can replace each multiple edge, which is the result + * of merging nodes into supernodes, by a single edge, whose + * capacity is the sum of capacities of particular edges; + * these summary capacities will be stored in the array SUM */ + for (I = 1; I <= NV; I++) + SUM[I] = 0.0; + for (I = 1; I <= NV; I++) + { /* DEG is number of single edges, which connects I-th + * supernode and some J-th supernode, where I < J */ + DEG = 0; + /* walk thru nodes that belong to I-th supernode */ + for (i = HEAD[I]; i != 0; i = NEXT[i]) + { /* i-th node belongs to I-th supernode */ + /* walk through edges with beg[k] = i */ + for (k = head1[i]; k != 0; k = next1[k]) + { j = end[k]; + /* j-th node belongs to J-th supernode */ + J = NUMB[j]; + /* ignore loops and edges with I > J */ + if (I >= J) + continue; + /* add an edge that connects I-th and J-th supernodes + * (if not added yet) */ + if (SUM[J] == 0.0) + ADJ[++DEG] = J; + /* sum up the capacity of the original edge */ + xassert(cap[k] > 0.0); + SUM[J] += cap[k]; + } + /* walk through edges with end[k] = i */ + for (k = head2[i]; k != 0; k = next2[k]) + { j = beg[k]; + /* j-th node belongs to J-th supernode */ + J = NUMB[j]; + /* ignore loops and edges with I > J */ + if (I >= J) + continue; + /* add an edge that connects I-th and J-th supernodes + * (if not added yet) */ + if (SUM[J] == 0.0) + ADJ[++DEG] = J; + /* sum up the capacity of the original edge */ + xassert(cap[k] > 0.0); + SUM[J] += cap[k]; + } + } + /* add single edges connecting I-th supernode with other + * supernodes to the auxiliary network; restore the array + * SUM for subsequent use */ + for (K = 1; K <= DEG; K++) + { NE++; + xassert(NE <= ne); + J = ADJ[K]; + BEG[NE] = I, END[NE] = J, CAP[NE] = SUM[J]; + SUM[J] = 0.0; + } + } + /* choose two arbitrary supernodes of the auxiliary network, + * one of which is the source and other is the sink */ + S = 1, T = NV; + /* determine max flow from S to T */ + flow = max_flow(NV, NE, BEG, END, CAP, S, T, X); + /* if the min cut that separates supernodes S and T is less + * than the currently known, remember it */ + if (min_cut > flow) + { min_cut = flow; + /* find min (s,t)-cut in the auxiliary network */ + temp = min_st_cut(NV, NE, BEG, END, CAP, S, T, X, CUT); + /* (Ford and Fulkerson insist on this) */ + xassert(flow == temp); + /* build corresponding min cut in the original network */ + for (i = 1; i <= nn; i++) cut[i] = CUT[NUMB[i]]; + /* if the min cut capacity is zero (i.e. the network has + * unconnected components), the search can be prematurely + * terminated */ + if (min_cut == 0) + break; + } + /* now merge all nodes of the original network, which belong + * to the supernodes S and T, into one new supernode; this is + * attained by carrying all nodes from T to S (for the sake of + * convenience T should be the last supernode) */ + xassert(T == NV); + /* assign new references to nodes from T */ + for (i = HEAD[T]; i != 0; i = NEXT[i]) + NUMB[i] = S; + /* find last entry in the node list of S */ + i = HEAD[S]; + xassert(i != 0); + while (NEXT[i] != 0) + i = NEXT[i]; + /* and attach to it the node list of T */ + NEXT[i] = HEAD[T]; + /* decrease number of nodes in the auxiliary network */ + NV--; + } + /* free working arrays */ + xfree(HEAD); + xfree(NEXT); + xfree(NUMB); + xfree(BEG); + xfree(END); + xfree(CAP); + xfree(X); + xfree(ADJ); + xfree(SUM); + xfree(CUT); + xfree(head1); + xfree(head2); + xfree(next1); + xfree(next2); + /* return to the calling program */ + return min_cut; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/mincut.h b/resources/3rdparty/glpk-4.57/examples/tsp/mincut.h new file mode 100644 index 000000000..aefdbb7dd --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/mincut.h @@ -0,0 +1,23 @@ +/* mincut.c */ + +/* Written by Andrew Makhorin , October 2015. */ + +#ifndef MINCUT_H +#define MINCUT_H + +int min_cut(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const cap[/*1+ne*/], int cut[/*1+nn*/]); +/* find min cut in undirected capacitated network */ + +int min_st_cut(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t, + const int x[/*1+ne*/], int cut[/*1+nn*/]); +/* find min (s,t)-cut for known max flow */ + +int min_cut_sw(int nn, int ne, const int beg[/*1+ne*/], + const int end[/*1+ne*/], const cap[/*1+ne*/], int cut[/*1+nn*/]); +/* find min cut with Stoer and Wagner algorithm */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/misc.c b/resources/3rdparty/glpk-4.57/examples/tsp/misc.c new file mode 100644 index 000000000..e0b08fb5b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/misc.c @@ -0,0 +1,159 @@ +/* misc.c */ + +/* Written by Andrew Makhorin , October 2015. */ + +#include +#include +#include +#include +#include "misc.h" + +/*********************************************************************** +* NAME +* +* str2int - convert character string to value of int type +* +* SYNOPSIS +* +* #include "misc.h" +* int str2int(const char *str, int *val); +* +* DESCRIPTION +* +* The routine str2int converts the character string str to a value of +* integer type and stores the value into location, which the parameter +* val points to (in the case of error content of this location is not +* changed). +* +* RETURNS +* +* The routine returns one of the following error codes: +* +* 0 - no error; +* 1 - value out of range; +* 2 - character string is syntactically incorrect. */ + +int str2int(const char *str, int *val_) +{ int d, k, s, val = 0; + /* scan optional sign */ + if (str[0] == '+') + s = +1, k = 1; + else if (str[0] == '-') + s = -1, k = 1; + else + s = +1, k = 0; + /* check for the first digit */ + if (!isdigit((unsigned char)str[k])) + return 2; + /* scan digits */ + while (isdigit((unsigned char)str[k])) + { d = str[k++] - '0'; + if (s > 0) + { if (val > INT_MAX / 10) + return 1; + val *= 10; + if (val > INT_MAX - d) + return 1; + val += d; + } + else /* s < 0 */ + { if (val < INT_MIN / 10) + return 1; + val *= 10; + if (val < INT_MIN + d) + return 1; + val -= d; + } + } + /* check for terminator */ + if (str[k] != '\0') + return 2; + /* conversion has been done */ + *val_ = val; + return 0; +} + +/*********************************************************************** +* NAME +* +* str2num - convert character string to value of double type +* +* SYNOPSIS +* +* #include "misc.h" +* int str2num(const char *str, double *val); +* +* DESCRIPTION +* +* The routine str2num converts the character string str to a value of +* double type and stores the value into location, which the parameter +* val points to (in the case of error content of this location is not +* changed). +* +* RETURNS +* +* The routine returns one of the following error codes: +* +* 0 - no error; +* 1 - value out of range; +* 2 - character string is syntactically incorrect. */ + +int str2num(const char *str, double *val_) +{ int k; + double val; + /* scan optional sign */ + k = (str[0] == '+' || str[0] == '-' ? 1 : 0); + /* check for decimal point */ + if (str[k] == '.') + { k++; + /* a digit should follow it */ + if (!isdigit((unsigned char)str[k])) + return 2; + k++; + goto frac; + } + /* integer part should start with a digit */ + if (!isdigit((unsigned char)str[k])) + return 2; + /* scan integer part */ + while (isdigit((unsigned char)str[k])) + k++; + /* check for decimal point */ + if (str[k] == '.') k++; +frac: /* scan optional fraction part */ + while (isdigit((unsigned char)str[k])) + k++; + /* check for decimal exponent */ + if (str[k] == 'E' || str[k] == 'e') + { k++; + /* scan optional sign */ + if (str[k] == '+' || str[k] == '-') + k++; + /* a digit should follow E, E+ or E- */ + if (!isdigit((unsigned char)str[k])) + return 2; + } + /* scan optional exponent part */ + while (isdigit((unsigned char)str[k])) + k++; + /* check for terminator */ + if (str[k] != '\0') + return 2; + /* perform conversion */ + { char *endptr; + val = strtod(str, &endptr); + if (*endptr != '\0') + return 2; + } + /* check for overflow */ + if (!(-DBL_MAX <= val && val <= +DBL_MAX)) + return 1; + /* check for underflow */ + if (-DBL_MIN < val && val < +DBL_MIN) + val = 0.0; + /* conversion has been done */ + *val_ = val; + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/misc.h b/resources/3rdparty/glpk-4.57/examples/tsp/misc.h new file mode 100644 index 000000000..097383157 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/misc.h @@ -0,0 +1,24 @@ +/* misc.h */ + +/* Written by Andrew Makhorin , October 2015. */ + +#ifndef MISC_H +#define MISC_H + +#include + +#define xprintf glp_printf +#define xerror glp_error +#define xassert glp_assert +#define xalloc glp_alloc +#define xfree glp_free + +int str2int(const char *str, int *val); +/* convert character string to value of int type */ + +int str2num(const char *str, double *val); +/* convert character string to value of double type */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/moscow.tsp b/resources/3rdparty/glpk-4.57/examples/tsp/moscow.tsp new file mode 100644 index 000000000..a2d4ea2fa --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/moscow.tsp @@ -0,0 +1,200 @@ +NAME: MOSCOW +TYPE: TSP +COMMENT: 68 cities in Moscow region (Andrew Makhorin ) +DIMENSION: 68 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: LOWER_DIAG_ROW +EDGE_WEIGHT_SECTION +0 +80 0 +99 66 0 +73 153 156 0 +118 156 205 116 0 +136 103 37 190 242 0 +134 128 180 141 90 217 0 +72 75 127 126 81 164 86 0 +131 94 146 184 133 183 67 91 0 +75 38 90 136 126 127 94 45 56 0 +67 52 46 124 169 83 165 88 132 76 0 +134 66 69 207 219 68 189 138 136 101 106 0 +179 142 194 204 153 231 87 139 52 104 180 188 0 +145 98 63 216 240 26 212 159 178 122 109 53 226 0 +83 7 69 156 159 106 131 78 97 41 55 60 145 95 0 +85 38 68 158 180 105 152 99 118 62 57 74 166 100 41 0 +188 163 97 222 294 77 277 223 243 187 135 145 291 93 166 165 0 +38 101 125 92 80 162 96 34 101 71 93 164 149 176 104 116 214 0 +88 66 118 142 97 155 62 40 67 36 103 129 115 150 69 90 215 50 0 +113 50 102 174 164 139 136 83 92 46 88 94 140 134 53 74 199 109 74 0 +67 94 146 113 62 183 81 19 86 64 107 157 134 178 97 118 242 29 35 102 0 +133 132 96 167 239 91 245 168 212 156 80 159 260 117 135 137 55 159 183 + 168 187 0 +51 64 54 108 157 91 159 82 139 83 25 118 187 117 67 69 143 77 97 100 101 + 88 0 +122 116 168 129 78 205 12 74 55 82 153 177 75 200 119 140 265 84 50 124 + 69 233 147 0 +148 115 49 202 254 29 229 176 195 139 95 97 243 45 118 117 48 174 167 + 151 195 83 103 217 0 +95 32 84 156 146 121 118 65 84 28 70 95 132 116 35 56 181 91 56 18 84 + 150 82 106 133 0 +133 70 122 194 184 159 156 103 112 66 108 99 160 148 73 94 219 129 94 25 + 122 188 120 144 171 38 0 +57 58 110 118 98 147 103 17 84 28 71 121 132 142 61 82 206 43 42 66 36 + 151 65 91 159 48 86 0 +164 101 142 225 188 167 122 134 55 97 139 109 107 152 104 125 239 150 + 116 67 135 219 151 110 191 69 87 117 0 +145 93 78 218 240 41 212 159 153 122 117 27 205 26 87 100 118 176 150 + 121 178 132 129 200 70 116 126 142 126 0 +142 74 77 215 227 60 197 146 134 109 114 8 186 45 68 82 137 172 137 102 + 165 151 126 185 89 103 107 129 107 19 0 +85 48 100 146 119 137 84 55 63 10 86 111 111 132 51 72 197 72 38 56 57 + 166 93 72 149 38 76 38 107 132 119 0 +106 26 73 179 182 110 154 101 120 64 78 48 168 97 30 62 170 127 92 76 + 120 158 90 142 122 58 84 84 102 75 56 74 0 +171 138 72 225 277 52 252 199 218 162 118 120 266 68 141 140 25 197 190 + 174 218 80 126 240 23 156 194 182 214 93 112 172 145 0 +65 18 48 138 160 85 132 79 98 42 37 69 146 80 21 20 145 96 70 54 98 117 + 49 120 97 36 74 62 105 80 77 52 44 120 0 +90 163 173 17 99 207 124 111 167 138 141 217 187 228 166 168 239 77 127 + 176 96 184 125 112 219 158 196 120 222 228 225 148 189 242 148 0 +47 22 67 116 121 104 106 40 80 24 44 85 128 99 25 39 164 66 44 46 59 124 + 46 94 116 28 66 23 97 99 93 34 48 139 19 118 0 +89 26 78 150 140 115 112 59 78 22 64 89 126 110 29 50 175 85 50 24 78 + 144 76 100 127 6 44 42 75 110 97 32 52 150 30 152 22 0 +31 111 118 42 134 155 153 91 157 101 86 165 205 176 114 116 207 57 107 + 139 86 152 70 141 167 121 159 83 190 176 173 111 137 190 96 59 78 115 0 +115 35 56 188 191 93 158 110 111 73 87 31 159 80 42 45 153 136 101 63 + 129 152 99 146 105 65 68 93 86 58 39 83 17 128 53 198 57 61 146 0 +37 70 103 91 121 140 121 44 101 45 62 124 149 135 73 75 197 41 59 83 63 + 142 56 109 152 65 103 27 134 135 132 55 96 175 55 93 25 59 56 105 0 +143 142 106 177 249 101 255 178 222 166 90 169 270 127 145 147 65 169 + 193 178 197 10 98 243 93 160 198 161 229 142 161 176 168 90 127 194 134 + 154 162 162 152 0 +152 151 115 186 258 110 264 187 231 175 99 178 279 136 154 156 100 178 + 202 187 206 45 107 252 98 169 207 170 238 151 170 185 177 121 136 203 + 143 163 171 171 161 55 0 +146 74 81 219 230 70 191 149 124 112 118 12 176 55 72 84 147 175 140 102 + 168 161 130 179 99 104 107 132 97 29 10 122 56 122 81 229 96 100 177 39 + 136 171 180 0 +118 50 53 191 203 84 173 122 126 85 90 16 174 69 44 58 150 148 113 78 + 141 149 102 161 102 79 83 105 101 43 24 95 32 125 53 201 69 73 149 15 + 108 159 168 28 0 +50 56 62 107 155 99 151 74 131 75 17 110 179 121 59 61 151 76 89 92 93 + 96 8 139 111 74 112 57 143 121 118 85 82 134 41 124 38 68 69 91 48 106 + 115 122 94 0 +107 126 110 113 209 117 221 144 201 145 87 179 249 143 129 131 149 133 + 159 162 162 94 62 209 129 144 182 127 213 158 177 155 152 152 111 130 + 108 138 98 161 118 104 113 187 163 70 0 +105 42 94 166 156 131 128 75 84 38 80 86 132 126 45 66 191 101 66 8 94 + 160 92 116 143 10 28 58 59 113 94 48 68 166 46 168 38 16 131 55 75 170 + 179 94 70 84 154 0 +114 133 117 120 216 124 228 151 208 152 94 186 256 150 136 138 156 140 + 166 169 169 101 69 216 136 151 189 134 220 165 184 162 159 159 118 137 + 115 145 105 168 125 111 120 194 170 77 35 161 0 +89 42 72 162 184 109 156 103 122 66 61 70 170 104 45 4 169 120 94 78 122 + 141 73 144 121 60 98 86 127 97 78 76 58 144 24 172 43 54 120 41 79 151 + 160 80 54 65 135 70 142 0 +218 166 151 291 313 114 285 232 226 195 190 100 278 99 160 173 191 249 + 223 194 251 205 202 273 143 189 199 215 199 73 92 205 148 166 153 301 + 172 183 249 131 208 215 224 102 116 194 231 186 238 170 0 +81 147 168 48 68 205 93 80 136 117 136 208 156 219 150 159 250 46 96 155 + 65 195 120 81 217 137 175 89 191 219 216 118 173 240 139 31 109 131 66 + 182 84 205 214 220 192 119 141 147 148 163 292 0 +147 84 125 208 180 160 115 117 48 80 122 100 100 145 87 108 222 133 99 + 50 118 202 134 103 174 52 70 100 17 119 100 90 85 197 88 210 80 58 173 + 69 117 212 221 90 84 126 196 42 203 110 192 179 0 +93 112 96 99 195 103 207 130 187 131 73 165 235 129 115 117 135 119 145 + 148 148 80 48 195 115 130 168 113 199 144 163 141 138 138 97 116 94 124 + 84 147 104 90 99 173 149 56 14 140 21 121 217 127 182 0 +97 91 143 151 103 180 37 49 76 57 128 152 100 175 94 115 240 59 25 99 44 + 208 122 25 192 81 119 66 125 175 160 47 117 215 95 136 69 75 116 121 84 + 218 227 160 136 114 184 91 191 119 248 105 108 170 0 +122 121 85 156 228 80 234 157 201 145 69 148 249 106 124 126 70 148 172 + 157 176 15 77 222 68 139 177 140 208 121 140 155 147 91 106 173 113 133 + 141 141 131 25 30 150 138 85 83 149 90 130 194 184 191 69 197 0 +179 142 194 232 181 222 115 139 48 104 180 164 38 207 145 166 291 149 + 115 126 134 260 187 103 243 128 146 132 83 181 162 111 161 266 146 215 + 128 126 205 145 149 270 279 152 160 179 249 118 256 170 254 184 76 235 + 124 249 0 +38 67 82 99 144 119 146 69 126 70 50 121 174 132 70 72 171 64 84 103 88 + 116 34 134 131 85 123 52 154 132 129 80 93 154 52 116 40 79 57 102 43 + 126 135 133 105 33 90 95 97 76 205 107 137 76 109 105 174 0 +100 34 86 173 168 123 140 87 100 50 72 70 148 118 37 58 183 113 78 52 + 106 152 84 128 135 44 57 70 75 97 78 60 27 158 38 180 39 38 131 39 87 + 162 171 78 54 76 146 44 153 62 170 159 58 132 103 141 134 87 0 +69 46 98 130 117 135 82 39 72 16 83 109 120 130 49 70 195 65 20 54 55 + 163 77 70 147 36 74 22 105 130 117 26 72 170 50 132 24 30 95 81 39 173 + 182 120 93 69 139 46 146 74 203 111 88 125 45 152 120 64 58 0 +160 97 138 219 168 173 102 126 35 91 135 113 87 158 100 121 235 136 102 + 63 121 215 147 90 187 65 83 113 30 132 113 98 98 210 101 202 93 71 186 + 82 130 225 234 103 97 139 209 55 216 123 205 171 13 195 111 204 83 150 + 71 101 0 +70 89 73 110 176 104 184 107 164 108 50 142 212 130 92 94 136 96 122 125 + 125 81 25 172 116 107 145 90 176 145 150 118 115 139 74 127 71 101 89 + 124 81 91 100 154 126 33 37 117 44 98 218 138 159 23 147 70 212 53 109 + 102 172 0 +188 136 121 261 283 84 255 202 196 165 160 70 248 69 130 143 161 219 193 + 164 221 175 172 243 113 159 169 185 169 43 62 175 118 136 123 271 142 + 153 219 101 178 185 194 72 86 164 201 156 208 140 30 262 162 187 218 + 164 224 175 140 173 175 188 0 +94 28 80 167 162 117 134 81 100 44 66 69 148 112 31 52 177 107 72 56 100 + 146 78 122 129 38 63 64 81 96 77 54 21 152 32 174 33 32 125 38 81 156 + 165 77 53 70 140 48 147 56 169 153 64 126 97 135 140 81 6 52 77 103 139 + 0 +45 43 75 118 142 112 138 61 118 62 30 97 166 108 46 48 164 76 76 79 80 + 109 21 126 124 61 99 44 130 108 105 72 69 147 28 128 25 55 76 78 35 119 + 128 109 81 13 83 71 90 52 181 119 113 69 101 98 166 32 63 56 126 46 151 + 57 0 +113 35 48 186 191 85 163 110 119 73 85 37 167 72 39 37 145 136 101 71 + 129 144 97 151 97 67 76 93 94 64 45 83 25 120 48 196 57 61 144 8 103 + 154 163 47 21 89 158 63 165 33 137 182 77 144 126 133 153 100 47 81 90 + 121 107 46 76 0 +97 21 57 170 173 94 145 92 111 55 69 46 159 81 14 55 154 118 83 67 111 + 149 81 133 106 49 87 75 118 73 54 65 18 129 35 180 39 43 128 33 87 159 + 168 58 30 73 143 59 150 58 146 164 101 129 108 138 159 84 45 63 114 106 + 116 39 60 25 0 +116 79 131 177 133 168 98 76 51 41 117 127 63 163 82 103 228 86 52 77 71 + 197 124 86 180 69 97 69 100 154 135 48 105 203 83 163 65 63 142 96 86 + 207 216 135 111 116 186 69 193 107 227 132 83 172 61 186 63 111 85 57 + 86 149 197 85 103 104 96 0 +EOF + +Vertices of the graph: + 1 Aprelevka 35 Lyubertsy + 2 Balashikha 36 Mozhaysk + 3 Bronnitsy 37 Moskva + 4 Vereya 38 Mytischi + 5 Volokolamsk 39 Naro-Fominsk + 6 Voskresensk 40 Noginsk + 7 Vysokovsk 41 Odintsovo + 8 Dedovsk 42 Ozherel'ye + 9 Dmitrov 43 Ozyory +10 Dolgoprudny 44 Orekhovo-Zuevo +11 Domodedovo 45 Pavlovsky Posad +12 Drezna 46 Podol'sk +13 Dubna 47 Protvino +14 Egor'yevsk 48 Pushkino +15 Zheleznodorozhny 49 Puschino +16 Zhukovsky 50 Ramenskoye +17 Zaraysk 51 Roshal +18 Zvenigorod 52 Ruza +19 Zelenograd 53 Sergiyev Posad +20 Ivanteyevka 54 Serpukhov +21 Istra 55 Solnechnogorsk +22 Kashira 56 Stupino +23 Klimovsk 57 Taldom +24 Klin 58 Troitsk +25 Kolomna 59 Fryazino +26 Korolyov (Podlipki) 60 Khimki +27 Krasnoarmeysk 61 Khot'kovo +28 Krasnogorsk 62 Chekhov +29 Krasnozavodsk 63 Shatura +30 Kurovskoye 64 Schyolkovo +31 Likino-Dulyovo 65 Scherbinka +32 Lobnya 66 Elektrostal +33 Losino-Petrovsky 67 Elektrougli +34 Lukhovitsy 68 Yakhroma + +Optimal tour length is 1994 kilometers (obtained by glpk tspsol): +1 39 4 36 52 5 7 24 55 19 60 10 32 68 13 57 9 61 53 29 27 20 48 26 38 +59 64 33 67 15 2 35 16 50 66 40 45 12 44 31 63 51 30 14 6 3 25 34 17 22 +42 56 43 47 49 54 62 23 46 11 65 58 41 37 28 8 21 18 1 diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/sample.tsp b/resources/3rdparty/glpk-4.57/examples/tsp/sample.tsp new file mode 100644 index 000000000..9e1367a33 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/sample.tsp @@ -0,0 +1,16 @@ +NAME: SAMPLE +TYPE: TSP +COMMENT: Example from D.Phillips, A.Garcia-Diaz, p.124 +DIMENSION: 8 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: LOWER_DIAG_ROW +EDGE_WEIGHT_SECTION +0 +190 0 +210 380 0 +680 760 890 0 +690 790 900 480 0 +460 610 340 760 890 0 +780 670 410 510 490 720 0 +750 450 600 250 560 600 500 0 +EOF diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/tsplib.c b/resources/3rdparty/glpk-4.57/examples/tsp/tsplib.c new file mode 100644 index 000000000..189ff8aa5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/tsplib.c @@ -0,0 +1,730 @@ +/* tsplib.c */ + +/* Written by Andrew Makhorin , October 2015. */ + +#include +#include +#include +#include +#include +#include +#include + +#include "misc.h" +#include "tsplib.h" + +/*********************************************************************** +* NAME +* +* tsp_read_data - read TSP instance data +* +* SYNOPSIS +* +* #include "tsplib.h" +* TSP *tsp_read_data(const char *fname); +* +* DESCRIPTION +* +* The routine tsp_read_data reads a TSP (or related problem) instance +* data from a text file, whose name is the character string fname. +* +* For detailed description of the format recognized by the routine see +* the report: G.Reinelt, TSPLIB 95. +* +* RETURNS +* +* If no error occurred, the routine tsp_read_data returns a pointer to +* the TSP instance data block, which contains loaded data. In the case +* of error the routine prints an error message and returns NULL. */ + +struct csa +{ /* common storage area used by the routine tsp_read_data */ + const char *fname; + /* name of the input text file */ + FILE *fp; + /* stream assigned to the input text file */ + int seqn; + /* line sequential number */ + int c; + /* current character */ + char token[255+1]; + /* current token */ +}; + +static int get_char(struct csa *csa) +{ csa->c = fgetc(csa->fp); + if (ferror(csa->fp)) + { xprintf("%s:%d: read error - %s\n", csa->fname, csa->seqn, + strerror(errno)); + return 1; + } + if (feof(csa->fp)) + csa->c = EOF; + else if (csa->c == '\n') + csa->seqn++; + else if (isspace(csa->c)) + csa->c = ' '; + else if (iscntrl(csa->c)) + { xprintf("%s:%d: invalid control character 0x%02X\n", + csa->fname, csa->seqn, csa->c); + return 1; + } + return 0; +} + +static int skip_spaces(struct csa *csa, int across) +{ while (csa->c == ' ' || (across && csa->c == '\n')) + if (get_char(csa)) return 1; + return 0; +} + +static int scan_keyword(struct csa *csa) +{ int len = 0; + if (skip_spaces(csa, 0)) + return 1; + if (csa->c == EOF) + { xprintf("%s:%d: warning: missing EOF inserted\n", csa->fname, + csa->seqn); + strcpy(csa->token, "EOF"); + return 0; + } + csa->token[0] = '\0'; + while (isalnum(csa->c) || csa->c == '_') + { if (len == 31) + { xprintf("%s:%d: keyword '%s...' too long\n", csa->fname, + csa->seqn, csa->token); + return 1; + } + csa->token[len++] = (char)csa->c, csa->token[len] = '\0'; + if (get_char(csa)) + return 1; + } + if (len == 0) + { xprintf("%s:%d: missing keyword\n", csa->fname, csa->seqn); + return 1; + } + return 0; +} + +static int check_colon(struct csa *csa) +{ if (skip_spaces(csa, 0)) + return 1; + if (csa->c != ':') + { xprintf("%s:%d: missing colon after '%s'\n", csa->fname, + csa->seqn, csa->token); + return 1; + } + if (get_char(csa)) + return 1; + return 0; +} + +static int scan_token(struct csa *csa, int across) +{ int len = 0; + if (skip_spaces(csa, across)) + return 1; + csa->token[0] = '\0'; + while (!(csa->c == EOF || csa->c == '\n' || csa->c == ' ')) + { if (len == 255) + { csa->token[31] = '\0'; + xprintf("%s:%d: token '%s...' too long\n", csa->fname, + csa->seqn, csa->token); + return 1; + } + csa->token[len++] = (char)csa->c, csa->token[len] = '\0'; + if (get_char(csa)) + return 1; + } + return 0; +} + +static int check_newline(struct csa *csa) +{ if (skip_spaces(csa, 0)) + return 1; + if (!(csa->c == EOF || csa->c == '\n')) + { xprintf("%s:%d: extra symbols detected\n", csa->fname, + csa->seqn); + return 1; + } + if (get_char(csa)) + return 1; + return 0; +} + +static int scan_comment(struct csa *csa) +{ int len = 0; + if (skip_spaces(csa, 0)) + return 1; + csa->token[0] = '\0'; + while (!(csa->c == EOF || csa->c == '\n')) + { if (len == 255) + { xprintf("%s:%d: comment too long\n", csa->fname, csa->seqn); + return 1; + } + csa->token[len++] = (char)csa->c, csa->token[len] = '\0'; + if (get_char(csa)) + return 1; + } + return 0; +} + +static int scan_integer(struct csa *csa, int across, int *val) +{ if (scan_token(csa, across)) + return 1; + if (strlen(csa->token) == 0) + { xprintf("%s:%d: missing integer\n", csa->fname, csa->seqn); + return 1; + } + if (str2int(csa->token, val)) + { xprintf("%s:%d: integer '%s' invalid\n", csa->fname, csa->seqn, + csa->token); + return 1; + } + return 0; +} + +static int scan_number(struct csa *csa, int across, double *val) +{ if (scan_token(csa, across)) + return 1; + if (strlen(csa->token) == 0) + { xprintf("%s:%d: missing number\n", csa->fname, csa->seqn); + return 1; + } + if (str2num(csa->token, val)) + { xprintf("%s:%d: number '%s' invalid\n", csa->fname, csa->seqn, + csa->token); + return 1; + } + return 0; +} + +TSP *tsp_read_data(const char *fname) +{ struct csa _dsa, *csa = &_dsa; + TSP *tsp = NULL; + csa->fname = fname; + xprintf("Reading TSP data from '%s'...\n", csa->fname); + csa->fp = fopen(csa->fname, "r"); + if (csa->fp == NULL) + { xprintf("Unable to open '%s' - %s\n", csa->fname, + strerror(errno)); + goto fail; + } + tsp = xalloc(1, sizeof(TSP)); + tsp->name = NULL; + tsp->type = TSP_UNDEF; + tsp->comment = NULL; + tsp->dimension = 0; + tsp->edge_weight_type = TSP_UNDEF; + tsp->edge_weight_format = TSP_UNDEF; + tsp->display_data_type = TSP_UNDEF; + tsp->node_x_coord = NULL; + tsp->node_y_coord = NULL; + tsp->dply_x_coord = NULL; + tsp->dply_y_coord = NULL; + tsp->tour = NULL; + tsp->edge_weight = NULL; + csa->seqn = 1; + if (get_char(csa)) + goto fail; +loop: if (scan_keyword(csa)) + goto fail; + if (strcmp(csa->token, "NAME") == 0) + { if (tsp->name != NULL) + { xprintf("%s:%d: NAME entry multiply defined\n", csa->fname, + csa->seqn); + goto fail; + } + if (check_colon(csa)) + goto fail; + if (scan_token(csa, 0)) + goto fail; + if (strlen(csa->token) == 0) + { xprintf("%s:%d: NAME entry incomplete\n", csa->fname, + csa->seqn); + goto fail; + } + tsp->name = xalloc(strlen(csa->token)+1, sizeof(char)); + strcpy(tsp->name, csa->token); + xprintf("NAME: %s\n", tsp->name); + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "TYPE") == 0) + { if (tsp->type != TSP_UNDEF) + { xprintf("%s:%d: TYPE entry multiply defined\n", csa->fname, + csa->seqn); + goto fail; + } + if (check_colon(csa)) + goto fail; + if (scan_keyword(csa)) + goto fail; + if (strcmp(csa->token, "TSP") == 0) + tsp->type = TSP_TSP; + else if (strcmp(csa->token, "ATSP") == 0) + tsp->type = TSP_ATSP; + else if (strcmp(csa->token, "TOUR") == 0) + tsp->type = TSP_TOUR; + else + { xprintf("%s:%d: data type '%s' not recognized\n", + csa->fname, csa->seqn, csa->token); + goto fail; + } + xprintf("TYPE: %s\n", csa->token); + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "COMMENT") == 0) + { if (check_colon(csa)) + goto fail; + if (scan_comment(csa)) + goto fail; + xprintf("COMMENT: %s\n", csa->token); + if (tsp->comment == NULL) + { tsp->comment = xalloc(strlen(csa->token)+1, sizeof(char)); + strcpy(tsp->comment, csa->token); + } + else + { xprintf("%s:%d: warning: extra COMMENT entry ignored\n", + csa->fname, csa->seqn); + } + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "DIMENSION") == 0) + { if (tsp->dimension != 0) + { xprintf("%s:%d: DIMENSION entry multiply defined\n", + csa->fname, csa->seqn); + goto fail; + } + if (check_colon(csa)) + goto fail; + if (scan_integer(csa, 0, &tsp->dimension)) + goto fail; + if (tsp->dimension < 1) + { xprintf("%s:%d: invalid dimension\n", csa->fname, + csa->seqn); + goto fail; + } + xprintf("DIMENSION: %d\n", tsp->dimension); + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "EDGE_WEIGHT_TYPE") == 0) + { if (tsp->edge_weight_type != TSP_UNDEF) + { xprintf("%s:%d: EDGE_WEIGHT_TYPE entry multiply defined\n", + csa->fname, csa->seqn); + goto fail; + } + if (check_colon(csa)) + goto fail; + if (scan_keyword(csa)) + goto fail; + if (strcmp(csa->token, "GEO") == 0) + tsp->edge_weight_type = TSP_GEO; + else if (strcmp(csa->token, "EUC_2D") == 0) + tsp->edge_weight_type = TSP_EUC_2D; + else if (strcmp(csa->token, "ATT") == 0) + tsp->edge_weight_type = TSP_ATT; + else if (strcmp(csa->token, "EXPLICIT") == 0) + tsp->edge_weight_type = TSP_EXPLICIT; + else if (strcmp(csa->token, "CEIL_2D") == 0) + tsp->edge_weight_type = TSP_CEIL_2D; + else + { xprintf("%s:%d: edge weight type '%s' not recognized\n", + csa->fname, csa->seqn, csa->token); + goto fail; + } + xprintf("EDGE_WEIGHT_TYPE: %s\n", csa->token); + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "EDGE_WEIGHT_FORMAT") == 0) + { if (tsp->edge_weight_format != TSP_UNDEF) + { xprintf("%s:%d: EDGE_WEIGHT_FORMAT entry multiply defined\n" + , csa->fname, csa->seqn); + goto fail; + } + if (check_colon(csa)) + goto fail; + if (scan_keyword(csa)) + goto fail; + if (strcmp(csa->token, "UPPER_ROW") == 0) + tsp->edge_weight_format = TSP_UPPER_ROW; + else if (strcmp(csa->token, "FULL_MATRIX") == 0) + tsp->edge_weight_format = TSP_FULL_MATRIX; + else if (strcmp(csa->token, "FUNCTION") == 0) + tsp->edge_weight_format = TSP_FUNCTION; + else if (strcmp(csa->token, "LOWER_DIAG_ROW") == 0) + tsp->edge_weight_format = TSP_LOWER_DIAG_ROW; + else + { xprintf("%s:%d: edge weight format '%s' not recognized\n", + csa->fname, csa->seqn, csa->token); + goto fail; + } + xprintf("EDGE_WEIGHT_FORMAT: %s\n", csa->token); + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "DISPLAY_DATA_TYPE") == 0) + { if (tsp->display_data_type != TSP_UNDEF) + { xprintf("%s:%d: DISPLAY_DATA_TYPE entry multiply defined\n", + csa->fname, csa->seqn); + goto fail; + } + if (check_colon(csa)) + goto fail; + if (scan_keyword(csa)) + goto fail; + if (strcmp(csa->token, "COORD_DISPLAY") == 0) + tsp->display_data_type = TSP_COORD_DISPLAY; + else if (strcmp(csa->token, "TWOD_DISPLAY") == 0) + tsp->display_data_type = TSP_TWOD_DISPLAY; + else + { xprintf("%s:%d: display data type '%s' not recognized\n", + csa->fname, csa->seqn, csa->token); + goto fail; + } + xprintf("DISPLAY_DATA_TYPE: %s\n", csa->token); + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "NODE_COORD_SECTION") == 0) + { int n = tsp->dimension, k, node; + if (n == 0) + { xprintf("%s:%d: DIMENSION entry not specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (tsp->node_x_coord != NULL) + { xprintf("%s:%d: NODE_COORD_SECTION multiply specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (check_newline(csa)) + goto fail; + tsp->node_x_coord = xalloc(1+n, sizeof(double)); + tsp->node_y_coord = xalloc(1+n, sizeof(double)); + for (node = 1; node <= n; node++) + tsp->node_x_coord[node] = tsp->node_y_coord[node] = DBL_MAX; + for (k = 1; k <= n; k++) + { if (scan_integer(csa, 0, &node)) + goto fail; + if (!(1 <= node && node <= n)) + { xprintf("%s:%d: invalid node number %d\n", csa->fname, + csa->seqn, node); + goto fail; + } + if (tsp->node_x_coord[node] != DBL_MAX) + { xprintf("%s:%d: node number %d multiply specified\n", + csa->fname, csa->seqn, node); + goto fail; + } + if (scan_number(csa, 0, &tsp->node_x_coord[node])) + goto fail; + if (scan_number(csa, 0, &tsp->node_y_coord[node])) + goto fail; + if (check_newline(csa)) + goto fail; + } + } + else if (strcmp(csa->token, "DISPLAY_DATA_SECTION") == 0) + { int n = tsp->dimension, k, node; + if (n == 0) + { xprintf("%s:%d: DIMENSION entry not specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (tsp->dply_x_coord != NULL) + { xprintf("%s:%d: DISPLAY_DATA_SECTION multiply specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (check_newline(csa)) + goto fail; + tsp->dply_x_coord = xalloc(1+n, sizeof(double)); + tsp->dply_y_coord = xalloc(1+n, sizeof(double)); + for (node = 1; node <= n; node++) + tsp->dply_x_coord[node] = tsp->dply_y_coord[node] = DBL_MAX; + for (k = 1; k <= n; k++) + { if (scan_integer(csa, 0, &node)) + goto fail; + if (!(1 <= node && node <= n)) + { xprintf("%s:%d: invalid node number %d\n", csa->fname, + csa->seqn, node); + goto fail; + } + if (tsp->dply_x_coord[node] != DBL_MAX) + { xprintf("%s:%d: node number %d multiply specified\n", + csa->fname, csa->seqn, node); + goto fail; + } + if (scan_number(csa, 0, &tsp->dply_x_coord[node])) + goto fail; + if (scan_number(csa, 0, &tsp->dply_y_coord[node])) + goto fail; + if (check_newline(csa)) + goto fail; + } + } + else if (strcmp(csa->token, "TOUR_SECTION") == 0) + { int n = tsp->dimension, k, node; + if (n == 0) + { xprintf("%s:%d: DIMENSION entry not specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (tsp->tour != NULL) + { xprintf("%s:%d: TOUR_SECTION multiply specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (check_newline(csa)) + goto fail; + tsp->tour = xalloc(1+n, sizeof(int)); + for (k = 1; k <= n; k++) + { if (scan_integer(csa, 1, &node)) + goto fail; + if (!(1 <= node && node <= n)) + { xprintf("%s:%d: invalid node number %d\n", csa->fname, + csa->seqn, node); + goto fail; + } + tsp->tour[k] = node; + } + if (scan_integer(csa, 1, &node)) + goto fail; + if (node != -1) + { xprintf("%s:%d: extra node(s) detected\n", csa->fname, + csa->seqn); + goto fail; + } + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "EDGE_WEIGHT_SECTION") == 0) + { int n = tsp->dimension, i, j, temp; + if (n == 0) + { xprintf("%s:%d: DIMENSION entry not specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (tsp->edge_weight_format == TSP_UNDEF) + { xprintf("%s:%d: EDGE_WEIGHT_FORMAT entry not specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (tsp->edge_weight != NULL) + { xprintf("%s:%d: EDGE_WEIGHT_SECTION multiply specified\n", + csa->fname, csa->seqn); + goto fail; + } + if (check_newline(csa)) + goto fail; + tsp->edge_weight = xalloc(1+n*n, sizeof(int)); + switch (tsp->edge_weight_format) + { case TSP_FULL_MATRIX: + for (i = 1; i <= n; i++) + { for (j = 1; j <= n; j++) + { if (scan_integer(csa, 1, &temp)) + goto fail; + tsp->edge_weight[(i - 1) * n + j] = temp; + } + } + break; + case TSP_UPPER_ROW: + for (i = 1; i <= n; i++) + { tsp->edge_weight[(i - 1) * n + i] = 0; + for (j = i + 1; j <= n; j++) + { if (scan_integer(csa, 1, &temp)) + goto fail; + tsp->edge_weight[(i - 1) * n + j] = temp; + tsp->edge_weight[(j - 1) * n + i] = temp; + } + } + break; + case TSP_LOWER_DIAG_ROW: + for (i = 1; i <= n; i++) + { for (j = 1; j <= i; j++) + { if (scan_integer(csa, 1, &temp)) + goto fail; + tsp->edge_weight[(i - 1) * n + j] = temp; + tsp->edge_weight[(j - 1) * n + i] = temp; + } + } + break; + default: + goto fail; + } + if (check_newline(csa)) + goto fail; + } + else if (strcmp(csa->token, "EOF") == 0) + { if (check_newline(csa)) + goto fail; + goto done; + } + else + { xprintf("%s:%d: keyword '%s' not recognized\n", csa->fname, + csa->seqn, csa->token); + goto fail; + } + goto loop; +done: xprintf("%d lines were read\n", csa->seqn-1); + fclose(csa->fp); + return tsp; +fail: if (tsp != NULL) + { if (tsp->name != NULL) + xfree(tsp->name); + if (tsp->comment != NULL) + xfree(tsp->comment); + if (tsp->node_x_coord != NULL) + xfree(tsp->node_x_coord); + if (tsp->node_y_coord != NULL) + xfree(tsp->node_y_coord); + if (tsp->dply_x_coord != NULL) + xfree(tsp->dply_x_coord); + if (tsp->dply_y_coord != NULL) + xfree(tsp->dply_y_coord); + if (tsp->tour != NULL) + xfree(tsp->tour); + if (tsp->edge_weight != NULL) + xfree(tsp->edge_weight); + xfree(tsp); + } + if (csa->fp != NULL) + fclose(csa->fp); + return NULL; +} + +/*********************************************************************** +* NAME +* +* tsp_distance - compute distance between two nodes +* +* SYNOPSIS +* +* #include "tsplib.h" +* int tsp_distance(TSP *tsp, int i, int j); +* +* DESCRIPTION +* +* The routine tsp_distance computes the distance between i-th and j-th +* nodes for the TSP instance, which tsp points to. +* +* RETURNS +* +* The routine tsp_distance returns the computed distance. */ + +#define nint(x) ((int)((x) + 0.5)) + +static double rad(double x) +{ /* convert input coordinate to longitude/latitude, in radians */ + double pi = 3.141592, deg, min; + deg = (int)x; + min = x - deg; + return pi * (deg + 5.0 * min / 3.0) / 180.0; +} + +int tsp_distance(const TSP *tsp, int i, int j) +{ int n = tsp->dimension, dij; + if (!(tsp->type == TSP_TSP || tsp->type == TSP_ATSP)) + xerror("tsp_distance: invalid TSP instance\n"); + if (!(1 <= i && i <= n && 1 <= j && j <= n)) + xerror("tsp_distance: node number out of range\n"); + switch (tsp->edge_weight_type) + { case TSP_UNDEF: + xerror("tsp_distance: edge weight type not specified\n"); + case TSP_EXPLICIT: + if (tsp->edge_weight == NULL) + xerror("tsp_distance: edge weights not specified\n"); + dij = tsp->edge_weight[(i - 1) * n + j]; + break; + case TSP_EUC_2D: + if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) + xerror("tsp_distance: node coordinates not specified\n"); + { double xd, yd; + xd = tsp->node_x_coord[i] - tsp->node_x_coord[j]; + yd = tsp->node_y_coord[i] - tsp->node_y_coord[j]; + dij = nint(sqrt(xd * xd + yd * yd)); + } + break; + case TSP_CEIL_2D: + if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) + xerror("tsp_distance: node coordinates not specified\n"); + { double xd, yd; + xd = tsp->node_x_coord[i] - tsp->node_x_coord[j]; + yd = tsp->node_y_coord[i] - tsp->node_y_coord[j]; + dij = (int)ceil(sqrt(xd * xd + yd * yd)); + } + break; + case TSP_GEO: + if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) + xerror("tsp_distance: node coordinates not specified\n"); + { double rrr = 6378.388; + double latitude_i = rad(tsp->node_x_coord[i]); + double latitude_j = rad(tsp->node_x_coord[j]); + double longitude_i = rad(tsp->node_y_coord[i]); + double longitude_j = rad(tsp->node_y_coord[j]); + double q1 = cos(longitude_i - longitude_j); + double q2 = cos(latitude_i - latitude_j); + double q3 = cos(latitude_i + latitude_j); + dij = (int)(rrr * acos(0.5 * ((1.0 + q1) * q2 - + (1.0 - q1) *q3)) + 1.0); + } + break; + case TSP_ATT: + if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) + xerror("tsp_distance: node coordinates not specified\n"); + { int tij; + double xd, yd, rij; + xd = tsp->node_x_coord[i] - tsp->node_x_coord[j]; + yd = tsp->node_y_coord[i] - tsp->node_y_coord[j]; + rij = sqrt((xd * xd + yd * yd) / 10.0); + tij = nint(rij); + if (tij < rij) dij = tij + 1; else dij = tij; + } + break; + default: + xassert(tsp->edge_weight_type != tsp->edge_weight_type); + } + return dij; +} + +/*********************************************************************** +* NAME +* +* tsp_free_data - free TSP instance data +* +* SYNOPSIS +* +* #include "tsplib.h" +* void tsp_free_data(TSP *tsp); +* +* DESCRIPTION +* +* The routine tsp_free_data frees all the memory allocated to the TSP +* instance data block, which the parameter tsp points to. */ + +void tsp_free_data(TSP *tsp) +{ if (tsp->name != NULL) + xfree(tsp->name); + if (tsp->comment != NULL) + xfree(tsp->comment); + if (tsp->node_x_coord != NULL) + xfree(tsp->node_x_coord); + if (tsp->node_y_coord != NULL) + xfree(tsp->node_y_coord); + if (tsp->dply_x_coord != NULL) + xfree(tsp->dply_x_coord); + if (tsp->dply_y_coord != NULL) + xfree(tsp->dply_y_coord); + if (tsp->tour != NULL) + xfree(tsp->tour); + if (tsp->edge_weight != NULL) + xfree(tsp->edge_weight); + xfree(tsp); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/tsplib.h b/resources/3rdparty/glpk-4.57/examples/tsp/tsplib.h new file mode 100644 index 000000000..efadaef88 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/tsplib.h @@ -0,0 +1,80 @@ +/* tsplib.h */ + +/* Written by Andrew Makhorin , October 2015. */ + +#ifndef TSPLIB_H +#define TSPLIB_H + +typedef struct TSP TSP; + +struct TSP +{ /* TSP (or related problem) instance in the format described in + * [G.Reinelt, TSPLIB 95] */ + /*--------------------------------------------------------------*/ + /* specification part */ + char *name; + /* identifies the data file */ + int type; + /* specifies the type of data: */ +#define TSP_UNDEF 0 /* undefined */ +#define TSP_TSP 1 /* symmetric TSP */ +#define TSP_ATSP 2 /* asymmetric TSP */ +#define TSP_TOUR 3 /* collection of tours */ + char *comment; + /* additional comments (usually the name of the contributor or + * creator of the problem instance is given here) */ + int dimension; + /* for a TSP or ATSP, the dimension is the number of its nodes + * for a TOUR it is the dimension of the corresponding problem */ + int edge_weight_type; + /* specifies how the edge weights (or distances) are given: */ +#define TSP_UNDEF 0 /* undefined */ +#define TSP_EXPLICIT 1 /* listed explicitly */ +#define TSP_EUC_2D 2 /* Eucl. distances in 2-D */ +#define TSP_CEIL_2D 3 /* Eucl. distances in 2-D rounded up */ +#define TSP_GEO 4 /* geographical distances */ +#define TSP_ATT 5 /* special distance function */ + int edge_weight_format; + /* describes the format of the edge weights if they are given + * explicitly: */ +#define TSP_UNDEF 0 /* undefined */ +#define TSP_FUNCTION 1 /* given by a function */ +#define TSP_FULL_MATRIX 2 /* given by a full matrix */ +#define TSP_UPPER_ROW 3 /* upper triangulat matrix (row-wise + * without diagonal entries) */ +#define TSP_LOWER_DIAG_ROW 4 /* lower triangular matrix (row-wise + * including diagonal entries) */ + int display_data_type; + /* specifies how a graphical display of the nodes can be + * obtained: */ +#define TSP_UNDEF 0 /* undefined */ +#define TSP_COORD_DISPLAY 1 /* display is generated from the node + * coordinates */ +#define TSP_TWOD_DISPLAY 2 /* explicit coordinates in 2-D are + * given */ + /*--------------------------------------------------------------*/ + /* data part */ + /* NODE_COORD_SECTION: */ + double *node_x_coord; /* double node_x_coord[1+dimension]; */ + double *node_y_coord; /* double node_y_coord[1+dimension]; */ + /* DISPLAY_DATA_SECTION: */ + double *dply_x_coord; /* double dply_x_coord[1+dimension]; */ + double *dply_y_coord; /* double dply_y_coord[1+dimension]; */ + /* TOUR_SECTION: */ + int *tour; /* int tour[1+dimension]; */ + /* EDGE_WEIGHT_SECTION: */ + int *edge_weight; /* int edge_weight[1+dimension*dimension]; */ +}; + +TSP *tsp_read_data(const char *fname); +/* read TSP instance data */ + +int tsp_distance(const TSP *tsp, int i, int j); +/* compute distance between two nodes */ + +void tsp_free_data(TSP *tsp); +/* free TSP instance data */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/ulysses16.tsp b/resources/3rdparty/glpk-4.57/examples/tsp/ulysses16.tsp new file mode 100644 index 000000000..4ce24a60e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/ulysses16.tsp @@ -0,0 +1,24 @@ +NAME: ulysses16.tsp +TYPE: TSP +COMMENT: Odyssey of Ulysses (Groetschel/Padberg) +DIMENSION: 16 +EDGE_WEIGHT_TYPE: GEO +DISPLAY_DATA_TYPE: COORD_DISPLAY +NODE_COORD_SECTION + 1 38.24 20.42 + 2 39.57 26.15 + 3 40.56 25.32 + 4 36.26 23.12 + 5 33.48 10.54 + 6 37.56 12.19 + 7 38.42 13.11 + 8 37.52 20.44 + 9 41.23 9.10 + 10 41.17 13.05 + 11 36.08 -5.21 + 12 38.47 15.13 + 13 38.15 15.35 + 14 37.51 15.17 + 15 35.49 14.32 + 16 39.36 19.56 + EOF diff --git a/resources/3rdparty/glpk-4.57/examples/tsp/ulysses22.tsp b/resources/3rdparty/glpk-4.57/examples/tsp/ulysses22.tsp new file mode 100644 index 000000000..9e95fb826 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/tsp/ulysses22.tsp @@ -0,0 +1,30 @@ +NAME: ulysses22.tsp +TYPE: TSP +COMMENT: Odyssey of Ulysses (Groetschel/Padberg) +DIMENSION: 22 +EDGE_WEIGHT_TYPE: GEO +DISPLAY_DATA_TYPE: COORD_DISPLAY +NODE_COORD_SECTION + 1 38.24 20.42 + 2 39.57 26.15 + 3 40.56 25.32 + 4 36.26 23.12 + 5 33.48 10.54 + 6 37.56 12.19 + 7 38.42 13.11 + 8 37.52 20.44 + 9 41.23 9.10 + 10 41.17 13.05 + 11 36.08 -5.21 + 12 38.47 15.13 + 13 38.15 15.35 + 14 37.51 15.17 + 15 35.49 14.32 + 16 39.36 19.56 + 17 38.09 24.36 + 18 36.09 23.00 + 19 40.44 13.57 + 20 40.33 14.15 + 21 40.37 14.23 + 22 37.57 22.56 +EOF diff --git a/resources/3rdparty/glpk-4.57/examples/xyacfs.mod b/resources/3rdparty/glpk-4.57/examples/xyacfs.mod new file mode 100644 index 000000000..5a0b22e0e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/xyacfs.mod @@ -0,0 +1,56 @@ +/*Extended Yet Another Curve Fitting Solution (The poor man's RMA) + + An extension of yacfs.mod adding a Weight parameter: + When set to 1 the model produces best fit by least squares with all error in y and none in x (YonX); + When set to zero the model produces best fit by least squares with all error in x and none in y (XonY); + When set to 0.5 the model assumes equal error in x and y producing results similar to fitting by Reduced Major Axis Analysis. + + Nigel_Galloway@operamail.com + November 5th., 2009 +*/ +set Sample; +param Sx {z in Sample}; +param Sy {z in Sample}; +param Weight := 0.5; + +var a; +var b; +var p; +var q; + +XonY1 :sum{z in Sample} q*Sy[z]*Sy[z] + sum{z in Sample} p*Sy[z] = sum{z in Sample} Sy[z]*Sx[z]; +XonY2 :sum{z in Sample} q*Sy[z] + sum{z in Sample} p = sum{z in Sample} Sx[z]; +YonX1 :sum{z in Sample} a*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z] = sum{z in Sample} Sy[z]*Sx[z]; +YonX2 :sum{z in Sample} a*Sx[z] + sum{z in Sample} b = sum{z in Sample} Sy[z]; + +solve; + +param W := Weight*a + (1-Weight)*(1/q); +printf "\nbest linear fit is:\n\ty = %f %s %fx\n\n", b*Weight - (1-Weight)*(p/q), if W < 0 then "-" else "+", abs(W); + +data; + +param: +Sample: Sx Sy := + 1 0 1 + 2 0.5 0.9 + 3 1 0.7 + 4 1.5 1.5 + 5 1.9 2 + 6 2.5 2.4 + 7 3 3.2 + 8 3.5 2 + 9 4 2.7 + 10 4.5 3.5 + 11 5 1 + 12 5.5 4 + 13 6 3.6 + 14 6.6 2.7 + 15 7 5.7 + 16 7.6 4.6 + 17 8.5 6 + 18 9 6.8 + 19 10 7.3 +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/yacfs.mod b/resources/3rdparty/glpk-4.57/examples/yacfs.mod new file mode 100644 index 000000000..270f2a083 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/yacfs.mod @@ -0,0 +1,48 @@ +/*Yet Another Curve Fitting Solution + + Obviously this solution produces the same answer + as examples/cflsq.mod + + Nigel_Galloway@operamail.com + February 1st., 2009 +*/ +set Sample; +param Sx {z in Sample}; +param Sy {z in Sample}; + +var a; +var b; + +equalz1 :sum{z in Sample} a*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z] = sum{z in Sample} Sy[z]*Sx[z]; +equalz2 :sum{z in Sample} a*Sx[z] + sum{z in Sample} b = sum{z in Sample} Sy[z]; + +solve; + +printf "\nbest linear fit is:\n\ty = %f %s %fx\n\n", b, if a < 0 then "-" else "+", abs(a); + +data; + +param: +Sample: Sx Sy := + 1 0 1 + 2 0.5 0.9 + 3 1 0.7 + 4 1.5 1.5 + 5 1.9 2 + 6 2.5 2.4 + 7 3 3.2 + 8 3.5 2 + 9 4 2.7 + 10 4.5 3.5 + 11 5 1 + 12 5.5 4 + 13 6 3.6 + 14 6.6 2.7 + 15 7 5.7 + 16 7.6 4.6 + 17 8.5 6 + 18 9 6.8 + 19 10 7.3 +; + +end; diff --git a/resources/3rdparty/glpk-4.57/examples/zebra.mod b/resources/3rdparty/glpk-4.57/examples/zebra.mod new file mode 100644 index 000000000..66f8c1aaf --- /dev/null +++ b/resources/3rdparty/glpk-4.57/examples/zebra.mod @@ -0,0 +1,151 @@ +/* ZEBRA, Who Owns the Zebra? */ + +/* Written in GNU MathProg by Andrew Makhorin */ + +######################################################################## +# The Zebra Puzzle is a well-known logic puzzle. +# +# It is often called "Einstein's Puzzle" or "Einstein's Riddle" +# because it is said to have been invented by Albert Einstein as a boy, +# with the common claim that Einstein said "only 2 percent of the +# world's population can solve". It is also sometimes attributed to +# Lewis Carroll. However, there is no known evidence for Einstein's or +# Carroll's authorship. +# +# There are several versions of this puzzle. The version below is +# quoted from the first known publication in Life International +# magazine on December 17, 1962. +# +# 1. There are five houses. +# 2. The Englishman lives in the red house. +# 3. The Spaniard owns the dog. +# 4. Coffee is drunk in the green house. +# 5. The Ukrainian drinks tea. +# 6. The green house is immediately to the right of the ivory house. +# 7. The Old Gold smoker owns snails. +# 8. Kools are smoked in the yellow house. +# 9. Milk is drunk in the middle house. +# 10. The Norwegian lives in the first house. +# 11. The man who smokes Chesterfields lives in the house next to the +# man with the fox. +# 12. Kools are smoked in the house next to the house where the horse +# is kept. +# 13. The Lucky Strike smoker drinks orange juice. +# 14. The Japanese smokes Parliaments. +# 15. The Norwegian lives next to the blue house. +# +# Now, who drinks water? Who owns the zebra? +# +# In the interest of clarity, it must be added that each of the five +# houses is painted a different color, and their inhabitants are of +# different national extractions, own different pets, drink different +# beverages and smoke different brands of American cigarettes. One +# other thing: In statement 6, right means your right. +# +# (From Wikipedia, the free encyclopedia.) +######################################################################## + +set HOUSE := { 1..5 }; + +set COLOR := { "blue", "green", "ivory", "red", "yellow" }; + +set NATIONALITY := { "Englishman", "Japanese", "Norwegian", "Spaniard", + "Ukranian" }; + +set DRINK := { "coffee", "milk", "orange_juice", "tea", "water" }; + +set SMOKE := { "Chesterfield", "Kools", "Lucky_Strike", "Old_Gold", + "Parliament" }; + +set PET := { "dog", "fox", "horse", "snails", "zebra" }; + +var color{HOUSE, COLOR}, binary; +c1{h in HOUSE}: sum{c in COLOR} color[h,c] = 1; +c2{c in COLOR}: sum{h in HOUSE} color[h,c] = 1; + +var nationality{HOUSE, NATIONALITY}, binary; +n1{h in HOUSE}: sum{n in NATIONALITY} nationality[h,n] = 1; +n2{n in NATIONALITY}: sum{h in HOUSE} nationality[h,n] = 1; + +var drink{HOUSE, DRINK}, binary; +d1{h in HOUSE}: sum{d in DRINK} drink[h,d] = 1; +d2{d in DRINK}: sum{h in HOUSE} drink[h,d] = 1; + +var smoke{HOUSE, SMOKE}, binary; +s1{h in HOUSE}: sum{s in SMOKE} smoke[h,s] = 1; +s2{s in SMOKE}: sum{h in HOUSE} smoke[h,s] = 1; + +var pet{HOUSE, PET}, binary; +p1{h in HOUSE}: sum{p in PET} pet[h,p] = 1; +p2{p in PET}: sum{h in HOUSE} pet[h,p] = 1; + +/* the Englishman lives in the red house */ +f2{h in HOUSE}: nationality[h,"Englishman"] = color[h,"red"]; + +/* the Spaniard owns the dog */ +f3{h in HOUSE}: nationality[h,"Spaniard"] = pet[h,"dog"]; + +/* coffee is drunk in the green house */ +f4{h in HOUSE}: drink[h,"coffee"] = color[h,"green"]; + +/* the Ukrainian drinks tea */ +f5{h in HOUSE}: nationality[h,"Ukranian"] = drink[h,"tea"]; + +/* the green house is immediately to the right of the ivory house */ +f6{h in HOUSE}: + color[h,"green"] = if h = 1 then 0 else color[h-1,"ivory"]; + +/* the Old Gold smoker owns snails */ +f7{h in HOUSE}: smoke[h,"Old_Gold"] = pet[h,"snails"]; + +/* Kools are smoked in the yellow house */ +f8{h in HOUSE}: smoke[h,"Kools"] = color[h,"yellow"]; + +/* milk is drunk in the middle house */ +f9: drink[3,"milk"] = 1; + +/* the Norwegian lives in the first house */ +f10: nationality[1,"Norwegian"] = 1; + +/* the man who smokes Chesterfields lives in the house next to the man + with the fox */ +f11{h in HOUSE}: + (1 - smoke[h,"Chesterfield"]) + + (if h = 1 then 0 else pet[h-1,"fox"]) + + (if h = 5 then 0 else pet[h+1,"fox"]) >= 1; + +/* Kools are smoked in the house next to the house where the horse is + kept */ +f12{h in HOUSE}: + (1 - smoke[h,"Kools"]) + + (if h = 1 then 0 else pet[h-1,"horse"]) + + (if h = 5 then 0 else pet[h+1,"horse"]) >= 1; + +/* the Lucky Strike smoker drinks orange juice */ +f13{h in HOUSE}: smoke[h,"Lucky_Strike"] = drink[h,"orange_juice"]; + +/* the Japanese smokes Parliaments */ +f14{h in HOUSE}: nationality[h,"Japanese"] = smoke[h,"Parliament"]; + +/* the Norwegian lives next to the blue house */ +f15{h in HOUSE}: + (1 - nationality[h,"Norwegian"]) + + (if h = 1 then 0 else color[h-1,"blue"]) + + (if h = 5 then 0 else color[h+1,"blue"]) >= 1; + +solve; + +printf "\n"; +printf "HOUSE COLOR NATIONALITY DRINK SMOKE PET\n"; +for {h in HOUSE} +{ printf "%5d", h; + printf{c in COLOR: color[h,c]} " %-6s", c; + printf{n in NATIONALITY: nationality[h,n]} " %-11s", n; + printf{d in DRINK: drink[h,d]} " %-12s", d; + printf{s in SMOKE: smoke[h,s]} " %-12s", s; + printf{p in PET: pet[h,p]} " %-6s", p; + printf "\n"; +} +printf "\n"; + +end; diff --git a/resources/3rdparty/glpk-4.57/install-sh b/resources/3rdparty/glpk-4.57/install-sh new file mode 100755 index 000000000..377bb8687 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-11-20.07; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/resources/3rdparty/glpk-4.57/ltmain.sh b/resources/3rdparty/glpk-4.57/ltmain.sh new file mode 100755 index 000000000..fcebbcb5f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/ltmain.sh @@ -0,0 +1,9687 @@ + +# libtool (GNU libtool) 2.4 +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --no-quiet, --no-silent +# print informational messages (default) +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print more informational messages than default +# --no-verbose don't print the extra informational messages +# --version print version information +# -h, --help, --help-all print short, long, or detailed help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. When passed as first option, +# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.4 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . +# GNU libtool home page: . +# General help using GNU software: . + +PROGRAM=libtool +PACKAGE=libtool +VERSION=2.4 +TIMESTAMP="" +package_revision=1.3294 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# NLS nuisances: We save the old values to restore during execute mode. +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL + +$lt_unset CDPATH + + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + + + +: ${CP="cp -f"} +test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${EGREP="/usr/bin/grep -E"} +: ${FGREP="/usr/bin/grep -F"} +: ${GREP="/usr/bin/grep"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SED="/usr/bin/sed"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} # func_dirname may be replaced by extended shell implementation + + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} # func_basename may be replaced by extended shell implementation + + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` +} # func_dirname_and_basename may be replaced by extended shell implementation + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname may be replaced by extended shell implementation + + +# These SED scripts presuppose an absolute path with a trailing slash. +pathcar='s,^/\([^/]*\).*$,\1,' +pathcdr='s,^/[^/]*,,' +removedotparts=':dotsl + s@/\./@/@g + t dotsl + s,/\.$,/,' +collapseslashes='s@/\{1,\}@/@g' +finalslash='s,/*$,/,' + +# func_normal_abspath PATH +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +# value returned in "$func_normal_abspath_result" +func_normal_abspath () +{ + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` + while :; do + # Processed it all yet? + if test "$func_normal_abspath_tpath" = / ; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result" ; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + +# func_relative_path SRCDIR DSTDIR +# generates a relative path from SRCDIR to DSTDIR, with a trailing +# slash if non-empty, suitable for immediately appending a filename +# without needing to append a separator. +# value returned in "$func_relative_path_result" +func_relative_path () +{ + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=${func_dirname_result} + if test "x$func_relative_path_tlibdir" = x ; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test "x$func_stripname_result" != x ; then + func_relative_path_result=${func_relative_path_result}/${func_stripname_result} + fi + + # Normalisation. If bindir is libdir, return empty string, + # else relative path ending with a slash; either way, target + # file name can be directly appended. + if test ! -z "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result/" + func_relative_path_result=$func_stripname_result + fi +} + +# The name of this program: +func_dirname_and_basename "$progpath" +progname=$func_basename_result + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=: + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' + +# Sed substitution that converts a w32 file name or path +# which contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }$*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` + done + my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "$my_tmpdir" +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "$1" | $SED \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + +# func_tr_sh +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $opt_debug + + $SED -n '/(C)/!b go + :more + /\./!{ + N + s/\n# / / + b more + } + :go + /^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $opt_debug + + $SED -n '/^# Usage:/,/^# *.*--help/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + echo + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help [NOEXIT] +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $opt_debug + + $SED -n '/^# Usage:/,/# Report bugs to/ { + :print + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ + p + d + } + /^# .* home page:/b print + /^# General help using/b print + ' < "$progpath" + ret=$? + if test -z "$1"; then + exit $ret + fi +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $opt_debug + + func_error "missing argument for $1." + exit_cmd=exit +} + + +# func_split_short_opt shortopt +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +func_split_short_opt () +{ + my_sed_short_opt='1s/^\(..\).*$/\1/;q' + my_sed_short_rest='1s/^..\(.*\)$/\1/;q' + + func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` + func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` +} # func_split_short_opt may be replaced by extended shell implementation + + +# func_split_long_opt longopt +# Set func_split_long_opt_name and func_split_long_opt_arg shell +# variables after splitting LONGOPT at the `=' sign. +func_split_long_opt () +{ + my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' + my_sed_long_arg='1s/^--[^=]*=//' + + func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` + func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` +} # func_split_long_opt may be replaced by extended shell implementation + +exit_cmd=: + + + + + +magic="%%%MAGIC variable%%%" +magic_exe="%%%MAGIC EXE variable%%%" + +# Global variables. +nonopt= +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "${1}=\$${1}\${2}" +} # func_append may be replaced by extended shell implementation + +# func_append_quoted var value +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +func_append_quoted () +{ + func_quote_for_eval "${2}" + eval "${1}=\$${1}\\ \$func_quote_for_eval_result" +} # func_append_quoted may be replaced by extended shell implementation + + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "${@}"` +} # func_arith may be replaced by extended shell implementation + + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` +} # func_len may be replaced by extended shell implementation + + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} # func_lo2o may be replaced by extended shell implementation + + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} # func_xform may be replaced by extended shell implementation + + +# func_fatal_configuration arg... +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func_error ${1+"$@"} + func_error "See the $PACKAGE documentation for more information." + func_fatal_error "Fatal configuration error." +} + + +# func_config +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + +# func_features +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + +# func_enable_tag tagname +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname="$1" + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf="/$re_begincf/,/$re_endcf/p" + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# Shorthand for --mode=foo, only valid as the first argument +case $1 in +clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; +compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; +execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; +finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; +install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; +link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; +uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; +esac + + + +# Option defaults: +opt_debug=: +opt_dry_run=false +opt_config=false +opt_preserve_dup_deps=false +opt_features=false +opt_finish=false +opt_help=false +opt_help_all=false +opt_silent=: +opt_verbose=: +opt_silent=false +opt_verbose=false + + +# Parse options once, thoroughly. This comes as soon as possible in the +# script to make things like `--version' happen as quickly as we can. +{ + # this just eases exit handling + while test $# -gt 0; do + opt="$1" + shift + case $opt in + --debug|-x) opt_debug='set -x' + func_echo "enabling shell trace mode" + $opt_debug + ;; + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + --config) + opt_config=: +func_config + ;; + --dlopen|-dlopen) + optarg="$1" + opt_dlopen="${opt_dlopen+$opt_dlopen +}$optarg" + shift + ;; + --preserve-dup-deps) + opt_preserve_dup_deps=: + ;; + --features) + opt_features=: +func_features + ;; + --finish) + opt_finish=: +set dummy --mode finish ${1+"$@"}; shift + ;; + --help) + opt_help=: + ;; + --help-all) + opt_help_all=: +opt_help=': help-all' + ;; + --mode) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_mode="$optarg" +case $optarg in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; +esac + shift + ;; + --no-silent|--no-quiet) + opt_silent=false +func_append preserve_args " $opt" + ;; + --no-verbose) + opt_verbose=false +func_append preserve_args " $opt" + ;; + --silent|--quiet) + opt_silent=: +func_append preserve_args " $opt" + opt_verbose=false + ;; + --verbose|-v) + opt_verbose=: +func_append preserve_args " $opt" +opt_silent=false + ;; + --tag) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_tag="$optarg" +func_append preserve_args " $opt $optarg" +func_enable_tag "$optarg" + shift + ;; + + -\?|-h) func_usage ;; + --help) func_help ;; + --version) func_version ;; + + # Separate optargs to long options: + --*=*) + func_split_long_opt "$opt" + set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-n*|-v*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognized option \`$opt'" ;; + *) set dummy "$opt" ${1+"$@"}; shift; break ;; + esac + done + + # Validate options: + + # save first non-option argument + if test "$#" -gt 0; then + nonopt="$opt" + shift + fi + + # preserve --debug + test "$opt_debug" = : || func_append preserve_args " --debug" + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test "$opt_mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$opt_mode' for more information." + } + + + # Bail if the options were screwed + $exit_cmd $EXIT_FAILURE +} + + + + +## ----------- ## +## Main. ## +## ----------- ## + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case "$lt_sysroot:$1" in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result="=$func_stripname_result" + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$lt_sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $opt_debug + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result="" + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $opt_debug + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $opt_debug + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $opt_debug + if test -z "$2" && test -n "$1" ; then + func_error "Could not determine host file name corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result="$1" + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $opt_debug + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " \`$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result="$3" + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $opt_debug + case $4 in + $1 ) func_to_host_path_result="$3$func_to_host_path_result" + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via `$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $opt_debug + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $opt_debug + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result="$1" +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result="$func_convert_core_msys_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via `$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $opt_debug + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd="func_convert_path_${func_stripname_result}" + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $opt_debug + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result="$1" +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_mode_compile arg... +func_mode_compile () +{ + $opt_debug + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify \`-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + func_append_quoted lastarg "$arg" + done + IFS="$save_ifs" + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with \`-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj="$func_basename_result" + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from \`$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test "$opt_mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$opt_mode'" + ;; + esac + + echo + $ECHO "Try \`$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test "$opt_help" = :; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | sed -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + sed '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "\`$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument \`$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test "$opt_mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test "x$prev" = x-m && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename="" + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname" ; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename="$func_basename_result" + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename" ; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $opt_debug + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $opt_debug + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive which possess that section. Heuristic: eliminate + # all those which have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $opt_debug + if func_cygming_gnu_implib_p "$1" ; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1" ; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result="" + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + if test "$lock_old_archive_extraction" = yes; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test "$lock_old_archive_extraction" = yes; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ which is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/* declarations of non-ANSI functions */ +#if defined(__MINGW32__) +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined(__CYGWIN__) +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined (other platforms) ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined(_MSC_VER) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +# ifndef _INTPTR_T_DEFINED +# define _INTPTR_T_DEFINED +# define intptr_t int +# endif +#elif defined(__MINGW32__) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined(__CYGWIN__) +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined (other platforms) ... */ +#endif + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#if defined(LT_DEBUGWRAPPER) +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -e 's/\([\\"]\)/\\\1/g' \ + -e 's/^/ fputs ("/' -e 's/$/\\n", f);/' + + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_emit_exe_manifest +# emit a Win32 UAC manifest for executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_exe_manifest () +{ + cat < + + + + + + + + + + + + +EOF +} + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $opt_debug + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -{shared,static}-libgcc, -static-{libgfortran|libstdc++} + # link against specified runtime library + # -fstack-protector* stack protector flags for GCC + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-flto*|-fwhopr*|-fuse-linker-plugin| \ + -shared-libgcc|-static-libgcc|-static-libgfortran|-static-libstdc++| \ + -fstack-protector*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps ; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + else + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test "$prefer_static_libs" = yes || + test "$prefer_static_libs,$installed" = "built,no"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib="$l" + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$lt_sysroot$libdir" + absdir="$lt_sysroot$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + case "$host" in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + echo + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$opt_mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$opt_mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|qnx|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + func_append verstring ":${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + func_append libobjs " $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$opt_mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_apped perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd1 in $cmds; do + IFS="$save_ifs" + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test "$try_normal_branch" = yes \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=${output_objdir}/${output_la}.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " ${wl}-bind_at_load" + func_append finalize_command " ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper $cwrapper.manifest; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + # Create the UAC manifests first if necessary (but the + # manifest files must have executable permission regardless). + case $output_name in + *instal*|*patch*|*setup*|*update*) + func_emit_exe_manifest > $cwrapper.manifest + func_emit_exe_manifest > $output_path/$objdir/$output_name.exe.manifest + chmod +x $cwrapper.manifest + chmod +x $output_path/$objdir/$output_name.exe.manifest + ;; + esac + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + func_append oldobjs " $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$opt_mode" = link || test "$opt_mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=yes ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + odir="$objdir" + else + odir="$dir/$objdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$opt_mode" = uninstall && odir="$dir" + + # Remember odir for removal later, being careful to avoid duplicates + if test "$opt_mode" = clean; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case "$opt_mode" in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$opt_mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.${objext}" + func_append rmfiles " ${name}.manifest $objdir/${name}.manifest" + if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name $objdir/lt-${name}.manifest" + fi + if test "X$noexename" != "X$name" ; then + func_append rmfiles " $odir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$opt_mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/resources/3rdparty/glpk-4.57/m4/libtool.m4 b/resources/3rdparty/glpk-4.57/m4/libtool.m4 new file mode 100644 index 000000000..6aebb63b5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/m4/libtool.m4 @@ -0,0 +1,7831 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES +# -------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Xcompiler -fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], + [[If ld is used when linking, flag to hardcode $libdir into a binary + during linking. This must work even if $libdir does not exist]]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/resources/3rdparty/glpk-4.57/m4/ltoptions.m4 b/resources/3rdparty/glpk-4.57/m4/ltoptions.m4 new file mode 100644 index 000000000..17cfd51c0 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/m4/ltoptions.m4 @@ -0,0 +1,369 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/resources/3rdparty/glpk-4.57/m4/ltsugar.m4 b/resources/3rdparty/glpk-4.57/m4/ltsugar.m4 new file mode 100644 index 000000000..9000a057d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/m4/ltsugar.m4 @@ -0,0 +1,123 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/resources/3rdparty/glpk-4.57/m4/ltversion.m4 b/resources/3rdparty/glpk-4.57/m4/ltversion.m4 new file mode 100644 index 000000000..9bf776f09 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 3294 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4]) +m4_define([LT_PACKAGE_REVISION], [1.3294]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4' +macro_revision='1.3294' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/resources/3rdparty/glpk-4.57/m4/lt~obsolete.m4 b/resources/3rdparty/glpk-4.57/m4/lt~obsolete.m4 new file mode 100644 index 000000000..c573da90c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/m4/lt~obsolete.m4 @@ -0,0 +1,98 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/resources/3rdparty/glpk-4.57/missing b/resources/3rdparty/glpk-4.57/missing new file mode 100755 index 000000000..9a5564823 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/missing @@ -0,0 +1,330 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2012-01-06.18; # UTC + +# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, 'missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle 'PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file 'aclocal.m4' + autoconf touch file 'configure' + autoheader touch file 'config.h.in' + autom4te touch the output file, or create a stub one + automake touch all 'Makefile.in' files + bison create 'y.tab.[ch]', if possible, from existing .[ch] + flex create 'lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create 'lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create 'y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running '$TOOL --version' or '$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: '$1' is $msg. You should only need it if + you modified 'acinclude.m4' or '${configure_ac}'. You might want + to install the Automake and Perl packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: '$1' is $msg. You should only need it if + you modified '${configure_ac}'. You might want to install the + Autoconf and GNU m4 packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: '$1' is $msg. You should only need it if + you modified 'acconfig.h' or '${configure_ac}'. You might want + to install the Autoconf and GNU m4 packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: '$1' is $msg. You should only need it if + you modified 'Makefile.am', 'acinclude.m4' or '${configure_ac}'. + You might want to install the Automake and Perl packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: '$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get '$1' as part of Autoconf from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: '$1' $msg. You should only need it if + you modified a '.y' file. You may need the Bison package + in order for those modifications to take effect. You can get + Bison from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: '$1' is $msg. You should only need it if + you modified a '.l' file. You may need the Flex package + in order for those modifications to take effect. You can get + Flex from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: '$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + Help2man package in order for those modifications to take + effect. You can get Help2man from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: '$1' is $msg. You should only need it if + you modified a '.texi' or '.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy 'make' (AIX, + DU, IRIX). You might want to install the Texinfo package or + the GNU make package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: '$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the 'README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing '$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/resources/3rdparty/glpk-4.57/src/Makefile.am b/resources/3rdparty/glpk-4.57/src/Makefile.am new file mode 100644 index 000000000..836ef11bd --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/Makefile.am @@ -0,0 +1,178 @@ +## Process this file with automake to produce Makefile.in ## + +include_HEADERS = glpk.h + +lib_LTLIBRARIES = libglpk.la + +libglpk_la_CPPFLAGS = \ +-I$(srcdir) \ +-I$(srcdir)/amd \ +-I$(srcdir)/bflib \ +-I$(srcdir)/cglib \ +-I$(srcdir)/colamd \ +-I$(srcdir)/env \ +-I$(srcdir)/minisat \ +-I$(srcdir)/misc \ +-I$(srcdir)/proxy \ +-I$(srcdir)/simplex \ +-I$(srcdir)/zlib + +libglpk_la_LDFLAGS = \ +-version-info 38:0:2 \ +-export-symbols-regex '^glp_*' + +libglpk_la_SOURCES = \ +avl.c \ +bfd.c \ +bfx.c \ +glpapi01.c \ +glpapi02.c \ +glpapi03.c \ +glpapi04.c \ +glpapi05.c \ +glpapi06.c \ +glpapi07.c \ +glpapi08.c \ +glpapi09.c \ +glpapi10.c \ +glpapi11.c \ +glpapi12.c \ +glpapi13.c \ +glpapi14.c \ +glpapi15.c \ +glpapi16.c \ +glpapi17.c \ +glpapi18.c \ +glpapi19.c \ +glpapi20.c \ +glpapi21.c \ +glpcpx.c \ +glpdmx.c \ +glpgmp.c \ +glphbm.c \ +glpini01.c \ +glpini02.c \ +glpios01.c \ +glpios02.c \ +glpios03.c \ +glpios04.c \ +glpios05.c \ +glpios06.c \ +glpios07.c \ +glpios08.c \ +glpios09.c \ +glpios10.c \ +glpios11.c \ +glpios12.c \ +glpipm.c \ +glpmat.c \ +glpmpl01.c \ +glpmpl02.c \ +glpmpl03.c \ +glpmpl04.c \ +glpmpl05.c \ +glpmpl06.c \ +glpmps.c \ +glpnet03.c \ +glpnet04.c \ +glpnet05.c \ +glpnpp01.c \ +glpnpp02.c \ +glpnpp03.c \ +glpnpp04.c \ +glpnpp05.c \ +glpnpp06.c \ +glprgr.c \ +glpscl.c \ +glpsdf.c \ +glpspm.c \ +glpsql.c \ +glpssx01.c \ +glpssx02.c \ +lux.c \ +amd/amd_1.c \ +amd/amd_2.c \ +amd/amd_aat.c \ +amd/amd_control.c \ +amd/amd_defaults.c \ +amd/amd_dump.c \ +amd/amd_info.c \ +amd/amd_order.c \ +amd/amd_post_tree.c \ +amd/amd_postorder.c \ +amd/amd_preprocess.c \ +amd/amd_valid.c \ +bflib/btf.c \ +bflib/btfint.c \ +bflib/fhv.c \ +bflib/fhvint.c \ +bflib/ifu.c \ +bflib/luf.c \ +bflib/lufint.c \ +bflib/scf.c \ +bflib/scfint.c \ +bflib/sgf.c \ +bflib/sva.c \ +cglib/cfg.c \ +cglib/cfg1.c \ +colamd/colamd.c \ +env/alloc.c \ +env/dlsup.c \ +env/env.c \ +env/error.c \ +env/stdout.c \ +env/stream.c \ +env/time.c \ +env/tls.c \ +minisat/minisat.c \ +misc/bignum.c \ +misc/dmp.c \ +misc/ffalg.c \ +misc/fp2rat.c \ +misc/gcd.c \ +misc/jd.c \ +misc/keller.c \ +misc/mc13d.c \ +misc/mc21a.c \ +misc/okalg.c \ +misc/qmd.c \ +misc/relax4.c \ +misc/rng.c \ +misc/rng1.c \ +misc/round2n.c \ +misc/str2int.c \ +misc/str2num.c \ +misc/strspx.c \ +misc/strtrim.c \ +misc/triang.c \ +misc/wclique.c \ +misc/wclique1.c \ +proxy/proxy.c \ +proxy/proxy1.c \ +simplex/spxat.c \ +simplex/spxchuzc.c \ +simplex/spxchuzr.c \ +simplex/spxlp.c \ +simplex/spxnt.c \ +simplex/spxprim.c \ +simplex/spxprob.c \ +simplex/spychuzc.c \ +simplex/spychuzr.c \ +simplex/spydual.c \ +zlib/adler32.c \ +zlib/compress.c \ +zlib/crc32.c \ +zlib/deflate.c \ +zlib/gzclose.c \ +zlib/gzlib.c \ +zlib/gzread.c \ +zlib/gzwrite.c \ +zlib/inffast.c \ +zlib/inflate.c \ +zlib/inftrees.c \ +zlib/trees.c \ +zlib/uncompr.c \ +zlib/zio.c \ +zlib/zutil.c + +## eof ## diff --git a/resources/3rdparty/glpk-4.57/src/Makefile.in b/resources/3rdparty/glpk-4.57/src/Makefile.in new file mode 100644 index 000000000..cf9f95ae2 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/Makefile.in @@ -0,0 +1,2045 @@ +# Makefile.in generated by automake 1.12.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src +DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libglpk_la_LIBADD = +am_libglpk_la_OBJECTS = libglpk_la-avl.lo libglpk_la-bfd.lo \ + libglpk_la-bfx.lo libglpk_la-glpapi01.lo \ + libglpk_la-glpapi02.lo libglpk_la-glpapi03.lo \ + libglpk_la-glpapi04.lo libglpk_la-glpapi05.lo \ + libglpk_la-glpapi06.lo libglpk_la-glpapi07.lo \ + libglpk_la-glpapi08.lo libglpk_la-glpapi09.lo \ + libglpk_la-glpapi10.lo libglpk_la-glpapi11.lo \ + libglpk_la-glpapi12.lo libglpk_la-glpapi13.lo \ + libglpk_la-glpapi14.lo libglpk_la-glpapi15.lo \ + libglpk_la-glpapi16.lo libglpk_la-glpapi17.lo \ + libglpk_la-glpapi18.lo libglpk_la-glpapi19.lo \ + libglpk_la-glpapi20.lo libglpk_la-glpapi21.lo \ + libglpk_la-glpcpx.lo libglpk_la-glpdmx.lo libglpk_la-glpgmp.lo \ + libglpk_la-glphbm.lo libglpk_la-glpini01.lo \ + libglpk_la-glpini02.lo libglpk_la-glpios01.lo \ + libglpk_la-glpios02.lo libglpk_la-glpios03.lo \ + libglpk_la-glpios04.lo libglpk_la-glpios05.lo \ + libglpk_la-glpios06.lo libglpk_la-glpios07.lo \ + libglpk_la-glpios08.lo libglpk_la-glpios09.lo \ + libglpk_la-glpios10.lo libglpk_la-glpios11.lo \ + libglpk_la-glpios12.lo libglpk_la-glpipm.lo \ + libglpk_la-glpmat.lo libglpk_la-glpmpl01.lo \ + libglpk_la-glpmpl02.lo libglpk_la-glpmpl03.lo \ + libglpk_la-glpmpl04.lo libglpk_la-glpmpl05.lo \ + libglpk_la-glpmpl06.lo libglpk_la-glpmps.lo \ + libglpk_la-glpnet03.lo libglpk_la-glpnet04.lo \ + libglpk_la-glpnet05.lo libglpk_la-glpnpp01.lo \ + libglpk_la-glpnpp02.lo libglpk_la-glpnpp03.lo \ + libglpk_la-glpnpp04.lo libglpk_la-glpnpp05.lo \ + libglpk_la-glpnpp06.lo libglpk_la-glprgr.lo \ + libglpk_la-glpscl.lo libglpk_la-glpsdf.lo libglpk_la-glpspm.lo \ + libglpk_la-glpsql.lo libglpk_la-glpssx01.lo \ + libglpk_la-glpssx02.lo libglpk_la-lux.lo libglpk_la-amd_1.lo \ + libglpk_la-amd_2.lo libglpk_la-amd_aat.lo \ + libglpk_la-amd_control.lo libglpk_la-amd_defaults.lo \ + libglpk_la-amd_dump.lo libglpk_la-amd_info.lo \ + libglpk_la-amd_order.lo libglpk_la-amd_post_tree.lo \ + libglpk_la-amd_postorder.lo libglpk_la-amd_preprocess.lo \ + libglpk_la-amd_valid.lo libglpk_la-btf.lo libglpk_la-btfint.lo \ + libglpk_la-fhv.lo libglpk_la-fhvint.lo libglpk_la-ifu.lo \ + libglpk_la-luf.lo libglpk_la-lufint.lo libglpk_la-scf.lo \ + libglpk_la-scfint.lo libglpk_la-sgf.lo libglpk_la-sva.lo \ + libglpk_la-cfg.lo libglpk_la-cfg1.lo libglpk_la-colamd.lo \ + libglpk_la-alloc.lo libglpk_la-dlsup.lo libglpk_la-env.lo \ + libglpk_la-error.lo libglpk_la-stdout.lo libglpk_la-stream.lo \ + libglpk_la-time.lo libglpk_la-tls.lo libglpk_la-minisat.lo \ + libglpk_la-bignum.lo libglpk_la-dmp.lo libglpk_la-ffalg.lo \ + libglpk_la-fp2rat.lo libglpk_la-gcd.lo libglpk_la-jd.lo \ + libglpk_la-keller.lo libglpk_la-mc13d.lo libglpk_la-mc21a.lo \ + libglpk_la-okalg.lo libglpk_la-qmd.lo libglpk_la-relax4.lo \ + libglpk_la-rng.lo libglpk_la-rng1.lo libglpk_la-round2n.lo \ + libglpk_la-str2int.lo libglpk_la-str2num.lo \ + libglpk_la-strspx.lo libglpk_la-strtrim.lo \ + libglpk_la-triang.lo libglpk_la-wclique.lo \ + libglpk_la-wclique1.lo libglpk_la-proxy.lo \ + libglpk_la-proxy1.lo libglpk_la-spxat.lo \ + libglpk_la-spxchuzc.lo libglpk_la-spxchuzr.lo \ + libglpk_la-spxlp.lo libglpk_la-spxnt.lo libglpk_la-spxprim.lo \ + libglpk_la-spxprob.lo libglpk_la-spychuzc.lo \ + libglpk_la-spychuzr.lo libglpk_la-spydual.lo \ + libglpk_la-adler32.lo libglpk_la-compress.lo \ + libglpk_la-crc32.lo libglpk_la-deflate.lo \ + libglpk_la-gzclose.lo libglpk_la-gzlib.lo libglpk_la-gzread.lo \ + libglpk_la-gzwrite.lo libglpk_la-inffast.lo \ + libglpk_la-inflate.lo libglpk_la-inftrees.lo \ + libglpk_la-trees.lo libglpk_la-uncompr.lo libglpk_la-zio.lo \ + libglpk_la-zutil.lo +libglpk_la_OBJECTS = $(am_libglpk_la_OBJECTS) +libglpk_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libglpk_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libglpk_la_SOURCES) +DIST_SOURCES = $(libglpk_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(include_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +include_HEADERS = glpk.h +lib_LTLIBRARIES = libglpk.la +libglpk_la_CPPFLAGS = \ +-I$(srcdir) \ +-I$(srcdir)/amd \ +-I$(srcdir)/bflib \ +-I$(srcdir)/cglib \ +-I$(srcdir)/colamd \ +-I$(srcdir)/env \ +-I$(srcdir)/minisat \ +-I$(srcdir)/misc \ +-I$(srcdir)/proxy \ +-I$(srcdir)/simplex \ +-I$(srcdir)/zlib + +libglpk_la_LDFLAGS = \ +-version-info 38:0:2 \ +-export-symbols-regex '^glp_*' + +libglpk_la_SOURCES = \ +avl.c \ +bfd.c \ +bfx.c \ +glpapi01.c \ +glpapi02.c \ +glpapi03.c \ +glpapi04.c \ +glpapi05.c \ +glpapi06.c \ +glpapi07.c \ +glpapi08.c \ +glpapi09.c \ +glpapi10.c \ +glpapi11.c \ +glpapi12.c \ +glpapi13.c \ +glpapi14.c \ +glpapi15.c \ +glpapi16.c \ +glpapi17.c \ +glpapi18.c \ +glpapi19.c \ +glpapi20.c \ +glpapi21.c \ +glpcpx.c \ +glpdmx.c \ +glpgmp.c \ +glphbm.c \ +glpini01.c \ +glpini02.c \ +glpios01.c \ +glpios02.c \ +glpios03.c \ +glpios04.c \ +glpios05.c \ +glpios06.c \ +glpios07.c \ +glpios08.c \ +glpios09.c \ +glpios10.c \ +glpios11.c \ +glpios12.c \ +glpipm.c \ +glpmat.c \ +glpmpl01.c \ +glpmpl02.c \ +glpmpl03.c \ +glpmpl04.c \ +glpmpl05.c \ +glpmpl06.c \ +glpmps.c \ +glpnet03.c \ +glpnet04.c \ +glpnet05.c \ +glpnpp01.c \ +glpnpp02.c \ +glpnpp03.c \ +glpnpp04.c \ +glpnpp05.c \ +glpnpp06.c \ +glprgr.c \ +glpscl.c \ +glpsdf.c \ +glpspm.c \ +glpsql.c \ +glpssx01.c \ +glpssx02.c \ +lux.c \ +amd/amd_1.c \ +amd/amd_2.c \ +amd/amd_aat.c \ +amd/amd_control.c \ +amd/amd_defaults.c \ +amd/amd_dump.c \ +amd/amd_info.c \ +amd/amd_order.c \ +amd/amd_post_tree.c \ +amd/amd_postorder.c \ +amd/amd_preprocess.c \ +amd/amd_valid.c \ +bflib/btf.c \ +bflib/btfint.c \ +bflib/fhv.c \ +bflib/fhvint.c \ +bflib/ifu.c \ +bflib/luf.c \ +bflib/lufint.c \ +bflib/scf.c \ +bflib/scfint.c \ +bflib/sgf.c \ +bflib/sva.c \ +cglib/cfg.c \ +cglib/cfg1.c \ +colamd/colamd.c \ +env/alloc.c \ +env/dlsup.c \ +env/env.c \ +env/error.c \ +env/stdout.c \ +env/stream.c \ +env/time.c \ +env/tls.c \ +minisat/minisat.c \ +misc/bignum.c \ +misc/dmp.c \ +misc/ffalg.c \ +misc/fp2rat.c \ +misc/gcd.c \ +misc/jd.c \ +misc/keller.c \ +misc/mc13d.c \ +misc/mc21a.c \ +misc/okalg.c \ +misc/qmd.c \ +misc/relax4.c \ +misc/rng.c \ +misc/rng1.c \ +misc/round2n.c \ +misc/str2int.c \ +misc/str2num.c \ +misc/strspx.c \ +misc/strtrim.c \ +misc/triang.c \ +misc/wclique.c \ +misc/wclique1.c \ +proxy/proxy.c \ +proxy/proxy1.c \ +simplex/spxat.c \ +simplex/spxchuzc.c \ +simplex/spxchuzr.c \ +simplex/spxlp.c \ +simplex/spxnt.c \ +simplex/spxprim.c \ +simplex/spxprob.c \ +simplex/spychuzc.c \ +simplex/spychuzr.c \ +simplex/spydual.c \ +zlib/adler32.c \ +zlib/compress.c \ +zlib/crc32.c \ +zlib/deflate.c \ +zlib/gzclose.c \ +zlib/gzlib.c \ +zlib/gzread.c \ +zlib/gzwrite.c \ +zlib/inffast.c \ +zlib/inflate.c \ +zlib/inftrees.c \ +zlib/trees.c \ +zlib/uncompr.c \ +zlib/zio.c \ +zlib/zutil.c + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +libglpk.la: $(libglpk_la_OBJECTS) $(libglpk_la_DEPENDENCIES) $(EXTRA_libglpk_la_DEPENDENCIES) + $(libglpk_la_LINK) -rpath $(libdir) $(libglpk_la_OBJECTS) $(libglpk_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-adler32.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-alloc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_aat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_control.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_defaults.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_dump.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_info.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_order.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_post_tree.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_postorder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_preprocess.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_valid.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-avl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-bfd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-bfx.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-bignum.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-btf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-btfint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-cfg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-cfg1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-colamd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-compress.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-crc32.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-deflate.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-dlsup.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-dmp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-env.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-error.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-ffalg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-fhv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-fhvint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-fp2rat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-gcd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi01.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi02.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi03.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi04.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi05.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi06.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi07.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi08.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi09.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi10.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi11.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi12.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi13.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi14.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi15.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi16.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi17.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi18.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi19.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi20.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi21.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpcpx.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpdmx.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpgmp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glphbm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpini01.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpini02.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios01.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios02.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios03.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios04.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios05.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios06.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios07.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios08.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios09.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios10.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios11.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios12.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpipm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmpl01.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmpl02.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmpl03.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmpl04.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmpl05.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmpl06.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmps.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnet03.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnet04.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnet05.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnpp01.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnpp02.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnpp03.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnpp04.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnpp05.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnpp06.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glprgr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpscl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpsdf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpspm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpsql.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpssx01.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpssx02.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-gzclose.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-gzlib.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-gzread.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-gzwrite.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-ifu.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-inffast.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-inflate.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-inftrees.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-jd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-keller.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-luf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-lufint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-lux.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-mc13d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-mc21a.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-minisat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-okalg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-proxy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-proxy1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-qmd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-relax4.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-rng.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-rng1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-round2n.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-scf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-scfint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-sgf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-spxat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-spxchuzc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-spxchuzr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-spxlp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-spxnt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-spxprim.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-spxprob.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-spychuzc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-spychuzr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-spydual.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-stdout.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-str2int.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-str2num.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-stream.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-strspx.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-strtrim.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-sva.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-time.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-tls.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-trees.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-triang.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-uncompr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-wclique.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-wclique1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-zio.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-zutil.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libglpk_la-avl.lo: avl.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-avl.lo -MD -MP -MF $(DEPDIR)/libglpk_la-avl.Tpo -c -o libglpk_la-avl.lo `test -f 'avl.c' || echo '$(srcdir)/'`avl.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-avl.Tpo $(DEPDIR)/libglpk_la-avl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='avl.c' object='libglpk_la-avl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-avl.lo `test -f 'avl.c' || echo '$(srcdir)/'`avl.c + +libglpk_la-bfd.lo: bfd.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-bfd.lo -MD -MP -MF $(DEPDIR)/libglpk_la-bfd.Tpo -c -o libglpk_la-bfd.lo `test -f 'bfd.c' || echo '$(srcdir)/'`bfd.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-bfd.Tpo $(DEPDIR)/libglpk_la-bfd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bfd.c' object='libglpk_la-bfd.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-bfd.lo `test -f 'bfd.c' || echo '$(srcdir)/'`bfd.c + +libglpk_la-bfx.lo: bfx.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-bfx.lo -MD -MP -MF $(DEPDIR)/libglpk_la-bfx.Tpo -c -o libglpk_la-bfx.lo `test -f 'bfx.c' || echo '$(srcdir)/'`bfx.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-bfx.Tpo $(DEPDIR)/libglpk_la-bfx.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bfx.c' object='libglpk_la-bfx.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-bfx.lo `test -f 'bfx.c' || echo '$(srcdir)/'`bfx.c + +libglpk_la-glpapi01.lo: glpapi01.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi01.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi01.Tpo -c -o libglpk_la-glpapi01.lo `test -f 'glpapi01.c' || echo '$(srcdir)/'`glpapi01.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi01.Tpo $(DEPDIR)/libglpk_la-glpapi01.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi01.c' object='libglpk_la-glpapi01.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi01.lo `test -f 'glpapi01.c' || echo '$(srcdir)/'`glpapi01.c + +libglpk_la-glpapi02.lo: glpapi02.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi02.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi02.Tpo -c -o libglpk_la-glpapi02.lo `test -f 'glpapi02.c' || echo '$(srcdir)/'`glpapi02.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi02.Tpo $(DEPDIR)/libglpk_la-glpapi02.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi02.c' object='libglpk_la-glpapi02.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi02.lo `test -f 'glpapi02.c' || echo '$(srcdir)/'`glpapi02.c + +libglpk_la-glpapi03.lo: glpapi03.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi03.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi03.Tpo -c -o libglpk_la-glpapi03.lo `test -f 'glpapi03.c' || echo '$(srcdir)/'`glpapi03.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi03.Tpo $(DEPDIR)/libglpk_la-glpapi03.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi03.c' object='libglpk_la-glpapi03.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi03.lo `test -f 'glpapi03.c' || echo '$(srcdir)/'`glpapi03.c + +libglpk_la-glpapi04.lo: glpapi04.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi04.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi04.Tpo -c -o libglpk_la-glpapi04.lo `test -f 'glpapi04.c' || echo '$(srcdir)/'`glpapi04.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi04.Tpo $(DEPDIR)/libglpk_la-glpapi04.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi04.c' object='libglpk_la-glpapi04.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi04.lo `test -f 'glpapi04.c' || echo '$(srcdir)/'`glpapi04.c + +libglpk_la-glpapi05.lo: glpapi05.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi05.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi05.Tpo -c -o libglpk_la-glpapi05.lo `test -f 'glpapi05.c' || echo '$(srcdir)/'`glpapi05.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi05.Tpo $(DEPDIR)/libglpk_la-glpapi05.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi05.c' object='libglpk_la-glpapi05.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi05.lo `test -f 'glpapi05.c' || echo '$(srcdir)/'`glpapi05.c + +libglpk_la-glpapi06.lo: glpapi06.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi06.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi06.Tpo -c -o libglpk_la-glpapi06.lo `test -f 'glpapi06.c' || echo '$(srcdir)/'`glpapi06.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi06.Tpo $(DEPDIR)/libglpk_la-glpapi06.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi06.c' object='libglpk_la-glpapi06.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi06.lo `test -f 'glpapi06.c' || echo '$(srcdir)/'`glpapi06.c + +libglpk_la-glpapi07.lo: glpapi07.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi07.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi07.Tpo -c -o libglpk_la-glpapi07.lo `test -f 'glpapi07.c' || echo '$(srcdir)/'`glpapi07.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi07.Tpo $(DEPDIR)/libglpk_la-glpapi07.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi07.c' object='libglpk_la-glpapi07.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi07.lo `test -f 'glpapi07.c' || echo '$(srcdir)/'`glpapi07.c + +libglpk_la-glpapi08.lo: glpapi08.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi08.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi08.Tpo -c -o libglpk_la-glpapi08.lo `test -f 'glpapi08.c' || echo '$(srcdir)/'`glpapi08.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi08.Tpo $(DEPDIR)/libglpk_la-glpapi08.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi08.c' object='libglpk_la-glpapi08.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi08.lo `test -f 'glpapi08.c' || echo '$(srcdir)/'`glpapi08.c + +libglpk_la-glpapi09.lo: glpapi09.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi09.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi09.Tpo -c -o libglpk_la-glpapi09.lo `test -f 'glpapi09.c' || echo '$(srcdir)/'`glpapi09.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi09.Tpo $(DEPDIR)/libglpk_la-glpapi09.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi09.c' object='libglpk_la-glpapi09.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi09.lo `test -f 'glpapi09.c' || echo '$(srcdir)/'`glpapi09.c + +libglpk_la-glpapi10.lo: glpapi10.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi10.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi10.Tpo -c -o libglpk_la-glpapi10.lo `test -f 'glpapi10.c' || echo '$(srcdir)/'`glpapi10.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi10.Tpo $(DEPDIR)/libglpk_la-glpapi10.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi10.c' object='libglpk_la-glpapi10.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi10.lo `test -f 'glpapi10.c' || echo '$(srcdir)/'`glpapi10.c + +libglpk_la-glpapi11.lo: glpapi11.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi11.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi11.Tpo -c -o libglpk_la-glpapi11.lo `test -f 'glpapi11.c' || echo '$(srcdir)/'`glpapi11.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi11.Tpo $(DEPDIR)/libglpk_la-glpapi11.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi11.c' object='libglpk_la-glpapi11.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi11.lo `test -f 'glpapi11.c' || echo '$(srcdir)/'`glpapi11.c + +libglpk_la-glpapi12.lo: glpapi12.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi12.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi12.Tpo -c -o libglpk_la-glpapi12.lo `test -f 'glpapi12.c' || echo '$(srcdir)/'`glpapi12.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi12.Tpo $(DEPDIR)/libglpk_la-glpapi12.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi12.c' object='libglpk_la-glpapi12.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi12.lo `test -f 'glpapi12.c' || echo '$(srcdir)/'`glpapi12.c + +libglpk_la-glpapi13.lo: glpapi13.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi13.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi13.Tpo -c -o libglpk_la-glpapi13.lo `test -f 'glpapi13.c' || echo '$(srcdir)/'`glpapi13.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi13.Tpo $(DEPDIR)/libglpk_la-glpapi13.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi13.c' object='libglpk_la-glpapi13.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi13.lo `test -f 'glpapi13.c' || echo '$(srcdir)/'`glpapi13.c + +libglpk_la-glpapi14.lo: glpapi14.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi14.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi14.Tpo -c -o libglpk_la-glpapi14.lo `test -f 'glpapi14.c' || echo '$(srcdir)/'`glpapi14.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi14.Tpo $(DEPDIR)/libglpk_la-glpapi14.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi14.c' object='libglpk_la-glpapi14.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi14.lo `test -f 'glpapi14.c' || echo '$(srcdir)/'`glpapi14.c + +libglpk_la-glpapi15.lo: glpapi15.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi15.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi15.Tpo -c -o libglpk_la-glpapi15.lo `test -f 'glpapi15.c' || echo '$(srcdir)/'`glpapi15.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi15.Tpo $(DEPDIR)/libglpk_la-glpapi15.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi15.c' object='libglpk_la-glpapi15.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi15.lo `test -f 'glpapi15.c' || echo '$(srcdir)/'`glpapi15.c + +libglpk_la-glpapi16.lo: glpapi16.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi16.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi16.Tpo -c -o libglpk_la-glpapi16.lo `test -f 'glpapi16.c' || echo '$(srcdir)/'`glpapi16.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi16.Tpo $(DEPDIR)/libglpk_la-glpapi16.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi16.c' object='libglpk_la-glpapi16.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi16.lo `test -f 'glpapi16.c' || echo '$(srcdir)/'`glpapi16.c + +libglpk_la-glpapi17.lo: glpapi17.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi17.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi17.Tpo -c -o libglpk_la-glpapi17.lo `test -f 'glpapi17.c' || echo '$(srcdir)/'`glpapi17.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi17.Tpo $(DEPDIR)/libglpk_la-glpapi17.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi17.c' object='libglpk_la-glpapi17.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi17.lo `test -f 'glpapi17.c' || echo '$(srcdir)/'`glpapi17.c + +libglpk_la-glpapi18.lo: glpapi18.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi18.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi18.Tpo -c -o libglpk_la-glpapi18.lo `test -f 'glpapi18.c' || echo '$(srcdir)/'`glpapi18.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi18.Tpo $(DEPDIR)/libglpk_la-glpapi18.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi18.c' object='libglpk_la-glpapi18.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi18.lo `test -f 'glpapi18.c' || echo '$(srcdir)/'`glpapi18.c + +libglpk_la-glpapi19.lo: glpapi19.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi19.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi19.Tpo -c -o libglpk_la-glpapi19.lo `test -f 'glpapi19.c' || echo '$(srcdir)/'`glpapi19.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi19.Tpo $(DEPDIR)/libglpk_la-glpapi19.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi19.c' object='libglpk_la-glpapi19.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi19.lo `test -f 'glpapi19.c' || echo '$(srcdir)/'`glpapi19.c + +libglpk_la-glpapi20.lo: glpapi20.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi20.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi20.Tpo -c -o libglpk_la-glpapi20.lo `test -f 'glpapi20.c' || echo '$(srcdir)/'`glpapi20.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi20.Tpo $(DEPDIR)/libglpk_la-glpapi20.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi20.c' object='libglpk_la-glpapi20.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi20.lo `test -f 'glpapi20.c' || echo '$(srcdir)/'`glpapi20.c + +libglpk_la-glpapi21.lo: glpapi21.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi21.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi21.Tpo -c -o libglpk_la-glpapi21.lo `test -f 'glpapi21.c' || echo '$(srcdir)/'`glpapi21.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi21.Tpo $(DEPDIR)/libglpk_la-glpapi21.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi21.c' object='libglpk_la-glpapi21.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi21.lo `test -f 'glpapi21.c' || echo '$(srcdir)/'`glpapi21.c + +libglpk_la-glpcpx.lo: glpcpx.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpcpx.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpcpx.Tpo -c -o libglpk_la-glpcpx.lo `test -f 'glpcpx.c' || echo '$(srcdir)/'`glpcpx.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpcpx.Tpo $(DEPDIR)/libglpk_la-glpcpx.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpcpx.c' object='libglpk_la-glpcpx.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpcpx.lo `test -f 'glpcpx.c' || echo '$(srcdir)/'`glpcpx.c + +libglpk_la-glpdmx.lo: glpdmx.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpdmx.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpdmx.Tpo -c -o libglpk_la-glpdmx.lo `test -f 'glpdmx.c' || echo '$(srcdir)/'`glpdmx.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpdmx.Tpo $(DEPDIR)/libglpk_la-glpdmx.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpdmx.c' object='libglpk_la-glpdmx.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpdmx.lo `test -f 'glpdmx.c' || echo '$(srcdir)/'`glpdmx.c + +libglpk_la-glpgmp.lo: glpgmp.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpgmp.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpgmp.Tpo -c -o libglpk_la-glpgmp.lo `test -f 'glpgmp.c' || echo '$(srcdir)/'`glpgmp.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpgmp.Tpo $(DEPDIR)/libglpk_la-glpgmp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpgmp.c' object='libglpk_la-glpgmp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpgmp.lo `test -f 'glpgmp.c' || echo '$(srcdir)/'`glpgmp.c + +libglpk_la-glphbm.lo: glphbm.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glphbm.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glphbm.Tpo -c -o libglpk_la-glphbm.lo `test -f 'glphbm.c' || echo '$(srcdir)/'`glphbm.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glphbm.Tpo $(DEPDIR)/libglpk_la-glphbm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glphbm.c' object='libglpk_la-glphbm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glphbm.lo `test -f 'glphbm.c' || echo '$(srcdir)/'`glphbm.c + +libglpk_la-glpini01.lo: glpini01.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpini01.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpini01.Tpo -c -o libglpk_la-glpini01.lo `test -f 'glpini01.c' || echo '$(srcdir)/'`glpini01.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpini01.Tpo $(DEPDIR)/libglpk_la-glpini01.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpini01.c' object='libglpk_la-glpini01.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpini01.lo `test -f 'glpini01.c' || echo '$(srcdir)/'`glpini01.c + +libglpk_la-glpini02.lo: glpini02.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpini02.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpini02.Tpo -c -o libglpk_la-glpini02.lo `test -f 'glpini02.c' || echo '$(srcdir)/'`glpini02.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpini02.Tpo $(DEPDIR)/libglpk_la-glpini02.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpini02.c' object='libglpk_la-glpini02.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpini02.lo `test -f 'glpini02.c' || echo '$(srcdir)/'`glpini02.c + +libglpk_la-glpios01.lo: glpios01.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios01.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios01.Tpo -c -o libglpk_la-glpios01.lo `test -f 'glpios01.c' || echo '$(srcdir)/'`glpios01.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios01.Tpo $(DEPDIR)/libglpk_la-glpios01.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios01.c' object='libglpk_la-glpios01.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios01.lo `test -f 'glpios01.c' || echo '$(srcdir)/'`glpios01.c + +libglpk_la-glpios02.lo: glpios02.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios02.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios02.Tpo -c -o libglpk_la-glpios02.lo `test -f 'glpios02.c' || echo '$(srcdir)/'`glpios02.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios02.Tpo $(DEPDIR)/libglpk_la-glpios02.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios02.c' object='libglpk_la-glpios02.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios02.lo `test -f 'glpios02.c' || echo '$(srcdir)/'`glpios02.c + +libglpk_la-glpios03.lo: glpios03.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios03.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios03.Tpo -c -o libglpk_la-glpios03.lo `test -f 'glpios03.c' || echo '$(srcdir)/'`glpios03.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios03.Tpo $(DEPDIR)/libglpk_la-glpios03.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios03.c' object='libglpk_la-glpios03.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios03.lo `test -f 'glpios03.c' || echo '$(srcdir)/'`glpios03.c + +libglpk_la-glpios04.lo: glpios04.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios04.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios04.Tpo -c -o libglpk_la-glpios04.lo `test -f 'glpios04.c' || echo '$(srcdir)/'`glpios04.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios04.Tpo $(DEPDIR)/libglpk_la-glpios04.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios04.c' object='libglpk_la-glpios04.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios04.lo `test -f 'glpios04.c' || echo '$(srcdir)/'`glpios04.c + +libglpk_la-glpios05.lo: glpios05.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios05.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios05.Tpo -c -o libglpk_la-glpios05.lo `test -f 'glpios05.c' || echo '$(srcdir)/'`glpios05.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios05.Tpo $(DEPDIR)/libglpk_la-glpios05.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios05.c' object='libglpk_la-glpios05.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios05.lo `test -f 'glpios05.c' || echo '$(srcdir)/'`glpios05.c + +libglpk_la-glpios06.lo: glpios06.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios06.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios06.Tpo -c -o libglpk_la-glpios06.lo `test -f 'glpios06.c' || echo '$(srcdir)/'`glpios06.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios06.Tpo $(DEPDIR)/libglpk_la-glpios06.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios06.c' object='libglpk_la-glpios06.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios06.lo `test -f 'glpios06.c' || echo '$(srcdir)/'`glpios06.c + +libglpk_la-glpios07.lo: glpios07.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios07.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios07.Tpo -c -o libglpk_la-glpios07.lo `test -f 'glpios07.c' || echo '$(srcdir)/'`glpios07.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios07.Tpo $(DEPDIR)/libglpk_la-glpios07.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios07.c' object='libglpk_la-glpios07.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios07.lo `test -f 'glpios07.c' || echo '$(srcdir)/'`glpios07.c + +libglpk_la-glpios08.lo: glpios08.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios08.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios08.Tpo -c -o libglpk_la-glpios08.lo `test -f 'glpios08.c' || echo '$(srcdir)/'`glpios08.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios08.Tpo $(DEPDIR)/libglpk_la-glpios08.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios08.c' object='libglpk_la-glpios08.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios08.lo `test -f 'glpios08.c' || echo '$(srcdir)/'`glpios08.c + +libglpk_la-glpios09.lo: glpios09.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios09.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios09.Tpo -c -o libglpk_la-glpios09.lo `test -f 'glpios09.c' || echo '$(srcdir)/'`glpios09.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios09.Tpo $(DEPDIR)/libglpk_la-glpios09.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios09.c' object='libglpk_la-glpios09.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios09.lo `test -f 'glpios09.c' || echo '$(srcdir)/'`glpios09.c + +libglpk_la-glpios10.lo: glpios10.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios10.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios10.Tpo -c -o libglpk_la-glpios10.lo `test -f 'glpios10.c' || echo '$(srcdir)/'`glpios10.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios10.Tpo $(DEPDIR)/libglpk_la-glpios10.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios10.c' object='libglpk_la-glpios10.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios10.lo `test -f 'glpios10.c' || echo '$(srcdir)/'`glpios10.c + +libglpk_la-glpios11.lo: glpios11.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios11.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios11.Tpo -c -o libglpk_la-glpios11.lo `test -f 'glpios11.c' || echo '$(srcdir)/'`glpios11.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios11.Tpo $(DEPDIR)/libglpk_la-glpios11.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios11.c' object='libglpk_la-glpios11.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios11.lo `test -f 'glpios11.c' || echo '$(srcdir)/'`glpios11.c + +libglpk_la-glpios12.lo: glpios12.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios12.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios12.Tpo -c -o libglpk_la-glpios12.lo `test -f 'glpios12.c' || echo '$(srcdir)/'`glpios12.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios12.Tpo $(DEPDIR)/libglpk_la-glpios12.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios12.c' object='libglpk_la-glpios12.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios12.lo `test -f 'glpios12.c' || echo '$(srcdir)/'`glpios12.c + +libglpk_la-glpipm.lo: glpipm.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpipm.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpipm.Tpo -c -o libglpk_la-glpipm.lo `test -f 'glpipm.c' || echo '$(srcdir)/'`glpipm.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpipm.Tpo $(DEPDIR)/libglpk_la-glpipm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpipm.c' object='libglpk_la-glpipm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpipm.lo `test -f 'glpipm.c' || echo '$(srcdir)/'`glpipm.c + +libglpk_la-glpmat.lo: glpmat.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmat.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmat.Tpo -c -o libglpk_la-glpmat.lo `test -f 'glpmat.c' || echo '$(srcdir)/'`glpmat.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmat.Tpo $(DEPDIR)/libglpk_la-glpmat.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmat.c' object='libglpk_la-glpmat.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmat.lo `test -f 'glpmat.c' || echo '$(srcdir)/'`glpmat.c + +libglpk_la-glpmpl01.lo: glpmpl01.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmpl01.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmpl01.Tpo -c -o libglpk_la-glpmpl01.lo `test -f 'glpmpl01.c' || echo '$(srcdir)/'`glpmpl01.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmpl01.Tpo $(DEPDIR)/libglpk_la-glpmpl01.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmpl01.c' object='libglpk_la-glpmpl01.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmpl01.lo `test -f 'glpmpl01.c' || echo '$(srcdir)/'`glpmpl01.c + +libglpk_la-glpmpl02.lo: glpmpl02.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmpl02.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmpl02.Tpo -c -o libglpk_la-glpmpl02.lo `test -f 'glpmpl02.c' || echo '$(srcdir)/'`glpmpl02.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmpl02.Tpo $(DEPDIR)/libglpk_la-glpmpl02.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmpl02.c' object='libglpk_la-glpmpl02.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmpl02.lo `test -f 'glpmpl02.c' || echo '$(srcdir)/'`glpmpl02.c + +libglpk_la-glpmpl03.lo: glpmpl03.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmpl03.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmpl03.Tpo -c -o libglpk_la-glpmpl03.lo `test -f 'glpmpl03.c' || echo '$(srcdir)/'`glpmpl03.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmpl03.Tpo $(DEPDIR)/libglpk_la-glpmpl03.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmpl03.c' object='libglpk_la-glpmpl03.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmpl03.lo `test -f 'glpmpl03.c' || echo '$(srcdir)/'`glpmpl03.c + +libglpk_la-glpmpl04.lo: glpmpl04.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmpl04.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmpl04.Tpo -c -o libglpk_la-glpmpl04.lo `test -f 'glpmpl04.c' || echo '$(srcdir)/'`glpmpl04.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmpl04.Tpo $(DEPDIR)/libglpk_la-glpmpl04.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmpl04.c' object='libglpk_la-glpmpl04.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmpl04.lo `test -f 'glpmpl04.c' || echo '$(srcdir)/'`glpmpl04.c + +libglpk_la-glpmpl05.lo: glpmpl05.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmpl05.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmpl05.Tpo -c -o libglpk_la-glpmpl05.lo `test -f 'glpmpl05.c' || echo '$(srcdir)/'`glpmpl05.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmpl05.Tpo $(DEPDIR)/libglpk_la-glpmpl05.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmpl05.c' object='libglpk_la-glpmpl05.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmpl05.lo `test -f 'glpmpl05.c' || echo '$(srcdir)/'`glpmpl05.c + +libglpk_la-glpmpl06.lo: glpmpl06.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmpl06.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmpl06.Tpo -c -o libglpk_la-glpmpl06.lo `test -f 'glpmpl06.c' || echo '$(srcdir)/'`glpmpl06.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmpl06.Tpo $(DEPDIR)/libglpk_la-glpmpl06.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmpl06.c' object='libglpk_la-glpmpl06.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmpl06.lo `test -f 'glpmpl06.c' || echo '$(srcdir)/'`glpmpl06.c + +libglpk_la-glpmps.lo: glpmps.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmps.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmps.Tpo -c -o libglpk_la-glpmps.lo `test -f 'glpmps.c' || echo '$(srcdir)/'`glpmps.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmps.Tpo $(DEPDIR)/libglpk_la-glpmps.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmps.c' object='libglpk_la-glpmps.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmps.lo `test -f 'glpmps.c' || echo '$(srcdir)/'`glpmps.c + +libglpk_la-glpnet03.lo: glpnet03.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnet03.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnet03.Tpo -c -o libglpk_la-glpnet03.lo `test -f 'glpnet03.c' || echo '$(srcdir)/'`glpnet03.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnet03.Tpo $(DEPDIR)/libglpk_la-glpnet03.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnet03.c' object='libglpk_la-glpnet03.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnet03.lo `test -f 'glpnet03.c' || echo '$(srcdir)/'`glpnet03.c + +libglpk_la-glpnet04.lo: glpnet04.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnet04.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnet04.Tpo -c -o libglpk_la-glpnet04.lo `test -f 'glpnet04.c' || echo '$(srcdir)/'`glpnet04.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnet04.Tpo $(DEPDIR)/libglpk_la-glpnet04.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnet04.c' object='libglpk_la-glpnet04.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnet04.lo `test -f 'glpnet04.c' || echo '$(srcdir)/'`glpnet04.c + +libglpk_la-glpnet05.lo: glpnet05.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnet05.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnet05.Tpo -c -o libglpk_la-glpnet05.lo `test -f 'glpnet05.c' || echo '$(srcdir)/'`glpnet05.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnet05.Tpo $(DEPDIR)/libglpk_la-glpnet05.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnet05.c' object='libglpk_la-glpnet05.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnet05.lo `test -f 'glpnet05.c' || echo '$(srcdir)/'`glpnet05.c + +libglpk_la-glpnpp01.lo: glpnpp01.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnpp01.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnpp01.Tpo -c -o libglpk_la-glpnpp01.lo `test -f 'glpnpp01.c' || echo '$(srcdir)/'`glpnpp01.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnpp01.Tpo $(DEPDIR)/libglpk_la-glpnpp01.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnpp01.c' object='libglpk_la-glpnpp01.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnpp01.lo `test -f 'glpnpp01.c' || echo '$(srcdir)/'`glpnpp01.c + +libglpk_la-glpnpp02.lo: glpnpp02.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnpp02.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnpp02.Tpo -c -o libglpk_la-glpnpp02.lo `test -f 'glpnpp02.c' || echo '$(srcdir)/'`glpnpp02.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnpp02.Tpo $(DEPDIR)/libglpk_la-glpnpp02.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnpp02.c' object='libglpk_la-glpnpp02.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnpp02.lo `test -f 'glpnpp02.c' || echo '$(srcdir)/'`glpnpp02.c + +libglpk_la-glpnpp03.lo: glpnpp03.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnpp03.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnpp03.Tpo -c -o libglpk_la-glpnpp03.lo `test -f 'glpnpp03.c' || echo '$(srcdir)/'`glpnpp03.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnpp03.Tpo $(DEPDIR)/libglpk_la-glpnpp03.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnpp03.c' object='libglpk_la-glpnpp03.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnpp03.lo `test -f 'glpnpp03.c' || echo '$(srcdir)/'`glpnpp03.c + +libglpk_la-glpnpp04.lo: glpnpp04.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnpp04.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnpp04.Tpo -c -o libglpk_la-glpnpp04.lo `test -f 'glpnpp04.c' || echo '$(srcdir)/'`glpnpp04.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnpp04.Tpo $(DEPDIR)/libglpk_la-glpnpp04.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnpp04.c' object='libglpk_la-glpnpp04.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnpp04.lo `test -f 'glpnpp04.c' || echo '$(srcdir)/'`glpnpp04.c + +libglpk_la-glpnpp05.lo: glpnpp05.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnpp05.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnpp05.Tpo -c -o libglpk_la-glpnpp05.lo `test -f 'glpnpp05.c' || echo '$(srcdir)/'`glpnpp05.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnpp05.Tpo $(DEPDIR)/libglpk_la-glpnpp05.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnpp05.c' object='libglpk_la-glpnpp05.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnpp05.lo `test -f 'glpnpp05.c' || echo '$(srcdir)/'`glpnpp05.c + +libglpk_la-glpnpp06.lo: glpnpp06.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnpp06.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnpp06.Tpo -c -o libglpk_la-glpnpp06.lo `test -f 'glpnpp06.c' || echo '$(srcdir)/'`glpnpp06.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnpp06.Tpo $(DEPDIR)/libglpk_la-glpnpp06.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnpp06.c' object='libglpk_la-glpnpp06.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnpp06.lo `test -f 'glpnpp06.c' || echo '$(srcdir)/'`glpnpp06.c + +libglpk_la-glprgr.lo: glprgr.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glprgr.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glprgr.Tpo -c -o libglpk_la-glprgr.lo `test -f 'glprgr.c' || echo '$(srcdir)/'`glprgr.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glprgr.Tpo $(DEPDIR)/libglpk_la-glprgr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glprgr.c' object='libglpk_la-glprgr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glprgr.lo `test -f 'glprgr.c' || echo '$(srcdir)/'`glprgr.c + +libglpk_la-glpscl.lo: glpscl.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpscl.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpscl.Tpo -c -o libglpk_la-glpscl.lo `test -f 'glpscl.c' || echo '$(srcdir)/'`glpscl.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpscl.Tpo $(DEPDIR)/libglpk_la-glpscl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpscl.c' object='libglpk_la-glpscl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpscl.lo `test -f 'glpscl.c' || echo '$(srcdir)/'`glpscl.c + +libglpk_la-glpsdf.lo: glpsdf.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpsdf.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpsdf.Tpo -c -o libglpk_la-glpsdf.lo `test -f 'glpsdf.c' || echo '$(srcdir)/'`glpsdf.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpsdf.Tpo $(DEPDIR)/libglpk_la-glpsdf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpsdf.c' object='libglpk_la-glpsdf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpsdf.lo `test -f 'glpsdf.c' || echo '$(srcdir)/'`glpsdf.c + +libglpk_la-glpspm.lo: glpspm.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpspm.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpspm.Tpo -c -o libglpk_la-glpspm.lo `test -f 'glpspm.c' || echo '$(srcdir)/'`glpspm.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpspm.Tpo $(DEPDIR)/libglpk_la-glpspm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpspm.c' object='libglpk_la-glpspm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpspm.lo `test -f 'glpspm.c' || echo '$(srcdir)/'`glpspm.c + +libglpk_la-glpsql.lo: glpsql.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpsql.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpsql.Tpo -c -o libglpk_la-glpsql.lo `test -f 'glpsql.c' || echo '$(srcdir)/'`glpsql.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpsql.Tpo $(DEPDIR)/libglpk_la-glpsql.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpsql.c' object='libglpk_la-glpsql.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpsql.lo `test -f 'glpsql.c' || echo '$(srcdir)/'`glpsql.c + +libglpk_la-glpssx01.lo: glpssx01.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpssx01.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpssx01.Tpo -c -o libglpk_la-glpssx01.lo `test -f 'glpssx01.c' || echo '$(srcdir)/'`glpssx01.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpssx01.Tpo $(DEPDIR)/libglpk_la-glpssx01.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpssx01.c' object='libglpk_la-glpssx01.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpssx01.lo `test -f 'glpssx01.c' || echo '$(srcdir)/'`glpssx01.c + +libglpk_la-glpssx02.lo: glpssx02.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpssx02.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpssx02.Tpo -c -o libglpk_la-glpssx02.lo `test -f 'glpssx02.c' || echo '$(srcdir)/'`glpssx02.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpssx02.Tpo $(DEPDIR)/libglpk_la-glpssx02.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpssx02.c' object='libglpk_la-glpssx02.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpssx02.lo `test -f 'glpssx02.c' || echo '$(srcdir)/'`glpssx02.c + +libglpk_la-lux.lo: lux.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-lux.lo -MD -MP -MF $(DEPDIR)/libglpk_la-lux.Tpo -c -o libglpk_la-lux.lo `test -f 'lux.c' || echo '$(srcdir)/'`lux.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-lux.Tpo $(DEPDIR)/libglpk_la-lux.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lux.c' object='libglpk_la-lux.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-lux.lo `test -f 'lux.c' || echo '$(srcdir)/'`lux.c + +libglpk_la-amd_1.lo: amd/amd_1.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_1.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_1.Tpo -c -o libglpk_la-amd_1.lo `test -f 'amd/amd_1.c' || echo '$(srcdir)/'`amd/amd_1.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_1.Tpo $(DEPDIR)/libglpk_la-amd_1.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_1.c' object='libglpk_la-amd_1.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_1.lo `test -f 'amd/amd_1.c' || echo '$(srcdir)/'`amd/amd_1.c + +libglpk_la-amd_2.lo: amd/amd_2.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_2.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_2.Tpo -c -o libglpk_la-amd_2.lo `test -f 'amd/amd_2.c' || echo '$(srcdir)/'`amd/amd_2.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_2.Tpo $(DEPDIR)/libglpk_la-amd_2.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_2.c' object='libglpk_la-amd_2.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_2.lo `test -f 'amd/amd_2.c' || echo '$(srcdir)/'`amd/amd_2.c + +libglpk_la-amd_aat.lo: amd/amd_aat.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_aat.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_aat.Tpo -c -o libglpk_la-amd_aat.lo `test -f 'amd/amd_aat.c' || echo '$(srcdir)/'`amd/amd_aat.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_aat.Tpo $(DEPDIR)/libglpk_la-amd_aat.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_aat.c' object='libglpk_la-amd_aat.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_aat.lo `test -f 'amd/amd_aat.c' || echo '$(srcdir)/'`amd/amd_aat.c + +libglpk_la-amd_control.lo: amd/amd_control.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_control.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_control.Tpo -c -o libglpk_la-amd_control.lo `test -f 'amd/amd_control.c' || echo '$(srcdir)/'`amd/amd_control.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_control.Tpo $(DEPDIR)/libglpk_la-amd_control.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_control.c' object='libglpk_la-amd_control.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_control.lo `test -f 'amd/amd_control.c' || echo '$(srcdir)/'`amd/amd_control.c + +libglpk_la-amd_defaults.lo: amd/amd_defaults.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_defaults.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_defaults.Tpo -c -o libglpk_la-amd_defaults.lo `test -f 'amd/amd_defaults.c' || echo '$(srcdir)/'`amd/amd_defaults.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_defaults.Tpo $(DEPDIR)/libglpk_la-amd_defaults.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_defaults.c' object='libglpk_la-amd_defaults.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_defaults.lo `test -f 'amd/amd_defaults.c' || echo '$(srcdir)/'`amd/amd_defaults.c + +libglpk_la-amd_dump.lo: amd/amd_dump.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_dump.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_dump.Tpo -c -o libglpk_la-amd_dump.lo `test -f 'amd/amd_dump.c' || echo '$(srcdir)/'`amd/amd_dump.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_dump.Tpo $(DEPDIR)/libglpk_la-amd_dump.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_dump.c' object='libglpk_la-amd_dump.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_dump.lo `test -f 'amd/amd_dump.c' || echo '$(srcdir)/'`amd/amd_dump.c + +libglpk_la-amd_info.lo: amd/amd_info.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_info.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_info.Tpo -c -o libglpk_la-amd_info.lo `test -f 'amd/amd_info.c' || echo '$(srcdir)/'`amd/amd_info.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_info.Tpo $(DEPDIR)/libglpk_la-amd_info.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_info.c' object='libglpk_la-amd_info.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_info.lo `test -f 'amd/amd_info.c' || echo '$(srcdir)/'`amd/amd_info.c + +libglpk_la-amd_order.lo: amd/amd_order.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_order.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_order.Tpo -c -o libglpk_la-amd_order.lo `test -f 'amd/amd_order.c' || echo '$(srcdir)/'`amd/amd_order.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_order.Tpo $(DEPDIR)/libglpk_la-amd_order.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_order.c' object='libglpk_la-amd_order.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_order.lo `test -f 'amd/amd_order.c' || echo '$(srcdir)/'`amd/amd_order.c + +libglpk_la-amd_post_tree.lo: amd/amd_post_tree.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_post_tree.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_post_tree.Tpo -c -o libglpk_la-amd_post_tree.lo `test -f 'amd/amd_post_tree.c' || echo '$(srcdir)/'`amd/amd_post_tree.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_post_tree.Tpo $(DEPDIR)/libglpk_la-amd_post_tree.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_post_tree.c' object='libglpk_la-amd_post_tree.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_post_tree.lo `test -f 'amd/amd_post_tree.c' || echo '$(srcdir)/'`amd/amd_post_tree.c + +libglpk_la-amd_postorder.lo: amd/amd_postorder.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_postorder.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_postorder.Tpo -c -o libglpk_la-amd_postorder.lo `test -f 'amd/amd_postorder.c' || echo '$(srcdir)/'`amd/amd_postorder.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_postorder.Tpo $(DEPDIR)/libglpk_la-amd_postorder.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_postorder.c' object='libglpk_la-amd_postorder.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_postorder.lo `test -f 'amd/amd_postorder.c' || echo '$(srcdir)/'`amd/amd_postorder.c + +libglpk_la-amd_preprocess.lo: amd/amd_preprocess.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_preprocess.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_preprocess.Tpo -c -o libglpk_la-amd_preprocess.lo `test -f 'amd/amd_preprocess.c' || echo '$(srcdir)/'`amd/amd_preprocess.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_preprocess.Tpo $(DEPDIR)/libglpk_la-amd_preprocess.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_preprocess.c' object='libglpk_la-amd_preprocess.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_preprocess.lo `test -f 'amd/amd_preprocess.c' || echo '$(srcdir)/'`amd/amd_preprocess.c + +libglpk_la-amd_valid.lo: amd/amd_valid.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_valid.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_valid.Tpo -c -o libglpk_la-amd_valid.lo `test -f 'amd/amd_valid.c' || echo '$(srcdir)/'`amd/amd_valid.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_valid.Tpo $(DEPDIR)/libglpk_la-amd_valid.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_valid.c' object='libglpk_la-amd_valid.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_valid.lo `test -f 'amd/amd_valid.c' || echo '$(srcdir)/'`amd/amd_valid.c + +libglpk_la-btf.lo: bflib/btf.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-btf.lo -MD -MP -MF $(DEPDIR)/libglpk_la-btf.Tpo -c -o libglpk_la-btf.lo `test -f 'bflib/btf.c' || echo '$(srcdir)/'`bflib/btf.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-btf.Tpo $(DEPDIR)/libglpk_la-btf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/btf.c' object='libglpk_la-btf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-btf.lo `test -f 'bflib/btf.c' || echo '$(srcdir)/'`bflib/btf.c + +libglpk_la-btfint.lo: bflib/btfint.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-btfint.lo -MD -MP -MF $(DEPDIR)/libglpk_la-btfint.Tpo -c -o libglpk_la-btfint.lo `test -f 'bflib/btfint.c' || echo '$(srcdir)/'`bflib/btfint.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-btfint.Tpo $(DEPDIR)/libglpk_la-btfint.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/btfint.c' object='libglpk_la-btfint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-btfint.lo `test -f 'bflib/btfint.c' || echo '$(srcdir)/'`bflib/btfint.c + +libglpk_la-fhv.lo: bflib/fhv.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-fhv.lo -MD -MP -MF $(DEPDIR)/libglpk_la-fhv.Tpo -c -o libglpk_la-fhv.lo `test -f 'bflib/fhv.c' || echo '$(srcdir)/'`bflib/fhv.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-fhv.Tpo $(DEPDIR)/libglpk_la-fhv.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/fhv.c' object='libglpk_la-fhv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-fhv.lo `test -f 'bflib/fhv.c' || echo '$(srcdir)/'`bflib/fhv.c + +libglpk_la-fhvint.lo: bflib/fhvint.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-fhvint.lo -MD -MP -MF $(DEPDIR)/libglpk_la-fhvint.Tpo -c -o libglpk_la-fhvint.lo `test -f 'bflib/fhvint.c' || echo '$(srcdir)/'`bflib/fhvint.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-fhvint.Tpo $(DEPDIR)/libglpk_la-fhvint.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/fhvint.c' object='libglpk_la-fhvint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-fhvint.lo `test -f 'bflib/fhvint.c' || echo '$(srcdir)/'`bflib/fhvint.c + +libglpk_la-ifu.lo: bflib/ifu.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-ifu.lo -MD -MP -MF $(DEPDIR)/libglpk_la-ifu.Tpo -c -o libglpk_la-ifu.lo `test -f 'bflib/ifu.c' || echo '$(srcdir)/'`bflib/ifu.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-ifu.Tpo $(DEPDIR)/libglpk_la-ifu.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/ifu.c' object='libglpk_la-ifu.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-ifu.lo `test -f 'bflib/ifu.c' || echo '$(srcdir)/'`bflib/ifu.c + +libglpk_la-luf.lo: bflib/luf.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-luf.lo -MD -MP -MF $(DEPDIR)/libglpk_la-luf.Tpo -c -o libglpk_la-luf.lo `test -f 'bflib/luf.c' || echo '$(srcdir)/'`bflib/luf.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-luf.Tpo $(DEPDIR)/libglpk_la-luf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/luf.c' object='libglpk_la-luf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-luf.lo `test -f 'bflib/luf.c' || echo '$(srcdir)/'`bflib/luf.c + +libglpk_la-lufint.lo: bflib/lufint.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-lufint.lo -MD -MP -MF $(DEPDIR)/libglpk_la-lufint.Tpo -c -o libglpk_la-lufint.lo `test -f 'bflib/lufint.c' || echo '$(srcdir)/'`bflib/lufint.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-lufint.Tpo $(DEPDIR)/libglpk_la-lufint.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/lufint.c' object='libglpk_la-lufint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-lufint.lo `test -f 'bflib/lufint.c' || echo '$(srcdir)/'`bflib/lufint.c + +libglpk_la-scf.lo: bflib/scf.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-scf.lo -MD -MP -MF $(DEPDIR)/libglpk_la-scf.Tpo -c -o libglpk_la-scf.lo `test -f 'bflib/scf.c' || echo '$(srcdir)/'`bflib/scf.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-scf.Tpo $(DEPDIR)/libglpk_la-scf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/scf.c' object='libglpk_la-scf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-scf.lo `test -f 'bflib/scf.c' || echo '$(srcdir)/'`bflib/scf.c + +libglpk_la-scfint.lo: bflib/scfint.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-scfint.lo -MD -MP -MF $(DEPDIR)/libglpk_la-scfint.Tpo -c -o libglpk_la-scfint.lo `test -f 'bflib/scfint.c' || echo '$(srcdir)/'`bflib/scfint.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-scfint.Tpo $(DEPDIR)/libglpk_la-scfint.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/scfint.c' object='libglpk_la-scfint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-scfint.lo `test -f 'bflib/scfint.c' || echo '$(srcdir)/'`bflib/scfint.c + +libglpk_la-sgf.lo: bflib/sgf.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-sgf.lo -MD -MP -MF $(DEPDIR)/libglpk_la-sgf.Tpo -c -o libglpk_la-sgf.lo `test -f 'bflib/sgf.c' || echo '$(srcdir)/'`bflib/sgf.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-sgf.Tpo $(DEPDIR)/libglpk_la-sgf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/sgf.c' object='libglpk_la-sgf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-sgf.lo `test -f 'bflib/sgf.c' || echo '$(srcdir)/'`bflib/sgf.c + +libglpk_la-sva.lo: bflib/sva.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-sva.lo -MD -MP -MF $(DEPDIR)/libglpk_la-sva.Tpo -c -o libglpk_la-sva.lo `test -f 'bflib/sva.c' || echo '$(srcdir)/'`bflib/sva.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-sva.Tpo $(DEPDIR)/libglpk_la-sva.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/sva.c' object='libglpk_la-sva.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-sva.lo `test -f 'bflib/sva.c' || echo '$(srcdir)/'`bflib/sva.c + +libglpk_la-cfg.lo: cglib/cfg.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-cfg.lo -MD -MP -MF $(DEPDIR)/libglpk_la-cfg.Tpo -c -o libglpk_la-cfg.lo `test -f 'cglib/cfg.c' || echo '$(srcdir)/'`cglib/cfg.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-cfg.Tpo $(DEPDIR)/libglpk_la-cfg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cglib/cfg.c' object='libglpk_la-cfg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-cfg.lo `test -f 'cglib/cfg.c' || echo '$(srcdir)/'`cglib/cfg.c + +libglpk_la-cfg1.lo: cglib/cfg1.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-cfg1.lo -MD -MP -MF $(DEPDIR)/libglpk_la-cfg1.Tpo -c -o libglpk_la-cfg1.lo `test -f 'cglib/cfg1.c' || echo '$(srcdir)/'`cglib/cfg1.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-cfg1.Tpo $(DEPDIR)/libglpk_la-cfg1.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cglib/cfg1.c' object='libglpk_la-cfg1.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-cfg1.lo `test -f 'cglib/cfg1.c' || echo '$(srcdir)/'`cglib/cfg1.c + +libglpk_la-colamd.lo: colamd/colamd.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-colamd.lo -MD -MP -MF $(DEPDIR)/libglpk_la-colamd.Tpo -c -o libglpk_la-colamd.lo `test -f 'colamd/colamd.c' || echo '$(srcdir)/'`colamd/colamd.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-colamd.Tpo $(DEPDIR)/libglpk_la-colamd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='colamd/colamd.c' object='libglpk_la-colamd.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-colamd.lo `test -f 'colamd/colamd.c' || echo '$(srcdir)/'`colamd/colamd.c + +libglpk_la-alloc.lo: env/alloc.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-alloc.lo -MD -MP -MF $(DEPDIR)/libglpk_la-alloc.Tpo -c -o libglpk_la-alloc.lo `test -f 'env/alloc.c' || echo '$(srcdir)/'`env/alloc.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-alloc.Tpo $(DEPDIR)/libglpk_la-alloc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/alloc.c' object='libglpk_la-alloc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-alloc.lo `test -f 'env/alloc.c' || echo '$(srcdir)/'`env/alloc.c + +libglpk_la-dlsup.lo: env/dlsup.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-dlsup.lo -MD -MP -MF $(DEPDIR)/libglpk_la-dlsup.Tpo -c -o libglpk_la-dlsup.lo `test -f 'env/dlsup.c' || echo '$(srcdir)/'`env/dlsup.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-dlsup.Tpo $(DEPDIR)/libglpk_la-dlsup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/dlsup.c' object='libglpk_la-dlsup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-dlsup.lo `test -f 'env/dlsup.c' || echo '$(srcdir)/'`env/dlsup.c + +libglpk_la-env.lo: env/env.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-env.lo -MD -MP -MF $(DEPDIR)/libglpk_la-env.Tpo -c -o libglpk_la-env.lo `test -f 'env/env.c' || echo '$(srcdir)/'`env/env.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-env.Tpo $(DEPDIR)/libglpk_la-env.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/env.c' object='libglpk_la-env.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-env.lo `test -f 'env/env.c' || echo '$(srcdir)/'`env/env.c + +libglpk_la-error.lo: env/error.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-error.lo -MD -MP -MF $(DEPDIR)/libglpk_la-error.Tpo -c -o libglpk_la-error.lo `test -f 'env/error.c' || echo '$(srcdir)/'`env/error.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-error.Tpo $(DEPDIR)/libglpk_la-error.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/error.c' object='libglpk_la-error.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-error.lo `test -f 'env/error.c' || echo '$(srcdir)/'`env/error.c + +libglpk_la-stdout.lo: env/stdout.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-stdout.lo -MD -MP -MF $(DEPDIR)/libglpk_la-stdout.Tpo -c -o libglpk_la-stdout.lo `test -f 'env/stdout.c' || echo '$(srcdir)/'`env/stdout.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-stdout.Tpo $(DEPDIR)/libglpk_la-stdout.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/stdout.c' object='libglpk_la-stdout.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-stdout.lo `test -f 'env/stdout.c' || echo '$(srcdir)/'`env/stdout.c + +libglpk_la-stream.lo: env/stream.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-stream.lo -MD -MP -MF $(DEPDIR)/libglpk_la-stream.Tpo -c -o libglpk_la-stream.lo `test -f 'env/stream.c' || echo '$(srcdir)/'`env/stream.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-stream.Tpo $(DEPDIR)/libglpk_la-stream.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/stream.c' object='libglpk_la-stream.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-stream.lo `test -f 'env/stream.c' || echo '$(srcdir)/'`env/stream.c + +libglpk_la-time.lo: env/time.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-time.lo -MD -MP -MF $(DEPDIR)/libglpk_la-time.Tpo -c -o libglpk_la-time.lo `test -f 'env/time.c' || echo '$(srcdir)/'`env/time.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-time.Tpo $(DEPDIR)/libglpk_la-time.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/time.c' object='libglpk_la-time.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-time.lo `test -f 'env/time.c' || echo '$(srcdir)/'`env/time.c + +libglpk_la-tls.lo: env/tls.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-tls.lo -MD -MP -MF $(DEPDIR)/libglpk_la-tls.Tpo -c -o libglpk_la-tls.lo `test -f 'env/tls.c' || echo '$(srcdir)/'`env/tls.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-tls.Tpo $(DEPDIR)/libglpk_la-tls.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/tls.c' object='libglpk_la-tls.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-tls.lo `test -f 'env/tls.c' || echo '$(srcdir)/'`env/tls.c + +libglpk_la-minisat.lo: minisat/minisat.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-minisat.lo -MD -MP -MF $(DEPDIR)/libglpk_la-minisat.Tpo -c -o libglpk_la-minisat.lo `test -f 'minisat/minisat.c' || echo '$(srcdir)/'`minisat/minisat.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-minisat.Tpo $(DEPDIR)/libglpk_la-minisat.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='minisat/minisat.c' object='libglpk_la-minisat.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-minisat.lo `test -f 'minisat/minisat.c' || echo '$(srcdir)/'`minisat/minisat.c + +libglpk_la-bignum.lo: misc/bignum.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-bignum.lo -MD -MP -MF $(DEPDIR)/libglpk_la-bignum.Tpo -c -o libglpk_la-bignum.lo `test -f 'misc/bignum.c' || echo '$(srcdir)/'`misc/bignum.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-bignum.Tpo $(DEPDIR)/libglpk_la-bignum.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/bignum.c' object='libglpk_la-bignum.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-bignum.lo `test -f 'misc/bignum.c' || echo '$(srcdir)/'`misc/bignum.c + +libglpk_la-dmp.lo: misc/dmp.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-dmp.lo -MD -MP -MF $(DEPDIR)/libglpk_la-dmp.Tpo -c -o libglpk_la-dmp.lo `test -f 'misc/dmp.c' || echo '$(srcdir)/'`misc/dmp.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-dmp.Tpo $(DEPDIR)/libglpk_la-dmp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/dmp.c' object='libglpk_la-dmp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-dmp.lo `test -f 'misc/dmp.c' || echo '$(srcdir)/'`misc/dmp.c + +libglpk_la-ffalg.lo: misc/ffalg.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-ffalg.lo -MD -MP -MF $(DEPDIR)/libglpk_la-ffalg.Tpo -c -o libglpk_la-ffalg.lo `test -f 'misc/ffalg.c' || echo '$(srcdir)/'`misc/ffalg.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-ffalg.Tpo $(DEPDIR)/libglpk_la-ffalg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/ffalg.c' object='libglpk_la-ffalg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-ffalg.lo `test -f 'misc/ffalg.c' || echo '$(srcdir)/'`misc/ffalg.c + +libglpk_la-fp2rat.lo: misc/fp2rat.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-fp2rat.lo -MD -MP -MF $(DEPDIR)/libglpk_la-fp2rat.Tpo -c -o libglpk_la-fp2rat.lo `test -f 'misc/fp2rat.c' || echo '$(srcdir)/'`misc/fp2rat.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-fp2rat.Tpo $(DEPDIR)/libglpk_la-fp2rat.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/fp2rat.c' object='libglpk_la-fp2rat.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-fp2rat.lo `test -f 'misc/fp2rat.c' || echo '$(srcdir)/'`misc/fp2rat.c + +libglpk_la-gcd.lo: misc/gcd.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-gcd.lo -MD -MP -MF $(DEPDIR)/libglpk_la-gcd.Tpo -c -o libglpk_la-gcd.lo `test -f 'misc/gcd.c' || echo '$(srcdir)/'`misc/gcd.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-gcd.Tpo $(DEPDIR)/libglpk_la-gcd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/gcd.c' object='libglpk_la-gcd.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-gcd.lo `test -f 'misc/gcd.c' || echo '$(srcdir)/'`misc/gcd.c + +libglpk_la-jd.lo: misc/jd.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-jd.lo -MD -MP -MF $(DEPDIR)/libglpk_la-jd.Tpo -c -o libglpk_la-jd.lo `test -f 'misc/jd.c' || echo '$(srcdir)/'`misc/jd.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-jd.Tpo $(DEPDIR)/libglpk_la-jd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/jd.c' object='libglpk_la-jd.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-jd.lo `test -f 'misc/jd.c' || echo '$(srcdir)/'`misc/jd.c + +libglpk_la-keller.lo: misc/keller.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-keller.lo -MD -MP -MF $(DEPDIR)/libglpk_la-keller.Tpo -c -o libglpk_la-keller.lo `test -f 'misc/keller.c' || echo '$(srcdir)/'`misc/keller.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-keller.Tpo $(DEPDIR)/libglpk_la-keller.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/keller.c' object='libglpk_la-keller.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-keller.lo `test -f 'misc/keller.c' || echo '$(srcdir)/'`misc/keller.c + +libglpk_la-mc13d.lo: misc/mc13d.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-mc13d.lo -MD -MP -MF $(DEPDIR)/libglpk_la-mc13d.Tpo -c -o libglpk_la-mc13d.lo `test -f 'misc/mc13d.c' || echo '$(srcdir)/'`misc/mc13d.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-mc13d.Tpo $(DEPDIR)/libglpk_la-mc13d.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/mc13d.c' object='libglpk_la-mc13d.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-mc13d.lo `test -f 'misc/mc13d.c' || echo '$(srcdir)/'`misc/mc13d.c + +libglpk_la-mc21a.lo: misc/mc21a.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-mc21a.lo -MD -MP -MF $(DEPDIR)/libglpk_la-mc21a.Tpo -c -o libglpk_la-mc21a.lo `test -f 'misc/mc21a.c' || echo '$(srcdir)/'`misc/mc21a.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-mc21a.Tpo $(DEPDIR)/libglpk_la-mc21a.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/mc21a.c' object='libglpk_la-mc21a.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-mc21a.lo `test -f 'misc/mc21a.c' || echo '$(srcdir)/'`misc/mc21a.c + +libglpk_la-okalg.lo: misc/okalg.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-okalg.lo -MD -MP -MF $(DEPDIR)/libglpk_la-okalg.Tpo -c -o libglpk_la-okalg.lo `test -f 'misc/okalg.c' || echo '$(srcdir)/'`misc/okalg.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-okalg.Tpo $(DEPDIR)/libglpk_la-okalg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/okalg.c' object='libglpk_la-okalg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-okalg.lo `test -f 'misc/okalg.c' || echo '$(srcdir)/'`misc/okalg.c + +libglpk_la-qmd.lo: misc/qmd.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-qmd.lo -MD -MP -MF $(DEPDIR)/libglpk_la-qmd.Tpo -c -o libglpk_la-qmd.lo `test -f 'misc/qmd.c' || echo '$(srcdir)/'`misc/qmd.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-qmd.Tpo $(DEPDIR)/libglpk_la-qmd.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/qmd.c' object='libglpk_la-qmd.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-qmd.lo `test -f 'misc/qmd.c' || echo '$(srcdir)/'`misc/qmd.c + +libglpk_la-relax4.lo: misc/relax4.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-relax4.lo -MD -MP -MF $(DEPDIR)/libglpk_la-relax4.Tpo -c -o libglpk_la-relax4.lo `test -f 'misc/relax4.c' || echo '$(srcdir)/'`misc/relax4.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-relax4.Tpo $(DEPDIR)/libglpk_la-relax4.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/relax4.c' object='libglpk_la-relax4.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-relax4.lo `test -f 'misc/relax4.c' || echo '$(srcdir)/'`misc/relax4.c + +libglpk_la-rng.lo: misc/rng.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-rng.lo -MD -MP -MF $(DEPDIR)/libglpk_la-rng.Tpo -c -o libglpk_la-rng.lo `test -f 'misc/rng.c' || echo '$(srcdir)/'`misc/rng.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-rng.Tpo $(DEPDIR)/libglpk_la-rng.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/rng.c' object='libglpk_la-rng.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-rng.lo `test -f 'misc/rng.c' || echo '$(srcdir)/'`misc/rng.c + +libglpk_la-rng1.lo: misc/rng1.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-rng1.lo -MD -MP -MF $(DEPDIR)/libglpk_la-rng1.Tpo -c -o libglpk_la-rng1.lo `test -f 'misc/rng1.c' || echo '$(srcdir)/'`misc/rng1.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-rng1.Tpo $(DEPDIR)/libglpk_la-rng1.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/rng1.c' object='libglpk_la-rng1.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-rng1.lo `test -f 'misc/rng1.c' || echo '$(srcdir)/'`misc/rng1.c + +libglpk_la-round2n.lo: misc/round2n.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-round2n.lo -MD -MP -MF $(DEPDIR)/libglpk_la-round2n.Tpo -c -o libglpk_la-round2n.lo `test -f 'misc/round2n.c' || echo '$(srcdir)/'`misc/round2n.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-round2n.Tpo $(DEPDIR)/libglpk_la-round2n.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/round2n.c' object='libglpk_la-round2n.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-round2n.lo `test -f 'misc/round2n.c' || echo '$(srcdir)/'`misc/round2n.c + +libglpk_la-str2int.lo: misc/str2int.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-str2int.lo -MD -MP -MF $(DEPDIR)/libglpk_la-str2int.Tpo -c -o libglpk_la-str2int.lo `test -f 'misc/str2int.c' || echo '$(srcdir)/'`misc/str2int.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-str2int.Tpo $(DEPDIR)/libglpk_la-str2int.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/str2int.c' object='libglpk_la-str2int.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-str2int.lo `test -f 'misc/str2int.c' || echo '$(srcdir)/'`misc/str2int.c + +libglpk_la-str2num.lo: misc/str2num.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-str2num.lo -MD -MP -MF $(DEPDIR)/libglpk_la-str2num.Tpo -c -o libglpk_la-str2num.lo `test -f 'misc/str2num.c' || echo '$(srcdir)/'`misc/str2num.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-str2num.Tpo $(DEPDIR)/libglpk_la-str2num.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/str2num.c' object='libglpk_la-str2num.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-str2num.lo `test -f 'misc/str2num.c' || echo '$(srcdir)/'`misc/str2num.c + +libglpk_la-strspx.lo: misc/strspx.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-strspx.lo -MD -MP -MF $(DEPDIR)/libglpk_la-strspx.Tpo -c -o libglpk_la-strspx.lo `test -f 'misc/strspx.c' || echo '$(srcdir)/'`misc/strspx.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-strspx.Tpo $(DEPDIR)/libglpk_la-strspx.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/strspx.c' object='libglpk_la-strspx.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-strspx.lo `test -f 'misc/strspx.c' || echo '$(srcdir)/'`misc/strspx.c + +libglpk_la-strtrim.lo: misc/strtrim.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-strtrim.lo -MD -MP -MF $(DEPDIR)/libglpk_la-strtrim.Tpo -c -o libglpk_la-strtrim.lo `test -f 'misc/strtrim.c' || echo '$(srcdir)/'`misc/strtrim.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-strtrim.Tpo $(DEPDIR)/libglpk_la-strtrim.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/strtrim.c' object='libglpk_la-strtrim.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-strtrim.lo `test -f 'misc/strtrim.c' || echo '$(srcdir)/'`misc/strtrim.c + +libglpk_la-triang.lo: misc/triang.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-triang.lo -MD -MP -MF $(DEPDIR)/libglpk_la-triang.Tpo -c -o libglpk_la-triang.lo `test -f 'misc/triang.c' || echo '$(srcdir)/'`misc/triang.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-triang.Tpo $(DEPDIR)/libglpk_la-triang.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/triang.c' object='libglpk_la-triang.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-triang.lo `test -f 'misc/triang.c' || echo '$(srcdir)/'`misc/triang.c + +libglpk_la-wclique.lo: misc/wclique.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-wclique.lo -MD -MP -MF $(DEPDIR)/libglpk_la-wclique.Tpo -c -o libglpk_la-wclique.lo `test -f 'misc/wclique.c' || echo '$(srcdir)/'`misc/wclique.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-wclique.Tpo $(DEPDIR)/libglpk_la-wclique.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/wclique.c' object='libglpk_la-wclique.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-wclique.lo `test -f 'misc/wclique.c' || echo '$(srcdir)/'`misc/wclique.c + +libglpk_la-wclique1.lo: misc/wclique1.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-wclique1.lo -MD -MP -MF $(DEPDIR)/libglpk_la-wclique1.Tpo -c -o libglpk_la-wclique1.lo `test -f 'misc/wclique1.c' || echo '$(srcdir)/'`misc/wclique1.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-wclique1.Tpo $(DEPDIR)/libglpk_la-wclique1.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/wclique1.c' object='libglpk_la-wclique1.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-wclique1.lo `test -f 'misc/wclique1.c' || echo '$(srcdir)/'`misc/wclique1.c + +libglpk_la-proxy.lo: proxy/proxy.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-proxy.lo -MD -MP -MF $(DEPDIR)/libglpk_la-proxy.Tpo -c -o libglpk_la-proxy.lo `test -f 'proxy/proxy.c' || echo '$(srcdir)/'`proxy/proxy.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-proxy.Tpo $(DEPDIR)/libglpk_la-proxy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='proxy/proxy.c' object='libglpk_la-proxy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-proxy.lo `test -f 'proxy/proxy.c' || echo '$(srcdir)/'`proxy/proxy.c + +libglpk_la-proxy1.lo: proxy/proxy1.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-proxy1.lo -MD -MP -MF $(DEPDIR)/libglpk_la-proxy1.Tpo -c -o libglpk_la-proxy1.lo `test -f 'proxy/proxy1.c' || echo '$(srcdir)/'`proxy/proxy1.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-proxy1.Tpo $(DEPDIR)/libglpk_la-proxy1.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='proxy/proxy1.c' object='libglpk_la-proxy1.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-proxy1.lo `test -f 'proxy/proxy1.c' || echo '$(srcdir)/'`proxy/proxy1.c + +libglpk_la-spxat.lo: simplex/spxat.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-spxat.lo -MD -MP -MF $(DEPDIR)/libglpk_la-spxat.Tpo -c -o libglpk_la-spxat.lo `test -f 'simplex/spxat.c' || echo '$(srcdir)/'`simplex/spxat.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-spxat.Tpo $(DEPDIR)/libglpk_la-spxat.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simplex/spxat.c' object='libglpk_la-spxat.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-spxat.lo `test -f 'simplex/spxat.c' || echo '$(srcdir)/'`simplex/spxat.c + +libglpk_la-spxchuzc.lo: simplex/spxchuzc.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-spxchuzc.lo -MD -MP -MF $(DEPDIR)/libglpk_la-spxchuzc.Tpo -c -o libglpk_la-spxchuzc.lo `test -f 'simplex/spxchuzc.c' || echo '$(srcdir)/'`simplex/spxchuzc.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-spxchuzc.Tpo $(DEPDIR)/libglpk_la-spxchuzc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simplex/spxchuzc.c' object='libglpk_la-spxchuzc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-spxchuzc.lo `test -f 'simplex/spxchuzc.c' || echo '$(srcdir)/'`simplex/spxchuzc.c + +libglpk_la-spxchuzr.lo: simplex/spxchuzr.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-spxchuzr.lo -MD -MP -MF $(DEPDIR)/libglpk_la-spxchuzr.Tpo -c -o libglpk_la-spxchuzr.lo `test -f 'simplex/spxchuzr.c' || echo '$(srcdir)/'`simplex/spxchuzr.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-spxchuzr.Tpo $(DEPDIR)/libglpk_la-spxchuzr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simplex/spxchuzr.c' object='libglpk_la-spxchuzr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-spxchuzr.lo `test -f 'simplex/spxchuzr.c' || echo '$(srcdir)/'`simplex/spxchuzr.c + +libglpk_la-spxlp.lo: simplex/spxlp.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-spxlp.lo -MD -MP -MF $(DEPDIR)/libglpk_la-spxlp.Tpo -c -o libglpk_la-spxlp.lo `test -f 'simplex/spxlp.c' || echo '$(srcdir)/'`simplex/spxlp.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-spxlp.Tpo $(DEPDIR)/libglpk_la-spxlp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simplex/spxlp.c' object='libglpk_la-spxlp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-spxlp.lo `test -f 'simplex/spxlp.c' || echo '$(srcdir)/'`simplex/spxlp.c + +libglpk_la-spxnt.lo: simplex/spxnt.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-spxnt.lo -MD -MP -MF $(DEPDIR)/libglpk_la-spxnt.Tpo -c -o libglpk_la-spxnt.lo `test -f 'simplex/spxnt.c' || echo '$(srcdir)/'`simplex/spxnt.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-spxnt.Tpo $(DEPDIR)/libglpk_la-spxnt.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simplex/spxnt.c' object='libglpk_la-spxnt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-spxnt.lo `test -f 'simplex/spxnt.c' || echo '$(srcdir)/'`simplex/spxnt.c + +libglpk_la-spxprim.lo: simplex/spxprim.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-spxprim.lo -MD -MP -MF $(DEPDIR)/libglpk_la-spxprim.Tpo -c -o libglpk_la-spxprim.lo `test -f 'simplex/spxprim.c' || echo '$(srcdir)/'`simplex/spxprim.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-spxprim.Tpo $(DEPDIR)/libglpk_la-spxprim.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simplex/spxprim.c' object='libglpk_la-spxprim.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-spxprim.lo `test -f 'simplex/spxprim.c' || echo '$(srcdir)/'`simplex/spxprim.c + +libglpk_la-spxprob.lo: simplex/spxprob.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-spxprob.lo -MD -MP -MF $(DEPDIR)/libglpk_la-spxprob.Tpo -c -o libglpk_la-spxprob.lo `test -f 'simplex/spxprob.c' || echo '$(srcdir)/'`simplex/spxprob.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-spxprob.Tpo $(DEPDIR)/libglpk_la-spxprob.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simplex/spxprob.c' object='libglpk_la-spxprob.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-spxprob.lo `test -f 'simplex/spxprob.c' || echo '$(srcdir)/'`simplex/spxprob.c + +libglpk_la-spychuzc.lo: simplex/spychuzc.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-spychuzc.lo -MD -MP -MF $(DEPDIR)/libglpk_la-spychuzc.Tpo -c -o libglpk_la-spychuzc.lo `test -f 'simplex/spychuzc.c' || echo '$(srcdir)/'`simplex/spychuzc.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-spychuzc.Tpo $(DEPDIR)/libglpk_la-spychuzc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simplex/spychuzc.c' object='libglpk_la-spychuzc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-spychuzc.lo `test -f 'simplex/spychuzc.c' || echo '$(srcdir)/'`simplex/spychuzc.c + +libglpk_la-spychuzr.lo: simplex/spychuzr.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-spychuzr.lo -MD -MP -MF $(DEPDIR)/libglpk_la-spychuzr.Tpo -c -o libglpk_la-spychuzr.lo `test -f 'simplex/spychuzr.c' || echo '$(srcdir)/'`simplex/spychuzr.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-spychuzr.Tpo $(DEPDIR)/libglpk_la-spychuzr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simplex/spychuzr.c' object='libglpk_la-spychuzr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-spychuzr.lo `test -f 'simplex/spychuzr.c' || echo '$(srcdir)/'`simplex/spychuzr.c + +libglpk_la-spydual.lo: simplex/spydual.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-spydual.lo -MD -MP -MF $(DEPDIR)/libglpk_la-spydual.Tpo -c -o libglpk_la-spydual.lo `test -f 'simplex/spydual.c' || echo '$(srcdir)/'`simplex/spydual.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-spydual.Tpo $(DEPDIR)/libglpk_la-spydual.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simplex/spydual.c' object='libglpk_la-spydual.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-spydual.lo `test -f 'simplex/spydual.c' || echo '$(srcdir)/'`simplex/spydual.c + +libglpk_la-adler32.lo: zlib/adler32.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-adler32.lo -MD -MP -MF $(DEPDIR)/libglpk_la-adler32.Tpo -c -o libglpk_la-adler32.lo `test -f 'zlib/adler32.c' || echo '$(srcdir)/'`zlib/adler32.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-adler32.Tpo $(DEPDIR)/libglpk_la-adler32.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/adler32.c' object='libglpk_la-adler32.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-adler32.lo `test -f 'zlib/adler32.c' || echo '$(srcdir)/'`zlib/adler32.c + +libglpk_la-compress.lo: zlib/compress.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-compress.lo -MD -MP -MF $(DEPDIR)/libglpk_la-compress.Tpo -c -o libglpk_la-compress.lo `test -f 'zlib/compress.c' || echo '$(srcdir)/'`zlib/compress.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-compress.Tpo $(DEPDIR)/libglpk_la-compress.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/compress.c' object='libglpk_la-compress.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-compress.lo `test -f 'zlib/compress.c' || echo '$(srcdir)/'`zlib/compress.c + +libglpk_la-crc32.lo: zlib/crc32.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-crc32.lo -MD -MP -MF $(DEPDIR)/libglpk_la-crc32.Tpo -c -o libglpk_la-crc32.lo `test -f 'zlib/crc32.c' || echo '$(srcdir)/'`zlib/crc32.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-crc32.Tpo $(DEPDIR)/libglpk_la-crc32.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/crc32.c' object='libglpk_la-crc32.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-crc32.lo `test -f 'zlib/crc32.c' || echo '$(srcdir)/'`zlib/crc32.c + +libglpk_la-deflate.lo: zlib/deflate.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-deflate.lo -MD -MP -MF $(DEPDIR)/libglpk_la-deflate.Tpo -c -o libglpk_la-deflate.lo `test -f 'zlib/deflate.c' || echo '$(srcdir)/'`zlib/deflate.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-deflate.Tpo $(DEPDIR)/libglpk_la-deflate.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/deflate.c' object='libglpk_la-deflate.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-deflate.lo `test -f 'zlib/deflate.c' || echo '$(srcdir)/'`zlib/deflate.c + +libglpk_la-gzclose.lo: zlib/gzclose.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-gzclose.lo -MD -MP -MF $(DEPDIR)/libglpk_la-gzclose.Tpo -c -o libglpk_la-gzclose.lo `test -f 'zlib/gzclose.c' || echo '$(srcdir)/'`zlib/gzclose.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-gzclose.Tpo $(DEPDIR)/libglpk_la-gzclose.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/gzclose.c' object='libglpk_la-gzclose.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-gzclose.lo `test -f 'zlib/gzclose.c' || echo '$(srcdir)/'`zlib/gzclose.c + +libglpk_la-gzlib.lo: zlib/gzlib.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-gzlib.lo -MD -MP -MF $(DEPDIR)/libglpk_la-gzlib.Tpo -c -o libglpk_la-gzlib.lo `test -f 'zlib/gzlib.c' || echo '$(srcdir)/'`zlib/gzlib.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-gzlib.Tpo $(DEPDIR)/libglpk_la-gzlib.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/gzlib.c' object='libglpk_la-gzlib.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-gzlib.lo `test -f 'zlib/gzlib.c' || echo '$(srcdir)/'`zlib/gzlib.c + +libglpk_la-gzread.lo: zlib/gzread.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-gzread.lo -MD -MP -MF $(DEPDIR)/libglpk_la-gzread.Tpo -c -o libglpk_la-gzread.lo `test -f 'zlib/gzread.c' || echo '$(srcdir)/'`zlib/gzread.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-gzread.Tpo $(DEPDIR)/libglpk_la-gzread.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/gzread.c' object='libglpk_la-gzread.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-gzread.lo `test -f 'zlib/gzread.c' || echo '$(srcdir)/'`zlib/gzread.c + +libglpk_la-gzwrite.lo: zlib/gzwrite.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-gzwrite.lo -MD -MP -MF $(DEPDIR)/libglpk_la-gzwrite.Tpo -c -o libglpk_la-gzwrite.lo `test -f 'zlib/gzwrite.c' || echo '$(srcdir)/'`zlib/gzwrite.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-gzwrite.Tpo $(DEPDIR)/libglpk_la-gzwrite.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/gzwrite.c' object='libglpk_la-gzwrite.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-gzwrite.lo `test -f 'zlib/gzwrite.c' || echo '$(srcdir)/'`zlib/gzwrite.c + +libglpk_la-inffast.lo: zlib/inffast.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-inffast.lo -MD -MP -MF $(DEPDIR)/libglpk_la-inffast.Tpo -c -o libglpk_la-inffast.lo `test -f 'zlib/inffast.c' || echo '$(srcdir)/'`zlib/inffast.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-inffast.Tpo $(DEPDIR)/libglpk_la-inffast.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/inffast.c' object='libglpk_la-inffast.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-inffast.lo `test -f 'zlib/inffast.c' || echo '$(srcdir)/'`zlib/inffast.c + +libglpk_la-inflate.lo: zlib/inflate.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-inflate.lo -MD -MP -MF $(DEPDIR)/libglpk_la-inflate.Tpo -c -o libglpk_la-inflate.lo `test -f 'zlib/inflate.c' || echo '$(srcdir)/'`zlib/inflate.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-inflate.Tpo $(DEPDIR)/libglpk_la-inflate.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/inflate.c' object='libglpk_la-inflate.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-inflate.lo `test -f 'zlib/inflate.c' || echo '$(srcdir)/'`zlib/inflate.c + +libglpk_la-inftrees.lo: zlib/inftrees.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-inftrees.lo -MD -MP -MF $(DEPDIR)/libglpk_la-inftrees.Tpo -c -o libglpk_la-inftrees.lo `test -f 'zlib/inftrees.c' || echo '$(srcdir)/'`zlib/inftrees.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-inftrees.Tpo $(DEPDIR)/libglpk_la-inftrees.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/inftrees.c' object='libglpk_la-inftrees.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-inftrees.lo `test -f 'zlib/inftrees.c' || echo '$(srcdir)/'`zlib/inftrees.c + +libglpk_la-trees.lo: zlib/trees.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-trees.lo -MD -MP -MF $(DEPDIR)/libglpk_la-trees.Tpo -c -o libglpk_la-trees.lo `test -f 'zlib/trees.c' || echo '$(srcdir)/'`zlib/trees.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-trees.Tpo $(DEPDIR)/libglpk_la-trees.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/trees.c' object='libglpk_la-trees.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-trees.lo `test -f 'zlib/trees.c' || echo '$(srcdir)/'`zlib/trees.c + +libglpk_la-uncompr.lo: zlib/uncompr.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-uncompr.lo -MD -MP -MF $(DEPDIR)/libglpk_la-uncompr.Tpo -c -o libglpk_la-uncompr.lo `test -f 'zlib/uncompr.c' || echo '$(srcdir)/'`zlib/uncompr.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-uncompr.Tpo $(DEPDIR)/libglpk_la-uncompr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/uncompr.c' object='libglpk_la-uncompr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-uncompr.lo `test -f 'zlib/uncompr.c' || echo '$(srcdir)/'`zlib/uncompr.c + +libglpk_la-zio.lo: zlib/zio.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-zio.lo -MD -MP -MF $(DEPDIR)/libglpk_la-zio.Tpo -c -o libglpk_la-zio.lo `test -f 'zlib/zio.c' || echo '$(srcdir)/'`zlib/zio.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-zio.Tpo $(DEPDIR)/libglpk_la-zio.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/zio.c' object='libglpk_la-zio.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-zio.lo `test -f 'zlib/zio.c' || echo '$(srcdir)/'`zlib/zio.c + +libglpk_la-zutil.lo: zlib/zutil.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-zutil.lo -MD -MP -MF $(DEPDIR)/libglpk_la-zutil.Tpo -c -o libglpk_la-zutil.lo `test -f 'zlib/zutil.c' || echo '$(srcdir)/'`zlib/zutil.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-zutil.Tpo $(DEPDIR)/libglpk_la-zutil.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/zutil.c' object='libglpk_la-zutil.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-zutil.lo `test -f 'zlib/zutil.c' || echo '$(srcdir)/'`zlib/zutil.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +cscopelist: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool cscopelist ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-includeHEADERS install-info \ + install-info-am install-libLTLIBRARIES install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-includeHEADERS \ + uninstall-libLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/resources/3rdparty/glpk-4.57/src/amd/COPYING b/resources/3rdparty/glpk-4.57/src/amd/COPYING new file mode 100644 index 000000000..84bba36d0 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/COPYING @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/resources/3rdparty/glpk-4.57/src/amd/README b/resources/3rdparty/glpk-4.57/src/amd/README new file mode 100644 index 000000000..de950eb48 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/README @@ -0,0 +1,58 @@ +NOTE: Files in this subdirectory are NOT part of the GLPK package, but + are used with GLPK. + + The original code was modified according to GLPK requirements by + Andrew Makhorin . +************************************************************************ +AMD Version 2.2, Copyright (C) 2007 by Timothy A. Davis, +Patrick R. Amestoy, and Iain S. Duff. All Rights Reserved. + +Description: + + AMD is a set of routines for pre-ordering sparse matrices prior to + Cholesky or LU factorization, using the approximate minimum degree + ordering algorithm. Written in ANSI/ISO C with a MATLAB interface, + and in Fortran 77. + +Authors: + + Timothy A. Davis (davis at cise.ufl.edu), University of Florida. + Patrick R. Amestoy, ENSEEIHT, Toulouse, France. + Iain S. Duff, Rutherford Appleton Laboratory, UK. + +AMD License: + + Your use or distribution of AMD or any modified version of AMD + implies that you agree to this License. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + USA. + + Permission is hereby granted to use or copy this program under the + terms of the GNU LGPL, provided that the Copyright, this License, + and the Availability of the original version is retained on all + copies. User documentation of any code that uses this code or any + modified version of this code must cite the Copyright, this License, + the Availability note, and "Used by permission." Permission to + modify the code and to distribute modified code is granted, provided + the Copyright, this License, and the Availability note are retained, + and a notice that the code was modified is included. + + AMD is available under alternate licences; contact T. Davis for + details. + +Availability: + + http://www.cise.ufl.edu/research/sparse/amd diff --git a/resources/3rdparty/glpk-4.57/src/amd/amd.h b/resources/3rdparty/glpk-4.57/src/amd/amd.h new file mode 100644 index 000000000..be662d954 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/amd.h @@ -0,0 +1,67 @@ +/* amd.h */ + +/* Written by Andrew Makhorin . */ + +#ifndef GLPAMD_H +#define GLPAMD_H + +#define AMD_DATE "May 31, 2007" +#define AMD_VERSION_CODE(main, sub) ((main) * 1000 + (sub)) +#define AMD_MAIN_VERSION 2 +#define AMD_SUB_VERSION 2 +#define AMD_SUBSUB_VERSION 0 +#define AMD_VERSION AMD_VERSION_CODE(AMD_MAIN_VERSION, AMD_SUB_VERSION) + +#define AMD_CONTROL 5 +#define AMD_INFO 20 + +#define AMD_DENSE 0 +#define AMD_AGGRESSIVE 1 + +#define AMD_DEFAULT_DENSE 10.0 +#define AMD_DEFAULT_AGGRESSIVE 1 + +#define AMD_STATUS 0 +#define AMD_N 1 +#define AMD_NZ 2 +#define AMD_SYMMETRY 3 +#define AMD_NZDIAG 4 +#define AMD_NZ_A_PLUS_AT 5 +#define AMD_NDENSE 6 +#define AMD_MEMORY 7 +#define AMD_NCMPA 8 +#define AMD_LNZ 9 +#define AMD_NDIV 10 +#define AMD_NMULTSUBS_LDL 11 +#define AMD_NMULTSUBS_LU 12 +#define AMD_DMAX 13 + +#define AMD_OK 0 +#define AMD_OUT_OF_MEMORY (-1) +#define AMD_INVALID (-2) +#define AMD_OK_BUT_JUMBLED 1 + +#define amd_order _glp_amd_order +int amd_order(int n, const int Ap[], const int Ai[], int P[], + double Control[], double Info[]); + +#define amd_2 _glp_amd_2 +void amd_2(int n, int Pe[], int Iw[], int Len[], int iwlen, int pfree, + int Nv[], int Next[], int Last[], int Head[], int Elen[], + int Degree[], int W[], double Control[], double Info[]); + +#define amd_valid _glp_amd_valid +int amd_valid(int n_row, int n_col, const int Ap[], const int Ai[]); + +#define amd_defaults _glp_amd_defaults +void amd_defaults(double Control[]); + +#define amd_control _glp_amd_control +void amd_control(double Control[]); + +#define amd_info _glp_amd_info +void amd_info(double Info[]); + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/amd/amd_1.c b/resources/3rdparty/glpk-4.57/src/amd/amd_1.c new file mode 100644 index 000000000..4f9b07d7c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/amd_1.c @@ -0,0 +1,181 @@ +/* ========================================================================= */ +/* === AMD_1 =============================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* AMD_1: Construct A+A' for a sparse matrix A and perform the AMD ordering. + * + * The n-by-n sparse matrix A can be unsymmetric. It is stored in MATLAB-style + * compressed-column form, with sorted row indices in each column, and no + * duplicate entries. Diagonal entries may be present, but they are ignored. + * Row indices of column j of A are stored in Ai [Ap [j] ... Ap [j+1]-1]. + * Ap [0] must be zero, and nz = Ap [n] is the number of entries in A. The + * size of the matrix, n, must be greater than or equal to zero. + * + * This routine must be preceded by a call to AMD_aat, which computes the + * number of entries in each row/column in A+A', excluding the diagonal. + * Len [j], on input, is the number of entries in row/column j of A+A'. This + * routine constructs the matrix A+A' and then calls AMD_2. No error checking + * is performed (this was done in AMD_valid). + */ + +#include "amd_internal.h" + +GLOBAL void AMD_1 +( + Int n, /* n > 0 */ + const Int Ap [ ], /* input of size n+1, not modified */ + const Int Ai [ ], /* input of size nz = Ap [n], not modified */ + Int P [ ], /* size n output permutation */ + Int Pinv [ ], /* size n output inverse permutation */ + Int Len [ ], /* size n input, undefined on output */ + Int slen, /* slen >= sum (Len [0..n-1]) + 7n, + * ideally slen = 1.2 * sum (Len) + 8n */ + Int S [ ], /* size slen workspace */ + double Control [ ], /* input array of size AMD_CONTROL */ + double Info [ ] /* output array of size AMD_INFO */ +) +{ + Int i, j, k, p, pfree, iwlen, pj, p1, p2, pj2, *Iw, *Pe, *Nv, *Head, + *Elen, *Degree, *s, *W, *Sp, *Tp ; + + /* --------------------------------------------------------------------- */ + /* construct the matrix for AMD_2 */ + /* --------------------------------------------------------------------- */ + + ASSERT (n > 0) ; + + iwlen = slen - 6*n ; + s = S ; + Pe = s ; s += n ; + Nv = s ; s += n ; + Head = s ; s += n ; + Elen = s ; s += n ; + Degree = s ; s += n ; + W = s ; s += n ; + Iw = s ; s += iwlen ; + + ASSERT (AMD_valid (n, n, Ap, Ai) == AMD_OK) ; + + /* construct the pointers for A+A' */ + Sp = Nv ; /* use Nv and W as workspace for Sp and Tp [ */ + Tp = W ; + pfree = 0 ; + for (j = 0 ; j < n ; j++) + { + Pe [j] = pfree ; + Sp [j] = pfree ; + pfree += Len [j] ; + } + + /* Note that this restriction on iwlen is slightly more restrictive than + * what is strictly required in AMD_2. AMD_2 can operate with no elbow + * room at all, but it will be very slow. For better performance, at + * least size-n elbow room is enforced. */ + ASSERT (iwlen >= pfree + n) ; + +#ifndef NDEBUG + for (p = 0 ; p < iwlen ; p++) Iw [p] = EMPTY ; +#endif + + for (k = 0 ; k < n ; k++) + { + AMD_DEBUG1 (("Construct row/column k= "ID" of A+A'\n", k)) ; + p1 = Ap [k] ; + p2 = Ap [k+1] ; + + /* construct A+A' */ + for (p = p1 ; p < p2 ; ) + { + /* scan the upper triangular part of A */ + j = Ai [p] ; + ASSERT (j >= 0 && j < n) ; + if (j < k) + { + /* entry A (j,k) in the strictly upper triangular part */ + ASSERT (Sp [j] < (j == n-1 ? pfree : Pe [j+1])) ; + ASSERT (Sp [k] < (k == n-1 ? pfree : Pe [k+1])) ; + Iw [Sp [j]++] = k ; + Iw [Sp [k]++] = j ; + p++ ; + } + else if (j == k) + { + /* skip the diagonal */ + p++ ; + break ; + } + else /* j > k */ + { + /* first entry below the diagonal */ + break ; + } + /* scan lower triangular part of A, in column j until reaching + * row k. Start where last scan left off. */ + ASSERT (Ap [j] <= Tp [j] && Tp [j] <= Ap [j+1]) ; + pj2 = Ap [j+1] ; + for (pj = Tp [j] ; pj < pj2 ; ) + { + i = Ai [pj] ; + ASSERT (i >= 0 && i < n) ; + if (i < k) + { + /* A (i,j) is only in the lower part, not in upper */ + ASSERT (Sp [i] < (i == n-1 ? pfree : Pe [i+1])) ; + ASSERT (Sp [j] < (j == n-1 ? pfree : Pe [j+1])) ; + Iw [Sp [i]++] = j ; + Iw [Sp [j]++] = i ; + pj++ ; + } + else if (i == k) + { + /* entry A (k,j) in lower part and A (j,k) in upper */ + pj++ ; + break ; + } + else /* i > k */ + { + /* consider this entry later, when k advances to i */ + break ; + } + } + Tp [j] = pj ; + } + Tp [k] = p ; + } + + /* clean up, for remaining mismatched entries */ + for (j = 0 ; j < n ; j++) + { + for (pj = Tp [j] ; pj < Ap [j+1] ; pj++) + { + i = Ai [pj] ; + ASSERT (i >= 0 && i < n) ; + /* A (i,j) is only in the lower part, not in upper */ + ASSERT (Sp [i] < (i == n-1 ? pfree : Pe [i+1])) ; + ASSERT (Sp [j] < (j == n-1 ? pfree : Pe [j+1])) ; + Iw [Sp [i]++] = j ; + Iw [Sp [j]++] = i ; + } + } + +#ifndef NDEBUG + for (j = 0 ; j < n-1 ; j++) ASSERT (Sp [j] == Pe [j+1]) ; + ASSERT (Sp [n-1] == pfree) ; +#endif + + /* Tp and Sp no longer needed ] */ + + /* --------------------------------------------------------------------- */ + /* order the matrix */ + /* --------------------------------------------------------------------- */ + + AMD_2 (n, Pe, Iw, Len, iwlen, pfree, + Nv, Pinv, P, Head, Elen, Degree, W, Control, Info) ; +} diff --git a/resources/3rdparty/glpk-4.57/src/amd/amd_2.c b/resources/3rdparty/glpk-4.57/src/amd/amd_2.c new file mode 100644 index 000000000..36ae828ab --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/amd_2.c @@ -0,0 +1,1842 @@ +/* ========================================================================= */ +/* === AMD_2 =============================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* AMD_2: performs the AMD ordering on a symmetric sparse matrix A, followed + * by a postordering (via depth-first search) of the assembly tree using the + * AMD_postorder routine. + */ + +#include "amd_internal.h" + +/* ========================================================================= */ +/* === clear_flag ========================================================== */ +/* ========================================================================= */ + +static Int clear_flag (Int wflg, Int wbig, Int W [ ], Int n) +{ + Int x ; + if (wflg < 2 || wflg >= wbig) + { + for (x = 0 ; x < n ; x++) + { + if (W [x] != 0) W [x] = 1 ; + } + wflg = 2 ; + } + /* at this point, W [0..n-1] < wflg holds */ + return (wflg) ; +} + + +/* ========================================================================= */ +/* === AMD_2 =============================================================== */ +/* ========================================================================= */ + +GLOBAL void AMD_2 +( + Int n, /* A is n-by-n, where n > 0 */ + Int Pe [ ], /* Pe [0..n-1]: index in Iw of row i on input */ + Int Iw [ ], /* workspace of size iwlen. Iw [0..pfree-1] + * holds the matrix on input */ + Int Len [ ], /* Len [0..n-1]: length for row/column i on input */ + Int iwlen, /* length of Iw. iwlen >= pfree + n */ + Int pfree, /* Iw [pfree ... iwlen-1] is empty on input */ + + /* 7 size-n workspaces, not defined on input: */ + Int Nv [ ], /* the size of each supernode on output */ + Int Next [ ], /* the output inverse permutation */ + Int Last [ ], /* the output permutation */ + Int Head [ ], + Int Elen [ ], /* the size columns of L for each supernode */ + Int Degree [ ], + Int W [ ], + + /* control parameters and output statistics */ + double Control [ ], /* array of size AMD_CONTROL */ + double Info [ ] /* array of size AMD_INFO */ +) +{ + +/* + * Given a representation of the nonzero pattern of a symmetric matrix, A, + * (excluding the diagonal) perform an approximate minimum (UMFPACK/MA38-style) + * degree ordering to compute a pivot order such that the introduction of + * nonzeros (fill-in) in the Cholesky factors A = LL' is kept low. At each + * step, the pivot selected is the one with the minimum UMFAPACK/MA38-style + * upper-bound on the external degree. This routine can optionally perform + * aggresive absorption (as done by MC47B in the Harwell Subroutine + * Library). + * + * The approximate degree algorithm implemented here is the symmetric analog of + * the degree update algorithm in MA38 and UMFPACK (the Unsymmetric-pattern + * MultiFrontal PACKage, both by Davis and Duff). The routine is based on the + * MA27 minimum degree ordering algorithm by Iain Duff and John Reid. + * + * This routine is a translation of the original AMDBAR and MC47B routines, + * in Fortran, with the following modifications: + * + * (1) dense rows/columns are removed prior to ordering the matrix, and placed + * last in the output order. The presence of a dense row/column can + * increase the ordering time by up to O(n^2), unless they are removed + * prior to ordering. + * + * (2) the minimum degree ordering is followed by a postordering (depth-first + * search) of the assembly tree. Note that mass elimination (discussed + * below) combined with the approximate degree update can lead to the mass + * elimination of nodes with lower exact degree than the current pivot + * element. No additional fill-in is caused in the representation of the + * Schur complement. The mass-eliminated nodes merge with the current + * pivot element. They are ordered prior to the current pivot element. + * Because they can have lower exact degree than the current element, the + * merger of two or more of these nodes in the current pivot element can + * lead to a single element that is not a "fundamental supernode". The + * diagonal block can have zeros in it. Thus, the assembly tree used here + * is not guaranteed to be the precise supernodal elemination tree (with + * "funadmental" supernodes), and the postordering performed by this + * routine is not guaranteed to be a precise postordering of the + * elimination tree. + * + * (3) input parameters are added, to control aggressive absorption and the + * detection of "dense" rows/columns of A. + * + * (4) additional statistical information is returned, such as the number of + * nonzeros in L, and the flop counts for subsequent LDL' and LU + * factorizations. These are slight upper bounds, because of the mass + * elimination issue discussed above. + * + * (5) additional routines are added to interface this routine to MATLAB + * to provide a simple C-callable user-interface, to check inputs for + * errors, compute the symmetry of the pattern of A and the number of + * nonzeros in each row/column of A+A', to compute the pattern of A+A', + * to perform the assembly tree postordering, and to provide debugging + * ouput. Many of these functions are also provided by the Fortran + * Harwell Subroutine Library routine MC47A. + * + * (6) both int and UF_long versions are provided. In the descriptions below + * and integer is and int or UF_long depending on which version is + * being used. + + ********************************************************************** + ***** CAUTION: ARGUMENTS ARE NOT CHECKED FOR ERRORS ON INPUT. ****** + ********************************************************************** + ** If you want error checking, a more versatile input format, and a ** + ** simpler user interface, use amd_order or amd_l_order instead. ** + ** This routine is not meant to be user-callable. ** + ********************************************************************** + + * ---------------------------------------------------------------------------- + * References: + * ---------------------------------------------------------------------------- + * + * [1] Timothy A. Davis and Iain Duff, "An unsymmetric-pattern multifrontal + * method for sparse LU factorization", SIAM J. Matrix Analysis and + * Applications, vol. 18, no. 1, pp. 140-158. Discusses UMFPACK / MA38, + * which first introduced the approximate minimum degree used by this + * routine. + * + * [2] Patrick Amestoy, Timothy A. Davis, and Iain S. Duff, "An approximate + * minimum degree ordering algorithm," SIAM J. Matrix Analysis and + * Applications, vol. 17, no. 4, pp. 886-905, 1996. Discusses AMDBAR and + * MC47B, which are the Fortran versions of this routine. + * + * [3] Alan George and Joseph Liu, "The evolution of the minimum degree + * ordering algorithm," SIAM Review, vol. 31, no. 1, pp. 1-19, 1989. + * We list below the features mentioned in that paper that this code + * includes: + * + * mass elimination: + * Yes. MA27 relied on supervariable detection for mass elimination. + * + * indistinguishable nodes: + * Yes (we call these "supervariables"). This was also in the MA27 + * code - although we modified the method of detecting them (the + * previous hash was the true degree, which we no longer keep track + * of). A supervariable is a set of rows with identical nonzero + * pattern. All variables in a supervariable are eliminated together. + * Each supervariable has as its numerical name that of one of its + * variables (its principal variable). + * + * quotient graph representation: + * Yes. We use the term "element" for the cliques formed during + * elimination. This was also in the MA27 code. The algorithm can + * operate in place, but it will work more efficiently if given some + * "elbow room." + * + * element absorption: + * Yes. This was also in the MA27 code. + * + * external degree: + * Yes. The MA27 code was based on the true degree. + * + * incomplete degree update and multiple elimination: + * No. This was not in MA27, either. Our method of degree update + * within MC47B is element-based, not variable-based. It is thus + * not well-suited for use with incomplete degree update or multiple + * elimination. + * + * Authors, and Copyright (C) 2004 by: + * Timothy A. Davis, Patrick Amestoy, Iain S. Duff, John K. Reid. + * + * Acknowledgements: This work (and the UMFPACK package) was supported by the + * National Science Foundation (ASC-9111263, DMS-9223088, and CCR-0203270). + * The UMFPACK/MA38 approximate degree update algorithm, the unsymmetric analog + * which forms the basis of AMD, was developed while Tim Davis was supported by + * CERFACS (Toulouse, France) in a post-doctoral position. This C version, and + * the etree postorder, were written while Tim Davis was on sabbatical at + * Stanford University and Lawrence Berkeley National Laboratory. + + * ---------------------------------------------------------------------------- + * INPUT ARGUMENTS (unaltered): + * ---------------------------------------------------------------------------- + + * n: The matrix order. Restriction: n >= 1. + * + * iwlen: The size of the Iw array. On input, the matrix is stored in + * Iw [0..pfree-1]. However, Iw [0..iwlen-1] should be slightly larger + * than what is required to hold the matrix, at least iwlen >= pfree + n. + * Otherwise, excessive compressions will take place. The recommended + * value of iwlen is 1.2 * pfree + n, which is the value used in the + * user-callable interface to this routine (amd_order.c). The algorithm + * will not run at all if iwlen < pfree. Restriction: iwlen >= pfree + n. + * Note that this is slightly more restrictive than the actual minimum + * (iwlen >= pfree), but AMD_2 will be very slow with no elbow room. + * Thus, this routine enforces a bare minimum elbow room of size n. + * + * pfree: On input the tail end of the array, Iw [pfree..iwlen-1], is empty, + * and the matrix is stored in Iw [0..pfree-1]. During execution, + * additional data is placed in Iw, and pfree is modified so that + * Iw [pfree..iwlen-1] is always the unused part of Iw. + * + * Control: A double array of size AMD_CONTROL containing input parameters + * that affect how the ordering is computed. If NULL, then default + * settings are used. + * + * Control [AMD_DENSE] is used to determine whether or not a given input + * row is "dense". A row is "dense" if the number of entries in the row + * exceeds Control [AMD_DENSE] times sqrt (n), except that rows with 16 or + * fewer entries are never considered "dense". To turn off the detection + * of dense rows, set Control [AMD_DENSE] to a negative number, or to a + * number larger than sqrt (n). The default value of Control [AMD_DENSE] + * is AMD_DEFAULT_DENSE, which is defined in amd.h as 10. + * + * Control [AMD_AGGRESSIVE] is used to determine whether or not aggressive + * absorption is to be performed. If nonzero, then aggressive absorption + * is performed (this is the default). + + * ---------------------------------------------------------------------------- + * INPUT/OUPUT ARGUMENTS: + * ---------------------------------------------------------------------------- + * + * Pe: An integer array of size n. On input, Pe [i] is the index in Iw of + * the start of row i. Pe [i] is ignored if row i has no off-diagonal + * entries. Thus Pe [i] must be in the range 0 to pfree-1 for non-empty + * rows. + * + * During execution, it is used for both supervariables and elements: + * + * Principal supervariable i: index into Iw of the description of + * supervariable i. A supervariable represents one or more rows of + * the matrix with identical nonzero pattern. In this case, + * Pe [i] >= 0. + * + * Non-principal supervariable i: if i has been absorbed into another + * supervariable j, then Pe [i] = FLIP (j), where FLIP (j) is defined + * as (-(j)-2). Row j has the same pattern as row i. Note that j + * might later be absorbed into another supervariable j2, in which + * case Pe [i] is still FLIP (j), and Pe [j] = FLIP (j2) which is + * < EMPTY, where EMPTY is defined as (-1) in amd_internal.h. + * + * Unabsorbed element e: the index into Iw of the description of element + * e, if e has not yet been absorbed by a subsequent element. Element + * e is created when the supervariable of the same name is selected as + * the pivot. In this case, Pe [i] >= 0. + * + * Absorbed element e: if element e is absorbed into element e2, then + * Pe [e] = FLIP (e2). This occurs when the pattern of e (which we + * refer to as Le) is found to be a subset of the pattern of e2 (that + * is, Le2). In this case, Pe [i] < EMPTY. If element e is "null" + * (it has no nonzeros outside its pivot block), then Pe [e] = EMPTY, + * and e is the root of an assembly subtree (or the whole tree if + * there is just one such root). + * + * Dense variable i: if i is "dense", then Pe [i] = EMPTY. + * + * On output, Pe holds the assembly tree/forest, which implicitly + * represents a pivot order with identical fill-in as the actual order + * (via a depth-first search of the tree), as follows. If Nv [i] > 0, + * then i represents a node in the assembly tree, and the parent of i is + * Pe [i], or EMPTY if i is a root. If Nv [i] = 0, then (i, Pe [i]) + * represents an edge in a subtree, the root of which is a node in the + * assembly tree. Note that i refers to a row/column in the original + * matrix, not the permuted matrix. + * + * Info: A double array of size AMD_INFO. If present, (that is, not NULL), + * then statistics about the ordering are returned in the Info array. + * See amd.h for a description. + + * ---------------------------------------------------------------------------- + * INPUT/MODIFIED (undefined on output): + * ---------------------------------------------------------------------------- + * + * Len: An integer array of size n. On input, Len [i] holds the number of + * entries in row i of the matrix, excluding the diagonal. The contents + * of Len are undefined on output. + * + * Iw: An integer array of size iwlen. On input, Iw [0..pfree-1] holds the + * description of each row i in the matrix. The matrix must be symmetric, + * and both upper and lower triangular parts must be present. The + * diagonal must not be present. Row i is held as follows: + * + * Len [i]: the length of the row i data structure in the Iw array. + * Iw [Pe [i] ... Pe [i] + Len [i] - 1]: + * the list of column indices for nonzeros in row i (simple + * supervariables), excluding the diagonal. All supervariables + * start with one row/column each (supervariable i is just row i). + * If Len [i] is zero on input, then Pe [i] is ignored on input. + * + * Note that the rows need not be in any particular order, and there + * may be empty space between the rows. + * + * During execution, the supervariable i experiences fill-in. This is + * represented by placing in i a list of the elements that cause fill-in + * in supervariable i: + * + * Len [i]: the length of supervariable i in the Iw array. + * Iw [Pe [i] ... Pe [i] + Elen [i] - 1]: + * the list of elements that contain i. This list is kept short + * by removing absorbed elements. + * Iw [Pe [i] + Elen [i] ... Pe [i] + Len [i] - 1]: + * the list of supervariables in i. This list is kept short by + * removing nonprincipal variables, and any entry j that is also + * contained in at least one of the elements (j in Le) in the list + * for i (e in row i). + * + * When supervariable i is selected as pivot, we create an element e of + * the same name (e=i): + * + * Len [e]: the length of element e in the Iw array. + * Iw [Pe [e] ... Pe [e] + Len [e] - 1]: + * the list of supervariables in element e. + * + * An element represents the fill-in that occurs when supervariable i is + * selected as pivot (which represents the selection of row i and all + * non-principal variables whose principal variable is i). We use the + * term Le to denote the set of all supervariables in element e. Absorbed + * supervariables and elements are pruned from these lists when + * computationally convenient. + * + * CAUTION: THE INPUT MATRIX IS OVERWRITTEN DURING COMPUTATION. + * The contents of Iw are undefined on output. + + * ---------------------------------------------------------------------------- + * OUTPUT (need not be set on input): + * ---------------------------------------------------------------------------- + * + * Nv: An integer array of size n. During execution, ABS (Nv [i]) is equal to + * the number of rows that are represented by the principal supervariable + * i. If i is a nonprincipal or dense variable, then Nv [i] = 0. + * Initially, Nv [i] = 1 for all i. Nv [i] < 0 signifies that i is a + * principal variable in the pattern Lme of the current pivot element me. + * After element me is constructed, Nv [i] is set back to a positive + * value. + * + * On output, Nv [i] holds the number of pivots represented by super + * row/column i of the original matrix, or Nv [i] = 0 for non-principal + * rows/columns. Note that i refers to a row/column in the original + * matrix, not the permuted matrix. + * + * Elen: An integer array of size n. See the description of Iw above. At the + * start of execution, Elen [i] is set to zero for all rows i. During + * execution, Elen [i] is the number of elements in the list for + * supervariable i. When e becomes an element, Elen [e] = FLIP (esize) is + * set, where esize is the size of the element (the number of pivots, plus + * the number of nonpivotal entries). Thus Elen [e] < EMPTY. + * Elen (i) = EMPTY set when variable i becomes nonprincipal. + * + * For variables, Elen (i) >= EMPTY holds until just before the + * postordering and permutation vectors are computed. For elements, + * Elen [e] < EMPTY holds. + * + * On output, Elen [i] is the degree of the row/column in the Cholesky + * factorization of the permuted matrix, corresponding to the original row + * i, if i is a super row/column. It is equal to EMPTY if i is + * non-principal. Note that i refers to a row/column in the original + * matrix, not the permuted matrix. + * + * Note that the contents of Elen on output differ from the Fortran + * version (Elen holds the inverse permutation in the Fortran version, + * which is instead returned in the Next array in this C version, + * described below). + * + * Last: In a degree list, Last [i] is the supervariable preceding i, or EMPTY + * if i is the head of the list. In a hash bucket, Last [i] is the hash + * key for i. + * + * Last [Head [hash]] is also used as the head of a hash bucket if + * Head [hash] contains a degree list (see the description of Head, + * below). + * + * On output, Last [0..n-1] holds the permutation. That is, if + * i = Last [k], then row i is the kth pivot row (where k ranges from 0 to + * n-1). Row Last [k] of A is the kth row in the permuted matrix, PAP'. + * + * Next: Next [i] is the supervariable following i in a link list, or EMPTY if + * i is the last in the list. Used for two kinds of lists: degree lists + * and hash buckets (a supervariable can be in only one kind of list at a + * time). + * + * On output Next [0..n-1] holds the inverse permutation. That is, if + * k = Next [i], then row i is the kth pivot row. Row i of A appears as + * the (Next[i])-th row in the permuted matrix, PAP'. + * + * Note that the contents of Next on output differ from the Fortran + * version (Next is undefined on output in the Fortran version). + + * ---------------------------------------------------------------------------- + * LOCAL WORKSPACE (not input or output - used only during execution): + * ---------------------------------------------------------------------------- + * + * Degree: An integer array of size n. If i is a supervariable, then + * Degree [i] holds the current approximation of the external degree of + * row i (an upper bound). The external degree is the number of nonzeros + * in row i, minus ABS (Nv [i]), the diagonal part. The bound is equal to + * the exact external degree if Elen [i] is less than or equal to two. + * + * We also use the term "external degree" for elements e to refer to + * |Le \ Lme|. If e is an element, then Degree [e] is |Le|, which is the + * degree of the off-diagonal part of the element e (not including the + * diagonal part). + * + * Head: An integer array of size n. Head is used for degree lists. + * Head [deg] is the first supervariable in a degree list. All + * supervariables i in a degree list Head [deg] have the same approximate + * degree, namely, deg = Degree [i]. If the list Head [deg] is empty then + * Head [deg] = EMPTY. + * + * During supervariable detection Head [hash] also serves as a pointer to + * a hash bucket. If Head [hash] >= 0, there is a degree list of degree + * hash. The hash bucket head pointer is Last [Head [hash]]. If + * Head [hash] = EMPTY, then the degree list and hash bucket are both + * empty. If Head [hash] < EMPTY, then the degree list is empty, and + * FLIP (Head [hash]) is the head of the hash bucket. After supervariable + * detection is complete, all hash buckets are empty, and the + * (Last [Head [hash]] = EMPTY) condition is restored for the non-empty + * degree lists. + * + * W: An integer array of size n. The flag array W determines the status of + * elements and variables, and the external degree of elements. + * + * for elements: + * if W [e] = 0, then the element e is absorbed. + * if W [e] >= wflg, then W [e] - wflg is the size of the set + * |Le \ Lme|, in terms of nonzeros (the sum of ABS (Nv [i]) for + * each principal variable i that is both in the pattern of + * element e and NOT in the pattern of the current pivot element, + * me). + * if wflg > W [e] > 0, then e is not absorbed and has not yet been + * seen in the scan of the element lists in the computation of + * |Le\Lme| in Scan 1 below. + * + * for variables: + * during supervariable detection, if W [j] != wflg then j is + * not in the pattern of variable i. + * + * The W array is initialized by setting W [i] = 1 for all i, and by + * setting wflg = 2. It is reinitialized if wflg becomes too large (to + * ensure that wflg+n does not cause integer overflow). + + * ---------------------------------------------------------------------------- + * LOCAL INTEGERS: + * ---------------------------------------------------------------------------- + */ + + Int deg, degme, dext, lemax, e, elenme, eln, i, ilast, inext, j, + jlast, jnext, k, knt1, knt2, knt3, lenj, ln, me, mindeg, nel, nleft, + nvi, nvj, nvpiv, slenme, wbig, we, wflg, wnvi, ok, ndense, ncmpa, + dense, aggressive ; + + unsigned Int hash ; /* unsigned, so that hash % n is well defined.*/ + +/* + * deg: the degree of a variable or element + * degme: size, |Lme|, of the current element, me (= Degree [me]) + * dext: external degree, |Le \ Lme|, of some element e + * lemax: largest |Le| seen so far (called dmax in Fortran version) + * e: an element + * elenme: the length, Elen [me], of element list of pivotal variable + * eln: the length, Elen [...], of an element list + * hash: the computed value of the hash function + * i: a supervariable + * ilast: the entry in a link list preceding i + * inext: the entry in a link list following i + * j: a supervariable + * jlast: the entry in a link list preceding j + * jnext: the entry in a link list, or path, following j + * k: the pivot order of an element or variable + * knt1: loop counter used during element construction + * knt2: loop counter used during element construction + * knt3: loop counter used during compression + * lenj: Len [j] + * ln: length of a supervariable list + * me: current supervariable being eliminated, and the current + * element created by eliminating that supervariable + * mindeg: current minimum degree + * nel: number of pivots selected so far + * nleft: n - nel, the number of nonpivotal rows/columns remaining + * nvi: the number of variables in a supervariable i (= Nv [i]) + * nvj: the number of variables in a supervariable j (= Nv [j]) + * nvpiv: number of pivots in current element + * slenme: number of variables in variable list of pivotal variable + * wbig: = INT_MAX - n for the int version, UF_long_max - n for the + * UF_long version. wflg is not allowed to be >= wbig. + * we: W [e] + * wflg: used for flagging the W array. See description of Iw. + * wnvi: wflg - Nv [i] + * x: either a supervariable or an element + * + * ok: true if supervariable j can be absorbed into i + * ndense: number of "dense" rows/columns + * dense: rows/columns with initial degree > dense are considered "dense" + * aggressive: true if aggressive absorption is being performed + * ncmpa: number of garbage collections + + * ---------------------------------------------------------------------------- + * LOCAL DOUBLES, used for statistical output only (except for alpha): + * ---------------------------------------------------------------------------- + */ + + double f, r, ndiv, s, nms_lu, nms_ldl, dmax, alpha, lnz, lnzme ; + +/* + * f: nvpiv + * r: degme + nvpiv + * ndiv: number of divisions for LU or LDL' factorizations + * s: number of multiply-subtract pairs for LU factorization, for the + * current element me + * nms_lu number of multiply-subtract pairs for LU factorization + * nms_ldl number of multiply-subtract pairs for LDL' factorization + * dmax: the largest number of entries in any column of L, including the + * diagonal + * alpha: "dense" degree ratio + * lnz: the number of nonzeros in L (excluding the diagonal) + * lnzme: the number of nonzeros in L (excl. the diagonal) for the + * current element me + + * ---------------------------------------------------------------------------- + * LOCAL "POINTERS" (indices into the Iw array) + * ---------------------------------------------------------------------------- +*/ + + Int p, p1, p2, p3, p4, pdst, pend, pj, pme, pme1, pme2, pn, psrc ; + +/* + * Any parameter (Pe [...] or pfree) or local variable starting with "p" (for + * Pointer) is an index into Iw, and all indices into Iw use variables starting + * with "p." The only exception to this rule is the iwlen input argument. + * + * p: pointer into lots of things + * p1: Pe [i] for some variable i (start of element list) + * p2: Pe [i] + Elen [i] - 1 for some variable i + * p3: index of first supervariable in clean list + * p4: + * pdst: destination pointer, for compression + * pend: end of memory to compress + * pj: pointer into an element or variable + * pme: pointer into the current element (pme1...pme2) + * pme1: the current element, me, is stored in Iw [pme1...pme2] + * pme2: the end of the current element + * pn: pointer into a "clean" variable, also used to compress + * psrc: source pointer, for compression +*/ + +/* ========================================================================= */ +/* INITIALIZATIONS */ +/* ========================================================================= */ + + /* Note that this restriction on iwlen is slightly more restrictive than + * what is actually required in AMD_2. AMD_2 can operate with no elbow + * room at all, but it will be slow. For better performance, at least + * size-n elbow room is enforced. */ + ASSERT (iwlen >= pfree + n) ; + ASSERT (n > 0) ; + + /* initialize output statistics */ + lnz = 0 ; + ndiv = 0 ; + nms_lu = 0 ; + nms_ldl = 0 ; + dmax = 1 ; + me = EMPTY ; + + mindeg = 0 ; + ncmpa = 0 ; + nel = 0 ; + lemax = 0 ; + + /* get control parameters */ + if (Control != (double *) NULL) + { + alpha = Control [AMD_DENSE] ; + aggressive = (Control [AMD_AGGRESSIVE] != 0) ; + } + else + { + alpha = AMD_DEFAULT_DENSE ; + aggressive = AMD_DEFAULT_AGGRESSIVE ; + } + /* Note: if alpha is NaN, this is undefined: */ + if (alpha < 0) + { + /* only remove completely dense rows/columns */ + dense = n-2 ; + } + else + { + dense = alpha * sqrt ((double) n) ; + } + dense = MAX (16, dense) ; + dense = MIN (n, dense) ; + AMD_DEBUG1 (("\n\nAMD (debug), alpha %g, aggr. "ID"\n", + alpha, aggressive)) ; + + for (i = 0 ; i < n ; i++) + { + Last [i] = EMPTY ; + Head [i] = EMPTY ; + Next [i] = EMPTY ; + /* if separate Hhead array is used for hash buckets: * + Hhead [i] = EMPTY ; + */ + Nv [i] = 1 ; + W [i] = 1 ; + Elen [i] = 0 ; + Degree [i] = Len [i] ; + } + +#ifndef NDEBUG + AMD_DEBUG1 (("\n======Nel "ID" initial\n", nel)) ; + AMD_dump (n, Pe, Iw, Len, iwlen, pfree, Nv, Next, Last, + Head, Elen, Degree, W, -1) ; +#endif + + /* initialize wflg */ + wbig = Int_MAX - n ; + wflg = clear_flag (0, wbig, W, n) ; + + /* --------------------------------------------------------------------- */ + /* initialize degree lists and eliminate dense and empty rows */ + /* --------------------------------------------------------------------- */ + + ndense = 0 ; + + for (i = 0 ; i < n ; i++) + { + deg = Degree [i] ; + ASSERT (deg >= 0 && deg < n) ; + if (deg == 0) + { + + /* ------------------------------------------------------------- + * we have a variable that can be eliminated at once because + * there is no off-diagonal non-zero in its row. Note that + * Nv [i] = 1 for an empty variable i. It is treated just + * the same as an eliminated element i. + * ------------------------------------------------------------- */ + + Elen [i] = FLIP (1) ; + nel++ ; + Pe [i] = EMPTY ; + W [i] = 0 ; + + } + else if (deg > dense) + { + + /* ------------------------------------------------------------- + * Dense variables are not treated as elements, but as unordered, + * non-principal variables that have no parent. They do not take + * part in the postorder, since Nv [i] = 0. Note that the Fortran + * version does not have this option. + * ------------------------------------------------------------- */ + + AMD_DEBUG1 (("Dense node "ID" degree "ID"\n", i, deg)) ; + ndense++ ; + Nv [i] = 0 ; /* do not postorder this node */ + Elen [i] = EMPTY ; + nel++ ; + Pe [i] = EMPTY ; + + } + else + { + + /* ------------------------------------------------------------- + * place i in the degree list corresponding to its degree + * ------------------------------------------------------------- */ + + inext = Head [deg] ; + ASSERT (inext >= EMPTY && inext < n) ; + if (inext != EMPTY) Last [inext] = i ; + Next [i] = inext ; + Head [deg] = i ; + + } + } + +/* ========================================================================= */ +/* WHILE (selecting pivots) DO */ +/* ========================================================================= */ + + while (nel < n) + { + +#ifndef NDEBUG + AMD_DEBUG1 (("\n======Nel "ID"\n", nel)) ; + if (AMD_debug >= 2) + { + AMD_dump (n, Pe, Iw, Len, iwlen, pfree, Nv, Next, + Last, Head, Elen, Degree, W, nel) ; + } +#endif + +/* ========================================================================= */ +/* GET PIVOT OF MINIMUM DEGREE */ +/* ========================================================================= */ + + /* ----------------------------------------------------------------- */ + /* find next supervariable for elimination */ + /* ----------------------------------------------------------------- */ + + ASSERT (mindeg >= 0 && mindeg < n) ; + for (deg = mindeg ; deg < n ; deg++) + { + me = Head [deg] ; + if (me != EMPTY) break ; + } + mindeg = deg ; + ASSERT (me >= 0 && me < n) ; + AMD_DEBUG1 (("=================me: "ID"\n", me)) ; + + /* ----------------------------------------------------------------- */ + /* remove chosen variable from link list */ + /* ----------------------------------------------------------------- */ + + inext = Next [me] ; + ASSERT (inext >= EMPTY && inext < n) ; + if (inext != EMPTY) Last [inext] = EMPTY ; + Head [deg] = inext ; + + /* ----------------------------------------------------------------- */ + /* me represents the elimination of pivots nel to nel+Nv[me]-1. */ + /* place me itself as the first in this set. */ + /* ----------------------------------------------------------------- */ + + elenme = Elen [me] ; + nvpiv = Nv [me] ; + ASSERT (nvpiv > 0) ; + nel += nvpiv ; + +/* ========================================================================= */ +/* CONSTRUCT NEW ELEMENT */ +/* ========================================================================= */ + + /* ----------------------------------------------------------------- + * At this point, me is the pivotal supervariable. It will be + * converted into the current element. Scan list of the pivotal + * supervariable, me, setting tree pointers and constructing new list + * of supervariables for the new element, me. p is a pointer to the + * current position in the old list. + * ----------------------------------------------------------------- */ + + /* flag the variable "me" as being in Lme by negating Nv [me] */ + Nv [me] = -nvpiv ; + degme = 0 ; + ASSERT (Pe [me] >= 0 && Pe [me] < iwlen) ; + + if (elenme == 0) + { + + /* ------------------------------------------------------------- */ + /* construct the new element in place */ + /* ------------------------------------------------------------- */ + + pme1 = Pe [me] ; + pme2 = pme1 - 1 ; + + for (p = pme1 ; p <= pme1 + Len [me] - 1 ; p++) + { + i = Iw [p] ; + ASSERT (i >= 0 && i < n && Nv [i] >= 0) ; + nvi = Nv [i] ; + if (nvi > 0) + { + + /* ----------------------------------------------------- */ + /* i is a principal variable not yet placed in Lme. */ + /* store i in new list */ + /* ----------------------------------------------------- */ + + /* flag i as being in Lme by negating Nv [i] */ + degme += nvi ; + Nv [i] = -nvi ; + Iw [++pme2] = i ; + + /* ----------------------------------------------------- */ + /* remove variable i from degree list. */ + /* ----------------------------------------------------- */ + + ilast = Last [i] ; + inext = Next [i] ; + ASSERT (ilast >= EMPTY && ilast < n) ; + ASSERT (inext >= EMPTY && inext < n) ; + if (inext != EMPTY) Last [inext] = ilast ; + if (ilast != EMPTY) + { + Next [ilast] = inext ; + } + else + { + /* i is at the head of the degree list */ + ASSERT (Degree [i] >= 0 && Degree [i] < n) ; + Head [Degree [i]] = inext ; + } + } + } + } + else + { + + /* ------------------------------------------------------------- */ + /* construct the new element in empty space, Iw [pfree ...] */ + /* ------------------------------------------------------------- */ + + p = Pe [me] ; + pme1 = pfree ; + slenme = Len [me] - elenme ; + + for (knt1 = 1 ; knt1 <= elenme + 1 ; knt1++) + { + + if (knt1 > elenme) + { + /* search the supervariables in me. */ + e = me ; + pj = p ; + ln = slenme ; + AMD_DEBUG2 (("Search sv: "ID" "ID" "ID"\n", me,pj,ln)) ; + } + else + { + /* search the elements in me. */ + e = Iw [p++] ; + ASSERT (e >= 0 && e < n) ; + pj = Pe [e] ; + ln = Len [e] ; + AMD_DEBUG2 (("Search element e "ID" in me "ID"\n", e,me)) ; + ASSERT (Elen [e] < EMPTY && W [e] > 0 && pj >= 0) ; + } + ASSERT (ln >= 0 && (ln == 0 || (pj >= 0 && pj < iwlen))) ; + + /* --------------------------------------------------------- + * search for different supervariables and add them to the + * new list, compressing when necessary. this loop is + * executed once for each element in the list and once for + * all the supervariables in the list. + * --------------------------------------------------------- */ + + for (knt2 = 1 ; knt2 <= ln ; knt2++) + { + i = Iw [pj++] ; + ASSERT (i >= 0 && i < n && (i == me || Elen [i] >= EMPTY)); + nvi = Nv [i] ; + AMD_DEBUG2 ((": "ID" "ID" "ID" "ID"\n", + i, Elen [i], Nv [i], wflg)) ; + + if (nvi > 0) + { + + /* ------------------------------------------------- */ + /* compress Iw, if necessary */ + /* ------------------------------------------------- */ + + if (pfree >= iwlen) + { + + AMD_DEBUG1 (("GARBAGE COLLECTION\n")) ; + + /* prepare for compressing Iw by adjusting pointers + * and lengths so that the lists being searched in + * the inner and outer loops contain only the + * remaining entries. */ + + Pe [me] = p ; + Len [me] -= knt1 ; + /* check if nothing left of supervariable me */ + if (Len [me] == 0) Pe [me] = EMPTY ; + Pe [e] = pj ; + Len [e] = ln - knt2 ; + /* nothing left of element e */ + if (Len [e] == 0) Pe [e] = EMPTY ; + + ncmpa++ ; /* one more garbage collection */ + + /* store first entry of each object in Pe */ + /* FLIP the first entry in each object */ + for (j = 0 ; j < n ; j++) + { + pn = Pe [j] ; + if (pn >= 0) + { + ASSERT (pn >= 0 && pn < iwlen) ; + Pe [j] = Iw [pn] ; + Iw [pn] = FLIP (j) ; + } + } + + /* psrc/pdst point to source/destination */ + psrc = 0 ; + pdst = 0 ; + pend = pme1 - 1 ; + + while (psrc <= pend) + { + /* search for next FLIP'd entry */ + j = FLIP (Iw [psrc++]) ; + if (j >= 0) + { + AMD_DEBUG2 (("Got object j: "ID"\n", j)) ; + Iw [pdst] = Pe [j] ; + Pe [j] = pdst++ ; + lenj = Len [j] ; + /* copy from source to destination */ + for (knt3 = 0 ; knt3 <= lenj - 2 ; knt3++) + { + Iw [pdst++] = Iw [psrc++] ; + } + } + } + + /* move the new partially-constructed element */ + p1 = pdst ; + for (psrc = pme1 ; psrc <= pfree-1 ; psrc++) + { + Iw [pdst++] = Iw [psrc] ; + } + pme1 = p1 ; + pfree = pdst ; + pj = Pe [e] ; + p = Pe [me] ; + + } + + /* ------------------------------------------------- */ + /* i is a principal variable not yet placed in Lme */ + /* store i in new list */ + /* ------------------------------------------------- */ + + /* flag i as being in Lme by negating Nv [i] */ + degme += nvi ; + Nv [i] = -nvi ; + Iw [pfree++] = i ; + AMD_DEBUG2 ((" s: "ID" nv "ID"\n", i, Nv [i])); + + /* ------------------------------------------------- */ + /* remove variable i from degree link list */ + /* ------------------------------------------------- */ + + ilast = Last [i] ; + inext = Next [i] ; + ASSERT (ilast >= EMPTY && ilast < n) ; + ASSERT (inext >= EMPTY && inext < n) ; + if (inext != EMPTY) Last [inext] = ilast ; + if (ilast != EMPTY) + { + Next [ilast] = inext ; + } + else + { + /* i is at the head of the degree list */ + ASSERT (Degree [i] >= 0 && Degree [i] < n) ; + Head [Degree [i]] = inext ; + } + } + } + + if (e != me) + { + /* set tree pointer and flag to indicate element e is + * absorbed into new element me (the parent of e is me) */ + AMD_DEBUG1 ((" Element "ID" => "ID"\n", e, me)) ; + Pe [e] = FLIP (me) ; + W [e] = 0 ; + } + } + + pme2 = pfree - 1 ; + } + + /* ----------------------------------------------------------------- */ + /* me has now been converted into an element in Iw [pme1..pme2] */ + /* ----------------------------------------------------------------- */ + + /* degme holds the external degree of new element */ + Degree [me] = degme ; + Pe [me] = pme1 ; + Len [me] = pme2 - pme1 + 1 ; + ASSERT (Pe [me] >= 0 && Pe [me] < iwlen) ; + + Elen [me] = FLIP (nvpiv + degme) ; + /* FLIP (Elen (me)) is now the degree of pivot (including + * diagonal part). */ + +#ifndef NDEBUG + AMD_DEBUG2 (("New element structure: length= "ID"\n", pme2-pme1+1)) ; + for (pme = pme1 ; pme <= pme2 ; pme++) AMD_DEBUG3 ((" "ID"", Iw[pme])); + AMD_DEBUG3 (("\n")) ; +#endif + + /* ----------------------------------------------------------------- */ + /* make sure that wflg is not too large. */ + /* ----------------------------------------------------------------- */ + + /* With the current value of wflg, wflg+n must not cause integer + * overflow */ + + wflg = clear_flag (wflg, wbig, W, n) ; + +/* ========================================================================= */ +/* COMPUTE (W [e] - wflg) = |Le\Lme| FOR ALL ELEMENTS */ +/* ========================================================================= */ + + /* ----------------------------------------------------------------- + * Scan 1: compute the external degrees of previous elements with + * respect to the current element. That is: + * (W [e] - wflg) = |Le \ Lme| + * for each element e that appears in any supervariable in Lme. The + * notation Le refers to the pattern (list of supervariables) of a + * previous element e, where e is not yet absorbed, stored in + * Iw [Pe [e] + 1 ... Pe [e] + Len [e]]. The notation Lme + * refers to the pattern of the current element (stored in + * Iw [pme1..pme2]). If aggressive absorption is enabled, and + * (W [e] - wflg) becomes zero, then the element e will be absorbed + * in Scan 2. + * ----------------------------------------------------------------- */ + + AMD_DEBUG2 (("me: ")) ; + for (pme = pme1 ; pme <= pme2 ; pme++) + { + i = Iw [pme] ; + ASSERT (i >= 0 && i < n) ; + eln = Elen [i] ; + AMD_DEBUG3 ((""ID" Elen "ID": \n", i, eln)) ; + if (eln > 0) + { + /* note that Nv [i] has been negated to denote i in Lme: */ + nvi = -Nv [i] ; + ASSERT (nvi > 0 && Pe [i] >= 0 && Pe [i] < iwlen) ; + wnvi = wflg - nvi ; + for (p = Pe [i] ; p <= Pe [i] + eln - 1 ; p++) + { + e = Iw [p] ; + ASSERT (e >= 0 && e < n) ; + we = W [e] ; + AMD_DEBUG4 ((" e "ID" we "ID" ", e, we)) ; + if (we >= wflg) + { + /* unabsorbed element e has been seen in this loop */ + AMD_DEBUG4 ((" unabsorbed, first time seen")) ; + we -= nvi ; + } + else if (we != 0) + { + /* e is an unabsorbed element */ + /* this is the first we have seen e in all of Scan 1 */ + AMD_DEBUG4 ((" unabsorbed")) ; + we = Degree [e] + wnvi ; + } + AMD_DEBUG4 (("\n")) ; + W [e] = we ; + } + } + } + AMD_DEBUG2 (("\n")) ; + +/* ========================================================================= */ +/* DEGREE UPDATE AND ELEMENT ABSORPTION */ +/* ========================================================================= */ + + /* ----------------------------------------------------------------- + * Scan 2: for each i in Lme, sum up the degree of Lme (which is + * degme), plus the sum of the external degrees of each Le for the + * elements e appearing within i, plus the supervariables in i. + * Place i in hash list. + * ----------------------------------------------------------------- */ + + for (pme = pme1 ; pme <= pme2 ; pme++) + { + i = Iw [pme] ; + ASSERT (i >= 0 && i < n && Nv [i] < 0 && Elen [i] >= 0) ; + AMD_DEBUG2 (("Updating: i "ID" "ID" "ID"\n", i, Elen[i], Len [i])); + p1 = Pe [i] ; + p2 = p1 + Elen [i] - 1 ; + pn = p1 ; + hash = 0 ; + deg = 0 ; + ASSERT (p1 >= 0 && p1 < iwlen && p2 >= -1 && p2 < iwlen) ; + + /* ------------------------------------------------------------- */ + /* scan the element list associated with supervariable i */ + /* ------------------------------------------------------------- */ + + /* UMFPACK/MA38-style approximate degree: */ + if (aggressive) + { + for (p = p1 ; p <= p2 ; p++) + { + e = Iw [p] ; + ASSERT (e >= 0 && e < n) ; + we = W [e] ; + if (we != 0) + { + /* e is an unabsorbed element */ + /* dext = | Le \ Lme | */ + dext = we - wflg ; + if (dext > 0) + { + deg += dext ; + Iw [pn++] = e ; + hash += e ; + AMD_DEBUG4 ((" e: "ID" hash = "ID"\n",e,hash)) ; + } + else + { + /* external degree of e is zero, absorb e into me*/ + AMD_DEBUG1 ((" Element "ID" =>"ID" (aggressive)\n", + e, me)) ; + ASSERT (dext == 0) ; + Pe [e] = FLIP (me) ; + W [e] = 0 ; + } + } + } + } + else + { + for (p = p1 ; p <= p2 ; p++) + { + e = Iw [p] ; + ASSERT (e >= 0 && e < n) ; + we = W [e] ; + if (we != 0) + { + /* e is an unabsorbed element */ + dext = we - wflg ; + ASSERT (dext >= 0) ; + deg += dext ; + Iw [pn++] = e ; + hash += e ; + AMD_DEBUG4 ((" e: "ID" hash = "ID"\n",e,hash)) ; + } + } + } + + /* count the number of elements in i (including me): */ + Elen [i] = pn - p1 + 1 ; + + /* ------------------------------------------------------------- */ + /* scan the supervariables in the list associated with i */ + /* ------------------------------------------------------------- */ + + /* The bulk of the AMD run time is typically spent in this loop, + * particularly if the matrix has many dense rows that are not + * removed prior to ordering. */ + p3 = pn ; + p4 = p1 + Len [i] ; + for (p = p2 + 1 ; p < p4 ; p++) + { + j = Iw [p] ; + ASSERT (j >= 0 && j < n) ; + nvj = Nv [j] ; + if (nvj > 0) + { + /* j is unabsorbed, and not in Lme. */ + /* add to degree and add to new list */ + deg += nvj ; + Iw [pn++] = j ; + hash += j ; + AMD_DEBUG4 ((" s: "ID" hash "ID" Nv[j]= "ID"\n", + j, hash, nvj)) ; + } + } + + /* ------------------------------------------------------------- */ + /* update the degree and check for mass elimination */ + /* ------------------------------------------------------------- */ + + /* with aggressive absorption, deg==0 is identical to the + * Elen [i] == 1 && p3 == pn test, below. */ + ASSERT (IMPLIES (aggressive, (deg==0) == (Elen[i]==1 && p3==pn))) ; + + if (Elen [i] == 1 && p3 == pn) + { + + /* --------------------------------------------------------- */ + /* mass elimination */ + /* --------------------------------------------------------- */ + + /* There is nothing left of this node except for an edge to + * the current pivot element. Elen [i] is 1, and there are + * no variables adjacent to node i. Absorb i into the + * current pivot element, me. Note that if there are two or + * more mass eliminations, fillin due to mass elimination is + * possible within the nvpiv-by-nvpiv pivot block. It is this + * step that causes AMD's analysis to be an upper bound. + * + * The reason is that the selected pivot has a lower + * approximate degree than the true degree of the two mass + * eliminated nodes. There is no edge between the two mass + * eliminated nodes. They are merged with the current pivot + * anyway. + * + * No fillin occurs in the Schur complement, in any case, + * and this effect does not decrease the quality of the + * ordering itself, just the quality of the nonzero and + * flop count analysis. It also means that the post-ordering + * is not an exact elimination tree post-ordering. */ + + AMD_DEBUG1 ((" MASS i "ID" => parent e "ID"\n", i, me)) ; + Pe [i] = FLIP (me) ; + nvi = -Nv [i] ; + degme -= nvi ; + nvpiv += nvi ; + nel += nvi ; + Nv [i] = 0 ; + Elen [i] = EMPTY ; + + } + else + { + + /* --------------------------------------------------------- */ + /* update the upper-bound degree of i */ + /* --------------------------------------------------------- */ + + /* the following degree does not yet include the size + * of the current element, which is added later: */ + + Degree [i] = MIN (Degree [i], deg) ; + + /* --------------------------------------------------------- */ + /* add me to the list for i */ + /* --------------------------------------------------------- */ + + /* move first supervariable to end of list */ + Iw [pn] = Iw [p3] ; + /* move first element to end of element part of list */ + Iw [p3] = Iw [p1] ; + /* add new element, me, to front of list. */ + Iw [p1] = me ; + /* store the new length of the list in Len [i] */ + Len [i] = pn - p1 + 1 ; + + /* --------------------------------------------------------- */ + /* place in hash bucket. Save hash key of i in Last [i]. */ + /* --------------------------------------------------------- */ + + /* NOTE: this can fail if hash is negative, because the ANSI C + * standard does not define a % b when a and/or b are negative. + * That's why hash is defined as an unsigned Int, to avoid this + * problem. */ + hash = hash % n ; + ASSERT (((Int) hash) >= 0 && ((Int) hash) < n) ; + + /* if the Hhead array is not used: */ + j = Head [hash] ; + if (j <= EMPTY) + { + /* degree list is empty, hash head is FLIP (j) */ + Next [i] = FLIP (j) ; + Head [hash] = FLIP (i) ; + } + else + { + /* degree list is not empty, use Last [Head [hash]] as + * hash head. */ + Next [i] = Last [j] ; + Last [j] = i ; + } + + /* if a separate Hhead array is used: * + Next [i] = Hhead [hash] ; + Hhead [hash] = i ; + */ + + Last [i] = hash ; + } + } + + Degree [me] = degme ; + + /* ----------------------------------------------------------------- */ + /* Clear the counter array, W [...], by incrementing wflg. */ + /* ----------------------------------------------------------------- */ + + /* make sure that wflg+n does not cause integer overflow */ + lemax = MAX (lemax, degme) ; + wflg += lemax ; + wflg = clear_flag (wflg, wbig, W, n) ; + /* at this point, W [0..n-1] < wflg holds */ + +/* ========================================================================= */ +/* SUPERVARIABLE DETECTION */ +/* ========================================================================= */ + + AMD_DEBUG1 (("Detecting supervariables:\n")) ; + for (pme = pme1 ; pme <= pme2 ; pme++) + { + i = Iw [pme] ; + ASSERT (i >= 0 && i < n) ; + AMD_DEBUG2 (("Consider i "ID" nv "ID"\n", i, Nv [i])) ; + if (Nv [i] < 0) + { + /* i is a principal variable in Lme */ + + /* --------------------------------------------------------- + * examine all hash buckets with 2 or more variables. We do + * this by examing all unique hash keys for supervariables in + * the pattern Lme of the current element, me + * --------------------------------------------------------- */ + + /* let i = head of hash bucket, and empty the hash bucket */ + ASSERT (Last [i] >= 0 && Last [i] < n) ; + hash = Last [i] ; + + /* if Hhead array is not used: */ + j = Head [hash] ; + if (j == EMPTY) + { + /* hash bucket and degree list are both empty */ + i = EMPTY ; + } + else if (j < EMPTY) + { + /* degree list is empty */ + i = FLIP (j) ; + Head [hash] = EMPTY ; + } + else + { + /* degree list is not empty, restore Last [j] of head j */ + i = Last [j] ; + Last [j] = EMPTY ; + } + + /* if separate Hhead array is used: * + i = Hhead [hash] ; + Hhead [hash] = EMPTY ; + */ + + ASSERT (i >= EMPTY && i < n) ; + AMD_DEBUG2 (("----i "ID" hash "ID"\n", i, hash)) ; + + while (i != EMPTY && Next [i] != EMPTY) + { + + /* ----------------------------------------------------- + * this bucket has one or more variables following i. + * scan all of them to see if i can absorb any entries + * that follow i in hash bucket. Scatter i into w. + * ----------------------------------------------------- */ + + ln = Len [i] ; + eln = Elen [i] ; + ASSERT (ln >= 0 && eln >= 0) ; + ASSERT (Pe [i] >= 0 && Pe [i] < iwlen) ; + /* do not flag the first element in the list (me) */ + for (p = Pe [i] + 1 ; p <= Pe [i] + ln - 1 ; p++) + { + ASSERT (Iw [p] >= 0 && Iw [p] < n) ; + W [Iw [p]] = wflg ; + } + + /* ----------------------------------------------------- */ + /* scan every other entry j following i in bucket */ + /* ----------------------------------------------------- */ + + jlast = i ; + j = Next [i] ; + ASSERT (j >= EMPTY && j < n) ; + + while (j != EMPTY) + { + /* ------------------------------------------------- */ + /* check if j and i have identical nonzero pattern */ + /* ------------------------------------------------- */ + + AMD_DEBUG3 (("compare i "ID" and j "ID"\n", i,j)) ; + + /* check if i and j have the same Len and Elen */ + ASSERT (Len [j] >= 0 && Elen [j] >= 0) ; + ASSERT (Pe [j] >= 0 && Pe [j] < iwlen) ; + ok = (Len [j] == ln) && (Elen [j] == eln) ; + /* skip the first element in the list (me) */ + for (p = Pe [j] + 1 ; ok && p <= Pe [j] + ln - 1 ; p++) + { + ASSERT (Iw [p] >= 0 && Iw [p] < n) ; + if (W [Iw [p]] != wflg) ok = 0 ; + } + if (ok) + { + /* --------------------------------------------- */ + /* found it! j can be absorbed into i */ + /* --------------------------------------------- */ + + AMD_DEBUG1 (("found it! j "ID" => i "ID"\n", j,i)); + Pe [j] = FLIP (i) ; + /* both Nv [i] and Nv [j] are negated since they */ + /* are in Lme, and the absolute values of each */ + /* are the number of variables in i and j: */ + Nv [i] += Nv [j] ; + Nv [j] = 0 ; + Elen [j] = EMPTY ; + /* delete j from hash bucket */ + ASSERT (j != Next [j]) ; + j = Next [j] ; + Next [jlast] = j ; + + } + else + { + /* j cannot be absorbed into i */ + jlast = j ; + ASSERT (j != Next [j]) ; + j = Next [j] ; + } + ASSERT (j >= EMPTY && j < n) ; + } + + /* ----------------------------------------------------- + * no more variables can be absorbed into i + * go to next i in bucket and clear flag array + * ----------------------------------------------------- */ + + wflg++ ; + i = Next [i] ; + ASSERT (i >= EMPTY && i < n) ; + + } + } + } + AMD_DEBUG2 (("detect done\n")) ; + +/* ========================================================================= */ +/* RESTORE DEGREE LISTS AND REMOVE NONPRINCIPAL SUPERVARIABLES FROM ELEMENT */ +/* ========================================================================= */ + + p = pme1 ; + nleft = n - nel ; + for (pme = pme1 ; pme <= pme2 ; pme++) + { + i = Iw [pme] ; + ASSERT (i >= 0 && i < n) ; + nvi = -Nv [i] ; + AMD_DEBUG3 (("Restore i "ID" "ID"\n", i, nvi)) ; + if (nvi > 0) + { + /* i is a principal variable in Lme */ + /* restore Nv [i] to signify that i is principal */ + Nv [i] = nvi ; + + /* --------------------------------------------------------- */ + /* compute the external degree (add size of current element) */ + /* --------------------------------------------------------- */ + + deg = Degree [i] + degme - nvi ; + deg = MIN (deg, nleft - nvi) ; + ASSERT (IMPLIES (aggressive, deg > 0) && deg >= 0 && deg < n) ; + + /* --------------------------------------------------------- */ + /* place the supervariable at the head of the degree list */ + /* --------------------------------------------------------- */ + + inext = Head [deg] ; + ASSERT (inext >= EMPTY && inext < n) ; + if (inext != EMPTY) Last [inext] = i ; + Next [i] = inext ; + Last [i] = EMPTY ; + Head [deg] = i ; + + /* --------------------------------------------------------- */ + /* save the new degree, and find the minimum degree */ + /* --------------------------------------------------------- */ + + mindeg = MIN (mindeg, deg) ; + Degree [i] = deg ; + + /* --------------------------------------------------------- */ + /* place the supervariable in the element pattern */ + /* --------------------------------------------------------- */ + + Iw [p++] = i ; + + } + } + AMD_DEBUG2 (("restore done\n")) ; + +/* ========================================================================= */ +/* FINALIZE THE NEW ELEMENT */ +/* ========================================================================= */ + + AMD_DEBUG2 (("ME = "ID" DONE\n", me)) ; + Nv [me] = nvpiv ; + /* save the length of the list for the new element me */ + Len [me] = p - pme1 ; + if (Len [me] == 0) + { + /* there is nothing left of the current pivot element */ + /* it is a root of the assembly tree */ + Pe [me] = EMPTY ; + W [me] = 0 ; + } + if (elenme != 0) + { + /* element was not constructed in place: deallocate part of */ + /* it since newly nonprincipal variables may have been removed */ + pfree = p ; + } + + /* The new element has nvpiv pivots and the size of the contribution + * block for a multifrontal method is degme-by-degme, not including + * the "dense" rows/columns. If the "dense" rows/columns are included, + * the frontal matrix is no larger than + * (degme+ndense)-by-(degme+ndense). + */ + + if (Info != (double *) NULL) + { + f = nvpiv ; + r = degme + ndense ; + dmax = MAX (dmax, f + r) ; + + /* number of nonzeros in L (excluding the diagonal) */ + lnzme = f*r + (f-1)*f/2 ; + lnz += lnzme ; + + /* number of divide operations for LDL' and for LU */ + ndiv += lnzme ; + + /* number of multiply-subtract pairs for LU */ + s = f*r*r + r*(f-1)*f + (f-1)*f*(2*f-1)/6 ; + nms_lu += s ; + + /* number of multiply-subtract pairs for LDL' */ + nms_ldl += (s + lnzme)/2 ; + } + +#ifndef NDEBUG + AMD_DEBUG2 (("finalize done nel "ID" n "ID"\n ::::\n", nel, n)) ; + for (pme = Pe [me] ; pme <= Pe [me] + Len [me] - 1 ; pme++) + { + AMD_DEBUG3 ((" "ID"", Iw [pme])) ; + } + AMD_DEBUG3 (("\n")) ; +#endif + + } + +/* ========================================================================= */ +/* DONE SELECTING PIVOTS */ +/* ========================================================================= */ + + if (Info != (double *) NULL) + { + + /* count the work to factorize the ndense-by-ndense submatrix */ + f = ndense ; + dmax = MAX (dmax, (double) ndense) ; + + /* number of nonzeros in L (excluding the diagonal) */ + lnzme = (f-1)*f/2 ; + lnz += lnzme ; + + /* number of divide operations for LDL' and for LU */ + ndiv += lnzme ; + + /* number of multiply-subtract pairs for LU */ + s = (f-1)*f*(2*f-1)/6 ; + nms_lu += s ; + + /* number of multiply-subtract pairs for LDL' */ + nms_ldl += (s + lnzme)/2 ; + + /* number of nz's in L (excl. diagonal) */ + Info [AMD_LNZ] = lnz ; + + /* number of divide ops for LU and LDL' */ + Info [AMD_NDIV] = ndiv ; + + /* number of multiply-subtract pairs for LDL' */ + Info [AMD_NMULTSUBS_LDL] = nms_ldl ; + + /* number of multiply-subtract pairs for LU */ + Info [AMD_NMULTSUBS_LU] = nms_lu ; + + /* number of "dense" rows/columns */ + Info [AMD_NDENSE] = ndense ; + + /* largest front is dmax-by-dmax */ + Info [AMD_DMAX] = dmax ; + + /* number of garbage collections in AMD */ + Info [AMD_NCMPA] = ncmpa ; + + /* successful ordering */ + Info [AMD_STATUS] = AMD_OK ; + } + +/* ========================================================================= */ +/* POST-ORDERING */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- + * Variables at this point: + * + * Pe: holds the elimination tree. The parent of j is FLIP (Pe [j]), + * or EMPTY if j is a root. The tree holds both elements and + * non-principal (unordered) variables absorbed into them. + * Dense variables are non-principal and unordered. + * + * Elen: holds the size of each element, including the diagonal part. + * FLIP (Elen [e]) > 0 if e is an element. For unordered + * variables i, Elen [i] is EMPTY. + * + * Nv: Nv [e] > 0 is the number of pivots represented by the element e. + * For unordered variables i, Nv [i] is zero. + * + * Contents no longer needed: + * W, Iw, Len, Degree, Head, Next, Last. + * + * The matrix itself has been destroyed. + * + * n: the size of the matrix. + * No other scalars needed (pfree, iwlen, etc.) + * ------------------------------------------------------------------------- */ + + /* restore Pe */ + for (i = 0 ; i < n ; i++) + { + Pe [i] = FLIP (Pe [i]) ; + } + + /* restore Elen, for output information, and for postordering */ + for (i = 0 ; i < n ; i++) + { + Elen [i] = FLIP (Elen [i]) ; + } + +/* Now the parent of j is Pe [j], or EMPTY if j is a root. Elen [e] > 0 + * is the size of element e. Elen [i] is EMPTY for unordered variable i. */ + +#ifndef NDEBUG + AMD_DEBUG2 (("\nTree:\n")) ; + for (i = 0 ; i < n ; i++) + { + AMD_DEBUG2 ((" "ID" parent: "ID" ", i, Pe [i])) ; + ASSERT (Pe [i] >= EMPTY && Pe [i] < n) ; + if (Nv [i] > 0) + { + /* this is an element */ + e = i ; + AMD_DEBUG2 ((" element, size is "ID"\n", Elen [i])) ; + ASSERT (Elen [e] > 0) ; + } + AMD_DEBUG2 (("\n")) ; + } + AMD_DEBUG2 (("\nelements:\n")) ; + for (e = 0 ; e < n ; e++) + { + if (Nv [e] > 0) + { + AMD_DEBUG3 (("Element e= "ID" size "ID" nv "ID" \n", e, + Elen [e], Nv [e])) ; + } + } + AMD_DEBUG2 (("\nvariables:\n")) ; + for (i = 0 ; i < n ; i++) + { + Int cnt ; + if (Nv [i] == 0) + { + AMD_DEBUG3 (("i unordered: "ID"\n", i)) ; + j = Pe [i] ; + cnt = 0 ; + AMD_DEBUG3 ((" j: "ID"\n", j)) ; + if (j == EMPTY) + { + AMD_DEBUG3 ((" i is a dense variable\n")) ; + } + else + { + ASSERT (j >= 0 && j < n) ; + while (Nv [j] == 0) + { + AMD_DEBUG3 ((" j : "ID"\n", j)) ; + j = Pe [j] ; + AMD_DEBUG3 ((" j:: "ID"\n", j)) ; + cnt++ ; + if (cnt > n) break ; + } + e = j ; + AMD_DEBUG3 ((" got to e: "ID"\n", e)) ; + } + } + } +#endif + +/* ========================================================================= */ +/* compress the paths of the variables */ +/* ========================================================================= */ + + for (i = 0 ; i < n ; i++) + { + if (Nv [i] == 0) + { + + /* ------------------------------------------------------------- + * i is an un-ordered row. Traverse the tree from i until + * reaching an element, e. The element, e, was the principal + * supervariable of i and all nodes in the path from i to when e + * was selected as pivot. + * ------------------------------------------------------------- */ + + AMD_DEBUG1 (("Path compression, i unordered: "ID"\n", i)) ; + j = Pe [i] ; + ASSERT (j >= EMPTY && j < n) ; + AMD_DEBUG3 ((" j: "ID"\n", j)) ; + if (j == EMPTY) + { + /* Skip a dense variable. It has no parent. */ + AMD_DEBUG3 ((" i is a dense variable\n")) ; + continue ; + } + + /* while (j is a variable) */ + while (Nv [j] == 0) + { + AMD_DEBUG3 ((" j : "ID"\n", j)) ; + j = Pe [j] ; + AMD_DEBUG3 ((" j:: "ID"\n", j)) ; + ASSERT (j >= 0 && j < n) ; + } + /* got to an element e */ + e = j ; + AMD_DEBUG3 (("got to e: "ID"\n", e)) ; + + /* ------------------------------------------------------------- + * traverse the path again from i to e, and compress the path + * (all nodes point to e). Path compression allows this code to + * compute in O(n) time. + * ------------------------------------------------------------- */ + + j = i ; + /* while (j is a variable) */ + while (Nv [j] == 0) + { + jnext = Pe [j] ; + AMD_DEBUG3 (("j "ID" jnext "ID"\n", j, jnext)) ; + Pe [j] = e ; + j = jnext ; + ASSERT (j >= 0 && j < n) ; + } + } + } + +/* ========================================================================= */ +/* postorder the assembly tree */ +/* ========================================================================= */ + + AMD_postorder (n, Pe, Nv, Elen, + W, /* output order */ + Head, Next, Last) ; /* workspace */ + +/* ========================================================================= */ +/* compute output permutation and inverse permutation */ +/* ========================================================================= */ + + /* W [e] = k means that element e is the kth element in the new + * order. e is in the range 0 to n-1, and k is in the range 0 to + * the number of elements. Use Head for inverse order. */ + + for (k = 0 ; k < n ; k++) + { + Head [k] = EMPTY ; + Next [k] = EMPTY ; + } + for (e = 0 ; e < n ; e++) + { + k = W [e] ; + ASSERT ((k == EMPTY) == (Nv [e] == 0)) ; + if (k != EMPTY) + { + ASSERT (k >= 0 && k < n) ; + Head [k] = e ; + } + } + + /* construct output inverse permutation in Next, + * and permutation in Last */ + nel = 0 ; + for (k = 0 ; k < n ; k++) + { + e = Head [k] ; + if (e == EMPTY) break ; + ASSERT (e >= 0 && e < n && Nv [e] > 0) ; + Next [e] = nel ; + nel += Nv [e] ; + } + ASSERT (nel == n - ndense) ; + + /* order non-principal variables (dense, & those merged into supervar's) */ + for (i = 0 ; i < n ; i++) + { + if (Nv [i] == 0) + { + e = Pe [i] ; + ASSERT (e >= EMPTY && e < n) ; + if (e != EMPTY) + { + /* This is an unordered variable that was merged + * into element e via supernode detection or mass + * elimination of i when e became the pivot element. + * Place i in order just before e. */ + ASSERT (Next [i] == EMPTY && Nv [e] > 0) ; + Next [i] = Next [e] ; + Next [e]++ ; + } + else + { + /* This is a dense unordered variable, with no parent. + * Place it last in the output order. */ + Next [i] = nel++ ; + } + } + } + ASSERT (nel == n) ; + + AMD_DEBUG2 (("\n\nPerm:\n")) ; + for (i = 0 ; i < n ; i++) + { + k = Next [i] ; + ASSERT (k >= 0 && k < n) ; + Last [k] = i ; + AMD_DEBUG2 ((" perm ["ID"] = "ID"\n", k, i)) ; + } +} diff --git a/resources/3rdparty/glpk-4.57/src/amd/amd_aat.c b/resources/3rdparty/glpk-4.57/src/amd/amd_aat.c new file mode 100644 index 000000000..63bf55f52 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/amd_aat.c @@ -0,0 +1,185 @@ +/* ========================================================================= */ +/* === AMD_aat ============================================================= */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* AMD_aat: compute the symmetry of the pattern of A, and count the number of + * nonzeros each column of A+A' (excluding the diagonal). Assumes the input + * matrix has no errors, with sorted columns and no duplicates + * (AMD_valid (n, n, Ap, Ai) must be AMD_OK, but this condition is not + * checked). + */ + +#include "amd_internal.h" + +GLOBAL size_t AMD_aat /* returns nz in A+A' */ +( + Int n, + const Int Ap [ ], + const Int Ai [ ], + Int Len [ ], /* Len [j]: length of column j of A+A', excl diagonal*/ + Int Tp [ ], /* workspace of size n */ + double Info [ ] +) +{ + Int p1, p2, p, i, j, pj, pj2, k, nzdiag, nzboth, nz ; + double sym ; + size_t nzaat ; + +#ifndef NDEBUG + AMD_debug_init ("AMD AAT") ; + for (k = 0 ; k < n ; k++) Tp [k] = EMPTY ; + ASSERT (AMD_valid (n, n, Ap, Ai) == AMD_OK) ; +#endif + + if (Info != (double *) NULL) + { + /* clear the Info array, if it exists */ + for (i = 0 ; i < AMD_INFO ; i++) + { + Info [i] = EMPTY ; + } + Info [AMD_STATUS] = AMD_OK ; + } + + for (k = 0 ; k < n ; k++) + { + Len [k] = 0 ; + } + + nzdiag = 0 ; + nzboth = 0 ; + nz = Ap [n] ; + + for (k = 0 ; k < n ; k++) + { + p1 = Ap [k] ; + p2 = Ap [k+1] ; + AMD_DEBUG2 (("\nAAT Column: "ID" p1: "ID" p2: "ID"\n", k, p1, p2)) ; + + /* construct A+A' */ + for (p = p1 ; p < p2 ; ) + { + /* scan the upper triangular part of A */ + j = Ai [p] ; + if (j < k) + { + /* entry A (j,k) is in the strictly upper triangular part, + * add both A (j,k) and A (k,j) to the matrix A+A' */ + Len [j]++ ; + Len [k]++ ; + AMD_DEBUG3 ((" upper ("ID","ID") ("ID","ID")\n", j,k, k,j)); + p++ ; + } + else if (j == k) + { + /* skip the diagonal */ + p++ ; + nzdiag++ ; + break ; + } + else /* j > k */ + { + /* first entry below the diagonal */ + break ; + } + /* scan lower triangular part of A, in column j until reaching + * row k. Start where last scan left off. */ + ASSERT (Tp [j] != EMPTY) ; + ASSERT (Ap [j] <= Tp [j] && Tp [j] <= Ap [j+1]) ; + pj2 = Ap [j+1] ; + for (pj = Tp [j] ; pj < pj2 ; ) + { + i = Ai [pj] ; + if (i < k) + { + /* A (i,j) is only in the lower part, not in upper. + * add both A (i,j) and A (j,i) to the matrix A+A' */ + Len [i]++ ; + Len [j]++ ; + AMD_DEBUG3 ((" lower ("ID","ID") ("ID","ID")\n", + i,j, j,i)) ; + pj++ ; + } + else if (i == k) + { + /* entry A (k,j) in lower part and A (j,k) in upper */ + pj++ ; + nzboth++ ; + break ; + } + else /* i > k */ + { + /* consider this entry later, when k advances to i */ + break ; + } + } + Tp [j] = pj ; + } + /* Tp [k] points to the entry just below the diagonal in column k */ + Tp [k] = p ; + } + + /* clean up, for remaining mismatched entries */ + for (j = 0 ; j < n ; j++) + { + for (pj = Tp [j] ; pj < Ap [j+1] ; pj++) + { + i = Ai [pj] ; + /* A (i,j) is only in the lower part, not in upper. + * add both A (i,j) and A (j,i) to the matrix A+A' */ + Len [i]++ ; + Len [j]++ ; + AMD_DEBUG3 ((" lower cleanup ("ID","ID") ("ID","ID")\n", + i,j, j,i)) ; + } + } + + /* --------------------------------------------------------------------- */ + /* compute the symmetry of the nonzero pattern of A */ + /* --------------------------------------------------------------------- */ + + /* Given a matrix A, the symmetry of A is: + * B = tril (spones (A), -1) + triu (spones (A), 1) ; + * sym = nnz (B & B') / nnz (B) ; + * or 1 if nnz (B) is zero. + */ + + if (nz == nzdiag) + { + sym = 1 ; + } + else + { + sym = (2 * (double) nzboth) / ((double) (nz - nzdiag)) ; + } + + nzaat = 0 ; + for (k = 0 ; k < n ; k++) + { + nzaat += Len [k] ; + } + + AMD_DEBUG1 (("AMD nz in A+A', excluding diagonal (nzaat) = %g\n", + (double) nzaat)) ; + AMD_DEBUG1 ((" nzboth: "ID" nz: "ID" nzdiag: "ID" symmetry: %g\n", + nzboth, nz, nzdiag, sym)) ; + + if (Info != (double *) NULL) + { + Info [AMD_STATUS] = AMD_OK ; + Info [AMD_N] = n ; + Info [AMD_NZ] = nz ; + Info [AMD_SYMMETRY] = sym ; /* symmetry of pattern of A */ + Info [AMD_NZDIAG] = nzdiag ; /* nonzeros on diagonal of A */ + Info [AMD_NZ_A_PLUS_AT] = nzaat ; /* nonzeros in A+A' */ + } + + return (nzaat) ; +} diff --git a/resources/3rdparty/glpk-4.57/src/amd/amd_control.c b/resources/3rdparty/glpk-4.57/src/amd/amd_control.c new file mode 100644 index 000000000..f4d4f0dfa --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/amd_control.c @@ -0,0 +1,64 @@ +/* ========================================================================= */ +/* === AMD_control ========================================================= */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* User-callable. Prints the control parameters for AMD. See amd.h + * for details. If the Control array is not present, the defaults are + * printed instead. + */ + +#include "amd_internal.h" + +GLOBAL void AMD_control +( + double Control [ ] +) +{ + double alpha ; + Int aggressive ; + + if (Control != (double *) NULL) + { + alpha = Control [AMD_DENSE] ; + aggressive = Control [AMD_AGGRESSIVE] != 0 ; + } + else + { + alpha = AMD_DEFAULT_DENSE ; + aggressive = AMD_DEFAULT_AGGRESSIVE ; + } + + PRINTF (("\nAMD version %d.%d.%d, %s: approximate minimum degree ordering\n" + " dense row parameter: %g\n", AMD_MAIN_VERSION, AMD_SUB_VERSION, + AMD_SUBSUB_VERSION, AMD_DATE, alpha)) ; + + if (alpha < 0) + { + PRINTF ((" no rows treated as dense\n")) ; + } + else + { + PRINTF (( + " (rows with more than max (%g * sqrt (n), 16) entries are\n" + " considered \"dense\", and placed last in output permutation)\n", + alpha)) ; + } + + if (aggressive) + { + PRINTF ((" aggressive absorption: yes\n")) ; + } + else + { + PRINTF ((" aggressive absorption: no\n")) ; + } + + PRINTF ((" size of AMD integer: %d\n\n", sizeof (Int))) ; +} diff --git a/resources/3rdparty/glpk-4.57/src/amd/amd_defaults.c b/resources/3rdparty/glpk-4.57/src/amd/amd_defaults.c new file mode 100644 index 000000000..820e89420 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/amd_defaults.c @@ -0,0 +1,38 @@ +/* ========================================================================= */ +/* === AMD_defaults ======================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* User-callable. Sets default control parameters for AMD. See amd.h + * for details. + */ + +#include "amd_internal.h" + +/* ========================================================================= */ +/* === AMD defaults ======================================================== */ +/* ========================================================================= */ + +GLOBAL void AMD_defaults +( + double Control [ ] +) +{ + Int i ; + + if (Control != (double *) NULL) + { + for (i = 0 ; i < AMD_CONTROL ; i++) + { + Control [i] = 0 ; + } + Control [AMD_DENSE] = AMD_DEFAULT_DENSE ; + Control [AMD_AGGRESSIVE] = AMD_DEFAULT_AGGRESSIVE ; + } +} diff --git a/resources/3rdparty/glpk-4.57/src/amd/amd_dump.c b/resources/3rdparty/glpk-4.57/src/amd/amd_dump.c new file mode 100644 index 000000000..39bbe1d8e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/amd_dump.c @@ -0,0 +1,180 @@ +/* ========================================================================= */ +/* === AMD_dump ============================================================ */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* Debugging routines for AMD. Not used if NDEBUG is not defined at compile- + * time (the default). See comments in amd_internal.h on how to enable + * debugging. Not user-callable. + */ + +#include "amd_internal.h" + +#ifndef NDEBUG + +/* This global variable is present only when debugging */ +GLOBAL Int AMD_debug = -999 ; /* default is no debug printing */ + +/* ========================================================================= */ +/* === AMD_debug_init ====================================================== */ +/* ========================================================================= */ + +/* Sets the debug print level, by reading the file debug.amd (if it exists) */ + +GLOBAL void AMD_debug_init ( char *s ) +{ + FILE *f ; + f = fopen ("debug.amd", "r") ; + if (f == (FILE *) NULL) + { + AMD_debug = -999 ; + } + else + { + fscanf (f, ID, &AMD_debug) ; + fclose (f) ; + } + if (AMD_debug >= 0) + { + printf ("%s: AMD_debug_init, D= "ID"\n", s, AMD_debug) ; + } +} + +/* ========================================================================= */ +/* === AMD_dump ============================================================ */ +/* ========================================================================= */ + +/* Dump AMD's data structure, except for the hash buckets. This routine + * cannot be called when the hash buckets are non-empty. + */ + +GLOBAL void AMD_dump ( + Int n, /* A is n-by-n */ + Int Pe [ ], /* pe [0..n-1]: index in iw of start of row i */ + Int Iw [ ], /* workspace of size iwlen, iwlen [0..pfree-1] + * holds the matrix on input */ + Int Len [ ], /* len [0..n-1]: length for row i */ + Int iwlen, /* length of iw */ + Int pfree, /* iw [pfree ... iwlen-1] is empty on input */ + Int Nv [ ], /* nv [0..n-1] */ + Int Next [ ], /* next [0..n-1] */ + Int Last [ ], /* last [0..n-1] */ + Int Head [ ], /* head [0..n-1] */ + Int Elen [ ], /* size n */ + Int Degree [ ], /* size n */ + Int W [ ], /* size n */ + Int nel +) +{ + Int i, pe, elen, nv, len, e, p, k, j, deg, w, cnt, ilast ; + + if (AMD_debug < 0) return ; + ASSERT (pfree <= iwlen) ; + AMD_DEBUG3 (("\nAMD dump, pfree: "ID"\n", pfree)) ; + for (i = 0 ; i < n ; i++) + { + pe = Pe [i] ; + elen = Elen [i] ; + nv = Nv [i] ; + len = Len [i] ; + w = W [i] ; + + if (elen >= EMPTY) + { + if (nv == 0) + { + AMD_DEBUG3 (("\nI "ID": nonprincipal: ", i)) ; + ASSERT (elen == EMPTY) ; + if (pe == EMPTY) + { + AMD_DEBUG3 ((" dense node\n")) ; + ASSERT (w == 1) ; + } + else + { + ASSERT (pe < EMPTY) ; + AMD_DEBUG3 ((" i "ID" -> parent "ID"\n", i, FLIP (Pe[i]))); + } + } + else + { + AMD_DEBUG3 (("\nI "ID": active principal supervariable:\n",i)); + AMD_DEBUG3 ((" nv(i): "ID" Flag: %d\n", nv, (nv < 0))) ; + ASSERT (elen >= 0) ; + ASSERT (nv > 0 && pe >= 0) ; + p = pe ; + AMD_DEBUG3 ((" e/s: ")) ; + if (elen == 0) AMD_DEBUG3 ((" : ")) ; + ASSERT (pe + len <= pfree) ; + for (k = 0 ; k < len ; k++) + { + j = Iw [p] ; + AMD_DEBUG3 ((" "ID"", j)) ; + ASSERT (j >= 0 && j < n) ; + if (k == elen-1) AMD_DEBUG3 ((" : ")) ; + p++ ; + } + AMD_DEBUG3 (("\n")) ; + } + } + else + { + e = i ; + if (w == 0) + { + AMD_DEBUG3 (("\nE "ID": absorbed element: w "ID"\n", e, w)) ; + ASSERT (nv > 0 && pe < 0) ; + AMD_DEBUG3 ((" e "ID" -> parent "ID"\n", e, FLIP (Pe [e]))) ; + } + else + { + AMD_DEBUG3 (("\nE "ID": unabsorbed element: w "ID"\n", e, w)) ; + ASSERT (nv > 0 && pe >= 0) ; + p = pe ; + AMD_DEBUG3 ((" : ")) ; + ASSERT (pe + len <= pfree) ; + for (k = 0 ; k < len ; k++) + { + j = Iw [p] ; + AMD_DEBUG3 ((" "ID"", j)) ; + ASSERT (j >= 0 && j < n) ; + p++ ; + } + AMD_DEBUG3 (("\n")) ; + } + } + } + + /* this routine cannot be called when the hash buckets are non-empty */ + AMD_DEBUG3 (("\nDegree lists:\n")) ; + if (nel >= 0) + { + cnt = 0 ; + for (deg = 0 ; deg < n ; deg++) + { + if (Head [deg] == EMPTY) continue ; + ilast = EMPTY ; + AMD_DEBUG3 ((ID": \n", deg)) ; + for (i = Head [deg] ; i != EMPTY ; i = Next [i]) + { + AMD_DEBUG3 ((" "ID" : next "ID" last "ID" deg "ID"\n", + i, Next [i], Last [i], Degree [i])) ; + ASSERT (i >= 0 && i < n && ilast == Last [i] && + deg == Degree [i]) ; + cnt += Nv [i] ; + ilast = i ; + } + AMD_DEBUG3 (("\n")) ; + } + ASSERT (cnt == n - nel) ; + } + +} + +#endif diff --git a/resources/3rdparty/glpk-4.57/src/amd/amd_info.c b/resources/3rdparty/glpk-4.57/src/amd/amd_info.c new file mode 100644 index 000000000..e7b806a97 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/amd_info.c @@ -0,0 +1,120 @@ +/* ========================================================================= */ +/* === AMD_info ============================================================ */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* User-callable. Prints the output statistics for AMD. See amd.h + * for details. If the Info array is not present, nothing is printed. + */ + +#include "amd_internal.h" + +#define PRI(format,x) { if (x >= 0) { PRINTF ((format, x)) ; }} + +GLOBAL void AMD_info +( + double Info [ ] +) +{ + double n, ndiv, nmultsubs_ldl, nmultsubs_lu, lnz, lnzd ; + + PRINTF (("\nAMD version %d.%d.%d, %s, results:\n", + AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION, AMD_DATE)) ; + + if (!Info) + { + return ; + } + + n = Info [AMD_N] ; + ndiv = Info [AMD_NDIV] ; + nmultsubs_ldl = Info [AMD_NMULTSUBS_LDL] ; + nmultsubs_lu = Info [AMD_NMULTSUBS_LU] ; + lnz = Info [AMD_LNZ] ; + lnzd = (n >= 0 && lnz >= 0) ? (n + lnz) : (-1) ; + + /* AMD return status */ + PRINTF ((" status: ")) ; + if (Info [AMD_STATUS] == AMD_OK) + { + PRINTF (("OK\n")) ; + } + else if (Info [AMD_STATUS] == AMD_OUT_OF_MEMORY) + { + PRINTF (("out of memory\n")) ; + } + else if (Info [AMD_STATUS] == AMD_INVALID) + { + PRINTF (("invalid matrix\n")) ; + } + else if (Info [AMD_STATUS] == AMD_OK_BUT_JUMBLED) + { + PRINTF (("OK, but jumbled\n")) ; + } + else + { + PRINTF (("unknown\n")) ; + } + + /* statistics about the input matrix */ + PRI (" n, dimension of A: %.20g\n", n); + PRI (" nz, number of nonzeros in A: %.20g\n", + Info [AMD_NZ]) ; + PRI (" symmetry of A: %.4f\n", + Info [AMD_SYMMETRY]) ; + PRI (" number of nonzeros on diagonal: %.20g\n", + Info [AMD_NZDIAG]) ; + PRI (" nonzeros in pattern of A+A' (excl. diagonal): %.20g\n", + Info [AMD_NZ_A_PLUS_AT]) ; + PRI (" # dense rows/columns of A+A': %.20g\n", + Info [AMD_NDENSE]) ; + + /* statistics about AMD's behavior */ + PRI (" memory used, in bytes: %.20g\n", + Info [AMD_MEMORY]) ; + PRI (" # of memory compactions: %.20g\n", + Info [AMD_NCMPA]) ; + + /* statistics about the ordering quality */ + PRINTF (("\n" + " The following approximate statistics are for a subsequent\n" + " factorization of A(P,P) + A(P,P)'. They are slight upper\n" + " bounds if there are no dense rows/columns in A+A', and become\n" + " looser if dense rows/columns exist.\n\n")) ; + + PRI (" nonzeros in L (excluding diagonal): %.20g\n", + lnz) ; + PRI (" nonzeros in L (including diagonal): %.20g\n", + lnzd) ; + PRI (" # divide operations for LDL' or LU: %.20g\n", + ndiv) ; + PRI (" # multiply-subtract operations for LDL': %.20g\n", + nmultsubs_ldl) ; + PRI (" # multiply-subtract operations for LU: %.20g\n", + nmultsubs_lu) ; + PRI (" max nz. in any column of L (incl. diagonal): %.20g\n", + Info [AMD_DMAX]) ; + + /* total flop counts for various factorizations */ + + if (n >= 0 && ndiv >= 0 && nmultsubs_ldl >= 0 && nmultsubs_lu >= 0) + { + PRINTF (("\n" + " chol flop count for real A, sqrt counted as 1 flop: %.20g\n" + " LDL' flop count for real A: %.20g\n" + " LDL' flop count for complex A: %.20g\n" + " LU flop count for real A (with no pivoting): %.20g\n" + " LU flop count for complex A (with no pivoting): %.20g\n\n", + n + ndiv + 2*nmultsubs_ldl, + ndiv + 2*nmultsubs_ldl, + 9*ndiv + 8*nmultsubs_ldl, + ndiv + 2*nmultsubs_lu, + 9*ndiv + 8*nmultsubs_lu)) ; + } +} diff --git a/resources/3rdparty/glpk-4.57/src/amd/amd_internal.h b/resources/3rdparty/glpk-4.57/src/amd/amd_internal.h new file mode 100644 index 000000000..b08f8436b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/amd_internal.h @@ -0,0 +1,117 @@ +/* amd_internal.h */ + +/* Written by Andrew Makhorin . */ + +#ifndef AMD_INTERNAL_H +#define AMD_INTERNAL_H + +/* AMD will be exceedingly slow when running in debug mode. */ +#if 1 +#define NDEBUG +#endif + +#include "amd.h" +#define _GLPSTD_STDIO +#include "env.h" + +#define Int int +#define ID "%d" +#define Int_MAX INT_MAX + +#if 0 /* 15/II-2012 */ +/* now this macro is defined in glpenv.h; besides, the definiton below + depends on implementation, because size_t is an unsigned type */ +#define SIZE_T_MAX ((size_t)(-1)) +#endif + +#define EMPTY (-1) +#define FLIP(i) (-(i)-2) +#define UNFLIP(i) ((i < EMPTY) ? FLIP (i) : (i)) + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +#define IMPLIES(p, q) (!(p) || (q)) + +#define GLOBAL + +#define AMD_order amd_order +#define AMD_defaults amd_defaults +#define AMD_control amd_control +#define AMD_info amd_info +#define AMD_1 amd_1 +#define AMD_2 amd_2 +#define AMD_valid amd_valid +#define AMD_aat amd_aat +#define AMD_postorder amd_postorder +#define AMD_post_tree amd_post_tree +#define AMD_dump amd_dump +#define AMD_debug amd_debug +#define AMD_debug_init amd_debug_init +#define AMD_preprocess amd_preprocess + +#define amd_malloc xmalloc +#if 0 /* 24/V-2009 */ +#define amd_free xfree +#else +#define amd_free(ptr) { if ((ptr) != NULL) xfree(ptr); } +#endif +#define amd_printf xprintf + +#define PRINTF(params) { amd_printf params; } + +#ifndef NDEBUG +#define ASSERT(expr) xassert(expr) +#define AMD_DEBUG0(params) { PRINTF(params); } +#define AMD_DEBUG1(params) { if (AMD_debug >= 1) PRINTF(params); } +#define AMD_DEBUG2(params) { if (AMD_debug >= 2) PRINTF(params); } +#define AMD_DEBUG3(params) { if (AMD_debug >= 3) PRINTF(params); } +#define AMD_DEBUG4(params) { if (AMD_debug >= 4) PRINTF(params); } +#else +#define ASSERT(expression) +#define AMD_DEBUG0(params) +#define AMD_DEBUG1(params) +#define AMD_DEBUG2(params) +#define AMD_DEBUG3(params) +#define AMD_DEBUG4(params) +#endif + +#define amd_aat _glp_amd_aat +size_t AMD_aat(Int n, const Int Ap[], const Int Ai[], Int Len[], + Int Tp[], double Info[]); + +#define amd_1 _glp_amd_1 +void AMD_1(Int n, const Int Ap[], const Int Ai[], Int P[], Int Pinv[], + Int Len[], Int slen, Int S[], double Control[], double Info[]); + +#define amd_postorder _glp_amd_postorder +void AMD_postorder(Int nn, Int Parent[], Int Npiv[], Int Fsize[], + Int Order[], Int Child[], Int Sibling[], Int Stack[]); + +#define amd_post_tree _glp_amd_post_tree +#ifndef NDEBUG +Int AMD_post_tree(Int root, Int k, Int Child[], const Int Sibling[], + Int Order[], Int Stack[], Int nn); +#else +Int AMD_post_tree(Int root, Int k, Int Child[], const Int Sibling[], + Int Order[], Int Stack[]); +#endif + +#define amd_preprocess _glp_amd_preprocess +void AMD_preprocess(Int n, const Int Ap[], const Int Ai[], Int Rp[], + Int Ri[], Int W[], Int Flag[]); + +#define amd_debug _glp_amd_debug +extern Int AMD_debug; + +#define amd_debug_init _glp_amd_debug_init +void AMD_debug_init(char *s); + +#define amd_dump _glp_amd_dump +void AMD_dump(Int n, Int Pe[], Int Iw[], Int Len[], Int iwlen, + Int pfree, Int Nv[], Int Next[], Int Last[], Int Head[], + Int Elen[], Int Degree[], Int W[], Int nel); + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/amd/amd_order.c b/resources/3rdparty/glpk-4.57/src/amd/amd_order.c new file mode 100644 index 000000000..332d56637 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/amd_order.c @@ -0,0 +1,200 @@ +/* ========================================================================= */ +/* === AMD_order =========================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* User-callable AMD minimum degree ordering routine. See amd.h for + * documentation. + */ + +#include "amd_internal.h" + +/* ========================================================================= */ +/* === AMD_order =========================================================== */ +/* ========================================================================= */ + +GLOBAL Int AMD_order +( + Int n, + const Int Ap [ ], + const Int Ai [ ], + Int P [ ], + double Control [ ], + double Info [ ] +) +{ + Int *Len, *S, nz, i, *Pinv, info, status, *Rp, *Ri, *Cp, *Ci, ok ; + size_t nzaat, slen ; + double mem = 0 ; + +#ifndef NDEBUG + AMD_debug_init ("amd") ; +#endif + + /* clear the Info array, if it exists */ + info = Info != (double *) NULL ; + if (info) + { + for (i = 0 ; i < AMD_INFO ; i++) + { + Info [i] = EMPTY ; + } + Info [AMD_N] = n ; + Info [AMD_STATUS] = AMD_OK ; + } + + /* make sure inputs exist and n is >= 0 */ + if (Ai == (Int *) NULL || Ap == (Int *) NULL || P == (Int *) NULL || n < 0) + { + if (info) Info [AMD_STATUS] = AMD_INVALID ; + return (AMD_INVALID) ; /* arguments are invalid */ + } + + if (n == 0) + { + return (AMD_OK) ; /* n is 0 so there's nothing to do */ + } + + nz = Ap [n] ; + if (info) + { + Info [AMD_NZ] = nz ; + } + if (nz < 0) + { + if (info) Info [AMD_STATUS] = AMD_INVALID ; + return (AMD_INVALID) ; + } + + /* check if n or nz will cause size_t overflow */ + if (((size_t) n) >= SIZE_T_MAX / sizeof (Int) + || ((size_t) nz) >= SIZE_T_MAX / sizeof (Int)) + { + if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; + return (AMD_OUT_OF_MEMORY) ; /* problem too large */ + } + + /* check the input matrix: AMD_OK, AMD_INVALID, or AMD_OK_BUT_JUMBLED */ + status = AMD_valid (n, n, Ap, Ai) ; + + if (status == AMD_INVALID) + { + if (info) Info [AMD_STATUS] = AMD_INVALID ; + return (AMD_INVALID) ; /* matrix is invalid */ + } + + /* allocate two size-n integer workspaces */ + Len = amd_malloc (n * sizeof (Int)) ; + Pinv = amd_malloc (n * sizeof (Int)) ; + mem += n ; + mem += n ; + if (!Len || !Pinv) + { + /* :: out of memory :: */ + amd_free (Len) ; + amd_free (Pinv) ; + if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; + return (AMD_OUT_OF_MEMORY) ; + } + + if (status == AMD_OK_BUT_JUMBLED) + { + /* sort the input matrix and remove duplicate entries */ + AMD_DEBUG1 (("Matrix is jumbled\n")) ; + Rp = amd_malloc ((n+1) * sizeof (Int)) ; + Ri = amd_malloc (MAX (nz,1) * sizeof (Int)) ; + mem += (n+1) ; + mem += MAX (nz,1) ; + if (!Rp || !Ri) + { + /* :: out of memory :: */ + amd_free (Rp) ; + amd_free (Ri) ; + amd_free (Len) ; + amd_free (Pinv) ; + if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; + return (AMD_OUT_OF_MEMORY) ; + } + /* use Len and Pinv as workspace to create R = A' */ + AMD_preprocess (n, Ap, Ai, Rp, Ri, Len, Pinv) ; + Cp = Rp ; + Ci = Ri ; + } + else + { + /* order the input matrix as-is. No need to compute R = A' first */ + Rp = NULL ; + Ri = NULL ; + Cp = (Int *) Ap ; + Ci = (Int *) Ai ; + } + + /* --------------------------------------------------------------------- */ + /* determine the symmetry and count off-diagonal nonzeros in A+A' */ + /* --------------------------------------------------------------------- */ + + nzaat = AMD_aat (n, Cp, Ci, Len, P, Info) ; + AMD_DEBUG1 (("nzaat: %g\n", (double) nzaat)) ; + ASSERT ((MAX (nz-n, 0) <= nzaat) && (nzaat <= 2 * (size_t) nz)) ; + + /* --------------------------------------------------------------------- */ + /* allocate workspace for matrix, elbow room, and 6 size-n vectors */ + /* --------------------------------------------------------------------- */ + + S = NULL ; + slen = nzaat ; /* space for matrix */ + ok = ((slen + nzaat/5) >= slen) ; /* check for size_t overflow */ + slen += nzaat/5 ; /* add elbow room */ + for (i = 0 ; ok && i < 7 ; i++) + { + ok = ((slen + n) > slen) ; /* check for size_t overflow */ + slen += n ; /* size-n elbow room, 6 size-n work */ + } + mem += slen ; + ok = ok && (slen < SIZE_T_MAX / sizeof (Int)) ; /* check for overflow */ + ok = ok && (slen < Int_MAX) ; /* S[i] for Int i must be OK */ + if (ok) + { + S = amd_malloc (slen * sizeof (Int)) ; + } + AMD_DEBUG1 (("slen %g\n", (double) slen)) ; + if (!S) + { + /* :: out of memory :: (or problem too large) */ + amd_free (Rp) ; + amd_free (Ri) ; + amd_free (Len) ; + amd_free (Pinv) ; + if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; + return (AMD_OUT_OF_MEMORY) ; + } + if (info) + { + /* memory usage, in bytes. */ + Info [AMD_MEMORY] = mem * sizeof (Int) ; + } + + /* --------------------------------------------------------------------- */ + /* order the matrix */ + /* --------------------------------------------------------------------- */ + + AMD_1 (n, Cp, Ci, P, Pinv, Len, slen, S, Control, Info) ; + + /* --------------------------------------------------------------------- */ + /* free the workspace */ + /* --------------------------------------------------------------------- */ + + amd_free (Rp) ; + amd_free (Ri) ; + amd_free (Len) ; + amd_free (Pinv) ; + amd_free (S) ; + if (info) Info [AMD_STATUS] = status ; + return (status) ; /* successful ordering */ +} diff --git a/resources/3rdparty/glpk-4.57/src/amd/amd_post_tree.c b/resources/3rdparty/glpk-4.57/src/amd/amd_post_tree.c new file mode 100644 index 000000000..bff0e263a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/amd_post_tree.c @@ -0,0 +1,121 @@ +/* ========================================================================= */ +/* === AMD_post_tree ======================================================= */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* Post-ordering of a supernodal elimination tree. */ + +#include "amd_internal.h" + +GLOBAL Int AMD_post_tree +( + Int root, /* root of the tree */ + Int k, /* start numbering at k */ + Int Child [ ], /* input argument of size nn, undefined on + * output. Child [i] is the head of a link + * list of all nodes that are children of node + * i in the tree. */ + const Int Sibling [ ], /* input argument of size nn, not modified. + * If f is a node in the link list of the + * children of node i, then Sibling [f] is the + * next child of node i. + */ + Int Order [ ], /* output order, of size nn. Order [i] = k + * if node i is the kth node of the reordered + * tree. */ + Int Stack [ ] /* workspace of size nn */ +#ifndef NDEBUG + , Int nn /* nodes are in the range 0..nn-1. */ +#endif +) +{ + Int f, head, h, i ; + +#if 0 + /* --------------------------------------------------------------------- */ + /* recursive version (Stack [ ] is not used): */ + /* --------------------------------------------------------------------- */ + + /* this is simple, but can caouse stack overflow if nn is large */ + i = root ; + for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) + { + k = AMD_post_tree (f, k, Child, Sibling, Order, Stack, nn) ; + } + Order [i] = k++ ; + return (k) ; +#endif + + /* --------------------------------------------------------------------- */ + /* non-recursive version, using an explicit stack */ + /* --------------------------------------------------------------------- */ + + /* push root on the stack */ + head = 0 ; + Stack [0] = root ; + + while (head >= 0) + { + /* get head of stack */ + ASSERT (head < nn) ; + i = Stack [head] ; + AMD_DEBUG1 (("head of stack "ID" \n", i)) ; + ASSERT (i >= 0 && i < nn) ; + + if (Child [i] != EMPTY) + { + /* the children of i are not yet ordered */ + /* push each child onto the stack in reverse order */ + /* so that small ones at the head of the list get popped first */ + /* and the biggest one at the end of the list gets popped last */ + for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) + { + head++ ; + ASSERT (head < nn) ; + ASSERT (f >= 0 && f < nn) ; + } + h = head ; + ASSERT (head < nn) ; + for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) + { + ASSERT (h > 0) ; + Stack [h--] = f ; + AMD_DEBUG1 (("push "ID" on stack\n", f)) ; + ASSERT (f >= 0 && f < nn) ; + } + ASSERT (Stack [h] == i) ; + + /* delete child list so that i gets ordered next time we see it */ + Child [i] = EMPTY ; + } + else + { + /* the children of i (if there were any) are already ordered */ + /* remove i from the stack and order it. Front i is kth front */ + head-- ; + AMD_DEBUG1 (("pop "ID" order "ID"\n", i, k)) ; + Order [i] = k++ ; + ASSERT (k <= nn) ; + } + +#ifndef NDEBUG + AMD_DEBUG1 (("\nStack:")) ; + for (h = head ; h >= 0 ; h--) + { + Int j = Stack [h] ; + AMD_DEBUG1 ((" "ID, j)) ; + ASSERT (j >= 0 && j < nn) ; + } + AMD_DEBUG1 (("\n\n")) ; + ASSERT (head < nn) ; +#endif + + } + return (k) ; +} diff --git a/resources/3rdparty/glpk-4.57/src/amd/amd_postorder.c b/resources/3rdparty/glpk-4.57/src/amd/amd_postorder.c new file mode 100644 index 000000000..a3ece915c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/amd_postorder.c @@ -0,0 +1,207 @@ +/* ========================================================================= */ +/* === AMD_postorder ======================================================= */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* Perform a postordering (via depth-first search) of an assembly tree. */ + +#include "amd_internal.h" + +GLOBAL void AMD_postorder +( + /* inputs, not modified on output: */ + Int nn, /* nodes are in the range 0..nn-1 */ + Int Parent [ ], /* Parent [j] is the parent of j, or EMPTY if root */ + Int Nv [ ], /* Nv [j] > 0 number of pivots represented by node j, + * or zero if j is not a node. */ + Int Fsize [ ], /* Fsize [j]: size of node j */ + + /* output, not defined on input: */ + Int Order [ ], /* output post-order */ + + /* workspaces of size nn: */ + Int Child [ ], + Int Sibling [ ], + Int Stack [ ] +) +{ + Int i, j, k, parent, frsize, f, fprev, maxfrsize, bigfprev, bigf, fnext ; + + for (j = 0 ; j < nn ; j++) + { + Child [j] = EMPTY ; + Sibling [j] = EMPTY ; + } + + /* --------------------------------------------------------------------- */ + /* place the children in link lists - bigger elements tend to be last */ + /* --------------------------------------------------------------------- */ + + for (j = nn-1 ; j >= 0 ; j--) + { + if (Nv [j] > 0) + { + /* this is an element */ + parent = Parent [j] ; + if (parent != EMPTY) + { + /* place the element in link list of the children its parent */ + /* bigger elements will tend to be at the end of the list */ + Sibling [j] = Child [parent] ; + Child [parent] = j ; + } + } + } + +#ifndef NDEBUG + { + Int nels, ff, nchild ; + AMD_DEBUG1 (("\n\n================================ AMD_postorder:\n")); + nels = 0 ; + for (j = 0 ; j < nn ; j++) + { + if (Nv [j] > 0) + { + AMD_DEBUG1 (( ""ID" : nels "ID" npiv "ID" size "ID + " parent "ID" maxfr "ID"\n", j, nels, + Nv [j], Fsize [j], Parent [j], Fsize [j])) ; + /* this is an element */ + /* dump the link list of children */ + nchild = 0 ; + AMD_DEBUG1 ((" Children: ")) ; + for (ff = Child [j] ; ff != EMPTY ; ff = Sibling [ff]) + { + AMD_DEBUG1 ((ID" ", ff)) ; + ASSERT (Parent [ff] == j) ; + nchild++ ; + ASSERT (nchild < nn) ; + } + AMD_DEBUG1 (("\n")) ; + parent = Parent [j] ; + if (parent != EMPTY) + { + ASSERT (Nv [parent] > 0) ; + } + nels++ ; + } + } + } + AMD_DEBUG1 (("\n\nGo through the children of each node, and put\n" + "the biggest child last in each list:\n")) ; +#endif + + /* --------------------------------------------------------------------- */ + /* place the largest child last in the list of children for each node */ + /* --------------------------------------------------------------------- */ + + for (i = 0 ; i < nn ; i++) + { + if (Nv [i] > 0 && Child [i] != EMPTY) + { + +#ifndef NDEBUG + Int nchild ; + AMD_DEBUG1 (("Before partial sort, element "ID"\n", i)) ; + nchild = 0 ; + for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) + { + ASSERT (f >= 0 && f < nn) ; + AMD_DEBUG1 ((" f: "ID" size: "ID"\n", f, Fsize [f])) ; + nchild++ ; + ASSERT (nchild <= nn) ; + } +#endif + + /* find the biggest element in the child list */ + fprev = EMPTY ; + maxfrsize = EMPTY ; + bigfprev = EMPTY ; + bigf = EMPTY ; + for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) + { + ASSERT (f >= 0 && f < nn) ; + frsize = Fsize [f] ; + if (frsize >= maxfrsize) + { + /* this is the biggest seen so far */ + maxfrsize = frsize ; + bigfprev = fprev ; + bigf = f ; + } + fprev = f ; + } + ASSERT (bigf != EMPTY) ; + + fnext = Sibling [bigf] ; + + AMD_DEBUG1 (("bigf "ID" maxfrsize "ID" bigfprev "ID" fnext "ID + " fprev " ID"\n", bigf, maxfrsize, bigfprev, fnext, fprev)) ; + + if (fnext != EMPTY) + { + /* if fnext is EMPTY then bigf is already at the end of list */ + + if (bigfprev == EMPTY) + { + /* delete bigf from the element of the list */ + Child [i] = fnext ; + } + else + { + /* delete bigf from the middle of the list */ + Sibling [bigfprev] = fnext ; + } + + /* put bigf at the end of the list */ + Sibling [bigf] = EMPTY ; + ASSERT (Child [i] != EMPTY) ; + ASSERT (fprev != bigf) ; + ASSERT (fprev != EMPTY) ; + Sibling [fprev] = bigf ; + } + +#ifndef NDEBUG + AMD_DEBUG1 (("After partial sort, element "ID"\n", i)) ; + for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) + { + ASSERT (f >= 0 && f < nn) ; + AMD_DEBUG1 ((" "ID" "ID"\n", f, Fsize [f])) ; + ASSERT (Nv [f] > 0) ; + nchild-- ; + } + ASSERT (nchild == 0) ; +#endif + + } + } + + /* --------------------------------------------------------------------- */ + /* postorder the assembly tree */ + /* --------------------------------------------------------------------- */ + + for (i = 0 ; i < nn ; i++) + { + Order [i] = EMPTY ; + } + + k = 0 ; + + for (i = 0 ; i < nn ; i++) + { + if (Parent [i] == EMPTY && Nv [i] > 0) + { + AMD_DEBUG1 (("Root of assembly tree "ID"\n", i)) ; + k = AMD_post_tree (i, k, Child, Sibling, Order, Stack +#ifndef NDEBUG + , nn +#endif + ) ; + } + } +} diff --git a/resources/3rdparty/glpk-4.57/src/amd/amd_preprocess.c b/resources/3rdparty/glpk-4.57/src/amd/amd_preprocess.c new file mode 100644 index 000000000..fc223fb51 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/amd_preprocess.c @@ -0,0 +1,119 @@ +/* ========================================================================= */ +/* === AMD_preprocess ====================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* Sorts, removes duplicate entries, and transposes from the nonzero pattern of + * a column-form matrix A, to obtain the matrix R. The input matrix can have + * duplicate entries and/or unsorted columns (AMD_valid (n,Ap,Ai) must not be + * AMD_INVALID). + * + * This input condition is NOT checked. This routine is not user-callable. + */ + +#include "amd_internal.h" + +/* ========================================================================= */ +/* === AMD_preprocess ====================================================== */ +/* ========================================================================= */ + +/* AMD_preprocess does not check its input for errors or allocate workspace. + * On input, the condition (AMD_valid (n,n,Ap,Ai) != AMD_INVALID) must hold. + */ + +GLOBAL void AMD_preprocess +( + Int n, /* input matrix: A is n-by-n */ + const Int Ap [ ], /* size n+1 */ + const Int Ai [ ], /* size nz = Ap [n] */ + + /* output matrix R: */ + Int Rp [ ], /* size n+1 */ + Int Ri [ ], /* size nz (or less, if duplicates present) */ + + Int W [ ], /* workspace of size n */ + Int Flag [ ] /* workspace of size n */ +) +{ + + /* --------------------------------------------------------------------- */ + /* local variables */ + /* --------------------------------------------------------------------- */ + + Int i, j, p, p2 ; + + ASSERT (AMD_valid (n, n, Ap, Ai) != AMD_INVALID) ; + + /* --------------------------------------------------------------------- */ + /* count the entries in each row of A (excluding duplicates) */ + /* --------------------------------------------------------------------- */ + + for (i = 0 ; i < n ; i++) + { + W [i] = 0 ; /* # of nonzeros in row i (excl duplicates) */ + Flag [i] = EMPTY ; /* Flag [i] = j if i appears in column j */ + } + for (j = 0 ; j < n ; j++) + { + p2 = Ap [j+1] ; + for (p = Ap [j] ; p < p2 ; p++) + { + i = Ai [p] ; + if (Flag [i] != j) + { + /* row index i has not yet appeared in column j */ + W [i]++ ; /* one more entry in row i */ + Flag [i] = j ; /* flag row index i as appearing in col j*/ + } + } + } + + /* --------------------------------------------------------------------- */ + /* compute the row pointers for R */ + /* --------------------------------------------------------------------- */ + + Rp [0] = 0 ; + for (i = 0 ; i < n ; i++) + { + Rp [i+1] = Rp [i] + W [i] ; + } + for (i = 0 ; i < n ; i++) + { + W [i] = Rp [i] ; + Flag [i] = EMPTY ; + } + + /* --------------------------------------------------------------------- */ + /* construct the row form matrix R */ + /* --------------------------------------------------------------------- */ + + /* R = row form of pattern of A */ + for (j = 0 ; j < n ; j++) + { + p2 = Ap [j+1] ; + for (p = Ap [j] ; p < p2 ; p++) + { + i = Ai [p] ; + if (Flag [i] != j) + { + /* row index i has not yet appeared in column j */ + Ri [W [i]++] = j ; /* put col j in row i */ + Flag [i] = j ; /* flag row index i as appearing in col j*/ + } + } + } + +#ifndef NDEBUG + ASSERT (AMD_valid (n, n, Rp, Ri) == AMD_OK) ; + for (j = 0 ; j < n ; j++) + { + ASSERT (W [j] == Rp [j+1]) ; + } +#endif +} diff --git a/resources/3rdparty/glpk-4.57/src/amd/amd_valid.c b/resources/3rdparty/glpk-4.57/src/amd/amd_valid.c new file mode 100644 index 000000000..e9e2e5ab6 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/amd/amd_valid.c @@ -0,0 +1,93 @@ +/* ========================================================================= */ +/* === AMD_valid =========================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* Check if a column-form matrix is valid or not. The matrix A is + * n_row-by-n_col. The row indices of entries in column j are in + * Ai [Ap [j] ... Ap [j+1]-1]. Required conditions are: + * + * n_row >= 0 + * n_col >= 0 + * nz = Ap [n_col] >= 0 number of entries in the matrix + * Ap [0] == 0 + * Ap [j] <= Ap [j+1] for all j in the range 0 to n_col. + * Ai [0 ... nz-1] must be in the range 0 to n_row-1. + * + * If any of the above conditions hold, AMD_INVALID is returned. If the + * following condition holds, AMD_OK_BUT_JUMBLED is returned (a warning, + * not an error): + * + * row indices in Ai [Ap [j] ... Ap [j+1]-1] are not sorted in ascending + * order, and/or duplicate entries exist. + * + * Otherwise, AMD_OK is returned. + * + * In v1.2 and earlier, this function returned TRUE if the matrix was valid + * (now returns AMD_OK), or FALSE otherwise (now returns AMD_INVALID or + * AMD_OK_BUT_JUMBLED). + */ + +#include "amd_internal.h" + +GLOBAL Int AMD_valid +( + /* inputs, not modified on output: */ + Int n_row, /* A is n_row-by-n_col */ + Int n_col, + const Int Ap [ ], /* column pointers of A, of size n_col+1 */ + const Int Ai [ ] /* row indices of A, of size nz = Ap [n_col] */ +) +{ + Int nz, j, p1, p2, ilast, i, p, result = AMD_OK ; + + if (n_row < 0 || n_col < 0 || Ap == NULL || Ai == NULL) + { + return (AMD_INVALID) ; + } + nz = Ap [n_col] ; + if (Ap [0] != 0 || nz < 0) + { + /* column pointers must start at Ap [0] = 0, and Ap [n] must be >= 0 */ + AMD_DEBUG0 (("column 0 pointer bad or nz < 0\n")) ; + return (AMD_INVALID) ; + } + for (j = 0 ; j < n_col ; j++) + { + p1 = Ap [j] ; + p2 = Ap [j+1] ; + AMD_DEBUG2 (("\nColumn: "ID" p1: "ID" p2: "ID"\n", j, p1, p2)) ; + if (p1 > p2) + { + /* column pointers must be ascending */ + AMD_DEBUG0 (("column "ID" pointer bad\n", j)) ; + return (AMD_INVALID) ; + } + ilast = EMPTY ; + for (p = p1 ; p < p2 ; p++) + { + i = Ai [p] ; + AMD_DEBUG3 (("row: "ID"\n", i)) ; + if (i < 0 || i >= n_row) + { + /* row index out of range */ + AMD_DEBUG0 (("index out of range, col "ID" row "ID"\n", j, i)); + return (AMD_INVALID) ; + } + if (i <= ilast) + { + /* row index unsorted, or duplicate entry present */ + AMD_DEBUG1 (("index unsorted/dupl col "ID" row "ID"\n", j, i)); + result = AMD_OK_BUT_JUMBLED ; + } + ilast = i ; + } + } + return (result) ; +} diff --git a/resources/3rdparty/glpk-4.57/src/avl.c b/resources/3rdparty/glpk-4.57/src/avl.c new file mode 100644 index 000000000..c9b7f2203 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/avl.c @@ -0,0 +1,406 @@ +/* avl.c (binary search tree) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "avl.h" +#include "dmp.h" +#include "env.h" + +struct AVL +{ /* AVL tree (Adelson-Velsky & Landis binary search tree) */ + DMP *pool; + /* memory pool for allocating nodes */ + AVLNODE *root; + /* pointer to the root node */ + int (*fcmp)(void *info, const void *key1, const void *key2); + /* application-defined key comparison routine */ + void *info; + /* transit pointer passed to the routine fcmp */ + int size; + /* the tree size (the total number of nodes) */ + int height; + /* the tree height */ +}; + +struct AVLNODE +{ /* node of AVL tree */ + const void *key; + /* pointer to the node key (data structure for representing keys + is supplied by the application) */ + int rank; + /* node rank = relative position of the node in its own subtree = + the number of nodes in the left subtree plus one */ + int type; + /* reserved for the application specific information */ + void *link; + /* reserved for the application specific information */ + AVLNODE *up; + /* pointer to the parent node */ + short int flag; + /* node flag: + 0 - this node is the left child of its parent (or this node is + the root of the tree and has no parent) + 1 - this node is the right child of its parent */ + short int bal; + /* node balance = the difference between heights of the right and + left subtrees: + -1 - the left subtree is higher than the right one; + 0 - the left and right subtrees have the same height; + +1 - the left subtree is lower than the right one */ + AVLNODE *left; + /* pointer to the root of the left subtree */ + AVLNODE *right; + /* pointer to the root of the right subtree */ +}; + +AVL *avl_create_tree(int (*fcmp)(void *info, const void *key1, + const void *key2), void *info) +{ /* create AVL tree */ + AVL *tree; + tree = xmalloc(sizeof(AVL)); + tree->pool = dmp_create_pool(); + tree->root = NULL; + tree->fcmp = fcmp; + tree->info = info; + tree->size = 0; + tree->height = 0; + return tree; +} + +int avl_strcmp(void *info, const void *key1, const void *key2) +{ /* compare character string keys */ + xassert(info == info); + return strcmp(key1, key2); +} + +static AVLNODE *rotate_subtree(AVL *tree, AVLNODE *node); + +AVLNODE *avl_insert_node(AVL *tree, const void *key) +{ /* insert new node into AVL tree */ + AVLNODE *p, *q, *r; + short int flag; + /* find an appropriate point for insertion */ + p = NULL; q = tree->root; + while (q != NULL) + { p = q; + if (tree->fcmp(tree->info, key, p->key) <= 0) + { flag = 0; + q = p->left; + p->rank++; + } + else + { flag = 1; + q = p->right; + } + } + /* create new node and insert it into the tree */ + r = dmp_get_atom(tree->pool, sizeof(AVLNODE)); + r->key = key; r->type = 0; r->link = NULL; + r->rank = 1; r->up = p; + r->flag = (short int)(p == NULL ? 0 : flag); + r->bal = 0; r->left = NULL; r->right = NULL; + tree->size++; + if (p == NULL) + tree->root = r; + else + if (flag == 0) p->left = r; else p->right = r; + /* go upstairs to the root and correct all subtrees affected by + insertion */ + while (p != NULL) + { if (flag == 0) + { /* the height of the left subtree of [p] is increased */ + if (p->bal > 0) + { p->bal = 0; + break; + } + if (p->bal < 0) + { rotate_subtree(tree, p); + break; + } + p->bal = -1; flag = p->flag; p = p->up; + } + else + { /* the height of the right subtree of [p] is increased */ + if (p->bal < 0) + { p->bal = 0; + break; + } + if (p->bal > 0) + { rotate_subtree(tree, p); + break; + } + p->bal = +1; flag = p->flag; p = p->up; + } + } + /* if the root has been reached, the height of the entire tree is + increased */ + if (p == NULL) tree->height++; + return r; +} + +void avl_set_node_type(AVLNODE *node, int type) +{ /* assign the type field of specified node */ + node->type = type; + return; +} + +void avl_set_node_link(AVLNODE *node, void *link) +{ /* assign the link field of specified node */ + node->link = link; + return; +} + +AVLNODE *avl_find_node(AVL *tree, const void *key) +{ /* find node in AVL tree */ + AVLNODE *p; + int c; + p = tree->root; + while (p != NULL) + { c = tree->fcmp(tree->info, key, p->key); + if (c == 0) break; + p = (c < 0 ? p->left : p->right); + } + return p; +} + +int avl_get_node_type(AVLNODE *node) +{ /* retrieve the type field of specified node */ + return node->type; +} + +void *avl_get_node_link(AVLNODE *node) +{ /* retrieve the link field of specified node */ + return node->link; +} + +static AVLNODE *find_next_node(AVL *tree, AVLNODE *node) +{ /* find next node in AVL tree */ + AVLNODE *p, *q; + if (tree->root == NULL) return NULL; + p = node; + q = (p == NULL ? tree->root : p->right); + if (q == NULL) + { /* go upstairs from the left subtree */ + for (;;) + { q = p->up; + if (q == NULL) break; + if (p->flag == 0) break; + p = q; + } + } + else + { /* go downstairs into the right subtree */ + for (;;) + { p = q->left; + if (p == NULL) break; + q = p; + } + } + return q; +} + +void avl_delete_node(AVL *tree, AVLNODE *node) +{ /* delete specified node from AVL tree */ + AVLNODE *f, *p, *q, *r, *s, *x, *y; + short int flag; + p = node; + /* if both subtrees of the specified node are non-empty, the node + should be interchanged with the next one, at least one subtree + of which is always empty */ + if (p->left == NULL || p->right == NULL) goto skip; + f = p->up; q = p->left; + r = find_next_node(tree, p); s = r->right; + if (p->right == r) + { if (f == NULL) + tree->root = r; + else + if (p->flag == 0) f->left = r; else f->right = r; + r->rank = p->rank; r->up = f; + r->flag = p->flag; r->bal = p->bal; + r->left = q; r->right = p; + q->up = r; + p->rank = 1; p->up = r; p->flag = 1; + p->bal = (short int)(s == NULL ? 0 : +1); + p->left = NULL; p->right = s; + if (s != NULL) s->up = p; + } + else + { x = p->right; y = r->up; + if (f == NULL) + tree->root = r; + else + if (p->flag == 0) f->left = r; else f->right = r; + r->rank = p->rank; r->up = f; + r->flag = p->flag; r->bal = p->bal; + r->left = q; r->right = x; + q->up = r; x->up = r; y->left = p; + p->rank = 1; p->up = y; p->flag = 0; + p->bal = (short int)(s == NULL ? 0 : +1); + p->left = NULL; p->right = s; + if (s != NULL) s->up = p; + } +skip: /* now the specified node [p] has at least one empty subtree; + go upstairs to the root and adjust the rank field of all nodes + affected by deletion */ + q = p; f = q->up; + while (f != NULL) + { if (q->flag == 0) f->rank--; + q = f; f = q->up; + } + /* delete the specified node from the tree */ + f = p->up; flag = p->flag; + q = p->left != NULL ? p->left : p->right; + if (f == NULL) + tree->root = q; + else + if (flag == 0) f->left = q; else f->right = q; + if (q != NULL) q->up = f, q->flag = flag; + tree->size--; + /* go upstairs to the root and correct all subtrees affected by + deletion */ + while (f != NULL) + { if (flag == 0) + { /* the height of the left subtree of [f] is decreased */ + if (f->bal == 0) + { f->bal = +1; + break; + } + if (f->bal < 0) + f->bal = 0; + else + { f = rotate_subtree(tree, f); + if (f->bal < 0) break; + } + flag = f->flag; f = f->up; + } + else + { /* the height of the right subtree of [f] is decreased */ + if (f->bal == 0) + { f->bal = -1; + break; + } + if (f->bal > 0) + f->bal = 0; + else + { f = rotate_subtree(tree, f); + if (f->bal > 0) break; + } + flag = f->flag; f = f->up; + } + } + /* if the root has been reached, the height of the entire tree is + decreased */ + if (f == NULL) tree->height--; + /* returns the deleted node to the memory pool */ + dmp_free_atom(tree->pool, p, sizeof(AVLNODE)); + return; +} + +static AVLNODE *rotate_subtree(AVL *tree, AVLNODE *node) +{ /* restore balance of AVL subtree */ + AVLNODE *f, *p, *q, *r, *x, *y; + xassert(node != NULL); + p = node; + if (p->bal < 0) + { /* perform negative (left) rotation */ + f = p->up; q = p->left; r = q->right; + if (q->bal <= 0) + { /* perform single negative rotation */ + if (f == NULL) + tree->root = q; + else + if (p->flag == 0) f->left = q; else f->right = q; + p->rank -= q->rank; + q->up = f; q->flag = p->flag; q->bal++; q->right = p; + p->up = q; p->flag = 1; + p->bal = (short int)(-q->bal); p->left = r; + if (r != NULL) r->up = p, r->flag = 0; + node = q; + } + else + { /* perform double negative rotation */ + x = r->left; y = r->right; + if (f == NULL) + tree->root = r; + else + if (p->flag == 0) f->left = r; else f->right = r; + p->rank -= (q->rank + r->rank); + r->rank += q->rank; + p->bal = (short int)(r->bal >= 0 ? 0 : +1); + q->bal = (short int)(r->bal <= 0 ? 0 : -1); + r->up = f; r->flag = p->flag; r->bal = 0; + r->left = q; r->right = p; + p->up = r; p->flag = 1; p->left = y; + q->up = r; q->flag = 0; q->right = x; + if (x != NULL) x->up = q, x->flag = 1; + if (y != NULL) y->up = p, y->flag = 0; + node = r; + } + } + else + { /* perform positive (right) rotation */ + f = p->up; q = p->right; r = q->left; + if (q->bal >= 0) + { /* perform single positive rotation */ + if (f == NULL) + tree->root = q; + else + if (p->flag == 0) f->left = q; else f->right = q; + q->rank += p->rank; + q->up = f; q->flag = p->flag; q->bal--; q->left = p; + p->up = q; p->flag = 0; + p->bal = (short int)(-q->bal); p->right = r; + if (r != NULL) r->up = p, r->flag = 1; + node = q; + } + else + { /* perform double positive rotation */ + x = r->left; y = r->right; + if (f == NULL) + tree->root = r; + else + if (p->flag == 0) f->left = r; else f->right = r; + q->rank -= r->rank; + r->rank += p->rank; + p->bal = (short int)(r->bal <= 0 ? 0 : -1); + q->bal = (short int)(r->bal >= 0 ? 0 : +1); + r->up = f; r->flag = p->flag; r->bal = 0; + r->left = p; r->right = q; + p->up = r; p->flag = 0; p->right = x; + q->up = r; q->flag = 1; q->left = y; + if (x != NULL) x->up = p, x->flag = 1; + if (y != NULL) y->up = q, y->flag = 0; + node = r; + } + } + return node; +} + +void avl_delete_tree(AVL *tree) +{ /* delete AVL tree */ + dmp_delete_pool(tree->pool); + xfree(tree); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/avl.h b/resources/3rdparty/glpk-4.57/src/avl.h new file mode 100644 index 000000000..c4144c293 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/avl.h @@ -0,0 +1,74 @@ +/* avl.h (binary search tree) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef AVL_H +#define AVL_H + +typedef struct AVL AVL; +typedef struct AVLNODE AVLNODE; + +#define avl_create_tree _glp_avl_create_tree +AVL *avl_create_tree(int (*fcmp)(void *info, const void *key1, + const void *key2), void *info); +/* create AVL tree */ + +#define avl_strcmp _glp_avl_strcmp +int avl_strcmp(void *info, const void *key1, const void *key2); +/* compare character string keys */ + +#define avl_insert_node _glp_avl_insert_node +AVLNODE *avl_insert_node(AVL *tree, const void *key); +/* insert new node into AVL tree */ + +#define avl_set_node_type _glp_avl_set_node_type +void avl_set_node_type(AVLNODE *node, int type); +/* assign the type field of specified node */ + +#define avl_set_node_link _glp_avl_set_node_link +void avl_set_node_link(AVLNODE *node, void *link); +/* assign the link field of specified node */ + +#define avl_find_node _glp_avl_find_node +AVLNODE *avl_find_node(AVL *tree, const void *key); +/* find node in AVL tree */ + +#define avl_get_node_type _glp_avl_get_node_type +int avl_get_node_type(AVLNODE *node); +/* retrieve the type field of specified node */ + +#define avl_get_node_link _glp_avl_get_node_link +void *avl_get_node_link(AVLNODE *node); +/* retrieve the link field of specified node */ + +#define avl_delete_node _glp_avl_delete_node +void avl_delete_node(AVL *tree, AVLNODE *node); +/* delete specified node from AVL tree */ + +#define avl_delete_tree _glp_avl_delete_tree +void avl_delete_tree(AVL *tree); +/* delete AVL tree */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bfd.c b/resources/3rdparty/glpk-4.57/src/bfd.c new file mode 100644 index 000000000..9e70619dc --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bfd.c @@ -0,0 +1,508 @@ +/* bfd.c (LP basis factorization driver) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2007, 2014 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "glpk.h" +#include "env.h" +#include "bfd.h" +#include "fhvint.h" +#include "scfint.h" +#ifdef GLP_DEBUG +#include "glpspm.h" +#endif + +struct BFD +{ /* LP basis factorization driver */ + int valid; + /* factorization is valid only if this flag is set */ + int type; + /* type of factorization used: + 0 - interface not established yet + 1 - FHV-factorization + 2 - Schur-complement-based factorization */ + union + { void *none; /* type = 0 */ + FHVINT *fhvi; /* type = 1 */ + SCFINT *scfi; /* type = 2 */ + } u; + /* interface to factorization of LP basis */ + glp_bfcp parm; + /* factorization control parameters */ +#ifdef GLP_DEBUG + SPM *B; + /* current basis (for testing/debugging only) */ +#endif + int upd_cnt; + /* factorization update count */ +#if 1 /* 21/IV-2014 */ + double b_norm; + /* 1-norm of matrix B */ + double i_norm; + /* estimated 1-norm of matrix inv(B) */ +#endif +}; + +BFD *bfd_create_it(void) +{ /* create LP basis factorization */ + BFD *bfd; +#ifdef GLP_DEBUG + xprintf("bfd_create_it: warning: debugging version used\n"); +#endif + bfd = talloc(1, BFD); + bfd->valid = 0; + bfd->type = 0; + bfd->u.none = NULL; + bfd_set_bfcp(bfd, NULL); +#ifdef GLP_DEBUG + bfd->B = NULL; +#endif + bfd->upd_cnt = 0; + return bfd; +} + +#if 0 /* 08/III-2014 */ +void bfd_set_parm(BFD *bfd, const void *parm) +{ /* change LP basis factorization control parameters */ + memcpy(&bfd->parm, parm, sizeof(glp_bfcp)); + return; +} +#endif + +void bfd_get_bfcp(BFD *bfd, void /* glp_bfcp */ *parm) +{ /* retrieve LP basis factorization control parameters */ + memcpy(parm, &bfd->parm, sizeof(glp_bfcp)); + return; +} + +void bfd_set_bfcp(BFD *bfd, const void /* glp_bfcp */ *parm) +{ /* change LP basis factorization control parameters */ + if (parm == NULL) + { /* reset to default */ + memset(&bfd->parm, 0, sizeof(glp_bfcp)); + bfd->parm.type = GLP_BF_LUF + GLP_BF_FT; + bfd->parm.piv_tol = 0.10; + bfd->parm.piv_lim = 4; + bfd->parm.suhl = 1; + bfd->parm.eps_tol = DBL_EPSILON; + bfd->parm.nfs_max = 100; + bfd->parm.nrs_max = 70; + } + else + memcpy(&bfd->parm, parm, sizeof(glp_bfcp)); + return; +} + +#if 1 /* 21/IV-2014 */ +struct bfd_info +{ BFD *bfd; + int (*col)(void *info, int j, int ind[], double val[]); + void *info; +}; + +static int bfd_col(void *info_, int j, int ind[], double val[]) +{ struct bfd_info *info = info_; + int t, len; + double sum; + len = info->col(info->info, j, ind, val); + sum = 0.0; + for (t = 1; t <= len; t++) + { if (val[t] >= 0.0) + sum += val[t]; + else + sum -= val[t]; + } + if (info->bfd->b_norm < sum) + info->bfd->b_norm = sum; + return len; +} +#endif + +int bfd_factorize(BFD *bfd, int m, /*const int bh[],*/ int (*col1) + (void *info, int j, int ind[], double val[]), void *info1) +{ /* compute LP basis factorization */ +#if 1 /* 21/IV-2014 */ + struct bfd_info info; +#endif + int type, ret; + /*xassert(bh == bh);*/ + /* invalidate current factorization */ + bfd->valid = 0; + /* determine required factorization type */ + switch (bfd->parm.type) + { case GLP_BF_LUF + GLP_BF_FT: + type = 1; + break; + case GLP_BF_LUF + GLP_BF_BG: + case GLP_BF_LUF + GLP_BF_GR: + case GLP_BF_BTF + GLP_BF_BG: + case GLP_BF_BTF + GLP_BF_GR: + type = 2; + break; + default: + xassert(bfd != bfd); + } + /* delete factorization interface, if necessary */ + switch (bfd->type) + { case 0: + break; + case 1: + if (type != 1) + { bfd->type = 0; + fhvint_delete(bfd->u.fhvi); + bfd->u.fhvi = NULL; + } + break; + case 2: + if (type != 2) + { bfd->type = 0; + scfint_delete(bfd->u.scfi); + bfd->u.scfi = NULL; + } + break; + default: + xassert(bfd != bfd); + } + /* establish factorization interface, if necessary */ + if (bfd->type == 0) + { switch (type) + { case 1: + bfd->type = 1; + xassert(bfd->u.fhvi == NULL); + bfd->u.fhvi = fhvint_create(); + break; + case 2: + bfd->type = 2; + xassert(bfd->u.scfi == NULL); + if (!(bfd->parm.type & GLP_BF_BTF)) + bfd->u.scfi = scfint_create(1); + else + bfd->u.scfi = scfint_create(2); + break; + default: + xassert(type != type); + } + } + /* try to compute factorization */ +#if 1 /* 21/IV-2014 */ + bfd->b_norm = bfd->i_norm = 0.0; + info.bfd = bfd; + info.col = col1; + info.info = info1; +#endif + switch (bfd->type) + { case 1: + bfd->u.fhvi->lufi->sgf_piv_tol = bfd->parm.piv_tol; + bfd->u.fhvi->lufi->sgf_piv_lim = bfd->parm.piv_lim; + bfd->u.fhvi->lufi->sgf_suhl = bfd->parm.suhl; + bfd->u.fhvi->lufi->sgf_eps_tol = bfd->parm.eps_tol; + bfd->u.fhvi->nfs_max = bfd->parm.nfs_max; + ret = fhvint_factorize(bfd->u.fhvi, m, bfd_col, &info); +#if 1 /* FIXME */ + if (ret == 0) + bfd->i_norm = fhvint_estimate(bfd->u.fhvi); + else + ret = BFD_ESING; +#endif + break; + case 2: + if (bfd->u.scfi->scf.type == 1) + { bfd->u.scfi->u.lufi->sgf_piv_tol = bfd->parm.piv_tol; + bfd->u.scfi->u.lufi->sgf_piv_lim = bfd->parm.piv_lim; + bfd->u.scfi->u.lufi->sgf_suhl = bfd->parm.suhl; + bfd->u.scfi->u.lufi->sgf_eps_tol = bfd->parm.eps_tol; + } + else if (bfd->u.scfi->scf.type == 2) + { bfd->u.scfi->u.btfi->sgf_piv_tol = bfd->parm.piv_tol; + bfd->u.scfi->u.btfi->sgf_piv_lim = bfd->parm.piv_lim; + bfd->u.scfi->u.btfi->sgf_suhl = bfd->parm.suhl; + bfd->u.scfi->u.btfi->sgf_eps_tol = bfd->parm.eps_tol; + } + else + xassert(bfd != bfd); + bfd->u.scfi->nn_max = bfd->parm.nrs_max; + ret = scfint_factorize(bfd->u.scfi, m, bfd_col, &info); +#if 1 /* FIXME */ + if (ret == 0) + bfd->i_norm = scfint_estimate(bfd->u.scfi); + else + ret = BFD_ESING; +#endif + break; + default: + xassert(bfd != bfd); + } +#ifdef GLP_DEBUG + /* save specified LP basis */ + if (bfd->B != NULL) + spm_delete_mat(bfd->B); + bfd->B = spm_create_mat(m, m); + { int *ind = talloc(1+m, int); + double *val = talloc(1+m, double); + int j, k, len; + for (j = 1; j <= m; j++) + { len = col(info, j, ind, val); + for (k = 1; k <= len; k++) + spm_new_elem(bfd->B, ind[k], j, val[k]); + } + tfree(ind); + tfree(val); + } +#endif + if (ret == 0) + { /* factorization has been successfully computed */ + double cond; + bfd->valid = 1; +#ifdef GLP_DEBUG + cond = bfd_condest(bfd); + if (cond > 1e9) + xprintf("bfd_factorize: warning: cond(B) = %g\n", cond); +#endif + } +#ifdef GLP_DEBUG + xprintf("bfd_factorize: m = %d; ret = %d\n", m, ret); +#endif + bfd->upd_cnt = 0; + return ret; +} + +#if 0 /* 21/IV-2014 */ +double bfd_estimate(BFD *bfd) +{ /* estimate 1-norm of inv(B) */ + double norm; + xassert(bfd->valid); + xassert(bfd->upd_cnt == 0); + switch (bfd->type) + { case 1: + norm = fhvint_estimate(bfd->u.fhvi); + break; + case 2: + norm = scfint_estimate(bfd->u.scfi); + break; + default: + xassert(bfd != bfd); + } + return norm; +} +#endif + +#if 1 /* 21/IV-2014 */ +double bfd_condest(BFD *bfd) +{ /* estimate condition of B */ + double cond; + xassert(bfd->valid); + /*xassert(bfd->upd_cnt == 0);*/ + cond = bfd->b_norm * bfd->i_norm; + if (cond < 1.0) + cond = 1.0; + return cond; +} +#endif + +void bfd_ftran(BFD *bfd, double x[]) +{ /* perform forward transformation (solve system B * x = b) */ +#ifdef GLP_DEBUG + SPM *B = bfd->B; + int m = B->m; + double *b = talloc(1+m, double); + SPME *e; + int k; + double s, relerr, maxerr; + for (k = 1; k <= m; k++) + b[k] = x[k]; +#endif + xassert(bfd->valid); + switch (bfd->type) + { case 1: + fhvint_ftran(bfd->u.fhvi, x); + break; + case 2: + scfint_ftran(bfd->u.scfi, x); + break; + default: + xassert(bfd != bfd); + } +#ifdef GLP_DEBUG + maxerr = 0.0; + for (k = 1; k <= m; k++) + { s = 0.0; + for (e = B->row[k]; e != NULL; e = e->r_next) + s += e->val * x[e->j]; + relerr = (b[k] - s) / (1.0 + fabs(b[k])); + if (maxerr < relerr) + maxerr = relerr; + } + if (maxerr > 1e-8) + xprintf("bfd_ftran: maxerr = %g; relative error too large\n", + maxerr); + tfree(b); +#endif + return; +} + +void bfd_btran(BFD *bfd, double x[]) +{ /* perform backward transformation (solve system B'* x = b) */ +#ifdef GLP_DEBUG + SPM *B = bfd->B; + int m = B->m; + double *b = talloc(1+m, double); + SPME *e; + int k; + double s, relerr, maxerr; + for (k = 1; k <= m; k++) + b[k] = x[k]; +#endif + xassert(bfd->valid); + switch (bfd->type) + { case 1: + fhvint_btran(bfd->u.fhvi, x); + break; + case 2: + scfint_btran(bfd->u.scfi, x); + break; + default: + xassert(bfd != bfd); + } +#ifdef GLP_DEBUG + maxerr = 0.0; + for (k = 1; k <= m; k++) + { s = 0.0; + for (e = B->col[k]; e != NULL; e = e->c_next) + s += e->val * x[e->i]; + relerr = (b[k] - s) / (1.0 + fabs(b[k])); + if (maxerr < relerr) + maxerr = relerr; + } + if (maxerr > 1e-8) + xprintf("bfd_btran: maxerr = %g; relative error too large\n", + maxerr); + tfree(b); +#endif + return; +} + +int bfd_update(BFD *bfd, int j, int len, const int ind[], const double + val[]) +{ /* update LP basis factorization */ + int ret; + xassert(bfd->valid); + switch (bfd->type) + { case 1: + ret = fhvint_update(bfd->u.fhvi, j, len, ind, val); +#if 1 /* FIXME */ + switch (ret) + { case 0: + break; + case 1: + ret = BFD_ESING; + break; + case 2: + case 3: + ret = BFD_ECOND; + break; + case 4: + ret = BFD_ELIMIT; + break; + case 5: + ret = BFD_ECHECK; + break; + default: + xassert(ret != ret); + } +#endif + break; + case 2: + switch (bfd->parm.type & 0x0F) + { case GLP_BF_BG: + ret = scfint_update(bfd->u.scfi, 1, j, len, ind, val); + break; + case GLP_BF_GR: + ret = scfint_update(bfd->u.scfi, 2, j, len, ind, val); + break; + default: + xassert(bfd != bfd); + } +#if 1 /* FIXME */ + switch (ret) + { case 0: + break; + case 1: + ret = BFD_ELIMIT; + break; + case 2: + ret = BFD_ECOND; + break; + default: + xassert(ret != ret); + } +#endif + break; + default: + xassert(bfd != bfd); + } + if (ret != 0) + { /* updating factorization failed */ + bfd->valid = 0; + } +#ifdef GLP_DEBUG + /* save updated LP basis */ + { SPME *e; + int k; + for (e = bfd->B->col[j]; e != NULL; e = e->c_next) + e->val = 0.0; + spm_drop_zeros(bfd->B, 0.0); + for (k = 1; k <= len; k++) + spm_new_elem(bfd->B, ind[k], j, val[k]); + } +#endif + if (ret == 0) + bfd->upd_cnt++; + return ret; +} + +int bfd_get_count(BFD *bfd) +{ /* determine factorization update count */ + return bfd->upd_cnt; +} + +void bfd_delete_it(BFD *bfd) +{ /* delete LP basis factorization */ + switch (bfd->type) + { case 0: + break; + case 1: + fhvint_delete(bfd->u.fhvi); + break; + case 2: + scfint_delete(bfd->u.scfi); + break; + default: + xassert(bfd != bfd); + } +#ifdef GLP_DEBUG + if (bfd->B != NULL) + spm_delete_mat(bfd->B); +#endif + tfree(bfd); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bfd.h b/resources/3rdparty/glpk-4.57/src/bfd.h new file mode 100644 index 000000000..1e18e561d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bfd.h @@ -0,0 +1,91 @@ +/* bfd.h (LP basis factorization driver) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef BFD_H +#define BFD_H + +typedef struct BFD BFD; + +/* return codes: */ +#define BFD_ESING 1 /* singular matrix */ +#define BFD_ECOND 2 /* ill-conditioned matrix */ +#define BFD_ECHECK 3 /* insufficient accuracy */ +#define BFD_ELIMIT 4 /* update limit reached */ +#if 0 /* 05/III-2014 */ +#define BFD_EROOM 5 /* SVA overflow */ +#endif + +#define bfd_create_it _glp_bfd_create_it +BFD *bfd_create_it(void); +/* create LP basis factorization */ + +#if 0 /* 08/III-2014 */ +#define bfd_set_parm _glp_bfd_set_parm +void bfd_set_parm(BFD *bfd, const void *parm); +/* change LP basis factorization control parameters */ +#endif + +#define bfd_get_bfcp _glp_bfd_get_bfcp +void bfd_get_bfcp(BFD *bfd, void /* glp_bfcp */ *parm); +/* retrieve LP basis factorization control parameters */ + +#define bfd_set_bfcp _glp_bfd_set_bfcp +void bfd_set_bfcp(BFD *bfd, const void /* glp_bfcp */ *parm); +/* change LP basis factorization control parameters */ + +#define bfd_factorize _glp_bfd_factorize +int bfd_factorize(BFD *bfd, int m, /*const int bh[],*/ int (*col) + (void *info, int j, int ind[], double val[]), void *info); +/* compute LP basis factorization */ + +#if 1 /* 21/IV-2014 */ +#define bfd_condest _glp_bfd_condest +double bfd_condest(BFD *bfd); +/* estimate condition of B */ +#endif + +#define bfd_ftran _glp_bfd_ftran +void bfd_ftran(BFD *bfd, double x[]); +/* perform forward transformation (solve system B*x = b) */ + +#define bfd_btran _glp_bfd_btran +void bfd_btran(BFD *bfd, double x[]); +/* perform backward transformation (solve system B'*x = b) */ + +#define bfd_update _glp_bfd_update +int bfd_update(BFD *bfd, int j, int len, const int ind[], const double + val[]); +/* update LP basis factorization */ + +#define bfd_get_count _glp_bfd_get_count +int bfd_get_count(BFD *bfd); +/* determine factorization update count */ + +#define bfd_delete_it _glp_bfd_delete_it +void bfd_delete_it(BFD *bfd); +/* delete LP basis factorization */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/btf.c b/resources/3rdparty/glpk-4.57/src/bflib/btf.c new file mode 100644 index 000000000..993c9ca17 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/btf.c @@ -0,0 +1,569 @@ +/* btf.c (sparse block triangular LU-factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2013-2014 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "btf.h" +#include "env.h" +#include "luf.h" +#include "mc13d.h" +#include "mc21a.h" + +/*********************************************************************** +* btf_store_a_cols - store pattern of matrix A in column-wise format +* +* This routine stores the pattern (that is, only indices of non-zero +* elements) of the original matrix A in column-wise format. +* +* On exit the routine returns the number of non-zeros in matrix A. */ + +int btf_store_a_cols(BTF *btf, int (*col)(void *info, int j, int ind[], + double val[]), void *info, int ind[], double val[]) +{ int n = btf->n; + SVA *sva = btf->sva; + int *sv_ind = sva->ind; + int ac_ref = btf->ac_ref; + int *ac_ptr = &sva->ptr[ac_ref-1]; + int *ac_len = &sva->len[ac_ref-1]; + int j, len, ptr, nnz; + nnz = 0; + for (j = 1; j <= n; j++) + { /* get j-th column */ + len = col(info, j, ind, val); + xassert(0 <= len && len <= n); + /* reserve locations for j-th column */ + if (len > 0) + { if (sva->r_ptr - sva->m_ptr < len) + { sva_more_space(sva, len); + sv_ind = sva->ind; + } + sva_reserve_cap(sva, ac_ref+(j-1), len); + } + /* store pattern of j-th column */ + ptr = ac_ptr[j]; + memcpy(&sv_ind[ptr], &ind[1], len * sizeof(int)); + ac_len[j] = len; + nnz += len; + } + return nnz; +} + +/*********************************************************************** +* btf_make_blocks - permutations to block triangular form +* +* This routine analyzes the pattern of the original matrix A and +* determines permutation matrices P and Q such that A = P * A~* Q, +* where A~ is an upper block triangular matrix. +* +* On exit the routine returns symbolic rank of matrix A. */ + +int btf_make_blocks(BTF *btf) +{ int n = btf->n; + SVA *sva = btf->sva; + int *sv_ind = sva->ind; + int *pp_ind = btf->pp_ind; + int *pp_inv = btf->pp_inv; + int *qq_ind = btf->qq_ind; + int *qq_inv = btf->qq_inv; + int *beg = btf->beg; + int ac_ref = btf->ac_ref; + int *ac_ptr = &sva->ptr[ac_ref-1]; + int *ac_len = &sva->len[ac_ref-1]; + int i, j, rank, *iperm, *pr, *arp, *cv, *out, *ip, *lenr, *lowl, + *numb, *prev; + /* determine column permutation matrix M such that matrix A * M + * has zero-free diagonal */ + iperm = qq_inv; /* matrix M */ + pr = btf->p1_ind; /* working array */ + arp = btf->p1_inv; /* working array */ + cv = btf->q1_ind; /* working array */ + out = btf->q1_inv; /* working array */ + rank = mc21a(n, sv_ind, ac_ptr, ac_len, iperm, pr, arp, cv, out); + xassert(0 <= rank && rank <= n); + if (rank < n) + { /* A is structurally singular (rank is its symbolic rank) */ + goto done; + } + /* build pattern of matrix A * M */ + ip = pp_ind; /* working array */ + lenr = qq_ind; /* working array */ + for (j = 1; j <= n; j++) + { ip[j] = ac_ptr[iperm[j]]; + lenr[j] = ac_len[iperm[j]]; + } + /* determine symmetric permutation matrix S such that matrix + * S * (A * M) * S' = A~ is upper block triangular */ + lowl = btf->p1_ind; /* working array */ + numb = btf->p1_inv; /* working array */ + prev = btf->q1_ind; /* working array */ + btf->num = + mc13d(n, sv_ind, ip, lenr, pp_inv, beg, lowl, numb, prev); + xassert(beg[1] == 1); + beg[btf->num+1] = n+1; + /* A * M = S' * A~ * S ==> A = S' * A~ * (S * M') */ + /* determine permutation matrix P = S' */ + for (j = 1; j <= n; j++) + pp_ind[pp_inv[j]] = j; + /* determine permutation matrix Q = S * M' = P' * M' */ + for (i = 1; i <= n; i++) + qq_ind[i] = iperm[pp_inv[i]]; + for (i = 1; i <= n; i++) + qq_inv[qq_ind[i]] = i; +done: return rank; +} + +/*********************************************************************** +* btf_check_blocks - check structure of matrix A~ +* +* This routine checks that structure of upper block triangular matrix +* A~ is correct. +* +* NOTE: For testing/debugging only. */ + +void btf_check_blocks(BTF *btf) +{ int n = btf->n; + SVA *sva = btf->sva; + int *sv_ind = sva->ind; + int *pp_ind = btf->pp_ind; + int *pp_inv = btf->pp_inv; + int *qq_ind = btf->qq_ind; + int *qq_inv = btf->qq_inv; + int num = btf->num; + int *beg = btf->beg; + int ac_ref = btf->ac_ref; + int *ac_ptr = &sva->ptr[ac_ref-1]; + int *ac_len = &sva->len[ac_ref-1]; + int i, ii, j, jj, k, size, ptr, end, diag; + xassert(n > 0); + /* check permutation matrices P and Q */ + for (k = 1; k <= n; k++) + { xassert(1 <= pp_ind[k] && pp_ind[k] <= n); + xassert(pp_inv[pp_ind[k]] == k); + xassert(1 <= qq_ind[k] && qq_ind[k] <= n); + xassert(qq_inv[qq_ind[k]] == k); + } + /* check that matrix A~ is upper block triangular with non-zero + * diagonal */ + xassert(1 <= num && num <= n); + xassert(beg[1] == 1); + xassert(beg[num+1] == n+1); + /* walk thru blocks of A~ */ + for (k = 1; k <= num; k++) + { /* determine size of k-th block */ + size = beg[k+1] - beg[k]; + xassert(size >= 1); + /* walk thru columns of k-th block */ + for (jj = beg[k]; jj < beg[k+1]; jj++) + { diag = 0; + /* jj-th column of A~ = j-th column of A */ + j = qq_ind[jj]; + /* walk thru elements of j-th column of A */ + ptr = ac_ptr[j]; + end = ptr + ac_len[j]; + for (; ptr < end; ptr++) + { /* determine row index of a[i,j] */ + i = sv_ind[ptr]; + /* i-th row of A = ii-th row of A~ */ + ii = pp_ind[i]; + /* a~[ii,jj] should not be below k-th block */ + xassert(ii < beg[k+1]); + if (ii == jj) + { /* non-zero diagonal element of A~ encountered */ + diag = 1; + } + } + xassert(diag); + } + } + return; +} + +/*********************************************************************** +* btf_build_a_rows - build matrix A in row-wise format +* +* This routine builds the row-wise representation of matrix A in the +* right part of SVA using its column-wise representation. +* +* The working array len should have at least 1+n elements (len[0] is +* not used). */ + +void btf_build_a_rows(BTF *btf, int len[/*1+n*/]) +{ int n = btf->n; + SVA *sva = btf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int ar_ref = btf->ar_ref; + int *ar_ptr = &sva->ptr[ar_ref-1]; + int *ar_len = &sva->len[ar_ref-1]; + int ac_ref = btf->ac_ref; + int *ac_ptr = &sva->ptr[ac_ref-1]; + int *ac_len = &sva->len[ac_ref-1]; + int i, j, end, nnz, ptr, ptr1; + /* calculate the number of non-zeros in each row of matrix A and + * the total number of non-zeros */ + nnz = 0; + for (i = 1; i <= n; i++) + len[i] = 0; + for (j = 1; j <= n; j++) + { nnz += ac_len[j]; + for (end = (ptr = ac_ptr[j]) + ac_len[j]; ptr < end; ptr++) + len[sv_ind[ptr]]++; + } + /* we need at least nnz free locations in SVA */ + if (sva->r_ptr - sva->m_ptr < nnz) + { sva_more_space(sva, nnz); + sv_ind = sva->ind; + sv_val = sva->val; + } + /* reserve locations for rows of matrix A */ + for (i = 1; i <= n; i++) + { if (len[i] > 0) + sva_reserve_cap(sva, ar_ref-1+i, len[i]); + ar_len[i] = len[i]; + } + /* walk thru columns of matrix A and build its rows */ + for (j = 1; j <= n; j++) + { for (end = (ptr = ac_ptr[j]) + ac_len[j]; ptr < end; ptr++) + { i = sv_ind[ptr]; + sv_ind[ptr1 = ar_ptr[i] + (--len[i])] = j; + sv_val[ptr1] = sv_val[ptr]; + } + } + return; +} + +/*********************************************************************** +* btf_a_solve - solve system A * x = b +* +* This routine solves the system A * x = b, where A is the original +* matrix. +* +* On entry the array b should contain elements of the right-hand size +* vector b in locations b[1], ..., b[n], where n is the order of the +* matrix A. On exit the array x will contain elements of the solution +* vector in locations x[1], ..., x[n]. Note that the array b will be +* clobbered on exit. +* +* The routine also uses locations [1], ..., [max_size] of two working +* arrays w1 and w2, where max_size is the maximal size of diagonal +* blocks in BT-factorization (max_size <= n). */ + +void btf_a_solve(BTF *btf, double b[/*1+n*/], double x[/*1+n*/], + double w1[/*1+n*/], double w2[/*1+n*/]) +{ SVA *sva = btf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int *pp_inv = btf->pp_inv; + int *qq_ind = btf->qq_ind; + int num = btf->num; + int *beg = btf->beg; + int ac_ref = btf->ac_ref; + int *ac_ptr = &sva->ptr[ac_ref-1]; + int *ac_len = &sva->len[ac_ref-1]; + double *bb = w1; + double *xx = w2; + LUF luf; + int i, j, jj, k, beg_k, flag; + double t; + for (k = num; k >= 1; k--) + { /* determine order of diagonal block A~[k,k] */ + luf.n = beg[k+1] - (beg_k = beg[k]); + if (luf.n == 1) + { /* trivial case */ + /* solve system A~[k,k] * X[k] = B[k] */ + t = x[qq_ind[beg_k]] = + b[pp_inv[beg_k]] / btf->vr_piv[beg_k]; + /* substitute X[k] into other equations */ + if (t != 0.0) + { int ptr = ac_ptr[qq_ind[beg_k]]; + int end = ptr + ac_len[qq_ind[beg_k]]; + for (; ptr < end; ptr++) + b[sv_ind[ptr]] -= sv_val[ptr] * t; + } + } + else + { /* general case */ + /* construct B[k] */ + flag = 0; + for (i = 1; i <= luf.n; i++) + { if ((bb[i] = b[pp_inv[i + (beg_k-1)]]) != 0.0) + flag = 1; + } + /* solve system A~[k,k] * X[k] = B[k] */ + if (!flag) + { /* B[k] = 0, so X[k] = 0 */ + for (j = 1; j <= luf.n; j++) + x[qq_ind[j + (beg_k-1)]] = 0.0; + continue; + } + luf.sva = sva; + luf.fr_ref = btf->fr_ref + (beg_k-1); + luf.fc_ref = btf->fc_ref + (beg_k-1); + luf.vr_ref = btf->vr_ref + (beg_k-1); + luf.vr_piv = btf->vr_piv + (beg_k-1); + luf.vc_ref = btf->vc_ref + (beg_k-1); + luf.pp_ind = btf->p1_ind + (beg_k-1); + luf.pp_inv = btf->p1_inv + (beg_k-1); + luf.qq_ind = btf->q1_ind + (beg_k-1); + luf.qq_inv = btf->q1_inv + (beg_k-1); + luf_f_solve(&luf, bb); + luf_v_solve(&luf, bb, xx); + /* store X[k] and substitute it into other equations */ + for (j = 1; j <= luf.n; j++) + { jj = j + (beg_k-1); + t = x[qq_ind[jj]] = xx[j]; + if (t != 0.0) + { int ptr = ac_ptr[qq_ind[jj]]; + int end = ptr + ac_len[qq_ind[jj]]; + for (; ptr < end; ptr++) + b[sv_ind[ptr]] -= sv_val[ptr] * t; + } + } + } + } + return; +} + +/*********************************************************************** +* btf_at_solve - solve system A'* x = b +* +* This routine solves the system A'* x = b, where A' is a matrix +* transposed to the original matrix A. +* +* On entry the array b should contain elements of the right-hand size +* vector b in locations b[1], ..., b[n], where n is the order of the +* matrix A. On exit the array x will contain elements of the solution +* vector in locations x[1], ..., x[n]. Note that the array b will be +* clobbered on exit. +* +* The routine also uses locations [1], ..., [max_size] of two working +* arrays w1 and w2, where max_size is the maximal size of diagonal +* blocks in BT-factorization (max_size <= n). */ + +void btf_at_solve(BTF *btf, double b[/*1+n*/], double x[/*1+n*/], + double w1[/*1+n*/], double w2[/*1+n*/]) +{ SVA *sva = btf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int *pp_inv = btf->pp_inv; + int *qq_ind = btf->qq_ind; + int num = btf->num; + int *beg = btf->beg; + int ar_ref = btf->ar_ref; + int *ar_ptr = &sva->ptr[ar_ref-1]; + int *ar_len = &sva->len[ar_ref-1]; + double *bb = w1; + double *xx = w2; + LUF luf; + int i, j, jj, k, beg_k, flag; + double t; + for (k = 1; k <= num; k++) + { /* determine order of diagonal block A~[k,k] */ + luf.n = beg[k+1] - (beg_k = beg[k]); + if (luf.n == 1) + { /* trivial case */ + /* solve system A~'[k,k] * X[k] = B[k] */ + t = x[pp_inv[beg_k]] = + b[qq_ind[beg_k]] / btf->vr_piv[beg_k]; + /* substitute X[k] into other equations */ + if (t != 0.0) + { int ptr = ar_ptr[pp_inv[beg_k]]; + int end = ptr + ar_len[pp_inv[beg_k]]; + for (; ptr < end; ptr++) + b[sv_ind[ptr]] -= sv_val[ptr] * t; + } + } + else + { /* general case */ + /* construct B[k] */ + flag = 0; + for (i = 1; i <= luf.n; i++) + { if ((bb[i] = b[qq_ind[i + (beg_k-1)]]) != 0.0) + flag = 1; + } + /* solve system A~'[k,k] * X[k] = B[k] */ + if (!flag) + { /* B[k] = 0, so X[k] = 0 */ + for (j = 1; j <= luf.n; j++) + x[pp_inv[j + (beg_k-1)]] = 0.0; + continue; + } + luf.sva = sva; + luf.fr_ref = btf->fr_ref + (beg_k-1); + luf.fc_ref = btf->fc_ref + (beg_k-1); + luf.vr_ref = btf->vr_ref + (beg_k-1); + luf.vr_piv = btf->vr_piv + (beg_k-1); + luf.vc_ref = btf->vc_ref + (beg_k-1); + luf.pp_ind = btf->p1_ind + (beg_k-1); + luf.pp_inv = btf->p1_inv + (beg_k-1); + luf.qq_ind = btf->q1_ind + (beg_k-1); + luf.qq_inv = btf->q1_inv + (beg_k-1); + luf_vt_solve(&luf, bb, xx); + luf_ft_solve(&luf, xx); + /* store X[k] and substitute it into other equations */ + for (j = 1; j <= luf.n; j++) + { jj = j + (beg_k-1); + t = x[pp_inv[jj]] = xx[j]; + if (t != 0.0) + { int ptr = ar_ptr[pp_inv[jj]]; + int end = ptr + ar_len[pp_inv[jj]]; + for (; ptr < end; ptr++) + b[sv_ind[ptr]] -= sv_val[ptr] * t; + } + } + } + } + return; +} + +/*********************************************************************** +* btf_at_solve1 - solve system A'* y = e' to cause growth in y +* +* This routine is a special version of btf_at_solve. It solves the +* system A'* y = e' = e + delta e, where A' is a matrix transposed to +* the original matrix A, e is the specified right-hand side vector, +* and delta e is a vector of +1 and -1 chosen to cause growth in the +* solution vector y. +* +* On entry the array e should contain elements of the right-hand size +* vector e in locations e[1], ..., e[n], where n is the order of the +* matrix A. On exit the array y will contain elements of the solution +* vector in locations y[1], ..., y[n]. Note that the array e will be +* clobbered on exit. +* +* The routine also uses locations [1], ..., [max_size] of two working +* arrays w1 and w2, where max_size is the maximal size of diagonal +* blocks in BT-factorization (max_size <= n). */ + +void btf_at_solve1(BTF *btf, double e[/*1+n*/], double y[/*1+n*/], + double w1[/*1+n*/], double w2[/*1+n*/]) +{ SVA *sva = btf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int *pp_inv = btf->pp_inv; + int *qq_ind = btf->qq_ind; + int num = btf->num; + int *beg = btf->beg; + int ar_ref = btf->ar_ref; + int *ar_ptr = &sva->ptr[ar_ref-1]; + int *ar_len = &sva->len[ar_ref-1]; + double *ee = w1; + double *yy = w2; + LUF luf; + int i, j, jj, k, beg_k, ptr, end; + double e_k, y_k; + for (k = 1; k <= num; k++) + { /* determine order of diagonal block A~[k,k] */ + luf.n = beg[k+1] - (beg_k = beg[k]); + if (luf.n == 1) + { /* trivial case */ + /* determine E'[k] = E[k] + delta E[k] */ + e_k = e[qq_ind[beg_k]]; + e_k = (e_k >= 0.0 ? e_k + 1.0 : e_k - 1.0); + /* solve system A~'[k,k] * Y[k] = E[k] */ + y_k = y[pp_inv[beg_k]] = e_k / btf->vr_piv[beg_k]; + /* substitute Y[k] into other equations */ + ptr = ar_ptr[pp_inv[beg_k]]; + end = ptr + ar_len[pp_inv[beg_k]]; + for (; ptr < end; ptr++) + e[sv_ind[ptr]] -= sv_val[ptr] * y_k; + } + else + { /* general case */ + /* construct E[k] */ + for (i = 1; i <= luf.n; i++) + ee[i] = e[qq_ind[i + (beg_k-1)]]; + /* solve system A~'[k,k] * Y[k] = E[k] + delta E[k] */ + luf.sva = sva; + luf.fr_ref = btf->fr_ref + (beg_k-1); + luf.fc_ref = btf->fc_ref + (beg_k-1); + luf.vr_ref = btf->vr_ref + (beg_k-1); + luf.vr_piv = btf->vr_piv + (beg_k-1); + luf.vc_ref = btf->vc_ref + (beg_k-1); + luf.pp_ind = btf->p1_ind + (beg_k-1); + luf.pp_inv = btf->p1_inv + (beg_k-1); + luf.qq_ind = btf->q1_ind + (beg_k-1); + luf.qq_inv = btf->q1_inv + (beg_k-1); + luf_vt_solve1(&luf, ee, yy); + luf_ft_solve(&luf, yy); + /* store Y[k] and substitute it into other equations */ + for (j = 1; j <= luf.n; j++) + { jj = j + (beg_k-1); + y_k = y[pp_inv[jj]] = yy[j]; + ptr = ar_ptr[pp_inv[jj]]; + end = ptr + ar_len[pp_inv[jj]]; + for (; ptr < end; ptr++) + e[sv_ind[ptr]] -= sv_val[ptr] * y_k; + } + } + } + return; +} + +/*********************************************************************** +* btf_estimate_norm - estimate 1-norm of inv(A) +* +* This routine estimates 1-norm of inv(A) by one step of inverse +* iteration for the small singular vector as described in [1]. This +* involves solving two systems of equations: +* +* A'* y = e, +* +* A * z = y, +* +* where A' is a matrix transposed to A, and e is a vector of +1 and -1 +* chosen to cause growth in y. Then +* +* estimate 1-norm of inv(A) = (1-norm of z) / (1-norm of y) +* +* REFERENCES +* +* 1. G.E.Forsythe, M.A.Malcolm, C.B.Moler. Computer Methods for +* Mathematical Computations. Prentice-Hall, Englewood Cliffs, N.J., +* pp. 30-62 (subroutines DECOMP and SOLVE). */ + +double btf_estimate_norm(BTF *btf, double w1[/*1+n*/], double + w2[/*1+n*/], double w3[/*1+n*/], double w4[/*1+n*/]) +{ int n = btf->n; + double *e = w1; + double *y = w2; + double *z = w1; + int i; + double y_norm, z_norm; + /* compute y = inv(A') * e to cause growth in y */ + for (i = 1; i <= n; i++) + e[i] = 0.0; + btf_at_solve1(btf, e, y, w3, w4); + /* compute 1-norm of y = sum |y[i]| */ + y_norm = 0.0; + for (i = 1; i <= n; i++) + y_norm += (y[i] >= 0.0 ? +y[i] : -y[i]); + /* compute z = inv(A) * y */ + btf_a_solve(btf, y, z, w3, w4); + /* compute 1-norm of z = sum |z[i]| */ + z_norm = 0.0; + for (i = 1; i <= n; i++) + z_norm += (z[i] >= 0.0 ? +z[i] : -z[i]); + /* estimate 1-norm of inv(A) = (1-norm of z) / (1-norm of y) */ + return z_norm / y_norm; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/btf.h b/resources/3rdparty/glpk-4.57/src/bflib/btf.h new file mode 100644 index 000000000..3f1b59265 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/btf.h @@ -0,0 +1,207 @@ +/* btf.h (sparse block triangular LU-factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2013-2014 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef BTF_H +#define BTF_H + +#include "sva.h" + +/*********************************************************************** +* The structure BTF describes BT-factorization, which is sparse block +* triangular LU-factorization. +* +* The BT-factorization has the following format: +* +* A = P * A~ * Q, (1) +* +* where A is a given (unsymmetric) square matrix, A~ is an upper block +* triangular matrix (see below), P and Q are permutation matrices. All +* the matrices have the same order n. +* +* The matrix A~, which is a permuted version of the original matrix A, +* has the following structure: +* +* A~[1,1] A~[1,2] ... A~[1,num-1] A~[1,num] +* +* A~[2,2] ... A~[2,num-1] A~[2,num] +* +* . . . . . . . . . (2) +* +* A~[num-1,num-1] A~[num-1,num] +* +* A~[num,num] +* +* where A~[i,j] is a submatrix called a "block," num is the number of +* blocks. Each diagonal block A~[k,k] is a non-singular square matrix, +* and each subdiagonal block A~[i,j], i > j, is a zero submatrix, thus +* A~ is an upper block triangular matrix. +* +* Permutation matrices P and Q are stored in ordinary arrays in both +* row- and column-like formats. +* +* The original matrix A is stored in both row- and column-wise sparse +* formats in the associated sparse vector area (SVA). Should note that +* elements of all diagonal blocks A~[k,k] in matrix A are set to zero +* (i.e. removed), so only elements of non-diagonal blocks are stored. +* +* Each diagonal block A~[k,k], 1 <= k <= num, is stored in the form of +* LU-factorization (see the module LUF). */ + +typedef struct BTF BTF; + +struct BTF +{ /* sparse block triangular LU-factorization */ + int n; + /* order of matrices A, A~, P, Q */ + SVA *sva; + /* associated sparse vector area used to store rows and columns + * of matrix A as well as sparse vectors for LU-factorizations of + * all diagonal blocks A~[k,k] */ + /*--------------------------------------------------------------*/ + /* matrix P */ + int *pp_ind; /* int pp_ind[1+n]; */ + /* pp_ind[i] = j means that P[i,j] = 1 */ + int *pp_inv; /* int pp_inv[1+n]; */ + /* pp_inv[j] = i means that P[i,j] = 1 */ + /* if i-th row of matrix A is i'-th row of matrix A~, then + * pp_ind[i] = i' and pp_inv[i'] = i */ + /*--------------------------------------------------------------*/ + /* matrix Q */ + int *qq_ind; /* int qq_ind[1+n]; */ + /* qq_ind[i] = j means that Q[i,j] = 1 */ + int *qq_inv; /* int qq_inv[1+n]; */ + /* qq_inv[j] = i means that Q[i,j] = 1 */ + /* if j-th column of matrix A is j'-th column of matrix A~, then + * qq_ind[j'] = j and qq_inv[j] = j' */ + /*--------------------------------------------------------------*/ + /* block triangular structure of matrix A~ */ + int num; + /* number of diagonal blocks, 1 <= num <= n */ + int *beg; /* int beg[1+num+1]; */ + /* beg[0] is not used; + * beg[k], 1 <= k <= num, is index of first row/column of k-th + * block of matrix A~; + * beg[num+1] is always n+1; + * note that order (size) of k-th diagonal block can be computed + * as beg[k+1] - beg[k] */ + /*--------------------------------------------------------------*/ + /* original matrix A in row-wise format */ + /* NOTE: elements of all diagonal blocks A~[k,k] are removed */ + int ar_ref; + /* reference number of sparse vector in SVA, which is the first + * row of matrix A */ +#if 0 + 0 + int *ar_ptr = &sva->ptr[ar_ref-1]; + /* ar_ptr[0] is not used; + * ar_ptr[i], 1 <= i <= n, is pointer to i-th row in SVA */ + int *ar_len = &sva->ptr[ar_ref-1]; + /* ar_len[0] is not used; + * ar_len[i], 1 <= i <= n, is length of i-th row */ +#endif + /*--------------------------------------------------------------*/ + /* original matrix A in column-wise format */ + /* NOTE: elements of all diagonal blocks A~[k,k] are removed */ + int ac_ref; + /* reference number of sparse vector in SVA, which is the first + * column of matrix A */ +#if 0 + 0 + int *ac_ptr = &sva->ptr[ac_ref-1]; + /* ac_ptr[0] is not used; + * ac_ptr[j], 1 <= j <= n, is pointer to j-th column in SVA */ + int *ac_len = &sva->ptr[ac_ref-1]; + /* ac_len[0] is not used; + * ac_len[j], 1 <= j <= n, is length of j-th column */ +#endif + /*--------------------------------------------------------------*/ + /* LU-factorizations of diagonal blocks A~[k,k] */ + /* to decrease overhead expenses similar arrays for all LUFs are + * packed into a single array; for example, elements fr_ptr[1], + * ..., fr_ptr[n1], where n1 = beg[2] - beg[1], are related to + * LUF for first diagonal block A~[1,1], elements fr_ptr[n1+1], + * ..., fr_ptr[n1+n2], where n2 = beg[3] - beg[2], are related to + * LUF for second diagonal block A~[2,2], etc.; in other words, + * elements related to LUF for k-th diagonal block A~[k,k] have + * indices beg[k], beg[k]+1, ..., beg[k+1]-1 */ + /* for details about LUF see description of the LUF module */ + int fr_ref; + /* reference number of sparse vector in SVA, which is the first + row of matrix F for first diagonal block A~[1,1] */ + int fc_ref; + /* reference number of sparse vector in SVA, which is the first + column of matrix F for first diagonal block A~[1,1] */ + int vr_ref; + /* reference number of sparse vector in SVA, which is the first + row of matrix V for first diagonal block A~[1,1] */ + double *vr_piv; /* double vr_piv[1+n]; */ + /* vr_piv[0] is not used; + vr_piv[1,...,n] are pivot elements for all diagonal blocks */ + int vc_ref; + /* reference number of sparse vector in SVA, which is the first + column of matrix V for first diagonal block A~[1,1] */ + int *p1_ind; /* int p1_ind[1+n]; */ + int *p1_inv; /* int p1_inv[1+n]; */ + int *q1_ind; /* int q1_ind[1+n]; */ + int *q1_inv; /* int q1_inv[1+n]; */ + /* permutation matrices P and Q for all diagonal blocks */ +}; + +#define btf_store_a_cols _glp_btf_store_a_cols +int btf_store_a_cols(BTF *btf, int (*col)(void *info, int j, int ind[], + double val[]), void *info, int ind[], double val[]); +/* store pattern of matrix A in column-wise format */ + +#define btf_make_blocks _glp_btf_make_blocks +int btf_make_blocks(BTF *btf); +/* permutations to block triangular form */ + +#define btf_check_blocks _glp_btf_check_blocks +void btf_check_blocks(BTF *btf); +/* check structure of matrix A~ */ + +#define btf_build_a_rows _glp_btf_build_a_rows +void btf_build_a_rows(BTF *btf, int len[/*1+n*/]); +/* build matrix A in row-wise format */ + +#define btf_a_solve _glp_btf_a_solve +void btf_a_solve(BTF *btf, double b[/*1+n*/], double x[/*1+n*/], + double w1[/*1+n*/], double w2[/*1+n*/]); +/* solve system A * x = b */ + +#define btf_at_solve _glp_btf_at_solve +void btf_at_solve(BTF *btf, double b[/*1+n*/], double x[/*1+n*/], + double w1[/*1+n*/], double w2[/*1+n*/]); +/* solve system A'* x = b */ + +#define btf_at_solve1 _glp_btf_at_solve1 +void btf_at_solve1(BTF *btf, double e[/*1+n*/], double y[/*1+n*/], + double w1[/*1+n*/], double w2[/*1+n*/]); +/* solve system A'* y = e' to cause growth in y */ + +#define btf_estimate_norm _glp_btf_estimate_norm +double btf_estimate_norm(BTF *btf, double w1[/*1+n*/], double + w2[/*1+n*/], double w3[/*1+n*/], double w4[/*1+n*/]); +/* estimate 1-norm of inv(A) */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/btfint.c b/resources/3rdparty/glpk-4.57/src/bflib/btfint.c new file mode 100644 index 000000000..378d3a816 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/btfint.c @@ -0,0 +1,407 @@ +/* btfint.c (interface to BT-factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2013-2014 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "btfint.h" + +BTFINT *btfint_create(void) +{ /* create interface to BT-factorization */ + BTFINT *fi; + fi = talloc(1, BTFINT); + fi->n_max = 0; + fi->valid = 0; + fi->sva = NULL; + fi->btf = NULL; + fi->sgf = NULL; + fi->sva_n_max = fi->sva_size = 0; + fi->delta_n0 = fi->delta_n = 0; + fi->sgf_piv_tol = 0.10; + fi->sgf_piv_lim = 4; + fi->sgf_suhl = 1; + fi->sgf_eps_tol = DBL_EPSILON; + return fi; +} + +static void factorize_triv(BTFINT *fi, int k, int (*col)(void *info, + int j, int ind[], double val[]), void *info) +{ /* compute LU-factorization of diagonal block A~[k,k] and store + * corresponding columns of matrix A except elements of A~[k,k] + * (trivial case when the block has unity size) */ + SVA *sva = fi->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + BTF *btf = fi->btf; + int *pp_inv = btf->pp_inv; + int *qq_ind = btf->qq_ind; + int *beg = btf->beg; + int ac_ref = btf->ac_ref; + int *ac_ptr = &sva->ptr[ac_ref-1]; + int *ac_len = &sva->len[ac_ref-1]; + SGF *sgf = fi->sgf; + int *ind = (int *)sgf->vr_max; /* working array */ + double *val = sgf->work; /* working array */ + int i, j, t, len, ptr, beg_k; + /* diagonal block A~[k,k] has the only element in matrix A~, + * which is a~[beg[k],beg[k]] = a[i,j] */ + beg_k = beg[k]; + i = pp_inv[beg_k]; + j = qq_ind[beg_k]; + /* get j-th column of A */ + len = col(info, j, ind, val); + /* find element a[i,j] = a~[beg[k],beg[k]] in j-th column */ + for (t = 1; t <= len; t++) + { if (ind[t] == i) + break; + } + xassert(t <= len); + /* compute LU-factorization of diagonal block A~[k,k], where + * F = (1), V = (a[i,j]), P = Q = (1) (see the module LUF) */ +#if 1 /* FIXME */ + xassert(val[t] != 0.0); +#endif + btf->vr_piv[beg_k] = val[t]; + btf->p1_ind[beg_k] = btf->p1_inv[beg_k] = 1; + btf->q1_ind[beg_k] = btf->q1_inv[beg_k] = 1; + /* remove element a[i,j] = a~[beg[k],beg[k]] from j-th column */ + memmove(&ind[t], &ind[t+1], (len-t) * sizeof(int)); + memmove(&val[t], &val[t+1], (len-t) * sizeof(double)); + len--; + /* and store resulting j-th column of A into BTF */ + if (len > 0) + { /* reserve locations for j-th column of A */ + if (sva->r_ptr - sva->m_ptr < len) + { sva_more_space(sva, len); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_reserve_cap(sva, ac_ref+(j-1), len); + /* store j-th column of A (except elements of A~[k,k]) */ + ptr = ac_ptr[j]; + memcpy(&sv_ind[ptr], &ind[1], len * sizeof(int)); + memcpy(&sv_val[ptr], &val[1], len * sizeof(double)); + ac_len[j] = len; + } + return; +} + +static int factorize_block(BTFINT *fi, int k, int (*col)(void *info, + int j, int ind[], double val[]), void *info) +{ /* compute LU-factorization of diagonal block A~[k,k] and store + * corresponding columns of matrix A except elements of A~[k,k] + * (general case) */ + SVA *sva = fi->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + BTF *btf = fi->btf; + int *pp_ind = btf->pp_ind; + int *qq_ind = btf->qq_ind; + int *beg = btf->beg; + int ac_ref = btf->ac_ref; + int *ac_ptr = &sva->ptr[ac_ref-1]; + int *ac_len = &sva->len[ac_ref-1]; + SGF *sgf = fi->sgf; + int *ind = (int *)sgf->vr_max; /* working array */ + double *val = sgf->work; /* working array */ + LUF luf; + int *vc_ptr, *vc_len, *vc_cap; + int i, ii, j, jj, t, len, cnt, ptr, beg_k; + /* construct fake LUF for LU-factorization of A~[k,k] */ + sgf->luf = &luf; + luf.n = beg[k+1] - (beg_k = beg[k]); + luf.sva = sva; + luf.fr_ref = btf->fr_ref + (beg_k-1); + luf.fc_ref = btf->fc_ref + (beg_k-1); + luf.vr_ref = btf->vr_ref + (beg_k-1); + luf.vr_piv = btf->vr_piv + (beg_k-1); + luf.vc_ref = btf->vc_ref + (beg_k-1); + luf.pp_ind = btf->p1_ind + (beg_k-1); + luf.pp_inv = btf->p1_inv + (beg_k-1); + luf.qq_ind = btf->q1_ind + (beg_k-1); + luf.qq_inv = btf->q1_inv + (beg_k-1); + /* process columns of k-th block of matrix A~ */ + vc_ptr = &sva->ptr[luf.vc_ref-1]; + vc_len = &sva->len[luf.vc_ref-1]; + vc_cap = &sva->cap[luf.vc_ref-1]; + for (jj = 1; jj <= luf.n; jj++) + { /* jj-th column of A~ = j-th column of A */ + j = qq_ind[jj + (beg_k-1)]; + /* get j-th column of A */ + len = col(info, j, ind, val); + /* move elements of diagonal block A~[k,k] to the beginning of + * the column list */ + cnt = 0; + for (t = 1; t <= len; t++) + { /* i = row index of element a[i,j] */ + i = ind[t]; + /* i-th row of A = ii-th row of A~ */ + ii = pp_ind[i]; + if (ii >= beg_k) + { /* a~[ii,jj] = a[i,j] is in diagonal block A~[k,k] */ + double temp; + cnt++; + ind[t] = ind[cnt]; + ind[cnt] = ii - (beg_k-1); /* local index */ + temp = val[t], val[t] = val[cnt], val[cnt] = temp; + } + } + /* first cnt elements in the column list give jj-th column of + * diagonal block A~[k,k], which is initial matrix V in LUF */ + /* enlarge capacity of jj-th column of V = A~[k,k] */ + if (vc_cap[jj] < cnt) + { if (sva->r_ptr - sva->m_ptr < cnt) + { sva_more_space(sva, cnt); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_enlarge_cap(sva, luf.vc_ref+(jj-1), cnt, 0); + } + /* store jj-th column of V = A~[k,k] */ + ptr = vc_ptr[jj]; + memcpy(&sv_ind[ptr], &ind[1], cnt * sizeof(int)); + memcpy(&sv_val[ptr], &val[1], cnt * sizeof(double)); + vc_len[jj] = cnt; + /* other (len-cnt) elements in the column list are stored in + * j-th column of the original matrix A */ + len -= cnt; + if (len > 0) + { /* reserve locations for j-th column of A */ + if (sva->r_ptr - sva->m_ptr < len) + { sva_more_space(sva, len); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_reserve_cap(sva, ac_ref-1+j, len); + /* store j-th column of A (except elements of A~[k,k]) */ + ptr = ac_ptr[j]; + memcpy(&sv_ind[ptr], &ind[cnt+1], len * sizeof(int)); + memcpy(&sv_val[ptr], &val[cnt+1], len * sizeof(double)); + ac_len[j] = len; + } + } + /* compute LU-factorization of diagonal block A~[k,k]; may note + * that A~[k,k] is irreducible (strongly connected), so singleton + * phase will have no effect */ + k = sgf_factorize(sgf, 0 /* disable singleton phase */); + /* now left (dynamic) part of SVA should be empty (wichtig!) */ + xassert(sva->m_ptr == 1); + return k; +} + +int btfint_factorize(BTFINT *fi, int n, int (*col)(void *info, int j, + int ind[], double val[]), void *info) +{ /* compute BT-factorization of specified matrix A */ + SVA *sva; + BTF *btf; + SGF *sgf; + int k, rank; + xassert(n > 0); + fi->valid = 0; + /* create sparse vector area (SVA), if necessary */ + sva = fi->sva; + if (sva == NULL) + { int sva_n_max = fi->sva_n_max; + int sva_size = fi->sva_size; + if (sva_n_max == 0) + sva_n_max = 6 * n; + if (sva_size == 0) + sva_size = 10 * n; + sva = fi->sva = sva_create_area(sva_n_max, sva_size); + } + /* allocate/reallocate underlying objects, if necessary */ + if (fi->n_max < n) + { int n_max = fi->n_max; + if (n_max == 0) + n_max = fi->n_max = n + fi->delta_n0; + else + n_max = fi->n_max = n + fi->delta_n; + xassert(n_max >= n); + /* allocate/reallocate block triangular factorization (BTF) */ + btf = fi->btf; + if (btf == NULL) + { btf = fi->btf = talloc(1, BTF); + memset(btf, 0, sizeof(BTF)); + btf->sva = sva; + } + else + { tfree(btf->pp_ind); + tfree(btf->pp_inv); + tfree(btf->qq_ind); + tfree(btf->qq_inv); + tfree(btf->beg); + tfree(btf->vr_piv); + tfree(btf->p1_ind); + tfree(btf->p1_inv); + tfree(btf->q1_ind); + tfree(btf->q1_inv); + } + btf->pp_ind = talloc(1+n_max, int); + btf->pp_inv = talloc(1+n_max, int); + btf->qq_ind = talloc(1+n_max, int); + btf->qq_inv = talloc(1+n_max, int); + btf->beg = talloc(1+n_max+1, int); + btf->vr_piv = talloc(1+n_max, double); + btf->p1_ind = talloc(1+n_max, int); + btf->p1_inv = talloc(1+n_max, int); + btf->q1_ind = talloc(1+n_max, int); + btf->q1_inv = talloc(1+n_max, int); + /* allocate/reallocate factorizer workspace (SGF) */ + /* (note that for SGF we could use the size of largest block + * rather than n_max) */ + sgf = fi->sgf; + sgf = fi->sgf; + if (sgf == NULL) + { sgf = fi->sgf = talloc(1, SGF); + memset(sgf, 0, sizeof(SGF)); + } + else + { tfree(sgf->rs_head); + tfree(sgf->rs_prev); + tfree(sgf->rs_next); + tfree(sgf->cs_head); + tfree(sgf->cs_prev); + tfree(sgf->cs_next); + tfree(sgf->vr_max); + tfree(sgf->flag); + tfree(sgf->work); + } + sgf->rs_head = talloc(1+n_max, int); + sgf->rs_prev = talloc(1+n_max, int); + sgf->rs_next = talloc(1+n_max, int); + sgf->cs_head = talloc(1+n_max, int); + sgf->cs_prev = talloc(1+n_max, int); + sgf->cs_next = talloc(1+n_max, int); + sgf->vr_max = talloc(1+n_max, double); + sgf->flag = talloc(1+n_max, char); + sgf->work = talloc(1+n_max, double); + } + btf = fi->btf; + btf->n = n; + sgf = fi->sgf; +#if 1 /* FIXME */ + /* initialize SVA */ + sva->n = 0; + sva->m_ptr = 1; + sva->r_ptr = sva->size + 1; + sva->head = sva->tail = 0; +#endif + /* store pattern of original matrix A in column-wise format */ + btf->ac_ref = sva_alloc_vecs(btf->sva, btf->n); + btf_store_a_cols(btf, col, info, btf->pp_ind, btf->vr_piv); +#ifdef GLP_DEBUG + sva_check_area(sva); +#endif + /* analyze pattern of original matrix A and determine permutation + * matrices P and Q such that A = P * A~* Q, where A~ is an upper + * block triangular matrix */ + rank = btf_make_blocks(btf); + if (rank != n) + { /* original matrix A is structurally singular */ + return 1; + } +#ifdef GLP_DEBUG + btf_check_blocks(btf); +#endif +#if 1 /* FIXME */ + /* initialize SVA */ + sva->n = 0; + sva->m_ptr = 1; + sva->r_ptr = sva->size + 1; + sva->head = sva->tail = 0; +#endif + /* allocate sparse vectors in SVA */ + btf->ar_ref = sva_alloc_vecs(btf->sva, btf->n); + btf->ac_ref = sva_alloc_vecs(btf->sva, btf->n); + btf->fr_ref = sva_alloc_vecs(btf->sva, btf->n); + btf->fc_ref = sva_alloc_vecs(btf->sva, btf->n); + btf->vr_ref = sva_alloc_vecs(btf->sva, btf->n); + btf->vc_ref = sva_alloc_vecs(btf->sva, btf->n); + /* setup factorizer control parameters */ + sgf->updat = 0; /* wichtig! */ + sgf->piv_tol = fi->sgf_piv_tol; + sgf->piv_lim = fi->sgf_piv_lim; + sgf->suhl = fi->sgf_suhl; + sgf->eps_tol = fi->sgf_eps_tol; + /* compute LU-factorizations of diagonal blocks A~[k,k] and also + * store corresponding columns of matrix A except elements of all + * blocks A~[k,k] */ + for (k = 1; k <= btf->num; k++) + { if (btf->beg[k+1] - btf->beg[k] == 1) + { /* trivial case (A~[k,k] has unity order) */ + factorize_triv(fi, k, col, info); + } + else + { /* general case */ + if (factorize_block(fi, k, col, info) != 0) + return 2; /* factorization of A~[k,k] failed */ + } + } +#ifdef GLP_DEBUG + sva_check_area(sva); +#endif + /* build row-wise representation of matrix A */ + btf_build_a_rows(fi->btf, fi->sgf->rs_head); +#ifdef GLP_DEBUG + sva_check_area(sva); +#endif + /* BT-factorization has been successfully computed */ + fi->valid = 1; + return 0; +} + +void btfint_delete(BTFINT *fi) +{ /* delete interface to BT-factorization */ + SVA *sva = fi->sva; + BTF *btf = fi->btf; + SGF *sgf = fi->sgf; + if (sva != NULL) + sva_delete_area(sva); + if (btf != NULL) + { tfree(btf->pp_ind); + tfree(btf->pp_inv); + tfree(btf->qq_ind); + tfree(btf->qq_inv); + tfree(btf->beg); + tfree(btf->vr_piv); + tfree(btf->p1_ind); + tfree(btf->p1_inv); + tfree(btf->q1_ind); + tfree(btf->q1_inv); + tfree(btf); + } + if (sgf != NULL) + { tfree(sgf->rs_head); + tfree(sgf->rs_prev); + tfree(sgf->rs_next); + tfree(sgf->cs_head); + tfree(sgf->cs_prev); + tfree(sgf->cs_next); + tfree(sgf->vr_max); + tfree(sgf->flag); + tfree(sgf->work); + tfree(sgf); + } + tfree(fi); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/btfint.h b/resources/3rdparty/glpk-4.57/src/bflib/btfint.h new file mode 100644 index 000000000..8d0e70e21 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/btfint.h @@ -0,0 +1,73 @@ +/* btfint.h (interface to BT-factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2013-2014 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef BTFINT_H +#define BTFINT_H + +#include "btf.h" +#include "sgf.h" + +typedef struct BTFINT BTFINT; + +struct BTFINT +{ /* interface to BT-factorization */ + int n_max; + /* maximal value of n (increased automatically) */ + int valid; + /* factorization is valid only if this flag is set */ + SVA *sva; + /* sparse vector area (SVA) */ + BTF *btf; + /* sparse block triangular LU-factorization */ + SGF *sgf; + /* sparse Gaussian factorizer workspace */ + /*--------------------------------------------------------------*/ + /* control parameters */ + int sva_n_max, sva_size; + /* parameters passed to sva_create_area */ + int delta_n0, delta_n; + /* if n_max = 0, set n_max = n + delta_n0 + * if n_max < n, set n_max = n + delta_n */ + double sgf_piv_tol; + int sgf_piv_lim; + int sgf_suhl; + double sgf_eps_tol; + /* factorizer control parameters */ +}; + +#define btfint_create _glp_btfint_create +BTFINT *btfint_create(void); +/* create interface to BT-factorization */ + +#define btfint_factorize _glp_btfint_factorize +int btfint_factorize(BTFINT *fi, int n, int (*col)(void *info, int j, + int ind[], double val[]), void *info); +/* compute BT-factorization of specified matrix A */ + +#define btfint_delete _glp_btfint_delete +void btfint_delete(BTFINT *fi); +/* delete interface to BT-factorization */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/fhv.c b/resources/3rdparty/glpk-4.57/src/bflib/fhv.c new file mode 100644 index 000000000..e4bdf8552 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/fhv.c @@ -0,0 +1,586 @@ +/* fhv.c (sparse updatable FHV-factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "fhv.h" + +/*********************************************************************** +* fhv_ft_update - update FHV-factorization (Forrest-Tomlin) +* +* This routine updates FHV-factorization of the original matrix A +* after replacing its j-th column by a new one. The routine is based +* on the method proposed by Forrest and Tomlin [1]. +* +* The parameter q specifies the number of column of A, which has been +* replaced, 1 <= q <= n, where n is the order of A. +* +* Row indices and numerical values of non-zero elements of the new +* j-th column of A should be placed in locations aq_ind[1], ..., +* aq_ind[aq_len] and aq_val[1], ..., aq_val[aq_len], respectively, +* where aq_len is the number of non-zeros. Neither zero nor duplicate +* elements are allowed. +* +* The working arrays ind, val, and work should have at least 1+n +* elements (0-th elements are not used). +* +* RETURNS +* +* 0 The factorization has been successfully updated. +* +* 1 New matrix U = P'* V * Q' is upper triangular with zero diagonal +* element u[s,s]. (Elimination was not performed.) +* +* 2 New matrix U = P'* V * Q' is upper triangular, and its diagonal +* element u[s,s] or u[t,t] is too small in magnitude. (Elimination +* was not performed.) +* +* 3 The same as 2, but after performing elimination. +* +* 4 The factorization has not been updated, because maximal number of +* updates has been reached. +* +* 5 Accuracy test failed for the updated factorization. +* +* BACKGROUND +* +* The routine is based on the updating method proposed by Forrest and +* Tomlin [1]. +* +* Let q-th column of the original matrix A have been replaced by new +* column A[q]. Then, to keep the equality A = F * H * V, q-th column +* of matrix V should be replaced by column V[q] = inv(F * H) * A[q]. +* From the standpoint of matrix U = P'* V * Q' such replacement is +* equivalent to replacement of s-th column of matrix U, where s is +* determined from q by permutation matrix Q. Thus, matrix U loses its +* upper triangular form and becomes the following: +* +* 1 s t n +* 1 x x * x x x x x x +* . x * x x x x x x +* s . . * x x x x x x +* . . * x x x x x x +* . . * . x x x x x +* . . * . . x x x x +* t . . * . . . x x x +* . . . . . . . x x +* n . . . . . . . . x +* +* where t is largest row index of a non-zero element in s-th column. +* +* The routine makes matrix U upper triangular as follows. First, it +* moves rows and columns s+1, ..., t by one position to the left and +* upwards, resp., and moves s-th row and s-th column to position t. +* Due to such symmetric permutations matrix U becomes the following +* (note that all diagonal elements remain on the diagonal, and element +* u[s,s] becomes u[t,t]): +* +* 1 s t n +* 1 x x x x x x * x x +* . x x x x x * x x +* s . . x x x x * x x +* . . . x x x * x x +* . . . . x x * x x +* . . . . . x * x x +* t . . x x x x * x x +* . . . . . . . x x +* n . . . . . . . . x +* +* Then the routine performs gaussian elimination to eliminate +* subdiagonal elements u[t,s], ..., u[t,t-1] using diagonal elements +* u[s,s], ..., u[t-1,t-1] as pivots. During the elimination process +* the routine permutes neither rows nor columns, so only t-th row is +* changed. Should note that actually all operations are performed on +* matrix V = P * U * Q, since matrix U is not stored. +* +* To keep the equality A = F * H * V, the routine appends new row-like +* factor H[k] to matrix H, and every time it applies elementary +* gaussian transformation to eliminate u[t,j'] = v[p,j] using pivot +* u[j',j'] = v[i,j], it also adds new element f[p,j] = v[p,j] / v[i,j] +* (gaussian multiplier) to factor H[k], which initially is a unity +* matrix. At the end of elimination process the row-like factor H[k] +* may look as follows: +* +* 1 n 1 s t n +* 1 1 . . . . . . . . 1 1 . . . . . . . . +* . 1 . . . . . . . . 1 . . . . . . . +* . . 1 . . . . . . s . . 1 . . . . . . +* p . x x 1 . x . x . . . . 1 . . . . . +* . . . . 1 . . . . . . . . 1 . . . . +* . . . . . 1 . . . . . . . . 1 . . . +* . . . . . . 1 . . t . . x x x x 1 . . +* . . . . . . . 1 . . . . . . . . 1 . +* n . . . . . . . . 1 n . . . . . . . . 1 +* +* H[k] inv(P) * H[k] * P +* +* If, however, s = t, no elimination is needed, in which case no new +* row-like factor is created. +* +* REFERENCES +* +* 1. J.J.H.Forrest and J.A.Tomlin, "Updated triangular factors of the +* basis to maintain sparsity in the product form simplex method," +* Math. Prog. 2 (1972), pp. 263-78. */ + +int fhv_ft_update(FHV *fhv, int q, int aq_len, const int aq_ind[], + const double aq_val[], int ind[/*1+n*/], double val[/*1+n*/], + double work[/*1+n*/]) +{ LUF *luf = fhv->luf; + int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int vr_ref = luf->vr_ref; + int *vr_ptr = &sva->ptr[vr_ref-1]; + int *vr_len = &sva->len[vr_ref-1]; + int *vr_cap = &sva->cap[vr_ref-1]; + double *vr_piv = luf->vr_piv; + int vc_ref = luf->vc_ref; + int *vc_ptr = &sva->ptr[vc_ref-1]; + int *vc_len = &sva->len[vc_ref-1]; + int *vc_cap = &sva->cap[vc_ref-1]; + int *pp_ind = luf->pp_ind; + int *pp_inv = luf->pp_inv; + int *qq_ind = luf->qq_ind; + int *qq_inv = luf->qq_inv; + int *hh_ind = fhv->hh_ind; + int hh_ref = fhv->hh_ref; + int *hh_ptr = &sva->ptr[hh_ref-1]; + int *hh_len = &sva->len[hh_ref-1]; +#if 1 /* FIXME */ + const double eps_tol = DBL_EPSILON; + const double vpq_tol = 1e-5; + const double err_tol = 1e-10; +#endif + int end, i, i_end, i_ptr, j, j_end, j_ptr, k, len, nnz, p, p_end, + p_ptr, ptr, q_end, q_ptr, s, t; + double f, vpq, temp; + /*--------------------------------------------------------------*/ + /* replace current q-th column of matrix V by new one */ + /*--------------------------------------------------------------*/ + xassert(1 <= q && q <= n); + /* convert new q-th column of matrix A to dense format */ + for (i = 1; i <= n; i++) + val[i] = 0.0; + xassert(0 <= aq_len && aq_len <= n); + for (k = 1; k <= aq_len; k++) + { i = aq_ind[k]; + xassert(1 <= i && i <= n); + xassert(val[i] == 0.0); + xassert(aq_val[k] != 0.0); + val[i] = aq_val[k]; + } + /* compute new q-th column of matrix V: + * new V[q] = inv(F * H) * (new A[q]) */ + luf->pp_ind = fhv->p0_ind; + luf->pp_inv = fhv->p0_inv; + luf_f_solve(luf, val); + luf->pp_ind = pp_ind; + luf->pp_inv = pp_inv; + fhv_h_solve(fhv, val); + /* q-th column of V = s-th column of U */ + s = qq_inv[q]; + /* determine row number of element v[p,q] that corresponds to + * diagonal element u[s,s] */ + p = pp_inv[s]; + /* convert new q-th column of V to sparse format; + * element v[p,q] = u[s,s] is not included in the element list + * and stored separately */ + vpq = 0.0; + len = 0; + for (i = 1; i <= n; i++) + { temp = val[i]; +#if 1 /* FIXME */ + if (-eps_tol < temp && temp < +eps_tol) +#endif + /* nop */; + else if (i == p) + vpq = temp; + else + { ind[++len] = i; + val[len] = temp; + } + } + /* clear q-th column of matrix V */ + for (q_end = (q_ptr = vc_ptr[q]) + vc_len[q]; + q_ptr < q_end; q_ptr++) + { /* get row index of v[i,q] */ + i = sv_ind[q_ptr]; + /* find and remove v[i,q] from i-th row */ + for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; + sv_ind[i_ptr] != q; i_ptr++) + /* nop */; + xassert(i_ptr < i_end); + sv_ind[i_ptr] = sv_ind[i_end-1]; + sv_val[i_ptr] = sv_val[i_end-1]; + vr_len[i]--; + } + /* now q-th column of matrix V is empty */ + vc_len[q] = 0; + /* put new q-th column of V (except element v[p,q] = u[s,s]) in + * column-wise format */ + if (len > 0) + { if (vc_cap[q] < len) + { if (sva->r_ptr - sva->m_ptr < len) + { sva_more_space(sva, len); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_enlarge_cap(sva, vc_ref-1+q, len, 0); + } + ptr = vc_ptr[q]; + memcpy(&sv_ind[ptr], &ind[1], len * sizeof(int)); + memcpy(&sv_val[ptr], &val[1], len * sizeof(double)); + vc_len[q] = len; + } + /* put new q-th column of V (except element v[p,q] = u[s,s]) in + * row-wise format, and determine largest row number t such that + * u[s,t] != 0 */ + t = (vpq == 0.0 ? 0 : s); + for (k = 1; k <= len; k++) + { /* get row index of v[i,q] */ + i = ind[k]; + /* put v[i,q] to i-th row */ + if (vr_cap[i] == vr_len[i]) + { /* reserve extra locations in i-th row to reduce further + * relocations of that row */ +#if 1 /* FIXME */ + int need = vr_len[i] + 5; +#endif + if (sva->r_ptr - sva->m_ptr < need) + { sva_more_space(sva, need); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_enlarge_cap(sva, vr_ref-1+i, need, 0); + } + sv_ind[ptr = vr_ptr[i] + (vr_len[i]++)] = q; + sv_val[ptr] = val[k]; + /* v[i,q] is non-zero; increase t */ + if (t < pp_ind[i]) + t = pp_ind[i]; + } + /*--------------------------------------------------------------*/ + /* check if matrix U is already upper triangular */ + /*--------------------------------------------------------------*/ + /* check if there is a spike in s-th column of matrix U, which + * is q-th column of matrix V */ + if (s >= t) + { /* no spike; matrix U is already upper triangular */ + /* store its diagonal element u[s,s] = v[p,q] */ + vr_piv[p] = vpq; + if (s > t) + { /* matrix U is structurally singular, because its diagonal + * element u[s,s] = v[p,q] is exact zero */ + xassert(vpq == 0.0); + return 1; + } +#if 1 /* FIXME */ + else if (-vpq_tol < vpq && vpq < +vpq_tol) +#endif + { /* matrix U is not well conditioned, because its diagonal + * element u[s,s] = v[p,q] is too small in magnitude */ + return 2; + } + else + { /* normal case */ + return 0; + } + } + /*--------------------------------------------------------------*/ + /* perform implicit symmetric permutations of rows and columns */ + /* of matrix U */ + /*--------------------------------------------------------------*/ + /* currently v[p,q] = u[s,s] */ + xassert(p == pp_inv[s] && q == qq_ind[s]); + for (k = s; k < t; k++) + { pp_ind[pp_inv[k] = pp_inv[k+1]] = k; + qq_inv[qq_ind[k] = qq_ind[k+1]] = k; + } + /* now v[p,q] = u[t,t] */ + pp_ind[pp_inv[t] = p] = qq_inv[qq_ind[t] = q] = t; + /*--------------------------------------------------------------*/ + /* check if matrix U is already upper triangular */ + /*--------------------------------------------------------------*/ + /* check if there is a spike in t-th row of matrix U, which is + * p-th row of matrix V */ + for (p_end = (p_ptr = vr_ptr[p]) + vr_len[p]; + p_ptr < p_end; p_ptr++) + { if (qq_inv[sv_ind[p_ptr]] < t) + break; /* spike detected */ + } + if (p_ptr == p_end) + { /* no spike; matrix U is already upper triangular */ + /* store its diagonal element u[t,t] = v[p,q] */ + vr_piv[p] = vpq; +#if 1 /* FIXME */ + if (-vpq_tol < vpq && vpq < +vpq_tol) +#endif + { /* matrix U is not well conditioned, because its diagonal + * element u[t,t] = v[p,q] is too small in magnitude */ + return 2; + } + else + { /* normal case */ + return 0; + } + } + /*--------------------------------------------------------------*/ + /* copy p-th row of matrix V, which is t-th row of matrix U, to */ + /* working array */ + /*--------------------------------------------------------------*/ + /* copy p-th row of matrix V, including element v[p,q] = u[t,t], + * to the working array in dense format and remove these elements + * from matrix V; since no pivoting is used, only this row will + * change during elimination */ + for (j = 1; j <= n; j++) + work[j] = 0.0; + work[q] = vpq; + for (p_end = (p_ptr = vr_ptr[p]) + vr_len[p]; + p_ptr < p_end; p_ptr++) + { /* get column index of v[p,j] and store this element to the + * working array */ + work[j = sv_ind[p_ptr]] = sv_val[p_ptr]; + /* find and remove v[p,j] from j-th column */ + for (j_end = (j_ptr = vc_ptr[j]) + vc_len[j]; + sv_ind[j_ptr] != p; j_ptr++) + /* nop */; + xassert(j_ptr < j_end); + sv_ind[j_ptr] = sv_ind[j_end-1]; + sv_val[j_ptr] = sv_val[j_end-1]; + vc_len[j]--; + } + /* now p-th row of matrix V is temporarily empty */ + vr_len[p] = 0; + /*--------------------------------------------------------------*/ + /* perform gaussian elimination */ + /*--------------------------------------------------------------*/ + /* transform p-th row of matrix V stored in working array, which + * is t-th row of matrix U, to eliminate subdiagonal elements + * u[t,s], ..., u[t,t-1]; corresponding gaussian multipliers will + * form non-trivial row of new row-like factor */ + nnz = 0; /* number of non-zero gaussian multipliers */ + for (k = s; k < t; k++) + { /* diagonal element u[k,k] = v[i,j] is used as pivot */ + i = pp_inv[k], j = qq_ind[k]; + /* take subdiagonal element u[t,k] = v[p,j] */ + temp = work[j]; +#if 1 /* FIXME */ + if (-eps_tol < temp && temp < +eps_tol) + continue; +#endif + /* compute and save gaussian multiplier: + * f := u[t,k] / u[k,k] = v[p,j] / v[i,j] */ + ind[++nnz] = i; + val[nnz] = f = work[j] / vr_piv[i]; + /* gaussian transformation to eliminate u[t,k] = v[p,j]: + * (p-th row of V) := (p-th row of V) - f * (i-th row of V) */ + for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; + i_ptr < i_end; i_ptr++) + work[sv_ind[i_ptr]] -= f * sv_val[i_ptr]; + } + /* now matrix U is again upper triangular */ +#if 1 /* FIXME */ + if (-vpq_tol < work[q] && work[q] < +vpq_tol) +#endif + { /* however, its new diagonal element u[t,t] = v[p,q] is too + * small in magnitude */ + return 3; + } + /*--------------------------------------------------------------*/ + /* create new row-like factor H[k] and add to eta file H */ + /*--------------------------------------------------------------*/ + /* (nnz = 0 means that all subdiagonal elements were too small + * in magnitude) */ + if (nnz > 0) + { if (fhv->nfs == fhv->nfs_max) + { /* maximal number of row-like factors has been reached */ + return 4; + } + k = ++(fhv->nfs); + hh_ind[k] = p; + /* store non-trivial row of H[k] in right (dynamic) part of + * SVA (diagonal unity element is not stored) */ + if (sva->r_ptr - sva->m_ptr < nnz) + { sva_more_space(sva, nnz); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_reserve_cap(sva, fhv->hh_ref-1+k, nnz); + ptr = hh_ptr[k]; + memcpy(&sv_ind[ptr], &ind[1], nnz * sizeof(int)); + memcpy(&sv_val[ptr], &val[1], nnz * sizeof(double)); + hh_len[k] = nnz; + } + /*--------------------------------------------------------------*/ + /* copy transformed p-th row of matrix V, which is t-th row of */ + /* matrix U, from working array back to matrix V */ + /*--------------------------------------------------------------*/ + /* copy elements of transformed p-th row of matrix V, which are + * non-diagonal elements u[t,t+1], ..., u[t,n] of matrix U, from + * working array to corresponding columns of matrix V (note that + * diagonal element u[t,t] = v[p,q] not copied); also transform + * p-th row of matrix V to sparse format */ + len = 0; + for (k = t+1; k <= n; k++) + { /* j-th column of V = k-th column of U */ + j = qq_ind[k]; + /* take non-diagonal element v[p,j] = u[t,k] */ + temp = work[j]; +#if 1 /* FIXME */ + if (-eps_tol < temp && temp < +eps_tol) + continue; +#endif + /* add v[p,j] to j-th column of matrix V */ + if (vc_cap[j] == vc_len[j]) + { /* reserve extra locations in j-th column to reduce further + * relocations of that column */ +#if 1 /* FIXME */ + int need = vc_len[j] + 5; +#endif + if (sva->r_ptr - sva->m_ptr < need) + { sva_more_space(sva, need); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_enlarge_cap(sva, vc_ref-1+j, need, 0); + } + sv_ind[ptr = vc_ptr[j] + (vc_len[j]++)] = p; + sv_val[ptr] = temp; + /* store element v[p,j] = u[t,k] to working sparse vector */ + ind[++len] = j; + val[len] = temp; + } + /* copy elements from working sparse vector to p-th row of matrix + * V (this row is currently empty) */ + if (vr_cap[p] < len) + { if (sva->r_ptr - sva->m_ptr < len) + { sva_more_space(sva, len); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_enlarge_cap(sva, vr_ref-1+p, len, 0); + } + ptr = vr_ptr[p]; + memcpy(&sv_ind[ptr], &ind[1], len * sizeof(int)); + memcpy(&sv_val[ptr], &val[1], len * sizeof(double)); + vr_len[p] = len; + /* store new diagonal element u[t,t] = v[p,q] */ + vr_piv[p] = work[q]; + /*--------------------------------------------------------------*/ + /* perform accuracy test (only if new H[k] was added) */ + /*--------------------------------------------------------------*/ + if (nnz > 0) + { /* copy p-th (non-trivial) row of row-like factor H[k] (except + * unity diagonal element) to working array in dense format */ + for (j = 1; j <= n; j++) + work[j] = 0.0; + k = fhv->nfs; + for (end = (ptr = hh_ptr[k]) + hh_len[k]; ptr < end; ptr++) + work[sv_ind[ptr]] = sv_val[ptr]; + /* compute inner product of p-th (non-trivial) row of matrix + * H[k] and q-th column of matrix V */ + temp = vr_piv[p]; /* 1 * v[p,q] */ + ptr = vc_ptr[q]; + end = ptr + vc_len[q]; + for (; ptr < end; ptr++) + temp += work[sv_ind[ptr]] * sv_val[ptr]; + /* inner product should be equal to element v[p,q] *before* + * matrix V was transformed */ + /* compute relative error */ + temp = fabs(vpq - temp) / (1.0 + fabs(vpq)); +#if 1 /* FIXME */ + if (temp > err_tol) +#endif + { /* relative error is too large */ + return 5; + } + } + /* factorization has been successfully updated */ + return 0; +} + +/*********************************************************************** +* fhv_h_solve - solve system H * x = b +* +* This routine solves the system H * x = b, where the matrix H is the +* middle factor of the sparse updatable FHV-factorization. +* +* On entry the array x should contain elements of the right-hand side +* vector b in locations x[1], ..., x[n], where n is the order of the +* matrix H. On exit this array will contain elements of the solution +* vector x in the same locations. */ + +void fhv_h_solve(FHV *fhv, double x[/*1+n*/]) +{ SVA *sva = fhv->luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int nfs = fhv->nfs; + int *hh_ind = fhv->hh_ind; + int hh_ref = fhv->hh_ref; + int *hh_ptr = &sva->ptr[hh_ref-1]; + int *hh_len = &sva->len[hh_ref-1]; + int i, k, end, ptr; + double x_i; + for (k = 1; k <= nfs; k++) + { x_i = x[i = hh_ind[k]]; + for (end = (ptr = hh_ptr[k]) + hh_len[k]; ptr < end; ptr++) + x_i -= sv_val[ptr] * x[sv_ind[ptr]]; + x[i] = x_i; + } + return; +} + +/*********************************************************************** +* fhv_ht_solve - solve system H' * x = b +* +* This routine solves the system H' * x = b, where H' is a matrix +* transposed to the matrix H, which is the middle factor of the sparse +* updatable FHV-factorization. +* +* On entry the array x should contain elements of the right-hand side +* vector b in locations x[1], ..., x[n], where n is the order of the +* matrix H. On exit this array will contain elements of the solution +* vector x in the same locations. */ + +void fhv_ht_solve(FHV *fhv, double x[/*1+n*/]) +{ SVA *sva = fhv->luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int nfs = fhv->nfs; + int *hh_ind = fhv->hh_ind; + int hh_ref = fhv->hh_ref; + int *hh_ptr = &sva->ptr[hh_ref-1]; + int *hh_len = &sva->len[hh_ref-1]; + int k, end, ptr; + double x_j; + for (k = nfs; k >= 1; k--) + { if ((x_j = x[hh_ind[k]]) == 0.0) + continue; + for (end = (ptr = hh_ptr[k]) + hh_len[k]; ptr < end; ptr++) + x[sv_ind[ptr]] -= sv_val[ptr] * x_j; + } + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/fhv.h b/resources/3rdparty/glpk-4.57/src/bflib/fhv.h new file mode 100644 index 000000000..df39ca5cb --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/fhv.h @@ -0,0 +1,114 @@ +/* fhv.h (sparse updatable FHV-factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef FHV_H +#define FHV_H + +#include "luf.h" + +/*********************************************************************** +* The structure FHV describes sparse updatable FHV-factorization. +* +* The FHV-factorization has the following format: +* +* A = F * H * V, (1) +* +* F = P0 * L * P0', (2) +* +* H = H[1] * H[2] * ... * H[nfs], (3) +* +* V = P * U * Q, (4) +* +* where: A is a given (unsymmetric) square matrix; F, H, V are matrix +* factors actually computed; L is a lower triangular matrix with unity +* diagonal; U is an upper tringular matrix; H[k], k = 1, 2, ..., nfs, +* is a row-like factor, which differs from unity matrix only in one +* row called a non-trivial row; P0, P, Q are permutation matrices; and +* P0' is a matrix transposed to P0. +* +* Matrices F, V, P, Q are stored in the underlying LUF object. +* +* Non-trivial rows of factors H[k] are stored as sparse vectors in the +* right (static) part of the sparse vector area (SVA). Note that unity +* diagonal elements of non-trivial rows are not stored. +* +* Matrix P0 is stored in the same way as matrix P. +* +* Matrices L and U are completely defined by matrices F, V, P, and Q, +* and therefore not stored explicitly. */ + +typedef struct FHV FHV; + +struct FHV +{ /* FHV-factorization */ + LUF *luf; + /* LU-factorization (contains matrices F, V, P, Q) */ + /*--------------------------------------------------------------*/ + /* matrix H in the form of eta file */ + int nfs_max; + /* maximal number of row-like factors (this limits the number of + * updates of the factorization) */ + int nfs; + /* current number of row-like factors, 0 <= nfs <= nfs_max */ + int *hh_ind; /* int hh_ind[1+nfs_max]; */ + /* hh_ind[0] is not used; + * hh_ind[k], 1 <= k <= nfs, is number of non-trivial row of + * factor H[k] */ + int hh_ref; + /* reference number of sparse vector in SVA, which is non-trivial + * row of factor H[1] */ +#if 0 + 0 + int *hh_ptr = &sva->ptr[hh_ref-1]; + /* hh_ptr[0] is not used; + * hh_ptr[k], 1 <= k <= nfs, is pointer to non-trivial row of + * factor H[k] */ + int *hh_len = &sva->len[hh_ref-1]; + /* hh_len[0] is not used; + * hh_len[k], 1 <= k <= nfs, is number of non-zero elements in + * non-trivial row of factor H[k] */ +#endif + /*--------------------------------------------------------------*/ + /* matrix P0 */ + int *p0_ind; /* int p0_ind[1+n]; */ + /* p0_ind[i] = j means that P0[i,j] = 1 */ + int *p0_inv; /* int p0_inv[1+n]; */ + /* p0_inv[j] = i means that P0[i,j] = 1 */ +}; + +#define fhv_ft_update _glp_fhv_ft_update +int fhv_ft_update(FHV *fhv, int q, int aq_len, const int aq_ind[], + const double aq_val[], int ind[/*1+n*/], double val[/*1+n*/], + double work[/*1+n*/]); +/* update FHV-factorization (Forrest-Tomlin) */ + +#define fhv_h_solve _glp_fhv_h_solve +void fhv_h_solve(FHV *fhv, double x[/*1+n*/]); +/* solve system H * x = b */ + +#define fhv_ht_solve _glp_fhv_ht_solve +void fhv_ht_solve(FHV *fhv, double x[/*1+n*/]); +/* solve system H' * x = b */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/fhvint.c b/resources/3rdparty/glpk-4.57/src/bflib/fhvint.c new file mode 100644 index 000000000..a21b71c67 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/fhvint.c @@ -0,0 +1,168 @@ +/* fhvint.c (interface to FHV-factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2014 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "fhvint.h" + +FHVINT *fhvint_create(void) +{ /* create interface to FHV-factorization */ + FHVINT *fi; + fi = talloc(1, FHVINT); + memset(fi, 0, sizeof(FHVINT)); + fi->lufi = lufint_create(); + return fi; +} + +int fhvint_factorize(FHVINT *fi, int n, int (*col)(void *info, int j, + int ind[], double val[]), void *info) +{ /* compute FHV-factorization of specified matrix A */ + int nfs_max, old_n_max, n_max, k, ret; + xassert(n > 0); + fi->valid = 0; + /* get required value of nfs_max */ + nfs_max = fi->nfs_max; + if (nfs_max == 0) + nfs_max = 100; + xassert(nfs_max > 0); + /* compute factorization of specified matrix A */ + old_n_max = fi->lufi->n_max; + fi->lufi->sva_n_max = 4 * n + nfs_max; + fi->lufi->sgf_updat = 1; + ret = lufint_factorize(fi->lufi, n, col, info); + n_max = fi->lufi->n_max; + /* allocate/reallocate arrays, if necessary */ + if (fi->fhv.nfs_max != nfs_max) + { if (fi->fhv.hh_ind != NULL) + tfree(fi->fhv.hh_ind); + fi->fhv.hh_ind = talloc(1+nfs_max, int); + } + if (old_n_max < n_max) + { if (fi->fhv.p0_ind != NULL) + tfree(fi->fhv.p0_ind); + if (fi->fhv.p0_inv != NULL) + tfree(fi->fhv.p0_inv); + fi->fhv.p0_ind = talloc(1+n_max, int); + fi->fhv.p0_inv = talloc(1+n_max, int); + } + /* initialize FHV-factorization */ + fi->fhv.luf = fi->lufi->luf; + fi->fhv.nfs_max = nfs_max; + /* H := I */ + fi->fhv.nfs = 0; + fi->fhv.hh_ref = sva_alloc_vecs(fi->lufi->sva, nfs_max); + /* P0 := P */ + for (k = 1; k <= n; k++) + { fi->fhv.p0_ind[k] = fi->fhv.luf->pp_ind[k]; + fi->fhv.p0_inv[k] = fi->fhv.luf->pp_inv[k]; + } + /* set validation flag */ + if (ret == 0) + fi->valid = 1; + return ret; +} + +int fhvint_update(FHVINT *fi, int j, int len, const int ind[], + const double val[]) +{ /* update FHV-factorization after replacing j-th column of A */ + SGF *sgf = fi->lufi->sgf; + int *ind1 = sgf->rs_next; + double *val1 = sgf->vr_max; + double *work = sgf->work; + int ret; + xassert(fi->valid); + ret = fhv_ft_update(&fi->fhv, j, len, ind, val, ind1, val1, work); + if (ret != 0) + fi->valid = 0; + return ret; +} + +void fhvint_ftran(FHVINT *fi, double x[]) +{ /* solve system A * x = b */ + FHV *fhv = &fi->fhv; + LUF *luf = fhv->luf; + int n = luf->n; + int *pp_ind = luf->pp_ind; + int *pp_inv = luf->pp_inv; + SGF *sgf = fi->lufi->sgf; + double *work = sgf->work; + xassert(fi->valid); + /* A = F * H * V */ + /* x = inv(A) * b = inv(V) * inv(H) * inv(F) * b */ + luf->pp_ind = fhv->p0_ind; + luf->pp_inv = fhv->p0_inv; + luf_f_solve(luf, x); + luf->pp_ind = pp_ind; + luf->pp_inv = pp_inv; + fhv_h_solve(fhv, x); + luf_v_solve(luf, x, work); + memcpy(&x[1], &work[1], n * sizeof(double)); + return; +} + +void fhvint_btran(FHVINT *fi, double x[]) +{ /* solve system A'* x = b */ + FHV *fhv = &fi->fhv; + LUF *luf = fhv->luf; + int n = luf->n; + int *pp_ind = luf->pp_ind; + int *pp_inv = luf->pp_inv; + SGF *sgf = fi->lufi->sgf; + double *work = sgf->work; + xassert(fi->valid); + /* A' = (F * H * V)' = V'* H'* F' */ + /* x = inv(A') * b = inv(F') * inv(H') * inv(V') * b */ + luf_vt_solve(luf, x, work); + fhv_ht_solve(fhv, work); + luf->pp_ind = fhv->p0_ind; + luf->pp_inv = fhv->p0_inv; + luf_ft_solve(luf, work); + luf->pp_ind = pp_ind; + luf->pp_inv = pp_inv; + memcpy(&x[1], &work[1], n * sizeof(double)); + return; +} + +double fhvint_estimate(FHVINT *fi) +{ /* estimate 1-norm of inv(A) */ + double norm; + xassert(fi->valid); + xassert(fi->fhv.nfs == 0); + norm = luf_estimate_norm(fi->fhv.luf, fi->lufi->sgf->vr_max, + fi->lufi->sgf->work); + return norm; +} + +void fhvint_delete(FHVINT *fi) +{ /* delete interface to FHV-factorization */ + lufint_delete(fi->lufi); + if (fi->fhv.hh_ind != NULL) + tfree(fi->fhv.hh_ind); + if (fi->fhv.p0_ind != NULL) + tfree(fi->fhv.p0_ind); + if (fi->fhv.p0_inv != NULL) + tfree(fi->fhv.p0_inv); + tfree(fi); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/fhvint.h b/resources/3rdparty/glpk-4.57/src/bflib/fhvint.h new file mode 100644 index 000000000..000829c6f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/fhvint.h @@ -0,0 +1,78 @@ +/* fhvint.h (interface to FHV-factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2014 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef FHVINT_H +#define FHVINT_H + +#include "fhv.h" +#include "lufint.h" + +typedef struct FHVINT FHVINT; + +struct FHVINT +{ /* interface to FHV-factorization */ + int valid; + /* factorization is valid only if this flag is set */ + FHV fhv; + /* FHV-factorization */ + LUFINT *lufi; + /* interface to underlying LU-factorization */ + /*--------------------------------------------------------------*/ + /* control parameters */ + int nfs_max; + /* required maximal number of row-like factors */ +}; + +#define fhvint_create _glp_fhvint_create +FHVINT *fhvint_create(void); +/* create interface to FHV-factorization */ + +#define fhvint_factorize _glp_fhvint_factorize +int fhvint_factorize(FHVINT *fi, int n, int (*col)(void *info, int j, + int ind[], double val[]), void *info); +/* compute FHV-factorization of specified matrix A */ + +#define fhvint_update _glp_fhvint_update +int fhvint_update(FHVINT *fi, int j, int len, const int ind[], + const double val[]); +/* update FHV-factorization after replacing j-th column of A */ + +#define fhvint_ftran _glp_fhvint_ftran +void fhvint_ftran(FHVINT *fi, double x[]); +/* solve system A * x = b */ + +#define fhvint_btran _glp_fhvint_btran +void fhvint_btran(FHVINT *fi, double x[]); +/* solve system A'* x = b */ + +#define fhvint_estimate _glp_fhvint_estimate +double fhvint_estimate(FHVINT *fi); +/* estimate 1-norm of inv(A) */ + +#define fhvint_delete _glp_fhvint_delete +void fhvint_delete(FHVINT *fi); +/* delete interface to FHV-factorization */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/ifu.c b/resources/3rdparty/glpk-4.57/src/bflib/ifu.c new file mode 100644 index 000000000..aa47fb092 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/ifu.c @@ -0,0 +1,392 @@ +/* ifu.c (dense updatable IFU-factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "ifu.h" + +/*********************************************************************** +* ifu_expand - expand IFU-factorization +* +* This routine expands the IFU-factorization of the matrix A according +* to the following expansion of A: +* +* ( A c ) +* new A = ( ) +* ( r' d ) +* +* where c[1,...,n] is a new column, r[1,...,n] is a new row, and d is +* a new diagonal element. +* +* From the main equality F * A = U it follows that: +* +* ( F 0 ) ( A c ) ( FA Fc ) ( U Fc ) +* ( ) ( ) = ( ) = ( ), +* ( 0 1 ) ( r' d ) ( r' d ) ( r' d ) +* +* thus, +* +* ( F 0 ) ( U Fc ) +* new F = ( ), new U = ( ). +* ( 0 1 ) ( r' d ) +* +* Note that the resulting matrix U loses its upper triangular form due +* to row spike r', which should be eliminated. */ + +void ifu_expand(IFU *ifu, double c[/*1+n*/], double r[/*1+n*/], + double d) +{ /* non-optimized version */ + int n_max = ifu->n_max; + int n = ifu->n; + double *f_ = ifu->f; + double *u_ = ifu->u; + int i, j; + double t; +# define f(i,j) f_[(i)*n_max+(j)] +# define u(i,j) u_[(i)*n_max+(j)] + xassert(0 <= n && n < n_max); + /* adjust indexing */ + c++, r++; + /* set new zero column of matrix F */ + for (i = 0; i < n; i++) + f(i,n) = 0.0; + /* set new zero row of matrix F */ + for (j = 0; j < n; j++) + f(n,j) = 0.0; + /* set new unity diagonal element of matrix F */ + f(n,n) = 1.0; + /* set new column of matrix U to vector (old F) * c */ + for (i = 0; i < n; i++) + { /* u[i,n] := (i-th row of old F) * c */ + t = 0.0; + for (j = 0; j < n; j++) + t += f(i,j) * c[j]; + u(i,n) = t; + } + /* set new row of matrix U to vector r */ + for (j = 0; j < n; j++) + u(n,j) = r[j]; + /* set new diagonal element of matrix U to scalar d */ + u(n,n) = d; + /* increase factorization order */ + ifu->n++; +# undef f +# undef u + return; +} + +/*********************************************************************** +* ifu_bg_update - update IFU-factorization (Bartels-Golub) +* +* This routine updates IFU-factorization of the matrix A according to +* its expansion (see comments to the routine ifu_expand). The routine +* is based on the method proposed by Bartels and Golub [1]. +* +* RETURNS +* +* 0 The factorization has been successfully updated. +* +* 1 On some elimination step diagional element u[k,k] to be used as +* pivot is too small in magnitude. +* +* 2 Diagonal element u[n,n] is too small in magnitude (at the end of +* update). +* +* REFERENCES +* +* 1. R.H.Bartels, G.H.Golub, "The Simplex Method of Linear Programming +* Using LU-decomposition", Comm. ACM, 12, pp. 266-68, 1969. */ + +int ifu_bg_update(IFU *ifu, double c[/*1+n*/], double r[/*1+n*/], + double d) +{ /* non-optimized version */ + int n_max = ifu->n_max; + int n = ifu->n; + double *f_ = ifu->f; + double *u_ = ifu->u; +#if 1 /* FIXME */ + double tol = 1e-5; +#endif + int j, k; + double t; +# define f(i,j) f_[(i)*n_max+(j)] +# define u(i,j) u_[(i)*n_max+(j)] + /* expand factorization */ + ifu_expand(ifu, c, r, d); + /* NOTE: n keeps its old value */ + /* eliminate spike (non-zero subdiagonal elements) in last row of + * matrix U */ + for (k = 0; k < n; k++) + { /* if |u[k,k]| < |u[n,k]|, interchange k-th and n-th rows to + * provide |u[k,k]| >= |u[n,k]| for numeric stability */ + if (fabs(u(k,k)) < fabs(u(n,k))) + { /* interchange k-th and n-th rows of matrix U */ + for (j = k; j <= n; j++) + t = u(k,j), u(k,j) = u(n,j), u(n,j) = t; + /* interchange k-th and n-th rows of matrix F to keep the + * main equality F * A = U */ + for (j = 0; j <= n; j++) + t = f(k,j), f(k,j) = f(n,j), f(n,j) = t; + } + /* now |u[k,k]| >= |u[n,k]| */ + /* check if diagonal element u[k,k] can be used as pivot */ + if (fabs(u(k,k)) < tol) + { /* u[k,k] is too small in magnitude */ + return 1; + } + /* if u[n,k] = 0, elimination is not needed */ + if (u(n,k) == 0.0) + continue; + /* compute gaussian multiplier t = u[n,k] / u[k,k] */ + t = u(n,k) / u(k,k); + /* apply gaussian transformation to eliminate u[n,k] */ + /* (n-th row of U) := (n-th row of U) - t * (k-th row of U) */ + for (j = k+1; j <= n; j++) + u(n,j) -= t * u(k,j); + /* apply the same transformation to matrix F to keep the main + * equality F * A = U */ + for (j = 0; j <= n; j++) + f(n,j) -= t * f(k,j); + } + /* now matrix U is upper triangular */ + if (fabs(u(n,n)) < tol) + { /* u[n,n] is too small in magnitude */ + return 2; + } +# undef f +# undef u + return 0; +} + +/*********************************************************************** +* The routine givens computes the parameters of Givens plane rotation +* c = cos(teta) and s = sin(teta) such that: +* +* ( c -s ) ( a ) ( r ) +* ( ) ( ) = ( ) , +* ( s c ) ( b ) ( 0 ) +* +* where a and b are given scalars. +* +* REFERENCES +* +* G.H.Golub, C.F.Van Loan, "Matrix Computations", 2nd ed. */ + +static void givens(double a, double b, double *c, double *s) +{ /* non-optimized version */ + double t; + if (b == 0.0) + (*c) = 1.0, (*s) = 0.0; + else if (fabs(a) <= fabs(b)) + t = - a / b, (*s) = 1.0 / sqrt(1.0 + t * t), (*c) = (*s) * t; + else + t = - b / a, (*c) = 1.0 / sqrt(1.0 + t * t), (*s) = (*c) * t; + return; +} + +/*********************************************************************** +* ifu_gr_update - update IFU-factorization (Givens rotations) +* +* This routine updates IFU-factorization of the matrix A according to +* its expansion (see comments to the routine ifu_expand). The routine +* is based on Givens plane rotations [1]. +* +* RETURNS +* +* 0 The factorization has been successfully updated. +* +* 1 On some elimination step both elements u[k,k] and u[n,k] are too +* small in magnitude. +* +* 2 Diagonal element u[n,n] is too small in magnitude (at the end of +* update). +* +* REFERENCES +* +* 1. G.H.Golub, C.F.Van Loan, "Matrix Computations", 2nd ed. */ + +int ifu_gr_update(IFU *ifu, double c[/*1+n*/], double r[/*1+n*/], + double d) +{ /* non-optimized version */ + int n_max = ifu->n_max; + int n = ifu->n; + double *f_ = ifu->f; + double *u_ = ifu->u; +#if 1 /* FIXME */ + double tol = 1e-5; +#endif + int j, k; + double cs, sn; +# define f(i,j) f_[(i)*n_max+(j)] +# define u(i,j) u_[(i)*n_max+(j)] + /* expand factorization */ + ifu_expand(ifu, c, r, d); + /* NOTE: n keeps its old value */ + /* eliminate spike (non-zero subdiagonal elements) in last row of + * matrix U */ + for (k = 0; k < n; k++) + { /* check if elements u[k,k] and u[n,k] are eligible */ + if (fabs(u(k,k)) < tol && fabs(u(n,k)) < tol) + { /* both u[k,k] and u[n,k] are too small in magnitude */ + return 1; + } + /* if u[n,k] = 0, elimination is not needed */ + if (u(n,k) == 0.0) + continue; + /* compute parameters of Givens plane rotation */ + givens(u(k,k), u(n,k), &cs, &sn); + /* apply Givens rotation to k-th and n-th rows of matrix U to + * eliminate u[n,k] */ + for (j = k; j <= n; j++) + { double ukj = u(k,j), unj = u(n,j); + u(k,j) = cs * ukj - sn * unj; + u(n,j) = sn * ukj + cs * unj; + } + /* apply the same transformation to matrix F to keep the main + * equality F * A = U */ + for (j = 0; j <= n; j++) + { double fkj = f(k,j), fnj = f(n,j); + f(k,j) = cs * fkj - sn * fnj; + f(n,j) = sn * fkj + cs * fnj; + } + } + /* now matrix U is upper triangular */ + if (fabs(u(n,n)) < tol) + { /* u[n,n] is too small in magnitude */ + return 2; + } +# undef f +# undef u + return 0; +} + +/*********************************************************************** +* ifu_a_solve - solve system A * x = b +* +* This routine solves the system A * x = b, where the matrix A is +* specified by its IFU-factorization. +* +* Using the main equality F * A = U we have: +* +* A * x = b => F * A * x = F * b => U * x = F * b => +* +* x = inv(U) * F * b. +* +* On entry the array x should contain elements of the right-hand side +* vector b in locations x[1], ..., x[n], where n is the order of the +* matrix A. On exit this array will contain elements of the solution +* vector x in the same locations. +* +* The working array w should have at least 1+n elements (0-th element +* is not used). */ + +void ifu_a_solve(IFU *ifu, double x[/*1+n*/], double w[/*1+n*/]) +{ /* non-optimized version */ + int n_max = ifu->n_max; + int n = ifu->n; + double *f_ = ifu->f; + double *u_ = ifu->u; + int i, j; + double t; +# define f(i,j) f_[(i)*n_max+(j)] +# define u(i,j) u_[(i)*n_max+(j)] + xassert(0 <= n && n <= n_max); + /* adjust indexing */ + x++, w++; + /* y := F * b */ + memcpy(w, x, n * sizeof(double)); + for (i = 0; i < n; i++) + { /* y[i] := (i-th row of F) * b */ + t = 0.0; + for (j = 0; j < n; j++) + t += f(i,j) * w[j]; + x[i] = t; + } + /* x := inv(U) * y */ + for (i = n-1; i >= 0; i--) + { t = x[i]; + for (j = i+1; j < n; j++) + t -= u(i,j) * x[j]; + x[i] = t / u(i,i); + } +# undef f +# undef u + return; +} + +/*********************************************************************** +* ifu_at_solve - solve system A'* x = b +* +* This routine solves the system A'* x = b, where A' is a matrix +* transposed to the matrix A, specified by its IFU-factorization. +* +* Using the main equality F * A = U, from which it follows that +* A'* F' = U', we have: +* +* A'* x = b => A'* F'* inv(F') * x = b => +* +* U'* inv(F') * x = b => inv(F') * x = inv(U') * b => +* +* x = F' * inv(U') * b. +* +* On entry the array x should contain elements of the right-hand side +* vector b in locations x[1], ..., x[n], where n is the order of the +* matrix A. On exit this array will contain elements of the solution +* vector x in the same locations. +* +* The working array w should have at least 1+n elements (0-th element +* is not used). */ + +void ifu_at_solve(IFU *ifu, double x[/*1+n*/], double w[/*1+n*/]) +{ /* non-optimized version */ + int n_max = ifu->n_max; + int n = ifu->n; + double *f_ = ifu->f; + double *u_ = ifu->u; + int i, j; + double t; +# define f(i,j) f_[(i)*n_max+(j)] +# define u(i,j) u_[(i)*n_max+(j)] + xassert(0 <= n && n <= n_max); + /* adjust indexing */ + x++, w++; + /* y := inv(U') * b */ + for (i = 0; i < n; i++) + { t = (x[i] /= u(i,i)); + for (j = i+1; j < n; j++) + x[j] -= u(i,j) * t; + } + /* x := F'* y */ + for (j = 0; j < n; j++) + { /* x[j] := (j-th column of F) * y */ + t = 0.0; + for (i = 0; i < n; i++) + t += f(i,j) * x[i]; + w[j] = t; + } + memcpy(x, w, n * sizeof(double)); +# undef f +# undef u + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/ifu.h b/resources/3rdparty/glpk-4.57/src/bflib/ifu.h new file mode 100644 index 000000000..1c67a8015 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/ifu.h @@ -0,0 +1,99 @@ +/* ifu.h (dense updatable IFU-factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef IFU_H +#define IFU_H + +/*********************************************************************** +* The structure IFU describes dense updatable IFU-factorization. +* +* The IFU-factorization has the following format: +* +* A = inv(F) * U, (1) +* +* where A is a given (unsymmetric) nxn square matrix, F is a square +* matrix, U is an upper triangular matrix. Obviously, the equality (1) +* is equivalent to the following equality: +* +* F * A = U. (2) +* +* It is assumed that matrix A is small and dense, so matrices F and U +* are stored by rows in dense format as follows: +* +* 1 n n_max 1 n n_max +* 1 * * * * * * x x x x 1 * * * * * * x x x x +* * * * * * * x x x x ? * * * * * x x x x +* * * * * * * x x x x ? ? * * * * x x x x +* * * * * * * x x x x ? ? ? * * * x x x x +* * * * * * * x x x x ? ? ? ? * * x x x x +* n * * * * * * x x x x n ? ? ? ? ? * x x x x +* x x x x x x x x x x x x x x x x x x x x +* x x x x x x x x x x x x x x x x x x x x +* x x x x x x x x x x x x x x x x x x x x +* n_max x x x x x x x x x x n_max x x x x x x x x x x +* +* matrix F matrix U +* +* where '*' are matrix elements, '?' are unused locations, 'x' are +* reserved locations. */ + +typedef struct IFU IFU; + +struct IFU +{ /* IFU-factorization */ + int n_max; + /* maximal order of matrices A, F, U; n_max >= 1 */ + int n; + /* current order of matrices A, F, U; 0 <= n <= n_max */ + double *f; /* double f[n_max*n_max]; */ + /* matrix F stored by rows */ + double *u; /* double u[n_max*n_max]; */ + /* matrix U stored by rows */ +}; + +#define ifu_expand _glp_ifu_expand +void ifu_expand(IFU *ifu, double c[/*1+n*/], double r[/*1+n*/], + double d); +/* expand IFU-factorization */ + +#define ifu_bg_update _glp_ifu_bg_update +int ifu_bg_update(IFU *ifu, double c[/*1+n*/], double r[/*1+n*/], + double d); +/* update IFU-factorization (Bartels-Golub) */ + +#define ifu_gr_update _glp_ifu_gr_update +int ifu_gr_update(IFU *ifu, double c[/*1+n*/], double r[/*1+n*/], + double d); +/* update IFU-factorization (Givens rotations) */ + +#define ifu_a_solve _glp_ifu_a_solve +void ifu_a_solve(IFU *ifu, double x[/*1+n*/], double w[/*1+n*/]); +/* solve system A * x = b */ + +#define ifu_at_solve _glp_ifu_at_solve +void ifu_at_solve(IFU *ifu, double x[/*1+n*/], double w[/*1+n*/]); +/* solve system A'* x = b */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/luf.c b/resources/3rdparty/glpk-4.57/src/bflib/luf.c new file mode 100644 index 000000000..2797407d9 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/luf.c @@ -0,0 +1,713 @@ +/* luf.c (sparse LU-factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "luf.h" + +/*********************************************************************** +* luf_store_v_cols - store matrix V = A in column-wise format +* +* This routine stores matrix V = A in column-wise format, where A is +* the original matrix to be factorized. +* +* On exit the routine returns the number of non-zeros in matrix V. */ + +int luf_store_v_cols(LUF *luf, int (*col)(void *info, int j, int ind[], + double val[]), void *info, int ind[], double val[]) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int vc_ref = luf->vc_ref; + int *vc_ptr = &sva->ptr[vc_ref-1]; + int *vc_len = &sva->len[vc_ref-1]; + int *vc_cap = &sva->cap[vc_ref-1]; + int j, len, ptr, nnz; + nnz = 0; + for (j = 1; j <= n; j++) + { /* get j-th column */ + len = col(info, j, ind, val); + xassert(0 <= len && len <= n); + /* enlarge j-th column capacity */ + if (vc_cap[j] < len) + { if (sva->r_ptr - sva->m_ptr < len) + { sva_more_space(sva, len); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_enlarge_cap(sva, vc_ref-1+j, len, 0); + } + /* store j-th column */ + ptr = vc_ptr[j]; + memcpy(&sv_ind[ptr], &ind[1], len * sizeof(int)); + memcpy(&sv_val[ptr], &val[1], len * sizeof(double)); + vc_len[j] = len; + nnz += len; + } + return nnz; +} + +/*********************************************************************** +* luf_check_all - check LU-factorization before k-th elimination step +* +* This routine checks that before performing k-th elimination step, +* 1 <= k <= n+1, all components of the LU-factorization are correct. +* +* In case of k = n+1, i.e. after last elimination step, it is assumed +* that rows of F and columns of V are *not* built yet. +* +* NOTE: For testing/debugging only. */ + +void luf_check_all(LUF *luf, int k) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int fr_ref = luf->fr_ref; + int *fr_len = &sva->len[fr_ref-1]; + int fc_ref = luf->fc_ref; + int *fc_ptr = &sva->ptr[fc_ref-1]; + int *fc_len = &sva->len[fc_ref-1]; + int vr_ref = luf->vr_ref; + int *vr_ptr = &sva->ptr[vr_ref-1]; + int *vr_len = &sva->len[vr_ref-1]; + int vc_ref = luf->vc_ref; + int *vc_ptr = &sva->ptr[vc_ref-1]; + int *vc_len = &sva->len[vc_ref-1]; + int *pp_ind = luf->pp_ind; + int *pp_inv = luf->pp_inv; + int *qq_ind = luf->qq_ind; + int *qq_inv = luf->qq_inv; + int i, ii, i_ptr, i_end, j, jj, j_ptr, j_end; + xassert(n > 0); + xassert(1 <= k && k <= n+1); + /* check permutation matrix P */ + for (i = 1; i <= n; i++) + { ii = pp_ind[i]; + xassert(1 <= ii && ii <= n); + xassert(pp_inv[ii] == i); + } + /* check permutation matrix Q */ + for (j = 1; j <= n; j++) + { jj = qq_inv[j]; + xassert(1 <= jj && jj <= n); + xassert(qq_ind[jj] == j); + } + /* check row-wise representation of matrix F */ + for (i = 1; i <= n; i++) + xassert(fr_len[i] == 0); + /* check column-wise representation of matrix F */ + for (j = 1; j <= n; j++) + { /* j-th column of F = jj-th column of L */ + jj = pp_ind[j]; + if (jj < k) + { j_ptr = fc_ptr[j]; + j_end = j_ptr + fc_len[j]; + for (; j_ptr < j_end; j_ptr++) + { i = sv_ind[j_ptr]; + xassert(1 <= i && i <= n); + ii = pp_ind[i]; /* f[i,j] = l[ii,jj] */ + xassert(ii > jj); + xassert(sv_val[j_ptr] != 0.0); + } + } + else /* jj >= k */ + xassert(fc_len[j] == 0); + } + /* check row-wise representation of matrix V */ + for (i = 1; i <= n; i++) + { /* i-th row of V = ii-th row of U */ + ii = pp_ind[i]; + i_ptr = vr_ptr[i]; + i_end = i_ptr + vr_len[i]; + for (; i_ptr < i_end; i_ptr++) + { j = sv_ind[i_ptr]; + xassert(1 <= j && j <= n); + jj = qq_inv[j]; /* v[i,j] = u[ii,jj] */ + if (ii < k) + xassert(jj > ii); + else /* ii >= k */ + { xassert(jj >= k); + /* find v[i,j] in j-th column */ + j_ptr = vc_ptr[j]; + j_end = j_ptr + vc_len[j]; + for (; sv_ind[j_ptr] != i; j_ptr++) + /* nop */; + xassert(j_ptr < j_end); + } + xassert(sv_val[i_ptr] != 0.0); + } + } + /* check column-wise representation of matrix V */ + for (j = 1; j <= n; j++) + { /* j-th column of V = jj-th column of U */ + jj = qq_inv[j]; + if (jj < k) + xassert(vc_len[j] == 0); + else /* jj >= k */ + { j_ptr = vc_ptr[j]; + j_end = j_ptr + vc_len[j]; + for (; j_ptr < j_end; j_ptr++) + { i = sv_ind[j_ptr]; + ii = pp_ind[i]; /* v[i,j] = u[ii,jj] */ + xassert(ii >= k); + /* find v[i,j] in i-th row */ + i_ptr = vr_ptr[i]; + i_end = i_ptr + vr_len[i]; + for (; sv_ind[i_ptr] != j; i_ptr++) + /* nop */; + xassert(i_ptr < i_end); + } + } + } + return; +} + +/*********************************************************************** +* luf_build_v_rows - build matrix V in row-wise format +* +* This routine builds the row-wise representation of matrix V in the +* left part of SVA using its column-wise representation. +* +* NOTE: On entry to the routine all rows of matrix V should have zero +* capacity. +* +* The working array len should have at least 1+n elements (len[0] is +* not used). */ + +void luf_build_v_rows(LUF *luf, int len[/*1+n*/]) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int vr_ref = luf->vr_ref; + int *vr_ptr = &sva->ptr[vr_ref-1]; + int *vr_len = &sva->len[vr_ref-1]; + int vc_ref = luf->vc_ref; + int *vc_ptr = &sva->ptr[vc_ref-1]; + int *vc_len = &sva->len[vc_ref-1]; + int i, j, end, nnz, ptr, ptr1; + /* calculate the number of non-zeros in each row of matrix V and + * the total number of non-zeros */ + nnz = 0; + for (i = 1; i <= n; i++) + len[i] = 0; + for (j = 1; j <= n; j++) + { nnz += vc_len[j]; + for (end = (ptr = vc_ptr[j]) + vc_len[j]; ptr < end; ptr++) + len[sv_ind[ptr]]++; + } + /* we need at least nnz free locations in SVA */ + if (sva->r_ptr - sva->m_ptr < nnz) + { sva_more_space(sva, nnz); + sv_ind = sva->ind; + sv_val = sva->val; + } + /* reserve locations for rows of matrix V */ + for (i = 1; i <= n; i++) + { if (len[i] > 0) + sva_enlarge_cap(sva, vr_ref-1+i, len[i], 0); + vr_len[i] = len[i]; + } + /* walk thru column of matrix V and build its rows */ + for (j = 1; j <= n; j++) + { for (end = (ptr = vc_ptr[j]) + vc_len[j]; ptr < end; ptr++) + { i = sv_ind[ptr]; + sv_ind[ptr1 = vr_ptr[i] + (--len[i])] = j; + sv_val[ptr1] = sv_val[ptr]; + } + } + return; +} + +/*********************************************************************** +* luf_build_f_rows - build matrix F in row-wise format +* +* This routine builds the row-wise representation of matrix F in the +* right part of SVA using its column-wise representation. +* +* NOTE: On entry to the routine all rows of matrix F should have zero +* capacity. +* +* The working array len should have at least 1+n elements (len[0] is +* not used). */ + +void luf_build_f_rows(LUF *luf, int len[/*1+n*/]) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int fr_ref = luf->fr_ref; + int *fr_ptr = &sva->ptr[fr_ref-1]; + int *fr_len = &sva->len[fr_ref-1]; + int fc_ref = luf->fc_ref; + int *fc_ptr = &sva->ptr[fc_ref-1]; + int *fc_len = &sva->len[fc_ref-1]; + int i, j, end, nnz, ptr, ptr1; + /* calculate the number of non-zeros in each row of matrix F and + * the total number of non-zeros (except diagonal elements) */ + nnz = 0; + for (i = 1; i <= n; i++) + len[i] = 0; + for (j = 1; j <= n; j++) + { nnz += fc_len[j]; + for (end = (ptr = fc_ptr[j]) + fc_len[j]; ptr < end; ptr++) + len[sv_ind[ptr]]++; + } + /* we need at least nnz free locations in SVA */ + if (sva->r_ptr - sva->m_ptr < nnz) + { sva_more_space(sva, nnz); + sv_ind = sva->ind; + sv_val = sva->val; + } + /* reserve locations for rows of matrix F */ + for (i = 1; i <= n; i++) + { if (len[i] > 0) + sva_reserve_cap(sva, fr_ref-1+i, len[i]); + fr_len[i] = len[i]; + } + /* walk through columns of matrix F and build its rows */ + for (j = 1; j <= n; j++) + { for (end = (ptr = fc_ptr[j]) + fc_len[j]; ptr < end; ptr++) + { i = sv_ind[ptr]; + sv_ind[ptr1 = fr_ptr[i] + (--len[i])] = j; + sv_val[ptr1] = sv_val[ptr]; + } + } + return; +} + +/*********************************************************************** +* luf_build_v_cols - build matrix V in column-wise format +* +* This routine builds the column-wise representation of matrix V in +* the left (if the flag updat is set) or right (if the flag updat is +* clear) part of SVA using its row-wise representation. +* +* NOTE: On entry to the routine all columns of matrix V should have +* zero capacity. +* +* The working array len should have at least 1+n elements (len[0] is +* not used). */ + +void luf_build_v_cols(LUF *luf, int updat, int len[/*1+n*/]) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int vr_ref = luf->vr_ref; + int *vr_ptr = &sva->ptr[vr_ref-1]; + int *vr_len = &sva->len[vr_ref-1]; + int vc_ref = luf->vc_ref; + int *vc_ptr = &sva->ptr[vc_ref-1]; + int *vc_len = &sva->len[vc_ref-1]; + int i, j, end, nnz, ptr, ptr1; + /* calculate the number of non-zeros in each column of matrix V + * and the total number of non-zeros (except pivot elements) */ + nnz = 0; + for (j = 1; j <= n; j++) + len[j] = 0; + for (i = 1; i <= n; i++) + { nnz += vr_len[i]; + for (end = (ptr = vr_ptr[i]) + vr_len[i]; ptr < end; ptr++) + len[sv_ind[ptr]]++; + } + /* we need at least nnz free locations in SVA */ + if (sva->r_ptr - sva->m_ptr < nnz) + { sva_more_space(sva, nnz); + sv_ind = sva->ind; + sv_val = sva->val; + } + /* reserve locations for columns of matrix V */ + for (j = 1; j <= n; j++) + { if (len[j] > 0) + { if (updat) + sva_enlarge_cap(sva, vc_ref-1+j, len[j], 0); + else + sva_reserve_cap(sva, vc_ref-1+j, len[j]); + } + vc_len[j] = len[j]; + } + /* walk through rows of matrix V and build its columns */ + for (i = 1; i <= n; i++) + { for (end = (ptr = vr_ptr[i]) + vr_len[i]; ptr < end; ptr++) + { j = sv_ind[ptr]; + sv_ind[ptr1 = vc_ptr[j] + (--len[j])] = i; + sv_val[ptr1] = sv_val[ptr]; + } + } + return; +} + +/*********************************************************************** +* luf_check_f_rc - check rows and columns of matrix F +* +* This routine checks that the row- and column-wise representations +* of matrix F are identical. +* +* NOTE: For testing/debugging only. */ + +void luf_check_f_rc(LUF *luf) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int fr_ref = luf->fr_ref; + int *fr_ptr = &sva->ptr[fr_ref-1]; + int *fr_len = &sva->len[fr_ref-1]; + int fc_ref = luf->fc_ref; + int *fc_ptr = &sva->ptr[fc_ref-1]; + int *fc_len = &sva->len[fc_ref-1]; + int i, i_end, i_ptr, j, j_end, j_ptr; + /* walk thru rows of matrix F */ + for (i = 1; i <= n; i++) + { for (i_end = (i_ptr = fr_ptr[i]) + fr_len[i]; + i_ptr < i_end; i_ptr++) + { j = sv_ind[i_ptr]; + /* find element f[i,j] in j-th column of matrix F */ + for (j_end = (j_ptr = fc_ptr[j]) + fc_len[j]; + sv_ind[j_ptr] != i; j_ptr++) + /* nop */; + xassert(j_ptr < j_end); + xassert(sv_val[i_ptr] == sv_val[j_ptr]); + /* mark element f[i,j] */ + sv_ind[j_ptr] = -i; + } + } + /* walk thru column of matix F and check that all elements has + been marked */ + for (j = 1; j <= n; j++) + { for (j_end = (j_ptr = fc_ptr[j]) + fc_len[j]; + j_ptr < j_end; j_ptr++) + { xassert((i = sv_ind[j_ptr]) < 0); + /* unmark element f[i,j] */ + sv_ind[j_ptr] = -i; + } + } + return; +} + +/*********************************************************************** +* luf_check_v_rc - check rows and columns of matrix V +* +* This routine checks that the row- and column-wise representations +* of matrix V are identical. +* +* NOTE: For testing/debugging only. */ + +void luf_check_v_rc(LUF *luf) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int vr_ref = luf->vr_ref; + int *vr_ptr = &sva->ptr[vr_ref-1]; + int *vr_len = &sva->len[vr_ref-1]; + int vc_ref = luf->vc_ref; + int *vc_ptr = &sva->ptr[vc_ref-1]; + int *vc_len = &sva->len[vc_ref-1]; + int i, i_end, i_ptr, j, j_end, j_ptr; + /* walk thru rows of matrix V */ + for (i = 1; i <= n; i++) + { for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; + i_ptr < i_end; i_ptr++) + { j = sv_ind[i_ptr]; + /* find element v[i,j] in j-th column of matrix V */ + for (j_end = (j_ptr = vc_ptr[j]) + vc_len[j]; + sv_ind[j_ptr] != i; j_ptr++) + /* nop */; + xassert(j_ptr < j_end); + xassert(sv_val[i_ptr] == sv_val[j_ptr]); + /* mark element v[i,j] */ + sv_ind[j_ptr] = -i; + } + } + /* walk thru column of matix V and check that all elements has + been marked */ + for (j = 1; j <= n; j++) + { for (j_end = (j_ptr = vc_ptr[j]) + vc_len[j]; + j_ptr < j_end; j_ptr++) + { xassert((i = sv_ind[j_ptr]) < 0); + /* unmark element v[i,j] */ + sv_ind[j_ptr] = -i; + } + } + return; +} + +/*********************************************************************** +* luf_f_solve - solve system F * x = b +* +* This routine solves the system F * x = b, where the matrix F is the +* left factor of the sparse LU-factorization. +* +* On entry the array x should contain elements of the right-hand side +* vector b in locations x[1], ..., x[n], where n is the order of the +* matrix F. On exit this array will contain elements of the solution +* vector x in the same locations. */ + +void luf_f_solve(LUF *luf, double x[/*1+n*/]) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int fc_ref = luf->fc_ref; + int *fc_ptr = &sva->ptr[fc_ref-1]; + int *fc_len = &sva->len[fc_ref-1]; + int *pp_inv = luf->pp_inv; + int j, k, ptr, end; + double x_j; + for (k = 1; k <= n; k++) + { /* k-th column of L = j-th column of F */ + j = pp_inv[k]; + /* x[j] is already computed */ + /* walk thru j-th column of matrix F and substitute x[j] into + * other equations */ + if ((x_j = x[j]) != 0.0) + { for (end = (ptr = fc_ptr[j]) + fc_len[j]; ptr < end; ptr++) + x[sv_ind[ptr]] -= sv_val[ptr] * x_j; + } + } + return; +} + +/*********************************************************************** +* luf_ft_solve - solve system F' * x = b +* +* This routine solves the system F' * x = b, where F' is a matrix +* transposed to the matrix F, which is the left factor of the sparse +* LU-factorization. +* +* On entry the array x should contain elements of the right-hand side +* vector b in locations x[1], ..., x[n], where n is the order of the +* matrix F. On exit this array will contain elements of the solution +* vector x in the same locations. */ + +void luf_ft_solve(LUF *luf, double x[/*1+n*/]) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int fr_ref = luf->fr_ref; + int *fr_ptr = &sva->ptr[fr_ref-1]; + int *fr_len = &sva->len[fr_ref-1]; + int *pp_inv = luf->pp_inv; + int i, k, ptr, end; + double x_i; + for (k = n; k >= 1; k--) + { /* k-th column of L' = i-th row of F */ + i = pp_inv[k]; + /* x[i] is already computed */ + /* walk thru i-th row of matrix F and substitute x[i] into + * other equations */ + if ((x_i = x[i]) != 0.0) + { for (end = (ptr = fr_ptr[i]) + fr_len[i]; ptr < end; ptr++) + x[sv_ind[ptr]] -= sv_val[ptr] * x_i; + } + } + return; +} + +/*********************************************************************** +* luf_v_solve - solve system V * x = b +* +* This routine solves the system V * x = b, where the matrix V is the +* right factor of the sparse LU-factorization. +* +* On entry the array b should contain elements of the right-hand side +* vector b in locations b[1], ..., b[n], where n is the order of the +* matrix V. On exit the array x will contain elements of the solution +* vector x in locations x[1], ..., x[n]. Note that the array b will be +* clobbered on exit. */ + +void luf_v_solve(LUF *luf, double b[/*1+n*/], double x[/*1+n*/]) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + double *vr_piv = luf->vr_piv; + int vc_ref = luf->vc_ref; + int *vc_ptr = &sva->ptr[vc_ref-1]; + int *vc_len = &sva->len[vc_ref-1]; + int *pp_inv = luf->pp_inv; + int *qq_ind = luf->qq_ind; + int i, j, k, ptr, end; + double x_j; + for (k = n; k >= 1; k--) + { /* k-th row of U = i-th row of V */ + /* k-th column of U = j-th column of V */ + i = pp_inv[k]; + j = qq_ind[k]; + /* compute x[j] = b[i] / u[k,k], where u[k,k] = v[i,j]; + * walk through j-th column of matrix V and substitute x[j] + * into other equations */ + if ((x_j = x[j] = b[i] / vr_piv[i]) != 0.0) + { for (end = (ptr = vc_ptr[j]) + vc_len[j]; ptr < end; ptr++) + b[sv_ind[ptr]] -= sv_val[ptr] * x_j; + } + } + return; +} + +/*********************************************************************** +* luf_vt_solve - solve system V' * x = b +* +* This routine solves the system V' * x = b, where V' is a matrix +* transposed to the matrix V, which is the right factor of the sparse +* LU-factorization. +* +* On entry the array b should contain elements of the right-hand side +* vector b in locations b[1], ..., b[n], where n is the order of the +* matrix V. On exit the array x will contain elements of the solution +* vector x in locations x[1], ..., x[n]. Note that the array b will be +* clobbered on exit. */ + +void luf_vt_solve(LUF *luf, double b[/*1+n*/], double x[/*1+n*/]) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + double *vr_piv = luf->vr_piv; + int vr_ref = luf->vr_ref; + int *vr_ptr = &sva->ptr[vr_ref-1]; + int *vr_len = &sva->len[vr_ref-1]; + int *pp_inv = luf->pp_inv; + int *qq_ind = luf->qq_ind; + int i, j, k, ptr, end; + double x_i; + for (k = 1; k <= n; k++) + { /* k-th row of U' = j-th column of V */ + /* k-th column of U' = i-th row of V */ + i = pp_inv[k]; + j = qq_ind[k]; + /* compute x[i] = b[j] / u'[k,k], where u'[k,k] = v[i,j]; + * walk through i-th row of matrix V and substitute x[i] into + * other equations */ + if ((x_i = x[i] = b[j] / vr_piv[i]) != 0.0) + { for (end = (ptr = vr_ptr[i]) + vr_len[i]; ptr < end; ptr++) + b[sv_ind[ptr]] -= sv_val[ptr] * x_i; + } + } + return; +} + +/*********************************************************************** +* luf_vt_solve1 - solve system V' * y = e' to cause growth in y +* +* This routine is a special version of luf_vt_solve. It solves the +* system V'* y = e' = e + delta e, where V' is a matrix transposed to +* the matrix V, e is the specified right-hand side vector, and delta e +* is a vector of +1 and -1 chosen to cause growth in the solution +* vector y. +* +* On entry the array e should contain elements of the right-hand side +* vector e in locations e[1], ..., e[n], where n is the order of the +* matrix V. On exit the array y will contain elements of the solution +* vector y in locations y[1], ..., y[n]. Note that the array e will be +* clobbered on exit. */ + +void luf_vt_solve1(LUF *luf, double e[/*1+n*/], double y[/*1+n*/]) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + double *vr_piv = luf->vr_piv; + int vr_ref = luf->vr_ref; + int *vr_ptr = &sva->ptr[vr_ref-1]; + int *vr_len = &sva->len[vr_ref-1]; + int *pp_inv = luf->pp_inv; + int *qq_ind = luf->qq_ind; + int i, j, k, ptr, end; + double e_j, y_i; + for (k = 1; k <= n; k++) + { /* k-th row of U' = j-th column of V */ + /* k-th column of U' = i-th row of V */ + i = pp_inv[k]; + j = qq_ind[k]; + /* determine e'[j] = e[j] + delta e[j] */ + e_j = (e[j] >= 0.0 ? e[j] + 1.0 : e[j] - 1.0); + /* compute y[i] = e'[j] / u'[k,k], where u'[k,k] = v[i,j] */ + y_i = y[i] = e_j / vr_piv[i]; + /* walk through i-th row of matrix V and substitute y[i] into + * other equations */ + for (end = (ptr = vr_ptr[i]) + vr_len[i]; ptr < end; ptr++) + e[sv_ind[ptr]] -= sv_val[ptr] * y_i; + } + return; +} + +/*********************************************************************** +* luf_estimate_norm - estimate 1-norm of inv(A) +* +* This routine estimates 1-norm of inv(A) by one step of inverse +* iteration for the small singular vector as described in [1]. This +* involves solving two systems of equations: +* +* A'* y = e, +* +* A * z = y, +* +* where A' is a matrix transposed to A, and e is a vector of +1 and -1 +* chosen to cause growth in y. Then +* +* estimate 1-norm of inv(A) = (1-norm of z) / (1-norm of y) +* +* REFERENCES +* +* 1. G.E.Forsythe, M.A.Malcolm, C.B.Moler. Computer Methods for +* Mathematical Computations. Prentice-Hall, Englewood Cliffs, N.J., +* pp. 30-62 (subroutines DECOMP and SOLVE). */ + +double luf_estimate_norm(LUF *luf, double w1[/*1+n*/], double + w2[/*1+n*/]) +{ int n = luf->n; + double *e = w1; + double *y = w2; + double *z = w1; + int i; + double y_norm, z_norm; + /* y = inv(A') * e = inv(F') * inv(V') * e */ + /* compute y' = inv(V') * e to cause growth in y' */ + for (i = 1; i <= n; i++) + e[i] = 0.0; + luf_vt_solve1(luf, e, y); + /* compute y = inv(F') * y' */ + luf_ft_solve(luf, y); + /* compute 1-norm of y = sum |y[i]| */ + y_norm = 0.0; + for (i = 1; i <= n; i++) + y_norm += (y[i] >= 0.0 ? +y[i] : -y[i]); + /* z = inv(A) * y = inv(V) * inv(F) * y */ + /* compute z' = inv(F) * y */ + luf_f_solve(luf, y); + /* compute z = inv(V) * z' */ + luf_v_solve(luf, y, z); + /* compute 1-norm of z = sum |z[i]| */ + z_norm = 0.0; + for (i = 1; i <= n; i++) + z_norm += (z[i] >= 0.0 ? +z[i] : -z[i]); + /* estimate 1-norm of inv(A) = (1-norm of z) / (1-norm of y) */ + return z_norm / y_norm; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/luf.h b/resources/3rdparty/glpk-4.57/src/bflib/luf.h new file mode 100644 index 000000000..d9264095a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/luf.h @@ -0,0 +1,227 @@ +/* luf.h (sparse LU-factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef LUF_H +#define LUF_H + +#include "sva.h" + +/*********************************************************************** +* The structure LUF describes sparse LU-factorization. +* +* The LU-factorization has the following format: +* +* A = F * V = P * L * U * Q, (1) +* +* F = P * L * P', (2) +* +* V = P * U * Q, (3) +* +* where A is a given (unsymmetric) square matrix, F and V are matrix +* factors actually computed, L is a lower triangular matrix with unity +* diagonal, U is an upper triangular matrix, P and Q are permutation +* matrices, P' is a matrix transposed to P. All the matrices have the +* same order n. +* +* Matrices F and V are stored in both row- and column-wise sparse +* formats in the associated sparse vector area (SVA). Unity diagonal +* elements of matrix F are not stored. Pivot elements of matrix V +* (which correspond to diagonal elements of matrix U) are stored in +* a separate ordinary array. +* +* Permutation matrices P and Q are stored in ordinary arrays in both +* row- and column-like formats. +* +* Matrices L and U are completely defined by matrices F, V, P, and Q, +* and therefore not stored explicitly. */ + +typedef struct LUF LUF; + +struct LUF +{ /* sparse LU-factorization */ + int n; + /* order of matrices A, F, V, P, Q */ + SVA *sva; + /* associated sparse vector area (SVA) used to store rows and + * columns of matrices F and V; note that different objects may + * share the same SVA */ + /*--------------------------------------------------------------*/ + /* matrix F in row-wise format */ + /* during the factorization process this object is not used */ + int fr_ref; + /* reference number of sparse vector in SVA, which is the first + * row of matrix F */ +#if 0 + 0 + int *fr_ptr = &sva->ptr[fr_ref-1]; + /* fr_ptr[0] is not used; + * fr_ptr[i], 1 <= i <= n, is pointer to i-th row in SVA */ + int *fr_len = &sva->len[fr_ref-1]; + /* fr_len[0] is not used; + * fr_len[i], 1 <= i <= n, is length of i-th row */ +#endif + /*--------------------------------------------------------------*/ + /* matrix F in column-wise format */ + /* during the factorization process this object is constructed + by columns */ + int fc_ref; + /* reference number of sparse vector in SVA, which is the first + * column of matrix F */ +#if 0 + 0 + int *fc_ptr = &sva->ptr[fc_ref-1]; + /* fc_ptr[0] is not used; + * fc_ptr[j], 1 <= j <= n, is pointer to j-th column in SVA */ + int *fc_len = &sva->len[fc_ref-1]; + /* fc_len[0] is not used; + * fc_len[j], 1 <= j <= n, is length of j-th column */ +#endif + /*--------------------------------------------------------------*/ + /* matrix V in row-wise format */ + int vr_ref; + /* reference number of sparse vector in SVA, which is the first + * row of matrix V */ +#if 0 + 0 + int *vr_ptr = &sva->ptr[vr_ref-1]; + /* vr_ptr[0] is not used; + * vr_ptr[i], 1 <= i <= n, is pointer to i-th row in SVA */ + int *vr_len = &sva->len[vr_ref-1]; + /* vr_len[0] is not used; + * vr_len[i], 1 <= i <= n, is length of i-th row */ + int *vr_cap = &sva->cap[vr_ref-1]; + /* vr_cap[0] is not used; + * vr_cap[i], 1 <= i <= n, is capacity of i-th row */ +#endif + double *vr_piv; /* double vr_piv[1+n]; */ + /* vr_piv[0] is not used; + * vr_piv[i], 1 <= i <= n, is pivot element of i-th row */ + /*--------------------------------------------------------------*/ + /* matrix V in column-wise format */ + /* during the factorization process this object contains only the + * patterns (row indices) of columns of the active submatrix */ + int vc_ref; + /* reference number of sparse vector in SVA, which is the first + * column of matrix V */ +#if 0 + 0 + int *vc_ptr = &sva->ptr[vc_ref-1]; + /* vc_ptr[0] is not used; + * vc_ptr[j], 1 <= j <= n, is pointer to j-th column in SVA */ + int *vc_len = &sva->len[vc_ref-1]; + /* vc_len[0] is not used; + * vc_len[j], 1 <= j <= n, is length of j-th column */ + int *vc_cap = &sva->cap[vc_ref-1]; + /* vc_cap[0] is not used; + * vc_cap[j], 1 <= j <= n, is capacity of j-th column */ +#endif + /*--------------------------------------------------------------*/ + /* matrix P */ + int *pp_ind; /* int pp_ind[1+n]; */ + /* pp_ind[i] = j means that P[i,j] = 1 */ + int *pp_inv; /* int pp_inv[1+n]; */ + /* pp_inv[j] = i means that P[i,j] = 1 */ + /* if i-th row or column of matrix F is i'-th row or column of + * matrix L, or if i-th row of matrix V is i'-th row of matrix U, + * then pp_ind[i] = i' and pp_inv[i'] = i */ + /*--------------------------------------------------------------*/ + /* matrix Q */ + int *qq_ind; /* int qq_ind[1+n]; */ + /* qq_ind[i] = j means that Q[i,j] = 1 */ + int *qq_inv; /* int qq_inv[1+n]; */ + /* qq_inv[j] = i means that Q[i,j] = 1 */ + /* if j-th column of matrix V is j'-th column of matrix U, then + * qq_ind[j'] = j and qq_inv[j] = j' */ +}; + +#define luf_swap_u_rows(i1, i2) \ + do \ + { int j1, j2; \ + j1 = pp_inv[i1], j2 = pp_inv[i2]; \ + pp_ind[j1] = i2, pp_inv[i2] = j1; \ + pp_ind[j2] = i1, pp_inv[i1] = j2; \ + } while (0) +/* swap rows i1 and i2 of matrix U = P'* V * Q' */ + +#define luf_swap_u_cols(j1, j2) \ + do \ + { int i1, i2; \ + i1 = qq_ind[j1], i2 = qq_ind[j2]; \ + qq_ind[j1] = i2, qq_inv[i2] = j1; \ + qq_ind[j2] = i1, qq_inv[i1] = j2; \ + } while (0) +/* swap columns j1 and j2 of matrix U = P'* V * Q' */ + +#define luf_store_v_cols _glp_luf_store_v_cols +int luf_store_v_cols(LUF *luf, int (*col)(void *info, int j, int ind[], + double val[]), void *info, int ind[], double val[]); +/* store matrix V = A in column-wise format */ + +#define luf_check_all _glp_luf_check_all +void luf_check_all(LUF *luf, int k); +/* check LU-factorization before k-th elimination step */ + +#define luf_build_v_rows _glp_luf_build_v_rows +void luf_build_v_rows(LUF *luf, int len[/*1+n*/]); +/* build matrix V in row-wise format */ + +#define luf_build_f_rows _glp_luf_build_f_rows +void luf_build_f_rows(LUF *luf, int len[/*1+n*/]); +/* build matrix F in row-wise format */ + +#define luf_build_v_cols _glp_luf_build_v_cols +void luf_build_v_cols(LUF *luf, int updat, int len[/*1+n*/]); +/* build matrix V in column-wise format */ + +#define luf_check_f_rc _glp_luf_check_f_rc +void luf_check_f_rc(LUF *luf); +/* check rows and columns of matrix F */ + +#define luf_check_v_rc _glp_luf_check_v_rc +void luf_check_v_rc(LUF *luf); +/* check rows and columns of matrix V */ + +#define luf_f_solve _glp_luf_f_solve +void luf_f_solve(LUF *luf, double x[/*1+n*/]); +/* solve system F * x = b */ + +#define luf_ft_solve _glp_luf_ft_solve +void luf_ft_solve(LUF *luf, double x[/*1+n*/]); +/* solve system F' * x = b */ + +#define luf_v_solve _glp_luf_v_solve +void luf_v_solve(LUF *luf, double b[/*1+n*/], double x[/*1+n*/]); +/* solve system V * x = b */ + +#define luf_vt_solve _glp_luf_vt_solve +void luf_vt_solve(LUF *luf, double b[/*1+n*/], double x[/*1+n*/]); +/* solve system V' * x = b */ + +#define luf_vt_solve1 _glp_luf_vt_solve1 +void luf_vt_solve1(LUF *luf, double e[/*1+n*/], double y[/*1+n*/]); +/* solve system V' * y = e' to cause growth in y */ + +#define luf_estimate_norm _glp_luf_estimate_norm +double luf_estimate_norm(LUF *luf, double w1[/*1+n*/], double + w2[/*1+n*/]); +/* estimate 1-norm of inv(A) */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/lufint.c b/resources/3rdparty/glpk-4.57/src/bflib/lufint.c new file mode 100644 index 000000000..7cd00924f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/lufint.c @@ -0,0 +1,182 @@ +/* lufint.c (interface to LU-factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "lufint.h" + +LUFINT *lufint_create(void) +{ /* create interface to LU-factorization */ + LUFINT *fi; + fi = talloc(1, LUFINT); + fi->n_max = 0; + fi->valid = 0; + fi->sva = NULL; + fi->luf = NULL; + fi->sgf = NULL; + fi->sva_n_max = fi->sva_size = 0; + fi->delta_n0 = fi->delta_n = 0; + fi->sgf_updat = 0; + fi->sgf_piv_tol = 0.10; + fi->sgf_piv_lim = 4; + fi->sgf_suhl = 1; + fi->sgf_eps_tol = DBL_EPSILON; + return fi; +} + +int lufint_factorize(LUFINT *fi, int n, int (*col)(void *info, int j, + int ind[], double val[]), void *info) +{ /* compute LU-factorization of specified matrix A */ + SVA *sva; + LUF *luf; + SGF *sgf; + int k; + xassert(n > 0); + fi->valid = 0; + /* create sparse vector area (SVA), if necessary */ + sva = fi->sva; + if (sva == NULL) + { int sva_n_max = fi->sva_n_max; + int sva_size = fi->sva_size; + if (sva_n_max == 0) + sva_n_max = 4 * n; + if (sva_size == 0) + sva_size = 10 * n; + sva = fi->sva = sva_create_area(sva_n_max, sva_size); + } + /* allocate/reallocate underlying objects, if necessary */ + if (fi->n_max < n) + { int n_max = fi->n_max; + if (n_max == 0) + n_max = fi->n_max = n + fi->delta_n0; + else + n_max = fi->n_max = n + fi->delta_n; + xassert(n_max >= n); + /* allocate/reallocate LU-factorization (LUF) */ + luf = fi->luf; + if (luf == NULL) + { luf = fi->luf = talloc(1, LUF); + memset(luf, 0, sizeof(LUF)); + luf->sva = sva; + } + else + { tfree(luf->vr_piv); + tfree(luf->pp_ind); + tfree(luf->pp_inv); + tfree(luf->qq_ind); + tfree(luf->qq_inv); + } + luf->vr_piv = talloc(1+n_max, double); + luf->pp_ind = talloc(1+n_max, int); + luf->pp_inv = talloc(1+n_max, int); + luf->qq_ind = talloc(1+n_max, int); + luf->qq_inv = talloc(1+n_max, int); + /* allocate/reallocate factorizer workspace (SGF) */ + sgf = fi->sgf; + if (sgf == NULL) + { sgf = fi->sgf = talloc(1, SGF); + memset(sgf, 0, sizeof(SGF)); + sgf->luf = luf; + } + else + { tfree(sgf->rs_head); + tfree(sgf->rs_prev); + tfree(sgf->rs_next); + tfree(sgf->cs_head); + tfree(sgf->cs_prev); + tfree(sgf->cs_next); + tfree(sgf->vr_max); + tfree(sgf->flag); + tfree(sgf->work); + } + sgf->rs_head = talloc(1+n_max, int); + sgf->rs_prev = talloc(1+n_max, int); + sgf->rs_next = talloc(1+n_max, int); + sgf->cs_head = talloc(1+n_max, int); + sgf->cs_prev = talloc(1+n_max, int); + sgf->cs_next = talloc(1+n_max, int); + sgf->vr_max = talloc(1+n_max, double); + sgf->flag = talloc(1+n_max, char); + sgf->work = talloc(1+n_max, double); + } + luf = fi->luf; + sgf = fi->sgf; +#if 1 /* FIXME */ + /* initialize SVA */ + sva->n = 0; + sva->m_ptr = 1; + sva->r_ptr = sva->size + 1; + sva->head = sva->tail = 0; +#endif + /* allocate sparse vectors in SVA */ + luf->n = n; + luf->fr_ref = sva_alloc_vecs(sva, n); + luf->fc_ref = sva_alloc_vecs(sva, n); + luf->vr_ref = sva_alloc_vecs(sva, n); + luf->vc_ref = sva_alloc_vecs(sva, n); + /* store matrix V = A in column-wise format */ + luf_store_v_cols(luf, col, info, sgf->rs_prev, sgf->work); + /* setup factorizer control parameters */ + sgf->updat = fi->sgf_updat; + sgf->piv_tol = fi->sgf_piv_tol; + sgf->piv_lim = fi->sgf_piv_lim; + sgf->suhl = fi->sgf_suhl; + sgf->eps_tol = fi->sgf_eps_tol; + /* compute LU-factorization of specified matrix A */ + k = sgf_factorize(sgf, 1); + if (k == 0) + fi->valid = 1; + return k; +} + +void lufint_delete(LUFINT *fi) +{ /* delete interface to LU-factorization */ + SVA *sva = fi->sva; + LUF *luf = fi->luf; + SGF *sgf = fi->sgf; + if (sva != NULL) + sva_delete_area(sva); + if (luf != NULL) + { tfree(luf->vr_piv); + tfree(luf->pp_ind); + tfree(luf->pp_inv); + tfree(luf->qq_ind); + tfree(luf->qq_inv); + tfree(luf); + } + if (sgf != NULL) + { tfree(sgf->rs_head); + tfree(sgf->rs_prev); + tfree(sgf->rs_next); + tfree(sgf->cs_head); + tfree(sgf->cs_prev); + tfree(sgf->cs_next); + tfree(sgf->vr_max); + tfree(sgf->flag); + tfree(sgf->work); + tfree(sgf); + } + tfree(fi); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/lufint.h b/resources/3rdparty/glpk-4.57/src/bflib/lufint.h new file mode 100644 index 000000000..b3ad5b646 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/lufint.h @@ -0,0 +1,73 @@ +/* lufint.h (interface to LU-factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef LUFINT_H +#define LUFINT_H + +#include "sgf.h" + +typedef struct LUFINT LUFINT; + +struct LUFINT +{ /* interface to LU-factorization */ + int n_max; + /* maximal value of n (increased automatically) */ + int valid; + /* factorization is valid only if this flag is set */ + SVA *sva; + /* sparse vector area (SVA) */ + LUF *luf; + /* sparse LU-factorization */ + SGF *sgf; + /* sparse Gaussian factorizer workspace */ + /*--------------------------------------------------------------*/ + /* control parameters */ + int sva_n_max, sva_size; + /* parameters passed to sva_create_area */ + int delta_n0, delta_n; + /* if n_max = 0, set n_max = n + delta_n0 + * if n_max < n, set n_max = n + delta_n */ + int sgf_updat; + double sgf_piv_tol; + int sgf_piv_lim; + int sgf_suhl; + double sgf_eps_tol; + /* factorizer control parameters */ +}; + +#define lufint_create _glp_lufint_create +LUFINT *lufint_create(void); +/* create interface to LU-factorization */ + +#define lufint_factorize _glp_lufint_factorize +int lufint_factorize(LUFINT *fi, int n, int (*col)(void *info, int j, + int ind[], double val[]), void *info); +/* compute LU-factorization of specified matrix A */ + +#define lufint_delete _glp_lufint_delete +void lufint_delete(LUFINT *fi); +/* delete interface to LU-factorization */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/scf.c b/resources/3rdparty/glpk-4.57/src/bflib/scf.c new file mode 100644 index 000000000..556b19114 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/scf.c @@ -0,0 +1,523 @@ +/* scf.c (sparse updatable Schur-complement-based factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2013-2014 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "scf.h" + +/*********************************************************************** +* scf_r0_solve - solve system R0 * x = b or R0'* x = b +* +* This routine solves the system R0 * x = b (if tr is zero) or the +* system R0'* x = b (if tr is non-zero), where R0 is the left factor +* of the initial matrix A0 = R0 * S0. +* +* On entry the array x should contain elements of the right-hand side +* vector b in locations x[1], ..., x[n0], where n0 is the order of the +* matrix R0. On exit the array x will contain elements of the solution +* vector in the same locations. */ + +void scf_r0_solve(SCF *scf, int tr, double x[/*1+n0*/]) +{ switch (scf->type) + { case 1: + /* A0 = F0 * V0, so R0 = F0 */ + if (!tr) + luf_f_solve(scf->a0.luf, x); + else + luf_ft_solve(scf->a0.luf, x); + break; + case 2: + /* A0 = I * A0, so R0 = I */ + break; + default: + xassert(scf != scf); + } + return; +} + +/*********************************************************************** +* scf_s0_solve - solve system S0 * x = b or S0'* x = b +* +* This routine solves the system S0 * x = b (if tr is zero) or the +* system S0'* x = b (if tr is non-zero), where S0 is the right factor +* of the initial matrix A0 = R0 * S0. +* +* On entry the array x should contain elements of the right-hand side +* vector b in locations x[1], ..., x[n0], where n0 is the order of the +* matrix S0. On exit the array x will contain elements of the solution +* vector in the same locations. +* +* The routine uses locations [1], ..., [n0] of three working arrays +* w1, w2, and w3. (In case of type = 1 arrays w2 and w3 are not used +* and can be specified as NULL.) */ + +void scf_s0_solve(SCF *scf, int tr, double x[/*1+n0*/], + double w1[/*1+n0*/], double w2[/*1+n0*/], double w3[/*1+n0*/]) +{ int n0 = scf->n0; + switch (scf->type) + { case 1: + /* A0 = F0 * V0, so S0 = V0 */ + if (!tr) + luf_v_solve(scf->a0.luf, x, w1); + else + luf_vt_solve(scf->a0.luf, x, w1); + break; + case 2: + /* A0 = I * A0, so S0 = A0 */ + if (!tr) + btf_a_solve(scf->a0.btf, x, w1, w2, w3); + else + btf_at_solve(scf->a0.btf, x, w1, w2, w3); + break; + default: + xassert(scf != scf); + } + memcpy(&x[1], &w1[1], n0 * sizeof(double)); + return; +} + +/*********************************************************************** +* scf_r_prod - compute product y := y + alpha * R * x +* +* This routine computes the product y := y + alpha * R * x, where +* x is a n0-vector, alpha is a scalar, y is a nn-vector. +* +* Since matrix R is available by rows, the product components are +* computed as inner products: +* +* y[i] = y[i] + alpha * (i-th row of R) * x +* +* for i = 1, 2, ..., nn. */ + +void scf_r_prod(SCF *scf, double y[/*1+nn*/], double a, const double + x[/*1+n0*/]) +{ int nn = scf->nn; + SVA *sva = scf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int rr_ref = scf->rr_ref; + int *rr_ptr = &sva->ptr[rr_ref-1]; + int *rr_len = &sva->len[rr_ref-1]; + int i, ptr, end; + double t; + for (i = 1; i <= nn; i++) + { /* t := (i-th row of R) * x */ + t = 0.0; + for (end = (ptr = rr_ptr[i]) + rr_len[i]; ptr < end; ptr++) + t += sv_val[ptr] * x[sv_ind[ptr]]; + /* y[i] := y[i] + alpha * t */ + y[i] += a * t; + } + return; +} + +/*********************************************************************** +* scf_rt_prod - compute product y := y + alpha * R'* x +* +* This routine computes the product y := y + alpha * R'* x, where +* R' is a matrix transposed to R, x is a nn-vector, alpha is a scalar, +* y is a n0-vector. +* +* Since matrix R is available by rows, the product is computed as a +* linear combination: +* +* y := y + alpha * (R'[1] * x[1] + ... + R'[nn] * x[nn]), +* +* where R'[i] is i-th row of R. */ + +void scf_rt_prod(SCF *scf, double y[/*1+n0*/], double a, const double + x[/*1+nn*/]) +{ int nn = scf->nn; + SVA *sva = scf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int rr_ref = scf->rr_ref; + int *rr_ptr = &sva->ptr[rr_ref-1]; + int *rr_len = &sva->len[rr_ref-1]; + int i, ptr, end; + double t; + for (i = 1; i <= nn; i++) + { if (x[i] == 0.0) + continue; + /* y := y + alpha * R'[i] * x[i] */ + t = a * x[i]; + for (end = (ptr = rr_ptr[i]) + rr_len[i]; ptr < end; ptr++) + y[sv_ind[ptr]] += sv_val[ptr] * t; + } + return; +} + +/*********************************************************************** +* scf_s_prod - compute product y := y + alpha * S * x +* +* This routine computes the product y := y + alpha * S * x, where +* x is a nn-vector, alpha is a scalar, y is a n0 vector. +* +* Since matrix S is available by columns, the product is computed as +* a linear combination: +* +* y := y + alpha * (S[1] * x[1] + ... + S[nn] * x[nn]), +* +* where S[j] is j-th column of S. */ + +void scf_s_prod(SCF *scf, double y[/*1+n0*/], double a, const double + x[/*1+nn*/]) +{ int nn = scf->nn; + SVA *sva = scf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int ss_ref = scf->ss_ref; + int *ss_ptr = &sva->ptr[ss_ref-1]; + int *ss_len = &sva->len[ss_ref-1]; + int j, ptr, end; + double t; + for (j = 1; j <= nn; j++) + { if (x[j] == 0.0) + continue; + /* y := y + alpha * S[j] * x[j] */ + t = a * x[j]; + for (end = (ptr = ss_ptr[j]) + ss_len[j]; ptr < end; ptr++) + y[sv_ind[ptr]] += sv_val[ptr] * t; + } + return; +} + +/*********************************************************************** +* scf_st_prod - compute product y := y + alpha * S'* x +* +* This routine computes the product y := y + alpha * S'* x, where +* S' is a matrix transposed to S, x is a n0-vector, alpha is a scalar, +* y is a nn-vector. +* +* Since matrix S is available by columns, the product components are +* computed as inner products: +* +* y[j] := y[j] + alpha * (j-th column of S) * x +* +* for j = 1, 2, ..., nn. */ + +void scf_st_prod(SCF *scf, double y[/*1+nn*/], double a, const double + x[/*1+n0*/]) +{ int nn = scf->nn; + SVA *sva = scf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int ss_ref = scf->ss_ref; + int *ss_ptr = &sva->ptr[ss_ref-1]; + int *ss_len = &sva->len[ss_ref-1]; + int j, ptr, end; + double t; + for (j = 1; j <= nn; j++) + { /* t := (j-th column of S) * x */ + t = 0.0; + for (end = (ptr = ss_ptr[j]) + ss_len[j]; ptr < end; ptr++) + t += sv_val[ptr] * x[sv_ind[ptr]]; + /* y[j] := y[j] + alpha * t */ + y[j] += a * t; + } + return; +} + +/*********************************************************************** +* scf_a_solve - solve system A * x = b +* +* This routine solves the system A * x = b, where A is the current +* matrix. +* +* On entry the array x should contain elements of the right-hand side +* vector b in locations x[1], ..., x[n], where n is the order of the +* matrix A. On exit the array x will contain elements of the solution +* vector in the same locations. +* +* For details see the program documentation. */ + +void scf_a_solve(SCF *scf, double x[/*1+n*/], + double w[/*1+n0+nn*/], double work1[/*1+max(n0,nn)*/], + double work2[/*1+n*/], double work3[/*1+n*/]) +{ int n = scf->n; + int n0 = scf->n0; + int nn = scf->nn; + int *pp_ind = scf->pp_ind; + int *qq_inv = scf->qq_inv; + int i, ii; + /* (u1, u2) := inv(P) * (b, 0) */ + for (ii = 1; ii <= n0+nn; ii++) + { i = pp_ind[ii]; +#if 1 /* FIXME: currently P = I */ + xassert(i == ii); +#endif + w[ii] = (i <= n ? x[i] : 0.0); + } + /* v1 := inv(R0) * u1 */ + scf_r0_solve(scf, 0, &w[0]); + /* v2 := u2 - R * v1 */ + scf_r_prod(scf, &w[n0], -1.0, &w[0]); + /* w2 := inv(C) * v2 */ + ifu_a_solve(&scf->ifu, &w[n0], work1); + /* w1 := inv(S0) * (v1 - S * w2) */ + scf_s_prod(scf, &w[0], -1.0, &w[n0]); + scf_s0_solve(scf, 0, &w[0], work1, work2, work3); + /* (x, x~) := inv(Q) * (w1, w2); x~ is not needed */ + for (i = 1; i <= n; i++) + x[i] = w[qq_inv[i]]; + return; +} + +/*********************************************************************** +* scf_at_solve - solve system A'* x = b +* +* This routine solves the system A'* x = b, where A' is a matrix +* transposed to the current matrix A. +* +* On entry the array x should contain elements of the right-hand side +* vector b in locations x[1], ..., x[n], where n is the order of the +* matrix A. On exit the array x will contain elements of the solution +* vector in the same locations. +* +* For details see the program documentation. */ + +void scf_at_solve(SCF *scf, double x[/*1+n*/], + double w[/*1+n0+nn*/], double work1[/*1+max(n0,nn)*/], + double work2[/*1+n*/], double work3[/*1+n*/]) +{ int n = scf->n; + int n0 = scf->n0; + int nn = scf->nn; + int *pp_inv = scf->pp_inv; + int *qq_ind = scf->qq_ind; + int i, ii; + /* (u1, u2) := Q * (b, 0) */ + for (ii = 1; ii <= n0+nn; ii++) + { i = qq_ind[ii]; + w[ii] = (i <= n ? x[i] : 0.0); + } + /* v1 := inv(S0') * u1 */ + scf_s0_solve(scf, 1, &w[0], work1, work2, work3); + /* v2 := inv(C') * (u2 - S'* v1) */ + scf_st_prod(scf, &w[n0], -1.0, &w[0]); + ifu_at_solve(&scf->ifu, &w[n0], work1); + /* w2 := v2 */ + /* nop */ + /* w1 := inv(R0') * (v1 - R'* w2) */ + scf_rt_prod(scf, &w[0], -1.0, &w[n0]); + scf_r0_solve(scf, 1, &w[0]); + /* compute (x, x~) := P * (w1, w2); x~ is not needed */ + for (i = 1; i <= n; i++) + { +#if 1 /* FIXME: currently P = I */ + xassert(pp_inv[i] == i); +#endif + x[i] = w[pp_inv[i]]; + } + return; +} + +/*********************************************************************** +* scf_add_r_row - add new row to matrix R +* +* This routine adds new (nn+1)-th row to matrix R, whose elements are +* specified in locations w[1,...,n0]. */ + +void scf_add_r_row(SCF *scf, const double w[/*1+n0*/]) +{ int n0 = scf->n0; + int nn = scf->nn; + SVA *sva = scf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int rr_ref = scf->rr_ref; + int *rr_ptr = &sva->ptr[rr_ref-1]; + int *rr_len = &sva->len[rr_ref-1]; + int j, len, ptr; + xassert(0 <= nn && nn < scf->nn_max); + /* determine length of new row */ + len = 0; + for (j = 1; j <= n0; j++) + { if (w[j] != 0.0) + len++; + } + /* reserve locations for new row in static part of SVA */ + if (len > 0) + { if (sva->r_ptr - sva->m_ptr < len) + { sva_more_space(sva, len); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_reserve_cap(sva, rr_ref + nn, len); + } + /* store new row in sparse format */ + ptr = rr_ptr[nn+1]; + for (j = 1; j <= n0; j++) + { if (w[j] != 0.0) + { sv_ind[ptr] = j; + sv_val[ptr] = w[j]; + ptr++; + } + } + xassert(ptr - rr_ptr[nn+1] == len); + rr_len[nn+1] = len; +#ifdef GLP_DEBUG + sva_check_area(sva); +#endif + return; +} + +/*********************************************************************** +* scf_add_s_col - add new column to matrix S +* +* This routine adds new (nn+1)-th column to matrix S, whose elements +* are specified in locations v[1,...,n0]. */ + +void scf_add_s_col(SCF *scf, const double v[/*1+n0*/]) +{ int n0 = scf->n0; + int nn = scf->nn; + SVA *sva = scf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int ss_ref = scf->ss_ref; + int *ss_ptr = &sva->ptr[ss_ref-1]; + int *ss_len = &sva->len[ss_ref-1]; + int i, len, ptr; + xassert(0 <= nn && nn < scf->nn_max); + /* determine length of new column */ + len = 0; + for (i = 1; i <= n0; i++) + { if (v[i] != 0.0) + len++; + } + /* reserve locations for new column in static part of SVA */ + if (len > 0) + { if (sva->r_ptr - sva->m_ptr < len) + { sva_more_space(sva, len); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_reserve_cap(sva, ss_ref + nn, len); + } + /* store new column in sparse format */ + ptr = ss_ptr[nn+1]; + for (i = 1; i <= n0; i++) + { if (v[i] != 0.0) + { sv_ind[ptr] = i; + sv_val[ptr] = v[i]; + ptr++; + } + } + xassert(ptr - ss_ptr[nn+1] == len); + ss_len[nn+1] = len; +#ifdef GLP_DEBUG + sva_check_area(sva); +#endif + return; +} + +/*********************************************************************** +* scf_update_aug - update factorization of augmented matrix +* +* Given factorization of the current augmented matrix: +* +* ( A0 A1 ) ( R0 ) ( S0 S ) +* ( ) = ( ) ( ), +* ( A2 A3 ) ( R I ) ( C ) +* +* this routine computes factorization of the new augmented matrix: +* +* ( A0 | A1 b ) +* ( ---+------ ) ( A0 A1^ ) ( R0 ) ( S0 S^ ) +* ( A2 | A3 f ) = ( ) = ( ) ( ), +* ( | ) ( A2^ A3^ ) ( R^ I ) ( C^ ) +* ( d' | g' h ) +* +* where b and d are specified n0-vectors, f and g are specified +* nn-vectors, and h is a specified scalar. (Note that corresponding +* arrays are clobbered on exit.) +* +* The parameter upd specifies how to update factorization of the Schur +* complement C: +* +* 1 Bartels-Golub updating. +* +* 2 Givens rotations updating. +* +* The working arrays w1, w2, and w3 are used in the same way as in the +* routine scf_s0_solve. +* +* RETURNS +* +* 0 Factorization has been successfully updated. +* +* 1 Updating limit has been reached. +* +* 2 Updating IFU-factorization of matrix C failed. +* +* For details see the program documentation. */ + +int scf_update_aug(SCF *scf, double b[/*1+n0*/], double d[/*1+n0*/], + double f[/*1+nn*/], double g[/*1+nn*/], double h, int upd, + double w1[/*1+n0*/], double w2[/*1+n0*/], double w3[/*1+n0*/]) +{ int n0 = scf->n0; + int k, ret; + double *v, *w, *x, *y, z; + if (scf->nn == scf->nn_max) + { /* updating limit has been reached */ + return 1; + } + /* v := inv(R0) * b */ + scf_r0_solve(scf, 0, (v = b)); + /* w := inv(S0') * d */ + scf_s0_solve(scf, 1, (w = d), w1, w2, w3); + /* x := f - R * v */ + scf_r_prod(scf, (x = f), -1.0, v); + /* y := g - S'* w */ + scf_st_prod(scf, (y = g), -1.0, w); + /* z := h - v'* w */ + z = h; + for (k = 1; k <= n0; k++) + z -= v[k] * w[k]; + /* new R := R with row w added */ + scf_add_r_row(scf, w); + /* new S := S with column v added */ + scf_add_s_col(scf, v); + /* update IFU-factorization of C */ + switch (upd) + { case 1: + ret = ifu_bg_update(&scf->ifu, x, y, z); + break; + case 2: + ret = ifu_gr_update(&scf->ifu, x, y, z); + break; + default: + xassert(upd != upd); + } + if (ret != 0) + { /* updating IFU-factorization failed */ + return 2; + } + /* increase number of additional rows and columns */ + scf->nn++; + /* expand P and Q */ + k = n0 + scf->nn; + scf->pp_ind[k] = scf->pp_inv[k] = k; + scf->qq_ind[k] = scf->qq_inv[k] = k; + /* factorization has been successfully updated */ + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/scf.h b/resources/3rdparty/glpk-4.57/src/bflib/scf.h new file mode 100644 index 000000000..69d8cfc2a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/scf.h @@ -0,0 +1,211 @@ +/* scf.h (sparse updatable Schur-complement-based factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2013-2014 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef SCF_H +#define SCF_H + +#include "btf.h" +#include "ifu.h" +#include "luf.h" + +/*********************************************************************** +* The structure SCF describes sparse updatable factorization based on +* Schur complement. +* +* The SCF-factorization has the following format: +* +* ( A A1~ ) ( A0 A1 ) ( R0 ) ( S0 S ) +* ( ) = P ( ) Q = P ( ) ( ) Q, (1) +* ( A2~ A3~ ) ( A2 A3 ) ( R I ) ( C ) +* +* where: +* +* A is current (unsymmetric) square matrix (not stored); +* +* A1~, A2~, A3~ are some additional matrices (not stored); +* +* A0 is initial (unsymmetric) square matrix (not stored); +* +* A1, A2, A3 are some additional matrices (not stored); +* +* R0 and S0 are matrices that define factorization of the initial +* matrix A0 = R0 * S0 (stored in an invertable form); +* +* R is a matrix defined from R * S0 = A2, so R = A2 * inv(S0) (stored +* in row-wise sparse format); +* +* S is a matrix defined from R0 * S = A1, so S = inv(R0) * A1 (stored +* in column-wise sparse format); +* +* C is Schur complement (to matrix A0) defined from R * S + C = A3, +* so C = A3 - R * S = A3 - A2 * inv(A0) * A1 (stored in an invertable +* form). +* +* P, Q are permutation matrices (stored in both row- and column-like +* formats). */ + +typedef struct SCF SCF; + +struct SCF +{ /* Schur-complement-based factorization */ + int n; + /* order of current matrix A */ + /*--------------------------------------------------------------*/ + /* initial matrix A0 = R0 * S0 of order n0 in invertable form */ + int n0; + /* order of matrix A0 */ + int type; + /* type of factorization used: + * 1 - LU-factorization (R0 = F0, S0 = V0) + * 2 - BT-factorization (R0 = I, S0 = A0) */ + union + { LUF *luf; /* type = 1 */ + BTF *btf; /* type = 2 */ + } a0; + /* factorization of matrix A0 */ + /*--------------------------------------------------------------*/ + /* augmented matrix (A0, A1; A2, A3) of order n0+nn */ + int nn_max; + /* maximal number of additional rows and columns in the augmented + * matrix (this limits the number of updates) */ + int nn; + /* current number of additional rows and columns in the augmented + * matrix, 0 <= nn <= nn_max */ + SVA *sva; + /* associated sparse vector area (SVA) used to store rows of + * matrix R and columns of matrix S */ + /*--------------------------------------------------------------*/ + /* nn*n0-matrix R in row-wise format */ + int rr_ref; + /* reference number of sparse vector in SVA, which is the first + * row of matrix R */ +#if 0 + 0 + int *rr_ptr = &sva->ptr[rr_ref-1]; + /* rr_ptr[0] is not used; + * rr_ptr[i], 1 <= i <= nn, is pointer to i-th row in SVA; + * rr_ptr[nn+1,...,nn_max] are reserved locations */ + int *rr_len = &sva->len[rr_ref-1]; + /* rr_len[0] is not used; + * rr_len[i], 1 <= i <= nn, is length of i-th row; + * rr_len[nn+1,...,nn_max] are reserved locations */ +#endif + /*--------------------------------------------------------------*/ + /* n0*nn-matrix S in column-wise format */ + int ss_ref; + /* reference number of sparse vector in SVA, which is the first + * column of matrix S */ +#if 0 + 0 + int *ss_ptr = &sva->ptr[ss_ref-1]; + /* ss_ptr[0] is not used; + * ss_ptr[j], 1 <= j <= nn, is pointer to j-th column in SVA; + * ss_ptr[nn+1,...,nn_max] are reserved locations */ + int *ss_len = &sva->len[ss_ref-1]; + /* ss_len[0] is not used; + * ss_len[j], 1 <= j <= nn, is length of j-th column; + * ss_len[nn+1,...,nn_max] are reserved locations */ +#endif + /*--------------------------------------------------------------*/ + /* Schur complement C of order nn in invertable form */ + IFU ifu; + /* IFU-factorization of matrix C */ + /*--------------------------------------------------------------*/ + /* permutation matrix P of order n0+nn */ + int *pp_ind; /* int pp_ind[1+n0+nn_max]; */ + /* pp_ind[i] = j means that P[i,j] = 1 */ + int *pp_inv; /* int pp_inv[1+n0+nn_max]; */ + /* pp_inv[j] = i means that P[i,j] = 1 */ + /*--------------------------------------------------------------*/ + /* permutation matrix Q of order n0+nn */ + int *qq_ind; /* int qq_ind[1+n0+nn_max]; */ + /* qq_ind[i] = j means that Q[i,j] = 1 */ + int *qq_inv; /* int qq_inv[1+n0+nn_max]; */ + /* qq_inv[j] = i means that Q[i,j] = 1 */ +}; + +#define scf_swap_q_cols(j1, j2) \ + do \ + { int i1, i2; \ + i1 = qq_inv[j1], i2 = qq_inv[j2]; \ + qq_ind[i1] = j2, qq_inv[j2] = i1; \ + qq_ind[i2] = j1, qq_inv[j1] = i2; \ + } while (0) +/* swap columns j1 and j2 of permutation matrix Q */ + +#define scf_r0_solve _glp_scf_r0_solve +void scf_r0_solve(SCF *scf, int tr, double x[/*1+n0*/]); +/* solve system R0 * x = b or R0'* x = b */ + +#define scf_s0_solve _glp_scf_s0_solve +void scf_s0_solve(SCF *scf, int tr, double x[/*1+n0*/], + double w1[/*1+n0*/], double w2[/*1+n0*/], double w3[/*1+n0*/]); +/* solve system S0 * x = b or S0'* x = b */ + +#define scf_r_prod _glp_scf_r_prod +void scf_r_prod(SCF *scf, double y[/*1+nn*/], double a, const double + x[/*1+n0*/]); +/* compute product y := y + alpha * R * x */ + +#define scf_rt_prod _glp_scf_rt_prod +void scf_rt_prod(SCF *scf, double y[/*1+n0*/], double a, const double + x[/*1+nn*/]); +/* compute product y := y + alpha * R'* x */ + +#define scf_s_prod _glp_scf_s_prod +void scf_s_prod(SCF *scf, double y[/*1+n0*/], double a, const double + x[/*1+nn*/]); +/* compute product y := y + alpha * S * x */ + +#define scf_st_prod _glp_scf_st_prod +void scf_st_prod(SCF *scf, double y[/*1+nn*/], double a, const double + x[/*1+n0*/]); +/* compute product y := y + alpha * S'* x */ + +#define scf_a_solve _glp_scf_a_solve +void scf_a_solve(SCF *scf, double x[/*1+n*/], + double w[/*1+n0+nn*/], double work1[/*1+max(n0,nn)*/], + double work2[/*1+n*/], double work3[/*1+n*/]); +/* solve system A * x = b */ + +#define scf_at_solve _glp_scf_at_solve +void scf_at_solve(SCF *scf, double x[/*1+n*/], + double w[/*1+n0+nn*/], double work1[/*1+max(n0,nn)*/], + double work2[/*1+n*/], double work3[/*1+n*/]); +/* solve system A'* x = b */ + +#define scf_add_r_row _glp_scf_add_r_row +void scf_add_r_row(SCF *scf, const double w[/*1+n0*/]); +/* add new row to matrix R */ + +#define scf_add_s_col _glp_scf_add_s_col +void scf_add_s_col(SCF *scf, const double v[/*1+n0*/]); +/* add new column to matrix S */ + +#define scf_update_aug _glp_scf_update_aug +int scf_update_aug(SCF *scf, double b[/*1+n0*/], double d[/*1+n0*/], + double f[/*1+nn*/], double g[/*1+nn*/], double h, int upd, + double w1[/*1+n0*/], double w2[/*1+n0*/], double w3[/*1+n0*/]); +/* update factorization of augmented matrix */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/scfint.c b/resources/3rdparty/glpk-4.57/src/bflib/scfint.c new file mode 100644 index 000000000..06aa8f7d4 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/scfint.c @@ -0,0 +1,255 @@ +/* scfint.c (interface to Schur-complement-based factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2013-2014 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "scfint.h" + +SCFINT *scfint_create(int type) +{ /* create interface to SC-factorization */ + SCFINT *fi; + fi = talloc(1, SCFINT); + memset(fi, 0, sizeof(SCFINT)); + switch ((fi->scf.type = type)) + { case 1: + fi->u.lufi = lufint_create(); + break; + case 2: + fi->u.btfi = btfint_create(); + break; + default: + xassert(type != type); + } + return fi; +} + +int scfint_factorize(SCFINT *fi, int n, int (*col)(void *info, int j, + int ind[], double val[]), void *info) +{ /* compute SC-factorization of specified matrix A */ + int nn_max, old_n0_max, n0_max, k, ret; + xassert(n > 0); + fi->valid = 0; + /* get required value of nn_max */ + nn_max = fi->nn_max; + if (nn_max == 0) + nn_max = 100; + xassert(nn_max > 0); + /* compute factorization of specified matrix A */ + switch (fi->scf.type) + { case 1: + old_n0_max = fi->u.lufi->n_max; + fi->u.lufi->sva_n_max = 4 * n + 2 * nn_max; + ret = lufint_factorize(fi->u.lufi, n, col, info); + n0_max = fi->u.lufi->n_max; + fi->scf.sva = fi->u.lufi->sva; + fi->scf.a0.luf = fi->u.lufi->luf; + break; + case 2: + old_n0_max = fi->u.btfi->n_max; + fi->u.btfi->sva_n_max = 6 * n + 2 * nn_max; + ret = btfint_factorize(fi->u.btfi, n, col, info); + n0_max = fi->u.btfi->n_max; + fi->scf.sva = fi->u.btfi->sva; + fi->scf.a0.btf = fi->u.btfi->btf; + break; + default: + xassert(fi != fi); + } + /* allocate/reallocate arrays, if necessary */ + if (old_n0_max < n0_max) + { if (fi->w1 != NULL) + tfree(fi->w1); + if (fi->w2 != NULL) + tfree(fi->w2); + if (fi->w3 != NULL) + tfree(fi->w3); + fi->w1 = talloc(1+n0_max, double); + fi->w2 = talloc(1+n0_max, double); + fi->w3 = talloc(1+n0_max, double); + } + if (fi->scf.nn_max != nn_max) + { if (fi->scf.ifu.f != NULL) + tfree(fi->scf.ifu.f); + if (fi->scf.ifu.u != NULL) + tfree(fi->scf.ifu.u); + fi->scf.ifu.f = talloc(nn_max * nn_max, double); + fi->scf.ifu.u = talloc(nn_max * nn_max, double); + } + if (old_n0_max < n0_max || fi->scf.nn_max != nn_max) + { if (fi->scf.pp_ind != NULL) + tfree(fi->scf.pp_ind); + if (fi->scf.pp_inv != NULL) + tfree(fi->scf.pp_inv); + if (fi->scf.qq_ind != NULL) + tfree(fi->scf.qq_ind); + if (fi->scf.qq_inv != NULL) + tfree(fi->scf.qq_inv); + if (fi->w4 != NULL) + tfree(fi->w4); + if (fi->w5 != NULL) + tfree(fi->w5); + fi->scf.pp_ind = talloc(1+n0_max+nn_max, int); + fi->scf.pp_inv = talloc(1+n0_max+nn_max, int); + fi->scf.qq_ind = talloc(1+n0_max+nn_max, int); + fi->scf.qq_inv = talloc(1+n0_max+nn_max, int); + fi->w4 = talloc(1+n0_max+nn_max, double); + fi->w5 = talloc(1+n0_max+nn_max, double); + } + /* initialize SC-factorization */ + fi->scf.n = n; + fi->scf.n0 = n; + fi->scf.nn_max = nn_max; + fi->scf.nn = 0; + fi->scf.rr_ref = sva_alloc_vecs(fi->scf.sva, nn_max); + fi->scf.ss_ref = sva_alloc_vecs(fi->scf.sva, nn_max); + fi->scf.ifu.n_max = nn_max; + fi->scf.ifu.n = 0; + for (k = 1; k <= n; k++) + { fi->scf.pp_ind[k] = k; + fi->scf.pp_inv[k] = k; + fi->scf.qq_ind[k] = k; + fi->scf.qq_inv[k] = k; + } + /* set validation flag */ + if (ret == 0) + fi->valid = 1; + return ret; +} + +int scfint_update(SCFINT *fi, int upd, int j, int len, const int ind[], + const double val[]) +{ /* update SC-factorization after replacing j-th column of A */ + int n = fi->scf.n; + int n0 = fi->scf.n0; + int nn = fi->scf.nn; + int *pp_ind = fi->scf.pp_ind; + int *qq_ind = fi->scf.qq_ind; + int *qq_inv = fi->scf.qq_inv; + double *bf = fi->w4; + double *dg = fi->w5; + int k, t, ret; + xassert(fi->valid); + xassert(0 <= n && n <= n0+nn); + /* (b, f) := inv(P) * (beta, 0) */ + for (k = 1; k <= n0+nn; k++) + bf[k] = 0.0; + for (t = 1; t <= len; t++) + { k = ind[t]; + xassert(1 <= k && k <= n); +#if 1 /* FIXME: currently P = I */ + xassert(pp_ind[k] == k); +#endif + xassert(bf[k] == 0.0); + xassert(val[t] != 0.0); + bf[k] = val[t]; + } + /* (d, g) := Q * (cj, 0) */ + for (k = 1; k <= n0+nn; k++) + dg[k] = 0.0; + xassert(1 <= j && j <= n); + dg[fi->scf.qq_inv[j]] = 1; + /* update factorization of augmented matrix */ + ret = scf_update_aug(&fi->scf, &bf[0], &dg[0], &bf[n0], &dg[n0], + 0.0, upd, fi->w1, fi->w2, fi->w3); + if (ret == 0) + { /* swap j-th and last columns of new matrix Q */ + scf_swap_q_cols(j, n0+nn+1); + } + else + { /* updating failed */ + fi->valid = 0; + } + return ret; +} + +void scfint_ftran(SCFINT *fi, double x[]) +{ /* solve system A * x = b */ + xassert(fi->valid); + scf_a_solve(&fi->scf, x, fi->w4, fi->w5, fi->w1, fi->w2); + return; +} + +void scfint_btran(SCFINT *fi, double x[]) +{ /* solve system A'* x = b */ + xassert(fi->valid); + scf_at_solve(&fi->scf, x, fi->w4, fi->w5, fi->w1, fi->w2); + return; +} + +double scfint_estimate(SCFINT *fi) +{ /* estimate 1-norm of inv(A) */ + double norm; + xassert(fi->valid); + xassert(fi->scf.n == fi->scf.n0); + switch (fi->scf.type) + { case 1: + norm = luf_estimate_norm(fi->scf.a0.luf, fi->w1, fi->w2); + break; + case 2: + norm = btf_estimate_norm(fi->scf.a0.btf, fi->w1, fi->w2, + fi->w3, fi->w4); + break; + default: + xassert(fi != fi); + } + return norm; +} + +void scfint_delete(SCFINT *fi) +{ /* delete interface to SC-factorization */ + switch (fi->scf.type) + { case 1: + lufint_delete(fi->u.lufi); + break; + case 2: + btfint_delete(fi->u.btfi); + break; + default: + xassert(fi != fi); + } + if (fi->scf.ifu.f != NULL) + tfree(fi->scf.ifu.f); + if (fi->scf.ifu.u != NULL) + tfree(fi->scf.ifu.u); + if (fi->scf.pp_ind != NULL) + tfree(fi->scf.pp_ind); + if (fi->scf.pp_inv != NULL) + tfree(fi->scf.pp_inv); + if (fi->scf.qq_ind != NULL) + tfree(fi->scf.qq_ind); + if (fi->scf.qq_inv != NULL) + tfree(fi->scf.qq_inv); + if (fi->w1 != NULL) + tfree(fi->w1); + if (fi->w2 != NULL) + tfree(fi->w2); + if (fi->w3 != NULL) + tfree(fi->w3); + if (fi->w4 != NULL) + tfree(fi->w4); + if (fi->w5 != NULL) + tfree(fi->w5); + tfree(fi); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/scfint.h b/resources/3rdparty/glpk-4.57/src/bflib/scfint.h new file mode 100644 index 000000000..3e56355ba --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/scfint.h @@ -0,0 +1,89 @@ +/* scfint.h (interface to Schur-complement-based factorization) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2013-2014 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef SCFINT_H +#define SCFINT_H + +#include "scf.h" +#include "lufint.h" +#include "btfint.h" + +typedef struct SCFINT SCFINT; + +struct SCFINT +{ /* interface to SC-factorization */ + int valid; + /* factorization is valid only if this flag is set */ + SCF scf; + /* Schur-complement based factorization */ + union + { LUFINT *lufi; /* scf.type = 1 */ + BTFINT *btfi; /* scf.type = 2 */ + } u; + /* interface to factorize initial matrix A0 */ + /*--------------------------------------------------------------*/ + /* working arrays */ + double *w1; /* double w1[1+n0_max]; */ + double *w2; /* double w2[1+n0_max]; */ + double *w3; /* double w3[1+n0_max]; */ + double *w4; /* double w4[1+n0_max+nn_max]; */ + double *w5; /* double w5[1+n0_max+nn_max]; */ + /*--------------------------------------------------------------*/ + /* control parameters */ + int nn_max; + /* required maximal number of updates */ +}; + +#define scfint_create _glp_scfint_create +SCFINT *scfint_create(int type); +/* create interface to SC-factorization */ + +#define scfint_factorize _glp_scfint_factorize +int scfint_factorize(SCFINT *fi, int n, int (*col)(void *info, int j, + int ind[], double val[]), void *info); +/* compute SC-factorization of specified matrix A */ + +#define scfint_update _glp_scfint_update +int scfint_update(SCFINT *fi, int upd, int j, int len, const int ind[], + const double val[]); +/* update SC-factorization after replacing j-th column of A */ + +#define scfint_ftran _glp_scfint_ftran +void scfint_ftran(SCFINT *fi, double x[]); +/* solve system A * x = b */ + +#define scfint_btran _glp_scfint_btran +void scfint_btran(SCFINT *fi, double x[]); +/* solve system A'* x = b */ + +#define scfint_estimate _glp_scfint_estimate +double scfint_estimate(SCFINT *fi); +/* estimate 1-norm of inv(A) */ + +#define scfint_delete _glp_scfint_delete +void scfint_delete(SCFINT *fi); +/* delete interface to SC-factorization */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/sgf.c b/resources/3rdparty/glpk-4.57/src/bflib/sgf.c new file mode 100644 index 000000000..4000c8a55 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/sgf.c @@ -0,0 +1,1430 @@ +/* sgf.c (sparse Gaussian factorizer) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "sgf.h" + +/*********************************************************************** +* sgf_reduce_nuc - initial reordering to minimize nucleus size +* +* On entry to this routine it is assumed that V = A and F = P = Q = I, +* where A is the original matrix to be factorized. It is also assumed +* that matrix V = A is stored in both row- and column-wise formats. +* +* This routine performs (implicit) non-symmetric permutations of rows +* and columns of matrix U = P'* V * Q' to reduce it to the form: +* +* 1 k1 k2 n +* 1 x x x x x x x x x x +* . x x x x x x x x x +* . . x x x x x x x x +* k1 . . . * * * * x x x +* . . . * * * * x x x +* . . . * * * * x x x +* k2 . . . * * * * x x x +* . . . . . . . x x x +* . . . . . . . . x x +* n . . . . . . . . . x +* +* where non-zeros in rows and columns k1, k1+1, ..., k2 constitute so +* called nucleus ('*'), whose size is minimized by the routine. +* +* The numbers k1 and k2 are returned by the routine on exit. Usually, +* if the nucleus exists, 1 <= k1 < k2 <= n. However, if the resultant +* matrix U is upper triangular (has no nucleus), k1 = n+1 and k2 = n. +* +* Note that the routines sgf_choose_pivot and sgf_eliminate perform +* exactly the same transformations (by processing row and columns +* singletons), so preliminary minimization of the nucleus may not be +* used. However, processing row and column singletons by the routines +* sgf_minimize_nuc and sgf_singl_phase is more efficient. */ + +void sgf_reduce_nuc(LUF *luf, int *k1_, int *k2_, int cnt[/*1+n*/], + int list[/*1+n*/]) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + int vr_ref = luf->vr_ref; + int *vr_ptr = &sva->ptr[vr_ref-1]; + int *vr_len = &sva->len[vr_ref-1]; + int vc_ref = luf->vc_ref; + int *vc_ptr = &sva->ptr[vc_ref-1]; + int *vc_len = &sva->len[vc_ref-1]; + int *pp_ind = luf->pp_ind; + int *pp_inv = luf->pp_inv; + int *qq_ind = luf->qq_ind; + int *qq_inv = luf->qq_inv; + int i, ii, j, jj, k1, k2, ns, ptr, end; + /* initial nucleus is U = V = A */ + k1 = 1, k2 = n; + /*--------------------------------------------------------------*/ + /* process column singletons */ + /*--------------------------------------------------------------*/ + /* determine initial counts of columns of V and initialize list + * of active column singletons */ + ns = 0; /* number of active column singletons */ + for (j = 1; j <= n; j++) + { if ((cnt[j] = vc_len[j]) == 1) + list[++ns] = j; + } + /* process active column singletons */ + while (ns > 0) + { /* column singleton is in j-th column of V */ + j = list[ns--]; +#if 1 /* 25/IX-2015 */ + if (cnt[j] == 0) + { /* j-th column in the current nucleus is actually empty */ + /* this happened because on a previous step in the nucleus + * there were two or more identical column singletons (that + * means structural singularity), so removing one of them + * from the nucleus made other columns empty */ + /* do not remove empty column from the nucleus */ + continue; + } +#endif + /* find i-th row of V containing column singleton */ + ptr = vc_ptr[j]; + end = ptr + vc_len[j]; + for (; pp_ind[i = sv_ind[ptr]] < k1; ptr++) + /* nop */; + xassert(ptr < end); + /* permute rows and columns of U to move column singleton to + * position u[k1,k1] */ + ii = pp_ind[i]; + luf_swap_u_rows(k1, ii); + jj = qq_inv[j]; + luf_swap_u_cols(k1, jj); + /* nucleus size decreased */ + k1++; + /* walk thru i-th row of V and decrease column counts; this + * may cause new column singletons to appear */ + ptr = vr_ptr[i]; + end = ptr + vr_len[i]; + for (; ptr < end; ptr++) + { if (--(cnt[j = sv_ind[ptr]]) == 1) + list[++ns] = j; + } + } + /* nucleus begins at k1-th row/column of U */ + if (k1 > n) + { /* U is upper triangular; no nucleus exist */ + goto done; + } + /*--------------------------------------------------------------*/ + /* process row singletons */ + /*--------------------------------------------------------------*/ + /* determine initial counts of rows of V and initialize list of + * active row singletons */ + ns = 0; /* number of active row singletons */ + for (i = 1; i <= n; i++) + { if (pp_ind[i] < k1) + { /* corresponding row of U is above its k1-th row; set its + * count to zero to prevent including it in active list */ + cnt[i] = 0; + } + else if ((cnt[i] = vr_len[i]) == 1) + list[++ns] = i; + } + /* process active row singletons */ + while (ns > 0) + { /* row singleton is in i-th row of V */ + i = list[ns--]; +#if 1 /* 25/IX-2015 */ + if (cnt[i] == 0) + { /* i-th row in the current nucleus is actually empty */ + /* (see comments above for similar case of empty column) */ + /* do not remove empty row from the nucleus */ + continue; + } +#endif + /* find j-th column of V containing row singleton */ + ptr = vr_ptr[i]; + end = ptr + vr_len[i]; + for (; qq_inv[j = sv_ind[ptr]] > k2; ptr++) + /* nop */; + xassert(ptr < end); + /* permute rows and columns of U to move row singleton to + * position u[k2,k2] */ + ii = pp_ind[i]; + luf_swap_u_rows(k2, ii); + jj = qq_inv[j]; + luf_swap_u_cols(k2, jj); + /* nucleus size decreased */ + k2--; + /* walk thru j-th column of V and decrease row counts; this + * may cause new row singletons to appear */ + ptr = vc_ptr[j]; + end = ptr + vc_len[j]; + for (; ptr < end; ptr++) + { if (--(cnt[i = sv_ind[ptr]]) == 1) + list[++ns] = i; + } + } + /* nucleus ends at k2-th row/column of U */ + xassert(k1 < k2); +done: *k1_ = k1, *k2_ = k2; + return; +} + +/*********************************************************************** +* sgf_singl_phase - compute LU-factorization (singleton phase) +* +* It is assumed that on entry to the routine L = P'* F * P = F = I +* and matrix U = P'* V * Q' has the following structure (provided by +* the routine sgf_reduce_nuc): +* +* 1 k1 k2 n +* 1 a a a b b b b c c c +* . a a b b b b c c c +* . . a b b b b c c c +* k1 . . . * * * * d d d +* . . . * * * * d d d +* . . . * * * * d d d +* k2 . . . * * * * d d d +* . . . . . . . e e e +* . . . . . . . . e e +* n . . . . . . . . . e +* +* First, the routine performs (implicit) symmetric permutations of +* rows and columns of matrix U to place them in the following order: +* +* 1, 2, ..., k1-1; n, n-1, ..., k2+1; k1, k1+1, ..., k2 +* +* This changes the structure of matrix U as follows: +* +* 1 k1 k2' n +* 1 a a a c c c b b b b +* . a a c c c b b b b +* . . a c c c b b b b +* k1 . . . e . . . . . . +* . . . e e . . . . . +* . . . e e e . . . . +* k2'. . . d d d * * * * +* . . . d d d * * * * +* . . . d d d * * * * +* n . . . d d d * * * * +* +* where k2' = n - k2 + k1. +* +* Then the routine performs elementary gaussian transformations to +* eliminate subdiagonal elements in columns k1, ..., k2'-1 of U. The +* effect is the same as if the routine sgf_eliminate would be called +* for k = 1, ..., k2'-1 using diagonal elements u[k,k] as pivots. +* +* After elimination matrices L and U becomes the following: +* +* 1 k1 k2' n 1 k1 k2' n +* 1 1 . . . . . . . . . 1 a a a c c c b b b b +* . 1 . . . . . . . . . a a c c c b b b b +* . . 1 . . . . . . . . . a c c c b b b b +* k1 . . . 1 . . . . . . k1 . . . e . . . . . . +* . . . e'1 . . . . . . . . . e . . . . . +* . . . e'e'1 . . . . . . . . . e . . . . +* k2'. . . d'd'd'1 . . . k2'. . . . . . * * * * +* . . . d'd'd'. 1 . . . . . . . . * * * * +* . . . d'd'd'. . 1 . . . . . . . * * * * +* n . . . d'd'd'. . . 1 n . . . . . . * * * * +* +* matrix L matrix U +* +* where columns k1, ..., k2'-1 of L consist of subdiagonal elements +* of initial matrix U divided by pivots u[k,k]. +* +* On exit the routine returns k2', the elimination step number, from +* which computing of the factorization should be continued. Note that +* k2' = n+1 means that matrix U is already upper triangular. */ + +int sgf_singl_phase(LUF *luf, int k1, int k2, int updat, + int ind[/*1+n*/], double val[/*1+n*/]) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int fc_ref = luf->fc_ref; + int *fc_ptr = &sva->ptr[fc_ref-1]; + int *fc_len = &sva->len[fc_ref-1]; + int vr_ref = luf->vr_ref; + int *vr_ptr = &sva->ptr[vr_ref-1]; + int *vr_len = &sva->len[vr_ref-1]; + double *vr_piv = luf->vr_piv; + int vc_ref = luf->vc_ref; + int *vc_ptr = &sva->ptr[vc_ref-1]; + int *vc_len = &sva->len[vc_ref-1]; + int *pp_ind = luf->pp_ind; + int *pp_inv = luf->pp_inv; + int *qq_ind = luf->qq_ind; + int *qq_inv = luf->qq_inv; + int i, j, k, ptr, ptr1, end, len; + double piv; + /* (see routine sgf_reduce_nuc) */ + xassert((1 <= k1 && k1 < k2 && k2 <= n) + || (k1 == n+1 && k2 == n)); + /* perform symmetric permutations of rows/columns of U */ + for (k = k1; k <= k2; k++) + pp_ind[pp_inv[k]] = qq_inv[qq_ind[k]] = k - k2 + n; + for (k = k2+1; k <= n; k++) + pp_ind[pp_inv[k]] = qq_inv[qq_ind[k]] = n - k + k1; + for (k = 1; k <= n; k++) + pp_inv[pp_ind[k]] = qq_ind[qq_inv[k]] = k; + /* determine k2' */ + k2 = n - k2 + k1; + /* process rows and columns of V corresponding to rows and + * columns 1, ..., k1-1 of U */ + for (k = 1; k < k1; k++) + { /* k-th row of U = i-th row of V */ + i = pp_inv[k]; + /* find pivot u[k,k] = v[i,j] in i-th row of V */ + ptr = vr_ptr[i]; + end = ptr + vr_len[i]; + for (; qq_inv[sv_ind[ptr]] != k; ptr++) + /* nop */; + xassert(ptr < end); + /* store pivot */ + vr_piv[i] = sv_val[ptr]; + /* and remove it from i-th row of V */ + sv_ind[ptr] = sv_ind[end-1]; + sv_val[ptr] = sv_val[end-1]; + vr_len[i]--; + /* clear column of V corresponding to k-th column of U */ + vc_len[qq_ind[k]] = 0; + } + /* clear rows of V corresponding to rows k1, ..., k2'-1 of U */ + for (k = k1; k < k2; k++) + vr_len[pp_inv[k]] = 0; + /* process rows and columns of V corresponding to rows and + * columns k2', ..., n of U */ + for (k = k2; k <= n; k++) + { /* k-th row of U = i-th row of V */ + i = pp_inv[k]; + /* remove elements from i-th row of V that correspond to + * elements u[k,k1], ..., u[k,k2'-1] */ + ptr = ptr1 = vr_ptr[i]; + end = ptr + vr_len[i]; + for (; ptr < end; ptr++) + { if (qq_inv[sv_ind[ptr]] >= k2) + { sv_ind[ptr1] = sv_ind[ptr]; + sv_val[ptr1] = sv_val[ptr]; + ptr1++; + } + } + vr_len[i] = ptr1 - vr_ptr[i]; + /* k-th column of U = j-th column of V */ + j = qq_ind[k]; + /* remove elements from j-th column of V that correspond to + * elements u[1,k], ..., u[k1-1,k] */ + ptr = ptr1 = vc_ptr[j]; + end = ptr + vc_len[j]; + for (; ptr < end; ptr++) + { if (pp_ind[sv_ind[ptr]] >= k2) + /* element value is not needed in this case */ + sv_ind[ptr1++] = sv_ind[ptr]; + } + vc_len[j] = ptr1 - vc_ptr[j]; + } + /* process columns of V corresponding to columns k1, ..., k2'-1 + * of U, build columns of F */ + for (k = k1; k < k2; k++) + { /* k-th column of U = j-th column of V */ + j = qq_ind[k]; + /* remove elements from j-th column of V that correspond to + * pivot (diagonal) element u[k,k] and subdiagonal elements + * u[k+1,k], ..., u[n,k]; subdiagonal elements are stored for + * further addition to matrix F */ + len = 0; + piv = 0.0; + ptr = vc_ptr[j]; + end = ptr + vc_len[j]; + for (; ptr < end; ptr++) + { i = sv_ind[ptr]; /* v[i,j] */ + if (pp_ind[i] == k) + { /* store pivot v[i,j] = u[k,k] */ + piv = vr_piv[i] = sv_val[ptr]; + } + else if (pp_ind[i] > k) + { /* store subdiagonal element v[i,j] = u[i',k] */ + len++; + ind[len] = i; + val[len] = sv_val[ptr]; + } + } + /* clear j-th column of V = k-th column of U */ + vc_len[j] = 0; + /* build k-th column of L = j-th column of F */ + j = pp_inv[k]; + xassert(piv != 0.0); + if (len > 0) + { if (sva->r_ptr - sva->m_ptr < len) + { sva_more_space(sva, len); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_reserve_cap(sva, fc_ref-1+j, len); + for (ptr = fc_ptr[j], ptr1 = 1; ptr1 <= len; ptr++, ptr1++) + { sv_ind[ptr] = ind[ptr1]; + sv_val[ptr] = val[ptr1] / piv; + } + fc_len[j] = len; + } + } + /* if it is not planned to update matrix V, relocate all its + * non-active rows corresponding to rows 1, ..., k2'-1 of U to + * the right (static) part of SVA */ + if (!updat) + { for (k = 1; k < k2; k++) + { i = pp_inv[k]; + len = vr_len[i]; + if (sva->r_ptr - sva->m_ptr < len) + { sva_more_space(sva, len); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_make_static(sva, vr_ref-1+i); + } + } + /* elimination steps 1, ..., k2'-1 have been performed */ + return k2; +} + +/*********************************************************************** +* sgf_choose_pivot - choose pivot element v[p,q] +* +* This routine chooses pivot element v[p,q], k <= p, q <= n, in the +* active submatrix of matrix V = P * U * Q, where k is the number of +* current elimination step, 1 <= k <= n. +* +* It is assumed that on entry to the routine matrix U = P'* V * Q' has +* the following partially triangularized form: +* +* 1 k n +* 1 x x x x x x x x x x +* . x x x x x x x x x +* . . x x x x x x x x +* . . . x x x x x x x +* k . . . . * * * * * * +* . . . . * * * * * * +* . . . . * * * * * * +* . . . . * * * * * * +* . . . . * * * * * * +* n . . . . * * * * * * +* +* where rows and columns k, k+1, ..., n belong to the active submatrix +* (its elements are marked by '*'). +* +* Since the matrix U is not stored, the routine works with the matrix +* V = P * U * Q. It is assumed that the row-wise representation +* corresponds to the matrix V, but the column-wise representation +* corresponds to the active submatrix of the matrix V, i.e. elements, +* which are not in the active submatrix, are not included in column +* vectors. It is also assumed that each active row of the matrix V is +* in the set R[len], where len is the number of non-zeros in the row, +* and each active column of the matrix V is in the set C[len], where +* len is the number of non-zeros in the column (in the latter case +* only elements of the active submatrix are counted; such elements are +* marked by '*' on the figure above). +* +* For the reason of numerical stability the routine applies so called +* threshold pivoting proposed by J.Reid. It is assumed that an element +* v[i,j] can be selected as a pivot candidate if it is not very small +* (in magnitude) among other elements in the same row, i.e. if it +* satisfies to the stability condition |v[i,j]| >= tol * max|v[i,*]|, +* where 0 < tol < 1 is a given tolerance. +* +* In order to keep sparsity of the matrix V the routine uses Markowitz +* strategy, trying to choose such element v[p,q], which satisfies to +* the stability condition (see above) and has smallest Markowitz cost +* (nr[p]-1) * (nc[q]-1), where nr[p] and nc[q] are, resp., numbers of +* non-zeros in p-th row and q-th column of the active submatrix. +* +* In order to reduce the search, i.e. not to walk through all elements +* of the active submatrix, the routine uses a technique proposed by +* I.Duff. This technique is based on using the sets R[len] and C[len] +* of active rows and columns. +* +* If the pivot element v[p,q] has been chosen, the routine stores its +* indices to locations *p and *q and returns zero. Otherwise, non-zero +* is returned. */ + +int sgf_choose_pivot(SGF *sgf, int *p_, int *q_) +{ LUF *luf = sgf->luf; + int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int vr_ref = luf->vr_ref; + int *vr_ptr = &sva->ptr[vr_ref-1]; + int *vr_len = &sva->len[vr_ref-1]; + int vc_ref = luf->vc_ref; + int *vc_ptr = &sva->ptr[vc_ref-1]; + int *vc_len = &sva->len[vc_ref-1]; + int *rs_head = sgf->rs_head; + int *rs_next = sgf->rs_next; + int *cs_head = sgf->cs_head; + int *cs_prev = sgf->cs_prev; + int *cs_next = sgf->cs_next; + double *vr_max = sgf->vr_max; + double piv_tol = sgf->piv_tol; + int piv_lim = sgf->piv_lim; + int suhl = sgf->suhl; + int i, i_ptr, i_end, j, j_ptr, j_end, len, min_i, min_j, min_len, + ncand, next_j, p, q; + double best, big, cost, temp; + /* no pivot candidate has been chosen so far */ + p = q = 0, best = DBL_MAX, ncand = 0; + /* if the active submatrix contains a column having the only + * non-zero element (column singleton), choose it as the pivot */ + j = cs_head[1]; + if (j != 0) + { xassert(vc_len[j] == 1); + p = sv_ind[vc_ptr[j]], q = j; + goto done; + } + /* if the active submatrix contains a row having the only + * non-zero element (row singleton), choose it as the pivot */ + i = rs_head[1]; + if (i != 0) + { xassert(vr_len[i] == 1); + p = i, q = sv_ind[vr_ptr[i]]; + goto done; + } + /* the active submatrix contains no singletons; walk thru its + * other non-empty rows and columns */ + for (len = 2; len <= n; len++) + { /* consider active columns containing len non-zeros */ + for (j = cs_head[len]; j != 0; j = next_j) + { /* save the number of next column of the same length */ + next_j = cs_next[j]; + /* find an element in j-th column, which is placed in the + * row with minimal number of non-zeros and satisfies to + * the stability condition (such element may not exist) */ + min_i = min_j = 0, min_len = INT_MAX; + for (j_end = (j_ptr = vc_ptr[j]) + vc_len[j]; + j_ptr < j_end; j_ptr++) + { /* get row index of v[i,j] */ + i = sv_ind[j_ptr]; + /* if i-th row is not shorter, skip v[i,j] */ + if (vr_len[i] >= min_len) + continue; + /* big := max|v[i,*]| */ + if ((big = vr_max[i]) < 0.0) + { /* largest magnitude is unknown; compute it */ + for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; + i_ptr < i_end; i_ptr++) + { if ((temp = sv_val[i_ptr]) < 0.0) + temp = -temp; + if (big < temp) + big = temp; + } + xassert(big > 0.0); + vr_max[i] = big; + } + /* find v[i,j] in i-th row */ + for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; + sv_ind[i_ptr] != j; i_ptr++) + /* nop */; + xassert(i_ptr < i_end); + /* if |v[i,j]| < piv_tol * max|v[i,*]|, skip v[i,j] */ + if ((temp = sv_val[i_ptr]) < 0.0) + temp = -temp; + if (temp < piv_tol * big) + continue; + /* v[i,j] is a better candidate */ + min_i = i, min_j = j, min_len = vr_len[i]; + /* if Markowitz cost of v[i,j] is not greater than + * (len-1)**2, v[i,j] can be chosen as the pivot right + * now; this heuristic reduces the search and works well + * in many cases */ + if (min_len <= len) + { p = min_i, q = min_j; + goto done; + } + } + /* j-th column has been scanned */ + if (min_i != 0) + { /* element v[min_i,min_j] is a next pivot candidate */ + ncand++; + /* compute its Markowitz cost */ + cost = (double)(min_len - 1) * (double)(len - 1); + /* if this element is better, choose it as the pivot */ + if (cost < best) + p = min_i, q = min_j, best = cost; + /* if piv_lim candidates were considered, terminate + * the search, because it is doubtful that a much better + * candidate will be found */ + if (ncand == piv_lim) + goto done; + } + else if (suhl) + { /* j-th column has no eligible elements that satisfy to + * the stability criterion; Uwe Suhl suggests to exclude + * such column from further considerations until it + * becomes a column singleton; in hard cases this may + * significantly reduce the time needed to choose the + * pivot element */ + sgf_deactivate_col(j); + cs_prev[j] = cs_next[j] = j; + } + } + /* consider active rows containing len non-zeros */ + for (i = rs_head[len]; i != 0; i = rs_next[i]) + { /* big := max|v[i,*]| */ + if ((big = vr_max[i]) < 0.0) + { /* largest magnitude is unknown; compute it */ + for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; + i_ptr < i_end; i_ptr++) + { if ((temp = sv_val[i_ptr]) < 0.0) + temp = -temp; + if (big < temp) + big = temp; + } + xassert(big > 0.0); + vr_max[i] = big; + } + /* find an element in i-th row, which is placed in the + * column with minimal number of non-zeros and satisfies to + * the stability condition (such element always exists) */ + min_i = min_j = 0, min_len = INT_MAX; + for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; + i_ptr < i_end; i_ptr++) + { /* get column index of v[i,j] */ + j = sv_ind[i_ptr]; + /* if j-th column is not shorter, skip v[i,j] */ + if (vc_len[j] >= min_len) + continue; + /* if |v[i,j]| < piv_tol * max|v[i,*]|, skip v[i,j] */ + if ((temp = sv_val[i_ptr]) < 0.0) + temp = -temp; + if (temp < piv_tol * big) + continue; + /* v[i,j] is a better candidate */ + min_i = i, min_j = j, min_len = vc_len[j]; + /* if Markowitz cost of v[i,j] is not greater than + * (len-1)**2, v[i,j] can be chosen as the pivot right + * now; this heuristic reduces the search and works well + * in many cases */ + if (min_len <= len) + { p = min_i, q = min_j; + goto done; + } + } + /* i-th row has been scanned */ + if (min_i != 0) + { /* element v[min_i,min_j] is a next pivot candidate */ + ncand++; + /* compute its Markowitz cost */ + cost = (double)(len - 1) * (double)(min_len - 1); + /* if this element is better, choose it as the pivot */ + if (cost < best) + p = min_i, q = min_j, best = cost; + /* if piv_lim candidates were considered, terminate + * the search, because it is doubtful that a much better + * candidate will be found */ + if (ncand == piv_lim) + goto done; + } + else + { /* this can never be */ + xassert(min_i != min_i); + } + } + } +done: /* report the pivot to the factorization routine */ + *p_ = p, *q_ = q; + return (p == 0); +} + +/*********************************************************************** +* sgf_eliminate - perform gaussian elimination +* +* This routine performs elementary gaussian transformations in order +* to eliminate subdiagonal elements in k-th column of matrix +* U = P'* V * Q' using pivot element u[k,k], where k is the number of +* current elimination step, 1 <= k <= n. +* +* The parameters p and q specify, resp., row and column indices of the +* pivot element v[p,q] = u[k,k]. +* +* On entry the routine assumes that partially triangularized matrices +* L = P'* F * P and U = P'* V * Q' have the following structure: +* +* 1 k n 1 k n +* 1 1 . . . . . . . . . 1 x x x x x x x x x x +* x 1 . . . . . . . . . x x x x x x x x x +* x x 1 . . . . . . . . . x x x x x x x x +* x x x 1 . . . . . . . . . x x x x x x x +* k x x x x 1 . . . . . k . . . . * * * * * * +* x x x x _ 1 . . . . . . . . # * * * * * +* x x x x _ . 1 . . . . . . . # * * * * * +* x x x x _ . . 1 . . . . . . # * * * * * +* x x x x _ . . . 1 . . . . . # * * * * * +* n x x x x _ . . . . 1 n . . . . # * * * * * +* +* matrix L matrix U +* +* where rows and columns k, k+1, ..., n of matrix U constitute the +* active submatrix. Elements to be eliminated are marked by '#', and +* other elements of the active submatrix are marked by '*'. May note +* that each eliminated non-zero element u[i,k] of matrix U gives +* corresponding non-zero element l[i,k] of matrix L (marked by '_'). +* +* Actually all operations are performed on matrix V. It is assumed +* that the row-wise representation corresponds to matrix V, but the +* column-wise representation corresponds to the active submatrix of +* matrix V (or, more precisely, to its pattern, because only row +* indices for columns of the active submatrix are used on this stage). +* +* Let u[k,k] = v[p,q] be the pivot. In order to eliminate subdiagonal +* elements u[i',k] = v[i,q], i'= k+1, k+2, ..., n, the routine applies +* the following elementary gaussian transformations: +* +* (i-th row of V) := (i-th row of V) - f[i,p] * (p-th row of V), +* +* where f[i,p] = v[i,q] / v[p,q] is a gaussian multiplier stored to +* p-th column of matrix F to keep the main equality A = F * V +* (corresponding elements l[i',k] of matrix L are marked by '_' on the +* figure above). +* +* NOTE: On entry to the routine the working arrays flag and work +* should contain zeros. This status is retained by the routine +* on exit. */ + +int sgf_eliminate(SGF *sgf, int p, int q) +{ LUF *luf = sgf->luf; + int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int fc_ref = luf->fc_ref; + int *fc_ptr = &sva->ptr[fc_ref-1]; + int *fc_len = &sva->len[fc_ref-1]; + int vr_ref = luf->vr_ref; + int *vr_ptr = &sva->ptr[vr_ref-1]; + int *vr_len = &sva->len[vr_ref-1]; + int *vr_cap = &sva->cap[vr_ref-1]; + double *vr_piv = luf->vr_piv; + int vc_ref = luf->vc_ref; + int *vc_ptr = &sva->ptr[vc_ref-1]; + int *vc_len = &sva->len[vc_ref-1]; + int *vc_cap = &sva->cap[vc_ref-1]; + int *rs_head = sgf->rs_head; + int *rs_prev = sgf->rs_prev; + int *rs_next = sgf->rs_next; + int *cs_head = sgf->cs_head; + int *cs_prev = sgf->cs_prev; + int *cs_next = sgf->cs_next; + double *vr_max = sgf->vr_max; + char *flag = sgf->flag; + double *work = sgf->work; + double eps_tol = sgf->eps_tol; + int nnz_diff = 0; + int fill, i, i_ptr, i_end, j, j_ptr, j_end, ptr, len, loc, loc1; + double vpq, fip, vij; + xassert(1 <= p && p <= n); + xassert(1 <= q && q <= n); + /* remove p-th row from the active set; this row will never + * return there */ + sgf_deactivate_row(p); + /* process p-th (pivot) row */ + ptr = 0; + for (i_end = (i_ptr = vr_ptr[p]) + vr_len[p]; + i_ptr < i_end; i_ptr++) + { /* get column index of v[p,j] */ + j = sv_ind[i_ptr]; + if (j == q) + { /* save pointer to pivot v[p,q] */ + ptr = i_ptr; + } + else + { /* store v[p,j], j != q, to working array */ + flag[j] = 1; + work[j] = sv_val[i_ptr]; + } + /* remove j-th column from the active set; q-th column will + * never return there while other columns will return to the + * active set with new length */ + if (cs_next[j] == j) + { /* j-th column was marked by the pivoting routine according + * to Uwe Suhl's suggestion and is already inactive */ + xassert(cs_prev[j] == j); + } + else + sgf_deactivate_col(j); + nnz_diff -= vc_len[j]; + /* find and remove v[p,j] from j-th column */ + for (j_end = (j_ptr = vc_ptr[j]) + vc_len[j]; + sv_ind[j_ptr] != p; j_ptr++) + /* nop */; + xassert(j_ptr < j_end); + sv_ind[j_ptr] = sv_ind[j_end-1]; + vc_len[j]--; + } + /* save pivot v[p,q] and remove it from p-th row */ + xassert(ptr > 0); + vpq = vr_piv[p] = sv_val[ptr]; + sv_ind[ptr] = sv_ind[i_end-1]; + sv_val[ptr] = sv_val[i_end-1]; + vr_len[p]--; + /* if it is not planned to update matrix V, relocate p-th row to + * the right (static) part of SVA */ + if (!sgf->updat) + { len = vr_len[p]; + if (sva->r_ptr - sva->m_ptr < len) + { sva_more_space(sva, len); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_make_static(sva, vr_ref-1+p); + } + /* copy the pattern (row indices) of q-th column of the active + * submatrix (from which v[p,q] has been just removed) to p-th + * column of matrix F (without unity diagonal element) */ + len = vc_len[q]; + if (len > 0) + { if (sva->r_ptr - sva->m_ptr < len) + { sva_more_space(sva, len); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_reserve_cap(sva, fc_ref-1+p, len); + memcpy(&sv_ind[fc_ptr[p]], &sv_ind[vc_ptr[q]], + len * sizeof(int)); + fc_len[p] = len; + } + /* make q-th column of the active submatrix empty */ + vc_len[q] = 0; + /* transform non-pivot rows of the active submatrix */ + for (loc = fc_len[p]-1; loc >= 0; loc--) + { /* get row index of v[i,q] = row index of f[i,p] */ + i = sv_ind[fc_ptr[p] + loc]; + xassert(i != p); /* v[p,q] was removed */ + /* remove i-th row from the active set; this row will return + * there with new length */ + sgf_deactivate_row(i); + /* find v[i,q] in i-th row */ + for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; + sv_ind[i_ptr] != q; i_ptr++) + /* nop */; + xassert(i_ptr < i_end); + /* compute gaussian multiplier f[i,p] = v[i,q] / v[p,q] */ + fip = sv_val[fc_ptr[p] + loc] = sv_val[i_ptr] / vpq; + /* remove v[i,q] from i-th row */ + sv_ind[i_ptr] = sv_ind[i_end-1]; + sv_val[i_ptr] = sv_val[i_end-1]; + vr_len[i]--; + /* perform elementary gaussian transformation: + * (i-th row) := (i-th row) - f[i,p] * (p-th row) + * note that p-th row of V, which is in the working array, + * doesn't contain pivot v[p,q], and i-th row of V doesn't + * contain v[i,q] to be eliminated */ + /* walk thru i-th row and transform existing elements */ + fill = vr_len[p]; + for (i_end = (i_ptr = ptr = vr_ptr[i]) + vr_len[i]; + i_ptr < i_end; i_ptr++) + { /* get column index and value of v[i,j] */ + j = sv_ind[i_ptr]; + vij = sv_val[i_ptr]; + if (flag[j]) + { /* v[p,j] != 0 */ + flag[j] = 0, fill--; + /* v[i,j] := v[i,j] - f[i,p] * v[p,j] */ + vij -= fip * work[j]; + if (-eps_tol < vij && vij < +eps_tol) + { /* new v[i,j] is close to zero; remove it from the + * active submatrix, i.e. replace it by exact zero */ + /* find and remove v[i,j] from j-th column */ + for (j_end = (j_ptr = vc_ptr[j]) + vc_len[j]; + sv_ind[j_ptr] != i; j_ptr++) + /* nop */; + xassert(j_ptr < j_end); + sv_ind[j_ptr] = sv_ind[j_end-1]; + vc_len[j]--; + continue; + } + } + /* keep new v[i,j] in i-th row */ + sv_ind[ptr] = j; + sv_val[ptr] = vij; + ptr++; + } + /* (new length of i-th row may decrease because of numerical + * cancellation) */ + vr_len[i] = len = ptr - vr_ptr[i]; + /* now flag[*] is the pattern of the set v[p,*] \ v[i,*], and + * fill is the number of non-zeros in this set */ + if (fill == 0) + { /* no fill-in occurs */ + /* walk thru p-th row and restore the column flags */ + for (i_end = (i_ptr = vr_ptr[p]) + vr_len[p]; + i_ptr < i_end; i_ptr++) + flag[sv_ind[i_ptr]] = 1; /* v[p,j] != 0 */ + goto skip; + } + /* up to fill new non-zero elements may appear in i-th row due + * to fill-in; reserve locations for these elements (note that + * actual length of i-th row is currently stored in len) */ + if (vr_cap[i] < len + fill) + { if (sva->r_ptr - sva->m_ptr < len + fill) + { sva_more_space(sva, len + fill); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_enlarge_cap(sva, vr_ref-1+i, len + fill, 0); + } + vr_len[i] += fill; + /* walk thru p-th row and add new elements to i-th row */ + for (loc1 = vr_len[p]-1; loc1 >= 0; loc1--) + { /* get column index of v[p,j] */ + j = sv_ind[vr_ptr[p] + loc1]; + if (!flag[j]) + { /* restore j-th column flag */ + flag[j] = 1; + /* v[i,j] was computed earlier on transforming existing + * elements of i-th row */ + continue; + } + /* v[i,j] := 0 - f[i,p] * v[p,j] */ + vij = - fip * work[j]; + if (-eps_tol < vij && vij < +eps_tol) + { /* new v[i,j] is close to zero; do not add it to the + * active submatrix, i.e. replace it by exact zero */ + continue; + } + /* add new v[i,j] to i-th row */ + sv_ind[ptr = vr_ptr[i] + (len++)] = j; + sv_val[ptr] = vij; + /* add new v[i,j] to j-th column */ + if (vc_cap[j] == vc_len[j]) + { /* we reserve extra locations in j-th column to reduce + * further relocations of that column */ +#if 1 /* FIXME */ + /* use control parameter to specify the number of extra + * locations reserved */ + int need = vc_len[j] + 10; +#endif + if (sva->r_ptr - sva->m_ptr < need) + { sva_more_space(sva, need); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_enlarge_cap(sva, vc_ref-1+j, need, 1); + } + sv_ind[vc_ptr[j] + (vc_len[j]++)] = i; + } + /* set final length of i-th row just transformed */ + xassert(len <= vr_len[i]); + vr_len[i] = len; +skip: /* return i-th row to the active set with new length */ + sgf_activate_row(i); + /* since i-th row has been changed, largest magnitude of its + * elements becomes unknown */ + vr_max[i] = -1.0; + } + /* walk thru p-th (pivot) row */ + for (i_end = (i_ptr = vr_ptr[p]) + vr_len[p]; + i_ptr < i_end; i_ptr++) + { /* get column index of v[p,j] */ + j = sv_ind[i_ptr]; + xassert(j != q); /* v[p,q] was removed */ + /* return j-th column to the active set with new length */ + if (cs_next[j] == j && vc_len[j] != 1) + { /* j-th column was marked by the pivoting routine and it is + * still not a column singleton, so leave it incative */ + xassert(cs_prev[j] == j); + } + else + sgf_activate_col(j); + nnz_diff += vc_len[j]; + /* restore zero content of the working arrays */ + flag[j] = 0; + work[j] = 0.0; + } + /* return the difference between the numbers of non-zeros in the + * active submatrix on entry and on exit, resp. */ + return nnz_diff; +} + +/*********************************************************************** +* sgf_dense_lu - compute dense LU-factorization with full pivoting +* +* This routine performs Gaussian elimination with full pivoting to +* compute dense LU-factorization of the specified matrix A of order n +* in the form: +* +* A = P * L * U * Q, (1) +* +* where L is lower triangular matrix with unit diagonal, U is upper +* triangular matrix, P and Q are permutation matrices. +* +* On entry to the routine elements of matrix A = (a[i,j]) should be +* placed in the array elements a[0], ..., a[n^2-1] in dense row-wise +* format. On exit from the routine matrix A is replaced by factors L +* and U as follows: +* +* u[1,1] u[1,2] ... u[1,n-1] u[1,n] +* l[2,1] u[2,2] ... u[2,n-1] u[2,n] +* . . . . . . . . . . . . . . +* l[n-1,1] l[n-1,2] u[n-1,n-1] u[n-1,n] +* l[n,1] l[n,2] ... l[n,n-1] u[n,n] +* +* The unit diagonal elements of L are not stored. +* +* Information on permutations of rows and columns of active submatrix +* during factorization is accumulated by the routine as follows. Every +* time the routine permutes rows i and i' or columns j and j', it also +* permutes elements r[i-1] and r[i'-1] or c[j-1] and c[j'-1], resp. +* Thus, on entry to the routine elements r[0], r[1], ..., r[n-1] and +* c[0], c[1], ..., c[n-1] should be initialized by some integers that +* identify rows and columns of the original matrix A. +* +* If the factorization has been successfully computed, the routine +* returns zero. Otherwise, if on k-th elimination step, 1 <= k <= n, +* all elements of the active submatrix are close to zero, the routine +* returns k, in which case a partial factorization is stored in the +* array a. */ + +int sgf_dense_lu(int n, double a_[], int r[], int c[], double eps) +{ /* non-optimized version */ + int i, j, k, p, q, ref; + double akk, big, temp; +# define a(i,j) a_[(i)*n+(j)] + /* initially U = A, L = P = Q = I */ + /* main elimination loop */ + for (k = 0; k < n; k++) + { /* choose pivot u[p,q], k <= p, q <= n */ + p = q = -1, big = eps; + for (i = k; i < n; i++) + { for (j = k; j < n; j++) + { /* temp = |u[i,j]| */ + if ((temp = a(i,j)) < 0.0) + temp = -temp; + if (big < temp) + p = i, q = j, big = temp; + } + } + if (p < 0) + { /* k-th elimination step failed */ + return k+1; + } + /* permute rows k and p */ + if (k != p) + { for (j = 0; j < n; j++) + temp = a(k,j), a(k,j) = a(p,j), a(p,j) = temp; + ref = r[k], r[k] = r[p], r[p] = ref; + } + /* permute columns k and q */ + if (k != q) + { for (i = 0; i < n; i++) + temp = a(i,k), a(i,k) = a(i,q), a(i,q) = temp; + ref = c[k], c[k] = c[q], c[q] = ref; + } + /* now pivot is in position u[k,k] */ + akk = a(k,k); + /* eliminate subdiagonal elements u[k+1,k], ..., u[n,k] */ + for (i = k+1; i < n; i++) + { if (a(i,k) != 0.0) + { /* gaussian multiplier l[i,k] := u[i,k] / u[k,k] */ + temp = (a(i,k) /= akk); + /* (i-th row) := (i-th row) - l[i,k] * (k-th row) */ + for (j = k+1; j < n; j++) + a(i,j) -= temp * a(k,j); + } + } + } +# undef a + return 0; +} + +/*********************************************************************** +* sgf_dense_phase - compute LU-factorization (dense phase) +* +* This routine performs dense phase of computing LU-factorization. +* +* The aim is two-fold. First, the main factorization routine switches +* to dense phase when the active submatrix is relatively dense, so +* using dense format allows significantly reduces overheads needed to +* maintain sparse data structures. And second, that is more important, +* on dense phase full pivoting is used (rather than partial pivoting) +* that allows improving numerical stability, since round-off errors +* tend to increase on last steps of the elimination process. +* +* On entry the routine assumes that elimination steps 1, 2, ..., k-1 +* have been performed, so partially transformed matrices L = P'* F * P +* and U = P'* V * Q' have the following structure: +* +* 1 k n 1 k n +* 1 1 . . . . . . . . . 1 x x x x x x x x x x +* x 1 . . . . . . . . . x x x x x x x x x +* x x 1 . . . . . . . . . x x x x x x x x +* x x x 1 . . . . . . . . . x x x x x x x +* k x x x x 1 . . . . . k . . . . * * * * * * +* x x x x . 1 . . . . . . . . * * * * * * +* x x x x . . 1 . . . . . . . * * * * * * +* x x x x . . . 1 . . . . . . * * * * * * +* x x x x . . . . 1 . . . . . * * * * * * +* n x x x x . . . . . 1 n . . . . * * * * * * +* +* matrix L matrix U +* +* where rows and columns k, k+1, ..., n of matrix U constitute the +* active submatrix A~, whose elements are marked by '*'. +* +* The routine copies the active submatrix A~ to a working array in +* dense format, compute dense factorization A~ = P~* L~* U~* Q~ using +* full pivoting, and then copies non-zero elements of factors L~ and +* U~ back to factors L and U (more precisely, to factors F and V). +* +* If the factorization has been successfully computed, the routine +* returns zero. Otherwise, if on k-th elimination step, 1 <= k <= n, +* all elements of the active submatrix are close to zero, the routine +* returns k (information on linearly dependent rows/columns in this +* case is provided by matrices P and Q). */ + +int sgf_dense_phase(LUF *luf, int k, int updat) +{ int n = luf->n; + SVA *sva = luf->sva; + int *sv_ind = sva->ind; + double *sv_val = sva->val; + int fc_ref = luf->fc_ref; + int *fc_ptr = &sva->ptr[fc_ref-1]; + int *fc_len = &sva->len[fc_ref-1]; + int *fc_cap = &sva->cap[fc_ref-1]; + int vr_ref = luf->vr_ref; + int *vr_ptr = &sva->ptr[vr_ref-1]; + int *vr_len = &sva->len[vr_ref-1]; + int *vr_cap = &sva->cap[vr_ref-1]; + double *vr_piv = luf->vr_piv; + int vc_ref = luf->vc_ref; + int *vc_len = &sva->len[vc_ref-1]; + int *pp_inv = luf->pp_inv; + int *pp_ind = luf->pp_ind; + int *qq_ind = luf->qq_ind; + int *qq_inv = luf->qq_inv; + int a_end, a_ptr, end, i, ia, ii, j, ja, jj, ka, len, na, ne, + need, ptr; + double *a_; + xassert(1 <= k && k <= n); + /* active columns of V are not longer needed; make them empty */ + for (jj = k; jj <= n; jj++) + { /* jj is number of active column of U = P'* V * Q' */ + vc_len[qq_ind[jj]] = 0; + } + /* determine order of active submatrix A~ of matrix U */ + na = n - k + 1; + xassert(1 <= na && na <= n); + /* determine number of elements in dense triangular factor (L~ or + * U~), except diagonal elements */ + ne = na * (na - 1) / 2; + /* we allocate active submatrix A~ in free (middle) part of SVA; + * to avoid defragmentation that could destroy A~ we also should + * reserve ne locations to build rows of V from rows of U~ and ne + * locations to build columns of F from columns of L~ */ + need = na * na + ne + ne; + if (sva->r_ptr - sva->m_ptr < need) + { sva_more_space(sva, need); + sv_ind = sva->ind; + sv_val = sva->val; + } + /* free (middle) part of SVA is structured as follows: + * end of left (dynamic) part + * ne free locations for new rows of V + * na free locations for active submatrix A~ + * unused locations, if any + * ne free locations for new columns of F + * beginning of right (static) part */ + a_ptr = sva->m_ptr + ne; + a_end = a_ptr + na * na; + /* copy active submatrix A~ from matrix V to working array in + * dense row-wise format */ + a_ = &sva->val[a_ptr]; +# define a(ia, ja) a_[((ia) - 1) * na + ((ja) - 1)] + for (ia = 1; ia <= na; ia++) + { /* clear ia-th row of A~ */ + for (ja = 1; ja <= na; ja++) + a(ia, ja) = 0.0; + /* ia-th row of A~ = (k-1+ia)-th row of U = i-th row of V */ + i = pp_inv[k-1+ia]; + ptr = vr_ptr[i]; + end = ptr + vr_len[i]; + for (; ptr < end; ptr++) + a(ia, qq_inv[sv_ind[ptr]]-k+1) = sv_val[ptr]; + /* i-th row of V is no longer needed; make it empty */ + vr_len[i] = 0; + } + /* compute dense factorization A~ = P~* L~* U~* Q~ */ +#if 1 /* FIXME: epsilon tolerance */ + ka = sgf_dense_lu(na, &a(1, 1), &pp_inv[k], &qq_ind[k], 1e-20); +#endif + /* rows of U with numbers pp_inv[k, k+1, ..., n] were permuted + * due to row permutations of A~; update matrix P using P~ */ + for (ii = k; ii <= n; ii++) + pp_ind[pp_inv[ii]] = ii; + /* columns of U with numbers qq_ind[k, k+1, ..., n] were permuted + * due to column permutations of A~; update matrix Q using Q~ */ + for (jj = k; jj <= n; jj++) + qq_inv[qq_ind[jj]] = jj; + /* check if dense factorization is complete */ + if (ka != 0) + { /* A~ is singular to working precision */ + /* information on linearly dependent rows/columns is provided + * by matrices P and Q */ + xassert(1 <= ka && ka <= na); + return k - 1 + ka; + } + /* build new rows of V from rows of U~ */ + for (ia = 1; ia <= na; ia++) + { /* ia-th row of U~ = (k-1+ia)-th row of U = i-th row of V */ + i = pp_inv[k-1+ia]; + xassert(vr_len[i] == 0); + /* store diagonal element u~[ia,ia] */ + vr_piv[i] = a(ia, ia); + /* determine number of non-zero non-diagonal elements in ia-th + * row of U~ */ + len = 0; + for (ja = ia+1; ja <= na; ja++) + { if (a(ia, ja) != 0.0) + len++; + } + /* reserve len locations for i-th row of matrix V in left + * (dynamic) part of SVA */ + if (vr_cap[i] < len) + { /* there should be enough room in free part of SVA */ + xassert(sva->r_ptr - sva->m_ptr >= len); + sva_enlarge_cap(sva, vr_ref-1+i, len, 0); + /* left part of SVA should not overlap matrix A~ */ + xassert(sva->m_ptr <= a_ptr); + } + /* copy non-zero non-diaginal elements of ia-th row of U~ to + * i-th row of V */ + ptr = vr_ptr[i]; + for (ja = ia+1; ja <= na; ja++) + { if (a(ia, ja) != 0.0) + { sv_ind[ptr] = qq_ind[k-1+ja]; + sv_val[ptr] = a(ia, ja); + ptr++; + } + } + xassert(ptr - vr_ptr[i] == len); + vr_len[i] = len; + } + /* build new columns of F from columns of L~ */ + for (ja = 1; ja <= na; ja++) + { /* ja-th column of L~ = (k-1+ja)-th column of L = j-th column + * of F */ + j = pp_inv[k-1+ja]; + xassert(fc_len[j] == 0); + xassert(fc_cap[j] == 0); + /* determine number of non-zero non-diagonal elements in ja-th + * column of L~ */ + len = 0; + for (ia = ja+1; ia <= na; ia++) + { if (a(ia, ja) != 0.0) + len++; + } + /* reserve len locations for j-th column of matrix F in right + * (static) part of SVA */ + /* there should be enough room in free part of SVA */ + xassert(sva->r_ptr - sva->m_ptr >= len); + if (len > 0) + sva_reserve_cap(sva, fc_ref-1+j, len); + /* right part of SVA should not overlap matrix A~ */ + xassert(a_end <= sva->r_ptr); + /* copy non-zero non-diagonal elements of ja-th column of L~ + * to j-th column of F */ + ptr = fc_ptr[j]; + for (ia = ja+1; ia <= na; ia++) + { if (a(ia, ja) != 0.0) + { sv_ind[ptr] = pp_inv[k-1+ia]; + sv_val[ptr] = a(ia, ja); + ptr++; + } + } + xassert(ptr - fc_ptr[j] == len); + fc_len[j] = len; + } + /* factors L~ and U~ are no longer needed */ +# undef a + /* if it is not planned to update matrix V, relocate all its new + * rows to the right (static) part of SVA */ + if (!updat) + { for (ia = 1; ia <= na; ia++) + { i = pp_inv[k-1+ia]; + len = vr_len[i]; + if (sva->r_ptr - sva->m_ptr < len) + { sva_more_space(sva, len); + sv_ind = sva->ind; + sv_val = sva->val; + } + sva_make_static(sva, vr_ref-1+i); + } + } + return 0; +} + +/*********************************************************************** +* sgf_factorize - compute LU-factorization (main routine) +* +* This routine computes sparse LU-factorization of specified matrix A +* using Gaussian elimination. +* +* On entry to the routine matrix V = A should be stored in column-wise +* format. +* +* If the factorization has been successfully computed, the routine +* returns zero. Otherwise, if on k-th elimination step, 1 <= k <= n, +* all elements of the active submatrix are close to zero, the routine +* returns k (information on linearly dependent rows/columns in this +* case is provided by matrices P and Q). */ + +int sgf_factorize(SGF *sgf, int singl) +{ LUF *luf = sgf->luf; + int n = luf->n; + SVA *sva = luf->sva; + int vr_ref = luf->vr_ref; + int *vr_len = &sva->len[vr_ref-1]; + double *vr_piv = luf->vr_piv; + int vc_ref = luf->vc_ref; + int *vc_len = &sva->len[vc_ref-1]; + int *pp_ind = luf->pp_ind; + int *pp_inv = luf->pp_inv; + int *qq_ind = luf->qq_ind; + int *qq_inv = luf->qq_inv; + int *rs_head = sgf->rs_head; + int *rs_prev = sgf->rs_prev; + int *rs_next = sgf->rs_next; + int *cs_head = sgf->cs_head; + int *cs_prev = sgf->cs_prev; + int *cs_next = sgf->cs_next; + double *vr_max = sgf->vr_max; + char *flag = sgf->flag; + double *work = sgf->work; + int i, j, k, k1, k2, p, q, nnz; + /* build matrix V = A in row-wise format */ + luf_build_v_rows(luf, rs_prev); + /* P := Q := I, so V = U = A, F = L = I */ + for (k = 1; k <= n; k++) + { vr_piv[k] = 0.0; + pp_ind[k] = pp_inv[k] = qq_ind[k] = qq_inv[k] = k; + } +#ifdef GLP_DEBUG + sva_check_area(sva); + luf_check_all(luf, 1); +#endif + /* perform singleton phase, if required */ + if (!singl) + { /* assume that nucleus is entire matrix U */ + k2 = 1; + } + else + { /* minimize nucleus size */ + sgf_reduce_nuc(luf, &k1, &k2, rs_prev, rs_next); +#ifdef GLP_DEBUG + xprintf("n = %d; k1 = %d; k2 = %d\n", n, k1, k2); +#endif + /* perform singleton phase */ + k2 = sgf_singl_phase(luf, k1, k2, sgf->updat, rs_prev, work); + } +#ifdef GLP_DEBUG + sva_check_area(sva); + luf_check_all(luf, k2); +#endif + /* initialize working arrays */ + rs_head[0] = cs_head[0] = 0; + for (k = 1; k <= n; k++) + { rs_head[k] = cs_head[k] = 0; + vr_max[k] = -1.0; + flag[k] = 0; + work[k] = 0.0; + } + /* build lists of active rows and columns of matrix V; determine + * number of non-zeros in initial active submatrix */ + nnz = 0; + for (k = k2; k <= n; k++) + { i = pp_inv[k]; + sgf_activate_row(i); + nnz += vr_len[i]; + j = qq_ind[k]; + sgf_activate_col(j); + } + /* main factorization loop */ + for (k = k2; k <= n; k++) + { int na; + double den; + /* calculate density of active submatrix */ + na = n - k + 1; /* order of active submatrix */ +#if 0 /* 21/VIII-2014 */ + den = (double)nnz / (double)(na * na); +#else + den = (double)nnz / ((double)(na) * (double)(na)); +#endif + /* if active submatrix is relatively dense, switch to dense + * phase */ +#if 1 /* FIXME */ + if (na >= 5 && den >= 0.71) + { +#ifdef GLP_DEBUG + xprintf("na = %d; nnz = %d; den = %g\n", na, nnz, den); +#endif + break; + } +#endif + /* choose pivot v[p,q] */ + if (sgf_choose_pivot(sgf, &p, &q) != 0) + return k; /* failure */ + /* u[i,j] = v[p,q], k <= i, j <= n */ + i = pp_ind[p]; + xassert(k <= i && i <= n); + j = qq_inv[q]; + xassert(k <= j && j <= n); + /* move u[i,j] to position u[k,k] by implicit permutations of + * rows and columns of matrix U */ + luf_swap_u_rows(k, i); + luf_swap_u_cols(k, j); + /* perform gaussian elimination */ + nnz += sgf_eliminate(sgf, p, q); + } +#if 1 /* FIXME */ + if (k <= n) + { /* continue computing factorization in dense mode */ +#ifdef GLP_DEBUG + sva_check_area(sva); + luf_check_all(luf, k); +#endif + k = sgf_dense_phase(luf, k, sgf->updat); + if (k != 0) + return k; /* failure */ + } +#endif +#ifdef GLP_DEBUG + sva_check_area(sva); + luf_check_all(luf, n+1); +#endif + /* defragment SVA; currently all columns of V are empty, so they + * will have zero capacity as required by luf_build_v_cols */ + sva_defrag_area(sva); + /* build matrix F in row-wise format */ + luf_build_f_rows(luf, rs_head); + /* build matrix V in column-wise format */ + luf_build_v_cols(luf, sgf->updat, rs_head); + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/sgf.h b/resources/3rdparty/glpk-4.57/src/bflib/sgf.h new file mode 100644 index 000000000..04d528cb7 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/sgf.h @@ -0,0 +1,203 @@ +/* sgf.h (sparse Gaussian factorizer) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef SGF_H +#define SGF_H + +#include "luf.h" + +typedef struct SGF SGF; + +struct SGF +{ /* sparse Gaussian factorizer workspace */ + LUF *luf; + /* LU-factorization being computed */ + /*--------------------------------------------------------------*/ + /* to efficiently choose pivot elements according to Markowitz + * strategy, the search technique proposed by Iain Duff is used; + * it is based on using two families of sets {R[0], ..., R[n]} + * and {C[0], ..., C[n]}, where R[k] and C[k], 0 <= k <= n, are, + * respectively, sets of rows and columns of the active submatrix + * of matrix V having k non-zeros (i.e. whose length is k); each + * set R[k] and C[k] is implemented as a doubly linked list */ + int *rs_head; /* int rs_head[1+n]; */ + /* rs_head[k], 0 <= k <= n, is the number of first row, which + * has k non-zeros in the active submatrix */ + int *rs_prev; /* int rs_prev[1+n]; */ + /* rs_prev[0] is not used; + * rs_prev[i], 1 <= i <= n, is the number of previous row, which + * has the same number of non-zeros as i-th row; + * rs_prev[i] < 0 means that i-th row is inactive */ + int *rs_next; /* int rs_next[1+n]; */ + /* rs_next[0] is not used; + * rs_next[i], 1 <= i <= n, is the number of next row, which has + * the same number of non-zeros as i-th row; + * rs_next[i] < 0 means that i-th row is inactive */ + int *cs_head; /* int cs_head[1+n]; */ + /* cs_head[k], 0 <= k <= n, is the number of first column, which + * has k non-zeros in the active submatrix */ + int *cs_prev; /* int cs_prev[1+n]; */ + /* cs_prev[0] is not used; + * cs_prev[j], 1 <= j <= n, is the number of previous column, + * which has the same number of non-zeros as j-th column; + * cs_prev[j] < 0 means that j-th column is inactive */ + int *cs_next; /* int cs_next[1+n]; */ + /* cs_next[0] is not used; + * cs_next[j], 1 <= j <= n, is the number of next column, which + * has the same number of non-zeros as j-th column; + * cs_next[j] < 0 means that j-th column is inactive */ + /* NOTE: cs_prev[j] = cs_next[j] = j means that j-th column was + * temporarily removed from corresponding set C[k] by the + * pivoting routine according to Uwe Suhl's heuristic */ + /*--------------------------------------------------------------*/ + /* working arrays */ + double *vr_max; /* int vr_max[1+n]; */ + /* vr_max[0] is not used; + * vr_max[i], 1 <= i <= n, is used only if i-th row of matrix V + * is active (i.e. belongs to the active submatrix), and is the + * largest magnitude of elements in that row; if vr_max[i] < 0, + * the largest magnitude is unknown yet */ + char *flag; /* char flag[1+n]; */ + /* boolean working array */ + double *work; /* double work[1+n]; */ + /* floating-point working array */ + /*--------------------------------------------------------------*/ + /* control parameters */ + int updat; + /* if this flag is set, the matrix V is assumed to be updatable; + * in this case factorized (non-active) part of V is stored in + * the left part of SVA rather than in its right part */ + double piv_tol; + /* threshold pivoting tolerance, 0 < piv_tol < 1; element v[i,j] + * of the active submatrix fits to be pivot if it satisfies to + * the stability criterion |v[i,j]| >= piv_tol * max |v[i,*]|, + * i.e. if it is not very small in the magnitude among other + * elements in the same row; decreasing this parameter gives + * better sparsity at the expense of numerical accuracy and vice + * versa */ + int piv_lim; + /* maximal allowable number of pivot candidates to be considered; + * if piv_lim pivot candidates have been considered, the pivoting + * routine terminates the search with the best candidate found */ + int suhl; + /* if this flag is set, the pivoting routine applies a heuristic + * proposed by Uwe Suhl: if a column of the active submatrix has + * no eligible pivot candidates (i.e. all its elements do not + * satisfy to the stability criterion), the routine excludes it + * from futher consideration until it becomes column singleton; + * in many cases this allows reducing the time needed to choose + * the pivot */ + double eps_tol; + /* epsilon tolerance; each element of the active submatrix, whose + * magnitude is less than eps_tol, is replaced by exact zero */ +#if 0 /* FIXME */ + double den_lim; + /* density limit; if the density of the active submatrix reaches + * this limit, the factorization routine switches from sparse to + * dense mode */ +#endif +}; + +#define sgf_activate_row(i) \ + do \ + { int len = vr_len[i]; \ + rs_prev[i] = 0; \ + rs_next[i] = rs_head[len]; \ + if (rs_next[i] != 0) \ + rs_prev[rs_next[i]] = i; \ + rs_head[len] = i; \ + } while (0) +/* include i-th row of matrix V in active set R[len] */ + +#define sgf_deactivate_row(i) \ + do \ + { if (rs_prev[i] == 0) \ + rs_head[vr_len[i]] = rs_next[i]; \ + else \ + rs_next[rs_prev[i]] = rs_next[i]; \ + if (rs_next[i] == 0) \ + ; \ + else \ + rs_prev[rs_next[i]] = rs_prev[i]; \ + rs_prev[i] = rs_next[i] = -1; \ + } while (0) +/* remove i-th row of matrix V from active set R[len] */ + +#define sgf_activate_col(j) \ + do \ + { int len = vc_len[j]; \ + cs_prev[j] = 0; \ + cs_next[j] = cs_head[len]; \ + if (cs_next[j] != 0) \ + cs_prev[cs_next[j]] = j; \ + cs_head[len] = j; \ + } while (0) +/* include j-th column of matrix V in active set C[len] */ + +#define sgf_deactivate_col(j) \ + do \ + { if (cs_prev[j] == 0) \ + cs_head[vc_len[j]] = cs_next[j]; \ + else \ + cs_next[cs_prev[j]] = cs_next[j]; \ + if (cs_next[j] == 0) \ + ; \ + else \ + cs_prev[cs_next[j]] = cs_prev[j]; \ + cs_prev[j] = cs_next[j] = -1; \ + } while (0) +/* remove j-th column of matrix V from active set C[len] */ + +#define sgf_reduce_nuc _glp_sgf_reduce_nuc +void sgf_reduce_nuc(LUF *luf, int *k1, int *k2, int cnt[/*1+n*/], + int list[/*1+n*/]); +/* initial reordering to minimize nucleus size */ + +#define sgf_singl_phase _glp_sgf_singl_phase +int sgf_singl_phase(LUF *luf, int k1, int k2, int updat, + int ind[/*1+n*/], double val[/*1+n*/]); +/* compute LU-factorization (singleton phase) */ + +#define sgf_choose_pivot _glp_sgf_choose_pivot +int sgf_choose_pivot(SGF *sgf, int *p, int *q); +/* choose pivot element v[p,q] */ + +#define sgf_eliminate _glp_sgf_eliminate +int sgf_eliminate(SGF *sgf, int p, int q); +/* perform gaussian elimination */ + +#define sgf_dense_lu _glp_sgf_dense_lu +int sgf_dense_lu(int n, double a[], int r[], int c[], double eps); +/* compute dense LU-factorization with full pivoting */ + +#define sgf_dense_phase _glp_sgf_dense_phase +int sgf_dense_phase(LUF *luf, int k, int updat); +/* compute LU-factorization (dense phase) */ + +#define sgf_factorize _glp_sgf_factorize +int sgf_factorize(SGF *sgf, int singl); +/* compute LU-factorization (main routine) */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/sva.c b/resources/3rdparty/glpk-4.57/src/bflib/sva.c new file mode 100644 index 000000000..e6a675ccb --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/sva.c @@ -0,0 +1,572 @@ +/* sva.c (sparse vector area) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "sva.h" + +/*********************************************************************** +* sva_create_area - create sparse vector area (SVA) +* +* This routine creates the sparse vector area (SVA), which initially +* is empty. +* +* The parameter n_max specifies the initial number of vectors that can +* be allocated in the SVA, n_max > 0. +* +* The parameter size specifies the initial number of free locations in +* the SVA, size > 0. +* +* On exit the routine returns a pointer to the SVA created. */ + +SVA *sva_create_area(int n_max, int size) +{ SVA *sva; + xassert(0 < n_max && n_max < INT_MAX); + xassert(0 < size && size < INT_MAX); + sva = talloc(1, SVA); + sva->n_max = n_max; + sva->n = 0; + sva->ptr = talloc(1+n_max, int); + sva->len = talloc(1+n_max, int); + sva->cap = talloc(1+n_max, int); + sva->size = size; + sva->m_ptr = 1; + sva->r_ptr = size+1; + sva->head = sva->tail = 0; + sva->prev = talloc(1+n_max, int); + sva->next = talloc(1+n_max, int); + sva->ind = talloc(1+size, int); + sva->val = talloc(1+size, double); + sva->talky = 0; + return sva; +} + +/*********************************************************************** +* sva_alloc_vecs - allocate new vectors in SVA +* +* This routine allocates nnn new empty vectors, nnn > 0, in the sparse +* vector area (SVA). +* +* The new vectors are assigned reference numbers k, k+1, ..., k+nnn-1, +* where k is a reference number assigned to the very first new vector, +* which is returned by the routine on exit. */ + +int sva_alloc_vecs(SVA *sva, int nnn) +{ int n = sva->n; + int n_max = sva->n_max; + int *ptr = sva->ptr; + int *len = sva->len; + int *cap = sva->cap; + int *prev = sva->prev; + int *next = sva->next; + int k, new_n; +#if 1 + if (sva->talky) + xprintf("sva_alloc_vecs: nnn = %d\n", nnn); +#endif + xassert(nnn > 0); + /* determine new number of vectors in SVA */ + new_n = n + nnn; + xassert(new_n > n); + if (n_max < new_n) + { /* enlarge the SVA arrays */ + while (n_max < new_n) + { n_max += n_max; + xassert(n_max > 0); + } + sva->n_max = n_max; + sva->ptr = ptr = trealloc(ptr, 1+n_max, int); + sva->len = len = trealloc(len, 1+n_max, int); + sva->cap = cap = trealloc(cap, 1+n_max, int); + sva->prev = prev = trealloc(prev, 1+n_max, int); + sva->next = next = trealloc(next, 1+n_max, int); + } + /* initialize new vectors */ + sva->n = new_n; + for (k = n+1; k <= new_n; k++) + { ptr[k] = len[k] = cap[k] = 0; + prev[k] = next[k] = -1; + } +#if 1 + if (sva->talky) + xprintf("now sva->n_max = %d, sva->n = %d\n", + sva->n_max, sva->n); +#endif + /* return reference number of very first new vector */ + return n+1; +} + +/*********************************************************************** +* sva_resize_area - change size of SVA storage +* +* This routine increases or decrases the size of the SVA storage by +* reallocating it. +* +* The parameter delta specifies the number of location by which the +* current size of the SVA storage should be increased (if delta > 0) +* or decreased (if delta < 0). Note that if delta is negative, it +* should not be less than the current size of the middle part. +* +* As a result of this operation the size of the middle part of SVA is +* increased/decreased by delta locations. +* +* NOTE: This operation changes ptr[k] for all vectors stored in the +* right part of SVA. */ + +void sva_resize_area(SVA *sva, int delta) +{ int n = sva->n; + int *ptr = sva->ptr; + int size = sva->size; + int m_ptr = sva->m_ptr; + int r_ptr = sva->r_ptr; + int k, r_size; +#if 1 + if (sva->talky) + xprintf("sva_resize_area: delta = %d\n", delta); +#endif + xassert(delta != 0); + /* determine size of the right part, in locations */ + r_size = size - r_ptr + 1; + /* relocate the right part in case of negative delta */ + if (delta < 0) + { xassert(delta >= m_ptr - r_ptr); + sva->r_ptr += delta; + memmove(&sva->ind[sva->r_ptr], &sva->ind[r_ptr], + r_size * sizeof(int)); + memmove(&sva->val[sva->r_ptr], &sva->val[r_ptr], + r_size * sizeof(double)); + } + /* reallocate the storage arrays */ + xassert(delta < INT_MAX - sva->size); + sva->size += delta; + sva->ind = trealloc(sva->ind, 1+sva->size, int); + sva->val = trealloc(sva->val, 1+sva->size, double); + /* relocate the right part in case of positive delta */ + if (delta > 0) + { sva->r_ptr += delta; + memmove(&sva->ind[sva->r_ptr], &sva->ind[r_ptr], + r_size * sizeof(int)); + memmove(&sva->val[sva->r_ptr], &sva->val[r_ptr], + r_size * sizeof(double)); + } + /* update pointers to vectors stored in the right part */ + for (k = 1; k <= n; k++) + { if (ptr[k] >= r_ptr) + ptr[k] += delta; + } +#if 1 + if (sva->talky) + xprintf("now sva->size = %d\n", sva->size); +#endif + return; +} + +/*********************************************************************** +* sva_defrag_area - defragment left part of SVA +* +* This routine performs "garbage" collection to defragment the left +* part of SVA. +* +* NOTE: This operation may change ptr[k] and cap[k] for all vectors +* stored in the left part of SVA. */ + +void sva_defrag_area(SVA *sva) +{ int *ptr = sva->ptr; + int *len = sva->len; + int *cap = sva->cap; + int *prev = sva->prev; + int *next = sva->next; + int *ind = sva->ind; + double *val = sva->val; + int k, next_k, ptr_k, len_k, m_ptr, head, tail; +#if 1 + if (sva->talky) + { xprintf("sva_defrag_area:\n"); + xprintf("before defragmenting = %d %d %d\n", sva->m_ptr - 1, + sva->r_ptr - sva->m_ptr, sva->size + 1 - sva->r_ptr); + } +#endif + m_ptr = 1; + head = tail = 0; + /* walk through the linked list of vectors stored in the left + * part of SVA */ + for (k = sva->head; k != 0; k = next_k) + { /* save number of next vector in the list */ + next_k = next[k]; + /* determine length of k-th vector */ + len_k = len[k]; + if (len_k == 0) + { /* k-th vector is empty; remove it from the left part */ + ptr[k] = cap[k] = 0; + prev[k] = next[k] = -1; + } + else + { /* determine pointer to first location of k-th vector */ + ptr_k = ptr[k]; + xassert(m_ptr <= ptr_k); + /* relocate k-th vector to the beginning of the left part, + * if necessary */ + if (m_ptr < ptr_k) + { memmove(&ind[m_ptr], &ind[ptr_k], + len_k * sizeof(int)); + memmove(&val[m_ptr], &val[ptr_k], + len_k * sizeof(double)); + ptr[k] = m_ptr; + } + /* remove unused locations from k-th vector */ + cap[k] = len_k; + /* the left part of SVA has been enlarged */ + m_ptr += len_k; + /* add k-th vector to the end of the new linked list */ + prev[k] = tail; + next[k] = 0; + if (head == 0) + head = k; + else + next[tail] = k; + tail = k; + } + } + /* set new pointer to the middle part of SVA */ + xassert(m_ptr <= sva->r_ptr); + sva->m_ptr = m_ptr; + /* set new head and tail of the linked list */ + sva->head = head; + sva->tail = tail; +#if 1 + if (sva->talky) + xprintf("after defragmenting = %d %d %d\n", sva->m_ptr - 1, + sva->r_ptr - sva->m_ptr, sva->size + 1 - sva->r_ptr); +#endif + return; +} + +/*********************************************************************** +* sva_more_space - increase size of middle (free) part of SVA +* +* This routine increases the size of the middle (free) part of the +* sparse vector area (SVA). +* +* The parameter m_size specifies the minimal size, in locations, of +* the middle part to be provided. This new size should be greater than +* the current size of the middle part. +* +* First, the routine defragments the left part of SVA. Then, if the +* size of the left part has not sufficiently increased, the routine +* increases the total size of the SVA storage by reallocating it. */ + +void sva_more_space(SVA *sva, int m_size) +{ int size, delta; +#if 1 + if (sva->talky) + xprintf("sva_more_space: m_size = %d\n", m_size); +#endif + xassert(m_size > sva->r_ptr - sva->m_ptr); + /* defragment the left part */ + sva_defrag_area(sva); + /* set, heuristically, the minimal size of the middle part to be + * not less than the size of the defragmented left part */ + if (m_size < sva->m_ptr - 1) + m_size = sva->m_ptr - 1; + /* if there is still not enough room, increase the total size of + * the SVA storage */ + if (sva->r_ptr - sva->m_ptr < m_size) + { size = sva->size; /* new sva size */ + for (;;) + { delta = size - sva->size; + if (sva->r_ptr - sva->m_ptr + delta >= m_size) + break; + size += size; + xassert(size > 0); + } + sva_resize_area(sva, delta); + xassert(sva->r_ptr - sva->m_ptr >= m_size); + } + return; +} + +/*********************************************************************** +* sva_enlarge_cap - enlarge capacity of specified vector +* +* This routine enlarges the current capacity of the specified vector +* by relocating its content. +* +* The parameter k specifies the reference number of the vector whose +* capacity should be enlarged, 1 <= k <= n. This vector should either +* have zero capacity or be stored in the left (dynamic) part of SVA. +* +* The parameter new_cap specifies the new capacity of the vector, +* in locations. This new capacity should be greater than the current +* capacity of the vector. +* +* The parameter skip is a flag. If this flag is set, the routine does +* *not* copy numerical values of elements of the vector on relocating +* its content, i.e. only element indices are copied. +* +* NOTE: On entry to the routine the middle part of SVA should have at +* least new_cap free locations. */ + +void sva_enlarge_cap(SVA *sva, int k, int new_cap, int skip) +{ int *ptr = sva->ptr; + int *len = sva->len; + int *cap = sva->cap; + int *prev = sva->prev; + int *next = sva->next; + int *ind = sva->ind; + double *val = sva->val; + xassert(1 <= k && k <= sva->n); + xassert(new_cap > cap[k]); + /* there should be at least new_cap free locations */ + xassert(sva->r_ptr - sva->m_ptr >= new_cap); + /* relocate the vector */ + if (cap[k] == 0) + { /* the vector is empty */ + xassert(ptr[k] == 0); + xassert(len[k] == 0); + } + else + { /* the vector has non-zero capacity */ + xassert(ptr[k] + len[k] <= sva->m_ptr); + /* copy the current vector content to the beginning of the + * middle part */ + if (len[k] > 0) + { memcpy(&ind[sva->m_ptr], &ind[ptr[k]], + len[k] * sizeof(int)); + if (!skip) + memcpy(&val[sva->m_ptr], &val[ptr[k]], + len[k] * sizeof(double)); + } + /* remove the vector from the linked list */ + if (prev[k] == 0) + sva->head = next[k]; + else + { /* preceding vector exists; increase its capacity */ + cap[prev[k]] += cap[k]; + next[prev[k]] = next[k]; + } + if (next[k] == 0) + sva->tail = prev[k]; + else + prev[next[k]] = prev[k]; + } + /* set new pointer and capacity of the vector */ + ptr[k] = sva->m_ptr; + cap[k] = new_cap; + /* add the vector to the end of the linked list */ + prev[k] = sva->tail; + next[k] = 0; + if (sva->head == 0) + sva->head = k; + else + next[sva->tail] = k; + sva->tail = k; + /* new_cap free locations have been consumed */ + sva->m_ptr += new_cap; + xassert(sva->m_ptr <= sva->r_ptr); + return; +} + +/*********************************************************************** +* sva_reserve_cap - reserve locations for specified vector +* +* This routine reserves locations for the specified vector in the +* right (static) part of SVA. +* +* The parameter k specifies the reference number of the vector (this +* vector should have zero capacity), 1 <= k <= n. +* +* The parameter new_cap specifies a non-zero capacity of the vector, +* in locations. +* +* NOTE: On entry to the routine the middle part of SVA should have at +* least new_cap free locations. */ + +void sva_reserve_cap(SVA *sva, int k, int new_cap) +{ int *ptr = sva->ptr; + int *len = sva->len; + int *cap = sva->cap; + xassert(1 <= k && k <= sva->n); + xassert(new_cap > 0); + xassert(ptr[k] == 0 && len[k] == 0 && cap[k] == 0); + /* there should be at least new_cap free locations */ + xassert(sva->r_ptr - sva->m_ptr >= new_cap); + /* set the pointer and capacity of the vector */ + ptr[k] = sva->r_ptr - new_cap; + cap[k] = new_cap; + /* new_cap free locations have been consumed */ + sva->r_ptr -= new_cap; + return; +} + +/*********************************************************************** +* sva_make_static - relocate specified vector to right part of SVA +* +* Assuming that the specified vector is stored in the left (dynamic) +* part of SVA, this routine makes the vector static by relocating its +* content to the right (static) part of SVA. However, if the specified +* vector has zero capacity, the routine does nothing. +* +* The parameter k specifies the reference number of the vector to be +* relocated, 1 <= k <= n. +* +* NOTE: On entry to the routine the middle part of SVA should have at +* least len[k] free locations, where len[k] is the length of the +* vector to be relocated. */ + +void sva_make_static(SVA *sva, int k) +{ int *ptr = sva->ptr; + int *len = sva->len; + int *cap = sva->cap; + int *prev = sva->prev; + int *next = sva->next; + int *ind = sva->ind; + double *val = sva->val; + int ptr_k, len_k; + xassert(1 <= k && k <= sva->n); + /* if the vector has zero capacity, do nothing */ + if (cap[k] == 0) + { xassert(ptr[k] == 0); + xassert(len[k] == 0); + goto done; + } + /* there should be at least len[k] free locations */ + len_k = len[k]; + xassert(sva->r_ptr - sva->m_ptr >= len_k); + /* remove the vector from the linked list */ + if (prev[k] == 0) + sva->head = next[k]; + else + { /* preceding vector exists; increase its capacity */ + cap[prev[k]] += cap[k]; + next[prev[k]] = next[k]; + } + if (next[k] == 0) + sva->tail = prev[k]; + else + prev[next[k]] = prev[k]; + /* if the vector has zero length, make it empty */ + if (len_k == 0) + { ptr[k] = cap[k] = 0; + goto done; + } + /* copy the vector content to the beginning of the right part */ + ptr_k = sva->r_ptr - len_k; + memcpy(&ind[ptr_k], &ind[ptr[k]], len_k * sizeof(int)); + memcpy(&val[ptr_k], &val[ptr[k]], len_k * sizeof(double)); + /* set new pointer and capacity of the vector */ + ptr[k] = ptr_k; + cap[k] = len_k; + /* len[k] free locations have been consumed */ + sva->r_ptr -= len_k; +done: return; +} + +/*********************************************************************** +* sva_check_area - check sparse vector area (SVA) +* +* This routine checks the SVA data structures for correctness. +* +* NOTE: For testing/debugging only. */ + +void sva_check_area(SVA *sva) +{ int n_max = sva->n_max; + int n = sva->n; + int *ptr = sva->ptr; + int *len = sva->len; + int *cap = sva->cap; + int size = sva->size; + int m_ptr = sva->m_ptr; + int r_ptr = sva->r_ptr; + int head = sva->head; + int tail = sva->tail; + int *prev = sva->prev; + int *next = sva->next; + int k; +#if 0 /* 16/II-2004; SVA may be empty */ + xassert(1 <= n && n <= n_max); +#else + xassert(0 <= n && n <= n_max); +#endif + xassert(1 <= m_ptr && m_ptr <= r_ptr && r_ptr <= size+1); + /* all vectors included the linked list should have non-zero + * capacity and be stored in the left part */ + for (k = head; k != 0; k = next[k]) + { xassert(1 <= k && k <= n); + xassert(cap[k] > 0); + xassert(0 <= len[k] && len[k] <= cap[k]); + if (prev[k] == 0) + xassert(k == head); + else + { xassert(1 <= prev[k] && prev[k] <= n); + xassert(next[prev[k]] == k); + } + if (next[k] == 0) + { xassert(k == tail); + xassert(ptr[k] + cap[k] <= m_ptr); + } + else + { xassert(1 <= next[k] && next[k] <= n); + xassert(prev[next[k]] == k); + xassert(ptr[k] + cap[k] <= ptr[next[k]]); + } + cap[k] = -cap[k]; + } + /* all other vectors should either have zero capacity or be + * stored in the right part */ + for (k = 1; k <= n; k++) + { if (cap[k] < 0) + { /* k-th vector is stored in the left part */ + cap[k] = -cap[k]; + } + else if (cap[k] == 0) + { /* k-th vector has zero capacity */ + xassert(ptr[k] == 0); + xassert(len[k] == 0); + } + else /* cap[k] > 0 */ + { /* k-th vector is stored in the right part */ + xassert(0 <= len[k] && len[k] <= cap[k]); + xassert(r_ptr <= ptr[k] && ptr[k] + cap[k] <= size+1); + } + } + return; +} + +/*********************************************************************** +* sva_delete_area - delete sparse vector area (SVA) +* +* This routine deletes the sparse vector area (SVA) freeing all the +* memory allocated to it. */ + +void sva_delete_area(SVA *sva) +{ tfree(sva->ptr); + tfree(sva->len); + tfree(sva->cap); + tfree(sva->prev); + tfree(sva->next); + tfree(sva->ind); + tfree(sva->val); + tfree(sva); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bflib/sva.h b/resources/3rdparty/glpk-4.57/src/bflib/sva.h new file mode 100644 index 000000000..0eab317b5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bflib/sva.h @@ -0,0 +1,161 @@ +/* sva.h (sparse vector area) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef SVA_H +#define SVA_H + +/*********************************************************************** +* Sparse Vector Area (SVA) is a container for sparse vectors. This +* program object is used mainly on computing factorization, where the +* sparse vectors are rows and columns of sparse matrices. +* +* The SVA storage is a set of locations numbered 1, 2, ..., size, +* where size is the size of SVA, which is the total number of +* locations currently allocated. Each location is identified by its +* pointer p, 1 <= p <= size, and is the pair (ind[p], val[p]), where +* ind[p] and val[p] are, respectively, the index and value fields used +* to store the index and numeric value of a particular vector element. +* +* Each sparse vector is identified by its reference number k, +* 1 <= k <= n, where n is the total number of vectors currently stored +* in SVA, and defined by the triplet (ptr[k], len[k], cap[k]), where: +* ptr[k] is a pointer to the first location of the vector; len[k] is +* the vector length, which is the number of its non-zero elements, +* len[k] >= 0; and cap[k] is the capacity of the vector, which is the +* total number of adjacent locations allocated to that vector, +* cap[k] >= len[k]. Thus, non-zero elements of k-th vector are stored +* in locations ptr[k], ptr[k]+1, ..., ptr[k]+len[k]-1, and locations +* ptr[k]+len[k], ptr[k]+len[k]+1, ..., ptr[k]+cap[k]-1 are reserved. +* +* The SVA storage is divided into three parts as follows: +* +* Locations 1, 2, ..., m_ptr-1 constitute the left (dynamic) part of +* SVA. This part is used to store vectors, whose capacity may change. +* Note that all vectors stored in the left part are also included in +* a doubly linked list, where they are ordered by increasing their +* pointers ptr[k] (this list is needed for efficient implementation +* of the garbage collector used to defragment the left part of SVA); +* +* Locations m_ptr, m_ptr+1, ..., r_ptr-1 are free and constitute the +* middle (free) part of SVA. +* +* Locations r_ptr, r_ptr+1, ..., size constitute the right (static) +* part of SVA. This part is used to store vectors, whose capacity is +* not changed. */ + +typedef struct SVA SVA; + +struct SVA +{ /* sparse vector area */ + int n_max; + /* maximal value of n (enlarged automatically) */ + int n; + /* number of currently allocated vectors, 0 <= n <= n_max */ + int *ptr; /* int ptr[1+n_max]; */ + /* ptr[0] is not used; + * ptr[k], 1 <= i <= n, is pointer to first location of k-th + * vector in the arrays ind and val */ + int *len; /* int len[1+n_max]; */ + /* len[0] is not used; + * len[k], 1 <= k <= n, is length of k-th vector, len[k] >= 0 */ + int *cap; /* int cap[1+n_max]; */ + /* cap[0] is not used; + * cap[k], 1 <= k <= n, is capacity of k-th vector (the number + * of adjacent locations allocated to it), cap[k] >= len[k] */ + /* NOTE: if cap[k] = 0, then ptr[k] = 0 and len[k] = 0 */ + int size; + /* total number of locations in SVA */ + int m_ptr, r_ptr; + /* partitioning pointers that define the left, middle, and right + * parts of SVA (see above); 1 <= m_ptr <= r_ptr <= size+1 */ + int head; + /* number of first (leftmost) vector in the linked list */ + int tail; + /* number of last (rightmost) vector in the linked list */ + int *prev; /* int prev[1+n_max]; */ + /* prev[0] is not used; + * prev[k] is number of vector which precedes k-th vector in the + * linked list; + * prev[k] < 0 means that k-th vector is not in the list */ + int *next; /* int next[1+n_max]; */ + /* next[0] is not used; + * next[k] is number of vector which succedes k-th vector in the + * linked list; + * next[k] < 0 means that k-th vector is not in the list */ + /* NOTE: only vectors having non-zero capacity and stored in the + * left part of SVA are included in this linked list */ + int *ind; /* int ind[1+size]; */ + /* ind[0] is not used; + * ind[p], 1 <= p <= size, is index field of location p */ + double *val; /* double val[1+size]; */ + /* val[0] is not used; + * val[p], 1 <= p <= size, is value field of location p */ +#if 1 + int talky; + /* option to enable talky mode */ +#endif +}; + +#define sva_create_area _glp_sva_create_area +SVA *sva_create_area(int n_max, int size); +/* create sparse vector area (SVA) */ + +#define sva_alloc_vecs _glp_sva_alloc_vecs +int sva_alloc_vecs(SVA *sva, int nnn); +/* allocate new vectors in SVA */ + +#define sva_resize_area _glp_sva_resize_area +void sva_resize_area(SVA *sva, int delta); +/* change size of SVA storage */ + +#define sva_defrag_area _glp_sva_defrag_area +void sva_defrag_area(SVA *sva); +/* defragment left part of SVA */ + +#define sva_more_space _glp_sva_more_space +void sva_more_space(SVA *sva, int m_size); +/* increase size of middle (free) part of SVA */ + +#define sva_enlarge_cap _glp_sva_enlarge_cap +void sva_enlarge_cap(SVA *sva, int k, int new_cap, int skip); +/* enlarge capacity of specified vector */ + +#define sva_reserve_cap _glp_sva_reserve_cap +void sva_reserve_cap(SVA *sva, int k, int new_cap); +/* reserve locations for specified vector */ + +#define sva_make_static _glp_sva_make_static +void sva_make_static(SVA *sva, int k); +/* relocate specified vector to right part of SVA */ + +#define sva_check_area _glp_sva_check_area +void sva_check_area(SVA *sva); +/* check sparse vector area (SVA) */ + +#define sva_delete_area _glp_sva_delete_area +void sva_delete_area(SVA *sva); +/* delete sparse vector area (SVA) */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bfx.c b/resources/3rdparty/glpk-4.57/src/bfx.c new file mode 100644 index 000000000..565480b6f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bfx.c @@ -0,0 +1,89 @@ +/* bfx.c (LP basis factorization driver, rational arithmetic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "bfx.h" +#include "env.h" +#include "lux.h" + +struct BFX +{ int valid; + LUX *lux; +}; + +BFX *bfx_create_binv(void) +{ /* create factorization of the basis matrix */ + BFX *bfx; + bfx = xmalloc(sizeof(BFX)); + bfx->valid = 0; + bfx->lux = NULL; + return bfx; +} + +int bfx_factorize(BFX *binv, int m, int (*col)(void *info, int j, + int ind[], mpq_t val[]), void *info) +{ /* compute factorization of the basis matrix */ + int ret; + xassert(m > 0); + if (binv->lux != NULL && binv->lux->n != m) + { lux_delete(binv->lux); + binv->lux = NULL; + } + if (binv->lux == NULL) + binv->lux = lux_create(m); + ret = lux_decomp(binv->lux, col, info); + binv->valid = (ret == 0); + return ret; +} + +void bfx_ftran(BFX *binv, mpq_t x[], int save) +{ /* perform forward transformation (FTRAN) */ + xassert(binv->valid); + lux_solve(binv->lux, 0, x); + xassert(save == save); + return; +} + +void bfx_btran(BFX *binv, mpq_t x[]) +{ /* perform backward transformation (BTRAN) */ + xassert(binv->valid); + lux_solve(binv->lux, 1, x); + return; +} + +int bfx_update(BFX *binv, int j) +{ /* update factorization of the basis matrix */ + xassert(binv->valid); + xassert(1 <= j && j <= binv->lux->n); + return 1; +} + +void bfx_delete_binv(BFX *binv) +{ /* delete factorization of the basis matrix */ + if (binv->lux != NULL) + lux_delete(binv->lux); + xfree(binv); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/bfx.h b/resources/3rdparty/glpk-4.57/src/bfx.h new file mode 100644 index 000000000..7d0aedaad --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/bfx.h @@ -0,0 +1,67 @@ +/* bfx.h (LP basis factorization driver, rational arithmetic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef BFX_H +#define BFX_H + +#include "glpgmp.h" + +typedef struct BFX BFX; + +#define bfx_create_binv _glp_bfx_create_binv +BFX *bfx_create_binv(void); +/* create factorization of the basis matrix */ + +#define bfx_is_valid _glp_bfx_is_valid +int bfx_is_valid(BFX *binv); +/* check if factorization is valid */ + +#define bfx_invalidate _glp_bfx_invalidate +void bfx_invalidate(BFX *binv); +/* invalidate factorization of the basis matrix */ + +#define bfx_factorize _glp_bfx_factorize +int bfx_factorize(BFX *binv, int m, int (*col)(void *info, int j, + int ind[], mpq_t val[]), void *info); +/* compute factorization of the basis matrix */ + +#define bfx_ftran _glp_bfx_ftran +void bfx_ftran(BFX *binv, mpq_t x[], int save); +/* perform forward transformation (FTRAN) */ + +#define bfx_btran _glp_bfx_btran +void bfx_btran(BFX *binv, mpq_t x[]); +/* perform backward transformation (BTRAN) */ + +#define bfx_update _glp_bfx_update +int bfx_update(BFX *binv, int j); +/* update factorization of the basis matrix */ + +#define bfx_delete_binv _glp_bfx_delete_binv +void bfx_delete_binv(BFX *binv); +/* delete factorization of the basis matrix */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/cglib/cfg.c b/resources/3rdparty/glpk-4.57/src/cglib/cfg.c new file mode 100644 index 000000000..ab73b2da1 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/cglib/cfg.c @@ -0,0 +1,409 @@ +/* cfg.c (conflict graph) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "cfg.h" +#include "env.h" + +/*********************************************************************** +* cfg_create_graph - create conflict graph +* +* This routine creates the conflict graph, which initially is empty, +* and returns a pointer to the graph descriptor. +* +* The parameter n specifies the number of *all* variables in MIP, for +* which the conflict graph will be built. +* +* The parameter nv_max specifies maximal number of vertices in the +* conflict graph. It should be the double number of binary variables +* in corresponding MIP. */ + +CFG *cfg_create_graph(int n, int nv_max) +{ CFG *G; + xassert(n >= 0); + xassert(0 <= nv_max && nv_max <= n + n); + G = talloc(1, CFG); + G->n = n; + G->pos = talloc(1+n, int); + memset(&G->pos[1], 0, n * sizeof(int)); + G->neg = talloc(1+n, int); + memset(&G->neg[1], 0, n * sizeof(int)); + G->pool = dmp_create_pool(); + G->nv_max = nv_max; + G->nv = 0; + G->ref = talloc(1+nv_max, int); + G->vptr = talloc(1+nv_max, CFGVLE *); + G->cptr = talloc(1+nv_max, CFGCLE *); + return G; +} + +/*********************************************************************** +* cfg_add_clique - add clique to conflict graph +* +* This routine adds a clique to the conflict graph. +* +* The parameter size specifies the clique size, size >= 2. Note that +* any edge can be considered as a clique of size 2. +* +* The array ind specifies vertices constituting the clique in elements +* ind[k], 1 <= k <= size: +* +* ind[k] = +j means a vertex of the conflict graph that corresponds to +* original binary variable x[j], 1 <= j <= n. +* +* ind[k] = -j means a vertex of the conflict graph that corresponds to +* complement of original binary variable x[j], 1 <= j <= n. +* +* Note that if both vertices for x[j] and (1 - x[j]) have appeared in +* the conflict graph, the routine automatically adds an edge incident +* to these vertices. */ + +static void add_edge(CFG *G, int v, int w) +{ /* add clique of size 2 */ + DMP *pool = G->pool; + int nv = G->nv; + CFGVLE **vptr = G->vptr; + CFGVLE *vle; + xassert(1 <= v && v <= nv); + xassert(1 <= w && w <= nv); + xassert(v != w); + vle = dmp_talloc(pool, CFGVLE); + vle->v = w; + vle->next = vptr[v]; + vptr[v] = vle; + vle = dmp_talloc(pool, CFGVLE); + vle->v = v; + vle->next = vptr[w]; + vptr[w] = vle; + return; +} + +void cfg_add_clique(CFG *G, int size, const int ind[]) +{ int n = G->n; + int *pos = G->pos; + int *neg = G->neg; + DMP *pool = G->pool; + int nv_max = G->nv_max; + int *ref = G->ref; + CFGVLE **vptr = G->vptr; + CFGCLE **cptr = G->cptr; + int j, k, v; + xassert(2 <= size && size <= nv_max); + /* add new vertices to the conflict graph */ + for (k = 1; k <= size; k++) + { j = ind[k]; + if (j > 0) + { /* vertex corresponds to x[j] */ + xassert(1 <= j && j <= n); + if (pos[j] == 0) + { /* no such vertex exists; add it */ + v = pos[j] = ++(G->nv); + xassert(v <= nv_max); + ref[v] = j; + vptr[v] = NULL; + cptr[v] = NULL; + if (neg[j] != 0) + { /* now both vertices for x[j] and (1 - x[j]) exist */ + add_edge(G, v, neg[j]); + } + } + } + else + { /* vertex corresponds to (1 - x[j]) */ + j = -j; + xassert(1 <= j && j <= n); + if (neg[j] == 0) + { /* no such vertex exists; add it */ + v = neg[j] = ++(G->nv); + xassert(v <= nv_max); + ref[v] = j; + vptr[v] = NULL; + cptr[v] = NULL; + if (pos[j] != 0) + { /* now both vertices for x[j] and (1 - x[j]) exist */ + add_edge(G, v, pos[j]); + } + } + } + } + /* add specified clique to the conflict graph */ + if (size == 2) + add_edge(G, + ind[1] > 0 ? pos[+ind[1]] : neg[-ind[1]], + ind[2] > 0 ? pos[+ind[2]] : neg[-ind[2]]); + else + { CFGVLE *vp, *vle; + CFGCLE *cle; + /* build list of clique vertices */ + vp = NULL; + for (k = 1; k <= size; k++) + { vle = dmp_talloc(pool, CFGVLE); + vle->v = ind[k] > 0 ? pos[+ind[k]] : neg[-ind[k]]; + vle->next = vp; + vp = vle; + } + /* attach the clique to all its vertices */ + for (k = 1; k <= size; k++) + { cle = dmp_talloc(pool, CFGCLE); + cle->vptr = vp; + v = ind[k] > 0 ? pos[+ind[k]] : neg[-ind[k]]; + cle->next = cptr[v]; + cptr[v] = cle; + } + } + return; +} + +/*********************************************************************** +* cfg_get_adjacent - get vertices adjacent to specified vertex +* +* This routine stores numbers of all vertices adjacent to specified +* vertex v of the conflict graph in locations ind[1], ..., ind[len], +* and returns len, 1 <= len <= nv-1, where nv is the total number of +* vertices in the conflict graph. +* +* Note that the conflict graph defined by this routine has neither +* self-loops nor multiple edges. */ + +int cfg_get_adjacent(CFG *G, int v, int ind[]) +{ int nv = G->nv; + int *ref = G->ref; + CFGVLE **vptr = G->vptr; + CFGCLE **cptr = G->cptr; + CFGVLE *vle; + CFGCLE *cle; + int k, w, len; + xassert(1 <= v && v <= nv); + len = 0; + /* walk thru the list of adjacent vertices */ + for (vle = vptr[v]; vle != NULL; vle = vle->next) + { w = vle->v; + xassert(1 <= w && w <= nv); + xassert(w != v); + if (ref[w] > 0) + { ind[++len] = w; + ref[w] = -ref[w]; + } + } + /* walk thru the list of incident cliques */ + for (cle = cptr[v]; cle != NULL; cle = cle->next) + { /* walk thru the list of clique vertices */ + for (vle = cle->vptr; vle != NULL; vle = vle->next) + { w = vle->v; + xassert(1 <= w && w <= nv); + if (w != v && ref[w] > 0) + { ind[++len] = w; + ref[w] = -ref[w]; + } + } + } + xassert(1 <= len && len < nv); + /* unmark vertices included in the resultant adjacency list */ + for (k = 1; k <= len; k++) + { w = ind[k]; + ref[w] = -ref[w]; + } + return len; +} + +/*********************************************************************** +* cfg_expand_clique - expand specified clique to maximal clique +* +* Given some clique in the conflict graph this routine expands it to +* a maximal clique by including in it new vertices. +* +* On entry vertex indices constituting the initial clique should be +* stored in locations c_ind[1], ..., c_ind[c_len], where c_len is the +* initial clique size. On exit the routine stores new vertex indices +* to locations c_ind[c_len+1], ..., c_ind[c_len'], where c_len' is the +* size of the maximal clique found, and returns c_len'. +* +* ALGORITHM +* +* Let G = (V, E) be a graph, C within V be a current clique to be +* expanded, and D within V \ C be a subset of vertices adjacent to all +* vertices from C. On every iteration the routine chooses some vertex +* v in D, includes it into C, and removes from D the vertex v as well +* as all vertices not adjacent to v. Initially C is empty and D = V. +* Iterations repeat until D becomes an empty set. Obviously, the final +* set C is a maximal clique in G. +* +* Now let C0 be an initial clique, and we want C0 to be a subset of +* the final maximal clique C. To provide this condition the routine +* starts constructing C by choosing only such vertices v in D, which +* are in C0, until all vertices from C0 have been included in C. May +* note that if on some iteration C0 \ C is non-empty (i.e. if not all +* vertices from C0 have been included in C), C0 \ C is a subset of D, +* because C0 is a clique. */ + +static int intersection(int d_len, int d_ind[], int d_pos[], int len, + const int ind[]) +{ /* compute intersection D := D inter W, where W is some specified + * set of vertices */ + int k, t, v, new_len; + /* walk thru vertices in W and mark vertices in D */ + for (t = 1; t <= len; t++) + { /* v in W */ + v = ind[t]; + /* determine position of v in D */ + k = d_pos[v]; + if (k != 0) + { /* v in D */ + xassert(d_ind[k] == v); + /* mark v to keep it in D */ + d_ind[k] = -v; + } + } + /* remove all unmarked vertices from D */ + new_len = 0; + for (k = 1; k <= d_len; k++) + { /* v in D */ + v = d_ind[k]; + if (v < 0) + { /* v is marked; keep it */ + v = -v; + new_len++; + d_ind[new_len] = v; + d_pos[v] = new_len; + } + else + { /* v is not marked; remove it */ + d_pos[v] = 0; + } + } + return new_len; +} + +int cfg_expand_clique(CFG *G, int c_len, int c_ind[]) +{ int nv = G->nv; + int d_len, *d_ind, *d_pos, len, *ind; + int k, v; + xassert(0 <= c_len && c_len <= nv); + /* allocate working arrays */ + d_ind = talloc(1+nv, int); + d_pos = talloc(1+nv, int); + ind = talloc(1+nv, int); + /* initialize C := 0, D := V */ + d_len = nv; + for (k = 1; k <= nv; k++) + d_ind[k] = d_pos[k] = k; + /* expand C by vertices of specified initial clique C0 */ + for (k = 1; k <= c_len; k++) + { /* v in C0 */ + v = c_ind[k]; + xassert(1 <= v && v <= nv); + /* since C0 is clique, v should be in D */ + xassert(d_pos[v] != 0); + /* W := set of vertices adjacent to v */ + len = cfg_get_adjacent(G, v, ind); + /* D := D inter W */ + d_len = intersection(d_len, d_ind, d_pos, len, ind); + /* since v not in W, now v should be not in D */ + xassert(d_pos[v] == 0); + } + /* expand C by some other vertices until D is empty */ + while (d_len > 0) + { /* v in D */ + v = d_ind[1]; + xassert(1 <= v && v <= nv); + /* note that v is adjacent to all vertices in C (by design), + * so add v to C */ + c_ind[++c_len] = v; + /* W := set of vertices adjacent to v */ + len = cfg_get_adjacent(G, v, ind); + /* D := D inter W */ + d_len = intersection(d_len, d_ind, d_pos, len, ind); + /* since v not in W, now v should be not in D */ + xassert(d_pos[v] == 0); + } + /* free working arrays */ + tfree(d_ind); + tfree(d_pos); + tfree(ind); + /* bring maximal clique to calling routine */ + return c_len; +} + +/*********************************************************************** +* cfg_check_clique - check clique in conflict graph +* +* This routine checks that vertices of the conflict graph specified +* in locations c_ind[1], ..., c_ind[c_len] constitute a clique. +* +* NOTE: for testing/debugging only. */ + +void cfg_check_clique(CFG *G, int c_len, const int c_ind[]) +{ int nv = G->nv; + int k, kk, v, w, len, *ind; + char *flag; + ind = talloc(1+nv, int); + flag = talloc(1+nv, char); + memset(&flag[1], 0, nv); + /* walk thru clique vertices */ + xassert(c_len >= 0); + for (k = 1; k <= c_len; k++) + { /* get clique vertex v */ + v = c_ind[k]; + xassert(1 <= v && v <= nv); + /* get vertices adjacent to vertex v */ + len = cfg_get_adjacent(G, v, ind); + for (kk = 1; kk <= len; kk++) + { w = ind[kk]; + xassert(1 <= w && w <= nv); + xassert(w != v); + flag[w] = 1; + } + /* check that all clique vertices other than v are adjacent + to v */ + for (kk = 1; kk <= c_len; kk++) + { w = c_ind[kk]; + xassert(1 <= w && w <= nv); + if (w != v) + xassert(flag[w]); + } + /* reset vertex flags */ + for (kk = 1; kk <= len; kk++) + flag[ind[kk]] = 0; + } + tfree(ind); + tfree(flag); + return; +} + +/*********************************************************************** +* cfg_delete_graph - delete conflict graph +* +* This routine deletes the conflict graph by freeing all the memory +* allocated to this program object. */ + +void cfg_delete_graph(CFG *G) +{ tfree(G->pos); + tfree(G->neg); + dmp_delete_pool(G->pool); + tfree(G->ref); + tfree(G->vptr); + tfree(G->cptr); + tfree(G); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/cglib/cfg.h b/resources/3rdparty/glpk-4.57/src/cglib/cfg.h new file mode 100644 index 000000000..bbf2454ca --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/cglib/cfg.h @@ -0,0 +1,130 @@ +/* cfg.h (conflict graph) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef CFG_H +#define CFG_H + +#include "dmp.h" + +/*********************************************************************** +* The structure CFG describes the conflict graph. +* +* Conflict graph is an undirected graph G = (V, E), where V is a set +* of vertices, E <= V x V is a set of edges. Each vertex v in V of the +* conflict graph corresponds to a binary variable z[v], which is +* either an original binary variable x[j] or its complement 1 - x[j]. +* Edge (v,w) in E means that z[v] and z[w] cannot take the value 1 at +* the same time, i.e. it defines an inequality z[v] + z[w] <= 1, which +* is assumed to be valid for original MIP. +* +* Since the conflict graph may be dense, it is stored as an union of +* its cliques rather than explicitly. */ + +typedef struct CFG CFG; +typedef struct CFGVLE CFGVLE; +typedef struct CFGCLE CFGCLE; + +struct CFG +{ /* conflict graph descriptor */ + int n; + /* number of *all* variables (columns) in corresponding MIP */ + int *pos; /* int pos[1+n]; */ + /* pos[0] is not used; + * pos[j] = v, 1 <= j <= n, means that vertex v corresponds to + * original binary variable x[j], and pos[j] = 0 means that the + * conflict graph has no such vertex */ + int *neg; /* int neg[1+n]; */ + /* neg[0] is not used; + * neg[j] = v, 1 <= j <= n, means that vertex v corresponds to + * complement of original binary variable x[j], and neg[j] = 0 + * means that the conflict graph has no such vertex */ + DMP *pool; + /* memory pool to allocate elements of the conflict graph */ + int nv_max; + /* maximal number of vertices in the conflict graph */ + int nv; + /* current number of vertices in the conflict graph */ + int *ref; /* int ref[1+nv_max]; */ + /* ref[v] = j, 1 <= v <= nv, means that vertex v corresponds + * either to original binary variable x[j] or to its complement, + * i.e. either pos[j] = v or neg[j] = v */ + CFGVLE **vptr; /* CFGVLE *vptr[1+nv_max]; */ + /* vptr[v], 1 <= v <= nv, is an initial pointer to the list of + * vertices adjacent to vertex v */ + CFGCLE **cptr; /* CFGCLE *cptr[1+nv_max]; */ + /* cptr[v], 1 <= v <= nv, is an initial pointer to the list of + * cliques that contain vertex v */ +}; + +struct CFGVLE +{ /* vertex list element */ + int v; + /* vertex number, 1 <= v <= nv */ + CFGVLE *next; + /* pointer to next vertex list element */ +}; + +struct CFGCLE +{ /* clique list element */ + CFGVLE *vptr; + /* initial pointer to the list of clique vertices */ + CFGCLE *next; + /* pointer to next clique list element */ +}; + +#define cfg_create_graph _glp_cfg_create_graph +CFG *cfg_create_graph(int n, int nv_max); +/* create conflict graph */ + +#define cfg_add_clique _glp_cfg_add_clique +void cfg_add_clique(CFG *G, int size, const int ind[]); +/* add clique to conflict graph */ + +#define cfg_get_adjacent _glp_cfg_get_adjacent +int cfg_get_adjacent(CFG *G, int v, int ind[]); +/* get vertices adjacent to specified vertex */ + +#define cfg_expand_clique _glp_cfg_expand_clique +int cfg_expand_clique(CFG *G, int c_len, int c_ind[]); +/* expand specified clique to maximal clique */ + +#define cfg_check_clique _glp_cfg_check_clique +void cfg_check_clique(CFG *G, int c_len, const int c_ind[]); +/* check clique in conflict graph */ + +#define cfg_delete_graph _glp_cfg_delete_graph +void cfg_delete_graph(CFG *G); +/* delete conflict graph */ + +#define cfg_build_graph _glp_cfg_build_graph +CFG *cfg_build_graph(void /* glp_prob */ *P); +/* build conflict graph */ + +#define cfg_find_clique _glp_cfg_find_clique +int cfg_find_clique(void /* glp_prob */ *P, CFG *G, int ind[], + double *sum); +/* find maximum weight clique in conflict graph */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/cglib/cfg1.c b/resources/3rdparty/glpk-4.57/src/cglib/cfg1.c new file mode 100644 index 000000000..0dbfbeb06 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/cglib/cfg1.c @@ -0,0 +1,703 @@ +/* cfg1.c (conflict graph) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "cfg.h" +#include "env.h" +#include "prob.h" +#include "wclique.h" +#include "wclique1.h" + +/*********************************************************************** +* cfg_build_graph - build conflict graph +* +* This routine builds the conflict graph. It analyzes the specified +* problem object to discover original and implied packing inequalities +* and adds corresponding cliques to the conflict graph. +* +* Packing inequality has the form: +* +* sum z[j] <= 1, (1) +* j in J +* +* where z[j] = x[j] or z[j] = 1 - x[j], x[j] is an original binary +* variable. Every packing inequality (1) is equivalent to a set of +* edge inequalities: +* +* z[i] + z[j] <= 1 for all i, j in J, i != j, (2) +* +* and since every edge inequality (2) defines an edge in the conflict +* graph, corresponding packing inequality (1) defines a clique. +* +* To discover packing inequalities the routine analyzes constraints +* of the specified MIP. To simplify the analysis each constraint is +* analyzed separately. The analysis is performed as follows. +* +* Let some original constraint be the following: +* +* L <= sum a[j] x[j] <= U. (3) +* +* To analyze it the routine analyzes two constraints of "not greater +* than" type: +* +* sum (-a[j]) x[j] <= -L, (4) +* +* sum (+a[j]) x[j] <= +U, (5) +* +* which are relaxations of the original constraint (3). (If, however, +* L = -oo, or U = +oo, corresponding constraint being redundant is not +* analyzed.) +* +* Let a constraint of "not greater than" type be the following: +* +* sum a[j] x[j] + sum a[j] x[j] <= b, (6) +* j in J j in J' +* +* where J is a subset of binary variables, J' is a subset of other +* (continues and non-binary integer) variables. The constraint (6) is +* is relaxed as follows, to eliminate non-binary variables: +* +* sum a[j] x[j] <= b - sum a[j] x[j] <= b', (7) +* j in J j in J' +* +* b' = sup(b - sum a[j] x[j]) = +* j in J' +* +* = b - inf(sum a[j] x[j]) = +* +* = b - sum inf(a[j] x[j]) = (8) +* +* = b - sum a[j] inf(x[j]) - sum a[j] sup(x[j]) = +* a[j]>0 a[j]<0 +* +* = b - sum a[j] l[j] - sum a[j] u[j], +* a[j]>0 a[j]<0 +* +* where l[j] and u[j] are, resp., lower and upper bounds of x[j]. +* +* Then the routine transforms the relaxed constraint containing only +* binary variables: +* +* sum a[j] x[j] <= b (9) +* +* to an equivalent 0-1 knapsack constraint as follows: +* +* sum a[j] x[j] + sum a[j] x[j] <= b ==> +* a[j]>0 a[j]<0 +* +* sum a[j] x[j] + sum a[j] (1 - x[j]) <= b ==> +* a[j]>0 a[j]<0 (10) +* +* sum (+a[j]) x[j] + sum (-a[j]) x[j] <= b + sum (-a[j]) ==> +* a[j]>0 a[j]<0 a[j]<0 +* +* sum a'[j] z[j] <= b', +* +* where a'[j] = |a[j]| > 0, and +* +* ( x[j] if a[j] > 0 +* z[j] = < +* ( 1 - x[j] if a[j] < 0 +* +* is a binary variable, which is either original binary variable x[j] +* or its complement. +* +* Finally, the routine analyzes the resultant 0-1 knapsack inequality: +* +* sum a[j] z[j] <= b, (11) +* j in J +* +* where all a[j] are positive, to discover clique inequalities (1), +* which are valid for (11) and therefore valid for (3). (It is assumed +* that the original MIP has been preprocessed, so it is not checked, +* for example, that b > 0 or that a[j] <= b.) +* +* In principle, to discover any edge inequalities valid for (11) it +* is sufficient to check whether a[i] + a[j] > b for all i, j in J, +* i < j. However, this way requires O(|J|^2) checks, so the routine +* analyses (11) in the following way, which is much more efficient in +* many practical cases. +* +* 1. Let a[p] and a[q] be two minimal coefficients: +* +* a[p] = min a[j], (12) +* +* a[q] = min a[j], j != p, (13) +* +* such that +* +* a[p] + a[q] > b. (14) +* +* This means that a[i] + a[j] > b for any i, j in J, i != j, so +* +* z[i] + z[j] <= 1 (15) +* +* are valid for (11) for any i, j in J, i != j. This case means that +* J define a clique in the conflict graph. +* +* 2. Otherwise, let a[p] and [q] be two maximal coefficients: +* +* a[p] = max a[j], (16) +* +* a[q] = max a[j], j != p, (17) +* +* such that +* +* a[p] + a[q] <= b. (18) +* +* This means that a[i] + a[j] <= b for any i, j in J, i != j, so in +* this case no valid edge inequalities for (11) exist. +* +* 3. Otherwise, let all a[j] be ordered by descending their values: +* +* a[1] >= a[2] >= ... >= a[p-1] >= a[p] >= a[p+1] >= ... (19) +* +* where p is such that +* +* a[p-1] + a[p] > b, (20) +* +* a[p] + a[p+1] <= b. (21) +* +* (May note that due to the former two cases in this case we always +* have 2 <= p <= |J|-1.) +* +* Since a[p] and a[p-1] are two minimal coefficients in the set +* J' = {1, ..., p}, J' define a clique in the conflict graph for the +* same reason as in the first case. Similarly, since a[p] and a[p+1] +* are two maximal coefficients in the set J" = {p, ..., |J|}, no edge +* inequalities exist for all i, j in J" for the same reason as in the +* second case. Thus, to discover other edge inequalities (15) valid +* for (11), the routine checks if a[i] + a[j] > b for all i in J', +* j in J", i != j. */ + +#define is_binary(j) \ + (P->col[j]->kind == GLP_IV && P->col[j]->type == GLP_DB && \ + P->col[j]->lb == 0.0 && P->col[j]->ub == 1.0) +/* check if x[j] is binary variable */ + +struct term { int ind; double val; }; +/* term a[j] * z[j] used to sort a[j]'s */ + +static int fcmp(const void *e1, const void *e2) +{ /* auxiliary routine called from qsort */ + const struct term *t1 = e1, *t2 = e2; + if (t1->val > t2->val) + return -1; + else if (t1->val < t2->val) + return +1; + else + return 0; +} + +static void analyze_ineq(glp_prob *P, CFG *G, int len, int ind[], + double val[], double rhs, struct term t[]) +{ /* analyze inequality constraint (6) */ + /* P is the original MIP + * G is the conflict graph to be built + * len is the number of terms in the constraint + * ind[1], ..., ind[len] are indices of variables x[j] + * val[1], ..., val[len] are constraint coefficients a[j] + * rhs is the right-hand side b + * t[1+len] is a working array */ + int j, k, kk, p, q, type, new_len; + /* eliminate non-binary variables; see (7) and (8) */ + new_len = 0; + for (k = 1; k <= len; k++) + { /* get index of variable x[j] */ + j = ind[k]; + if (is_binary(j)) + { /* x[j] remains in relaxed constraint */ + new_len++; + ind[new_len] = j; + val[new_len] = val[k]; + } + else if (val[k] > 0.0) + { /* eliminate non-binary x[j] in case a[j] > 0 */ + /* b := b - a[j] * l[j]; see (8) */ + type = P->col[j]->type; + if (type == GLP_FR || type == GLP_UP) + { /* x[j] has no lower bound */ + goto done; + } + rhs -= val[k] * P->col[j]->lb; + } + else /* val[j] < 0.0 */ + { /* eliminate non-binary x[j] in case a[j] < 0 */ + /* b := b - a[j] * u[j]; see (8) */ + type = P->col[j]->type; + if (type == GLP_FR || type == GLP_LO) + { /* x[j] has no upper bound */ + goto done; + } + rhs -= val[k] * P->col[j]->ub; + } + } + len = new_len; + /* now we have the constraint (9) */ + if (len <= 1) + { /* at least two terms are needed */ + goto done; + } + /* make all constraint coefficients positive; see (10) */ + for (k = 1; k <= len; k++) + { if (val[k] < 0.0) + { /* a[j] < 0; substitute x[j] = 1 - x'[j], where x'[j] is + * a complement binary variable */ + ind[k] = -ind[k]; + val[k] = -val[k]; + rhs += val[k]; + } + } + /* now we have 0-1 knapsack inequality (11) */ + /* increase the right-hand side a bit to avoid false checks due + * to rounding errors */ + rhs += 0.001 * (1.0 + fabs(rhs)); + /*** first case ***/ + /* find two minimal coefficients a[p] and a[q] */ + p = 0; + for (k = 1; k <= len; k++) + { if (p == 0 || val[p] > val[k]) + p = k; + } + q = 0; + for (k = 1; k <= len; k++) + { if (k != p && (q == 0 || val[q] > val[k])) + q = k; + } + xassert(p != 0 && q != 0 && p != q); + /* check condition (14) */ + if (val[p] + val[q] > rhs) + { /* all z[j] define a clique in the conflict graph */ + cfg_add_clique(G, len, ind); + goto done; + } + /*** second case ***/ + /* find two maximal coefficients a[p] and a[q] */ + p = 0; + for (k = 1; k <= len; k++) + { if (p == 0 || val[p] < val[k]) + p = k; + } + q = 0; + for (k = 1; k <= len; k++) + { if (k != p && (q == 0 || val[q] < val[k])) + q = k; + } + xassert(p != 0 && q != 0 && p != q); + /* check condition (18) */ + if (val[p] + val[q] <= rhs) + { /* no valid edge inequalities exist */ + goto done; + } + /*** third case ***/ + xassert(len >= 3); + /* sort terms in descending order of coefficient values */ + for (k = 1; k <= len; k++) + { t[k].ind = ind[k]; + t[k].val = val[k]; + } + qsort(&t[1], len, sizeof(struct term), fcmp); + for (k = 1; k <= len; k++) + { ind[k] = t[k].ind; + val[k] = t[k].val; + } + /* now a[1] >= a[2] >= ... >= a[len-1] >= a[len] */ + /* note that a[1] + a[2] > b and a[len-1] + a[len] <= b due two + * the former two cases */ + xassert(val[1] + val[2] > rhs); + xassert(val[len-1] + val[len] <= rhs); + /* find p according to conditions (20) and (21) */ + for (p = 2; p < len; p++) + { if (val[p] + val[p+1] <= rhs) + break; + } + xassert(p < len); + /* z[1], ..., z[p] define a clique in the conflict graph */ + cfg_add_clique(G, p, ind); + /* discover other edge inequalities */ + for (k = 1; k <= p; k++) + { for (kk = p; kk <= len; kk++) + { if (k != kk && val[k] + val[kk] > rhs) + { int iii[1+2]; + iii[1] = ind[k]; + iii[2] = ind[kk]; + cfg_add_clique(G, 2, iii); + } + } + } +done: return; +} + +CFG *cfg_build_graph(void *P_) +{ glp_prob *P = P_; + int m = P->m; + int n = P->n; + CFG *G; + int i, k, type, len, *ind; + double *val; + struct term *t; + /* create the conflict graph (number of its vertices cannot be + * greater than double number of binary variables) */ + G = cfg_create_graph(n, 2 * glp_get_num_bin(P)); + /* allocate working arrays */ + ind = talloc(1+n, int); + val = talloc(1+n, double); + t = talloc(1+n, struct term); + /* analyze constraints to discover edge inequalities */ + for (i = 1; i <= m; i++) + { type = P->row[i]->type; + if (type == GLP_LO || type == GLP_DB || type == GLP_FX) + { /* i-th row has lower bound */ + /* analyze inequality sum (-a[j]) * x[j] <= -lb */ + len = glp_get_mat_row(P, i, ind, val); + for (k = 1; k <= len; k++) + val[k] = -val[k]; + analyze_ineq(P, G, len, ind, val, -P->row[i]->lb, t); + } + if (type == GLP_UP || type == GLP_DB || type == GLP_FX) + { /* i-th row has upper bound */ + /* analyze inequality sum (+a[j]) * x[j] <= +ub */ + len = glp_get_mat_row(P, i, ind, val); + analyze_ineq(P, G, len, ind, val, +P->row[i]->ub, t); + } + } + /* free working arrays */ + tfree(ind); + tfree(val); + tfree(t); + return G; +} + +/*********************************************************************** +* cfg_find_clique - find maximum weight clique in conflict graph +* +* This routine finds a maximum weight clique in the conflict graph +* G = (V, E), where the weight of vertex v in V is the value of +* corresponding binary variable z (which is either an original binary +* variable or its complement) in the optimal solution to LP relaxation +* provided in the problem object. The goal is to find a clique in G, +* whose weight is greater than 1, in which case corresponding packing +* inequality is violated at the optimal point. +* +* On exit the routine stores vertex indices of the conflict graph +* included in the clique found to locations ind[1], ..., ind[len], and +* returns len, which is the clique size. The clique weight is stored +* in location pointed to by the parameter sum. If no clique has been +* found, the routine returns 0. +* +* Since the conflict graph may have a big number of vertices and be +* quite dense, the routine uses an induced subgraph G' = (V', E'), +* which is constructed as follows: +* +* 1. If the weight of some vertex v in V is zero (close to zero), it +* is not included in V'. Obviously, including in a clique +* zero-weight vertices does not change its weight, so if in G there +* exist a clique of a non-zero weight, in G' exists a clique of the +* same weight. This point is extremely important, because dropping +* out zero-weight vertices can be done without retrieving lists of +* adjacent vertices whose size may be very large. +* +* 2. Cumulative weight of vertex v in V is the sum of the weight of v +* and weights of all vertices in V adjacent to v. Obviously, if +* a clique includes a vertex v, the clique weight cannot be greater +* than the cumulative weight of v. Since we are interested only in +* cliques whose weight is greater than 1, vertices of V, whose +* cumulative weight is not greater than 1, are not included in V'. +* +* May note that in many practical cases the size of the induced +* subgraph G' is much less than the size of the original conflict +* graph G due to many binary variables, whose optimal values are zero +* or close to zero. For example, it may happen that |V| = 100,000 and +* |E| = 1e9 while |V'| = 50 and |E'| = 1000. */ + +struct csa +{ /* common storage area */ + glp_prob *P; + /* original MIP */ + CFG *G; + /* original conflict graph G = (V, E), |V| = nv */ + int *ind; /* int ind[1+nv]; */ + /* working array */ + /*--------------------------------------------------------------*/ + /* induced subgraph G' = (V', E') of original conflict graph */ + int nn; + /* number of vertices in V' */ + int *vtoi; /* int vtoi[1+nv]; */ + /* vtoi[v] = i, 1 <= v <= nv, means that vertex v in V is vertex + * i in V'; vtoi[v] = 0 means that vertex v is not included in + * the subgraph */ + int *itov; /* int itov[1+nv]; */ + /* itov[i] = v, 1 <= i <= nn, means that vertex i in V' is vertex + * v in V */ + double *wgt; /* double wgt[1+nv]; */ + /* wgt[i], 1 <= i <= nn, is a weight of vertex i in V', which is + * the value of corresponding binary variable in optimal solution + * to LP relaxation */ +}; + +static void build_subgraph(struct csa *csa) +{ /* build induced subgraph */ + glp_prob *P = csa->P; + int n = P->n; + CFG *G = csa->G; + int *ind = csa->ind; + int *pos = G->pos; + int *neg = G->neg; + int nv = G->nv; + int *ref = G->ref; + int *vtoi = csa->vtoi; + int *itov = csa->itov; + double *wgt = csa->wgt; + int j, k, v, w, nn, len; + double z, sum; + /* initially induced subgraph is empty */ + nn = 0; + /* walk thru vertices of original conflict graph */ + for (v = 1; v <= nv; v++) + { /* determine value of binary variable z[j] that corresponds to + * vertex v */ + j = ref[v]; + xassert(1 <= j && j <= n); + if (pos[j] == v) + { /* z[j] = x[j], where x[j] is original variable */ + z = P->col[j]->prim; + } + else if (neg[j] == v) + { /* z[j] = 1 - x[j], where x[j] is original variable */ + z = 1.0 - P->col[j]->prim; + } + else + xassert(v != v); + /* if z[j] is close to zero, do not include v in the induced + * subgraph */ + if (z < 0.001) + { vtoi[v] = 0; + continue; + } + /* calculate cumulative weight of vertex v */ + sum = z; + /* walk thru all vertices adjacent to v */ + len = cfg_get_adjacent(G, v, ind); + for (k = 1; k <= len; k++) + { /* there is an edge (v,w) in the conflict graph */ + w = ind[k]; + xassert(w != v); + /* add value of z[j] that corresponds to vertex w */ + j = ref[w]; + xassert(1 <= j && j <= n); + if (pos[j] == w) + sum += P->col[j]->prim; + else if (neg[j] == w) + sum += 1.0 - P->col[j]->prim; + else + xassert(w != w); + } + /* cumulative weight of vertex v is an upper bound of weight + * of any clique containing v; so if it not greater than 1, do + * not include v in the induced subgraph */ + if (sum < 1.010) + { vtoi[v] = 0; + continue; + } + /* include vertex v in the induced subgraph */ + nn++; + vtoi[v] = nn; + itov[nn] = v; + wgt[nn] = z; + } + /* induced subgraph has been built */ + csa->nn = nn; + return; +} + +static int sub_adjacent(struct csa *csa, int i, int adj[]) +{ /* retrieve vertices of induced subgraph adjacent to specified + * vertex */ + CFG *G = csa->G; + int nv = G->nv; + int *ind = csa->ind; + int nn = csa->nn; + int *vtoi = csa->vtoi; + int *itov = csa->itov; + int j, k, v, w, len, len1; + /* determine original vertex v corresponding to vertex i */ + xassert(1 <= i && i <= nn); + v = itov[i]; + /* retrieve vertices adjacent to vertex v in original graph */ + len1 = cfg_get_adjacent(G, v, ind); + /* keep only adjacent vertices which are in induced subgraph and + * change their numbers appropriately */ + len = 0; + for (k = 1; k <= len1; k++) + { /* there exists edge (v, w) in original graph */ + w = ind[k]; + xassert(1 <= w && w <= nv && w != v); + j = vtoi[w]; + if (j != 0) + { /* vertex w is vertex j in induced subgraph */ + xassert(1 <= j && j <= nn && j != i); + adj[++len] = j; + } + } + return len; +} + +static int find_clique(struct csa *csa, int c_ind[]) +{ /* find maximum weight clique in induced subgraph with exact + * Ostergard's algorithm */ + int nn = csa->nn; + double *wgt = csa->wgt; + int i, j, k, p, q, t, ne, nb, len, *iwt, *ind; + unsigned char *a; + xassert(nn >= 2); + /* allocate working array */ + ind = talloc(1+nn, int); + /* calculate the number of elements in lower triangle (without + * diagonal) of adjacency matrix of induced subgraph */ + ne = (nn * (nn - 1)) / 2; + /* calculate the number of bytes needed to store lower triangle + * of adjacency matrix */ + nb = (ne + (CHAR_BIT - 1)) / CHAR_BIT; + /* allocate lower triangle of adjacency matrix */ + a = talloc(nb, unsigned char); + /* fill lower triangle of adjacency matrix */ + memset(a, 0, nb); + for (p = 1; p <= nn; p++) + { /* retrieve vertices adjacent to vertex p */ + len = sub_adjacent(csa, p, ind); + for (k = 1; k <= len; k++) + { /* there exists edge (p, q) in induced subgraph */ + q = ind[k]; + xassert(1 <= q && q <= nn && q != p); + /* determine row and column indices of this edge in lower + * triangle of adjacency matrix */ + if (p > q) + i = p, j = q; + else /* p < q */ + i = q, j = p; + /* set bit a[i,j] to 1, i > j */ + t = ((i - 1) * (i - 2)) / 2 + (j - 1); + a[t / CHAR_BIT] |= + (unsigned char)(1 << ((CHAR_BIT - 1) - t % CHAR_BIT)); + } + } + /* scale vertex weights by 1000 and convert them to integers as + * required by Ostergard's algorithm */ + iwt = ind; + for (i = 1; i <= nn; i++) + { /* it is assumed that 0 <= wgt[i] <= 1 */ + t = (int)(1000.0 * wgt[i] + 0.5); + if (t < 0) + t = 0; + else if (t > 1000) + t = 1000; + iwt[i] = t; + } + /* find maximum weight clique */ + len = wclique(nn, iwt, a, c_ind); + /* free working arrays */ + tfree(ind); + tfree(a); + /* return clique size to calling routine */ + return len; +} + +static int func(void *info, int i, int ind[]) +{ /* auxiliary routine used by routine find_clique1 */ + struct csa *csa = info; + xassert(1 <= i && i <= csa->nn); + return sub_adjacent(csa, i, ind); +} + +static int find_clique1(struct csa *csa, int c_ind[]) +{ /* find maximum weight clique in induced subgraph with greedy + * heuristic */ + int nn = csa->nn; + double *wgt = csa->wgt; + int len; + xassert(nn >= 2); + len = wclique1(nn, wgt, func, csa, c_ind); + /* return clique size to calling routine */ + return len; +} + +int cfg_find_clique(void *P, CFG *G, int ind[], double *sum_) +{ int nv = G->nv; + struct csa csa; + int i, k, len; + double sum; + /* initialize common storage area */ + csa.P = P; + csa.G = G; + csa.ind = talloc(1+nv, int); + csa.nn = -1; + csa.vtoi = talloc(1+nv, int); + csa.itov = talloc(1+nv, int); + csa.wgt = talloc(1+nv, double); + /* build induced subgraph */ + build_subgraph(&csa); +#ifdef GLP_DEBUG + xprintf("nn = %d\n", csa.nn); +#endif + /* if subgraph has less than two vertices, do nothing */ + if (csa.nn < 2) + { len = 0; + sum = 0.0; + goto skip; + } + /* find maximum weight clique in induced subgraph */ +#if 1 /* FIXME */ + if (csa.nn <= 50) +#endif + { /* induced subgraph is small; use exact algorithm */ + len = find_clique(&csa, ind); + } + else + { /* induced subgraph is large; use greedy heuristic */ + len = find_clique1(&csa, ind); + } + /* do not report clique, if it has less than two vertices */ + if (len < 2) + { len = 0; + sum = 0.0; + goto skip; + } + /* convert indices of clique vertices from induced subgraph to + * original conflict graph and compute clique weight */ + sum = 0.0; + for (k = 1; k <= len; k++) + { i = ind[k]; + xassert(1 <= i && i <= csa.nn); + sum += csa.wgt[i]; + ind[k] = csa.itov[i]; + } +skip: /* free working arrays */ + tfree(csa.ind); + tfree(csa.vtoi); + tfree(csa.itov); + tfree(csa.wgt); + /* return to calling routine */ + *sum_ = sum; + return len; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/colamd/COPYING b/resources/3rdparty/glpk-4.57/src/colamd/COPYING new file mode 100644 index 000000000..84bba36d0 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/colamd/COPYING @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/resources/3rdparty/glpk-4.57/src/colamd/README b/resources/3rdparty/glpk-4.57/src/colamd/README new file mode 100644 index 000000000..a365059fe --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/colamd/README @@ -0,0 +1,98 @@ +NOTE: Files in this subdirectory are NOT part of the GLPK package, but + are used with GLPK. + + The original code was modified according to GLPK requirements by + Andrew Makhorin . +************************************************************************ +COLAMD/SYMAMD Version 2.7, Copyright (C) 1998-2007, Timothy A. Davis, +All Rights Reserved. + +Description: + + colamd: an approximate minimum degree column ordering algorithm, + for LU factorization of symmetric or unsymmetric matrices, + QR factorization, least squares, interior point methods for + linear programming problems, and other related problems. + + symamd: an approximate minimum degree ordering algorithm for + Cholesky factorization of symmetric matrices. + +Purpose: + + Colamd computes a permutation Q such that the Cholesky factorization + of (AQ)'(AQ) has less fill-in and requires fewer floating point + operations than A'A. This also provides a good ordering for sparse + partial pivoting methods, P(AQ) = LU, where Q is computed prior to + numerical factorization, and P is computed during numerical + factorization via conventional partial pivoting with row + interchanges. Colamd is the column ordering method used in SuperLU, + part of the ScaLAPACK library. It is also available as built-in + function in MATLAB Version 6, available from MathWorks, Inc. + (http://www.mathworks.com). This routine can be used in place of + colmmd in MATLAB. + + Symamd computes a permutation P of a symmetric matrix A such that + the Cholesky factorization of PAP' has less fill-in and requires + fewer floating point operations than A. Symamd constructs a matrix + M such that M'M has the same nonzero pattern of A, and then orders + the columns of M using colmmd. The column ordering of M is then + returned as the row and column ordering P of A. + +Authors: + + The authors of the code itself are Stefan I. Larimore and Timothy A. + Davis (davis at cise.ufl.edu), University of Florida. The algorithm + was developed in collaboration with John Gilbert, Xerox PARC, and + Esmond Ng, Oak Ridge National Laboratory. + +Acknowledgements: + + This work was supported by the National Science Foundation, under + grants DMS-9504974 and DMS-9803599. + +License: + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + USA. + + Permission is hereby granted to use or copy this program under the + terms of the GNU LGPL, provided that the Copyright, this License, + and the Availability of the original version is retained on all + copies. User documentation of any code that uses this code or any + modified version of this code must cite the Copyright, this License, + the Availability note, and "Used by permission." Permission to + modify the code and to distribute modified code is granted, provided + the Copyright, this License, and the Availability note are retained, + and a notice that the code was modified is included. + + COLAMD is also available under alternate licenses, contact T. Davis + for details. + +Availability: + + The colamd/symamd library is available at: + + http://www.cise.ufl.edu/research/sparse/colamd/ + +References: + + T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, An approximate + column minimum degree ordering algorithm, ACM Transactions on + Mathematical Software, vol. 30, no. 3., pp. 353-376, 2004. + + T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, Algorithm 836: + COLAMD, an approximate column minimum degree ordering algorithm, ACM + Transactions on Mathematical Software, vol. 30, no. 3., pp. 377-380, + 2004. diff --git a/resources/3rdparty/glpk-4.57/src/colamd/colamd.c b/resources/3rdparty/glpk-4.57/src/colamd/colamd.c new file mode 100644 index 000000000..86ddd6b74 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/colamd/colamd.c @@ -0,0 +1,3622 @@ +/* ========================================================================== */ +/* === colamd/symamd - a sparse matrix column ordering algorithm ============ */ +/* ========================================================================== */ + +/* COLAMD / SYMAMD + + colamd: an approximate minimum degree column ordering algorithm, + for LU factorization of symmetric or unsymmetric matrices, + QR factorization, least squares, interior point methods for + linear programming problems, and other related problems. + + symamd: an approximate minimum degree ordering algorithm for Cholesky + factorization of symmetric matrices. + + Purpose: + + Colamd computes a permutation Q such that the Cholesky factorization of + (AQ)'(AQ) has less fill-in and requires fewer floating point operations + than A'A. This also provides a good ordering for sparse partial + pivoting methods, P(AQ) = LU, where Q is computed prior to numerical + factorization, and P is computed during numerical factorization via + conventional partial pivoting with row interchanges. Colamd is the + column ordering method used in SuperLU, part of the ScaLAPACK library. + It is also available as built-in function in MATLAB Version 6, + available from MathWorks, Inc. (http://www.mathworks.com). This + routine can be used in place of colmmd in MATLAB. + + Symamd computes a permutation P of a symmetric matrix A such that the + Cholesky factorization of PAP' has less fill-in and requires fewer + floating point operations than A. Symamd constructs a matrix M such + that M'M has the same nonzero pattern of A, and then orders the columns + of M using colmmd. The column ordering of M is then returned as the + row and column ordering P of A. + + Authors: + + The authors of the code itself are Stefan I. Larimore and Timothy A. + Davis (davis at cise.ufl.edu), University of Florida. The algorithm was + developed in collaboration with John Gilbert, Xerox PARC, and Esmond + Ng, Oak Ridge National Laboratory. + + Acknowledgements: + + This work was supported by the National Science Foundation, under + grants DMS-9504974 and DMS-9803599. + + Copyright and License: + + Copyright (c) 1998-2007, Timothy A. Davis, All Rights Reserved. + COLAMD is also available under alternate licenses, contact T. Davis + for details. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + USA + + Permission is hereby granted to use or copy this program under the + terms of the GNU LGPL, provided that the Copyright, this License, + and the Availability of the original version is retained on all copies. + User documentation of any code that uses this code or any modified + version of this code must cite the Copyright, this License, the + Availability note, and "Used by permission." Permission to modify + the code and to distribute modified code is granted, provided the + Copyright, this License, and the Availability note are retained, + and a notice that the code was modified is included. + + Availability: + + The colamd/symamd library is available at + + http://www.cise.ufl.edu/research/sparse/colamd/ + + This is the http://www.cise.ufl.edu/research/sparse/colamd/colamd.c + file. It requires the colamd.h file. It is required by the colamdmex.c + and symamdmex.c files, for the MATLAB interface to colamd and symamd. + Appears as ACM Algorithm 836. + + See the ChangeLog file for changes since Version 1.0. + + References: + + T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, An approximate column + minimum degree ordering algorithm, ACM Transactions on Mathematical + Software, vol. 30, no. 3., pp. 353-376, 2004. + + T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, Algorithm 836: COLAMD, + an approximate column minimum degree ordering algorithm, ACM + Transactions on Mathematical Software, vol. 30, no. 3., pp. 377-380, + 2004. + +*/ + +/* ========================================================================== */ +/* === Description of user-callable routines ================================ */ +/* ========================================================================== */ + +/* COLAMD includes both int and UF_long versions of all its routines. The + * description below is for the int version. For UF_long, all int arguments + * become UF_long. UF_long is normally defined as long, except for WIN64. + + ---------------------------------------------------------------------------- + colamd_recommended: + ---------------------------------------------------------------------------- + + C syntax: + + #include "colamd.h" + size_t colamd_recommended (int nnz, int n_row, int n_col) ; + size_t colamd_l_recommended (UF_long nnz, UF_long n_row, + UF_long n_col) ; + + Purpose: + + Returns recommended value of Alen for use by colamd. Returns 0 + if any input argument is negative. The use of this routine + is optional. Not needed for symamd, which dynamically allocates + its own memory. + + Note that in v2.4 and earlier, these routines returned int or long. + They now return a value of type size_t. + + Arguments (all input arguments): + + int nnz ; Number of nonzeros in the matrix A. This must + be the same value as p [n_col] in the call to + colamd - otherwise you will get a wrong value + of the recommended memory to use. + + int n_row ; Number of rows in the matrix A. + + int n_col ; Number of columns in the matrix A. + + ---------------------------------------------------------------------------- + colamd_set_defaults: + ---------------------------------------------------------------------------- + + C syntax: + + #include "colamd.h" + colamd_set_defaults (double knobs [COLAMD_KNOBS]) ; + colamd_l_set_defaults (double knobs [COLAMD_KNOBS]) ; + + Purpose: + + Sets the default parameters. The use of this routine is optional. + + Arguments: + + double knobs [COLAMD_KNOBS] ; Output only. + + NOTE: the meaning of the dense row/col knobs has changed in v2.4 + + knobs [0] and knobs [1] control dense row and col detection: + + Colamd: rows with more than + max (16, knobs [COLAMD_DENSE_ROW] * sqrt (n_col)) + entries are removed prior to ordering. Columns with more than + max (16, knobs [COLAMD_DENSE_COL] * sqrt (MIN (n_row,n_col))) + entries are removed prior to + ordering, and placed last in the output column ordering. + + Symamd: uses only knobs [COLAMD_DENSE_ROW], which is knobs [0]. + Rows and columns with more than + max (16, knobs [COLAMD_DENSE_ROW] * sqrt (n)) + entries are removed prior to ordering, and placed last in the + output ordering. + + COLAMD_DENSE_ROW and COLAMD_DENSE_COL are defined as 0 and 1, + respectively, in colamd.h. Default values of these two knobs + are both 10. Currently, only knobs [0] and knobs [1] are + used, but future versions may use more knobs. If so, they will + be properly set to their defaults by the future version of + colamd_set_defaults, so that the code that calls colamd will + not need to change, assuming that you either use + colamd_set_defaults, or pass a (double *) NULL pointer as the + knobs array to colamd or symamd. + + knobs [2]: aggressive absorption + + knobs [COLAMD_AGGRESSIVE] controls whether or not to do + aggressive absorption during the ordering. Default is TRUE. + + + ---------------------------------------------------------------------------- + colamd: + ---------------------------------------------------------------------------- + + C syntax: + + #include "colamd.h" + int colamd (int n_row, int n_col, int Alen, int *A, int *p, + double knobs [COLAMD_KNOBS], int stats [COLAMD_STATS]) ; + UF_long colamd_l (UF_long n_row, UF_long n_col, UF_long Alen, + UF_long *A, UF_long *p, double knobs [COLAMD_KNOBS], + UF_long stats [COLAMD_STATS]) ; + + Purpose: + + Computes a column ordering (Q) of A such that P(AQ)=LU or + (AQ)'AQ=LL' have less fill-in and require fewer floating point + operations than factorizing the unpermuted matrix A or A'A, + respectively. + + Returns: + + TRUE (1) if successful, FALSE (0) otherwise. + + Arguments: + + int n_row ; Input argument. + + Number of rows in the matrix A. + Restriction: n_row >= 0. + Colamd returns FALSE if n_row is negative. + + int n_col ; Input argument. + + Number of columns in the matrix A. + Restriction: n_col >= 0. + Colamd returns FALSE if n_col is negative. + + int Alen ; Input argument. + + Restriction (see note): + Alen >= 2*nnz + 6*(n_col+1) + 4*(n_row+1) + n_col + Colamd returns FALSE if these conditions are not met. + + Note: this restriction makes an modest assumption regarding + the size of the two typedef's structures in colamd.h. + We do, however, guarantee that + + Alen >= colamd_recommended (nnz, n_row, n_col) + + will be sufficient. Note: the macro version does not check + for integer overflow, and thus is not recommended. Use + the colamd_recommended routine instead. + + int A [Alen] ; Input argument, undefined on output. + + A is an integer array of size Alen. Alen must be at least as + large as the bare minimum value given above, but this is very + low, and can result in excessive run time. For best + performance, we recommend that Alen be greater than or equal to + colamd_recommended (nnz, n_row, n_col), which adds + nnz/5 to the bare minimum value given above. + + On input, the row indices of the entries in column c of the + matrix are held in A [(p [c]) ... (p [c+1]-1)]. The row indices + in a given column c need not be in ascending order, and + duplicate row indices may be be present. However, colamd will + work a little faster if both of these conditions are met + (Colamd puts the matrix into this format, if it finds that the + the conditions are not met). + + The matrix is 0-based. That is, rows are in the range 0 to + n_row-1, and columns are in the range 0 to n_col-1. Colamd + returns FALSE if any row index is out of range. + + The contents of A are modified during ordering, and are + undefined on output. + + int p [n_col+1] ; Both input and output argument. + + p is an integer array of size n_col+1. On input, it holds the + "pointers" for the column form of the matrix A. Column c of + the matrix A is held in A [(p [c]) ... (p [c+1]-1)]. The first + entry, p [0], must be zero, and p [c] <= p [c+1] must hold + for all c in the range 0 to n_col-1. The value p [n_col] is + thus the total number of entries in the pattern of the matrix A. + Colamd returns FALSE if these conditions are not met. + + On output, if colamd returns TRUE, the array p holds the column + permutation (Q, for P(AQ)=LU or (AQ)'(AQ)=LL'), where p [0] is + the first column index in the new ordering, and p [n_col-1] is + the last. That is, p [k] = j means that column j of A is the + kth pivot column, in AQ, where k is in the range 0 to n_col-1 + (p [0] = j means that column j of A is the first column in AQ). + + If colamd returns FALSE, then no permutation is returned, and + p is undefined on output. + + double knobs [COLAMD_KNOBS] ; Input argument. + + See colamd_set_defaults for a description. + + int stats [COLAMD_STATS] ; Output argument. + + Statistics on the ordering, and error status. + See colamd.h for related definitions. + Colamd returns FALSE if stats is not present. + + stats [0]: number of dense or empty rows ignored. + + stats [1]: number of dense or empty columns ignored (and + ordered last in the output permutation p) + Note that a row can become "empty" if it + contains only "dense" and/or "empty" columns, + and similarly a column can become "empty" if it + only contains "dense" and/or "empty" rows. + + stats [2]: number of garbage collections performed. + This can be excessively high if Alen is close + to the minimum required value. + + stats [3]: status code. < 0 is an error code. + > 1 is a warning or notice. + + 0 OK. Each column of the input matrix contained + row indices in increasing order, with no + duplicates. + + 1 OK, but columns of input matrix were jumbled + (unsorted columns or duplicate entries). Colamd + had to do some extra work to sort the matrix + first and remove duplicate entries, but it + still was able to return a valid permutation + (return value of colamd was TRUE). + + stats [4]: highest numbered column that + is unsorted or has duplicate + entries. + stats [5]: last seen duplicate or + unsorted row index. + stats [6]: number of duplicate or + unsorted row indices. + + -1 A is a null pointer + + -2 p is a null pointer + + -3 n_row is negative + + stats [4]: n_row + + -4 n_col is negative + + stats [4]: n_col + + -5 number of nonzeros in matrix is negative + + stats [4]: number of nonzeros, p [n_col] + + -6 p [0] is nonzero + + stats [4]: p [0] + + -7 A is too small + + stats [4]: required size + stats [5]: actual size (Alen) + + -8 a column has a negative number of entries + + stats [4]: column with < 0 entries + stats [5]: number of entries in col + + -9 a row index is out of bounds + + stats [4]: column with bad row index + stats [5]: bad row index + stats [6]: n_row, # of rows of matrx + + -10 (unused; see symamd.c) + + -999 (unused; see symamd.c) + + Future versions may return more statistics in the stats array. + + Example: + + See http://www.cise.ufl.edu/research/sparse/colamd/example.c + for a complete example. + + To order the columns of a 5-by-4 matrix with 11 nonzero entries in + the following nonzero pattern + + x 0 x 0 + x 0 x x + 0 x x 0 + 0 0 x x + x x 0 0 + + with default knobs and no output statistics, do the following: + + #include "colamd.h" + #define ALEN 100 + int A [ALEN] = {0, 1, 4, 2, 4, 0, 1, 2, 3, 1, 3} ; + int p [ ] = {0, 3, 5, 9, 11} ; + int stats [COLAMD_STATS] ; + colamd (5, 4, ALEN, A, p, (double *) NULL, stats) ; + + The permutation is returned in the array p, and A is destroyed. + + ---------------------------------------------------------------------------- + symamd: + ---------------------------------------------------------------------------- + + C syntax: + + #include "colamd.h" + int symamd (int n, int *A, int *p, int *perm, + double knobs [COLAMD_KNOBS], int stats [COLAMD_STATS], + void (*allocate) (size_t, size_t), void (*release) (void *)) ; + UF_long symamd_l (UF_long n, UF_long *A, UF_long *p, UF_long *perm, + double knobs [COLAMD_KNOBS], UF_long stats [COLAMD_STATS], + void (*allocate) (size_t, size_t), void (*release) (void *)) ; + + Purpose: + + The symamd routine computes an ordering P of a symmetric sparse + matrix A such that the Cholesky factorization PAP' = LL' remains + sparse. It is based on a column ordering of a matrix M constructed + so that the nonzero pattern of M'M is the same as A. The matrix A + is assumed to be symmetric; only the strictly lower triangular part + is accessed. You must pass your selected memory allocator (usually + calloc/free or mxCalloc/mxFree) to symamd, for it to allocate + memory for the temporary matrix M. + + Returns: + + TRUE (1) if successful, FALSE (0) otherwise. + + Arguments: + + int n ; Input argument. + + Number of rows and columns in the symmetrix matrix A. + Restriction: n >= 0. + Symamd returns FALSE if n is negative. + + int A [nnz] ; Input argument. + + A is an integer array of size nnz, where nnz = p [n]. + + The row indices of the entries in column c of the matrix are + held in A [(p [c]) ... (p [c+1]-1)]. The row indices in a + given column c need not be in ascending order, and duplicate + row indices may be present. However, symamd will run faster + if the columns are in sorted order with no duplicate entries. + + The matrix is 0-based. That is, rows are in the range 0 to + n-1, and columns are in the range 0 to n-1. Symamd + returns FALSE if any row index is out of range. + + The contents of A are not modified. + + int p [n+1] ; Input argument. + + p is an integer array of size n+1. On input, it holds the + "pointers" for the column form of the matrix A. Column c of + the matrix A is held in A [(p [c]) ... (p [c+1]-1)]. The first + entry, p [0], must be zero, and p [c] <= p [c+1] must hold + for all c in the range 0 to n-1. The value p [n] is + thus the total number of entries in the pattern of the matrix A. + Symamd returns FALSE if these conditions are not met. + + The contents of p are not modified. + + int perm [n+1] ; Output argument. + + On output, if symamd returns TRUE, the array perm holds the + permutation P, where perm [0] is the first index in the new + ordering, and perm [n-1] is the last. That is, perm [k] = j + means that row and column j of A is the kth column in PAP', + where k is in the range 0 to n-1 (perm [0] = j means + that row and column j of A are the first row and column in + PAP'). The array is used as a workspace during the ordering, + which is why it must be of length n+1, not just n. + + double knobs [COLAMD_KNOBS] ; Input argument. + + See colamd_set_defaults for a description. + + int stats [COLAMD_STATS] ; Output argument. + + Statistics on the ordering, and error status. + See colamd.h for related definitions. + Symamd returns FALSE if stats is not present. + + stats [0]: number of dense or empty row and columns ignored + (and ordered last in the output permutation + perm). Note that a row/column can become + "empty" if it contains only "dense" and/or + "empty" columns/rows. + + stats [1]: (same as stats [0]) + + stats [2]: number of garbage collections performed. + + stats [3]: status code. < 0 is an error code. + > 1 is a warning or notice. + + 0 OK. Each column of the input matrix contained + row indices in increasing order, with no + duplicates. + + 1 OK, but columns of input matrix were jumbled + (unsorted columns or duplicate entries). Symamd + had to do some extra work to sort the matrix + first and remove duplicate entries, but it + still was able to return a valid permutation + (return value of symamd was TRUE). + + stats [4]: highest numbered column that + is unsorted or has duplicate + entries. + stats [5]: last seen duplicate or + unsorted row index. + stats [6]: number of duplicate or + unsorted row indices. + + -1 A is a null pointer + + -2 p is a null pointer + + -3 (unused, see colamd.c) + + -4 n is negative + + stats [4]: n + + -5 number of nonzeros in matrix is negative + + stats [4]: # of nonzeros (p [n]). + + -6 p [0] is nonzero + + stats [4]: p [0] + + -7 (unused) + + -8 a column has a negative number of entries + + stats [4]: column with < 0 entries + stats [5]: number of entries in col + + -9 a row index is out of bounds + + stats [4]: column with bad row index + stats [5]: bad row index + stats [6]: n_row, # of rows of matrx + + -10 out of memory (unable to allocate temporary + workspace for M or count arrays using the + "allocate" routine passed into symamd). + + Future versions may return more statistics in the stats array. + + void * (*allocate) (size_t, size_t) + + A pointer to a function providing memory allocation. The + allocated memory must be returned initialized to zero. For a + C application, this argument should normally be a pointer to + calloc. For a MATLAB mexFunction, the routine mxCalloc is + passed instead. + + void (*release) (size_t, size_t) + + A pointer to a function that frees memory allocated by the + memory allocation routine above. For a C application, this + argument should normally be a pointer to free. For a MATLAB + mexFunction, the routine mxFree is passed instead. + + + ---------------------------------------------------------------------------- + colamd_report: + ---------------------------------------------------------------------------- + + C syntax: + + #include "colamd.h" + colamd_report (int stats [COLAMD_STATS]) ; + colamd_l_report (UF_long stats [COLAMD_STATS]) ; + + Purpose: + + Prints the error status and statistics recorded in the stats + array on the standard error output (for a standard C routine) + or on the MATLAB output (for a mexFunction). + + Arguments: + + int stats [COLAMD_STATS] ; Input only. Statistics from colamd. + + + ---------------------------------------------------------------------------- + symamd_report: + ---------------------------------------------------------------------------- + + C syntax: + + #include "colamd.h" + symamd_report (int stats [COLAMD_STATS]) ; + symamd_l_report (UF_long stats [COLAMD_STATS]) ; + + Purpose: + + Prints the error status and statistics recorded in the stats + array on the standard error output (for a standard C routine) + or on the MATLAB output (for a mexFunction). + + Arguments: + + int stats [COLAMD_STATS] ; Input only. Statistics from symamd. + + +*/ + +/* ========================================================================== */ +/* === Scaffolding code definitions ======================================== */ +/* ========================================================================== */ + +/* Ensure that debugging is turned off: */ +#ifndef NDEBUG +#define NDEBUG +#endif + +/* turn on debugging by uncommenting the following line + #undef NDEBUG +*/ + +/* + Our "scaffolding code" philosophy: In our opinion, well-written library + code should keep its "debugging" code, and just normally have it turned off + by the compiler so as not to interfere with performance. This serves + several purposes: + + (1) assertions act as comments to the reader, telling you what the code + expects at that point. All assertions will always be true (unless + there really is a bug, of course). + + (2) leaving in the scaffolding code assists anyone who would like to modify + the code, or understand the algorithm (by reading the debugging output, + one can get a glimpse into what the code is doing). + + (3) (gasp!) for actually finding bugs. This code has been heavily tested + and "should" be fully functional and bug-free ... but you never know... + + The code will become outrageously slow when debugging is + enabled. To control the level of debugging output, set an environment + variable D to 0 (little), 1 (some), 2, 3, or 4 (lots). When debugging, + you should see the following message on the standard output: + + colamd: debug version, D = 1 (THIS WILL BE SLOW!) + + or a similar message for symamd. If you don't, then debugging has not + been enabled. + +*/ + +/* ========================================================================== */ +/* === Include files ======================================================== */ +/* ========================================================================== */ + +#include "colamd.h" + +#if 0 /* by mao */ +#include +#include + +#ifdef MATLAB_MEX_FILE +#include "mex.h" +#include "matrix.h" +#endif /* MATLAB_MEX_FILE */ + +#if !defined (NPRINT) || !defined (NDEBUG) +#include +#endif + +#ifndef NULL +#define NULL ((void *) 0) +#endif +#endif + +/* ========================================================================== */ +/* === int or UF_long ======================================================= */ +/* ========================================================================== */ + +#if 0 /* by mao */ +/* define UF_long */ +#include "UFconfig.h" +#endif + +#ifdef DLONG + +#define Int UF_long +#define ID UF_long_id +#define Int_MAX UF_long_max + +#define COLAMD_recommended colamd_l_recommended +#define COLAMD_set_defaults colamd_l_set_defaults +#define COLAMD_MAIN colamd_l +#define SYMAMD_MAIN symamd_l +#define COLAMD_report colamd_l_report +#define SYMAMD_report symamd_l_report + +#else + +#define Int int +#define ID "%d" +#define Int_MAX INT_MAX + +#define COLAMD_recommended colamd_recommended +#define COLAMD_set_defaults colamd_set_defaults +#define COLAMD_MAIN colamd +#define SYMAMD_MAIN symamd +#define COLAMD_report colamd_report +#define SYMAMD_report symamd_report + +#endif + +/* ========================================================================== */ +/* === Row and Column structures ============================================ */ +/* ========================================================================== */ + +/* User code that makes use of the colamd/symamd routines need not directly */ +/* reference these structures. They are used only for colamd_recommended. */ + +typedef struct Colamd_Col_struct +{ + Int start ; /* index for A of first row in this column, or DEAD */ + /* if column is dead */ + Int length ; /* number of rows in this column */ + union + { + Int thickness ; /* number of original columns represented by this */ + /* col, if the column is alive */ + Int parent ; /* parent in parent tree super-column structure, if */ + /* the column is dead */ + } shared1 ; + union + { + Int score ; /* the score used to maintain heap, if col is alive */ + Int order ; /* pivot ordering of this column, if col is dead */ + } shared2 ; + union + { + Int headhash ; /* head of a hash bucket, if col is at the head of */ + /* a degree list */ + Int hash ; /* hash value, if col is not in a degree list */ + Int prev ; /* previous column in degree list, if col is in a */ + /* degree list (but not at the head of a degree list) */ + } shared3 ; + union + { + Int degree_next ; /* next column, if col is in a degree list */ + Int hash_next ; /* next column, if col is in a hash list */ + } shared4 ; + +} Colamd_Col ; + +typedef struct Colamd_Row_struct +{ + Int start ; /* index for A of first col in this row */ + Int length ; /* number of principal columns in this row */ + union + { + Int degree ; /* number of principal & non-principal columns in row */ + Int p ; /* used as a row pointer in init_rows_cols () */ + } shared1 ; + union + { + Int mark ; /* for computing set differences and marking dead rows*/ + Int first_column ;/* first column in row (used in garbage collection) */ + } shared2 ; + +} Colamd_Row ; + +/* ========================================================================== */ +/* === Definitions ========================================================== */ +/* ========================================================================== */ + +/* Routines are either PUBLIC (user-callable) or PRIVATE (not user-callable) */ +#define PUBLIC +#define PRIVATE static + +#define DENSE_DEGREE(alpha,n) \ + ((Int) MAX (16.0, (alpha) * sqrt ((double) (n)))) + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +#define ONES_COMPLEMENT(r) (-(r)-1) + +/* -------------------------------------------------------------------------- */ +/* Change for version 2.1: define TRUE and FALSE only if not yet defined */ +/* -------------------------------------------------------------------------- */ + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +/* -------------------------------------------------------------------------- */ + +#define EMPTY (-1) + +/* Row and column status */ +#define ALIVE (0) +#define DEAD (-1) + +/* Column status */ +#define DEAD_PRINCIPAL (-1) +#define DEAD_NON_PRINCIPAL (-2) + +/* Macros for row and column status update and checking. */ +#define ROW_IS_DEAD(r) ROW_IS_MARKED_DEAD (Row[r].shared2.mark) +#define ROW_IS_MARKED_DEAD(row_mark) (row_mark < ALIVE) +#define ROW_IS_ALIVE(r) (Row [r].shared2.mark >= ALIVE) +#define COL_IS_DEAD(c) (Col [c].start < ALIVE) +#define COL_IS_ALIVE(c) (Col [c].start >= ALIVE) +#define COL_IS_DEAD_PRINCIPAL(c) (Col [c].start == DEAD_PRINCIPAL) +#define KILL_ROW(r) { Row [r].shared2.mark = DEAD ; } +#define KILL_PRINCIPAL_COL(c) { Col [c].start = DEAD_PRINCIPAL ; } +#define KILL_NON_PRINCIPAL_COL(c) { Col [c].start = DEAD_NON_PRINCIPAL ; } + +/* ========================================================================== */ +/* === Colamd reporting mechanism =========================================== */ +/* ========================================================================== */ + +#if defined (MATLAB_MEX_FILE) || defined (MATHWORKS) +/* In MATLAB, matrices are 1-based to the user, but 0-based internally */ +#define INDEX(i) ((i)+1) +#else +/* In C, matrices are 0-based and indices are reported as such in *_report */ +#define INDEX(i) (i) +#endif + +/* All output goes through the PRINTF macro. */ +#define PRINTF(params) { if (colamd_printf != NULL) (void) colamd_printf params ; } + +/* ========================================================================== */ +/* === Prototypes of PRIVATE routines ======================================= */ +/* ========================================================================== */ + +PRIVATE Int init_rows_cols +( + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [], + Int p [], + Int stats [COLAMD_STATS] +) ; + +PRIVATE void init_scoring +( + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [], + Int head [], + double knobs [COLAMD_KNOBS], + Int *p_n_row2, + Int *p_n_col2, + Int *p_max_deg +) ; + +PRIVATE Int find_ordering +( + Int n_row, + Int n_col, + Int Alen, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [], + Int head [], + Int n_col2, + Int max_deg, + Int pfree, + Int aggressive +) ; + +PRIVATE void order_children +( + Int n_col, + Colamd_Col Col [], + Int p [] +) ; + +PRIVATE void detect_super_cols +( + +#ifndef NDEBUG + Int n_col, + Colamd_Row Row [], +#endif /* NDEBUG */ + + Colamd_Col Col [], + Int A [], + Int head [], + Int row_start, + Int row_length +) ; + +PRIVATE Int garbage_collection +( + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [], + Int *pfree +) ; + +PRIVATE Int clear_mark +( + Int tag_mark, + Int max_mark, + Int n_row, + Colamd_Row Row [] +) ; + +PRIVATE void print_report +( + char *method, + Int stats [COLAMD_STATS] +) ; + +/* ========================================================================== */ +/* === Debugging prototypes and definitions ================================= */ +/* ========================================================================== */ + +#ifndef NDEBUG + +#if 0 /* by mao */ +#include +#endif + +/* colamd_debug is the *ONLY* global variable, and is only */ +/* present when debugging */ + +PRIVATE Int colamd_debug = 0 ; /* debug print level */ + +#define DEBUG0(params) { PRINTF (params) ; } +#define DEBUG1(params) { if (colamd_debug >= 1) PRINTF (params) ; } +#define DEBUG2(params) { if (colamd_debug >= 2) PRINTF (params) ; } +#define DEBUG3(params) { if (colamd_debug >= 3) PRINTF (params) ; } +#define DEBUG4(params) { if (colamd_debug >= 4) PRINTF (params) ; } + +#if 0 /* by mao */ +#ifdef MATLAB_MEX_FILE +#define ASSERT(expression) (mxAssert ((expression), "")) +#else +#define ASSERT(expression) (assert (expression)) +#endif /* MATLAB_MEX_FILE */ +#else +#define ASSERT xassert +#endif + +PRIVATE void colamd_get_debug /* gets the debug print level from getenv */ +( + char *method +) ; + +PRIVATE void debug_deg_lists +( + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int head [], + Int min_score, + Int should, + Int max_deg +) ; + +PRIVATE void debug_mark +( + Int n_row, + Colamd_Row Row [], + Int tag_mark, + Int max_mark +) ; + +PRIVATE void debug_matrix +( + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [] +) ; + +PRIVATE void debug_structures +( + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [], + Int n_col2 +) ; + +#else /* NDEBUG */ + +/* === No debugging ========================================================= */ + +#define DEBUG0(params) ; +#define DEBUG1(params) ; +#define DEBUG2(params) ; +#define DEBUG3(params) ; +#define DEBUG4(params) ; + +#define ASSERT(expression) + +#endif /* NDEBUG */ + +/* ========================================================================== */ +/* === USER-CALLABLE ROUTINES: ============================================== */ +/* ========================================================================== */ + +/* ========================================================================== */ +/* === colamd_recommended =================================================== */ +/* ========================================================================== */ + +/* + The colamd_recommended routine returns the suggested size for Alen. This + value has been determined to provide good balance between the number of + garbage collections and the memory requirements for colamd. If any + argument is negative, or if integer overflow occurs, a 0 is returned as an + error condition. 2*nnz space is required for the row and column + indices of the matrix. COLAMD_C (n_col) + COLAMD_R (n_row) space is + required for the Col and Row arrays, respectively, which are internal to + colamd (roughly 6*n_col + 4*n_row). An additional n_col space is the + minimal amount of "elbow room", and nnz/5 more space is recommended for + run time efficiency. + + Alen is approximately 2.2*nnz + 7*n_col + 4*n_row + 10. + + This function is not needed when using symamd. +*/ + +/* add two values of type size_t, and check for integer overflow */ +static size_t t_add (size_t a, size_t b, int *ok) +{ + (*ok) = (*ok) && ((a + b) >= MAX (a,b)) ; + return ((*ok) ? (a + b) : 0) ; +} + +/* compute a*k where k is a small integer, and check for integer overflow */ +static size_t t_mult (size_t a, size_t k, int *ok) +{ + size_t i, s = 0 ; + for (i = 0 ; i < k ; i++) + { + s = t_add (s, a, ok) ; + } + return (s) ; +} + +/* size of the Col and Row structures */ +#define COLAMD_C(n_col,ok) \ + ((t_mult (t_add (n_col, 1, ok), sizeof (Colamd_Col), ok) / sizeof (Int))) + +#define COLAMD_R(n_row,ok) \ + ((t_mult (t_add (n_row, 1, ok), sizeof (Colamd_Row), ok) / sizeof (Int))) + + +PUBLIC size_t COLAMD_recommended /* returns recommended value of Alen. */ +( + /* === Parameters ======================================================= */ + + Int nnz, /* number of nonzeros in A */ + Int n_row, /* number of rows in A */ + Int n_col /* number of columns in A */ +) +{ + size_t s, c, r ; + int ok = TRUE ; + if (nnz < 0 || n_row < 0 || n_col < 0) + { + return (0) ; + } + s = t_mult (nnz, 2, &ok) ; /* 2*nnz */ + c = COLAMD_C (n_col, &ok) ; /* size of column structures */ + r = COLAMD_R (n_row, &ok) ; /* size of row structures */ + s = t_add (s, c, &ok) ; + s = t_add (s, r, &ok) ; + s = t_add (s, n_col, &ok) ; /* elbow room */ + s = t_add (s, nnz/5, &ok) ; /* elbow room */ + ok = ok && (s < Int_MAX) ; + return (ok ? s : 0) ; +} + + +/* ========================================================================== */ +/* === colamd_set_defaults ================================================== */ +/* ========================================================================== */ + +/* + The colamd_set_defaults routine sets the default values of the user- + controllable parameters for colamd and symamd: + + Colamd: rows with more than max (16, knobs [0] * sqrt (n_col)) + entries are removed prior to ordering. Columns with more than + max (16, knobs [1] * sqrt (MIN (n_row,n_col))) entries are removed + prior to ordering, and placed last in the output column ordering. + + Symamd: Rows and columns with more than max (16, knobs [0] * sqrt (n)) + entries are removed prior to ordering, and placed last in the + output ordering. + + knobs [0] dense row control + + knobs [1] dense column control + + knobs [2] if nonzero, do aggresive absorption + + knobs [3..19] unused, but future versions might use this + +*/ + +PUBLIC void COLAMD_set_defaults +( + /* === Parameters ======================================================= */ + + double knobs [COLAMD_KNOBS] /* knob array */ +) +{ + /* === Local variables ================================================== */ + + Int i ; + + if (!knobs) + { + return ; /* no knobs to initialize */ + } + for (i = 0 ; i < COLAMD_KNOBS ; i++) + { + knobs [i] = 0 ; + } + knobs [COLAMD_DENSE_ROW] = 10 ; + knobs [COLAMD_DENSE_COL] = 10 ; + knobs [COLAMD_AGGRESSIVE] = TRUE ; /* default: do aggressive absorption*/ +} + + +/* ========================================================================== */ +/* === symamd =============================================================== */ +/* ========================================================================== */ + +PUBLIC Int SYMAMD_MAIN /* return TRUE if OK, FALSE otherwise */ +( + /* === Parameters ======================================================= */ + + Int n, /* number of rows and columns of A */ + Int A [], /* row indices of A */ + Int p [], /* column pointers of A */ + Int perm [], /* output permutation, size n+1 */ + double knobs [COLAMD_KNOBS], /* parameters (uses defaults if NULL) */ + Int stats [COLAMD_STATS], /* output statistics and error codes */ + void * (*allocate) (size_t, size_t), + /* pointer to calloc (ANSI C) or */ + /* mxCalloc (for MATLAB mexFunction) */ + void (*release) (void *) + /* pointer to free (ANSI C) or */ + /* mxFree (for MATLAB mexFunction) */ +) +{ + /* === Local variables ================================================== */ + + Int *count ; /* length of each column of M, and col pointer*/ + Int *mark ; /* mark array for finding duplicate entries */ + Int *M ; /* row indices of matrix M */ + size_t Mlen ; /* length of M */ + Int n_row ; /* number of rows in M */ + Int nnz ; /* number of entries in A */ + Int i ; /* row index of A */ + Int j ; /* column index of A */ + Int k ; /* row index of M */ + Int mnz ; /* number of nonzeros in M */ + Int pp ; /* index into a column of A */ + Int last_row ; /* last row seen in the current column */ + Int length ; /* number of nonzeros in a column */ + + double cknobs [COLAMD_KNOBS] ; /* knobs for colamd */ + double default_knobs [COLAMD_KNOBS] ; /* default knobs for colamd */ + +#ifndef NDEBUG + colamd_get_debug ("symamd") ; +#endif /* NDEBUG */ + + /* === Check the input arguments ======================================== */ + + if (!stats) + { + DEBUG0 (("symamd: stats not present\n")) ; + return (FALSE) ; + } + for (i = 0 ; i < COLAMD_STATS ; i++) + { + stats [i] = 0 ; + } + stats [COLAMD_STATUS] = COLAMD_OK ; + stats [COLAMD_INFO1] = -1 ; + stats [COLAMD_INFO2] = -1 ; + + if (!A) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_A_not_present ; + DEBUG0 (("symamd: A not present\n")) ; + return (FALSE) ; + } + + if (!p) /* p is not present */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_p_not_present ; + DEBUG0 (("symamd: p not present\n")) ; + return (FALSE) ; + } + + if (n < 0) /* n must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_ncol_negative ; + stats [COLAMD_INFO1] = n ; + DEBUG0 (("symamd: n negative %d\n", n)) ; + return (FALSE) ; + } + + nnz = p [n] ; + if (nnz < 0) /* nnz must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_nnz_negative ; + stats [COLAMD_INFO1] = nnz ; + DEBUG0 (("symamd: number of entries negative %d\n", nnz)) ; + return (FALSE) ; + } + + if (p [0] != 0) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_p0_nonzero ; + stats [COLAMD_INFO1] = p [0] ; + DEBUG0 (("symamd: p[0] not zero %d\n", p [0])) ; + return (FALSE) ; + } + + /* === If no knobs, set default knobs =================================== */ + + if (!knobs) + { + COLAMD_set_defaults (default_knobs) ; + knobs = default_knobs ; + } + + /* === Allocate count and mark ========================================== */ + + count = (Int *) ((*allocate) (n+1, sizeof (Int))) ; + if (!count) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; + DEBUG0 (("symamd: allocate count (size %d) failed\n", n+1)) ; + return (FALSE) ; + } + + mark = (Int *) ((*allocate) (n+1, sizeof (Int))) ; + if (!mark) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; + (*release) ((void *) count) ; + DEBUG0 (("symamd: allocate mark (size %d) failed\n", n+1)) ; + return (FALSE) ; + } + + /* === Compute column counts of M, check if A is valid ================== */ + + stats [COLAMD_INFO3] = 0 ; /* number of duplicate or unsorted row indices*/ + + for (i = 0 ; i < n ; i++) + { + mark [i] = -1 ; + } + + for (j = 0 ; j < n ; j++) + { + last_row = -1 ; + + length = p [j+1] - p [j] ; + if (length < 0) + { + /* column pointers must be non-decreasing */ + stats [COLAMD_STATUS] = COLAMD_ERROR_col_length_negative ; + stats [COLAMD_INFO1] = j ; + stats [COLAMD_INFO2] = length ; + (*release) ((void *) count) ; + (*release) ((void *) mark) ; + DEBUG0 (("symamd: col %d negative length %d\n", j, length)) ; + return (FALSE) ; + } + + for (pp = p [j] ; pp < p [j+1] ; pp++) + { + i = A [pp] ; + if (i < 0 || i >= n) + { + /* row index i, in column j, is out of bounds */ + stats [COLAMD_STATUS] = COLAMD_ERROR_row_index_out_of_bounds ; + stats [COLAMD_INFO1] = j ; + stats [COLAMD_INFO2] = i ; + stats [COLAMD_INFO3] = n ; + (*release) ((void *) count) ; + (*release) ((void *) mark) ; + DEBUG0 (("symamd: row %d col %d out of bounds\n", i, j)) ; + return (FALSE) ; + } + + if (i <= last_row || mark [i] == j) + { + /* row index is unsorted or repeated (or both), thus col */ + /* is jumbled. This is a notice, not an error condition. */ + stats [COLAMD_STATUS] = COLAMD_OK_BUT_JUMBLED ; + stats [COLAMD_INFO1] = j ; + stats [COLAMD_INFO2] = i ; + (stats [COLAMD_INFO3]) ++ ; + DEBUG1 (("symamd: row %d col %d unsorted/duplicate\n", i, j)) ; + } + + if (i > j && mark [i] != j) + { + /* row k of M will contain column indices i and j */ + count [i]++ ; + count [j]++ ; + } + + /* mark the row as having been seen in this column */ + mark [i] = j ; + + last_row = i ; + } + } + + /* v2.4: removed free(mark) */ + + /* === Compute column pointers of M ===================================== */ + + /* use output permutation, perm, for column pointers of M */ + perm [0] = 0 ; + for (j = 1 ; j <= n ; j++) + { + perm [j] = perm [j-1] + count [j-1] ; + } + for (j = 0 ; j < n ; j++) + { + count [j] = perm [j] ; + } + + /* === Construct M ====================================================== */ + + mnz = perm [n] ; + n_row = mnz / 2 ; + Mlen = COLAMD_recommended (mnz, n_row, n) ; + M = (Int *) ((*allocate) (Mlen, sizeof (Int))) ; + DEBUG0 (("symamd: M is %d-by-%d with %d entries, Mlen = %g\n", + n_row, n, mnz, (double) Mlen)) ; + + if (!M) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; + (*release) ((void *) count) ; + (*release) ((void *) mark) ; + DEBUG0 (("symamd: allocate M (size %g) failed\n", (double) Mlen)) ; + return (FALSE) ; + } + + k = 0 ; + + if (stats [COLAMD_STATUS] == COLAMD_OK) + { + /* Matrix is OK */ + for (j = 0 ; j < n ; j++) + { + ASSERT (p [j+1] - p [j] >= 0) ; + for (pp = p [j] ; pp < p [j+1] ; pp++) + { + i = A [pp] ; + ASSERT (i >= 0 && i < n) ; + if (i > j) + { + /* row k of M contains column indices i and j */ + M [count [i]++] = k ; + M [count [j]++] = k ; + k++ ; + } + } + } + } + else + { + /* Matrix is jumbled. Do not add duplicates to M. Unsorted cols OK. */ + DEBUG0 (("symamd: Duplicates in A.\n")) ; + for (i = 0 ; i < n ; i++) + { + mark [i] = -1 ; + } + for (j = 0 ; j < n ; j++) + { + ASSERT (p [j+1] - p [j] >= 0) ; + for (pp = p [j] ; pp < p [j+1] ; pp++) + { + i = A [pp] ; + ASSERT (i >= 0 && i < n) ; + if (i > j && mark [i] != j) + { + /* row k of M contains column indices i and j */ + M [count [i]++] = k ; + M [count [j]++] = k ; + k++ ; + mark [i] = j ; + } + } + } + /* v2.4: free(mark) moved below */ + } + + /* count and mark no longer needed */ + (*release) ((void *) count) ; + (*release) ((void *) mark) ; /* v2.4: free (mark) moved here */ + ASSERT (k == n_row) ; + + /* === Adjust the knobs for M =========================================== */ + + for (i = 0 ; i < COLAMD_KNOBS ; i++) + { + cknobs [i] = knobs [i] ; + } + + /* there are no dense rows in M */ + cknobs [COLAMD_DENSE_ROW] = -1 ; + cknobs [COLAMD_DENSE_COL] = knobs [COLAMD_DENSE_ROW] ; + + /* === Order the columns of M =========================================== */ + + /* v2.4: colamd cannot fail here, so the error check is removed */ + (void) COLAMD_MAIN (n_row, n, (Int) Mlen, M, perm, cknobs, stats) ; + + /* Note that the output permutation is now in perm */ + + /* === get the statistics for symamd from colamd ======================== */ + + /* a dense column in colamd means a dense row and col in symamd */ + stats [COLAMD_DENSE_ROW] = stats [COLAMD_DENSE_COL] ; + + /* === Free M =========================================================== */ + + (*release) ((void *) M) ; + DEBUG0 (("symamd: done.\n")) ; + return (TRUE) ; + +} + +/* ========================================================================== */ +/* === colamd =============================================================== */ +/* ========================================================================== */ + +/* + The colamd routine computes a column ordering Q of a sparse matrix + A such that the LU factorization P(AQ) = LU remains sparse, where P is + selected via partial pivoting. The routine can also be viewed as + providing a permutation Q such that the Cholesky factorization + (AQ)'(AQ) = LL' remains sparse. +*/ + +PUBLIC Int COLAMD_MAIN /* returns TRUE if successful, FALSE otherwise*/ +( + /* === Parameters ======================================================= */ + + Int n_row, /* number of rows in A */ + Int n_col, /* number of columns in A */ + Int Alen, /* length of A */ + Int A [], /* row indices of A */ + Int p [], /* pointers to columns in A */ + double knobs [COLAMD_KNOBS],/* parameters (uses defaults if NULL) */ + Int stats [COLAMD_STATS] /* output statistics and error codes */ +) +{ + /* === Local variables ================================================== */ + + Int i ; /* loop index */ + Int nnz ; /* nonzeros in A */ + size_t Row_size ; /* size of Row [], in integers */ + size_t Col_size ; /* size of Col [], in integers */ + size_t need ; /* minimum required length of A */ + Colamd_Row *Row ; /* pointer into A of Row [0..n_row] array */ + Colamd_Col *Col ; /* pointer into A of Col [0..n_col] array */ + Int n_col2 ; /* number of non-dense, non-empty columns */ + Int n_row2 ; /* number of non-dense, non-empty rows */ + Int ngarbage ; /* number of garbage collections performed */ + Int max_deg ; /* maximum row degree */ + double default_knobs [COLAMD_KNOBS] ; /* default knobs array */ + Int aggressive ; /* do aggressive absorption */ + int ok ; + +#ifndef NDEBUG + colamd_get_debug ("colamd") ; +#endif /* NDEBUG */ + + /* === Check the input arguments ======================================== */ + + if (!stats) + { + DEBUG0 (("colamd: stats not present\n")) ; + return (FALSE) ; + } + for (i = 0 ; i < COLAMD_STATS ; i++) + { + stats [i] = 0 ; + } + stats [COLAMD_STATUS] = COLAMD_OK ; + stats [COLAMD_INFO1] = -1 ; + stats [COLAMD_INFO2] = -1 ; + + if (!A) /* A is not present */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_A_not_present ; + DEBUG0 (("colamd: A not present\n")) ; + return (FALSE) ; + } + + if (!p) /* p is not present */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_p_not_present ; + DEBUG0 (("colamd: p not present\n")) ; + return (FALSE) ; + } + + if (n_row < 0) /* n_row must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_nrow_negative ; + stats [COLAMD_INFO1] = n_row ; + DEBUG0 (("colamd: nrow negative %d\n", n_row)) ; + return (FALSE) ; + } + + if (n_col < 0) /* n_col must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_ncol_negative ; + stats [COLAMD_INFO1] = n_col ; + DEBUG0 (("colamd: ncol negative %d\n", n_col)) ; + return (FALSE) ; + } + + nnz = p [n_col] ; + if (nnz < 0) /* nnz must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_nnz_negative ; + stats [COLAMD_INFO1] = nnz ; + DEBUG0 (("colamd: number of entries negative %d\n", nnz)) ; + return (FALSE) ; + } + + if (p [0] != 0) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_p0_nonzero ; + stats [COLAMD_INFO1] = p [0] ; + DEBUG0 (("colamd: p[0] not zero %d\n", p [0])) ; + return (FALSE) ; + } + + /* === If no knobs, set default knobs =================================== */ + + if (!knobs) + { + COLAMD_set_defaults (default_knobs) ; + knobs = default_knobs ; + } + + aggressive = (knobs [COLAMD_AGGRESSIVE] != FALSE) ; + + /* === Allocate the Row and Col arrays from array A ===================== */ + + ok = TRUE ; + Col_size = COLAMD_C (n_col, &ok) ; /* size of Col array of structs */ + Row_size = COLAMD_R (n_row, &ok) ; /* size of Row array of structs */ + + /* need = 2*nnz + n_col + Col_size + Row_size ; */ + need = t_mult (nnz, 2, &ok) ; + need = t_add (need, n_col, &ok) ; + need = t_add (need, Col_size, &ok) ; + need = t_add (need, Row_size, &ok) ; + + if (!ok || need > (size_t) Alen || need > Int_MAX) + { + /* not enough space in array A to perform the ordering */ + stats [COLAMD_STATUS] = COLAMD_ERROR_A_too_small ; + stats [COLAMD_INFO1] = need ; + stats [COLAMD_INFO2] = Alen ; + DEBUG0 (("colamd: Need Alen >= %d, given only Alen = %d\n", need,Alen)); + return (FALSE) ; + } + + Alen -= Col_size + Row_size ; + Col = (Colamd_Col *) &A [Alen] ; + Row = (Colamd_Row *) &A [Alen + Col_size] ; + + /* === Construct the row and column data structures ===================== */ + + if (!init_rows_cols (n_row, n_col, Row, Col, A, p, stats)) + { + /* input matrix is invalid */ + DEBUG0 (("colamd: Matrix invalid\n")) ; + return (FALSE) ; + } + + /* === Initialize scores, kill dense rows/columns ======================= */ + + init_scoring (n_row, n_col, Row, Col, A, p, knobs, + &n_row2, &n_col2, &max_deg) ; + + /* === Order the supercolumns =========================================== */ + + ngarbage = find_ordering (n_row, n_col, Alen, Row, Col, A, p, + n_col2, max_deg, 2*nnz, aggressive) ; + + /* === Order the non-principal columns ================================== */ + + order_children (n_col, Col, p) ; + + /* === Return statistics in stats ======================================= */ + + stats [COLAMD_DENSE_ROW] = n_row - n_row2 ; + stats [COLAMD_DENSE_COL] = n_col - n_col2 ; + stats [COLAMD_DEFRAG_COUNT] = ngarbage ; + DEBUG0 (("colamd: done.\n")) ; + return (TRUE) ; +} + + +/* ========================================================================== */ +/* === colamd_report ======================================================== */ +/* ========================================================================== */ + +PUBLIC void COLAMD_report +( + Int stats [COLAMD_STATS] +) +{ + print_report ("colamd", stats) ; +} + + +/* ========================================================================== */ +/* === symamd_report ======================================================== */ +/* ========================================================================== */ + +PUBLIC void SYMAMD_report +( + Int stats [COLAMD_STATS] +) +{ + print_report ("symamd", stats) ; +} + + + +/* ========================================================================== */ +/* === NON-USER-CALLABLE ROUTINES: ========================================== */ +/* ========================================================================== */ + +/* There are no user-callable routines beyond this point in the file */ + + +/* ========================================================================== */ +/* === init_rows_cols ======================================================= */ +/* ========================================================================== */ + +/* + Takes the column form of the matrix in A and creates the row form of the + matrix. Also, row and column attributes are stored in the Col and Row + structs. If the columns are un-sorted or contain duplicate row indices, + this routine will also sort and remove duplicate row indices from the + column form of the matrix. Returns FALSE if the matrix is invalid, + TRUE otherwise. Not user-callable. +*/ + +PRIVATE Int init_rows_cols /* returns TRUE if OK, or FALSE otherwise */ +( + /* === Parameters ======================================================= */ + + Int n_row, /* number of rows of A */ + Int n_col, /* number of columns of A */ + Colamd_Row Row [], /* of size n_row+1 */ + Colamd_Col Col [], /* of size n_col+1 */ + Int A [], /* row indices of A, of size Alen */ + Int p [], /* pointers to columns in A, of size n_col+1 */ + Int stats [COLAMD_STATS] /* colamd statistics */ +) +{ + /* === Local variables ================================================== */ + + Int col ; /* a column index */ + Int row ; /* a row index */ + Int *cp ; /* a column pointer */ + Int *cp_end ; /* a pointer to the end of a column */ + Int *rp ; /* a row pointer */ + Int *rp_end ; /* a pointer to the end of a row */ + Int last_row ; /* previous row */ + + /* === Initialize columns, and check column pointers ==================== */ + + for (col = 0 ; col < n_col ; col++) + { + Col [col].start = p [col] ; + Col [col].length = p [col+1] - p [col] ; + + if (Col [col].length < 0) + { + /* column pointers must be non-decreasing */ + stats [COLAMD_STATUS] = COLAMD_ERROR_col_length_negative ; + stats [COLAMD_INFO1] = col ; + stats [COLAMD_INFO2] = Col [col].length ; + DEBUG0 (("colamd: col %d length %d < 0\n", col, Col [col].length)) ; + return (FALSE) ; + } + + Col [col].shared1.thickness = 1 ; + Col [col].shared2.score = 0 ; + Col [col].shared3.prev = EMPTY ; + Col [col].shared4.degree_next = EMPTY ; + } + + /* p [0..n_col] no longer needed, used as "head" in subsequent routines */ + + /* === Scan columns, compute row degrees, and check row indices ========= */ + + stats [COLAMD_INFO3] = 0 ; /* number of duplicate or unsorted row indices*/ + + for (row = 0 ; row < n_row ; row++) + { + Row [row].length = 0 ; + Row [row].shared2.mark = -1 ; + } + + for (col = 0 ; col < n_col ; col++) + { + last_row = -1 ; + + cp = &A [p [col]] ; + cp_end = &A [p [col+1]] ; + + while (cp < cp_end) + { + row = *cp++ ; + + /* make sure row indices within range */ + if (row < 0 || row >= n_row) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_row_index_out_of_bounds ; + stats [COLAMD_INFO1] = col ; + stats [COLAMD_INFO2] = row ; + stats [COLAMD_INFO3] = n_row ; + DEBUG0 (("colamd: row %d col %d out of bounds\n", row, col)) ; + return (FALSE) ; + } + + if (row <= last_row || Row [row].shared2.mark == col) + { + /* row index are unsorted or repeated (or both), thus col */ + /* is jumbled. This is a notice, not an error condition. */ + stats [COLAMD_STATUS] = COLAMD_OK_BUT_JUMBLED ; + stats [COLAMD_INFO1] = col ; + stats [COLAMD_INFO2] = row ; + (stats [COLAMD_INFO3]) ++ ; + DEBUG1 (("colamd: row %d col %d unsorted/duplicate\n",row,col)); + } + + if (Row [row].shared2.mark != col) + { + Row [row].length++ ; + } + else + { + /* this is a repeated entry in the column, */ + /* it will be removed */ + Col [col].length-- ; + } + + /* mark the row as having been seen in this column */ + Row [row].shared2.mark = col ; + + last_row = row ; + } + } + + /* === Compute row pointers ============================================= */ + + /* row form of the matrix starts directly after the column */ + /* form of matrix in A */ + Row [0].start = p [n_col] ; + Row [0].shared1.p = Row [0].start ; + Row [0].shared2.mark = -1 ; + for (row = 1 ; row < n_row ; row++) + { + Row [row].start = Row [row-1].start + Row [row-1].length ; + Row [row].shared1.p = Row [row].start ; + Row [row].shared2.mark = -1 ; + } + + /* === Create row form ================================================== */ + + if (stats [COLAMD_STATUS] == COLAMD_OK_BUT_JUMBLED) + { + /* if cols jumbled, watch for repeated row indices */ + for (col = 0 ; col < n_col ; col++) + { + cp = &A [p [col]] ; + cp_end = &A [p [col+1]] ; + while (cp < cp_end) + { + row = *cp++ ; + if (Row [row].shared2.mark != col) + { + A [(Row [row].shared1.p)++] = col ; + Row [row].shared2.mark = col ; + } + } + } + } + else + { + /* if cols not jumbled, we don't need the mark (this is faster) */ + for (col = 0 ; col < n_col ; col++) + { + cp = &A [p [col]] ; + cp_end = &A [p [col+1]] ; + while (cp < cp_end) + { + A [(Row [*cp++].shared1.p)++] = col ; + } + } + } + + /* === Clear the row marks and set row degrees ========================== */ + + for (row = 0 ; row < n_row ; row++) + { + Row [row].shared2.mark = 0 ; + Row [row].shared1.degree = Row [row].length ; + } + + /* === See if we need to re-create columns ============================== */ + + if (stats [COLAMD_STATUS] == COLAMD_OK_BUT_JUMBLED) + { + DEBUG0 (("colamd: reconstructing column form, matrix jumbled\n")) ; + +#ifndef NDEBUG + /* make sure column lengths are correct */ + for (col = 0 ; col < n_col ; col++) + { + p [col] = Col [col].length ; + } + for (row = 0 ; row < n_row ; row++) + { + rp = &A [Row [row].start] ; + rp_end = rp + Row [row].length ; + while (rp < rp_end) + { + p [*rp++]-- ; + } + } + for (col = 0 ; col < n_col ; col++) + { + ASSERT (p [col] == 0) ; + } + /* now p is all zero (different than when debugging is turned off) */ +#endif /* NDEBUG */ + + /* === Compute col pointers ========================================= */ + + /* col form of the matrix starts at A [0]. */ + /* Note, we may have a gap between the col form and the row */ + /* form if there were duplicate entries, if so, it will be */ + /* removed upon the first garbage collection */ + Col [0].start = 0 ; + p [0] = Col [0].start ; + for (col = 1 ; col < n_col ; col++) + { + /* note that the lengths here are for pruned columns, i.e. */ + /* no duplicate row indices will exist for these columns */ + Col [col].start = Col [col-1].start + Col [col-1].length ; + p [col] = Col [col].start ; + } + + /* === Re-create col form =========================================== */ + + for (row = 0 ; row < n_row ; row++) + { + rp = &A [Row [row].start] ; + rp_end = rp + Row [row].length ; + while (rp < rp_end) + { + A [(p [*rp++])++] = row ; + } + } + } + + /* === Done. Matrix is not (or no longer) jumbled ====================== */ + + return (TRUE) ; +} + + +/* ========================================================================== */ +/* === init_scoring ========================================================= */ +/* ========================================================================== */ + +/* + Kills dense or empty columns and rows, calculates an initial score for + each column, and places all columns in the degree lists. Not user-callable. +*/ + +PRIVATE void init_scoring +( + /* === Parameters ======================================================= */ + + Int n_row, /* number of rows of A */ + Int n_col, /* number of columns of A */ + Colamd_Row Row [], /* of size n_row+1 */ + Colamd_Col Col [], /* of size n_col+1 */ + Int A [], /* column form and row form of A */ + Int head [], /* of size n_col+1 */ + double knobs [COLAMD_KNOBS],/* parameters */ + Int *p_n_row2, /* number of non-dense, non-empty rows */ + Int *p_n_col2, /* number of non-dense, non-empty columns */ + Int *p_max_deg /* maximum row degree */ +) +{ + /* === Local variables ================================================== */ + + Int c ; /* a column index */ + Int r, row ; /* a row index */ + Int *cp ; /* a column pointer */ + Int deg ; /* degree of a row or column */ + Int *cp_end ; /* a pointer to the end of a column */ + Int *new_cp ; /* new column pointer */ + Int col_length ; /* length of pruned column */ + Int score ; /* current column score */ + Int n_col2 ; /* number of non-dense, non-empty columns */ + Int n_row2 ; /* number of non-dense, non-empty rows */ + Int dense_row_count ; /* remove rows with more entries than this */ + Int dense_col_count ; /* remove cols with more entries than this */ + Int min_score ; /* smallest column score */ + Int max_deg ; /* maximum row degree */ + Int next_col ; /* Used to add to degree list.*/ + +#ifndef NDEBUG + Int debug_count ; /* debug only. */ +#endif /* NDEBUG */ + + /* === Extract knobs ==================================================== */ + + /* Note: if knobs contains a NaN, this is undefined: */ + if (knobs [COLAMD_DENSE_ROW] < 0) + { + /* only remove completely dense rows */ + dense_row_count = n_col-1 ; + } + else + { + dense_row_count = DENSE_DEGREE (knobs [COLAMD_DENSE_ROW], n_col) ; + } + if (knobs [COLAMD_DENSE_COL] < 0) + { + /* only remove completely dense columns */ + dense_col_count = n_row-1 ; + } + else + { + dense_col_count = + DENSE_DEGREE (knobs [COLAMD_DENSE_COL], MIN (n_row, n_col)) ; + } + + DEBUG1 (("colamd: densecount: %d %d\n", dense_row_count, dense_col_count)) ; + max_deg = 0 ; + n_col2 = n_col ; + n_row2 = n_row ; + + /* === Kill empty columns =============================================== */ + + /* Put the empty columns at the end in their natural order, so that LU */ + /* factorization can proceed as far as possible. */ + for (c = n_col-1 ; c >= 0 ; c--) + { + deg = Col [c].length ; + if (deg == 0) + { + /* this is a empty column, kill and order it last */ + Col [c].shared2.order = --n_col2 ; + KILL_PRINCIPAL_COL (c) ; + } + } + DEBUG1 (("colamd: null columns killed: %d\n", n_col - n_col2)) ; + + /* === Kill dense columns =============================================== */ + + /* Put the dense columns at the end, in their natural order */ + for (c = n_col-1 ; c >= 0 ; c--) + { + /* skip any dead columns */ + if (COL_IS_DEAD (c)) + { + continue ; + } + deg = Col [c].length ; + if (deg > dense_col_count) + { + /* this is a dense column, kill and order it last */ + Col [c].shared2.order = --n_col2 ; + /* decrement the row degrees */ + cp = &A [Col [c].start] ; + cp_end = cp + Col [c].length ; + while (cp < cp_end) + { + Row [*cp++].shared1.degree-- ; + } + KILL_PRINCIPAL_COL (c) ; + } + } + DEBUG1 (("colamd: Dense and null columns killed: %d\n", n_col - n_col2)) ; + + /* === Kill dense and empty rows ======================================== */ + + for (r = 0 ; r < n_row ; r++) + { + deg = Row [r].shared1.degree ; + ASSERT (deg >= 0 && deg <= n_col) ; + if (deg > dense_row_count || deg == 0) + { + /* kill a dense or empty row */ + KILL_ROW (r) ; + --n_row2 ; + } + else + { + /* keep track of max degree of remaining rows */ + max_deg = MAX (max_deg, deg) ; + } + } + DEBUG1 (("colamd: Dense and null rows killed: %d\n", n_row - n_row2)) ; + + /* === Compute initial column scores ==================================== */ + + /* At this point the row degrees are accurate. They reflect the number */ + /* of "live" (non-dense) columns in each row. No empty rows exist. */ + /* Some "live" columns may contain only dead rows, however. These are */ + /* pruned in the code below. */ + + /* now find the initial matlab score for each column */ + for (c = n_col-1 ; c >= 0 ; c--) + { + /* skip dead column */ + if (COL_IS_DEAD (c)) + { + continue ; + } + score = 0 ; + cp = &A [Col [c].start] ; + new_cp = cp ; + cp_end = cp + Col [c].length ; + while (cp < cp_end) + { + /* get a row */ + row = *cp++ ; + /* skip if dead */ + if (ROW_IS_DEAD (row)) + { + continue ; + } + /* compact the column */ + *new_cp++ = row ; + /* add row's external degree */ + score += Row [row].shared1.degree - 1 ; + /* guard against integer overflow */ + score = MIN (score, n_col) ; + } + /* determine pruned column length */ + col_length = (Int) (new_cp - &A [Col [c].start]) ; + if (col_length == 0) + { + /* a newly-made null column (all rows in this col are "dense" */ + /* and have already been killed) */ + DEBUG2 (("Newly null killed: %d\n", c)) ; + Col [c].shared2.order = --n_col2 ; + KILL_PRINCIPAL_COL (c) ; + } + else + { + /* set column length and set score */ + ASSERT (score >= 0) ; + ASSERT (score <= n_col) ; + Col [c].length = col_length ; + Col [c].shared2.score = score ; + } + } + DEBUG1 (("colamd: Dense, null, and newly-null columns killed: %d\n", + n_col-n_col2)) ; + + /* At this point, all empty rows and columns are dead. All live columns */ + /* are "clean" (containing no dead rows) and simplicial (no supercolumns */ + /* yet). Rows may contain dead columns, but all live rows contain at */ + /* least one live column. */ + +#ifndef NDEBUG + debug_structures (n_row, n_col, Row, Col, A, n_col2) ; +#endif /* NDEBUG */ + + /* === Initialize degree lists ========================================== */ + +#ifndef NDEBUG + debug_count = 0 ; +#endif /* NDEBUG */ + + /* clear the hash buckets */ + for (c = 0 ; c <= n_col ; c++) + { + head [c] = EMPTY ; + } + min_score = n_col ; + /* place in reverse order, so low column indices are at the front */ + /* of the lists. This is to encourage natural tie-breaking */ + for (c = n_col-1 ; c >= 0 ; c--) + { + /* only add principal columns to degree lists */ + if (COL_IS_ALIVE (c)) + { + DEBUG4 (("place %d score %d minscore %d ncol %d\n", + c, Col [c].shared2.score, min_score, n_col)) ; + + /* === Add columns score to DList =============================== */ + + score = Col [c].shared2.score ; + + ASSERT (min_score >= 0) ; + ASSERT (min_score <= n_col) ; + ASSERT (score >= 0) ; + ASSERT (score <= n_col) ; + ASSERT (head [score] >= EMPTY) ; + + /* now add this column to dList at proper score location */ + next_col = head [score] ; + Col [c].shared3.prev = EMPTY ; + Col [c].shared4.degree_next = next_col ; + + /* if there already was a column with the same score, set its */ + /* previous pointer to this new column */ + if (next_col != EMPTY) + { + Col [next_col].shared3.prev = c ; + } + head [score] = c ; + + /* see if this score is less than current min */ + min_score = MIN (min_score, score) ; + +#ifndef NDEBUG + debug_count++ ; +#endif /* NDEBUG */ + + } + } + +#ifndef NDEBUG + DEBUG1 (("colamd: Live cols %d out of %d, non-princ: %d\n", + debug_count, n_col, n_col-debug_count)) ; + ASSERT (debug_count == n_col2) ; + debug_deg_lists (n_row, n_col, Row, Col, head, min_score, n_col2, max_deg) ; +#endif /* NDEBUG */ + + /* === Return number of remaining columns, and max row degree =========== */ + + *p_n_col2 = n_col2 ; + *p_n_row2 = n_row2 ; + *p_max_deg = max_deg ; +} + + +/* ========================================================================== */ +/* === find_ordering ======================================================== */ +/* ========================================================================== */ + +/* + Order the principal columns of the supercolumn form of the matrix + (no supercolumns on input). Uses a minimum approximate column minimum + degree ordering method. Not user-callable. +*/ + +PRIVATE Int find_ordering /* return the number of garbage collections */ +( + /* === Parameters ======================================================= */ + + Int n_row, /* number of rows of A */ + Int n_col, /* number of columns of A */ + Int Alen, /* size of A, 2*nnz + n_col or larger */ + Colamd_Row Row [], /* of size n_row+1 */ + Colamd_Col Col [], /* of size n_col+1 */ + Int A [], /* column form and row form of A */ + Int head [], /* of size n_col+1 */ + Int n_col2, /* Remaining columns to order */ + Int max_deg, /* Maximum row degree */ + Int pfree, /* index of first free slot (2*nnz on entry) */ + Int aggressive +) +{ + /* === Local variables ================================================== */ + + Int k ; /* current pivot ordering step */ + Int pivot_col ; /* current pivot column */ + Int *cp ; /* a column pointer */ + Int *rp ; /* a row pointer */ + Int pivot_row ; /* current pivot row */ + Int *new_cp ; /* modified column pointer */ + Int *new_rp ; /* modified row pointer */ + Int pivot_row_start ; /* pointer to start of pivot row */ + Int pivot_row_degree ; /* number of columns in pivot row */ + Int pivot_row_length ; /* number of supercolumns in pivot row */ + Int pivot_col_score ; /* score of pivot column */ + Int needed_memory ; /* free space needed for pivot row */ + Int *cp_end ; /* pointer to the end of a column */ + Int *rp_end ; /* pointer to the end of a row */ + Int row ; /* a row index */ + Int col ; /* a column index */ + Int max_score ; /* maximum possible score */ + Int cur_score ; /* score of current column */ + unsigned Int hash ; /* hash value for supernode detection */ + Int head_column ; /* head of hash bucket */ + Int first_col ; /* first column in hash bucket */ + Int tag_mark ; /* marker value for mark array */ + Int row_mark ; /* Row [row].shared2.mark */ + Int set_difference ; /* set difference size of row with pivot row */ + Int min_score ; /* smallest column score */ + Int col_thickness ; /* "thickness" (no. of columns in a supercol) */ + Int max_mark ; /* maximum value of tag_mark */ + Int pivot_col_thickness ; /* number of columns represented by pivot col */ + Int prev_col ; /* Used by Dlist operations. */ + Int next_col ; /* Used by Dlist operations. */ + Int ngarbage ; /* number of garbage collections performed */ + +#ifndef NDEBUG + Int debug_d ; /* debug loop counter */ + Int debug_step = 0 ; /* debug loop counter */ +#endif /* NDEBUG */ + + /* === Initialization and clear mark ==================================== */ + + max_mark = INT_MAX - n_col ; /* INT_MAX defined in */ + tag_mark = clear_mark (0, max_mark, n_row, Row) ; + min_score = 0 ; + ngarbage = 0 ; + DEBUG1 (("colamd: Ordering, n_col2=%d\n", n_col2)) ; + + /* === Order the columns ================================================ */ + + for (k = 0 ; k < n_col2 ; /* 'k' is incremented below */) + { + +#ifndef NDEBUG + if (debug_step % 100 == 0) + { + DEBUG2 (("\n... Step k: %d out of n_col2: %d\n", k, n_col2)) ; + } + else + { + DEBUG3 (("\n----------Step k: %d out of n_col2: %d\n", k, n_col2)) ; + } + debug_step++ ; + debug_deg_lists (n_row, n_col, Row, Col, head, + min_score, n_col2-k, max_deg) ; + debug_matrix (n_row, n_col, Row, Col, A) ; +#endif /* NDEBUG */ + + /* === Select pivot column, and order it ============================ */ + + /* make sure degree list isn't empty */ + ASSERT (min_score >= 0) ; + ASSERT (min_score <= n_col) ; + ASSERT (head [min_score] >= EMPTY) ; + +#ifndef NDEBUG + for (debug_d = 0 ; debug_d < min_score ; debug_d++) + { + ASSERT (head [debug_d] == EMPTY) ; + } +#endif /* NDEBUG */ + + /* get pivot column from head of minimum degree list */ + while (head [min_score] == EMPTY && min_score < n_col) + { + min_score++ ; + } + pivot_col = head [min_score] ; + ASSERT (pivot_col >= 0 && pivot_col <= n_col) ; + next_col = Col [pivot_col].shared4.degree_next ; + head [min_score] = next_col ; + if (next_col != EMPTY) + { + Col [next_col].shared3.prev = EMPTY ; + } + + ASSERT (COL_IS_ALIVE (pivot_col)) ; + + /* remember score for defrag check */ + pivot_col_score = Col [pivot_col].shared2.score ; + + /* the pivot column is the kth column in the pivot order */ + Col [pivot_col].shared2.order = k ; + + /* increment order count by column thickness */ + pivot_col_thickness = Col [pivot_col].shared1.thickness ; + k += pivot_col_thickness ; + ASSERT (pivot_col_thickness > 0) ; + DEBUG3 (("Pivot col: %d thick %d\n", pivot_col, pivot_col_thickness)) ; + + /* === Garbage_collection, if necessary ============================= */ + + needed_memory = MIN (pivot_col_score, n_col - k) ; + if (pfree + needed_memory >= Alen) + { + pfree = garbage_collection (n_row, n_col, Row, Col, A, &A [pfree]) ; + ngarbage++ ; + /* after garbage collection we will have enough */ + ASSERT (pfree + needed_memory < Alen) ; + /* garbage collection has wiped out the Row[].shared2.mark array */ + tag_mark = clear_mark (0, max_mark, n_row, Row) ; + +#ifndef NDEBUG + debug_matrix (n_row, n_col, Row, Col, A) ; +#endif /* NDEBUG */ + } + + /* === Compute pivot row pattern ==================================== */ + + /* get starting location for this new merged row */ + pivot_row_start = pfree ; + + /* initialize new row counts to zero */ + pivot_row_degree = 0 ; + + /* tag pivot column as having been visited so it isn't included */ + /* in merged pivot row */ + Col [pivot_col].shared1.thickness = -pivot_col_thickness ; + + /* pivot row is the union of all rows in the pivot column pattern */ + cp = &A [Col [pivot_col].start] ; + cp_end = cp + Col [pivot_col].length ; + while (cp < cp_end) + { + /* get a row */ + row = *cp++ ; + DEBUG4 (("Pivot col pattern %d %d\n", ROW_IS_ALIVE (row), row)) ; + /* skip if row is dead */ + if (ROW_IS_ALIVE (row)) + { + rp = &A [Row [row].start] ; + rp_end = rp + Row [row].length ; + while (rp < rp_end) + { + /* get a column */ + col = *rp++ ; + /* add the column, if alive and untagged */ + col_thickness = Col [col].shared1.thickness ; + if (col_thickness > 0 && COL_IS_ALIVE (col)) + { + /* tag column in pivot row */ + Col [col].shared1.thickness = -col_thickness ; + ASSERT (pfree < Alen) ; + /* place column in pivot row */ + A [pfree++] = col ; + pivot_row_degree += col_thickness ; + } + } + } + } + + /* clear tag on pivot column */ + Col [pivot_col].shared1.thickness = pivot_col_thickness ; + max_deg = MAX (max_deg, pivot_row_degree) ; + +#ifndef NDEBUG + DEBUG3 (("check2\n")) ; + debug_mark (n_row, Row, tag_mark, max_mark) ; +#endif /* NDEBUG */ + + /* === Kill all rows used to construct pivot row ==================== */ + + /* also kill pivot row, temporarily */ + cp = &A [Col [pivot_col].start] ; + cp_end = cp + Col [pivot_col].length ; + while (cp < cp_end) + { + /* may be killing an already dead row */ + row = *cp++ ; + DEBUG3 (("Kill row in pivot col: %d\n", row)) ; + KILL_ROW (row) ; + } + + /* === Select a row index to use as the new pivot row =============== */ + + pivot_row_length = pfree - pivot_row_start ; + if (pivot_row_length > 0) + { + /* pick the "pivot" row arbitrarily (first row in col) */ + pivot_row = A [Col [pivot_col].start] ; + DEBUG3 (("Pivotal row is %d\n", pivot_row)) ; + } + else + { + /* there is no pivot row, since it is of zero length */ + pivot_row = EMPTY ; + ASSERT (pivot_row_length == 0) ; + } + ASSERT (Col [pivot_col].length > 0 || pivot_row_length == 0) ; + + /* === Approximate degree computation =============================== */ + + /* Here begins the computation of the approximate degree. The column */ + /* score is the sum of the pivot row "length", plus the size of the */ + /* set differences of each row in the column minus the pattern of the */ + /* pivot row itself. The column ("thickness") itself is also */ + /* excluded from the column score (we thus use an approximate */ + /* external degree). */ + + /* The time taken by the following code (compute set differences, and */ + /* add them up) is proportional to the size of the data structure */ + /* being scanned - that is, the sum of the sizes of each column in */ + /* the pivot row. Thus, the amortized time to compute a column score */ + /* is proportional to the size of that column (where size, in this */ + /* context, is the column "length", or the number of row indices */ + /* in that column). The number of row indices in a column is */ + /* monotonically non-decreasing, from the length of the original */ + /* column on input to colamd. */ + + /* === Compute set differences ====================================== */ + + DEBUG3 (("** Computing set differences phase. **\n")) ; + + /* pivot row is currently dead - it will be revived later. */ + + DEBUG3 (("Pivot row: ")) ; + /* for each column in pivot row */ + rp = &A [pivot_row_start] ; + rp_end = rp + pivot_row_length ; + while (rp < rp_end) + { + col = *rp++ ; + ASSERT (COL_IS_ALIVE (col) && col != pivot_col) ; + DEBUG3 (("Col: %d\n", col)) ; + + /* clear tags used to construct pivot row pattern */ + col_thickness = -Col [col].shared1.thickness ; + ASSERT (col_thickness > 0) ; + Col [col].shared1.thickness = col_thickness ; + + /* === Remove column from degree list =========================== */ + + cur_score = Col [col].shared2.score ; + prev_col = Col [col].shared3.prev ; + next_col = Col [col].shared4.degree_next ; + ASSERT (cur_score >= 0) ; + ASSERT (cur_score <= n_col) ; + ASSERT (cur_score >= EMPTY) ; + if (prev_col == EMPTY) + { + head [cur_score] = next_col ; + } + else + { + Col [prev_col].shared4.degree_next = next_col ; + } + if (next_col != EMPTY) + { + Col [next_col].shared3.prev = prev_col ; + } + + /* === Scan the column ========================================== */ + + cp = &A [Col [col].start] ; + cp_end = cp + Col [col].length ; + while (cp < cp_end) + { + /* get a row */ + row = *cp++ ; + row_mark = Row [row].shared2.mark ; + /* skip if dead */ + if (ROW_IS_MARKED_DEAD (row_mark)) + { + continue ; + } + ASSERT (row != pivot_row) ; + set_difference = row_mark - tag_mark ; + /* check if the row has been seen yet */ + if (set_difference < 0) + { + ASSERT (Row [row].shared1.degree <= max_deg) ; + set_difference = Row [row].shared1.degree ; + } + /* subtract column thickness from this row's set difference */ + set_difference -= col_thickness ; + ASSERT (set_difference >= 0) ; + /* absorb this row if the set difference becomes zero */ + if (set_difference == 0 && aggressive) + { + DEBUG3 (("aggressive absorption. Row: %d\n", row)) ; + KILL_ROW (row) ; + } + else + { + /* save the new mark */ + Row [row].shared2.mark = set_difference + tag_mark ; + } + } + } + +#ifndef NDEBUG + debug_deg_lists (n_row, n_col, Row, Col, head, + min_score, n_col2-k-pivot_row_degree, max_deg) ; +#endif /* NDEBUG */ + + /* === Add up set differences for each column ======================= */ + + DEBUG3 (("** Adding set differences phase. **\n")) ; + + /* for each column in pivot row */ + rp = &A [pivot_row_start] ; + rp_end = rp + pivot_row_length ; + while (rp < rp_end) + { + /* get a column */ + col = *rp++ ; + ASSERT (COL_IS_ALIVE (col) && col != pivot_col) ; + hash = 0 ; + cur_score = 0 ; + cp = &A [Col [col].start] ; + /* compact the column */ + new_cp = cp ; + cp_end = cp + Col [col].length ; + + DEBUG4 (("Adding set diffs for Col: %d.\n", col)) ; + + while (cp < cp_end) + { + /* get a row */ + row = *cp++ ; + ASSERT(row >= 0 && row < n_row) ; + row_mark = Row [row].shared2.mark ; + /* skip if dead */ + if (ROW_IS_MARKED_DEAD (row_mark)) + { + DEBUG4 ((" Row %d, dead\n", row)) ; + continue ; + } + DEBUG4 ((" Row %d, set diff %d\n", row, row_mark-tag_mark)); + ASSERT (row_mark >= tag_mark) ; + /* compact the column */ + *new_cp++ = row ; + /* compute hash function */ + hash += row ; + /* add set difference */ + cur_score += row_mark - tag_mark ; + /* integer overflow... */ + cur_score = MIN (cur_score, n_col) ; + } + + /* recompute the column's length */ + Col [col].length = (Int) (new_cp - &A [Col [col].start]) ; + + /* === Further mass elimination ================================= */ + + if (Col [col].length == 0) + { + DEBUG4 (("further mass elimination. Col: %d\n", col)) ; + /* nothing left but the pivot row in this column */ + KILL_PRINCIPAL_COL (col) ; + pivot_row_degree -= Col [col].shared1.thickness ; + ASSERT (pivot_row_degree >= 0) ; + /* order it */ + Col [col].shared2.order = k ; + /* increment order count by column thickness */ + k += Col [col].shared1.thickness ; + } + else + { + /* === Prepare for supercolumn detection ==================== */ + + DEBUG4 (("Preparing supercol detection for Col: %d.\n", col)) ; + + /* save score so far */ + Col [col].shared2.score = cur_score ; + + /* add column to hash table, for supercolumn detection */ + hash %= n_col + 1 ; + + DEBUG4 ((" Hash = %d, n_col = %d.\n", hash, n_col)) ; + ASSERT (((Int) hash) <= n_col) ; + + head_column = head [hash] ; + if (head_column > EMPTY) + { + /* degree list "hash" is non-empty, use prev (shared3) of */ + /* first column in degree list as head of hash bucket */ + first_col = Col [head_column].shared3.headhash ; + Col [head_column].shared3.headhash = col ; + } + else + { + /* degree list "hash" is empty, use head as hash bucket */ + first_col = - (head_column + 2) ; + head [hash] = - (col + 2) ; + } + Col [col].shared4.hash_next = first_col ; + + /* save hash function in Col [col].shared3.hash */ + Col [col].shared3.hash = (Int) hash ; + ASSERT (COL_IS_ALIVE (col)) ; + } + } + + /* The approximate external column degree is now computed. */ + + /* === Supercolumn detection ======================================== */ + + DEBUG3 (("** Supercolumn detection phase. **\n")) ; + + detect_super_cols ( + +#ifndef NDEBUG + n_col, Row, +#endif /* NDEBUG */ + + Col, A, head, pivot_row_start, pivot_row_length) ; + + /* === Kill the pivotal column ====================================== */ + + KILL_PRINCIPAL_COL (pivot_col) ; + + /* === Clear mark =================================================== */ + + tag_mark = clear_mark (tag_mark+max_deg+1, max_mark, n_row, Row) ; + +#ifndef NDEBUG + DEBUG3 (("check3\n")) ; + debug_mark (n_row, Row, tag_mark, max_mark) ; +#endif /* NDEBUG */ + + /* === Finalize the new pivot row, and column scores ================ */ + + DEBUG3 (("** Finalize scores phase. **\n")) ; + + /* for each column in pivot row */ + rp = &A [pivot_row_start] ; + /* compact the pivot row */ + new_rp = rp ; + rp_end = rp + pivot_row_length ; + while (rp < rp_end) + { + col = *rp++ ; + /* skip dead columns */ + if (COL_IS_DEAD (col)) + { + continue ; + } + *new_rp++ = col ; + /* add new pivot row to column */ + A [Col [col].start + (Col [col].length++)] = pivot_row ; + + /* retrieve score so far and add on pivot row's degree. */ + /* (we wait until here for this in case the pivot */ + /* row's degree was reduced due to mass elimination). */ + cur_score = Col [col].shared2.score + pivot_row_degree ; + + /* calculate the max possible score as the number of */ + /* external columns minus the 'k' value minus the */ + /* columns thickness */ + max_score = n_col - k - Col [col].shared1.thickness ; + + /* make the score the external degree of the union-of-rows */ + cur_score -= Col [col].shared1.thickness ; + + /* make sure score is less or equal than the max score */ + cur_score = MIN (cur_score, max_score) ; + ASSERT (cur_score >= 0) ; + + /* store updated score */ + Col [col].shared2.score = cur_score ; + + /* === Place column back in degree list ========================= */ + + ASSERT (min_score >= 0) ; + ASSERT (min_score <= n_col) ; + ASSERT (cur_score >= 0) ; + ASSERT (cur_score <= n_col) ; + ASSERT (head [cur_score] >= EMPTY) ; + next_col = head [cur_score] ; + Col [col].shared4.degree_next = next_col ; + Col [col].shared3.prev = EMPTY ; + if (next_col != EMPTY) + { + Col [next_col].shared3.prev = col ; + } + head [cur_score] = col ; + + /* see if this score is less than current min */ + min_score = MIN (min_score, cur_score) ; + + } + +#ifndef NDEBUG + debug_deg_lists (n_row, n_col, Row, Col, head, + min_score, n_col2-k, max_deg) ; +#endif /* NDEBUG */ + + /* === Resurrect the new pivot row ================================== */ + + if (pivot_row_degree > 0) + { + /* update pivot row length to reflect any cols that were killed */ + /* during super-col detection and mass elimination */ + Row [pivot_row].start = pivot_row_start ; + Row [pivot_row].length = (Int) (new_rp - &A[pivot_row_start]) ; + ASSERT (Row [pivot_row].length > 0) ; + Row [pivot_row].shared1.degree = pivot_row_degree ; + Row [pivot_row].shared2.mark = 0 ; + /* pivot row is no longer dead */ + + DEBUG1 (("Resurrect Pivot_row %d deg: %d\n", + pivot_row, pivot_row_degree)) ; + } + } + + /* === All principal columns have now been ordered ====================== */ + + return (ngarbage) ; +} + + +/* ========================================================================== */ +/* === order_children ======================================================= */ +/* ========================================================================== */ + +/* + The find_ordering routine has ordered all of the principal columns (the + representatives of the supercolumns). The non-principal columns have not + yet been ordered. This routine orders those columns by walking up the + parent tree (a column is a child of the column which absorbed it). The + final permutation vector is then placed in p [0 ... n_col-1], with p [0] + being the first column, and p [n_col-1] being the last. It doesn't look + like it at first glance, but be assured that this routine takes time linear + in the number of columns. Although not immediately obvious, the time + taken by this routine is O (n_col), that is, linear in the number of + columns. Not user-callable. +*/ + +PRIVATE void order_children +( + /* === Parameters ======================================================= */ + + Int n_col, /* number of columns of A */ + Colamd_Col Col [], /* of size n_col+1 */ + Int p [] /* p [0 ... n_col-1] is the column permutation*/ +) +{ + /* === Local variables ================================================== */ + + Int i ; /* loop counter for all columns */ + Int c ; /* column index */ + Int parent ; /* index of column's parent */ + Int order ; /* column's order */ + + /* === Order each non-principal column ================================== */ + + for (i = 0 ; i < n_col ; i++) + { + /* find an un-ordered non-principal column */ + ASSERT (COL_IS_DEAD (i)) ; + if (!COL_IS_DEAD_PRINCIPAL (i) && Col [i].shared2.order == EMPTY) + { + parent = i ; + /* once found, find its principal parent */ + do + { + parent = Col [parent].shared1.parent ; + } while (!COL_IS_DEAD_PRINCIPAL (parent)) ; + + /* now, order all un-ordered non-principal columns along path */ + /* to this parent. collapse tree at the same time */ + c = i ; + /* get order of parent */ + order = Col [parent].shared2.order ; + + do + { + ASSERT (Col [c].shared2.order == EMPTY) ; + + /* order this column */ + Col [c].shared2.order = order++ ; + /* collaps tree */ + Col [c].shared1.parent = parent ; + + /* get immediate parent of this column */ + c = Col [c].shared1.parent ; + + /* continue until we hit an ordered column. There are */ + /* guarranteed not to be anymore unordered columns */ + /* above an ordered column */ + } while (Col [c].shared2.order == EMPTY) ; + + /* re-order the super_col parent to largest order for this group */ + Col [parent].shared2.order = order ; + } + } + + /* === Generate the permutation ========================================= */ + + for (c = 0 ; c < n_col ; c++) + { + p [Col [c].shared2.order] = c ; + } +} + + +/* ========================================================================== */ +/* === detect_super_cols ==================================================== */ +/* ========================================================================== */ + +/* + Detects supercolumns by finding matches between columns in the hash buckets. + Check amongst columns in the set A [row_start ... row_start + row_length-1]. + The columns under consideration are currently *not* in the degree lists, + and have already been placed in the hash buckets. + + The hash bucket for columns whose hash function is equal to h is stored + as follows: + + if head [h] is >= 0, then head [h] contains a degree list, so: + + head [h] is the first column in degree bucket h. + Col [head [h]].headhash gives the first column in hash bucket h. + + otherwise, the degree list is empty, and: + + -(head [h] + 2) is the first column in hash bucket h. + + For a column c in a hash bucket, Col [c].shared3.prev is NOT a "previous + column" pointer. Col [c].shared3.hash is used instead as the hash number + for that column. The value of Col [c].shared4.hash_next is the next column + in the same hash bucket. + + Assuming no, or "few" hash collisions, the time taken by this routine is + linear in the sum of the sizes (lengths) of each column whose score has + just been computed in the approximate degree computation. + Not user-callable. +*/ + +PRIVATE void detect_super_cols +( + /* === Parameters ======================================================= */ + +#ifndef NDEBUG + /* these two parameters are only needed when debugging is enabled: */ + Int n_col, /* number of columns of A */ + Colamd_Row Row [], /* of size n_row+1 */ +#endif /* NDEBUG */ + + Colamd_Col Col [], /* of size n_col+1 */ + Int A [], /* row indices of A */ + Int head [], /* head of degree lists and hash buckets */ + Int row_start, /* pointer to set of columns to check */ + Int row_length /* number of columns to check */ +) +{ + /* === Local variables ================================================== */ + + Int hash ; /* hash value for a column */ + Int *rp ; /* pointer to a row */ + Int c ; /* a column index */ + Int super_c ; /* column index of the column to absorb into */ + Int *cp1 ; /* column pointer for column super_c */ + Int *cp2 ; /* column pointer for column c */ + Int length ; /* length of column super_c */ + Int prev_c ; /* column preceding c in hash bucket */ + Int i ; /* loop counter */ + Int *rp_end ; /* pointer to the end of the row */ + Int col ; /* a column index in the row to check */ + Int head_column ; /* first column in hash bucket or degree list */ + Int first_col ; /* first column in hash bucket */ + + /* === Consider each column in the row ================================== */ + + rp = &A [row_start] ; + rp_end = rp + row_length ; + while (rp < rp_end) + { + col = *rp++ ; + if (COL_IS_DEAD (col)) + { + continue ; + } + + /* get hash number for this column */ + hash = Col [col].shared3.hash ; + ASSERT (hash <= n_col) ; + + /* === Get the first column in this hash bucket ===================== */ + + head_column = head [hash] ; + if (head_column > EMPTY) + { + first_col = Col [head_column].shared3.headhash ; + } + else + { + first_col = - (head_column + 2) ; + } + + /* === Consider each column in the hash bucket ====================== */ + + for (super_c = first_col ; super_c != EMPTY ; + super_c = Col [super_c].shared4.hash_next) + { + ASSERT (COL_IS_ALIVE (super_c)) ; + ASSERT (Col [super_c].shared3.hash == hash) ; + length = Col [super_c].length ; + + /* prev_c is the column preceding column c in the hash bucket */ + prev_c = super_c ; + + /* === Compare super_c with all columns after it ================ */ + + for (c = Col [super_c].shared4.hash_next ; + c != EMPTY ; c = Col [c].shared4.hash_next) + { + ASSERT (c != super_c) ; + ASSERT (COL_IS_ALIVE (c)) ; + ASSERT (Col [c].shared3.hash == hash) ; + + /* not identical if lengths or scores are different */ + if (Col [c].length != length || + Col [c].shared2.score != Col [super_c].shared2.score) + { + prev_c = c ; + continue ; + } + + /* compare the two columns */ + cp1 = &A [Col [super_c].start] ; + cp2 = &A [Col [c].start] ; + + for (i = 0 ; i < length ; i++) + { + /* the columns are "clean" (no dead rows) */ + ASSERT (ROW_IS_ALIVE (*cp1)) ; + ASSERT (ROW_IS_ALIVE (*cp2)) ; + /* row indices will same order for both supercols, */ + /* no gather scatter nessasary */ + if (*cp1++ != *cp2++) + { + break ; + } + } + + /* the two columns are different if the for-loop "broke" */ + if (i != length) + { + prev_c = c ; + continue ; + } + + /* === Got it! two columns are identical =================== */ + + ASSERT (Col [c].shared2.score == Col [super_c].shared2.score) ; + + Col [super_c].shared1.thickness += Col [c].shared1.thickness ; + Col [c].shared1.parent = super_c ; + KILL_NON_PRINCIPAL_COL (c) ; + /* order c later, in order_children() */ + Col [c].shared2.order = EMPTY ; + /* remove c from hash bucket */ + Col [prev_c].shared4.hash_next = Col [c].shared4.hash_next ; + } + } + + /* === Empty this hash bucket ======================================= */ + + if (head_column > EMPTY) + { + /* corresponding degree list "hash" is not empty */ + Col [head_column].shared3.headhash = EMPTY ; + } + else + { + /* corresponding degree list "hash" is empty */ + head [hash] = EMPTY ; + } + } +} + + +/* ========================================================================== */ +/* === garbage_collection =================================================== */ +/* ========================================================================== */ + +/* + Defragments and compacts columns and rows in the workspace A. Used when + all avaliable memory has been used while performing row merging. Returns + the index of the first free position in A, after garbage collection. The + time taken by this routine is linear is the size of the array A, which is + itself linear in the number of nonzeros in the input matrix. + Not user-callable. +*/ + +PRIVATE Int garbage_collection /* returns the new value of pfree */ +( + /* === Parameters ======================================================= */ + + Int n_row, /* number of rows */ + Int n_col, /* number of columns */ + Colamd_Row Row [], /* row info */ + Colamd_Col Col [], /* column info */ + Int A [], /* A [0 ... Alen-1] holds the matrix */ + Int *pfree /* &A [0] ... pfree is in use */ +) +{ + /* === Local variables ================================================== */ + + Int *psrc ; /* source pointer */ + Int *pdest ; /* destination pointer */ + Int j ; /* counter */ + Int r ; /* a row index */ + Int c ; /* a column index */ + Int length ; /* length of a row or column */ + +#ifndef NDEBUG + Int debug_rows ; + DEBUG2 (("Defrag..\n")) ; + for (psrc = &A[0] ; psrc < pfree ; psrc++) ASSERT (*psrc >= 0) ; + debug_rows = 0 ; +#endif /* NDEBUG */ + + /* === Defragment the columns =========================================== */ + + pdest = &A[0] ; + for (c = 0 ; c < n_col ; c++) + { + if (COL_IS_ALIVE (c)) + { + psrc = &A [Col [c].start] ; + + /* move and compact the column */ + ASSERT (pdest <= psrc) ; + Col [c].start = (Int) (pdest - &A [0]) ; + length = Col [c].length ; + for (j = 0 ; j < length ; j++) + { + r = *psrc++ ; + if (ROW_IS_ALIVE (r)) + { + *pdest++ = r ; + } + } + Col [c].length = (Int) (pdest - &A [Col [c].start]) ; + } + } + + /* === Prepare to defragment the rows =================================== */ + + for (r = 0 ; r < n_row ; r++) + { + if (ROW_IS_DEAD (r) || (Row [r].length == 0)) + { + /* This row is already dead, or is of zero length. Cannot compact + * a row of zero length, so kill it. NOTE: in the current version, + * there are no zero-length live rows. Kill the row (for the first + * time, or again) just to be safe. */ + KILL_ROW (r) ; + } + else + { + /* save first column index in Row [r].shared2.first_column */ + psrc = &A [Row [r].start] ; + Row [r].shared2.first_column = *psrc ; + ASSERT (ROW_IS_ALIVE (r)) ; + /* flag the start of the row with the one's complement of row */ + *psrc = ONES_COMPLEMENT (r) ; +#ifndef NDEBUG + debug_rows++ ; +#endif /* NDEBUG */ + } + } + + /* === Defragment the rows ============================================== */ + + psrc = pdest ; + while (psrc < pfree) + { + /* find a negative number ... the start of a row */ + if (*psrc++ < 0) + { + psrc-- ; + /* get the row index */ + r = ONES_COMPLEMENT (*psrc) ; + ASSERT (r >= 0 && r < n_row) ; + /* restore first column index */ + *psrc = Row [r].shared2.first_column ; + ASSERT (ROW_IS_ALIVE (r)) ; + ASSERT (Row [r].length > 0) ; + /* move and compact the row */ + ASSERT (pdest <= psrc) ; + Row [r].start = (Int) (pdest - &A [0]) ; + length = Row [r].length ; + for (j = 0 ; j < length ; j++) + { + c = *psrc++ ; + if (COL_IS_ALIVE (c)) + { + *pdest++ = c ; + } + } + Row [r].length = (Int) (pdest - &A [Row [r].start]) ; + ASSERT (Row [r].length > 0) ; +#ifndef NDEBUG + debug_rows-- ; +#endif /* NDEBUG */ + } + } + /* ensure we found all the rows */ + ASSERT (debug_rows == 0) ; + + /* === Return the new value of pfree ==================================== */ + + return ((Int) (pdest - &A [0])) ; +} + + +/* ========================================================================== */ +/* === clear_mark =========================================================== */ +/* ========================================================================== */ + +/* + Clears the Row [].shared2.mark array, and returns the new tag_mark. + Return value is the new tag_mark. Not user-callable. +*/ + +PRIVATE Int clear_mark /* return the new value for tag_mark */ +( + /* === Parameters ======================================================= */ + + Int tag_mark, /* new value of tag_mark */ + Int max_mark, /* max allowed value of tag_mark */ + + Int n_row, /* number of rows in A */ + Colamd_Row Row [] /* Row [0 ... n_row-1].shared2.mark is set to zero */ +) +{ + /* === Local variables ================================================== */ + + Int r ; + + if (tag_mark <= 0 || tag_mark >= max_mark) + { + for (r = 0 ; r < n_row ; r++) + { + if (ROW_IS_ALIVE (r)) + { + Row [r].shared2.mark = 0 ; + } + } + tag_mark = 1 ; + } + + return (tag_mark) ; +} + + +/* ========================================================================== */ +/* === print_report ========================================================= */ +/* ========================================================================== */ + +PRIVATE void print_report +( + char *method, + Int stats [COLAMD_STATS] +) +{ + + Int i1, i2, i3 ; + + PRINTF (("\n%s version %d.%d, %s: ", method, + COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE)) ; + + if (!stats) + { + PRINTF (("No statistics available.\n")) ; + return ; + } + + i1 = stats [COLAMD_INFO1] ; + i2 = stats [COLAMD_INFO2] ; + i3 = stats [COLAMD_INFO3] ; + + if (stats [COLAMD_STATUS] >= 0) + { + PRINTF (("OK. ")) ; + } + else + { + PRINTF (("ERROR. ")) ; + } + + switch (stats [COLAMD_STATUS]) + { + + case COLAMD_OK_BUT_JUMBLED: + + PRINTF(("Matrix has unsorted or duplicate row indices.\n")) ; + + PRINTF(("%s: number of duplicate or out-of-order row indices: %d\n", + method, i3)) ; + + PRINTF(("%s: last seen duplicate or out-of-order row index: %d\n", + method, INDEX (i2))) ; + + PRINTF(("%s: last seen in column: %d", + method, INDEX (i1))) ; + + /* no break - fall through to next case instead */ + + case COLAMD_OK: + + PRINTF(("\n")) ; + + PRINTF(("%s: number of dense or empty rows ignored: %d\n", + method, stats [COLAMD_DENSE_ROW])) ; + + PRINTF(("%s: number of dense or empty columns ignored: %d\n", + method, stats [COLAMD_DENSE_COL])) ; + + PRINTF(("%s: number of garbage collections performed: %d\n", + method, stats [COLAMD_DEFRAG_COUNT])) ; + break ; + + case COLAMD_ERROR_A_not_present: + + PRINTF(("Array A (row indices of matrix) not present.\n")) ; + break ; + + case COLAMD_ERROR_p_not_present: + + PRINTF(("Array p (column pointers for matrix) not present.\n")) ; + break ; + + case COLAMD_ERROR_nrow_negative: + + PRINTF(("Invalid number of rows (%d).\n", i1)) ; + break ; + + case COLAMD_ERROR_ncol_negative: + + PRINTF(("Invalid number of columns (%d).\n", i1)) ; + break ; + + case COLAMD_ERROR_nnz_negative: + + PRINTF(("Invalid number of nonzero entries (%d).\n", i1)) ; + break ; + + case COLAMD_ERROR_p0_nonzero: + + PRINTF(("Invalid column pointer, p [0] = %d, must be zero.\n", i1)); + break ; + + case COLAMD_ERROR_A_too_small: + + PRINTF(("Array A too small.\n")) ; + PRINTF((" Need Alen >= %d, but given only Alen = %d.\n", + i1, i2)) ; + break ; + + case COLAMD_ERROR_col_length_negative: + + PRINTF + (("Column %d has a negative number of nonzero entries (%d).\n", + INDEX (i1), i2)) ; + break ; + + case COLAMD_ERROR_row_index_out_of_bounds: + + PRINTF + (("Row index (row %d) out of bounds (%d to %d) in column %d.\n", + INDEX (i2), INDEX (0), INDEX (i3-1), INDEX (i1))) ; + break ; + + case COLAMD_ERROR_out_of_memory: + + PRINTF(("Out of memory.\n")) ; + break ; + + /* v2.4: internal-error case deleted */ + } +} + + + + +/* ========================================================================== */ +/* === colamd debugging routines ============================================ */ +/* ========================================================================== */ + +/* When debugging is disabled, the remainder of this file is ignored. */ + +#ifndef NDEBUG + + +/* ========================================================================== */ +/* === debug_structures ===================================================== */ +/* ========================================================================== */ + +/* + At this point, all empty rows and columns are dead. All live columns + are "clean" (containing no dead rows) and simplicial (no supercolumns + yet). Rows may contain dead columns, but all live rows contain at + least one live column. +*/ + +PRIVATE void debug_structures +( + /* === Parameters ======================================================= */ + + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [], + Int n_col2 +) +{ + /* === Local variables ================================================== */ + + Int i ; + Int c ; + Int *cp ; + Int *cp_end ; + Int len ; + Int score ; + Int r ; + Int *rp ; + Int *rp_end ; + Int deg ; + + /* === Check A, Row, and Col ============================================ */ + + for (c = 0 ; c < n_col ; c++) + { + if (COL_IS_ALIVE (c)) + { + len = Col [c].length ; + score = Col [c].shared2.score ; + DEBUG4 (("initial live col %5d %5d %5d\n", c, len, score)) ; + ASSERT (len > 0) ; + ASSERT (score >= 0) ; + ASSERT (Col [c].shared1.thickness == 1) ; + cp = &A [Col [c].start] ; + cp_end = cp + len ; + while (cp < cp_end) + { + r = *cp++ ; + ASSERT (ROW_IS_ALIVE (r)) ; + } + } + else + { + i = Col [c].shared2.order ; + ASSERT (i >= n_col2 && i < n_col) ; + } + } + + for (r = 0 ; r < n_row ; r++) + { + if (ROW_IS_ALIVE (r)) + { + i = 0 ; + len = Row [r].length ; + deg = Row [r].shared1.degree ; + ASSERT (len > 0) ; + ASSERT (deg > 0) ; + rp = &A [Row [r].start] ; + rp_end = rp + len ; + while (rp < rp_end) + { + c = *rp++ ; + if (COL_IS_ALIVE (c)) + { + i++ ; + } + } + ASSERT (i > 0) ; + } + } +} + + +/* ========================================================================== */ +/* === debug_deg_lists ====================================================== */ +/* ========================================================================== */ + +/* + Prints the contents of the degree lists. Counts the number of columns + in the degree list and compares it to the total it should have. Also + checks the row degrees. +*/ + +PRIVATE void debug_deg_lists +( + /* === Parameters ======================================================= */ + + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int head [], + Int min_score, + Int should, + Int max_deg +) +{ + /* === Local variables ================================================== */ + + Int deg ; + Int col ; + Int have ; + Int row ; + + /* === Check the degree lists =========================================== */ + + if (n_col > 10000 && colamd_debug <= 0) + { + return ; + } + have = 0 ; + DEBUG4 (("Degree lists: %d\n", min_score)) ; + for (deg = 0 ; deg <= n_col ; deg++) + { + col = head [deg] ; + if (col == EMPTY) + { + continue ; + } + DEBUG4 (("%d:", deg)) ; + while (col != EMPTY) + { + DEBUG4 ((" %d", col)) ; + have += Col [col].shared1.thickness ; + ASSERT (COL_IS_ALIVE (col)) ; + col = Col [col].shared4.degree_next ; + } + DEBUG4 (("\n")) ; + } + DEBUG4 (("should %d have %d\n", should, have)) ; + ASSERT (should == have) ; + + /* === Check the row degrees ============================================ */ + + if (n_row > 10000 && colamd_debug <= 0) + { + return ; + } + for (row = 0 ; row < n_row ; row++) + { + if (ROW_IS_ALIVE (row)) + { + ASSERT (Row [row].shared1.degree <= max_deg) ; + } + } +} + + +/* ========================================================================== */ +/* === debug_mark =========================================================== */ +/* ========================================================================== */ + +/* + Ensures that the tag_mark is less that the maximum and also ensures that + each entry in the mark array is less than the tag mark. +*/ + +PRIVATE void debug_mark +( + /* === Parameters ======================================================= */ + + Int n_row, + Colamd_Row Row [], + Int tag_mark, + Int max_mark +) +{ + /* === Local variables ================================================== */ + + Int r ; + + /* === Check the Row marks ============================================== */ + + ASSERT (tag_mark > 0 && tag_mark <= max_mark) ; + if (n_row > 10000 && colamd_debug <= 0) + { + return ; + } + for (r = 0 ; r < n_row ; r++) + { + ASSERT (Row [r].shared2.mark < tag_mark) ; + } +} + + +/* ========================================================================== */ +/* === debug_matrix ========================================================= */ +/* ========================================================================== */ + +/* + Prints out the contents of the columns and the rows. +*/ + +PRIVATE void debug_matrix +( + /* === Parameters ======================================================= */ + + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [] +) +{ + /* === Local variables ================================================== */ + + Int r ; + Int c ; + Int *rp ; + Int *rp_end ; + Int *cp ; + Int *cp_end ; + + /* === Dump the rows and columns of the matrix ========================== */ + + if (colamd_debug < 3) + { + return ; + } + DEBUG3 (("DUMP MATRIX:\n")) ; + for (r = 0 ; r < n_row ; r++) + { + DEBUG3 (("Row %d alive? %d\n", r, ROW_IS_ALIVE (r))) ; + if (ROW_IS_DEAD (r)) + { + continue ; + } + DEBUG3 (("start %d length %d degree %d\n", + Row [r].start, Row [r].length, Row [r].shared1.degree)) ; + rp = &A [Row [r].start] ; + rp_end = rp + Row [r].length ; + while (rp < rp_end) + { + c = *rp++ ; + DEBUG4 ((" %d col %d\n", COL_IS_ALIVE (c), c)) ; + } + } + + for (c = 0 ; c < n_col ; c++) + { + DEBUG3 (("Col %d alive? %d\n", c, COL_IS_ALIVE (c))) ; + if (COL_IS_DEAD (c)) + { + continue ; + } + DEBUG3 (("start %d length %d shared1 %d shared2 %d\n", + Col [c].start, Col [c].length, + Col [c].shared1.thickness, Col [c].shared2.score)) ; + cp = &A [Col [c].start] ; + cp_end = cp + Col [c].length ; + while (cp < cp_end) + { + r = *cp++ ; + DEBUG4 ((" %d row %d\n", ROW_IS_ALIVE (r), r)) ; + } + } +} + +PRIVATE void colamd_get_debug +( + char *method +) +{ + FILE *f ; + colamd_debug = 0 ; /* no debug printing */ + f = fopen ("debug", "r") ; + if (f == (FILE *) NULL) + { + colamd_debug = 0 ; + } + else + { + fscanf (f, "%d", &colamd_debug) ; + fclose (f) ; + } + DEBUG0 (("%s: debug version, D = %d (THIS WILL BE SLOW!)\n", + method, colamd_debug)) ; +} + +#endif /* NDEBUG */ diff --git a/resources/3rdparty/glpk-4.57/src/colamd/colamd.h b/resources/3rdparty/glpk-4.57/src/colamd/colamd.h new file mode 100644 index 000000000..511735e5c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/colamd/colamd.h @@ -0,0 +1,69 @@ +/* colamd.h */ + +/* Written by Andrew Makhorin . */ + +#ifndef COLAMD_H +#define COLAMD_H + +#define _GLPSTD_STDIO +#include "env.h" + +#define COLAMD_DATE "Nov 1, 2007" +#define COLAMD_VERSION_CODE(main, sub) ((main) * 1000 + (sub)) +#define COLAMD_MAIN_VERSION 2 +#define COLAMD_SUB_VERSION 7 +#define COLAMD_SUBSUB_VERSION 1 +#define COLAMD_VERSION \ + COLAMD_VERSION_CODE(COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION) + +#define COLAMD_KNOBS 20 +#define COLAMD_STATS 20 +#define COLAMD_DENSE_ROW 0 +#define COLAMD_DENSE_COL 1 +#define COLAMD_AGGRESSIVE 2 +#define COLAMD_DEFRAG_COUNT 2 +#define COLAMD_STATUS 3 +#define COLAMD_INFO1 4 +#define COLAMD_INFO2 5 +#define COLAMD_INFO3 6 + +#define COLAMD_OK (0) +#define COLAMD_OK_BUT_JUMBLED (1) +#define COLAMD_ERROR_A_not_present (-1) +#define COLAMD_ERROR_p_not_present (-2) +#define COLAMD_ERROR_nrow_negative (-3) +#define COLAMD_ERROR_ncol_negative (-4) +#define COLAMD_ERROR_nnz_negative (-5) +#define COLAMD_ERROR_p0_nonzero (-6) +#define COLAMD_ERROR_A_too_small (-7) +#define COLAMD_ERROR_col_length_negative (-8) +#define COLAMD_ERROR_row_index_out_of_bounds (-9) +#define COLAMD_ERROR_out_of_memory (-10) +#define COLAMD_ERROR_internal_error (-999) + +#define colamd_recommended _glp_colamd_recommended +size_t colamd_recommended(int nnz, int n_row, int n_col); + +#define colamd_set_defaults _glp_colamd_set_defaults +void colamd_set_defaults(double knobs [COLAMD_KNOBS]); + +#define colamd _glp_colamd +int colamd(int n_row, int n_col, int Alen, int A[], int p[], + double knobs[COLAMD_KNOBS], int stats[COLAMD_STATS]); + +#define symamd _glp_symamd +int symamd(int n, int A[], int p[], int perm[], + double knobs[COLAMD_KNOBS], int stats[COLAMD_STATS], + void *(*allocate)(size_t, size_t), void(*release)(void *)); + +#define colamd_report _glp_colamd_report +void colamd_report(int stats[COLAMD_STATS]); + +#define symamd_report _glp_symamd_report +void symamd_report(int stats[COLAMD_STATS]); + +#define colamd_printf xprintf + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/draft.h b/resources/3rdparty/glpk-4.57/src/draft.h new file mode 100644 index 000000000..b453acd48 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/draft.h @@ -0,0 +1,32 @@ +/* draft.h */ + +/* (reserved for copyright notice) */ + +#ifndef DRAFT_H +#define DRAFT_H + +#include "glpk.h" + +#if 1 /* 28/XI-2009 */ +int _glp_analyze_row(glp_prob *P, int len, const int ind[], + const double val[], int type, double rhs, double eps, int *_piv, + double *_x, double *_dx, double *_y, double *_dy, double *_dz); +/* simulate one iteration of dual simplex method */ +#endif + +#if 1 /* 08/XII-2009 */ +void _glp_mpl_init_rand(glp_tran *tran, int seed); +#endif + +#define glp_skpgen _glp_skpgen +void glp_skpgen(int n, int r, int type, int v, int s, int a[], + int *b, int c[]); +/* Pisinger's 0-1 single knapsack problem generator */ + +#if 1 /* 28/V-2010 */ +int _glp_intopt1(glp_prob *P, const glp_iocp *parm); +#endif + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/env/alloc.c b/resources/3rdparty/glpk-4.57/src/env/alloc.c new file mode 100644 index 000000000..8e2d613de --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/env/alloc.c @@ -0,0 +1,252 @@ +/* alloc.c (dynamic memory allocation) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" + +#define ALIGN 16 +/* some processors need data to be properly aligned, so this macro + * defines the alignment boundary, in bytes, provided by glpk memory + * allocation routines; looks like 16-byte alignment boundary is + * sufficient for all 32- and 64-bit platforms (8-byte boundary is not + * sufficient for some 64-bit platforms because of jmp_buf) */ + +#define MBD_SIZE (((sizeof(MBD) + (ALIGN - 1)) / ALIGN) * ALIGN) +/* size of memory block descriptor, in bytes, rounded up to multiple + * of the alignment boundary */ + +/*********************************************************************** +* dma - dynamic memory allocation (basic routine) +* +* This routine performs dynamic memory allocation. It is similar to +* the standard realloc function, however, it provides every allocated +* memory block with a descriptor, which is used for sanity checks on +* reallocating/freeing previously allocated memory blocks as well as +* for book-keeping the memory usage statistics. */ + +static void *dma(const char *func, void *ptr, size_t size) +{ ENV *env = get_env_ptr(); + MBD *mbd; + if (ptr == NULL) + { /* new memory block will be allocated */ + mbd = NULL; + } + else + { /* allocated memory block will be reallocated or freed */ + /* get pointer to the block descriptor */ + mbd = (MBD *)((char *)ptr - MBD_SIZE); + /* make sure that the block descriptor is valid */ + if (mbd->self != mbd) + xerror("%s: ptr = %p; invalid pointer\n", func, ptr); + /* remove the block from the linked list */ + mbd->self = NULL; + if (mbd->prev == NULL) + env->mem_ptr = mbd->next; + else + mbd->prev->next = mbd->next; + if (mbd->next == NULL) + ; + else + mbd->next->prev = mbd->prev; + /* decrease usage counts */ + if (!(env->mem_count >= 1 && env->mem_total >= mbd->size)) + xerror("%s: memory allocation error\n", func); + env->mem_count--; + env->mem_total -= mbd->size; + if (size == 0) + { /* free the memory block */ + free(mbd); + return NULL; + } + } + /* allocate/reallocate memory block */ + if (size > SIZE_T_MAX - MBD_SIZE) + xerror("%s: block too large\n", func); + size += MBD_SIZE; + if (size > env->mem_limit - env->mem_total) + xerror("%s: memory allocation limit exceeded\n", func); + if (env->mem_count == INT_MAX) + xerror("%s: too many memory blocks allocated\n", func); + mbd = (mbd == NULL ? malloc(size) : realloc(mbd, size)); + if (mbd == NULL) + xerror("%s: no memory available\n", func); + /* setup the block descriptor */ + mbd->size = size; + mbd->self = mbd; + mbd->prev = NULL; + mbd->next = env->mem_ptr; + /* add the block to the beginning of the linked list */ + if (mbd->next != NULL) + mbd->next->prev = mbd; + env->mem_ptr = mbd; + /* increase usage counts */ + env->mem_count++; + if (env->mem_cpeak < env->mem_count) + env->mem_cpeak = env->mem_count; + env->mem_total += size; + if (env->mem_tpeak < env->mem_total) + env->mem_tpeak = env->mem_total; + return (char *)mbd + MBD_SIZE; +} + +/*********************************************************************** +* NAME +* +* glp_alloc - allocate memory block +* +* SYNOPSIS +* +* void *glp_alloc(int n, int size); +* +* DESCRIPTION +* +* The routine glp_alloc allocates a memory block of n * size bytes +* long. +* +* Note that being allocated the memory block contains arbitrary data +* (not binary zeros!). +* +* RETURNS +* +* The routine glp_alloc returns a pointer to the block allocated. +* To free this block the routine glp_free (not free!) must be used. */ + +void *glp_alloc(int n, int size) +{ if (n < 1) + xerror("glp_alloc: n = %d; invalid parameter\n", n); + if (size < 1) + xerror("glp_alloc: size = %d; invalid parameter\n", size); + if ((size_t)n > SIZE_T_MAX / (size_t)size) + xerror("glp_alloc: n = %d, size = %d; block too large\n", + n, size); + return dma("glp_alloc", NULL, (size_t)n * (size_t)size); +} + +/**********************************************************************/ + +void *glp_realloc(void *ptr, int n, int size) +{ /* reallocate memory block */ + if (ptr == NULL) + xerror("glp_realloc: ptr = %p; invalid pointer\n", ptr); + if (n < 1) + xerror("glp_realloc: n = %d; invalid parameter\n", n); + if (size < 1) + xerror("glp_realloc: size = %d; invalid parameter\n", size); + if ((size_t)n > SIZE_T_MAX / (size_t)size) + xerror("glp_realloc: n = %d, size = %d; block too large\n", + n, size); + return dma("glp_realloc", ptr, (size_t)n * (size_t)size); +} + +/*********************************************************************** +* NAME +* +* glp_free - free (deallocate) memory block +* +* SYNOPSIS +* +* void glp_free(void *ptr); +* +* DESCRIPTION +* +* The routine glp_free frees (deallocates) a memory block pointed to +* by ptr, which was previuosly allocated by the routine glp_alloc or +* reallocated by the routine glp_realloc. */ + +void glp_free(void *ptr) +{ if (ptr == NULL) + xerror("glp_free: ptr = %p; invalid pointer\n", ptr); + dma("glp_free", ptr, 0); + return; +} + +/*********************************************************************** +* NAME +* +* glp_mem_limit - set memory usage limit +* +* SYNOPSIS +* +* void glp_mem_limit(int limit); +* +* DESCRIPTION +* +* The routine glp_mem_limit limits the amount of memory available for +* dynamic allocation (in GLPK routines) to limit megabytes. */ + +void glp_mem_limit(int limit) +{ ENV *env = get_env_ptr(); + if (limit < 1) + xerror("glp_mem_limit: limit = %d; invalid parameter\n", + limit); + if ((size_t)limit <= (SIZE_T_MAX >> 20)) + env->mem_limit = (size_t)limit << 20; + else + env->mem_limit = SIZE_T_MAX; + return; +} + +/*********************************************************************** +* NAME +* +* glp_mem_usage - get memory usage information +* +* SYNOPSIS +* +* void glp_mem_usage(int *count, int *cpeak, size_t *total, +* size_t *tpeak); +* +* DESCRIPTION +* +* The routine glp_mem_usage reports some information about utilization +* of the memory by GLPK routines. Information is stored to locations +* specified by corresponding parameters (see below). Any parameter can +* be specified as NULL, in which case its value is not stored. +* +* *count is the number of the memory blocks currently allocated by the +* routines glp_malloc and glp_calloc (one call to glp_malloc or +* glp_calloc results in allocating one memory block). +* +* *cpeak is the peak value of *count reached since the initialization +* of the GLPK library environment. +* +* *total is the total amount, in bytes, of the memory blocks currently +* allocated by the routines glp_malloc and glp_calloc. +* +* *tpeak is the peak value of *total reached since the initialization +* of the GLPK library envirionment. */ + +void glp_mem_usage(int *count, int *cpeak, size_t *total, + size_t *tpeak) +{ ENV *env = get_env_ptr(); + if (count != NULL) + *count = env->mem_count; + if (cpeak != NULL) + *cpeak = env->mem_cpeak; + if (total != NULL) + *total = env->mem_total; + if (tpeak != NULL) + *tpeak = env->mem_tpeak; + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/env/dlsup.c b/resources/3rdparty/glpk-4.57/src/env/dlsup.c new file mode 100644 index 000000000..54c56c6dd --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/env/dlsup.c @@ -0,0 +1,167 @@ +/* dlsup.c (dynamic linking support) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2008-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "env.h" + +/* GNU version ********************************************************/ + +#if defined(HAVE_LTDL) + +#include + +void *xdlopen(const char *module) +{ /* open dynamically linked library */ + void *h = NULL; + if (lt_dlinit() != 0) + { put_err_msg(lt_dlerror()); + goto done; + } + h = lt_dlopen(module); + if (h == NULL) + { put_err_msg(lt_dlerror()); + if (lt_dlexit() != 0) + xerror("xdlopen: %s\n", lt_dlerror()); + } +done: return h; +} + +void *xdlsym(void *h, const char *symbol) +{ /* obtain address of symbol from dynamically linked library */ + void *ptr; + xassert(h != NULL); + ptr = lt_dlsym(h, symbol); + if (ptr == NULL) + xerror("xdlsym: %s: %s\n", symbol, lt_dlerror()); + return ptr; +} + +void xdlclose(void *h) +{ /* close dynamically linked library */ + xassert(h != NULL); + if (lt_dlclose(h) != 0) + xerror("xdlclose: %s\n", lt_dlerror()); + if (lt_dlexit() != 0) + xerror("xdlclose: %s\n", lt_dlerror()); + return; +} + +/* POSIX version ******************************************************/ + +#elif defined(HAVE_DLFCN) + +#include + +void *xdlopen(const char *module) +{ /* open dynamically linked library */ + void *h; + h = dlopen(module, RTLD_NOW); + if (h == NULL) + put_err_msg(dlerror()); + return h; +} + +void *xdlsym(void *h, const char *symbol) +{ /* obtain address of symbol from dynamically linked library */ + void *ptr; + xassert(h != NULL); + ptr = dlsym(h, symbol); + if (ptr == NULL) + xerror("xdlsym: %s: %s\n", symbol, dlerror()); + return ptr; +} + +void xdlclose(void *h) +{ /* close dynamically linked library */ + xassert(h != NULL); + if (dlclose(h) != 0) + xerror("xdlclose: %s\n", dlerror()); + return; +} + +/* MS Windows version *************************************************/ + +#elif defined(__WOE__) + +#include + +void *xdlopen(const char *module) +{ /* open dynamically linked library */ + void *h; + h = LoadLibrary(module); + if (h == NULL) + { char msg[20]; + sprintf(msg, "Error %d", GetLastError()); + put_err_msg(msg); + } + return h; +} + +void *xdlsym(void *h, const char *symbol) +{ /* obtain address of symbol from dynamically linked library */ + void *ptr; + xassert(h != NULL); + ptr = GetProcAddress(h, symbol); + if (ptr == NULL) + xerror("xdlsym: %s: Error %d\n", symbol, GetLastError()); + return ptr; +} + +void xdlclose(void *h) +{ /* close dynamically linked library */ + xassert(h != NULL); + if (!FreeLibrary(h)) + xerror("xdlclose: Error %d\n", GetLastError()); + return; +} + +/* NULL version *******************************************************/ + +#else + +void *xdlopen(const char *module) +{ /* open dynamically linked library */ + xassert(module == module); + put_err_msg("Shared libraries not supported"); + return NULL; +} + +void *xdlsym(void *h, const char *symbol) +{ /* obtain address of symbol from dynamically linked library */ + xassert(h != h); + xassert(symbol != symbol); + return NULL; +} + +void xdlclose(void *h) +{ /* close dynamically linked library */ + xassert(h != h); + return; +} + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/env/env.c b/resources/3rdparty/glpk-4.57/src/env/env.c new file mode 100644 index 000000000..2cc67a3b9 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/env/env.c @@ -0,0 +1,237 @@ +/* env.c (GLPK environment initialization/termination) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "glpk.h" +#include "env.h" + +/*********************************************************************** +* NAME +* +* glp_init_env - initialize GLPK environment +* +* SYNOPSIS +* +* int glp_init_env(void); +* +* DESCRIPTION +* +* The routine glp_init_env initializes the GLPK environment. Normally +* the application program does not need to call this routine, because +* it is called automatically on the first call to any API routine. +* +* RETURNS +* +* The routine glp_init_env returns one of the following codes: +* +* 0 - initialization successful; +* 1 - environment has been already initialized; +* 2 - initialization failed (insufficient memory); +* 3 - initialization failed (unsupported programming model). */ + +int glp_init_env(void) +{ ENV *env; + int ok; + /* check if the programming model is supported */ + ok = (CHAR_BIT == 8 && sizeof(char) == 1 && + sizeof(short) == 2 && sizeof(int) == 4 && + (sizeof(void *) == 4 || sizeof(void *) == 8)); + if (!ok) + return 3; + /* check if the environment is already initialized */ + if (tls_get_ptr() != NULL) + return 1; + /* allocate and initialize the environment block */ + env = malloc(sizeof(ENV)); + if (env == NULL) + return 2; + memset(env, 0, sizeof(ENV)); + sprintf(env->version, "%d.%d", + GLP_MAJOR_VERSION, GLP_MINOR_VERSION); + env->self = env; + env->term_buf = malloc(TBUF_SIZE); + if (env->term_buf == NULL) + { free(env); + return 2; + } + env->term_out = GLP_ON; + env->term_hook = NULL; + env->term_info = NULL; + env->tee_file = NULL; + env->err_file = NULL; + env->err_line = 0; + env->err_hook = NULL; + env->err_info = NULL; + env->err_buf = malloc(EBUF_SIZE); + if (env->err_buf == NULL) + { free(env->term_buf); + free(env); + return 2; + } + env->err_buf[0] = '\0'; + env->mem_limit = SIZE_T_MAX; + env->mem_ptr = NULL; + env->mem_count = env->mem_cpeak = 0; + env->mem_total = env->mem_tpeak = 0; + env->h_odbc = env->h_mysql = NULL; + /* save pointer to the environment block */ + tls_set_ptr(env); + /* initialization successful */ + return 0; +} + +/*********************************************************************** +* NAME +* +* get_env_ptr - retrieve pointer to environment block +* +* SYNOPSIS +* +* #include "env.h" +* ENV *get_env_ptr(void); +* +* DESCRIPTION +* +* The routine get_env_ptr retrieves and returns a pointer to the GLPK +* environment block. +* +* If the GLPK environment has not been initialized yet, the routine +* performs initialization. If initialization fails, the routine prints +* an error message to stderr and terminates the program. +* +* RETURNS +* +* The routine returns a pointer to the environment block. */ + +ENV *get_env_ptr(void) +{ ENV *env = tls_get_ptr(); + /* check if the environment has been initialized */ + if (env == NULL) + { /* not initialized yet; perform initialization */ + if (glp_init_env() != 0) + { /* initialization failed; display an error message */ + fprintf(stderr, "GLPK initialization failed\n"); + fflush(stderr); + /* and abnormally terminate the program */ + abort(); + } + /* initialization successful; retrieve the pointer */ + env = tls_get_ptr(); + } + /* check if the environment block is valid */ + if (env->self != env) + { fprintf(stderr, "Invalid GLPK environment\n"); + fflush(stderr); + abort(); + } + return env; +} + +/*********************************************************************** +* NAME +* +* glp_version - determine library version +* +* SYNOPSIS +* +* const char *glp_version(void); +* +* RETURNS +* +* The routine glp_version returns a pointer to a null-terminated +* character string, which specifies the version of the GLPK library in +* the form "X.Y", where X is the major version number, and Y is the +* minor version number, for example, "4.16". */ + +const char *glp_version(void) +{ ENV *env = get_env_ptr(); + return env->version; +} + +/*********************************************************************** +* NAME +* +* glp_free_env - free GLPK environment +* +* SYNOPSIS +* +* int glp_free_env(void); +* +* DESCRIPTION +* +* The routine glp_free_env frees all resources used by GLPK routines +* (memory blocks, etc.) which are currently still in use. +* +* Normally the application program does not need to call this routine, +* because GLPK routines always free all unused resources. However, if +* the application program even has deleted all problem objects, there +* will be several memory blocks still allocated for the library needs. +* For some reasons the application program may want GLPK to free this +* memory, in which case it should call glp_free_env. +* +* Note that a call to glp_free_env invalidates all problem objects as +* if no GLPK routine were called. +* +* RETURNS +* +* 0 - termination successful; +* 1 - environment is inactive (was not initialized). */ + +int glp_free_env(void) +{ ENV *env = tls_get_ptr(); + MBD *desc; + /* check if the environment is active */ + if (env == NULL) + return 1; + /* check if the environment block is valid */ + if (env->self != env) + { fprintf(stderr, "Invalid GLPK environment\n"); + fflush(stderr); + abort(); + } + /* close handles to shared libraries */ + if (env->h_odbc != NULL) + xdlclose(env->h_odbc); + if (env->h_mysql != NULL) + xdlclose(env->h_mysql); + /* free memory blocks which are still allocated */ + while (env->mem_ptr != NULL) + { desc = env->mem_ptr; + env->mem_ptr = desc->next; + free(desc); + } + /* close text file used for copying terminal output */ + if (env->tee_file != NULL) + fclose(env->tee_file); + /* invalidate the environment block */ + env->self = NULL; + /* free memory allocated to the environment block */ + free(env->term_buf); + free(env->err_buf); + free(env); + /* reset a pointer to the environment block */ + tls_set_ptr(NULL); + /* termination successful */ + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/env/env.h b/resources/3rdparty/glpk-4.57/src/env/env.h new file mode 100644 index 000000000..7d26a21ee --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/env/env.h @@ -0,0 +1,262 @@ +/* env.h (GLPK environment) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef ENV_H +#define ENV_H + +#include "stdc.h" + +typedef struct ENV ENV; +typedef struct MBD MBD; + +#define SIZE_T_MAX (~(size_t)0) +/* largest value of size_t type */ + +#define TBUF_SIZE 4096 +/* terminal output buffer size, in bytes */ + +#define EBUF_SIZE 1024 +/* error message buffer size, in bytes */ + +/* enable/disable flag: */ +#define GLP_ON 1 +#define GLP_OFF 0 + +struct ENV +{ /* GLPK environment block */ + char version[7+1]; + /* version string returned by the routine glp_version */ + ENV *self; + /* pointer to this block to check its validity */ + /*--------------------------------------------------------------*/ + /* terminal output */ + char *term_buf; /* char term_buf[TBUF_SIZE]; */ + /* terminal output buffer */ + int term_out; + /* flag to enable/disable terminal output */ + int (*term_hook)(void *info, const char *s); + /* user-defined routine to intercept terminal output */ + void *term_info; + /* transit pointer (cookie) passed to the routine term_hook */ + FILE *tee_file; + /* output stream used to copy terminal output */ + /*--------------------------------------------------------------*/ + /* error handling */ +#if 1 /* 07/XI-2015 */ + int err_st; + /* error state flag; set on entry to glp_error */ +#endif + const char *err_file; + /* value of the __FILE__ macro passed to glp_error */ + int err_line; + /* value of the __LINE__ macro passed to glp_error */ + void (*err_hook)(void *info); + /* user-defined routine to intercept abnormal termination */ + void *err_info; + /* transit pointer (cookie) passed to the routine err_hook */ + char *err_buf; /* char err_buf[EBUF_SIZE]; */ + /* buffer to store error messages (used by I/O routines) */ + /*--------------------------------------------------------------*/ + /* dynamic memory allocation */ + size_t mem_limit; + /* maximal amount of memory, in bytes, available for dynamic + * allocation */ + MBD *mem_ptr; + /* pointer to the linked list of allocated memory blocks */ + int mem_count; + /* total number of currently allocated memory blocks */ + int mem_cpeak; + /* peak value of mem_count */ + size_t mem_total; + /* total amount of currently allocated memory, in bytes; it is + * the sum of the size field over all memory block descriptors */ + size_t mem_tpeak; + /* peak value of mem_total */ + /*--------------------------------------------------------------*/ + /* dynamic linking support (optional) */ + void *h_odbc; + /* handle to ODBC shared library */ + void *h_mysql; + /* handle to MySQL shared library */ +}; + +struct MBD +{ /* memory block descriptor */ + size_t size; + /* size of block, in bytes, including descriptor */ + MBD *self; + /* pointer to this descriptor to check its validity */ + MBD *prev; + /* pointer to previous memory block descriptor */ + MBD *next; + /* pointer to next memory block descriptor */ +}; + +#define get_env_ptr _glp_get_env_ptr +ENV *get_env_ptr(void); +/* retrieve pointer to environment block */ + +#define tls_set_ptr _glp_tls_set_ptr +void tls_set_ptr(void *ptr); +/* store global pointer in TLS */ + +#define tls_get_ptr _glp_tls_get_ptr +void *tls_get_ptr(void); +/* retrieve global pointer from TLS */ + +#define xputs glp_puts +void glp_puts(const char *s); +/* write string on terminal */ + +#define xprintf glp_printf +void glp_printf(const char *fmt, ...); +/* write formatted output on terminal */ + +#define xvprintf glp_vprintf +void glp_vprintf(const char *fmt, va_list arg); +/* write formatted output on terminal */ + +int glp_term_out(int flag); +/* enable/disable terminal output */ + +void glp_term_hook(int (*func)(void *info, const char *s), void *info); +/* install hook to intercept terminal output */ + +int glp_open_tee(const char *fname); +/* start copying terminal output to text file */ + +int glp_close_tee(void); +/* stop copying terminal output to text file */ + +#ifndef GLP_ERRFUNC_DEFINED +#define GLP_ERRFUNC_DEFINED +typedef void (*glp_errfunc)(const char *fmt, ...); +#endif + +#define xerror glp_error_(__FILE__, __LINE__) +glp_errfunc glp_error_(const char *file, int line); +/* display fatal error message and terminate execution */ + +#define xassert(expr) \ + ((void)((expr) || (glp_assert_(#expr, __FILE__, __LINE__), 1))) +void glp_assert_(const char *expr, const char *file, int line); +/* check for logical condition */ + +void glp_error_hook(void (*func)(void *info), void *info); +/* install hook to intercept abnormal termination */ + +#define put_err_msg _glp_put_err_msg +void put_err_msg(const char *msg); +/* provide error message string */ + +#define get_err_msg _glp_get_err_msg +const char *get_err_msg(void); +/* obtain error message string */ + +#define xmalloc(size) glp_alloc(1, size) +/* allocate memory block (obsolete) */ + +#define xcalloc(n, size) glp_alloc(n, size) +/* allocate memory block (obsolete) */ + +#define xalloc(n, size) glp_alloc(n, size) +#define talloc(n, type) ((type *)glp_alloc(n, sizeof(type))) +void *glp_alloc(int n, int size); +/* allocate memory block */ + +#define xrealloc(ptr, n, size) glp_realloc(ptr, n, size) +#define trealloc(ptr, n, type) ((type *)glp_realloc(ptr, n, \ + sizeof(type))) +void *glp_realloc(void *ptr, int n, int size); +/* reallocate memory block */ + +#define xfree(ptr) glp_free(ptr) +#define tfree(ptr) glp_free(ptr) +void glp_free(void *ptr); +/* free memory block */ + +void glp_mem_limit(int limit); +/* set memory usage limit */ + +void glp_mem_usage(int *count, int *cpeak, size_t *total, + size_t *tpeak); +/* get memory usage information */ + +typedef struct glp_file glp_file; +/* sequential stream descriptor */ + +#define glp_open _glp_open +glp_file *glp_open(const char *name, const char *mode); +/* open stream */ + +#define glp_eof _glp_eof +int glp_eof(glp_file *f); +/* test end-of-file indicator */ + +#define glp_ioerr _glp_ioerr +int glp_ioerr(glp_file *f); +/* test I/O error indicator */ + +#define glp_read _glp_read +int glp_read(glp_file *f, void *buf, int nnn); +/* read data from stream */ + +#define glp_getc _glp_getc +int glp_getc(glp_file *f); +/* read character from stream */ + +#define glp_write _glp_write +int glp_write(glp_file *f, const void *buf, int nnn); +/* write data to stream */ + +#define glp_format _glp_format +int glp_format(glp_file *f, const char *fmt, ...); +/* write formatted data to stream */ + +#define glp_close _glp_close +int glp_close(glp_file *f); +/* close stream */ + +#define xtime glp_time +double glp_time(void); +/* determine current universal time */ + +#define xdifftime glp_difftime +double glp_difftime(double t1, double t0); +/* compute difference between two time values */ + +#define xdlopen _glp_dlopen +void *xdlopen(const char *module); +/* open dynamically linked library */ + +#define xdlsym _glp_dlsym +void *xdlsym(void *h, const char *symbol); +/* obtain address of symbol from dynamically linked library */ + +#define xdlclose _glp_dlclose +void xdlclose(void *h); +/* close dynamically linked library */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/env/error.c b/resources/3rdparty/glpk-4.57/src/env/error.c new file mode 100644 index 000000000..a898b7687 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/env/error.c @@ -0,0 +1,200 @@ +/* error.c (error handling) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" + +/*********************************************************************** +* NAME +* +* glp_error - display fatal error message and terminate execution +* +* SYNOPSIS +* +* void glp_error(const char *fmt, ...); +* +* DESCRIPTION +* +* The routine glp_error (implemented as a macro) formats its +* parameters using the format control string fmt, writes the formatted +* message on the terminal, and abnormally terminates the program. */ + +static void errfunc(const char *fmt, ...) +{ ENV *env = get_env_ptr(); + va_list arg; +#if 1 /* 07/XI-2015 */ + env->err_st = 1; +#endif + env->term_out = GLP_ON; + va_start(arg, fmt); + xvprintf(fmt, arg); + va_end(arg); + xprintf("Error detected in file %s at line %d\n", + env->err_file, env->err_line); + if (env->err_hook != NULL) + env->err_hook(env->err_info); + abort(); + exit(EXIT_FAILURE); + /* no return */ +} + +glp_errfunc glp_error_(const char *file, int line) +{ ENV *env = get_env_ptr(); + env->err_file = file; + env->err_line = line; + return errfunc; +} + +#if 1 /* 07/XI-2015 */ +/*********************************************************************** +* NAME +* +* glp_at_error - check for error state +* +* SYNOPSIS +* +* int glp_at_error(void); +* +* DESCRIPTION +* +* The routine glp_at_error checks if the GLPK environment is at error +* state, i.e. if the call to the routine is (indirectly) made from the +* glp_error routine via an user-defined hook routine. +* +* RETURNS +* +* If the GLPK environment is at error state, the routine glp_at_error +* returns non-zero, otherwise zero. */ + +int glp_at_error(void) +{ ENV *env = get_env_ptr(); + return env->err_st; +} +#endif + +/*********************************************************************** +* NAME +* +* glp_assert - check for logical condition +* +* SYNOPSIS +* +* void glp_assert(int expr); +* +* DESCRIPTION +* +* The routine glp_assert (implemented as a macro) checks for a logical +* condition specified by the parameter expr. If the condition is false +* (i.e. the value of expr is zero), the routine writes a message on +* the terminal and abnormally terminates the program. */ + +void glp_assert_(const char *expr, const char *file, int line) +{ glp_error_(file, line)("Assertion failed: %s\n", expr); + /* no return */ +} + +/*********************************************************************** +* NAME +* +* glp_error_hook - install hook to intercept abnormal termination +* +* SYNOPSIS +* +* void glp_error_hook(void (*func)(void *info), void *info); +* +* DESCRIPTION +* +* The routine glp_error_hook installs a user-defined hook routine to +* intercept abnormal termination. +* +* The parameter func specifies the user-defined hook routine. It is +* called from the routine glp_error before the latter calls the abort +* function to abnormally terminate the application program because of +* fatal error. The parameter info is a transit pointer, specified in +* the corresponding call to the routine glp_error_hook; it may be used +* to pass some information to the hook routine. +* +* To uninstall the hook routine the parameters func and info should be +* both specified as NULL. */ + +void glp_error_hook(void (*func)(void *info), void *info) +{ ENV *env = get_env_ptr(); + if (func == NULL) + { env->err_hook = NULL; + env->err_info = NULL; + } + else + { env->err_hook = func; + env->err_info = info; + } + return; +} + +/*********************************************************************** +* NAME +* +* put_err_msg - provide error message string +* +* SYNOPSIS +* +* #include "env.h" +* void put_err_msg(const char *msg); +* +* DESCRIPTION +* +* The routine put_err_msg stores an error message string pointed to by +* msg to the environment block. */ + +void put_err_msg(const char *msg) +{ ENV *env = get_env_ptr(); + int len; + len = strlen(msg); + if (len >= EBUF_SIZE) + len = EBUF_SIZE - 1; + memcpy(env->err_buf, msg, len); + if (len > 0 && env->err_buf[len-1] == '\n') + len--; + env->err_buf[len] = '\0'; + return; +} + +/*********************************************************************** +* NAME +* +* get_err_msg - obtain error message string +* +* SYNOPSIS +* +* #include "env.h" +* const char *get_err_msg(void); +* +* RETURNS +* +* The routine get_err_msg returns a pointer to an error message string +* previously stored by the routine put_err_msg. */ + +const char *get_err_msg(void) +{ ENV *env = get_env_ptr(); + return env->err_buf; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/env/stdc.h b/resources/3rdparty/glpk-4.57/src/env/stdc.h new file mode 100644 index 000000000..9ffdcd942 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/env/stdc.h @@ -0,0 +1,42 @@ +/* stdc.h (standard ANSI C headers) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef STDC_H +#define STDC_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/env/stdout.c b/resources/3rdparty/glpk-4.57/src/env/stdout.c new file mode 100644 index 000000000..94eee02a4 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/env/stdout.c @@ -0,0 +1,262 @@ +/* stdout.c (terminal output) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#undef NDEBUG +#include +#include "env.h" + +/*********************************************************************** +* NAME +* +* glp_puts - write string on terminal +* +* SYNOPSIS +* +* void glp_puts(const char *s); +* +* The routine glp_puts writes the string s on the terminal. */ + +void glp_puts(const char *s) +{ ENV *env = get_env_ptr(); + /* if terminal output is disabled, do nothing */ + if (!env->term_out) + goto skip; + /* pass the string to the hook routine, if defined */ + if (env->term_hook != NULL) + { if (env->term_hook(env->term_info, s) != 0) + goto skip; + } + /* write the string on the terminal */ + fputs(s, stdout); + fflush(stdout); + /* write the string on the tee file, if required */ + if (env->tee_file != NULL) + { fputs(s, env->tee_file); + fflush(env->tee_file); + } +skip: return; +} + +/*********************************************************************** +* NAME +* +* glp_printf - write formatted output on terminal +* +* SYNOPSIS +* +* void glp_printf(const char *fmt, ...); +* +* DESCRIPTION +* +* The routine glp_printf uses the format control string fmt to format +* its parameters and writes the formatted output on the terminal. */ + +void glp_printf(const char *fmt, ...) +{ ENV *env = get_env_ptr(); + va_list arg; + /* if terminal output is disabled, do nothing */ + if (!env->term_out) + goto skip; + /* format the output */ + va_start(arg, fmt); + vsprintf(env->term_buf, fmt, arg); + /* (do not use xassert) */ + assert(strlen(env->term_buf) < TBUF_SIZE); + va_end(arg); + /* write the formatted output on the terminal */ + glp_puts(env->term_buf); +skip: return; +} + +/*********************************************************************** +* NAME +* +* glp_vprintf - write formatted output on terminal +* +* SYNOPSIS +* +* void glp_vprintf(const char *fmt, va_list arg); +* +* DESCRIPTION +* +* The routine glp_vprintf uses the format control string fmt to format +* its parameters specified by the list arg and writes the formatted +* output on the terminal. */ + +void glp_vprintf(const char *fmt, va_list arg) +{ ENV *env = get_env_ptr(); + /* if terminal output is disabled, do nothing */ + if (!env->term_out) + goto skip; + /* format the output */ + vsprintf(env->term_buf, fmt, arg); + /* (do not use xassert) */ + assert(strlen(env->term_buf) < TBUF_SIZE); + /* write the formatted output on the terminal */ + glp_puts(env->term_buf); +skip: return; +} + +/*********************************************************************** +* NAME +* +* glp_term_out - enable/disable terminal output +* +* SYNOPSIS +* +* int glp_term_out(int flag); +* +* DESCRIPTION +* +* Depending on the parameter flag the routine glp_term_out enables or +* disables terminal output performed by glpk routines: +* +* GLP_ON - enable terminal output; +* GLP_OFF - disable terminal output. +* +* RETURNS +* +* The routine glp_term_out returns the previous value of the terminal +* output flag. */ + +int glp_term_out(int flag) +{ ENV *env = get_env_ptr(); + int old = env->term_out; + if (!(flag == GLP_ON || flag == GLP_OFF)) + xerror("glp_term_out: flag = %d; invalid parameter\n", flag); + env->term_out = flag; + return old; +} + +/*********************************************************************** +* NAME +* +* glp_term_hook - install hook to intercept terminal output +* +* SYNOPSIS +* +* void glp_term_hook(int (*func)(void *info, const char *s), +* void *info); +* +* DESCRIPTION +* +* The routine glp_term_hook installs a user-defined hook routine to +* intercept all terminal output performed by glpk routines. +* +* This feature can be used to redirect the terminal output to other +* destination, for example to a file or a text window. +* +* The parameter func specifies the user-defined hook routine. It is +* called from an internal printing routine, which passes to it two +* parameters: info and s. The parameter info is a transit pointer, +* specified in the corresponding call to the routine glp_term_hook; +* it may be used to pass some information to the hook routine. The +* parameter s is a pointer to the null terminated character string, +* which is intended to be written to the terminal. If the hook routine +* returns zero, the printing routine writes the string s to the +* terminal in a usual way; otherwise, if the hook routine returns +* non-zero, no terminal output is performed. +* +* To uninstall the hook routine the parameters func and info should be +* specified as NULL. */ + +void glp_term_hook(int (*func)(void *info, const char *s), void *info) +{ ENV *env = get_env_ptr(); + if (func == NULL) + { env->term_hook = NULL; + env->term_info = NULL; + } + else + { env->term_hook = func; + env->term_info = info; + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_open_tee - start copying terminal output to text file +* +* SYNOPSIS +* +* int glp_open_tee(const char *name); +* +* DESCRIPTION +* +* The routine glp_open_tee starts copying all the terminal output to +* an output text file, whose name is specified by the character string +* name. +* +* RETURNS +* +* 0 - operation successful +* 1 - copying terminal output is already active +* 2 - unable to create output file */ + +int glp_open_tee(const char *name) +{ ENV *env = get_env_ptr(); + if (env->tee_file != NULL) + { /* copying terminal output is already active */ + return 1; + } + env->tee_file = fopen(name, "w"); + if (env->tee_file == NULL) + { /* unable to create output file */ + return 2; + } + return 0; +} + +/*********************************************************************** +* NAME +* +* glp_close_tee - stop copying terminal output to text file +* +* SYNOPSIS +* +* int glp_close_tee(void); +* +* DESCRIPTION +* +* The routine glp_close_tee stops copying the terminal output to the +* output text file previously open by the routine glp_open_tee closing +* that file. +* +* RETURNS +* +* 0 - operation successful +* 1 - copying terminal output was not started */ + +int glp_close_tee(void) +{ ENV *env = get_env_ptr(); + if (env->tee_file == NULL) + { /* copying terminal output was not started */ + return 1; + } + fclose(env->tee_file); + env->tee_file = NULL; + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/env/stream.c b/resources/3rdparty/glpk-4.57/src/env/stream.c new file mode 100644 index 000000000..8879616e2 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/env/stream.c @@ -0,0 +1,485 @@ +/* stream.c (stream input/output) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2008-2014 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "zlib.h" + +struct glp_file +{ /* sequential stream descriptor */ + char *base; + /* pointer to buffer */ + int size; + /* size of buffer, in bytes */ + char *ptr; + /* pointer to next byte in buffer */ + int cnt; + /* count of bytes in buffer */ + int flag; + /* stream flags: */ +#define IONULL 0x01 /* null file */ +#define IOSTD 0x02 /* standard stream */ +#define IOGZIP 0x04 /* gzipped file */ +#define IOWRT 0x08 /* output stream */ +#define IOEOF 0x10 /* end of file */ +#define IOERR 0x20 /* input/output error */ + void *file; + /* pointer to underlying control object */ +}; + +/*********************************************************************** +* NAME +* +* glp_open - open stream +* +* SYNOPSIS +* +* glp_file *glp_open(const char *name, const char *mode); +* +* DESCRIPTION +* +* The routine glp_open opens a file whose name is a string pointed to +* by name and associates a stream with it. +* +* The following special filenames are recognized by the routine (this +* feature is platform independent): +* +* "/dev/null" empty (null) file; +* "/dev/stdin" standard input stream; +* "/dev/stdout" standard output stream; +* "/dev/stderr" standard error stream. +* +* If the specified filename is ended with ".gz", it is assumed that +* the file is in gzipped format. In this case the file is compressed +* or decompressed by the I/O routines "on the fly". +* +* The parameter mode points to a string, which indicates the open mode +* and should be one of the following: +* +* "r" open text file for reading; +* "w" truncate to zero length or create text file for writing; +* "a" append, open or create text file for writing at end-of-file; +* "rb" open binary file for reading; +* "wb" truncate to zero length or create binary file for writing; +* "ab" append, open or create binary file for writing at end-of-file. +* +* RETURNS +* +* The routine glp_open returns a pointer to the object controlling the +* stream. If the operation fails, the routine returns NULL. */ + +glp_file *glp_open(const char *name, const char *mode) +{ glp_file *f; + int flag; + void *file; + if (strcmp(mode, "r") == 0 || strcmp(mode, "rb") == 0) + flag = 0; + else if (strcmp(mode, "w") == 0 || strcmp(mode, "wb") == 0) + flag = IOWRT; +#if 1 /* 08/V-2014 */ + else if (strcmp(mode, "a") == 0 || strcmp(mode, "ab") == 0) + flag = IOWRT; +#endif + else + xerror("glp_open: invalid mode string\n"); + if (strcmp(name, "/dev/null") == 0) + { flag |= IONULL; + file = NULL; + } + else if (strcmp(name, "/dev/stdin") == 0) + { flag |= IOSTD; + file = stdin; + } + else if (strcmp(name, "/dev/stdout") == 0) + { flag |= IOSTD; + file = stdout; + } + else if (strcmp(name, "/dev/stderr") == 0) + { flag |= IOSTD; + file = stderr; + } + else + { char *ext = strrchr(name, '.'); + if (ext == NULL || strcmp(ext, ".gz") != 0) + { file = fopen(name, mode); + if (file == NULL) + { put_err_msg(strerror(errno)); + return NULL; + } + } + else + { flag |= IOGZIP; + if (strcmp(mode, "r") == 0) + mode = "rb"; + else if (strcmp(mode, "w") == 0) + mode = "wb"; +#if 1 /* 08/V-2014; this mode seems not to work */ + else if (strcmp(mode, "a") == 0) + mode = "ab"; +#endif + file = gzopen(name, mode); + if (file == NULL) + { put_err_msg(strerror(errno)); + return NULL; + } + } + } + f = talloc(1, glp_file); + f->base = talloc(BUFSIZ, char); + f->size = BUFSIZ; + f->ptr = f->base; + f->cnt = 0; + f->flag = flag; + f->file = file; + return f; +} + +/*********************************************************************** +* NAME +* +* glp_eof - test end-of-file indicator +* +* SYNOPSIS +* +* int glp_eof(glp_file *f); +* +* DESCRIPTION +* +* The routine glp_eof tests the end-of-file indicator for the stream +* pointed to by f. +* +* RETURNS +* +* The routine glp_eof returns non-zero if and only if the end-of-file +* indicator is set for the specified stream. */ + +int glp_eof(glp_file *f) +{ return + f->flag & IOEOF; +} + +/*********************************************************************** +* NAME +* +* glp_ioerr - test I/O error indicator +* +* SYNOPSIS +* +* int glp_ioerr(glp_file *f); +* +* DESCRIPTION +* +* The routine glp_ioerr tests the I/O error indicator for the stream +* pointed to by f. +* +* RETURNS +* +* The routine glp_ioerr returns non-zero if and only if the I/O error +* indicator is set for the specified stream. */ + +int glp_ioerr(glp_file *f) +{ return + f->flag & IOERR; +} + +/*********************************************************************** +* NAME +* +* glp_read - read data from stream +* +* SYNOPSIS +* +* int glp_read(glp_file *f, void *buf, int nnn); +* +* DESCRIPTION +* +* The routine glp_read reads, into the buffer pointed to by buf, up to +* nnn bytes, from the stream pointed to by f. +* +* RETURNS +* +* The routine glp_read returns the number of bytes successfully read +* (which may be less than nnn). If an end-of-file is encountered, the +* end-of-file indicator for the stream is set and glp_read returns +* zero. If a read error occurs, the error indicator for the stream is +* set and glp_read returns a negative value. */ + +int glp_read(glp_file *f, void *buf, int nnn) +{ int nrd, cnt; + if (f->flag & IOWRT) + xerror("glp_read: attempt to read from output stream\n"); + if (nnn < 1) + xerror("glp_read: nnn = %d; invalid parameter\n", nnn); + for (nrd = 0; nrd < nnn; nrd += cnt) + { if (f->cnt == 0) + { /* buffer is empty; fill it */ + if (f->flag & IONULL) + cnt = 0; + else if (!(f->flag & IOGZIP)) + { cnt = fread(f->base, 1, f->size, (FILE *)(f->file)); + if (ferror((FILE *)(f->file))) + { f->flag |= IOERR; + put_err_msg(strerror(errno)); + return EOF; + } + } + else + { int errnum; + const char *msg; + cnt = gzread((gzFile)(f->file), f->base, f->size); + if (cnt < 0) + { f->flag |= IOERR; + msg = gzerror((gzFile)(f->file), &errnum); + if (errnum == Z_ERRNO) + put_err_msg(strerror(errno)); + else + put_err_msg(msg); + return EOF; + } + } + if (cnt == 0) + { if (nrd == 0) + f->flag |= IOEOF; + break; + } + f->ptr = f->base; + f->cnt = cnt; + } + cnt = nnn - nrd; + if (cnt > f->cnt) + cnt = f->cnt; + memcpy((char *)buf + nrd, f->ptr, cnt); + f->ptr += cnt; + f->cnt -= cnt; + } + return nrd; +} + +/*********************************************************************** +* NAME +* +* glp_getc - read character from stream +* +* SYNOPSIS +* +* int glp_getc(glp_file *f); +* +* DESCRIPTION +* +* The routine glp_getc obtains a next character as an unsigned char +* converted to an int from the input stream pointed to by f. +* +* RETURNS +* +* The routine glp_getc returns the next character obtained. However, +* if an end-of-file is encountered or a read error occurs, the routine +* returns EOF. (An end-of-file and a read error can be distinguished +* by use of the routines glp_eof and glp_ioerr.) */ + +int glp_getc(glp_file *f) +{ unsigned char buf[1]; + if (f->flag & IOWRT) + xerror("glp_getc: attempt to read from output stream\n"); + if (glp_read(f, buf, 1) != 1) + return EOF; + return buf[0]; +} + +/*********************************************************************** +* do_flush - flush output stream +* +* This routine causes buffered data for the specified output stream to +* be written to the associated file. +* +* If the operation was successful, the routine returns zero, otherwise +* non-zero. */ + +static int do_flush(glp_file *f) +{ xassert(f->flag & IOWRT); + if (f->cnt > 0) + { if (f->flag & IONULL) + ; + else if (!(f->flag & IOGZIP)) + { if ((int)fwrite(f->base, 1, f->cnt, (FILE *)(f->file)) + != f->cnt) + { f->flag |= IOERR; + put_err_msg(strerror(errno)); + return EOF; + } + } + else + { int errnum; + const char *msg; + if (gzwrite((gzFile)(f->file), f->base, f->cnt) != f->cnt) + { f->flag |= IOERR; + msg = gzerror((gzFile)(f->file), &errnum); + if (errnum == Z_ERRNO) + put_err_msg(strerror(errno)); + else + put_err_msg(msg); + return EOF; + } + } + } + f->ptr = f->base; + f->cnt = 0; + return 0; +} + +/*********************************************************************** +* NAME +* +* glp_write - write data to stream +* +* SYNOPSIS +* +* int glp_write(glp_file *f, const void *buf, int nnn); +* +* DESCRIPTION +* +* The routine glp_write writes, from the buffer pointed to by buf, up +* to nnn bytes, to the stream pointed to by f. +* +* RETURNS +* +* The routine glp_write returns the number of bytes successfully +* written (which is equal to nnn). If a write error occurs, the error +* indicator for the stream is set and glp_write returns a negative +* value. */ + +int glp_write(glp_file *f, const void *buf, int nnn) +{ int nwr, cnt; + if (!(f->flag & IOWRT)) + xerror("glp_write: attempt to write to input stream\n"); + if (nnn < 1) + xerror("glp_write: nnn = %d; invalid parameter\n", nnn); + for (nwr = 0; nwr < nnn; nwr += cnt) + { cnt = nnn - nwr; + if (cnt > f->size - f->cnt) + cnt = f->size - f->cnt; + memcpy(f->ptr, (const char *)buf + nwr, cnt); + f->ptr += cnt; + f->cnt += cnt; + if (f->cnt == f->size) + { /* buffer is full; flush it */ + if (do_flush(f) != 0) + return EOF; + } + } + return nwr; +} + +/*********************************************************************** +* NAME +* +* glp_format - write formatted data to stream +* +* SYNOPSIS +* +* int glp_format(glp_file *f, const char *fmt, ...); +* +* DESCRIPTION +* +* The routine glp_format writes formatted data to the stream pointed +* to by f. The format control string pointed to by fmt specifies how +* subsequent arguments are converted for output. +* +* RETURNS +* +* The routine glp_format returns the number of characters written, or +* a negative value if an output error occurs. */ + +int glp_format(glp_file *f, const char *fmt, ...) +{ ENV *env = get_env_ptr(); + va_list arg; + int nnn; + if (!(f->flag & IOWRT)) + xerror("glp_format: attempt to write to input stream\n"); + va_start(arg, fmt); + nnn = vsprintf(env->term_buf, fmt, arg); + xassert(0 <= nnn && nnn < TBUF_SIZE); + va_end(arg); + return nnn == 0 ? 0 : glp_write(f, env->term_buf, nnn); +} + +/*********************************************************************** +* NAME +* +* glp_close - close stream +* +* SYNOPSIS +* +* int glp_close(glp_file *f); +* +* DESCRIPTION +* +* The routine glp_close closes the stream pointed to by f. +* +* RETURNS +* +* If the operation was successful, the routine returns zero, otherwise +* non-zero. */ + +int glp_close(glp_file *f) +{ int ret = 0; + if (f->flag & IOWRT) + { if (do_flush(f) != 0) + ret = EOF; + } + if (f->flag & (IONULL | IOSTD)) + ; + else if (!(f->flag & IOGZIP)) + { if (fclose((FILE *)(f->file)) != 0) + { if (ret == 0) + { put_err_msg(strerror(errno)); + ret = EOF; + } + } + } + else + { int errnum; + errnum = gzclose((gzFile)(f->file)); + if (errnum == Z_OK) + ; + else if (errnum == Z_ERRNO) + { if (ret == 0) + { put_err_msg(strerror(errno)); + ret = EOF; + } + } +#if 1 /* FIXME */ + else + { if (ret == 0) + { ENV *env = get_env_ptr(); + sprintf(env->term_buf, "gzclose returned %d", errnum); + put_err_msg(env->term_buf); + ret = EOF; + } + } +#endif + } + tfree(f->base); + tfree(f); + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/env/time.c b/resources/3rdparty/glpk-4.57/src/env/time.c new file mode 100644 index 000000000..e5aac0b0b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/env/time.c @@ -0,0 +1,159 @@ +/* time.c (standard time) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "env.h" +#include "jd.h" + +/*********************************************************************** +* NAME +* +* glp_time - determine current universal time +* +* SYNOPSIS +* +* double glp_time(void); +* +* RETURNS +* +* The routine glp_time returns the current universal time (UTC), in +* milliseconds, elapsed since 00:00:00 GMT January 1, 1970. */ + +#define EPOCH 2440588 /* jday(1, 1, 1970) */ + +/* POSIX version ******************************************************/ + +#if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY) + +#include +#include + +double glp_time(void) +{ struct timeval tv; + struct tm *tm; + int j; + double t; + gettimeofday(&tv, NULL); + tm = gmtime(&tv.tv_sec); + j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year); + xassert(j >= 0); + t = ((((double)(j - EPOCH) * 24.0 + (double)tm->tm_hour) * 60.0 + + (double)tm->tm_min) * 60.0 + (double)tm->tm_sec) * 1000.0 + + (double)(tv.tv_usec / 1000); + return t; +} + +/* MS Windows version *************************************************/ + +#elif defined(__WOE__) + +#include + +double glp_time(void) +{ SYSTEMTIME st; + int j; + double t; + GetSystemTime(&st); + j = jday(st.wDay, st.wMonth, st.wYear); + xassert(j >= 0); + t = ((((double)(j - EPOCH) * 24.0 + (double)st.wHour) * 60.0 + + (double)st.wMinute) * 60.0 + (double)st.wSecond) * 1000.0 + + (double)st.wMilliseconds; + return t; +} + +/* portable ANSI C version ********************************************/ + +#else + +#include + +double glp_time(void) +{ time_t timer; + struct tm *tm; + int j; + double t; + timer = time(NULL); + tm = gmtime(&timer); + j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year); + xassert(j >= 0); + t = ((((double)(j - EPOCH) * 24.0 + (double)tm->tm_hour) * 60.0 + + (double)tm->tm_min) * 60.0 + (double)tm->tm_sec) * 1000.0; + return t; +} + +#endif + +/*********************************************************************** +* NAME +* +* glp_difftime - compute difference between two time values +* +* SYNOPSIS +* +* double glp_difftime(double t1, double t0); +* +* RETURNS +* +* The routine glp_difftime returns the difference between two time +* values t1 and t0, expressed in seconds. */ + +double glp_difftime(double t1, double t0) +{ return + (t1 - t0) / 1000.0; +} + +/**********************************************************************/ + +#ifdef GLP_TEST +#include + +int main(void) +{ int ttt, ss, mm, hh, day, month, year; + double t; + t = glp_time(); + xprintf("t = %.f\n", t); + assert(floor(t) == t); + ttt = (int)fmod(t, 1000.0); + t = (t - (double)ttt) / 1000.0; + assert(floor(t) == t); + ss = (int)fmod(t, 60.0); + t = (t - (double)ss) / 60.0; + assert(floor(t) == t); + mm = (int)fmod(t, 60.0); + t = (t - (double)mm) / 60.0; + assert(floor(t) == t); + hh = (int)fmod(t, 24.0); + t = (t - (double)hh) / 24.0; + assert(floor(t) == t); + assert(jdate((int)t + EPOCH, &day, &month, &year) == 0); + printf("%04d-%02d-%02d %02d:%02d:%02d.%03d\n", + year, month, day, hh, mm, ss, ttt); + return 0; +} +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/env/tls.c b/resources/3rdparty/glpk-4.57/src/env/tls.c new file mode 100644 index 000000000..3ffa11437 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/env/tls.c @@ -0,0 +1,72 @@ +/* tls.c (thread local storage) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2001-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" + +static void *tls = NULL; +/* NOTE: in a re-entrant version of the package this variable should be + * placed in the Thread Local Storage (TLS) */ + +/*********************************************************************** +* NAME +* +* tls_set_ptr - store global pointer in TLS +* +* SYNOPSIS +* +* #include "env.h" +* void tls_set_ptr(void *ptr); +* +* DESCRIPTION +* +* The routine tls_set_ptr stores a pointer specified by the parameter +* ptr in the Thread Local Storage (TLS). */ + +void tls_set_ptr(void *ptr) +{ tls = ptr; + return; +} + +/*********************************************************************** +* NAME +* +* tls_get_ptr - retrieve global pointer from TLS +* +* SYNOPSIS +* +* #include "env.h" +* void *tls_get_ptr(void); +* +* RETURNS +* +* The routine tls_get_ptr returns a pointer previously stored by the +* routine tls_set_ptr. If the latter has not been called yet, NULL is +* returned. */ + +void *tls_get_ptr(void) +{ void *ptr; + ptr = tls; + return ptr; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi01.c b/resources/3rdparty/glpk-4.57/src/glpapi01.c new file mode 100644 index 000000000..376d98c47 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi01.c @@ -0,0 +1,1579 @@ +/* glpapi01.c (problem creating and modifying routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpios.h" + +/* CAUTION: DO NOT CHANGE THE LIMITS BELOW */ + +#define M_MAX 100000000 /* = 100*10^6 */ +/* maximal number of rows in the problem object */ + +#define N_MAX 100000000 /* = 100*10^6 */ +/* maximal number of columns in the problem object */ + +#define NNZ_MAX 500000000 /* = 500*10^6 */ +/* maximal number of constraint coefficients in the problem object */ + +/*********************************************************************** +* NAME +* +* glp_create_prob - create problem object +* +* SYNOPSIS +* +* glp_prob *glp_create_prob(void); +* +* DESCRIPTION +* +* The routine glp_create_prob creates a new problem object, which is +* initially "empty", i.e. has no rows and columns. +* +* RETURNS +* +* The routine returns a pointer to the object created, which should be +* used in any subsequent operations on this object. */ + +static void create_prob(glp_prob *lp) +{ lp->magic = GLP_PROB_MAGIC; + lp->pool = dmp_create_pool(); +#if 0 /* 08/III-2014 */ +#if 0 /* 17/XI-2009 */ + lp->cps = xmalloc(sizeof(struct LPXCPS)); + lpx_reset_parms(lp); +#else + lp->parms = NULL; +#endif +#endif + lp->tree = NULL; +#if 0 + lp->lwa = 0; + lp->cwa = NULL; +#endif + /* LP/MIP data */ + lp->name = NULL; + lp->obj = NULL; + lp->dir = GLP_MIN; + lp->c0 = 0.0; + lp->m_max = 100; + lp->n_max = 200; + lp->m = lp->n = 0; + lp->nnz = 0; + lp->row = xcalloc(1+lp->m_max, sizeof(GLPROW *)); + lp->col = xcalloc(1+lp->n_max, sizeof(GLPCOL *)); + lp->r_tree = lp->c_tree = NULL; + /* basis factorization */ + lp->valid = 0; + lp->head = xcalloc(1+lp->m_max, sizeof(int)); +#if 0 /* 08/III-2014 */ + lp->bfcp = NULL; +#endif + lp->bfd = NULL; + /* basic solution (LP) */ + lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; + lp->obj_val = 0.0; + lp->it_cnt = 0; + lp->some = 0; + /* interior-point solution (LP) */ + lp->ipt_stat = GLP_UNDEF; + lp->ipt_obj = 0.0; + /* integer solution (MIP) */ + lp->mip_stat = GLP_UNDEF; + lp->mip_obj = 0.0; + return; +} + +glp_prob *glp_create_prob(void) +{ glp_prob *lp; + lp = xmalloc(sizeof(glp_prob)); + create_prob(lp); + return lp; +} + +/*********************************************************************** +* NAME +* +* glp_set_prob_name - assign (change) problem name +* +* SYNOPSIS +* +* void glp_set_prob_name(glp_prob *lp, const char *name); +* +* DESCRIPTION +* +* The routine glp_set_prob_name assigns a given symbolic name (1 up to +* 255 characters) to the specified problem object. +* +* If the parameter name is NULL or empty string, the routine erases an +* existing symbolic name of the problem object. */ + +void glp_set_prob_name(glp_prob *lp, const char *name) +{ glp_tree *tree = lp->tree; + if (tree != NULL && tree->reason != 0) + xerror("glp_set_prob_name: operation not allowed\n"); + if (lp->name != NULL) + { dmp_free_atom(lp->pool, lp->name, strlen(lp->name)+1); + lp->name = NULL; + } + if (!(name == NULL || name[0] == '\0')) + { int k; + for (k = 0; name[k] != '\0'; k++) + { if (k == 256) + xerror("glp_set_prob_name: problem name too long\n"); + if (iscntrl((unsigned char)name[k])) + xerror("glp_set_prob_name: problem name contains invalid" + " character(s)\n"); + } + lp->name = dmp_get_atom(lp->pool, strlen(name)+1); + strcpy(lp->name, name); + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_set_obj_name - assign (change) objective function name +* +* SYNOPSIS +* +* void glp_set_obj_name(glp_prob *lp, const char *name); +* +* DESCRIPTION +* +* The routine glp_set_obj_name assigns a given symbolic name (1 up to +* 255 characters) to the objective function of the specified problem +* object. +* +* If the parameter name is NULL or empty string, the routine erases an +* existing name of the objective function. */ + +void glp_set_obj_name(glp_prob *lp, const char *name) +{ glp_tree *tree = lp->tree; + if (tree != NULL && tree->reason != 0) + xerror("glp_set_obj_name: operation not allowed\n"); + if (lp->obj != NULL) + { dmp_free_atom(lp->pool, lp->obj, strlen(lp->obj)+1); + lp->obj = NULL; + } + if (!(name == NULL || name[0] == '\0')) + { int k; + for (k = 0; name[k] != '\0'; k++) + { if (k == 256) + xerror("glp_set_obj_name: objective name too long\n"); + if (iscntrl((unsigned char)name[k])) + xerror("glp_set_obj_name: objective name contains invali" + "d character(s)\n"); + } + lp->obj = dmp_get_atom(lp->pool, strlen(name)+1); + strcpy(lp->obj, name); + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_set_obj_dir - set (change) optimization direction flag +* +* SYNOPSIS +* +* void glp_set_obj_dir(glp_prob *lp, int dir); +* +* DESCRIPTION +* +* The routine glp_set_obj_dir sets (changes) optimization direction +* flag (i.e. "sense" of the objective function) as specified by the +* parameter dir: +* +* GLP_MIN - minimization; +* GLP_MAX - maximization. */ + +void glp_set_obj_dir(glp_prob *lp, int dir) +{ glp_tree *tree = lp->tree; + if (tree != NULL && tree->reason != 0) + xerror("glp_set_obj_dir: operation not allowed\n"); + if (!(dir == GLP_MIN || dir == GLP_MAX)) + xerror("glp_set_obj_dir: dir = %d; invalid direction flag\n", + dir); + lp->dir = dir; + return; +} + +/*********************************************************************** +* NAME +* +* glp_add_rows - add new rows to problem object +* +* SYNOPSIS +* +* int glp_add_rows(glp_prob *lp, int nrs); +* +* DESCRIPTION +* +* The routine glp_add_rows adds nrs rows (constraints) to the specified +* problem object. New rows are always added to the end of the row list, +* so the ordinal numbers of existing rows remain unchanged. +* +* Being added each new row is initially free (unbounded) and has empty +* list of the constraint coefficients. +* +* RETURNS +* +* The routine glp_add_rows returns the ordinal number of the first new +* row added to the problem object. */ + +int glp_add_rows(glp_prob *lp, int nrs) +{ glp_tree *tree = lp->tree; + GLPROW *row; + int m_new, i; + /* determine new number of rows */ + if (nrs < 1) + xerror("glp_add_rows: nrs = %d; invalid number of rows\n", + nrs); + if (nrs > M_MAX - lp->m) + xerror("glp_add_rows: nrs = %d; too many rows\n", nrs); + m_new = lp->m + nrs; + /* increase the room, if necessary */ + if (lp->m_max < m_new) + { GLPROW **save = lp->row; + while (lp->m_max < m_new) + { lp->m_max += lp->m_max; + xassert(lp->m_max > 0); + } + lp->row = xcalloc(1+lp->m_max, sizeof(GLPROW *)); + memcpy(&lp->row[1], &save[1], lp->m * sizeof(GLPROW *)); + xfree(save); + /* do not forget about the basis header */ + xfree(lp->head); + lp->head = xcalloc(1+lp->m_max, sizeof(int)); + } + /* add new rows to the end of the row list */ + for (i = lp->m+1; i <= m_new; i++) + { /* create row descriptor */ + lp->row[i] = row = dmp_get_atom(lp->pool, sizeof(GLPROW)); + row->i = i; + row->name = NULL; + row->node = NULL; +#if 1 /* 20/IX-2008 */ + row->level = 0; + row->origin = 0; + row->klass = 0; + if (tree != NULL) + { switch (tree->reason) + { case 0: + break; + case GLP_IROWGEN: + xassert(tree->curr != NULL); + row->level = tree->curr->level; + row->origin = GLP_RF_LAZY; + break; + case GLP_ICUTGEN: + xassert(tree->curr != NULL); + row->level = tree->curr->level; + row->origin = GLP_RF_CUT; + break; + default: + xassert(tree != tree); + } + } +#endif + row->type = GLP_FR; + row->lb = row->ub = 0.0; + row->ptr = NULL; + row->rii = 1.0; + row->stat = GLP_BS; +#if 0 + row->bind = -1; +#else + row->bind = 0; +#endif + row->prim = row->dual = 0.0; + row->pval = row->dval = 0.0; + row->mipx = 0.0; + } + /* set new number of rows */ + lp->m = m_new; + /* invalidate the basis factorization */ + lp->valid = 0; +#if 1 + if (tree != NULL && tree->reason != 0) tree->reopt = 1; +#endif + /* return the ordinal number of the first row added */ + return m_new - nrs + 1; +} + +/*********************************************************************** +* NAME +* +* glp_add_cols - add new columns to problem object +* +* SYNOPSIS +* +* int glp_add_cols(glp_prob *lp, int ncs); +* +* DESCRIPTION +* +* The routine glp_add_cols adds ncs columns (structural variables) to +* the specified problem object. New columns are always added to the end +* of the column list, so the ordinal numbers of existing columns remain +* unchanged. +* +* Being added each new column is initially fixed at zero and has empty +* list of the constraint coefficients. +* +* RETURNS +* +* The routine glp_add_cols returns the ordinal number of the first new +* column added to the problem object. */ + +int glp_add_cols(glp_prob *lp, int ncs) +{ glp_tree *tree = lp->tree; + GLPCOL *col; + int n_new, j; + if (tree != NULL && tree->reason != 0) + xerror("glp_add_cols: operation not allowed\n"); + /* determine new number of columns */ + if (ncs < 1) + xerror("glp_add_cols: ncs = %d; invalid number of columns\n", + ncs); + if (ncs > N_MAX - lp->n) + xerror("glp_add_cols: ncs = %d; too many columns\n", ncs); + n_new = lp->n + ncs; + /* increase the room, if necessary */ + if (lp->n_max < n_new) + { GLPCOL **save = lp->col; + while (lp->n_max < n_new) + { lp->n_max += lp->n_max; + xassert(lp->n_max > 0); + } + lp->col = xcalloc(1+lp->n_max, sizeof(GLPCOL *)); + memcpy(&lp->col[1], &save[1], lp->n * sizeof(GLPCOL *)); + xfree(save); + } + /* add new columns to the end of the column list */ + for (j = lp->n+1; j <= n_new; j++) + { /* create column descriptor */ + lp->col[j] = col = dmp_get_atom(lp->pool, sizeof(GLPCOL)); + col->j = j; + col->name = NULL; + col->node = NULL; + col->kind = GLP_CV; + col->type = GLP_FX; + col->lb = col->ub = 0.0; + col->coef = 0.0; + col->ptr = NULL; + col->sjj = 1.0; + col->stat = GLP_NS; +#if 0 + col->bind = -1; +#else + col->bind = 0; /* the basis may remain valid */ +#endif + col->prim = col->dual = 0.0; + col->pval = col->dval = 0.0; + col->mipx = 0.0; + } + /* set new number of columns */ + lp->n = n_new; + /* return the ordinal number of the first column added */ + return n_new - ncs + 1; +} + +/*********************************************************************** +* NAME +* +* glp_set_row_name - assign (change) row name +* +* SYNOPSIS +* +* void glp_set_row_name(glp_prob *lp, int i, const char *name); +* +* DESCRIPTION +* +* The routine glp_set_row_name assigns a given symbolic name (1 up to +* 255 characters) to i-th row (auxiliary variable) of the specified +* problem object. +* +* If the parameter name is NULL or empty string, the routine erases an +* existing name of i-th row. */ + +void glp_set_row_name(glp_prob *lp, int i, const char *name) +{ glp_tree *tree = lp->tree; + GLPROW *row; + if (!(1 <= i && i <= lp->m)) + xerror("glp_set_row_name: i = %d; row number out of range\n", + i); + row = lp->row[i]; + if (tree != NULL && tree->reason != 0) + { xassert(tree->curr != NULL); + xassert(row->level == tree->curr->level); + } + if (row->name != NULL) + { if (row->node != NULL) + { xassert(lp->r_tree != NULL); + avl_delete_node(lp->r_tree, row->node); + row->node = NULL; + } + dmp_free_atom(lp->pool, row->name, strlen(row->name)+1); + row->name = NULL; + } + if (!(name == NULL || name[0] == '\0')) + { int k; + for (k = 0; name[k] != '\0'; k++) + { if (k == 256) + xerror("glp_set_row_name: i = %d; row name too long\n", + i); + if (iscntrl((unsigned char)name[k])) + xerror("glp_set_row_name: i = %d: row name contains inva" + "lid character(s)\n", i); + } + row->name = dmp_get_atom(lp->pool, strlen(name)+1); + strcpy(row->name, name); + if (lp->r_tree != NULL) + { xassert(row->node == NULL); + row->node = avl_insert_node(lp->r_tree, row->name); + avl_set_node_link(row->node, row); + } + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_set_col_name - assign (change) column name +* +* SYNOPSIS +* +* void glp_set_col_name(glp_prob *lp, int j, const char *name); +* +* DESCRIPTION +* +* The routine glp_set_col_name assigns a given symbolic name (1 up to +* 255 characters) to j-th column (structural variable) of the specified +* problem object. +* +* If the parameter name is NULL or empty string, the routine erases an +* existing name of j-th column. */ + +void glp_set_col_name(glp_prob *lp, int j, const char *name) +{ glp_tree *tree = lp->tree; + GLPCOL *col; + if (tree != NULL && tree->reason != 0) + xerror("glp_set_col_name: operation not allowed\n"); + if (!(1 <= j && j <= lp->n)) + xerror("glp_set_col_name: j = %d; column number out of range\n" + , j); + col = lp->col[j]; + if (col->name != NULL) + { if (col->node != NULL) + { xassert(lp->c_tree != NULL); + avl_delete_node(lp->c_tree, col->node); + col->node = NULL; + } + dmp_free_atom(lp->pool, col->name, strlen(col->name)+1); + col->name = NULL; + } + if (!(name == NULL || name[0] == '\0')) + { int k; + for (k = 0; name[k] != '\0'; k++) + { if (k == 256) + xerror("glp_set_col_name: j = %d; column name too long\n" + , j); + if (iscntrl((unsigned char)name[k])) + xerror("glp_set_col_name: j = %d: column name contains i" + "nvalid character(s)\n", j); + } + col->name = dmp_get_atom(lp->pool, strlen(name)+1); + strcpy(col->name, name); + if (lp->c_tree != NULL && col->name != NULL) + { xassert(col->node == NULL); + col->node = avl_insert_node(lp->c_tree, col->name); + avl_set_node_link(col->node, col); + } + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_set_row_bnds - set (change) row bounds +* +* SYNOPSIS +* +* void glp_set_row_bnds(glp_prob *lp, int i, int type, double lb, +* double ub); +* +* DESCRIPTION +* +* The routine glp_set_row_bnds sets (changes) the type and bounds of +* i-th row (auxiliary variable) of the specified problem object. +* +* Parameters type, lb, and ub specify the type, lower bound, and upper +* bound, respectively, as follows: +* +* Type Bounds Comments +* ------------------------------------------------------ +* GLP_FR -inf < x < +inf Free variable +* GLP_LO lb <= x < +inf Variable with lower bound +* GLP_UP -inf < x <= ub Variable with upper bound +* GLP_DB lb <= x <= ub Double-bounded variable +* GLP_FX x = lb Fixed variable +* +* where x is the auxiliary variable associated with i-th row. +* +* If the row has no lower bound, the parameter lb is ignored. If the +* row has no upper bound, the parameter ub is ignored. If the row is +* an equality constraint (i.e. the corresponding auxiliary variable is +* of fixed type), only the parameter lb is used while the parameter ub +* is ignored. */ + +void glp_set_row_bnds(glp_prob *lp, int i, int type, double lb, + double ub) +{ GLPROW *row; + if (!(1 <= i && i <= lp->m)) + xerror("glp_set_row_bnds: i = %d; row number out of range\n", + i); + row = lp->row[i]; + row->type = type; + switch (type) + { case GLP_FR: + row->lb = row->ub = 0.0; + if (row->stat != GLP_BS) row->stat = GLP_NF; + break; + case GLP_LO: + row->lb = lb, row->ub = 0.0; + if (row->stat != GLP_BS) row->stat = GLP_NL; + break; + case GLP_UP: + row->lb = 0.0, row->ub = ub; + if (row->stat != GLP_BS) row->stat = GLP_NU; + break; + case GLP_DB: + row->lb = lb, row->ub = ub; + if (!(row->stat == GLP_BS || + row->stat == GLP_NL || row->stat == GLP_NU)) + row->stat = (fabs(lb) <= fabs(ub) ? GLP_NL : GLP_NU); + break; + case GLP_FX: + row->lb = row->ub = lb; + if (row->stat != GLP_BS) row->stat = GLP_NS; + break; + default: + xerror("glp_set_row_bnds: i = %d; type = %d; invalid row ty" + "pe\n", i, type); + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_set_col_bnds - set (change) column bounds +* +* SYNOPSIS +* +* void glp_set_col_bnds(glp_prob *lp, int j, int type, double lb, +* double ub); +* +* DESCRIPTION +* +* The routine glp_set_col_bnds sets (changes) the type and bounds of +* j-th column (structural variable) of the specified problem object. +* +* Parameters type, lb, and ub specify the type, lower bound, and upper +* bound, respectively, as follows: +* +* Type Bounds Comments +* ------------------------------------------------------ +* GLP_FR -inf < x < +inf Free variable +* GLP_LO lb <= x < +inf Variable with lower bound +* GLP_UP -inf < x <= ub Variable with upper bound +* GLP_DB lb <= x <= ub Double-bounded variable +* GLP_FX x = lb Fixed variable +* +* where x is the structural variable associated with j-th column. +* +* If the column has no lower bound, the parameter lb is ignored. If the +* column has no upper bound, the parameter ub is ignored. If the column +* is of fixed type, only the parameter lb is used while the parameter +* ub is ignored. */ + +void glp_set_col_bnds(glp_prob *lp, int j, int type, double lb, + double ub) +{ GLPCOL *col; + if (!(1 <= j && j <= lp->n)) + xerror("glp_set_col_bnds: j = %d; column number out of range\n" + , j); + col = lp->col[j]; + col->type = type; + switch (type) + { case GLP_FR: + col->lb = col->ub = 0.0; + if (col->stat != GLP_BS) col->stat = GLP_NF; + break; + case GLP_LO: + col->lb = lb, col->ub = 0.0; + if (col->stat != GLP_BS) col->stat = GLP_NL; + break; + case GLP_UP: + col->lb = 0.0, col->ub = ub; + if (col->stat != GLP_BS) col->stat = GLP_NU; + break; + case GLP_DB: + col->lb = lb, col->ub = ub; + if (!(col->stat == GLP_BS || + col->stat == GLP_NL || col->stat == GLP_NU)) + col->stat = (fabs(lb) <= fabs(ub) ? GLP_NL : GLP_NU); + break; + case GLP_FX: + col->lb = col->ub = lb; + if (col->stat != GLP_BS) col->stat = GLP_NS; + break; + default: + xerror("glp_set_col_bnds: j = %d; type = %d; invalid column" + " type\n", j, type); + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_set_obj_coef - set (change) obj. coefficient or constant term +* +* SYNOPSIS +* +* void glp_set_obj_coef(glp_prob *lp, int j, double coef); +* +* DESCRIPTION +* +* The routine glp_set_obj_coef sets (changes) objective coefficient at +* j-th column (structural variable) of the specified problem object. +* +* If the parameter j is 0, the routine sets (changes) the constant term +* ("shift") of the objective function. */ + +void glp_set_obj_coef(glp_prob *lp, int j, double coef) +{ glp_tree *tree = lp->tree; + if (tree != NULL && tree->reason != 0) + xerror("glp_set_obj_coef: operation not allowed\n"); + if (!(0 <= j && j <= lp->n)) + xerror("glp_set_obj_coef: j = %d; column number out of range\n" + , j); + if (j == 0) + lp->c0 = coef; + else + lp->col[j]->coef = coef; + return; +} + +/*********************************************************************** +* NAME +* +* glp_set_mat_row - set (replace) row of the constraint matrix +* +* SYNOPSIS +* +* void glp_set_mat_row(glp_prob *lp, int i, int len, const int ind[], +* const double val[]); +* +* DESCRIPTION +* +* The routine glp_set_mat_row stores (replaces) the contents of i-th +* row of the constraint matrix of the specified problem object. +* +* Column indices and numeric values of new row elements must be placed +* in locations ind[1], ..., ind[len] and val[1], ..., val[len], where +* 0 <= len <= n is the new length of i-th row, n is the current number +* of columns in the problem object. Elements with identical column +* indices are not allowed. Zero elements are allowed, but they are not +* stored in the constraint matrix. +* +* If the parameter len is zero, the parameters ind and/or val can be +* specified as NULL. */ + +void glp_set_mat_row(glp_prob *lp, int i, int len, const int ind[], + const double val[]) +{ glp_tree *tree = lp->tree; + GLPROW *row; + GLPCOL *col; + GLPAIJ *aij, *next; + int j, k; + /* obtain pointer to i-th row */ + if (!(1 <= i && i <= lp->m)) + xerror("glp_set_mat_row: i = %d; row number out of range\n", + i); + row = lp->row[i]; + if (tree != NULL && tree->reason != 0) + { xassert(tree->curr != NULL); + xassert(row->level == tree->curr->level); + } + /* remove all existing elements from i-th row */ + while (row->ptr != NULL) + { /* take next element in the row */ + aij = row->ptr; + /* remove the element from the row list */ + row->ptr = aij->r_next; + /* obtain pointer to corresponding column */ + col = aij->col; + /* remove the element from the column list */ + if (aij->c_prev == NULL) + col->ptr = aij->c_next; + else + aij->c_prev->c_next = aij->c_next; + if (aij->c_next == NULL) + ; + else + aij->c_next->c_prev = aij->c_prev; + /* return the element to the memory pool */ + dmp_free_atom(lp->pool, aij, sizeof(GLPAIJ)), lp->nnz--; + /* if the corresponding column is basic, invalidate the basis + factorization */ + if (col->stat == GLP_BS) lp->valid = 0; + } + /* store new contents of i-th row */ + if (!(0 <= len && len <= lp->n)) + xerror("glp_set_mat_row: i = %d; len = %d; invalid row length " + "\n", i, len); + if (len > NNZ_MAX - lp->nnz) + xerror("glp_set_mat_row: i = %d; len = %d; too many constraint" + " coefficients\n", i, len); + for (k = 1; k <= len; k++) + { /* take number j of corresponding column */ + j = ind[k]; + /* obtain pointer to j-th column */ + if (!(1 <= j && j <= lp->n)) + xerror("glp_set_mat_row: i = %d; ind[%d] = %d; column index" + " out of range\n", i, k, j); + col = lp->col[j]; + /* if there is element with the same column index, it can only + be found in the beginning of j-th column list */ + if (col->ptr != NULL && col->ptr->row->i == i) + xerror("glp_set_mat_row: i = %d; ind[%d] = %d; duplicate co" + "lumn indices not allowed\n", i, k, j); + /* create new element */ + aij = dmp_get_atom(lp->pool, sizeof(GLPAIJ)), lp->nnz++; + aij->row = row; + aij->col = col; + aij->val = val[k]; + /* add the new element to the beginning of i-th row and j-th + column lists */ + aij->r_prev = NULL; + aij->r_next = row->ptr; + aij->c_prev = NULL; + aij->c_next = col->ptr; + if (aij->r_next != NULL) aij->r_next->r_prev = aij; + if (aij->c_next != NULL) aij->c_next->c_prev = aij; + row->ptr = col->ptr = aij; + /* if the corresponding column is basic, invalidate the basis + factorization */ + if (col->stat == GLP_BS && aij->val != 0.0) lp->valid = 0; + } + /* remove zero elements from i-th row */ + for (aij = row->ptr; aij != NULL; aij = next) + { next = aij->r_next; + if (aij->val == 0.0) + { /* remove the element from the row list */ + if (aij->r_prev == NULL) + row->ptr = next; + else + aij->r_prev->r_next = next; + if (next == NULL) + ; + else + next->r_prev = aij->r_prev; + /* remove the element from the column list */ + xassert(aij->c_prev == NULL); + aij->col->ptr = aij->c_next; + if (aij->c_next != NULL) aij->c_next->c_prev = NULL; + /* return the element to the memory pool */ + dmp_free_atom(lp->pool, aij, sizeof(GLPAIJ)), lp->nnz--; + } + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_set_mat_col - set (replace) column of the constraint matrix +* +* SYNOPSIS +* +* void glp_set_mat_col(glp_prob *lp, int j, int len, const int ind[], +* const double val[]); +* +* DESCRIPTION +* +* The routine glp_set_mat_col stores (replaces) the contents of j-th +* column of the constraint matrix of the specified problem object. +* +* Row indices and numeric values of new column elements must be placed +* in locations ind[1], ..., ind[len] and val[1], ..., val[len], where +* 0 <= len <= m is the new length of j-th column, m is the current +* number of rows in the problem object. Elements with identical column +* indices are not allowed. Zero elements are allowed, but they are not +* stored in the constraint matrix. +* +* If the parameter len is zero, the parameters ind and/or val can be +* specified as NULL. */ + +void glp_set_mat_col(glp_prob *lp, int j, int len, const int ind[], + const double val[]) +{ glp_tree *tree = lp->tree; + GLPROW *row; + GLPCOL *col; + GLPAIJ *aij, *next; + int i, k; + if (tree != NULL && tree->reason != 0) + xerror("glp_set_mat_col: operation not allowed\n"); + /* obtain pointer to j-th column */ + if (!(1 <= j && j <= lp->n)) + xerror("glp_set_mat_col: j = %d; column number out of range\n", + j); + col = lp->col[j]; + /* remove all existing elements from j-th column */ + while (col->ptr != NULL) + { /* take next element in the column */ + aij = col->ptr; + /* remove the element from the column list */ + col->ptr = aij->c_next; + /* obtain pointer to corresponding row */ + row = aij->row; + /* remove the element from the row list */ + if (aij->r_prev == NULL) + row->ptr = aij->r_next; + else + aij->r_prev->r_next = aij->r_next; + if (aij->r_next == NULL) + ; + else + aij->r_next->r_prev = aij->r_prev; + /* return the element to the memory pool */ + dmp_free_atom(lp->pool, aij, sizeof(GLPAIJ)), lp->nnz--; + } + /* store new contents of j-th column */ + if (!(0 <= len && len <= lp->m)) + xerror("glp_set_mat_col: j = %d; len = %d; invalid column leng" + "th\n", j, len); + if (len > NNZ_MAX - lp->nnz) + xerror("glp_set_mat_col: j = %d; len = %d; too many constraint" + " coefficients\n", j, len); + for (k = 1; k <= len; k++) + { /* take number i of corresponding row */ + i = ind[k]; + /* obtain pointer to i-th row */ + if (!(1 <= i && i <= lp->m)) + xerror("glp_set_mat_col: j = %d; ind[%d] = %d; row index ou" + "t of range\n", j, k, i); + row = lp->row[i]; + /* if there is element with the same row index, it can only be + found in the beginning of i-th row list */ + if (row->ptr != NULL && row->ptr->col->j == j) + xerror("glp_set_mat_col: j = %d; ind[%d] = %d; duplicate ro" + "w indices not allowed\n", j, k, i); + /* create new element */ + aij = dmp_get_atom(lp->pool, sizeof(GLPAIJ)), lp->nnz++; + aij->row = row; + aij->col = col; + aij->val = val[k]; + /* add the new element to the beginning of i-th row and j-th + column lists */ + aij->r_prev = NULL; + aij->r_next = row->ptr; + aij->c_prev = NULL; + aij->c_next = col->ptr; + if (aij->r_next != NULL) aij->r_next->r_prev = aij; + if (aij->c_next != NULL) aij->c_next->c_prev = aij; + row->ptr = col->ptr = aij; + } + /* remove zero elements from j-th column */ + for (aij = col->ptr; aij != NULL; aij = next) + { next = aij->c_next; + if (aij->val == 0.0) + { /* remove the element from the row list */ + xassert(aij->r_prev == NULL); + aij->row->ptr = aij->r_next; + if (aij->r_next != NULL) aij->r_next->r_prev = NULL; + /* remove the element from the column list */ + if (aij->c_prev == NULL) + col->ptr = next; + else + aij->c_prev->c_next = next; + if (next == NULL) + ; + else + next->c_prev = aij->c_prev; + /* return the element to the memory pool */ + dmp_free_atom(lp->pool, aij, sizeof(GLPAIJ)), lp->nnz--; + } + } + /* if j-th column is basic, invalidate the basis factorization */ + if (col->stat == GLP_BS) lp->valid = 0; + return; +} + +/*********************************************************************** +* NAME +* +* glp_load_matrix - load (replace) the whole constraint matrix +* +* SYNOPSIS +* +* void glp_load_matrix(glp_prob *lp, int ne, const int ia[], +* const int ja[], const double ar[]); +* +* DESCRIPTION +* +* The routine glp_load_matrix loads the constraint matrix passed in +* the arrays ia, ja, and ar into the specified problem object. Before +* loading the current contents of the constraint matrix is destroyed. +* +* Constraint coefficients (elements of the constraint matrix) must be +* specified as triplets (ia[k], ja[k], ar[k]) for k = 1, ..., ne, +* where ia[k] is the row index, ja[k] is the column index, ar[k] is a +* numeric value of corresponding constraint coefficient. The parameter +* ne specifies the total number of (non-zero) elements in the matrix +* to be loaded. Coefficients with identical indices are not allowed. +* Zero coefficients are allowed, however, they are not stored in the +* constraint matrix. +* +* If the parameter ne is zero, the parameters ia, ja, and ar can be +* specified as NULL. */ + +void glp_load_matrix(glp_prob *lp, int ne, const int ia[], + const int ja[], const double ar[]) +{ glp_tree *tree = lp->tree; + GLPROW *row; + GLPCOL *col; + GLPAIJ *aij, *next; + int i, j, k; + if (tree != NULL && tree->reason != 0) + xerror("glp_load_matrix: operation not allowed\n"); + /* clear the constraint matrix */ + for (i = 1; i <= lp->m; i++) + { row = lp->row[i]; + while (row->ptr != NULL) + { aij = row->ptr; + row->ptr = aij->r_next; + dmp_free_atom(lp->pool, aij, sizeof(GLPAIJ)), lp->nnz--; + } + } + xassert(lp->nnz == 0); + for (j = 1; j <= lp->n; j++) lp->col[j]->ptr = NULL; + /* load the new contents of the constraint matrix and build its + row lists */ + if (ne < 0) + xerror("glp_load_matrix: ne = %d; invalid number of constraint" + " coefficients\n", ne); + if (ne > NNZ_MAX) + xerror("glp_load_matrix: ne = %d; too many constraint coeffici" + "ents\n", ne); + for (k = 1; k <= ne; k++) + { /* take indices of new element */ + i = ia[k], j = ja[k]; + /* obtain pointer to i-th row */ + if (!(1 <= i && i <= lp->m)) + xerror("glp_load_matrix: ia[%d] = %d; row index out of rang" + "e\n", k, i); + row = lp->row[i]; + /* obtain pointer to j-th column */ + if (!(1 <= j && j <= lp->n)) + xerror("glp_load_matrix: ja[%d] = %d; column index out of r" + "ange\n", k, j); + col = lp->col[j]; + /* create new element */ + aij = dmp_get_atom(lp->pool, sizeof(GLPAIJ)), lp->nnz++; + aij->row = row; + aij->col = col; + aij->val = ar[k]; + /* add the new element to the beginning of i-th row list */ + aij->r_prev = NULL; + aij->r_next = row->ptr; + if (aij->r_next != NULL) aij->r_next->r_prev = aij; + row->ptr = aij; + } + xassert(lp->nnz == ne); + /* build column lists of the constraint matrix and check elements + with identical indices */ + for (i = 1; i <= lp->m; i++) + { for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) + { /* obtain pointer to corresponding column */ + col = aij->col; + /* if there is element with identical indices, it can only + be found in the beginning of j-th column list */ + if (col->ptr != NULL && col->ptr->row->i == i) + { for (k = 1; k <= ne; k++) + if (ia[k] == i && ja[k] == col->j) break; + xerror("glp_load_mat: ia[%d] = %d; ja[%d] = %d; duplicat" + "e indices not allowed\n", k, i, k, col->j); + } + /* add the element to the beginning of j-th column list */ + aij->c_prev = NULL; + aij->c_next = col->ptr; + if (aij->c_next != NULL) aij->c_next->c_prev = aij; + col->ptr = aij; + } + } + /* remove zero elements from the constraint matrix */ + for (i = 1; i <= lp->m; i++) + { row = lp->row[i]; + for (aij = row->ptr; aij != NULL; aij = next) + { next = aij->r_next; + if (aij->val == 0.0) + { /* remove the element from the row list */ + if (aij->r_prev == NULL) + row->ptr = next; + else + aij->r_prev->r_next = next; + if (next == NULL) + ; + else + next->r_prev = aij->r_prev; + /* remove the element from the column list */ + if (aij->c_prev == NULL) + aij->col->ptr = aij->c_next; + else + aij->c_prev->c_next = aij->c_next; + if (aij->c_next == NULL) + ; + else + aij->c_next->c_prev = aij->c_prev; + /* return the element to the memory pool */ + dmp_free_atom(lp->pool, aij, sizeof(GLPAIJ)), lp->nnz--; + } + } + } + /* invalidate the basis factorization */ + lp->valid = 0; + return; +} + +/*********************************************************************** +* NAME +* +* glp_check_dup - check for duplicate elements in sparse matrix +* +* SYNOPSIS +* +* int glp_check_dup(int m, int n, int ne, const int ia[], +* const int ja[]); +* +* DESCRIPTION +* +* The routine glp_check_dup checks for duplicate elements (that is, +* elements with identical indices) in a sparse matrix specified in the +* coordinate format. +* +* The parameters m and n specifies, respectively, the number of rows +* and columns in the matrix, m >= 0, n >= 0. +* +* The parameter ne specifies the number of (structurally) non-zero +* elements in the matrix, ne >= 0. +* +* Elements of the matrix are specified as doublets (ia[k],ja[k]) for +* k = 1,...,ne, where ia[k] is a row index, ja[k] is a column index. +* +* The routine glp_check_dup can be used prior to a call to the routine +* glp_load_matrix to check that the constraint matrix to be loaded has +* no duplicate elements. +* +* RETURNS +* +* The routine glp_check_dup returns one of the following values: +* +* 0 - the matrix has no duplicate elements; +* +* -k - indices ia[k] or/and ja[k] are out of range; +* +* +k - element (ia[k],ja[k]) is duplicate. */ + +int glp_check_dup(int m, int n, int ne, const int ia[], const int ja[]) +{ int i, j, k, *ptr, *next, ret; + char *flag; + if (m < 0) + xerror("glp_check_dup: m = %d; invalid parameter\n"); + if (n < 0) + xerror("glp_check_dup: n = %d; invalid parameter\n"); + if (ne < 0) + xerror("glp_check_dup: ne = %d; invalid parameter\n"); + if (ne > 0 && ia == NULL) + xerror("glp_check_dup: ia = %p; invalid parameter\n", ia); + if (ne > 0 && ja == NULL) + xerror("glp_check_dup: ja = %p; invalid parameter\n", ja); + for (k = 1; k <= ne; k++) + { i = ia[k], j = ja[k]; + if (!(1 <= i && i <= m && 1 <= j && j <= n)) + { ret = -k; + goto done; + } + } + if (m == 0 || n == 0) + { ret = 0; + goto done; + } + /* allocate working arrays */ + ptr = xcalloc(1+m, sizeof(int)); + next = xcalloc(1+ne, sizeof(int)); + flag = xcalloc(1+n, sizeof(char)); + /* build row lists */ + for (i = 1; i <= m; i++) + ptr[i] = 0; + for (k = 1; k <= ne; k++) + { i = ia[k]; + next[k] = ptr[i]; + ptr[i] = k; + } + /* clear column flags */ + for (j = 1; j <= n; j++) + flag[j] = 0; + /* check for duplicate elements */ + for (i = 1; i <= m; i++) + { for (k = ptr[i]; k != 0; k = next[k]) + { j = ja[k]; + if (flag[j]) + { /* find first element (i,j) */ + for (k = 1; k <= ne; k++) + if (ia[k] == i && ja[k] == j) break; + xassert(k <= ne); + /* find next (duplicate) element (i,j) */ + for (k++; k <= ne; k++) + if (ia[k] == i && ja[k] == j) break; + xassert(k <= ne); + ret = +k; + goto skip; + } + flag[j] = 1; + } + /* clear column flags */ + for (k = ptr[i]; k != 0; k = next[k]) + flag[ja[k]] = 0; + } + /* no duplicate element found */ + ret = 0; +skip: /* free working arrays */ + xfree(ptr); + xfree(next); + xfree(flag); +done: return ret; +} + +/*********************************************************************** +* NAME +* +* glp_sort_matrix - sort elements of the constraint matrix +* +* SYNOPSIS +* +* void glp_sort_matrix(glp_prob *P); +* +* DESCRIPTION +* +* The routine glp_sort_matrix sorts elements of the constraint matrix +* rebuilding its row and column linked lists. On exit from the routine +* the constraint matrix is not changed, however, elements in the row +* linked lists become ordered by ascending column indices, and the +* elements in the column linked lists become ordered by ascending row +* indices. */ + +void glp_sort_matrix(glp_prob *P) +{ GLPAIJ *aij; + int i, j; + if (P == NULL || P->magic != GLP_PROB_MAGIC) + xerror("glp_sort_matrix: P = %p; invalid problem object\n", + P); + /* rebuild row linked lists */ + for (i = P->m; i >= 1; i--) + P->row[i]->ptr = NULL; + for (j = P->n; j >= 1; j--) + { for (aij = P->col[j]->ptr; aij != NULL; aij = aij->c_next) + { i = aij->row->i; + aij->r_prev = NULL; + aij->r_next = P->row[i]->ptr; + if (aij->r_next != NULL) aij->r_next->r_prev = aij; + P->row[i]->ptr = aij; + } + } + /* rebuild column linked lists */ + for (j = P->n; j >= 1; j--) + P->col[j]->ptr = NULL; + for (i = P->m; i >= 1; i--) + { for (aij = P->row[i]->ptr; aij != NULL; aij = aij->r_next) + { j = aij->col->j; + aij->c_prev = NULL; + aij->c_next = P->col[j]->ptr; + if (aij->c_next != NULL) aij->c_next->c_prev = aij; + P->col[j]->ptr = aij; + } + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_del_rows - delete rows from problem object +* +* SYNOPSIS +* +* void glp_del_rows(glp_prob *lp, int nrs, const int num[]); +* +* DESCRIPTION +* +* The routine glp_del_rows deletes rows from the specified problem +* object. Ordinal numbers of rows to be deleted should be placed in +* locations num[1], ..., num[nrs], where nrs > 0. +* +* Note that deleting rows involves changing ordinal numbers of other +* rows remaining in the problem object. New ordinal numbers of the +* remaining rows are assigned under the assumption that the original +* order of rows is not changed. */ + +void glp_del_rows(glp_prob *lp, int nrs, const int num[]) +{ glp_tree *tree = lp->tree; + GLPROW *row; + int i, k, m_new; + /* mark rows to be deleted */ + if (!(1 <= nrs && nrs <= lp->m)) + xerror("glp_del_rows: nrs = %d; invalid number of rows\n", + nrs); + for (k = 1; k <= nrs; k++) + { /* take the number of row to be deleted */ + i = num[k]; + /* obtain pointer to i-th row */ + if (!(1 <= i && i <= lp->m)) + xerror("glp_del_rows: num[%d] = %d; row number out of range" + "\n", k, i); + row = lp->row[i]; + if (tree != NULL && tree->reason != 0) + { if (!(tree->reason == GLP_IROWGEN || + tree->reason == GLP_ICUTGEN)) + xerror("glp_del_rows: operation not allowed\n"); + xassert(tree->curr != NULL); + if (row->level != tree->curr->level) + xerror("glp_del_rows: num[%d] = %d; invalid attempt to d" + "elete row created not in current subproblem\n", k,i); + if (row->stat != GLP_BS) + xerror("glp_del_rows: num[%d] = %d; invalid attempt to d" + "elete active row (constraint)\n", k, i); + tree->reinv = 1; + } + /* check that the row is not marked yet */ + if (row->i == 0) + xerror("glp_del_rows: num[%d] = %d; duplicate row numbers n" + "ot allowed\n", k, i); + /* erase symbolic name assigned to the row */ + glp_set_row_name(lp, i, NULL); + xassert(row->node == NULL); + /* erase corresponding row of the constraint matrix */ + glp_set_mat_row(lp, i, 0, NULL, NULL); + xassert(row->ptr == NULL); + /* mark the row to be deleted */ + row->i = 0; + } + /* delete all marked rows from the row list */ + m_new = 0; + for (i = 1; i <= lp->m; i++) + { /* obtain pointer to i-th row */ + row = lp->row[i]; + /* check if the row is marked */ + if (row->i == 0) + { /* it is marked, delete it */ + dmp_free_atom(lp->pool, row, sizeof(GLPROW)); + } + else + { /* it is not marked; keep it */ + row->i = ++m_new; + lp->row[row->i] = row; + } + } + /* set new number of rows */ + lp->m = m_new; + /* invalidate the basis factorization */ + lp->valid = 0; + return; +} + +/*********************************************************************** +* NAME +* +* glp_del_cols - delete columns from problem object +* +* SYNOPSIS +* +* void glp_del_cols(glp_prob *lp, int ncs, const int num[]); +* +* DESCRIPTION +* +* The routine glp_del_cols deletes columns from the specified problem +* object. Ordinal numbers of columns to be deleted should be placed in +* locations num[1], ..., num[ncs], where ncs > 0. +* +* Note that deleting columns involves changing ordinal numbers of +* other columns remaining in the problem object. New ordinal numbers +* of the remaining columns are assigned under the assumption that the +* original order of columns is not changed. */ + +void glp_del_cols(glp_prob *lp, int ncs, const int num[]) +{ glp_tree *tree = lp->tree; + GLPCOL *col; + int j, k, n_new; + if (tree != NULL && tree->reason != 0) + xerror("glp_del_cols: operation not allowed\n"); + /* mark columns to be deleted */ + if (!(1 <= ncs && ncs <= lp->n)) + xerror("glp_del_cols: ncs = %d; invalid number of columns\n", + ncs); + for (k = 1; k <= ncs; k++) + { /* take the number of column to be deleted */ + j = num[k]; + /* obtain pointer to j-th column */ + if (!(1 <= j && j <= lp->n)) + xerror("glp_del_cols: num[%d] = %d; column number out of ra" + "nge", k, j); + col = lp->col[j]; + /* check that the column is not marked yet */ + if (col->j == 0) + xerror("glp_del_cols: num[%d] = %d; duplicate column number" + "s not allowed\n", k, j); + /* erase symbolic name assigned to the column */ + glp_set_col_name(lp, j, NULL); + xassert(col->node == NULL); + /* erase corresponding column of the constraint matrix */ + glp_set_mat_col(lp, j, 0, NULL, NULL); + xassert(col->ptr == NULL); + /* mark the column to be deleted */ + col->j = 0; + /* if it is basic, invalidate the basis factorization */ + if (col->stat == GLP_BS) lp->valid = 0; + } + /* delete all marked columns from the column list */ + n_new = 0; + for (j = 1; j <= lp->n; j++) + { /* obtain pointer to j-th column */ + col = lp->col[j]; + /* check if the column is marked */ + if (col->j == 0) + { /* it is marked; delete it */ + dmp_free_atom(lp->pool, col, sizeof(GLPCOL)); + } + else + { /* it is not marked; keep it */ + col->j = ++n_new; + lp->col[col->j] = col; + } + } + /* set new number of columns */ + lp->n = n_new; + /* if the basis header is still valid, adjust it */ + if (lp->valid) + { int m = lp->m; + int *head = lp->head; + for (j = 1; j <= n_new; j++) + { k = lp->col[j]->bind; + if (k != 0) + { xassert(1 <= k && k <= m); + head[k] = m + j; + } + } + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_copy_prob - copy problem object content +* +* SYNOPSIS +* +* void glp_copy_prob(glp_prob *dest, glp_prob *prob, int names); +* +* DESCRIPTION +* +* The routine glp_copy_prob copies the content of the problem object +* prob to the problem object dest. +* +* The parameter names is a flag. If it is non-zero, the routine also +* copies all symbolic names; otherwise, if it is zero, symbolic names +* are not copied. */ + +void glp_copy_prob(glp_prob *dest, glp_prob *prob, int names) +{ glp_tree *tree = dest->tree; + glp_bfcp bfcp; + int i, j, len, *ind; + double *val; + if (tree != NULL && tree->reason != 0) + xerror("glp_copy_prob: operation not allowed\n"); + if (dest == prob) + xerror("glp_copy_prob: copying problem object to itself not al" + "lowed\n"); + if (!(names == GLP_ON || names == GLP_OFF)) + xerror("glp_copy_prob: names = %d; invalid parameter\n", + names); + glp_erase_prob(dest); + if (names && prob->name != NULL) + glp_set_prob_name(dest, prob->name); + if (names && prob->obj != NULL) + glp_set_obj_name(dest, prob->obj); + dest->dir = prob->dir; + dest->c0 = prob->c0; + if (prob->m > 0) + glp_add_rows(dest, prob->m); + if (prob->n > 0) + glp_add_cols(dest, prob->n); + glp_get_bfcp(prob, &bfcp); + glp_set_bfcp(dest, &bfcp); + dest->pbs_stat = prob->pbs_stat; + dest->dbs_stat = prob->dbs_stat; + dest->obj_val = prob->obj_val; + dest->some = prob->some; + dest->ipt_stat = prob->ipt_stat; + dest->ipt_obj = prob->ipt_obj; + dest->mip_stat = prob->mip_stat; + dest->mip_obj = prob->mip_obj; + for (i = 1; i <= prob->m; i++) + { GLPROW *to = dest->row[i]; + GLPROW *from = prob->row[i]; + if (names && from->name != NULL) + glp_set_row_name(dest, i, from->name); + to->type = from->type; + to->lb = from->lb; + to->ub = from->ub; + to->rii = from->rii; + to->stat = from->stat; + to->prim = from->prim; + to->dual = from->dual; + to->pval = from->pval; + to->dval = from->dval; + to->mipx = from->mipx; + } + ind = xcalloc(1+prob->m, sizeof(int)); + val = xcalloc(1+prob->m, sizeof(double)); + for (j = 1; j <= prob->n; j++) + { GLPCOL *to = dest->col[j]; + GLPCOL *from = prob->col[j]; + if (names && from->name != NULL) + glp_set_col_name(dest, j, from->name); + to->kind = from->kind; + to->type = from->type; + to->lb = from->lb; + to->ub = from->ub; + to->coef = from->coef; + len = glp_get_mat_col(prob, j, ind, val); + glp_set_mat_col(dest, j, len, ind, val); + to->sjj = from->sjj; + to->stat = from->stat; + to->prim = from->prim; + to->dual = from->dual; + to->pval = from->pval; + to->dval = from->dval; + to->mipx = from->mipx; + } + xfree(ind); + xfree(val); + return; +} + +/*********************************************************************** +* NAME +* +* glp_erase_prob - erase problem object content +* +* SYNOPSIS +* +* void glp_erase_prob(glp_prob *lp); +* +* DESCRIPTION +* +* The routine glp_erase_prob erases the content of the specified +* problem object. The effect of this operation is the same as if the +* problem object would be deleted with the routine glp_delete_prob and +* then created anew with the routine glp_create_prob, with exception +* that the handle (pointer) to the problem object remains valid. */ + +static void delete_prob(glp_prob *lp); + +void glp_erase_prob(glp_prob *lp) +{ glp_tree *tree = lp->tree; + if (tree != NULL && tree->reason != 0) + xerror("glp_erase_prob: operation not allowed\n"); + delete_prob(lp); + create_prob(lp); + return; +} + +/*********************************************************************** +* NAME +* +* glp_delete_prob - delete problem object +* +* SYNOPSIS +* +* void glp_delete_prob(glp_prob *lp); +* +* DESCRIPTION +* +* The routine glp_delete_prob deletes the specified problem object and +* frees all the memory allocated to it. */ + +static void delete_prob(glp_prob *lp) +{ lp->magic = 0x3F3F3F3F; + dmp_delete_pool(lp->pool); +#if 0 /* 08/III-2014 */ +#if 0 /* 17/XI-2009 */ + xfree(lp->cps); +#else + if (lp->parms != NULL) xfree(lp->parms); +#endif +#endif + xassert(lp->tree == NULL); +#if 0 + if (lp->cwa != NULL) xfree(lp->cwa); +#endif + xfree(lp->row); + xfree(lp->col); + if (lp->r_tree != NULL) avl_delete_tree(lp->r_tree); + if (lp->c_tree != NULL) avl_delete_tree(lp->c_tree); + xfree(lp->head); +#if 0 /* 08/III-2014 */ + if (lp->bfcp != NULL) xfree(lp->bfcp); +#endif + if (lp->bfd != NULL) bfd_delete_it(lp->bfd); + return; +} + +void glp_delete_prob(glp_prob *lp) +{ glp_tree *tree = lp->tree; + if (tree != NULL && tree->reason != 0) + xerror("glp_delete_prob: operation not allowed\n"); + delete_prob(lp); + xfree(lp); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi02.c b/resources/3rdparty/glpk-4.57/src/glpapi02.c new file mode 100644 index 000000000..5b74aab95 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi02.c @@ -0,0 +1,492 @@ +/* glpapi02.c (problem retrieving routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "prob.h" + +/*********************************************************************** +* NAME +* +* glp_get_prob_name - retrieve problem name +* +* SYNOPSIS +* +* const char *glp_get_prob_name(glp_prob *lp); +* +* RETURNS +* +* The routine glp_get_prob_name returns a pointer to an internal +* buffer, which contains symbolic name of the problem. However, if the +* problem has no assigned name, the routine returns NULL. */ + +const char *glp_get_prob_name(glp_prob *lp) +{ char *name; + name = lp->name; + return name; +} + +/*********************************************************************** +* NAME +* +* glp_get_obj_name - retrieve objective function name +* +* SYNOPSIS +* +* const char *glp_get_obj_name(glp_prob *lp); +* +* RETURNS +* +* The routine glp_get_obj_name returns a pointer to an internal +* buffer, which contains a symbolic name of the objective function. +* However, if the objective function has no assigned name, the routine +* returns NULL. */ + +const char *glp_get_obj_name(glp_prob *lp) +{ char *name; + name = lp->obj; + return name; +} + +/*********************************************************************** +* NAME +* +* glp_get_obj_dir - retrieve optimization direction flag +* +* SYNOPSIS +* +* int glp_get_obj_dir(glp_prob *lp); +* +* RETURNS +* +* The routine glp_get_obj_dir returns the optimization direction flag +* (i.e. "sense" of the objective function): +* +* GLP_MIN - minimization; +* GLP_MAX - maximization. */ + +int glp_get_obj_dir(glp_prob *lp) +{ int dir = lp->dir; + return dir; +} + +/*********************************************************************** +* NAME +* +* glp_get_num_rows - retrieve number of rows +* +* SYNOPSIS +* +* int glp_get_num_rows(glp_prob *lp); +* +* RETURNS +* +* The routine glp_get_num_rows returns the current number of rows in +* the specified problem object. */ + +int glp_get_num_rows(glp_prob *lp) +{ int m = lp->m; + return m; +} + +/*********************************************************************** +* NAME +* +* glp_get_num_cols - retrieve number of columns +* +* SYNOPSIS +* +* int glp_get_num_cols(glp_prob *lp); +* +* RETURNS +* +* The routine glp_get_num_cols returns the current number of columns +* in the specified problem object. */ + +int glp_get_num_cols(glp_prob *lp) +{ int n = lp->n; + return n; +} + +/*********************************************************************** +* NAME +* +* glp_get_row_name - retrieve row name +* +* SYNOPSIS +* +* const char *glp_get_row_name(glp_prob *lp, int i); +* +* RETURNS +* +* The routine glp_get_row_name returns a pointer to an internal +* buffer, which contains symbolic name of i-th row. However, if i-th +* row has no assigned name, the routine returns NULL. */ + +const char *glp_get_row_name(glp_prob *lp, int i) +{ char *name; + if (!(1 <= i && i <= lp->m)) + xerror("glp_get_row_name: i = %d; row number out of range\n", + i); + name = lp->row[i]->name; + return name; +} + +/*********************************************************************** +* NAME +* +* glp_get_col_name - retrieve column name +* +* SYNOPSIS +* +* const char *glp_get_col_name(glp_prob *lp, int j); +* +* RETURNS +* +* The routine glp_get_col_name returns a pointer to an internal +* buffer, which contains symbolic name of j-th column. However, if j-th +* column has no assigned name, the routine returns NULL. */ + +const char *glp_get_col_name(glp_prob *lp, int j) +{ char *name; + if (!(1 <= j && j <= lp->n)) + xerror("glp_get_col_name: j = %d; column number out of range\n" + , j); + name = lp->col[j]->name; + return name; +} + +/*********************************************************************** +* NAME +* +* glp_get_row_type - retrieve row type +* +* SYNOPSIS +* +* int glp_get_row_type(glp_prob *lp, int i); +* +* RETURNS +* +* The routine glp_get_row_type returns the type of i-th row, i.e. the +* type of corresponding auxiliary variable, as follows: +* +* GLP_FR - free (unbounded) variable; +* GLP_LO - variable with lower bound; +* GLP_UP - variable with upper bound; +* GLP_DB - double-bounded variable; +* GLP_FX - fixed variable. */ + +int glp_get_row_type(glp_prob *lp, int i) +{ if (!(1 <= i && i <= lp->m)) + xerror("glp_get_row_type: i = %d; row number out of range\n", + i); + return lp->row[i]->type; +} + +/*********************************************************************** +* NAME +* +* glp_get_row_lb - retrieve row lower bound +* +* SYNOPSIS +* +* double glp_get_row_lb(glp_prob *lp, int i); +* +* RETURNS +* +* The routine glp_get_row_lb returns the lower bound of i-th row, i.e. +* the lower bound of corresponding auxiliary variable. However, if the +* row has no lower bound, the routine returns -DBL_MAX. */ + +double glp_get_row_lb(glp_prob *lp, int i) +{ double lb; + if (!(1 <= i && i <= lp->m)) + xerror("glp_get_row_lb: i = %d; row number out of range\n", i); + switch (lp->row[i]->type) + { case GLP_FR: + case GLP_UP: + lb = -DBL_MAX; break; + case GLP_LO: + case GLP_DB: + case GLP_FX: + lb = lp->row[i]->lb; break; + default: + xassert(lp != lp); + } + return lb; +} + +/*********************************************************************** +* NAME +* +* glp_get_row_ub - retrieve row upper bound +* +* SYNOPSIS +* +* double glp_get_row_ub(glp_prob *lp, int i); +* +* RETURNS +* +* The routine glp_get_row_ub returns the upper bound of i-th row, i.e. +* the upper bound of corresponding auxiliary variable. However, if the +* row has no upper bound, the routine returns +DBL_MAX. */ + +double glp_get_row_ub(glp_prob *lp, int i) +{ double ub; + if (!(1 <= i && i <= lp->m)) + xerror("glp_get_row_ub: i = %d; row number out of range\n", i); + switch (lp->row[i]->type) + { case GLP_FR: + case GLP_LO: + ub = +DBL_MAX; break; + case GLP_UP: + case GLP_DB: + case GLP_FX: + ub = lp->row[i]->ub; break; + default: + xassert(lp != lp); + } + return ub; +} + +/*********************************************************************** +* NAME +* +* glp_get_col_type - retrieve column type +* +* SYNOPSIS +* +* int glp_get_col_type(glp_prob *lp, int j); +* +* RETURNS +* +* The routine glp_get_col_type returns the type of j-th column, i.e. +* the type of corresponding structural variable, as follows: +* +* GLP_FR - free (unbounded) variable; +* GLP_LO - variable with lower bound; +* GLP_UP - variable with upper bound; +* GLP_DB - double-bounded variable; +* GLP_FX - fixed variable. */ + +int glp_get_col_type(glp_prob *lp, int j) +{ if (!(1 <= j && j <= lp->n)) + xerror("glp_get_col_type: j = %d; column number out of range\n" + , j); + return lp->col[j]->type; +} + +/*********************************************************************** +* NAME +* +* glp_get_col_lb - retrieve column lower bound +* +* SYNOPSIS +* +* double glp_get_col_lb(glp_prob *lp, int j); +* +* RETURNS +* +* The routine glp_get_col_lb returns the lower bound of j-th column, +* i.e. the lower bound of corresponding structural variable. However, +* if the column has no lower bound, the routine returns -DBL_MAX. */ + +double glp_get_col_lb(glp_prob *lp, int j) +{ double lb; + if (!(1 <= j && j <= lp->n)) + xerror("glp_get_col_lb: j = %d; column number out of range\n", + j); + switch (lp->col[j]->type) + { case GLP_FR: + case GLP_UP: + lb = -DBL_MAX; break; + case GLP_LO: + case GLP_DB: + case GLP_FX: + lb = lp->col[j]->lb; break; + default: + xassert(lp != lp); + } + return lb; +} + +/*********************************************************************** +* NAME +* +* glp_get_col_ub - retrieve column upper bound +* +* SYNOPSIS +* +* double glp_get_col_ub(glp_prob *lp, int j); +* +* RETURNS +* +* The routine glp_get_col_ub returns the upper bound of j-th column, +* i.e. the upper bound of corresponding structural variable. However, +* if the column has no upper bound, the routine returns +DBL_MAX. */ + +double glp_get_col_ub(glp_prob *lp, int j) +{ double ub; + if (!(1 <= j && j <= lp->n)) + xerror("glp_get_col_ub: j = %d; column number out of range\n", + j); + switch (lp->col[j]->type) + { case GLP_FR: + case GLP_LO: + ub = +DBL_MAX; break; + case GLP_UP: + case GLP_DB: + case GLP_FX: + ub = lp->col[j]->ub; break; + default: + xassert(lp != lp); + } + return ub; +} + +/*********************************************************************** +* NAME +* +* glp_get_obj_coef - retrieve obj. coefficient or constant term +* +* SYNOPSIS +* +* double glp_get_obj_coef(glp_prob *lp, int j); +* +* RETURNS +* +* The routine glp_get_obj_coef returns the objective coefficient at +* j-th structural variable (column) of the specified problem object. +* +* If the parameter j is zero, the routine returns the constant term +* ("shift") of the objective function. */ + +double glp_get_obj_coef(glp_prob *lp, int j) +{ if (!(0 <= j && j <= lp->n)) + xerror("glp_get_obj_coef: j = %d; column number out of range\n" + , j); + return j == 0 ? lp->c0 : lp->col[j]->coef; +} + +/*********************************************************************** +* NAME +* +* glp_get_num_nz - retrieve number of constraint coefficients +* +* SYNOPSIS +* +* int glp_get_num_nz(glp_prob *lp); +* +* RETURNS +* +* The routine glp_get_num_nz returns the number of (non-zero) elements +* in the constraint matrix of the specified problem object. */ + +int glp_get_num_nz(glp_prob *lp) +{ int nnz = lp->nnz; + return nnz; +} + +/*********************************************************************** +* NAME +* +* glp_get_mat_row - retrieve row of the constraint matrix +* +* SYNOPSIS +* +* int glp_get_mat_row(glp_prob *lp, int i, int ind[], double val[]); +* +* DESCRIPTION +* +* The routine glp_get_mat_row scans (non-zero) elements of i-th row +* of the constraint matrix of the specified problem object and stores +* their column indices and numeric values to locations ind[1], ..., +* ind[len] and val[1], ..., val[len], respectively, where 0 <= len <= n +* is the number of elements in i-th row, n is the number of columns. +* +* The parameter ind and/or val can be specified as NULL, in which case +* corresponding information is not stored. +* +* RETURNS +* +* The routine glp_get_mat_row returns the length len, i.e. the number +* of (non-zero) elements in i-th row. */ + +int glp_get_mat_row(glp_prob *lp, int i, int ind[], double val[]) +{ GLPAIJ *aij; + int len; + if (!(1 <= i && i <= lp->m)) + xerror("glp_get_mat_row: i = %d; row number out of range\n", + i); + len = 0; + for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) + { len++; + if (ind != NULL) ind[len] = aij->col->j; + if (val != NULL) val[len] = aij->val; + } + xassert(len <= lp->n); + return len; +} + +/*********************************************************************** +* NAME +* +* glp_get_mat_col - retrieve column of the constraint matrix +* +* SYNOPSIS +* +* int glp_get_mat_col(glp_prob *lp, int j, int ind[], double val[]); +* +* DESCRIPTION +* +* The routine glp_get_mat_col scans (non-zero) elements of j-th column +* of the constraint matrix of the specified problem object and stores +* their row indices and numeric values to locations ind[1], ..., +* ind[len] and val[1], ..., val[len], respectively, where 0 <= len <= m +* is the number of elements in j-th column, m is the number of rows. +* +* The parameter ind or/and val can be specified as NULL, in which case +* corresponding information is not stored. +* +* RETURNS +* +* The routine glp_get_mat_col returns the length len, i.e. the number +* of (non-zero) elements in j-th column. */ + +int glp_get_mat_col(glp_prob *lp, int j, int ind[], double val[]) +{ GLPAIJ *aij; + int len; + if (!(1 <= j && j <= lp->n)) + xerror("glp_get_mat_col: j = %d; column number out of range\n", + j); + len = 0; + for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next) + { len++; + if (ind != NULL) ind[len] = aij->row->i; + if (val != NULL) val[len] = aij->val; + } + xassert(len <= lp->m); + return len; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi03.c b/resources/3rdparty/glpk-4.57/src/glpapi03.c new file mode 100644 index 000000000..daf9174af --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi03.c @@ -0,0 +1,167 @@ +/* glpapi03.c (row and column searching routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "prob.h" + +/*********************************************************************** +* NAME +* +* glp_create_index - create the name index +* +* SYNOPSIS +* +* void glp_create_index(glp_prob *lp); +* +* DESCRIPTION +* +* The routine glp_create_index creates the name index for the +* specified problem object. The name index is an auxiliary data +* structure, which is intended to quickly (i.e. for logarithmic time) +* find rows and columns by their names. +* +* This routine can be called at any time. If the name index already +* exists, the routine does nothing. */ + +void glp_create_index(glp_prob *lp) +{ GLPROW *row; + GLPCOL *col; + int i, j; + /* create row name index */ + if (lp->r_tree == NULL) + { lp->r_tree = avl_create_tree(avl_strcmp, NULL); + for (i = 1; i <= lp->m; i++) + { row = lp->row[i]; + xassert(row->node == NULL); + if (row->name != NULL) + { row->node = avl_insert_node(lp->r_tree, row->name); + avl_set_node_link(row->node, row); + } + } + } + /* create column name index */ + if (lp->c_tree == NULL) + { lp->c_tree = avl_create_tree(avl_strcmp, NULL); + for (j = 1; j <= lp->n; j++) + { col = lp->col[j]; + xassert(col->node == NULL); + if (col->name != NULL) + { col->node = avl_insert_node(lp->c_tree, col->name); + avl_set_node_link(col->node, col); + } + } + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_find_row - find row by its name +* +* SYNOPSIS +* +* int glp_find_row(glp_prob *lp, const char *name); +* +* RETURNS +* +* The routine glp_find_row returns the ordinal number of a row, +* which is assigned (by the routine glp_set_row_name) the specified +* symbolic name. If no such row exists, the routine returns 0. */ + +int glp_find_row(glp_prob *lp, const char *name) +{ AVLNODE *node; + int i = 0; + if (lp->r_tree == NULL) + xerror("glp_find_row: row name index does not exist\n"); + if (!(name == NULL || name[0] == '\0' || strlen(name) > 255)) + { node = avl_find_node(lp->r_tree, name); + if (node != NULL) + i = ((GLPROW *)avl_get_node_link(node))->i; + } + return i; +} + +/*********************************************************************** +* NAME +* +* glp_find_col - find column by its name +* +* SYNOPSIS +* +* int glp_find_col(glp_prob *lp, const char *name); +* +* RETURNS +* +* The routine glp_find_col returns the ordinal number of a column, +* which is assigned (by the routine glp_set_col_name) the specified +* symbolic name. If no such column exists, the routine returns 0. */ + +int glp_find_col(glp_prob *lp, const char *name) +{ AVLNODE *node; + int j = 0; + if (lp->c_tree == NULL) + xerror("glp_find_col: column name index does not exist\n"); + if (!(name == NULL || name[0] == '\0' || strlen(name) > 255)) + { node = avl_find_node(lp->c_tree, name); + if (node != NULL) + j = ((GLPCOL *)avl_get_node_link(node))->j; + } + return j; +} + +/*********************************************************************** +* NAME +* +* glp_delete_index - delete the name index +* +* SYNOPSIS +* +* void glp_delete_index(glp_prob *lp); +* +* DESCRIPTION +* +* The routine glp_delete_index deletes the name index previously +* created by the routine glp_create_index and frees the memory +* allocated to this auxiliary data structure. +* +* This routine can be called at any time. If the name index does not +* exist, the routine does nothing. */ + +void glp_delete_index(glp_prob *lp) +{ int i, j; + /* delete row name index */ + if (lp->r_tree != NULL) + { for (i = 1; i <= lp->m; i++) lp->row[i]->node = NULL; + avl_delete_tree(lp->r_tree), lp->r_tree = NULL; + } + /* delete column name index */ + if (lp->c_tree != NULL) + { for (j = 1; j <= lp->n; j++) lp->col[j]->node = NULL; + avl_delete_tree(lp->c_tree), lp->c_tree = NULL; + } + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi04.c b/resources/3rdparty/glpk-4.57/src/glpapi04.c new file mode 100644 index 000000000..adabb02c1 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi04.c @@ -0,0 +1,157 @@ +/* glpapi04.c (problem scaling routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "prob.h" + +/*********************************************************************** +* NAME +* +* glp_set_rii - set (change) row scale factor +* +* SYNOPSIS +* +* void glp_set_rii(glp_prob *lp, int i, double rii); +* +* DESCRIPTION +* +* The routine glp_set_rii sets (changes) the scale factor r[i,i] for +* i-th row of the specified problem object. */ + +void glp_set_rii(glp_prob *lp, int i, double rii) +{ if (!(1 <= i && i <= lp->m)) + xerror("glp_set_rii: i = %d; row number out of range\n", i); + if (rii <= 0.0) + xerror("glp_set_rii: i = %d; rii = %g; invalid scale factor\n", + i, rii); + if (lp->valid && lp->row[i]->rii != rii) + { GLPAIJ *aij; + for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) + { if (aij->col->stat == GLP_BS) + { /* invalidate the basis factorization */ + lp->valid = 0; + break; + } + } + } + lp->row[i]->rii = rii; + return; +} + +/*********************************************************************** +* NAME +* +* glp_set sjj - set (change) column scale factor +* +* SYNOPSIS +* +* void glp_set_sjj(glp_prob *lp, int j, double sjj); +* +* DESCRIPTION +* +* The routine glp_set_sjj sets (changes) the scale factor s[j,j] for +* j-th column of the specified problem object. */ + +void glp_set_sjj(glp_prob *lp, int j, double sjj) +{ if (!(1 <= j && j <= lp->n)) + xerror("glp_set_sjj: j = %d; column number out of range\n", j); + if (sjj <= 0.0) + xerror("glp_set_sjj: j = %d; sjj = %g; invalid scale factor\n", + j, sjj); + if (lp->valid && lp->col[j]->sjj != sjj && lp->col[j]->stat == + GLP_BS) + { /* invalidate the basis factorization */ + lp->valid = 0; + } + lp->col[j]->sjj = sjj; + return; +} + +/*********************************************************************** +* NAME +* +* glp_get_rii - retrieve row scale factor +* +* SYNOPSIS +* +* double glp_get_rii(glp_prob *lp, int i); +* +* RETURNS +* +* The routine glp_get_rii returns current scale factor r[i,i] for i-th +* row of the specified problem object. */ + +double glp_get_rii(glp_prob *lp, int i) +{ if (!(1 <= i && i <= lp->m)) + xerror("glp_get_rii: i = %d; row number out of range\n", i); + return lp->row[i]->rii; +} + +/*********************************************************************** +* NAME +* +* glp_get_sjj - retrieve column scale factor +* +* SYNOPSIS +* +* double glp_get_sjj(glp_prob *lp, int j); +* +* RETURNS +* +* The routine glp_get_sjj returns current scale factor s[j,j] for j-th +* column of the specified problem object. */ + +double glp_get_sjj(glp_prob *lp, int j) +{ if (!(1 <= j && j <= lp->n)) + xerror("glp_get_sjj: j = %d; column number out of range\n", j); + return lp->col[j]->sjj; +} + +/*********************************************************************** +* NAME +* +* glp_unscale_prob - unscale problem data +* +* SYNOPSIS +* +* void glp_unscale_prob(glp_prob *lp); +* +* DESCRIPTION +* +* The routine glp_unscale_prob performs unscaling of problem data for +* the specified problem object. +* +* "Unscaling" means replacing the current scaling matrices R and S by +* unity matrices that cancels the scaling effect. */ + +void glp_unscale_prob(glp_prob *lp) +{ int m = glp_get_num_rows(lp); + int n = glp_get_num_cols(lp); + int i, j; + for (i = 1; i <= m; i++) glp_set_rii(lp, i, 1.0); + for (j = 1; j <= n; j++) glp_set_sjj(lp, j, 1.0); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi05.c b/resources/3rdparty/glpk-4.57/src/glpapi05.c new file mode 100644 index 000000000..b18845522 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi05.c @@ -0,0 +1,169 @@ +/* glpapi05.c (LP basis constructing routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "prob.h" + +/*********************************************************************** +* NAME +* +* glp_set_row_stat - set (change) row status +* +* SYNOPSIS +* +* void glp_set_row_stat(glp_prob *lp, int i, int stat); +* +* DESCRIPTION +* +* The routine glp_set_row_stat sets (changes) status of the auxiliary +* variable associated with i-th row. +* +* The new status of the auxiliary variable should be specified by the +* parameter stat as follows: +* +* GLP_BS - basic variable; +* GLP_NL - non-basic variable; +* GLP_NU - non-basic variable on its upper bound; if the variable is +* not double-bounded, this means the same as GLP_NL (only in +* case of this routine); +* GLP_NF - the same as GLP_NL (only in case of this routine); +* GLP_NS - the same as GLP_NL (only in case of this routine). */ + +void glp_set_row_stat(glp_prob *lp, int i, int stat) +{ GLPROW *row; + if (!(1 <= i && i <= lp->m)) + xerror("glp_set_row_stat: i = %d; row number out of range\n", + i); + if (!(stat == GLP_BS || stat == GLP_NL || stat == GLP_NU || + stat == GLP_NF || stat == GLP_NS)) + xerror("glp_set_row_stat: i = %d; stat = %d; invalid status\n", + i, stat); + row = lp->row[i]; + if (stat != GLP_BS) + { switch (row->type) + { case GLP_FR: stat = GLP_NF; break; + case GLP_LO: stat = GLP_NL; break; + case GLP_UP: stat = GLP_NU; break; + case GLP_DB: if (stat != GLP_NU) stat = GLP_NL; break; + case GLP_FX: stat = GLP_NS; break; + default: xassert(row != row); + } + } + if (row->stat == GLP_BS && stat != GLP_BS || + row->stat != GLP_BS && stat == GLP_BS) + { /* invalidate the basis factorization */ + lp->valid = 0; + } + row->stat = stat; + return; +} + +/*********************************************************************** +* NAME +* +* glp_set_col_stat - set (change) column status +* +* SYNOPSIS +* +* void glp_set_col_stat(glp_prob *lp, int j, int stat); +* +* DESCRIPTION +* +* The routine glp_set_col_stat sets (changes) status of the structural +* variable associated with j-th column. +* +* The new status of the structural variable should be specified by the +* parameter stat as follows: +* +* GLP_BS - basic variable; +* GLP_NL - non-basic variable; +* GLP_NU - non-basic variable on its upper bound; if the variable is +* not double-bounded, this means the same as GLP_NL (only in +* case of this routine); +* GLP_NF - the same as GLP_NL (only in case of this routine); +* GLP_NS - the same as GLP_NL (only in case of this routine). */ + +void glp_set_col_stat(glp_prob *lp, int j, int stat) +{ GLPCOL *col; + if (!(1 <= j && j <= lp->n)) + xerror("glp_set_col_stat: j = %d; column number out of range\n" + , j); + if (!(stat == GLP_BS || stat == GLP_NL || stat == GLP_NU || + stat == GLP_NF || stat == GLP_NS)) + xerror("glp_set_col_stat: j = %d; stat = %d; invalid status\n", + j, stat); + col = lp->col[j]; + if (stat != GLP_BS) + { switch (col->type) + { case GLP_FR: stat = GLP_NF; break; + case GLP_LO: stat = GLP_NL; break; + case GLP_UP: stat = GLP_NU; break; + case GLP_DB: if (stat != GLP_NU) stat = GLP_NL; break; + case GLP_FX: stat = GLP_NS; break; + default: xassert(col != col); + } + } + if (col->stat == GLP_BS && stat != GLP_BS || + col->stat != GLP_BS && stat == GLP_BS) + { /* invalidate the basis factorization */ + lp->valid = 0; + } + col->stat = stat; + return; +} + +/*********************************************************************** +* NAME +* +* glp_std_basis - construct standard initial LP basis +* +* SYNOPSIS +* +* void glp_std_basis(glp_prob *lp); +* +* DESCRIPTION +* +* The routine glp_std_basis builds the "standard" (trivial) initial +* basis for the specified problem object. +* +* In the "standard" basis all auxiliary variables are basic, and all +* structural variables are non-basic. */ + +void glp_std_basis(glp_prob *lp) +{ int i, j; + /* make all auxiliary variables basic */ + for (i = 1; i <= lp->m; i++) + glp_set_row_stat(lp, i, GLP_BS); + /* make all structural variables non-basic */ + for (j = 1; j <= lp->n; j++) + { GLPCOL *col = lp->col[j]; + if (col->type == GLP_DB && fabs(col->lb) > fabs(col->ub)) + glp_set_col_stat(lp, j, GLP_NU); + else + glp_set_col_stat(lp, j, GLP_NL); + } + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi06.c b/resources/3rdparty/glpk-4.57/src/glpapi06.c new file mode 100644 index 000000000..715e1954e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi06.c @@ -0,0 +1,831 @@ +/* glpapi06.c (simplex method routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpios.h" +#include "glpnpp.h" +#if 0 /* 07/XI-2015 */ +#include "glpspx.h" +#else +#include "simplex.h" +#define spx_dual spy_dual +#endif + +/*********************************************************************** +* NAME +* +* glp_simplex - solve LP problem with the simplex method +* +* SYNOPSIS +* +* int glp_simplex(glp_prob *P, const glp_smcp *parm); +* +* DESCRIPTION +* +* The routine glp_simplex is a driver to the LP solver based on the +* simplex method. This routine retrieves problem data from the +* specified problem object, calls the solver to solve the problem +* instance, and stores results of computations back into the problem +* object. +* +* The simplex solver has a set of control parameters. Values of the +* control parameters can be passed in a structure glp_smcp, which the +* parameter parm points to. +* +* The parameter parm can be specified as NULL, in which case the LP +* solver uses default settings. +* +* RETURNS +* +* 0 The LP problem instance has been successfully solved. This code +* does not necessarily mean that the solver has found optimal +* solution. It only means that the solution process was successful. +* +* GLP_EBADB +* Unable to start the search, because the initial basis specified +* in the problem object is invalid--the number of basic (auxiliary +* and structural) variables is not the same as the number of rows in +* the problem object. +* +* GLP_ESING +* Unable to start the search, because the basis matrix correspodning +* to the initial basis is singular within the working precision. +* +* GLP_ECOND +* Unable to start the search, because the basis matrix correspodning +* to the initial basis is ill-conditioned, i.e. its condition number +* is too large. +* +* GLP_EBOUND +* Unable to start the search, because some double-bounded variables +* have incorrect bounds. +* +* GLP_EFAIL +* The search was prematurely terminated due to the solver failure. +* +* GLP_EOBJLL +* The search was prematurely terminated, because the objective +* function being maximized has reached its lower limit and continues +* decreasing (dual simplex only). +* +* GLP_EOBJUL +* The search was prematurely terminated, because the objective +* function being minimized has reached its upper limit and continues +* increasing (dual simplex only). +* +* GLP_EITLIM +* The search was prematurely terminated, because the simplex +* iteration limit has been exceeded. +* +* GLP_ETMLIM +* The search was prematurely terminated, because the time limit has +* been exceeded. +* +* GLP_ENOPFS +* The LP problem instance has no primal feasible solution (only if +* the LP presolver is used). +* +* GLP_ENODFS +* The LP problem instance has no dual feasible solution (only if the +* LP presolver is used). */ + +static void trivial_lp(glp_prob *P, const glp_smcp *parm) +{ /* solve trivial LP which has empty constraint matrix */ + GLPROW *row; + GLPCOL *col; + int i, j; + double p_infeas, d_infeas, zeta; + P->valid = 0; + P->pbs_stat = P->dbs_stat = GLP_FEAS; + P->obj_val = P->c0; + P->some = 0; + p_infeas = d_infeas = 0.0; + /* make all auxiliary variables basic */ + for (i = 1; i <= P->m; i++) + { row = P->row[i]; + row->stat = GLP_BS; + row->prim = row->dual = 0.0; + /* check primal feasibility */ + if (row->type == GLP_LO || row->type == GLP_DB || + row->type == GLP_FX) + { /* row has lower bound */ + if (row->lb > + parm->tol_bnd) + { P->pbs_stat = GLP_NOFEAS; + if (P->some == 0 && parm->meth != GLP_PRIMAL) + P->some = i; + } + if (p_infeas < + row->lb) + p_infeas = + row->lb; + } + if (row->type == GLP_UP || row->type == GLP_DB || + row->type == GLP_FX) + { /* row has upper bound */ + if (row->ub < - parm->tol_bnd) + { P->pbs_stat = GLP_NOFEAS; + if (P->some == 0 && parm->meth != GLP_PRIMAL) + P->some = i; + } + if (p_infeas < - row->ub) + p_infeas = - row->ub; + } + } + /* determine scale factor for the objective row */ + zeta = 1.0; + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + if (zeta < fabs(col->coef)) zeta = fabs(col->coef); + } + zeta = (P->dir == GLP_MIN ? +1.0 : -1.0) / zeta; + /* make all structural variables non-basic */ + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + if (col->type == GLP_FR) + col->stat = GLP_NF, col->prim = 0.0; + else if (col->type == GLP_LO) +lo: col->stat = GLP_NL, col->prim = col->lb; + else if (col->type == GLP_UP) +up: col->stat = GLP_NU, col->prim = col->ub; + else if (col->type == GLP_DB) + { if (zeta * col->coef > 0.0) + goto lo; + else if (zeta * col->coef < 0.0) + goto up; + else if (fabs(col->lb) <= fabs(col->ub)) + goto lo; + else + goto up; + } + else if (col->type == GLP_FX) + col->stat = GLP_NS, col->prim = col->lb; + col->dual = col->coef; + P->obj_val += col->coef * col->prim; + /* check dual feasibility */ + if (col->type == GLP_FR || col->type == GLP_LO) + { /* column has no upper bound */ + if (zeta * col->dual < - parm->tol_dj) + { P->dbs_stat = GLP_NOFEAS; + if (P->some == 0 && parm->meth == GLP_PRIMAL) + P->some = P->m + j; + } + if (d_infeas < - zeta * col->dual) + d_infeas = - zeta * col->dual; + } + if (col->type == GLP_FR || col->type == GLP_UP) + { /* column has no lower bound */ + if (zeta * col->dual > + parm->tol_dj) + { P->dbs_stat = GLP_NOFEAS; + if (P->some == 0 && parm->meth == GLP_PRIMAL) + P->some = P->m + j; + } + if (d_infeas < + zeta * col->dual) + d_infeas = + zeta * col->dual; + } + } + /* simulate the simplex solver output */ + if (parm->msg_lev >= GLP_MSG_ON && parm->out_dly == 0) + { xprintf("~%6d: obj = %17.9e infeas = %10.3e\n", P->it_cnt, + P->obj_val, parm->meth == GLP_PRIMAL ? p_infeas : d_infeas); + } + if (parm->msg_lev >= GLP_MSG_ALL && parm->out_dly == 0) + { if (P->pbs_stat == GLP_FEAS && P->dbs_stat == GLP_FEAS) + xprintf("OPTIMAL SOLUTION FOUND\n"); + else if (P->pbs_stat == GLP_NOFEAS) + xprintf("PROBLEM HAS NO FEASIBLE SOLUTION\n"); + else if (parm->meth == GLP_PRIMAL) + xprintf("PROBLEM HAS UNBOUNDED SOLUTION\n"); + else + xprintf("PROBLEM HAS NO DUAL FEASIBLE SOLUTION\n"); + } + return; +} + +static int solve_lp(glp_prob *P, const glp_smcp *parm) +{ /* solve LP directly without using the preprocessor */ + int ret; + if (!glp_bf_exists(P)) + { ret = glp_factorize(P); + if (ret == 0) + ; + else if (ret == GLP_EBADB) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_simplex: initial basis is invalid\n"); + } + else if (ret == GLP_ESING) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_simplex: initial basis is singular\n"); + } + else if (ret == GLP_ECOND) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf( + "glp_simplex: initial basis is ill-conditioned\n"); + } + else + xassert(ret != ret); + if (ret != 0) goto done; + } + if (parm->meth == GLP_PRIMAL) + ret = spx_primal(P, parm); + else if (parm->meth == GLP_DUALP) + { ret = spx_dual(P, parm); + if (ret == GLP_EFAIL && P->valid) + ret = spx_primal(P, parm); + } + else if (parm->meth == GLP_DUAL) + ret = spx_dual(P, parm); + else + xassert(parm != parm); +done: return ret; +} + +static int preprocess_and_solve_lp(glp_prob *P, const glp_smcp *parm) +{ /* solve LP using the preprocessor */ + NPP *npp; + glp_prob *lp = NULL; + glp_bfcp bfcp; + int ret; + if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("Preprocessing...\n"); + /* create preprocessor workspace */ + npp = npp_create_wksp(); + /* load original problem into the preprocessor workspace */ + npp_load_prob(npp, P, GLP_OFF, GLP_SOL, GLP_OFF); + /* process LP prior to applying primal/dual simplex method */ + ret = npp_simplex(npp, parm); + if (ret == 0) + ; + else if (ret == GLP_ENOPFS) + { if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n"); + } + else if (ret == GLP_ENODFS) + { if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("PROBLEM HAS NO DUAL FEASIBLE SOLUTION\n"); + } + else + xassert(ret != ret); + if (ret != 0) goto done; + /* build transformed LP */ + lp = glp_create_prob(); + npp_build_prob(npp, lp); + /* if the transformed LP is empty, it has empty solution, which + is optimal */ + if (lp->m == 0 && lp->n == 0) + { lp->pbs_stat = lp->dbs_stat = GLP_FEAS; + lp->obj_val = lp->c0; + if (parm->msg_lev >= GLP_MSG_ON && parm->out_dly == 0) + { xprintf("~%6d: obj = %17.9e infeas = %10.3e\n", P->it_cnt, + lp->obj_val, 0.0); + } + if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("OPTIMAL SOLUTION FOUND BY LP PREPROCESSOR\n"); + goto post; + } + if (parm->msg_lev >= GLP_MSG_ALL) + { xprintf("%d row%s, %d column%s, %d non-zero%s\n", + lp->m, lp->m == 1 ? "" : "s", lp->n, lp->n == 1 ? "" : "s", + lp->nnz, lp->nnz == 1 ? "" : "s"); + } + /* inherit basis factorization control parameters */ + glp_get_bfcp(P, &bfcp); + glp_set_bfcp(lp, &bfcp); + /* scale the transformed problem */ + { ENV *env = get_env_ptr(); + int term_out = env->term_out; + if (!term_out || parm->msg_lev < GLP_MSG_ALL) + env->term_out = GLP_OFF; + else + env->term_out = GLP_ON; + glp_scale_prob(lp, GLP_SF_AUTO); + env->term_out = term_out; + } + /* build advanced initial basis */ + { ENV *env = get_env_ptr(); + int term_out = env->term_out; + if (!term_out || parm->msg_lev < GLP_MSG_ALL) + env->term_out = GLP_OFF; + else + env->term_out = GLP_ON; + glp_adv_basis(lp, 0); + env->term_out = term_out; + } + /* solve the transformed LP */ + lp->it_cnt = P->it_cnt; + ret = solve_lp(lp, parm); + P->it_cnt = lp->it_cnt; + /* only optimal solution can be postprocessed */ + if (!(ret == 0 && lp->pbs_stat == GLP_FEAS && lp->dbs_stat == + GLP_FEAS)) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_simplex: unable to recover undefined or non-op" + "timal solution\n"); + if (ret == 0) + { if (lp->pbs_stat == GLP_NOFEAS) + ret = GLP_ENOPFS; + else if (lp->dbs_stat == GLP_NOFEAS) + ret = GLP_ENODFS; + else + xassert(lp != lp); + } + goto done; + } +post: /* postprocess solution from the transformed LP */ + npp_postprocess(npp, lp); + /* the transformed LP is no longer needed */ + glp_delete_prob(lp), lp = NULL; + /* store solution to the original problem */ + npp_unload_sol(npp, P); + /* the original LP has been successfully solved */ + ret = 0; +done: /* delete the transformed LP, if it exists */ + if (lp != NULL) glp_delete_prob(lp); + /* delete preprocessor workspace */ + npp_delete_wksp(npp); + return ret; +} + +int glp_simplex(glp_prob *P, const glp_smcp *parm) +{ /* solve LP problem with the simplex method */ + glp_smcp _parm; + int i, j, ret; + /* check problem object */ + if (P == NULL || P->magic != GLP_PROB_MAGIC) + xerror("glp_simplex: P = %p; invalid problem object\n", P); + if (P->tree != NULL && P->tree->reason != 0) + xerror("glp_simplex: operation not allowed\n"); + /* check control parameters */ + if (parm == NULL) + parm = &_parm, glp_init_smcp((glp_smcp *)parm); + if (!(parm->msg_lev == GLP_MSG_OFF || + parm->msg_lev == GLP_MSG_ERR || + parm->msg_lev == GLP_MSG_ON || + parm->msg_lev == GLP_MSG_ALL || + parm->msg_lev == GLP_MSG_DBG)) + xerror("glp_simplex: msg_lev = %d; invalid parameter\n", + parm->msg_lev); + if (!(parm->meth == GLP_PRIMAL || + parm->meth == GLP_DUALP || + parm->meth == GLP_DUAL)) + xerror("glp_simplex: meth = %d; invalid parameter\n", + parm->meth); + if (!(parm->pricing == GLP_PT_STD || + parm->pricing == GLP_PT_PSE)) + xerror("glp_simplex: pricing = %d; invalid parameter\n", + parm->pricing); + if (!(parm->r_test == GLP_RT_STD || + parm->r_test == GLP_RT_HAR)) + xerror("glp_simplex: r_test = %d; invalid parameter\n", + parm->r_test); + if (!(0.0 < parm->tol_bnd && parm->tol_bnd < 1.0)) + xerror("glp_simplex: tol_bnd = %g; invalid parameter\n", + parm->tol_bnd); + if (!(0.0 < parm->tol_dj && parm->tol_dj < 1.0)) + xerror("glp_simplex: tol_dj = %g; invalid parameter\n", + parm->tol_dj); + if (!(0.0 < parm->tol_piv && parm->tol_piv < 1.0)) + xerror("glp_simplex: tol_piv = %g; invalid parameter\n", + parm->tol_piv); + if (parm->it_lim < 0) + xerror("glp_simplex: it_lim = %d; invalid parameter\n", + parm->it_lim); + if (parm->tm_lim < 0) + xerror("glp_simplex: tm_lim = %d; invalid parameter\n", + parm->tm_lim); + if (parm->out_frq < 1) + xerror("glp_simplex: out_frq = %d; invalid parameter\n", + parm->out_frq); + if (parm->out_dly < 0) + xerror("glp_simplex: out_dly = %d; invalid parameter\n", + parm->out_dly); + if (!(parm->presolve == GLP_ON || parm->presolve == GLP_OFF)) + xerror("glp_simplex: presolve = %d; invalid parameter\n", + parm->presolve); + /* basic solution is currently undefined */ + P->pbs_stat = P->dbs_stat = GLP_UNDEF; + P->obj_val = 0.0; + P->some = 0; + /* check bounds of double-bounded variables */ + for (i = 1; i <= P->m; i++) + { GLPROW *row = P->row[i]; + if (row->type == GLP_DB && row->lb >= row->ub) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_simplex: row %d: lb = %g, ub = %g; incorrec" + "t bounds\n", i, row->lb, row->ub); + ret = GLP_EBOUND; + goto done; + } + } + for (j = 1; j <= P->n; j++) + { GLPCOL *col = P->col[j]; + if (col->type == GLP_DB && col->lb >= col->ub) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_simplex: column %d: lb = %g, ub = %g; incor" + "rect bounds\n", j, col->lb, col->ub); + ret = GLP_EBOUND; + goto done; + } + } + /* solve LP problem */ + if (parm->msg_lev >= GLP_MSG_ALL) + { xprintf("GLPK Simplex Optimizer, v%s\n", glp_version()); + xprintf("%d row%s, %d column%s, %d non-zero%s\n", + P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s", + P->nnz, P->nnz == 1 ? "" : "s"); + } + if (P->nnz == 0) + trivial_lp(P, parm), ret = 0; + else if (!parm->presolve) + ret = solve_lp(P, parm); + else + ret = preprocess_and_solve_lp(P, parm); +done: /* return to the application program */ + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_init_smcp - initialize simplex method control parameters +* +* SYNOPSIS +* +* void glp_init_smcp(glp_smcp *parm); +* +* DESCRIPTION +* +* The routine glp_init_smcp initializes control parameters, which are +* used by the simplex solver, with default values. +* +* Default values of the control parameters are stored in a glp_smcp +* structure, which the parameter parm points to. */ + +void glp_init_smcp(glp_smcp *parm) +{ parm->msg_lev = GLP_MSG_ALL; + parm->meth = GLP_PRIMAL; + parm->pricing = GLP_PT_PSE; + parm->r_test = GLP_RT_HAR; + parm->tol_bnd = 1e-7; + parm->tol_dj = 1e-7; +#if 0 /* 07/XI-2015 */ + parm->tol_piv = 1e-10; +#else + parm->tol_piv = 1e-9; +#endif + parm->obj_ll = -DBL_MAX; + parm->obj_ul = +DBL_MAX; + parm->it_lim = INT_MAX; + parm->tm_lim = INT_MAX; + parm->out_frq = 500; + parm->out_dly = 0; + parm->presolve = GLP_OFF; + return; +} + +/*********************************************************************** +* NAME +* +* glp_get_status - retrieve generic status of basic solution +* +* SYNOPSIS +* +* int glp_get_status(glp_prob *lp); +* +* RETURNS +* +* The routine glp_get_status reports the generic status of the basic +* solution for the specified problem object as follows: +* +* GLP_OPT - solution is optimal; +* GLP_FEAS - solution is feasible; +* GLP_INFEAS - solution is infeasible; +* GLP_NOFEAS - problem has no feasible solution; +* GLP_UNBND - problem has unbounded solution; +* GLP_UNDEF - solution is undefined. */ + +int glp_get_status(glp_prob *lp) +{ int status; + status = glp_get_prim_stat(lp); + switch (status) + { case GLP_FEAS: + switch (glp_get_dual_stat(lp)) + { case GLP_FEAS: + status = GLP_OPT; + break; + case GLP_NOFEAS: + status = GLP_UNBND; + break; + case GLP_UNDEF: + case GLP_INFEAS: + status = status; + break; + default: + xassert(lp != lp); + } + break; + case GLP_UNDEF: + case GLP_INFEAS: + case GLP_NOFEAS: + status = status; + break; + default: + xassert(lp != lp); + } + return status; +} + +/*********************************************************************** +* NAME +* +* glp_get_prim_stat - retrieve status of primal basic solution +* +* SYNOPSIS +* +* int glp_get_prim_stat(glp_prob *lp); +* +* RETURNS +* +* The routine glp_get_prim_stat reports the status of the primal basic +* solution for the specified problem object as follows: +* +* GLP_UNDEF - primal solution is undefined; +* GLP_FEAS - primal solution is feasible; +* GLP_INFEAS - primal solution is infeasible; +* GLP_NOFEAS - no primal feasible solution exists. */ + +int glp_get_prim_stat(glp_prob *lp) +{ int pbs_stat = lp->pbs_stat; + return pbs_stat; +} + +/*********************************************************************** +* NAME +* +* glp_get_dual_stat - retrieve status of dual basic solution +* +* SYNOPSIS +* +* int glp_get_dual_stat(glp_prob *lp); +* +* RETURNS +* +* The routine glp_get_dual_stat reports the status of the dual basic +* solution for the specified problem object as follows: +* +* GLP_UNDEF - dual solution is undefined; +* GLP_FEAS - dual solution is feasible; +* GLP_INFEAS - dual solution is infeasible; +* GLP_NOFEAS - no dual feasible solution exists. */ + +int glp_get_dual_stat(glp_prob *lp) +{ int dbs_stat = lp->dbs_stat; + return dbs_stat; +} + +/*********************************************************************** +* NAME +* +* glp_get_obj_val - retrieve objective value (basic solution) +* +* SYNOPSIS +* +* double glp_get_obj_val(glp_prob *lp); +* +* RETURNS +* +* The routine glp_get_obj_val returns value of the objective function +* for basic solution. */ + +double glp_get_obj_val(glp_prob *lp) +{ /*struct LPXCPS *cps = lp->cps;*/ + double z; + z = lp->obj_val; + /*if (cps->round && fabs(z) < 1e-9) z = 0.0;*/ + return z; +} + +/*********************************************************************** +* NAME +* +* glp_get_row_stat - retrieve row status +* +* SYNOPSIS +* +* int glp_get_row_stat(glp_prob *lp, int i); +* +* RETURNS +* +* The routine glp_get_row_stat returns current status assigned to the +* auxiliary variable associated with i-th row as follows: +* +* GLP_BS - basic variable; +* GLP_NL - non-basic variable on its lower bound; +* GLP_NU - non-basic variable on its upper bound; +* GLP_NF - non-basic free (unbounded) variable; +* GLP_NS - non-basic fixed variable. */ + +int glp_get_row_stat(glp_prob *lp, int i) +{ if (!(1 <= i && i <= lp->m)) + xerror("glp_get_row_stat: i = %d; row number out of range\n", + i); + return lp->row[i]->stat; +} + +/*********************************************************************** +* NAME +* +* glp_get_row_prim - retrieve row primal value (basic solution) +* +* SYNOPSIS +* +* double glp_get_row_prim(glp_prob *lp, int i); +* +* RETURNS +* +* The routine glp_get_row_prim returns primal value of the auxiliary +* variable associated with i-th row. */ + +double glp_get_row_prim(glp_prob *lp, int i) +{ /*struct LPXCPS *cps = lp->cps;*/ + double prim; + if (!(1 <= i && i <= lp->m)) + xerror("glp_get_row_prim: i = %d; row number out of range\n", + i); + prim = lp->row[i]->prim; + /*if (cps->round && fabs(prim) < 1e-9) prim = 0.0;*/ + return prim; +} + +/*********************************************************************** +* NAME +* +* glp_get_row_dual - retrieve row dual value (basic solution) +* +* SYNOPSIS +* +* double glp_get_row_dual(glp_prob *lp, int i); +* +* RETURNS +* +* The routine glp_get_row_dual returns dual value (i.e. reduced cost) +* of the auxiliary variable associated with i-th row. */ + +double glp_get_row_dual(glp_prob *lp, int i) +{ /*struct LPXCPS *cps = lp->cps;*/ + double dual; + if (!(1 <= i && i <= lp->m)) + xerror("glp_get_row_dual: i = %d; row number out of range\n", + i); + dual = lp->row[i]->dual; + /*if (cps->round && fabs(dual) < 1e-9) dual = 0.0;*/ + return dual; +} + +/*********************************************************************** +* NAME +* +* glp_get_col_stat - retrieve column status +* +* SYNOPSIS +* +* int glp_get_col_stat(glp_prob *lp, int j); +* +* RETURNS +* +* The routine glp_get_col_stat returns current status assigned to the +* structural variable associated with j-th column as follows: +* +* GLP_BS - basic variable; +* GLP_NL - non-basic variable on its lower bound; +* GLP_NU - non-basic variable on its upper bound; +* GLP_NF - non-basic free (unbounded) variable; +* GLP_NS - non-basic fixed variable. */ + +int glp_get_col_stat(glp_prob *lp, int j) +{ if (!(1 <= j && j <= lp->n)) + xerror("glp_get_col_stat: j = %d; column number out of range\n" + , j); + return lp->col[j]->stat; +} + +/*********************************************************************** +* NAME +* +* glp_get_col_prim - retrieve column primal value (basic solution) +* +* SYNOPSIS +* +* double glp_get_col_prim(glp_prob *lp, int j); +* +* RETURNS +* +* The routine glp_get_col_prim returns primal value of the structural +* variable associated with j-th column. */ + +double glp_get_col_prim(glp_prob *lp, int j) +{ /*struct LPXCPS *cps = lp->cps;*/ + double prim; + if (!(1 <= j && j <= lp->n)) + xerror("glp_get_col_prim: j = %d; column number out of range\n" + , j); + prim = lp->col[j]->prim; + /*if (cps->round && fabs(prim) < 1e-9) prim = 0.0;*/ + return prim; +} + +/*********************************************************************** +* NAME +* +* glp_get_col_dual - retrieve column dual value (basic solution) +* +* SYNOPSIS +* +* double glp_get_col_dual(glp_prob *lp, int j); +* +* RETURNS +* +* The routine glp_get_col_dual returns dual value (i.e. reduced cost) +* of the structural variable associated with j-th column. */ + +double glp_get_col_dual(glp_prob *lp, int j) +{ /*struct LPXCPS *cps = lp->cps;*/ + double dual; + if (!(1 <= j && j <= lp->n)) + xerror("glp_get_col_dual: j = %d; column number out of range\n" + , j); + dual = lp->col[j]->dual; + /*if (cps->round && fabs(dual) < 1e-9) dual = 0.0;*/ + return dual; +} + +/*********************************************************************** +* NAME +* +* glp_get_unbnd_ray - determine variable causing unboundedness +* +* SYNOPSIS +* +* int glp_get_unbnd_ray(glp_prob *lp); +* +* RETURNS +* +* The routine glp_get_unbnd_ray returns the number k of a variable, +* which causes primal or dual unboundedness. If 1 <= k <= m, it is +* k-th auxiliary variable, and if m+1 <= k <= m+n, it is (k-m)-th +* structural variable, where m is the number of rows, n is the number +* of columns in the problem object. If such variable is not defined, +* the routine returns 0. +* +* COMMENTS +* +* If it is not exactly known which version of the simplex solver +* detected unboundedness, i.e. whether the unboundedness is primal or +* dual, it is sufficient to check the status of the variable reported +* with the routine glp_get_row_stat or glp_get_col_stat. If the +* variable is non-basic, the unboundedness is primal, otherwise, if +* the variable is basic, the unboundedness is dual (the latter case +* means that the problem has no primal feasible dolution). */ + +int glp_get_unbnd_ray(glp_prob *lp) +{ int k; + k = lp->some; + xassert(k >= 0); + if (k > lp->m + lp->n) k = 0; + return k; +} + +#if 1 /* 08/VIII-2013 */ +int glp_get_it_cnt(glp_prob *P) +{ /* get simplex solver iteration count */ + return P->it_cnt; +} +#endif + +#if 1 /* 08/VIII-2013 */ +void glp_set_it_cnt(glp_prob *P, int it_cnt) +{ /* set simplex solver iteration count */ + P->it_cnt = it_cnt; + return; +} +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi07.c b/resources/3rdparty/glpk-4.57/src/glpapi07.c new file mode 100644 index 000000000..5258a4dec --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi07.c @@ -0,0 +1,456 @@ +/* glpapi07.c (exact simplex solver) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "draft.h" +#include "glpssx.h" +#include "misc.h" +#include "prob.h" + +/*********************************************************************** +* NAME +* +* glp_exact - solve LP problem in exact arithmetic +* +* SYNOPSIS +* +* int glp_exact(glp_prob *lp, const glp_smcp *parm); +* +* DESCRIPTION +* +* The routine glp_exact is a tentative implementation of the primal +* two-phase simplex method based on exact (rational) arithmetic. It is +* similar to the routine glp_simplex, however, for all internal +* computations it uses arithmetic of rational numbers, which is exact +* in mathematical sense, i.e. free of round-off errors unlike floating +* point arithmetic. +* +* Note that the routine glp_exact uses inly two control parameters +* passed in the structure glp_smcp, namely, it_lim and tm_lim. +* +* RETURNS +* +* 0 The LP problem instance has been successfully solved. This code +* does not necessarily mean that the solver has found optimal +* solution. It only means that the solution process was successful. +* +* GLP_EBADB +* Unable to start the search, because the initial basis specified +* in the problem object is invalid--the number of basic (auxiliary +* and structural) variables is not the same as the number of rows in +* the problem object. +* +* GLP_ESING +* Unable to start the search, because the basis matrix correspodning +* to the initial basis is exactly singular. +* +* GLP_EBOUND +* Unable to start the search, because some double-bounded variables +* have incorrect bounds. +* +* GLP_EFAIL +* The problem has no rows/columns. +* +* GLP_EITLIM +* The search was prematurely terminated, because the simplex +* iteration limit has been exceeded. +* +* GLP_ETMLIM +* The search was prematurely terminated, because the time limit has +* been exceeded. */ + +static void set_d_eps(mpq_t x, double val) +{ /* convert double val to rational x obtaining a more adequate + fraction than provided by mpq_set_d due to allowing a small + approximation error specified by a given relative tolerance; + for example, mpq_set_d would give the following + 1/3 ~= 0.333333333333333314829616256247391... -> + -> 6004799503160661/18014398509481984 + while this routine gives exactly 1/3 */ + int s, n, j; + double f, p, q, eps = 1e-9; + mpq_t temp; + xassert(-DBL_MAX <= val && val <= +DBL_MAX); +#if 1 /* 30/VII-2008 */ + if (val == floor(val)) + { /* if val is integral, do not approximate */ + mpq_set_d(x, val); + goto done; + } +#endif + if (val > 0.0) + s = +1; + else if (val < 0.0) + s = -1; + else + { mpq_set_si(x, 0, 1); + goto done; + } + f = frexp(fabs(val), &n); + /* |val| = f * 2^n, where 0.5 <= f < 1.0 */ + fp2rat(f, 0.1 * eps, &p, &q); + /* f ~= p / q, where p and q are integers */ + mpq_init(temp); + mpq_set_d(x, p); + mpq_set_d(temp, q); + mpq_div(x, x, temp); + mpq_set_si(temp, 1, 1); + for (j = 1; j <= abs(n); j++) + mpq_add(temp, temp, temp); + if (n > 0) + mpq_mul(x, x, temp); + else if (n < 0) + mpq_div(x, x, temp); + mpq_clear(temp); + if (s < 0) mpq_neg(x, x); + /* check that the desired tolerance has been attained */ + xassert(fabs(val - mpq_get_d(x)) <= eps * (1.0 + fabs(val))); +done: return; +} + +static void load_data(SSX *ssx, glp_prob *lp) +{ /* load LP problem data into simplex solver workspace */ + int m = ssx->m; + int n = ssx->n; + int nnz = ssx->A_ptr[n+1]-1; + int j, k, type, loc, len, *ind; + double lb, ub, coef, *val; + xassert(lp->m == m); + xassert(lp->n == n); + xassert(lp->nnz == nnz); + /* types and bounds of rows and columns */ + for (k = 1; k <= m+n; k++) + { if (k <= m) + { type = lp->row[k]->type; + lb = lp->row[k]->lb; + ub = lp->row[k]->ub; + } + else + { type = lp->col[k-m]->type; + lb = lp->col[k-m]->lb; + ub = lp->col[k-m]->ub; + } + switch (type) + { case GLP_FR: type = SSX_FR; break; + case GLP_LO: type = SSX_LO; break; + case GLP_UP: type = SSX_UP; break; + case GLP_DB: type = SSX_DB; break; + case GLP_FX: type = SSX_FX; break; + default: xassert(type != type); + } + ssx->type[k] = type; + set_d_eps(ssx->lb[k], lb); + set_d_eps(ssx->ub[k], ub); + } + /* optimization direction */ + switch (lp->dir) + { case GLP_MIN: ssx->dir = SSX_MIN; break; + case GLP_MAX: ssx->dir = SSX_MAX; break; + default: xassert(lp != lp); + } + /* objective coefficients */ + for (k = 0; k <= m+n; k++) + { if (k == 0) + coef = lp->c0; + else if (k <= m) + coef = 0.0; + else + coef = lp->col[k-m]->coef; + set_d_eps(ssx->coef[k], coef); + } + /* constraint coefficients */ + ind = xcalloc(1+m, sizeof(int)); + val = xcalloc(1+m, sizeof(double)); + loc = 0; + for (j = 1; j <= n; j++) + { ssx->A_ptr[j] = loc+1; + len = glp_get_mat_col(lp, j, ind, val); + for (k = 1; k <= len; k++) + { loc++; + ssx->A_ind[loc] = ind[k]; + set_d_eps(ssx->A_val[loc], val[k]); + } + } + xassert(loc == nnz); + xfree(ind); + xfree(val); + return; +} + +static int load_basis(SSX *ssx, glp_prob *lp) +{ /* load current LP basis into simplex solver workspace */ + int m = ssx->m; + int n = ssx->n; + int *type = ssx->type; + int *stat = ssx->stat; + int *Q_row = ssx->Q_row; + int *Q_col = ssx->Q_col; + int i, j, k; + xassert(lp->m == m); + xassert(lp->n == n); + /* statuses of rows and columns */ + for (k = 1; k <= m+n; k++) + { if (k <= m) + stat[k] = lp->row[k]->stat; + else + stat[k] = lp->col[k-m]->stat; + switch (stat[k]) + { case GLP_BS: + stat[k] = SSX_BS; + break; + case GLP_NL: + stat[k] = SSX_NL; + xassert(type[k] == SSX_LO || type[k] == SSX_DB); + break; + case GLP_NU: + stat[k] = SSX_NU; + xassert(type[k] == SSX_UP || type[k] == SSX_DB); + break; + case GLP_NF: + stat[k] = SSX_NF; + xassert(type[k] == SSX_FR); + break; + case GLP_NS: + stat[k] = SSX_NS; + xassert(type[k] == SSX_FX); + break; + default: + xassert(stat != stat); + } + } + /* build permutation matix Q */ + i = j = 0; + for (k = 1; k <= m+n; k++) + { if (stat[k] == SSX_BS) + { i++; + if (i > m) return 1; + Q_row[k] = i, Q_col[i] = k; + } + else + { j++; + if (j > n) return 1; + Q_row[k] = m+j, Q_col[m+j] = k; + } + } + xassert(i == m && j == n); + return 0; +} + +int glp_exact(glp_prob *lp, const glp_smcp *parm) +{ glp_smcp _parm; + SSX *ssx; + int m = lp->m; + int n = lp->n; + int nnz = lp->nnz; + int i, j, k, type, pst, dst, ret, stat; + double lb, ub, prim, dual, sum; + if (parm == NULL) + parm = &_parm, glp_init_smcp((glp_smcp *)parm); + /* check control parameters */ + if (parm->it_lim < 0) + xerror("glp_exact: it_lim = %d; invalid parameter\n", + parm->it_lim); + if (parm->tm_lim < 0) + xerror("glp_exact: tm_lim = %d; invalid parameter\n", + parm->tm_lim); + /* the problem must have at least one row and one column */ + if (!(m > 0 && n > 0)) + { xprintf("glp_exact: problem has no rows/columns\n"); + return GLP_EFAIL; + } +#if 1 + /* basic solution is currently undefined */ + lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; + lp->obj_val = 0.0; + lp->some = 0; +#endif + /* check that all double-bounded variables have correct bounds */ + for (k = 1; k <= m+n; k++) + { if (k <= m) + { type = lp->row[k]->type; + lb = lp->row[k]->lb; + ub = lp->row[k]->ub; + } + else + { type = lp->col[k-m]->type; + lb = lp->col[k-m]->lb; + ub = lp->col[k-m]->ub; + } + if (type == GLP_DB && lb >= ub) + { xprintf("glp_exact: %s %d has invalid bounds\n", + k <= m ? "row" : "column", k <= m ? k : k-m); + return GLP_EBOUND; + } + } + /* create the simplex solver workspace */ + xprintf("glp_exact: %d rows, %d columns, %d non-zeros\n", + m, n, nnz); +#ifdef HAVE_GMP + xprintf("GNU MP bignum library is being used\n"); +#else + xprintf("GLPK bignum module is being used\n"); + xprintf("(Consider installing GNU MP to attain a much better perf" + "ormance.)\n"); +#endif + ssx = ssx_create(m, n, nnz); + /* load LP problem data into the workspace */ + load_data(ssx, lp); + /* load current LP basis into the workspace */ + if (load_basis(ssx, lp)) + { xprintf("glp_exact: initial LP basis is invalid\n"); + ret = GLP_EBADB; + goto done; + } + /* inherit some control parameters from the LP object */ +#if 0 + ssx->it_lim = lpx_get_int_parm(lp, LPX_K_ITLIM); + ssx->it_cnt = lpx_get_int_parm(lp, LPX_K_ITCNT); + ssx->tm_lim = lpx_get_real_parm(lp, LPX_K_TMLIM); +#else + ssx->it_lim = parm->it_lim; + ssx->it_cnt = lp->it_cnt; + ssx->tm_lim = (double)parm->tm_lim / 1000.0; +#endif + ssx->out_frq = 5.0; + ssx->tm_beg = xtime(); +#if 0 /* 10/VI-2013 */ + ssx->tm_lag = xlset(0); +#else + ssx->tm_lag = 0.0; +#endif + /* solve LP */ + ret = ssx_driver(ssx); + /* copy back some statistics to the LP object */ +#if 0 + lpx_set_int_parm(lp, LPX_K_ITLIM, ssx->it_lim); + lpx_set_int_parm(lp, LPX_K_ITCNT, ssx->it_cnt); + lpx_set_real_parm(lp, LPX_K_TMLIM, ssx->tm_lim); +#else + lp->it_cnt = ssx->it_cnt; +#endif + /* analyze the return code */ + switch (ret) + { case 0: + /* optimal solution found */ + ret = 0; + pst = dst = GLP_FEAS; + break; + case 1: + /* problem has no feasible solution */ + ret = 0; + pst = GLP_NOFEAS, dst = GLP_INFEAS; + break; + case 2: + /* problem has unbounded solution */ + ret = 0; + pst = GLP_FEAS, dst = GLP_NOFEAS; +#if 1 + xassert(1 <= ssx->q && ssx->q <= n); + lp->some = ssx->Q_col[m + ssx->q]; + xassert(1 <= lp->some && lp->some <= m+n); +#endif + break; + case 3: + /* iteration limit exceeded (phase I) */ + ret = GLP_EITLIM; + pst = dst = GLP_INFEAS; + break; + case 4: + /* iteration limit exceeded (phase II) */ + ret = GLP_EITLIM; + pst = GLP_FEAS, dst = GLP_INFEAS; + break; + case 5: + /* time limit exceeded (phase I) */ + ret = GLP_ETMLIM; + pst = dst = GLP_INFEAS; + break; + case 6: + /* time limit exceeded (phase II) */ + ret = GLP_ETMLIM; + pst = GLP_FEAS, dst = GLP_INFEAS; + break; + case 7: + /* initial basis matrix is singular */ + ret = GLP_ESING; + goto done; + default: + xassert(ret != ret); + } + /* store final basic solution components into LP object */ + lp->pbs_stat = pst; + lp->dbs_stat = dst; + sum = lp->c0; + for (k = 1; k <= m+n; k++) + { if (ssx->stat[k] == SSX_BS) + { i = ssx->Q_row[k]; /* x[k] = xB[i] */ + xassert(1 <= i && i <= m); + stat = GLP_BS; + prim = mpq_get_d(ssx->bbar[i]); + dual = 0.0; + } + else + { j = ssx->Q_row[k] - m; /* x[k] = xN[j] */ + xassert(1 <= j && j <= n); + switch (ssx->stat[k]) + { case SSX_NF: + stat = GLP_NF; + prim = 0.0; + break; + case SSX_NL: + stat = GLP_NL; + prim = mpq_get_d(ssx->lb[k]); + break; + case SSX_NU: + stat = GLP_NU; + prim = mpq_get_d(ssx->ub[k]); + break; + case SSX_NS: + stat = GLP_NS; + prim = mpq_get_d(ssx->lb[k]); + break; + default: + xassert(ssx != ssx); + } + dual = mpq_get_d(ssx->cbar[j]); + } + if (k <= m) + { glp_set_row_stat(lp, k, stat); + lp->row[k]->prim = prim; + lp->row[k]->dual = dual; + } + else + { glp_set_col_stat(lp, k-m, stat); + lp->col[k-m]->prim = prim; + lp->col[k-m]->dual = dual; + sum += lp->col[k-m]->coef * prim; + } + } + lp->obj_val = sum; +done: /* delete the simplex solver workspace */ + ssx_delete(ssx); + /* return to the application program */ + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi08.c b/resources/3rdparty/glpk-4.57/src/glpapi08.c new file mode 100644 index 000000000..e7fc62e8f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi08.c @@ -0,0 +1,388 @@ +/* glpapi08.c (interior-point method routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpipm.h" +#include "glpnpp.h" + +/*********************************************************************** +* NAME +* +* glp_interior - solve LP problem with the interior-point method +* +* SYNOPSIS +* +* int glp_interior(glp_prob *P, const glp_iptcp *parm); +* +* The routine glp_interior is a driver to the LP solver based on the +* interior-point method. +* +* The interior-point solver has a set of control parameters. Values of +* the control parameters can be passed in a structure glp_iptcp, which +* the parameter parm points to. +* +* Currently this routine implements an easy variant of the primal-dual +* interior-point method based on Mehrotra's technique. +* +* This routine transforms the original LP problem to an equivalent LP +* problem in the standard formulation (all constraints are equalities, +* all variables are non-negative), calls the routine ipm_main to solve +* the transformed problem, and then transforms an obtained solution to +* the solution of the original problem. +* +* RETURNS +* +* 0 The LP problem instance has been successfully solved. This code +* does not necessarily mean that the solver has found optimal +* solution. It only means that the solution process was successful. +* +* GLP_EFAIL +* The problem has no rows/columns. +* +* GLP_ENOCVG +* Very slow convergence or divergence. +* +* GLP_EITLIM +* Iteration limit exceeded. +* +* GLP_EINSTAB +* Numerical instability on solving Newtonian system. */ + +static void transform(NPP *npp) +{ /* transform LP to the standard formulation */ + NPPROW *row, *prev_row; + NPPCOL *col, *prev_col; + for (row = npp->r_tail; row != NULL; row = prev_row) + { prev_row = row->prev; + if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) + npp_free_row(npp, row); + else if (row->lb == -DBL_MAX) + npp_leq_row(npp, row); + else if (row->ub == +DBL_MAX) + npp_geq_row(npp, row); + else if (row->lb != row->ub) + { if (fabs(row->lb) < fabs(row->ub)) + npp_geq_row(npp, row); + else + npp_leq_row(npp, row); + } + } + for (col = npp->c_tail; col != NULL; col = prev_col) + { prev_col = col->prev; + if (col->lb == -DBL_MAX && col->ub == +DBL_MAX) + npp_free_col(npp, col); + else if (col->lb == -DBL_MAX) + npp_ubnd_col(npp, col); + else if (col->ub == +DBL_MAX) + { if (col->lb != 0.0) + npp_lbnd_col(npp, col); + } + else if (col->lb != col->ub) + { if (fabs(col->lb) < fabs(col->ub)) + { if (col->lb != 0.0) + npp_lbnd_col(npp, col); + } + else + npp_ubnd_col(npp, col); + npp_dbnd_col(npp, col); + } + else + npp_fixed_col(npp, col); + } + for (row = npp->r_head; row != NULL; row = row->next) + xassert(row->lb == row->ub); + for (col = npp->c_head; col != NULL; col = col->next) + xassert(col->lb == 0.0 && col->ub == +DBL_MAX); + return; +} + +int glp_interior(glp_prob *P, const glp_iptcp *parm) +{ glp_iptcp _parm; + GLPROW *row; + GLPCOL *col; + NPP *npp = NULL; + glp_prob *prob = NULL; + int i, j, ret; + /* check control parameters */ + if (parm == NULL) + glp_init_iptcp(&_parm), parm = &_parm; + if (!(parm->msg_lev == GLP_MSG_OFF || + parm->msg_lev == GLP_MSG_ERR || + parm->msg_lev == GLP_MSG_ON || + parm->msg_lev == GLP_MSG_ALL)) + xerror("glp_interior: msg_lev = %d; invalid parameter\n", + parm->msg_lev); + if (!(parm->ord_alg == GLP_ORD_NONE || + parm->ord_alg == GLP_ORD_QMD || + parm->ord_alg == GLP_ORD_AMD || + parm->ord_alg == GLP_ORD_SYMAMD)) + xerror("glp_interior: ord_alg = %d; invalid parameter\n", + parm->ord_alg); + /* interior-point solution is currently undefined */ + P->ipt_stat = GLP_UNDEF; + P->ipt_obj = 0.0; + /* check bounds of double-bounded variables */ + for (i = 1; i <= P->m; i++) + { row = P->row[i]; + if (row->type == GLP_DB && row->lb >= row->ub) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_interior: row %d: lb = %g, ub = %g; incorre" + "ct bounds\n", i, row->lb, row->ub); + ret = GLP_EBOUND; + goto done; + } + } + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + if (col->type == GLP_DB && col->lb >= col->ub) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_interior: column %d: lb = %g, ub = %g; inco" + "rrect bounds\n", j, col->lb, col->ub); + ret = GLP_EBOUND; + goto done; + } + } + /* transform LP to the standard formulation */ + if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("Original LP has %d row(s), %d column(s), and %d non-z" + "ero(s)\n", P->m, P->n, P->nnz); + npp = npp_create_wksp(); + npp_load_prob(npp, P, GLP_OFF, GLP_IPT, GLP_ON); + transform(npp); + prob = glp_create_prob(); + npp_build_prob(npp, prob); + if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("Working LP has %d row(s), %d column(s), and %d non-ze" + "ro(s)\n", prob->m, prob->n, prob->nnz); +#if 1 + /* currently empty problem cannot be solved */ + if (!(prob->m > 0 && prob->n > 0)) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_interior: unable to solve empty problem\n"); + ret = GLP_EFAIL; + goto done; + } +#endif + /* scale the resultant LP */ + { ENV *env = get_env_ptr(); + int term_out = env->term_out; + env->term_out = GLP_OFF; + glp_scale_prob(prob, GLP_SF_EQ); + env->term_out = term_out; + } + /* warn about dense columns */ + if (parm->msg_lev >= GLP_MSG_ON && prob->m >= 200) + { int len, cnt = 0; + for (j = 1; j <= prob->n; j++) + { len = glp_get_mat_col(prob, j, NULL, NULL); + if ((double)len >= 0.20 * (double)prob->m) cnt++; + } + if (cnt == 1) + xprintf("WARNING: PROBLEM HAS ONE DENSE COLUMN\n"); + else if (cnt > 0) + xprintf("WARNING: PROBLEM HAS %d DENSE COLUMNS\n", cnt); + } + /* solve the transformed LP */ + ret = ipm_solve(prob, parm); + /* postprocess solution from the transformed LP */ + npp_postprocess(npp, prob); + /* and store solution to the original LP */ + npp_unload_sol(npp, P); +done: /* free working program objects */ + if (npp != NULL) npp_delete_wksp(npp); + if (prob != NULL) glp_delete_prob(prob); + /* return to the application program */ + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_init_iptcp - initialize interior-point solver control parameters +* +* SYNOPSIS +* +* void glp_init_iptcp(glp_iptcp *parm); +* +* DESCRIPTION +* +* The routine glp_init_iptcp initializes control parameters, which are +* used by the interior-point solver, with default values. +* +* Default values of the control parameters are stored in the glp_iptcp +* structure, which the parameter parm points to. */ + +void glp_init_iptcp(glp_iptcp *parm) +{ parm->msg_lev = GLP_MSG_ALL; + parm->ord_alg = GLP_ORD_AMD; + return; +} + +/*********************************************************************** +* NAME +* +* glp_ipt_status - retrieve status of interior-point solution +* +* SYNOPSIS +* +* int glp_ipt_status(glp_prob *lp); +* +* RETURNS +* +* The routine glp_ipt_status reports the status of solution found by +* the interior-point solver as follows: +* +* GLP_UNDEF - interior-point solution is undefined; +* GLP_OPT - interior-point solution is optimal; +* GLP_INFEAS - interior-point solution is infeasible; +* GLP_NOFEAS - no feasible solution exists. */ + +int glp_ipt_status(glp_prob *lp) +{ int ipt_stat = lp->ipt_stat; + return ipt_stat; +} + +/*********************************************************************** +* NAME +* +* glp_ipt_obj_val - retrieve objective value (interior point) +* +* SYNOPSIS +* +* double glp_ipt_obj_val(glp_prob *lp); +* +* RETURNS +* +* The routine glp_ipt_obj_val returns value of the objective function +* for interior-point solution. */ + +double glp_ipt_obj_val(glp_prob *lp) +{ /*struct LPXCPS *cps = lp->cps;*/ + double z; + z = lp->ipt_obj; + /*if (cps->round && fabs(z) < 1e-9) z = 0.0;*/ + return z; +} + +/*********************************************************************** +* NAME +* +* glp_ipt_row_prim - retrieve row primal value (interior point) +* +* SYNOPSIS +* +* double glp_ipt_row_prim(glp_prob *lp, int i); +* +* RETURNS +* +* The routine glp_ipt_row_prim returns primal value of the auxiliary +* variable associated with i-th row. */ + +double glp_ipt_row_prim(glp_prob *lp, int i) +{ /*struct LPXCPS *cps = lp->cps;*/ + double pval; + if (!(1 <= i && i <= lp->m)) + xerror("glp_ipt_row_prim: i = %d; row number out of range\n", + i); + pval = lp->row[i]->pval; + /*if (cps->round && fabs(pval) < 1e-9) pval = 0.0;*/ + return pval; +} + +/*********************************************************************** +* NAME +* +* glp_ipt_row_dual - retrieve row dual value (interior point) +* +* SYNOPSIS +* +* double glp_ipt_row_dual(glp_prob *lp, int i); +* +* RETURNS +* +* The routine glp_ipt_row_dual returns dual value (i.e. reduced cost) +* of the auxiliary variable associated with i-th row. */ + +double glp_ipt_row_dual(glp_prob *lp, int i) +{ /*struct LPXCPS *cps = lp->cps;*/ + double dval; + if (!(1 <= i && i <= lp->m)) + xerror("glp_ipt_row_dual: i = %d; row number out of range\n", + i); + dval = lp->row[i]->dval; + /*if (cps->round && fabs(dval) < 1e-9) dval = 0.0;*/ + return dval; +} + +/*********************************************************************** +* NAME +* +* glp_ipt_col_prim - retrieve column primal value (interior point) +* +* SYNOPSIS +* +* double glp_ipt_col_prim(glp_prob *lp, int j); +* +* RETURNS +* +* The routine glp_ipt_col_prim returns primal value of the structural +* variable associated with j-th column. */ + +double glp_ipt_col_prim(glp_prob *lp, int j) +{ /*struct LPXCPS *cps = lp->cps;*/ + double pval; + if (!(1 <= j && j <= lp->n)) + xerror("glp_ipt_col_prim: j = %d; column number out of range\n" + , j); + pval = lp->col[j]->pval; + /*if (cps->round && fabs(pval) < 1e-9) pval = 0.0;*/ + return pval; +} + +/*********************************************************************** +* NAME +* +* glp_ipt_col_dual - retrieve column dual value (interior point) +* +* SYNOPSIS +* +* double glp_ipt_col_dual(glp_prob *lp, int j); +* +* RETURNS +* +* The routine glp_ipt_col_dual returns dual value (i.e. reduced cost) +* of the structural variable associated with j-th column. */ + +double glp_ipt_col_dual(glp_prob *lp, int j) +{ /*struct LPXCPS *cps = lp->cps;*/ + double dval; + if (!(1 <= j && j <= lp->n)) + xerror("glp_ipt_col_dual: j = %d; column number out of range\n" + , j); + dval = lp->col[j]->dval; + /*if (cps->round && fabs(dval) < 1e-9) dval = 0.0;*/ + return dval; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi09.c b/resources/3rdparty/glpk-4.57/src/glpapi09.c new file mode 100644 index 000000000..a864e9b18 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi09.c @@ -0,0 +1,785 @@ +/* glpapi09.c (mixed integer programming routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "draft.h" +#include "env.h" +#include "glpios.h" +#include "glpnpp.h" + +/*********************************************************************** +* NAME +* +* glp_set_col_kind - set (change) column kind +* +* SYNOPSIS +* +* void glp_set_col_kind(glp_prob *mip, int j, int kind); +* +* DESCRIPTION +* +* The routine glp_set_col_kind sets (changes) the kind of j-th column +* (structural variable) as specified by the parameter kind: +* +* GLP_CV - continuous variable; +* GLP_IV - integer variable; +* GLP_BV - binary variable. */ + +void glp_set_col_kind(glp_prob *mip, int j, int kind) +{ GLPCOL *col; + if (!(1 <= j && j <= mip->n)) + xerror("glp_set_col_kind: j = %d; column number out of range\n" + , j); + col = mip->col[j]; + switch (kind) + { case GLP_CV: + col->kind = GLP_CV; + break; + case GLP_IV: + col->kind = GLP_IV; + break; + case GLP_BV: + col->kind = GLP_IV; + if (!(col->type == GLP_DB && col->lb == 0.0 && col->ub == + 1.0)) glp_set_col_bnds(mip, j, GLP_DB, 0.0, 1.0); + break; + default: + xerror("glp_set_col_kind: j = %d; kind = %d; invalid column" + " kind\n", j, kind); + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_get_col_kind - retrieve column kind +* +* SYNOPSIS +* +* int glp_get_col_kind(glp_prob *mip, int j); +* +* RETURNS +* +* The routine glp_get_col_kind returns the kind of j-th column, i.e. +* the kind of corresponding structural variable, as follows: +* +* GLP_CV - continuous variable; +* GLP_IV - integer variable; +* GLP_BV - binary variable */ + +int glp_get_col_kind(glp_prob *mip, int j) +{ GLPCOL *col; + int kind; + if (!(1 <= j && j <= mip->n)) + xerror("glp_get_col_kind: j = %d; column number out of range\n" + , j); + col = mip->col[j]; + kind = col->kind; + switch (kind) + { case GLP_CV: + break; + case GLP_IV: + if (col->type == GLP_DB && col->lb == 0.0 && col->ub == 1.0) + kind = GLP_BV; + break; + default: + xassert(kind != kind); + } + return kind; +} + +/*********************************************************************** +* NAME +* +* glp_get_num_int - retrieve number of integer columns +* +* SYNOPSIS +* +* int glp_get_num_int(glp_prob *mip); +* +* RETURNS +* +* The routine glp_get_num_int returns the current number of columns, +* which are marked as integer. */ + +int glp_get_num_int(glp_prob *mip) +{ GLPCOL *col; + int j, count = 0; + for (j = 1; j <= mip->n; j++) + { col = mip->col[j]; + if (col->kind == GLP_IV) count++; + } + return count; +} + +/*********************************************************************** +* NAME +* +* glp_get_num_bin - retrieve number of binary columns +* +* SYNOPSIS +* +* int glp_get_num_bin(glp_prob *mip); +* +* RETURNS +* +* The routine glp_get_num_bin returns the current number of columns, +* which are marked as binary. */ + +int glp_get_num_bin(glp_prob *mip) +{ GLPCOL *col; + int j, count = 0; + for (j = 1; j <= mip->n; j++) + { col = mip->col[j]; + if (col->kind == GLP_IV && col->type == GLP_DB && col->lb == + 0.0 && col->ub == 1.0) count++; + } + return count; +} + +/*********************************************************************** +* NAME +* +* glp_intopt - solve MIP problem with the branch-and-bound method +* +* SYNOPSIS +* +* int glp_intopt(glp_prob *P, const glp_iocp *parm); +* +* DESCRIPTION +* +* The routine glp_intopt is a driver to the MIP solver based on the +* branch-and-bound method. +* +* On entry the problem object should contain optimal solution to LP +* relaxation (which can be obtained with the routine glp_simplex). +* +* The MIP solver has a set of control parameters. Values of the control +* parameters can be passed in a structure glp_iocp, which the parameter +* parm points to. +* +* The parameter parm can be specified as NULL, in which case the MIP +* solver uses default settings. +* +* RETURNS +* +* 0 The MIP problem instance has been successfully solved. This code +* does not necessarily mean that the solver has found optimal +* solution. It only means that the solution process was successful. +* +* GLP_EBOUND +* Unable to start the search, because some double-bounded variables +* have incorrect bounds or some integer variables have non-integer +* (fractional) bounds. +* +* GLP_EROOT +* Unable to start the search, because optimal basis for initial LP +* relaxation is not provided. +* +* GLP_EFAIL +* The search was prematurely terminated due to the solver failure. +* +* GLP_EMIPGAP +* The search was prematurely terminated, because the relative mip +* gap tolerance has been reached. +* +* GLP_ETMLIM +* The search was prematurely terminated, because the time limit has +* been exceeded. +* +* GLP_ENOPFS +* The MIP problem instance has no primal feasible solution (only if +* the MIP presolver is used). +* +* GLP_ENODFS +* LP relaxation of the MIP problem instance has no dual feasible +* solution (only if the MIP presolver is used). +* +* GLP_ESTOP +* The search was prematurely terminated by application. */ + +#if 0 /* 11/VII-2013 */ +static int solve_mip(glp_prob *P, const glp_iocp *parm) +#else +static int solve_mip(glp_prob *P, const glp_iocp *parm, + glp_prob *P0 /* problem passed to glp_intopt */, + NPP *npp /* preprocessor workspace or NULL */) +#endif +{ /* solve MIP directly without using the preprocessor */ + glp_tree *T; + int ret; + /* optimal basis to LP relaxation must be provided */ + if (glp_get_status(P) != GLP_OPT) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_intopt: optimal basis to initial LP relaxation" + " not provided\n"); + ret = GLP_EROOT; + goto done; + } + /* it seems all is ok */ + if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("Integer optimization begins...\n"); + /* create the branch-and-bound tree */ + T = ios_create_tree(P, parm); +#if 1 /* 11/VII-2013 */ + T->P = P0; + T->npp = npp; +#endif + /* solve the problem instance */ + ret = ios_driver(T); + /* delete the branch-and-bound tree */ + ios_delete_tree(T); + /* analyze exit code reported by the mip driver */ + if (ret == 0) + { if (P->mip_stat == GLP_FEAS) + { if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("INTEGER OPTIMAL SOLUTION FOUND\n"); + P->mip_stat = GLP_OPT; + } + else + { if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("PROBLEM HAS NO INTEGER FEASIBLE SOLUTION\n"); + P->mip_stat = GLP_NOFEAS; + } + } + else if (ret == GLP_EMIPGAP) + { if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("RELATIVE MIP GAP TOLERANCE REACHED; SEARCH TERMINA" + "TED\n"); + } + else if (ret == GLP_ETMLIM) + { if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); + } + else if (ret == GLP_EFAIL) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_intopt: cannot solve current LP relaxation\n"); + } + else if (ret == GLP_ESTOP) + { if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("SEARCH TERMINATED BY APPLICATION\n"); + } + else + xassert(ret != ret); +done: return ret; +} + +static int preprocess_and_solve_mip(glp_prob *P, const glp_iocp *parm) +{ /* solve MIP using the preprocessor */ + ENV *env = get_env_ptr(); + int term_out = env->term_out; + NPP *npp; + glp_prob *mip = NULL; + glp_bfcp bfcp; + glp_smcp smcp; + int ret; + if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("Preprocessing...\n"); + /* create preprocessor workspace */ + npp = npp_create_wksp(); + /* load original problem into the preprocessor workspace */ + npp_load_prob(npp, P, GLP_OFF, GLP_MIP, GLP_OFF); + /* process MIP prior to applying the branch-and-bound method */ + if (!term_out || parm->msg_lev < GLP_MSG_ALL) + env->term_out = GLP_OFF; + else + env->term_out = GLP_ON; + ret = npp_integer(npp, parm); + env->term_out = term_out; + if (ret == 0) + ; + else if (ret == GLP_ENOPFS) + { if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n"); + } + else if (ret == GLP_ENODFS) + { if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("LP RELAXATION HAS NO DUAL FEASIBLE SOLUTION\n"); + } + else + xassert(ret != ret); + if (ret != 0) goto done; + /* build transformed MIP */ + mip = glp_create_prob(); + npp_build_prob(npp, mip); + /* if the transformed MIP is empty, it has empty solution, which + is optimal */ + if (mip->m == 0 && mip->n == 0) + { mip->mip_stat = GLP_OPT; + mip->mip_obj = mip->c0; + if (parm->msg_lev >= GLP_MSG_ALL) + { xprintf("Objective value = %17.9e\n", mip->mip_obj); + xprintf("INTEGER OPTIMAL SOLUTION FOUND BY MIP PREPROCESSOR" + "\n"); + } + goto post; + } + /* display some statistics */ + if (parm->msg_lev >= GLP_MSG_ALL) + { int ni = glp_get_num_int(mip); + int nb = glp_get_num_bin(mip); + char s[50]; + xprintf("%d row%s, %d column%s, %d non-zero%s\n", + mip->m, mip->m == 1 ? "" : "s", mip->n, mip->n == 1 ? "" : + "s", mip->nnz, mip->nnz == 1 ? "" : "s"); + if (nb == 0) + strcpy(s, "none of"); + else if (ni == 1 && nb == 1) + strcpy(s, ""); + else if (nb == 1) + strcpy(s, "one of"); + else if (nb == ni) + strcpy(s, "all of"); + else + sprintf(s, "%d of", nb); + xprintf("%d integer variable%s, %s which %s binary\n", + ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are"); + } + /* inherit basis factorization control parameters */ + glp_get_bfcp(P, &bfcp); + glp_set_bfcp(mip, &bfcp); + /* scale the transformed problem */ + if (!term_out || parm->msg_lev < GLP_MSG_ALL) + env->term_out = GLP_OFF; + else + env->term_out = GLP_ON; + glp_scale_prob(mip, + GLP_SF_GM | GLP_SF_EQ | GLP_SF_2N | GLP_SF_SKIP); + env->term_out = term_out; + /* build advanced initial basis */ + if (!term_out || parm->msg_lev < GLP_MSG_ALL) + env->term_out = GLP_OFF; + else + env->term_out = GLP_ON; + glp_adv_basis(mip, 0); + env->term_out = term_out; + /* solve initial LP relaxation */ + if (parm->msg_lev >= GLP_MSG_ALL) + xprintf("Solving LP relaxation...\n"); + glp_init_smcp(&smcp); + smcp.msg_lev = parm->msg_lev; + mip->it_cnt = P->it_cnt; + ret = glp_simplex(mip, &smcp); + P->it_cnt = mip->it_cnt; + if (ret != 0) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_intopt: cannot solve LP relaxation\n"); + ret = GLP_EFAIL; + goto done; + } + /* check status of the basic solution */ + ret = glp_get_status(mip); + if (ret == GLP_OPT) + ret = 0; + else if (ret == GLP_NOFEAS) + ret = GLP_ENOPFS; + else if (ret == GLP_UNBND) + ret = GLP_ENODFS; + else + xassert(ret != ret); + if (ret != 0) goto done; + /* solve the transformed MIP */ + mip->it_cnt = P->it_cnt; +#if 0 /* 11/VII-2013 */ + ret = solve_mip(mip, parm); +#else + if (parm->use_sol) + { mip->mip_stat = P->mip_stat; + mip->mip_obj = P->mip_obj; + } + ret = solve_mip(mip, parm, P, npp); +#endif + P->it_cnt = mip->it_cnt; + /* only integer feasible solution can be postprocessed */ + if (!(mip->mip_stat == GLP_OPT || mip->mip_stat == GLP_FEAS)) + { P->mip_stat = mip->mip_stat; + goto done; + } + /* postprocess solution from the transformed MIP */ +post: npp_postprocess(npp, mip); + /* the transformed MIP is no longer needed */ + glp_delete_prob(mip), mip = NULL; + /* store solution to the original problem */ + npp_unload_sol(npp, P); +done: /* delete the transformed MIP, if it exists */ + if (mip != NULL) glp_delete_prob(mip); + /* delete preprocessor workspace */ + npp_delete_wksp(npp); + return ret; +} + +#ifndef HAVE_ALIEN_SOLVER /* 28/V-2010 */ +int _glp_intopt1(glp_prob *P, const glp_iocp *parm) +{ xassert(P == P); + xassert(parm == parm); + xprintf("glp_intopt: no alien solver is available\n"); + return GLP_EFAIL; +} +#endif + +int glp_intopt(glp_prob *P, const glp_iocp *parm) +{ /* solve MIP problem with the branch-and-bound method */ + glp_iocp _parm; + int i, j, ret; + /* check problem object */ + if (P == NULL || P->magic != GLP_PROB_MAGIC) + xerror("glp_intopt: P = %p; invalid problem object\n", P); + if (P->tree != NULL) + xerror("glp_intopt: operation not allowed\n"); + /* check control parameters */ + if (parm == NULL) + parm = &_parm, glp_init_iocp((glp_iocp *)parm); + if (!(parm->msg_lev == GLP_MSG_OFF || + parm->msg_lev == GLP_MSG_ERR || + parm->msg_lev == GLP_MSG_ON || + parm->msg_lev == GLP_MSG_ALL || + parm->msg_lev == GLP_MSG_DBG)) + xerror("glp_intopt: msg_lev = %d; invalid parameter\n", + parm->msg_lev); + if (!(parm->br_tech == GLP_BR_FFV || + parm->br_tech == GLP_BR_LFV || + parm->br_tech == GLP_BR_MFV || + parm->br_tech == GLP_BR_DTH || + parm->br_tech == GLP_BR_PCH)) + xerror("glp_intopt: br_tech = %d; invalid parameter\n", + parm->br_tech); + if (!(parm->bt_tech == GLP_BT_DFS || + parm->bt_tech == GLP_BT_BFS || + parm->bt_tech == GLP_BT_BLB || + parm->bt_tech == GLP_BT_BPH)) + xerror("glp_intopt: bt_tech = %d; invalid parameter\n", + parm->bt_tech); + if (!(0.0 < parm->tol_int && parm->tol_int < 1.0)) + xerror("glp_intopt: tol_int = %g; invalid parameter\n", + parm->tol_int); + if (!(0.0 < parm->tol_obj && parm->tol_obj < 1.0)) + xerror("glp_intopt: tol_obj = %g; invalid parameter\n", + parm->tol_obj); + if (parm->tm_lim < 0) + xerror("glp_intopt: tm_lim = %d; invalid parameter\n", + parm->tm_lim); + if (parm->out_frq < 0) + xerror("glp_intopt: out_frq = %d; invalid parameter\n", + parm->out_frq); + if (parm->out_dly < 0) + xerror("glp_intopt: out_dly = %d; invalid parameter\n", + parm->out_dly); + if (!(0 <= parm->cb_size && parm->cb_size <= 256)) + xerror("glp_intopt: cb_size = %d; invalid parameter\n", + parm->cb_size); + if (!(parm->pp_tech == GLP_PP_NONE || + parm->pp_tech == GLP_PP_ROOT || + parm->pp_tech == GLP_PP_ALL)) + xerror("glp_intopt: pp_tech = %d; invalid parameter\n", + parm->pp_tech); + if (parm->mip_gap < 0.0) + xerror("glp_intopt: mip_gap = %g; invalid parameter\n", + parm->mip_gap); + if (!(parm->mir_cuts == GLP_ON || parm->mir_cuts == GLP_OFF)) + xerror("glp_intopt: mir_cuts = %d; invalid parameter\n", + parm->mir_cuts); + if (!(parm->gmi_cuts == GLP_ON || parm->gmi_cuts == GLP_OFF)) + xerror("glp_intopt: gmi_cuts = %d; invalid parameter\n", + parm->gmi_cuts); + if (!(parm->cov_cuts == GLP_ON || parm->cov_cuts == GLP_OFF)) + xerror("glp_intopt: cov_cuts = %d; invalid parameter\n", + parm->cov_cuts); + if (!(parm->clq_cuts == GLP_ON || parm->clq_cuts == GLP_OFF)) + xerror("glp_intopt: clq_cuts = %d; invalid parameter\n", + parm->clq_cuts); + if (!(parm->presolve == GLP_ON || parm->presolve == GLP_OFF)) + xerror("glp_intopt: presolve = %d; invalid parameter\n", + parm->presolve); + if (!(parm->binarize == GLP_ON || parm->binarize == GLP_OFF)) + xerror("glp_intopt: binarize = %d; invalid parameter\n", + parm->binarize); + if (!(parm->fp_heur == GLP_ON || parm->fp_heur == GLP_OFF)) + xerror("glp_intopt: fp_heur = %d; invalid parameter\n", + parm->fp_heur); +#if 1 /* 28/V-2010 */ + if (!(parm->alien == GLP_ON || parm->alien == GLP_OFF)) + xerror("glp_intopt: alien = %d; invalid parameter\n", + parm->alien); +#endif +#if 0 /* 11/VII-2013 */ + /* integer solution is currently undefined */ + P->mip_stat = GLP_UNDEF; + P->mip_obj = 0.0; +#else + if (!parm->use_sol) + P->mip_stat = GLP_UNDEF; + if (P->mip_stat == GLP_NOFEAS) + P->mip_stat = GLP_UNDEF; + if (P->mip_stat == GLP_UNDEF) + P->mip_obj = 0.0; + else if (P->mip_stat == GLP_OPT) + P->mip_stat = GLP_FEAS; +#endif + /* check bounds of double-bounded variables */ + for (i = 1; i <= P->m; i++) + { GLPROW *row = P->row[i]; + if (row->type == GLP_DB && row->lb >= row->ub) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_intopt: row %d: lb = %g, ub = %g; incorrect" + " bounds\n", i, row->lb, row->ub); + ret = GLP_EBOUND; + goto done; + } + } + for (j = 1; j <= P->n; j++) + { GLPCOL *col = P->col[j]; + if (col->type == GLP_DB && col->lb >= col->ub) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_intopt: column %d: lb = %g, ub = %g; incorr" + "ect bounds\n", j, col->lb, col->ub); + ret = GLP_EBOUND; + goto done; + } + } + /* bounds of all integer variables must be integral */ + for (j = 1; j <= P->n; j++) + { GLPCOL *col = P->col[j]; + if (col->kind != GLP_IV) continue; + if (col->type == GLP_LO || col->type == GLP_DB) + { if (col->lb != floor(col->lb)) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_intopt: integer column %d has non-intege" + "r lower bound %g\n", j, col->lb); + ret = GLP_EBOUND; + goto done; + } + } + if (col->type == GLP_UP || col->type == GLP_DB) + { if (col->ub != floor(col->ub)) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_intopt: integer column %d has non-intege" + "r upper bound %g\n", j, col->ub); + ret = GLP_EBOUND; + goto done; + } + } + if (col->type == GLP_FX) + { if (col->lb != floor(col->lb)) + { if (parm->msg_lev >= GLP_MSG_ERR) + xprintf("glp_intopt: integer column %d has non-intege" + "r fixed value %g\n", j, col->lb); + ret = GLP_EBOUND; + goto done; + } + } + } + /* solve MIP problem */ + if (parm->msg_lev >= GLP_MSG_ALL) + { int ni = glp_get_num_int(P); + int nb = glp_get_num_bin(P); + char s[50]; + xprintf("GLPK Integer Optimizer, v%s\n", glp_version()); + xprintf("%d row%s, %d column%s, %d non-zero%s\n", + P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s", + P->nnz, P->nnz == 1 ? "" : "s"); + if (nb == 0) + strcpy(s, "none of"); + else if (ni == 1 && nb == 1) + strcpy(s, ""); + else if (nb == 1) + strcpy(s, "one of"); + else if (nb == ni) + strcpy(s, "all of"); + else + sprintf(s, "%d of", nb); + xprintf("%d integer variable%s, %s which %s binary\n", + ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are"); + } +#if 1 /* 28/V-2010 */ + if (parm->alien) + { /* use alien integer optimizer */ + ret = _glp_intopt1(P, parm); + goto done; + } +#endif + if (!parm->presolve) +#if 0 /* 11/VII-2013 */ + ret = solve_mip(P, parm); +#else + ret = solve_mip(P, parm, P, NULL); +#endif + else + ret = preprocess_and_solve_mip(P, parm); +#if 1 /* 12/III-2013 */ + if (ret == GLP_ENOPFS) + P->mip_stat = GLP_NOFEAS; +#endif +done: /* return to the application program */ + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_init_iocp - initialize integer optimizer control parameters +* +* SYNOPSIS +* +* void glp_init_iocp(glp_iocp *parm); +* +* DESCRIPTION +* +* The routine glp_init_iocp initializes control parameters, which are +* used by the integer optimizer, with default values. +* +* Default values of the control parameters are stored in a glp_iocp +* structure, which the parameter parm points to. */ + +void glp_init_iocp(glp_iocp *parm) +{ parm->msg_lev = GLP_MSG_ALL; + parm->br_tech = GLP_BR_DTH; + parm->bt_tech = GLP_BT_BLB; + parm->tol_int = 1e-5; + parm->tol_obj = 1e-7; + parm->tm_lim = INT_MAX; + parm->out_frq = 5000; + parm->out_dly = 10000; + parm->cb_func = NULL; + parm->cb_info = NULL; + parm->cb_size = 0; + parm->pp_tech = GLP_PP_ALL; + parm->mip_gap = 0.0; + parm->mir_cuts = GLP_OFF; + parm->gmi_cuts = GLP_OFF; + parm->cov_cuts = GLP_OFF; + parm->clq_cuts = GLP_OFF; + parm->presolve = GLP_OFF; + parm->binarize = GLP_OFF; + parm->fp_heur = GLP_OFF; + parm->ps_heur = GLP_OFF; + parm->ps_tm_lim = 60000; /* 1 minute */ + parm->sr_heur = GLP_ON; +#if 1 /* 24/X-2015; not documented--should not be used */ + parm->use_sol = GLP_OFF; + parm->save_sol = NULL; + parm->alien = GLP_OFF; +#endif + return; +} + +/*********************************************************************** +* NAME +* +* glp_mip_status - retrieve status of MIP solution +* +* SYNOPSIS +* +* int glp_mip_status(glp_prob *mip); +* +* RETURNS +* +* The routine lpx_mip_status reports the status of MIP solution found +* by the branch-and-bound solver as follows: +* +* GLP_UNDEF - MIP solution is undefined; +* GLP_OPT - MIP solution is integer optimal; +* GLP_FEAS - MIP solution is integer feasible but its optimality +* (or non-optimality) has not been proven, perhaps due to +* premature termination of the search; +* GLP_NOFEAS - problem has no integer feasible solution (proven by the +* solver). */ + +int glp_mip_status(glp_prob *mip) +{ int mip_stat = mip->mip_stat; + return mip_stat; +} + +/*********************************************************************** +* NAME +* +* glp_mip_obj_val - retrieve objective value (MIP solution) +* +* SYNOPSIS +* +* double glp_mip_obj_val(glp_prob *mip); +* +* RETURNS +* +* The routine glp_mip_obj_val returns value of the objective function +* for MIP solution. */ + +double glp_mip_obj_val(glp_prob *mip) +{ /*struct LPXCPS *cps = mip->cps;*/ + double z; + z = mip->mip_obj; + /*if (cps->round && fabs(z) < 1e-9) z = 0.0;*/ + return z; +} + +/*********************************************************************** +* NAME +* +* glp_mip_row_val - retrieve row value (MIP solution) +* +* SYNOPSIS +* +* double glp_mip_row_val(glp_prob *mip, int i); +* +* RETURNS +* +* The routine glp_mip_row_val returns value of the auxiliary variable +* associated with i-th row. */ + +double glp_mip_row_val(glp_prob *mip, int i) +{ /*struct LPXCPS *cps = mip->cps;*/ + double mipx; + if (!(1 <= i && i <= mip->m)) + xerror("glp_mip_row_val: i = %d; row number out of range\n", i) + ; + mipx = mip->row[i]->mipx; + /*if (cps->round && fabs(mipx) < 1e-9) mipx = 0.0;*/ + return mipx; +} + +/*********************************************************************** +* NAME +* +* glp_mip_col_val - retrieve column value (MIP solution) +* +* SYNOPSIS +* +* double glp_mip_col_val(glp_prob *mip, int j); +* +* RETURNS +* +* The routine glp_mip_col_val returns value of the structural variable +* associated with j-th column. */ + +double glp_mip_col_val(glp_prob *mip, int j) +{ /*struct LPXCPS *cps = mip->cps;*/ + double mipx; + if (!(1 <= j && j <= mip->n)) + xerror("glp_mip_col_val: j = %d; column number out of range\n", + j); + mipx = mip->col[j]->mipx; + /*if (cps->round && fabs(mipx) < 1e-9) mipx = 0.0;*/ + return mipx; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi10.c b/resources/3rdparty/glpk-4.57/src/glpapi10.c new file mode 100644 index 000000000..5550aa39f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi10.c @@ -0,0 +1,305 @@ +/* glpapi10.c (solution checking routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "prob.h" + +void glp_check_kkt(glp_prob *P, int sol, int cond, double *_ae_max, + int *_ae_ind, double *_re_max, int *_re_ind) +{ /* check feasibility and optimality conditions */ + int m = P->m; + int n = P->n; + GLPROW *row; + GLPCOL *col; + GLPAIJ *aij; + int i, j, ae_ind, re_ind; + double e, sp, sn, t, ae_max, re_max; + if (!(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP)) + xerror("glp_check_kkt: sol = %d; invalid solution indicator\n", + sol); + if (!(cond == GLP_KKT_PE || cond == GLP_KKT_PB || + cond == GLP_KKT_DE || cond == GLP_KKT_DB || + cond == GLP_KKT_CS)) + xerror("glp_check_kkt: cond = %d; invalid condition indicator " + "\n", cond); + ae_max = re_max = 0.0; + ae_ind = re_ind = 0; + if (cond == GLP_KKT_PE) + { /* xR - A * xS = 0 */ + for (i = 1; i <= m; i++) + { row = P->row[i]; + sp = sn = 0.0; + /* t := xR[i] */ + if (sol == GLP_SOL) + t = row->prim; + else if (sol == GLP_IPT) + t = row->pval; + else if (sol == GLP_MIP) + t = row->mipx; + else + xassert(sol != sol); + if (t >= 0.0) sp += t; else sn -= t; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { col = aij->col; + /* t := - a[i,j] * xS[j] */ + if (sol == GLP_SOL) + t = - aij->val * col->prim; + else if (sol == GLP_IPT) + t = - aij->val * col->pval; + else if (sol == GLP_MIP) + t = - aij->val * col->mipx; + else + xassert(sol != sol); + if (t >= 0.0) sp += t; else sn -= t; + } + /* absolute error */ + e = fabs(sp - sn); + if (ae_max < e) + ae_max = e, ae_ind = i; + /* relative error */ + e /= (1.0 + sp + sn); + if (re_max < e) + re_max = e, re_ind = i; + } + } + else if (cond == GLP_KKT_PB) + { /* lR <= xR <= uR */ + for (i = 1; i <= m; i++) + { row = P->row[i]; + /* t := xR[i] */ + if (sol == GLP_SOL) + t = row->prim; + else if (sol == GLP_IPT) + t = row->pval; + else if (sol == GLP_MIP) + t = row->mipx; + else + xassert(sol != sol); + /* check lower bound */ + if (row->type == GLP_LO || row->type == GLP_DB || + row->type == GLP_FX) + { if (t < row->lb) + { /* absolute error */ + e = row->lb - t; + if (ae_max < e) + ae_max = e, ae_ind = i; + /* relative error */ + e /= (1.0 + fabs(row->lb)); + if (re_max < e) + re_max = e, re_ind = i; + } + } + /* check upper bound */ + if (row->type == GLP_UP || row->type == GLP_DB || + row->type == GLP_FX) + { if (t > row->ub) + { /* absolute error */ + e = t - row->ub; + if (ae_max < e) + ae_max = e, ae_ind = i; + /* relative error */ + e /= (1.0 + fabs(row->ub)); + if (re_max < e) + re_max = e, re_ind = i; + } + } + } + /* lS <= xS <= uS */ + for (j = 1; j <= n; j++) + { col = P->col[j]; + /* t := xS[j] */ + if (sol == GLP_SOL) + t = col->prim; + else if (sol == GLP_IPT) + t = col->pval; + else if (sol == GLP_MIP) + t = col->mipx; + else + xassert(sol != sol); + /* check lower bound */ + if (col->type == GLP_LO || col->type == GLP_DB || + col->type == GLP_FX) + { if (t < col->lb) + { /* absolute error */ + e = col->lb - t; + if (ae_max < e) + ae_max = e, ae_ind = m+j; + /* relative error */ + e /= (1.0 + fabs(col->lb)); + if (re_max < e) + re_max = e, re_ind = m+j; + } + } + /* check upper bound */ + if (col->type == GLP_UP || col->type == GLP_DB || + col->type == GLP_FX) + { if (t > col->ub) + { /* absolute error */ + e = t - col->ub; + if (ae_max < e) + ae_max = e, ae_ind = m+j; + /* relative error */ + e /= (1.0 + fabs(col->ub)); + if (re_max < e) + re_max = e, re_ind = m+j; + } + } + } + } + else if (cond == GLP_KKT_DE) + { /* A' * (lambdaR - cR) + (lambdaS - cS) = 0 */ + for (j = 1; j <= n; j++) + { col = P->col[j]; + sp = sn = 0.0; + /* t := lambdaS[j] - cS[j] */ + if (sol == GLP_SOL) + t = col->dual - col->coef; + else if (sol == GLP_IPT) + t = col->dval - col->coef; + else + xassert(sol != sol); + if (t >= 0.0) sp += t; else sn -= t; + for (aij = col->ptr; aij != NULL; aij = aij->c_next) + { row = aij->row; + /* t := a[i,j] * (lambdaR[i] - cR[i]) */ + if (sol == GLP_SOL) + t = aij->val * row->dual; + else if (sol == GLP_IPT) + t = aij->val * row->dval; + else + xassert(sol != sol); + if (t >= 0.0) sp += t; else sn -= t; + } + /* absolute error */ + e = fabs(sp - sn); + if (ae_max < e) + ae_max = e, ae_ind = m+j; + /* relative error */ + e /= (1.0 + sp + sn); + if (re_max < e) + re_max = e, re_ind = m+j; + } + } + else if (cond == GLP_KKT_DB) + { /* check lambdaR */ + for (i = 1; i <= m; i++) + { row = P->row[i]; + /* t := lambdaR[i] */ + if (sol == GLP_SOL) + t = row->dual; + else if (sol == GLP_IPT) + t = row->dval; + else + xassert(sol != sol); + /* correct sign */ + if (P->dir == GLP_MIN) + t = + t; + else if (P->dir == GLP_MAX) + t = - t; + else + xassert(P != P); + /* check for positivity */ +#if 1 /* 08/III-2013 */ + /* the former check was correct */ + /* the bug reported by David Price is related to violation + of complementarity slackness, not to this condition */ + if (row->type == GLP_FR || row->type == GLP_LO) +#else + if (row->stat == GLP_NF || row->stat == GLP_NL) +#endif + { if (t < 0.0) + { e = - t; + if (ae_max < e) + ae_max = re_max = e, ae_ind = re_ind = i; + } + } + /* check for negativity */ +#if 1 /* 08/III-2013 */ + /* see comment above */ + if (row->type == GLP_FR || row->type == GLP_UP) +#else + if (row->stat == GLP_NF || row->stat == GLP_NU) +#endif + { if (t > 0.0) + { e = + t; + if (ae_max < e) + ae_max = re_max = e, ae_ind = re_ind = i; + } + } + } + /* check lambdaS */ + for (j = 1; j <= n; j++) + { col = P->col[j]; + /* t := lambdaS[j] */ + if (sol == GLP_SOL) + t = col->dual; + else if (sol == GLP_IPT) + t = col->dval; + else + xassert(sol != sol); + /* correct sign */ + if (P->dir == GLP_MIN) + t = + t; + else if (P->dir == GLP_MAX) + t = - t; + else + xassert(P != P); + /* check for positivity */ +#if 1 /* 08/III-2013 */ + /* see comment above */ + if (col->type == GLP_FR || col->type == GLP_LO) +#else + if (col->stat == GLP_NF || col->stat == GLP_NL) +#endif + { if (t < 0.0) + { e = - t; + if (ae_max < e) + ae_max = re_max = e, ae_ind = re_ind = m+j; + } + } + /* check for negativity */ +#if 1 /* 08/III-2013 */ + /* see comment above */ + if (col->type == GLP_FR || col->type == GLP_UP) +#else + if (col->stat == GLP_NF || col->stat == GLP_NU) +#endif + { if (t > 0.0) + { e = + t; + if (ae_max < e) + ae_max = re_max = e, ae_ind = re_ind = m+j; + } + } + } + } + else + xassert(cond != cond); + if (_ae_max != NULL) *_ae_max = ae_max; + if (_ae_ind != NULL) *_ae_ind = ae_ind; + if (_re_max != NULL) *_re_max = re_max; + if (_re_ind != NULL) *_re_ind = re_ind; + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi11.c b/resources/3rdparty/glpk-4.57/src/glpapi11.c new file mode 100644 index 000000000..7bc528172 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi11.c @@ -0,0 +1,1235 @@ +/* glpapi11.c (utility routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpsdf.h" +#include "prob.h" + +#define xfprintf glp_format + +int glp_print_sol(glp_prob *P, const char *fname) +{ /* write basic solution in printable format */ + glp_file *fp; + GLPROW *row; + GLPCOL *col; + int i, j, t, ae_ind, re_ind, ret; + double ae_max, re_max; + xprintf("Writing basic solution to '%s'...\n", fname); + fp = glp_open(fname, "w"); + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xfprintf(fp, "%-12s%s\n", "Problem:", + P->name == NULL ? "" : P->name); + xfprintf(fp, "%-12s%d\n", "Rows:", P->m); + xfprintf(fp, "%-12s%d\n", "Columns:", P->n); + xfprintf(fp, "%-12s%d\n", "Non-zeros:", P->nnz); + t = glp_get_status(P); + xfprintf(fp, "%-12s%s\n", "Status:", + t == GLP_OPT ? "OPTIMAL" : + t == GLP_FEAS ? "FEASIBLE" : + t == GLP_INFEAS ? "INFEASIBLE (INTERMEDIATE)" : + t == GLP_NOFEAS ? "INFEASIBLE (FINAL)" : + t == GLP_UNBND ? "UNBOUNDED" : + t == GLP_UNDEF ? "UNDEFINED" : "???"); + xfprintf(fp, "%-12s%s%s%.10g (%s)\n", "Objective:", + P->obj == NULL ? "" : P->obj, + P->obj == NULL ? "" : " = ", P->obj_val, + P->dir == GLP_MIN ? "MINimum" : + P->dir == GLP_MAX ? "MAXimum" : "???"); + xfprintf(fp, "\n"); + xfprintf(fp, " No. Row name St Activity Lower bound " + " Upper bound Marginal\n"); + xfprintf(fp, "------ ------------ -- ------------- ------------- " + "------------- -------------\n"); + for (i = 1; i <= P->m; i++) + { row = P->row[i]; + xfprintf(fp, "%6d ", i); + if (row->name == NULL || strlen(row->name) <= 12) + xfprintf(fp, "%-12s ", row->name == NULL ? "" : row->name); + else + xfprintf(fp, "%s\n%20s", row->name, ""); + xfprintf(fp, "%s ", + row->stat == GLP_BS ? "B " : + row->stat == GLP_NL ? "NL" : + row->stat == GLP_NU ? "NU" : + row->stat == GLP_NF ? "NF" : + row->stat == GLP_NS ? "NS" : "??"); + xfprintf(fp, "%13.6g ", + fabs(row->prim) <= 1e-9 ? 0.0 : row->prim); + if (row->type == GLP_LO || row->type == GLP_DB || + row->type == GLP_FX) + xfprintf(fp, "%13.6g ", row->lb); + else + xfprintf(fp, "%13s ", ""); + if (row->type == GLP_UP || row->type == GLP_DB) + xfprintf(fp, "%13.6g ", row->ub); + else + xfprintf(fp, "%13s ", row->type == GLP_FX ? "=" : ""); + if (row->stat != GLP_BS) + { if (fabs(row->dual) <= 1e-9) + xfprintf(fp, "%13s", "< eps"); + else + xfprintf(fp, "%13.6g ", row->dual); + } + xfprintf(fp, "\n"); + } + xfprintf(fp, "\n"); + xfprintf(fp, " No. Column name St Activity Lower bound " + " Upper bound Marginal\n"); + xfprintf(fp, "------ ------------ -- ------------- ------------- " + "------------- -------------\n"); + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + xfprintf(fp, "%6d ", j); + if (col->name == NULL || strlen(col->name) <= 12) + xfprintf(fp, "%-12s ", col->name == NULL ? "" : col->name); + else + xfprintf(fp, "%s\n%20s", col->name, ""); + xfprintf(fp, "%s ", + col->stat == GLP_BS ? "B " : + col->stat == GLP_NL ? "NL" : + col->stat == GLP_NU ? "NU" : + col->stat == GLP_NF ? "NF" : + col->stat == GLP_NS ? "NS" : "??"); + xfprintf(fp, "%13.6g ", + fabs(col->prim) <= 1e-9 ? 0.0 : col->prim); + if (col->type == GLP_LO || col->type == GLP_DB || + col->type == GLP_FX) + xfprintf(fp, "%13.6g ", col->lb); + else + xfprintf(fp, "%13s ", ""); + if (col->type == GLP_UP || col->type == GLP_DB) + xfprintf(fp, "%13.6g ", col->ub); + else + xfprintf(fp, "%13s ", col->type == GLP_FX ? "=" : ""); + if (col->stat != GLP_BS) + { if (fabs(col->dual) <= 1e-9) + xfprintf(fp, "%13s", "< eps"); + else + xfprintf(fp, "%13.6g ", col->dual); + } + xfprintf(fp, "\n"); + } + xfprintf(fp, "\n"); + xfprintf(fp, "Karush-Kuhn-Tucker optimality conditions:\n"); + xfprintf(fp, "\n"); + glp_check_kkt(P, GLP_SOL, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, + &re_ind); + xfprintf(fp, "KKT.PE: max.abs.err = %.2e on row %d\n", + ae_max, ae_ind); + xfprintf(fp, " max.rel.err = %.2e on row %d\n", + re_max, re_ind); + xfprintf(fp, "%8s%s\n", "", + re_max <= 1e-9 ? "High quality" : + re_max <= 1e-6 ? "Medium quality" : + re_max <= 1e-3 ? "Low quality" : "PRIMAL SOLUTION IS WRONG"); + xfprintf(fp, "\n"); + glp_check_kkt(P, GLP_SOL, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, + &re_ind); + xfprintf(fp, "KKT.PB: max.abs.err = %.2e on %s %d\n", + ae_max, ae_ind <= P->m ? "row" : "column", + ae_ind <= P->m ? ae_ind : ae_ind - P->m); + xfprintf(fp, " max.rel.err = %.2e on %s %d\n", + re_max, re_ind <= P->m ? "row" : "column", + re_ind <= P->m ? re_ind : re_ind - P->m); + xfprintf(fp, "%8s%s\n", "", + re_max <= 1e-9 ? "High quality" : + re_max <= 1e-6 ? "Medium quality" : + re_max <= 1e-3 ? "Low quality" : "PRIMAL SOLUTION IS INFEASIBL" + "E"); + xfprintf(fp, "\n"); + glp_check_kkt(P, GLP_SOL, GLP_KKT_DE, &ae_max, &ae_ind, &re_max, + &re_ind); + xfprintf(fp, "KKT.DE: max.abs.err = %.2e on column %d\n", + ae_max, ae_ind == 0 ? 0 : ae_ind - P->m); + xfprintf(fp, " max.rel.err = %.2e on column %d\n", + re_max, re_ind == 0 ? 0 : re_ind - P->m); + xfprintf(fp, "%8s%s\n", "", + re_max <= 1e-9 ? "High quality" : + re_max <= 1e-6 ? "Medium quality" : + re_max <= 1e-3 ? "Low quality" : "DUAL SOLUTION IS WRONG"); + xfprintf(fp, "\n"); + glp_check_kkt(P, GLP_SOL, GLP_KKT_DB, &ae_max, &ae_ind, &re_max, + &re_ind); + xfprintf(fp, "KKT.DB: max.abs.err = %.2e on %s %d\n", + ae_max, ae_ind <= P->m ? "row" : "column", + ae_ind <= P->m ? ae_ind : ae_ind - P->m); + xfprintf(fp, " max.rel.err = %.2e on %s %d\n", + re_max, re_ind <= P->m ? "row" : "column", + re_ind <= P->m ? re_ind : re_ind - P->m); + xfprintf(fp, "%8s%s\n", "", + re_max <= 1e-9 ? "High quality" : + re_max <= 1e-6 ? "Medium quality" : + re_max <= 1e-3 ? "Low quality" : "DUAL SOLUTION IS INFEASIBLE") + ; + xfprintf(fp, "\n"); + xfprintf(fp, "End of output\n"); +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + ret = 0; +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_read_sol - read basic solution from text file +* +* SYNOPSIS +* +* int glp_read_sol(glp_prob *lp, const char *fname); +* +* DESCRIPTION +* +* The routine glp_read_sol reads basic solution from a text file whose +* name is specified by the parameter fname into the problem object. +* +* For the file format see description of the routine glp_write_sol. +* +* RETURNS +* +* On success the routine returns zero, otherwise non-zero. */ + +int glp_read_sol(glp_prob *lp, const char *fname) +{ glp_data *data; + jmp_buf jump; + int i, j, k, ret = 0; + xprintf("Reading basic solution from '%s'...\n", fname); + data = glp_sdf_open_file(fname); + if (data == NULL) + { ret = 1; + goto done; + } + if (setjmp(jump)) + { ret = 1; + goto done; + } + glp_sdf_set_jump(data, jump); + /* number of rows, number of columns */ + k = glp_sdf_read_int(data); + if (k != lp->m) + glp_sdf_error(data, "wrong number of rows\n"); + k = glp_sdf_read_int(data); + if (k != lp->n) + glp_sdf_error(data, "wrong number of columns\n"); + /* primal status, dual status, objective value */ + k = glp_sdf_read_int(data); + if (!(k == GLP_UNDEF || k == GLP_FEAS || k == GLP_INFEAS || + k == GLP_NOFEAS)) + glp_sdf_error(data, "invalid primal status\n"); + lp->pbs_stat = k; + k = glp_sdf_read_int(data); + if (!(k == GLP_UNDEF || k == GLP_FEAS || k == GLP_INFEAS || + k == GLP_NOFEAS)) + glp_sdf_error(data, "invalid dual status\n"); + lp->dbs_stat = k; + lp->obj_val = glp_sdf_read_num(data); + /* rows (auxiliary variables) */ + for (i = 1; i <= lp->m; i++) + { GLPROW *row = lp->row[i]; + /* status, primal value, dual value */ + k = glp_sdf_read_int(data); + if (!(k == GLP_BS || k == GLP_NL || k == GLP_NU || + k == GLP_NF || k == GLP_NS)) + glp_sdf_error(data, "invalid row status\n"); + glp_set_row_stat(lp, i, k); + row->prim = glp_sdf_read_num(data); + row->dual = glp_sdf_read_num(data); + } + /* columns (structural variables) */ + for (j = 1; j <= lp->n; j++) + { GLPCOL *col = lp->col[j]; + /* status, primal value, dual value */ + k = glp_sdf_read_int(data); + if (!(k == GLP_BS || k == GLP_NL || k == GLP_NU || + k == GLP_NF || k == GLP_NS)) + glp_sdf_error(data, "invalid column status\n"); + glp_set_col_stat(lp, j, k); + col->prim = glp_sdf_read_num(data); + col->dual = glp_sdf_read_num(data); + } + xprintf("%d lines were read\n", glp_sdf_line(data)); +done: if (ret) lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; + if (data != NULL) glp_sdf_close_file(data); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_write_sol - write basic solution to text file +* +* SYNOPSIS +* +* int glp_write_sol(glp_prob *lp, const char *fname); +* +* DESCRIPTION +* +* The routine glp_write_sol writes the current basic solution to a +* text file whose name is specified by the parameter fname. This file +* can be read back with the routine glp_read_sol. +* +* RETURNS +* +* On success the routine returns zero, otherwise non-zero. +* +* FILE FORMAT +* +* The file created by the routine glp_write_sol is a plain text file, +* which contains the following information: +* +* m n +* p_stat d_stat obj_val +* r_stat[1] r_prim[1] r_dual[1] +* . . . +* r_stat[m] r_prim[m] r_dual[m] +* c_stat[1] c_prim[1] c_dual[1] +* . . . +* c_stat[n] c_prim[n] c_dual[n] +* +* where: +* m is the number of rows (auxiliary variables); +* n is the number of columns (structural variables); +* p_stat is the primal status of the basic solution (GLP_UNDEF = 1, +* GLP_FEAS = 2, GLP_INFEAS = 3, or GLP_NOFEAS = 4); +* d_stat is the dual status of the basic solution (GLP_UNDEF = 1, +* GLP_FEAS = 2, GLP_INFEAS = 3, or GLP_NOFEAS = 4); +* obj_val is the objective value; +* r_stat[i], i = 1,...,m, is the status of i-th row (GLP_BS = 1, +* GLP_NL = 2, GLP_NU = 3, GLP_NF = 4, or GLP_NS = 5); +* r_prim[i], i = 1,...,m, is the primal value of i-th row; +* r_dual[i], i = 1,...,m, is the dual value of i-th row; +* c_stat[j], j = 1,...,n, is the status of j-th column (GLP_BS = 1, +* GLP_NL = 2, GLP_NU = 3, GLP_NF = 4, or GLP_NS = 5); +* c_prim[j], j = 1,...,n, is the primal value of j-th column; +* c_dual[j], j = 1,...,n, is the dual value of j-th column. */ + +int glp_write_sol(glp_prob *lp, const char *fname) +{ glp_file *fp; + int i, j, ret = 0; + xprintf("Writing basic solution to '%s'...\n", fname); + fp = glp_open(fname, "w"); + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + /* number of rows, number of columns */ + xfprintf(fp, "%d %d\n", lp->m, lp->n); + /* primal status, dual status, objective value */ + xfprintf(fp, "%d %d %.*g\n", lp->pbs_stat, lp->dbs_stat, DBL_DIG, + lp->obj_val); + /* rows (auxiliary variables) */ + for (i = 1; i <= lp->m; i++) + { GLPROW *row = lp->row[i]; + /* status, primal value, dual value */ + xfprintf(fp, "%d %.*g %.*g\n", row->stat, DBL_DIG, row->prim, + DBL_DIG, row->dual); + } + /* columns (structural variables) */ + for (j = 1; j <= lp->n; j++) + { GLPCOL *col = lp->col[j]; + /* status, primal value, dual value */ + xfprintf(fp, "%d %.*g %.*g\n", col->stat, DBL_DIG, col->prim, + DBL_DIG, col->dual); + } +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xprintf("%d lines were written\n", 2 + lp->m + lp->n); +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/**********************************************************************/ + +static char *format(char buf[13+1], double x) +{ /* format floating-point number in MPS/360-like style */ + if (x == -DBL_MAX) + strcpy(buf, " -Inf"); + else if (x == +DBL_MAX) + strcpy(buf, " +Inf"); + else if (fabs(x) <= 999999.99998) + { sprintf(buf, "%13.5f", x); +#if 1 + if (strcmp(buf, " 0.00000") == 0 || + strcmp(buf, " -0.00000") == 0) + strcpy(buf, " . "); + else if (memcmp(buf, " 0.", 8) == 0) + memcpy(buf, " .", 8); + else if (memcmp(buf, " -0.", 8) == 0) + memcpy(buf, " -.", 8); +#endif + } + else + sprintf(buf, "%13.6g", x); + return buf; +} + +int glp_print_ranges(glp_prob *P, int len, const int list[], + int flags, const char *fname) +{ /* print sensitivity analysis report */ + glp_file *fp = NULL; + GLPROW *row; + GLPCOL *col; + int m, n, pass, k, t, numb, type, stat, var1, var2, count, page, + ret; + double lb, ub, slack, coef, prim, dual, value1, value2, coef1, + coef2, obj1, obj2; + const char *name, *limit; + char buf[13+1]; + /* sanity checks */ + if (P == NULL || P->magic != GLP_PROB_MAGIC) + xerror("glp_print_ranges: P = %p; invalid problem object\n", + P); + m = P->m, n = P->n; + if (len < 0) + xerror("glp_print_ranges: len = %d; invalid list length\n", + len); + if (len > 0) + { if (list == NULL) + xerror("glp_print_ranges: list = %p: invalid parameter\n", + list); + for (t = 1; t <= len; t++) + { k = list[t]; + if (!(1 <= k && k <= m+n)) + xerror("glp_print_ranges: list[%d] = %d; row/column numb" + "er out of range\n", t, k); + } + } + if (flags != 0) + xerror("glp_print_ranges: flags = %d; invalid parameter\n", + flags); + if (fname == NULL) + xerror("glp_print_ranges: fname = %p; invalid parameter\n", + fname); + if (glp_get_status(P) != GLP_OPT) + { xprintf("glp_print_ranges: optimal basic solution required\n"); + ret = 1; + goto done; + } + if (!glp_bf_exists(P)) + { xprintf("glp_print_ranges: basis factorization required\n"); + ret = 2; + goto done; + } + /* start reporting */ + xprintf("Write sensitivity analysis report to '%s'...\n", fname); + fp = glp_open(fname, "w"); + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 3; + goto done; + } + page = count = 0; + for (pass = 1; pass <= 2; pass++) + for (t = 1; t <= (len == 0 ? m+n : len); t++) + { if (t == 1) count = 0; + k = (len == 0 ? t : list[t]); + if (pass == 1 && k > m || pass == 2 && k <= m) + continue; + if (count == 0) + { xfprintf(fp, "GLPK %-4s - SENSITIVITY ANALYSIS REPORT%73sPa" + "ge%4d\n", glp_version(), "", ++page); + xfprintf(fp, "\n"); + xfprintf(fp, "%-12s%s\n", "Problem:", + P->name == NULL ? "" : P->name); + xfprintf(fp, "%-12s%s%s%.10g (%s)\n", "Objective:", + P->obj == NULL ? "" : P->obj, + P->obj == NULL ? "" : " = ", P->obj_val, + P->dir == GLP_MIN ? "MINimum" : + P->dir == GLP_MAX ? "MAXimum" : "???"); + xfprintf(fp, "\n"); + xfprintf(fp, "%6s %-12s %2s %13s %13s %13s %13s %13s %13s " + "%s\n", "No.", pass == 1 ? "Row name" : "Column name", + "St", "Activity", pass == 1 ? "Slack" : "Obj coef", + "Lower bound", "Activity", "Obj coef", "Obj value at", + "Limiting"); + xfprintf(fp, "%6s %-12s %2s %13s %13s %13s %13s %13s %13s " + "%s\n", "", "", "", "", "Marginal", "Upper bound", + "range", "range", "break point", "variable"); + xfprintf(fp, "------ ------------ -- ------------- --------" + "----- ------------- ------------- ------------- ------" + "------- ------------\n"); + } + if (pass == 1) + { numb = k; + xassert(1 <= numb && numb <= m); + row = P->row[numb]; + name = row->name; + type = row->type; + lb = glp_get_row_lb(P, numb); + ub = glp_get_row_ub(P, numb); + coef = 0.0; + stat = row->stat; + prim = row->prim; + if (type == GLP_FR) + slack = - prim; + else if (type == GLP_LO) + slack = lb - prim; + else if (type == GLP_UP || type == GLP_DB || type == GLP_FX) + slack = ub - prim; + dual = row->dual; + } + else + { numb = k - m; + xassert(1 <= numb && numb <= n); + col = P->col[numb]; + name = col->name; + lb = glp_get_col_lb(P, numb); + ub = glp_get_col_ub(P, numb); + coef = col->coef; + stat = col->stat; + prim = col->prim; + slack = 0.0; + dual = col->dual; + } + if (stat != GLP_BS) + { glp_analyze_bound(P, k, &value1, &var1, &value2, &var2); + if (stat == GLP_NF) + coef1 = coef2 = coef; + else if (stat == GLP_NS) + coef1 = -DBL_MAX, coef2 = +DBL_MAX; + else if (stat == GLP_NL && P->dir == GLP_MIN || + stat == GLP_NU && P->dir == GLP_MAX) + coef1 = coef - dual, coef2 = +DBL_MAX; + else + coef1 = -DBL_MAX, coef2 = coef - dual; + if (value1 == -DBL_MAX) + { if (dual < -1e-9) + obj1 = +DBL_MAX; + else if (dual > +1e-9) + obj1 = -DBL_MAX; + else + obj1 = P->obj_val; + } + else + obj1 = P->obj_val + dual * (value1 - prim); + if (value2 == +DBL_MAX) + { if (dual < -1e-9) + obj2 = -DBL_MAX; + else if (dual > +1e-9) + obj2 = +DBL_MAX; + else + obj2 = P->obj_val; + } + else + obj2 = P->obj_val + dual * (value2 - prim); + } + else + { glp_analyze_coef(P, k, &coef1, &var1, &value1, &coef2, + &var2, &value2); + if (coef1 == -DBL_MAX) + { if (prim < -1e-9) + obj1 = +DBL_MAX; + else if (prim > +1e-9) + obj1 = -DBL_MAX; + else + obj1 = P->obj_val; + } + else + obj1 = P->obj_val + (coef1 - coef) * prim; + if (coef2 == +DBL_MAX) + { if (prim < -1e-9) + obj2 = -DBL_MAX; + else if (prim > +1e-9) + obj2 = +DBL_MAX; + else + obj2 = P->obj_val; + } + else + obj2 = P->obj_val + (coef2 - coef) * prim; + } + /*** first line ***/ + /* row/column number */ + xfprintf(fp, "%6d", numb); + /* row/column name */ + xfprintf(fp, " %-12.12s", name == NULL ? "" : name); + if (name != NULL && strlen(name) > 12) + xfprintf(fp, "%s\n%6s %12s", name+12, "", ""); + /* row/column status */ + xfprintf(fp, " %2s", + stat == GLP_BS ? "BS" : stat == GLP_NL ? "NL" : + stat == GLP_NU ? "NU" : stat == GLP_NF ? "NF" : + stat == GLP_NS ? "NS" : "??"); + /* row/column activity */ + xfprintf(fp, " %s", format(buf, prim)); + /* row slack, column objective coefficient */ + xfprintf(fp, " %s", format(buf, k <= m ? slack : coef)); + /* row/column lower bound */ + xfprintf(fp, " %s", format(buf, lb)); + /* row/column activity range */ + xfprintf(fp, " %s", format(buf, value1)); + /* row/column objective coefficient range */ + xfprintf(fp, " %s", format(buf, coef1)); + /* objective value at break point */ + xfprintf(fp, " %s", format(buf, obj1)); + /* limiting variable name */ + if (var1 != 0) + { if (var1 <= m) + limit = glp_get_row_name(P, var1); + else + limit = glp_get_col_name(P, var1 - m); + if (limit != NULL) + xfprintf(fp, " %s", limit); + } + xfprintf(fp, "\n"); + /*** second line ***/ + xfprintf(fp, "%6s %-12s %2s %13s", "", "", "", ""); + /* row/column reduced cost */ + xfprintf(fp, " %s", format(buf, dual)); + /* row/column upper bound */ + xfprintf(fp, " %s", format(buf, ub)); + /* row/column activity range */ + xfprintf(fp, " %s", format(buf, value2)); + /* row/column objective coefficient range */ + xfprintf(fp, " %s", format(buf, coef2)); + /* objective value at break point */ + xfprintf(fp, " %s", format(buf, obj2)); + /* limiting variable name */ + if (var2 != 0) + { if (var2 <= m) + limit = glp_get_row_name(P, var2); + else + limit = glp_get_col_name(P, var2 - m); + if (limit != NULL) + xfprintf(fp, " %s", limit); + } + xfprintf(fp, "\n"); + xfprintf(fp, "\n"); + /* print 10 items per page */ + count = (count + 1) % 10; + } + xfprintf(fp, "End of report\n"); +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 4; + goto done; + } + ret = 0; +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/**********************************************************************/ + +int glp_print_ipt(glp_prob *P, const char *fname) +{ /* write interior-point solution in printable format */ + glp_file *fp; + GLPROW *row; + GLPCOL *col; + int i, j, t, ae_ind, re_ind, ret; + double ae_max, re_max; + xprintf("Writing interior-point solution to '%s'...\n", fname); + fp = glp_open(fname, "w"); + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xfprintf(fp, "%-12s%s\n", "Problem:", + P->name == NULL ? "" : P->name); + xfprintf(fp, "%-12s%d\n", "Rows:", P->m); + xfprintf(fp, "%-12s%d\n", "Columns:", P->n); + xfprintf(fp, "%-12s%d\n", "Non-zeros:", P->nnz); + t = glp_ipt_status(P); + xfprintf(fp, "%-12s%s\n", "Status:", + t == GLP_OPT ? "OPTIMAL" : + t == GLP_UNDEF ? "UNDEFINED" : + t == GLP_INFEAS ? "INFEASIBLE (INTERMEDIATE)" : + t == GLP_NOFEAS ? "INFEASIBLE (FINAL)" : "???"); + xfprintf(fp, "%-12s%s%s%.10g (%s)\n", "Objective:", + P->obj == NULL ? "" : P->obj, + P->obj == NULL ? "" : " = ", P->ipt_obj, + P->dir == GLP_MIN ? "MINimum" : + P->dir == GLP_MAX ? "MAXimum" : "???"); + xfprintf(fp, "\n"); + xfprintf(fp, " No. Row name Activity Lower bound " + " Upper bound Marginal\n"); + xfprintf(fp, "------ ------------ ------------- ------------- " + "------------- -------------\n"); + for (i = 1; i <= P->m; i++) + { row = P->row[i]; + xfprintf(fp, "%6d ", i); + if (row->name == NULL || strlen(row->name) <= 12) + xfprintf(fp, "%-12s ", row->name == NULL ? "" : row->name); + else + xfprintf(fp, "%s\n%20s", row->name, ""); + xfprintf(fp, "%3s", ""); + xfprintf(fp, "%13.6g ", + fabs(row->pval) <= 1e-9 ? 0.0 : row->pval); + if (row->type == GLP_LO || row->type == GLP_DB || + row->type == GLP_FX) + xfprintf(fp, "%13.6g ", row->lb); + else + xfprintf(fp, "%13s ", ""); + if (row->type == GLP_UP || row->type == GLP_DB) + xfprintf(fp, "%13.6g ", row->ub); + else + xfprintf(fp, "%13s ", row->type == GLP_FX ? "=" : ""); + if (fabs(row->dval) <= 1e-9) + xfprintf(fp, "%13s", "< eps"); + else + xfprintf(fp, "%13.6g ", row->dval); + xfprintf(fp, "\n"); + } + xfprintf(fp, "\n"); + xfprintf(fp, " No. Column name Activity Lower bound " + " Upper bound Marginal\n"); + xfprintf(fp, "------ ------------ ------------- ------------- " + "------------- -------------\n"); + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + xfprintf(fp, "%6d ", j); + if (col->name == NULL || strlen(col->name) <= 12) + xfprintf(fp, "%-12s ", col->name == NULL ? "" : col->name); + else + xfprintf(fp, "%s\n%20s", col->name, ""); + xfprintf(fp, "%3s", ""); + xfprintf(fp, "%13.6g ", + fabs(col->pval) <= 1e-9 ? 0.0 : col->pval); + if (col->type == GLP_LO || col->type == GLP_DB || + col->type == GLP_FX) + xfprintf(fp, "%13.6g ", col->lb); + else + xfprintf(fp, "%13s ", ""); + if (col->type == GLP_UP || col->type == GLP_DB) + xfprintf(fp, "%13.6g ", col->ub); + else + xfprintf(fp, "%13s ", col->type == GLP_FX ? "=" : ""); + if (fabs(col->dval) <= 1e-9) + xfprintf(fp, "%13s", "< eps"); + else + xfprintf(fp, "%13.6g ", col->dval); + xfprintf(fp, "\n"); + } + xfprintf(fp, "\n"); + xfprintf(fp, "Karush-Kuhn-Tucker optimality conditions:\n"); + xfprintf(fp, "\n"); + glp_check_kkt(P, GLP_IPT, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, + &re_ind); + xfprintf(fp, "KKT.PE: max.abs.err = %.2e on row %d\n", + ae_max, ae_ind); + xfprintf(fp, " max.rel.err = %.2e on row %d\n", + re_max, re_ind); + xfprintf(fp, "%8s%s\n", "", + re_max <= 1e-9 ? "High quality" : + re_max <= 1e-6 ? "Medium quality" : + re_max <= 1e-3 ? "Low quality" : "PRIMAL SOLUTION IS WRONG"); + xfprintf(fp, "\n"); + glp_check_kkt(P, GLP_IPT, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, + &re_ind); + xfprintf(fp, "KKT.PB: max.abs.err = %.2e on %s %d\n", + ae_max, ae_ind <= P->m ? "row" : "column", + ae_ind <= P->m ? ae_ind : ae_ind - P->m); + xfprintf(fp, " max.rel.err = %.2e on %s %d\n", + re_max, re_ind <= P->m ? "row" : "column", + re_ind <= P->m ? re_ind : re_ind - P->m); + xfprintf(fp, "%8s%s\n", "", + re_max <= 1e-9 ? "High quality" : + re_max <= 1e-6 ? "Medium quality" : + re_max <= 1e-3 ? "Low quality" : "PRIMAL SOLUTION IS INFEASIBL" + "E"); + xfprintf(fp, "\n"); + glp_check_kkt(P, GLP_IPT, GLP_KKT_DE, &ae_max, &ae_ind, &re_max, + &re_ind); + xfprintf(fp, "KKT.DE: max.abs.err = %.2e on column %d\n", + ae_max, ae_ind == 0 ? 0 : ae_ind - P->m); + xfprintf(fp, " max.rel.err = %.2e on column %d\n", + re_max, re_ind == 0 ? 0 : re_ind - P->m); + xfprintf(fp, "%8s%s\n", "", + re_max <= 1e-9 ? "High quality" : + re_max <= 1e-6 ? "Medium quality" : + re_max <= 1e-3 ? "Low quality" : "DUAL SOLUTION IS WRONG"); + xfprintf(fp, "\n"); + glp_check_kkt(P, GLP_IPT, GLP_KKT_DB, &ae_max, &ae_ind, &re_max, + &re_ind); + xfprintf(fp, "KKT.DB: max.abs.err = %.2e on %s %d\n", + ae_max, ae_ind <= P->m ? "row" : "column", + ae_ind <= P->m ? ae_ind : ae_ind - P->m); + xfprintf(fp, " max.rel.err = %.2e on %s %d\n", + re_max, re_ind <= P->m ? "row" : "column", + re_ind <= P->m ? re_ind : re_ind - P->m); + xfprintf(fp, "%8s%s\n", "", + re_max <= 1e-9 ? "High quality" : + re_max <= 1e-6 ? "Medium quality" : + re_max <= 1e-3 ? "Low quality" : "DUAL SOLUTION IS INFEASIBLE") + ; + xfprintf(fp, "\n"); + xfprintf(fp, "End of output\n"); +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + ret = 0; +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_read_ipt - read interior-point solution from text file +* +* SYNOPSIS +* +* int glp_read_ipt(glp_prob *lp, const char *fname); +* +* DESCRIPTION +* +* The routine glp_read_ipt reads interior-point solution from a text +* file whose name is specified by the parameter fname into the problem +* object. +* +* For the file format see description of the routine glp_write_ipt. +* +* RETURNS +* +* On success the routine returns zero, otherwise non-zero. */ + +int glp_read_ipt(glp_prob *lp, const char *fname) +{ glp_data *data; + jmp_buf jump; + int i, j, k, ret = 0; + xprintf("Reading interior-point solution from '%s'...\n", fname); + data = glp_sdf_open_file(fname); + if (data == NULL) + { ret = 1; + goto done; + } + if (setjmp(jump)) + { ret = 1; + goto done; + } + glp_sdf_set_jump(data, jump); + /* number of rows, number of columns */ + k = glp_sdf_read_int(data); + if (k != lp->m) + glp_sdf_error(data, "wrong number of rows\n"); + k = glp_sdf_read_int(data); + if (k != lp->n) + glp_sdf_error(data, "wrong number of columns\n"); + /* solution status, objective value */ + k = glp_sdf_read_int(data); + if (!(k == GLP_UNDEF || k == GLP_OPT)) + glp_sdf_error(data, "invalid solution status\n"); + lp->ipt_stat = k; + lp->ipt_obj = glp_sdf_read_num(data); + /* rows (auxiliary variables) */ + for (i = 1; i <= lp->m; i++) + { GLPROW *row = lp->row[i]; + /* primal value, dual value */ + row->pval = glp_sdf_read_num(data); + row->dval = glp_sdf_read_num(data); + } + /* columns (structural variables) */ + for (j = 1; j <= lp->n; j++) + { GLPCOL *col = lp->col[j]; + /* primal value, dual value */ + col->pval = glp_sdf_read_num(data); + col->dval = glp_sdf_read_num(data); + } + xprintf("%d lines were read\n", glp_sdf_line(data)); +done: if (ret) lp->ipt_stat = GLP_UNDEF; + if (data != NULL) glp_sdf_close_file(data); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_write_ipt - write interior-point solution to text file +* +* SYNOPSIS +* +* int glp_write_ipt(glp_prob *lp, const char *fname); +* +* DESCRIPTION +* +* The routine glp_write_ipt writes the current interior-point solution +* to a text file whose name is specified by the parameter fname. This +* file can be read back with the routine glp_read_ipt. +* +* RETURNS +* +* On success the routine returns zero, otherwise non-zero. +* +* FILE FORMAT +* +* The file created by the routine glp_write_ipt is a plain text file, +* which contains the following information: +* +* m n +* stat obj_val +* r_prim[1] r_dual[1] +* . . . +* r_prim[m] r_dual[m] +* c_prim[1] c_dual[1] +* . . . +* c_prim[n] c_dual[n] +* +* where: +* m is the number of rows (auxiliary variables); +* n is the number of columns (structural variables); +* stat is the solution status (GLP_UNDEF = 1 or GLP_OPT = 5); +* obj_val is the objective value; +* r_prim[i], i = 1,...,m, is the primal value of i-th row; +* r_dual[i], i = 1,...,m, is the dual value of i-th row; +* c_prim[j], j = 1,...,n, is the primal value of j-th column; +* c_dual[j], j = 1,...,n, is the dual value of j-th column. */ + +int glp_write_ipt(glp_prob *lp, const char *fname) +{ glp_file *fp; + int i, j, ret = 0; + xprintf("Writing interior-point solution to '%s'...\n", fname); + fp = glp_open(fname, "w"); + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + /* number of rows, number of columns */ + xfprintf(fp, "%d %d\n", lp->m, lp->n); + /* solution status, objective value */ + xfprintf(fp, "%d %.*g\n", lp->ipt_stat, DBL_DIG, lp->ipt_obj); + /* rows (auxiliary variables) */ + for (i = 1; i <= lp->m; i++) + { GLPROW *row = lp->row[i]; + /* primal value, dual value */ + xfprintf(fp, "%.*g %.*g\n", DBL_DIG, row->pval, DBL_DIG, + row->dval); + } + /* columns (structural variables) */ + for (j = 1; j <= lp->n; j++) + { GLPCOL *col = lp->col[j]; + /* primal value, dual value */ + xfprintf(fp, "%.*g %.*g\n", DBL_DIG, col->pval, DBL_DIG, + col->dval); + } +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xprintf("%d lines were written\n", 2 + lp->m + lp->n); +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/**********************************************************************/ + +int glp_print_mip(glp_prob *P, const char *fname) +{ /* write MIP solution in printable format */ + glp_file *fp; + GLPROW *row; + GLPCOL *col; + int i, j, t, ae_ind, re_ind, ret; + double ae_max, re_max; + xprintf("Writing MIP solution to '%s'...\n", fname); + fp = glp_open(fname, "w"); + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xfprintf(fp, "%-12s%s\n", "Problem:", + P->name == NULL ? "" : P->name); + xfprintf(fp, "%-12s%d\n", "Rows:", P->m); + xfprintf(fp, "%-12s%d (%d integer, %d binary)\n", "Columns:", + P->n, glp_get_num_int(P), glp_get_num_bin(P)); + xfprintf(fp, "%-12s%d\n", "Non-zeros:", P->nnz); + t = glp_mip_status(P); + xfprintf(fp, "%-12s%s\n", "Status:", + t == GLP_OPT ? "INTEGER OPTIMAL" : + t == GLP_FEAS ? "INTEGER NON-OPTIMAL" : + t == GLP_NOFEAS ? "INTEGER EMPTY" : + t == GLP_UNDEF ? "INTEGER UNDEFINED" : "???"); + xfprintf(fp, "%-12s%s%s%.10g (%s)\n", "Objective:", + P->obj == NULL ? "" : P->obj, + P->obj == NULL ? "" : " = ", P->mip_obj, + P->dir == GLP_MIN ? "MINimum" : + P->dir == GLP_MAX ? "MAXimum" : "???"); + xfprintf(fp, "\n"); + xfprintf(fp, " No. Row name Activity Lower bound " + " Upper bound\n"); + xfprintf(fp, "------ ------------ ------------- ------------- " + "-------------\n"); + for (i = 1; i <= P->m; i++) + { row = P->row[i]; + xfprintf(fp, "%6d ", i); + if (row->name == NULL || strlen(row->name) <= 12) + xfprintf(fp, "%-12s ", row->name == NULL ? "" : row->name); + else + xfprintf(fp, "%s\n%20s", row->name, ""); + xfprintf(fp, "%3s", ""); + xfprintf(fp, "%13.6g ", + fabs(row->mipx) <= 1e-9 ? 0.0 : row->mipx); + if (row->type == GLP_LO || row->type == GLP_DB || + row->type == GLP_FX) + xfprintf(fp, "%13.6g ", row->lb); + else + xfprintf(fp, "%13s ", ""); + if (row->type == GLP_UP || row->type == GLP_DB) + xfprintf(fp, "%13.6g ", row->ub); + else + xfprintf(fp, "%13s ", row->type == GLP_FX ? "=" : ""); + xfprintf(fp, "\n"); + } + xfprintf(fp, "\n"); + xfprintf(fp, " No. Column name Activity Lower bound " + " Upper bound\n"); + xfprintf(fp, "------ ------------ ------------- ------------- " + "-------------\n"); + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + xfprintf(fp, "%6d ", j); + if (col->name == NULL || strlen(col->name) <= 12) + xfprintf(fp, "%-12s ", col->name == NULL ? "" : col->name); + else + xfprintf(fp, "%s\n%20s", col->name, ""); + xfprintf(fp, "%s ", + col->kind == GLP_CV ? " " : + col->kind == GLP_IV ? "*" : "?"); + xfprintf(fp, "%13.6g ", + fabs(col->mipx) <= 1e-9 ? 0.0 : col->mipx); + if (col->type == GLP_LO || col->type == GLP_DB || + col->type == GLP_FX) + xfprintf(fp, "%13.6g ", col->lb); + else + xfprintf(fp, "%13s ", ""); + if (col->type == GLP_UP || col->type == GLP_DB) + xfprintf(fp, "%13.6g ", col->ub); + else + xfprintf(fp, "%13s ", col->type == GLP_FX ? "=" : ""); + xfprintf(fp, "\n"); + } + xfprintf(fp, "\n"); + xfprintf(fp, "Integer feasibility conditions:\n"); + xfprintf(fp, "\n"); + glp_check_kkt(P, GLP_MIP, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, + &re_ind); + xfprintf(fp, "KKT.PE: max.abs.err = %.2e on row %d\n", + ae_max, ae_ind); + xfprintf(fp, " max.rel.err = %.2e on row %d\n", + re_max, re_ind); + xfprintf(fp, "%8s%s\n", "", + re_max <= 1e-9 ? "High quality" : + re_max <= 1e-6 ? "Medium quality" : + re_max <= 1e-3 ? "Low quality" : "SOLUTION IS WRONG"); + xfprintf(fp, "\n"); + glp_check_kkt(P, GLP_MIP, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, + &re_ind); + xfprintf(fp, "KKT.PB: max.abs.err = %.2e on %s %d\n", + ae_max, ae_ind <= P->m ? "row" : "column", + ae_ind <= P->m ? ae_ind : ae_ind - P->m); + xfprintf(fp, " max.rel.err = %.2e on %s %d\n", + re_max, re_ind <= P->m ? "row" : "column", + re_ind <= P->m ? re_ind : re_ind - P->m); + xfprintf(fp, "%8s%s\n", "", + re_max <= 1e-9 ? "High quality" : + re_max <= 1e-6 ? "Medium quality" : + re_max <= 1e-3 ? "Low quality" : "SOLUTION IS INFEASIBLE"); + xfprintf(fp, "\n"); + xfprintf(fp, "End of output\n"); +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + ret = 0; +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_read_mip - read MIP solution from text file +* +* SYNOPSIS +* +* int glp_read_mip(glp_prob *mip, const char *fname); +* +* DESCRIPTION +* +* The routine glp_read_mip reads MIP solution from a text file whose +* name is specified by the parameter fname into the problem object. +* +* For the file format see description of the routine glp_write_mip. +* +* RETURNS +* +* On success the routine returns zero, otherwise non-zero. */ + +int glp_read_mip(glp_prob *mip, const char *fname) +{ glp_data *data; + jmp_buf jump; + int i, j, k, ret = 0; + xprintf("Reading MIP solution from '%s'...\n", fname); + data = glp_sdf_open_file(fname); + if (data == NULL) + { ret = 1; + goto done; + } + if (setjmp(jump)) + { ret = 1; + goto done; + } + glp_sdf_set_jump(data, jump); + /* number of rows, number of columns */ + k = glp_sdf_read_int(data); + if (k != mip->m) + glp_sdf_error(data, "wrong number of rows\n"); + k = glp_sdf_read_int(data); + if (k != mip->n) + glp_sdf_error(data, "wrong number of columns\n"); + /* solution status, objective value */ + k = glp_sdf_read_int(data); + if (!(k == GLP_UNDEF || k == GLP_OPT || k == GLP_FEAS || + k == GLP_NOFEAS)) + glp_sdf_error(data, "invalid solution status\n"); + mip->mip_stat = k; + mip->mip_obj = glp_sdf_read_num(data); + /* rows (auxiliary variables) */ + for (i = 1; i <= mip->m; i++) + { GLPROW *row = mip->row[i]; + row->mipx = glp_sdf_read_num(data); + } + /* columns (structural variables) */ + for (j = 1; j <= mip->n; j++) + { GLPCOL *col = mip->col[j]; + col->mipx = glp_sdf_read_num(data); + if (col->kind == GLP_IV && col->mipx != floor(col->mipx)) + glp_sdf_error(data, "non-integer column value"); + } + xprintf("%d lines were read\n", glp_sdf_line(data)); +done: if (ret) mip->mip_stat = GLP_UNDEF; + if (data != NULL) glp_sdf_close_file(data); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_write_mip - write MIP solution to text file +* +* SYNOPSIS +* +* int glp_write_mip(glp_prob *mip, const char *fname); +* +* DESCRIPTION +* +* The routine glp_write_mip writes the current MIP solution to a text +* file whose name is specified by the parameter fname. This file can +* be read back with the routine glp_read_mip. +* +* RETURNS +* +* On success the routine returns zero, otherwise non-zero. +* +* FILE FORMAT +* +* The file created by the routine glp_write_sol is a plain text file, +* which contains the following information: +* +* m n +* stat obj_val +* r_val[1] +* . . . +* r_val[m] +* c_val[1] +* . . . +* c_val[n] +* +* where: +* m is the number of rows (auxiliary variables); +* n is the number of columns (structural variables); +* stat is the solution status (GLP_UNDEF = 1, GLP_FEAS = 2, +* GLP_NOFEAS = 4, or GLP_OPT = 5); +* obj_val is the objective value; +* r_val[i], i = 1,...,m, is the value of i-th row; +* c_val[j], j = 1,...,n, is the value of j-th column. */ + +int glp_write_mip(glp_prob *mip, const char *fname) +{ glp_file *fp; + int i, j, ret = 0; + xprintf("Writing MIP solution to '%s'...\n", fname); + fp = glp_open(fname, "w"); + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + /* number of rows, number of columns */ + xfprintf(fp, "%d %d\n", mip->m, mip->n); + /* solution status, objective value */ + xfprintf(fp, "%d %.*g\n", mip->mip_stat, DBL_DIG, mip->mip_obj); + /* rows (auxiliary variables) */ + for (i = 1; i <= mip->m; i++) + xfprintf(fp, "%.*g\n", DBL_DIG, mip->row[i]->mipx); + /* columns (structural variables) */ + for (j = 1; j <= mip->n; j++) + xfprintf(fp, "%.*g\n", DBL_DIG, mip->col[j]->mipx); +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xprintf("%d lines were written\n", 2 + mip->m + mip->n); +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi12.c b/resources/3rdparty/glpk-4.57/src/glpapi12.c new file mode 100644 index 000000000..120953048 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi12.c @@ -0,0 +1,2181 @@ +/* glpapi12.c (basis factorization and simplex tableau routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "draft.h" +#include "env.h" +#include "prob.h" + +/*********************************************************************** +* NAME +* +* glp_bf_exists - check if the basis factorization exists +* +* SYNOPSIS +* +* int glp_bf_exists(glp_prob *lp); +* +* RETURNS +* +* If the basis factorization for the current basis associated with +* the specified problem object exists and therefore is available for +* computations, the routine glp_bf_exists returns non-zero. Otherwise +* the routine returns zero. */ + +int glp_bf_exists(glp_prob *lp) +{ int ret; + ret = (lp->m == 0 || lp->valid); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_factorize - compute the basis factorization +* +* SYNOPSIS +* +* int glp_factorize(glp_prob *lp); +* +* DESCRIPTION +* +* The routine glp_factorize computes the basis factorization for the +* current basis associated with the specified problem object. +* +* RETURNS +* +* 0 The basis factorization has been successfully computed. +* +* GLP_EBADB +* The basis matrix is invalid, i.e. the number of basic (auxiliary +* and structural) variables differs from the number of rows in the +* problem object. +* +* GLP_ESING +* The basis matrix is singular within the working precision. +* +* GLP_ECOND +* The basis matrix is ill-conditioned. */ + +static int b_col(void *info, int j, int ind[], double val[]) +{ glp_prob *lp = info; + int m = lp->m; + GLPAIJ *aij; + int k, len; + xassert(1 <= j && j <= m); + /* determine the ordinal number of basic auxiliary or structural + variable x[k] corresponding to basic variable xB[j] */ + k = lp->head[j]; + /* build j-th column of the basic matrix, which is k-th column of + the scaled augmented matrix (I | -R*A*S) */ + if (k <= m) + { /* x[k] is auxiliary variable */ + len = 1; + ind[1] = k; + val[1] = 1.0; + } + else + { /* x[k] is structural variable */ + len = 0; + for (aij = lp->col[k-m]->ptr; aij != NULL; aij = aij->c_next) + { len++; + ind[len] = aij->row->i; + val[len] = - aij->row->rii * aij->val * aij->col->sjj; + } + } + return len; +} + +int glp_factorize(glp_prob *lp) +{ int m = lp->m; + int n = lp->n; + GLPROW **row = lp->row; + GLPCOL **col = lp->col; + int *head = lp->head; + int j, k, stat, ret; + /* invalidate the basis factorization */ + lp->valid = 0; + /* build the basis header */ + j = 0; + for (k = 1; k <= m+n; k++) + { if (k <= m) + { stat = row[k]->stat; + row[k]->bind = 0; + } + else + { stat = col[k-m]->stat; + col[k-m]->bind = 0; + } + if (stat == GLP_BS) + { j++; + if (j > m) + { /* too many basic variables */ + ret = GLP_EBADB; + goto fini; + } + head[j] = k; + if (k <= m) + row[k]->bind = j; + else + col[k-m]->bind = j; + } + } + if (j < m) + { /* too few basic variables */ + ret = GLP_EBADB; + goto fini; + } + /* try to factorize the basis matrix */ + if (m > 0) + { if (lp->bfd == NULL) + { lp->bfd = bfd_create_it(); +#if 0 /* 08/III-2014 */ + copy_bfcp(lp); +#endif + } + switch (bfd_factorize(lp->bfd, m, /*lp->head,*/ b_col, lp)) + { case 0: + /* ok */ + break; + case BFD_ESING: + /* singular matrix */ + ret = GLP_ESING; + goto fini; + case BFD_ECOND: + /* ill-conditioned matrix */ + ret = GLP_ECOND; + goto fini; + default: + xassert(lp != lp); + } + lp->valid = 1; + } + /* factorization successful */ + ret = 0; +fini: /* bring the return code to the calling program */ + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_bf_updated - check if the basis factorization has been updated +* +* SYNOPSIS +* +* int glp_bf_updated(glp_prob *lp); +* +* RETURNS +* +* If the basis factorization has been just computed from scratch, the +* routine glp_bf_updated returns zero. Otherwise, if the factorization +* has been updated one or more times, the routine returns non-zero. */ + +int glp_bf_updated(glp_prob *lp) +{ int cnt; + if (!(lp->m == 0 || lp->valid)) + xerror("glp_bf_update: basis factorization does not exist\n"); +#if 0 /* 15/XI-2009 */ + cnt = (lp->m == 0 ? 0 : lp->bfd->upd_cnt); +#else + cnt = (lp->m == 0 ? 0 : bfd_get_count(lp->bfd)); +#endif + return cnt; +} + +/*********************************************************************** +* NAME +* +* glp_get_bfcp - retrieve basis factorization control parameters +* +* SYNOPSIS +* +* void glp_get_bfcp(glp_prob *lp, glp_bfcp *parm); +* +* DESCRIPTION +* +* The routine glp_get_bfcp retrieves control parameters, which are +* used on computing and updating the basis factorization associated +* with the specified problem object. +* +* Current values of control parameters are stored by the routine in +* a glp_bfcp structure, which the parameter parm points to. */ + +#if 1 /* 08/III-2014 */ +void glp_get_bfcp(glp_prob *P, glp_bfcp *parm) +{ if (P->bfd == NULL) + P->bfd = bfd_create_it(); + bfd_get_bfcp(P->bfd, parm); + return; +} +#endif + +/*********************************************************************** +* NAME +* +* glp_set_bfcp - change basis factorization control parameters +* +* SYNOPSIS +* +* void glp_set_bfcp(glp_prob *lp, const glp_bfcp *parm); +* +* DESCRIPTION +* +* The routine glp_set_bfcp changes control parameters, which are used +* by internal GLPK routines in computing and updating the basis +* factorization associated with the specified problem object. +* +* New values of the control parameters should be passed in a structure +* glp_bfcp, which the parameter parm points to. +* +* The parameter parm can be specified as NULL, in which case all +* control parameters are reset to their default values. */ + +#if 1 /* 08/III-2014 */ +void glp_set_bfcp(glp_prob *P, const glp_bfcp *parm) +{ if (P->bfd == NULL) + P->bfd = bfd_create_it(); + if (parm != NULL) + { if (!(parm->type == GLP_BF_LUF + GLP_BF_FT || + parm->type == GLP_BF_LUF + GLP_BF_BG || + parm->type == GLP_BF_LUF + GLP_BF_GR || + parm->type == GLP_BF_BTF + GLP_BF_BG || + parm->type == GLP_BF_BTF + GLP_BF_GR)) + xerror("glp_set_bfcp: type = 0x%02X; invalid parameter\n", + parm->type); + if (!(0.0 < parm->piv_tol && parm->piv_tol < 1.0)) + xerror("glp_set_bfcp: piv_tol = %g; invalid parameter\n", + parm->piv_tol); + if (parm->piv_lim < 1) + xerror("glp_set_bfcp: piv_lim = %d; invalid parameter\n", + parm->piv_lim); + if (!(parm->suhl == GLP_ON || parm->suhl == GLP_OFF)) + xerror("glp_set_bfcp: suhl = %d; invalid parameter\n", + parm->suhl); + if (!(0.0 <= parm->eps_tol && parm->eps_tol <= 1e-6)) + xerror("glp_set_bfcp: eps_tol = %g; invalid parameter\n", + parm->eps_tol); + if (!(1 <= parm->nfs_max && parm->nfs_max <= 32767)) + xerror("glp_set_bfcp: nfs_max = %d; invalid parameter\n", + parm->nfs_max); + if (!(1 <= parm->nrs_max && parm->nrs_max <= 32767)) + xerror("glp_set_bfcp: nrs_max = %d; invalid parameter\n", + parm->nrs_max); + } + bfd_set_bfcp(P->bfd, parm); + return; +} +#endif + +/*********************************************************************** +* NAME +* +* glp_get_bhead - retrieve the basis header information +* +* SYNOPSIS +* +* int glp_get_bhead(glp_prob *lp, int k); +* +* DESCRIPTION +* +* The routine glp_get_bhead returns the basis header information for +* the current basis associated with the specified problem object. +* +* RETURNS +* +* If xB[k], 1 <= k <= m, is i-th auxiliary variable (1 <= i <= m), the +* routine returns i. Otherwise, if xB[k] is j-th structural variable +* (1 <= j <= n), the routine returns m+j. Here m is the number of rows +* and n is the number of columns in the problem object. */ + +int glp_get_bhead(glp_prob *lp, int k) +{ if (!(lp->m == 0 || lp->valid)) + xerror("glp_get_bhead: basis factorization does not exist\n"); + if (!(1 <= k && k <= lp->m)) + xerror("glp_get_bhead: k = %d; index out of range\n", k); + return lp->head[k]; +} + +/*********************************************************************** +* NAME +* +* glp_get_row_bind - retrieve row index in the basis header +* +* SYNOPSIS +* +* int glp_get_row_bind(glp_prob *lp, int i); +* +* RETURNS +* +* The routine glp_get_row_bind returns the index k of basic variable +* xB[k], 1 <= k <= m, which is i-th auxiliary variable, 1 <= i <= m, +* in the current basis associated with the specified problem object, +* where m is the number of rows. However, if i-th auxiliary variable +* is non-basic, the routine returns zero. */ + +int glp_get_row_bind(glp_prob *lp, int i) +{ if (!(lp->m == 0 || lp->valid)) + xerror("glp_get_row_bind: basis factorization does not exist\n" + ); + if (!(1 <= i && i <= lp->m)) + xerror("glp_get_row_bind: i = %d; row number out of range\n", + i); + return lp->row[i]->bind; +} + +/*********************************************************************** +* NAME +* +* glp_get_col_bind - retrieve column index in the basis header +* +* SYNOPSIS +* +* int glp_get_col_bind(glp_prob *lp, int j); +* +* RETURNS +* +* The routine glp_get_col_bind returns the index k of basic variable +* xB[k], 1 <= k <= m, which is j-th structural variable, 1 <= j <= n, +* in the current basis associated with the specified problem object, +* where m is the number of rows, n is the number of columns. However, +* if j-th structural variable is non-basic, the routine returns zero.*/ + +int glp_get_col_bind(glp_prob *lp, int j) +{ if (!(lp->m == 0 || lp->valid)) + xerror("glp_get_col_bind: basis factorization does not exist\n" + ); + if (!(1 <= j && j <= lp->n)) + xerror("glp_get_col_bind: j = %d; column number out of range\n" + , j); + return lp->col[j]->bind; +} + +/*********************************************************************** +* NAME +* +* glp_ftran - perform forward transformation (solve system B*x = b) +* +* SYNOPSIS +* +* void glp_ftran(glp_prob *lp, double x[]); +* +* DESCRIPTION +* +* The routine glp_ftran performs forward transformation, i.e. solves +* the system B*x = b, where B is the basis matrix corresponding to the +* current basis for the specified problem object, x is the vector of +* unknowns to be computed, b is the vector of right-hand sides. +* +* On entry elements of the vector b should be stored in dense format +* in locations x[1], ..., x[m], where m is the number of rows. On exit +* the routine stores elements of the vector x in the same locations. +* +* SCALING/UNSCALING +* +* Let A~ = (I | -A) is the augmented constraint matrix of the original +* (unscaled) problem. In the scaled LP problem instead the matrix A the +* scaled matrix A" = R*A*S is actually used, so +* +* A~" = (I | A") = (I | R*A*S) = (R*I*inv(R) | R*A*S) = +* (1) +* = R*(I | A)*S~ = R*A~*S~, +* +* is the scaled augmented constraint matrix, where R and S are diagonal +* scaling matrices used to scale rows and columns of the matrix A, and +* +* S~ = diag(inv(R) | S) (2) +* +* is an augmented diagonal scaling matrix. +* +* By definition: +* +* A~ = (B | N), (3) +* +* where B is the basic matrix, which consists of basic columns of the +* augmented constraint matrix A~, and N is a matrix, which consists of +* non-basic columns of A~. From (1) it follows that: +* +* A~" = (B" | N") = (R*B*SB | R*N*SN), (4) +* +* where SB and SN are parts of the augmented scaling matrix S~, which +* correspond to basic and non-basic variables, respectively. Therefore +* +* B" = R*B*SB, (5) +* +* which is the scaled basis matrix. */ + +void glp_ftran(glp_prob *lp, double x[]) +{ int m = lp->m; + GLPROW **row = lp->row; + GLPCOL **col = lp->col; + int i, k; + /* B*x = b ===> (R*B*SB)*(inv(SB)*x) = R*b ===> + B"*x" = b", where b" = R*b, x = SB*x" */ + if (!(m == 0 || lp->valid)) + xerror("glp_ftran: basis factorization does not exist\n"); + /* b" := R*b */ + for (i = 1; i <= m; i++) + x[i] *= row[i]->rii; + /* x" := inv(B")*b" */ + if (m > 0) bfd_ftran(lp->bfd, x); + /* x := SB*x" */ + for (i = 1; i <= m; i++) + { k = lp->head[i]; + if (k <= m) + x[i] /= row[k]->rii; + else + x[i] *= col[k-m]->sjj; + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_btran - perform backward transformation (solve system B'*x = b) +* +* SYNOPSIS +* +* void glp_btran(glp_prob *lp, double x[]); +* +* DESCRIPTION +* +* The routine glp_btran performs backward transformation, i.e. solves +* the system B'*x = b, where B' is a matrix transposed to the basis +* matrix corresponding to the current basis for the specified problem +* problem object, x is the vector of unknowns to be computed, b is the +* vector of right-hand sides. +* +* On entry elements of the vector b should be stored in dense format +* in locations x[1], ..., x[m], where m is the number of rows. On exit +* the routine stores elements of the vector x in the same locations. +* +* SCALING/UNSCALING +* +* See comments to the routine glp_ftran. */ + +void glp_btran(glp_prob *lp, double x[]) +{ int m = lp->m; + GLPROW **row = lp->row; + GLPCOL **col = lp->col; + int i, k; + /* B'*x = b ===> (SB*B'*R)*(inv(R)*x) = SB*b ===> + (B")'*x" = b", where b" = SB*b, x = R*x" */ + if (!(m == 0 || lp->valid)) + xerror("glp_btran: basis factorization does not exist\n"); + /* b" := SB*b */ + for (i = 1; i <= m; i++) + { k = lp->head[i]; + if (k <= m) + x[i] /= row[k]->rii; + else + x[i] *= col[k-m]->sjj; + } + /* x" := inv[(B")']*b" */ + if (m > 0) bfd_btran(lp->bfd, x); + /* x := R*x" */ + for (i = 1; i <= m; i++) + x[i] *= row[i]->rii; + return; +} + +/*********************************************************************** +* NAME +* +* glp_warm_up - "warm up" LP basis +* +* SYNOPSIS +* +* int glp_warm_up(glp_prob *P); +* +* DESCRIPTION +* +* The routine glp_warm_up "warms up" the LP basis for the specified +* problem object using current statuses assigned to rows and columns +* (that is, to auxiliary and structural variables). +* +* This operation includes computing factorization of the basis matrix +* (if it does not exist), computing primal and dual components of basic +* solution, and determining the solution status. +* +* RETURNS +* +* 0 The operation has been successfully performed. +* +* GLP_EBADB +* The basis matrix is invalid, i.e. the number of basic (auxiliary +* and structural) variables differs from the number of rows in the +* problem object. +* +* GLP_ESING +* The basis matrix is singular within the working precision. +* +* GLP_ECOND +* The basis matrix is ill-conditioned. */ + +int glp_warm_up(glp_prob *P) +{ GLPROW *row; + GLPCOL *col; + GLPAIJ *aij; + int i, j, type, stat, ret; + double eps, temp, *work; + /* invalidate basic solution */ + P->pbs_stat = P->dbs_stat = GLP_UNDEF; + P->obj_val = 0.0; + P->some = 0; + for (i = 1; i <= P->m; i++) + { row = P->row[i]; + row->prim = row->dual = 0.0; + } + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + col->prim = col->dual = 0.0; + } + /* compute the basis factorization, if necessary */ + if (!glp_bf_exists(P)) + { ret = glp_factorize(P); + if (ret != 0) goto done; + } + /* allocate working array */ + work = xcalloc(1+P->m, sizeof(double)); + /* determine and store values of non-basic variables, compute + vector (- N * xN) */ + for (i = 1; i <= P->m; i++) + work[i] = 0.0; + for (i = 1; i <= P->m; i++) + { row = P->row[i]; + if (row->stat == GLP_BS) + continue; + else if (row->stat == GLP_NL) + row->prim = row->lb; + else if (row->stat == GLP_NU) + row->prim = row->ub; + else if (row->stat == GLP_NF) + row->prim = 0.0; + else if (row->stat == GLP_NS) + row->prim = row->lb; + else + xassert(row != row); + /* N[j] is i-th column of matrix (I|-A) */ + work[i] -= row->prim; + } + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + if (col->stat == GLP_BS) + continue; + else if (col->stat == GLP_NL) + col->prim = col->lb; + else if (col->stat == GLP_NU) + col->prim = col->ub; + else if (col->stat == GLP_NF) + col->prim = 0.0; + else if (col->stat == GLP_NS) + col->prim = col->lb; + else + xassert(col != col); + /* N[j] is (m+j)-th column of matrix (I|-A) */ + if (col->prim != 0.0) + { for (aij = col->ptr; aij != NULL; aij = aij->c_next) + work[aij->row->i] += aij->val * col->prim; + } + } + /* compute vector of basic variables xB = - inv(B) * N * xN */ + glp_ftran(P, work); + /* store values of basic variables, check primal feasibility */ + P->pbs_stat = GLP_FEAS; + for (i = 1; i <= P->m; i++) + { row = P->row[i]; + if (row->stat != GLP_BS) + continue; + row->prim = work[row->bind]; + type = row->type; + if (type == GLP_LO || type == GLP_DB || type == GLP_FX) + { eps = 1e-6 + 1e-9 * fabs(row->lb); + if (row->prim < row->lb - eps) + P->pbs_stat = GLP_INFEAS; + } + if (type == GLP_UP || type == GLP_DB || type == GLP_FX) + { eps = 1e-6 + 1e-9 * fabs(row->ub); + if (row->prim > row->ub + eps) + P->pbs_stat = GLP_INFEAS; + } + } + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + if (col->stat != GLP_BS) + continue; + col->prim = work[col->bind]; + type = col->type; + if (type == GLP_LO || type == GLP_DB || type == GLP_FX) + { eps = 1e-6 + 1e-9 * fabs(col->lb); + if (col->prim < col->lb - eps) + P->pbs_stat = GLP_INFEAS; + } + if (type == GLP_UP || type == GLP_DB || type == GLP_FX) + { eps = 1e-6 + 1e-9 * fabs(col->ub); + if (col->prim > col->ub + eps) + P->pbs_stat = GLP_INFEAS; + } + } + /* compute value of the objective function */ + P->obj_val = P->c0; + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + P->obj_val += col->coef * col->prim; + } + /* build vector cB of objective coefficients at basic variables */ + for (i = 1; i <= P->m; i++) + work[i] = 0.0; + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + if (col->stat == GLP_BS) + work[col->bind] = col->coef; + } + /* compute vector of simplex multipliers pi = inv(B') * cB */ + glp_btran(P, work); + /* compute and store reduced costs of non-basic variables d[j] = + c[j] - N'[j] * pi, check dual feasibility */ + P->dbs_stat = GLP_FEAS; + for (i = 1; i <= P->m; i++) + { row = P->row[i]; + if (row->stat == GLP_BS) + { row->dual = 0.0; + continue; + } + /* N[j] is i-th column of matrix (I|-A) */ + row->dual = - work[i]; +#if 0 /* 07/III-2013 */ + type = row->type; + temp = (P->dir == GLP_MIN ? + row->dual : - row->dual); + if ((type == GLP_FR || type == GLP_LO) && temp < -1e-5 || + (type == GLP_FR || type == GLP_UP) && temp > +1e-5) + P->dbs_stat = GLP_INFEAS; +#else + stat = row->stat; + temp = (P->dir == GLP_MIN ? + row->dual : - row->dual); + if ((stat == GLP_NF || stat == GLP_NL) && temp < -1e-5 || + (stat == GLP_NF || stat == GLP_NU) && temp > +1e-5) + P->dbs_stat = GLP_INFEAS; +#endif + } + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + if (col->stat == GLP_BS) + { col->dual = 0.0; + continue; + } + /* N[j] is (m+j)-th column of matrix (I|-A) */ + col->dual = col->coef; + for (aij = col->ptr; aij != NULL; aij = aij->c_next) + col->dual += aij->val * work[aij->row->i]; +#if 0 /* 07/III-2013 */ + type = col->type; + temp = (P->dir == GLP_MIN ? + col->dual : - col->dual); + if ((type == GLP_FR || type == GLP_LO) && temp < -1e-5 || + (type == GLP_FR || type == GLP_UP) && temp > +1e-5) + P->dbs_stat = GLP_INFEAS; +#else + stat = col->stat; + temp = (P->dir == GLP_MIN ? + col->dual : - col->dual); + if ((stat == GLP_NF || stat == GLP_NL) && temp < -1e-5 || + (stat == GLP_NF || stat == GLP_NU) && temp > +1e-5) + P->dbs_stat = GLP_INFEAS; +#endif + } + /* free working array */ + xfree(work); + ret = 0; +done: return ret; +} + +/*********************************************************************** +* NAME +* +* glp_eval_tab_row - compute row of the simplex tableau +* +* SYNOPSIS +* +* int glp_eval_tab_row(glp_prob *lp, int k, int ind[], double val[]); +* +* DESCRIPTION +* +* The routine glp_eval_tab_row computes a row of the current simplex +* tableau for the basic variable, which is specified by the number k: +* if 1 <= k <= m, x[k] is k-th auxiliary variable; if m+1 <= k <= m+n, +* x[k] is (k-m)-th structural variable, where m is number of rows, and +* n is number of columns. The current basis must be available. +* +* The routine stores column indices and numerical values of non-zero +* elements of the computed row using sparse format to the locations +* ind[1], ..., ind[len] and val[1], ..., val[len], respectively, where +* 0 <= len <= n is number of non-zeros returned on exit. +* +* Element indices stored in the array ind have the same sense as the +* index k, i.e. indices 1 to m denote auxiliary variables and indices +* m+1 to m+n denote structural ones (all these variables are obviously +* non-basic by definition). +* +* The computed row shows how the specified basic variable x[k] = xB[i] +* depends on non-basic variables: +* +* xB[i] = alfa[i,1]*xN[1] + alfa[i,2]*xN[2] + ... + alfa[i,n]*xN[n], +* +* where alfa[i,j] are elements of the simplex table row, xN[j] are +* non-basic (auxiliary and structural) variables. +* +* RETURNS +* +* The routine returns number of non-zero elements in the simplex table +* row stored in the arrays ind and val. +* +* BACKGROUND +* +* The system of equality constraints of the LP problem is: +* +* xR = A * xS, (1) +* +* where xR is the vector of auxliary variables, xS is the vector of +* structural variables, A is the matrix of constraint coefficients. +* +* The system (1) can be written in homogenous form as follows: +* +* A~ * x = 0, (2) +* +* where A~ = (I | -A) is the augmented constraint matrix (has m rows +* and m+n columns), x = (xR | xS) is the vector of all (auxiliary and +* structural) variables. +* +* By definition for the current basis we have: +* +* A~ = (B | N), (3) +* +* where B is the basis matrix. Thus, the system (2) can be written as: +* +* B * xB + N * xN = 0. (4) +* +* From (4) it follows that: +* +* xB = A^ * xN, (5) +* +* where the matrix +* +* A^ = - inv(B) * N (6) +* +* is called the simplex table. +* +* It is understood that i-th row of the simplex table is: +* +* e * A^ = - e * inv(B) * N, (7) +* +* where e is a unity vector with e[i] = 1. +* +* To compute i-th row of the simplex table the routine first computes +* i-th row of the inverse: +* +* rho = inv(B') * e, (8) +* +* where B' is a matrix transposed to B, and then computes elements of +* i-th row of the simplex table as scalar products: +* +* alfa[i,j] = - rho * N[j] for all j, (9) +* +* where N[j] is a column of the augmented constraint matrix A~, which +* corresponds to some non-basic auxiliary or structural variable. */ + +int glp_eval_tab_row(glp_prob *lp, int k, int ind[], double val[]) +{ int m = lp->m; + int n = lp->n; + int i, t, len, lll, *iii; + double alfa, *rho, *vvv; + if (!(m == 0 || lp->valid)) + xerror("glp_eval_tab_row: basis factorization does not exist\n" + ); + if (!(1 <= k && k <= m+n)) + xerror("glp_eval_tab_row: k = %d; variable number out of range" + , k); + /* determine xB[i] which corresponds to x[k] */ + if (k <= m) + i = glp_get_row_bind(lp, k); + else + i = glp_get_col_bind(lp, k-m); + if (i == 0) + xerror("glp_eval_tab_row: k = %d; variable must be basic", k); + xassert(1 <= i && i <= m); + /* allocate working arrays */ + rho = xcalloc(1+m, sizeof(double)); + iii = xcalloc(1+m, sizeof(int)); + vvv = xcalloc(1+m, sizeof(double)); + /* compute i-th row of the inverse; see (8) */ + for (t = 1; t <= m; t++) rho[t] = 0.0; + rho[i] = 1.0; + glp_btran(lp, rho); + /* compute i-th row of the simplex table */ + len = 0; + for (k = 1; k <= m+n; k++) + { if (k <= m) + { /* x[k] is auxiliary variable, so N[k] is a unity column */ + if (glp_get_row_stat(lp, k) == GLP_BS) continue; + /* compute alfa[i,j]; see (9) */ + alfa = - rho[k]; + } + else + { /* x[k] is structural variable, so N[k] is a column of the + original constraint matrix A with negative sign */ + if (glp_get_col_stat(lp, k-m) == GLP_BS) continue; + /* compute alfa[i,j]; see (9) */ + lll = glp_get_mat_col(lp, k-m, iii, vvv); + alfa = 0.0; + for (t = 1; t <= lll; t++) alfa += rho[iii[t]] * vvv[t]; + } + /* store alfa[i,j] */ + if (alfa != 0.0) len++, ind[len] = k, val[len] = alfa; + } + xassert(len <= n); + /* free working arrays */ + xfree(rho); + xfree(iii); + xfree(vvv); + /* return to the calling program */ + return len; +} + +/*********************************************************************** +* NAME +* +* glp_eval_tab_col - compute column of the simplex tableau +* +* SYNOPSIS +* +* int glp_eval_tab_col(glp_prob *lp, int k, int ind[], double val[]); +* +* DESCRIPTION +* +* The routine glp_eval_tab_col computes a column of the current simplex +* table for the non-basic variable, which is specified by the number k: +* if 1 <= k <= m, x[k] is k-th auxiliary variable; if m+1 <= k <= m+n, +* x[k] is (k-m)-th structural variable, where m is number of rows, and +* n is number of columns. The current basis must be available. +* +* The routine stores row indices and numerical values of non-zero +* elements of the computed column using sparse format to the locations +* ind[1], ..., ind[len] and val[1], ..., val[len] respectively, where +* 0 <= len <= m is number of non-zeros returned on exit. +* +* Element indices stored in the array ind have the same sense as the +* index k, i.e. indices 1 to m denote auxiliary variables and indices +* m+1 to m+n denote structural ones (all these variables are obviously +* basic by the definition). +* +* The computed column shows how basic variables depend on the specified +* non-basic variable x[k] = xN[j]: +* +* xB[1] = ... + alfa[1,j]*xN[j] + ... +* xB[2] = ... + alfa[2,j]*xN[j] + ... +* . . . . . . +* xB[m] = ... + alfa[m,j]*xN[j] + ... +* +* where alfa[i,j] are elements of the simplex table column, xB[i] are +* basic (auxiliary and structural) variables. +* +* RETURNS +* +* The routine returns number of non-zero elements in the simplex table +* column stored in the arrays ind and val. +* +* BACKGROUND +* +* As it was explained in comments to the routine glp_eval_tab_row (see +* above) the simplex table is the following matrix: +* +* A^ = - inv(B) * N. (1) +* +* Therefore j-th column of the simplex table is: +* +* A^ * e = - inv(B) * N * e = - inv(B) * N[j], (2) +* +* where e is a unity vector with e[j] = 1, B is the basis matrix, N[j] +* is a column of the augmented constraint matrix A~, which corresponds +* to the given non-basic auxiliary or structural variable. */ + +int glp_eval_tab_col(glp_prob *lp, int k, int ind[], double val[]) +{ int m = lp->m; + int n = lp->n; + int t, len, stat; + double *col; + if (!(m == 0 || lp->valid)) + xerror("glp_eval_tab_col: basis factorization does not exist\n" + ); + if (!(1 <= k && k <= m+n)) + xerror("glp_eval_tab_col: k = %d; variable number out of range" + , k); + if (k <= m) + stat = glp_get_row_stat(lp, k); + else + stat = glp_get_col_stat(lp, k-m); + if (stat == GLP_BS) + xerror("glp_eval_tab_col: k = %d; variable must be non-basic", + k); + /* obtain column N[k] with negative sign */ + col = xcalloc(1+m, sizeof(double)); + for (t = 1; t <= m; t++) col[t] = 0.0; + if (k <= m) + { /* x[k] is auxiliary variable, so N[k] is a unity column */ + col[k] = -1.0; + } + else + { /* x[k] is structural variable, so N[k] is a column of the + original constraint matrix A with negative sign */ + len = glp_get_mat_col(lp, k-m, ind, val); + for (t = 1; t <= len; t++) col[ind[t]] = val[t]; + } + /* compute column of the simplex table, which corresponds to the + specified non-basic variable x[k] */ + glp_ftran(lp, col); + len = 0; + for (t = 1; t <= m; t++) + { if (col[t] != 0.0) + { len++; + ind[len] = glp_get_bhead(lp, t); + val[len] = col[t]; + } + } + xfree(col); + /* return to the calling program */ + return len; +} + +/*********************************************************************** +* NAME +* +* glp_transform_row - transform explicitly specified row +* +* SYNOPSIS +* +* int glp_transform_row(glp_prob *P, int len, int ind[], double val[]); +* +* DESCRIPTION +* +* The routine glp_transform_row performs the same operation as the +* routine glp_eval_tab_row with exception that the row to be +* transformed is specified explicitly as a sparse vector. +* +* The explicitly specified row may be thought as a linear form: +* +* x = a[1]*x[m+1] + a[2]*x[m+2] + ... + a[n]*x[m+n], (1) +* +* where x is an auxiliary variable for this row, a[j] are coefficients +* of the linear form, x[m+j] are structural variables. +* +* On entry column indices and numerical values of non-zero elements of +* the row should be stored in locations ind[1], ..., ind[len] and +* val[1], ..., val[len], where len is the number of non-zero elements. +* +* This routine uses the system of equality constraints and the current +* basis in order to express the auxiliary variable x in (1) through the +* current non-basic variables (as if the transformed row were added to +* the problem object and its auxiliary variable were basic), i.e. the +* resultant row has the form: +* +* x = alfa[1]*xN[1] + alfa[2]*xN[2] + ... + alfa[n]*xN[n], (2) +* +* where xN[j] are non-basic (auxiliary or structural) variables, n is +* the number of columns in the LP problem object. +* +* On exit the routine stores indices and numerical values of non-zero +* elements of the resultant row (2) in locations ind[1], ..., ind[len'] +* and val[1], ..., val[len'], where 0 <= len' <= n is the number of +* non-zero elements in the resultant row returned by the routine. Note +* that indices (numbers) of non-basic variables stored in the array ind +* correspond to original ordinal numbers of variables: indices 1 to m +* mean auxiliary variables and indices m+1 to m+n mean structural ones. +* +* RETURNS +* +* The routine returns len', which is the number of non-zero elements in +* the resultant row stored in the arrays ind and val. +* +* BACKGROUND +* +* The explicitly specified row (1) is transformed in the same way as it +* were the objective function row. +* +* From (1) it follows that: +* +* x = aB * xB + aN * xN, (3) +* +* where xB is the vector of basic variables, xN is the vector of +* non-basic variables. +* +* The simplex table, which corresponds to the current basis, is: +* +* xB = [-inv(B) * N] * xN. (4) +* +* Therefore substituting xB from (4) to (3) we have: +* +* x = aB * [-inv(B) * N] * xN + aN * xN = +* (5) +* = rho * (-N) * xN + aN * xN = alfa * xN, +* +* where: +* +* rho = inv(B') * aB, (6) +* +* and +* +* alfa = aN + rho * (-N) (7) +* +* is the resultant row computed by the routine. */ + +int glp_transform_row(glp_prob *P, int len, int ind[], double val[]) +{ int i, j, k, m, n, t, lll, *iii; + double alfa, *a, *aB, *rho, *vvv; + if (!glp_bf_exists(P)) + xerror("glp_transform_row: basis factorization does not exist " + "\n"); + m = glp_get_num_rows(P); + n = glp_get_num_cols(P); + /* unpack the row to be transformed to the array a */ + a = xcalloc(1+n, sizeof(double)); + for (j = 1; j <= n; j++) a[j] = 0.0; + if (!(0 <= len && len <= n)) + xerror("glp_transform_row: len = %d; invalid row length\n", + len); + for (t = 1; t <= len; t++) + { j = ind[t]; + if (!(1 <= j && j <= n)) + xerror("glp_transform_row: ind[%d] = %d; column index out o" + "f range\n", t, j); + if (val[t] == 0.0) + xerror("glp_transform_row: val[%d] = 0; zero coefficient no" + "t allowed\n", t); + if (a[j] != 0.0) + xerror("glp_transform_row: ind[%d] = %d; duplicate column i" + "ndices not allowed\n", t, j); + a[j] = val[t]; + } + /* construct the vector aB */ + aB = xcalloc(1+m, sizeof(double)); + for (i = 1; i <= m; i++) + { k = glp_get_bhead(P, i); + /* xB[i] is k-th original variable */ + xassert(1 <= k && k <= m+n); + aB[i] = (k <= m ? 0.0 : a[k-m]); + } + /* solve the system B'*rho = aB to compute the vector rho */ + rho = aB, glp_btran(P, rho); + /* compute coefficients at non-basic auxiliary variables */ + len = 0; + for (i = 1; i <= m; i++) + { if (glp_get_row_stat(P, i) != GLP_BS) + { alfa = - rho[i]; + if (alfa != 0.0) + { len++; + ind[len] = i; + val[len] = alfa; + } + } + } + /* compute coefficients at non-basic structural variables */ + iii = xcalloc(1+m, sizeof(int)); + vvv = xcalloc(1+m, sizeof(double)); + for (j = 1; j <= n; j++) + { if (glp_get_col_stat(P, j) != GLP_BS) + { alfa = a[j]; + lll = glp_get_mat_col(P, j, iii, vvv); + for (t = 1; t <= lll; t++) alfa += vvv[t] * rho[iii[t]]; + if (alfa != 0.0) + { len++; + ind[len] = m+j; + val[len] = alfa; + } + } + } + xassert(len <= n); + xfree(iii); + xfree(vvv); + xfree(aB); + xfree(a); + return len; +} + +/*********************************************************************** +* NAME +* +* glp_transform_col - transform explicitly specified column +* +* SYNOPSIS +* +* int glp_transform_col(glp_prob *P, int len, int ind[], double val[]); +* +* DESCRIPTION +* +* The routine glp_transform_col performs the same operation as the +* routine glp_eval_tab_col with exception that the column to be +* transformed is specified explicitly as a sparse vector. +* +* The explicitly specified column may be thought as if it were added +* to the original system of equality constraints: +* +* x[1] = a[1,1]*x[m+1] + ... + a[1,n]*x[m+n] + a[1]*x +* x[2] = a[2,1]*x[m+1] + ... + a[2,n]*x[m+n] + a[2]*x (1) +* . . . . . . . . . . . . . . . +* x[m] = a[m,1]*x[m+1] + ... + a[m,n]*x[m+n] + a[m]*x +* +* where x[i] are auxiliary variables, x[m+j] are structural variables, +* x is a structural variable for the explicitly specified column, a[i] +* are constraint coefficients for x. +* +* On entry row indices and numerical values of non-zero elements of +* the column should be stored in locations ind[1], ..., ind[len] and +* val[1], ..., val[len], where len is the number of non-zero elements. +* +* This routine uses the system of equality constraints and the current +* basis in order to express the current basic variables through the +* structural variable x in (1) (as if the transformed column were added +* to the problem object and the variable x were non-basic), i.e. the +* resultant column has the form: +* +* xB[1] = ... + alfa[1]*x +* xB[2] = ... + alfa[2]*x (2) +* . . . . . . +* xB[m] = ... + alfa[m]*x +* +* where xB are basic (auxiliary and structural) variables, m is the +* number of rows in the problem object. +* +* On exit the routine stores indices and numerical values of non-zero +* elements of the resultant column (2) in locations ind[1], ..., +* ind[len'] and val[1], ..., val[len'], where 0 <= len' <= m is the +* number of non-zero element in the resultant column returned by the +* routine. Note that indices (numbers) of basic variables stored in +* the array ind correspond to original ordinal numbers of variables: +* indices 1 to m mean auxiliary variables and indices m+1 to m+n mean +* structural ones. +* +* RETURNS +* +* The routine returns len', which is the number of non-zero elements +* in the resultant column stored in the arrays ind and val. +* +* BACKGROUND +* +* The explicitly specified column (1) is transformed in the same way +* as any other column of the constraint matrix using the formula: +* +* alfa = inv(B) * a, (3) +* +* where alfa is the resultant column computed by the routine. */ + +int glp_transform_col(glp_prob *P, int len, int ind[], double val[]) +{ int i, m, t; + double *a, *alfa; + if (!glp_bf_exists(P)) + xerror("glp_transform_col: basis factorization does not exist " + "\n"); + m = glp_get_num_rows(P); + /* unpack the column to be transformed to the array a */ + a = xcalloc(1+m, sizeof(double)); + for (i = 1; i <= m; i++) a[i] = 0.0; + if (!(0 <= len && len <= m)) + xerror("glp_transform_col: len = %d; invalid column length\n", + len); + for (t = 1; t <= len; t++) + { i = ind[t]; + if (!(1 <= i && i <= m)) + xerror("glp_transform_col: ind[%d] = %d; row index out of r" + "ange\n", t, i); + if (val[t] == 0.0) + xerror("glp_transform_col: val[%d] = 0; zero coefficient no" + "t allowed\n", t); + if (a[i] != 0.0) + xerror("glp_transform_col: ind[%d] = %d; duplicate row indi" + "ces not allowed\n", t, i); + a[i] = val[t]; + } + /* solve the system B*a = alfa to compute the vector alfa */ + alfa = a, glp_ftran(P, alfa); + /* store resultant coefficients */ + len = 0; + for (i = 1; i <= m; i++) + { if (alfa[i] != 0.0) + { len++; + ind[len] = glp_get_bhead(P, i); + val[len] = alfa[i]; + } + } + xfree(a); + return len; +} + +/*********************************************************************** +* NAME +* +* glp_prim_rtest - perform primal ratio test +* +* SYNOPSIS +* +* int glp_prim_rtest(glp_prob *P, int len, const int ind[], +* const double val[], int dir, double eps); +* +* DESCRIPTION +* +* The routine glp_prim_rtest performs the primal ratio test using an +* explicitly specified column of the simplex table. +* +* The current basic solution associated with the LP problem object +* must be primal feasible. +* +* The explicitly specified column of the simplex table shows how the +* basic variables xB depend on some non-basic variable x (which is not +* necessarily presented in the problem object): +* +* xB[1] = ... + alfa[1] * x + ... +* xB[2] = ... + alfa[2] * x + ... (*) +* . . . . . . . . +* xB[m] = ... + alfa[m] * x + ... +* +* The column (*) is specifed on entry to the routine using the sparse +* format. Ordinal numbers of basic variables xB[i] should be placed in +* locations ind[1], ..., ind[len], where ordinal number 1 to m denote +* auxiliary variables, and ordinal numbers m+1 to m+n denote structural +* variables. The corresponding non-zero coefficients alfa[i] should be +* placed in locations val[1], ..., val[len]. The arrays ind and val are +* not changed on exit. +* +* The parameter dir specifies direction in which the variable x changes +* on entering the basis: +1 means increasing, -1 means decreasing. +* +* The parameter eps is an absolute tolerance (small positive number) +* used by the routine to skip small alfa[j] of the row (*). +* +* The routine determines which basic variable (among specified in +* ind[1], ..., ind[len]) should leave the basis in order to keep primal +* feasibility. +* +* RETURNS +* +* The routine glp_prim_rtest returns the index piv in the arrays ind +* and val corresponding to the pivot element chosen, 1 <= piv <= len. +* If the adjacent basic solution is primal unbounded and therefore the +* choice cannot be made, the routine returns zero. +* +* COMMENTS +* +* If the non-basic variable x is presented in the LP problem object, +* the column (*) can be computed with the routine glp_eval_tab_col; +* otherwise it can be computed with the routine glp_transform_col. */ + +int glp_prim_rtest(glp_prob *P, int len, const int ind[], + const double val[], int dir, double eps) +{ int k, m, n, piv, t, type, stat; + double alfa, big, beta, lb, ub, temp, teta; + if (glp_get_prim_stat(P) != GLP_FEAS) + xerror("glp_prim_rtest: basic solution is not primal feasible " + "\n"); + if (!(dir == +1 || dir == -1)) + xerror("glp_prim_rtest: dir = %d; invalid parameter\n", dir); + if (!(0.0 < eps && eps < 1.0)) + xerror("glp_prim_rtest: eps = %g; invalid parameter\n", eps); + m = glp_get_num_rows(P); + n = glp_get_num_cols(P); + /* initial settings */ + piv = 0, teta = DBL_MAX, big = 0.0; + /* walk through the entries of the specified column */ + for (t = 1; t <= len; t++) + { /* get the ordinal number of basic variable */ + k = ind[t]; + if (!(1 <= k && k <= m+n)) + xerror("glp_prim_rtest: ind[%d] = %d; variable number out o" + "f range\n", t, k); + /* determine type, bounds, status and primal value of basic + variable xB[i] = x[k] in the current basic solution */ + if (k <= m) + { type = glp_get_row_type(P, k); + lb = glp_get_row_lb(P, k); + ub = glp_get_row_ub(P, k); + stat = glp_get_row_stat(P, k); + beta = glp_get_row_prim(P, k); + } + else + { type = glp_get_col_type(P, k-m); + lb = glp_get_col_lb(P, k-m); + ub = glp_get_col_ub(P, k-m); + stat = glp_get_col_stat(P, k-m); + beta = glp_get_col_prim(P, k-m); + } + if (stat != GLP_BS) + xerror("glp_prim_rtest: ind[%d] = %d; non-basic variable no" + "t allowed\n", t, k); + /* determine influence coefficient at basic variable xB[i] + in the explicitly specified column and turn to the case of + increasing the variable x in order to simplify the program + logic */ + alfa = (dir > 0 ? + val[t] : - val[t]); + /* analyze main cases */ + if (type == GLP_FR) + { /* xB[i] is free variable */ + continue; + } + else if (type == GLP_LO) +lo: { /* xB[i] has an lower bound */ + if (alfa > - eps) continue; + temp = (lb - beta) / alfa; + } + else if (type == GLP_UP) +up: { /* xB[i] has an upper bound */ + if (alfa < + eps) continue; + temp = (ub - beta) / alfa; + } + else if (type == GLP_DB) + { /* xB[i] has both lower and upper bounds */ + if (alfa < 0.0) goto lo; else goto up; + } + else if (type == GLP_FX) + { /* xB[i] is fixed variable */ + if (- eps < alfa && alfa < + eps) continue; + temp = 0.0; + } + else + xassert(type != type); + /* if the value of the variable xB[i] violates its lower or + upper bound (slightly, because the current basis is assumed + to be primal feasible), temp is negative; we can think this + happens due to round-off errors and the value is exactly on + the bound; this allows replacing temp by zero */ + if (temp < 0.0) temp = 0.0; + /* apply the minimal ratio test */ + if (teta > temp || teta == temp && big < fabs(alfa)) + piv = t, teta = temp, big = fabs(alfa); + } + /* return index of the pivot element chosen */ + return piv; +} + +/*********************************************************************** +* NAME +* +* glp_dual_rtest - perform dual ratio test +* +* SYNOPSIS +* +* int glp_dual_rtest(glp_prob *P, int len, const int ind[], +* const double val[], int dir, double eps); +* +* DESCRIPTION +* +* The routine glp_dual_rtest performs the dual ratio test using an +* explicitly specified row of the simplex table. +* +* The current basic solution associated with the LP problem object +* must be dual feasible. +* +* The explicitly specified row of the simplex table is a linear form +* that shows how some basic variable x (which is not necessarily +* presented in the problem object) depends on non-basic variables xN: +* +* x = alfa[1] * xN[1] + alfa[2] * xN[2] + ... + alfa[n] * xN[n]. (*) +* +* The row (*) is specified on entry to the routine using the sparse +* format. Ordinal numbers of non-basic variables xN[j] should be placed +* in locations ind[1], ..., ind[len], where ordinal numbers 1 to m +* denote auxiliary variables, and ordinal numbers m+1 to m+n denote +* structural variables. The corresponding non-zero coefficients alfa[j] +* should be placed in locations val[1], ..., val[len]. The arrays ind +* and val are not changed on exit. +* +* The parameter dir specifies direction in which the variable x changes +* on leaving the basis: +1 means that x goes to its lower bound, and -1 +* means that x goes to its upper bound. +* +* The parameter eps is an absolute tolerance (small positive number) +* used by the routine to skip small alfa[j] of the row (*). +* +* The routine determines which non-basic variable (among specified in +* ind[1], ..., ind[len]) should enter the basis in order to keep dual +* feasibility. +* +* RETURNS +* +* The routine glp_dual_rtest returns the index piv in the arrays ind +* and val corresponding to the pivot element chosen, 1 <= piv <= len. +* If the adjacent basic solution is dual unbounded and therefore the +* choice cannot be made, the routine returns zero. +* +* COMMENTS +* +* If the basic variable x is presented in the LP problem object, the +* row (*) can be computed with the routine glp_eval_tab_row; otherwise +* it can be computed with the routine glp_transform_row. */ + +int glp_dual_rtest(glp_prob *P, int len, const int ind[], + const double val[], int dir, double eps) +{ int k, m, n, piv, t, stat; + double alfa, big, cost, obj, temp, teta; + if (glp_get_dual_stat(P) != GLP_FEAS) + xerror("glp_dual_rtest: basic solution is not dual feasible\n") + ; + if (!(dir == +1 || dir == -1)) + xerror("glp_dual_rtest: dir = %d; invalid parameter\n", dir); + if (!(0.0 < eps && eps < 1.0)) + xerror("glp_dual_rtest: eps = %g; invalid parameter\n", eps); + m = glp_get_num_rows(P); + n = glp_get_num_cols(P); + /* take into account optimization direction */ + obj = (glp_get_obj_dir(P) == GLP_MIN ? +1.0 : -1.0); + /* initial settings */ + piv = 0, teta = DBL_MAX, big = 0.0; + /* walk through the entries of the specified row */ + for (t = 1; t <= len; t++) + { /* get ordinal number of non-basic variable */ + k = ind[t]; + if (!(1 <= k && k <= m+n)) + xerror("glp_dual_rtest: ind[%d] = %d; variable number out o" + "f range\n", t, k); + /* determine status and reduced cost of non-basic variable + x[k] = xN[j] in the current basic solution */ + if (k <= m) + { stat = glp_get_row_stat(P, k); + cost = glp_get_row_dual(P, k); + } + else + { stat = glp_get_col_stat(P, k-m); + cost = glp_get_col_dual(P, k-m); + } + if (stat == GLP_BS) + xerror("glp_dual_rtest: ind[%d] = %d; basic variable not al" + "lowed\n", t, k); + /* determine influence coefficient at non-basic variable xN[j] + in the explicitly specified row and turn to the case of + increasing the variable x in order to simplify the program + logic */ + alfa = (dir > 0 ? + val[t] : - val[t]); + /* analyze main cases */ + if (stat == GLP_NL) + { /* xN[j] is on its lower bound */ + if (alfa < + eps) continue; + temp = (obj * cost) / alfa; + } + else if (stat == GLP_NU) + { /* xN[j] is on its upper bound */ + if (alfa > - eps) continue; + temp = (obj * cost) / alfa; + } + else if (stat == GLP_NF) + { /* xN[j] is non-basic free variable */ + if (- eps < alfa && alfa < + eps) continue; + temp = 0.0; + } + else if (stat == GLP_NS) + { /* xN[j] is non-basic fixed variable */ + continue; + } + else + xassert(stat != stat); + /* if the reduced cost of the variable xN[j] violates its zero + bound (slightly, because the current basis is assumed to be + dual feasible), temp is negative; we can think this happens + due to round-off errors and the reduced cost is exact zero; + this allows replacing temp by zero */ + if (temp < 0.0) temp = 0.0; + /* apply the minimal ratio test */ + if (teta > temp || teta == temp && big < fabs(alfa)) + piv = t, teta = temp, big = fabs(alfa); + } + /* return index of the pivot element chosen */ + return piv; +} + +/*********************************************************************** +* NAME +* +* glp_analyze_row - simulate one iteration of dual simplex method +* +* SYNOPSIS +* +* int glp_analyze_row(glp_prob *P, int len, const int ind[], +* const double val[], int type, double rhs, double eps, int *piv, +* double *x, double *dx, double *y, double *dy, double *dz); +* +* DESCRIPTION +* +* Let the current basis be optimal or dual feasible, and there be +* specified a row (constraint), which is violated by the current basic +* solution. The routine glp_analyze_row simulates one iteration of the +* dual simplex method to determine some information on the adjacent +* basis (see below), where the specified row becomes active constraint +* (i.e. its auxiliary variable becomes non-basic). +* +* The current basic solution associated with the problem object passed +* to the routine must be dual feasible, and its primal components must +* be defined. +* +* The row to be analyzed must be previously transformed either with +* the routine glp_eval_tab_row (if the row is in the problem object) +* or with the routine glp_transform_row (if the row is external, i.e. +* not in the problem object). This is needed to express the row only +* through (auxiliary and structural) variables, which are non-basic in +* the current basis: +* +* y = alfa[1] * xN[1] + alfa[2] * xN[2] + ... + alfa[n] * xN[n], +* +* where y is an auxiliary variable of the row, alfa[j] is an influence +* coefficient, xN[j] is a non-basic variable. +* +* The row is passed to the routine in sparse format. Ordinal numbers +* of non-basic variables are stored in locations ind[1], ..., ind[len], +* where numbers 1 to m denote auxiliary variables while numbers m+1 to +* m+n denote structural variables. Corresponding non-zero coefficients +* alfa[j] are stored in locations val[1], ..., val[len]. The arrays +* ind and val are ot changed on exit. +* +* The parameters type and rhs specify the row type and its right-hand +* side as follows: +* +* type = GLP_LO: y = sum alfa[j] * xN[j] >= rhs +* +* type = GLP_UP: y = sum alfa[j] * xN[j] <= rhs +* +* The parameter eps is an absolute tolerance (small positive number) +* used by the routine to skip small coefficients alfa[j] on performing +* the dual ratio test. +* +* If the operation was successful, the routine stores the following +* information to corresponding location (if some parameter is NULL, +* its value is not stored): +* +* piv index in the array ind and val, 1 <= piv <= len, determining +* the non-basic variable, which would enter the adjacent basis; +* +* x value of the non-basic variable in the current basis; +* +* dx difference between values of the non-basic variable in the +* adjacent and current bases, dx = x.new - x.old; +* +* y value of the row (i.e. of its auxiliary variable) in the +* current basis; +* +* dy difference between values of the row in the adjacent and +* current bases, dy = y.new - y.old; +* +* dz difference between values of the objective function in the +* adjacent and current bases, dz = z.new - z.old. Note that in +* case of minimization dz >= 0, and in case of maximization +* dz <= 0, i.e. in the adjacent basis the objective function +* always gets worse (degrades). */ + +int _glp_analyze_row(glp_prob *P, int len, const int ind[], + const double val[], int type, double rhs, double eps, int *_piv, + double *_x, double *_dx, double *_y, double *_dy, double *_dz) +{ int t, k, dir, piv, ret = 0; + double x, dx, y, dy, dz; + if (P->pbs_stat == GLP_UNDEF) + xerror("glp_analyze_row: primal basic solution components are " + "undefined\n"); + if (P->dbs_stat != GLP_FEAS) + xerror("glp_analyze_row: basic solution is not dual feasible\n" + ); + /* compute the row value y = sum alfa[j] * xN[j] in the current + basis */ + if (!(0 <= len && len <= P->n)) + xerror("glp_analyze_row: len = %d; invalid row length\n", len); + y = 0.0; + for (t = 1; t <= len; t++) + { /* determine value of x[k] = xN[j] in the current basis */ + k = ind[t]; + if (!(1 <= k && k <= P->m+P->n)) + xerror("glp_analyze_row: ind[%d] = %d; row/column index out" + " of range\n", t, k); + if (k <= P->m) + { /* x[k] is auxiliary variable */ + if (P->row[k]->stat == GLP_BS) + xerror("glp_analyze_row: ind[%d] = %d; basic auxiliary v" + "ariable is not allowed\n", t, k); + x = P->row[k]->prim; + } + else + { /* x[k] is structural variable */ + if (P->col[k-P->m]->stat == GLP_BS) + xerror("glp_analyze_row: ind[%d] = %d; basic structural " + "variable is not allowed\n", t, k); + x = P->col[k-P->m]->prim; + } + y += val[t] * x; + } + /* check if the row is primal infeasible in the current basis, + i.e. the constraint is violated at the current point */ + if (type == GLP_LO) + { if (y >= rhs) + { /* the constraint is not violated */ + ret = 1; + goto done; + } + /* in the adjacent basis y goes to its lower bound */ + dir = +1; + } + else if (type == GLP_UP) + { if (y <= rhs) + { /* the constraint is not violated */ + ret = 1; + goto done; + } + /* in the adjacent basis y goes to its upper bound */ + dir = -1; + } + else + xerror("glp_analyze_row: type = %d; invalid parameter\n", + type); + /* compute dy = y.new - y.old */ + dy = rhs - y; + /* perform dual ratio test to determine which non-basic variable + should enter the adjacent basis to keep it dual feasible */ + piv = glp_dual_rtest(P, len, ind, val, dir, eps); + if (piv == 0) + { /* no dual feasible adjacent basis exists */ + ret = 2; + goto done; + } + /* non-basic variable x[k] = xN[j] should enter the basis */ + k = ind[piv]; + xassert(1 <= k && k <= P->m+P->n); + /* determine its value in the current basis */ + if (k <= P->m) + x = P->row[k]->prim; + else + x = P->col[k-P->m]->prim; + /* compute dx = x.new - x.old = dy / alfa[j] */ + xassert(val[piv] != 0.0); + dx = dy / val[piv]; + /* compute dz = z.new - z.old = d[j] * dx, where d[j] is reduced + cost of xN[j] in the current basis */ + if (k <= P->m) + dz = P->row[k]->dual * dx; + else + dz = P->col[k-P->m]->dual * dx; + /* store the analysis results */ + if (_piv != NULL) *_piv = piv; + if (_x != NULL) *_x = x; + if (_dx != NULL) *_dx = dx; + if (_y != NULL) *_y = y; + if (_dy != NULL) *_dy = dy; + if (_dz != NULL) *_dz = dz; +done: return ret; +} + +#if 0 +int main(void) +{ /* example program for the routine glp_analyze_row */ + glp_prob *P; + glp_smcp parm; + int i, k, len, piv, ret, ind[1+100]; + double rhs, x, dx, y, dy, dz, val[1+100]; + P = glp_create_prob(); + /* read plan.mps (see glpk/examples) */ + ret = glp_read_mps(P, GLP_MPS_DECK, NULL, "plan.mps"); + glp_assert(ret == 0); + /* and solve it to optimality */ + ret = glp_simplex(P, NULL); + glp_assert(ret == 0); + glp_assert(glp_get_status(P) == GLP_OPT); + /* the optimal objective value is 296.217 */ + /* we would like to know what happens if we would add a new row + (constraint) to plan.mps: + .01 * bin1 + .01 * bin2 + .02 * bin4 + .02 * bin5 <= 12 */ + /* first, we specify this new row */ + glp_create_index(P); + len = 0; + ind[++len] = glp_find_col(P, "BIN1"), val[len] = .01; + ind[++len] = glp_find_col(P, "BIN2"), val[len] = .01; + ind[++len] = glp_find_col(P, "BIN4"), val[len] = .02; + ind[++len] = glp_find_col(P, "BIN5"), val[len] = .02; + rhs = 12; + /* then we can compute value of the row (i.e. of its auxiliary + variable) in the current basis to see if the constraint is + violated */ + y = 0.0; + for (k = 1; k <= len; k++) + y += val[k] * glp_get_col_prim(P, ind[k]); + glp_printf("y = %g\n", y); + /* this prints y = 15.1372, so the constraint is violated, since + we require that y <= rhs = 12 */ + /* now we transform the row to express it only through non-basic + (auxiliary and artificial) variables */ + len = glp_transform_row(P, len, ind, val); + /* finally, we simulate one step of the dual simplex method to + obtain necessary information for the adjacent basis */ + ret = _glp_analyze_row(P, len, ind, val, GLP_UP, rhs, 1e-9, &piv, + &x, &dx, &y, &dy, &dz); + glp_assert(ret == 0); + glp_printf("k = %d, x = %g; dx = %g; y = %g; dy = %g; dz = %g\n", + ind[piv], x, dx, y, dy, dz); + /* this prints dz = 5.64418 and means that in the adjacent basis + the objective function would be 296.217 + 5.64418 = 301.861 */ + /* now we actually include the row into the problem object; note + that the arrays ind and val are clobbered, so we need to build + them once again */ + len = 0; + ind[++len] = glp_find_col(P, "BIN1"), val[len] = .01; + ind[++len] = glp_find_col(P, "BIN2"), val[len] = .01; + ind[++len] = glp_find_col(P, "BIN4"), val[len] = .02; + ind[++len] = glp_find_col(P, "BIN5"), val[len] = .02; + rhs = 12; + i = glp_add_rows(P, 1); + glp_set_row_bnds(P, i, GLP_UP, 0, rhs); + glp_set_mat_row(P, i, len, ind, val); + /* and perform one dual simplex iteration */ + glp_init_smcp(&parm); + parm.meth = GLP_DUAL; + parm.it_lim = 1; + glp_simplex(P, &parm); + /* the current objective value is 301.861 */ + return 0; +} +#endif + +/*********************************************************************** +* NAME +* +* glp_analyze_bound - analyze active bound of non-basic variable +* +* SYNOPSIS +* +* void glp_analyze_bound(glp_prob *P, int k, double *limit1, int *var1, +* double *limit2, int *var2); +* +* DESCRIPTION +* +* The routine glp_analyze_bound analyzes the effect of varying the +* active bound of specified non-basic variable. +* +* The non-basic variable is specified by the parameter k, where +* 1 <= k <= m means auxiliary variable of corresponding row while +* m+1 <= k <= m+n means structural variable (column). +* +* Note that the current basic solution must be optimal, and the basis +* factorization must exist. +* +* Results of the analysis have the following meaning. +* +* value1 is the minimal value of the active bound, at which the basis +* still remains primal feasible and thus optimal. -DBL_MAX means that +* the active bound has no lower limit. +* +* var1 is the ordinal number of an auxiliary (1 to m) or structural +* (m+1 to n) basic variable, which reaches its bound first and thereby +* limits further decreasing the active bound being analyzed. +* if value1 = -DBL_MAX, var1 is set to 0. +* +* value2 is the maximal value of the active bound, at which the basis +* still remains primal feasible and thus optimal. +DBL_MAX means that +* the active bound has no upper limit. +* +* var2 is the ordinal number of an auxiliary (1 to m) or structural +* (m+1 to n) basic variable, which reaches its bound first and thereby +* limits further increasing the active bound being analyzed. +* if value2 = +DBL_MAX, var2 is set to 0. */ + +void glp_analyze_bound(glp_prob *P, int k, double *value1, int *var1, + double *value2, int *var2) +{ GLPROW *row; + GLPCOL *col; + int m, n, stat, kase, p, len, piv, *ind; + double x, new_x, ll, uu, xx, delta, *val; + /* sanity checks */ + if (P == NULL || P->magic != GLP_PROB_MAGIC) + xerror("glp_analyze_bound: P = %p; invalid problem object\n", + P); + m = P->m, n = P->n; + if (!(P->pbs_stat == GLP_FEAS && P->dbs_stat == GLP_FEAS)) + xerror("glp_analyze_bound: optimal basic solution required\n"); + if (!(m == 0 || P->valid)) + xerror("glp_analyze_bound: basis factorization required\n"); + if (!(1 <= k && k <= m+n)) + xerror("glp_analyze_bound: k = %d; variable number out of rang" + "e\n", k); + /* retrieve information about the specified non-basic variable + x[k] whose active bound is to be analyzed */ + if (k <= m) + { row = P->row[k]; + stat = row->stat; + x = row->prim; + } + else + { col = P->col[k-m]; + stat = col->stat; + x = col->prim; + } + if (stat == GLP_BS) + xerror("glp_analyze_bound: k = %d; basic variable not allowed " + "\n", k); + /* allocate working arrays */ + ind = xcalloc(1+m, sizeof(int)); + val = xcalloc(1+m, sizeof(double)); + /* compute column of the simplex table corresponding to the + non-basic variable x[k] */ + len = glp_eval_tab_col(P, k, ind, val); + xassert(0 <= len && len <= m); + /* perform analysis */ + for (kase = -1; kase <= +1; kase += 2) + { /* kase < 0 means active bound of x[k] is decreasing; + kase > 0 means active bound of x[k] is increasing */ + /* use the primal ratio test to determine some basic variable + x[p] which reaches its bound first */ + piv = glp_prim_rtest(P, len, ind, val, kase, 1e-9); + if (piv == 0) + { /* nothing limits changing the active bound of x[k] */ + p = 0; + new_x = (kase < 0 ? -DBL_MAX : +DBL_MAX); + goto store; + } + /* basic variable x[p] limits changing the active bound of + x[k]; determine its value in the current basis */ + xassert(1 <= piv && piv <= len); + p = ind[piv]; + if (p <= m) + { row = P->row[p]; + ll = glp_get_row_lb(P, row->i); + uu = glp_get_row_ub(P, row->i); + stat = row->stat; + xx = row->prim; + } + else + { col = P->col[p-m]; + ll = glp_get_col_lb(P, col->j); + uu = glp_get_col_ub(P, col->j); + stat = col->stat; + xx = col->prim; + } + xassert(stat == GLP_BS); + /* determine delta x[p] = bound of x[p] - value of x[p] */ + if (kase < 0 && val[piv] > 0.0 || + kase > 0 && val[piv] < 0.0) + { /* delta x[p] < 0, so x[p] goes toward its lower bound */ + xassert(ll != -DBL_MAX); + delta = ll - xx; + } + else + { /* delta x[p] > 0, so x[p] goes toward its upper bound */ + xassert(uu != +DBL_MAX); + delta = uu - xx; + } + /* delta x[p] = alfa[p,k] * delta x[k], so new x[k] = x[k] + + delta x[k] = x[k] + delta x[p] / alfa[p,k] is the value of + x[k] in the adjacent basis */ + xassert(val[piv] != 0.0); + new_x = x + delta / val[piv]; +store: /* store analysis results */ + if (kase < 0) + { if (value1 != NULL) *value1 = new_x; + if (var1 != NULL) *var1 = p; + } + else + { if (value2 != NULL) *value2 = new_x; + if (var2 != NULL) *var2 = p; + } + } + /* free working arrays */ + xfree(ind); + xfree(val); + return; +} + +/*********************************************************************** +* NAME +* +* glp_analyze_coef - analyze objective coefficient at basic variable +* +* SYNOPSIS +* +* void glp_analyze_coef(glp_prob *P, int k, double *coef1, int *var1, +* double *value1, double *coef2, int *var2, double *value2); +* +* DESCRIPTION +* +* The routine glp_analyze_coef analyzes the effect of varying the +* objective coefficient at specified basic variable. +* +* The basic variable is specified by the parameter k, where +* 1 <= k <= m means auxiliary variable of corresponding row while +* m+1 <= k <= m+n means structural variable (column). +* +* Note that the current basic solution must be optimal, and the basis +* factorization must exist. +* +* Results of the analysis have the following meaning. +* +* coef1 is the minimal value of the objective coefficient, at which +* the basis still remains dual feasible and thus optimal. -DBL_MAX +* means that the objective coefficient has no lower limit. +* +* var1 is the ordinal number of an auxiliary (1 to m) or structural +* (m+1 to n) non-basic variable, whose reduced cost reaches its zero +* bound first and thereby limits further decreasing the objective +* coefficient being analyzed. If coef1 = -DBL_MAX, var1 is set to 0. +* +* value1 is value of the basic variable being analyzed in an adjacent +* basis, which is defined as follows. Let the objective coefficient +* reaches its minimal value (coef1) and continues decreasing. Then the +* reduced cost of the limiting non-basic variable (var1) becomes dual +* infeasible and the current basis becomes non-optimal that forces the +* limiting non-basic variable to enter the basis replacing there some +* basic variable that leaves the basis to keep primal feasibility. +* Should note that on determining the adjacent basis current bounds +* of the basic variable being analyzed are ignored as if it were free +* (unbounded) variable, so it cannot leave the basis. It may happen +* that no dual feasible adjacent basis exists, in which case value1 is +* set to -DBL_MAX or +DBL_MAX. +* +* coef2 is the maximal value of the objective coefficient, at which +* the basis still remains dual feasible and thus optimal. +DBL_MAX +* means that the objective coefficient has no upper limit. +* +* var2 is the ordinal number of an auxiliary (1 to m) or structural +* (m+1 to n) non-basic variable, whose reduced cost reaches its zero +* bound first and thereby limits further increasing the objective +* coefficient being analyzed. If coef2 = +DBL_MAX, var2 is set to 0. +* +* value2 is value of the basic variable being analyzed in an adjacent +* basis, which is defined exactly in the same way as value1 above with +* exception that now the objective coefficient is increasing. */ + +void glp_analyze_coef(glp_prob *P, int k, double *coef1, int *var1, + double *value1, double *coef2, int *var2, double *value2) +{ GLPROW *row; GLPCOL *col; + int m, n, type, stat, kase, p, q, dir, clen, cpiv, rlen, rpiv, + *cind, *rind; + double lb, ub, coef, x, lim_coef, new_x, d, delta, ll, uu, xx, + *rval, *cval; + /* sanity checks */ + if (P == NULL || P->magic != GLP_PROB_MAGIC) + xerror("glp_analyze_coef: P = %p; invalid problem object\n", + P); + m = P->m, n = P->n; + if (!(P->pbs_stat == GLP_FEAS && P->dbs_stat == GLP_FEAS)) + xerror("glp_analyze_coef: optimal basic solution required\n"); + if (!(m == 0 || P->valid)) + xerror("glp_analyze_coef: basis factorization required\n"); + if (!(1 <= k && k <= m+n)) + xerror("glp_analyze_coef: k = %d; variable number out of range" + "\n", k); + /* retrieve information about the specified basic variable x[k] + whose objective coefficient c[k] is to be analyzed */ + if (k <= m) + { row = P->row[k]; + type = row->type; + lb = row->lb; + ub = row->ub; + coef = 0.0; + stat = row->stat; + x = row->prim; + } + else + { col = P->col[k-m]; + type = col->type; + lb = col->lb; + ub = col->ub; + coef = col->coef; + stat = col->stat; + x = col->prim; + } + if (stat != GLP_BS) + xerror("glp_analyze_coef: k = %d; non-basic variable not allow" + "ed\n", k); + /* allocate working arrays */ + cind = xcalloc(1+m, sizeof(int)); + cval = xcalloc(1+m, sizeof(double)); + rind = xcalloc(1+n, sizeof(int)); + rval = xcalloc(1+n, sizeof(double)); + /* compute row of the simplex table corresponding to the basic + variable x[k] */ + rlen = glp_eval_tab_row(P, k, rind, rval); + xassert(0 <= rlen && rlen <= n); + /* perform analysis */ + for (kase = -1; kase <= +1; kase += 2) + { /* kase < 0 means objective coefficient c[k] is decreasing; + kase > 0 means objective coefficient c[k] is increasing */ + /* note that decreasing c[k] is equivalent to increasing dual + variable lambda[k] and vice versa; we need to correctly set + the dir flag as required by the routine glp_dual_rtest */ + if (P->dir == GLP_MIN) + dir = - kase; + else if (P->dir == GLP_MAX) + dir = + kase; + else + xassert(P != P); + /* use the dual ratio test to determine non-basic variable + x[q] whose reduced cost d[q] reaches zero bound first */ + rpiv = glp_dual_rtest(P, rlen, rind, rval, dir, 1e-9); + if (rpiv == 0) + { /* nothing limits changing c[k] */ + lim_coef = (kase < 0 ? -DBL_MAX : +DBL_MAX); + q = 0; + /* x[k] keeps its current value */ + new_x = x; + goto store; + } + /* non-basic variable x[q] limits changing coefficient c[k]; + determine its status and reduced cost d[k] in the current + basis */ + xassert(1 <= rpiv && rpiv <= rlen); + q = rind[rpiv]; + xassert(1 <= q && q <= m+n); + if (q <= m) + { row = P->row[q]; + stat = row->stat; + d = row->dual; + } + else + { col = P->col[q-m]; + stat = col->stat; + d = col->dual; + } + /* note that delta d[q] = new d[q] - d[q] = - d[q], because + new d[q] = 0; delta d[q] = alfa[k,q] * delta c[k], so + delta c[k] = delta d[q] / alfa[k,q] = - d[q] / alfa[k,q] */ + xassert(rval[rpiv] != 0.0); + delta = - d / rval[rpiv]; + /* compute new c[k] = c[k] + delta c[k], which is the limiting + value of the objective coefficient c[k] */ + lim_coef = coef + delta; + /* let c[k] continue decreasing/increasing that makes d[q] + dual infeasible and forces x[q] to enter the basis; + to perform the primal ratio test we need to know in which + direction x[q] changes on entering the basis; we determine + that analyzing the sign of delta d[q] (see above), since + d[q] may be close to zero having wrong sign */ + /* let, for simplicity, the problem is minimization */ + if (kase < 0 && rval[rpiv] > 0.0 || + kase > 0 && rval[rpiv] < 0.0) + { /* delta d[q] < 0, so d[q] being non-negative will become + negative, so x[q] will increase */ + dir = +1; + } + else + { /* delta d[q] > 0, so d[q] being non-positive will become + positive, so x[q] will decrease */ + dir = -1; + } + /* if the problem is maximization, correct the direction */ + if (P->dir == GLP_MAX) dir = - dir; + /* check that we didn't make a silly mistake */ + if (dir > 0) + xassert(stat == GLP_NL || stat == GLP_NF); + else + xassert(stat == GLP_NU || stat == GLP_NF); + /* compute column of the simplex table corresponding to the + non-basic variable x[q] */ + clen = glp_eval_tab_col(P, q, cind, cval); + /* make x[k] temporarily free (unbounded) */ + if (k <= m) + { row = P->row[k]; + row->type = GLP_FR; + row->lb = row->ub = 0.0; + } + else + { col = P->col[k-m]; + col->type = GLP_FR; + col->lb = col->ub = 0.0; + } + /* use the primal ratio test to determine some basic variable + which leaves the basis */ + cpiv = glp_prim_rtest(P, clen, cind, cval, dir, 1e-9); + /* restore original bounds of the basic variable x[k] */ + if (k <= m) + { row = P->row[k]; + row->type = type; + row->lb = lb, row->ub = ub; + } + else + { col = P->col[k-m]; + col->type = type; + col->lb = lb, col->ub = ub; + } + if (cpiv == 0) + { /* non-basic variable x[q] can change unlimitedly */ + if (dir < 0 && rval[rpiv] > 0.0 || + dir > 0 && rval[rpiv] < 0.0) + { /* delta x[k] = alfa[k,q] * delta x[q] < 0 */ + new_x = -DBL_MAX; + } + else + { /* delta x[k] = alfa[k,q] * delta x[q] > 0 */ + new_x = +DBL_MAX; + } + goto store; + } + /* some basic variable x[p] limits changing non-basic variable + x[q] in the adjacent basis */ + xassert(1 <= cpiv && cpiv <= clen); + p = cind[cpiv]; + xassert(1 <= p && p <= m+n); + xassert(p != k); + if (p <= m) + { row = P->row[p]; + xassert(row->stat == GLP_BS); + ll = glp_get_row_lb(P, row->i); + uu = glp_get_row_ub(P, row->i); + xx = row->prim; + } + else + { col = P->col[p-m]; + xassert(col->stat == GLP_BS); + ll = glp_get_col_lb(P, col->j); + uu = glp_get_col_ub(P, col->j); + xx = col->prim; + } + /* determine delta x[p] = new x[p] - x[p] */ + if (dir < 0 && cval[cpiv] > 0.0 || + dir > 0 && cval[cpiv] < 0.0) + { /* delta x[p] < 0, so x[p] goes toward its lower bound */ + xassert(ll != -DBL_MAX); + delta = ll - xx; + } + else + { /* delta x[p] > 0, so x[p] goes toward its upper bound */ + xassert(uu != +DBL_MAX); + delta = uu - xx; + } + /* compute new x[k] = x[k] + alfa[k,q] * delta x[q], where + delta x[q] = delta x[p] / alfa[p,q] */ + xassert(cval[cpiv] != 0.0); + new_x = x + (rval[rpiv] / cval[cpiv]) * delta; +store: /* store analysis results */ + if (kase < 0) + { if (coef1 != NULL) *coef1 = lim_coef; + if (var1 != NULL) *var1 = q; + if (value1 != NULL) *value1 = new_x; + } + else + { if (coef2 != NULL) *coef2 = lim_coef; + if (var2 != NULL) *var2 = q; + if (value2 != NULL) *value2 = new_x; + } + } + /* free working arrays */ + xfree(cind); + xfree(cval); + xfree(rind); + xfree(rval); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi13.c b/resources/3rdparty/glpk-4.57/src/glpapi13.c new file mode 100644 index 000000000..a4ad10b66 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi13.c @@ -0,0 +1,706 @@ +/* glpapi13.c (branch-and-bound interface routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpios.h" + +/*********************************************************************** +* NAME +* +* glp_ios_reason - determine reason for calling the callback routine +* +* SYNOPSIS +* +* glp_ios_reason(glp_tree *tree); +* +* RETURNS +* +* The routine glp_ios_reason returns a code, which indicates why the +* user-defined callback routine is being called. */ + +int glp_ios_reason(glp_tree *tree) +{ return + tree->reason; +} + +/*********************************************************************** +* NAME +* +* glp_ios_get_prob - access the problem object +* +* SYNOPSIS +* +* glp_prob *glp_ios_get_prob(glp_tree *tree); +* +* DESCRIPTION +* +* The routine glp_ios_get_prob can be called from the user-defined +* callback routine to access the problem object, which is used by the +* MIP solver. It is the original problem object passed to the routine +* glp_intopt if the MIP presolver is not used; otherwise it is an +* internal problem object built by the presolver. If the current +* subproblem exists, LP segment of the problem object corresponds to +* its LP relaxation. +* +* RETURNS +* +* The routine glp_ios_get_prob returns a pointer to the problem object +* used by the MIP solver. */ + +glp_prob *glp_ios_get_prob(glp_tree *tree) +{ return + tree->mip; +} + +/*********************************************************************** +* NAME +* +* glp_ios_tree_size - determine size of the branch-and-bound tree +* +* SYNOPSIS +* +* void glp_ios_tree_size(glp_tree *tree, int *a_cnt, int *n_cnt, +* int *t_cnt); +* +* DESCRIPTION +* +* The routine glp_ios_tree_size stores the following three counts which +* characterize the current size of the branch-and-bound tree: +* +* a_cnt is the current number of active nodes, i.e. the current size of +* the active list; +* +* n_cnt is the current number of all (active and inactive) nodes; +* +* t_cnt is the total number of nodes including those which have been +* already removed from the tree. This count is increased whenever +* a new node appears in the tree and never decreased. +* +* If some of the parameters a_cnt, n_cnt, t_cnt is a null pointer, the +* corresponding count is not stored. */ + +void glp_ios_tree_size(glp_tree *tree, int *a_cnt, int *n_cnt, + int *t_cnt) +{ if (a_cnt != NULL) *a_cnt = tree->a_cnt; + if (n_cnt != NULL) *n_cnt = tree->n_cnt; + if (t_cnt != NULL) *t_cnt = tree->t_cnt; + return; +} + +/*********************************************************************** +* NAME +* +* glp_ios_curr_node - determine current active subproblem +* +* SYNOPSIS +* +* int glp_ios_curr_node(glp_tree *tree); +* +* RETURNS +* +* The routine glp_ios_curr_node returns the reference number of the +* current active subproblem. However, if the current subproblem does +* not exist, the routine returns zero. */ + +int glp_ios_curr_node(glp_tree *tree) +{ IOSNPD *node; + /* obtain pointer to the current subproblem */ + node = tree->curr; + /* return its reference number */ + return node == NULL ? 0 : node->p; +} + +/*********************************************************************** +* NAME +* +* glp_ios_next_node - determine next active subproblem +* +* SYNOPSIS +* +* int glp_ios_next_node(glp_tree *tree, int p); +* +* RETURNS +* +* If the parameter p is zero, the routine glp_ios_next_node returns +* the reference number of the first active subproblem. However, if the +* tree is empty, zero is returned. +* +* If the parameter p is not zero, it must specify the reference number +* of some active subproblem, in which case the routine returns the +* reference number of the next active subproblem. However, if there is +* no next active subproblem in the list, zero is returned. +* +* All subproblems in the active list are ordered chronologically, i.e. +* subproblem A precedes subproblem B if A was created before B. */ + +int glp_ios_next_node(glp_tree *tree, int p) +{ IOSNPD *node; + if (p == 0) + { /* obtain pointer to the first active subproblem */ + node = tree->head; + } + else + { /* obtain pointer to the specified subproblem */ + if (!(1 <= p && p <= tree->nslots)) +err: xerror("glp_ios_next_node: p = %d; invalid subproblem refer" + "ence number\n", p); + node = tree->slot[p].node; + if (node == NULL) goto err; + /* the specified subproblem must be active */ + if (node->count != 0) + xerror("glp_ios_next_node: p = %d; subproblem not in the ac" + "tive list\n", p); + /* obtain pointer to the next active subproblem */ + node = node->next; + } + /* return the reference number */ + return node == NULL ? 0 : node->p; +} + +/*********************************************************************** +* NAME +* +* glp_ios_prev_node - determine previous active subproblem +* +* SYNOPSIS +* +* int glp_ios_prev_node(glp_tree *tree, int p); +* +* RETURNS +* +* If the parameter p is zero, the routine glp_ios_prev_node returns +* the reference number of the last active subproblem. However, if the +* tree is empty, zero is returned. +* +* If the parameter p is not zero, it must specify the reference number +* of some active subproblem, in which case the routine returns the +* reference number of the previous active subproblem. However, if there +* is no previous active subproblem in the list, zero is returned. +* +* All subproblems in the active list are ordered chronologically, i.e. +* subproblem A precedes subproblem B if A was created before B. */ + +int glp_ios_prev_node(glp_tree *tree, int p) +{ IOSNPD *node; + if (p == 0) + { /* obtain pointer to the last active subproblem */ + node = tree->tail; + } + else + { /* obtain pointer to the specified subproblem */ + if (!(1 <= p && p <= tree->nslots)) +err: xerror("glp_ios_prev_node: p = %d; invalid subproblem refer" + "ence number\n", p); + node = tree->slot[p].node; + if (node == NULL) goto err; + /* the specified subproblem must be active */ + if (node->count != 0) + xerror("glp_ios_prev_node: p = %d; subproblem not in the ac" + "tive list\n", p); + /* obtain pointer to the previous active subproblem */ + node = node->prev; + } + /* return the reference number */ + return node == NULL ? 0 : node->p; +} + +/*********************************************************************** +* NAME +* +* glp_ios_up_node - determine parent subproblem +* +* SYNOPSIS +* +* int glp_ios_up_node(glp_tree *tree, int p); +* +* RETURNS +* +* The parameter p must specify the reference number of some (active or +* inactive) subproblem, in which case the routine iet_get_up_node +* returns the reference number of its parent subproblem. However, if +* the specified subproblem is the root of the tree and, therefore, has +* no parent, the routine returns zero. */ + +int glp_ios_up_node(glp_tree *tree, int p) +{ IOSNPD *node; + /* obtain pointer to the specified subproblem */ + if (!(1 <= p && p <= tree->nslots)) +err: xerror("glp_ios_up_node: p = %d; invalid subproblem reference " + "number\n", p); + node = tree->slot[p].node; + if (node == NULL) goto err; + /* obtain pointer to the parent subproblem */ + node = node->up; + /* return the reference number */ + return node == NULL ? 0 : node->p; +} + +/*********************************************************************** +* NAME +* +* glp_ios_node_level - determine subproblem level +* +* SYNOPSIS +* +* int glp_ios_node_level(glp_tree *tree, int p); +* +* RETURNS +* +* The routine glp_ios_node_level returns the level of the subproblem, +* whose reference number is p, in the branch-and-bound tree. (The root +* subproblem has level 0, and the level of any other subproblem is the +* level of its parent plus one.) */ + +int glp_ios_node_level(glp_tree *tree, int p) +{ IOSNPD *node; + /* obtain pointer to the specified subproblem */ + if (!(1 <= p && p <= tree->nslots)) +err: xerror("glp_ios_node_level: p = %d; invalid subproblem referen" + "ce number\n", p); + node = tree->slot[p].node; + if (node == NULL) goto err; + /* return the node level */ + return node->level; +} + +/*********************************************************************** +* NAME +* +* glp_ios_node_bound - determine subproblem local bound +* +* SYNOPSIS +* +* double glp_ios_node_bound(glp_tree *tree, int p); +* +* RETURNS +* +* The routine glp_ios_node_bound returns the local bound for (active or +* inactive) subproblem, whose reference number is p. +* +* COMMENTS +* +* The local bound for subproblem p is an lower (minimization) or upper +* (maximization) bound for integer optimal solution to this subproblem +* (not to the original problem). This bound is local in the sense that +* only subproblems in the subtree rooted at node p cannot have better +* integer feasible solutions. +* +* On creating a subproblem (due to the branching step) its local bound +* is inherited from its parent and then may get only stronger (never +* weaker). For the root subproblem its local bound is initially set to +* -DBL_MAX (minimization) or +DBL_MAX (maximization) and then improved +* as the root LP relaxation has been solved. +* +* Note that the local bound is not necessarily the optimal objective +* value to corresponding LP relaxation; it may be stronger. */ + +double glp_ios_node_bound(glp_tree *tree, int p) +{ IOSNPD *node; + /* obtain pointer to the specified subproblem */ + if (!(1 <= p && p <= tree->nslots)) +err: xerror("glp_ios_node_bound: p = %d; invalid subproblem referen" + "ce number\n", p); + node = tree->slot[p].node; + if (node == NULL) goto err; + /* return the node local bound */ + return node->bound; +} + +/*********************************************************************** +* NAME +* +* glp_ios_best_node - find active subproblem with best local bound +* +* SYNOPSIS +* +* int glp_ios_best_node(glp_tree *tree); +* +* RETURNS +* +* The routine glp_ios_best_node returns the reference number of the +* active subproblem, whose local bound is best (i.e. smallest in case +* of minimization or largest in case of maximization). However, if the +* tree is empty, the routine returns zero. +* +* COMMENTS +* +* The best local bound is an lower (minimization) or upper +* (maximization) bound for integer optimal solution to the original +* MIP problem. */ + +int glp_ios_best_node(glp_tree *tree) +{ return + ios_best_node(tree); +} + +/*********************************************************************** +* NAME +* +* glp_ios_mip_gap - compute relative MIP gap +* +* SYNOPSIS +* +* double glp_ios_mip_gap(glp_tree *tree); +* +* DESCRIPTION +* +* The routine glp_ios_mip_gap computes the relative MIP gap with the +* following formula: +* +* gap = |best_mip - best_bnd| / (|best_mip| + DBL_EPSILON), +* +* where best_mip is the best integer feasible solution found so far, +* best_bnd is the best (global) bound. If no integer feasible solution +* has been found yet, gap is set to DBL_MAX. +* +* RETURNS +* +* The routine glp_ios_mip_gap returns the relative MIP gap. */ + +double glp_ios_mip_gap(glp_tree *tree) +{ return + ios_relative_gap(tree); +} + +/*********************************************************************** +* NAME +* +* glp_ios_node_data - access subproblem application-specific data +* +* SYNOPSIS +* +* void *glp_ios_node_data(glp_tree *tree, int p); +* +* DESCRIPTION +* +* The routine glp_ios_node_data allows the application accessing a +* memory block allocated for the subproblem (which may be active or +* inactive), whose reference number is p. +* +* The size of the block is defined by the control parameter cb_size +* passed to the routine glp_intopt. The block is initialized by binary +* zeros on creating corresponding subproblem, and its contents is kept +* until the subproblem will be removed from the tree. +* +* The application may use these memory blocks to store specific data +* for each subproblem. +* +* RETURNS +* +* The routine glp_ios_node_data returns a pointer to the memory block +* for the specified subproblem. Note that if cb_size = 0, the routine +* returns a null pointer. */ + +void *glp_ios_node_data(glp_tree *tree, int p) +{ IOSNPD *node; + /* obtain pointer to the specified subproblem */ + if (!(1 <= p && p <= tree->nslots)) +err: xerror("glp_ios_node_level: p = %d; invalid subproblem referen" + "ce number\n", p); + node = tree->slot[p].node; + if (node == NULL) goto err; + /* return pointer to the application-specific data */ + return node->data; +} + +/*********************************************************************** +* NAME +* +* glp_ios_row_attr - retrieve additional row attributes +* +* SYNOPSIS +* +* void glp_ios_row_attr(glp_tree *tree, int i, glp_attr *attr); +* +* DESCRIPTION +* +* The routine glp_ios_row_attr retrieves additional attributes of row +* i and stores them in the structure glp_attr. */ + +void glp_ios_row_attr(glp_tree *tree, int i, glp_attr *attr) +{ GLPROW *row; + if (!(1 <= i && i <= tree->mip->m)) + xerror("glp_ios_row_attr: i = %d; row number out of range\n", + i); + row = tree->mip->row[i]; + attr->level = row->level; + attr->origin = row->origin; + attr->klass = row->klass; + return; +} + +/**********************************************************************/ + +int glp_ios_pool_size(glp_tree *tree) +{ /* determine current size of the cut pool */ + if (tree->reason != GLP_ICUTGEN) + xerror("glp_ios_pool_size: operation not allowed\n"); + xassert(tree->local != NULL); + return tree->local->size; +} + +/**********************************************************************/ + +int glp_ios_add_row(glp_tree *tree, + const char *name, int klass, int flags, int len, const int ind[], + const double val[], int type, double rhs) +{ /* add row (constraint) to the cut pool */ + int num; + if (tree->reason != GLP_ICUTGEN) + xerror("glp_ios_add_row: operation not allowed\n"); + xassert(tree->local != NULL); + num = ios_add_row(tree, tree->local, name, klass, flags, len, + ind, val, type, rhs); + return num; +} + +/**********************************************************************/ + +void glp_ios_del_row(glp_tree *tree, int i) +{ /* remove row (constraint) from the cut pool */ + if (tree->reason != GLP_ICUTGEN) + xerror("glp_ios_del_row: operation not allowed\n"); + ios_del_row(tree, tree->local, i); + return; +} + +/**********************************************************************/ + +void glp_ios_clear_pool(glp_tree *tree) +{ /* remove all rows (constraints) from the cut pool */ + if (tree->reason != GLP_ICUTGEN) + xerror("glp_ios_clear_pool: operation not allowed\n"); + ios_clear_pool(tree, tree->local); + return; +} + +/*********************************************************************** +* NAME +* +* glp_ios_can_branch - check if can branch upon specified variable +* +* SYNOPSIS +* +* int glp_ios_can_branch(glp_tree *tree, int j); +* +* RETURNS +* +* If j-th variable (column) can be used to branch upon, the routine +* glp_ios_can_branch returns non-zero, otherwise zero. */ + +int glp_ios_can_branch(glp_tree *tree, int j) +{ if (!(1 <= j && j <= tree->mip->n)) + xerror("glp_ios_can_branch: j = %d; column number out of range" + "\n", j); + return tree->non_int[j]; +} + +/*********************************************************************** +* NAME +* +* glp_ios_branch_upon - choose variable to branch upon +* +* SYNOPSIS +* +* void glp_ios_branch_upon(glp_tree *tree, int j, int sel); +* +* DESCRIPTION +* +* The routine glp_ios_branch_upon can be called from the user-defined +* callback routine in response to the reason GLP_IBRANCH to choose a +* branching variable, whose ordinal number is j. Should note that only +* variables, for which the routine glp_ios_can_branch returns non-zero, +* can be used to branch upon. +* +* The parameter sel is a flag that indicates which branch (subproblem) +* should be selected next to continue the search: +* +* GLP_DN_BRNCH - select down-branch; +* GLP_UP_BRNCH - select up-branch; +* GLP_NO_BRNCH - use general selection technique. */ + +void glp_ios_branch_upon(glp_tree *tree, int j, int sel) +{ if (!(1 <= j && j <= tree->mip->n)) + xerror("glp_ios_branch_upon: j = %d; column number out of rang" + "e\n", j); + if (!(sel == GLP_DN_BRNCH || sel == GLP_UP_BRNCH || + sel == GLP_NO_BRNCH)) + xerror("glp_ios_branch_upon: sel = %d: invalid branch selectio" + "n flag\n", sel); + if (!(tree->non_int[j])) + xerror("glp_ios_branch_upon: j = %d; variable cannot be used t" + "o branch upon\n", j); + if (tree->br_var != 0) + xerror("glp_ios_branch_upon: branching variable already chosen" + "\n"); + tree->br_var = j; + tree->br_sel = sel; + return; +} + +/*********************************************************************** +* NAME +* +* glp_ios_select_node - select subproblem to continue the search +* +* SYNOPSIS +* +* void glp_ios_select_node(glp_tree *tree, int p); +* +* DESCRIPTION +* +* The routine glp_ios_select_node can be called from the user-defined +* callback routine in response to the reason GLP_ISELECT to select an +* active subproblem, whose reference number is p. The search will be +* continued from the subproblem selected. */ + +void glp_ios_select_node(glp_tree *tree, int p) +{ IOSNPD *node; + /* obtain pointer to the specified subproblem */ + if (!(1 <= p && p <= tree->nslots)) +err: xerror("glp_ios_select_node: p = %d; invalid subproblem refere" + "nce number\n", p); + node = tree->slot[p].node; + if (node == NULL) goto err; + /* the specified subproblem must be active */ + if (node->count != 0) + xerror("glp_ios_select_node: p = %d; subproblem not in the act" + "ive list\n", p); + /* no subproblem must be selected yet */ + if (tree->next_p != 0) + xerror("glp_ios_select_node: subproblem already selected\n"); + /* select the specified subproblem to continue the search */ + tree->next_p = p; + return; +} + +/*********************************************************************** +* NAME +* +* glp_ios_heur_sol - provide solution found by heuristic +* +* SYNOPSIS +* +* int glp_ios_heur_sol(glp_tree *tree, const double x[]); +* +* DESCRIPTION +* +* The routine glp_ios_heur_sol can be called from the user-defined +* callback routine in response to the reason GLP_IHEUR to provide an +* integer feasible solution found by a primal heuristic. +* +* Primal values of *all* variables (columns) found by the heuristic +* should be placed in locations x[1], ..., x[n], where n is the number +* of columns in the original problem object. Note that the routine +* glp_ios_heur_sol *does not* check primal feasibility of the solution +* provided. +* +* Using the solution passed in the array x the routine computes value +* of the objective function. If the objective value is better than the +* best known integer feasible solution, the routine computes values of +* auxiliary variables (rows) and stores all solution components in the +* problem object. +* +* RETURNS +* +* If the provided solution is accepted, the routine glp_ios_heur_sol +* returns zero. Otherwise, if the provided solution is rejected, the +* routine returns non-zero. */ + +int glp_ios_heur_sol(glp_tree *tree, const double x[]) +{ glp_prob *mip = tree->mip; + int m = tree->orig_m; + int n = tree->n; + int i, j; + double obj; + xassert(mip->m >= m); + xassert(mip->n == n); + /* check values of integer variables and compute value of the + objective function */ + obj = mip->c0; + for (j = 1; j <= n; j++) + { GLPCOL *col = mip->col[j]; + if (col->kind == GLP_IV) + { /* provided value must be integral */ + if (x[j] != floor(x[j])) return 1; + } + obj += col->coef * x[j]; + } + /* check if the provided solution is better than the best known + integer feasible solution */ + if (mip->mip_stat == GLP_FEAS) + { switch (mip->dir) + { case GLP_MIN: + if (obj >= tree->mip->mip_obj) return 1; + break; + case GLP_MAX: + if (obj <= tree->mip->mip_obj) return 1; + break; + default: + xassert(mip != mip); + } + } + /* it is better; store it in the problem object */ + if (tree->parm->msg_lev >= GLP_MSG_ON) + xprintf("Solution found by heuristic: %.12g\n", obj); + mip->mip_stat = GLP_FEAS; + mip->mip_obj = obj; + for (j = 1; j <= n; j++) + mip->col[j]->mipx = x[j]; + for (i = 1; i <= m; i++) + { GLPROW *row = mip->row[i]; + GLPAIJ *aij; + row->mipx = 0.0; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + row->mipx += aij->val * aij->col->mipx; + } +#if 1 /* 11/VII-2013 */ + ios_process_sol(tree); +#endif + return 0; +} + +/*********************************************************************** +* NAME +* +* glp_ios_terminate - terminate the solution process. +* +* SYNOPSIS +* +* void glp_ios_terminate(glp_tree *tree); +* +* DESCRIPTION +* +* The routine glp_ios_terminate sets a flag indicating that the MIP +* solver should prematurely terminate the search. */ + +void glp_ios_terminate(glp_tree *tree) +{ if (tree->parm->msg_lev >= GLP_MSG_DBG) + xprintf("The search is prematurely terminated due to applicati" + "on request\n"); + tree->stop = 1; + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi14.c b/resources/3rdparty/glpk-4.57/src/glpapi14.c new file mode 100644 index 000000000..fc3b73757 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi14.c @@ -0,0 +1,272 @@ +/* glpapi14.c (processing models in GNU MathProg language) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "draft.h" +#include "glpmpl.h" +#include "prob.h" + +glp_tran *glp_mpl_alloc_wksp(void) +{ /* allocate the MathProg translator workspace */ + glp_tran *tran; + tran = mpl_initialize(); + return tran; +} + +#if 1 /* 08/XII-2009 */ +void _glp_mpl_init_rand(glp_tran *tran, int seed) +{ if (tran->phase != 0) + xerror("glp_mpl_init_rand: invalid call sequence\n"); + rng_init_rand(tran->rand, seed); + return; +} +#endif + +int glp_mpl_read_model(glp_tran *tran, const char *fname, int skip) +{ /* read and translate model section */ + int ret; + if (tran->phase != 0) + xerror("glp_mpl_read_model: invalid call sequence\n"); + ret = mpl_read_model(tran, (char *)fname, skip); + if (ret == 1 || ret == 2) + ret = 0; + else if (ret == 4) + ret = 1; + else + xassert(ret != ret); + return ret; +} + +int glp_mpl_read_data(glp_tran *tran, const char *fname) +{ /* read and translate data section */ + int ret; + if (!(tran->phase == 1 || tran->phase == 2)) + xerror("glp_mpl_read_data: invalid call sequence\n"); + ret = mpl_read_data(tran, (char *)fname); + if (ret == 2) + ret = 0; + else if (ret == 4) + ret = 1; + else + xassert(ret != ret); + return ret; +} + +int glp_mpl_generate(glp_tran *tran, const char *fname) +{ /* generate the model */ + int ret; + if (!(tran->phase == 1 || tran->phase == 2)) + xerror("glp_mpl_generate: invalid call sequence\n"); + ret = mpl_generate(tran, (char *)fname); + if (ret == 3) + ret = 0; + else if (ret == 4) + ret = 1; + return ret; +} + +void glp_mpl_build_prob(glp_tran *tran, glp_prob *prob) +{ /* build LP/MIP problem instance from the model */ + int m, n, i, j, t, kind, type, len, *ind; + double lb, ub, *val; + if (tran->phase != 3) + xerror("glp_mpl_build_prob: invalid call sequence\n"); + /* erase the problem object */ + glp_erase_prob(prob); + /* set problem name */ + glp_set_prob_name(prob, mpl_get_prob_name(tran)); + /* build rows (constraints) */ + m = mpl_get_num_rows(tran); + if (m > 0) + glp_add_rows(prob, m); + for (i = 1; i <= m; i++) + { /* set row name */ + glp_set_row_name(prob, i, mpl_get_row_name(tran, i)); + /* set row bounds */ + type = mpl_get_row_bnds(tran, i, &lb, &ub); + switch (type) + { case MPL_FR: type = GLP_FR; break; + case MPL_LO: type = GLP_LO; break; + case MPL_UP: type = GLP_UP; break; + case MPL_DB: type = GLP_DB; break; + case MPL_FX: type = GLP_FX; break; + default: xassert(type != type); + } + if (type == GLP_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb))) + { type = GLP_FX; + if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub; + } + glp_set_row_bnds(prob, i, type, lb, ub); + /* warn about non-zero constant term */ + if (mpl_get_row_c0(tran, i) != 0.0) + xprintf("glp_mpl_build_prob: row %s; constant term %.12g ig" + "nored\n", + mpl_get_row_name(tran, i), mpl_get_row_c0(tran, i)); + } + /* build columns (variables) */ + n = mpl_get_num_cols(tran); + if (n > 0) + glp_add_cols(prob, n); + for (j = 1; j <= n; j++) + { /* set column name */ + glp_set_col_name(prob, j, mpl_get_col_name(tran, j)); + /* set column kind */ + kind = mpl_get_col_kind(tran, j); + switch (kind) + { case MPL_NUM: + break; + case MPL_INT: + case MPL_BIN: + glp_set_col_kind(prob, j, GLP_IV); + break; + default: + xassert(kind != kind); + } + /* set column bounds */ + type = mpl_get_col_bnds(tran, j, &lb, &ub); + switch (type) + { case MPL_FR: type = GLP_FR; break; + case MPL_LO: type = GLP_LO; break; + case MPL_UP: type = GLP_UP; break; + case MPL_DB: type = GLP_DB; break; + case MPL_FX: type = GLP_FX; break; + default: xassert(type != type); + } + if (kind == MPL_BIN) + { if (type == GLP_FR || type == GLP_UP || lb < 0.0) lb = 0.0; + if (type == GLP_FR || type == GLP_LO || ub > 1.0) ub = 1.0; + type = GLP_DB; + } + if (type == GLP_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb))) + { type = GLP_FX; + if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub; + } + glp_set_col_bnds(prob, j, type, lb, ub); + } + /* load the constraint matrix */ + ind = xcalloc(1+n, sizeof(int)); + val = xcalloc(1+n, sizeof(double)); + for (i = 1; i <= m; i++) + { len = mpl_get_mat_row(tran, i, ind, val); + glp_set_mat_row(prob, i, len, ind, val); + } + /* build objective function (the first objective is used) */ + for (i = 1; i <= m; i++) + { kind = mpl_get_row_kind(tran, i); + if (kind == MPL_MIN || kind == MPL_MAX) + { /* set objective name */ + glp_set_obj_name(prob, mpl_get_row_name(tran, i)); + /* set optimization direction */ + glp_set_obj_dir(prob, kind == MPL_MIN ? GLP_MIN : GLP_MAX); + /* set constant term */ + glp_set_obj_coef(prob, 0, mpl_get_row_c0(tran, i)); + /* set objective coefficients */ + len = mpl_get_mat_row(tran, i, ind, val); + for (t = 1; t <= len; t++) + glp_set_obj_coef(prob, ind[t], val[t]); + break; + } + } + /* free working arrays */ + xfree(ind); + xfree(val); + return; +} + +int glp_mpl_postsolve(glp_tran *tran, glp_prob *prob, int sol) +{ /* postsolve the model */ + int i, j, m, n, stat, ret; + double prim, dual; + if (!(tran->phase == 3 && !tran->flag_p)) + xerror("glp_mpl_postsolve: invalid call sequence\n"); + if (!(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP)) + xerror("glp_mpl_postsolve: sol = %d; invalid parameter\n", + sol); + m = mpl_get_num_rows(tran); + n = mpl_get_num_cols(tran); + if (!(m == glp_get_num_rows(prob) && + n == glp_get_num_cols(prob))) + xerror("glp_mpl_postsolve: wrong problem object\n"); + if (!mpl_has_solve_stmt(tran)) + { ret = 0; + goto done; + } + for (i = 1; i <= m; i++) + { if (sol == GLP_SOL) + { stat = glp_get_row_stat(prob, i); + prim = glp_get_row_prim(prob, i); + dual = glp_get_row_dual(prob, i); + } + else if (sol == GLP_IPT) + { stat = 0; + prim = glp_ipt_row_prim(prob, i); + dual = glp_ipt_row_dual(prob, i); + } + else if (sol == GLP_MIP) + { stat = 0; + prim = glp_mip_row_val(prob, i); + dual = 0.0; + } + else + xassert(sol != sol); + if (fabs(prim) < 1e-9) prim = 0.0; + if (fabs(dual) < 1e-9) dual = 0.0; + mpl_put_row_soln(tran, i, stat, prim, dual); + } + for (j = 1; j <= n; j++) + { if (sol == GLP_SOL) + { stat = glp_get_col_stat(prob, j); + prim = glp_get_col_prim(prob, j); + dual = glp_get_col_dual(prob, j); + } + else if (sol == GLP_IPT) + { stat = 0; + prim = glp_ipt_col_prim(prob, j); + dual = glp_ipt_col_dual(prob, j); + } + else if (sol == GLP_MIP) + { stat = 0; + prim = glp_mip_col_val(prob, j); + dual = 0.0; + } + else + xassert(sol != sol); + if (fabs(prim) < 1e-9) prim = 0.0; + if (fabs(dual) < 1e-9) dual = 0.0; + mpl_put_col_soln(tran, j, stat, prim, dual); + } + ret = mpl_postsolve(tran); + if (ret == 3) + ret = 0; + else if (ret == 4) + ret = 1; +done: return ret; +} + +void glp_mpl_free_wksp(glp_tran *tran) +{ /* free the MathProg translator workspace */ + mpl_terminate(tran); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi15.c b/resources/3rdparty/glpk-4.57/src/glpapi15.c new file mode 100644 index 000000000..be1248c57 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi15.c @@ -0,0 +1,615 @@ +/* glpapi15.c (basic graph and network routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpsdf.h" +#include "prob.h" + +#define xfprintf glp_format + +/* CAUTION: DO NOT CHANGE THE LIMITS BELOW */ + +#define NV_MAX 100000000 /* = 100*10^6 */ +/* maximal number of vertices in the graph */ + +#define NA_MAX 500000000 /* = 500*10^6 */ +/* maximal number of arcs in the graph */ + +/*********************************************************************** +* NAME +* +* glp_create_graph - create graph +* +* SYNOPSIS +* +* glp_graph *glp_create_graph(int v_size, int a_size); +* +* DESCRIPTION +* +* The routine creates a new graph, which initially is empty, i.e. has +* no vertices and arcs. +* +* The parameter v_size specifies the size of data associated with each +* vertex of the graph (0 to 256 bytes). +* +* The parameter a_size specifies the size of data associated with each +* arc of the graph (0 to 256 bytes). +* +* RETURNS +* +* The routine returns a pointer to the graph created. */ + +static void create_graph(glp_graph *G, int v_size, int a_size) +{ G->pool = dmp_create_pool(); + G->name = NULL; + G->nv_max = 50; + G->nv = G->na = 0; + G->v = xcalloc(1+G->nv_max, sizeof(glp_vertex *)); + G->index = NULL; + G->v_size = v_size; + G->a_size = a_size; + return; +} + +glp_graph *glp_create_graph(int v_size, int a_size) +{ glp_graph *G; + if (!(0 <= v_size && v_size <= 256)) + xerror("glp_create_graph: v_size = %d; invalid size of vertex " + "data\n", v_size); + if (!(0 <= a_size && a_size <= 256)) + xerror("glp_create_graph: a_size = %d; invalid size of arc dat" + "a\n", a_size); + G = xmalloc(sizeof(glp_graph)); + create_graph(G, v_size, a_size); + return G; +} + +/*********************************************************************** +* NAME +* +* glp_set_graph_name - assign (change) graph name +* +* SYNOPSIS +* +* void glp_set_graph_name(glp_graph *G, const char *name); +* +* DESCRIPTION +* +* The routine glp_set_graph_name assigns a symbolic name specified by +* the character string name (1 to 255 chars) to the graph. +* +* If the parameter name is NULL or an empty string, the routine erases +* the existing symbolic name of the graph. */ + +void glp_set_graph_name(glp_graph *G, const char *name) +{ if (G->name != NULL) + { dmp_free_atom(G->pool, G->name, strlen(G->name)+1); + G->name = NULL; + } + if (!(name == NULL || name[0] == '\0')) + { int j; + for (j = 0; name[j] != '\0'; j++) + { if (j == 256) + xerror("glp_set_graph_name: graph name too long\n"); + if (iscntrl((unsigned char)name[j])) + xerror("glp_set_graph_name: graph name contains invalid " + "character(s)\n"); + } + G->name = dmp_get_atom(G->pool, strlen(name)+1); + strcpy(G->name, name); + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_add_vertices - add new vertices to graph +* +* SYNOPSIS +* +* int glp_add_vertices(glp_graph *G, int nadd); +* +* DESCRIPTION +* +* The routine glp_add_vertices adds nadd vertices to the specified +* graph. New vertices are always added to the end of the vertex list, +* so ordinal numbers of existing vertices remain unchanged. +* +* Being added each new vertex is isolated (has no incident arcs). +* +* RETURNS +* +* The routine glp_add_vertices returns an ordinal number of the first +* new vertex added to the graph. */ + +int glp_add_vertices(glp_graph *G, int nadd) +{ int i, nv_new; + if (nadd < 1) + xerror("glp_add_vertices: nadd = %d; invalid number of vertice" + "s\n", nadd); + if (nadd > NV_MAX - G->nv) + xerror("glp_add_vertices: nadd = %d; too many vertices\n", + nadd); + /* determine new number of vertices */ + nv_new = G->nv + nadd; + /* increase the room, if necessary */ + if (G->nv_max < nv_new) + { glp_vertex **save = G->v; + while (G->nv_max < nv_new) + { G->nv_max += G->nv_max; + xassert(G->nv_max > 0); + } + G->v = xcalloc(1+G->nv_max, sizeof(glp_vertex *)); + memcpy(&G->v[1], &save[1], G->nv * sizeof(glp_vertex *)); + xfree(save); + } + /* add new vertices to the end of the vertex list */ + for (i = G->nv+1; i <= nv_new; i++) + { glp_vertex *v; + G->v[i] = v = dmp_get_atom(G->pool, sizeof(glp_vertex)); + v->i = i; + v->name = NULL; + v->entry = NULL; + if (G->v_size == 0) + v->data = NULL; + else + { v->data = dmp_get_atom(G->pool, G->v_size); + memset(v->data, 0, G->v_size); + } + v->temp = NULL; + v->in = v->out = NULL; + } + /* set new number of vertices */ + G->nv = nv_new; + /* return the ordinal number of the first vertex added */ + return nv_new - nadd + 1; +} + +/**********************************************************************/ + +void glp_set_vertex_name(glp_graph *G, int i, const char *name) +{ /* assign (change) vertex name */ + glp_vertex *v; + if (!(1 <= i && i <= G->nv)) + xerror("glp_set_vertex_name: i = %d; vertex number out of rang" + "e\n", i); + v = G->v[i]; + if (v->name != NULL) + { if (v->entry != NULL) + { xassert(G->index != NULL); + avl_delete_node(G->index, v->entry); + v->entry = NULL; + } + dmp_free_atom(G->pool, v->name, strlen(v->name)+1); + v->name = NULL; + } + if (!(name == NULL || name[0] == '\0')) + { int k; + for (k = 0; name[k] != '\0'; k++) + { if (k == 256) + xerror("glp_set_vertex_name: i = %d; vertex name too lon" + "g\n", i); + if (iscntrl((unsigned char)name[k])) + xerror("glp_set_vertex_name: i = %d; vertex name contain" + "s invalid character(s)\n", i); + } + v->name = dmp_get_atom(G->pool, strlen(name)+1); + strcpy(v->name, name); + if (G->index != NULL) + { xassert(v->entry == NULL); + v->entry = avl_insert_node(G->index, v->name); + avl_set_node_link(v->entry, v); + } + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_add_arc - add new arc to graph +* +* SYNOPSIS +* +* glp_arc *glp_add_arc(glp_graph *G, int i, int j); +* +* DESCRIPTION +* +* The routine glp_add_arc adds a new arc to the specified graph. +* +* The parameters i and j specify the ordinal numbers of, resp., tail +* and head vertices of the arc. Note that self-loops and multiple arcs +* are allowed. +* +* RETURNS +* +* The routine glp_add_arc returns a pointer to the arc added. */ + +glp_arc *glp_add_arc(glp_graph *G, int i, int j) +{ glp_arc *a; + if (!(1 <= i && i <= G->nv)) + xerror("glp_add_arc: i = %d; tail vertex number out of range\n" + , i); + if (!(1 <= j && j <= G->nv)) + xerror("glp_add_arc: j = %d; head vertex number out of range\n" + , j); + if (G->na == NA_MAX) + xerror("glp_add_arc: too many arcs\n"); + a = dmp_get_atom(G->pool, sizeof(glp_arc)); + a->tail = G->v[i]; + a->head = G->v[j]; + if (G->a_size == 0) + a->data = NULL; + else + { a->data = dmp_get_atom(G->pool, G->a_size); + memset(a->data, 0, G->a_size); + } + a->temp = NULL; + a->t_prev = NULL; + a->t_next = G->v[i]->out; + if (a->t_next != NULL) a->t_next->t_prev = a; + a->h_prev = NULL; + a->h_next = G->v[j]->in; + if (a->h_next != NULL) a->h_next->h_prev = a; + G->v[i]->out = G->v[j]->in = a; + G->na++; + return a; +} + +/*********************************************************************** +* NAME +* +* glp_del_vertices - delete vertices from graph +* +* SYNOPSIS +* +* void glp_del_vertices(glp_graph *G, int ndel, const int num[]); +* +* DESCRIPTION +* +* The routine glp_del_vertices deletes vertices along with all +* incident arcs from the specified graph. Ordinal numbers of vertices +* to be deleted should be placed in locations num[1], ..., num[ndel], +* ndel > 0. +* +* Note that deleting vertices involves changing ordinal numbers of +* other vertices remaining in the graph. New ordinal numbers of the +* remaining vertices are assigned under the assumption that the +* original order of vertices is not changed. */ + +void glp_del_vertices(glp_graph *G, int ndel, const int num[]) +{ glp_vertex *v; + int i, k, nv_new; + /* scan the list of vertices to be deleted */ + if (!(1 <= ndel && ndel <= G->nv)) + xerror("glp_del_vertices: ndel = %d; invalid number of vertice" + "s\n", ndel); + for (k = 1; k <= ndel; k++) + { /* take the number of vertex to be deleted */ + i = num[k]; + /* obtain pointer to i-th vertex */ + if (!(1 <= i && i <= G->nv)) + xerror("glp_del_vertices: num[%d] = %d; vertex number out o" + "f range\n", k, i); + v = G->v[i]; + /* check that the vertex is not marked yet */ + if (v->i == 0) + xerror("glp_del_vertices: num[%d] = %d; duplicate vertex nu" + "mbers not allowed\n", k, i); + /* erase symbolic name assigned to the vertex */ + glp_set_vertex_name(G, i, NULL); + xassert(v->name == NULL); + xassert(v->entry == NULL); + /* free vertex data, if allocated */ + if (v->data != NULL) + dmp_free_atom(G->pool, v->data, G->v_size); + /* delete all incoming arcs */ + while (v->in != NULL) + glp_del_arc(G, v->in); + /* delete all outgoing arcs */ + while (v->out != NULL) + glp_del_arc(G, v->out); + /* mark the vertex to be deleted */ + v->i = 0; + } + /* delete all marked vertices from the vertex list */ + nv_new = 0; + for (i = 1; i <= G->nv; i++) + { /* obtain pointer to i-th vertex */ + v = G->v[i]; + /* check if the vertex is marked */ + if (v->i == 0) + { /* it is marked, delete it */ + dmp_free_atom(G->pool, v, sizeof(glp_vertex)); + } + else + { /* it is not marked, keep it */ + v->i = ++nv_new; + G->v[v->i] = v; + } + } + /* set new number of vertices in the graph */ + G->nv = nv_new; + return; +} + +/*********************************************************************** +* NAME +* +* glp_del_arc - delete arc from graph +* +* SYNOPSIS +* +* void glp_del_arc(glp_graph *G, glp_arc *a); +* +* DESCRIPTION +* +* The routine glp_del_arc deletes an arc from the specified graph. +* The arc to be deleted must exist. */ + +void glp_del_arc(glp_graph *G, glp_arc *a) +{ /* some sanity checks */ + xassert(G->na > 0); + xassert(1 <= a->tail->i && a->tail->i <= G->nv); + xassert(a->tail == G->v[a->tail->i]); + xassert(1 <= a->head->i && a->head->i <= G->nv); + xassert(a->head == G->v[a->head->i]); + /* remove the arc from the list of incoming arcs */ + if (a->h_prev == NULL) + a->head->in = a->h_next; + else + a->h_prev->h_next = a->h_next; + if (a->h_next == NULL) + ; + else + a->h_next->h_prev = a->h_prev; + /* remove the arc from the list of outgoing arcs */ + if (a->t_prev == NULL) + a->tail->out = a->t_next; + else + a->t_prev->t_next = a->t_next; + if (a->t_next == NULL) + ; + else + a->t_next->t_prev = a->t_prev; + /* free arc data, if allocated */ + if (a->data != NULL) + dmp_free_atom(G->pool, a->data, G->a_size); + /* delete the arc from the graph */ + dmp_free_atom(G->pool, a, sizeof(glp_arc)); + G->na--; + return; +} + +/*********************************************************************** +* NAME +* +* glp_erase_graph - erase graph content +* +* SYNOPSIS +* +* void glp_erase_graph(glp_graph *G, int v_size, int a_size); +* +* DESCRIPTION +* +* The routine glp_erase_graph erases the content of the specified +* graph. The effect of this operation is the same as if the graph +* would be deleted with the routine glp_delete_graph and then created +* anew with the routine glp_create_graph, with exception that the +* handle (pointer) to the graph remains valid. */ + +static void delete_graph(glp_graph *G) +{ dmp_delete_pool(G->pool); + xfree(G->v); + if (G->index != NULL) avl_delete_tree(G->index); + return; +} + +void glp_erase_graph(glp_graph *G, int v_size, int a_size) +{ if (!(0 <= v_size && v_size <= 256)) + xerror("glp_erase_graph: v_size = %d; invalid size of vertex d" + "ata\n", v_size); + if (!(0 <= a_size && a_size <= 256)) + xerror("glp_erase_graph: a_size = %d; invalid size of arc data" + "\n", a_size); + delete_graph(G); + create_graph(G, v_size, a_size); + return; +} + +/*********************************************************************** +* NAME +* +* glp_delete_graph - delete graph +* +* SYNOPSIS +* +* void glp_delete_graph(glp_graph *G); +* +* DESCRIPTION +* +* The routine glp_delete_graph deletes the specified graph and frees +* all the memory allocated to this program object. */ + +void glp_delete_graph(glp_graph *G) +{ delete_graph(G); + xfree(G); + return; +} + +/**********************************************************************/ + +void glp_create_v_index(glp_graph *G) +{ /* create vertex name index */ + glp_vertex *v; + int i; + if (G->index == NULL) + { G->index = avl_create_tree(avl_strcmp, NULL); + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + xassert(v->entry == NULL); + if (v->name != NULL) + { v->entry = avl_insert_node(G->index, v->name); + avl_set_node_link(v->entry, v); + } + } + } + return; +} + +int glp_find_vertex(glp_graph *G, const char *name) +{ /* find vertex by its name */ + AVLNODE *node; + int i = 0; + if (G->index == NULL) + xerror("glp_find_vertex: vertex name index does not exist\n"); + if (!(name == NULL || name[0] == '\0' || strlen(name) > 255)) + { node = avl_find_node(G->index, name); + if (node != NULL) + i = ((glp_vertex *)avl_get_node_link(node))->i; + } + return i; +} + +void glp_delete_v_index(glp_graph *G) +{ /* delete vertex name index */ + int i; + if (G->index != NULL) + { avl_delete_tree(G->index), G->index = NULL; + for (i = 1; i <= G->nv; i++) G->v[i]->entry = NULL; + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_read_graph - read graph from plain text file +* +* SYNOPSIS +* +* int glp_read_graph(glp_graph *G, const char *fname); +* +* DESCRIPTION +* +* The routine glp_read_graph reads a graph from a plain text file. +* +* RETURNS +* +* If the operation was successful, the routine returns zero. Otherwise +* it prints an error message and returns non-zero. */ + +int glp_read_graph(glp_graph *G, const char *fname) +{ glp_data *data; + jmp_buf jump; + int nv, na, i, j, k, ret; + glp_erase_graph(G, G->v_size, G->a_size); + xprintf("Reading graph from '%s'...\n", fname); + data = glp_sdf_open_file(fname); + if (data == NULL) + { ret = 1; + goto done; + } + if (setjmp(jump)) + { ret = 1; + goto done; + } + glp_sdf_set_jump(data, jump); + nv = glp_sdf_read_int(data); + if (nv < 0) + glp_sdf_error(data, "invalid number of vertices\n"); + na = glp_sdf_read_int(data); + if (na < 0) + glp_sdf_error(data, "invalid number of arcs\n"); + xprintf("Graph has %d vert%s and %d arc%s\n", + nv, nv == 1 ? "ex" : "ices", na, na == 1 ? "" : "s"); + if (nv > 0) glp_add_vertices(G, nv); + for (k = 1; k <= na; k++) + { i = glp_sdf_read_int(data); + if (!(1 <= i && i <= nv)) + glp_sdf_error(data, "tail vertex number out of range\n"); + j = glp_sdf_read_int(data); + if (!(1 <= j && j <= nv)) + glp_sdf_error(data, "head vertex number out of range\n"); + glp_add_arc(G, i, j); + } + xprintf("%d lines were read\n", glp_sdf_line(data)); + ret = 0; +done: if (data != NULL) glp_sdf_close_file(data); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_write_graph - write graph to plain text file +* +* SYNOPSIS +* +* int glp_write_graph(glp_graph *G, const char *fname). +* +* DESCRIPTION +* +* The routine glp_write_graph writes the specified graph to a plain +* text file. +* +* RETURNS +* +* If the operation was successful, the routine returns zero. Otherwise +* it prints an error message and returns non-zero. */ + +int glp_write_graph(glp_graph *G, const char *fname) +{ glp_file *fp; + glp_vertex *v; + glp_arc *a; + int i, count, ret; + xprintf("Writing graph to '%s'...\n", fname); + fp = glp_open(fname, "w"), count = 0; + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xfprintf(fp, "%d %d\n", G->nv, G->na), count++; + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + xfprintf(fp, "%d %d\n", a->tail->i, a->head->i), count++; + } +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xprintf("%d lines were written\n", count); + ret = 0; +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi16.c b/resources/3rdparty/glpk-4.57/src/glpapi16.c new file mode 100644 index 000000000..9af86e2bd --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi16.c @@ -0,0 +1,330 @@ +/* glpapi16.c (graph and network analysis routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "mc13d.h" +#include "prob.h" + +/*********************************************************************** +* NAME +* +* glp_weak_comp - find all weakly connected components of graph +* +* SYNOPSIS +* +* int glp_weak_comp(glp_graph *G, int v_num); +* +* DESCRIPTION +* +* The routine glp_weak_comp finds all weakly connected components of +* the specified graph. +* +* The parameter v_num specifies an offset of the field of type int +* in the vertex data block, to which the routine stores the number of +* a (weakly) connected component containing that vertex. If v_num < 0, +* no component numbers are stored. +* +* The components are numbered in arbitrary order from 1 to nc, where +* nc is the total number of components found, 0 <= nc <= |V|. +* +* RETURNS +* +* The routine returns nc, the total number of components found. */ + +int glp_weak_comp(glp_graph *G, int v_num) +{ glp_vertex *v; + glp_arc *a; + int f, i, j, nc, nv, pos1, pos2, *prev, *next, *list; + if (v_num >= 0 && v_num > G->v_size - (int)sizeof(int)) + xerror("glp_weak_comp: v_num = %d; invalid offset\n", v_num); + nv = G->nv; + if (nv == 0) + { nc = 0; + goto done; + } + /* allocate working arrays */ + prev = xcalloc(1+nv, sizeof(int)); + next = xcalloc(1+nv, sizeof(int)); + list = xcalloc(1+nv, sizeof(int)); + /* if vertex i is unlabelled, prev[i] is the index of previous + unlabelled vertex, and next[i] is the index of next unlabelled + vertex; if vertex i is labelled, then prev[i] < 0, and next[i] + is the connected component number */ + /* initially all vertices are unlabelled */ + f = 1; + for (i = 1; i <= nv; i++) + prev[i] = i - 1, next[i] = i + 1; + next[nv] = 0; + /* main loop (until all vertices have been labelled) */ + nc = 0; + while (f != 0) + { /* take an unlabelled vertex */ + i = f; + /* and remove it from the list of unlabelled vertices */ + f = next[i]; + if (f != 0) prev[f] = 0; + /* label the vertex; it begins a new component */ + prev[i] = -1, next[i] = ++nc; + /* breadth first search */ + list[1] = i, pos1 = pos2 = 1; + while (pos1 <= pos2) + { /* dequeue vertex i */ + i = list[pos1++]; + /* consider all arcs incoming to vertex i */ + for (a = G->v[i]->in; a != NULL; a = a->h_next) + { /* vertex j is adjacent to vertex i */ + j = a->tail->i; + if (prev[j] >= 0) + { /* vertex j is unlabelled */ + /* remove it from the list of unlabelled vertices */ + if (prev[j] == 0) + f = next[j]; + else + next[prev[j]] = next[j]; + if (next[j] == 0) + ; + else + prev[next[j]] = prev[j]; + /* label the vertex */ + prev[j] = -1, next[j] = nc; + /* and enqueue it for further consideration */ + list[++pos2] = j; + } + } + /* consider all arcs outgoing from vertex i */ + for (a = G->v[i]->out; a != NULL; a = a->t_next) + { /* vertex j is adjacent to vertex i */ + j = a->head->i; + if (prev[j] >= 0) + { /* vertex j is unlabelled */ + /* remove it from the list of unlabelled vertices */ + if (prev[j] == 0) + f = next[j]; + else + next[prev[j]] = next[j]; + if (next[j] == 0) + ; + else + prev[next[j]] = prev[j]; + /* label the vertex */ + prev[j] = -1, next[j] = nc; + /* and enqueue it for further consideration */ + list[++pos2] = j; + } + } + } + } + /* store component numbers */ + if (v_num >= 0) + { for (i = 1; i <= nv; i++) + { v = G->v[i]; + memcpy((char *)v->data + v_num, &next[i], sizeof(int)); + } + } + /* free working arrays */ + xfree(prev); + xfree(next); + xfree(list); +done: return nc; +} + +/*********************************************************************** +* NAME +* +* glp_strong_comp - find all strongly connected components of graph +* +* SYNOPSIS +* +* int glp_strong_comp(glp_graph *G, int v_num); +* +* DESCRIPTION +* +* The routine glp_strong_comp finds all strongly connected components +* of the specified graph. +* +* The parameter v_num specifies an offset of the field of type int +* in the vertex data block, to which the routine stores the number of +* a strongly connected component containing that vertex. If v_num < 0, +* no component numbers are stored. +* +* The components are numbered in arbitrary order from 1 to nc, where +* nc is the total number of components found, 0 <= nc <= |V|. However, +* the component numbering has the property that for every arc (i->j) +* in the graph the condition num(i) >= num(j) holds. +* +* RETURNS +* +* The routine returns nc, the total number of components found. */ + +int glp_strong_comp(glp_graph *G, int v_num) +{ glp_vertex *v; + glp_arc *a; + int i, k, last, n, na, nc, *icn, *ip, *lenr, *ior, *ib, *lowl, + *numb, *prev; + if (v_num >= 0 && v_num > G->v_size - (int)sizeof(int)) + xerror("glp_strong_comp: v_num = %d; invalid offset\n", + v_num); + n = G->nv; + if (n == 0) + { nc = 0; + goto done; + } + na = G->na; + icn = xcalloc(1+na, sizeof(int)); + ip = xcalloc(1+n, sizeof(int)); + lenr = xcalloc(1+n, sizeof(int)); + ior = xcalloc(1+n, sizeof(int)); + ib = xcalloc(1+n, sizeof(int)); + lowl = xcalloc(1+n, sizeof(int)); + numb = xcalloc(1+n, sizeof(int)); + prev = xcalloc(1+n, sizeof(int)); + k = 1; + for (i = 1; i <= n; i++) + { v = G->v[i]; + ip[i] = k; + for (a = v->out; a != NULL; a = a->t_next) + icn[k++] = a->head->i; + lenr[i] = k - ip[i]; + } + xassert(na == k-1); + nc = mc13d(n, icn, ip, lenr, ior, ib, lowl, numb, prev); + if (v_num >= 0) + { xassert(ib[1] == 1); + for (k = 1; k <= nc; k++) + { last = (k < nc ? ib[k+1] : n+1); + xassert(ib[k] < last); + for (i = ib[k]; i < last; i++) + { v = G->v[ior[i]]; + memcpy((char *)v->data + v_num, &k, sizeof(int)); + } + } + } + xfree(icn); + xfree(ip); + xfree(lenr); + xfree(ior); + xfree(ib); + xfree(lowl); + xfree(numb); + xfree(prev); +done: return nc; +} + +/*********************************************************************** +* NAME +* +* glp_top_sort - topological sorting of acyclic digraph +* +* SYNOPSIS +* +* int glp_top_sort(glp_graph *G, int v_num); +* +* DESCRIPTION +* +* The routine glp_top_sort performs topological sorting of vertices of +* the specified acyclic digraph. +* +* The parameter v_num specifies an offset of the field of type int in +* the vertex data block, to which the routine stores the vertex number +* assigned. If v_num < 0, vertex numbers are not stored. +* +* The vertices are numbered from 1 to n, where n is the total number +* of vertices in the graph. The vertex numbering has the property that +* for every arc (i->j) in the graph the condition num(i) < num(j) +* holds. Special case num(i) = 0 means that vertex i is not assigned a +* number, because the graph is *not* acyclic. +* +* RETURNS +* +* If the graph is acyclic and therefore all the vertices have been +* assigned numbers, the routine glp_top_sort returns zero. Otherwise, +* if the graph is not acyclic, the routine returns the number of +* vertices which have not been numbered, i.e. for which num(i) = 0. */ + +static int top_sort(glp_graph *G, int num[]) +{ glp_arc *a; + int i, j, cnt, top, *stack, *indeg; + /* allocate working arrays */ + indeg = xcalloc(1+G->nv, sizeof(int)); + stack = xcalloc(1+G->nv, sizeof(int)); + /* determine initial indegree of each vertex; push into the stack + the vertices having zero indegree */ + top = 0; + for (i = 1; i <= G->nv; i++) + { num[i] = indeg[i] = 0; + for (a = G->v[i]->in; a != NULL; a = a->h_next) + indeg[i]++; + if (indeg[i] == 0) + stack[++top] = i; + } + /* assign numbers to vertices in the sorted order */ + cnt = 0; + while (top > 0) + { /* pull vertex i from the stack */ + i = stack[top--]; + /* it has zero indegree in the current graph */ + xassert(indeg[i] == 0); + /* so assign it a next number */ + xassert(num[i] == 0); + num[i] = ++cnt; + /* remove vertex i from the current graph, update indegree of + its adjacent vertices, and push into the stack new vertices + whose indegree becomes zero */ + for (a = G->v[i]->out; a != NULL; a = a->t_next) + { j = a->head->i; + /* there exists arc (i->j) in the graph */ + xassert(indeg[j] > 0); + indeg[j]--; + if (indeg[j] == 0) + stack[++top] = j; + } + } + /* free working arrays */ + xfree(indeg); + xfree(stack); + return G->nv - cnt; +} + +int glp_top_sort(glp_graph *G, int v_num) +{ glp_vertex *v; + int i, cnt, *num; + if (v_num >= 0 && v_num > G->v_size - (int)sizeof(int)) + xerror("glp_top_sort: v_num = %d; invalid offset\n", v_num); + if (G->nv == 0) + { cnt = 0; + goto done; + } + num = xcalloc(1+G->nv, sizeof(int)); + cnt = top_sort(G, num); + if (v_num >= 0) + { for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + memcpy((char *)v->data + v_num, &num[i], sizeof(int)); + } + } + xfree(num); +done: return cnt; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi17.c b/resources/3rdparty/glpk-4.57/src/glpapi17.c new file mode 100644 index 000000000..425c6a5a8 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi17.c @@ -0,0 +1,1269 @@ +/* glpapi17.c (flow network problems) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "ffalg.h" +#include "mc21a.h" +#include "okalg.h" +#include "prob.h" +#include "relax4.h" + +/*********************************************************************** +* NAME +* +* glp_mincost_lp - convert minimum cost flow problem to LP +* +* SYNOPSIS +* +* void glp_mincost_lp(glp_prob *lp, glp_graph *G, int names, +* int v_rhs, int a_low, int a_cap, int a_cost); +* +* DESCRIPTION +* +* The routine glp_mincost_lp builds an LP problem, which corresponds +* to the minimum cost flow problem on the specified network G. */ + +void glp_mincost_lp(glp_prob *lp, glp_graph *G, int names, int v_rhs, + int a_low, int a_cap, int a_cost) +{ glp_vertex *v; + glp_arc *a; + int i, j, type, ind[1+2]; + double rhs, low, cap, cost, val[1+2]; + if (!(names == GLP_ON || names == GLP_OFF)) + xerror("glp_mincost_lp: names = %d; invalid parameter\n", + names); + if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) + xerror("glp_mincost_lp: v_rhs = %d; invalid offset\n", v_rhs); + if (a_low >= 0 && a_low > G->a_size - (int)sizeof(double)) + xerror("glp_mincost_lp: a_low = %d; invalid offset\n", a_low); + if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) + xerror("glp_mincost_lp: a_cap = %d; invalid offset\n", a_cap); + if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) + xerror("glp_mincost_lp: a_cost = %d; invalid offset\n", a_cost) + ; + glp_erase_prob(lp); + if (names) glp_set_prob_name(lp, G->name); + if (G->nv > 0) glp_add_rows(lp, G->nv); + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + if (names) glp_set_row_name(lp, i, v->name); + if (v_rhs >= 0) + memcpy(&rhs, (char *)v->data + v_rhs, sizeof(double)); + else + rhs = 0.0; + glp_set_row_bnds(lp, i, GLP_FX, rhs, rhs); + } + if (G->na > 0) glp_add_cols(lp, G->na); + for (i = 1, j = 0; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { j++; + if (names) + { char name[50+1]; + sprintf(name, "x[%d,%d]", a->tail->i, a->head->i); + xassert(strlen(name) < sizeof(name)); + glp_set_col_name(lp, j, name); + } + if (a->tail->i != a->head->i) + { ind[1] = a->tail->i, val[1] = +1.0; + ind[2] = a->head->i, val[2] = -1.0; + glp_set_mat_col(lp, j, 2, ind, val); + } + if (a_low >= 0) + memcpy(&low, (char *)a->data + a_low, sizeof(double)); + else + low = 0.0; + if (a_cap >= 0) + memcpy(&cap, (char *)a->data + a_cap, sizeof(double)); + else + cap = 1.0; + if (cap == DBL_MAX) + type = GLP_LO; + else if (low != cap) + type = GLP_DB; + else + type = GLP_FX; + glp_set_col_bnds(lp, j, type, low, cap); + if (a_cost >= 0) + memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); + else + cost = 0.0; + glp_set_obj_coef(lp, j, cost); + } + } + xassert(j == G->na); + return; +} + +/**********************************************************************/ + +int glp_mincost_okalg(glp_graph *G, int v_rhs, int a_low, int a_cap, + int a_cost, double *sol, int a_x, int v_pi) +{ /* find minimum-cost flow with out-of-kilter algorithm */ + glp_vertex *v; + glp_arc *a; + int nv, na, i, k, s, t, *tail, *head, *low, *cap, *cost, *x, *pi, + ret; + double sum, temp; + if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) + xerror("glp_mincost_okalg: v_rhs = %d; invalid offset\n", + v_rhs); + if (a_low >= 0 && a_low > G->a_size - (int)sizeof(double)) + xerror("glp_mincost_okalg: a_low = %d; invalid offset\n", + a_low); + if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) + xerror("glp_mincost_okalg: a_cap = %d; invalid offset\n", + a_cap); + if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) + xerror("glp_mincost_okalg: a_cost = %d; invalid offset\n", + a_cost); + if (a_x >= 0 && a_x > G->a_size - (int)sizeof(double)) + xerror("glp_mincost_okalg: a_x = %d; invalid offset\n", a_x); + if (v_pi >= 0 && v_pi > G->v_size - (int)sizeof(double)) + xerror("glp_mincost_okalg: v_pi = %d; invalid offset\n", v_pi); + /* s is artificial source node */ + s = G->nv + 1; + /* t is artificial sink node */ + t = s + 1; + /* nv is the total number of nodes in the resulting network */ + nv = t; + /* na is the total number of arcs in the resulting network */ + na = G->na + 1; + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + if (v_rhs >= 0) + memcpy(&temp, (char *)v->data + v_rhs, sizeof(double)); + else + temp = 0.0; + if (temp != 0.0) na++; + } + /* allocate working arrays */ + tail = xcalloc(1+na, sizeof(int)); + head = xcalloc(1+na, sizeof(int)); + low = xcalloc(1+na, sizeof(int)); + cap = xcalloc(1+na, sizeof(int)); + cost = xcalloc(1+na, sizeof(int)); + x = xcalloc(1+na, sizeof(int)); + pi = xcalloc(1+nv, sizeof(int)); + /* construct the resulting network */ + k = 0; + /* (original arcs) */ + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { k++; + tail[k] = a->tail->i; + head[k] = a->head->i; + if (tail[k] == head[k]) + { ret = GLP_EDATA; + goto done; + } + if (a_low >= 0) + memcpy(&temp, (char *)a->data + a_low, sizeof(double)); + else + temp = 0.0; + if (!(0.0 <= temp && temp <= (double)INT_MAX && + temp == floor(temp))) + { ret = GLP_EDATA; + goto done; + } + low[k] = (int)temp; + if (a_cap >= 0) + memcpy(&temp, (char *)a->data + a_cap, sizeof(double)); + else + temp = 1.0; + if (!((double)low[k] <= temp && temp <= (double)INT_MAX && + temp == floor(temp))) + { ret = GLP_EDATA; + goto done; + } + cap[k] = (int)temp; + if (a_cost >= 0) + memcpy(&temp, (char *)a->data + a_cost, sizeof(double)); + else + temp = 0.0; + if (!(fabs(temp) <= (double)INT_MAX && temp == floor(temp))) + { ret = GLP_EDATA; + goto done; + } + cost[k] = (int)temp; + } + } + /* (artificial arcs) */ + sum = 0.0; + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + if (v_rhs >= 0) + memcpy(&temp, (char *)v->data + v_rhs, sizeof(double)); + else + temp = 0.0; + if (!(fabs(temp) <= (double)INT_MAX && temp == floor(temp))) + { ret = GLP_EDATA; + goto done; + } + if (temp > 0.0) + { /* artificial arc from s to original source i */ + k++; + tail[k] = s; + head[k] = i; + low[k] = cap[k] = (int)(+temp); /* supply */ + cost[k] = 0; + sum += (double)temp; + } + else if (temp < 0.0) + { /* artificial arc from original sink i to t */ + k++; + tail[k] = i; + head[k] = t; + low[k] = cap[k] = (int)(-temp); /* demand */ + cost[k] = 0; + } + } + /* (feedback arc from t to s) */ + k++; + xassert(k == na); + tail[k] = t; + head[k] = s; + if (sum > (double)INT_MAX) + { ret = GLP_EDATA; + goto done; + } + low[k] = cap[k] = (int)sum; /* total supply/demand */ + cost[k] = 0; + /* find minimal-cost circulation in the resulting network */ + ret = okalg(nv, na, tail, head, low, cap, cost, x, pi); + switch (ret) + { case 0: + /* optimal circulation found */ + ret = 0; + break; + case 1: + /* no feasible circulation exists */ + ret = GLP_ENOPFS; + break; + case 2: + /* integer overflow occured */ + ret = GLP_ERANGE; + goto done; + case 3: + /* optimality test failed (logic error) */ + ret = GLP_EFAIL; + goto done; + default: + xassert(ret != ret); + } + /* store solution components */ + /* (objective function = the total cost) */ + if (sol != NULL) + { temp = 0.0; + for (k = 1; k <= na; k++) + temp += (double)cost[k] * (double)x[k]; + *sol = temp; + } + /* (arc flows) */ + if (a_x >= 0) + { k = 0; + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { temp = (double)x[++k]; + memcpy((char *)a->data + a_x, &temp, sizeof(double)); + } + } + } + /* (node potentials = Lagrange multipliers) */ + if (v_pi >= 0) + { for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + temp = - (double)pi[i]; + memcpy((char *)v->data + v_pi, &temp, sizeof(double)); + } + } +done: /* free working arrays */ + xfree(tail); + xfree(head); + xfree(low); + xfree(cap); + xfree(cost); + xfree(x); + xfree(pi); + return ret; +} + +/**********************************************************************/ + +static int overflow(int u, int v) +{ /* check for integer overflow on computing u + v */ + if (u > 0 && v > 0 && u + v < 0) return 1; + if (u < 0 && v < 0 && u + v > 0) return 1; + return 0; +} + +int glp_mincost_relax4(glp_graph *G, int v_rhs, int a_low, int a_cap, + int a_cost, int crash, double *sol, int a_x, int a_rc) +{ /* find minimum-cost flow with Bertsekas-Tseng relaxation method + (RELAX-IV) */ + glp_vertex *v; + glp_arc *a; + struct relax4_csa csa; + int i, k, large, n, na, ret; + double cap, cost, low, rc, rhs, sum, x; + if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) + xerror("glp_mincost_relax4: v_rhs = %d; invalid offset\n", + v_rhs); + if (a_low >= 0 && a_low > G->a_size - (int)sizeof(double)) + xerror("glp_mincost_relax4: a_low = %d; invalid offset\n", + a_low); + if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) + xerror("glp_mincost_relax4: a_cap = %d; invalid offset\n", + a_cap); + if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) + xerror("glp_mincost_relax4: a_cost = %d; invalid offset\n", + a_cost); + if (a_x >= 0 && a_x > G->a_size - (int)sizeof(double)) + xerror("glp_mincost_relax4: a_x = %d; invalid offset\n", + a_x); + if (a_rc >= 0 && a_rc > G->a_size - (int)sizeof(double)) + xerror("glp_mincost_relax4: a_rc = %d; invalid offset\n", + a_rc); + csa.n = n = G->nv; /* number of nodes */ + csa.na = na = G->na; /* number of arcs */ + csa.large = large = INT_MAX / 4; + csa.repeat = 0; + csa.crash = crash; + /* allocate working arrays */ + csa.startn = xcalloc(1+na, sizeof(int)); + csa.endn = xcalloc(1+na, sizeof(int)); + csa.fou = xcalloc(1+n, sizeof(int)); + csa.nxtou = xcalloc(1+na, sizeof(int)); + csa.fin = xcalloc(1+n, sizeof(int)); + csa.nxtin = xcalloc(1+na, sizeof(int)); + csa.rc = xcalloc(1+na, sizeof(int)); + csa.u = xcalloc(1+na, sizeof(int)); + csa.dfct = xcalloc(1+n, sizeof(int)); + csa.x = xcalloc(1+na, sizeof(int)); + csa.label = xcalloc(1+n, sizeof(int)); + csa.prdcsr = xcalloc(1+n, sizeof(int)); + csa.save = xcalloc(1+na, sizeof(int)); + csa.tfstou = xcalloc(1+n, sizeof(int)); + csa.tnxtou = xcalloc(1+na, sizeof(int)); + csa.tfstin = xcalloc(1+n, sizeof(int)); + csa.tnxtin = xcalloc(1+na, sizeof(int)); + csa.nxtqueue = xcalloc(1+n, sizeof(int)); + csa.scan = xcalloc(1+n, sizeof(char)); + csa.mark = xcalloc(1+n, sizeof(char)); + if (crash) + { csa.extend_arc = xcalloc(1+n, sizeof(int)); + csa.sb_level = xcalloc(1+n, sizeof(int)); + csa.sb_arc = xcalloc(1+n, sizeof(int)); + } + else + { csa.extend_arc = NULL; + csa.sb_level = NULL; + csa.sb_arc = NULL; + } + /* scan nodes */ + for (i = 1; i <= n; i++) + { v = G->v[i]; + /* get supply at i-th node */ + if (v_rhs >= 0) + memcpy(&rhs, (char *)v->data + v_rhs, sizeof(double)); + else + rhs = 0.0; + if (!(fabs(rhs) <= (double)large && rhs == floor(rhs))) + { ret = GLP_EDATA; + goto done; + } + /* set demand at i-th node */ + csa.dfct[i] = -(int)rhs; + } + /* scan arcs */ + k = 0; + for (i = 1; i <= n; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { k++; + /* set endpoints of k-th arc */ + if (a->tail->i == a->head->i) + { /* self-loops not allowed */ + ret = GLP_EDATA; + goto done; + } + csa.startn[k] = a->tail->i; + csa.endn[k] = a->head->i; + /* set per-unit cost for k-th arc flow */ + if (a_cost >= 0) + memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); + else + cost = 0.0; + if (!(fabs(cost) <= (double)large && cost == floor(cost))) + { ret = GLP_EDATA; + goto done; + } + csa.rc[k] = (int)cost; + /* get lower bound for k-th arc flow */ + if (a_low >= 0) + memcpy(&low, (char *)a->data + a_low, sizeof(double)); + else + low = 0.0; + if (!(0.0 <= low && low <= (double)large && + low == floor(low))) + { ret = GLP_EDATA; + goto done; + } + /* get upper bound for k-th arc flow */ + if (a_cap >= 0) + memcpy(&cap, (char *)a->data + a_cap, sizeof(double)); + else + cap = 1.0; + if (!(low <= cap && cap <= (double)large && + cap == floor(cap))) + { ret = GLP_EDATA; + goto done; + } + /* substitute x = x' + low, where 0 <= x' <= cap - low */ + csa.u[k] = (int)(cap - low); + /* correct demands at endpoints of k-th arc */ + if (overflow(csa.dfct[a->tail->i], +low)) + { ret = GLP_ERANGE; + goto done; + } + csa.dfct[a->tail->i] += low; + if (overflow(csa.dfct[a->head->i], -low)) + { ret = GLP_ERANGE; + goto done; + } + csa.dfct[a->head->i] -= low; + } + } + /* construct linked list for network topology */ + relax4_inidat(&csa); + /* find minimum-cost flow */ + ret = relax4(&csa); + if (ret != 0) + { /* problem is found to be infeasible */ + xassert(1 <= ret && ret <= 8); + ret = GLP_ENOPFS; + goto done; + } + /* store solution */ + sum = 0.0; + k = 0; + for (i = 1; i <= n; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { k++; + /* get lower bound for k-th arc flow */ + if (a_low >= 0) + memcpy(&low, (char *)a->data + a_low, sizeof(double)); + else + low = 0.0; + /* store original flow x = x' + low thru k-th arc */ + x = (double)csa.x[k] + low; + if (a_x >= 0) + memcpy((char *)a->data + a_x, &x, sizeof(double)); + /* store reduced cost for k-th arc flow */ + rc = (double)csa.rc[k]; + if (a_rc >= 0) + memcpy((char *)a->data + a_rc, &rc, sizeof(double)); + /* get per-unit cost for k-th arc flow */ + if (a_cost >= 0) + memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); + else + cost = 0.0; + /* compute the total cost */ + sum += cost * x; + } + } + /* store the total cost */ + if (sol != NULL) + *sol = sum; +done: /* free working arrays */ + xfree(csa.startn); + xfree(csa.endn); + xfree(csa.fou); + xfree(csa.nxtou); + xfree(csa.fin); + xfree(csa.nxtin); + xfree(csa.rc); + xfree(csa.u); + xfree(csa.dfct); + xfree(csa.x); + xfree(csa.label); + xfree(csa.prdcsr); + xfree(csa.save); + xfree(csa.tfstou); + xfree(csa.tnxtou); + xfree(csa.tfstin); + xfree(csa.tnxtin); + xfree(csa.nxtqueue); + xfree(csa.scan); + xfree(csa.mark); + if (crash) + { xfree(csa.extend_arc); + xfree(csa.sb_level); + xfree(csa.sb_arc); + } + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_maxflow_lp - convert maximum flow problem to LP +* +* SYNOPSIS +* +* void glp_maxflow_lp(glp_prob *lp, glp_graph *G, int names, int s, +* int t, int a_cap); +* +* DESCRIPTION +* +* The routine glp_maxflow_lp builds an LP problem, which corresponds +* to the maximum flow problem on the specified network G. */ + +void glp_maxflow_lp(glp_prob *lp, glp_graph *G, int names, int s, + int t, int a_cap) +{ glp_vertex *v; + glp_arc *a; + int i, j, type, ind[1+2]; + double cap, val[1+2]; + if (!(names == GLP_ON || names == GLP_OFF)) + xerror("glp_maxflow_lp: names = %d; invalid parameter\n", + names); + if (!(1 <= s && s <= G->nv)) + xerror("glp_maxflow_lp: s = %d; source node number out of rang" + "e\n", s); + if (!(1 <= t && t <= G->nv)) + xerror("glp_maxflow_lp: t = %d: sink node number out of range " + "\n", t); + if (s == t) + xerror("glp_maxflow_lp: s = t = %d; source and sink nodes must" + " be distinct\n", s); + if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) + xerror("glp_maxflow_lp: a_cap = %d; invalid offset\n", a_cap); + glp_erase_prob(lp); + if (names) glp_set_prob_name(lp, G->name); + glp_set_obj_dir(lp, GLP_MAX); + glp_add_rows(lp, G->nv); + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + if (names) glp_set_row_name(lp, i, v->name); + if (i == s) + type = GLP_LO; + else if (i == t) + type = GLP_UP; + else + type = GLP_FX; + glp_set_row_bnds(lp, i, type, 0.0, 0.0); + } + if (G->na > 0) glp_add_cols(lp, G->na); + for (i = 1, j = 0; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { j++; + if (names) + { char name[50+1]; + sprintf(name, "x[%d,%d]", a->tail->i, a->head->i); + xassert(strlen(name) < sizeof(name)); + glp_set_col_name(lp, j, name); + } + if (a->tail->i != a->head->i) + { ind[1] = a->tail->i, val[1] = +1.0; + ind[2] = a->head->i, val[2] = -1.0; + glp_set_mat_col(lp, j, 2, ind, val); + } + if (a_cap >= 0) + memcpy(&cap, (char *)a->data + a_cap, sizeof(double)); + else + cap = 1.0; + if (cap == DBL_MAX) + type = GLP_LO; + else if (cap != 0.0) + type = GLP_DB; + else + type = GLP_FX; + glp_set_col_bnds(lp, j, type, 0.0, cap); + if (a->tail->i == s) + glp_set_obj_coef(lp, j, +1.0); + else if (a->head->i == s) + glp_set_obj_coef(lp, j, -1.0); + } + } + xassert(j == G->na); + return; +} + +int glp_maxflow_ffalg(glp_graph *G, int s, int t, int a_cap, + double *sol, int a_x, int v_cut) +{ /* find maximal flow with Ford-Fulkerson algorithm */ + glp_vertex *v; + glp_arc *a; + int nv, na, i, k, flag, *tail, *head, *cap, *x, ret; + char *cut; + double temp; + if (!(1 <= s && s <= G->nv)) + xerror("glp_maxflow_ffalg: s = %d; source node number out of r" + "ange\n", s); + if (!(1 <= t && t <= G->nv)) + xerror("glp_maxflow_ffalg: t = %d: sink node number out of ran" + "ge\n", t); + if (s == t) + xerror("glp_maxflow_ffalg: s = t = %d; source and sink nodes m" + "ust be distinct\n", s); + if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) + xerror("glp_maxflow_ffalg: a_cap = %d; invalid offset\n", + a_cap); + if (v_cut >= 0 && v_cut > G->v_size - (int)sizeof(int)) + xerror("glp_maxflow_ffalg: v_cut = %d; invalid offset\n", + v_cut); + /* allocate working arrays */ + nv = G->nv; + na = G->na; + tail = xcalloc(1+na, sizeof(int)); + head = xcalloc(1+na, sizeof(int)); + cap = xcalloc(1+na, sizeof(int)); + x = xcalloc(1+na, sizeof(int)); + if (v_cut < 0) + cut = NULL; + else + cut = xcalloc(1+nv, sizeof(char)); + /* copy the flow network */ + k = 0; + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { k++; + tail[k] = a->tail->i; + head[k] = a->head->i; + if (tail[k] == head[k]) + { ret = GLP_EDATA; + goto done; + } + if (a_cap >= 0) + memcpy(&temp, (char *)a->data + a_cap, sizeof(double)); + else + temp = 1.0; + if (!(0.0 <= temp && temp <= (double)INT_MAX && + temp == floor(temp))) + { ret = GLP_EDATA; + goto done; + } + cap[k] = (int)temp; + } + } + xassert(k == na); + /* find maximal flow in the flow network */ + ffalg(nv, na, tail, head, s, t, cap, x, cut); + ret = 0; + /* store solution components */ + /* (objective function = total flow through the network) */ + if (sol != NULL) + { temp = 0.0; + for (k = 1; k <= na; k++) + { if (tail[k] == s) + temp += (double)x[k]; + else if (head[k] == s) + temp -= (double)x[k]; + } + *sol = temp; + } + /* (arc flows) */ + if (a_x >= 0) + { k = 0; + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { temp = (double)x[++k]; + memcpy((char *)a->data + a_x, &temp, sizeof(double)); + } + } + } + /* (node flags) */ + if (v_cut >= 0) + { for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + flag = cut[i]; + memcpy((char *)v->data + v_cut, &flag, sizeof(int)); + } + } +done: /* free working arrays */ + xfree(tail); + xfree(head); + xfree(cap); + xfree(x); + if (cut != NULL) xfree(cut); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_check_asnprob - check correctness of assignment problem data +* +* SYNOPSIS +* +* int glp_check_asnprob(glp_graph *G, int v_set); +* +* RETURNS +* +* If the specified assignment problem data are correct, the routine +* glp_check_asnprob returns zero, otherwise, non-zero. */ + +int glp_check_asnprob(glp_graph *G, int v_set) +{ glp_vertex *v; + int i, k, ret = 0; + if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) + xerror("glp_check_asnprob: v_set = %d; invalid offset\n", + v_set); + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + if (v_set >= 0) + { memcpy(&k, (char *)v->data + v_set, sizeof(int)); + if (k == 0) + { if (v->in != NULL) + { ret = 1; + break; + } + } + else if (k == 1) + { if (v->out != NULL) + { ret = 2; + break; + } + } + else + { ret = 3; + break; + } + } + else + { if (v->in != NULL && v->out != NULL) + { ret = 4; + break; + } + } + } + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_asnprob_lp - convert assignment problem to LP +* +* SYNOPSIS +* +* int glp_asnprob_lp(glp_prob *P, int form, glp_graph *G, int names, +* int v_set, int a_cost); +* +* DESCRIPTION +* +* The routine glp_asnprob_lp builds an LP problem, which corresponds +* to the assignment problem on the specified graph G. +* +* RETURNS +* +* If the LP problem has been successfully built, the routine returns +* zero, otherwise, non-zero. */ + +int glp_asnprob_lp(glp_prob *P, int form, glp_graph *G, int names, + int v_set, int a_cost) +{ glp_vertex *v; + glp_arc *a; + int i, j, ret, ind[1+2]; + double cost, val[1+2]; + if (!(form == GLP_ASN_MIN || form == GLP_ASN_MAX || + form == GLP_ASN_MMP)) + xerror("glp_asnprob_lp: form = %d; invalid parameter\n", + form); + if (!(names == GLP_ON || names == GLP_OFF)) + xerror("glp_asnprob_lp: names = %d; invalid parameter\n", + names); + if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) + xerror("glp_asnprob_lp: v_set = %d; invalid offset\n", + v_set); + if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) + xerror("glp_asnprob_lp: a_cost = %d; invalid offset\n", + a_cost); + ret = glp_check_asnprob(G, v_set); + if (ret != 0) goto done; + glp_erase_prob(P); + if (names) glp_set_prob_name(P, G->name); + glp_set_obj_dir(P, form == GLP_ASN_MIN ? GLP_MIN : GLP_MAX); + if (G->nv > 0) glp_add_rows(P, G->nv); + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + if (names) glp_set_row_name(P, i, v->name); + glp_set_row_bnds(P, i, form == GLP_ASN_MMP ? GLP_UP : GLP_FX, + 1.0, 1.0); + } + if (G->na > 0) glp_add_cols(P, G->na); + for (i = 1, j = 0; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { j++; + if (names) + { char name[50+1]; + sprintf(name, "x[%d,%d]", a->tail->i, a->head->i); + xassert(strlen(name) < sizeof(name)); + glp_set_col_name(P, j, name); + } + ind[1] = a->tail->i, val[1] = +1.0; + ind[2] = a->head->i, val[2] = +1.0; + glp_set_mat_col(P, j, 2, ind, val); + glp_set_col_bnds(P, j, GLP_DB, 0.0, 1.0); + if (a_cost >= 0) + memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); + else + cost = 1.0; + glp_set_obj_coef(P, j, cost); + } + } + xassert(j == G->na); +done: return ret; +} + +/**********************************************************************/ + +int glp_asnprob_okalg(int form, glp_graph *G, int v_set, int a_cost, + double *sol, int a_x) +{ /* solve assignment problem with out-of-kilter algorithm */ + glp_vertex *v; + glp_arc *a; + int nv, na, i, k, *tail, *head, *low, *cap, *cost, *x, *pi, ret; + double temp; + if (!(form == GLP_ASN_MIN || form == GLP_ASN_MAX || + form == GLP_ASN_MMP)) + xerror("glp_asnprob_okalg: form = %d; invalid parameter\n", + form); + if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) + xerror("glp_asnprob_okalg: v_set = %d; invalid offset\n", + v_set); + if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) + xerror("glp_asnprob_okalg: a_cost = %d; invalid offset\n", + a_cost); + if (a_x >= 0 && a_x > G->a_size - (int)sizeof(int)) + xerror("glp_asnprob_okalg: a_x = %d; invalid offset\n", a_x); + if (glp_check_asnprob(G, v_set)) + return GLP_EDATA; + /* nv is the total number of nodes in the resulting network */ + nv = G->nv + 1; + /* na is the total number of arcs in the resulting network */ + na = G->na + G->nv; + /* allocate working arrays */ + tail = xcalloc(1+na, sizeof(int)); + head = xcalloc(1+na, sizeof(int)); + low = xcalloc(1+na, sizeof(int)); + cap = xcalloc(1+na, sizeof(int)); + cost = xcalloc(1+na, sizeof(int)); + x = xcalloc(1+na, sizeof(int)); + pi = xcalloc(1+nv, sizeof(int)); + /* construct the resulting network */ + k = 0; + /* (original arcs) */ + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { k++; + tail[k] = a->tail->i; + head[k] = a->head->i; + low[k] = 0; + cap[k] = 1; + if (a_cost >= 0) + memcpy(&temp, (char *)a->data + a_cost, sizeof(double)); + else + temp = 1.0; + if (!(fabs(temp) <= (double)INT_MAX && temp == floor(temp))) + { ret = GLP_EDATA; + goto done; + } + cost[k] = (int)temp; + if (form != GLP_ASN_MIN) cost[k] = - cost[k]; + } + } + /* (artificial arcs) */ + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + k++; + if (v->out == NULL) + tail[k] = i, head[k] = nv; + else if (v->in == NULL) + tail[k] = nv, head[k] = i; + else + xassert(v != v); + low[k] = (form == GLP_ASN_MMP ? 0 : 1); + cap[k] = 1; + cost[k] = 0; + } + xassert(k == na); + /* find minimal-cost circulation in the resulting network */ + ret = okalg(nv, na, tail, head, low, cap, cost, x, pi); + switch (ret) + { case 0: + /* optimal circulation found */ + ret = 0; + break; + case 1: + /* no feasible circulation exists */ + ret = GLP_ENOPFS; + break; + case 2: + /* integer overflow occured */ + ret = GLP_ERANGE; + goto done; + case 3: + /* optimality test failed (logic error) */ + ret = GLP_EFAIL; + goto done; + default: + xassert(ret != ret); + } + /* store solution components */ + /* (objective function = the total cost) */ + if (sol != NULL) + { temp = 0.0; + for (k = 1; k <= na; k++) + temp += (double)cost[k] * (double)x[k]; + if (form != GLP_ASN_MIN) temp = - temp; + *sol = temp; + } + /* (arc flows) */ + if (a_x >= 0) + { k = 0; + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { k++; + if (ret == 0) + xassert(x[k] == 0 || x[k] == 1); + memcpy((char *)a->data + a_x, &x[k], sizeof(int)); + } + } + } +done: /* free working arrays */ + xfree(tail); + xfree(head); + xfree(low); + xfree(cap); + xfree(cost); + xfree(x); + xfree(pi); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_asnprob_hall - find bipartite matching of maximum cardinality +* +* SYNOPSIS +* +* int glp_asnprob_hall(glp_graph *G, int v_set, int a_x); +* +* DESCRIPTION +* +* The routine glp_asnprob_hall finds a matching of maximal cardinality +* in the specified bipartite graph G. It uses a version of the Fortran +* routine MC21A developed by I.S.Duff [1], which implements Hall's +* algorithm [2]. +* +* RETURNS +* +* The routine glp_asnprob_hall returns the cardinality of the matching +* found. However, if the specified graph is incorrect (as detected by +* the routine glp_check_asnprob), the routine returns negative value. +* +* REFERENCES +* +* 1. I.S.Duff, Algorithm 575: Permutations for zero-free diagonal, ACM +* Trans. on Math. Softw. 7 (1981), 387-390. +* +* 2. M.Hall, "An Algorithm for distinct representatives," Amer. Math. +* Monthly 63 (1956), 716-717. */ + +int glp_asnprob_hall(glp_graph *G, int v_set, int a_x) +{ glp_vertex *v; + glp_arc *a; + int card, i, k, loc, n, n1, n2, xij; + int *num, *icn, *ip, *lenr, *iperm, *pr, *arp, *cv, *out; + if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) + xerror("glp_asnprob_hall: v_set = %d; invalid offset\n", + v_set); + if (a_x >= 0 && a_x > G->a_size - (int)sizeof(int)) + xerror("glp_asnprob_hall: a_x = %d; invalid offset\n", a_x); + if (glp_check_asnprob(G, v_set)) + return -1; + /* determine the number of vertices in sets R and S and renumber + vertices in S which correspond to columns of the matrix; skip + all isolated vertices */ + num = xcalloc(1+G->nv, sizeof(int)); + n1 = n2 = 0; + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + if (v->in == NULL && v->out != NULL) + n1++, num[i] = 0; /* vertex in R */ + else if (v->in != NULL && v->out == NULL) + n2++, num[i] = n2; /* vertex in S */ + else + { xassert(v->in == NULL && v->out == NULL); + num[i] = -1; /* isolated vertex */ + } + } + /* the matrix must be square, thus, if it has more columns than + rows, extra rows will be just empty, and vice versa */ + n = (n1 >= n2 ? n1 : n2); + /* allocate working arrays */ + icn = xcalloc(1+G->na, sizeof(int)); + ip = xcalloc(1+n, sizeof(int)); + lenr = xcalloc(1+n, sizeof(int)); + iperm = xcalloc(1+n, sizeof(int)); + pr = xcalloc(1+n, sizeof(int)); + arp = xcalloc(1+n, sizeof(int)); + cv = xcalloc(1+n, sizeof(int)); + out = xcalloc(1+n, sizeof(int)); + /* build the adjacency matrix of the bipartite graph in row-wise + format (rows are vertices in R, columns are vertices in S) */ + k = 0, loc = 1; + for (i = 1; i <= G->nv; i++) + { if (num[i] != 0) continue; + /* vertex i in R */ + ip[++k] = loc; + v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { xassert(num[a->head->i] != 0); + icn[loc++] = num[a->head->i]; + } + lenr[k] = loc - ip[k]; + } + xassert(loc-1 == G->na); + /* make all extra rows empty (all extra columns are empty due to + the row-wise format used) */ + for (k++; k <= n; k++) + ip[k] = loc, lenr[k] = 0; + /* find a row permutation that maximizes the number of non-zeros + on the main diagonal */ + card = mc21a(n, icn, ip, lenr, iperm, pr, arp, cv, out); +#if 1 /* 18/II-2010 */ + /* FIXED: if card = n, arp remains clobbered on exit */ + for (i = 1; i <= n; i++) + arp[i] = 0; + for (i = 1; i <= card; i++) + { k = iperm[i]; + xassert(1 <= k && k <= n); + xassert(arp[k] == 0); + arp[k] = i; + } +#endif + /* store solution, if necessary */ + if (a_x < 0) goto skip; + k = 0; + for (i = 1; i <= G->nv; i++) + { if (num[i] != 0) continue; + /* vertex i in R */ + k++; + v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { /* arp[k] is the number of matched column or zero */ + if (arp[k] == num[a->head->i]) + { xassert(arp[k] != 0); + xij = 1; + } + else + xij = 0; + memcpy((char *)a->data + a_x, &xij, sizeof(int)); + } + } +skip: /* free working arrays */ + xfree(num); + xfree(icn); + xfree(ip); + xfree(lenr); + xfree(iperm); + xfree(pr); + xfree(arp); + xfree(cv); + xfree(out); + return card; +} + +/*********************************************************************** +* NAME +* +* glp_cpp - solve critical path problem +* +* SYNOPSIS +* +* double glp_cpp(glp_graph *G, int v_t, int v_es, int v_ls); +* +* DESCRIPTION +* +* The routine glp_cpp solves the critical path problem represented in +* the form of the project network. +* +* The parameter G is a pointer to the graph object, which specifies +* the project network. This graph must be acyclic. Multiple arcs are +* allowed being considered as single arcs. +* +* The parameter v_t specifies an offset of the field of type double +* in the vertex data block, which contains time t[i] >= 0 needed to +* perform corresponding job j. If v_t < 0, it is assumed that t[i] = 1 +* for all jobs. +* +* The parameter v_es specifies an offset of the field of type double +* in the vertex data block, to which the routine stores earliest start +* time for corresponding job. If v_es < 0, this time is not stored. +* +* The parameter v_ls specifies an offset of the field of type double +* in the vertex data block, to which the routine stores latest start +* time for corresponding job. If v_ls < 0, this time is not stored. +* +* RETURNS +* +* The routine glp_cpp returns the minimal project duration, that is, +* minimal time needed to perform all jobs in the project. */ + +static void sorting(glp_graph *G, int list[]); + +double glp_cpp(glp_graph *G, int v_t, int v_es, int v_ls) +{ glp_vertex *v; + glp_arc *a; + int i, j, k, nv, *list; + double temp, total, *t, *es, *ls; + if (v_t >= 0 && v_t > G->v_size - (int)sizeof(double)) + xerror("glp_cpp: v_t = %d; invalid offset\n", v_t); + if (v_es >= 0 && v_es > G->v_size - (int)sizeof(double)) + xerror("glp_cpp: v_es = %d; invalid offset\n", v_es); + if (v_ls >= 0 && v_ls > G->v_size - (int)sizeof(double)) + xerror("glp_cpp: v_ls = %d; invalid offset\n", v_ls); + nv = G->nv; + if (nv == 0) + { total = 0.0; + goto done; + } + /* allocate working arrays */ + t = xcalloc(1+nv, sizeof(double)); + es = xcalloc(1+nv, sizeof(double)); + ls = xcalloc(1+nv, sizeof(double)); + list = xcalloc(1+nv, sizeof(int)); + /* retrieve job times */ + for (i = 1; i <= nv; i++) + { v = G->v[i]; + if (v_t >= 0) + { memcpy(&t[i], (char *)v->data + v_t, sizeof(double)); + if (t[i] < 0.0) + xerror("glp_cpp: t[%d] = %g; invalid time\n", i, t[i]); + } + else + t[i] = 1.0; + } + /* perform topological sorting to determine the list of nodes + (jobs) such that if list[k] = i and list[kk] = j and there + exists arc (i->j), then k < kk */ + sorting(G, list); + /* FORWARD PASS */ + /* determine earliest start times */ + for (k = 1; k <= nv; k++) + { j = list[k]; + es[j] = 0.0; + for (a = G->v[j]->in; a != NULL; a = a->h_next) + { i = a->tail->i; + /* there exists arc (i->j) in the project network */ + temp = es[i] + t[i]; + if (es[j] < temp) es[j] = temp; + } + } + /* determine the minimal project duration */ + total = 0.0; + for (i = 1; i <= nv; i++) + { temp = es[i] + t[i]; + if (total < temp) total = temp; + } + /* BACKWARD PASS */ + /* determine latest start times */ + for (k = nv; k >= 1; k--) + { i = list[k]; + ls[i] = total - t[i]; + for (a = G->v[i]->out; a != NULL; a = a->t_next) + { j = a->head->i; + /* there exists arc (i->j) in the project network */ + temp = ls[j] - t[i]; + if (ls[i] > temp) ls[i] = temp; + } + /* avoid possible round-off errors */ + if (ls[i] < es[i]) ls[i] = es[i]; + } + /* store results, if necessary */ + if (v_es >= 0) + { for (i = 1; i <= nv; i++) + { v = G->v[i]; + memcpy((char *)v->data + v_es, &es[i], sizeof(double)); + } + } + if (v_ls >= 0) + { for (i = 1; i <= nv; i++) + { v = G->v[i]; + memcpy((char *)v->data + v_ls, &ls[i], sizeof(double)); + } + } + /* free working arrays */ + xfree(t); + xfree(es); + xfree(ls); + xfree(list); +done: return total; +} + +static void sorting(glp_graph *G, int list[]) +{ /* perform topological sorting to determine the list of nodes + (jobs) such that if list[k] = i and list[kk] = j and there + exists arc (i->j), then k < kk */ + int i, k, nv, v_size, *num; + void **save; + nv = G->nv; + v_size = G->v_size; + save = xcalloc(1+nv, sizeof(void *)); + num = xcalloc(1+nv, sizeof(int)); + G->v_size = sizeof(int); + for (i = 1; i <= nv; i++) + { save[i] = G->v[i]->data; + G->v[i]->data = &num[i]; + list[i] = 0; + } + if (glp_top_sort(G, 0) != 0) + xerror("glp_cpp: project network is not acyclic\n"); + G->v_size = v_size; + for (i = 1; i <= nv; i++) + { G->v[i]->data = save[i]; + k = num[i]; + xassert(1 <= k && k <= nv); + xassert(list[k] == 0); + list[k] = i; + } + xfree(save); + xfree(num); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi18.c b/resources/3rdparty/glpk-4.57/src/glpapi18.c new file mode 100644 index 000000000..07ab490d5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi18.c @@ -0,0 +1,123 @@ +/* glpapi18.c (maximum clique problem) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "prob.h" +#include "wclique.h" + +static void set_edge(int nv, unsigned char a[], int i, int j) +{ int k; + xassert(1 <= j && j < i && i <= nv); + k = ((i - 1) * (i - 2)) / 2 + (j - 1); + a[k / CHAR_BIT] |= + (unsigned char)(1 << ((CHAR_BIT - 1) - k % CHAR_BIT)); + return; +} + +int glp_wclique_exact(glp_graph *G, int v_wgt, double *sol, int v_set) +{ /* find maximum weight clique with exact algorithm */ + glp_arc *e; + int i, j, k, len, x, *w, *ind, ret = 0; + unsigned char *a; + double s, t; + if (v_wgt >= 0 && v_wgt > G->v_size - (int)sizeof(double)) + xerror("glp_wclique_exact: v_wgt = %d; invalid parameter\n", + v_wgt); + if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) + xerror("glp_wclique_exact: v_set = %d; invalid parameter\n", + v_set); + if (G->nv == 0) + { /* empty graph has only empty clique */ + if (sol != NULL) *sol = 0.0; + return 0; + } + /* allocate working arrays */ + w = xcalloc(1+G->nv, sizeof(int)); + ind = xcalloc(1+G->nv, sizeof(int)); + len = G->nv; /* # vertices */ + len = len * (len - 1) / 2; /* # entries in lower triangle */ + len = (len + (CHAR_BIT - 1)) / CHAR_BIT; /* # bytes needed */ + a = xcalloc(len, sizeof(char)); + memset(a, 0, len * sizeof(char)); + /* determine vertex weights */ + s = 0.0; + for (i = 1; i <= G->nv; i++) + { if (v_wgt >= 0) + { memcpy(&t, (char *)G->v[i]->data + v_wgt, sizeof(double)); + if (!(0.0 <= t && t <= (double)INT_MAX && t == floor(t))) + { ret = GLP_EDATA; + goto done; + } + w[i] = (int)t; + } + else + w[i] = 1; + s += (double)w[i]; + } + if (s > (double)INT_MAX) + { ret = GLP_EDATA; + goto done; + } + /* build the adjacency matrix */ + for (i = 1; i <= G->nv; i++) + { for (e = G->v[i]->in; e != NULL; e = e->h_next) + { j = e->tail->i; + /* there exists edge (j,i) in the graph */ + if (i > j) set_edge(G->nv, a, i, j); + } + for (e = G->v[i]->out; e != NULL; e = e->t_next) + { j = e->head->i; + /* there exists edge (i,j) in the graph */ + if (i > j) set_edge(G->nv, a, i, j); + } + } + /* find maximum weight clique in the graph */ + len = wclique(G->nv, w, a, ind); + /* compute the clique weight */ + s = 0.0; + for (k = 1; k <= len; k++) + { i = ind[k]; + xassert(1 <= i && i <= G->nv); + s += (double)w[i]; + } + if (sol != NULL) *sol = s; + /* mark vertices included in the clique */ + if (v_set >= 0) + { x = 0; + for (i = 1; i <= G->nv; i++) + memcpy((char *)G->v[i]->data + v_set, &x, sizeof(int)); + x = 1; + for (k = 1; k <= len; k++) + { i = ind[k]; + memcpy((char *)G->v[i]->data + v_set, &x, sizeof(int)); + } + } +done: /* free working arrays */ + xfree(w); + xfree(ind); + xfree(a); + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi19.c b/resources/3rdparty/glpk-4.57/src/glpapi19.c new file mode 100644 index 000000000..eda96a946 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi19.c @@ -0,0 +1,141 @@ +/* glpapi19.c (driver to MiniSat solver) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "minisat.h" +#include "prob.h" + +int glp_minisat1(glp_prob *P) +{ /* solve CNF-SAT problem with MiniSat solver */ + solver *s; + GLPAIJ *aij; + int i, j, len, ret, *ind; + double sum; + /* check problem object */ + if (P == NULL || P->magic != GLP_PROB_MAGIC) + xerror("glp_minisat1: P = %p; invalid problem object\n", + P); + if (P->tree != NULL) + xerror("glp_minisat1: operation not allowed\n"); + /* integer solution is currently undefined */ + P->mip_stat = GLP_UNDEF; + P->mip_obj = 0.0; + /* check that problem object encodes CNF-SAT instance */ + if (glp_check_cnfsat(P) != 0) + { xprintf("glp_minisat1: problem object does not encode CNF-SAT " + "instance\n"); + ret = GLP_EDATA; + goto done; + } +#if 1 /* 07/XI-2015 */ + if (sizeof(void *) != sizeof(int)) + { xprintf("glp_minisat1: sorry, MiniSat solver is not supported " + "on 64-bit platforms\n"); + ret = GLP_EFAIL; + goto done; + } +#endif + /* solve CNF-SAT problem */ + xprintf("Solving CNF-SAT problem...\n"); + xprintf("Instance has %d variable%s, %d clause%s, and %d literal%" + "s\n", P->n, P->n == 1 ? "" : "s", P->m, P->m == 1 ? "" : "s", + P->nnz, P->nnz == 1 ? "" : "s"); + /* if CNF-SAT has no clauses, it is satisfiable */ + if (P->m == 0) + { P->mip_stat = GLP_OPT; + for (j = 1; j <= P->n; j++) + P->col[j]->mipx = 0.0; + goto fini; + } + /* if CNF-SAT has an empty clause, it is unsatisfiable */ + for (i = 1; i <= P->m; i++) + { if (P->row[i]->ptr == NULL) + { P->mip_stat = GLP_NOFEAS; + goto fini; + } + } + /* prepare input data for the solver */ + s = solver_new(); + solver_setnvars(s, P->n); + ind = xcalloc(1+P->n, sizeof(int)); + for (i = 1; i <= P->m; i++) + { len = 0; + for (aij = P->row[i]->ptr; aij != NULL; aij = aij->r_next) + { ind[++len] = toLit(aij->col->j-1); + if (aij->val < 0.0) + ind[len] = lit_neg(ind[len]); + } + xassert(len > 0); + xassert(solver_addclause(s, &ind[1], &ind[1+len])); + } + xfree(ind); + /* call the solver */ + s->verbosity = 1; + if (solver_solve(s, 0, 0)) + { /* instance is reported as satisfiable */ + P->mip_stat = GLP_OPT; + /* copy solution to the problem object */ + xassert(s->model.size == P->n); + for (j = 1; j <= P->n; j++) + { P->col[j]->mipx = + s->model.ptr[j-1] == l_True ? 1.0 : 0.0; + } + /* compute row values */ + for (i = 1; i <= P->m; i++) + { sum = 0; + for (aij = P->row[i]->ptr; aij != NULL; aij = aij->r_next) + sum += aij->val * aij->col->mipx; + P->row[i]->mipx = sum; + } + /* check integer feasibility */ + for (i = 1; i <= P->m; i++) + { if (P->row[i]->mipx < P->row[i]->lb) + { /* solution is wrong */ + P->mip_stat = GLP_UNDEF; + break; + } + } + } + else + { /* instance is reported as unsatisfiable */ + P->mip_stat = GLP_NOFEAS; + } + solver_delete(s); +fini: /* report the instance status */ + if (P->mip_stat == GLP_OPT) + { xprintf("SATISFIABLE\n"); + ret = 0; + } + else if (P->mip_stat == GLP_NOFEAS) + { xprintf("UNSATISFIABLE\n"); + ret = 0; + } + else + { xprintf("glp_minisat1: solver failed\n"); + ret = GLP_EFAIL; + } +done: return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi20.c b/resources/3rdparty/glpk-4.57/src/glpapi20.c new file mode 100644 index 000000000..2a2f6f988 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi20.c @@ -0,0 +1,257 @@ +/* glpapi20.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpnpp.h" + +int glp_intfeas1(glp_prob *P, int use_bound, int obj_bound) +{ /* solve integer feasibility problem */ + NPP *npp = NULL; + glp_prob *mip = NULL; + int *obj_ind = NULL; + double *obj_val = NULL; + int obj_row = 0; + int i, j, k, obj_len, temp, ret; + /* check the problem object */ + if (P == NULL || P->magic != GLP_PROB_MAGIC) + xerror("glp_intfeas1: P = %p; invalid problem object\n", + P); + if (P->tree != NULL) + xerror("glp_intfeas1: operation not allowed\n"); + /* integer solution is currently undefined */ + P->mip_stat = GLP_UNDEF; + P->mip_obj = 0.0; + /* check columns (variables) */ + for (j = 1; j <= P->n; j++) + { GLPCOL *col = P->col[j]; +#if 0 /* currently binarization is not yet implemented */ + if (!(col->kind == GLP_IV || col->type == GLP_FX)) + { xprintf("glp_intfeas1: column %d: non-integer non-fixed var" + "iable not allowed\n", j); +#else + if (!((col->kind == GLP_IV && col->lb == 0.0 && col->ub == 1.0) + || col->type == GLP_FX)) + { xprintf("glp_intfeas1: column %d: non-binary non-fixed vari" + "able not allowed\n", j); +#endif + ret = GLP_EDATA; + goto done; + } + temp = (int)col->lb; + if ((double)temp != col->lb) + { if (col->type == GLP_FX) + xprintf("glp_intfeas1: column %d: fixed value %g is non-" + "integer or out of range\n", j, col->lb); + else + xprintf("glp_intfeas1: column %d: lower bound %g is non-" + "integer or out of range\n", j, col->lb); + ret = GLP_EDATA; + goto done; + } + temp = (int)col->ub; + if ((double)temp != col->ub) + { xprintf("glp_intfeas1: column %d: upper bound %g is non-int" + "eger or out of range\n", j, col->ub); + ret = GLP_EDATA; + goto done; + } + if (col->type == GLP_DB && col->lb > col->ub) + { xprintf("glp_intfeas1: column %d: lower bound %g is greater" + " than upper bound %g\n", j, col->lb, col->ub); + ret = GLP_EBOUND; + goto done; + } + } + /* check rows (constraints) */ + for (i = 1; i <= P->m; i++) + { GLPROW *row = P->row[i]; + GLPAIJ *aij; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { temp = (int)aij->val; + if ((double)temp != aij->val) + { xprintf("glp_intfeas1: row = %d, column %d: constraint c" + "oefficient %g is non-integer or out of range\n", + i, aij->col->j, aij->val); + ret = GLP_EDATA; + goto done; + } + } + temp = (int)row->lb; + if ((double)temp != row->lb) + { if (row->type == GLP_FX) + xprintf("glp_intfeas1: row = %d: fixed value %g is non-i" + "nteger or out of range\n", i, row->lb); + else + xprintf("glp_intfeas1: row = %d: lower bound %g is non-i" + "nteger or out of range\n", i, row->lb); + ret = GLP_EDATA; + goto done; + } + temp = (int)row->ub; + if ((double)temp != row->ub) + { xprintf("glp_intfeas1: row = %d: upper bound %g is non-inte" + "ger or out of range\n", i, row->ub); + ret = GLP_EDATA; + goto done; + } + if (row->type == GLP_DB && row->lb > row->ub) + { xprintf("glp_intfeas1: row %d: lower bound %g is greater th" + "an upper bound %g\n", i, row->lb, row->ub); + ret = GLP_EBOUND; + goto done; + } + } + /* check the objective function */ + temp = (int)P->c0; + if ((double)temp != P->c0) + { xprintf("glp_intfeas1: objective constant term %g is non-integ" + "er or out of range\n", P->c0); + ret = GLP_EDATA; + goto done; + } + for (j = 1; j <= P->n; j++) + { temp = (int)P->col[j]->coef; + if ((double)temp != P->col[j]->coef) + { xprintf("glp_intfeas1: column %d: objective coefficient is " + "non-integer or out of range\n", j, P->col[j]->coef); + ret = GLP_EDATA; + goto done; + } + } + /* save the objective function and set it to zero */ + obj_ind = xcalloc(1+P->n, sizeof(int)); + obj_val = xcalloc(1+P->n, sizeof(double)); + obj_len = 0; + obj_ind[0] = 0; + obj_val[0] = P->c0; + P->c0 = 0.0; + for (j = 1; j <= P->n; j++) + { if (P->col[j]->coef != 0.0) + { obj_len++; + obj_ind[obj_len] = j; + obj_val[obj_len] = P->col[j]->coef; + P->col[j]->coef = 0.0; + } + } + /* add inequality to bound the objective function, if required */ + if (!use_bound) + xprintf("Will search for ANY feasible solution\n"); + else + { xprintf("Will search only for solution not worse than %d\n", + obj_bound); + obj_row = glp_add_rows(P, 1); + glp_set_mat_row(P, obj_row, obj_len, obj_ind, obj_val); + if (P->dir == GLP_MIN) + glp_set_row_bnds(P, obj_row, + GLP_UP, 0.0, (double)obj_bound - obj_val[0]); + else if (P->dir == GLP_MAX) + glp_set_row_bnds(P, obj_row, + GLP_LO, (double)obj_bound - obj_val[0], 0.0); + else + xassert(P != P); + } + /* create preprocessor workspace */ + xprintf("Translating to CNF-SAT...\n"); + xprintf("Original problem has %d row%s, %d column%s, and %d non-z" + "ero%s\n", P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : + "s", P->nnz, P->nnz == 1 ? "" : "s"); + npp = npp_create_wksp(); + /* load the original problem into the preprocessor workspace */ + npp_load_prob(npp, P, GLP_OFF, GLP_MIP, GLP_OFF); + /* perform translation to SAT-CNF problem instance */ + ret = npp_sat_encode_prob(npp); + if (ret == 0) + ; + else if (ret == GLP_ENOPFS) + xprintf("PROBLEM HAS NO INTEGER FEASIBLE SOLUTION\n"); + else if (ret == GLP_ERANGE) + xprintf("glp_intfeas1: translation to SAT-CNF failed because o" + "f integer overflow\n"); + else + xassert(ret != ret); + if (ret != 0) + goto done; + /* build SAT-CNF problem instance and try to solve it */ + mip = glp_create_prob(); + npp_build_prob(npp, mip); + ret = glp_minisat1(mip); + /* only integer feasible solution can be postprocessed */ + if (!(mip->mip_stat == GLP_OPT || mip->mip_stat == GLP_FEAS)) + { P->mip_stat = mip->mip_stat; + goto done; + } + /* postprocess the solution found */ + npp_postprocess(npp, mip); + /* the transformed problem is no longer needed */ + glp_delete_prob(mip), mip = NULL; + /* store solution to the original problem object */ + npp_unload_sol(npp, P); + /* change the solution status to 'integer feasible' */ + P->mip_stat = GLP_FEAS; + /* check integer feasibility */ + for (i = 1; i <= P->m; i++) + { GLPROW *row; + GLPAIJ *aij; + double sum; + row = P->row[i]; + sum = 0.0; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + sum += aij->val * aij->col->mipx; + xassert(sum == row->mipx); + if (row->type == GLP_LO || row->type == GLP_DB || + row->type == GLP_FX) + xassert(sum >= row->lb); + if (row->type == GLP_UP || row->type == GLP_DB || + row->type == GLP_FX) + xassert(sum <= row->ub); + } + /* compute value of the original objective function */ + P->mip_obj = obj_val[0]; + for (k = 1; k <= obj_len; k++) + P->mip_obj += obj_val[k] * P->col[obj_ind[k]]->mipx; + xprintf("Objective value = %17.9e\n", P->mip_obj); +done: /* delete the transformed problem, if it exists */ + if (mip != NULL) + glp_delete_prob(mip); + /* delete the preprocessor workspace, if it exists */ + if (npp != NULL) + npp_delete_wksp(npp); + /* remove inequality used to bound the objective function */ + if (obj_row > 0) + { int ind[1+1]; + ind[1] = obj_row; + glp_del_rows(P, 1, ind); + } + /* restore the original objective function */ + if (obj_ind != NULL) + { P->c0 = obj_val[0]; + for (k = 1; k <= obj_len; k++) + P->col[obj_ind[k]]->coef = obj_val[k]; + xfree(obj_ind); + xfree(obj_val); + } + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpapi21.c b/resources/3rdparty/glpk-4.57/src/glpapi21.c new file mode 100644 index 000000000..30866310a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpapi21.c @@ -0,0 +1,1462 @@ +/* glpapi21.c (stand-alone LP/MIP solver) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "draft.h" +#include "env.h" +#include "glpgmp.h" +#include "misc.h" +#include "prob.h" + +struct csa +{ /* common storage area */ + glp_prob *prob; + /* LP/MIP problem object */ + glp_bfcp bfcp; + /* basis factorization control parameters */ + glp_smcp smcp; + /* simplex method control parameters */ + glp_iptcp iptcp; + /* interior-point method control parameters */ + glp_iocp iocp; + /* integer optimizer control parameters */ + glp_tran *tran; + /* model translator workspace */ + glp_graph *graph; + /* network problem object */ + int format; + /* problem file format: */ +#define FMT_MPS_DECK 1 /* fixed MPS */ +#define FMT_MPS_FILE 2 /* free MPS */ +#define FMT_LP 3 /* CPLEX LP */ +#define FMT_GLP 4 /* GLPK LP/MIP */ +#define FMT_MATHPROG 5 /* MathProg */ +#define FMT_MIN_COST 6 /* DIMACS min-cost flow */ +#define FMT_MAX_FLOW 7 /* DIMACS maximum flow */ +#if 1 /* 06/VIII-2011 */ +#define FMT_CNF 8 /* DIMACS CNF-SAT */ +#endif + const char *in_file; + /* name of input problem file */ +#define DATA_MAX 10 + /* maximal number of input data files */ + int ndf; + /* number of input data files specified */ + const char *in_data[1+DATA_MAX]; + /* name(s) of input data file(s) */ + const char *out_dpy; + /* name of output file to send display output; NULL means the + display output is sent to the terminal */ + int seed; + /* seed value to be passed to the MathProg translator; initially + set to 1; 0x80000000 means the value is omitted */ + int solution; + /* solution type flag: */ +#define SOL_BASIC 1 /* basic */ +#define SOL_INTERIOR 2 /* interior-point */ +#define SOL_INTEGER 3 /* mixed integer */ + const char *in_res; + /* name of input solution file in raw format */ + int dir; + /* optimization direction flag: + 0 - not specified + GLP_MIN - minimization + GLP_MAX - maximization */ + int scale; + /* automatic problem scaling flag */ + const char *out_sol; + /* name of output solution file in printable format */ + const char *out_res; + /* name of output solution file in raw format */ + const char *out_ranges; + /* name of output file to write sensitivity analysis report */ + int check; + /* input data checking flag; no solution is performed */ + const char *new_name; + /* new name to be assigned to the problem */ + const char *out_mps; + /* name of output problem file in fixed MPS format */ + const char *out_freemps; + /* name of output problem file in free MPS format */ + const char *out_cpxlp; + /* name of output problem file in CPLEX LP format */ + const char *out_glp; + /* name of output problem file in GLPK format */ +#if 0 + const char *out_pb; + /* name of output problem file in OPB format */ + const char *out_npb; + /* name of output problem file in normalized OPB format */ +#endif +#if 1 /* 06/VIII-2011 */ + const char *out_cnf; + /* name of output problem file in DIMACS CNF-SAT format */ +#endif + const char *log_file; + /* name of output file to hardcopy terminal output */ + int crash; + /* initial basis option: */ +#define USE_STD_BASIS 1 /* use standard basis */ +#define USE_ADV_BASIS 2 /* use advanced basis */ +#define USE_CPX_BASIS 3 /* use Bixby's basis */ +#define USE_INI_BASIS 4 /* use initial basis from ini_file */ + const char *ini_file; + /* name of input file containing initial basis */ + int exact; + /* flag to use glp_exact rather than glp_simplex */ + int xcheck; + /* flag to check final basis with glp_exact */ + int nomip; + /* flag to consider MIP as pure LP */ +#if 1 /* 15/VIII-2011 */ + int minisat; + /* option to solve feasibility problem with MiniSat solver */ + int use_bnd; + /* option to bound objective function */ + int obj_bnd; + /* upper (minization) or lower (maximization) objective bound */ +#endif +#if 1 /* 11/VII-2013 */ + const char *use_sol; + /* name of input mip solution file in GLPK format */ +#endif +}; + +static void print_help(const char *my_name) +{ /* print help information */ + xprintf("Usage: %s [options...] filename\n", my_name); + xprintf("\n"); + xprintf("General options:\n"); + xprintf(" --mps read LP/MIP problem in fixed MPS fo" + "rmat\n"); + xprintf(" --freemps read LP/MIP problem in free MPS for" + "mat (default)\n"); + xprintf(" --lp read LP/MIP problem in CPLEX LP for" + "mat\n"); + xprintf(" --glp read LP/MIP problem in GLPK format " + "\n"); + xprintf(" --math read LP/MIP model written in GNU Ma" + "thProg modeling\n"); + xprintf(" language\n"); + xprintf(" -m filename, --model filename\n"); + xprintf(" read model section and optional dat" + "a section from\n"); + xprintf(" filename (same as --math)\n"); + xprintf(" -d filename, --data filename\n"); + xprintf(" read data section from filename (fo" + "r --math only);\n"); + xprintf(" if model file also has data section" + ", it is ignored\n"); + xprintf(" -y filename, --display filename\n"); + xprintf(" send display output to filename (fo" + "r --math only);\n"); + xprintf(" by default the output is sent to te" + "rminal\n"); + xprintf(" --seed value initialize pseudo-random number gen" + "erator used in\n"); + xprintf(" MathProg model with specified seed " + "(any integer);\n"); + xprintf(" if seed value is ?, some random see" + "d will be used\n"); + xprintf(" --mincost read min-cost flow problem in DIMAC" + "S format\n"); + xprintf(" --maxflow read maximum flow problem in DIMACS" + " format\n"); +#if 1 /* 06/VIII-2011 */ + xprintf(" --cnf read CNF-SAT problem in DIMACS form" + "at\n"); +#endif + xprintf(" --simplex use simplex method (default)\n"); + xprintf(" --interior use interior point method (LP only)" + "\n"); + xprintf(" -r filename, --read filename\n"); + xprintf(" read solution from filename rather " + "to find it with\n"); + xprintf(" the solver\n"); + xprintf(" --min minimization\n"); + xprintf(" --max maximization\n"); + xprintf(" --scale scale problem (default)\n"); + xprintf(" --noscale do not scale problem\n"); + xprintf(" -o filename, --output filename\n"); + xprintf(" write solution to filename in print" + "able format\n"); + xprintf(" -w filename, --write filename\n"); + xprintf(" write solution to filename in plain" + " text format\n"); + xprintf(" --ranges filename\n"); + xprintf(" write sensitivity analysis report t" + "o filename in\n"); + xprintf(" printable format (simplex only)\n"); + xprintf(" --tmlim nnn limit solution time to nnn seconds " + "\n"); + xprintf(" --memlim nnn limit available memory to nnn megab" + "ytes\n"); + xprintf(" --check do not solve problem, check input d" + "ata only\n"); + xprintf(" --name probname change problem name to probname\n"); + xprintf(" --wmps filename write problem to filename in fixed " + "MPS format\n"); + xprintf(" --wfreemps filename\n"); + xprintf(" write problem to filename in free M" + "PS format\n"); + xprintf(" --wlp filename write problem to filename in CPLEX " + "LP format\n"); + xprintf(" --wglp filename write problem to filename in GLPK f" + "ormat\n"); +#if 0 + xprintf(" --wpb filename write problem to filename in OPB fo" + "rmat\n"); + xprintf(" --wnpb filename write problem to filename in normal" + "ized OPB format\n"); +#endif +#if 1 /* 06/VIII-2011 */ + xprintf(" --wcnf filename write problem to filename in DIMACS" + " CNF-SAT format\n"); +#endif + xprintf(" --log filename write copy of terminal output to fi" + "lename\n"); + xprintf(" -h, --help display this help information and e" + "xit\n"); + xprintf(" -v, --version display program version and exit\n") + ; + xprintf("\n"); + xprintf("LP basis factorization options:\n"); +#if 0 /* 08/III-2014 */ + xprintf(" --luf LU + Forrest-Tomlin update\n"); + xprintf(" (faster, less stable; default)\n"); + xprintf(" --cbg LU + Schur complement + Bartels-Gol" + "ub update\n"); + xprintf(" (slower, more stable)\n"); + xprintf(" --cgr LU + Schur complement + Givens rota" + "tion update\n"); + xprintf(" (slower, more stable)\n"); +#else + xprintf(" --luf plain LU-factorization (default)\n") + ; + xprintf(" --btf block triangular LU-factorization\n" + ); + xprintf(" --ft Forrest-Tomlin update (requires --l" + "uf; default)\n"); + xprintf(" --cbg Schur complement + Bartels-Golub up" + "date\n"); + xprintf(" --cgr Schur complement + Givens rotation " + "update\n"); +#endif + xprintf("\n"); + xprintf("Options specific to simplex solver:\n"); + xprintf(" --primal use primal simplex (default)\n"); + xprintf(" --dual use dual simplex\n"); + xprintf(" --std use standard initial basis of all s" + "lacks\n"); + xprintf(" --adv use advanced initial basis (default" + ")\n"); + xprintf(" --bib use Bixby's initial basis\n"); + xprintf(" --ini filename use as initial basis previously sav" + "ed with -w\n"); + xprintf(" (disables LP presolver)\n"); + xprintf(" --steep use steepest edge technique (defaul" + "t)\n"); + xprintf(" --nosteep use standard \"textbook\" pricing\n" + ); + xprintf(" --relax use Harris' two-pass ratio test (de" + "fault)\n"); + xprintf(" --norelax use standard \"textbook\" ratio tes" + "t\n"); + xprintf(" --presol use presolver (default; assumes --s" + "cale and --adv)\n"); + xprintf(" --nopresol do not use presolver\n"); + xprintf(" --exact use simplex method based on exact a" + "rithmetic\n"); + xprintf(" --xcheck check final basis using exact arith" + "metic\n"); + xprintf("\n"); + xprintf("Options specific to interior-point solver:\n"); + xprintf(" --nord use natural (original) ordering\n"); + xprintf(" --qmd use quotient minimum degree orderin" + "g\n"); + xprintf(" --amd use approximate minimum degree orde" + "ring (default)\n"); + xprintf(" --symamd use approximate minimum degree orde" + "ring\n"); + xprintf("\n"); + xprintf("Options specific to MIP solver:\n"); + xprintf(" --nomip consider all integer variables as c" + "ontinuous\n"); + xprintf(" (allows solving MIP as pure LP)\n"); + xprintf(" --first branch on first integer variable\n") + ; + xprintf(" --last branch on last integer variable\n"); + xprintf(" --mostf branch on most fractional variable " + "\n"); + xprintf(" --drtom branch using heuristic by Driebeck " + "and Tomlin\n"); + xprintf(" (default)\n"); + xprintf(" --pcost branch using hybrid pseudocost heur" + "istic (may be\n"); + xprintf(" useful for hard instances)\n"); + xprintf(" --dfs backtrack using depth first search " + "\n"); + xprintf(" --bfs backtrack using breadth first searc" + "h\n"); + xprintf(" --bestp backtrack using the best projection" + " heuristic\n"); + xprintf(" --bestb backtrack using node with best loca" + "l bound\n"); + xprintf(" (default)\n"); + xprintf(" --intopt use MIP presolver (default)\n"); + xprintf(" --nointopt do not use MIP presolver\n"); + xprintf(" --binarize replace general integer variables b" + "y binary ones\n"); + xprintf(" (assumes --intopt)\n"); + xprintf(" --fpump apply feasibility pump heuristic\n") + ; +#if 1 /* 29/VI-2013 */ + xprintf(" --proxy [nnn] apply proximity search heuristic (n" + "nn is time limit\n"); + xprintf(" in seconds; default is 60)\n"); +#endif + xprintf(" --gomory generate Gomory's mixed integer cut" + "s\n"); + xprintf(" --mir generate MIR (mixed integer roundin" + "g) cuts\n"); + xprintf(" --cover generate mixed cover cuts\n"); + xprintf(" --clique generate clique cuts\n"); + xprintf(" --cuts generate all cuts above\n"); + xprintf(" --mipgap tol set relative mip gap tolerance to t" + "ol\n"); +#if 1 /* 15/VIII-2011 */ + xprintf(" --minisat translate integer feasibility probl" + "em to CNF-SAT\n"); + xprintf(" and solve it with MiniSat solver\n") + ; + xprintf(" --objbnd bound add inequality obj <= bound (minimi" + "zation) or\n"); + xprintf(" obj >= bound (maximization) to inte" + "ger feasibility\n"); + xprintf(" problem (assumes --minisat)\n"); +#endif + xprintf("\n"); + xprintf("For description of the MPS and CPLEX LP formats see Refe" + "rence Manual.\n"); + xprintf("For description of the modeling language see \"GLPK: Mod" + "eling Language\n"); + xprintf("GNU MathProg\". Both documents are included in the GLPK " + "distribution.\n"); + xprintf("\n"); + xprintf("See GLPK web page at .\n"); + xprintf("\n"); + xprintf("Please report bugs to .\n"); + return; +} + +static void print_version(int briefly) +{ /* print version information */ + xprintf("GLPSOL: GLPK LP/MIP Solver, v%s\n", glp_version()); + if (briefly) goto done; + xprintf("\n"); + xprintf("Copyright (C) 2000-2015 Andrew Makhorin, Department for " + "Applied\n"); + xprintf("Informatics, Moscow Aviation Institute, Moscow, Russia. " + "All rights\n"); + xprintf("reserved. E-mail: .\n"); + xprintf("\n"); + xprintf("This program has ABSOLUTELY NO WARRANTY.\n"); + xprintf("\n"); + xprintf("This program is free software; you may re-distribute it " + "under the terms\n"); + xprintf("of the GNU General Public License version 3 or later.\n") + ; +done: return; +} + +static int parse_cmdline(struct csa *csa, int argc, const char *argv[]) +{ /* parse command-line parameters */ + int k; +#define p(str) (strcmp(argv[k], str) == 0) + for (k = 1; k < argc; k++) + { if (p("--mps")) + csa->format = FMT_MPS_DECK; + else if (p("--freemps")) + csa->format = FMT_MPS_FILE; + else if (p("--lp") || p("--cpxlp")) + csa->format = FMT_LP; + else if (p("--glp")) + csa->format = FMT_GLP; + else if (p("--math") || p("-m") || p("--model")) + csa->format = FMT_MATHPROG; + else if (p("-d") || p("--data")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No input data file specified\n"); + return 1; + } + if (csa->ndf == DATA_MAX) + { xprintf("Too many input data files\n"); + return 1; + } + csa->in_data[++(csa->ndf)] = argv[k]; + } + else if (p("-y") || p("--display")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No display output file specified\n"); + return 1; + } + if (csa->out_dpy != NULL) + { xprintf("Only one display output file allowed\n"); + return 1; + } + csa->out_dpy = argv[k]; + } + else if (p("--seed")) + { k++; + if (k == argc || argv[k][0] == '\0' || + argv[k][0] == '-' && !isdigit((unsigned char)argv[k][1])) + { xprintf("No seed value specified\n"); + return 1; + } + if (strcmp(argv[k], "?") == 0) + csa->seed = 0x80000000; + else if (str2int(argv[k], &csa->seed)) + { xprintf("Invalid seed value '%s'\n", argv[k]); + return 1; + } + } + else if (p("--mincost")) + csa->format = FMT_MIN_COST; + else if (p("--maxflow")) + csa->format = FMT_MAX_FLOW; +#if 1 /* 06/VIII-2011 */ + else if (p("--cnf")) + csa->format = FMT_CNF; +#endif + else if (p("--simplex")) + csa->solution = SOL_BASIC; + else if (p("--interior")) + csa->solution = SOL_INTERIOR; +#if 1 /* 28/V-2010 */ + else if (p("--alien")) + csa->iocp.alien = GLP_ON; +#endif + else if (p("-r") || p("--read")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No input solution file specified\n"); + return 1; + } + if (csa->in_res != NULL) + { xprintf("Only one input solution file allowed\n"); + return 1; + } + csa->in_res = argv[k]; + } + else if (p("--min")) + csa->dir = GLP_MIN; + else if (p("--max")) + csa->dir = GLP_MAX; + else if (p("--scale")) + csa->scale = 1; + else if (p("--noscale")) + csa->scale = 0; + else if (p("-o") || p("--output")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No output solution file specified\n"); + return 1; + } + if (csa->out_sol != NULL) + { xprintf("Only one output solution file allowed\n"); + return 1; + } + csa->out_sol = argv[k]; + } + else if (p("-w") || p("--write")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No output solution file specified\n"); + return 1; + } + if (csa->out_res != NULL) + { xprintf("Only one output solution file allowed\n"); + return 1; + } + csa->out_res = argv[k]; + } + else if (p("--ranges") || p("--bounds")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No output file specified to write sensitivity a" + "nalysis report\n"); + return 1; + } + if (csa->out_ranges != NULL) + { xprintf("Only one output file allowed to write sensitivi" + "ty analysis report\n"); + return 1; + } + csa->out_ranges = argv[k]; + } + else if (p("--tmlim")) + { int tm_lim; + k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No time limit specified\n"); + return 1; + } + if (str2int(argv[k], &tm_lim) || tm_lim < 0) + { xprintf("Invalid time limit '%s'\n", argv[k]); + return 1; + } + if (tm_lim <= INT_MAX / 1000) + csa->smcp.tm_lim = csa->iocp.tm_lim = 1000 * tm_lim; + else + csa->smcp.tm_lim = csa->iocp.tm_lim = INT_MAX; + } + else if (p("--memlim")) + { int mem_lim; + k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No memory limit specified\n"); + return 1; + } + if (str2int(argv[k], &mem_lim) || mem_lim < 1) + { xprintf("Invalid memory limit '%s'\n", argv[k]); + return 1; + } + glp_mem_limit(mem_lim); + } + else if (p("--check")) + csa->check = 1; + else if (p("--name")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No problem name specified\n"); + return 1; + } + if (csa->new_name != NULL) + { xprintf("Only one problem name allowed\n"); + return 1; + } + csa->new_name = argv[k]; + } + else if (p("--wmps")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No fixed MPS output file specified\n"); + return 1; + } + if (csa->out_mps != NULL) + { xprintf("Only one fixed MPS output file allowed\n"); + return 1; + } + csa->out_mps = argv[k]; + } + else if (p("--wfreemps")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No free MPS output file specified\n"); + return 1; + } + if (csa->out_freemps != NULL) + { xprintf("Only one free MPS output file allowed\n"); + return 1; + } + csa->out_freemps = argv[k]; + } + else if (p("--wlp") || p("--wcpxlp") || p("--wlpt")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No CPLEX LP output file specified\n"); + return 1; + } + if (csa->out_cpxlp != NULL) + { xprintf("Only one CPLEX LP output file allowed\n"); + return 1; + } + csa->out_cpxlp = argv[k]; + } + else if (p("--wglp")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No GLPK LP/MIP output file specified\n"); + return 1; + } + if (csa->out_glp != NULL) + { xprintf("Only one GLPK LP/MIP output file allowed\n"); + return 1; + } + csa->out_glp = argv[k]; + } +#if 0 + else if (p("--wpb")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No problem output file specified\n"); + return 1; + } + if (csa->out_pb != NULL) + { xprintf("Only one OPB output file allowed\n"); + return 1; + } + csa->out_pb = argv[k]; + } + else if (p("--wnpb")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No problem output file specified\n"); + return 1; + } + if (csa->out_npb != NULL) + { xprintf("Only one normalized OPB output file allowed\n"); + return 1; + } + csa->out_npb = argv[k]; + } +#endif +#if 1 /* 06/VIII-2011 */ + else if (p("--wcnf")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No problem output file specified\n"); + return 1; + } + if (csa->out_cnf != NULL) + { xprintf("Only one output DIMACS CNF-SAT file allowed\n"); + return 1; + } + csa->out_cnf = argv[k]; + } +#endif + else if (p("--log")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No log file specified\n"); + return 1; + } + if (csa->log_file != NULL) + { xprintf("Only one log file allowed\n"); + return 1; + } + csa->log_file = argv[k]; + } + else if (p("-h") || p("--help")) + { print_help(argv[0]); + return -1; + } + else if (p("-v") || p("--version")) + { print_version(0); + return -1; + } +#if 0 /* 08/III-2014 */ + else if (p("--luf")) + csa->bfcp.type = GLP_BF_FT; + else if (p("--cbg")) + csa->bfcp.type = GLP_BF_BG; + else if (p("--cgr")) + csa->bfcp.type = GLP_BF_GR; +#else + else if (p("--luf")) + { csa->bfcp.type &= 0x0F; + csa->bfcp.type |= GLP_BF_LUF; + } + else if (p("--btf")) + { csa->bfcp.type &= 0x0F; + csa->bfcp.type |= GLP_BF_BTF; + } + else if (p("--ft")) + { csa->bfcp.type &= 0xF0; + csa->bfcp.type |= GLP_BF_FT; + } + else if (p("--cbg")) + { csa->bfcp.type &= 0xF0; + csa->bfcp.type |= GLP_BF_BG; + } + else if (p("--cgr")) + { csa->bfcp.type &= 0xF0; + csa->bfcp.type |= GLP_BF_GR; + } +#endif + else if (p("--primal")) + csa->smcp.meth = GLP_PRIMAL; + else if (p("--dual")) + csa->smcp.meth = GLP_DUAL; + else if (p("--std")) + csa->crash = USE_STD_BASIS; + else if (p("--adv")) + csa->crash = USE_ADV_BASIS; + else if (p("--bib")) + csa->crash = USE_CPX_BASIS; + else if (p("--ini")) + { csa->crash = USE_INI_BASIS; + csa->smcp.presolve = GLP_OFF; + k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No initial basis file specified\n"); + return 1; + } + if (csa->ini_file != NULL) + { xprintf("Only one initial basis file allowed\n"); + return 1; + } + csa->ini_file = argv[k]; + } + else if (p("--steep")) + csa->smcp.pricing = GLP_PT_PSE; + else if (p("--nosteep")) + csa->smcp.pricing = GLP_PT_STD; + else if (p("--relax")) + csa->smcp.r_test = GLP_RT_HAR; + else if (p("--norelax")) + csa->smcp.r_test = GLP_RT_STD; + else if (p("--presol")) + csa->smcp.presolve = GLP_ON; + else if (p("--nopresol")) + csa->smcp.presolve = GLP_OFF; + else if (p("--exact")) + csa->exact = 1; + else if (p("--xcheck")) + csa->xcheck = 1; + else if (p("--nord")) + csa->iptcp.ord_alg = GLP_ORD_NONE; + else if (p("--qmd")) + csa->iptcp.ord_alg = GLP_ORD_QMD; + else if (p("--amd")) + csa->iptcp.ord_alg = GLP_ORD_AMD; + else if (p("--symamd")) + csa->iptcp.ord_alg = GLP_ORD_SYMAMD; + else if (p("--nomip")) + csa->nomip = 1; + else if (p("--first")) + csa->iocp.br_tech = GLP_BR_FFV; + else if (p("--last")) + csa->iocp.br_tech = GLP_BR_LFV; + else if (p("--drtom")) + csa->iocp.br_tech = GLP_BR_DTH; + else if (p("--mostf")) + csa->iocp.br_tech = GLP_BR_MFV; + else if (p("--pcost")) + csa->iocp.br_tech = GLP_BR_PCH; + else if (p("--dfs")) + csa->iocp.bt_tech = GLP_BT_DFS; + else if (p("--bfs")) + csa->iocp.bt_tech = GLP_BT_BFS; + else if (p("--bestp")) + csa->iocp.bt_tech = GLP_BT_BPH; + else if (p("--bestb")) + csa->iocp.bt_tech = GLP_BT_BLB; + else if (p("--intopt")) + csa->iocp.presolve = GLP_ON; + else if (p("--nointopt")) + csa->iocp.presolve = GLP_OFF; + else if (p("--binarize")) + csa->iocp.presolve = csa->iocp.binarize = GLP_ON; + else if (p("--fpump")) + csa->iocp.fp_heur = GLP_ON; +#if 1 /* 29/VI-2013 */ + else if (p("--proxy")) + { csa->iocp.ps_heur = GLP_ON; + if (argv[k+1] && isdigit((unsigned char)argv[k+1][0])) + { int nnn; + k++; + if (str2int(argv[k], &nnn) || nnn < 1) + { xprintf("Invalid proxy time limit '%s'\n", argv[k]); + return 1; + } + csa->iocp.ps_tm_lim = 1000 * nnn; + } + } +#endif + else if (p("--gomory")) + csa->iocp.gmi_cuts = GLP_ON; + else if (p("--mir")) + csa->iocp.mir_cuts = GLP_ON; + else if (p("--cover")) + csa->iocp.cov_cuts = GLP_ON; + else if (p("--clique")) + csa->iocp.clq_cuts = GLP_ON; + else if (p("--cuts")) + csa->iocp.gmi_cuts = csa->iocp.mir_cuts = + csa->iocp.cov_cuts = csa->iocp.clq_cuts = GLP_ON; + else if (p("--mipgap")) + { double mip_gap; + k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No relative gap tolerance specified\n"); + return 1; + } + if (str2num(argv[k], &mip_gap) || mip_gap < 0.0) + { xprintf("Invalid relative mip gap tolerance '%s'\n", + argv[k]); + return 1; + } + csa->iocp.mip_gap = mip_gap; + } +#if 1 /* 15/VIII-2011 */ + else if (p("--minisat")) + csa->minisat = 1; + else if (p("--objbnd")) + { k++; + if (k == argc || argv[k][0] == '\0' || + argv[k][0] == '-' && !isdigit((unsigned char)argv[k][1])) + { xprintf("No objective bound specified\n"); + return 1; + } + csa->minisat = 1; + csa->use_bnd = 1; + if (str2int(argv[k], &csa->obj_bnd)) + { xprintf("Invalid objective bound '%s' (should be integer" + " value)\n", argv[k]); + return 1; + } + } +#endif +#if 1 /* 11/VII-2013 */ + else if (p("--use")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No input MIP solution file specified\n"); + return 1; + } + if (csa->use_sol != NULL) + { xprintf("Only one input MIP solution file allowed\n"); + return 1; + } + csa->use_sol = argv[k]; + } + else if (p("--save")) + { k++; + if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') + { xprintf("No output MIP solution file specified\n"); + return 1; + } + if (csa->iocp.save_sol != NULL) + { xprintf("Only one output MIP solution file allowed\n"); + return 1; + } + csa->iocp.save_sol = argv[k]; + } +#endif + else if (argv[k][0] == '-' || + (argv[k][0] == '-' && argv[k][1] == '-')) + { xprintf("Invalid option '%s'; try %s --help\n", + argv[k], argv[0]); + return 1; + } + else + { if (csa->in_file != NULL) + { xprintf("Only one input problem file allowed\n"); + return 1; + } + csa->in_file = argv[k]; + } + } +#undef p + return 0; +} + +typedef struct { double rhs, pi; } v_data; +typedef struct { double low, cap, cost, x; } a_data; + +int glp_main(int argc, const char *argv[]) +{ /* stand-alone LP/MIP solver */ + struct csa _csa, *csa = &_csa; + int ret; +#if 0 /* 10/VI-2013 */ + glp_long start; +#else + double start; +#endif + /* perform initialization */ + csa->prob = glp_create_prob(); + glp_get_bfcp(csa->prob, &csa->bfcp); + glp_init_smcp(&csa->smcp); + csa->smcp.presolve = GLP_ON; + glp_init_iptcp(&csa->iptcp); + glp_init_iocp(&csa->iocp); + csa->iocp.presolve = GLP_ON; + csa->tran = NULL; + csa->graph = NULL; + csa->format = FMT_MPS_FILE; + csa->in_file = NULL; + csa->ndf = 0; + csa->out_dpy = NULL; + csa->seed = 1; + csa->solution = SOL_BASIC; + csa->in_res = NULL; + csa->dir = 0; + csa->scale = 1; + csa->out_sol = NULL; + csa->out_res = NULL; + csa->out_ranges = NULL; + csa->check = 0; + csa->new_name = NULL; + csa->out_mps = NULL; + csa->out_freemps = NULL; + csa->out_cpxlp = NULL; + csa->out_glp = NULL; +#if 0 + csa->out_pb = NULL; + csa->out_npb = NULL; +#endif +#if 1 /* 06/VIII-2011 */ + csa->out_cnf = NULL; +#endif + csa->log_file = NULL; + csa->crash = USE_ADV_BASIS; + csa->ini_file = NULL; + csa->exact = 0; + csa->xcheck = 0; + csa->nomip = 0; +#if 1 /* 15/VIII-2011 */ + csa->minisat = 0; + csa->use_bnd = 0; + csa->obj_bnd = 0; +#endif +#if 1 /* 11/VII-2013 */ + csa->use_sol = NULL; +#endif + /* parse command-line parameters */ + ret = parse_cmdline(csa, argc, argv); + if (ret < 0) + { ret = EXIT_SUCCESS; + goto done; + } + if (ret > 0) + { ret = EXIT_FAILURE; + goto done; + } + /*--------------------------------------------------------------*/ + /* remove all output files specified in the command line */ + if (csa->out_dpy != NULL) remove(csa->out_dpy); + if (csa->out_sol != NULL) remove(csa->out_sol); + if (csa->out_res != NULL) remove(csa->out_res); + if (csa->out_ranges != NULL) remove(csa->out_ranges); + if (csa->out_mps != NULL) remove(csa->out_mps); + if (csa->out_freemps != NULL) remove(csa->out_freemps); + if (csa->out_cpxlp != NULL) remove(csa->out_cpxlp); + if (csa->out_glp != NULL) remove(csa->out_glp); +#if 0 + if (csa->out_pb != NULL) remove(csa->out_pb); + if (csa->out_npb != NULL) remove(csa->out_npb); +#endif +#if 1 /* 06/VIII-2011 */ + if (csa->out_cnf != NULL) remove(csa->out_cnf); +#endif + if (csa->log_file != NULL) remove(csa->log_file); + /*--------------------------------------------------------------*/ + /* open log file, if required */ + if (csa->log_file != NULL) + { if (glp_open_tee(csa->log_file)) + { xprintf("Unable to create log file\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /*--------------------------------------------------------------*/ + /* print version information */ + print_version(1); + /*--------------------------------------------------------------*/ + /* print parameters specified in the command line */ + if (argc > 1) + { int k, len = INT_MAX; + xprintf("Parameter(s) specified in the command line:"); + for (k = 1; k < argc; k++) + { if (len > 72) + xprintf("\n"), len = 0; + xprintf(" %s", argv[k]); + len += 1 + strlen(argv[k]); + } + xprintf("\n"); + } + /*--------------------------------------------------------------*/ + /* read problem data from the input file */ + if (csa->in_file == NULL) + { xprintf("No input problem file specified; try %s --help\n", + argv[0]); + ret = EXIT_FAILURE; + goto done; + } + if (csa->format == FMT_MPS_DECK) + { ret = glp_read_mps(csa->prob, GLP_MPS_DECK, NULL, + csa->in_file); + if (ret != 0) +err1: { xprintf("MPS file processing error\n"); + ret = EXIT_FAILURE; + goto done; + } + } + else if (csa->format == FMT_MPS_FILE) + { ret = glp_read_mps(csa->prob, GLP_MPS_FILE, NULL, + csa->in_file); + if (ret != 0) goto err1; + } + else if (csa->format == FMT_LP) + { ret = glp_read_lp(csa->prob, NULL, csa->in_file); + if (ret != 0) + { xprintf("CPLEX LP file processing error\n"); + ret = EXIT_FAILURE; + goto done; + } + } + else if (csa->format == FMT_GLP) + { ret = glp_read_prob(csa->prob, 0, csa->in_file); + if (ret != 0) + { xprintf("GLPK LP/MIP file processing error\n"); + ret = EXIT_FAILURE; + goto done; + } + } + else if (csa->format == FMT_MATHPROG) + { int k; + /* allocate the translator workspace */ + csa->tran = glp_mpl_alloc_wksp(); + /* set seed value */ + if (csa->seed == 0x80000000) +#if 0 /* 10/VI-2013 */ + { csa->seed = glp_time().lo; +#else + { csa->seed = (int)fmod(glp_time(), 1000000000.0); +#endif + xprintf("Seed value %d will be used\n", csa->seed); + } + _glp_mpl_init_rand(csa->tran, csa->seed); + /* read model section and optional data section */ + if (glp_mpl_read_model(csa->tran, csa->in_file, csa->ndf > 0)) +err2: { xprintf("MathProg model processing error\n"); + ret = EXIT_FAILURE; + goto done; + } + /* read optional data section(s), if necessary */ + for (k = 1; k <= csa->ndf; k++) + { if (glp_mpl_read_data(csa->tran, csa->in_data[k])) + goto err2; + } + /* generate the model */ + if (glp_mpl_generate(csa->tran, csa->out_dpy)) goto err2; + /* build the problem instance from the model */ + glp_mpl_build_prob(csa->tran, csa->prob); + } + else if (csa->format == FMT_MIN_COST) + { csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data)); + ret = glp_read_mincost(csa->graph, offsetof(v_data, rhs), + offsetof(a_data, low), offsetof(a_data, cap), + offsetof(a_data, cost), csa->in_file); + if (ret != 0) + { xprintf("DIMACS file processing error\n"); + ret = EXIT_FAILURE; + goto done; + } + glp_mincost_lp(csa->prob, csa->graph, GLP_ON, + offsetof(v_data, rhs), offsetof(a_data, low), + offsetof(a_data, cap), offsetof(a_data, cost)); + glp_set_prob_name(csa->prob, csa->in_file); + } + else if (csa->format == FMT_MAX_FLOW) + { int s, t; + csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data)); + ret = glp_read_maxflow(csa->graph, &s, &t, + offsetof(a_data, cap), csa->in_file); + if (ret != 0) + { xprintf("DIMACS file processing error\n"); + ret = EXIT_FAILURE; + goto done; + } + glp_maxflow_lp(csa->prob, csa->graph, GLP_ON, s, t, + offsetof(a_data, cap)); + glp_set_prob_name(csa->prob, csa->in_file); + } +#if 1 /* 06/VIII-2011 */ + else if (csa->format == FMT_CNF) + { ret = glp_read_cnfsat(csa->prob, csa->in_file); + if (ret != 0) + { xprintf("DIMACS file processing error\n"); + ret = EXIT_FAILURE; + goto done; + } + glp_set_prob_name(csa->prob, csa->in_file); + } +#endif + else + xassert(csa != csa); + /*--------------------------------------------------------------*/ + /* change problem name, if required */ + if (csa->new_name != NULL) + glp_set_prob_name(csa->prob, csa->new_name); + /* change optimization direction, if required */ + if (csa->dir != 0) + glp_set_obj_dir(csa->prob, csa->dir); + /* sort elements of the constraint matrix */ + glp_sort_matrix(csa->prob); + /*--------------------------------------------------------------*/ + /* write problem data in fixed MPS format, if required */ + if (csa->out_mps != NULL) + { ret = glp_write_mps(csa->prob, GLP_MPS_DECK, NULL, + csa->out_mps); + if (ret != 0) + { xprintf("Unable to write problem in fixed MPS format\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /* write problem data in free MPS format, if required */ + if (csa->out_freemps != NULL) + { ret = glp_write_mps(csa->prob, GLP_MPS_FILE, NULL, + csa->out_freemps); + if (ret != 0) + { xprintf("Unable to write problem in free MPS format\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /* write problem data in CPLEX LP format, if required */ + if (csa->out_cpxlp != NULL) + { ret = glp_write_lp(csa->prob, NULL, csa->out_cpxlp); + if (ret != 0) + { xprintf("Unable to write problem in CPLEX LP format\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /* write problem data in GLPK format, if required */ + if (csa->out_glp != NULL) + { ret = glp_write_prob(csa->prob, 0, csa->out_glp); + if (ret != 0) + { xprintf("Unable to write problem in GLPK format\n"); + ret = EXIT_FAILURE; + goto done; + } + } +#if 0 + /* write problem data in OPB format, if required */ + if (csa->out_pb != NULL) + { ret = lpx_write_pb(csa->prob, csa->out_pb, 0, 0); + if (ret != 0) + { xprintf("Unable to write problem in OPB format\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /* write problem data in normalized OPB format, if required */ + if (csa->out_npb != NULL) + { ret = lpx_write_pb(csa->prob, csa->out_npb, 1, 1); + if (ret != 0) + { xprintf( + "Unable to write problem in normalized OPB format\n"); + ret = EXIT_FAILURE; + goto done; + } + } +#endif +#if 1 /* 06/VIII-2011 */ + /* write problem data in DIMACS CNF-SAT format, if required */ + if (csa->out_cnf != NULL) + { ret = glp_write_cnfsat(csa->prob, csa->out_cnf); + if (ret != 0) + { xprintf( + "Unable to write problem in DIMACS CNF-SAT format\n"); + ret = EXIT_FAILURE; + goto done; + } + } +#endif + /*--------------------------------------------------------------*/ + /* if only problem data check is required, skip computations */ + if (csa->check) + { ret = EXIT_SUCCESS; + goto done; + } + /*--------------------------------------------------------------*/ + /* determine the solution type */ + if (!csa->nomip && + glp_get_num_int(csa->prob) + glp_get_num_bin(csa->prob) > 0) + { if (csa->solution == SOL_INTERIOR) + { xprintf("Interior-point method is not able to solve MIP pro" + "blem; use --simplex\n"); + ret = EXIT_FAILURE; + goto done; + } + csa->solution = SOL_INTEGER; + } + /*--------------------------------------------------------------*/ + /* if solution is provided, read it and skip computations */ + if (csa->in_res != NULL) + { if (csa->solution == SOL_BASIC) + ret = glp_read_sol(csa->prob, csa->in_res); + else if (csa->solution == SOL_INTERIOR) + ret = glp_read_ipt(csa->prob, csa->in_res); + else if (csa->solution == SOL_INTEGER) + ret = glp_read_mip(csa->prob, csa->in_res); + else + xassert(csa != csa); + if (ret != 0) + { xprintf("Unable to read problem solution\n"); + ret = EXIT_FAILURE; + goto done; + } + goto skip; + } +#if 1 /* 11/VII-2013 */ + /*--------------------------------------------------------------*/ + /* if initial MIP solution is provided, read it */ + if (csa->solution == SOL_INTEGER && csa->use_sol != NULL) + { ret = glp_read_mip(csa->prob, csa->use_sol); + if (ret != 0) + { xprintf("Unable to read initial MIP solution\n"); + ret = EXIT_FAILURE; + goto done; + } + csa->iocp.use_sol = GLP_ON; + } +#endif + /*--------------------------------------------------------------*/ + /* scale the problem data, if required */ + if (csa->scale) + { if (csa->solution == SOL_BASIC && !csa->smcp.presolve || + csa->solution == SOL_INTERIOR || + csa->solution == SOL_INTEGER && !csa->iocp.presolve) + glp_scale_prob(csa->prob, GLP_SF_AUTO); + } + /*--------------------------------------------------------------*/ + /* construct starting LP basis */ + if (csa->solution == SOL_BASIC && !csa->smcp.presolve || + csa->solution == SOL_INTEGER && !csa->iocp.presolve) + { if (csa->crash == USE_STD_BASIS) + glp_std_basis(csa->prob); + else if (csa->crash == USE_ADV_BASIS) + glp_adv_basis(csa->prob, 0); + else if (csa->crash == USE_CPX_BASIS) + glp_cpx_basis(csa->prob); + else if (csa->crash == USE_INI_BASIS) + { ret = glp_read_sol(csa->prob, csa->ini_file); + if (ret != 0) + { xprintf("Unable to read initial basis\n"); + ret = EXIT_FAILURE; + goto done; + } + } + else + xassert(csa != csa); + } + /*--------------------------------------------------------------*/ + /* solve the problem */ + start = xtime(); + if (csa->solution == SOL_BASIC) + { if (!csa->exact) + { glp_set_bfcp(csa->prob, &csa->bfcp); + glp_simplex(csa->prob, &csa->smcp); + if (csa->xcheck) + { if (csa->smcp.presolve && + glp_get_status(csa->prob) != GLP_OPT) + xprintf("If you need to check final basis for non-opt" + "imal solution, use --nopresol\n"); + else + glp_exact(csa->prob, &csa->smcp); + } + if (csa->out_sol != NULL || csa->out_res != NULL) + { if (csa->smcp.presolve && + glp_get_status(csa->prob) != GLP_OPT) + xprintf("If you need actual output for non-optimal solut" + "ion, use --nopresol\n"); + } + } + else + glp_exact(csa->prob, &csa->smcp); + } + else if (csa->solution == SOL_INTERIOR) + glp_interior(csa->prob, &csa->iptcp); +#if 1 /* 15/VIII-2011 */ + else if (csa->solution == SOL_INTEGER && csa->minisat) + { if (glp_check_cnfsat(csa->prob) == 0) + glp_minisat1(csa->prob); + else + glp_intfeas1(csa->prob, csa->use_bnd, csa->obj_bnd); + } +#endif + else if (csa->solution == SOL_INTEGER) + { glp_set_bfcp(csa->prob, &csa->bfcp); + if (!csa->iocp.presolve) + glp_simplex(csa->prob, &csa->smcp); +#if 0 + csa->iocp.msg_lev = GLP_MSG_DBG; + csa->iocp.pp_tech = GLP_PP_NONE; +#endif + glp_intopt(csa->prob, &csa->iocp); + } + else + xassert(csa != csa); + /*--------------------------------------------------------------*/ + /* display statistics */ + xprintf("Time used: %.1f secs\n", xdifftime(xtime(), start)); +#if 0 /* 16/II-2012 */ + { glp_long tpeak; + char buf[50]; + glp_mem_usage(NULL, NULL, NULL, &tpeak); + xprintf("Memory used: %.1f Mb (%s bytes)\n", + xltod(tpeak) / 1048576.0, xltoa(tpeak, buf)); + } +#else + { size_t tpeak; + glp_mem_usage(NULL, NULL, NULL, &tpeak); + xprintf("Memory used: %.1f Mb (%.0f bytes)\n", + (double)tpeak / 1048576.0, (double)tpeak); + } +#endif + /*--------------------------------------------------------------*/ +skip: /* postsolve the model, if necessary */ + if (csa->tran != NULL) + { if (csa->solution == SOL_BASIC) + { if (!(glp_get_status(csa->prob) == GLP_OPT || + glp_get_status(csa->prob) == GLP_FEAS)) + ret = -1; + else + ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_SOL); + } + else if (csa->solution == SOL_INTERIOR) + { if (!(glp_ipt_status(csa->prob) == GLP_OPT || + glp_ipt_status(csa->prob) == GLP_FEAS)) + ret = -1; + else + ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_IPT); + } + else if (csa->solution == SOL_INTEGER) + { if (!(glp_mip_status(csa->prob) == GLP_OPT || + glp_mip_status(csa->prob) == GLP_FEAS)) + ret = -1; + else + ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_MIP); + } + else + xassert(csa != csa); + if (ret > 0) + { xprintf("Model postsolving error\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /*--------------------------------------------------------------*/ + /* write problem solution in printable format, if required */ + if (csa->out_sol != NULL) + { if (csa->solution == SOL_BASIC) + ret = glp_print_sol(csa->prob, csa->out_sol); + else if (csa->solution == SOL_INTERIOR) + ret = glp_print_ipt(csa->prob, csa->out_sol); + else if (csa->solution == SOL_INTEGER) + ret = glp_print_mip(csa->prob, csa->out_sol); + else + xassert(csa != csa); + if (ret != 0) + { xprintf("Unable to write problem solution\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /* write problem solution in printable format, if required */ + if (csa->out_res != NULL) + { if (csa->solution == SOL_BASIC) + ret = glp_write_sol(csa->prob, csa->out_res); + else if (csa->solution == SOL_INTERIOR) + ret = glp_write_ipt(csa->prob, csa->out_res); + else if (csa->solution == SOL_INTEGER) + ret = glp_write_mip(csa->prob, csa->out_res); + else + xassert(csa != csa); + if (ret != 0) + { xprintf("Unable to write problem solution\n"); + ret = EXIT_FAILURE; + goto done; + } + } + /* write sensitivity analysis report, if required */ + if (csa->out_ranges != NULL) + { if (csa->solution == SOL_BASIC) + { if (glp_get_status(csa->prob) == GLP_OPT) + { if (glp_bf_exists(csa->prob)) +ranges: { ret = glp_print_ranges(csa->prob, 0, NULL, 0, + csa->out_ranges); + if (ret != 0) + { xprintf("Unable to write sensitivity analysis repo" + "rt\n"); + ret = EXIT_FAILURE; + goto done; + } + } + else + { ret = glp_factorize(csa->prob); + if (ret == 0) goto ranges; + xprintf("Cannot produce sensitivity analysis report d" + "ue to error in basis factorization (glp_factorize" + " returned %d); try --nopresol\n", ret); + } + } + else + xprintf("Cannot produce sensitivity analysis report for " + "non-optimal basic solution\n"); + } + else + xprintf("Cannot produce sensitivity analysis report for int" + "erior-point or MIP solution\n"); + } + /*--------------------------------------------------------------*/ + /* all seems to be ok */ + ret = EXIT_SUCCESS; + /*--------------------------------------------------------------*/ +done: /* delete the LP/MIP problem object */ + if (csa->prob != NULL) + glp_delete_prob(csa->prob); + /* free the translator workspace, if necessary */ + if (csa->tran != NULL) + glp_mpl_free_wksp(csa->tran); + /* delete the network problem object, if necessary */ + if (csa->graph != NULL) + glp_delete_graph(csa->graph); + xassert(gmp_pool_count() == 0); + gmp_free_mem(); + /* close log file, if necessary */ + if (csa->log_file != NULL) glp_close_tee(); + /* check that no memory blocks are still allocated */ +#if 0 /* 16/II-2012 */ + { int count; + glp_long total; + glp_mem_usage(&count, NULL, &total, NULL); + if (count != 0) + xerror("Error: %d memory block(s) were lost\n", count); + xassert(count == 0); + xassert(total.lo == 0 && total.hi == 0); + } +#else + { int count; + size_t total; + glp_mem_usage(&count, NULL, &total, NULL); + if (count != 0) + xerror("Error: %d memory block(s) were lost\n", count); + xassert(total == 0); + } +#endif + /* free the GLPK environment */ + glp_free_env(); + /* return to the control program */ + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpcpx.c b/resources/3rdparty/glpk-4.57/src/glpcpx.c new file mode 100644 index 000000000..1aa3f346b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpcpx.c @@ -0,0 +1,1262 @@ +/* glpcpx.c (CPLEX LP format routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "misc.h" +#include "prob.h" + +#define xfprintf glp_format + +/*********************************************************************** +* NAME +* +* glp_init_cpxcp - initialize CPLEX LP format control parameters +* +* SYNOPSIS +* +* void glp_init_cpxcp(glp_cpxcp *parm): +* +* The routine glp_init_cpxcp initializes control parameters used by +* the CPLEX LP input/output routines glp_read_lp and glp_write_lp with +* default values. +* +* Default values of the control parameters are stored in the glp_cpxcp +* structure, which the parameter parm points to. */ + +void glp_init_cpxcp(glp_cpxcp *parm) +{ xassert(parm != NULL); + return; +} + +static void check_parm(const char *func, const glp_cpxcp *parm) +{ /* check control parameters */ + xassert(func != NULL); + xassert(parm != NULL); + return; +} + +/*********************************************************************** +* NAME +* +* glp_read_lp - read problem data in CPLEX LP format +* +* SYNOPSIS +* +* int glp_read_lp(glp_prob *P, const glp_cpxcp *parm, const char +* *fname); +* +* DESCRIPTION +* +* The routine glp_read_lp reads problem data in CPLEX LP format from +* a text file. +* +* The parameter parm is a pointer to the structure glp_cpxcp, which +* specifies control parameters used by the routine. If parm is NULL, +* the routine uses default settings. +* +* The character string fname specifies a name of the text file to be +* read. +* +* Note that before reading data the current content of the problem +* object is completely erased with the routine glp_erase_prob. +* +* RETURNS +* +* If the operation was successful, the routine glp_read_lp returns +* zero. Otherwise, it prints an error message and returns non-zero. */ + +struct csa +{ /* common storage area */ + glp_prob *P; + /* LP/MIP problem object */ + const glp_cpxcp *parm; + /* pointer to control parameters */ + const char *fname; + /* name of input CPLEX LP file */ + glp_file *fp; + /* stream assigned to input CPLEX LP file */ + jmp_buf jump; + /* label for go to in case of error */ + int count; + /* line count */ + int c; + /* current character or EOF */ + int token; + /* current token: */ +#define T_EOF 0x00 /* end of file */ +#define T_MINIMIZE 0x01 /* keyword 'minimize' */ +#define T_MAXIMIZE 0x02 /* keyword 'maximize' */ +#define T_SUBJECT_TO 0x03 /* keyword 'subject to' */ +#define T_BOUNDS 0x04 /* keyword 'bounds' */ +#define T_GENERAL 0x05 /* keyword 'general' */ +#define T_INTEGER 0x06 /* keyword 'integer' */ +#define T_BINARY 0x07 /* keyword 'binary' */ +#define T_END 0x08 /* keyword 'end' */ +#define T_NAME 0x09 /* symbolic name */ +#define T_NUMBER 0x0A /* numeric constant */ +#define T_PLUS 0x0B /* delimiter '+' */ +#define T_MINUS 0x0C /* delimiter '-' */ +#define T_COLON 0x0D /* delimiter ':' */ +#define T_LE 0x0E /* delimiter '<=' */ +#define T_GE 0x0F /* delimiter '>=' */ +#define T_EQ 0x10 /* delimiter '=' */ + char image[255+1]; + /* image of current token */ + int imlen; + /* length of token image */ + double value; + /* value of numeric constant */ + int n_max; + /* length of the following five arrays (enlarged automatically, + if necessary) */ + int *ind; /* int ind[1+n_max]; */ + double *val; /* double val[1+n_max]; */ + char *flag; /* char flag[1+n_max]; */ + /* working arrays used to construct linear forms */ + double *lb; /* double lb[1+n_max]; */ + double *ub; /* double ub[1+n_max]; */ + /* lower and upper bounds of variables (columns) */ +#if 1 /* 27/VII-2013 */ + int lb_warn, ub_warn; + /* warning 'lower/upper bound redefined' already issued */ +#endif +}; + +#define CHAR_SET "!\"#$%&()/,.;?@_`'{}|~" +/* characters, which may appear in symbolic names */ + +static void error(struct csa *csa, const char *fmt, ...) +{ /* print error message and terminate processing */ + va_list arg; + xprintf("%s:%d: ", csa->fname, csa->count); + va_start(arg, fmt); + xvprintf(fmt, arg); + va_end(arg); + longjmp(csa->jump, 1); + /* no return */ +} + +static void warning(struct csa *csa, const char *fmt, ...) +{ /* print warning message and continue processing */ + va_list arg; + xprintf("%s:%d: warning: ", csa->fname, csa->count); + va_start(arg, fmt); + xvprintf(fmt, arg); + va_end(arg); + return; +} + +static void read_char(struct csa *csa) +{ /* read next character from input file */ + int c; + xassert(csa->c != EOF); + if (csa->c == '\n') csa->count++; + c = glp_getc(csa->fp); + if (c < 0) + { if (glp_ioerr(csa->fp)) + error(csa, "read error - %s\n", get_err_msg()); + else if (csa->c == '\n') + { csa->count--; + c = EOF; + } + else + { warning(csa, "missing final end of line\n"); + c = '\n'; + } + } + else if (c == '\n') + ; + else if (isspace(c)) + c = ' '; + else if (iscntrl(c)) + error(csa, "invalid control character 0x%02X\n", c); + csa->c = c; + return; +} + +static void add_char(struct csa *csa) +{ /* append current character to current token */ + if (csa->imlen == sizeof(csa->image)-1) + error(csa, "token '%.15s...' too long\n", csa->image); + csa->image[csa->imlen++] = (char)csa->c; + csa->image[csa->imlen] = '\0'; + read_char(csa); + return; +} + +static int the_same(char *s1, char *s2) +{ /* compare two character strings ignoring case sensitivity */ + for (; *s1 != '\0'; s1++, s2++) + { if (tolower((unsigned char)*s1) != tolower((unsigned char)*s2)) + return 0; + } + return 1; +} + +static void scan_token(struct csa *csa) +{ /* scan next token */ + int flag; + csa->token = -1; + csa->image[0] = '\0'; + csa->imlen = 0; + csa->value = 0.0; +loop: flag = 0; + /* skip non-significant characters */ + while (csa->c == ' ') read_char(csa); + /* recognize and scan current token */ + if (csa->c == EOF) + csa->token = T_EOF; + else if (csa->c == '\n') + { read_char(csa); + /* if the next character is letter, it may begin a keyword */ + if (isalpha(csa->c)) + { flag = 1; + goto name; + } + goto loop; + } + else if (csa->c == '\\') + { /* comment; ignore everything until end-of-line */ + while (csa->c != '\n') read_char(csa); + goto loop; + } + else if (isalpha(csa->c) || csa->c != '.' && strchr(CHAR_SET, + csa->c) != NULL) +name: { /* symbolic name */ + csa->token = T_NAME; + while (isalnum(csa->c) || strchr(CHAR_SET, csa->c) != NULL) + add_char(csa); + if (flag) + { /* check for keyword */ + if (the_same(csa->image, "minimize")) + csa->token = T_MINIMIZE; + else if (the_same(csa->image, "minimum")) + csa->token = T_MINIMIZE; + else if (the_same(csa->image, "min")) + csa->token = T_MINIMIZE; + else if (the_same(csa->image, "maximize")) + csa->token = T_MAXIMIZE; + else if (the_same(csa->image, "maximum")) + csa->token = T_MAXIMIZE; + else if (the_same(csa->image, "max")) + csa->token = T_MAXIMIZE; + else if (the_same(csa->image, "subject")) + { if (csa->c == ' ') + { read_char(csa); + if (tolower(csa->c) == 't') + { csa->token = T_SUBJECT_TO; + csa->image[csa->imlen++] = ' '; + csa->image[csa->imlen] = '\0'; + add_char(csa); + if (tolower(csa->c) != 'o') + error(csa, "keyword 'subject to' incomplete\n"); + add_char(csa); + if (isalpha(csa->c)) + error(csa, "keyword '%s%c...' not recognized\n", + csa->image, csa->c); + } + } + } + else if (the_same(csa->image, "such")) + { if (csa->c == ' ') + { read_char(csa); + if (tolower(csa->c) == 't') + { csa->token = T_SUBJECT_TO; + csa->image[csa->imlen++] = ' '; + csa->image[csa->imlen] = '\0'; + add_char(csa); + if (tolower(csa->c) != 'h') +err: error(csa, "keyword 'such that' incomplete\n"); + add_char(csa); + if (tolower(csa->c) != 'a') goto err; + add_char(csa); + if (tolower(csa->c) != 't') goto err; + add_char(csa); + if (isalpha(csa->c)) + error(csa, "keyword '%s%c...' not recognized\n", + csa->image, csa->c); + } + } + } + else if (the_same(csa->image, "st")) + csa->token = T_SUBJECT_TO; + else if (the_same(csa->image, "s.t.")) + csa->token = T_SUBJECT_TO; + else if (the_same(csa->image, "st.")) + csa->token = T_SUBJECT_TO; + else if (the_same(csa->image, "bounds")) + csa->token = T_BOUNDS; + else if (the_same(csa->image, "bound")) + csa->token = T_BOUNDS; + else if (the_same(csa->image, "general")) + csa->token = T_GENERAL; + else if (the_same(csa->image, "generals")) + csa->token = T_GENERAL; + else if (the_same(csa->image, "gen")) + csa->token = T_GENERAL; + else if (the_same(csa->image, "integer")) + csa->token = T_INTEGER; + else if (the_same(csa->image, "integers")) + csa->token = T_INTEGER; + else if (the_same(csa->image, "int")) + csa->token = T_INTEGER; + else if (the_same(csa->image, "binary")) + csa->token = T_BINARY; + else if (the_same(csa->image, "binaries")) + csa->token = T_BINARY; + else if (the_same(csa->image, "bin")) + csa->token = T_BINARY; + else if (the_same(csa->image, "end")) + csa->token = T_END; + } + } + else if (isdigit(csa->c) || csa->c == '.') + { /* numeric constant */ + csa->token = T_NUMBER; + /* scan integer part */ + while (isdigit(csa->c)) add_char(csa); + /* scan optional fractional part (it is mandatory, if there is + no integer part) */ + if (csa->c == '.') + { add_char(csa); + if (csa->imlen == 1 && !isdigit(csa->c)) + error(csa, "invalid use of decimal point\n"); + while (isdigit(csa->c)) add_char(csa); + } + /* scan optional decimal exponent */ + if (csa->c == 'e' || csa->c == 'E') + { add_char(csa); + if (csa->c == '+' || csa->c == '-') add_char(csa); + if (!isdigit(csa->c)) + error(csa, "numeric constant '%s' incomplete\n", + csa->image); + while (isdigit(csa->c)) add_char(csa); + } + /* convert the numeric constant to floating-point */ + if (str2num(csa->image, &csa->value)) + error(csa, "numeric constant '%s' out of range\n", + csa->image); + } + else if (csa->c == '+') + csa->token = T_PLUS, add_char(csa); + else if (csa->c == '-') + csa->token = T_MINUS, add_char(csa); + else if (csa->c == ':') + csa->token = T_COLON, add_char(csa); + else if (csa->c == '<') + { csa->token = T_LE, add_char(csa); + if (csa->c == '=') add_char(csa); + } + else if (csa->c == '>') + { csa->token = T_GE, add_char(csa); + if (csa->c == '=') add_char(csa); + } + else if (csa->c == '=') + { csa->token = T_EQ, add_char(csa); + if (csa->c == '<') + csa->token = T_LE, add_char(csa); + else if (csa->c == '>') + csa->token = T_GE, add_char(csa); + } + else + error(csa, "character '%c' not recognized\n", csa->c); + /* skip non-significant characters */ + while (csa->c == ' ') read_char(csa); + return; +} + +static int find_col(struct csa *csa, char *name) +{ /* find column by its symbolic name */ + int j; + j = glp_find_col(csa->P, name); + if (j == 0) + { /* not found; create new column */ + j = glp_add_cols(csa->P, 1); + glp_set_col_name(csa->P, j, name); + /* enlarge working arrays, if necessary */ + if (csa->n_max < j) + { int n_max = csa->n_max; + int *ind = csa->ind; + double *val = csa->val; + char *flag = csa->flag; + double *lb = csa->lb; + double *ub = csa->ub; + csa->n_max += csa->n_max; + csa->ind = xcalloc(1+csa->n_max, sizeof(int)); + memcpy(&csa->ind[1], &ind[1], n_max * sizeof(int)); + xfree(ind); + csa->val = xcalloc(1+csa->n_max, sizeof(double)); + memcpy(&csa->val[1], &val[1], n_max * sizeof(double)); + xfree(val); + csa->flag = xcalloc(1+csa->n_max, sizeof(char)); + memset(&csa->flag[1], 0, csa->n_max * sizeof(char)); + memcpy(&csa->flag[1], &flag[1], n_max * sizeof(char)); + xfree(flag); + csa->lb = xcalloc(1+csa->n_max, sizeof(double)); + memcpy(&csa->lb[1], &lb[1], n_max * sizeof(double)); + xfree(lb); + csa->ub = xcalloc(1+csa->n_max, sizeof(double)); + memcpy(&csa->ub[1], &ub[1], n_max * sizeof(double)); + xfree(ub); + } + csa->lb[j] = +DBL_MAX, csa->ub[j] = -DBL_MAX; + } + return j; +} + +/*********************************************************************** +* parse_linear_form - parse linear form +* +* This routine parses the linear form using the following syntax: +* +* ::= +* ::= +* ::= | +* ::= | + | - | +* + | - +* +* The routine returns the number of terms in the linear form. */ + +static int parse_linear_form(struct csa *csa) +{ int j, k, len = 0, newlen; + double s, coef; +loop: /* parse an optional sign */ + if (csa->token == T_PLUS) + s = +1.0, scan_token(csa); + else if (csa->token == T_MINUS) + s = -1.0, scan_token(csa); + else + s = +1.0; + /* parse an optional coefficient */ + if (csa->token == T_NUMBER) + coef = csa->value, scan_token(csa); + else + coef = 1.0; + /* parse a variable name */ + if (csa->token != T_NAME) + error(csa, "missing variable name\n"); + /* find the corresponding column */ + j = find_col(csa, csa->image); + /* check if the variable is already used in the linear form */ + if (csa->flag[j]) + error(csa, "multiple use of variable '%s' not allowed\n", + csa->image); + /* add new term to the linear form */ + len++, csa->ind[len] = j, csa->val[len] = s * coef; + /* and mark that the variable is used in the linear form */ + csa->flag[j] = 1; + scan_token(csa); + /* if the next token is a sign, there is another term */ + if (csa->token == T_PLUS || csa->token == T_MINUS) goto loop; + /* clear marks of the variables used in the linear form */ + for (k = 1; k <= len; k++) csa->flag[csa->ind[k]] = 0; + /* remove zero coefficients */ + newlen = 0; + for (k = 1; k <= len; k++) + { if (csa->val[k] != 0.0) + { newlen++; + csa->ind[newlen] = csa->ind[k]; + csa->val[newlen] = csa->val[k]; + } + } + return newlen; +} + +/*********************************************************************** +* parse_objective - parse objective function +* +* This routine parses definition of the objective function using the +* following syntax: +* +* ::= minimize | minimum | min | maximize | maximum | max +* ::= | : +* ::= */ + +static void parse_objective(struct csa *csa) +{ /* parse objective sense */ + int k, len; + /* parse the keyword 'minimize' or 'maximize' */ + if (csa->token == T_MINIMIZE) + glp_set_obj_dir(csa->P, GLP_MIN); + else if (csa->token == T_MAXIMIZE) + glp_set_obj_dir(csa->P, GLP_MAX); + else + xassert(csa != csa); + scan_token(csa); + /* parse objective name */ + if (csa->token == T_NAME && csa->c == ':') + { /* objective name is followed by a colon */ + glp_set_obj_name(csa->P, csa->image); + scan_token(csa); + xassert(csa->token == T_COLON); + scan_token(csa); + } + else + { /* objective name is not specified; use default */ + glp_set_obj_name(csa->P, "obj"); + } + /* parse linear form */ + len = parse_linear_form(csa); + for (k = 1; k <= len; k++) + glp_set_obj_coef(csa->P, csa->ind[k], csa->val[k]); + return; +} + +/*********************************************************************** +* parse_constraints - parse constraints section +* +* This routine parses the constraints section using the following +* syntax: +* +* ::= | : +* ::= < | <= | =< | > | >= | => | = +* ::= | + | +* - +* ::= +* +* ::= subject to | such that | st | s.t. | st. +* ::= | +* */ + +static void parse_constraints(struct csa *csa) +{ int i, len, type; + double s; + /* parse the keyword 'subject to' */ + xassert(csa->token == T_SUBJECT_TO); + scan_token(csa); +loop: /* create new row (constraint) */ + i = glp_add_rows(csa->P, 1); + /* parse row name */ + if (csa->token == T_NAME && csa->c == ':') + { /* row name is followed by a colon */ + if (glp_find_row(csa->P, csa->image) != 0) + error(csa, "constraint '%s' multiply defined\n", + csa->image); + glp_set_row_name(csa->P, i, csa->image); + scan_token(csa); + xassert(csa->token == T_COLON); + scan_token(csa); + } + else + { /* row name is not specified; use default */ + char name[50]; + sprintf(name, "r.%d", csa->count); + glp_set_row_name(csa->P, i, name); + } + /* parse linear form */ + len = parse_linear_form(csa); + glp_set_mat_row(csa->P, i, len, csa->ind, csa->val); + /* parse constraint sense */ + if (csa->token == T_LE) + type = GLP_UP, scan_token(csa); + else if (csa->token == T_GE) + type = GLP_LO, scan_token(csa); + else if (csa->token == T_EQ) + type = GLP_FX, scan_token(csa); + else + error(csa, "missing constraint sense\n"); + /* parse right-hand side */ + if (csa->token == T_PLUS) + s = +1.0, scan_token(csa); + else if (csa->token == T_MINUS) + s = -1.0, scan_token(csa); + else + s = +1.0; + if (csa->token != T_NUMBER) + error(csa, "missing right-hand side\n"); + glp_set_row_bnds(csa->P, i, type, s * csa->value, s * csa->value); + /* the rest of the current line must be empty */ + if (!(csa->c == '\n' || csa->c == EOF)) + error(csa, "invalid symbol(s) beyond right-hand side\n"); + scan_token(csa); + /* if the next token is a sign, numeric constant, or a symbolic + name, here is another constraint */ + if (csa->token == T_PLUS || csa->token == T_MINUS || + csa->token == T_NUMBER || csa->token == T_NAME) goto loop; + return; +} + +static void set_lower_bound(struct csa *csa, int j, double lb) +{ /* set lower bound of j-th variable */ + if (csa->lb[j] != +DBL_MAX && !csa->lb_warn) + { warning(csa, "lower bound of variable '%s' redefined\n", + glp_get_col_name(csa->P, j)); + csa->lb_warn = 1; + } + csa->lb[j] = lb; + return; +} + +static void set_upper_bound(struct csa *csa, int j, double ub) +{ /* set upper bound of j-th variable */ + if (csa->ub[j] != -DBL_MAX && !csa->ub_warn) + { warning(csa, "upper bound of variable '%s' redefined\n", + glp_get_col_name(csa->P, j)); + csa->ub_warn = 1; + } + csa->ub[j] = ub; + return; +} + +/*********************************************************************** +* parse_bounds - parse bounds section +* +* This routine parses the bounds section using the following syntax: +* +* ::= +* ::= infinity | inf +* ::= | + | +* - | + | - +* ::= < | <= | =< +* ::= > | >= | => +* ::= | +* | | +* | = | free +* ::= bounds | bound +* ::= | +* */ + +static void parse_bounds(struct csa *csa) +{ int j, lb_flag; + double lb, s; + /* parse the keyword 'bounds' */ + xassert(csa->token == T_BOUNDS); + scan_token(csa); +loop: /* bound definition can start with a sign, numeric constant, or + a symbolic name */ + if (!(csa->token == T_PLUS || csa->token == T_MINUS || + csa->token == T_NUMBER || csa->token == T_NAME)) goto done; + /* parse bound definition */ + if (csa->token == T_PLUS || csa->token == T_MINUS) + { /* parse signed lower bound */ + lb_flag = 1; + s = (csa->token == T_PLUS ? +1.0 : -1.0); + scan_token(csa); + if (csa->token == T_NUMBER) + lb = s * csa->value, scan_token(csa); + else if (the_same(csa->image, "infinity") || + the_same(csa->image, "inf")) + { if (s > 0.0) + error(csa, "invalid use of '+inf' as lower bound\n"); + lb = -DBL_MAX, scan_token(csa); + } + else + error(csa, "missing lower bound\n"); + } + else if (csa->token == T_NUMBER) + { /* parse unsigned lower bound */ + lb_flag = 1; + lb = csa->value, scan_token(csa); + } + else + { /* lower bound is not specified */ + lb_flag = 0; + } + /* parse the token that should follow the lower bound */ + if (lb_flag) + { if (csa->token != T_LE) + error(csa, "missing '<', '<=', or '=<' after lower bound\n") + ; + scan_token(csa); + } + /* parse variable name */ + if (csa->token != T_NAME) + error(csa, "missing variable name\n"); + j = find_col(csa, csa->image); + /* set lower bound */ + if (lb_flag) set_lower_bound(csa, j, lb); + scan_token(csa); + /* parse the context that follows the variable name */ + if (csa->token == T_LE) + { /* parse upper bound */ + scan_token(csa); + if (csa->token == T_PLUS || csa->token == T_MINUS) + { /* parse signed upper bound */ + s = (csa->token == T_PLUS ? +1.0 : -1.0); + scan_token(csa); + if (csa->token == T_NUMBER) + { set_upper_bound(csa, j, s * csa->value); + scan_token(csa); + } + else if (the_same(csa->image, "infinity") || + the_same(csa->image, "inf")) + { if (s < 0.0) + error(csa, "invalid use of '-inf' as upper bound\n"); + set_upper_bound(csa, j, +DBL_MAX); + scan_token(csa); + } + else + error(csa, "missing upper bound\n"); + } + else if (csa->token == T_NUMBER) + { /* parse unsigned upper bound */ + set_upper_bound(csa, j, csa->value); + scan_token(csa); + } + else + error(csa, "missing upper bound\n"); + } + else if (csa->token == T_GE) + { /* parse lower bound */ + if (lb_flag) + { /* the context '... <= x >= ...' is invalid */ + error(csa, "invalid bound definition\n"); + } + scan_token(csa); + if (csa->token == T_PLUS || csa->token == T_MINUS) + { /* parse signed lower bound */ + s = (csa->token == T_PLUS ? +1.0 : -1.0); + scan_token(csa); + if (csa->token == T_NUMBER) + { set_lower_bound(csa, j, s * csa->value); + scan_token(csa); + } + else if (the_same(csa->image, "infinity") || + the_same(csa->image, "inf") == 0) + { if (s > 0.0) + error(csa, "invalid use of '+inf' as lower bound\n"); + set_lower_bound(csa, j, -DBL_MAX); + scan_token(csa); + } + else + error(csa, "missing lower bound\n"); + } + else if (csa->token == T_NUMBER) + { /* parse unsigned lower bound */ + set_lower_bound(csa, j, csa->value); + scan_token(csa); + } + else + error(csa, "missing lower bound\n"); + } + else if (csa->token == T_EQ) + { /* parse fixed value */ + if (lb_flag) + { /* the context '... <= x = ...' is invalid */ + error(csa, "invalid bound definition\n"); + } + scan_token(csa); + if (csa->token == T_PLUS || csa->token == T_MINUS) + { /* parse signed fixed value */ + s = (csa->token == T_PLUS ? +1.0 : -1.0); + scan_token(csa); + if (csa->token == T_NUMBER) + { set_lower_bound(csa, j, s * csa->value); + set_upper_bound(csa, j, s * csa->value); + scan_token(csa); + } + else + error(csa, "missing fixed value\n"); + } + else if (csa->token == T_NUMBER) + { /* parse unsigned fixed value */ + set_lower_bound(csa, j, csa->value); + set_upper_bound(csa, j, csa->value); + scan_token(csa); + } + else + error(csa, "missing fixed value\n"); + } + else if (the_same(csa->image, "free")) + { /* parse the keyword 'free' */ + if (lb_flag) + { /* the context '... <= x free ...' is invalid */ + error(csa, "invalid bound definition\n"); + } + set_lower_bound(csa, j, -DBL_MAX); + set_upper_bound(csa, j, +DBL_MAX); + scan_token(csa); + } + else if (!lb_flag) + { /* neither lower nor upper bounds are specified */ + error(csa, "invalid bound definition\n"); + } + goto loop; +done: return; +} + +/*********************************************************************** +* parse_integer - parse general, integer, or binary section +* +* ::= +* ::= general | generals | gen +* ::= integer | integers | int +* ::= binary | binaries | bin +*

::= +* ::=
| +* */ + +static void parse_integer(struct csa *csa) +{ int j, binary; + /* parse the keyword 'general', 'integer', or 'binary' */ + if (csa->token == T_GENERAL) + binary = 0, scan_token(csa); + else if (csa->token == T_INTEGER) + binary = 0, scan_token(csa); + else if (csa->token == T_BINARY) + binary = 1, scan_token(csa); + else + xassert(csa != csa); + /* parse list of variables (may be empty) */ + while (csa->token == T_NAME) + { /* find the corresponding column */ + j = find_col(csa, csa->image); + /* change kind of the variable */ + glp_set_col_kind(csa->P, j, GLP_IV); + /* set bounds for the binary variable */ + if (binary) +#if 0 /* 07/VIII-2013 */ + { set_lower_bound(csa, j, 0.0); + set_upper_bound(csa, j, 1.0); + } +#else + { set_lower_bound(csa, j, + csa->lb[j] == +DBL_MAX ? 0.0 : csa->lb[j]); + set_upper_bound(csa, j, + csa->ub[j] == -DBL_MAX ? 1.0 : csa->ub[j]); + } +#endif + scan_token(csa); + } + return; +} + +int glp_read_lp(glp_prob *P, const glp_cpxcp *parm, const char *fname) +{ /* read problem data in CPLEX LP format */ + glp_cpxcp _parm; + struct csa _csa, *csa = &_csa; + int ret; + xprintf("Reading problem data from '%s'...\n", fname); + if (parm == NULL) + glp_init_cpxcp(&_parm), parm = &_parm; + /* check control parameters */ + check_parm("glp_read_lp", parm); + /* initialize common storage area */ + csa->P = P; + csa->parm = parm; + csa->fname = fname; + csa->fp = NULL; + if (setjmp(csa->jump)) + { ret = 1; + goto done; + } + csa->count = 0; + csa->c = '\n'; + csa->token = T_EOF; + csa->image[0] = '\0'; + csa->imlen = 0; + csa->value = 0.0; + csa->n_max = 100; + csa->ind = xcalloc(1+csa->n_max, sizeof(int)); + csa->val = xcalloc(1+csa->n_max, sizeof(double)); + csa->flag = xcalloc(1+csa->n_max, sizeof(char)); + memset(&csa->flag[1], 0, csa->n_max * sizeof(char)); + csa->lb = xcalloc(1+csa->n_max, sizeof(double)); + csa->ub = xcalloc(1+csa->n_max, sizeof(double)); +#if 1 /* 27/VII-2013 */ + csa->lb_warn = csa->ub_warn = 0; +#endif + /* erase problem object */ + glp_erase_prob(P); + glp_create_index(P); + /* open input CPLEX LP file */ + csa->fp = glp_open(fname, "r"); + if (csa->fp == NULL) + { xprintf("Unable to open '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + /* scan very first token */ + scan_token(csa); + /* parse definition of the objective function */ + if (!(csa->token == T_MINIMIZE || csa->token == T_MAXIMIZE)) + error(csa, "'minimize' or 'maximize' keyword missing\n"); + parse_objective(csa); + /* parse constraints section */ + if (csa->token != T_SUBJECT_TO) + error(csa, "constraints section missing\n"); + parse_constraints(csa); + /* parse optional bounds section */ + if (csa->token == T_BOUNDS) parse_bounds(csa); + /* parse optional general, integer, and binary sections */ + while (csa->token == T_GENERAL || + csa->token == T_INTEGER || + csa->token == T_BINARY) parse_integer(csa); + /* check for the keyword 'end' */ + if (csa->token == T_END) + scan_token(csa); + else if (csa->token == T_EOF) + warning(csa, "keyword 'end' missing\n"); + else + error(csa, "symbol '%s' in wrong position\n", csa->image); + /* nothing must follow the keyword 'end' (except comments) */ + if (csa->token != T_EOF) + error(csa, "extra symbol(s) detected beyond 'end'\n"); + /* set bounds of variables */ + { int j, type; + double lb, ub; + for (j = 1; j <= P->n; j++) + { lb = csa->lb[j]; + ub = csa->ub[j]; + if (lb == +DBL_MAX) lb = 0.0; /* default lb */ + if (ub == -DBL_MAX) ub = +DBL_MAX; /* default ub */ + if (lb == -DBL_MAX && ub == +DBL_MAX) + type = GLP_FR; + else if (ub == +DBL_MAX) + type = GLP_LO; + else if (lb == -DBL_MAX) + type = GLP_UP; + else if (lb != ub) + type = GLP_DB; + else + type = GLP_FX; + glp_set_col_bnds(csa->P, j, type, lb, ub); + } + } + /* print some statistics */ + xprintf("%d row%s, %d column%s, %d non-zero%s\n", + P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s", + P->nnz, P->nnz == 1 ? "" : "s"); + if (glp_get_num_int(P) > 0) + { int ni = glp_get_num_int(P); + int nb = glp_get_num_bin(P); + if (ni == 1) + { if (nb == 0) + xprintf("One variable is integer\n"); + else + xprintf("One variable is binary\n"); + } + else + { xprintf("%d integer variables, ", ni); + if (nb == 0) + xprintf("none"); + else if (nb == 1) + xprintf("one"); + else if (nb == ni) + xprintf("all"); + else + xprintf("%d", nb); + xprintf(" of which %s binary\n", nb == 1 ? "is" : "are"); + } + } + xprintf("%d lines were read\n", csa->count); + /* problem data has been successfully read */ + glp_delete_index(P); + glp_sort_matrix(P); + ret = 0; +done: if (csa->fp != NULL) glp_close(csa->fp); + xfree(csa->ind); + xfree(csa->val); + xfree(csa->flag); + xfree(csa->lb); + xfree(csa->ub); + if (ret != 0) glp_erase_prob(P); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_write_lp - write problem data in CPLEX LP format +* +* SYNOPSIS +* +* int glp_write_lp(glp_prob *P, const glp_cpxcp *parm, const char +* *fname); +* +* DESCRIPTION +* +* The routine glp_write_lp writes problem data in CPLEX LP format to +* a text file. +* +* The parameter parm is a pointer to the structure glp_cpxcp, which +* specifies control parameters used by the routine. If parm is NULL, +* the routine uses default settings. +* +* The character string fname specifies a name of the text file to be +* written. +* +* RETURNS +* +* If the operation was successful, the routine glp_write_lp returns +* zero. Otherwise, it prints an error message and returns non-zero. */ + +#define csa csa1 + +struct csa +{ /* common storage area */ + glp_prob *P; + /* pointer to problem object */ + const glp_cpxcp *parm; + /* pointer to control parameters */ +}; + +static int check_name(char *name) +{ /* check if specified name is valid for CPLEX LP format */ + if (*name == '.') return 1; + if (isdigit((unsigned char)*name)) return 1; + for (; *name; name++) + { if (!isalnum((unsigned char)*name) && + strchr(CHAR_SET, (unsigned char)*name) == NULL) return 1; + } + return 0; /* name is ok */ +} + +static void adjust_name(char *name) +{ /* attempt to adjust specified name to make it valid for CPLEX LP + format */ + for (; *name; name++) + { if (*name == ' ') + *name = '_'; + else if (*name == '-') + *name = '~'; + else if (*name == '[') + *name = '('; + else if (*name == ']') + *name = ')'; + } + return; +} + +static char *row_name(struct csa *csa, int i, char rname[255+1]) +{ /* construct symbolic name of i-th row (constraint) */ + const char *name; + if (i == 0) + name = glp_get_obj_name(csa->P); + else + name = glp_get_row_name(csa->P, i); + if (name == NULL) goto fake; + strcpy(rname, name); + adjust_name(rname); + if (check_name(rname)) goto fake; + return rname; +fake: if (i == 0) + strcpy(rname, "obj"); + else + sprintf(rname, "r_%d", i); + return rname; +} + +static char *col_name(struct csa *csa, int j, char cname[255+1]) +{ /* construct symbolic name of j-th column (variable) */ + const char *name; + name = glp_get_col_name(csa->P, j); + if (name == NULL) goto fake; + strcpy(cname, name); + adjust_name(cname); + if (check_name(cname)) goto fake; + return cname; +fake: sprintf(cname, "x_%d", j); + return cname; +} + +int glp_write_lp(glp_prob *P, const glp_cpxcp *parm, const char *fname) +{ /* write problem data in CPLEX LP format */ + glp_cpxcp _parm; + struct csa _csa, *csa = &_csa; + glp_file *fp; + GLPROW *row; + GLPCOL *col; + GLPAIJ *aij; + int i, j, len, flag, count, ret; + char line[1000+1], term[500+1], name[255+1]; + xprintf("Writing problem data to '%s'...\n", fname); + if (parm == NULL) + glp_init_cpxcp(&_parm), parm = &_parm; + /* check control parameters */ + check_parm("glp_write_lp", parm); + /* initialize common storage area */ + csa->P = P; + csa->parm = parm; + /* create output CPLEX LP file */ + fp = glp_open(fname, "w"), count = 0; + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + /* write problem name */ + xfprintf(fp, "\\* Problem: %s *\\\n", + P->name == NULL ? "Unknown" : P->name), count++; + xfprintf(fp, "\n"), count++; + /* the problem should contain at least one row and one column */ + if (!(P->m > 0 && P->n > 0)) + { xprintf("Warning: problem has no rows/columns\n"); + xfprintf(fp, "\\* WARNING: PROBLEM HAS NO ROWS/COLUMNS *\\\n"), + count++; + xfprintf(fp, "\n"), count++; + goto skip; + } + /* write the objective function definition */ + if (P->dir == GLP_MIN) + xfprintf(fp, "Minimize\n"), count++; + else if (P->dir == GLP_MAX) + xfprintf(fp, "Maximize\n"), count++; + else + xassert(P != P); + row_name(csa, 0, name); + sprintf(line, " %s:", name); + len = 0; + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + if (col->coef != 0.0 || col->ptr == NULL) + { len++; + col_name(csa, j, name); + if (col->coef == 0.0) + sprintf(term, " + 0 %s", name); /* empty column */ + else if (col->coef == +1.0) + sprintf(term, " + %s", name); + else if (col->coef == -1.0) + sprintf(term, " - %s", name); + else if (col->coef > 0.0) + sprintf(term, " + %.*g %s", DBL_DIG, +col->coef, name); + else + sprintf(term, " - %.*g %s", DBL_DIG, -col->coef, name); + if (strlen(line) + strlen(term) > 72) + xfprintf(fp, "%s\n", line), line[0] = '\0', count++; + strcat(line, term); + } + } + if (len == 0) + { /* empty objective */ + sprintf(term, " 0 %s", col_name(csa, 1, name)); + strcat(line, term); + } + xfprintf(fp, "%s\n", line), count++; + if (P->c0 != 0.0) + xfprintf(fp, "\\* constant term = %.*g *\\\n", DBL_DIG, P->c0), + count++; + xfprintf(fp, "\n"), count++; + /* write the constraints section */ + xfprintf(fp, "Subject To\n"), count++; + for (i = 1; i <= P->m; i++) + { row = P->row[i]; + if (row->type == GLP_FR) continue; /* skip free row */ + row_name(csa, i, name); + sprintf(line, " %s:", name); + /* linear form */ + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { col_name(csa, aij->col->j, name); + if (aij->val == +1.0) + sprintf(term, " + %s", name); + else if (aij->val == -1.0) + sprintf(term, " - %s", name); + else if (aij->val > 0.0) + sprintf(term, " + %.*g %s", DBL_DIG, +aij->val, name); + else + sprintf(term, " - %.*g %s", DBL_DIG, -aij->val, name); + if (strlen(line) + strlen(term) > 72) + xfprintf(fp, "%s\n", line), line[0] = '\0', count++; + strcat(line, term); + } + if (row->type == GLP_DB) + { /* double-bounded (ranged) constraint */ + sprintf(term, " - ~r_%d", i); + if (strlen(line) + strlen(term) > 72) + xfprintf(fp, "%s\n", line), line[0] = '\0', count++; + strcat(line, term); + } + else if (row->ptr == NULL) + { /* empty constraint */ + sprintf(term, " 0 %s", col_name(csa, 1, name)); + strcat(line, term); + } + /* right hand-side */ + if (row->type == GLP_LO) + sprintf(term, " >= %.*g", DBL_DIG, row->lb); + else if (row->type == GLP_UP) + sprintf(term, " <= %.*g", DBL_DIG, row->ub); + else if (row->type == GLP_DB || row->type == GLP_FX) + sprintf(term, " = %.*g", DBL_DIG, row->lb); + else + xassert(row != row); + if (strlen(line) + strlen(term) > 72) + xfprintf(fp, "%s\n", line), line[0] = '\0', count++; + strcat(line, term); + xfprintf(fp, "%s\n", line), count++; + } + xfprintf(fp, "\n"), count++; + /* write the bounds section */ + flag = 0; + for (i = 1; i <= P->m; i++) + { row = P->row[i]; + if (row->type != GLP_DB) continue; + if (!flag) + xfprintf(fp, "Bounds\n"), flag = 1, count++; + xfprintf(fp, " 0 <= ~r_%d <= %.*g\n", + i, DBL_DIG, row->ub - row->lb), count++; + } + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + if (col->type == GLP_LO && col->lb == 0.0) continue; + if (!flag) + xfprintf(fp, "Bounds\n"), flag = 1, count++; + col_name(csa, j, name); + if (col->type == GLP_FR) + xfprintf(fp, " %s free\n", name), count++; + else if (col->type == GLP_LO) + xfprintf(fp, " %s >= %.*g\n", + name, DBL_DIG, col->lb), count++; + else if (col->type == GLP_UP) + xfprintf(fp, " -Inf <= %s <= %.*g\n", + name, DBL_DIG, col->ub), count++; + else if (col->type == GLP_DB) + xfprintf(fp, " %.*g <= %s <= %.*g\n", + DBL_DIG, col->lb, name, DBL_DIG, col->ub), count++; + else if (col->type == GLP_FX) + xfprintf(fp, " %s = %.*g\n", + name, DBL_DIG, col->lb), count++; + else + xassert(col != col); + } + if (flag) xfprintf(fp, "\n"), count++; + /* write the integer section */ + flag = 0; + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + if (col->kind == GLP_CV) continue; + xassert(col->kind == GLP_IV); + if (!flag) + xfprintf(fp, "Generals\n"), flag = 1, count++; + xfprintf(fp, " %s\n", col_name(csa, j, name)), count++; + } + if (flag) xfprintf(fp, "\n"), count++; +skip: /* write the end keyword */ + xfprintf(fp, "End\n"), count++; +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + /* problem data has been successfully written */ + xprintf("%d lines were written\n", count); + ret = 0; +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpdmx.c b/resources/3rdparty/glpk-4.57/src/glpdmx.c new file mode 100644 index 000000000..e8a323da9 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpdmx.c @@ -0,0 +1,1693 @@ +/* glpdmx.c (reading/writing data in DIMACS format) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "misc.h" +#include "prob.h" + +#define xfprintf glp_format + +struct csa +{ /* common storage area */ + jmp_buf jump; + /* label for go to in case of error */ + const char *fname; + /* name of input text file */ + glp_file *fp; + /* stream assigned to input text file */ + int count; + /* line count */ + int c; + /* current character */ + char field[255+1]; + /* data field */ + int empty; + /* warning 'empty line ignored' was printed */ + int nonint; + /* warning 'non-integer data detected' was printed */ +}; + +static void error(struct csa *csa, const char *fmt, ...) +{ /* print error message and terminate processing */ + va_list arg; + xprintf("%s:%d: error: ", csa->fname, csa->count); + va_start(arg, fmt); + xvprintf(fmt, arg); + va_end(arg); + xprintf("\n"); + longjmp(csa->jump, 1); + /* no return */ +} + +static void warning(struct csa *csa, const char *fmt, ...) +{ /* print warning message and continue processing */ + va_list arg; + xprintf("%s:%d: warning: ", csa->fname, csa->count); + va_start(arg, fmt); + xvprintf(fmt, arg); + va_end(arg); + xprintf("\n"); + return; +} + +static void read_char(struct csa *csa) +{ /* read character from input text file */ + int c; + if (csa->c == '\n') csa->count++; + c = glp_getc(csa->fp); + if (c < 0) + { if (glp_ioerr(csa->fp)) + error(csa, "read error - %s", get_err_msg()); + else if (csa->c == '\n') + error(csa, "unexpected end of file"); + else + { warning(csa, "missing final end of line"); + c = '\n'; + } + } + else if (c == '\n') + ; + else if (isspace(c)) + c = ' '; + else if (iscntrl(c)) + error(csa, "invalid control character 0x%02X", c); + csa->c = c; + return; +} + +static void read_designator(struct csa *csa) +{ /* read one-character line designator */ + xassert(csa->c == '\n'); + read_char(csa); + for (;;) + { /* skip preceding white-space characters */ + while (csa->c == ' ') + read_char(csa); + if (csa->c == '\n') + { /* ignore empty line */ + if (!csa->empty) + { warning(csa, "empty line ignored"); + csa->empty = 1; + } + read_char(csa); + } + else if (csa->c == 'c') + { /* skip comment line */ + while (csa->c != '\n') + read_char(csa); + read_char(csa); + } + else + { /* hmm... looks like a line designator */ + csa->field[0] = (char)csa->c, csa->field[1] = '\0'; + /* check that it is followed by a white-space character */ + read_char(csa); + if (!(csa->c == ' ' || csa->c == '\n')) + error(csa, "line designator missing or invalid"); + break; + } + } + return; +} + +static void read_field(struct csa *csa) +{ /* read data field */ + int len = 0; + /* skip preceding white-space characters */ + while (csa->c == ' ') + read_char(csa); + /* scan data field */ + if (csa->c == '\n') + error(csa, "unexpected end of line"); + while (!(csa->c == ' ' || csa->c == '\n')) + { if (len == sizeof(csa->field)-1) + error(csa, "data field '%.15s...' too long", csa->field); + csa->field[len++] = (char)csa->c; + read_char(csa); + } + csa->field[len] = '\0'; + return; +} + +static void end_of_line(struct csa *csa) +{ /* skip white-space characters until end of line */ + while (csa->c == ' ') + read_char(csa); + if (csa->c != '\n') + error(csa, "too many data fields specified"); + return; +} + +static void check_int(struct csa *csa, double num) +{ /* print a warning if non-integer data are detected */ + if (!csa->nonint && num != floor(num)) + { warning(csa, "non-integer data detected"); + csa->nonint = 1; + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_read_mincost - read min-cost flow problem data in DIMACS format +* +* SYNOPSIS +* +* int glp_read_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, +* int a_cost, const char *fname); +* +* DESCRIPTION +* +* The routine glp_read_mincost reads minimum cost flow problem data in +* DIMACS format from a text file. +* +* RETURNS +* +* If the operation was successful, the routine returns zero. Otherwise +* it prints an error message and returns non-zero. */ + +int glp_read_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, + int a_cost, const char *fname) +{ struct csa _csa, *csa = &_csa; + glp_vertex *v; + glp_arc *a; + int i, j, k, nv, na, ret = 0; + double rhs, low, cap, cost; + char *flag = NULL; + if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) + xerror("glp_read_mincost: v_rhs = %d; invalid offset\n", + v_rhs); + if (a_low >= 0 && a_low > G->a_size - (int)sizeof(double)) + xerror("glp_read_mincost: a_low = %d; invalid offset\n", + a_low); + if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) + xerror("glp_read_mincost: a_cap = %d; invalid offset\n", + a_cap); + if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) + xerror("glp_read_mincost: a_cost = %d; invalid offset\n", + a_cost); + glp_erase_graph(G, G->v_size, G->a_size); + if (setjmp(csa->jump)) + { ret = 1; + goto done; + } + csa->fname = fname; + csa->fp = NULL; + csa->count = 0; + csa->c = '\n'; + csa->field[0] = '\0'; + csa->empty = csa->nonint = 0; + xprintf("Reading min-cost flow problem data from '%s'...\n", + fname); + csa->fp = glp_open(fname, "r"); + if (csa->fp == NULL) + { xprintf("Unable to open '%s' - %s\n", fname, get_err_msg()); + longjmp(csa->jump, 1); + } + /* read problem line */ + read_designator(csa); + if (strcmp(csa->field, "p") != 0) + error(csa, "problem line missing or invalid"); + read_field(csa); + if (strcmp(csa->field, "min") != 0) + error(csa, "wrong problem designator; 'min' expected"); + read_field(csa); + if (!(str2int(csa->field, &nv) == 0 && nv >= 0)) + error(csa, "number of nodes missing or invalid"); + read_field(csa); + if (!(str2int(csa->field, &na) == 0 && na >= 0)) + error(csa, "number of arcs missing or invalid"); + xprintf("Flow network has %d node%s and %d arc%s\n", + nv, nv == 1 ? "" : "s", na, na == 1 ? "" : "s"); + if (nv > 0) glp_add_vertices(G, nv); + end_of_line(csa); + /* read node descriptor lines */ + flag = xcalloc(1+nv, sizeof(char)); + memset(&flag[1], 0, nv * sizeof(char)); + if (v_rhs >= 0) + { rhs = 0.0; + for (i = 1; i <= nv; i++) + { v = G->v[i]; + memcpy((char *)v->data + v_rhs, &rhs, sizeof(double)); + } + } + for (;;) + { read_designator(csa); + if (strcmp(csa->field, "n") != 0) break; + read_field(csa); + if (str2int(csa->field, &i) != 0) + error(csa, "node number missing or invalid"); + if (!(1 <= i && i <= nv)) + error(csa, "node number %d out of range", i); + if (flag[i]) + error(csa, "duplicate descriptor of node %d", i); + read_field(csa); + if (str2num(csa->field, &rhs) != 0) + error(csa, "node supply/demand missing or invalid"); + check_int(csa, rhs); + if (v_rhs >= 0) + { v = G->v[i]; + memcpy((char *)v->data + v_rhs, &rhs, sizeof(double)); + } + flag[i] = 1; + end_of_line(csa); + } + xfree(flag), flag = NULL; + /* read arc descriptor lines */ + for (k = 1; k <= na; k++) + { if (k > 1) read_designator(csa); + if (strcmp(csa->field, "a") != 0) + error(csa, "wrong line designator; 'a' expected"); + read_field(csa); + if (str2int(csa->field, &i) != 0) + error(csa, "starting node number missing or invalid"); + if (!(1 <= i && i <= nv)) + error(csa, "starting node number %d out of range", i); + read_field(csa); + if (str2int(csa->field, &j) != 0) + error(csa, "ending node number missing or invalid"); + if (!(1 <= j && j <= nv)) + error(csa, "ending node number %d out of range", j); + read_field(csa); + if (!(str2num(csa->field, &low) == 0 && low >= 0.0)) + error(csa, "lower bound of arc flow missing or invalid"); + check_int(csa, low); + read_field(csa); + if (!(str2num(csa->field, &cap) == 0 && cap >= low)) + error(csa, "upper bound of arc flow missing or invalid"); + check_int(csa, cap); + read_field(csa); + if (str2num(csa->field, &cost) != 0) + error(csa, "per-unit cost of arc flow missing or invalid"); + check_int(csa, cost); + a = glp_add_arc(G, i, j); + if (a_low >= 0) + memcpy((char *)a->data + a_low, &low, sizeof(double)); + if (a_cap >= 0) + memcpy((char *)a->data + a_cap, &cap, sizeof(double)); + if (a_cost >= 0) + memcpy((char *)a->data + a_cost, &cost, sizeof(double)); + end_of_line(csa); + } + xprintf("%d lines were read\n", csa->count); +done: if (ret) glp_erase_graph(G, G->v_size, G->a_size); + if (csa->fp != NULL) glp_close(csa->fp); + if (flag != NULL) xfree(flag); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_write_mincost - write min-cost flow problem data in DIMACS format +* +* SYNOPSIS +* +* int glp_write_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, +* int a_cost, const char *fname); +* +* DESCRIPTION +* +* The routine glp_write_mincost writes minimum cost flow problem data +* in DIMACS format to a text file. +* +* RETURNS +* +* If the operation was successful, the routine returns zero. Otherwise +* it prints an error message and returns non-zero. */ + +int glp_write_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, + int a_cost, const char *fname) +{ glp_file *fp; + glp_vertex *v; + glp_arc *a; + int i, count = 0, ret; + double rhs, low, cap, cost; + if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) + xerror("glp_write_mincost: v_rhs = %d; invalid offset\n", + v_rhs); + if (a_low >= 0 && a_low > G->a_size - (int)sizeof(double)) + xerror("glp_write_mincost: a_low = %d; invalid offset\n", + a_low); + if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) + xerror("glp_write_mincost: a_cap = %d; invalid offset\n", + a_cap); + if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) + xerror("glp_write_mincost: a_cost = %d; invalid offset\n", + a_cost); + xprintf("Writing min-cost flow problem data to '%s'...\n", + fname); + fp = glp_open(fname, "w"); + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xfprintf(fp, "c %s\n", + G->name == NULL ? "unknown" : G->name), count++; + xfprintf(fp, "p min %d %d\n", G->nv, G->na), count++; + if (v_rhs >= 0) + { for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + memcpy(&rhs, (char *)v->data + v_rhs, sizeof(double)); + if (rhs != 0.0) + xfprintf(fp, "n %d %.*g\n", i, DBL_DIG, rhs), count++; + } + } + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { if (a_low >= 0) + memcpy(&low, (char *)a->data + a_low, sizeof(double)); + else + low = 0.0; + if (a_cap >= 0) + memcpy(&cap, (char *)a->data + a_cap, sizeof(double)); + else + cap = 1.0; + if (a_cost >= 0) + memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); + else + cost = 0.0; + xfprintf(fp, "a %d %d %.*g %.*g %.*g\n", + a->tail->i, a->head->i, DBL_DIG, low, DBL_DIG, cap, + DBL_DIG, cost), count++; + } + } + xfprintf(fp, "c eof\n"), count++; +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xprintf("%d lines were written\n", count); + ret = 0; +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_read_maxflow - read maximum flow problem data in DIMACS format +* +* SYNOPSIS +* +* int glp_read_maxflow(glp_graph *G, int *s, int *t, int a_cap, +* const char *fname); +* +* DESCRIPTION +* +* The routine glp_read_maxflow reads maximum flow problem data in +* DIMACS format from a text file. +* +* RETURNS +* +* If the operation was successful, the routine returns zero. Otherwise +* it prints an error message and returns non-zero. */ + +int glp_read_maxflow(glp_graph *G, int *_s, int *_t, int a_cap, + const char *fname) +{ struct csa _csa, *csa = &_csa; + glp_arc *a; + int i, j, k, s, t, nv, na, ret = 0; + double cap; + if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) + xerror("glp_read_maxflow: a_cap = %d; invalid offset\n", + a_cap); + glp_erase_graph(G, G->v_size, G->a_size); + if (setjmp(csa->jump)) + { ret = 1; + goto done; + } + csa->fname = fname; + csa->fp = NULL; + csa->count = 0; + csa->c = '\n'; + csa->field[0] = '\0'; + csa->empty = csa->nonint = 0; + xprintf("Reading maximum flow problem data from '%s'...\n", + fname); + csa->fp = glp_open(fname, "r"); + if (csa->fp == NULL) + { xprintf("Unable to open '%s' - %s\n", fname, get_err_msg()); + longjmp(csa->jump, 1); + } + /* read problem line */ + read_designator(csa); + if (strcmp(csa->field, "p") != 0) + error(csa, "problem line missing or invalid"); + read_field(csa); + if (strcmp(csa->field, "max") != 0) + error(csa, "wrong problem designator; 'max' expected"); + read_field(csa); + if (!(str2int(csa->field, &nv) == 0 && nv >= 2)) + error(csa, "number of nodes missing or invalid"); + read_field(csa); + if (!(str2int(csa->field, &na) == 0 && na >= 0)) + error(csa, "number of arcs missing or invalid"); + xprintf("Flow network has %d node%s and %d arc%s\n", + nv, nv == 1 ? "" : "s", na, na == 1 ? "" : "s"); + if (nv > 0) glp_add_vertices(G, nv); + end_of_line(csa); + /* read node descriptor lines */ + s = t = 0; + for (;;) + { read_designator(csa); + if (strcmp(csa->field, "n") != 0) break; + read_field(csa); + if (str2int(csa->field, &i) != 0) + error(csa, "node number missing or invalid"); + if (!(1 <= i && i <= nv)) + error(csa, "node number %d out of range", i); + read_field(csa); + if (strcmp(csa->field, "s") == 0) + { if (s > 0) + error(csa, "only one source node allowed"); + s = i; + } + else if (strcmp(csa->field, "t") == 0) + { if (t > 0) + error(csa, "only one sink node allowed"); + t = i; + } + else + error(csa, "wrong node designator; 's' or 't' expected"); + if (s > 0 && s == t) + error(csa, "source and sink nodes must be distinct"); + end_of_line(csa); + } + if (s == 0) + error(csa, "source node descriptor missing\n"); + if (t == 0) + error(csa, "sink node descriptor missing\n"); + if (_s != NULL) *_s = s; + if (_t != NULL) *_t = t; + /* read arc descriptor lines */ + for (k = 1; k <= na; k++) + { if (k > 1) read_designator(csa); + if (strcmp(csa->field, "a") != 0) + error(csa, "wrong line designator; 'a' expected"); + read_field(csa); + if (str2int(csa->field, &i) != 0) + error(csa, "starting node number missing or invalid"); + if (!(1 <= i && i <= nv)) + error(csa, "starting node number %d out of range", i); + read_field(csa); + if (str2int(csa->field, &j) != 0) + error(csa, "ending node number missing or invalid"); + if (!(1 <= j && j <= nv)) + error(csa, "ending node number %d out of range", j); + read_field(csa); + if (!(str2num(csa->field, &cap) == 0 && cap >= 0.0)) + error(csa, "arc capacity missing or invalid"); + check_int(csa, cap); + a = glp_add_arc(G, i, j); + if (a_cap >= 0) + memcpy((char *)a->data + a_cap, &cap, sizeof(double)); + end_of_line(csa); + } + xprintf("%d lines were read\n", csa->count); +done: if (ret) glp_erase_graph(G, G->v_size, G->a_size); + if (csa->fp != NULL) glp_close(csa->fp); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_write_maxflow - write maximum flow problem data in DIMACS format +* +* SYNOPSIS +* +* int glp_write_maxflow(glp_graph *G, int s, int t, int a_cap, +* const char *fname); +* +* DESCRIPTION +* +* The routine glp_write_maxflow writes maximum flow problem data in +* DIMACS format to a text file. +* +* RETURNS +* +* If the operation was successful, the routine returns zero. Otherwise +* it prints an error message and returns non-zero. */ + +int glp_write_maxflow(glp_graph *G, int s, int t, int a_cap, + const char *fname) +{ glp_file *fp; + glp_vertex *v; + glp_arc *a; + int i, count = 0, ret; + double cap; + if (!(1 <= s && s <= G->nv)) + xerror("glp_write_maxflow: s = %d; source node number out of r" + "ange\n", s); + if (!(1 <= t && t <= G->nv)) + xerror("glp_write_maxflow: t = %d: sink node number out of ran" + "ge\n", t); + if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) + xerror("glp_write_mincost: a_cap = %d; invalid offset\n", + a_cap); + xprintf("Writing maximum flow problem data to '%s'...\n", + fname); + fp = glp_open(fname, "w"); + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xfprintf(fp, "c %s\n", + G->name == NULL ? "unknown" : G->name), count++; + xfprintf(fp, "p max %d %d\n", G->nv, G->na), count++; + xfprintf(fp, "n %d s\n", s), count++; + xfprintf(fp, "n %d t\n", t), count++; + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { if (a_cap >= 0) + memcpy(&cap, (char *)a->data + a_cap, sizeof(double)); + else + cap = 1.0; + xfprintf(fp, "a %d %d %.*g\n", + a->tail->i, a->head->i, DBL_DIG, cap), count++; + } + } + xfprintf(fp, "c eof\n"), count++; +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xprintf("%d lines were written\n", count); + ret = 0; +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_read_asnprob - read assignment problem data in DIMACS format +* +* SYNOPSIS +* +* int glp_read_asnprob(glp_graph *G, int v_set, int a_cost, +* const char *fname); +* +* DESCRIPTION +* +* The routine glp_read_asnprob reads assignment problem data in DIMACS +* format from a text file. +* +* RETURNS +* +* If the operation was successful, the routine returns zero. Otherwise +* it prints an error message and returns non-zero. */ + +int glp_read_asnprob(glp_graph *G, int v_set, int a_cost, const char + *fname) +{ struct csa _csa, *csa = &_csa; + glp_vertex *v; + glp_arc *a; + int nv, na, n1, i, j, k, ret = 0; + double cost; + char *flag = NULL; + if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) + xerror("glp_read_asnprob: v_set = %d; invalid offset\n", + v_set); + if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) + xerror("glp_read_asnprob: a_cost = %d; invalid offset\n", + a_cost); + glp_erase_graph(G, G->v_size, G->a_size); + if (setjmp(csa->jump)) + { ret = 1; + goto done; + } + csa->fname = fname; + csa->fp = NULL; + csa->count = 0; + csa->c = '\n'; + csa->field[0] = '\0'; + csa->empty = csa->nonint = 0; + xprintf("Reading assignment problem data from '%s'...\n", fname); + csa->fp = glp_open(fname, "r"); + if (csa->fp == NULL) + { xprintf("Unable to open '%s' - %s\n", fname, get_err_msg()); + longjmp(csa->jump, 1); + } + /* read problem line */ + read_designator(csa); + if (strcmp(csa->field, "p") != 0) + error(csa, "problem line missing or invalid"); + read_field(csa); + if (strcmp(csa->field, "asn") != 0) + error(csa, "wrong problem designator; 'asn' expected"); + read_field(csa); + if (!(str2int(csa->field, &nv) == 0 && nv >= 0)) + error(csa, "number of nodes missing or invalid"); + read_field(csa); + if (!(str2int(csa->field, &na) == 0 && na >= 0)) + error(csa, "number of arcs missing or invalid"); + if (nv > 0) glp_add_vertices(G, nv); + end_of_line(csa); + /* read node descriptor lines */ + flag = xcalloc(1+nv, sizeof(char)); + memset(&flag[1], 0, nv * sizeof(char)); + n1 = 0; + for (;;) + { read_designator(csa); + if (strcmp(csa->field, "n") != 0) break; + read_field(csa); + if (str2int(csa->field, &i) != 0) + error(csa, "node number missing or invalid"); + if (!(1 <= i && i <= nv)) + error(csa, "node number %d out of range", i); + if (flag[i]) + error(csa, "duplicate descriptor of node %d", i); + flag[i] = 1, n1++; + end_of_line(csa); + } + xprintf( + "Assignment problem has %d + %d = %d node%s and %d arc%s\n", + n1, nv - n1, nv, nv == 1 ? "" : "s", na, na == 1 ? "" : "s"); + if (v_set >= 0) + { for (i = 1; i <= nv; i++) + { v = G->v[i]; + k = (flag[i] ? 0 : 1); + memcpy((char *)v->data + v_set, &k, sizeof(int)); + } + } + /* read arc descriptor lines */ + for (k = 1; k <= na; k++) + { if (k > 1) read_designator(csa); + if (strcmp(csa->field, "a") != 0) + error(csa, "wrong line designator; 'a' expected"); + read_field(csa); + if (str2int(csa->field, &i) != 0) + error(csa, "starting node number missing or invalid"); + if (!(1 <= i && i <= nv)) + error(csa, "starting node number %d out of range", i); + if (!flag[i]) + error(csa, "node %d cannot be a starting node", i); + read_field(csa); + if (str2int(csa->field, &j) != 0) + error(csa, "ending node number missing or invalid"); + if (!(1 <= j && j <= nv)) + error(csa, "ending node number %d out of range", j); + if (flag[j]) + error(csa, "node %d cannot be an ending node", j); + read_field(csa); + if (str2num(csa->field, &cost) != 0) + error(csa, "arc cost missing or invalid"); + check_int(csa, cost); + a = glp_add_arc(G, i, j); + if (a_cost >= 0) + memcpy((char *)a->data + a_cost, &cost, sizeof(double)); + end_of_line(csa); + } + xprintf("%d lines were read\n", csa->count); +done: if (ret) glp_erase_graph(G, G->v_size, G->a_size); + if (csa->fp != NULL) glp_close(csa->fp); + if (flag != NULL) xfree(flag); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_write_asnprob - write assignment problem data in DIMACS format +* +* SYNOPSIS +* +* int glp_write_asnprob(glp_graph *G, int v_set, int a_cost, +* const char *fname); +* +* DESCRIPTION +* +* The routine glp_write_asnprob writes assignment problem data in +* DIMACS format to a text file. +* +* RETURNS +* +* If the operation was successful, the routine returns zero. Otherwise +* it prints an error message and returns non-zero. */ + +int glp_write_asnprob(glp_graph *G, int v_set, int a_cost, const char + *fname) +{ glp_file *fp; + glp_vertex *v; + glp_arc *a; + int i, k, count = 0, ret; + double cost; + if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) + xerror("glp_write_asnprob: v_set = %d; invalid offset\n", + v_set); + if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) + xerror("glp_write_asnprob: a_cost = %d; invalid offset\n", + a_cost); + xprintf("Writing assignment problem data to '%s'...\n", fname); + fp = glp_open(fname, "w"); + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xfprintf(fp, "c %s\n", + G->name == NULL ? "unknown" : G->name), count++; + xfprintf(fp, "p asn %d %d\n", G->nv, G->na), count++; + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + if (v_set >= 0) + memcpy(&k, (char *)v->data + v_set, sizeof(int)); + else + k = (v->out != NULL ? 0 : 1); + if (k == 0) + xfprintf(fp, "n %d\n", i), count++; + } + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (a = v->out; a != NULL; a = a->t_next) + { if (a_cost >= 0) + memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); + else + cost = 1.0; + xfprintf(fp, "a %d %d %.*g\n", + a->tail->i, a->head->i, DBL_DIG, cost), count++; + } + } + xfprintf(fp, "c eof\n"), count++; +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xprintf("%d lines were written\n", count); + ret = 0; +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_read_ccdata - read graph in DIMACS clique/coloring format +* +* SYNOPSIS +* +* int glp_read_ccdata(glp_graph *G, int v_wgt, const char *fname); +* +* DESCRIPTION +* +* The routine glp_read_ccdata reads an (undirected) graph in DIMACS +* clique/coloring format from a text file. +* +* RETURNS +* +* If the operation was successful, the routine returns zero. Otherwise +* it prints an error message and returns non-zero. */ + +int glp_read_ccdata(glp_graph *G, int v_wgt, const char *fname) +{ struct csa _csa, *csa = &_csa; + glp_vertex *v; + int i, j, k, nv, ne, ret = 0; + double w; + char *flag = NULL; + if (v_wgt >= 0 && v_wgt > G->v_size - (int)sizeof(double)) + xerror("glp_read_ccdata: v_wgt = %d; invalid offset\n", + v_wgt); + glp_erase_graph(G, G->v_size, G->a_size); + if (setjmp(csa->jump)) + { ret = 1; + goto done; + } + csa->fname = fname; + csa->fp = NULL; + csa->count = 0; + csa->c = '\n'; + csa->field[0] = '\0'; + csa->empty = csa->nonint = 0; + xprintf("Reading graph from '%s'...\n", fname); + csa->fp = glp_open(fname, "r"); + if (csa->fp == NULL) + { xprintf("Unable to open '%s' - %s\n", fname, get_err_msg()); + longjmp(csa->jump, 1); + } + /* read problem line */ + read_designator(csa); + if (strcmp(csa->field, "p") != 0) + error(csa, "problem line missing or invalid"); + read_field(csa); + if (strcmp(csa->field, "edge") != 0) + error(csa, "wrong problem designator; 'edge' expected"); + read_field(csa); + if (!(str2int(csa->field, &nv) == 0 && nv >= 0)) + error(csa, "number of vertices missing or invalid"); + read_field(csa); + if (!(str2int(csa->field, &ne) == 0 && ne >= 0)) + error(csa, "number of edges missing or invalid"); + xprintf("Graph has %d vert%s and %d edge%s\n", + nv, nv == 1 ? "ex" : "ices", ne, ne == 1 ? "" : "s"); + if (nv > 0) glp_add_vertices(G, nv); + end_of_line(csa); + /* read node descriptor lines */ + flag = xcalloc(1+nv, sizeof(char)); + memset(&flag[1], 0, nv * sizeof(char)); + if (v_wgt >= 0) + { w = 1.0; + for (i = 1; i <= nv; i++) + { v = G->v[i]; + memcpy((char *)v->data + v_wgt, &w, sizeof(double)); + } + } + for (;;) + { read_designator(csa); + if (strcmp(csa->field, "n") != 0) break; + read_field(csa); + if (str2int(csa->field, &i) != 0) + error(csa, "vertex number missing or invalid"); + if (!(1 <= i && i <= nv)) + error(csa, "vertex number %d out of range", i); + if (flag[i]) + error(csa, "duplicate descriptor of vertex %d", i); + read_field(csa); + if (str2num(csa->field, &w) != 0) + error(csa, "vertex weight missing or invalid"); + check_int(csa, w); + if (v_wgt >= 0) + { v = G->v[i]; + memcpy((char *)v->data + v_wgt, &w, sizeof(double)); + } + flag[i] = 1; + end_of_line(csa); + } + xfree(flag), flag = NULL; + /* read edge descriptor lines */ + for (k = 1; k <= ne; k++) + { if (k > 1) read_designator(csa); + if (strcmp(csa->field, "e") != 0) + error(csa, "wrong line designator; 'e' expected"); + read_field(csa); + if (str2int(csa->field, &i) != 0) + error(csa, "first vertex number missing or invalid"); + if (!(1 <= i && i <= nv)) + error(csa, "first vertex number %d out of range", i); + read_field(csa); + if (str2int(csa->field, &j) != 0) + error(csa, "second vertex number missing or invalid"); + if (!(1 <= j && j <= nv)) + error(csa, "second vertex number %d out of range", j); + glp_add_arc(G, i, j); + end_of_line(csa); + } + xprintf("%d lines were read\n", csa->count); +done: if (ret) glp_erase_graph(G, G->v_size, G->a_size); + if (csa->fp != NULL) glp_close(csa->fp); + if (flag != NULL) xfree(flag); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_write_ccdata - write graph in DIMACS clique/coloring format +* +* SYNOPSIS +* +* int glp_write_ccdata(glp_graph *G, int v_wgt, const char *fname); +* +* DESCRIPTION +* +* The routine glp_write_ccdata writes the specified graph in DIMACS +* clique/coloring format to a text file. +* +* RETURNS +* +* If the operation was successful, the routine returns zero. Otherwise +* it prints an error message and returns non-zero. */ + +int glp_write_ccdata(glp_graph *G, int v_wgt, const char *fname) +{ glp_file *fp; + glp_vertex *v; + glp_arc *e; + int i, count = 0, ret; + double w; + if (v_wgt >= 0 && v_wgt > G->v_size - (int)sizeof(double)) + xerror("glp_write_ccdata: v_wgt = %d; invalid offset\n", + v_wgt); + xprintf("Writing graph to '%s'\n", fname); + fp = glp_open(fname, "w"); + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xfprintf(fp, "c %s\n", + G->name == NULL ? "unknown" : G->name), count++; + xfprintf(fp, "p edge %d %d\n", G->nv, G->na), count++; + if (v_wgt >= 0) + { for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + memcpy(&w, (char *)v->data + v_wgt, sizeof(double)); + if (w != 1.0) + xfprintf(fp, "n %d %.*g\n", i, DBL_DIG, w), count++; + } + } + for (i = 1; i <= G->nv; i++) + { v = G->v[i]; + for (e = v->out; e != NULL; e = e->t_next) + xfprintf(fp, "e %d %d\n", e->tail->i, e->head->i), count++; + } + xfprintf(fp, "c eof\n"), count++; +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xprintf("%d lines were written\n", count); + ret = 0; +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_read_prob - read problem data in GLPK format +* +* SYNOPSIS +* +* int glp_read_prob(glp_prob *P, int flags, const char *fname); +* +* The routine glp_read_prob reads problem data in GLPK LP/MIP format +* from a text file. +* +* RETURNS +* +* If the operation was successful, the routine returns zero. Otherwise +* it prints an error message and returns non-zero. */ + +int glp_read_prob(glp_prob *P, int flags, const char *fname) +{ struct csa _csa, *csa = &_csa; + int mip, m, n, nnz, ne, i, j, k, type, kind, ret, *ln = NULL, + *ia = NULL, *ja = NULL; + double lb, ub, temp, *ar = NULL; + char *rf = NULL, *cf = NULL; + if (P == NULL || P->magic != GLP_PROB_MAGIC) + xerror("glp_read_prob: P = %p; invalid problem object\n", + P); + if (flags != 0) + xerror("glp_read_prob: flags = %d; invalid parameter\n", + flags); + if (fname == NULL) + xerror("glp_read_prob: fname = %d; invalid parameter\n", + fname); + glp_erase_prob(P); + if (setjmp(csa->jump)) + { ret = 1; + goto done; + } + csa->fname = fname; + csa->fp = NULL; + csa->count = 0; + csa->c = '\n'; + csa->field[0] = '\0'; + csa->empty = csa->nonint = 0; + xprintf("Reading problem data from '%s'...\n", fname); + csa->fp = glp_open(fname, "r"); + if (csa->fp == NULL) + { xprintf("Unable to open '%s' - %s\n", fname, get_err_msg()); + longjmp(csa->jump, 1); + } + /* read problem line */ + read_designator(csa); + if (strcmp(csa->field, "p") != 0) + error(csa, "problem line missing or invalid"); + read_field(csa); + if (strcmp(csa->field, "lp") == 0) + mip = 0; + else if (strcmp(csa->field, "mip") == 0) + mip = 1; + else + error(csa, "wrong problem designator; 'lp' or 'mip' expected\n" + ); + read_field(csa); + if (strcmp(csa->field, "min") == 0) + glp_set_obj_dir(P, GLP_MIN); + else if (strcmp(csa->field, "max") == 0) + glp_set_obj_dir(P, GLP_MAX); + else + error(csa, "objective sense missing or invalid"); + read_field(csa); + if (!(str2int(csa->field, &m) == 0 && m >= 0)) + error(csa, "number of rows missing or invalid"); + read_field(csa); + if (!(str2int(csa->field, &n) == 0 && n >= 0)) + error(csa, "number of columns missing or invalid"); + read_field(csa); + if (!(str2int(csa->field, &nnz) == 0 && nnz >= 0)) + error(csa, "number of constraint coefficients missing or inval" + "id"); + if (m > 0) + { glp_add_rows(P, m); + for (i = 1; i <= m; i++) + glp_set_row_bnds(P, i, GLP_FX, 0.0, 0.0); + } + if (n > 0) + { glp_add_cols(P, n); + for (j = 1; j <= n; j++) + { if (!mip) + glp_set_col_bnds(P, j, GLP_LO, 0.0, 0.0); + else + glp_set_col_kind(P, j, GLP_BV); + } + } + end_of_line(csa); + /* allocate working arrays */ + rf = xcalloc(1+m, sizeof(char)); + memset(rf, 0, 1+m); + cf = xcalloc(1+n, sizeof(char)); + memset(cf, 0, 1+n); + ln = xcalloc(1+nnz, sizeof(int)); + ia = xcalloc(1+nnz, sizeof(int)); + ja = xcalloc(1+nnz, sizeof(int)); + ar = xcalloc(1+nnz, sizeof(double)); + /* read descriptor lines */ + ne = 0; + for (;;) + { read_designator(csa); + if (strcmp(csa->field, "i") == 0) + { /* row descriptor */ + read_field(csa); + if (str2int(csa->field, &i) != 0) + error(csa, "row number missing or invalid"); + if (!(1 <= i && i <= m)) + error(csa, "row number out of range"); + read_field(csa); + if (strcmp(csa->field, "f") == 0) + type = GLP_FR; + else if (strcmp(csa->field, "l") == 0) + type = GLP_LO; + else if (strcmp(csa->field, "u") == 0) + type = GLP_UP; + else if (strcmp(csa->field, "d") == 0) + type = GLP_DB; + else if (strcmp(csa->field, "s") == 0) + type = GLP_FX; + else + error(csa, "row type missing or invalid"); + if (type == GLP_LO || type == GLP_DB || type == GLP_FX) + { read_field(csa); + if (str2num(csa->field, &lb) != 0) + error(csa, "row lower bound/fixed value missing or in" + "valid"); + } + else + lb = 0.0; + if (type == GLP_UP || type == GLP_DB) + { read_field(csa); + if (str2num(csa->field, &ub) != 0) + error(csa, "row upper bound missing or invalid"); + } + else + ub = 0.0; + if (rf[i] & 0x01) + error(csa, "duplicate row descriptor"); + glp_set_row_bnds(P, i, type, lb, ub), rf[i] |= 0x01; + } + else if (strcmp(csa->field, "j") == 0) + { /* column descriptor */ + read_field(csa); + if (str2int(csa->field, &j) != 0) + error(csa, "column number missing or invalid"); + if (!(1 <= j && j <= n)) + error(csa, "column number out of range"); + if (!mip) + kind = GLP_CV; + else + { read_field(csa); + if (strcmp(csa->field, "c") == 0) + kind = GLP_CV; + else if (strcmp(csa->field, "i") == 0) + kind = GLP_IV; + else if (strcmp(csa->field, "b") == 0) + { kind = GLP_IV; + type = GLP_DB, lb = 0.0, ub = 1.0; + goto skip; + } + else + error(csa, "column kind missing or invalid"); + } + read_field(csa); + if (strcmp(csa->field, "f") == 0) + type = GLP_FR; + else if (strcmp(csa->field, "l") == 0) + type = GLP_LO; + else if (strcmp(csa->field, "u") == 0) + type = GLP_UP; + else if (strcmp(csa->field, "d") == 0) + type = GLP_DB; + else if (strcmp(csa->field, "s") == 0) + type = GLP_FX; + else + error(csa, "column type missing or invalid"); + if (type == GLP_LO || type == GLP_DB || type == GLP_FX) + { read_field(csa); + if (str2num(csa->field, &lb) != 0) + error(csa, "column lower bound/fixed value missing or" + " invalid"); + } + else + lb = 0.0; + if (type == GLP_UP || type == GLP_DB) + { read_field(csa); + if (str2num(csa->field, &ub) != 0) + error(csa, "column upper bound missing or invalid"); + } + else + ub = 0.0; +skip: if (cf[j] & 0x01) + error(csa, "duplicate column descriptor"); + glp_set_col_kind(P, j, kind); + glp_set_col_bnds(P, j, type, lb, ub), cf[j] |= 0x01; + } + else if (strcmp(csa->field, "a") == 0) + { /* coefficient descriptor */ + read_field(csa); + if (str2int(csa->field, &i) != 0) + error(csa, "row number missing or invalid"); + if (!(0 <= i && i <= m)) + error(csa, "row number out of range"); + read_field(csa); + if (str2int(csa->field, &j) != 0) + error(csa, "column number missing or invalid"); + if (!((i == 0 ? 0 : 1) <= j && j <= n)) + error(csa, "column number out of range"); + read_field(csa); + if (i == 0) + { if (str2num(csa->field, &temp) != 0) + error(csa, "objective %s missing or invalid", + j == 0 ? "constant term" : "coefficient"); + if (cf[j] & 0x10) + error(csa, "duplicate objective %s", + j == 0 ? "constant term" : "coefficient"); + glp_set_obj_coef(P, j, temp), cf[j] |= 0x10; + } + else + { if (str2num(csa->field, &temp) != 0) + error(csa, "constraint coefficient missing or invalid" + ); + if (ne == nnz) + error(csa, "too many constraint coefficient descripto" + "rs"); + ln[++ne] = csa->count; + ia[ne] = i, ja[ne] = j, ar[ne] = temp; + } + } + else if (strcmp(csa->field, "n") == 0) + { /* symbolic name descriptor */ + read_field(csa); + if (strcmp(csa->field, "p") == 0) + { /* problem name */ + read_field(csa); + if (P->name != NULL) + error(csa, "duplicate problem name"); + glp_set_prob_name(P, csa->field); + } + else if (strcmp(csa->field, "z") == 0) + { /* objective name */ + read_field(csa); + if (P->obj != NULL) + error(csa, "duplicate objective name"); + glp_set_obj_name(P, csa->field); + } + else if (strcmp(csa->field, "i") == 0) + { /* row name */ + read_field(csa); + if (str2int(csa->field, &i) != 0) + error(csa, "row number missing or invalid"); + if (!(1 <= i && i <= m)) + error(csa, "row number out of range"); + read_field(csa); + if (P->row[i]->name != NULL) + error(csa, "duplicate row name"); + glp_set_row_name(P, i, csa->field); + } + else if (strcmp(csa->field, "j") == 0) + { /* column name */ + read_field(csa); + if (str2int(csa->field, &j) != 0) + error(csa, "column number missing or invalid"); + if (!(1 <= j && j <= n)) + error(csa, "column number out of range"); + read_field(csa); + if (P->col[j]->name != NULL) + error(csa, "duplicate column name"); + glp_set_col_name(P, j, csa->field); + } + else + error(csa, "object designator missing or invalid"); + } + else if (strcmp(csa->field, "e") == 0) + break; + else + error(csa, "line designator missing or invalid"); + end_of_line(csa); + } + if (ne < nnz) + error(csa, "too few constraint coefficient descriptors"); + xassert(ne == nnz); + k = glp_check_dup(m, n, ne, ia, ja); + xassert(0 <= k && k <= nnz); + if (k > 0) + { csa->count = ln[k]; + error(csa, "duplicate constraint coefficient"); + } + glp_load_matrix(P, ne, ia, ja, ar); + /* print some statistics */ + if (P->name != NULL) + xprintf("Problem: %s\n", P->name); + if (P->obj != NULL) + xprintf("Objective: %s\n", P->obj); + xprintf("%d row%s, %d column%s, %d non-zero%s\n", + m, m == 1 ? "" : "s", n, n == 1 ? "" : "s", nnz, nnz == 1 ? + "" : "s"); + if (glp_get_num_int(P) > 0) + { int ni = glp_get_num_int(P); + int nb = glp_get_num_bin(P); + if (ni == 1) + { if (nb == 0) + xprintf("One variable is integer\n"); + else + xprintf("One variable is binary\n"); + } + else + { xprintf("%d integer variables, ", ni); + if (nb == 0) + xprintf("none"); + else if (nb == 1) + xprintf("one"); + else if (nb == ni) + xprintf("all"); + else + xprintf("%d", nb); + xprintf(" of which %s binary\n", nb == 1 ? "is" : "are"); + } + } + xprintf("%d lines were read\n", csa->count); + /* problem data has been successfully read */ + glp_sort_matrix(P); + ret = 0; +done: if (csa->fp != NULL) glp_close(csa->fp); + if (rf != NULL) xfree(rf); + if (cf != NULL) xfree(cf); + if (ln != NULL) xfree(ln); + if (ia != NULL) xfree(ia); + if (ja != NULL) xfree(ja); + if (ar != NULL) xfree(ar); + if (ret) glp_erase_prob(P); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_write_prob - write problem data in GLPK format +* +* SYNOPSIS +* +* int glp_write_prob(glp_prob *P, int flags, const char *fname); +* +* The routine glp_write_prob writes problem data in GLPK LP/MIP format +* to a text file. +* +* RETURNS +* +* If the operation was successful, the routine returns zero. Otherwise +* it prints an error message and returns non-zero. */ + +int glp_write_prob(glp_prob *P, int flags, const char *fname) +{ glp_file *fp; + GLPROW *row; + GLPCOL *col; + GLPAIJ *aij; + int mip, i, j, count, ret; + if (P == NULL || P->magic != GLP_PROB_MAGIC) + xerror("glp_write_prob: P = %p; invalid problem object\n", + P); + if (flags != 0) + xerror("glp_write_prob: flags = %d; invalid parameter\n", + flags); + if (fname == NULL) + xerror("glp_write_prob: fname = %d; invalid parameter\n", + fname); + xprintf("Writing problem data to '%s'...\n", fname); + fp = glp_open(fname, "w"), count = 0; + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + /* write problem line */ + mip = (glp_get_num_int(P) > 0); + xfprintf(fp, "p %s %s %d %d %d\n", !mip ? "lp" : "mip", + P->dir == GLP_MIN ? "min" : P->dir == GLP_MAX ? "max" : "???", + P->m, P->n, P->nnz), count++; + if (P->name != NULL) + xfprintf(fp, "n p %s\n", P->name), count++; + if (P->obj != NULL) + xfprintf(fp, "n z %s\n", P->obj), count++; + /* write row descriptors */ + for (i = 1; i <= P->m; i++) + { row = P->row[i]; + if (row->type == GLP_FX && row->lb == 0.0) + goto skip1; + xfprintf(fp, "i %d ", i), count++; + if (row->type == GLP_FR) + xfprintf(fp, "f\n"); + else if (row->type == GLP_LO) + xfprintf(fp, "l %.*g\n", DBL_DIG, row->lb); + else if (row->type == GLP_UP) + xfprintf(fp, "u %.*g\n", DBL_DIG, row->ub); + else if (row->type == GLP_DB) + xfprintf(fp, "d %.*g %.*g\n", DBL_DIG, row->lb, DBL_DIG, + row->ub); + else if (row->type == GLP_FX) + xfprintf(fp, "s %.*g\n", DBL_DIG, row->lb); + else + xassert(row != row); +skip1: if (row->name != NULL) + xfprintf(fp, "n i %d %s\n", i, row->name), count++; + } + /* write column descriptors */ + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + if (!mip && col->type == GLP_LO && col->lb == 0.0) + goto skip2; + if (mip && col->kind == GLP_IV && col->type == GLP_DB && + col->lb == 0.0 && col->ub == 1.0) + goto skip2; + xfprintf(fp, "j %d ", j), count++; + if (mip) + { if (col->kind == GLP_CV) + xfprintf(fp, "c "); + else if (col->kind == GLP_IV) + xfprintf(fp, "i "); + else + xassert(col != col); + } + if (col->type == GLP_FR) + xfprintf(fp, "f\n"); + else if (col->type == GLP_LO) + xfprintf(fp, "l %.*g\n", DBL_DIG, col->lb); + else if (col->type == GLP_UP) + xfprintf(fp, "u %.*g\n", DBL_DIG, col->ub); + else if (col->type == GLP_DB) + xfprintf(fp, "d %.*g %.*g\n", DBL_DIG, col->lb, DBL_DIG, + col->ub); + else if (col->type == GLP_FX) + xfprintf(fp, "s %.*g\n", DBL_DIG, col->lb); + else + xassert(col != col); +skip2: if (col->name != NULL) + xfprintf(fp, "n j %d %s\n", j, col->name), count++; + } + /* write objective coefficient descriptors */ + if (P->c0 != 0.0) + xfprintf(fp, "a 0 0 %.*g\n", DBL_DIG, P->c0), count++; + for (j = 1; j <= P->n; j++) + { col = P->col[j]; + if (col->coef != 0.0) + xfprintf(fp, "a 0 %d %.*g\n", j, DBL_DIG, col->coef), + count++; + } + /* write constraint coefficient descriptors */ + for (i = 1; i <= P->m; i++) + { row = P->row[i]; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + xfprintf(fp, "a %d %d %.*g\n", i, aij->col->j, DBL_DIG, + aij->val), count++; + } + /* write end line */ + xfprintf(fp, "e o f\n"), count++; +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xprintf("%d lines were written\n", count); + ret = 0; +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/**********************************************************************/ + +int glp_read_cnfsat(glp_prob *P, const char *fname) +{ /* read CNF-SAT problem data in DIMACS format */ + struct csa _csa, *csa = &_csa; + int m, n, i, j, len, neg, rhs, ret = 0, *ind = NULL; + double *val = NULL; + char *map = NULL; + if (P == NULL || P->magic != GLP_PROB_MAGIC) + xerror("glp_read_cnfsat: P = %p; invalid problem object\n", + P); + if (fname == NULL) + xerror("glp_read_cnfsat: fname = %p; invalid parameter\n", + fname); + glp_erase_prob(P); + if (setjmp(csa->jump)) + { ret = 1; + goto done; + } + csa->fname = fname; + csa->fp = NULL; + csa->count = 0; + csa->c = '\n'; + csa->field[0] = '\0'; + csa->empty = csa->nonint = 0; + xprintf("Reading CNF-SAT problem data from '%s'...\n", fname); + csa->fp = glp_open(fname, "r"); + if (csa->fp == NULL) + { xprintf("Unable to open '%s' - %s\n", fname, get_err_msg()); + longjmp(csa->jump, 1); + } + /* read problem line */ + read_designator(csa); + if (strcmp(csa->field, "p") != 0) + error(csa, "problem line missing or invalid"); + read_field(csa); + if (strcmp(csa->field, "cnf") != 0) + error(csa, "wrong problem designator; 'cnf' expected\n"); + read_field(csa); + if (!(str2int(csa->field, &n) == 0 && n >= 0)) + error(csa, "number of variables missing or invalid\n"); + read_field(csa); + if (!(str2int(csa->field, &m) == 0 && m >= 0)) + error(csa, "number of clauses missing or invalid\n"); + xprintf("Instance has %d variable%s and %d clause%s\n", + n, n == 1 ? "" : "s", m, m == 1 ? "" : "s"); + end_of_line(csa); + if (m > 0) + glp_add_rows(P, m); + if (n > 0) + { glp_add_cols(P, n); + for (j = 1; j <= n; j++) + glp_set_col_kind(P, j, GLP_BV); + } + /* allocate working arrays */ + ind = xcalloc(1+n, sizeof(int)); + val = xcalloc(1+n, sizeof(double)); + map = xcalloc(1+n, sizeof(char)); + for (j = 1; j <= n; j++) map[j] = 0; + /* read clauses */ + for (i = 1; i <= m; i++) + { /* read i-th clause */ + len = 0, rhs = 1; + for (;;) + { /* skip white-space characters */ + while (csa->c == ' ' || csa->c == '\n') + read_char(csa); + /* read term */ + read_field(csa); + if (str2int(csa->field, &j) != 0) + error(csa, "variable number missing or invalid\n"); + if (j > 0) + neg = 0; + else if (j < 0) + neg = 1, j = -j, rhs--; + else + break; + if (!(1 <= j && j <= n)) + error(csa, "variable number out of range\n"); + if (map[j]) + error(csa, "duplicate variable number\n"); + len++, ind[len] = j, val[len] = (neg ? -1.0 : +1.0); + map[j] = 1; + } + glp_set_row_bnds(P, i, GLP_LO, (double)rhs, 0.0); + glp_set_mat_row(P, i, len, ind, val); + while (len > 0) map[ind[len--]] = 0; + } + xprintf("%d lines were read\n", csa->count); + /* problem data has been successfully read */ + glp_sort_matrix(P); +done: if (csa->fp != NULL) glp_close(csa->fp); + if (ind != NULL) xfree(ind); + if (val != NULL) xfree(val); + if (map != NULL) xfree(map); + if (ret) glp_erase_prob(P); + return ret; +} + +/**********************************************************************/ + +int glp_check_cnfsat(glp_prob *P) +{ /* check for CNF-SAT problem instance */ + int m = P->m; + int n = P->n; + GLPROW *row; + GLPCOL *col; + GLPAIJ *aij; + int i, j, neg; + if (P == NULL || P->magic != GLP_PROB_MAGIC) + xerror("glp_check_cnfsat: P = %p; invalid problem object\n", + P); + /* check columns */ + for (j = 1; j <= n; j++) + { col = P->col[j]; + /* the variable should be binary */ + if (!(col->kind == GLP_IV && col->type == GLP_DB && + col->lb == 0.0 && col->ub == 1.0)) + return 1; + } + /* objective function should be zero */ + if (P->c0 != 0.0) + return 2; + for (j = 1; j <= n; j++) + { col = P->col[j]; + if (col->coef != 0.0) + return 3; + } + /* check rows */ + for (i = 1; i <= m; i++) + { row = P->row[i]; + /* the row should be of ">=" type */ + if (row->type != GLP_LO) + return 4; + /* check constraint coefficients */ + neg = 0; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { /* the constraint coefficient should be +1 or -1 */ + if (aij->val == +1.0) + ; + else if (aij->val == -1.0) + neg++; + else + return 5; + } + /* the right-hand side should be (1 - neg), where neg is the + number of negative constraint coefficients in the row */ + if (row->lb != (double)(1 - neg)) + return 6; + } + /* congratulations; this is CNF-SAT */ + return 0; +} + +/**********************************************************************/ + +int glp_write_cnfsat(glp_prob *P, const char *fname) +{ /* write CNF-SAT problem data in DIMACS format */ + glp_file *fp = NULL; + GLPAIJ *aij; + int i, j, len, count = 0, ret; + char s[50]; + if (P == NULL || P->magic != GLP_PROB_MAGIC) + xerror("glp_write_cnfsat: P = %p; invalid problem object\n", + P); + if (glp_check_cnfsat(P) != 0) + { xprintf("glp_write_cnfsat: problem object does not encode CNF-" + "SAT instance\n"); + ret = 1; + goto done; + } + xprintf("Writing CNF-SAT problem data to '%s'...\n", fname); + fp = glp_open(fname, "w"); + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xfprintf(fp, "c %s\n", + P->name == NULL ? "unknown" : P->name), count++; + xfprintf(fp, "p cnf %d %d\n", P->n, P->m), count++; + for (i = 1; i <= P->m; i++) + { len = 0; + for (aij = P->row[i]->ptr; aij != NULL; aij = aij->r_next) + { j = aij->col->j; + if (aij->val < 0.0) j = -j; + sprintf(s, "%d", j); + if (len > 0 && len + 1 + strlen(s) > 72) + xfprintf(fp, "\n"), count++, len = 0; + xfprintf(fp, "%s%s", len == 0 ? "" : " ", s); + if (len > 0) len++; + len += strlen(s); + } + if (len > 0 && len + 1 + 1 > 72) + xfprintf(fp, "\n"), count++, len = 0; + xfprintf(fp, "%s0\n", len == 0 ? "" : " "), count++; + } + xfprintf(fp, "c eof\n"), count++; +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + xprintf("%d lines were written\n", count); + ret = 0; +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpgmp.c b/resources/3rdparty/glpk-4.57/src/glpgmp.c new file mode 100644 index 000000000..95c5159bd --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpgmp.c @@ -0,0 +1,1116 @@ +/* glpgmp.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#define _GLPSTD_STDIO +#if 1 /* 11/VI-2013 */ +#include "bignum.h" +#endif +#include "dmp.h" +#include "glpgmp.h" +#include "env.h" +#define xfault xerror + +#ifdef HAVE_GMP /* use GNU MP bignum library */ + +int gmp_pool_count(void) { return 0; } + +void gmp_free_mem(void) { return; } + +#else /* use GLPK bignum module */ + +static DMP *gmp_pool = NULL; +static int gmp_size = 0; +static unsigned short *gmp_work = NULL; + +void *gmp_get_atom(int size) +{ if (gmp_pool == NULL) + gmp_pool = dmp_create_pool(); + return dmp_get_atom(gmp_pool, size); +} + +void gmp_free_atom(void *ptr, int size) +{ xassert(gmp_pool != NULL); + dmp_free_atom(gmp_pool, ptr, size); + return; +} + +int gmp_pool_count(void) +{ if (gmp_pool == NULL) + return 0; + else +#if 0 /* 10/VI-2013 */ + return dmp_in_use(gmp_pool).lo; +#else + return dmp_in_use(gmp_pool); +#endif +} + +unsigned short *gmp_get_work(int size) +{ xassert(size > 0); + if (gmp_size < size) + { if (gmp_size == 0) + { xassert(gmp_work == NULL); + gmp_size = 100; + } + else + { xassert(gmp_work != NULL); + xfree(gmp_work); + } + while (gmp_size < size) gmp_size += gmp_size; + gmp_work = xcalloc(gmp_size, sizeof(unsigned short)); + } + return gmp_work; +} + +void gmp_free_mem(void) +{ if (gmp_pool != NULL) dmp_delete_pool(gmp_pool); + if (gmp_work != NULL) xfree(gmp_work); + gmp_pool = NULL; + gmp_size = 0; + gmp_work = NULL; + return; +} + +/*====================================================================*/ + +mpz_t _mpz_init(void) +{ /* initialize x, and set its value to 0 */ + mpz_t x; + x = gmp_get_atom(sizeof(struct mpz)); + x->val = 0; + x->ptr = NULL; + return x; +} + +void mpz_clear(mpz_t x) +{ /* free the space occupied by x */ + mpz_set_si(x, 0); + xassert(x->ptr == NULL); + /* free the number descriptor */ + gmp_free_atom(x, sizeof(struct mpz)); + return; +} + +void mpz_set(mpz_t z, mpz_t x) +{ /* set the value of z from x */ + struct mpz_seg *e, *ee, *es; + if (z != x) + { mpz_set_si(z, 0); + z->val = x->val; + xassert(z->ptr == NULL); + for (e = x->ptr, es = NULL; e != NULL; e = e->next) + { ee = gmp_get_atom(sizeof(struct mpz_seg)); + memcpy(ee->d, e->d, 12); + ee->next = NULL; + if (z->ptr == NULL) + z->ptr = ee; + else + es->next = ee; + es = ee; + } + } + return; +} + +void mpz_set_si(mpz_t x, int val) +{ /* set the value of x to val */ + struct mpz_seg *e; + /* free existing segments, if any */ + while (x->ptr != NULL) + { e = x->ptr; + x->ptr = e->next; + gmp_free_atom(e, sizeof(struct mpz_seg)); + } + /* assign new value */ + if (val == 0x80000000) + { /* long format is needed */ + x->val = -1; + x->ptr = e = gmp_get_atom(sizeof(struct mpz_seg)); + memset(e->d, 0, 12); + e->d[1] = 0x8000; + e->next = NULL; + } + else + { /* short format is enough */ + x->val = val; + } + return; +} + +double mpz_get_d(mpz_t x) +{ /* convert x to a double, truncating if necessary */ + struct mpz_seg *e; + int j; + double val, deg; + if (x->ptr == NULL) + val = (double)x->val; + else + { xassert(x->val != 0); + val = 0.0; + deg = 1.0; + for (e = x->ptr; e != NULL; e = e->next) + { for (j = 0; j <= 5; j++) + { val += deg * (double)((int)e->d[j]); + deg *= 65536.0; + } + } + if (x->val < 0) val = - val; + } + return val; +} + +double mpz_get_d_2exp(int *exp, mpz_t x) +{ /* convert x to a double, truncating if necessary (i.e. rounding + towards zero), and returning the exponent separately; + the return value is in the range 0.5 <= |d| < 1 and the + exponent is stored to *exp; d*2^exp is the (truncated) x value; + if x is zero, the return is 0.0 and 0 is stored to *exp; + this is similar to the standard C frexp function */ + struct mpz_seg *e; + int j, n, n1; + double val; + if (x->ptr == NULL) + val = (double)x->val, n = 0; + else + { xassert(x->val != 0); + val = 0.0, n = 0; + for (e = x->ptr; e != NULL; e = e->next) + { for (j = 0; j <= 5; j++) + { val += (double)((int)e->d[j]); + val /= 65536.0, n += 16; + } + } + if (x->val < 0) val = - val; + } + val = frexp(val, &n1); + *exp = n + n1; + return val; +} + +void mpz_swap(mpz_t x, mpz_t y) +{ /* swap the values x and y efficiently */ + int val; + void *ptr; + val = x->val, ptr = x->ptr; + x->val = y->val, x->ptr = y->ptr; + y->val = val, y->ptr = ptr; + return; +} + +static void normalize(mpz_t x) +{ /* normalize integer x that includes removing non-significant + (leading) zeros and converting to short format, if possible */ + struct mpz_seg *es, *e; + /* if the integer is in short format, it remains unchanged */ + if (x->ptr == NULL) + { xassert(x->val != 0x80000000); + goto done; + } + xassert(x->val == +1 || x->val == -1); + /* find the last (most significant) non-zero segment */ + es = NULL; + for (e = x->ptr; e != NULL; e = e->next) + { if (e->d[0] || e->d[1] || e->d[2] || + e->d[3] || e->d[4] || e->d[5]) es = e; + } + /* if all segments contain zeros, the integer is zero */ + if (es == NULL) + { mpz_set_si(x, 0); + goto done; + } + /* remove non-significant (leading) zero segments */ + while (es->next != NULL) + { e = es->next; + es->next = e->next; + gmp_free_atom(e, sizeof(struct mpz_seg)); + } + /* convert the integer to short format, if possible */ + e = x->ptr; + if (e->next == NULL && e->d[1] <= 0x7FFF && + !e->d[2] && !e->d[3] && !e->d[4] && !e->d[5]) + { int val; + val = (int)e->d[0] + ((int)e->d[1] << 16); + if (x->val < 0) val = - val; + mpz_set_si(x, val); + } +done: return; +} + +void mpz_add(mpz_t z, mpz_t x, mpz_t y) +{ /* set z to x + y */ + static struct mpz_seg zero = { { 0, 0, 0, 0, 0, 0 }, NULL }; + struct mpz_seg dumx, dumy, *ex, *ey, *ez, *es, *ee; + int k, sx, sy, sz; + unsigned int t; + /* if [x] = 0 then [z] = [y] */ + if (x->val == 0) + { xassert(x->ptr == NULL); + mpz_set(z, y); + goto done; + } + /* if [y] = 0 then [z] = [x] */ + if (y->val == 0) + { xassert(y->ptr == NULL); + mpz_set(z, x); + goto done; + } + /* special case when both [x] and [y] are in short format */ + if (x->ptr == NULL && y->ptr == NULL) + { int xval = x->val, yval = y->val, zval = x->val + y->val; + xassert(xval != 0x80000000 && yval != 0x80000000); + if (!(xval > 0 && yval > 0 && zval <= 0 || + xval < 0 && yval < 0 && zval >= 0)) + { mpz_set_si(z, zval); + goto done; + } + } + /* convert [x] to long format, if necessary */ + if (x->ptr == NULL) + { xassert(x->val != 0x80000000); + if (x->val >= 0) + { sx = +1; + t = (unsigned int)(+ x->val); + } + else + { sx = -1; + t = (unsigned int)(- x->val); + } + ex = &dumx; + ex->d[0] = (unsigned short)t; + ex->d[1] = (unsigned short)(t >> 16); + ex->d[2] = ex->d[3] = ex->d[4] = ex->d[5] = 0; + ex->next = NULL; + } + else + { sx = x->val; + xassert(sx == +1 || sx == -1); + ex = x->ptr; + } + /* convert [y] to long format, if necessary */ + if (y->ptr == NULL) + { xassert(y->val != 0x80000000); + if (y->val >= 0) + { sy = +1; + t = (unsigned int)(+ y->val); + } + else + { sy = -1; + t = (unsigned int)(- y->val); + } + ey = &dumy; + ey->d[0] = (unsigned short)t; + ey->d[1] = (unsigned short)(t >> 16); + ey->d[2] = ey->d[3] = ey->d[4] = ey->d[5] = 0; + ey->next = NULL; + } + else + { sy = y->val; + xassert(sy == +1 || sy == -1); + ey = y->ptr; + } + /* main fragment */ + sz = sx; + ez = es = NULL; + if (sx > 0 && sy > 0 || sx < 0 && sy < 0) + { /* [x] and [y] have identical signs -- addition */ + t = 0; + for (; ex || ey; ex = ex->next, ey = ey->next) + { if (ex == NULL) ex = &zero; + if (ey == NULL) ey = &zero; + ee = gmp_get_atom(sizeof(struct mpz_seg)); + for (k = 0; k <= 5; k++) + { t += (unsigned int)ex->d[k]; + t += (unsigned int)ey->d[k]; + ee->d[k] = (unsigned short)t; + t >>= 16; + } + ee->next = NULL; + if (ez == NULL) + ez = ee; + else + es->next = ee; + es = ee; + } + if (t) + { /* overflow -- one extra digit is needed */ + ee = gmp_get_atom(sizeof(struct mpz_seg)); + ee->d[0] = 1; + ee->d[1] = ee->d[2] = ee->d[3] = ee->d[4] = ee->d[5] = 0; + ee->next = NULL; + xassert(es != NULL); + es->next = ee; + } + } + else + { /* [x] and [y] have different signs -- subtraction */ + t = 1; + for (; ex || ey; ex = ex->next, ey = ey->next) + { if (ex == NULL) ex = &zero; + if (ey == NULL) ey = &zero; + ee = gmp_get_atom(sizeof(struct mpz_seg)); + for (k = 0; k <= 5; k++) + { t += (unsigned int)ex->d[k]; + t += (0xFFFF - (unsigned int)ey->d[k]); + ee->d[k] = (unsigned short)t; + t >>= 16; + } + ee->next = NULL; + if (ez == NULL) + ez = ee; + else + es->next = ee; + es = ee; + } + if (!t) + { /* |[x]| < |[y]| -- result in complement coding */ + sz = - sz; + t = 1; + for (ee = ez; ee != NULL; ee = ee->next) + for (k = 0; k <= 5; k++) + { t += (0xFFFF - (unsigned int)ee->d[k]); + ee->d[k] = (unsigned short)t; + t >>= 16; + } + } + } + /* contruct and normalize result */ + mpz_set_si(z, 0); + z->val = sz; + z->ptr = ez; + normalize(z); +done: return; +} + +void mpz_sub(mpz_t z, mpz_t x, mpz_t y) +{ /* set z to x - y */ + if (x == y) + mpz_set_si(z, 0); + else + { y->val = - y->val; + mpz_add(z, x, y); + if (y != z) y->val = - y->val; + } + return; +} + +void mpz_mul(mpz_t z, mpz_t x, mpz_t y) +{ /* set z to x * y */ + struct mpz_seg dumx, dumy, *ex, *ey, *es, *e; + int sx, sy, k, nx, ny, n; + unsigned int t; + unsigned short *work, *wx, *wy; + /* if [x] = 0 then [z] = 0 */ + if (x->val == 0) + { xassert(x->ptr == NULL); + mpz_set_si(z, 0); + goto done; + } + /* if [y] = 0 then [z] = 0 */ + if (y->val == 0) + { xassert(y->ptr == NULL); + mpz_set_si(z, 0); + goto done; + } + /* special case when both [x] and [y] are in short format */ + if (x->ptr == NULL && y->ptr == NULL) + { int xval = x->val, yval = y->val, sz = +1; + xassert(xval != 0x80000000 && yval != 0x80000000); + if (xval < 0) xval = - xval, sz = - sz; + if (yval < 0) yval = - yval, sz = - sz; + if (xval <= 0x7FFFFFFF / yval) + { mpz_set_si(z, sz * (xval * yval)); + goto done; + } + } + /* convert [x] to long format, if necessary */ + if (x->ptr == NULL) + { xassert(x->val != 0x80000000); + if (x->val >= 0) + { sx = +1; + t = (unsigned int)(+ x->val); + } + else + { sx = -1; + t = (unsigned int)(- x->val); + } + ex = &dumx; + ex->d[0] = (unsigned short)t; + ex->d[1] = (unsigned short)(t >> 16); + ex->d[2] = ex->d[3] = ex->d[4] = ex->d[5] = 0; + ex->next = NULL; + } + else + { sx = x->val; + xassert(sx == +1 || sx == -1); + ex = x->ptr; + } + /* convert [y] to long format, if necessary */ + if (y->ptr == NULL) + { xassert(y->val != 0x80000000); + if (y->val >= 0) + { sy = +1; + t = (unsigned int)(+ y->val); + } + else + { sy = -1; + t = (unsigned int)(- y->val); + } + ey = &dumy; + ey->d[0] = (unsigned short)t; + ey->d[1] = (unsigned short)(t >> 16); + ey->d[2] = ey->d[3] = ey->d[4] = ey->d[5] = 0; + ey->next = NULL; + } + else + { sy = y->val; + xassert(sy == +1 || sy == -1); + ey = y->ptr; + } + /* determine the number of digits of [x] */ + nx = n = 0; + for (e = ex; e != NULL; e = e->next) + for (k = 0; k <= 5; k++) + { n++; + if (e->d[k]) nx = n; + } + xassert(nx > 0); + /* determine the number of digits of [y] */ + ny = n = 0; + for (e = ey; e != NULL; e = e->next) + for (k = 0; k <= 5; k++) + { n++; + if (e->d[k]) ny = n; + } + xassert(ny > 0); + /* we need working array containing at least nx+ny+ny places */ + work = gmp_get_work(nx+ny+ny); + /* load digits of [x] */ + wx = &work[0]; + for (n = 0; n < nx; n++) wx[ny+n] = 0; + for (n = 0, e = ex; e != NULL; e = e->next) + for (k = 0; k <= 5; k++, n++) + if (e->d[k]) wx[ny+n] = e->d[k]; + /* load digits of [y] */ + wy = &work[nx+ny]; + for (n = 0; n < ny; n++) wy[n] = 0; + for (n = 0, e = ey; e != NULL; e = e->next) + for (k = 0; k <= 5; k++, n++) + if (e->d[k]) wy[n] = e->d[k]; + /* compute [x] * [y] */ + bigmul(nx, ny, wx, wy); + /* construct and normalize result */ + mpz_set_si(z, 0); + z->val = sx * sy; + es = NULL; + k = 6; + for (n = 0; n < nx+ny; n++) + { if (k > 5) + { e = gmp_get_atom(sizeof(struct mpz_seg)); + e->d[0] = e->d[1] = e->d[2] = 0; + e->d[3] = e->d[4] = e->d[5] = 0; + e->next = NULL; + if (z->ptr == NULL) + z->ptr = e; + else + es->next = e; + es = e; + k = 0; + } + es->d[k++] = wx[n]; + } + normalize(z); +done: return; +} + +void mpz_neg(mpz_t z, mpz_t x) +{ /* set z to 0 - x */ + mpz_set(z, x); + z->val = - z->val; + return; +} + +void mpz_abs(mpz_t z, mpz_t x) +{ /* set z to the absolute value of x */ + mpz_set(z, x); + if (z->val < 0) z->val = - z->val; + return; +} + +void mpz_div(mpz_t q, mpz_t r, mpz_t x, mpz_t y) +{ /* divide x by y, forming quotient q and/or remainder r + if q = NULL then quotient is not stored; if r = NULL then + remainder is not stored + the sign of quotient is determined as in algebra while the + sign of remainder is the same as the sign of dividend: + +26 : +7 = +3, remainder is +5 + -26 : +7 = -3, remainder is -5 + +26 : -7 = -3, remainder is +5 + -26 : -7 = +3, remainder is -5 */ + struct mpz_seg dumx, dumy, *ex, *ey, *es, *e; + int sx, sy, k, nx, ny, n; + unsigned int t; + unsigned short *work, *wx, *wy; + /* divide by zero is not allowed */ + if (y->val == 0) + { xassert(y->ptr == NULL); + xfault("mpz_div: divide by zero not allowed\n"); + } + /* if [x] = 0 then [q] = [r] = 0 */ + if (x->val == 0) + { xassert(x->ptr == NULL); + if (q != NULL) mpz_set_si(q, 0); + if (r != NULL) mpz_set_si(r, 0); + goto done; + } + /* special case when both [x] and [y] are in short format */ + if (x->ptr == NULL && y->ptr == NULL) + { int xval = x->val, yval = y->val; + xassert(xval != 0x80000000 && yval != 0x80000000); + if (q != NULL) mpz_set_si(q, xval / yval); + if (r != NULL) mpz_set_si(r, xval % yval); + goto done; + } + /* convert [x] to long format, if necessary */ + if (x->ptr == NULL) + { xassert(x->val != 0x80000000); + if (x->val >= 0) + { sx = +1; + t = (unsigned int)(+ x->val); + } + else + { sx = -1; + t = (unsigned int)(- x->val); + } + ex = &dumx; + ex->d[0] = (unsigned short)t; + ex->d[1] = (unsigned short)(t >> 16); + ex->d[2] = ex->d[3] = ex->d[4] = ex->d[5] = 0; + ex->next = NULL; + } + else + { sx = x->val; + xassert(sx == +1 || sx == -1); + ex = x->ptr; + } + /* convert [y] to long format, if necessary */ + if (y->ptr == NULL) + { xassert(y->val != 0x80000000); + if (y->val >= 0) + { sy = +1; + t = (unsigned int)(+ y->val); + } + else + { sy = -1; + t = (unsigned int)(- y->val); + } + ey = &dumy; + ey->d[0] = (unsigned short)t; + ey->d[1] = (unsigned short)(t >> 16); + ey->d[2] = ey->d[3] = ey->d[4] = ey->d[5] = 0; + ey->next = NULL; + } + else + { sy = y->val; + xassert(sy == +1 || sy == -1); + ey = y->ptr; + } + /* determine the number of digits of [x] */ + nx = n = 0; + for (e = ex; e != NULL; e = e->next) + for (k = 0; k <= 5; k++) + { n++; + if (e->d[k]) nx = n; + } + xassert(nx > 0); + /* determine the number of digits of [y] */ + ny = n = 0; + for (e = ey; e != NULL; e = e->next) + for (k = 0; k <= 5; k++) + { n++; + if (e->d[k]) ny = n; + } + xassert(ny > 0); + /* if nx < ny then [q] = 0 and [r] = [x] */ + if (nx < ny) + { if (r != NULL) mpz_set(r, x); + if (q != NULL) mpz_set_si(q, 0); + goto done; + } + /* we need working array containing at least nx+ny+1 places */ + work = gmp_get_work(nx+ny+1); + /* load digits of [x] */ + wx = &work[0]; + for (n = 0; n < nx; n++) wx[n] = 0; + for (n = 0, e = ex; e != NULL; e = e->next) + for (k = 0; k <= 5; k++, n++) + if (e->d[k]) wx[n] = e->d[k]; + /* load digits of [y] */ + wy = &work[nx+1]; + for (n = 0; n < ny; n++) wy[n] = 0; + for (n = 0, e = ey; e != NULL; e = e->next) + for (k = 0; k <= 5; k++, n++) + if (e->d[k]) wy[n] = e->d[k]; + /* compute quotient and remainder */ + xassert(wy[ny-1] != 0); + bigdiv(nx-ny, ny, wx, wy); + /* construct and normalize quotient */ + if (q != NULL) + { mpz_set_si(q, 0); + q->val = sx * sy; + es = NULL; + k = 6; + for (n = ny; n <= nx; n++) + { if (k > 5) + { e = gmp_get_atom(sizeof(struct mpz_seg)); + e->d[0] = e->d[1] = e->d[2] = 0; + e->d[3] = e->d[4] = e->d[5] = 0; + e->next = NULL; + if (q->ptr == NULL) + q->ptr = e; + else + es->next = e; + es = e; + k = 0; + } + es->d[k++] = wx[n]; + } + normalize(q); + } + /* construct and normalize remainder */ + if (r != NULL) + { mpz_set_si(r, 0); + r->val = sx; + es = NULL; + k = 6; + for (n = 0; n < ny; n++) + { if (k > 5) + { e = gmp_get_atom(sizeof(struct mpz_seg)); + e->d[0] = e->d[1] = e->d[2] = 0; + e->d[3] = e->d[4] = e->d[5] = 0; + e->next = NULL; + if (r->ptr == NULL) + r->ptr = e; + else + es->next = e; + es = e; + k = 0; + } + es->d[k++] = wx[n]; + } + normalize(r); + } +done: return; +} + +void mpz_gcd(mpz_t z, mpz_t x, mpz_t y) +{ /* set z to the greatest common divisor of x and y */ + /* in case of arbitrary integers GCD(x, y) = GCD(|x|, |y|), and, + in particular, GCD(0, 0) = 0 */ + mpz_t u, v, r; + mpz_init(u); + mpz_init(v); + mpz_init(r); + mpz_abs(u, x); + mpz_abs(v, y); + while (mpz_sgn(v)) + { mpz_div(NULL, r, u, v); + mpz_set(u, v); + mpz_set(v, r); + } + mpz_set(z, u); + mpz_clear(u); + mpz_clear(v); + mpz_clear(r); + return; +} + +int mpz_cmp(mpz_t x, mpz_t y) +{ /* compare x and y; return a positive value if x > y, zero if + x = y, or a nefative value if x < y */ + static struct mpz_seg zero = { { 0, 0, 0, 0, 0, 0 }, NULL }; + struct mpz_seg dumx, dumy, *ex, *ey; + int cc, sx, sy, k; + unsigned int t; + if (x == y) + { cc = 0; + goto done; + } + /* special case when both [x] and [y] are in short format */ + if (x->ptr == NULL && y->ptr == NULL) + { int xval = x->val, yval = y->val; + xassert(xval != 0x80000000 && yval != 0x80000000); + cc = (xval > yval ? +1 : xval < yval ? -1 : 0); + goto done; + } + /* special case when [x] and [y] have different signs */ + if (x->val > 0 && y->val <= 0 || x->val == 0 && y->val < 0) + { cc = +1; + goto done; + } + if (x->val < 0 && y->val >= 0 || x->val == 0 && y->val > 0) + { cc = -1; + goto done; + } + /* convert [x] to long format, if necessary */ + if (x->ptr == NULL) + { xassert(x->val != 0x80000000); + if (x->val >= 0) + { sx = +1; + t = (unsigned int)(+ x->val); + } + else + { sx = -1; + t = (unsigned int)(- x->val); + } + ex = &dumx; + ex->d[0] = (unsigned short)t; + ex->d[1] = (unsigned short)(t >> 16); + ex->d[2] = ex->d[3] = ex->d[4] = ex->d[5] = 0; + ex->next = NULL; + } + else + { sx = x->val; + xassert(sx == +1 || sx == -1); + ex = x->ptr; + } + /* convert [y] to long format, if necessary */ + if (y->ptr == NULL) + { xassert(y->val != 0x80000000); + if (y->val >= 0) + { sy = +1; + t = (unsigned int)(+ y->val); + } + else + { sy = -1; + t = (unsigned int)(- y->val); + } + ey = &dumy; + ey->d[0] = (unsigned short)t; + ey->d[1] = (unsigned short)(t >> 16); + ey->d[2] = ey->d[3] = ey->d[4] = ey->d[5] = 0; + ey->next = NULL; + } + else + { sy = y->val; + xassert(sy == +1 || sy == -1); + ey = y->ptr; + } + /* main fragment */ + xassert(sx > 0 && sy > 0 || sx < 0 && sy < 0); + cc = 0; + for (; ex || ey; ex = ex->next, ey = ey->next) + { if (ex == NULL) ex = &zero; + if (ey == NULL) ey = &zero; + for (k = 0; k <= 5; k++) + { if (ex->d[k] > ey->d[k]) cc = +1; + if (ex->d[k] < ey->d[k]) cc = -1; + } + } + if (sx < 0) cc = - cc; +done: return cc; +} + +int mpz_sgn(mpz_t x) +{ /* return +1 if x > 0, 0 if x = 0, and -1 if x < 0 */ + int s; + s = (x->val > 0 ? +1 : x->val < 0 ? -1 : 0); + return s; +} + +int mpz_out_str(void *_fp, int base, mpz_t x) +{ /* output x on stream fp, as a string in given base; the base + may vary from 2 to 36; + return the number of bytes written, or if an error occurred, + return 0 */ + FILE *fp = _fp; + mpz_t b, y, r; + int n, j, nwr = 0; + unsigned char *d; + static char *set = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (!(2 <= base && base <= 36)) + xfault("mpz_out_str: base = %d; invalid base\n", base); + mpz_init(b); + mpz_set_si(b, base); + mpz_init(y); + mpz_init(r); + /* determine the number of digits */ + mpz_abs(y, x); + for (n = 0; mpz_sgn(y) != 0; n++) + mpz_div(y, NULL, y, b); + if (n == 0) n = 1; + /* compute the digits */ + d = xmalloc(n); + mpz_abs(y, x); + for (j = 0; j < n; j++) + { mpz_div(y, r, y, b); + xassert(0 <= r->val && r->val < base && r->ptr == NULL); + d[j] = (unsigned char)r->val; + } + /* output the integer to the stream */ + if (fp == NULL) fp = stdout; + if (mpz_sgn(x) < 0) + fputc('-', fp), nwr++; + for (j = n-1; j >= 0; j--) + fputc(set[d[j]], fp), nwr++; + if (ferror(fp)) nwr = 0; + mpz_clear(b); + mpz_clear(y); + mpz_clear(r); + xfree(d); + return nwr; +} + +/*====================================================================*/ + +mpq_t _mpq_init(void) +{ /* initialize x, and set its value to 0/1 */ + mpq_t x; + x = gmp_get_atom(sizeof(struct mpq)); + x->p.val = 0; + x->p.ptr = NULL; + x->q.val = 1; + x->q.ptr = NULL; + return x; +} + +void mpq_clear(mpq_t x) +{ /* free the space occupied by x */ + mpz_set_si(&x->p, 0); + xassert(x->p.ptr == NULL); + mpz_set_si(&x->q, 0); + xassert(x->q.ptr == NULL); + /* free the number descriptor */ + gmp_free_atom(x, sizeof(struct mpq)); + return; +} + +void mpq_canonicalize(mpq_t x) +{ /* remove any factors that are common to the numerator and + denominator of x, and make the denominator positive */ + mpz_t f; + xassert(x->q.val != 0); + if (x->q.val < 0) + { mpz_neg(&x->p, &x->p); + mpz_neg(&x->q, &x->q); + } + mpz_init(f); + mpz_gcd(f, &x->p, &x->q); + if (!(f->val == 1 && f->ptr == NULL)) + { mpz_div(&x->p, NULL, &x->p, f); + mpz_div(&x->q, NULL, &x->q, f); + } + mpz_clear(f); + return; +} + +void mpq_set(mpq_t z, mpq_t x) +{ /* set the value of z from x */ + if (z != x) + { mpz_set(&z->p, &x->p); + mpz_set(&z->q, &x->q); + } + return; +} + +void mpq_set_si(mpq_t x, int p, unsigned int q) +{ /* set the value of x to p/q */ + if (q == 0) + xfault("mpq_set_si: zero denominator not allowed\n"); + mpz_set_si(&x->p, p); + xassert(q <= 0x7FFFFFFF); + mpz_set_si(&x->q, q); + return; +} + +double mpq_get_d(mpq_t x) +{ /* convert x to a double, truncating if necessary */ + int np, nq; + double p, q; + p = mpz_get_d_2exp(&np, &x->p); + q = mpz_get_d_2exp(&nq, &x->q); + return ldexp(p / q, np - nq); +} + +void mpq_set_d(mpq_t x, double val) +{ /* set x to val; there is no rounding, the conversion is exact */ + int s, n, d, j; + double f; + mpz_t temp; + xassert(-DBL_MAX <= val && val <= +DBL_MAX); + mpq_set_si(x, 0, 1); + if (val > 0.0) + s = +1; + else if (val < 0.0) + s = -1; + else + goto done; + f = frexp(fabs(val), &n); + /* |val| = f * 2^n, where 0.5 <= f < 1.0 */ + mpz_init(temp); + while (f != 0.0) + { f *= 16.0, n -= 4; + d = (int)f; + xassert(0 <= d && d <= 15); + f -= (double)d; + /* x := 16 * x + d */ + mpz_set_si(temp, 16); + mpz_mul(&x->p, &x->p, temp); + mpz_set_si(temp, d); + mpz_add(&x->p, &x->p, temp); + } + mpz_clear(temp); + /* x := x * 2^n */ + if (n > 0) + { for (j = 1; j <= n; j++) + mpz_add(&x->p, &x->p, &x->p); + } + else if (n < 0) + { for (j = 1; j <= -n; j++) + mpz_add(&x->q, &x->q, &x->q); + mpq_canonicalize(x); + } + if (s < 0) mpq_neg(x, x); +done: return; +} + +void mpq_add(mpq_t z, mpq_t x, mpq_t y) +{ /* set z to x + y */ + mpz_t p, q; + mpz_init(p); + mpz_init(q); + mpz_mul(p, &x->p, &y->q); + mpz_mul(q, &x->q, &y->p); + mpz_add(p, p, q); + mpz_mul(q, &x->q, &y->q); + mpz_set(&z->p, p); + mpz_set(&z->q, q); + mpz_clear(p); + mpz_clear(q); + mpq_canonicalize(z); + return; +} + +void mpq_sub(mpq_t z, mpq_t x, mpq_t y) +{ /* set z to x - y */ + mpz_t p, q; + mpz_init(p); + mpz_init(q); + mpz_mul(p, &x->p, &y->q); + mpz_mul(q, &x->q, &y->p); + mpz_sub(p, p, q); + mpz_mul(q, &x->q, &y->q); + mpz_set(&z->p, p); + mpz_set(&z->q, q); + mpz_clear(p); + mpz_clear(q); + mpq_canonicalize(z); + return; +} + +void mpq_mul(mpq_t z, mpq_t x, mpq_t y) +{ /* set z to x * y */ + mpz_mul(&z->p, &x->p, &y->p); + mpz_mul(&z->q, &x->q, &y->q); + mpq_canonicalize(z); + return; +} + +void mpq_div(mpq_t z, mpq_t x, mpq_t y) +{ /* set z to x / y */ + mpz_t p, q; + if (mpq_sgn(y) == 0) + xfault("mpq_div: zero divisor not allowed\n"); + mpz_init(p); + mpz_init(q); + mpz_mul(p, &x->p, &y->q); + mpz_mul(q, &x->q, &y->p); + mpz_set(&z->p, p); + mpz_set(&z->q, q); + mpz_clear(p); + mpz_clear(q); + mpq_canonicalize(z); + return; +} + +void mpq_neg(mpq_t z, mpq_t x) +{ /* set z to 0 - x */ + mpq_set(z, x); + mpz_neg(&z->p, &z->p); + return; +} + +void mpq_abs(mpq_t z, mpq_t x) +{ /* set z to the absolute value of x */ + mpq_set(z, x); + mpz_abs(&z->p, &z->p); + xassert(mpz_sgn(&x->q) > 0); + return; +} + +int mpq_cmp(mpq_t x, mpq_t y) +{ /* compare x and y; return a positive value if x > y, zero if + x = y, or a nefative value if x < y */ + mpq_t temp; + int s; + mpq_init(temp); + mpq_sub(temp, x, y); + s = mpq_sgn(temp); + mpq_clear(temp); + return s; +} + +int mpq_sgn(mpq_t x) +{ /* return +1 if x > 0, 0 if x = 0, and -1 if x < 0 */ + int s; + s = mpz_sgn(&x->p); + xassert(mpz_sgn(&x->q) > 0); + return s; +} + +int mpq_out_str(void *_fp, int base, mpq_t x) +{ /* output x on stream fp, as a string in given base; the base + may vary from 2 to 36; output is in the form 'num/den' or if + the denominator is 1 then just 'num'; + if the parameter fp is a null pointer, stdout is assumed; + return the number of bytes written, or if an error occurred, + return 0 */ + FILE *fp = _fp; + int nwr; + if (!(2 <= base && base <= 36)) + xfault("mpq_out_str: base = %d; invalid base\n", base); + if (fp == NULL) fp = stdout; + nwr = mpz_out_str(fp, base, &x->p); + if (x->q.val == 1 && x->q.ptr == NULL) + ; + else + { fputc('/', fp), nwr++; + nwr += mpz_out_str(fp, base, &x->q); + } + if (ferror(fp)) nwr = 0; + return nwr; +} + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpgmp.h b/resources/3rdparty/glpk-4.57/src/glpgmp.h new file mode 100644 index 000000000..e1615ae27 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpgmp.h @@ -0,0 +1,190 @@ +/* glpgmp.h (bignum arithmetic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef GLPGMP_H +#define GLPGMP_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_GMP /* use GNU MP bignum library */ + +#include + +#define gmp_pool_count _glp_gmp_pool_count +#define gmp_free_mem _glp_gmp_free_mem + +int gmp_pool_count(void); +void gmp_free_mem(void); + +#else /* use GLPK bignum module */ + +/*---------------------------------------------------------------------- +// INTEGER NUMBERS +// +// Depending on its magnitude an integer number of arbitrary precision +// is represented either in short format or in long format. +// +// Short format corresponds to the int type and allows representing +// integer numbers in the range [-(2^31-1), +(2^31-1)]. Note that for +// the most negative number of int type the short format is not used. +// +// In long format integer numbers are represented using the positional +// system with the base (radix) 2^16 = 65536: +// +// x = (-1)^s sum{j in 0..n-1} d[j] * 65536^j, +// +// where x is the integer to be represented, s is its sign (+1 or -1), +// d[j] are its digits (0 <= d[j] <= 65535). +// +// RATIONAL NUMBERS +// +// A rational number is represented as an irreducible fraction: +// +// p / q, +// +// where p (numerator) and q (denominator) are integer numbers (q > 0) +// having no common divisors. */ + +struct mpz +{ /* integer number */ + int val; + /* if ptr is a null pointer, the number is in short format, and + val is its value; otherwise, the number is in long format, and + val is its sign (+1 or -1) */ + struct mpz_seg *ptr; + /* pointer to the linked list of the number segments ordered in + ascending of powers of the base */ +}; + +struct mpz_seg +{ /* integer number segment */ + unsigned short d[6]; + /* six digits of the number ordered in ascending of powers of the + base */ + struct mpz_seg *next; + /* pointer to the next number segment */ +}; + +struct mpq +{ /* rational number (p / q) */ + struct mpz p; + /* numerator */ + struct mpz q; + /* denominator */ +}; + +typedef struct mpz *mpz_t; +typedef struct mpq *mpq_t; + +#define gmp_get_atom _glp_gmp_get_atom +#define gmp_free_atom _glp_gmp_free_atom +#define gmp_pool_count _glp_gmp_pool_count +#define gmp_get_work _glp_gmp_get_work +#define gmp_free_mem _glp_gmp_free_mem + +#define _mpz_init _glp_mpz_init +#define mpz_clear _glp_mpz_clear +#define mpz_set _glp_mpz_set +#define mpz_set_si _glp_mpz_set_si +#define mpz_get_d _glp_mpz_get_d +#define mpz_get_d_2exp _glp_mpz_get_d_2exp +#define mpz_swap _glp_mpz_swap +#define mpz_add _glp_mpz_add +#define mpz_sub _glp_mpz_sub +#define mpz_mul _glp_mpz_mul +#define mpz_neg _glp_mpz_neg +#define mpz_abs _glp_mpz_abs +#define mpz_div _glp_mpz_div +#define mpz_gcd _glp_mpz_gcd +#define mpz_cmp _glp_mpz_cmp +#define mpz_sgn _glp_mpz_sgn +#define mpz_out_str _glp_mpz_out_str + +#define _mpq_init _glp_mpq_init +#define mpq_clear _glp_mpq_clear +#define mpq_canonicalize _glp_mpq_canonicalize +#define mpq_set _glp_mpq_set +#define mpq_set_si _glp_mpq_set_si +#define mpq_get_d _glp_mpq_get_d +#define mpq_set_d _glp_mpq_set_d +#define mpq_add _glp_mpq_add +#define mpq_sub _glp_mpq_sub +#define mpq_mul _glp_mpq_mul +#define mpq_div _glp_mpq_div +#define mpq_neg _glp_mpq_neg +#define mpq_abs _glp_mpq_abs +#define mpq_cmp _glp_mpq_cmp +#define mpq_sgn _glp_mpq_sgn +#define mpq_out_str _glp_mpq_out_str + +void *gmp_get_atom(int size); +void gmp_free_atom(void *ptr, int size); +int gmp_pool_count(void); +unsigned short *gmp_get_work(int size); +void gmp_free_mem(void); + +mpz_t _mpz_init(void); +#define mpz_init(x) (void)((x) = _mpz_init()) +void mpz_clear(mpz_t x); +void mpz_set(mpz_t z, mpz_t x); +void mpz_set_si(mpz_t x, int val); +double mpz_get_d(mpz_t x); +double mpz_get_d_2exp(int *exp, mpz_t x); +void mpz_swap(mpz_t x, mpz_t y); +void mpz_add(mpz_t, mpz_t, mpz_t); +void mpz_sub(mpz_t, mpz_t, mpz_t); +void mpz_mul(mpz_t, mpz_t, mpz_t); +void mpz_neg(mpz_t z, mpz_t x); +void mpz_abs(mpz_t z, mpz_t x); +void mpz_div(mpz_t q, mpz_t r, mpz_t x, mpz_t y); +void mpz_gcd(mpz_t z, mpz_t x, mpz_t y); +int mpz_cmp(mpz_t x, mpz_t y); +int mpz_sgn(mpz_t x); +int mpz_out_str(void *fp, int base, mpz_t x); + +mpq_t _mpq_init(void); +#define mpq_init(x) (void)((x) = _mpq_init()) +void mpq_clear(mpq_t x); +void mpq_canonicalize(mpq_t x); +void mpq_set(mpq_t z, mpq_t x); +void mpq_set_si(mpq_t x, int p, unsigned int q); +double mpq_get_d(mpq_t x); +void mpq_set_d(mpq_t x, double val); +void mpq_add(mpq_t z, mpq_t x, mpq_t y); +void mpq_sub(mpq_t z, mpq_t x, mpq_t y); +void mpq_mul(mpq_t z, mpq_t x, mpq_t y); +void mpq_div(mpq_t z, mpq_t x, mpq_t y); +void mpq_neg(mpq_t z, mpq_t x); +void mpq_abs(mpq_t z, mpq_t x); +int mpq_cmp(mpq_t x, mpq_t y); +int mpq_sgn(mpq_t x); +int mpq_out_str(void *fp, int base, mpq_t x); + +#endif + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glphbm.c b/resources/3rdparty/glpk-4.57/src/glphbm.c new file mode 100644 index 000000000..100ece6e2 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glphbm.c @@ -0,0 +1,529 @@ +/* glphbm.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glphbm.h" +#include "misc.h" + +/*********************************************************************** +* NAME +* +* hbm_read_mat - read sparse matrix in Harwell-Boeing format +* +* SYNOPSIS +* +* #include "glphbm.h" +* HBM *hbm_read_mat(const char *fname); +* +* DESCRIPTION +* +* The routine hbm_read_mat reads a sparse matrix in the Harwell-Boeing +* format from a text file whose name is the character string fname. +* +* Detailed description of the Harwell-Boeing format recognised by this +* routine is given in the following report: +* +* I.S.Duff, R.G.Grimes, J.G.Lewis. User's Guide for the Harwell-Boeing +* Sparse Matrix Collection (Release I), TR/PA/92/86, October 1992. +* +* RETURNS +* +* If no error occured, the routine hbm_read_mat returns a pointer to +* a data structure containing the matrix. In case of error the routine +* prints an appropriate error message and returns NULL. */ + +struct dsa +{ /* working area used by routine hbm_read_mat */ + const char *fname; + /* name of input text file */ + FILE *fp; + /* stream assigned to input text file */ + int seqn; + /* card sequential number */ + char card[80+1]; + /* card image buffer */ + int fmt_p; + /* scale factor */ + int fmt_k; + /* iterator */ + int fmt_f; + /* format code */ + int fmt_w; + /* field width */ + int fmt_d; + /* number of decimal places after point */ +}; + +/*********************************************************************** +* read_card - read next data card +* +* This routine reads the next 80-column card from the input text file +* and stores its image into the character string card. If the card was +* read successfully, the routine returns zero, otherwise non-zero. */ + +#if 1 /* 11/III-2012 */ +static int read_card(struct dsa *dsa) +{ int c, len = 0; + char buf[255+1]; + dsa->seqn++; + for (;;) + { c = fgetc(dsa->fp); + if (c == EOF) + { if (ferror(dsa->fp)) + xprintf("%s:%d: read error\n", + dsa->fname, dsa->seqn); + else + xprintf("%s:%d: unexpected end-of-file\n", + dsa->fname, dsa->seqn); + return 1; + } + else if (c == '\r') + /* nop */; + else if (c == '\n') + break; + else if (iscntrl(c)) + { xprintf("%s:%d: invalid control character\n", + dsa->fname, dsa->seqn, c); + return 1; + } + else + { if (len == sizeof(buf)-1) + goto err; + buf[len++] = (char)c; + } + } + /* remove trailing spaces */ + while (len > 80 && buf[len-1] == ' ') + len--; + buf[len] = '\0'; + /* line should not be longer than 80 chars */ + if (len > 80) +err: { xerror("%s:%d: card image too long\n", + dsa->fname, dsa->seqn); + return 1; + } + /* padd by spaces to 80-column card image */ + strcpy(dsa->card, buf); + memset(&dsa->card[len], ' ', 80 - len); + dsa->card[80] = '\0'; + return 0; +} +#endif + +/*********************************************************************** +* scan_int - scan integer value from the current card +* +* This routine scans an integer value from the current card, where fld +* is the name of the field, pos is the position of the field, width is +* the width of the field, val points to a location to which the scanned +* value should be stored. If the value was scanned successfully, the +* routine returns zero, otherwise non-zero. */ + +static int scan_int(struct dsa *dsa, char *fld, int pos, int width, + int *val) +{ char str[80+1]; + xassert(1 <= width && width <= 80); + memcpy(str, dsa->card + pos, width), str[width] = '\0'; + if (str2int(strspx(str), val)) + { xprintf("%s:%d: field '%s' contains invalid value '%s'\n", + dsa->fname, dsa->seqn, fld, str); + return 1; + } + return 0; +} + +/*********************************************************************** +* parse_fmt - parse Fortran format specification +* +* This routine parses the Fortran format specification represented as +* character string which fmt points to and stores format elements into +* appropriate static locations. Should note that not all valid Fortran +* format specifications may be recognised. If the format specification +* was recognised, the routine returns zero, otherwise non-zero. */ + +static int parse_fmt(struct dsa *dsa, char *fmt) +{ int k, s, val; + char str[80+1]; + /* first character should be left parenthesis */ + if (fmt[0] != '(') +fail: { xprintf("hbm_read_mat: format '%s' not recognised\n", fmt); + return 1; + } + k = 1; + /* optional scale factor */ + dsa->fmt_p = 0; + if (isdigit((unsigned char)fmt[k])) + { s = 0; + while (isdigit((unsigned char)fmt[k])) + { if (s == 80) goto fail; + str[s++] = fmt[k++]; + } + str[s] = '\0'; + if (str2int(str, &val)) goto fail; + if (toupper((unsigned char)fmt[k]) != 'P') goto iter; + dsa->fmt_p = val, k++; + if (!(0 <= dsa->fmt_p && dsa->fmt_p <= 255)) goto fail; + /* optional comma may follow scale factor */ + if (fmt[k] == ',') k++; + } + /* optional iterator */ + dsa->fmt_k = 1; + if (isdigit((unsigned char)fmt[k])) + { s = 0; + while (isdigit((unsigned char)fmt[k])) + { if (s == 80) goto fail; + str[s++] = fmt[k++]; + } + str[s] = '\0'; + if (str2int(str, &val)) goto fail; +iter: dsa->fmt_k = val; + if (!(1 <= dsa->fmt_k && dsa->fmt_k <= 255)) goto fail; + } + /* format code */ + dsa->fmt_f = toupper((unsigned char)fmt[k++]); + if (!(dsa->fmt_f == 'D' || dsa->fmt_f == 'E' || + dsa->fmt_f == 'F' || dsa->fmt_f == 'G' || + dsa->fmt_f == 'I')) goto fail; + /* field width */ + if (!isdigit((unsigned char)fmt[k])) goto fail; + s = 0; + while (isdigit((unsigned char)fmt[k])) + { if (s == 80) goto fail; + str[s++] = fmt[k++]; + } + str[s] = '\0'; + if (str2int(str, &dsa->fmt_w)) goto fail; + if (!(1 <= dsa->fmt_w && dsa->fmt_w <= 255)) goto fail; + /* optional number of decimal places after point */ + dsa->fmt_d = 0; + if (fmt[k] == '.') + { k++; + if (!isdigit((unsigned char)fmt[k])) goto fail; + s = 0; + while (isdigit((unsigned char)fmt[k])) + { if (s == 80) goto fail; + str[s++] = fmt[k++]; + } + str[s] = '\0'; + if (str2int(str, &dsa->fmt_d)) goto fail; + if (!(0 <= dsa->fmt_d && dsa->fmt_d <= 255)) goto fail; + } + /* last character should be right parenthesis */ + if (!(fmt[k] == ')' && fmt[k+1] == '\0')) goto fail; + return 0; +} + +/*********************************************************************** +* read_int_array - read array of integer type +* +* This routine reads an integer array from the input text file, where +* name is array name, fmt is Fortran format specification that controls +* reading, n is number of array elements, val is array of integer type. +* If the array was read successful, the routine returns zero, otherwise +* non-zero. */ + +static int read_int_array(struct dsa *dsa, char *name, char *fmt, + int n, int val[]) +{ int k, pos; + char str[80+1]; + if (parse_fmt(dsa, fmt)) return 1; + if (!(dsa->fmt_f == 'I' && dsa->fmt_w <= 80 && + dsa->fmt_k * dsa->fmt_w <= 80)) + { xprintf( + "%s:%d: can't read array '%s' - invalid format '%s'\n", + dsa->fname, dsa->seqn, name, fmt); + return 1; + } + for (k = 1, pos = INT_MAX; k <= n; k++, pos++) + { if (pos >= dsa->fmt_k) + { if (read_card(dsa)) return 1; + pos = 0; + } + memcpy(str, dsa->card + dsa->fmt_w * pos, dsa->fmt_w); + str[dsa->fmt_w] = '\0'; + strspx(str); + if (str2int(str, &val[k])) + { xprintf( + "%s:%d: can't read array '%s' - invalid value '%s'\n", + dsa->fname, dsa->seqn, name, str); + return 1; + } + } + return 0; +} + +/*********************************************************************** +* read_real_array - read array of real type +* +* This routine reads a real array from the input text file, where name +* is array name, fmt is Fortran format specification that controls +* reading, n is number of array elements, val is array of real type. +* If the array was read successful, the routine returns zero, otherwise +* non-zero. */ + +static int read_real_array(struct dsa *dsa, char *name, char *fmt, + int n, double val[]) +{ int k, pos; + char str[80+1], *ptr; + if (parse_fmt(dsa, fmt)) return 1; + if (!(dsa->fmt_f != 'I' && dsa->fmt_w <= 80 && + dsa->fmt_k * dsa->fmt_w <= 80)) + { xprintf( + "%s:%d: can't read array '%s' - invalid format '%s'\n", + dsa->fname, dsa->seqn, name, fmt); + return 1; + } + for (k = 1, pos = INT_MAX; k <= n; k++, pos++) + { if (pos >= dsa->fmt_k) + { if (read_card(dsa)) return 1; + pos = 0; + } + memcpy(str, dsa->card + dsa->fmt_w * pos, dsa->fmt_w); + str[dsa->fmt_w] = '\0'; + strspx(str); + if (strchr(str, '.') == NULL && strcmp(str, "0")) + { xprintf("%s(%d): can't read array '%s' - value '%s' has no " + "decimal point\n", dsa->fname, dsa->seqn, name, str); + return 1; + } + /* sometimes lower case letters appear */ + for (ptr = str; *ptr; ptr++) + *ptr = (char)toupper((unsigned char)*ptr); + ptr = strchr(str, 'D'); + if (ptr != NULL) *ptr = 'E'; + /* value may appear with decimal exponent but without letters + E or D (for example, -123.456-012), so missing letter should + be inserted */ + ptr = strchr(str+1, '+'); + if (ptr == NULL) ptr = strchr(str+1, '-'); + if (ptr != NULL && *(ptr-1) != 'E') + { xassert(strlen(str) < 80); + memmove(ptr+1, ptr, strlen(ptr)+1); + *ptr = 'E'; + } + if (str2num(str, &val[k])) + { xprintf( + "%s:%d: can't read array '%s' - invalid value '%s'\n", + dsa->fname, dsa->seqn, name, str); + return 1; + } + } + return 0; +} + +HBM *hbm_read_mat(const char *fname) +{ struct dsa _dsa, *dsa = &_dsa; + HBM *hbm = NULL; + dsa->fname = fname; + xprintf("hbm_read_mat: reading matrix from '%s'...\n", + dsa->fname); + dsa->fp = fopen(dsa->fname, "r"); + if (dsa->fp == NULL) + { xprintf("hbm_read_mat: unable to open '%s' - %s\n", + dsa->fname, strerror(errno)); + goto fail; + } + dsa->seqn = 0; + hbm = xmalloc(sizeof(HBM)); + memset(hbm, 0, sizeof(HBM)); + /* read the first heading card */ + if (read_card(dsa)) goto fail; + memcpy(hbm->title, dsa->card, 72), hbm->title[72] = '\0'; + strtrim(hbm->title); + xprintf("%s\n", hbm->title); + memcpy(hbm->key, dsa->card+72, 8), hbm->key[8] = '\0'; + strspx(hbm->key); + xprintf("key = %s\n", hbm->key); + /* read the second heading card */ + if (read_card(dsa)) goto fail; + if (scan_int(dsa, "totcrd", 0, 14, &hbm->totcrd)) goto fail; + if (scan_int(dsa, "ptrcrd", 14, 14, &hbm->ptrcrd)) goto fail; + if (scan_int(dsa, "indcrd", 28, 14, &hbm->indcrd)) goto fail; + if (scan_int(dsa, "valcrd", 42, 14, &hbm->valcrd)) goto fail; + if (scan_int(dsa, "rhscrd", 56, 14, &hbm->rhscrd)) goto fail; + xprintf("totcrd = %d; ptrcrd = %d; indcrd = %d; valcrd = %d; rhsc" + "rd = %d\n", hbm->totcrd, hbm->ptrcrd, hbm->indcrd, + hbm->valcrd, hbm->rhscrd); + /* read the third heading card */ + if (read_card(dsa)) goto fail; + memcpy(hbm->mxtype, dsa->card, 3), hbm->mxtype[3] = '\0'; + if (strchr("RCP", hbm->mxtype[0]) == NULL || + strchr("SUHZR", hbm->mxtype[1]) == NULL || + strchr("AE", hbm->mxtype[2]) == NULL) + { xprintf("%s:%d: matrix type '%s' not recognised\n", + dsa->fname, dsa->seqn, hbm->mxtype); + goto fail; + } + if (scan_int(dsa, "nrow", 14, 14, &hbm->nrow)) goto fail; + if (scan_int(dsa, "ncol", 28, 14, &hbm->ncol)) goto fail; + if (scan_int(dsa, "nnzero", 42, 14, &hbm->nnzero)) goto fail; + if (scan_int(dsa, "neltvl", 56, 14, &hbm->neltvl)) goto fail; + xprintf("mxtype = %s; nrow = %d; ncol = %d; nnzero = %d; neltvl =" + " %d\n", hbm->mxtype, hbm->nrow, hbm->ncol, hbm->nnzero, + hbm->neltvl); + /* read the fourth heading card */ + if (read_card(dsa)) goto fail; + memcpy(hbm->ptrfmt, dsa->card, 16), hbm->ptrfmt[16] = '\0'; + strspx(hbm->ptrfmt); + memcpy(hbm->indfmt, dsa->card+16, 16), hbm->indfmt[16] = '\0'; + strspx(hbm->indfmt); + memcpy(hbm->valfmt, dsa->card+32, 20), hbm->valfmt[20] = '\0'; + strspx(hbm->valfmt); + memcpy(hbm->rhsfmt, dsa->card+52, 20), hbm->rhsfmt[20] = '\0'; + strspx(hbm->rhsfmt); + xprintf("ptrfmt = %s; indfmt = %s; valfmt = %s; rhsfmt = %s\n", + hbm->ptrfmt, hbm->indfmt, hbm->valfmt, hbm->rhsfmt); + /* read the fifth heading card (optional) */ + if (hbm->rhscrd <= 0) + { strcpy(hbm->rhstyp, "???"); + hbm->nrhs = 0; + hbm->nrhsix = 0; + } + else + { if (read_card(dsa)) goto fail; + memcpy(hbm->rhstyp, dsa->card, 3), hbm->rhstyp[3] = '\0'; + if (scan_int(dsa, "nrhs", 14, 14, &hbm->nrhs)) goto fail; + if (scan_int(dsa, "nrhsix", 28, 14, &hbm->nrhsix)) goto fail; + xprintf("rhstyp = '%s'; nrhs = %d; nrhsix = %d\n", + hbm->rhstyp, hbm->nrhs, hbm->nrhsix); + } + /* read matrix structure */ + hbm->colptr = xcalloc(1+hbm->ncol+1, sizeof(int)); + if (read_int_array(dsa, "colptr", hbm->ptrfmt, hbm->ncol+1, + hbm->colptr)) goto fail; + hbm->rowind = xcalloc(1+hbm->nnzero, sizeof(int)); + if (read_int_array(dsa, "rowind", hbm->indfmt, hbm->nnzero, + hbm->rowind)) goto fail; + /* read matrix values */ + if (hbm->valcrd <= 0) goto done; + if (hbm->mxtype[2] == 'A') + { /* assembled matrix */ + hbm->values = xcalloc(1+hbm->nnzero, sizeof(double)); + if (read_real_array(dsa, "values", hbm->valfmt, hbm->nnzero, + hbm->values)) goto fail; + } + else + { /* elemental (unassembled) matrix */ + hbm->values = xcalloc(1+hbm->neltvl, sizeof(double)); + if (read_real_array(dsa, "values", hbm->valfmt, hbm->neltvl, + hbm->values)) goto fail; + } + /* read right-hand sides */ + if (hbm->nrhs <= 0) goto done; + if (hbm->rhstyp[0] == 'F') + { /* dense format */ + hbm->nrhsvl = hbm->nrow * hbm->nrhs; + hbm->rhsval = xcalloc(1+hbm->nrhsvl, sizeof(double)); + if (read_real_array(dsa, "rhsval", hbm->rhsfmt, hbm->nrhsvl, + hbm->rhsval)) goto fail; + } + else if (hbm->rhstyp[0] == 'M' && hbm->mxtype[2] == 'A') + { /* sparse format */ + /* read pointers */ + hbm->rhsptr = xcalloc(1+hbm->nrhs+1, sizeof(int)); + if (read_int_array(dsa, "rhsptr", hbm->ptrfmt, hbm->nrhs+1, + hbm->rhsptr)) goto fail; + /* read sparsity pattern */ + hbm->rhsind = xcalloc(1+hbm->nrhsix, sizeof(int)); + if (read_int_array(dsa, "rhsind", hbm->indfmt, hbm->nrhsix, + hbm->rhsind)) goto fail; + /* read values */ + hbm->rhsval = xcalloc(1+hbm->nrhsix, sizeof(double)); + if (read_real_array(dsa, "rhsval", hbm->rhsfmt, hbm->nrhsix, + hbm->rhsval)) goto fail; + } + else if (hbm->rhstyp[0] == 'M' && hbm->mxtype[2] == 'E') + { /* elemental format */ + hbm->rhsval = xcalloc(1+hbm->nrhsvl, sizeof(double)); + if (read_real_array(dsa, "rhsval", hbm->rhsfmt, hbm->nrhsvl, + hbm->rhsval)) goto fail; + } + else + { xprintf("%s:%d: right-hand side type '%c' not recognised\n", + dsa->fname, dsa->seqn, hbm->rhstyp[0]); + goto fail; + } + /* read starting guesses */ + if (hbm->rhstyp[1] == 'G') + { hbm->nguess = hbm->nrow * hbm->nrhs; + hbm->sguess = xcalloc(1+hbm->nguess, sizeof(double)); + if (read_real_array(dsa, "sguess", hbm->rhsfmt, hbm->nguess, + hbm->sguess)) goto fail; + } + /* read solution vectors */ + if (hbm->rhstyp[2] == 'X') + { hbm->nexact = hbm->nrow * hbm->nrhs; + hbm->xexact = xcalloc(1+hbm->nexact, sizeof(double)); + if (read_real_array(dsa, "xexact", hbm->rhsfmt, hbm->nexact, + hbm->xexact)) goto fail; + } +done: /* reading has been completed */ + xprintf("hbm_read_mat: %d cards were read\n", dsa->seqn); + fclose(dsa->fp); + return hbm; +fail: /* something wrong in Danish kingdom */ + if (hbm != NULL) + { if (hbm->colptr != NULL) xfree(hbm->colptr); + if (hbm->rowind != NULL) xfree(hbm->rowind); + if (hbm->rhsptr != NULL) xfree(hbm->rhsptr); + if (hbm->rhsind != NULL) xfree(hbm->rhsind); + if (hbm->values != NULL) xfree(hbm->values); + if (hbm->rhsval != NULL) xfree(hbm->rhsval); + if (hbm->sguess != NULL) xfree(hbm->sguess); + if (hbm->xexact != NULL) xfree(hbm->xexact); + xfree(hbm); + } + if (dsa->fp != NULL) fclose(dsa->fp); + return NULL; +} + +/*********************************************************************** +* NAME +* +* hbm_free_mat - free sparse matrix in Harwell-Boeing format +* +* SYNOPSIS +* +* #include "glphbm.h" +* void hbm_free_mat(HBM *hbm); +* +* DESCRIPTION +* +* The hbm_free_mat routine frees all the memory allocated to the data +* structure containing a sparse matrix in the Harwell-Boeing format. */ + +void hbm_free_mat(HBM *hbm) +{ if (hbm->colptr != NULL) xfree(hbm->colptr); + if (hbm->rowind != NULL) xfree(hbm->rowind); + if (hbm->rhsptr != NULL) xfree(hbm->rhsptr); + if (hbm->rhsind != NULL) xfree(hbm->rhsind); + if (hbm->values != NULL) xfree(hbm->values); + if (hbm->rhsval != NULL) xfree(hbm->rhsval); + if (hbm->sguess != NULL) xfree(hbm->sguess); + if (hbm->xexact != NULL) xfree(hbm->xexact); + xfree(hbm); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glphbm.h b/resources/3rdparty/glpk-4.57/src/glphbm.h new file mode 100644 index 000000000..688a78ec1 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glphbm.h @@ -0,0 +1,127 @@ +/* glphbm.h (Harwell-Boeing sparse matrix format) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef GLPHBM_H +#define GLPHBM_H + +typedef struct HBM HBM; + +struct HBM +{ /* sparse matrix in Harwell-Boeing format; for details see the + report: I.S.Duff, R.G.Grimes, J.G.Lewis. User's Guide for the + Harwell-Boeing Sparse Matrix Collection (Release I), 1992 */ + char title[72+1]; + /* matrix title (informative) */ + char key[8+1]; + /* matrix key (informative) */ + char mxtype[3+1]; + /* matrix type: + R.. real matrix + C.. complex matrix + P.. pattern only (no numerical values supplied) + .S. symmetric (lower triangle + main diagonal) + .U. unsymmetric + .H. hermitian (lower triangle + main diagonal) + .Z. skew symmetric (lower triangle only) + .R. rectangular + ..A assembled + ..E elemental (unassembled) */ + char rhstyp[3+1]; + /* optional types: + F.. right-hand sides in dense format + M.. right-hand sides in same format as matrix + .G. starting vector(s) (guess) is supplied + ..X exact solution vector(s) is supplied */ + char ptrfmt[16+1]; + /* format for pointers */ + char indfmt[16+1]; + /* format for row (or variable) indices */ + char valfmt[20+1]; + /* format for numerical values of coefficient matrix */ + char rhsfmt[20+1]; + /* format for numerical values of right-hand sides */ + int totcrd; + /* total number of cards excluding header */ + int ptrcrd; + /* number of cards for ponters */ + int indcrd; + /* number of cards for row (or variable) indices */ + int valcrd; + /* number of cards for numerical values */ + int rhscrd; + /* number of lines for right-hand sides; + including starting guesses and solution vectors if present; + zero indicates no right-hand side data is present */ + int nrow; + /* number of rows (or variables) */ + int ncol; + /* number of columns (or elements) */ + int nnzero; + /* number of row (or variable) indices; + equal to number of entries for assembled matrix */ + int neltvl; + /* number of elemental matrix entries; + zero in case of assembled matrix */ + int nrhs; + /* number of right-hand sides */ + int nrhsix; + /* number of row indices; + ignored in case of unassembled matrix */ + int nrhsvl; + /* total number of entries in all right-hand sides */ + int nguess; + /* total number of entries in all starting guesses */ + int nexact; + /* total number of entries in all solution vectors */ + int *colptr; /* alias: eltptr */ + /* column pointers (in case of assembled matrix); + elemental matrix pointers (in case of unassembled matrix) */ + int *rowind; /* alias: varind */ + /* row indices (in case of assembled matrix); + variable indices (in case of unassembled matrix) */ + int *rhsptr; + /* right-hand side pointers */ + int *rhsind; + /* right-hand side indices */ + double *values; + /* matrix values */ + double *rhsval; + /* right-hand side values */ + double *sguess; + /* starting guess values */ + double *xexact; + /* solution vector values */ +}; + +#define hbm_read_mat _glp_hbm_read_mat +HBM *hbm_read_mat(const char *fname); +/* read sparse matrix in Harwell-Boeing format */ + +#define hbm_free_mat _glp_hbm_free_mat +void hbm_free_mat(HBM *hbm); +/* free sparse matrix in Harwell-Boeing format */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpini01.c b/resources/3rdparty/glpk-4.57/src/glpini01.c new file mode 100644 index 000000000..76c021477 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpini01.c @@ -0,0 +1,155 @@ +/* glpini01.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "prob.h" +#include "triang.h" + +/*********************************************************************** +* NAME +* +* glp_adv_basis - construct advanced initial LP basis +* +* SYNOPSIS +* +* void glp_adv_basis(glp_prob *P, int flags); +* +* DESCRIPTION +* +* The routine glp_adv_basis constructs an advanced initial LP basis +* for the specified problem object. +* +* The parameter flag is reserved for use in the future and should be +* specified as zero. +* +* NOTE +* +* The routine glp_adv_basis should be called after the constraint +* matrix has been scaled (if scaling is used). */ + +static int mat(void *info, int k, int ind[], double val[]) +{ glp_prob *P = info; + int m = P->m; + int n = P->n; + GLPROW **row = P->row; + GLPCOL **col = P->col; + GLPAIJ *aij; + int i, j, len; + if (k > 0) + { /* retrieve scaled row of constraint matrix */ + i = +k; + xassert(1 <= i && i <= m); + len = 0; + if (row[i]->type == GLP_FX) + { for (aij = row[i]->ptr; aij != NULL; aij = aij->r_next) + { j = aij->col->j; + if (col[j]->type != GLP_FX) + { len++; + ind[len] = j; + val[len] = aij->row->rii * aij->val * aij->col->sjj; + } + } + } + } + else + { /* retrieve scaled column of constraint matrix */ + j = -k; + xassert(1 <= j && j <= n); + len = 0; + if (col[j]->type != GLP_FX) + { for (aij = col[j]->ptr; aij != NULL; aij = aij->c_next) + { i = aij->row->i; + if (row[i]->type == GLP_FX) + { len++; + ind[len] = i; + val[len] = aij->row->rii * aij->val * aij->col->sjj; + } + } + } + } + return len; +} + +void glp_adv_basis(glp_prob *P, int flags) +{ int i, j, k, m, n, min_mn, size, *rn, *cn; + char *flag; + if (flags != 0) + xerror("glp_adv_basis: flags = %d; invalid flags\n", flags); + m = P->m; /* number of rows */ + n = P->n; /* number of columns */ + if (m == 0 || n == 0) + { /* trivial case */ + glp_std_basis(P); + goto done; + } + xprintf("Constructing initial basis...\n"); + /* allocate working arrays */ + min_mn = (m < n ? m : n); + rn = talloc(1+min_mn, int); + cn = talloc(1+min_mn, int); + flag = talloc(1+m, char); + /* make the basis empty */ + for (i = 1; i <= m; i++) + { flag[i] = 0; + glp_set_row_stat(P, i, GLP_NS); + } + for (j = 1; j <= n; j++) + glp_set_col_stat(P, j, GLP_NS); + /* find maximal triangular part of the constraint matrix; + to prevent including non-fixed rows and fixed columns in the + triangular part, such rows and columns are temporarily made + empty by the routine mat */ +#if 1 /* FIXME: tolerance */ + size = triang(m, n, mat, P, 0.001, rn, cn); +#endif + xassert(0 <= size && size <= min_mn); + /* include in the basis non-fixed structural variables, whose + columns constitute the triangular part */ + for (k = 1; k <= size; k++) + { i = rn[k]; + xassert(1 <= i && i <= m); + flag[i] = 1; + j = cn[k]; + xassert(1 <= j && j <= n); + glp_set_col_stat(P, j, GLP_BS); + } + /* include in the basis appropriate auxiliary variables, whose + unity columns preserve triangular form of the basis matrix */ + for (i = 1; i <= m; i++) + { if (flag[i] == 0) + { glp_set_row_stat(P, i, GLP_BS); + if (P->row[i]->type != GLP_FX) + size++; + } + } + /* size of triangular part = (number of rows) - (number of basic + fixed auxiliary variables) */ + xprintf("Size of triangular part is %d\n", size); + /* deallocate working arrays */ + tfree(rn); + tfree(cn); + tfree(flag); +done: return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpini02.c b/resources/3rdparty/glpk-4.57/src/glpini02.c new file mode 100644 index 000000000..6aad59feb --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpini02.c @@ -0,0 +1,270 @@ +/* glpini02.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "prob.h" + +struct var +{ /* structural variable */ + int j; + /* ordinal number */ + double q; + /* penalty value */ +}; + +static int fcmp(const void *ptr1, const void *ptr2) +{ /* this routine is passed to the qsort() function */ + struct var *col1 = (void *)ptr1, *col2 = (void *)ptr2; + if (col1->q < col2->q) return -1; + if (col1->q > col2->q) return +1; + return 0; +} + +static int get_column(glp_prob *lp, int j, int ind[], double val[]) +{ /* Bixby's algorithm assumes that the constraint matrix is scaled + such that the maximum absolute value in every non-zero row and + column is 1 */ + int k, len; + double big; + len = glp_get_mat_col(lp, j, ind, val); + big = 0.0; + for (k = 1; k <= len; k++) + if (big < fabs(val[k])) big = fabs(val[k]); + if (big == 0.0) big = 1.0; + for (k = 1; k <= len; k++) val[k] /= big; + return len; +} + +static void cpx_basis(glp_prob *lp) +{ /* main routine */ + struct var *C, *C2, *C3, *C4; + int m, n, i, j, jk, k, l, ll, t, n2, n3, n4, type, len, *I, *r, + *ind; + double alpha, gamma, cmax, temp, *v, *val; + xprintf("Constructing initial basis...\n"); + /* determine the number of rows and columns */ + m = glp_get_num_rows(lp); + n = glp_get_num_cols(lp); + /* allocate working arrays */ + C = xcalloc(1+n, sizeof(struct var)); + I = xcalloc(1+m, sizeof(int)); + r = xcalloc(1+m, sizeof(int)); + v = xcalloc(1+m, sizeof(double)); + ind = xcalloc(1+m, sizeof(int)); + val = xcalloc(1+m, sizeof(double)); + /* make all auxiliary variables non-basic */ + for (i = 1; i <= m; i++) + { if (glp_get_row_type(lp, i) != GLP_DB) + glp_set_row_stat(lp, i, GLP_NS); + else if (fabs(glp_get_row_lb(lp, i)) <= + fabs(glp_get_row_ub(lp, i))) + glp_set_row_stat(lp, i, GLP_NL); + else + glp_set_row_stat(lp, i, GLP_NU); + } + /* make all structural variables non-basic */ + for (j = 1; j <= n; j++) + { if (glp_get_col_type(lp, j) != GLP_DB) + glp_set_col_stat(lp, j, GLP_NS); + else if (fabs(glp_get_col_lb(lp, j)) <= + fabs(glp_get_col_ub(lp, j))) + glp_set_col_stat(lp, j, GLP_NL); + else + glp_set_col_stat(lp, j, GLP_NU); + } + /* C2 is a set of free structural variables */ + n2 = 0, C2 = C + 0; + for (j = 1; j <= n; j++) + { type = glp_get_col_type(lp, j); + if (type == GLP_FR) + { n2++; + C2[n2].j = j; + C2[n2].q = 0.0; + } + } + /* C3 is a set of structural variables having excatly one (lower + or upper) bound */ + n3 = 0, C3 = C2 + n2; + for (j = 1; j <= n; j++) + { type = glp_get_col_type(lp, j); + if (type == GLP_LO) + { n3++; + C3[n3].j = j; + C3[n3].q = + glp_get_col_lb(lp, j); + } + else if (type == GLP_UP) + { n3++; + C3[n3].j = j; + C3[n3].q = - glp_get_col_ub(lp, j); + } + } + /* C4 is a set of structural variables having both (lower and + upper) bounds */ + n4 = 0, C4 = C3 + n3; + for (j = 1; j <= n; j++) + { type = glp_get_col_type(lp, j); + if (type == GLP_DB) + { n4++; + C4[n4].j = j; + C4[n4].q = glp_get_col_lb(lp, j) - glp_get_col_ub(lp, j); + } + } + /* compute gamma = max{|c[j]|: 1 <= j <= n} */ + gamma = 0.0; + for (j = 1; j <= n; j++) + { temp = fabs(glp_get_obj_coef(lp, j)); + if (gamma < temp) gamma = temp; + } + /* compute cmax */ + cmax = (gamma == 0.0 ? 1.0 : 1000.0 * gamma); + /* compute final penalty for all structural variables within sets + C2, C3, and C4 */ + switch (glp_get_obj_dir(lp)) + { case GLP_MIN: temp = +1.0; break; + case GLP_MAX: temp = -1.0; break; + default: xassert(lp != lp); + } + for (k = 1; k <= n2+n3+n4; k++) + { j = C[k].j; + C[k].q += (temp * glp_get_obj_coef(lp, j)) / cmax; + } + /* sort structural variables within C2, C3, and C4 in ascending + order of penalty value */ + qsort(C2+1, n2, sizeof(struct var), fcmp); + for (k = 1; k < n2; k++) xassert(C2[k].q <= C2[k+1].q); + qsort(C3+1, n3, sizeof(struct var), fcmp); + for (k = 1; k < n3; k++) xassert(C3[k].q <= C3[k+1].q); + qsort(C4+1, n4, sizeof(struct var), fcmp); + for (k = 1; k < n4; k++) xassert(C4[k].q <= C4[k+1].q); + /*** STEP 1 ***/ + for (i = 1; i <= m; i++) + { type = glp_get_row_type(lp, i); + if (type != GLP_FX) + { /* row i is either free or inequality constraint */ + glp_set_row_stat(lp, i, GLP_BS); + I[i] = 1; + r[i] = 1; + } + else + { /* row i is equality constraint */ + I[i] = 0; + r[i] = 0; + } + v[i] = +DBL_MAX; + } + /*** STEP 2 ***/ + for (k = 1; k <= n2+n3+n4; k++) + { jk = C[k].j; + len = get_column(lp, jk, ind, val); + /* let alpha = max{|A[l,jk]|: r[l] = 0} and let l' be such + that alpha = |A[l',jk]| */ + alpha = 0.0, ll = 0; + for (t = 1; t <= len; t++) + { l = ind[t]; + if (r[l] == 0 && alpha < fabs(val[t])) + alpha = fabs(val[t]), ll = l; + } + if (alpha >= 0.99) + { /* B := B union {jk} */ + glp_set_col_stat(lp, jk, GLP_BS); + I[ll] = 1; + v[ll] = alpha; + /* r[l] := r[l] + 1 for all l such that |A[l,jk]| != 0 */ + for (t = 1; t <= len; t++) + { l = ind[t]; + if (val[t] != 0.0) r[l]++; + } + /* continue to the next k */ + continue; + } + /* if |A[l,jk]| > 0.01 * v[l] for some l, continue to the + next k */ + for (t = 1; t <= len; t++) + { l = ind[t]; + if (fabs(val[t]) > 0.01 * v[l]) break; + } + if (t <= len) continue; + /* otherwise, let alpha = max{|A[l,jk]|: I[l] = 0} and let l' + be such that alpha = |A[l',jk]| */ + alpha = 0.0, ll = 0; + for (t = 1; t <= len; t++) + { l = ind[t]; + if (I[l] == 0 && alpha < fabs(val[t])) + alpha = fabs(val[t]), ll = l; + } + /* if alpha = 0, continue to the next k */ + if (alpha == 0.0) continue; + /* B := B union {jk} */ + glp_set_col_stat(lp, jk, GLP_BS); + I[ll] = 1; + v[ll] = alpha; + /* r[l] := r[l] + 1 for all l such that |A[l,jk]| != 0 */ + for (t = 1; t <= len; t++) + { l = ind[t]; + if (val[t] != 0.0) r[l]++; + } + } + /*** STEP 3 ***/ + /* add an artificial variable (auxiliary variable for equality + constraint) to cover each remaining uncovered row */ + for (i = 1; i <= m; i++) + if (I[i] == 0) glp_set_row_stat(lp, i, GLP_BS); + /* free working arrays */ + xfree(C); + xfree(I); + xfree(r); + xfree(v); + xfree(ind); + xfree(val); + return; +} + +/*********************************************************************** +* NAME +* +* glp_cpx_basis - construct Bixby's initial LP basis +* +* SYNOPSIS +* +* void glp_cpx_basis(glp_prob *lp); +* +* DESCRIPTION +* +* The routine glp_cpx_basis constructs an advanced initial basis for +* the specified problem object. +* +* The routine is based on Bixby's algorithm described in the paper: +* +* Robert E. Bixby. Implementing the Simplex Method: The Initial Basis. +* ORSA Journal on Computing, Vol. 4, No. 3, 1992, pp. 267-84. */ + +void glp_cpx_basis(glp_prob *lp) +{ if (lp->m == 0 || lp->n == 0) + glp_std_basis(lp); + else + cpx_basis(lp); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpios.h b/resources/3rdparty/glpk-4.57/src/glpios.h new file mode 100644 index 000000000..07ee9810e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpios.h @@ -0,0 +1,620 @@ +/* glpios.h (integer optimization suite) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef GLPIOS_H +#define GLPIOS_H + +#include "prob.h" + +typedef struct IOSLOT IOSLOT; +typedef struct IOSNPD IOSNPD; +typedef struct IOSBND IOSBND; +typedef struct IOSTAT IOSTAT; +typedef struct IOSROW IOSROW; +typedef struct IOSAIJ IOSAIJ; +typedef struct IOSPOOL IOSPOOL; +typedef struct IOSCUT IOSCUT; + +struct glp_tree +{ /* branch-and-bound tree */ + int magic; + /* magic value used for debugging */ + DMP *pool; + /* memory pool to store all IOS components */ + int n; + /* number of columns (variables) */ + /*--------------------------------------------------------------*/ + /* problem components corresponding to the original MIP and its + LP relaxation (used to restore the original problem object on + exit from the solver) */ + int orig_m; + /* number of rows */ + unsigned char *orig_type; /* uchar orig_type[1+orig_m+n]; */ + /* types of all variables */ + double *orig_lb; /* double orig_lb[1+orig_m+n]; */ + /* lower bounds of all variables */ + double *orig_ub; /* double orig_ub[1+orig_m+n]; */ + /* upper bounds of all variables */ + unsigned char *orig_stat; /* uchar orig_stat[1+orig_m+n]; */ + /* statuses of all variables */ + double *orig_prim; /* double orig_prim[1+orig_m+n]; */ + /* primal values of all variables */ + double *orig_dual; /* double orig_dual[1+orig_m+n]; */ + /* dual values of all variables */ + double orig_obj; + /* optimal objective value for LP relaxation */ + /*--------------------------------------------------------------*/ + /* branch-and-bound tree */ + int nslots; + /* length of the array of slots (enlarged automatically) */ + int avail; + /* index of the first free slot; 0 means all slots are in use */ + IOSLOT *slot; /* IOSLOT slot[1+nslots]; */ + /* array of slots: + slot[0] is not used; + slot[p], 1 <= p <= nslots, either contains a pointer to some + node of the branch-and-bound tree, in which case p is used on + API level as the reference number of corresponding subproblem, + or is free; all free slots are linked into single linked list; + slot[1] always contains a pointer to the root node (it is free + only if the tree is empty) */ + IOSNPD *head; + /* pointer to the head of the active list */ + IOSNPD *tail; + /* pointer to the tail of the active list */ + /* the active list is a doubly linked list of active subproblems + which correspond to leaves of the tree; all subproblems in the + active list are ordered chronologically (each a new subproblem + is always added to the tail of the list) */ + int a_cnt; + /* current number of active nodes (including the current one) */ + int n_cnt; + /* current number of all (active and inactive) nodes */ + int t_cnt; + /* total number of nodes including those which have been already + removed from the tree; this count is increased by one whenever + a new node is created and never decreased */ + /*--------------------------------------------------------------*/ + /* problem components corresponding to the root subproblem */ + int root_m; + /* number of rows */ + unsigned char *root_type; /* uchar root_type[1+root_m+n]; */ + /* types of all variables */ + double *root_lb; /* double root_lb[1+root_m+n]; */ + /* lower bounds of all variables */ + double *root_ub; /* double root_ub[1+root_m+n]; */ + /* upper bounds of all variables */ + unsigned char *root_stat; /* uchar root_stat[1+root_m+n]; */ + /* statuses of all variables */ + /*--------------------------------------------------------------*/ + /* current subproblem and its LP relaxation */ + IOSNPD *curr; + /* pointer to the current subproblem (which can be only active); + NULL means the current subproblem does not exist */ + glp_prob *mip; + /* original problem object passed to the solver; if the current + subproblem exists, its LP segment corresponds to LP relaxation + of the current subproblem; if the current subproblem does not + exist, its LP segment corresponds to LP relaxation of the root + subproblem (note that the root subproblem may differ from the + original MIP, because it may be preprocessed and/or may have + additional rows) */ + unsigned char *non_int; /* uchar non_int[1+n]; */ + /* these column flags are set each time when LP relaxation of the + current subproblem has been solved; + non_int[0] is not used; + non_int[j], 1 <= j <= n, is j-th column flag; if this flag is + set, corresponding variable is required to be integer, but its + value in basic solution is fractional */ + /*--------------------------------------------------------------*/ + /* problem components corresponding to the parent (predecessor) + subproblem for the current subproblem; used to inspect changes + on freezing the current subproblem */ + int pred_m; + /* number of rows */ + int pred_max; + /* length of the following four arrays (enlarged automatically), + pred_max >= pred_m + n */ + unsigned char *pred_type; /* uchar pred_type[1+pred_m+n]; */ + /* types of all variables */ + double *pred_lb; /* double pred_lb[1+pred_m+n]; */ + /* lower bounds of all variables */ + double *pred_ub; /* double pred_ub[1+pred_m+n]; */ + /* upper bounds of all variables */ + unsigned char *pred_stat; /* uchar pred_stat[1+pred_m+n]; */ + /* statuses of all variables */ + /****************************************************************/ + /* built-in cut generators segment */ + IOSPOOL *local; + /* local cut pool */ + void *mir_gen; + /* pointer to working area used by the MIR cut generator */ + void *clq_gen; + /* pointer to working area used by the clique cut generator */ + /*--------------------------------------------------------------*/ + void *pcost; + /* pointer to working area used on pseudocost branching */ + int *iwrk; /* int iwrk[1+n]; */ + /* working array */ + double *dwrk; /* double dwrk[1+n]; */ + /* working array */ + /*--------------------------------------------------------------*/ + /* control parameters and statistics */ + const glp_iocp *parm; + /* copy of control parameters passed to the solver */ +#if 0 /* 10/VI-2013 */ + glp_long tm_beg; +#else + double tm_beg; +#endif + /* starting time of the search, in seconds; the total time of the + search is the difference between xtime() and tm_beg */ +#if 0 /* 10/VI-2013 */ + glp_long tm_lag; +#else + double tm_lag; +#endif + /* the most recent time, in seconds, at which the progress of the + the search was displayed */ + int sol_cnt; + /* number of integer feasible solutions found */ +#if 1 /* 11/VII-2013 */ + void *P; /* glp_prob *P; */ + /* problem passed to glp_intopt */ + void *npp; /* NPP *npp; */ + /* preprocessor workspace or NULL */ + const char *save_sol; + /* filename (template) to save every new solution */ + int save_cnt; + /* count to generate filename */ +#endif + /*--------------------------------------------------------------*/ + /* advanced solver interface */ + int reason; + /* flag indicating the reason why the callback routine is being + called (see glpk.h) */ + int stop; + /* flag indicating that the callback routine requires premature + termination of the search */ + int next_p; + /* reference number of active subproblem selected to continue + the search; 0 means no subproblem has been selected */ + int reopt; + /* flag indicating that the current LP relaxation needs to be + re-optimized */ + int reinv; + /* flag indicating that some (non-active) rows were removed from + the current LP relaxation, so if there no new rows appear, the + basis must be re-factorized */ + int br_var; + /* the number of variable chosen to branch on */ + int br_sel; + /* flag indicating which branch (subproblem) is suggested to be + selected to continue the search: + GLP_DN_BRNCH - select down-branch + GLP_UP_BRNCH - select up-branch + GLP_NO_BRNCH - use general selection technique */ + int child; + /* subproblem reference number corresponding to br_sel */ +}; + +struct IOSLOT +{ /* node subproblem slot */ + IOSNPD *node; + /* pointer to subproblem descriptor; NULL means free slot */ + int next; + /* index of another free slot (only if this slot is free) */ +}; + +struct IOSNPD +{ /* node subproblem descriptor */ + int p; + /* subproblem reference number (it is the index to corresponding + slot, i.e. slot[p] points to this descriptor) */ + IOSNPD *up; + /* pointer to the parent subproblem; NULL means this node is the + root of the tree, in which case p = 1 */ + int level; + /* node level (the root node has level 0) */ + int count; + /* if count = 0, this subproblem is active; if count > 0, this + subproblem is inactive, in which case count is the number of + its child subproblems */ + /* the following three linked lists are destroyed on reviving and + built anew on freezing the subproblem: */ + IOSBND *b_ptr; + /* linked list of rows and columns of the parent subproblem whose + types and bounds were changed */ + IOSTAT *s_ptr; + /* linked list of rows and columns of the parent subproblem whose + statuses were changed */ + IOSROW *r_ptr; + /* linked list of rows (cuts) added to the parent subproblem */ + int solved; + /* how many times LP relaxation of this subproblem was solved; + for inactive subproblem this count is always non-zero; + for active subproblem, which is not current, this count may be + non-zero, if the subproblem was temporarily suspended */ + double lp_obj; + /* optimal objective value to LP relaxation of this subproblem; + on creating a subproblem this value is inherited from its + parent; for the root subproblem, which has no parent, this + value is initially set to -DBL_MAX (minimization) or +DBL_MAX + (maximization); each time the subproblem is re-optimized, this + value is appropriately changed */ + double bound; + /* local lower (minimization) or upper (maximization) bound for + integer optimal solution to *this* subproblem; this bound is + local in the sense that only subproblems in the subtree rooted + at this node cannot have better integer feasible solutions; + on creating a subproblem its local bound is inherited from its + parent and then can be made stronger (never weaker); for the + root subproblem its local bound is initially set to -DBL_MAX + (minimization) or +DBL_MAX (maximization) and then improved as + the root LP relaxation has been solved */ + /* the following two quantities are defined only if LP relaxation + of this subproblem was solved at least once (solved > 0): */ + int ii_cnt; + /* number of integer variables whose value in optimal solution to + LP relaxation of this subproblem is fractional */ + double ii_sum; + /* sum of integer infeasibilities */ +#if 1 /* 30/XI-2009 */ + int changed; + /* how many times this subproblem was re-formulated (by adding + cutting plane constraints) */ +#endif + int br_var; + /* ordinal number of branching variable, 1 <= br_var <= n, used + to split this subproblem; 0 means that either this subproblem + is active or branching was made on a constraint */ + double br_val; + /* (fractional) value of branching variable in optimal solution + to final LP relaxation of this subproblem */ + void *data; /* char data[tree->cb_size]; */ + /* pointer to the application-specific data */ + IOSNPD *temp; + /* working pointer used by some routines */ + IOSNPD *prev; + /* pointer to previous subproblem in the active list */ + IOSNPD *next; + /* pointer to next subproblem in the active list */ +}; + +struct IOSBND +{ /* bounds change entry */ + int k; + /* ordinal number of corresponding row (1 <= k <= m) or column + (m+1 <= k <= m+n), where m and n are the number of rows and + columns, resp., in the parent subproblem */ + unsigned char type; + /* new type */ + double lb; + /* new lower bound */ + double ub; + /* new upper bound */ + IOSBND *next; + /* pointer to next entry for the same subproblem */ +}; + +struct IOSTAT +{ /* status change entry */ + int k; + /* ordinal number of corresponding row (1 <= k <= m) or column + (m+1 <= k <= m+n), where m and n are the number of rows and + columns, resp., in the parent subproblem */ + unsigned char stat; + /* new status */ + IOSTAT *next; + /* pointer to next entry for the same subproblem */ +}; + +struct IOSROW +{ /* row (constraint) addition entry */ + char *name; + /* row name or NULL */ + unsigned char origin; + /* row origin flag (see glp_attr.origin) */ + unsigned char klass; + /* row class descriptor (see glp_attr.klass) */ + unsigned char type; + /* row type (GLP_LO, GLP_UP, etc.) */ + double lb; + /* row lower bound */ + double ub; + /* row upper bound */ + IOSAIJ *ptr; + /* pointer to the row coefficient list */ + double rii; + /* row scale factor */ + unsigned char stat; + /* row status (GLP_BS, GLP_NL, etc.) */ + IOSROW *next; + /* pointer to next entry for the same subproblem */ +}; + +struct IOSAIJ +{ /* constraint coefficient */ + int j; + /* variable (column) number, 1 <= j <= n */ + double val; + /* non-zero coefficient value */ + IOSAIJ *next; + /* pointer to next coefficient for the same row */ +}; + +struct IOSPOOL +{ /* cut pool */ + int size; + /* pool size = number of cuts in the pool */ + IOSCUT *head; + /* pointer to the first cut */ + IOSCUT *tail; + /* pointer to the last cut */ + int ord; + /* ordinal number of the current cut, 1 <= ord <= size */ + IOSCUT *curr; + /* pointer to the current cut */ +}; + +struct IOSCUT +{ /* cut (cutting plane constraint) */ + char *name; + /* cut name or NULL */ + unsigned char klass; + /* cut class descriptor (see glp_attr.klass) */ + IOSAIJ *ptr; + /* pointer to the cut coefficient list */ + unsigned char type; + /* cut type: + GLP_LO: sum a[j] * x[j] >= b + GLP_UP: sum a[j] * x[j] <= b + GLP_FX: sum a[j] * x[j] = b */ + double rhs; + /* cut right-hand side */ + IOSCUT *prev; + /* pointer to previous cut */ + IOSCUT *next; + /* pointer to next cut */ +}; + +#define ios_create_tree _glp_ios_create_tree +glp_tree *ios_create_tree(glp_prob *mip, const glp_iocp *parm); +/* create branch-and-bound tree */ + +#define ios_revive_node _glp_ios_revive_node +void ios_revive_node(glp_tree *tree, int p); +/* revive specified subproblem */ + +#define ios_freeze_node _glp_ios_freeze_node +void ios_freeze_node(glp_tree *tree); +/* freeze current subproblem */ + +#define ios_clone_node _glp_ios_clone_node +void ios_clone_node(glp_tree *tree, int p, int nnn, int ref[]); +/* clone specified subproblem */ + +#define ios_delete_node _glp_ios_delete_node +void ios_delete_node(glp_tree *tree, int p); +/* delete specified subproblem */ + +#define ios_delete_tree _glp_ios_delete_tree +void ios_delete_tree(glp_tree *tree); +/* delete branch-and-bound tree */ + +#define ios_eval_degrad _glp_ios_eval_degrad +void ios_eval_degrad(glp_tree *tree, int j, double *dn, double *up); +/* estimate obj. degrad. for down- and up-branches */ + +#define ios_round_bound _glp_ios_round_bound +double ios_round_bound(glp_tree *tree, double bound); +/* improve local bound by rounding */ + +#define ios_is_hopeful _glp_ios_is_hopeful +int ios_is_hopeful(glp_tree *tree, double bound); +/* check if subproblem is hopeful */ + +#define ios_best_node _glp_ios_best_node +int ios_best_node(glp_tree *tree); +/* find active node with best local bound */ + +#define ios_relative_gap _glp_ios_relative_gap +double ios_relative_gap(glp_tree *tree); +/* compute relative mip gap */ + +#define ios_solve_node _glp_ios_solve_node +int ios_solve_node(glp_tree *tree); +/* solve LP relaxation of current subproblem */ + +#define ios_create_pool _glp_ios_create_pool +IOSPOOL *ios_create_pool(glp_tree *tree); +/* create cut pool */ + +#define ios_add_row _glp_ios_add_row +int ios_add_row(glp_tree *tree, IOSPOOL *pool, + const char *name, int klass, int flags, int len, const int ind[], + const double val[], int type, double rhs); +/* add row (constraint) to the cut pool */ + +#define ios_find_row _glp_ios_find_row +IOSCUT *ios_find_row(IOSPOOL *pool, int i); +/* find row (constraint) in the cut pool */ + +#define ios_del_row _glp_ios_del_row +void ios_del_row(glp_tree *tree, IOSPOOL *pool, int i); +/* remove row (constraint) from the cut pool */ + +#define ios_clear_pool _glp_ios_clear_pool +void ios_clear_pool(glp_tree *tree, IOSPOOL *pool); +/* remove all rows (constraints) from the cut pool */ + +#define ios_delete_pool _glp_ios_delete_pool +void ios_delete_pool(glp_tree *tree, IOSPOOL *pool); +/* delete cut pool */ + +#if 1 /* 11/VII-2013 */ +#define ios_process_sol _glp_ios_process_sol +void ios_process_sol(glp_tree *T); +/* process integer feasible solution just found */ +#endif + +#define ios_preprocess_node _glp_ios_preprocess_node +int ios_preprocess_node(glp_tree *tree, int max_pass); +/* preprocess current subproblem */ + +#define ios_driver _glp_ios_driver +int ios_driver(glp_tree *tree); +/* branch-and-bound driver */ + +/**********************************************************************/ + +typedef struct IOSVEC IOSVEC; + +struct IOSVEC +{ /* sparse vector v = (v[j]) */ + int n; + /* dimension, n >= 0 */ + int nnz; + /* number of non-zero components, 0 <= nnz <= n */ + int *pos; /* int pos[1+n]; */ + /* pos[j] = k, 1 <= j <= n, is position of (non-zero) v[j] in the + arrays ind and val, where 1 <= k <= nnz; pos[j] = 0 means that + v[j] is structural zero */ + int *ind; /* int ind[1+n]; */ + /* ind[k] = j, 1 <= k <= nnz, is index of v[j] */ + double *val; /* double val[1+n]; */ + /* val[k], 1 <= k <= nnz, is a numeric value of v[j] */ +}; + +#define ios_create_vec _glp_ios_create_vec +IOSVEC *ios_create_vec(int n); +/* create sparse vector */ + +#define ios_check_vec _glp_ios_check_vec +void ios_check_vec(IOSVEC *v); +/* check that sparse vector has correct representation */ + +#define ios_get_vj _glp_ios_get_vj +double ios_get_vj(IOSVEC *v, int j); +/* retrieve component of sparse vector */ + +#define ios_set_vj _glp_ios_set_vj +void ios_set_vj(IOSVEC *v, int j, double val); +/* set/change component of sparse vector */ + +#define ios_clear_vec _glp_ios_clear_vec +void ios_clear_vec(IOSVEC *v); +/* set all components of sparse vector to zero */ + +#define ios_clean_vec _glp_ios_clean_vec +void ios_clean_vec(IOSVEC *v, double eps); +/* remove zero or small components from sparse vector */ + +#define ios_copy_vec _glp_ios_copy_vec +void ios_copy_vec(IOSVEC *x, IOSVEC *y); +/* copy sparse vector (x := y) */ + +#define ios_linear_comb _glp_ios_linear_comb +void ios_linear_comb(IOSVEC *x, double a, IOSVEC *y); +/* compute linear combination (x := x + a * y) */ + +#define ios_delete_vec _glp_ios_delete_vec +void ios_delete_vec(IOSVEC *v); +/* delete sparse vector */ + +/**********************************************************************/ + +#define ios_gmi_gen _glp_ios_gmi_gen +void ios_gmi_gen(glp_tree *tree); +/* generate Gomory's mixed integer cuts */ + +#define ios_mir_init _glp_ios_mir_init +void *ios_mir_init(glp_tree *tree); +/* initialize MIR cut generator */ + +#define ios_mir_gen _glp_ios_mir_gen +void ios_mir_gen(glp_tree *tree, void *gen); +/* generate MIR cuts */ + +#define ios_mir_term _glp_ios_mir_term +void ios_mir_term(void *gen); +/* terminate MIR cut generator */ + +#define ios_cov_gen _glp_ios_cov_gen +void ios_cov_gen(glp_tree *tree); +/* generate mixed cover cuts */ + +#define ios_clq_init _glp_ios_clq_init +void *ios_clq_init(glp_tree *tree); +/* initialize clique cut generator */ + +#define ios_clq_gen _glp_ios_clq_gen +void ios_clq_gen(glp_tree *tree, void *gen); +/* generate clique cuts */ + +#define ios_clq_term _glp_ios_clq_term +void ios_clq_term(void *gen); +/* terminate clique cut generator */ + +#define ios_pcost_init _glp_ios_pcost_init +void *ios_pcost_init(glp_tree *tree); +/* initialize working data used on pseudocost branching */ + +#define ios_pcost_branch _glp_ios_pcost_branch +int ios_pcost_branch(glp_tree *T, int *next); +/* choose branching variable with pseudocost branching */ + +#define ios_pcost_update _glp_ios_pcost_update +void ios_pcost_update(glp_tree *tree); +/* update history information for pseudocost branching */ + +#define ios_pcost_free _glp_ios_pcost_free +void ios_pcost_free(glp_tree *tree); +/* free working area used on pseudocost branching */ + +#define ios_feas_pump _glp_ios_feas_pump +void ios_feas_pump(glp_tree *T); +/* feasibility pump heuristic */ + +#if 1 /* 25/V-2013 */ +#define ios_proxy_heur _glp_ios_proxy_heur +void ios_proxy_heur(glp_tree *T); +/* proximity search heuristic */ +#endif + +#define ios_process_cuts _glp_ios_process_cuts +void ios_process_cuts(glp_tree *T); +/* process cuts stored in the local cut pool */ + +#define ios_choose_node _glp_ios_choose_node +int ios_choose_node(glp_tree *T); +/* select subproblem to continue the search */ + +#define ios_choose_var _glp_ios_choose_var +int ios_choose_var(glp_tree *T, int *next); +/* select variable to branch on */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpios01.c b/resources/3rdparty/glpk-4.57/src/glpios01.c new file mode 100644 index 000000000..da1b9479f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpios01.c @@ -0,0 +1,1602 @@ +/* glpios01.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpios.h" +#include "misc.h" + +static int lpx_eval_tab_row(glp_prob *lp, int k, int ind[], + double val[]) +{ /* compute row of the simplex tableau */ + return glp_eval_tab_row(lp, k, ind, val); +} + +static int lpx_dual_ratio_test(glp_prob *lp, int len, const int ind[], + const double val[], int how, double tol) +{ /* perform dual ratio test */ + int piv; + piv = glp_dual_rtest(lp, len, ind, val, how, tol); + xassert(0 <= piv && piv <= len); + return piv == 0 ? 0 : ind[piv]; +} + +/*********************************************************************** +* NAME +* +* ios_create_tree - create branch-and-bound tree +* +* SYNOPSIS +* +* #include "glpios.h" +* glp_tree *ios_create_tree(glp_prob *mip, const glp_iocp *parm); +* +* DESCRIPTION +* +* The routine ios_create_tree creates the branch-and-bound tree. +* +* Being created the tree consists of the only root subproblem whose +* reference number is 1. Note that initially the root subproblem is in +* frozen state and therefore needs to be revived. +* +* RETURNS +* +* The routine returns a pointer to the tree created. */ + +static IOSNPD *new_node(glp_tree *tree, IOSNPD *parent); + +glp_tree *ios_create_tree(glp_prob *mip, const glp_iocp *parm) +{ int m = mip->m; + int n = mip->n; + glp_tree *tree; + int i, j; + xassert(mip->tree == NULL); + mip->tree = tree = xmalloc(sizeof(glp_tree)); + tree->pool = dmp_create_pool(); + tree->n = n; + /* save original problem components */ + tree->orig_m = m; + tree->orig_type = xcalloc(1+m+n, sizeof(char)); + tree->orig_lb = xcalloc(1+m+n, sizeof(double)); + tree->orig_ub = xcalloc(1+m+n, sizeof(double)); + tree->orig_stat = xcalloc(1+m+n, sizeof(char)); + tree->orig_prim = xcalloc(1+m+n, sizeof(double)); + tree->orig_dual = xcalloc(1+m+n, sizeof(double)); + for (i = 1; i <= m; i++) + { GLPROW *row = mip->row[i]; + tree->orig_type[i] = (char)row->type; + tree->orig_lb[i] = row->lb; + tree->orig_ub[i] = row->ub; + tree->orig_stat[i] = (char)row->stat; + tree->orig_prim[i] = row->prim; + tree->orig_dual[i] = row->dual; + } + for (j = 1; j <= n; j++) + { GLPCOL *col = mip->col[j]; + tree->orig_type[m+j] = (char)col->type; + tree->orig_lb[m+j] = col->lb; + tree->orig_ub[m+j] = col->ub; + tree->orig_stat[m+j] = (char)col->stat; + tree->orig_prim[m+j] = col->prim; + tree->orig_dual[m+j] = col->dual; + } + tree->orig_obj = mip->obj_val; + /* initialize the branch-and-bound tree */ + tree->nslots = 0; + tree->avail = 0; + tree->slot = NULL; + tree->head = tree->tail = NULL; + tree->a_cnt = tree->n_cnt = tree->t_cnt = 0; + /* the root subproblem is not solved yet, so its final components + are unknown so far */ + tree->root_m = 0; + tree->root_type = NULL; + tree->root_lb = tree->root_ub = NULL; + tree->root_stat = NULL; + /* the current subproblem does not exist yet */ + tree->curr = NULL; + tree->mip = mip; + /*tree->solved = 0;*/ + tree->non_int = xcalloc(1+n, sizeof(char)); + memset(&tree->non_int[1], 0, n); + /* arrays to save parent subproblem components will be allocated + later */ + tree->pred_m = tree->pred_max = 0; + tree->pred_type = NULL; + tree->pred_lb = tree->pred_ub = NULL; + tree->pred_stat = NULL; + /* cut generator */ + tree->local = ios_create_pool(tree); + /*tree->first_attempt = 1;*/ + /*tree->max_added_cuts = 0;*/ + /*tree->min_eff = 0.0;*/ + /*tree->miss = 0;*/ + /*tree->just_selected = 0;*/ + tree->mir_gen = NULL; + tree->clq_gen = NULL; + /*tree->round = 0;*/ +#if 0 + /* create the conflict graph */ + tree->n_ref = xcalloc(1+n, sizeof(int)); + memset(&tree->n_ref[1], 0, n * sizeof(int)); + tree->c_ref = xcalloc(1+n, sizeof(int)); + memset(&tree->c_ref[1], 0, n * sizeof(int)); + tree->g = scg_create_graph(0); + tree->j_ref = xcalloc(1+tree->g->n_max, sizeof(int)); +#endif + /* pseudocost branching */ + tree->pcost = NULL; + tree->iwrk = xcalloc(1+n, sizeof(int)); + tree->dwrk = xcalloc(1+n, sizeof(double)); + /* initialize control parameters */ + tree->parm = parm; + tree->tm_beg = xtime(); +#if 0 /* 10/VI-2013 */ + tree->tm_lag = xlset(0); +#else + tree->tm_lag = 0.0; +#endif + tree->sol_cnt = 0; +#if 1 /* 11/VII-2013 */ + tree->P = NULL; + tree->npp = NULL; + tree->save_sol = parm->save_sol; + tree->save_cnt = 0; +#endif + /* initialize advanced solver interface */ + tree->reason = 0; + tree->reopt = 0; + tree->reinv = 0; + tree->br_var = 0; + tree->br_sel = 0; + tree->child = 0; + tree->next_p = 0; + /*tree->btrack = NULL;*/ + tree->stop = 0; + /* create the root subproblem, which initially is identical to + the original MIP */ + new_node(tree, NULL); + return tree; +} + +/*********************************************************************** +* NAME +* +* ios_revive_node - revive specified subproblem +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_revive_node(glp_tree *tree, int p); +* +* DESCRIPTION +* +* The routine ios_revive_node revives the specified subproblem, whose +* reference number is p, and thereby makes it the current subproblem. +* Note that the specified subproblem must be active. Besides, if the +* current subproblem already exists, it must be frozen before reviving +* another subproblem. */ + +void ios_revive_node(glp_tree *tree, int p) +{ glp_prob *mip = tree->mip; + IOSNPD *node, *root; + /* obtain pointer to the specified subproblem */ + xassert(1 <= p && p <= tree->nslots); + node = tree->slot[p].node; + xassert(node != NULL); + /* the specified subproblem must be active */ + xassert(node->count == 0); + /* the current subproblem must not exist */ + xassert(tree->curr == NULL); + /* the specified subproblem becomes current */ + tree->curr = node; + /*tree->solved = 0;*/ + /* obtain pointer to the root subproblem */ + root = tree->slot[1].node; + xassert(root != NULL); + /* at this point problem object components correspond to the root + subproblem, so if the root subproblem should be revived, there + is nothing more to do */ + if (node == root) goto done; + xassert(mip->m == tree->root_m); + /* build path from the root to the current node */ + node->temp = NULL; + for (node = node; node != NULL; node = node->up) + { if (node->up == NULL) + xassert(node == root); + else + node->up->temp = node; + } + /* go down from the root to the current node and make necessary + changes to restore components of the current subproblem */ + for (node = root; node != NULL; node = node->temp) + { int m = mip->m; + int n = mip->n; + /* if the current node is reached, the problem object at this + point corresponds to its parent, so save attributes of rows + and columns for the parent subproblem */ + if (node->temp == NULL) + { int i, j; + tree->pred_m = m; + /* allocate/reallocate arrays, if necessary */ + if (tree->pred_max < m + n) + { int new_size = m + n + 100; + if (tree->pred_type != NULL) xfree(tree->pred_type); + if (tree->pred_lb != NULL) xfree(tree->pred_lb); + if (tree->pred_ub != NULL) xfree(tree->pred_ub); + if (tree->pred_stat != NULL) xfree(tree->pred_stat); + tree->pred_max = new_size; + tree->pred_type = xcalloc(1+new_size, sizeof(char)); + tree->pred_lb = xcalloc(1+new_size, sizeof(double)); + tree->pred_ub = xcalloc(1+new_size, sizeof(double)); + tree->pred_stat = xcalloc(1+new_size, sizeof(char)); + } + /* save row attributes */ + for (i = 1; i <= m; i++) + { GLPROW *row = mip->row[i]; + tree->pred_type[i] = (char)row->type; + tree->pred_lb[i] = row->lb; + tree->pred_ub[i] = row->ub; + tree->pred_stat[i] = (char)row->stat; + } + /* save column attributes */ + for (j = 1; j <= n; j++) + { GLPCOL *col = mip->col[j]; + tree->pred_type[mip->m+j] = (char)col->type; + tree->pred_lb[mip->m+j] = col->lb; + tree->pred_ub[mip->m+j] = col->ub; + tree->pred_stat[mip->m+j] = (char)col->stat; + } + } + /* change bounds of rows and columns */ + { IOSBND *b; + for (b = node->b_ptr; b != NULL; b = b->next) + { if (b->k <= m) + glp_set_row_bnds(mip, b->k, b->type, b->lb, b->ub); + else + glp_set_col_bnds(mip, b->k-m, b->type, b->lb, b->ub); + } + } + /* change statuses of rows and columns */ + { IOSTAT *s; + for (s = node->s_ptr; s != NULL; s = s->next) + { if (s->k <= m) + glp_set_row_stat(mip, s->k, s->stat); + else + glp_set_col_stat(mip, s->k-m, s->stat); + } + } + /* add new rows */ + if (node->r_ptr != NULL) + { IOSROW *r; + IOSAIJ *a; + int i, len, *ind; + double *val; + ind = xcalloc(1+n, sizeof(int)); + val = xcalloc(1+n, sizeof(double)); + for (r = node->r_ptr; r != NULL; r = r->next) + { i = glp_add_rows(mip, 1); + glp_set_row_name(mip, i, r->name); +#if 1 /* 20/IX-2008 */ + xassert(mip->row[i]->level == 0); + mip->row[i]->level = node->level; + mip->row[i]->origin = r->origin; + mip->row[i]->klass = r->klass; +#endif + glp_set_row_bnds(mip, i, r->type, r->lb, r->ub); + len = 0; + for (a = r->ptr; a != NULL; a = a->next) + len++, ind[len] = a->j, val[len] = a->val; + glp_set_mat_row(mip, i, len, ind, val); + glp_set_rii(mip, i, r->rii); + glp_set_row_stat(mip, i, r->stat); + } + xfree(ind); + xfree(val); + } +#if 0 + /* add new edges to the conflict graph */ + /* add new cliques to the conflict graph */ + /* (not implemented yet) */ + xassert(node->own_nn == 0); + xassert(node->own_nc == 0); + xassert(node->e_ptr == NULL); +#endif + } + /* the specified subproblem has been revived */ + node = tree->curr; + /* delete its bound change list */ + while (node->b_ptr != NULL) + { IOSBND *b; + b = node->b_ptr; + node->b_ptr = b->next; + dmp_free_atom(tree->pool, b, sizeof(IOSBND)); + } + /* delete its status change list */ + while (node->s_ptr != NULL) + { IOSTAT *s; + s = node->s_ptr; + node->s_ptr = s->next; + dmp_free_atom(tree->pool, s, sizeof(IOSTAT)); + } +#if 1 /* 20/XI-2009 */ + /* delete its row addition list (additional rows may appear, for + example, due to branching on GUB constraints */ + while (node->r_ptr != NULL) + { IOSROW *r; + r = node->r_ptr; + node->r_ptr = r->next; + xassert(r->name == NULL); + while (r->ptr != NULL) + { IOSAIJ *a; + a = r->ptr; + r->ptr = a->next; + dmp_free_atom(tree->pool, a, sizeof(IOSAIJ)); + } + dmp_free_atom(tree->pool, r, sizeof(IOSROW)); + } +#endif +done: return; +} + +/*********************************************************************** +* NAME +* +* ios_freeze_node - freeze current subproblem +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_freeze_node(glp_tree *tree); +* +* DESCRIPTION +* +* The routine ios_freeze_node freezes the current subproblem. */ + +void ios_freeze_node(glp_tree *tree) +{ glp_prob *mip = tree->mip; + int m = mip->m; + int n = mip->n; + IOSNPD *node; + /* obtain pointer to the current subproblem */ + node = tree->curr; + xassert(node != NULL); + if (node->up == NULL) + { /* freeze the root subproblem */ + int k; + xassert(node->p == 1); + xassert(tree->root_m == 0); + xassert(tree->root_type == NULL); + xassert(tree->root_lb == NULL); + xassert(tree->root_ub == NULL); + xassert(tree->root_stat == NULL); + tree->root_m = m; + tree->root_type = xcalloc(1+m+n, sizeof(char)); + tree->root_lb = xcalloc(1+m+n, sizeof(double)); + tree->root_ub = xcalloc(1+m+n, sizeof(double)); + tree->root_stat = xcalloc(1+m+n, sizeof(char)); + for (k = 1; k <= m+n; k++) + { if (k <= m) + { GLPROW *row = mip->row[k]; + tree->root_type[k] = (char)row->type; + tree->root_lb[k] = row->lb; + tree->root_ub[k] = row->ub; + tree->root_stat[k] = (char)row->stat; + } + else + { GLPCOL *col = mip->col[k-m]; + tree->root_type[k] = (char)col->type; + tree->root_lb[k] = col->lb; + tree->root_ub[k] = col->ub; + tree->root_stat[k] = (char)col->stat; + } + } + } + else + { /* freeze non-root subproblem */ + int root_m = tree->root_m; + int pred_m = tree->pred_m; + int i, j, k; + xassert(pred_m <= m); + /* build change lists for rows and columns which exist in the + parent subproblem */ + xassert(node->b_ptr == NULL); + xassert(node->s_ptr == NULL); + for (k = 1; k <= pred_m + n; k++) + { int pred_type, pred_stat, type, stat; + double pred_lb, pred_ub, lb, ub; + /* determine attributes in the parent subproblem */ + pred_type = tree->pred_type[k]; + pred_lb = tree->pred_lb[k]; + pred_ub = tree->pred_ub[k]; + pred_stat = tree->pred_stat[k]; + /* determine attributes in the current subproblem */ + if (k <= pred_m) + { GLPROW *row = mip->row[k]; + type = row->type; + lb = row->lb; + ub = row->ub; + stat = row->stat; + } + else + { GLPCOL *col = mip->col[k - pred_m]; + type = col->type; + lb = col->lb; + ub = col->ub; + stat = col->stat; + } + /* save type and bounds of a row/column, if changed */ + if (!(pred_type == type && pred_lb == lb && pred_ub == ub)) + { IOSBND *b; + b = dmp_get_atom(tree->pool, sizeof(IOSBND)); + b->k = k; + b->type = (unsigned char)type; + b->lb = lb; + b->ub = ub; + b->next = node->b_ptr; + node->b_ptr = b; + } + /* save status of a row/column, if changed */ + if (pred_stat != stat) + { IOSTAT *s; + s = dmp_get_atom(tree->pool, sizeof(IOSTAT)); + s->k = k; + s->stat = (unsigned char)stat; + s->next = node->s_ptr; + node->s_ptr = s; + } + } + /* save new rows added to the current subproblem */ + xassert(node->r_ptr == NULL); + if (pred_m < m) + { int i, len, *ind; + double *val; + ind = xcalloc(1+n, sizeof(int)); + val = xcalloc(1+n, sizeof(double)); + for (i = m; i > pred_m; i--) + { GLPROW *row = mip->row[i]; + IOSROW *r; + const char *name; + r = dmp_get_atom(tree->pool, sizeof(IOSROW)); + name = glp_get_row_name(mip, i); + if (name == NULL) + r->name = NULL; + else + { r->name = dmp_get_atom(tree->pool, strlen(name)+1); + strcpy(r->name, name); + } +#if 1 /* 20/IX-2008 */ + r->origin = row->origin; + r->klass = row->klass; +#endif + r->type = (unsigned char)row->type; + r->lb = row->lb; + r->ub = row->ub; + r->ptr = NULL; + len = glp_get_mat_row(mip, i, ind, val); + for (k = 1; k <= len; k++) + { IOSAIJ *a; + a = dmp_get_atom(tree->pool, sizeof(IOSAIJ)); + a->j = ind[k]; + a->val = val[k]; + a->next = r->ptr; + r->ptr = a; + } + r->rii = row->rii; + r->stat = (unsigned char)row->stat; + r->next = node->r_ptr; + node->r_ptr = r; + } + xfree(ind); + xfree(val); + } + /* remove all rows missing in the root subproblem */ + if (m != root_m) + { int nrs, *num; + nrs = m - root_m; + xassert(nrs > 0); + num = xcalloc(1+nrs, sizeof(int)); + for (i = 1; i <= nrs; i++) num[i] = root_m + i; + glp_del_rows(mip, nrs, num); + xfree(num); + } + m = mip->m; + /* and restore attributes of all rows and columns for the root + subproblem */ + xassert(m == root_m); + for (i = 1; i <= m; i++) + { glp_set_row_bnds(mip, i, tree->root_type[i], + tree->root_lb[i], tree->root_ub[i]); + glp_set_row_stat(mip, i, tree->root_stat[i]); + } + for (j = 1; j <= n; j++) + { glp_set_col_bnds(mip, j, tree->root_type[m+j], + tree->root_lb[m+j], tree->root_ub[m+j]); + glp_set_col_stat(mip, j, tree->root_stat[m+j]); + } +#if 1 + /* remove all edges and cliques missing in the conflict graph + for the root subproblem */ + /* (not implemented yet) */ +#endif + } + /* the current subproblem has been frozen */ + tree->curr = NULL; + return; +} + +/*********************************************************************** +* NAME +* +* ios_clone_node - clone specified subproblem +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_clone_node(glp_tree *tree, int p, int nnn, int ref[]); +* +* DESCRIPTION +* +* The routine ios_clone_node clones the specified subproblem, whose +* reference number is p, creating its nnn exact copies. Note that the +* specified subproblem must be active and must be in the frozen state +* (i.e. it must not be the current subproblem). +* +* Each clone, an exact copy of the specified subproblem, becomes a new +* active subproblem added to the end of the active list. After cloning +* the specified subproblem becomes inactive. +* +* The reference numbers of clone subproblems are stored to locations +* ref[1], ..., ref[nnn]. */ + +static int get_slot(glp_tree *tree) +{ int p; + /* if no free slots are available, increase the room */ + if (tree->avail == 0) + { int nslots = tree->nslots; + IOSLOT *save = tree->slot; + if (nslots == 0) + tree->nslots = 20; + else + { tree->nslots = nslots + nslots; + xassert(tree->nslots > nslots); + } + tree->slot = xcalloc(1+tree->nslots, sizeof(IOSLOT)); + if (save != NULL) + { memcpy(&tree->slot[1], &save[1], nslots * sizeof(IOSLOT)); + xfree(save); + } + /* push more free slots into the stack */ + for (p = tree->nslots; p > nslots; p--) + { tree->slot[p].node = NULL; + tree->slot[p].next = tree->avail; + tree->avail = p; + } + } + /* pull a free slot from the stack */ + p = tree->avail; + tree->avail = tree->slot[p].next; + xassert(tree->slot[p].node == NULL); + tree->slot[p].next = 0; + return p; +} + +static IOSNPD *new_node(glp_tree *tree, IOSNPD *parent) +{ IOSNPD *node; + int p; + /* pull a free slot for the new node */ + p = get_slot(tree); + /* create descriptor of the new subproblem */ + node = dmp_get_atom(tree->pool, sizeof(IOSNPD)); + tree->slot[p].node = node; + node->p = p; + node->up = parent; + node->level = (parent == NULL ? 0 : parent->level + 1); + node->count = 0; + node->b_ptr = NULL; + node->s_ptr = NULL; + node->r_ptr = NULL; + node->solved = 0; +#if 0 + node->own_nn = node->own_nc = 0; + node->e_ptr = NULL; +#endif +#if 1 /* 04/X-2008 */ + node->lp_obj = (parent == NULL ? (tree->mip->dir == GLP_MIN ? + -DBL_MAX : +DBL_MAX) : parent->lp_obj); +#endif + node->bound = (parent == NULL ? (tree->mip->dir == GLP_MIN ? + -DBL_MAX : +DBL_MAX) : parent->bound); + node->br_var = 0; + node->br_val = 0.0; + node->ii_cnt = 0; + node->ii_sum = 0.0; +#if 1 /* 30/XI-2009 */ + node->changed = 0; +#endif + if (tree->parm->cb_size == 0) + node->data = NULL; + else + { node->data = dmp_get_atom(tree->pool, tree->parm->cb_size); + memset(node->data, 0, tree->parm->cb_size); + } + node->temp = NULL; + node->prev = tree->tail; + node->next = NULL; + /* add the new subproblem to the end of the active list */ + if (tree->head == NULL) + tree->head = node; + else + tree->tail->next = node; + tree->tail = node; + tree->a_cnt++; + tree->n_cnt++; + tree->t_cnt++; + /* increase the number of child subproblems */ + if (parent == NULL) + xassert(p == 1); + else + parent->count++; + return node; +} + +void ios_clone_node(glp_tree *tree, int p, int nnn, int ref[]) +{ IOSNPD *node; + int k; + /* obtain pointer to the subproblem to be cloned */ + xassert(1 <= p && p <= tree->nslots); + node = tree->slot[p].node; + xassert(node != NULL); + /* the specified subproblem must be active */ + xassert(node->count == 0); + /* and must be in the frozen state */ + xassert(tree->curr != node); + /* remove the specified subproblem from the active list, because + it becomes inactive */ + if (node->prev == NULL) + tree->head = node->next; + else + node->prev->next = node->next; + if (node->next == NULL) + tree->tail = node->prev; + else + node->next->prev = node->prev; + node->prev = node->next = NULL; + tree->a_cnt--; + /* create clone subproblems */ + xassert(nnn > 0); + for (k = 1; k <= nnn; k++) + ref[k] = new_node(tree, node)->p; + return; +} + +/*********************************************************************** +* NAME +* +* ios_delete_node - delete specified subproblem +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_delete_node(glp_tree *tree, int p); +* +* DESCRIPTION +* +* The routine ios_delete_node deletes the specified subproblem, whose +* reference number is p. The subproblem must be active and must be in +* the frozen state (i.e. it must not be the current subproblem). +* +* Note that deletion is performed recursively, i.e. if a subproblem to +* be deleted is the only child of its parent, the parent subproblem is +* also deleted, etc. */ + +void ios_delete_node(glp_tree *tree, int p) +{ IOSNPD *node, *temp; + /* obtain pointer to the subproblem to be deleted */ + xassert(1 <= p && p <= tree->nslots); + node = tree->slot[p].node; + xassert(node != NULL); + /* the specified subproblem must be active */ + xassert(node->count == 0); + /* and must be in the frozen state */ + xassert(tree->curr != node); + /* remove the specified subproblem from the active list, because + it is gone from the tree */ + if (node->prev == NULL) + tree->head = node->next; + else + node->prev->next = node->next; + if (node->next == NULL) + tree->tail = node->prev; + else + node->next->prev = node->prev; + node->prev = node->next = NULL; + tree->a_cnt--; +loop: /* recursive deletion starts here */ + /* delete the bound change list */ + { IOSBND *b; + while (node->b_ptr != NULL) + { b = node->b_ptr; + node->b_ptr = b->next; + dmp_free_atom(tree->pool, b, sizeof(IOSBND)); + } + } + /* delete the status change list */ + { IOSTAT *s; + while (node->s_ptr != NULL) + { s = node->s_ptr; + node->s_ptr = s->next; + dmp_free_atom(tree->pool, s, sizeof(IOSTAT)); + } + } + /* delete the row addition list */ + while (node->r_ptr != NULL) + { IOSROW *r; + r = node->r_ptr; + if (r->name != NULL) + dmp_free_atom(tree->pool, r->name, strlen(r->name)+1); + while (r->ptr != NULL) + { IOSAIJ *a; + a = r->ptr; + r->ptr = a->next; + dmp_free_atom(tree->pool, a, sizeof(IOSAIJ)); + } + node->r_ptr = r->next; + dmp_free_atom(tree->pool, r, sizeof(IOSROW)); + } +#if 0 + /* delete the edge addition list */ + /* delete the clique addition list */ + /* (not implemented yet) */ + xassert(node->own_nn == 0); + xassert(node->own_nc == 0); + xassert(node->e_ptr == NULL); +#endif + /* free application-specific data */ + if (tree->parm->cb_size == 0) + xassert(node->data == NULL); + else + dmp_free_atom(tree->pool, node->data, tree->parm->cb_size); + /* free the corresponding node slot */ + p = node->p; + xassert(tree->slot[p].node == node); + tree->slot[p].node = NULL; + tree->slot[p].next = tree->avail; + tree->avail = p; + /* save pointer to the parent subproblem */ + temp = node->up; + /* delete the subproblem descriptor */ + dmp_free_atom(tree->pool, node, sizeof(IOSNPD)); + tree->n_cnt--; + /* take pointer to the parent subproblem */ + node = temp; + if (node != NULL) + { /* the parent subproblem exists; decrease the number of its + child subproblems */ + xassert(node->count > 0); + node->count--; + /* if now the parent subproblem has no childs, it also must be + deleted */ + if (node->count == 0) goto loop; + } + return; +} + +/*********************************************************************** +* NAME +* +* ios_delete_tree - delete branch-and-bound tree +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_delete_tree(glp_tree *tree); +* +* DESCRIPTION +* +* The routine ios_delete_tree deletes the branch-and-bound tree, which +* the parameter tree points to, and frees all the memory allocated to +* this program object. +* +* On exit components of the problem object are restored to correspond +* to the original MIP passed to the routine ios_create_tree. */ + +void ios_delete_tree(glp_tree *tree) +{ glp_prob *mip = tree->mip; + int i, j; + int m = mip->m; + int n = mip->n; + xassert(mip->tree == tree); + /* remove all additional rows */ + if (m != tree->orig_m) + { int nrs, *num; + nrs = m - tree->orig_m; + xassert(nrs > 0); + num = xcalloc(1+nrs, sizeof(int)); + for (i = 1; i <= nrs; i++) num[i] = tree->orig_m + i; + glp_del_rows(mip, nrs, num); + xfree(num); + } + m = tree->orig_m; + /* restore original attributes of rows and columns */ + xassert(m == tree->orig_m); + xassert(n == tree->n); + for (i = 1; i <= m; i++) + { glp_set_row_bnds(mip, i, tree->orig_type[i], + tree->orig_lb[i], tree->orig_ub[i]); + glp_set_row_stat(mip, i, tree->orig_stat[i]); + mip->row[i]->prim = tree->orig_prim[i]; + mip->row[i]->dual = tree->orig_dual[i]; + } + for (j = 1; j <= n; j++) + { glp_set_col_bnds(mip, j, tree->orig_type[m+j], + tree->orig_lb[m+j], tree->orig_ub[m+j]); + glp_set_col_stat(mip, j, tree->orig_stat[m+j]); + mip->col[j]->prim = tree->orig_prim[m+j]; + mip->col[j]->dual = tree->orig_dual[m+j]; + } + mip->pbs_stat = mip->dbs_stat = GLP_FEAS; + mip->obj_val = tree->orig_obj; + /* delete the branch-and-bound tree */ + xassert(tree->local != NULL); + ios_delete_pool(tree, tree->local); + dmp_delete_pool(tree->pool); + xfree(tree->orig_type); + xfree(tree->orig_lb); + xfree(tree->orig_ub); + xfree(tree->orig_stat); + xfree(tree->orig_prim); + xfree(tree->orig_dual); + xfree(tree->slot); + if (tree->root_type != NULL) xfree(tree->root_type); + if (tree->root_lb != NULL) xfree(tree->root_lb); + if (tree->root_ub != NULL) xfree(tree->root_ub); + if (tree->root_stat != NULL) xfree(tree->root_stat); + xfree(tree->non_int); +#if 0 + xfree(tree->n_ref); + xfree(tree->c_ref); + xfree(tree->j_ref); +#endif + if (tree->pcost != NULL) ios_pcost_free(tree); + xfree(tree->iwrk); + xfree(tree->dwrk); +#if 0 + scg_delete_graph(tree->g); +#endif + if (tree->pred_type != NULL) xfree(tree->pred_type); + if (tree->pred_lb != NULL) xfree(tree->pred_lb); + if (tree->pred_ub != NULL) xfree(tree->pred_ub); + if (tree->pred_stat != NULL) xfree(tree->pred_stat); +#if 0 + xassert(tree->cut_gen == NULL); +#endif + xassert(tree->mir_gen == NULL); + xassert(tree->clq_gen == NULL); + xfree(tree); + mip->tree = NULL; + return; +} + +/*********************************************************************** +* NAME +* +* ios_eval_degrad - estimate obj. degrad. for down- and up-branches +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_eval_degrad(glp_tree *tree, int j, double *dn, double *up); +* +* DESCRIPTION +* +* Given optimal basis to LP relaxation of the current subproblem the +* routine ios_eval_degrad performs the dual ratio test to compute the +* objective values in the adjacent basis for down- and up-branches, +* which are stored in locations *dn and *up, assuming that x[j] is a +* variable chosen to branch upon. */ + +void ios_eval_degrad(glp_tree *tree, int j, double *dn, double *up) +{ glp_prob *mip = tree->mip; + int m = mip->m, n = mip->n; + int len, kase, k, t, stat; + double alfa, beta, gamma, delta, dz; + int *ind = tree->iwrk; + double *val = tree->dwrk; + /* current basis must be optimal */ + xassert(glp_get_status(mip) == GLP_OPT); + /* basis factorization must exist */ + xassert(glp_bf_exists(mip)); + /* obtain (fractional) value of x[j] in optimal basic solution + to LP relaxation of the current subproblem */ + xassert(1 <= j && j <= n); + beta = mip->col[j]->prim; + /* since the value of x[j] is fractional, it is basic; compute + corresponding row of the simplex table */ + len = lpx_eval_tab_row(mip, m+j, ind, val); + /* kase < 0 means down-branch; kase > 0 means up-branch */ + for (kase = -1; kase <= +1; kase += 2) + { /* for down-branch we introduce new upper bound floor(beta) + for x[j]; similarly, for up-branch we introduce new lower + bound ceil(beta) for x[j]; in the current basis this new + upper/lower bound is violated, so in the adjacent basis + x[j] will leave the basis and go to its new upper/lower + bound; we need to know which non-basic variable x[k] should + enter the basis to keep dual feasibility */ +#if 0 /* 23/XI-2009 */ + k = lpx_dual_ratio_test(mip, len, ind, val, kase, 1e-7); +#else + k = lpx_dual_ratio_test(mip, len, ind, val, kase, 1e-9); +#endif + /* if no variable has been chosen, current basis being primal + infeasible due to the new upper/lower bound of x[j] is dual + unbounded, therefore, LP relaxation to corresponding branch + has no primal feasible solution */ + if (k == 0) + { if (mip->dir == GLP_MIN) + { if (kase < 0) + *dn = +DBL_MAX; + else + *up = +DBL_MAX; + } + else if (mip->dir == GLP_MAX) + { if (kase < 0) + *dn = -DBL_MAX; + else + *up = -DBL_MAX; + } + else + xassert(mip != mip); + continue; + } + xassert(1 <= k && k <= m+n); + /* row of the simplex table corresponding to specified basic + variable x[j] is the following: + x[j] = ... + alfa * x[k] + ... ; + we need to know influence coefficient, alfa, at non-basic + variable x[k] chosen with the dual ratio test */ + for (t = 1; t <= len; t++) + if (ind[t] == k) break; + xassert(1 <= t && t <= len); + alfa = val[t]; + /* determine status and reduced cost of variable x[k] */ + if (k <= m) + { stat = mip->row[k]->stat; + gamma = mip->row[k]->dual; + } + else + { stat = mip->col[k-m]->stat; + gamma = mip->col[k-m]->dual; + } + /* x[k] cannot be basic or fixed non-basic */ + xassert(stat == GLP_NL || stat == GLP_NU || stat == GLP_NF); + /* if the current basis is dual degenerative, some reduced + costs, which are close to zero, may have wrong sign due to + round-off errors, so correct the sign of gamma */ + if (mip->dir == GLP_MIN) + { if (stat == GLP_NL && gamma < 0.0 || + stat == GLP_NU && gamma > 0.0 || + stat == GLP_NF) gamma = 0.0; + } + else if (mip->dir == GLP_MAX) + { if (stat == GLP_NL && gamma > 0.0 || + stat == GLP_NU && gamma < 0.0 || + stat == GLP_NF) gamma = 0.0; + } + else + xassert(mip != mip); + /* determine the change of x[j] in the adjacent basis: + delta x[j] = new x[j] - old x[j] */ + delta = (kase < 0 ? floor(beta) : ceil(beta)) - beta; + /* compute the change of x[k] in the adjacent basis: + delta x[k] = new x[k] - old x[k] = delta x[j] / alfa */ + delta /= alfa; + /* compute the change of the objective in the adjacent basis: + delta z = new z - old z = gamma * delta x[k] */ + dz = gamma * delta; + if (mip->dir == GLP_MIN) + xassert(dz >= 0.0); + else if (mip->dir == GLP_MAX) + xassert(dz <= 0.0); + else + xassert(mip != mip); + /* compute the new objective value in the adjacent basis: + new z = old z + delta z */ + if (kase < 0) + *dn = mip->obj_val + dz; + else + *up = mip->obj_val + dz; + } + /*xprintf("obj = %g; dn = %g; up = %g\n", + mip->obj_val, *dn, *up);*/ + return; +} + +/*********************************************************************** +* NAME +* +* ios_round_bound - improve local bound by rounding +* +* SYNOPSIS +* +* #include "glpios.h" +* double ios_round_bound(glp_tree *tree, double bound); +* +* RETURNS +* +* For the given local bound for any integer feasible solution to the +* current subproblem the routine ios_round_bound returns an improved +* local bound for the same integer feasible solution. +* +* BACKGROUND +* +* Let the current subproblem has the following objective function: +* +* z = sum c[j] * x[j] + s >= b, (1) +* j in J +* +* where J = {j: c[j] is non-zero and integer, x[j] is integer}, s is +* the sum of terms corresponding to fixed variables, b is an initial +* local bound (minimization). +* +* From (1) it follows that: +* +* d * sum (c[j] / d) * x[j] + s >= b, (2) +* j in J +* +* or, equivalently, +* +* sum (c[j] / d) * x[j] >= (b - s) / d = h, (3) +* j in J +* +* where d = gcd(c[j]). Since the left-hand side of (3) is integer, +* h = (b - s) / d can be rounded up to the nearest integer: +* +* h' = ceil(h) = (b' - s) / d, (4) +* +* that gives an rounded, improved local bound: +* +* b' = d * h' + s. (5) +* +* In case of maximization '>=' in (1) should be replaced by '<=' that +* leads to the following formula: +* +* h' = floor(h) = (b' - s) / d, (6) +* +* which should used in the same way as (4). +* +* NOTE: If b is a valid local bound for a child of the current +* subproblem, b' is also valid for that child subproblem. */ + +double ios_round_bound(glp_tree *tree, double bound) +{ glp_prob *mip = tree->mip; + int n = mip->n; + int d, j, nn, *c = tree->iwrk; + double s, h; + /* determine c[j] and compute s */ + nn = 0, s = mip->c0, d = 0; + for (j = 1; j <= n; j++) + { GLPCOL *col = mip->col[j]; + if (col->coef == 0.0) continue; + if (col->type == GLP_FX) + { /* fixed variable */ + s += col->coef * col->prim; + } + else + { /* non-fixed variable */ + if (col->kind != GLP_IV) goto skip; + if (col->coef != floor(col->coef)) goto skip; + if (fabs(col->coef) <= (double)INT_MAX) + c[++nn] = (int)fabs(col->coef); + else + d = 1; + } + } + /* compute d = gcd(c[1],...c[nn]) */ + if (d == 0) + { if (nn == 0) goto skip; + d = gcdn(nn, c); + } + xassert(d > 0); + /* compute new local bound */ + if (mip->dir == GLP_MIN) + { if (bound != +DBL_MAX) + { h = (bound - s) / (double)d; + if (h >= floor(h) + 0.001) + { /* round up */ + h = ceil(h); + /*xprintf("d = %d; old = %g; ", d, bound);*/ + bound = (double)d * h + s; + /*xprintf("new = %g\n", bound);*/ + } + } + } + else if (mip->dir == GLP_MAX) + { if (bound != -DBL_MAX) + { h = (bound - s) / (double)d; + if (h <= ceil(h) - 0.001) + { /* round down */ + h = floor(h); + bound = (double)d * h + s; + } + } + } + else + xassert(mip != mip); +skip: return bound; +} + +/*********************************************************************** +* NAME +* +* ios_is_hopeful - check if subproblem is hopeful +* +* SYNOPSIS +* +* #include "glpios.h" +* int ios_is_hopeful(glp_tree *tree, double bound); +* +* DESCRIPTION +* +* Given the local bound of a subproblem the routine ios_is_hopeful +* checks if the subproblem can have an integer optimal solution which +* is better than the best one currently known. +* +* RETURNS +* +* If the subproblem can have a better integer optimal solution, the +* routine returns non-zero; otherwise, if the corresponding branch can +* be pruned, the routine returns zero. */ + +int ios_is_hopeful(glp_tree *tree, double bound) +{ glp_prob *mip = tree->mip; + int ret = 1; + double eps; + if (mip->mip_stat == GLP_FEAS) + { eps = tree->parm->tol_obj * (1.0 + fabs(mip->mip_obj)); + switch (mip->dir) + { case GLP_MIN: + if (bound >= mip->mip_obj - eps) ret = 0; + break; + case GLP_MAX: + if (bound <= mip->mip_obj + eps) ret = 0; + break; + default: + xassert(mip != mip); + } + } + else + { switch (mip->dir) + { case GLP_MIN: + if (bound == +DBL_MAX) ret = 0; + break; + case GLP_MAX: + if (bound == -DBL_MAX) ret = 0; + break; + default: + xassert(mip != mip); + } + } + return ret; +} + +/*********************************************************************** +* NAME +* +* ios_best_node - find active node with best local bound +* +* SYNOPSIS +* +* #include "glpios.h" +* int ios_best_node(glp_tree *tree); +* +* DESCRIPTION +* +* The routine ios_best_node finds an active node whose local bound is +* best among other active nodes. +* +* It is understood that the integer optimal solution of the original +* mip problem cannot be better than the best bound, so the best bound +* is an lower (minimization) or upper (maximization) global bound for +* the original problem. +* +* RETURNS +* +* The routine ios_best_node returns the subproblem reference number +* for the best node. However, if the tree is empty, it returns zero. */ + +int ios_best_node(glp_tree *tree) +{ IOSNPD *node, *best = NULL; + switch (tree->mip->dir) + { case GLP_MIN: + /* minimization */ + for (node = tree->head; node != NULL; node = node->next) + if (best == NULL || best->bound > node->bound) + best = node; + break; + case GLP_MAX: + /* maximization */ + for (node = tree->head; node != NULL; node = node->next) + if (best == NULL || best->bound < node->bound) + best = node; + break; + default: + xassert(tree != tree); + } + return best == NULL ? 0 : best->p; +} + +/*********************************************************************** +* NAME +* +* ios_relative_gap - compute relative mip gap +* +* SYNOPSIS +* +* #include "glpios.h" +* double ios_relative_gap(glp_tree *tree); +* +* DESCRIPTION +* +* The routine ios_relative_gap computes the relative mip gap using the +* formula: +* +* gap = |best_mip - best_bnd| / (|best_mip| + DBL_EPSILON), +* +* where best_mip is the best integer feasible solution found so far, +* best_bnd is the best (global) bound. If no integer feasible solution +* has been found yet, rel_gap is set to DBL_MAX. +* +* RETURNS +* +* The routine ios_relative_gap returns the relative mip gap. */ + +double ios_relative_gap(glp_tree *tree) +{ glp_prob *mip = tree->mip; + int p; + double best_mip, best_bnd, gap; + if (mip->mip_stat == GLP_FEAS) + { best_mip = mip->mip_obj; + p = ios_best_node(tree); + if (p == 0) + { /* the tree is empty */ + gap = 0.0; + } + else + { best_bnd = tree->slot[p].node->bound; + gap = fabs(best_mip - best_bnd) / (fabs(best_mip) + + DBL_EPSILON); + } + } + else + { /* no integer feasible solution has been found yet */ + gap = DBL_MAX; + } + return gap; +} + +/*********************************************************************** +* NAME +* +* ios_solve_node - solve LP relaxation of current subproblem +* +* SYNOPSIS +* +* #include "glpios.h" +* int ios_solve_node(glp_tree *tree); +* +* DESCRIPTION +* +* The routine ios_solve_node re-optimizes LP relaxation of the current +* subproblem using the dual simplex method. +* +* RETURNS +* +* The routine returns the code which is reported by glp_simplex. */ + +int ios_solve_node(glp_tree *tree) +{ glp_prob *mip = tree->mip; + glp_smcp parm; + int ret; + /* the current subproblem must exist */ + xassert(tree->curr != NULL); + /* set some control parameters */ + glp_init_smcp(&parm); + switch (tree->parm->msg_lev) + { case GLP_MSG_OFF: + parm.msg_lev = GLP_MSG_OFF; break; + case GLP_MSG_ERR: + parm.msg_lev = GLP_MSG_ERR; break; + case GLP_MSG_ON: + case GLP_MSG_ALL: + parm.msg_lev = GLP_MSG_ON; break; + case GLP_MSG_DBG: + parm.msg_lev = GLP_MSG_ALL; break; + default: + xassert(tree != tree); + } + parm.meth = GLP_DUALP; + if (tree->parm->msg_lev < GLP_MSG_DBG) + parm.out_dly = tree->parm->out_dly; + else + parm.out_dly = 0; + /* if the incumbent objective value is already known, use it to + prematurely terminate the dual simplex search */ + if (mip->mip_stat == GLP_FEAS) + { switch (tree->mip->dir) + { case GLP_MIN: + parm.obj_ul = mip->mip_obj; + break; + case GLP_MAX: + parm.obj_ll = mip->mip_obj; + break; + default: + xassert(mip != mip); + } + } + /* try to solve/re-optimize the LP relaxation */ + ret = glp_simplex(mip, &parm); + tree->curr->solved++; +#if 0 + xprintf("ret = %d; status = %d; pbs = %d; dbs = %d; some = %d\n", + ret, glp_get_status(mip), mip->pbs_stat, mip->dbs_stat, + mip->some); + lpx_print_sol(mip, "sol"); +#endif + return ret; +} + +/**********************************************************************/ + +IOSPOOL *ios_create_pool(glp_tree *tree) +{ /* create cut pool */ + IOSPOOL *pool; +#if 0 + pool = dmp_get_atom(tree->pool, sizeof(IOSPOOL)); +#else + xassert(tree == tree); + pool = xmalloc(sizeof(IOSPOOL)); +#endif + pool->size = 0; + pool->head = pool->tail = NULL; + pool->ord = 0, pool->curr = NULL; + return pool; +} + +int ios_add_row(glp_tree *tree, IOSPOOL *pool, + const char *name, int klass, int flags, int len, const int ind[], + const double val[], int type, double rhs) +{ /* add row (constraint) to the cut pool */ + IOSCUT *cut; + IOSAIJ *aij; + int k; + xassert(pool != NULL); + cut = dmp_get_atom(tree->pool, sizeof(IOSCUT)); + if (name == NULL || name[0] == '\0') + cut->name = NULL; + else + { for (k = 0; name[k] != '\0'; k++) + { if (k == 256) + xerror("glp_ios_add_row: cut name too long\n"); + if (iscntrl((unsigned char)name[k])) + xerror("glp_ios_add_row: cut name contains invalid chara" + "cter(s)\n"); + } + cut->name = dmp_get_atom(tree->pool, strlen(name)+1); + strcpy(cut->name, name); + } + if (!(0 <= klass && klass <= 255)) + xerror("glp_ios_add_row: klass = %d; invalid cut class\n", + klass); + cut->klass = (unsigned char)klass; + if (flags != 0) + xerror("glp_ios_add_row: flags = %d; invalid cut flags\n", + flags); + cut->ptr = NULL; + if (!(0 <= len && len <= tree->n)) + xerror("glp_ios_add_row: len = %d; invalid cut length\n", + len); + for (k = 1; k <= len; k++) + { aij = dmp_get_atom(tree->pool, sizeof(IOSAIJ)); + if (!(1 <= ind[k] && ind[k] <= tree->n)) + xerror("glp_ios_add_row: ind[%d] = %d; column index out of " + "range\n", k, ind[k]); + aij->j = ind[k]; + aij->val = val[k]; + aij->next = cut->ptr; + cut->ptr = aij; + } + if (!(type == GLP_LO || type == GLP_UP || type == GLP_FX)) + xerror("glp_ios_add_row: type = %d; invalid cut type\n", + type); + cut->type = (unsigned char)type; + cut->rhs = rhs; + cut->prev = pool->tail; + cut->next = NULL; + if (cut->prev == NULL) + pool->head = cut; + else + cut->prev->next = cut; + pool->tail = cut; + pool->size++; + return pool->size; +} + +IOSCUT *ios_find_row(IOSPOOL *pool, int i) +{ /* find row (constraint) in the cut pool */ + /* (smart linear search) */ + xassert(pool != NULL); + xassert(1 <= i && i <= pool->size); + if (pool->ord == 0) + { xassert(pool->curr == NULL); + pool->ord = 1; + pool->curr = pool->head; + } + xassert(pool->curr != NULL); + if (i < pool->ord) + { if (i < pool->ord - i) + { pool->ord = 1; + pool->curr = pool->head; + while (pool->ord != i) + { pool->ord++; + xassert(pool->curr != NULL); + pool->curr = pool->curr->next; + } + } + else + { while (pool->ord != i) + { pool->ord--; + xassert(pool->curr != NULL); + pool->curr = pool->curr->prev; + } + } + } + else if (i > pool->ord) + { if (i - pool->ord < pool->size - i) + { while (pool->ord != i) + { pool->ord++; + xassert(pool->curr != NULL); + pool->curr = pool->curr->next; + } + } + else + { pool->ord = pool->size; + pool->curr = pool->tail; + while (pool->ord != i) + { pool->ord--; + xassert(pool->curr != NULL); + pool->curr = pool->curr->prev; + } + } + } + xassert(pool->ord == i); + xassert(pool->curr != NULL); + return pool->curr; +} + +void ios_del_row(glp_tree *tree, IOSPOOL *pool, int i) +{ /* remove row (constraint) from the cut pool */ + IOSCUT *cut; + IOSAIJ *aij; + xassert(pool != NULL); + if (!(1 <= i && i <= pool->size)) + xerror("glp_ios_del_row: i = %d; cut number out of range\n", + i); + cut = ios_find_row(pool, i); + xassert(pool->curr == cut); + if (cut->next != NULL) + pool->curr = cut->next; + else if (cut->prev != NULL) + pool->ord--, pool->curr = cut->prev; + else + pool->ord = 0, pool->curr = NULL; + if (cut->name != NULL) + dmp_free_atom(tree->pool, cut->name, strlen(cut->name)+1); + if (cut->prev == NULL) + { xassert(pool->head == cut); + pool->head = cut->next; + } + else + { xassert(cut->prev->next == cut); + cut->prev->next = cut->next; + } + if (cut->next == NULL) + { xassert(pool->tail == cut); + pool->tail = cut->prev; + } + else + { xassert(cut->next->prev == cut); + cut->next->prev = cut->prev; + } + while (cut->ptr != NULL) + { aij = cut->ptr; + cut->ptr = aij->next; + dmp_free_atom(tree->pool, aij, sizeof(IOSAIJ)); + } + dmp_free_atom(tree->pool, cut, sizeof(IOSCUT)); + pool->size--; + return; +} + +void ios_clear_pool(glp_tree *tree, IOSPOOL *pool) +{ /* remove all rows (constraints) from the cut pool */ + xassert(pool != NULL); + while (pool->head != NULL) + { IOSCUT *cut = pool->head; + pool->head = cut->next; + if (cut->name != NULL) + dmp_free_atom(tree->pool, cut->name, strlen(cut->name)+1); + while (cut->ptr != NULL) + { IOSAIJ *aij = cut->ptr; + cut->ptr = aij->next; + dmp_free_atom(tree->pool, aij, sizeof(IOSAIJ)); + } + dmp_free_atom(tree->pool, cut, sizeof(IOSCUT)); + } + pool->size = 0; + pool->head = pool->tail = NULL; + pool->ord = 0, pool->curr = NULL; + return; +} + +void ios_delete_pool(glp_tree *tree, IOSPOOL *pool) +{ /* delete cut pool */ + xassert(pool != NULL); + ios_clear_pool(tree, pool); + xfree(pool); + return; +} + +#if 1 /* 11/VII-2013 */ +#include "glpnpp.h" + +void ios_process_sol(glp_tree *T) +{ /* process integer feasible solution just found */ + if (T->npp != NULL) + { /* postprocess solution from transformed mip */ + npp_postprocess(T->npp, T->mip); + /* store solution to problem passed to glp_intopt */ + npp_unload_sol(T->npp, T->P); + } + xassert(T->P != NULL); + /* save solution to text file, if requested */ + if (T->save_sol != NULL) + { char *fn, *mark; + fn = talloc(strlen(T->save_sol) + 50, char); + mark = strrchr(T->save_sol, '*'); + if (mark == NULL) + strcpy(fn, T->save_sol); + else + { memcpy(fn, T->save_sol, mark - T->save_sol); + fn[mark - T->save_sol] = '\0'; + sprintf(fn + strlen(fn), "%03d", ++(T->save_cnt)); + strcat(fn, &mark[1]); + } + glp_write_mip(T->P, fn); + tfree(fn); + } + return; +} +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpios02.c b/resources/3rdparty/glpk-4.57/src/glpios02.c new file mode 100644 index 000000000..43cff57e1 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpios02.c @@ -0,0 +1,826 @@ +/* glpios02.c (preprocess current subproblem) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpios.h" + +/*********************************************************************** +* prepare_row_info - prepare row info to determine implied bounds +* +* Given a row (linear form) +* +* n +* sum a[j] * x[j] (1) +* j=1 +* +* and bounds of columns (variables) +* +* l[j] <= x[j] <= u[j] (2) +* +* this routine computes f_min, j_min, f_max, j_max needed to determine +* implied bounds. +* +* ALGORITHM +* +* Let J+ = {j : a[j] > 0} and J- = {j : a[j] < 0}. +* +* Parameters f_min and j_min are computed as follows: +* +* 1) if there is no x[k] such that k in J+ and l[k] = -inf or k in J- +* and u[k] = +inf, then +* +* f_min := sum a[j] * l[j] + sum a[j] * u[j] +* j in J+ j in J- +* (3) +* j_min := 0 +* +* 2) if there is exactly one x[k] such that k in J+ and l[k] = -inf +* or k in J- and u[k] = +inf, then +* +* f_min := sum a[j] * l[j] + sum a[j] * u[j] +* j in J+\{k} j in J-\{k} +* (4) +* j_min := k +* +* 3) if there are two or more x[k] such that k in J+ and l[k] = -inf +* or k in J- and u[k] = +inf, then +* +* f_min := -inf +* (5) +* j_min := 0 +* +* Parameters f_max and j_max are computed in a similar way as follows: +* +* 1) if there is no x[k] such that k in J+ and u[k] = +inf or k in J- +* and l[k] = -inf, then +* +* f_max := sum a[j] * u[j] + sum a[j] * l[j] +* j in J+ j in J- +* (6) +* j_max := 0 +* +* 2) if there is exactly one x[k] such that k in J+ and u[k] = +inf +* or k in J- and l[k] = -inf, then +* +* f_max := sum a[j] * u[j] + sum a[j] * l[j] +* j in J+\{k} j in J-\{k} +* (7) +* j_max := k +* +* 3) if there are two or more x[k] such that k in J+ and u[k] = +inf +* or k in J- and l[k] = -inf, then +* +* f_max := +inf +* (8) +* j_max := 0 */ + +struct f_info +{ int j_min, j_max; + double f_min, f_max; +}; + +static void prepare_row_info(int n, const double a[], const double l[], + const double u[], struct f_info *f) +{ int j, j_min, j_max; + double f_min, f_max; + xassert(n >= 0); + /* determine f_min and j_min */ + f_min = 0.0, j_min = 0; + for (j = 1; j <= n; j++) + { if (a[j] > 0.0) + { if (l[j] == -DBL_MAX) + { if (j_min == 0) + j_min = j; + else + { f_min = -DBL_MAX, j_min = 0; + break; + } + } + else + f_min += a[j] * l[j]; + } + else if (a[j] < 0.0) + { if (u[j] == +DBL_MAX) + { if (j_min == 0) + j_min = j; + else + { f_min = -DBL_MAX, j_min = 0; + break; + } + } + else + f_min += a[j] * u[j]; + } + else + xassert(a != a); + } + f->f_min = f_min, f->j_min = j_min; + /* determine f_max and j_max */ + f_max = 0.0, j_max = 0; + for (j = 1; j <= n; j++) + { if (a[j] > 0.0) + { if (u[j] == +DBL_MAX) + { if (j_max == 0) + j_max = j; + else + { f_max = +DBL_MAX, j_max = 0; + break; + } + } + else + f_max += a[j] * u[j]; + } + else if (a[j] < 0.0) + { if (l[j] == -DBL_MAX) + { if (j_max == 0) + j_max = j; + else + { f_max = +DBL_MAX, j_max = 0; + break; + } + } + else + f_max += a[j] * l[j]; + } + else + xassert(a != a); + } + f->f_max = f_max, f->j_max = j_max; + return; +} + +/*********************************************************************** +* row_implied_bounds - determine row implied bounds +* +* Given a row (linear form) +* +* n +* sum a[j] * x[j] +* j=1 +* +* and bounds of columns (variables) +* +* l[j] <= x[j] <= u[j] +* +* this routine determines implied bounds of the row. +* +* ALGORITHM +* +* Let J+ = {j : a[j] > 0} and J- = {j : a[j] < 0}. +* +* The implied lower bound of the row is computed as follows: +* +* L' := sum a[j] * l[j] + sum a[j] * u[j] (9) +* j in J+ j in J- +* +* and as it follows from (3), (4), and (5): +* +* L' := if j_min = 0 then f_min else -inf (10) +* +* The implied upper bound of the row is computed as follows: +* +* U' := sum a[j] * u[j] + sum a[j] * l[j] (11) +* j in J+ j in J- +* +* and as it follows from (6), (7), and (8): +* +* U' := if j_max = 0 then f_max else +inf (12) +* +* The implied bounds are stored in locations LL and UU. */ + +static void row_implied_bounds(const struct f_info *f, double *LL, + double *UU) +{ *LL = (f->j_min == 0 ? f->f_min : -DBL_MAX); + *UU = (f->j_max == 0 ? f->f_max : +DBL_MAX); + return; +} + +/*********************************************************************** +* col_implied_bounds - determine column implied bounds +* +* Given a row (constraint) +* +* n +* L <= sum a[j] * x[j] <= U (13) +* j=1 +* +* and bounds of columns (variables) +* +* l[j] <= x[j] <= u[j] +* +* this routine determines implied bounds of variable x[k]. +* +* It is assumed that if L != -inf, the lower bound of the row can be +* active, and if U != +inf, the upper bound of the row can be active. +* +* ALGORITHM +* +* From (13) it follows that +* +* L <= sum a[j] * x[j] + a[k] * x[k] <= U +* j!=k +* or +* +* L - sum a[j] * x[j] <= a[k] * x[k] <= U - sum a[j] * x[j] +* j!=k j!=k +* +* Thus, if the row lower bound L can be active, implied lower bound of +* term a[k] * x[k] can be determined as follows: +* +* ilb(a[k] * x[k]) = min(L - sum a[j] * x[j]) = +* j!=k +* (14) +* = L - max sum a[j] * x[j] +* j!=k +* +* where, as it follows from (6), (7), and (8) +* +* / f_max - a[k] * u[k], j_max = 0, a[k] > 0 +* | +* | f_max - a[k] * l[k], j_max = 0, a[k] < 0 +* max sum a[j] * x[j] = { +* j!=k | f_max, j_max = k +* | +* \ +inf, j_max != 0 +* +* and if the upper bound U can be active, implied upper bound of term +* a[k] * x[k] can be determined as follows: +* +* iub(a[k] * x[k]) = max(U - sum a[j] * x[j]) = +* j!=k +* (15) +* = U - min sum a[j] * x[j] +* j!=k +* +* where, as it follows from (3), (4), and (5) +* +* / f_min - a[k] * l[k], j_min = 0, a[k] > 0 +* | +* | f_min - a[k] * u[k], j_min = 0, a[k] < 0 +* min sum a[j] * x[j] = { +* j!=k | f_min, j_min = k +* | +* \ -inf, j_min != 0 +* +* Since +* +* ilb(a[k] * x[k]) <= a[k] * x[k] <= iub(a[k] * x[k]) +* +* implied lower and upper bounds of x[k] are determined as follows: +* +* l'[k] := if a[k] > 0 then ilb / a[k] else ulb / a[k] (16) +* +* u'[k] := if a[k] > 0 then ulb / a[k] else ilb / a[k] (17) +* +* The implied bounds are stored in locations ll and uu. */ + +static void col_implied_bounds(const struct f_info *f, int n, + const double a[], double L, double U, const double l[], + const double u[], int k, double *ll, double *uu) +{ double ilb, iub; + xassert(n >= 0); + xassert(1 <= k && k <= n); + /* determine implied lower bound of term a[k] * x[k] (14) */ + if (L == -DBL_MAX || f->f_max == +DBL_MAX) + ilb = -DBL_MAX; + else if (f->j_max == 0) + { if (a[k] > 0.0) + { xassert(u[k] != +DBL_MAX); + ilb = L - (f->f_max - a[k] * u[k]); + } + else if (a[k] < 0.0) + { xassert(l[k] != -DBL_MAX); + ilb = L - (f->f_max - a[k] * l[k]); + } + else + xassert(a != a); + } + else if (f->j_max == k) + ilb = L - f->f_max; + else + ilb = -DBL_MAX; + /* determine implied upper bound of term a[k] * x[k] (15) */ + if (U == +DBL_MAX || f->f_min == -DBL_MAX) + iub = +DBL_MAX; + else if (f->j_min == 0) + { if (a[k] > 0.0) + { xassert(l[k] != -DBL_MAX); + iub = U - (f->f_min - a[k] * l[k]); + } + else if (a[k] < 0.0) + { xassert(u[k] != +DBL_MAX); + iub = U - (f->f_min - a[k] * u[k]); + } + else + xassert(a != a); + } + else if (f->j_min == k) + iub = U - f->f_min; + else + iub = +DBL_MAX; + /* determine implied bounds of x[k] (16) and (17) */ +#if 1 + /* do not use a[k] if it has small magnitude to prevent wrong + implied bounds; for example, 1e-15 * x1 >= x2 + x3, where + x1 >= -10, x2, x3 >= 0, would lead to wrong conclusion that + x1 >= 0 */ + if (fabs(a[k]) < 1e-6) + *ll = -DBL_MAX, *uu = +DBL_MAX; else +#endif + if (a[k] > 0.0) + { *ll = (ilb == -DBL_MAX ? -DBL_MAX : ilb / a[k]); + *uu = (iub == +DBL_MAX ? +DBL_MAX : iub / a[k]); + } + else if (a[k] < 0.0) + { *ll = (iub == +DBL_MAX ? -DBL_MAX : iub / a[k]); + *uu = (ilb == -DBL_MAX ? +DBL_MAX : ilb / a[k]); + } + else + xassert(a != a); + return; +} + +/*********************************************************************** +* check_row_bounds - check and relax original row bounds +* +* Given a row (constraint) +* +* n +* L <= sum a[j] * x[j] <= U +* j=1 +* +* and bounds of columns (variables) +* +* l[j] <= x[j] <= u[j] +* +* this routine checks the original row bounds L and U for feasibility +* and redundancy. If the original lower bound L or/and upper bound U +* cannot be active due to bounds of variables, the routine remove them +* replacing by -inf or/and +inf, respectively. +* +* If no primal infeasibility is detected, the routine returns zero, +* otherwise non-zero. */ + +static int check_row_bounds(const struct f_info *f, double *L_, + double *U_) +{ int ret = 0; + double L = *L_, U = *U_, LL, UU; + /* determine implied bounds of the row */ + row_implied_bounds(f, &LL, &UU); + /* check if the original lower bound is infeasible */ + if (L != -DBL_MAX) + { double eps = 1e-3 * (1.0 + fabs(L)); + if (UU < L - eps) + { ret = 1; + goto done; + } + } + /* check if the original upper bound is infeasible */ + if (U != +DBL_MAX) + { double eps = 1e-3 * (1.0 + fabs(U)); + if (LL > U + eps) + { ret = 1; + goto done; + } + } + /* check if the original lower bound is redundant */ + if (L != -DBL_MAX) + { double eps = 1e-12 * (1.0 + fabs(L)); + if (LL > L - eps) + { /* it cannot be active, so remove it */ + *L_ = -DBL_MAX; + } + } + /* check if the original upper bound is redundant */ + if (U != +DBL_MAX) + { double eps = 1e-12 * (1.0 + fabs(U)); + if (UU < U + eps) + { /* it cannot be active, so remove it */ + *U_ = +DBL_MAX; + } + } +done: return ret; +} + +/*********************************************************************** +* check_col_bounds - check and tighten original column bounds +* +* Given a row (constraint) +* +* n +* L <= sum a[j] * x[j] <= U +* j=1 +* +* and bounds of columns (variables) +* +* l[j] <= x[j] <= u[j] +* +* for column (variable) x[j] this routine checks the original column +* bounds l[j] and u[j] for feasibility and redundancy. If the original +* lower bound l[j] or/and upper bound u[j] cannot be active due to +* bounds of the constraint and other variables, the routine tighten +* them replacing by corresponding implied bounds, if possible. +* +* NOTE: It is assumed that if L != -inf, the row lower bound can be +* active, and if U != +inf, the row upper bound can be active. +* +* The flag means that variable x[j] is required to be integer. +* +* New actual bounds for x[j] are stored in locations lj and uj. +* +* If no primal infeasibility is detected, the routine returns zero, +* otherwise non-zero. */ + +static int check_col_bounds(const struct f_info *f, int n, + const double a[], double L, double U, const double l[], + const double u[], int flag, int j, double *_lj, double *_uj) +{ int ret = 0; + double lj, uj, ll, uu; + xassert(n >= 0); + xassert(1 <= j && j <= n); + lj = l[j], uj = u[j]; + /* determine implied bounds of the column */ + col_implied_bounds(f, n, a, L, U, l, u, j, &ll, &uu); + /* if x[j] is integral, round its implied bounds */ + if (flag) + { if (ll != -DBL_MAX) + ll = (ll - floor(ll) < 1e-3 ? floor(ll) : ceil(ll)); + if (uu != +DBL_MAX) + uu = (ceil(uu) - uu < 1e-3 ? ceil(uu) : floor(uu)); + } + /* check if the original lower bound is infeasible */ + if (lj != -DBL_MAX) + { double eps = 1e-3 * (1.0 + fabs(lj)); + if (uu < lj - eps) + { ret = 1; + goto done; + } + } + /* check if the original upper bound is infeasible */ + if (uj != +DBL_MAX) + { double eps = 1e-3 * (1.0 + fabs(uj)); + if (ll > uj + eps) + { ret = 1; + goto done; + } + } + /* check if the original lower bound is redundant */ + if (ll != -DBL_MAX) + { double eps = 1e-3 * (1.0 + fabs(ll)); + if (lj < ll - eps) + { /* it cannot be active, so tighten it */ + lj = ll; + } + } + /* check if the original upper bound is redundant */ + if (uu != +DBL_MAX) + { double eps = 1e-3 * (1.0 + fabs(uu)); + if (uj > uu + eps) + { /* it cannot be active, so tighten it */ + uj = uu; + } + } + /* due to round-off errors it may happen that lj > uj (although + lj < uj + eps, since no primal infeasibility is detected), so + adjuct the new actual bounds to provide lj <= uj */ + if (!(lj == -DBL_MAX || uj == +DBL_MAX)) + { double t1 = fabs(lj), t2 = fabs(uj); + double eps = 1e-10 * (1.0 + (t1 <= t2 ? t1 : t2)); + if (lj > uj - eps) + { if (lj == l[j]) + uj = lj; + else if (uj == u[j]) + lj = uj; + else if (t1 <= t2) + uj = lj; + else + lj = uj; + } + } + *_lj = lj, *_uj = uj; +done: return ret; +} + +/*********************************************************************** +* check_efficiency - check if change in column bounds is efficient +* +* Given the original bounds of a column l and u and its new actual +* bounds l' and u' (possibly tighten by the routine check_col_bounds) +* this routine checks if the change in the column bounds is efficient +* enough. If so, the routine returns non-zero, otherwise zero. +* +* The flag means that the variable is required to be integer. */ + +static int check_efficiency(int flag, double l, double u, double ll, + double uu) +{ int eff = 0; + /* check efficiency for lower bound */ + if (l < ll) + { if (flag || l == -DBL_MAX) + eff++; + else + { double r; + if (u == +DBL_MAX) + r = 1.0 + fabs(l); + else + r = 1.0 + (u - l); + if (ll - l >= 0.25 * r) + eff++; + } + } + /* check efficiency for upper bound */ + if (u > uu) + { if (flag || u == +DBL_MAX) + eff++; + else + { double r; + if (l == -DBL_MAX) + r = 1.0 + fabs(u); + else + r = 1.0 + (u - l); + if (u - uu >= 0.25 * r) + eff++; + } + } + return eff; +} + +/*********************************************************************** +* basic_preprocessing - perform basic preprocessing +* +* This routine performs basic preprocessing of the specified MIP that +* includes relaxing some row bounds and tightening some column bounds. +* +* On entry the arrays L and U contains original row bounds, and the +* arrays l and u contains original column bounds: +* +* L[0] is the lower bound of the objective row; +* L[i], i = 1,...,m, is the lower bound of i-th row; +* U[0] is the upper bound of the objective row; +* U[i], i = 1,...,m, is the upper bound of i-th row; +* l[0] is not used; +* l[j], j = 1,...,n, is the lower bound of j-th column; +* u[0] is not used; +* u[j], j = 1,...,n, is the upper bound of j-th column. +* +* On exit the arrays L, U, l, and u contain new actual bounds of rows +* and column in the same locations. +* +* The parameters nrs and num specify an initial list of rows to be +* processed: +* +* nrs is the number of rows in the initial list, 0 <= nrs <= m+1; +* num[0] is not used; +* num[1,...,nrs] are row numbers (0 means the objective row). +* +* The parameter max_pass specifies the maximal number of times that +* each row can be processed, max_pass > 0. +* +* If no primal infeasibility is detected, the routine returns zero, +* otherwise non-zero. */ + +static int basic_preprocessing(glp_prob *mip, double L[], double U[], + double l[], double u[], int nrs, const int num[], int max_pass) +{ int m = mip->m; + int n = mip->n; + struct f_info f; + int i, j, k, len, size, ret = 0; + int *ind, *list, *mark, *pass; + double *val, *lb, *ub; + xassert(0 <= nrs && nrs <= m+1); + xassert(max_pass > 0); + /* allocate working arrays */ + ind = xcalloc(1+n, sizeof(int)); + list = xcalloc(1+m+1, sizeof(int)); + mark = xcalloc(1+m+1, sizeof(int)); + memset(&mark[0], 0, (m+1) * sizeof(int)); + pass = xcalloc(1+m+1, sizeof(int)); + memset(&pass[0], 0, (m+1) * sizeof(int)); + val = xcalloc(1+n, sizeof(double)); + lb = xcalloc(1+n, sizeof(double)); + ub = xcalloc(1+n, sizeof(double)); + /* initialize the list of rows to be processed */ + size = 0; + for (k = 1; k <= nrs; k++) + { i = num[k]; + xassert(0 <= i && i <= m); + /* duplicate row numbers are not allowed */ + xassert(!mark[i]); + list[++size] = i, mark[i] = 1; + } + xassert(size == nrs); + /* process rows in the list until it becomes empty */ + while (size > 0) + { /* get a next row from the list */ + i = list[size--], mark[i] = 0; + /* increase the row processing count */ + pass[i]++; + /* if the row is free, skip it */ + if (L[i] == -DBL_MAX && U[i] == +DBL_MAX) continue; + /* obtain coefficients of the row */ + len = 0; + if (i == 0) + { for (j = 1; j <= n; j++) + { GLPCOL *col = mip->col[j]; + if (col->coef != 0.0) + len++, ind[len] = j, val[len] = col->coef; + } + } + else + { GLPROW *row = mip->row[i]; + GLPAIJ *aij; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + len++, ind[len] = aij->col->j, val[len] = aij->val; + } + /* determine lower and upper bounds of columns corresponding + to non-zero row coefficients */ + for (k = 1; k <= len; k++) + j = ind[k], lb[k] = l[j], ub[k] = u[j]; + /* prepare the row info to determine implied bounds */ + prepare_row_info(len, val, lb, ub, &f); + /* check and relax bounds of the row */ + if (check_row_bounds(&f, &L[i], &U[i])) + { /* the feasible region is empty */ + ret = 1; + goto done; + } + /* if the row became free, drop it */ + if (L[i] == -DBL_MAX && U[i] == +DBL_MAX) continue; + /* process columns having non-zero coefficients in the row */ + for (k = 1; k <= len; k++) + { GLPCOL *col; + int flag, eff; + double ll, uu; + /* take a next column in the row */ + j = ind[k], col = mip->col[j]; + flag = col->kind != GLP_CV; + /* check and tighten bounds of the column */ + if (check_col_bounds(&f, len, val, L[i], U[i], lb, ub, + flag, k, &ll, &uu)) + { /* the feasible region is empty */ + ret = 1; + goto done; + } + /* check if change in the column bounds is efficient */ + eff = check_efficiency(flag, l[j], u[j], ll, uu); + /* set new actual bounds of the column */ + l[j] = ll, u[j] = uu; + /* if the change is efficient, add all rows affected by the + corresponding column, to the list */ + if (eff > 0) + { GLPAIJ *aij; + for (aij = col->ptr; aij != NULL; aij = aij->c_next) + { int ii = aij->row->i; + /* if the row was processed maximal number of times, + skip it */ + if (pass[ii] >= max_pass) continue; + /* if the row is free, skip it */ + if (L[ii] == -DBL_MAX && U[ii] == +DBL_MAX) continue; + /* put the row into the list */ + if (mark[ii] == 0) + { xassert(size <= m); + list[++size] = ii, mark[ii] = 1; + } + } + } + } + } +done: /* free working arrays */ + xfree(ind); + xfree(list); + xfree(mark); + xfree(pass); + xfree(val); + xfree(lb); + xfree(ub); + return ret; +} + +/*********************************************************************** +* NAME +* +* ios_preprocess_node - preprocess current subproblem +* +* SYNOPSIS +* +* #include "glpios.h" +* int ios_preprocess_node(glp_tree *tree, int max_pass); +* +* DESCRIPTION +* +* The routine ios_preprocess_node performs basic preprocessing of the +* current subproblem. +* +* RETURNS +* +* If no primal infeasibility is detected, the routine returns zero, +* otherwise non-zero. */ + +int ios_preprocess_node(glp_tree *tree, int max_pass) +{ glp_prob *mip = tree->mip; + int m = mip->m; + int n = mip->n; + int i, j, nrs, *num, ret = 0; + double *L, *U, *l, *u; + /* the current subproblem must exist */ + xassert(tree->curr != NULL); + /* determine original row bounds */ + L = xcalloc(1+m, sizeof(double)); + U = xcalloc(1+m, sizeof(double)); + switch (mip->mip_stat) + { case GLP_UNDEF: + L[0] = -DBL_MAX, U[0] = +DBL_MAX; + break; + case GLP_FEAS: + switch (mip->dir) + { case GLP_MIN: + L[0] = -DBL_MAX, U[0] = mip->mip_obj - mip->c0; + break; + case GLP_MAX: + L[0] = mip->mip_obj - mip->c0, U[0] = +DBL_MAX; + break; + default: + xassert(mip != mip); + } + break; + default: + xassert(mip != mip); + } + for (i = 1; i <= m; i++) + { L[i] = glp_get_row_lb(mip, i); + U[i] = glp_get_row_ub(mip, i); + } + /* determine original column bounds */ + l = xcalloc(1+n, sizeof(double)); + u = xcalloc(1+n, sizeof(double)); + for (j = 1; j <= n; j++) + { l[j] = glp_get_col_lb(mip, j); + u[j] = glp_get_col_ub(mip, j); + } + /* build the initial list of rows to be analyzed */ + nrs = m + 1; + num = xcalloc(1+nrs, sizeof(int)); + for (i = 1; i <= nrs; i++) num[i] = i - 1; + /* perform basic preprocessing */ + if (basic_preprocessing(mip , L, U, l, u, nrs, num, max_pass)) + { ret = 1; + goto done; + } + /* set new actual (relaxed) row bounds */ + for (i = 1; i <= m; i++) + { /* consider only non-active rows to keep dual feasibility */ + if (glp_get_row_stat(mip, i) == GLP_BS) + { if (L[i] == -DBL_MAX && U[i] == +DBL_MAX) + glp_set_row_bnds(mip, i, GLP_FR, 0.0, 0.0); + else if (U[i] == +DBL_MAX) + glp_set_row_bnds(mip, i, GLP_LO, L[i], 0.0); + else if (L[i] == -DBL_MAX) + glp_set_row_bnds(mip, i, GLP_UP, 0.0, U[i]); + } + } + /* set new actual (tightened) column bounds */ + for (j = 1; j <= n; j++) + { int type; + if (l[j] == -DBL_MAX && u[j] == +DBL_MAX) + type = GLP_FR; + else if (u[j] == +DBL_MAX) + type = GLP_LO; + else if (l[j] == -DBL_MAX) + type = GLP_UP; + else if (l[j] != u[j]) + type = GLP_DB; + else + type = GLP_FX; + glp_set_col_bnds(mip, j, type, l[j], u[j]); + } +done: /* free working arrays and return */ + xfree(L); + xfree(U); + xfree(l); + xfree(u); + xfree(num); + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpios03.c b/resources/3rdparty/glpk-4.57/src/glpios03.c new file mode 100644 index 000000000..29ea32e2c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpios03.c @@ -0,0 +1,1372 @@ +/* glpios03.c (branch-and-cut driver) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpios.h" + +/*********************************************************************** +* show_progress - display current progress of the search +* +* This routine displays some information about current progress of the +* search. +* +* The information includes: +* +* the current number of iterations performed by the simplex solver; +* +* the objective value for the best known integer feasible solution, +* which is upper (minimization) or lower (maximization) global bound +* for optimal solution of the original mip problem; +* +* the best local bound for active nodes, which is lower (minimization) +* or upper (maximization) global bound for optimal solution of the +* original mip problem; +* +* the relative mip gap, in percents; +* +* the number of open (active) subproblems; +* +* the number of completely explored subproblems, i.e. whose nodes have +* been removed from the tree. */ + +static void show_progress(glp_tree *T, int bingo) +{ int p; + double temp; + char best_mip[50], best_bound[50], *rho, rel_gap[50]; + /* format the best known integer feasible solution */ + if (T->mip->mip_stat == GLP_FEAS) + sprintf(best_mip, "%17.9e", T->mip->mip_obj); + else + sprintf(best_mip, "%17s", "not found yet"); + /* determine reference number of an active subproblem whose local + bound is best */ + p = ios_best_node(T); + /* format the best bound */ + if (p == 0) + sprintf(best_bound, "%17s", "tree is empty"); + else + { temp = T->slot[p].node->bound; + if (temp == -DBL_MAX) + sprintf(best_bound, "%17s", "-inf"); + else if (temp == +DBL_MAX) + sprintf(best_bound, "%17s", "+inf"); + else + sprintf(best_bound, "%17.9e", temp); + } + /* choose the relation sign between global bounds */ + if (T->mip->dir == GLP_MIN) + rho = ">="; + else if (T->mip->dir == GLP_MAX) + rho = "<="; + else + xassert(T != T); + /* format the relative mip gap */ + temp = ios_relative_gap(T); + if (temp == 0.0) + sprintf(rel_gap, " 0.0%%"); + else if (temp < 0.001) + sprintf(rel_gap, "< 0.1%%"); + else if (temp <= 9.999) + sprintf(rel_gap, "%5.1f%%", 100.0 * temp); + else + sprintf(rel_gap, "%6s", ""); + /* display progress of the search */ + xprintf("+%6d: %s %s %s %s %s (%d; %d)\n", + T->mip->it_cnt, bingo ? ">>>>>" : "mip =", best_mip, rho, + best_bound, rel_gap, T->a_cnt, T->t_cnt - T->n_cnt); + T->tm_lag = xtime(); + return; +} + +/*********************************************************************** +* is_branch_hopeful - check if specified branch is hopeful +* +* This routine checks if the specified subproblem can have an integer +* optimal solution which is better than the best known one. +* +* The check is based on comparison of the local objective bound stored +* in the subproblem descriptor and the incumbent objective value which +* is the global objective bound. +* +* If there is a chance that the specified subproblem can have a better +* integer optimal solution, the routine returns non-zero. Otherwise, if +* the corresponding branch can pruned, zero is returned. */ + +static int is_branch_hopeful(glp_tree *T, int p) +{ xassert(1 <= p && p <= T->nslots); + xassert(T->slot[p].node != NULL); + return ios_is_hopeful(T, T->slot[p].node->bound); +} + +/*********************************************************************** +* check_integrality - check integrality of basic solution +* +* This routine checks if the basic solution of LP relaxation of the +* current subproblem satisfies to integrality conditions, i.e. that all +* variables of integer kind have integral primal values. (The solution +* is assumed to be optimal.) +* +* For each variable of integer kind the routine computes the following +* quantity: +* +* ii(x[j]) = min(x[j] - floor(x[j]), ceil(x[j]) - x[j]), (1) +* +* which is a measure of the integer infeasibility (non-integrality) of +* x[j] (for example, ii(2.1) = 0.1, ii(3.7) = 0.3, ii(5.0) = 0). It is +* understood that 0 <= ii(x[j]) <= 0.5, and variable x[j] is integer +* feasible if ii(x[j]) = 0. However, due to floating-point arithmetic +* the routine checks less restrictive condition: +* +* ii(x[j]) <= tol_int, (2) +* +* where tol_int is a given tolerance (small positive number) and marks +* each variable which does not satisfy to (2) as integer infeasible by +* setting its fractionality flag. +* +* In order to characterize integer infeasibility of the basic solution +* in the whole the routine computes two parameters: ii_cnt, which is +* the number of variables with the fractionality flag set, and ii_sum, +* which is the sum of integer infeasibilities (1). */ + +static void check_integrality(glp_tree *T) +{ glp_prob *mip = T->mip; + int j, type, ii_cnt = 0; + double lb, ub, x, temp1, temp2, ii_sum = 0.0; + /* walk through the set of columns (structural variables) */ + for (j = 1; j <= mip->n; j++) + { GLPCOL *col = mip->col[j]; + T->non_int[j] = 0; + /* if the column is not integer, skip it */ + if (col->kind != GLP_IV) continue; + /* if the column is non-basic, it is integer feasible */ + if (col->stat != GLP_BS) continue; + /* obtain the type and bounds of the column */ + type = col->type, lb = col->lb, ub = col->ub; + /* obtain value of the column in optimal basic solution */ + x = col->prim; + /* if the column's primal value is close to the lower bound, + the column is integer feasible within given tolerance */ + if (type == GLP_LO || type == GLP_DB || type == GLP_FX) + { temp1 = lb - T->parm->tol_int; + temp2 = lb + T->parm->tol_int; + if (temp1 <= x && x <= temp2) continue; +#if 0 + /* the lower bound must not be violated */ + xassert(x >= lb); +#else + if (x < lb) continue; +#endif + } + /* if the column's primal value is close to the upper bound, + the column is integer feasible within given tolerance */ + if (type == GLP_UP || type == GLP_DB || type == GLP_FX) + { temp1 = ub - T->parm->tol_int; + temp2 = ub + T->parm->tol_int; + if (temp1 <= x && x <= temp2) continue; +#if 0 + /* the upper bound must not be violated */ + xassert(x <= ub); +#else + if (x > ub) continue; +#endif + } + /* if the column's primal value is close to nearest integer, + the column is integer feasible within given tolerance */ + temp1 = floor(x + 0.5) - T->parm->tol_int; + temp2 = floor(x + 0.5) + T->parm->tol_int; + if (temp1 <= x && x <= temp2) continue; + /* otherwise the column is integer infeasible */ + T->non_int[j] = 1; + /* increase the number of fractional-valued columns */ + ii_cnt++; + /* compute the sum of integer infeasibilities */ + temp1 = x - floor(x); + temp2 = ceil(x) - x; + xassert(temp1 > 0.0 && temp2 > 0.0); + ii_sum += (temp1 <= temp2 ? temp1 : temp2); + } + /* store ii_cnt and ii_sum to the current problem descriptor */ + xassert(T->curr != NULL); + T->curr->ii_cnt = ii_cnt; + T->curr->ii_sum = ii_sum; + /* and also display these parameters */ + if (T->parm->msg_lev >= GLP_MSG_DBG) + { if (ii_cnt == 0) + xprintf("There are no fractional columns\n"); + else if (ii_cnt == 1) + xprintf("There is one fractional column, integer infeasibil" + "ity is %.3e\n", ii_sum); + else + xprintf("There are %d fractional columns, integer infeasibi" + "lity is %.3e\n", ii_cnt, ii_sum); + } + return; +} + +/*********************************************************************** +* record_solution - record better integer feasible solution +* +* This routine records optimal basic solution of LP relaxation of the +* current subproblem, which being integer feasible is better than the +* best known integer feasible solution. */ + +static void record_solution(glp_tree *T) +{ glp_prob *mip = T->mip; + int i, j; + mip->mip_stat = GLP_FEAS; + mip->mip_obj = mip->obj_val; + for (i = 1; i <= mip->m; i++) + { GLPROW *row = mip->row[i]; + row->mipx = row->prim; + } + for (j = 1; j <= mip->n; j++) + { GLPCOL *col = mip->col[j]; + if (col->kind == GLP_CV) + col->mipx = col->prim; + else if (col->kind == GLP_IV) + { /* value of the integer column must be integral */ + col->mipx = floor(col->prim + 0.5); + } + else + xassert(col != col); + } + T->sol_cnt++; + return; +} + +/*********************************************************************** +* fix_by_red_cost - fix non-basic integer columns by reduced costs +* +* This routine fixes some non-basic integer columns if their reduced +* costs indicate that increasing (decreasing) the column at least by +* one involves the objective value becoming worse than the incumbent +* objective value. */ + +static void fix_by_red_cost(glp_tree *T) +{ glp_prob *mip = T->mip; + int j, stat, fixed = 0; + double obj, lb, ub, dj; + /* the global bound must exist */ + xassert(T->mip->mip_stat == GLP_FEAS); + /* basic solution of LP relaxation must be optimal */ + xassert(mip->pbs_stat == GLP_FEAS && mip->dbs_stat == GLP_FEAS); + /* determine the objective function value */ + obj = mip->obj_val; + /* walk through the column list */ + for (j = 1; j <= mip->n; j++) + { GLPCOL *col = mip->col[j]; + /* if the column is not integer, skip it */ + if (col->kind != GLP_IV) continue; + /* obtain bounds of j-th column */ + lb = col->lb, ub = col->ub; + /* and determine its status and reduced cost */ + stat = col->stat, dj = col->dual; + /* analyze the reduced cost */ + switch (mip->dir) + { case GLP_MIN: + /* minimization */ + if (stat == GLP_NL) + { /* j-th column is non-basic on its lower bound */ + if (dj < 0.0) dj = 0.0; + if (obj + dj >= mip->mip_obj) + glp_set_col_bnds(mip, j, GLP_FX, lb, lb), fixed++; + } + else if (stat == GLP_NU) + { /* j-th column is non-basic on its upper bound */ + if (dj > 0.0) dj = 0.0; + if (obj - dj >= mip->mip_obj) + glp_set_col_bnds(mip, j, GLP_FX, ub, ub), fixed++; + } + break; + case GLP_MAX: + /* maximization */ + if (stat == GLP_NL) + { /* j-th column is non-basic on its lower bound */ + if (dj > 0.0) dj = 0.0; + if (obj + dj <= mip->mip_obj) + glp_set_col_bnds(mip, j, GLP_FX, lb, lb), fixed++; + } + else if (stat == GLP_NU) + { /* j-th column is non-basic on its upper bound */ + if (dj < 0.0) dj = 0.0; + if (obj - dj <= mip->mip_obj) + glp_set_col_bnds(mip, j, GLP_FX, ub, ub), fixed++; + } + break; + default: + xassert(T != T); + } + } + if (T->parm->msg_lev >= GLP_MSG_DBG) + { if (fixed == 0) + /* nothing to say */; + else if (fixed == 1) + xprintf("One column has been fixed by reduced cost\n"); + else + xprintf("%d columns have been fixed by reduced costs\n", + fixed); + } + /* fixing non-basic columns on their current bounds does not + change the basic solution */ + xassert(mip->pbs_stat == GLP_FEAS && mip->dbs_stat == GLP_FEAS); + return; +} + +/*********************************************************************** +* branch_on - perform branching on specified variable +* +* This routine performs branching on j-th column (structural variable) +* of the current subproblem. The specified column must be of integer +* kind and must have a fractional value in optimal basic solution of +* LP relaxation of the current subproblem (i.e. only columns for which +* the flag non_int[j] is set are valid candidates to branch on). +* +* Let x be j-th structural variable, and beta be its primal fractional +* value in the current basic solution. Branching on j-th variable is +* dividing the current subproblem into two new subproblems, which are +* identical to the current subproblem with the following exception: in +* the first subproblem that begins the down-branch x has a new upper +* bound x <= floor(beta), and in the second subproblem that begins the +* up-branch x has a new lower bound x >= ceil(beta). +* +* Depending on estimation of local bounds for down- and up-branches +* this routine returns the following: +* +* 0 - both branches have been created; +* 1 - one branch is hopeless and has been pruned, so now the current +* subproblem is other branch; +* 2 - both branches are hopeless and have been pruned; new subproblem +* selection is needed to continue the search. */ + +static int branch_on(glp_tree *T, int j, int next) +{ glp_prob *mip = T->mip; + IOSNPD *node; + int m = mip->m; + int n = mip->n; + int type, dn_type, up_type, dn_bad, up_bad, p, ret, clone[1+2]; + double lb, ub, beta, new_ub, new_lb, dn_lp, up_lp, dn_bnd, up_bnd; + /* determine bounds and value of x[j] in optimal solution to LP + relaxation of the current subproblem */ + xassert(1 <= j && j <= n); + type = mip->col[j]->type; + lb = mip->col[j]->lb; + ub = mip->col[j]->ub; + beta = mip->col[j]->prim; + /* determine new bounds of x[j] for down- and up-branches */ + new_ub = floor(beta); + new_lb = ceil(beta); + switch (type) + { case GLP_FR: + dn_type = GLP_UP; + up_type = GLP_LO; + break; + case GLP_LO: + xassert(lb <= new_ub); + dn_type = (lb == new_ub ? GLP_FX : GLP_DB); + xassert(lb + 1.0 <= new_lb); + up_type = GLP_LO; + break; + case GLP_UP: + xassert(new_ub <= ub - 1.0); + dn_type = GLP_UP; + xassert(new_lb <= ub); + up_type = (new_lb == ub ? GLP_FX : GLP_DB); + break; + case GLP_DB: + xassert(lb <= new_ub && new_ub <= ub - 1.0); + dn_type = (lb == new_ub ? GLP_FX : GLP_DB); + xassert(lb + 1.0 <= new_lb && new_lb <= ub); + up_type = (new_lb == ub ? GLP_FX : GLP_DB); + break; + default: + xassert(type != type); + } + /* compute local bounds to LP relaxation for both branches */ + ios_eval_degrad(T, j, &dn_lp, &up_lp); + /* and improve them by rounding */ + dn_bnd = ios_round_bound(T, dn_lp); + up_bnd = ios_round_bound(T, up_lp); + /* check local bounds for down- and up-branches */ + dn_bad = !ios_is_hopeful(T, dn_bnd); + up_bad = !ios_is_hopeful(T, up_bnd); + if (dn_bad && up_bad) + { if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Both down- and up-branches are hopeless\n"); + ret = 2; + goto done; + } + else if (up_bad) + { if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Up-branch is hopeless\n"); + glp_set_col_bnds(mip, j, dn_type, lb, new_ub); + T->curr->lp_obj = dn_lp; + if (mip->dir == GLP_MIN) + { if (T->curr->bound < dn_bnd) + T->curr->bound = dn_bnd; + } + else if (mip->dir == GLP_MAX) + { if (T->curr->bound > dn_bnd) + T->curr->bound = dn_bnd; + } + else + xassert(mip != mip); + ret = 1; + goto done; + } + else if (dn_bad) + { if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Down-branch is hopeless\n"); + glp_set_col_bnds(mip, j, up_type, new_lb, ub); + T->curr->lp_obj = up_lp; + if (mip->dir == GLP_MIN) + { if (T->curr->bound < up_bnd) + T->curr->bound = up_bnd; + } + else if (mip->dir == GLP_MAX) + { if (T->curr->bound > up_bnd) + T->curr->bound = up_bnd; + } + else + xassert(mip != mip); + ret = 1; + goto done; + } + /* both down- and up-branches seem to be hopeful */ + if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Branching on column %d, primal value is %.9e\n", + j, beta); + /* determine the reference number of the current subproblem */ + xassert(T->curr != NULL); + p = T->curr->p; + T->curr->br_var = j; + T->curr->br_val = beta; + /* freeze the current subproblem */ + ios_freeze_node(T); + /* create two clones of the current subproblem; the first clone + begins the down-branch, the second one begins the up-branch */ + ios_clone_node(T, p, 2, clone); + if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Node %d begins down branch, node %d begins up branch " + "\n", clone[1], clone[2]); + /* set new upper bound of j-th column in the down-branch */ + node = T->slot[clone[1]].node; + xassert(node != NULL); + xassert(node->up != NULL); + xassert(node->b_ptr == NULL); + node->b_ptr = dmp_get_atom(T->pool, sizeof(IOSBND)); + node->b_ptr->k = m + j; + node->b_ptr->type = (unsigned char)dn_type; + node->b_ptr->lb = lb; + node->b_ptr->ub = new_ub; + node->b_ptr->next = NULL; + node->lp_obj = dn_lp; + if (mip->dir == GLP_MIN) + { if (node->bound < dn_bnd) + node->bound = dn_bnd; + } + else if (mip->dir == GLP_MAX) + { if (node->bound > dn_bnd) + node->bound = dn_bnd; + } + else + xassert(mip != mip); + /* set new lower bound of j-th column in the up-branch */ + node = T->slot[clone[2]].node; + xassert(node != NULL); + xassert(node->up != NULL); + xassert(node->b_ptr == NULL); + node->b_ptr = dmp_get_atom(T->pool, sizeof(IOSBND)); + node->b_ptr->k = m + j; + node->b_ptr->type = (unsigned char)up_type; + node->b_ptr->lb = new_lb; + node->b_ptr->ub = ub; + node->b_ptr->next = NULL; + node->lp_obj = up_lp; + if (mip->dir == GLP_MIN) + { if (node->bound < up_bnd) + node->bound = up_bnd; + } + else if (mip->dir == GLP_MAX) + { if (node->bound > up_bnd) + node->bound = up_bnd; + } + else + xassert(mip != mip); + /* suggest the subproblem to be solved next */ + xassert(T->child == 0); + if (next == GLP_NO_BRNCH) + T->child = 0; + else if (next == GLP_DN_BRNCH) + T->child = clone[1]; + else if (next == GLP_UP_BRNCH) + T->child = clone[2]; + else + xassert(next != next); + ret = 0; +done: return ret; +} + +/*********************************************************************** +* cleanup_the_tree - prune hopeless branches from the tree +* +* This routine walks through the active list and checks the local +* bound for every active subproblem. If the local bound indicates that +* the subproblem cannot have integer optimal solution better than the +* incumbent objective value, the routine deletes such subproblem that, +* in turn, involves pruning the corresponding branch of the tree. */ + +static void cleanup_the_tree(glp_tree *T) +{ IOSNPD *node, *next_node; + int count = 0; + /* the global bound must exist */ + xassert(T->mip->mip_stat == GLP_FEAS); + /* walk through the list of active subproblems */ + for (node = T->head; node != NULL; node = next_node) + { /* deleting some active problem node may involve deleting its + parents recursively; however, all its parents being created + *before* it are always *precede* it in the node list, so + the next problem node is never affected by such deletion */ + next_node = node->next; + /* if the branch is hopeless, prune it */ + if (!is_branch_hopeful(T, node->p)) + ios_delete_node(T, node->p), count++; + } + if (T->parm->msg_lev >= GLP_MSG_DBG) + { if (count == 1) + xprintf("One hopeless branch has been pruned\n"); + else if (count > 1) + xprintf("%d hopeless branches have been pruned\n", count); + } + return; +} + +/*********************************************************************** +* round_heur - simple rounding heuristic +* +* This routine attempts to guess an integer feasible solution by +* simple rounding values of all integer variables in basic solution to +* nearest integers. */ + +static int round_heur(glp_tree *T) +{ glp_prob *P = T->mip; + /*int m = P->m;*/ + int n = P->n; + int i, j, ret; + double *x; + /* compute rounded values of variables */ + x = talloc(1+n, double); + for (j = 1; j <= n; j++) + { GLPCOL *col = P->col[j]; + if (col->kind == GLP_IV) + { /* integer variable */ + x[j] = floor(col->prim + 0.5); + } + else if (col->type == GLP_FX) + { /* fixed variable */ + x[j] = col->prim; + } + else + { /* non-integer non-fixed variable */ + ret = 3; + goto done; + } + } + /* check that no constraints are violated */ + for (i = 1; i <= T->orig_m; i++) + { int type = T->orig_type[i]; + GLPAIJ *aij; + double sum; + if (type == GLP_FR) + continue; + /* compute value of linear form */ + sum = 0.0; + for (aij = P->row[i]->ptr; aij != NULL; aij = aij->r_next) + sum += aij->val * x[aij->col->j]; + /* check lower bound */ + if (type == GLP_LO || type == GLP_DB || type == GLP_FX) + { if (sum < T->orig_lb[i] - 1e-9) + { /* lower bound is violated */ + ret = 2; + goto done; + } + } + /* check upper bound */ + if (type == GLP_UP || type == GLP_DB || type == GLP_FX) + { if (sum > T->orig_ub[i] + 1e-9) + { /* upper bound is violated */ + ret = 2; + goto done; + } + } + } + /* rounded solution is integer feasible */ + if (glp_ios_heur_sol(T, x) == 0) + { /* solution is accepted */ + ret = 0; + } + else + { /* solution is rejected */ + ret = 1; + } +done: tfree(x); + return ret; +} + +#if 0 +#define round_heur round_heur2 +static int round_heur(glp_tree *T) +{ glp_prob *lp; + int *ind, ret, i, j, len; + double *val; + lp = glp_create_prob(); + ind = talloc(1+T->mip->n, int); + val = talloc(1+T->mip->n, double); + glp_add_rows(lp, T->orig_m); + glp_add_cols(lp, T->n); + for (i = 1; i <= T->orig_m; i++) + { glp_set_row_bnds(lp, i, + T->orig_type[i], T->orig_lb[i], T->orig_ub[i]); + len = glp_get_mat_row(T->mip, i, ind, val); + glp_set_mat_row(lp, i, len, ind, val); + } + for (j = 1; j <= T->n; j++) + { GLPCOL *col = T->mip->col[j]; + glp_set_obj_coef(lp, j, col->coef); + if (col->kind == GLP_IV) + { /* integer variable */ + glp_set_col_bnds(lp, j, GLP_FX, floor(col->prim + .5), 0); + } + else + { glp_set_col_bnds(lp, j, T->orig_type[T->orig_m+j], + T->orig_lb[T->orig_m+j], T->orig_ub[T->orig_m+j]); + } + } +glp_term_out(GLP_OFF); + glp_adv_basis(lp, 0); + ret = glp_simplex(lp, NULL); +glp_term_out(GLP_ON); + if (ret != 0) + { ret = 1; + goto done; + } + if (glp_get_status(lp) != GLP_OPT) + { ret = 2; + goto done; + } + for (j = 1; j <= lp->n; j++) + val[j] = lp->col[j]->prim; + if (glp_ios_heur_sol(T, val) == 0) + ret = 0; + else + ret = 3; +done: glp_delete_prob(lp); + tfree(ind); + tfree(val); + return ret; +} +#endif + +/**********************************************************************/ + +static void generate_cuts(glp_tree *T) +{ /* generate generic cuts with built-in generators */ + if (!(T->parm->mir_cuts == GLP_ON || + T->parm->gmi_cuts == GLP_ON || + T->parm->cov_cuts == GLP_ON || + T->parm->clq_cuts == GLP_ON)) goto done; +#if 1 /* 20/IX-2008 */ + { int i, max_cuts, added_cuts; + max_cuts = T->n; + if (max_cuts < 1000) max_cuts = 1000; + added_cuts = 0; + for (i = T->orig_m+1; i <= T->mip->m; i++) + { if (T->mip->row[i]->origin == GLP_RF_CUT) + added_cuts++; + } + /* xprintf("added_cuts = %d\n", added_cuts); */ + if (added_cuts >= max_cuts) goto done; + } +#endif + /* generate and add to POOL all cuts violated by x* */ + if (T->parm->gmi_cuts == GLP_ON) + { if (T->curr->changed < 7) + ios_gmi_gen(T); + } + if (T->parm->mir_cuts == GLP_ON) + { xassert(T->mir_gen != NULL); + ios_mir_gen(T, T->mir_gen); + } + if (T->parm->cov_cuts == GLP_ON) + { /* cover cuts works well along with mir cuts */ + /*if (T->round <= 5)*/ + ios_cov_gen(T); + } + if (T->parm->clq_cuts == GLP_ON) + { if (T->clq_gen != NULL) +#if 0 /* 29/VI-2013 */ + { if (T->curr->level == 0 && T->curr->changed < 50 || + T->curr->level > 0 && T->curr->changed < 5) +#else /* FIXME */ + { if (T->curr->level == 0 && T->curr->changed < 500 || + T->curr->level > 0 && T->curr->changed < 50) +#endif + ios_clq_gen(T, T->clq_gen); + } + } +done: return; +} + +/**********************************************************************/ + +static void remove_cuts(glp_tree *T) +{ /* remove inactive cuts (some valueable globally valid cut might + be saved in the global cut pool) */ + int i, cnt = 0, *num = NULL; + xassert(T->curr != NULL); + for (i = T->orig_m+1; i <= T->mip->m; i++) + { if (T->mip->row[i]->origin == GLP_RF_CUT && + T->mip->row[i]->level == T->curr->level && + T->mip->row[i]->stat == GLP_BS) + { if (num == NULL) + num = xcalloc(1+T->mip->m, sizeof(int)); + num[++cnt] = i; + } + } + if (cnt > 0) + { glp_del_rows(T->mip, cnt, num); +#if 0 + xprintf("%d inactive cut(s) removed\n", cnt); +#endif + xfree(num); + xassert(glp_factorize(T->mip) == 0); + } + return; +} + +/**********************************************************************/ + +static void display_cut_info(glp_tree *T) +{ glp_prob *mip = T->mip; + int i, gmi = 0, mir = 0, cov = 0, clq = 0, app = 0; + for (i = mip->m; i > 0; i--) + { GLPROW *row; + row = mip->row[i]; + /* if (row->level < T->curr->level) break; */ + if (row->origin == GLP_RF_CUT) + { if (row->klass == GLP_RF_GMI) + gmi++; + else if (row->klass == GLP_RF_MIR) + mir++; + else if (row->klass == GLP_RF_COV) + cov++; + else if (row->klass == GLP_RF_CLQ) + clq++; + else + app++; + } + } + xassert(T->curr != NULL); + if (gmi + mir + cov + clq + app > 0) + { xprintf("Cuts on level %d:", T->curr->level); + if (gmi > 0) xprintf(" gmi = %d;", gmi); + if (mir > 0) xprintf(" mir = %d;", mir); + if (cov > 0) xprintf(" cov = %d;", cov); + if (clq > 0) xprintf(" clq = %d;", clq); + if (app > 0) xprintf(" app = %d;", app); + xprintf("\n"); + } + return; +} + +/*********************************************************************** +* NAME +* +* ios_driver - branch-and-cut driver +* +* SYNOPSIS +* +* #include "glpios.h" +* int ios_driver(glp_tree *T); +* +* DESCRIPTION +* +* The routine ios_driver is a branch-and-cut driver. It controls the +* MIP solution process. +* +* RETURNS +* +* 0 The MIP problem instance has been successfully solved. This code +* does not necessarily mean that the solver has found optimal +* solution. It only means that the solution process was successful. +* +* GLP_EFAIL +* The search was prematurely terminated due to the solver failure. +* +* GLP_EMIPGAP +* The search was prematurely terminated, because the relative mip +* gap tolerance has been reached. +* +* GLP_ETMLIM +* The search was prematurely terminated, because the time limit has +* been exceeded. +* +* GLP_ESTOP +* The search was prematurely terminated by application. */ + +int ios_driver(glp_tree *T) +{ int p, curr_p, p_stat, d_stat, ret; +#if 1 /* carry out to glp_tree */ + int pred_p = 0; + /* if the current subproblem has been just created due to + branching, pred_p is the reference number of its parent + subproblem, otherwise pred_p is zero */ +#endif +#if 1 /* 18/VII-2013 */ + int bad_cut; + double old_obj; +#endif +#if 0 /* 10/VI-2013 */ + glp_long ttt = T->tm_beg; +#else + double ttt = T->tm_beg; +#endif +#if 0 + ((glp_iocp *)T->parm)->msg_lev = GLP_MSG_DBG; +#endif + /* on entry to the B&B driver it is assumed that the active list + contains the only active (i.e. root) subproblem, which is the + original MIP problem to be solved */ +loop: /* main loop starts here */ + /* at this point the current subproblem does not exist */ + xassert(T->curr == NULL); + /* if the active list is empty, the search is finished */ + if (T->head == NULL) + { if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Active list is empty!\n"); +#if 0 /* 10/VI-2013 */ + xassert(dmp_in_use(T->pool).lo == 0); +#else + xassert(dmp_in_use(T->pool) == 0); +#endif + ret = 0; + goto done; + } + /* select some active subproblem to continue the search */ + xassert(T->next_p == 0); + /* let the application program select subproblem */ + if (T->parm->cb_func != NULL) + { xassert(T->reason == 0); + T->reason = GLP_ISELECT; + T->parm->cb_func(T, T->parm->cb_info); + T->reason = 0; + if (T->stop) + { ret = GLP_ESTOP; + goto done; + } + } + if (T->next_p != 0) + { /* the application program has selected something */ + ; + } + else if (T->a_cnt == 1) + { /* the only active subproblem exists, so select it */ + xassert(T->head->next == NULL); + T->next_p = T->head->p; + } + else if (T->child != 0) + { /* select one of branching childs suggested by the branching + heuristic */ + T->next_p = T->child; + } + else + { /* select active subproblem as specified by the backtracking + technique option */ + T->next_p = ios_choose_node(T); + } + /* the active subproblem just selected becomes current */ + ios_revive_node(T, T->next_p); + T->next_p = T->child = 0; + /* invalidate pred_p, if it is not the reference number of the + parent of the current subproblem */ + if (T->curr->up != NULL && T->curr->up->p != pred_p) pred_p = 0; + /* determine the reference number of the current subproblem */ + p = T->curr->p; + if (T->parm->msg_lev >= GLP_MSG_DBG) + { xprintf("-----------------------------------------------------" + "-------------------\n"); + xprintf("Processing node %d at level %d\n", p, T->curr->level); + } +#if 0 + if (p == 1) + glp_write_lp(T->mip, NULL, "root.lp"); +#endif +#if 1 /* 24/X-2015 */ + if (p == 1) + { if (T->parm->sr_heur == GLP_OFF) + { if (T->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Simple rounding heuristic disabled\n"); + } + } +#endif + /* if it is the root subproblem, initialize cut generators */ + if (p == 1) + { if (T->parm->gmi_cuts == GLP_ON) + { if (T->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Gomory's cuts enabled\n"); + } + if (T->parm->mir_cuts == GLP_ON) + { if (T->parm->msg_lev >= GLP_MSG_ALL) + xprintf("MIR cuts enabled\n"); + xassert(T->mir_gen == NULL); + T->mir_gen = ios_mir_init(T); + } + if (T->parm->cov_cuts == GLP_ON) + { if (T->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Cover cuts enabled\n"); + } + if (T->parm->clq_cuts == GLP_ON) + { xassert(T->clq_gen == NULL); + if (T->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Clique cuts enabled\n"); + T->clq_gen = ios_clq_init(T); + } + } +#if 1 /* 18/VII-2013 */ + bad_cut = 0; +#endif +more: /* minor loop starts here */ + /* at this point the current subproblem needs either to be solved + for the first time or re-optimized due to reformulation */ + /* display current progress of the search */ + if (T->parm->msg_lev >= GLP_MSG_DBG || + T->parm->msg_lev >= GLP_MSG_ON && + (double)(T->parm->out_frq - 1) <= + 1000.0 * xdifftime(xtime(), T->tm_lag)) + show_progress(T, 0); + if (T->parm->msg_lev >= GLP_MSG_ALL && + xdifftime(xtime(), ttt) >= 60.0) +#if 0 /* 16/II-2012 */ + { glp_long total; + glp_mem_usage(NULL, NULL, &total, NULL); + xprintf("Time used: %.1f secs. Memory used: %.1f Mb.\n", + xdifftime(xtime(), T->tm_beg), xltod(total) / 1048576.0); + ttt = xtime(); + } +#else + { size_t total; + glp_mem_usage(NULL, NULL, &total, NULL); + xprintf("Time used: %.1f secs. Memory used: %.1f Mb.\n", + xdifftime(xtime(), T->tm_beg), (double)total / 1048576.0); + ttt = xtime(); + } +#endif + /* check the mip gap */ + if (T->parm->mip_gap > 0.0 && + ios_relative_gap(T) <= T->parm->mip_gap) + { if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Relative gap tolerance reached; search terminated " + "\n"); + ret = GLP_EMIPGAP; + goto done; + } + /* check if the time limit has been exhausted */ + if (T->parm->tm_lim < INT_MAX && + (double)(T->parm->tm_lim - 1) <= + 1000.0 * xdifftime(xtime(), T->tm_beg)) + { if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Time limit exhausted; search terminated\n"); + ret = GLP_ETMLIM; + goto done; + } + /* let the application program preprocess the subproblem */ + if (T->parm->cb_func != NULL) + { xassert(T->reason == 0); + T->reason = GLP_IPREPRO; + T->parm->cb_func(T, T->parm->cb_info); + T->reason = 0; + if (T->stop) + { ret = GLP_ESTOP; + goto done; + } + } + /* perform basic preprocessing */ + if (T->parm->pp_tech == GLP_PP_NONE) + ; + else if (T->parm->pp_tech == GLP_PP_ROOT) + { if (T->curr->level == 0) + { if (ios_preprocess_node(T, 100)) + goto fath; + } + } + else if (T->parm->pp_tech == GLP_PP_ALL) + { if (ios_preprocess_node(T, T->curr->level == 0 ? 100 : 10)) + goto fath; + } + else + xassert(T != T); + /* preprocessing may improve the global bound */ + if (!is_branch_hopeful(T, p)) + { xprintf("*** not tested yet ***\n"); + goto fath; + } + /* solve LP relaxation of the current subproblem */ + if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Solving LP relaxation...\n"); + ret = ios_solve_node(T); + if (!(ret == 0 || ret == GLP_EOBJLL || ret == GLP_EOBJUL)) + { if (T->parm->msg_lev >= GLP_MSG_ERR) + xprintf("ios_driver: unable to solve current LP relaxation;" + " glp_simplex returned %d\n", ret); + ret = GLP_EFAIL; + goto done; + } + /* analyze status of the basic solution to LP relaxation found */ + p_stat = T->mip->pbs_stat; + d_stat = T->mip->dbs_stat; + if (p_stat == GLP_FEAS && d_stat == GLP_FEAS) + { /* LP relaxation has optimal solution */ + if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Found optimal solution to LP relaxation\n"); + } + else if (d_stat == GLP_NOFEAS) + { /* LP relaxation has no dual feasible solution */ + /* since the current subproblem cannot have a larger feasible + region than its parent, there is something wrong */ + if (T->parm->msg_lev >= GLP_MSG_ERR) + xprintf("ios_driver: current LP relaxation has no dual feas" + "ible solution\n"); + ret = GLP_EFAIL; + goto done; + } + else if (p_stat == GLP_INFEAS && d_stat == GLP_FEAS) + { /* LP relaxation has no primal solution which is better than + the incumbent objective value */ + xassert(T->mip->mip_stat == GLP_FEAS); + if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("LP relaxation has no solution better than incumben" + "t objective value\n"); + /* prune the branch */ + goto fath; + } + else if (p_stat == GLP_NOFEAS) + { /* LP relaxation has no primal feasible solution */ + if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("LP relaxation has no feasible solution\n"); + /* prune the branch */ + goto fath; + } + else + { /* other cases cannot appear */ + xassert(T->mip != T->mip); + } + /* at this point basic solution to LP relaxation of the current + subproblem is optimal */ + xassert(p_stat == GLP_FEAS && d_stat == GLP_FEAS); + xassert(T->curr != NULL); + T->curr->lp_obj = T->mip->obj_val; + /* thus, it defines a local bound to integer optimal solution of + the current subproblem */ + { double bound = T->mip->obj_val; + /* some local bound to the current subproblem could be already + set before, so we should only improve it */ + bound = ios_round_bound(T, bound); + if (T->mip->dir == GLP_MIN) + { if (T->curr->bound < bound) + T->curr->bound = bound; + } + else if (T->mip->dir == GLP_MAX) + { if (T->curr->bound > bound) + T->curr->bound = bound; + } + else + xassert(T->mip != T->mip); + if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Local bound is %.9e\n", bound); + } + /* if the local bound indicates that integer optimal solution of + the current subproblem cannot be better than the global bound, + prune the branch */ + if (!is_branch_hopeful(T, p)) + { if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Current branch is hopeless and can be pruned\n"); + goto fath; + } + /* let the application program generate additional rows ("lazy" + constraints) */ + xassert(T->reopt == 0); + xassert(T->reinv == 0); + if (T->parm->cb_func != NULL) + { xassert(T->reason == 0); + T->reason = GLP_IROWGEN; + T->parm->cb_func(T, T->parm->cb_info); + T->reason = 0; + if (T->stop) + { ret = GLP_ESTOP; + goto done; + } + if (T->reopt) + { /* some rows were added; re-optimization is needed */ + T->reopt = T->reinv = 0; + goto more; + } + if (T->reinv) + { /* no rows were added, however, some inactive rows were + removed */ + T->reinv = 0; + xassert(glp_factorize(T->mip) == 0); + } + } + /* check if the basic solution is integer feasible */ + check_integrality(T); + /* if the basic solution satisfies to all integrality conditions, + it is a new, better integer feasible solution */ + if (T->curr->ii_cnt == 0) + { if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("New integer feasible solution found\n"); + if (T->parm->msg_lev >= GLP_MSG_ALL) + display_cut_info(T); + record_solution(T); + if (T->parm->msg_lev >= GLP_MSG_ON) + show_progress(T, 1); +#if 1 /* 11/VII-2013 */ + ios_process_sol(T); +#endif + /* make the application program happy */ + if (T->parm->cb_func != NULL) + { xassert(T->reason == 0); + T->reason = GLP_IBINGO; + T->parm->cb_func(T, T->parm->cb_info); + T->reason = 0; + if (T->stop) + { ret = GLP_ESTOP; + goto done; + } + } + /* since the current subproblem has been fathomed, prune its + branch */ + goto fath; + } + /* at this point basic solution to LP relaxation of the current + subproblem is optimal, but integer infeasible */ + /* try to fix some non-basic structural variables of integer kind + on their current bounds due to reduced costs */ + if (T->mip->mip_stat == GLP_FEAS) + fix_by_red_cost(T); + /* let the application program try to find some solution to the + original MIP with a primal heuristic */ + if (T->parm->cb_func != NULL) + { xassert(T->reason == 0); + T->reason = GLP_IHEUR; + T->parm->cb_func(T, T->parm->cb_info); + T->reason = 0; + if (T->stop) + { ret = GLP_ESTOP; + goto done; + } + /* check if the current branch became hopeless */ + if (!is_branch_hopeful(T, p)) + { if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Current branch became hopeless and can be prune" + "d\n"); + goto fath; + } + } + /* try to find solution with the feasibility pump heuristic */ + if (T->parm->fp_heur) + { xassert(T->reason == 0); + T->reason = GLP_IHEUR; + ios_feas_pump(T); + T->reason = 0; + /* check if the current branch became hopeless */ + if (!is_branch_hopeful(T, p)) + { if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Current branch became hopeless and can be prune" + "d\n"); + goto fath; + } + } +#if 1 /* 25/V-2013 */ + /* try to find solution with the proximity search heuristic */ + if (T->parm->ps_heur) + { xassert(T->reason == 0); + T->reason = GLP_IHEUR; + ios_proxy_heur(T); + T->reason = 0; + /* check if the current branch became hopeless */ + if (!is_branch_hopeful(T, p)) + { if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Current branch became hopeless and can be prune" + "d\n"); + goto fath; + } + } +#endif +#if 1 /* 24/X-2015 */ + /* try to find solution with a simple rounding heuristic */ + if (T->parm->sr_heur) + { xassert(T->reason == 0); + T->reason = GLP_IHEUR; + round_heur(T); + T->reason = 0; + /* check if the current branch became hopeless */ + if (!is_branch_hopeful(T, p)) + { if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Current branch became hopeless and can be prune" + "d\n"); + goto fath; + } + } +#endif + /* it's time to generate cutting planes */ + xassert(T->local != NULL); + xassert(T->local->size == 0); + /* let the application program generate some cuts; note that it + can add cuts either to the local cut pool or directly to the + current subproblem */ + if (T->parm->cb_func != NULL) + { xassert(T->reason == 0); + T->reason = GLP_ICUTGEN; + T->parm->cb_func(T, T->parm->cb_info); + T->reason = 0; + if (T->stop) + { ret = GLP_ESTOP; + goto done; + } + } +#if 1 /* 18/VII-2013 */ + if (T->curr->changed > 0) + { double degrad = fabs(T->curr->lp_obj - old_obj); + if (degrad < 1e-4 * (1.0 + fabs(old_obj))) + bad_cut++; + else + bad_cut = 0; + } + old_obj = T->curr->lp_obj; + if (bad_cut == 0 || (T->curr->level == 0 && bad_cut <= 3)) +#endif + /* try to generate generic cuts with built-in generators + (as suggested by Prof. Fischetti et al. the built-in cuts are + not generated at each branching node; an intense attempt of + generating new cuts is only made at the root node, and then + a moderate effort is spent after each backtracking step) */ + if (T->curr->level == 0 || pred_p == 0) + { xassert(T->reason == 0); + T->reason = GLP_ICUTGEN; + generate_cuts(T); + T->reason = 0; + } + /* if the local cut pool is not empty, select useful cuts and add + them to the current subproblem */ + if (T->local->size > 0) + { xassert(T->reason == 0); + T->reason = GLP_ICUTGEN; + ios_process_cuts(T); + T->reason = 0; + } + /* clear the local cut pool */ + ios_clear_pool(T, T->local); + /* perform re-optimization, if necessary */ + if (T->reopt) + { T->reopt = 0; + T->curr->changed++; + goto more; + } + /* no cuts were generated; remove inactive cuts */ + remove_cuts(T); + if (T->parm->msg_lev >= GLP_MSG_ALL && T->curr->level == 0) + display_cut_info(T); + /* update history information used on pseudocost branching */ + if (T->pcost != NULL) ios_pcost_update(T); + /* it's time to perform branching */ + xassert(T->br_var == 0); + xassert(T->br_sel == 0); + /* let the application program choose variable to branch on */ + if (T->parm->cb_func != NULL) + { xassert(T->reason == 0); + xassert(T->br_var == 0); + xassert(T->br_sel == 0); + T->reason = GLP_IBRANCH; + T->parm->cb_func(T, T->parm->cb_info); + T->reason = 0; + if (T->stop) + { ret = GLP_ESTOP; + goto done; + } + } + /* if nothing has been chosen, choose some variable as specified + by the branching technique option */ + if (T->br_var == 0) + T->br_var = ios_choose_var(T, &T->br_sel); + /* perform actual branching */ + curr_p = T->curr->p; + ret = branch_on(T, T->br_var, T->br_sel); + T->br_var = T->br_sel = 0; + if (ret == 0) + { /* both branches have been created */ + pred_p = curr_p; + goto loop; + } + else if (ret == 1) + { /* one branch is hopeless and has been pruned, so now the + current subproblem is other branch */ + /* the current subproblem should be considered as a new one, + since one bound of the branching variable was changed */ + T->curr->solved = T->curr->changed = 0; +#if 1 /* 18/VII-2013 */ + /* bad_cut = 0; */ +#endif + goto more; + } + else if (ret == 2) + { /* both branches are hopeless and have been pruned; new + subproblem selection is needed to continue the search */ + goto fath; + } + else + xassert(ret != ret); +fath: /* the current subproblem has been fathomed */ + if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("Node %d fathomed\n", p); + /* freeze the current subproblem */ + ios_freeze_node(T); + /* and prune the corresponding branch of the tree */ + ios_delete_node(T, p); + /* if a new integer feasible solution has just been found, other + branches may become hopeless and therefore must be pruned */ + if (T->mip->mip_stat == GLP_FEAS) cleanup_the_tree(T); + /* new subproblem selection is needed due to backtracking */ + pred_p = 0; + goto loop; +done: /* display progress of the search on exit from the solver */ + if (T->parm->msg_lev >= GLP_MSG_ON) + show_progress(T, 0); + if (T->mir_gen != NULL) + ios_mir_term(T->mir_gen), T->mir_gen = NULL; + if (T->clq_gen != NULL) + ios_clq_term(T->clq_gen), T->clq_gen = NULL; + /* return to the calling program */ + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpios04.c b/resources/3rdparty/glpk-4.57/src/glpios04.c new file mode 100644 index 000000000..8074f7e71 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpios04.c @@ -0,0 +1,304 @@ +/* glpios04.c (operations on sparse vectors) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpios.h" + +/*********************************************************************** +* NAME +* +* ios_create_vec - create sparse vector +* +* SYNOPSIS +* +* #include "glpios.h" +* IOSVEC *ios_create_vec(int n); +* +* DESCRIPTION +* +* The routine ios_create_vec creates a sparse vector of dimension n, +* which initially is a null vector. +* +* RETURNS +* +* The routine returns a pointer to the vector created. */ + +IOSVEC *ios_create_vec(int n) +{ IOSVEC *v; + xassert(n >= 0); + v = xmalloc(sizeof(IOSVEC)); + v->n = n; + v->nnz = 0; + v->pos = xcalloc(1+n, sizeof(int)); + memset(&v->pos[1], 0, n * sizeof(int)); + v->ind = xcalloc(1+n, sizeof(int)); + v->val = xcalloc(1+n, sizeof(double)); + return v; +} + +/*********************************************************************** +* NAME +* +* ios_check_vec - check that sparse vector has correct representation +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_check_vec(IOSVEC *v); +* +* DESCRIPTION +* +* The routine ios_check_vec checks that a sparse vector specified by +* the parameter v has correct representation. +* +* NOTE +* +* Complexity of this operation is O(n). */ + +void ios_check_vec(IOSVEC *v) +{ int j, k, nnz; + xassert(v->n >= 0); + nnz = 0; + for (j = v->n; j >= 1; j--) + { k = v->pos[j]; + xassert(0 <= k && k <= v->nnz); + if (k != 0) + { xassert(v->ind[k] == j); + nnz++; + } + } + xassert(v->nnz == nnz); + return; +} + +/*********************************************************************** +* NAME +* +* ios_get_vj - retrieve component of sparse vector +* +* SYNOPSIS +* +* #include "glpios.h" +* double ios_get_vj(IOSVEC *v, int j); +* +* RETURNS +* +* The routine ios_get_vj returns j-th component of a sparse vector +* specified by the parameter v. */ + +double ios_get_vj(IOSVEC *v, int j) +{ int k; + xassert(1 <= j && j <= v->n); + k = v->pos[j]; + xassert(0 <= k && k <= v->nnz); + return (k == 0 ? 0.0 : v->val[k]); +} + +/*********************************************************************** +* NAME +* +* ios_set_vj - set/change component of sparse vector +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_set_vj(IOSVEC *v, int j, double val); +* +* DESCRIPTION +* +* The routine ios_set_vj assigns val to j-th component of a sparse +* vector specified by the parameter v. */ + +void ios_set_vj(IOSVEC *v, int j, double val) +{ int k; + xassert(1 <= j && j <= v->n); + k = v->pos[j]; + if (val == 0.0) + { if (k != 0) + { /* remove j-th component */ + v->pos[j] = 0; + if (k < v->nnz) + { v->pos[v->ind[v->nnz]] = k; + v->ind[k] = v->ind[v->nnz]; + v->val[k] = v->val[v->nnz]; + } + v->nnz--; + } + } + else + { if (k == 0) + { /* create j-th component */ + k = ++(v->nnz); + v->pos[j] = k; + v->ind[k] = j; + } + v->val[k] = val; + } + return; +} + +/*********************************************************************** +* NAME +* +* ios_clear_vec - set all components of sparse vector to zero +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_clear_vec(IOSVEC *v); +* +* DESCRIPTION +* +* The routine ios_clear_vec sets all components of a sparse vector +* specified by the parameter v to zero. */ + +void ios_clear_vec(IOSVEC *v) +{ int k; + for (k = 1; k <= v->nnz; k++) + v->pos[v->ind[k]] = 0; + v->nnz = 0; + return; +} + +/*********************************************************************** +* NAME +* +* ios_clean_vec - remove zero or small components from sparse vector +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_clean_vec(IOSVEC *v, double eps); +* +* DESCRIPTION +* +* The routine ios_clean_vec removes zero components and components +* whose magnitude is less than eps from a sparse vector specified by +* the parameter v. If eps is 0.0, only zero components are removed. */ + +void ios_clean_vec(IOSVEC *v, double eps) +{ int k, nnz; + nnz = 0; + for (k = 1; k <= v->nnz; k++) + { if (fabs(v->val[k]) == 0.0 || fabs(v->val[k]) < eps) + { /* remove component */ + v->pos[v->ind[k]] = 0; + } + else + { /* keep component */ + nnz++; + v->pos[v->ind[k]] = nnz; + v->ind[nnz] = v->ind[k]; + v->val[nnz] = v->val[k]; + } + } + v->nnz = nnz; + return; +} + +/*********************************************************************** +* NAME +* +* ios_copy_vec - copy sparse vector (x := y) +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_copy_vec(IOSVEC *x, IOSVEC *y); +* +* DESCRIPTION +* +* The routine ios_copy_vec copies a sparse vector specified by the +* parameter y to a sparse vector specified by the parameter x. */ + +void ios_copy_vec(IOSVEC *x, IOSVEC *y) +{ int j; + xassert(x != y); + xassert(x->n == y->n); + ios_clear_vec(x); + x->nnz = y->nnz; + memcpy(&x->ind[1], &y->ind[1], x->nnz * sizeof(int)); + memcpy(&x->val[1], &y->val[1], x->nnz * sizeof(double)); + for (j = 1; j <= x->nnz; j++) + x->pos[x->ind[j]] = j; + return; +} + +/*********************************************************************** +* NAME +* +* ios_linear_comb - compute linear combination (x := x + a * y) +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_linear_comb(IOSVEC *x, double a, IOSVEC *y); +* +* DESCRIPTION +* +* The routine ios_linear_comb computes the linear combination +* +* x := x + a * y, +* +* where x and y are sparse vectors, a is a scalar. */ + +void ios_linear_comb(IOSVEC *x, double a, IOSVEC *y) +{ int j, k; + double xj, yj; + xassert(x != y); + xassert(x->n == y->n); + for (k = 1; k <= y->nnz; k++) + { j = y->ind[k]; + xj = ios_get_vj(x, j); + yj = y->val[k]; + ios_set_vj(x, j, xj + a * yj); + } + return; +} + +/*********************************************************************** +* NAME +* +* ios_delete_vec - delete sparse vector +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_delete_vec(IOSVEC *v); +* +* DESCRIPTION +* +* The routine ios_delete_vec deletes a sparse vector specified by the +* parameter v freeing all the memory allocated to this object. */ + +void ios_delete_vec(IOSVEC *v) +{ /* delete sparse vector */ + xfree(v->pos); + xfree(v->ind); + xfree(v->val); + xfree(v); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpios05.c b/resources/3rdparty/glpk-4.57/src/glpios05.c new file mode 100644 index 000000000..18ae0cbbb --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpios05.c @@ -0,0 +1,282 @@ +/* glpios05.c (Gomory's mixed integer cut generator) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpios.h" + +/*********************************************************************** +* NAME +* +* ios_gmi_gen - generate Gomory's mixed integer cuts. +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_gmi_gen(glp_tree *tree, IOSPOOL *pool); +* +* DESCRIPTION +* +* The routine ios_gmi_gen generates Gomory's mixed integer cuts for +* the current point and adds them to the cut pool. */ + +#define MAXCUTS 50 +/* maximal number of cuts to be generated for one round */ + +struct worka +{ /* Gomory's cut generator working area */ + int *ind; /* int ind[1+n]; */ + double *val; /* double val[1+n]; */ + double *phi; /* double phi[1+m+n]; */ +}; + +#define f(x) ((x) - floor(x)) +/* compute fractional part of x */ + +static void gen_cut(glp_tree *tree, struct worka *worka, int j) +{ /* this routine tries to generate Gomory's mixed integer cut for + specified structural variable x[m+j] of integer kind, which is + basic and has fractional value in optimal solution to current + LP relaxation */ + glp_prob *mip = tree->mip; + int m = mip->m; + int n = mip->n; + int *ind = worka->ind; + double *val = worka->val; + double *phi = worka->phi; + int i, k, len, kind, stat; + double lb, ub, alfa, beta, ksi, phi1, rhs; + /* compute row of the simplex tableau, which (row) corresponds + to specified basic variable xB[i] = x[m+j]; see (23) */ + len = glp_eval_tab_row(mip, m+j, ind, val); + /* determine beta[i], which a value of xB[i] in optimal solution + to current LP relaxation; note that this value is the same as + if it would be computed with formula (27); it is assumed that + beta[i] is fractional enough */ + beta = mip->col[j]->prim; + /* compute cut coefficients phi and right-hand side rho, which + correspond to formula (30); dense format is used, because rows + of the simplex tableau is usually dense */ + for (k = 1; k <= m+n; k++) phi[k] = 0.0; + rhs = f(beta); /* initial value of rho; see (28), (32) */ + for (j = 1; j <= len; j++) + { /* determine original number of non-basic variable xN[j] */ + k = ind[j]; + xassert(1 <= k && k <= m+n); + /* determine the kind, bounds and current status of xN[j] in + optimal solution to LP relaxation */ + if (k <= m) + { /* auxiliary variable */ + GLPROW *row = mip->row[k]; + kind = GLP_CV; + lb = row->lb; + ub = row->ub; + stat = row->stat; + } + else + { /* structural variable */ + GLPCOL *col = mip->col[k-m]; + kind = col->kind; + lb = col->lb; + ub = col->ub; + stat = col->stat; + } + /* xN[j] cannot be basic */ + xassert(stat != GLP_BS); + /* determine row coefficient ksi[i,j] at xN[j]; see (23) */ + ksi = val[j]; + /* if ksi[i,j] is too large in the magnitude, do not generate + the cut */ + if (fabs(ksi) > 1e+05) goto fini; + /* if ksi[i,j] is too small in the magnitude, skip it */ + if (fabs(ksi) < 1e-10) goto skip; + /* compute row coefficient alfa[i,j] at y[j]; see (26) */ + switch (stat) + { case GLP_NF: + /* xN[j] is free (unbounded) having non-zero ksi[i,j]; + do not generate the cut */ + goto fini; + case GLP_NL: + /* xN[j] has active lower bound */ + alfa = - ksi; + break; + case GLP_NU: + /* xN[j] has active upper bound */ + alfa = + ksi; + break; + case GLP_NS: + /* xN[j] is fixed; skip it */ + goto skip; + default: + xassert(stat != stat); + } + /* compute cut coefficient phi'[j] at y[j]; see (21), (28) */ + switch (kind) + { case GLP_IV: + /* y[j] is integer */ + if (fabs(alfa - floor(alfa + 0.5)) < 1e-10) + { /* alfa[i,j] is close to nearest integer; skip it */ + goto skip; + } + else if (f(alfa) <= f(beta)) + phi1 = f(alfa); + else + phi1 = (f(beta) / (1.0 - f(beta))) * (1.0 - f(alfa)); + break; + case GLP_CV: + /* y[j] is continuous */ + if (alfa >= 0.0) + phi1 = + alfa; + else + phi1 = (f(beta) / (1.0 - f(beta))) * (- alfa); + break; + default: + xassert(kind != kind); + } + /* compute cut coefficient phi[j] at xN[j] and update right- + hand side rho; see (31), (32) */ + switch (stat) + { case GLP_NL: + /* xN[j] has active lower bound */ + phi[k] = + phi1; + rhs += phi1 * lb; + break; + case GLP_NU: + /* xN[j] has active upper bound */ + phi[k] = - phi1; + rhs -= phi1 * ub; + break; + default: + xassert(stat != stat); + } +skip: ; + } + /* now the cut has the form sum_k phi[k] * x[k] >= rho, where cut + coefficients are stored in the array phi in dense format; + x[1,...,m] are auxiliary variables, x[m+1,...,m+n] are struc- + tural variables; see (30) */ + /* eliminate auxiliary variables in order to express the cut only + through structural variables; see (33) */ + for (i = 1; i <= m; i++) + { GLPROW *row; + GLPAIJ *aij; + if (fabs(phi[i]) < 1e-10) continue; + /* auxiliary variable x[i] has non-zero cut coefficient */ + row = mip->row[i]; + /* x[i] cannot be fixed */ + xassert(row->type != GLP_FX); + /* substitute x[i] = sum_j a[i,j] * x[m+j] */ + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + phi[m+aij->col->j] += phi[i] * aij->val; + } + /* convert the final cut to sparse format and substitute fixed + (structural) variables */ + len = 0; + for (j = 1; j <= n; j++) + { GLPCOL *col; + if (fabs(phi[m+j]) < 1e-10) continue; + /* structural variable x[m+j] has non-zero cut coefficient */ + col = mip->col[j]; + if (col->type == GLP_FX) + { /* eliminate x[m+j] */ + rhs -= phi[m+j] * col->lb; + } + else + { len++; + ind[len] = j; + val[len] = phi[m+j]; + } + } + if (fabs(rhs) < 1e-12) rhs = 0.0; + /* if the cut inequality seems to be badly scaled, reject it to + avoid numeric difficulties */ + for (k = 1; k <= len; k++) + { if (fabs(val[k]) < 1e-03) goto fini; + if (fabs(val[k]) > 1e+03) goto fini; + } + /* add the cut to the cut pool for further consideration */ +#if 0 + ios_add_cut_row(tree, pool, GLP_RF_GMI, len, ind, val, GLP_LO, + rhs); +#else + glp_ios_add_row(tree, NULL, GLP_RF_GMI, 0, len, ind, val, GLP_LO, + rhs); +#endif +fini: return; +} + +struct var { int j; double f; }; + +static int fcmp(const void *p1, const void *p2) +{ const struct var *v1 = p1, *v2 = p2; + if (v1->f > v2->f) return -1; + if (v1->f < v2->f) return +1; + return 0; +} + +void ios_gmi_gen(glp_tree *tree) +{ /* main routine to generate Gomory's cuts */ + glp_prob *mip = tree->mip; + int m = mip->m; + int n = mip->n; + struct var *var; + int k, nv, j, size; + struct worka _worka, *worka = &_worka; + /* allocate working arrays */ + var = xcalloc(1+n, sizeof(struct var)); + worka->ind = xcalloc(1+n, sizeof(int)); + worka->val = xcalloc(1+n, sizeof(double)); + worka->phi = xcalloc(1+m+n, sizeof(double)); + /* build the list of integer structural variables, which are + basic and have fractional value in optimal solution to current + LP relaxation */ + nv = 0; + for (j = 1; j <= n; j++) + { GLPCOL *col = mip->col[j]; + double frac; + if (col->kind != GLP_IV) continue; + if (col->type == GLP_FX) continue; + if (col->stat != GLP_BS) continue; + frac = f(col->prim); + if (!(0.05 <= frac && frac <= 0.95)) continue; + /* add variable to the list */ + nv++, var[nv].j = j, var[nv].f = frac; + } + /* order the list by descending fractionality */ + qsort(&var[1], nv, sizeof(struct var), fcmp); + /* try to generate cuts by one for each variable in the list, but + not more than MAXCUTS cuts */ + size = glp_ios_pool_size(tree); + for (k = 1; k <= nv; k++) + { if (glp_ios_pool_size(tree) - size >= MAXCUTS) break; + gen_cut(tree, worka, var[k].j); + } + /* free working arrays */ + xfree(var); + xfree(worka->ind); + xfree(worka->val); + xfree(worka->phi); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpios06.c b/resources/3rdparty/glpk-4.57/src/glpios06.c new file mode 100644 index 000000000..53f8dcfc7 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpios06.c @@ -0,0 +1,1448 @@ +/* glpios06.c (MIR cut generator) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpios.h" + +#define _MIR_DEBUG 0 + +#define MAXAGGR 5 +/* maximal number of rows which can be aggregated */ + +struct MIR +{ /* MIR cut generator working area */ + /*--------------------------------------------------------------*/ + /* global information valid for the root subproblem */ + int m; + /* number of rows (in the root subproblem) */ + int n; + /* number of columns */ + char *skip; /* char skip[1+m]; */ + /* skip[i], 1 <= i <= m, is a flag that means that row i should + not be used because (1) it is not suitable, or (2) because it + has been used in the aggregated constraint */ + char *isint; /* char isint[1+m+n]; */ + /* isint[k], 1 <= k <= m+n, is a flag that means that variable + x[k] is integer (otherwise, continuous) */ + double *lb; /* double lb[1+m+n]; */ + /* lb[k], 1 <= k <= m+n, is lower bound of x[k]; -DBL_MAX means + that x[k] has no lower bound */ + int *vlb; /* int vlb[1+m+n]; */ + /* vlb[k] = k', 1 <= k <= m+n, is the number of integer variable, + which defines variable lower bound x[k] >= lb[k] * x[k']; zero + means that x[k] has simple lower bound */ + double *ub; /* double ub[1+m+n]; */ + /* ub[k], 1 <= k <= m+n, is upper bound of x[k]; +DBL_MAX means + that x[k] has no upper bound */ + int *vub; /* int vub[1+m+n]; */ + /* vub[k] = k', 1 <= k <= m+n, is the number of integer variable, + which defines variable upper bound x[k] <= ub[k] * x[k']; zero + means that x[k] has simple upper bound */ + /*--------------------------------------------------------------*/ + /* current (fractional) point to be separated */ + double *x; /* double x[1+m+n]; */ + /* x[k] is current value of auxiliary (1 <= k <= m) or structural + (m+1 <= k <= m+n) variable */ + /*--------------------------------------------------------------*/ + /* aggregated constraint sum a[k] * x[k] = b, which is a linear + combination of original constraints transformed to equalities + by introducing auxiliary variables */ + int agg_cnt; + /* number of rows (original constraints) used to build aggregated + constraint, 1 <= agg_cnt <= MAXAGGR */ + int *agg_row; /* int agg_row[1+MAXAGGR]; */ + /* agg_row[k], 1 <= k <= agg_cnt, is the row number used to build + aggregated constraint */ + IOSVEC *agg_vec; /* IOSVEC agg_vec[1:m+n]; */ + /* sparse vector of aggregated constraint coefficients, a[k] */ + double agg_rhs; + /* right-hand side of the aggregated constraint, b */ + /*--------------------------------------------------------------*/ + /* bound substitution flags for modified constraint */ + char *subst; /* char subst[1+m+n]; */ + /* subst[k], 1 <= k <= m+n, is a bound substitution flag used for + variable x[k]: + '?' - x[k] is missing in modified constraint + 'L' - x[k] = (lower bound) + x'[k] + 'U' - x[k] = (upper bound) - x'[k] */ + /*--------------------------------------------------------------*/ + /* modified constraint sum a'[k] * x'[k] = b', where x'[k] >= 0, + derived from aggregated constraint by substituting bounds; + note that due to substitution of variable bounds there may be + additional terms in the modified constraint */ + IOSVEC *mod_vec; /* IOSVEC mod_vec[1:m+n]; */ + /* sparse vector of modified constraint coefficients, a'[k] */ + double mod_rhs; + /* right-hand side of the modified constraint, b' */ + /*--------------------------------------------------------------*/ + /* cutting plane sum alpha[k] * x[k] <= beta */ + IOSVEC *cut_vec; /* IOSVEC cut_vec[1:m+n]; */ + /* sparse vector of cutting plane coefficients, alpha[k] */ + double cut_rhs; + /* right-hand size of the cutting plane, beta */ +}; + +/*********************************************************************** +* NAME +* +* ios_mir_init - initialize MIR cut generator +* +* SYNOPSIS +* +* #include "glpios.h" +* void *ios_mir_init(glp_tree *tree); +* +* DESCRIPTION +* +* The routine ios_mir_init initializes the MIR cut generator assuming +* that the current subproblem is the root subproblem. +* +* RETURNS +* +* The routine ios_mir_init returns a pointer to the MIR cut generator +* working area. */ + +static void set_row_attrib(glp_tree *tree, struct MIR *mir) +{ /* set global row attributes */ + glp_prob *mip = tree->mip; + int m = mir->m; + int k; + for (k = 1; k <= m; k++) + { GLPROW *row = mip->row[k]; + mir->skip[k] = 0; + mir->isint[k] = 0; + switch (row->type) + { case GLP_FR: + mir->lb[k] = -DBL_MAX, mir->ub[k] = +DBL_MAX; break; + case GLP_LO: + mir->lb[k] = row->lb, mir->ub[k] = +DBL_MAX; break; + case GLP_UP: + mir->lb[k] = -DBL_MAX, mir->ub[k] = row->ub; break; + case GLP_DB: + mir->lb[k] = row->lb, mir->ub[k] = row->ub; break; + case GLP_FX: + mir->lb[k] = mir->ub[k] = row->lb; break; + default: + xassert(row != row); + } + mir->vlb[k] = mir->vub[k] = 0; + } + return; +} + +static void set_col_attrib(glp_tree *tree, struct MIR *mir) +{ /* set global column attributes */ + glp_prob *mip = tree->mip; + int m = mir->m; + int n = mir->n; + int k; + for (k = m+1; k <= m+n; k++) + { GLPCOL *col = mip->col[k-m]; + switch (col->kind) + { case GLP_CV: + mir->isint[k] = 0; break; + case GLP_IV: + mir->isint[k] = 1; break; + default: + xassert(col != col); + } + switch (col->type) + { case GLP_FR: + mir->lb[k] = -DBL_MAX, mir->ub[k] = +DBL_MAX; break; + case GLP_LO: + mir->lb[k] = col->lb, mir->ub[k] = +DBL_MAX; break; + case GLP_UP: + mir->lb[k] = -DBL_MAX, mir->ub[k] = col->ub; break; + case GLP_DB: + mir->lb[k] = col->lb, mir->ub[k] = col->ub; break; + case GLP_FX: + mir->lb[k] = mir->ub[k] = col->lb; break; + default: + xassert(col != col); + } + mir->vlb[k] = mir->vub[k] = 0; + } + return; +} + +static void set_var_bounds(glp_tree *tree, struct MIR *mir) +{ /* set variable bounds */ + glp_prob *mip = tree->mip; + int m = mir->m; + GLPAIJ *aij; + int i, k1, k2; + double a1, a2; + for (i = 1; i <= m; i++) + { /* we need the row to be '>= 0' or '<= 0' */ + if (!(mir->lb[i] == 0.0 && mir->ub[i] == +DBL_MAX || + mir->lb[i] == -DBL_MAX && mir->ub[i] == 0.0)) continue; + /* take first term */ + aij = mip->row[i]->ptr; + if (aij == NULL) continue; + k1 = m + aij->col->j, a1 = aij->val; + /* take second term */ + aij = aij->r_next; + if (aij == NULL) continue; + k2 = m + aij->col->j, a2 = aij->val; + /* there must be only two terms */ + if (aij->r_next != NULL) continue; + /* interchange terms, if needed */ + if (!mir->isint[k1] && mir->isint[k2]) + ; + else if (mir->isint[k1] && !mir->isint[k2]) + { k2 = k1, a2 = a1; + k1 = m + aij->col->j, a1 = aij->val; + } + else + { /* both terms are either continuous or integer */ + continue; + } + /* x[k2] should be double-bounded */ + if (mir->lb[k2] == -DBL_MAX || mir->ub[k2] == +DBL_MAX || + mir->lb[k2] == mir->ub[k2]) continue; + /* change signs, if necessary */ + if (mir->ub[i] == 0.0) a1 = - a1, a2 = - a2; + /* now the row has the form a1 * x1 + a2 * x2 >= 0, where x1 + is continuous, x2 is integer */ + if (a1 > 0.0) + { /* x1 >= - (a2 / a1) * x2 */ + if (mir->vlb[k1] == 0) + { /* set variable lower bound for x1 */ + mir->lb[k1] = - a2 / a1; + mir->vlb[k1] = k2; + /* the row should not be used */ + mir->skip[i] = 1; + } + } + else /* a1 < 0.0 */ + { /* x1 <= - (a2 / a1) * x2 */ + if (mir->vub[k1] == 0) + { /* set variable upper bound for x1 */ + mir->ub[k1] = - a2 / a1; + mir->vub[k1] = k2; + /* the row should not be used */ + mir->skip[i] = 1; + } + } + } + return; +} + +static void mark_useless_rows(glp_tree *tree, struct MIR *mir) +{ /* mark rows which should not be used */ + glp_prob *mip = tree->mip; + int m = mir->m; + GLPAIJ *aij; + int i, k, nv; + for (i = 1; i <= m; i++) + { /* free rows should not be used */ + if (mir->lb[i] == -DBL_MAX && mir->ub[i] == +DBL_MAX) + { mir->skip[i] = 1; + continue; + } + nv = 0; + for (aij = mip->row[i]->ptr; aij != NULL; aij = aij->r_next) + { k = m + aij->col->j; + /* rows with free variables should not be used */ + if (mir->lb[k] == -DBL_MAX && mir->ub[k] == +DBL_MAX) + { mir->skip[i] = 1; + break; + } + /* rows with integer variables having infinite (lower or + upper) bound should not be used */ + if (mir->isint[k] && mir->lb[k] == -DBL_MAX || + mir->isint[k] && mir->ub[k] == +DBL_MAX) + { mir->skip[i] = 1; + break; + } + /* count non-fixed variables */ + if (!(mir->vlb[k] == 0 && mir->vub[k] == 0 && + mir->lb[k] == mir->ub[k])) nv++; + } + /* rows with all variables fixed should not be used */ + if (nv == 0) + { mir->skip[i] = 1; + continue; + } + } + return; +} + +void *ios_mir_init(glp_tree *tree) +{ /* initialize MIR cut generator */ + glp_prob *mip = tree->mip; + int m = mip->m; + int n = mip->n; + struct MIR *mir; +#if _MIR_DEBUG + xprintf("ios_mir_init: warning: debug mode enabled\n"); +#endif + /* allocate working area */ + mir = xmalloc(sizeof(struct MIR)); + mir->m = m; + mir->n = n; + mir->skip = xcalloc(1+m, sizeof(char)); + mir->isint = xcalloc(1+m+n, sizeof(char)); + mir->lb = xcalloc(1+m+n, sizeof(double)); + mir->vlb = xcalloc(1+m+n, sizeof(int)); + mir->ub = xcalloc(1+m+n, sizeof(double)); + mir->vub = xcalloc(1+m+n, sizeof(int)); + mir->x = xcalloc(1+m+n, sizeof(double)); + mir->agg_row = xcalloc(1+MAXAGGR, sizeof(int)); + mir->agg_vec = ios_create_vec(m+n); + mir->subst = xcalloc(1+m+n, sizeof(char)); + mir->mod_vec = ios_create_vec(m+n); + mir->cut_vec = ios_create_vec(m+n); + /* set global row attributes */ + set_row_attrib(tree, mir); + /* set global column attributes */ + set_col_attrib(tree, mir); + /* set variable bounds */ + set_var_bounds(tree, mir); + /* mark rows which should not be used */ + mark_useless_rows(tree, mir); + return mir; +} + +/*********************************************************************** +* NAME +* +* ios_mir_gen - generate MIR cuts +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_mir_gen(glp_tree *tree, void *gen, IOSPOOL *pool); +* +* DESCRIPTION +* +* The routine ios_mir_gen generates MIR cuts for the current point and +* adds them to the cut pool. */ + +static void get_current_point(glp_tree *tree, struct MIR *mir) +{ /* obtain current point */ + glp_prob *mip = tree->mip; + int m = mir->m; + int n = mir->n; + int k; + for (k = 1; k <= m; k++) + mir->x[k] = mip->row[k]->prim; + for (k = m+1; k <= m+n; k++) + mir->x[k] = mip->col[k-m]->prim; + return; +} + +#if _MIR_DEBUG +static void check_current_point(struct MIR *mir) +{ /* check current point */ + int m = mir->m; + int n = mir->n; + int k, kk; + double lb, ub, eps; + for (k = 1; k <= m+n; k++) + { /* determine lower bound */ + lb = mir->lb[k]; + kk = mir->vlb[k]; + if (kk != 0) + { xassert(lb != -DBL_MAX); + xassert(!mir->isint[k]); + xassert(mir->isint[kk]); + lb *= mir->x[kk]; + } + /* check lower bound */ + if (lb != -DBL_MAX) + { eps = 1e-6 * (1.0 + fabs(lb)); + xassert(mir->x[k] >= lb - eps); + } + /* determine upper bound */ + ub = mir->ub[k]; + kk = mir->vub[k]; + if (kk != 0) + { xassert(ub != +DBL_MAX); + xassert(!mir->isint[k]); + xassert(mir->isint[kk]); + ub *= mir->x[kk]; + } + /* check upper bound */ + if (ub != +DBL_MAX) + { eps = 1e-6 * (1.0 + fabs(ub)); + xassert(mir->x[k] <= ub + eps); + } + } + return; +} +#endif + +static void initial_agg_row(glp_tree *tree, struct MIR *mir, int i) +{ /* use original i-th row as initial aggregated constraint */ + glp_prob *mip = tree->mip; + int m = mir->m; + GLPAIJ *aij; + xassert(1 <= i && i <= m); + xassert(!mir->skip[i]); + /* mark i-th row in order not to use it in the same aggregated + constraint */ + mir->skip[i] = 2; + mir->agg_cnt = 1; + mir->agg_row[1] = i; + /* use x[i] - sum a[i,j] * x[m+j] = 0, where x[i] is auxiliary + variable of row i, x[m+j] are structural variables */ + ios_clear_vec(mir->agg_vec); + ios_set_vj(mir->agg_vec, i, 1.0); + for (aij = mip->row[i]->ptr; aij != NULL; aij = aij->r_next) + ios_set_vj(mir->agg_vec, m + aij->col->j, - aij->val); + mir->agg_rhs = 0.0; +#if _MIR_DEBUG + ios_check_vec(mir->agg_vec); +#endif + return; +} + +#if _MIR_DEBUG +static void check_agg_row(struct MIR *mir) +{ /* check aggregated constraint */ + int m = mir->m; + int n = mir->n; + int j, k; + double r, big; + /* compute the residual r = sum a[k] * x[k] - b and determine + big = max(1, |a[k]|, |b|) */ + r = 0.0, big = 1.0; + for (j = 1; j <= mir->agg_vec->nnz; j++) + { k = mir->agg_vec->ind[j]; + xassert(1 <= k && k <= m+n); + r += mir->agg_vec->val[j] * mir->x[k]; + if (big < fabs(mir->agg_vec->val[j])) + big = fabs(mir->agg_vec->val[j]); + } + r -= mir->agg_rhs; + if (big < fabs(mir->agg_rhs)) + big = fabs(mir->agg_rhs); + /* the residual must be close to zero */ + xassert(fabs(r) <= 1e-6 * big); + return; +} +#endif + +static void subst_fixed_vars(struct MIR *mir) +{ /* substitute fixed variables into aggregated constraint */ + int m = mir->m; + int n = mir->n; + int j, k; + for (j = 1; j <= mir->agg_vec->nnz; j++) + { k = mir->agg_vec->ind[j]; + xassert(1 <= k && k <= m+n); + if (mir->vlb[k] == 0 && mir->vub[k] == 0 && + mir->lb[k] == mir->ub[k]) + { /* x[k] is fixed */ + mir->agg_rhs -= mir->agg_vec->val[j] * mir->lb[k]; + mir->agg_vec->val[j] = 0.0; + } + } + /* remove terms corresponding to fixed variables */ + ios_clean_vec(mir->agg_vec, DBL_EPSILON); +#if _MIR_DEBUG + ios_check_vec(mir->agg_vec); +#endif + return; +} + +static void bound_subst_heur(struct MIR *mir) +{ /* bound substitution heuristic */ + int m = mir->m; + int n = mir->n; + int j, k, kk; + double d1, d2; + for (j = 1; j <= mir->agg_vec->nnz; j++) + { k = mir->agg_vec->ind[j]; + xassert(1 <= k && k <= m+n); + if (mir->isint[k]) continue; /* skip integer variable */ + /* compute distance from x[k] to its lower bound */ + kk = mir->vlb[k]; + if (kk == 0) + { if (mir->lb[k] == -DBL_MAX) + d1 = DBL_MAX; + else + d1 = mir->x[k] - mir->lb[k]; + } + else + { xassert(1 <= kk && kk <= m+n); + xassert(mir->isint[kk]); + xassert(mir->lb[k] != -DBL_MAX); + d1 = mir->x[k] - mir->lb[k] * mir->x[kk]; + } + /* compute distance from x[k] to its upper bound */ + kk = mir->vub[k]; + if (kk == 0) + { if (mir->vub[k] == +DBL_MAX) + d2 = DBL_MAX; + else + d2 = mir->ub[k] - mir->x[k]; + } + else + { xassert(1 <= kk && kk <= m+n); + xassert(mir->isint[kk]); + xassert(mir->ub[k] != +DBL_MAX); + d2 = mir->ub[k] * mir->x[kk] - mir->x[k]; + } + /* x[k] cannot be free */ + xassert(d1 != DBL_MAX || d2 != DBL_MAX); + /* choose the bound which is closer to x[k] */ + xassert(mir->subst[k] == '?'); + if (d1 <= d2) + mir->subst[k] = 'L'; + else + mir->subst[k] = 'U'; + } + return; +} + +static void build_mod_row(struct MIR *mir) +{ /* substitute bounds and build modified constraint */ + int m = mir->m; + int n = mir->n; + int j, jj, k, kk; + /* initially modified constraint is aggregated constraint */ + ios_copy_vec(mir->mod_vec, mir->agg_vec); + mir->mod_rhs = mir->agg_rhs; +#if _MIR_DEBUG + ios_check_vec(mir->mod_vec); +#endif + /* substitute bounds for continuous variables; note that due to + substitution of variable bounds additional terms may appear in + modified constraint */ + for (j = mir->mod_vec->nnz; j >= 1; j--) + { k = mir->mod_vec->ind[j]; + xassert(1 <= k && k <= m+n); + if (mir->isint[k]) continue; /* skip integer variable */ + if (mir->subst[k] == 'L') + { /* x[k] = (lower bound) + x'[k] */ + xassert(mir->lb[k] != -DBL_MAX); + kk = mir->vlb[k]; + if (kk == 0) + { /* x[k] = lb[k] + x'[k] */ + mir->mod_rhs -= mir->mod_vec->val[j] * mir->lb[k]; + } + else + { /* x[k] = lb[k] * x[kk] + x'[k] */ + xassert(mir->isint[kk]); + jj = mir->mod_vec->pos[kk]; + if (jj == 0) + { ios_set_vj(mir->mod_vec, kk, 1.0); + jj = mir->mod_vec->pos[kk]; + mir->mod_vec->val[jj] = 0.0; + } + mir->mod_vec->val[jj] += + mir->mod_vec->val[j] * mir->lb[k]; + } + } + else if (mir->subst[k] == 'U') + { /* x[k] = (upper bound) - x'[k] */ + xassert(mir->ub[k] != +DBL_MAX); + kk = mir->vub[k]; + if (kk == 0) + { /* x[k] = ub[k] - x'[k] */ + mir->mod_rhs -= mir->mod_vec->val[j] * mir->ub[k]; + } + else + { /* x[k] = ub[k] * x[kk] - x'[k] */ + xassert(mir->isint[kk]); + jj = mir->mod_vec->pos[kk]; + if (jj == 0) + { ios_set_vj(mir->mod_vec, kk, 1.0); + jj = mir->mod_vec->pos[kk]; + mir->mod_vec->val[jj] = 0.0; + } + mir->mod_vec->val[jj] += + mir->mod_vec->val[j] * mir->ub[k]; + } + mir->mod_vec->val[j] = - mir->mod_vec->val[j]; + } + else + xassert(k != k); + } +#if _MIR_DEBUG + ios_check_vec(mir->mod_vec); +#endif + /* substitute bounds for integer variables */ + for (j = 1; j <= mir->mod_vec->nnz; j++) + { k = mir->mod_vec->ind[j]; + xassert(1 <= k && k <= m+n); + if (!mir->isint[k]) continue; /* skip continuous variable */ + xassert(mir->subst[k] == '?'); + xassert(mir->vlb[k] == 0 && mir->vub[k] == 0); + xassert(mir->lb[k] != -DBL_MAX && mir->ub[k] != +DBL_MAX); + if (fabs(mir->lb[k]) <= fabs(mir->ub[k])) + { /* x[k] = lb[k] + x'[k] */ + mir->subst[k] = 'L'; + mir->mod_rhs -= mir->mod_vec->val[j] * mir->lb[k]; + } + else + { /* x[k] = ub[k] - x'[k] */ + mir->subst[k] = 'U'; + mir->mod_rhs -= mir->mod_vec->val[j] * mir->ub[k]; + mir->mod_vec->val[j] = - mir->mod_vec->val[j]; + } + } +#if _MIR_DEBUG + ios_check_vec(mir->mod_vec); +#endif + return; +} + +#if _MIR_DEBUG +static void check_mod_row(struct MIR *mir) +{ /* check modified constraint */ + int m = mir->m; + int n = mir->n; + int j, k, kk; + double r, big, x; + /* compute the residual r = sum a'[k] * x'[k] - b' and determine + big = max(1, |a[k]|, |b|) */ + r = 0.0, big = 1.0; + for (j = 1; j <= mir->mod_vec->nnz; j++) + { k = mir->mod_vec->ind[j]; + xassert(1 <= k && k <= m+n); + if (mir->subst[k] == 'L') + { /* x'[k] = x[k] - (lower bound) */ + xassert(mir->lb[k] != -DBL_MAX); + kk = mir->vlb[k]; + if (kk == 0) + x = mir->x[k] - mir->lb[k]; + else + x = mir->x[k] - mir->lb[k] * mir->x[kk]; + } + else if (mir->subst[k] == 'U') + { /* x'[k] = (upper bound) - x[k] */ + xassert(mir->ub[k] != +DBL_MAX); + kk = mir->vub[k]; + if (kk == 0) + x = mir->ub[k] - mir->x[k]; + else + x = mir->ub[k] * mir->x[kk] - mir->x[k]; + } + else + xassert(k != k); + r += mir->mod_vec->val[j] * x; + if (big < fabs(mir->mod_vec->val[j])) + big = fabs(mir->mod_vec->val[j]); + } + r -= mir->mod_rhs; + if (big < fabs(mir->mod_rhs)) + big = fabs(mir->mod_rhs); + /* the residual must be close to zero */ + xassert(fabs(r) <= 1e-6 * big); + return; +} +#endif + +/*********************************************************************** +* mir_ineq - construct MIR inequality +* +* Given the single constraint mixed integer set +* +* |N| +* X = {(x,s) in Z x R : sum a[j] * x[j] <= b + s}, +* + + j in N +* +* this routine constructs the mixed integer rounding (MIR) inequality +* +* sum alpha[j] * x[j] <= beta + gamma * s, +* j in N +* +* which is valid for X. +* +* If the MIR inequality has been successfully constructed, the routine +* returns zero. Otherwise, if b is close to nearest integer, there may +* be numeric difficulties due to big coefficients; so in this case the +* routine returns non-zero. */ + +static int mir_ineq(const int n, const double a[], const double b, + double alpha[], double *beta, double *gamma) +{ int j; + double f, t; + if (fabs(b - floor(b + .5)) < 0.01) + return 1; + f = b - floor(b); + for (j = 1; j <= n; j++) + { t = (a[j] - floor(a[j])) - f; + if (t <= 0.0) + alpha[j] = floor(a[j]); + else + alpha[j] = floor(a[j]) + t / (1.0 - f); + } + *beta = floor(b); + *gamma = 1.0 / (1.0 - f); + return 0; +} + +/*********************************************************************** +* cmir_ineq - construct c-MIR inequality +* +* Given the mixed knapsack set +* +* MK |N| +* X = {(x,s) in Z x R : sum a[j] * x[j] <= b + s, +* + + j in N +* +* x[j] <= u[j]}, +* +* a subset C of variables to be complemented, and a divisor delta > 0, +* this routine constructs the complemented MIR (c-MIR) inequality +* +* sum alpha[j] * x[j] <= beta + gamma * s, +* j in N +* MK +* which is valid for X . +* +* If the c-MIR inequality has been successfully constructed, the +* routine returns zero. Otherwise, if there is a risk of numerical +* difficulties due to big coefficients (see comments to the routine +* mir_ineq), the routine cmir_ineq returns non-zero. */ + +static int cmir_ineq(const int n, const double a[], const double b, + const double u[], const char cset[], const double delta, + double alpha[], double *beta, double *gamma) +{ int j; + double *aa, bb; + aa = alpha, bb = b; + for (j = 1; j <= n; j++) + { aa[j] = a[j] / delta; + if (cset[j]) + aa[j] = - aa[j], bb -= a[j] * u[j]; + } + bb /= delta; + if (mir_ineq(n, aa, bb, alpha, beta, gamma)) return 1; + for (j = 1; j <= n; j++) + { if (cset[j]) + alpha[j] = - alpha[j], *beta += alpha[j] * u[j]; + } + *gamma /= delta; + return 0; +} + +/*********************************************************************** +* cmir_sep - c-MIR separation heuristic +* +* Given the mixed knapsack set +* +* MK |N| +* X = {(x,s) in Z x R : sum a[j] * x[j] <= b + s, +* + + j in N +* +* x[j] <= u[j]} +* +* * * +* and a fractional point (x , s ), this routine tries to construct +* c-MIR inequality +* +* sum alpha[j] * x[j] <= beta + gamma * s, +* j in N +* MK +* which is valid for X and has (desirably maximal) violation at the +* fractional point given. This is attained by choosing an appropriate +* set C of variables to be complemented and a divisor delta > 0, which +* together define corresponding c-MIR inequality. +* +* If a violated c-MIR inequality has been successfully constructed, +* the routine returns its violation: +* +* * * +* sum alpha[j] * x [j] - beta - gamma * s , +* j in N +* +* which is positive. In case of failure the routine returns zero. */ + +struct vset { int j; double v; }; + +static int cmir_cmp(const void *p1, const void *p2) +{ const struct vset *v1 = p1, *v2 = p2; + if (v1->v < v2->v) return -1; + if (v1->v > v2->v) return +1; + return 0; +} + +static double cmir_sep(const int n, const double a[], const double b, + const double u[], const double x[], const double s, + double alpha[], double *beta, double *gamma) +{ int fail, j, k, nv, v; + double delta, eps, d_try[1+3], r, r_best; + char *cset; + struct vset *vset; + /* allocate working arrays */ + cset = xcalloc(1+n, sizeof(char)); + vset = xcalloc(1+n, sizeof(struct vset)); + /* choose initial C */ + for (j = 1; j <= n; j++) + cset[j] = (char)(x[j] >= 0.5 * u[j]); + /* choose initial delta */ + r_best = delta = 0.0; + for (j = 1; j <= n; j++) + { xassert(a[j] != 0.0); + /* if x[j] is close to its bounds, skip it */ + eps = 1e-9 * (1.0 + fabs(u[j])); + if (x[j] < eps || x[j] > u[j] - eps) continue; + /* try delta = |a[j]| to construct c-MIR inequality */ + fail = cmir_ineq(n, a, b, u, cset, fabs(a[j]), alpha, beta, + gamma); + if (fail) continue; + /* compute violation */ + r = - (*beta) - (*gamma) * s; + for (k = 1; k <= n; k++) r += alpha[k] * x[k]; + if (r_best < r) r_best = r, delta = fabs(a[j]); + } + if (r_best < 0.001) r_best = 0.0; + if (r_best == 0.0) goto done; + xassert(delta > 0.0); + /* try to increase violation by dividing delta by 2, 4, and 8, + respectively */ + d_try[1] = delta / 2.0; + d_try[2] = delta / 4.0; + d_try[3] = delta / 8.0; + for (j = 1; j <= 3; j++) + { /* construct c-MIR inequality */ + fail = cmir_ineq(n, a, b, u, cset, d_try[j], alpha, beta, + gamma); + if (fail) continue; + /* compute violation */ + r = - (*beta) - (*gamma) * s; + for (k = 1; k <= n; k++) r += alpha[k] * x[k]; + if (r_best < r) r_best = r, delta = d_try[j]; + } + /* build subset of variables lying strictly between their bounds + and order it by nondecreasing values of |x[j] - u[j]/2| */ + nv = 0; + for (j = 1; j <= n; j++) + { /* if x[j] is close to its bounds, skip it */ + eps = 1e-9 * (1.0 + fabs(u[j])); + if (x[j] < eps || x[j] > u[j] - eps) continue; + /* add x[j] to the subset */ + nv++; + vset[nv].j = j; + vset[nv].v = fabs(x[j] - 0.5 * u[j]); + } + qsort(&vset[1], nv, sizeof(struct vset), cmir_cmp); + /* try to increase violation by successively complementing each + variable in the subset */ + for (v = 1; v <= nv; v++) + { j = vset[v].j; + /* replace x[j] by its complement or vice versa */ + cset[j] = (char)!cset[j]; + /* construct c-MIR inequality */ + fail = cmir_ineq(n, a, b, u, cset, delta, alpha, beta, gamma); + /* restore the variable */ + cset[j] = (char)!cset[j]; + /* do not replace the variable in case of failure */ + if (fail) continue; + /* compute violation */ + r = - (*beta) - (*gamma) * s; + for (k = 1; k <= n; k++) r += alpha[k] * x[k]; + if (r_best < r) r_best = r, cset[j] = (char)!cset[j]; + } + /* construct the best c-MIR inequality chosen */ + fail = cmir_ineq(n, a, b, u, cset, delta, alpha, beta, gamma); + xassert(!fail); +done: /* free working arrays */ + xfree(cset); + xfree(vset); + /* return to the calling routine */ + return r_best; +} + +static double generate(struct MIR *mir) +{ /* try to generate violated c-MIR cut for modified constraint */ + int m = mir->m; + int n = mir->n; + int j, k, kk, nint; + double s, *u, *x, *alpha, r_best = 0.0, b, beta, gamma; + ios_copy_vec(mir->cut_vec, mir->mod_vec); + mir->cut_rhs = mir->mod_rhs; + /* remove small terms, which can appear due to substitution of + variable bounds */ + ios_clean_vec(mir->cut_vec, DBL_EPSILON); +#if _MIR_DEBUG + ios_check_vec(mir->cut_vec); +#endif + /* remove positive continuous terms to obtain MK relaxation */ + for (j = 1; j <= mir->cut_vec->nnz; j++) + { k = mir->cut_vec->ind[j]; + xassert(1 <= k && k <= m+n); + if (!mir->isint[k] && mir->cut_vec->val[j] > 0.0) + mir->cut_vec->val[j] = 0.0; + } + ios_clean_vec(mir->cut_vec, 0.0); +#if _MIR_DEBUG + ios_check_vec(mir->cut_vec); +#endif + /* move integer terms to the beginning of the sparse vector and + determine the number of integer variables */ + nint = 0; + for (j = 1; j <= mir->cut_vec->nnz; j++) + { k = mir->cut_vec->ind[j]; + xassert(1 <= k && k <= m+n); + if (mir->isint[k]) + { double temp; + nint++; + /* interchange elements [nint] and [j] */ + kk = mir->cut_vec->ind[nint]; + mir->cut_vec->pos[k] = nint; + mir->cut_vec->pos[kk] = j; + mir->cut_vec->ind[nint] = k; + mir->cut_vec->ind[j] = kk; + temp = mir->cut_vec->val[nint]; + mir->cut_vec->val[nint] = mir->cut_vec->val[j]; + mir->cut_vec->val[j] = temp; + } + } +#if _MIR_DEBUG + ios_check_vec(mir->cut_vec); +#endif + /* if there is no integer variable, nothing to generate */ + if (nint == 0) goto done; + /* allocate working arrays */ + u = xcalloc(1+nint, sizeof(double)); + x = xcalloc(1+nint, sizeof(double)); + alpha = xcalloc(1+nint, sizeof(double)); + /* determine u and x */ + for (j = 1; j <= nint; j++) + { k = mir->cut_vec->ind[j]; + xassert(m+1 <= k && k <= m+n); + xassert(mir->isint[k]); + u[j] = mir->ub[k] - mir->lb[k]; + xassert(u[j] >= 1.0); + if (mir->subst[k] == 'L') + x[j] = mir->x[k] - mir->lb[k]; + else if (mir->subst[k] == 'U') + x[j] = mir->ub[k] - mir->x[k]; + else + xassert(k != k); + xassert(x[j] >= -0.001); + if (x[j] < 0.0) x[j] = 0.0; + } + /* compute s = - sum of continuous terms */ + s = 0.0; + for (j = nint+1; j <= mir->cut_vec->nnz; j++) + { double x; + k = mir->cut_vec->ind[j]; + xassert(1 <= k && k <= m+n); + /* must be continuous */ + xassert(!mir->isint[k]); + if (mir->subst[k] == 'L') + { xassert(mir->lb[k] != -DBL_MAX); + kk = mir->vlb[k]; + if (kk == 0) + x = mir->x[k] - mir->lb[k]; + else + x = mir->x[k] - mir->lb[k] * mir->x[kk]; + } + else if (mir->subst[k] == 'U') + { xassert(mir->ub[k] != +DBL_MAX); + kk = mir->vub[k]; + if (kk == 0) + x = mir->ub[k] - mir->x[k]; + else + x = mir->ub[k] * mir->x[kk] - mir->x[k]; + } + else + xassert(k != k); + xassert(x >= -0.001); + if (x < 0.0) x = 0.0; + s -= mir->cut_vec->val[j] * x; + } + xassert(s >= 0.0); + /* apply heuristic to obtain most violated c-MIR inequality */ + b = mir->cut_rhs; + r_best = cmir_sep(nint, mir->cut_vec->val, b, u, x, s, alpha, + &beta, &gamma); + if (r_best == 0.0) goto skip; + xassert(r_best > 0.0); + /* convert to raw cut */ + /* sum alpha[j] * x[j] <= beta + gamma * s */ + for (j = 1; j <= nint; j++) + mir->cut_vec->val[j] = alpha[j]; + for (j = nint+1; j <= mir->cut_vec->nnz; j++) + { k = mir->cut_vec->ind[j]; + if (k <= m+n) mir->cut_vec->val[j] *= gamma; + } + mir->cut_rhs = beta; +#if _MIR_DEBUG + ios_check_vec(mir->cut_vec); +#endif +skip: /* free working arrays */ + xfree(u); + xfree(x); + xfree(alpha); +done: return r_best; +} + +#if _MIR_DEBUG +static void check_raw_cut(struct MIR *mir, double r_best) +{ /* check raw cut before back bound substitution */ + int m = mir->m; + int n = mir->n; + int j, k, kk; + double r, big, x; + /* compute the residual r = sum a[k] * x[k] - b and determine + big = max(1, |a[k]|, |b|) */ + r = 0.0, big = 1.0; + for (j = 1; j <= mir->cut_vec->nnz; j++) + { k = mir->cut_vec->ind[j]; + xassert(1 <= k && k <= m+n); + if (mir->subst[k] == 'L') + { xassert(mir->lb[k] != -DBL_MAX); + kk = mir->vlb[k]; + if (kk == 0) + x = mir->x[k] - mir->lb[k]; + else + x = mir->x[k] - mir->lb[k] * mir->x[kk]; + } + else if (mir->subst[k] == 'U') + { xassert(mir->ub[k] != +DBL_MAX); + kk = mir->vub[k]; + if (kk == 0) + x = mir->ub[k] - mir->x[k]; + else + x = mir->ub[k] * mir->x[kk] - mir->x[k]; + } + else + xassert(k != k); + r += mir->cut_vec->val[j] * x; + if (big < fabs(mir->cut_vec->val[j])) + big = fabs(mir->cut_vec->val[j]); + } + r -= mir->cut_rhs; + if (big < fabs(mir->cut_rhs)) + big = fabs(mir->cut_rhs); + /* the residual must be close to r_best */ + xassert(fabs(r - r_best) <= 1e-6 * big); + return; +} +#endif + +static void back_subst(struct MIR *mir) +{ /* back substitution of original bounds */ + int m = mir->m; + int n = mir->n; + int j, jj, k, kk; + /* at first, restore bounds of integer variables (because on + restoring variable bounds of continuous variables we need + original, not shifted, bounds of integer variables) */ + for (j = 1; j <= mir->cut_vec->nnz; j++) + { k = mir->cut_vec->ind[j]; + xassert(1 <= k && k <= m+n); + if (!mir->isint[k]) continue; /* skip continuous */ + if (mir->subst[k] == 'L') + { /* x'[k] = x[k] - lb[k] */ + xassert(mir->lb[k] != -DBL_MAX); + xassert(mir->vlb[k] == 0); + mir->cut_rhs += mir->cut_vec->val[j] * mir->lb[k]; + } + else if (mir->subst[k] == 'U') + { /* x'[k] = ub[k] - x[k] */ + xassert(mir->ub[k] != +DBL_MAX); + xassert(mir->vub[k] == 0); + mir->cut_rhs -= mir->cut_vec->val[j] * mir->ub[k]; + mir->cut_vec->val[j] = - mir->cut_vec->val[j]; + } + else + xassert(k != k); + } + /* now restore bounds of continuous variables */ + for (j = 1; j <= mir->cut_vec->nnz; j++) + { k = mir->cut_vec->ind[j]; + xassert(1 <= k && k <= m+n); + if (mir->isint[k]) continue; /* skip integer */ + if (mir->subst[k] == 'L') + { /* x'[k] = x[k] - (lower bound) */ + xassert(mir->lb[k] != -DBL_MAX); + kk = mir->vlb[k]; + if (kk == 0) + { /* x'[k] = x[k] - lb[k] */ + mir->cut_rhs += mir->cut_vec->val[j] * mir->lb[k]; + } + else + { /* x'[k] = x[k] - lb[k] * x[kk] */ + jj = mir->cut_vec->pos[kk]; +#if 0 + xassert(jj != 0); +#else + if (jj == 0) + { ios_set_vj(mir->cut_vec, kk, 1.0); + jj = mir->cut_vec->pos[kk]; + xassert(jj != 0); + mir->cut_vec->val[jj] = 0.0; + } +#endif + mir->cut_vec->val[jj] -= mir->cut_vec->val[j] * + mir->lb[k]; + } + } + else if (mir->subst[k] == 'U') + { /* x'[k] = (upper bound) - x[k] */ + xassert(mir->ub[k] != +DBL_MAX); + kk = mir->vub[k]; + if (kk == 0) + { /* x'[k] = ub[k] - x[k] */ + mir->cut_rhs -= mir->cut_vec->val[j] * mir->ub[k]; + } + else + { /* x'[k] = ub[k] * x[kk] - x[k] */ + jj = mir->cut_vec->pos[kk]; + if (jj == 0) + { ios_set_vj(mir->cut_vec, kk, 1.0); + jj = mir->cut_vec->pos[kk]; + xassert(jj != 0); + mir->cut_vec->val[jj] = 0.0; + } + mir->cut_vec->val[jj] += mir->cut_vec->val[j] * + mir->ub[k]; + } + mir->cut_vec->val[j] = - mir->cut_vec->val[j]; + } + else + xassert(k != k); + } +#if _MIR_DEBUG + ios_check_vec(mir->cut_vec); +#endif + return; +} + +#if _MIR_DEBUG +static void check_cut_row(struct MIR *mir, double r_best) +{ /* check the cut after back bound substitution or elimination of + auxiliary variables */ + int m = mir->m; + int n = mir->n; + int j, k; + double r, big; + /* compute the residual r = sum a[k] * x[k] - b and determine + big = max(1, |a[k]|, |b|) */ + r = 0.0, big = 1.0; + for (j = 1; j <= mir->cut_vec->nnz; j++) + { k = mir->cut_vec->ind[j]; + xassert(1 <= k && k <= m+n); + r += mir->cut_vec->val[j] * mir->x[k]; + if (big < fabs(mir->cut_vec->val[j])) + big = fabs(mir->cut_vec->val[j]); + } + r -= mir->cut_rhs; + if (big < fabs(mir->cut_rhs)) + big = fabs(mir->cut_rhs); + /* the residual must be close to r_best */ + xassert(fabs(r - r_best) <= 1e-6 * big); + return; +} +#endif + +static void subst_aux_vars(glp_tree *tree, struct MIR *mir) +{ /* final substitution to eliminate auxiliary variables */ + glp_prob *mip = tree->mip; + int m = mir->m; + int n = mir->n; + GLPAIJ *aij; + int j, k, kk, jj; + for (j = mir->cut_vec->nnz; j >= 1; j--) + { k = mir->cut_vec->ind[j]; + xassert(1 <= k && k <= m+n); + if (k > m) continue; /* skip structurals */ + for (aij = mip->row[k]->ptr; aij != NULL; aij = aij->r_next) + { kk = m + aij->col->j; /* structural */ + jj = mir->cut_vec->pos[kk]; + if (jj == 0) + { ios_set_vj(mir->cut_vec, kk, 1.0); + jj = mir->cut_vec->pos[kk]; + mir->cut_vec->val[jj] = 0.0; + } + mir->cut_vec->val[jj] += mir->cut_vec->val[j] * aij->val; + } + mir->cut_vec->val[j] = 0.0; + } + ios_clean_vec(mir->cut_vec, 0.0); + return; +} + +static void add_cut(glp_tree *tree, struct MIR *mir) +{ /* add constructed cut inequality to the cut pool */ + int m = mir->m; + int n = mir->n; + int j, k, len; + int *ind = xcalloc(1+n, sizeof(int)); + double *val = xcalloc(1+n, sizeof(double)); + len = 0; + for (j = mir->cut_vec->nnz; j >= 1; j--) + { k = mir->cut_vec->ind[j]; + xassert(m+1 <= k && k <= m+n); + len++, ind[len] = k - m, val[len] = mir->cut_vec->val[j]; + } +#if 0 + ios_add_cut_row(tree, pool, GLP_RF_MIR, len, ind, val, GLP_UP, + mir->cut_rhs); +#else + glp_ios_add_row(tree, NULL, GLP_RF_MIR, 0, len, ind, val, GLP_UP, + mir->cut_rhs); +#endif + xfree(ind); + xfree(val); + return; +} + +static int aggregate_row(glp_tree *tree, struct MIR *mir) +{ /* try to aggregate another row */ + glp_prob *mip = tree->mip; + int m = mir->m; + int n = mir->n; + GLPAIJ *aij; + IOSVEC *v; + int ii, j, jj, k, kk, kappa = 0, ret = 0; + double d1, d2, d, d_max = 0.0; + /* choose appropriate structural variable in the aggregated row + to be substituted */ + for (j = 1; j <= mir->agg_vec->nnz; j++) + { k = mir->agg_vec->ind[j]; + xassert(1 <= k && k <= m+n); + if (k <= m) continue; /* skip auxiliary var */ + if (mir->isint[k]) continue; /* skip integer var */ + if (fabs(mir->agg_vec->val[j]) < 0.001) continue; + /* compute distance from x[k] to its lower bound */ + kk = mir->vlb[k]; + if (kk == 0) + { if (mir->lb[k] == -DBL_MAX) + d1 = DBL_MAX; + else + d1 = mir->x[k] - mir->lb[k]; + } + else + { xassert(1 <= kk && kk <= m+n); + xassert(mir->isint[kk]); + xassert(mir->lb[k] != -DBL_MAX); + d1 = mir->x[k] - mir->lb[k] * mir->x[kk]; + } + /* compute distance from x[k] to its upper bound */ + kk = mir->vub[k]; + if (kk == 0) + { if (mir->vub[k] == +DBL_MAX) + d2 = DBL_MAX; + else + d2 = mir->ub[k] - mir->x[k]; + } + else + { xassert(1 <= kk && kk <= m+n); + xassert(mir->isint[kk]); + xassert(mir->ub[k] != +DBL_MAX); + d2 = mir->ub[k] * mir->x[kk] - mir->x[k]; + } + /* x[k] cannot be free */ + xassert(d1 != DBL_MAX || d2 != DBL_MAX); + /* d = min(d1, d2) */ + d = (d1 <= d2 ? d1 : d2); + xassert(d != DBL_MAX); + /* should not be close to corresponding bound */ + if (d < 0.001) continue; + if (d_max < d) d_max = d, kappa = k; + } + if (kappa == 0) + { /* nothing chosen */ + ret = 1; + goto done; + } + /* x[kappa] has been chosen */ + xassert(m+1 <= kappa && kappa <= m+n); + xassert(!mir->isint[kappa]); + /* find another row, which have not been used yet, to eliminate + x[kappa] from the aggregated row */ + for (ii = 1; ii <= m; ii++) + { if (mir->skip[ii]) continue; + for (aij = mip->row[ii]->ptr; aij != NULL; aij = aij->r_next) + if (aij->col->j == kappa - m) break; + if (aij != NULL && fabs(aij->val) >= 0.001) break; + } + if (ii > m) + { /* nothing found */ + ret = 2; + goto done; + } + /* row ii has been found; include it in the aggregated list */ + mir->agg_cnt++; + xassert(mir->agg_cnt <= MAXAGGR); + mir->agg_row[mir->agg_cnt] = ii; + mir->skip[ii] = 2; + /* v := new row */ + v = ios_create_vec(m+n); + ios_set_vj(v, ii, 1.0); + for (aij = mip->row[ii]->ptr; aij != NULL; aij = aij->r_next) + ios_set_vj(v, m + aij->col->j, - aij->val); +#if _MIR_DEBUG + ios_check_vec(v); +#endif + /* perform gaussian elimination to remove x[kappa] */ + j = mir->agg_vec->pos[kappa]; + xassert(j != 0); + jj = v->pos[kappa]; + xassert(jj != 0); + ios_linear_comb(mir->agg_vec, + - mir->agg_vec->val[j] / v->val[jj], v); + ios_delete_vec(v); + ios_set_vj(mir->agg_vec, kappa, 0.0); +#if _MIR_DEBUG + ios_check_vec(mir->agg_vec); +#endif +done: return ret; +} + +void ios_mir_gen(glp_tree *tree, void *gen) +{ /* main routine to generate MIR cuts */ + glp_prob *mip = tree->mip; + struct MIR *mir = gen; + int m = mir->m; + int n = mir->n; + int i; + double r_best; + xassert(mip->m >= m); + xassert(mip->n == n); + /* obtain current point */ + get_current_point(tree, mir); +#if _MIR_DEBUG + /* check current point */ + check_current_point(mir); +#endif + /* reset bound substitution flags */ + memset(&mir->subst[1], '?', m+n); + /* try to generate a set of violated MIR cuts */ + for (i = 1; i <= m; i++) + { if (mir->skip[i]) continue; + /* use original i-th row as initial aggregated constraint */ + initial_agg_row(tree, mir, i); +loop: ; +#if _MIR_DEBUG + /* check aggregated row */ + check_agg_row(mir); +#endif + /* substitute fixed variables into aggregated constraint */ + subst_fixed_vars(mir); +#if _MIR_DEBUG + /* check aggregated row */ + check_agg_row(mir); +#endif +#if _MIR_DEBUG + /* check bound substitution flags */ + { int k; + for (k = 1; k <= m+n; k++) + xassert(mir->subst[k] == '?'); + } +#endif + /* apply bound substitution heuristic */ + bound_subst_heur(mir); + /* substitute bounds and build modified constraint */ + build_mod_row(mir); +#if _MIR_DEBUG + /* check modified row */ + check_mod_row(mir); +#endif + /* try to generate violated c-MIR cut for modified row */ + r_best = generate(mir); + if (r_best > 0.0) + { /* success */ +#if _MIR_DEBUG + /* check raw cut before back bound substitution */ + check_raw_cut(mir, r_best); +#endif + /* back substitution of original bounds */ + back_subst(mir); +#if _MIR_DEBUG + /* check the cut after back bound substitution */ + check_cut_row(mir, r_best); +#endif + /* final substitution to eliminate auxiliary variables */ + subst_aux_vars(tree, mir); +#if _MIR_DEBUG + /* check the cut after elimination of auxiliaries */ + check_cut_row(mir, r_best); +#endif + /* add constructed cut inequality to the cut pool */ + add_cut(tree, mir); + } + /* reset bound substitution flags */ + { int j, k; + for (j = 1; j <= mir->mod_vec->nnz; j++) + { k = mir->mod_vec->ind[j]; + xassert(1 <= k && k <= m+n); + xassert(mir->subst[k] != '?'); + mir->subst[k] = '?'; + } + } + if (r_best == 0.0) + { /* failure */ + if (mir->agg_cnt < MAXAGGR) + { /* try to aggregate another row */ + if (aggregate_row(tree, mir) == 0) goto loop; + } + } + /* unmark rows used in the aggregated constraint */ + { int k, ii; + for (k = 1; k <= mir->agg_cnt; k++) + { ii = mir->agg_row[k]; + xassert(1 <= ii && ii <= m); + xassert(mir->skip[ii] == 2); + mir->skip[ii] = 0; + } + } + } + return; +} + +/*********************************************************************** +* NAME +* +* ios_mir_term - terminate MIR cut generator +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_mir_term(void *gen); +* +* DESCRIPTION +* +* The routine ios_mir_term deletes the MIR cut generator working area +* freeing all the memory allocated to it. */ + +void ios_mir_term(void *gen) +{ struct MIR *mir = gen; + xfree(mir->skip); + xfree(mir->isint); + xfree(mir->lb); + xfree(mir->vlb); + xfree(mir->ub); + xfree(mir->vub); + xfree(mir->x); + xfree(mir->agg_row); + ios_delete_vec(mir->agg_vec); + xfree(mir->subst); + ios_delete_vec(mir->mod_vec); + ios_delete_vec(mir->cut_vec); + xfree(mir); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpios07.c b/resources/3rdparty/glpk-4.57/src/glpios07.c new file mode 100644 index 000000000..3ea515b67 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpios07.c @@ -0,0 +1,551 @@ +/* glpios07.c (mixed cover cut generator) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpios.h" + +/*---------------------------------------------------------------------- +-- COVER INEQUALITIES +-- +-- Consider the set of feasible solutions to 0-1 knapsack problem: +-- +-- sum a[j]*x[j] <= b, (1) +-- j in J +-- +-- x[j] is binary, (2) +-- +-- where, wlog, we assume that a[j] > 0 (since 0-1 variables can be +-- complemented) and a[j] <= b (since a[j] > b implies x[j] = 0). +-- +-- A set C within J is called a cover if +-- +-- sum a[j] > b. (3) +-- j in C +-- +-- For any cover C the inequality +-- +-- sum x[j] <= |C| - 1 (4) +-- j in C +-- +-- is called a cover inequality and is valid for (1)-(2). +-- +-- MIXED COVER INEQUALITIES +-- +-- Consider the set of feasible solutions to mixed knapsack problem: +-- +-- sum a[j]*x[j] + y <= b, (5) +-- j in J +-- +-- x[j] is binary, (6) +-- +-- 0 <= y <= u is continuous, (7) +-- +-- where again we assume that a[j] > 0. +-- +-- Let C within J be some set. From (1)-(4) it follows that +-- +-- sum a[j] > b - y (8) +-- j in C +-- +-- implies +-- +-- sum x[j] <= |C| - 1. (9) +-- j in C +-- +-- Thus, we need to modify the inequality (9) in such a way that it be +-- a constraint only if the condition (8) is satisfied. +-- +-- Consider the following inequality: +-- +-- sum x[j] <= |C| - t. (10) +-- j in C +-- +-- If 0 < t <= 1, then (10) is equivalent to (9), because all x[j] are +-- binary variables. On the other hand, if t <= 0, (10) being satisfied +-- for any values of x[j] is not a constraint. +-- +-- Let +-- +-- t' = sum a[j] + y - b. (11) +-- j in C +-- +-- It is understood that the condition t' > 0 is equivalent to (8). +-- Besides, from (6)-(7) it follows that t' has an implied upper bound: +-- +-- t'max = sum a[j] + u - b. (12) +-- j in C +-- +-- This allows to express the parameter t having desired properties: +-- +-- t = t' / t'max. (13) +-- +-- In fact, t <= 1 by definition, and t > 0 being equivalent to t' > 0 +-- is equivalent to (8). +-- +-- Thus, the inequality (10), where t is given by formula (13) is valid +-- for (5)-(7). +-- +-- Note that if u = 0, then y = 0, so t = 1, and the conditions (8) and +-- (10) is transformed to the conditions (3) and (4). +-- +-- GENERATING MIXED COVER CUTS +-- +-- To generate a mixed cover cut in the form (10) we need to find such +-- set C which satisfies to the inequality (8) and for which, in turn, +-- the inequality (10) is violated in the current point. +-- +-- Substituting t from (13) to (10) gives: +-- +-- 1 +-- sum x[j] <= |C| - ----- (sum a[j] + y - b), (14) +-- j in C t'max j in C +-- +-- and finally we have the cut inequality in the standard form: +-- +-- sum x[j] + alfa * y <= beta, (15) +-- j in C +-- +-- where: +-- +-- alfa = 1 / t'max, (16) +-- +-- beta = |C| - alfa * (sum a[j] - b). (17) +-- j in C */ + +#if 1 +#define MAXTRY 1000 +#else +#define MAXTRY 10000 +#endif + +static int cover2(int n, double a[], double b, double u, double x[], + double y, int cov[], double *_alfa, double *_beta) +{ /* try to generate mixed cover cut using two-element cover */ + int i, j, try = 0, ret = 0; + double eps, alfa, beta, temp, rmax = 0.001; + eps = 0.001 * (1.0 + fabs(b)); + for (i = 0+1; i <= n; i++) + for (j = i+1; j <= n; j++) + { /* C = {i, j} */ + try++; + if (try > MAXTRY) goto done; + /* check if condition (8) is satisfied */ + if (a[i] + a[j] + y > b + eps) + { /* compute parameters for inequality (15) */ + temp = a[i] + a[j] - b; + alfa = 1.0 / (temp + u); + beta = 2.0 - alfa * temp; + /* compute violation of inequality (15) */ + temp = x[i] + x[j] + alfa * y - beta; + /* choose C providing maximum violation */ + if (rmax < temp) + { rmax = temp; + cov[1] = i; + cov[2] = j; + *_alfa = alfa; + *_beta = beta; + ret = 1; + } + } + } +done: return ret; +} + +static int cover3(int n, double a[], double b, double u, double x[], + double y, int cov[], double *_alfa, double *_beta) +{ /* try to generate mixed cover cut using three-element cover */ + int i, j, k, try = 0, ret = 0; + double eps, alfa, beta, temp, rmax = 0.001; + eps = 0.001 * (1.0 + fabs(b)); + for (i = 0+1; i <= n; i++) + for (j = i+1; j <= n; j++) + for (k = j+1; k <= n; k++) + { /* C = {i, j, k} */ + try++; + if (try > MAXTRY) goto done; + /* check if condition (8) is satisfied */ + if (a[i] + a[j] + a[k] + y > b + eps) + { /* compute parameters for inequality (15) */ + temp = a[i] + a[j] + a[k] - b; + alfa = 1.0 / (temp + u); + beta = 3.0 - alfa * temp; + /* compute violation of inequality (15) */ + temp = x[i] + x[j] + x[k] + alfa * y - beta; + /* choose C providing maximum violation */ + if (rmax < temp) + { rmax = temp; + cov[1] = i; + cov[2] = j; + cov[3] = k; + *_alfa = alfa; + *_beta = beta; + ret = 1; + } + } + } +done: return ret; +} + +static int cover4(int n, double a[], double b, double u, double x[], + double y, int cov[], double *_alfa, double *_beta) +{ /* try to generate mixed cover cut using four-element cover */ + int i, j, k, l, try = 0, ret = 0; + double eps, alfa, beta, temp, rmax = 0.001; + eps = 0.001 * (1.0 + fabs(b)); + for (i = 0+1; i <= n; i++) + for (j = i+1; j <= n; j++) + for (k = j+1; k <= n; k++) + for (l = k+1; l <= n; l++) + { /* C = {i, j, k, l} */ + try++; + if (try > MAXTRY) goto done; + /* check if condition (8) is satisfied */ + if (a[i] + a[j] + a[k] + a[l] + y > b + eps) + { /* compute parameters for inequality (15) */ + temp = a[i] + a[j] + a[k] + a[l] - b; + alfa = 1.0 / (temp + u); + beta = 4.0 - alfa * temp; + /* compute violation of inequality (15) */ + temp = x[i] + x[j] + x[k] + x[l] + alfa * y - beta; + /* choose C providing maximum violation */ + if (rmax < temp) + { rmax = temp; + cov[1] = i; + cov[2] = j; + cov[3] = k; + cov[4] = l; + *_alfa = alfa; + *_beta = beta; + ret = 1; + } + } + } +done: return ret; +} + +static int cover(int n, double a[], double b, double u, double x[], + double y, int cov[], double *alfa, double *beta) +{ /* try to generate mixed cover cut; + input (see (5)): + n is the number of binary variables; + a[1:n] are coefficients at binary variables; + b is the right-hand side; + u is upper bound of continuous variable; + x[1:n] are values of binary variables at current point; + y is value of continuous variable at current point; + output (see (15), (16), (17)): + cov[1:r] are indices of binary variables included in cover C, + where r is the set cardinality returned on exit; + alfa coefficient at continuous variable; + beta is the right-hand side; */ + int j; + /* perform some sanity checks */ + xassert(n >= 2); + for (j = 1; j <= n; j++) xassert(a[j] > 0.0); +#if 1 /* ??? */ + xassert(b > -1e-5); +#else + xassert(b > 0.0); +#endif + xassert(u >= 0.0); + for (j = 1; j <= n; j++) xassert(0.0 <= x[j] && x[j] <= 1.0); + xassert(0.0 <= y && y <= u); + /* try to generate mixed cover cut */ + if (cover2(n, a, b, u, x, y, cov, alfa, beta)) return 2; + if (cover3(n, a, b, u, x, y, cov, alfa, beta)) return 3; + if (cover4(n, a, b, u, x, y, cov, alfa, beta)) return 4; + return 0; +} + +/*---------------------------------------------------------------------- +-- lpx_cover_cut - generate mixed cover cut. +-- +-- SYNOPSIS +-- +-- int lpx_cover_cut(LPX *lp, int len, int ind[], double val[], +-- double work[]); +-- +-- DESCRIPTION +-- +-- The routine lpx_cover_cut generates a mixed cover cut for a given +-- row of the MIP problem. +-- +-- The given row of the MIP problem should be explicitly specified in +-- the form: +-- +-- sum{j in J} a[j]*x[j] <= b. (1) +-- +-- On entry indices (ordinal numbers) of structural variables, which +-- have non-zero constraint coefficients, should be placed in locations +-- ind[1], ..., ind[len], and corresponding constraint coefficients +-- should be placed in locations val[1], ..., val[len]. The right-hand +-- side b should be stored in location val[0]. +-- +-- The working array work should have at least nb locations, where nb +-- is the number of binary variables in (1). +-- +-- The routine generates a mixed cover cut in the same form as (1) and +-- stores the cut coefficients and right-hand side in the same way as +-- just described above. +-- +-- RETURNS +-- +-- If the cutting plane has been successfully generated, the routine +-- returns 1 <= len' <= n, which is the number of non-zero coefficients +-- in the inequality constraint. Otherwise, the routine returns zero. */ + +static int lpx_cover_cut(glp_prob *lp, int len, int ind[], + double val[], double work[]) +{ int cov[1+4], j, k, nb, newlen, r; + double f_min, f_max, alfa, beta, u, *x = work, y; + /* substitute and remove fixed variables */ + newlen = 0; + for (k = 1; k <= len; k++) + { j = ind[k]; + if (glp_get_col_type(lp, j) == GLP_FX) + val[0] -= val[k] * glp_get_col_lb(lp, j); + else + { newlen++; + ind[newlen] = ind[k]; + val[newlen] = val[k]; + } + } + len = newlen; + /* move binary variables to the beginning of the list so that + elements 1, 2, ..., nb correspond to binary variables, and + elements nb+1, nb+2, ..., len correspond to rest variables */ + nb = 0; + for (k = 1; k <= len; k++) + { j = ind[k]; + if (glp_get_col_kind(lp, j) == GLP_BV) + { /* binary variable */ + int ind_k; + double val_k; + nb++; + ind_k = ind[nb], val_k = val[nb]; + ind[nb] = ind[k], val[nb] = val[k]; + ind[k] = ind_k, val[k] = val_k; + } + } + /* now the specified row has the form: + sum a[j]*x[j] + sum a[j]*y[j] <= b, + where x[j] are binary variables, y[j] are rest variables */ + /* at least two binary variables are needed */ + if (nb < 2) return 0; + /* compute implied lower and upper bounds for sum a[j]*y[j] */ + f_min = f_max = 0.0; + for (k = nb+1; k <= len; k++) + { j = ind[k]; + /* both bounds must be finite */ + if (glp_get_col_type(lp, j) != GLP_DB) return 0; + if (val[k] > 0.0) + { f_min += val[k] * glp_get_col_lb(lp, j); + f_max += val[k] * glp_get_col_ub(lp, j); + } + else + { f_min += val[k] * glp_get_col_ub(lp, j); + f_max += val[k] * glp_get_col_lb(lp, j); + } + } + /* sum a[j]*x[j] + sum a[j]*y[j] <= b ===> + sum a[j]*x[j] + (sum a[j]*y[j] - f_min) <= b - f_min ===> + sum a[j]*x[j] + y <= b - f_min, + where y = sum a[j]*y[j] - f_min; + note that 0 <= y <= u, u = f_max - f_min */ + /* determine upper bound of y */ + u = f_max - f_min; + /* determine value of y at the current point */ + y = 0.0; + for (k = nb+1; k <= len; k++) + { j = ind[k]; + y += val[k] * glp_get_col_prim(lp, j); + } + y -= f_min; + if (y < 0.0) y = 0.0; + if (y > u) y = u; + /* modify the right-hand side b */ + val[0] -= f_min; + /* now the transformed row has the form: + sum a[j]*x[j] + y <= b, where 0 <= y <= u */ + /* determine values of x[j] at the current point */ + for (k = 1; k <= nb; k++) + { j = ind[k]; + x[k] = glp_get_col_prim(lp, j); + if (x[k] < 0.0) x[k] = 0.0; + if (x[k] > 1.0) x[k] = 1.0; + } + /* if a[j] < 0, replace x[j] by its complement 1 - x'[j] */ + for (k = 1; k <= nb; k++) + { if (val[k] < 0.0) + { ind[k] = - ind[k]; + val[k] = - val[k]; + val[0] += val[k]; + x[k] = 1.0 - x[k]; + } + } + /* try to generate a mixed cover cut for the transformed row */ + r = cover(nb, val, val[0], u, x, y, cov, &alfa, &beta); + if (r == 0) return 0; + xassert(2 <= r && r <= 4); + /* now the cut is in the form: + sum{j in C} x[j] + alfa * y <= beta */ + /* store the right-hand side beta */ + ind[0] = 0, val[0] = beta; + /* restore the original ordinal numbers of x[j] */ + for (j = 1; j <= r; j++) cov[j] = ind[cov[j]]; + /* store cut coefficients at binary variables complementing back + the variables having negative row coefficients */ + xassert(r <= nb); + for (k = 1; k <= r; k++) + { if (cov[k] > 0) + { ind[k] = +cov[k]; + val[k] = +1.0; + } + else + { ind[k] = -cov[k]; + val[k] = -1.0; + val[0] -= 1.0; + } + } + /* substitute y = sum a[j]*y[j] - f_min */ + for (k = nb+1; k <= len; k++) + { r++; + ind[r] = ind[k]; + val[r] = alfa * val[k]; + } + val[0] += alfa * f_min; + xassert(r <= len); + len = r; + return len; +} + +/*---------------------------------------------------------------------- +-- lpx_eval_row - compute explictily specified row. +-- +-- SYNOPSIS +-- +-- double lpx_eval_row(LPX *lp, int len, int ind[], double val[]); +-- +-- DESCRIPTION +-- +-- The routine lpx_eval_row computes the primal value of an explicitly +-- specified row using current values of structural variables. +-- +-- The explicitly specified row may be thought as a linear form: +-- +-- y = a[1]*x[m+1] + a[2]*x[m+2] + ... + a[n]*x[m+n], +-- +-- where y is an auxiliary variable for this row, a[j] are coefficients +-- of the linear form, x[m+j] are structural variables. +-- +-- On entry column indices and numerical values of non-zero elements of +-- the row should be stored in locations ind[1], ..., ind[len] and +-- val[1], ..., val[len], where len is the number of non-zero elements. +-- The array ind and val are not changed on exit. +-- +-- RETURNS +-- +-- The routine returns a computed value of y, the auxiliary variable of +-- the specified row. */ + +static double lpx_eval_row(glp_prob *lp, int len, int ind[], + double val[]) +{ int n = glp_get_num_cols(lp); + int j, k; + double sum = 0.0; + if (len < 0) + xerror("lpx_eval_row: len = %d; invalid row length\n", len); + for (k = 1; k <= len; k++) + { j = ind[k]; + if (!(1 <= j && j <= n)) + xerror("lpx_eval_row: j = %d; column number out of range\n", + j); + sum += val[k] * glp_get_col_prim(lp, j); + } + return sum; +} + +/*********************************************************************** +* NAME +* +* ios_cov_gen - generate mixed cover cuts +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_cov_gen(glp_tree *tree); +* +* DESCRIPTION +* +* The routine ios_cov_gen generates mixed cover cuts for the current +* point and adds them to the cut pool. */ + +void ios_cov_gen(glp_tree *tree) +{ glp_prob *prob = tree->mip; + int m = glp_get_num_rows(prob); + int n = glp_get_num_cols(prob); + int i, k, type, kase, len, *ind; + double r, *val, *work; + xassert(glp_get_status(prob) == GLP_OPT); + /* allocate working arrays */ + ind = xcalloc(1+n, sizeof(int)); + val = xcalloc(1+n, sizeof(double)); + work = xcalloc(1+n, sizeof(double)); + /* look through all rows */ + for (i = 1; i <= m; i++) + for (kase = 1; kase <= 2; kase++) + { type = glp_get_row_type(prob, i); + if (kase == 1) + { /* consider rows of '<=' type */ + if (!(type == GLP_UP || type == GLP_DB)) continue; + len = glp_get_mat_row(prob, i, ind, val); + val[0] = glp_get_row_ub(prob, i); + } + else + { /* consider rows of '>=' type */ + if (!(type == GLP_LO || type == GLP_DB)) continue; + len = glp_get_mat_row(prob, i, ind, val); + for (k = 1; k <= len; k++) val[k] = - val[k]; + val[0] = - glp_get_row_lb(prob, i); + } + /* generate mixed cover cut: + sum{j in J} a[j] * x[j] <= b */ + len = lpx_cover_cut(prob, len, ind, val, work); + if (len == 0) continue; + /* at the current point the cut inequality is violated, i.e. + sum{j in J} a[j] * x[j] - b > 0 */ + r = lpx_eval_row(prob, len, ind, val) - val[0]; + if (r < 1e-3) continue; + /* add the cut to the cut pool */ + glp_ios_add_row(tree, NULL, GLP_RF_COV, 0, len, ind, val, + GLP_UP, val[0]); + } + /* free working arrays */ + xfree(ind); + xfree(val); + xfree(work); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpios08.c b/resources/3rdparty/glpk-4.57/src/glpios08.c new file mode 100644 index 000000000..d165492f7 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpios08.c @@ -0,0 +1,147 @@ +/* glpios08.c (clique cut generator) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2008, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "cfg.h" +#include "env.h" +#include "glpios.h" + +void *ios_clq_init(glp_tree *T) +{ /* initialize clique cut generator */ + glp_prob *P = T->mip; + CFG *G; + int j, n1, n2; + xprintf("Constructing conflict graph...\n"); + G = cfg_build_graph(P); + n1 = n2 = 0; + for (j = 1; j <= P->n; j++) + { if (G->pos[j]) + n1 ++; + if (G->neg[j]) + n2++; + } + if (n1 == 0 && n2 == 0) + { xprintf("No conflicts found\n"); + cfg_delete_graph(G); + G = NULL; + } + else + xprintf("Conflict graph has %d + %d = %d vertices\n", + n1, n2, G->nv); + return G; +} + +void ios_clq_gen(glp_tree *T, void *G_) +{ /* attempt to generate clique cut */ + glp_prob *P = T->mip; + int n = P->n; + CFG *G = G_; + int *pos = G->pos; + int *neg = G->neg; + int nv = G->nv; + int *ref = G->ref; + int j, k, v, len, *ind; + double rhs, sum, *val; + xassert(G->n == n); + /* allocate working arrays */ + ind = talloc(1+n, int); + val = talloc(1+n, double); + /* find maximum weight clique in conflict graph */ + len = cfg_find_clique(P, G, ind, &sum); +#ifdef GLP_DEBUG + xprintf("len = %d; sum = %g\n", len, sum); + cfg_check_clique(G, len, ind); +#endif + /* check if clique inequality is violated */ + if (sum < 1.07) + goto skip; + /* expand clique to maximal one */ + len = cfg_expand_clique(G, len, ind); +#ifdef GLP_DEBUG + xprintf("maximal clique size = %d\n", len); + cfg_check_clique(G, len, ind); +#endif + /* construct clique cut (fixed binary variables are removed, so + this cut is only locally valid) */ + rhs = 1.0; + for (j = 1; j <= n; j++) + val[j] = 0.0; + for (k = 1; k <= len; k++) + { /* v is clique vertex */ + v = ind[k]; + xassert(1 <= v && v <= nv); + /* j is number of corresponding binary variable */ + j = ref[v]; + xassert(1 <= j && j <= n); + if (pos[j] == v) + { /* v corresponds to x[j] */ + if (P->col[j]->type == GLP_FX) + { /* x[j] is fixed */ + rhs -= P->col[j]->prim; + } + else + { /* x[j] is not fixed */ + val[j] += 1.0; + } + } + else if (neg[j] == v) + { /* v corresponds to (1 - x[j]) */ + if (P->col[j]->type == GLP_FX) + { /* x[j] is fixed */ + rhs -= (1.0 - P->col[j]->prim); + } + else + { /* x[j] is not fixed */ + val[j] -= 1.0; + rhs -= 1.0; + } + } + else + xassert(v != v); + } + /* convert cut inequality to sparse format */ + len = 0; + for (j = 1; j <= n; j++) + { if (val[j] != 0.0) + { len++; + ind[len] = j; + val[len] = val[j]; + } + } + /* add cut inequality to local cut pool */ + glp_ios_add_row(T, NULL, GLP_RF_CLQ, 0, len, ind, val, GLP_UP, + rhs); +skip: /* free working arrays */ + tfree(ind); + tfree(val); + return; +} + +void ios_clq_term(void *G_) +{ /* terminate clique cut generator */ + CFG *G = G_; + xassert(G != NULL); + cfg_delete_graph(G); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpios09.c b/resources/3rdparty/glpk-4.57/src/glpios09.c new file mode 100644 index 000000000..d87578cbc --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpios09.c @@ -0,0 +1,664 @@ +/* glpios09.c (branching heuristics) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpios.h" + +/*********************************************************************** +* NAME +* +* ios_choose_var - select variable to branch on +* +* SYNOPSIS +* +* #include "glpios.h" +* int ios_choose_var(glp_tree *T, int *next); +* +* The routine ios_choose_var chooses a variable from the candidate +* list to branch on. Additionally the routine provides a flag stored +* in the location next to suggests which of the child subproblems +* should be solved next. +* +* RETURNS +* +* The routine ios_choose_var returns the ordinal number of the column +* choosen. */ + +static int branch_first(glp_tree *T, int *next); +static int branch_last(glp_tree *T, int *next); +static int branch_mostf(glp_tree *T, int *next); +static int branch_drtom(glp_tree *T, int *next); + +int ios_choose_var(glp_tree *T, int *next) +{ int j; + if (T->parm->br_tech == GLP_BR_FFV) + { /* branch on first fractional variable */ + j = branch_first(T, next); + } + else if (T->parm->br_tech == GLP_BR_LFV) + { /* branch on last fractional variable */ + j = branch_last(T, next); + } + else if (T->parm->br_tech == GLP_BR_MFV) + { /* branch on most fractional variable */ + j = branch_mostf(T, next); + } + else if (T->parm->br_tech == GLP_BR_DTH) + { /* branch using the heuristic by Dreebeck and Tomlin */ + j = branch_drtom(T, next); + } + else if (T->parm->br_tech == GLP_BR_PCH) + { /* hybrid pseudocost heuristic */ + j = ios_pcost_branch(T, next); + } + else + xassert(T != T); + return j; +} + +/*********************************************************************** +* branch_first - choose first branching variable +* +* This routine looks up the list of structural variables and chooses +* the first one, which is of integer kind and has fractional value in +* optimal solution to the current LP relaxation. +* +* This routine also selects the branch to be solved next where integer +* infeasibility of the chosen variable is less than in other one. */ + +static int branch_first(glp_tree *T, int *_next) +{ int j, next; + double beta; + /* choose the column to branch on */ + for (j = 1; j <= T->n; j++) + if (T->non_int[j]) break; + xassert(1 <= j && j <= T->n); + /* select the branch to be solved next */ + beta = glp_get_col_prim(T->mip, j); + if (beta - floor(beta) < ceil(beta) - beta) + next = GLP_DN_BRNCH; + else + next = GLP_UP_BRNCH; + *_next = next; + return j; +} + +/*********************************************************************** +* branch_last - choose last branching variable +* +* This routine looks up the list of structural variables and chooses +* the last one, which is of integer kind and has fractional value in +* optimal solution to the current LP relaxation. +* +* This routine also selects the branch to be solved next where integer +* infeasibility of the chosen variable is less than in other one. */ + +static int branch_last(glp_tree *T, int *_next) +{ int j, next; + double beta; + /* choose the column to branch on */ + for (j = T->n; j >= 1; j--) + if (T->non_int[j]) break; + xassert(1 <= j && j <= T->n); + /* select the branch to be solved next */ + beta = glp_get_col_prim(T->mip, j); + if (beta - floor(beta) < ceil(beta) - beta) + next = GLP_DN_BRNCH; + else + next = GLP_UP_BRNCH; + *_next = next; + return j; +} + +/*********************************************************************** +* branch_mostf - choose most fractional branching variable +* +* This routine looks up the list of structural variables and chooses +* that one, which is of integer kind and has most fractional value in +* optimal solution to the current LP relaxation. +* +* This routine also selects the branch to be solved next where integer +* infeasibility of the chosen variable is less than in other one. +* +* (Alexander Martin notices that "...most infeasible is as good as +* random...".) */ + +static int branch_mostf(glp_tree *T, int *_next) +{ int j, jj, next; + double beta, most, temp; + /* choose the column to branch on */ + jj = 0, most = DBL_MAX; + for (j = 1; j <= T->n; j++) + { if (T->non_int[j]) + { beta = glp_get_col_prim(T->mip, j); + temp = floor(beta) + 0.5; + if (most > fabs(beta - temp)) + { jj = j, most = fabs(beta - temp); + if (beta < temp) + next = GLP_DN_BRNCH; + else + next = GLP_UP_BRNCH; + } + } + } + *_next = next; + return jj; +} + +/*********************************************************************** +* branch_drtom - choose branching var using Driebeck-Tomlin heuristic +* +* This routine chooses a structural variable, which is required to be +* integral and has fractional value in optimal solution of the current +* LP relaxation, using a heuristic proposed by Driebeck and Tomlin. +* +* The routine also selects the branch to be solved next, again due to +* Driebeck and Tomlin. +* +* This routine is based on the heuristic proposed in: +* +* Driebeck N.J. An algorithm for the solution of mixed-integer +* programming problems, Management Science, 12: 576-87 (1966); +* +* and improved in: +* +* Tomlin J.A. Branch and bound methods for integer and non-convex +* programming, in J.Abadie (ed.), Integer and Nonlinear Programming, +* North-Holland, Amsterdam, pp. 437-50 (1970). +* +* Must note that this heuristic is time-expensive, because computing +* one-step degradation (see the routine below) requires one BTRAN for +* each fractional-valued structural variable. */ + +static int branch_drtom(glp_tree *T, int *_next) +{ glp_prob *mip = T->mip; + int m = mip->m; + int n = mip->n; + unsigned char *non_int = T->non_int; + int j, jj, k, t, next, kase, len, stat, *ind; + double x, dk, alfa, delta_j, delta_k, delta_z, dz_dn, dz_up, + dd_dn, dd_up, degrad, *val; + /* basic solution of LP relaxation must be optimal */ + xassert(glp_get_status(mip) == GLP_OPT); + /* allocate working arrays */ + ind = xcalloc(1+n, sizeof(int)); + val = xcalloc(1+n, sizeof(double)); + /* nothing has been chosen so far */ + jj = 0, degrad = -1.0; + /* walk through the list of columns (structural variables) */ + for (j = 1; j <= n; j++) + { /* if j-th column is not marked as fractional, skip it */ + if (!non_int[j]) continue; + /* obtain (fractional) value of j-th column in basic solution + of LP relaxation */ + x = glp_get_col_prim(mip, j); + /* since the value of j-th column is fractional, the column is + basic; compute corresponding row of the simplex table */ + len = glp_eval_tab_row(mip, m+j, ind, val); + /* the following fragment computes a change in the objective + function: delta Z = new Z - old Z, where old Z is the + objective value in the current optimal basis, and new Z is + the objective value in the adjacent basis, for two cases: + 1) if new upper bound ub' = floor(x[j]) is introduced for + j-th column (down branch); + 2) if new lower bound lb' = ceil(x[j]) is introduced for + j-th column (up branch); + since in both cases the solution remaining dual feasible + becomes primal infeasible, one implicit simplex iteration + is performed to determine the change delta Z; + it is obvious that new Z, which is never better than old Z, + is a lower (minimization) or upper (maximization) bound of + the objective function for down- and up-branches. */ + for (kase = -1; kase <= +1; kase += 2) + { /* if kase < 0, the new upper bound of x[j] is introduced; + in this case x[j] should decrease in order to leave the + basis and go to its new upper bound */ + /* if kase > 0, the new lower bound of x[j] is introduced; + in this case x[j] should increase in order to leave the + basis and go to its new lower bound */ + /* apply the dual ratio test in order to determine which + auxiliary or structural variable should enter the basis + to keep dual feasibility */ + k = glp_dual_rtest(mip, len, ind, val, kase, 1e-9); + if (k != 0) k = ind[k]; + /* if no non-basic variable has been chosen, LP relaxation + of corresponding branch being primal infeasible and dual + unbounded has no primal feasible solution; in this case + the change delta Z is formally set to infinity */ + if (k == 0) + { delta_z = + (T->mip->dir == GLP_MIN ? +DBL_MAX : -DBL_MAX); + goto skip; + } + /* row of the simplex table that corresponds to non-basic + variable x[k] choosen by the dual ratio test is: + x[j] = ... + alfa * x[k] + ... + where alfa is the influence coefficient (an element of + the simplex table row) */ + /* determine the coefficient alfa */ + for (t = 1; t <= len; t++) if (ind[t] == k) break; + xassert(1 <= t && t <= len); + alfa = val[t]; + /* since in the adjacent basis the variable x[j] becomes + non-basic, knowing its value in the current basis we can + determine its change delta x[j] = new x[j] - old x[j] */ + delta_j = (kase < 0 ? floor(x) : ceil(x)) - x; + /* and knowing the coefficient alfa we can determine the + corresponding change delta x[k] = new x[k] - old x[k], + where old x[k] is a value of x[k] in the current basis, + and new x[k] is a value of x[k] in the adjacent basis */ + delta_k = delta_j / alfa; + /* Tomlin noticed that if the variable x[k] is of integer + kind, its change cannot be less (eventually) than one in + the magnitude */ + if (k > m && glp_get_col_kind(mip, k-m) != GLP_CV) + { /* x[k] is structural integer variable */ + if (fabs(delta_k - floor(delta_k + 0.5)) > 1e-3) + { if (delta_k > 0.0) + delta_k = ceil(delta_k); /* +3.14 -> +4 */ + else + delta_k = floor(delta_k); /* -3.14 -> -4 */ + } + } + /* now determine the status and reduced cost of x[k] in the + current basis */ + if (k <= m) + { stat = glp_get_row_stat(mip, k); + dk = glp_get_row_dual(mip, k); + } + else + { stat = glp_get_col_stat(mip, k-m); + dk = glp_get_col_dual(mip, k-m); + } + /* if the current basis is dual degenerate, some reduced + costs which are close to zero may have wrong sign due to + round-off errors, so correct the sign of d[k] */ + switch (T->mip->dir) + { case GLP_MIN: + if (stat == GLP_NL && dk < 0.0 || + stat == GLP_NU && dk > 0.0 || + stat == GLP_NF) dk = 0.0; + break; + case GLP_MAX: + if (stat == GLP_NL && dk > 0.0 || + stat == GLP_NU && dk < 0.0 || + stat == GLP_NF) dk = 0.0; + break; + default: + xassert(T != T); + } + /* now knowing the change of x[k] and its reduced cost d[k] + we can compute the corresponding change in the objective + function delta Z = new Z - old Z = d[k] * delta x[k]; + note that due to Tomlin's modification new Z can be even + worse than in the adjacent basis */ + delta_z = dk * delta_k; +skip: /* new Z is never better than old Z, therefore the change + delta Z is always non-negative (in case of minimization) + or non-positive (in case of maximization) */ + switch (T->mip->dir) + { case GLP_MIN: xassert(delta_z >= 0.0); break; + case GLP_MAX: xassert(delta_z <= 0.0); break; + default: xassert(T != T); + } + /* save the change in the objective fnction for down- and + up-branches, respectively */ + if (kase < 0) dz_dn = delta_z; else dz_up = delta_z; + } + /* thus, in down-branch no integer feasible solution can be + better than Z + dz_dn, and in up-branch no integer feasible + solution can be better than Z + dz_up, where Z is value of + the objective function in the current basis */ + /* following the heuristic by Driebeck and Tomlin we choose a + column (i.e. structural variable) which provides largest + degradation of the objective function in some of branches; + besides, we select the branch with smaller degradation to + be solved next and keep other branch with larger degradation + in the active list hoping to minimize the number of further + backtrackings */ + if (degrad < fabs(dz_dn) || degrad < fabs(dz_up)) + { jj = j; + if (fabs(dz_dn) < fabs(dz_up)) + { /* select down branch to be solved next */ + next = GLP_DN_BRNCH; + degrad = fabs(dz_up); + } + else + { /* select up branch to be solved next */ + next = GLP_UP_BRNCH; + degrad = fabs(dz_dn); + } + /* save the objective changes for printing */ + dd_dn = dz_dn, dd_up = dz_up; + /* if down- or up-branch has no feasible solution, we does + not need to consider other candidates (in principle, the + corresponding branch could be pruned right now) */ + if (degrad == DBL_MAX) break; + } + } + /* free working arrays */ + xfree(ind); + xfree(val); + /* something must be chosen */ + xassert(1 <= jj && jj <= n); +#if 1 /* 02/XI-2009 */ + if (degrad < 1e-6 * (1.0 + 0.001 * fabs(mip->obj_val))) + { jj = branch_mostf(T, &next); + goto done; + } +#endif + if (T->parm->msg_lev >= GLP_MSG_DBG) + { xprintf("branch_drtom: column %d chosen to branch on\n", jj); + if (fabs(dd_dn) == DBL_MAX) + xprintf("branch_drtom: down-branch is infeasible\n"); + else + xprintf("branch_drtom: down-branch bound is %.9e\n", + glp_get_obj_val(mip) + dd_dn); + if (fabs(dd_up) == DBL_MAX) + xprintf("branch_drtom: up-branch is infeasible\n"); + else + xprintf("branch_drtom: up-branch bound is %.9e\n", + glp_get_obj_val(mip) + dd_up); + } +done: *_next = next; + return jj; +} + +/**********************************************************************/ + +struct csa +{ /* common storage area */ + int *dn_cnt; /* int dn_cnt[1+n]; */ + /* dn_cnt[j] is the number of subproblems, whose LP relaxations + have been solved and which are down-branches for variable x[j]; + dn_cnt[j] = 0 means the down pseudocost is uninitialized */ + double *dn_sum; /* double dn_sum[1+n]; */ + /* dn_sum[j] is the sum of per unit degradations of the objective + over all dn_cnt[j] subproblems */ + int *up_cnt; /* int up_cnt[1+n]; */ + /* up_cnt[j] is the number of subproblems, whose LP relaxations + have been solved and which are up-branches for variable x[j]; + up_cnt[j] = 0 means the up pseudocost is uninitialized */ + double *up_sum; /* double up_sum[1+n]; */ + /* up_sum[j] is the sum of per unit degradations of the objective + over all up_cnt[j] subproblems */ +}; + +void *ios_pcost_init(glp_tree *tree) +{ /* initialize working data used on pseudocost branching */ + struct csa *csa; + int n = tree->n, j; + csa = xmalloc(sizeof(struct csa)); + csa->dn_cnt = xcalloc(1+n, sizeof(int)); + csa->dn_sum = xcalloc(1+n, sizeof(double)); + csa->up_cnt = xcalloc(1+n, sizeof(int)); + csa->up_sum = xcalloc(1+n, sizeof(double)); + for (j = 1; j <= n; j++) + { csa->dn_cnt[j] = csa->up_cnt[j] = 0; + csa->dn_sum[j] = csa->up_sum[j] = 0.0; + } + return csa; +} + +static double eval_degrad(glp_prob *P, int j, double bnd) +{ /* compute degradation of the objective on fixing x[j] at given + value with a limited number of dual simplex iterations */ + /* this routine fixes column x[j] at specified value bnd, + solves resulting LP, and returns a lower bound to degradation + of the objective, degrad >= 0 */ + glp_prob *lp; + glp_smcp parm; + int ret; + double degrad; + /* the current basis must be optimal */ + xassert(glp_get_status(P) == GLP_OPT); + /* create a copy of P */ + lp = glp_create_prob(); + glp_copy_prob(lp, P, 0); + /* fix column x[j] at specified value */ + glp_set_col_bnds(lp, j, GLP_FX, bnd, bnd); + /* try to solve resulting LP */ + glp_init_smcp(&parm); + parm.msg_lev = GLP_MSG_OFF; + parm.meth = GLP_DUAL; + parm.it_lim = 30; + parm.out_dly = 1000; + parm.meth = GLP_DUAL; + ret = glp_simplex(lp, &parm); + if (ret == 0 || ret == GLP_EITLIM) + { if (glp_get_prim_stat(lp) == GLP_NOFEAS) + { /* resulting LP has no primal feasible solution */ + degrad = DBL_MAX; + } + else if (glp_get_dual_stat(lp) == GLP_FEAS) + { /* resulting basis is optimal or at least dual feasible, + so we have the correct lower bound to degradation */ + if (P->dir == GLP_MIN) + degrad = lp->obj_val - P->obj_val; + else if (P->dir == GLP_MAX) + degrad = P->obj_val - lp->obj_val; + else + xassert(P != P); + /* degradation cannot be negative by definition */ + /* note that the lower bound to degradation may be close + to zero even if its exact value is zero due to round-off + errors on computing the objective value */ + if (degrad < 1e-6 * (1.0 + 0.001 * fabs(P->obj_val))) + degrad = 0.0; + } + else + { /* the final basis reported by the simplex solver is dual + infeasible, so we cannot determine a non-trivial lower + bound to degradation */ + degrad = 0.0; + } + } + else + { /* the simplex solver failed */ + degrad = 0.0; + } + /* delete the copy of P */ + glp_delete_prob(lp); + return degrad; +} + +void ios_pcost_update(glp_tree *tree) +{ /* update history information for pseudocost branching */ + /* this routine is called every time when LP relaxation of the + current subproblem has been solved to optimality with all lazy + and cutting plane constraints included */ + int j; + double dx, dz, psi; + struct csa *csa = tree->pcost; + xassert(csa != NULL); + xassert(tree->curr != NULL); + /* if the current subproblem is the root, skip updating */ + if (tree->curr->up == NULL) goto skip; + /* determine branching variable x[j], which was used in the + parent subproblem to create the current subproblem */ + j = tree->curr->up->br_var; + xassert(1 <= j && j <= tree->n); + /* determine the change dx[j] = new x[j] - old x[j], + where new x[j] is a value of x[j] in optimal solution to LP + relaxation of the current subproblem, old x[j] is a value of + x[j] in optimal solution to LP relaxation of the parent + subproblem */ + dx = tree->mip->col[j]->prim - tree->curr->up->br_val; + xassert(dx != 0.0); + /* determine corresponding change dz = new dz - old dz in the + objective function value */ + dz = tree->mip->obj_val - tree->curr->up->lp_obj; + /* determine per unit degradation of the objective function */ + psi = fabs(dz / dx); + /* update history information */ + if (dx < 0.0) + { /* the current subproblem is down-branch */ + csa->dn_cnt[j]++; + csa->dn_sum[j] += psi; + } + else /* dx > 0.0 */ + { /* the current subproblem is up-branch */ + csa->up_cnt[j]++; + csa->up_sum[j] += psi; + } +skip: return; +} + +void ios_pcost_free(glp_tree *tree) +{ /* free working area used on pseudocost branching */ + struct csa *csa = tree->pcost; + xassert(csa != NULL); + xfree(csa->dn_cnt); + xfree(csa->dn_sum); + xfree(csa->up_cnt); + xfree(csa->up_sum); + xfree(csa); + tree->pcost = NULL; + return; +} + +static double eval_psi(glp_tree *T, int j, int brnch) +{ /* compute estimation of pseudocost of variable x[j] for down- + or up-branch */ + struct csa *csa = T->pcost; + double beta, degrad, psi; + xassert(csa != NULL); + xassert(1 <= j && j <= T->n); + if (brnch == GLP_DN_BRNCH) + { /* down-branch */ + if (csa->dn_cnt[j] == 0) + { /* initialize down pseudocost */ + beta = T->mip->col[j]->prim; + degrad = eval_degrad(T->mip, j, floor(beta)); + if (degrad == DBL_MAX) + { psi = DBL_MAX; + goto done; + } + csa->dn_cnt[j] = 1; + csa->dn_sum[j] = degrad / (beta - floor(beta)); + } + psi = csa->dn_sum[j] / (double)csa->dn_cnt[j]; + } + else if (brnch == GLP_UP_BRNCH) + { /* up-branch */ + if (csa->up_cnt[j] == 0) + { /* initialize up pseudocost */ + beta = T->mip->col[j]->prim; + degrad = eval_degrad(T->mip, j, ceil(beta)); + if (degrad == DBL_MAX) + { psi = DBL_MAX; + goto done; + } + csa->up_cnt[j] = 1; + csa->up_sum[j] = degrad / (ceil(beta) - beta); + } + psi = csa->up_sum[j] / (double)csa->up_cnt[j]; + } + else + xassert(brnch != brnch); +done: return psi; +} + +static void progress(glp_tree *T) +{ /* display progress of pseudocost initialization */ + struct csa *csa = T->pcost; + int j, nv = 0, ni = 0; + for (j = 1; j <= T->n; j++) + { if (glp_ios_can_branch(T, j)) + { nv++; + if (csa->dn_cnt[j] > 0 && csa->up_cnt[j] > 0) ni++; + } + } + xprintf("Pseudocosts initialized for %d of %d variables\n", + ni, nv); + return; +} + +int ios_pcost_branch(glp_tree *T, int *_next) +{ /* choose branching variable with pseudocost branching */ +#if 0 /* 10/VI-2013 */ + glp_long t = xtime(); +#else + double t = xtime(); +#endif + int j, jjj, sel; + double beta, psi, d1, d2, d, dmax; + /* initialize the working arrays */ + if (T->pcost == NULL) + T->pcost = ios_pcost_init(T); + /* nothing has been chosen so far */ + jjj = 0, dmax = -1.0; + /* go through the list of branching candidates */ + for (j = 1; j <= T->n; j++) + { if (!glp_ios_can_branch(T, j)) continue; + /* determine primal value of x[j] in optimal solution to LP + relaxation of the current subproblem */ + beta = T->mip->col[j]->prim; + /* estimate pseudocost of x[j] for down-branch */ + psi = eval_psi(T, j, GLP_DN_BRNCH); + if (psi == DBL_MAX) + { /* down-branch has no primal feasible solution */ + jjj = j, sel = GLP_DN_BRNCH; + goto done; + } + /* estimate degradation of the objective for down-branch */ + d1 = psi * (beta - floor(beta)); + /* estimate pseudocost of x[j] for up-branch */ + psi = eval_psi(T, j, GLP_UP_BRNCH); + if (psi == DBL_MAX) + { /* up-branch has no primal feasible solution */ + jjj = j, sel = GLP_UP_BRNCH; + goto done; + } + /* estimate degradation of the objective for up-branch */ + d2 = psi * (ceil(beta) - beta); + /* determine d = max(d1, d2) */ + d = (d1 > d2 ? d1 : d2); + /* choose x[j] which provides maximal estimated degradation of + the objective either in down- or up-branch */ + if (dmax < d) + { dmax = d; + jjj = j; + /* continue the search from a subproblem, where degradation + is less than in other one */ + sel = (d1 <= d2 ? GLP_DN_BRNCH : GLP_UP_BRNCH); + } + /* display progress of pseudocost initialization */ + if (T->parm->msg_lev >= GLP_ON) + { if (xdifftime(xtime(), t) >= 10.0) + { progress(T); + t = xtime(); + } + } + } + if (dmax == 0.0) + { /* no degradation is indicated; choose a variable having most + fractional value */ + jjj = branch_mostf(T, &sel); + } +done: *_next = sel; + return jjj; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpios10.c b/resources/3rdparty/glpk-4.57/src/glpios10.c new file mode 100644 index 000000000..e67625795 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpios10.c @@ -0,0 +1,355 @@ +/* glpios10.c (feasibility pump heuristic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpios.h" +#include "rng.h" + +/*********************************************************************** +* NAME +* +* ios_feas_pump - feasibility pump heuristic +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_feas_pump(glp_tree *T); +* +* DESCRIPTION +* +* The routine ios_feas_pump is a simple implementation of the Feasi- +* bility Pump heuristic. +* +* REFERENCES +* +* M.Fischetti, F.Glover, and A.Lodi. "The feasibility pump." Math. +* Program., Ser. A 104, pp. 91-104 (2005). */ + +struct VAR +{ /* binary variable */ + int j; + /* ordinal number */ + int x; + /* value in the rounded solution (0 or 1) */ + double d; + /* sorting key */ +}; + +static int fcmp(const void *x, const void *y) +{ /* comparison routine */ + const struct VAR *vx = x, *vy = y; + if (vx->d > vy->d) + return -1; + else if (vx->d < vy->d) + return +1; + else + return 0; +} + +void ios_feas_pump(glp_tree *T) +{ glp_prob *P = T->mip; + int n = P->n; + glp_prob *lp = NULL; + struct VAR *var = NULL; + RNG *rand = NULL; + GLPCOL *col; + glp_smcp parm; + int j, k, new_x, nfail, npass, nv, ret, stalling; + double dist, tol; + xassert(glp_get_status(P) == GLP_OPT); + /* this heuristic is applied only once on the root level */ + if (!(T->curr->level == 0 && T->curr->solved == 1)) goto done; + /* determine number of binary variables */ + nv = 0; + for (j = 1; j <= n; j++) + { col = P->col[j]; + /* if x[j] is continuous, skip it */ + if (col->kind == GLP_CV) continue; + /* if x[j] is fixed, skip it */ + if (col->type == GLP_FX) continue; + /* x[j] is non-fixed integer */ + xassert(col->kind == GLP_IV); + if (col->type == GLP_DB && col->lb == 0.0 && col->ub == 1.0) + { /* x[j] is binary */ + nv++; + } + else + { /* x[j] is general integer */ + if (T->parm->msg_lev >= GLP_MSG_ALL) + xprintf("FPUMP heuristic cannot be applied due to genera" + "l integer variables\n"); + goto done; + } + } + /* there must be at least one binary variable */ + if (nv == 0) goto done; + if (T->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Applying FPUMP heuristic...\n"); + /* build the list of binary variables */ + var = xcalloc(1+nv, sizeof(struct VAR)); + k = 0; + for (j = 1; j <= n; j++) + { col = P->col[j]; + if (col->kind == GLP_IV && col->type == GLP_DB) + var[++k].j = j; + } + xassert(k == nv); + /* create working problem object */ + lp = glp_create_prob(); +more: /* copy the original problem object to keep it intact */ + glp_copy_prob(lp, P, GLP_OFF); + /* we are interested to find an integer feasible solution, which + is better than the best known one */ + if (P->mip_stat == GLP_FEAS) + { int *ind; + double *val, bnd; + /* add a row and make it identical to the objective row */ + glp_add_rows(lp, 1); + ind = xcalloc(1+n, sizeof(int)); + val = xcalloc(1+n, sizeof(double)); + for (j = 1; j <= n; j++) + { ind[j] = j; + val[j] = P->col[j]->coef; + } + glp_set_mat_row(lp, lp->m, n, ind, val); + xfree(ind); + xfree(val); + /* introduce upper (minimization) or lower (maximization) + bound to the original objective function; note that this + additional constraint is not violated at the optimal point + to LP relaxation */ +#if 0 /* modified by xypron */ + if (P->dir == GLP_MIN) + { bnd = P->mip_obj - 0.10 * (1.0 + fabs(P->mip_obj)); + if (bnd < P->obj_val) bnd = P->obj_val; + glp_set_row_bnds(lp, lp->m, GLP_UP, 0.0, bnd - P->c0); + } + else if (P->dir == GLP_MAX) + { bnd = P->mip_obj + 0.10 * (1.0 + fabs(P->mip_obj)); + if (bnd > P->obj_val) bnd = P->obj_val; + glp_set_row_bnds(lp, lp->m, GLP_LO, bnd - P->c0, 0.0); + } + else + xassert(P != P); +#else + bnd = 0.1 * P->obj_val + 0.9 * P->mip_obj; + /* xprintf("bnd = %f\n", bnd); */ + if (P->dir == GLP_MIN) + glp_set_row_bnds(lp, lp->m, GLP_UP, 0.0, bnd - P->c0); + else if (P->dir == GLP_MAX) + glp_set_row_bnds(lp, lp->m, GLP_LO, bnd - P->c0, 0.0); + else + xassert(P != P); +#endif + } + /* reset pass count */ + npass = 0; + /* invalidate the rounded point */ + for (k = 1; k <= nv; k++) + var[k].x = -1; +pass: /* next pass starts here */ + npass++; + if (T->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Pass %d\n", npass); + /* initialize minimal distance between the basic point and the + rounded one obtained during this pass */ + dist = DBL_MAX; + /* reset failure count (the number of succeeded iterations failed + to improve the distance) */ + nfail = 0; + /* if it is not the first pass, perturb the last rounded point + rather than construct it from the basic solution */ + if (npass > 1) + { double rho, temp; + if (rand == NULL) + rand = rng_create_rand(); + for (k = 1; k <= nv; k++) + { j = var[k].j; + col = lp->col[j]; + rho = rng_uniform(rand, -0.3, 0.7); + if (rho < 0.0) rho = 0.0; + temp = fabs((double)var[k].x - col->prim); + if (temp + rho > 0.5) var[k].x = 1 - var[k].x; + } + goto skip; + } +loop: /* innermost loop begins here */ + /* round basic solution (which is assumed primal feasible) */ + stalling = 1; + for (k = 1; k <= nv; k++) + { col = lp->col[var[k].j]; + if (col->prim < 0.5) + { /* rounded value is 0 */ + new_x = 0; + } + else + { /* rounded value is 1 */ + new_x = 1; + } + if (var[k].x != new_x) + { stalling = 0; + var[k].x = new_x; + } + } + /* if the rounded point has not changed (stalling), choose and + flip some its entries heuristically */ + if (stalling) + { /* compute d[j] = |x[j] - round(x[j])| */ + for (k = 1; k <= nv; k++) + { col = lp->col[var[k].j]; + var[k].d = fabs(col->prim - (double)var[k].x); + } + /* sort the list of binary variables by descending d[j] */ + qsort(&var[1], nv, sizeof(struct VAR), fcmp); + /* choose and flip some rounded components */ + for (k = 1; k <= nv; k++) + { if (k >= 5 && var[k].d < 0.35 || k >= 10) break; + var[k].x = 1 - var[k].x; + } + } +skip: /* check if the time limit has been exhausted */ + if (T->parm->tm_lim < INT_MAX && + (double)(T->parm->tm_lim - 1) <= + 1000.0 * xdifftime(xtime(), T->tm_beg)) goto done; + /* build the objective, which is the distance between the current + (basic) point and the rounded one */ + lp->dir = GLP_MIN; + lp->c0 = 0.0; + for (j = 1; j <= n; j++) + lp->col[j]->coef = 0.0; + for (k = 1; k <= nv; k++) + { j = var[k].j; + if (var[k].x == 0) + lp->col[j]->coef = +1.0; + else + { lp->col[j]->coef = -1.0; + lp->c0 += 1.0; + } + } + /* minimize the distance with the simplex method */ + glp_init_smcp(&parm); + if (T->parm->msg_lev <= GLP_MSG_ERR) + parm.msg_lev = T->parm->msg_lev; + else if (T->parm->msg_lev <= GLP_MSG_ALL) + { parm.msg_lev = GLP_MSG_ON; + parm.out_dly = 10000; + } + ret = glp_simplex(lp, &parm); + if (ret != 0) + { if (T->parm->msg_lev >= GLP_MSG_ERR) + xprintf("Warning: glp_simplex returned %d\n", ret); + goto done; + } + ret = glp_get_status(lp); + if (ret != GLP_OPT) + { if (T->parm->msg_lev >= GLP_MSG_ERR) + xprintf("Warning: glp_get_status returned %d\n", ret); + goto done; + } + if (T->parm->msg_lev >= GLP_MSG_DBG) + xprintf("delta = %g\n", lp->obj_val); + /* check if the basic solution is integer feasible; note that it + may be so even if the minimial distance is positive */ + tol = 0.3 * T->parm->tol_int; + for (k = 1; k <= nv; k++) + { col = lp->col[var[k].j]; + if (tol < col->prim && col->prim < 1.0 - tol) break; + } + if (k > nv) + { /* okay; the basic solution seems to be integer feasible */ + double *x = xcalloc(1+n, sizeof(double)); + for (j = 1; j <= n; j++) + { x[j] = lp->col[j]->prim; + if (P->col[j]->kind == GLP_IV) x[j] = floor(x[j] + 0.5); + } +#if 1 /* modified by xypron */ + /* reset direction and right-hand side of objective */ + lp->c0 = P->c0; + lp->dir = P->dir; + /* fix integer variables */ + for (k = 1; k <= nv; k++) +#if 0 /* 18/VI-2013; fixed by mao + * this bug causes numerical instability, because column statuses + * are not changed appropriately */ + { lp->col[var[k].j]->lb = x[var[k].j]; + lp->col[var[k].j]->ub = x[var[k].j]; + lp->col[var[k].j]->type = GLP_FX; + } +#else + glp_set_col_bnds(lp, var[k].j, GLP_FX, x[var[k].j], 0.); +#endif + /* copy original objective function */ + for (j = 1; j <= n; j++) + lp->col[j]->coef = P->col[j]->coef; + /* solve original LP and copy result */ + ret = glp_simplex(lp, &parm); + if (ret != 0) + { if (T->parm->msg_lev >= GLP_MSG_ERR) + xprintf("Warning: glp_simplex returned %d\n", ret); + goto done; + } + ret = glp_get_status(lp); + if (ret != GLP_OPT) + { if (T->parm->msg_lev >= GLP_MSG_ERR) + xprintf("Warning: glp_get_status returned %d\n", ret); + goto done; + } + for (j = 1; j <= n; j++) + if (P->col[j]->kind != GLP_IV) x[j] = lp->col[j]->prim; +#endif + ret = glp_ios_heur_sol(T, x); + xfree(x); + if (ret == 0) + { /* the integer solution is accepted */ + if (ios_is_hopeful(T, T->curr->bound)) + { /* it is reasonable to apply the heuristic once again */ + goto more; + } + else + { /* the best known integer feasible solution just found + is close to optimal solution to LP relaxation */ + goto done; + } + } + } + /* the basic solution is fractional */ + if (dist == DBL_MAX || + lp->obj_val <= dist - 1e-6 * (1.0 + dist)) + { /* the distance is reducing */ + nfail = 0, dist = lp->obj_val; + } + else + { /* improving the distance failed */ + nfail++; + } + if (nfail < 3) goto loop; + if (npass < 5) goto pass; +done: /* delete working objects */ + if (lp != NULL) glp_delete_prob(lp); + if (var != NULL) xfree(var); + if (rand != NULL) rng_delete_rand(rand); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpios11.c b/resources/3rdparty/glpk-4.57/src/glpios11.c new file mode 100644 index 000000000..a9f4854d8 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpios11.c @@ -0,0 +1,282 @@ +/* glpios11.c (process cuts stored in the local cut pool) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "draft.h" +#include "env.h" +#include "glpios.h" + +/*********************************************************************** +* NAME +* +* ios_process_cuts - process cuts stored in the local cut pool +* +* SYNOPSIS +* +* #include "glpios.h" +* void ios_process_cuts(glp_tree *T); +* +* DESCRIPTION +* +* The routine ios_process_cuts analyzes each cut currently stored in +* the local cut pool, which must be non-empty, and either adds the cut +* to the current subproblem or just discards it. All cuts are assumed +* to be locally valid. On exit the local cut pool remains unchanged. +* +* REFERENCES +* +* 1. E.Balas, S.Ceria, G.Cornuejols, "Mixed 0-1 Programming by +* Lift-and-Project in a Branch-and-Cut Framework", Management Sc., +* 42 (1996) 1229-1246. +* +* 2. G.Andreello, A.Caprara, and M.Fischetti, "Embedding Cuts in +* a Branch&Cut Framework: a Computational Study with {0,1/2}-Cuts", +* Preliminary Draft, October 28, 2003, pp.6-8. */ + +struct info +{ /* estimated cut efficiency */ + IOSCUT *cut; + /* pointer to cut in the cut pool */ + char flag; + /* if this flag is set, the cut is included into the current + subproblem */ + double eff; + /* cut efficacy (normalized residual) */ + double deg; + /* lower bound to objective degradation */ +}; + +static int fcmp(const void *arg1, const void *arg2) +{ const struct info *info1 = arg1, *info2 = arg2; + if (info1->deg == 0.0 && info2->deg == 0.0) + { if (info1->eff > info2->eff) return -1; + if (info1->eff < info2->eff) return +1; + } + else + { if (info1->deg > info2->deg) return -1; + if (info1->deg < info2->deg) return +1; + } + return 0; +} + +static double parallel(IOSCUT *a, IOSCUT *b, double work[]); + +void ios_process_cuts(glp_tree *T) +{ IOSPOOL *pool; + IOSCUT *cut; + IOSAIJ *aij; + struct info *info; + int k, kk, max_cuts, len, ret, *ind; + double *val, *work; + /* the current subproblem must exist */ + xassert(T->curr != NULL); + /* the pool must exist and be non-empty */ + pool = T->local; + xassert(pool != NULL); + xassert(pool->size > 0); + /* allocate working arrays */ + info = xcalloc(1+pool->size, sizeof(struct info)); + ind = xcalloc(1+T->n, sizeof(int)); + val = xcalloc(1+T->n, sizeof(double)); + work = xcalloc(1+T->n, sizeof(double)); + for (k = 1; k <= T->n; k++) work[k] = 0.0; + /* build the list of cuts stored in the cut pool */ + for (k = 0, cut = pool->head; cut != NULL; cut = cut->next) + k++, info[k].cut = cut, info[k].flag = 0; + xassert(k == pool->size); + /* estimate efficiency of all cuts in the cut pool */ + for (k = 1; k <= pool->size; k++) + { double temp, dy, dz; + cut = info[k].cut; + /* build the vector of cut coefficients and compute its + Euclidean norm */ + len = 0; temp = 0.0; + for (aij = cut->ptr; aij != NULL; aij = aij->next) + { xassert(1 <= aij->j && aij->j <= T->n); + len++, ind[len] = aij->j, val[len] = aij->val; + temp += aij->val * aij->val; + } + if (temp < DBL_EPSILON * DBL_EPSILON) temp = DBL_EPSILON; + /* transform the cut to express it only through non-basic + (auxiliary and structural) variables */ + len = glp_transform_row(T->mip, len, ind, val); + /* determine change in the cut value and in the objective + value for the adjacent basis by simulating one step of the + dual simplex */ + ret = _glp_analyze_row(T->mip, len, ind, val, cut->type, + cut->rhs, 1e-9, NULL, NULL, NULL, NULL, &dy, &dz); + /* determine normalized residual and lower bound to objective + degradation */ + if (ret == 0) + { info[k].eff = fabs(dy) / sqrt(temp); + /* if some reduced costs violates (slightly) their zero + bounds (i.e. have wrong signs) due to round-off errors, + dz also may have wrong sign being close to zero */ + if (T->mip->dir == GLP_MIN) + { if (dz < 0.0) dz = 0.0; + info[k].deg = + dz; + } + else /* GLP_MAX */ + { if (dz > 0.0) dz = 0.0; + info[k].deg = - dz; + } + } + else if (ret == 1) + { /* the constraint is not violated at the current point */ + info[k].eff = info[k].deg = 0.0; + } + else if (ret == 2) + { /* no dual feasible adjacent basis exists */ + info[k].eff = 1.0; + info[k].deg = DBL_MAX; + } + else + xassert(ret != ret); + /* if the degradation is too small, just ignore it */ + if (info[k].deg < 0.01) info[k].deg = 0.0; + } + /* sort the list of cuts by decreasing objective degradation and + then by decreasing efficacy */ + qsort(&info[1], pool->size, sizeof(struct info), fcmp); + /* only first (most efficient) max_cuts in the list are qualified + as candidates to be added to the current subproblem */ + max_cuts = (T->curr->level == 0 ? 90 : 10); + if (max_cuts > pool->size) max_cuts = pool->size; + /* add cuts to the current subproblem */ +#if 0 + xprintf("*** adding cuts ***\n"); +#endif + for (k = 1; k <= max_cuts; k++) + { int i, len; + /* if this cut seems to be inefficient, skip it */ + if (info[k].deg < 0.01 && info[k].eff < 0.01) continue; + /* if the angle between this cut and every other cut included + in the current subproblem is small, skip this cut */ + for (kk = 1; kk < k; kk++) + { if (info[kk].flag) + { if (parallel(info[k].cut, info[kk].cut, work) > 0.90) + break; + } + } + if (kk < k) continue; + /* add this cut to the current subproblem */ +#if 0 + xprintf("eff = %g; deg = %g\n", info[k].eff, info[k].deg); +#endif + cut = info[k].cut, info[k].flag = 1; + i = glp_add_rows(T->mip, 1); + if (cut->name != NULL) + glp_set_row_name(T->mip, i, cut->name); + xassert(T->mip->row[i]->origin == GLP_RF_CUT); + T->mip->row[i]->klass = cut->klass; + len = 0; + for (aij = cut->ptr; aij != NULL; aij = aij->next) + len++, ind[len] = aij->j, val[len] = aij->val; + glp_set_mat_row(T->mip, i, len, ind, val); + xassert(cut->type == GLP_LO || cut->type == GLP_UP); + glp_set_row_bnds(T->mip, i, cut->type, cut->rhs, cut->rhs); + } + /* free working arrays */ + xfree(info); + xfree(ind); + xfree(val); + xfree(work); + return; +} + +#if 0 +/*********************************************************************** +* Given a cut a * x >= b (<= b) the routine efficacy computes the cut +* efficacy as follows: +* +* eff = d * (a * x~ - b) / ||a||, +* +* where d is -1 (in case of '>= b') or +1 (in case of '<= b'), x~ is +* the vector of values of structural variables in optimal solution to +* LP relaxation of the current subproblem, ||a|| is the Euclidean norm +* of the vector of cut coefficients. +* +* If the cut is violated at point x~, the efficacy eff is positive, +* and its value is the Euclidean distance between x~ and the cut plane +* a * x = b in the space of structural variables. +* +* Following geometrical intuition, it is quite natural to consider +* this distance as a first-order measure of the expected efficacy of +* the cut: the larger the distance the better the cut [1]. */ + +static double efficacy(glp_tree *T, IOSCUT *cut) +{ glp_prob *mip = T->mip; + IOSAIJ *aij; + double s = 0.0, t = 0.0, temp; + for (aij = cut->ptr; aij != NULL; aij = aij->next) + { xassert(1 <= aij->j && aij->j <= mip->n); + s += aij->val * mip->col[aij->j]->prim; + t += aij->val * aij->val; + } + temp = sqrt(t); + if (temp < DBL_EPSILON) temp = DBL_EPSILON; + if (cut->type == GLP_LO) + temp = (s >= cut->rhs ? 0.0 : (cut->rhs - s) / temp); + else if (cut->type == GLP_UP) + temp = (s <= cut->rhs ? 0.0 : (s - cut->rhs) / temp); + else + xassert(cut != cut); + return temp; +} +#endif + +/*********************************************************************** +* Given two cuts a1 * x >= b1 (<= b1) and a2 * x >= b2 (<= b2) the +* routine parallel computes the cosine of angle between the cut planes +* a1 * x = b1 and a2 * x = b2 (which is the acute angle between two +* normals to these planes) in the space of structural variables as +* follows: +* +* cos phi = (a1' * a2) / (||a1|| * ||a2||), +* +* where (a1' * a2) is a dot product of vectors of cut coefficients, +* ||a1|| and ||a2|| are Euclidean norms of vectors a1 and a2. +* +* Note that requirement cos phi = 0 forces the cuts to be orthogonal, +* i.e. with disjoint support, while requirement cos phi <= 0.999 means +* only avoiding duplicate (parallel) cuts [1]. */ + +static double parallel(IOSCUT *a, IOSCUT *b, double work[]) +{ IOSAIJ *aij; + double s = 0.0, sa = 0.0, sb = 0.0, temp; + for (aij = a->ptr; aij != NULL; aij = aij->next) + { work[aij->j] = aij->val; + sa += aij->val * aij->val; + } + for (aij = b->ptr; aij != NULL; aij = aij->next) + { s += work[aij->j] * aij->val; + sb += aij->val * aij->val; + } + for (aij = a->ptr; aij != NULL; aij = aij->next) + work[aij->j] = 0.0; + temp = sqrt(sa) * sqrt(sb); + if (temp < DBL_EPSILON * DBL_EPSILON) temp = DBL_EPSILON; + return s / temp; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpios12.c b/resources/3rdparty/glpk-4.57/src/glpios12.c new file mode 100644 index 000000000..d5cf302a8 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpios12.c @@ -0,0 +1,177 @@ +/* glpios12.c (node selection heuristics) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpios.h" + +/*********************************************************************** +* NAME +* +* ios_choose_node - select subproblem to continue the search +* +* SYNOPSIS +* +* #include "glpios.h" +* int ios_choose_node(glp_tree *T); +* +* DESCRIPTION +* +* The routine ios_choose_node selects a subproblem from the active +* list to continue the search. The choice depends on the backtracking +* technique option. +* +* RETURNS +* +* The routine ios_choose_node return the reference number of the +* subproblem selected. */ + +static int most_feas(glp_tree *T); +static int best_proj(glp_tree *T); +static int best_node(glp_tree *T); + +int ios_choose_node(glp_tree *T) +{ int p; + if (T->parm->bt_tech == GLP_BT_DFS) + { /* depth first search */ + xassert(T->tail != NULL); + p = T->tail->p; + } + else if (T->parm->bt_tech == GLP_BT_BFS) + { /* breadth first search */ + xassert(T->head != NULL); + p = T->head->p; + } + else if (T->parm->bt_tech == GLP_BT_BLB) + { /* select node with best local bound */ + p = best_node(T); + } + else if (T->parm->bt_tech == GLP_BT_BPH) + { if (T->mip->mip_stat == GLP_UNDEF) + { /* "most integer feasible" subproblem */ + p = most_feas(T); + } + else + { /* best projection heuristic */ + p = best_proj(T); + } + } + else + xassert(T != T); + return p; +} + +static int most_feas(glp_tree *T) +{ /* select subproblem whose parent has minimal sum of integer + infeasibilities */ + IOSNPD *node; + int p; + double best; + p = 0, best = DBL_MAX; + for (node = T->head; node != NULL; node = node->next) + { xassert(node->up != NULL); + if (best > node->up->ii_sum) + p = node->p, best = node->up->ii_sum; + } + return p; +} + +static int best_proj(glp_tree *T) +{ /* select subproblem using the best projection heuristic */ + IOSNPD *root, *node; + int p; + double best, deg, obj; + /* the global bound must exist */ + xassert(T->mip->mip_stat == GLP_FEAS); + /* obtain pointer to the root node, which must exist */ + root = T->slot[1].node; + xassert(root != NULL); + /* deg estimates degradation of the objective function per unit + of the sum of integer infeasibilities */ + xassert(root->ii_sum > 0.0); + deg = (T->mip->mip_obj - root->bound) / root->ii_sum; + /* nothing has been selected so far */ + p = 0, best = DBL_MAX; + /* walk through the list of active subproblems */ + for (node = T->head; node != NULL; node = node->next) + { xassert(node->up != NULL); + /* obj estimates optimal objective value if the sum of integer + infeasibilities were zero */ + obj = node->up->bound + deg * node->up->ii_sum; + if (T->mip->dir == GLP_MAX) obj = - obj; + /* select the subproblem which has the best estimated optimal + objective value */ + if (best > obj) p = node->p, best = obj; + } + return p; +} + +static int best_node(glp_tree *T) +{ /* select subproblem with best local bound */ + IOSNPD *node, *best = NULL; + double bound, eps; + switch (T->mip->dir) + { case GLP_MIN: + bound = +DBL_MAX; + for (node = T->head; node != NULL; node = node->next) + if (bound > node->bound) bound = node->bound; + xassert(bound != +DBL_MAX); + eps = 1e-10 * (1.0 + fabs(bound)); + for (node = T->head; node != NULL; node = node->next) + { if (node->bound <= bound + eps) + { xassert(node->up != NULL); + if (best == NULL || +#if 1 + best->up->ii_sum > node->up->ii_sum) best = node; +#else + best->lp_obj > node->lp_obj) best = node; +#endif + } + } + break; + case GLP_MAX: + bound = -DBL_MAX; + for (node = T->head; node != NULL; node = node->next) + if (bound < node->bound) bound = node->bound; + xassert(bound != -DBL_MAX); + eps = 1e-10 * (1.0 + fabs(bound)); + for (node = T->head; node != NULL; node = node->next) + { if (node->bound >= bound - eps) + { xassert(node->up != NULL); + if (best == NULL || +#if 1 + best->up->ii_sum > node->up->ii_sum) best = node; +#else + best->lp_obj < node->lp_obj) best = node; +#endif + } + } + break; + default: + xassert(T != T); + } + xassert(best != NULL); + return best->p; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpipm.c b/resources/3rdparty/glpk-4.57/src/glpipm.c new file mode 100644 index 000000000..2b3a81762 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpipm.c @@ -0,0 +1,1144 @@ +/* glpipm.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpipm.h" +#include "glpmat.h" + +#define ITER_MAX 100 +/* maximal number of iterations */ + +struct csa +{ /* common storage area */ + /*--------------------------------------------------------------*/ + /* LP data */ + int m; + /* number of rows (equality constraints) */ + int n; + /* number of columns (structural variables) */ + int *A_ptr; /* int A_ptr[1+m+1]; */ + int *A_ind; /* int A_ind[A_ptr[m+1]]; */ + double *A_val; /* double A_val[A_ptr[m+1]]; */ + /* mxn-matrix A in storage-by-rows format */ + double *b; /* double b[1+m]; */ + /* m-vector b of right-hand sides */ + double *c; /* double c[1+n]; */ + /* n-vector c of objective coefficients; c[0] is constant term of + the objective function */ + /*--------------------------------------------------------------*/ + /* LP solution */ + double *x; /* double x[1+n]; */ + double *y; /* double y[1+m]; */ + double *z; /* double z[1+n]; */ + /* current point in primal-dual space; the best point on exit */ + /*--------------------------------------------------------------*/ + /* control parameters */ + const glp_iptcp *parm; + /*--------------------------------------------------------------*/ + /* working arrays and variables */ + double *D; /* double D[1+n]; */ + /* diagonal nxn-matrix D = X*inv(Z), where X = diag(x[j]) and + Z = diag(z[j]) */ + int *P; /* int P[1+m+m]; */ + /* permutation mxm-matrix P used to minimize fill-in in Cholesky + factorization */ + int *S_ptr; /* int S_ptr[1+m+1]; */ + int *S_ind; /* int S_ind[S_ptr[m+1]]; */ + double *S_val; /* double S_val[S_ptr[m+1]]; */ + double *S_diag; /* double S_diag[1+m]; */ + /* symmetric mxm-matrix S = P*A*D*A'*P' whose upper triangular + part without diagonal elements is stored in S_ptr, S_ind, and + S_val in storage-by-rows format, diagonal elements are stored + in S_diag */ + int *U_ptr; /* int U_ptr[1+m+1]; */ + int *U_ind; /* int U_ind[U_ptr[m+1]]; */ + double *U_val; /* double U_val[U_ptr[m+1]]; */ + double *U_diag; /* double U_diag[1+m]; */ + /* upper triangular mxm-matrix U defining Cholesky factorization + S = U'*U; its non-diagonal elements are stored in U_ptr, U_ind, + U_val in storage-by-rows format, diagonal elements are stored + in U_diag */ + int iter; + /* iteration number (0, 1, 2, ...); iter = 0 corresponds to the + initial point */ + double obj; + /* current value of the objective function */ + double rpi; + /* relative primal infeasibility rpi = ||A*x-b||/(1+||b||) */ + double rdi; + /* relative dual infeasibility rdi = ||A'*y+z-c||/(1+||c||) */ + double gap; + /* primal-dual gap = |c'*x-b'*y|/(1+|c'*x|) which is a relative + difference between primal and dual objective functions */ + double phi; + /* merit function phi = ||A*x-b||/max(1,||b||) + + + ||A'*y+z-c||/max(1,||c||) + + + |c'*x-b'*y|/max(1,||b||,||c||) */ + double mu; + /* duality measure mu = x'*z/n (used as barrier parameter) */ + double rmu; + /* rmu = max(||A*x-b||,||A'*y+z-c||)/mu */ + double rmu0; + /* the initial value of rmu on iteration 0 */ + double *phi_min; /* double phi_min[1+ITER_MAX]; */ + /* phi_min[k] = min(phi[k]), where phi[k] is the value of phi on + k-th iteration, 0 <= k <= iter */ + int best_iter; + /* iteration number, on which the value of phi reached its best + (minimal) value */ + double *best_x; /* double best_x[1+n]; */ + double *best_y; /* double best_y[1+m]; */ + double *best_z; /* double best_z[1+n]; */ + /* best point (in the sense of the merit function phi) which has + been reached on iteration iter_best */ + double best_obj; + /* objective value at the best point */ + double *dx_aff; /* double dx_aff[1+n]; */ + double *dy_aff; /* double dy_aff[1+m]; */ + double *dz_aff; /* double dz_aff[1+n]; */ + /* affine scaling direction */ + double alfa_aff_p, alfa_aff_d; + /* maximal primal and dual stepsizes in affine scaling direction, + on which x and z are still non-negative */ + double mu_aff; + /* duality measure mu_aff = x_aff'*z_aff/n in the boundary point + x_aff' = x+alfa_aff_p*dx_aff, z_aff' = z+alfa_aff_d*dz_aff */ + double sigma; + /* Mehrotra's heuristic parameter (0 <= sigma <= 1) */ + double *dx_cc; /* double dx_cc[1+n]; */ + double *dy_cc; /* double dy_cc[1+m]; */ + double *dz_cc; /* double dz_cc[1+n]; */ + /* centering corrector direction */ + double *dx; /* double dx[1+n]; */ + double *dy; /* double dy[1+m]; */ + double *dz; /* double dz[1+n]; */ + /* final combined direction dx = dx_aff+dx_cc, dy = dy_aff+dy_cc, + dz = dz_aff+dz_cc */ + double alfa_max_p; + double alfa_max_d; + /* maximal primal and dual stepsizes in combined direction, on + which x and z are still non-negative */ +}; + +/*********************************************************************** +* initialize - allocate and initialize common storage area +* +* This routine allocates and initializes the common storage area (CSA) +* used by interior-point method routines. */ + +static void initialize(struct csa *csa) +{ int m = csa->m; + int n = csa->n; + int i; + if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Matrix A has %d non-zeros\n", csa->A_ptr[m+1]-1); + csa->D = xcalloc(1+n, sizeof(double)); + /* P := I */ + csa->P = xcalloc(1+m+m, sizeof(int)); + for (i = 1; i <= m; i++) csa->P[i] = csa->P[m+i] = i; + /* S := A*A', symbolically */ + csa->S_ptr = xcalloc(1+m+1, sizeof(int)); + csa->S_ind = adat_symbolic(m, n, csa->P, csa->A_ptr, csa->A_ind, + csa->S_ptr); + if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Matrix S = A*A' has %d non-zeros (upper triangle)\n", + csa->S_ptr[m+1]-1 + m); + /* determine P using specified ordering algorithm */ + if (csa->parm->ord_alg == GLP_ORD_NONE) + { if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Original ordering is being used\n"); + for (i = 1; i <= m; i++) + csa->P[i] = csa->P[m+i] = i; + } + else if (csa->parm->ord_alg == GLP_ORD_QMD) + { if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Minimum degree ordering (QMD)...\n"); + min_degree(m, csa->S_ptr, csa->S_ind, csa->P); + } + else if (csa->parm->ord_alg == GLP_ORD_AMD) + { if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Approximate minimum degree ordering (AMD)...\n"); + amd_order1(m, csa->S_ptr, csa->S_ind, csa->P); + } + else if (csa->parm->ord_alg == GLP_ORD_SYMAMD) + { if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Approximate minimum degree ordering (SYMAMD)...\n") + ; + symamd_ord(m, csa->S_ptr, csa->S_ind, csa->P); + } + else + xassert(csa != csa); + /* S := P*A*A'*P', symbolically */ + xfree(csa->S_ind); + csa->S_ind = adat_symbolic(m, n, csa->P, csa->A_ptr, csa->A_ind, + csa->S_ptr); + csa->S_val = xcalloc(csa->S_ptr[m+1], sizeof(double)); + csa->S_diag = xcalloc(1+m, sizeof(double)); + /* compute Cholesky factorization S = U'*U, symbolically */ + if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Computing Cholesky factorization S = L*L'...\n"); + csa->U_ptr = xcalloc(1+m+1, sizeof(int)); + csa->U_ind = chol_symbolic(m, csa->S_ptr, csa->S_ind, csa->U_ptr); + if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Matrix L has %d non-zeros\n", csa->U_ptr[m+1]-1 + m); + csa->U_val = xcalloc(csa->U_ptr[m+1], sizeof(double)); + csa->U_diag = xcalloc(1+m, sizeof(double)); + csa->iter = 0; + csa->obj = 0.0; + csa->rpi = 0.0; + csa->rdi = 0.0; + csa->gap = 0.0; + csa->phi = 0.0; + csa->mu = 0.0; + csa->rmu = 0.0; + csa->rmu0 = 0.0; + csa->phi_min = xcalloc(1+ITER_MAX, sizeof(double)); + csa->best_iter = 0; + csa->best_x = xcalloc(1+n, sizeof(double)); + csa->best_y = xcalloc(1+m, sizeof(double)); + csa->best_z = xcalloc(1+n, sizeof(double)); + csa->best_obj = 0.0; + csa->dx_aff = xcalloc(1+n, sizeof(double)); + csa->dy_aff = xcalloc(1+m, sizeof(double)); + csa->dz_aff = xcalloc(1+n, sizeof(double)); + csa->alfa_aff_p = 0.0; + csa->alfa_aff_d = 0.0; + csa->mu_aff = 0.0; + csa->sigma = 0.0; + csa->dx_cc = xcalloc(1+n, sizeof(double)); + csa->dy_cc = xcalloc(1+m, sizeof(double)); + csa->dz_cc = xcalloc(1+n, sizeof(double)); + csa->dx = csa->dx_aff; + csa->dy = csa->dy_aff; + csa->dz = csa->dz_aff; + csa->alfa_max_p = 0.0; + csa->alfa_max_d = 0.0; + return; +} + +/*********************************************************************** +* A_by_vec - compute y = A*x +* +* This routine computes matrix-vector product y = A*x, where A is the +* constraint matrix. */ + +static void A_by_vec(struct csa *csa, double x[], double y[]) +{ /* compute y = A*x */ + int m = csa->m; + int *A_ptr = csa->A_ptr; + int *A_ind = csa->A_ind; + double *A_val = csa->A_val; + int i, t, beg, end; + double temp; + for (i = 1; i <= m; i++) + { temp = 0.0; + beg = A_ptr[i], end = A_ptr[i+1]; + for (t = beg; t < end; t++) temp += A_val[t] * x[A_ind[t]]; + y[i] = temp; + } + return; +} + +/*********************************************************************** +* AT_by_vec - compute y = A'*x +* +* This routine computes matrix-vector product y = A'*x, where A' is a +* matrix transposed to the constraint matrix A. */ + +static void AT_by_vec(struct csa *csa, double x[], double y[]) +{ /* compute y = A'*x, where A' is transposed to A */ + int m = csa->m; + int n = csa->n; + int *A_ptr = csa->A_ptr; + int *A_ind = csa->A_ind; + double *A_val = csa->A_val; + int i, j, t, beg, end; + double temp; + for (j = 1; j <= n; j++) y[j] = 0.0; + for (i = 1; i <= m; i++) + { temp = x[i]; + if (temp == 0.0) continue; + beg = A_ptr[i], end = A_ptr[i+1]; + for (t = beg; t < end; t++) y[A_ind[t]] += A_val[t] * temp; + } + return; +} + +/*********************************************************************** +* decomp_NE - numeric factorization of matrix S = P*A*D*A'*P' +* +* This routine implements numeric phase of Cholesky factorization of +* the matrix S = P*A*D*A'*P', which is a permuted matrix of the normal +* equation system. Matrix D is assumed to be already computed. */ + +static void decomp_NE(struct csa *csa) +{ adat_numeric(csa->m, csa->n, csa->P, csa->A_ptr, csa->A_ind, + csa->A_val, csa->D, csa->S_ptr, csa->S_ind, csa->S_val, + csa->S_diag); + chol_numeric(csa->m, csa->S_ptr, csa->S_ind, csa->S_val, + csa->S_diag, csa->U_ptr, csa->U_ind, csa->U_val, csa->U_diag); + return; +} + +/*********************************************************************** +* solve_NE - solve normal equation system +* +* This routine solves the normal equation system: +* +* A*D*A'*y = h. +* +* It is assumed that the matrix A*D*A' has been previously factorized +* by the routine decomp_NE. +* +* On entry the array y contains the vector of right-hand sides h. On +* exit this array contains the computed vector of unknowns y. +* +* Once the vector y has been computed the routine checks for numeric +* stability. If the residual vector: +* +* r = A*D*A'*y - h +* +* is relatively small, the routine returns zero, otherwise non-zero is +* returned. */ + +static int solve_NE(struct csa *csa, double y[]) +{ int m = csa->m; + int n = csa->n; + int *P = csa->P; + int i, j, ret = 0; + double *h, *r, *w; + /* save vector of right-hand sides h */ + h = xcalloc(1+m, sizeof(double)); + for (i = 1; i <= m; i++) h[i] = y[i]; + /* solve normal equation system (A*D*A')*y = h */ + /* since S = P*A*D*A'*P' = U'*U, then A*D*A' = P'*U'*U*P, so we + have inv(A*D*A') = P'*inv(U)*inv(U')*P */ + /* w := P*h */ + w = xcalloc(1+m, sizeof(double)); + for (i = 1; i <= m; i++) w[i] = y[P[i]]; + /* w := inv(U')*w */ + ut_solve(m, csa->U_ptr, csa->U_ind, csa->U_val, csa->U_diag, w); + /* w := inv(U)*w */ + u_solve(m, csa->U_ptr, csa->U_ind, csa->U_val, csa->U_diag, w); + /* y := P'*w */ + for (i = 1; i <= m; i++) y[i] = w[P[m+i]]; + xfree(w); + /* compute residual vector r = A*D*A'*y - h */ + r = xcalloc(1+m, sizeof(double)); + /* w := A'*y */ + w = xcalloc(1+n, sizeof(double)); + AT_by_vec(csa, y, w); + /* w := D*w */ + for (j = 1; j <= n; j++) w[j] *= csa->D[j]; + /* r := A*w */ + A_by_vec(csa, w, r); + xfree(w); + /* r := r - h */ + for (i = 1; i <= m; i++) r[i] -= h[i]; + /* check for numeric stability */ + for (i = 1; i <= m; i++) + { if (fabs(r[i]) / (1.0 + fabs(h[i])) > 1e-4) + { ret = 1; + break; + } + } + xfree(h); + xfree(r); + return ret; +} + +/*********************************************************************** +* solve_NS - solve Newtonian system +* +* This routine solves the Newtonian system: +* +* A*dx = p +* +* A'*dy + dz = q +* +* Z*dx + X*dz = r +* +* where X = diag(x[j]), Z = diag(z[j]), by reducing it to the normal +* equation system: +* +* (A*inv(Z)*X*A')*dy = A*inv(Z)*(X*q-r)+p +* +* (it is assumed that the matrix A*inv(Z)*X*A' has been factorized by +* the routine decomp_NE). +* +* Once vector dy has been computed the routine computes vectors dx and +* dz as follows: +* +* dx = inv(Z)*(X*(A'*dy-q)+r) +* +* dz = inv(X)*(r-Z*dx) +* +* The routine solve_NS returns the same code which was reported by the +* routine solve_NE (see above). */ + +static int solve_NS(struct csa *csa, double p[], double q[], double r[], + double dx[], double dy[], double dz[]) +{ int m = csa->m; + int n = csa->n; + double *x = csa->x; + double *z = csa->z; + int i, j, ret; + double *w = dx; + /* compute the vector of right-hand sides A*inv(Z)*(X*q-r)+p for + the normal equation system */ + for (j = 1; j <= n; j++) + w[j] = (x[j] * q[j] - r[j]) / z[j]; + A_by_vec(csa, w, dy); + for (i = 1; i <= m; i++) dy[i] += p[i]; + /* solve the normal equation system to compute vector dy */ + ret = solve_NE(csa, dy); + /* compute vectors dx and dz */ + AT_by_vec(csa, dy, dx); + for (j = 1; j <= n; j++) + { dx[j] = (x[j] * (dx[j] - q[j]) + r[j]) / z[j]; + dz[j] = (r[j] - z[j] * dx[j]) / x[j]; + } + return ret; +} + +/*********************************************************************** +* initial_point - choose initial point using Mehrotra's heuristic +* +* This routine chooses a starting point using a heuristic proposed in +* the paper: +* +* S. Mehrotra. On the implementation of a primal-dual interior point +* method. SIAM J. on Optim., 2(4), pp. 575-601, 1992. +* +* The starting point x in the primal space is chosen as a solution of +* the following least squares problem: +* +* minimize ||x|| +* +* subject to A*x = b +* +* which can be computed explicitly as follows: +* +* x = A'*inv(A*A')*b +* +* Similarly, the starting point (y, z) in the dual space is chosen as +* a solution of the following least squares problem: +* +* minimize ||z|| +* +* subject to A'*y + z = c +* +* which can be computed explicitly as follows: +* +* y = inv(A*A')*A*c +* +* z = c - A'*y +* +* However, some components of the vectors x and z may be non-positive +* or close to zero, so the routine uses a Mehrotra's heuristic to find +* a more appropriate starting point. */ + +static void initial_point(struct csa *csa) +{ int m = csa->m; + int n = csa->n; + double *b = csa->b; + double *c = csa->c; + double *x = csa->x; + double *y = csa->y; + double *z = csa->z; + double *D = csa->D; + int i, j; + double dp, dd, ex, ez, xz; + /* factorize A*A' */ + for (j = 1; j <= n; j++) D[j] = 1.0; + decomp_NE(csa); + /* x~ = A'*inv(A*A')*b */ + for (i = 1; i <= m; i++) y[i] = b[i]; + solve_NE(csa, y); + AT_by_vec(csa, y, x); + /* y~ = inv(A*A')*A*c */ + A_by_vec(csa, c, y); + solve_NE(csa, y); + /* z~ = c - A'*y~ */ + AT_by_vec(csa, y,z); + for (j = 1; j <= n; j++) z[j] = c[j] - z[j]; + /* use Mehrotra's heuristic in order to choose more appropriate + starting point with positive components of vectors x and z */ + dp = dd = 0.0; + for (j = 1; j <= n; j++) + { if (dp < -1.5 * x[j]) dp = -1.5 * x[j]; + if (dd < -1.5 * z[j]) dd = -1.5 * z[j]; + } + /* note that b = 0 involves x = 0, and c = 0 involves y = 0 and + z = 0, so we need to be careful */ + if (dp == 0.0) dp = 1.5; + if (dd == 0.0) dd = 1.5; + ex = ez = xz = 0.0; + for (j = 1; j <= n; j++) + { ex += (x[j] + dp); + ez += (z[j] + dd); + xz += (x[j] + dp) * (z[j] + dd); + } + dp += 0.5 * (xz / ez); + dd += 0.5 * (xz / ex); + for (j = 1; j <= n; j++) + { x[j] += dp; + z[j] += dd; + xassert(x[j] > 0.0 && z[j] > 0.0); + } + return; +} + +/*********************************************************************** +* basic_info - perform basic computations at the current point +* +* This routine computes the following quantities at the current point: +* +* 1) value of the objective function: +* +* F = c'*x + c[0] +* +* 2) relative primal infeasibility: +* +* rpi = ||A*x-b|| / (1+||b||) +* +* 3) relative dual infeasibility: +* +* rdi = ||A'*y+z-c|| / (1+||c||) +* +* 4) primal-dual gap (relative difference between the primal and the +* dual objective function values): +* +* gap = |c'*x-b'*y| / (1+|c'*x|) +* +* 5) merit function: +* +* phi = ||A*x-b|| / max(1,||b||) + ||A'*y+z-c|| / max(1,||c||) + +* +* + |c'*x-b'*y| / max(1,||b||,||c||) +* +* 6) duality measure: +* +* mu = x'*z / n +* +* 7) the ratio of infeasibility to mu: +* +* rmu = max(||A*x-b||,||A'*y+z-c||) / mu +* +* where ||*|| denotes euclidian norm, *' denotes transposition. */ + +static void basic_info(struct csa *csa) +{ int m = csa->m; + int n = csa->n; + double *b = csa->b; + double *c = csa->c; + double *x = csa->x; + double *y = csa->y; + double *z = csa->z; + int i, j; + double norm1, bnorm, norm2, cnorm, cx, by, *work, temp; + /* compute value of the objective function */ + temp = c[0]; + for (j = 1; j <= n; j++) temp += c[j] * x[j]; + csa->obj = temp; + /* norm1 = ||A*x-b|| */ + work = xcalloc(1+m, sizeof(double)); + A_by_vec(csa, x, work); + norm1 = 0.0; + for (i = 1; i <= m; i++) + norm1 += (work[i] - b[i]) * (work[i] - b[i]); + norm1 = sqrt(norm1); + xfree(work); + /* bnorm = ||b|| */ + bnorm = 0.0; + for (i = 1; i <= m; i++) bnorm += b[i] * b[i]; + bnorm = sqrt(bnorm); + /* compute relative primal infeasibility */ + csa->rpi = norm1 / (1.0 + bnorm); + /* norm2 = ||A'*y+z-c|| */ + work = xcalloc(1+n, sizeof(double)); + AT_by_vec(csa, y, work); + norm2 = 0.0; + for (j = 1; j <= n; j++) + norm2 += (work[j] + z[j] - c[j]) * (work[j] + z[j] - c[j]); + norm2 = sqrt(norm2); + xfree(work); + /* cnorm = ||c|| */ + cnorm = 0.0; + for (j = 1; j <= n; j++) cnorm += c[j] * c[j]; + cnorm = sqrt(cnorm); + /* compute relative dual infeasibility */ + csa->rdi = norm2 / (1.0 + cnorm); + /* by = b'*y */ + by = 0.0; + for (i = 1; i <= m; i++) by += b[i] * y[i]; + /* cx = c'*x */ + cx = 0.0; + for (j = 1; j <= n; j++) cx += c[j] * x[j]; + /* compute primal-dual gap */ + csa->gap = fabs(cx - by) / (1.0 + fabs(cx)); + /* compute merit function */ + csa->phi = 0.0; + csa->phi += norm1 / (bnorm > 1.0 ? bnorm : 1.0); + csa->phi += norm2 / (cnorm > 1.0 ? cnorm : 1.0); + temp = 1.0; + if (temp < bnorm) temp = bnorm; + if (temp < cnorm) temp = cnorm; + csa->phi += fabs(cx - by) / temp; + /* compute duality measure */ + temp = 0.0; + for (j = 1; j <= n; j++) temp += x[j] * z[j]; + csa->mu = temp / (double)n; + /* compute the ratio of infeasibility to mu */ + csa->rmu = (norm1 > norm2 ? norm1 : norm2) / csa->mu; + return; +} + +/*********************************************************************** +* make_step - compute next point using Mehrotra's technique +* +* This routine computes the next point using the predictor-corrector +* technique proposed in the paper: +* +* S. Mehrotra. On the implementation of a primal-dual interior point +* method. SIAM J. on Optim., 2(4), pp. 575-601, 1992. +* +* At first, the routine computes so called affine scaling (predictor) +* direction (dx_aff,dy_aff,dz_aff) which is a solution of the system: +* +* A*dx_aff = b - A*x +* +* A'*dy_aff + dz_aff = c - A'*y - z +* +* Z*dx_aff + X*dz_aff = - X*Z*e +* +* where (x,y,z) is the current point, X = diag(x[j]), Z = diag(z[j]), +* e = (1,...,1)'. +* +* Then, the routine computes the centering parameter sigma, using the +* following Mehrotra's heuristic: +* +* alfa_aff_p = inf{0 <= alfa <= 1 | x+alfa*dx_aff >= 0} +* +* alfa_aff_d = inf{0 <= alfa <= 1 | z+alfa*dz_aff >= 0} +* +* mu_aff = (x+alfa_aff_p*dx_aff)'*(z+alfa_aff_d*dz_aff)/n +* +* sigma = (mu_aff/mu)^3 +* +* where alfa_aff_p is the maximal stepsize along the affine scaling +* direction in the primal space, alfa_aff_d is the maximal stepsize +* along the same direction in the dual space. +* +* After determining sigma the routine computes so called centering +* (corrector) direction (dx_cc,dy_cc,dz_cc) which is the solution of +* the system: +* +* A*dx_cc = 0 +* +* A'*dy_cc + dz_cc = 0 +* +* Z*dx_cc + X*dz_cc = sigma*mu*e - X*Z*e +* +* Finally, the routine computes the combined direction +* +* (dx,dy,dz) = (dx_aff,dy_aff,dz_aff) + (dx_cc,dy_cc,dz_cc) +* +* and determines maximal primal and dual stepsizes along the combined +* direction: +* +* alfa_max_p = inf{0 <= alfa <= 1 | x+alfa*dx >= 0} +* +* alfa_max_d = inf{0 <= alfa <= 1 | z+alfa*dz >= 0} +* +* In order to prevent the next point to be too close to the boundary +* of the positive ortant, the routine decreases maximal stepsizes: +* +* alfa_p = gamma_p * alfa_max_p +* +* alfa_d = gamma_d * alfa_max_d +* +* where gamma_p and gamma_d are scaling factors, and computes the next +* point: +* +* x_new = x + alfa_p * dx +* +* y_new = y + alfa_d * dy +* +* z_new = z + alfa_d * dz +* +* which becomes the current point on the next iteration. */ + +static int make_step(struct csa *csa) +{ int m = csa->m; + int n = csa->n; + double *b = csa->b; + double *c = csa->c; + double *x = csa->x; + double *y = csa->y; + double *z = csa->z; + double *dx_aff = csa->dx_aff; + double *dy_aff = csa->dy_aff; + double *dz_aff = csa->dz_aff; + double *dx_cc = csa->dx_cc; + double *dy_cc = csa->dy_cc; + double *dz_cc = csa->dz_cc; + double *dx = csa->dx; + double *dy = csa->dy; + double *dz = csa->dz; + int i, j, ret = 0; + double temp, gamma_p, gamma_d, *p, *q, *r; + /* allocate working arrays */ + p = xcalloc(1+m, sizeof(double)); + q = xcalloc(1+n, sizeof(double)); + r = xcalloc(1+n, sizeof(double)); + /* p = b - A*x */ + A_by_vec(csa, x, p); + for (i = 1; i <= m; i++) p[i] = b[i] - p[i]; + /* q = c - A'*y - z */ + AT_by_vec(csa, y,q); + for (j = 1; j <= n; j++) q[j] = c[j] - q[j] - z[j]; + /* r = - X * Z * e */ + for (j = 1; j <= n; j++) r[j] = - x[j] * z[j]; + /* solve the first Newtonian system */ + if (solve_NS(csa, p, q, r, dx_aff, dy_aff, dz_aff)) + { ret = 1; + goto done; + } + /* alfa_aff_p = inf{0 <= alfa <= 1 | x + alfa*dx_aff >= 0} */ + /* alfa_aff_d = inf{0 <= alfa <= 1 | z + alfa*dz_aff >= 0} */ + csa->alfa_aff_p = csa->alfa_aff_d = 1.0; + for (j = 1; j <= n; j++) + { if (dx_aff[j] < 0.0) + { temp = - x[j] / dx_aff[j]; + if (csa->alfa_aff_p > temp) csa->alfa_aff_p = temp; + } + if (dz_aff[j] < 0.0) + { temp = - z[j] / dz_aff[j]; + if (csa->alfa_aff_d > temp) csa->alfa_aff_d = temp; + } + } + /* mu_aff = (x+alfa_aff_p*dx_aff)' * (z+alfa_aff_d*dz_aff) / n */ + temp = 0.0; + for (j = 1; j <= n; j++) + temp += (x[j] + csa->alfa_aff_p * dx_aff[j]) * + (z[j] + csa->alfa_aff_d * dz_aff[j]); + csa->mu_aff = temp / (double)n; + /* sigma = (mu_aff/mu)^3 */ + temp = csa->mu_aff / csa->mu; + csa->sigma = temp * temp * temp; + /* p = 0 */ + for (i = 1; i <= m; i++) p[i] = 0.0; + /* q = 0 */ + for (j = 1; j <= n; j++) q[j] = 0.0; + /* r = sigma * mu * e - X * Z * e */ + for (j = 1; j <= n; j++) + r[j] = csa->sigma * csa->mu - dx_aff[j] * dz_aff[j]; + /* solve the second Newtonian system with the same coefficients + but with altered right-hand sides */ + if (solve_NS(csa, p, q, r, dx_cc, dy_cc, dz_cc)) + { ret = 1; + goto done; + } + /* (dx,dy,dz) = (dx_aff,dy_aff,dz_aff) + (dx_cc,dy_cc,dz_cc) */ + for (j = 1; j <= n; j++) dx[j] = dx_aff[j] + dx_cc[j]; + for (i = 1; i <= m; i++) dy[i] = dy_aff[i] + dy_cc[i]; + for (j = 1; j <= n; j++) dz[j] = dz_aff[j] + dz_cc[j]; + /* alfa_max_p = inf{0 <= alfa <= 1 | x + alfa*dx >= 0} */ + /* alfa_max_d = inf{0 <= alfa <= 1 | z + alfa*dz >= 0} */ + csa->alfa_max_p = csa->alfa_max_d = 1.0; + for (j = 1; j <= n; j++) + { if (dx[j] < 0.0) + { temp = - x[j] / dx[j]; + if (csa->alfa_max_p > temp) csa->alfa_max_p = temp; + } + if (dz[j] < 0.0) + { temp = - z[j] / dz[j]; + if (csa->alfa_max_d > temp) csa->alfa_max_d = temp; + } + } + /* determine scale factors (not implemented yet) */ + gamma_p = 0.90; + gamma_d = 0.90; + /* compute the next point */ + for (j = 1; j <= n; j++) + { x[j] += gamma_p * csa->alfa_max_p * dx[j]; + xassert(x[j] > 0.0); + } + for (i = 1; i <= m; i++) + y[i] += gamma_d * csa->alfa_max_d * dy[i]; + for (j = 1; j <= n; j++) + { z[j] += gamma_d * csa->alfa_max_d * dz[j]; + xassert(z[j] > 0.0); + } +done: /* free working arrays */ + xfree(p); + xfree(q); + xfree(r); + return ret; +} + +/*********************************************************************** +* terminate - deallocate common storage area +* +* This routine frees all memory allocated to the common storage area +* used by interior-point method routines. */ + +static void terminate(struct csa *csa) +{ xfree(csa->D); + xfree(csa->P); + xfree(csa->S_ptr); + xfree(csa->S_ind); + xfree(csa->S_val); + xfree(csa->S_diag); + xfree(csa->U_ptr); + xfree(csa->U_ind); + xfree(csa->U_val); + xfree(csa->U_diag); + xfree(csa->phi_min); + xfree(csa->best_x); + xfree(csa->best_y); + xfree(csa->best_z); + xfree(csa->dx_aff); + xfree(csa->dy_aff); + xfree(csa->dz_aff); + xfree(csa->dx_cc); + xfree(csa->dy_cc); + xfree(csa->dz_cc); + return; +} + +/*********************************************************************** +* ipm_main - main interior-point method routine +* +* This is a main routine of the primal-dual interior-point method. +* +* The routine ipm_main returns one of the following codes: +* +* 0 - optimal solution found; +* 1 - problem has no feasible (primal or dual) solution; +* 2 - no convergence; +* 3 - iteration limit exceeded; +* 4 - numeric instability on solving Newtonian system. +* +* In case of non-zero return code the routine returns the best point, +* which has been reached during optimization. */ + +static int ipm_main(struct csa *csa) +{ int m = csa->m; + int n = csa->n; + int i, j, status; + double temp; + /* choose initial point using Mehrotra's heuristic */ + if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Guessing initial point...\n"); + initial_point(csa); + /* main loop starts here */ + if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Optimization begins...\n"); + for (;;) + { /* perform basic computations at the current point */ + basic_info(csa); + /* save initial value of rmu */ + if (csa->iter == 0) csa->rmu0 = csa->rmu; + /* accumulate values of min(phi[k]) and save the best point */ + xassert(csa->iter <= ITER_MAX); + if (csa->iter == 0 || csa->phi_min[csa->iter-1] > csa->phi) + { csa->phi_min[csa->iter] = csa->phi; + csa->best_iter = csa->iter; + for (j = 1; j <= n; j++) csa->best_x[j] = csa->x[j]; + for (i = 1; i <= m; i++) csa->best_y[i] = csa->y[i]; + for (j = 1; j <= n; j++) csa->best_z[j] = csa->z[j]; + csa->best_obj = csa->obj; + } + else + csa->phi_min[csa->iter] = csa->phi_min[csa->iter-1]; + /* display information at the current point */ + if (csa->parm->msg_lev >= GLP_MSG_ON) + xprintf("%3d: obj = %17.9e; rpi = %8.1e; rdi = %8.1e; gap =" + " %8.1e\n", csa->iter, csa->obj, csa->rpi, csa->rdi, + csa->gap); + /* check if the current point is optimal */ + if (csa->rpi < 1e-8 && csa->rdi < 1e-8 && csa->gap < 1e-8) + { if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("OPTIMAL SOLUTION FOUND\n"); + status = 0; + break; + } + /* check if the problem has no feasible solution */ + temp = 1e5 * csa->phi_min[csa->iter]; + if (temp < 1e-8) temp = 1e-8; + if (csa->phi >= temp) + { if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("PROBLEM HAS NO FEASIBLE PRIMAL/DUAL SOLUTION\n") + ; + status = 1; + break; + } + /* check for very slow convergence or divergence */ + if (((csa->rpi >= 1e-8 || csa->rdi >= 1e-8) && csa->rmu / + csa->rmu0 >= 1e6) || + (csa->iter >= 30 && csa->phi_min[csa->iter] >= 0.5 * + csa->phi_min[csa->iter - 30])) + { if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("NO CONVERGENCE; SEARCH TERMINATED\n"); + status = 2; + break; + } + /* check for maximal number of iterations */ + if (csa->iter == ITER_MAX) + { if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("ITERATION LIMIT EXCEEDED; SEARCH TERMINATED\n"); + status = 3; + break; + } + /* start the next iteration */ + csa->iter++; + /* factorize normal equation system */ + for (j = 1; j <= n; j++) csa->D[j] = csa->x[j] / csa->z[j]; + decomp_NE(csa); + /* compute the next point using Mehrotra's predictor-corrector + technique */ + if (make_step(csa)) + { if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("NUMERIC INSTABILITY; SEARCH TERMINATED\n"); + status = 4; + break; + } + } + /* restore the best point */ + if (status != 0) + { for (j = 1; j <= n; j++) csa->x[j] = csa->best_x[j]; + for (i = 1; i <= m; i++) csa->y[i] = csa->best_y[i]; + for (j = 1; j <= n; j++) csa->z[j] = csa->best_z[j]; + if (csa->parm->msg_lev >= GLP_MSG_ALL) + xprintf("Best point %17.9e was reached on iteration %d\n", + csa->best_obj, csa->best_iter); + } + /* return to the calling program */ + return status; +} + +/*********************************************************************** +* NAME +* +* ipm_solve - core LP solver based on the interior-point method +* +* SYNOPSIS +* +* #include "glpipm.h" +* int ipm_solve(glp_prob *P, const glp_iptcp *parm); +* +* DESCRIPTION +* +* The routine ipm_solve is a core LP solver based on the primal-dual +* interior-point method. +* +* The routine assumes the following standard formulation of LP problem +* to be solved: +* +* minimize +* +* F = c[0] + c[1]*x[1] + c[2]*x[2] + ... + c[n]*x[n] +* +* subject to linear constraints +* +* a[1,1]*x[1] + a[1,2]*x[2] + ... + a[1,n]*x[n] = b[1] +* +* a[2,1]*x[1] + a[2,2]*x[2] + ... + a[2,n]*x[n] = b[2] +* +* . . . . . . +* +* a[m,1]*x[1] + a[m,2]*x[2] + ... + a[m,n]*x[n] = b[m] +* +* and non-negative variables +* +* x[1] >= 0, x[2] >= 0, ..., x[n] >= 0 +* +* where: +* F is the objective function; +* x[1], ..., x[n] are (structural) variables; +* c[0] is a constant term of the objective function; +* c[1], ..., c[n] are objective coefficients; +* a[1,1], ..., a[m,n] are constraint coefficients; +* b[1], ..., b[n] are right-hand sides. +* +* The solution is three vectors x, y, and z, which are stored by the +* routine in the arrays x, y, and z, respectively. These vectors +* correspond to the best primal-dual point found during optimization. +* They are approximate solution of the following system (which is the +* Karush-Kuhn-Tucker optimality conditions): +* +* A*x = b (primal feasibility condition) +* +* A'*y + z = c (dual feasibility condition) +* +* x'*z = 0 (primal-dual complementarity condition) +* +* x >= 0, z >= 0 (non-negativity condition) +* +* where: +* x[1], ..., x[n] are primal (structural) variables; +* y[1], ..., y[m] are dual variables (Lagrange multipliers) for +* equality constraints; +* z[1], ..., z[n] are dual variables (Lagrange multipliers) for +* non-negativity constraints. +* +* RETURNS +* +* 0 LP has been successfully solved. +* +* GLP_ENOCVG +* No convergence. +* +* GLP_EITLIM +* Iteration limit exceeded. +* +* GLP_EINSTAB +* Numeric instability on solving Newtonian system. +* +* In case of non-zero return code the routine returns the best point, +* which has been reached during optimization. */ + +int ipm_solve(glp_prob *P, const glp_iptcp *parm) +{ struct csa _dsa, *csa = &_dsa; + int m = P->m; + int n = P->n; + int nnz = P->nnz; + GLPROW *row; + GLPCOL *col; + GLPAIJ *aij; + int i, j, loc, ret, *A_ind, *A_ptr; + double dir, *A_val, *b, *c, *x, *y, *z; + xassert(m > 0); + xassert(n > 0); + /* allocate working arrays */ + A_ptr = xcalloc(1+m+1, sizeof(int)); + A_ind = xcalloc(1+nnz, sizeof(int)); + A_val = xcalloc(1+nnz, sizeof(double)); + b = xcalloc(1+m, sizeof(double)); + c = xcalloc(1+n, sizeof(double)); + x = xcalloc(1+n, sizeof(double)); + y = xcalloc(1+m, sizeof(double)); + z = xcalloc(1+n, sizeof(double)); + /* prepare rows and constraint coefficients */ + loc = 1; + for (i = 1; i <= m; i++) + { row = P->row[i]; + xassert(row->type == GLP_FX); + b[i] = row->lb * row->rii; + A_ptr[i] = loc; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { A_ind[loc] = aij->col->j; + A_val[loc] = row->rii * aij->val * aij->col->sjj; + loc++; + } + } + A_ptr[m+1] = loc; + xassert(loc-1 == nnz); + /* prepare columns and objective coefficients */ + if (P->dir == GLP_MIN) + dir = +1.0; + else if (P->dir == GLP_MAX) + dir = -1.0; + else + xassert(P != P); + c[0] = dir * P->c0; + for (j = 1; j <= n; j++) + { col = P->col[j]; + xassert(col->type == GLP_LO && col->lb == 0.0); + c[j] = dir * col->coef * col->sjj; + } + /* allocate and initialize the common storage area */ + csa->m = m; + csa->n = n; + csa->A_ptr = A_ptr; + csa->A_ind = A_ind; + csa->A_val = A_val; + csa->b = b; + csa->c = c; + csa->x = x; + csa->y = y; + csa->z = z; + csa->parm = parm; + initialize(csa); + /* solve LP with the interior-point method */ + ret = ipm_main(csa); + /* deallocate the common storage area */ + terminate(csa); + /* determine solution status */ + if (ret == 0) + { /* optimal solution found */ + P->ipt_stat = GLP_OPT; + ret = 0; + } + else if (ret == 1) + { /* problem has no feasible (primal or dual) solution */ + P->ipt_stat = GLP_NOFEAS; + ret = 0; + } + else if (ret == 2) + { /* no convergence */ + P->ipt_stat = GLP_INFEAS; + ret = GLP_ENOCVG; + } + else if (ret == 3) + { /* iteration limit exceeded */ + P->ipt_stat = GLP_INFEAS; + ret = GLP_EITLIM; + } + else if (ret == 4) + { /* numeric instability on solving Newtonian system */ + P->ipt_stat = GLP_INFEAS; + ret = GLP_EINSTAB; + } + else + xassert(ret != ret); + /* store row solution components */ + for (i = 1; i <= m; i++) + { row = P->row[i]; + row->pval = row->lb; + row->dval = dir * y[i] * row->rii; + } + /* store column solution components */ + P->ipt_obj = P->c0; + for (j = 1; j <= n; j++) + { col = P->col[j]; + col->pval = x[j] * col->sjj; + col->dval = dir * z[j] / col->sjj; + P->ipt_obj += col->coef * col->pval; + } + /* free working arrays */ + xfree(A_ptr); + xfree(A_ind); + xfree(A_val); + xfree(b); + xfree(c); + xfree(x); + xfree(y); + xfree(z); + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpipm.h b/resources/3rdparty/glpk-4.57/src/glpipm.h new file mode 100644 index 000000000..a5f94fec1 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpipm.h @@ -0,0 +1,36 @@ +/* glpipm.h (primal-dual interior-point method) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef GLPIPM_H +#define GLPIPM_H + +#include "prob.h" + +#define ipm_solve _glp_ipm_solve +int ipm_solve(glp_prob *P, const glp_iptcp *parm); +/* core LP solver based on the interior-point method */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpk.h b/resources/3rdparty/glpk-4.57/src/glpk.h new file mode 100644 index 000000000..ed5be77fc --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpk.h @@ -0,0 +1,1080 @@ +/* glpk.h (GLPK API) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013, 2014, 2015 Andrew Makhorin, Department for +* Applied Informatics, Moscow Aviation Institute, Moscow, Russia. All +* rights reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef GLPK_H +#define GLPK_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* library version numbers: */ +#define GLP_MAJOR_VERSION 4 +#define GLP_MINOR_VERSION 57 + +typedef struct glp_prob glp_prob; +/* LP/MIP problem object */ + +/* optimization direction flag: */ +#define GLP_MIN 1 /* minimization */ +#define GLP_MAX 2 /* maximization */ + +/* kind of structural variable: */ +#define GLP_CV 1 /* continuous variable */ +#define GLP_IV 2 /* integer variable */ +#define GLP_BV 3 /* binary variable */ + +/* type of auxiliary/structural variable: */ +#define GLP_FR 1 /* free (unbounded) variable */ +#define GLP_LO 2 /* variable with lower bound */ +#define GLP_UP 3 /* variable with upper bound */ +#define GLP_DB 4 /* double-bounded variable */ +#define GLP_FX 5 /* fixed variable */ + +/* status of auxiliary/structural variable: */ +#define GLP_BS 1 /* basic variable */ +#define GLP_NL 2 /* non-basic variable on lower bound */ +#define GLP_NU 3 /* non-basic variable on upper bound */ +#define GLP_NF 4 /* non-basic free (unbounded) variable */ +#define GLP_NS 5 /* non-basic fixed variable */ + +/* scaling options: */ +#define GLP_SF_GM 0x01 /* perform geometric mean scaling */ +#define GLP_SF_EQ 0x10 /* perform equilibration scaling */ +#define GLP_SF_2N 0x20 /* round scale factors to power of two */ +#define GLP_SF_SKIP 0x40 /* skip if problem is well scaled */ +#define GLP_SF_AUTO 0x80 /* choose scaling options automatically */ + +/* solution indicator: */ +#define GLP_SOL 1 /* basic solution */ +#define GLP_IPT 2 /* interior-point solution */ +#define GLP_MIP 3 /* mixed integer solution */ + +/* solution status: */ +#define GLP_UNDEF 1 /* solution is undefined */ +#define GLP_FEAS 2 /* solution is feasible */ +#define GLP_INFEAS 3 /* solution is infeasible */ +#define GLP_NOFEAS 4 /* no feasible solution exists */ +#define GLP_OPT 5 /* solution is optimal */ +#define GLP_UNBND 6 /* solution is unbounded */ + +typedef struct +{ /* basis factorization control parameters */ + int msg_lev; /* (not used) */ + int type; /* factorization type: */ +#if 1 /* 05/III-2014 */ +#define GLP_BF_LUF 0x00 /* plain LU-factorization */ +#define GLP_BF_BTF 0x10 /* block triangular LU-factorization */ +#endif +#define GLP_BF_FT 0x01 /* Forrest-Tomlin (LUF only) */ +#define GLP_BF_BG 0x02 /* Schur compl. + Bartels-Golub */ +#define GLP_BF_GR 0x03 /* Schur compl. + Givens rotation */ + int lu_size; /* (not used) */ + double piv_tol; /* sgf_piv_tol */ + int piv_lim; /* sgf_piv_lim */ + int suhl; /* sgf_suhl */ + double eps_tol; /* sgf_eps_tol */ + double max_gro; /* (not used) */ + int nfs_max; /* fhvint.nfs_max */ + double upd_tol; /* (not used) */ + int nrs_max; /* scfint.nn_max */ + int rs_size; /* (not used) */ + double foo_bar[38]; /* (reserved) */ +} glp_bfcp; + +typedef struct +{ /* simplex method control parameters */ + int msg_lev; /* message level: */ +#define GLP_MSG_OFF 0 /* no output */ +#define GLP_MSG_ERR 1 /* warning and error messages only */ +#define GLP_MSG_ON 2 /* normal output */ +#define GLP_MSG_ALL 3 /* full output */ +#define GLP_MSG_DBG 4 /* debug output */ + int meth; /* simplex method option: */ +#define GLP_PRIMAL 1 /* use primal simplex */ +#define GLP_DUALP 2 /* use dual; if it fails, use primal */ +#define GLP_DUAL 3 /* use dual simplex */ + int pricing; /* pricing technique: */ +#define GLP_PT_STD 0x11 /* standard (Dantzig's rule) */ +#define GLP_PT_PSE 0x22 /* projected steepest edge */ + int r_test; /* ratio test technique: */ +#define GLP_RT_STD 0x11 /* standard (textbook) */ +#define GLP_RT_HAR 0x22 /* Harris' two-pass ratio test */ + double tol_bnd; /* spx.tol_bnd */ + double tol_dj; /* spx.tol_dj */ + double tol_piv; /* spx.tol_piv */ + double obj_ll; /* spx.obj_ll */ + double obj_ul; /* spx.obj_ul */ + int it_lim; /* spx.it_lim */ + int tm_lim; /* spx.tm_lim (milliseconds) */ + int out_frq; /* spx.out_frq */ + int out_dly; /* spx.out_dly (milliseconds) */ + int presolve; /* enable/disable using LP presolver */ + double foo_bar[36]; /* (reserved) */ +} glp_smcp; + +typedef struct +{ /* interior-point solver control parameters */ + int msg_lev; /* message level (see glp_smcp) */ + int ord_alg; /* ordering algorithm: */ +#define GLP_ORD_NONE 0 /* natural (original) ordering */ +#define GLP_ORD_QMD 1 /* quotient minimum degree (QMD) */ +#define GLP_ORD_AMD 2 /* approx. minimum degree (AMD) */ +#define GLP_ORD_SYMAMD 3 /* approx. minimum degree (SYMAMD) */ + double foo_bar[48]; /* (reserved) */ +} glp_iptcp; + +typedef struct glp_tree glp_tree; +/* branch-and-bound tree */ + +typedef struct +{ /* integer optimizer control parameters */ + int msg_lev; /* message level (see glp_smcp) */ + int br_tech; /* branching technique: */ +#define GLP_BR_FFV 1 /* first fractional variable */ +#define GLP_BR_LFV 2 /* last fractional variable */ +#define GLP_BR_MFV 3 /* most fractional variable */ +#define GLP_BR_DTH 4 /* heuristic by Driebeck and Tomlin */ +#define GLP_BR_PCH 5 /* hybrid pseudocost heuristic */ + int bt_tech; /* backtracking technique: */ +#define GLP_BT_DFS 1 /* depth first search */ +#define GLP_BT_BFS 2 /* breadth first search */ +#define GLP_BT_BLB 3 /* best local bound */ +#define GLP_BT_BPH 4 /* best projection heuristic */ + double tol_int; /* mip.tol_int */ + double tol_obj; /* mip.tol_obj */ + int tm_lim; /* mip.tm_lim (milliseconds) */ + int out_frq; /* mip.out_frq (milliseconds) */ + int out_dly; /* mip.out_dly (milliseconds) */ + void (*cb_func)(glp_tree *T, void *info); + /* mip.cb_func */ + void *cb_info; /* mip.cb_info */ + int cb_size; /* mip.cb_size */ + int pp_tech; /* preprocessing technique: */ +#define GLP_PP_NONE 0 /* disable preprocessing */ +#define GLP_PP_ROOT 1 /* preprocessing only on root level */ +#define GLP_PP_ALL 2 /* preprocessing on all levels */ + double mip_gap; /* relative MIP gap tolerance */ + int mir_cuts; /* MIR cuts (GLP_ON/GLP_OFF) */ + int gmi_cuts; /* Gomory's cuts (GLP_ON/GLP_OFF) */ + int cov_cuts; /* cover cuts (GLP_ON/GLP_OFF) */ + int clq_cuts; /* clique cuts (GLP_ON/GLP_OFF) */ + int presolve; /* enable/disable using MIP presolver */ + int binarize; /* try to binarize integer variables */ + int fp_heur; /* feasibility pump heuristic */ + int ps_heur; /* proximity search heuristic */ + int ps_tm_lim; /* proxy time limit, milliseconds */ + int sr_heur; /* simple rounding heuristic */ +#if 1 /* 24/X-2015; not documented--should not be used */ + int use_sol; /* use existing solution */ + const char *save_sol; /* filename to save every new solution */ + int alien; /* use alien solver */ +#endif + double foo_bar[24]; /* (reserved) */ +} glp_iocp; + +typedef struct +{ /* additional row attributes */ + int level; + /* subproblem level at which the row was added */ + int origin; + /* row origin flag: */ +#define GLP_RF_REG 0 /* regular constraint */ +#define GLP_RF_LAZY 1 /* "lazy" constraint */ +#define GLP_RF_CUT 2 /* cutting plane constraint */ + int klass; + /* row class descriptor: */ +#define GLP_RF_GMI 1 /* Gomory's mixed integer cut */ +#define GLP_RF_MIR 2 /* mixed integer rounding cut */ +#define GLP_RF_COV 3 /* mixed cover cut */ +#define GLP_RF_CLQ 4 /* clique cut */ + double foo_bar[7]; + /* (reserved) */ +} glp_attr; + +/* enable/disable flag: */ +#define GLP_ON 1 /* enable something */ +#define GLP_OFF 0 /* disable something */ + +/* reason codes: */ +#define GLP_IROWGEN 0x01 /* request for row generation */ +#define GLP_IBINGO 0x02 /* better integer solution found */ +#define GLP_IHEUR 0x03 /* request for heuristic solution */ +#define GLP_ICUTGEN 0x04 /* request for cut generation */ +#define GLP_IBRANCH 0x05 /* request for branching */ +#define GLP_ISELECT 0x06 /* request for subproblem selection */ +#define GLP_IPREPRO 0x07 /* request for preprocessing */ + +/* branch selection indicator: */ +#define GLP_NO_BRNCH 0 /* select no branch */ +#define GLP_DN_BRNCH 1 /* select down-branch */ +#define GLP_UP_BRNCH 2 /* select up-branch */ + +/* return codes: */ +#define GLP_EBADB 0x01 /* invalid basis */ +#define GLP_ESING 0x02 /* singular matrix */ +#define GLP_ECOND 0x03 /* ill-conditioned matrix */ +#define GLP_EBOUND 0x04 /* invalid bounds */ +#define GLP_EFAIL 0x05 /* solver failed */ +#define GLP_EOBJLL 0x06 /* objective lower limit reached */ +#define GLP_EOBJUL 0x07 /* objective upper limit reached */ +#define GLP_EITLIM 0x08 /* iteration limit exceeded */ +#define GLP_ETMLIM 0x09 /* time limit exceeded */ +#define GLP_ENOPFS 0x0A /* no primal feasible solution */ +#define GLP_ENODFS 0x0B /* no dual feasible solution */ +#define GLP_EROOT 0x0C /* root LP optimum not provided */ +#define GLP_ESTOP 0x0D /* search terminated by application */ +#define GLP_EMIPGAP 0x0E /* relative mip gap tolerance reached */ +#define GLP_ENOFEAS 0x0F /* no primal/dual feasible solution */ +#define GLP_ENOCVG 0x10 /* no convergence */ +#define GLP_EINSTAB 0x11 /* numerical instability */ +#define GLP_EDATA 0x12 /* invalid data */ +#define GLP_ERANGE 0x13 /* result out of range */ + +/* condition indicator: */ +#define GLP_KKT_PE 1 /* primal equalities */ +#define GLP_KKT_PB 2 /* primal bounds */ +#define GLP_KKT_DE 3 /* dual equalities */ +#define GLP_KKT_DB 4 /* dual bounds */ +#define GLP_KKT_CS 5 /* complementary slackness */ + +/* MPS file format: */ +#define GLP_MPS_DECK 1 /* fixed (ancient) */ +#define GLP_MPS_FILE 2 /* free (modern) */ + +typedef struct +{ /* MPS format control parameters */ + int blank; + /* character code to replace blanks in symbolic names */ + char *obj_name; + /* objective row name */ + double tol_mps; + /* zero tolerance for MPS data */ + double foo_bar[17]; + /* (reserved for use in the future) */ +} glp_mpscp; + +typedef struct +{ /* CPLEX LP format control parameters */ + double foo_bar[20]; + /* (reserved for use in the future) */ +} glp_cpxcp; + +typedef struct glp_tran glp_tran; +/* MathProg translator workspace */ + +glp_prob *glp_create_prob(void); +/* create problem object */ + +void glp_set_prob_name(glp_prob *P, const char *name); +/* assign (change) problem name */ + +void glp_set_obj_name(glp_prob *P, const char *name); +/* assign (change) objective function name */ + +void glp_set_obj_dir(glp_prob *P, int dir); +/* set (change) optimization direction flag */ + +int glp_add_rows(glp_prob *P, int nrs); +/* add new rows to problem object */ + +int glp_add_cols(glp_prob *P, int ncs); +/* add new columns to problem object */ + +void glp_set_row_name(glp_prob *P, int i, const char *name); +/* assign (change) row name */ + +void glp_set_col_name(glp_prob *P, int j, const char *name); +/* assign (change) column name */ + +void glp_set_row_bnds(glp_prob *P, int i, int type, double lb, + double ub); +/* set (change) row bounds */ + +void glp_set_col_bnds(glp_prob *P, int j, int type, double lb, + double ub); +/* set (change) column bounds */ + +void glp_set_obj_coef(glp_prob *P, int j, double coef); +/* set (change) obj. coefficient or constant term */ + +void glp_set_mat_row(glp_prob *P, int i, int len, const int ind[], + const double val[]); +/* set (replace) row of the constraint matrix */ + +void glp_set_mat_col(glp_prob *P, int j, int len, const int ind[], + const double val[]); +/* set (replace) column of the constraint matrix */ + +void glp_load_matrix(glp_prob *P, int ne, const int ia[], + const int ja[], const double ar[]); +/* load (replace) the whole constraint matrix */ + +int glp_check_dup(int m, int n, int ne, const int ia[], const int ja[]); +/* check for duplicate elements in sparse matrix */ + +void glp_sort_matrix(glp_prob *P); +/* sort elements of the constraint matrix */ + +void glp_del_rows(glp_prob *P, int nrs, const int num[]); +/* delete specified rows from problem object */ + +void glp_del_cols(glp_prob *P, int ncs, const int num[]); +/* delete specified columns from problem object */ + +void glp_copy_prob(glp_prob *dest, glp_prob *prob, int names); +/* copy problem object content */ + +void glp_erase_prob(glp_prob *P); +/* erase problem object content */ + +void glp_delete_prob(glp_prob *P); +/* delete problem object */ + +const char *glp_get_prob_name(glp_prob *P); +/* retrieve problem name */ + +const char *glp_get_obj_name(glp_prob *P); +/* retrieve objective function name */ + +int glp_get_obj_dir(glp_prob *P); +/* retrieve optimization direction flag */ + +int glp_get_num_rows(glp_prob *P); +/* retrieve number of rows */ + +int glp_get_num_cols(glp_prob *P); +/* retrieve number of columns */ + +const char *glp_get_row_name(glp_prob *P, int i); +/* retrieve row name */ + +const char *glp_get_col_name(glp_prob *P, int j); +/* retrieve column name */ + +int glp_get_row_type(glp_prob *P, int i); +/* retrieve row type */ + +double glp_get_row_lb(glp_prob *P, int i); +/* retrieve row lower bound */ + +double glp_get_row_ub(glp_prob *P, int i); +/* retrieve row upper bound */ + +int glp_get_col_type(glp_prob *P, int j); +/* retrieve column type */ + +double glp_get_col_lb(glp_prob *P, int j); +/* retrieve column lower bound */ + +double glp_get_col_ub(glp_prob *P, int j); +/* retrieve column upper bound */ + +double glp_get_obj_coef(glp_prob *P, int j); +/* retrieve obj. coefficient or constant term */ + +int glp_get_num_nz(glp_prob *P); +/* retrieve number of constraint coefficients */ + +int glp_get_mat_row(glp_prob *P, int i, int ind[], double val[]); +/* retrieve row of the constraint matrix */ + +int glp_get_mat_col(glp_prob *P, int j, int ind[], double val[]); +/* retrieve column of the constraint matrix */ + +void glp_create_index(glp_prob *P); +/* create the name index */ + +int glp_find_row(glp_prob *P, const char *name); +/* find row by its name */ + +int glp_find_col(glp_prob *P, const char *name); +/* find column by its name */ + +void glp_delete_index(glp_prob *P); +/* delete the name index */ + +void glp_set_rii(glp_prob *P, int i, double rii); +/* set (change) row scale factor */ + +void glp_set_sjj(glp_prob *P, int j, double sjj); +/* set (change) column scale factor */ + +double glp_get_rii(glp_prob *P, int i); +/* retrieve row scale factor */ + +double glp_get_sjj(glp_prob *P, int j); +/* retrieve column scale factor */ + +void glp_scale_prob(glp_prob *P, int flags); +/* scale problem data */ + +void glp_unscale_prob(glp_prob *P); +/* unscale problem data */ + +void glp_set_row_stat(glp_prob *P, int i, int stat); +/* set (change) row status */ + +void glp_set_col_stat(glp_prob *P, int j, int stat); +/* set (change) column status */ + +void glp_std_basis(glp_prob *P); +/* construct standard initial LP basis */ + +void glp_adv_basis(glp_prob *P, int flags); +/* construct advanced initial LP basis */ + +void glp_cpx_basis(glp_prob *P); +/* construct Bixby's initial LP basis */ + +int glp_simplex(glp_prob *P, const glp_smcp *parm); +/* solve LP problem with the simplex method */ + +int glp_exact(glp_prob *P, const glp_smcp *parm); +/* solve LP problem in exact arithmetic */ + +void glp_init_smcp(glp_smcp *parm); +/* initialize simplex method control parameters */ + +int glp_get_status(glp_prob *P); +/* retrieve generic status of basic solution */ + +int glp_get_prim_stat(glp_prob *P); +/* retrieve status of primal basic solution */ + +int glp_get_dual_stat(glp_prob *P); +/* retrieve status of dual basic solution */ + +double glp_get_obj_val(glp_prob *P); +/* retrieve objective value (basic solution) */ + +int glp_get_row_stat(glp_prob *P, int i); +/* retrieve row status */ + +double glp_get_row_prim(glp_prob *P, int i); +/* retrieve row primal value (basic solution) */ + +double glp_get_row_dual(glp_prob *P, int i); +/* retrieve row dual value (basic solution) */ + +int glp_get_col_stat(glp_prob *P, int j); +/* retrieve column status */ + +double glp_get_col_prim(glp_prob *P, int j); +/* retrieve column primal value (basic solution) */ + +double glp_get_col_dual(glp_prob *P, int j); +/* retrieve column dual value (basic solution) */ + +int glp_get_unbnd_ray(glp_prob *P); +/* determine variable causing unboundedness */ + +#if 1 /* 08/VIII-2013; not documented yet */ +int glp_get_it_cnt(glp_prob *P); +/* get simplex solver iteration count */ +#endif + +#if 1 /* 08/VIII-2013; not documented yet */ +void glp_set_it_cnt(glp_prob *P, int it_cnt); +/* set simplex solver iteration count */ +#endif + +int glp_interior(glp_prob *P, const glp_iptcp *parm); +/* solve LP problem with the interior-point method */ + +void glp_init_iptcp(glp_iptcp *parm); +/* initialize interior-point solver control parameters */ + +int glp_ipt_status(glp_prob *P); +/* retrieve status of interior-point solution */ + +double glp_ipt_obj_val(glp_prob *P); +/* retrieve objective value (interior point) */ + +double glp_ipt_row_prim(glp_prob *P, int i); +/* retrieve row primal value (interior point) */ + +double glp_ipt_row_dual(glp_prob *P, int i); +/* retrieve row dual value (interior point) */ + +double glp_ipt_col_prim(glp_prob *P, int j); +/* retrieve column primal value (interior point) */ + +double glp_ipt_col_dual(glp_prob *P, int j); +/* retrieve column dual value (interior point) */ + +void glp_set_col_kind(glp_prob *P, int j, int kind); +/* set (change) column kind */ + +int glp_get_col_kind(glp_prob *P, int j); +/* retrieve column kind */ + +int glp_get_num_int(glp_prob *P); +/* retrieve number of integer columns */ + +int glp_get_num_bin(glp_prob *P); +/* retrieve number of binary columns */ + +int glp_intopt(glp_prob *P, const glp_iocp *parm); +/* solve MIP problem with the branch-and-bound method */ + +void glp_init_iocp(glp_iocp *parm); +/* initialize integer optimizer control parameters */ + +int glp_mip_status(glp_prob *P); +/* retrieve status of MIP solution */ + +double glp_mip_obj_val(glp_prob *P); +/* retrieve objective value (MIP solution) */ + +double glp_mip_row_val(glp_prob *P, int i); +/* retrieve row value (MIP solution) */ + +double glp_mip_col_val(glp_prob *P, int j); +/* retrieve column value (MIP solution) */ + +void glp_check_kkt(glp_prob *P, int sol, int cond, double *ae_max, + int *ae_ind, double *re_max, int *re_ind); +/* check feasibility/optimality conditions */ + +int glp_print_sol(glp_prob *P, const char *fname); +/* write basic solution in printable format */ + +int glp_read_sol(glp_prob *P, const char *fname); +/* read basic solution from text file */ + +int glp_write_sol(glp_prob *P, const char *fname); +/* write basic solution to text file */ + +int glp_print_ranges(glp_prob *P, int len, const int list[], + int flags, const char *fname); +/* print sensitivity analysis report */ + +int glp_print_ipt(glp_prob *P, const char *fname); +/* write interior-point solution in printable format */ + +int glp_read_ipt(glp_prob *P, const char *fname); +/* read interior-point solution from text file */ + +int glp_write_ipt(glp_prob *P, const char *fname); +/* write interior-point solution to text file */ + +int glp_print_mip(glp_prob *P, const char *fname); +/* write MIP solution in printable format */ + +int glp_read_mip(glp_prob *P, const char *fname); +/* read MIP solution from text file */ + +int glp_write_mip(glp_prob *P, const char *fname); +/* write MIP solution to text file */ + +int glp_bf_exists(glp_prob *P); +/* check if LP basis factorization exists */ + +int glp_factorize(glp_prob *P); +/* compute LP basis factorization */ + +int glp_bf_updated(glp_prob *P); +/* check if LP basis factorization has been updated */ + +void glp_get_bfcp(glp_prob *P, glp_bfcp *parm); +/* retrieve LP basis factorization control parameters */ + +void glp_set_bfcp(glp_prob *P, const glp_bfcp *parm); +/* change LP basis factorization control parameters */ + +int glp_get_bhead(glp_prob *P, int k); +/* retrieve LP basis header information */ + +int glp_get_row_bind(glp_prob *P, int i); +/* retrieve row index in the basis header */ + +int glp_get_col_bind(glp_prob *P, int j); +/* retrieve column index in the basis header */ + +void glp_ftran(glp_prob *P, double x[]); +/* perform forward transformation (solve system B*x = b) */ + +void glp_btran(glp_prob *P, double x[]); +/* perform backward transformation (solve system B'*x = b) */ + +int glp_warm_up(glp_prob *P); +/* "warm up" LP basis */ + +int glp_eval_tab_row(glp_prob *P, int k, int ind[], double val[]); +/* compute row of the simplex tableau */ + +int glp_eval_tab_col(glp_prob *P, int k, int ind[], double val[]); +/* compute column of the simplex tableau */ + +int glp_transform_row(glp_prob *P, int len, int ind[], double val[]); +/* transform explicitly specified row */ + +int glp_transform_col(glp_prob *P, int len, int ind[], double val[]); +/* transform explicitly specified column */ + +int glp_prim_rtest(glp_prob *P, int len, const int ind[], + const double val[], int dir, double eps); +/* perform primal ratio test */ + +int glp_dual_rtest(glp_prob *P, int len, const int ind[], + const double val[], int dir, double eps); +/* perform dual ratio test */ + +void glp_analyze_bound(glp_prob *P, int k, double *value1, int *var1, + double *value2, int *var2); +/* analyze active bound of non-basic variable */ + +void glp_analyze_coef(glp_prob *P, int k, double *coef1, int *var1, + double *value1, double *coef2, int *var2, double *value2); +/* analyze objective coefficient at basic variable */ + +int glp_ios_reason(glp_tree *T); +/* determine reason for calling the callback routine */ + +glp_prob *glp_ios_get_prob(glp_tree *T); +/* access the problem object */ + +void glp_ios_tree_size(glp_tree *T, int *a_cnt, int *n_cnt, + int *t_cnt); +/* determine size of the branch-and-bound tree */ + +int glp_ios_curr_node(glp_tree *T); +/* determine current active subproblem */ + +int glp_ios_next_node(glp_tree *T, int p); +/* determine next active subproblem */ + +int glp_ios_prev_node(glp_tree *T, int p); +/* determine previous active subproblem */ + +int glp_ios_up_node(glp_tree *T, int p); +/* determine parent subproblem */ + +int glp_ios_node_level(glp_tree *T, int p); +/* determine subproblem level */ + +double glp_ios_node_bound(glp_tree *T, int p); +/* determine subproblem local bound */ + +int glp_ios_best_node(glp_tree *T); +/* find active subproblem with best local bound */ + +double glp_ios_mip_gap(glp_tree *T); +/* compute relative MIP gap */ + +void *glp_ios_node_data(glp_tree *T, int p); +/* access subproblem application-specific data */ + +void glp_ios_row_attr(glp_tree *T, int i, glp_attr *attr); +/* retrieve additional row attributes */ + +int glp_ios_pool_size(glp_tree *T); +/* determine current size of the cut pool */ + +int glp_ios_add_row(glp_tree *T, + const char *name, int klass, int flags, int len, const int ind[], + const double val[], int type, double rhs); +/* add row (constraint) to the cut pool */ + +void glp_ios_del_row(glp_tree *T, int i); +/* remove row (constraint) from the cut pool */ + +void glp_ios_clear_pool(glp_tree *T); +/* remove all rows (constraints) from the cut pool */ + +int glp_ios_can_branch(glp_tree *T, int j); +/* check if can branch upon specified variable */ + +void glp_ios_branch_upon(glp_tree *T, int j, int sel); +/* choose variable to branch upon */ + +void glp_ios_select_node(glp_tree *T, int p); +/* select subproblem to continue the search */ + +int glp_ios_heur_sol(glp_tree *T, const double x[]); +/* provide solution found by heuristic */ + +void glp_ios_terminate(glp_tree *T); +/* terminate the solution process */ + +void glp_init_mpscp(glp_mpscp *parm); +/* initialize MPS format control parameters */ + +int glp_read_mps(glp_prob *P, int fmt, const glp_mpscp *parm, + const char *fname); +/* read problem data in MPS format */ + +int glp_write_mps(glp_prob *P, int fmt, const glp_mpscp *parm, + const char *fname); +/* write problem data in MPS format */ + +void glp_init_cpxcp(glp_cpxcp *parm); +/* initialize CPLEX LP format control parameters */ + +int glp_read_lp(glp_prob *P, const glp_cpxcp *parm, const char *fname); +/* read problem data in CPLEX LP format */ + +int glp_write_lp(glp_prob *P, const glp_cpxcp *parm, const char *fname); +/* write problem data in CPLEX LP format */ + +int glp_read_prob(glp_prob *P, int flags, const char *fname); +/* read problem data in GLPK format */ + +int glp_write_prob(glp_prob *P, int flags, const char *fname); +/* write problem data in GLPK format */ + +glp_tran *glp_mpl_alloc_wksp(void); +/* allocate the MathProg translator workspace */ + +int glp_mpl_read_model(glp_tran *tran, const char *fname, int skip); +/* read and translate model section */ + +int glp_mpl_read_data(glp_tran *tran, const char *fname); +/* read and translate data section */ + +int glp_mpl_generate(glp_tran *tran, const char *fname); +/* generate the model */ + +void glp_mpl_build_prob(glp_tran *tran, glp_prob *prob); +/* build LP/MIP problem instance from the model */ + +int glp_mpl_postsolve(glp_tran *tran, glp_prob *prob, int sol); +/* postsolve the model */ + +void glp_mpl_free_wksp(glp_tran *tran); +/* free the MathProg translator workspace */ + +int glp_main(int argc, const char *argv[]); +/* stand-alone LP/MIP solver */ + +int glp_read_cnfsat(glp_prob *P, const char *fname); +/* read CNF-SAT problem data in DIMACS format */ + +int glp_check_cnfsat(glp_prob *P); +/* check for CNF-SAT problem instance */ + +int glp_write_cnfsat(glp_prob *P, const char *fname); +/* write CNF-SAT problem data in DIMACS format */ + +int glp_minisat1(glp_prob *P); +/* solve CNF-SAT problem with MiniSat solver */ + +int glp_intfeas1(glp_prob *P, int use_bound, int obj_bound); +/* solve integer feasibility problem */ + +int glp_init_env(void); +/* initialize GLPK environment */ + +const char *glp_version(void); +/* determine library version */ + +int glp_free_env(void); +/* free GLPK environment */ + +void glp_puts(const char *s); +/* write string on terminal */ + +void glp_printf(const char *fmt, ...); +/* write formatted output on terminal */ + +void glp_vprintf(const char *fmt, va_list arg); +/* write formatted output on terminal */ + +int glp_term_out(int flag); +/* enable/disable terminal output */ + +void glp_term_hook(int (*func)(void *info, const char *s), void *info); +/* install hook to intercept terminal output */ + +int glp_open_tee(const char *name); +/* start copying terminal output to text file */ + +int glp_close_tee(void); +/* stop copying terminal output to text file */ + +#ifndef GLP_ERRFUNC_DEFINED +#define GLP_ERRFUNC_DEFINED +typedef void (*glp_errfunc)(const char *fmt, ...); +#endif + +#define glp_error glp_error_(__FILE__, __LINE__) +glp_errfunc glp_error_(const char *file, int line); +/* display fatal error message and terminate execution */ + +#if 1 /* 07/XI-2015 */ +int glp_at_error(void); +/* check for error state */ +#endif + +#define glp_assert(expr) \ + ((void)((expr) || (glp_assert_(#expr, __FILE__, __LINE__), 1))) +void glp_assert_(const char *expr, const char *file, int line); +/* check for logical condition */ + +void glp_error_hook(void (*func)(void *info), void *info); +/* install hook to intercept abnormal termination */ + +#define glp_malloc(size) glp_alloc(1, size) +/* allocate memory block (obsolete) */ + +#define glp_calloc(n, size) glp_alloc(n, size) +/* allocate memory block (obsolete) */ + +void *glp_alloc(int n, int size); +/* allocate memory block */ + +void *glp_realloc(void *ptr, int n, int size); +/* reallocate memory block */ + +void glp_free(void *ptr); +/* free (deallocate) memory block */ + +void glp_mem_limit(int limit); +/* set memory usage limit */ + +void glp_mem_usage(int *count, int *cpeak, size_t *total, + size_t *tpeak); +/* get memory usage information */ + +typedef struct glp_graph glp_graph; +typedef struct glp_vertex glp_vertex; +typedef struct glp_arc glp_arc; + +struct glp_graph +{ /* graph descriptor */ + void *pool; /* DMP *pool; */ + /* memory pool to store graph components */ + char *name; + /* graph name (1 to 255 chars); NULL means no name is assigned + to the graph */ + int nv_max; + /* length of the vertex list (enlarged automatically) */ + int nv; + /* number of vertices in the graph, 0 <= nv <= nv_max */ + int na; + /* number of arcs in the graph, na >= 0 */ + glp_vertex **v; /* glp_vertex *v[1+nv_max]; */ + /* v[i], 1 <= i <= nv, is a pointer to i-th vertex */ + void *index; /* AVL *index; */ + /* vertex index to find vertices by their names; NULL means the + index does not exist */ + int v_size; + /* size of data associated with each vertex (0 to 256 bytes) */ + int a_size; + /* size of data associated with each arc (0 to 256 bytes) */ +}; + +struct glp_vertex +{ /* vertex descriptor */ + int i; + /* vertex ordinal number, 1 <= i <= nv */ + char *name; + /* vertex name (1 to 255 chars); NULL means no name is assigned + to the vertex */ + void *entry; /* AVLNODE *entry; */ + /* pointer to corresponding entry in the vertex index; NULL means + that either the index does not exist or the vertex has no name + assigned */ + void *data; + /* pointer to data associated with the vertex */ + void *temp; + /* working pointer */ + glp_arc *in; + /* pointer to the (unordered) list of incoming arcs */ + glp_arc *out; + /* pointer to the (unordered) list of outgoing arcs */ +}; + +struct glp_arc +{ /* arc descriptor */ + glp_vertex *tail; + /* pointer to the tail endpoint */ + glp_vertex *head; + /* pointer to the head endpoint */ + void *data; + /* pointer to data associated with the arc */ + void *temp; + /* working pointer */ + glp_arc *t_prev; + /* pointer to previous arc having the same tail endpoint */ + glp_arc *t_next; + /* pointer to next arc having the same tail endpoint */ + glp_arc *h_prev; + /* pointer to previous arc having the same head endpoint */ + glp_arc *h_next; + /* pointer to next arc having the same head endpoint */ +}; + +glp_graph *glp_create_graph(int v_size, int a_size); +/* create graph */ + +void glp_set_graph_name(glp_graph *G, const char *name); +/* assign (change) graph name */ + +int glp_add_vertices(glp_graph *G, int nadd); +/* add new vertices to graph */ + +void glp_set_vertex_name(glp_graph *G, int i, const char *name); +/* assign (change) vertex name */ + +glp_arc *glp_add_arc(glp_graph *G, int i, int j); +/* add new arc to graph */ + +void glp_del_vertices(glp_graph *G, int ndel, const int num[]); +/* delete vertices from graph */ + +void glp_del_arc(glp_graph *G, glp_arc *a); +/* delete arc from graph */ + +void glp_erase_graph(glp_graph *G, int v_size, int a_size); +/* erase graph content */ + +void glp_delete_graph(glp_graph *G); +/* delete graph */ + +void glp_create_v_index(glp_graph *G); +/* create vertex name index */ + +int glp_find_vertex(glp_graph *G, const char *name); +/* find vertex by its name */ + +void glp_delete_v_index(glp_graph *G); +/* delete vertex name index */ + +int glp_read_graph(glp_graph *G, const char *fname); +/* read graph from plain text file */ + +int glp_write_graph(glp_graph *G, const char *fname); +/* write graph to plain text file */ + +void glp_mincost_lp(glp_prob *P, glp_graph *G, int names, int v_rhs, + int a_low, int a_cap, int a_cost); +/* convert minimum cost flow problem to LP */ + +int glp_mincost_okalg(glp_graph *G, int v_rhs, int a_low, int a_cap, + int a_cost, double *sol, int a_x, int v_pi); +/* find minimum-cost flow with out-of-kilter algorithm */ + +int glp_mincost_relax4(glp_graph *G, int v_rhs, int a_low, int a_cap, + int a_cost, int crash, double *sol, int a_x, int a_rc); +/* find minimum-cost flow with Bertsekas-Tseng relaxation method */ + +void glp_maxflow_lp(glp_prob *P, glp_graph *G, int names, int s, + int t, int a_cap); +/* convert maximum flow problem to LP */ + +int glp_maxflow_ffalg(glp_graph *G, int s, int t, int a_cap, + double *sol, int a_x, int v_cut); +/* find maximal flow with Ford-Fulkerson algorithm */ + +int glp_check_asnprob(glp_graph *G, int v_set); +/* check correctness of assignment problem data */ + +/* assignment problem formulation: */ +#define GLP_ASN_MIN 1 /* perfect matching (minimization) */ +#define GLP_ASN_MAX 2 /* perfect matching (maximization) */ +#define GLP_ASN_MMP 3 /* maximum matching */ + +int glp_asnprob_lp(glp_prob *P, int form, glp_graph *G, int names, + int v_set, int a_cost); +/* convert assignment problem to LP */ + +int glp_asnprob_okalg(int form, glp_graph *G, int v_set, int a_cost, + double *sol, int a_x); +/* solve assignment problem with out-of-kilter algorithm */ + +int glp_asnprob_hall(glp_graph *G, int v_set, int a_x); +/* find bipartite matching of maximum cardinality */ + +double glp_cpp(glp_graph *G, int v_t, int v_es, int v_ls); +/* solve critical path problem */ + +int glp_read_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, + int a_cost, const char *fname); +/* read min-cost flow problem data in DIMACS format */ + +int glp_write_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, + int a_cost, const char *fname); +/* write min-cost flow problem data in DIMACS format */ + +int glp_read_maxflow(glp_graph *G, int *s, int *t, int a_cap, + const char *fname); +/* read maximum flow problem data in DIMACS format */ + +int glp_write_maxflow(glp_graph *G, int s, int t, int a_cap, + const char *fname); +/* write maximum flow problem data in DIMACS format */ + +int glp_read_asnprob(glp_graph *G, int v_set, int a_cost, const char + *fname); +/* read assignment problem data in DIMACS format */ + +int glp_write_asnprob(glp_graph *G, int v_set, int a_cost, const char + *fname); +/* write assignment problem data in DIMACS format */ + +int glp_read_ccdata(glp_graph *G, int v_wgt, const char *fname); +/* read graph in DIMACS clique/coloring format */ + +int glp_write_ccdata(glp_graph *G, int v_wgt, const char *fname); +/* write graph in DIMACS clique/coloring format */ + +int glp_netgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, + const int parm[1+15]); +/* Klingman's network problem generator */ + +void glp_netgen_prob(int nprob, int parm[1+15]); +/* Klingman's standard network problem instance */ + +int glp_gridgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, + const int parm[1+14]); +/* grid-like network problem generator */ + +int glp_rmfgen(glp_graph *G, int *s, int *t, int a_cap, + const int parm[1+5]); +/* Goldfarb's maximum flow problem generator */ + +int glp_weak_comp(glp_graph *G, int v_num); +/* find all weakly connected components of graph */ + +int glp_strong_comp(glp_graph *G, int v_num); +/* find all strongly connected components of graph */ + +int glp_top_sort(glp_graph *G, int v_num); +/* topological sorting of acyclic digraph */ + +int glp_wclique_exact(glp_graph *G, int v_wgt, double *sol, int v_set); +/* find maximum weight clique with exact algorithm */ + +#ifdef __cplusplus +} +#endif + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpmat.c b/resources/3rdparty/glpk-4.57/src/glpmat.c new file mode 100644 index 000000000..97d1c6515 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpmat.c @@ -0,0 +1,924 @@ +/* glpmat.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpmat.h" +#include "qmd.h" +#include "amd.h" +#include "colamd.h" + +/*---------------------------------------------------------------------- +-- check_fvs - check sparse vector in full-vector storage format. +-- +-- SYNOPSIS +-- +-- #include "glpmat.h" +-- int check_fvs(int n, int nnz, int ind[], double vec[]); +-- +-- DESCRIPTION +-- +-- The routine check_fvs checks if a given vector of dimension n in +-- full-vector storage format has correct representation. +-- +-- RETURNS +-- +-- The routine returns one of the following codes: +-- +-- 0 - the vector is correct; +-- 1 - the number of elements (n) is negative; +-- 2 - the number of non-zero elements (nnz) is negative; +-- 3 - some element index is out of range; +-- 4 - some element index is duplicate; +-- 5 - some non-zero element is out of pattern. */ + +int check_fvs(int n, int nnz, int ind[], double vec[]) +{ int i, t, ret, *flag = NULL; + /* check the number of elements */ + if (n < 0) + { ret = 1; + goto done; + } + /* check the number of non-zero elements */ + if (nnz < 0) + { ret = 2; + goto done; + } + /* check vector indices */ + flag = xcalloc(1+n, sizeof(int)); + for (i = 1; i <= n; i++) flag[i] = 0; + for (t = 1; t <= nnz; t++) + { i = ind[t]; + if (!(1 <= i && i <= n)) + { ret = 3; + goto done; + } + if (flag[i]) + { ret = 4; + goto done; + } + flag[i] = 1; + } + /* check vector elements */ + for (i = 1; i <= n; i++) + { if (!flag[i] && vec[i] != 0.0) + { ret = 5; + goto done; + } + } + /* the vector is ok */ + ret = 0; +done: if (flag != NULL) xfree(flag); + return ret; +} + +/*---------------------------------------------------------------------- +-- check_pattern - check pattern of sparse matrix. +-- +-- SYNOPSIS +-- +-- #include "glpmat.h" +-- int check_pattern(int m, int n, int A_ptr[], int A_ind[]); +-- +-- DESCRIPTION +-- +-- The routine check_pattern checks the pattern of a given mxn matrix +-- in storage-by-rows format. +-- +-- RETURNS +-- +-- The routine returns one of the following codes: +-- +-- 0 - the pattern is correct; +-- 1 - the number of rows (m) is negative; +-- 2 - the number of columns (n) is negative; +-- 3 - A_ptr[1] is not 1; +-- 4 - some column index is out of range; +-- 5 - some column indices are duplicate. */ + +int check_pattern(int m, int n, int A_ptr[], int A_ind[]) +{ int i, j, ptr, ret, *flag = NULL; + /* check the number of rows */ + if (m < 0) + { ret = 1; + goto done; + } + /* check the number of columns */ + if (n < 0) + { ret = 2; + goto done; + } + /* check location A_ptr[1] */ + if (A_ptr[1] != 1) + { ret = 3; + goto done; + } + /* check row patterns */ + flag = xcalloc(1+n, sizeof(int)); + for (j = 1; j <= n; j++) flag[j] = 0; + for (i = 1; i <= m; i++) + { /* check pattern of row i */ + for (ptr = A_ptr[i]; ptr < A_ptr[i+1]; ptr++) + { j = A_ind[ptr]; + /* check column index */ + if (!(1 <= j && j <= n)) + { ret = 4; + goto done; + } + /* check for duplication */ + if (flag[j]) + { ret = 5; + goto done; + } + flag[j] = 1; + } + /* clear flags */ + for (ptr = A_ptr[i]; ptr < A_ptr[i+1]; ptr++) + { j = A_ind[ptr]; + flag[j] = 0; + } + } + /* the pattern is ok */ + ret = 0; +done: if (flag != NULL) xfree(flag); + return ret; +} + +/*---------------------------------------------------------------------- +-- transpose - transpose sparse matrix. +-- +-- *Synopsis* +-- +-- #include "glpmat.h" +-- void transpose(int m, int n, int A_ptr[], int A_ind[], +-- double A_val[], int AT_ptr[], int AT_ind[], double AT_val[]); +-- +-- *Description* +-- +-- For a given mxn sparse matrix A the routine transpose builds a nxm +-- sparse matrix A' which is a matrix transposed to A. +-- +-- The arrays A_ptr, A_ind, and A_val specify a given mxn matrix A to +-- be transposed in storage-by-rows format. The parameter A_val can be +-- NULL, in which case numeric values are not copied. The arrays A_ptr, +-- A_ind, and A_val are not changed on exit. +-- +-- On entry the arrays AT_ptr, AT_ind, and AT_val must be allocated, +-- but their content is ignored. On exit the routine stores a resultant +-- nxm matrix A' in these arrays in storage-by-rows format. Note that +-- if the parameter A_val is NULL, the array AT_val is not used. +-- +-- The routine transpose has a side effect that elements in rows of the +-- resultant matrix A' follow in ascending their column indices. */ + +void transpose(int m, int n, int A_ptr[], int A_ind[], double A_val[], + int AT_ptr[], int AT_ind[], double AT_val[]) +{ int i, j, t, beg, end, pos, len; + /* determine row lengths of resultant matrix */ + for (j = 1; j <= n; j++) AT_ptr[j] = 0; + for (i = 1; i <= m; i++) + { beg = A_ptr[i], end = A_ptr[i+1]; + for (t = beg; t < end; t++) AT_ptr[A_ind[t]]++; + } + /* set up row pointers of resultant matrix */ + pos = 1; + for (j = 1; j <= n; j++) + len = AT_ptr[j], pos += len, AT_ptr[j] = pos; + AT_ptr[n+1] = pos; + /* build resultant matrix */ + for (i = m; i >= 1; i--) + { beg = A_ptr[i], end = A_ptr[i+1]; + for (t = beg; t < end; t++) + { pos = --AT_ptr[A_ind[t]]; + AT_ind[pos] = i; + if (A_val != NULL) AT_val[pos] = A_val[t]; + } + } + return; +} + +/*---------------------------------------------------------------------- +-- adat_symbolic - compute S = P*A*D*A'*P' (symbolic phase). +-- +-- *Synopsis* +-- +-- #include "glpmat.h" +-- int *adat_symbolic(int m, int n, int P_per[], int A_ptr[], +-- int A_ind[], int S_ptr[]); +-- +-- *Description* +-- +-- The routine adat_symbolic implements the symbolic phase to compute +-- symmetric matrix S = P*A*D*A'*P', where P is a permutation matrix, +-- A is a given sparse matrix, D is a diagonal matrix, A' is a matrix +-- transposed to A, P' is an inverse of P. +-- +-- The parameter m is the number of rows in A and the order of P. +-- +-- The parameter n is the number of columns in A and the order of D. +-- +-- The array P_per specifies permutation matrix P. It is not changed on +-- exit. +-- +-- The arrays A_ptr and A_ind specify the pattern of matrix A. They are +-- not changed on exit. +-- +-- On exit the routine stores the pattern of upper triangular part of +-- matrix S without diagonal elements in the arrays S_ptr and S_ind in +-- storage-by-rows format. The array S_ptr should be allocated on entry, +-- however, its content is ignored. The array S_ind is allocated by the +-- routine itself which returns a pointer to it. +-- +-- *Returns* +-- +-- The routine returns a pointer to the array S_ind. */ + +int *adat_symbolic(int m, int n, int P_per[], int A_ptr[], int A_ind[], + int S_ptr[]) +{ int i, j, t, ii, jj, tt, k, size, len; + int *S_ind, *AT_ptr, *AT_ind, *ind, *map, *temp; + /* build the pattern of A', which is a matrix transposed to A, to + efficiently access A in column-wise manner */ + AT_ptr = xcalloc(1+n+1, sizeof(int)); + AT_ind = xcalloc(A_ptr[m+1], sizeof(int)); + transpose(m, n, A_ptr, A_ind, NULL, AT_ptr, AT_ind, NULL); + /* allocate the array S_ind */ + size = A_ptr[m+1] - 1; + if (size < m) size = m; + S_ind = xcalloc(1+size, sizeof(int)); + /* allocate and initialize working arrays */ + ind = xcalloc(1+m, sizeof(int)); + map = xcalloc(1+m, sizeof(int)); + for (jj = 1; jj <= m; jj++) map[jj] = 0; + /* compute pattern of S; note that symbolically S = B*B', where + B = P*A, B' is matrix transposed to B */ + S_ptr[1] = 1; + for (ii = 1; ii <= m; ii++) + { /* compute pattern of ii-th row of S */ + len = 0; + i = P_per[ii]; /* i-th row of A = ii-th row of B */ + for (t = A_ptr[i]; t < A_ptr[i+1]; t++) + { k = A_ind[t]; + /* walk through k-th column of A */ + for (tt = AT_ptr[k]; tt < AT_ptr[k+1]; tt++) + { j = AT_ind[tt]; + jj = P_per[m+j]; /* j-th row of A = jj-th row of B */ + /* a[i,k] != 0 and a[j,k] != 0 ergo s[ii,jj] != 0 */ + if (ii < jj && !map[jj]) ind[++len] = jj, map[jj] = 1; + } + } + /* now (ind) is pattern of ii-th row of S */ + S_ptr[ii+1] = S_ptr[ii] + len; + /* at least (S_ptr[ii+1] - 1) locations should be available in + the array S_ind */ + if (S_ptr[ii+1] - 1 > size) + { temp = S_ind; + size += size; + S_ind = xcalloc(1+size, sizeof(int)); + memcpy(&S_ind[1], &temp[1], (S_ptr[ii] - 1) * sizeof(int)); + xfree(temp); + } + xassert(S_ptr[ii+1] - 1 <= size); + /* (ii-th row of S) := (ind) */ + memcpy(&S_ind[S_ptr[ii]], &ind[1], len * sizeof(int)); + /* clear the row pattern map */ + for (t = 1; t <= len; t++) map[ind[t]] = 0; + } + /* free working arrays */ + xfree(AT_ptr); + xfree(AT_ind); + xfree(ind); + xfree(map); + /* reallocate the array S_ind to free unused locations */ + temp = S_ind; + size = S_ptr[m+1] - 1; + S_ind = xcalloc(1+size, sizeof(int)); + memcpy(&S_ind[1], &temp[1], size * sizeof(int)); + xfree(temp); + return S_ind; +} + +/*---------------------------------------------------------------------- +-- adat_numeric - compute S = P*A*D*A'*P' (numeric phase). +-- +-- *Synopsis* +-- +-- #include "glpmat.h" +-- void adat_numeric(int m, int n, int P_per[], +-- int A_ptr[], int A_ind[], double A_val[], double D_diag[], +-- int S_ptr[], int S_ind[], double S_val[], double S_diag[]); +-- +-- *Description* +-- +-- The routine adat_numeric implements the numeric phase to compute +-- symmetric matrix S = P*A*D*A'*P', where P is a permutation matrix, +-- A is a given sparse matrix, D is a diagonal matrix, A' is a matrix +-- transposed to A, P' is an inverse of P. +-- +-- The parameter m is the number of rows in A and the order of P. +-- +-- The parameter n is the number of columns in A and the order of D. +-- +-- The matrix P is specified in the array P_per, which is not changed +-- on exit. +-- +-- The matrix A is specified in the arrays A_ptr, A_ind, and A_val in +-- storage-by-rows format. These arrays are not changed on exit. +-- +-- Diagonal elements of the matrix D are specified in the array D_diag, +-- where D_diag[0] is not used, D_diag[i] = d[i,i] for i = 1, ..., n. +-- The array D_diag is not changed on exit. +-- +-- The pattern of the upper triangular part of the matrix S without +-- diagonal elements (previously computed by the routine adat_symbolic) +-- is specified in the arrays S_ptr and S_ind, which are not changed on +-- exit. Numeric values of non-diagonal elements of S are stored in +-- corresponding locations of the array S_val, and values of diagonal +-- elements of S are stored in locations S_diag[1], ..., S_diag[n]. */ + +void adat_numeric(int m, int n, int P_per[], + int A_ptr[], int A_ind[], double A_val[], double D_diag[], + int S_ptr[], int S_ind[], double S_val[], double S_diag[]) +{ int i, j, t, ii, jj, tt, beg, end, beg1, end1, k; + double sum, *work; + work = xcalloc(1+n, sizeof(double)); + for (j = 1; j <= n; j++) work[j] = 0.0; + /* compute S = B*D*B', where B = P*A, B' is a matrix transposed + to B */ + for (ii = 1; ii <= m; ii++) + { i = P_per[ii]; /* i-th row of A = ii-th row of B */ + /* (work) := (i-th row of A) */ + beg = A_ptr[i], end = A_ptr[i+1]; + for (t = beg; t < end; t++) + work[A_ind[t]] = A_val[t]; + /* compute ii-th row of S */ + beg = S_ptr[ii], end = S_ptr[ii+1]; + for (t = beg; t < end; t++) + { jj = S_ind[t]; + j = P_per[jj]; /* j-th row of A = jj-th row of B */ + /* s[ii,jj] := sum a[i,k] * d[k,k] * a[j,k] */ + sum = 0.0; + beg1 = A_ptr[j], end1 = A_ptr[j+1]; + for (tt = beg1; tt < end1; tt++) + { k = A_ind[tt]; + sum += work[k] * D_diag[k] * A_val[tt]; + } + S_val[t] = sum; + } + /* s[ii,ii] := sum a[i,k] * d[k,k] * a[i,k] */ + sum = 0.0; + beg = A_ptr[i], end = A_ptr[i+1]; + for (t = beg; t < end; t++) + { k = A_ind[t]; + sum += A_val[t] * D_diag[k] * A_val[t]; + work[k] = 0.0; + } + S_diag[ii] = sum; + } + xfree(work); + return; +} + +/*---------------------------------------------------------------------- +-- min_degree - minimum degree ordering. +-- +-- *Synopsis* +-- +-- #include "glpmat.h" +-- void min_degree(int n, int A_ptr[], int A_ind[], int P_per[]); +-- +-- *Description* +-- +-- The routine min_degree uses the minimum degree ordering algorithm +-- to find a permutation matrix P for a given sparse symmetric positive +-- matrix A which minimizes the number of non-zeros in upper triangular +-- factor U for Cholesky factorization P*A*P' = U'*U. +-- +-- The parameter n is the order of matrices A and P. +-- +-- The pattern of the given matrix A is specified on entry in the arrays +-- A_ptr and A_ind in storage-by-rows format. Only the upper triangular +-- part without diagonal elements (which all are assumed to be non-zero) +-- should be specified as if A were upper triangular. The arrays A_ptr +-- and A_ind are not changed on exit. +-- +-- The permutation matrix P is stored by the routine in the array P_per +-- on exit. +-- +-- *Algorithm* +-- +-- The routine min_degree is based on some subroutines from the package +-- SPARSPAK (see comments in the module glpqmd). */ + +void min_degree(int n, int A_ptr[], int A_ind[], int P_per[]) +{ int i, j, ne, t, pos, len; + int *xadj, *adjncy, *deg, *marker, *rchset, *nbrhd, *qsize, + *qlink, nofsub; + /* determine number of non-zeros in complete pattern */ + ne = A_ptr[n+1] - 1; + ne += ne; + /* allocate working arrays */ + xadj = xcalloc(1+n+1, sizeof(int)); + adjncy = xcalloc(1+ne, sizeof(int)); + deg = xcalloc(1+n, sizeof(int)); + marker = xcalloc(1+n, sizeof(int)); + rchset = xcalloc(1+n, sizeof(int)); + nbrhd = xcalloc(1+n, sizeof(int)); + qsize = xcalloc(1+n, sizeof(int)); + qlink = xcalloc(1+n, sizeof(int)); + /* determine row lengths in complete pattern */ + for (i = 1; i <= n; i++) xadj[i] = 0; + for (i = 1; i <= n; i++) + { for (t = A_ptr[i]; t < A_ptr[i+1]; t++) + { j = A_ind[t]; + xassert(i < j && j <= n); + xadj[i]++, xadj[j]++; + } + } + /* set up row pointers for complete pattern */ + pos = 1; + for (i = 1; i <= n; i++) + len = xadj[i], pos += len, xadj[i] = pos; + xadj[n+1] = pos; + xassert(pos - 1 == ne); + /* construct complete pattern */ + for (i = 1; i <= n; i++) + { for (t = A_ptr[i]; t < A_ptr[i+1]; t++) + { j = A_ind[t]; + adjncy[--xadj[i]] = j, adjncy[--xadj[j]] = i; + } + } + /* call the main minimimum degree ordering routine */ + genqmd(&n, xadj, adjncy, P_per, P_per + n, deg, marker, rchset, + nbrhd, qsize, qlink, &nofsub); + /* make sure that permutation matrix P is correct */ + for (i = 1; i <= n; i++) + { j = P_per[i]; + xassert(1 <= j && j <= n); + xassert(P_per[n+j] == i); + } + /* free working arrays */ + xfree(xadj); + xfree(adjncy); + xfree(deg); + xfree(marker); + xfree(rchset); + xfree(nbrhd); + xfree(qsize); + xfree(qlink); + return; +} + +/**********************************************************************/ + +void amd_order1(int n, int A_ptr[], int A_ind[], int P_per[]) +{ /* approximate minimum degree ordering (AMD) */ + int k, ret; + double Control[AMD_CONTROL], Info[AMD_INFO]; + /* get the default parameters */ + amd_defaults(Control); +#if 0 + /* and print them */ + amd_control(Control); +#endif + /* make all indices 0-based */ + for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]--; + for (k = 1; k <= n+1; k++) A_ptr[k]--; + /* call the ordering routine */ + ret = amd_order(n, &A_ptr[1], &A_ind[1], &P_per[1], Control, Info) + ; +#if 0 + amd_info(Info); +#endif + xassert(ret == AMD_OK || ret == AMD_OK_BUT_JUMBLED); + /* retsore 1-based indices */ + for (k = 1; k <= n+1; k++) A_ptr[k]++; + for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]++; + /* patch up permutation matrix */ + memset(&P_per[n+1], 0, n * sizeof(int)); + for (k = 1; k <= n; k++) + { P_per[k]++; + xassert(1 <= P_per[k] && P_per[k] <= n); + xassert(P_per[n+P_per[k]] == 0); + P_per[n+P_per[k]] = k; + } + return; +} + +/**********************************************************************/ + +static void *allocate(size_t n, size_t size) +{ void *ptr; + ptr = xcalloc(n, size); + memset(ptr, 0, n * size); + return ptr; +} + +static void release(void *ptr) +{ xfree(ptr); + return; +} + +void symamd_ord(int n, int A_ptr[], int A_ind[], int P_per[]) +{ /* approximate minimum degree ordering (SYMAMD) */ + int k, ok; + int stats[COLAMD_STATS]; + /* make all indices 0-based */ + for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]--; + for (k = 1; k <= n+1; k++) A_ptr[k]--; + /* call the ordering routine */ + ok = symamd(n, &A_ind[1], &A_ptr[1], &P_per[1], NULL, stats, + allocate, release); +#if 0 + symamd_report(stats); +#endif + xassert(ok); + /* restore 1-based indices */ + for (k = 1; k <= n+1; k++) A_ptr[k]++; + for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]++; + /* patch up permutation matrix */ + memset(&P_per[n+1], 0, n * sizeof(int)); + for (k = 1; k <= n; k++) + { P_per[k]++; + xassert(1 <= P_per[k] && P_per[k] <= n); + xassert(P_per[n+P_per[k]] == 0); + P_per[n+P_per[k]] = k; + } + return; +} + +/*---------------------------------------------------------------------- +-- chol_symbolic - compute Cholesky factorization (symbolic phase). +-- +-- *Synopsis* +-- +-- #include "glpmat.h" +-- int *chol_symbolic(int n, int A_ptr[], int A_ind[], int U_ptr[]); +-- +-- *Description* +-- +-- The routine chol_symbolic implements the symbolic phase of Cholesky +-- factorization A = U'*U, where A is a given sparse symmetric positive +-- definite matrix, U is a resultant upper triangular factor, U' is a +-- matrix transposed to U. +-- +-- The parameter n is the order of matrices A and U. +-- +-- The pattern of the given matrix A is specified on entry in the arrays +-- A_ptr and A_ind in storage-by-rows format. Only the upper triangular +-- part without diagonal elements (which all are assumed to be non-zero) +-- should be specified as if A were upper triangular. The arrays A_ptr +-- and A_ind are not changed on exit. +-- +-- The pattern of the matrix U without diagonal elements (which all are +-- assumed to be non-zero) is stored on exit from the routine in the +-- arrays U_ptr and U_ind in storage-by-rows format. The array U_ptr +-- should be allocated on entry, however, its content is ignored. The +-- array U_ind is allocated by the routine which returns a pointer to it +-- on exit. +-- +-- *Returns* +-- +-- The routine returns a pointer to the array U_ind. +-- +-- *Method* +-- +-- The routine chol_symbolic computes the pattern of the matrix U in a +-- row-wise manner. No pivoting is used. +-- +-- It is known that to compute the pattern of row k of the matrix U we +-- need to merge the pattern of row k of the matrix A and the patterns +-- of each row i of U, where u[i,k] is non-zero (these rows are already +-- computed and placed above row k). +-- +-- However, to reduce the number of rows to be merged the routine uses +-- an advanced algorithm proposed in: +-- +-- D.J.Rose, R.E.Tarjan, and G.S.Lueker. Algorithmic aspects of vertex +-- elimination on graphs. SIAM J. Comput. 5, 1976, 266-83. +-- +-- The authors of the cited paper show that we have the same result if +-- we merge row k of the matrix A and such rows of the matrix U (among +-- rows 1, ..., k-1) whose leftmost non-diagonal non-zero element is +-- placed in k-th column. This feature signficantly reduces the number +-- of rows to be merged, especially on the final steps, where rows of +-- the matrix U become quite dense. +-- +-- To determine rows, which should be merged on k-th step, for a fixed +-- time the routine uses linked lists of row numbers of the matrix U. +-- Location head[k] contains the number of a first row, whose leftmost +-- non-diagonal non-zero element is placed in column k, and location +-- next[i] contains the number of a next row with the same property as +-- row i. */ + +int *chol_symbolic(int n, int A_ptr[], int A_ind[], int U_ptr[]) +{ int i, j, k, t, len, size, beg, end, min_j, *U_ind, *head, *next, + *ind, *map, *temp; + /* initially we assume that on computing the pattern of U fill-in + will double the number of non-zeros in A */ + size = A_ptr[n+1] - 1; + if (size < n) size = n; + size += size; + U_ind = xcalloc(1+size, sizeof(int)); + /* allocate and initialize working arrays */ + head = xcalloc(1+n, sizeof(int)); + for (i = 1; i <= n; i++) head[i] = 0; + next = xcalloc(1+n, sizeof(int)); + ind = xcalloc(1+n, sizeof(int)); + map = xcalloc(1+n, sizeof(int)); + for (j = 1; j <= n; j++) map[j] = 0; + /* compute the pattern of matrix U */ + U_ptr[1] = 1; + for (k = 1; k <= n; k++) + { /* compute the pattern of k-th row of U, which is the union of + k-th row of A and those rows of U (among 1, ..., k-1) whose + leftmost non-diagonal non-zero is placed in k-th column */ + /* (ind) := (k-th row of A) */ + len = A_ptr[k+1] - A_ptr[k]; + memcpy(&ind[1], &A_ind[A_ptr[k]], len * sizeof(int)); + for (t = 1; t <= len; t++) + { j = ind[t]; + xassert(k < j && j <= n); + map[j] = 1; + } + /* walk through rows of U whose leftmost non-diagonal non-zero + is placed in k-th column */ + for (i = head[k]; i != 0; i = next[i]) + { /* (ind) := (ind) union (i-th row of U) */ + beg = U_ptr[i], end = U_ptr[i+1]; + for (t = beg; t < end; t++) + { j = U_ind[t]; + if (j > k && !map[j]) ind[++len] = j, map[j] = 1; + } + } + /* now (ind) is the pattern of k-th row of U */ + U_ptr[k+1] = U_ptr[k] + len; + /* at least (U_ptr[k+1] - 1) locations should be available in + the array U_ind */ + if (U_ptr[k+1] - 1 > size) + { temp = U_ind; + size += size; + U_ind = xcalloc(1+size, sizeof(int)); + memcpy(&U_ind[1], &temp[1], (U_ptr[k] - 1) * sizeof(int)); + xfree(temp); + } + xassert(U_ptr[k+1] - 1 <= size); + /* (k-th row of U) := (ind) */ + memcpy(&U_ind[U_ptr[k]], &ind[1], len * sizeof(int)); + /* determine column index of leftmost non-diagonal non-zero in + k-th row of U and clear the row pattern map */ + min_j = n + 1; + for (t = 1; t <= len; t++) + { j = ind[t], map[j] = 0; + if (min_j > j) min_j = j; + } + /* include k-th row into corresponding linked list */ + if (min_j <= n) next[k] = head[min_j], head[min_j] = k; + } + /* free working arrays */ + xfree(head); + xfree(next); + xfree(ind); + xfree(map); + /* reallocate the array U_ind to free unused locations */ + temp = U_ind; + size = U_ptr[n+1] - 1; + U_ind = xcalloc(1+size, sizeof(int)); + memcpy(&U_ind[1], &temp[1], size * sizeof(int)); + xfree(temp); + return U_ind; +} + +/*---------------------------------------------------------------------- +-- chol_numeric - compute Cholesky factorization (numeric phase). +-- +-- *Synopsis* +-- +-- #include "glpmat.h" +-- int chol_numeric(int n, +-- int A_ptr[], int A_ind[], double A_val[], double A_diag[], +-- int U_ptr[], int U_ind[], double U_val[], double U_diag[]); +-- +-- *Description* +-- +-- The routine chol_symbolic implements the numeric phase of Cholesky +-- factorization A = U'*U, where A is a given sparse symmetric positive +-- definite matrix, U is a resultant upper triangular factor, U' is a +-- matrix transposed to U. +-- +-- The parameter n is the order of matrices A and U. +-- +-- Upper triangular part of the matrix A without diagonal elements is +-- specified in the arrays A_ptr, A_ind, and A_val in storage-by-rows +-- format. Diagonal elements of A are specified in the array A_diag, +-- where A_diag[0] is not used, A_diag[i] = a[i,i] for i = 1, ..., n. +-- The arrays A_ptr, A_ind, A_val, and A_diag are not changed on exit. +-- +-- The pattern of the matrix U without diagonal elements (previously +-- computed with the routine chol_symbolic) is specified in the arrays +-- U_ptr and U_ind, which are not changed on exit. Numeric values of +-- non-diagonal elements of U are stored in corresponding locations of +-- the array U_val, and values of diagonal elements of U are stored in +-- locations U_diag[1], ..., U_diag[n]. +-- +-- *Returns* +-- +-- The routine returns the number of non-positive diagonal elements of +-- the matrix U which have been replaced by a huge positive number (see +-- the method description below). Zero return code means the matrix A +-- has been successfully factorized. +-- +-- *Method* +-- +-- The routine chol_numeric computes the matrix U in a row-wise manner +-- using standard gaussian elimination technique. No pivoting is used. +-- +-- Initially the routine sets U = A, and before k-th elimination step +-- the matrix U is the following: +-- +-- 1 k n +-- 1 x x x x x x x x x x +-- . x x x x x x x x x +-- . . x x x x x x x x +-- . . . x x x x x x x +-- k . . . . * * * * * * +-- . . . . * * * * * * +-- . . . . * * * * * * +-- . . . . * * * * * * +-- . . . . * * * * * * +-- n . . . . * * * * * * +-- +-- where 'x' are elements of already computed rows, '*' are elements of +-- the active submatrix. (Note that the lower triangular part of the +-- active submatrix being symmetric is not stored and diagonal elements +-- are stored separately in the array U_diag.) +-- +-- The matrix A is assumed to be positive definite. However, if it is +-- close to semi-definite, on some elimination step a pivot u[k,k] may +-- happen to be non-positive due to round-off errors. In this case the +-- routine uses a technique proposed in: +-- +-- S.J.Wright. The Cholesky factorization in interior-point and barrier +-- methods. Preprint MCS-P600-0596, Mathematics and Computer Science +-- Division, Argonne National Laboratory, Argonne, Ill., May 1996. +-- +-- The routine just replaces non-positive u[k,k] by a huge positive +-- number. This involves non-diagonal elements in k-th row of U to be +-- close to zero that, in turn, involves k-th component of a solution +-- vector to be close to zero. Note, however, that this technique works +-- only if the system A*x = b is consistent. */ + +int chol_numeric(int n, + int A_ptr[], int A_ind[], double A_val[], double A_diag[], + int U_ptr[], int U_ind[], double U_val[], double U_diag[]) +{ int i, j, k, t, t1, beg, end, beg1, end1, count = 0; + double ukk, uki, *work; + work = xcalloc(1+n, sizeof(double)); + for (j = 1; j <= n; j++) work[j] = 0.0; + /* U := (upper triangle of A) */ + /* note that the upper traingle of A is a subset of U */ + for (i = 1; i <= n; i++) + { beg = A_ptr[i], end = A_ptr[i+1]; + for (t = beg; t < end; t++) + j = A_ind[t], work[j] = A_val[t]; + beg = U_ptr[i], end = U_ptr[i+1]; + for (t = beg; t < end; t++) + j = U_ind[t], U_val[t] = work[j], work[j] = 0.0; + U_diag[i] = A_diag[i]; + } + /* main elimination loop */ + for (k = 1; k <= n; k++) + { /* transform k-th row of U */ + ukk = U_diag[k]; + if (ukk > 0.0) + U_diag[k] = ukk = sqrt(ukk); + else + U_diag[k] = ukk = DBL_MAX, count++; + /* (work) := (transformed k-th row) */ + beg = U_ptr[k], end = U_ptr[k+1]; + for (t = beg; t < end; t++) + work[U_ind[t]] = (U_val[t] /= ukk); + /* transform other rows of U */ + for (t = beg; t < end; t++) + { i = U_ind[t]; + xassert(i > k); + /* (i-th row) := (i-th row) - u[k,i] * (k-th row) */ + uki = work[i]; + beg1 = U_ptr[i], end1 = U_ptr[i+1]; + for (t1 = beg1; t1 < end1; t1++) + U_val[t1] -= uki * work[U_ind[t1]]; + U_diag[i] -= uki * uki; + } + /* (work) := 0 */ + for (t = beg; t < end; t++) + work[U_ind[t]] = 0.0; + } + xfree(work); + return count; +} + +/*---------------------------------------------------------------------- +-- u_solve - solve upper triangular system U*x = b. +-- +-- *Synopsis* +-- +-- #include "glpmat.h" +-- void u_solve(int n, int U_ptr[], int U_ind[], double U_val[], +-- double U_diag[], double x[]); +-- +-- *Description* +-- +-- The routine u_solve solves an linear system U*x = b, where U is an +-- upper triangular matrix. +-- +-- The parameter n is the order of matrix U. +-- +-- The matrix U without diagonal elements is specified in the arrays +-- U_ptr, U_ind, and U_val in storage-by-rows format. Diagonal elements +-- of U are specified in the array U_diag, where U_diag[0] is not used, +-- U_diag[i] = u[i,i] for i = 1, ..., n. All these four arrays are not +-- changed on exit. +-- +-- The right-hand side vector b is specified on entry in the array x, +-- where x[0] is not used, and x[i] = b[i] for i = 1, ..., n. On exit +-- the routine stores computed components of the vector of unknowns x +-- in the array x in the same manner. */ + +void u_solve(int n, int U_ptr[], int U_ind[], double U_val[], + double U_diag[], double x[]) +{ int i, t, beg, end; + double temp; + for (i = n; i >= 1; i--) + { temp = x[i]; + beg = U_ptr[i], end = U_ptr[i+1]; + for (t = beg; t < end; t++) + temp -= U_val[t] * x[U_ind[t]]; + xassert(U_diag[i] != 0.0); + x[i] = temp / U_diag[i]; + } + return; +} + +/*---------------------------------------------------------------------- +-- ut_solve - solve lower triangular system U'*x = b. +-- +-- *Synopsis* +-- +-- #include "glpmat.h" +-- void ut_solve(int n, int U_ptr[], int U_ind[], double U_val[], +-- double U_diag[], double x[]); +-- +-- *Description* +-- +-- The routine ut_solve solves an linear system U'*x = b, where U is a +-- matrix transposed to an upper triangular matrix. +-- +-- The parameter n is the order of matrix U. +-- +-- The matrix U without diagonal elements is specified in the arrays +-- U_ptr, U_ind, and U_val in storage-by-rows format. Diagonal elements +-- of U are specified in the array U_diag, where U_diag[0] is not used, +-- U_diag[i] = u[i,i] for i = 1, ..., n. All these four arrays are not +-- changed on exit. +-- +-- The right-hand side vector b is specified on entry in the array x, +-- where x[0] is not used, and x[i] = b[i] for i = 1, ..., n. On exit +-- the routine stores computed components of the vector of unknowns x +-- in the array x in the same manner. */ + +void ut_solve(int n, int U_ptr[], int U_ind[], double U_val[], + double U_diag[], double x[]) +{ int i, t, beg, end; + double temp; + for (i = 1; i <= n; i++) + { xassert(U_diag[i] != 0.0); + temp = (x[i] /= U_diag[i]); + if (temp == 0.0) continue; + beg = U_ptr[i], end = U_ptr[i+1]; + for (t = beg; t < end; t++) + x[U_ind[t]] -= U_val[t] * temp; + } + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpmat.h b/resources/3rdparty/glpk-4.57/src/glpmat.h new file mode 100644 index 000000000..5b0584371 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpmat.h @@ -0,0 +1,198 @@ +/* glpmat.h (linear algebra routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef GLPMAT_H +#define GLPMAT_H + +/*********************************************************************** +* FULL-VECTOR STORAGE +* +* For a sparse vector x having n elements, ne of which are non-zero, +* the full-vector storage format uses two arrays x_ind and x_vec, which +* are set up as follows: +* +* x_ind is an integer array of length [1+ne]. Location x_ind[0] is +* not used, and locations x_ind[1], ..., x_ind[ne] contain indices of +* non-zero elements in vector x. +* +* x_vec is a floating-point array of length [1+n]. Location x_vec[0] +* is not used, and locations x_vec[1], ..., x_vec[n] contain numeric +* values of ALL elements in vector x, including its zero elements. +* +* Let, for example, the following sparse vector x be given: +* +* (0, 1, 0, 0, 2, 3, 0, 4) +* +* Then the arrays are: +* +* x_ind = { X; 2, 5, 6, 8 } +* +* x_vec = { X; 0, 1, 0, 0, 2, 3, 0, 4 } +* +* COMPRESSED-VECTOR STORAGE +* +* For a sparse vector x having n elements, ne of which are non-zero, +* the compressed-vector storage format uses two arrays x_ind and x_vec, +* which are set up as follows: +* +* x_ind is an integer array of length [1+ne]. Location x_ind[0] is +* not used, and locations x_ind[1], ..., x_ind[ne] contain indices of +* non-zero elements in vector x. +* +* x_vec is a floating-point array of length [1+ne]. Location x_vec[0] +* is not used, and locations x_vec[1], ..., x_vec[ne] contain numeric +* values of corresponding non-zero elements in vector x. +* +* Let, for example, the following sparse vector x be given: +* +* (0, 1, 0, 0, 2, 3, 0, 4) +* +* Then the arrays are: +* +* x_ind = { X; 2, 5, 6, 8 } +* +* x_vec = { X; 1, 2, 3, 4 } +* +* STORAGE-BY-ROWS +* +* For a sparse matrix A, which has m rows, n columns, and ne non-zero +* elements the storage-by-rows format uses three arrays A_ptr, A_ind, +* and A_val, which are set up as follows: +* +* A_ptr is an integer array of length [1+m+1] also called "row pointer +* array". It contains the relative starting positions of each row of A +* in the arrays A_ind and A_val, i.e. element A_ptr[i], 1 <= i <= m, +* indicates where row i begins in the arrays A_ind and A_val. If all +* elements in row i are zero, then A_ptr[i] = A_ptr[i+1]. Location +* A_ptr[0] is not used, location A_ptr[1] must contain 1, and location +* A_ptr[m+1] must contain ne+1 that indicates the position after the +* last element in the arrays A_ind and A_val. +* +* A_ind is an integer array of length [1+ne]. Location A_ind[0] is not +* used, and locations A_ind[1], ..., A_ind[ne] contain column indices +* of (non-zero) elements in matrix A. +* +* A_val is a floating-point array of length [1+ne]. Location A_val[0] +* is not used, and locations A_val[1], ..., A_val[ne] contain numeric +* values of non-zero elements in matrix A. +* +* Non-zero elements of matrix A are stored contiguously, and the rows +* of matrix A are stored consecutively from 1 to m in the arrays A_ind +* and A_val. The elements in each row of A may be stored in any order +* in A_ind and A_val. Note that elements with duplicate column indices +* are not allowed. +* +* Let, for example, the following sparse matrix A be given: +* +* | 11 . 13 . . . | +* | 21 22 . 24 . . | +* | . 32 33 . . . | +* | . . 43 44 . 46 | +* | . . . . . . | +* | 61 62 . . . 66 | +* +* Then the arrays are: +* +* A_ptr = { X; 1, 3, 6, 8, 11, 11; 14 } +* +* A_ind = { X; 1, 3; 4, 2, 1; 2, 3; 4, 3, 6; 1, 2, 6 } +* +* A_val = { X; 11, 13; 24, 22, 21; 32, 33; 44, 43, 46; 61, 62, 66 } +* +* PERMUTATION MATRICES +* +* Let P be a permutation matrix of the order n. It is represented as +* an integer array P_per of length [1+n+n] as follows: if p[i,j] = 1, +* then P_per[i] = j and P_per[n+j] = i. Location P_per[0] is not used. +* +* Let A' = P*A. If i-th row of A corresponds to i'-th row of A', then +* P_per[i'] = i and P_per[n+i] = i'. +* +* References: +* +* 1. Gustavson F.G. Some basic techniques for solving sparse systems of +* linear equations. In Rose and Willoughby (1972), pp. 41-52. +* +* 2. Basic Linear Algebra Subprograms Technical (BLAST) Forum Standard. +* University of Tennessee (2001). */ + +#define check_fvs _glp_mat_check_fvs +int check_fvs(int n, int nnz, int ind[], double vec[]); +/* check sparse vector in full-vector storage format */ + +#define check_pattern _glp_mat_check_pattern +int check_pattern(int m, int n, int A_ptr[], int A_ind[]); +/* check pattern of sparse matrix */ + +#define transpose _glp_mat_transpose +void transpose(int m, int n, int A_ptr[], int A_ind[], double A_val[], + int AT_ptr[], int AT_ind[], double AT_val[]); +/* transpose sparse matrix */ + +#define adat_symbolic _glp_mat_adat_symbolic +int *adat_symbolic(int m, int n, int P_per[], int A_ptr[], int A_ind[], + int S_ptr[]); +/* compute S = P*A*D*A'*P' (symbolic phase) */ + +#define adat_numeric _glp_mat_adat_numeric +void adat_numeric(int m, int n, int P_per[], + int A_ptr[], int A_ind[], double A_val[], double D_diag[], + int S_ptr[], int S_ind[], double S_val[], double S_diag[]); +/* compute S = P*A*D*A'*P' (numeric phase) */ + +#define min_degree _glp_mat_min_degree +void min_degree(int n, int A_ptr[], int A_ind[], int P_per[]); +/* minimum degree ordering */ + +#define amd_order1 _glp_mat_amd_order1 +void amd_order1(int n, int A_ptr[], int A_ind[], int P_per[]); +/* approximate minimum degree ordering (AMD) */ + +#define symamd_ord _glp_mat_symamd_ord +void symamd_ord(int n, int A_ptr[], int A_ind[], int P_per[]); +/* approximate minimum degree ordering (SYMAMD) */ + +#define chol_symbolic _glp_mat_chol_symbolic +int *chol_symbolic(int n, int A_ptr[], int A_ind[], int U_ptr[]); +/* compute Cholesky factorization (symbolic phase) */ + +#define chol_numeric _glp_mat_chol_numeric +int chol_numeric(int n, + int A_ptr[], int A_ind[], double A_val[], double A_diag[], + int U_ptr[], int U_ind[], double U_val[], double U_diag[]); +/* compute Cholesky factorization (numeric phase) */ + +#define u_solve _glp_mat_u_solve +void u_solve(int n, int U_ptr[], int U_ind[], double U_val[], + double U_diag[], double x[]); +/* solve upper triangular system U*x = b */ + +#define ut_solve _glp_mat_ut_solve +void ut_solve(int n, int U_ptr[], int U_ind[], double U_val[], + double U_diag[], double x[]); +/* solve lower triangular system U'*x = b */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpmpl.h b/resources/3rdparty/glpk-4.57/src/glpmpl.h new file mode 100644 index 000000000..34445d30a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpmpl.h @@ -0,0 +1,2594 @@ +/* glpmpl.h (GNU MathProg translator) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef GLPMPL_H +#define GLPMPL_H + +#include "avl.h" +#include "dmp.h" +#include "env.h" +#include "misc.h" +#include "rng.h" + +#if 0 /* 22/I-2013 */ +typedef struct MPL MPL; +#else +typedef struct glp_tran MPL; +#endif +typedef char STRING; +typedef struct SYMBOL SYMBOL; +typedef struct TUPLE TUPLE; +typedef struct ARRAY ELEMSET; +typedef struct ELEMVAR ELEMVAR; +typedef struct FORMULA FORMULA; +typedef struct ELEMCON ELEMCON; +typedef union VALUE VALUE; +typedef struct ARRAY ARRAY; +typedef struct MEMBER MEMBER; +#if 1 +/* many C compilers have DOMAIN declared in :( */ +#undef DOMAIN +#define DOMAIN DOMAIN1 +#endif +typedef struct DOMAIN DOMAIN; +typedef struct DOMAIN_BLOCK DOMAIN_BLOCK; +typedef struct DOMAIN_SLOT DOMAIN_SLOT; +typedef struct SET SET; +typedef struct WITHIN WITHIN; +typedef struct GADGET GADGET; +typedef struct PARAMETER PARAMETER; +typedef struct CONDITION CONDITION; +typedef struct VARIABLE VARIABLE; +typedef struct CONSTRAINT CONSTRAINT; +typedef struct TABLE TABLE; +typedef struct TABARG TABARG; +typedef struct TABFLD TABFLD; +typedef struct TABIN TABIN; +typedef struct TABOUT TABOUT; +typedef struct TABDCA TABDCA; +typedef union OPERANDS OPERANDS; +typedef struct ARG_LIST ARG_LIST; +typedef struct CODE CODE; +typedef struct CHECK CHECK; +typedef struct DISPLAY DISPLAY; +typedef struct DISPLAY1 DISPLAY1; +typedef struct PRINTF PRINTF; +typedef struct PRINTF1 PRINTF1; +typedef struct FOR FOR; +typedef struct STATEMENT STATEMENT; +typedef struct TUPLE SLICE; + +/**********************************************************************/ +/* * * TRANSLATOR DATABASE * * */ +/**********************************************************************/ + +#define A_BINARY 101 /* something binary */ +#define A_CHECK 102 /* check statement */ +#define A_CONSTRAINT 103 /* model constraint */ +#define A_DISPLAY 104 /* display statement */ +#define A_ELEMCON 105 /* elemental constraint/objective */ +#define A_ELEMSET 106 /* elemental set */ +#define A_ELEMVAR 107 /* elemental variable */ +#define A_EXPRESSION 108 /* expression */ +#define A_FOR 109 /* for statement */ +#define A_FORMULA 110 /* formula */ +#define A_INDEX 111 /* dummy index */ +#define A_INPUT 112 /* input table */ +#define A_INTEGER 113 /* something integer */ +#define A_LOGICAL 114 /* something logical */ +#define A_MAXIMIZE 115 /* objective has to be maximized */ +#define A_MINIMIZE 116 /* objective has to be minimized */ +#define A_NONE 117 /* nothing */ +#define A_NUMERIC 118 /* something numeric */ +#define A_OUTPUT 119 /* output table */ +#define A_PARAMETER 120 /* model parameter */ +#define A_PRINTF 121 /* printf statement */ +#define A_SET 122 /* model set */ +#define A_SOLVE 123 /* solve statement */ +#define A_SYMBOLIC 124 /* something symbolic */ +#define A_TABLE 125 /* data table */ +#define A_TUPLE 126 /* n-tuple */ +#define A_VARIABLE 127 /* model variable */ + +#define MAX_LENGTH 100 +/* maximal length of any symbolic value (this includes symbolic names, + numeric and string literals, and all symbolic values that may appear + during the evaluation phase) */ + +#define CONTEXT_SIZE 60 +/* size of the context queue, in characters */ + +#define OUTBUF_SIZE 1024 +/* size of the output buffer, in characters */ + +#if 0 /* 22/I-2013 */ +struct MPL +#else +struct glp_tran +#endif +{ /* translator database */ + /*--------------------------------------------------------------*/ + /* scanning segment */ + int line; + /* number of the current text line */ + int c; + /* the current character or EOF */ + int token; + /* the current token: */ +#define T_EOF 201 /* end of file */ +#define T_NAME 202 /* symbolic name (model section only) */ +#define T_SYMBOL 203 /* symbol (data section only) */ +#define T_NUMBER 204 /* numeric literal */ +#define T_STRING 205 /* string literal */ +#define T_AND 206 /* and && */ +#define T_BY 207 /* by */ +#define T_CROSS 208 /* cross */ +#define T_DIFF 209 /* diff */ +#define T_DIV 210 /* div */ +#define T_ELSE 211 /* else */ +#define T_IF 212 /* if */ +#define T_IN 213 /* in */ +#define T_INFINITY 214 /* Infinity */ +#define T_INTER 215 /* inter */ +#define T_LESS 216 /* less */ +#define T_MOD 217 /* mod */ +#define T_NOT 218 /* not ! */ +#define T_OR 219 /* or || */ +#define T_SPTP 220 /* s.t. */ +#define T_SYMDIFF 221 /* symdiff */ +#define T_THEN 222 /* then */ +#define T_UNION 223 /* union */ +#define T_WITHIN 224 /* within */ +#define T_PLUS 225 /* + */ +#define T_MINUS 226 /* - */ +#define T_ASTERISK 227 /* * */ +#define T_SLASH 228 /* / */ +#define T_POWER 229 /* ^ ** */ +#define T_LT 230 /* < */ +#define T_LE 231 /* <= */ +#define T_EQ 232 /* = == */ +#define T_GE 233 /* >= */ +#define T_GT 234 /* > */ +#define T_NE 235 /* <> != */ +#define T_CONCAT 236 /* & */ +#define T_BAR 237 /* | */ +#define T_POINT 238 /* . */ +#define T_COMMA 239 /* , */ +#define T_COLON 240 /* : */ +#define T_SEMICOLON 241 /* ; */ +#define T_ASSIGN 242 /* := */ +#define T_DOTS 243 /* .. */ +#define T_LEFT 244 /* ( */ +#define T_RIGHT 245 /* ) */ +#define T_LBRACKET 246 /* [ */ +#define T_RBRACKET 247 /* ] */ +#define T_LBRACE 248 /* { */ +#define T_RBRACE 249 /* } */ +#define T_APPEND 250 /* >> */ +#define T_TILDE 251 /* ~ */ +#define T_INPUT 252 /* <- */ + int imlen; + /* length of the current token */ + char *image; /* char image[MAX_LENGTH+1]; */ + /* image of the current token */ + double value; + /* value of the current token (for T_NUMBER only) */ + int b_token; + /* the previous token */ + int b_imlen; + /* length of the previous token */ + char *b_image; /* char b_image[MAX_LENGTH+1]; */ + /* image of the previous token */ + double b_value; + /* value of the previous token (if token is T_NUMBER) */ + int f_dots; + /* if this flag is set, the next token should be recognized as + T_DOTS, not as T_POINT */ + int f_scan; + /* if this flag is set, the next token is already scanned */ + int f_token; + /* the next token */ + int f_imlen; + /* length of the next token */ + char *f_image; /* char f_image[MAX_LENGTH+1]; */ + /* image of the next token */ + double f_value; + /* value of the next token (if token is T_NUMBER) */ + char *context; /* char context[CONTEXT_SIZE]; */ + /* context circular queue (not null-terminated!) */ + int c_ptr; + /* pointer to the current position in the context queue */ + int flag_d; + /* if this flag is set, the data section is being processed */ + /*--------------------------------------------------------------*/ + /* translating segment */ + DMP *pool; + /* memory pool used to allocate all data instances created during + the translation phase */ + AVL *tree; + /* symbolic name table: + node.type = A_INDEX => node.link -> DOMAIN_SLOT + node.type = A_SET => node.link -> SET + node.type = A_PARAMETER => node.link -> PARAMETER + node.type = A_VARIABLE => node.link -> VARIABLE + node.type = A_CONSTRANT => node.link -> CONSTRAINT */ + STATEMENT *model; + /* linked list of model statements in the original order */ + int flag_x; + /* if this flag is set, the current token being left parenthesis + begins a slice that allows recognizing any undeclared symbolic + names as dummy indices; this flag is automatically reset once + the next token has been scanned */ + int as_within; + /* the warning "in understood as within" has been issued */ + int as_in; + /* the warning "within understood as in" has been issued */ + int as_binary; + /* the warning "logical understood as binary" has been issued */ + int flag_s; + /* if this flag is set, the solve statement has been parsed */ + /*--------------------------------------------------------------*/ + /* common segment */ + DMP *strings; + /* memory pool to allocate STRING data structures */ + DMP *symbols; + /* memory pool to allocate SYMBOL data structures */ + DMP *tuples; + /* memory pool to allocate TUPLE data structures */ + DMP *arrays; + /* memory pool to allocate ARRAY data structures */ + DMP *members; + /* memory pool to allocate MEMBER data structures */ + DMP *elemvars; + /* memory pool to allocate ELEMVAR data structures */ + DMP *formulae; + /* memory pool to allocate FORMULA data structures */ + DMP *elemcons; + /* memory pool to allocate ELEMCON data structures */ + ARRAY *a_list; + /* linked list of all arrays in the database */ + char *sym_buf; /* char sym_buf[255+1]; */ + /* working buffer used by the routine format_symbol */ + char *tup_buf; /* char tup_buf[255+1]; */ + /* working buffer used by the routine format_tuple */ + /*--------------------------------------------------------------*/ + /* generating/postsolving segment */ + RNG *rand; + /* pseudo-random number generator */ + int flag_p; + /* if this flag is set, the postsolving phase is in effect */ + STATEMENT *stmt; + /* model statement being currently executed */ + TABDCA *dca; + /* pointer to table driver communication area for table statement + currently executed */ + int m; + /* number of rows in the problem, m >= 0 */ + int n; + /* number of columns in the problem, n >= 0 */ + ELEMCON **row; /* ELEMCON *row[1+m]; */ + /* row[0] is not used; + row[i] is elemental constraint or objective, which corresponds + to i-th row of the problem, 1 <= i <= m */ + ELEMVAR **col; /* ELEMVAR *col[1+n]; */ + /* col[0] is not used; + col[j] is elemental variable, which corresponds to j-th column + of the problem, 1 <= j <= n */ + /*--------------------------------------------------------------*/ + /* input/output segment */ + glp_file *in_fp; + /* stream assigned to the input text file */ + char *in_file; + /* name of the input text file */ + glp_file *out_fp; + /* stream assigned to the output text file used to write all data + produced by display and printf statements; NULL means the data + should be sent to stdout via the routine xprintf */ + char *out_file; + /* name of the output text file */ +#if 0 /* 08/XI-2009 */ + char *out_buf; /* char out_buf[OUTBUF_SIZE] */ + /* buffer to accumulate output data */ + int out_cnt; + /* count of data bytes stored in the output buffer */ +#endif + glp_file *prt_fp; + /* stream assigned to the print text file; may be NULL */ + char *prt_file; + /* name of the output print file */ + /*--------------------------------------------------------------*/ + /* solver interface segment */ + jmp_buf jump; + /* jump address for non-local go to in case of error */ + int phase; + /* phase of processing: + 0 - database is being or has been initialized + 1 - model section is being or has been read + 2 - data section is being or has been read + 3 - model is being or has been generated/postsolved + 4 - model processing error has occurred */ + char *mod_file; + /* name of the input text file, which contains model section */ + char *mpl_buf; /* char mpl_buf[255+1]; */ + /* working buffer used by some interface routines */ +}; + +/**********************************************************************/ +/* * * PROCESSING MODEL SECTION * * */ +/**********************************************************************/ + +#define alloc(type) ((type *)dmp_get_atomv(mpl->pool, sizeof(type))) +/* allocate atom of given type */ + +#define enter_context _glp_mpl_enter_context +void enter_context(MPL *mpl); +/* enter current token into context queue */ + +#define print_context _glp_mpl_print_context +void print_context(MPL *mpl); +/* print current content of context queue */ + +#define get_char _glp_mpl_get_char +void get_char(MPL *mpl); +/* scan next character from input text file */ + +#define append_char _glp_mpl_append_char +void append_char(MPL *mpl); +/* append character to current token */ + +#define get_token _glp_mpl_get_token +void get_token(MPL *mpl); +/* scan next token from input text file */ + +#define unget_token _glp_mpl_unget_token +void unget_token(MPL *mpl); +/* return current token back to input stream */ + +#define is_keyword _glp_mpl_is_keyword +int is_keyword(MPL *mpl, char *keyword); +/* check if current token is given non-reserved keyword */ + +#define is_reserved _glp_mpl_is_reserved +int is_reserved(MPL *mpl); +/* check if current token is reserved keyword */ + +#define make_code _glp_mpl_make_code +CODE *make_code(MPL *mpl, int op, OPERANDS *arg, int type, int dim); +/* generate pseudo-code (basic routine) */ + +#define make_unary _glp_mpl_make_unary +CODE *make_unary(MPL *mpl, int op, CODE *x, int type, int dim); +/* generate pseudo-code for unary operation */ + +#define make_binary _glp_mpl_make_binary +CODE *make_binary(MPL *mpl, int op, CODE *x, CODE *y, int type, + int dim); +/* generate pseudo-code for binary operation */ + +#define make_ternary _glp_mpl_make_ternary +CODE *make_ternary(MPL *mpl, int op, CODE *x, CODE *y, CODE *z, + int type, int dim); +/* generate pseudo-code for ternary operation */ + +#define numeric_literal _glp_mpl_numeric_literal +CODE *numeric_literal(MPL *mpl); +/* parse reference to numeric literal */ + +#define string_literal _glp_mpl_string_literal +CODE *string_literal(MPL *mpl); +/* parse reference to string literal */ + +#define create_arg_list _glp_mpl_create_arg_list +ARG_LIST *create_arg_list(MPL *mpl); +/* create empty operands list */ + +#define expand_arg_list _glp_mpl_expand_arg_list +ARG_LIST *expand_arg_list(MPL *mpl, ARG_LIST *list, CODE *x); +/* append operand to operands list */ + +#define arg_list_len _glp_mpl_arg_list_len +int arg_list_len(MPL *mpl, ARG_LIST *list); +/* determine length of operands list */ + +#define subscript_list _glp_mpl_subscript_list +ARG_LIST *subscript_list(MPL *mpl); +/* parse subscript list */ + +#define object_reference _glp_mpl_object_reference +CODE *object_reference(MPL *mpl); +/* parse reference to named object */ + +#define numeric_argument _glp_mpl_numeric_argument +CODE *numeric_argument(MPL *mpl, char *func); +/* parse argument passed to built-in function */ + +#define symbolic_argument _glp_mpl_symbolic_argument +CODE *symbolic_argument(MPL *mpl, char *func); + +#define elemset_argument _glp_mpl_elemset_argument +CODE *elemset_argument(MPL *mpl, char *func); + +#define function_reference _glp_mpl_function_reference +CODE *function_reference(MPL *mpl); +/* parse reference to built-in function */ + +#define create_domain _glp_mpl_create_domain +DOMAIN *create_domain(MPL *mpl); +/* create empty domain */ + +#define create_block _glp_mpl_create_block +DOMAIN_BLOCK *create_block(MPL *mpl); +/* create empty domain block */ + +#define append_block _glp_mpl_append_block +void append_block(MPL *mpl, DOMAIN *domain, DOMAIN_BLOCK *block); +/* append domain block to specified domain */ + +#define append_slot _glp_mpl_append_slot +DOMAIN_SLOT *append_slot(MPL *mpl, DOMAIN_BLOCK *block, char *name, + CODE *code); +/* create and append new slot to domain block */ + +#define expression_list _glp_mpl_expression_list +CODE *expression_list(MPL *mpl); +/* parse expression list */ + +#define literal_set _glp_mpl_literal_set +CODE *literal_set(MPL *mpl, CODE *code); +/* parse literal set */ + +#define indexing_expression _glp_mpl_indexing_expression +DOMAIN *indexing_expression(MPL *mpl); +/* parse indexing expression */ + +#define close_scope _glp_mpl_close_scope +void close_scope(MPL *mpl, DOMAIN *domain); +/* close scope of indexing expression */ + +#define iterated_expression _glp_mpl_iterated_expression +CODE *iterated_expression(MPL *mpl); +/* parse iterated expression */ + +#define domain_arity _glp_mpl_domain_arity +int domain_arity(MPL *mpl, DOMAIN *domain); +/* determine arity of domain */ + +#define set_expression _glp_mpl_set_expression +CODE *set_expression(MPL *mpl); +/* parse set expression */ + +#define branched_expression _glp_mpl_branched_expression +CODE *branched_expression(MPL *mpl); +/* parse conditional expression */ + +#define primary_expression _glp_mpl_primary_expression +CODE *primary_expression(MPL *mpl); +/* parse primary expression */ + +#define error_preceding _glp_mpl_error_preceding +void error_preceding(MPL *mpl, char *opstr); +/* raise error if preceding operand has wrong type */ + +#define error_following _glp_mpl_error_following +void error_following(MPL *mpl, char *opstr); +/* raise error if following operand has wrong type */ + +#define error_dimension _glp_mpl_error_dimension +void error_dimension(MPL *mpl, char *opstr, int dim1, int dim2); +/* raise error if operands have different dimension */ + +#define expression_0 _glp_mpl_expression_0 +CODE *expression_0(MPL *mpl); +/* parse expression of level 0 */ + +#define expression_1 _glp_mpl_expression_1 +CODE *expression_1(MPL *mpl); +/* parse expression of level 1 */ + +#define expression_2 _glp_mpl_expression_2 +CODE *expression_2(MPL *mpl); +/* parse expression of level 2 */ + +#define expression_3 _glp_mpl_expression_3 +CODE *expression_3(MPL *mpl); +/* parse expression of level 3 */ + +#define expression_4 _glp_mpl_expression_4 +CODE *expression_4(MPL *mpl); +/* parse expression of level 4 */ + +#define expression_5 _glp_mpl_expression_5 +CODE *expression_5(MPL *mpl); +/* parse expression of level 5 */ + +#define expression_6 _glp_mpl_expression_6 +CODE *expression_6(MPL *mpl); +/* parse expression of level 6 */ + +#define expression_7 _glp_mpl_expression_7 +CODE *expression_7(MPL *mpl); +/* parse expression of level 7 */ + +#define expression_8 _glp_mpl_expression_8 +CODE *expression_8(MPL *mpl); +/* parse expression of level 8 */ + +#define expression_9 _glp_mpl_expression_9 +CODE *expression_9(MPL *mpl); +/* parse expression of level 9 */ + +#define expression_10 _glp_mpl_expression_10 +CODE *expression_10(MPL *mpl); +/* parse expression of level 10 */ + +#define expression_11 _glp_mpl_expression_11 +CODE *expression_11(MPL *mpl); +/* parse expression of level 11 */ + +#define expression_12 _glp_mpl_expression_12 +CODE *expression_12(MPL *mpl); +/* parse expression of level 12 */ + +#define expression_13 _glp_mpl_expression_13 +CODE *expression_13(MPL *mpl); +/* parse expression of level 13 */ + +#define set_statement _glp_mpl_set_statement +SET *set_statement(MPL *mpl); +/* parse set statement */ + +#define parameter_statement _glp_mpl_parameter_statement +PARAMETER *parameter_statement(MPL *mpl); +/* parse parameter statement */ + +#define variable_statement _glp_mpl_variable_statement +VARIABLE *variable_statement(MPL *mpl); +/* parse variable statement */ + +#define constraint_statement _glp_mpl_constraint_statement +CONSTRAINT *constraint_statement(MPL *mpl); +/* parse constraint statement */ + +#define objective_statement _glp_mpl_objective_statement +CONSTRAINT *objective_statement(MPL *mpl); +/* parse objective statement */ + +#define table_statement _glp_mpl_table_statement +TABLE *table_statement(MPL *mpl); +/* parse table statement */ + +#define solve_statement _glp_mpl_solve_statement +void *solve_statement(MPL *mpl); +/* parse solve statement */ + +#define check_statement _glp_mpl_check_statement +CHECK *check_statement(MPL *mpl); +/* parse check statement */ + +#define display_statement _glp_mpl_display_statement +DISPLAY *display_statement(MPL *mpl); +/* parse display statement */ + +#define printf_statement _glp_mpl_printf_statement +PRINTF *printf_statement(MPL *mpl); +/* parse printf statement */ + +#define for_statement _glp_mpl_for_statement +FOR *for_statement(MPL *mpl); +/* parse for statement */ + +#define end_statement _glp_mpl_end_statement +void end_statement(MPL *mpl); +/* parse end statement */ + +#define simple_statement _glp_mpl_simple_statement +STATEMENT *simple_statement(MPL *mpl, int spec); +/* parse simple statement */ + +#define model_section _glp_mpl_model_section +void model_section(MPL *mpl); +/* parse model section */ + +/**********************************************************************/ +/* * * PROCESSING DATA SECTION * * */ +/**********************************************************************/ + +#if 2 + 2 == 5 +struct SLICE /* see TUPLE */ +{ /* component of slice; the slice itself is associated with its + first component; slices are similar to n-tuples with exception + that some slice components (which are indicated by asterisks) + don't refer to any symbols */ + SYMBOL *sym; + /* symbol, which this component refers to; can be NULL */ + SLICE *next; + /* the next component of slice */ +}; +#endif + +#define create_slice _glp_mpl_create_slice +SLICE *create_slice(MPL *mpl); +/* create slice */ + +#define expand_slice _glp_mpl_expand_slice +SLICE *expand_slice +( MPL *mpl, + SLICE *slice, /* destroyed */ + SYMBOL *sym /* destroyed */ +); +/* append new component to slice */ + +#define slice_dimen _glp_mpl_slice_dimen +int slice_dimen +( MPL *mpl, + SLICE *slice /* not changed */ +); +/* determine dimension of slice */ + +#define slice_arity _glp_mpl_slice_arity +int slice_arity +( MPL *mpl, + SLICE *slice /* not changed */ +); +/* determine arity of slice */ + +#define fake_slice _glp_mpl_fake_slice +SLICE *fake_slice(MPL *mpl, int dim); +/* create fake slice of all asterisks */ + +#define delete_slice _glp_mpl_delete_slice +void delete_slice +( MPL *mpl, + SLICE *slice /* destroyed */ +); +/* delete slice */ + +#define is_number _glp_mpl_is_number +int is_number(MPL *mpl); +/* check if current token is number */ + +#define is_symbol _glp_mpl_is_symbol +int is_symbol(MPL *mpl); +/* check if current token is symbol */ + +#define is_literal _glp_mpl_is_literal +int is_literal(MPL *mpl, char *literal); +/* check if current token is given symbolic literal */ + +#define read_number _glp_mpl_read_number +double read_number(MPL *mpl); +/* read number */ + +#define read_symbol _glp_mpl_read_symbol +SYMBOL *read_symbol(MPL *mpl); +/* read symbol */ + +#define read_slice _glp_mpl_read_slice +SLICE *read_slice +( MPL *mpl, + char *name, /* not changed */ + int dim +); +/* read slice */ + +#define select_set _glp_mpl_select_set +SET *select_set +( MPL *mpl, + char *name /* not changed */ +); +/* select set to saturate it with elemental sets */ + +#define simple_format _glp_mpl_simple_format +void simple_format +( MPL *mpl, + SET *set, /* not changed */ + MEMBER *memb, /* modified */ + SLICE *slice /* not changed */ +); +/* read set data block in simple format */ + +#define matrix_format _glp_mpl_matrix_format +void matrix_format +( MPL *mpl, + SET *set, /* not changed */ + MEMBER *memb, /* modified */ + SLICE *slice, /* not changed */ + int tr +); +/* read set data block in matrix format */ + +#define set_data _glp_mpl_set_data +void set_data(MPL *mpl); +/* read set data */ + +#define select_parameter _glp_mpl_select_parameter +PARAMETER *select_parameter +( MPL *mpl, + char *name /* not changed */ +); +/* select parameter to saturate it with data */ + +#define set_default _glp_mpl_set_default +void set_default +( MPL *mpl, + PARAMETER *par, /* not changed */ + SYMBOL *altval /* destroyed */ +); +/* set default parameter value */ + +#define read_value _glp_mpl_read_value +MEMBER *read_value +( MPL *mpl, + PARAMETER *par, /* not changed */ + TUPLE *tuple /* destroyed */ +); +/* read value and assign it to parameter member */ + +#define plain_format _glp_mpl_plain_format +void plain_format +( MPL *mpl, + PARAMETER *par, /* not changed */ + SLICE *slice /* not changed */ +); +/* read parameter data block in plain format */ + +#define tabular_format _glp_mpl_tabular_format +void tabular_format +( MPL *mpl, + PARAMETER *par, /* not changed */ + SLICE *slice, /* not changed */ + int tr +); +/* read parameter data block in tabular format */ + +#define tabbing_format _glp_mpl_tabbing_format +void tabbing_format +( MPL *mpl, + SYMBOL *altval /* not changed */ +); +/* read parameter data block in tabbing format */ + +#define parameter_data _glp_mpl_parameter_data +void parameter_data(MPL *mpl); +/* read parameter data */ + +#define data_section _glp_mpl_data_section +void data_section(MPL *mpl); +/* read data section */ + +/**********************************************************************/ +/* * * FLOATING-POINT NUMBERS * * */ +/**********************************************************************/ + +#define fp_add _glp_mpl_fp_add +double fp_add(MPL *mpl, double x, double y); +/* floating-point addition */ + +#define fp_sub _glp_mpl_fp_sub +double fp_sub(MPL *mpl, double x, double y); +/* floating-point subtraction */ + +#define fp_less _glp_mpl_fp_less +double fp_less(MPL *mpl, double x, double y); +/* floating-point non-negative subtraction */ + +#define fp_mul _glp_mpl_fp_mul +double fp_mul(MPL *mpl, double x, double y); +/* floating-point multiplication */ + +#define fp_div _glp_mpl_fp_div +double fp_div(MPL *mpl, double x, double y); +/* floating-point division */ + +#define fp_idiv _glp_mpl_fp_idiv +double fp_idiv(MPL *mpl, double x, double y); +/* floating-point quotient of exact division */ + +#define fp_mod _glp_mpl_fp_mod +double fp_mod(MPL *mpl, double x, double y); +/* floating-point remainder of exact division */ + +#define fp_power _glp_mpl_fp_power +double fp_power(MPL *mpl, double x, double y); +/* floating-point exponentiation (raise to power) */ + +#define fp_exp _glp_mpl_fp_exp +double fp_exp(MPL *mpl, double x); +/* floating-point base-e exponential */ + +#define fp_log _glp_mpl_fp_log +double fp_log(MPL *mpl, double x); +/* floating-point natural logarithm */ + +#define fp_log10 _glp_mpl_fp_log10 +double fp_log10(MPL *mpl, double x); +/* floating-point common (decimal) logarithm */ + +#define fp_sqrt _glp_mpl_fp_sqrt +double fp_sqrt(MPL *mpl, double x); +/* floating-point square root */ + +#define fp_sin _glp_mpl_fp_sin +double fp_sin(MPL *mpl, double x); +/* floating-point trigonometric sine */ + +#define fp_cos _glp_mpl_fp_cos +double fp_cos(MPL *mpl, double x); +/* floating-point trigonometric cosine */ + +#define fp_atan _glp_mpl_fp_atan +double fp_atan(MPL *mpl, double x); +/* floating-point trigonometric arctangent */ + +#define fp_atan2 _glp_mpl_fp_atan2 +double fp_atan2(MPL *mpl, double y, double x); +/* floating-point trigonometric arctangent */ + +#define fp_round _glp_mpl_fp_round +double fp_round(MPL *mpl, double x, double n); +/* round floating-point value to n fractional digits */ + +#define fp_trunc _glp_mpl_fp_trunc +double fp_trunc(MPL *mpl, double x, double n); +/* truncate floating-point value to n fractional digits */ + +/**********************************************************************/ +/* * * PSEUDO-RANDOM NUMBER GENERATORS * * */ +/**********************************************************************/ + +#define fp_irand224 _glp_mpl_fp_irand224 +double fp_irand224(MPL *mpl); +/* pseudo-random integer in the range [0, 2^24) */ + +#define fp_uniform01 _glp_mpl_fp_uniform01 +double fp_uniform01(MPL *mpl); +/* pseudo-random number in the range [0, 1) */ + +#define fp_uniform _glp_mpl_uniform +double fp_uniform(MPL *mpl, double a, double b); +/* pseudo-random number in the range [a, b) */ + +#define fp_normal01 _glp_mpl_fp_normal01 +double fp_normal01(MPL *mpl); +/* Gaussian random variate with mu = 0 and sigma = 1 */ + +#define fp_normal _glp_mpl_fp_normal +double fp_normal(MPL *mpl, double mu, double sigma); +/* Gaussian random variate with specified mu and sigma */ + +/**********************************************************************/ +/* * * DATE/TIME * * */ +/**********************************************************************/ + +#define fn_gmtime _glp_mpl_fn_gmtime +double fn_gmtime(MPL *mpl); +/* obtain the current calendar time (UTC) */ + +#define fn_str2time _glp_mpl_fn_str2time +double fn_str2time(MPL *mpl, const char *str, const char *fmt); +/* convert character string to the calendar time */ + +#define fn_time2str _glp_mpl_fn_time2str +void fn_time2str(MPL *mpl, char *str, double t, const char *fmt); +/* convert the calendar time to character string */ + +/**********************************************************************/ +/* * * CHARACTER STRINGS * * */ +/**********************************************************************/ + +#define create_string _glp_mpl_create_string +STRING *create_string +( MPL *mpl, + char buf[MAX_LENGTH+1] /* not changed */ +); +/* create character string */ + +#define copy_string _glp_mpl_copy_string +STRING *copy_string +( MPL *mpl, + STRING *str /* not changed */ +); +/* make copy of character string */ + +#define compare_strings _glp_mpl_compare_strings +int compare_strings +( MPL *mpl, + STRING *str1, /* not changed */ + STRING *str2 /* not changed */ +); +/* compare one character string with another */ + +#define fetch_string _glp_mpl_fetch_string +char *fetch_string +( MPL *mpl, + STRING *str, /* not changed */ + char buf[MAX_LENGTH+1] /* modified */ +); +/* extract content of character string */ + +#define delete_string _glp_mpl_delete_string +void delete_string +( MPL *mpl, + STRING *str /* destroyed */ +); +/* delete character string */ + +/**********************************************************************/ +/* * * SYMBOLS * * */ +/**********************************************************************/ + +struct SYMBOL +{ /* symbol (numeric or abstract quantity) */ + double num; + /* numeric value of symbol (used only if str == NULL) */ + STRING *str; + /* abstract value of symbol (used only if str != NULL) */ +}; + +#define create_symbol_num _glp_mpl_create_symbol_num +SYMBOL *create_symbol_num(MPL *mpl, double num); +/* create symbol of numeric type */ + +#define create_symbol_str _glp_mpl_create_symbol_str +SYMBOL *create_symbol_str +( MPL *mpl, + STRING *str /* destroyed */ +); +/* create symbol of abstract type */ + +#define copy_symbol _glp_mpl_copy_symbol +SYMBOL *copy_symbol +( MPL *mpl, + SYMBOL *sym /* not changed */ +); +/* make copy of symbol */ + +#define compare_symbols _glp_mpl_compare_symbols +int compare_symbols +( MPL *mpl, + SYMBOL *sym1, /* not changed */ + SYMBOL *sym2 /* not changed */ +); +/* compare one symbol with another */ + +#define delete_symbol _glp_mpl_delete_symbol +void delete_symbol +( MPL *mpl, + SYMBOL *sym /* destroyed */ +); +/* delete symbol */ + +#define format_symbol _glp_mpl_format_symbol +char *format_symbol +( MPL *mpl, + SYMBOL *sym /* not changed */ +); +/* format symbol for displaying or printing */ + +#define concat_symbols _glp_mpl_concat_symbols +SYMBOL *concat_symbols +( MPL *mpl, + SYMBOL *sym1, /* destroyed */ + SYMBOL *sym2 /* destroyed */ +); +/* concatenate one symbol with another */ + +/**********************************************************************/ +/* * * N-TUPLES * * */ +/**********************************************************************/ + +struct TUPLE +{ /* component of n-tuple; the n-tuple itself is associated with + its first component; (note that 0-tuple has no components) */ + SYMBOL *sym; + /* symbol, which the component refers to; cannot be NULL */ + TUPLE *next; + /* the next component of n-tuple */ +}; + +#define create_tuple _glp_mpl_create_tuple +TUPLE *create_tuple(MPL *mpl); +/* create n-tuple */ + +#define expand_tuple _glp_mpl_expand_tuple +TUPLE *expand_tuple +( MPL *mpl, + TUPLE *tuple, /* destroyed */ + SYMBOL *sym /* destroyed */ +); +/* append symbol to n-tuple */ + +#define tuple_dimen _glp_mpl_tuple_dimen +int tuple_dimen +( MPL *mpl, + TUPLE *tuple /* not changed */ +); +/* determine dimension of n-tuple */ + +#define copy_tuple _glp_mpl_copy_tuple +TUPLE *copy_tuple +( MPL *mpl, + TUPLE *tuple /* not changed */ +); +/* make copy of n-tuple */ + +#define compare_tuples _glp_mpl_compare_tuples +int compare_tuples +( MPL *mpl, + TUPLE *tuple1, /* not changed */ + TUPLE *tuple2 /* not changed */ +); +/* compare one n-tuple with another */ + +#define build_subtuple _glp_mpl_build_subtuple +TUPLE *build_subtuple +( MPL *mpl, + TUPLE *tuple, /* not changed */ + int dim +); +/* build subtuple of given n-tuple */ + +#define delete_tuple _glp_mpl_delete_tuple +void delete_tuple +( MPL *mpl, + TUPLE *tuple /* destroyed */ +); +/* delete n-tuple */ + +#define format_tuple _glp_mpl_format_tuple +char *format_tuple +( MPL *mpl, + int c, + TUPLE *tuple /* not changed */ +); +/* format n-tuple for displaying or printing */ + +/**********************************************************************/ +/* * * ELEMENTAL SETS * * */ +/**********************************************************************/ + +#if 2 + 2 == 5 +struct ELEMSET /* see ARRAY */ +{ /* elemental set of n-tuples; formally it is a "value" assigned + to members of model sets (like numbers and symbols, which are + values assigned to members of model parameters); note that a + simple model set is not an elemental set, it is 0-dimensional + array, the only member of which (if it exists) is assigned an + elemental set */ +#endif + +#define create_elemset _glp_mpl_create_elemset +ELEMSET *create_elemset(MPL *mpl, int dim); +/* create elemental set */ + +#define find_tuple _glp_mpl_find_tuple +MEMBER *find_tuple +( MPL *mpl, + ELEMSET *set, /* not changed */ + TUPLE *tuple /* not changed */ +); +/* check if elemental set contains given n-tuple */ + +#define add_tuple _glp_mpl_add_tuple +MEMBER *add_tuple +( MPL *mpl, + ELEMSET *set, /* modified */ + TUPLE *tuple /* destroyed */ +); +/* add new n-tuple to elemental set */ + +#define check_then_add _glp_mpl_check_then_add +MEMBER *check_then_add +( MPL *mpl, + ELEMSET *set, /* modified */ + TUPLE *tuple /* destroyed */ +); +/* check and add new n-tuple to elemental set */ + +#define copy_elemset _glp_mpl_copy_elemset +ELEMSET *copy_elemset +( MPL *mpl, + ELEMSET *set /* not changed */ +); +/* make copy of elemental set */ + +#define delete_elemset _glp_mpl_delete_elemset +void delete_elemset +( MPL *mpl, + ELEMSET *set /* destroyed */ +); +/* delete elemental set */ + +#define arelset_size _glp_mpl_arelset_size +int arelset_size(MPL *mpl, double t0, double tf, double dt); +/* compute size of "arithmetic" elemental set */ + +#define arelset_member _glp_mpl_arelset_member +double arelset_member(MPL *mpl, double t0, double tf, double dt, int j); +/* compute member of "arithmetic" elemental set */ + +#define create_arelset _glp_mpl_create_arelset +ELEMSET *create_arelset(MPL *mpl, double t0, double tf, double dt); +/* create "arithmetic" elemental set */ + +#define set_union _glp_mpl_set_union +ELEMSET *set_union +( MPL *mpl, + ELEMSET *X, /* destroyed */ + ELEMSET *Y /* destroyed */ +); +/* union of two elemental sets */ + +#define set_diff _glp_mpl_set_diff +ELEMSET *set_diff +( MPL *mpl, + ELEMSET *X, /* destroyed */ + ELEMSET *Y /* destroyed */ +); +/* difference between two elemental sets */ + +#define set_symdiff _glp_mpl_set_symdiff +ELEMSET *set_symdiff +( MPL *mpl, + ELEMSET *X, /* destroyed */ + ELEMSET *Y /* destroyed */ +); +/* symmetric difference between two elemental sets */ + +#define set_inter _glp_mpl_set_inter +ELEMSET *set_inter +( MPL *mpl, + ELEMSET *X, /* destroyed */ + ELEMSET *Y /* destroyed */ +); +/* intersection of two elemental sets */ + +#define set_cross _glp_mpl_set_cross +ELEMSET *set_cross +( MPL *mpl, + ELEMSET *X, /* destroyed */ + ELEMSET *Y /* destroyed */ +); +/* cross (Cartesian) product of two elemental sets */ + +/**********************************************************************/ +/* * * ELEMENTAL VARIABLES * * */ +/**********************************************************************/ + +struct ELEMVAR +{ /* elemental variable; formally it is a "value" assigned to + members of model variables (like numbers and symbols, which + are values assigned to members of model parameters) */ + int j; + /* LP column number assigned to this elemental variable */ + VARIABLE *var; + /* model variable, which contains this elemental variable */ + MEMBER *memb; + /* array member, which is assigned this elemental variable */ + double lbnd; + /* lower bound */ + double ubnd; + /* upper bound */ + double temp; + /* working quantity used in operations on linear forms; normally + it contains floating-point zero */ +#if 1 /* 15/V-2010 */ + int stat; + double prim, dual; + /* solution components provided by the solver */ +#endif +}; + +/**********************************************************************/ +/* * * LINEAR FORMS * * */ +/**********************************************************************/ + +struct FORMULA +{ /* term of linear form c * x, where c is a coefficient, x is an + elemental variable; the linear form itself is the sum of terms + and is associated with its first term; (note that the linear + form may be empty that means the sum is equal to zero) */ + double coef; + /* coefficient at elemental variable or constant term */ + ELEMVAR *var; + /* reference to elemental variable; NULL means constant term */ + FORMULA *next; + /* the next term of linear form */ +}; + +#define constant_term _glp_mpl_constant_term +FORMULA *constant_term(MPL *mpl, double coef); +/* create constant term */ + +#define single_variable _glp_mpl_single_variable +FORMULA *single_variable +( MPL *mpl, + ELEMVAR *var /* referenced */ +); +/* create single variable */ + +#define copy_formula _glp_mpl_copy_formula +FORMULA *copy_formula +( MPL *mpl, + FORMULA *form /* not changed */ +); +/* make copy of linear form */ + +#define delete_formula _glp_mpl_delete_formula +void delete_formula +( MPL *mpl, + FORMULA *form /* destroyed */ +); +/* delete linear form */ + +#define linear_comb _glp_mpl_linear_comb +FORMULA *linear_comb +( MPL *mpl, + double a, FORMULA *fx, /* destroyed */ + double b, FORMULA *fy /* destroyed */ +); +/* linear combination of two linear forms */ + +#define remove_constant _glp_mpl_remove_constant +FORMULA *remove_constant +( MPL *mpl, + FORMULA *form, /* destroyed */ + double *coef /* modified */ +); +/* remove constant term from linear form */ + +#define reduce_terms _glp_mpl_reduce_terms +FORMULA *reduce_terms +( MPL *mpl, + FORMULA *form /* destroyed */ +); +/* reduce identical terms in linear form */ + +/**********************************************************************/ +/* * * ELEMENTAL CONSTRAINTS * * */ +/**********************************************************************/ + +struct ELEMCON +{ /* elemental constraint; formally it is a "value" assigned to + members of model constraints (like numbers or symbols, which + are values assigned to members of model parameters) */ + int i; + /* LP row number assigned to this elemental constraint */ + CONSTRAINT *con; + /* model constraint, which contains this elemental constraint */ + MEMBER *memb; + /* array member, which is assigned this elemental constraint */ + FORMULA *form; + /* linear form */ + double lbnd; + /* lower bound */ + double ubnd; + /* upper bound */ +#if 1 /* 15/V-2010 */ + int stat; + double prim, dual; + /* solution components provided by the solver */ +#endif +}; + +/**********************************************************************/ +/* * * GENERIC VALUES * * */ +/**********************************************************************/ + +union VALUE +{ /* generic value, which can be assigned to object member or be a + result of evaluation of expression */ + /* indicator that specifies the particular type of generic value + is stored in the corresponding array or pseudo-code descriptor + and can be one of the following: + A_NONE - no value + A_NUMERIC - floating-point number + A_SYMBOLIC - symbol + A_LOGICAL - logical value + A_TUPLE - n-tuple + A_ELEMSET - elemental set + A_ELEMVAR - elemental variable + A_FORMULA - linear form + A_ELEMCON - elemental constraint */ + void *none; /* null */ + double num; /* value */ + SYMBOL *sym; /* value */ + int bit; /* value */ + TUPLE *tuple; /* value */ + ELEMSET *set; /* value */ + ELEMVAR *var; /* reference */ + FORMULA *form; /* value */ + ELEMCON *con; /* reference */ +}; + +#define delete_value _glp_mpl_delete_value +void delete_value +( MPL *mpl, + int type, + VALUE *value /* content destroyed */ +); +/* delete generic value */ + +/**********************************************************************/ +/* * * SYMBOLICALLY INDEXED ARRAYS * * */ +/**********************************************************************/ + +struct ARRAY +{ /* multi-dimensional array, a set of members indexed over simple + or compound sets of symbols; arrays are used to represent the + contents of model objects (i.e. sets, parameters, variables, + constraints, and objectives); arrays also are used as "values" + that are assigned to members of set objects, in which case the + array itself represents an elemental set */ + int type; + /* type of generic values assigned to the array members: + A_NONE - none (members have no assigned values) + A_NUMERIC - floating-point numbers + A_SYMBOLIC - symbols + A_ELEMSET - elemental sets + A_ELEMVAR - elemental variables + A_ELEMCON - elemental constraints */ + int dim; + /* dimension of the array that determines number of components in + n-tuples for all members of the array, dim >= 0; dim = 0 means + the array is 0-dimensional */ + int size; + /* size of the array, i.e. number of its members */ + MEMBER *head; + /* the first array member; NULL means the array is empty */ + MEMBER *tail; + /* the last array member; NULL means the array is empty */ + AVL *tree; + /* the search tree intended to find array members for logarithmic + time; NULL means the search tree doesn't exist */ + ARRAY *prev; + /* the previous array in the translator database */ + ARRAY *next; + /* the next array in the translator database */ +}; + +struct MEMBER +{ /* array member */ + TUPLE *tuple; + /* n-tuple, which identifies the member; number of its components + is the same for all members within the array and determined by + the array dimension; duplicate members are not allowed */ + MEMBER *next; + /* the next array member */ + VALUE value; + /* generic value assigned to the member */ +}; + +#define create_array _glp_mpl_create_array +ARRAY *create_array(MPL *mpl, int type, int dim); +/* create array */ + +#define find_member _glp_mpl_find_member +MEMBER *find_member +( MPL *mpl, + ARRAY *array, /* not changed */ + TUPLE *tuple /* not changed */ +); +/* find array member with given n-tuple */ + +#define add_member _glp_mpl_add_member +MEMBER *add_member +( MPL *mpl, + ARRAY *array, /* modified */ + TUPLE *tuple /* destroyed */ +); +/* add new member to array */ + +#define delete_array _glp_mpl_delete_array +void delete_array +( MPL *mpl, + ARRAY *array /* destroyed */ +); +/* delete array */ + +/**********************************************************************/ +/* * * DOMAINS AND DUMMY INDICES * * */ +/**********************************************************************/ + +struct DOMAIN +{ /* domain (a simple or compound set); syntactically domain looks + like '{ i in I, (j,k) in S, t in T : }'; domains + are used to define sets, over which model objects are indexed, + and also as constituents of iterated operators */ + DOMAIN_BLOCK *list; + /* linked list of domain blocks (in the example above such blocks + are 'i in I', '(j,k) in S', and 't in T'); this list cannot be + empty */ + CODE *code; + /* pseudo-code for computing the logical predicate, which follows + the colon; NULL means no predicate is specified */ +}; + +struct DOMAIN_BLOCK +{ /* domain block; syntactically domain blocks look like 'i in I', + '(j,k) in S', and 't in T' in the example above (in the sequel + sets like I, S, and T are called basic sets) */ + DOMAIN_SLOT *list; + /* linked list of domain slots (i.e. indexing positions); number + of slots in this list is the same as dimension of n-tuples in + the basic set; this list cannot be empty */ + CODE *code; + /* pseudo-code for computing basic set; cannot be NULL */ + TUPLE *backup; + /* if this n-tuple is not empty, current values of dummy indices + in the domain block are the same as components of this n-tuple + (note that this n-tuple may have larger dimension than number + of dummy indices in this block, in which case extra components + are ignored); this n-tuple is used to restore former values of + dummy indices, if they were changed due to recursive calls to + the domain block */ + DOMAIN_BLOCK *next; + /* the next block in the same domain */ +}; + +struct DOMAIN_SLOT +{ /* domain slot; it specifies an individual indexing position and + defines the corresponding dummy index */ + char *name; + /* symbolic name of the dummy index; null pointer means the dummy + index is not explicitly specified */ + CODE *code; + /* pseudo-code for computing symbolic value, at which the dummy + index is bound; NULL means the dummy index is free within the + domain scope */ + SYMBOL *value; + /* current value assigned to the dummy index; NULL means no value + is assigned at the moment */ + CODE *list; + /* linked list of pseudo-codes with operation O_INDEX referring + to this slot; this linked list is used to invalidate resultant + values of the operation, which depend on this dummy index */ + DOMAIN_SLOT *next; + /* the next slot in the same domain block */ +}; + +#define assign_dummy_index _glp_mpl_assign_dummy_index +void assign_dummy_index +( MPL *mpl, + DOMAIN_SLOT *slot, /* modified */ + SYMBOL *value /* not changed */ +); +/* assign new value to dummy index */ + +#define update_dummy_indices _glp_mpl_update_dummy_indices +void update_dummy_indices +( MPL *mpl, + DOMAIN_BLOCK *block /* not changed */ +); +/* update current values of dummy indices */ + +#define enter_domain_block _glp_mpl_enter_domain_block +int enter_domain_block +( MPL *mpl, + DOMAIN_BLOCK *block, /* not changed */ + TUPLE *tuple, /* not changed */ + void *info, void (*func)(MPL *mpl, void *info) +); +/* enter domain block */ + +#define eval_within_domain _glp_mpl_eval_within_domain +int eval_within_domain +( MPL *mpl, + DOMAIN *domain, /* not changed */ + TUPLE *tuple, /* not changed */ + void *info, void (*func)(MPL *mpl, void *info) +); +/* perform evaluation within domain scope */ + +#define loop_within_domain _glp_mpl_loop_within_domain +void loop_within_domain +( MPL *mpl, + DOMAIN *domain, /* not changed */ + void *info, int (*func)(MPL *mpl, void *info) +); +/* perform iterations within domain scope */ + +#define out_of_domain _glp_mpl_out_of_domain +void out_of_domain +( MPL *mpl, + char *name, /* not changed */ + TUPLE *tuple /* not changed */ +); +/* raise domain exception */ + +#define get_domain_tuple _glp_mpl_get_domain_tuple +TUPLE *get_domain_tuple +( MPL *mpl, + DOMAIN *domain /* not changed */ +); +/* obtain current n-tuple from domain */ + +#define clean_domain _glp_mpl_clean_domain +void clean_domain(MPL *mpl, DOMAIN *domain); +/* clean domain */ + +/**********************************************************************/ +/* * * MODEL SETS * * */ +/**********************************************************************/ + +struct SET +{ /* model set */ + char *name; + /* symbolic name; cannot be NULL */ + char *alias; + /* alias; NULL means alias is not specified */ + int dim; /* aka arity */ + /* dimension (number of subscripts); dim = 0 means 0-dimensional + (unsubscripted) set, dim > 0 means set of sets */ + DOMAIN *domain; + /* subscript domain; NULL for 0-dimensional set */ + int dimen; + /* dimension of n-tuples, which members of this set consist of + (note that the model set itself is an array of elemental sets, + which are its members; so, don't confuse this dimension with + dimension of the model set); always non-zero */ + WITHIN *within; + /* list of supersets, which restrict each member of the set to be + in every superset from this list; this list can be empty */ + CODE *assign; + /* pseudo-code for computing assigned value; can be NULL */ + CODE *option; + /* pseudo-code for computing default value; can be NULL */ + GADGET *gadget; + /* plain set used to initialize the array of sets; can be NULL */ + int data; + /* data status flag: + 0 - no data are provided in the data section + 1 - data are provided, but not checked yet + 2 - data are provided and have been checked */ + ARRAY *array; + /* array of members, which are assigned elemental sets */ +}; + +struct WITHIN +{ /* restricting superset list entry */ + CODE *code; + /* pseudo-code for computing the superset; cannot be NULL */ + WITHIN *next; + /* the next entry for the same set or parameter */ +}; + +struct GADGET +{ /* plain set used to initialize the array of sets with data */ + SET *set; + /* pointer to plain set; cannot be NULL */ + int ind[20]; /* ind[dim+dimen]; */ + /* permutation of integers 1, 2, ..., dim+dimen */ +}; + +#define check_elem_set _glp_mpl_check_elem_set +void check_elem_set +( MPL *mpl, + SET *set, /* not changed */ + TUPLE *tuple, /* not changed */ + ELEMSET *refer /* not changed */ +); +/* check elemental set assigned to set member */ + +#define take_member_set _glp_mpl_take_member_set +ELEMSET *take_member_set /* returns reference, not value */ +( MPL *mpl, + SET *set, /* not changed */ + TUPLE *tuple /* not changed */ +); +/* obtain elemental set assigned to set member */ + +#define eval_member_set _glp_mpl_eval_member_set +ELEMSET *eval_member_set /* returns reference, not value */ +( MPL *mpl, + SET *set, /* not changed */ + TUPLE *tuple /* not changed */ +); +/* evaluate elemental set assigned to set member */ + +#define eval_whole_set _glp_mpl_eval_whole_set +void eval_whole_set(MPL *mpl, SET *set); +/* evaluate model set over entire domain */ + +#define clean_set _glp_mpl_clean_set +void clean_set(MPL *mpl, SET *set); +/* clean model set */ + +/**********************************************************************/ +/* * * MODEL PARAMETERS * * */ +/**********************************************************************/ + +struct PARAMETER +{ /* model parameter */ + char *name; + /* symbolic name; cannot be NULL */ + char *alias; + /* alias; NULL means alias is not specified */ + int dim; /* aka arity */ + /* dimension (number of subscripts); dim = 0 means 0-dimensional + (unsubscripted) parameter */ + DOMAIN *domain; + /* subscript domain; NULL for 0-dimensional parameter */ + int type; + /* parameter type: + A_NUMERIC - numeric + A_INTEGER - integer + A_BINARY - binary + A_SYMBOLIC - symbolic */ + CONDITION *cond; + /* list of conditions, which restrict each parameter member to + satisfy to every condition from this list; this list is used + only for numeric parameters and can be empty */ + WITHIN *in; + /* list of supersets, which restrict each parameter member to be + in every superset from this list; this list is used only for + symbolic parameters and can be empty */ + CODE *assign; + /* pseudo-code for computing assigned value; can be NULL */ + CODE *option; + /* pseudo-code for computing default value; can be NULL */ + int data; + /* data status flag: + 0 - no data are provided in the data section + 1 - data are provided, but not checked yet + 2 - data are provided and have been checked */ + SYMBOL *defval; + /* default value provided in the data section; can be NULL */ + ARRAY *array; + /* array of members, which are assigned numbers or symbols */ +}; + +struct CONDITION +{ /* restricting condition list entry */ + int rho; + /* flag that specifies the form of the condition: + O_LT - less than + O_LE - less than or equal to + O_EQ - equal to + O_GE - greater than or equal to + O_GT - greater than + O_NE - not equal to */ + CODE *code; + /* pseudo-code for computing the reference value */ + CONDITION *next; + /* the next entry for the same parameter */ +}; + +#define check_value_num _glp_mpl_check_value_num +void check_value_num +( MPL *mpl, + PARAMETER *par, /* not changed */ + TUPLE *tuple, /* not changed */ + double value +); +/* check numeric value assigned to parameter member */ + +#define take_member_num _glp_mpl_take_member_num +double take_member_num +( MPL *mpl, + PARAMETER *par, /* not changed */ + TUPLE *tuple /* not changed */ +); +/* obtain numeric value assigned to parameter member */ + +#define eval_member_num _glp_mpl_eval_member_num +double eval_member_num +( MPL *mpl, + PARAMETER *par, /* not changed */ + TUPLE *tuple /* not changed */ +); +/* evaluate numeric value assigned to parameter member */ + +#define check_value_sym _glp_mpl_check_value_sym +void check_value_sym +( MPL *mpl, + PARAMETER *par, /* not changed */ + TUPLE *tuple, /* not changed */ + SYMBOL *value /* not changed */ +); +/* check symbolic value assigned to parameter member */ + +#define take_member_sym _glp_mpl_take_member_sym +SYMBOL *take_member_sym /* returns value, not reference */ +( MPL *mpl, + PARAMETER *par, /* not changed */ + TUPLE *tuple /* not changed */ +); +/* obtain symbolic value assigned to parameter member */ + +#define eval_member_sym _glp_mpl_eval_member_sym +SYMBOL *eval_member_sym /* returns value, not reference */ +( MPL *mpl, + PARAMETER *par, /* not changed */ + TUPLE *tuple /* not changed */ +); +/* evaluate symbolic value assigned to parameter member */ + +#define eval_whole_par _glp_mpl_eval_whole_par +void eval_whole_par(MPL *mpl, PARAMETER *par); +/* evaluate model parameter over entire domain */ + +#define clean_parameter _glp_mpl_clean_parameter +void clean_parameter(MPL *mpl, PARAMETER *par); +/* clean model parameter */ + +/**********************************************************************/ +/* * * MODEL VARIABLES * * */ +/**********************************************************************/ + +struct VARIABLE +{ /* model variable */ + char *name; + /* symbolic name; cannot be NULL */ + char *alias; + /* alias; NULL means alias is not specified */ + int dim; /* aka arity */ + /* dimension (number of subscripts); dim = 0 means 0-dimensional + (unsubscripted) variable */ + DOMAIN *domain; + /* subscript domain; NULL for 0-dimensional variable */ + int type; + /* variable type: + A_NUMERIC - continuous + A_INTEGER - integer + A_BINARY - binary */ + CODE *lbnd; + /* pseudo-code for computing lower bound; NULL means lower bound + is not specified */ + CODE *ubnd; + /* pseudo-code for computing upper bound; NULL means upper bound + is not specified */ + /* if both the pointers lbnd and ubnd refer to the same code, the + variable is fixed at the corresponding value */ + ARRAY *array; + /* array of members, which are assigned elemental variables */ +}; + +#define take_member_var _glp_mpl_take_member_var +ELEMVAR *take_member_var /* returns reference */ +( MPL *mpl, + VARIABLE *var, /* not changed */ + TUPLE *tuple /* not changed */ +); +/* obtain reference to elemental variable */ + +#define eval_member_var _glp_mpl_eval_member_var +ELEMVAR *eval_member_var /* returns reference */ +( MPL *mpl, + VARIABLE *var, /* not changed */ + TUPLE *tuple /* not changed */ +); +/* evaluate reference to elemental variable */ + +#define eval_whole_var _glp_mpl_eval_whole_var +void eval_whole_var(MPL *mpl, VARIABLE *var); +/* evaluate model variable over entire domain */ + +#define clean_variable _glp_mpl_clean_variable +void clean_variable(MPL *mpl, VARIABLE *var); +/* clean model variable */ + +/**********************************************************************/ +/* * * MODEL CONSTRAINTS AND OBJECTIVES * * */ +/**********************************************************************/ + +struct CONSTRAINT +{ /* model constraint or objective */ + char *name; + /* symbolic name; cannot be NULL */ + char *alias; + /* alias; NULL means alias is not specified */ + int dim; /* aka arity */ + /* dimension (number of subscripts); dim = 0 means 0-dimensional + (unsubscripted) constraint */ + DOMAIN *domain; + /* subscript domain; NULL for 0-dimensional constraint */ + int type; + /* constraint type: + A_CONSTRAINT - constraint + A_MINIMIZE - objective (minimization) + A_MAXIMIZE - objective (maximization) */ + CODE *code; + /* pseudo-code for computing main linear form; cannot be NULL */ + CODE *lbnd; + /* pseudo-code for computing lower bound; NULL means lower bound + is not specified */ + CODE *ubnd; + /* pseudo-code for computing upper bound; NULL means upper bound + is not specified */ + /* if both the pointers lbnd and ubnd refer to the same code, the + constraint has the form of equation */ + ARRAY *array; + /* array of members, which are assigned elemental constraints */ +}; + +#define take_member_con _glp_mpl_take_member_con +ELEMCON *take_member_con /* returns reference */ +( MPL *mpl, + CONSTRAINT *con, /* not changed */ + TUPLE *tuple /* not changed */ +); +/* obtain reference to elemental constraint */ + +#define eval_member_con _glp_mpl_eval_member_con +ELEMCON *eval_member_con /* returns reference */ +( MPL *mpl, + CONSTRAINT *con, /* not changed */ + TUPLE *tuple /* not changed */ +); +/* evaluate reference to elemental constraint */ + +#define eval_whole_con _glp_mpl_eval_whole_con +void eval_whole_con(MPL *mpl, CONSTRAINT *con); +/* evaluate model constraint over entire domain */ + +#define clean_constraint _glp_mpl_clean_constraint +void clean_constraint(MPL *mpl, CONSTRAINT *con); +/* clean model constraint */ + +/**********************************************************************/ +/* * * DATA TABLES * * */ +/**********************************************************************/ + +struct TABLE +{ /* data table */ + char *name; + /* symbolic name; cannot be NULL */ + char *alias; + /* alias; NULL means alias is not specified */ + int type; + /* table type: + A_INPUT - input table + A_OUTPUT - output table */ + TABARG *arg; + /* argument list; cannot be empty */ + union + { struct + { SET *set; + /* input set; NULL means the set is not specified */ + TABFLD *fld; + /* field list; cannot be empty */ + TABIN *list; + /* input list; can be empty */ + } in; + struct + { DOMAIN *domain; + /* subscript domain; cannot be NULL */ + TABOUT *list; + /* output list; cannot be empty */ + } out; + } u; +}; + +struct TABARG +{ /* table argument list entry */ + CODE *code; + /* pseudo-code for computing the argument */ + TABARG *next; + /* next entry for the same table */ +}; + +struct TABFLD +{ /* table field list entry */ + char *name; + /* field name; cannot be NULL */ + TABFLD *next; + /* next entry for the same table */ +}; + +struct TABIN +{ /* table input list entry */ + PARAMETER *par; + /* parameter to be read; cannot be NULL */ + char *name; + /* column name; cannot be NULL */ + TABIN *next; + /* next entry for the same table */ +}; + +struct TABOUT +{ /* table output list entry */ + CODE *code; + /* pseudo-code for computing the value to be written */ + char *name; + /* column name; cannot be NULL */ + TABOUT *next; + /* next entry for the same table */ +}; + +struct TABDCA +{ /* table driver communication area */ + int id; + /* driver identifier (set by mpl_tab_drv_open) */ + void *link; + /* driver link pointer (set by mpl_tab_drv_open) */ + int na; + /* number of arguments */ + char **arg; /* char *arg[1+ns]; */ + /* arg[k], 1 <= k <= ns, is pointer to k-th argument */ + int nf; + /* number of fields */ + char **name; /* char *name[1+nc]; */ + /* name[k], 1 <= k <= nc, is name of k-th field */ + int *type; /* int type[1+nc]; */ + /* type[k], 1 <= k <= nc, is type of k-th field: + '?' - value not assigned + 'N' - number + 'S' - character string */ + double *num; /* double num[1+nc]; */ + /* num[k], 1 <= k <= nc, is numeric value of k-th field */ + char **str; + /* str[k], 1 <= k <= nc, is string value of k-th field */ +}; + +#define mpl_tab_num_args _glp_mpl_tab_num_args +int mpl_tab_num_args(TABDCA *dca); + +#define mpl_tab_get_arg _glp_mpl_tab_get_arg +const char *mpl_tab_get_arg(TABDCA *dca, int k); + +#define mpl_tab_num_flds _glp_mpl_tab_num_flds +int mpl_tab_num_flds(TABDCA *dca); + +#define mpl_tab_get_name _glp_mpl_tab_get_name +const char *mpl_tab_get_name(TABDCA *dca, int k); + +#define mpl_tab_get_type _glp_mpl_tab_get_type +int mpl_tab_get_type(TABDCA *dca, int k); + +#define mpl_tab_get_num _glp_mpl_tab_get_num +double mpl_tab_get_num(TABDCA *dca, int k); + +#define mpl_tab_get_str _glp_mpl_tab_get_str +const char *mpl_tab_get_str(TABDCA *dca, int k); + +#define mpl_tab_set_num _glp_mpl_tab_set_num +void mpl_tab_set_num(TABDCA *dca, int k, double num); + +#define mpl_tab_set_str _glp_mpl_tab_set_str +void mpl_tab_set_str(TABDCA *dca, int k, const char *str); + +#define mpl_tab_drv_open _glp_mpl_tab_drv_open +void mpl_tab_drv_open(MPL *mpl, int mode); + +#define mpl_tab_drv_read _glp_mpl_tab_drv_read +int mpl_tab_drv_read(MPL *mpl); + +#define mpl_tab_drv_write _glp_mpl_tab_drv_write +void mpl_tab_drv_write(MPL *mpl); + +#define mpl_tab_drv_close _glp_mpl_tab_drv_close +void mpl_tab_drv_close(MPL *mpl); + +/**********************************************************************/ +/* * * PSEUDO-CODE * * */ +/**********************************************************************/ + +union OPERANDS +{ /* operands that participate in pseudo-code operation (choice of + particular operands depends on the operation code) */ + /*--------------------------------------------------------------*/ + double num; /* O_NUMBER */ + /* floaing-point number to be taken */ + /*--------------------------------------------------------------*/ + char *str; /* O_STRING */ + /* character string to be taken */ + /*--------------------------------------------------------------*/ + struct /* O_INDEX */ + { DOMAIN_SLOT *slot; + /* domain slot, which contains dummy index to be taken */ + CODE *next; + /* the next pseudo-code with op = O_INDEX, which refers to the + same slot as this one; pointer to the beginning of this list + is stored in the corresponding domain slot */ + } index; + /*--------------------------------------------------------------*/ + struct /* O_MEMNUM, O_MEMSYM */ + { PARAMETER *par; + /* model parameter, which contains member to be taken */ + ARG_LIST *list; + /* list of subscripts; NULL for 0-dimensional parameter */ + } par; + /*--------------------------------------------------------------*/ + struct /* O_MEMSET */ + { SET *set; + /* model set, which contains member to be taken */ + ARG_LIST *list; + /* list of subscripts; NULL for 0-dimensional set */ + } set; + /*--------------------------------------------------------------*/ + struct /* O_MEMVAR */ + { VARIABLE *var; + /* model variable, which contains member to be taken */ + ARG_LIST *list; + /* list of subscripts; NULL for 0-dimensional variable */ +#if 1 /* 15/V-2010 */ + int suff; + /* suffix specified: */ +#define DOT_NONE 0x00 /* none (means variable itself) */ +#define DOT_LB 0x01 /* .lb (lower bound) */ +#define DOT_UB 0x02 /* .ub (upper bound) */ +#define DOT_STATUS 0x03 /* .status (status) */ +#define DOT_VAL 0x04 /* .val (primal value) */ +#define DOT_DUAL 0x05 /* .dual (dual value) */ +#endif + } var; +#if 1 /* 15/V-2010 */ + /*--------------------------------------------------------------*/ + struct /* O_MEMCON */ + { CONSTRAINT *con; + /* model constraint, which contains member to be taken */ + ARG_LIST *list; + /* list of subscripys; NULL for 0-dimensional constraint */ + int suff; + /* suffix specified (see O_MEMVAR above) */ + } con; +#endif + /*--------------------------------------------------------------*/ + ARG_LIST *list; /* O_TUPLE, O_MAKE, n-ary operations */ + /* list of operands */ + /*--------------------------------------------------------------*/ + DOMAIN_BLOCK *slice; /* O_SLICE */ + /* domain block, which specifies slice (i.e. n-tuple that contains + free dummy indices); this operation is never evaluated */ + /*--------------------------------------------------------------*/ + struct /* unary, binary, ternary operations */ + { CODE *x; + /* pseudo-code for computing first operand */ + CODE *y; + /* pseudo-code for computing second operand */ + CODE *z; + /* pseudo-code for computing third operand */ + } arg; + /*--------------------------------------------------------------*/ + struct /* iterated operations */ + { DOMAIN *domain; + /* domain, over which the operation is performed */ + CODE *x; + /* pseudo-code for computing "integrand" */ + } loop; + /*--------------------------------------------------------------*/ +}; + +struct ARG_LIST +{ /* operands list entry */ + CODE *x; + /* pseudo-code for computing operand */ + ARG_LIST *next; + /* the next operand of the same operation */ +}; + +struct CODE +{ /* pseudo-code (internal form of expressions) */ + int op; + /* operation code: */ +#define O_NUMBER 301 /* take floating-point number */ +#define O_STRING 302 /* take character string */ +#define O_INDEX 303 /* take dummy index */ +#define O_MEMNUM 304 /* take member of numeric parameter */ +#define O_MEMSYM 305 /* take member of symbolic parameter */ +#define O_MEMSET 306 /* take member of set */ +#define O_MEMVAR 307 /* take member of variable */ +#define O_MEMCON 308 /* take member of constraint */ +#define O_TUPLE 309 /* make n-tuple */ +#define O_MAKE 310 /* make elemental set of n-tuples */ +#define O_SLICE 311 /* define domain block (dummy op) */ + /* 0-ary operations --------------------*/ +#define O_IRAND224 312 /* pseudo-random in [0, 2^24-1] */ +#define O_UNIFORM01 313 /* pseudo-random in [0, 1) */ +#define O_NORMAL01 314 /* gaussian random, mu = 0, sigma = 1 */ +#define O_GMTIME 315 /* current calendar time (UTC) */ + /* unary operations --------------------*/ +#define O_CVTNUM 316 /* conversion to numeric */ +#define O_CVTSYM 317 /* conversion to symbolic */ +#define O_CVTLOG 318 /* conversion to logical */ +#define O_CVTTUP 319 /* conversion to 1-tuple */ +#define O_CVTLFM 320 /* conversion to linear form */ +#define O_PLUS 321 /* unary plus */ +#define O_MINUS 322 /* unary minus */ +#define O_NOT 323 /* negation (logical "not") */ +#define O_ABS 324 /* absolute value */ +#define O_CEIL 325 /* round upward ("ceiling of x") */ +#define O_FLOOR 326 /* round downward ("floor of x") */ +#define O_EXP 327 /* base-e exponential */ +#define O_LOG 328 /* natural logarithm */ +#define O_LOG10 329 /* common (decimal) logarithm */ +#define O_SQRT 330 /* square root */ +#define O_SIN 331 /* trigonometric sine */ +#define O_COS 332 /* trigonometric cosine */ +#define O_ATAN 333 /* trigonometric arctangent */ +#define O_ROUND 334 /* round to nearest integer */ +#define O_TRUNC 335 /* truncate to nearest integer */ +#define O_CARD 336 /* cardinality of set */ +#define O_LENGTH 337 /* length of symbolic value */ + /* binary operations -------------------*/ +#define O_ADD 338 /* addition */ +#define O_SUB 339 /* subtraction */ +#define O_LESS 340 /* non-negative subtraction */ +#define O_MUL 341 /* multiplication */ +#define O_DIV 342 /* division */ +#define O_IDIV 343 /* quotient of exact division */ +#define O_MOD 344 /* remainder of exact division */ +#define O_POWER 345 /* exponentiation (raise to power) */ +#define O_ATAN2 346 /* trigonometric arctangent */ +#define O_ROUND2 347 /* round to n fractional digits */ +#define O_TRUNC2 348 /* truncate to n fractional digits */ +#define O_UNIFORM 349 /* pseudo-random in [a, b) */ +#define O_NORMAL 350 /* gaussian random, given mu and sigma */ +#define O_CONCAT 351 /* concatenation */ +#define O_LT 352 /* comparison on 'less than' */ +#define O_LE 353 /* comparison on 'not greater than' */ +#define O_EQ 354 /* comparison on 'equal to' */ +#define O_GE 355 /* comparison on 'not less than' */ +#define O_GT 356 /* comparison on 'greater than' */ +#define O_NE 357 /* comparison on 'not equal to' */ +#define O_AND 358 /* conjunction (logical "and") */ +#define O_OR 359 /* disjunction (logical "or") */ +#define O_UNION 360 /* union */ +#define O_DIFF 361 /* difference */ +#define O_SYMDIFF 362 /* symmetric difference */ +#define O_INTER 363 /* intersection */ +#define O_CROSS 364 /* cross (Cartesian) product */ +#define O_IN 365 /* test on 'x in Y' */ +#define O_NOTIN 366 /* test on 'x not in Y' */ +#define O_WITHIN 367 /* test on 'X within Y' */ +#define O_NOTWITHIN 368 /* test on 'X not within Y' */ +#define O_SUBSTR 369 /* substring */ +#define O_STR2TIME 370 /* convert string to time */ +#define O_TIME2STR 371 /* convert time to string */ + /* ternary operations ------------------*/ +#define O_DOTS 372 /* build "arithmetic" set */ +#define O_FORK 373 /* if-then-else */ +#define O_SUBSTR3 374 /* substring */ + /* n-ary operations --------------------*/ +#define O_MIN 375 /* minimal value (n-ary) */ +#define O_MAX 376 /* maximal value (n-ary) */ + /* iterated operations -----------------*/ +#define O_SUM 377 /* summation */ +#define O_PROD 378 /* multiplication */ +#define O_MINIMUM 379 /* minimum */ +#define O_MAXIMUM 380 /* maximum */ +#define O_FORALL 381 /* conjunction (A-quantification) */ +#define O_EXISTS 382 /* disjunction (E-quantification) */ +#define O_SETOF 383 /* compute elemental set */ +#define O_BUILD 384 /* build elemental set */ + OPERANDS arg; + /* operands that participate in the operation */ + int type; + /* type of the resultant value: + A_NUMERIC - numeric + A_SYMBOLIC - symbolic + A_LOGICAL - logical + A_TUPLE - n-tuple + A_ELEMSET - elemental set + A_FORMULA - linear form */ + int dim; + /* dimension of the resultant value; for A_TUPLE and A_ELEMSET it + is the dimension of the corresponding n-tuple(s) and cannot be + zero; for other resultant types it is always zero */ + CODE *up; + /* parent pseudo-code, which refers to this pseudo-code as to its + operand; NULL means this pseudo-code has no parent and defines + an expression, which is not contained in another expression */ + int vflag; + /* volatile flag; being set this flag means that this operation + has a side effect; for primary expressions this flag is set + directly by corresponding parsing routines (for example, if + primary expression is a reference to a function that generates + pseudo-random numbers); in other cases this flag is inherited + from operands */ + int valid; + /* if this flag is set, the resultant value, which is a temporary + result of evaluating this operation on particular values of + operands, is valid; if this flag is clear, the resultant value + doesn't exist and therefore not valid; having been evaluated + the resultant value is stored here and not destroyed until the + dummy indices, which this value depends on, have been changed + (and if it doesn't depend on dummy indices at all, it is never + destroyed); thus, if the resultant value is valid, evaluating + routine can immediately take its copy not computing the result + from scratch; this mechanism is similar to moving invariants + out of loops and allows improving efficiency at the expense of + some extra memory needed to keep temporary results */ + /* however, if the volatile flag (see above) is set, even if the + resultant value is valid, evaluating routine computes it as if + it were not valid, i.e. caching is not used in this case */ + VALUE value; + /* resultant value in generic format */ +}; + +#define eval_numeric _glp_mpl_eval_numeric +double eval_numeric(MPL *mpl, CODE *code); +/* evaluate pseudo-code to determine numeric value */ + +#define eval_symbolic _glp_mpl_eval_symbolic +SYMBOL *eval_symbolic(MPL *mpl, CODE *code); +/* evaluate pseudo-code to determine symbolic value */ + +#define eval_logical _glp_mpl_eval_logical +int eval_logical(MPL *mpl, CODE *code); +/* evaluate pseudo-code to determine logical value */ + +#define eval_tuple _glp_mpl_eval_tuple +TUPLE *eval_tuple(MPL *mpl, CODE *code); +/* evaluate pseudo-code to construct n-tuple */ + +#define eval_elemset _glp_mpl_eval_elemset +ELEMSET *eval_elemset(MPL *mpl, CODE *code); +/* evaluate pseudo-code to construct elemental set */ + +#define is_member _glp_mpl_is_member +int is_member(MPL *mpl, CODE *code, TUPLE *tuple); +/* check if n-tuple is in set specified by pseudo-code */ + +#define eval_formula _glp_mpl_eval_formula +FORMULA *eval_formula(MPL *mpl, CODE *code); +/* evaluate pseudo-code to construct linear form */ + +#define clean_code _glp_mpl_clean_code +void clean_code(MPL *mpl, CODE *code); +/* clean pseudo-code */ + +/**********************************************************************/ +/* * * MODEL STATEMENTS * * */ +/**********************************************************************/ + +struct CHECK +{ /* check statement */ + DOMAIN *domain; + /* subscript domain; NULL means domain is not used */ + CODE *code; + /* code for computing the predicate to be checked */ +}; + +struct DISPLAY +{ /* display statement */ + DOMAIN *domain; + /* subscript domain; NULL means domain is not used */ + DISPLAY1 *list; + /* display list; cannot be empty */ +}; + +struct DISPLAY1 +{ /* display list entry */ + int type; + /* item type: + A_INDEX - dummy index + A_SET - model set + A_PARAMETER - model parameter + A_VARIABLE - model variable + A_CONSTRAINT - model constraint/objective + A_EXPRESSION - expression */ + union + { DOMAIN_SLOT *slot; + SET *set; + PARAMETER *par; + VARIABLE *var; + CONSTRAINT *con; + CODE *code; + } u; + /* item to be displayed */ +#if 0 /* 15/V-2010 */ + ARG_LIST *list; + /* optional subscript list (for constraint/objective only) */ +#endif + DISPLAY1 *next; + /* the next entry for the same statement */ +}; + +struct PRINTF +{ /* printf statement */ + DOMAIN *domain; + /* subscript domain; NULL means domain is not used */ + CODE *fmt; + /* pseudo-code for computing format string */ + PRINTF1 *list; + /* printf list; can be empty */ + CODE *fname; + /* pseudo-code for computing filename to redirect the output; + NULL means the output goes to stdout */ + int app; + /* if this flag is set, the output is appended */ +}; + +struct PRINTF1 +{ /* printf list entry */ + CODE *code; + /* pseudo-code for computing value to be printed */ + PRINTF1 *next; + /* the next entry for the same statement */ +}; + +struct FOR +{ /* for statement */ + DOMAIN *domain; + /* subscript domain; cannot be NULL */ + STATEMENT *list; + /* linked list of model statements within this for statement in + the original order */ +}; + +struct STATEMENT +{ /* model statement */ + int line; + /* number of source text line, where statement begins */ + int type; + /* statement type: + A_SET - set statement + A_PARAMETER - parameter statement + A_VARIABLE - variable statement + A_CONSTRAINT - constraint/objective statement + A_TABLE - table statement + A_SOLVE - solve statement + A_CHECK - check statement + A_DISPLAY - display statement + A_PRINTF - printf statement + A_FOR - for statement */ + union + { SET *set; + PARAMETER *par; + VARIABLE *var; + CONSTRAINT *con; + TABLE *tab; + void *slv; /* currently not used (set to NULL) */ + CHECK *chk; + DISPLAY *dpy; + PRINTF *prt; + FOR *fur; + } u; + /* specific part of statement */ + STATEMENT *next; + /* the next statement; in this list statements follow in the same + order as they appear in the model section */ +}; + +#define execute_table _glp_mpl_execute_table +void execute_table(MPL *mpl, TABLE *tab); +/* execute table statement */ + +#define free_dca _glp_mpl_free_dca +void free_dca(MPL *mpl); +/* free table driver communucation area */ + +#define clean_table _glp_mpl_clean_table +void clean_table(MPL *mpl, TABLE *tab); +/* clean table statement */ + +#define execute_check _glp_mpl_execute_check +void execute_check(MPL *mpl, CHECK *chk); +/* execute check statement */ + +#define clean_check _glp_mpl_clean_check +void clean_check(MPL *mpl, CHECK *chk); +/* clean check statement */ + +#define execute_display _glp_mpl_execute_display +void execute_display(MPL *mpl, DISPLAY *dpy); +/* execute display statement */ + +#define clean_display _glp_mpl_clean_display +void clean_display(MPL *mpl, DISPLAY *dpy); +/* clean display statement */ + +#define execute_printf _glp_mpl_execute_printf +void execute_printf(MPL *mpl, PRINTF *prt); +/* execute printf statement */ + +#define clean_printf _glp_mpl_clean_printf +void clean_printf(MPL *mpl, PRINTF *prt); +/* clean printf statement */ + +#define execute_for _glp_mpl_execute_for +void execute_for(MPL *mpl, FOR *fur); +/* execute for statement */ + +#define clean_for _glp_mpl_clean_for +void clean_for(MPL *mpl, FOR *fur); +/* clean for statement */ + +#define execute_statement _glp_mpl_execute_statement +void execute_statement(MPL *mpl, STATEMENT *stmt); +/* execute specified model statement */ + +#define clean_statement _glp_mpl_clean_statement +void clean_statement(MPL *mpl, STATEMENT *stmt); +/* clean specified model statement */ + +/**********************************************************************/ +/* * * GENERATING AND POSTSOLVING MODEL * * */ +/**********************************************************************/ + +#define alloc_content _glp_mpl_alloc_content +void alloc_content(MPL *mpl); +/* allocate content arrays for all model objects */ + +#define generate_model _glp_mpl_generate_model +void generate_model(MPL *mpl); +/* generate model */ + +#define build_problem _glp_mpl_build_problem +void build_problem(MPL *mpl); +/* build problem instance */ + +#define postsolve_model _glp_mpl_postsolve_model +void postsolve_model(MPL *mpl); +/* postsolve model */ + +#define clean_model _glp_mpl_clean_model +void clean_model(MPL *mpl); +/* clean model content */ + +/**********************************************************************/ +/* * * INPUT/OUTPUT * * */ +/**********************************************************************/ + +#define open_input _glp_mpl_open_input +void open_input(MPL *mpl, char *file); +/* open input text file */ + +#define read_char _glp_mpl_read_char +int read_char(MPL *mpl); +/* read next character from input text file */ + +#define close_input _glp_mpl_close_input +void close_input(MPL *mpl); +/* close input text file */ + +#define open_output _glp_mpl_open_output +void open_output(MPL *mpl, char *file); +/* open output text file */ + +#define write_char _glp_mpl_write_char +void write_char(MPL *mpl, int c); +/* write next character to output text file */ + +#define write_text _glp_mpl_write_text +void write_text(MPL *mpl, char *fmt, ...); +/* format and write text to output text file */ + +#define flush_output _glp_mpl_flush_output +void flush_output(MPL *mpl); +/* finalize writing data to output text file */ + +/**********************************************************************/ +/* * * SOLVER INTERFACE * * */ +/**********************************************************************/ + +#define MPL_FR 401 /* free (unbounded) */ +#define MPL_LO 402 /* lower bound */ +#define MPL_UP 403 /* upper bound */ +#define MPL_DB 404 /* both lower and upper bounds */ +#define MPL_FX 405 /* fixed */ + +#define MPL_ST 411 /* constraint */ +#define MPL_MIN 412 /* objective (minimization) */ +#define MPL_MAX 413 /* objective (maximization) */ + +#define MPL_NUM 421 /* continuous */ +#define MPL_INT 422 /* integer */ +#define MPL_BIN 423 /* binary */ + +#define error _glp_mpl_error +void error(MPL *mpl, char *fmt, ...); +/* print error message and terminate model processing */ + +#define warning _glp_mpl_warning +void warning(MPL *mpl, char *fmt, ...); +/* print warning message and continue model processing */ + +#define mpl_initialize _glp_mpl_initialize +MPL *mpl_initialize(void); +/* create and initialize translator database */ + +#define mpl_read_model _glp_mpl_read_model +int mpl_read_model(MPL *mpl, char *file, int skip_data); +/* read model section and optional data section */ + +#define mpl_read_data _glp_mpl_read_data +int mpl_read_data(MPL *mpl, char *file); +/* read data section */ + +#define mpl_generate _glp_mpl_generate +int mpl_generate(MPL *mpl, char *file); +/* generate model */ + +#define mpl_get_prob_name _glp_mpl_get_prob_name +char *mpl_get_prob_name(MPL *mpl); +/* obtain problem (model) name */ + +#define mpl_get_num_rows _glp_mpl_get_num_rows +int mpl_get_num_rows(MPL *mpl); +/* determine number of rows */ + +#define mpl_get_num_cols _glp_mpl_get_num_cols +int mpl_get_num_cols(MPL *mpl); +/* determine number of columns */ + +#define mpl_get_row_name _glp_mpl_get_row_name +char *mpl_get_row_name(MPL *mpl, int i); +/* obtain row name */ + +#define mpl_get_row_kind _glp_mpl_get_row_kind +int mpl_get_row_kind(MPL *mpl, int i); +/* determine row kind */ + +#define mpl_get_row_bnds _glp_mpl_get_row_bnds +int mpl_get_row_bnds(MPL *mpl, int i, double *lb, double *ub); +/* obtain row bounds */ + +#define mpl_get_mat_row _glp_mpl_get_mat_row +int mpl_get_mat_row(MPL *mpl, int i, int ndx[], double val[]); +/* obtain row of the constraint matrix */ + +#define mpl_get_row_c0 _glp_mpl_get_row_c0 +double mpl_get_row_c0(MPL *mpl, int i); +/* obtain constant term of free row */ + +#define mpl_get_col_name _glp_mpl_get_col_name +char *mpl_get_col_name(MPL *mpl, int j); +/* obtain column name */ + +#define mpl_get_col_kind _glp_mpl_get_col_kind +int mpl_get_col_kind(MPL *mpl, int j); +/* determine column kind */ + +#define mpl_get_col_bnds _glp_mpl_get_col_bnds +int mpl_get_col_bnds(MPL *mpl, int j, double *lb, double *ub); +/* obtain column bounds */ + +#define mpl_has_solve_stmt _glp_mpl_has_solve_stmt +int mpl_has_solve_stmt(MPL *mpl); +/* check if model has solve statement */ + +#if 1 /* 15/V-2010 */ +#define mpl_put_row_soln _glp_mpl_put_row_soln +void mpl_put_row_soln(MPL *mpl, int i, int stat, double prim, + double dual); +/* store row (constraint/objective) solution components */ +#endif + +#if 1 /* 15/V-2010 */ +#define mpl_put_col_soln _glp_mpl_put_col_soln +void mpl_put_col_soln(MPL *mpl, int j, int stat, double prim, + double dual); +/* store column (variable) solution components */ +#endif + +#if 0 /* 15/V-2010 */ +#define mpl_put_col_value _glp_mpl_put_col_value +void mpl_put_col_value(MPL *mpl, int j, double val); +/* store column value */ +#endif + +#define mpl_postsolve _glp_mpl_postsolve +int mpl_postsolve(MPL *mpl); +/* postsolve model */ + +#define mpl_terminate _glp_mpl_terminate +void mpl_terminate(MPL *mpl); +/* free all resources used by translator */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpmpl01.c b/resources/3rdparty/glpk-4.57/src/glpmpl01.c new file mode 100644 index 000000000..db7af246b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpmpl01.c @@ -0,0 +1,4715 @@ +/* glpmpl01.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "glpmpl.h" + +#define dmp_get_atomv dmp_get_atom + +/**********************************************************************/ +/* * * PROCESSING MODEL SECTION * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- enter_context - enter current token into context queue. +-- +-- This routine enters the current token into the context queue. */ + +void enter_context(MPL *mpl) +{ char *image, *s; + if (mpl->token == T_EOF) + image = "_|_"; + else if (mpl->token == T_STRING) + image = "'...'"; + else + image = mpl->image; + xassert(0 <= mpl->c_ptr && mpl->c_ptr < CONTEXT_SIZE); + mpl->context[mpl->c_ptr++] = ' '; + if (mpl->c_ptr == CONTEXT_SIZE) mpl->c_ptr = 0; + for (s = image; *s != '\0'; s++) + { mpl->context[mpl->c_ptr++] = *s; + if (mpl->c_ptr == CONTEXT_SIZE) mpl->c_ptr = 0; + } + return; +} + +/*---------------------------------------------------------------------- +-- print_context - print current content of context queue. +-- +-- This routine prints current content of the context queue. */ + +void print_context(MPL *mpl) +{ int c; + while (mpl->c_ptr > 0) + { mpl->c_ptr--; + c = mpl->context[0]; + memmove(mpl->context, mpl->context+1, CONTEXT_SIZE-1); + mpl->context[CONTEXT_SIZE-1] = (char)c; + } + xprintf("Context: %s%.*s\n", mpl->context[0] == ' ' ? "" : "...", + CONTEXT_SIZE, mpl->context); + return; +} + +/*---------------------------------------------------------------------- +-- get_char - scan next character from input text file. +-- +-- This routine scans a next ASCII character from the input text file. +-- In case of end-of-file, the character is assigned EOF. */ + +void get_char(MPL *mpl) +{ int c; + if (mpl->c == EOF) goto done; + if (mpl->c == '\n') mpl->line++; + c = read_char(mpl); + if (c == EOF) + { if (mpl->c == '\n') + mpl->line--; + else + warning(mpl, "final NL missing before end of file"); + } + else if (c == '\n') + ; + else if (isspace(c)) + c = ' '; + else if (iscntrl(c)) + { enter_context(mpl); + error(mpl, "control character 0x%02X not allowed", c); + } + mpl->c = c; +done: return; +} + +/*---------------------------------------------------------------------- +-- append_char - append character to current token. +-- +-- This routine appends the current character to the current token and +-- then scans a next character. */ + +void append_char(MPL *mpl) +{ xassert(0 <= mpl->imlen && mpl->imlen <= MAX_LENGTH); + if (mpl->imlen == MAX_LENGTH) + { switch (mpl->token) + { case T_NAME: + enter_context(mpl); + error(mpl, "symbolic name %s... too long", mpl->image); + case T_SYMBOL: + enter_context(mpl); + error(mpl, "symbol %s... too long", mpl->image); + case T_NUMBER: + enter_context(mpl); + error(mpl, "numeric literal %s... too long", mpl->image); + case T_STRING: + enter_context(mpl); + error(mpl, "string literal too long"); + default: + xassert(mpl != mpl); + } + } + mpl->image[mpl->imlen++] = (char)mpl->c; + mpl->image[mpl->imlen] = '\0'; + get_char(mpl); + return; +} + +/*---------------------------------------------------------------------- +-- get_token - scan next token from input text file. +-- +-- This routine scans a next token from the input text file using the +-- standard finite automation technique. */ + +void get_token(MPL *mpl) +{ /* save the current token */ + mpl->b_token = mpl->token; + mpl->b_imlen = mpl->imlen; + strcpy(mpl->b_image, mpl->image); + mpl->b_value = mpl->value; + /* if the next token is already scanned, make it current */ + if (mpl->f_scan) + { mpl->f_scan = 0; + mpl->token = mpl->f_token; + mpl->imlen = mpl->f_imlen; + strcpy(mpl->image, mpl->f_image); + mpl->value = mpl->f_value; + goto done; + } +loop: /* nothing has been scanned so far */ + mpl->token = 0; + mpl->imlen = 0; + mpl->image[0] = '\0'; + mpl->value = 0.0; + /* skip any uninteresting characters */ + while (mpl->c == ' ' || mpl->c == '\n') get_char(mpl); + /* recognize and construct the token */ + if (mpl->c == EOF) + { /* end-of-file reached */ + mpl->token = T_EOF; + } + else if (mpl->c == '#') + { /* comment; skip anything until end-of-line */ + while (mpl->c != '\n' && mpl->c != EOF) get_char(mpl); + goto loop; + } + else if (!mpl->flag_d && (isalpha(mpl->c) || mpl->c == '_')) + { /* symbolic name or reserved keyword */ + mpl->token = T_NAME; + while (isalnum(mpl->c) || mpl->c == '_') append_char(mpl); + if (strcmp(mpl->image, "and") == 0) + mpl->token = T_AND; + else if (strcmp(mpl->image, "by") == 0) + mpl->token = T_BY; + else if (strcmp(mpl->image, "cross") == 0) + mpl->token = T_CROSS; + else if (strcmp(mpl->image, "diff") == 0) + mpl->token = T_DIFF; + else if (strcmp(mpl->image, "div") == 0) + mpl->token = T_DIV; + else if (strcmp(mpl->image, "else") == 0) + mpl->token = T_ELSE; + else if (strcmp(mpl->image, "if") == 0) + mpl->token = T_IF; + else if (strcmp(mpl->image, "in") == 0) + mpl->token = T_IN; +#if 1 /* 21/VII-2006 */ + else if (strcmp(mpl->image, "Infinity") == 0) + mpl->token = T_INFINITY; +#endif + else if (strcmp(mpl->image, "inter") == 0) + mpl->token = T_INTER; + else if (strcmp(mpl->image, "less") == 0) + mpl->token = T_LESS; + else if (strcmp(mpl->image, "mod") == 0) + mpl->token = T_MOD; + else if (strcmp(mpl->image, "not") == 0) + mpl->token = T_NOT; + else if (strcmp(mpl->image, "or") == 0) + mpl->token = T_OR; + else if (strcmp(mpl->image, "s") == 0 && mpl->c == '.') + { mpl->token = T_SPTP; + append_char(mpl); + if (mpl->c != 't') +sptp: { enter_context(mpl); + error(mpl, "keyword s.t. incomplete"); + } + append_char(mpl); + if (mpl->c != '.') goto sptp; + append_char(mpl); + } + else if (strcmp(mpl->image, "symdiff") == 0) + mpl->token = T_SYMDIFF; + else if (strcmp(mpl->image, "then") == 0) + mpl->token = T_THEN; + else if (strcmp(mpl->image, "union") == 0) + mpl->token = T_UNION; + else if (strcmp(mpl->image, "within") == 0) + mpl->token = T_WITHIN; + } + else if (!mpl->flag_d && isdigit(mpl->c)) + { /* numeric literal */ + mpl->token = T_NUMBER; + /* scan integer part */ + while (isdigit(mpl->c)) append_char(mpl); + /* scan optional fractional part */ + if (mpl->c == '.') + { append_char(mpl); + if (mpl->c == '.') + { /* hmm, it is not the fractional part, it is dots that + follow the integer part */ + mpl->imlen--; + mpl->image[mpl->imlen] = '\0'; + mpl->f_dots = 1; + goto conv; + } +frac: while (isdigit(mpl->c)) append_char(mpl); + } + /* scan optional decimal exponent */ + if (mpl->c == 'e' || mpl->c == 'E') + { append_char(mpl); + if (mpl->c == '+' || mpl->c == '-') append_char(mpl); + if (!isdigit(mpl->c)) + { enter_context(mpl); + error(mpl, "numeric literal %s incomplete", mpl->image); + } + while (isdigit(mpl->c)) append_char(mpl); + } + /* there must be no letter following the numeric literal */ + if (isalpha(mpl->c) || mpl->c == '_') + { enter_context(mpl); + error(mpl, "symbol %s%c... should be enclosed in quotes", + mpl->image, mpl->c); + } +conv: /* convert numeric literal to floating-point */ + if (str2num(mpl->image, &mpl->value)) +err: { enter_context(mpl); + error(mpl, "cannot convert numeric literal %s to floating-p" + "oint number", mpl->image); + } + } + else if (mpl->c == '\'' || mpl->c == '"') + { /* character string */ + int quote = mpl->c; + mpl->token = T_STRING; + get_char(mpl); + for (;;) + { if (mpl->c == '\n' || mpl->c == EOF) + { enter_context(mpl); + error(mpl, "unexpected end of line; string literal incom" + "plete"); + } + if (mpl->c == quote) + { get_char(mpl); + if (mpl->c != quote) break; + } + append_char(mpl); + } + } + else if (!mpl->flag_d && mpl->c == '+') + mpl->token = T_PLUS, append_char(mpl); + else if (!mpl->flag_d && mpl->c == '-') + mpl->token = T_MINUS, append_char(mpl); + else if (mpl->c == '*') + { mpl->token = T_ASTERISK, append_char(mpl); + if (mpl->c == '*') + mpl->token = T_POWER, append_char(mpl); + } + else if (mpl->c == '/') + { mpl->token = T_SLASH, append_char(mpl); + if (mpl->c == '*') + { /* comment sequence */ + get_char(mpl); + for (;;) + { if (mpl->c == EOF) + { /* do not call enter_context at this point */ + error(mpl, "unexpected end of file; comment sequence " + "incomplete"); + } + else if (mpl->c == '*') + { get_char(mpl); + if (mpl->c == '/') break; + } + else + get_char(mpl); + } + get_char(mpl); + goto loop; + } + } + else if (mpl->c == '^') + mpl->token = T_POWER, append_char(mpl); + else if (mpl->c == '<') + { mpl->token = T_LT, append_char(mpl); + if (mpl->c == '=') + mpl->token = T_LE, append_char(mpl); + else if (mpl->c == '>') + mpl->token = T_NE, append_char(mpl); +#if 1 /* 11/II-2008 */ + else if (mpl->c == '-') + mpl->token = T_INPUT, append_char(mpl); +#endif + } + else if (mpl->c == '=') + { mpl->token = T_EQ, append_char(mpl); + if (mpl->c == '=') append_char(mpl); + } + else if (mpl->c == '>') + { mpl->token = T_GT, append_char(mpl); + if (mpl->c == '=') + mpl->token = T_GE, append_char(mpl); +#if 1 /* 14/VII-2006 */ + else if (mpl->c == '>') + mpl->token = T_APPEND, append_char(mpl); +#endif + } + else if (mpl->c == '!') + { mpl->token = T_NOT, append_char(mpl); + if (mpl->c == '=') + mpl->token = T_NE, append_char(mpl); + } + else if (mpl->c == '&') + { mpl->token = T_CONCAT, append_char(mpl); + if (mpl->c == '&') + mpl->token = T_AND, append_char(mpl); + } + else if (mpl->c == '|') + { mpl->token = T_BAR, append_char(mpl); + if (mpl->c == '|') + mpl->token = T_OR, append_char(mpl); + } + else if (!mpl->flag_d && mpl->c == '.') + { mpl->token = T_POINT, append_char(mpl); + if (mpl->f_dots) + { /* dots; the first dot was read on the previous call to the + scanner, so the current character is the second dot */ + mpl->token = T_DOTS; + mpl->imlen = 2; + strcpy(mpl->image, ".."); + mpl->f_dots = 0; + } + else if (mpl->c == '.') + mpl->token = T_DOTS, append_char(mpl); + else if (isdigit(mpl->c)) + { /* numeric literal that begins with the decimal point */ + mpl->token = T_NUMBER, append_char(mpl); + goto frac; + } + } + else if (mpl->c == ',') + mpl->token = T_COMMA, append_char(mpl); + else if (mpl->c == ':') + { mpl->token = T_COLON, append_char(mpl); + if (mpl->c == '=') + mpl->token = T_ASSIGN, append_char(mpl); + } + else if (mpl->c == ';') + mpl->token = T_SEMICOLON, append_char(mpl); + else if (mpl->c == '(') + mpl->token = T_LEFT, append_char(mpl); + else if (mpl->c == ')') + mpl->token = T_RIGHT, append_char(mpl); + else if (mpl->c == '[') + mpl->token = T_LBRACKET, append_char(mpl); + else if (mpl->c == ']') + mpl->token = T_RBRACKET, append_char(mpl); + else if (mpl->c == '{') + mpl->token = T_LBRACE, append_char(mpl); + else if (mpl->c == '}') + mpl->token = T_RBRACE, append_char(mpl); +#if 1 /* 11/II-2008 */ + else if (mpl->c == '~') + mpl->token = T_TILDE, append_char(mpl); +#endif + else if (isalnum(mpl->c) || strchr("+-._", mpl->c) != NULL) + { /* symbol */ + xassert(mpl->flag_d); + mpl->token = T_SYMBOL; + while (isalnum(mpl->c) || strchr("+-._", mpl->c) != NULL) + append_char(mpl); + switch (str2num(mpl->image, &mpl->value)) + { case 0: + mpl->token = T_NUMBER; + break; + case 1: + goto err; + case 2: + break; + default: + xassert(mpl != mpl); + } + } + else + { enter_context(mpl); + error(mpl, "character %c not allowed", mpl->c); + } + /* enter the current token into the context queue */ + enter_context(mpl); + /* reset the flag, which may be set by indexing_expression() and + is used by expression_list() */ + mpl->flag_x = 0; +done: return; +} + +/*---------------------------------------------------------------------- +-- unget_token - return current token back to input stream. +-- +-- This routine returns the current token back to the input stream, so +-- the previously scanned token becomes the current one. */ + +void unget_token(MPL *mpl) +{ /* save the current token, which becomes the next one */ + xassert(!mpl->f_scan); + mpl->f_scan = 1; + mpl->f_token = mpl->token; + mpl->f_imlen = mpl->imlen; + strcpy(mpl->f_image, mpl->image); + mpl->f_value = mpl->value; + /* restore the previous token, which becomes the current one */ + mpl->token = mpl->b_token; + mpl->imlen = mpl->b_imlen; + strcpy(mpl->image, mpl->b_image); + mpl->value = mpl->b_value; + return; +} + +/*---------------------------------------------------------------------- +-- is_keyword - check if current token is given non-reserved keyword. +-- +-- If the current token is given (non-reserved) keyword, this routine +-- returns non-zero. Otherwise zero is returned. */ + +int is_keyword(MPL *mpl, char *keyword) +{ return + mpl->token == T_NAME && strcmp(mpl->image, keyword) == 0; +} + +/*---------------------------------------------------------------------- +-- is_reserved - check if current token is reserved keyword. +-- +-- If the current token is a reserved keyword, this routine returns +-- non-zero. Otherwise zero is returned. */ + +int is_reserved(MPL *mpl) +{ return + mpl->token == T_AND && mpl->image[0] == 'a' || + mpl->token == T_BY || + mpl->token == T_CROSS || + mpl->token == T_DIFF || + mpl->token == T_DIV || + mpl->token == T_ELSE || + mpl->token == T_IF || + mpl->token == T_IN || + mpl->token == T_INTER || + mpl->token == T_LESS || + mpl->token == T_MOD || + mpl->token == T_NOT && mpl->image[0] == 'n' || + mpl->token == T_OR && mpl->image[0] == 'o' || + mpl->token == T_SYMDIFF || + mpl->token == T_THEN || + mpl->token == T_UNION || + mpl->token == T_WITHIN; +} + +/*---------------------------------------------------------------------- +-- make_code - generate pseudo-code (basic routine). +-- +-- This routine generates specified pseudo-code. It is assumed that all +-- other translator routines use this basic routine. */ + +CODE *make_code(MPL *mpl, int op, OPERANDS *arg, int type, int dim) +{ CODE *code; + DOMAIN *domain; + DOMAIN_BLOCK *block; + ARG_LIST *e; + /* generate pseudo-code */ + code = alloc(CODE); + code->op = op; + code->vflag = 0; /* is inherited from operand(s) */ + /* copy operands and also make them referring to the pseudo-code + being generated, because the latter becomes the parent for all + its operands */ + memset(&code->arg, '?', sizeof(OPERANDS)); + switch (op) + { case O_NUMBER: + code->arg.num = arg->num; + break; + case O_STRING: + code->arg.str = arg->str; + break; + case O_INDEX: + code->arg.index.slot = arg->index.slot; + code->arg.index.next = arg->index.next; + break; + case O_MEMNUM: + case O_MEMSYM: + for (e = arg->par.list; e != NULL; e = e->next) + { xassert(e->x != NULL); + xassert(e->x->up == NULL); + e->x->up = code; + code->vflag |= e->x->vflag; + } + code->arg.par.par = arg->par.par; + code->arg.par.list = arg->par.list; + break; + case O_MEMSET: + for (e = arg->set.list; e != NULL; e = e->next) + { xassert(e->x != NULL); + xassert(e->x->up == NULL); + e->x->up = code; + code->vflag |= e->x->vflag; + } + code->arg.set.set = arg->set.set; + code->arg.set.list = arg->set.list; + break; + case O_MEMVAR: + for (e = arg->var.list; e != NULL; e = e->next) + { xassert(e->x != NULL); + xassert(e->x->up == NULL); + e->x->up = code; + code->vflag |= e->x->vflag; + } + code->arg.var.var = arg->var.var; + code->arg.var.list = arg->var.list; +#if 1 /* 15/V-2010 */ + code->arg.var.suff = arg->var.suff; +#endif + break; +#if 1 /* 15/V-2010 */ + case O_MEMCON: + for (e = arg->con.list; e != NULL; e = e->next) + { xassert(e->x != NULL); + xassert(e->x->up == NULL); + e->x->up = code; + code->vflag |= e->x->vflag; + } + code->arg.con.con = arg->con.con; + code->arg.con.list = arg->con.list; + code->arg.con.suff = arg->con.suff; + break; +#endif + case O_TUPLE: + case O_MAKE: + for (e = arg->list; e != NULL; e = e->next) + { xassert(e->x != NULL); + xassert(e->x->up == NULL); + e->x->up = code; + code->vflag |= e->x->vflag; + } + code->arg.list = arg->list; + break; + case O_SLICE: + xassert(arg->slice != NULL); + code->arg.slice = arg->slice; + break; + case O_IRAND224: + case O_UNIFORM01: + case O_NORMAL01: + case O_GMTIME: + code->vflag = 1; + break; + case O_CVTNUM: + case O_CVTSYM: + case O_CVTLOG: + case O_CVTTUP: + case O_CVTLFM: + case O_PLUS: + case O_MINUS: + case O_NOT: + case O_ABS: + case O_CEIL: + case O_FLOOR: + case O_EXP: + case O_LOG: + case O_LOG10: + case O_SQRT: + case O_SIN: + case O_COS: + case O_ATAN: + case O_ROUND: + case O_TRUNC: + case O_CARD: + case O_LENGTH: + /* unary operation */ + xassert(arg->arg.x != NULL); + xassert(arg->arg.x->up == NULL); + arg->arg.x->up = code; + code->vflag |= arg->arg.x->vflag; + code->arg.arg.x = arg->arg.x; + break; + case O_ADD: + case O_SUB: + case O_LESS: + case O_MUL: + case O_DIV: + case O_IDIV: + case O_MOD: + case O_POWER: + case O_ATAN2: + case O_ROUND2: + case O_TRUNC2: + case O_UNIFORM: + if (op == O_UNIFORM) code->vflag = 1; + case O_NORMAL: + if (op == O_NORMAL) code->vflag = 1; + case O_CONCAT: + case O_LT: + case O_LE: + case O_EQ: + case O_GE: + case O_GT: + case O_NE: + case O_AND: + case O_OR: + case O_UNION: + case O_DIFF: + case O_SYMDIFF: + case O_INTER: + case O_CROSS: + case O_IN: + case O_NOTIN: + case O_WITHIN: + case O_NOTWITHIN: + case O_SUBSTR: + case O_STR2TIME: + case O_TIME2STR: + /* binary operation */ + xassert(arg->arg.x != NULL); + xassert(arg->arg.x->up == NULL); + arg->arg.x->up = code; + code->vflag |= arg->arg.x->vflag; + xassert(arg->arg.y != NULL); + xassert(arg->arg.y->up == NULL); + arg->arg.y->up = code; + code->vflag |= arg->arg.y->vflag; + code->arg.arg.x = arg->arg.x; + code->arg.arg.y = arg->arg.y; + break; + case O_DOTS: + case O_FORK: + case O_SUBSTR3: + /* ternary operation */ + xassert(arg->arg.x != NULL); + xassert(arg->arg.x->up == NULL); + arg->arg.x->up = code; + code->vflag |= arg->arg.x->vflag; + xassert(arg->arg.y != NULL); + xassert(arg->arg.y->up == NULL); + arg->arg.y->up = code; + code->vflag |= arg->arg.y->vflag; + if (arg->arg.z != NULL) + { xassert(arg->arg.z->up == NULL); + arg->arg.z->up = code; + code->vflag |= arg->arg.z->vflag; + } + code->arg.arg.x = arg->arg.x; + code->arg.arg.y = arg->arg.y; + code->arg.arg.z = arg->arg.z; + break; + case O_MIN: + case O_MAX: + /* n-ary operation */ + for (e = arg->list; e != NULL; e = e->next) + { xassert(e->x != NULL); + xassert(e->x->up == NULL); + e->x->up = code; + code->vflag |= e->x->vflag; + } + code->arg.list = arg->list; + break; + case O_SUM: + case O_PROD: + case O_MINIMUM: + case O_MAXIMUM: + case O_FORALL: + case O_EXISTS: + case O_SETOF: + case O_BUILD: + /* iterated operation */ + domain = arg->loop.domain; + xassert(domain != NULL); + if (domain->code != NULL) + { xassert(domain->code->up == NULL); + domain->code->up = code; + code->vflag |= domain->code->vflag; + } + for (block = domain->list; block != NULL; block = + block->next) + { xassert(block->code != NULL); + xassert(block->code->up == NULL); + block->code->up = code; + code->vflag |= block->code->vflag; + } + if (arg->loop.x != NULL) + { xassert(arg->loop.x->up == NULL); + arg->loop.x->up = code; + code->vflag |= arg->loop.x->vflag; + } + code->arg.loop.domain = arg->loop.domain; + code->arg.loop.x = arg->loop.x; + break; + default: + xassert(op != op); + } + /* set other attributes of the pseudo-code */ + code->type = type; + code->dim = dim; + code->up = NULL; + code->valid = 0; + memset(&code->value, '?', sizeof(VALUE)); + return code; +} + +/*---------------------------------------------------------------------- +-- make_unary - generate pseudo-code for unary operation. +-- +-- This routine generates pseudo-code for unary operation. */ + +CODE *make_unary(MPL *mpl, int op, CODE *x, int type, int dim) +{ CODE *code; + OPERANDS arg; + xassert(x != NULL); + arg.arg.x = x; + code = make_code(mpl, op, &arg, type, dim); + return code; +} + +/*---------------------------------------------------------------------- +-- make_binary - generate pseudo-code for binary operation. +-- +-- This routine generates pseudo-code for binary operation. */ + +CODE *make_binary(MPL *mpl, int op, CODE *x, CODE *y, int type, + int dim) +{ CODE *code; + OPERANDS arg; + xassert(x != NULL); + xassert(y != NULL); + arg.arg.x = x; + arg.arg.y = y; + code = make_code(mpl, op, &arg, type, dim); + return code; +} + +/*---------------------------------------------------------------------- +-- make_ternary - generate pseudo-code for ternary operation. +-- +-- This routine generates pseudo-code for ternary operation. */ + +CODE *make_ternary(MPL *mpl, int op, CODE *x, CODE *y, CODE *z, + int type, int dim) +{ CODE *code; + OPERANDS arg; + xassert(x != NULL); + xassert(y != NULL); + /* third operand can be NULL */ + arg.arg.x = x; + arg.arg.y = y; + arg.arg.z = z; + code = make_code(mpl, op, &arg, type, dim); + return code; +} + +/*---------------------------------------------------------------------- +-- numeric_literal - parse reference to numeric literal. +-- +-- This routine parses primary expression using the syntax: +-- +-- ::= */ + +CODE *numeric_literal(MPL *mpl) +{ CODE *code; + OPERANDS arg; + xassert(mpl->token == T_NUMBER); + arg.num = mpl->value; + code = make_code(mpl, O_NUMBER, &arg, A_NUMERIC, 0); + get_token(mpl /* */); + return code; +} + +/*---------------------------------------------------------------------- +-- string_literal - parse reference to string literal. +-- +-- This routine parses primary expression using the syntax: +-- +-- ::= */ + +CODE *string_literal(MPL *mpl) +{ CODE *code; + OPERANDS arg; + xassert(mpl->token == T_STRING); + arg.str = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(arg.str, mpl->image); + code = make_code(mpl, O_STRING, &arg, A_SYMBOLIC, 0); + get_token(mpl /* */); + return code; +} + +/*---------------------------------------------------------------------- +-- create_arg_list - create empty operands list. +-- +-- This routine creates operands list, which is initially empty. */ + +ARG_LIST *create_arg_list(MPL *mpl) +{ ARG_LIST *list; + xassert(mpl == mpl); + list = NULL; + return list; +} + +/*---------------------------------------------------------------------- +-- expand_arg_list - append operand to operands list. +-- +-- This routine appends new operand to specified operands list. */ + +ARG_LIST *expand_arg_list(MPL *mpl, ARG_LIST *list, CODE *x) +{ ARG_LIST *tail, *temp; + xassert(x != NULL); + /* create new operands list entry */ + tail = alloc(ARG_LIST); + tail->x = x; + tail->next = NULL; + /* and append it to the operands list */ + if (list == NULL) + list = tail; + else + { for (temp = list; temp->next != NULL; temp = temp->next); + temp->next = tail; + } + return list; +} + +/*---------------------------------------------------------------------- +-- arg_list_len - determine length of operands list. +-- +-- This routine returns the number of operands in operands list. */ + +int arg_list_len(MPL *mpl, ARG_LIST *list) +{ ARG_LIST *temp; + int len; + xassert(mpl == mpl); + len = 0; + for (temp = list; temp != NULL; temp = temp->next) len++; + return len; +} + +/*---------------------------------------------------------------------- +-- subscript_list - parse subscript list. +-- +-- This routine parses subscript list using the syntax: +-- +-- ::= +-- ::= , +-- ::= */ + +ARG_LIST *subscript_list(MPL *mpl) +{ ARG_LIST *list; + CODE *x; + list = create_arg_list(mpl); + for (;;) + { /* parse subscript expression */ + x = expression_5(mpl); + /* convert it to symbolic type, if necessary */ + if (x->type == A_NUMERIC) + x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); + /* check that now the expression is of symbolic type */ + if (x->type != A_SYMBOLIC) + error(mpl, "subscript expression has invalid type"); + xassert(x->dim == 0); + /* and append it to the subscript list */ + list = expand_arg_list(mpl, list, x); + /* check a token that follows the subscript expression */ + if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else if (mpl->token == T_RBRACKET) + break; + else + error(mpl, "syntax error in subscript list"); + } + return list; +} + +#if 1 /* 15/V-2010 */ +/*---------------------------------------------------------------------- +-- object_reference - parse reference to named object. +-- +-- This routine parses primary expression using the syntax: +-- +-- ::= +-- ::= +-- ::= [ ] +-- ::= +-- ::= [ ] +-- ::= +-- ::= [ ] +-- +-- ::= +-- ::= [ ] +-- +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= | .lb | .ub | .status | .val | .dual */ + +CODE *object_reference(MPL *mpl) +{ AVLNODE *node; + DOMAIN_SLOT *slot; + SET *set; + PARAMETER *par; + VARIABLE *var; + CONSTRAINT *con; + ARG_LIST *list; + OPERANDS arg; + CODE *code; + char *name; + int dim, suff; + /* find the object in the symbolic name table */ + xassert(mpl->token == T_NAME); + node = avl_find_node(mpl->tree, mpl->image); + if (node == NULL) + error(mpl, "%s not defined", mpl->image); + /* check the object type and obtain its dimension */ + switch (avl_get_node_type(node)) + { case A_INDEX: + /* dummy index */ + slot = (DOMAIN_SLOT *)avl_get_node_link(node); + name = slot->name; + dim = 0; + break; + case A_SET: + /* model set */ + set = (SET *)avl_get_node_link(node); + name = set->name; + dim = set->dim; + /* if a set object is referenced in its own declaration and + the dimen attribute is not specified yet, use dimen 1 by + default */ + if (set->dimen == 0) set->dimen = 1; + break; + case A_PARAMETER: + /* model parameter */ + par = (PARAMETER *)avl_get_node_link(node); + name = par->name; + dim = par->dim; + break; + case A_VARIABLE: + /* model variable */ + var = (VARIABLE *)avl_get_node_link(node); + name = var->name; + dim = var->dim; + break; + case A_CONSTRAINT: + /* model constraint or objective */ + con = (CONSTRAINT *)avl_get_node_link(node); + name = con->name; + dim = con->dim; + break; + default: + xassert(node != node); + } + get_token(mpl /* */); + /* parse optional subscript list */ + if (mpl->token == T_LBRACKET) + { /* subscript list is specified */ + if (dim == 0) + error(mpl, "%s cannot be subscripted", name); + get_token(mpl /* [ */); + list = subscript_list(mpl); + if (dim != arg_list_len(mpl, list)) + error(mpl, "%s must have %d subscript%s rather than %d", + name, dim, dim == 1 ? "" : "s", arg_list_len(mpl, list)); + xassert(mpl->token == T_RBRACKET); + get_token(mpl /* ] */); + } + else + { /* subscript list is not specified */ + if (dim != 0) + error(mpl, "%s must be subscripted", name); + list = create_arg_list(mpl); + } + /* parse optional suffix */ + if (!mpl->flag_s && avl_get_node_type(node) == A_VARIABLE) + suff = DOT_NONE; + else + suff = DOT_VAL; + if (mpl->token == T_POINT) + { get_token(mpl /* . */); + if (mpl->token != T_NAME) + error(mpl, "invalid use of period"); + if (!(avl_get_node_type(node) == A_VARIABLE || + avl_get_node_type(node) == A_CONSTRAINT)) + error(mpl, "%s cannot have a suffix", name); + if (strcmp(mpl->image, "lb") == 0) + suff = DOT_LB; + else if (strcmp(mpl->image, "ub") == 0) + suff = DOT_UB; + else if (strcmp(mpl->image, "status") == 0) + suff = DOT_STATUS; + else if (strcmp(mpl->image, "val") == 0) + suff = DOT_VAL; + else if (strcmp(mpl->image, "dual") == 0) + suff = DOT_DUAL; + else + error(mpl, "suffix .%s invalid", mpl->image); + get_token(mpl /* suffix */); + } + /* generate pseudo-code to take value of the object */ + switch (avl_get_node_type(node)) + { case A_INDEX: + arg.index.slot = slot; + arg.index.next = slot->list; + code = make_code(mpl, O_INDEX, &arg, A_SYMBOLIC, 0); + slot->list = code; + break; + case A_SET: + arg.set.set = set; + arg.set.list = list; + code = make_code(mpl, O_MEMSET, &arg, A_ELEMSET, + set->dimen); + break; + case A_PARAMETER: + arg.par.par = par; + arg.par.list = list; + if (par->type == A_SYMBOLIC) + code = make_code(mpl, O_MEMSYM, &arg, A_SYMBOLIC, 0); + else + code = make_code(mpl, O_MEMNUM, &arg, A_NUMERIC, 0); + break; + case A_VARIABLE: + if (!mpl->flag_s && (suff == DOT_STATUS || suff == DOT_VAL + || suff == DOT_DUAL)) + error(mpl, "invalid reference to status, primal value, o" + "r dual value of variable %s above solve statement", + var->name); + arg.var.var = var; + arg.var.list = list; + arg.var.suff = suff; + code = make_code(mpl, O_MEMVAR, &arg, suff == DOT_NONE ? + A_FORMULA : A_NUMERIC, 0); + break; + case A_CONSTRAINT: + if (!mpl->flag_s && (suff == DOT_STATUS || suff == DOT_VAL + || suff == DOT_DUAL)) + error(mpl, "invalid reference to status, primal value, o" + "r dual value of %s %s above solve statement", + con->type == A_CONSTRAINT ? "constraint" : "objective" + , con->name); + arg.con.con = con; + arg.con.list = list; + arg.con.suff = suff; + code = make_code(mpl, O_MEMCON, &arg, A_NUMERIC, 0); + break; + default: + xassert(node != node); + } + return code; +} +#endif + +/*---------------------------------------------------------------------- +-- numeric_argument - parse argument passed to built-in function. +-- +-- This routine parses an argument passed to numeric built-in function +-- using the syntax: +-- +-- ::= */ + +CODE *numeric_argument(MPL *mpl, char *func) +{ CODE *x; + x = expression_5(mpl); + /* convert the argument to numeric type, if necessary */ + if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + /* check that now the argument is of numeric type */ + if (x->type != A_NUMERIC) + error(mpl, "argument for %s has invalid type", func); + xassert(x->dim == 0); + return x; +} + +#if 1 /* 15/VII-2006 */ +CODE *symbolic_argument(MPL *mpl, char *func) +{ CODE *x; + x = expression_5(mpl); + /* convert the argument to symbolic type, if necessary */ + if (x->type == A_NUMERIC) + x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); + /* check that now the argument is of symbolic type */ + if (x->type != A_SYMBOLIC) + error(mpl, "argument for %s has invalid type", func); + xassert(x->dim == 0); + return x; +} +#endif + +#if 1 /* 15/VII-2006 */ +CODE *elemset_argument(MPL *mpl, char *func) +{ CODE *x; + x = expression_9(mpl); + if (x->type != A_ELEMSET) + error(mpl, "argument for %s has invalid type", func); + xassert(x->dim > 0); + return x; +} +#endif + +/*---------------------------------------------------------------------- +-- function_reference - parse reference to built-in function. +-- +-- This routine parses primary expression using the syntax: +-- +-- ::= abs ( ) +-- ::= ceil ( ) +-- ::= floor ( ) +-- ::= exp ( ) +-- ::= log ( ) +-- ::= log10 ( ) +-- ::= max ( ) +-- ::= min ( ) +-- ::= sqrt ( ) +-- ::= sin ( ) +-- ::= cos ( ) +-- ::= atan ( ) +-- ::= atan2 ( , ) +-- ::= round ( ) +-- ::= round ( , ) +-- ::= trunc ( ) +-- ::= trunc ( , ) +-- ::= Irand224 ( ) +-- ::= Uniform01 ( ) +-- ::= Uniform ( , ) +-- ::= Normal01 ( ) +-- ::= Normal ( , ) +-- ::= card ( ) +-- ::= length ( ) +-- ::= substr ( , ) +-- ::= substr ( , , ) +-- ::= str2time ( , ) +-- ::= time2str ( , ) +-- ::= gmtime ( ) +-- ::= +-- ::= , */ + +CODE *function_reference(MPL *mpl) +{ CODE *code; + OPERANDS arg; + int op; + char func[15+1]; + /* determine operation code */ + xassert(mpl->token == T_NAME); + if (strcmp(mpl->image, "abs") == 0) + op = O_ABS; + else if (strcmp(mpl->image, "ceil") == 0) + op = O_CEIL; + else if (strcmp(mpl->image, "floor") == 0) + op = O_FLOOR; + else if (strcmp(mpl->image, "exp") == 0) + op = O_EXP; + else if (strcmp(mpl->image, "log") == 0) + op = O_LOG; + else if (strcmp(mpl->image, "log10") == 0) + op = O_LOG10; + else if (strcmp(mpl->image, "sqrt") == 0) + op = O_SQRT; + else if (strcmp(mpl->image, "sin") == 0) + op = O_SIN; + else if (strcmp(mpl->image, "cos") == 0) + op = O_COS; + else if (strcmp(mpl->image, "atan") == 0) + op = O_ATAN; + else if (strcmp(mpl->image, "min") == 0) + op = O_MIN; + else if (strcmp(mpl->image, "max") == 0) + op = O_MAX; + else if (strcmp(mpl->image, "round") == 0) + op = O_ROUND; + else if (strcmp(mpl->image, "trunc") == 0) + op = O_TRUNC; + else if (strcmp(mpl->image, "Irand224") == 0) + op = O_IRAND224; + else if (strcmp(mpl->image, "Uniform01") == 0) + op = O_UNIFORM01; + else if (strcmp(mpl->image, "Uniform") == 0) + op = O_UNIFORM; + else if (strcmp(mpl->image, "Normal01") == 0) + op = O_NORMAL01; + else if (strcmp(mpl->image, "Normal") == 0) + op = O_NORMAL; + else if (strcmp(mpl->image, "card") == 0) + op = O_CARD; + else if (strcmp(mpl->image, "length") == 0) + op = O_LENGTH; + else if (strcmp(mpl->image, "substr") == 0) + op = O_SUBSTR; + else if (strcmp(mpl->image, "str2time") == 0) + op = O_STR2TIME; + else if (strcmp(mpl->image, "time2str") == 0) + op = O_TIME2STR; + else if (strcmp(mpl->image, "gmtime") == 0) + op = O_GMTIME; + else + error(mpl, "function %s unknown", mpl->image); + /* save symbolic name of the function */ + strcpy(func, mpl->image); + xassert(strlen(func) < sizeof(func)); + get_token(mpl /* */); + /* check the left parenthesis that follows the function name */ + xassert(mpl->token == T_LEFT); + get_token(mpl /* ( */); + /* parse argument list */ + if (op == O_MIN || op == O_MAX) + { /* min and max allow arbitrary number of arguments */ + arg.list = create_arg_list(mpl); + /* parse argument list */ + for (;;) + { /* parse argument and append it to the operands list */ + arg.list = expand_arg_list(mpl, arg.list, + numeric_argument(mpl, func)); + /* check a token that follows the argument */ + if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else if (mpl->token == T_RIGHT) + break; + else + error(mpl, "syntax error in argument list for %s", func); + } + } + else if (op == O_IRAND224 || op == O_UNIFORM01 || op == + O_NORMAL01 || op == O_GMTIME) + { /* Irand224, Uniform01, Normal01, gmtime need no arguments */ + if (mpl->token != T_RIGHT) + error(mpl, "%s needs no arguments", func); + } + else if (op == O_UNIFORM || op == O_NORMAL) + { /* Uniform and Normal need two arguments */ + /* parse the first argument */ + arg.arg.x = numeric_argument(mpl, func); + /* check a token that follows the first argument */ + if (mpl->token == T_COMMA) + ; + else if (mpl->token == T_RIGHT) + error(mpl, "%s needs two arguments", func); + else + error(mpl, "syntax error in argument for %s", func); + get_token(mpl /* , */); + /* parse the second argument */ + arg.arg.y = numeric_argument(mpl, func); + /* check a token that follows the second argument */ + if (mpl->token == T_COMMA) + error(mpl, "%s needs two argument", func); + else if (mpl->token == T_RIGHT) + ; + else + error(mpl, "syntax error in argument for %s", func); + } + else if (op == O_ATAN || op == O_ROUND || op == O_TRUNC) + { /* atan, round, and trunc need one or two arguments */ + /* parse the first argument */ + arg.arg.x = numeric_argument(mpl, func); + /* parse the second argument, if specified */ + if (mpl->token == T_COMMA) + { switch (op) + { case O_ATAN: op = O_ATAN2; break; + case O_ROUND: op = O_ROUND2; break; + case O_TRUNC: op = O_TRUNC2; break; + default: xassert(op != op); + } + get_token(mpl /* , */); + arg.arg.y = numeric_argument(mpl, func); + } + /* check a token that follows the last argument */ + if (mpl->token == T_COMMA) + error(mpl, "%s needs one or two arguments", func); + else if (mpl->token == T_RIGHT) + ; + else + error(mpl, "syntax error in argument for %s", func); + } + else if (op == O_SUBSTR) + { /* substr needs two or three arguments */ + /* parse the first argument */ + arg.arg.x = symbolic_argument(mpl, func); + /* check a token that follows the first argument */ + if (mpl->token == T_COMMA) + ; + else if (mpl->token == T_RIGHT) + error(mpl, "%s needs two or three arguments", func); + else + error(mpl, "syntax error in argument for %s", func); + get_token(mpl /* , */); + /* parse the second argument */ + arg.arg.y = numeric_argument(mpl, func); + /* parse the third argument, if specified */ + if (mpl->token == T_COMMA) + { op = O_SUBSTR3; + get_token(mpl /* , */); + arg.arg.z = numeric_argument(mpl, func); + } + /* check a token that follows the last argument */ + if (mpl->token == T_COMMA) + error(mpl, "%s needs two or three arguments", func); + else if (mpl->token == T_RIGHT) + ; + else + error(mpl, "syntax error in argument for %s", func); + } + else if (op == O_STR2TIME) + { /* str2time needs two arguments, both symbolic */ + /* parse the first argument */ + arg.arg.x = symbolic_argument(mpl, func); + /* check a token that follows the first argument */ + if (mpl->token == T_COMMA) + ; + else if (mpl->token == T_RIGHT) + error(mpl, "%s needs two arguments", func); + else + error(mpl, "syntax error in argument for %s", func); + get_token(mpl /* , */); + /* parse the second argument */ + arg.arg.y = symbolic_argument(mpl, func); + /* check a token that follows the second argument */ + if (mpl->token == T_COMMA) + error(mpl, "%s needs two argument", func); + else if (mpl->token == T_RIGHT) + ; + else + error(mpl, "syntax error in argument for %s", func); + } + else if (op == O_TIME2STR) + { /* time2str needs two arguments, numeric and symbolic */ + /* parse the first argument */ + arg.arg.x = numeric_argument(mpl, func); + /* check a token that follows the first argument */ + if (mpl->token == T_COMMA) + ; + else if (mpl->token == T_RIGHT) + error(mpl, "%s needs two arguments", func); + else + error(mpl, "syntax error in argument for %s", func); + get_token(mpl /* , */); + /* parse the second argument */ + arg.arg.y = symbolic_argument(mpl, func); + /* check a token that follows the second argument */ + if (mpl->token == T_COMMA) + error(mpl, "%s needs two argument", func); + else if (mpl->token == T_RIGHT) + ; + else + error(mpl, "syntax error in argument for %s", func); + } + else + { /* other functions need one argument */ + if (op == O_CARD) + arg.arg.x = elemset_argument(mpl, func); + else if (op == O_LENGTH) + arg.arg.x = symbolic_argument(mpl, func); + else + arg.arg.x = numeric_argument(mpl, func); + /* check a token that follows the argument */ + if (mpl->token == T_COMMA) + error(mpl, "%s needs one argument", func); + else if (mpl->token == T_RIGHT) + ; + else + error(mpl, "syntax error in argument for %s", func); + } + /* make pseudo-code to call the built-in function */ + if (op == O_SUBSTR || op == O_SUBSTR3 || op == O_TIME2STR) + code = make_code(mpl, op, &arg, A_SYMBOLIC, 0); + else + code = make_code(mpl, op, &arg, A_NUMERIC, 0); + /* the reference ends with the right parenthesis */ + xassert(mpl->token == T_RIGHT); + get_token(mpl /* ) */); + return code; +} + +/*---------------------------------------------------------------------- +-- create_domain - create empty domain. +-- +-- This routine creates empty domain, which is initially empty, i.e. +-- has no domain blocks. */ + +DOMAIN *create_domain(MPL *mpl) +{ DOMAIN *domain; + domain = alloc(DOMAIN); + domain->list = NULL; + domain->code = NULL; + return domain; +} + +/*---------------------------------------------------------------------- +-- create_block - create empty domain block. +-- +-- This routine creates empty domain block, which is initially empty, +-- i.e. has no domain slots. */ + +DOMAIN_BLOCK *create_block(MPL *mpl) +{ DOMAIN_BLOCK *block; + block = alloc(DOMAIN_BLOCK); + block->list = NULL; + block->code = NULL; + block->backup = NULL; + block->next = NULL; + return block; +} + +/*---------------------------------------------------------------------- +-- append_block - append domain block to specified domain. +-- +-- This routine adds given domain block to the end of the block list of +-- specified domain. */ + +void append_block(MPL *mpl, DOMAIN *domain, DOMAIN_BLOCK *block) +{ DOMAIN_BLOCK *temp; + xassert(mpl == mpl); + xassert(domain != NULL); + xassert(block != NULL); + xassert(block->next == NULL); + if (domain->list == NULL) + domain->list = block; + else + { for (temp = domain->list; temp->next != NULL; temp = + temp->next); + temp->next = block; + } + return; +} + +/*---------------------------------------------------------------------- +-- append_slot - create and append new slot to domain block. +-- +-- This routine creates new domain slot and adds it to the end of slot +-- list of specified domain block. +-- +-- The parameter name is symbolic name of the dummy index associated +-- with the slot (the character string must be allocated). NULL means +-- the dummy index is not explicitly specified. +-- +-- The parameter code is pseudo-code for computing symbolic value, at +-- which the dummy index is bounded. NULL means the dummy index is free +-- in the domain scope. */ + +DOMAIN_SLOT *append_slot(MPL *mpl, DOMAIN_BLOCK *block, char *name, + CODE *code) +{ DOMAIN_SLOT *slot, *temp; + xassert(block != NULL); + slot = alloc(DOMAIN_SLOT); + slot->name = name; + slot->code = code; + slot->value = NULL; + slot->list = NULL; + slot->next = NULL; + if (block->list == NULL) + block->list = slot; + else + { for (temp = block->list; temp->next != NULL; temp = + temp->next); + temp->next = slot; + } + return slot; +} + +/*---------------------------------------------------------------------- +-- expression_list - parse expression list. +-- +-- This routine parses a list of one or more expressions enclosed into +-- the parentheses using the syntax: +-- +-- ::= ( ) +-- ::= +-- ::= , +-- +-- Note that this construction may have three different meanings: +-- +-- 1. If consists of only one expression, is a parenthesized expression, which may be of any +-- valid type (not necessarily 1-tuple). +-- +-- 2. If consists of several expressions separated by +-- commae, where no expression is undeclared symbolic name, is a n-tuple. +-- +-- 3. If consists of several expressions separated by +-- commae, where at least one expression is undeclared symbolic name +-- (that denotes a dummy index), is a slice and +-- can be only used as constituent of indexing expression. */ + +#define max_dim 20 +/* maximal number of components allowed within parentheses */ + +CODE *expression_list(MPL *mpl) +{ CODE *code; + OPERANDS arg; + struct { char *name; CODE *code; } list[1+max_dim]; + int flag_x, next_token, dim, j, slice = 0; + xassert(mpl->token == T_LEFT); + /* the flag, which allows recognizing undeclared symbolic names + as dummy indices, will be automatically reset by get_token(), + so save it before scanning the next token */ + flag_x = mpl->flag_x; + get_token(mpl /* ( */); + /* parse */ + for (dim = 1; ; dim++) + { if (dim > max_dim) + error(mpl, "too many components within parentheses"); + /* current component of can be either dummy + index or expression */ + if (mpl->token == T_NAME) + { /* symbolic name is recognized as dummy index only if: + the flag, which allows that, is set, and + the name is followed by comma or right parenthesis, and + the name is undeclared */ + get_token(mpl /* */); + next_token = mpl->token; + unget_token(mpl); + if (!(flag_x && + (next_token == T_COMMA || next_token == T_RIGHT) && + avl_find_node(mpl->tree, mpl->image) == NULL)) + { /* this is not dummy index */ + goto expr; + } + /* all dummy indices within the same slice must have unique + symbolic names */ + for (j = 1; j < dim; j++) + { if (list[j].name != NULL && strcmp(list[j].name, + mpl->image) == 0) + error(mpl, "duplicate dummy index %s not allowed", + mpl->image); + } + /* current component of is dummy index */ + list[dim].name + = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(list[dim].name, mpl->image); + list[dim].code = NULL; + get_token(mpl /* */); + /* is a slice, because at least one dummy + index has appeared */ + slice = 1; + /* note that the context ( ) is not allowed, + i.e. in this case is considered as + a parenthesized expression */ + if (dim == 1 && mpl->token == T_RIGHT) + error(mpl, "%s not defined", list[dim].name); + } + else +expr: { /* current component of is expression */ + code = expression_13(mpl); + /* if the current expression is followed by comma or it is + not the very first expression, entire + is n-tuple or slice, in which case the current expression + should be converted to symbolic type, if necessary */ + if (mpl->token == T_COMMA || dim > 1) + { if (code->type == A_NUMERIC) + code = make_unary(mpl, O_CVTSYM, code, A_SYMBOLIC, 0); + /* now the expression must be of symbolic type */ + if (code->type != A_SYMBOLIC) + error(mpl, "component expression has invalid type"); + xassert(code->dim == 0); + } + list[dim].name = NULL; + list[dim].code = code; + } + /* check a token that follows the current component */ + if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else if (mpl->token == T_RIGHT) + break; + else + error(mpl, "right parenthesis missing where expected"); + } + /* generate pseudo-code for */ + if (dim == 1 && !slice) + { /* is a parenthesized expression */ + code = list[1].code; + } + else if (!slice) + { /* is a n-tuple */ + arg.list = create_arg_list(mpl); + for (j = 1; j <= dim; j++) + arg.list = expand_arg_list(mpl, arg.list, list[j].code); + code = make_code(mpl, O_TUPLE, &arg, A_TUPLE, dim); + } + else + { /* is a slice */ + arg.slice = create_block(mpl); + for (j = 1; j <= dim; j++) + append_slot(mpl, arg.slice, list[j].name, list[j].code); + /* note that actually pseudo-codes with op = O_SLICE are never + evaluated */ + code = make_code(mpl, O_SLICE, &arg, A_TUPLE, dim); + } + get_token(mpl /* ) */); + /* if is a slice, there must be the keyword + 'in', which follows the right parenthesis */ + if (slice && mpl->token != T_IN) + error(mpl, "keyword in missing where expected"); + /* if the slice flag is set and there is the keyword 'in', which + follows , the latter must be a slice */ + if (flag_x && mpl->token == T_IN && !slice) + { if (dim == 1) + error(mpl, "syntax error in indexing expression"); + else + error(mpl, "0-ary slice not allowed"); + } + return code; +} + +/*---------------------------------------------------------------------- +-- literal set - parse literal set. +-- +-- This routine parses literal set using the syntax: +-- +-- ::= { } +-- ::= +-- ::= , +-- ::= +-- +-- It is assumed that the left curly brace and the very first member +-- expression that follows it are already parsed. The right curly brace +-- remains unscanned on exit. */ + +CODE *literal_set(MPL *mpl, CODE *code) +{ OPERANDS arg; + int j; + xassert(code != NULL); + arg.list = create_arg_list(mpl); + /* parse */ + for (j = 1; ; j++) + { /* all member expressions must be n-tuples; so, if the current + expression is not n-tuple, convert it to 1-tuple */ + if (code->type == A_NUMERIC) + code = make_unary(mpl, O_CVTSYM, code, A_SYMBOLIC, 0); + if (code->type == A_SYMBOLIC) + code = make_unary(mpl, O_CVTTUP, code, A_TUPLE, 1); + /* now the expression must be n-tuple */ + if (code->type != A_TUPLE) + error(mpl, "member expression has invalid type"); + /* all member expressions must have identical dimension */ + if (arg.list != NULL && arg.list->x->dim != code->dim) + error(mpl, "member %d has %d component%s while member %d ha" + "s %d component%s", + j-1, arg.list->x->dim, arg.list->x->dim == 1 ? "" : "s", + j, code->dim, code->dim == 1 ? "" : "s"); + /* append the current expression to the member list */ + arg.list = expand_arg_list(mpl, arg.list, code); + /* check a token that follows the current expression */ + if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else if (mpl->token == T_RBRACE) + break; + else + error(mpl, "syntax error in literal set"); + /* parse the next expression that follows the comma */ + code = expression_5(mpl); + } + /* generate pseudo-code for */ + code = make_code(mpl, O_MAKE, &arg, A_ELEMSET, arg.list->x->dim); + return code; +} + +/*---------------------------------------------------------------------- +-- indexing_expression - parse indexing expression. +-- +-- This routine parses indexing expression using the syntax: +-- +-- ::= +-- ::= { } +-- ::= { : } +-- ::= +-- ::= , +-- ::= +-- ::= in +-- ::= in +-- ::= +-- ::= ( ) +-- ::= +-- ::= +-- +-- This routine creates domain for , where each +-- domain block corresponds to , and each domain slot +-- corresponds to individual indexing position. */ + +DOMAIN *indexing_expression(MPL *mpl) +{ DOMAIN *domain; + DOMAIN_BLOCK *block; + DOMAIN_SLOT *slot; + CODE *code; + xassert(mpl->token == T_LBRACE); + get_token(mpl /* { */); + if (mpl->token == T_RBRACE) + error(mpl, "empty indexing expression not allowed"); + /* create domain to be constructed */ + domain = create_domain(mpl); + /* parse either or that follows the + left brace */ + for (;;) + { /* domain block for is not created yet */ + block = NULL; + /* pseudo-code for is not generated yet */ + code = NULL; + /* check a token, which begins with */ + if (mpl->token == T_NAME) + { /* it is a symbolic name */ + int next_token; + char *name; + /* symbolic name is recognized as dummy index only if it is + followed by the keyword 'in' and not declared */ + get_token(mpl /* */); + next_token = mpl->token; + unget_token(mpl); + if (!(next_token == T_IN && + avl_find_node(mpl->tree, mpl->image) == NULL)) + { /* this is not dummy index; the symbolic name begins an + expression, which is either or the + very first in */ + goto expr; + } + /* create domain block with one slot, which is assigned the + dummy index */ + block = create_block(mpl); + name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(name, mpl->image); + append_slot(mpl, block, name, NULL); + get_token(mpl /* */); + /* the keyword 'in' is already checked above */ + xassert(mpl->token == T_IN); + get_token(mpl /* in */); + /* that follows the keyword 'in' will be + parsed below */ + } + else if (mpl->token == T_LEFT) + { /* it is the left parenthesis; parse expression that begins + with this parenthesis (the flag is set in order to allow + recognizing slices; see the routine expression_list) */ + mpl->flag_x = 1; + code = expression_9(mpl); + if (code->op != O_SLICE) + { /* this is either or the very first + in */ + goto expr; + } + /* this is a slice; besides the corresponding domain block + is already created by expression_list() */ + block = code->arg.slice; + code = NULL; /* is not parsed yet */ + /* the keyword 'in' following the slice is already checked + by expression_list() */ + xassert(mpl->token == T_IN); + get_token(mpl /* in */); + /* that follows the keyword 'in' will be + parsed below */ + } +expr: /* parse expression that follows either the keyword 'in' (in + which case it can be as well as the + very first in ); note that + this expression can be already parsed above */ + if (code == NULL) code = expression_9(mpl); + /* check the type of the expression just parsed */ + if (code->type != A_ELEMSET) + { /* it is not and therefore it can only + be the very first in ; + however, then there must be no dummy index neither slice + between the left brace and this expression */ + if (block != NULL) + error(mpl, "domain expression has invalid type"); + /* parse the rest part of and make this set + be , i.e. the construction {a, b, c} + is parsed as it were written as {A}, where A = {a, b, c} + is a temporary elemental set */ + code = literal_set(mpl, code); + } + /* now pseudo-code for has been built */ + xassert(code != NULL); + xassert(code->type == A_ELEMSET); + xassert(code->dim > 0); + /* if domain block for the current is still + not created, create it for fake slice of the same dimension + as */ + if (block == NULL) + { int j; + block = create_block(mpl); + for (j = 1; j <= code->dim; j++) + append_slot(mpl, block, NULL, NULL); + } + /* number of indexing positions in must be + the same as dimension of n-tuples in basic set */ + { int dim = 0; + for (slot = block->list; slot != NULL; slot = slot->next) + dim++; + if (dim != code->dim) + error(mpl,"%d %s specified for set of dimension %d", + dim, dim == 1 ? "index" : "indices", code->dim); + } + /* store pseudo-code for in the domain block */ + xassert(block->code == NULL); + block->code = code; + /* and append the domain block to the domain */ + append_block(mpl, domain, block); + /* the current has been completely parsed; + include all its dummy indices into the symbolic name table + to make them available for referencing from expressions; + implicit declarations of dummy indices remain valid while + the corresponding domain scope is valid */ + for (slot = block->list; slot != NULL; slot = slot->next) + if (slot->name != NULL) + { AVLNODE *node; + xassert(avl_find_node(mpl->tree, slot->name) == NULL); + node = avl_insert_node(mpl->tree, slot->name); + avl_set_node_type(node, A_INDEX); + avl_set_node_link(node, (void *)slot); + } + /* check a token that follows */ + if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else if (mpl->token == T_COLON || mpl->token == T_RBRACE) + break; + else + error(mpl, "syntax error in indexing expression"); + } + /* parse that follows the colon */ + if (mpl->token == T_COLON) + { get_token(mpl /* : */); + code = expression_13(mpl); + /* convert the expression to logical type, if necessary */ + if (code->type == A_SYMBOLIC) + code = make_unary(mpl, O_CVTNUM, code, A_NUMERIC, 0); + if (code->type == A_NUMERIC) + code = make_unary(mpl, O_CVTLOG, code, A_LOGICAL, 0); + /* now the expression must be of logical type */ + if (code->type != A_LOGICAL) + error(mpl, "expression following colon has invalid type"); + xassert(code->dim == 0); + domain->code = code; + /* the right brace must follow the logical expression */ + if (mpl->token != T_RBRACE) + error(mpl, "syntax error in indexing expression"); + } + get_token(mpl /* } */); + return domain; +} + +/*---------------------------------------------------------------------- +-- close_scope - close scope of indexing expression. +-- +-- The routine closes the scope of indexing expression specified by its +-- domain and thereby makes all dummy indices introduced in the indexing +-- expression no longer available for referencing. */ + +void close_scope(MPL *mpl, DOMAIN *domain) +{ DOMAIN_BLOCK *block; + DOMAIN_SLOT *slot; + AVLNODE *node; + xassert(domain != NULL); + /* remove all dummy indices from the symbolic names table */ + for (block = domain->list; block != NULL; block = block->next) + { for (slot = block->list; slot != NULL; slot = slot->next) + { if (slot->name != NULL) + { node = avl_find_node(mpl->tree, slot->name); + xassert(node != NULL); + xassert(avl_get_node_type(node) == A_INDEX); + avl_delete_node(mpl->tree, node); + } + } + } + return; +} + +/*---------------------------------------------------------------------- +-- iterated_expression - parse iterated expression. +-- +-- This routine parses primary expression using the syntax: +-- +-- ::= +-- ::= sum +-- ::= prod +-- ::= min +-- ::= max +-- ::= exists +-- +-- ::= forall +-- +-- ::= setof +-- +-- Note that parsing "integrand" depends on the iterated operator. */ + +#if 1 /* 07/IX-2008 */ +static void link_up(CODE *code) +{ /* if we have something like sum{(i+1,j,k-1) in E} x[i,j,k], + where i and k are dummy indices defined out of the iterated + expression, we should link up pseudo-code for computing i+1 + and k-1 to pseudo-code for computing the iterated expression; + this is needed to invalidate current value of the iterated + expression once i or k have been changed */ + DOMAIN_BLOCK *block; + DOMAIN_SLOT *slot; + for (block = code->arg.loop.domain->list; block != NULL; + block = block->next) + { for (slot = block->list; slot != NULL; slot = slot->next) + { if (slot->code != NULL) + { xassert(slot->code->up == NULL); + slot->code->up = code; + } + } + } + return; +} +#endif + +CODE *iterated_expression(MPL *mpl) +{ CODE *code; + OPERANDS arg; + int op; + char opstr[8]; + /* determine operation code */ + xassert(mpl->token == T_NAME); + if (strcmp(mpl->image, "sum") == 0) + op = O_SUM; + else if (strcmp(mpl->image, "prod") == 0) + op = O_PROD; + else if (strcmp(mpl->image, "min") == 0) + op = O_MINIMUM; + else if (strcmp(mpl->image, "max") == 0) + op = O_MAXIMUM; + else if (strcmp(mpl->image, "forall") == 0) + op = O_FORALL; + else if (strcmp(mpl->image, "exists") == 0) + op = O_EXISTS; + else if (strcmp(mpl->image, "setof") == 0) + op = O_SETOF; + else + error(mpl, "operator %s unknown", mpl->image); + strcpy(opstr, mpl->image); + xassert(strlen(opstr) < sizeof(opstr)); + get_token(mpl /* */); + /* check the left brace that follows the operator name */ + xassert(mpl->token == T_LBRACE); + /* parse indexing expression that controls iterating */ + arg.loop.domain = indexing_expression(mpl); + /* parse "integrand" expression and generate pseudo-code */ + switch (op) + { case O_SUM: + case O_PROD: + case O_MINIMUM: + case O_MAXIMUM: + arg.loop.x = expression_3(mpl); + /* convert the integrand to numeric type, if necessary */ + if (arg.loop.x->type == A_SYMBOLIC) + arg.loop.x = make_unary(mpl, O_CVTNUM, arg.loop.x, + A_NUMERIC, 0); + /* now the integrand must be of numeric type or linear form + (the latter is only allowed for the sum operator) */ + if (!(arg.loop.x->type == A_NUMERIC || + op == O_SUM && arg.loop.x->type == A_FORMULA)) +err: error(mpl, "integrand following %s{...} has invalid type" + , opstr); + xassert(arg.loop.x->dim == 0); + /* generate pseudo-code */ + code = make_code(mpl, op, &arg, arg.loop.x->type, 0); + break; + case O_FORALL: + case O_EXISTS: + arg.loop.x = expression_12(mpl); + /* convert the integrand to logical type, if necessary */ + if (arg.loop.x->type == A_SYMBOLIC) + arg.loop.x = make_unary(mpl, O_CVTNUM, arg.loop.x, + A_NUMERIC, 0); + if (arg.loop.x->type == A_NUMERIC) + arg.loop.x = make_unary(mpl, O_CVTLOG, arg.loop.x, + A_LOGICAL, 0); + /* now the integrand must be of logical type */ + if (arg.loop.x->type != A_LOGICAL) goto err; + xassert(arg.loop.x->dim == 0); + /* generate pseudo-code */ + code = make_code(mpl, op, &arg, A_LOGICAL, 0); + break; + case O_SETOF: + arg.loop.x = expression_5(mpl); + /* convert the integrand to 1-tuple, if necessary */ + if (arg.loop.x->type == A_NUMERIC) + arg.loop.x = make_unary(mpl, O_CVTSYM, arg.loop.x, + A_SYMBOLIC, 0); + if (arg.loop.x->type == A_SYMBOLIC) + arg.loop.x = make_unary(mpl, O_CVTTUP, arg.loop.x, + A_TUPLE, 1); + /* now the integrand must be n-tuple */ + if (arg.loop.x->type != A_TUPLE) goto err; + xassert(arg.loop.x->dim > 0); + /* generate pseudo-code */ + code = make_code(mpl, op, &arg, A_ELEMSET, arg.loop.x->dim); + break; + default: + xassert(op != op); + } + /* close the scope of the indexing expression */ + close_scope(mpl, arg.loop.domain); +#if 1 /* 07/IX-2008 */ + link_up(code); +#endif + return code; +} + +/*---------------------------------------------------------------------- +-- domain_arity - determine arity of domain. +-- +-- This routine returns arity of specified domain, which is number of +-- its free dummy indices. */ + +int domain_arity(MPL *mpl, DOMAIN *domain) +{ DOMAIN_BLOCK *block; + DOMAIN_SLOT *slot; + int arity; + xassert(mpl == mpl); + arity = 0; + for (block = domain->list; block != NULL; block = block->next) + for (slot = block->list; slot != NULL; slot = slot->next) + if (slot->code == NULL) arity++; + return arity; +} + +/*---------------------------------------------------------------------- +-- set_expression - parse set expression. +-- +-- This routine parses primary expression using the syntax: +-- +-- ::= { } +-- ::= */ + +CODE *set_expression(MPL *mpl) +{ CODE *code; + OPERANDS arg; + xassert(mpl->token == T_LBRACE); + get_token(mpl /* { */); + /* check a token that follows the left brace */ + if (mpl->token == T_RBRACE) + { /* it is the right brace, so the resultant is an empty set of + dimension 1 */ + arg.list = NULL; + /* generate pseudo-code to build the resultant set */ + code = make_code(mpl, O_MAKE, &arg, A_ELEMSET, 1); + get_token(mpl /* } */); + } + else + { /* the next token begins an indexing expression */ + unget_token(mpl); + arg.loop.domain = indexing_expression(mpl); + arg.loop.x = NULL; /* integrand is not used */ + /* close the scope of the indexing expression */ + close_scope(mpl, arg.loop.domain); + /* generate pseudo-code to build the resultant set */ + code = make_code(mpl, O_BUILD, &arg, A_ELEMSET, + domain_arity(mpl, arg.loop.domain)); +#if 1 /* 07/IX-2008 */ + link_up(code); +#endif + } + return code; +} + +/*---------------------------------------------------------------------- +-- branched_expression - parse conditional expression. +-- +-- This routine parses primary expression using the syntax: +-- +-- ::= +-- ::= if then +-- ::= if then +-- else +-- ::= */ + +CODE *branched_expression(MPL *mpl) +{ CODE *code, *x, *y, *z; + xassert(mpl->token == T_IF); + get_token(mpl /* if */); + /* parse that follows 'if' */ + x = expression_13(mpl); + /* convert the expression to logical type, if necessary */ + if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (x->type == A_NUMERIC) + x = make_unary(mpl, O_CVTLOG, x, A_LOGICAL, 0); + /* now the expression must be of logical type */ + if (x->type != A_LOGICAL) + error(mpl, "expression following if has invalid type"); + xassert(x->dim == 0); + /* the keyword 'then' must follow the logical expression */ + if (mpl->token != T_THEN) + error(mpl, "keyword then missing where expected"); + get_token(mpl /* then */); + /* parse that follows 'then' and check its type */ + y = expression_9(mpl); + if (!(y->type == A_NUMERIC || y->type == A_SYMBOLIC || + y->type == A_ELEMSET || y->type == A_FORMULA)) + error(mpl, "expression following then has invalid type"); + /* if the expression that follows the keyword 'then' is elemental + set, the keyword 'else' cannot be omitted; otherwise else-part + is optional */ + if (mpl->token != T_ELSE) + { if (y->type == A_ELEMSET) + error(mpl, "keyword else missing where expected"); + z = NULL; + goto skip; + } + get_token(mpl /* else */); + /* parse that follow 'else' and check its type */ + z = expression_9(mpl); + if (!(z->type == A_NUMERIC || z->type == A_SYMBOLIC || + z->type == A_ELEMSET || z->type == A_FORMULA)) + error(mpl, "expression following else has invalid type"); + /* convert to identical types, if necessary */ + if (y->type == A_FORMULA || z->type == A_FORMULA) + { if (y->type == A_SYMBOLIC) + y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); + if (y->type == A_NUMERIC) + y = make_unary(mpl, O_CVTLFM, y, A_FORMULA, 0); + if (z->type == A_SYMBOLIC) + z = make_unary(mpl, O_CVTNUM, z, A_NUMERIC, 0); + if (z->type == A_NUMERIC) + z = make_unary(mpl, O_CVTLFM, z, A_FORMULA, 0); + } + if (y->type == A_SYMBOLIC || z->type == A_SYMBOLIC) + { if (y->type == A_NUMERIC) + y = make_unary(mpl, O_CVTSYM, y, A_SYMBOLIC, 0); + if (z->type == A_NUMERIC) + z = make_unary(mpl, O_CVTSYM, z, A_SYMBOLIC, 0); + } + /* now both expressions must have identical types */ + if (y->type != z->type) + error(mpl, "expressions following then and else have incompati" + "ble types"); + /* and identical dimensions */ + if (y->dim != z->dim) + error(mpl, "expressions following then and else have different" + " dimensions %d and %d, respectively", y->dim, z->dim); +skip: /* generate pseudo-code to perform branching */ + code = make_ternary(mpl, O_FORK, x, y, z, y->type, y->dim); + return code; +} + +/*---------------------------------------------------------------------- +-- primary_expression - parse primary expression. +-- +-- This routine parses primary expression using the syntax: +-- +-- ::= +-- ::= Infinity +-- ::= +-- ::= +-- ::= +-- ::= [ ] +-- ::= +-- ::= [ ] +-- ::= +-- ::= [ ] +-- ::= ( ) +-- ::= ( ) +-- ::= +-- ::= { } +-- ::= +-- ::= +-- +-- For complete list of syntactic rules for see +-- comments to the corresponding parsing routines. */ + +CODE *primary_expression(MPL *mpl) +{ CODE *code; + if (mpl->token == T_NUMBER) + { /* parse numeric literal */ + code = numeric_literal(mpl); + } +#if 1 /* 21/VII-2006 */ + else if (mpl->token == T_INFINITY) + { /* parse "infinity" */ + OPERANDS arg; + arg.num = DBL_MAX; + code = make_code(mpl, O_NUMBER, &arg, A_NUMERIC, 0); + get_token(mpl /* Infinity */); + } +#endif + else if (mpl->token == T_STRING) + { /* parse string literal */ + code = string_literal(mpl); + } + else if (mpl->token == T_NAME) + { int next_token; + get_token(mpl /* */); + next_token = mpl->token; + unget_token(mpl); + /* check a token that follows */ + switch (next_token) + { case T_LBRACKET: + /* parse reference to subscripted object */ + code = object_reference(mpl); + break; + case T_LEFT: + /* parse reference to built-in function */ + code = function_reference(mpl); + break; + case T_LBRACE: + /* parse iterated expression */ + code = iterated_expression(mpl); + break; + default: + /* parse reference to unsubscripted object */ + code = object_reference(mpl); + break; + } + } + else if (mpl->token == T_LEFT) + { /* parse parenthesized expression */ + code = expression_list(mpl); + } + else if (mpl->token == T_LBRACE) + { /* parse set expression */ + code = set_expression(mpl); + } + else if (mpl->token == T_IF) + { /* parse conditional expression */ + code = branched_expression(mpl); + } + else if (is_reserved(mpl)) + { /* other reserved keywords cannot be used here */ + error(mpl, "invalid use of reserved keyword %s", mpl->image); + } + else + error(mpl, "syntax error in expression"); + return code; +} + +/*---------------------------------------------------------------------- +-- error_preceding - raise error if preceding operand has wrong type. +-- +-- This routine is called to raise error if operand that precedes some +-- infix operator has invalid type. */ + +void error_preceding(MPL *mpl, char *opstr) +{ error(mpl, "operand preceding %s has invalid type", opstr); + /* no return */ +} + +/*---------------------------------------------------------------------- +-- error_following - raise error if following operand has wrong type. +-- +-- This routine is called to raise error if operand that follows some +-- infix operator has invalid type. */ + +void error_following(MPL *mpl, char *opstr) +{ error(mpl, "operand following %s has invalid type", opstr); + /* no return */ +} + +/*---------------------------------------------------------------------- +-- error_dimension - raise error if operands have different dimension. +-- +-- This routine is called to raise error if two operands of some infix +-- operator have different dimension. */ + +void error_dimension(MPL *mpl, char *opstr, int dim1, int dim2) +{ error(mpl, "operands preceding and following %s have different di" + "mensions %d and %d, respectively", opstr, dim1, dim2); + /* no return */ +} + +/*---------------------------------------------------------------------- +-- expression_0 - parse expression of level 0. +-- +-- This routine parses expression of level 0 using the syntax: +-- +-- ::= */ + +CODE *expression_0(MPL *mpl) +{ CODE *code; + code = primary_expression(mpl); + return code; +} + +/*---------------------------------------------------------------------- +-- expression_1 - parse expression of level 1. +-- +-- This routine parses expression of level 1 using the syntax: +-- +-- ::= +-- ::= +-- ::= +-- ::= ^ | ** */ + +CODE *expression_1(MPL *mpl) +{ CODE *x, *y; + char opstr[8]; + x = expression_0(mpl); + if (mpl->token == T_POWER) + { strcpy(opstr, mpl->image); + xassert(strlen(opstr) < sizeof(opstr)); + if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (x->type != A_NUMERIC) + error_preceding(mpl, opstr); + get_token(mpl /* ^ | ** */); + if (mpl->token == T_PLUS || mpl->token == T_MINUS) + y = expression_2(mpl); + else + y = expression_1(mpl); + if (y->type == A_SYMBOLIC) + y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); + if (y->type != A_NUMERIC) + error_following(mpl, opstr); + x = make_binary(mpl, O_POWER, x, y, A_NUMERIC, 0); + } + return x; +} + +/*---------------------------------------------------------------------- +-- expression_2 - parse expression of level 2. +-- +-- This routine parses expression of level 2 using the syntax: +-- +-- ::= +-- ::= + +-- ::= - */ + +CODE *expression_2(MPL *mpl) +{ CODE *x; + if (mpl->token == T_PLUS) + { get_token(mpl /* + */); + x = expression_1(mpl); + if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) + error_following(mpl, "+"); + x = make_unary(mpl, O_PLUS, x, x->type, 0); + } + else if (mpl->token == T_MINUS) + { get_token(mpl /* - */); + x = expression_1(mpl); + if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) + error_following(mpl, "-"); + x = make_unary(mpl, O_MINUS, x, x->type, 0); + } + else + x = expression_1(mpl); + return x; +} + +/*---------------------------------------------------------------------- +-- expression_3 - parse expression of level 3. +-- +-- This routine parses expression of level 3 using the syntax: +-- +-- ::= +-- ::= * +-- ::= / +-- ::= div +-- ::= mod */ + +CODE *expression_3(MPL *mpl) +{ CODE *x, *y; + x = expression_2(mpl); + for (;;) + { if (mpl->token == T_ASTERISK) + { if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) + error_preceding(mpl, "*"); + get_token(mpl /* * */); + y = expression_2(mpl); + if (y->type == A_SYMBOLIC) + y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); + if (!(y->type == A_NUMERIC || y->type == A_FORMULA)) + error_following(mpl, "*"); + if (x->type == A_FORMULA && y->type == A_FORMULA) + error(mpl, "multiplication of linear forms not allowed"); + if (x->type == A_NUMERIC && y->type == A_NUMERIC) + x = make_binary(mpl, O_MUL, x, y, A_NUMERIC, 0); + else + x = make_binary(mpl, O_MUL, x, y, A_FORMULA, 0); + } + else if (mpl->token == T_SLASH) + { if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) + error_preceding(mpl, "/"); + get_token(mpl /* / */); + y = expression_2(mpl); + if (y->type == A_SYMBOLIC) + y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); + if (y->type != A_NUMERIC) + error_following(mpl, "/"); + if (x->type == A_NUMERIC) + x = make_binary(mpl, O_DIV, x, y, A_NUMERIC, 0); + else + x = make_binary(mpl, O_DIV, x, y, A_FORMULA, 0); + } + else if (mpl->token == T_DIV) + { if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (x->type != A_NUMERIC) + error_preceding(mpl, "div"); + get_token(mpl /* div */); + y = expression_2(mpl); + if (y->type == A_SYMBOLIC) + y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); + if (y->type != A_NUMERIC) + error_following(mpl, "div"); + x = make_binary(mpl, O_IDIV, x, y, A_NUMERIC, 0); + } + else if (mpl->token == T_MOD) + { if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (x->type != A_NUMERIC) + error_preceding(mpl, "mod"); + get_token(mpl /* mod */); + y = expression_2(mpl); + if (y->type == A_SYMBOLIC) + y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); + if (y->type != A_NUMERIC) + error_following(mpl, "mod"); + x = make_binary(mpl, O_MOD, x, y, A_NUMERIC, 0); + } + else + break; + } + return x; +} + +/*---------------------------------------------------------------------- +-- expression_4 - parse expression of level 4. +-- +-- This routine parses expression of level 4 using the syntax: +-- +-- ::= +-- ::= + +-- ::= - +-- ::= less */ + +CODE *expression_4(MPL *mpl) +{ CODE *x, *y; + x = expression_3(mpl); + for (;;) + { if (mpl->token == T_PLUS) + { if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) + error_preceding(mpl, "+"); + get_token(mpl /* + */); + y = expression_3(mpl); + if (y->type == A_SYMBOLIC) + y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); + if (!(y->type == A_NUMERIC || y->type == A_FORMULA)) + error_following(mpl, "+"); + if (x->type == A_NUMERIC && y->type == A_FORMULA) + x = make_unary(mpl, O_CVTLFM, x, A_FORMULA, 0); + if (x->type == A_FORMULA && y->type == A_NUMERIC) + y = make_unary(mpl, O_CVTLFM, y, A_FORMULA, 0); + x = make_binary(mpl, O_ADD, x, y, x->type, 0); + } + else if (mpl->token == T_MINUS) + { if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) + error_preceding(mpl, "-"); + get_token(mpl /* - */); + y = expression_3(mpl); + if (y->type == A_SYMBOLIC) + y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); + if (!(y->type == A_NUMERIC || y->type == A_FORMULA)) + error_following(mpl, "-"); + if (x->type == A_NUMERIC && y->type == A_FORMULA) + x = make_unary(mpl, O_CVTLFM, x, A_FORMULA, 0); + if (x->type == A_FORMULA && y->type == A_NUMERIC) + y = make_unary(mpl, O_CVTLFM, y, A_FORMULA, 0); + x = make_binary(mpl, O_SUB, x, y, x->type, 0); + } + else if (mpl->token == T_LESS) + { if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (x->type != A_NUMERIC) + error_preceding(mpl, "less"); + get_token(mpl /* less */); + y = expression_3(mpl); + if (y->type == A_SYMBOLIC) + y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); + if (y->type != A_NUMERIC) + error_following(mpl, "less"); + x = make_binary(mpl, O_LESS, x, y, A_NUMERIC, 0); + } + else + break; + } + return x; +} + +/*---------------------------------------------------------------------- +-- expression_5 - parse expression of level 5. +-- +-- This routine parses expression of level 5 using the syntax: +-- +-- ::= +-- ::= & */ + +CODE *expression_5(MPL *mpl) +{ CODE *x, *y; + x = expression_4(mpl); + for (;;) + { if (mpl->token == T_CONCAT) + { if (x->type == A_NUMERIC) + x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); + if (x->type != A_SYMBOLIC) + error_preceding(mpl, "&"); + get_token(mpl /* & */); + y = expression_4(mpl); + if (y->type == A_NUMERIC) + y = make_unary(mpl, O_CVTSYM, y, A_SYMBOLIC, 0); + if (y->type != A_SYMBOLIC) + error_following(mpl, "&"); + x = make_binary(mpl, O_CONCAT, x, y, A_SYMBOLIC, 0); + } + else + break; + } + return x; +} + +/*---------------------------------------------------------------------- +-- expression_6 - parse expression of level 6. +-- +-- This routine parses expression of level 6 using the syntax: +-- +-- ::= +-- ::= .. +-- ::= .. by +-- */ + +CODE *expression_6(MPL *mpl) +{ CODE *x, *y, *z; + x = expression_5(mpl); + if (mpl->token == T_DOTS) + { if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (x->type != A_NUMERIC) + error_preceding(mpl, ".."); + get_token(mpl /* .. */); + y = expression_5(mpl); + if (y->type == A_SYMBOLIC) + y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); + if (y->type != A_NUMERIC) + error_following(mpl, ".."); + if (mpl->token == T_BY) + { get_token(mpl /* by */); + z = expression_5(mpl); + if (z->type == A_SYMBOLIC) + z = make_unary(mpl, O_CVTNUM, z, A_NUMERIC, 0); + if (z->type != A_NUMERIC) + error_following(mpl, "by"); + } + else + z = NULL; + x = make_ternary(mpl, O_DOTS, x, y, z, A_ELEMSET, 1); + } + return x; +} + +/*---------------------------------------------------------------------- +-- expression_7 - parse expression of level 7. +-- +-- This routine parses expression of level 7 using the syntax: +-- +-- ::= +-- ::= cross */ + +CODE *expression_7(MPL *mpl) +{ CODE *x, *y; + x = expression_6(mpl); + for (;;) + { if (mpl->token == T_CROSS) + { if (x->type != A_ELEMSET) + error_preceding(mpl, "cross"); + get_token(mpl /* cross */); + y = expression_6(mpl); + if (y->type != A_ELEMSET) + error_following(mpl, "cross"); + x = make_binary(mpl, O_CROSS, x, y, A_ELEMSET, + x->dim + y->dim); + } + else + break; + } + return x; +} + +/*---------------------------------------------------------------------- +-- expression_8 - parse expression of level 8. +-- +-- This routine parses expression of level 8 using the syntax: +-- +-- ::= +-- ::= inter */ + +CODE *expression_8(MPL *mpl) +{ CODE *x, *y; + x = expression_7(mpl); + for (;;) + { if (mpl->token == T_INTER) + { if (x->type != A_ELEMSET) + error_preceding(mpl, "inter"); + get_token(mpl /* inter */); + y = expression_7(mpl); + if (y->type != A_ELEMSET) + error_following(mpl, "inter"); + if (x->dim != y->dim) + error_dimension(mpl, "inter", x->dim, y->dim); + x = make_binary(mpl, O_INTER, x, y, A_ELEMSET, x->dim); + } + else + break; + } + return x; +} + +/*---------------------------------------------------------------------- +-- expression_9 - parse expression of level 9. +-- +-- This routine parses expression of level 9 using the syntax: +-- +-- ::= +-- ::= union +-- ::= diff +-- ::= symdiff */ + +CODE *expression_9(MPL *mpl) +{ CODE *x, *y; + x = expression_8(mpl); + for (;;) + { if (mpl->token == T_UNION) + { if (x->type != A_ELEMSET) + error_preceding(mpl, "union"); + get_token(mpl /* union */); + y = expression_8(mpl); + if (y->type != A_ELEMSET) + error_following(mpl, "union"); + if (x->dim != y->dim) + error_dimension(mpl, "union", x->dim, y->dim); + x = make_binary(mpl, O_UNION, x, y, A_ELEMSET, x->dim); + } + else if (mpl->token == T_DIFF) + { if (x->type != A_ELEMSET) + error_preceding(mpl, "diff"); + get_token(mpl /* diff */); + y = expression_8(mpl); + if (y->type != A_ELEMSET) + error_following(mpl, "diff"); + if (x->dim != y->dim) + error_dimension(mpl, "diff", x->dim, y->dim); + x = make_binary(mpl, O_DIFF, x, y, A_ELEMSET, x->dim); + } + else if (mpl->token == T_SYMDIFF) + { if (x->type != A_ELEMSET) + error_preceding(mpl, "symdiff"); + get_token(mpl /* symdiff */); + y = expression_8(mpl); + if (y->type != A_ELEMSET) + error_following(mpl, "symdiff"); + if (x->dim != y->dim) + error_dimension(mpl, "symdiff", x->dim, y->dim); + x = make_binary(mpl, O_SYMDIFF, x, y, A_ELEMSET, x->dim); + } + else + break; + } + return x; +} + +/*---------------------------------------------------------------------- +-- expression_10 - parse expression of level 10. +-- +-- This routine parses expression of level 10 using the syntax: +-- +-- ::= +-- ::= +-- ::= < | <= | = | == | >= | > | <> | != | in | not in | ! in | +-- within | not within | ! within */ + +CODE *expression_10(MPL *mpl) +{ CODE *x, *y; + int op = -1; + char opstr[16]; + x = expression_9(mpl); + strcpy(opstr, ""); + switch (mpl->token) + { case T_LT: + op = O_LT; break; + case T_LE: + op = O_LE; break; + case T_EQ: + op = O_EQ; break; + case T_GE: + op = O_GE; break; + case T_GT: + op = O_GT; break; + case T_NE: + op = O_NE; break; + case T_IN: + op = O_IN; break; + case T_WITHIN: + op = O_WITHIN; break; + case T_NOT: + strcpy(opstr, mpl->image); + get_token(mpl /* not | ! */); + if (mpl->token == T_IN) + op = O_NOTIN; + else if (mpl->token == T_WITHIN) + op = O_NOTWITHIN; + else + error(mpl, "invalid use of %s", opstr); + strcat(opstr, " "); + break; + default: + goto done; + } + strcat(opstr, mpl->image); + xassert(strlen(opstr) < sizeof(opstr)); + switch (op) + { case O_EQ: + case O_NE: +#if 1 /* 02/VIII-2008 */ + case O_LT: + case O_LE: + case O_GT: + case O_GE: +#endif + if (!(x->type == A_NUMERIC || x->type == A_SYMBOLIC)) + error_preceding(mpl, opstr); + get_token(mpl /* */); + y = expression_9(mpl); + if (!(y->type == A_NUMERIC || y->type == A_SYMBOLIC)) + error_following(mpl, opstr); + if (x->type == A_NUMERIC && y->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); + if (x->type == A_SYMBOLIC && y->type == A_NUMERIC) + y = make_unary(mpl, O_CVTSYM, y, A_SYMBOLIC, 0); + x = make_binary(mpl, op, x, y, A_LOGICAL, 0); + break; +#if 0 /* 02/VIII-2008 */ + case O_LT: + case O_LE: + case O_GT: + case O_GE: + if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (x->type != A_NUMERIC) + error_preceding(mpl, opstr); + get_token(mpl /* */); + y = expression_9(mpl); + if (y->type == A_SYMBOLIC) + y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); + if (y->type != A_NUMERIC) + error_following(mpl, opstr); + x = make_binary(mpl, op, x, y, A_LOGICAL, 0); + break; +#endif + case O_IN: + case O_NOTIN: + if (x->type == A_NUMERIC) + x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); + if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTTUP, x, A_TUPLE, 1); + if (x->type != A_TUPLE) + error_preceding(mpl, opstr); + get_token(mpl /* */); + y = expression_9(mpl); + if (y->type != A_ELEMSET) + error_following(mpl, opstr); + if (x->dim != y->dim) + error_dimension(mpl, opstr, x->dim, y->dim); + x = make_binary(mpl, op, x, y, A_LOGICAL, 0); + break; + case O_WITHIN: + case O_NOTWITHIN: + if (x->type != A_ELEMSET) + error_preceding(mpl, opstr); + get_token(mpl /* */); + y = expression_9(mpl); + if (y->type != A_ELEMSET) + error_following(mpl, opstr); + if (x->dim != y->dim) + error_dimension(mpl, opstr, x->dim, y->dim); + x = make_binary(mpl, op, x, y, A_LOGICAL, 0); + break; + default: + xassert(op != op); + } +done: return x; +} + +/*---------------------------------------------------------------------- +-- expression_11 - parse expression of level 11. +-- +-- This routine parses expression of level 11 using the syntax: +-- +-- ::= +-- ::= not +-- ::= ! */ + +CODE *expression_11(MPL *mpl) +{ CODE *x; + char opstr[8]; + if (mpl->token == T_NOT) + { strcpy(opstr, mpl->image); + xassert(strlen(opstr) < sizeof(opstr)); + get_token(mpl /* not | ! */); + x = expression_10(mpl); + if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (x->type == A_NUMERIC) + x = make_unary(mpl, O_CVTLOG, x, A_LOGICAL, 0); + if (x->type != A_LOGICAL) + error_following(mpl, opstr); + x = make_unary(mpl, O_NOT, x, A_LOGICAL, 0); + } + else + x = expression_10(mpl); + return x; +} + +/*---------------------------------------------------------------------- +-- expression_12 - parse expression of level 12. +-- +-- This routine parses expression of level 12 using the syntax: +-- +-- ::= +-- ::= and +-- ::= && */ + +CODE *expression_12(MPL *mpl) +{ CODE *x, *y; + char opstr[8]; + x = expression_11(mpl); + for (;;) + { if (mpl->token == T_AND) + { strcpy(opstr, mpl->image); + xassert(strlen(opstr) < sizeof(opstr)); + if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (x->type == A_NUMERIC) + x = make_unary(mpl, O_CVTLOG, x, A_LOGICAL, 0); + if (x->type != A_LOGICAL) + error_preceding(mpl, opstr); + get_token(mpl /* and | && */); + y = expression_11(mpl); + if (y->type == A_SYMBOLIC) + y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); + if (y->type == A_NUMERIC) + y = make_unary(mpl, O_CVTLOG, y, A_LOGICAL, 0); + if (y->type != A_LOGICAL) + error_following(mpl, opstr); + x = make_binary(mpl, O_AND, x, y, A_LOGICAL, 0); + } + else + break; + } + return x; +} + +/*---------------------------------------------------------------------- +-- expression_13 - parse expression of level 13. +-- +-- This routine parses expression of level 13 using the syntax: +-- +-- ::= +-- ::= or +-- ::= || */ + +CODE *expression_13(MPL *mpl) +{ CODE *x, *y; + char opstr[8]; + x = expression_12(mpl); + for (;;) + { if (mpl->token == T_OR) + { strcpy(opstr, mpl->image); + xassert(strlen(opstr) < sizeof(opstr)); + if (x->type == A_SYMBOLIC) + x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); + if (x->type == A_NUMERIC) + x = make_unary(mpl, O_CVTLOG, x, A_LOGICAL, 0); + if (x->type != A_LOGICAL) + error_preceding(mpl, opstr); + get_token(mpl /* or | || */); + y = expression_12(mpl); + if (y->type == A_SYMBOLIC) + y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); + if (y->type == A_NUMERIC) + y = make_unary(mpl, O_CVTLOG, y, A_LOGICAL, 0); + if (y->type != A_LOGICAL) + error_following(mpl, opstr); + x = make_binary(mpl, O_OR, x, y, A_LOGICAL, 0); + } + else + break; + } + return x; +} + +/*---------------------------------------------------------------------- +-- set_statement - parse set statement. +-- +-- This routine parses set statement using the syntax: +-- +-- ::= set +-- ; +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= , dimen +-- ::= , within +-- ::= , := +-- ::= , default +-- +-- Commae in are optional and may be omitted anywhere. */ + +SET *set_statement(MPL *mpl) +{ SET *set; + int dimen_used = 0; + xassert(is_keyword(mpl, "set")); + get_token(mpl /* set */); + /* symbolic name must follow the keyword 'set' */ + if (mpl->token == T_NAME) + ; + else if (is_reserved(mpl)) + error(mpl, "invalid use of reserved keyword %s", mpl->image); + else + error(mpl, "symbolic name missing where expected"); + /* there must be no other object with the same name */ + if (avl_find_node(mpl->tree, mpl->image) != NULL) + error(mpl, "%s multiply declared", mpl->image); + /* create model set */ + set = alloc(SET); + set->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(set->name, mpl->image); + set->alias = NULL; + set->dim = 0; + set->domain = NULL; + set->dimen = 0; + set->within = NULL; + set->assign = NULL; + set->option = NULL; + set->gadget = NULL; + set->data = 0; + set->array = NULL; + get_token(mpl /* */); + /* parse optional alias */ + if (mpl->token == T_STRING) + { set->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(set->alias, mpl->image); + get_token(mpl /* */); + } + /* parse optional indexing expression */ + if (mpl->token == T_LBRACE) + { set->domain = indexing_expression(mpl); + set->dim = domain_arity(mpl, set->domain); + } + /* include the set name in the symbolic names table */ + { AVLNODE *node; + node = avl_insert_node(mpl->tree, set->name); + avl_set_node_type(node, A_SET); + avl_set_node_link(node, (void *)set); + } + /* parse the list of optional attributes */ + for (;;) + { if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else if (mpl->token == T_SEMICOLON) + break; + if (is_keyword(mpl, "dimen")) + { /* dimension of set members */ + int dimen; + get_token(mpl /* dimen */); + if (!(mpl->token == T_NUMBER && + 1.0 <= mpl->value && mpl->value <= 20.0 && + floor(mpl->value) == mpl->value)) + error(mpl, "dimension must be integer between 1 and 20"); + dimen = (int)(mpl->value + 0.5); + if (dimen_used) + error(mpl, "at most one dimension attribute allowed"); + if (set->dimen > 0) + error(mpl, "dimension %d conflicts with dimension %d alr" + "eady determined", dimen, set->dimen); + set->dimen = dimen; + dimen_used = 1; + get_token(mpl /* */); + } + else if (mpl->token == T_WITHIN || mpl->token == T_IN) + { /* restricting superset */ + WITHIN *within, *temp; + if (mpl->token == T_IN && !mpl->as_within) + { warning(mpl, "keyword in understood as within"); + mpl->as_within = 1; + } + get_token(mpl /* within */); + /* create new restricting superset list entry and append it + to the within-list */ + within = alloc(WITHIN); + within->code = NULL; + within->next = NULL; + if (set->within == NULL) + set->within = within; + else + { for (temp = set->within; temp->next != NULL; temp = + temp->next); + temp->next = within; + } + /* parse an expression that follows 'within' */ + within->code = expression_9(mpl); + if (within->code->type != A_ELEMSET) + error(mpl, "expression following within has invalid type" + ); + xassert(within->code->dim > 0); + /* check/set dimension of set members */ + if (set->dimen == 0) set->dimen = within->code->dim; + if (set->dimen != within->code->dim) + error(mpl, "set expression following within must have di" + "mension %d rather than %d", + set->dimen, within->code->dim); + } + else if (mpl->token == T_ASSIGN) + { /* assignment expression */ + if (!(set->assign == NULL && set->option == NULL && + set->gadget == NULL)) +err: error(mpl, "at most one := or default/data allowed"); + get_token(mpl /* := */); + /* parse an expression that follows ':=' */ + set->assign = expression_9(mpl); + if (set->assign->type != A_ELEMSET) + error(mpl, "expression following := has invalid type"); + xassert(set->assign->dim > 0); + /* check/set dimension of set members */ + if (set->dimen == 0) set->dimen = set->assign->dim; + if (set->dimen != set->assign->dim) + error(mpl, "set expression following := must have dimens" + "ion %d rather than %d", + set->dimen, set->assign->dim); + } + else if (is_keyword(mpl, "default")) + { /* expression for default value */ + if (!(set->assign == NULL && set->option == NULL)) goto err; + get_token(mpl /* := */); + /* parse an expression that follows 'default' */ + set->option = expression_9(mpl); + if (set->option->type != A_ELEMSET) + error(mpl, "expression following default has invalid typ" + "e"); + xassert(set->option->dim > 0); + /* check/set dimension of set members */ + if (set->dimen == 0) set->dimen = set->option->dim; + if (set->dimen != set->option->dim) + error(mpl, "set expression following default must have d" + "imension %d rather than %d", + set->dimen, set->option->dim); + } +#if 1 /* 12/XII-2008 */ + else if (is_keyword(mpl, "data")) + { /* gadget to initialize the set by data from plain set */ + GADGET *gadget; + AVLNODE *node; + int i, k, fff[20]; + if (!(set->assign == NULL && set->gadget == NULL)) goto err; + get_token(mpl /* data */); + set->gadget = gadget = alloc(GADGET); + /* set name must follow the keyword 'data' */ + if (mpl->token == T_NAME) + ; + else if (is_reserved(mpl)) + error(mpl, "invalid use of reserved keyword %s", + mpl->image); + else + error(mpl, "set name missing where expected"); + /* find the set in the symbolic name table */ + node = avl_find_node(mpl->tree, mpl->image); + if (node == NULL) + error(mpl, "%s not defined", mpl->image); + if (avl_get_node_type(node) != A_SET) +err1: error(mpl, "%s not a plain set", mpl->image); + gadget->set = avl_get_node_link(node); + if (gadget->set->dim != 0) goto err1; + if (gadget->set == set) + error(mpl, "set cannot be initialized by itself"); + /* check and set dimensions */ + if (set->dim >= gadget->set->dimen) +err2: error(mpl, "dimension of %s too small", mpl->image); + if (set->dimen == 0) + set->dimen = gadget->set->dimen - set->dim; + if (set->dim + set->dimen > gadget->set->dimen) + goto err2; + else if (set->dim + set->dimen < gadget->set->dimen) + error(mpl, "dimension of %s too big", mpl->image); + get_token(mpl /* set name */); + /* left parenthesis must follow the set name */ + if (mpl->token == T_LEFT) + get_token(mpl /* ( */); + else + error(mpl, "left parenthesis missing where expected"); + /* parse permutation of component numbers */ + for (k = 0; k < gadget->set->dimen; k++) fff[k] = 0; + k = 0; + for (;;) + { if (mpl->token != T_NUMBER) + error(mpl, "component number missing where expected"); + if (str2int(mpl->image, &i) != 0) +err3: error(mpl, "component number must be integer between " + "1 and %d", gadget->set->dimen); + if (!(1 <= i && i <= gadget->set->dimen)) goto err3; + if (fff[i-1] != 0) + error(mpl, "component %d multiply specified", i); + gadget->ind[k++] = i, fff[i-1] = 1; + xassert(k <= gadget->set->dimen); + get_token(mpl /* number */); + if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else if (mpl->token == T_RIGHT) + break; + else + error(mpl, "syntax error in data attribute"); + } + if (k < gadget->set->dimen) + error(mpl, "there are must be %d components rather than " + "%d", gadget->set->dimen, k); + get_token(mpl /* ) */); + } +#endif + else + error(mpl, "syntax error in set statement"); + } + /* close the domain scope */ + if (set->domain != NULL) close_scope(mpl, set->domain); + /* if dimension of set members is still unknown, set it to 1 */ + if (set->dimen == 0) set->dimen = 1; + /* the set statement has been completely parsed */ + xassert(mpl->token == T_SEMICOLON); + get_token(mpl /* ; */); + return set; +} + +/*---------------------------------------------------------------------- +-- parameter_statement - parse parameter statement. +-- +-- This routine parses parameter statement using the syntax: +-- +-- ::= param +-- ; +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= , integer +-- ::= , binary +-- ::= , symbolic +-- ::= , +-- ::= , in +-- ::= , := +-- ::= , default +-- ::= < | <= | = | == | >= | > | <> | != +-- +-- Commae in are optional and may be omitted anywhere. */ + +PARAMETER *parameter_statement(MPL *mpl) +{ PARAMETER *par; + int integer_used = 0, binary_used = 0, symbolic_used = 0; + xassert(is_keyword(mpl, "param")); + get_token(mpl /* param */); + /* symbolic name must follow the keyword 'param' */ + if (mpl->token == T_NAME) + ; + else if (is_reserved(mpl)) + error(mpl, "invalid use of reserved keyword %s", mpl->image); + else + error(mpl, "symbolic name missing where expected"); + /* there must be no other object with the same name */ + if (avl_find_node(mpl->tree, mpl->image) != NULL) + error(mpl, "%s multiply declared", mpl->image); + /* create model parameter */ + par = alloc(PARAMETER); + par->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(par->name, mpl->image); + par->alias = NULL; + par->dim = 0; + par->domain = NULL; + par->type = A_NUMERIC; + par->cond = NULL; + par->in = NULL; + par->assign = NULL; + par->option = NULL; + par->data = 0; + par->defval = NULL; + par->array = NULL; + get_token(mpl /* */); + /* parse optional alias */ + if (mpl->token == T_STRING) + { par->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(par->alias, mpl->image); + get_token(mpl /* */); + } + /* parse optional indexing expression */ + if (mpl->token == T_LBRACE) + { par->domain = indexing_expression(mpl); + par->dim = domain_arity(mpl, par->domain); + } + /* include the parameter name in the symbolic names table */ + { AVLNODE *node; + node = avl_insert_node(mpl->tree, par->name); + avl_set_node_type(node, A_PARAMETER); + avl_set_node_link(node, (void *)par); + } + /* parse the list of optional attributes */ + for (;;) + { if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else if (mpl->token == T_SEMICOLON) + break; + if (is_keyword(mpl, "integer")) + { if (integer_used) + error(mpl, "at most one integer allowed"); + if (par->type == A_SYMBOLIC) + error(mpl, "symbolic parameter cannot be integer"); + if (par->type != A_BINARY) par->type = A_INTEGER; + integer_used = 1; + get_token(mpl /* integer */); + } + else if (is_keyword(mpl, "binary")) +bin: { if (binary_used) + error(mpl, "at most one binary allowed"); + if (par->type == A_SYMBOLIC) + error(mpl, "symbolic parameter cannot be binary"); + par->type = A_BINARY; + binary_used = 1; + get_token(mpl /* binary */); + } + else if (is_keyword(mpl, "logical")) + { if (!mpl->as_binary) + { warning(mpl, "keyword logical understood as binary"); + mpl->as_binary = 1; + } + goto bin; + } + else if (is_keyword(mpl, "symbolic")) + { if (symbolic_used) + error(mpl, "at most one symbolic allowed"); + if (par->type != A_NUMERIC) + error(mpl, "integer or binary parameter cannot be symbol" + "ic"); + /* the parameter may be referenced from expressions given + in the same parameter declaration, so its type must be + completed before parsing that expressions */ + if (!(par->cond == NULL && par->in == NULL && + par->assign == NULL && par->option == NULL)) + error(mpl, "keyword symbolic must precede any other para" + "meter attributes"); + par->type = A_SYMBOLIC; + symbolic_used = 1; + get_token(mpl /* symbolic */); + } + else if (mpl->token == T_LT || mpl->token == T_LE || + mpl->token == T_EQ || mpl->token == T_GE || + mpl->token == T_GT || mpl->token == T_NE) + { /* restricting condition */ + CONDITION *cond, *temp; + char opstr[8]; + /* create new restricting condition list entry and append + it to the conditions list */ + cond = alloc(CONDITION); + switch (mpl->token) + { case T_LT: + cond->rho = O_LT, strcpy(opstr, mpl->image); break; + case T_LE: + cond->rho = O_LE, strcpy(opstr, mpl->image); break; + case T_EQ: + cond->rho = O_EQ, strcpy(opstr, mpl->image); break; + case T_GE: + cond->rho = O_GE, strcpy(opstr, mpl->image); break; + case T_GT: + cond->rho = O_GT, strcpy(opstr, mpl->image); break; + case T_NE: + cond->rho = O_NE, strcpy(opstr, mpl->image); break; + default: + xassert(mpl->token != mpl->token); + } + xassert(strlen(opstr) < sizeof(opstr)); + cond->code = NULL; + cond->next = NULL; + if (par->cond == NULL) + par->cond = cond; + else + { for (temp = par->cond; temp->next != NULL; temp = + temp->next); + temp->next = cond; + } +#if 0 /* 13/VIII-2008 */ + if (par->type == A_SYMBOLIC && + !(cond->rho == O_EQ || cond->rho == O_NE)) + error(mpl, "inequality restriction not allowed"); +#endif + get_token(mpl /* rho */); + /* parse an expression that follows relational operator */ + cond->code = expression_5(mpl); + if (!(cond->code->type == A_NUMERIC || + cond->code->type == A_SYMBOLIC)) + error(mpl, "expression following %s has invalid type", + opstr); + xassert(cond->code->dim == 0); + /* convert to the parameter type, if necessary */ + if (par->type != A_SYMBOLIC && cond->code->type == + A_SYMBOLIC) + cond->code = make_unary(mpl, O_CVTNUM, cond->code, + A_NUMERIC, 0); + if (par->type == A_SYMBOLIC && cond->code->type != + A_SYMBOLIC) + cond->code = make_unary(mpl, O_CVTSYM, cond->code, + A_SYMBOLIC, 0); + } + else if (mpl->token == T_IN || mpl->token == T_WITHIN) + { /* restricting superset */ + WITHIN *in, *temp; + if (mpl->token == T_WITHIN && !mpl->as_in) + { warning(mpl, "keyword within understood as in"); + mpl->as_in = 1; + } + get_token(mpl /* in */); + /* create new restricting superset list entry and append it + to the in-list */ + in = alloc(WITHIN); + in->code = NULL; + in->next = NULL; + if (par->in == NULL) + par->in = in; + else + { for (temp = par->in; temp->next != NULL; temp = + temp->next); + temp->next = in; + } + /* parse an expression that follows 'in' */ + in->code = expression_9(mpl); + if (in->code->type != A_ELEMSET) + error(mpl, "expression following in has invalid type"); + xassert(in->code->dim > 0); + if (in->code->dim != 1) + error(mpl, "set expression following in must have dimens" + "ion 1 rather than %d", in->code->dim); + } + else if (mpl->token == T_ASSIGN) + { /* assignment expression */ + if (!(par->assign == NULL && par->option == NULL)) +err: error(mpl, "at most one := or default allowed"); + get_token(mpl /* := */); + /* parse an expression that follows ':=' */ + par->assign = expression_5(mpl); + /* the expression must be of numeric/symbolic type */ + if (!(par->assign->type == A_NUMERIC || + par->assign->type == A_SYMBOLIC)) + error(mpl, "expression following := has invalid type"); + xassert(par->assign->dim == 0); + /* convert to the parameter type, if necessary */ + if (par->type != A_SYMBOLIC && par->assign->type == + A_SYMBOLIC) + par->assign = make_unary(mpl, O_CVTNUM, par->assign, + A_NUMERIC, 0); + if (par->type == A_SYMBOLIC && par->assign->type != + A_SYMBOLIC) + par->assign = make_unary(mpl, O_CVTSYM, par->assign, + A_SYMBOLIC, 0); + } + else if (is_keyword(mpl, "default")) + { /* expression for default value */ + if (!(par->assign == NULL && par->option == NULL)) goto err; + get_token(mpl /* default */); + /* parse an expression that follows 'default' */ + par->option = expression_5(mpl); + if (!(par->option->type == A_NUMERIC || + par->option->type == A_SYMBOLIC)) + error(mpl, "expression following default has invalid typ" + "e"); + xassert(par->option->dim == 0); + /* convert to the parameter type, if necessary */ + if (par->type != A_SYMBOLIC && par->option->type == + A_SYMBOLIC) + par->option = make_unary(mpl, O_CVTNUM, par->option, + A_NUMERIC, 0); + if (par->type == A_SYMBOLIC && par->option->type != + A_SYMBOLIC) + par->option = make_unary(mpl, O_CVTSYM, par->option, + A_SYMBOLIC, 0); + } + else + error(mpl, "syntax error in parameter statement"); + } + /* close the domain scope */ + if (par->domain != NULL) close_scope(mpl, par->domain); + /* the parameter statement has been completely parsed */ + xassert(mpl->token == T_SEMICOLON); + get_token(mpl /* ; */); + return par; +} + +/*---------------------------------------------------------------------- +-- variable_statement - parse variable statement. +-- +-- This routine parses variable statement using the syntax: +-- +-- ::= var +-- ; +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= , integer +-- ::= , binary +-- ::= , +-- ::= >= | <= | = | == +-- +-- Commae in are optional and may be omitted anywhere. */ + +VARIABLE *variable_statement(MPL *mpl) +{ VARIABLE *var; + int integer_used = 0, binary_used = 0; + xassert(is_keyword(mpl, "var")); + if (mpl->flag_s) + error(mpl, "variable statement must precede solve statement"); + get_token(mpl /* var */); + /* symbolic name must follow the keyword 'var' */ + if (mpl->token == T_NAME) + ; + else if (is_reserved(mpl)) + error(mpl, "invalid use of reserved keyword %s", mpl->image); + else + error(mpl, "symbolic name missing where expected"); + /* there must be no other object with the same name */ + if (avl_find_node(mpl->tree, mpl->image) != NULL) + error(mpl, "%s multiply declared", mpl->image); + /* create model variable */ + var = alloc(VARIABLE); + var->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(var->name, mpl->image); + var->alias = NULL; + var->dim = 0; + var->domain = NULL; + var->type = A_NUMERIC; + var->lbnd = NULL; + var->ubnd = NULL; + var->array = NULL; + get_token(mpl /* */); + /* parse optional alias */ + if (mpl->token == T_STRING) + { var->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(var->alias, mpl->image); + get_token(mpl /* */); + } + /* parse optional indexing expression */ + if (mpl->token == T_LBRACE) + { var->domain = indexing_expression(mpl); + var->dim = domain_arity(mpl, var->domain); + } + /* include the variable name in the symbolic names table */ + { AVLNODE *node; + node = avl_insert_node(mpl->tree, var->name); + avl_set_node_type(node, A_VARIABLE); + avl_set_node_link(node, (void *)var); + } + /* parse the list of optional attributes */ + for (;;) + { if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else if (mpl->token == T_SEMICOLON) + break; + if (is_keyword(mpl, "integer")) + { if (integer_used) + error(mpl, "at most one integer allowed"); + if (var->type != A_BINARY) var->type = A_INTEGER; + integer_used = 1; + get_token(mpl /* integer */); + } + else if (is_keyword(mpl, "binary")) +bin: { if (binary_used) + error(mpl, "at most one binary allowed"); + var->type = A_BINARY; + binary_used = 1; + get_token(mpl /* binary */); + } + else if (is_keyword(mpl, "logical")) + { if (!mpl->as_binary) + { warning(mpl, "keyword logical understood as binary"); + mpl->as_binary = 1; + } + goto bin; + } + else if (is_keyword(mpl, "symbolic")) + error(mpl, "variable cannot be symbolic"); + else if (mpl->token == T_GE) + { /* lower bound */ + if (var->lbnd != NULL) + { if (var->lbnd == var->ubnd) + error(mpl, "both fixed value and lower bound not allo" + "wed"); + else + error(mpl, "at most one lower bound allowed"); + } + get_token(mpl /* >= */); + /* parse an expression that specifies the lower bound */ + var->lbnd = expression_5(mpl); + if (var->lbnd->type == A_SYMBOLIC) + var->lbnd = make_unary(mpl, O_CVTNUM, var->lbnd, + A_NUMERIC, 0); + if (var->lbnd->type != A_NUMERIC) + error(mpl, "expression following >= has invalid type"); + xassert(var->lbnd->dim == 0); + } + else if (mpl->token == T_LE) + { /* upper bound */ + if (var->ubnd != NULL) + { if (var->ubnd == var->lbnd) + error(mpl, "both fixed value and upper bound not allo" + "wed"); + else + error(mpl, "at most one upper bound allowed"); + } + get_token(mpl /* <= */); + /* parse an expression that specifies the upper bound */ + var->ubnd = expression_5(mpl); + if (var->ubnd->type == A_SYMBOLIC) + var->ubnd = make_unary(mpl, O_CVTNUM, var->ubnd, + A_NUMERIC, 0); + if (var->ubnd->type != A_NUMERIC) + error(mpl, "expression following <= has invalid type"); + xassert(var->ubnd->dim == 0); + } + else if (mpl->token == T_EQ) + { /* fixed value */ + char opstr[8]; + if (!(var->lbnd == NULL && var->ubnd == NULL)) + { if (var->lbnd == var->ubnd) + error(mpl, "at most one fixed value allowed"); + else if (var->lbnd != NULL) + error(mpl, "both lower bound and fixed value not allo" + "wed"); + else + error(mpl, "both upper bound and fixed value not allo" + "wed"); + } + strcpy(opstr, mpl->image); + xassert(strlen(opstr) < sizeof(opstr)); + get_token(mpl /* = | == */); + /* parse an expression that specifies the fixed value */ + var->lbnd = expression_5(mpl); + if (var->lbnd->type == A_SYMBOLIC) + var->lbnd = make_unary(mpl, O_CVTNUM, var->lbnd, + A_NUMERIC, 0); + if (var->lbnd->type != A_NUMERIC) + error(mpl, "expression following %s has invalid type", + opstr); + xassert(var->lbnd->dim == 0); + /* indicate that the variable is fixed, not bounded */ + var->ubnd = var->lbnd; + } + else if (mpl->token == T_LT || mpl->token == T_GT || + mpl->token == T_NE) + error(mpl, "strict bound not allowed"); + else + error(mpl, "syntax error in variable statement"); + } + /* close the domain scope */ + if (var->domain != NULL) close_scope(mpl, var->domain); + /* the variable statement has been completely parsed */ + xassert(mpl->token == T_SEMICOLON); + get_token(mpl /* ; */); + return var; +} + +/*---------------------------------------------------------------------- +-- constraint_statement - parse constraint statement. +-- +-- This routine parses constraint statement using the syntax: +-- +-- ::= +-- : ; +-- ::= +-- ::= subject to +-- ::= subj to +-- ::= s.t. +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= , >= +-- ::= , <= +-- ::= , = +-- ::= , <= , <= +-- ::= , >= , >= +-- ::= +-- +-- Commae in are optional and may be omitted anywhere. */ + +CONSTRAINT *constraint_statement(MPL *mpl) +{ CONSTRAINT *con; + CODE *first, *second, *third; + int rho; + char opstr[8]; + if (mpl->flag_s) + error(mpl, "constraint statement must precede solve statement") + ; + if (is_keyword(mpl, "subject")) + { get_token(mpl /* subject */); + if (!is_keyword(mpl, "to")) + error(mpl, "keyword subject to incomplete"); + get_token(mpl /* to */); + } + else if (is_keyword(mpl, "subj")) + { get_token(mpl /* subj */); + if (!is_keyword(mpl, "to")) + error(mpl, "keyword subj to incomplete"); + get_token(mpl /* to */); + } + else if (mpl->token == T_SPTP) + get_token(mpl /* s.t. */); + /* the current token must be symbolic name of constraint */ + if (mpl->token == T_NAME) + ; + else if (is_reserved(mpl)) + error(mpl, "invalid use of reserved keyword %s", mpl->image); + else + error(mpl, "symbolic name missing where expected"); + /* there must be no other object with the same name */ + if (avl_find_node(mpl->tree, mpl->image) != NULL) + error(mpl, "%s multiply declared", mpl->image); + /* create model constraint */ + con = alloc(CONSTRAINT); + con->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(con->name, mpl->image); + con->alias = NULL; + con->dim = 0; + con->domain = NULL; + con->type = A_CONSTRAINT; + con->code = NULL; + con->lbnd = NULL; + con->ubnd = NULL; + con->array = NULL; + get_token(mpl /* */); + /* parse optional alias */ + if (mpl->token == T_STRING) + { con->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(con->alias, mpl->image); + get_token(mpl /* */); + } + /* parse optional indexing expression */ + if (mpl->token == T_LBRACE) + { con->domain = indexing_expression(mpl); + con->dim = domain_arity(mpl, con->domain); + } + /* include the constraint name in the symbolic names table */ + { AVLNODE *node; + node = avl_insert_node(mpl->tree, con->name); + avl_set_node_type(node, A_CONSTRAINT); + avl_set_node_link(node, (void *)con); + } + /* the colon must precede the first expression */ + if (mpl->token != T_COLON) + error(mpl, "colon missing where expected"); + get_token(mpl /* : */); + /* parse the first expression */ + first = expression_5(mpl); + if (first->type == A_SYMBOLIC) + first = make_unary(mpl, O_CVTNUM, first, A_NUMERIC, 0); + if (!(first->type == A_NUMERIC || first->type == A_FORMULA)) + error(mpl, "expression following colon has invalid type"); + xassert(first->dim == 0); + /* relational operator must follow the first expression */ + if (mpl->token == T_COMMA) get_token(mpl /* , */); + switch (mpl->token) + { case T_LE: + case T_GE: + case T_EQ: + break; + case T_LT: + case T_GT: + case T_NE: + error(mpl, "strict inequality not allowed"); + case T_SEMICOLON: + error(mpl, "constraint must be equality or inequality"); + default: + goto err; + } + rho = mpl->token; + strcpy(opstr, mpl->image); + xassert(strlen(opstr) < sizeof(opstr)); + get_token(mpl /* rho */); + /* parse the second expression */ + second = expression_5(mpl); + if (second->type == A_SYMBOLIC) + second = make_unary(mpl, O_CVTNUM, second, A_NUMERIC, 0); + if (!(second->type == A_NUMERIC || second->type == A_FORMULA)) + error(mpl, "expression following %s has invalid type", opstr); + xassert(second->dim == 0); + /* check a token that follow the second expression */ + if (mpl->token == T_COMMA) + { get_token(mpl /* , */); + if (mpl->token == T_SEMICOLON) goto err; + } + if (mpl->token == T_LT || mpl->token == T_LE || + mpl->token == T_EQ || mpl->token == T_GE || + mpl->token == T_GT || mpl->token == T_NE) + { /* it is another relational operator, therefore the constraint + is double inequality */ + if (rho == T_EQ || mpl->token != rho) + error(mpl, "double inequality must be ... <= ... <= ... or " + "... >= ... >= ..."); + /* the first expression cannot be linear form */ + if (first->type == A_FORMULA) + error(mpl, "leftmost expression in double inequality cannot" + " be linear form"); + get_token(mpl /* rho */); + /* parse the third expression */ + third = expression_5(mpl); + if (third->type == A_SYMBOLIC) + third = make_unary(mpl, O_CVTNUM, second, A_NUMERIC, 0); + if (!(third->type == A_NUMERIC || third->type == A_FORMULA)) + error(mpl, "rightmost expression in double inequality const" + "raint has invalid type"); + xassert(third->dim == 0); + /* the third expression also cannot be linear form */ + if (third->type == A_FORMULA) + error(mpl, "rightmost expression in double inequality canno" + "t be linear form"); + } + else + { /* the constraint is equality or single inequality */ + third = NULL; + } + /* close the domain scope */ + if (con->domain != NULL) close_scope(mpl, con->domain); + /* convert all expressions to linear form, if necessary */ + if (first->type != A_FORMULA) + first = make_unary(mpl, O_CVTLFM, first, A_FORMULA, 0); + if (second->type != A_FORMULA) + second = make_unary(mpl, O_CVTLFM, second, A_FORMULA, 0); + if (third != NULL) + third = make_unary(mpl, O_CVTLFM, third, A_FORMULA, 0); + /* arrange expressions in the constraint */ + if (third == NULL) + { /* the constraint is equality or single inequality */ + switch (rho) + { case T_LE: + /* first <= second */ + con->code = first; + con->lbnd = NULL; + con->ubnd = second; + break; + case T_GE: + /* first >= second */ + con->code = first; + con->lbnd = second; + con->ubnd = NULL; + break; + case T_EQ: + /* first = second */ + con->code = first; + con->lbnd = second; + con->ubnd = second; + break; + default: + xassert(rho != rho); + } + } + else + { /* the constraint is double inequality */ + switch (rho) + { case T_LE: + /* first <= second <= third */ + con->code = second; + con->lbnd = first; + con->ubnd = third; + break; + case T_GE: + /* first >= second >= third */ + con->code = second; + con->lbnd = third; + con->ubnd = first; + break; + default: + xassert(rho != rho); + } + } + /* the constraint statement has been completely parsed */ + if (mpl->token != T_SEMICOLON) +err: error(mpl, "syntax error in constraint statement"); + get_token(mpl /* ; */); + return con; +} + +/*---------------------------------------------------------------------- +-- objective_statement - parse objective statement. +-- +-- This routine parses objective statement using the syntax: +-- +-- ::= : +-- ; +-- ::= minimize +-- ::= maximize +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= */ + +CONSTRAINT *objective_statement(MPL *mpl) +{ CONSTRAINT *obj; + int type; + if (is_keyword(mpl, "minimize")) + type = A_MINIMIZE; + else if (is_keyword(mpl, "maximize")) + type = A_MAXIMIZE; + else + xassert(mpl != mpl); + if (mpl->flag_s) + error(mpl, "objective statement must precede solve statement"); + get_token(mpl /* minimize | maximize */); + /* symbolic name must follow the verb 'minimize' or 'maximize' */ + if (mpl->token == T_NAME) + ; + else if (is_reserved(mpl)) + error(mpl, "invalid use of reserved keyword %s", mpl->image); + else + error(mpl, "symbolic name missing where expected"); + /* there must be no other object with the same name */ + if (avl_find_node(mpl->tree, mpl->image) != NULL) + error(mpl, "%s multiply declared", mpl->image); + /* create model objective */ + obj = alloc(CONSTRAINT); + obj->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(obj->name, mpl->image); + obj->alias = NULL; + obj->dim = 0; + obj->domain = NULL; + obj->type = type; + obj->code = NULL; + obj->lbnd = NULL; + obj->ubnd = NULL; + obj->array = NULL; + get_token(mpl /* */); + /* parse optional alias */ + if (mpl->token == T_STRING) + { obj->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(obj->alias, mpl->image); + get_token(mpl /* */); + } + /* parse optional indexing expression */ + if (mpl->token == T_LBRACE) + { obj->domain = indexing_expression(mpl); + obj->dim = domain_arity(mpl, obj->domain); + } + /* include the constraint name in the symbolic names table */ + { AVLNODE *node; + node = avl_insert_node(mpl->tree, obj->name); + avl_set_node_type(node, A_CONSTRAINT); + avl_set_node_link(node, (void *)obj); + } + /* the colon must precede the objective expression */ + if (mpl->token != T_COLON) + error(mpl, "colon missing where expected"); + get_token(mpl /* : */); + /* parse the objective expression */ + obj->code = expression_5(mpl); + if (obj->code->type == A_SYMBOLIC) + obj->code = make_unary(mpl, O_CVTNUM, obj->code, A_NUMERIC, 0); + if (obj->code->type == A_NUMERIC) + obj->code = make_unary(mpl, O_CVTLFM, obj->code, A_FORMULA, 0); + if (obj->code->type != A_FORMULA) + error(mpl, "expression following colon has invalid type"); + xassert(obj->code->dim == 0); + /* close the domain scope */ + if (obj->domain != NULL) close_scope(mpl, obj->domain); + /* the objective statement has been completely parsed */ + if (mpl->token != T_SEMICOLON) + error(mpl, "syntax error in objective statement"); + get_token(mpl /* ; */); + return obj; +} + +#if 1 /* 11/II-2008 */ +/*********************************************************************** +* table_statement - parse table statement +* +* This routine parses table statement using the syntax: +* +* ::= +*
::= +* +* ::= +* table
IN : +* [ ] , ; +* ::= +* ::= +* ::= +* ::= +* ::= , +* ::= +* ::= <- +* ::= +* ::= , +* ::= +* ::= , +* ::= +* ::= ~ +* +* ::= +* table
OUT : +* ; +* ::= +* ::= +* ::= , +* ::= +* ::= ~ */ + +TABLE *table_statement(MPL *mpl) +{ TABLE *tab; + TABARG *last_arg, *arg; + TABFLD *last_fld, *fld; + TABIN *last_in, *in; + TABOUT *last_out, *out; + AVLNODE *node; + int nflds; + char name[MAX_LENGTH+1]; + xassert(is_keyword(mpl, "table")); + get_token(mpl /* solve */); + /* symbolic name must follow the keyword table */ + if (mpl->token == T_NAME) + ; + else if (is_reserved(mpl)) + error(mpl, "invalid use of reserved keyword %s", mpl->image); + else + error(mpl, "symbolic name missing where expected"); + /* there must be no other object with the same name */ + if (avl_find_node(mpl->tree, mpl->image) != NULL) + error(mpl, "%s multiply declared", mpl->image); + /* create data table */ + tab = alloc(TABLE); + tab->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(tab->name, mpl->image); + get_token(mpl /* */); + /* parse optional alias */ + if (mpl->token == T_STRING) + { tab->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(tab->alias, mpl->image); + get_token(mpl /* */); + } + else + tab->alias = NULL; + /* parse optional indexing expression */ + if (mpl->token == T_LBRACE) + { /* this is output table */ + tab->type = A_OUTPUT; + tab->u.out.domain = indexing_expression(mpl); + if (!is_keyword(mpl, "OUT")) + error(mpl, "keyword OUT missing where expected"); + get_token(mpl /* OUT */); + } + else + { /* this is input table */ + tab->type = A_INPUT; + if (!is_keyword(mpl, "IN")) + error(mpl, "keyword IN missing where expected"); + get_token(mpl /* IN */); + } + /* parse argument list */ + tab->arg = last_arg = NULL; + for (;;) + { /* create argument list entry */ + arg = alloc(TABARG); + /* parse argument expression */ + if (mpl->token == T_COMMA || mpl->token == T_COLON || + mpl->token == T_SEMICOLON) + error(mpl, "argument expression missing where expected"); + arg->code = expression_5(mpl); + /* convert the result to symbolic type, if necessary */ + if (arg->code->type == A_NUMERIC) + arg->code = + make_unary(mpl, O_CVTSYM, arg->code, A_SYMBOLIC, 0); + /* check that now the result is of symbolic type */ + if (arg->code->type != A_SYMBOLIC) + error(mpl, "argument expression has invalid type"); + /* add the entry to the end of the list */ + arg->next = NULL; + if (last_arg == NULL) + tab->arg = arg; + else + last_arg->next = arg; + last_arg = arg; + /* argument expression has been parsed */ + if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else if (mpl->token == T_COLON || mpl->token == T_SEMICOLON) + break; + } + xassert(tab->arg != NULL); + /* argument list must end with colon */ + if (mpl->token == T_COLON) + get_token(mpl /* : */); + else + error(mpl, "colon missing where expected"); + /* parse specific part of the table statement */ + switch (tab->type) + { case A_INPUT: goto input_table; + case A_OUTPUT: goto output_table; + default: xassert(tab != tab); + } +input_table: + /* parse optional set name */ + if (mpl->token == T_NAME) + { node = avl_find_node(mpl->tree, mpl->image); + if (node == NULL) + error(mpl, "%s not defined", mpl->image); + if (avl_get_node_type(node) != A_SET) + error(mpl, "%s not a set", mpl->image); + tab->u.in.set = (SET *)avl_get_node_link(node); + if (tab->u.in.set->assign != NULL) + error(mpl, "%s needs no data", mpl->image); + if (tab->u.in.set->dim != 0) + error(mpl, "%s must be a simple set", mpl->image); + get_token(mpl /* */); + if (mpl->token == T_INPUT) + get_token(mpl /* <- */); + else + error(mpl, "delimiter <- missing where expected"); + } + else if (is_reserved(mpl)) + error(mpl, "invalid use of reserved keyword %s", mpl->image); + else + tab->u.in.set = NULL; + /* parse field list */ + tab->u.in.fld = last_fld = NULL; + nflds = 0; + if (mpl->token == T_LBRACKET) + get_token(mpl /* [ */); + else + error(mpl, "field list missing where expected"); + for (;;) + { /* create field list entry */ + fld = alloc(TABFLD); + /* parse field name */ + if (mpl->token == T_NAME) + ; + else if (is_reserved(mpl)) + error(mpl, + "invalid use of reserved keyword %s", mpl->image); + else + error(mpl, "field name missing where expected"); + fld->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); + strcpy(fld->name, mpl->image); + get_token(mpl /* */); + /* add the entry to the end of the list */ + fld->next = NULL; + if (last_fld == NULL) + tab->u.in.fld = fld; + else + last_fld->next = fld; + last_fld = fld; + nflds++; + /* field name has been parsed */ + if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else if (mpl->token == T_RBRACKET) + break; + else + error(mpl, "syntax error in field list"); + } + /* check that the set dimen is equal to the number of fields */ + if (tab->u.in.set != NULL && tab->u.in.set->dimen != nflds) + error(mpl, "there must be %d field%s rather than %d", + tab->u.in.set->dimen, tab->u.in.set->dimen == 1 ? "" : "s", + nflds); + get_token(mpl /* ] */); + /* parse optional input list */ + tab->u.in.list = last_in = NULL; + while (mpl->token == T_COMMA) + { get_token(mpl /* , */); + /* create input list entry */ + in = alloc(TABIN); + /* parse parameter name */ + if (mpl->token == T_NAME) + ; + else if (is_reserved(mpl)) + error(mpl, + "invalid use of reserved keyword %s", mpl->image); + else + error(mpl, "parameter name missing where expected"); + node = avl_find_node(mpl->tree, mpl->image); + if (node == NULL) + error(mpl, "%s not defined", mpl->image); + if (avl_get_node_type(node) != A_PARAMETER) + error(mpl, "%s not a parameter", mpl->image); + in->par = (PARAMETER *)avl_get_node_link(node); + if (in->par->dim != nflds) + error(mpl, "%s must have %d subscript%s rather than %d", + mpl->image, nflds, nflds == 1 ? "" : "s", in->par->dim); + if (in->par->assign != NULL) + error(mpl, "%s needs no data", mpl->image); + get_token(mpl /* */); + /* parse optional field name */ + if (mpl->token == T_TILDE) + { get_token(mpl /* ~ */); + /* parse field name */ + if (mpl->token == T_NAME) + ; + else if (is_reserved(mpl)) + error(mpl, + "invalid use of reserved keyword %s", mpl->image); + else + error(mpl, "field name missing where expected"); + xassert(strlen(mpl->image) < sizeof(name)); + strcpy(name, mpl->image); + get_token(mpl /* */); + } + else + { /* field name is the same as the parameter name */ + xassert(strlen(in->par->name) < sizeof(name)); + strcpy(name, in->par->name); + } + /* assign field name */ + in->name = dmp_get_atomv(mpl->pool, strlen(name)+1); + strcpy(in->name, name); + /* add the entry to the end of the list */ + in->next = NULL; + if (last_in == NULL) + tab->u.in.list = in; + else + last_in->next = in; + last_in = in; + } + goto end_of_table; +output_table: + /* parse output list */ + tab->u.out.list = last_out = NULL; + for (;;) + { /* create output list entry */ + out = alloc(TABOUT); + /* parse expression */ + if (mpl->token == T_COMMA || mpl->token == T_SEMICOLON) + error(mpl, "expression missing where expected"); + if (mpl->token == T_NAME) + { xassert(strlen(mpl->image) < sizeof(name)); + strcpy(name, mpl->image); + } + else + name[0] = '\0'; + out->code = expression_5(mpl); + /* parse optional field name */ + if (mpl->token == T_TILDE) + { get_token(mpl /* ~ */); + /* parse field name */ + if (mpl->token == T_NAME) + ; + else if (is_reserved(mpl)) + error(mpl, + "invalid use of reserved keyword %s", mpl->image); + else + error(mpl, "field name missing where expected"); + xassert(strlen(mpl->image) < sizeof(name)); + strcpy(name, mpl->image); + get_token(mpl /* */); + } + /* assign field name */ + if (name[0] == '\0') + error(mpl, "field name required"); + out->name = dmp_get_atomv(mpl->pool, strlen(name)+1); + strcpy(out->name, name); + /* add the entry to the end of the list */ + out->next = NULL; + if (last_out == NULL) + tab->u.out.list = out; + else + last_out->next = out; + last_out = out; + /* output item has been parsed */ + if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else if (mpl->token == T_SEMICOLON) + break; + else + error(mpl, "syntax error in output list"); + } + /* close the domain scope */ + close_scope(mpl,tab->u.out.domain); +end_of_table: + /* the table statement must end with semicolon */ + if (mpl->token != T_SEMICOLON) + error(mpl, "syntax error in table statement"); + get_token(mpl /* ; */); + return tab; +} +#endif + +/*---------------------------------------------------------------------- +-- solve_statement - parse solve statement. +-- +-- This routine parses solve statement using the syntax: +-- +-- ::= solve ; +-- +-- The solve statement can be used at most once. */ + +void *solve_statement(MPL *mpl) +{ xassert(is_keyword(mpl, "solve")); + if (mpl->flag_s) + error(mpl, "at most one solve statement allowed"); + mpl->flag_s = 1; + get_token(mpl /* solve */); + /* semicolon must follow solve statement */ + if (mpl->token != T_SEMICOLON) + error(mpl, "syntax error in solve statement"); + get_token(mpl /* ; */); + return NULL; +} + +/*---------------------------------------------------------------------- +-- check_statement - parse check statement. +-- +-- This routine parses check statement using the syntax: +-- +-- ::= check : ; +-- ::= +-- ::= +-- +-- If is omitted, colon following it may also be omitted. */ + +CHECK *check_statement(MPL *mpl) +{ CHECK *chk; + xassert(is_keyword(mpl, "check")); + /* create check descriptor */ + chk = alloc(CHECK); + chk->domain = NULL; + chk->code = NULL; + get_token(mpl /* check */); + /* parse optional indexing expression */ + if (mpl->token == T_LBRACE) + { chk->domain = indexing_expression(mpl); +#if 0 + if (mpl->token != T_COLON) + error(mpl, "colon missing where expected"); +#endif + } + /* skip optional colon */ + if (mpl->token == T_COLON) get_token(mpl /* : */); + /* parse logical expression */ + chk->code = expression_13(mpl); + if (chk->code->type != A_LOGICAL) + error(mpl, "expression has invalid type"); + xassert(chk->code->dim == 0); + /* close the domain scope */ + if (chk->domain != NULL) close_scope(mpl, chk->domain); + /* the check statement has been completely parsed */ + if (mpl->token != T_SEMICOLON) + error(mpl, "syntax error in check statement"); + get_token(mpl /* ; */); + return chk; +} + +#if 1 /* 15/V-2010 */ +/*---------------------------------------------------------------------- +-- display_statement - parse display statement. +-- +-- This routine parses display statement using the syntax: +-- +-- ::= display : ; +-- ::= display ; +-- ::= +-- ::= +-- ::= +-- ::= , +-- ::= +-- ::= +-- ::= [ ] +-- ::= +-- ::= [ ] +-- ::= +-- ::= [ ] +-- ::= +-- ::= [ ] +-- ::= */ + +DISPLAY *display_statement(MPL *mpl) +{ DISPLAY *dpy; + DISPLAY1 *entry, *last_entry; + xassert(is_keyword(mpl, "display")); + /* create display descriptor */ + dpy = alloc(DISPLAY); + dpy->domain = NULL; + dpy->list = last_entry = NULL; + get_token(mpl /* display */); + /* parse optional indexing expression */ + if (mpl->token == T_LBRACE) + dpy->domain = indexing_expression(mpl); + /* skip optional colon */ + if (mpl->token == T_COLON) get_token(mpl /* : */); + /* parse display list */ + for (;;) + { /* create new display entry */ + entry = alloc(DISPLAY1); + entry->type = 0; + entry->next = NULL; + /* and append it to the display list */ + if (dpy->list == NULL) + dpy->list = entry; + else + last_entry->next = entry; + last_entry = entry; + /* parse display entry */ + if (mpl->token == T_NAME) + { AVLNODE *node; + int next_token; + get_token(mpl /* */); + next_token = mpl->token; + unget_token(mpl); + if (!(next_token == T_COMMA || next_token == T_SEMICOLON)) + { /* symbolic name begins expression */ + goto expr; + } + /* display entry is dummy index or model object */ + node = avl_find_node(mpl->tree, mpl->image); + if (node == NULL) + error(mpl, "%s not defined", mpl->image); + entry->type = avl_get_node_type(node); + switch (avl_get_node_type(node)) + { case A_INDEX: + entry->u.slot = + (DOMAIN_SLOT *)avl_get_node_link(node); + break; + case A_SET: + entry->u.set = (SET *)avl_get_node_link(node); + break; + case A_PARAMETER: + entry->u.par = (PARAMETER *)avl_get_node_link(node); + break; + case A_VARIABLE: + entry->u.var = (VARIABLE *)avl_get_node_link(node); + if (!mpl->flag_s) + error(mpl, "invalid reference to variable %s above" + " solve statement", entry->u.var->name); + break; + case A_CONSTRAINT: + entry->u.con = (CONSTRAINT *)avl_get_node_link(node); + if (!mpl->flag_s) + error(mpl, "invalid reference to %s %s above solve" + " statement", + entry->u.con->type == A_CONSTRAINT ? + "constraint" : "objective", entry->u.con->name); + break; + default: + xassert(node != node); + } + get_token(mpl /* */); + } + else +expr: { /* display entry is expression */ + entry->type = A_EXPRESSION; + entry->u.code = expression_13(mpl); + } + /* check a token that follows the entry parsed */ + if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else + break; + } + /* close the domain scope */ + if (dpy->domain != NULL) close_scope(mpl, dpy->domain); + /* the display statement has been completely parsed */ + if (mpl->token != T_SEMICOLON) + error(mpl, "syntax error in display statement"); + get_token(mpl /* ; */); + return dpy; +} +#endif + +/*---------------------------------------------------------------------- +-- printf_statement - parse printf statement. +-- +-- This routine parses print statement using the syntax: +-- +-- ::= ; +-- ::= > ; +-- ::= >> ; +-- ::= printf : +-- ::= printf +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= , +-- ::= +-- ::= */ + +PRINTF *printf_statement(MPL *mpl) +{ PRINTF *prt; + PRINTF1 *entry, *last_entry; + xassert(is_keyword(mpl, "printf")); + /* create printf descriptor */ + prt = alloc(PRINTF); + prt->domain = NULL; + prt->fmt = NULL; + prt->list = last_entry = NULL; + get_token(mpl /* printf */); + /* parse optional indexing expression */ + if (mpl->token == T_LBRACE) + { prt->domain = indexing_expression(mpl); +#if 0 + if (mpl->token != T_COLON) + error(mpl, "colon missing where expected"); +#endif + } + /* skip optional colon */ + if (mpl->token == T_COLON) get_token(mpl /* : */); + /* parse expression for format string */ + prt->fmt = expression_5(mpl); + /* convert it to symbolic type, if necessary */ + if (prt->fmt->type == A_NUMERIC) + prt->fmt = make_unary(mpl, O_CVTSYM, prt->fmt, A_SYMBOLIC, 0); + /* check that now the expression is of symbolic type */ + if (prt->fmt->type != A_SYMBOLIC) + error(mpl, "format expression has invalid type"); + /* parse printf list */ + while (mpl->token == T_COMMA) + { get_token(mpl /* , */); + /* create new printf entry */ + entry = alloc(PRINTF1); + entry->code = NULL; + entry->next = NULL; + /* and append it to the printf list */ + if (prt->list == NULL) + prt->list = entry; + else + last_entry->next = entry; + last_entry = entry; + /* parse printf entry */ + entry->code = expression_9(mpl); + if (!(entry->code->type == A_NUMERIC || + entry->code->type == A_SYMBOLIC || + entry->code->type == A_LOGICAL)) + error(mpl, "only numeric, symbolic, or logical expression a" + "llowed"); + } + /* close the domain scope */ + if (prt->domain != NULL) close_scope(mpl, prt->domain); +#if 1 /* 14/VII-2006 */ + /* parse optional redirection */ + prt->fname = NULL, prt->app = 0; + if (mpl->token == T_GT || mpl->token == T_APPEND) + { prt->app = (mpl->token == T_APPEND); + get_token(mpl /* > or >> */); + /* parse expression for file name string */ + prt->fname = expression_5(mpl); + /* convert it to symbolic type, if necessary */ + if (prt->fname->type == A_NUMERIC) + prt->fname = make_unary(mpl, O_CVTSYM, prt->fname, + A_SYMBOLIC, 0); + /* check that now the expression is of symbolic type */ + if (prt->fname->type != A_SYMBOLIC) + error(mpl, "file name expression has invalid type"); + } +#endif + /* the printf statement has been completely parsed */ + if (mpl->token != T_SEMICOLON) + error(mpl, "syntax error in printf statement"); + get_token(mpl /* ; */); + return prt; +} + +/*---------------------------------------------------------------------- +-- for_statement - parse for statement. +-- +-- This routine parses for statement using the syntax: +-- +-- ::= for +-- ::= for { } +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= */ + +FOR *for_statement(MPL *mpl) +{ FOR *fur; + STATEMENT *stmt, *last_stmt; + xassert(is_keyword(mpl, "for")); + /* create for descriptor */ + fur = alloc(FOR); + fur->domain = NULL; + fur->list = last_stmt = NULL; + get_token(mpl /* for */); + /* parse indexing expression */ + if (mpl->token != T_LBRACE) + error(mpl, "indexing expression missing where expected"); + fur->domain = indexing_expression(mpl); + /* skip optional colon */ + if (mpl->token == T_COLON) get_token(mpl /* : */); + /* parse for statement body */ + if (mpl->token != T_LBRACE) + { /* parse simple statement */ + fur->list = simple_statement(mpl, 1); + } + else + { /* parse compound statement */ + get_token(mpl /* { */); + while (mpl->token != T_RBRACE) + { /* parse statement */ + stmt = simple_statement(mpl, 1); + /* and append it to the end of the statement list */ + if (last_stmt == NULL) + fur->list = stmt; + else + last_stmt->next = stmt; + last_stmt = stmt; + } + get_token(mpl /* } */); + } + /* close the domain scope */ + xassert(fur->domain != NULL); + close_scope(mpl, fur->domain); + /* the for statement has been completely parsed */ + return fur; +} + +/*---------------------------------------------------------------------- +-- end_statement - parse end statement. +-- +-- This routine parses end statement using the syntax: +-- +-- ::= end ; */ + +void end_statement(MPL *mpl) +{ if (!mpl->flag_d && is_keyword(mpl, "end") || + mpl->flag_d && is_literal(mpl, "end")) + { get_token(mpl /* end */); + if (mpl->token == T_SEMICOLON) + get_token(mpl /* ; */); + else + warning(mpl, "no semicolon following end statement; missing" + " semicolon inserted"); + } + else + warning(mpl, "unexpected end of file; missing end statement in" + "serted"); + if (mpl->token != T_EOF) + warning(mpl, "some text detected beyond end statement; text ig" + "nored"); + return; +} + +/*---------------------------------------------------------------------- +-- simple_statement - parse simple statement. +-- +-- This routine parses simple statement using the syntax: +-- +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= +-- ::= +-- +-- If the flag spec is set, some statements cannot be used. */ + +STATEMENT *simple_statement(MPL *mpl, int spec) +{ STATEMENT *stmt; + stmt = alloc(STATEMENT); + stmt->line = mpl->line; + stmt->next = NULL; + if (is_keyword(mpl, "set")) + { if (spec) + error(mpl, "set statement not allowed here"); + stmt->type = A_SET; + stmt->u.set = set_statement(mpl); + } + else if (is_keyword(mpl, "param")) + { if (spec) + error(mpl, "parameter statement not allowed here"); + stmt->type = A_PARAMETER; + stmt->u.par = parameter_statement(mpl); + } + else if (is_keyword(mpl, "var")) + { if (spec) + error(mpl, "variable statement not allowed here"); + stmt->type = A_VARIABLE; + stmt->u.var = variable_statement(mpl); + } + else if (is_keyword(mpl, "subject") || + is_keyword(mpl, "subj") || + mpl->token == T_SPTP) + { if (spec) + error(mpl, "constraint statement not allowed here"); + stmt->type = A_CONSTRAINT; + stmt->u.con = constraint_statement(mpl); + } + else if (is_keyword(mpl, "minimize") || + is_keyword(mpl, "maximize")) + { if (spec) + error(mpl, "objective statement not allowed here"); + stmt->type = A_CONSTRAINT; + stmt->u.con = objective_statement(mpl); + } +#if 1 /* 11/II-2008 */ + else if (is_keyword(mpl, "table")) + { if (spec) + error(mpl, "table statement not allowed here"); + stmt->type = A_TABLE; + stmt->u.tab = table_statement(mpl); + } +#endif + else if (is_keyword(mpl, "solve")) + { if (spec) + error(mpl, "solve statement not allowed here"); + stmt->type = A_SOLVE; + stmt->u.slv = solve_statement(mpl); + } + else if (is_keyword(mpl, "check")) + { stmt->type = A_CHECK; + stmt->u.chk = check_statement(mpl); + } + else if (is_keyword(mpl, "display")) + { stmt->type = A_DISPLAY; + stmt->u.dpy = display_statement(mpl); + } + else if (is_keyword(mpl, "printf")) + { stmt->type = A_PRINTF; + stmt->u.prt = printf_statement(mpl); + } + else if (is_keyword(mpl, "for")) + { stmt->type = A_FOR; + stmt->u.fur = for_statement(mpl); + } + else if (mpl->token == T_NAME) + { if (spec) + error(mpl, "constraint statement not allowed here"); + stmt->type = A_CONSTRAINT; + stmt->u.con = constraint_statement(mpl); + } + else if (is_reserved(mpl)) + error(mpl, "invalid use of reserved keyword %s", mpl->image); + else + error(mpl, "syntax error in model section"); + return stmt; +} + +/*---------------------------------------------------------------------- +-- model_section - parse model section. +-- +-- This routine parses model section using the syntax: +-- +-- ::= +-- ::= +-- +-- Parsing model section is terminated by either the keyword 'data', or +-- the keyword 'end', or the end of file. */ + +void model_section(MPL *mpl) +{ STATEMENT *stmt, *last_stmt; + xassert(mpl->model == NULL); + last_stmt = NULL; + while (!(mpl->token == T_EOF || is_keyword(mpl, "data") || + is_keyword(mpl, "end"))) + { /* parse statement */ + stmt = simple_statement(mpl, 0); + /* and append it to the end of the statement list */ + if (last_stmt == NULL) + mpl->model = stmt; + else + last_stmt->next = stmt; + last_stmt = stmt; + } + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpmpl02.c b/resources/3rdparty/glpk-4.57/src/glpmpl02.c new file mode 100644 index 000000000..277593981 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpmpl02.c @@ -0,0 +1,1203 @@ +/* glpmpl02.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "glpmpl.h" + +/**********************************************************************/ +/* * * PROCESSING DATA SECTION * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- create_slice - create slice. +-- +-- This routine creates a slice, which initially has no components. */ + +SLICE *create_slice(MPL *mpl) +{ SLICE *slice; + xassert(mpl == mpl); + slice = NULL; + return slice; +} + +/*---------------------------------------------------------------------- +-- expand_slice - append new component to slice. +-- +-- This routine expands slice appending to it either a given symbol or +-- null component, which becomes the last component of the slice. */ + +SLICE *expand_slice +( MPL *mpl, + SLICE *slice, /* destroyed */ + SYMBOL *sym /* destroyed */ +) +{ SLICE *tail, *temp; + /* create a new component */ + tail = dmp_get_atom(mpl->tuples, sizeof(SLICE)); + tail->sym = sym; + tail->next = NULL; + /* and append it to the component list */ + if (slice == NULL) + slice = tail; + else + { for (temp = slice; temp->next != NULL; temp = temp->next); + temp->next = tail; + } + return slice; +} + +/*---------------------------------------------------------------------- +-- slice_dimen - determine dimension of slice. +-- +-- This routine returns dimension of slice, which is number of all its +-- components including null ones. */ + +int slice_dimen +( MPL *mpl, + SLICE *slice /* not changed */ +) +{ SLICE *temp; + int dim; + xassert(mpl == mpl); + dim = 0; + for (temp = slice; temp != NULL; temp = temp->next) dim++; + return dim; +} + +/*---------------------------------------------------------------------- +-- slice_arity - determine arity of slice. +-- +-- This routine returns arity of slice, i.e. number of null components +-- (indicated by asterisks) in the slice. */ + +int slice_arity +( MPL *mpl, + SLICE *slice /* not changed */ +) +{ SLICE *temp; + int arity; + xassert(mpl == mpl); + arity = 0; + for (temp = slice; temp != NULL; temp = temp->next) + if (temp->sym == NULL) arity++; + return arity; +} + +/*---------------------------------------------------------------------- +-- fake_slice - create fake slice of all asterisks. +-- +-- This routine creates a fake slice of given dimension, which contains +-- asterisks in all components. Zero dimension is allowed. */ + +SLICE *fake_slice(MPL *mpl, int dim) +{ SLICE *slice; + slice = create_slice(mpl); + while (dim-- > 0) slice = expand_slice(mpl, slice, NULL); + return slice; +} + +/*---------------------------------------------------------------------- +-- delete_slice - delete slice. +-- +-- This routine deletes specified slice. */ + +void delete_slice +( MPL *mpl, + SLICE *slice /* destroyed */ +) +{ SLICE *temp; + while (slice != NULL) + { temp = slice; + slice = temp->next; + if (temp->sym != NULL) delete_symbol(mpl, temp->sym); +xassert(sizeof(SLICE) == sizeof(TUPLE)); + dmp_free_atom(mpl->tuples, temp, sizeof(TUPLE)); + } + return; +} + +/*---------------------------------------------------------------------- +-- is_number - check if current token is number. +-- +-- If the current token is a number, this routine returns non-zero. +-- Otherwise zero is returned. */ + +int is_number(MPL *mpl) +{ return + mpl->token == T_NUMBER; +} + +/*---------------------------------------------------------------------- +-- is_symbol - check if current token is symbol. +-- +-- If the current token is suitable to be a symbol, the routine returns +-- non-zero. Otherwise zero is returned. */ + +int is_symbol(MPL *mpl) +{ return + mpl->token == T_NUMBER || + mpl->token == T_SYMBOL || + mpl->token == T_STRING; +} + +/*---------------------------------------------------------------------- +-- is_literal - check if current token is given symbolic literal. +-- +-- If the current token is given symbolic literal, this routine returns +-- non-zero. Otherwise zero is returned. +-- +-- This routine is used on processing the data section in the same way +-- as the routine is_keyword on processing the model section. */ + +int is_literal(MPL *mpl, char *literal) +{ return + is_symbol(mpl) && strcmp(mpl->image, literal) == 0; +} + +/*---------------------------------------------------------------------- +-- read_number - read number. +-- +-- This routine reads the current token, which must be a number, and +-- returns its numeric value. */ + +double read_number(MPL *mpl) +{ double num; + xassert(is_number(mpl)); + num = mpl->value; + get_token(mpl /* */); + return num; +} + +/*---------------------------------------------------------------------- +-- read_symbol - read symbol. +-- +-- This routine reads the current token, which must be a symbol, and +-- returns its symbolic value. */ + +SYMBOL *read_symbol(MPL *mpl) +{ SYMBOL *sym; + xassert(is_symbol(mpl)); + if (is_number(mpl)) + sym = create_symbol_num(mpl, mpl->value); + else + sym = create_symbol_str(mpl, create_string(mpl, mpl->image)); + get_token(mpl /* */); + return sym; +} + +/*---------------------------------------------------------------------- +-- read_slice - read slice. +-- +-- This routine reads slice using the syntax: +-- +-- ::= [ ] +-- ::= ( ) +-- ::= +-- ::= , +-- ::= +-- ::= * +-- +-- The bracketed form of slice is used for members of multi-dimensional +-- objects while the parenthesized form is used for elemental sets. */ + +SLICE *read_slice +( MPL *mpl, + char *name, /* not changed */ + int dim +) +{ SLICE *slice; + int close; + xassert(name != NULL); + switch (mpl->token) + { case T_LBRACKET: + close = T_RBRACKET; + break; + case T_LEFT: + xassert(dim > 0); + close = T_RIGHT; + break; + default: + xassert(mpl != mpl); + } + if (dim == 0) + error(mpl, "%s cannot be subscripted", name); + get_token(mpl /* ( | [ */); + /* read slice components */ + slice = create_slice(mpl); + for (;;) + { /* the current token must be a symbol or asterisk */ + if (is_symbol(mpl)) + slice = expand_slice(mpl, slice, read_symbol(mpl)); + else if (mpl->token == T_ASTERISK) + { slice = expand_slice(mpl, slice, NULL); + get_token(mpl /* * */); + } + else + error(mpl, "number, symbol, or asterisk missing where expec" + "ted"); + /* check a token that follows the symbol */ + if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else if (mpl->token == close) + break; + else + error(mpl, "syntax error in slice"); + } + /* number of slice components must be the same as the appropriate + dimension */ + if (slice_dimen(mpl, slice) != dim) + { switch (close) + { case T_RBRACKET: + error(mpl, "%s must have %d subscript%s, not %d", name, + dim, dim == 1 ? "" : "s", slice_dimen(mpl, slice)); + break; + case T_RIGHT: + error(mpl, "%s has dimension %d, not %d", name, dim, + slice_dimen(mpl, slice)); + break; + default: + xassert(close != close); + } + } + get_token(mpl /* ) | ] */); + return slice; +} + +/*---------------------------------------------------------------------- +-- select_set - select set to saturate it with elemental sets. +-- +-- This routine selects set to saturate it with elemental sets provided +-- in the data section. */ + +SET *select_set +( MPL *mpl, + char *name /* not changed */ +) +{ SET *set; + AVLNODE *node; + xassert(name != NULL); + node = avl_find_node(mpl->tree, name); + if (node == NULL || avl_get_node_type(node) != A_SET) + error(mpl, "%s not a set", name); + set = (SET *)avl_get_node_link(node); + if (set->assign != NULL || set->gadget != NULL) + error(mpl, "%s needs no data", name); + set->data = 1; + return set; +} + +/*---------------------------------------------------------------------- +-- simple_format - read set data block in simple format. +-- +-- This routine reads set data block using the syntax: +-- +-- ::= , , ... , +-- +-- where are used to construct a complete n-tuple, which is +-- included in elemental set assigned to the set member. Commae between +-- symbols are optional and may be omitted anywhere. +-- +-- Number of components in the slice must be the same as dimension of +-- n-tuples in elemental sets assigned to the set members. To construct +-- complete n-tuple the routine replaces null positions in the slice by +-- corresponding . +-- +-- If the slice contains at least one null position, the current token +-- must be symbol. Otherwise, the routine reads no symbols to construct +-- the n-tuple, so the current token is not checked. */ + +void simple_format +( MPL *mpl, + SET *set, /* not changed */ + MEMBER *memb, /* modified */ + SLICE *slice /* not changed */ +) +{ TUPLE *tuple; + SLICE *temp; + SYMBOL *sym, *with = NULL; + xassert(set != NULL); + xassert(memb != NULL); + xassert(slice != NULL); + xassert(set->dimen == slice_dimen(mpl, slice)); + xassert(memb->value.set->dim == set->dimen); + if (slice_arity(mpl, slice) > 0) xassert(is_symbol(mpl)); + /* read symbols and construct complete n-tuple */ + tuple = create_tuple(mpl); + for (temp = slice; temp != NULL; temp = temp->next) + { if (temp->sym == NULL) + { /* substitution is needed; read symbol */ + if (!is_symbol(mpl)) + { int lack = slice_arity(mpl, temp); + /* with cannot be null due to assertion above */ + xassert(with != NULL); + if (lack == 1) + error(mpl, "one item missing in data group beginning " + "with %s", format_symbol(mpl, with)); + else + error(mpl, "%d items missing in data group beginning " + "with %s", lack, format_symbol(mpl, with)); + } + sym = read_symbol(mpl); + if (with == NULL) with = sym; + } + else + { /* copy symbol from the slice */ + sym = copy_symbol(mpl, temp->sym); + } + /* append the symbol to the n-tuple */ + tuple = expand_tuple(mpl, tuple, sym); + /* skip optional comma *between* */ + if (temp->next != NULL && mpl->token == T_COMMA) + get_token(mpl /* , */); + } + /* add constructed n-tuple to elemental set */ + check_then_add(mpl, memb->value.set, tuple); + return; +} + +/*---------------------------------------------------------------------- +-- matrix_format - read set data block in matrix format. +-- +-- This routine reads set data block using the syntax: +-- +-- ::= ... := +-- +/- +/- ... +/- +-- +/- +/- ... +/- +-- . . . . . . . . . . . +-- +/- +/- ... +/- +-- +-- where are symbols that denote rows of the matrix, +-- are symbols that denote columns of the matrix, "+" and "-" indicate +-- whether corresponding n-tuple needs to be included in the elemental +-- set or not, respectively. +-- +-- Number of the slice components must be the same as dimension of the +-- elemental set. The slice must have two null positions. To construct +-- complete n-tuple for particular element of the matrix the routine +-- replaces first null position of the slice by the corresponding +-- (or , if the flag tr is on) and second null position by the +-- corresponding (or by , if the flag tr is on). */ + +void matrix_format +( MPL *mpl, + SET *set, /* not changed */ + MEMBER *memb, /* modified */ + SLICE *slice, /* not changed */ + int tr +) +{ SLICE *list, *col, *temp; + TUPLE *tuple; + SYMBOL *row; + xassert(set != NULL); + xassert(memb != NULL); + xassert(slice != NULL); + xassert(set->dimen == slice_dimen(mpl, slice)); + xassert(memb->value.set->dim == set->dimen); + xassert(slice_arity(mpl, slice) == 2); + /* read the matrix heading that contains column symbols (there + may be no columns at all) */ + list = create_slice(mpl); + while (mpl->token != T_ASSIGN) + { /* read column symbol and append it to the column list */ + if (!is_symbol(mpl)) + error(mpl, "number, symbol, or := missing where expected"); + list = expand_slice(mpl, list, read_symbol(mpl)); + } + get_token(mpl /* := */); + /* read zero or more rows that contain matrix data */ + while (is_symbol(mpl)) + { /* read row symbol (if the matrix has no columns, row symbols + are just ignored) */ + row = read_symbol(mpl); + /* read the matrix row accordingly to the column list */ + for (col = list; col != NULL; col = col->next) + { int which = 0; + /* check indicator */ + if (is_literal(mpl, "+")) + ; + else if (is_literal(mpl, "-")) + { get_token(mpl /* - */); + continue; + } + else + { int lack = slice_dimen(mpl, col); + if (lack == 1) + error(mpl, "one item missing in data group beginning " + "with %s", format_symbol(mpl, row)); + else + error(mpl, "%d items missing in data group beginning " + "with %s", lack, format_symbol(mpl, row)); + } + /* construct complete n-tuple */ + tuple = create_tuple(mpl); + for (temp = slice; temp != NULL; temp = temp->next) + { if (temp->sym == NULL) + { /* substitution is needed */ + switch (++which) + { case 1: + /* substitute in the first null position */ + tuple = expand_tuple(mpl, tuple, + copy_symbol(mpl, tr ? col->sym : row)); + break; + case 2: + /* substitute in the second null position */ + tuple = expand_tuple(mpl, tuple, + copy_symbol(mpl, tr ? row : col->sym)); + break; + default: + xassert(which != which); + } + } + else + { /* copy symbol from the slice */ + tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, + temp->sym)); + } + } + xassert(which == 2); + /* add constructed n-tuple to elemental set */ + check_then_add(mpl, memb->value.set, tuple); + get_token(mpl /* + */); + } + /* delete the row symbol */ + delete_symbol(mpl, row); + } + /* delete the column list */ + delete_slice(mpl, list); + return; +} + +/*---------------------------------------------------------------------- +-- set_data - read set data. +-- +-- This routine reads set data using the syntax: +-- +-- ::= set ; +-- ::= set [ ] ; +-- ::= +-- ::= +-- ::= , := +-- ::= , ( ) +-- ::= , +-- ::= , : +-- ::= , (tr) +-- ::= , (tr) : +-- +-- Commae in are optional and may be omitted anywhere. */ + +void set_data(MPL *mpl) +{ SET *set; + TUPLE *tuple; + MEMBER *memb; + SLICE *slice; + int tr = 0; + xassert(is_literal(mpl, "set")); + get_token(mpl /* set */); + /* symbolic name of set must follows the keyword 'set' */ + if (!is_symbol(mpl)) + error(mpl, "set name missing where expected"); + /* select the set to saturate it with data */ + set = select_set(mpl, mpl->image); + get_token(mpl /* */); + /* read optional subscript list, which identifies member of the + set to be read */ + tuple = create_tuple(mpl); + if (mpl->token == T_LBRACKET) + { /* subscript list is specified */ + if (set->dim == 0) + error(mpl, "%s cannot be subscripted", set->name); + get_token(mpl /* [ */); + /* read symbols and construct subscript list */ + for (;;) + { if (!is_symbol(mpl)) + error(mpl, "number or symbol missing where expected"); + tuple = expand_tuple(mpl, tuple, read_symbol(mpl)); + if (mpl->token == T_COMMA) + get_token(mpl /* , */); + else if (mpl->token == T_RBRACKET) + break; + else + error(mpl, "syntax error in subscript list"); + } + if (set->dim != tuple_dimen(mpl, tuple)) + error(mpl, "%s must have %d subscript%s rather than %d", + set->name, set->dim, set->dim == 1 ? "" : "s", + tuple_dimen(mpl, tuple)); + get_token(mpl /* ] */); + } + else + { /* subscript list is not specified */ + if (set->dim != 0) + error(mpl, "%s must be subscripted", set->name); + } + /* there must be no member with the same subscript list */ + if (find_member(mpl, set->array, tuple) != NULL) + error(mpl, "%s%s already defined", + set->name, format_tuple(mpl, '[', tuple)); + /* add new member to the set and assign it empty elemental set */ + memb = add_member(mpl, set->array, tuple); + memb->value.set = create_elemset(mpl, set->dimen); + /* create an initial fake slice of all asterisks */ + slice = fake_slice(mpl, set->dimen); + /* read zero or more data assignments */ + for (;;) + { /* skip optional comma */ + if (mpl->token == T_COMMA) get_token(mpl /* , */); + /* process assignment element */ + if (mpl->token == T_ASSIGN) + { /* assignment ligature is non-significant element */ + get_token(mpl /* := */); + } + else if (mpl->token == T_LEFT) + { /* left parenthesis begins either new slice or "transpose" + indicator */ + int is_tr; + get_token(mpl /* ( */); + is_tr = is_literal(mpl, "tr"); + unget_token(mpl /* ( */); + if (is_tr) goto left; + /* delete the current slice and read new one */ + delete_slice(mpl, slice); + slice = read_slice(mpl, set->name, set->dimen); + /* each new slice resets the "transpose" indicator */ + tr = 0; + /* if the new slice is 0-ary, formally there is one 0-tuple + (in the simple format) that follows it */ + if (slice_arity(mpl, slice) == 0) + simple_format(mpl, set, memb, slice); + } + else if (is_symbol(mpl)) + { /* number or symbol begins data in the simple format */ + simple_format(mpl, set, memb, slice); + } + else if (mpl->token == T_COLON) + { /* colon begins data in the matrix format */ + if (slice_arity(mpl, slice) != 2) +err1: error(mpl, "slice currently used must specify 2 asterisk" + "s, not %d", slice_arity(mpl, slice)); + get_token(mpl /* : */); + /* read elemental set data in the matrix format */ + matrix_format(mpl, set, memb, slice, tr); + } + else if (mpl->token == T_LEFT) +left: { /* left parenthesis begins the "transpose" indicator, which + is followed by data in the matrix format */ + get_token(mpl /* ( */); + if (!is_literal(mpl, "tr")) +err2: error(mpl, "transpose indicator (tr) incomplete"); + if (slice_arity(mpl, slice) != 2) goto err1; + get_token(mpl /* tr */); + if (mpl->token != T_RIGHT) goto err2; + get_token(mpl /* ) */); + /* in this case the colon is optional */ + if (mpl->token == T_COLON) get_token(mpl /* : */); + /* set the "transpose" indicator */ + tr = 1; + /* read elemental set data in the matrix format */ + matrix_format(mpl, set, memb, slice, tr); + } + else if (mpl->token == T_SEMICOLON) + { /* semicolon terminates the data block */ + get_token(mpl /* ; */); + break; + } + else + error(mpl, "syntax error in set data block"); + } + /* delete the current slice */ + delete_slice(mpl, slice); + return; +} + +/*---------------------------------------------------------------------- +-- select_parameter - select parameter to saturate it with data. +-- +-- This routine selects parameter to saturate it with data provided in +-- the data section. */ + +PARAMETER *select_parameter +( MPL *mpl, + char *name /* not changed */ +) +{ PARAMETER *par; + AVLNODE *node; + xassert(name != NULL); + node = avl_find_node(mpl->tree, name); + if (node == NULL || avl_get_node_type(node) != A_PARAMETER) + error(mpl, "%s not a parameter", name); + par = (PARAMETER *)avl_get_node_link(node); + if (par->assign != NULL) + error(mpl, "%s needs no data", name); + if (par->data) + error(mpl, "%s already provided with data", name); + par->data = 1; + return par; +} + +/*---------------------------------------------------------------------- +-- set_default - set default parameter value. +-- +-- This routine sets default value for specified parameter. */ + +void set_default +( MPL *mpl, + PARAMETER *par, /* not changed */ + SYMBOL *altval /* destroyed */ +) +{ xassert(par != NULL); + xassert(altval != NULL); + if (par->option != NULL) + error(mpl, "default value for %s already specified in model se" + "ction", par->name); + xassert(par->defval == NULL); + par->defval = altval; + return; +} + +/*---------------------------------------------------------------------- +-- read_value - read value and assign it to parameter member. +-- +-- This routine reads numeric or symbolic value from the input stream +-- and assigns to new parameter member specified by its n-tuple, which +-- (the member) is created and added to the parameter array. */ + +MEMBER *read_value +( MPL *mpl, + PARAMETER *par, /* not changed */ + TUPLE *tuple /* destroyed */ +) +{ MEMBER *memb; + xassert(par != NULL); + xassert(is_symbol(mpl)); + /* there must be no member with the same n-tuple */ + if (find_member(mpl, par->array, tuple) != NULL) + error(mpl, "%s%s already defined", + par->name, format_tuple(mpl, '[', tuple)); + /* create new parameter member with given n-tuple */ + memb = add_member(mpl, par->array, tuple); + /* read value and assigns it to the new parameter member */ + switch (par->type) + { case A_NUMERIC: + case A_INTEGER: + case A_BINARY: + if (!is_number(mpl)) + error(mpl, "%s requires numeric data", par->name); + memb->value.num = read_number(mpl); + break; + case A_SYMBOLIC: + memb->value.sym = read_symbol(mpl); + break; + default: + xassert(par != par); + } + return memb; +} + +/*---------------------------------------------------------------------- +-- plain_format - read parameter data block in plain format. +-- +-- This routine reads parameter data block using the syntax: +-- +-- ::= , , ... , , +-- +-- where are used to determine a complete subscript list for +-- parameter member, is a numeric or symbolic value assigned to +-- the parameter member. Commae between data items are optional and may +-- be omitted anywhere. +-- +-- Number of components in the slice must be the same as dimension of +-- the parameter. To construct the complete subscript list the routine +-- replaces null positions in the slice by corresponding . */ + +void plain_format +( MPL *mpl, + PARAMETER *par, /* not changed */ + SLICE *slice /* not changed */ +) +{ TUPLE *tuple; + SLICE *temp; + SYMBOL *sym, *with = NULL; + xassert(par != NULL); + xassert(par->dim == slice_dimen(mpl, slice)); + xassert(is_symbol(mpl)); + /* read symbols and construct complete subscript list */ + tuple = create_tuple(mpl); + for (temp = slice; temp != NULL; temp = temp->next) + { if (temp->sym == NULL) + { /* substitution is needed; read symbol */ + if (!is_symbol(mpl)) + { int lack = slice_arity(mpl, temp) + 1; + xassert(with != NULL); + xassert(lack > 1); + error(mpl, "%d items missing in data group beginning wit" + "h %s", lack, format_symbol(mpl, with)); + } + sym = read_symbol(mpl); + if (with == NULL) with = sym; + } + else + { /* copy symbol from the slice */ + sym = copy_symbol(mpl, temp->sym); + } + /* append the symbol to the subscript list */ + tuple = expand_tuple(mpl, tuple, sym); + /* skip optional comma */ + if (mpl->token == T_COMMA) get_token(mpl /* , */); + } + /* read value and assign it to new parameter member */ + if (!is_symbol(mpl)) + { xassert(with != NULL); + error(mpl, "one item missing in data group beginning with %s", + format_symbol(mpl, with)); + } + read_value(mpl, par, tuple); + return; +} + +/*---------------------------------------------------------------------- +-- tabular_format - read parameter data block in tabular format. +-- +-- This routine reads parameter data block using the syntax: +-- +-- ::= ... := +-- ... +-- ... +-- . . . . . . . . . . . +-- ... +-- +-- where are symbols that denote rows of the table, +-- are symbols that denote columns of the table, are numeric +-- or symbolic values assigned to the corresponding parameter members. +-- If is specified as single point, no value is provided. +-- +-- Number of components in the slice must be the same as dimension of +-- the parameter. The slice must have two null positions. To construct +-- complete subscript list for particular the routine replaces +-- the first null position of the slice by the corresponding (or +-- , if the flag tr is on) and the second null position by the +-- corresponding (or by , if the flag tr is on). */ + +void tabular_format +( MPL *mpl, + PARAMETER *par, /* not changed */ + SLICE *slice, /* not changed */ + int tr +) +{ SLICE *list, *col, *temp; + TUPLE *tuple; + SYMBOL *row; + xassert(par != NULL); + xassert(par->dim == slice_dimen(mpl, slice)); + xassert(slice_arity(mpl, slice) == 2); + /* read the table heading that contains column symbols (the table + may have no columns) */ + list = create_slice(mpl); + while (mpl->token != T_ASSIGN) + { /* read column symbol and append it to the column list */ + if (!is_symbol(mpl)) + error(mpl, "number, symbol, or := missing where expected"); + list = expand_slice(mpl, list, read_symbol(mpl)); + } + get_token(mpl /* := */); + /* read zero or more rows that contain tabular data */ + while (is_symbol(mpl)) + { /* read row symbol (if the table has no columns, these symbols + are just ignored) */ + row = read_symbol(mpl); + /* read values accordingly to the column list */ + for (col = list; col != NULL; col = col->next) + { int which = 0; + /* if the token is single point, no value is provided */ + if (is_literal(mpl, ".")) + { get_token(mpl /* . */); + continue; + } + /* construct complete subscript list */ + tuple = create_tuple(mpl); + for (temp = slice; temp != NULL; temp = temp->next) + { if (temp->sym == NULL) + { /* substitution is needed */ + switch (++which) + { case 1: + /* substitute in the first null position */ + tuple = expand_tuple(mpl, tuple, + copy_symbol(mpl, tr ? col->sym : row)); + break; + case 2: + /* substitute in the second null position */ + tuple = expand_tuple(mpl, tuple, + copy_symbol(mpl, tr ? row : col->sym)); + break; + default: + xassert(which != which); + } + } + else + { /* copy symbol from the slice */ + tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, + temp->sym)); + } + } + xassert(which == 2); + /* read value and assign it to new parameter member */ + if (!is_symbol(mpl)) + { int lack = slice_dimen(mpl, col); + if (lack == 1) + error(mpl, "one item missing in data group beginning " + "with %s", format_symbol(mpl, row)); + else + error(mpl, "%d items missing in data group beginning " + "with %s", lack, format_symbol(mpl, row)); + } + read_value(mpl, par, tuple); + } + /* delete the row symbol */ + delete_symbol(mpl, row); + } + /* delete the column list */ + delete_slice(mpl, list); + return; +} + +/*---------------------------------------------------------------------- +-- tabbing_format - read parameter data block in tabbing format. +-- +-- This routine reads parameter data block using the syntax: +-- +-- ::= , ... , , := , +-- , ... , , , ... , , +-- , ... , , , ... , , +-- . . . . . . . . . . . . . . . . . +-- , ... , , , ... , +-- ::= +-- ::= : +-- +-- where are names of parameters (all the parameters must be +-- subscripted and have identical dimensions), are symbols +-- used to define subscripts of parameter members, are numeric +-- or symbolic values assigned to the corresponding parameter members. +-- Optional may specify a simple set, in which case n-tuples +-- built of for each row of the data table (i.e. subscripts +-- of parameter members) are added to the specified set. Commae between +-- data items are optional and may be omitted anywhere. +-- +-- If the parameter altval is not NULL, it specifies a default value +-- provided for all the parameters specified in the data block. */ + +void tabbing_format +( MPL *mpl, + SYMBOL *altval /* not changed */ +) +{ SET *set = NULL; + PARAMETER *par; + SLICE *list, *col; + TUPLE *tuple; + int next_token, j, dim = 0; + char *last_name = NULL; + /* read the optional */ + if (is_symbol(mpl)) + { get_token(mpl /* */); + next_token = mpl->token; + unget_token(mpl /* */); + if (next_token == T_COLON) + { /* select the set to saturate it with data */ + set = select_set(mpl, mpl->image); + /* the set must be simple (i.e. not set of sets) */ + if (set->dim != 0) + error(mpl, "%s must be a simple set", set->name); + /* and must not be defined yet */ + if (set->array->head != NULL) + error(mpl, "%s already defined", set->name); + /* add new (the only) member to the set and assign it empty + elemental set */ + add_member(mpl, set->array, NULL)->value.set = + create_elemset(mpl, set->dimen); + last_name = set->name, dim = set->dimen; + get_token(mpl /* */); + xassert(mpl->token == T_COLON); + get_token(mpl /* : */); + } + } + /* read the table heading that contains parameter names */ + list = create_slice(mpl); + while (mpl->token != T_ASSIGN) + { /* there must be symbolic name of parameter */ + if (!is_symbol(mpl)) + error(mpl, "parameter name or := missing where expected"); + /* select the parameter to saturate it with data */ + par = select_parameter(mpl, mpl->image); + /* the parameter must be subscripted */ + if (par->dim == 0) + error(mpl, "%s not a subscripted parameter", mpl->image); + /* the set (if specified) and all the parameters in the data + block must have identical dimension */ + if (dim != 0 && par->dim != dim) + { xassert(last_name != NULL); + error(mpl, "%s has dimension %d while %s has dimension %d", + last_name, dim, par->name, par->dim); + } + /* set default value for the parameter (if specified) */ + if (altval != NULL) + set_default(mpl, par, copy_symbol(mpl, altval)); + /* append the parameter to the column list */ + list = expand_slice(mpl, list, (SYMBOL *)par); + last_name = par->name, dim = par->dim; + get_token(mpl /* */); + /* skip optional comma */ + if (mpl->token == T_COMMA) get_token(mpl /* , */); + } + if (slice_dimen(mpl, list) == 0) + error(mpl, "at least one parameter name required"); + get_token(mpl /* := */); + /* skip optional comma */ + if (mpl->token == T_COMMA) get_token(mpl /* , */); + /* read rows that contain tabbing data */ + while (is_symbol(mpl)) + { /* read subscript list */ + tuple = create_tuple(mpl); + for (j = 1; j <= dim; j++) + { /* read j-th subscript */ + if (!is_symbol(mpl)) + { int lack = slice_dimen(mpl, list) + dim - j + 1; + xassert(tuple != NULL); + xassert(lack > 1); + error(mpl, "%d items missing in data group beginning wit" + "h %s", lack, format_symbol(mpl, tuple->sym)); + } + /* read and append j-th subscript to the n-tuple */ + tuple = expand_tuple(mpl, tuple, read_symbol(mpl)); + /* skip optional comma *between* */ + if (j < dim && mpl->token == T_COMMA) + get_token(mpl /* , */); + } + /* if the set is specified, add to it new n-tuple, which is a + copy of the subscript list just read */ + if (set != NULL) + check_then_add(mpl, set->array->head->value.set, + copy_tuple(mpl, tuple)); + /* skip optional comma between and */ + if (mpl->token == T_COMMA) get_token(mpl /* , */); + /* read values accordingly to the column list */ + for (col = list; col != NULL; col = col->next) + { /* if the token is single point, no value is provided */ + if (is_literal(mpl, ".")) + { get_token(mpl /* . */); + continue; + } + /* read value and assign it to new parameter member */ + if (!is_symbol(mpl)) + { int lack = slice_dimen(mpl, col); + xassert(tuple != NULL); + if (lack == 1) + error(mpl, "one item missing in data group beginning " + "with %s", format_symbol(mpl, tuple->sym)); + else + error(mpl, "%d items missing in data group beginning " + "with %s", lack, format_symbol(mpl, tuple->sym)); + } + read_value(mpl, (PARAMETER *)col->sym, copy_tuple(mpl, + tuple)); + /* skip optional comma preceding the next value */ + if (col->next != NULL && mpl->token == T_COMMA) + get_token(mpl /* , */); + } + /* delete the original subscript list */ + delete_tuple(mpl, tuple); + /* skip optional comma (only if there is next data group) */ + if (mpl->token == T_COMMA) + { get_token(mpl /* , */); + if (!is_symbol(mpl)) unget_token(mpl /* , */); + } + } + /* delete the column list (it contains parameters, not symbols, + so nullify it before) */ + for (col = list; col != NULL; col = col->next) col->sym = NULL; + delete_slice(mpl, list); + return; +} + +/*---------------------------------------------------------------------- +-- parameter_data - read parameter data. +-- +-- This routine reads parameter data using the syntax: +-- +-- ::= param : ; +-- ::= param +-- ; +-- ::= +-- ::= +-- ::= default +-- ::= +-- ::= , := +-- ::= , [ ] +-- ::= , +-- ::= , : +-- ::= , (tr) +-- ::= , (tr) : +-- +-- Commae in are optional and may be omitted anywhere. */ + +void parameter_data(MPL *mpl) +{ PARAMETER *par; + SYMBOL *altval = NULL; + SLICE *slice; + int tr = 0; + xassert(is_literal(mpl, "param")); + get_token(mpl /* param */); + /* read optional default value */ + if (is_literal(mpl, "default")) + { get_token(mpl /* default */); + if (!is_symbol(mpl)) + error(mpl, "default value missing where expected"); + altval = read_symbol(mpl); + /* if the default value follows the keyword 'param', the next + token must be only the colon */ + if (mpl->token != T_COLON) + error(mpl, "colon missing where expected"); + } + /* being used after the keyword 'param' or the optional default + value the colon begins data in the tabbing format */ + if (mpl->token == T_COLON) + { get_token(mpl /* : */); + /* skip optional comma */ + if (mpl->token == T_COMMA) get_token(mpl /* , */); + /* read parameter data in the tabbing format */ + tabbing_format(mpl, altval); + /* on reading data in the tabbing format the default value is + always copied, so delete the original symbol */ + if (altval != NULL) delete_symbol(mpl, altval); + /* the next token must be only semicolon */ + if (mpl->token != T_SEMICOLON) + error(mpl, "symbol, number, or semicolon missing where expe" + "cted"); + get_token(mpl /* ; */); + goto done; + } + /* in other cases there must be symbolic name of parameter, which + follows the keyword 'param' */ + if (!is_symbol(mpl)) + error(mpl, "parameter name missing where expected"); + /* select the parameter to saturate it with data */ + par = select_parameter(mpl, mpl->image); + get_token(mpl /* */); + /* read optional default value */ + if (is_literal(mpl, "default")) + { get_token(mpl /* default */); + if (!is_symbol(mpl)) + error(mpl, "default value missing where expected"); + altval = read_symbol(mpl); + /* set default value for the parameter */ + set_default(mpl, par, altval); + } + /* create initial fake slice of all asterisks */ + slice = fake_slice(mpl, par->dim); + /* read zero or more data assignments */ + for (;;) + { /* skip optional comma */ + if (mpl->token == T_COMMA) get_token(mpl /* , */); + /* process current assignment */ + if (mpl->token == T_ASSIGN) + { /* assignment ligature is non-significant element */ + get_token(mpl /* := */); + } + else if (mpl->token == T_LBRACKET) + { /* left bracket begins new slice; delete the current slice + and read new one */ + delete_slice(mpl, slice); + slice = read_slice(mpl, par->name, par->dim); + /* each new slice resets the "transpose" indicator */ + tr = 0; + } + else if (is_symbol(mpl)) + { /* number or symbol begins data in the plain format */ + plain_format(mpl, par, slice); + } + else if (mpl->token == T_COLON) + { /* colon begins data in the tabular format */ + if (par->dim == 0) +err1: error(mpl, "%s not a subscripted parameter", + par->name); + if (slice_arity(mpl, slice) != 2) +err2: error(mpl, "slice currently used must specify 2 asterisk" + "s, not %d", slice_arity(mpl, slice)); + get_token(mpl /* : */); + /* read parameter data in the tabular format */ + tabular_format(mpl, par, slice, tr); + } + else if (mpl->token == T_LEFT) + { /* left parenthesis begins the "transpose" indicator, which + is followed by data in the tabular format */ + get_token(mpl /* ( */); + if (!is_literal(mpl, "tr")) +err3: error(mpl, "transpose indicator (tr) incomplete"); + if (par->dim == 0) goto err1; + if (slice_arity(mpl, slice) != 2) goto err2; + get_token(mpl /* tr */); + if (mpl->token != T_RIGHT) goto err3; + get_token(mpl /* ) */); + /* in this case the colon is optional */ + if (mpl->token == T_COLON) get_token(mpl /* : */); + /* set the "transpose" indicator */ + tr = 1; + /* read parameter data in the tabular format */ + tabular_format(mpl, par, slice, tr); + } + else if (mpl->token == T_SEMICOLON) + { /* semicolon terminates the data block */ + get_token(mpl /* ; */); + break; + } + else + error(mpl, "syntax error in parameter data block"); + } + /* delete the current slice */ + delete_slice(mpl, slice); +done: return; +} + +/*---------------------------------------------------------------------- +-- data_section - read data section. +-- +-- This routine reads data section using the syntax: +-- +-- ::= +-- ::= ; +-- ::= +-- ::= +-- +-- Reading data section is terminated by either the keyword 'end' or +-- the end of file. */ + +void data_section(MPL *mpl) +{ while (!(mpl->token == T_EOF || is_literal(mpl, "end"))) + { if (is_literal(mpl, "set")) + set_data(mpl); + else if (is_literal(mpl, "param")) + parameter_data(mpl); + else + error(mpl, "syntax error in data section"); + } + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpmpl03.c b/resources/3rdparty/glpk-4.57/src/glpmpl03.c new file mode 100644 index 000000000..ddc3b583e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpmpl03.c @@ -0,0 +1,6085 @@ +/* glpmpl03.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "glpmpl.h" + +/**********************************************************************/ +/* * * FLOATING-POINT NUMBERS * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- fp_add - floating-point addition. +-- +-- This routine computes the sum x + y. */ + +double fp_add(MPL *mpl, double x, double y) +{ if (x > 0.0 && y > 0.0 && x > + 0.999 * DBL_MAX - y || + x < 0.0 && y < 0.0 && x < - 0.999 * DBL_MAX - y) + error(mpl, "%.*g + %.*g; floating-point overflow", + DBL_DIG, x, DBL_DIG, y); + return x + y; +} + +/*---------------------------------------------------------------------- +-- fp_sub - floating-point subtraction. +-- +-- This routine computes the difference x - y. */ + +double fp_sub(MPL *mpl, double x, double y) +{ if (x > 0.0 && y < 0.0 && x > + 0.999 * DBL_MAX + y || + x < 0.0 && y > 0.0 && x < - 0.999 * DBL_MAX + y) + error(mpl, "%.*g - %.*g; floating-point overflow", + DBL_DIG, x, DBL_DIG, y); + return x - y; +} + +/*---------------------------------------------------------------------- +-- fp_less - floating-point non-negative subtraction. +-- +-- This routine computes the non-negative difference max(0, x - y). */ + +double fp_less(MPL *mpl, double x, double y) +{ if (x < y) return 0.0; + if (x > 0.0 && y < 0.0 && x > + 0.999 * DBL_MAX + y) + error(mpl, "%.*g less %.*g; floating-point overflow", + DBL_DIG, x, DBL_DIG, y); + return x - y; +} + +/*---------------------------------------------------------------------- +-- fp_mul - floating-point multiplication. +-- +-- This routine computes the product x * y. */ + +double fp_mul(MPL *mpl, double x, double y) +{ if (fabs(y) > 1.0 && fabs(x) > (0.999 * DBL_MAX) / fabs(y)) + error(mpl, "%.*g * %.*g; floating-point overflow", + DBL_DIG, x, DBL_DIG, y); + return x * y; +} + +/*---------------------------------------------------------------------- +-- fp_div - floating-point division. +-- +-- This routine computes the quotient x / y. */ + +double fp_div(MPL *mpl, double x, double y) +{ if (fabs(y) < DBL_MIN) + error(mpl, "%.*g / %.*g; floating-point zero divide", + DBL_DIG, x, DBL_DIG, y); + if (fabs(y) < 1.0 && fabs(x) > (0.999 * DBL_MAX) * fabs(y)) + error(mpl, "%.*g / %.*g; floating-point overflow", + DBL_DIG, x, DBL_DIG, y); + return x / y; +} + +/*---------------------------------------------------------------------- +-- fp_idiv - floating-point quotient of exact division. +-- +-- This routine computes the quotient of exact division x div y. */ + +double fp_idiv(MPL *mpl, double x, double y) +{ if (fabs(y) < DBL_MIN) + error(mpl, "%.*g div %.*g; floating-point zero divide", + DBL_DIG, x, DBL_DIG, y); + if (fabs(y) < 1.0 && fabs(x) > (0.999 * DBL_MAX) * fabs(y)) + error(mpl, "%.*g div %.*g; floating-point overflow", + DBL_DIG, x, DBL_DIG, y); + x /= y; + return x > 0.0 ? floor(x) : x < 0.0 ? ceil(x) : 0.0; +} + +/*---------------------------------------------------------------------- +-- fp_mod - floating-point remainder of exact division. +-- +-- This routine computes the remainder of exact division x mod y. +-- +-- NOTE: By definition x mod y = x - y * floor(x / y). */ + +double fp_mod(MPL *mpl, double x, double y) +{ double r; + xassert(mpl == mpl); + if (x == 0.0) + r = 0.0; + else if (y == 0.0) + r = x; + else + { r = fmod(fabs(x), fabs(y)); + if (r != 0.0) + { if (x < 0.0) r = - r; + if (x > 0.0 && y < 0.0 || x < 0.0 && y > 0.0) r += y; + } + } + return r; +} + +/*---------------------------------------------------------------------- +-- fp_power - floating-point exponentiation (raise to power). +-- +-- This routine computes the exponentiation x ** y. */ + +double fp_power(MPL *mpl, double x, double y) +{ double r; + if (x == 0.0 && y <= 0.0 || x < 0.0 && y != floor(y)) + error(mpl, "%.*g ** %.*g; result undefined", + DBL_DIG, x, DBL_DIG, y); + if (x == 0.0) goto eval; + if (fabs(x) > 1.0 && y > +1.0 && + +log(fabs(x)) > (0.999 * log(DBL_MAX)) / y || + fabs(x) < 1.0 && y < -1.0 && + +log(fabs(x)) < (0.999 * log(DBL_MAX)) / y) + error(mpl, "%.*g ** %.*g; floating-point overflow", + DBL_DIG, x, DBL_DIG, y); + if (fabs(x) > 1.0 && y < -1.0 && + -log(fabs(x)) < (0.999 * log(DBL_MAX)) / y || + fabs(x) < 1.0 && y > +1.0 && + -log(fabs(x)) > (0.999 * log(DBL_MAX)) / y) + r = 0.0; + else +eval: r = pow(x, y); + return r; +} + +/*---------------------------------------------------------------------- +-- fp_exp - floating-point base-e exponential. +-- +-- This routine computes the base-e exponential e ** x. */ + +double fp_exp(MPL *mpl, double x) +{ if (x > 0.999 * log(DBL_MAX)) + error(mpl, "exp(%.*g); floating-point overflow", DBL_DIG, x); + return exp(x); +} + +/*---------------------------------------------------------------------- +-- fp_log - floating-point natural logarithm. +-- +-- This routine computes the natural logarithm log x. */ + +double fp_log(MPL *mpl, double x) +{ if (x <= 0.0) + error(mpl, "log(%.*g); non-positive argument", DBL_DIG, x); + return log(x); +} + +/*---------------------------------------------------------------------- +-- fp_log10 - floating-point common (decimal) logarithm. +-- +-- This routine computes the common (decimal) logarithm lg x. */ + +double fp_log10(MPL *mpl, double x) +{ if (x <= 0.0) + error(mpl, "log10(%.*g); non-positive argument", DBL_DIG, x); + return log10(x); +} + +/*---------------------------------------------------------------------- +-- fp_sqrt - floating-point square root. +-- +-- This routine computes the square root x ** 0.5. */ + +double fp_sqrt(MPL *mpl, double x) +{ if (x < 0.0) + error(mpl, "sqrt(%.*g); negative argument", DBL_DIG, x); + return sqrt(x); +} + +/*---------------------------------------------------------------------- +-- fp_sin - floating-point trigonometric sine. +-- +-- This routine computes the trigonometric sine sin(x). */ + +double fp_sin(MPL *mpl, double x) +{ if (!(-1e6 <= x && x <= +1e6)) + error(mpl, "sin(%.*g); argument too large", DBL_DIG, x); + return sin(x); +} + +/*---------------------------------------------------------------------- +-- fp_cos - floating-point trigonometric cosine. +-- +-- This routine computes the trigonometric cosine cos(x). */ + +double fp_cos(MPL *mpl, double x) +{ if (!(-1e6 <= x && x <= +1e6)) + error(mpl, "cos(%.*g); argument too large", DBL_DIG, x); + return cos(x); +} + +/*---------------------------------------------------------------------- +-- fp_atan - floating-point trigonometric arctangent. +-- +-- This routine computes the trigonometric arctangent atan(x). */ + +double fp_atan(MPL *mpl, double x) +{ xassert(mpl == mpl); + return atan(x); +} + +/*---------------------------------------------------------------------- +-- fp_atan2 - floating-point trigonometric arctangent. +-- +-- This routine computes the trigonometric arctangent atan(y / x). */ + +double fp_atan2(MPL *mpl, double y, double x) +{ xassert(mpl == mpl); + return atan2(y, x); +} + +/*---------------------------------------------------------------------- +-- fp_round - round floating-point value to n fractional digits. +-- +-- This routine rounds given floating-point value x to n fractional +-- digits with the formula: +-- +-- round(x, n) = floor(x * 10^n + 0.5) / 10^n. +-- +-- The parameter n is assumed to be integer. */ + +double fp_round(MPL *mpl, double x, double n) +{ double ten_to_n; + if (n != floor(n)) + error(mpl, "round(%.*g, %.*g); non-integer second argument", + DBL_DIG, x, DBL_DIG, n); + if (n <= DBL_DIG + 2) + { ten_to_n = pow(10.0, n); + if (fabs(x) < (0.999 * DBL_MAX) / ten_to_n) + { x = floor(x * ten_to_n + 0.5); + if (x != 0.0) x /= ten_to_n; + } + } + return x; +} + +/*---------------------------------------------------------------------- +-- fp_trunc - truncate floating-point value to n fractional digits. +-- +-- This routine truncates given floating-point value x to n fractional +-- digits with the formula: +-- +-- ( floor(x * 10^n) / 10^n, if x >= 0 +-- trunc(x, n) = < +-- ( ceil(x * 10^n) / 10^n, if x < 0 +-- +-- The parameter n is assumed to be integer. */ + +double fp_trunc(MPL *mpl, double x, double n) +{ double ten_to_n; + if (n != floor(n)) + error(mpl, "trunc(%.*g, %.*g); non-integer second argument", + DBL_DIG, x, DBL_DIG, n); + if (n <= DBL_DIG + 2) + { ten_to_n = pow(10.0, n); + if (fabs(x) < (0.999 * DBL_MAX) / ten_to_n) + { x = (x >= 0.0 ? floor(x * ten_to_n) : ceil(x * ten_to_n)); + if (x != 0.0) x /= ten_to_n; + } + } + return x; +} + +/**********************************************************************/ +/* * * PSEUDO-RANDOM NUMBER GENERATORS * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- fp_irand224 - pseudo-random integer in the range [0, 2^24). +-- +-- This routine returns a next pseudo-random integer (converted to +-- floating-point) which is uniformly distributed between 0 and 2^24-1, +-- inclusive. */ + +#define two_to_the_24 0x1000000 + +double fp_irand224(MPL *mpl) +{ return + (double)rng_unif_rand(mpl->rand, two_to_the_24); +} + +/*---------------------------------------------------------------------- +-- fp_uniform01 - pseudo-random number in the range [0, 1). +-- +-- This routine returns a next pseudo-random number which is uniformly +-- distributed in the range [0, 1). */ + +#define two_to_the_31 ((unsigned int)0x80000000) + +double fp_uniform01(MPL *mpl) +{ return + (double)rng_next_rand(mpl->rand) / (double)two_to_the_31; +} + +/*---------------------------------------------------------------------- +-- fp_uniform - pseudo-random number in the range [a, b). +-- +-- This routine returns a next pseudo-random number which is uniformly +-- distributed in the range [a, b). */ + +double fp_uniform(MPL *mpl, double a, double b) +{ double x; + if (a >= b) + error(mpl, "Uniform(%.*g, %.*g); invalid range", + DBL_DIG, a, DBL_DIG, b); + x = fp_uniform01(mpl); +#if 0 + x = a * (1.0 - x) + b * x; +#else + x = fp_add(mpl, a * (1.0 - x), b * x); +#endif + return x; +} + +/*---------------------------------------------------------------------- +-- fp_normal01 - Gaussian random variate with mu = 0 and sigma = 1. +-- +-- This routine returns a Gaussian random variate with zero mean and +-- unit standard deviation. The polar (Box-Mueller) method is used. +-- +-- This code is a modified version of the routine gsl_ran_gaussian from +-- the GNU Scientific Library Version 1.0. */ + +double fp_normal01(MPL *mpl) +{ double x, y, r2; + do + { /* choose x, y in uniform square (-1,-1) to (+1,+1) */ + x = -1.0 + 2.0 * fp_uniform01(mpl); + y = -1.0 + 2.0 * fp_uniform01(mpl); + /* see if it is in the unit circle */ + r2 = x * x + y * y; + } while (r2 > 1.0 || r2 == 0.0); + /* Box-Muller transform */ + return y * sqrt(-2.0 * log (r2) / r2); +} + +/*---------------------------------------------------------------------- +-- fp_normal - Gaussian random variate with specified mu and sigma. +-- +-- This routine returns a Gaussian random variate with mean mu and +-- standard deviation sigma. */ + +double fp_normal(MPL *mpl, double mu, double sigma) +{ double x; +#if 0 + x = mu + sigma * fp_normal01(mpl); +#else + x = fp_add(mpl, mu, fp_mul(mpl, sigma, fp_normal01(mpl))); +#endif + return x; +} + +/**********************************************************************/ +/* * * SEGMENTED CHARACTER STRINGS * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- create_string - create character string. +-- +-- This routine creates a segmented character string, which is exactly +-- equivalent to specified character string. */ + +STRING *create_string +( MPL *mpl, + char buf[MAX_LENGTH+1] /* not changed */ +) +#if 0 +{ STRING *head, *tail; + int i, j; + xassert(buf != NULL); + xassert(strlen(buf) <= MAX_LENGTH); + head = tail = dmp_get_atom(mpl->strings, sizeof(STRING)); + for (i = j = 0; ; i++) + { if ((tail->seg[j++] = buf[i]) == '\0') break; + if (j == STRSEG_SIZE) +tail = (tail->next = dmp_get_atom(mpl->strings, sizeof(STRING))), j = 0; + } + tail->next = NULL; + return head; +} +#else +{ STRING *str; + xassert(strlen(buf) <= MAX_LENGTH); + str = dmp_get_atom(mpl->strings, strlen(buf)+1); + strcpy(str, buf); + return str; +} +#endif + +/*---------------------------------------------------------------------- +-- copy_string - make copy of character string. +-- +-- This routine returns an exact copy of segmented character string. */ + +STRING *copy_string +( MPL *mpl, + STRING *str /* not changed */ +) +#if 0 +{ STRING *head, *tail; + xassert(str != NULL); + head = tail = dmp_get_atom(mpl->strings, sizeof(STRING)); + for (; str != NULL; str = str->next) + { memcpy(tail->seg, str->seg, STRSEG_SIZE); + if (str->next != NULL) +tail = (tail->next = dmp_get_atom(mpl->strings, sizeof(STRING))); + } + tail->next = NULL; + return head; +} +#else +{ xassert(mpl == mpl); + return create_string(mpl, str); +} +#endif + +/*---------------------------------------------------------------------- +-- compare_strings - compare one character string with another. +-- +-- This routine compares one segmented character strings with another +-- and returns the result of comparison as follows: +-- +-- = 0 - both strings are identical; +-- < 0 - the first string precedes the second one; +-- > 0 - the first string follows the second one. */ + +int compare_strings +( MPL *mpl, + STRING *str1, /* not changed */ + STRING *str2 /* not changed */ +) +#if 0 +{ int j, c1, c2; + xassert(mpl == mpl); + for (;; str1 = str1->next, str2 = str2->next) + { xassert(str1 != NULL); + xassert(str2 != NULL); + for (j = 0; j < STRSEG_SIZE; j++) + { c1 = (unsigned char)str1->seg[j]; + c2 = (unsigned char)str2->seg[j]; + if (c1 < c2) return -1; + if (c1 > c2) return +1; + if (c1 == '\0') goto done; + } + } +done: return 0; +} +#else +{ xassert(mpl == mpl); + return strcmp(str1, str2); +} +#endif + +/*---------------------------------------------------------------------- +-- fetch_string - extract content of character string. +-- +-- This routine returns a character string, which is exactly equivalent +-- to specified segmented character string. */ + +char *fetch_string +( MPL *mpl, + STRING *str, /* not changed */ + char buf[MAX_LENGTH+1] /* modified */ +) +#if 0 +{ int i, j; + xassert(mpl == mpl); + xassert(buf != NULL); + for (i = 0; ; str = str->next) + { xassert(str != NULL); + for (j = 0; j < STRSEG_SIZE; j++) + if ((buf[i++] = str->seg[j]) == '\0') goto done; + } +done: xassert(strlen(buf) <= MAX_LENGTH); + return buf; +} +#else +{ xassert(mpl == mpl); + return strcpy(buf, str); +} +#endif + +/*---------------------------------------------------------------------- +-- delete_string - delete character string. +-- +-- This routine deletes specified segmented character string. */ + +void delete_string +( MPL *mpl, + STRING *str /* destroyed */ +) +#if 0 +{ STRING *temp; + xassert(str != NULL); + while (str != NULL) + { temp = str; + str = str->next; + dmp_free_atom(mpl->strings, temp, sizeof(STRING)); + } + return; +} +#else +{ dmp_free_atom(mpl->strings, str, strlen(str)+1); + return; +} +#endif + +/**********************************************************************/ +/* * * SYMBOLS * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- create_symbol_num - create symbol of numeric type. +-- +-- This routine creates a symbol, which has a numeric value specified +-- as floating-point number. */ + +SYMBOL *create_symbol_num(MPL *mpl, double num) +{ SYMBOL *sym; + sym = dmp_get_atom(mpl->symbols, sizeof(SYMBOL)); + sym->num = num; + sym->str = NULL; + return sym; +} + +/*---------------------------------------------------------------------- +-- create_symbol_str - create symbol of abstract type. +-- +-- This routine creates a symbol, which has an abstract value specified +-- as segmented character string. */ + +SYMBOL *create_symbol_str +( MPL *mpl, + STRING *str /* destroyed */ +) +{ SYMBOL *sym; + xassert(str != NULL); + sym = dmp_get_atom(mpl->symbols, sizeof(SYMBOL)); + sym->num = 0.0; + sym->str = str; + return sym; +} + +/*---------------------------------------------------------------------- +-- copy_symbol - make copy of symbol. +-- +-- This routine returns an exact copy of symbol. */ + +SYMBOL *copy_symbol +( MPL *mpl, + SYMBOL *sym /* not changed */ +) +{ SYMBOL *copy; + xassert(sym != NULL); + copy = dmp_get_atom(mpl->symbols, sizeof(SYMBOL)); + if (sym->str == NULL) + { copy->num = sym->num; + copy->str = NULL; + } + else + { copy->num = 0.0; + copy->str = copy_string(mpl, sym->str); + } + return copy; +} + +/*---------------------------------------------------------------------- +-- compare_symbols - compare one symbol with another. +-- +-- This routine compares one symbol with another and returns the result +-- of comparison as follows: +-- +-- = 0 - both symbols are identical; +-- < 0 - the first symbol precedes the second one; +-- > 0 - the first symbol follows the second one. +-- +-- Note that the linear order, in which symbols follow each other, is +-- implementation-dependent. It may be not an alphabetical order. */ + +int compare_symbols +( MPL *mpl, + SYMBOL *sym1, /* not changed */ + SYMBOL *sym2 /* not changed */ +) +{ xassert(sym1 != NULL); + xassert(sym2 != NULL); + /* let all numeric quantities precede all symbolic quantities */ + if (sym1->str == NULL && sym2->str == NULL) + { if (sym1->num < sym2->num) return -1; + if (sym1->num > sym2->num) return +1; + return 0; + } + if (sym1->str == NULL) return -1; + if (sym2->str == NULL) return +1; + return compare_strings(mpl, sym1->str, sym2->str); +} + +/*---------------------------------------------------------------------- +-- delete_symbol - delete symbol. +-- +-- This routine deletes specified symbol. */ + +void delete_symbol +( MPL *mpl, + SYMBOL *sym /* destroyed */ +) +{ xassert(sym != NULL); + if (sym->str != NULL) delete_string(mpl, sym->str); + dmp_free_atom(mpl->symbols, sym, sizeof(SYMBOL)); + return; +} + +/*---------------------------------------------------------------------- +-- format_symbol - format symbol for displaying or printing. +-- +-- This routine converts specified symbol to a charater string, which +-- is suitable for displaying or printing. +-- +-- The resultant string is never longer than 255 characters. If it gets +-- longer, it is truncated from the right and appended by dots. */ + +char *format_symbol +( MPL *mpl, + SYMBOL *sym /* not changed */ +) +{ char *buf = mpl->sym_buf; + xassert(sym != NULL); + if (sym->str == NULL) + sprintf(buf, "%.*g", DBL_DIG, sym->num); + else + { char str[MAX_LENGTH+1]; + int quoted, j, len; + fetch_string(mpl, sym->str, str); + if (!(isalpha((unsigned char)str[0]) || str[0] == '_')) + quoted = 1; + else + { quoted = 0; + for (j = 1; str[j] != '\0'; j++) + { if (!(isalnum((unsigned char)str[j]) || + strchr("+-._", (unsigned char)str[j]) != NULL)) + { quoted = 1; + break; + } + } + } +# define safe_append(c) \ + (void)(len < 255 ? (buf[len++] = (char)(c)) : 0) + buf[0] = '\0', len = 0; + if (quoted) safe_append('\''); + for (j = 0; str[j] != '\0'; j++) + { if (quoted && str[j] == '\'') safe_append('\''); + safe_append(str[j]); + } + if (quoted) safe_append('\''); +# undef safe_append + buf[len] = '\0'; + if (len == 255) strcpy(buf+252, "..."); + } + xassert(strlen(buf) <= 255); + return buf; +} + +/*---------------------------------------------------------------------- +-- concat_symbols - concatenate one symbol with another. +-- +-- This routine concatenates values of two given symbols and assigns +-- the resultant character string to a new symbol, which is returned on +-- exit. Both original symbols are destroyed. */ + +SYMBOL *concat_symbols +( MPL *mpl, + SYMBOL *sym1, /* destroyed */ + SYMBOL *sym2 /* destroyed */ +) +{ char str1[MAX_LENGTH+1], str2[MAX_LENGTH+1]; + xassert(MAX_LENGTH >= DBL_DIG + DBL_DIG); + if (sym1->str == NULL) + sprintf(str1, "%.*g", DBL_DIG, sym1->num); + else + fetch_string(mpl, sym1->str, str1); + if (sym2->str == NULL) + sprintf(str2, "%.*g", DBL_DIG, sym2->num); + else + fetch_string(mpl, sym2->str, str2); + if (strlen(str1) + strlen(str2) > MAX_LENGTH) + { char buf[255+1]; + strcpy(buf, format_symbol(mpl, sym1)); + xassert(strlen(buf) < sizeof(buf)); + error(mpl, "%s & %s; resultant symbol exceeds %d characters", + buf, format_symbol(mpl, sym2), MAX_LENGTH); + } + delete_symbol(mpl, sym1); + delete_symbol(mpl, sym2); + return create_symbol_str(mpl, create_string(mpl, strcat(str1, + str2))); +} + +/**********************************************************************/ +/* * * N-TUPLES * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- create_tuple - create n-tuple. +-- +-- This routine creates a n-tuple, which initially has no components, +-- i.e. which is 0-tuple. */ + +TUPLE *create_tuple(MPL *mpl) +{ TUPLE *tuple; + xassert(mpl == mpl); + tuple = NULL; + return tuple; +} + +/*---------------------------------------------------------------------- +-- expand_tuple - append symbol to n-tuple. +-- +-- This routine expands n-tuple appending to it a given symbol, which +-- becomes its new last component. */ + +TUPLE *expand_tuple +( MPL *mpl, + TUPLE *tuple, /* destroyed */ + SYMBOL *sym /* destroyed */ +) +{ TUPLE *tail, *temp; + xassert(sym != NULL); + /* create a new component */ + tail = dmp_get_atom(mpl->tuples, sizeof(TUPLE)); + tail->sym = sym; + tail->next = NULL; + /* and append it to the component list */ + if (tuple == NULL) + tuple = tail; + else + { for (temp = tuple; temp->next != NULL; temp = temp->next); + temp->next = tail; + } + return tuple; +} + +/*---------------------------------------------------------------------- +-- tuple_dimen - determine dimension of n-tuple. +-- +-- This routine returns dimension of n-tuple, i.e. number of components +-- in the n-tuple. */ + +int tuple_dimen +( MPL *mpl, + TUPLE *tuple /* not changed */ +) +{ TUPLE *temp; + int dim = 0; + xassert(mpl == mpl); + for (temp = tuple; temp != NULL; temp = temp->next) dim++; + return dim; +} + +/*---------------------------------------------------------------------- +-- copy_tuple - make copy of n-tuple. +-- +-- This routine returns an exact copy of n-tuple. */ + +TUPLE *copy_tuple +( MPL *mpl, + TUPLE *tuple /* not changed */ +) +{ TUPLE *head, *tail; + if (tuple == NULL) + head = NULL; + else + { head = tail = dmp_get_atom(mpl->tuples, sizeof(TUPLE)); + for (; tuple != NULL; tuple = tuple->next) + { xassert(tuple->sym != NULL); + tail->sym = copy_symbol(mpl, tuple->sym); + if (tuple->next != NULL) +tail = (tail->next = dmp_get_atom(mpl->tuples, sizeof(TUPLE))); + } + tail->next = NULL; + } + return head; +} + +/*---------------------------------------------------------------------- +-- compare_tuples - compare one n-tuple with another. +-- +-- This routine compares two given n-tuples, which must have the same +-- dimension (not checked for the sake of efficiency), and returns one +-- of the following codes: +-- +-- = 0 - both n-tuples are identical; +-- < 0 - the first n-tuple precedes the second one; +-- > 0 - the first n-tuple follows the second one. +-- +-- Note that the linear order, in which n-tuples follow each other, is +-- implementation-dependent. It may be not an alphabetical order. */ + +int compare_tuples +( MPL *mpl, + TUPLE *tuple1, /* not changed */ + TUPLE *tuple2 /* not changed */ +) +{ TUPLE *item1, *item2; + int ret; + xassert(mpl == mpl); + for (item1 = tuple1, item2 = tuple2; item1 != NULL; + item1 = item1->next, item2 = item2->next) + { xassert(item2 != NULL); + xassert(item1->sym != NULL); + xassert(item2->sym != NULL); + ret = compare_symbols(mpl, item1->sym, item2->sym); + if (ret != 0) return ret; + } + xassert(item2 == NULL); + return 0; +} + +/*---------------------------------------------------------------------- +-- build_subtuple - build subtuple of given n-tuple. +-- +-- This routine builds subtuple, which consists of first dim components +-- of given n-tuple. */ + +TUPLE *build_subtuple +( MPL *mpl, + TUPLE *tuple, /* not changed */ + int dim +) +{ TUPLE *head, *temp; + int j; + head = create_tuple(mpl); + for (j = 1, temp = tuple; j <= dim; j++, temp = temp->next) + { xassert(temp != NULL); + head = expand_tuple(mpl, head, copy_symbol(mpl, temp->sym)); + } + return head; +} + +/*---------------------------------------------------------------------- +-- delete_tuple - delete n-tuple. +-- +-- This routine deletes specified n-tuple. */ + +void delete_tuple +( MPL *mpl, + TUPLE *tuple /* destroyed */ +) +{ TUPLE *temp; + while (tuple != NULL) + { temp = tuple; + tuple = temp->next; + xassert(temp->sym != NULL); + delete_symbol(mpl, temp->sym); + dmp_free_atom(mpl->tuples, temp, sizeof(TUPLE)); + } + return; +} + +/*---------------------------------------------------------------------- +-- format_tuple - format n-tuple for displaying or printing. +-- +-- This routine converts specified n-tuple to a character string, which +-- is suitable for displaying or printing. +-- +-- The resultant string is never longer than 255 characters. If it gets +-- longer, it is truncated from the right and appended by dots. */ + +char *format_tuple +( MPL *mpl, + int c, + TUPLE *tuple /* not changed */ +) +{ TUPLE *temp; + int dim, j, len; + char *buf = mpl->tup_buf, str[255+1], *save; +# define safe_append(c) \ + (void)(len < 255 ? (buf[len++] = (char)(c)) : 0) + buf[0] = '\0', len = 0; + dim = tuple_dimen(mpl, tuple); + if (c == '[' && dim > 0) safe_append('['); + if (c == '(' && dim > 1) safe_append('('); + for (temp = tuple; temp != NULL; temp = temp->next) + { if (temp != tuple) safe_append(','); + xassert(temp->sym != NULL); + save = mpl->sym_buf; + mpl->sym_buf = str; + format_symbol(mpl, temp->sym); + mpl->sym_buf = save; + xassert(strlen(str) < sizeof(str)); + for (j = 0; str[j] != '\0'; j++) safe_append(str[j]); + } + if (c == '[' && dim > 0) safe_append(']'); + if (c == '(' && dim > 1) safe_append(')'); +# undef safe_append + buf[len] = '\0'; + if (len == 255) strcpy(buf+252, "..."); + xassert(strlen(buf) <= 255); + return buf; +} + +/**********************************************************************/ +/* * * ELEMENTAL SETS * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- create_elemset - create elemental set. +-- +-- This routine creates an elemental set, whose members are n-tuples of +-- specified dimension. Being created the set is initially empty. */ + +ELEMSET *create_elemset(MPL *mpl, int dim) +{ ELEMSET *set; + xassert(dim > 0); + set = create_array(mpl, A_NONE, dim); + return set; +} + +/*---------------------------------------------------------------------- +-- find_tuple - check if elemental set contains given n-tuple. +-- +-- This routine finds given n-tuple in specified elemental set in order +-- to check if the set contains that n-tuple. If the n-tuple is found, +-- the routine returns pointer to corresponding array member. Otherwise +-- null pointer is returned. */ + +MEMBER *find_tuple +( MPL *mpl, + ELEMSET *set, /* not changed */ + TUPLE *tuple /* not changed */ +) +{ xassert(set != NULL); + xassert(set->type == A_NONE); + xassert(set->dim == tuple_dimen(mpl, tuple)); + return find_member(mpl, set, tuple); +} + +/*---------------------------------------------------------------------- +-- add_tuple - add new n-tuple to elemental set. +-- +-- This routine adds given n-tuple to specified elemental set. +-- +-- For the sake of efficiency this routine doesn't check whether the +-- set already contains the same n-tuple or not. Therefore the calling +-- program should use the routine find_tuple (if necessary) in order to +-- make sure that the given n-tuple is not contained in the set, since +-- duplicate n-tuples within the same set are not allowed. */ + +MEMBER *add_tuple +( MPL *mpl, + ELEMSET *set, /* modified */ + TUPLE *tuple /* destroyed */ +) +{ MEMBER *memb; + xassert(set != NULL); + xassert(set->type == A_NONE); + xassert(set->dim == tuple_dimen(mpl, tuple)); + memb = add_member(mpl, set, tuple); + memb->value.none = NULL; + return memb; +} + +/*---------------------------------------------------------------------- +-- check_then_add - check and add new n-tuple to elemental set. +-- +-- This routine is equivalent to the routine add_tuple except that it +-- does check for duplicate n-tuples. */ + +MEMBER *check_then_add +( MPL *mpl, + ELEMSET *set, /* modified */ + TUPLE *tuple /* destroyed */ +) +{ if (find_tuple(mpl, set, tuple) != NULL) + error(mpl, "duplicate tuple %s detected", format_tuple(mpl, + '(', tuple)); + return add_tuple(mpl, set, tuple); +} + +/*---------------------------------------------------------------------- +-- copy_elemset - make copy of elemental set. +-- +-- This routine makes an exact copy of elemental set. */ + +ELEMSET *copy_elemset +( MPL *mpl, + ELEMSET *set /* not changed */ +) +{ ELEMSET *copy; + MEMBER *memb; + xassert(set != NULL); + xassert(set->type == A_NONE); + xassert(set->dim > 0); + copy = create_elemset(mpl, set->dim); + for (memb = set->head; memb != NULL; memb = memb->next) + add_tuple(mpl, copy, copy_tuple(mpl, memb->tuple)); + return copy; +} + +/*---------------------------------------------------------------------- +-- delete_elemset - delete elemental set. +-- +-- This routine deletes specified elemental set. */ + +void delete_elemset +( MPL *mpl, + ELEMSET *set /* destroyed */ +) +{ xassert(set != NULL); + xassert(set->type == A_NONE); + delete_array(mpl, set); + return; +} + +/*---------------------------------------------------------------------- +-- arelset_size - compute size of "arithmetic" elemental set. +-- +-- This routine computes the size of "arithmetic" elemental set, which +-- is specified in the form of arithmetic progression: +-- +-- { t0 .. tf by dt }. +-- +-- The size is computed using the formula: +-- +-- n = max(0, floor((tf - t0) / dt) + 1). */ + +int arelset_size(MPL *mpl, double t0, double tf, double dt) +{ double temp; + if (dt == 0.0) + error(mpl, "%.*g .. %.*g by %.*g; zero stride not allowed", + DBL_DIG, t0, DBL_DIG, tf, DBL_DIG, dt); + if (tf > 0.0 && t0 < 0.0 && tf > + 0.999 * DBL_MAX + t0) + temp = +DBL_MAX; + else if (tf < 0.0 && t0 > 0.0 && tf < - 0.999 * DBL_MAX + t0) + temp = -DBL_MAX; + else + temp = tf - t0; + if (fabs(dt) < 1.0 && fabs(temp) > (0.999 * DBL_MAX) * fabs(dt)) + { if (temp > 0.0 && dt > 0.0 || temp < 0.0 && dt < 0.0) + temp = +DBL_MAX; + else + temp = 0.0; + } + else + { temp = floor(temp / dt) + 1.0; + if (temp < 0.0) temp = 0.0; + } + xassert(temp >= 0.0); + if (temp > (double)(INT_MAX - 1)) + error(mpl, "%.*g .. %.*g by %.*g; set too large", + DBL_DIG, t0, DBL_DIG, tf, DBL_DIG, dt); + return (int)(temp + 0.5); +} + +/*---------------------------------------------------------------------- +-- arelset_member - compute member of "arithmetic" elemental set. +-- +-- This routine returns a numeric value of symbol, which is equivalent +-- to j-th member of given "arithmetic" elemental set specified in the +-- form of arithmetic progression: +-- +-- { t0 .. tf by dt }. +-- +-- The symbol value is computed with the formula: +-- +-- j-th member = t0 + (j - 1) * dt, +-- +-- The number j must satisfy to the restriction 1 <= j <= n, where n is +-- the set size computed by the routine arelset_size. */ + +double arelset_member(MPL *mpl, double t0, double tf, double dt, int j) +{ xassert(1 <= j && j <= arelset_size(mpl, t0, tf, dt)); + return t0 + (double)(j - 1) * dt; +} + +/*---------------------------------------------------------------------- +-- create_arelset - create "arithmetic" elemental set. +-- +-- This routine creates "arithmetic" elemental set, which is specified +-- in the form of arithmetic progression: +-- +-- { t0 .. tf by dt }. +-- +-- Components of this set are 1-tuples. */ + +ELEMSET *create_arelset(MPL *mpl, double t0, double tf, double dt) +{ ELEMSET *set; + int j, n; + set = create_elemset(mpl, 1); + n = arelset_size(mpl, t0, tf, dt); + for (j = 1; j <= n; j++) + { add_tuple + ( mpl, + set, + expand_tuple + ( mpl, + create_tuple(mpl), + create_symbol_num + ( mpl, + arelset_member(mpl, t0, tf, dt, j) + ) + ) + ); + } + return set; +} + +/*---------------------------------------------------------------------- +-- set_union - union of two elemental sets. +-- +-- This routine computes the union: +-- +-- X U Y = { j | (j in X) or (j in Y) }, +-- +-- where X and Y are given elemental sets (destroyed on exit). */ + +ELEMSET *set_union +( MPL *mpl, + ELEMSET *X, /* destroyed */ + ELEMSET *Y /* destroyed */ +) +{ MEMBER *memb; + xassert(X != NULL); + xassert(X->type == A_NONE); + xassert(X->dim > 0); + xassert(Y != NULL); + xassert(Y->type == A_NONE); + xassert(Y->dim > 0); + xassert(X->dim == Y->dim); + for (memb = Y->head; memb != NULL; memb = memb->next) + { if (find_tuple(mpl, X, memb->tuple) == NULL) + add_tuple(mpl, X, copy_tuple(mpl, memb->tuple)); + } + delete_elemset(mpl, Y); + return X; +} + +/*---------------------------------------------------------------------- +-- set_diff - difference between two elemental sets. +-- +-- This routine computes the difference: +-- +-- X \ Y = { j | (j in X) and (j not in Y) }, +-- +-- where X and Y are given elemental sets (destroyed on exit). */ + +ELEMSET *set_diff +( MPL *mpl, + ELEMSET *X, /* destroyed */ + ELEMSET *Y /* destroyed */ +) +{ ELEMSET *Z; + MEMBER *memb; + xassert(X != NULL); + xassert(X->type == A_NONE); + xassert(X->dim > 0); + xassert(Y != NULL); + xassert(Y->type == A_NONE); + xassert(Y->dim > 0); + xassert(X->dim == Y->dim); + Z = create_elemset(mpl, X->dim); + for (memb = X->head; memb != NULL; memb = memb->next) + { if (find_tuple(mpl, Y, memb->tuple) == NULL) + add_tuple(mpl, Z, copy_tuple(mpl, memb->tuple)); + } + delete_elemset(mpl, X); + delete_elemset(mpl, Y); + return Z; +} + +/*---------------------------------------------------------------------- +-- set_symdiff - symmetric difference between two elemental sets. +-- +-- This routine computes the symmetric difference: +-- +-- X (+) Y = (X \ Y) U (Y \ X), +-- +-- where X and Y are given elemental sets (destroyed on exit). */ + +ELEMSET *set_symdiff +( MPL *mpl, + ELEMSET *X, /* destroyed */ + ELEMSET *Y /* destroyed */ +) +{ ELEMSET *Z; + MEMBER *memb; + xassert(X != NULL); + xassert(X->type == A_NONE); + xassert(X->dim > 0); + xassert(Y != NULL); + xassert(Y->type == A_NONE); + xassert(Y->dim > 0); + xassert(X->dim == Y->dim); + /* Z := X \ Y */ + Z = create_elemset(mpl, X->dim); + for (memb = X->head; memb != NULL; memb = memb->next) + { if (find_tuple(mpl, Y, memb->tuple) == NULL) + add_tuple(mpl, Z, copy_tuple(mpl, memb->tuple)); + } + /* Z := Z U (Y \ X) */ + for (memb = Y->head; memb != NULL; memb = memb->next) + { if (find_tuple(mpl, X, memb->tuple) == NULL) + add_tuple(mpl, Z, copy_tuple(mpl, memb->tuple)); + } + delete_elemset(mpl, X); + delete_elemset(mpl, Y); + return Z; +} + +/*---------------------------------------------------------------------- +-- set_inter - intersection of two elemental sets. +-- +-- This routine computes the intersection: +-- +-- X ^ Y = { j | (j in X) and (j in Y) }, +-- +-- where X and Y are given elemental sets (destroyed on exit). */ + +ELEMSET *set_inter +( MPL *mpl, + ELEMSET *X, /* destroyed */ + ELEMSET *Y /* destroyed */ +) +{ ELEMSET *Z; + MEMBER *memb; + xassert(X != NULL); + xassert(X->type == A_NONE); + xassert(X->dim > 0); + xassert(Y != NULL); + xassert(Y->type == A_NONE); + xassert(Y->dim > 0); + xassert(X->dim == Y->dim); + Z = create_elemset(mpl, X->dim); + for (memb = X->head; memb != NULL; memb = memb->next) + { if (find_tuple(mpl, Y, memb->tuple) != NULL) + add_tuple(mpl, Z, copy_tuple(mpl, memb->tuple)); + } + delete_elemset(mpl, X); + delete_elemset(mpl, Y); + return Z; +} + +/*---------------------------------------------------------------------- +-- set_cross - cross (Cartesian) product of two elemental sets. +-- +-- This routine computes the cross (Cartesian) product: +-- +-- X x Y = { (i,j) | (i in X) and (j in Y) }, +-- +-- where X and Y are given elemental sets (destroyed on exit). */ + +ELEMSET *set_cross +( MPL *mpl, + ELEMSET *X, /* destroyed */ + ELEMSET *Y /* destroyed */ +) +{ ELEMSET *Z; + MEMBER *memx, *memy; + TUPLE *tuple, *temp; + xassert(X != NULL); + xassert(X->type == A_NONE); + xassert(X->dim > 0); + xassert(Y != NULL); + xassert(Y->type == A_NONE); + xassert(Y->dim > 0); + Z = create_elemset(mpl, X->dim + Y->dim); + for (memx = X->head; memx != NULL; memx = memx->next) + { for (memy = Y->head; memy != NULL; memy = memy->next) + { tuple = copy_tuple(mpl, memx->tuple); + for (temp = memy->tuple; temp != NULL; temp = temp->next) + tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, + temp->sym)); + add_tuple(mpl, Z, tuple); + } + } + delete_elemset(mpl, X); + delete_elemset(mpl, Y); + return Z; +} + +/**********************************************************************/ +/* * * ELEMENTAL VARIABLES * * */ +/**********************************************************************/ + +/* (there are no specific routines for elemental variables) */ + +/**********************************************************************/ +/* * * LINEAR FORMS * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- constant_term - create constant term. +-- +-- This routine creates the linear form, which is a constant term. */ + +FORMULA *constant_term(MPL *mpl, double coef) +{ FORMULA *form; + if (coef == 0.0) + form = NULL; + else + { form = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); + form->coef = coef; + form->var = NULL; + form->next = NULL; + } + return form; +} + +/*---------------------------------------------------------------------- +-- single_variable - create single variable. +-- +-- This routine creates the linear form, which is a single elemental +-- variable. */ + +FORMULA *single_variable +( MPL *mpl, + ELEMVAR *var /* referenced */ +) +{ FORMULA *form; + xassert(var != NULL); + form = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); + form->coef = 1.0; + form->var = var; + form->next = NULL; + return form; +} + +/*---------------------------------------------------------------------- +-- copy_formula - make copy of linear form. +-- +-- This routine returns an exact copy of linear form. */ + +FORMULA *copy_formula +( MPL *mpl, + FORMULA *form /* not changed */ +) +{ FORMULA *head, *tail; + if (form == NULL) + head = NULL; + else + { head = tail = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); + for (; form != NULL; form = form->next) + { tail->coef = form->coef; + tail->var = form->var; + if (form->next != NULL) +tail = (tail->next = dmp_get_atom(mpl->formulae, sizeof(FORMULA))); + } + tail->next = NULL; + } + return head; +} + +/*---------------------------------------------------------------------- +-- delete_formula - delete linear form. +-- +-- This routine deletes specified linear form. */ + +void delete_formula +( MPL *mpl, + FORMULA *form /* destroyed */ +) +{ FORMULA *temp; + while (form != NULL) + { temp = form; + form = form->next; + dmp_free_atom(mpl->formulae, temp, sizeof(FORMULA)); + } + return; +} + +/*---------------------------------------------------------------------- +-- linear_comb - linear combination of two linear forms. +-- +-- This routine computes the linear combination: +-- +-- a * fx + b * fy, +-- +-- where a and b are numeric coefficients, fx and fy are linear forms +-- (destroyed on exit). */ + +FORMULA *linear_comb +( MPL *mpl, + double a, FORMULA *fx, /* destroyed */ + double b, FORMULA *fy /* destroyed */ +) +{ FORMULA *form = NULL, *term, *temp; + double c0 = 0.0; + for (term = fx; term != NULL; term = term->next) + { if (term->var == NULL) + c0 = fp_add(mpl, c0, fp_mul(mpl, a, term->coef)); + else + term->var->temp = + fp_add(mpl, term->var->temp, fp_mul(mpl, a, term->coef)); + } + for (term = fy; term != NULL; term = term->next) + { if (term->var == NULL) + c0 = fp_add(mpl, c0, fp_mul(mpl, b, term->coef)); + else + term->var->temp = + fp_add(mpl, term->var->temp, fp_mul(mpl, b, term->coef)); + } + for (term = fx; term != NULL; term = term->next) + { if (term->var != NULL && term->var->temp != 0.0) + { temp = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); + temp->coef = term->var->temp, temp->var = term->var; + temp->next = form, form = temp; + term->var->temp = 0.0; + } + } + for (term = fy; term != NULL; term = term->next) + { if (term->var != NULL && term->var->temp != 0.0) + { temp = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); + temp->coef = term->var->temp, temp->var = term->var; + temp->next = form, form = temp; + term->var->temp = 0.0; + } + } + if (c0 != 0.0) + { temp = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); + temp->coef = c0, temp->var = NULL; + temp->next = form, form = temp; + } + delete_formula(mpl, fx); + delete_formula(mpl, fy); + return form; +} + +/*---------------------------------------------------------------------- +-- remove_constant - remove constant term from linear form. +-- +-- This routine removes constant term from linear form and stores its +-- value to given location. */ + +FORMULA *remove_constant +( MPL *mpl, + FORMULA *form, /* destroyed */ + double *coef /* modified */ +) +{ FORMULA *head = NULL, *temp; + *coef = 0.0; + while (form != NULL) + { temp = form; + form = form->next; + if (temp->var == NULL) + { /* constant term */ + *coef = fp_add(mpl, *coef, temp->coef); + dmp_free_atom(mpl->formulae, temp, sizeof(FORMULA)); + } + else + { /* linear term */ + temp->next = head; + head = temp; + } + } + return head; +} + +/*---------------------------------------------------------------------- +-- reduce_terms - reduce identical terms in linear form. +-- +-- This routine reduces identical terms in specified linear form. */ + +FORMULA *reduce_terms +( MPL *mpl, + FORMULA *form /* destroyed */ +) +{ FORMULA *term, *next_term; + double c0 = 0.0; + for (term = form; term != NULL; term = term->next) + { if (term->var == NULL) + c0 = fp_add(mpl, c0, term->coef); + else + term->var->temp = fp_add(mpl, term->var->temp, term->coef); + } + next_term = form, form = NULL; + for (term = next_term; term != NULL; term = next_term) + { next_term = term->next; + if (term->var == NULL && c0 != 0.0) + { term->coef = c0, c0 = 0.0; + term->next = form, form = term; + } + else if (term->var != NULL && term->var->temp != 0.0) + { term->coef = term->var->temp, term->var->temp = 0.0; + term->next = form, form = term; + } + else + dmp_free_atom(mpl->formulae, term, sizeof(FORMULA)); + } + return form; +} + +/**********************************************************************/ +/* * * ELEMENTAL CONSTRAINTS * * */ +/**********************************************************************/ + +/* (there are no specific routines for elemental constraints) */ + +/**********************************************************************/ +/* * * GENERIC VALUES * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- delete_value - delete generic value. +-- +-- This routine deletes specified generic value. +-- +-- NOTE: The generic value to be deleted must be valid. */ + +void delete_value +( MPL *mpl, + int type, + VALUE *value /* content destroyed */ +) +{ xassert(value != NULL); + switch (type) + { case A_NONE: + value->none = NULL; + break; + case A_NUMERIC: + value->num = 0.0; + break; + case A_SYMBOLIC: + delete_symbol(mpl, value->sym), value->sym = NULL; + break; + case A_LOGICAL: + value->bit = 0; + break; + case A_TUPLE: + delete_tuple(mpl, value->tuple), value->tuple = NULL; + break; + case A_ELEMSET: + delete_elemset(mpl, value->set), value->set = NULL; + break; + case A_ELEMVAR: + value->var = NULL; + break; + case A_FORMULA: + delete_formula(mpl, value->form), value->form = NULL; + break; + case A_ELEMCON: + value->con = NULL; + break; + default: + xassert(type != type); + } + return; +} + +/**********************************************************************/ +/* * * SYMBOLICALLY INDEXED ARRAYS * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- create_array - create array. +-- +-- This routine creates an array of specified type and dimension. Being +-- created the array is initially empty. +-- +-- The type indicator determines generic values, which can be assigned +-- to the array members: +-- +-- A_NONE - none (members have no assigned values) +-- A_NUMERIC - floating-point numbers +-- A_SYMBOLIC - symbols +-- A_ELEMSET - elemental sets +-- A_ELEMVAR - elemental variables +-- A_ELEMCON - elemental constraints +-- +-- The dimension may be 0, in which case the array consists of the only +-- member (such arrays represent 0-dimensional objects). */ + +ARRAY *create_array(MPL *mpl, int type, int dim) +{ ARRAY *array; + xassert(type == A_NONE || type == A_NUMERIC || + type == A_SYMBOLIC || type == A_ELEMSET || + type == A_ELEMVAR || type == A_ELEMCON); + xassert(dim >= 0); + array = dmp_get_atom(mpl->arrays, sizeof(ARRAY)); + array->type = type; + array->dim = dim; + array->size = 0; + array->head = NULL; + array->tail = NULL; + array->tree = NULL; + array->prev = NULL; + array->next = mpl->a_list; + /* include the array in the global array list */ + if (array->next != NULL) array->next->prev = array; + mpl->a_list = array; + return array; +} + +/*---------------------------------------------------------------------- +-- find_member - find array member with given n-tuple. +-- +-- This routine finds an array member, which has given n-tuple. If the +-- array is short, the linear search is used. Otherwise the routine +-- autimatically creates the search tree (i.e. the array index) to find +-- members for logarithmic time. */ + +static int compare_member_tuples(void *info, const void *key1, + const void *key2) +{ /* this is an auxiliary routine used to compare keys, which are + n-tuples assigned to array members */ + return compare_tuples((MPL *)info, (TUPLE *)key1, (TUPLE *)key2); +} + +MEMBER *find_member +( MPL *mpl, + ARRAY *array, /* not changed */ + TUPLE *tuple /* not changed */ +) +{ MEMBER *memb; + xassert(array != NULL); + /* the n-tuple must have the same dimension as the array */ + xassert(tuple_dimen(mpl, tuple) == array->dim); + /* if the array is large enough, create the search tree and index + all existing members of the array */ + if (array->size > 30 && array->tree == NULL) + { array->tree = avl_create_tree(compare_member_tuples, mpl); + for (memb = array->head; memb != NULL; memb = memb->next) +avl_set_node_link(avl_insert_node(array->tree, memb->tuple), + (void *)memb); + } + /* find a member, which has the given tuple */ + if (array->tree == NULL) + { /* the search tree doesn't exist; use the linear search */ + for (memb = array->head; memb != NULL; memb = memb->next) + if (compare_tuples(mpl, memb->tuple, tuple) == 0) break; + } + else + { /* the search tree exists; use the binary search */ + AVLNODE *node; + node = avl_find_node(array->tree, tuple); +memb = (MEMBER *)(node == NULL ? NULL : avl_get_node_link(node)); + } + return memb; +} + +/*---------------------------------------------------------------------- +-- add_member - add new member to array. +-- +-- This routine creates a new member with given n-tuple and adds it to +-- specified array. +-- +-- For the sake of efficiency this routine doesn't check whether the +-- array already contains a member with the given n-tuple or not. Thus, +-- if necessary, the calling program should use the routine find_member +-- in order to be sure that the array contains no member with the same +-- n-tuple, because members with duplicate n-tuples are not allowed. +-- +-- This routine assigns no generic value to the new member, because the +-- calling program must do that. */ + +MEMBER *add_member +( MPL *mpl, + ARRAY *array, /* modified */ + TUPLE *tuple /* destroyed */ +) +{ MEMBER *memb; + xassert(array != NULL); + /* the n-tuple must have the same dimension as the array */ + xassert(tuple_dimen(mpl, tuple) == array->dim); + /* create new member */ + memb = dmp_get_atom(mpl->members, sizeof(MEMBER)); + memb->tuple = tuple; + memb->next = NULL; + memset(&memb->value, '?', sizeof(VALUE)); + /* and append it to the member list */ + array->size++; + if (array->head == NULL) + array->head = memb; + else + array->tail->next = memb; + array->tail = memb; + /* if the search tree exists, index the new member */ + if (array->tree != NULL) +avl_set_node_link(avl_insert_node(array->tree, memb->tuple), + (void *)memb); + return memb; +} + +/*---------------------------------------------------------------------- +-- delete_array - delete array. +-- +-- This routine deletes specified array. +-- +-- Generic values assigned to the array members are not deleted by this +-- routine. The calling program itself must delete all assigned generic +-- values before deleting the array. */ + +void delete_array +( MPL *mpl, + ARRAY *array /* destroyed */ +) +{ MEMBER *memb; + xassert(array != NULL); + /* delete all existing array members */ + while (array->head != NULL) + { memb = array->head; + array->head = memb->next; + delete_tuple(mpl, memb->tuple); + dmp_free_atom(mpl->members, memb, sizeof(MEMBER)); + } + /* if the search tree exists, also delete it */ + if (array->tree != NULL) avl_delete_tree(array->tree); + /* remove the array from the global array list */ + if (array->prev == NULL) + mpl->a_list = array->next; + else + array->prev->next = array->next; + if (array->next == NULL) + ; + else + array->next->prev = array->prev; + /* delete the array descriptor */ + dmp_free_atom(mpl->arrays, array, sizeof(ARRAY)); + return; +} + +/**********************************************************************/ +/* * * DOMAINS AND DUMMY INDICES * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- assign_dummy_index - assign new value to dummy index. +-- +-- This routine assigns new value to specified dummy index and, that is +-- important, invalidates all temporary resultant values, which depends +-- on that dummy index. */ + +void assign_dummy_index +( MPL *mpl, + DOMAIN_SLOT *slot, /* modified */ + SYMBOL *value /* not changed */ +) +{ CODE *leaf, *code; + xassert(slot != NULL); + xassert(value != NULL); + /* delete the current value assigned to the dummy index */ + if (slot->value != NULL) + { /* if the current value and the new one are identical, actual + assignment is not needed */ + if (compare_symbols(mpl, slot->value, value) == 0) goto done; + /* delete a symbol, which is the current value */ + delete_symbol(mpl, slot->value), slot->value = NULL; + } + /* now walk through all the pseudo-codes with op = O_INDEX, which + refer to the dummy index to be changed (these pseudo-codes are + leaves in the forest of *all* expressions in the database) */ + for (leaf = slot->list; leaf != NULL; leaf = leaf->arg.index. + next) + { xassert(leaf->op == O_INDEX); + /* invalidate all resultant values, which depend on the dummy + index, walking from the current leaf toward the root of the + corresponding expression tree */ + for (code = leaf; code != NULL; code = code->up) + { if (code->valid) + { /* invalidate and delete resultant value */ + code->valid = 0; + delete_value(mpl, code->type, &code->value); + } + } + } + /* assign new value to the dummy index */ + slot->value = copy_symbol(mpl, value); +done: return; +} + +/*---------------------------------------------------------------------- +-- update_dummy_indices - update current values of dummy indices. +-- +-- This routine assigns components of "backup" n-tuple to dummy indices +-- of specified domain block. If no "backup" n-tuple is defined for the +-- domain block, values of the dummy indices remain untouched. */ + +void update_dummy_indices +( MPL *mpl, + DOMAIN_BLOCK *block /* not changed */ +) +{ DOMAIN_SLOT *slot; + TUPLE *temp; + if (block->backup != NULL) + { for (slot = block->list, temp = block->backup; slot != NULL; + slot = slot->next, temp = temp->next) + { xassert(temp != NULL); + xassert(temp->sym != NULL); + assign_dummy_index(mpl, slot, temp->sym); + } + } + return; +} + +/*---------------------------------------------------------------------- +-- enter_domain_block - enter domain block. +-- +-- Let specified domain block have the form: +-- +-- { ..., (j1, j2, ..., jn) in J, ... } +-- +-- where j1, j2, ..., jn are dummy indices, J is a basic set. +-- +-- This routine does the following: +-- +-- 1. Checks if the given n-tuple is a member of the basic set J. Note +-- that J being *out of the scope* of the domain block cannot depend +-- on the dummy indices in the same and inner domain blocks, so it +-- can be computed before the dummy indices are assigned new values. +-- If this check fails, the routine returns with non-zero code. +-- +-- 2. Saves current values of the dummy indices j1, j2, ..., jn. +-- +-- 3. Assigns new values, which are components of the given n-tuple, to +-- the dummy indices j1, j2, ..., jn. If dimension of the n-tuple is +-- larger than n, its extra components n+1, n+2, ... are not used. +-- +-- 4. Calls the formal routine func which either enters the next domain +-- block or evaluates some code within the domain scope. +-- +-- 5. Restores former values of the dummy indices j1, j2, ..., jn. +-- +-- Since current values assigned to the dummy indices on entry to this +-- routine are restored on exit, the formal routine func is allowed to +-- call this routine recursively. */ + +int enter_domain_block +( MPL *mpl, + DOMAIN_BLOCK *block, /* not changed */ + TUPLE *tuple, /* not changed */ + void *info, void (*func)(MPL *mpl, void *info) +) +{ TUPLE *backup; + int ret = 0; + /* check if the given n-tuple is a member of the basic set */ + xassert(block->code != NULL); + if (!is_member(mpl, block->code, tuple)) + { ret = 1; + goto done; + } + /* save reference to "backup" n-tuple, which was used to assign + current values of the dummy indices (it is sufficient to save + reference, not value, because that n-tuple is defined in some + outer level of recursion and therefore cannot be changed on + this and deeper recursive calls) */ + backup = block->backup; + /* set up new "backup" n-tuple, which defines new values of the + dummy indices */ + block->backup = tuple; + /* assign new values to the dummy indices */ + update_dummy_indices(mpl, block); + /* call the formal routine that does the rest part of the job */ + func(mpl, info); + /* restore reference to the former "backup" n-tuple */ + block->backup = backup; + /* restore former values of the dummy indices; note that if the + domain block just escaped has no other active instances which + may exist due to recursion (it is indicated by a null pointer + to the former n-tuple), former values of the dummy indices are + undefined; therefore in this case the routine keeps currently + assigned values of the dummy indices that involves keeping all + dependent temporary results and thereby, if this domain block + is not used recursively, allows improving efficiency */ + update_dummy_indices(mpl, block); +done: return ret; +} + +/*---------------------------------------------------------------------- +-- eval_within_domain - perform evaluation within domain scope. +-- +-- This routine assigns new values (symbols) to all dummy indices of +-- specified domain and calls the formal routine func, which is used to +-- evaluate some code in the domain scope. Each free dummy index in the +-- domain is assigned a value specified in the corresponding component +-- of given n-tuple. Non-free dummy indices are assigned values, which +-- are computed by this routine. +-- +-- Number of components in the given n-tuple must be the same as number +-- of free indices in the domain. +-- +-- If the given n-tuple is not a member of the domain set, the routine +-- func is not called, and non-zero code is returned. +-- +-- For the sake of convenience it is allowed to specify domain as NULL +-- (then n-tuple also must be 0-tuple, i.e. empty), in which case this +-- routine just calls the routine func and returns zero. +-- +-- This routine allows recursive calls from the routine func providing +-- correct values of dummy indices for each instance. +-- +-- NOTE: The n-tuple passed to this routine must not be changed by any +-- other routines called from the formal routine func until this +-- routine has returned. */ + +struct eval_domain_info +{ /* working info used by the routine eval_within_domain */ + DOMAIN *domain; + /* domain, which has to be entered */ + DOMAIN_BLOCK *block; + /* domain block, which is currently processed */ + TUPLE *tuple; + /* tail of original n-tuple, whose components have to be assigned + to free dummy indices in the current domain block */ + void *info; + /* transit pointer passed to the formal routine func */ + void (*func)(MPL *mpl, void *info); + /* routine, which has to be executed in the domain scope */ + int failure; + /* this flag indicates that given n-tuple is not a member of the + domain set */ +}; + +static void eval_domain_func(MPL *mpl, void *_my_info) +{ /* this routine recursively enters into the domain scope and then + calls the routine func */ + struct eval_domain_info *my_info = _my_info; + if (my_info->block != NULL) + { /* the current domain block to be entered exists */ + DOMAIN_BLOCK *block; + DOMAIN_SLOT *slot; + TUPLE *tuple = NULL, *temp = NULL; + /* save pointer to the current domain block */ + block = my_info->block; + /* and get ready to enter the next block (if it exists) */ + my_info->block = block->next; + /* construct temporary n-tuple, whose components correspond to + dummy indices (slots) of the current domain; components of + the temporary n-tuple that correspond to free dummy indices + are assigned references (not values!) to symbols specified + in the corresponding components of the given n-tuple, while + other components that correspond to non-free dummy indices + are assigned symbolic values computed here */ + for (slot = block->list; slot != NULL; slot = slot->next) + { /* create component that corresponds to the current slot */ + if (tuple == NULL) + tuple = temp = dmp_get_atom(mpl->tuples, sizeof(TUPLE)); + else +temp = (temp->next = dmp_get_atom(mpl->tuples, sizeof(TUPLE))); + if (slot->code == NULL) + { /* dummy index is free; take reference to symbol, which + is specified in the corresponding component of given + n-tuple */ + xassert(my_info->tuple != NULL); + temp->sym = my_info->tuple->sym; + xassert(temp->sym != NULL); + my_info->tuple = my_info->tuple->next; + } + else + { /* dummy index is non-free; compute symbolic value to be + temporarily assigned to the dummy index */ + temp->sym = eval_symbolic(mpl, slot->code); + } + } + temp->next = NULL; + /* enter the current domain block */ + if (enter_domain_block(mpl, block, tuple, my_info, + eval_domain_func)) my_info->failure = 1; + /* delete temporary n-tuple as well as symbols that correspond + to non-free dummy indices (they were computed here) */ + for (slot = block->list; slot != NULL; slot = slot->next) + { xassert(tuple != NULL); + temp = tuple; + tuple = tuple->next; + if (slot->code != NULL) + { /* dummy index is non-free; delete symbolic value */ + delete_symbol(mpl, temp->sym); + } + /* delete component that corresponds to the current slot */ + dmp_free_atom(mpl->tuples, temp, sizeof(TUPLE)); + } + } + else + { /* there are no more domain blocks, i.e. we have reached the + domain scope */ + xassert(my_info->tuple == NULL); + /* check optional predicate specified for the domain */ + if (my_info->domain->code != NULL && !eval_logical(mpl, + my_info->domain->code)) + { /* the predicate is false */ + my_info->failure = 2; + } + else + { /* the predicate is true; do the job */ + my_info->func(mpl, my_info->info); + } + } + return; +} + +int eval_within_domain +( MPL *mpl, + DOMAIN *domain, /* not changed */ + TUPLE *tuple, /* not changed */ + void *info, void (*func)(MPL *mpl, void *info) +) +{ /* this routine performs evaluation within domain scope */ + struct eval_domain_info _my_info, *my_info = &_my_info; + if (domain == NULL) + { xassert(tuple == NULL); + func(mpl, info); + my_info->failure = 0; + } + else + { xassert(tuple != NULL); + my_info->domain = domain; + my_info->block = domain->list; + my_info->tuple = tuple; + my_info->info = info; + my_info->func = func; + my_info->failure = 0; + /* enter the very first domain block */ + eval_domain_func(mpl, my_info); + } + return my_info->failure; +} + +/*---------------------------------------------------------------------- +-- loop_within_domain - perform iterations within domain scope. +-- +-- This routine iteratively assigns new values (symbols) to the dummy +-- indices of specified domain by enumerating all n-tuples, which are +-- members of the domain set, and for every n-tuple it calls the formal +-- routine func to evaluate some code within the domain scope. +-- +-- If the routine func returns non-zero, enumeration within the domain +-- is prematurely terminated. +-- +-- For the sake of convenience it is allowed to specify domain as NULL, +-- in which case this routine just calls the routine func only once and +-- returns zero. +-- +-- This routine allows recursive calls from the routine func providing +-- correct values of dummy indices for each instance. */ + +struct loop_domain_info +{ /* working info used by the routine loop_within_domain */ + DOMAIN *domain; + /* domain, which has to be entered */ + DOMAIN_BLOCK *block; + /* domain block, which is currently processed */ + int looping; + /* clearing this flag leads to terminating enumeration */ + void *info; + /* transit pointer passed to the formal routine func */ + int (*func)(MPL *mpl, void *info); + /* routine, which needs to be executed in the domain scope */ +}; + +static void loop_domain_func(MPL *mpl, void *_my_info) +{ /* this routine enumerates all n-tuples in the basic set of the + current domain block, enters recursively into the domain scope + for every n-tuple, and then calls the routine func */ + struct loop_domain_info *my_info = _my_info; + if (my_info->block != NULL) + { /* the current domain block to be entered exists */ + DOMAIN_BLOCK *block; + DOMAIN_SLOT *slot; + TUPLE *bound; + /* save pointer to the current domain block */ + block = my_info->block; + /* and get ready to enter the next block (if it exists) */ + my_info->block = block->next; + /* compute symbolic values, at which non-free dummy indices of + the current domain block are bound; since that values don't + depend on free dummy indices of the current block, they can + be computed once out of the enumeration loop */ + bound = create_tuple(mpl); + for (slot = block->list; slot != NULL; slot = slot->next) + { if (slot->code != NULL) + bound = expand_tuple(mpl, bound, eval_symbolic(mpl, + slot->code)); + } + /* start enumeration */ + xassert(block->code != NULL); + if (block->code->op == O_DOTS) + { /* the basic set is "arithmetic", in which case it doesn't + need to be computed explicitly */ + TUPLE *tuple; + int n, j; + double t0, tf, dt; + /* compute "parameters" of the basic set */ + t0 = eval_numeric(mpl, block->code->arg.arg.x); + tf = eval_numeric(mpl, block->code->arg.arg.y); + if (block->code->arg.arg.z == NULL) + dt = 1.0; + else + dt = eval_numeric(mpl, block->code->arg.arg.z); + /* determine cardinality of the basic set */ + n = arelset_size(mpl, t0, tf, dt); + /* create dummy 1-tuple for members of the basic set */ + tuple = expand_tuple(mpl, create_tuple(mpl), + create_symbol_num(mpl, 0.0)); + /* in case of "arithmetic" set there is exactly one dummy + index, which cannot be non-free */ + xassert(bound == NULL); + /* walk through 1-tuples of the basic set */ + for (j = 1; j <= n && my_info->looping; j++) + { /* construct dummy 1-tuple for the current member */ + tuple->sym->num = arelset_member(mpl, t0, tf, dt, j); + /* enter the current domain block */ + enter_domain_block(mpl, block, tuple, my_info, + loop_domain_func); + } + /* delete dummy 1-tuple */ + delete_tuple(mpl, tuple); + } + else + { /* the basic set is of general kind, in which case it needs + to be explicitly computed */ + ELEMSET *set; + MEMBER *memb; + TUPLE *temp1, *temp2; + /* compute the basic set */ + set = eval_elemset(mpl, block->code); + /* walk through all n-tuples of the basic set */ + for (memb = set->head; memb != NULL && my_info->looping; + memb = memb->next) + { /* all components of the current n-tuple that correspond + to non-free dummy indices must be feasible; otherwise + the n-tuple is not in the basic set */ + temp1 = memb->tuple; + temp2 = bound; + for (slot = block->list; slot != NULL; slot = slot->next) + { xassert(temp1 != NULL); + if (slot->code != NULL) + { /* non-free dummy index */ + xassert(temp2 != NULL); + if (compare_symbols(mpl, temp1->sym, temp2->sym) + != 0) + { /* the n-tuple is not in the basic set */ + goto skip; + } + temp2 = temp2->next; + } + temp1 = temp1->next; + } + xassert(temp1 == NULL); + xassert(temp2 == NULL); + /* enter the current domain block */ + enter_domain_block(mpl, block, memb->tuple, my_info, + loop_domain_func); +skip: ; + } + /* delete the basic set */ + delete_elemset(mpl, set); + } + /* delete symbolic values binding non-free dummy indices */ + delete_tuple(mpl, bound); + /* restore pointer to the current domain block */ + my_info->block = block; + } + else + { /* there are no more domain blocks, i.e. we have reached the + domain scope */ + /* check optional predicate specified for the domain */ + if (my_info->domain->code != NULL && !eval_logical(mpl, + my_info->domain->code)) + { /* the predicate is false */ + /* nop */; + } + else + { /* the predicate is true; do the job */ + my_info->looping = !my_info->func(mpl, my_info->info); + } + } + return; +} + +void loop_within_domain +( MPL *mpl, + DOMAIN *domain, /* not changed */ + void *info, int (*func)(MPL *mpl, void *info) +) +{ /* this routine performs iterations within domain scope */ + struct loop_domain_info _my_info, *my_info = &_my_info; + if (domain == NULL) + func(mpl, info); + else + { my_info->domain = domain; + my_info->block = domain->list; + my_info->looping = 1; + my_info->info = info; + my_info->func = func; + /* enter the very first domain block */ + loop_domain_func(mpl, my_info); + } + return; +} + +/*---------------------------------------------------------------------- +-- out_of_domain - raise domain exception. +-- +-- This routine is called when a reference is made to a member of some +-- model object, but its n-tuple is out of the object domain. */ + +void out_of_domain +( MPL *mpl, + char *name, /* not changed */ + TUPLE *tuple /* not changed */ +) +{ xassert(name != NULL); + xassert(tuple != NULL); + error(mpl, "%s%s out of domain", name, format_tuple(mpl, '[', + tuple)); + /* no return */ +} + +/*---------------------------------------------------------------------- +-- get_domain_tuple - obtain current n-tuple from domain. +-- +-- This routine constructs n-tuple, whose components are current values +-- assigned to *free* dummy indices of specified domain. +-- +-- For the sake of convenience it is allowed to specify domain as NULL, +-- in which case this routine returns 0-tuple. +-- +-- NOTE: This routine must not be called out of domain scope. */ + +TUPLE *get_domain_tuple +( MPL *mpl, + DOMAIN *domain /* not changed */ +) +{ DOMAIN_BLOCK *block; + DOMAIN_SLOT *slot; + TUPLE *tuple; + tuple = create_tuple(mpl); + if (domain != NULL) + { for (block = domain->list; block != NULL; block = block->next) + { for (slot = block->list; slot != NULL; slot = slot->next) + { if (slot->code == NULL) + { xassert(slot->value != NULL); + tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, + slot->value)); + } + } + } + } + return tuple; +} + +/*---------------------------------------------------------------------- +-- clean_domain - clean domain. +-- +-- This routine cleans specified domain that assumes deleting all stuff +-- dynamically allocated during the generation phase. */ + +void clean_domain(MPL *mpl, DOMAIN *domain) +{ DOMAIN_BLOCK *block; + DOMAIN_SLOT *slot; + /* if no domain is specified, do nothing */ + if (domain == NULL) goto done; + /* clean all domain blocks */ + for (block = domain->list; block != NULL; block = block->next) + { /* clean all domain slots */ + for (slot = block->list; slot != NULL; slot = slot->next) + { /* clean pseudo-code for computing bound value */ + clean_code(mpl, slot->code); + /* delete symbolic value assigned to dummy index */ + if (slot->value != NULL) + delete_symbol(mpl, slot->value), slot->value = NULL; + } + /* clean pseudo-code for computing basic set */ + clean_code(mpl, block->code); + } + /* clean pseudo-code for computing domain predicate */ + clean_code(mpl, domain->code); +done: return; +} + +/**********************************************************************/ +/* * * MODEL SETS * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- check_elem_set - check elemental set assigned to set member. +-- +-- This routine checks if given elemental set being assigned to member +-- of specified model set satisfies to all restrictions. +-- +-- NOTE: This routine must not be called out of domain scope. */ + +void check_elem_set +( MPL *mpl, + SET *set, /* not changed */ + TUPLE *tuple, /* not changed */ + ELEMSET *refer /* not changed */ +) +{ WITHIN *within; + MEMBER *memb; + int eqno; + /* elemental set must be within all specified supersets */ + for (within = set->within, eqno = 1; within != NULL; within = + within->next, eqno++) + { xassert(within->code != NULL); + for (memb = refer->head; memb != NULL; memb = memb->next) + { if (!is_member(mpl, within->code, memb->tuple)) + { char buf[255+1]; + strcpy(buf, format_tuple(mpl, '(', memb->tuple)); + xassert(strlen(buf) < sizeof(buf)); + error(mpl, "%s%s contains %s which not within specified " + "set; see (%d)", set->name, format_tuple(mpl, '[', + tuple), buf, eqno); + } + } + } + return; +} + +/*---------------------------------------------------------------------- +-- take_member_set - obtain elemental set assigned to set member. +-- +-- This routine obtains a reference to elemental set assigned to given +-- member of specified model set and returns it on exit. +-- +-- NOTE: This routine must not be called out of domain scope. */ + +ELEMSET *take_member_set /* returns reference, not value */ +( MPL *mpl, + SET *set, /* not changed */ + TUPLE *tuple /* not changed */ +) +{ MEMBER *memb; + ELEMSET *refer; + /* find member in the set array */ + memb = find_member(mpl, set->array, tuple); + if (memb != NULL) + { /* member exists, so just take the reference */ + refer = memb->value.set; + } + else if (set->assign != NULL) + { /* compute value using assignment expression */ + refer = eval_elemset(mpl, set->assign); +add: /* check that the elemental set satisfies to all restrictions, + assign it to new member, and add the member to the array */ + check_elem_set(mpl, set, tuple, refer); + memb = add_member(mpl, set->array, copy_tuple(mpl, tuple)); + memb->value.set = refer; + } + else if (set->option != NULL) + { /* compute default elemental set */ + refer = eval_elemset(mpl, set->option); + goto add; + } + else + { /* no value (elemental set) is provided */ + error(mpl, "no value for %s%s", set->name, format_tuple(mpl, + '[', tuple)); + } + return refer; +} + +/*---------------------------------------------------------------------- +-- eval_member_set - evaluate elemental set assigned to set member. +-- +-- This routine evaluates a reference to elemental set assigned to given +-- member of specified model set and returns it on exit. */ + +struct eval_set_info +{ /* working info used by the routine eval_member_set */ + SET *set; + /* model set */ + TUPLE *tuple; + /* n-tuple, which defines set member */ + MEMBER *memb; + /* normally this pointer is NULL; the routine uses this pointer + to check data provided in the data section, in which case it + points to a member currently checked; this check is performed + automatically only once when a reference to any member occurs + for the first time */ + ELEMSET *refer; + /* evaluated reference to elemental set */ +}; + +static void eval_set_func(MPL *mpl, void *_info) +{ /* this is auxiliary routine to work within domain scope */ + struct eval_set_info *info = _info; + if (info->memb != NULL) + { /* checking call; check elemental set being assigned */ + check_elem_set(mpl, info->set, info->memb->tuple, + info->memb->value.set); + } + else + { /* normal call; evaluate member, which has given n-tuple */ + info->refer = take_member_set(mpl, info->set, info->tuple); + } + return; +} + +#if 1 /* 12/XII-2008 */ +static void saturate_set(MPL *mpl, SET *set) +{ GADGET *gadget = set->gadget; + ELEMSET *data; + MEMBER *elem, *memb; + TUPLE *tuple, *work[20]; + int i; + xprintf("Generating %s...\n", set->name); + eval_whole_set(mpl, gadget->set); + /* gadget set must have exactly one member */ + xassert(gadget->set->array != NULL); + xassert(gadget->set->array->head != NULL); + xassert(gadget->set->array->head == gadget->set->array->tail); + data = gadget->set->array->head->value.set; + xassert(data->type == A_NONE); + xassert(data->dim == gadget->set->dimen); + /* walk thru all elements of the plain set */ + for (elem = data->head; elem != NULL; elem = elem->next) + { /* create a copy of n-tuple */ + tuple = copy_tuple(mpl, elem->tuple); + /* rearrange component of the n-tuple */ + for (i = 0; i < gadget->set->dimen; i++) + work[i] = NULL; + for (i = 0; tuple != NULL; tuple = tuple->next) + work[gadget->ind[i++]-1] = tuple; + xassert(i == gadget->set->dimen); + for (i = 0; i < gadget->set->dimen; i++) + { xassert(work[i] != NULL); + work[i]->next = work[i+1]; + } + /* construct subscript list from first set->dim components */ + if (set->dim == 0) + tuple = NULL; + else + tuple = work[0], work[set->dim-1]->next = NULL; + /* find corresponding member of the set to be initialized */ + memb = find_member(mpl, set->array, tuple); + if (memb == NULL) + { /* not found; add new member to the set and assign it empty + elemental set */ + memb = add_member(mpl, set->array, tuple); + memb->value.set = create_elemset(mpl, set->dimen); + } + else + { /* found; free subscript list */ + delete_tuple(mpl, tuple); + } + /* construct new n-tuple from rest set->dimen components */ + tuple = work[set->dim]; + xassert(set->dim + set->dimen == gadget->set->dimen); + work[gadget->set->dimen-1]->next = NULL; + /* and add it to the elemental set assigned to the member + (no check for duplicates is needed) */ + add_tuple(mpl, memb->value.set, tuple); + } + /* the set has been saturated with data */ + set->data = 1; + return; +} +#endif + +ELEMSET *eval_member_set /* returns reference, not value */ +( MPL *mpl, + SET *set, /* not changed */ + TUPLE *tuple /* not changed */ +) +{ /* this routine evaluates set member */ + struct eval_set_info _info, *info = &_info; + xassert(set->dim == tuple_dimen(mpl, tuple)); + info->set = set; + info->tuple = tuple; +#if 1 /* 12/XII-2008 */ + if (set->gadget != NULL && set->data == 0) + { /* initialize the set with data from a plain set */ + saturate_set(mpl, set); + } +#endif + if (set->data == 1) + { /* check data, which are provided in the data section, but not + checked yet */ + /* save pointer to the last array member; note that during the + check new members may be added beyond the last member due to + references to the same parameter from default expression as + well as from expressions that define restricting supersets; + however, values assigned to the new members will be checked + by other routine, so we don't need to check them here */ + MEMBER *tail = set->array->tail; + /* change the data status to prevent infinite recursive loop + due to references to the same set during the check */ + set->data = 2; + /* check elemental sets assigned to array members in the data + section until the marked member has been reached */ + for (info->memb = set->array->head; info->memb != NULL; + info->memb = info->memb->next) + { if (eval_within_domain(mpl, set->domain, info->memb->tuple, + info, eval_set_func)) + out_of_domain(mpl, set->name, info->memb->tuple); + if (info->memb == tail) break; + } + /* the check has been finished */ + } + /* evaluate member, which has given n-tuple */ + info->memb = NULL; + if (eval_within_domain(mpl, info->set->domain, info->tuple, info, + eval_set_func)) + out_of_domain(mpl, set->name, info->tuple); + /* bring evaluated reference to the calling program */ + return info->refer; +} + +/*---------------------------------------------------------------------- +-- eval_whole_set - evaluate model set over entire domain. +-- +-- This routine evaluates all members of specified model set over entire +-- domain. */ + +static int whole_set_func(MPL *mpl, void *info) +{ /* this is auxiliary routine to work within domain scope */ + SET *set = (SET *)info; + TUPLE *tuple = get_domain_tuple(mpl, set->domain); + eval_member_set(mpl, set, tuple); + delete_tuple(mpl, tuple); + return 0; +} + +void eval_whole_set(MPL *mpl, SET *set) +{ loop_within_domain(mpl, set->domain, set, whole_set_func); + return; +} + +/*---------------------------------------------------------------------- +-- clean set - clean model set. +-- +-- This routine cleans specified model set that assumes deleting all +-- stuff dynamically allocated during the generation phase. */ + +void clean_set(MPL *mpl, SET *set) +{ WITHIN *within; + MEMBER *memb; + /* clean subscript domain */ + clean_domain(mpl, set->domain); + /* clean pseudo-code for computing supersets */ + for (within = set->within; within != NULL; within = within->next) + clean_code(mpl, within->code); + /* clean pseudo-code for computing assigned value */ + clean_code(mpl, set->assign); + /* clean pseudo-code for computing default value */ + clean_code(mpl, set->option); + /* reset data status flag */ + set->data = 0; + /* delete content array */ + for (memb = set->array->head; memb != NULL; memb = memb->next) + delete_value(mpl, set->array->type, &memb->value); + delete_array(mpl, set->array), set->array = NULL; + return; +} + +/**********************************************************************/ +/* * * MODEL PARAMETERS * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- check_value_num - check numeric value assigned to parameter member. +-- +-- This routine checks if numeric value being assigned to some member +-- of specified numeric model parameter satisfies to all restrictions. +-- +-- NOTE: This routine must not be called out of domain scope. */ + +void check_value_num +( MPL *mpl, + PARAMETER *par, /* not changed */ + TUPLE *tuple, /* not changed */ + double value +) +{ CONDITION *cond; + WITHIN *in; + int eqno; + /* the value must satisfy to the parameter type */ + switch (par->type) + { case A_NUMERIC: + break; + case A_INTEGER: + if (value != floor(value)) + error(mpl, "%s%s = %.*g not integer", par->name, + format_tuple(mpl, '[', tuple), DBL_DIG, value); + break; + case A_BINARY: + if (!(value == 0.0 || value == 1.0)) + error(mpl, "%s%s = %.*g not binary", par->name, + format_tuple(mpl, '[', tuple), DBL_DIG, value); + break; + default: + xassert(par != par); + } + /* the value must satisfy to all specified conditions */ + for (cond = par->cond, eqno = 1; cond != NULL; cond = cond->next, + eqno++) + { double bound; + char *rho; + xassert(cond->code != NULL); + bound = eval_numeric(mpl, cond->code); + switch (cond->rho) + { case O_LT: + if (!(value < bound)) + { rho = "<"; +err: error(mpl, "%s%s = %.*g not %s %.*g; see (%d)", + par->name, format_tuple(mpl, '[', tuple), DBL_DIG, + value, rho, DBL_DIG, bound, eqno); + } + break; + case O_LE: + if (!(value <= bound)) { rho = "<="; goto err; } + break; + case O_EQ: + if (!(value == bound)) { rho = "="; goto err; } + break; + case O_GE: + if (!(value >= bound)) { rho = ">="; goto err; } + break; + case O_GT: + if (!(value > bound)) { rho = ">"; goto err; } + break; + case O_NE: + if (!(value != bound)) { rho = "<>"; goto err; } + break; + default: + xassert(cond != cond); + } + } + /* the value must be in all specified supersets */ + for (in = par->in, eqno = 1; in != NULL; in = in->next, eqno++) + { TUPLE *dummy; + xassert(in->code != NULL); + xassert(in->code->dim == 1); + dummy = expand_tuple(mpl, create_tuple(mpl), + create_symbol_num(mpl, value)); + if (!is_member(mpl, in->code, dummy)) + error(mpl, "%s%s = %.*g not in specified set; see (%d)", + par->name, format_tuple(mpl, '[', tuple), DBL_DIG, + value, eqno); + delete_tuple(mpl, dummy); + } + return; +} + +/*---------------------------------------------------------------------- +-- take_member_num - obtain num. value assigned to parameter member. +-- +-- This routine obtains a numeric value assigned to member of specified +-- numeric model parameter and returns it on exit. +-- +-- NOTE: This routine must not be called out of domain scope. */ + +double take_member_num +( MPL *mpl, + PARAMETER *par, /* not changed */ + TUPLE *tuple /* not changed */ +) +{ MEMBER *memb; + double value; + /* find member in the parameter array */ + memb = find_member(mpl, par->array, tuple); + if (memb != NULL) + { /* member exists, so just take its value */ + value = memb->value.num; + } + else if (par->assign != NULL) + { /* compute value using assignment expression */ + value = eval_numeric(mpl, par->assign); +add: /* check that the value satisfies to all restrictions, assign + it to new member, and add the member to the array */ + check_value_num(mpl, par, tuple, value); + memb = add_member(mpl, par->array, copy_tuple(mpl, tuple)); + memb->value.num = value; + } + else if (par->option != NULL) + { /* compute default value */ + value = eval_numeric(mpl, par->option); + goto add; + } + else if (par->defval != NULL) + { /* take default value provided in the data section */ + if (par->defval->str != NULL) + error(mpl, "cannot convert %s to floating-point number", + format_symbol(mpl, par->defval)); + value = par->defval->num; + goto add; + } + else + { /* no value is provided */ + error(mpl, "no value for %s%s", par->name, format_tuple(mpl, + '[', tuple)); + } + return value; +} + +/*---------------------------------------------------------------------- +-- eval_member_num - evaluate num. value assigned to parameter member. +-- +-- This routine evaluates a numeric value assigned to given member of +-- specified numeric model parameter and returns it on exit. */ + +struct eval_num_info +{ /* working info used by the routine eval_member_num */ + PARAMETER *par; + /* model parameter */ + TUPLE *tuple; + /* n-tuple, which defines parameter member */ + MEMBER *memb; + /* normally this pointer is NULL; the routine uses this pointer + to check data provided in the data section, in which case it + points to a member currently checked; this check is performed + automatically only once when a reference to any member occurs + for the first time */ + double value; + /* evaluated numeric value */ +}; + +static void eval_num_func(MPL *mpl, void *_info) +{ /* this is auxiliary routine to work within domain scope */ + struct eval_num_info *info = _info; + if (info->memb != NULL) + { /* checking call; check numeric value being assigned */ + check_value_num(mpl, info->par, info->memb->tuple, + info->memb->value.num); + } + else + { /* normal call; evaluate member, which has given n-tuple */ + info->value = take_member_num(mpl, info->par, info->tuple); + } + return; +} + +double eval_member_num +( MPL *mpl, + PARAMETER *par, /* not changed */ + TUPLE *tuple /* not changed */ +) +{ /* this routine evaluates numeric parameter member */ + struct eval_num_info _info, *info = &_info; + xassert(par->type == A_NUMERIC || par->type == A_INTEGER || + par->type == A_BINARY); + xassert(par->dim == tuple_dimen(mpl, tuple)); + info->par = par; + info->tuple = tuple; + if (par->data == 1) + { /* check data, which are provided in the data section, but not + checked yet */ + /* save pointer to the last array member; note that during the + check new members may be added beyond the last member due to + references to the same parameter from default expression as + well as from expressions that define restricting conditions; + however, values assigned to the new members will be checked + by other routine, so we don't need to check them here */ + MEMBER *tail = par->array->tail; + /* change the data status to prevent infinite recursive loop + due to references to the same parameter during the check */ + par->data = 2; + /* check values assigned to array members in the data section + until the marked member has been reached */ + for (info->memb = par->array->head; info->memb != NULL; + info->memb = info->memb->next) + { if (eval_within_domain(mpl, par->domain, info->memb->tuple, + info, eval_num_func)) + out_of_domain(mpl, par->name, info->memb->tuple); + if (info->memb == tail) break; + } + /* the check has been finished */ + } + /* evaluate member, which has given n-tuple */ + info->memb = NULL; + if (eval_within_domain(mpl, info->par->domain, info->tuple, info, + eval_num_func)) + out_of_domain(mpl, par->name, info->tuple); + /* bring evaluated value to the calling program */ + return info->value; +} + +/*---------------------------------------------------------------------- +-- check_value_sym - check symbolic value assigned to parameter member. +-- +-- This routine checks if symbolic value being assigned to some member +-- of specified symbolic model parameter satisfies to all restrictions. +-- +-- NOTE: This routine must not be called out of domain scope. */ + +void check_value_sym +( MPL *mpl, + PARAMETER *par, /* not changed */ + TUPLE *tuple, /* not changed */ + SYMBOL *value /* not changed */ +) +{ CONDITION *cond; + WITHIN *in; + int eqno; + /* the value must satisfy to all specified conditions */ + for (cond = par->cond, eqno = 1; cond != NULL; cond = cond->next, + eqno++) + { SYMBOL *bound; + char buf[255+1]; + xassert(cond->code != NULL); + bound = eval_symbolic(mpl, cond->code); + switch (cond->rho) + { +#if 1 /* 13/VIII-2008 */ + case O_LT: + if (!(compare_symbols(mpl, value, bound) < 0)) + { strcpy(buf, format_symbol(mpl, bound)); + xassert(strlen(buf) < sizeof(buf)); + error(mpl, "%s%s = %s not < %s", + par->name, format_tuple(mpl, '[', tuple), + format_symbol(mpl, value), buf, eqno); + } + break; + case O_LE: + if (!(compare_symbols(mpl, value, bound) <= 0)) + { strcpy(buf, format_symbol(mpl, bound)); + xassert(strlen(buf) < sizeof(buf)); + error(mpl, "%s%s = %s not <= %s", + par->name, format_tuple(mpl, '[', tuple), + format_symbol(mpl, value), buf, eqno); + } + break; +#endif + case O_EQ: + if (!(compare_symbols(mpl, value, bound) == 0)) + { strcpy(buf, format_symbol(mpl, bound)); + xassert(strlen(buf) < sizeof(buf)); + error(mpl, "%s%s = %s not = %s", + par->name, format_tuple(mpl, '[', tuple), + format_symbol(mpl, value), buf, eqno); + } + break; +#if 1 /* 13/VIII-2008 */ + case O_GE: + if (!(compare_symbols(mpl, value, bound) >= 0)) + { strcpy(buf, format_symbol(mpl, bound)); + xassert(strlen(buf) < sizeof(buf)); + error(mpl, "%s%s = %s not >= %s", + par->name, format_tuple(mpl, '[', tuple), + format_symbol(mpl, value), buf, eqno); + } + break; + case O_GT: + if (!(compare_symbols(mpl, value, bound) > 0)) + { strcpy(buf, format_symbol(mpl, bound)); + xassert(strlen(buf) < sizeof(buf)); + error(mpl, "%s%s = %s not > %s", + par->name, format_tuple(mpl, '[', tuple), + format_symbol(mpl, value), buf, eqno); + } + break; +#endif + case O_NE: + if (!(compare_symbols(mpl, value, bound) != 0)) + { strcpy(buf, format_symbol(mpl, bound)); + xassert(strlen(buf) < sizeof(buf)); + error(mpl, "%s%s = %s not <> %s", + par->name, format_tuple(mpl, '[', tuple), + format_symbol(mpl, value), buf, eqno); + } + break; + default: + xassert(cond != cond); + } + delete_symbol(mpl, bound); + } + /* the value must be in all specified supersets */ + for (in = par->in, eqno = 1; in != NULL; in = in->next, eqno++) + { TUPLE *dummy; + xassert(in->code != NULL); + xassert(in->code->dim == 1); + dummy = expand_tuple(mpl, create_tuple(mpl), copy_symbol(mpl, + value)); + if (!is_member(mpl, in->code, dummy)) + error(mpl, "%s%s = %s not in specified set; see (%d)", + par->name, format_tuple(mpl, '[', tuple), + format_symbol(mpl, value), eqno); + delete_tuple(mpl, dummy); + } + return; +} + +/*---------------------------------------------------------------------- +-- take_member_sym - obtain symb. value assigned to parameter member. +-- +-- This routine obtains a symbolic value assigned to member of specified +-- symbolic model parameter and returns it on exit. +-- +-- NOTE: This routine must not be called out of domain scope. */ + +SYMBOL *take_member_sym /* returns value, not reference */ +( MPL *mpl, + PARAMETER *par, /* not changed */ + TUPLE *tuple /* not changed */ +) +{ MEMBER *memb; + SYMBOL *value; + /* find member in the parameter array */ + memb = find_member(mpl, par->array, tuple); + if (memb != NULL) + { /* member exists, so just take its value */ + value = copy_symbol(mpl, memb->value.sym); + } + else if (par->assign != NULL) + { /* compute value using assignment expression */ + value = eval_symbolic(mpl, par->assign); +add: /* check that the value satisfies to all restrictions, assign + it to new member, and add the member to the array */ + check_value_sym(mpl, par, tuple, value); + memb = add_member(mpl, par->array, copy_tuple(mpl, tuple)); + memb->value.sym = copy_symbol(mpl, value); + } + else if (par->option != NULL) + { /* compute default value */ + value = eval_symbolic(mpl, par->option); + goto add; + } + else if (par->defval != NULL) + { /* take default value provided in the data section */ + value = copy_symbol(mpl, par->defval); + goto add; + } + else + { /* no value is provided */ + error(mpl, "no value for %s%s", par->name, format_tuple(mpl, + '[', tuple)); + } + return value; +} + +/*---------------------------------------------------------------------- +-- eval_member_sym - evaluate symb. value assigned to parameter member. +-- +-- This routine evaluates a symbolic value assigned to given member of +-- specified symbolic model parameter and returns it on exit. */ + +struct eval_sym_info +{ /* working info used by the routine eval_member_sym */ + PARAMETER *par; + /* model parameter */ + TUPLE *tuple; + /* n-tuple, which defines parameter member */ + MEMBER *memb; + /* normally this pointer is NULL; the routine uses this pointer + to check data provided in the data section, in which case it + points to a member currently checked; this check is performed + automatically only once when a reference to any member occurs + for the first time */ + SYMBOL *value; + /* evaluated symbolic value */ +}; + +static void eval_sym_func(MPL *mpl, void *_info) +{ /* this is auxiliary routine to work within domain scope */ + struct eval_sym_info *info = _info; + if (info->memb != NULL) + { /* checking call; check symbolic value being assigned */ + check_value_sym(mpl, info->par, info->memb->tuple, + info->memb->value.sym); + } + else + { /* normal call; evaluate member, which has given n-tuple */ + info->value = take_member_sym(mpl, info->par, info->tuple); + } + return; +} + +SYMBOL *eval_member_sym /* returns value, not reference */ +( MPL *mpl, + PARAMETER *par, /* not changed */ + TUPLE *tuple /* not changed */ +) +{ /* this routine evaluates symbolic parameter member */ + struct eval_sym_info _info, *info = &_info; + xassert(par->type == A_SYMBOLIC); + xassert(par->dim == tuple_dimen(mpl, tuple)); + info->par = par; + info->tuple = tuple; + if (par->data == 1) + { /* check data, which are provided in the data section, but not + checked yet */ + /* save pointer to the last array member; note that during the + check new members may be added beyond the last member due to + references to the same parameter from default expression as + well as from expressions that define restricting conditions; + however, values assigned to the new members will be checked + by other routine, so we don't need to check them here */ + MEMBER *tail = par->array->tail; + /* change the data status to prevent infinite recursive loop + due to references to the same parameter during the check */ + par->data = 2; + /* check values assigned to array members in the data section + until the marked member has been reached */ + for (info->memb = par->array->head; info->memb != NULL; + info->memb = info->memb->next) + { if (eval_within_domain(mpl, par->domain, info->memb->tuple, + info, eval_sym_func)) + out_of_domain(mpl, par->name, info->memb->tuple); + if (info->memb == tail) break; + } + /* the check has been finished */ + } + /* evaluate member, which has given n-tuple */ + info->memb = NULL; + if (eval_within_domain(mpl, info->par->domain, info->tuple, info, + eval_sym_func)) + out_of_domain(mpl, par->name, info->tuple); + /* bring evaluated value to the calling program */ + return info->value; +} + +/*---------------------------------------------------------------------- +-- eval_whole_par - evaluate model parameter over entire domain. +-- +-- This routine evaluates all members of specified model parameter over +-- entire domain. */ + +static int whole_par_func(MPL *mpl, void *info) +{ /* this is auxiliary routine to work within domain scope */ + PARAMETER *par = (PARAMETER *)info; + TUPLE *tuple = get_domain_tuple(mpl, par->domain); + switch (par->type) + { case A_NUMERIC: + case A_INTEGER: + case A_BINARY: + eval_member_num(mpl, par, tuple); + break; + case A_SYMBOLIC: + delete_symbol(mpl, eval_member_sym(mpl, par, tuple)); + break; + default: + xassert(par != par); + } + delete_tuple(mpl, tuple); + return 0; +} + +void eval_whole_par(MPL *mpl, PARAMETER *par) +{ loop_within_domain(mpl, par->domain, par, whole_par_func); + return; +} + +/*---------------------------------------------------------------------- +-- clean_parameter - clean model parameter. +-- +-- This routine cleans specified model parameter that assumes deleting +-- all stuff dynamically allocated during the generation phase. */ + +void clean_parameter(MPL *mpl, PARAMETER *par) +{ CONDITION *cond; + WITHIN *in; + MEMBER *memb; + /* clean subscript domain */ + clean_domain(mpl, par->domain); + /* clean pseudo-code for computing restricting conditions */ + for (cond = par->cond; cond != NULL; cond = cond->next) + clean_code(mpl, cond->code); + /* clean pseudo-code for computing restricting supersets */ + for (in = par->in; in != NULL; in = in->next) + clean_code(mpl, in->code); + /* clean pseudo-code for computing assigned value */ + clean_code(mpl, par->assign); + /* clean pseudo-code for computing default value */ + clean_code(mpl, par->option); + /* reset data status flag */ + par->data = 0; + /* delete default symbolic value */ + if (par->defval != NULL) + delete_symbol(mpl, par->defval), par->defval = NULL; + /* delete content array */ + for (memb = par->array->head; memb != NULL; memb = memb->next) + delete_value(mpl, par->array->type, &memb->value); + delete_array(mpl, par->array), par->array = NULL; + return; +} + +/**********************************************************************/ +/* * * MODEL VARIABLES * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- take_member_var - obtain reference to elemental variable. +-- +-- This routine obtains a reference to elemental variable assigned to +-- given member of specified model variable and returns it on exit. If +-- necessary, new elemental variable is created. +-- +-- NOTE: This routine must not be called out of domain scope. */ + +ELEMVAR *take_member_var /* returns reference */ +( MPL *mpl, + VARIABLE *var, /* not changed */ + TUPLE *tuple /* not changed */ +) +{ MEMBER *memb; + ELEMVAR *refer; + /* find member in the variable array */ + memb = find_member(mpl, var->array, tuple); + if (memb != NULL) + { /* member exists, so just take the reference */ + refer = memb->value.var; + } + else + { /* member is referenced for the first time and therefore does + not exist; create new elemental variable, assign it to new + member, and add the member to the variable array */ + memb = add_member(mpl, var->array, copy_tuple(mpl, tuple)); + refer = (memb->value.var = + dmp_get_atom(mpl->elemvars, sizeof(ELEMVAR))); + refer->j = 0; + refer->var = var; + refer->memb = memb; + /* compute lower bound */ + if (var->lbnd == NULL) + refer->lbnd = 0.0; + else + refer->lbnd = eval_numeric(mpl, var->lbnd); + /* compute upper bound */ + if (var->ubnd == NULL) + refer->ubnd = 0.0; + else if (var->ubnd == var->lbnd) + refer->ubnd = refer->lbnd; + else + refer->ubnd = eval_numeric(mpl, var->ubnd); + /* nullify working quantity */ + refer->temp = 0.0; +#if 1 /* 15/V-2010 */ + /* solution has not been obtained by the solver yet */ + refer->stat = 0; + refer->prim = refer->dual = 0.0; +#endif + } + return refer; +} + +/*---------------------------------------------------------------------- +-- eval_member_var - evaluate reference to elemental variable. +-- +-- This routine evaluates a reference to elemental variable assigned to +-- member of specified model variable and returns it on exit. */ + +struct eval_var_info +{ /* working info used by the routine eval_member_var */ + VARIABLE *var; + /* model variable */ + TUPLE *tuple; + /* n-tuple, which defines variable member */ + ELEMVAR *refer; + /* evaluated reference to elemental variable */ +}; + +static void eval_var_func(MPL *mpl, void *_info) +{ /* this is auxiliary routine to work within domain scope */ + struct eval_var_info *info = _info; + info->refer = take_member_var(mpl, info->var, info->tuple); + return; +} + +ELEMVAR *eval_member_var /* returns reference */ +( MPL *mpl, + VARIABLE *var, /* not changed */ + TUPLE *tuple /* not changed */ +) +{ /* this routine evaluates variable member */ + struct eval_var_info _info, *info = &_info; + xassert(var->dim == tuple_dimen(mpl, tuple)); + info->var = var; + info->tuple = tuple; + /* evaluate member, which has given n-tuple */ + if (eval_within_domain(mpl, info->var->domain, info->tuple, info, + eval_var_func)) + out_of_domain(mpl, var->name, info->tuple); + /* bring evaluated reference to the calling program */ + return info->refer; +} + +/*---------------------------------------------------------------------- +-- eval_whole_var - evaluate model variable over entire domain. +-- +-- This routine evaluates all members of specified model variable over +-- entire domain. */ + +static int whole_var_func(MPL *mpl, void *info) +{ /* this is auxiliary routine to work within domain scope */ + VARIABLE *var = (VARIABLE *)info; + TUPLE *tuple = get_domain_tuple(mpl, var->domain); + eval_member_var(mpl, var, tuple); + delete_tuple(mpl, tuple); + return 0; +} + +void eval_whole_var(MPL *mpl, VARIABLE *var) +{ loop_within_domain(mpl, var->domain, var, whole_var_func); + return; +} + +/*---------------------------------------------------------------------- +-- clean_variable - clean model variable. +-- +-- This routine cleans specified model variable that assumes deleting +-- all stuff dynamically allocated during the generation phase. */ + +void clean_variable(MPL *mpl, VARIABLE *var) +{ MEMBER *memb; + /* clean subscript domain */ + clean_domain(mpl, var->domain); + /* clean code for computing lower bound */ + clean_code(mpl, var->lbnd); + /* clean code for computing upper bound */ + if (var->ubnd != var->lbnd) clean_code(mpl, var->ubnd); + /* delete content array */ + for (memb = var->array->head; memb != NULL; memb = memb->next) + dmp_free_atom(mpl->elemvars, memb->value.var, sizeof(ELEMVAR)); + delete_array(mpl, var->array), var->array = NULL; + return; +} + +/**********************************************************************/ +/* * * MODEL CONSTRAINTS AND OBJECTIVES * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- take_member_con - obtain reference to elemental constraint. +-- +-- This routine obtains a reference to elemental constraint assigned +-- to given member of specified model constraint and returns it on exit. +-- If necessary, new elemental constraint is created. +-- +-- NOTE: This routine must not be called out of domain scope. */ + +ELEMCON *take_member_con /* returns reference */ +( MPL *mpl, + CONSTRAINT *con, /* not changed */ + TUPLE *tuple /* not changed */ +) +{ MEMBER *memb; + ELEMCON *refer; + /* find member in the constraint array */ + memb = find_member(mpl, con->array, tuple); + if (memb != NULL) + { /* member exists, so just take the reference */ + refer = memb->value.con; + } + else + { /* member is referenced for the first time and therefore does + not exist; create new elemental constraint, assign it to new + member, and add the member to the constraint array */ + memb = add_member(mpl, con->array, copy_tuple(mpl, tuple)); + refer = (memb->value.con = + dmp_get_atom(mpl->elemcons, sizeof(ELEMCON))); + refer->i = 0; + refer->con = con; + refer->memb = memb; + /* compute linear form */ + xassert(con->code != NULL); + refer->form = eval_formula(mpl, con->code); + /* compute lower and upper bounds */ + if (con->lbnd == NULL && con->ubnd == NULL) + { /* objective has no bounds */ + double temp; + xassert(con->type == A_MINIMIZE || con->type == A_MAXIMIZE); + /* carry the constant term to the right-hand side */ + refer->form = remove_constant(mpl, refer->form, &temp); + refer->lbnd = refer->ubnd = - temp; + } + else if (con->lbnd != NULL && con->ubnd == NULL) + { /* constraint a * x + b >= c * y + d is transformed to the + standard form a * x - c * y >= d - b */ + double temp; + xassert(con->type == A_CONSTRAINT); + refer->form = linear_comb(mpl, + +1.0, refer->form, + -1.0, eval_formula(mpl, con->lbnd)); + refer->form = remove_constant(mpl, refer->form, &temp); + refer->lbnd = - temp; + refer->ubnd = 0.0; + } + else if (con->lbnd == NULL && con->ubnd != NULL) + { /* constraint a * x + b <= c * y + d is transformed to the + standard form a * x - c * y <= d - b */ + double temp; + xassert(con->type == A_CONSTRAINT); + refer->form = linear_comb(mpl, + +1.0, refer->form, + -1.0, eval_formula(mpl, con->ubnd)); + refer->form = remove_constant(mpl, refer->form, &temp); + refer->lbnd = 0.0; + refer->ubnd = - temp; + } + else if (con->lbnd == con->ubnd) + { /* constraint a * x + b = c * y + d is transformed to the + standard form a * x - c * y = d - b */ + double temp; + xassert(con->type == A_CONSTRAINT); + refer->form = linear_comb(mpl, + +1.0, refer->form, + -1.0, eval_formula(mpl, con->lbnd)); + refer->form = remove_constant(mpl, refer->form, &temp); + refer->lbnd = refer->ubnd = - temp; + } + else + { /* ranged constraint c <= a * x + b <= d is transformed to + the standard form c - b <= a * x <= d - b */ + double temp, temp1, temp2; + xassert(con->type == A_CONSTRAINT); + refer->form = remove_constant(mpl, refer->form, &temp); + xassert(remove_constant(mpl, eval_formula(mpl, con->lbnd), + &temp1) == NULL); + xassert(remove_constant(mpl, eval_formula(mpl, con->ubnd), + &temp2) == NULL); + refer->lbnd = fp_sub(mpl, temp1, temp); + refer->ubnd = fp_sub(mpl, temp2, temp); + } +#if 1 /* 15/V-2010 */ + /* solution has not been obtained by the solver yet */ + refer->stat = 0; + refer->prim = refer->dual = 0.0; +#endif + } + return refer; +} + +/*---------------------------------------------------------------------- +-- eval_member_con - evaluate reference to elemental constraint. +-- +-- This routine evaluates a reference to elemental constraint assigned +-- to member of specified model constraint and returns it on exit. */ + +struct eval_con_info +{ /* working info used by the routine eval_member_con */ + CONSTRAINT *con; + /* model constraint */ + TUPLE *tuple; + /* n-tuple, which defines constraint member */ + ELEMCON *refer; + /* evaluated reference to elemental constraint */ +}; + +static void eval_con_func(MPL *mpl, void *_info) +{ /* this is auxiliary routine to work within domain scope */ + struct eval_con_info *info = _info; + info->refer = take_member_con(mpl, info->con, info->tuple); + return; +} + +ELEMCON *eval_member_con /* returns reference */ +( MPL *mpl, + CONSTRAINT *con, /* not changed */ + TUPLE *tuple /* not changed */ +) +{ /* this routine evaluates constraint member */ + struct eval_con_info _info, *info = &_info; + xassert(con->dim == tuple_dimen(mpl, tuple)); + info->con = con; + info->tuple = tuple; + /* evaluate member, which has given n-tuple */ + if (eval_within_domain(mpl, info->con->domain, info->tuple, info, + eval_con_func)) + out_of_domain(mpl, con->name, info->tuple); + /* bring evaluated reference to the calling program */ + return info->refer; +} + +/*---------------------------------------------------------------------- +-- eval_whole_con - evaluate model constraint over entire domain. +-- +-- This routine evaluates all members of specified model constraint over +-- entire domain. */ + +static int whole_con_func(MPL *mpl, void *info) +{ /* this is auxiliary routine to work within domain scope */ + CONSTRAINT *con = (CONSTRAINT *)info; + TUPLE *tuple = get_domain_tuple(mpl, con->domain); + eval_member_con(mpl, con, tuple); + delete_tuple(mpl, tuple); + return 0; +} + +void eval_whole_con(MPL *mpl, CONSTRAINT *con) +{ loop_within_domain(mpl, con->domain, con, whole_con_func); + return; +} + +/*---------------------------------------------------------------------- +-- clean_constraint - clean model constraint. +-- +-- This routine cleans specified model constraint that assumes deleting +-- all stuff dynamically allocated during the generation phase. */ + +void clean_constraint(MPL *mpl, CONSTRAINT *con) +{ MEMBER *memb; + /* clean subscript domain */ + clean_domain(mpl, con->domain); + /* clean code for computing main linear form */ + clean_code(mpl, con->code); + /* clean code for computing lower bound */ + clean_code(mpl, con->lbnd); + /* clean code for computing upper bound */ + if (con->ubnd != con->lbnd) clean_code(mpl, con->ubnd); + /* delete content array */ + for (memb = con->array->head; memb != NULL; memb = memb->next) + { delete_formula(mpl, memb->value.con->form); + dmp_free_atom(mpl->elemcons, memb->value.con, sizeof(ELEMCON)); + } + delete_array(mpl, con->array), con->array = NULL; + return; +} + +/**********************************************************************/ +/* * * PSEUDO-CODE * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- eval_numeric - evaluate pseudo-code to determine numeric value. +-- +-- This routine evaluates specified pseudo-code to determine resultant +-- numeric value, which is returned on exit. */ + +struct iter_num_info +{ /* working info used by the routine iter_num_func */ + CODE *code; + /* pseudo-code for iterated operation to be performed */ + double value; + /* resultant value */ +}; + +static int iter_num_func(MPL *mpl, void *_info) +{ /* this is auxiliary routine used to perform iterated operation + on numeric "integrand" within domain scope */ + struct iter_num_info *info = _info; + double temp; + temp = eval_numeric(mpl, info->code->arg.loop.x); + switch (info->code->op) + { case O_SUM: + /* summation over domain */ + info->value = fp_add(mpl, info->value, temp); + break; + case O_PROD: + /* multiplication over domain */ + info->value = fp_mul(mpl, info->value, temp); + break; + case O_MINIMUM: + /* minimum over domain */ + if (info->value > temp) info->value = temp; + break; + case O_MAXIMUM: + /* maximum over domain */ + if (info->value < temp) info->value = temp; + break; + default: + xassert(info != info); + } + return 0; +} + +double eval_numeric(MPL *mpl, CODE *code) +{ double value; + xassert(code != NULL); + xassert(code->type == A_NUMERIC); + xassert(code->dim == 0); + /* if the operation has a side effect, invalidate and delete the + resultant value */ + if (code->vflag && code->valid) + { code->valid = 0; + delete_value(mpl, code->type, &code->value); + } + /* if resultant value is valid, no evaluation is needed */ + if (code->valid) + { value = code->value.num; + goto done; + } + /* evaluate pseudo-code recursively */ + switch (code->op) + { case O_NUMBER: + /* take floating-point number */ + value = code->arg.num; + break; + case O_MEMNUM: + /* take member of numeric parameter */ + { TUPLE *tuple; + ARG_LIST *e; + tuple = create_tuple(mpl); + for (e = code->arg.par.list; e != NULL; e = e->next) + tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, + e->x)); + value = eval_member_num(mpl, code->arg.par.par, tuple); + delete_tuple(mpl, tuple); + } + break; + case O_MEMVAR: + /* take computed value of elemental variable */ + { TUPLE *tuple; + ARG_LIST *e; +#if 1 /* 15/V-2010 */ + ELEMVAR *var; +#endif + tuple = create_tuple(mpl); + for (e = code->arg.var.list; e != NULL; e = e->next) + tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, + e->x)); +#if 0 /* 15/V-2010 */ + value = eval_member_var(mpl, code->arg.var.var, tuple) + ->value; +#else + var = eval_member_var(mpl, code->arg.var.var, tuple); + switch (code->arg.var.suff) + { case DOT_LB: + if (var->var->lbnd == NULL) + value = -DBL_MAX; + else + value = var->lbnd; + break; + case DOT_UB: + if (var->var->ubnd == NULL) + value = +DBL_MAX; + else + value = var->ubnd; + break; + case DOT_STATUS: + value = var->stat; + break; + case DOT_VAL: + value = var->prim; + break; + case DOT_DUAL: + value = var->dual; + break; + default: + xassert(code != code); + } +#endif + delete_tuple(mpl, tuple); + } + break; +#if 1 /* 15/V-2010 */ + case O_MEMCON: + /* take computed value of elemental constraint */ + { TUPLE *tuple; + ARG_LIST *e; + ELEMCON *con; + tuple = create_tuple(mpl); + for (e = code->arg.con.list; e != NULL; e = e->next) + tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, + e->x)); + con = eval_member_con(mpl, code->arg.con.con, tuple); + switch (code->arg.con.suff) + { case DOT_LB: + if (con->con->lbnd == NULL) + value = -DBL_MAX; + else + value = con->lbnd; + break; + case DOT_UB: + if (con->con->ubnd == NULL) + value = +DBL_MAX; + else + value = con->ubnd; + break; + case DOT_STATUS: + value = con->stat; + break; + case DOT_VAL: + value = con->prim; + break; + case DOT_DUAL: + value = con->dual; + break; + default: + xassert(code != code); + } + delete_tuple(mpl, tuple); + } + break; +#endif + case O_IRAND224: + /* pseudo-random in [0, 2^24-1] */ + value = fp_irand224(mpl); + break; + case O_UNIFORM01: + /* pseudo-random in [0, 1) */ + value = fp_uniform01(mpl); + break; + case O_NORMAL01: + /* gaussian random, mu = 0, sigma = 1 */ + value = fp_normal01(mpl); + break; + case O_GMTIME: + /* current calendar time */ + value = fn_gmtime(mpl); + break; + case O_CVTNUM: + /* conversion to numeric */ + { SYMBOL *sym; + sym = eval_symbolic(mpl, code->arg.arg.x); +#if 0 /* 23/XI-2008 */ + if (sym->str != NULL) + error(mpl, "cannot convert %s to floating-point numbe" + "r", format_symbol(mpl, sym)); + value = sym->num; +#else + if (sym->str == NULL) + value = sym->num; + else + { if (str2num(sym->str, &value)) + error(mpl, "cannot convert %s to floating-point nu" + "mber", format_symbol(mpl, sym)); + } +#endif + delete_symbol(mpl, sym); + } + break; + case O_PLUS: + /* unary plus */ + value = + eval_numeric(mpl, code->arg.arg.x); + break; + case O_MINUS: + /* unary minus */ + value = - eval_numeric(mpl, code->arg.arg.x); + break; + case O_ABS: + /* absolute value */ + value = fabs(eval_numeric(mpl, code->arg.arg.x)); + break; + case O_CEIL: + /* round upward ("ceiling of x") */ + value = ceil(eval_numeric(mpl, code->arg.arg.x)); + break; + case O_FLOOR: + /* round downward ("floor of x") */ + value = floor(eval_numeric(mpl, code->arg.arg.x)); + break; + case O_EXP: + /* base-e exponential */ + value = fp_exp(mpl, eval_numeric(mpl, code->arg.arg.x)); + break; + case O_LOG: + /* natural logarithm */ + value = fp_log(mpl, eval_numeric(mpl, code->arg.arg.x)); + break; + case O_LOG10: + /* common (decimal) logarithm */ + value = fp_log10(mpl, eval_numeric(mpl, code->arg.arg.x)); + break; + case O_SQRT: + /* square root */ + value = fp_sqrt(mpl, eval_numeric(mpl, code->arg.arg.x)); + break; + case O_SIN: + /* trigonometric sine */ + value = fp_sin(mpl, eval_numeric(mpl, code->arg.arg.x)); + break; + case O_COS: + /* trigonometric cosine */ + value = fp_cos(mpl, eval_numeric(mpl, code->arg.arg.x)); + break; + case O_ATAN: + /* trigonometric arctangent (one argument) */ + value = fp_atan(mpl, eval_numeric(mpl, code->arg.arg.x)); + break; + case O_ATAN2: + /* trigonometric arctangent (two arguments) */ + value = fp_atan2(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_numeric(mpl, code->arg.arg.y)); + break; + case O_ROUND: + /* round to nearest integer */ + value = fp_round(mpl, + eval_numeric(mpl, code->arg.arg.x), 0.0); + break; + case O_ROUND2: + /* round to n fractional digits */ + value = fp_round(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_numeric(mpl, code->arg.arg.y)); + break; + case O_TRUNC: + /* truncate to nearest integer */ + value = fp_trunc(mpl, + eval_numeric(mpl, code->arg.arg.x), 0.0); + break; + case O_TRUNC2: + /* truncate to n fractional digits */ + value = fp_trunc(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_numeric(mpl, code->arg.arg.y)); + break; + case O_ADD: + /* addition */ + value = fp_add(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_numeric(mpl, code->arg.arg.y)); + break; + case O_SUB: + /* subtraction */ + value = fp_sub(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_numeric(mpl, code->arg.arg.y)); + break; + case O_LESS: + /* non-negative subtraction */ + value = fp_less(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_numeric(mpl, code->arg.arg.y)); + break; + case O_MUL: + /* multiplication */ + value = fp_mul(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_numeric(mpl, code->arg.arg.y)); + break; + case O_DIV: + /* division */ + value = fp_div(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_numeric(mpl, code->arg.arg.y)); + break; + case O_IDIV: + /* quotient of exact division */ + value = fp_idiv(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_numeric(mpl, code->arg.arg.y)); + break; + case O_MOD: + /* remainder of exact division */ + value = fp_mod(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_numeric(mpl, code->arg.arg.y)); + break; + case O_POWER: + /* exponentiation (raise to power) */ + value = fp_power(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_numeric(mpl, code->arg.arg.y)); + break; + case O_UNIFORM: + /* pseudo-random in [a, b) */ + value = fp_uniform(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_numeric(mpl, code->arg.arg.y)); + break; + case O_NORMAL: + /* gaussian random, given mu and sigma */ + value = fp_normal(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_numeric(mpl, code->arg.arg.y)); + break; + case O_CARD: + { ELEMSET *set; + set = eval_elemset(mpl, code->arg.arg.x); + value = set->size; + delete_array(mpl, set); + } + break; + case O_LENGTH: + { SYMBOL *sym; + char str[MAX_LENGTH+1]; + sym = eval_symbolic(mpl, code->arg.arg.x); + if (sym->str == NULL) + sprintf(str, "%.*g", DBL_DIG, sym->num); + else + fetch_string(mpl, sym->str, str); + delete_symbol(mpl, sym); + value = strlen(str); + } + break; + case O_STR2TIME: + { SYMBOL *sym; + char str[MAX_LENGTH+1], fmt[MAX_LENGTH+1]; + sym = eval_symbolic(mpl, code->arg.arg.x); + if (sym->str == NULL) + sprintf(str, "%.*g", DBL_DIG, sym->num); + else + fetch_string(mpl, sym->str, str); + delete_symbol(mpl, sym); + sym = eval_symbolic(mpl, code->arg.arg.y); + if (sym->str == NULL) + sprintf(fmt, "%.*g", DBL_DIG, sym->num); + else + fetch_string(mpl, sym->str, fmt); + delete_symbol(mpl, sym); + value = fn_str2time(mpl, str, fmt); + } + break; + case O_FORK: + /* if-then-else */ + if (eval_logical(mpl, code->arg.arg.x)) + value = eval_numeric(mpl, code->arg.arg.y); + else if (code->arg.arg.z == NULL) + value = 0.0; + else + value = eval_numeric(mpl, code->arg.arg.z); + break; + case O_MIN: + /* minimal value (n-ary) */ + { ARG_LIST *e; + double temp; + value = +DBL_MAX; + for (e = code->arg.list; e != NULL; e = e->next) + { temp = eval_numeric(mpl, e->x); + if (value > temp) value = temp; + } + } + break; + case O_MAX: + /* maximal value (n-ary) */ + { ARG_LIST *e; + double temp; + value = -DBL_MAX; + for (e = code->arg.list; e != NULL; e = e->next) + { temp = eval_numeric(mpl, e->x); + if (value < temp) value = temp; + } + } + break; + case O_SUM: + /* summation over domain */ + { struct iter_num_info _info, *info = &_info; + info->code = code; + info->value = 0.0; + loop_within_domain(mpl, code->arg.loop.domain, info, + iter_num_func); + value = info->value; + } + break; + case O_PROD: + /* multiplication over domain */ + { struct iter_num_info _info, *info = &_info; + info->code = code; + info->value = 1.0; + loop_within_domain(mpl, code->arg.loop.domain, info, + iter_num_func); + value = info->value; + } + break; + case O_MINIMUM: + /* minimum over domain */ + { struct iter_num_info _info, *info = &_info; + info->code = code; + info->value = +DBL_MAX; + loop_within_domain(mpl, code->arg.loop.domain, info, + iter_num_func); + if (info->value == +DBL_MAX) + error(mpl, "min{} over empty set; result undefined"); + value = info->value; + } + break; + case O_MAXIMUM: + /* maximum over domain */ + { struct iter_num_info _info, *info = &_info; + info->code = code; + info->value = -DBL_MAX; + loop_within_domain(mpl, code->arg.loop.domain, info, + iter_num_func); + if (info->value == -DBL_MAX) + error(mpl, "max{} over empty set; result undefined"); + value = info->value; + } + break; + default: + xassert(code != code); + } + /* save resultant value */ + xassert(!code->valid); + code->valid = 1; + code->value.num = value; +done: return value; +} + +/*---------------------------------------------------------------------- +-- eval_symbolic - evaluate pseudo-code to determine symbolic value. +-- +-- This routine evaluates specified pseudo-code to determine resultant +-- symbolic value, which is returned on exit. */ + +SYMBOL *eval_symbolic(MPL *mpl, CODE *code) +{ SYMBOL *value; + xassert(code != NULL); + xassert(code->type == A_SYMBOLIC); + xassert(code->dim == 0); + /* if the operation has a side effect, invalidate and delete the + resultant value */ + if (code->vflag && code->valid) + { code->valid = 0; + delete_value(mpl, code->type, &code->value); + } + /* if resultant value is valid, no evaluation is needed */ + if (code->valid) + { value = copy_symbol(mpl, code->value.sym); + goto done; + } + /* evaluate pseudo-code recursively */ + switch (code->op) + { case O_STRING: + /* take character string */ + value = create_symbol_str(mpl, create_string(mpl, + code->arg.str)); + break; + case O_INDEX: + /* take dummy index */ + xassert(code->arg.index.slot->value != NULL); + value = copy_symbol(mpl, code->arg.index.slot->value); + break; + case O_MEMSYM: + /* take member of symbolic parameter */ + { TUPLE *tuple; + ARG_LIST *e; + tuple = create_tuple(mpl); + for (e = code->arg.par.list; e != NULL; e = e->next) + tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, + e->x)); + value = eval_member_sym(mpl, code->arg.par.par, tuple); + delete_tuple(mpl, tuple); + } + break; + case O_CVTSYM: + /* conversion to symbolic */ + value = create_symbol_num(mpl, eval_numeric(mpl, + code->arg.arg.x)); + break; + case O_CONCAT: + /* concatenation */ + value = concat_symbols(mpl, + eval_symbolic(mpl, code->arg.arg.x), + eval_symbolic(mpl, code->arg.arg.y)); + break; + case O_FORK: + /* if-then-else */ + if (eval_logical(mpl, code->arg.arg.x)) + value = eval_symbolic(mpl, code->arg.arg.y); + else if (code->arg.arg.z == NULL) + value = create_symbol_num(mpl, 0.0); + else + value = eval_symbolic(mpl, code->arg.arg.z); + break; + case O_SUBSTR: + case O_SUBSTR3: + { double pos, len; + char str[MAX_LENGTH+1]; + value = eval_symbolic(mpl, code->arg.arg.x); + if (value->str == NULL) + sprintf(str, "%.*g", DBL_DIG, value->num); + else + fetch_string(mpl, value->str, str); + delete_symbol(mpl, value); + if (code->op == O_SUBSTR) + { pos = eval_numeric(mpl, code->arg.arg.y); + if (pos != floor(pos)) + error(mpl, "substr('...', %.*g); non-integer secon" + "d argument", DBL_DIG, pos); + if (pos < 1 || pos > strlen(str) + 1) + error(mpl, "substr('...', %.*g); substring out of " + "range", DBL_DIG, pos); + } + else + { pos = eval_numeric(mpl, code->arg.arg.y); + len = eval_numeric(mpl, code->arg.arg.z); + if (pos != floor(pos) || len != floor(len)) + error(mpl, "substr('...', %.*g, %.*g); non-integer" + " second and/or third argument", DBL_DIG, pos, + DBL_DIG, len); + if (pos < 1 || len < 0 || pos + len > strlen(str) + 1) + error(mpl, "substr('...', %.*g, %.*g); substring o" + "ut of range", DBL_DIG, pos, DBL_DIG, len); + str[(int)pos + (int)len - 1] = '\0'; + } + value = create_symbol_str(mpl, create_string(mpl, str + + (int)pos - 1)); + } + break; + case O_TIME2STR: + { double num; + SYMBOL *sym; + char str[MAX_LENGTH+1], fmt[MAX_LENGTH+1]; + num = eval_numeric(mpl, code->arg.arg.x); + sym = eval_symbolic(mpl, code->arg.arg.y); + if (sym->str == NULL) + sprintf(fmt, "%.*g", DBL_DIG, sym->num); + else + fetch_string(mpl, sym->str, fmt); + delete_symbol(mpl, sym); + fn_time2str(mpl, str, num, fmt); + value = create_symbol_str(mpl, create_string(mpl, str)); + } + break; + default: + xassert(code != code); + } + /* save resultant value */ + xassert(!code->valid); + code->valid = 1; + code->value.sym = copy_symbol(mpl, value); +done: return value; +} + +/*---------------------------------------------------------------------- +-- eval_logical - evaluate pseudo-code to determine logical value. +-- +-- This routine evaluates specified pseudo-code to determine resultant +-- logical value, which is returned on exit. */ + +struct iter_log_info +{ /* working info used by the routine iter_log_func */ + CODE *code; + /* pseudo-code for iterated operation to be performed */ + int value; + /* resultant value */ +}; + +static int iter_log_func(MPL *mpl, void *_info) +{ /* this is auxiliary routine used to perform iterated operation + on logical "integrand" within domain scope */ + struct iter_log_info *info = _info; + int ret = 0; + switch (info->code->op) + { case O_FORALL: + /* conjunction over domain */ + info->value &= eval_logical(mpl, info->code->arg.loop.x); + if (!info->value) ret = 1; + break; + case O_EXISTS: + /* disjunction over domain */ + info->value |= eval_logical(mpl, info->code->arg.loop.x); + if (info->value) ret = 1; + break; + default: + xassert(info != info); + } + return ret; +} + +int eval_logical(MPL *mpl, CODE *code) +{ int value; + xassert(code->type == A_LOGICAL); + xassert(code->dim == 0); + /* if the operation has a side effect, invalidate and delete the + resultant value */ + if (code->vflag && code->valid) + { code->valid = 0; + delete_value(mpl, code->type, &code->value); + } + /* if resultant value is valid, no evaluation is needed */ + if (code->valid) + { value = code->value.bit; + goto done; + } + /* evaluate pseudo-code recursively */ + switch (code->op) + { case O_CVTLOG: + /* conversion to logical */ + value = (eval_numeric(mpl, code->arg.arg.x) != 0.0); + break; + case O_NOT: + /* negation (logical "not") */ + value = !eval_logical(mpl, code->arg.arg.x); + break; + case O_LT: + /* comparison on 'less than' */ +#if 0 /* 02/VIII-2008 */ + value = (eval_numeric(mpl, code->arg.arg.x) < + eval_numeric(mpl, code->arg.arg.y)); +#else + xassert(code->arg.arg.x != NULL); + if (code->arg.arg.x->type == A_NUMERIC) + value = (eval_numeric(mpl, code->arg.arg.x) < + eval_numeric(mpl, code->arg.arg.y)); + else + { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); + SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); + value = (compare_symbols(mpl, sym1, sym2) < 0); + delete_symbol(mpl, sym1); + delete_symbol(mpl, sym2); + } +#endif + break; + case O_LE: + /* comparison on 'not greater than' */ +#if 0 /* 02/VIII-2008 */ + value = (eval_numeric(mpl, code->arg.arg.x) <= + eval_numeric(mpl, code->arg.arg.y)); +#else + xassert(code->arg.arg.x != NULL); + if (code->arg.arg.x->type == A_NUMERIC) + value = (eval_numeric(mpl, code->arg.arg.x) <= + eval_numeric(mpl, code->arg.arg.y)); + else + { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); + SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); + value = (compare_symbols(mpl, sym1, sym2) <= 0); + delete_symbol(mpl, sym1); + delete_symbol(mpl, sym2); + } +#endif + break; + case O_EQ: + /* comparison on 'equal to' */ + xassert(code->arg.arg.x != NULL); + if (code->arg.arg.x->type == A_NUMERIC) + value = (eval_numeric(mpl, code->arg.arg.x) == + eval_numeric(mpl, code->arg.arg.y)); + else + { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); + SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); + value = (compare_symbols(mpl, sym1, sym2) == 0); + delete_symbol(mpl, sym1); + delete_symbol(mpl, sym2); + } + break; + case O_GE: + /* comparison on 'not less than' */ +#if 0 /* 02/VIII-2008 */ + value = (eval_numeric(mpl, code->arg.arg.x) >= + eval_numeric(mpl, code->arg.arg.y)); +#else + xassert(code->arg.arg.x != NULL); + if (code->arg.arg.x->type == A_NUMERIC) + value = (eval_numeric(mpl, code->arg.arg.x) >= + eval_numeric(mpl, code->arg.arg.y)); + else + { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); + SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); + value = (compare_symbols(mpl, sym1, sym2) >= 0); + delete_symbol(mpl, sym1); + delete_symbol(mpl, sym2); + } +#endif + break; + case O_GT: + /* comparison on 'greater than' */ +#if 0 /* 02/VIII-2008 */ + value = (eval_numeric(mpl, code->arg.arg.x) > + eval_numeric(mpl, code->arg.arg.y)); +#else + xassert(code->arg.arg.x != NULL); + if (code->arg.arg.x->type == A_NUMERIC) + value = (eval_numeric(mpl, code->arg.arg.x) > + eval_numeric(mpl, code->arg.arg.y)); + else + { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); + SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); + value = (compare_symbols(mpl, sym1, sym2) > 0); + delete_symbol(mpl, sym1); + delete_symbol(mpl, sym2); + } +#endif + break; + case O_NE: + /* comparison on 'not equal to' */ + xassert(code->arg.arg.x != NULL); + if (code->arg.arg.x->type == A_NUMERIC) + value = (eval_numeric(mpl, code->arg.arg.x) != + eval_numeric(mpl, code->arg.arg.y)); + else + { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); + SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); + value = (compare_symbols(mpl, sym1, sym2) != 0); + delete_symbol(mpl, sym1); + delete_symbol(mpl, sym2); + } + break; + case O_AND: + /* conjunction (logical "and") */ + value = eval_logical(mpl, code->arg.arg.x) && + eval_logical(mpl, code->arg.arg.y); + break; + case O_OR: + /* disjunction (logical "or") */ + value = eval_logical(mpl, code->arg.arg.x) || + eval_logical(mpl, code->arg.arg.y); + break; + case O_IN: + /* test on 'x in Y' */ + { TUPLE *tuple; + tuple = eval_tuple(mpl, code->arg.arg.x); + value = is_member(mpl, code->arg.arg.y, tuple); + delete_tuple(mpl, tuple); + } + break; + case O_NOTIN: + /* test on 'x not in Y' */ + { TUPLE *tuple; + tuple = eval_tuple(mpl, code->arg.arg.x); + value = !is_member(mpl, code->arg.arg.y, tuple); + delete_tuple(mpl, tuple); + } + break; + case O_WITHIN: + /* test on 'X within Y' */ + { ELEMSET *set; + MEMBER *memb; + set = eval_elemset(mpl, code->arg.arg.x); + value = 1; + for (memb = set->head; memb != NULL; memb = memb->next) + { if (!is_member(mpl, code->arg.arg.y, memb->tuple)) + { value = 0; + break; + } + } + delete_elemset(mpl, set); + } + break; + case O_NOTWITHIN: + /* test on 'X not within Y' */ + { ELEMSET *set; + MEMBER *memb; + set = eval_elemset(mpl, code->arg.arg.x); + value = 1; + for (memb = set->head; memb != NULL; memb = memb->next) + { if (is_member(mpl, code->arg.arg.y, memb->tuple)) + { value = 0; + break; + } + } + delete_elemset(mpl, set); + } + break; + case O_FORALL: + /* conjunction (A-quantification) */ + { struct iter_log_info _info, *info = &_info; + info->code = code; + info->value = 1; + loop_within_domain(mpl, code->arg.loop.domain, info, + iter_log_func); + value = info->value; + } + break; + case O_EXISTS: + /* disjunction (E-quantification) */ + { struct iter_log_info _info, *info = &_info; + info->code = code; + info->value = 0; + loop_within_domain(mpl, code->arg.loop.domain, info, + iter_log_func); + value = info->value; + } + break; + default: + xassert(code != code); + } + /* save resultant value */ + xassert(!code->valid); + code->valid = 1; + code->value.bit = value; +done: return value; +} + +/*---------------------------------------------------------------------- +-- eval_tuple - evaluate pseudo-code to construct n-tuple. +-- +-- This routine evaluates specified pseudo-code to construct resultant +-- n-tuple, which is returned on exit. */ + +TUPLE *eval_tuple(MPL *mpl, CODE *code) +{ TUPLE *value; + xassert(code != NULL); + xassert(code->type == A_TUPLE); + xassert(code->dim > 0); + /* if the operation has a side effect, invalidate and delete the + resultant value */ + if (code->vflag && code->valid) + { code->valid = 0; + delete_value(mpl, code->type, &code->value); + } + /* if resultant value is valid, no evaluation is needed */ + if (code->valid) + { value = copy_tuple(mpl, code->value.tuple); + goto done; + } + /* evaluate pseudo-code recursively */ + switch (code->op) + { case O_TUPLE: + /* make n-tuple */ + { ARG_LIST *e; + value = create_tuple(mpl); + for (e = code->arg.list; e != NULL; e = e->next) + value = expand_tuple(mpl, value, eval_symbolic(mpl, + e->x)); + } + break; + case O_CVTTUP: + /* convert to 1-tuple */ + value = expand_tuple(mpl, create_tuple(mpl), + eval_symbolic(mpl, code->arg.arg.x)); + break; + default: + xassert(code != code); + } + /* save resultant value */ + xassert(!code->valid); + code->valid = 1; + code->value.tuple = copy_tuple(mpl, value); +done: return value; +} + +/*---------------------------------------------------------------------- +-- eval_elemset - evaluate pseudo-code to construct elemental set. +-- +-- This routine evaluates specified pseudo-code to construct resultant +-- elemental set, which is returned on exit. */ + +struct iter_set_info +{ /* working info used by the routine iter_set_func */ + CODE *code; + /* pseudo-code for iterated operation to be performed */ + ELEMSET *value; + /* resultant value */ +}; + +static int iter_set_func(MPL *mpl, void *_info) +{ /* this is auxiliary routine used to perform iterated operation + on n-tuple "integrand" within domain scope */ + struct iter_set_info *info = _info; + TUPLE *tuple; + switch (info->code->op) + { case O_SETOF: + /* compute next n-tuple and add it to the set; in this case + duplicate n-tuples are silently ignored */ + tuple = eval_tuple(mpl, info->code->arg.loop.x); + if (find_tuple(mpl, info->value, tuple) == NULL) + add_tuple(mpl, info->value, tuple); + else + delete_tuple(mpl, tuple); + break; + case O_BUILD: + /* construct next n-tuple using current values assigned to + *free* dummy indices as its components and add it to the + set; in this case duplicate n-tuples cannot appear */ + add_tuple(mpl, info->value, get_domain_tuple(mpl, + info->code->arg.loop.domain)); + break; + default: + xassert(info != info); + } + return 0; +} + +ELEMSET *eval_elemset(MPL *mpl, CODE *code) +{ ELEMSET *value; + xassert(code != NULL); + xassert(code->type == A_ELEMSET); + xassert(code->dim > 0); + /* if the operation has a side effect, invalidate and delete the + resultant value */ + if (code->vflag && code->valid) + { code->valid = 0; + delete_value(mpl, code->type, &code->value); + } + /* if resultant value is valid, no evaluation is needed */ + if (code->valid) + { value = copy_elemset(mpl, code->value.set); + goto done; + } + /* evaluate pseudo-code recursively */ + switch (code->op) + { case O_MEMSET: + /* take member of set */ + { TUPLE *tuple; + ARG_LIST *e; + tuple = create_tuple(mpl); + for (e = code->arg.set.list; e != NULL; e = e->next) + tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, + e->x)); + value = copy_elemset(mpl, + eval_member_set(mpl, code->arg.set.set, tuple)); + delete_tuple(mpl, tuple); + } + break; + case O_MAKE: + /* make elemental set of n-tuples */ + { ARG_LIST *e; + value = create_elemset(mpl, code->dim); + for (e = code->arg.list; e != NULL; e = e->next) + check_then_add(mpl, value, eval_tuple(mpl, e->x)); + } + break; + case O_UNION: + /* union of two elemental sets */ + value = set_union(mpl, + eval_elemset(mpl, code->arg.arg.x), + eval_elemset(mpl, code->arg.arg.y)); + break; + case O_DIFF: + /* difference between two elemental sets */ + value = set_diff(mpl, + eval_elemset(mpl, code->arg.arg.x), + eval_elemset(mpl, code->arg.arg.y)); + break; + case O_SYMDIFF: + /* symmetric difference between two elemental sets */ + value = set_symdiff(mpl, + eval_elemset(mpl, code->arg.arg.x), + eval_elemset(mpl, code->arg.arg.y)); + break; + case O_INTER: + /* intersection of two elemental sets */ + value = set_inter(mpl, + eval_elemset(mpl, code->arg.arg.x), + eval_elemset(mpl, code->arg.arg.y)); + break; + case O_CROSS: + /* cross (Cartesian) product of two elemental sets */ + value = set_cross(mpl, + eval_elemset(mpl, code->arg.arg.x), + eval_elemset(mpl, code->arg.arg.y)); + break; + case O_DOTS: + /* build "arithmetic" elemental set */ + value = create_arelset(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_numeric(mpl, code->arg.arg.y), + code->arg.arg.z == NULL ? 1.0 : eval_numeric(mpl, + code->arg.arg.z)); + break; + case O_FORK: + /* if-then-else */ + if (eval_logical(mpl, code->arg.arg.x)) + value = eval_elemset(mpl, code->arg.arg.y); + else + value = eval_elemset(mpl, code->arg.arg.z); + break; + case O_SETOF: + /* compute elemental set */ + { struct iter_set_info _info, *info = &_info; + info->code = code; + info->value = create_elemset(mpl, code->dim); + loop_within_domain(mpl, code->arg.loop.domain, info, + iter_set_func); + value = info->value; + } + break; + case O_BUILD: + /* build elemental set identical to domain set */ + { struct iter_set_info _info, *info = &_info; + info->code = code; + info->value = create_elemset(mpl, code->dim); + loop_within_domain(mpl, code->arg.loop.domain, info, + iter_set_func); + value = info->value; + } + break; + default: + xassert(code != code); + } + /* save resultant value */ + xassert(!code->valid); + code->valid = 1; + code->value.set = copy_elemset(mpl, value); +done: return value; +} + +/*---------------------------------------------------------------------- +-- is_member - check if n-tuple is in set specified by pseudo-code. +-- +-- This routine checks if given n-tuple is a member of elemental set +-- specified in the form of pseudo-code (i.e. by expression). +-- +-- The n-tuple may have more components that dimension of the elemental +-- set, in which case the extra components are ignored. */ + +static void null_func(MPL *mpl, void *info) +{ /* this is dummy routine used to enter the domain scope */ + xassert(mpl == mpl); + xassert(info == NULL); + return; +} + +int is_member(MPL *mpl, CODE *code, TUPLE *tuple) +{ int value; + xassert(code != NULL); + xassert(code->type == A_ELEMSET); + xassert(code->dim > 0); + xassert(tuple != NULL); + switch (code->op) + { case O_MEMSET: + /* check if given n-tuple is member of elemental set, which + is assigned to member of model set */ + { ARG_LIST *e; + TUPLE *temp; + ELEMSET *set; + /* evaluate reference to elemental set */ + temp = create_tuple(mpl); + for (e = code->arg.set.list; e != NULL; e = e->next) + temp = expand_tuple(mpl, temp, eval_symbolic(mpl, + e->x)); + set = eval_member_set(mpl, code->arg.set.set, temp); + delete_tuple(mpl, temp); + /* check if the n-tuple is contained in the set array */ + temp = build_subtuple(mpl, tuple, set->dim); + value = (find_tuple(mpl, set, temp) != NULL); + delete_tuple(mpl, temp); + } + break; + case O_MAKE: + /* check if given n-tuple is member of literal set */ + { ARG_LIST *e; + TUPLE *temp, *that; + value = 0; + temp = build_subtuple(mpl, tuple, code->dim); + for (e = code->arg.list; e != NULL; e = e->next) + { that = eval_tuple(mpl, e->x); + value = (compare_tuples(mpl, temp, that) == 0); + delete_tuple(mpl, that); + if (value) break; + } + delete_tuple(mpl, temp); + } + break; + case O_UNION: + value = is_member(mpl, code->arg.arg.x, tuple) || + is_member(mpl, code->arg.arg.y, tuple); + break; + case O_DIFF: + value = is_member(mpl, code->arg.arg.x, tuple) && + !is_member(mpl, code->arg.arg.y, tuple); + break; + case O_SYMDIFF: + { int in1 = is_member(mpl, code->arg.arg.x, tuple); + int in2 = is_member(mpl, code->arg.arg.y, tuple); + value = (in1 && !in2) || (!in1 && in2); + } + break; + case O_INTER: + value = is_member(mpl, code->arg.arg.x, tuple) && + is_member(mpl, code->arg.arg.y, tuple); + break; + case O_CROSS: + { int j; + value = is_member(mpl, code->arg.arg.x, tuple); + if (value) + { for (j = 1; j <= code->arg.arg.x->dim; j++) + { xassert(tuple != NULL); + tuple = tuple->next; + } + value = is_member(mpl, code->arg.arg.y, tuple); + } + } + break; + case O_DOTS: + /* check if given 1-tuple is member of "arithmetic" set */ + { int j; + double x, t0, tf, dt; + xassert(code->dim == 1); + /* compute "parameters" of the "arithmetic" set */ + t0 = eval_numeric(mpl, code->arg.arg.x); + tf = eval_numeric(mpl, code->arg.arg.y); + if (code->arg.arg.z == NULL) + dt = 1.0; + else + dt = eval_numeric(mpl, code->arg.arg.z); + /* make sure the parameters are correct */ + arelset_size(mpl, t0, tf, dt); + /* if component of 1-tuple is symbolic, not numeric, the + 1-tuple cannot be member of "arithmetic" set */ + xassert(tuple->sym != NULL); + if (tuple->sym->str != NULL) + { value = 0; + break; + } + /* determine numeric value of the component */ + x = tuple->sym->num; + /* if the component value is out of the set range, the + 1-tuple is not in the set */ + if (dt > 0.0 && !(t0 <= x && x <= tf) || + dt < 0.0 && !(tf <= x && x <= t0)) + { value = 0; + break; + } + /* estimate ordinal number of the 1-tuple in the set */ + j = (int)(((x - t0) / dt) + 0.5) + 1; + /* perform the main check */ + value = (arelset_member(mpl, t0, tf, dt, j) == x); + } + break; + case O_FORK: + /* check if given n-tuple is member of conditional set */ + if (eval_logical(mpl, code->arg.arg.x)) + value = is_member(mpl, code->arg.arg.y, tuple); + else + value = is_member(mpl, code->arg.arg.z, tuple); + break; + case O_SETOF: + /* check if given n-tuple is member of computed set */ + /* it is not clear how to efficiently perform the check not + computing the entire elemental set :+( */ + error(mpl, "implementation restriction; in/within setof{} n" + "ot allowed"); + break; + case O_BUILD: + /* check if given n-tuple is member of domain set */ + { TUPLE *temp; + temp = build_subtuple(mpl, tuple, code->dim); + /* try to enter the domain scope; if it is successful, + the n-tuple is in the domain set */ + value = (eval_within_domain(mpl, code->arg.loop.domain, + temp, NULL, null_func) == 0); + delete_tuple(mpl, temp); + } + break; + default: + xassert(code != code); + } + return value; +} + +/*---------------------------------------------------------------------- +-- eval_formula - evaluate pseudo-code to construct linear form. +-- +-- This routine evaluates specified pseudo-code to construct resultant +-- linear form, which is returned on exit. */ + +struct iter_form_info +{ /* working info used by the routine iter_form_func */ + CODE *code; + /* pseudo-code for iterated operation to be performed */ + FORMULA *value; + /* resultant value */ + FORMULA *tail; + /* pointer to the last term */ +}; + +static int iter_form_func(MPL *mpl, void *_info) +{ /* this is auxiliary routine used to perform iterated operation + on linear form "integrand" within domain scope */ + struct iter_form_info *info = _info; + switch (info->code->op) + { case O_SUM: + /* summation over domain */ +#if 0 + info->value = + linear_comb(mpl, + +1.0, info->value, + +1.0, eval_formula(mpl, info->code->arg.loop.x)); +#else + /* the routine linear_comb needs to look through all terms + of both linear forms to reduce identical terms, so using + it here is not a good idea (for example, evaluation of + sum{i in 1..n} x[i] required quadratic time); the better + idea is to gather all terms of the integrand in one list + and reduce identical terms only once after all terms of + the resultant linear form have been evaluated */ + { FORMULA *form, *term; + form = eval_formula(mpl, info->code->arg.loop.x); + if (info->value == NULL) + { xassert(info->tail == NULL); + info->value = form; + } + else + { xassert(info->tail != NULL); + info->tail->next = form; + } + for (term = form; term != NULL; term = term->next) + info->tail = term; + } +#endif + break; + default: + xassert(info != info); + } + return 0; +} + +FORMULA *eval_formula(MPL *mpl, CODE *code) +{ FORMULA *value; + xassert(code != NULL); + xassert(code->type == A_FORMULA); + xassert(code->dim == 0); + /* if the operation has a side effect, invalidate and delete the + resultant value */ + if (code->vflag && code->valid) + { code->valid = 0; + delete_value(mpl, code->type, &code->value); + } + /* if resultant value is valid, no evaluation is needed */ + if (code->valid) + { value = copy_formula(mpl, code->value.form); + goto done; + } + /* evaluate pseudo-code recursively */ + switch (code->op) + { case O_MEMVAR: + /* take member of variable */ + { TUPLE *tuple; + ARG_LIST *e; + tuple = create_tuple(mpl); + for (e = code->arg.var.list; e != NULL; e = e->next) + tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, + e->x)); +#if 1 /* 15/V-2010 */ + xassert(code->arg.var.suff == DOT_NONE); +#endif + value = single_variable(mpl, + eval_member_var(mpl, code->arg.var.var, tuple)); + delete_tuple(mpl, tuple); + } + break; + case O_CVTLFM: + /* convert to linear form */ + value = constant_term(mpl, eval_numeric(mpl, + code->arg.arg.x)); + break; + case O_PLUS: + /* unary plus */ + value = linear_comb(mpl, + 0.0, constant_term(mpl, 0.0), + +1.0, eval_formula(mpl, code->arg.arg.x)); + break; + case O_MINUS: + /* unary minus */ + value = linear_comb(mpl, + 0.0, constant_term(mpl, 0.0), + -1.0, eval_formula(mpl, code->arg.arg.x)); + break; + case O_ADD: + /* addition */ + value = linear_comb(mpl, + +1.0, eval_formula(mpl, code->arg.arg.x), + +1.0, eval_formula(mpl, code->arg.arg.y)); + break; + case O_SUB: + /* subtraction */ + value = linear_comb(mpl, + +1.0, eval_formula(mpl, code->arg.arg.x), + -1.0, eval_formula(mpl, code->arg.arg.y)); + break; + case O_MUL: + /* multiplication */ + xassert(code->arg.arg.x != NULL); + xassert(code->arg.arg.y != NULL); + if (code->arg.arg.x->type == A_NUMERIC) + { xassert(code->arg.arg.y->type == A_FORMULA); + value = linear_comb(mpl, + eval_numeric(mpl, code->arg.arg.x), + eval_formula(mpl, code->arg.arg.y), + 0.0, constant_term(mpl, 0.0)); + } + else + { xassert(code->arg.arg.x->type == A_FORMULA); + xassert(code->arg.arg.y->type == A_NUMERIC); + value = linear_comb(mpl, + eval_numeric(mpl, code->arg.arg.y), + eval_formula(mpl, code->arg.arg.x), + 0.0, constant_term(mpl, 0.0)); + } + break; + case O_DIV: + /* division */ + value = linear_comb(mpl, + fp_div(mpl, 1.0, eval_numeric(mpl, code->arg.arg.y)), + eval_formula(mpl, code->arg.arg.x), + 0.0, constant_term(mpl, 0.0)); + break; + case O_FORK: + /* if-then-else */ + if (eval_logical(mpl, code->arg.arg.x)) + value = eval_formula(mpl, code->arg.arg.y); + else if (code->arg.arg.z == NULL) + value = constant_term(mpl, 0.0); + else + value = eval_formula(mpl, code->arg.arg.z); + break; + case O_SUM: + /* summation over domain */ + { struct iter_form_info _info, *info = &_info; + info->code = code; + info->value = constant_term(mpl, 0.0); + info->tail = NULL; + loop_within_domain(mpl, code->arg.loop.domain, info, + iter_form_func); + value = reduce_terms(mpl, info->value); + } + break; + default: + xassert(code != code); + } + /* save resultant value */ + xassert(!code->valid); + code->valid = 1; + code->value.form = copy_formula(mpl, value); +done: return value; +} + +/*---------------------------------------------------------------------- +-- clean_code - clean pseudo-code. +-- +-- This routine recursively cleans specified pseudo-code that assumes +-- deleting all temporary resultant values. */ + +void clean_code(MPL *mpl, CODE *code) +{ ARG_LIST *e; + /* if no pseudo-code is specified, do nothing */ + if (code == NULL) goto done; + /* if resultant value is valid (exists), delete it */ + if (code->valid) + { code->valid = 0; + delete_value(mpl, code->type, &code->value); + } + /* recursively clean pseudo-code for operands */ + switch (code->op) + { case O_NUMBER: + case O_STRING: + case O_INDEX: + break; + case O_MEMNUM: + case O_MEMSYM: + for (e = code->arg.par.list; e != NULL; e = e->next) + clean_code(mpl, e->x); + break; + case O_MEMSET: + for (e = code->arg.set.list; e != NULL; e = e->next) + clean_code(mpl, e->x); + break; + case O_MEMVAR: + for (e = code->arg.var.list; e != NULL; e = e->next) + clean_code(mpl, e->x); + break; +#if 1 /* 15/V-2010 */ + case O_MEMCON: + for (e = code->arg.con.list; e != NULL; e = e->next) + clean_code(mpl, e->x); + break; +#endif + case O_TUPLE: + case O_MAKE: + for (e = code->arg.list; e != NULL; e = e->next) + clean_code(mpl, e->x); + break; + case O_SLICE: + xassert(code != code); + case O_IRAND224: + case O_UNIFORM01: + case O_NORMAL01: + case O_GMTIME: + break; + case O_CVTNUM: + case O_CVTSYM: + case O_CVTLOG: + case O_CVTTUP: + case O_CVTLFM: + case O_PLUS: + case O_MINUS: + case O_NOT: + case O_ABS: + case O_CEIL: + case O_FLOOR: + case O_EXP: + case O_LOG: + case O_LOG10: + case O_SQRT: + case O_SIN: + case O_COS: + case O_ATAN: + case O_ROUND: + case O_TRUNC: + case O_CARD: + case O_LENGTH: + /* unary operation */ + clean_code(mpl, code->arg.arg.x); + break; + case O_ADD: + case O_SUB: + case O_LESS: + case O_MUL: + case O_DIV: + case O_IDIV: + case O_MOD: + case O_POWER: + case O_ATAN2: + case O_ROUND2: + case O_TRUNC2: + case O_UNIFORM: + case O_NORMAL: + case O_CONCAT: + case O_LT: + case O_LE: + case O_EQ: + case O_GE: + case O_GT: + case O_NE: + case O_AND: + case O_OR: + case O_UNION: + case O_DIFF: + case O_SYMDIFF: + case O_INTER: + case O_CROSS: + case O_IN: + case O_NOTIN: + case O_WITHIN: + case O_NOTWITHIN: + case O_SUBSTR: + case O_STR2TIME: + case O_TIME2STR: + /* binary operation */ + clean_code(mpl, code->arg.arg.x); + clean_code(mpl, code->arg.arg.y); + break; + case O_DOTS: + case O_FORK: + case O_SUBSTR3: + /* ternary operation */ + clean_code(mpl, code->arg.arg.x); + clean_code(mpl, code->arg.arg.y); + clean_code(mpl, code->arg.arg.z); + break; + case O_MIN: + case O_MAX: + /* n-ary operation */ + for (e = code->arg.list; e != NULL; e = e->next) + clean_code(mpl, e->x); + break; + case O_SUM: + case O_PROD: + case O_MINIMUM: + case O_MAXIMUM: + case O_FORALL: + case O_EXISTS: + case O_SETOF: + case O_BUILD: + /* iterated operation */ + clean_domain(mpl, code->arg.loop.domain); + clean_code(mpl, code->arg.loop.x); + break; + default: + xassert(code->op != code->op); + } +done: return; +} + +#if 1 /* 11/II-2008 */ +/**********************************************************************/ +/* * * DATA TABLES * * */ +/**********************************************************************/ + +int mpl_tab_num_args(TABDCA *dca) +{ /* returns the number of arguments */ + return dca->na; +} + +const char *mpl_tab_get_arg(TABDCA *dca, int k) +{ /* returns pointer to k-th argument */ + xassert(1 <= k && k <= dca->na); + return dca->arg[k]; +} + +int mpl_tab_num_flds(TABDCA *dca) +{ /* returns the number of fields */ + return dca->nf; +} + +const char *mpl_tab_get_name(TABDCA *dca, int k) +{ /* returns pointer to name of k-th field */ + xassert(1 <= k && k <= dca->nf); + return dca->name[k]; +} + +int mpl_tab_get_type(TABDCA *dca, int k) +{ /* returns type of k-th field */ + xassert(1 <= k && k <= dca->nf); + return dca->type[k]; +} + +double mpl_tab_get_num(TABDCA *dca, int k) +{ /* returns numeric value of k-th field */ + xassert(1 <= k && k <= dca->nf); + xassert(dca->type[k] == 'N'); + return dca->num[k]; +} + +const char *mpl_tab_get_str(TABDCA *dca, int k) +{ /* returns pointer to string value of k-th field */ + xassert(1 <= k && k <= dca->nf); + xassert(dca->type[k] == 'S'); + xassert(dca->str[k] != NULL); + return dca->str[k]; +} + +void mpl_tab_set_num(TABDCA *dca, int k, double num) +{ /* assign numeric value to k-th field */ + xassert(1 <= k && k <= dca->nf); + xassert(dca->type[k] == '?'); + dca->type[k] = 'N'; + dca->num[k] = num; + return; +} + +void mpl_tab_set_str(TABDCA *dca, int k, const char *str) +{ /* assign string value to k-th field */ + xassert(1 <= k && k <= dca->nf); + xassert(dca->type[k] == '?'); + xassert(strlen(str) <= MAX_LENGTH); + xassert(dca->str[k] != NULL); + dca->type[k] = 'S'; + strcpy(dca->str[k], str); + return; +} + +static int write_func(MPL *mpl, void *info) +{ /* this is auxiliary routine to work within domain scope */ + TABLE *tab = info; + TABDCA *dca = mpl->dca; + TABOUT *out; + SYMBOL *sym; + int k; + char buf[MAX_LENGTH+1]; + /* evaluate field values */ + k = 0; + for (out = tab->u.out.list; out != NULL; out = out->next) + { k++; + switch (out->code->type) + { case A_NUMERIC: + dca->type[k] = 'N'; + dca->num[k] = eval_numeric(mpl, out->code); + dca->str[k][0] = '\0'; + break; + case A_SYMBOLIC: + sym = eval_symbolic(mpl, out->code); + if (sym->str == NULL) + { dca->type[k] = 'N'; + dca->num[k] = sym->num; + dca->str[k][0] = '\0'; + } + else + { dca->type[k] = 'S'; + dca->num[k] = 0.0; + fetch_string(mpl, sym->str, buf); + strcpy(dca->str[k], buf); + } + delete_symbol(mpl, sym); + break; + default: + xassert(out != out); + } + } + /* write record to output table */ + mpl_tab_drv_write(mpl); + return 0; +} + +void execute_table(MPL *mpl, TABLE *tab) +{ /* execute table statement */ + TABARG *arg; + TABFLD *fld; + TABIN *in; + TABOUT *out; + TABDCA *dca; + SET *set; + int k; + char buf[MAX_LENGTH+1]; + /* allocate table driver communication area */ + xassert(mpl->dca == NULL); + mpl->dca = dca = xmalloc(sizeof(TABDCA)); + dca->id = 0; + dca->link = NULL; + dca->na = 0; + dca->arg = NULL; + dca->nf = 0; + dca->name = NULL; + dca->type = NULL; + dca->num = NULL; + dca->str = NULL; + /* allocate arguments */ + xassert(dca->na == 0); + for (arg = tab->arg; arg != NULL; arg = arg->next) + dca->na++; + dca->arg = xcalloc(1+dca->na, sizeof(char *)); +#if 1 /* 28/IX-2008 */ + for (k = 1; k <= dca->na; k++) dca->arg[k] = NULL; +#endif + /* evaluate argument values */ + k = 0; + for (arg = tab->arg; arg != NULL; arg = arg->next) + { SYMBOL *sym; + k++; + xassert(arg->code->type == A_SYMBOLIC); + sym = eval_symbolic(mpl, arg->code); + if (sym->str == NULL) + sprintf(buf, "%.*g", DBL_DIG, sym->num); + else + fetch_string(mpl, sym->str, buf); + delete_symbol(mpl, sym); + dca->arg[k] = xmalloc(strlen(buf)+1); + strcpy(dca->arg[k], buf); + } + /* perform table input/output */ + switch (tab->type) + { case A_INPUT: goto read_table; + case A_OUTPUT: goto write_table; + default: xassert(tab != tab); + } +read_table: + /* read data from input table */ + /* add the only member to the control set and assign it empty + elemental set */ + set = tab->u.in.set; + if (set != NULL) + { if (set->data) + error(mpl, "%s already provided with data", set->name); + xassert(set->array->head == NULL); + add_member(mpl, set->array, NULL)->value.set = + create_elemset(mpl, set->dimen); + set->data = 1; + } + /* check parameters specified in the input list */ + for (in = tab->u.in.list; in != NULL; in = in->next) + { if (in->par->data) + error(mpl, "%s already provided with data", in->par->name); + in->par->data = 1; + } + /* allocate and initialize fields */ + xassert(dca->nf == 0); + for (fld = tab->u.in.fld; fld != NULL; fld = fld->next) + dca->nf++; + for (in = tab->u.in.list; in != NULL; in = in->next) + dca->nf++; + dca->name = xcalloc(1+dca->nf, sizeof(char *)); + dca->type = xcalloc(1+dca->nf, sizeof(int)); + dca->num = xcalloc(1+dca->nf, sizeof(double)); + dca->str = xcalloc(1+dca->nf, sizeof(char *)); + k = 0; + for (fld = tab->u.in.fld; fld != NULL; fld = fld->next) + { k++; + dca->name[k] = fld->name; + dca->type[k] = '?'; + dca->num[k] = 0.0; + dca->str[k] = xmalloc(MAX_LENGTH+1); + dca->str[k][0] = '\0'; + } + for (in = tab->u.in.list; in != NULL; in = in->next) + { k++; + dca->name[k] = in->name; + dca->type[k] = '?'; + dca->num[k] = 0.0; + dca->str[k] = xmalloc(MAX_LENGTH+1); + dca->str[k][0] = '\0'; + } + /* open input table */ + mpl_tab_drv_open(mpl, 'R'); + /* read and process records */ + for (;;) + { TUPLE *tup; + /* reset field types */ + for (k = 1; k <= dca->nf; k++) + dca->type[k] = '?'; + /* read next record */ + if (mpl_tab_drv_read(mpl)) break; + /* all fields must be set by the driver */ + for (k = 1; k <= dca->nf; k++) + { if (dca->type[k] == '?') + error(mpl, "field %s missing in input table", + dca->name[k]); + } + /* construct n-tuple */ + tup = create_tuple(mpl); + k = 0; + for (fld = tab->u.in.fld; fld != NULL; fld = fld->next) + { k++; + xassert(k <= dca->nf); + switch (dca->type[k]) + { case 'N': + tup = expand_tuple(mpl, tup, create_symbol_num(mpl, + dca->num[k])); + break; + case 'S': + xassert(strlen(dca->str[k]) <= MAX_LENGTH); + tup = expand_tuple(mpl, tup, create_symbol_str(mpl, + create_string(mpl, dca->str[k]))); + break; + default: + xassert(dca != dca); + } + } + /* add n-tuple just read to the control set */ + if (tab->u.in.set != NULL) + check_then_add(mpl, tab->u.in.set->array->head->value.set, + copy_tuple(mpl, tup)); + /* assign values to the parameters in the input list */ + for (in = tab->u.in.list; in != NULL; in = in->next) + { MEMBER *memb; + k++; + xassert(k <= dca->nf); + /* there must be no member with the same n-tuple */ + if (find_member(mpl, in->par->array, tup) != NULL) + error(mpl, "%s%s already defined", in->par->name, + format_tuple(mpl, '[', tup)); + /* create new parameter member with given n-tuple */ + memb = add_member(mpl, in->par->array, copy_tuple(mpl, tup)) + ; + /* assign value to the parameter member */ + switch (in->par->type) + { case A_NUMERIC: + case A_INTEGER: + case A_BINARY: + if (dca->type[k] != 'N') + error(mpl, "%s requires numeric data", + in->par->name); + memb->value.num = dca->num[k]; + break; + case A_SYMBOLIC: + switch (dca->type[k]) + { case 'N': + memb->value.sym = create_symbol_num(mpl, + dca->num[k]); + break; + case 'S': + xassert(strlen(dca->str[k]) <= MAX_LENGTH); + memb->value.sym = create_symbol_str(mpl, + create_string(mpl,dca->str[k])); + break; + default: + xassert(dca != dca); + } + break; + default: + xassert(in != in); + } + } + /* n-tuple is no more needed */ + delete_tuple(mpl, tup); + } + /* close input table */ + mpl_tab_drv_close(mpl); + goto done; +write_table: + /* write data to output table */ + /* allocate and initialize fields */ + xassert(dca->nf == 0); + for (out = tab->u.out.list; out != NULL; out = out->next) + dca->nf++; + dca->name = xcalloc(1+dca->nf, sizeof(char *)); + dca->type = xcalloc(1+dca->nf, sizeof(int)); + dca->num = xcalloc(1+dca->nf, sizeof(double)); + dca->str = xcalloc(1+dca->nf, sizeof(char *)); + k = 0; + for (out = tab->u.out.list; out != NULL; out = out->next) + { k++; + dca->name[k] = out->name; + dca->type[k] = '?'; + dca->num[k] = 0.0; + dca->str[k] = xmalloc(MAX_LENGTH+1); + dca->str[k][0] = '\0'; + } + /* open output table */ + mpl_tab_drv_open(mpl, 'W'); + /* evaluate fields and write records */ + loop_within_domain(mpl, tab->u.out.domain, tab, write_func); + /* close output table */ + mpl_tab_drv_close(mpl); +done: /* free table driver communication area */ + free_dca(mpl); + return; +} + +void free_dca(MPL *mpl) +{ /* free table driver communucation area */ + TABDCA *dca = mpl->dca; + int k; + if (dca != NULL) + { if (dca->link != NULL) + mpl_tab_drv_close(mpl); + if (dca->arg != NULL) + { for (k = 1; k <= dca->na; k++) +#if 1 /* 28/IX-2008 */ + if (dca->arg[k] != NULL) +#endif + xfree(dca->arg[k]); + xfree(dca->arg); + } + if (dca->name != NULL) xfree(dca->name); + if (dca->type != NULL) xfree(dca->type); + if (dca->num != NULL) xfree(dca->num); + if (dca->str != NULL) + { for (k = 1; k <= dca->nf; k++) + xfree(dca->str[k]); + xfree(dca->str); + } + xfree(dca), mpl->dca = NULL; + } + return; +} + +void clean_table(MPL *mpl, TABLE *tab) +{ /* clean table statement */ + TABARG *arg; + TABOUT *out; + /* clean string list */ + for (arg = tab->arg; arg != NULL; arg = arg->next) + clean_code(mpl, arg->code); + switch (tab->type) + { case A_INPUT: + break; + case A_OUTPUT: + /* clean subscript domain */ + clean_domain(mpl, tab->u.out.domain); + /* clean output list */ + for (out = tab->u.out.list; out != NULL; out = out->next) + clean_code(mpl, out->code); + break; + default: + xassert(tab != tab); + } + return; +} +#endif + +/**********************************************************************/ +/* * * MODEL STATEMENTS * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- execute_check - execute check statement. +-- +-- This routine executes specified check statement. */ + +static int check_func(MPL *mpl, void *info) +{ /* this is auxiliary routine to work within domain scope */ + CHECK *chk = (CHECK *)info; + if (!eval_logical(mpl, chk->code)) + error(mpl, "check%s failed", format_tuple(mpl, '[', + get_domain_tuple(mpl, chk->domain))); + return 0; +} + +void execute_check(MPL *mpl, CHECK *chk) +{ loop_within_domain(mpl, chk->domain, chk, check_func); + return; +} + +/*---------------------------------------------------------------------- +-- clean_check - clean check statement. +-- +-- This routine cleans specified check statement that assumes deleting +-- all stuff dynamically allocated on generating/postsolving phase. */ + +void clean_check(MPL *mpl, CHECK *chk) +{ /* clean subscript domain */ + clean_domain(mpl, chk->domain); + /* clean pseudo-code for computing predicate */ + clean_code(mpl, chk->code); + return; +} + +/*---------------------------------------------------------------------- +-- execute_display - execute display statement. +-- +-- This routine executes specified display statement. */ + +static void display_set(MPL *mpl, SET *set, MEMBER *memb) +{ /* display member of model set */ + ELEMSET *s = memb->value.set; + MEMBER *m; + write_text(mpl, "%s%s%s\n", set->name, + format_tuple(mpl, '[', memb->tuple), + s->head == NULL ? " is empty" : ":"); + for (m = s->head; m != NULL; m = m->next) + write_text(mpl, " %s\n", format_tuple(mpl, '(', m->tuple)); + return; +} + +static void display_par(MPL *mpl, PARAMETER *par, MEMBER *memb) +{ /* display member of model parameter */ + switch (par->type) + { case A_NUMERIC: + case A_INTEGER: + case A_BINARY: + write_text(mpl, "%s%s = %.*g\n", par->name, + format_tuple(mpl, '[', memb->tuple), + DBL_DIG, memb->value.num); + break; + case A_SYMBOLIC: + write_text(mpl, "%s%s = %s\n", par->name, + format_tuple(mpl, '[', memb->tuple), + format_symbol(mpl, memb->value.sym)); + break; + default: + xassert(par != par); + } + return; +} + +#if 1 /* 15/V-2010 */ +static void display_var(MPL *mpl, VARIABLE *var, MEMBER *memb, + int suff) +{ /* display member of model variable */ + if (suff == DOT_NONE || suff == DOT_VAL) + write_text(mpl, "%s%s.val = %.*g\n", var->name, + format_tuple(mpl, '[', memb->tuple), DBL_DIG, + memb->value.var->prim); + else if (suff == DOT_LB) + write_text(mpl, "%s%s.lb = %.*g\n", var->name, + format_tuple(mpl, '[', memb->tuple), DBL_DIG, + memb->value.var->var->lbnd == NULL ? -DBL_MAX : + memb->value.var->lbnd); + else if (suff == DOT_UB) + write_text(mpl, "%s%s.ub = %.*g\n", var->name, + format_tuple(mpl, '[', memb->tuple), DBL_DIG, + memb->value.var->var->ubnd == NULL ? +DBL_MAX : + memb->value.var->ubnd); + else if (suff == DOT_STATUS) + write_text(mpl, "%s%s.status = %d\n", var->name, format_tuple + (mpl, '[', memb->tuple), memb->value.var->stat); + else if (suff == DOT_DUAL) + write_text(mpl, "%s%s.dual = %.*g\n", var->name, + format_tuple(mpl, '[', memb->tuple), DBL_DIG, + memb->value.var->dual); + else + xassert(suff != suff); + return; +} +#endif + +#if 1 /* 15/V-2010 */ +static void display_con(MPL *mpl, CONSTRAINT *con, MEMBER *memb, + int suff) +{ /* display member of model constraint */ + if (suff == DOT_NONE || suff == DOT_VAL) + write_text(mpl, "%s%s.val = %.*g\n", con->name, + format_tuple(mpl, '[', memb->tuple), DBL_DIG, + memb->value.con->prim); + else if (suff == DOT_LB) + write_text(mpl, "%s%s.lb = %.*g\n", con->name, + format_tuple(mpl, '[', memb->tuple), DBL_DIG, + memb->value.con->con->lbnd == NULL ? -DBL_MAX : + memb->value.con->lbnd); + else if (suff == DOT_UB) + write_text(mpl, "%s%s.ub = %.*g\n", con->name, + format_tuple(mpl, '[', memb->tuple), DBL_DIG, + memb->value.con->con->ubnd == NULL ? +DBL_MAX : + memb->value.con->ubnd); + else if (suff == DOT_STATUS) + write_text(mpl, "%s%s.status = %d\n", con->name, format_tuple + (mpl, '[', memb->tuple), memb->value.con->stat); + else if (suff == DOT_DUAL) + write_text(mpl, "%s%s.dual = %.*g\n", con->name, + format_tuple(mpl, '[', memb->tuple), DBL_DIG, + memb->value.con->dual); + else + xassert(suff != suff); + return; +} +#endif + +static void display_memb(MPL *mpl, CODE *code) +{ /* display member specified by pseudo-code */ + MEMBER memb; + ARG_LIST *e; + xassert(code->op == O_MEMNUM || code->op == O_MEMSYM + || code->op == O_MEMSET || code->op == O_MEMVAR + || code->op == O_MEMCON); + memb.tuple = create_tuple(mpl); + for (e = code->arg.par.list; e != NULL; e = e->next) + memb.tuple = expand_tuple(mpl, memb.tuple, eval_symbolic(mpl, + e->x)); + switch (code->op) + { case O_MEMNUM: + memb.value.num = eval_member_num(mpl, code->arg.par.par, + memb.tuple); + display_par(mpl, code->arg.par.par, &memb); + break; + case O_MEMSYM: + memb.value.sym = eval_member_sym(mpl, code->arg.par.par, + memb.tuple); + display_par(mpl, code->arg.par.par, &memb); + delete_symbol(mpl, memb.value.sym); + break; + case O_MEMSET: + memb.value.set = eval_member_set(mpl, code->arg.set.set, + memb.tuple); + display_set(mpl, code->arg.set.set, &memb); + break; + case O_MEMVAR: + memb.value.var = eval_member_var(mpl, code->arg.var.var, + memb.tuple); + display_var + (mpl, code->arg.var.var, &memb, code->arg.var.suff); + break; + case O_MEMCON: + memb.value.con = eval_member_con(mpl, code->arg.con.con, + memb.tuple); + display_con + (mpl, code->arg.con.con, &memb, code->arg.con.suff); + break; + default: + xassert(code != code); + } + delete_tuple(mpl, memb.tuple); + return; +} + +static void display_code(MPL *mpl, CODE *code) +{ /* display value of expression */ + switch (code->type) + { case A_NUMERIC: + /* numeric value */ + { double num; + num = eval_numeric(mpl, code); + write_text(mpl, "%.*g\n", DBL_DIG, num); + } + break; + case A_SYMBOLIC: + /* symbolic value */ + { SYMBOL *sym; + sym = eval_symbolic(mpl, code); + write_text(mpl, "%s\n", format_symbol(mpl, sym)); + delete_symbol(mpl, sym); + } + break; + case A_LOGICAL: + /* logical value */ + { int bit; + bit = eval_logical(mpl, code); + write_text(mpl, "%s\n", bit ? "true" : "false"); + } + break; + case A_TUPLE: + /* n-tuple */ + { TUPLE *tuple; + tuple = eval_tuple(mpl, code); + write_text(mpl, "%s\n", format_tuple(mpl, '(', tuple)); + delete_tuple(mpl, tuple); + } + break; + case A_ELEMSET: + /* elemental set */ + { ELEMSET *set; + MEMBER *memb; + set = eval_elemset(mpl, code); + if (set->head == 0) + write_text(mpl, "set is empty\n"); + for (memb = set->head; memb != NULL; memb = memb->next) + write_text(mpl, " %s\n", format_tuple(mpl, '(', + memb->tuple)); + delete_elemset(mpl, set); + } + break; + case A_FORMULA: + /* linear form */ + { FORMULA *form, *term; + form = eval_formula(mpl, code); + if (form == NULL) + write_text(mpl, "linear form is empty\n"); + for (term = form; term != NULL; term = term->next) + { if (term->var == NULL) + write_text(mpl, " %.*g\n", term->coef); + else + write_text(mpl, " %.*g %s%s\n", DBL_DIG, + term->coef, term->var->var->name, + format_tuple(mpl, '[', term->var->memb->tuple)); + } + delete_formula(mpl, form); + } + break; + default: + xassert(code != code); + } + return; +} + +static int display_func(MPL *mpl, void *info) +{ /* this is auxiliary routine to work within domain scope */ + DISPLAY *dpy = (DISPLAY *)info; + DISPLAY1 *entry; + for (entry = dpy->list; entry != NULL; entry = entry->next) + { if (entry->type == A_INDEX) + { /* dummy index */ + DOMAIN_SLOT *slot = entry->u.slot; + write_text(mpl, "%s = %s\n", slot->name, + format_symbol(mpl, slot->value)); + } + else if (entry->type == A_SET) + { /* model set */ + SET *set = entry->u.set; + MEMBER *memb; + if (set->assign != NULL) + { /* the set has assignment expression; evaluate all its + members over entire domain */ + eval_whole_set(mpl, set); + } + else + { /* the set has no assignment expression; refer to its + any existing member ignoring resultant value to check + the data provided the data section */ +#if 1 /* 12/XII-2008 */ + if (set->gadget != NULL && set->data == 0) + { /* initialize the set with data from a plain set */ + saturate_set(mpl, set); + } +#endif + if (set->array->head != NULL) + eval_member_set(mpl, set, set->array->head->tuple); + } + /* display all members of the set array */ + if (set->array->head == NULL) + write_text(mpl, "%s has empty content\n", set->name); + for (memb = set->array->head; memb != NULL; memb = + memb->next) display_set(mpl, set, memb); + } + else if (entry->type == A_PARAMETER) + { /* model parameter */ + PARAMETER *par = entry->u.par; + MEMBER *memb; + if (par->assign != NULL) + { /* the parameter has an assignment expression; evaluate + all its member over entire domain */ + eval_whole_par(mpl, par); + } + else + { /* the parameter has no assignment expression; refer to + its any existing member ignoring resultant value to + check the data provided in the data section */ + if (par->array->head != NULL) + { if (par->type != A_SYMBOLIC) + eval_member_num(mpl, par, par->array->head->tuple); + else + delete_symbol(mpl, eval_member_sym(mpl, par, + par->array->head->tuple)); + } + } + /* display all members of the parameter array */ + if (par->array->head == NULL) + write_text(mpl, "%s has empty content\n", par->name); + for (memb = par->array->head; memb != NULL; memb = + memb->next) display_par(mpl, par, memb); + } + else if (entry->type == A_VARIABLE) + { /* model variable */ + VARIABLE *var = entry->u.var; + MEMBER *memb; + xassert(mpl->flag_p); + /* display all members of the variable array */ + if (var->array->head == NULL) + write_text(mpl, "%s has empty content\n", var->name); + for (memb = var->array->head; memb != NULL; memb = + memb->next) display_var(mpl, var, memb, DOT_NONE); + } + else if (entry->type == A_CONSTRAINT) + { /* model constraint */ + CONSTRAINT *con = entry->u.con; + MEMBER *memb; + xassert(mpl->flag_p); + /* display all members of the constraint array */ + if (con->array->head == NULL) + write_text(mpl, "%s has empty content\n", con->name); + for (memb = con->array->head; memb != NULL; memb = + memb->next) display_con(mpl, con, memb, DOT_NONE); + } + else if (entry->type == A_EXPRESSION) + { /* expression */ + CODE *code = entry->u.code; + if (code->op == O_MEMNUM || code->op == O_MEMSYM || + code->op == O_MEMSET || code->op == O_MEMVAR || + code->op == O_MEMCON) + display_memb(mpl, code); + else + display_code(mpl, code); + } + else + xassert(entry != entry); + } + return 0; +} + +void execute_display(MPL *mpl, DISPLAY *dpy) +{ loop_within_domain(mpl, dpy->domain, dpy, display_func); + return; +} + +/*---------------------------------------------------------------------- +-- clean_display - clean display statement. +-- +-- This routine cleans specified display statement that assumes deleting +-- all stuff dynamically allocated on generating/postsolving phase. */ + +void clean_display(MPL *mpl, DISPLAY *dpy) +{ DISPLAY1 *d; +#if 0 /* 15/V-2010 */ + ARG_LIST *e; +#endif + /* clean subscript domain */ + clean_domain(mpl, dpy->domain); + /* clean display list */ + for (d = dpy->list; d != NULL; d = d->next) + { /* clean pseudo-code for computing expression */ + if (d->type == A_EXPRESSION) + clean_code(mpl, d->u.code); +#if 0 /* 15/V-2010 */ + /* clean pseudo-code for computing subscripts */ + for (e = d->list; e != NULL; e = e->next) + clean_code(mpl, e->x); +#endif + } + return; +} + +/*---------------------------------------------------------------------- +-- execute_printf - execute printf statement. +-- +-- This routine executes specified printf statement. */ + +#if 1 /* 14/VII-2006 */ +static void print_char(MPL *mpl, int c) +{ if (mpl->prt_fp == NULL) + write_char(mpl, c); + else +#if 0 /* 04/VIII-2013 */ + xfputc(c, mpl->prt_fp); +#else + { unsigned char buf[1]; + buf[0] = (unsigned char)c; + glp_write(mpl->prt_fp, buf, 1); + } +#endif + return; +} + +static void print_text(MPL *mpl, char *fmt, ...) +{ va_list arg; + char buf[OUTBUF_SIZE], *c; + va_start(arg, fmt); + vsprintf(buf, fmt, arg); + xassert(strlen(buf) < sizeof(buf)); + va_end(arg); + for (c = buf; *c != '\0'; c++) print_char(mpl, *c); + return; +} +#endif + +static int printf_func(MPL *mpl, void *info) +{ /* this is auxiliary routine to work within domain scope */ + PRINTF *prt = (PRINTF *)info; + PRINTF1 *entry; + SYMBOL *sym; + char fmt[MAX_LENGTH+1], *c, *from, save; + /* evaluate format control string */ + sym = eval_symbolic(mpl, prt->fmt); + if (sym->str == NULL) + sprintf(fmt, "%.*g", DBL_DIG, sym->num); + else + fetch_string(mpl, sym->str, fmt); + delete_symbol(mpl, sym); + /* scan format control string and perform formatting output */ + entry = prt->list; + for (c = fmt; *c != '\0'; c++) + { if (*c == '%') + { /* scan format specifier */ + from = c++; + if (*c == '%') + { print_char(mpl, '%'); + continue; + } + if (entry == NULL) break; + /* scan optional flags */ + while (*c == '-' || *c == '+' || *c == ' ' || *c == '#' || + *c == '0') c++; + /* scan optional minimum field width */ + while (isdigit((unsigned char)*c)) c++; + /* scan optional precision */ + if (*c == '.') + { c++; + while (isdigit((unsigned char)*c)) c++; + } + /* scan conversion specifier and perform formatting */ + save = *(c+1), *(c+1) = '\0'; + if (*c == 'd' || *c == 'i' || *c == 'e' || *c == 'E' || + *c == 'f' || *c == 'F' || *c == 'g' || *c == 'G') + { /* the specifier requires numeric value */ + double value; + xassert(entry != NULL); + switch (entry->code->type) + { case A_NUMERIC: + value = eval_numeric(mpl, entry->code); + break; + case A_SYMBOLIC: + sym = eval_symbolic(mpl, entry->code); + if (sym->str != NULL) + error(mpl, "cannot convert %s to floating-point" + " number", format_symbol(mpl, sym)); + value = sym->num; + delete_symbol(mpl, sym); + break; + case A_LOGICAL: + if (eval_logical(mpl, entry->code)) + value = 1.0; + else + value = 0.0; + break; + default: + xassert(entry != entry); + } + if (*c == 'd' || *c == 'i') + { double int_max = (double)INT_MAX; + if (!(-int_max <= value && value <= +int_max)) + error(mpl, "cannot convert %.*g to integer", + DBL_DIG, value); + print_text(mpl, from, (int)floor(value + 0.5)); + } + else + print_text(mpl, from, value); + } + else if (*c == 's') + { /* the specifier requires symbolic value */ + char value[MAX_LENGTH+1]; + switch (entry->code->type) + { case A_NUMERIC: + sprintf(value, "%.*g", DBL_DIG, eval_numeric(mpl, + entry->code)); + break; + case A_LOGICAL: + if (eval_logical(mpl, entry->code)) + strcpy(value, "T"); + else + strcpy(value, "F"); + break; + case A_SYMBOLIC: + sym = eval_symbolic(mpl, entry->code); + if (sym->str == NULL) + sprintf(value, "%.*g", DBL_DIG, sym->num); + else + fetch_string(mpl, sym->str, value); + delete_symbol(mpl, sym); + break; + default: + xassert(entry != entry); + } + print_text(mpl, from, value); + } + else + error(mpl, "format specifier missing or invalid"); + *(c+1) = save; + entry = entry->next; + } + else if (*c == '\\') + { /* write some control character */ + c++; + if (*c == 't') + print_char(mpl, '\t'); + else if (*c == 'n') + print_char(mpl, '\n'); +#if 1 /* 28/X-2010 */ + else if (*c == '\0') + { /* format string ends with backslash */ + error(mpl, "invalid use of escape character \\ in format" + " control string"); + } +#endif + else + print_char(mpl, *c); + } + else + { /* write character without formatting */ + print_char(mpl, *c); + } + } + return 0; +} + +#if 0 /* 14/VII-2006 */ +void execute_printf(MPL *mpl, PRINTF *prt) +{ loop_within_domain(mpl, prt->domain, prt, printf_func); + return; +} +#else +void execute_printf(MPL *mpl, PRINTF *prt) +{ if (prt->fname == NULL) + { /* switch to the standard output */ + if (mpl->prt_fp != NULL) + { glp_close(mpl->prt_fp), mpl->prt_fp = NULL; + xfree(mpl->prt_file), mpl->prt_file = NULL; + } + } + else + { /* evaluate file name string */ + SYMBOL *sym; + char fname[MAX_LENGTH+1]; + sym = eval_symbolic(mpl, prt->fname); + if (sym->str == NULL) + sprintf(fname, "%.*g", DBL_DIG, sym->num); + else + fetch_string(mpl, sym->str, fname); + delete_symbol(mpl, sym); + /* close the current print file, if necessary */ + if (mpl->prt_fp != NULL && + (!prt->app || strcmp(mpl->prt_file, fname) != 0)) + { glp_close(mpl->prt_fp), mpl->prt_fp = NULL; + xfree(mpl->prt_file), mpl->prt_file = NULL; + } + /* open the specified print file, if necessary */ + if (mpl->prt_fp == NULL) + { mpl->prt_fp = glp_open(fname, prt->app ? "a" : "w"); + if (mpl->prt_fp == NULL) + error(mpl, "unable to open '%s' for writing - %s", + fname, get_err_msg()); + mpl->prt_file = xmalloc(strlen(fname)+1); + strcpy(mpl->prt_file, fname); + } + } + loop_within_domain(mpl, prt->domain, prt, printf_func); + if (mpl->prt_fp != NULL) + { +#if 0 /* FIXME */ + xfflush(mpl->prt_fp); +#endif + if (glp_ioerr(mpl->prt_fp)) + error(mpl, "writing error to '%s' - %s", mpl->prt_file, + get_err_msg()); + } + return; +} +#endif + +/*---------------------------------------------------------------------- +-- clean_printf - clean printf statement. +-- +-- This routine cleans specified printf statement that assumes deleting +-- all stuff dynamically allocated on generating/postsolving phase. */ + +void clean_printf(MPL *mpl, PRINTF *prt) +{ PRINTF1 *p; + /* clean subscript domain */ + clean_domain(mpl, prt->domain); + /* clean pseudo-code for computing format string */ + clean_code(mpl, prt->fmt); + /* clean printf list */ + for (p = prt->list; p != NULL; p = p->next) + { /* clean pseudo-code for computing value to be printed */ + clean_code(mpl, p->code); + } +#if 1 /* 14/VII-2006 */ + /* clean pseudo-code for computing file name string */ + clean_code(mpl, prt->fname); +#endif + return; +} + +/*---------------------------------------------------------------------- +-- execute_for - execute for statement. +-- +-- This routine executes specified for statement. */ + +static int for_func(MPL *mpl, void *info) +{ /* this is auxiliary routine to work within domain scope */ + FOR *fur = (FOR *)info; + STATEMENT *stmt, *save; + save = mpl->stmt; + for (stmt = fur->list; stmt != NULL; stmt = stmt->next) + execute_statement(mpl, stmt); + mpl->stmt = save; + return 0; +} + +void execute_for(MPL *mpl, FOR *fur) +{ loop_within_domain(mpl, fur->domain, fur, for_func); + return; +} + +/*---------------------------------------------------------------------- +-- clean_for - clean for statement. +-- +-- This routine cleans specified for statement that assumes deleting all +-- stuff dynamically allocated on generating/postsolving phase. */ + +void clean_for(MPL *mpl, FOR *fur) +{ STATEMENT *stmt; + /* clean subscript domain */ + clean_domain(mpl, fur->domain); + /* clean all sub-statements */ + for (stmt = fur->list; stmt != NULL; stmt = stmt->next) + clean_statement(mpl, stmt); + return; +} + +/*---------------------------------------------------------------------- +-- execute_statement - execute specified model statement. +-- +-- This routine executes specified model statement. */ + +void execute_statement(MPL *mpl, STATEMENT *stmt) +{ mpl->stmt = stmt; + switch (stmt->type) + { case A_SET: + case A_PARAMETER: + case A_VARIABLE: + break; + case A_CONSTRAINT: + xprintf("Generating %s...\n", stmt->u.con->name); + eval_whole_con(mpl, stmt->u.con); + break; + case A_TABLE: + switch (stmt->u.tab->type) + { case A_INPUT: + xprintf("Reading %s...\n", stmt->u.tab->name); + break; + case A_OUTPUT: + xprintf("Writing %s...\n", stmt->u.tab->name); + break; + default: + xassert(stmt != stmt); + } + execute_table(mpl, stmt->u.tab); + break; + case A_SOLVE: + break; + case A_CHECK: + xprintf("Checking (line %d)...\n", stmt->line); + execute_check(mpl, stmt->u.chk); + break; + case A_DISPLAY: + write_text(mpl, "Display statement at line %d\n", + stmt->line); + execute_display(mpl, stmt->u.dpy); + break; + case A_PRINTF: + execute_printf(mpl, stmt->u.prt); + break; + case A_FOR: + execute_for(mpl, stmt->u.fur); + break; + default: + xassert(stmt != stmt); + } + return; +} + +/*---------------------------------------------------------------------- +-- clean_statement - clean specified model statement. +-- +-- This routine cleans specified model statement that assumes deleting +-- all stuff dynamically allocated on generating/postsolving phase. */ + +void clean_statement(MPL *mpl, STATEMENT *stmt) +{ switch(stmt->type) + { case A_SET: + clean_set(mpl, stmt->u.set); break; + case A_PARAMETER: + clean_parameter(mpl, stmt->u.par); break; + case A_VARIABLE: + clean_variable(mpl, stmt->u.var); break; + case A_CONSTRAINT: + clean_constraint(mpl, stmt->u.con); break; +#if 1 /* 11/II-2008 */ + case A_TABLE: + clean_table(mpl, stmt->u.tab); break; +#endif + case A_SOLVE: + break; + case A_CHECK: + clean_check(mpl, stmt->u.chk); break; + case A_DISPLAY: + clean_display(mpl, stmt->u.dpy); break; + case A_PRINTF: + clean_printf(mpl, stmt->u.prt); break; + case A_FOR: + clean_for(mpl, stmt->u.fur); break; + default: + xassert(stmt != stmt); + } + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpmpl04.c b/resources/3rdparty/glpk-4.57/src/glpmpl04.c new file mode 100644 index 000000000..4ec2c19c2 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpmpl04.c @@ -0,0 +1,1427 @@ +/* glpmpl04.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "glpmpl.h" + +#define xfault xerror +#define xfprintf glp_format +#define dmp_create_poolx(size) dmp_create_pool() + +/**********************************************************************/ +/* * * GENERATING AND POSTSOLVING MODEL * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- alloc_content - allocate content arrays for all model objects. +-- +-- This routine allocates content arrays for all existing model objects +-- and thereby finalizes creating model. +-- +-- This routine must be called immediately after reading model section, +-- i.e. before reading data section or generating model. */ + +void alloc_content(MPL *mpl) +{ STATEMENT *stmt; + /* walk through all model statements */ + for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) + { switch (stmt->type) + { case A_SET: + /* model set */ + xassert(stmt->u.set->array == NULL); + stmt->u.set->array = create_array(mpl, A_ELEMSET, + stmt->u.set->dim); + break; + case A_PARAMETER: + /* model parameter */ + xassert(stmt->u.par->array == NULL); + switch (stmt->u.par->type) + { case A_NUMERIC: + case A_INTEGER: + case A_BINARY: + stmt->u.par->array = create_array(mpl, A_NUMERIC, + stmt->u.par->dim); + break; + case A_SYMBOLIC: + stmt->u.par->array = create_array(mpl, A_SYMBOLIC, + stmt->u.par->dim); + break; + default: + xassert(stmt != stmt); + } + break; + case A_VARIABLE: + /* model variable */ + xassert(stmt->u.var->array == NULL); + stmt->u.var->array = create_array(mpl, A_ELEMVAR, + stmt->u.var->dim); + break; + case A_CONSTRAINT: + /* model constraint/objective */ + xassert(stmt->u.con->array == NULL); + stmt->u.con->array = create_array(mpl, A_ELEMCON, + stmt->u.con->dim); + break; +#if 1 /* 11/II-2008 */ + case A_TABLE: +#endif + case A_SOLVE: + case A_CHECK: + case A_DISPLAY: + case A_PRINTF: + case A_FOR: + /* functional statements have no content array */ + break; + default: + xassert(stmt != stmt); + } + } + return; +} + +/*---------------------------------------------------------------------- +-- generate_model - generate model. +-- +-- This routine executes the model statements which precede the solve +-- statement. */ + +void generate_model(MPL *mpl) +{ STATEMENT *stmt; + xassert(!mpl->flag_p); + for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) + { execute_statement(mpl, stmt); + if (mpl->stmt->type == A_SOLVE) break; + } + mpl->stmt = stmt; + return; +} + +/*---------------------------------------------------------------------- +-- build_problem - build problem instance. +-- +-- This routine builds lists of rows and columns for problem instance, +-- which corresponds to the generated model. */ + +void build_problem(MPL *mpl) +{ STATEMENT *stmt; + MEMBER *memb; + VARIABLE *v; + CONSTRAINT *c; + FORMULA *t; + int i, j; + xassert(mpl->m == 0); + xassert(mpl->n == 0); + xassert(mpl->row == NULL); + xassert(mpl->col == NULL); + /* check that all elemental variables has zero column numbers */ + for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) + { if (stmt->type == A_VARIABLE) + { v = stmt->u.var; + for (memb = v->array->head; memb != NULL; memb = memb->next) + xassert(memb->value.var->j == 0); + } + } + /* assign row numbers to elemental constraints and objectives */ + for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) + { if (stmt->type == A_CONSTRAINT) + { c = stmt->u.con; + for (memb = c->array->head; memb != NULL; memb = memb->next) + { xassert(memb->value.con->i == 0); + memb->value.con->i = ++mpl->m; + /* walk through linear form and mark elemental variables, + which are referenced at least once */ + for (t = memb->value.con->form; t != NULL; t = t->next) + { xassert(t->var != NULL); + t->var->memb->value.var->j = -1; + } + } + } + } + /* assign column numbers to marked elemental variables */ + for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) + { if (stmt->type == A_VARIABLE) + { v = stmt->u.var; + for (memb = v->array->head; memb != NULL; memb = memb->next) + if (memb->value.var->j != 0) memb->value.var->j = + ++mpl->n; + } + } + /* build list of rows */ + mpl->row = xcalloc(1+mpl->m, sizeof(ELEMCON *)); + for (i = 1; i <= mpl->m; i++) mpl->row[i] = NULL; + for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) + { if (stmt->type == A_CONSTRAINT) + { c = stmt->u.con; + for (memb = c->array->head; memb != NULL; memb = memb->next) + { i = memb->value.con->i; + xassert(1 <= i && i <= mpl->m); + xassert(mpl->row[i] == NULL); + mpl->row[i] = memb->value.con; + } + } + } + for (i = 1; i <= mpl->m; i++) xassert(mpl->row[i] != NULL); + /* build list of columns */ + mpl->col = xcalloc(1+mpl->n, sizeof(ELEMVAR *)); + for (j = 1; j <= mpl->n; j++) mpl->col[j] = NULL; + for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) + { if (stmt->type == A_VARIABLE) + { v = stmt->u.var; + for (memb = v->array->head; memb != NULL; memb = memb->next) + { j = memb->value.var->j; + if (j == 0) continue; + xassert(1 <= j && j <= mpl->n); + xassert(mpl->col[j] == NULL); + mpl->col[j] = memb->value.var; + } + } + } + for (j = 1; j <= mpl->n; j++) xassert(mpl->col[j] != NULL); + return; +} + +/*---------------------------------------------------------------------- +-- postsolve_model - postsolve model. +-- +-- This routine executes the model statements which follow the solve +-- statement. */ + +void postsolve_model(MPL *mpl) +{ STATEMENT *stmt; + xassert(!mpl->flag_p); + mpl->flag_p = 1; + for (stmt = mpl->stmt; stmt != NULL; stmt = stmt->next) + execute_statement(mpl, stmt); + mpl->stmt = NULL; + return; +} + +/*---------------------------------------------------------------------- +-- clean_model - clean model content. +-- +-- This routine cleans the model content that assumes deleting all stuff +-- dynamically allocated on generating/postsolving phase. +-- +-- Actually cleaning model content is not needed. This function is used +-- mainly to be sure that there were no logical errors on using dynamic +-- memory pools during the generation phase. +-- +-- NOTE: This routine must not be called if any errors were detected on +-- the generation phase. */ + +void clean_model(MPL *mpl) +{ STATEMENT *stmt; + for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) + clean_statement(mpl, stmt); + /* check that all atoms have been returned to their pools */ + if (dmp_in_use(mpl->strings) != 0) + error(mpl, "internal logic error: %d string segment(s) were lo" + "st", dmp_in_use(mpl->strings)); + if (dmp_in_use(mpl->symbols) != 0) + error(mpl, "internal logic error: %d symbol(s) were lost", + dmp_in_use(mpl->symbols)); + if (dmp_in_use(mpl->tuples) != 0) + error(mpl, "internal logic error: %d n-tuple component(s) were" + " lost", dmp_in_use(mpl->tuples)); + if (dmp_in_use(mpl->arrays) != 0) + error(mpl, "internal logic error: %d array(s) were lost", + dmp_in_use(mpl->arrays)); + if (dmp_in_use(mpl->members) != 0) + error(mpl, "internal logic error: %d array member(s) were lost" + , dmp_in_use(mpl->members)); + if (dmp_in_use(mpl->elemvars) != 0) + error(mpl, "internal logic error: %d elemental variable(s) wer" + "e lost", dmp_in_use(mpl->elemvars)); + if (dmp_in_use(mpl->formulae) != 0) + error(mpl, "internal logic error: %d linear term(s) were lost", + dmp_in_use(mpl->formulae)); + if (dmp_in_use(mpl->elemcons) != 0) + error(mpl, "internal logic error: %d elemental constraint(s) w" + "ere lost", dmp_in_use(mpl->elemcons)); + return; +} + +/**********************************************************************/ +/* * * INPUT/OUTPUT * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- open_input - open input text file. +-- +-- This routine opens the input text file for scanning. */ + +void open_input(MPL *mpl, char *file) +{ mpl->line = 0; + mpl->c = '\n'; + mpl->token = 0; + mpl->imlen = 0; + mpl->image[0] = '\0'; + mpl->value = 0.0; + mpl->b_token = T_EOF; + mpl->b_imlen = 0; + mpl->b_image[0] = '\0'; + mpl->b_value = 0.0; + mpl->f_dots = 0; + mpl->f_scan = 0; + mpl->f_token = 0; + mpl->f_imlen = 0; + mpl->f_image[0] = '\0'; + mpl->f_value = 0.0; + memset(mpl->context, ' ', CONTEXT_SIZE); + mpl->c_ptr = 0; + xassert(mpl->in_fp == NULL); + mpl->in_fp = glp_open(file, "r"); + if (mpl->in_fp == NULL) + error(mpl, "unable to open %s - %s", file, get_err_msg()); + mpl->in_file = file; + /* scan the very first character */ + get_char(mpl); + /* scan the very first token */ + get_token(mpl); + return; +} + +/*---------------------------------------------------------------------- +-- read_char - read next character from input text file. +-- +-- This routine returns a next ASCII character read from the input text +-- file. If the end of file has been reached, EOF is returned. */ + +int read_char(MPL *mpl) +{ int c; + xassert(mpl->in_fp != NULL); + c = glp_getc(mpl->in_fp); + if (c < 0) + { if (glp_ioerr(mpl->in_fp)) + error(mpl, "read error on %s - %s", mpl->in_file, + get_err_msg()); + c = EOF; + } + return c; +} + +/*---------------------------------------------------------------------- +-- close_input - close input text file. +-- +-- This routine closes the input text file. */ + +void close_input(MPL *mpl) +{ xassert(mpl->in_fp != NULL); + glp_close(mpl->in_fp); + mpl->in_fp = NULL; + mpl->in_file = NULL; + return; +} + +/*---------------------------------------------------------------------- +-- open_output - open output text file. +-- +-- This routine opens the output text file for writing data produced by +-- display and printf statements. */ + +void open_output(MPL *mpl, char *file) +{ xassert(mpl->out_fp == NULL); + if (file == NULL) + { file = ""; + mpl->out_fp = (void *)stdout; + } + else + { mpl->out_fp = glp_open(file, "w"); + if (mpl->out_fp == NULL) + error(mpl, "unable to create %s - %s", file, get_err_msg()); + } + mpl->out_file = xmalloc(strlen(file)+1); + strcpy(mpl->out_file, file); + return; +} + +/*---------------------------------------------------------------------- +-- write_char - write next character to output text file. +-- +-- This routine writes an ASCII character to the output text file. */ + +void write_char(MPL *mpl, int c) +{ xassert(mpl->out_fp != NULL); + if (mpl->out_fp == (void *)stdout) + xprintf("%c", c); + else + xfprintf(mpl->out_fp, "%c", c); + return; +} + +/*---------------------------------------------------------------------- +-- write_text - format and write text to output text file. +-- +-- This routine formats a text using the format control string and then +-- writes this text to the output text file. */ + +void write_text(MPL *mpl, char *fmt, ...) +{ va_list arg; + char buf[OUTBUF_SIZE], *c; + va_start(arg, fmt); + vsprintf(buf, fmt, arg); + xassert(strlen(buf) < sizeof(buf)); + va_end(arg); + for (c = buf; *c != '\0'; c++) write_char(mpl, *c); + return; +} + +/*---------------------------------------------------------------------- +-- flush_output - finalize writing data to output text file. +-- +-- This routine finalizes writing data to the output text file. */ + +void flush_output(MPL *mpl) +{ xassert(mpl->out_fp != NULL); + if (mpl->out_fp != (void *)stdout) + { +#if 0 /* FIXME */ + xfflush(mpl->out_fp); +#endif + if (glp_ioerr(mpl->out_fp)) + error(mpl, "write error on %s - %s", mpl->out_file, + get_err_msg()); + } + return; +} + +/**********************************************************************/ +/* * * SOLVER INTERFACE * * */ +/**********************************************************************/ + +/*---------------------------------------------------------------------- +-- error - print error message and terminate model processing. +-- +-- This routine formats and prints an error message and then terminates +-- model processing. */ + +void error(MPL *mpl, char *fmt, ...) +{ va_list arg; + char msg[4095+1]; + va_start(arg, fmt); + vsprintf(msg, fmt, arg); + xassert(strlen(msg) < sizeof(msg)); + va_end(arg); + switch (mpl->phase) + { case 1: + case 2: + /* translation phase */ + xprintf("%s:%d: %s\n", + mpl->in_file == NULL ? "(unknown)" : mpl->in_file, + mpl->line, msg); + print_context(mpl); + break; + case 3: + /* generation/postsolve phase */ + xprintf("%s:%d: %s\n", + mpl->mod_file == NULL ? "(unknown)" : mpl->mod_file, + mpl->stmt == NULL ? 0 : mpl->stmt->line, msg); + break; + default: + xassert(mpl != mpl); + } + mpl->phase = 4; + longjmp(mpl->jump, 1); + /* no return */ +} + +/*---------------------------------------------------------------------- +-- warning - print warning message and continue model processing. +-- +-- This routine formats and prints a warning message and returns to the +-- calling program. */ + +void warning(MPL *mpl, char *fmt, ...) +{ va_list arg; + char msg[4095+1]; + va_start(arg, fmt); + vsprintf(msg, fmt, arg); + xassert(strlen(msg) < sizeof(msg)); + va_end(arg); + switch (mpl->phase) + { case 1: + case 2: + /* translation phase */ + xprintf("%s:%d: warning: %s\n", + mpl->in_file == NULL ? "(unknown)" : mpl->in_file, + mpl->line, msg); + break; + case 3: + /* generation/postsolve phase */ + xprintf("%s:%d: warning: %s\n", + mpl->mod_file == NULL ? "(unknown)" : mpl->mod_file, + mpl->stmt == NULL ? 0 : mpl->stmt->line, msg); + break; + default: + xassert(mpl != mpl); + } + return; +} + +/*---------------------------------------------------------------------- +-- mpl_initialize - create and initialize translator database. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- MPL *mpl_initialize(void); +-- +-- *Description* +-- +-- The routine mpl_initialize creates and initializes the database used +-- by the GNU MathProg translator. +-- +-- *Returns* +-- +-- The routine returns a pointer to the database created. */ + +MPL *mpl_initialize(void) +{ MPL *mpl; + mpl = xmalloc(sizeof(MPL)); + /* scanning segment */ + mpl->line = 0; + mpl->c = 0; + mpl->token = 0; + mpl->imlen = 0; + mpl->image = xcalloc(MAX_LENGTH+1, sizeof(char)); + mpl->image[0] = '\0'; + mpl->value = 0.0; + mpl->b_token = 0; + mpl->b_imlen = 0; + mpl->b_image = xcalloc(MAX_LENGTH+1, sizeof(char)); + mpl->b_image[0] = '\0'; + mpl->b_value = 0.0; + mpl->f_dots = 0; + mpl->f_scan = 0; + mpl->f_token = 0; + mpl->f_imlen = 0; + mpl->f_image = xcalloc(MAX_LENGTH+1, sizeof(char)); + mpl->f_image[0] = '\0'; + mpl->f_value = 0.0; + mpl->context = xcalloc(CONTEXT_SIZE, sizeof(char)); + memset(mpl->context, ' ', CONTEXT_SIZE); + mpl->c_ptr = 0; + mpl->flag_d = 0; + /* translating segment */ + mpl->pool = dmp_create_poolx(0); + mpl->tree = avl_create_tree(avl_strcmp, NULL); + mpl->model = NULL; + mpl->flag_x = 0; + mpl->as_within = 0; + mpl->as_in = 0; + mpl->as_binary = 0; + mpl->flag_s = 0; + /* common segment */ + mpl->strings = dmp_create_poolx(sizeof(STRING)); + mpl->symbols = dmp_create_poolx(sizeof(SYMBOL)); + mpl->tuples = dmp_create_poolx(sizeof(TUPLE)); + mpl->arrays = dmp_create_poolx(sizeof(ARRAY)); + mpl->members = dmp_create_poolx(sizeof(MEMBER)); + mpl->elemvars = dmp_create_poolx(sizeof(ELEMVAR)); + mpl->formulae = dmp_create_poolx(sizeof(FORMULA)); + mpl->elemcons = dmp_create_poolx(sizeof(ELEMCON)); + mpl->a_list = NULL; + mpl->sym_buf = xcalloc(255+1, sizeof(char)); + mpl->sym_buf[0] = '\0'; + mpl->tup_buf = xcalloc(255+1, sizeof(char)); + mpl->tup_buf[0] = '\0'; + /* generating/postsolving segment */ + mpl->rand = rng_create_rand(); + mpl->flag_p = 0; + mpl->stmt = NULL; +#if 1 /* 11/II-2008 */ + mpl->dca = NULL; +#endif + mpl->m = 0; + mpl->n = 0; + mpl->row = NULL; + mpl->col = NULL; + /* input/output segment */ + mpl->in_fp = NULL; + mpl->in_file = NULL; + mpl->out_fp = NULL; + mpl->out_file = NULL; + mpl->prt_fp = NULL; + mpl->prt_file = NULL; + /* solver interface segment */ + if (setjmp(mpl->jump)) xassert(mpl != mpl); + mpl->phase = 0; + mpl->mod_file = NULL; + mpl->mpl_buf = xcalloc(255+1, sizeof(char)); + mpl->mpl_buf[0] = '\0'; + return mpl; +} + +/*---------------------------------------------------------------------- +-- mpl_read_model - read model section and optional data section. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- int mpl_read_model(MPL *mpl, char *file, int skip_data); +-- +-- *Description* +-- +-- The routine mpl_read_model reads model section and optionally data +-- section, which may follow the model section, from the text file, +-- whose name is the character string file, performs translating model +-- statements and data blocks, and stores all the information in the +-- translator database. +-- +-- The parameter skip_data is a flag. If the input file contains the +-- data section and this flag is set, the data section is not read as +-- if there were no data section and a warning message is issued. This +-- allows reading the data section from another input file. +-- +-- This routine should be called once after the routine mpl_initialize +-- and before other API routines. +-- +-- *Returns* +-- +-- The routine mpl_read_model returns one the following codes: +-- +-- 1 - translation successful. The input text file contains only model +-- section. In this case the calling program may call the routine +-- mpl_read_data to read data section from another file. +-- 2 - translation successful. The input text file contains both model +-- and data section. +-- 4 - processing failed due to some errors. In this case the calling +-- program should call the routine mpl_terminate to terminate model +-- processing. */ + +int mpl_read_model(MPL *mpl, char *file, int skip_data) +{ if (mpl->phase != 0) + xfault("mpl_read_model: invalid call sequence\n"); + if (file == NULL) + xfault("mpl_read_model: no input filename specified\n"); + /* set up error handler */ + if (setjmp(mpl->jump)) goto done; + /* translate model section */ + mpl->phase = 1; + xprintf("Reading model section from %s...\n", file); + open_input(mpl, file); + model_section(mpl); + if (mpl->model == NULL) + error(mpl, "empty model section not allowed"); + /* save name of the input text file containing model section for + error diagnostics during the generation phase */ + mpl->mod_file = xcalloc(strlen(file)+1, sizeof(char)); + strcpy(mpl->mod_file, mpl->in_file); + /* allocate content arrays for all model objects */ + alloc_content(mpl); + /* optional data section may begin with the keyword 'data' */ + if (is_keyword(mpl, "data")) + { if (skip_data) + { warning(mpl, "data section ignored"); + goto skip; + } + mpl->flag_d = 1; + get_token(mpl /* data */); + if (mpl->token != T_SEMICOLON) + error(mpl, "semicolon missing where expected"); + get_token(mpl /* ; */); + /* translate data section */ + mpl->phase = 2; + xprintf("Reading data section from %s...\n", file); + data_section(mpl); + } + /* process end statement */ + end_statement(mpl); +skip: xprintf("%d line%s were read\n", + mpl->line, mpl->line == 1 ? "" : "s"); + close_input(mpl); +done: /* return to the calling program */ + return mpl->phase; +} + +/*---------------------------------------------------------------------- +-- mpl_read_data - read data section. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- int mpl_read_data(MPL *mpl, char *file); +-- +-- *Description* +-- +-- The routine mpl_read_data reads data section from the text file, +-- whose name is the character string file, performs translating data +-- blocks, and stores the data read in the translator database. +-- +-- If this routine is used, it should be called once after the routine +-- mpl_read_model and if the latter returned the code 1. +-- +-- *Returns* +-- +-- The routine mpl_read_data returns one of the following codes: +-- +-- 2 - data section has been successfully processed. +-- 4 - processing failed due to some errors. In this case the calling +-- program should call the routine mpl_terminate to terminate model +-- processing. */ + +int mpl_read_data(MPL *mpl, char *file) +#if 0 /* 02/X-2008 */ +{ if (mpl->phase != 1) +#else +{ if (!(mpl->phase == 1 || mpl->phase == 2)) +#endif + xfault("mpl_read_data: invalid call sequence\n"); + if (file == NULL) + xfault("mpl_read_data: no input filename specified\n"); + /* set up error handler */ + if (setjmp(mpl->jump)) goto done; + /* process data section */ + mpl->phase = 2; + xprintf("Reading data section from %s...\n", file); + mpl->flag_d = 1; + open_input(mpl, file); + /* in this case the keyword 'data' is optional */ + if (is_literal(mpl, "data")) + { get_token(mpl /* data */); + if (mpl->token != T_SEMICOLON) + error(mpl, "semicolon missing where expected"); + get_token(mpl /* ; */); + } + data_section(mpl); + /* process end statement */ + end_statement(mpl); + xprintf("%d line%s were read\n", + mpl->line, mpl->line == 1 ? "" : "s"); + close_input(mpl); +done: /* return to the calling program */ + return mpl->phase; +} + +/*---------------------------------------------------------------------- +-- mpl_generate - generate model. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- int mpl_generate(MPL *mpl, char *file); +-- +-- *Description* +-- +-- The routine mpl_generate generates the model using its description +-- stored in the translator database. This phase means generating all +-- variables, constraints, and objectives, executing check and display +-- statements, which precede the solve statement (if it is presented), +-- and building the problem instance. +-- +-- The character string file specifies the name of output text file, to +-- which output produced by display statements should be written. It is +-- allowed to specify NULL, in which case the output goes to stdout via +-- the routine print. +-- +-- This routine should be called once after the routine mpl_read_model +-- or mpl_read_data and if one of the latters returned the code 2. +-- +-- *Returns* +-- +-- The routine mpl_generate returns one of the following codes: +-- +-- 3 - model has been successfully generated. In this case the calling +-- program may call other api routines to obtain components of the +-- problem instance from the translator database. +-- 4 - processing failed due to some errors. In this case the calling +-- program should call the routine mpl_terminate to terminate model +-- processing. */ + +int mpl_generate(MPL *mpl, char *file) +{ if (!(mpl->phase == 1 || mpl->phase == 2)) + xfault("mpl_generate: invalid call sequence\n"); + /* set up error handler */ + if (setjmp(mpl->jump)) goto done; + /* generate model */ + mpl->phase = 3; + open_output(mpl, file); + generate_model(mpl); + flush_output(mpl); + /* build problem instance */ + build_problem(mpl); + /* generation phase has been finished */ + xprintf("Model has been successfully generated\n"); +done: /* return to the calling program */ + return mpl->phase; +} + +/*---------------------------------------------------------------------- +-- mpl_get_prob_name - obtain problem (model) name. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- char *mpl_get_prob_name(MPL *mpl); +-- +-- *Returns* +-- +-- The routine mpl_get_prob_name returns a pointer to internal buffer, +-- which contains symbolic name of the problem (model). +-- +-- *Note* +-- +-- Currently MathProg has no feature to assign a symbolic name to the +-- model. Therefore the routine mpl_get_prob_name tries to construct +-- such name using the name of input text file containing model section, +-- although this is not a good idea (due to portability problems). */ + +char *mpl_get_prob_name(MPL *mpl) +{ char *name = mpl->mpl_buf; + char *file = mpl->mod_file; + int k; + if (mpl->phase != 3) + xfault("mpl_get_prob_name: invalid call sequence\n"); + for (;;) + { if (strchr(file, '/') != NULL) + file = strchr(file, '/') + 1; + else if (strchr(file, '\\') != NULL) + file = strchr(file, '\\') + 1; + else if (strchr(file, ':') != NULL) + file = strchr(file, ':') + 1; + else + break; + } + for (k = 0; ; k++) + { if (k == 255) break; + if (!(isalnum((unsigned char)*file) || *file == '_')) break; + name[k] = *file++; + } + if (k == 0) + strcpy(name, "Unknown"); + else + name[k] = '\0'; + xassert(strlen(name) <= 255); + return name; +} + +/*---------------------------------------------------------------------- +-- mpl_get_num_rows - determine number of rows. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- int mpl_get_num_rows(MPL *mpl); +-- +-- *Returns* +-- +-- The routine mpl_get_num_rows returns total number of rows in the +-- problem, where each row is an individual constraint or objective. */ + +int mpl_get_num_rows(MPL *mpl) +{ if (mpl->phase != 3) + xfault("mpl_get_num_rows: invalid call sequence\n"); + return mpl->m; +} + +/*---------------------------------------------------------------------- +-- mpl_get_num_cols - determine number of columns. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- int mpl_get_num_cols(MPL *mpl); +-- +-- *Returns* +-- +-- The routine mpl_get_num_cols returns total number of columns in the +-- problem, where each column is an individual variable. */ + +int mpl_get_num_cols(MPL *mpl) +{ if (mpl->phase != 3) + xfault("mpl_get_num_cols: invalid call sequence\n"); + return mpl->n; +} + +/*---------------------------------------------------------------------- +-- mpl_get_row_name - obtain row name. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- char *mpl_get_row_name(MPL *mpl, int i); +-- +-- *Returns* +-- +-- The routine mpl_get_row_name returns a pointer to internal buffer, +-- which contains symbolic name of i-th row of the problem. */ + +char *mpl_get_row_name(MPL *mpl, int i) +{ char *name = mpl->mpl_buf, *t; + int len; + if (mpl->phase != 3) + xfault("mpl_get_row_name: invalid call sequence\n"); + if (!(1 <= i && i <= mpl->m)) + xfault("mpl_get_row_name: i = %d; row number out of range\n", + i); + strcpy(name, mpl->row[i]->con->name); + len = strlen(name); + xassert(len <= 255); + t = format_tuple(mpl, '[', mpl->row[i]->memb->tuple); + while (*t) + { if (len == 255) break; + name[len++] = *t++; + } + name[len] = '\0'; + if (len == 255) strcpy(name+252, "..."); + xassert(strlen(name) <= 255); + return name; +} + +/*---------------------------------------------------------------------- +-- mpl_get_row_kind - determine row kind. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- int mpl_get_row_kind(MPL *mpl, int i); +-- +-- *Returns* +-- +-- The routine mpl_get_row_kind returns the kind of i-th row, which can +-- be one of the following: +-- +-- MPL_ST - non-free (constraint) row; +-- MPL_MIN - free (objective) row to be minimized; +-- MPL_MAX - free (objective) row to be maximized. */ + +int mpl_get_row_kind(MPL *mpl, int i) +{ int kind; + if (mpl->phase != 3) + xfault("mpl_get_row_kind: invalid call sequence\n"); + if (!(1 <= i && i <= mpl->m)) + xfault("mpl_get_row_kind: i = %d; row number out of range\n", + i); + switch (mpl->row[i]->con->type) + { case A_CONSTRAINT: + kind = MPL_ST; break; + case A_MINIMIZE: + kind = MPL_MIN; break; + case A_MAXIMIZE: + kind = MPL_MAX; break; + default: + xassert(mpl != mpl); + } + return kind; +} + +/*---------------------------------------------------------------------- +-- mpl_get_row_bnds - obtain row bounds. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- int mpl_get_row_bnds(MPL *mpl, int i, double *lb, double *ub); +-- +-- *Description* +-- +-- The routine mpl_get_row_bnds stores lower and upper bounds of i-th +-- row of the problem to the locations, which the parameters lb and ub +-- point to, respectively. Besides the routine returns the type of the +-- i-th row. +-- +-- If some of the parameters lb and ub is NULL, the corresponding bound +-- value is not stored. +-- +-- Types and bounds have the following meaning: +-- +-- Type Bounds Note +-- ----------------------------------------------------------- +-- MPL_FR -inf < f(x) < +inf Free linear form +-- MPL_LO lb <= f(x) < +inf Inequality f(x) >= lb +-- MPL_UP -inf < f(x) <= ub Inequality f(x) <= ub +-- MPL_DB lb <= f(x) <= ub Inequality lb <= f(x) <= ub +-- MPL_FX f(x) = lb Equality f(x) = lb +-- +-- where f(x) is the corresponding linear form of the i-th row. +-- +-- If the row has no lower bound, *lb is set to zero; if the row has +-- no upper bound, *ub is set to zero; and if the row is of fixed type, +-- both *lb and *ub are set to the same value. +-- +-- *Returns* +-- +-- The routine returns the type of the i-th row as it is stated in the +-- table above. */ + +int mpl_get_row_bnds(MPL *mpl, int i, double *_lb, double *_ub) +{ ELEMCON *con; + int type; + double lb, ub; + if (mpl->phase != 3) + xfault("mpl_get_row_bnds: invalid call sequence\n"); + if (!(1 <= i && i <= mpl->m)) + xfault("mpl_get_row_bnds: i = %d; row number out of range\n", + i); + con = mpl->row[i]; +#if 0 /* 21/VII-2006 */ + if (con->con->lbnd == NULL && con->con->ubnd == NULL) + type = MPL_FR, lb = ub = 0.0; + else if (con->con->ubnd == NULL) + type = MPL_LO, lb = con->lbnd, ub = 0.0; + else if (con->con->lbnd == NULL) + type = MPL_UP, lb = 0.0, ub = con->ubnd; + else if (con->con->lbnd != con->con->ubnd) + type = MPL_DB, lb = con->lbnd, ub = con->ubnd; + else + type = MPL_FX, lb = ub = con->lbnd; +#else + lb = (con->con->lbnd == NULL ? -DBL_MAX : con->lbnd); + ub = (con->con->ubnd == NULL ? +DBL_MAX : con->ubnd); + if (lb == -DBL_MAX && ub == +DBL_MAX) + type = MPL_FR, lb = ub = 0.0; + else if (ub == +DBL_MAX) + type = MPL_LO, ub = 0.0; + else if (lb == -DBL_MAX) + type = MPL_UP, lb = 0.0; + else if (con->con->lbnd != con->con->ubnd) + type = MPL_DB; + else + type = MPL_FX; +#endif + if (_lb != NULL) *_lb = lb; + if (_ub != NULL) *_ub = ub; + return type; +} + +/*---------------------------------------------------------------------- +-- mpl_get_mat_row - obtain row of the constraint matrix. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- int mpl_get_mat_row(MPL *mpl, int i, int ndx[], double val[]); +-- +-- *Description* +-- +-- The routine mpl_get_mat_row stores column indices and numeric values +-- of constraint coefficients for the i-th row to locations ndx[1], ..., +-- ndx[len] and val[1], ..., val[len], respectively, where 0 <= len <= n +-- is number of (structural) non-zero constraint coefficients, and n is +-- number of columns in the problem. +-- +-- If the parameter ndx is NULL, column indices are not stored. If the +-- parameter val is NULL, numeric values are not stored. +-- +-- Note that free rows may have constant terms, which are not part of +-- the constraint matrix and therefore not reported by this routine. The +-- constant term of a particular row can be obtained, if necessary, via +-- the routine mpl_get_row_c0. +-- +-- *Returns* +-- +-- The routine mpl_get_mat_row returns len, which is length of i-th row +-- of the constraint matrix (i.e. number of non-zero coefficients). */ + +int mpl_get_mat_row(MPL *mpl, int i, int ndx[], double val[]) +{ FORMULA *term; + int len = 0; + if (mpl->phase != 3) + xfault("mpl_get_mat_row: invalid call sequence\n"); + if (!(1 <= i && i <= mpl->m)) + xfault("mpl_get_mat_row: i = %d; row number out of range\n", + i); + for (term = mpl->row[i]->form; term != NULL; term = term->next) + { xassert(term->var != NULL); + len++; + xassert(len <= mpl->n); + if (ndx != NULL) ndx[len] = term->var->j; + if (val != NULL) val[len] = term->coef; + } + return len; +} + +/*---------------------------------------------------------------------- +-- mpl_get_row_c0 - obtain constant term of free row. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- double mpl_get_row_c0(MPL *mpl, int i); +-- +-- *Returns* +-- +-- The routine mpl_get_row_c0 returns numeric value of constant term of +-- i-th row. +-- +-- Note that only free rows may have non-zero constant terms. Therefore +-- if i-th row is not free, the routine returns zero. */ + +double mpl_get_row_c0(MPL *mpl, int i) +{ ELEMCON *con; + double c0; + if (mpl->phase != 3) + xfault("mpl_get_row_c0: invalid call sequence\n"); + if (!(1 <= i && i <= mpl->m)) + xfault("mpl_get_row_c0: i = %d; row number out of range\n", + i); + con = mpl->row[i]; + if (con->con->lbnd == NULL && con->con->ubnd == NULL) + c0 = - con->lbnd; + else + c0 = 0.0; + return c0; +} + +/*---------------------------------------------------------------------- +-- mpl_get_col_name - obtain column name. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- char *mpl_get_col_name(MPL *mpl, int j); +-- +-- *Returns* +-- +-- The routine mpl_get_col_name returns a pointer to internal buffer, +-- which contains symbolic name of j-th column of the problem. */ + +char *mpl_get_col_name(MPL *mpl, int j) +{ char *name = mpl->mpl_buf, *t; + int len; + if (mpl->phase != 3) + xfault("mpl_get_col_name: invalid call sequence\n"); + if (!(1 <= j && j <= mpl->n)) + xfault("mpl_get_col_name: j = %d; column number out of range\n" + , j); + strcpy(name, mpl->col[j]->var->name); + len = strlen(name); + xassert(len <= 255); + t = format_tuple(mpl, '[', mpl->col[j]->memb->tuple); + while (*t) + { if (len == 255) break; + name[len++] = *t++; + } + name[len] = '\0'; + if (len == 255) strcpy(name+252, "..."); + xassert(strlen(name) <= 255); + return name; +} + +/*---------------------------------------------------------------------- +-- mpl_get_col_kind - determine column kind. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- int mpl_get_col_kind(MPL *mpl, int j); +-- +-- *Returns* +-- +-- The routine mpl_get_col_kind returns the kind of j-th column, which +-- can be one of the following: +-- +-- MPL_NUM - continuous variable; +-- MPL_INT - integer variable; +-- MPL_BIN - binary variable. +-- +-- Note that column kinds are defined independently on type and bounds +-- (reported by the routine mpl_get_col_bnds) of corresponding columns. +-- This means, in particular, that bounds of an integer column may be +-- fractional, or a binary column may have lower and upper bounds that +-- are not 0 and 1 (or it may have no lower/upper bound at all). */ + +int mpl_get_col_kind(MPL *mpl, int j) +{ int kind; + if (mpl->phase != 3) + xfault("mpl_get_col_kind: invalid call sequence\n"); + if (!(1 <= j && j <= mpl->n)) + xfault("mpl_get_col_kind: j = %d; column number out of range\n" + , j); + switch (mpl->col[j]->var->type) + { case A_NUMERIC: + kind = MPL_NUM; break; + case A_INTEGER: + kind = MPL_INT; break; + case A_BINARY: + kind = MPL_BIN; break; + default: + xassert(mpl != mpl); + } + return kind; +} + +/*---------------------------------------------------------------------- +-- mpl_get_col_bnds - obtain column bounds. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- int mpl_get_col_bnds(MPL *mpl, int j, double *lb, double *ub); +-- +-- *Description* +-- +-- The routine mpl_get_col_bnds stores lower and upper bound of j-th +-- column of the problem to the locations, which the parameters lb and +-- ub point to, respectively. Besides the routine returns the type of +-- the j-th column. +-- +-- If some of the parameters lb and ub is NULL, the corresponding bound +-- value is not stored. +-- +-- Types and bounds have the following meaning: +-- +-- Type Bounds Note +-- ------------------------------------------------------ +-- MPL_FR -inf < x < +inf Free (unbounded) variable +-- MPL_LO lb <= x < +inf Variable with lower bound +-- MPL_UP -inf < x <= ub Variable with upper bound +-- MPL_DB lb <= x <= ub Double-bounded variable +-- MPL_FX x = lb Fixed variable +-- +-- where x is individual variable corresponding to the j-th column. +-- +-- If the column has no lower bound, *lb is set to zero; if the column +-- has no upper bound, *ub is set to zero; and if the column is of fixed +-- type, both *lb and *ub are set to the same value. +-- +-- *Returns* +-- +-- The routine returns the type of the j-th column as it is stated in +-- the table above. */ + +int mpl_get_col_bnds(MPL *mpl, int j, double *_lb, double *_ub) +{ ELEMVAR *var; + int type; + double lb, ub; + if (mpl->phase != 3) + xfault("mpl_get_col_bnds: invalid call sequence\n"); + if (!(1 <= j && j <= mpl->n)) + xfault("mpl_get_col_bnds: j = %d; column number out of range\n" + , j); + var = mpl->col[j]; +#if 0 /* 21/VII-2006 */ + if (var->var->lbnd == NULL && var->var->ubnd == NULL) + type = MPL_FR, lb = ub = 0.0; + else if (var->var->ubnd == NULL) + type = MPL_LO, lb = var->lbnd, ub = 0.0; + else if (var->var->lbnd == NULL) + type = MPL_UP, lb = 0.0, ub = var->ubnd; + else if (var->var->lbnd != var->var->ubnd) + type = MPL_DB, lb = var->lbnd, ub = var->ubnd; + else + type = MPL_FX, lb = ub = var->lbnd; +#else + lb = (var->var->lbnd == NULL ? -DBL_MAX : var->lbnd); + ub = (var->var->ubnd == NULL ? +DBL_MAX : var->ubnd); + if (lb == -DBL_MAX && ub == +DBL_MAX) + type = MPL_FR, lb = ub = 0.0; + else if (ub == +DBL_MAX) + type = MPL_LO, ub = 0.0; + else if (lb == -DBL_MAX) + type = MPL_UP, lb = 0.0; + else if (var->var->lbnd != var->var->ubnd) + type = MPL_DB; + else + type = MPL_FX; +#endif + if (_lb != NULL) *_lb = lb; + if (_ub != NULL) *_ub = ub; + return type; +} + +/*---------------------------------------------------------------------- +-- mpl_has_solve_stmt - check if model has solve statement. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- int mpl_has_solve_stmt(MPL *mpl); +-- +-- *Returns* +-- +-- If the model has the solve statement, the routine returns non-zero, +-- otherwise zero is returned. */ + +int mpl_has_solve_stmt(MPL *mpl) +{ if (mpl->phase != 3) + xfault("mpl_has_solve_stmt: invalid call sequence\n"); + return mpl->flag_s; +} + +#if 1 /* 15/V-2010 */ +void mpl_put_row_soln(MPL *mpl, int i, int stat, double prim, + double dual) +{ /* store row (constraint/objective) solution components */ + xassert(mpl->phase == 3); + xassert(1 <= i && i <= mpl->m); + mpl->row[i]->stat = stat; + mpl->row[i]->prim = prim; + mpl->row[i]->dual = dual; + return; +} +#endif + +#if 1 /* 15/V-2010 */ +void mpl_put_col_soln(MPL *mpl, int j, int stat, double prim, + double dual) +{ /* store column (variable) solution components */ + xassert(mpl->phase == 3); + xassert(1 <= j && j <= mpl->n); + mpl->col[j]->stat = stat; + mpl->col[j]->prim = prim; + mpl->col[j]->dual = dual; + return; +} +#endif + +#if 0 /* 15/V-2010 */ +/*---------------------------------------------------------------------- +-- mpl_put_col_value - store column value. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- void mpl_put_col_value(MPL *mpl, int j, double val); +-- +-- *Description* +-- +-- The routine mpl_put_col_value stores numeric value of j-th column +-- into the translator database. It is assumed that the column value is +-- provided by the solver. */ + +void mpl_put_col_value(MPL *mpl, int j, double val) +{ if (mpl->phase != 3) + xfault("mpl_put_col_value: invalid call sequence\n"); + if (!(1 <= j && j <= mpl->n)) + xfault( + "mpl_put_col_value: j = %d; column number out of range\n", j); + mpl->col[j]->prim = val; + return; +} +#endif + +/*---------------------------------------------------------------------- +-- mpl_postsolve - postsolve model. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- int mpl_postsolve(MPL *mpl); +-- +-- *Description* +-- +-- The routine mpl_postsolve performs postsolving of the model using +-- its description stored in the translator database. This phase means +-- executing statements, which follow the solve statement. +-- +-- If this routine is used, it should be called once after the routine +-- mpl_generate and if the latter returned the code 3. +-- +-- *Returns* +-- +-- The routine mpl_postsolve returns one of the following codes: +-- +-- 3 - model has been successfully postsolved. +-- 4 - processing failed due to some errors. In this case the calling +-- program should call the routine mpl_terminate to terminate model +-- processing. */ + +int mpl_postsolve(MPL *mpl) +{ if (!(mpl->phase == 3 && !mpl->flag_p)) + xfault("mpl_postsolve: invalid call sequence\n"); + /* set up error handler */ + if (setjmp(mpl->jump)) goto done; + /* perform postsolving */ + postsolve_model(mpl); + flush_output(mpl); + /* postsolving phase has been finished */ + xprintf("Model has been successfully processed\n"); +done: /* return to the calling program */ + return mpl->phase; +} + +/*---------------------------------------------------------------------- +-- mpl_terminate - free all resources used by translator. +-- +-- *Synopsis* +-- +-- #include "glpmpl.h" +-- void mpl_terminate(MPL *mpl); +-- +-- *Description* +-- +-- The routine mpl_terminate frees all the resources used by the GNU +-- MathProg translator. */ + +void mpl_terminate(MPL *mpl) +{ if (setjmp(mpl->jump)) xassert(mpl != mpl); + switch (mpl->phase) + { case 0: + case 1: + case 2: + case 3: + /* there were no errors; clean the model content */ + clean_model(mpl); + xassert(mpl->a_list == NULL); +#if 1 /* 11/II-2008 */ + xassert(mpl->dca == NULL); +#endif + break; + case 4: + /* model processing has been finished due to error; delete + search trees, which may be created for some arrays */ + { ARRAY *a; + for (a = mpl->a_list; a != NULL; a = a->next) + if (a->tree != NULL) avl_delete_tree(a->tree); + } +#if 1 /* 11/II-2008 */ + free_dca(mpl); +#endif + break; + default: + xassert(mpl != mpl); + } + /* delete the translator database */ + xfree(mpl->image); + xfree(mpl->b_image); + xfree(mpl->f_image); + xfree(mpl->context); + dmp_delete_pool(mpl->pool); + avl_delete_tree(mpl->tree); + dmp_delete_pool(mpl->strings); + dmp_delete_pool(mpl->symbols); + dmp_delete_pool(mpl->tuples); + dmp_delete_pool(mpl->arrays); + dmp_delete_pool(mpl->members); + dmp_delete_pool(mpl->elemvars); + dmp_delete_pool(mpl->formulae); + dmp_delete_pool(mpl->elemcons); + xfree(mpl->sym_buf); + xfree(mpl->tup_buf); + rng_delete_rand(mpl->rand); + if (mpl->row != NULL) xfree(mpl->row); + if (mpl->col != NULL) xfree(mpl->col); + if (mpl->in_fp != NULL) glp_close(mpl->in_fp); + if (mpl->out_fp != NULL && mpl->out_fp != (void *)stdout) + glp_close(mpl->out_fp); + if (mpl->out_file != NULL) xfree(mpl->out_file); + if (mpl->prt_fp != NULL) glp_close(mpl->prt_fp); + if (mpl->prt_file != NULL) xfree(mpl->prt_file); + if (mpl->mod_file != NULL) xfree(mpl->mod_file); + xfree(mpl->mpl_buf); + xfree(mpl); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpmpl05.c b/resources/3rdparty/glpk-4.57/src/glpmpl05.c new file mode 100644 index 000000000..2207572a7 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpmpl05.c @@ -0,0 +1,563 @@ +/* glpmpl05.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Authors: Andrew Makhorin +* Heinrich Schuchardt +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "glpmpl.h" +#if 1 /* 11/VI-2013 */ +#include "jd.h" +#endif + +double fn_gmtime(MPL *mpl) +{ /* obtain the current calendar time (UTC) */ + time_t timer; + struct tm *tm; + int j; + time(&timer); + if (timer == (time_t)(-1)) +err: error(mpl, "gmtime(); unable to obtain current calendar time"); + tm = gmtime(&timer); + if (tm == NULL) goto err; + j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year); + if (j < 0) goto err; + return (((double)(j - jday(1, 1, 1970)) * 24.0 + + (double)tm->tm_hour) * 60.0 + (double)tm->tm_min) * 60.0 + + (double)tm->tm_sec; +} + +static char *week[] = { "Monday", "Tuesday", "Wednesday", "Thursday", + "Friday", "Saturday", "Sunday" }; + +static char *moon[] = { "January", "February", "March", "April", "May", + "June", "July", "August", "September", "October", "November", + "December" }; + +static void error1(MPL *mpl, const char *str, const char *s, + const char *fmt, const char *f, const char *msg) +{ xprintf("Input string passed to str2time:\n"); + xprintf("%s\n", str); + xprintf("%*s\n", (s - str) + 1, "^"); + xprintf("Format string passed to str2time:\n"); + xprintf("%s\n", fmt); + xprintf("%*s\n", (f - fmt) + 1, "^"); + error(mpl, "%s", msg); + /* no return */ +} + +double fn_str2time(MPL *mpl, const char *str, const char *fmt) +{ /* convert character string to the calendar time */ + int j, year, month, day, hh, mm, ss, zone; + const char *s, *f; + year = month = day = hh = mm = ss = -1, zone = INT_MAX; + s = str; + for (f = fmt; *f != '\0'; f++) + { if (*f == '%') + { f++; + if (*f == 'b' || *f == 'h') + { /* the abbreviated month name */ + int k; + char *name; + if (month >= 0) + error1(mpl, str, s, fmt, f, "month multiply specified" + ); + while (*s == ' ') s++; + for (month = 1; month <= 12; month++) + { name = moon[month-1]; + for (k = 0; k <= 2; k++) + { if (toupper((unsigned char)s[k]) != + toupper((unsigned char)name[k])) goto next; + } + s += 3; + for (k = 3; name[k] != '\0'; k++) + { if (toupper((unsigned char)*s) != + toupper((unsigned char)name[k])) break; + s++; + } + break; +next: ; + } + if (month > 12) + error1(mpl, str, s, fmt, f, "abbreviated month name m" + "issing or invalid"); + } + else if (*f == 'd') + { /* the day of the month as a decimal number (01..31) */ + if (day >= 0) + error1(mpl, str, s, fmt, f, "day multiply specified"); + while (*s == ' ') s++; + if (!('0' <= *s && *s <= '9')) + error1(mpl, str, s, fmt, f, "day missing or invalid"); + day = (*s++) - '0'; + if ('0' <= *s && *s <= '9') + day = 10 * day + ((*s++) - '0'); + if (!(1 <= day && day <= 31)) + error1(mpl, str, s, fmt, f, "day out of range"); + } + else if (*f == 'H') + { /* the hour as a decimal number, using a 24-hour clock + (00..23) */ + if (hh >= 0) + error1(mpl, str, s, fmt, f, "hour multiply specified") + ; + while (*s == ' ') s++; + if (!('0' <= *s && *s <= '9')) + error1(mpl, str, s, fmt, f, "hour missing or invalid") + ; + hh = (*s++) - '0'; + if ('0' <= *s && *s <= '9') + hh = 10 * hh + ((*s++) - '0'); + if (!(0 <= hh && hh <= 23)) + error1(mpl, str, s, fmt, f, "hour out of range"); + } + else if (*f == 'm') + { /* the month as a decimal number (01..12) */ + if (month >= 0) + error1(mpl, str, s, fmt, f, "month multiply specified" + ); + while (*s == ' ') s++; + if (!('0' <= *s && *s <= '9')) + error1(mpl, str, s, fmt, f, "month missing or invalid" + ); + month = (*s++) - '0'; + if ('0' <= *s && *s <= '9') + month = 10 * month + ((*s++) - '0'); + if (!(1 <= month && month <= 12)) + error1(mpl, str, s, fmt, f, "month out of range"); + } + else if (*f == 'M') + { /* the minute as a decimal number (00..59) */ + if (mm >= 0) + error1(mpl, str, s, fmt, f, "minute multiply specifie" + "d"); + while (*s == ' ') s++; + if (!('0' <= *s && *s <= '9')) + error1(mpl, str, s, fmt, f, "minute missing or invali" + "d"); + mm = (*s++) - '0'; + if ('0' <= *s && *s <= '9') + mm = 10 * mm + ((*s++) - '0'); + if (!(0 <= mm && mm <= 59)) + error1(mpl, str, s, fmt, f, "minute out of range"); + } + else if (*f == 'S') + { /* the second as a decimal number (00..60) */ + if (ss >= 0) + error1(mpl, str, s, fmt, f, "second multiply specifie" + "d"); + while (*s == ' ') s++; + if (!('0' <= *s && *s <= '9')) + error1(mpl, str, s, fmt, f, "second missing or invali" + "d"); + ss = (*s++) - '0'; + if ('0' <= *s && *s <= '9') + ss = 10 * ss + ((*s++) - '0'); + if (!(0 <= ss && ss <= 60)) + error1(mpl, str, s, fmt, f, "second out of range"); + } + else if (*f == 'y') + { /* the year without a century as a decimal number + (00..99); the values 00 to 68 mean the years 2000 to + 2068 while the values 69 to 99 mean the years 1969 to + 1999 */ + if (year >= 0) + error1(mpl, str, s, fmt, f, "year multiply specified") + ; + while (*s == ' ') s++; + if (!('0' <= *s && *s <= '9')) + error1(mpl, str, s, fmt, f, "year missing or invalid") + ; + year = (*s++) - '0'; + if ('0' <= *s && *s <= '9') + year = 10 * year + ((*s++) - '0'); + year += (year >= 69 ? 1900 : 2000); + } + else if (*f == 'Y') + { /* the year as a decimal number, using the Gregorian + calendar */ + if (year >= 0) + error1(mpl, str, s, fmt, f, "year multiply specified") + ; + while (*s == ' ') s++; + if (!('0' <= *s && *s <= '9')) + error1(mpl, str, s, fmt, f, "year missing or invalid") + ; + year = 0; + for (j = 1; j <= 4; j++) + { if (!('0' <= *s && *s <= '9')) break; + year = 10 * year + ((*s++) - '0'); + } + if (!(1 <= year && year <= 4000)) + error1(mpl, str, s, fmt, f, "year out of range"); + } + else if (*f == 'z') + { /* time zone offset in the form zhhmm */ + int z, hh, mm; + if (zone != INT_MAX) + error1(mpl, str, s, fmt, f, "time zone offset multipl" + "y specified"); + while (*s == ' ') s++; + if (*s == 'Z') + { z = hh = mm = 0, s++; + goto skip; + } + if (*s == '+') + z = +1, s++; + else if (*s == '-') + z = -1, s++; + else + error1(mpl, str, s, fmt, f, "time zone offset sign mi" + "ssing"); + hh = 0; + for (j = 1; j <= 2; j++) + { if (!('0' <= *s && *s <= '9')) +err1: error1(mpl, str, s, fmt, f, "time zone offset valu" + "e incomplete or invalid"); + hh = 10 * hh + ((*s++) - '0'); + } + if (hh > 23) +err2: error1(mpl, str, s, fmt, f, "time zone offset value o" + "ut of range"); + if (*s == ':') + { s++; + if (!('0' <= *s && *s <= '9')) goto err1; + } + mm = 0; + if (!('0' <= *s && *s <= '9')) goto skip; + for (j = 1; j <= 2; j++) + { if (!('0' <= *s && *s <= '9')) goto err1; + mm = 10 * mm + ((*s++) - '0'); + } + if (mm > 59) goto err2; +skip: zone = z * (60 * hh + mm); + } + else if (*f == '%') + { /* literal % character */ + goto test; + } + else + error1(mpl, str, s, fmt, f, "invalid conversion specifie" + "r"); + } + else if (*f == ' ') + ; + else +test: { /* check a matching character in the input string */ + if (*s != *f) + error1(mpl, str, s, fmt, f, "character mismatch"); + s++; + } + } + if (year < 0) year = 1970; + if (month < 0) month = 1; + if (day < 0) day = 1; + if (hh < 0) hh = 0; + if (mm < 0) mm = 0; + if (ss < 0) ss = 0; + if (zone == INT_MAX) zone = 0; + j = jday(day, month, year); + xassert(j >= 0); + return (((double)(j - jday(1, 1, 1970)) * 24.0 + (double)hh) * + 60.0 + (double)mm) * 60.0 + (double)ss - 60.0 * (double)zone; +} + +static void error2(MPL *mpl, const char *fmt, const char *f, + const char *msg) +{ xprintf("Format string passed to time2str:\n"); + xprintf("%s\n", fmt); + xprintf("%*s\n", (f - fmt) + 1, "^"); + error(mpl, "%s", msg); + /* no return */ +} + +static int weekday(int j) +{ /* determine weekday number (1 = Mon, ..., 7 = Sun) */ + return (j + jday(1, 1, 1970)) % 7 + 1; +} + +static int firstday(int year) +{ /* determine the first day of the first week for a specified year + according to ISO 8601 */ + int j; + /* if 1 January is Monday, Tuesday, Wednesday or Thursday, it is + in week 01; if 1 January is Friday, Saturday or Sunday, it is + in week 52 or 53 of the previous year */ + j = jday(1, 1, year) - jday(1, 1, 1970); + switch (weekday(j)) + { case 1: /* 1 Jan is Mon */ j += 0; break; + case 2: /* 1 Jan is Tue */ j -= 1; break; + case 3: /* 1 Jan is Wed */ j -= 2; break; + case 4: /* 1 Jan is Thu */ j -= 3; break; + case 5: /* 1 Jan is Fri */ j += 3; break; + case 6: /* 1 Jan is Sat */ j += 2; break; + case 7: /* 1 Jan is Sun */ j += 1; break; + default: xassert(j != j); + } + /* the first day of the week must be Monday */ + xassert(weekday(j) == 1); + return j; +} + +void fn_time2str(MPL *mpl, char *str, double t, const char *fmt) +{ /* convert the calendar time to character string */ + int j, year, month, day, hh, mm, ss, len; + double temp; + const char *f; + char buf[MAX_LENGTH+1]; + if (!(-62135596800.0 <= t && t <= 64092211199.0)) + error(mpl, "time2str(%.*g,...); argument out of range", + DBL_DIG, t); + t = floor(t + 0.5); + temp = fabs(t) / 86400.0; + j = (int)floor(temp); + if (t < 0.0) + { if (temp == floor(temp)) + j = - j; + else + j = - (j + 1); + } + xassert(jdate(j + jday(1, 1, 1970), &day, &month, &year) == 0); + ss = (int)(t - 86400.0 * (double)j); + xassert(0 <= ss && ss < 86400); + mm = ss / 60, ss %= 60; + hh = mm / 60, mm %= 60; + len = 0; + for (f = fmt; *f != '\0'; f++) + { if (*f == '%') + { f++; + if (*f == 'a') + { /* the abbreviated weekday name */ + memcpy(buf, week[weekday(j)-1], 3), buf[3] = '\0'; + } + else if (*f == 'A') + { /* the full weekday name */ + strcpy(buf, week[weekday(j)-1]); + } + else if (*f == 'b' || *f == 'h') + { /* the abbreviated month name */ + memcpy(buf, moon[month-1], 3), buf[3] = '\0'; + } + else if (*f == 'B') + { /* the full month name */ + strcpy(buf, moon[month-1]); + } + else if (*f == 'C') + { /* the century of the year */ + sprintf(buf, "%02d", year / 100); + } + else if (*f == 'd') + { /* the day of the month as a decimal number (01..31) */ + sprintf(buf, "%02d", day); + } + else if (*f == 'D') + { /* the date using the format %m/%d/%y */ + sprintf(buf, "%02d/%02d/%02d", month, day, year % 100); + } + else if (*f == 'e') + { /* the day of the month like with %d, but padded with + blank (1..31) */ + sprintf(buf, "%2d", day); + } + else if (*f == 'F') + { /* the date using the format %Y-%m-%d */ + sprintf(buf, "%04d-%02d-%02d", year, month, day); + } + else if (*f == 'g') + { /* the year corresponding to the ISO week number, but + without the century (range 00 through 99); this has + the same format and value as %y, except that if the + ISO week number (see %V) belongs to the previous or + next year, that year is used instead */ + int iso; + if (j < firstday(year)) + iso = year - 1; + else if (j < firstday(year + 1)) + iso = year; + else + iso = year + 1; + sprintf(buf, "%02d", iso % 100); + } + else if (*f == 'G') + { /* the year corresponding to the ISO week number; this + has the same format and value as %Y, excepth that if + the ISO week number (see %V) belongs to the previous + or next year, that year is used instead */ + int iso; + if (j < firstday(year)) + iso = year - 1; + else if (j < firstday(year + 1)) + iso = year; + else + iso = year + 1; + sprintf(buf, "%04d", iso); + } + else if (*f == 'H') + { /* the hour as a decimal number, using a 24-hour clock + (00..23) */ + sprintf(buf, "%02d", hh); + } + else if (*f == 'I') + { /* the hour as a decimal number, using a 12-hour clock + (01..12) */ + sprintf(buf, "%02d", + hh == 0 ? 12 : hh <= 12 ? hh : hh - 12); + } + else if (*f == 'j') + { /* the day of the year as a decimal number (001..366) */ + sprintf(buf, "%03d", + jday(day, month, year) - jday(1, 1, year) + 1); + } + else if (*f == 'k') + { /* the hour as a decimal number, using a 24-hour clock + like %H, but padded with blank (0..23) */ + sprintf(buf, "%2d", hh); + } + else if (*f == 'l') + { /* the hour as a decimal number, using a 12-hour clock + like %I, but padded with blank (1..12) */ + sprintf(buf, "%2d", + hh == 0 ? 12 : hh <= 12 ? hh : hh - 12); + } + else if (*f == 'm') + { /* the month as a decimal number (01..12) */ + sprintf(buf, "%02d", month); + } + else if (*f == 'M') + { /* the minute as a decimal number (00..59) */ + sprintf(buf, "%02d", mm); + } + else if (*f == 'p') + { /* either AM or PM, according to the given time value; + noon is treated as PM and midnight as AM */ + strcpy(buf, hh <= 11 ? "AM" : "PM"); + } + else if (*f == 'P') + { /* either am or pm, according to the given time value; + noon is treated as pm and midnight as am */ + strcpy(buf, hh <= 11 ? "am" : "pm"); + } + else if (*f == 'r') + { /* the calendar time using the format %I:%M:%S %p */ + sprintf(buf, "%02d:%02d:%02d %s", + hh == 0 ? 12 : hh <= 12 ? hh : hh - 12, + mm, ss, hh <= 11 ? "AM" : "PM"); + } + else if (*f == 'R') + { /* the hour and minute using the format %H:%M */ + sprintf(buf, "%02d:%02d", hh, mm); + } + else if (*f == 'S') + { /* the second as a decimal number (00..59) */ + sprintf(buf, "%02d", ss); + } + else if (*f == 'T') + { /* the time of day using the format %H:%M:%S */ + sprintf(buf, "%02d:%02d:%02d", hh, mm, ss); + } + else if (*f == 'u') + { /* the day of the week as a decimal number (1..7), + Monday being 1 */ + sprintf(buf, "%d", weekday(j)); + } + else if (*f == 'U') + { /* the week number of the current year as a decimal + number (range 00 through 53), starting with the first + Sunday as the first day of the first week; days + preceding the first Sunday in the year are considered + to be in week 00 */ +#if 1 /* 09/I-2009 */ +#undef sun +/* causes compilation error in SunOS */ +#endif + int sun; + /* sun = the first Sunday of the year */ + sun = jday(1, 1, year) - jday(1, 1, 1970); + sun += (7 - weekday(sun)); + sprintf(buf, "%02d", (j + 7 - sun) / 7); + } + else if (*f == 'V') + { /* the ISO week number as a decimal number (range 01 + through 53); ISO weeks start with Monday and end with + Sunday; week 01 of a year is the first week which has + the majority of its days in that year; week 01 of + a year can contain days from the previous year; the + week before week 01 of a year is the last week (52 or + 53) of the previous year even if it contains days + from the new year */ + int iso; + if (j < firstday(year)) + iso = j - firstday(year - 1); + else if (j < firstday(year + 1)) + iso = j - firstday(year); + else + iso = j - firstday(year + 1); + sprintf(buf, "%02d", iso / 7 + 1); + } + else if (*f == 'w') + { /* the day of the week as a decimal number (0..6), + Sunday being 0 */ + sprintf(buf, "%d", weekday(j) % 7); + } + else if (*f == 'W') + { /* the week number of the current year as a decimal + number (range 00 through 53), starting with the first + Monday as the first day of the first week; days + preceding the first Monday in the year are considered + to be in week 00 */ + int mon; + /* mon = the first Monday of the year */ + mon = jday(1, 1, year) - jday(1, 1, 1970); + mon += (8 - weekday(mon)) % 7; + sprintf(buf, "%02d", (j + 7 - mon) / 7); + } + else if (*f == 'y') + { /* the year without a century as a decimal number + (00..99) */ + sprintf(buf, "%02d", year % 100); + } + else if (*f == 'Y') + { /* the year as a decimal number, using the Gregorian + calendar */ + sprintf(buf, "%04d", year); + } + else if (*f == '%') + { /* a literal % character */ + buf[0] = '%', buf[1] = '\0'; + } + else + error2(mpl, fmt, f, "invalid conversion specifier"); + } + else + buf[0] = *f, buf[1] = '\0'; + if (len + strlen(buf) > MAX_LENGTH) + error(mpl, "time2str; output string length exceeds %d chara" + "cters", MAX_LENGTH); + memcpy(str+len, buf, strlen(buf)); + len += strlen(buf); + } + str[len] = '\0'; + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpmpl06.c b/resources/3rdparty/glpk-4.57/src/glpmpl06.c new file mode 100644 index 000000000..67c5aa05e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpmpl06.c @@ -0,0 +1,1000 @@ +/* glpmpl06.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "glpmpl.h" +#include "glpsql.h" + +/**********************************************************************/ + +#define CSV_FIELD_MAX 50 +/* maximal number of fields in record */ + +#define CSV_FDLEN_MAX 100 +/* maximal field length */ + +struct csv +{ /* comma-separated values file */ + int mode; + /* 'R' = reading; 'W' = writing */ + char *fname; + /* name of csv file */ + FILE *fp; + /* stream assigned to csv file */ + jmp_buf jump; + /* address for non-local go to in case of error */ + int count; + /* record count */ + /*--------------------------------------------------------------*/ + /* used only for input csv file */ + int c; + /* current character or EOF */ + int what; + /* current marker: */ +#define CSV_EOF 0 /* end-of-file */ +#define CSV_EOR 1 /* end-of-record */ +#define CSV_NUM 2 /* floating-point number */ +#define CSV_STR 3 /* character string */ + char field[CSV_FDLEN_MAX+1]; + /* current field just read */ + int nf; + /* number of fields in the csv file */ + int ref[1+CSV_FIELD_MAX]; + /* ref[k] = k', if k-th field of the csv file corresponds to + k'-th field in the table statement; if ref[k] = 0, k-th field + of the csv file is ignored */ +#if 1 /* 01/VI-2010 */ + int nskip; + /* number of comment records preceding the header record */ +#endif +}; + +#undef read_char + +static void read_char(struct csv *csv) +{ /* read character from csv data file */ + int c; + xassert(csv->c != EOF); + if (csv->c == '\n') csv->count++; +loop: c = fgetc(csv->fp); + if (ferror(csv->fp)) + { xprintf("%s:%d: read error - %s\n", csv->fname, csv->count, + strerror(errno)); + longjmp(csv->jump, 0); + } + if (feof(csv->fp)) + { if (csv->c == '\n') + { csv->count--; + c = EOF; + } + else + { xprintf("%s:%d: warning: missing final end-of-line\n", + csv->fname, csv->count); + c = '\n'; + } + } + else if (c == '\r') + goto loop; + else if (c == '\n') + ; + else if (iscntrl(c)) + { xprintf("%s:%d: invalid control character 0x%02X\n", + csv->fname, csv->count, c); + longjmp(csv->jump, 0); + } + csv->c = c; + return; +} + +static void read_field(struct csv *csv) +{ /* read field from csv data file */ + /* check for end of file */ + if (csv->c == EOF) + { csv->what = CSV_EOF; + strcpy(csv->field, "EOF"); + goto done; + } + /* check for end of record */ + if (csv->c == '\n') + { csv->what = CSV_EOR; + strcpy(csv->field, "EOR"); + read_char(csv); + if (csv->c == ',') +err1: { xprintf("%s:%d: empty field not allowed\n", csv->fname, + csv->count); + longjmp(csv->jump, 0); + } + if (csv->c == '\n') + { xprintf("%s:%d: empty record not allowed\n", csv->fname, + csv->count); + longjmp(csv->jump, 0); + } +#if 1 /* 01/VI-2010 */ + /* skip comment records; may appear only before the very first + record containing field names */ + if (csv->c == '#' && csv->count == 1) + { while (csv->c == '#') + { while (csv->c != '\n') + read_char(csv); + read_char(csv); + csv->nskip++; + } + } +#endif + goto done; + } + /* skip comma before next field */ + if (csv->c == ',') + read_char(csv); + /* read field */ + if (csv->c == '\'' || csv->c == '"') + { /* read a field enclosed in quotes */ + int quote = csv->c, len = 0; + csv->what = CSV_STR; + /* skip opening quote */ + read_char(csv); + /* read field characters within quotes */ + for (;;) + { /* check for closing quote and read it */ + if (csv->c == quote) + { read_char(csv); + if (csv->c == quote) + ; + else if (csv->c == ',' || csv->c == '\n') + break; + else + { xprintf("%s:%d: invalid field\n", csv->fname, + csv->count); + longjmp(csv->jump, 0); + } + } + /* check the current field length */ + if (len == CSV_FDLEN_MAX) +err2: { xprintf("%s:%d: field too long\n", csv->fname, + csv->count); + longjmp(csv->jump, 0); + } + /* add the current character to the field */ + csv->field[len++] = (char)csv->c; + /* read the next character */ + read_char(csv); + } + /* the field has been read */ + if (len == 0) goto err1; + csv->field[len] = '\0'; + } + else + { /* read a field not enclosed in quotes */ + int len = 0; + double temp; + csv->what = CSV_NUM; + while (!(csv->c == ',' || csv->c == '\n')) + { /* quotes within the field are not allowed */ + if (csv->c == '\'' || csv->c == '"') + { xprintf("%s:%d: invalid use of single or double quote wi" + "thin field\n", csv->fname, csv->count); + longjmp(csv->jump, 0); + } + /* check the current field length */ + if (len == CSV_FDLEN_MAX) goto err2; + /* add the current character to the field */ + csv->field[len++] = (char)csv->c; + /* read the next character */ + read_char(csv); + } + /* the field has been read */ + if (len == 0) goto err1; + csv->field[len] = '\0'; + /* check the field type */ + if (str2num(csv->field, &temp)) csv->what = CSV_STR; + } +done: return; +} + +static struct csv *csv_open_file(TABDCA *dca, int mode) +{ /* open csv data file */ + struct csv *csv; + /* create control structure */ + csv = xmalloc(sizeof(struct csv)); + csv->mode = mode; + csv->fname = NULL; + csv->fp = NULL; + if (setjmp(csv->jump)) goto fail; + csv->count = 0; + csv->c = '\n'; + csv->what = 0; + csv->field[0] = '\0'; + csv->nf = 0; + /* try to open the csv data file */ + if (mpl_tab_num_args(dca) < 2) + { xprintf("csv_driver: file name not specified\n"); + longjmp(csv->jump, 0); + } + csv->fname = xmalloc(strlen(mpl_tab_get_arg(dca, 2))+1); + strcpy(csv->fname, mpl_tab_get_arg(dca, 2)); + if (mode == 'R') + { /* open the file for reading */ + int k; + csv->fp = fopen(csv->fname, "r"); + if (csv->fp == NULL) + { xprintf("csv_driver: unable to open %s - %s\n", + csv->fname, strerror(errno)); + longjmp(csv->jump, 0); + } +#if 1 /* 01/VI-2010 */ + csv->nskip = 0; +#endif + /* skip fake new-line */ + read_field(csv); + xassert(csv->what == CSV_EOR); + /* read field names */ + xassert(csv->nf == 0); + for (;;) + { read_field(csv); + if (csv->what == CSV_EOR) + break; + if (csv->what != CSV_STR) + { xprintf("%s:%d: invalid field name\n", csv->fname, + csv->count); + longjmp(csv->jump, 0); + } + if (csv->nf == CSV_FIELD_MAX) + { xprintf("%s:%d: too many fields\n", csv->fname, + csv->count); + longjmp(csv->jump, 0); + } + csv->nf++; + /* find corresponding field in the table statement */ + for (k = mpl_tab_num_flds(dca); k >= 1; k--) + { if (strcmp(mpl_tab_get_name(dca, k), csv->field) == 0) + break; + } + csv->ref[csv->nf] = k; + } + /* find dummy RECNO field in the table statement */ + for (k = mpl_tab_num_flds(dca); k >= 1; k--) + if (strcmp(mpl_tab_get_name(dca, k), "RECNO") == 0) break; + csv->ref[0] = k; + } + else if (mode == 'W') + { /* open the file for writing */ + int k, nf; + csv->fp = fopen(csv->fname, "w"); + if (csv->fp == NULL) + { xprintf("csv_driver: unable to create %s - %s\n", + csv->fname, strerror(errno)); + longjmp(csv->jump, 0); + } + /* write field names */ + nf = mpl_tab_num_flds(dca); + for (k = 1; k <= nf; k++) + fprintf(csv->fp, "%s%c", mpl_tab_get_name(dca, k), + k < nf ? ',' : '\n'); + csv->count++; + } + else + xassert(mode != mode); + /* the file has been open */ + return csv; +fail: /* the file cannot be open */ + if (csv->fname != NULL) xfree(csv->fname); + if (csv->fp != NULL) fclose(csv->fp); + xfree(csv); + return NULL; +} + +static int csv_read_record(TABDCA *dca, struct csv *csv) +{ /* read next record from csv data file */ + int k, ret = 0; + xassert(csv->mode == 'R'); + if (setjmp(csv->jump)) + { ret = 1; + goto done; + } + /* read dummy RECNO field */ + if (csv->ref[0] > 0) +#if 0 /* 01/VI-2010 */ + mpl_tab_set_num(dca, csv->ref[0], csv->count-1); +#else + mpl_tab_set_num(dca, csv->ref[0], csv->count-csv->nskip-1); +#endif + /* read fields */ + for (k = 1; k <= csv->nf; k++) + { read_field(csv); + if (csv->what == CSV_EOF) + { /* end-of-file reached */ + xassert(k == 1); + ret = -1; + goto done; + } + else if (csv->what == CSV_EOR) + { /* end-of-record reached */ + int lack = csv->nf - k + 1; + if (lack == 1) + xprintf("%s:%d: one field missing\n", csv->fname, + csv->count); + else + xprintf("%s:%d: %d fields missing\n", csv->fname, + csv->count, lack); + longjmp(csv->jump, 0); + } + else if (csv->what == CSV_NUM) + { /* floating-point number */ + if (csv->ref[k] > 0) + { double num; + xassert(str2num(csv->field, &num) == 0); + mpl_tab_set_num(dca, csv->ref[k], num); + } + } + else if (csv->what == CSV_STR) + { /* character string */ + if (csv->ref[k] > 0) + mpl_tab_set_str(dca, csv->ref[k], csv->field); + } + else + xassert(csv != csv); + } + /* now there must be NL */ + read_field(csv); + xassert(csv->what != CSV_EOF); + if (csv->what != CSV_EOR) + { xprintf("%s:%d: too many fields\n", csv->fname, csv->count); + longjmp(csv->jump, 0); + } +done: return ret; +} + +static int csv_write_record(TABDCA *dca, struct csv *csv) +{ /* write next record to csv data file */ + int k, nf, ret = 0; + const char *c; + xassert(csv->mode == 'W'); + nf = mpl_tab_num_flds(dca); + for (k = 1; k <= nf; k++) + { switch (mpl_tab_get_type(dca, k)) + { case 'N': + fprintf(csv->fp, "%.*g", DBL_DIG, + mpl_tab_get_num(dca, k)); + break; + case 'S': + fputc('"', csv->fp); + for (c = mpl_tab_get_str(dca, k); *c != '\0'; c++) + { if (*c == '"') + fputc('"', csv->fp), fputc('"', csv->fp); + else + fputc(*c, csv->fp); + } + fputc('"', csv->fp); + break; + default: + xassert(dca != dca); + } + fputc(k < nf ? ',' : '\n', csv->fp); + } + csv->count++; + if (ferror(csv->fp)) + { xprintf("%s:%d: write error - %s\n", csv->fname, csv->count, + strerror(errno)); + ret = 1; + } + return ret; +} + +static int csv_close_file(TABDCA *dca, struct csv *csv) +{ /* close csv data file */ + int ret = 0; + xassert(dca == dca); + if (csv->mode == 'W') + { fflush(csv->fp); + if (ferror(csv->fp)) + { xprintf("%s:%d: write error - %s\n", csv->fname, + csv->count, strerror(errno)); + ret = 1; + } + } + xfree(csv->fname); + fclose(csv->fp); + xfree(csv); + return ret; +} + +/**********************************************************************/ + +#define DBF_FIELD_MAX 50 +/* maximal number of fields in record */ + +#define DBF_FDLEN_MAX 100 +/* maximal field length */ + +struct dbf +{ /* xBASE data file */ + int mode; + /* 'R' = reading; 'W' = writing */ + char *fname; + /* name of xBASE file */ + FILE *fp; + /* stream assigned to xBASE file */ + jmp_buf jump; + /* address for non-local go to in case of error */ + int offset; + /* offset of a byte to be read next */ + int count; + /* record count */ + int nf; + /* number of fields */ + int ref[1+DBF_FIELD_MAX]; + /* ref[k] = k', if k-th field of the csv file corresponds to + k'-th field in the table statement; if ref[k] = 0, k-th field + of the csv file is ignored */ + int type[1+DBF_FIELD_MAX]; + /* type[k] is type of k-th field */ + int len[1+DBF_FIELD_MAX]; + /* len[k] is length of k-th field */ + int prec[1+DBF_FIELD_MAX]; + /* prec[k] is precision of k-th field */ +}; + +static int read_byte(struct dbf *dbf) +{ /* read byte from xBASE data file */ + int b; + b = fgetc(dbf->fp); + if (ferror(dbf->fp)) + { xprintf("%s:0x%X: read error - %s\n", dbf->fname, + dbf->offset, strerror(errno)); + longjmp(dbf->jump, 0); + } + if (feof(dbf->fp)) + { xprintf("%s:0x%X: unexpected end of file\n", dbf->fname, + dbf->offset); + longjmp(dbf->jump, 0); + } + xassert(0x00 <= b && b <= 0xFF); + dbf->offset++; + return b; +} + +static void read_header(TABDCA *dca, struct dbf *dbf) +{ /* read xBASE data file header */ + int b, j, k, recl; + char name[10+1]; + /* (ignored) */ + for (j = 1; j <= 10; j++) + read_byte(dbf); + /* length of each record, in bytes */ + recl = read_byte(dbf); + recl += read_byte(dbf) << 8; + /* (ignored) */ + for (j = 1; j <= 20; j++) + read_byte(dbf); + /* field descriptor array */ + xassert(dbf->nf == 0); + for (;;) + { /* check for end of array */ + b = read_byte(dbf); + if (b == 0x0D) break; + if (dbf->nf == DBF_FIELD_MAX) + { xprintf("%s:0x%X: too many fields\n", dbf->fname, + dbf->offset); + longjmp(dbf->jump, 0); + } + dbf->nf++; + /* field name */ + name[0] = (char)b; + for (j = 1; j < 10; j++) + { b = read_byte(dbf); + name[j] = (char)b; + } + name[10] = '\0'; + b = read_byte(dbf); + if (b != 0x00) + { xprintf("%s:0x%X: invalid field name\n", dbf->fname, + dbf->offset); + longjmp(dbf->jump, 0); + } + /* find corresponding field in the table statement */ + for (k = mpl_tab_num_flds(dca); k >= 1; k--) + if (strcmp(mpl_tab_get_name(dca, k), name) == 0) break; + dbf->ref[dbf->nf] = k; + /* field type */ + b = read_byte(dbf); + if (!(b == 'C' || b == 'N')) + { xprintf("%s:0x%X: invalid field type\n", dbf->fname, + dbf->offset); + longjmp(dbf->jump, 0); + } + dbf->type[dbf->nf] = b; + /* (ignored) */ + for (j = 1; j <= 4; j++) + read_byte(dbf); + /* field length */ + b = read_byte(dbf); + if (b == 0) + { xprintf("%s:0x%X: invalid field length\n", dbf->fname, + dbf->offset); + longjmp(dbf->jump, 0); + } + if (b > DBF_FDLEN_MAX) + { xprintf("%s:0x%X: field too long\n", dbf->fname, + dbf->offset); + longjmp(dbf->jump, 0); + } + dbf->len[dbf->nf] = b; + recl -= b; + /* (ignored) */ + for (j = 1; j <= 15; j++) + read_byte(dbf); + } + if (recl != 1) + { xprintf("%s:0x%X: invalid file header\n", dbf->fname, + dbf->offset); + longjmp(dbf->jump, 0); + } + /* find dummy RECNO field in the table statement */ + for (k = mpl_tab_num_flds(dca); k >= 1; k--) + if (strcmp(mpl_tab_get_name(dca, k), "RECNO") == 0) break; + dbf->ref[0] = k; + return; +} + +static void parse_third_arg(TABDCA *dca, struct dbf *dbf) +{ /* parse xBASE file format (third argument) */ + int j, k, temp; + const char *arg; + dbf->nf = mpl_tab_num_flds(dca); + arg = mpl_tab_get_arg(dca, 3), j = 0; + for (k = 1; k <= dbf->nf; k++) + { /* parse specification of k-th field */ + if (arg[j] == '\0') + { xprintf("xBASE driver: field %s: specification missing\n", + mpl_tab_get_name(dca, k)); + longjmp(dbf->jump, 0); + } + /* parse field type */ + if (arg[j] == 'C' || arg[j] == 'N') + dbf->type[k] = arg[j], j++; + else + { xprintf("xBASE driver: field %s: invalid field type\n", + mpl_tab_get_name(dca, k)); + longjmp(dbf->jump, 0); + } + /* check for left parenthesis */ + if (arg[j] == '(') + j++; + else +err: { xprintf("xBASE driver: field %s: invalid field format\n", + mpl_tab_get_name(dca, k)); + longjmp(dbf->jump, 0); + } + /* parse field length */ + temp = 0; + while (isdigit(arg[j])) + { if (temp > DBF_FDLEN_MAX) break; + temp = 10 * temp + (arg[j] - '0'), j++; + } + if (!(1 <= temp && temp <= DBF_FDLEN_MAX)) + { xprintf("xBASE driver: field %s: invalid field length\n", + mpl_tab_get_name(dca, k)); + longjmp(dbf->jump, 0); + } + dbf->len[k] = temp; + /* parse optional field precision */ + if (dbf->type[k] == 'N' && arg[j] == ',') + { j++; + temp = 0; + while (isdigit(arg[j])) + { if (temp > dbf->len[k]) break; + temp = 10 * temp + (arg[j] - '0'), j++; + } + if (temp > dbf->len[k]) + { xprintf("xBASE driver: field %s: invalid field precision" + "\n", mpl_tab_get_name(dca, k)); + longjmp(dbf->jump, 0); + } + dbf->prec[k] = temp; + } + else + dbf->prec[k] = 0; + /* check for right parenthesis */ + if (arg[j] == ')') + j++; + else + goto err; + } + /* ignore other specifications */ + return; +} + +static void write_byte(struct dbf *dbf, int b) +{ /* write byte to xBASE data file */ + fputc(b, dbf->fp); + dbf->offset++; + return; +} + +static void write_header(TABDCA *dca, struct dbf *dbf) +{ /* write xBASE data file header */ + int j, k, temp; + const char *name; + /* version number */ + write_byte(dbf, 0x03 /* file without DBT */); + /* date of last update (YYMMDD) */ + write_byte(dbf, 70 /* 1970 */); + write_byte(dbf, 1 /* January */); + write_byte(dbf, 1 /* 1st */); + /* number of records (unknown so far) */ + for (j = 1; j <= 4; j++) + write_byte(dbf, 0xFF); + /* length of the header, in bytes */ + temp = 32 + dbf->nf * 32 + 1; + write_byte(dbf, temp); + write_byte(dbf, temp >> 8); + /* length of each record, in bytes */ + temp = 1; + for (k = 1; k <= dbf->nf; k++) + temp += dbf->len[k]; + write_byte(dbf, temp); + write_byte(dbf, temp >> 8); + /* (reserved) */ + for (j = 1; j <= 20; j++) + write_byte(dbf, 0x00); + /* field descriptor array */ + for (k = 1; k <= dbf->nf; k++) + { /* field name (terminated by 0x00) */ + name = mpl_tab_get_name(dca, k); + for (j = 0; j < 10 && name[j] != '\0'; j++) + write_byte(dbf, name[j]); + for (j = j; j < 11; j++) + write_byte(dbf, 0x00); + /* field type */ + write_byte(dbf, dbf->type[k]); + /* (reserved) */ + for (j = 1; j <= 4; j++) + write_byte(dbf, 0x00); + /* field length */ + write_byte(dbf, dbf->len[k]); + /* field precision */ + write_byte(dbf, dbf->prec[k]); + /* (reserved) */ + for (j = 1; j <= 14; j++) + write_byte(dbf, 0x00); + } + /* end of header */ + write_byte(dbf, 0x0D); + return; +} + +static struct dbf *dbf_open_file(TABDCA *dca, int mode) +{ /* open xBASE data file */ + struct dbf *dbf; + /* create control structure */ + dbf = xmalloc(sizeof(struct dbf)); + dbf->mode = mode; + dbf->fname = NULL; + dbf->fp = NULL; + if (setjmp(dbf->jump)) goto fail; + dbf->offset = 0; + dbf->count = 0; + dbf->nf = 0; + /* try to open the xBASE data file */ + if (mpl_tab_num_args(dca) < 2) + { xprintf("xBASE driver: file name not specified\n"); + longjmp(dbf->jump, 0); + } + dbf->fname = xmalloc(strlen(mpl_tab_get_arg(dca, 2))+1); + strcpy(dbf->fname, mpl_tab_get_arg(dca, 2)); + if (mode == 'R') + { /* open the file for reading */ + dbf->fp = fopen(dbf->fname, "rb"); + if (dbf->fp == NULL) + { xprintf("xBASE driver: unable to open %s - %s\n", + dbf->fname, strerror(errno)); + longjmp(dbf->jump, 0); + } + read_header(dca, dbf); + } + else if (mode == 'W') + { /* open the file for writing */ + if (mpl_tab_num_args(dca) < 3) + { xprintf("xBASE driver: file format not specified\n"); + longjmp(dbf->jump, 0); + } + parse_third_arg(dca, dbf); + dbf->fp = fopen(dbf->fname, "wb"); + if (dbf->fp == NULL) + { xprintf("xBASE driver: unable to create %s - %s\n", + dbf->fname, strerror(errno)); + longjmp(dbf->jump, 0); + } + write_header(dca, dbf); + } + else + xassert(mode != mode); + /* the file has been open */ + return dbf; +fail: /* the file cannot be open */ + if (dbf->fname != NULL) xfree(dbf->fname); + if (dbf->fp != NULL) fclose(dbf->fp); + xfree(dbf); + return NULL; +} + +static int dbf_read_record(TABDCA *dca, struct dbf *dbf) +{ /* read next record from xBASE data file */ + int b, j, k, ret = 0; + char buf[DBF_FDLEN_MAX+1]; + xassert(dbf->mode == 'R'); + if (setjmp(dbf->jump)) + { ret = 1; + goto done; + } + /* check record flag */ + b = read_byte(dbf); + if (b == 0x1A) + { /* end of data */ + ret = -1; + goto done; + } + if (b != 0x20) + { xprintf("%s:0x%X: invalid record flag\n", dbf->fname, + dbf->offset); + longjmp(dbf->jump, 0); + } + /* read dummy RECNO field */ + if (dbf->ref[0] > 0) + mpl_tab_set_num(dca, dbf->ref[0], dbf->count+1); + /* read fields */ + for (k = 1; k <= dbf->nf; k++) + { /* read k-th field */ + for (j = 0; j < dbf->len[k]; j++) + buf[j] = (char)read_byte(dbf); + buf[dbf->len[k]] = '\0'; + /* set field value */ + if (dbf->type[k] == 'C') + { /* character field */ + if (dbf->ref[k] > 0) + mpl_tab_set_str(dca, dbf->ref[k], strtrim(buf)); + } + else if (dbf->type[k] == 'N') + { /* numeric field */ + if (dbf->ref[k] > 0) + { double num; + strspx(buf); + xassert(str2num(buf, &num) == 0); + mpl_tab_set_num(dca, dbf->ref[k], num); + } + } + else + xassert(dbf != dbf); + } + /* increase record count */ + dbf->count++; +done: return ret; +} + +static int dbf_write_record(TABDCA *dca, struct dbf *dbf) +{ /* write next record to xBASE data file */ + int j, k, ret = 0; + char buf[255+1]; + xassert(dbf->mode == 'W'); + if (setjmp(dbf->jump)) + { ret = 1; + goto done; + } + /* record flag */ + write_byte(dbf, 0x20); + xassert(dbf->nf == mpl_tab_num_flds(dca)); + for (k = 1; k <= dbf->nf; k++) + { if (dbf->type[k] == 'C') + { /* character field */ + const char *str; + if (mpl_tab_get_type(dca, k) == 'N') + { sprintf(buf, "%.*g", DBL_DIG, mpl_tab_get_num(dca, k)); + str = buf; + } + else if (mpl_tab_get_type(dca, k) == 'S') + str = mpl_tab_get_str(dca, k); + else + xassert(dca != dca); + if ((int)strlen(str) > dbf->len[k]) + { xprintf("xBASE driver: field %s: cannot convert %.15s..." + " to field format\n", mpl_tab_get_name(dca, k), str); + longjmp(dbf->jump, 0); + } + for (j = 0; j < dbf->len[k] && str[j] != '\0'; j++) + write_byte(dbf, str[j]); + for (j = j; j < dbf->len[k]; j++) + write_byte(dbf, ' '); + } + else if (dbf->type[k] == 'N') + { /* numeric field */ + double num = mpl_tab_get_num(dca, k); + if (fabs(num) > 1e20) +err: { xprintf("xBASE driver: field %s: cannot convert %g to fi" + "eld format\n", mpl_tab_get_name(dca, k), num); + longjmp(dbf->jump, 0); + } + sprintf(buf, "%*.*f", dbf->len[k], dbf->prec[k], num); + xassert(strlen(buf) < sizeof(buf)); + if ((int)strlen(buf) != dbf->len[k]) goto err; + for (j = 0; j < dbf->len[k]; j++) + write_byte(dbf, buf[j]); + } + else + xassert(dbf != dbf); + } + /* increase record count */ + dbf->count++; +done: return ret; +} + +static int dbf_close_file(TABDCA *dca, struct dbf *dbf) +{ /* close xBASE data file */ + int ret = 0; + xassert(dca == dca); + if (dbf->mode == 'W') + { if (setjmp(dbf->jump)) + { ret = 1; + goto skip; + } + /* end-of-file flag */ + write_byte(dbf, 0x1A); + /* number of records */ + dbf->offset = 4; + if (fseek(dbf->fp, dbf->offset, SEEK_SET)) + { xprintf("%s:0x%X: seek error - %s\n", dbf->fname, + dbf->offset, strerror(errno)); + longjmp(dbf->jump, 0); + } + write_byte(dbf, dbf->count); + write_byte(dbf, dbf->count >> 8); + write_byte(dbf, dbf->count >> 16); + write_byte(dbf, dbf->count >> 24); + fflush(dbf->fp); + if (ferror(dbf->fp)) + { xprintf("%s:0x%X: write error - %s\n", dbf->fname, + dbf->offset, strerror(errno)); + longjmp(dbf->jump, 0); + } +skip: ; + } + xfree(dbf->fname); + fclose(dbf->fp); + xfree(dbf); + return ret; +} + +/**********************************************************************/ + +#define TAB_CSV 1 +#define TAB_XBASE 2 +#define TAB_ODBC 3 +#define TAB_MYSQL 4 + +void mpl_tab_drv_open(MPL *mpl, int mode) +{ TABDCA *dca = mpl->dca; + xassert(dca->id == 0); + xassert(dca->link == NULL); + xassert(dca->na >= 1); + if (strcmp(dca->arg[1], "CSV") == 0) + { dca->id = TAB_CSV; + dca->link = csv_open_file(dca, mode); + } + else if (strcmp(dca->arg[1], "xBASE") == 0) + { dca->id = TAB_XBASE; + dca->link = dbf_open_file(dca, mode); + } + else if (strcmp(dca->arg[1], "ODBC") == 0 || + strcmp(dca->arg[1], "iODBC") == 0) + { dca->id = TAB_ODBC; + dca->link = db_iodbc_open(dca, mode); + } + else if (strcmp(dca->arg[1], "MySQL") == 0) + { dca->id = TAB_MYSQL; + dca->link = db_mysql_open(dca, mode); + } + else + xprintf("Invalid table driver '%s'\n", dca->arg[1]); + if (dca->link == NULL) + error(mpl, "error on opening table %s", + mpl->stmt->u.tab->name); + return; +} + +int mpl_tab_drv_read(MPL *mpl) +{ TABDCA *dca = mpl->dca; + int ret; + switch (dca->id) + { case TAB_CSV: + ret = csv_read_record(dca, dca->link); + break; + case TAB_XBASE: + ret = dbf_read_record(dca, dca->link); + break; + case TAB_ODBC: + ret = db_iodbc_read(dca, dca->link); + break; + case TAB_MYSQL: + ret = db_mysql_read(dca, dca->link); + break; + default: + xassert(dca != dca); + } + if (ret > 0) + error(mpl, "error on reading data from table %s", + mpl->stmt->u.tab->name); + return ret; +} + +void mpl_tab_drv_write(MPL *mpl) +{ TABDCA *dca = mpl->dca; + int ret; + switch (dca->id) + { case TAB_CSV: + ret = csv_write_record(dca, dca->link); + break; + case TAB_XBASE: + ret = dbf_write_record(dca, dca->link); + break; + case TAB_ODBC: + ret = db_iodbc_write(dca, dca->link); + break; + case TAB_MYSQL: + ret = db_mysql_write(dca, dca->link); + break; + default: + xassert(dca != dca); + } + if (ret) + error(mpl, "error on writing data to table %s", + mpl->stmt->u.tab->name); + return; +} + +void mpl_tab_drv_close(MPL *mpl) +{ TABDCA *dca = mpl->dca; + int ret; + switch (dca->id) + { case TAB_CSV: + ret = csv_close_file(dca, dca->link); + break; + case TAB_XBASE: + ret = dbf_close_file(dca, dca->link); + break; + case TAB_ODBC: + ret = db_iodbc_close(dca, dca->link); + break; + case TAB_MYSQL: + ret = db_mysql_close(dca, dca->link); + break; + default: + xassert(dca != dca); + } + dca->id = 0; + dca->link = NULL; + if (ret) + error(mpl, "error on closing table %s", + mpl->stmt->u.tab->name); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpmps.c b/resources/3rdparty/glpk-4.57/src/glpmps.c new file mode 100644 index 000000000..69be984c5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpmps.c @@ -0,0 +1,1433 @@ +/* glpmps.c (MPS format routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "misc.h" +#include "prob.h" + +#define xfprintf glp_format + +/*********************************************************************** +* NAME +* +* glp_init_mpscp - initialize MPS format control parameters +* +* SYNOPSIS +* +* void glp_init_mpscp(glp_mpscp *parm); +* +* DESCRIPTION +* +* The routine glp_init_mpscp initializes control parameters, which are +* used by the MPS input/output routines glp_read_mps and glp_write_mps, +* with default values. +* +* Default values of the control parameters are stored in the glp_mpscp +* structure, which the parameter parm points to. */ + +void glp_init_mpscp(glp_mpscp *parm) +{ parm->blank = '\0'; + parm->obj_name = NULL; + parm->tol_mps = 1e-12; + return; +} + +static void check_parm(const char *func, const glp_mpscp *parm) +{ /* check control parameters */ + if (!(0x00 <= parm->blank && parm->blank <= 0xFF) || + !(parm->blank == '\0' || isprint(parm->blank))) + xerror("%s: blank = 0x%02X; invalid parameter\n", + func, parm->blank); + if (!(parm->obj_name == NULL || strlen(parm->obj_name) <= 255)) + xerror("%s: obj_name = \"%.12s...\"; parameter too long\n", + func, parm->obj_name); + if (!(0.0 <= parm->tol_mps && parm->tol_mps < 1.0)) + xerror("%s: tol_mps = %g; invalid parameter\n", + func, parm->tol_mps); + return; +} + +/*********************************************************************** +* NAME +* +* glp_read_mps - read problem data in MPS format +* +* SYNOPSIS +* +* int glp_read_mps(glp_prob *P, int fmt, const glp_mpscp *parm, +* const char *fname); +* +* DESCRIPTION +* +* The routine glp_read_mps reads problem data in MPS format from a +* text file. +* +* The parameter fmt specifies the version of MPS format: +* +* GLP_MPS_DECK - fixed (ancient) MPS format; +* GLP_MPS_FILE - free (modern) MPS format. +* +* The parameter parm is a pointer to the structure glp_mpscp, which +* specifies control parameters used by the routine. If parm is NULL, +* the routine uses default settings. +* +* The character string fname specifies a name of the text file to be +* read. +* +* Note that before reading data the current content of the problem +* object is completely erased with the routine glp_erase_prob. +* +* RETURNS +* +* If the operation was successful, the routine glp_read_mps returns +* zero. Otherwise, it prints an error message and returns non-zero. */ + +struct csa +{ /* common storage area */ + glp_prob *P; + /* pointer to problem object */ + int deck; + /* MPS format (0 - free, 1 - fixed) */ + const glp_mpscp *parm; + /* pointer to control parameters */ + const char *fname; + /* name of input MPS file */ + glp_file *fp; + /* stream assigned to input MPS file */ + jmp_buf jump; + /* label for go to in case of error */ + int recno; + /* current record (card) number */ + int recpos; + /* current record (card) position */ + int c; + /* current character */ + int fldno; + /* current field number */ + char field[255+1]; + /* current field content */ + int w80; + /* warning 'record must not be longer than 80 chars' issued */ + int wef; + /* warning 'extra fields detected beyond field 6' issued */ + int obj_row; + /* objective row number */ + void *work1, *work2, *work3; + /* working arrays */ +}; + +static void error(struct csa *csa, const char *fmt, ...) +{ /* print error message and terminate processing */ + va_list arg; + xprintf("%s:%d: ", csa->fname, csa->recno); + va_start(arg, fmt); + xvprintf(fmt, arg); + va_end(arg); + longjmp(csa->jump, 1); + /* no return */ +} + +static void warning(struct csa *csa, const char *fmt, ...) +{ /* print warning message and continue processing */ + va_list arg; + xprintf("%s:%d: warning: ", csa->fname, csa->recno); + va_start(arg, fmt); + xvprintf(fmt, arg); + va_end(arg); + return; +} + +static void read_char(struct csa *csa) +{ /* read next character */ + int c; + if (csa->c == '\n') + csa->recno++, csa->recpos = 0; + csa->recpos++; +read: c = glp_getc(csa->fp); + if (c < 0) + { if (glp_ioerr(csa->fp)) + error(csa, "read error - %s\n", get_err_msg()); + else if (csa->c == '\n') + error(csa, "unexpected end of file\n"); + else + { warning(csa, "missing final end of line\n"); + c = '\n'; + } + } + else if (c == '\n') + ; + else if (csa->c == '\r') + { c = '\r'; + goto badc; + } + else if (csa->deck && c == '\r') + { csa->c = '\r'; + goto read; + } + else if (c == ' ') + ; + else if (isspace(c)) + { if (csa->deck) +badc: error(csa, "in fixed MPS format white-space character 0x%02" + "X is not allowed\n", c); + c = ' '; + } + else if (iscntrl(c)) + error(csa, "invalid control character 0x%02X\n", c); + if (csa->deck && csa->recpos == 81 && c != '\n' && csa->w80 < 1) + { warning(csa, "in fixed MPS format record must not be longer th" + "an 80 characters\n"); + csa->w80++; + } + csa->c = c; + return; +} + +static int indicator(struct csa *csa, int name) +{ /* skip comment records and read possible indicator record */ + int ret; + /* reset current field number */ + csa->fldno = 0; +loop: /* read the very first character of the next record */ + xassert(csa->c == '\n'); + read_char(csa); + if (csa->c == ' ' || csa->c == '\n') + { /* data record */ + ret = 0; + } + else if (csa->c == '*') + { /* comment record */ + while (csa->c != '\n') + read_char(csa); + goto loop; + } + else + { /* indicator record */ + int len = 0; + while (csa->c != ' ' && csa->c != '\n' && len < 12) + { csa->field[len++] = (char)csa->c; + read_char(csa); + } + csa->field[len] = '\0'; + if (!(strcmp(csa->field, "NAME") == 0 || + strcmp(csa->field, "ROWS") == 0 || + strcmp(csa->field, "COLUMNS") == 0 || + strcmp(csa->field, "RHS") == 0 || + strcmp(csa->field, "RANGES") == 0 || + strcmp(csa->field, "BOUNDS") == 0 || + strcmp(csa->field, "ENDATA") == 0)) + error(csa, "invalid indicator record\n"); + if (!name) + { while (csa->c != '\n') + read_char(csa); + } + ret = 1; + } + return ret; +} + +static void read_field(struct csa *csa) +{ /* read next field of the current data record */ + csa->fldno++; + if (csa->deck) + { /* fixed MPS format */ + int beg, end, pos; + /* determine predefined field positions */ + if (csa->fldno == 1) + beg = 2, end = 3; + else if (csa->fldno == 2) + beg = 5, end = 12; + else if (csa->fldno == 3) + beg = 15, end = 22; + else if (csa->fldno == 4) + beg = 25, end = 36; + else if (csa->fldno == 5) + beg = 40, end = 47; + else if (csa->fldno == 6) + beg = 50, end = 61; + else + xassert(csa != csa); + /* skip blanks preceding the current field */ + if (csa->c != '\n') + { pos = csa->recpos; + while (csa->recpos < beg) + { if (csa->c == ' ') + ; + else if (csa->c == '\n') + break; + else + error(csa, "in fixed MPS format positions %d-%d must " + "be blank\n", pos, beg-1); + read_char(csa); + } + } + /* skip possible comment beginning in the field 3 or 5 */ + if ((csa->fldno == 3 || csa->fldno == 5) && csa->c == '$') + { while (csa->c != '\n') + read_char(csa); + } + /* read the current field */ + for (pos = beg; pos <= end; pos++) + { if (csa->c == '\n') break; + csa->field[pos-beg] = (char)csa->c; + read_char(csa); + } + csa->field[pos-beg] = '\0'; + strtrim(csa->field); + /* skip blanks following the last field */ + if (csa->fldno == 6 && csa->c != '\n') + { while (csa->recpos <= 72) + { if (csa->c == ' ') + ; + else if (csa->c == '\n') + break; + else + error(csa, "in fixed MPS format positions 62-72 must " + "be blank\n"); + read_char(csa); + } + while (csa->c != '\n') + read_char(csa); + } + } + else + { /* free MPS format */ + int len; + /* skip blanks preceding the current field */ + while (csa->c == ' ') + read_char(csa); + /* skip possible comment */ + if (csa->c == '$') + { while (csa->c != '\n') + read_char(csa); + } + /* read the current field */ + len = 0; + while (!(csa->c == ' ' || csa->c == '\n')) + { if (len == 255) + error(csa, "length of field %d exceeds 255 characters\n", + csa->fldno++); + csa->field[len++] = (char)csa->c; + read_char(csa); + } + csa->field[len] = '\0'; + /* skip anything following the last field (any extra fields + are considered to be comments) */ + if (csa->fldno == 6) + { while (csa->c == ' ') + read_char(csa); + if (csa->c != '$' && csa->c != '\n' && csa->wef < 1) + { warning(csa, "some extra field(s) detected beyond field " + "6; field(s) ignored\n"); + csa->wef++; + } + while (csa->c != '\n') + read_char(csa); + } + } + return; +} + +static void patch_name(struct csa *csa, char *name) +{ /* process embedded blanks in symbolic name */ + int blank = csa->parm->blank; + if (blank == '\0') + { /* remove emedded blanks */ + strspx(name); + } + else + { /* replace embedded blanks by specified character */ + for (; *name != '\0'; name++) + if (*name == ' ') *name = (char)blank; + } + return; +} + +static double read_number(struct csa *csa) +{ /* read next field and convert it to floating-point number */ + double x; + char *s; + /* read next field */ + read_field(csa); + xassert(csa->fldno == 4 || csa->fldno == 6); + if (csa->field[0] == '\0') + error(csa, "missing numeric value in field %d\n", csa->fldno); + /* skip initial spaces of the field */ + for (s = csa->field; *s == ' '; s++); + /* perform conversion */ + if (str2num(s, &x) != 0) + error(csa, "cannot convert '%s' to floating-point number\n", + s); + return x; +} + +static void skip_field(struct csa *csa) +{ /* read and skip next field (assumed to be blank) */ + read_field(csa); + if (csa->field[0] != '\0') + error(csa, "field %d must be blank\n", csa->fldno); + return; +} + +static void read_name(struct csa *csa) +{ /* read NAME indicator record */ + if (!(indicator(csa, 1) && strcmp(csa->field, "NAME") == 0)) + error(csa, "missing NAME indicator record\n"); + /* this indicator record looks like a data record; simulate that + fields 1 and 2 were read */ + csa->fldno = 2; + /* field 3: model name */ + read_field(csa), patch_name(csa, csa->field); + if (csa->field[0] == '\0') + warning(csa, "missing model name in field 3\n"); + else + glp_set_prob_name(csa->P, csa->field); + /* skip anything following field 3 */ + while (csa->c != '\n') + read_char(csa); + return; +} + +static void read_rows(struct csa *csa) +{ /* read ROWS section */ + int i, type; +loop: if (indicator(csa, 0)) goto done; + /* field 1: row type */ + read_field(csa), strspx(csa->field); + if (strcmp(csa->field, "N") == 0) + type = GLP_FR; + else if (strcmp(csa->field, "G") == 0) + type = GLP_LO; + else if (strcmp(csa->field, "L") == 0) + type = GLP_UP; + else if (strcmp(csa->field, "E") == 0) + type = GLP_FX; + else if (csa->field[0] == '\0') + error(csa, "missing row type in field 1\n"); + else + error(csa, "invalid row type in field 1\n"); + /* field 2: row name */ + read_field(csa), patch_name(csa, csa->field); + if (csa->field[0] == '\0') + error(csa, "missing row name in field 2\n"); + if (glp_find_row(csa->P, csa->field) != 0) + error(csa, "row '%s' multiply specified\n", csa->field); + i = glp_add_rows(csa->P, 1); + glp_set_row_name(csa->P, i, csa->field); + glp_set_row_bnds(csa->P, i, type, 0.0, 0.0); + /* fields 3, 4, 5, and 6 must be blank */ + skip_field(csa); + skip_field(csa); + skip_field(csa); + skip_field(csa); + goto loop; +done: return; +} + +static void read_columns(struct csa *csa) +{ /* read COLUMNS section */ + int i, j, f, len, kind = GLP_CV, *ind; + double aij, *val; + char name[255+1], *flag; + /* allocate working arrays */ + csa->work1 = ind = xcalloc(1+csa->P->m, sizeof(int)); + csa->work2 = val = xcalloc(1+csa->P->m, sizeof(double)); + csa->work3 = flag = xcalloc(1+csa->P->m, sizeof(char)); + memset(&flag[1], 0, csa->P->m); + /* no current column exists */ + j = 0, len = 0; +loop: if (indicator(csa, 0)) goto done; + /* field 1 must be blank */ + if (csa->deck) + { read_field(csa); + if (csa->field[0] != '\0') + error(csa, "field 1 must be blank\n"); + } + else + csa->fldno++; + /* field 2: column or kind name */ + read_field(csa), patch_name(csa, csa->field); + strcpy(name, csa->field); + /* field 3: row name or keyword 'MARKER' */ + read_field(csa), patch_name(csa, csa->field); + if (strcmp(csa->field, "'MARKER'") == 0) + { /* process kind data record */ + /* field 4 must be blank */ + if (csa->deck) + { read_field(csa); + if (csa->field[0] != '\0') + error(csa, "field 4 must be blank\n"); + } + else + csa->fldno++; + /* field 5: keyword 'INTORG' or 'INTEND' */ + read_field(csa), patch_name(csa, csa->field); + if (strcmp(csa->field, "'INTORG'") == 0) + kind = GLP_IV; + else if (strcmp(csa->field, "'INTEND'") == 0) + kind = GLP_CV; + else if (csa->field[0] == '\0') + error(csa, "missing keyword in field 5\n"); + else + error(csa, "invalid keyword in field 5\n"); + /* field 6 must be blank */ + skip_field(csa); + goto loop; + } + /* process column name specified in field 2 */ + if (name[0] == '\0') + { /* the same column as in previous data record */ + if (j == 0) + error(csa, "missing column name in field 2\n"); + } + else if (j != 0 && strcmp(name, csa->P->col[j]->name) == 0) + { /* the same column as in previous data record */ + xassert(j != 0); + } + else + { /* store the current column */ + if (j != 0) + { glp_set_mat_col(csa->P, j, len, ind, val); + while (len > 0) flag[ind[len--]] = 0; + } + /* create new column */ + if (glp_find_col(csa->P, name) != 0) + error(csa, "column '%s' multiply specified\n", name); + j = glp_add_cols(csa->P, 1); + glp_set_col_name(csa->P, j, name); + glp_set_col_kind(csa->P, j, kind); + if (kind == GLP_CV) + glp_set_col_bnds(csa->P, j, GLP_LO, 0.0, 0.0); + else if (kind == GLP_IV) + glp_set_col_bnds(csa->P, j, GLP_DB, 0.0, 1.0); + else + xassert(kind != kind); + } + /* process fields 3-4 and 5-6 */ + for (f = 3; f <= 5; f += 2) + { /* field 3 or 5: row name */ + if (f == 3) + { if (csa->field[0] == '\0') + error(csa, "missing row name in field 3\n"); + } + else + { read_field(csa), patch_name(csa, csa->field); + if (csa->field[0] == '\0') + { /* if field 5 is blank, field 6 also must be blank */ + skip_field(csa); + continue; + } + } + i = glp_find_row(csa->P, csa->field); + if (i == 0) + error(csa, "row '%s' not found\n", csa->field); + if (flag[i]) + error(csa, "duplicate coefficient in row '%s'\n", + csa->field); + /* field 4 or 6: coefficient value */ + aij = read_number(csa); + if (fabs(aij) < csa->parm->tol_mps) aij = 0.0; + len++, ind[len] = i, val[len] = aij, flag[i] = 1; + } + goto loop; +done: /* store the last column */ + if (j != 0) + glp_set_mat_col(csa->P, j, len, ind, val); + /* free working arrays */ + xfree(ind); + xfree(val); + xfree(flag); + csa->work1 = csa->work2 = csa->work3 = NULL; + return; +} + +static void read_rhs(struct csa *csa) +{ /* read RHS section */ + int i, f, v, type; + double rhs; + char name[255+1], *flag; + /* allocate working array */ + csa->work3 = flag = xcalloc(1+csa->P->m, sizeof(char)); + memset(&flag[1], 0, csa->P->m); + /* no current RHS vector exists */ + v = 0; +loop: if (indicator(csa, 0)) goto done; + /* field 1 must be blank */ + if (csa->deck) + { read_field(csa); + if (csa->field[0] != '\0') + error(csa, "field 1 must be blank\n"); + } + else + csa->fldno++; + /* field 2: RHS vector name */ + read_field(csa), patch_name(csa, csa->field); + if (csa->field[0] == '\0') + { /* the same RHS vector as in previous data record */ + if (v == 0) + { warning(csa, "missing RHS vector name in field 2\n"); + goto blnk; + } + } + else if (v != 0 && strcmp(csa->field, name) == 0) + { /* the same RHS vector as in previous data record */ + xassert(v != 0); + } + else +blnk: { /* new RHS vector */ + if (v != 0) + error(csa, "multiple RHS vectors not supported\n"); + v++; + strcpy(name, csa->field); + } + /* process fields 3-4 and 5-6 */ + for (f = 3; f <= 5; f += 2) + { /* field 3 or 5: row name */ + read_field(csa), patch_name(csa, csa->field); + if (csa->field[0] == '\0') + { if (f == 3) + error(csa, "missing row name in field 3\n"); + else + { /* if field 5 is blank, field 6 also must be blank */ + skip_field(csa); + continue; + } + } + i = glp_find_row(csa->P, csa->field); + if (i == 0) + error(csa, "row '%s' not found\n", csa->field); + if (flag[i]) + error(csa, "duplicate right-hand side for row '%s'\n", + csa->field); + /* field 4 or 6: right-hand side value */ + rhs = read_number(csa); + if (fabs(rhs) < csa->parm->tol_mps) rhs = 0.0; + type = csa->P->row[i]->type; + if (type == GLP_FR) + { if (i == csa->obj_row) + glp_set_obj_coef(csa->P, 0, rhs); + else if (rhs != 0.0) + warning(csa, "non-zero right-hand side for free row '%s'" + " ignored\n", csa->P->row[i]->name); + } + else + glp_set_row_bnds(csa->P, i, type, rhs, rhs); + flag[i] = 1; + } + goto loop; +done: /* free working array */ + xfree(flag); + csa->work3 = NULL; + return; +} + +static void read_ranges(struct csa *csa) +{ /* read RANGES section */ + int i, f, v, type; + double rhs, rng; + char name[255+1], *flag; + /* allocate working array */ + csa->work3 = flag = xcalloc(1+csa->P->m, sizeof(char)); + memset(&flag[1], 0, csa->P->m); + /* no current RANGES vector exists */ + v = 0; +loop: if (indicator(csa, 0)) goto done; + /* field 1 must be blank */ + if (csa->deck) + { read_field(csa); + if (csa->field[0] != '\0') + error(csa, "field 1 must be blank\n"); + } + else + csa->fldno++; + /* field 2: RANGES vector name */ + read_field(csa), patch_name(csa, csa->field); + if (csa->field[0] == '\0') + { /* the same RANGES vector as in previous data record */ + if (v == 0) + { warning(csa, "missing RANGES vector name in field 2\n"); + goto blnk; + } + } + else if (v != 0 && strcmp(csa->field, name) == 0) + { /* the same RANGES vector as in previous data record */ + xassert(v != 0); + } + else +blnk: { /* new RANGES vector */ + if (v != 0) + error(csa, "multiple RANGES vectors not supported\n"); + v++; + strcpy(name, csa->field); + } + /* process fields 3-4 and 5-6 */ + for (f = 3; f <= 5; f += 2) + { /* field 3 or 5: row name */ + read_field(csa), patch_name(csa, csa->field); + if (csa->field[0] == '\0') + { if (f == 3) + error(csa, "missing row name in field 3\n"); + else + { /* if field 5 is blank, field 6 also must be blank */ + skip_field(csa); + continue; + } + } + i = glp_find_row(csa->P, csa->field); + if (i == 0) + error(csa, "row '%s' not found\n", csa->field); + if (flag[i]) + error(csa, "duplicate range for row '%s'\n", csa->field); + /* field 4 or 6: range value */ + rng = read_number(csa); + if (fabs(rng) < csa->parm->tol_mps) rng = 0.0; + type = csa->P->row[i]->type; + if (type == GLP_FR) + warning(csa, "range for free row '%s' ignored\n", + csa->P->row[i]->name); + else if (type == GLP_LO) + { rhs = csa->P->row[i]->lb; + glp_set_row_bnds(csa->P, i, rhs == 0.0 ? GLP_FX : GLP_DB, + rhs, rhs + fabs(rng)); + } + else if (type == GLP_UP) + { rhs = csa->P->row[i]->ub; + glp_set_row_bnds(csa->P, i, rhs == 0.0 ? GLP_FX : GLP_DB, + rhs - fabs(rng), rhs); + } + else if (type == GLP_FX) + { rhs = csa->P->row[i]->lb; + if (rng > 0.0) + glp_set_row_bnds(csa->P, i, GLP_DB, rhs, rhs + rng); + else if (rng < 0.0) + glp_set_row_bnds(csa->P, i, GLP_DB, rhs + rng, rhs); + } + else + xassert(type != type); + flag[i] = 1; + } + goto loop; +done: /* free working array */ + xfree(flag); + csa->work3 = NULL; + return; +} + +static void read_bounds(struct csa *csa) +{ /* read BOUNDS section */ + GLPCOL *col; + int j, v, mask, data; + double bnd, lb, ub; + char type[2+1], name[255+1], *flag; + /* allocate working array */ + csa->work3 = flag = xcalloc(1+csa->P->n, sizeof(char)); + memset(&flag[1], 0, csa->P->n); + /* no current BOUNDS vector exists */ + v = 0; +loop: if (indicator(csa, 0)) goto done; + /* field 1: bound type */ + read_field(csa); + if (strcmp(csa->field, "LO") == 0) + mask = 0x01, data = 1; + else if (strcmp(csa->field, "UP") == 0) + mask = 0x10, data = 1; + else if (strcmp(csa->field, "FX") == 0) + mask = 0x11, data = 1; + else if (strcmp(csa->field, "FR") == 0) + mask = 0x11, data = 0; + else if (strcmp(csa->field, "MI") == 0) + mask = 0x01, data = 0; + else if (strcmp(csa->field, "PL") == 0) + mask = 0x10, data = 0; + else if (strcmp(csa->field, "LI") == 0) + mask = 0x01, data = 1; + else if (strcmp(csa->field, "UI") == 0) + mask = 0x10, data = 1; + else if (strcmp(csa->field, "BV") == 0) + mask = 0x11, data = 0; + else if (csa->field[0] == '\0') + error(csa, "missing bound type in field 1\n"); + else + error(csa, "invalid bound type in field 1\n"); + strcpy(type, csa->field); + /* field 2: BOUNDS vector name */ + read_field(csa), patch_name(csa, csa->field); + if (csa->field[0] == '\0') + { /* the same BOUNDS vector as in previous data record */ + if (v == 0) + { warning(csa, "missing BOUNDS vector name in field 2\n"); + goto blnk; + } + } + else if (v != 0 && strcmp(csa->field, name) == 0) + { /* the same BOUNDS vector as in previous data record */ + xassert(v != 0); + } + else +blnk: { /* new BOUNDS vector */ + if (v != 0) + error(csa, "multiple BOUNDS vectors not supported\n"); + v++; + strcpy(name, csa->field); + } + /* field 3: column name */ + read_field(csa), patch_name(csa, csa->field); + if (csa->field[0] == '\0') + error(csa, "missing column name in field 3\n"); + j = glp_find_col(csa->P, csa->field); + if (j == 0) + error(csa, "column '%s' not found\n", csa->field); + if ((flag[j] & mask) == 0x01) + error(csa, "duplicate lower bound for column '%s'\n", + csa->field); + if ((flag[j] & mask) == 0x10) + error(csa, "duplicate upper bound for column '%s'\n", + csa->field); + xassert((flag[j] & mask) == 0x00); + /* field 4: bound value */ + if (data) + { bnd = read_number(csa); + if (fabs(bnd) < csa->parm->tol_mps) bnd = 0.0; + } + else + read_field(csa), bnd = 0.0; + /* get current column bounds */ + col = csa->P->col[j]; + if (col->type == GLP_FR) + lb = -DBL_MAX, ub = +DBL_MAX; + else if (col->type == GLP_LO) + lb = col->lb, ub = +DBL_MAX; + else if (col->type == GLP_UP) + lb = -DBL_MAX, ub = col->ub; + else if (col->type == GLP_DB) + lb = col->lb, ub = col->ub; + else if (col->type == GLP_FX) + lb = ub = col->lb; + else + xassert(col != col); + /* change column bounds */ + if (strcmp(type, "LO") == 0) + lb = bnd; + else if (strcmp(type, "UP") == 0) + ub = bnd; + else if (strcmp(type, "FX") == 0) + lb = ub = bnd; + else if (strcmp(type, "FR") == 0) + lb = -DBL_MAX, ub = +DBL_MAX; + else if (strcmp(type, "MI") == 0) + lb = -DBL_MAX; + else if (strcmp(type, "PL") == 0) + ub = +DBL_MAX; + else if (strcmp(type, "LI") == 0) + { glp_set_col_kind(csa->P, j, GLP_IV); + lb = ceil(bnd); +#if 1 /* 16/VII-2013 */ + /* if column upper bound has not been explicitly specified, + take it as +inf */ + if (!(flag[j] & 0x10)) + ub = +DBL_MAX; +#endif + } + else if (strcmp(type, "UI") == 0) + { glp_set_col_kind(csa->P, j, GLP_IV); + ub = floor(bnd); + } + else if (strcmp(type, "BV") == 0) + { glp_set_col_kind(csa->P, j, GLP_IV); + lb = 0.0, ub = 1.0; + } + else + xassert(type != type); + /* set new column bounds */ + if (lb == -DBL_MAX && ub == +DBL_MAX) + glp_set_col_bnds(csa->P, j, GLP_FR, lb, ub); + else if (ub == +DBL_MAX) + glp_set_col_bnds(csa->P, j, GLP_LO, lb, ub); + else if (lb == -DBL_MAX) + glp_set_col_bnds(csa->P, j, GLP_UP, lb, ub); + else if (lb != ub) + glp_set_col_bnds(csa->P, j, GLP_DB, lb, ub); + else + glp_set_col_bnds(csa->P, j, GLP_FX, lb, ub); + flag[j] |= (char)mask; + /* fields 5 and 6 must be blank */ + skip_field(csa); + skip_field(csa); + goto loop; +done: /* free working array */ + xfree(flag); + csa->work3 = NULL; + return; +} + +int glp_read_mps(glp_prob *P, int fmt, const glp_mpscp *parm, + const char *fname) +{ /* read problem data in MPS format */ + glp_mpscp _parm; + struct csa _csa, *csa = &_csa; + int ret; + xprintf("Reading problem data from '%s'...\n", fname); + if (!(fmt == GLP_MPS_DECK || fmt == GLP_MPS_FILE)) + xerror("glp_read_mps: fmt = %d; invalid parameter\n", fmt); + if (parm == NULL) + glp_init_mpscp(&_parm), parm = &_parm; + /* check control parameters */ + check_parm("glp_read_mps", parm); + /* initialize common storage area */ + csa->P = P; + csa->deck = (fmt == GLP_MPS_DECK); + csa->parm = parm; + csa->fname = fname; + csa->fp = NULL; + if (setjmp(csa->jump)) + { ret = 1; + goto done; + } + csa->recno = csa->recpos = 0; + csa->c = '\n'; + csa->fldno = 0; + csa->field[0] = '\0'; + csa->w80 = csa->wef = 0; + csa->obj_row = 0; + csa->work1 = csa->work2 = csa->work3 = NULL; + /* erase problem object */ + glp_erase_prob(P); + glp_create_index(P); + /* open input MPS file */ + csa->fp = glp_open(fname, "r"); + if (csa->fp == NULL) + { xprintf("Unable to open '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + /* read NAME indicator record */ + read_name(csa); + if (P->name != NULL) + xprintf("Problem: %s\n", P->name); + /* read ROWS section */ + if (!(indicator(csa, 0) && strcmp(csa->field, "ROWS") == 0)) + error(csa, "missing ROWS indicator record\n"); + read_rows(csa); + /* determine objective row */ + if (parm->obj_name == NULL || parm->obj_name[0] == '\0') + { /* use the first row of N type */ + int i; + for (i = 1; i <= P->m; i++) + { if (P->row[i]->type == GLP_FR) + { csa->obj_row = i; + break; + } + } + if (csa->obj_row == 0) + warning(csa, "unable to determine objective row\n"); + } + else + { /* use a row with specified name */ + int i; + for (i = 1; i <= P->m; i++) + { xassert(P->row[i]->name != NULL); + if (strcmp(parm->obj_name, P->row[i]->name) == 0) + { csa->obj_row = i; + break; + } + } + if (csa->obj_row == 0) + error(csa, "objective row '%s' not found\n", + parm->obj_name); + } + if (csa->obj_row != 0) + { glp_set_obj_name(P, P->row[csa->obj_row]->name); + xprintf("Objective: %s\n", P->obj); + } + /* read COLUMNS section */ + if (strcmp(csa->field, "COLUMNS") != 0) + error(csa, "missing COLUMNS indicator record\n"); + read_columns(csa); + /* set objective coefficients */ + if (csa->obj_row != 0) + { GLPAIJ *aij; + for (aij = P->row[csa->obj_row]->ptr; aij != NULL; aij = + aij->r_next) glp_set_obj_coef(P, aij->col->j, aij->val); + } + /* read optional RHS section */ + if (strcmp(csa->field, "RHS") == 0) + read_rhs(csa); + /* read optional RANGES section */ + if (strcmp(csa->field, "RANGES") == 0) + read_ranges(csa); + /* read optional BOUNDS section */ + if (strcmp(csa->field, "BOUNDS") == 0) + read_bounds(csa); + /* read ENDATA indicator record */ + if (strcmp(csa->field, "ENDATA") != 0) + error(csa, "invalid use of %s indicator record\n", + csa->field); + /* print some statistics */ + xprintf("%d row%s, %d column%s, %d non-zero%s\n", + P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s", + P->nnz, P->nnz == 1 ? "" : "s"); + if (glp_get_num_int(P) > 0) + { int ni = glp_get_num_int(P); + int nb = glp_get_num_bin(P); + if (ni == 1) + { if (nb == 0) + xprintf("One variable is integer\n"); + else + xprintf("One variable is binary\n"); + } + else + { xprintf("%d integer variables, ", ni); + if (nb == 0) + xprintf("none"); + else if (nb == 1) + xprintf("one"); + else if (nb == ni) + xprintf("all"); + else + xprintf("%d", nb); + xprintf(" of which %s binary\n", nb == 1 ? "is" : "are"); + } + } + xprintf("%d records were read\n", csa->recno); +#if 1 /* 08/VIII-2013 */ + /* remove free rows */ + { int i, nrs, *num; + num = talloc(1+P->m, int); + nrs = 0; + for (i = 1; i <= P->m; i++) + { if (P->row[i]->type == GLP_FR) + num[++nrs] = i; + } + if (nrs > 0) + { glp_del_rows(P, nrs, num); + if (nrs == 1) + xprintf("One free row was removed\n"); + else + xprintf("%d free rows were removed\n", nrs); + } + tfree(num); + } +#endif + /* problem data has been successfully read */ + glp_delete_index(P); + glp_sort_matrix(P); + ret = 0; +done: if (csa->fp != NULL) glp_close(csa->fp); + if (csa->work1 != NULL) xfree(csa->work1); + if (csa->work2 != NULL) xfree(csa->work2); + if (csa->work3 != NULL) xfree(csa->work3); + if (ret != 0) glp_erase_prob(P); + return ret; +} + +/*********************************************************************** +* NAME +* +* glp_write_mps - write problem data in MPS format +* +* SYNOPSIS +* +* int glp_write_mps(glp_prob *P, int fmt, const glp_mpscp *parm, +* const char *fname); +* +* DESCRIPTION +* +* The routine glp_write_mps writes problem data in MPS format to a +* text file. +* +* The parameter fmt specifies the version of MPS format: +* +* GLP_MPS_DECK - fixed (ancient) MPS format; +* GLP_MPS_FILE - free (modern) MPS format. +* +* The parameter parm is a pointer to the structure glp_mpscp, which +* specifies control parameters used by the routine. If parm is NULL, +* the routine uses default settings. +* +* The character string fname specifies a name of the text file to be +* written. +* +* RETURNS +* +* If the operation was successful, the routine glp_read_mps returns +* zero. Otherwise, it prints an error message and returns non-zero. */ + +#define csa csa1 + +struct csa +{ /* common storage area */ + glp_prob *P; + /* pointer to problem object */ + int deck; + /* MPS format (0 - free, 1 - fixed) */ + const glp_mpscp *parm; + /* pointer to control parameters */ + char field[255+1]; + /* field buffer */ +}; + +static char *mps_name(struct csa *csa) +{ /* make problem name */ + char *f; + if (csa->P->name == NULL) + csa->field[0] = '\0'; + else if (csa->deck) + { strncpy(csa->field, csa->P->name, 8); + csa->field[8] = '\0'; + } + else + strcpy(csa->field, csa->P->name); + for (f = csa->field; *f != '\0'; f++) + if (*f == ' ') *f = '_'; + return csa->field; +} + +static char *row_name(struct csa *csa, int i) +{ /* make i-th row name */ + char *f; + xassert(0 <= i && i <= csa->P->m); + if (i == 0 || csa->P->row[i]->name == NULL || + csa->deck && strlen(csa->P->row[i]->name) > 8) + sprintf(csa->field, "R%07d", i); + else + { strcpy(csa->field, csa->P->row[i]->name); + for (f = csa->field; *f != '\0'; f++) + if (*f == ' ') *f = '_'; + } + return csa->field; +} + +static char *col_name(struct csa *csa, int j) +{ /* make j-th column name */ + char *f; + xassert(1 <= j && j <= csa->P->n); + if (csa->P->col[j]->name == NULL || + csa->deck && strlen(csa->P->col[j]->name) > 8) + sprintf(csa->field, "C%07d", j); + else + { strcpy(csa->field, csa->P->col[j]->name); + for (f = csa->field; *f != '\0'; f++) + if (*f == ' ') *f = '_'; + } + return csa->field; +} + +static char *mps_numb(struct csa *csa, double val) +{ /* format floating-point number */ + int dig; + char *exp; + for (dig = 12; dig >= 6; dig--) + { if (val != 0.0 && fabs(val) < 0.002) + sprintf(csa->field, "%.*E", dig-1, val); + else + sprintf(csa->field, "%.*G", dig, val); + exp = strchr(csa->field, 'E'); + if (exp != NULL) + sprintf(exp+1, "%d", atoi(exp+1)); + if (strlen(csa->field) <= 12) break; + } + xassert(strlen(csa->field) <= 12); + return csa->field; +} + +int glp_write_mps(glp_prob *P, int fmt, const glp_mpscp *parm, + const char *fname) +{ /* write problem data in MPS format */ + glp_mpscp _parm; + struct csa _csa, *csa = &_csa; + glp_file *fp; + int out_obj, one_col = 0, empty = 0; + int i, j, recno, marker, count, gap, ret; + xprintf("Writing problem data to '%s'...\n", fname); + if (!(fmt == GLP_MPS_DECK || fmt == GLP_MPS_FILE)) + xerror("glp_write_mps: fmt = %d; invalid parameter\n", fmt); + if (parm == NULL) + glp_init_mpscp(&_parm), parm = &_parm; + /* check control parameters */ + check_parm("glp_write_mps", parm); + /* initialize common storage area */ + csa->P = P; + csa->deck = (fmt == GLP_MPS_DECK); + csa->parm = parm; + /* create output MPS file */ + fp = glp_open(fname, "w"), recno = 0; + if (fp == NULL) + { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + /* write comment records */ + xfprintf(fp, "* %-*s%s\n", P->name == NULL ? 1 : 12, "Problem:", + P->name == NULL ? "" : P->name), recno++; + xfprintf(fp, "* %-12s%s\n", "Class:", glp_get_num_int(P) == 0 ? + "LP" : "MIP"), recno++; + xfprintf(fp, "* %-12s%d\n", "Rows:", P->m), recno++; + if (glp_get_num_int(P) == 0) + xfprintf(fp, "* %-12s%d\n", "Columns:", P->n), recno++; + else + xfprintf(fp, "* %-12s%d (%d integer, %d binary)\n", + "Columns:", P->n, glp_get_num_int(P), glp_get_num_bin(P)), + recno++; + xfprintf(fp, "* %-12s%d\n", "Non-zeros:", P->nnz), recno++; + xfprintf(fp, "* %-12s%s\n", "Format:", csa->deck ? "Fixed MPS" : + "Free MPS"), recno++; + xfprintf(fp, "*\n", recno++); + /* write NAME indicator record */ + xfprintf(fp, "NAME%*s%s\n", + P->name == NULL ? 0 : csa->deck ? 10 : 1, "", mps_name(csa)), + recno++; +#if 1 + /* determine whether to write the objective row */ + out_obj = 1; + for (i = 1; i <= P->m; i++) + { if (P->row[i]->type == GLP_FR) + { out_obj = 0; + break; + } + } +#endif + /* write ROWS section */ + xfprintf(fp, "ROWS\n"), recno++; + for (i = (out_obj ? 0 : 1); i <= P->m; i++) + { int type; + type = (i == 0 ? GLP_FR : P->row[i]->type); + if (type == GLP_FR) + type = 'N'; + else if (type == GLP_LO) + type = 'G'; + else if (type == GLP_UP) + type = 'L'; + else if (type == GLP_DB || type == GLP_FX) + type = 'E'; + else + xassert(type != type); + xfprintf(fp, " %c%*s%s\n", type, csa->deck ? 2 : 1, "", + row_name(csa, i)), recno++; + } + /* write COLUMNS section */ + xfprintf(fp, "COLUMNS\n"), recno++; + marker = 0; + for (j = 1; j <= P->n; j++) + { GLPAIJ cj, *aij; + int kind; + kind = P->col[j]->kind; + if (kind == GLP_CV) + { if (marker % 2 == 1) + { /* close current integer block */ + marker++; + xfprintf(fp, "%*sM%07d%*s'MARKER'%*s'INTEND'\n", + csa->deck ? 4 : 1, "", marker, csa->deck ? 2 : 1, "", + csa->deck ? 17 : 1, ""), recno++; + } + } + else if (kind == GLP_IV) + { if (marker % 2 == 0) + { /* open new integer block */ + marker++; + xfprintf(fp, "%*sM%07d%*s'MARKER'%*s'INTORG'\n", + csa->deck ? 4 : 1, "", marker, csa->deck ? 2 : 1, "", + csa->deck ? 17 : 1, ""), recno++; + } + } + else + xassert(kind != kind); + if (out_obj && P->col[j]->coef != 0.0) + { /* make fake objective coefficient */ + aij = &cj; + aij->row = NULL; + aij->val = P->col[j]->coef; + aij->c_next = P->col[j]->ptr; + } + else + aij = P->col[j]->ptr; +#if 1 /* FIXME */ + if (aij == NULL) + { /* empty column */ + empty++; + xfprintf(fp, "%*s%-*s", csa->deck ? 4 : 1, "", + csa->deck ? 8 : 1, col_name(csa, j)); + /* we need a row */ + xassert(P->m > 0); + xfprintf(fp, "%*s%-*s", + csa->deck ? 2 : 1, "", csa->deck ? 8 : 1, + row_name(csa, 1)); + xfprintf(fp, "%*s0%*s$ empty column\n", + csa->deck ? 13 : 1, "", csa->deck ? 3 : 1, ""), recno++; + } +#endif + count = 0; + for (aij = aij; aij != NULL; aij = aij->c_next) + { if (one_col || count % 2 == 0) + xfprintf(fp, "%*s%-*s", csa->deck ? 4 : 1, "", + csa->deck ? 8 : 1, col_name(csa, j)); + gap = (one_col || count % 2 == 0 ? 2 : 3); + xfprintf(fp, "%*s%-*s", + csa->deck ? gap : 1, "", csa->deck ? 8 : 1, + row_name(csa, aij->row == NULL ? 0 : aij->row->i)); + xfprintf(fp, "%*s%*s", + csa->deck ? 2 : 1, "", csa->deck ? 12 : 1, + mps_numb(csa, aij->val)), count++; + if (one_col || count % 2 == 0) + xfprintf(fp, "\n"), recno++; + } + if (!(one_col || count % 2 == 0)) + xfprintf(fp, "\n"), recno++; + } + if (marker % 2 == 1) + { /* close last integer block */ + marker++; + xfprintf(fp, "%*sM%07d%*s'MARKER'%*s'INTEND'\n", + csa->deck ? 4 : 1, "", marker, csa->deck ? 2 : 1, "", + csa->deck ? 17 : 1, ""), recno++; + } +#if 1 + if (empty > 0) + xprintf("Warning: problem has %d empty column(s)\n", empty); +#endif + /* write RHS section */ + xfprintf(fp, "RHS\n"), recno++; + count = 0; + for (i = (out_obj ? 0 : 1); i <= P->m; i++) + { int type; + double rhs; + if (i == 0) + rhs = P->c0; + else + { type = P->row[i]->type; + if (type == GLP_FR) + rhs = 0.0; + else if (type == GLP_LO) + rhs = P->row[i]->lb; + else if (type == GLP_UP) + rhs = P->row[i]->ub; + else if (type == GLP_DB || type == GLP_FX) + rhs = P->row[i]->lb; + else + xassert(type != type); + } + if (rhs != 0.0) + { if (one_col || count % 2 == 0) + xfprintf(fp, "%*s%-*s", csa->deck ? 4 : 1, "", + csa->deck ? 8 : 1, "RHS1"); + gap = (one_col || count % 2 == 0 ? 2 : 3); + xfprintf(fp, "%*s%-*s", + csa->deck ? gap : 1, "", csa->deck ? 8 : 1, + row_name(csa, i)); + xfprintf(fp, "%*s%*s", + csa->deck ? 2 : 1, "", csa->deck ? 12 : 1, + mps_numb(csa, rhs)), count++; + if (one_col || count % 2 == 0) + xfprintf(fp, "\n"), recno++; + } + } + if (!(one_col || count % 2 == 0)) + xfprintf(fp, "\n"), recno++; + /* write RANGES section */ + for (i = P->m; i >= 1; i--) + if (P->row[i]->type == GLP_DB) break; + if (i == 0) goto bnds; + xfprintf(fp, "RANGES\n"), recno++; + count = 0; + for (i = 1; i <= P->m; i++) + { if (P->row[i]->type == GLP_DB) + { if (one_col || count % 2 == 0) + xfprintf(fp, "%*s%-*s", csa->deck ? 4 : 1, "", + csa->deck ? 8 : 1, "RNG1"); + gap = (one_col || count % 2 == 0 ? 2 : 3); + xfprintf(fp, "%*s%-*s", + csa->deck ? gap : 1, "", csa->deck ? 8 : 1, + row_name(csa, i)); + xfprintf(fp, "%*s%*s", + csa->deck ? 2 : 1, "", csa->deck ? 12 : 1, + mps_numb(csa, P->row[i]->ub - P->row[i]->lb)), count++; + if (one_col || count % 2 == 0) + xfprintf(fp, "\n"), recno++; + } + } + if (!(one_col || count % 2 == 0)) + xfprintf(fp, "\n"), recno++; +bnds: /* write BOUNDS section */ + for (j = P->n; j >= 1; j--) + if (!(P->col[j]->kind == GLP_CV && + P->col[j]->type == GLP_LO && P->col[j]->lb == 0.0)) + break; + if (j == 0) goto endt; + xfprintf(fp, "BOUNDS\n"), recno++; + for (j = 1; j <= P->n; j++) + { int type, data[2]; + double bnd[2]; + char *spec[2]; + spec[0] = spec[1] = NULL; + type = P->col[j]->type; + if (type == GLP_FR) + spec[0] = "FR", data[0] = 0; + else if (type == GLP_LO) + { if (P->col[j]->lb != 0.0) + spec[0] = "LO", data[0] = 1, bnd[0] = P->col[j]->lb; + if (P->col[j]->kind == GLP_IV) + spec[1] = "PL", data[1] = 0; + } + else if (type == GLP_UP) + { spec[0] = "MI", data[0] = 0; + spec[1] = "UP", data[1] = 1, bnd[1] = P->col[j]->ub; + } + else if (type == GLP_DB) + { if (P->col[j]->lb != 0.0) + spec[0] = "LO", data[0] = 1, bnd[0] = P->col[j]->lb; + spec[1] = "UP", data[1] = 1, bnd[1] = P->col[j]->ub; + } + else if (type == GLP_FX) + spec[0] = "FX", data[0] = 1, bnd[0] = P->col[j]->lb; + else + xassert(type != type); + for (i = 0; i <= 1; i++) + { if (spec[i] != NULL) + { xfprintf(fp, " %s %-*s%*s%-*s", spec[i], + csa->deck ? 8 : 1, "BND1", csa->deck ? 2 : 1, "", + csa->deck ? 8 : 1, col_name(csa, j)); + if (data[i]) + xfprintf(fp, "%*s%*s", csa->deck ? 2 : 1, "", + csa->deck ? 12 : 1, mps_numb(csa, bnd[i])); + xfprintf(fp, "\n"), recno++; + } + } + } +endt: /* write ENDATA indicator record */ + xfprintf(fp, "ENDATA\n"), recno++; +#if 0 /* FIXME */ + xfflush(fp); +#endif + if (glp_ioerr(fp)) + { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); + ret = 1; + goto done; + } + /* problem data has been successfully written */ + xprintf("%d records were written\n", recno); + ret = 0; +done: if (fp != NULL) glp_close(fp); + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpnet03.c b/resources/3rdparty/glpk-4.57/src/glpnet03.c new file mode 100644 index 000000000..9ddf1cb75 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpnet03.c @@ -0,0 +1,1020 @@ +/* glpnet03.c (Klingman's network problem generator) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* This code is the result of translation of the Fortran program NETGEN +* developed by Dr. Darwin Klingman, which is publically available from +* NETLIB at . +* +* The translation was made by Andrew Makhorin . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpk.h" + +/*********************************************************************** +* NAME +* +* glp_netgen - Klingman's network problem generator +* +* SYNOPSIS +* +* int glp_netgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, +* const int parm[1+15]); +* +* DESCRIPTION +* +* The routine glp_netgen is a network problem generator developed by +* Dr. Darwin Klingman. It can create capacitated and uncapacitated +* minimum cost flow (or transshipment), transportation, and assignment +* problems. +* +* The parameter G specifies the graph object, to which the generated +* problem data have to be stored. Note that on entry the graph object +* is erased with the routine glp_erase_graph. +* +* The parameter v_rhs specifies an offset of the field of type double +* in the vertex data block, to which the routine stores the supply or +* demand value. If v_rhs < 0, the value is not stored. +* +* The parameter a_cap specifies an offset of the field of type double +* in the arc data block, to which the routine stores the arc capacity. +* If a_cap < 0, the capacity is not stored. +* +* The parameter a_cost specifies an offset of the field of type double +* in the arc data block, to which the routine stores the per-unit cost +* if the arc flow. If a_cost < 0, the cost is not stored. +* +* The array parm contains description of the network to be generated: +* +* parm[0] not used +* parm[1] (iseed) 8-digit positive random number seed +* parm[2] (nprob) 8-digit problem id number +* parm[3] (nodes) total number of nodes +* parm[4] (nsorc) total number of source nodes (including +* transshipment nodes) +* parm[5] (nsink) total number of sink nodes (including +* transshipment nodes) +* parm[6] (iarcs) number of arcs +* parm[7] (mincst) minimum cost for arcs +* parm[8] (maxcst) maximum cost for arcs +* parm[9] (itsup) total supply +* parm[10] (ntsorc) number of transshipment source nodes +* parm[11] (ntsink) number of transshipment sink nodes +* parm[12] (iphic) percentage of skeleton arcs to be given +* the maximum cost +* parm[13] (ipcap) percentage of arcs to be capacitated +* parm[14] (mincap) minimum upper bound for capacitated arcs +* parm[15] (maxcap) maximum upper bound for capacitated arcs +* +* The routine generates a transportation problem if: +* +* nsorc + nsink = nodes, ntsorc = 0, and ntsink = 0. +* +* The routine generates an assignment problem if the requirements for +* a transportation problem are met and: +* +* nsorc = nsink and itsup = nsorc. +* +* RETURNS +* +* If the instance was successfully generated, the routine glp_netgen +* returns zero; otherwise, if specified parameters are inconsistent, +* the routine returns a non-zero error code. +* +* REFERENCES +* +* D.Klingman, A.Napier, and J.Stutz. NETGEN: A program for generating +* large scale capacitated assignment, transportation, and minimum cost +* flow networks. Management Science 20 (1974), 814-20. */ + +struct csa +{ /* common storage area */ + glp_graph *G; + int v_rhs, a_cap, a_cost; + int nodes, iarcs, mincst, maxcst, itsup, nsorc, nsink, nonsor, + nfsink, narcs, nsort, nftsor, ipcap, mincap, maxcap, ktl, + nodlft, *ipred, *ihead, *itail, *iflag, *isup, *lsinks, mult, + modul, i15, i16, jran; +}; + +#define G (csa->G) +#define v_rhs (csa->v_rhs) +#define a_cap (csa->a_cap) +#define a_cost (csa->a_cost) +#define nodes (csa->nodes) +#define iarcs (csa->iarcs) +#define mincst (csa->mincst) +#define maxcst (csa->maxcst) +#define itsup (csa->itsup) +#define nsorc (csa->nsorc) +#define nsink (csa->nsink) +#define nonsor (csa->nonsor) +#define nfsink (csa->nfsink) +#define narcs (csa->narcs) +#define nsort (csa->nsort) +#define nftsor (csa->nftsor) +#define ipcap (csa->ipcap) +#define mincap (csa->mincap) +#define maxcap (csa->maxcap) +#define ktl (csa->ktl) +#define nodlft (csa->nodlft) +#if 0 +/* spent a day to find out this bug */ +#define ist (csa->ist) +#else +#define ist (ipred[0]) +#endif +#define ipred (csa->ipred) +#define ihead (csa->ihead) +#define itail (csa->itail) +#define iflag (csa->iflag) +#define isup (csa->isup) +#define lsinks (csa->lsinks) +#define mult (csa->mult) +#define modul (csa->modul) +#define i15 (csa->i15) +#define i16 (csa->i16) +#define jran (csa->jran) + +static void cresup(struct csa *csa); +static void chain(struct csa *csa, int lpick, int lsorc); +static void chnarc(struct csa *csa, int lsorc); +static void sort(struct csa *csa); +static void pickj(struct csa *csa, int it); +static void assign(struct csa *csa); +static void setran(struct csa *csa, int iseed); +static int iran(struct csa *csa, int ilow, int ihigh); + +int glp_netgen(glp_graph *G_, int _v_rhs, int _a_cap, int _a_cost, + const int parm[1+15]) +{ struct csa _csa, *csa = &_csa; + int iseed, nprob, ntsorc, ntsink, iphic, i, nskel, nltr, ltsink, + ntrans, npsink, nftr, npsorc, ntravl, ntrrem, lsorc, lpick, + nsksr, nsrchn, j, item, l, ks, k, ksp, li, n, ii, it, ih, icap, + jcap, icost, jcost, ret; + G = G_; + v_rhs = _v_rhs; + a_cap = _a_cap; + a_cost = _a_cost; + if (G != NULL) + { if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) + xerror("glp_netgen: v_rhs = %d; invalid offset\n", v_rhs); + if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) + xerror("glp_netgen: a_cap = %d; invalid offset\n", a_cap); + if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) + xerror("glp_netgen: a_cost = %d; invalid offset\n", a_cost); + } + /* Input the user's random number seed and fix it if + non-positive. */ + iseed = parm[1]; + nprob = parm[2]; + if (iseed <= 0) iseed = 13502460; + setran(csa, iseed); + /* Input the user's problem characteristics. */ + nodes = parm[3]; + nsorc = parm[4]; + nsink = parm[5]; + iarcs = parm[6]; + mincst = parm[7]; + maxcst = parm[8]; + itsup = parm[9]; + ntsorc = parm[10]; + ntsink = parm[11]; + iphic = parm[12]; + ipcap = parm[13]; + mincap = parm[14]; + maxcap = parm[15]; + /* Check the size of the problem. */ + if (!(10 <= nodes && nodes <= 100000)) + { ret = 1; + goto done; + } + /* Check user supplied parameters for consistency. */ + if (!(nsorc >= 0 && nsink >= 0 && nsorc + nsink <= nodes)) + { ret = 2; + goto done; + } + if (iarcs < 0) + { ret = 3; + goto done; + } + if (mincst > maxcst) + { ret = 4; + goto done; + } + if (itsup < 0) + { ret = 5; + goto done; + } + if (!(0 <= ntsorc && ntsorc <= nsorc)) + { ret = 6; + goto done; + } + if (!(0 <= ntsink && ntsink <= nsink)) + { ret = 7; + goto done; + } + if (!(0 <= iphic && iphic <= 100)) + { ret = 8; + goto done; + } + if (!(0 <= ipcap && ipcap <= 100)) + { ret = 9; + goto done; + } + if (mincap > maxcap) + { ret = 10; + goto done; + } + /* Initailize the graph object. */ + if (G != NULL) + { glp_erase_graph(G, G->v_size, G->a_size); + glp_add_vertices(G, nodes); + if (v_rhs >= 0) + { double zero = 0.0; + for (i = 1; i <= nodes; i++) + { glp_vertex *v = G->v[i]; + memcpy((char *)v->data + v_rhs, &zero, sizeof(double)); + } + } + } + /* Allocate working arrays. */ + ipred = xcalloc(1+nodes, sizeof(int)); + ihead = xcalloc(1+nodes, sizeof(int)); + itail = xcalloc(1+nodes, sizeof(int)); + iflag = xcalloc(1+nodes, sizeof(int)); + isup = xcalloc(1+nodes, sizeof(int)); + lsinks = xcalloc(1+nodes, sizeof(int)); + /* Print the problem documentation records. */ + if (G == NULL) + { xprintf("BEGIN\n"); + xprintf("NETGEN PROBLEM%8d%10s%10d NODES AND%10d ARCS\n", + nprob, "", nodes, iarcs); + xprintf("USER:%11d%11d%11d%11d%11d%11d\nDATA:%11d%11d%11d%11d%" + "11d%11d\n", iseed, nsorc, nsink, mincst, + maxcst, itsup, ntsorc, ntsink, iphic, ipcap, + mincap, maxcap); + } + else + glp_set_graph_name(G, "NETGEN"); + /* Set various constants used in the program. */ + narcs = 0; + nskel = 0; + nltr = nodes - nsink; + ltsink = nltr + ntsink; + ntrans = nltr - nsorc; + nfsink = nltr + 1; + nonsor = nodes - nsorc + ntsorc; + npsink = nsink - ntsink; + nodlft = nodes - nsink + ntsink; + nftr = nsorc + 1; + nftsor = nsorc - ntsorc + 1; + npsorc = nsorc - ntsorc; + /* Randomly distribute the supply among the source nodes. */ + if (npsorc + npsink == nodes && npsorc == npsink && + itsup == nsorc) + { assign(csa); + nskel = nsorc; + goto L390; + } + cresup(csa); + /* Print the supply records. */ + if (G == NULL) + { xprintf("SUPPLY\n"); + for (i = 1; i <= nsorc; i++) + xprintf("%6s%6d%18s%10d\n", "", i, "", isup[i]); + xprintf("ARCS\n"); + } + else + { if (v_rhs >= 0) + { for (i = 1; i <= nsorc; i++) + { double temp = (double)isup[i]; + glp_vertex *v = G->v[i]; + memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); + } + } + } + /* Make the sources point to themselves in ipred array. */ + for (i = 1; i <= nsorc; i++) + ipred[i] = i; + if (ntrans == 0) goto L170; + /* Chain the transshipment nodes together in the ipred array. */ + ist = nftr; + ipred[nltr] = 0; + for (i = nftr; i < nltr; i++) + ipred[i] = i+1; + /* Form even length chains for 60 percent of the transshipments.*/ + ntravl = 6 * ntrans / 10; + ntrrem = ntrans - ntravl; +L140: lsorc = 1; + while (ntravl != 0) + { lpick = iran(csa, 1, ntravl + ntrrem); + ntravl--; + chain(csa, lpick, lsorc); + if (lsorc == nsorc) goto L140; + lsorc++; + } + /* Add the remaining transshipments to the chains. */ + while (ntrrem != 0) + { + lpick = iran(csa, 1, ntrrem); + ntrrem--; + lsorc = iran(csa, 1, nsorc); + chain(csa, lpick, lsorc); + } +L170: /* Set all demands equal to zero. */ + for (i = nfsink; i <= nodes; i++) + ipred[i] = 0; + /* The following loop takes one chain at a time (through the use + of logic contained in the loop and calls to other routines) and + creates the remaining network arcs. */ + for (lsorc = 1; lsorc <= nsorc; lsorc++) + { chnarc(csa, lsorc); + for (i = nfsink; i <= nodes; i++) + iflag[i] = 0; + /* Choose the number of sinks to be hooked up to the current + chain. */ + if (ntrans != 0) + nsksr = (nsort * 2 * nsink) / ntrans; + else + nsksr = nsink / nsorc + 1; + if (nsksr < 2) nsksr = 2; + if (nsksr > nsink) nsksr = nsink; + nsrchn = nsort; + /* Randomly pick nsksr sinks and put their names in lsinks. */ + ktl = nsink; + for (j = 1; j <= nsksr; j++) + { item = iran(csa, 1, ktl); + ktl--; + for (l = nfsink; l <= nodes; l++) + { if (iflag[l] != 1) + { item--; + if (item == 0) goto L230; + } + } + break; +L230: lsinks[j] = l; + iflag[l] = 1; + } + /* If last source chain, add all sinks with zero demand to + lsinks list. */ + if (lsorc == nsorc) + { for (j = nfsink; j <= nodes; j++) + { if (ipred[j] == 0 && iflag[j] != 1) + { nsksr++; + lsinks[nsksr] = j; + iflag[j] = 1; + } + } + } + /* Create demands for group of sinks in lsinks. */ + ks = isup[lsorc] / nsksr; + k = ipred[lsorc]; + for (i = 1; i <= nsksr; i++) + { nsort++; + ksp = iran(csa, 1, ks); + j = iran(csa, 1, nsksr); + itail[nsort] = k; + li = lsinks[i]; + ihead[nsort] = li; + ipred[li] += ksp; + li = lsinks[j]; + ipred[li] += ks - ksp; + n = iran(csa, 1, nsrchn); + k = lsorc; + for (ii = 1; ii <= n; ii++) + k = ipred[k]; + } + li = lsinks[1]; + ipred[li] += isup[lsorc] - ks * nsksr; + nskel += nsort; + /* Sort the arcs in the chain from source lsorc using itail as + sort key. */ + sort(csa); + /* Print this part of skeleton and create the arcs for these + nodes. */ + i = 1; + itail[nsort+1] = 0; +L300: for (j = nftsor; j <= nodes; j++) + iflag[j] = 0; + ktl = nonsor - 1; + it = itail[i]; + iflag[it] = 1; +L320: ih = ihead[i]; + iflag[ih] = 1; + narcs++; + ktl--; + /* Determine if this skeleton arc should be capacitated. */ + icap = itsup; + jcap = iran(csa, 1, 100); + if (jcap <= ipcap) + { icap = isup[lsorc]; + if (mincap > icap) icap = mincap; + } + /* Determine if this skeleton arc should have the maximum + cost. */ + icost = maxcst; + jcost = iran(csa, 1, 100); + if (jcost > iphic) + icost = iran(csa, mincst, maxcst); + if (G == NULL) + xprintf("%6s%6d%6d%2s%10d%10d\n", "", it, ih, "", icost, + icap); + else + { glp_arc *a = glp_add_arc(G, it, ih); + if (a_cap >= 0) + { double temp = (double)icap; + memcpy((char *)a->data + a_cap, &temp, sizeof(double)); + } + if (a_cost >= 0) + { double temp = (double)icost; + memcpy((char *)a->data + a_cost, &temp, sizeof(double)); + } + } + i++; + if (itail[i] == it) goto L320; + pickj(csa, it); + if (i <= nsort) goto L300; + } + /* Create arcs from the transshipment sinks. */ + if (ntsink != 0) + { for (i = nfsink; i <= ltsink; i++) + { for (j = nftsor; j <= nodes; j++) + iflag[j] = 0; + ktl = nonsor - 1; + iflag[i] = 1; + pickj(csa, i); + } + } +L390: /* Print the demand records and end record. */ + if (G == NULL) + { xprintf("DEMAND\n"); + for (i = nfsink; i <= nodes; i++) + xprintf("%6s%6d%18s%10d\n", "", i, "", ipred[i]); + xprintf("END\n"); + } + else + { if (v_rhs >= 0) + { for (i = nfsink; i <= nodes; i++) + { double temp = - (double)ipred[i]; + glp_vertex *v = G->v[i]; + memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); + } + } + } + /* Free working arrays. */ + xfree(ipred); + xfree(ihead); + xfree(itail); + xfree(iflag); + xfree(isup); + xfree(lsinks); + /* The instance has been successfully generated. */ + ret = 0; +done: return ret; +} + +/*********************************************************************** +* The routine cresup randomly distributes the total supply among the +* source nodes. */ + +static void cresup(struct csa *csa) +{ int i, j, ks, ksp; + xassert(itsup > nsorc); + ks = itsup / nsorc; + for (i = 1; i <= nsorc; i++) + isup[i] = 0; + for (i = 1; i <= nsorc; i++) + { ksp = iran(csa, 1, ks); + j = iran(csa, 1, nsorc); + isup[i] += ksp; + isup[j] += ks - ksp; + } + j = iran(csa, 1, nsorc); + isup[j] += itsup - ks * nsorc; + return; +} + +/*********************************************************************** +* The routine chain adds node lpick to the end of the chain with source +* node lsorc. */ + +static void chain(struct csa *csa, int lpick, int lsorc) +{ int i, j, k, l, m; + k = 0; + m = ist; + for (i = 1; i <= lpick; i++) + { l = k; + k = m; + m = ipred[k]; + } + ipred[l] = m; + j = ipred[lsorc]; + ipred[k] = j; + ipred[lsorc] = k; + return; +} + +/*********************************************************************** +* The routine chnarc puts the arcs in the chain from source lsorc into +* the ihead and itail arrays for sorting. */ + +static void chnarc(struct csa *csa, int lsorc) +{ int ito, ifrom; + nsort = 0; + ito = ipred[lsorc]; +L10: if (ito == lsorc) return; + nsort++; + ifrom = ipred[ito]; + ihead[nsort] = ito; + itail[nsort] = ifrom; + ito = ifrom; + goto L10; +} + +/*********************************************************************** +* The routine sort sorts the nsort arcs in the ihead and itail arrays. +* ihead is used as the sort key (i.e. forward star sort order). */ + +static void sort(struct csa *csa) +{ int i, j, k, l, m, n, it; + n = nsort; + m = n; +L10: m /= 2; + if (m == 0) return; + k = n - m; + j = 1; +L20: i = j; +L30: l = i + m; + if (itail[i] <= itail[l]) goto L40; + it = itail[i]; + itail[i] = itail[l]; + itail[l] = it; + it = ihead[i]; + ihead[i] = ihead[l]; + ihead[l] = it; + i -= m; + if (i >= 1) goto L30; +L40: j++; + if (j <= k) goto L20; + goto L10; +} + +/*********************************************************************** +* The routine pickj creates a random number of arcs out of node 'it'. +* Various parameters are dynamically adjusted in an attempt to ensure +* that the generated network has the correct number of arcs. */ + +static void pickj(struct csa *csa, int it) +{ int j, k, l, nn, nupbnd, icap, jcap, icost; + if ((nodlft - 1) * 2 > iarcs - narcs - 1) + { nodlft--; + return; + } + if ((iarcs - narcs + nonsor - ktl - 1) / nodlft - nonsor + 1 >= 0) + k = nonsor; + else + { nupbnd = (iarcs - narcs - nodlft) / nodlft * 2; +L40: k = iran(csa, 1, nupbnd); + if (nodlft == 1) k = iarcs - narcs; + if ((nodlft - 1) * (nonsor - 1) < iarcs - narcs - k) goto L40; + } + nodlft--; + for (j = 1; j <= k; j++) + { nn = iran(csa, 1, ktl); + ktl--; + for (l = nftsor; l <= nodes; l++) + { if (iflag[l] != 1) + { nn--; + if (nn == 0) goto L70; + } + } + return; +L70: iflag[l] = 1; + icap = itsup; + jcap = iran(csa, 1, 100); + if (jcap <= ipcap) + icap = iran(csa, mincap, maxcap); + icost = iran(csa, mincst, maxcst); + if (G == NULL) + xprintf("%6s%6d%6d%2s%10d%10d\n", "", it, l, "", icost, + icap); + else + { glp_arc *a = glp_add_arc(G, it, l); + if (a_cap >= 0) + { double temp = (double)icap; + memcpy((char *)a->data + a_cap, &temp, sizeof(double)); + } + if (a_cost >= 0) + { double temp = (double)icost; + memcpy((char *)a->data + a_cost, &temp, sizeof(double)); + } + } + narcs++; + } + return; +} + +/*********************************************************************** +* The routine assign generate assignment problems. It defines the unit +* supplies, builds a skeleton, then calls pickj to create the arcs. */ + +static void assign(struct csa *csa) +{ int i, it, nn, l, ll, icost; + if (G == NULL) + xprintf("SUPPLY\n"); + for (i = 1; i <= nsorc; i++) + { isup[i] = 1; + iflag[i] = 0; + if (G == NULL) + xprintf("%6s%6d%18s%10d\n", "", i, "", isup[i]); + else + { if (v_rhs >= 0) + { double temp = (double)isup[i]; + glp_vertex *v = G->v[i]; + memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); + } + } + } + if (G == NULL) + xprintf("ARCS\n"); + for (i = nfsink; i <= nodes; i++) + ipred[i] = 1; + for (it = 1; it <= nsorc; it++) + { for (i = nfsink; i <= nodes; i++) + iflag[i] = 0; + ktl = nsink - 1; + nn = iran(csa, 1, nsink - it + 1); + for (l = 1; l <= nsorc; l++) + { if (iflag[l] != 1) + { nn--; + if (nn == 0) break; + } + } + narcs++; + ll = nsorc + l; + icost = iran(csa, mincst, maxcst); + if (G == NULL) + xprintf("%6s%6d%6d%2s%10d%10d\n", "", it, ll, "", icost, + isup[1]); + else + { glp_arc *a = glp_add_arc(G, it, ll); + if (a_cap >= 0) + { double temp = (double)isup[1]; + memcpy((char *)a->data + a_cap, &temp, sizeof(double)); + } + if (a_cost >= 0) + { double temp = (double)icost; + memcpy((char *)a->data + a_cost, &temp, sizeof(double)); + } + } + iflag[l] = 1; + iflag[ll] = 1; + pickj(csa, it); + } + return; +} + +/*********************************************************************** +* Portable congruential (uniform) random number generator: +* +* next_value = ((7**5) * previous_value) modulo ((2**31)-1) +* +* This generator consists of three routines: +* +* (1) setran - initializes constants and seed +* (2) iran - generates an integer random number +* (3) rran - generates a real random number +* +* The generator requires a machine with at least 32 bits of precision. +* The seed (iseed) must be in the range [1,(2**31)-1]. */ + +static void setran(struct csa *csa, int iseed) +{ xassert(iseed >= 1); + mult = 16807; + modul = 2147483647; + i15 = 1 << 15; + i16 = 1 << 16; + jran = iseed; + return; +} + +/*********************************************************************** +* The routine iran generates an integer random number between ilow and +* ihigh. If ilow > ihigh then iran returns ihigh. */ + +static int iran(struct csa *csa, int ilow, int ihigh) +{ int ixhi, ixlo, ixalo, leftlo, ixahi, ifulhi, irtlo, iover, + irthi, j; + ixhi = jran / i16; + ixlo = jran - ixhi * i16; + ixalo = ixlo * mult; + leftlo = ixalo / i16; + ixahi = ixhi * mult; + ifulhi = ixahi + leftlo; + irtlo = ixalo - leftlo * i16; + iover = ifulhi / i15; + irthi = ifulhi - iover * i15; + jran = ((irtlo - modul) + irthi * i16) + iover; + if (jran < 0) jran += modul; + j = ihigh - ilow + 1; + if (j > 0) + return jran % j + ilow; + else + return ihigh; +} + +/*********************************************************************** +* NAME +* +* glp_netgen_prob - Klingman's standard network problem instance +* +* SYNOPSIS +* +* void glp_netgen_prob(int nprob, int parm[1+15]); +* +* DESCRIPTION +* +* The routine glp_netgen_prob provides the set of parameters for +* Klingman's network problem generator (see the routine glp_netgen), +* which describe a standard network problem instance. +* +* The parameter nprob (101 <= nprob <= 150) specifies the problem +* instance number. +* +* The array parm contains description of the network, provided by the +* routine. (For detailed description of these parameters see comments +* to the routine glp_netgen.) +* +* PROBLEM CHARACTERISTICS +* +* The table below shows characteristics of Klingman's standard network +* problem instances. +* +* Problem Nodes Arcs Optimum +* ------- ----- ----- ---------- +* 101 5000 25336 6191726 +* 102 5000 25387 72337144 +* 103 5000 25355 218947553 +* 104 5000 25344 -19100371 +* 105 5000 25332 31192578 +* 106 5000 12870 4314276 +* 107 5000 37832 7393769 +* 108 5000 50309 8405738 +* 109 5000 75299 9190300 +* 110 5000 12825 8975048 +* 111 5000 37828 4747532 +* 112 5000 50325 4012671 +* 113 5000 75318 2979725 +* 114 5000 26514 5821181 +* 115 5000 25962 6353310 +* 116 5000 25304 5915426 +* 117 5000 12816 4420560 +* 118 5000 37797 7045842 +* 119 5000 50301 7724179 +* 120 5000 75330 8455200 +* 121 5000 25000 66366360 +* 122 5000 25000 30997529 +* 123 5000 25000 23388777 +* 124 5000 25000 17803443 +* 125 5000 25000 14119622 +* 126 5000 12500 18802218 +* 127 5000 37500 27674647 +* 128 5000 50000 30906194 +* 129 5000 75000 40905209 +* 130 5000 12500 38939608 +* 131 5000 37500 16752978 +* 132 5000 50000 13302951 +* 133 5000 75000 9830268 +* 134 1000 25000 3804874 +* 135 2500 25000 11729616 +* 136 7500 25000 33318101 +* 137 10000 25000 46426030 +* 138 5000 25000 60710879 +* 139 5000 25000 32729682 +* 140 5000 25000 27183831 +* 141 5000 25000 19963286 +* 142 5000 25000 20243457 +* 143 5000 25000 18586777 +* 144 5000 25000 2504591 +* 145 5000 25000 215956138 +* 146 5000 25000 2253113811 +* 147 5000 25000 -427908373 +* 148 5000 25000 -92965318 +* 149 5000 25000 86051224 +* 150 5000 25000 619314919 */ + +static const int data[50][1+15] = +{ { 0, 13502460, 101, 5000, 2500, 2500, 25000, + 1, 100, 250000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 4281922, 102, 5000, 2500, 2500, 25000, + 1, 100, 2500000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 44820113, 103, 5000, 2500, 2500, 25000, + 1, 100, 6250000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 13450451, 104, 5000, 2500, 2500, 25000, + -100, -1, 250000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 14719436, 105, 5000, 2500, 2500, 25000, + 101, 200, 250000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 17365786, 106, 5000, 2500, 2500, 12500, + 1, 100, 125000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 19540113, 107, 5000, 2500, 2500, 37500, + 1, 100, 375000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 19560313, 108, 5000, 2500, 2500, 50000, + 1, 100, 500000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 2403509, 109, 5000, 2500, 2500, 75000, + 1, 100, 750000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 92480414, 110, 5000, 2500, 2500, 12500, + 1, 100, 250000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 4230140, 111, 5000, 2500, 2500, 37500, + 1, 100, 250000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 10032490, 112, 5000, 2500, 2500, 50000, + 1, 100, 250000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 17307474, 113, 5000, 2500, 2500, 75000, + 1, 100, 250000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 4925114, 114, 5000, 500, 4500, 25000, + 1, 100, 250000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 19842704, 115, 5000, 1500, 3500, 25000, + 1, 100, 250000, 0, 0, 0, 100, 1, 1000 + }, + { 0, 88392060, 116, 5000, 2500, 2500, 25000, + 1, 100, 250000, 0, 0, 0, 0, 1, 1000 + }, + { 0, 12904407, 117, 5000, 2500, 2500, 12500, + 1, 100, 125000, 0, 0, 0, 0, 1, 1000 + }, + { 0, 11811811, 118, 5000, 2500, 2500, 37500, + 1, 100, 375000, 0, 0, 0, 0, 1, 1000 + }, + { 0, 90023593, 119, 5000, 2500, 2500, 50000, + 1, 100, 500000, 0, 0, 0, 0, 1, 1000 + }, + { 0, 93028922, 120, 5000, 2500, 2500, 75000, + 1, 100, 750000, 0, 0, 0, 0, 1, 1000 + }, + { 0, 72707401, 121, 5000, 50, 50, 25000, + 1, 100, 250000, 50, 50, 0, 100, 1, 1000 + }, + { 0, 93040771, 122, 5000, 250, 250, 25000, + 1, 100, 250000, 250, 250, 0, 100, 1, 1000 + }, + { 0, 70220611, 123, 5000, 500, 500, 25000, + 1, 100, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 52774811, 124, 5000, 1000, 1000, 25000, + 1, 100, 250000, 1000, 1000, 0, 100, 1, 1000 + }, + { 0, 22492311, 125, 5000, 1500, 1500, 25000, + 1, 100, 250000, 1500, 1500, 0, 100, 1, 1000 + }, + { 0, 35269337, 126, 5000, 500, 500, 12500, + 1, 100, 125000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 30140502, 127, 5000, 500, 500, 37500, + 1, 100, 375000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 49205455, 128, 5000, 500, 500, 50000, + 1, 100, 500000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 42958341, 129, 5000, 500, 500, 75000, + 1, 100, 750000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 25440925, 130, 5000, 500, 500, 12500, + 1, 100, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 75294924, 131, 5000, 500, 500, 37500, + 1, 100, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 4463965, 132, 5000, 500, 500, 50000, + 1, 100, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 13390427, 133, 5000, 500, 500, 75000, + 1, 100, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 95250971, 134, 1000, 500, 500, 25000, + 1, 100, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 54830522, 135, 2500, 500, 500, 25000, + 1, 100, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 520593, 136, 7500, 500, 500, 25000, + 1, 100, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 52900925, 137, 10000, 500, 500, 25000, + 1, 100, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 22603395, 138, 5000, 500, 500, 25000, + 1, 100, 250000, 500, 500, 0, 100, 1, 50 + }, + { 0, 55253099, 139, 5000, 500, 500, 25000, + 1, 100, 250000, 500, 500, 0, 100, 1, 250 + }, + { 0, 75357001, 140, 5000, 500, 500, 25000, + 1, 100, 250000, 500, 500, 0, 100, 1, 500 + }, + { 0, 10072459, 141, 5000, 500, 500, 25000, + 1, 100, 250000, 500, 500, 0, 100, 1, 2500 + }, + { 0, 55728492, 142, 5000, 500, 500, 25000, + 1, 100, 250000, 500, 500, 0, 100, 1, 5000 + }, + { 0, 593043, 143, 5000, 500, 500, 25000, + 1, 100, 250000, 500, 500, 0, 0, 1, 1000 + }, + { 0, 94236572, 144, 5000, 500, 500, 25000, + 1, 10, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 94882955, 145, 5000, 500, 500, 25000, + 1, 1000, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 48489922, 146, 5000, 500, 500, 25000, + 1, 10000, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 75578374, 147, 5000, 500, 500, 25000, + -100, -1, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 44821152, 148, 5000, 500, 500, 25000, + -50, 49, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 45224103, 149, 5000, 500, 500, 25000, + 101, 200, 250000, 500, 500, 0, 100, 1, 1000 + }, + { 0, 63491741, 150, 5000, 500, 500, 25000, + 1001, 1100, 250000, 500, 500, 0, 100, 1, 1000 + }, +}; + +void glp_netgen_prob(int nprob, int parm[1+15]) +{ int k; + if (!(101 <= nprob && nprob <= 150)) + xerror("glp_netgen_prob: nprob = %d; invalid problem instance " + "number\n", nprob); + for (k = 1; k <= 15; k++) + parm[k] = data[nprob-101][k]; + return; +} + +/**********************************************************************/ + +#if 0 +static int scan(char card[80+1], int pos, int len) +{ char buf[10+1]; + memcpy(buf, &card[pos-1], len); + buf[len] = '\0'; + return atoi(buf); +} + +int main(void) +{ int parm[1+15]; + char card[80+1]; + xassert(fgets(card, sizeof(card), stdin) == card); + parm[1] = scan(card, 1, 8); + parm[2] = scan(card, 9, 8); + xassert(fgets(card, sizeof(card), stdin) == card); + parm[3] = scan(card, 1, 5); + parm[4] = scan(card, 6, 5); + parm[5] = scan(card, 11, 5); + parm[6] = scan(card, 16, 5); + parm[7] = scan(card, 21, 5); + parm[8] = scan(card, 26, 5); + parm[9] = scan(card, 31, 10); + parm[10] = scan(card, 41, 5); + parm[11] = scan(card, 46, 5); + parm[12] = scan(card, 51, 5); + parm[13] = scan(card, 56, 5); + parm[14] = scan(card, 61, 10); + parm[15] = scan(card, 71, 10); + glp_netgen(NULL, 0, 0, 0, parm); + return 0; +} +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpnet04.c b/resources/3rdparty/glpk-4.57/src/glpnet04.c new file mode 100644 index 000000000..391392878 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpnet04.c @@ -0,0 +1,769 @@ +/* glpnet04.c (grid-like network problem generator) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* This code is a modified version of the program GRIDGEN, a grid-like +* network problem generator developed by Yusin Lee and Jim Orlin. +* The original code is publically available on the DIMACS ftp site at: +* . +* +* All changes concern only the program interface, so this modified +* version produces exactly the same instances as the original version. +* +* Changes were made by Andrew Makhorin . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpk.h" + +/*********************************************************************** +* NAME +* +* glp_gridgen - grid-like network problem generator +* +* SYNOPSIS +* +* int glp_gridgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, +* const int parm[1+14]); +* +* DESCRIPTION +* +* The routine glp_gridgen is a grid-like network problem generator +* developed by Yusin Lee and Jim Orlin. +* +* The parameter G specifies the graph object, to which the generated +* problem data have to be stored. Note that on entry the graph object +* is erased with the routine glp_erase_graph. +* +* The parameter v_rhs specifies an offset of the field of type double +* in the vertex data block, to which the routine stores the supply or +* demand value. If v_rhs < 0, the value is not stored. +* +* The parameter a_cap specifies an offset of the field of type double +* in the arc data block, to which the routine stores the arc capacity. +* If a_cap < 0, the capacity is not stored. +* +* The parameter a_cost specifies an offset of the field of type double +* in the arc data block, to which the routine stores the per-unit cost +* if the arc flow. If a_cost < 0, the cost is not stored. +* +* The array parm contains description of the network to be generated: +* +* parm[0] not used +* parm[1] two-ways arcs indicator: +* 1 - if links in both direction should be generated +* 0 - otherwise +* parm[2] random number seed (a positive integer) +* parm[3] number of nodes (the number of nodes generated might be +* slightly different to make the network a grid) +* parm[4] grid width +* parm[5] number of sources +* parm[6] number of sinks +* parm[7] average degree +* parm[8] total flow +* parm[9] distribution of arc costs: +* 1 - uniform +* 2 - exponential +* parm[10] lower bound for arc cost (uniform) +* 100 * lambda (exponential) +* parm[11] upper bound for arc cost (uniform) +* not used (exponential) +* parm[12] distribution of arc capacities: +* 1 - uniform +* 2 - exponential +* parm[13] lower bound for arc capacity (uniform) +* 100 * lambda (exponential) +* parm[14] upper bound for arc capacity (uniform) +* not used (exponential) +* +* RETURNS +* +* If the instance was successfully generated, the routine glp_gridgen +* returns zero; otherwise, if specified parameters are inconsistent, +* the routine returns a non-zero error code. +* +* COMMENTS +* +* This network generator generates a grid-like network plus a super +* node. In additional to the arcs connecting the nodes in the grid, +* there is an arc from each supply node to the super node and from the +* super node to each demand node to guarantee feasiblity. These arcs +* have very high costs and very big capacities. +* +* The idea of this network generator is as follows: First, a grid of +* n1 * n2 is generated. For example, 5 * 3. The nodes are numbered as +* 1 to 15, and the supernode is numbered as n1*n2+1. Then arcs between +* adjacent nodes are generated. For these arcs, the user is allowed to +* specify either to generate two-way arcs or one-way arcs. If two-way +* arcs are to be generated, two arcs, one in each direction, will be +* generated between each adjacent node pairs. Otherwise, only one arc +* will be generated. If this is the case, the arcs will be generated +* in alterntive directions as shown below. +* +* 1 ---> 2 ---> 3 ---> 4 ---> 5 +* | ^ | ^ | +* | | | | | +* V | V | V +* 6 <--- 7 <--- 8 <--- 9 <--- 10 +* | ^ | ^ | +* | | | | | +* V | V | V +* 11 --->12 --->13 --->14 ---> 15 +* +* Then the arcs between the super node and the source/sink nodes are +* added as mentioned before. If the number of arcs still doesn't reach +* the requirement, additional arcs will be added by uniformly picking +* random node pairs. There is no checking to prevent multiple arcs +* between any pair of nodes. However, there will be no self-arcs (arcs +* that poins back to its tail node) in the network. +* +* The source and sink nodes are selected uniformly in the network, and +* the imbalances of each source/sink node are also assigned by uniform +* distribution. */ + +struct stat_para +{ /* structure for statistical distributions */ + int distribution; + /* the distribution: */ +#define UNIFORM 1 /* uniform distribution */ +#define EXPONENTIAL 2 /* exponential distribution */ + double parameter[5]; + /* the parameters of the distribution */ +}; + +struct arcs +{ int from; + /* the FROM node of that arc */ + int to; + /* the TO node of that arc */ + int cost; + /* original cost of that arc */ + int u; + /* capacity of the arc */ +}; + +struct imbalance +{ int node; + /* Node ID */ + int supply; + /* Supply of that node */ +}; + +struct csa +{ /* common storage area */ + glp_graph *G; + int v_rhs, a_cap, a_cost; + int seed; + /* random number seed */ + int seed_original; + /* the original seed from input */ + int two_way; + /* 0: generate arcs in both direction for the basic grid, except + for the arcs to/from the super node. 1: o/w */ + int n_node; + /* total number of nodes in the network, numbered 1 to n_node, + including the super node, which is the last one */ + int n_arc; + /* total number of arcs in the network, counting EVERY arc. */ + int n_grid_arc; + /* number of arcs in the basic grid, including the arcs to/from + the super node */ + int n_source, n_sink; + /* number of source and sink nodes */ + int avg_degree; + /* average degree, arcs to and from the super node are counted */ + int t_supply; + /* total supply in the network */ + int n1, n2; + /* the two edges of the network grid. n1 >= n2 */ + struct imbalance *source_list, *sink_list; + /* head of the array of source/sink nodes */ + struct stat_para arc_costs; + /* the distribution of arc costs */ + struct stat_para capacities; + /* distribution of the capacities of the arcs */ + struct arcs *arc_list; + /* head of the arc list array. Arcs in this array are in the + order of grid_arcs, arcs to/from super node, and other arcs */ +}; + +#define G (csa->G) +#define v_rhs (csa->v_rhs) +#define a_cap (csa->a_cap) +#define a_cost (csa->a_cost) +#define seed (csa->seed) +#define seed_original (csa->seed_original) +#define two_way (csa->two_way) +#define n_node (csa->n_node) +#define n_arc (csa->n_arc) +#define n_grid_arc (csa->n_grid_arc) +#define n_source (csa->n_source) +#define n_sink (csa->n_sink) +#define avg_degree (csa->avg_degree) +#define t_supply (csa->t_supply) +#define n1 (csa->n1) +#define n2 (csa->n2) +#define source_list (csa->source_list) +#define sink_list (csa->sink_list) +#define arc_costs (csa->arc_costs) +#define capacities (csa->capacities) +#define arc_list (csa->arc_list) + +static void assign_capacities(struct csa *csa); +static void assign_costs(struct csa *csa); +static void assign_imbalance(struct csa *csa); +static int exponential(struct csa *csa, double lambda[1]); +static struct arcs *gen_additional_arcs(struct csa *csa, struct arcs + *arc_ptr); +static struct arcs *gen_basic_grid(struct csa *csa, struct arcs + *arc_ptr); +static void gen_more_arcs(struct csa *csa, struct arcs *arc_ptr); +static void generate(struct csa *csa); +static void output(struct csa *csa); +static double randy(struct csa *csa); +static void select_source_sinks(struct csa *csa); +static int uniform(struct csa *csa, double a[2]); + +int glp_gridgen(glp_graph *G_, int _v_rhs, int _a_cap, int _a_cost, + const int parm[1+14]) +{ struct csa _csa, *csa = &_csa; + int n, ret; + G = G_; + v_rhs = _v_rhs; + a_cap = _a_cap; + a_cost = _a_cost; + if (G != NULL) + { if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) + xerror("glp_gridgen: v_rhs = %d; invalid offset\n", v_rhs); + if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) + xerror("glp_gridgen: a_cap = %d; invalid offset\n", a_cap); + if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) + xerror("glp_gridgen: a_cost = %d; invalid offset\n", a_cost) + ; + } + /* Check the parameters for consistency. */ + if (!(parm[1] == 0 || parm[1] == 1)) + { ret = 1; + goto done; + } + if (parm[2] < 1) + { ret = 2; + goto done; + } + if (!(10 <= parm[3] && parm[3] <= 40000)) + { ret = 3; + goto done; + } + if (!(1 <= parm[4] && parm[4] <= 40000)) + { ret = 4; + goto done; + } + if (!(parm[5] >= 0 && parm[6] >= 0 && parm[5] + parm[6] <= + parm[3])) + { ret = 5; + goto done; + } + if (!(1 <= parm[7] && parm[7] <= parm[3])) + { ret = 6; + goto done; + } + if (parm[8] < 0) + { ret = 7; + goto done; + } + if (!(parm[9] == 1 || parm[9] == 2)) + { ret = 8; + goto done; + } + if (parm[9] == 1 && parm[10] > parm[11] || + parm[9] == 2 && parm[10] < 1) + { ret = 9; + goto done; + } + if (!(parm[12] == 1 || parm[12] == 2)) + { ret = 10; + goto done; + } + if (parm[12] == 1 && !(0 <= parm[13] && parm[13] <= parm[14]) || + parm[12] == 2 && parm[13] < 1) + { ret = 11; + goto done; + } + /* Initialize the graph object. */ + if (G != NULL) + { glp_erase_graph(G, G->v_size, G->a_size); + glp_set_graph_name(G, "GRIDGEN"); + } + /* Copy the generator parameters. */ + two_way = parm[1]; + seed_original = seed = parm[2]; + n_node = parm[3]; + n = parm[4]; + n_source = parm[5]; + n_sink = parm[6]; + avg_degree = parm[7]; + t_supply = parm[8]; + arc_costs.distribution = parm[9]; + if (parm[9] == 1) + { arc_costs.parameter[0] = parm[10]; + arc_costs.parameter[1] = parm[11]; + } + else + { arc_costs.parameter[0] = (double)parm[10] / 100.0; + arc_costs.parameter[1] = 0.0; + } + capacities.distribution = parm[12]; + if (parm[12] == 1) + { capacities.parameter[0] = parm[13]; + capacities.parameter[1] = parm[14]; + } + else + { capacities.parameter[0] = (double)parm[13] / 100.0; + capacities.parameter[1] = 0.0; + } + /* Calculate the edge lengths of the grid according to the + input. */ + if (n * n >= n_node) + { n1 = n; + n2 = (int)((double)n_node / (double)n + 0.5); + } + else + { n2 = n; + n1 = (int)((double)n_node / (double)n + 0.5); + } + /* Recalculate the total number of nodes and plus 1 for the super + node. */ + n_node = n1 * n2 + 1; + n_arc = n_node * avg_degree; + n_grid_arc = (two_way + 1) * ((n1 - 1) * n2 + (n2 - 1) * n1) + + n_source + n_sink; + if (n_grid_arc > n_arc) n_arc = n_grid_arc; + arc_list = xcalloc(n_arc, sizeof(struct arcs)); + source_list = xcalloc(n_source, sizeof(struct imbalance)); + sink_list = xcalloc(n_sink, sizeof(struct imbalance)); + /* Generate a random network. */ + generate(csa); + /* Output the network. */ + output(csa); + /* Free all allocated memory. */ + xfree(arc_list); + xfree(source_list); + xfree(sink_list); + /* The instance has been successfully generated. */ + ret = 0; +done: return ret; +} + +#undef random + +static void assign_capacities(struct csa *csa) +{ /* Assign a capacity to each arc. */ + struct arcs *arc_ptr = arc_list; + int (*random)(struct csa *csa, double *); + int i; + /* Determine the random number generator to use. */ + switch (arc_costs.distribution) + { case UNIFORM: + random = uniform; + break; + case EXPONENTIAL: + random = exponential; + break; + default: + xassert(csa != csa); + } + /* Assign capacities to grid arcs. */ + for (i = n_source + n_sink; i < n_grid_arc; i++, arc_ptr++) + arc_ptr->u = random(csa, capacities.parameter); + i = i - n_source - n_sink; + /* Assign capacities to arcs to/from supernode. */ + for (; i < n_grid_arc; i++, arc_ptr++) + arc_ptr->u = t_supply; + /* Assign capacities to all other arcs. */ + for (; i < n_arc; i++, arc_ptr++) + arc_ptr->u = random(csa, capacities.parameter); + return; +} + +static void assign_costs(struct csa *csa) +{ /* Assign a cost to each arc. */ + struct arcs *arc_ptr = arc_list; + int (*random)(struct csa *csa, double *); + int i; + /* A high cost assigned to arcs to/from the supernode. */ + int high_cost; + /* The maximum cost assigned to arcs in the base grid. */ + int max_cost = 0; + /* Determine the random number generator to use. */ + switch (arc_costs.distribution) + { case UNIFORM: + random = uniform; + break; + case EXPONENTIAL: + random = exponential; + break; + default: + xassert(csa != csa); + } + /* Assign costs to arcs in the base grid. */ + for (i = n_source + n_sink; i < n_grid_arc; i++, arc_ptr++) + { arc_ptr->cost = random(csa, arc_costs.parameter); + if (max_cost < arc_ptr->cost) max_cost = arc_ptr->cost; + } + i = i - n_source - n_sink; + /* Assign costs to arcs to/from the super node. */ + high_cost = max_cost * 2; + for (; i < n_grid_arc; i++, arc_ptr++) + arc_ptr->cost = high_cost; + /* Assign costs to all other arcs. */ + for (; i < n_arc; i++, arc_ptr++) + arc_ptr->cost = random(csa, arc_costs.parameter); + return; +} + +static void assign_imbalance(struct csa *csa) +{ /* Assign an imbalance to each node. */ + int total, i; + double avg; + struct imbalance *ptr; + /* assign the supply nodes */ + avg = 2.0 * t_supply / n_source; + do + { for (i = 1, total = t_supply, ptr = source_list + 1; + i < n_source; i++, ptr++) + { ptr->supply = (int)(randy(csa) * avg + 0.5); + total -= ptr->supply; + } + source_list->supply = total; + } + /* redo all if the assignment "overshooted" */ + while (total <= 0); + /* assign the demand nodes */ + avg = -2.0 * t_supply / n_sink; + do + { for (i = 1, total = t_supply, ptr = sink_list + 1; + i < n_sink; i++, ptr++) + { ptr->supply = (int)(randy(csa) * avg - 0.5); + total += ptr->supply; + } + sink_list->supply = - total; + } + while (total <= 0); + return; +} + +static int exponential(struct csa *csa, double lambda[1]) +{ /* Returns an "exponentially distributed" integer with parameter + lambda. */ + return ((int)(- lambda[0] * log((double)randy(csa)) + 0.5)); +} + +static struct arcs *gen_additional_arcs(struct csa *csa, struct arcs + *arc_ptr) +{ /* Generate an arc from each source to the supernode and from + supernode to each sink. */ + int i; + for (i = 0; i < n_source; i++, arc_ptr++) + { arc_ptr->from = source_list[i].node; + arc_ptr->to = n_node; + } + for (i = 0; i < n_sink; i++, arc_ptr++) + { arc_ptr->to = sink_list[i].node; + arc_ptr->from = n_node; + } + return arc_ptr; +} + +static struct arcs *gen_basic_grid(struct csa *csa, struct arcs + *arc_ptr) +{ /* Generate the basic grid. */ + int direction = 1, i, j, k; + if (two_way) + { /* Generate an arc in each direction. */ + for (i = 1; i < n_node; i += n1) + { for (j = i, k = j + n1 - 1; j < k; j++) + { arc_ptr->from = j; + arc_ptr->to = j + 1; + arc_ptr++; + arc_ptr->from = j + 1; + arc_ptr->to = j; + arc_ptr++; + } + } + for (i = 1; i <= n1; i++) + { for (j = i + n1; j < n_node; j += n1) + { arc_ptr->from = j; + arc_ptr->to = j - n1; + arc_ptr++; + arc_ptr->from = j - n1; + arc_ptr->to = j; + arc_ptr++; + } + } + } + else + { /* Generate one arc in each direction. */ + for (i = 1; i < n_node; i += n1) + { if (direction == 1) + j = i; + else + j = i + 1; + for (k = j + n1 - 1; j < k; j++) + { arc_ptr->from = j; + arc_ptr->to = j + direction; + arc_ptr++; + } + direction = - direction; + } + for (i = 1; i <= n1; i++) + { j = i + n1; + if (direction == 1) + { for (; j < n_node; j += n1) + { arc_ptr->from = j - n1; + arc_ptr->to = j; + arc_ptr++; + } + } + else + { for (; j < n_node; j += n1) + { arc_ptr->from = j - n1; + arc_ptr->to = j; + arc_ptr++; + } + } + direction = - direction; + } + } + return arc_ptr; +} + +static void gen_more_arcs(struct csa *csa, struct arcs *arc_ptr) +{ /* Generate random arcs to meet the specified density. */ + int i; + double ab[2]; + ab[0] = 0.9; + ab[1] = n_node - 0.99; /* upper limit is n_node-1 because the + supernode cannot be selected */ + for (i = n_grid_arc; i < n_arc; i++, arc_ptr++) + { arc_ptr->from = uniform(csa, ab); + arc_ptr->to = uniform(csa, ab); + if (arc_ptr->from == arc_ptr->to) + { arc_ptr--; + i--; + } + } + return; +} + +static void generate(struct csa *csa) +{ /* Generate a random network. */ + struct arcs *arc_ptr = arc_list; + arc_ptr = gen_basic_grid(csa, arc_ptr); + select_source_sinks(csa); + arc_ptr = gen_additional_arcs(csa, arc_ptr); + gen_more_arcs(csa, arc_ptr); + assign_costs(csa); + assign_capacities(csa); + assign_imbalance(csa); + return; +} + +static void output(struct csa *csa) +{ /* Output the network in DIMACS format. */ + struct arcs *arc_ptr; + struct imbalance *imb_ptr; + int i; + if (G != NULL) goto skip; + /* Output "c", "p" records. */ + xprintf("c generated by GRIDGEN\n"); + xprintf("c seed %d\n", seed_original); + xprintf("c nodes %d\n", n_node); + xprintf("c grid size %d X %d\n", n1, n2); + xprintf("c sources %d sinks %d\n", n_source, n_sink); + xprintf("c avg. degree %d\n", avg_degree); + xprintf("c supply %d\n", t_supply); + switch (arc_costs.distribution) + { case UNIFORM: + xprintf("c arc costs: UNIFORM distr. min %d max %d\n", + (int)arc_costs.parameter[0], + (int)arc_costs.parameter[1]); + break; + case EXPONENTIAL: + xprintf("c arc costs: EXPONENTIAL distr. lambda %d\n", + (int)arc_costs.parameter[0]); + break; + default: + xassert(csa != csa); + } + switch (capacities.distribution) + { case UNIFORM: + xprintf("c arc caps : UNIFORM distr. min %d max %d\n", + (int)capacities.parameter[0], + (int)capacities.parameter[1]); + break; + case EXPONENTIAL: + xprintf("c arc caps : EXPONENTIAL distr. %d lambda %d\n", + (int)capacities.parameter[0]); + break; + default: + xassert(csa != csa); + } +skip: if (G == NULL) + xprintf("p min %d %d\n", n_node, n_arc); + else + { glp_add_vertices(G, n_node); + if (v_rhs >= 0) + { double zero = 0.0; + for (i = 1; i <= n_node; i++) + { glp_vertex *v = G->v[i]; + memcpy((char *)v->data + v_rhs, &zero, sizeof(double)); + } + } + } + /* Output "n node supply". */ + for (i = 0, imb_ptr = source_list; i < n_source; i++, imb_ptr++) + { if (G == NULL) + xprintf("n %d %d\n", imb_ptr->node, imb_ptr->supply); + else + { if (v_rhs >= 0) + { double temp = (double)imb_ptr->supply; + glp_vertex *v = G->v[imb_ptr->node]; + memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); + } + } + } + for (i = 0, imb_ptr = sink_list; i < n_sink; i++, imb_ptr++) + { if (G == NULL) + xprintf("n %d %d\n", imb_ptr->node, imb_ptr->supply); + else + { if (v_rhs >= 0) + { double temp = (double)imb_ptr->supply; + glp_vertex *v = G->v[imb_ptr->node]; + memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); + } + } + } + /* Output "a from to lowcap=0 hicap cost". */ + for (i = 0, arc_ptr = arc_list; i < n_arc; i++, arc_ptr++) + { if (G == NULL) + xprintf("a %d %d 0 %d %d\n", arc_ptr->from, arc_ptr->to, + arc_ptr->u, arc_ptr->cost); + else + { glp_arc *a = glp_add_arc(G, arc_ptr->from, arc_ptr->to); + if (a_cap >= 0) + { double temp = (double)arc_ptr->u; + memcpy((char *)a->data + a_cap, &temp, sizeof(double)); + } + if (a_cost >= 0) + { double temp = (double)arc_ptr->cost; + memcpy((char *)a->data + a_cost, &temp, sizeof(double)); + } + } + } + return; +} + +static double randy(struct csa *csa) +{ /* Returns a random number between 0.0 and 1.0. + See Ward Cheney & David Kincaid, "Numerical Mathematics and + Computing," 2Ed, pp. 335. */ + seed = 16807 * seed % 2147483647; + if (seed < 0) seed = - seed; + return seed * 4.6566128752459e-10; +} + +static void select_source_sinks(struct csa *csa) +{ /* Randomly select the source nodes and sink nodes. */ + int i, *int_ptr; + int *temp_list; /* a temporary list of nodes */ + struct imbalance *ptr; + double ab[2]; /* parameter for random number generator */ + ab[0] = 0.9; + ab[1] = n_node - 0.99; /* upper limit is n_node-1 because the + supernode cannot be selected */ + temp_list = xcalloc(n_node, sizeof(int)); + for (i = 0, int_ptr = temp_list; i < n_node; i++, int_ptr++) + *int_ptr = 0; + /* Select the source nodes. */ + for (i = 0, ptr = source_list; i < n_source; i++, ptr++) + { ptr->node = uniform(csa, ab); + if (temp_list[ptr->node] == 1) /* check for duplicates */ + { ptr--; + i--; + } + else + temp_list[ptr->node] = 1; + } + /* Select the sink nodes. */ + for (i = 0, ptr = sink_list; i < n_sink; i++, ptr++) + { ptr->node = uniform(csa, ab); + if (temp_list[ptr->node] == 1) + { ptr--; + i--; + } + else + temp_list[ptr->node] = 1; + } + xfree(temp_list); + return; +} + +int uniform(struct csa *csa, double a[2]) +{ /* Generates an integer uniformly selected from [a[0],a[1]]. */ + return (int)((a[1] - a[0]) * randy(csa) + a[0] + 0.5); +} + +/**********************************************************************/ + +#if 0 +int main(void) +{ int parm[1+14]; + double temp; + scanf("%d", &parm[1]); + scanf("%d", &parm[2]); + scanf("%d", &parm[3]); + scanf("%d", &parm[4]); + scanf("%d", &parm[5]); + scanf("%d", &parm[6]); + scanf("%d", &parm[7]); + scanf("%d", &parm[8]); + scanf("%d", &parm[9]); + if (parm[9] == 1) + { scanf("%d", &parm[10]); + scanf("%d", &parm[11]); + } + else + { scanf("%le", &temp); + parm[10] = (int)(100.0 * temp + .5); + parm[11] = 0; + } + scanf("%d", &parm[12]); + if (parm[12] == 1) + { scanf("%d", &parm[13]); + scanf("%d", &parm[14]); + } + else + { scanf("%le", &temp); + parm[13] = (int)(100.0 * temp + .5); + parm[14] = 0; + } + glp_gridgen(NULL, 0, 0, 0, parm); + return 0; +} +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpnet05.c b/resources/3rdparty/glpk-4.57/src/glpnet05.c new file mode 100644 index 000000000..ea7ca6300 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpnet05.c @@ -0,0 +1,368 @@ +/* glpnet05.c (Goldfarb's maximum flow problem generator) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* This code is a modified version of the program RMFGEN, a maxflow +* problem generator developed by D.Goldfarb and M.Grigoriadis, and +* originally implemented by Tamas Badics . +* The original code is publically available on the DIMACS ftp site at: +* . +* +* All changes concern only the program interface, so this modified +* version produces exactly the same instances as the original version. +* +* Changes were made by Andrew Makhorin . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpk.h" +#include "rng.h" + +/*********************************************************************** +* NAME +* +* glp_rmfgen - Goldfarb's maximum flow problem generator +* +* SYNOPSIS +* +* int glp_rmfgen(glp_graph *G, int *s, int *t, int a_cap, +* const int parm[1+5]); +* +* DESCRIPTION +* +* The routine glp_rmfgen is a maximum flow problem generator developed +* by D.Goldfarb and M.Grigoriadis. +* +* The parameter G specifies the graph object, to which the generated +* problem data have to be stored. Note that on entry the graph object +* is erased with the routine glp_erase_graph. +* +* The pointer s specifies a location, to which the routine stores the +* source node number. If s is NULL, the node number is not stored. +* +* The pointer t specifies a location, to which the routine stores the +* sink node number. If t is NULL, the node number is not stored. +* +* The parameter a_cap specifies an offset of the field of type double +* in the arc data block, to which the routine stores the arc capacity. +* If a_cap < 0, the capacity is not stored. +* +* The array parm contains description of the network to be generated: +* +* parm[0] not used +* parm[1] (seed) random number seed (a positive integer) +* parm[2] (a) frame size +* parm[3] (b) depth +* parm[4] (c1) minimal arc capacity +* parm[5] (c2) maximal arc capacity +* +* RETURNS +* +* If the instance was successfully generated, the routine glp_netgen +* returns zero; otherwise, if specified parameters are inconsistent, +* the routine returns a non-zero error code. +* +* COMMENTS +* +* The generated network is as follows. It has b pieces of frames of +* size a * a. (So alltogether the number of vertices is a * a * b) +* +* In each frame all the vertices are connected with their neighbours +* (forth and back). In addition the vertices of a frame are connected +* one to one with the vertices of next frame using a random permutation +* of those vertices. +* +* The source is the lower left vertex of the first frame, the sink is +* the upper right vertex of the b'th frame. +* +* t +* +-------+ +* | .| +* | . | +* / | / | +* +-------+/ -+ b +* | | |/. +* a | -v- |/ +* | | |/ +* +-------+ 1 +* s a +* +* The capacities are randomly chosen integers from the range of [c1,c2] +* in the case of interconnecting edges, and c2 * a * a for the in-frame +* edges. +* +* REFERENCES +* +* D.Goldfarb and M.D.Grigoriadis, "A computational comparison of the +* Dinic and network simplex methods for maximum flow." Annals of Op. +* Res. 13 (1988), pp. 83-123. +* +* U.Derigs and W.Meier, "Implementing Goldberg's max-flow algorithm: +* A computational investigation." Zeitschrift fuer Operations Research +* 33 (1989), pp. 383-403. */ + +typedef struct VERTEX +{ struct EDGE **edgelist; + /* Pointer to the list of pointers to the adjacent edges. + (No matter that to or from edges) */ + struct EDGE **current; + /* Pointer to the current edge */ + int degree; + /* Number of adjacent edges (both direction) */ + int index; +} vertex; + +typedef struct EDGE +{ int from; + int to; + int cap; + /* Capacity */ +} edge; + +typedef struct NETWORK +{ struct NETWORK *next, *prev; + int vertnum; + int edgenum; + vertex *verts; + /* Vertex array[1..vertnum] */ + edge *edges; + /* Edge array[1..edgenum] */ + int source; + /* Pointer to the source */ + int sink; + /* Pointer to the sink */ +} network; + +struct csa +{ /* common storage area */ + glp_graph *G; + int *s, *t, a_cap; + RNG *rand; + network *N; + int *Parr; + int A, AA, C2AA, Ec; +}; + +#define G (csa->G) +#define s (csa->s) +#define t (csa->t) +#define a_cap (csa->a_cap) +#define N (csa->N) +#define Parr (csa->Parr) +#define A (csa->A) +#define AA (csa->AA) +#define C2AA (csa->C2AA) +#define Ec (csa->Ec) + +#undef random +#define random(A) (int)(rng_unif_01(csa->rand) * (double)(A)) +#define RANDOM(A, B) (int)(random((B) - (A) + 1) + (A)) +#define sgn(A) (((A) > 0) ? 1 : ((A) == 0) ? 0 : -1) + +static void make_edge(struct csa *csa, int from, int to, int c1, int c2) +{ Ec++; + N->edges[Ec].from = from; + N->edges[Ec].to = to; + N->edges[Ec].cap = RANDOM(c1, c2); + return; +} + +static void permute(struct csa *csa) +{ int i, j, tmp; + for (i = 1; i < AA; i++) + { j = RANDOM(i, AA); + tmp = Parr[i]; + Parr[i] = Parr[j]; + Parr[j] = tmp; + } + return; +} + +static void connect(struct csa *csa, int offset, int cv, int x1, int y1) +{ int cv1; + cv1 = offset + (x1 - 1) * A + y1; + Ec++; + N->edges[Ec].from = cv; + N->edges[Ec].to = cv1; + N->edges[Ec].cap = C2AA; + return; +} + +static network *gen_rmf(struct csa *csa, int a, int b, int c1, int c2) +{ /* generates a network with a*a*b nodes and 6a*a*b-4ab-2a*a edges + random_frame network: + Derigs & Meier, Methods & Models of OR (1989), 33:383-403 */ + int x, y, z, offset, cv; + A = a; + AA = a * a; + C2AA = c2 * AA; + Ec = 0; + N = (network *)xmalloc(sizeof(network)); + N->vertnum = AA * b; + N->edgenum = 5 * AA * b - 4 * A * b - AA; + N->edges = (edge *)xcalloc(N->edgenum + 1, sizeof(edge)); + N->source = 1; + N->sink = N->vertnum; + Parr = (int *)xcalloc(AA + 1, sizeof(int)); + for (x = 1; x <= AA; x++) + Parr[x] = x; + for (z = 1; z <= b; z++) + { offset = AA * (z - 1); + if (z != b) + permute(csa); + for (x = 1; x <= A; x++) + { for (y = 1; y <= A; y++) + { cv = offset + (x - 1) * A + y; + if (z != b) + make_edge(csa, cv, offset + AA + Parr[cv - offset], + c1, c2); /* the intermediate edges */ + if (y < A) + connect(csa, offset, cv, x, y + 1); + if (y > 1) + connect(csa, offset, cv, x, y - 1); + if (x < A) + connect(csa, offset, cv, x + 1, y); + if (x > 1) + connect(csa, offset, cv, x - 1, y); + } + } + } + xfree(Parr); + return N; +} + +static void print_max_format(struct csa *csa, network *n, char *comm[], + int dim) +{ /* prints a network heading with dim lines of comments (no \n + needs at the ends) */ + int i, vnum, e_num; + edge *e; + vnum = n->vertnum; + e_num = n->edgenum; + if (G == NULL) + { for (i = 0; i < dim; i++) + xprintf("c %s\n", comm[i]); + xprintf("p max %7d %10d\n", vnum, e_num); + xprintf("n %7d s\n", n->source); + xprintf("n %7d t\n", n->sink); + } + else + { glp_add_vertices(G, vnum); + if (s != NULL) *s = n->source; + if (t != NULL) *t = n->sink; + } + for (i = 1; i <= e_num; i++) + { e = &n->edges[i]; + if (G == NULL) + xprintf("a %7d %7d %10d\n", e->from, e->to, (int)e->cap); + else + { glp_arc *a = glp_add_arc(G, e->from, e->to); + if (a_cap >= 0) + { double temp = (double)e->cap; + memcpy((char *)a->data + a_cap, &temp, sizeof(double)); + } + } + } + return; +} + +static void gen_free_net(network *n) +{ xfree(n->edges); + xfree(n); + return; +} + +int glp_rmfgen(glp_graph *G_, int *_s, int *_t, int _a_cap, + const int parm[1+5]) +{ struct csa _csa, *csa = &_csa; + network *n; + char comm[10][80], *com1[10]; + int seed, a, b, c1, c2, ret; + G = G_; + s = _s; + t = _t; + a_cap = _a_cap; + if (G != NULL) + { if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) + xerror("glp_rmfgen: a_cap = %d; invalid offset\n", a_cap); + } + seed = parm[1]; + a = parm[2]; + b = parm[3]; + c1 = parm[4]; + c2 = parm[5]; + if (!(seed > 0 && 1 <= a && a <= 1000 && 1 <= b && b <= 1000 && + 0 <= c1 && c1 <= c2 && c2 <= 1000)) + { ret = 1; + goto done; + } + if (G != NULL) + { glp_erase_graph(G, G->v_size, G->a_size); + glp_set_graph_name(G, "RMFGEN"); + } + csa->rand = rng_create_rand(); + rng_init_rand(csa->rand, seed); + n = gen_rmf(csa, a, b, c1, c2); + sprintf(comm[0], "This file was generated by genrmf."); + sprintf(comm[1], "The parameters are: a: %d b: %d c1: %d c2: %d", + a, b, c1, c2); + com1[0] = comm[0]; + com1[1] = comm[1]; + print_max_format(csa, n, com1, 2); + gen_free_net(n); + rng_delete_rand(csa->rand); + ret = 0; +done: return ret; +} + +/**********************************************************************/ + +#if 0 +int main(int argc, char *argv[]) +{ int seed, a, b, c1, c2, i, parm[1+5]; + seed = 123; + a = b = c1 = c2 = -1; + for (i = 1; i < argc; i++) + { if (strcmp(argv[i], "-seed") == 0) + seed = atoi(argv[++i]); + else if (strcmp(argv[i], "-a") == 0) + a = atoi(argv[++i]); + else if (strcmp(argv[i], "-b") == 0) + b = atoi(argv[++i]); + else if (strcmp(argv[i], "-c1") == 0) + c1 = atoi(argv[++i]); + else if (strcmp(argv[i], "-c2") == 0) + c2 = atoi(argv[++i]); + } + if (a < 0 || b < 0 || c1 < 0 || c2 < 0) + { xprintf("Usage:\n"); + xprintf("genrmf [-seed seed] -a frame_size -b depth\n"); + xprintf(" -c1 cap_range1 -c2 cap_range2\n"); + } + else + { parm[1] = seed; + parm[2] = a; + parm[3] = b; + parm[4] = c1; + parm[5] = c2; + glp_rmfgen(NULL, NULL, NULL, 0, parm); + } + return 0; +} +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpnpp.h b/resources/3rdparty/glpk-4.57/src/glpnpp.h new file mode 100644 index 000000000..6aaebe8d4 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpnpp.h @@ -0,0 +1,638 @@ +/* glpnpp.h (LP/MIP preprocessor) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef GLPNPP_H +#define GLPNPP_H + +#include "prob.h" + +typedef struct NPP NPP; +typedef struct NPPROW NPPROW; +typedef struct NPPCOL NPPCOL; +typedef struct NPPAIJ NPPAIJ; +typedef struct NPPTSE NPPTSE; +typedef struct NPPLFE NPPLFE; + +struct NPP +{ /* LP/MIP preprocessor workspace */ + /*--------------------------------------------------------------*/ + /* original problem segment */ + int orig_dir; + /* optimization direction flag: + GLP_MIN - minimization + GLP_MAX - maximization */ + int orig_m; + /* number of rows */ + int orig_n; + /* number of columns */ + int orig_nnz; + /* number of non-zero constraint coefficients */ + /*--------------------------------------------------------------*/ + /* transformed problem segment (always minimization) */ + DMP *pool; + /* memory pool to store problem components */ + char *name; + /* problem name (1 to 255 chars); NULL means no name is assigned + to the problem */ + char *obj; + /* objective function name (1 to 255 chars); NULL means no name + is assigned to the objective function */ + double c0; + /* constant term of the objective function */ + int nrows; + /* number of rows introduced into the problem; this count + increases by one every time a new row is added and never + decreases; thus, actual number of rows may be less than nrows + due to row deletions */ + int ncols; + /* number of columns introduced into the problem; this count + increases by one every time a new column is added and never + decreases; thus, actual number of column may be less than + ncols due to column deletions */ + NPPROW *r_head; + /* pointer to the beginning of the row list */ + NPPROW *r_tail; + /* pointer to the end of the row list */ + NPPCOL *c_head; + /* pointer to the beginning of the column list */ + NPPCOL *c_tail; + /* pointer to the end of the column list */ + /*--------------------------------------------------------------*/ + /* transformation history */ + DMP *stack; + /* memory pool to store transformation entries */ + NPPTSE *top; + /* pointer to most recent transformation entry */ +#if 0 /* 16/XII-2009 */ + int count[1+25]; + /* transformation statistics */ +#endif + /*--------------------------------------------------------------*/ + /* resultant (preprocessed) problem segment */ + int m; + /* number of rows */ + int n; + /* number of columns */ + int nnz; + /* number of non-zero constraint coefficients */ + int *row_ref; /* int row_ref[1+m]; */ + /* row_ref[i], 1 <= i <= m, is the reference number assigned to + a row, which is i-th row of the resultant problem */ + int *col_ref; /* int col_ref[1+n]; */ + /* col_ref[j], 1 <= j <= n, is the reference number assigned to + a column, which is j-th column of the resultant problem */ + /*--------------------------------------------------------------*/ + /* recovered solution segment */ + int sol; + /* solution indicator: + GLP_SOL - basic solution + GLP_IPT - interior-point solution + GLP_MIP - mixed integer solution */ + int scaling; + /* scaling option: + GLP_OFF - scaling is disabled + GLP_ON - scaling is enabled */ + int p_stat; + /* status of primal basic solution: + GLP_UNDEF - primal solution is undefined + GLP_FEAS - primal solution is feasible + GLP_INFEAS - primal solution is infeasible + GLP_NOFEAS - no primal feasible solution exists */ + int d_stat; + /* status of dual basic solution: + GLP_UNDEF - dual solution is undefined + GLP_FEAS - dual solution is feasible + GLP_INFEAS - dual solution is infeasible + GLP_NOFEAS - no dual feasible solution exists */ + int t_stat; + /* status of interior-point solution: + GLP_UNDEF - interior solution is undefined + GLP_OPT - interior solution is optimal */ + int i_stat; + /* status of mixed integer solution: + GLP_UNDEF - integer solution is undefined + GLP_OPT - integer solution is optimal + GLP_FEAS - integer solution is feasible + GLP_NOFEAS - no integer solution exists */ + char *r_stat; /* char r_stat[1+nrows]; */ + /* r_stat[i], 1 <= i <= nrows, is status of i-th row: + GLP_BS - inactive constraint + GLP_NL - active constraint on lower bound + GLP_NU - active constraint on upper bound + GLP_NF - active free row + GLP_NS - active equality constraint */ + char *c_stat; /* char c_stat[1+nrows]; */ + /* c_stat[j], 1 <= j <= nrows, is status of j-th column: + GLP_BS - basic variable + GLP_NL - non-basic variable on lower bound + GLP_NU - non-basic variable on upper bound + GLP_NF - non-basic free variable + GLP_NS - non-basic fixed variable */ + double *r_pi; /* double r_pi[1+nrows]; */ + /* r_pi[i], 1 <= i <= nrows, is Lagrange multiplier (dual value) + for i-th row (constraint) */ + double *c_value; /* double c_value[1+ncols]; */ + /* c_value[j], 1 <= j <= ncols, is primal value of j-th column + (structural variable) */ +}; + +struct NPPROW +{ /* row (constraint) */ + int i; + /* reference number assigned to the row, 1 <= i <= nrows */ + char *name; + /* row name (1 to 255 chars); NULL means no name is assigned to + the row */ + double lb; + /* lower bound; -DBL_MAX means the row has no lower bound */ + double ub; + /* upper bound; +DBL_MAX means the row has no upper bound */ + NPPAIJ *ptr; + /* pointer to the linked list of constraint coefficients */ + int temp; + /* working field used by preprocessor routines */ + NPPROW *prev; + /* pointer to previous row in the row list */ + NPPROW *next; + /* pointer to next row in the row list */ +}; + +struct NPPCOL +{ /* column (variable) */ + int j; + /* reference number assigned to the column, 1 <= j <= ncols */ + char *name; + /* column name (1 to 255 chars); NULL means no name is assigned + to the column */ + char is_int; + /* 0 means continuous variable; 1 means integer variable */ + double lb; + /* lower bound; -DBL_MAX means the column has no lower bound */ + double ub; + /* upper bound; +DBL_MAX means the column has no upper bound */ + double coef; + /* objective coefficient */ + NPPAIJ *ptr; + /* pointer to the linked list of constraint coefficients */ + int temp; + /* working field used by preprocessor routines */ +#if 1 /* 28/XII-2009 */ + union + { double ll; + /* implied column lower bound */ + int pos; + /* vertex ordinal number corresponding to this binary column + in the conflict graph (0, if the vertex does not exist) */ + } ll; + union + { double uu; + /* implied column upper bound */ + int neg; + /* vertex ordinal number corresponding to complement of this + binary column in the conflict graph (0, if the vertex does + not exist) */ + } uu; +#endif + NPPCOL *prev; + /* pointer to previous column in the column list */ + NPPCOL *next; + /* pointer to next column in the column list */ +}; + +struct NPPAIJ +{ /* constraint coefficient */ + NPPROW *row; + /* pointer to corresponding row */ + NPPCOL *col; + /* pointer to corresponding column */ + double val; + /* (non-zero) coefficient value */ + NPPAIJ *r_prev; + /* pointer to previous coefficient in the same row */ + NPPAIJ *r_next; + /* pointer to next coefficient in the same row */ + NPPAIJ *c_prev; + /* pointer to previous coefficient in the same column */ + NPPAIJ *c_next; + /* pointer to next coefficient in the same column */ +}; + +struct NPPTSE +{ /* transformation stack entry */ + int (*func)(NPP *npp, void *info); + /* pointer to routine performing back transformation */ + void *info; + /* pointer to specific info (depends on the transformation) */ + NPPTSE *link; + /* pointer to another entry created *before* this entry */ +}; + +struct NPPLFE +{ /* linear form element */ + int ref; + /* row/column reference number */ + double val; + /* (non-zero) coefficient value */ + NPPLFE *next; + /* pointer to another element */ +}; + +#define npp_create_wksp _glp_npp_create_wksp +NPP *npp_create_wksp(void); +/* create LP/MIP preprocessor workspace */ + +#define npp_insert_row _glp_npp_insert_row +void npp_insert_row(NPP *npp, NPPROW *row, int where); +/* insert row to the row list */ + +#define npp_remove_row _glp_npp_remove_row +void npp_remove_row(NPP *npp, NPPROW *row); +/* remove row from the row list */ + +#define npp_activate_row _glp_npp_activate_row +void npp_activate_row(NPP *npp, NPPROW *row); +/* make row active */ + +#define npp_deactivate_row _glp_npp_deactivate_row +void npp_deactivate_row(NPP *npp, NPPROW *row); +/* make row inactive */ + +#define npp_insert_col _glp_npp_insert_col +void npp_insert_col(NPP *npp, NPPCOL *col, int where); +/* insert column to the column list */ + +#define npp_remove_col _glp_npp_remove_col +void npp_remove_col(NPP *npp, NPPCOL *col); +/* remove column from the column list */ + +#define npp_activate_col _glp_npp_activate_col +void npp_activate_col(NPP *npp, NPPCOL *col); +/* make column active */ + +#define npp_deactivate_col _glp_npp_deactivate_col +void npp_deactivate_col(NPP *npp, NPPCOL *col); +/* make column inactive */ + +#define npp_add_row _glp_npp_add_row +NPPROW *npp_add_row(NPP *npp); +/* add new row to the current problem */ + +#define npp_add_col _glp_npp_add_col +NPPCOL *npp_add_col(NPP *npp); +/* add new column to the current problem */ + +#define npp_add_aij _glp_npp_add_aij +NPPAIJ *npp_add_aij(NPP *npp, NPPROW *row, NPPCOL *col, double val); +/* add new element to the constraint matrix */ + +#define npp_row_nnz _glp_npp_row_nnz +int npp_row_nnz(NPP *npp, NPPROW *row); +/* count number of non-zero coefficients in row */ + +#define npp_col_nnz _glp_npp_col_nnz +int npp_col_nnz(NPP *npp, NPPCOL *col); +/* count number of non-zero coefficients in column */ + +#define npp_push_tse _glp_npp_push_tse +void *npp_push_tse(NPP *npp, int (*func)(NPP *npp, void *info), + int size); +/* push new entry to the transformation stack */ + +#define npp_erase_row _glp_npp_erase_row +void npp_erase_row(NPP *npp, NPPROW *row); +/* erase row content to make it empty */ + +#define npp_del_row _glp_npp_del_row +void npp_del_row(NPP *npp, NPPROW *row); +/* remove row from the current problem */ + +#define npp_del_col _glp_npp_del_col +void npp_del_col(NPP *npp, NPPCOL *col); +/* remove column from the current problem */ + +#define npp_del_aij _glp_npp_del_aij +void npp_del_aij(NPP *npp, NPPAIJ *aij); +/* remove element from the constraint matrix */ + +#define npp_load_prob _glp_npp_load_prob +void npp_load_prob(NPP *npp, glp_prob *orig, int names, int sol, + int scaling); +/* load original problem into the preprocessor workspace */ + +#define npp_build_prob _glp_npp_build_prob +void npp_build_prob(NPP *npp, glp_prob *prob); +/* build resultant (preprocessed) problem */ + +#define npp_postprocess _glp_npp_postprocess +void npp_postprocess(NPP *npp, glp_prob *prob); +/* postprocess solution from the resultant problem */ + +#define npp_unload_sol _glp_npp_unload_sol +void npp_unload_sol(NPP *npp, glp_prob *orig); +/* store solution to the original problem */ + +#define npp_delete_wksp _glp_npp_delete_wksp +void npp_delete_wksp(NPP *npp); +/* delete LP/MIP preprocessor workspace */ + +#define npp_error() + +#define npp_free_row _glp_npp_free_row +void npp_free_row(NPP *npp, NPPROW *p); +/* process free (unbounded) row */ + +#define npp_geq_row _glp_npp_geq_row +void npp_geq_row(NPP *npp, NPPROW *p); +/* process row of 'not less than' type */ + +#define npp_leq_row _glp_npp_leq_row +void npp_leq_row(NPP *npp, NPPROW *p); +/* process row of 'not greater than' type */ + +#define npp_free_col _glp_npp_free_col +void npp_free_col(NPP *npp, NPPCOL *q); +/* process free (unbounded) column */ + +#define npp_lbnd_col _glp_npp_lbnd_col +void npp_lbnd_col(NPP *npp, NPPCOL *q); +/* process column with (non-zero) lower bound */ + +#define npp_ubnd_col _glp_npp_ubnd_col +void npp_ubnd_col(NPP *npp, NPPCOL *q); +/* process column with upper bound */ + +#define npp_dbnd_col _glp_npp_dbnd_col +void npp_dbnd_col(NPP *npp, NPPCOL *q); +/* process non-negative column with upper bound */ + +#define npp_fixed_col _glp_npp_fixed_col +void npp_fixed_col(NPP *npp, NPPCOL *q); +/* process fixed column */ + +#define npp_make_equality _glp_npp_make_equality +int npp_make_equality(NPP *npp, NPPROW *p); +/* process row with almost identical bounds */ + +#define npp_make_fixed _glp_npp_make_fixed +int npp_make_fixed(NPP *npp, NPPCOL *q); +/* process column with almost identical bounds */ + +#define npp_empty_row _glp_npp_empty_row +int npp_empty_row(NPP *npp, NPPROW *p); +/* process empty row */ + +#define npp_empty_col _glp_npp_empty_col +int npp_empty_col(NPP *npp, NPPCOL *q); +/* process empty column */ + +#define npp_implied_value _glp_npp_implied_value +int npp_implied_value(NPP *npp, NPPCOL *q, double s); +/* process implied column value */ + +#define npp_eq_singlet _glp_npp_eq_singlet +int npp_eq_singlet(NPP *npp, NPPROW *p); +/* process row singleton (equality constraint) */ + +#define npp_implied_lower _glp_npp_implied_lower +int npp_implied_lower(NPP *npp, NPPCOL *q, double l); +/* process implied column lower bound */ + +#define npp_implied_upper _glp_npp_implied_upper +int npp_implied_upper(NPP *npp, NPPCOL *q, double u); +/* process implied upper bound of column */ + +#define npp_ineq_singlet _glp_npp_ineq_singlet +int npp_ineq_singlet(NPP *npp, NPPROW *p); +/* process row singleton (inequality constraint) */ + +#define npp_implied_slack _glp_npp_implied_slack +void npp_implied_slack(NPP *npp, NPPCOL *q); +/* process column singleton (implied slack variable) */ + +#define npp_implied_free _glp_npp_implied_free +int npp_implied_free(NPP *npp, NPPCOL *q); +/* process column singleton (implied free variable) */ + +#define npp_eq_doublet _glp_npp_eq_doublet +NPPCOL *npp_eq_doublet(NPP *npp, NPPROW *p); +/* process row doubleton (equality constraint) */ + +#define npp_forcing_row _glp_npp_forcing_row +int npp_forcing_row(NPP *npp, NPPROW *p, int at); +/* process forcing row */ + +#define npp_analyze_row _glp_npp_analyze_row +int npp_analyze_row(NPP *npp, NPPROW *p); +/* perform general row analysis */ + +#define npp_inactive_bound _glp_npp_inactive_bound +void npp_inactive_bound(NPP *npp, NPPROW *p, int which); +/* remove row lower/upper inactive bound */ + +#define npp_implied_bounds _glp_npp_implied_bounds +void npp_implied_bounds(NPP *npp, NPPROW *p); +/* determine implied column bounds */ + +#define npp_binarize_prob _glp_npp_binarize_prob +int npp_binarize_prob(NPP *npp); +/* binarize MIP problem */ + +#define npp_is_packing _glp_npp_is_packing +int npp_is_packing(NPP *npp, NPPROW *row); +/* test if constraint is packing inequality */ + +#define npp_hidden_packing _glp_npp_hidden_packing +int npp_hidden_packing(NPP *npp, NPPROW *row); +/* identify hidden packing inequality */ + +#define npp_implied_packing _glp_npp_implied_packing +int npp_implied_packing(NPP *npp, NPPROW *row, int which, + NPPCOL *var[], char set[]); +/* identify implied packing inequality */ + +#define npp_is_covering _glp_npp_is_covering +int npp_is_covering(NPP *npp, NPPROW *row); +/* test if constraint is covering inequality */ + +#define npp_hidden_covering _glp_npp_hidden_covering +int npp_hidden_covering(NPP *npp, NPPROW *row); +/* identify hidden covering inequality */ + +#define npp_is_partitioning _glp_npp_is_partitioning +int npp_is_partitioning(NPP *npp, NPPROW *row); +/* test if constraint is partitioning equality */ + +#define npp_reduce_ineq_coef _glp_npp_reduce_ineq_coef +int npp_reduce_ineq_coef(NPP *npp, NPPROW *row); +/* reduce inequality constraint coefficients */ + +#define npp_clean_prob _glp_npp_clean_prob +void npp_clean_prob(NPP *npp); +/* perform initial LP/MIP processing */ + +#define npp_process_row _glp_npp_process_row +int npp_process_row(NPP *npp, NPPROW *row, int hard); +/* perform basic row processing */ + +#define npp_improve_bounds _glp_npp_improve_bounds +int npp_improve_bounds(NPP *npp, NPPROW *row, int flag); +/* improve current column bounds */ + +#define npp_process_col _glp_npp_process_col +int npp_process_col(NPP *npp, NPPCOL *col); +/* perform basic column processing */ + +#define npp_process_prob _glp_npp_process_prob +int npp_process_prob(NPP *npp, int hard); +/* perform basic LP/MIP processing */ + +#define npp_simplex _glp_npp_simplex +int npp_simplex(NPP *npp, const glp_smcp *parm); +/* process LP prior to applying primal/dual simplex method */ + +#define npp_integer _glp_npp_integer +int npp_integer(NPP *npp, const glp_iocp *parm); +/* process MIP prior to applying branch-and-bound method */ + +/**********************************************************************/ + +#define npp_sat_free_row _glp_npp_sat_free_row +void npp_sat_free_row(NPP *npp, NPPROW *p); +/* process free (unbounded) row */ + +#define npp_sat_fixed_col _glp_npp_sat_fixed_col +int npp_sat_fixed_col(NPP *npp, NPPCOL *q); +/* process fixed column */ + +#define npp_sat_is_bin_comb _glp_npp_sat_is_bin_comb +int npp_sat_is_bin_comb(NPP *npp, NPPROW *row); +/* test if row is binary combination */ + +#define npp_sat_num_pos_coef _glp_npp_sat_num_pos_coef +int npp_sat_num_pos_coef(NPP *npp, NPPROW *row); +/* determine number of positive coefficients */ + +#define npp_sat_num_neg_coef _glp_npp_sat_num_neg_coef +int npp_sat_num_neg_coef(NPP *npp, NPPROW *row); +/* determine number of negative coefficients */ + +#define npp_sat_is_cover_ineq _glp_npp_sat_is_cover_ineq +int npp_sat_is_cover_ineq(NPP *npp, NPPROW *row); +/* test if row is covering inequality */ + +#define npp_sat_is_pack_ineq _glp_npp_sat_is_pack_ineq +int npp_sat_is_pack_ineq(NPP *npp, NPPROW *row); +/* test if row is packing inequality */ + +#define npp_sat_is_partn_eq _glp_npp_sat_is_partn_eq +int npp_sat_is_partn_eq(NPP *npp, NPPROW *row); +/* test if row is partitioning equality */ + +#define npp_sat_reverse_row _glp_npp_sat_reverse_row +int npp_sat_reverse_row(NPP *npp, NPPROW *row); +/* multiply both sides of row by -1 */ + +#define npp_sat_split_pack _glp_npp_sat_split_pack +NPPROW *npp_sat_split_pack(NPP *npp, NPPROW *row, int nnn); +/* split packing inequality */ + +#define npp_sat_encode_pack _glp_npp_sat_encode_pack +void npp_sat_encode_pack(NPP *npp, NPPROW *row); +/* encode packing inequality */ + +typedef struct NPPLIT NPPLIT; +typedef struct NPPLSE NPPLSE; +typedef struct NPPSED NPPSED; + +struct NPPLIT +{ /* literal (binary variable or its negation) */ + NPPCOL *col; + /* pointer to binary variable; NULL means constant false */ + int neg; + /* negation flag: + 0 - literal is variable (or constant false) + 1 - literal is negation of variable (or constant true) */ +}; + +struct NPPLSE +{ /* literal set element */ + NPPLIT lit; + /* literal */ + NPPLSE *next; + /* pointer to another element */ +}; + +struct NPPSED +{ /* summation encoding descriptor */ + /* this struct describes the equality + x + y + z = s + 2 * c, + which was encoded as CNF and included into the transformed + problem; here x and y are literals, z is either a literal or + constant zero, s and c are binary variables modeling, resp., + the low and high (carry) sum bits */ + NPPLIT x, y, z; + /* literals; if z.col = NULL, z is constant zero */ + NPPCOL *s, *c; + /* binary variables modeling the sum bits */ +}; + +#define npp_sat_encode_sum2 _glp_npp_sat_encode_sum2 +void npp_sat_encode_sum2(NPP *npp, NPPLSE *set, NPPSED *sed); +/* encode 2-bit summation */ + +#define npp_sat_encode_sum3 _glp_npp_sat_encode_sum3 +void npp_sat_encode_sum3(NPP *npp, NPPLSE *set, NPPSED *sed); +/* encode 3-bit summation */ + +#define npp_sat_encode_sum_ax _glp_npp_sat_encode_sum_ax +int npp_sat_encode_sum_ax(NPP *npp, NPPROW *row, NPPLIT y[]); +/* encode linear combination of 0-1 variables */ + +#define npp_sat_normalize_clause _glp_npp_sat_normalize_clause +int npp_sat_normalize_clause(NPP *npp, int size, NPPLIT lit[]); +/* normalize clause */ + +#define npp_sat_encode_clause _glp_npp_sat_encode_clause +NPPROW *npp_sat_encode_clause(NPP *npp, int size, NPPLIT lit[]); +/* translate clause to cover inequality */ + +#define npp_sat_encode_geq _glp_npp_sat_encode_geq +int npp_sat_encode_geq(NPP *npp, int n, NPPLIT y[], int rhs); +/* encode "not less than" constraint */ + +#define npp_sat_encode_leq _glp_npp_sat_encode_leq +int npp_sat_encode_leq(NPP *npp, int n, NPPLIT y[], int rhs); +/* encode "not greater than" constraint */ + +#define npp_sat_encode_row _glp_npp_sat_encode_row +int npp_sat_encode_row(NPP *npp, NPPROW *row); +/* encode constraint (row) of general type */ + +#define npp_sat_encode_prob _glp_npp_sat_encode_prob +int npp_sat_encode_prob(NPP *npp); +/* encode 0-1 feasibility problem */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpnpp01.c b/resources/3rdparty/glpk-4.57/src/glpnpp01.c new file mode 100644 index 000000000..9eb59f28e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpnpp01.c @@ -0,0 +1,938 @@ +/* glpnpp01.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpnpp.h" + +NPP *npp_create_wksp(void) +{ /* create LP/MIP preprocessor workspace */ + NPP *npp; + npp = xmalloc(sizeof(NPP)); + npp->orig_dir = 0; + npp->orig_m = npp->orig_n = npp->orig_nnz = 0; + npp->pool = dmp_create_pool(); + npp->name = npp->obj = NULL; + npp->c0 = 0.0; + npp->nrows = npp->ncols = 0; + npp->r_head = npp->r_tail = NULL; + npp->c_head = npp->c_tail = NULL; + npp->stack = dmp_create_pool(); + npp->top = NULL; +#if 0 /* 16/XII-2009 */ + memset(&npp->count, 0, sizeof(npp->count)); +#endif + npp->m = npp->n = npp->nnz = 0; + npp->row_ref = npp->col_ref = NULL; + npp->sol = npp->scaling = 0; + npp->p_stat = npp->d_stat = npp->t_stat = npp->i_stat = 0; + npp->r_stat = NULL; + /*npp->r_prim =*/ npp->r_pi = NULL; + npp->c_stat = NULL; + npp->c_value = /*npp->c_dual =*/ NULL; + return npp; +} + +void npp_insert_row(NPP *npp, NPPROW *row, int where) +{ /* insert row to the row list */ + if (where == 0) + { /* insert row to the beginning of the row list */ + row->prev = NULL; + row->next = npp->r_head; + if (row->next == NULL) + npp->r_tail = row; + else + row->next->prev = row; + npp->r_head = row; + } + else + { /* insert row to the end of the row list */ + row->prev = npp->r_tail; + row->next = NULL; + if (row->prev == NULL) + npp->r_head = row; + else + row->prev->next = row; + npp->r_tail = row; + } + return; +} + +void npp_remove_row(NPP *npp, NPPROW *row) +{ /* remove row from the row list */ + if (row->prev == NULL) + npp->r_head = row->next; + else + row->prev->next = row->next; + if (row->next == NULL) + npp->r_tail = row->prev; + else + row->next->prev = row->prev; + return; +} + +void npp_activate_row(NPP *npp, NPPROW *row) +{ /* make row active */ + if (!row->temp) + { row->temp = 1; + /* move the row to the beginning of the row list */ + npp_remove_row(npp, row); + npp_insert_row(npp, row, 0); + } + return; +} + +void npp_deactivate_row(NPP *npp, NPPROW *row) +{ /* make row inactive */ + if (row->temp) + { row->temp = 0; + /* move the row to the end of the row list */ + npp_remove_row(npp, row); + npp_insert_row(npp, row, 1); + } + return; +} + +void npp_insert_col(NPP *npp, NPPCOL *col, int where) +{ /* insert column to the column list */ + if (where == 0) + { /* insert column to the beginning of the column list */ + col->prev = NULL; + col->next = npp->c_head; + if (col->next == NULL) + npp->c_tail = col; + else + col->next->prev = col; + npp->c_head = col; + } + else + { /* insert column to the end of the column list */ + col->prev = npp->c_tail; + col->next = NULL; + if (col->prev == NULL) + npp->c_head = col; + else + col->prev->next = col; + npp->c_tail = col; + } + return; +} + +void npp_remove_col(NPP *npp, NPPCOL *col) +{ /* remove column from the column list */ + if (col->prev == NULL) + npp->c_head = col->next; + else + col->prev->next = col->next; + if (col->next == NULL) + npp->c_tail = col->prev; + else + col->next->prev = col->prev; + return; +} + +void npp_activate_col(NPP *npp, NPPCOL *col) +{ /* make column active */ + if (!col->temp) + { col->temp = 1; + /* move the column to the beginning of the column list */ + npp_remove_col(npp, col); + npp_insert_col(npp, col, 0); + } + return; +} + +void npp_deactivate_col(NPP *npp, NPPCOL *col) +{ /* make column inactive */ + if (col->temp) + { col->temp = 0; + /* move the column to the end of the column list */ + npp_remove_col(npp, col); + npp_insert_col(npp, col, 1); + } + return; +} + +NPPROW *npp_add_row(NPP *npp) +{ /* add new row to the current problem */ + NPPROW *row; + row = dmp_get_atom(npp->pool, sizeof(NPPROW)); + row->i = ++(npp->nrows); + row->name = NULL; + row->lb = -DBL_MAX, row->ub = +DBL_MAX; + row->ptr = NULL; + row->temp = 0; + npp_insert_row(npp, row, 1); + return row; +} + +NPPCOL *npp_add_col(NPP *npp) +{ /* add new column to the current problem */ + NPPCOL *col; + col = dmp_get_atom(npp->pool, sizeof(NPPCOL)); + col->j = ++(npp->ncols); + col->name = NULL; +#if 0 + col->kind = GLP_CV; +#else + col->is_int = 0; +#endif + col->lb = col->ub = col->coef = 0.0; + col->ptr = NULL; + col->temp = 0; + npp_insert_col(npp, col, 1); + return col; +} + +NPPAIJ *npp_add_aij(NPP *npp, NPPROW *row, NPPCOL *col, double val) +{ /* add new element to the constraint matrix */ + NPPAIJ *aij; + aij = dmp_get_atom(npp->pool, sizeof(NPPAIJ)); + aij->row = row; + aij->col = col; + aij->val = val; + aij->r_prev = NULL; + aij->r_next = row->ptr; + aij->c_prev = NULL; + aij->c_next = col->ptr; + if (aij->r_next != NULL) + aij->r_next->r_prev = aij; + if (aij->c_next != NULL) + aij->c_next->c_prev = aij; + row->ptr = col->ptr = aij; + return aij; +} + +int npp_row_nnz(NPP *npp, NPPROW *row) +{ /* count number of non-zero coefficients in row */ + NPPAIJ *aij; + int nnz; + xassert(npp == npp); + nnz = 0; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + nnz++; + return nnz; +} + +int npp_col_nnz(NPP *npp, NPPCOL *col) +{ /* count number of non-zero coefficients in column */ + NPPAIJ *aij; + int nnz; + xassert(npp == npp); + nnz = 0; + for (aij = col->ptr; aij != NULL; aij = aij->c_next) + nnz++; + return nnz; +} + +void *npp_push_tse(NPP *npp, int (*func)(NPP *npp, void *info), + int size) +{ /* push new entry to the transformation stack */ + NPPTSE *tse; + tse = dmp_get_atom(npp->stack, sizeof(NPPTSE)); + tse->func = func; + tse->info = dmp_get_atom(npp->stack, size); + tse->link = npp->top; + npp->top = tse; + return tse->info; +} + +#if 1 /* 23/XII-2009 */ +void npp_erase_row(NPP *npp, NPPROW *row) +{ /* erase row content to make it empty */ + NPPAIJ *aij; + while (row->ptr != NULL) + { aij = row->ptr; + row->ptr = aij->r_next; + if (aij->c_prev == NULL) + aij->col->ptr = aij->c_next; + else + aij->c_prev->c_next = aij->c_next; + if (aij->c_next == NULL) + ; + else + aij->c_next->c_prev = aij->c_prev; + dmp_free_atom(npp->pool, aij, sizeof(NPPAIJ)); + } + return; +} +#endif + +void npp_del_row(NPP *npp, NPPROW *row) +{ /* remove row from the current problem */ +#if 0 /* 23/XII-2009 */ + NPPAIJ *aij; +#endif + if (row->name != NULL) + dmp_free_atom(npp->pool, row->name, strlen(row->name)+1); +#if 0 /* 23/XII-2009 */ + while (row->ptr != NULL) + { aij = row->ptr; + row->ptr = aij->r_next; + if (aij->c_prev == NULL) + aij->col->ptr = aij->c_next; + else + aij->c_prev->c_next = aij->c_next; + if (aij->c_next == NULL) + ; + else + aij->c_next->c_prev = aij->c_prev; + dmp_free_atom(npp->pool, aij, sizeof(NPPAIJ)); + } +#else + npp_erase_row(npp, row); +#endif + npp_remove_row(npp, row); + dmp_free_atom(npp->pool, row, sizeof(NPPROW)); + return; +} + +void npp_del_col(NPP *npp, NPPCOL *col) +{ /* remove column from the current problem */ + NPPAIJ *aij; + if (col->name != NULL) + dmp_free_atom(npp->pool, col->name, strlen(col->name)+1); + while (col->ptr != NULL) + { aij = col->ptr; + col->ptr = aij->c_next; + if (aij->r_prev == NULL) + aij->row->ptr = aij->r_next; + else + aij->r_prev->r_next = aij->r_next; + if (aij->r_next == NULL) + ; + else + aij->r_next->r_prev = aij->r_prev; + dmp_free_atom(npp->pool, aij, sizeof(NPPAIJ)); + } + npp_remove_col(npp, col); + dmp_free_atom(npp->pool, col, sizeof(NPPCOL)); + return; +} + +void npp_del_aij(NPP *npp, NPPAIJ *aij) +{ /* remove element from the constraint matrix */ + if (aij->r_prev == NULL) + aij->row->ptr = aij->r_next; + else + aij->r_prev->r_next = aij->r_next; + if (aij->r_next == NULL) + ; + else + aij->r_next->r_prev = aij->r_prev; + if (aij->c_prev == NULL) + aij->col->ptr = aij->c_next; + else + aij->c_prev->c_next = aij->c_next; + if (aij->c_next == NULL) + ; + else + aij->c_next->c_prev = aij->c_prev; + dmp_free_atom(npp->pool, aij, sizeof(NPPAIJ)); + return; +} + +void npp_load_prob(NPP *npp, glp_prob *orig, int names, int sol, + int scaling) +{ /* load original problem into the preprocessor workspace */ + int m = orig->m; + int n = orig->n; + NPPROW **link; + int i, j; + double dir; + xassert(names == GLP_OFF || names == GLP_ON); + xassert(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP); + xassert(scaling == GLP_OFF || scaling == GLP_ON); + if (sol == GLP_MIP) xassert(!scaling); + npp->orig_dir = orig->dir; + if (npp->orig_dir == GLP_MIN) + dir = +1.0; + else if (npp->orig_dir == GLP_MAX) + dir = -1.0; + else + xassert(npp != npp); + npp->orig_m = m; + npp->orig_n = n; + npp->orig_nnz = orig->nnz; + if (names && orig->name != NULL) + { npp->name = dmp_get_atom(npp->pool, strlen(orig->name)+1); + strcpy(npp->name, orig->name); + } + if (names && orig->obj != NULL) + { npp->obj = dmp_get_atom(npp->pool, strlen(orig->obj)+1); + strcpy(npp->obj, orig->obj); + } + npp->c0 = dir * orig->c0; + /* load rows */ + link = xcalloc(1+m, sizeof(NPPROW *)); + for (i = 1; i <= m; i++) + { GLPROW *rrr = orig->row[i]; + NPPROW *row; + link[i] = row = npp_add_row(npp); + xassert(row->i == i); + if (names && rrr->name != NULL) + { row->name = dmp_get_atom(npp->pool, strlen(rrr->name)+1); + strcpy(row->name, rrr->name); + } + if (!scaling) + { if (rrr->type == GLP_FR) + row->lb = -DBL_MAX, row->ub = +DBL_MAX; + else if (rrr->type == GLP_LO) + row->lb = rrr->lb, row->ub = +DBL_MAX; + else if (rrr->type == GLP_UP) + row->lb = -DBL_MAX, row->ub = rrr->ub; + else if (rrr->type == GLP_DB) + row->lb = rrr->lb, row->ub = rrr->ub; + else if (rrr->type == GLP_FX) + row->lb = row->ub = rrr->lb; + else + xassert(rrr != rrr); + } + else + { double rii = rrr->rii; + if (rrr->type == GLP_FR) + row->lb = -DBL_MAX, row->ub = +DBL_MAX; + else if (rrr->type == GLP_LO) + row->lb = rrr->lb * rii, row->ub = +DBL_MAX; + else if (rrr->type == GLP_UP) + row->lb = -DBL_MAX, row->ub = rrr->ub * rii; + else if (rrr->type == GLP_DB) + row->lb = rrr->lb * rii, row->ub = rrr->ub * rii; + else if (rrr->type == GLP_FX) + row->lb = row->ub = rrr->lb * rii; + else + xassert(rrr != rrr); + } + } + /* load columns and constraint coefficients */ + for (j = 1; j <= n; j++) + { GLPCOL *ccc = orig->col[j]; + GLPAIJ *aaa; + NPPCOL *col; + col = npp_add_col(npp); + xassert(col->j == j); + if (names && ccc->name != NULL) + { col->name = dmp_get_atom(npp->pool, strlen(ccc->name)+1); + strcpy(col->name, ccc->name); + } + if (sol == GLP_MIP) +#if 0 + col->kind = ccc->kind; +#else + col->is_int = (char)(ccc->kind == GLP_IV); +#endif + if (!scaling) + { if (ccc->type == GLP_FR) + col->lb = -DBL_MAX, col->ub = +DBL_MAX; + else if (ccc->type == GLP_LO) + col->lb = ccc->lb, col->ub = +DBL_MAX; + else if (ccc->type == GLP_UP) + col->lb = -DBL_MAX, col->ub = ccc->ub; + else if (ccc->type == GLP_DB) + col->lb = ccc->lb, col->ub = ccc->ub; + else if (ccc->type == GLP_FX) + col->lb = col->ub = ccc->lb; + else + xassert(ccc != ccc); + col->coef = dir * ccc->coef; + for (aaa = ccc->ptr; aaa != NULL; aaa = aaa->c_next) + npp_add_aij(npp, link[aaa->row->i], col, aaa->val); + } + else + { double sjj = ccc->sjj; + if (ccc->type == GLP_FR) + col->lb = -DBL_MAX, col->ub = +DBL_MAX; + else if (ccc->type == GLP_LO) + col->lb = ccc->lb / sjj, col->ub = +DBL_MAX; + else if (ccc->type == GLP_UP) + col->lb = -DBL_MAX, col->ub = ccc->ub / sjj; + else if (ccc->type == GLP_DB) + col->lb = ccc->lb / sjj, col->ub = ccc->ub / sjj; + else if (ccc->type == GLP_FX) + col->lb = col->ub = ccc->lb / sjj; + else + xassert(ccc != ccc); + col->coef = dir * ccc->coef * sjj; + for (aaa = ccc->ptr; aaa != NULL; aaa = aaa->c_next) + npp_add_aij(npp, link[aaa->row->i], col, + aaa->row->rii * aaa->val * sjj); + } + } + xfree(link); + /* keep solution indicator and scaling option */ + npp->sol = sol; + npp->scaling = scaling; + return; +} + +void npp_build_prob(NPP *npp, glp_prob *prob) +{ /* build resultant (preprocessed) problem */ + NPPROW *row; + NPPCOL *col; + NPPAIJ *aij; + int i, j, type, len, *ind; + double dir, *val; + glp_erase_prob(prob); + glp_set_prob_name(prob, npp->name); + glp_set_obj_name(prob, npp->obj); + glp_set_obj_dir(prob, npp->orig_dir); + if (npp->orig_dir == GLP_MIN) + dir = +1.0; + else if (npp->orig_dir == GLP_MAX) + dir = -1.0; + else + xassert(npp != npp); + glp_set_obj_coef(prob, 0, dir * npp->c0); + /* build rows */ + for (row = npp->r_head; row != NULL; row = row->next) + { row->temp = i = glp_add_rows(prob, 1); + glp_set_row_name(prob, i, row->name); + if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) + type = GLP_FR; + else if (row->ub == +DBL_MAX) + type = GLP_LO; + else if (row->lb == -DBL_MAX) + type = GLP_UP; + else if (row->lb != row->ub) + type = GLP_DB; + else + type = GLP_FX; + glp_set_row_bnds(prob, i, type, row->lb, row->ub); + } + /* build columns and the constraint matrix */ + ind = xcalloc(1+prob->m, sizeof(int)); + val = xcalloc(1+prob->m, sizeof(double)); + for (col = npp->c_head; col != NULL; col = col->next) + { j = glp_add_cols(prob, 1); + glp_set_col_name(prob, j, col->name); +#if 0 + glp_set_col_kind(prob, j, col->kind); +#else + glp_set_col_kind(prob, j, col->is_int ? GLP_IV : GLP_CV); +#endif + if (col->lb == -DBL_MAX && col->ub == +DBL_MAX) + type = GLP_FR; + else if (col->ub == +DBL_MAX) + type = GLP_LO; + else if (col->lb == -DBL_MAX) + type = GLP_UP; + else if (col->lb != col->ub) + type = GLP_DB; + else + type = GLP_FX; + glp_set_col_bnds(prob, j, type, col->lb, col->ub); + glp_set_obj_coef(prob, j, dir * col->coef); + len = 0; + for (aij = col->ptr; aij != NULL; aij = aij->c_next) + { len++; + ind[len] = aij->row->temp; + val[len] = aij->val; + } + glp_set_mat_col(prob, j, len, ind, val); + } + xfree(ind); + xfree(val); + /* resultant problem has been built */ + npp->m = prob->m; + npp->n = prob->n; + npp->nnz = prob->nnz; + npp->row_ref = xcalloc(1+npp->m, sizeof(int)); + npp->col_ref = xcalloc(1+npp->n, sizeof(int)); + for (row = npp->r_head, i = 0; row != NULL; row = row->next) + npp->row_ref[++i] = row->i; + for (col = npp->c_head, j = 0; col != NULL; col = col->next) + npp->col_ref[++j] = col->j; + /* transformed problem segment is no longer needed */ + dmp_delete_pool(npp->pool), npp->pool = NULL; + npp->name = npp->obj = NULL; + npp->c0 = 0.0; + npp->r_head = npp->r_tail = NULL; + npp->c_head = npp->c_tail = NULL; + return; +} + +void npp_postprocess(NPP *npp, glp_prob *prob) +{ /* postprocess solution from the resultant problem */ + GLPROW *row; + GLPCOL *col; + NPPTSE *tse; + int i, j, k; + double dir; + xassert(npp->orig_dir == prob->dir); + if (npp->orig_dir == GLP_MIN) + dir = +1.0; + else if (npp->orig_dir == GLP_MAX) + dir = -1.0; + else + xassert(npp != npp); +#if 0 /* 11/VII-2013; due to call from ios_main */ + xassert(npp->m == prob->m); +#else + if (npp->sol != GLP_MIP) + xassert(npp->m == prob->m); +#endif + xassert(npp->n == prob->n); +#if 0 /* 11/VII-2013; due to call from ios_main */ + xassert(npp->nnz == prob->nnz); +#else + if (npp->sol != GLP_MIP) + xassert(npp->nnz == prob->nnz); +#endif + /* copy solution status */ + if (npp->sol == GLP_SOL) + { npp->p_stat = prob->pbs_stat; + npp->d_stat = prob->dbs_stat; + } + else if (npp->sol == GLP_IPT) + npp->t_stat = prob->ipt_stat; + else if (npp->sol == GLP_MIP) + npp->i_stat = prob->mip_stat; + else + xassert(npp != npp); + /* allocate solution arrays */ + if (npp->sol == GLP_SOL) + { if (npp->r_stat == NULL) + npp->r_stat = xcalloc(1+npp->nrows, sizeof(char)); + for (i = 1; i <= npp->nrows; i++) + npp->r_stat[i] = 0; + if (npp->c_stat == NULL) + npp->c_stat = xcalloc(1+npp->ncols, sizeof(char)); + for (j = 1; j <= npp->ncols; j++) + npp->c_stat[j] = 0; + } +#if 0 + if (npp->r_prim == NULL) + npp->r_prim = xcalloc(1+npp->nrows, sizeof(double)); + for (i = 1; i <= npp->nrows; i++) + npp->r_prim[i] = DBL_MAX; +#endif + if (npp->c_value == NULL) + npp->c_value = xcalloc(1+npp->ncols, sizeof(double)); + for (j = 1; j <= npp->ncols; j++) + npp->c_value[j] = DBL_MAX; + if (npp->sol != GLP_MIP) + { if (npp->r_pi == NULL) + npp->r_pi = xcalloc(1+npp->nrows, sizeof(double)); + for (i = 1; i <= npp->nrows; i++) + npp->r_pi[i] = DBL_MAX; +#if 0 + if (npp->c_dual == NULL) + npp->c_dual = xcalloc(1+npp->ncols, sizeof(double)); + for (j = 1; j <= npp->ncols; j++) + npp->c_dual[j] = DBL_MAX; +#endif + } + /* copy solution components from the resultant problem */ + if (npp->sol == GLP_SOL) + { for (i = 1; i <= npp->m; i++) + { row = prob->row[i]; + k = npp->row_ref[i]; + npp->r_stat[k] = (char)row->stat; + /*npp->r_prim[k] = row->prim;*/ + npp->r_pi[k] = dir * row->dual; + } + for (j = 1; j <= npp->n; j++) + { col = prob->col[j]; + k = npp->col_ref[j]; + npp->c_stat[k] = (char)col->stat; + npp->c_value[k] = col->prim; + /*npp->c_dual[k] = dir * col->dual;*/ + } + } + else if (npp->sol == GLP_IPT) + { for (i = 1; i <= npp->m; i++) + { row = prob->row[i]; + k = npp->row_ref[i]; + /*npp->r_prim[k] = row->pval;*/ + npp->r_pi[k] = dir * row->dval; + } + for (j = 1; j <= npp->n; j++) + { col = prob->col[j]; + k = npp->col_ref[j]; + npp->c_value[k] = col->pval; + /*npp->c_dual[k] = dir * col->dval;*/ + } + } + else if (npp->sol == GLP_MIP) + { +#if 0 + for (i = 1; i <= npp->m; i++) + { row = prob->row[i]; + k = npp->row_ref[i]; + /*npp->r_prim[k] = row->mipx;*/ + } +#endif + for (j = 1; j <= npp->n; j++) + { col = prob->col[j]; + k = npp->col_ref[j]; + npp->c_value[k] = col->mipx; + } + } + else + xassert(npp != npp); + /* perform postprocessing to construct solution to the original + problem */ + for (tse = npp->top; tse != NULL; tse = tse->link) + { xassert(tse->func != NULL); + xassert(tse->func(npp, tse->info) == 0); + } + return; +} + +void npp_unload_sol(NPP *npp, glp_prob *orig) +{ /* store solution to the original problem */ + GLPROW *row; + GLPCOL *col; + int i, j; + double dir; + xassert(npp->orig_dir == orig->dir); + if (npp->orig_dir == GLP_MIN) + dir = +1.0; + else if (npp->orig_dir == GLP_MAX) + dir = -1.0; + else + xassert(npp != npp); + xassert(npp->orig_m == orig->m); + xassert(npp->orig_n == orig->n); + xassert(npp->orig_nnz == orig->nnz); + if (npp->sol == GLP_SOL) + { /* store basic solution */ + orig->valid = 0; + orig->pbs_stat = npp->p_stat; + orig->dbs_stat = npp->d_stat; + orig->obj_val = orig->c0; + orig->some = 0; + for (i = 1; i <= orig->m; i++) + { row = orig->row[i]; + row->stat = npp->r_stat[i]; + if (!npp->scaling) + { /*row->prim = npp->r_prim[i];*/ + row->dual = dir * npp->r_pi[i]; + } + else + { /*row->prim = npp->r_prim[i] / row->rii;*/ + row->dual = dir * npp->r_pi[i] * row->rii; + } + if (row->stat == GLP_BS) + row->dual = 0.0; + else if (row->stat == GLP_NL) + { xassert(row->type == GLP_LO || row->type == GLP_DB); + row->prim = row->lb; + } + else if (row->stat == GLP_NU) + { xassert(row->type == GLP_UP || row->type == GLP_DB); + row->prim = row->ub; + } + else if (row->stat == GLP_NF) + { xassert(row->type == GLP_FR); + row->prim = 0.0; + } + else if (row->stat == GLP_NS) + { xassert(row->type == GLP_FX); + row->prim = row->lb; + } + else + xassert(row != row); + } + for (j = 1; j <= orig->n; j++) + { col = orig->col[j]; + col->stat = npp->c_stat[j]; + if (!npp->scaling) + { col->prim = npp->c_value[j]; + /*col->dual = dir * npp->c_dual[j];*/ + } + else + { col->prim = npp->c_value[j] * col->sjj; + /*col->dual = dir * npp->c_dual[j] / col->sjj;*/ + } + if (col->stat == GLP_BS) + col->dual = 0.0; +#if 1 + else if (col->stat == GLP_NL) + { xassert(col->type == GLP_LO || col->type == GLP_DB); + col->prim = col->lb; + } + else if (col->stat == GLP_NU) + { xassert(col->type == GLP_UP || col->type == GLP_DB); + col->prim = col->ub; + } + else if (col->stat == GLP_NF) + { xassert(col->type == GLP_FR); + col->prim = 0.0; + } + else if (col->stat == GLP_NS) + { xassert(col->type == GLP_FX); + col->prim = col->lb; + } + else + xassert(col != col); +#endif + orig->obj_val += col->coef * col->prim; + } +#if 1 + /* compute primal values of inactive rows */ + for (i = 1; i <= orig->m; i++) + { row = orig->row[i]; + if (row->stat == GLP_BS) + { GLPAIJ *aij; + double temp; + temp = 0.0; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + temp += aij->val * aij->col->prim; + row->prim = temp; + } + } + /* compute reduced costs of active columns */ + for (j = 1; j <= orig->n; j++) + { col = orig->col[j]; + if (col->stat != GLP_BS) + { GLPAIJ *aij; + double temp; + temp = col->coef; + for (aij = col->ptr; aij != NULL; aij = aij->c_next) + temp -= aij->val * aij->row->dual; + col->dual = temp; + } + } +#endif + } + else if (npp->sol == GLP_IPT) + { /* store interior-point solution */ + orig->ipt_stat = npp->t_stat; + orig->ipt_obj = orig->c0; + for (i = 1; i <= orig->m; i++) + { row = orig->row[i]; + if (!npp->scaling) + { /*row->pval = npp->r_prim[i];*/ + row->dval = dir * npp->r_pi[i]; + } + else + { /*row->pval = npp->r_prim[i] / row->rii;*/ + row->dval = dir * npp->r_pi[i] * row->rii; + } + } + for (j = 1; j <= orig->n; j++) + { col = orig->col[j]; + if (!npp->scaling) + { col->pval = npp->c_value[j]; + /*col->dval = dir * npp->c_dual[j];*/ + } + else + { col->pval = npp->c_value[j] * col->sjj; + /*col->dval = dir * npp->c_dual[j] / col->sjj;*/ + } + orig->ipt_obj += col->coef * col->pval; + } +#if 1 + /* compute row primal values */ + for (i = 1; i <= orig->m; i++) + { row = orig->row[i]; + { GLPAIJ *aij; + double temp; + temp = 0.0; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + temp += aij->val * aij->col->pval; + row->pval = temp; + } + } + /* compute column dual values */ + for (j = 1; j <= orig->n; j++) + { col = orig->col[j]; + { GLPAIJ *aij; + double temp; + temp = col->coef; + for (aij = col->ptr; aij != NULL; aij = aij->c_next) + temp -= aij->val * aij->row->dval; + col->dval = temp; + } + } +#endif + } + else if (npp->sol == GLP_MIP) + { /* store MIP solution */ + xassert(!npp->scaling); + orig->mip_stat = npp->i_stat; + orig->mip_obj = orig->c0; +#if 0 + for (i = 1; i <= orig->m; i++) + { row = orig->row[i]; + /*row->mipx = npp->r_prim[i];*/ + } +#endif + for (j = 1; j <= orig->n; j++) + { col = orig->col[j]; + col->mipx = npp->c_value[j]; + if (col->kind == GLP_IV) + xassert(col->mipx == floor(col->mipx)); + orig->mip_obj += col->coef * col->mipx; + } +#if 1 + /* compute row primal values */ + for (i = 1; i <= orig->m; i++) + { row = orig->row[i]; + { GLPAIJ *aij; + double temp; + temp = 0.0; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + temp += aij->val * aij->col->mipx; + row->mipx = temp; + } + } +#endif + } + else + xassert(npp != npp); + return; +} + +void npp_delete_wksp(NPP *npp) +{ /* delete LP/MIP preprocessor workspace */ + if (npp->pool != NULL) + dmp_delete_pool(npp->pool); + if (npp->stack != NULL) + dmp_delete_pool(npp->stack); + if (npp->row_ref != NULL) + xfree(npp->row_ref); + if (npp->col_ref != NULL) + xfree(npp->col_ref); + if (npp->r_stat != NULL) + xfree(npp->r_stat); +#if 0 + if (npp->r_prim != NULL) + xfree(npp->r_prim); +#endif + if (npp->r_pi != NULL) + xfree(npp->r_pi); + if (npp->c_stat != NULL) + xfree(npp->c_stat); + if (npp->c_value != NULL) + xfree(npp->c_value); +#if 0 + if (npp->c_dual != NULL) + xfree(npp->c_dual); +#endif + xfree(npp); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpnpp02.c b/resources/3rdparty/glpk-4.57/src/glpnpp02.c new file mode 100644 index 000000000..ec4a455b4 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpnpp02.c @@ -0,0 +1,1434 @@ +/* glpnpp02.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpnpp.h" + +/*********************************************************************** +* NAME +* +* npp_free_row - process free (unbounded) row +* +* SYNOPSIS +* +* #include "glpnpp.h" +* void npp_free_row(NPP *npp, NPPROW *p); +* +* DESCRIPTION +* +* The routine npp_free_row processes row p, which is free (i.e. has +* no finite bounds): +* +* -inf < sum a[p,j] x[j] < +inf. (1) +* j +* +* PROBLEM TRANSFORMATION +* +* Constraint (1) cannot be active, so it is redundant and can be +* removed from the original problem. +* +* Removing row p leads to removing a column of multiplier pi[p] for +* this row in the dual system. Since row p has no bounds, pi[p] = 0, +* so removing the column does not affect the dual solution. +* +* RECOVERING BASIC SOLUTION +* +* In solution to the original problem row p is inactive constraint, +* so it is assigned status GLP_BS, and multiplier pi[p] is assigned +* zero value. +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* In solution to the original problem row p is inactive constraint, +* so its multiplier pi[p] is assigned zero value. +* +* RECOVERING MIP SOLUTION +* +* None needed. */ + +struct free_row +{ /* free (unbounded) row */ + int p; + /* row reference number */ +}; + +static int rcv_free_row(NPP *npp, void *info); + +void npp_free_row(NPP *npp, NPPROW *p) +{ /* process free (unbounded) row */ + struct free_row *info; + /* the row must be free */ + xassert(p->lb == -DBL_MAX && p->ub == +DBL_MAX); + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_free_row, sizeof(struct free_row)); + info->p = p->i; + /* remove the row from the problem */ + npp_del_row(npp, p); + return; +} + +static int rcv_free_row(NPP *npp, void *_info) +{ /* recover free (unbounded) row */ + struct free_row *info = _info; + if (npp->sol == GLP_SOL) + npp->r_stat[info->p] = GLP_BS; + if (npp->sol != GLP_MIP) + npp->r_pi[info->p] = 0.0; + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_geq_row - process row of 'not less than' type +* +* SYNOPSIS +* +* #include "glpnpp.h" +* void npp_geq_row(NPP *npp, NPPROW *p); +* +* DESCRIPTION +* +* The routine npp_geq_row processes row p, which is 'not less than' +* inequality constraint: +* +* L[p] <= sum a[p,j] x[j] (<= U[p]), (1) +* j +* +* where L[p] < U[p], and upper bound may not exist (U[p] = +oo). +* +* PROBLEM TRANSFORMATION +* +* Constraint (1) can be replaced by equality constraint: +* +* sum a[p,j] x[j] - s = L[p], (2) +* j +* +* where +* +* 0 <= s (<= U[p] - L[p]) (3) +* +* is a non-negative surplus variable. +* +* Since in the primal system there appears column s having the only +* non-zero coefficient in row p, in the dual system there appears a +* new row: +* +* (-1) pi[p] + lambda = 0, (4) +* +* where (-1) is coefficient of column s in row p, pi[p] is multiplier +* of row p, lambda is multiplier of column q, 0 is coefficient of +* column s in the objective row. +* +* RECOVERING BASIC SOLUTION +* +* Status of row p in solution to the original problem is determined +* by its status and status of column q in solution to the transformed +* problem as follows: +* +* +--------------------------------------+------------------+ +* | Transformed problem | Original problem | +* +-----------------+--------------------+------------------+ +* | Status of row p | Status of column s | Status of row p | +* +-----------------+--------------------+------------------+ +* | GLP_BS | GLP_BS | N/A | +* | GLP_BS | GLP_NL | GLP_BS | +* | GLP_BS | GLP_NU | GLP_BS | +* | GLP_NS | GLP_BS | GLP_BS | +* | GLP_NS | GLP_NL | GLP_NL | +* | GLP_NS | GLP_NU | GLP_NU | +* +-----------------+--------------------+------------------+ +* +* Value of row multiplier pi[p] in solution to the original problem +* is the same as in solution to the transformed problem. +* +* 1. In solution to the transformed problem row p and column q cannot +* be basic at the same time; otherwise the basis matrix would have +* two linear dependent columns: unity column of auxiliary variable +* of row p and unity column of variable s. +* +* 2. Though in the transformed problem row p is equality constraint, +* it may be basic due to primal degenerate solution. +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* Value of row multiplier pi[p] in solution to the original problem +* is the same as in solution to the transformed problem. +* +* RECOVERING MIP SOLUTION +* +* None needed. */ + +struct ineq_row +{ /* inequality constraint row */ + int p; + /* row reference number */ + int s; + /* column reference number for slack/surplus variable */ +}; + +static int rcv_geq_row(NPP *npp, void *info); + +void npp_geq_row(NPP *npp, NPPROW *p) +{ /* process row of 'not less than' type */ + struct ineq_row *info; + NPPCOL *s; + /* the row must have lower bound */ + xassert(p->lb != -DBL_MAX); + xassert(p->lb < p->ub); + /* create column for surplus variable */ + s = npp_add_col(npp); + s->lb = 0.0; + s->ub = (p->ub == +DBL_MAX ? +DBL_MAX : p->ub - p->lb); + /* and add it to the transformed problem */ + npp_add_aij(npp, p, s, -1.0); + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_geq_row, sizeof(struct ineq_row)); + info->p = p->i; + info->s = s->j; + /* replace the row by equality constraint */ + p->ub = p->lb; + return; +} + +static int rcv_geq_row(NPP *npp, void *_info) +{ /* recover row of 'not less than' type */ + struct ineq_row *info = _info; + if (npp->sol == GLP_SOL) + { if (npp->r_stat[info->p] == GLP_BS) + { if (npp->c_stat[info->s] == GLP_BS) + { npp_error(); + return 1; + } + else if (npp->c_stat[info->s] == GLP_NL || + npp->c_stat[info->s] == GLP_NU) + npp->r_stat[info->p] = GLP_BS; + else + { npp_error(); + return 1; + } + } + else if (npp->r_stat[info->p] == GLP_NS) + { if (npp->c_stat[info->s] == GLP_BS) + npp->r_stat[info->p] = GLP_BS; + else if (npp->c_stat[info->s] == GLP_NL) + npp->r_stat[info->p] = GLP_NL; + else if (npp->c_stat[info->s] == GLP_NU) + npp->r_stat[info->p] = GLP_NU; + else + { npp_error(); + return 1; + } + } + else + { npp_error(); + return 1; + } + } + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_leq_row - process row of 'not greater than' type +* +* SYNOPSIS +* +* #include "glpnpp.h" +* void npp_leq_row(NPP *npp, NPPROW *p); +* +* DESCRIPTION +* +* The routine npp_leq_row processes row p, which is 'not greater than' +* inequality constraint: +* +* (L[p] <=) sum a[p,j] x[j] <= U[p], (1) +* j +* +* where L[p] < U[p], and lower bound may not exist (L[p] = +oo). +* +* PROBLEM TRANSFORMATION +* +* Constraint (1) can be replaced by equality constraint: +* +* sum a[p,j] x[j] + s = L[p], (2) +* j +* +* where +* +* 0 <= s (<= U[p] - L[p]) (3) +* +* is a non-negative slack variable. +* +* Since in the primal system there appears column s having the only +* non-zero coefficient in row p, in the dual system there appears a +* new row: +* +* (+1) pi[p] + lambda = 0, (4) +* +* where (+1) is coefficient of column s in row p, pi[p] is multiplier +* of row p, lambda is multiplier of column q, 0 is coefficient of +* column s in the objective row. +* +* RECOVERING BASIC SOLUTION +* +* Status of row p in solution to the original problem is determined +* by its status and status of column q in solution to the transformed +* problem as follows: +* +* +--------------------------------------+------------------+ +* | Transformed problem | Original problem | +* +-----------------+--------------------+------------------+ +* | Status of row p | Status of column s | Status of row p | +* +-----------------+--------------------+------------------+ +* | GLP_BS | GLP_BS | N/A | +* | GLP_BS | GLP_NL | GLP_BS | +* | GLP_BS | GLP_NU | GLP_BS | +* | GLP_NS | GLP_BS | GLP_BS | +* | GLP_NS | GLP_NL | GLP_NU | +* | GLP_NS | GLP_NU | GLP_NL | +* +-----------------+--------------------+------------------+ +* +* Value of row multiplier pi[p] in solution to the original problem +* is the same as in solution to the transformed problem. +* +* 1. In solution to the transformed problem row p and column q cannot +* be basic at the same time; otherwise the basis matrix would have +* two linear dependent columns: unity column of auxiliary variable +* of row p and unity column of variable s. +* +* 2. Though in the transformed problem row p is equality constraint, +* it may be basic due to primal degeneracy. +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* Value of row multiplier pi[p] in solution to the original problem +* is the same as in solution to the transformed problem. +* +* RECOVERING MIP SOLUTION +* +* None needed. */ + +static int rcv_leq_row(NPP *npp, void *info); + +void npp_leq_row(NPP *npp, NPPROW *p) +{ /* process row of 'not greater than' type */ + struct ineq_row *info; + NPPCOL *s; + /* the row must have upper bound */ + xassert(p->ub != +DBL_MAX); + xassert(p->lb < p->ub); + /* create column for slack variable */ + s = npp_add_col(npp); + s->lb = 0.0; + s->ub = (p->lb == -DBL_MAX ? +DBL_MAX : p->ub - p->lb); + /* and add it to the transformed problem */ + npp_add_aij(npp, p, s, +1.0); + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_leq_row, sizeof(struct ineq_row)); + info->p = p->i; + info->s = s->j; + /* replace the row by equality constraint */ + p->lb = p->ub; + return; +} + +static int rcv_leq_row(NPP *npp, void *_info) +{ /* recover row of 'not greater than' type */ + struct ineq_row *info = _info; + if (npp->sol == GLP_SOL) + { if (npp->r_stat[info->p] == GLP_BS) + { if (npp->c_stat[info->s] == GLP_BS) + { npp_error(); + return 1; + } + else if (npp->c_stat[info->s] == GLP_NL || + npp->c_stat[info->s] == GLP_NU) + npp->r_stat[info->p] = GLP_BS; + else + { npp_error(); + return 1; + } + } + else if (npp->r_stat[info->p] == GLP_NS) + { if (npp->c_stat[info->s] == GLP_BS) + npp->r_stat[info->p] = GLP_BS; + else if (npp->c_stat[info->s] == GLP_NL) + npp->r_stat[info->p] = GLP_NU; + else if (npp->c_stat[info->s] == GLP_NU) + npp->r_stat[info->p] = GLP_NL; + else + { npp_error(); + return 1; + } + } + else + { npp_error(); + return 1; + } + } + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_free_col - process free (unbounded) column +* +* SYNOPSIS +* +* #include "glpnpp.h" +* void npp_free_col(NPP *npp, NPPCOL *q); +* +* DESCRIPTION +* +* The routine npp_free_col processes column q, which is free (i.e. has +* no finite bounds): +* +* -oo < x[q] < +oo. (1) +* +* PROBLEM TRANSFORMATION +* +* Free (unbounded) variable can be replaced by the difference of two +* non-negative variables: +* +* x[q] = s' - s'', s', s'' >= 0. (2) +* +* Assuming that in the transformed problem x[q] becomes s', +* transformation (2) causes new column s'' to appear, which differs +* from column s' only in the sign of coefficients in constraint and +* objective rows. Thus, if in the dual system the following row +* corresponds to column s': +* +* sum a[i,q] pi[i] + lambda' = c[q], (3) +* i +* +* the row which corresponds to column s'' is the following: +* +* sum (-a[i,q]) pi[i] + lambda'' = -c[q]. (4) +* i +* +* Then from (3) and (4) it follows that: +* +* lambda' + lambda'' = 0 => lambda' = lmabda'' = 0, (5) +* +* where lambda' and lambda'' are multipliers for columns s' and s'', +* resp. +* +* RECOVERING BASIC SOLUTION +* +* With respect to (5) status of column q in solution to the original +* problem is determined by statuses of columns s' and s'' in solution +* to the transformed problem as follows: +* +* +--------------------------------------+------------------+ +* | Transformed problem | Original problem | +* +------------------+-------------------+------------------+ +* | Status of col s' | Status of col s'' | Status of col q | +* +------------------+-------------------+------------------+ +* | GLP_BS | GLP_BS | N/A | +* | GLP_BS | GLP_NL | GLP_BS | +* | GLP_NL | GLP_BS | GLP_BS | +* | GLP_NL | GLP_NL | GLP_NF | +* +------------------+-------------------+------------------+ +* +* Value of column q is computed with formula (2). +* +* 1. In solution to the transformed problem columns s' and s'' cannot +* be basic at the same time, because they differ only in the sign, +* hence, are linear dependent. +* +* 2. Though column q is free, it can be non-basic due to dual +* degeneracy. +* +* 3. If column q is integral, columns s' and s'' are also integral. +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* Value of column q is computed with formula (2). +* +* RECOVERING MIP SOLUTION +* +* Value of column q is computed with formula (2). */ + +struct free_col +{ /* free (unbounded) column */ + int q; + /* column reference number for variables x[q] and s' */ + int s; + /* column reference number for variable s'' */ +}; + +static int rcv_free_col(NPP *npp, void *info); + +void npp_free_col(NPP *npp, NPPCOL *q) +{ /* process free (unbounded) column */ + struct free_col *info; + NPPCOL *s; + NPPAIJ *aij; + /* the column must be free */ + xassert(q->lb == -DBL_MAX && q->ub == +DBL_MAX); + /* variable x[q] becomes s' */ + q->lb = 0.0, q->ub = +DBL_MAX; + /* create variable s'' */ + s = npp_add_col(npp); + s->is_int = q->is_int; + s->lb = 0.0, s->ub = +DBL_MAX; + /* duplicate objective coefficient */ + s->coef = -q->coef; + /* duplicate column of the constraint matrix */ + for (aij = q->ptr; aij != NULL; aij = aij->c_next) + npp_add_aij(npp, aij->row, s, -aij->val); + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_free_col, sizeof(struct free_col)); + info->q = q->j; + info->s = s->j; + return; +} + +static int rcv_free_col(NPP *npp, void *_info) +{ /* recover free (unbounded) column */ + struct free_col *info = _info; + if (npp->sol == GLP_SOL) + { if (npp->c_stat[info->q] == GLP_BS) + { if (npp->c_stat[info->s] == GLP_BS) + { npp_error(); + return 1; + } + else if (npp->c_stat[info->s] == GLP_NL) + npp->c_stat[info->q] = GLP_BS; + else + { npp_error(); + return -1; + } + } + else if (npp->c_stat[info->q] == GLP_NL) + { if (npp->c_stat[info->s] == GLP_BS) + npp->c_stat[info->q] = GLP_BS; + else if (npp->c_stat[info->s] == GLP_NL) + npp->c_stat[info->q] = GLP_NF; + else + { npp_error(); + return -1; + } + } + else + { npp_error(); + return -1; + } + } + /* compute value of x[q] with formula (2) */ + npp->c_value[info->q] -= npp->c_value[info->s]; + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_lbnd_col - process column with (non-zero) lower bound +* +* SYNOPSIS +* +* #include "glpnpp.h" +* void npp_lbnd_col(NPP *npp, NPPCOL *q); +* +* DESCRIPTION +* +* The routine npp_lbnd_col processes column q, which has (non-zero) +* lower bound: +* +* l[q] <= x[q] (<= u[q]), (1) +* +* where l[q] < u[q], and upper bound may not exist (u[q] = +oo). +* +* PROBLEM TRANSFORMATION +* +* Column q can be replaced as follows: +* +* x[q] = l[q] + s, (2) +* +* where +* +* 0 <= s (<= u[q] - l[q]) (3) +* +* is a non-negative variable. +* +* Substituting x[q] from (2) into the objective row, we have: +* +* z = sum c[j] x[j] + c0 = +* j +* +* = sum c[j] x[j] + c[q] x[q] + c0 = +* j!=q +* +* = sum c[j] x[j] + c[q] (l[q] + s) + c0 = +* j!=q +* +* = sum c[j] x[j] + c[q] s + c~0, +* +* where +* +* c~0 = c0 + c[q] l[q] (4) +* +* is the constant term of the objective in the transformed problem. +* Similarly, substituting x[q] into constraint row i, we have: +* +* L[i] <= sum a[i,j] x[j] <= U[i] ==> +* j +* +* L[i] <= sum a[i,j] x[j] + a[i,q] x[q] <= U[i] ==> +* j!=q +* +* L[i] <= sum a[i,j] x[j] + a[i,q] (l[q] + s) <= U[i] ==> +* j!=q +* +* L~[i] <= sum a[i,j] x[j] + a[i,q] s <= U~[i], +* j!=q +* +* where +* +* L~[i] = L[i] - a[i,q] l[q], U~[i] = U[i] - a[i,q] l[q] (5) +* +* are lower and upper bounds of row i in the transformed problem, +* resp. +* +* Transformation (2) does not affect the dual system. +* +* RECOVERING BASIC SOLUTION +* +* Status of column q in solution to the original problem is the same +* as in solution to the transformed problem (GLP_BS, GLP_NL or GLP_NU). +* Value of column q is computed with formula (2). +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* Value of column q is computed with formula (2). +* +* RECOVERING MIP SOLUTION +* +* Value of column q is computed with formula (2). */ + +struct bnd_col +{ /* bounded column */ + int q; + /* column reference number for variables x[q] and s */ + double bnd; + /* lower/upper bound l[q] or u[q] */ +}; + +static int rcv_lbnd_col(NPP *npp, void *info); + +void npp_lbnd_col(NPP *npp, NPPCOL *q) +{ /* process column with (non-zero) lower bound */ + struct bnd_col *info; + NPPROW *i; + NPPAIJ *aij; + /* the column must have non-zero lower bound */ + xassert(q->lb != 0.0); + xassert(q->lb != -DBL_MAX); + xassert(q->lb < q->ub); + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_lbnd_col, sizeof(struct bnd_col)); + info->q = q->j; + info->bnd = q->lb; + /* substitute x[q] into objective row */ + npp->c0 += q->coef * q->lb; + /* substitute x[q] into constraint rows */ + for (aij = q->ptr; aij != NULL; aij = aij->c_next) + { i = aij->row; + if (i->lb == i->ub) + i->ub = (i->lb -= aij->val * q->lb); + else + { if (i->lb != -DBL_MAX) + i->lb -= aij->val * q->lb; + if (i->ub != +DBL_MAX) + i->ub -= aij->val * q->lb; + } + } + /* column x[q] becomes column s */ + if (q->ub != +DBL_MAX) + q->ub -= q->lb; + q->lb = 0.0; + return; +} + +static int rcv_lbnd_col(NPP *npp, void *_info) +{ /* recover column with (non-zero) lower bound */ + struct bnd_col *info = _info; + if (npp->sol == GLP_SOL) + { if (npp->c_stat[info->q] == GLP_BS || + npp->c_stat[info->q] == GLP_NL || + npp->c_stat[info->q] == GLP_NU) + npp->c_stat[info->q] = npp->c_stat[info->q]; + else + { npp_error(); + return 1; + } + } + /* compute value of x[q] with formula (2) */ + npp->c_value[info->q] = info->bnd + npp->c_value[info->q]; + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_ubnd_col - process column with upper bound +* +* SYNOPSIS +* +* #include "glpnpp.h" +* void npp_ubnd_col(NPP *npp, NPPCOL *q); +* +* DESCRIPTION +* +* The routine npp_ubnd_col processes column q, which has upper bound: +* +* (l[q] <=) x[q] <= u[q], (1) +* +* where l[q] < u[q], and lower bound may not exist (l[q] = -oo). +* +* PROBLEM TRANSFORMATION +* +* Column q can be replaced as follows: +* +* x[q] = u[q] - s, (2) +* +* where +* +* 0 <= s (<= u[q] - l[q]) (3) +* +* is a non-negative variable. +* +* Substituting x[q] from (2) into the objective row, we have: +* +* z = sum c[j] x[j] + c0 = +* j +* +* = sum c[j] x[j] + c[q] x[q] + c0 = +* j!=q +* +* = sum c[j] x[j] + c[q] (u[q] - s) + c0 = +* j!=q +* +* = sum c[j] x[j] - c[q] s + c~0, +* +* where +* +* c~0 = c0 + c[q] u[q] (4) +* +* is the constant term of the objective in the transformed problem. +* Similarly, substituting x[q] into constraint row i, we have: +* +* L[i] <= sum a[i,j] x[j] <= U[i] ==> +* j +* +* L[i] <= sum a[i,j] x[j] + a[i,q] x[q] <= U[i] ==> +* j!=q +* +* L[i] <= sum a[i,j] x[j] + a[i,q] (u[q] - s) <= U[i] ==> +* j!=q +* +* L~[i] <= sum a[i,j] x[j] - a[i,q] s <= U~[i], +* j!=q +* +* where +* +* L~[i] = L[i] - a[i,q] u[q], U~[i] = U[i] - a[i,q] u[q] (5) +* +* are lower and upper bounds of row i in the transformed problem, +* resp. +* +* Note that in the transformed problem coefficients c[q] and a[i,q] +* change their sign. Thus, the row of the dual system corresponding to +* column q: +* +* sum a[i,q] pi[i] + lambda[q] = c[q] (6) +* i +* +* in the transformed problem becomes the following: +* +* sum (-a[i,q]) pi[i] + lambda[s] = -c[q]. (7) +* i +* +* Therefore: +* +* lambda[q] = - lambda[s], (8) +* +* where lambda[q] is multiplier for column q, lambda[s] is multiplier +* for column s. +* +* RECOVERING BASIC SOLUTION +* +* With respect to (8) status of column q in solution to the original +* problem is determined by status of column s in solution to the +* transformed problem as follows: +* +* +-----------------------+--------------------+ +* | Status of column s | Status of column q | +* | (transformed problem) | (original problem) | +* +-----------------------+--------------------+ +* | GLP_BS | GLP_BS | +* | GLP_NL | GLP_NU | +* | GLP_NU | GLP_NL | +* +-----------------------+--------------------+ +* +* Value of column q is computed with formula (2). +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* Value of column q is computed with formula (2). +* +* RECOVERING MIP SOLUTION +* +* Value of column q is computed with formula (2). */ + +static int rcv_ubnd_col(NPP *npp, void *info); + +void npp_ubnd_col(NPP *npp, NPPCOL *q) +{ /* process column with upper bound */ + struct bnd_col *info; + NPPROW *i; + NPPAIJ *aij; + /* the column must have upper bound */ + xassert(q->ub != +DBL_MAX); + xassert(q->lb < q->ub); + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_ubnd_col, sizeof(struct bnd_col)); + info->q = q->j; + info->bnd = q->ub; + /* substitute x[q] into objective row */ + npp->c0 += q->coef * q->ub; + q->coef = -q->coef; + /* substitute x[q] into constraint rows */ + for (aij = q->ptr; aij != NULL; aij = aij->c_next) + { i = aij->row; + if (i->lb == i->ub) + i->ub = (i->lb -= aij->val * q->ub); + else + { if (i->lb != -DBL_MAX) + i->lb -= aij->val * q->ub; + if (i->ub != +DBL_MAX) + i->ub -= aij->val * q->ub; + } + aij->val = -aij->val; + } + /* column x[q] becomes column s */ + if (q->lb != -DBL_MAX) + q->ub -= q->lb; + else + q->ub = +DBL_MAX; + q->lb = 0.0; + return; +} + +static int rcv_ubnd_col(NPP *npp, void *_info) +{ /* recover column with upper bound */ + struct bnd_col *info = _info; + if (npp->sol == GLP_BS) + { if (npp->c_stat[info->q] == GLP_BS) + npp->c_stat[info->q] = GLP_BS; + else if (npp->c_stat[info->q] == GLP_NL) + npp->c_stat[info->q] = GLP_NU; + else if (npp->c_stat[info->q] == GLP_NU) + npp->c_stat[info->q] = GLP_NL; + else + { npp_error(); + return 1; + } + } + /* compute value of x[q] with formula (2) */ + npp->c_value[info->q] = info->bnd - npp->c_value[info->q]; + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_dbnd_col - process non-negative column with upper bound +* +* SYNOPSIS +* +* #include "glpnpp.h" +* void npp_dbnd_col(NPP *npp, NPPCOL *q); +* +* DESCRIPTION +* +* The routine npp_dbnd_col processes column q, which is non-negative +* and has upper bound: +* +* 0 <= x[q] <= u[q], (1) +* +* where u[q] > 0. +* +* PROBLEM TRANSFORMATION +* +* Upper bound of column q can be replaced by the following equality +* constraint: +* +* x[q] + s = u[q], (2) +* +* where s >= 0 is a non-negative complement variable. +* +* Since in the primal system along with new row (2) there appears a +* new column s having the only non-zero coefficient in this row, in +* the dual system there appears a new row: +* +* (+1)pi + lambda[s] = 0, (3) +* +* where (+1) is coefficient at column s in row (2), pi is multiplier +* for row (2), lambda[s] is multiplier for column s, 0 is coefficient +* at column s in the objective row. +* +* RECOVERING BASIC SOLUTION +* +* Status of column q in solution to the original problem is determined +* by its status and status of column s in solution to the transformed +* problem as follows: +* +* +-----------------------------------+------------------+ +* | Transformed problem | Original problem | +* +-----------------+-----------------+------------------+ +* | Status of col q | Status of col s | Status of col q | +* +-----------------+-----------------+------------------+ +* | GLP_BS | GLP_BS | GLP_BS | +* | GLP_BS | GLP_NL | GLP_NU | +* | GLP_NL | GLP_BS | GLP_NL | +* | GLP_NL | GLP_NL | GLP_NL (*) | +* +-----------------+-----------------+------------------+ +* +* Value of column q in solution to the original problem is the same as +* in solution to the transformed problem. +* +* 1. Formally, in solution to the transformed problem columns q and s +* cannot be non-basic at the same time, since the constraint (2) +* would be violated. However, if u[q] is close to zero, violation +* may be less than a working precision even if both columns q and s +* are non-basic. In this degenerate case row (2) can be only basic, +* i.e. non-active constraint (otherwise corresponding row of the +* basis matrix would be zero). This allows to pivot out auxiliary +* variable and pivot in column s, in which case the row becomes +* active while column s becomes basic. +* +* 2. If column q is integral, column s is also integral. +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* Value of column q in solution to the original problem is the same as +* in solution to the transformed problem. +* +* RECOVERING MIP SOLUTION +* +* Value of column q in solution to the original problem is the same as +* in solution to the transformed problem. */ + +struct dbnd_col +{ /* double-bounded column */ + int q; + /* column reference number for variable x[q] */ + int s; + /* column reference number for complement variable s */ +}; + +static int rcv_dbnd_col(NPP *npp, void *info); + +void npp_dbnd_col(NPP *npp, NPPCOL *q) +{ /* process non-negative column with upper bound */ + struct dbnd_col *info; + NPPROW *p; + NPPCOL *s; + /* the column must be non-negative with upper bound */ + xassert(q->lb == 0.0); + xassert(q->ub > 0.0); + xassert(q->ub != +DBL_MAX); + /* create variable s */ + s = npp_add_col(npp); + s->is_int = q->is_int; + s->lb = 0.0, s->ub = +DBL_MAX; + /* create equality constraint (2) */ + p = npp_add_row(npp); + p->lb = p->ub = q->ub; + npp_add_aij(npp, p, q, +1.0); + npp_add_aij(npp, p, s, +1.0); + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_dbnd_col, sizeof(struct dbnd_col)); + info->q = q->j; + info->s = s->j; + /* remove upper bound of x[q] */ + q->ub = +DBL_MAX; + return; +} + +static int rcv_dbnd_col(NPP *npp, void *_info) +{ /* recover non-negative column with upper bound */ + struct dbnd_col *info = _info; + if (npp->sol == GLP_BS) + { if (npp->c_stat[info->q] == GLP_BS) + { if (npp->c_stat[info->s] == GLP_BS) + npp->c_stat[info->q] = GLP_BS; + else if (npp->c_stat[info->s] == GLP_NL) + npp->c_stat[info->q] = GLP_NU; + else + { npp_error(); + return 1; + } + } + else if (npp->c_stat[info->q] == GLP_NL) + { if (npp->c_stat[info->s] == GLP_BS || + npp->c_stat[info->s] == GLP_NL) + npp->c_stat[info->q] = GLP_NL; + else + { npp_error(); + return 1; + } + } + else + { npp_error(); + return 1; + } + } + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_fixed_col - process fixed column +* +* SYNOPSIS +* +* #include "glpnpp.h" +* void npp_fixed_col(NPP *npp, NPPCOL *q); +* +* DESCRIPTION +* +* The routine npp_fixed_col processes column q, which is fixed: +* +* x[q] = s[q], (1) +* +* where s[q] is a fixed column value. +* +* PROBLEM TRANSFORMATION +* +* The value of a fixed column can be substituted into the objective +* and constraint rows that allows removing the column from the problem. +* +* Substituting x[q] = s[q] into the objective row, we have: +* +* z = sum c[j] x[j] + c0 = +* j +* +* = sum c[j] x[j] + c[q] x[q] + c0 = +* j!=q +* +* = sum c[j] x[j] + c[q] s[q] + c0 = +* j!=q +* +* = sum c[j] x[j] + c~0, +* j!=q +* +* where +* +* c~0 = c0 + c[q] s[q] (2) +* +* is the constant term of the objective in the transformed problem. +* Similarly, substituting x[q] = s[q] into constraint row i, we have: +* +* L[i] <= sum a[i,j] x[j] <= U[i] ==> +* j +* +* L[i] <= sum a[i,j] x[j] + a[i,q] x[q] <= U[i] ==> +* j!=q +* +* L[i] <= sum a[i,j] x[j] + a[i,q] s[q] <= U[i] ==> +* j!=q +* +* L~[i] <= sum a[i,j] x[j] + a[i,q] s <= U~[i], +* j!=q +* +* where +* +* L~[i] = L[i] - a[i,q] s[q], U~[i] = U[i] - a[i,q] s[q] (3) +* +* are lower and upper bounds of row i in the transformed problem, +* resp. +* +* RECOVERING BASIC SOLUTION +* +* Column q is assigned status GLP_NS and its value is assigned s[q]. +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* Value of column q is assigned s[q]. +* +* RECOVERING MIP SOLUTION +* +* Value of column q is assigned s[q]. */ + +struct fixed_col +{ /* fixed column */ + int q; + /* column reference number for variable x[q] */ + double s; + /* value, at which x[q] is fixed */ +}; + +static int rcv_fixed_col(NPP *npp, void *info); + +void npp_fixed_col(NPP *npp, NPPCOL *q) +{ /* process fixed column */ + struct fixed_col *info; + NPPROW *i; + NPPAIJ *aij; + /* the column must be fixed */ + xassert(q->lb == q->ub); + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_fixed_col, sizeof(struct fixed_col)); + info->q = q->j; + info->s = q->lb; + /* substitute x[q] = s[q] into objective row */ + npp->c0 += q->coef * q->lb; + /* substitute x[q] = s[q] into constraint rows */ + for (aij = q->ptr; aij != NULL; aij = aij->c_next) + { i = aij->row; + if (i->lb == i->ub) + i->ub = (i->lb -= aij->val * q->lb); + else + { if (i->lb != -DBL_MAX) + i->lb -= aij->val * q->lb; + if (i->ub != +DBL_MAX) + i->ub -= aij->val * q->lb; + } + } + /* remove the column from the problem */ + npp_del_col(npp, q); + return; +} + +static int rcv_fixed_col(NPP *npp, void *_info) +{ /* recover fixed column */ + struct fixed_col *info = _info; + if (npp->sol == GLP_SOL) + npp->c_stat[info->q] = GLP_NS; + npp->c_value[info->q] = info->s; + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_make_equality - process row with almost identical bounds +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_make_equality(NPP *npp, NPPROW *p); +* +* DESCRIPTION +* +* The routine npp_make_equality processes row p: +* +* L[p] <= sum a[p,j] x[j] <= U[p], (1) +* j +* +* where -oo < L[p] < U[p] < +oo, i.e. which is double-sided inequality +* constraint. +* +* RETURNS +* +* 0 - row bounds have not been changed; +* +* 1 - row has been replaced by equality constraint. +* +* PROBLEM TRANSFORMATION +* +* If bounds of row (1) are very close to each other: +* +* U[p] - L[p] <= eps, (2) +* +* where eps is an absolute tolerance for row value, the row can be +* replaced by the following almost equivalent equiality constraint: +* +* sum a[p,j] x[j] = b, (3) +* j +* +* where b = (L[p] + U[p]) / 2. If the right-hand side in (3) happens +* to be very close to its nearest integer: +* +* |b - floor(b + 0.5)| <= eps, (4) +* +* it is reasonable to use this nearest integer as the right-hand side. +* +* RECOVERING BASIC SOLUTION +* +* Status of row p in solution to the original problem is determined +* by its status and the sign of its multiplier pi[p] in solution to +* the transformed problem as follows: +* +* +-----------------------+---------+--------------------+ +* | Status of row p | Sign of | Status of row p | +* | (transformed problem) | pi[p] | (original problem) | +* +-----------------------+---------+--------------------+ +* | GLP_BS | + / - | GLP_BS | +* | GLP_NS | + | GLP_NL | +* | GLP_NS | - | GLP_NU | +* +-----------------------+---------+--------------------+ +* +* Value of row multiplier pi[p] in solution to the original problem is +* the same as in solution to the transformed problem. +* +* RECOVERING INTERIOR POINT SOLUTION +* +* Value of row multiplier pi[p] in solution to the original problem is +* the same as in solution to the transformed problem. +* +* RECOVERING MIP SOLUTION +* +* None needed. */ + +struct make_equality +{ /* row with almost identical bounds */ + int p; + /* row reference number */ +}; + +static int rcv_make_equality(NPP *npp, void *info); + +int npp_make_equality(NPP *npp, NPPROW *p) +{ /* process row with almost identical bounds */ + struct make_equality *info; + double b, eps, nint; + /* the row must be double-sided inequality */ + xassert(p->lb != -DBL_MAX); + xassert(p->ub != +DBL_MAX); + xassert(p->lb < p->ub); + /* check row bounds */ + eps = 1e-9 + 1e-12 * fabs(p->lb); + if (p->ub - p->lb > eps) return 0; + /* row bounds are very close to each other */ + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_make_equality, sizeof(struct make_equality)); + info->p = p->i; + /* compute right-hand side */ + b = 0.5 * (p->ub + p->lb); + nint = floor(b + 0.5); + if (fabs(b - nint) <= eps) b = nint; + /* replace row p by almost equivalent equality constraint */ + p->lb = p->ub = b; + return 1; +} + +int rcv_make_equality(NPP *npp, void *_info) +{ /* recover row with almost identical bounds */ + struct make_equality *info = _info; + if (npp->sol == GLP_SOL) + { if (npp->r_stat[info->p] == GLP_BS) + npp->r_stat[info->p] = GLP_BS; + else if (npp->r_stat[info->p] == GLP_NS) + { if (npp->r_pi[info->p] >= 0.0) + npp->r_stat[info->p] = GLP_NL; + else + npp->r_stat[info->p] = GLP_NU; + } + else + { npp_error(); + return 1; + } + } + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_make_fixed - process column with almost identical bounds +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_make_fixed(NPP *npp, NPPCOL *q); +* +* DESCRIPTION +* +* The routine npp_make_fixed processes column q: +* +* l[q] <= x[q] <= u[q], (1) +* +* where -oo < l[q] < u[q] < +oo, i.e. which has both lower and upper +* bounds. +* +* RETURNS +* +* 0 - column bounds have not been changed; +* +* 1 - column has been fixed. +* +* PROBLEM TRANSFORMATION +* +* If bounds of column (1) are very close to each other: +* +* u[q] - l[q] <= eps, (2) +* +* where eps is an absolute tolerance for column value, the column can +* be fixed: +* +* x[q] = s[q], (3) +* +* where s[q] = (l[q] + u[q]) / 2. And if the fixed column value s[q] +* happens to be very close to its nearest integer: +* +* |s[q] - floor(s[q] + 0.5)| <= eps, (4) +* +* it is reasonable to use this nearest integer as the fixed value. +* +* RECOVERING BASIC SOLUTION +* +* In the dual system of the original (as well as transformed) problem +* column q corresponds to the following row: +* +* sum a[i,q] pi[i] + lambda[q] = c[q]. (5) +* i +* +* Since multipliers pi[i] are known for all rows from solution to the +* transformed problem, formula (5) allows computing value of multiplier +* (reduced cost) for column q: +* +* lambda[q] = c[q] - sum a[i,q] pi[i]. (6) +* i +* +* Status of column q in solution to the original problem is determined +* by its status and the sign of its multiplier lambda[q] in solution to +* the transformed problem as follows: +* +* +-----------------------+-----------+--------------------+ +* | Status of column q | Sign of | Status of column q | +* | (transformed problem) | lambda[q] | (original problem) | +* +-----------------------+-----------+--------------------+ +* | GLP_BS | + / - | GLP_BS | +* | GLP_NS | + | GLP_NL | +* | GLP_NS | - | GLP_NU | +* +-----------------------+-----------+--------------------+ +* +* Value of column q in solution to the original problem is the same as +* in solution to the transformed problem. +* +* RECOVERING INTERIOR POINT SOLUTION +* +* Value of column q in solution to the original problem is the same as +* in solution to the transformed problem. +* +* RECOVERING MIP SOLUTION +* +* None needed. */ + +struct make_fixed +{ /* column with almost identical bounds */ + int q; + /* column reference number */ + double c; + /* objective coefficient at x[q] */ + NPPLFE *ptr; + /* list of non-zero coefficients a[i,q] */ +}; + +static int rcv_make_fixed(NPP *npp, void *info); + +int npp_make_fixed(NPP *npp, NPPCOL *q) +{ /* process column with almost identical bounds */ + struct make_fixed *info; + NPPAIJ *aij; + NPPLFE *lfe; + double s, eps, nint; + /* the column must be double-bounded */ + xassert(q->lb != -DBL_MAX); + xassert(q->ub != +DBL_MAX); + xassert(q->lb < q->ub); + /* check column bounds */ + eps = 1e-9 + 1e-12 * fabs(q->lb); + if (q->ub - q->lb > eps) return 0; + /* column bounds are very close to each other */ + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_make_fixed, sizeof(struct make_fixed)); + info->q = q->j; + info->c = q->coef; + info->ptr = NULL; + /* save column coefficients a[i,q] (needed for basic solution + only) */ + if (npp->sol == GLP_SOL) + { for (aij = q->ptr; aij != NULL; aij = aij->c_next) + { lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); + lfe->ref = aij->row->i; + lfe->val = aij->val; + lfe->next = info->ptr; + info->ptr = lfe; + } + } + /* compute column fixed value */ + s = 0.5 * (q->ub + q->lb); + nint = floor(s + 0.5); + if (fabs(s - nint) <= eps) s = nint; + /* make column q fixed */ + q->lb = q->ub = s; + return 1; +} + +static int rcv_make_fixed(NPP *npp, void *_info) +{ /* recover column with almost identical bounds */ + struct make_fixed *info = _info; + NPPLFE *lfe; + double lambda; + if (npp->sol == GLP_SOL) + { if (npp->c_stat[info->q] == GLP_BS) + npp->c_stat[info->q] = GLP_BS; + else if (npp->c_stat[info->q] == GLP_NS) + { /* compute multiplier for column q with formula (6) */ + lambda = info->c; + for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) + lambda -= lfe->val * npp->r_pi[lfe->ref]; + /* assign status to non-basic column */ + if (lambda >= 0.0) + npp->c_stat[info->q] = GLP_NL; + else + npp->c_stat[info->q] = GLP_NU; + } + else + { npp_error(); + return 1; + } + } + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpnpp03.c b/resources/3rdparty/glpk-4.57/src/glpnpp03.c new file mode 100644 index 000000000..0c869ee39 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpnpp03.c @@ -0,0 +1,2862 @@ +/* glpnpp03.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpnpp.h" + +/*********************************************************************** +* NAME +* +* npp_empty_row - process empty row +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_empty_row(NPP *npp, NPPROW *p); +* +* DESCRIPTION +* +* The routine npp_empty_row processes row p, which is empty, i.e. +* coefficients at all columns in this row are zero: +* +* L[p] <= sum 0 x[j] <= U[p], (1) +* +* where L[p] <= U[p]. +* +* RETURNS +* +* 0 - success; +* +* 1 - problem has no primal feasible solution. +* +* PROBLEM TRANSFORMATION +* +* If the following conditions hold: +* +* L[p] <= +eps, U[p] >= -eps, (2) +* +* where eps is an absolute tolerance for row value, the row p is +* redundant. In this case it can be replaced by equivalent redundant +* row, which is free (unbounded), and then removed from the problem. +* Otherwise, the row p is infeasible and, thus, the problem has no +* primal feasible solution. +* +* RECOVERING BASIC SOLUTION +* +* See the routine npp_free_row. +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* See the routine npp_free_row. +* +* RECOVERING MIP SOLUTION +* +* None needed. */ + +int npp_empty_row(NPP *npp, NPPROW *p) +{ /* process empty row */ + double eps = 1e-3; + /* the row must be empty */ + xassert(p->ptr == NULL); + /* check primal feasibility */ + if (p->lb > +eps || p->ub < -eps) + return 1; + /* replace the row by equivalent free (unbounded) row */ + p->lb = -DBL_MAX, p->ub = +DBL_MAX; + /* and process it */ + npp_free_row(npp, p); + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_empty_col - process empty column +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_empty_col(NPP *npp, NPPCOL *q); +* +* DESCRIPTION +* +* The routine npp_empty_col processes column q: +* +* l[q] <= x[q] <= u[q], (1) +* +* where l[q] <= u[q], which is empty, i.e. has zero coefficients in +* all constraint rows. +* +* RETURNS +* +* 0 - success; +* +* 1 - problem has no dual feasible solution. +* +* PROBLEM TRANSFORMATION +* +* The row of the dual system corresponding to the empty column is the +* following: +* +* sum 0 pi[i] + lambda[q] = c[q], (2) +* i +* +* from which it follows that: +* +* lambda[q] = c[q]. (3) +* +* If the following condition holds: +* +* c[q] < - eps, (4) +* +* where eps is an absolute tolerance for column multiplier, the lower +* column bound l[q] must be active to provide dual feasibility (note +* that being preprocessed the problem is always minimization). In this +* case the column can be fixed on its lower bound and removed from the +* problem (if the column is integral, its bounds are also assumed to +* be integral). And if the column has no lower bound (l[q] = -oo), the +* problem has no dual feasible solution. +* +* If the following condition holds: +* +* c[q] > + eps, (5) +* +* the upper column bound u[q] must be active to provide dual +* feasibility. In this case the column can be fixed on its upper bound +* and removed from the problem. And if the column has no upper bound +* (u[q] = +oo), the problem has no dual feasible solution. +* +* Finally, if the following condition holds: +* +* - eps <= c[q] <= +eps, (6) +* +* dual feasibility does not depend on a particular value of column q. +* In this case the column can be fixed either on its lower bound (if +* l[q] > -oo) or on its upper bound (if u[q] < +oo) or at zero (if the +* column is unbounded) and then removed from the problem. +* +* RECOVERING BASIC SOLUTION +* +* See the routine npp_fixed_col. Having been recovered the column +* is assigned status GLP_NS. However, if actually it is not fixed +* (l[q] < u[q]), its status should be changed to GLP_NL, GLP_NU, or +* GLP_NF depending on which bound it was fixed on transformation stage. +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* See the routine npp_fixed_col. +* +* RECOVERING MIP SOLUTION +* +* See the routine npp_fixed_col. */ + +struct empty_col +{ /* empty column */ + int q; + /* column reference number */ + char stat; + /* status in basic solution */ +}; + +static int rcv_empty_col(NPP *npp, void *info); + +int npp_empty_col(NPP *npp, NPPCOL *q) +{ /* process empty column */ + struct empty_col *info; + double eps = 1e-3; + /* the column must be empty */ + xassert(q->ptr == NULL); + /* check dual feasibility */ + if (q->coef > +eps && q->lb == -DBL_MAX) + return 1; + if (q->coef < -eps && q->ub == +DBL_MAX) + return 1; + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_empty_col, sizeof(struct empty_col)); + info->q = q->j; + /* fix the column */ + if (q->lb == -DBL_MAX && q->ub == +DBL_MAX) + { /* free column */ + info->stat = GLP_NF; + q->lb = q->ub = 0.0; + } + else if (q->ub == +DBL_MAX) +lo: { /* column with lower bound */ + info->stat = GLP_NL; + q->ub = q->lb; + } + else if (q->lb == -DBL_MAX) +up: { /* column with upper bound */ + info->stat = GLP_NU; + q->lb = q->ub; + } + else if (q->lb != q->ub) + { /* double-bounded column */ + if (q->coef >= +DBL_EPSILON) goto lo; + if (q->coef <= -DBL_EPSILON) goto up; + if (fabs(q->lb) <= fabs(q->ub)) goto lo; else goto up; + } + else + { /* fixed column */ + info->stat = GLP_NS; + } + /* process fixed column */ + npp_fixed_col(npp, q); + return 0; +} + +static int rcv_empty_col(NPP *npp, void *_info) +{ /* recover empty column */ + struct empty_col *info = _info; + if (npp->sol == GLP_SOL) + npp->c_stat[info->q] = info->stat; + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_implied_value - process implied column value +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_implied_value(NPP *npp, NPPCOL *q, double s); +* +* DESCRIPTION +* +* For column q: +* +* l[q] <= x[q] <= u[q], (1) +* +* where l[q] < u[q], the routine npp_implied_value processes its +* implied value s[q]. If this implied value satisfies to the current +* column bounds and integrality condition, the routine fixes column q +* at the given point. Note that the column is kept in the problem in +* any case. +* +* RETURNS +* +* 0 - column has been fixed; +* +* 1 - implied value violates to current column bounds; +* +* 2 - implied value violates integrality condition. +* +* ALGORITHM +* +* Implied column value s[q] satisfies to the current column bounds if +* the following condition holds: +* +* l[q] - eps <= s[q] <= u[q] + eps, (2) +* +* where eps is an absolute tolerance for column value. If the column +* is integral, the following condition also must hold: +* +* |s[q] - floor(s[q]+0.5)| <= eps, (3) +* +* where floor(s[q]+0.5) is the nearest integer to s[q]. +* +* If both condition (2) and (3) are satisfied, the column can be fixed +* at the value s[q], or, if it is integral, at floor(s[q]+0.5). +* Otherwise, if s[q] violates (2) or (3), the problem has no feasible +* solution. +* +* Note: If s[q] is close to l[q] or u[q], it seems to be reasonable to +* fix the column at its lower or upper bound, resp. rather than at the +* implied value. */ + +int npp_implied_value(NPP *npp, NPPCOL *q, double s) +{ /* process implied column value */ + double eps, nint; + xassert(npp == npp); + /* column must not be fixed */ + xassert(q->lb < q->ub); + /* check integrality */ + if (q->is_int) + { nint = floor(s + 0.5); + if (fabs(s - nint) <= 1e-5) + s = nint; + else + return 2; + } + /* check current column lower bound */ + if (q->lb != -DBL_MAX) + { eps = (q->is_int ? 1e-5 : 1e-5 + 1e-8 * fabs(q->lb)); + if (s < q->lb - eps) return 1; + /* if s[q] is close to l[q], fix column at its lower bound + rather than at the implied value */ + if (s < q->lb + 1e-3 * eps) + { q->ub = q->lb; + return 0; + } + } + /* check current column upper bound */ + if (q->ub != +DBL_MAX) + { eps = (q->is_int ? 1e-5 : 1e-5 + 1e-8 * fabs(q->ub)); + if (s > q->ub + eps) return 1; + /* if s[q] is close to u[q], fix column at its upper bound + rather than at the implied value */ + if (s > q->ub - 1e-3 * eps) + { q->lb = q->ub; + return 0; + } + } + /* fix column at the implied value */ + q->lb = q->ub = s; + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_eq_singlet - process row singleton (equality constraint) +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_eq_singlet(NPP *npp, NPPROW *p); +* +* DESCRIPTION +* +* The routine npp_eq_singlet processes row p, which is equiality +* constraint having the only non-zero coefficient: +* +* a[p,q] x[q] = b. (1) +* +* RETURNS +* +* 0 - success; +* +* 1 - problem has no primal feasible solution; +* +* 2 - problem has no integer feasible solution. +* +* PROBLEM TRANSFORMATION +* +* The equality constraint defines implied value of column q: +* +* x[q] = s[q] = b / a[p,q]. (2) +* +* If the implied value s[q] satisfies to the column bounds (see the +* routine npp_implied_value), the column can be fixed at s[q] and +* removed from the problem. In this case row p becomes redundant, so +* it can be replaced by equivalent free row and also removed from the +* problem. +* +* Note that the routine removes from the problem only row p. Column q +* becomes fixed, however, it is kept in the problem. +* +* RECOVERING BASIC SOLUTION +* +* In solution to the original problem row p is assigned status GLP_NS +* (active equality constraint), and column q is assigned status GLP_BS +* (basic column). +* +* Multiplier for row p can be computed as follows. In the dual system +* of the original problem column q corresponds to the following row: +* +* sum a[i,q] pi[i] + lambda[q] = c[q] ==> +* i +* +* sum a[i,q] pi[i] + a[p,q] pi[p] + lambda[q] = c[q]. +* i!=p +* +* Therefore: +* +* 1 +* pi[p] = ------ (c[q] - lambda[q] - sum a[i,q] pi[i]), (3) +* a[p,q] i!=q +* +* where lambda[q] = 0 (since column[q] is basic), and pi[i] for all +* i != p are known in solution to the transformed problem. +* +* Value of column q in solution to the original problem is assigned +* its implied value s[q]. +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* Multiplier for row p is computed with formula (3). Value of column +* q is assigned its implied value s[q]. +* +* RECOVERING MIP SOLUTION +* +* Value of column q is assigned its implied value s[q]. */ + +struct eq_singlet +{ /* row singleton (equality constraint) */ + int p; + /* row reference number */ + int q; + /* column reference number */ + double apq; + /* constraint coefficient a[p,q] */ + double c; + /* objective coefficient at x[q] */ + NPPLFE *ptr; + /* list of non-zero coefficients a[i,q], i != p */ +}; + +static int rcv_eq_singlet(NPP *npp, void *info); + +int npp_eq_singlet(NPP *npp, NPPROW *p) +{ /* process row singleton (equality constraint) */ + struct eq_singlet *info; + NPPCOL *q; + NPPAIJ *aij; + NPPLFE *lfe; + int ret; + double s; + /* the row must be singleton equality constraint */ + xassert(p->lb == p->ub); + xassert(p->ptr != NULL && p->ptr->r_next == NULL); + /* compute and process implied column value */ + aij = p->ptr; + q = aij->col; + s = p->lb / aij->val; + ret = npp_implied_value(npp, q, s); + xassert(0 <= ret && ret <= 2); + if (ret != 0) return ret; + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_eq_singlet, sizeof(struct eq_singlet)); + info->p = p->i; + info->q = q->j; + info->apq = aij->val; + info->c = q->coef; + info->ptr = NULL; + /* save column coefficients a[i,q], i != p (not needed for MIP + solution) */ + if (npp->sol != GLP_MIP) + { for (aij = q->ptr; aij != NULL; aij = aij->c_next) + { if (aij->row == p) continue; /* skip a[p,q] */ + lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); + lfe->ref = aij->row->i; + lfe->val = aij->val; + lfe->next = info->ptr; + info->ptr = lfe; + } + } + /* remove the row from the problem */ + npp_del_row(npp, p); + return 0; +} + +static int rcv_eq_singlet(NPP *npp, void *_info) +{ /* recover row singleton (equality constraint) */ + struct eq_singlet *info = _info; + NPPLFE *lfe; + double temp; + if (npp->sol == GLP_SOL) + { /* column q must be already recovered as GLP_NS */ + if (npp->c_stat[info->q] != GLP_NS) + { npp_error(); + return 1; + } + npp->r_stat[info->p] = GLP_NS; + npp->c_stat[info->q] = GLP_BS; + } + if (npp->sol != GLP_MIP) + { /* compute multiplier for row p with formula (3) */ + temp = info->c; + for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) + temp -= lfe->val * npp->r_pi[lfe->ref]; + npp->r_pi[info->p] = temp / info->apq; + } + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_implied_lower - process implied column lower bound +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_implied_lower(NPP *npp, NPPCOL *q, double l); +* +* DESCRIPTION +* +* For column q: +* +* l[q] <= x[q] <= u[q], (1) +* +* where l[q] < u[q], the routine npp_implied_lower processes its +* implied lower bound l'[q]. As the result the current column lower +* bound may increase. Note that the column is kept in the problem in +* any case. +* +* RETURNS +* +* 0 - current column lower bound has not changed; +* +* 1 - current column lower bound has changed, but not significantly; +* +* 2 - current column lower bound has significantly changed; +* +* 3 - column has been fixed on its upper bound; +* +* 4 - implied lower bound violates current column upper bound. +* +* ALGORITHM +* +* If column q is integral, before processing its implied lower bound +* should be rounded up: +* +* ( floor(l'[q]+0.5), if |l'[q] - floor(l'[q]+0.5)| <= eps +* l'[q] := < (2) +* ( ceil(l'[q]), otherwise +* +* where floor(l'[q]+0.5) is the nearest integer to l'[q], ceil(l'[q]) +* is smallest integer not less than l'[q], and eps is an absolute +* tolerance for column value. +* +* Processing implied column lower bound l'[q] includes the following +* cases: +* +* 1) if l'[q] < l[q] + eps, implied lower bound is redundant; +* +* 2) if l[q] + eps <= l[q] <= u[q] + eps, current column lower bound +* l[q] can be strengthened by replacing it with l'[q]. If in this +* case new column lower bound becomes close to current column upper +* bound u[q], the column can be fixed on its upper bound; +* +* 3) if l'[q] > u[q] + eps, implied lower bound violates current +* column upper bound u[q], in which case the problem has no primal +* feasible solution. */ + +int npp_implied_lower(NPP *npp, NPPCOL *q, double l) +{ /* process implied column lower bound */ + int ret; + double eps, nint; + xassert(npp == npp); + /* column must not be fixed */ + xassert(q->lb < q->ub); + /* implied lower bound must be finite */ + xassert(l != -DBL_MAX); + /* if column is integral, round up l'[q] */ + if (q->is_int) + { nint = floor(l + 0.5); + if (fabs(l - nint) <= 1e-5) + l = nint; + else + l = ceil(l); + } + /* check current column lower bound */ + if (q->lb != -DBL_MAX) + { eps = (q->is_int ? 1e-3 : 1e-3 + 1e-6 * fabs(q->lb)); + if (l < q->lb + eps) + { ret = 0; /* redundant */ + goto done; + } + } + /* check current column upper bound */ + if (q->ub != +DBL_MAX) + { eps = (q->is_int ? 1e-5 : 1e-5 + 1e-8 * fabs(q->ub)); + if (l > q->ub + eps) + { ret = 4; /* infeasible */ + goto done; + } + /* if l'[q] is close to u[q], fix column at its upper bound */ + if (l > q->ub - 1e-3 * eps) + { q->lb = q->ub; + ret = 3; /* fixed */ + goto done; + } + } + /* check if column lower bound changes significantly */ + if (q->lb == -DBL_MAX) + ret = 2; /* significantly */ + else if (q->is_int && l > q->lb + 0.5) + ret = 2; /* significantly */ + else if (l > q->lb + 0.30 * (1.0 + fabs(q->lb))) + ret = 2; /* significantly */ + else + ret = 1; /* not significantly */ + /* set new column lower bound */ + q->lb = l; +done: return ret; +} + +/*********************************************************************** +* NAME +* +* npp_implied_upper - process implied column upper bound +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_implied_upper(NPP *npp, NPPCOL *q, double u); +* +* DESCRIPTION +* +* For column q: +* +* l[q] <= x[q] <= u[q], (1) +* +* where l[q] < u[q], the routine npp_implied_upper processes its +* implied upper bound u'[q]. As the result the current column upper +* bound may decrease. Note that the column is kept in the problem in +* any case. +* +* RETURNS +* +* 0 - current column upper bound has not changed; +* +* 1 - current column upper bound has changed, but not significantly; +* +* 2 - current column upper bound has significantly changed; +* +* 3 - column has been fixed on its lower bound; +* +* 4 - implied upper bound violates current column lower bound. +* +* ALGORITHM +* +* If column q is integral, before processing its implied upper bound +* should be rounded down: +* +* ( floor(u'[q]+0.5), if |u'[q] - floor(l'[q]+0.5)| <= eps +* u'[q] := < (2) +* ( floor(l'[q]), otherwise +* +* where floor(u'[q]+0.5) is the nearest integer to u'[q], +* floor(u'[q]) is largest integer not greater than u'[q], and eps is +* an absolute tolerance for column value. +* +* Processing implied column upper bound u'[q] includes the following +* cases: +* +* 1) if u'[q] > u[q] - eps, implied upper bound is redundant; +* +* 2) if l[q] - eps <= u[q] <= u[q] - eps, current column upper bound +* u[q] can be strengthened by replacing it with u'[q]. If in this +* case new column upper bound becomes close to current column lower +* bound, the column can be fixed on its lower bound; +* +* 3) if u'[q] < l[q] - eps, implied upper bound violates current +* column lower bound l[q], in which case the problem has no primal +* feasible solution. */ + +int npp_implied_upper(NPP *npp, NPPCOL *q, double u) +{ int ret; + double eps, nint; + xassert(npp == npp); + /* column must not be fixed */ + xassert(q->lb < q->ub); + /* implied upper bound must be finite */ + xassert(u != +DBL_MAX); + /* if column is integral, round down u'[q] */ + if (q->is_int) + { nint = floor(u + 0.5); + if (fabs(u - nint) <= 1e-5) + u = nint; + else + u = floor(u); + } + /* check current column upper bound */ + if (q->ub != +DBL_MAX) + { eps = (q->is_int ? 1e-3 : 1e-3 + 1e-6 * fabs(q->ub)); + if (u > q->ub - eps) + { ret = 0; /* redundant */ + goto done; + } + } + /* check current column lower bound */ + if (q->lb != -DBL_MAX) + { eps = (q->is_int ? 1e-5 : 1e-5 + 1e-8 * fabs(q->lb)); + if (u < q->lb - eps) + { ret = 4; /* infeasible */ + goto done; + } + /* if u'[q] is close to l[q], fix column at its lower bound */ + if (u < q->lb + 1e-3 * eps) + { q->ub = q->lb; + ret = 3; /* fixed */ + goto done; + } + } + /* check if column upper bound changes significantly */ + if (q->ub == +DBL_MAX) + ret = 2; /* significantly */ + else if (q->is_int && u < q->ub - 0.5) + ret = 2; /* significantly */ + else if (u < q->ub - 0.30 * (1.0 + fabs(q->ub))) + ret = 2; /* significantly */ + else + ret = 1; /* not significantly */ + /* set new column upper bound */ + q->ub = u; +done: return ret; +} + +/*********************************************************************** +* NAME +* +* npp_ineq_singlet - process row singleton (inequality constraint) +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_ineq_singlet(NPP *npp, NPPROW *p); +* +* DESCRIPTION +* +* The routine npp_ineq_singlet processes row p, which is inequality +* constraint having the only non-zero coefficient: +* +* L[p] <= a[p,q] * x[q] <= U[p], (1) +* +* where L[p] < U[p], L[p] > -oo and/or U[p] < +oo. +* +* RETURNS +* +* 0 - current column bounds have not changed; +* +* 1 - current column bounds have changed, but not significantly; +* +* 2 - current column bounds have significantly changed; +* +* 3 - column has been fixed on its lower or upper bound; +* +* 4 - problem has no primal feasible solution. +* +* PROBLEM TRANSFORMATION +* +* Inequality constraint (1) defines implied bounds of column q: +* +* ( L[p] / a[p,q], if a[p,q] > 0 +* l'[q] = < (2) +* ( U[p] / a[p,q], if a[p,q] < 0 +* +* ( U[p] / a[p,q], if a[p,q] > 0 +* u'[q] = < (3) +* ( L[p] / a[p,q], if a[p,q] < 0 +* +* If these implied bounds do not violate current bounds of column q: +* +* l[q] <= x[q] <= u[q], (4) +* +* they can be used to strengthen the current column bounds: +* +* l[q] := max(l[q], l'[q]), (5) +* +* u[q] := min(u[q], u'[q]). (6) +* +* (See the routines npp_implied_lower and npp_implied_upper.) +* +* Once bounds of row p (1) have been carried over column q, the row +* becomes redundant, so it can be replaced by equivalent free row and +* removed from the problem. +* +* Note that the routine removes from the problem only row p. Column q, +* even it has been fixed, is kept in the problem. +* +* RECOVERING BASIC SOLUTION +* +* Note that the row in the dual system corresponding to column q is +* the following: +* +* sum a[i,q] pi[i] + lambda[q] = c[q] ==> +* i +* (7) +* sum a[i,q] pi[i] + a[p,q] pi[p] + lambda[q] = c[q], +* i!=p +* +* where pi[i] for all i != p are known in solution to the transformed +* problem. Row p does not exist in the transformed problem, so it has +* zero multiplier there. This allows computing multiplier for column q +* in solution to the transformed problem: +* +* lambda~[q] = c[q] - sum a[i,q] pi[i]. (8) +* i!=p +* +* Let in solution to the transformed problem column q be non-basic +* with lower bound active (GLP_NL, lambda~[q] >= 0), and this lower +* bound be implied one l'[q]. From the original problem's standpoint +* this then means that actually the original column lower bound l[q] +* is inactive, and active is that row bound L[p] or U[p] that defines +* the implied bound l'[q] (2). In this case in solution to the +* original problem column q is assigned status GLP_BS while row p is +* assigned status GLP_NL (if a[p,q] > 0) or GLP_NU (if a[p,q] < 0). +* Since now column q is basic, its multiplier lambda[q] is zero. This +* allows using (7) and (8) to find multiplier for row p in solution to +* the original problem: +* +* 1 +* pi[p] = ------ (c[q] - sum a[i,q] pi[i]) = lambda~[q] / a[p,q] (9) +* a[p,q] i!=p +* +* Now let in solution to the transformed problem column q be non-basic +* with upper bound active (GLP_NU, lambda~[q] <= 0), and this upper +* bound be implied one u'[q]. As in the previous case this then means +* that from the original problem's standpoint actually the original +* column upper bound u[q] is inactive, and active is that row bound +* L[p] or U[p] that defines the implied bound u'[q] (3). In this case +* in solution to the original problem column q is assigned status +* GLP_BS, row p is assigned status GLP_NU (if a[p,q] > 0) or GLP_NL +* (if a[p,q] < 0), and its multiplier is computed with formula (9). +* +* Strengthening bounds of column q according to (5) and (6) may make +* it fixed. Thus, if in solution to the transformed problem column q is +* non-basic and fixed (GLP_NS), we can suppose that if lambda~[q] > 0, +* column q has active lower bound (GLP_NL), and if lambda~[q] < 0, +* column q has active upper bound (GLP_NU), reducing this case to two +* previous ones. If, however, lambda~[q] is close to zero or +* corresponding bound of row p does not exist (this may happen if +* lambda~[q] has wrong sign due to round-off errors, in which case it +* is expected to be close to zero, since solution is assumed to be dual +* feasible), column q can be assigned status GLP_BS (basic), and row p +* can be made active on its existing bound. In the latter case row +* multiplier pi[p] computed with formula (9) will be also close to +* zero, and dual feasibility will be kept. +* +* In all other cases, namely, if in solution to the transformed +* problem column q is basic (GLP_BS), or non-basic with original lower +* bound l[q] active (GLP_NL), or non-basic with original upper bound +* u[q] active (GLP_NU), constraint (1) is inactive. So in solution to +* the original problem status of column q remains unchanged, row p is +* assigned status GLP_BS, and its multiplier pi[p] is assigned zero +* value. +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* First, value of multiplier for column q in solution to the original +* problem is computed with formula (8). If lambda~[q] > 0 and column q +* has implied lower bound, or if lambda~[q] < 0 and column q has +* implied upper bound, this means that from the original problem's +* standpoint actually row p has corresponding active bound, in which +* case its multiplier pi[p] is computed with formula (9). In other +* cases, when the sign of lambda~[q] corresponds to original bound of +* column q, or when lambda~[q] =~ 0, value of row multiplier pi[p] is +* assigned zero value. +* +* RECOVERING MIP SOLUTION +* +* None needed. */ + +struct ineq_singlet +{ /* row singleton (inequality constraint) */ + int p; + /* row reference number */ + int q; + /* column reference number */ + double apq; + /* constraint coefficient a[p,q] */ + double c; + /* objective coefficient at x[q] */ + double lb; + /* row lower bound */ + double ub; + /* row upper bound */ + char lb_changed; + /* this flag is set if column lower bound was changed */ + char ub_changed; + /* this flag is set if column upper bound was changed */ + NPPLFE *ptr; + /* list of non-zero coefficients a[i,q], i != p */ +}; + +static int rcv_ineq_singlet(NPP *npp, void *info); + +int npp_ineq_singlet(NPP *npp, NPPROW *p) +{ /* process row singleton (inequality constraint) */ + struct ineq_singlet *info; + NPPCOL *q; + NPPAIJ *apq, *aij; + NPPLFE *lfe; + int lb_changed, ub_changed; + double ll, uu; + /* the row must be singleton inequality constraint */ + xassert(p->lb != -DBL_MAX || p->ub != +DBL_MAX); + xassert(p->lb < p->ub); + xassert(p->ptr != NULL && p->ptr->r_next == NULL); + /* compute implied column bounds */ + apq = p->ptr; + q = apq->col; + xassert(q->lb < q->ub); + if (apq->val > 0.0) + { ll = (p->lb == -DBL_MAX ? -DBL_MAX : p->lb / apq->val); + uu = (p->ub == +DBL_MAX ? +DBL_MAX : p->ub / apq->val); + } + else + { ll = (p->ub == +DBL_MAX ? -DBL_MAX : p->ub / apq->val); + uu = (p->lb == -DBL_MAX ? +DBL_MAX : p->lb / apq->val); + } + /* process implied column lower bound */ + if (ll == -DBL_MAX) + lb_changed = 0; + else + { lb_changed = npp_implied_lower(npp, q, ll); + xassert(0 <= lb_changed && lb_changed <= 4); + if (lb_changed == 4) return 4; /* infeasible */ + } + /* process implied column upper bound */ + if (uu == +DBL_MAX) + ub_changed = 0; + else if (lb_changed == 3) + { /* column was fixed on its upper bound due to l'[q] = u[q] */ + /* note that L[p] < U[p], so l'[q] = u[q] < u'[q] */ + ub_changed = 0; + } + else + { ub_changed = npp_implied_upper(npp, q, uu); + xassert(0 <= ub_changed && ub_changed <= 4); + if (ub_changed == 4) return 4; /* infeasible */ + } + /* if neither lower nor upper column bound was changed, the row + is originally redundant and can be replaced by free row */ + if (!lb_changed && !ub_changed) + { p->lb = -DBL_MAX, p->ub = +DBL_MAX; + npp_free_row(npp, p); + return 0; + } + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_ineq_singlet, sizeof(struct ineq_singlet)); + info->p = p->i; + info->q = q->j; + info->apq = apq->val; + info->c = q->coef; + info->lb = p->lb; + info->ub = p->ub; + info->lb_changed = (char)lb_changed; + info->ub_changed = (char)ub_changed; + info->ptr = NULL; + /* save column coefficients a[i,q], i != p (not needed for MIP + solution) */ + if (npp->sol != GLP_MIP) + { for (aij = q->ptr; aij != NULL; aij = aij->c_next) + { if (aij == apq) continue; /* skip a[p,q] */ + lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); + lfe->ref = aij->row->i; + lfe->val = aij->val; + lfe->next = info->ptr; + info->ptr = lfe; + } + } + /* remove the row from the problem */ + npp_del_row(npp, p); + return lb_changed >= ub_changed ? lb_changed : ub_changed; +} + +static int rcv_ineq_singlet(NPP *npp, void *_info) +{ /* recover row singleton (inequality constraint) */ + struct ineq_singlet *info = _info; + NPPLFE *lfe; + double lambda; + if (npp->sol == GLP_MIP) goto done; + /* compute lambda~[q] in solution to the transformed problem + with formula (8) */ + lambda = info->c; + for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) + lambda -= lfe->val * npp->r_pi[lfe->ref]; + if (npp->sol == GLP_SOL) + { /* recover basic solution */ + if (npp->c_stat[info->q] == GLP_BS) + { /* column q is basic, so row p is inactive */ + npp->r_stat[info->p] = GLP_BS; + npp->r_pi[info->p] = 0.0; + } + else if (npp->c_stat[info->q] == GLP_NL) +nl: { /* column q is non-basic with lower bound active */ + if (info->lb_changed) + { /* it is implied bound, so actually row p is active + while column q is basic */ + npp->r_stat[info->p] = + (char)(info->apq > 0.0 ? GLP_NL : GLP_NU); + npp->c_stat[info->q] = GLP_BS; + npp->r_pi[info->p] = lambda / info->apq; + } + else + { /* it is original bound, so row p is inactive */ + npp->r_stat[info->p] = GLP_BS; + npp->r_pi[info->p] = 0.0; + } + } + else if (npp->c_stat[info->q] == GLP_NU) +nu: { /* column q is non-basic with upper bound active */ + if (info->ub_changed) + { /* it is implied bound, so actually row p is active + while column q is basic */ + npp->r_stat[info->p] = + (char)(info->apq > 0.0 ? GLP_NU : GLP_NL); + npp->c_stat[info->q] = GLP_BS; + npp->r_pi[info->p] = lambda / info->apq; + } + else + { /* it is original bound, so row p is inactive */ + npp->r_stat[info->p] = GLP_BS; + npp->r_pi[info->p] = 0.0; + } + } + else if (npp->c_stat[info->q] == GLP_NS) + { /* column q is non-basic and fixed; note, however, that in + in the original problem it is non-fixed */ + if (lambda > +1e-7) + { if (info->apq > 0.0 && info->lb != -DBL_MAX || + info->apq < 0.0 && info->ub != +DBL_MAX || + !info->lb_changed) + { /* either corresponding bound of row p exists or + column q remains non-basic with its original lower + bound active */ + npp->c_stat[info->q] = GLP_NL; + goto nl; + } + } + if (lambda < -1e-7) + { if (info->apq > 0.0 && info->ub != +DBL_MAX || + info->apq < 0.0 && info->lb != -DBL_MAX || + !info->ub_changed) + { /* either corresponding bound of row p exists or + column q remains non-basic with its original upper + bound active */ + npp->c_stat[info->q] = GLP_NU; + goto nu; + } + } + /* either lambda~[q] is close to zero, or corresponding + bound of row p does not exist, because lambda~[q] has + wrong sign due to round-off errors; in the latter case + lambda~[q] is also assumed to be close to zero; so, we + can make row p active on its existing bound and column q + basic; pi[p] will have wrong sign, but it also will be + close to zero (rarus casus of dual degeneracy) */ + if (info->lb != -DBL_MAX && info->ub == +DBL_MAX) + { /* row lower bound exists, but upper bound doesn't */ + npp->r_stat[info->p] = GLP_NL; + } + else if (info->lb == -DBL_MAX && info->ub != +DBL_MAX) + { /* row upper bound exists, but lower bound doesn't */ + npp->r_stat[info->p] = GLP_NU; + } + else if (info->lb != -DBL_MAX && info->ub != +DBL_MAX) + { /* both row lower and upper bounds exist */ + /* to choose proper active row bound we should not use + lambda~[q], because its value being close to zero is + unreliable; so we choose that bound which provides + primal feasibility for original constraint (1) */ + if (info->apq * npp->c_value[info->q] <= + 0.5 * (info->lb + info->ub)) + npp->r_stat[info->p] = GLP_NL; + else + npp->r_stat[info->p] = GLP_NU; + } + else + { npp_error(); + return 1; + } + npp->c_stat[info->q] = GLP_BS; + npp->r_pi[info->p] = lambda / info->apq; + } + else + { npp_error(); + return 1; + } + } + if (npp->sol == GLP_IPT) + { /* recover interior-point solution */ + if (lambda > +DBL_EPSILON && info->lb_changed || + lambda < -DBL_EPSILON && info->ub_changed) + { /* actually row p has corresponding active bound */ + npp->r_pi[info->p] = lambda / info->apq; + } + else + { /* either bounds of column q are both inactive or its + original bound is active */ + npp->r_pi[info->p] = 0.0; + } + } +done: return 0; +} + +/*********************************************************************** +* NAME +* +* npp_implied_slack - process column singleton (implied slack variable) +* +* SYNOPSIS +* +* #include "glpnpp.h" +* void npp_implied_slack(NPP *npp, NPPCOL *q); +* +* DESCRIPTION +* +* The routine npp_implied_slack processes column q: +* +* l[q] <= x[q] <= u[q], (1) +* +* where l[q] < u[q], having the only non-zero coefficient in row p, +* which is equality constraint: +* +* sum a[p,j] x[j] + a[p,q] x[q] = b. (2) +* j!=q +* +* PROBLEM TRANSFORMATION +* +* (If x[q] is integral, this transformation must not be used.) +* +* The term a[p,q] x[q] in constraint (2) can be considered as a slack +* variable that allows to carry bounds of column q over row p and then +* remove column q from the problem. +* +* Constraint (2) can be written as follows: +* +* sum a[p,j] x[j] = b - a[p,q] x[q]. (3) +* j!=q +* +* According to (1) constraint (3) is equivalent to the following +* inequality constraint: +* +* L[p] <= sum a[p,j] x[j] <= U[p], (4) +* j!=q +* +* where +* +* ( b - a[p,q] u[q], if a[p,q] > 0 +* L[p] = < (5) +* ( b - a[p,q] l[q], if a[p,q] < 0 +* +* ( b - a[p,q] l[q], if a[p,q] > 0 +* U[p] = < (6) +* ( b - a[p,q] u[q], if a[p,q] < 0 +* +* From (2) it follows that: +* +* 1 +* x[q] = ------ (b - sum a[p,j] x[j]). (7) +* a[p,q] j!=q +* +* In order to eliminate x[q] from the objective row we substitute it +* from (6) to that row: +* +* z = sum c[j] x[j] + c[q] x[q] + c[0] = +* j!=q +* 1 +* = sum c[j] x[j] + c[q] [------ (b - sum a[p,j] x[j])] + c0 = +* j!=q a[p,q] j!=q +* +* = sum c~[j] x[j] + c~[0], +* j!=q +* a[p,j] b +* c~[j] = c[j] - c[q] ------, c~0 = c0 - c[q] ------ (8) +* a[p,q] a[p,q] +* +* are values of objective coefficients and constant term, resp., in +* the transformed problem. +* +* Note that column q is column singleton, so in the dual system of the +* original problem it corresponds to the following row singleton: +* +* a[p,q] pi[p] + lambda[q] = c[q]. (9) +* +* In the transformed problem row (9) would be the following: +* +* a[p,q] pi~[p] + lambda[q] = c~[q] = 0. (10) +* +* Subtracting (10) from (9) we have: +* +* a[p,q] (pi[p] - pi~[p]) = c[q] +* +* that gives the following formula to compute multiplier for row p in +* solution to the original problem using its value in solution to the +* transformed problem: +* +* pi[p] = pi~[p] + c[q] / a[p,q]. (11) +* +* RECOVERING BASIC SOLUTION +* +* Status of column q in solution to the original problem is defined +* by status of row p in solution to the transformed problem and the +* sign of coefficient a[p,q] in the original inequality constraint (2) +* as follows: +* +* +-----------------------+---------+--------------------+ +* | Status of row p | Sign of | Status of column q | +* | (transformed problem) | a[p,q] | (original problem) | +* +-----------------------+---------+--------------------+ +* | GLP_BS | + / - | GLP_BS | +* | GLP_NL | + | GLP_NU | +* | GLP_NL | - | GLP_NL | +* | GLP_NU | + | GLP_NL | +* | GLP_NU | - | GLP_NU | +* | GLP_NF | + / - | GLP_NF | +* +-----------------------+---------+--------------------+ +* +* Value of column q is computed with formula (7). Since originally row +* p is equality constraint, its status is assigned GLP_NS, and value of +* its multiplier pi[p] is computed with formula (11). +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* Value of column q is computed with formula (7). Row multiplier value +* pi[p] is computed with formula (11). +* +* RECOVERING MIP SOLUTION +* +* Value of column q is computed with formula (7). */ + +struct implied_slack +{ /* column singleton (implied slack variable) */ + int p; + /* row reference number */ + int q; + /* column reference number */ + double apq; + /* constraint coefficient a[p,q] */ + double b; + /* right-hand side of original equality constraint */ + double c; + /* original objective coefficient at x[q] */ + NPPLFE *ptr; + /* list of non-zero coefficients a[p,j], j != q */ +}; + +static int rcv_implied_slack(NPP *npp, void *info); + +void npp_implied_slack(NPP *npp, NPPCOL *q) +{ /* process column singleton (implied slack variable) */ + struct implied_slack *info; + NPPROW *p; + NPPAIJ *aij; + NPPLFE *lfe; + /* the column must be non-integral non-fixed singleton */ + xassert(!q->is_int); + xassert(q->lb < q->ub); + xassert(q->ptr != NULL && q->ptr->c_next == NULL); + /* corresponding row must be equality constraint */ + aij = q->ptr; + p = aij->row; + xassert(p->lb == p->ub); + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_implied_slack, sizeof(struct implied_slack)); + info->p = p->i; + info->q = q->j; + info->apq = aij->val; + info->b = p->lb; + info->c = q->coef; + info->ptr = NULL; + /* save row coefficients a[p,j], j != q, and substitute x[q] + into the objective row */ + for (aij = p->ptr; aij != NULL; aij = aij->r_next) + { if (aij->col == q) continue; /* skip a[p,q] */ + lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); + lfe->ref = aij->col->j; + lfe->val = aij->val; + lfe->next = info->ptr; + info->ptr = lfe; + aij->col->coef -= info->c * (aij->val / info->apq); + } + npp->c0 += info->c * (info->b / info->apq); + /* compute new row bounds */ + if (info->apq > 0.0) + { p->lb = (q->ub == +DBL_MAX ? + -DBL_MAX : info->b - info->apq * q->ub); + p->ub = (q->lb == -DBL_MAX ? + +DBL_MAX : info->b - info->apq * q->lb); + } + else + { p->lb = (q->lb == -DBL_MAX ? + -DBL_MAX : info->b - info->apq * q->lb); + p->ub = (q->ub == +DBL_MAX ? + +DBL_MAX : info->b - info->apq * q->ub); + } + /* remove the column from the problem */ + npp_del_col(npp, q); + return; +} + +static int rcv_implied_slack(NPP *npp, void *_info) +{ /* recover column singleton (implied slack variable) */ + struct implied_slack *info = _info; + NPPLFE *lfe; + double temp; + if (npp->sol == GLP_SOL) + { /* assign statuses to row p and column q */ + if (npp->r_stat[info->p] == GLP_BS || + npp->r_stat[info->p] == GLP_NF) + npp->c_stat[info->q] = npp->r_stat[info->p]; + else if (npp->r_stat[info->p] == GLP_NL) + npp->c_stat[info->q] = + (char)(info->apq > 0.0 ? GLP_NU : GLP_NL); + else if (npp->r_stat[info->p] == GLP_NU) + npp->c_stat[info->q] = + (char)(info->apq > 0.0 ? GLP_NL : GLP_NU); + else + { npp_error(); + return 1; + } + npp->r_stat[info->p] = GLP_NS; + } + if (npp->sol != GLP_MIP) + { /* compute multiplier for row p */ + npp->r_pi[info->p] += info->c / info->apq; + } + /* compute value of column q */ + temp = info->b; + for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) + temp -= lfe->val * npp->c_value[lfe->ref]; + npp->c_value[info->q] = temp / info->apq; + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_implied_free - process column singleton (implied free variable) +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_implied_free(NPP *npp, NPPCOL *q); +* +* DESCRIPTION +* +* The routine npp_implied_free processes column q: +* +* l[q] <= x[q] <= u[q], (1) +* +* having non-zero coefficient in the only row p, which is inequality +* constraint: +* +* L[p] <= sum a[p,j] x[j] + a[p,q] x[q] <= U[p], (2) +* j!=q +* +* where l[q] < u[q], L[p] < U[p], L[p] > -oo and/or U[p] < +oo. +* +* RETURNS +* +* 0 - success; +* +* 1 - column lower and/or upper bound(s) can be active; +* +* 2 - problem has no dual feasible solution. +* +* PROBLEM TRANSFORMATION +* +* Constraint (2) can be written as follows: +* +* L[p] - sum a[p,j] x[j] <= a[p,q] x[q] <= U[p] - sum a[p,j] x[j], +* j!=q j!=q +* +* from which it follows that: +* +* alfa <= a[p,q] x[q] <= beta, (3) +* +* where +* +* alfa = inf(L[p] - sum a[p,j] x[j]) = +* j!=q +* +* = L[p] - sup sum a[p,j] x[j] = (4) +* j!=q +* +* = L[p] - sum a[p,j] u[j] - sum a[p,j] l[j], +* j in Jp j in Jn +* +* beta = sup(L[p] - sum a[p,j] x[j]) = +* j!=q +* +* = L[p] - inf sum a[p,j] x[j] = (5) +* j!=q +* +* = L[p] - sum a[p,j] l[j] - sum a[p,j] u[j], +* j in Jp j in Jn +* +* Jp = {j != q: a[p,j] > 0}, Jn = {j != q: a[p,j] < 0}. (6) +* +* Inequality (3) defines implied bounds of variable x[q]: +* +* l'[q] <= x[q] <= u'[q], (7) +* +* where +* +* ( alfa / a[p,q], if a[p,q] > 0 +* l'[q] = < (8a) +* ( beta / a[p,q], if a[p,q] < 0 +* +* ( beta / a[p,q], if a[p,q] > 0 +* u'[q] = < (8b) +* ( alfa / a[p,q], if a[p,q] < 0 +* +* Thus, if l'[q] > l[q] - eps and u'[q] < u[q] + eps, where eps is +* an absolute tolerance for column value, column bounds (1) cannot be +* active, in which case column q can be replaced by equivalent free +* (unbounded) column. +* +* Note that column q is column singleton, so in the dual system of the +* original problem it corresponds to the following row singleton: +* +* a[p,q] pi[p] + lambda[q] = c[q], (9) +* +* from which it follows that: +* +* pi[p] = (c[q] - lambda[q]) / a[p,q]. (10) +* +* Let x[q] be implied free (unbounded) variable. Then column q can be +* only basic, so its multiplier lambda[q] is equal to zero, and from +* (10) we have: +* +* pi[p] = c[q] / a[p,q]. (11) +* +* There are possible three cases: +* +* 1) pi[p] < -eps, where eps is an absolute tolerance for row +* multiplier. In this case, to provide dual feasibility of the +* original problem, row p must be active on its lower bound, and +* if its lower bound does not exist (L[p] = -oo), the problem has +* no dual feasible solution; +* +* 2) pi[p] > +eps. In this case row p must be active on its upper +* bound, and if its upper bound does not exist (U[p] = +oo), the +* problem has no dual feasible solution; +* +* 3) -eps <= pi[p] <= +eps. In this case any (either lower or upper) +* bound of row p can be active, because this does not affect dual +* feasibility. +* +* Thus, in all three cases original inequality constraint (2) can be +* replaced by equality constraint, where the right-hand side is either +* lower or upper bound of row p, and bounds of column q can be removed +* that makes it free (unbounded). (May note that this transformation +* can be followed by transformation "Column singleton (implied slack +* variable)" performed by the routine npp_implied_slack.) +* +* RECOVERING BASIC SOLUTION +* +* Status of row p in solution to the original problem is determined +* by its status in solution to the transformed problem and its bound, +* which was choosen to be active: +* +* +-----------------------+--------+--------------------+ +* | Status of row p | Active | Status of row p | +* | (transformed problem) | bound | (original problem) | +* +-----------------------+--------+--------------------+ +* | GLP_BS | L[p] | GLP_BS | +* | GLP_BS | U[p] | GLP_BS | +* | GLP_NS | L[p] | GLP_NL | +* | GLP_NS | U[p] | GLP_NU | +* +-----------------------+--------+--------------------+ +* +* Value of row multiplier pi[p] (as well as value of column q) in +* solution to the original problem is the same as in solution to the +* transformed problem. +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* Value of row multiplier pi[p] in solution to the original problem is +* the same as in solution to the transformed problem. +* +* RECOVERING MIP SOLUTION +* +* None needed. */ + +struct implied_free +{ /* column singleton (implied free variable) */ + int p; + /* row reference number */ + char stat; + /* row status: + GLP_NL - active constraint on lower bound + GLP_NU - active constraint on upper bound */ +}; + +static int rcv_implied_free(NPP *npp, void *info); + +int npp_implied_free(NPP *npp, NPPCOL *q) +{ /* process column singleton (implied free variable) */ + struct implied_free *info; + NPPROW *p; + NPPAIJ *apq, *aij; + double alfa, beta, l, u, pi, eps; + /* the column must be non-fixed singleton */ + xassert(q->lb < q->ub); + xassert(q->ptr != NULL && q->ptr->c_next == NULL); + /* corresponding row must be inequality constraint */ + apq = q->ptr; + p = apq->row; + xassert(p->lb != -DBL_MAX || p->ub != +DBL_MAX); + xassert(p->lb < p->ub); + /* compute alfa */ + alfa = p->lb; + if (alfa != -DBL_MAX) + { for (aij = p->ptr; aij != NULL; aij = aij->r_next) + { if (aij == apq) continue; /* skip a[p,q] */ + if (aij->val > 0.0) + { if (aij->col->ub == +DBL_MAX) + { alfa = -DBL_MAX; + break; + } + alfa -= aij->val * aij->col->ub; + } + else /* < 0.0 */ + { if (aij->col->lb == -DBL_MAX) + { alfa = -DBL_MAX; + break; + } + alfa -= aij->val * aij->col->lb; + } + } + } + /* compute beta */ + beta = p->ub; + if (beta != +DBL_MAX) + { for (aij = p->ptr; aij != NULL; aij = aij->r_next) + { if (aij == apq) continue; /* skip a[p,q] */ + if (aij->val > 0.0) + { if (aij->col->lb == -DBL_MAX) + { beta = +DBL_MAX; + break; + } + beta -= aij->val * aij->col->lb; + } + else /* < 0.0 */ + { if (aij->col->ub == +DBL_MAX) + { beta = +DBL_MAX; + break; + } + beta -= aij->val * aij->col->ub; + } + } + } + /* compute implied column lower bound l'[q] */ + if (apq->val > 0.0) + l = (alfa == -DBL_MAX ? -DBL_MAX : alfa / apq->val); + else /* < 0.0 */ + l = (beta == +DBL_MAX ? -DBL_MAX : beta / apq->val); + /* compute implied column upper bound u'[q] */ + if (apq->val > 0.0) + u = (beta == +DBL_MAX ? +DBL_MAX : beta / apq->val); + else + u = (alfa == -DBL_MAX ? +DBL_MAX : alfa / apq->val); + /* check if column lower bound l[q] can be active */ + if (q->lb != -DBL_MAX) + { eps = 1e-9 + 1e-12 * fabs(q->lb); + if (l < q->lb - eps) return 1; /* yes, it can */ + } + /* check if column upper bound u[q] can be active */ + if (q->ub != +DBL_MAX) + { eps = 1e-9 + 1e-12 * fabs(q->ub); + if (u > q->ub + eps) return 1; /* yes, it can */ + } + /* okay; make column q free (unbounded) */ + q->lb = -DBL_MAX, q->ub = +DBL_MAX; + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_implied_free, sizeof(struct implied_free)); + info->p = p->i; + info->stat = -1; + /* compute row multiplier pi[p] */ + pi = q->coef / apq->val; + /* check dual feasibility for row p */ + if (pi > +DBL_EPSILON) + { /* lower bound L[p] must be active */ + if (p->lb != -DBL_MAX) +nl: { info->stat = GLP_NL; + p->ub = p->lb; + } + else + { if (pi > +1e-5) return 2; /* dual infeasibility */ + /* take a chance on U[p] */ + xassert(p->ub != +DBL_MAX); + goto nu; + } + } + else if (pi < -DBL_EPSILON) + { /* upper bound U[p] must be active */ + if (p->ub != +DBL_MAX) +nu: { info->stat = GLP_NU; + p->lb = p->ub; + } + else + { if (pi < -1e-5) return 2; /* dual infeasibility */ + /* take a chance on L[p] */ + xassert(p->lb != -DBL_MAX); + goto nl; + } + } + else + { /* any bound (either L[p] or U[p]) can be made active */ + if (p->ub == +DBL_MAX) + { xassert(p->lb != -DBL_MAX); + goto nl; + } + if (p->lb == -DBL_MAX) + { xassert(p->ub != +DBL_MAX); + goto nu; + } + if (fabs(p->lb) <= fabs(p->ub)) goto nl; else goto nu; + } + return 0; +} + +static int rcv_implied_free(NPP *npp, void *_info) +{ /* recover column singleton (implied free variable) */ + struct implied_free *info = _info; + if (npp->sol == GLP_SOL) + { if (npp->r_stat[info->p] == GLP_BS) + npp->r_stat[info->p] = GLP_BS; + else if (npp->r_stat[info->p] == GLP_NS) + { xassert(info->stat == GLP_NL || info->stat == GLP_NU); + npp->r_stat[info->p] = info->stat; + } + else + { npp_error(); + return 1; + } + } + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_eq_doublet - process row doubleton (equality constraint) +* +* SYNOPSIS +* +* #include "glpnpp.h" +* NPPCOL *npp_eq_doublet(NPP *npp, NPPROW *p); +* +* DESCRIPTION +* +* The routine npp_eq_doublet processes row p, which is equality +* constraint having exactly two non-zero coefficients: +* +* a[p,q] x[q] + a[p,r] x[r] = b. (1) +* +* As the result of processing one of columns q or r is eliminated from +* all other rows and, thus, becomes column singleton of type "implied +* slack variable". Row p is not changed and along with column q and r +* remains in the problem. +* +* RETURNS +* +* The routine npp_eq_doublet returns pointer to the descriptor of that +* column q or r which has been eliminated. If, due to some reason, the +* elimination was not performed, the routine returns NULL. +* +* PROBLEM TRANSFORMATION +* +* First, we decide which column q or r will be eliminated. Let it be +* column q. Consider i-th constraint row, where column q has non-zero +* coefficient a[i,q] != 0: +* +* L[i] <= sum a[i,j] x[j] <= U[i]. (2) +* j +* +* In order to eliminate column q from row (2) we subtract from it row +* (1) multiplied by gamma[i] = a[i,q] / a[p,q], i.e. we replace in the +* transformed problem row (2) by its linear combination with row (1). +* This transformation changes only coefficients in columns q and r, +* and bounds of row i as follows: +* +* a~[i,q] = a[i,q] - gamma[i] a[p,q] = 0, (3) +* +* a~[i,r] = a[i,r] - gamma[i] a[p,r], (4) +* +* L~[i] = L[i] - gamma[i] b, (5) +* +* U~[i] = U[i] - gamma[i] b. (6) +* +* RECOVERING BASIC SOLUTION +* +* The transformation of the primal system of the original problem: +* +* L <= A x <= U (7) +* +* is equivalent to multiplying from the left a transformation matrix F +* by components of this primal system, which in the transformed problem +* becomes the following: +* +* F L <= F A x <= F U ==> L~ <= A~x <= U~. (8) +* +* The matrix F has the following structure: +* +* ( 1 -gamma[1] ) +* ( ) +* ( 1 -gamma[2] ) +* ( ) +* ( ... ... ) +* ( ) +* F = ( 1 -gamma[p-1] ) (9) +* ( ) +* ( 1 ) +* ( ) +* ( -gamma[p+1] 1 ) +* ( ) +* ( ... ... ) +* +* where its column containing elements -gamma[i] corresponds to row p +* of the primal system. +* +* From (8) it follows that the dual system of the original problem: +* +* A'pi + lambda = c, (10) +* +* in the transformed problem becomes the following: +* +* A'F'inv(F')pi + lambda = c ==> (A~)'pi~ + lambda = c, (11) +* +* where: +* +* pi~ = inv(F')pi (12) +* +* is the vector of row multipliers in the transformed problem. Thus: +* +* pi = F'pi~. (13) +* +* Therefore, as it follows from (13), value of multiplier for row p in +* solution to the original problem can be computed as follows: +* +* pi[p] = pi~[p] - sum gamma[i] pi~[i], (14) +* i +* +* where pi~[i] = pi[i] is multiplier for row i (i != p). +* +* Note that the statuses of all rows and columns are not changed. +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* Multiplier for row p in solution to the original problem is computed +* with formula (14). +* +* RECOVERING MIP SOLUTION +* +* None needed. */ + +struct eq_doublet +{ /* row doubleton (equality constraint) */ + int p; + /* row reference number */ + double apq; + /* constraint coefficient a[p,q] */ + NPPLFE *ptr; + /* list of non-zero coefficients a[i,q], i != p */ +}; + +static int rcv_eq_doublet(NPP *npp, void *info); + +NPPCOL *npp_eq_doublet(NPP *npp, NPPROW *p) +{ /* process row doubleton (equality constraint) */ + struct eq_doublet *info; + NPPROW *i; + NPPCOL *q, *r; + NPPAIJ *apq, *apr, *aiq, *air, *next; + NPPLFE *lfe; + double gamma; + /* the row must be doubleton equality constraint */ + xassert(p->lb == p->ub); + xassert(p->ptr != NULL && p->ptr->r_next != NULL && + p->ptr->r_next->r_next == NULL); + /* choose column to be eliminated */ + { NPPAIJ *a1, *a2; + a1 = p->ptr, a2 = a1->r_next; + if (fabs(a2->val) < 0.001 * fabs(a1->val)) + { /* only first column can be eliminated, because second one + has too small constraint coefficient */ + apq = a1, apr = a2; + } + else if (fabs(a1->val) < 0.001 * fabs(a2->val)) + { /* only second column can be eliminated, because first one + has too small constraint coefficient */ + apq = a2, apr = a1; + } + else + { /* both columns are appropriate; choose that one which is + shorter to minimize fill-in */ + if (npp_col_nnz(npp, a1->col) <= npp_col_nnz(npp, a2->col)) + { /* first column is shorter */ + apq = a1, apr = a2; + } + else + { /* second column is shorter */ + apq = a2, apr = a1; + } + } + } + /* now columns q and r have been chosen */ + q = apq->col, r = apr->col; + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_eq_doublet, sizeof(struct eq_doublet)); + info->p = p->i; + info->apq = apq->val; + info->ptr = NULL; + /* transform each row i (i != p), where a[i,q] != 0, to eliminate + column q */ + for (aiq = q->ptr; aiq != NULL; aiq = next) + { next = aiq->c_next; + if (aiq == apq) continue; /* skip row p */ + i = aiq->row; /* row i to be transformed */ + /* save constraint coefficient a[i,q] */ + if (npp->sol != GLP_MIP) + { lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); + lfe->ref = i->i; + lfe->val = aiq->val; + lfe->next = info->ptr; + info->ptr = lfe; + } + /* find coefficient a[i,r] in row i */ + for (air = i->ptr; air != NULL; air = air->r_next) + if (air->col == r) break; + /* if a[i,r] does not exist, create a[i,r] = 0 */ + if (air == NULL) + air = npp_add_aij(npp, i, r, 0.0); + /* compute gamma[i] = a[i,q] / a[p,q] */ + gamma = aiq->val / apq->val; + /* (row i) := (row i) - gamma[i] * (row p); see (3)-(6) */ + /* new a[i,q] is exact zero due to elimnation; remove it from + row i */ + npp_del_aij(npp, aiq); + /* compute new a[i,r] */ + air->val -= gamma * apr->val; + /* if new a[i,r] is close to zero due to numeric cancelation, + remove it from row i */ + if (fabs(air->val) <= 1e-10) + npp_del_aij(npp, air); + /* compute new lower and upper bounds of row i */ + if (i->lb == i->ub) + i->lb = i->ub = (i->lb - gamma * p->lb); + else + { if (i->lb != -DBL_MAX) + i->lb -= gamma * p->lb; + if (i->ub != +DBL_MAX) + i->ub -= gamma * p->lb; + } + } + return q; +} + +static int rcv_eq_doublet(NPP *npp, void *_info) +{ /* recover row doubleton (equality constraint) */ + struct eq_doublet *info = _info; + NPPLFE *lfe; + double gamma, temp; + /* we assume that processing row p is followed by processing + column q as singleton of type "implied slack variable", in + which case row p must always be active equality constraint */ + if (npp->sol == GLP_SOL) + { if (npp->r_stat[info->p] != GLP_NS) + { npp_error(); + return 1; + } + } + if (npp->sol != GLP_MIP) + { /* compute value of multiplier for row p; see (14) */ + temp = npp->r_pi[info->p]; + for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) + { gamma = lfe->val / info->apq; /* a[i,q] / a[p,q] */ + temp -= gamma * npp->r_pi[lfe->ref]; + } + npp->r_pi[info->p] = temp; + } + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_forcing_row - process forcing row +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_forcing_row(NPP *npp, NPPROW *p, int at); +* +* DESCRIPTION +* +* The routine npp_forcing row processes row p of general format: +* +* L[p] <= sum a[p,j] x[j] <= U[p], (1) +* j +* +* l[j] <= x[j] <= u[j], (2) +* +* where L[p] <= U[p] and l[j] < u[j] for all a[p,j] != 0. It is also +* assumed that: +* +* 1) if at = 0 then |L[p] - U'[p]| <= eps, where U'[p] is implied +* row upper bound (see below), eps is an absolute tolerance for row +* value; +* +* 2) if at = 1 then |U[p] - L'[p]| <= eps, where L'[p] is implied +* row lower bound (see below). +* +* RETURNS +* +* 0 - success; +* +* 1 - cannot fix columns due to too small constraint coefficients. +* +* PROBLEM TRANSFORMATION +* +* Implied lower and upper bounds of row (1) are determined by bounds +* of corresponding columns (variables) as follows: +* +* L'[p] = inf sum a[p,j] x[j] = +* j +* (3) +* = sum a[p,j] l[j] + sum a[p,j] u[j], +* j in Jp j in Jn +* +* U'[p] = sup sum a[p,j] x[j] = +* (4) +* = sum a[p,j] u[j] + sum a[p,j] l[j], +* j in Jp j in Jn +* +* Jp = {j: a[p,j] > 0}, Jn = {j: a[p,j] < 0}. (5) +* +* If L[p] =~ U'[p] (at = 0), solution can be primal feasible only when +* all variables take their boundary values as defined by (4): +* +* ( u[j], if j in Jp +* x[j] = < (6) +* ( l[j], if j in Jn +* +* Similarly, if U[p] =~ L'[p] (at = 1), solution can be primal feasible +* only when all variables take their boundary values as defined by (3): +* +* ( l[j], if j in Jp +* x[j] = < (7) +* ( u[j], if j in Jn +* +* Condition (6) or (7) allows fixing all columns (variables x[j]) +* in row (1) on their bounds and then removing them from the problem +* (see the routine npp_fixed_col). Due to this row p becomes redundant, +* so it can be replaced by equivalent free (unbounded) row and also +* removed from the problem (see the routine npp_free_row). +* +* 1. To apply this transformation row (1) should not have coefficients +* whose magnitude is too small, i.e. all a[p,j] should satisfy to +* the following condition: +* +* |a[p,j]| >= eps * max(1, |a[p,k]|), (8) +* k +* where eps is a relative tolerance for constraint coefficients. +* Otherwise, fixing columns may be numerically unreliable and may +* lead to wrong solution. +* +* 2. The routine fixes columns and remove bounds of row p, however, +* it does not remove the row and columns from the problem. +* +* RECOVERING BASIC SOLUTION +* +* In the transformed problem row p being inactive constraint is +* assigned status GLP_BS (as the result of transformation of free +* row), and all columns in this row are assigned status GLP_NS (as the +* result of transformation of fixed columns). +* +* Note that in the dual system of the transformed (as well as original) +* problem every column j in row p corresponds to the following row: +* +* sum a[i,j] pi[i] + a[p,j] pi[p] + lambda[j] = c[j], (9) +* i!=p +* +* from which it follows that: +* +* lambda[j] = c[j] - sum a[i,j] pi[i] - a[p,j] pi[p]. (10) +* i!=p +* +* In the transformed problem values of all multipliers pi[i] are known +* (including pi[i], whose value is zero, since row p is inactive). +* Thus, using formula (10) it is possible to compute values of +* multipliers lambda[j] for all columns in row p. +* +* Note also that in the original problem all columns in row p are +* bounded, not fixed. So status GLP_NS assigned to every such column +* must be changed to GLP_NL or GLP_NU depending on which bound the +* corresponding column has been fixed. This status change may lead to +* dual feasibility violation for solution of the original problem, +* because now column multipliers must satisfy to the following +* condition: +* +* ( >= 0, if status of column j is GLP_NL, +* lambda[j] < (11) +* ( <= 0, if status of column j is GLP_NU. +* +* If this condition holds, solution to the original problem is the +* same as to the transformed problem. Otherwise, we have to perform +* one degenerate pivoting step of the primal simplex method to obtain +* dual feasible (hence, optimal) solution to the original problem as +* follows. If, on problem transformation, row p was made active on its +* lower bound (case at = 0), we change its status to GLP_NL (or GLP_NS) +* and start increasing its multiplier pi[p]. Otherwise, if row p was +* made active on its upper bound (case at = 1), we change its status +* to GLP_NU (or GLP_NS) and start decreasing pi[p]. From (10) it +* follows that: +* +* delta lambda[j] = - a[p,j] * delta pi[p] = - a[p,j] pi[p]. (12) +* +* Simple analysis of formulae (3)-(5) shows that changing pi[p] in the +* specified direction causes increasing lambda[j] for every column j +* assigned status GLP_NL (delta lambda[j] > 0) and decreasing lambda[j] +* for every column j assigned status GLP_NU (delta lambda[j] < 0). It +* is understood that once the last lambda[q], which violates condition +* (11), has reached zero, multipliers lambda[j] for all columns get +* valid signs. Such column q can be determined as follows. Let d[j] be +* initial value of lambda[j] (i.e. reduced cost of column j) in the +* transformed problem computed with formula (10) when pi[p] = 0. Then +* lambda[j] = d[j] + delta lambda[j], and from (12) it follows that +* lambda[j] becomes zero if: +* +* delta lambda[j] = - a[p,j] pi[p] = - d[j] ==> +* (13) +* pi[p] = d[j] / a[p,j]. +* +* Therefore, the last column q, for which lambda[q] becomes zero, can +* be determined from the following condition: +* +* |d[q] / a[p,q]| = max |pi[p]| = max |d[j] / a[p,j]|, (14) +* j in D j in D +* +* where D is a set of columns j whose, reduced costs d[j] have invalid +* signs, i.e. violate condition (11). (Thus, if D is empty, solution +* to the original problem is the same as solution to the transformed +* problem, and no correction is needed as was noticed above.) In +* solution to the original problem column q is assigned status GLP_BS, +* since it replaces column of auxiliary variable of row p (becoming +* active) in the basis, and multiplier for row p is assigned its new +* value, which is pi[p] = d[q] / a[p,q]. Note that due to primal +* degeneracy values of all columns having non-zero coefficients in row +* p remain unchanged. +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* Value of multiplier pi[p] in solution to the original problem is +* corrected in the same way as for basic solution. Values of all +* columns having non-zero coefficients in row p remain unchanged. +* +* RECOVERING MIP SOLUTION +* +* None needed. */ + +struct forcing_col +{ /* column fixed on its bound by forcing row */ + int j; + /* column reference number */ + char stat; + /* original column status: + GLP_NL - fixed on lower bound + GLP_NU - fixed on upper bound */ + double a; + /* constraint coefficient a[p,j] */ + double c; + /* objective coefficient c[j] */ + NPPLFE *ptr; + /* list of non-zero coefficients a[i,j], i != p */ + struct forcing_col *next; + /* pointer to another column fixed by forcing row */ +}; + +struct forcing_row +{ /* forcing row */ + int p; + /* row reference number */ + char stat; + /* status assigned to the row if it becomes active: + GLP_NS - active equality constraint + GLP_NL - inequality constraint with lower bound active + GLP_NU - inequality constraint with upper bound active */ + struct forcing_col *ptr; + /* list of all columns having non-zero constraint coefficient + a[p,j] in the forcing row */ +}; + +static int rcv_forcing_row(NPP *npp, void *info); + +int npp_forcing_row(NPP *npp, NPPROW *p, int at) +{ /* process forcing row */ + struct forcing_row *info; + struct forcing_col *col = NULL; + NPPCOL *j; + NPPAIJ *apj, *aij; + NPPLFE *lfe; + double big; + xassert(at == 0 || at == 1); + /* determine maximal magnitude of the row coefficients */ + big = 1.0; + for (apj = p->ptr; apj != NULL; apj = apj->r_next) + if (big < fabs(apj->val)) big = fabs(apj->val); + /* if there are too small coefficients in the row, transformation + should not be applied */ + for (apj = p->ptr; apj != NULL; apj = apj->r_next) + if (fabs(apj->val) < 1e-7 * big) return 1; + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_forcing_row, sizeof(struct forcing_row)); + info->p = p->i; + if (p->lb == p->ub) + { /* equality constraint */ + info->stat = GLP_NS; + } + else if (at == 0) + { /* inequality constraint; case L[p] = U'[p] */ + info->stat = GLP_NL; + xassert(p->lb != -DBL_MAX); + } + else /* at == 1 */ + { /* inequality constraint; case U[p] = L'[p] */ + info->stat = GLP_NU; + xassert(p->ub != +DBL_MAX); + } + info->ptr = NULL; + /* scan the forcing row, fix columns at corresponding bounds, and + save column information (the latter is not needed for MIP) */ + for (apj = p->ptr; apj != NULL; apj = apj->r_next) + { /* column j has non-zero coefficient in the forcing row */ + j = apj->col; + /* it must be non-fixed */ + xassert(j->lb < j->ub); + /* allocate stack entry to save column information */ + if (npp->sol != GLP_MIP) + { col = dmp_get_atom(npp->stack, sizeof(struct forcing_col)); + col->j = j->j; + col->stat = -1; /* will be set below */ + col->a = apj->val; + col->c = j->coef; + col->ptr = NULL; + col->next = info->ptr; + info->ptr = col; + } + /* fix column j */ + if (at == 0 && apj->val < 0.0 || at != 0 && apj->val > 0.0) + { /* at its lower bound */ + if (npp->sol != GLP_MIP) + col->stat = GLP_NL; + xassert(j->lb != -DBL_MAX); + j->ub = j->lb; + } + else + { /* at its upper bound */ + if (npp->sol != GLP_MIP) + col->stat = GLP_NU; + xassert(j->ub != +DBL_MAX); + j->lb = j->ub; + } + /* save column coefficients a[i,j], i != p */ + if (npp->sol != GLP_MIP) + { for (aij = j->ptr; aij != NULL; aij = aij->c_next) + { if (aij == apj) continue; /* skip a[p,j] */ + lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); + lfe->ref = aij->row->i; + lfe->val = aij->val; + lfe->next = col->ptr; + col->ptr = lfe; + } + } + } + /* make the row free (unbounded) */ + p->lb = -DBL_MAX, p->ub = +DBL_MAX; + return 0; +} + +static int rcv_forcing_row(NPP *npp, void *_info) +{ /* recover forcing row */ + struct forcing_row *info = _info; + struct forcing_col *col, *piv; + NPPLFE *lfe; + double d, big, temp; + if (npp->sol == GLP_MIP) goto done; + /* initially solution to the original problem is the same as + to the transformed problem, where row p is inactive constraint + with pi[p] = 0, and all columns are non-basic */ + if (npp->sol == GLP_SOL) + { if (npp->r_stat[info->p] != GLP_BS) + { npp_error(); + return 1; + } + for (col = info->ptr; col != NULL; col = col->next) + { if (npp->c_stat[col->j] != GLP_NS) + { npp_error(); + return 1; + } + npp->c_stat[col->j] = col->stat; /* original status */ + } + } + /* compute reduced costs d[j] for all columns with formula (10) + and store them in col.c instead objective coefficients */ + for (col = info->ptr; col != NULL; col = col->next) + { d = col->c; + for (lfe = col->ptr; lfe != NULL; lfe = lfe->next) + d -= lfe->val * npp->r_pi[lfe->ref]; + col->c = d; + } + /* consider columns j, whose multipliers lambda[j] has wrong + sign in solution to the transformed problem (where lambda[j] = + d[j]), and choose column q, whose multipler lambda[q] reaches + zero last on changing row multiplier pi[p]; see (14) */ + piv = NULL, big = 0.0; + for (col = info->ptr; col != NULL; col = col->next) + { d = col->c; /* d[j] */ + temp = fabs(d / col->a); + if (col->stat == GLP_NL) + { /* column j has active lower bound */ + if (d < 0.0 && big < temp) + piv = col, big = temp; + } + else if (col->stat == GLP_NU) + { /* column j has active upper bound */ + if (d > 0.0 && big < temp) + piv = col, big = temp; + } + else + { npp_error(); + return 1; + } + } + /* if column q does not exist, no correction is needed */ + if (piv != NULL) + { /* correct solution; row p becomes active constraint while + column q becomes basic */ + if (npp->sol == GLP_SOL) + { npp->r_stat[info->p] = info->stat; + npp->c_stat[piv->j] = GLP_BS; + } + /* assign new value to row multiplier pi[p] = d[p] / a[p,q] */ + npp->r_pi[info->p] = piv->c / piv->a; + } +done: return 0; +} + +/*********************************************************************** +* NAME +* +* npp_analyze_row - perform general row analysis +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_analyze_row(NPP *npp, NPPROW *p); +* +* DESCRIPTION +* +* The routine npp_analyze_row performs analysis of row p of general +* format: +* +* L[p] <= sum a[p,j] x[j] <= U[p], (1) +* j +* +* l[j] <= x[j] <= u[j], (2) +* +* where L[p] <= U[p] and l[j] <= u[j] for all a[p,j] != 0. +* +* RETURNS +* +* 0x?0 - row lower bound does not exist or is redundant; +* +* 0x?1 - row lower bound can be active; +* +* 0x?2 - row lower bound is a forcing bound; +* +* 0x0? - row upper bound does not exist or is redundant; +* +* 0x1? - row upper bound can be active; +* +* 0x2? - row upper bound is a forcing bound; +* +* 0x33 - row bounds are inconsistent with column bounds. +* +* ALGORITHM +* +* Analysis of row (1) is based on analysis of its implied lower and +* upper bounds, which are determined by bounds of corresponding columns +* (variables) as follows: +* +* L'[p] = inf sum a[p,j] x[j] = +* j +* (3) +* = sum a[p,j] l[j] + sum a[p,j] u[j], +* j in Jp j in Jn +* +* U'[p] = sup sum a[p,j] x[j] = +* (4) +* = sum a[p,j] u[j] + sum a[p,j] l[j], +* j in Jp j in Jn +* +* Jp = {j: a[p,j] > 0}, Jn = {j: a[p,j] < 0}. (5) +* +* (Note that bounds of all columns in row p are assumed to be correct, +* so L'[p] <= U'[p].) +* +* Analysis of row lower bound L[p] includes the following cases: +* +* 1) if L[p] > U'[p] + eps, where eps is an absolute tolerance for row +* value, row lower bound L[p] and implied row upper bound U'[p] are +* inconsistent, ergo, the problem has no primal feasible solution; +* +* 2) if U'[p] - eps <= L[p] <= U'[p] + eps, i.e. if L[p] =~ U'[p], +* the row is a forcing row on its lower bound (see description of +* the routine npp_forcing_row); +* +* 3) if L[p] > L'[p] + eps, row lower bound L[p] can be active (this +* conclusion does not account other rows in the problem); +* +* 4) if L[p] <= L'[p] + eps, row lower bound L[p] cannot be active, so +* it is redundant and can be removed (replaced by -oo). +* +* Analysis of row upper bound U[p] is performed in a similar way and +* includes the following cases: +* +* 1) if U[p] < L'[p] - eps, row upper bound U[p] and implied row lower +* bound L'[p] are inconsistent, ergo the problem has no primal +* feasible solution; +* +* 2) if L'[p] - eps <= U[p] <= L'[p] + eps, i.e. if U[p] =~ L'[p], +* the row is a forcing row on its upper bound (see description of +* the routine npp_forcing_row); +* +* 3) if U[p] < U'[p] - eps, row upper bound U[p] can be active (this +* conclusion does not account other rows in the problem); +* +* 4) if U[p] >= U'[p] - eps, row upper bound U[p] cannot be active, so +* it is redundant and can be removed (replaced by +oo). */ + +int npp_analyze_row(NPP *npp, NPPROW *p) +{ /* perform general row analysis */ + NPPAIJ *aij; + int ret = 0x00; + double l, u, eps; + xassert(npp == npp); + /* compute implied lower bound L'[p]; see (3) */ + l = 0.0; + for (aij = p->ptr; aij != NULL; aij = aij->r_next) + { if (aij->val > 0.0) + { if (aij->col->lb == -DBL_MAX) + { l = -DBL_MAX; + break; + } + l += aij->val * aij->col->lb; + } + else /* aij->val < 0.0 */ + { if (aij->col->ub == +DBL_MAX) + { l = -DBL_MAX; + break; + } + l += aij->val * aij->col->ub; + } + } + /* compute implied upper bound U'[p]; see (4) */ + u = 0.0; + for (aij = p->ptr; aij != NULL; aij = aij->r_next) + { if (aij->val > 0.0) + { if (aij->col->ub == +DBL_MAX) + { u = +DBL_MAX; + break; + } + u += aij->val * aij->col->ub; + } + else /* aij->val < 0.0 */ + { if (aij->col->lb == -DBL_MAX) + { u = +DBL_MAX; + break; + } + u += aij->val * aij->col->lb; + } + } + /* column bounds are assumed correct, so L'[p] <= U'[p] */ + /* check if row lower bound is consistent */ + if (p->lb != -DBL_MAX) + { eps = 1e-3 + 1e-6 * fabs(p->lb); + if (p->lb - eps > u) + { ret = 0x33; + goto done; + } + } + /* check if row upper bound is consistent */ + if (p->ub != +DBL_MAX) + { eps = 1e-3 + 1e-6 * fabs(p->ub); + if (p->ub + eps < l) + { ret = 0x33; + goto done; + } + } + /* check if row lower bound can be active/forcing */ + if (p->lb != -DBL_MAX) + { eps = 1e-9 + 1e-12 * fabs(p->lb); + if (p->lb - eps > l) + { if (p->lb + eps <= u) + ret |= 0x01; + else + ret |= 0x02; + } + } + /* check if row upper bound can be active/forcing */ + if (p->ub != +DBL_MAX) + { eps = 1e-9 + 1e-12 * fabs(p->ub); + if (p->ub + eps < u) + { /* check if the upper bound is forcing */ + if (p->ub - eps >= l) + ret |= 0x10; + else + ret |= 0x20; + } + } +done: return ret; +} + +/*********************************************************************** +* NAME +* +* npp_inactive_bound - remove row lower/upper inactive bound +* +* SYNOPSIS +* +* #include "glpnpp.h" +* void npp_inactive_bound(NPP *npp, NPPROW *p, int which); +* +* DESCRIPTION +* +* The routine npp_inactive_bound removes lower (if which = 0) or upper +* (if which = 1) bound of row p: +* +* L[p] <= sum a[p,j] x[j] <= U[p], +* +* which (bound) is assumed to be redundant. +* +* PROBLEM TRANSFORMATION +* +* If which = 0, current lower bound L[p] of row p is assigned -oo. +* If which = 1, current upper bound U[p] of row p is assigned +oo. +* +* RECOVERING BASIC SOLUTION +* +* If in solution to the transformed problem row p is inactive +* constraint (GLP_BS), its status is not changed in solution to the +* original problem. Otherwise, status of row p in solution to the +* original problem is defined by its type before transformation and +* its status in solution to the transformed problem as follows: +* +* +---------------------+-------+---------------+---------------+ +* | Row | Flag | Row status in | Row status in | +* | type | which | transfmd soln | original soln | +* +---------------------+-------+---------------+---------------+ +* | sum >= L[p] | 0 | GLP_NF | GLP_NL | +* | sum <= U[p] | 1 | GLP_NF | GLP_NU | +* | L[p] <= sum <= U[p] | 0 | GLP_NU | GLP_NU | +* | L[p] <= sum <= U[p] | 1 | GLP_NL | GLP_NL | +* | sum = L[p] = U[p] | 0 | GLP_NU | GLP_NS | +* | sum = L[p] = U[p] | 1 | GLP_NL | GLP_NS | +* +---------------------+-------+---------------+---------------+ +* +* RECOVERING INTERIOR-POINT SOLUTION +* +* None needed. +* +* RECOVERING MIP SOLUTION +* +* None needed. */ + +struct inactive_bound +{ /* row inactive bound */ + int p; + /* row reference number */ + char stat; + /* row status (if active constraint) */ +}; + +static int rcv_inactive_bound(NPP *npp, void *info); + +void npp_inactive_bound(NPP *npp, NPPROW *p, int which) +{ /* remove row lower/upper inactive bound */ + struct inactive_bound *info; + if (npp->sol == GLP_SOL) + { /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_inactive_bound, sizeof(struct inactive_bound)); + info->p = p->i; + if (p->ub == +DBL_MAX) + info->stat = GLP_NL; + else if (p->lb == -DBL_MAX) + info->stat = GLP_NU; + else if (p->lb != p->ub) + info->stat = (char)(which == 0 ? GLP_NU : GLP_NL); + else + info->stat = GLP_NS; + } + /* remove row inactive bound */ + if (which == 0) + { xassert(p->lb != -DBL_MAX); + p->lb = -DBL_MAX; + } + else if (which == 1) + { xassert(p->ub != +DBL_MAX); + p->ub = +DBL_MAX; + } + else + xassert(which != which); + return; +} + +static int rcv_inactive_bound(NPP *npp, void *_info) +{ /* recover row status */ + struct inactive_bound *info = _info; + if (npp->sol != GLP_SOL) + { npp_error(); + return 1; + } + if (npp->r_stat[info->p] == GLP_BS) + npp->r_stat[info->p] = GLP_BS; + else + npp->r_stat[info->p] = info->stat; + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_implied_bounds - determine implied column bounds +* +* SYNOPSIS +* +* #include "glpnpp.h" +* void npp_implied_bounds(NPP *npp, NPPROW *p); +* +* DESCRIPTION +* +* The routine npp_implied_bounds inspects general row (constraint) p: +* +* L[p] <= sum a[p,j] x[j] <= U[p], (1) +* +* l[j] <= x[j] <= u[j], (2) +* +* where L[p] <= U[p] and l[j] <= u[j] for all a[p,j] != 0, to compute +* implied bounds of columns (variables x[j]) in this row. +* +* The routine stores implied column bounds l'[j] and u'[j] in column +* descriptors (NPPCOL); it does not change current column bounds l[j] +* and u[j]. (Implied column bounds can be then used to strengthen the +* current column bounds; see the routines npp_implied_lower and +* npp_implied_upper). +* +* ALGORITHM +* +* Current column bounds (2) define implied lower and upper bounds of +* row (1) as follows: +* +* L'[p] = inf sum a[p,j] x[j] = +* j +* (3) +* = sum a[p,j] l[j] + sum a[p,j] u[j], +* j in Jp j in Jn +* +* U'[p] = sup sum a[p,j] x[j] = +* (4) +* = sum a[p,j] u[j] + sum a[p,j] l[j], +* j in Jp j in Jn +* +* Jp = {j: a[p,j] > 0}, Jn = {j: a[p,j] < 0}. (5) +* +* (Note that bounds of all columns in row p are assumed to be correct, +* so L'[p] <= U'[p].) +* +* If L[p] > L'[p] and/or U[p] < U'[p], the lower and/or upper bound of +* row (1) can be active, in which case such row defines implied bounds +* of its variables. +* +* Let x[k] be some variable having in row (1) coefficient a[p,k] != 0. +* Consider a case when row lower bound can be active (L[p] > L'[p]): +* +* sum a[p,j] x[j] >= L[p] ==> +* j +* +* sum a[p,j] x[j] + a[p,k] x[k] >= L[p] ==> +* j!=k +* (6) +* a[p,k] x[k] >= L[p] - sum a[p,j] x[j] ==> +* j!=k +* +* a[p,k] x[k] >= L[p,k], +* +* where +* +* L[p,k] = inf(L[p] - sum a[p,j] x[j]) = +* j!=k +* +* = L[p] - sup sum a[p,j] x[j] = (7) +* j!=k +* +* = L[p] - sum a[p,j] u[j] - sum a[p,j] l[j]. +* j in Jp\{k} j in Jn\{k} +* +* Thus: +* +* x[k] >= l'[k] = L[p,k] / a[p,k], if a[p,k] > 0, (8) +* +* x[k] <= u'[k] = L[p,k] / a[p,k], if a[p,k] < 0. (9) +* +* where l'[k] and u'[k] are implied lower and upper bounds of variable +* x[k], resp. +* +* Now consider a similar case when row upper bound can be active +* (U[p] < U'[p]): +* +* sum a[p,j] x[j] <= U[p] ==> +* j +* +* sum a[p,j] x[j] + a[p,k] x[k] <= U[p] ==> +* j!=k +* (10) +* a[p,k] x[k] <= U[p] - sum a[p,j] x[j] ==> +* j!=k +* +* a[p,k] x[k] <= U[p,k], +* +* where: +* +* U[p,k] = sup(U[p] - sum a[p,j] x[j]) = +* j!=k +* +* = U[p] - inf sum a[p,j] x[j] = (11) +* j!=k +* +* = U[p] - sum a[p,j] l[j] - sum a[p,j] u[j]. +* j in Jp\{k} j in Jn\{k} +* +* Thus: +* +* x[k] <= u'[k] = U[p,k] / a[p,k], if a[p,k] > 0, (12) +* +* x[k] >= l'[k] = U[p,k] / a[p,k], if a[p,k] < 0. (13) +* +* Note that in formulae (8), (9), (12), and (13) coefficient a[p,k] +* must not be too small in magnitude relatively to other non-zero +* coefficients in row (1), i.e. the following condition must hold: +* +* |a[p,k]| >= eps * max(1, |a[p,j]|), (14) +* j +* +* where eps is a relative tolerance for constraint coefficients. +* Otherwise the implied column bounds can be numerical inreliable. For +* example, using formula (8) for the following inequality constraint: +* +* 1e-12 x1 - x2 - x3 >= 0, +* +* where x1 >= -1, x2, x3, >= 0, may lead to numerically unreliable +* conclusion that x1 >= 0. +* +* Using formulae (8), (9), (12), and (13) to compute implied bounds +* for one variable requires |J| operations, where J = {j: a[p,j] != 0}, +* because this needs computing L[p,k] and U[p,k]. Thus, computing +* implied bounds for all variables in row (1) would require |J|^2 +* operations, that is not a good technique. However, the total number +* of operations can be reduced to |J| as follows. +* +* Let a[p,k] > 0. Then from (7) and (11) we have: +* +* L[p,k] = L[p] - (U'[p] - a[p,k] u[k]) = +* +* = L[p] - U'[p] + a[p,k] u[k], +* +* U[p,k] = U[p] - (L'[p] - a[p,k] l[k]) = +* +* = U[p] - L'[p] + a[p,k] l[k], +* +* where L'[p] and U'[p] are implied row lower and upper bounds defined +* by formulae (3) and (4). Substituting these expressions into (8) and +* (12) gives: +* +* l'[k] = L[p,k] / a[p,k] = u[k] + (L[p] - U'[p]) / a[p,k], (15) +* +* u'[k] = U[p,k] / a[p,k] = l[k] + (U[p] - L'[p]) / a[p,k]. (16) +* +* Similarly, if a[p,k] < 0, according to (7) and (11) we have: +* +* L[p,k] = L[p] - (U'[p] - a[p,k] l[k]) = +* +* = L[p] - U'[p] + a[p,k] l[k], +* +* U[p,k] = U[p] - (L'[p] - a[p,k] u[k]) = +* +* = U[p] - L'[p] + a[p,k] u[k], +* +* and substituting these expressions into (8) and (12) gives: +* +* l'[k] = U[p,k] / a[p,k] = u[k] + (U[p] - L'[p]) / a[p,k], (17) +* +* u'[k] = L[p,k] / a[p,k] = l[k] + (L[p] - U'[p]) / a[p,k]. (18) +* +* Note that formulae (15)-(18) can be used only if L'[p] and U'[p] +* exist. However, if for some variable x[j] it happens that l[j] = -oo +* and/or u[j] = +oo, values of L'[p] (if a[p,j] > 0) and/or U'[p] (if +* a[p,j] < 0) are undefined. Consider, therefore, the most general +* situation, when some column bounds (2) may not exist. +* +* Let: +* +* J' = {j : (a[p,j] > 0 and l[j] = -oo) or +* (19) +* (a[p,j] < 0 and u[j] = +oo)}. +* +* Then (assuming that row upper bound U[p] can be active) the following +* three cases are possible: +* +* 1) |J'| = 0. In this case L'[p] exists, thus, for all variables x[j] +* in row (1) we can use formulae (16) and (17); +* +* 2) J' = {k}. In this case L'[p] = -oo, however, U[p,k] (11) exists, +* so for variable x[k] we can use formulae (12) and (13). Note that +* for all other variables x[j] (j != k) l'[j] = -oo (if a[p,j] < 0) +* or u'[j] = +oo (if a[p,j] > 0); +* +* 3) |J'| > 1. In this case for all variables x[j] in row [1] we have +* l'[j] = -oo (if a[p,j] < 0) or u'[j] = +oo (if a[p,j] > 0). +* +* Similarly, let: +* +* J'' = {j : (a[p,j] > 0 and u[j] = +oo) or +* (20) +* (a[p,j] < 0 and l[j] = -oo)}. +* +* Then (assuming that row lower bound L[p] can be active) the following +* three cases are possible: +* +* 1) |J''| = 0. In this case U'[p] exists, thus, for all variables x[j] +* in row (1) we can use formulae (15) and (18); +* +* 2) J'' = {k}. In this case U'[p] = +oo, however, L[p,k] (7) exists, +* so for variable x[k] we can use formulae (8) and (9). Note that +* for all other variables x[j] (j != k) l'[j] = -oo (if a[p,j] > 0) +* or u'[j] = +oo (if a[p,j] < 0); +* +* 3) |J''| > 1. In this case for all variables x[j] in row (1) we have +* l'[j] = -oo (if a[p,j] > 0) or u'[j] = +oo (if a[p,j] < 0). */ + +void npp_implied_bounds(NPP *npp, NPPROW *p) +{ NPPAIJ *apj, *apk; + double big, eps, temp; + xassert(npp == npp); + /* initialize implied bounds for all variables and determine + maximal magnitude of row coefficients a[p,j] */ + big = 1.0; + for (apj = p->ptr; apj != NULL; apj = apj->r_next) + { apj->col->ll.ll = -DBL_MAX, apj->col->uu.uu = +DBL_MAX; + if (big < fabs(apj->val)) big = fabs(apj->val); + } + eps = 1e-6 * big; + /* process row lower bound (assuming that it can be active) */ + if (p->lb != -DBL_MAX) + { apk = NULL; + for (apj = p->ptr; apj != NULL; apj = apj->r_next) + { if (apj->val > 0.0 && apj->col->ub == +DBL_MAX || + apj->val < 0.0 && apj->col->lb == -DBL_MAX) + { if (apk == NULL) + apk = apj; + else + goto skip1; + } + } + /* if a[p,k] = NULL then |J'| = 0 else J' = { k } */ + temp = p->lb; + for (apj = p->ptr; apj != NULL; apj = apj->r_next) + { if (apj == apk) + /* skip a[p,k] */; + else if (apj->val > 0.0) + temp -= apj->val * apj->col->ub; + else /* apj->val < 0.0 */ + temp -= apj->val * apj->col->lb; + } + /* compute column implied bounds */ + if (apk == NULL) + { /* temp = L[p] - U'[p] */ + for (apj = p->ptr; apj != NULL; apj = apj->r_next) + { if (apj->val >= +eps) + { /* l'[j] := u[j] + (L[p] - U'[p]) / a[p,j] */ + apj->col->ll.ll = apj->col->ub + temp / apj->val; + } + else if (apj->val <= -eps) + { /* u'[j] := l[j] + (L[p] - U'[p]) / a[p,j] */ + apj->col->uu.uu = apj->col->lb + temp / apj->val; + } + } + } + else + { /* temp = L[p,k] */ + if (apk->val >= +eps) + { /* l'[k] := L[p,k] / a[p,k] */ + apk->col->ll.ll = temp / apk->val; + } + else if (apk->val <= -eps) + { /* u'[k] := L[p,k] / a[p,k] */ + apk->col->uu.uu = temp / apk->val; + } + } +skip1: ; + } + /* process row upper bound (assuming that it can be active) */ + if (p->ub != +DBL_MAX) + { apk = NULL; + for (apj = p->ptr; apj != NULL; apj = apj->r_next) + { if (apj->val > 0.0 && apj->col->lb == -DBL_MAX || + apj->val < 0.0 && apj->col->ub == +DBL_MAX) + { if (apk == NULL) + apk = apj; + else + goto skip2; + } + } + /* if a[p,k] = NULL then |J''| = 0 else J'' = { k } */ + temp = p->ub; + for (apj = p->ptr; apj != NULL; apj = apj->r_next) + { if (apj == apk) + /* skip a[p,k] */; + else if (apj->val > 0.0) + temp -= apj->val * apj->col->lb; + else /* apj->val < 0.0 */ + temp -= apj->val * apj->col->ub; + } + /* compute column implied bounds */ + if (apk == NULL) + { /* temp = U[p] - L'[p] */ + for (apj = p->ptr; apj != NULL; apj = apj->r_next) + { if (apj->val >= +eps) + { /* u'[j] := l[j] + (U[p] - L'[p]) / a[p,j] */ + apj->col->uu.uu = apj->col->lb + temp / apj->val; + } + else if (apj->val <= -eps) + { /* l'[j] := u[j] + (U[p] - L'[p]) / a[p,j] */ + apj->col->ll.ll = apj->col->ub + temp / apj->val; + } + } + } + else + { /* temp = U[p,k] */ + if (apk->val >= +eps) + { /* u'[k] := U[p,k] / a[p,k] */ + apk->col->uu.uu = temp / apk->val; + } + else if (apk->val <= -eps) + { /* l'[k] := U[p,k] / a[p,k] */ + apk->col->ll.ll = temp / apk->val; + } + } +skip2: ; + } + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpnpp04.c b/resources/3rdparty/glpk-4.57/src/glpnpp04.c new file mode 100644 index 000000000..925b1ba0f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpnpp04.c @@ -0,0 +1,1415 @@ +/* glpnpp04.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpnpp.h" + +/*********************************************************************** +* NAME +* +* npp_binarize_prob - binarize MIP problem +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_binarize_prob(NPP *npp); +* +* DESCRIPTION +* +* The routine npp_binarize_prob replaces in the original MIP problem +* every integer variable: +* +* l[q] <= x[q] <= u[q], (1) +* +* where l[q] < u[q], by an equivalent sum of binary variables. +* +* RETURNS +* +* The routine returns the number of integer variables for which the +* transformation failed, because u[q] - l[q] > d_max. +* +* PROBLEM TRANSFORMATION +* +* If variable x[q] has non-zero lower bound, it is first processed +* with the routine npp_lbnd_col. Thus, we can assume that: +* +* 0 <= x[q] <= u[q]. (2) +* +* If u[q] = 1, variable x[q] is already binary, so further processing +* is not needed. Let, therefore, that 2 <= u[q] <= d_max, and n be a +* smallest integer such that u[q] <= 2^n - 1 (n >= 2, since u[q] >= 2). +* Then variable x[q] can be replaced by the following sum: +* +* n-1 +* x[q] = sum 2^k x[k], (3) +* k=0 +* +* where x[k] are binary columns (variables). If u[q] < 2^n - 1, the +* following additional inequality constraint must be also included in +* the transformed problem: +* +* n-1 +* sum 2^k x[k] <= u[q]. (4) +* k=0 +* +* Note: Assuming that in the transformed problem x[q] becomes binary +* variable x[0], this transformation causes new n-1 binary variables +* to appear. +* +* Substituting x[q] from (3) to the objective row gives: +* +* z = sum c[j] x[j] + c[0] = +* j +* +* = sum c[j] x[j] + c[q] x[q] + c[0] = +* j!=q +* n-1 +* = sum c[j] x[j] + c[q] sum 2^k x[k] + c[0] = +* j!=q k=0 +* n-1 +* = sum c[j] x[j] + sum c[k] x[k] + c[0], +* j!=q k=0 +* +* where: +* +* c[k] = 2^k c[q], k = 0, ..., n-1. (5) +* +* And substituting x[q] from (3) to i-th constraint row i gives: +* +* L[i] <= sum a[i,j] x[j] <= U[i] ==> +* j +* +* L[i] <= sum a[i,j] x[j] + a[i,q] x[q] <= U[i] ==> +* j!=q +* n-1 +* L[i] <= sum a[i,j] x[j] + a[i,q] sum 2^k x[k] <= U[i] ==> +* j!=q k=0 +* n-1 +* L[i] <= sum a[i,j] x[j] + sum a[i,k] x[k] <= U[i], +* j!=q k=0 +* +* where: +* +* a[i,k] = 2^k a[i,q], k = 0, ..., n-1. (6) +* +* RECOVERING SOLUTION +* +* Value of variable x[q] is computed with formula (3). */ + +struct binarize +{ int q; + /* column reference number for x[q] = x[0] */ + int j; + /* column reference number for x[1]; x[2] has reference number + j+1, x[3] - j+2, etc. */ + int n; + /* total number of binary variables, n >= 2 */ +}; + +static int rcv_binarize_prob(NPP *npp, void *info); + +int npp_binarize_prob(NPP *npp) +{ /* binarize MIP problem */ + struct binarize *info; + NPPROW *row; + NPPCOL *col, *bin; + NPPAIJ *aij; + int u, n, k, temp, nfails, nvars, nbins, nrows; + /* new variables will be added to the end of the column list, so + we go from the end to beginning of the column list */ + nfails = nvars = nbins = nrows = 0; + for (col = npp->c_tail; col != NULL; col = col->prev) + { /* skip continuous variable */ + if (!col->is_int) continue; + /* skip fixed variable */ + if (col->lb == col->ub) continue; + /* skip binary variable */ + if (col->lb == 0.0 && col->ub == 1.0) continue; + /* check if the transformation is applicable */ + if (col->lb < -1e6 || col->ub > +1e6 || + col->ub - col->lb > 4095.0) + { /* unfortunately, not */ + nfails++; + continue; + } + /* process integer non-binary variable x[q] */ + nvars++; + /* make x[q] non-negative, if its lower bound is non-zero */ + if (col->lb != 0.0) + npp_lbnd_col(npp, col); + /* now 0 <= x[q] <= u[q] */ + xassert(col->lb == 0.0); + u = (int)col->ub; + xassert(col->ub == (double)u); + /* if x[q] is binary, further processing is not needed */ + if (u == 1) continue; + /* determine smallest n such that u <= 2^n - 1 (thus, n is the + number of binary variables needed) */ + n = 2, temp = 4; + while (u >= temp) + n++, temp += temp; + nbins += n; + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_binarize_prob, sizeof(struct binarize)); + info->q = col->j; + info->j = 0; /* will be set below */ + info->n = n; + /* if u < 2^n - 1, we need one additional row for (4) */ + if (u < temp - 1) + { row = npp_add_row(npp), nrows++; + row->lb = -DBL_MAX, row->ub = u; + } + else + row = NULL; + /* in the transformed problem variable x[q] becomes binary + variable x[0], so its objective and constraint coefficients + are not changed */ + col->ub = 1.0; + /* include x[0] into constraint (4) */ + if (row != NULL) + npp_add_aij(npp, row, col, 1.0); + /* add other binary variables x[1], ..., x[n-1] */ + for (k = 1, temp = 2; k < n; k++, temp += temp) + { /* add new binary variable x[k] */ + bin = npp_add_col(npp); + bin->is_int = 1; + bin->lb = 0.0, bin->ub = 1.0; + bin->coef = (double)temp * col->coef; + /* store column reference number for x[1] */ + if (info->j == 0) + info->j = bin->j; + else + xassert(info->j + (k-1) == bin->j); + /* duplicate constraint coefficients for x[k]; this also + automatically includes x[k] into constraint (4) */ + for (aij = col->ptr; aij != NULL; aij = aij->c_next) + npp_add_aij(npp, aij->row, bin, (double)temp * aij->val); + } + } + if (nvars > 0) + xprintf("%d integer variable(s) were replaced by %d binary one" + "s\n", nvars, nbins); + if (nrows > 0) + xprintf("%d row(s) were added due to binarization\n", nrows); + if (nfails > 0) + xprintf("Binarization failed for %d integer variable(s)\n", + nfails); + return nfails; +} + +static int rcv_binarize_prob(NPP *npp, void *_info) +{ /* recovery binarized variable */ + struct binarize *info = _info; + int k, temp; + double sum; + /* compute value of x[q]; see formula (3) */ + sum = npp->c_value[info->q]; + for (k = 1, temp = 2; k < info->n; k++, temp += temp) + sum += (double)temp * npp->c_value[info->j + (k-1)]; + npp->c_value[info->q] = sum; + return 0; +} + +/**********************************************************************/ + +struct elem +{ /* linear form element a[j] x[j] */ + double aj; + /* non-zero coefficient value */ + NPPCOL *xj; + /* pointer to variable (column) */ + struct elem *next; + /* pointer to another term */ +}; + +static struct elem *copy_form(NPP *npp, NPPROW *row, double s) +{ /* copy linear form */ + NPPAIJ *aij; + struct elem *ptr, *e; + ptr = NULL; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { e = dmp_get_atom(npp->pool, sizeof(struct elem)); + e->aj = s * aij->val; + e->xj = aij->col; + e->next = ptr; + ptr = e; + } + return ptr; +} + +static void drop_form(NPP *npp, struct elem *ptr) +{ /* drop linear form */ + struct elem *e; + while (ptr != NULL) + { e = ptr; + ptr = e->next; + dmp_free_atom(npp->pool, e, sizeof(struct elem)); + } + return; +} + +/*********************************************************************** +* NAME +* +* npp_is_packing - test if constraint is packing inequality +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_is_packing(NPP *npp, NPPROW *row); +* +* RETURNS +* +* If the specified row (constraint) is packing inequality (see below), +* the routine npp_is_packing returns non-zero. Otherwise, it returns +* zero. +* +* PACKING INEQUALITIES +* +* In canonical format the packing inequality is the following: +* +* sum x[j] <= 1, (1) +* j in J +* +* where all variables x[j] are binary. This inequality expresses the +* condition that in any integer feasible solution at most one variable +* from set J can take non-zero (unity) value while other variables +* must be equal to zero. W.l.o.g. it is assumed that |J| >= 2, because +* if J is empty or |J| = 1, the inequality (1) is redundant. +* +* In general case the packing inequality may include original variables +* x[j] as well as their complements x~[j]: +* +* sum x[j] + sum x~[j] <= 1, (2) +* j in Jp j in Jn +* +* where Jp and Jn are not intersected. Therefore, using substitution +* x~[j] = 1 - x[j] gives the packing inequality in generalized format: +* +* sum x[j] - sum x[j] <= 1 - |Jn|. (3) +* j in Jp j in Jn */ + +int npp_is_packing(NPP *npp, NPPROW *row) +{ /* test if constraint is packing inequality */ + NPPCOL *col; + NPPAIJ *aij; + int b; + xassert(npp == npp); + if (!(row->lb == -DBL_MAX && row->ub != +DBL_MAX)) + return 0; + b = 1; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { col = aij->col; + if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) + return 0; + if (aij->val == +1.0) + ; + else if (aij->val == -1.0) + b--; + else + return 0; + } + if (row->ub != (double)b) return 0; + return 1; +} + +/*********************************************************************** +* NAME +* +* npp_hidden_packing - identify hidden packing inequality +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_hidden_packing(NPP *npp, NPPROW *row); +* +* DESCRIPTION +* +* The routine npp_hidden_packing processes specified inequality +* constraint, which includes only binary variables, and the number of +* the variables is not less than two. If the original inequality is +* equivalent to a packing inequality, the routine replaces it by this +* equivalent inequality. If the original constraint is double-sided +* inequality, it is replaced by a pair of single-sided inequalities, +* if necessary. +* +* RETURNS +* +* If the original inequality constraint was replaced by equivalent +* packing inequality, the routine npp_hidden_packing returns non-zero. +* Otherwise, it returns zero. +* +* PROBLEM TRANSFORMATION +* +* Consider an inequality constraint: +* +* sum a[j] x[j] <= b, (1) +* j in J +* +* where all variables x[j] are binary, and |J| >= 2. (In case of '>=' +* inequality it can be transformed to '<=' format by multiplying both +* its sides by -1.) +* +* Let Jp = {j: a[j] > 0}, Jn = {j: a[j] < 0}. Performing substitution +* x[j] = 1 - x~[j] for all j in Jn, we have: +* +* sum a[j] x[j] <= b ==> +* j in J +* +* sum a[j] x[j] + sum a[j] x[j] <= b ==> +* j in Jp j in Jn +* +* sum a[j] x[j] + sum a[j] (1 - x~[j]) <= b ==> +* j in Jp j in Jn +* +* sum a[j] x[j] - sum a[j] x~[j] <= b - sum a[j]. +* j in Jp j in Jn j in Jn +* +* Thus, meaning the transformation above, we can assume that in +* inequality (1) all coefficients a[j] are positive. Moreover, we can +* assume that a[j] <= b. In fact, let a[j] > b; then the following +* three cases are possible: +* +* 1) b < 0. In this case inequality (1) is infeasible, so the problem +* has no feasible solution (see the routine npp_analyze_row); +* +* 2) b = 0. In this case inequality (1) is a forcing inequality on its +* upper bound (see the routine npp_forcing row), from which it +* follows that all variables x[j] should be fixed at zero; +* +* 3) b > 0. In this case inequality (1) defines an implied zero upper +* bound for variable x[j] (see the routine npp_implied_bounds), from +* which it follows that x[j] should be fixed at zero. +* +* It is assumed that all three cases listed above have been recognized +* by the routine npp_process_prob, which performs basic MIP processing +* prior to a call the routine npp_hidden_packing. So, if one of these +* cases occurs, we should just skip processing such constraint. +* +* Thus, let 0 < a[j] <= b. Then it is obvious that constraint (1) is +* equivalent to packing inquality only if: +* +* a[j] + a[k] > b + eps (2) +* +* for all j, k in J, j != k, where eps is an absolute tolerance for +* row (linear form) value. Checking the condition (2) for all j and k, +* j != k, requires time O(|J|^2). However, this time can be reduced to +* O(|J|), if use minimal a[j] and a[k], in which case it is sufficient +* to check the condition (2) only once. +* +* Once the original inequality (1) is replaced by equivalent packing +* inequality, we need to perform back substitution x~[j] = 1 - x[j] for +* all j in Jn (see above). +* +* RECOVERING SOLUTION +* +* None needed. */ + +static int hidden_packing(NPP *npp, struct elem *ptr, double *_b) +{ /* process inequality constraint: sum a[j] x[j] <= b; + 0 - specified row is NOT hidden packing inequality; + 1 - specified row is packing inequality; + 2 - specified row is hidden packing inequality. */ + struct elem *e, *ej, *ek; + int neg; + double b = *_b, eps; + xassert(npp == npp); + /* a[j] must be non-zero, x[j] must be binary, for all j in J */ + for (e = ptr; e != NULL; e = e->next) + { xassert(e->aj != 0.0); + xassert(e->xj->is_int); + xassert(e->xj->lb == 0.0 && e->xj->ub == 1.0); + } + /* check if the specified inequality constraint already has the + form of packing inequality */ + neg = 0; /* neg is |Jn| */ + for (e = ptr; e != NULL; e = e->next) + { if (e->aj == +1.0) + ; + else if (e->aj == -1.0) + neg++; + else + break; + } + if (e == NULL) + { /* all coefficients a[j] are +1 or -1; check rhs b */ + if (b == (double)(1 - neg)) + { /* it is packing inequality; no processing is needed */ + return 1; + } + } + /* substitute x[j] = 1 - x~[j] for all j in Jn to make all a[j] + positive; the result is a~[j] = |a[j]| and new rhs b */ + for (e = ptr; e != NULL; e = e->next) + if (e->aj < 0) b -= e->aj; + /* now a[j] > 0 for all j in J (actually |a[j]| are used) */ + /* if a[j] > b, skip processing--this case must not appear */ + for (e = ptr; e != NULL; e = e->next) + if (fabs(e->aj) > b) return 0; + /* now 0 < a[j] <= b for all j in J */ + /* find two minimal coefficients a[j] and a[k], j != k */ + ej = NULL; + for (e = ptr; e != NULL; e = e->next) + if (ej == NULL || fabs(ej->aj) > fabs(e->aj)) ej = e; + xassert(ej != NULL); + ek = NULL; + for (e = ptr; e != NULL; e = e->next) + if (e != ej) + if (ek == NULL || fabs(ek->aj) > fabs(e->aj)) ek = e; + xassert(ek != NULL); + /* the specified constraint is equivalent to packing inequality + iff a[j] + a[k] > b + eps */ + eps = 1e-3 + 1e-6 * fabs(b); + if (fabs(ej->aj) + fabs(ek->aj) <= b + eps) return 0; + /* perform back substitution x~[j] = 1 - x[j] and construct the + final equivalent packing inequality in generalized format */ + b = 1.0; + for (e = ptr; e != NULL; e = e->next) + { if (e->aj > 0.0) + e->aj = +1.0; + else /* e->aj < 0.0 */ + e->aj = -1.0, b -= 1.0; + } + *_b = b; + return 2; +} + +int npp_hidden_packing(NPP *npp, NPPROW *row) +{ /* identify hidden packing inequality */ + NPPROW *copy; + NPPAIJ *aij; + struct elem *ptr, *e; + int kase, ret, count = 0; + double b; + /* the row must be inequality constraint */ + xassert(row->lb < row->ub); + for (kase = 0; kase <= 1; kase++) + { if (kase == 0) + { /* process row upper bound */ + if (row->ub == +DBL_MAX) continue; + ptr = copy_form(npp, row, +1.0); + b = + row->ub; + } + else + { /* process row lower bound */ + if (row->lb == -DBL_MAX) continue; + ptr = copy_form(npp, row, -1.0); + b = - row->lb; + } + /* now the inequality has the form "sum a[j] x[j] <= b" */ + ret = hidden_packing(npp, ptr, &b); + xassert(0 <= ret && ret <= 2); + if (kase == 1 && ret == 1 || ret == 2) + { /* the original inequality has been identified as hidden + packing inequality */ + count++; +#ifdef GLP_DEBUG + xprintf("Original constraint:\n"); + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + xprintf(" %+g x%d", aij->val, aij->col->j); + if (row->lb != -DBL_MAX) xprintf(", >= %g", row->lb); + if (row->ub != +DBL_MAX) xprintf(", <= %g", row->ub); + xprintf("\n"); + xprintf("Equivalent packing inequality:\n"); + for (e = ptr; e != NULL; e = e->next) + xprintf(" %sx%d", e->aj > 0.0 ? "+" : "-", e->xj->j); + xprintf(", <= %g\n", b); +#endif + if (row->lb == -DBL_MAX || row->ub == +DBL_MAX) + { /* the original row is single-sided inequality; no copy + is needed */ + copy = NULL; + } + else + { /* the original row is double-sided inequality; we need + to create its copy for other bound before replacing it + with the equivalent inequality */ + copy = npp_add_row(npp); + if (kase == 0) + { /* the copy is for lower bound */ + copy->lb = row->lb, copy->ub = +DBL_MAX; + } + else + { /* the copy is for upper bound */ + copy->lb = -DBL_MAX, copy->ub = row->ub; + } + /* copy original row coefficients */ + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + npp_add_aij(npp, copy, aij->col, aij->val); + } + /* replace the original inequality by equivalent one */ + npp_erase_row(npp, row); + row->lb = -DBL_MAX, row->ub = b; + for (e = ptr; e != NULL; e = e->next) + npp_add_aij(npp, row, e->xj, e->aj); + /* continue processing lower bound for the copy */ + if (copy != NULL) row = copy; + } + drop_form(npp, ptr); + } + return count; +} + +/*********************************************************************** +* NAME +* +* npp_implied_packing - identify implied packing inequality +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_implied_packing(NPP *npp, NPPROW *row, int which, +* NPPCOL *var[], char set[]); +* +* DESCRIPTION +* +* The routine npp_implied_packing processes specified row (constraint) +* of general format: +* +* L <= sum a[j] x[j] <= U. (1) +* j +* +* If which = 0, only lower bound L, which must exist, is considered, +* while upper bound U is ignored. Similarly, if which = 1, only upper +* bound U, which must exist, is considered, while lower bound L is +* ignored. Thus, if the specified row is a double-sided inequality or +* equality constraint, this routine should be called twice for both +* lower and upper bounds. +* +* The routine npp_implied_packing attempts to find a non-trivial (i.e. +* having not less than two binary variables) packing inequality: +* +* sum x[j] - sum x[j] <= 1 - |Jn|, (2) +* j in Jp j in Jn +* +* which is relaxation of the constraint (1) in the sense that any +* solution satisfying to that constraint also satisfies to the packing +* inequality (2). If such relaxation exists, the routine stores +* pointers to descriptors of corresponding binary variables and their +* flags, resp., to locations var[1], var[2], ..., var[len] and set[1], +* set[2], ..., set[len], where set[j] = 0 means that j in Jp and +* set[j] = 1 means that j in Jn. +* +* RETURNS +* +* The routine npp_implied_packing returns len, which is the total +* number of binary variables in the packing inequality found, len >= 2. +* However, if the relaxation does not exist, the routine returns zero. +* +* ALGORITHM +* +* If which = 0, the constraint coefficients (1) are multiplied by -1 +* and b is assigned -L; if which = 1, the constraint coefficients (1) +* are not changed and b is assigned +U. In both cases the specified +* constraint gets the following format: +* +* sum a[j] x[j] <= b. (3) +* j +* +* (Note that (3) is a relaxation of (1), because one of bounds L or U +* is ignored.) +* +* Let J be set of binary variables, Kp be set of non-binary (integer +* or continuous) variables with a[j] > 0, and Kn be set of non-binary +* variables with a[j] < 0. Then the inequality (3) can be written as +* follows: +* +* sum a[j] x[j] <= b - sum a[j] x[j] - sum a[j] x[j]. (4) +* j in J j in Kp j in Kn +* +* To get rid of non-binary variables we can replace the inequality (4) +* by the following relaxed inequality: +* +* sum a[j] x[j] <= b~, (5) +* j in J +* +* where: +* +* b~ = sup(b - sum a[j] x[j] - sum a[j] x[j]) = +* j in Kp j in Kn +* +* = b - inf sum a[j] x[j] - inf sum a[j] x[j] = (6) +* j in Kp j in Kn +* +* = b - sum a[j] l[j] - sum a[j] u[j]. +* j in Kp j in Kn +* +* Note that if lower bound l[j] (if j in Kp) or upper bound u[j] +* (if j in Kn) of some non-binary variable x[j] does not exist, then +* formally b = +oo, in which case further analysis is not performed. +* +* Let Bp = {j in J: a[j] > 0}, Bn = {j in J: a[j] < 0}. To make all +* the inequality coefficients in (5) positive, we replace all x[j] in +* Bn by their complementaries, substituting x[j] = 1 - x~[j] for all +* j in Bn, that gives: +* +* sum a[j] x[j] - sum a[j] x~[j] <= b~ - sum a[j]. (7) +* j in Bp j in Bn j in Bn +* +* This inequality is a relaxation of the original constraint (1), and +* it is a binary knapsack inequality. Writing it in the standard format +* we have: +* +* sum alfa[j] z[j] <= beta, (8) +* j in J +* +* where: +* ( + a[j], if j in Bp, +* alfa[j] = < (9) +* ( - a[j], if j in Bn, +* +* ( x[j], if j in Bp, +* z[j] = < (10) +* ( 1 - x[j], if j in Bn, +* +* beta = b~ - sum a[j]. (11) +* j in Bn +* +* In the inequality (8) all coefficients are positive, therefore, the +* packing relaxation to be found for this inequality is the following: +* +* sum z[j] <= 1. (12) +* j in P +* +* It is obvious that set P within J, which we would like to find, must +* satisfy to the following condition: +* +* alfa[j] + alfa[k] > beta + eps for all j, k in P, j != k, (13) +* +* where eps is an absolute tolerance for value of the linear form. +* Thus, it is natural to take P = {j: alpha[j] > (beta + eps) / 2}. +* Moreover, if in the equality (8) there exist coefficients alfa[k], +* for which alfa[k] <= (beta + eps) / 2, but which, nevertheless, +* satisfies to the condition (13) for all j in P, *one* corresponding +* variable z[k] (having, for example, maximal coefficient alfa[k]) can +* be included in set P, that allows increasing the number of binary +* variables in (12) by one. +* +* Once the set P has been built, for the inequality (12) we need to +* perform back substitution according to (10) in order to express it +* through the original binary variables. As the result of such back +* substitution the relaxed packing inequality get its final format (2), +* where Jp = J intersect Bp, and Jn = J intersect Bn. */ + +int npp_implied_packing(NPP *npp, NPPROW *row, int which, + NPPCOL *var[], char set[]) +{ struct elem *ptr, *e, *i, *k; + int len = 0; + double b, eps; + /* build inequality (3) */ + if (which == 0) + { ptr = copy_form(npp, row, -1.0); + xassert(row->lb != -DBL_MAX); + b = - row->lb; + } + else if (which == 1) + { ptr = copy_form(npp, row, +1.0); + xassert(row->ub != +DBL_MAX); + b = + row->ub; + } + /* remove non-binary variables to build relaxed inequality (5); + compute its right-hand side b~ with formula (6) */ + for (e = ptr; e != NULL; e = e->next) + { if (!(e->xj->is_int && e->xj->lb == 0.0 && e->xj->ub == 1.0)) + { /* x[j] is non-binary variable */ + if (e->aj > 0.0) + { if (e->xj->lb == -DBL_MAX) goto done; + b -= e->aj * e->xj->lb; + } + else /* e->aj < 0.0 */ + { if (e->xj->ub == +DBL_MAX) goto done; + b -= e->aj * e->xj->ub; + } + /* a[j] = 0 means that variable x[j] is removed */ + e->aj = 0.0; + } + } + /* substitute x[j] = 1 - x~[j] to build knapsack inequality (8); + compute its right-hand side beta with formula (11) */ + for (e = ptr; e != NULL; e = e->next) + if (e->aj < 0.0) b -= e->aj; + /* if beta is close to zero, the knapsack inequality is either + infeasible or forcing inequality; this must never happen, so + we skip further analysis */ + if (b < 1e-3) goto done; + /* build set P as well as sets Jp and Jn, and determine x[k] as + explained above in comments to the routine */ + eps = 1e-3 + 1e-6 * b; + i = k = NULL; + for (e = ptr; e != NULL; e = e->next) + { /* note that alfa[j] = |a[j]| */ + if (fabs(e->aj) > 0.5 * (b + eps)) + { /* alfa[j] > (b + eps) / 2; include x[j] in set P, i.e. in + set Jp or Jn */ + var[++len] = e->xj; + set[len] = (char)(e->aj > 0.0 ? 0 : 1); + /* alfa[i] = min alfa[j] over all j included in set P */ + if (i == NULL || fabs(i->aj) > fabs(e->aj)) i = e; + } + else if (fabs(e->aj) >= 1e-3) + { /* alfa[k] = max alfa[j] over all j not included in set P; + we skip coefficient a[j] if it is close to zero to avoid + numerically unreliable results */ + if (k == NULL || fabs(k->aj) < fabs(e->aj)) k = e; + } + } + /* if alfa[k] satisfies to condition (13) for all j in P, include + x[k] in P */ + if (i != NULL && k != NULL && fabs(i->aj) + fabs(k->aj) > b + eps) + { var[++len] = k->xj; + set[len] = (char)(k->aj > 0.0 ? 0 : 1); + } + /* trivial packing inequality being redundant must never appear, + so we just ignore it */ + if (len < 2) len = 0; +done: drop_form(npp, ptr); + return len; +} + +/*********************************************************************** +* NAME +* +* npp_is_covering - test if constraint is covering inequality +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_is_covering(NPP *npp, NPPROW *row); +* +* RETURNS +* +* If the specified row (constraint) is covering inequality (see below), +* the routine npp_is_covering returns non-zero. Otherwise, it returns +* zero. +* +* COVERING INEQUALITIES +* +* In canonical format the covering inequality is the following: +* +* sum x[j] >= 1, (1) +* j in J +* +* where all variables x[j] are binary. This inequality expresses the +* condition that in any integer feasible solution variables in set J +* cannot be all equal to zero at the same time, i.e. at least one +* variable must take non-zero (unity) value. W.l.o.g. it is assumed +* that |J| >= 2, because if J is empty, the inequality (1) is +* infeasible, and if |J| = 1, the inequality (1) is a forcing row. +* +* In general case the covering inequality may include original +* variables x[j] as well as their complements x~[j]: +* +* sum x[j] + sum x~[j] >= 1, (2) +* j in Jp j in Jn +* +* where Jp and Jn are not intersected. Therefore, using substitution +* x~[j] = 1 - x[j] gives the packing inequality in generalized format: +* +* sum x[j] - sum x[j] >= 1 - |Jn|. (3) +* j in Jp j in Jn +* +* (May note that the inequality (3) cuts off infeasible solutions, +* where x[j] = 0 for all j in Jp and x[j] = 1 for all j in Jn.) +* +* NOTE: If |J| = 2, the inequality (3) is equivalent to packing +* inequality (see the routine npp_is_packing). */ + +int npp_is_covering(NPP *npp, NPPROW *row) +{ /* test if constraint is covering inequality */ + NPPCOL *col; + NPPAIJ *aij; + int b; + xassert(npp == npp); + if (!(row->lb != -DBL_MAX && row->ub == +DBL_MAX)) + return 0; + b = 1; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { col = aij->col; + if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) + return 0; + if (aij->val == +1.0) + ; + else if (aij->val == -1.0) + b--; + else + return 0; + } + if (row->lb != (double)b) return 0; + return 1; +} + +/*********************************************************************** +* NAME +* +* npp_hidden_covering - identify hidden covering inequality +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_hidden_covering(NPP *npp, NPPROW *row); +* +* DESCRIPTION +* +* The routine npp_hidden_covering processes specified inequality +* constraint, which includes only binary variables, and the number of +* the variables is not less than three. If the original inequality is +* equivalent to a covering inequality (see below), the routine +* replaces it by the equivalent inequality. If the original constraint +* is double-sided inequality, it is replaced by a pair of single-sided +* inequalities, if necessary. +* +* RETURNS +* +* If the original inequality constraint was replaced by equivalent +* covering inequality, the routine npp_hidden_covering returns +* non-zero. Otherwise, it returns zero. +* +* PROBLEM TRANSFORMATION +* +* Consider an inequality constraint: +* +* sum a[j] x[j] >= b, (1) +* j in J +* +* where all variables x[j] are binary, and |J| >= 3. (In case of '<=' +* inequality it can be transformed to '>=' format by multiplying both +* its sides by -1.) +* +* Let Jp = {j: a[j] > 0}, Jn = {j: a[j] < 0}. Performing substitution +* x[j] = 1 - x~[j] for all j in Jn, we have: +* +* sum a[j] x[j] >= b ==> +* j in J +* +* sum a[j] x[j] + sum a[j] x[j] >= b ==> +* j in Jp j in Jn +* +* sum a[j] x[j] + sum a[j] (1 - x~[j]) >= b ==> +* j in Jp j in Jn +* +* sum m a[j] x[j] - sum a[j] x~[j] >= b - sum a[j]. +* j in Jp j in Jn j in Jn +* +* Thus, meaning the transformation above, we can assume that in +* inequality (1) all coefficients a[j] are positive. Moreover, we can +* assume that b > 0, because otherwise the inequality (1) would be +* redundant (see the routine npp_analyze_row). It is then obvious that +* constraint (1) is equivalent to covering inequality only if: +* +* a[j] >= b, (2) +* +* for all j in J. +* +* Once the original inequality (1) is replaced by equivalent covering +* inequality, we need to perform back substitution x~[j] = 1 - x[j] for +* all j in Jn (see above). +* +* RECOVERING SOLUTION +* +* None needed. */ + +static int hidden_covering(NPP *npp, struct elem *ptr, double *_b) +{ /* process inequality constraint: sum a[j] x[j] >= b; + 0 - specified row is NOT hidden covering inequality; + 1 - specified row is covering inequality; + 2 - specified row is hidden covering inequality. */ + struct elem *e; + int neg; + double b = *_b, eps; + xassert(npp == npp); + /* a[j] must be non-zero, x[j] must be binary, for all j in J */ + for (e = ptr; e != NULL; e = e->next) + { xassert(e->aj != 0.0); + xassert(e->xj->is_int); + xassert(e->xj->lb == 0.0 && e->xj->ub == 1.0); + } + /* check if the specified inequality constraint already has the + form of covering inequality */ + neg = 0; /* neg is |Jn| */ + for (e = ptr; e != NULL; e = e->next) + { if (e->aj == +1.0) + ; + else if (e->aj == -1.0) + neg++; + else + break; + } + if (e == NULL) + { /* all coefficients a[j] are +1 or -1; check rhs b */ + if (b == (double)(1 - neg)) + { /* it is covering inequality; no processing is needed */ + return 1; + } + } + /* substitute x[j] = 1 - x~[j] for all j in Jn to make all a[j] + positive; the result is a~[j] = |a[j]| and new rhs b */ + for (e = ptr; e != NULL; e = e->next) + if (e->aj < 0) b -= e->aj; + /* now a[j] > 0 for all j in J (actually |a[j]| are used) */ + /* if b <= 0, skip processing--this case must not appear */ + if (b < 1e-3) return 0; + /* now a[j] > 0 for all j in J, and b > 0 */ + /* the specified constraint is equivalent to covering inequality + iff a[j] >= b for all j in J */ + eps = 1e-9 + 1e-12 * fabs(b); + for (e = ptr; e != NULL; e = e->next) + if (fabs(e->aj) < b - eps) return 0; + /* perform back substitution x~[j] = 1 - x[j] and construct the + final equivalent covering inequality in generalized format */ + b = 1.0; + for (e = ptr; e != NULL; e = e->next) + { if (e->aj > 0.0) + e->aj = +1.0; + else /* e->aj < 0.0 */ + e->aj = -1.0, b -= 1.0; + } + *_b = b; + return 2; +} + +int npp_hidden_covering(NPP *npp, NPPROW *row) +{ /* identify hidden covering inequality */ + NPPROW *copy; + NPPAIJ *aij; + struct elem *ptr, *e; + int kase, ret, count = 0; + double b; + /* the row must be inequality constraint */ + xassert(row->lb < row->ub); + for (kase = 0; kase <= 1; kase++) + { if (kase == 0) + { /* process row lower bound */ + if (row->lb == -DBL_MAX) continue; + ptr = copy_form(npp, row, +1.0); + b = + row->lb; + } + else + { /* process row upper bound */ + if (row->ub == +DBL_MAX) continue; + ptr = copy_form(npp, row, -1.0); + b = - row->ub; + } + /* now the inequality has the form "sum a[j] x[j] >= b" */ + ret = hidden_covering(npp, ptr, &b); + xassert(0 <= ret && ret <= 2); + if (kase == 1 && ret == 1 || ret == 2) + { /* the original inequality has been identified as hidden + covering inequality */ + count++; +#ifdef GLP_DEBUG + xprintf("Original constraint:\n"); + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + xprintf(" %+g x%d", aij->val, aij->col->j); + if (row->lb != -DBL_MAX) xprintf(", >= %g", row->lb); + if (row->ub != +DBL_MAX) xprintf(", <= %g", row->ub); + xprintf("\n"); + xprintf("Equivalent covering inequality:\n"); + for (e = ptr; e != NULL; e = e->next) + xprintf(" %sx%d", e->aj > 0.0 ? "+" : "-", e->xj->j); + xprintf(", >= %g\n", b); +#endif + if (row->lb == -DBL_MAX || row->ub == +DBL_MAX) + { /* the original row is single-sided inequality; no copy + is needed */ + copy = NULL; + } + else + { /* the original row is double-sided inequality; we need + to create its copy for other bound before replacing it + with the equivalent inequality */ + copy = npp_add_row(npp); + if (kase == 0) + { /* the copy is for upper bound */ + copy->lb = -DBL_MAX, copy->ub = row->ub; + } + else + { /* the copy is for lower bound */ + copy->lb = row->lb, copy->ub = +DBL_MAX; + } + /* copy original row coefficients */ + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + npp_add_aij(npp, copy, aij->col, aij->val); + } + /* replace the original inequality by equivalent one */ + npp_erase_row(npp, row); + row->lb = b, row->ub = +DBL_MAX; + for (e = ptr; e != NULL; e = e->next) + npp_add_aij(npp, row, e->xj, e->aj); + /* continue processing upper bound for the copy */ + if (copy != NULL) row = copy; + } + drop_form(npp, ptr); + } + return count; +} + +/*********************************************************************** +* NAME +* +* npp_is_partitioning - test if constraint is partitioning equality +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_is_partitioning(NPP *npp, NPPROW *row); +* +* RETURNS +* +* If the specified row (constraint) is partitioning equality (see +* below), the routine npp_is_partitioning returns non-zero. Otherwise, +* it returns zero. +* +* PARTITIONING EQUALITIES +* +* In canonical format the partitioning equality is the following: +* +* sum x[j] = 1, (1) +* j in J +* +* where all variables x[j] are binary. This equality expresses the +* condition that in any integer feasible solution exactly one variable +* in set J must take non-zero (unity) value while other variables must +* be equal to zero. W.l.o.g. it is assumed that |J| >= 2, because if +* J is empty, the inequality (1) is infeasible, and if |J| = 1, the +* inequality (1) is a fixing row. +* +* In general case the partitioning equality may include original +* variables x[j] as well as their complements x~[j]: +* +* sum x[j] + sum x~[j] = 1, (2) +* j in Jp j in Jn +* +* where Jp and Jn are not intersected. Therefore, using substitution +* x~[j] = 1 - x[j] leads to the partitioning equality in generalized +* format: +* +* sum x[j] - sum x[j] = 1 - |Jn|. (3) +* j in Jp j in Jn */ + +int npp_is_partitioning(NPP *npp, NPPROW *row) +{ /* test if constraint is partitioning equality */ + NPPCOL *col; + NPPAIJ *aij; + int b; + xassert(npp == npp); + if (row->lb != row->ub) return 0; + b = 1; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { col = aij->col; + if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) + return 0; + if (aij->val == +1.0) + ; + else if (aij->val == -1.0) + b--; + else + return 0; + } + if (row->lb != (double)b) return 0; + return 1; +} + +/*********************************************************************** +* NAME +* +* npp_reduce_ineq_coef - reduce inequality constraint coefficients +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_reduce_ineq_coef(NPP *npp, NPPROW *row); +* +* DESCRIPTION +* +* The routine npp_reduce_ineq_coef processes specified inequality +* constraint attempting to replace it by an equivalent constraint, +* where magnitude of coefficients at binary variables is smaller than +* in the original constraint. If the inequality is double-sided, it is +* replaced by a pair of single-sided inequalities, if necessary. +* +* RETURNS +* +* The routine npp_reduce_ineq_coef returns the number of coefficients +* reduced. +* +* BACKGROUND +* +* Consider an inequality constraint: +* +* sum a[j] x[j] >= b. (1) +* j in J +* +* (In case of '<=' inequality it can be transformed to '>=' format by +* multiplying both its sides by -1.) Let x[k] be a binary variable; +* other variables can be integer as well as continuous. We can write +* constraint (1) as follows: +* +* a[k] x[k] + t[k] >= b, (2) +* +* where: +* +* t[k] = sum a[j] x[j]. (3) +* j in J\{k} +* +* Since x[k] is binary, constraint (2) is equivalent to disjunction of +* the following two constraints: +* +* x[k] = 0, t[k] >= b (4) +* +* OR +* +* x[k] = 1, t[k] >= b - a[k]. (5) +* +* Let also that for the partial sum t[k] be known some its implied +* lower bound inf t[k]. +* +* Case a[k] > 0. Let inf t[k] < b, since otherwise both constraints +* (4) and (5) and therefore constraint (2) are redundant. +* If inf t[k] > b - a[k], only constraint (5) is redundant, in which +* case it can be replaced with the following redundant and therefore +* equivalent constraint: +* +* t[k] >= b - a'[k] = inf t[k], (6) +* +* where: +* +* a'[k] = b - inf t[k]. (7) +* +* Thus, the original constraint (2) is equivalent to the following +* constraint with coefficient at variable x[k] changed: +* +* a'[k] x[k] + t[k] >= b. (8) +* +* From inf t[k] < b it follows that a'[k] > 0, i.e. the coefficient +* at x[k] keeps its sign. And from inf t[k] > b - a[k] it follows that +* a'[k] < a[k], i.e. the coefficient reduces in magnitude. +* +* Case a[k] < 0. Let inf t[k] < b - a[k], since otherwise both +* constraints (4) and (5) and therefore constraint (2) are redundant. +* If inf t[k] > b, only constraint (4) is redundant, in which case it +* can be replaced with the following redundant and therefore equivalent +* constraint: +* +* t[k] >= b' = inf t[k]. (9) +* +* Rewriting constraint (5) as follows: +* +* t[k] >= b - a[k] = b' - a'[k], (10) +* +* where: +* +* a'[k] = a[k] + b' - b = a[k] + inf t[k] - b, (11) +* +* we can see that disjunction of constraint (9) and (10) is equivalent +* to disjunction of constraint (4) and (5), from which it follows that +* the original constraint (2) is equivalent to the following constraint +* with both coefficient at variable x[k] and right-hand side changed: +* +* a'[k] x[k] + t[k] >= b'. (12) +* +* From inf t[k] < b - a[k] it follows that a'[k] < 0, i.e. the +* coefficient at x[k] keeps its sign. And from inf t[k] > b it follows +* that a'[k] > a[k], i.e. the coefficient reduces in magnitude. +* +* PROBLEM TRANSFORMATION +* +* In the routine npp_reduce_ineq_coef the following implied lower +* bound of the partial sum (3) is used: +* +* inf t[k] = sum a[j] l[j] + sum a[j] u[j], (13) +* j in Jp\{k} k in Jn\{k} +* +* where Jp = {j : a[j] > 0}, Jn = {j : a[j] < 0}, l[j] and u[j] are +* lower and upper bounds, resp., of variable x[j]. +* +* In order to compute inf t[k] more efficiently, the following formula, +* which is equivalent to (13), is actually used: +* +* ( h - a[k] l[k] = h, if a[k] > 0, +* inf t[k] = < (14) +* ( h - a[k] u[k] = h - a[k], if a[k] < 0, +* +* where: +* +* h = sum a[j] l[j] + sum a[j] u[j] (15) +* j in Jp j in Jn +* +* is the implied lower bound of row (1). +* +* Reduction of positive coefficient (a[k] > 0) does not change value +* of h, since l[k] = 0. In case of reduction of negative coefficient +* (a[k] < 0) from (11) it follows that: +* +* delta a[k] = a'[k] - a[k] = inf t[k] - b (> 0), (16) +* +* so new value of h (accounting that u[k] = 1) can be computed as +* follows: +* +* h := h + delta a[k] = h + (inf t[k] - b). (17) +* +* RECOVERING SOLUTION +* +* None needed. */ + +static int reduce_ineq_coef(NPP *npp, struct elem *ptr, double *_b) +{ /* process inequality constraint: sum a[j] x[j] >= b */ + /* returns: the number of coefficients reduced */ + struct elem *e; + int count = 0; + double h, inf_t, new_a, b = *_b; + xassert(npp == npp); + /* compute h; see (15) */ + h = 0.0; + for (e = ptr; e != NULL; e = e->next) + { if (e->aj > 0.0) + { if (e->xj->lb == -DBL_MAX) goto done; + h += e->aj * e->xj->lb; + } + else /* e->aj < 0.0 */ + { if (e->xj->ub == +DBL_MAX) goto done; + h += e->aj * e->xj->ub; + } + } + /* perform reduction of coefficients at binary variables */ + for (e = ptr; e != NULL; e = e->next) + { /* skip non-binary variable */ + if (!(e->xj->is_int && e->xj->lb == 0.0 && e->xj->ub == 1.0)) + continue; + if (e->aj > 0.0) + { /* compute inf t[k]; see (14) */ + inf_t = h; + if (b - e->aj < inf_t && inf_t < b) + { /* compute reduced coefficient a'[k]; see (7) */ + new_a = b - inf_t; + if (new_a >= +1e-3 && + e->aj - new_a >= 0.01 * (1.0 + e->aj)) + { /* accept a'[k] */ +#ifdef GLP_DEBUG + xprintf("+"); +#endif + e->aj = new_a; + count++; + } + } + } + else /* e->aj < 0.0 */ + { /* compute inf t[k]; see (14) */ + inf_t = h - e->aj; + if (b < inf_t && inf_t < b - e->aj) + { /* compute reduced coefficient a'[k]; see (11) */ + new_a = e->aj + (inf_t - b); + if (new_a <= -1e-3 && + new_a - e->aj >= 0.01 * (1.0 - e->aj)) + { /* accept a'[k] */ +#ifdef GLP_DEBUG + xprintf("-"); +#endif + e->aj = new_a; + /* update h; see (17) */ + h += (inf_t - b); + /* compute b'; see (9) */ + b = inf_t; + count++; + } + } + } + } + *_b = b; +done: return count; +} + +int npp_reduce_ineq_coef(NPP *npp, NPPROW *row) +{ /* reduce inequality constraint coefficients */ + NPPROW *copy; + NPPAIJ *aij; + struct elem *ptr, *e; + int kase, count[2]; + double b; + /* the row must be inequality constraint */ + xassert(row->lb < row->ub); + count[0] = count[1] = 0; + for (kase = 0; kase <= 1; kase++) + { if (kase == 0) + { /* process row lower bound */ + if (row->lb == -DBL_MAX) continue; +#ifdef GLP_DEBUG + xprintf("L"); +#endif + ptr = copy_form(npp, row, +1.0); + b = + row->lb; + } + else + { /* process row upper bound */ + if (row->ub == +DBL_MAX) continue; +#ifdef GLP_DEBUG + xprintf("U"); +#endif + ptr = copy_form(npp, row, -1.0); + b = - row->ub; + } + /* now the inequality has the form "sum a[j] x[j] >= b" */ + count[kase] = reduce_ineq_coef(npp, ptr, &b); + if (count[kase] > 0) + { /* the original inequality has been replaced by equivalent + one with coefficients reduced */ + if (row->lb == -DBL_MAX || row->ub == +DBL_MAX) + { /* the original row is single-sided inequality; no copy + is needed */ + copy = NULL; + } + else + { /* the original row is double-sided inequality; we need + to create its copy for other bound before replacing it + with the equivalent inequality */ +#ifdef GLP_DEBUG + xprintf("*"); +#endif + copy = npp_add_row(npp); + if (kase == 0) + { /* the copy is for upper bound */ + copy->lb = -DBL_MAX, copy->ub = row->ub; + } + else + { /* the copy is for lower bound */ + copy->lb = row->lb, copy->ub = +DBL_MAX; + } + /* copy original row coefficients */ + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + npp_add_aij(npp, copy, aij->col, aij->val); + } + /* replace the original inequality by equivalent one */ + npp_erase_row(npp, row); + row->lb = b, row->ub = +DBL_MAX; + for (e = ptr; e != NULL; e = e->next) + npp_add_aij(npp, row, e->xj, e->aj); + /* continue processing upper bound for the copy */ + if (copy != NULL) row = copy; + } + drop_form(npp, ptr); + } + return count[0] + count[1]; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpnpp05.c b/resources/3rdparty/glpk-4.57/src/glpnpp05.c new file mode 100644 index 000000000..8c8818508 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpnpp05.c @@ -0,0 +1,810 @@ +/* glpnpp05.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpnpp.h" + +/*********************************************************************** +* NAME +* +* npp_clean_prob - perform initial LP/MIP processing +* +* SYNOPSIS +* +* #include "glpnpp.h" +* void npp_clean_prob(NPP *npp); +* +* DESCRIPTION +* +* The routine npp_clean_prob performs initial LP/MIP processing that +* currently includes: +* +* 1) removing free rows; +* +* 2) replacing double-sided constraint rows with almost identical +* bounds, by equality constraint rows; +* +* 3) removing fixed columns; +* +* 4) replacing double-bounded columns with almost identical bounds by +* fixed columns and removing those columns; +* +* 5) initial processing constraint coefficients (not implemented); +* +* 6) initial processing objective coefficients (not implemented). */ + +void npp_clean_prob(NPP *npp) +{ /* perform initial LP/MIP processing */ + NPPROW *row, *next_row; + NPPCOL *col, *next_col; + int ret; + xassert(npp == npp); + /* process rows which originally are free */ + for (row = npp->r_head; row != NULL; row = next_row) + { next_row = row->next; + if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) + { /* process free row */ +#ifdef GLP_DEBUG + xprintf("1"); +#endif + npp_free_row(npp, row); + /* row was deleted */ + } + } + /* process rows which originally are double-sided inequalities */ + for (row = npp->r_head; row != NULL; row = next_row) + { next_row = row->next; + if (row->lb != -DBL_MAX && row->ub != +DBL_MAX && + row->lb < row->ub) + { ret = npp_make_equality(npp, row); + if (ret == 0) + ; + else if (ret == 1) + { /* row was replaced by equality constraint */ +#ifdef GLP_DEBUG + xprintf("2"); +#endif + } + else + xassert(ret != ret); + } + } + /* process columns which are originally fixed */ + for (col = npp->c_head; col != NULL; col = next_col) + { next_col = col->next; + if (col->lb == col->ub) + { /* process fixed column */ +#ifdef GLP_DEBUG + xprintf("3"); +#endif + npp_fixed_col(npp, col); + /* column was deleted */ + } + } + /* process columns which are originally double-bounded */ + for (col = npp->c_head; col != NULL; col = next_col) + { next_col = col->next; + if (col->lb != -DBL_MAX && col->ub != +DBL_MAX && + col->lb < col->ub) + { ret = npp_make_fixed(npp, col); + if (ret == 0) + ; + else if (ret == 1) + { /* column was replaced by fixed column; process it */ +#ifdef GLP_DEBUG + xprintf("4"); +#endif + npp_fixed_col(npp, col); + /* column was deleted */ + } + } + } + return; +} + +/*********************************************************************** +* NAME +* +* npp_process_row - perform basic row processing +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_process_row(NPP *npp, NPPROW *row, int hard); +* +* DESCRIPTION +* +* The routine npp_process_row performs basic row processing that +* currently includes: +* +* 1) removing empty row; +* +* 2) removing equality constraint row singleton and corresponding +* column; +* +* 3) removing inequality constraint row singleton and corresponding +* column if it was fixed; +* +* 4) performing general row analysis; +* +* 5) removing redundant row bounds; +* +* 6) removing forcing row and corresponding columns; +* +* 7) removing row which becomes free due to redundant bounds; +* +* 8) computing implied bounds for all columns in the row and using +* them to strengthen current column bounds (MIP only, optional, +* performed if the flag hard is on). +* +* Additionally the routine may activate affected rows and/or columns +* for further processing. +* +* RETURNS +* +* 0 success; +* +* GLP_ENOPFS primal/integer infeasibility detected; +* +* GLP_ENODFS dual infeasibility detected. */ + +int npp_process_row(NPP *npp, NPPROW *row, int hard) +{ /* perform basic row processing */ + NPPCOL *col; + NPPAIJ *aij, *next_aij, *aaa; + int ret; + /* row must not be free */ + xassert(!(row->lb == -DBL_MAX && row->ub == +DBL_MAX)); + /* start processing row */ + if (row->ptr == NULL) + { /* empty row */ + ret = npp_empty_row(npp, row); + if (ret == 0) + { /* row was deleted */ +#ifdef GLP_DEBUG + xprintf("A"); +#endif + return 0; + } + else if (ret == 1) + { /* primal infeasibility */ + return GLP_ENOPFS; + } + else + xassert(ret != ret); + } + if (row->ptr->r_next == NULL) + { /* row singleton */ + col = row->ptr->col; + if (row->lb == row->ub) + { /* equality constraint */ + ret = npp_eq_singlet(npp, row); + if (ret == 0) + { /* column was fixed, row was deleted */ +#ifdef GLP_DEBUG + xprintf("B"); +#endif + /* activate rows affected by column */ + for (aij = col->ptr; aij != NULL; aij = aij->c_next) + npp_activate_row(npp, aij->row); + /* process fixed column */ + npp_fixed_col(npp, col); + /* column was deleted */ + return 0; + } + else if (ret == 1 || ret == 2) + { /* primal/integer infeasibility */ + return GLP_ENOPFS; + } + else + xassert(ret != ret); + } + else + { /* inequality constraint */ + ret = npp_ineq_singlet(npp, row); + if (0 <= ret && ret <= 3) + { /* row was deleted */ +#ifdef GLP_DEBUG + xprintf("C"); +#endif + /* activate column, since its length was changed due to + row deletion */ + npp_activate_col(npp, col); + if (ret >= 2) + { /* column bounds changed significantly or column was + fixed */ + /* activate rows affected by column */ + for (aij = col->ptr; aij != NULL; aij = aij->c_next) + npp_activate_row(npp, aij->row); + } + if (ret == 3) + { /* column was fixed; process it */ +#ifdef GLP_DEBUG + xprintf("D"); +#endif + npp_fixed_col(npp, col); + /* column was deleted */ + } + return 0; + } + else if (ret == 4) + { /* primal infeasibility */ + return GLP_ENOPFS; + } + else + xassert(ret != ret); + } + } +#if 0 + /* sometimes this causes too large round-off errors; probably + pivot coefficient should be chosen more carefully */ + if (row->ptr->r_next->r_next == NULL) + { /* row doubleton */ + if (row->lb == row->ub) + { /* equality constraint */ + if (!(row->ptr->col->is_int || + row->ptr->r_next->col->is_int)) + { /* both columns are continuous */ + NPPCOL *q; + q = npp_eq_doublet(npp, row); + if (q != NULL) + { /* column q was eliminated */ +#ifdef GLP_DEBUG + xprintf("E"); +#endif + /* now column q is singleton of type "implied slack + variable"; we process it here to make sure that on + recovering basic solution the row is always active + equality constraint (as required by the routine + rcv_eq_doublet) */ + xassert(npp_process_col(npp, q) == 0); + /* column q was deleted; note that row p also may be + deleted */ + return 0; + } + } + } + } +#endif + /* general row analysis */ + ret = npp_analyze_row(npp, row); + xassert(0x00 <= ret && ret <= 0xFF); + if (ret == 0x33) + { /* row bounds are inconsistent with column bounds */ + return GLP_ENOPFS; + } + if ((ret & 0x0F) == 0x00) + { /* row lower bound does not exist or redundant */ + if (row->lb != -DBL_MAX) + { /* remove redundant row lower bound */ +#ifdef GLP_DEBUG + xprintf("F"); +#endif + npp_inactive_bound(npp, row, 0); + } + } + else if ((ret & 0x0F) == 0x01) + { /* row lower bound can be active */ + /* see below */ + } + else if ((ret & 0x0F) == 0x02) + { /* row lower bound is a forcing bound */ +#ifdef GLP_DEBUG + xprintf("G"); +#endif + /* process forcing row */ + if (npp_forcing_row(npp, row, 0) == 0) +fixup: { /* columns were fixed, row was made free */ + for (aij = row->ptr; aij != NULL; aij = next_aij) + { /* process column fixed by forcing row */ +#ifdef GLP_DEBUG + xprintf("H"); +#endif + col = aij->col; + next_aij = aij->r_next; + /* activate rows affected by column */ + for (aaa = col->ptr; aaa != NULL; aaa = aaa->c_next) + npp_activate_row(npp, aaa->row); + /* process fixed column */ + npp_fixed_col(npp, col); + /* column was deleted */ + } + /* process free row (which now is empty due to deletion of + all its columns) */ + npp_free_row(npp, row); + /* row was deleted */ + return 0; + } + } + else + xassert(ret != ret); + if ((ret & 0xF0) == 0x00) + { /* row upper bound does not exist or redundant */ + if (row->ub != +DBL_MAX) + { /* remove redundant row upper bound */ +#ifdef GLP_DEBUG + xprintf("I"); +#endif + npp_inactive_bound(npp, row, 1); + } + } + else if ((ret & 0xF0) == 0x10) + { /* row upper bound can be active */ + /* see below */ + } + else if ((ret & 0xF0) == 0x20) + { /* row upper bound is a forcing bound */ +#ifdef GLP_DEBUG + xprintf("J"); +#endif + /* process forcing row */ + if (npp_forcing_row(npp, row, 1) == 0) goto fixup; + } + else + xassert(ret != ret); + if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) + { /* row became free due to redundant bounds removal */ +#ifdef GLP_DEBUG + xprintf("K"); +#endif + /* activate its columns, since their length will change due + to row deletion */ + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + npp_activate_col(npp, aij->col); + /* process free row */ + npp_free_row(npp, row); + /* row was deleted */ + return 0; + } +#if 1 /* 23/XII-2009 */ + /* row lower and/or upper bounds can be active */ + if (npp->sol == GLP_MIP && hard) + { /* improve current column bounds (optional) */ + if (npp_improve_bounds(npp, row, 1) < 0) + return GLP_ENOPFS; + } +#endif + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_improve_bounds - improve current column bounds +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_improve_bounds(NPP *npp, NPPROW *row, int flag); +* +* DESCRIPTION +* +* The routine npp_improve_bounds analyzes specified row (inequality +* or equality constraint) to determine implied column bounds and then +* uses these bounds to improve (strengthen) current column bounds. +* +* If the flag is on and current column bounds changed significantly +* or the column was fixed, the routine activate rows affected by the +* column for further processing. (This feature is intended to be used +* in the main loop of the routine npp_process_row.) +* +* NOTE: This operation can be used for MIP problem only. +* +* RETURNS +* +* The routine npp_improve_bounds returns the number of significantly +* changed bounds plus the number of column having been fixed due to +* bound improvements. However, if the routine detects primal/integer +* infeasibility, it returns a negative value. */ + +int npp_improve_bounds(NPP *npp, NPPROW *row, int flag) +{ /* improve current column bounds */ + NPPCOL *col; + NPPAIJ *aij, *next_aij, *aaa; + int kase, ret, count = 0; + double lb, ub; + xassert(npp->sol == GLP_MIP); + /* row must not be free */ + xassert(!(row->lb == -DBL_MAX && row->ub == +DBL_MAX)); + /* determine implied column bounds */ + npp_implied_bounds(npp, row); + /* and use these bounds to strengthen current column bounds */ + for (aij = row->ptr; aij != NULL; aij = next_aij) + { col = aij->col; + next_aij = aij->r_next; + for (kase = 0; kase <= 1; kase++) + { /* save current column bounds */ + lb = col->lb, ub = col->ub; + if (kase == 0) + { /* process implied column lower bound */ + if (col->ll.ll == -DBL_MAX) continue; + ret = npp_implied_lower(npp, col, col->ll.ll); + } + else + { /* process implied column upper bound */ + if (col->uu.uu == +DBL_MAX) continue; + ret = npp_implied_upper(npp, col, col->uu.uu); + } + if (ret == 0 || ret == 1) + { /* current column bounds did not change or changed, but + not significantly; restore current column bounds */ + col->lb = lb, col->ub = ub; + } + else if (ret == 2 || ret == 3) + { /* current column bounds changed significantly or column + was fixed */ +#ifdef GLP_DEBUG + xprintf("L"); +#endif + count++; + /* activate other rows affected by column, if required */ + if (flag) + { for (aaa = col->ptr; aaa != NULL; aaa = aaa->c_next) + { if (aaa->row != row) + npp_activate_row(npp, aaa->row); + } + } + if (ret == 3) + { /* process fixed column */ +#ifdef GLP_DEBUG + xprintf("M"); +#endif + npp_fixed_col(npp, col); + /* column was deleted */ + break; /* for kase */ + } + } + else if (ret == 4) + { /* primal/integer infeasibility */ + return -1; + } + else + xassert(ret != ret); + } + } + return count; +} + +/*********************************************************************** +* NAME +* +* npp_process_col - perform basic column processing +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_process_col(NPP *npp, NPPCOL *col); +* +* DESCRIPTION +* +* The routine npp_process_col performs basic column processing that +* currently includes: +* +* 1) fixing and removing empty column; +* +* 2) removing column singleton, which is implied slack variable, and +* corresponding row if it becomes free; +* +* 3) removing bounds of column, which is implied free variable, and +* replacing corresponding row by equality constraint. +* +* Additionally the routine may activate affected rows and/or columns +* for further processing. +* +* RETURNS +* +* 0 success; +* +* GLP_ENOPFS primal/integer infeasibility detected; +* +* GLP_ENODFS dual infeasibility detected. */ + +int npp_process_col(NPP *npp, NPPCOL *col) +{ /* perform basic column processing */ + NPPROW *row; + NPPAIJ *aij; + int ret; + /* column must not be fixed */ + xassert(col->lb < col->ub); + /* start processing column */ + if (col->ptr == NULL) + { /* empty column */ + ret = npp_empty_col(npp, col); + if (ret == 0) + { /* column was fixed and deleted */ +#ifdef GLP_DEBUG + xprintf("N"); +#endif + return 0; + } + else if (ret == 1) + { /* dual infeasibility */ + return GLP_ENODFS; + } + else + xassert(ret != ret); + } + if (col->ptr->c_next == NULL) + { /* column singleton */ + row = col->ptr->row; + if (row->lb == row->ub) + { /* equality constraint */ + if (!col->is_int) +slack: { /* implied slack variable */ +#ifdef GLP_DEBUG + xprintf("O"); +#endif + npp_implied_slack(npp, col); + /* column was deleted */ + if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) + { /* row became free due to implied slack variable */ +#ifdef GLP_DEBUG + xprintf("P"); +#endif + /* activate columns affected by row */ + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + npp_activate_col(npp, aij->col); + /* process free row */ + npp_free_row(npp, row); + /* row was deleted */ + } + else + { /* row became inequality constraint; activate it + since its length changed due to column deletion */ + npp_activate_row(npp, row); + } + return 0; + } + } + else + { /* inequality constraint */ + if (!col->is_int) + { ret = npp_implied_free(npp, col); + if (ret == 0) + { /* implied free variable */ +#ifdef GLP_DEBUG + xprintf("Q"); +#endif + /* column bounds were removed, row was replaced by + equality constraint */ + goto slack; + } + else if (ret == 1) + { /* column is not implied free variable, because its + lower and/or upper bounds can be active */ + } + else if (ret == 2) + { /* dual infeasibility */ + return GLP_ENODFS; + } + } + } + } + /* column still exists */ + return 0; +} + +/*********************************************************************** +* NAME +* +* npp_process_prob - perform basic LP/MIP processing +* +* SYNOPSIS +* +* #include "glpnpp.h" +* int npp_process_prob(NPP *npp, int hard); +* +* DESCRIPTION +* +* The routine npp_process_prob performs basic LP/MIP processing that +* currently includes: +* +* 1) initial LP/MIP processing (see the routine npp_clean_prob), +* +* 2) basic row processing (see the routine npp_process_row), and +* +* 3) basic column processing (see the routine npp_process_col). +* +* If the flag hard is on, the routine attempts to improve current +* column bounds multiple times within the main processing loop, in +* which case this feature may take a time. Otherwise, if the flag hard +* is off, improving column bounds is performed only once at the end of +* the main loop. (Note that this feature is used for MIP only.) +* +* The routine uses two sets: the set of active rows and the set of +* active columns. Rows/columns are marked by a flag (the field temp in +* NPPROW/NPPCOL). If the flag is non-zero, the row/column is active, +* in which case it is placed in the beginning of the row/column list; +* otherwise, if the flag is zero, the row/column is inactive, in which +* case it is placed in the end of the row/column list. If a row/column +* being currently processed may affect other rows/columns, the latters +* are activated for further processing. +* +* RETURNS +* +* 0 success; +* +* GLP_ENOPFS primal/integer infeasibility detected; +* +* GLP_ENODFS dual infeasibility detected. */ + +int npp_process_prob(NPP *npp, int hard) +{ /* perform basic LP/MIP processing */ + NPPROW *row; + NPPCOL *col; + int processing, ret; + /* perform initial LP/MIP processing */ + npp_clean_prob(npp); + /* activate all remaining rows and columns */ + for (row = npp->r_head; row != NULL; row = row->next) + row->temp = 1; + for (col = npp->c_head; col != NULL; col = col->next) + col->temp = 1; + /* main processing loop */ + processing = 1; + while (processing) + { processing = 0; + /* process all active rows */ + for (;;) + { row = npp->r_head; + if (row == NULL || !row->temp) break; + npp_deactivate_row(npp, row); + ret = npp_process_row(npp, row, hard); + if (ret != 0) goto done; + processing = 1; + } + /* process all active columns */ + for (;;) + { col = npp->c_head; + if (col == NULL || !col->temp) break; + npp_deactivate_col(npp, col); + ret = npp_process_col(npp, col); + if (ret != 0) goto done; + processing = 1; + } + } +#if 1 /* 23/XII-2009 */ + if (npp->sol == GLP_MIP && !hard) + { /* improve current column bounds (optional) */ + for (row = npp->r_head; row != NULL; row = row->next) + { if (npp_improve_bounds(npp, row, 0) < 0) + { ret = GLP_ENOPFS; + goto done; + } + } + } +#endif + /* all seems ok */ + ret = 0; +done: xassert(ret == 0 || ret == GLP_ENOPFS || ret == GLP_ENODFS); +#ifdef GLP_DEBUG + xprintf("\n"); +#endif + return ret; +} + +/**********************************************************************/ + +int npp_simplex(NPP *npp, const glp_smcp *parm) +{ /* process LP prior to applying primal/dual simplex method */ + int ret; + xassert(npp->sol == GLP_SOL); + xassert(parm == parm); + ret = npp_process_prob(npp, 0); + return ret; +} + +/**********************************************************************/ + +int npp_integer(NPP *npp, const glp_iocp *parm) +{ /* process MIP prior to applying branch-and-bound method */ + NPPROW *row, *prev_row; + NPPCOL *col; + NPPAIJ *aij; + int count, ret; + xassert(npp->sol == GLP_MIP); + xassert(parm == parm); + /*==============================================================*/ + /* perform basic MIP processing */ + ret = npp_process_prob(npp, 1); + if (ret != 0) goto done; + /*==============================================================*/ + /* binarize problem, if required */ + if (parm->binarize) + npp_binarize_prob(npp); + /*==============================================================*/ + /* identify hidden packing inequalities */ + count = 0; + /* new rows will be added to the end of the row list, so we go + from the end to beginning of the row list */ + for (row = npp->r_tail; row != NULL; row = prev_row) + { prev_row = row->prev; + /* skip free row */ + if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) continue; + /* skip equality constraint */ + if (row->lb == row->ub) continue; + /* skip row having less than two variables */ + if (row->ptr == NULL || row->ptr->r_next == NULL) continue; + /* skip row having non-binary variables */ + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { col = aij->col; + if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) + break; + } + if (aij != NULL) continue; + count += npp_hidden_packing(npp, row); + } + if (count > 0) + xprintf("%d hidden packing inequaliti(es) were detected\n", + count); + /*==============================================================*/ + /* identify hidden covering inequalities */ + count = 0; + /* new rows will be added to the end of the row list, so we go + from the end to beginning of the row list */ + for (row = npp->r_tail; row != NULL; row = prev_row) + { prev_row = row->prev; + /* skip free row */ + if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) continue; + /* skip equality constraint */ + if (row->lb == row->ub) continue; + /* skip row having less than three variables */ + if (row->ptr == NULL || row->ptr->r_next == NULL || + row->ptr->r_next->r_next == NULL) continue; + /* skip row having non-binary variables */ + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { col = aij->col; + if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) + break; + } + if (aij != NULL) continue; + count += npp_hidden_covering(npp, row); + } + if (count > 0) + xprintf("%d hidden covering inequaliti(es) were detected\n", + count); + /*==============================================================*/ + /* reduce inequality constraint coefficients */ + count = 0; + /* new rows will be added to the end of the row list, so we go + from the end to beginning of the row list */ + for (row = npp->r_tail; row != NULL; row = prev_row) + { prev_row = row->prev; + /* skip equality constraint */ + if (row->lb == row->ub) continue; + count += npp_reduce_ineq_coef(npp, row); + } + if (count > 0) + xprintf("%d constraint coefficient(s) were reduced\n", count); + /*==============================================================*/ +#ifdef GLP_DEBUG + routine(npp); +#endif + /*==============================================================*/ + /* all seems ok */ + ret = 0; +done: return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpnpp06.c b/resources/3rdparty/glpk-4.57/src/glpnpp06.c new file mode 100644 index 000000000..57d283ec9 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpnpp06.c @@ -0,0 +1,1501 @@ +/* glpnpp06.c (translate feasibility problem to CNF-SAT) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpnpp.h" + +/*********************************************************************** +* npp_sat_free_row - process free (unbounded) row +* +* This routine processes row p, which is free (i.e. has no finite +* bounds): +* +* -inf < sum a[p,j] x[j] < +inf. (1) +* +* The constraint (1) cannot be active and therefore it is redundant, +* so the routine simply removes it from the original problem. */ + +void npp_sat_free_row(NPP *npp, NPPROW *p) +{ /* the row should be free */ + xassert(p->lb == -DBL_MAX && p->ub == +DBL_MAX); + /* remove the row from the problem */ + npp_del_row(npp, p); + return; +} + +/*********************************************************************** +* npp_sat_fixed_col - process fixed column +* +* This routine processes column q, which is fixed: +* +* x[q] = s[q], (1) +* +* where s[q] is a fixed column value. +* +* The routine substitutes fixed value s[q] into constraint rows and +* then removes column x[q] from the original problem. +* +* Substitution of x[q] = s[q] into row i gives: +* +* L[i] <= sum a[i,j] x[j] <= U[i] ==> +* j +* +* L[i] <= sum a[i,j] x[j] + a[i,q] x[q] <= U[i] ==> +* j!=q +* +* L[i] <= sum a[i,j] x[j] + a[i,q] s[q] <= U[i] ==> +* j!=q +* +* L~[i] <= sum a[i,j] x[j] <= U~[i], +* j!=q +* +* where +* +* L~[i] = L[i] - a[i,q] s[q], (2) +* +* U~[i] = U[i] - a[i,q] s[q] (3) +* +* are, respectively, lower and upper bound of row i in the transformed +* problem. +* +* On recovering solution x[q] is assigned the value of s[q]. */ + +struct sat_fixed_col +{ /* fixed column */ + int q; + /* column reference number for variable x[q] */ + int s; + /* value, at which x[q] is fixed */ +}; + +static int rcv_sat_fixed_col(NPP *, void *); + +int npp_sat_fixed_col(NPP *npp, NPPCOL *q) +{ struct sat_fixed_col *info; + NPPROW *i; + NPPAIJ *aij; + int temp; + /* the column should be fixed */ + xassert(q->lb == q->ub); + /* create transformation stack entry */ + info = npp_push_tse(npp, + rcv_sat_fixed_col, sizeof(struct sat_fixed_col)); + info->q = q->j; + info->s = (int)q->lb; + xassert((double)info->s == q->lb); + /* substitute x[q] = s[q] into constraint rows */ + if (info->s == 0) + goto skip; + for (aij = q->ptr; aij != NULL; aij = aij->c_next) + { i = aij->row; + if (i->lb != -DBL_MAX) + { i->lb -= aij->val * (double)info->s; + temp = (int)i->lb; + if ((double)temp != i->lb) + return 1; /* integer arithmetic error */ + } + if (i->ub != +DBL_MAX) + { i->ub -= aij->val * (double)info->s; + temp = (int)i->ub; + if ((double)temp != i->ub) + return 2; /* integer arithmetic error */ + } + } +skip: /* remove the column from the problem */ + npp_del_col(npp, q); + return 0; +} + +static int rcv_sat_fixed_col(NPP *npp, void *info_) +{ struct sat_fixed_col *info = info_; + npp->c_value[info->q] = (double)info->s; + return 0; +} + +/*********************************************************************** +* npp_sat_is_bin_comb - test if row is binary combination +* +* This routine tests if the specified row is a binary combination, +* i.e. all its constraint coefficients are +1 and -1 and all variables +* are binary. If the test was passed, the routine returns non-zero, +* otherwise zero. */ + +int npp_sat_is_bin_comb(NPP *npp, NPPROW *row) +{ NPPCOL *col; + NPPAIJ *aij; + xassert(npp == npp); + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { if (!(aij->val == +1.0 || aij->val == -1.0)) + return 0; /* non-unity coefficient */ + col = aij->col; + if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) + return 0; /* non-binary column */ + } + return 1; /* test was passed */ +} + +/*********************************************************************** +* npp_sat_num_pos_coef - determine number of positive coefficients +* +* This routine returns the number of positive coefficients in the +* specified row. */ + +int npp_sat_num_pos_coef(NPP *npp, NPPROW *row) +{ NPPAIJ *aij; + int num = 0; + xassert(npp == npp); + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { if (aij->val > 0.0) + num++; + } + return num; +} + +/*********************************************************************** +* npp_sat_num_neg_coef - determine number of negative coefficients +* +* This routine returns the number of negative coefficients in the +* specified row. */ + +int npp_sat_num_neg_coef(NPP *npp, NPPROW *row) +{ NPPAIJ *aij; + int num = 0; + xassert(npp == npp); + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { if (aij->val < 0.0) + num++; + } + return num; +} + +/*********************************************************************** +* npp_sat_is_cover_ineq - test if row is covering inequality +* +* The canonical form of a covering inequality is the following: +* +* sum x[j] >= 1, (1) +* j in J +* +* where all x[j] are binary variables. +* +* In general case a covering inequality may have one of the following +* two forms: +* +* sum x[j] - sum x[j] >= 1 - |J-|, (2) +* j in J+ j in J- +* +* +* sum x[j] - sum x[j] <= |J+| - 1. (3) +* j in J+ j in J- +* +* Obviously, the inequality (2) can be transformed to the form (1) by +* substitution x[j] = 1 - x'[j] for all j in J-, where x'[j] is the +* negation of variable x[j]. And the inequality (3) can be transformed +* to (2) by multiplying both left- and right-hand sides by -1. +* +* This routine returns one of the following codes: +* +* 0, if the specified row is not a covering inequality; +* +* 1, if the specified row has the form (2); +* +* 2, if the specified row has the form (3). */ + +int npp_sat_is_cover_ineq(NPP *npp, NPPROW *row) +{ xassert(npp == npp); + if (row->lb != -DBL_MAX && row->ub == +DBL_MAX) + { /* row is inequality of '>=' type */ + if (npp_sat_is_bin_comb(npp, row)) + { /* row is a binary combination */ + if (row->lb == 1.0 - npp_sat_num_neg_coef(npp, row)) + { /* row has the form (2) */ + return 1; + } + } + } + else if (row->lb == -DBL_MAX && row->ub != +DBL_MAX) + { /* row is inequality of '<=' type */ + if (npp_sat_is_bin_comb(npp, row)) + { /* row is a binary combination */ + if (row->ub == npp_sat_num_pos_coef(npp, row) - 1.0) + { /* row has the form (3) */ + return 2; + } + } + } + /* row is not a covering inequality */ + return 0; +} + +/*********************************************************************** +* npp_sat_is_pack_ineq - test if row is packing inequality +* +* The canonical form of a packing inequality is the following: +* +* sum x[j] <= 1, (1) +* j in J +* +* where all x[j] are binary variables. +* +* In general case a packing inequality may have one of the following +* two forms: +* +* sum x[j] - sum x[j] <= 1 - |J-|, (2) +* j in J+ j in J- +* +* +* sum x[j] - sum x[j] >= |J+| - 1. (3) +* j in J+ j in J- +* +* Obviously, the inequality (2) can be transformed to the form (1) by +* substitution x[j] = 1 - x'[j] for all j in J-, where x'[j] is the +* negation of variable x[j]. And the inequality (3) can be transformed +* to (2) by multiplying both left- and right-hand sides by -1. +* +* This routine returns one of the following codes: +* +* 0, if the specified row is not a packing inequality; +* +* 1, if the specified row has the form (2); +* +* 2, if the specified row has the form (3). */ + +int npp_sat_is_pack_ineq(NPP *npp, NPPROW *row) +{ xassert(npp == npp); + if (row->lb == -DBL_MAX && row->ub != +DBL_MAX) + { /* row is inequality of '<=' type */ + if (npp_sat_is_bin_comb(npp, row)) + { /* row is a binary combination */ + if (row->ub == 1.0 - npp_sat_num_neg_coef(npp, row)) + { /* row has the form (2) */ + return 1; + } + } + } + else if (row->lb != -DBL_MAX && row->ub == +DBL_MAX) + { /* row is inequality of '>=' type */ + if (npp_sat_is_bin_comb(npp, row)) + { /* row is a binary combination */ + if (row->lb == npp_sat_num_pos_coef(npp, row) - 1.0) + { /* row has the form (3) */ + return 2; + } + } + } + /* row is not a packing inequality */ + return 0; +} + +/*********************************************************************** +* npp_sat_is_partn_eq - test if row is partitioning equality +* +* The canonical form of a partitioning equality is the following: +* +* sum x[j] = 1, (1) +* j in J +* +* where all x[j] are binary variables. +* +* In general case a partitioning equality may have one of the following +* two forms: +* +* sum x[j] - sum x[j] = 1 - |J-|, (2) +* j in J+ j in J- +* +* +* sum x[j] - sum x[j] = |J+| - 1. (3) +* j in J+ j in J- +* +* Obviously, the equality (2) can be transformed to the form (1) by +* substitution x[j] = 1 - x'[j] for all j in J-, where x'[j] is the +* negation of variable x[j]. And the equality (3) can be transformed +* to (2) by multiplying both left- and right-hand sides by -1. +* +* This routine returns one of the following codes: +* +* 0, if the specified row is not a partitioning equality; +* +* 1, if the specified row has the form (2); +* +* 2, if the specified row has the form (3). */ + +int npp_sat_is_partn_eq(NPP *npp, NPPROW *row) +{ xassert(npp == npp); + if (row->lb == row->ub) + { /* row is equality constraint */ + if (npp_sat_is_bin_comb(npp, row)) + { /* row is a binary combination */ + if (row->lb == 1.0 - npp_sat_num_neg_coef(npp, row)) + { /* row has the form (2) */ + return 1; + } + if (row->ub == npp_sat_num_pos_coef(npp, row) - 1.0) + { /* row has the form (3) */ + return 2; + } + } + } + /* row is not a partitioning equality */ + return 0; +} + +/*********************************************************************** +* npp_sat_reverse_row - multiply both sides of row by -1 +* +* This routines multiplies by -1 both left- and right-hand sides of +* the specified row: +* +* L <= sum x[j] <= U, +* +* that results in the following row: +* +* -U <= sum (-x[j]) <= -L. +* +* If no integer overflow occured, the routine returns zero, otherwise +* non-zero. */ + +int npp_sat_reverse_row(NPP *npp, NPPROW *row) +{ NPPAIJ *aij; + int temp, ret = 0; + double old_lb, old_ub; + xassert(npp == npp); + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { aij->val = -aij->val; + temp = (int)aij->val; + if ((double)temp != aij->val) + ret = 1; + } + old_lb = row->lb, old_ub = row->ub; + if (old_ub == +DBL_MAX) + row->lb = -DBL_MAX; + else + { row->lb = -old_ub; + temp = (int)row->lb; + if ((double)temp != row->lb) + ret = 2; + } + if (old_lb == -DBL_MAX) + row->ub = +DBL_MAX; + else + { row->ub = -old_lb; + temp = (int)row->ub; + if ((double)temp != row->ub) + ret = 3; + } + return ret; +} + +/*********************************************************************** +* npp_sat_split_pack - split packing inequality +* +* Let there be given a packing inequality in canonical form: +* +* sum t[j] <= 1, (1) +* j in J +* +* where t[j] = x[j] or t[j] = 1 - x[j], x[j] is a binary variable. +* And let J = J1 U J2 is a partition of the set of literals. Then the +* inequality (1) is obviously equivalent to the following two packing +* inequalities: +* +* sum t[j] <= y <--> sum t[j] + (1 - y) <= 1, (2) +* j in J1 j in J1 +* +* sum t[j] <= 1 - y <--> sum t[j] + y <= 1, (3) +* j in J2 j in J2 +* +* where y is a new binary variable added to the transformed problem. +* +* Assuming that the specified row is a packing inequality (1), this +* routine constructs the set J1 by including there first nlit literals +* (terms) from the specified row, and the set J2 = J \ J1. Then the +* routine creates a new row, which corresponds to inequality (2), and +* replaces the specified row with inequality (3). */ + +NPPROW *npp_sat_split_pack(NPP *npp, NPPROW *row, int nlit) +{ NPPROW *rrr; + NPPCOL *col; + NPPAIJ *aij; + int k; + /* original row should be packing inequality (1) */ + xassert(npp_sat_is_pack_ineq(npp, row) == 1); + /* and nlit should be less than the number of literals (terms) + in the original row */ + xassert(0 < nlit && nlit < npp_row_nnz(npp, row)); + /* create new row corresponding to inequality (2) */ + rrr = npp_add_row(npp); + rrr->lb = -DBL_MAX, rrr->ub = 1.0; + /* move first nlit literals (terms) from the original row to the + new row; the original row becomes inequality (3) */ + for (k = 1; k <= nlit; k++) + { aij = row->ptr; + xassert(aij != NULL); + /* add literal to the new row */ + npp_add_aij(npp, rrr, aij->col, aij->val); + /* correct rhs */ + if (aij->val < 0.0) + rrr->ub -= 1.0, row->ub += 1.0; + /* remove literal from the original row */ + npp_del_aij(npp, aij); + } + /* create new binary variable y */ + col = npp_add_col(npp); + col->is_int = 1, col->lb = 0.0, col->ub = 1.0; + /* include literal (1 - y) in the new row */ + npp_add_aij(npp, rrr, col, -1.0); + rrr->ub -= 1.0; + /* include literal y in the original row */ + npp_add_aij(npp, row, col, +1.0); + return rrr; +} + +/*********************************************************************** +* npp_sat_encode_pack - encode packing inequality +* +* Given a packing inequality in canonical form: +* +* sum t[j] <= 1, (1) +* j in J +* +* where t[j] = x[j] or t[j] = 1 - x[j], x[j] is a binary variable, +* this routine translates it to CNF by replacing it with the following +* equivalent set of edge packing inequalities: +* +* t[j] + t[k] <= 1 for all j, k in J, j != k. (2) +* +* Then the routine transforms each edge packing inequality (2) to +* corresponding covering inequality (that encodes two-literal clause) +* by multiplying both its part by -1: +* +* - t[j] - t[k] >= -1 <--> (1 - t[j]) + (1 - t[k]) >= 1. (3) +* +* On exit the routine removes the original row from the problem. */ + +void npp_sat_encode_pack(NPP *npp, NPPROW *row) +{ NPPROW *rrr; + NPPAIJ *aij, *aik; + /* original row should be packing inequality (1) */ + xassert(npp_sat_is_pack_ineq(npp, row) == 1); + /* create equivalent system of covering inequalities (3) */ + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { /* due to symmetry only one of inequalities t[j] + t[k] <= 1 + and t[k] <= t[j] <= 1 can be considered */ + for (aik = aij->r_next; aik != NULL; aik = aik->r_next) + { /* create edge packing inequality (2) */ + rrr = npp_add_row(npp); + rrr->lb = -DBL_MAX, rrr->ub = 1.0; + npp_add_aij(npp, rrr, aij->col, aij->val); + if (aij->val < 0.0) + rrr->ub -= 1.0; + npp_add_aij(npp, rrr, aik->col, aik->val); + if (aik->val < 0.0) + rrr->ub -= 1.0; + /* and transform it to covering inequality (3) */ + npp_sat_reverse_row(npp, rrr); + xassert(npp_sat_is_cover_ineq(npp, rrr) == 1); + } + } + /* remove the original row from the problem */ + npp_del_row(npp, row); + return; +} + +/*********************************************************************** +* npp_sat_encode_sum2 - encode 2-bit summation +* +* Given a set containing two literals x and y this routine encodes +* the equality +* +* x + y = s + 2 * c, (1) +* +* where +* +* s = (x + y) % 2 (2) +* +* is a binary variable modeling the low sum bit, and +* +* c = (x + y) / 2 (3) +* +* is a binary variable modeling the high (carry) sum bit. */ + +void npp_sat_encode_sum2(NPP *npp, NPPLSE *set, NPPSED *sed) +{ NPPROW *row; + int x, y, s, c; + /* the set should contain exactly two literals */ + xassert(set != NULL); + xassert(set->next != NULL); + xassert(set->next->next == NULL); + sed->x = set->lit; + xassert(sed->x.neg == 0 || sed->x.neg == 1); + sed->y = set->next->lit; + xassert(sed->y.neg == 0 || sed->y.neg == 1); + sed->z.col = NULL, sed->z.neg = 0; + /* perform encoding s = (x + y) % 2 */ + sed->s = npp_add_col(npp); + sed->s->is_int = 1, sed->s->lb = 0.0, sed->s->ub = 1.0; + for (x = 0; x <= 1; x++) + { for (y = 0; y <= 1; y++) + { for (s = 0; s <= 1; s++) + { if ((x + y) % 2 != s) + { /* generate CNF clause to disable infeasible + combination */ + row = npp_add_row(npp); + row->lb = 1.0, row->ub = +DBL_MAX; + if (x == sed->x.neg) + npp_add_aij(npp, row, sed->x.col, +1.0); + else + { npp_add_aij(npp, row, sed->x.col, -1.0); + row->lb -= 1.0; + } + if (y == sed->y.neg) + npp_add_aij(npp, row, sed->y.col, +1.0); + else + { npp_add_aij(npp, row, sed->y.col, -1.0); + row->lb -= 1.0; + } + if (s == 0) + npp_add_aij(npp, row, sed->s, +1.0); + else + { npp_add_aij(npp, row, sed->s, -1.0); + row->lb -= 1.0; + } + } + } + } + } + /* perform encoding c = (x + y) / 2 */ + sed->c = npp_add_col(npp); + sed->c->is_int = 1, sed->c->lb = 0.0, sed->c->ub = 1.0; + for (x = 0; x <= 1; x++) + { for (y = 0; y <= 1; y++) + { for (c = 0; c <= 1; c++) + { if ((x + y) / 2 != c) + { /* generate CNF clause to disable infeasible + combination */ + row = npp_add_row(npp); + row->lb = 1.0, row->ub = +DBL_MAX; + if (x == sed->x.neg) + npp_add_aij(npp, row, sed->x.col, +1.0); + else + { npp_add_aij(npp, row, sed->x.col, -1.0); + row->lb -= 1.0; + } + if (y == sed->y.neg) + npp_add_aij(npp, row, sed->y.col, +1.0); + else + { npp_add_aij(npp, row, sed->y.col, -1.0); + row->lb -= 1.0; + } + if (c == 0) + npp_add_aij(npp, row, sed->c, +1.0); + else + { npp_add_aij(npp, row, sed->c, -1.0); + row->lb -= 1.0; + } + } + } + } + } + return; +} + +/*********************************************************************** +* npp_sat_encode_sum3 - encode 3-bit summation +* +* Given a set containing at least three literals this routine chooses +* some literals x, y, z from that set and encodes the equality +* +* x + y + z = s + 2 * c, (1) +* +* where +* +* s = (x + y + z) % 2 (2) +* +* is a binary variable modeling the low sum bit, and +* +* c = (x + y + z) / 2 (3) +* +* is a binary variable modeling the high (carry) sum bit. */ + +void npp_sat_encode_sum3(NPP *npp, NPPLSE *set, NPPSED *sed) +{ NPPROW *row; + int x, y, z, s, c; + /* the set should contain at least three literals */ + xassert(set != NULL); + xassert(set->next != NULL); + xassert(set->next->next != NULL); + sed->x = set->lit; + xassert(sed->x.neg == 0 || sed->x.neg == 1); + sed->y = set->next->lit; + xassert(sed->y.neg == 0 || sed->y.neg == 1); + sed->z = set->next->next->lit; + xassert(sed->z.neg == 0 || sed->z.neg == 1); + /* perform encoding s = (x + y + z) % 2 */ + sed->s = npp_add_col(npp); + sed->s->is_int = 1, sed->s->lb = 0.0, sed->s->ub = 1.0; + for (x = 0; x <= 1; x++) + { for (y = 0; y <= 1; y++) + { for (z = 0; z <= 1; z++) + { for (s = 0; s <= 1; s++) + { if ((x + y + z) % 2 != s) + { /* generate CNF clause to disable infeasible + combination */ + row = npp_add_row(npp); + row->lb = 1.0, row->ub = +DBL_MAX; + if (x == sed->x.neg) + npp_add_aij(npp, row, sed->x.col, +1.0); + else + { npp_add_aij(npp, row, sed->x.col, -1.0); + row->lb -= 1.0; + } + if (y == sed->y.neg) + npp_add_aij(npp, row, sed->y.col, +1.0); + else + { npp_add_aij(npp, row, sed->y.col, -1.0); + row->lb -= 1.0; + } + if (z == sed->z.neg) + npp_add_aij(npp, row, sed->z.col, +1.0); + else + { npp_add_aij(npp, row, sed->z.col, -1.0); + row->lb -= 1.0; + } + if (s == 0) + npp_add_aij(npp, row, sed->s, +1.0); + else + { npp_add_aij(npp, row, sed->s, -1.0); + row->lb -= 1.0; + } + } + } + } + } + } + /* perform encoding c = (x + y + z) / 2 */ + sed->c = npp_add_col(npp); + sed->c->is_int = 1, sed->c->lb = 0.0, sed->c->ub = 1.0; + for (x = 0; x <= 1; x++) + { for (y = 0; y <= 1; y++) + { for (z = 0; z <= 1; z++) + { for (c = 0; c <= 1; c++) + { if ((x + y + z) / 2 != c) + { /* generate CNF clause to disable infeasible + combination */ + row = npp_add_row(npp); + row->lb = 1.0, row->ub = +DBL_MAX; + if (x == sed->x.neg) + npp_add_aij(npp, row, sed->x.col, +1.0); + else + { npp_add_aij(npp, row, sed->x.col, -1.0); + row->lb -= 1.0; + } + if (y == sed->y.neg) + npp_add_aij(npp, row, sed->y.col, +1.0); + else + { npp_add_aij(npp, row, sed->y.col, -1.0); + row->lb -= 1.0; + } + if (z == sed->z.neg) + npp_add_aij(npp, row, sed->z.col, +1.0); + else + { npp_add_aij(npp, row, sed->z.col, -1.0); + row->lb -= 1.0; + } + if (c == 0) + npp_add_aij(npp, row, sed->c, +1.0); + else + { npp_add_aij(npp, row, sed->c, -1.0); + row->lb -= 1.0; + } + } + } + } + } + } + return; +} + +/*********************************************************************** +* npp_sat_encode_sum_ax - encode linear combination of 0-1 variables +* +* PURPOSE +* +* Given a linear combination of binary variables: +* +* sum a[j] x[j], (1) +* j +* +* which is the linear form of the specified row, this routine encodes +* (i.e. translates to CNF) the following equality: +* +* n +* sum |a[j]| t[j] = sum 2**(k-1) * y[k], (2) +* j k=1 +* +* where t[j] = x[j] (if a[j] > 0) or t[j] = 1 - x[j] (if a[j] < 0), +* and y[k] is either t[j] or a new literal created by the routine or +* a constant zero. Note that the sum in the right-hand side of (2) can +* be thought as a n-bit representation of the sum in the left-hand +* side, which is a non-negative integer number. +* +* ALGORITHM +* +* First, the number of bits, n, sufficient to represent any value in +* the left-hand side of (2) is determined. Obviously, n is the number +* of bits sufficient to represent the sum (sum |a[j]|). +* +* Let +* +* n +* |a[j]| = sum 2**(k-1) b[j,k], (3) +* k=1 +* +* where b[j,k] is k-th bit in a n-bit representation of |a[j]|. Then +* +* m n +* sum |a[j]| * t[j] = sum 2**(k-1) sum b[j,k] * t[j]. (4) +* j k=1 j=1 +* +* Introducing the set +* +* J[k] = { j : b[j,k] = 1 } (5) +* +* allows rewriting (4) as follows: +* +* n +* sum |a[j]| * t[j] = sum 2**(k-1) sum t[j]. (6) +* j k=1 j in J[k] +* +* Thus, our goal is to provide |J[k]| <= 1 for all k, in which case +* we will have the representation (1). +* +* Let |J[k]| = 2, i.e. J[k] has exactly two literals u and v. In this +* case we can apply the following transformation: +* +* u + v = s + 2 * c, (7) +* +* where s and c are, respectively, low (sum) and high (carry) bits of +* the sum of two bits. This allows to replace two literals u and v in +* J[k] by one literal s, and carry out literal c to J[k+1]. +* +* If |J[k]| >= 3, i.e. J[k] has at least three literals u, v, and w, +* we can apply the following transformation: +* +* u + v + w = s + 2 * c. (8) +* +* Again, literal s replaces literals u, v, and w in J[k], and literal +* c goes into J[k+1]. +* +* On exit the routine stores each literal from J[k] in element y[k], +* 1 <= k <= n. If J[k] is empty, y[k] is set to constant false. +* +* RETURNS +* +* The routine returns n, the number of literals in the right-hand side +* of (2), 0 <= n <= NBIT_MAX. If the sum (sum |a[j]|) is too large, so +* more than NBIT_MAX (= 31) literals are needed to encode the original +* linear combination, the routine returns a negative value. */ + +#define NBIT_MAX 31 +/* maximal number of literals in the right hand-side of (2) */ + +static NPPLSE *remove_lse(NPP *npp, NPPLSE *set, NPPCOL *col) +{ /* remove specified literal from specified literal set */ + NPPLSE *lse, *prev = NULL; + for (lse = set; lse != NULL; prev = lse, lse = lse->next) + if (lse->lit.col == col) break; + xassert(lse != NULL); + if (prev == NULL) + set = lse->next; + else + prev->next = lse->next; + dmp_free_atom(npp->pool, lse, sizeof(NPPLSE)); + return set; +} + +int npp_sat_encode_sum_ax(NPP *npp, NPPROW *row, NPPLIT y[]) +{ NPPAIJ *aij; + NPPLSE *set[1+NBIT_MAX], *lse; + NPPSED sed; + int k, n, temp; + double sum; + /* compute the sum (sum |a[j]|) */ + sum = 0.0; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + sum += fabs(aij->val); + /* determine n, the number of bits in the sum */ + temp = (int)sum; + if ((double)temp != sum) + return -1; /* integer arithmetic error */ + for (n = 0; temp > 0; n++, temp >>= 1); + xassert(0 <= n && n <= NBIT_MAX); + /* build initial sets J[k], 1 <= k <= n; see (5) */ + /* set[k] is a pointer to the list of literals in J[k] */ + for (k = 1; k <= n; k++) + set[k] = NULL; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { temp = (int)fabs(aij->val); + xassert((int)temp == fabs(aij->val)); + for (k = 1; temp > 0; k++, temp >>= 1) + { if (temp & 1) + { xassert(k <= n); + lse = dmp_get_atom(npp->pool, sizeof(NPPLSE)); + lse->lit.col = aij->col; + lse->lit.neg = (aij->val > 0.0 ? 0 : 1); + lse->next = set[k]; + set[k] = lse; + } + } + } + /* main transformation loop */ + for (k = 1; k <= n; k++) + { /* reduce J[k] and set y[k] */ + for (;;) + { if (set[k] == NULL) + { /* J[k] is empty */ + /* set y[k] to constant false */ + y[k].col = NULL, y[k].neg = 0; + break; + } + if (set[k]->next == NULL) + { /* J[k] contains one literal */ + /* set y[k] to that literal */ + y[k] = set[k]->lit; + dmp_free_atom(npp->pool, set[k], sizeof(NPPLSE)); + break; + } + if (set[k]->next->next == NULL) + { /* J[k] contains two literals */ + /* apply transformation (7) */ + npp_sat_encode_sum2(npp, set[k], &sed); + } + else + { /* J[k] contains at least three literals */ + /* apply transformation (8) */ + npp_sat_encode_sum3(npp, set[k], &sed); + /* remove third literal from set[k] */ + set[k] = remove_lse(npp, set[k], sed.z.col); + } + /* remove second literal from set[k] */ + set[k] = remove_lse(npp, set[k], sed.y.col); + /* remove first literal from set[k] */ + set[k] = remove_lse(npp, set[k], sed.x.col); + /* include new literal s to set[k] */ + lse = dmp_get_atom(npp->pool, sizeof(NPPLSE)); + lse->lit.col = sed.s, lse->lit.neg = 0; + lse->next = set[k]; + set[k] = lse; + /* include new literal c to set[k+1] */ + xassert(k < n); /* FIXME: can "overflow" happen? */ + lse = dmp_get_atom(npp->pool, sizeof(NPPLSE)); + lse->lit.col = sed.c, lse->lit.neg = 0; + lse->next = set[k+1]; + set[k+1] = lse; + } + } + return n; +} + +/*********************************************************************** +* npp_sat_normalize_clause - normalize clause +* +* This routine normalizes the specified clause, which is a disjunction +* of literals, by replacing multiple literals, which refer to the same +* binary variable, with a single literal. +* +* On exit the routine returns the number of literals in the resulting +* clause. However, if the specified clause includes both a literal and +* its negation, the routine returns a negative value meaning that the +* clause is equivalent to the value true. */ + +int npp_sat_normalize_clause(NPP *npp, int size, NPPLIT lit[]) +{ int j, k, new_size; + xassert(npp == npp); + xassert(size >= 0); + new_size = 0; + for (k = 1; k <= size; k++) + { for (j = 1; j <= new_size; j++) + { if (lit[k].col == lit[j].col) + { /* lit[k] refers to the same variable as lit[j], which + is already included in the resulting clause */ + if (lit[k].neg == lit[j].neg) + { /* ignore lit[k] due to the idempotent law */ + goto skip; + } + else + { /* lit[k] is NOT lit[j]; the clause is equivalent to + the value true */ + return -1; + } + } + } + /* include lit[k] in the resulting clause */ + lit[++new_size] = lit[k]; +skip: ; + } + return new_size; +} + +/*********************************************************************** +* npp_sat_encode_clause - translate clause to cover inequality +* +* Given a clause +* +* OR t[j], (1) +* j in J +* +* where t[j] is a literal, i.e. t[j] = x[j] or t[j] = NOT x[j], this +* routine translates it to the following equivalent cover inequality, +* which is added to the transformed problem: +* +* sum t[j] >= 1, (2) +* j in J +* +* where t[j] = x[j] or t[j] = 1 - x[j]. +* +* If necessary, the clause should be normalized before a call to this +* routine. */ + +NPPROW *npp_sat_encode_clause(NPP *npp, int size, NPPLIT lit[]) +{ NPPROW *row; + int k; + xassert(size >= 1); + row = npp_add_row(npp); + row->lb = 1.0, row->ub = +DBL_MAX; + for (k = 1; k <= size; k++) + { xassert(lit[k].col != NULL); + if (lit[k].neg == 0) + npp_add_aij(npp, row, lit[k].col, +1.0); + else if (lit[k].neg == 1) + { npp_add_aij(npp, row, lit[k].col, -1.0); + row->lb -= 1.0; + } + else + xassert(lit != lit); + } + return row; +} + +/*********************************************************************** +* npp_sat_encode_geq - encode "not less than" constraint +* +* PURPOSE +* +* This routine translates to CNF the following constraint: +* +* n +* sum 2**(k-1) * y[k] >= b, (1) +* k=1 +* +* where y[k] is either a literal (i.e. y[k] = x[k] or y[k] = 1 - x[k]) +* or constant false (zero), b is a given lower bound. +* +* ALGORITHM +* +* If b < 0, the constraint is redundant, so assume that b >= 0. Let +* +* n +* b = sum 2**(k-1) b[k], (2) +* k=1 +* +* where b[k] is k-th binary digit of b. (Note that if b >= 2**n and +* therefore cannot be represented in the form (2), the constraint (1) +* is infeasible.) In this case the condition (1) is equivalent to the +* following condition: +* +* y[n] y[n-1] ... y[2] y[1] >= b[n] b[n-1] ... b[2] b[1], (3) +* +* where ">=" is understood lexicographically. +* +* Algorithmically the condition (3) can be tested as follows: +* +* for (k = n; k >= 1; k--) +* { if (y[k] < b[k]) +* y is less than b; +* if (y[k] > b[k]) +* y is greater than b; +* } +* y is equal to b; +* +* Thus, y is less than b iff there exists k, 1 <= k <= n, for which +* the following condition is satisfied: +* +* y[n] = b[n] AND ... AND y[k+1] = b[k+1] AND y[k] < b[k]. (4) +* +* Negating the condition (4) we have that y is not less than b iff for +* all k, 1 <= k <= n, the following condition is satisfied: +* +* y[n] != b[n] OR ... OR y[k+1] != b[k+1] OR y[k] >= b[k]. (5) +* +* Note that if b[k] = 0, the literal y[k] >= b[k] is always true, in +* which case the entire clause (5) is true and can be omitted. +* +* RETURNS +* +* Normally the routine returns zero. However, if the constraint (1) is +* infeasible, the routine returns non-zero. */ + +int npp_sat_encode_geq(NPP *npp, int n, NPPLIT y[], int rhs) +{ NPPLIT lit[1+NBIT_MAX]; + int j, k, size, temp, b[1+NBIT_MAX]; + xassert(0 <= n && n <= NBIT_MAX); + /* if the constraint (1) is redundant, do nothing */ + if (rhs < 0) + return 0; + /* determine binary digits of b according to (2) */ + for (k = 1, temp = rhs; k <= n; k++, temp >>= 1) + b[k] = temp & 1; + if (temp != 0) + { /* b >= 2**n; the constraint (1) is infeasible */ + return 1; + } + /* main transformation loop */ + for (k = 1; k <= n; k++) + { /* build the clause (5) for current k */ + size = 0; /* clause size = number of literals */ + /* add literal y[k] >= b[k] */ + if (b[k] == 0) + { /* b[k] = 0 -> the literal is true */ + goto skip; + } + else if (y[k].col == NULL) + { /* y[k] = 0, b[k] = 1 -> the literal is false */ + xassert(y[k].neg == 0); + } + else + { /* add literal y[k] = 1 */ + lit[++size] = y[k]; + } + for (j = k+1; j <= n; j++) + { /* add literal y[j] != b[j] */ + if (y[j].col == NULL) + { xassert(y[j].neg == 0); + if (b[j] == 0) + { /* y[j] = 0, b[j] = 0 -> the literal is false */ + continue; + } + else + { /* y[j] = 0, b[j] = 1 -> the literal is true */ + goto skip; + } + } + else + { lit[++size] = y[j]; + if (b[j] != 0) + lit[size].neg = 1 - lit[size].neg; + } + } + /* normalize the clause */ + size = npp_sat_normalize_clause(npp, size, lit); + if (size < 0) + { /* the clause is equivalent to the value true */ + goto skip; + } + if (size == 0) + { /* the clause is equivalent to the value false; this means + that the constraint (1) is infeasible */ + return 2; + } + /* translate the clause to corresponding cover inequality */ + npp_sat_encode_clause(npp, size, lit); +skip: ; + } + return 0; +} + +/*********************************************************************** +* npp_sat_encode_leq - encode "not greater than" constraint +* +* PURPOSE +* +* This routine translates to CNF the following constraint: +* +* n +* sum 2**(k-1) * y[k] <= b, (1) +* k=1 +* +* where y[k] is either a literal (i.e. y[k] = x[k] or y[k] = 1 - x[k]) +* or constant false (zero), b is a given upper bound. +* +* ALGORITHM +* +* If b < 0, the constraint is infeasible, so assume that b >= 0. Let +* +* n +* b = sum 2**(k-1) b[k], (2) +* k=1 +* +* where b[k] is k-th binary digit of b. (Note that if b >= 2**n and +* therefore cannot be represented in the form (2), the constraint (1) +* is redundant.) In this case the condition (1) is equivalent to the +* following condition: +* +* y[n] y[n-1] ... y[2] y[1] <= b[n] b[n-1] ... b[2] b[1], (3) +* +* where "<=" is understood lexicographically. +* +* Algorithmically the condition (3) can be tested as follows: +* +* for (k = n; k >= 1; k--) +* { if (y[k] < b[k]) +* y is less than b; +* if (y[k] > b[k]) +* y is greater than b; +* } +* y is equal to b; +* +* Thus, y is greater than b iff there exists k, 1 <= k <= n, for which +* the following condition is satisfied: +* +* y[n] = b[n] AND ... AND y[k+1] = b[k+1] AND y[k] > b[k]. (4) +* +* Negating the condition (4) we have that y is not greater than b iff +* for all k, 1 <= k <= n, the following condition is satisfied: +* +* y[n] != b[n] OR ... OR y[k+1] != b[k+1] OR y[k] <= b[k]. (5) +* +* Note that if b[k] = 1, the literal y[k] <= b[k] is always true, in +* which case the entire clause (5) is true and can be omitted. +* +* RETURNS +* +* Normally the routine returns zero. However, if the constraint (1) is +* infeasible, the routine returns non-zero. */ + +int npp_sat_encode_leq(NPP *npp, int n, NPPLIT y[], int rhs) +{ NPPLIT lit[1+NBIT_MAX]; + int j, k, size, temp, b[1+NBIT_MAX]; + xassert(0 <= n && n <= NBIT_MAX); + /* check if the constraint (1) is infeasible */ + if (rhs < 0) + return 1; + /* determine binary digits of b according to (2) */ + for (k = 1, temp = rhs; k <= n; k++, temp >>= 1) + b[k] = temp & 1; + if (temp != 0) + { /* b >= 2**n; the constraint (1) is redundant */ + return 0; + } + /* main transformation loop */ + for (k = 1; k <= n; k++) + { /* build the clause (5) for current k */ + size = 0; /* clause size = number of literals */ + /* add literal y[k] <= b[k] */ + if (b[k] == 1) + { /* b[k] = 1 -> the literal is true */ + goto skip; + } + else if (y[k].col == NULL) + { /* y[k] = 0, b[k] = 0 -> the literal is true */ + xassert(y[k].neg == 0); + goto skip; + } + else + { /* add literal y[k] = 0 */ + lit[++size] = y[k]; + lit[size].neg = 1 - lit[size].neg; + } + for (j = k+1; j <= n; j++) + { /* add literal y[j] != b[j] */ + if (y[j].col == NULL) + { xassert(y[j].neg == 0); + if (b[j] == 0) + { /* y[j] = 0, b[j] = 0 -> the literal is false */ + continue; + } + else + { /* y[j] = 0, b[j] = 1 -> the literal is true */ + goto skip; + } + } + else + { lit[++size] = y[j]; + if (b[j] != 0) + lit[size].neg = 1 - lit[size].neg; + } + } + /* normalize the clause */ + size = npp_sat_normalize_clause(npp, size, lit); + if (size < 0) + { /* the clause is equivalent to the value true */ + goto skip; + } + if (size == 0) + { /* the clause is equivalent to the value false; this means + that the constraint (1) is infeasible */ + return 2; + } + /* translate the clause to corresponding cover inequality */ + npp_sat_encode_clause(npp, size, lit); +skip: ; + } + return 0; +} + +/*********************************************************************** +* npp_sat_encode_row - encode constraint (row) of general type +* +* PURPOSE +* +* This routine translates to CNF the following constraint (row): +* +* L <= sum a[j] x[j] <= U, (1) +* j +* +* where all x[j] are binary variables. +* +* ALGORITHM +* +* First, the routine performs substitution x[j] = t[j] for j in J+ +* and x[j] = 1 - t[j] for j in J-, where J+ = { j : a[j] > 0 } and +* J- = { j : a[j] < 0 }. This gives: +* +* L <= sum a[j] t[j] + sum a[j] (1 - t[j]) <= U ==> +* j in J+ j in J- +* +* L' <= sum |a[j]| t[j] <= U', (2) +* j +* +* where +* +* L' = L - sum a[j], U' = U - sum a[j]. (3) +* j in J- j in J- +* +* (Actually only new bounds L' and U' are computed.) +* +* Then the routine translates to CNF the following equality: +* +* n +* sum |a[j]| t[j] = sum 2**(k-1) * y[k], (4) +* j k=1 +* +* where y[k] is either some t[j] or a new literal or a constant zero +* (see the routine npp_sat_encode_sum_ax). +* +* Finally, the routine translates to CNF the following conditions: +* +* n +* sum 2**(k-1) * y[k] >= L' (5) +* k=1 +* +* and +* +* n +* sum 2**(k-1) * y[k] <= U' (6) +* k=1 +* +* (see the routines npp_sat_encode_geq and npp_sat_encode_leq). +* +* All resulting clauses are encoded as cover inequalities and included +* into the transformed problem. +* +* Note that on exit the routine removes the specified constraint (row) +* from the original problem. +* +* RETURNS +* +* The routine returns one of the following codes: +* +* 0 - translation was successful; +* 1 - constraint (1) was found infeasible; +* 2 - integer arithmetic error occured. */ + +int npp_sat_encode_row(NPP *npp, NPPROW *row) +{ NPPAIJ *aij; + NPPLIT y[1+NBIT_MAX]; + int n, rhs; + double lb, ub; + /* the row should not be free */ + xassert(!(row->lb == -DBL_MAX && row->ub == +DBL_MAX)); + /* compute new bounds L' and U' (3) */ + lb = row->lb; + ub = row->ub; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + { if (aij->val < 0.0) + { if (lb != -DBL_MAX) + lb -= aij->val; + if (ub != -DBL_MAX) + ub -= aij->val; + } + } + /* encode the equality (4) */ + n = npp_sat_encode_sum_ax(npp, row, y); + if (n < 0) + return 2; /* integer arithmetic error */ + /* encode the condition (5) */ + if (lb != -DBL_MAX) + { rhs = (int)lb; + if ((double)rhs != lb) + return 2; /* integer arithmetic error */ + if (npp_sat_encode_geq(npp, n, y, rhs) != 0) + return 1; /* original constraint is infeasible */ + } + /* encode the condition (6) */ + if (ub != +DBL_MAX) + { rhs = (int)ub; + if ((double)rhs != ub) + return 2; /* integer arithmetic error */ + if (npp_sat_encode_leq(npp, n, y, rhs) != 0) + return 1; /* original constraint is infeasible */ + } + /* remove the specified row from the problem */ + npp_del_row(npp, row); + return 0; +} + +/*********************************************************************** +* npp_sat_encode_prob - encode 0-1 feasibility problem +* +* This routine translates the specified 0-1 feasibility problem to an +* equivalent SAT-CNF problem. +* +* N.B. Currently this is a very crude implementation. +* +* RETURNS +* +* 0 success; +* +* GLP_ENOPFS primal/integer infeasibility detected; +* +* GLP_ERANGE integer overflow occured. */ + +int npp_sat_encode_prob(NPP *npp) +{ NPPROW *row, *next_row, *prev_row; + NPPCOL *col, *next_col; + int cover = 0, pack = 0, partn = 0, ret; + /* process and remove free rows */ + for (row = npp->r_head; row != NULL; row = next_row) + { next_row = row->next; + if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) + npp_sat_free_row(npp, row); + } + /* process and remove fixed columns */ + for (col = npp->c_head; col != NULL; col = next_col) + { next_col = col->next; + if (col->lb == col->ub) + xassert(npp_sat_fixed_col(npp, col) == 0); + } + /* only binary variables should remain */ + for (col = npp->c_head; col != NULL; col = col->next) + xassert(col->is_int && col->lb == 0.0 && col->ub == 1.0); + /* new rows may be added to the end of the row list, so we walk + from the end to beginning of the list */ + for (row = npp->r_tail; row != NULL; row = prev_row) + { prev_row = row->prev; + /* process special cases */ + ret = npp_sat_is_cover_ineq(npp, row); + if (ret != 0) + { /* row is covering inequality */ + cover++; + /* since it already encodes a clause, just transform it to + canonical form */ + if (ret == 2) + { xassert(npp_sat_reverse_row(npp, row) == 0); + ret = npp_sat_is_cover_ineq(npp, row); + } + xassert(ret == 1); + continue; + } + ret = npp_sat_is_partn_eq(npp, row); + if (ret != 0) + { /* row is partitioning equality */ + NPPROW *cov; + NPPAIJ *aij; + partn++; + /* transform it to canonical form */ + if (ret == 2) + { xassert(npp_sat_reverse_row(npp, row) == 0); + ret = npp_sat_is_partn_eq(npp, row); + } + xassert(ret == 1); + /* and split it into covering and packing inequalities, + both in canonical forms */ + cov = npp_add_row(npp); + cov->lb = row->lb, cov->ub = +DBL_MAX; + for (aij = row->ptr; aij != NULL; aij = aij->r_next) + npp_add_aij(npp, cov, aij->col, aij->val); + xassert(npp_sat_is_cover_ineq(npp, cov) == 1); + /* the cover inequality already encodes a clause and do + not need any further processing */ + row->lb = -DBL_MAX; + xassert(npp_sat_is_pack_ineq(npp, row) == 1); + /* the packing inequality will be processed below */ + pack--; + } + ret = npp_sat_is_pack_ineq(npp, row); + if (ret != 0) + { /* row is packing inequality */ + NPPROW *rrr; + int nlit, desired_nlit = 4; + pack++; + /* transform it to canonical form */ + if (ret == 2) + { xassert(npp_sat_reverse_row(npp, row) == 0); + ret = npp_sat_is_pack_ineq(npp, row); + } + xassert(ret == 1); + /* process the packing inequality */ + for (;;) + { /* determine the number of literals in the remaining + inequality */ + nlit = npp_row_nnz(npp, row); + if (nlit <= desired_nlit) + break; + /* split the current inequality into one having not more + than desired_nlit literals and remaining one */ + rrr = npp_sat_split_pack(npp, row, desired_nlit-1); + /* translate the former inequality to CNF and remove it + from the original problem */ + npp_sat_encode_pack(npp, rrr); + } + /* translate the remaining inequality to CNF and remove it + from the original problem */ + npp_sat_encode_pack(npp, row); + continue; + } + /* translate row of general type to CNF and remove it from the + original problem */ + ret = npp_sat_encode_row(npp, row); + if (ret == 0) + ; + else if (ret == 1) + ret = GLP_ENOPFS; + else if (ret == 2) + ret = GLP_ERANGE; + else + xassert(ret != ret); + if (ret != 0) + goto done; + } + ret = 0; + if (cover != 0) + xprintf("%d covering inequalities\n", cover); + if (pack != 0) + xprintf("%d packing inequalities\n", pack); + if (partn != 0) + xprintf("%d partitioning equalities\n", partn); +done: return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glprgr.c b/resources/3rdparty/glpk-4.57/src/glprgr.c new file mode 100644 index 000000000..b4b616b1b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glprgr.c @@ -0,0 +1,165 @@ +/* glprgr.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#define _GLPSTD_ERRNO +#define _GLPSTD_STDIO +#include "env.h" +#include "glprgr.h" +#define xfault xerror + +/*********************************************************************** +* NAME +* +* rgr_write_bmp16 - write 16-color raster image in BMP file format +* +* SYNOPSIS +* +* #include "glprgr.h" +* int rgr_write_bmp16(const char *fname, int m, int n, const char +* map[]); +* +* DESCRIPTION +* +* The routine rgr_write_bmp16 writes 16-color raster image in +* uncompressed BMP file format (Windows bitmap) to a binary file whose +* name is specified by the character string fname. +* +* The parameters m and n specify, respectively, the number of rows and +* the numbers of columns (i.e. height and width) of the raster image. +* +* The character array map has m*n elements. Elements map[0, ..., n-1] +* correspond to the first (top) scanline, elements map[n, ..., 2*n-1] +* correspond to the second scanline, etc. +* +* Each element of the array map specifies a color of the corresponding +* pixel as 8-bit binary number XXXXIRGB, where four high-order bits (X) +* are ignored, I is high intensity bit, R is red color bit, G is green +* color bit, and B is blue color bit. Thus, all 16 possible colors are +* coded as following hexadecimal numbers: +* +* 0x00 = black 0x08 = dark gray +* 0x01 = blue 0x09 = bright blue +* 0x02 = green 0x0A = bright green +* 0x03 = cyan 0x0B = bright cyan +* 0x04 = red 0x0C = bright red +* 0x05 = magenta 0x0D = bright magenta +* 0x06 = brown 0x0E = yellow +* 0x07 = light gray 0x0F = white +* +* RETURNS +* +* If no error occured, the routine returns zero; otherwise, it prints +* an appropriate error message and returns non-zero. */ + +static void put_byte(FILE *fp, int c) +{ fputc(c, fp); + return; +} + +static void put_word(FILE *fp, int w) +{ /* big endian */ + put_byte(fp, w); + put_byte(fp, w >> 8); + return; +} + +static void put_dword(FILE *fp, int d) +{ /* big endian */ + put_word(fp, d); + put_word(fp, d >> 16); + return; +} + +int rgr_write_bmp16(const char *fname, int m, int n, const char map[]) +{ FILE *fp; + int offset, bmsize, i, j, b, ret = 0; + if (!(1 <= m && m <= 32767)) + xfault("rgr_write_bmp16: m = %d; invalid height\n", m); + if (!(1 <= n && n <= 32767)) + xfault("rgr_write_bmp16: n = %d; invalid width\n", n); + fp = fopen(fname, "wb"); + if (fp == NULL) + { xprintf("rgr_write_bmp16: unable to create '%s' - %s\n", + fname, strerror(errno)); + ret = 1; + goto fini; + } + offset = 14 + 40 + 16 * 4; + bmsize = (4 * n + 31) / 32; + /* struct BMPFILEHEADER (14 bytes) */ + /* UINT bfType */ put_byte(fp, 'B'), put_byte(fp, 'M'); + /* DWORD bfSize */ put_dword(fp, offset + bmsize * 4); + /* UINT bfReserved1 */ put_word(fp, 0); + /* UNIT bfReserved2 */ put_word(fp, 0); + /* DWORD bfOffBits */ put_dword(fp, offset); + /* struct BMPINFOHEADER (40 bytes) */ + /* DWORD biSize */ put_dword(fp, 40); + /* LONG biWidth */ put_dword(fp, n); + /* LONG biHeight */ put_dword(fp, m); + /* WORD biPlanes */ put_word(fp, 1); + /* WORD biBitCount */ put_word(fp, 4); + /* DWORD biCompression */ put_dword(fp, 0 /* BI_RGB */); + /* DWORD biSizeImage */ put_dword(fp, 0); + /* LONG biXPelsPerMeter */ put_dword(fp, 2953 /* 75 dpi */); + /* LONG biYPelsPerMeter */ put_dword(fp, 2953 /* 75 dpi */); + /* DWORD biClrUsed */ put_dword(fp, 0); + /* DWORD biClrImportant */ put_dword(fp, 0); + /* struct RGBQUAD (16 * 4 = 64 bytes) */ + /* CGA-compatible colors: */ + /* 0x00 = black */ put_dword(fp, 0x000000); + /* 0x01 = blue */ put_dword(fp, 0x000080); + /* 0x02 = green */ put_dword(fp, 0x008000); + /* 0x03 = cyan */ put_dword(fp, 0x008080); + /* 0x04 = red */ put_dword(fp, 0x800000); + /* 0x05 = magenta */ put_dword(fp, 0x800080); + /* 0x06 = brown */ put_dword(fp, 0x808000); + /* 0x07 = light gray */ put_dword(fp, 0xC0C0C0); + /* 0x08 = dark gray */ put_dword(fp, 0x808080); + /* 0x09 = bright blue */ put_dword(fp, 0x0000FF); + /* 0x0A = bright green */ put_dword(fp, 0x00FF00); + /* 0x0B = bright cyan */ put_dword(fp, 0x00FFFF); + /* 0x0C = bright red */ put_dword(fp, 0xFF0000); + /* 0x0D = bright magenta */ put_dword(fp, 0xFF00FF); + /* 0x0E = yellow */ put_dword(fp, 0xFFFF00); + /* 0x0F = white */ put_dword(fp, 0xFFFFFF); + /* pixel data bits */ + b = 0; + for (i = m - 1; i >= 0; i--) + { for (j = 0; j < ((n + 7) / 8) * 8; j++) + { b <<= 4; + b |= (j < n ? map[i * n + j] & 15 : 0); + if (j & 1) put_byte(fp, b); + } + } + fflush(fp); + if (ferror(fp)) + { xprintf("rgr_write_bmp16: write error on '%s' - %s\n", + fname, strerror(errno)); + ret = 1; + } +fini: if (fp != NULL) fclose(fp); + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glprgr.h b/resources/3rdparty/glpk-4.57/src/glprgr.h new file mode 100644 index 000000000..71e089e91 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glprgr.h @@ -0,0 +1,34 @@ +/* glprgr.h (raster graphics) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef GLPRGR_H +#define GLPRGR_H + +#define rgr_write_bmp16 _glp_rgr_write_bmp16 +int rgr_write_bmp16(const char *fname, int m, int n, const char map[]); +/* write 16-color raster image in BMP file format */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpscl.c b/resources/3rdparty/glpk-4.57/src/glpscl.c new file mode 100644 index 000000000..de769a8b1 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpscl.c @@ -0,0 +1,478 @@ +/* glpscl.c (problem scaling routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "misc.h" +#include "prob.h" + +/*********************************************************************** +* min_row_aij - determine minimal |a[i,j]| in i-th row +* +* This routine returns minimal magnitude of (non-zero) constraint +* coefficients in i-th row of the constraint matrix. +* +* If the parameter scaled is zero, the original constraint matrix A is +* assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. +* +* If i-th row of the matrix is empty, the routine returns 1. */ + +static double min_row_aij(glp_prob *lp, int i, int scaled) +{ GLPAIJ *aij; + double min_aij, temp; + xassert(1 <= i && i <= lp->m); + min_aij = 1.0; + for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) + { temp = fabs(aij->val); + if (scaled) temp *= (aij->row->rii * aij->col->sjj); + if (aij->r_prev == NULL || min_aij > temp) + min_aij = temp; + } + return min_aij; +} + +/*********************************************************************** +* max_row_aij - determine maximal |a[i,j]| in i-th row +* +* This routine returns maximal magnitude of (non-zero) constraint +* coefficients in i-th row of the constraint matrix. +* +* If the parameter scaled is zero, the original constraint matrix A is +* assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. +* +* If i-th row of the matrix is empty, the routine returns 1. */ + +static double max_row_aij(glp_prob *lp, int i, int scaled) +{ GLPAIJ *aij; + double max_aij, temp; + xassert(1 <= i && i <= lp->m); + max_aij = 1.0; + for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) + { temp = fabs(aij->val); + if (scaled) temp *= (aij->row->rii * aij->col->sjj); + if (aij->r_prev == NULL || max_aij < temp) + max_aij = temp; + } + return max_aij; +} + +/*********************************************************************** +* min_col_aij - determine minimal |a[i,j]| in j-th column +* +* This routine returns minimal magnitude of (non-zero) constraint +* coefficients in j-th column of the constraint matrix. +* +* If the parameter scaled is zero, the original constraint matrix A is +* assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. +* +* If j-th column of the matrix is empty, the routine returns 1. */ + +static double min_col_aij(glp_prob *lp, int j, int scaled) +{ GLPAIJ *aij; + double min_aij, temp; + xassert(1 <= j && j <= lp->n); + min_aij = 1.0; + for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next) + { temp = fabs(aij->val); + if (scaled) temp *= (aij->row->rii * aij->col->sjj); + if (aij->c_prev == NULL || min_aij > temp) + min_aij = temp; + } + return min_aij; +} + +/*********************************************************************** +* max_col_aij - determine maximal |a[i,j]| in j-th column +* +* This routine returns maximal magnitude of (non-zero) constraint +* coefficients in j-th column of the constraint matrix. +* +* If the parameter scaled is zero, the original constraint matrix A is +* assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. +* +* If j-th column of the matrix is empty, the routine returns 1. */ + +static double max_col_aij(glp_prob *lp, int j, int scaled) +{ GLPAIJ *aij; + double max_aij, temp; + xassert(1 <= j && j <= lp->n); + max_aij = 1.0; + for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next) + { temp = fabs(aij->val); + if (scaled) temp *= (aij->row->rii * aij->col->sjj); + if (aij->c_prev == NULL || max_aij < temp) + max_aij = temp; + } + return max_aij; +} + +/*********************************************************************** +* min_mat_aij - determine minimal |a[i,j]| in constraint matrix +* +* This routine returns minimal magnitude of (non-zero) constraint +* coefficients in the constraint matrix. +* +* If the parameter scaled is zero, the original constraint matrix A is +* assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. +* +* If the matrix is empty, the routine returns 1. */ + +static double min_mat_aij(glp_prob *lp, int scaled) +{ int i; + double min_aij, temp; + min_aij = 1.0; + for (i = 1; i <= lp->m; i++) + { temp = min_row_aij(lp, i, scaled); + if (i == 1 || min_aij > temp) + min_aij = temp; + } + return min_aij; +} + +/*********************************************************************** +* max_mat_aij - determine maximal |a[i,j]| in constraint matrix +* +* This routine returns maximal magnitude of (non-zero) constraint +* coefficients in the constraint matrix. +* +* If the parameter scaled is zero, the original constraint matrix A is +* assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. +* +* If the matrix is empty, the routine returns 1. */ + +static double max_mat_aij(glp_prob *lp, int scaled) +{ int i; + double max_aij, temp; + max_aij = 1.0; + for (i = 1; i <= lp->m; i++) + { temp = max_row_aij(lp, i, scaled); + if (i == 1 || max_aij < temp) + max_aij = temp; + } + return max_aij; +} + +/*********************************************************************** +* eq_scaling - perform equilibration scaling +* +* This routine performs equilibration scaling of rows and columns of +* the constraint matrix. +* +* If the parameter flag is zero, the routine scales rows at first and +* then columns. Otherwise, the routine scales columns and then rows. +* +* Rows are scaled as follows: +* +* n +* a'[i,j] = a[i,j] / max |a[i,j]|, i = 1,...,m. +* j=1 +* +* This makes the infinity (maximum) norm of each row of the matrix +* equal to 1. +* +* Columns are scaled as follows: +* +* m +* a'[i,j] = a[i,j] / max |a[i,j]|, j = 1,...,n. +* i=1 +* +* This makes the infinity (maximum) norm of each column of the matrix +* equal to 1. */ + +static void eq_scaling(glp_prob *lp, int flag) +{ int i, j, pass; + double temp; + xassert(flag == 0 || flag == 1); + for (pass = 0; pass <= 1; pass++) + { if (pass == flag) + { /* scale rows */ + for (i = 1; i <= lp->m; i++) + { temp = max_row_aij(lp, i, 1); + glp_set_rii(lp, i, glp_get_rii(lp, i) / temp); + } + } + else + { /* scale columns */ + for (j = 1; j <= lp->n; j++) + { temp = max_col_aij(lp, j, 1); + glp_set_sjj(lp, j, glp_get_sjj(lp, j) / temp); + } + } + } + return; +} + +/*********************************************************************** +* gm_scaling - perform geometric mean scaling +* +* This routine performs geometric mean scaling of rows and columns of +* the constraint matrix. +* +* If the parameter flag is zero, the routine scales rows at first and +* then columns. Otherwise, the routine scales columns and then rows. +* +* Rows are scaled as follows: +* +* a'[i,j] = a[i,j] / sqrt(alfa[i] * beta[i]), i = 1,...,m, +* +* where: +* n n +* alfa[i] = min |a[i,j]|, beta[i] = max |a[i,j]|. +* j=1 j=1 +* +* This allows decreasing the ratio beta[i] / alfa[i] for each row of +* the matrix. +* +* Columns are scaled as follows: +* +* a'[i,j] = a[i,j] / sqrt(alfa[j] * beta[j]), j = 1,...,n, +* +* where: +* m m +* alfa[j] = min |a[i,j]|, beta[j] = max |a[i,j]|. +* i=1 i=1 +* +* This allows decreasing the ratio beta[j] / alfa[j] for each column +* of the matrix. */ + +static void gm_scaling(glp_prob *lp, int flag) +{ int i, j, pass; + double temp; + xassert(flag == 0 || flag == 1); + for (pass = 0; pass <= 1; pass++) + { if (pass == flag) + { /* scale rows */ + for (i = 1; i <= lp->m; i++) + { temp = min_row_aij(lp, i, 1) * max_row_aij(lp, i, 1); + glp_set_rii(lp, i, glp_get_rii(lp, i) / sqrt(temp)); + } + } + else + { /* scale columns */ + for (j = 1; j <= lp->n; j++) + { temp = min_col_aij(lp, j, 1) * max_col_aij(lp, j, 1); + glp_set_sjj(lp, j, glp_get_sjj(lp, j) / sqrt(temp)); + } + } + } + return; +} + +/*********************************************************************** +* max_row_ratio - determine worst scaling "quality" for rows +* +* This routine returns the worst scaling "quality" for rows of the +* currently scaled constraint matrix: +* +* m +* ratio = max ratio[i], +* i=1 +* where: +* n n +* ratio[i] = max |a[i,j]| / min |a[i,j]|, 1 <= i <= m, +* j=1 j=1 +* +* is the scaling "quality" of i-th row. */ + +static double max_row_ratio(glp_prob *lp) +{ int i; + double ratio, temp; + ratio = 1.0; + for (i = 1; i <= lp->m; i++) + { temp = max_row_aij(lp, i, 1) / min_row_aij(lp, i, 1); + if (i == 1 || ratio < temp) ratio = temp; + } + return ratio; +} + +/*********************************************************************** +* max_col_ratio - determine worst scaling "quality" for columns +* +* This routine returns the worst scaling "quality" for columns of the +* currently scaled constraint matrix: +* +* n +* ratio = max ratio[j], +* j=1 +* where: +* m m +* ratio[j] = max |a[i,j]| / min |a[i,j]|, 1 <= j <= n, +* i=1 i=1 +* +* is the scaling "quality" of j-th column. */ + +static double max_col_ratio(glp_prob *lp) +{ int j; + double ratio, temp; + ratio = 1.0; + for (j = 1; j <= lp->n; j++) + { temp = max_col_aij(lp, j, 1) / min_col_aij(lp, j, 1); + if (j == 1 || ratio < temp) ratio = temp; + } + return ratio; +} + +/*********************************************************************** +* gm_iterate - perform iterative geometric mean scaling +* +* This routine performs iterative geometric mean scaling of rows and +* columns of the constraint matrix. +* +* The parameter it_max specifies the maximal number of iterations. +* Recommended value of it_max is 15. +* +* The parameter tau specifies a minimal improvement of the scaling +* "quality" on each iteration, 0 < tau < 1. It means than the scaling +* process continues while the following condition is satisfied: +* +* ratio[k] <= tau * ratio[k-1], +* +* where ratio = max |a[i,j]| / min |a[i,j]| is the scaling "quality" +* to be minimized, k is the iteration number. Recommended value of tau +* is 0.90. */ + +static void gm_iterate(glp_prob *lp, int it_max, double tau) +{ int k, flag; + double ratio = 0.0, r_old; + /* if the scaling "quality" for rows is better than for columns, + the rows are scaled first; otherwise, the columns are scaled + first */ + flag = (max_row_ratio(lp) > max_col_ratio(lp)); + for (k = 1; k <= it_max; k++) + { /* save the scaling "quality" from previous iteration */ + r_old = ratio; + /* determine the current scaling "quality" */ + ratio = max_mat_aij(lp, 1) / min_mat_aij(lp, 1); +#if 0 + xprintf("k = %d; ratio = %g\n", k, ratio); +#endif + /* if improvement is not enough, terminate scaling */ + if (k > 1 && ratio > tau * r_old) break; + /* otherwise, perform another iteration */ + gm_scaling(lp, flag); + } + return; +} + +/*********************************************************************** +* NAME +* +* scale_prob - scale problem data +* +* SYNOPSIS +* +* #include "glpscl.h" +* void scale_prob(glp_prob *lp, int flags); +* +* DESCRIPTION +* +* The routine scale_prob performs automatic scaling of problem data +* for the specified problem object. */ + +static void scale_prob(glp_prob *lp, int flags) +{ static const char *fmt = + "%s: min|aij| = %10.3e max|aij| = %10.3e ratio = %10.3e\n"; + double min_aij, max_aij, ratio; + xprintf("Scaling...\n"); + /* cancel the current scaling effect */ + glp_unscale_prob(lp); + /* report original scaling "quality" */ + min_aij = min_mat_aij(lp, 1); + max_aij = max_mat_aij(lp, 1); + ratio = max_aij / min_aij; + xprintf(fmt, " A", min_aij, max_aij, ratio); + /* check if the problem is well scaled */ + if (min_aij >= 0.10 && max_aij <= 10.0) + { xprintf("Problem data seem to be well scaled\n"); + /* skip scaling, if required */ + if (flags & GLP_SF_SKIP) goto done; + } + /* perform iterative geometric mean scaling, if required */ + if (flags & GLP_SF_GM) + { gm_iterate(lp, 15, 0.90); + min_aij = min_mat_aij(lp, 1); + max_aij = max_mat_aij(lp, 1); + ratio = max_aij / min_aij; + xprintf(fmt, "GM", min_aij, max_aij, ratio); + } + /* perform equilibration scaling, if required */ + if (flags & GLP_SF_EQ) + { eq_scaling(lp, max_row_ratio(lp) > max_col_ratio(lp)); + min_aij = min_mat_aij(lp, 1); + max_aij = max_mat_aij(lp, 1); + ratio = max_aij / min_aij; + xprintf(fmt, "EQ", min_aij, max_aij, ratio); + } + /* round scale factors to nearest power of two, if required */ + if (flags & GLP_SF_2N) + { int i, j; + for (i = 1; i <= lp->m; i++) + glp_set_rii(lp, i, round2n(glp_get_rii(lp, i))); + for (j = 1; j <= lp->n; j++) + glp_set_sjj(lp, j, round2n(glp_get_sjj(lp, j))); + min_aij = min_mat_aij(lp, 1); + max_aij = max_mat_aij(lp, 1); + ratio = max_aij / min_aij; + xprintf(fmt, "2N", min_aij, max_aij, ratio); + } +done: return; +} + +/*********************************************************************** +* NAME +* +* glp_scale_prob - scale problem data +* +* SYNOPSIS +* +* void glp_scale_prob(glp_prob *lp, int flags); +* +* DESCRIPTION +* +* The routine glp_scale_prob performs automatic scaling of problem +* data for the specified problem object. +* +* The parameter flags specifies scaling options used by the routine. +* Options can be combined with the bitwise OR operator and may be the +* following: +* +* GLP_SF_GM perform geometric mean scaling; +* GLP_SF_EQ perform equilibration scaling; +* GLP_SF_2N round scale factors to nearest power of two; +* GLP_SF_SKIP skip scaling, if the problem is well scaled. +* +* The parameter flags may be specified as GLP_SF_AUTO, in which case +* the routine chooses scaling options automatically. */ + +void glp_scale_prob(glp_prob *lp, int flags) +{ if (flags & ~(GLP_SF_GM | GLP_SF_EQ | GLP_SF_2N | GLP_SF_SKIP | + GLP_SF_AUTO)) + xerror("glp_scale_prob: flags = 0x%02X; invalid scaling option" + "s\n", flags); + if (flags & GLP_SF_AUTO) + flags = (GLP_SF_GM | GLP_SF_EQ | GLP_SF_SKIP); + scale_prob(lp, flags); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpsdf.c b/resources/3rdparty/glpk-4.57/src/glpsdf.c new file mode 100644 index 000000000..e14bd0662 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpsdf.c @@ -0,0 +1,259 @@ +/* glpsdf.c (plain data file reading routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpsdf.h" +#include "misc.h" + +struct glp_data +{ /* plain data file */ + char *fname; + /* name of data file */ + glp_file *fp; + /* stream assigned to data file */ + void *jump; /* jmp_buf jump; */ + /* label for go to in case of error */ + int count; + /* line count */ + int c; + /* current character of EOF */ + char item[255+1]; + /* current data item */ +}; + +static void next_char(glp_data *data); + +glp_data *glp_sdf_open_file(const char *fname) +{ /* open plain data file */ + glp_data *data = NULL; + glp_file *fp; + jmp_buf jump; + fp = glp_open(fname, "r"); + if (fp == NULL) + { xprintf("Unable to open '%s' - %s\n", fname, get_err_msg()); + goto done; + } + data = xmalloc(sizeof(glp_data)); + data->fname = xmalloc(strlen(fname)+1); + strcpy(data->fname, fname); + data->fp = fp; + data->jump = NULL; + data->count = 0; + data->c = '\n'; + data->item[0] = '\0'; + /* read the very first character */ + if (setjmp(jump)) + { glp_sdf_close_file(data); + data = NULL; + goto done; + } + data->jump = jump; + next_char(data); + data->jump = NULL; +done: return data; +} + +void glp_sdf_set_jump(glp_data *data, void *jump) +{ /* set up error handling */ + data->jump = jump; + return; +} + +void glp_sdf_error(glp_data *data, const char *fmt, ...) +{ /* print error message */ + va_list arg; + xprintf("%s:%d: ", data->fname, data->count); + va_start(arg, fmt); + xvprintf(fmt, arg); + va_end(arg); + if (data->jump == NULL) + xerror(""); + else + longjmp(data->jump, 1); + /* no return */ +} + +void glp_sdf_warning(glp_data *data, const char *fmt, ...) +{ /* print warning message */ + va_list arg; + xprintf("%s:%d: warning: ", data->fname, data->count); + va_start(arg, fmt); + xvprintf(fmt, arg); + va_end(arg); + return; +} + +static void next_char(glp_data *data) +{ /* read next character */ + int c; + if (data->c == EOF) + glp_sdf_error(data, "unexpected end of file\n"); + else if (data->c == '\n') + data->count++; + c = glp_getc(data->fp); + if (c < 0) + { if (glp_ioerr(data->fp)) + glp_sdf_error(data, "read error - %s\n", get_err_msg()); + else if (data->c == '\n') + c = EOF; + else + { glp_sdf_warning(data, "missing final end of line\n"); + c = '\n'; + } + } + else if (c == '\n') + ; + else if (isspace(c)) + c = ' '; + else if (iscntrl(c)) + glp_sdf_error(data, "invalid control character 0x%02X\n", c); + data->c = c; + return; +} + +static void skip_pad(glp_data *data) +{ /* skip uninteresting characters and comments */ +loop: while (data->c == ' ' || data->c == '\n') + next_char(data); + if (data->c == '/') + { next_char(data); + if (data->c != '*') + glp_sdf_error(data, "invalid use of slash\n"); + next_char(data); + for (;;) + { if (data->c == '*') + { next_char(data); + if (data->c == '/') + { next_char(data); + break; + } + } + next_char(data); + } + goto loop; + } + return; +} + +static void next_item(glp_data *data) +{ /* read next item */ + int len; + skip_pad(data); + len = 0; + while (!(data->c == ' ' || data->c == '\n')) + { data->item[len++] = (char)data->c; + if (len == sizeof(data->item)) + glp_sdf_error(data, "data item '%.31s...' too long\n", + data->item); + next_char(data); + } + data->item[len] = '\0'; + return; +} + +int glp_sdf_read_int(glp_data *data) +{ /* read integer number */ + int x; + next_item(data); + switch (str2int(data->item, &x)) + { case 0: + break; + case 1: + glp_sdf_error(data, "integer '%s' out of range\n", + data->item); + case 2: + glp_sdf_error(data, "cannot convert '%s' to integer\n", + data->item); + default: + xassert(data != data); + } + return x; +} + +double glp_sdf_read_num(glp_data *data) +{ /* read floating-point number */ + double x; + next_item(data); + switch (str2num(data->item, &x)) + { case 0: + break; + case 1: + glp_sdf_error(data, "number '%s' out of range\n", + data->item); + case 2: + glp_sdf_error(data, "cannot convert '%s' to number\n", + data->item); + default: + xassert(data != data); + } + return x; +} + +const char *glp_sdf_read_item(glp_data *data) +{ /* read data item */ + next_item(data); + return data->item; +} + +const char *glp_sdf_read_text(glp_data *data) +{ /* read text until end of line */ + int c, len = 0; + for (;;) + { c = data->c; + next_char(data); + if (c == ' ') + { /* ignore initial spaces */ + if (len == 0) continue; + /* and multiple ones */ + if (data->item[len-1] == ' ') continue; + } + else if (c == '\n') + { /* remove trailing space */ + if (len > 0 && data->item[len-1] == ' ') len--; + /* and stop reading */ + break; + } + /* add current character to the buffer */ + data->item[len++] = (char)c; + if (len == sizeof(data->item)) + glp_sdf_error(data, "line too long\n", data->item); + } + data->item[len] = '\0'; + return data->item; +} + +int glp_sdf_line(glp_data *data) +{ /* determine current line number */ + return data->count; +} + +void glp_sdf_close_file(glp_data *data) +{ /* close plain data file */ + glp_close(data->fp); + xfree(data->fname); + xfree(data); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpsdf.h b/resources/3rdparty/glpk-4.57/src/glpsdf.h new file mode 100644 index 000000000..d327a1033 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpsdf.h @@ -0,0 +1,63 @@ +/* glpsdf.h */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef GLPSDF_H +#define GLPSDF_H + +typedef struct glp_data glp_data; +/* plain data file */ + +glp_data *glp_sdf_open_file(const char *fname); +/* open plain data file */ + +void glp_sdf_set_jump(glp_data *data, void *jump); +/* set up error handling */ + +void glp_sdf_error(glp_data *data, const char *fmt, ...); +/* print error message */ + +void glp_sdf_warning(glp_data *data, const char *fmt, ...); +/* print warning message */ + +int glp_sdf_read_int(glp_data *data); +/* read integer number */ + +double glp_sdf_read_num(glp_data *data); +/* read floating-point number */ + +const char *glp_sdf_read_item(glp_data *data); +/* read data item */ + +const char *glp_sdf_read_text(glp_data *data); +/* read text until end of line */ + +int glp_sdf_line(glp_data *data); +/* determine current line number */ + +void glp_sdf_close_file(glp_data *data); +/* close plain data file */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpspm.c b/resources/3rdparty/glpk-4.57/src/glpspm.c new file mode 100644 index 000000000..c6cfd25dd --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpspm.c @@ -0,0 +1,847 @@ +/* glpspm.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "glphbm.h" +#include "glprgr.h" +#include "glpspm.h" +#include "env.h" + +/*********************************************************************** +* NAME +* +* spm_create_mat - create general sparse matrix +* +* SYNOPSIS +* +* #include "glpspm.h" +* SPM *spm_create_mat(int m, int n); +* +* DESCRIPTION +* +* The routine spm_create_mat creates a general sparse matrix having +* m rows and n columns. Being created the matrix is zero (empty), i.e. +* has no elements. +* +* RETURNS +* +* The routine returns a pointer to the matrix created. */ + +SPM *spm_create_mat(int m, int n) +{ SPM *A; + xassert(0 <= m && m < INT_MAX); + xassert(0 <= n && n < INT_MAX); + A = xmalloc(sizeof(SPM)); + A->m = m; + A->n = n; + if (m == 0 || n == 0) + { A->pool = NULL; + A->row = NULL; + A->col = NULL; + } + else + { int i, j; + A->pool = dmp_create_pool(); + A->row = xcalloc(1+m, sizeof(SPME *)); + for (i = 1; i <= m; i++) A->row[i] = NULL; + A->col = xcalloc(1+n, sizeof(SPME *)); + for (j = 1; j <= n; j++) A->col[j] = NULL; + } + return A; +} + +/*********************************************************************** +* NAME +* +* spm_new_elem - add new element to sparse matrix +* +* SYNOPSIS +* +* #include "glpspm.h" +* SPME *spm_new_elem(SPM *A, int i, int j, double val); +* +* DESCRIPTION +* +* The routine spm_new_elem adds a new element to the specified sparse +* matrix. Parameters i, j, and val specify the row number, the column +* number, and a numerical value of the element, respectively. +* +* RETURNS +* +* The routine returns a pointer to the new element added. */ + +SPME *spm_new_elem(SPM *A, int i, int j, double val) +{ SPME *e; + xassert(1 <= i && i <= A->m); + xassert(1 <= j && j <= A->n); + e = dmp_get_atom(A->pool, sizeof(SPME)); + e->i = i; + e->j = j; + e->val = val; + e->r_prev = NULL; + e->r_next = A->row[i]; + if (e->r_next != NULL) e->r_next->r_prev = e; + e->c_prev = NULL; + e->c_next = A->col[j]; + if (e->c_next != NULL) e->c_next->c_prev = e; + A->row[i] = A->col[j] = e; + return e; +} + +/*********************************************************************** +* NAME +* +* spm_delete_mat - delete general sparse matrix +* +* SYNOPSIS +* +* #include "glpspm.h" +* void spm_delete_mat(SPM *A); +* +* DESCRIPTION +* +* The routine deletes the specified general sparse matrix freeing all +* the memory allocated to this object. */ + +void spm_delete_mat(SPM *A) +{ /* delete sparse matrix */ + if (A->pool != NULL) dmp_delete_pool(A->pool); + if (A->row != NULL) xfree(A->row); + if (A->col != NULL) xfree(A->col); + xfree(A); + return; +} + +/*********************************************************************** +* NAME +* +* spm_test_mat_e - create test sparse matrix of E(n,c) class +* +* SYNOPSIS +* +* #include "glpspm.h" +* SPM *spm_test_mat_e(int n, int c); +* +* DESCRIPTION +* +* The routine spm_test_mat_e creates a test sparse matrix of E(n,c) +* class as described in the book: Ole 0sterby, Zahari Zlatev. Direct +* Methods for Sparse Matrices. Springer-Verlag, 1983. +* +* Matrix of E(n,c) class is a symmetric positive definite matrix of +* the order n. It has the number 4 on its main diagonal and the number +* -1 on its four co-diagonals, two of which are neighbour to the main +* diagonal and two others are shifted from the main diagonal on the +* distance c. +* +* It is necessary that n >= 3 and 2 <= c <= n-1. +* +* RETURNS +* +* The routine returns a pointer to the matrix created. */ + +SPM *spm_test_mat_e(int n, int c) +{ SPM *A; + int i; + xassert(n >= 3 && 2 <= c && c <= n-1); + A = spm_create_mat(n, n); + for (i = 1; i <= n; i++) + spm_new_elem(A, i, i, 4.0); + for (i = 1; i <= n-1; i++) + { spm_new_elem(A, i, i+1, -1.0); + spm_new_elem(A, i+1, i, -1.0); + } + for (i = 1; i <= n-c; i++) + { spm_new_elem(A, i, i+c, -1.0); + spm_new_elem(A, i+c, i, -1.0); + } + return A; +} + +/*********************************************************************** +* NAME +* +* spm_test_mat_d - create test sparse matrix of D(n,c) class +* +* SYNOPSIS +* +* #include "glpspm.h" +* SPM *spm_test_mat_d(int n, int c); +* +* DESCRIPTION +* +* The routine spm_test_mat_d creates a test sparse matrix of D(n,c) +* class as described in the book: Ole 0sterby, Zahari Zlatev. Direct +* Methods for Sparse Matrices. Springer-Verlag, 1983. +* +* Matrix of D(n,c) class is a non-singular matrix of the order n. It +* has unity main diagonal, three co-diagonals above the main diagonal +* on the distance c, which are cyclically continued below the main +* diagonal, and a triangle block of the size 10x10 in the upper right +* corner. +* +* It is necessary that n >= 14 and 1 <= c <= n-13. +* +* RETURNS +* +* The routine returns a pointer to the matrix created. */ + +SPM *spm_test_mat_d(int n, int c) +{ SPM *A; + int i, j; + xassert(n >= 14 && 1 <= c && c <= n-13); + A = spm_create_mat(n, n); + for (i = 1; i <= n; i++) + spm_new_elem(A, i, i, 1.0); + for (i = 1; i <= n-c; i++) + spm_new_elem(A, i, i+c, (double)(i+1)); + for (i = n-c+1; i <= n; i++) + spm_new_elem(A, i, i-n+c, (double)(i+1)); + for (i = 1; i <= n-c-1; i++) + spm_new_elem(A, i, i+c+1, (double)(-i)); + for (i = n-c; i <= n; i++) + spm_new_elem(A, i, i-n+c+1, (double)(-i)); + for (i = 1; i <= n-c-2; i++) + spm_new_elem(A, i, i+c+2, 16.0); + for (i = n-c-1; i <= n; i++) + spm_new_elem(A, i, i-n+c+2, 16.0); + for (j = 1; j <= 10; j++) + for (i = 1; i <= 11-j; i++) + spm_new_elem(A, i, n-11+i+j, 100.0 * (double)j); + return A; +} + +/*********************************************************************** +* NAME +* +* spm_show_mat - write sparse matrix pattern in BMP file format +* +* SYNOPSIS +* +* #include "glpspm.h" +* int spm_show_mat(const SPM *A, const char *fname); +* +* DESCRIPTION +* +* The routine spm_show_mat writes pattern of the specified sparse +* matrix in uncompressed BMP file format (Windows bitmap) to a binary +* file whose name is specified by the character string fname. +* +* Each pixel corresponds to one matrix element. The pixel colors have +* the following meaning: +* +* Black structurally zero element +* White positive element +* Cyan negative element +* Green zero element +* Red duplicate element +* +* RETURNS +* +* If no error occured, the routine returns zero. Otherwise, it prints +* an appropriate error message and returns non-zero. */ + +int spm_show_mat(const SPM *A, const char *fname) +{ int m = A->m; + int n = A->n; + int i, j, k, ret; + char *map; + xprintf("spm_show_mat: writing matrix pattern to '%s'...\n", + fname); + xassert(1 <= m && m <= 32767); + xassert(1 <= n && n <= 32767); + map = xmalloc(m * n); + memset(map, 0x08, m * n); + for (i = 1; i <= m; i++) + { SPME *e; + for (e = A->row[i]; e != NULL; e = e->r_next) + { j = e->j; + xassert(1 <= j && j <= n); + k = n * (i - 1) + (j - 1); + if (map[k] != 0x08) + map[k] = 0x0C; + else if (e->val > 0.0) + map[k] = 0x0F; + else if (e->val < 0.0) + map[k] = 0x0B; + else + map[k] = 0x0A; + } + } + ret = rgr_write_bmp16(fname, m, n, map); + xfree(map); + return ret; +} + +/*********************************************************************** +* NAME +* +* spm_read_hbm - read sparse matrix in Harwell-Boeing format +* +* SYNOPSIS +* +* #include "glpspm.h" +* SPM *spm_read_hbm(const char *fname); +* +* DESCRIPTION +* +* The routine spm_read_hbm reads a sparse matrix in the Harwell-Boeing +* format from a text file whose name is the character string fname. +* +* Detailed description of the Harwell-Boeing format recognised by this +* routine can be found in the following report: +* +* I.S.Duff, R.G.Grimes, J.G.Lewis. User's Guide for the Harwell-Boeing +* Sparse Matrix Collection (Release I), TR/PA/92/86, October 1992. +* +* NOTE +* +* The routine spm_read_hbm reads the matrix "as is", due to which zero +* and/or duplicate elements can appear in the matrix. +* +* RETURNS +* +* If no error occured, the routine returns a pointer to the matrix +* created. Otherwise, the routine prints an appropriate error message +* and returns NULL. */ + +SPM *spm_read_hbm(const char *fname) +{ SPM *A = NULL; + HBM *hbm; + int nrow, ncol, nnzero, i, j, beg, end, ptr, *colptr, *rowind; + double val, *values; + char *mxtype; + hbm = hbm_read_mat(fname); + if (hbm == NULL) + { xprintf("spm_read_hbm: unable to read matrix\n"); + goto fini; + } + mxtype = hbm->mxtype; + nrow = hbm->nrow; + ncol = hbm->ncol; + nnzero = hbm->nnzero; + colptr = hbm->colptr; + rowind = hbm->rowind; + values = hbm->values; + if (!(strcmp(mxtype, "RSA") == 0 || strcmp(mxtype, "PSA") == 0 || + strcmp(mxtype, "RUA") == 0 || strcmp(mxtype, "PUA") == 0 || + strcmp(mxtype, "RRA") == 0 || strcmp(mxtype, "PRA") == 0)) + { xprintf("spm_read_hbm: matrix type '%s' not supported\n", + mxtype); + goto fini; + } + A = spm_create_mat(nrow, ncol); + if (mxtype[1] == 'S' || mxtype[1] == 'U') + xassert(nrow == ncol); + for (j = 1; j <= ncol; j++) + { beg = colptr[j]; + end = colptr[j+1]; + xassert(1 <= beg && beg <= end && end <= nnzero + 1); + for (ptr = beg; ptr < end; ptr++) + { i = rowind[ptr]; + xassert(1 <= i && i <= nrow); + if (mxtype[0] == 'R') + val = values[ptr]; + else + val = 1.0; + spm_new_elem(A, i, j, val); + if (mxtype[1] == 'S' && i != j) + spm_new_elem(A, j, i, val); + } + } +fini: if (hbm != NULL) hbm_free_mat(hbm); + return A; +} + +/*********************************************************************** +* NAME +* +* spm_count_nnz - determine number of non-zeros in sparse matrix +* +* SYNOPSIS +* +* #include "glpspm.h" +* int spm_count_nnz(const SPM *A); +* +* RETURNS +* +* The routine spm_count_nnz returns the number of structural non-zero +* elements in the specified sparse matrix. */ + +int spm_count_nnz(const SPM *A) +{ SPME *e; + int i, nnz = 0; + for (i = 1; i <= A->m; i++) + for (e = A->row[i]; e != NULL; e = e->r_next) nnz++; + return nnz; +} + +/*********************************************************************** +* NAME +* +* spm_drop_zeros - remove zero elements from sparse matrix +* +* SYNOPSIS +* +* #include "glpspm.h" +* int spm_drop_zeros(SPM *A, double eps); +* +* DESCRIPTION +* +* The routine spm_drop_zeros removes all elements from the specified +* sparse matrix, whose absolute value is less than eps. +* +* If the parameter eps is 0, only zero elements are removed from the +* matrix. +* +* RETURNS +* +* The routine returns the number of elements removed. */ + +int spm_drop_zeros(SPM *A, double eps) +{ SPME *e, *next; + int i, count = 0; + for (i = 1; i <= A->m; i++) + { for (e = A->row[i]; e != NULL; e = next) + { next = e->r_next; + if (e->val == 0.0 || fabs(e->val) < eps) + { /* remove element from the row list */ + if (e->r_prev == NULL) + A->row[e->i] = e->r_next; + else + e->r_prev->r_next = e->r_next; + if (e->r_next == NULL) + ; + else + e->r_next->r_prev = e->r_prev; + /* remove element from the column list */ + if (e->c_prev == NULL) + A->col[e->j] = e->c_next; + else + e->c_prev->c_next = e->c_next; + if (e->c_next == NULL) + ; + else + e->c_next->c_prev = e->c_prev; + /* return element to the memory pool */ + dmp_free_atom(A->pool, e, sizeof(SPME)); + count++; + } + } + } + return count; +} + +/*********************************************************************** +* NAME +* +* spm_read_mat - read sparse matrix from text file +* +* SYNOPSIS +* +* #include "glpspm.h" +* SPM *spm_read_mat(const char *fname); +* +* DESCRIPTION +* +* The routine reads a sparse matrix from a text file whose name is +* specified by the parameter fname. +* +* For the file format see description of the routine spm_write_mat. +* +* RETURNS +* +* On success the routine returns a pointer to the matrix created, +* otherwise NULL. */ + +#if 1 +SPM *spm_read_mat(const char *fname) +{ xassert(fname != fname); + return NULL; +} +#else +SPM *spm_read_mat(const char *fname) +{ SPM *A = NULL; + PDS *pds; + jmp_buf jump; + int i, j, k, m, n, nnz, fail = 0; + double val; + xprintf("spm_read_mat: reading matrix from '%s'...\n", fname); + pds = pds_open_file(fname); + if (pds == NULL) + { xprintf("spm_read_mat: unable to open '%s' - %s\n", fname, + strerror(errno)); + fail = 1; + goto done; + } + if (setjmp(jump)) + { fail = 1; + goto done; + } + pds_set_jump(pds, jump); + /* number of rows, number of columns, number of non-zeros */ + m = pds_scan_int(pds); + if (m < 0) + pds_error(pds, "invalid number of rows\n"); + n = pds_scan_int(pds); + if (n < 0) + pds_error(pds, "invalid number of columns\n"); + nnz = pds_scan_int(pds); + if (nnz < 0) + pds_error(pds, "invalid number of non-zeros\n"); + /* create matrix */ + xprintf("spm_read_mat: %d rows, %d columns, %d non-zeros\n", + m, n, nnz); + A = spm_create_mat(m, n); + /* read matrix elements */ + for (k = 1; k <= nnz; k++) + { /* row index, column index, element value */ + i = pds_scan_int(pds); + if (!(1 <= i && i <= m)) + pds_error(pds, "row index out of range\n"); + j = pds_scan_int(pds); + if (!(1 <= j && j <= n)) + pds_error(pds, "column index out of range\n"); + val = pds_scan_num(pds); + /* add new element to the matrix */ + spm_new_elem(A, i, j, val); + } + xprintf("spm_read_mat: %d lines were read\n", pds->count); +done: if (pds != NULL) pds_close_file(pds); + if (fail && A != NULL) spm_delete_mat(A), A = NULL; + return A; +} +#endif + +/*********************************************************************** +* NAME +* +* spm_write_mat - write sparse matrix to text file +* +* SYNOPSIS +* +* #include "glpspm.h" +* int spm_write_mat(const SPM *A, const char *fname); +* +* DESCRIPTION +* +* The routine spm_write_mat writes the specified sparse matrix to a +* text file whose name is specified by the parameter fname. This file +* can be read back with the routine spm_read_mat. +* +* RETURNS +* +* On success the routine returns zero, otherwise non-zero. +* +* FILE FORMAT +* +* The file created by the routine spm_write_mat is a plain text file, +* which contains the following information: +* +* m n nnz +* row[1] col[1] val[1] +* row[2] col[2] val[2] +* . . . +* row[nnz] col[nnz] val[nnz] +* +* where: +* m is the number of rows; +* n is the number of columns; +* nnz is the number of non-zeros; +* row[k], k = 1,...,nnz, are row indices; +* col[k], k = 1,...,nnz, are column indices; +* val[k], k = 1,...,nnz, are element values. */ + +#if 1 +int spm_write_mat(const SPM *A, const char *fname) +{ xassert(A != A); + xassert(fname != fname); + return 0; +} +#else +int spm_write_mat(const SPM *A, const char *fname) +{ FILE *fp; + int i, nnz, ret = 0; + xprintf("spm_write_mat: writing matrix to '%s'...\n", fname); + fp = fopen(fname, "w"); + if (fp == NULL) + { xprintf("spm_write_mat: unable to create '%s' - %s\n", fname, + strerror(errno)); + ret = 1; + goto done; + } + /* number of rows, number of columns, number of non-zeros */ + nnz = spm_count_nnz(A); + fprintf(fp, "%d %d %d\n", A->m, A->n, nnz); + /* walk through rows of the matrix */ + for (i = 1; i <= A->m; i++) + { SPME *e; + /* walk through elements of i-th row */ + for (e = A->row[i]; e != NULL; e = e->r_next) + { /* row index, column index, element value */ + fprintf(fp, "%d %d %.*g\n", e->i, e->j, DBL_DIG, e->val); + } + } + fflush(fp); + if (ferror(fp)) + { xprintf("spm_write_mat: writing error on '%s' - %s\n", fname, + strerror(errno)); + ret = 1; + goto done; + } + xprintf("spm_write_mat: %d lines were written\n", 1 + nnz); +done: if (fp != NULL) fclose(fp); + return ret; +} +#endif + +/*********************************************************************** +* NAME +* +* spm_transpose - transpose sparse matrix +* +* SYNOPSIS +* +* #include "glpspm.h" +* SPM *spm_transpose(const SPM *A); +* +* RETURNS +* +* The routine computes and returns sparse matrix B, which is a matrix +* transposed to sparse matrix A. */ + +SPM *spm_transpose(const SPM *A) +{ SPM *B; + int i; + B = spm_create_mat(A->n, A->m); + for (i = 1; i <= A->m; i++) + { SPME *e; + for (e = A->row[i]; e != NULL; e = e->r_next) + spm_new_elem(B, e->j, i, e->val); + } + return B; +} + +SPM *spm_add_sym(const SPM *A, const SPM *B) +{ /* add two sparse matrices (symbolic phase) */ + SPM *C; + int i, j, *flag; + xassert(A->m == B->m); + xassert(A->n == B->n); + /* create resultant matrix */ + C = spm_create_mat(A->m, A->n); + /* allocate and clear the flag array */ + flag = xcalloc(1+C->n, sizeof(int)); + for (j = 1; j <= C->n; j++) + flag[j] = 0; + /* compute pattern of C = A + B */ + for (i = 1; i <= C->m; i++) + { SPME *e; + /* at the beginning i-th row of C is empty */ + /* (i-th row of C) := (i-th row of C) union (i-th row of A) */ + for (e = A->row[i]; e != NULL; e = e->r_next) + { /* (note that i-th row of A may have duplicate elements) */ + j = e->j; + if (!flag[j]) + { spm_new_elem(C, i, j, 0.0); + flag[j] = 1; + } + } + /* (i-th row of C) := (i-th row of C) union (i-th row of B) */ + for (e = B->row[i]; e != NULL; e = e->r_next) + { /* (note that i-th row of B may have duplicate elements) */ + j = e->j; + if (!flag[j]) + { spm_new_elem(C, i, j, 0.0); + flag[j] = 1; + } + } + /* reset the flag array */ + for (e = C->row[i]; e != NULL; e = e->r_next) + flag[e->j] = 0; + } + /* check and deallocate the flag array */ + for (j = 1; j <= C->n; j++) + xassert(!flag[j]); + xfree(flag); + return C; +} + +void spm_add_num(SPM *C, double alfa, const SPM *A, double beta, + const SPM *B) +{ /* add two sparse matrices (numeric phase) */ + int i, j; + double *work; + /* allocate and clear the working array */ + work = xcalloc(1+C->n, sizeof(double)); + for (j = 1; j <= C->n; j++) + work[j] = 0.0; + /* compute matrix C = alfa * A + beta * B */ + for (i = 1; i <= C->n; i++) + { SPME *e; + /* work := alfa * (i-th row of A) + beta * (i-th row of B) */ + /* (note that A and/or B may have duplicate elements) */ + for (e = A->row[i]; e != NULL; e = e->r_next) + work[e->j] += alfa * e->val; + for (e = B->row[i]; e != NULL; e = e->r_next) + work[e->j] += beta * e->val; + /* (i-th row of C) := work, work := 0 */ + for (e = C->row[i]; e != NULL; e = e->r_next) + { j = e->j; + e->val = work[j]; + work[j] = 0.0; + } + } + /* check and deallocate the working array */ + for (j = 1; j <= C->n; j++) + xassert(work[j] == 0.0); + xfree(work); + return; +} + +SPM *spm_add_mat(double alfa, const SPM *A, double beta, const SPM *B) +{ /* add two sparse matrices (driver routine) */ + SPM *C; + C = spm_add_sym(A, B); + spm_add_num(C, alfa, A, beta, B); + return C; +} + +SPM *spm_mul_sym(const SPM *A, const SPM *B) +{ /* multiply two sparse matrices (symbolic phase) */ + int i, j, k, *flag; + SPM *C; + xassert(A->n == B->m); + /* create resultant matrix */ + C = spm_create_mat(A->m, B->n); + /* allocate and clear the flag array */ + flag = xcalloc(1+C->n, sizeof(int)); + for (j = 1; j <= C->n; j++) + flag[j] = 0; + /* compute pattern of C = A * B */ + for (i = 1; i <= C->m; i++) + { SPME *e, *ee; + /* compute pattern of i-th row of C */ + for (e = A->row[i]; e != NULL; e = e->r_next) + { k = e->j; + for (ee = B->row[k]; ee != NULL; ee = ee->r_next) + { j = ee->j; + /* if a[i,k] != 0 and b[k,j] != 0 then c[i,j] != 0 */ + if (!flag[j]) + { /* c[i,j] does not exist, so create it */ + spm_new_elem(C, i, j, 0.0); + flag[j] = 1; + } + } + } + /* reset the flag array */ + for (e = C->row[i]; e != NULL; e = e->r_next) + flag[e->j] = 0; + } + /* check and deallocate the flag array */ + for (j = 1; j <= C->n; j++) + xassert(!flag[j]); + xfree(flag); + return C; +} + +void spm_mul_num(SPM *C, const SPM *A, const SPM *B) +{ /* multiply two sparse matrices (numeric phase) */ + int i, j; + double *work; + /* allocate and clear the working array */ + work = xcalloc(1+A->n, sizeof(double)); + for (j = 1; j <= A->n; j++) + work[j] = 0.0; + /* compute matrix C = A * B */ + for (i = 1; i <= C->m; i++) + { SPME *e, *ee; + double temp; + /* work := (i-th row of A) */ + /* (note that A may have duplicate elements) */ + for (e = A->row[i]; e != NULL; e = e->r_next) + work[e->j] += e->val; + /* compute i-th row of C */ + for (e = C->row[i]; e != NULL; e = e->r_next) + { j = e->j; + /* c[i,j] := work * (j-th column of B) */ + temp = 0.0; + for (ee = B->col[j]; ee != NULL; ee = ee->c_next) + temp += work[ee->i] * ee->val; + e->val = temp; + } + /* reset the working array */ + for (e = A->row[i]; e != NULL; e = e->r_next) + work[e->j] = 0.0; + } + /* check and deallocate the working array */ + for (j = 1; j <= A->n; j++) + xassert(work[j] == 0.0); + xfree(work); + return; +} + +SPM *spm_mul_mat(const SPM *A, const SPM *B) +{ /* multiply two sparse matrices (driver routine) */ + SPM *C; + C = spm_mul_sym(A, B); + spm_mul_num(C, A, B); + return C; +} + +PER *spm_create_per(int n) +{ /* create permutation matrix */ + PER *P; + int k; + xassert(n >= 0); + P = xmalloc(sizeof(PER)); + P->n = n; + P->row = xcalloc(1+n, sizeof(int)); + P->col = xcalloc(1+n, sizeof(int)); + /* initially it is identity matrix */ + for (k = 1; k <= n; k++) + P->row[k] = P->col[k] = k; + return P; +} + +void spm_check_per(PER *P) +{ /* check permutation matrix for correctness */ + int i, j; + xassert(P->n >= 0); + for (i = 1; i <= P->n; i++) + { j = P->row[i]; + xassert(1 <= j && j <= P->n); + xassert(P->col[j] == i); + } + return; +} + +void spm_delete_per(PER *P) +{ /* delete permutation matrix */ + xfree(P->row); + xfree(P->col); + xfree(P); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpspm.h b/resources/3rdparty/glpk-4.57/src/glpspm.h new file mode 100644 index 000000000..eda9f98f2 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpspm.h @@ -0,0 +1,165 @@ +/* glpspm.h (general sparse matrix) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef GLPSPM_H +#define GLPSPM_H + +#include "dmp.h" + +typedef struct SPM SPM; +typedef struct SPME SPME; + +struct SPM +{ /* general sparse matrix */ + int m; + /* number of rows, m >= 0 */ + int n; + /* number of columns, n >= 0 */ + DMP *pool; + /* memory pool to store matrix elements */ + SPME **row; /* SPME *row[1+m]; */ + /* row[i], 1 <= i <= m, is a pointer to i-th row list */ + SPME **col; /* SPME *col[1+n]; */ + /* col[j], 1 <= j <= n, is a pointer to j-th column list */ +}; + +struct SPME +{ /* sparse matrix element */ + int i; + /* row number */ + int j; + /* column number */ + double val; + /* element value */ + SPME *r_prev; + /* pointer to previous element in the same row */ + SPME *r_next; + /* pointer to next element in the same row */ + SPME *c_prev; + /* pointer to previous element in the same column */ + SPME *c_next; + /* pointer to next element in the same column */ +}; + +typedef struct PER PER; + +struct PER +{ /* permutation matrix */ + int n; + /* matrix order, n >= 0 */ + int *row; /* int row[1+n]; */ + /* row[i] = j means p[i,j] = 1 */ + int *col; /* int col[1+n]; */ + /* col[j] = i means p[i,j] = 1 */ +}; + +#define spm_create_mat _glp_spm_create_mat +SPM *spm_create_mat(int m, int n); +/* create general sparse matrix */ + +#define spm_new_elem _glp_spm_new_elem +SPME *spm_new_elem(SPM *A, int i, int j, double val); +/* add new element to sparse matrix */ + +#define spm_delete_mat _glp_spm_delete_mat +void spm_delete_mat(SPM *A); +/* delete general sparse matrix */ + +#define spm_test_mat_e _glp_spm_test_mat_e +SPM *spm_test_mat_e(int n, int c); +/* create test sparse matrix of E(n,c) class */ + +#define spm_test_mat_d _glp_spm_test_mat_d +SPM *spm_test_mat_d(int n, int c); +/* create test sparse matrix of D(n,c) class */ + +#define spm_show_mat _glp_spm_show_mat +int spm_show_mat(const SPM *A, const char *fname); +/* write sparse matrix pattern in BMP file format */ + +#define spm_read_hbm _glp_spm_read_hbm +SPM *spm_read_hbm(const char *fname); +/* read sparse matrix in Harwell-Boeing format */ + +#define spm_count_nnz _glp_spm_count_nnz +int spm_count_nnz(const SPM *A); +/* determine number of non-zeros in sparse matrix */ + +#define spm_drop_zeros _glp_spm_drop_zeros +int spm_drop_zeros(SPM *A, double eps); +/* remove zero elements from sparse matrix */ + +#define spm_read_mat _glp_spm_read_mat +SPM *spm_read_mat(const char *fname); +/* read sparse matrix from text file */ + +#define spm_write_mat _glp_spm_write_mat +int spm_write_mat(const SPM *A, const char *fname); +/* write sparse matrix to text file */ + +#define spm_transpose _glp_spm_transpose +SPM *spm_transpose(const SPM *A); +/* transpose sparse matrix */ + +#define spm_add_sym _glp_spm_add_sym +SPM *spm_add_sym(const SPM *A, const SPM *B); +/* add two sparse matrices (symbolic phase) */ + +#define spm_add_num _glp_spm_add_num +void spm_add_num(SPM *C, double alfa, const SPM *A, double beta, + const SPM *B); +/* add two sparse matrices (numeric phase) */ + +#define spm_add_mat _glp_spm_add_mat +SPM *spm_add_mat(double alfa, const SPM *A, double beta, + const SPM *B); +/* add two sparse matrices (driver routine) */ + +#define spm_mul_sym _glp_spm_mul_sym +SPM *spm_mul_sym(const SPM *A, const SPM *B); +/* multiply two sparse matrices (symbolic phase) */ + +#define spm_mul_num _glp_spm_mul_num +void spm_mul_num(SPM *C, const SPM *A, const SPM *B); +/* multiply two sparse matrices (numeric phase) */ + +#define spm_mul_mat _glp_spm_mul_mat +SPM *spm_mul_mat(const SPM *A, const SPM *B); +/* multiply two sparse matrices (driver routine) */ + +#define spm_create_per _glp_spm_create_per +PER *spm_create_per(int n); +/* create permutation matrix */ + +#define spm_check_per _glp_spm_check_per +void spm_check_per(PER *P); +/* check permutation matrix for correctness */ + +#define spm_delete_per _glp_spm_delete_per +void spm_delete_per(PER *P); +/* delete permutation matrix */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpsql.c b/resources/3rdparty/glpk-4.57/src/glpsql.c new file mode 100644 index 000000000..9c664dbc5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpsql.c @@ -0,0 +1,1641 @@ +/* glpsql.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Author: Heinrich Schuchardt . +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "glpmpl.h" +#include "glpsql.h" + +#ifdef ODBC_DLNAME +#define HAVE_ODBC +#define libodbc ODBC_DLNAME +#define h_odbc (get_env_ptr()->h_odbc) +#endif + +#ifdef MYSQL_DLNAME +#define HAVE_MYSQL +#define libmysql MYSQL_DLNAME +#define h_mysql (get_env_ptr()->h_mysql) +#endif + +static void *db_iodbc_open_int(TABDCA *dca, int mode, const char + **sqllines); +static void *db_mysql_open_int(TABDCA *dca, int mode, const char + **sqllines); + +/**********************************************************************/ + +#if defined(HAVE_ODBC) || defined(HAVE_MYSQL) + +#define SQL_FIELD_MAX 100 +/* maximal field count */ + +#define SQL_FDLEN_MAX 255 +/* maximal field length */ + +/*********************************************************************** +* NAME +* +* args_concat - concatenate arguments +* +* SYNOPSIS +* +* static char **args_concat(TABDCA *dca); +* +* DESCRIPTION +* +* The arguments passed in dca are SQL statements. A SQL statement may +* be split over multiple arguments. The last argument of a SQL +* statement will be terminated with a semilocon. Each SQL statement is +* merged into a single zero terminated string. Boundaries between +* arguments are replaced by space. +* +* RETURNS +* +* Buffer with SQL statements */ + +static char **args_concat(TABDCA *dca) +{ + const char *arg; + int i; + int j; + int j0; + int j1; + size_t len; + int lentot; + int narg; + int nline = 0; + char **sqllines = NULL; + + narg = mpl_tab_num_args(dca); + /* The SQL statements start with argument 3. */ + if (narg < 3) + return NULL; + /* Count the SQL statements */ + for (j = 3; j <= narg; j++) + { + arg = mpl_tab_get_arg(dca, j); + len = strlen(arg); + if (arg[len-1] == ';' || j == narg) + nline ++; + } + /* Allocate string buffer. */ + sqllines = (char **) xmalloc((nline+1) * sizeof(char **)); + /* Join arguments */ + sqllines[0] = NULL; + j0 = 3; + i = 0; + lentot = 0; + for (j = 3; j <= narg; j++) + { + arg = mpl_tab_get_arg(dca, j); + len = strlen(arg); + /* add length of part */ + lentot += len; + /* add length of space separating parts or 0x00 at end of SQL + statement */ + lentot++; + if (arg[len-1] == ';' || j == narg) + { /* Join arguments for a single SQL statement */ + sqllines[i] = xmalloc(lentot); + sqllines[i+1] = NULL; + sqllines[i][0] = 0x00; + for (j1 = j0; j1 <= j; j1++) + { if(j1>j0) + strcat(sqllines[i], " "); + strcat(sqllines[i], mpl_tab_get_arg(dca, j1)); + } + len = strlen(sqllines[i]); + if (sqllines[i][len-1] == ';') + sqllines[i][len-1] = 0x00; + j0 = j+1; + i++; + lentot = 0; + } + } + return sqllines; +} + +/*********************************************************************** +* NAME +* +* free_buffer - free multiline string buffer +* +* SYNOPSIS +* +* static void free_buffer(char **buf); +* +* DESCRIPTION +* +* buf is a list of strings terminated by NULL. +* The memory for the strings and for the list is released. */ + +static void free_buffer(char **buf) +{ int i; + + for(i = 0; buf[i] != NULL; i++) + xfree(buf[i]); + xfree(buf); +} + +static int db_escaped_string_length(const char* from) +/* length of escaped string */ +{ + int count; + const char *pointer; + + for (pointer = from, count = 0; *pointer != (char) '\0'; pointer++, + count++) + { + switch (*pointer) + { + case '\'': + count++; + break; + } + } + + return count; +} + +static void db_escape_string (char *to, const char *from) +/* escape string*/ +{ + const char *source = from; + char *target = to; + size_t remaining; + + remaining = strlen(from); + + if (to == NULL) + to = (char *) (from + remaining); + + while (remaining > 0) + { + switch (*source) + { + case '\'': + *target = '\''; + target++; + *target = '\''; + break; + + default: + *target = *source; + } + source++; + target++; + remaining--; + } + + /* Write the terminating NUL character. */ + *target = '\0'; +} + +static char *db_generate_select_stmt(TABDCA *dca) +/* generate select statement */ +{ + char *arg; + char const *field; + char *query; + int j; + int narg; + int nf; + int total; + + total = 50; + nf = mpl_tab_num_flds(dca); + narg = mpl_tab_num_args(dca); + for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) + { + field = mpl_tab_get_name(dca, j); + total += strlen(field); + total += 2; + } + arg = (char *) mpl_tab_get_arg(dca, narg); + total += strlen(arg); + query = xmalloc( total * sizeof(char)); + strcpy (query, "SELECT "); + for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) + { + field = mpl_tab_get_name(dca, j); + strcat(query, field); + if ( j < nf ) + strcat(query, ", "); + } + strcat(query, " FROM "); + strcat(query, arg); + return query; +} + +static char *db_generate_insert_stmt(TABDCA *dca) +/* generate insert statement */ +{ + char *arg; + char const *field; + char *query; + int j; + int narg; + int nf; + int total; + + total = 50; + nf = mpl_tab_num_flds(dca); + narg = mpl_tab_num_args(dca); + for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) + { + field = mpl_tab_get_name(dca, j); + total += strlen(field); + total += 5; + } + arg = (char *) mpl_tab_get_arg(dca, narg); + total += strlen(arg); + query = xmalloc( (total+1) * sizeof(char)); + strcpy (query, "INSERT INTO "); + strcat(query, arg); + strcat(query, " ( "); + for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) + { + field = mpl_tab_get_name(dca, j); + strcat(query, field); + if ( j < nf ) + strcat(query, ", "); + } + strcat(query, " ) VALUES ( "); + for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) + { + strcat(query, "?"); + if ( j < nf ) + strcat(query, ", "); + } + strcat(query, " )"); + return query; +} + +#endif + +/**********************************************************************/ + +#ifndef HAVE_ODBC + +void *db_iodbc_open(TABDCA *dca, int mode) +{ xassert(dca == dca); + xassert(mode == mode); + xprintf("iODBC table driver not supported\n"); + return NULL; +} + +int db_iodbc_read(TABDCA *dca, void *link) +{ xassert(dca != dca); + xassert(link != link); + return 0; +} + +int db_iodbc_write(TABDCA *dca, void *link) +{ xassert(dca != dca); + xassert(link != link); + return 0; +} + +int db_iodbc_close(TABDCA *dca, void *link) +{ xassert(dca != dca); + xassert(link != link); + return 0; +} + +#else + +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WOE__) +#include +#endif + +#include +#include + +struct db_odbc +{ + int mode; /*'R' = Read, 'W' = Write*/ + SQLHDBC hdbc; /*connection handle*/ + SQLHENV henv; /*environment handle*/ + SQLHSTMT hstmt; /*statement handle*/ + SQLSMALLINT nresultcols; /* columns in result*/ + SQLULEN collen[SQL_FIELD_MAX+1]; + SQLLEN outlen[SQL_FIELD_MAX+1]; + SQLSMALLINT coltype[SQL_FIELD_MAX+1]; + SQLCHAR data[SQL_FIELD_MAX+1][SQL_FDLEN_MAX+1]; +#if 1 /* 12/I-2014 */ + SQLDOUBLE datanum[SQL_FIELD_MAX+1]; +#endif + SQLCHAR colname[SQL_FIELD_MAX+1][SQL_FDLEN_MAX+1]; + int isnumeric[SQL_FIELD_MAX+1]; + int nf; + /* number of fields in the csv file */ + int ref[1+SQL_FIELD_MAX]; + /* ref[k] = k', if k-th field of the csv file corresponds to + k'-th field in the table statement; if ref[k] = 0, k-th field + of the csv file is ignored */ + SQLCHAR *query; + /* query generated by db_iodbc_open */ +}; + +SQLRETURN SQL_API dl_SQLAllocHandle ( + SQLSMALLINT HandleType, + SQLHANDLE InputHandle, + SQLHANDLE *OutputHandle) +{ + typedef SQLRETURN SQL_API ep_SQLAllocHandle( + SQLSMALLINT HandleType, + SQLHANDLE InputHandle, + SQLHANDLE *OutputHandle); + + ep_SQLAllocHandle *fn; + fn = (ep_SQLAllocHandle *) xdlsym(h_odbc, "SQLAllocHandle"); + xassert(fn != NULL); + return (*fn)(HandleType, InputHandle, OutputHandle); +} + +SQLRETURN SQL_API dl_SQLBindCol ( + SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLSMALLINT TargetType, + SQLPOINTER TargetValue, + SQLLEN BufferLength, + SQLLEN *StrLen_or_Ind) +{ + typedef SQLRETURN SQL_API ep_SQLBindCol( + SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLSMALLINT TargetType, + SQLPOINTER TargetValue, + SQLLEN BufferLength, + SQLLEN *StrLen_or_Ind); + ep_SQLBindCol *fn; + fn = (ep_SQLBindCol *) xdlsym(h_odbc, "SQLBindCol"); + xassert(fn != NULL); + return (*fn)(StatementHandle, ColumnNumber, TargetType, + TargetValue, BufferLength, StrLen_or_Ind); +} + +SQLRETURN SQL_API dl_SQLCloseCursor ( + SQLHSTMT StatementHandle) +{ + typedef SQLRETURN SQL_API ep_SQLCloseCursor ( + SQLHSTMT StatementHandle); + + ep_SQLCloseCursor *fn; + fn = (ep_SQLCloseCursor *) xdlsym(h_odbc, "SQLCloseCursor"); + xassert(fn != NULL); + return (*fn)(StatementHandle); +} + + +SQLRETURN SQL_API dl_SQLDisconnect ( + SQLHDBC ConnectionHandle) +{ + typedef SQLRETURN SQL_API ep_SQLDisconnect( + SQLHDBC ConnectionHandle); + + ep_SQLDisconnect *fn; + fn = (ep_SQLDisconnect *) xdlsym(h_odbc, "SQLDisconnect"); + xassert(fn != NULL); + return (*fn)(ConnectionHandle); +} + +SQLRETURN SQL_API dl_SQLDriverConnect ( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut, + SQLUSMALLINT fDriverCompletion) +{ + typedef SQLRETURN SQL_API ep_SQLDriverConnect( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLCHAR * szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR * szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT * pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); + + ep_SQLDriverConnect *fn; + fn = (ep_SQLDriverConnect *) xdlsym(h_odbc, "SQLDriverConnect"); + xassert(fn != NULL); + return (*fn)(hdbc, hwnd, szConnStrIn, cbConnStrIn, szConnStrOut, + cbConnStrOutMax, pcbConnStrOut, fDriverCompletion); +} + +SQLRETURN SQL_API dl_SQLEndTran ( + SQLSMALLINT HandleType, + SQLHANDLE Handle, + SQLSMALLINT CompletionType) +{ + typedef SQLRETURN SQL_API ep_SQLEndTran ( + SQLSMALLINT HandleType, + SQLHANDLE Handle, + SQLSMALLINT CompletionType); + + ep_SQLEndTran *fn; + fn = (ep_SQLEndTran *) xdlsym(h_odbc, "SQLEndTran"); + xassert(fn != NULL); + return (*fn)(HandleType, Handle, CompletionType); +} + +SQLRETURN SQL_API dl_SQLExecDirect ( + SQLHSTMT StatementHandle, + SQLCHAR * StatementText, + SQLINTEGER TextLength) +{ + typedef SQLRETURN SQL_API ep_SQLExecDirect ( + SQLHSTMT StatementHandle, + SQLCHAR * StatementText, + SQLINTEGER TextLength); + + ep_SQLExecDirect *fn; + fn = (ep_SQLExecDirect *) xdlsym(h_odbc, "SQLExecDirect"); + xassert(fn != NULL); + return (*fn)(StatementHandle, StatementText, TextLength); +} + +SQLRETURN SQL_API dl_SQLFetch ( + SQLHSTMT StatementHandle) +{ + typedef SQLRETURN SQL_API ep_SQLFetch ( + SQLHSTMT StatementHandle); + + ep_SQLFetch *fn; + fn = (ep_SQLFetch*) xdlsym(h_odbc, "SQLFetch"); + xassert(fn != NULL); + return (*fn)(StatementHandle); +} + +SQLRETURN SQL_API dl_SQLFreeHandle ( + SQLSMALLINT HandleType, + SQLHANDLE Handle) +{ + typedef SQLRETURN SQL_API ep_SQLFreeHandle ( + SQLSMALLINT HandleType, + SQLHANDLE Handle); + + ep_SQLFreeHandle *fn; + fn = (ep_SQLFreeHandle *) xdlsym(h_odbc, "SQLFreeHandle"); + xassert(fn != NULL); + return (*fn)(HandleType, Handle); +} + +SQLRETURN SQL_API dl_SQLDescribeCol ( + SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLCHAR * ColumnName, + SQLSMALLINT BufferLength, + SQLSMALLINT * NameLength, + SQLSMALLINT * DataType, + SQLULEN * ColumnSize, + SQLSMALLINT * DecimalDigits, + SQLSMALLINT * Nullable) +{ + typedef SQLRETURN SQL_API ep_SQLDescribeCol ( + SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLCHAR *ColumnName, + SQLSMALLINT BufferLength, + SQLSMALLINT *NameLength, + SQLSMALLINT *DataType, + SQLULEN *ColumnSize, + SQLSMALLINT *DecimalDigits, + SQLSMALLINT *Nullable); + + ep_SQLDescribeCol *fn; + fn = (ep_SQLDescribeCol *) xdlsym(h_odbc, "SQLDescribeCol"); + xassert(fn != NULL); + return (*fn)(StatementHandle, ColumnNumber, ColumnName, + BufferLength, NameLength, + DataType, ColumnSize, DecimalDigits, Nullable); +} + +SQLRETURN SQL_API dl_SQLGetDiagRec ( + SQLSMALLINT HandleType, + SQLHANDLE Handle, + SQLSMALLINT RecNumber, + SQLCHAR *Sqlstate, + SQLINTEGER *NativeError, + SQLCHAR *MessageText, + SQLSMALLINT BufferLength, + SQLSMALLINT *TextLength) +{ + typedef SQLRETURN SQL_API ep_SQLGetDiagRec ( + SQLSMALLINT HandleType, + SQLHANDLE Handle, + SQLSMALLINT RecNumber, + SQLCHAR *Sqlstate, + SQLINTEGER *NativeError, + SQLCHAR *MessageText, + SQLSMALLINT BufferLength, + SQLSMALLINT *TextLength); + + ep_SQLGetDiagRec *fn; + fn = (ep_SQLGetDiagRec *) xdlsym(h_odbc, "SQLGetDiagRec"); + xassert(fn != NULL); + return (*fn)(HandleType, Handle, RecNumber, Sqlstate, + NativeError, MessageText, BufferLength, TextLength); +} + +SQLRETURN SQL_API dl_SQLGetInfo ( + SQLHDBC ConnectionHandle, + SQLUSMALLINT InfoType, + SQLPOINTER InfoValue, + SQLSMALLINT BufferLength, + SQLSMALLINT *StringLength) +{ + typedef SQLRETURN SQL_API ep_SQLGetInfo ( + SQLHDBC ConnectionHandle, + SQLUSMALLINT InfoType, + SQLPOINTER InfoValue, + SQLSMALLINT BufferLength, + SQLSMALLINT *StringLength); + + ep_SQLGetInfo *fn; + fn = (ep_SQLGetInfo *) xdlsym(h_odbc, "SQLGetInfo"); + xassert(fn != NULL); + return (*fn)(ConnectionHandle, InfoType, InfoValue, BufferLength, + StringLength); +} + +SQLRETURN SQL_API dl_SQLNumResultCols ( + SQLHSTMT StatementHandle, + SQLSMALLINT *ColumnCount) +{ + typedef SQLRETURN SQL_API ep_SQLNumResultCols ( + SQLHSTMT StatementHandle, + SQLSMALLINT *ColumnCount); + + ep_SQLNumResultCols *fn; + fn = (ep_SQLNumResultCols *) xdlsym(h_odbc, "SQLNumResultCols"); + xassert(fn != NULL); + return (*fn)(StatementHandle, ColumnCount); +} + +SQLRETURN SQL_API dl_SQLSetConnectAttr ( + SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER StringLength) +{ + typedef SQLRETURN SQL_API ep_SQLSetConnectAttr ( + SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER StringLength); + + ep_SQLSetConnectAttr *fn; + fn = (ep_SQLSetConnectAttr *) xdlsym(h_odbc, "SQLSetConnectAttr"); + xassert(fn != NULL); + return (*fn)(ConnectionHandle, Attribute, Value, StringLength); +} + +SQLRETURN SQL_API dl_SQLSetEnvAttr ( + SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER StringLength) +{ + typedef SQLRETURN SQL_API ep_SQLSetEnvAttr ( + SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER StringLength); + + ep_SQLSetEnvAttr *fn; + fn = (ep_SQLSetEnvAttr *) xdlsym(h_odbc, "SQLSetEnvAttr"); + xassert(fn != NULL); + return (*fn)(EnvironmentHandle, Attribute, Value, StringLength); +} + +static void extract_error( + char *fn, + SQLHANDLE handle, + SQLSMALLINT type); + +static int is_numeric( + SQLSMALLINT coltype); + +/*********************************************************************** +* NAME +* +* db_iodbc_open - open connection to ODBC data base +* +* SYNOPSIS +* +* #include "glpsql.h" +* void *db_iodbc_open(TABDCA *dca, int mode); +* +* DESCRIPTION +* +* The routine db_iodbc_open opens a connection to an ODBC data base. +* It then executes the sql statements passed. +* +* In the case of table read the SELECT statement is executed. +* +* In the case of table write the INSERT statement is prepared. +* RETURNS +* +* The routine returns a pointer to data storage area created. */ +void *db_iodbc_open(TABDCA *dca, int mode) +{ void *ret; + char **sqllines; + + sqllines = args_concat(dca); + if (sqllines == NULL) + { xprintf("Missing arguments in table statement.\n" + "Please, supply table driver, dsn, and query.\n"); + return NULL; + } + ret = db_iodbc_open_int(dca, mode, (const char **) sqllines); + free_buffer(sqllines); + return ret; +} + +static void *db_iodbc_open_int(TABDCA *dca, int mode, const char + **sqllines) +{ + struct db_odbc *sql; + SQLRETURN ret; + SQLCHAR FAR *dsn; + SQLCHAR info[256]; + SQLSMALLINT colnamelen; + SQLSMALLINT nullable; + SQLSMALLINT scale; + const char *arg; + int narg; + int i, j; + int total; + + if (libodbc == NULL) + { + xprintf("No loader for shared ODBC library available\n"); + return NULL; + } + + if (h_odbc == NULL) + { + h_odbc = xdlopen(libodbc); + if (h_odbc == NULL) + { xprintf("unable to open library %s\n", libodbc); + xprintf("%s\n", get_err_msg()); + return NULL; + } + } + + sql = (struct db_odbc *) xmalloc(sizeof(struct db_odbc)); + if (sql == NULL) + return NULL; + + sql->mode = mode; + sql->hdbc = NULL; + sql->henv = NULL; + sql->hstmt = NULL; + sql->query = NULL; + narg = mpl_tab_num_args(dca); + + dsn = (SQLCHAR FAR *) mpl_tab_get_arg(dca, 2); + /* allocate an environment handle */ + ret = dl_SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, + &(sql->henv)); + /* set attribute to enable application to run as ODBC 3.0 + application */ + ret = dl_SQLSetEnvAttr(sql->henv, SQL_ATTR_ODBC_VERSION, + (void *) SQL_OV_ODBC3, 0); + /* allocate a connection handle */ + ret = dl_SQLAllocHandle(SQL_HANDLE_DBC, sql->henv, &(sql->hdbc)); + /* connect */ + ret = dl_SQLDriverConnect(sql->hdbc, NULL, dsn, SQL_NTS, NULL, 0, + NULL, SQL_DRIVER_COMPLETE); + if (SQL_SUCCEEDED(ret)) + { /* output information about data base connection */ + xprintf("Connected to "); + dl_SQLGetInfo(sql->hdbc, SQL_DBMS_NAME, (SQLPOINTER)info, + sizeof(info), NULL); + xprintf("%s ", info); + dl_SQLGetInfo(sql->hdbc, SQL_DBMS_VER, (SQLPOINTER)info, + sizeof(info), NULL); + xprintf("%s - ", info); + dl_SQLGetInfo(sql->hdbc, SQL_DATABASE_NAME, (SQLPOINTER)info, + sizeof(info), NULL); + xprintf("%s\n", info); + } + else + { /* describe error */ + xprintf("Failed to connect\n"); + extract_error("SQLDriverConnect", sql->hdbc, SQL_HANDLE_DBC); + dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); + dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); + xfree(sql); + return NULL; + } + /* set AUTOCOMMIT on*/ + ret = dl_SQLSetConnectAttr(sql->hdbc, SQL_ATTR_AUTOCOMMIT, + (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0); + /* allocate a statement handle */ + ret = dl_SQLAllocHandle(SQL_HANDLE_STMT, sql->hdbc, &(sql->hstmt)); + + /* initialization queries */ + for(j = 0; sqllines[j+1] != NULL; j++) + { + sql->query = (SQLCHAR *) sqllines[j]; + xprintf("%s\n", sql->query); + ret = dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS); + switch (ret) + { + case SQL_SUCCESS: + case SQL_SUCCESS_WITH_INFO: + case SQL_NO_DATA_FOUND: + break; + default: + xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n", + sql->query); + extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT); + dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); + dl_SQLDisconnect(sql->hdbc); + dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); + dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); + xfree(sql); + return NULL; + } + /* commit statement */ + dl_SQLEndTran(SQL_HANDLE_ENV, sql->henv, SQL_COMMIT); + } + + if ( sql->mode == 'R' ) + { sql->nf = mpl_tab_num_flds(dca); + for(j = 0; sqllines[j] != NULL; j++) + arg = sqllines[j]; + total = strlen(arg); + if (total > 7 && 0 == strncmp(arg, "SELECT ", 7)) + { + total = strlen(arg); + sql->query = xmalloc( (total+1) * sizeof(char)); + strcpy (sql->query, arg); + } + else + { + sql->query = db_generate_select_stmt(dca); + } + xprintf("%s\n", sql->query); + if (dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS) != + SQL_SUCCESS) + { + xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n", sql->query); + extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT); + dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); + dl_SQLDisconnect(sql->hdbc); + dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); + dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); + xfree(sql->query); + xfree(sql); + return NULL; + } + xfree(sql->query); + /* determine number of result columns */ + ret = dl_SQLNumResultCols(sql->hstmt, &sql->nresultcols); + total = sql->nresultcols; + if (total > SQL_FIELD_MAX) + { xprintf("db_iodbc_open: Too many fields (> %d) in query.\n" + "\"%s\"\n", SQL_FIELD_MAX, sql->query); + dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); + dl_SQLDisconnect(sql->hdbc); + dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); + dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); + xfree(sql->query); + return NULL; + } + for (i = 1; i <= total; i++) + { /* return a set of attributes for a column */ + ret = dl_SQLDescribeCol(sql->hstmt, (SQLSMALLINT) i, + sql->colname[i], SQL_FDLEN_MAX, + &colnamelen, &(sql->coltype[i]), &(sql->collen[i]), &scale, + &nullable); + sql->isnumeric[i] = is_numeric(sql->coltype[i]); + /* bind columns to program vars, converting all types to CHAR*/ + if (sql->isnumeric[i]) +#if 0 /* 12/I-2014 */ + { dl_SQLBindCol(sql->hstmt, i, SQL_DOUBLE, sql->data[i], +#else + { dl_SQLBindCol(sql->hstmt, i, SQL_DOUBLE, &sql->datanum[i], +#endif + SQL_FDLEN_MAX, &(sql->outlen[i])); + } else + { dl_SQLBindCol(sql->hstmt, i, SQL_CHAR, sql->data[i], + SQL_FDLEN_MAX, &(sql->outlen[i])); + } + for (j = sql->nf; j >= 1; j--) + { if (strcmp(mpl_tab_get_name(dca, j), sql->colname[i]) == 0) + break; + } + sql->ref[i] = j; + } + } + else if ( sql->mode == 'W' ) + { for(j = 0; sqllines[j] != NULL; j++) + arg = sqllines[j]; + if ( NULL != strchr(arg, '?') ) + { + total = strlen(arg); + sql->query = xmalloc( (total+1) * sizeof(char)); + strcpy (sql->query, arg); + } + else + { + sql->query = db_generate_insert_stmt(dca); + } + xprintf("%s\n", sql->query); + } + return sql; +} + +int db_iodbc_read(TABDCA *dca, void *link) +{ + struct db_odbc *sql; + SQLRETURN ret; + char buf[SQL_FDLEN_MAX+1]; + int i; + int len; + double num; + + sql = (struct db_odbc *) link; + + xassert(sql != NULL); + xassert(sql->mode == 'R'); + + ret=dl_SQLFetch(sql->hstmt); + if (ret== SQL_ERROR) + return -1; + if (ret== SQL_NO_DATA_FOUND) + return -1; /*EOF*/ + for (i=1; i <= sql->nresultcols; i++) + { + if (sql->ref[i] > 0) + { + len = sql->outlen[i]; + if (len != SQL_NULL_DATA) + { + if (sql->isnumeric[i]) + { mpl_tab_set_num(dca, sql->ref[i], +#if 0 /* 12/I-2014 */ + *((const double *) sql->data[i])); +#else + (const double) sql->datanum[i]); +#endif + } + else + { if (len > SQL_FDLEN_MAX) + len = SQL_FDLEN_MAX; + else if (len < 0) + len = 0; + strncpy(buf, (const char *) sql->data[i], len); + buf[len] = 0x00; + mpl_tab_set_str(dca, sql->ref[i], strtrim(buf)); + } + } + } + } + return 0; +} + +int db_iodbc_write(TABDCA *dca, void *link) +{ + struct db_odbc *sql; + char *part; + char *query; + char *template; + char num[50]; + int k; + int len; + int nf; + + sql = (struct db_odbc *) link; + xassert(sql != NULL); + xassert(sql->mode == 'W'); + + len = strlen(sql->query); + template = (char *) xmalloc( (len + 1) * sizeof(char) ); + strcpy(template, sql->query); + + nf = mpl_tab_num_flds(dca); + for (k = 1; k <= nf; k++) + { switch (mpl_tab_get_type(dca, k)) + { case 'N': + len += 20; + break; + case 'S': + len += db_escaped_string_length(mpl_tab_get_str(dca, k)); + len += 2; + break; + default: + xassert(dca != dca); + } + } + query = xmalloc( (len + 1 ) * sizeof(char) ); + query[0] = 0x00; + for (k = 1, part = strtok (template, "?"); (part != NULL); + part = strtok (NULL, "?"), k++) + { + if (k > nf) break; + strcat( query, part ); + switch (mpl_tab_get_type(dca, k)) + { case 'N': +#if 0 /* 02/XI-2010 by xypron */ + sprintf(num, "%-18g",mpl_tab_get_num(dca, k)); +#else + sprintf(num, "%.*g", DBL_DIG, mpl_tab_get_num(dca, k)); +#endif + strcat( query, num ); + break; + case 'S': + strcat( query, "'"); + db_escape_string( query + strlen(query), + mpl_tab_get_str(dca, k) ); + strcat( query, "'"); + break; + default: + xassert(dca != dca); + } + } + if (part != NULL) + strcat(query, part); + if (dl_SQLExecDirect(sql->hstmt, (SQLCHAR *) query, SQL_NTS) + != SQL_SUCCESS) + { + xprintf("db_iodbc_write: Query\n\"%s\"\nfailed.\n", query); + extract_error("SQLExecDirect", sql->hdbc, SQL_HANDLE_DBC); + xfree(query); + xfree(template); + return 1; + } + + xfree(query); + xfree(template); + return 0; +} + +int db_iodbc_close(TABDCA *dca, void *link) +{ + struct db_odbc *sql; + + sql = (struct db_odbc *) link; + xassert(sql != NULL); + /* Commit */ + if ( sql->mode == 'W' ) + dl_SQLEndTran(SQL_HANDLE_ENV, sql->henv, SQL_COMMIT); + if ( sql->mode == 'R' ) + dl_SQLCloseCursor(sql->hstmt); + + dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); + dl_SQLDisconnect(sql->hdbc); + dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); + dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); + if ( sql->mode == 'W' ) + xfree(sql->query); + xfree(sql); + dca->link = NULL; + return 0; +} + +static void extract_error( + char *fn, + SQLHANDLE handle, + SQLSMALLINT type) +{ + SQLINTEGER i = 0; + SQLINTEGER native; + SQLCHAR state[ 7 ]; + SQLCHAR text[256]; + SQLSMALLINT len; + SQLRETURN ret; + + xprintf("\nThe driver reported the following diagnostics whilst " + "running %s\n", fn); + + do + { + ret = dl_SQLGetDiagRec(type, handle, ++i, state, &native, text, + sizeof(text), &len ); + if (SQL_SUCCEEDED(ret)) + xprintf("%s:%ld:%ld:%s\n", state, i, native, text); + } + while( ret == SQL_SUCCESS ); +} + +static int is_numeric(SQLSMALLINT coltype) +{ + int ret = 0; + switch (coltype) + { + case SQL_DECIMAL: + case SQL_NUMERIC: + case SQL_SMALLINT: + case SQL_INTEGER: + case SQL_REAL: + case SQL_FLOAT: + case SQL_DOUBLE: + case SQL_TINYINT: + case SQL_BIGINT: + ret = 1; + break; + } + return ret; +} + +#endif + +/**********************************************************************/ + +#ifndef HAVE_MYSQL + +void *db_mysql_open(TABDCA *dca, int mode) +{ xassert(dca == dca); + xassert(mode == mode); + xprintf("MySQL table driver not supported\n"); + return NULL; +} + +int db_mysql_read(TABDCA *dca, void *link) +{ xassert(dca != dca); + xassert(link != link); + return 0; +} + +int db_mysql_write(TABDCA *dca, void *link) +{ xassert(dca != dca); + xassert(link != link); + return 0; +} + +int db_mysql_close(TABDCA *dca, void *link) +{ xassert(dca != dca); + xassert(link != link); + return 0; +} + +#else + +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WOE__) +#include +#endif + +#ifdef __CYGWIN__ +#define byte_defined 1 +#endif + +#if 0 /* 12/II-2014; to fix namespace bug */ +#include +#include +#endif +#include + +struct db_mysql +{ + int mode; /*'R' = Read, 'W' = Write*/ + MYSQL *con; /*connection*/ + MYSQL_RES *res; /*result*/ + int nf; + /* number of fields in the csv file */ + int ref[1+SQL_FIELD_MAX]; + /* ref[k] = k', if k-th field of the csv file corresponds to + k'-th field in the table statement; if ref[k] = 0, k-th field + of the csv file is ignored */ + char *query; + /* query generated by db_mysql_open */ +}; + +void STDCALL dl_mysql_close(MYSQL *sock) +{ + typedef void STDCALL ep_mysql_close(MYSQL *sock); + + ep_mysql_close *fn; + fn = (ep_mysql_close *) xdlsym(h_mysql, "mysql_close"); + xassert(fn != NULL); + return (*fn)(sock); +} + +const char * STDCALL dl_mysql_error(MYSQL *mysql) +{ + typedef const char * STDCALL ep_mysql_error(MYSQL *mysql); + + ep_mysql_error *fn; + fn = (ep_mysql_error *) xdlsym(h_mysql, "mysql_error"); + xassert(fn != NULL); + return (*fn)(mysql); +} + +MYSQL_FIELD * STDCALL dl_mysql_fetch_fields(MYSQL_RES *res) +{ + typedef MYSQL_FIELD * STDCALL + ep_mysql_fetch_fields(MYSQL_RES *res); + + ep_mysql_fetch_fields *fn; + fn = (ep_mysql_fetch_fields *) xdlsym(h_mysql, "mysql_fetch_fields"); + xassert(fn != NULL); + return (*fn)(res); +} + +unsigned long * STDCALL dl_mysql_fetch_lengths(MYSQL_RES *result) +{ + typedef unsigned long * STDCALL + ep_mysql_fetch_lengths(MYSQL_RES *result); + + ep_mysql_fetch_lengths *fn; + fn = (ep_mysql_fetch_lengths *) xdlsym(h_mysql, + "mysql_fetch_lengths"); + xassert(fn != NULL); + return (*fn)(result); +} + +MYSQL_ROW STDCALL dl_mysql_fetch_row(MYSQL_RES *result) +{ + typedef MYSQL_ROW STDCALL ep_mysql_fetch_row(MYSQL_RES *result); + + ep_mysql_fetch_row *fn; + fn = (ep_mysql_fetch_row *) xdlsym(h_mysql, "mysql_fetch_row"); + xassert(fn != NULL); + return (*fn)(result); +} + +unsigned int STDCALL dl_mysql_field_count(MYSQL *mysql) +{ + typedef unsigned int STDCALL ep_mysql_field_count(MYSQL *mysql); + + ep_mysql_field_count *fn; + fn = (ep_mysql_field_count *) xdlsym(h_mysql, "mysql_field_count"); + xassert(fn != NULL); + return (*fn)(mysql); +} + +MYSQL * STDCALL dl_mysql_init(MYSQL *mysql) +{ + typedef MYSQL * STDCALL ep_mysql_init(MYSQL *mysql); + + ep_mysql_init *fn; + fn = (ep_mysql_init *) xdlsym(h_mysql, "mysql_init"); + xassert(fn != NULL); + return (*fn)(mysql); +} + +unsigned int STDCALL dl_mysql_num_fields(MYSQL_RES *res) +{ + typedef unsigned int STDCALL ep_mysql_num_fields(MYSQL_RES *res); + + ep_mysql_num_fields *fn; + fn = (ep_mysql_num_fields *) xdlsym(h_mysql, "mysql_num_fields"); + xassert(fn != NULL); + return (*fn)(res); +} + +int STDCALL dl_mysql_query(MYSQL *mysql, const char *q) +{ + typedef int STDCALL ep_mysql_query(MYSQL *mysql, const char *q); + + ep_mysql_query *fn; + fn = (ep_mysql_query *) xdlsym(h_mysql, "mysql_query"); + xassert(fn != NULL); + return (*fn)(mysql, q); +} + +MYSQL * STDCALL dl_mysql_real_connect(MYSQL *mysql, const char *host, + const char *user, + const char *passwd, + const char *db, + unsigned int port, + const char *unix_socket, + unsigned long clientflag) +{ + typedef MYSQL * STDCALL ep_mysql_real_connect(MYSQL *mysql, + const char *host, + const char *user, + const char *passwd, + const char *db, + unsigned int port, + const char *unix_socket, + unsigned long clientflag); + + ep_mysql_real_connect *fn; + fn = (ep_mysql_real_connect *) xdlsym(h_mysql, + "mysql_real_connect"); + xassert(fn != NULL); + return (*fn)(mysql, host, user, passwd, db, port, unix_socket, + clientflag); +} + +MYSQL_RES * STDCALL dl_mysql_use_result(MYSQL *mysql) +{ + typedef MYSQL_RES * STDCALL ep_mysql_use_result(MYSQL *mysql); + ep_mysql_use_result *fn; + fn = (ep_mysql_use_result *) xdlsym(h_mysql, "mysql_use_result"); + xassert(fn != NULL); + return (*fn)(mysql); +} + +/*********************************************************************** +* NAME +* +* db_mysql_open - open connection to ODBC data base +* +* SYNOPSIS +* +* #include "glpsql.h" +* void *db_mysql_open(TABDCA *dca, int mode); +* +* DESCRIPTION +* +* The routine db_mysql_open opens a connection to a MySQL data base. +* It then executes the sql statements passed. +* +* In the case of table read the SELECT statement is executed. +* +* In the case of table write the INSERT statement is prepared. +* RETURNS +* +* The routine returns a pointer to data storage area created. */ + +void *db_mysql_open(TABDCA *dca, int mode) +{ void *ret; + char **sqllines; + + sqllines = args_concat(dca); + if (sqllines == NULL) + { xprintf("Missing arguments in table statement.\n" + "Please, supply table driver, dsn, and query.\n"); + return NULL; + } + ret = db_mysql_open_int(dca, mode, (const char **) sqllines); + free_buffer(sqllines); + return ret; +} + +static void *db_mysql_open_int(TABDCA *dca, int mode, const char + **sqllines) +{ + struct db_mysql *sql = NULL; + char *arg = NULL; + const char *field; + MYSQL_FIELD *fields; + char *keyword; + char *value; + char *query; + char *dsn; +/* "Server=[server_name];Database=[database_name];UID=[username];*/ +/* PWD=[password];Port=[port]"*/ + char *server = NULL; /* Server */ + char *user = NULL; /* UID */ + char *password = NULL; /* PWD */ + char *database = NULL; /* Database */ + unsigned int port = 0; /* Port */ + int narg; + int i, j, total; + + if (libmysql == NULL) + { + xprintf("No loader for shared MySQL library available\n"); + return NULL; + } + + if (h_mysql == NULL) + { + h_mysql = xdlopen(libmysql); + if (h_mysql == NULL) + { xprintf("unable to open library %s\n", libmysql); + xprintf("%s\n", get_err_msg()); + return NULL; + } + } + + sql = (struct db_mysql *) xmalloc(sizeof(struct db_mysql)); + if (sql == NULL) + return NULL; + sql->mode = mode; + sql->res = NULL; + sql->query = NULL; + sql->nf = mpl_tab_num_flds(dca); + + narg = mpl_tab_num_args(dca); + if (narg < 3 ) + xprintf("MySQL driver: string list too short \n"); + + /* get connection string*/ + dsn = (char *) mpl_tab_get_arg(dca, 2); + /* copy connection string*/ + i = strlen(dsn); + i++; + arg = xmalloc(i * sizeof(char)); + strcpy(arg, dsn); + /*tokenize connection string*/ + for (i = 1, keyword = strtok (arg, "="); (keyword != NULL); + keyword = strtok (NULL, "="), i++) + { + value = strtok (NULL, ";"); + if (value==NULL) + { + xprintf("db_mysql_open: Missing value for keyword %s\n", + keyword); + xfree(arg); + xfree(sql); + return NULL; + } + if (0 == strcmp(keyword, "Server")) + server = value; + else if (0 == strcmp(keyword, "Database")) + database = value; + else if (0 == strcmp(keyword, "UID")) + user = value; + else if (0 == strcmp(keyword, "PWD")) + password = value; + else if (0 == strcmp(keyword, "Port")) + port = (unsigned int) atol(value); + } + /* Connect to database */ + sql->con = dl_mysql_init(NULL); + if (!dl_mysql_real_connect(sql->con, server, user, password, database, + port, NULL, 0)) + { + xprintf("db_mysql_open: Connect failed\n"); + xprintf("%s\n", dl_mysql_error(sql->con)); + xfree(arg); + xfree(sql); + return NULL; + } + xfree(arg); + + for(j = 0; sqllines[j+1] != NULL; j++) + { query = (char *) sqllines[j]; + xprintf("%s\n", query); + if (dl_mysql_query(sql->con, query)) + { + xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query); + xprintf("%s\n",dl_mysql_error(sql->con)); + dl_mysql_close(sql->con); + xfree(sql); + return NULL; + } + } + + if ( sql->mode == 'R' ) + { sql->nf = mpl_tab_num_flds(dca); + for(j = 0; sqllines[j] != NULL; j++) + arg = (char *) sqllines[j]; + total = strlen(arg); + if (total > 7 && 0 == strncmp(arg, "SELECT ", 7)) + { + total = strlen(arg); + query = xmalloc( (total+1) * sizeof(char)); + strcpy (query, arg); + } + else + { + query = db_generate_select_stmt(dca); + } + xprintf("%s\n", query); + if (dl_mysql_query(sql->con, query)) + { + xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query); + xprintf("%s\n",dl_mysql_error(sql->con)); + dl_mysql_close(sql->con); + xfree(query); + xfree(sql); + return NULL; + } + xfree(query); + sql->res = dl_mysql_use_result(sql->con); + if (sql->res) + { + /* create references between query results and table fields*/ + total = dl_mysql_num_fields(sql->res); + if (total > SQL_FIELD_MAX) + { xprintf("db_mysql_open: Too many fields (> %d) in query.\n" + "\"%s\"\n", SQL_FIELD_MAX, query); + xprintf("%s\n",dl_mysql_error(sql->con)); + dl_mysql_close(sql->con); + xfree(query); + xfree(sql); + return NULL; + } + fields = dl_mysql_fetch_fields(sql->res); + for (i = 1; i <= total; i++) + { + for (j = sql->nf; j >= 1; j--) + { + if (strcmp(mpl_tab_get_name(dca, j), fields[i-1].name) + == 0) + break; + } + sql->ref[i] = j; + } + } + else + { + if(dl_mysql_field_count(sql->con) == 0) + { + xprintf("db_mysql_open: Query was not a SELECT\n\"%s\"\n", + query); + xprintf("%s\n",dl_mysql_error(sql->con)); + xfree(query); + xfree(sql); + return NULL; + } + else + { + xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query); + xprintf("%s\n",dl_mysql_error(sql->con)); + xfree(query); + xfree(sql); + return NULL; + } + } + } + else if ( sql->mode == 'W' ) + { for(j = 0; sqllines[j] != NULL; j++) + arg = (char *) sqllines[j]; + if ( NULL != strchr(arg, '?') ) + { + total = strlen(arg); + query = xmalloc( (total+1) * sizeof(char)); + strcpy (query, arg); + } + else + query = db_generate_insert_stmt(dca); + sql->query = query; + xprintf("%s\n", query); + } + return sql; +} + +int db_mysql_read(TABDCA *dca, void *link) +{ struct db_mysql *sql; + char buf[255+1]; + char **row; + unsigned long *lengths; + MYSQL_FIELD *fields; + double num; + int len; + unsigned long num_fields; + int i; + + sql = (struct db_mysql *) link; + + xassert(sql != NULL); + xassert(sql->mode == 'R'); + if (NULL == sql->res) + { + xprintf("db_mysql_read: no result set available"); + return 1; + } + if (NULL==(row = (char **)dl_mysql_fetch_row(sql->res))) { + return -1; /*EOF*/ + } + lengths = dl_mysql_fetch_lengths(sql->res); + fields = dl_mysql_fetch_fields(sql->res); + num_fields = dl_mysql_num_fields(sql->res); + for (i=1; i <= num_fields; i++) + { + if (row[i-1] != NULL) + { len = (size_t) lengths[i-1]; + if (len > 255) + len = 255; + strncpy(buf, (const char *) row[i-1], len); + buf[len] = 0x00; + if (0 != (fields[i-1].flags & NUM_FLAG)) + { strspx(buf); /* remove spaces*/ + if (str2num(buf, &num) != 0) + { xprintf("'%s' cannot be converted to a number.\n", buf); + return 1; + } + if (sql->ref[i] > 0) + mpl_tab_set_num(dca, sql->ref[i], num); + } + else + { if (sql->ref[i] > 0) + mpl_tab_set_str(dca, sql->ref[i], strtrim(buf)); + } + } + } + return 0; +} + +int db_mysql_write(TABDCA *dca, void *link) +{ + struct db_mysql *sql; + char *part; + char *query; + char *template; + char num[50]; + int k; + int len; + int nf; + + sql = (struct db_mysql *) link; + xassert(sql != NULL); + xassert(sql->mode == 'W'); + + len = strlen(sql->query); + template = (char *) xmalloc( (len + 1) * sizeof(char) ); + strcpy(template, sql->query); + + nf = mpl_tab_num_flds(dca); + for (k = 1; k <= nf; k++) + { switch (mpl_tab_get_type(dca, k)) + { case 'N': + len += 20; + break; + case 'S': + len += db_escaped_string_length(mpl_tab_get_str(dca, k)); + len += 2; + break; + default: + xassert(dca != dca); + } + } + query = xmalloc( (len + 1 ) * sizeof(char) ); + query[0] = 0x00; + for (k = 1, part = strtok (template, "?"); (part != NULL); + part = strtok (NULL, "?"), k++) + { + if (k > nf) break; + strcat( query, part ); + switch (mpl_tab_get_type(dca, k)) + { case 'N': +#if 0 /* 02/XI-2010 by xypron */ + sprintf(num, "%-18g",mpl_tab_get_num(dca, k)); +#else + sprintf(num, "%.*g", DBL_DIG, mpl_tab_get_num(dca, k)); +#endif + strcat( query, num ); + break; + case 'S': + strcat( query, "'"); + db_escape_string( query + strlen(query), + mpl_tab_get_str(dca, k) ); + strcat( query, "'"); + break; + default: + xassert(dca != dca); + } + } + if (part != NULL) + strcat(query, part); + if (dl_mysql_query(sql->con, query)) + { + xprintf("db_mysql_write: Query\n\"%s\"\nfailed.\n", query); + xprintf("%s\n",dl_mysql_error(sql->con)); + xfree(query); + xfree(template); + return 1; + } + + xfree(query); + xfree(template); + return 0; + } + +int db_mysql_close(TABDCA *dca, void *link) +{ + struct db_mysql *sql; + + sql = (struct db_mysql *) link; + xassert(sql != NULL); + dl_mysql_close(sql->con); + if ( sql->mode == 'W' ) + xfree(sql->query); + xfree(sql); + dca->link = NULL; + return 0; +} + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpsql.h b/resources/3rdparty/glpk-4.57/src/glpsql.h new file mode 100644 index 000000000..2a1650561 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpsql.h @@ -0,0 +1,64 @@ +/* glpsql.h */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Author: Heinrich Schuchardt . +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef GLPSQL_H +#define GLPSQL_H + +#define db_iodbc_open _glp_db_iodbc_open +void *db_iodbc_open(TABDCA *dca, int mode); +/* open iODBC database connection */ + +#define db_iodbc_read _glp_db_iodbc_read +int db_iodbc_read(TABDCA *dca, void *link); +/* read data from iODBC */ + +#define db_iodbc_write _glp_db_iodbc_write +int db_iodbc_write(TABDCA *dca, void *link); +/* write data to iODBC */ + +#define db_iodbc_close _glp_db_iodbc_close +int db_iodbc_close(TABDCA *dca, void *link); +/* close iODBC database connection */ + +#define db_mysql_open _glp_db_mysql_open +void *db_mysql_open(TABDCA *dca, int mode); +/* open MySQL database connection */ + +#define db_mysql_read _glp_db_mysql_read +int db_mysql_read(TABDCA *dca, void *link); +/* read data from MySQL */ + +#define db_mysql_write _glp_db_mysql_write +int db_mysql_write(TABDCA *dca, void *link); +/* write data to MySQL */ + +#define db_mysql_close _glp_db_mysql_close +int db_mysql_close(TABDCA *dca, void *link); +/* close MySQL database connection */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpssx.h b/resources/3rdparty/glpk-4.57/src/glpssx.h new file mode 100644 index 000000000..1b55d7a3d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpssx.h @@ -0,0 +1,426 @@ +/* glpssx.h (simplex method, rational arithmetic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef GLPSSX_H +#define GLPSSX_H + +#include "bfx.h" +#include "env.h" + +typedef struct SSX SSX; + +struct SSX +{ /* simplex solver workspace */ +/*---------------------------------------------------------------------- +// LP PROBLEM DATA +// +// It is assumed that LP problem has the following statement: +// +// minimize (or maximize) +// +// z = c[1]*x[1] + ... + c[m+n]*x[m+n] + c[0] (1) +// +// subject to equality constraints +// +// x[1] - a[1,1]*x[m+1] - ... - a[1,n]*x[m+n] = 0 +// +// . . . . . . . (2) +// +// x[m] - a[m,1]*x[m+1] + ... - a[m,n]*x[m+n] = 0 +// +// and bounds of variables +// +// l[1] <= x[1] <= u[1] +// +// . . . . . . . (3) +// +// l[m+n] <= x[m+n] <= u[m+n] +// +// where: +// x[1], ..., x[m] - auxiliary variables; +// x[m+1], ..., x[m+n] - structural variables; +// z - objective function; +// c[1], ..., c[m+n] - coefficients of the objective function; +// c[0] - constant term of the objective function; +// a[1,1], ..., a[m,n] - constraint coefficients; +// l[1], ..., l[m+n] - lower bounds of variables; +// u[1], ..., u[m+n] - upper bounds of variables. +// +// Bounds of variables can be finite as well as inifinite. Besides, +// lower and upper bounds can be equal to each other. So the following +// five types of variables are possible: +// +// Bounds of variable Type of variable +// ------------------------------------------------- +// -inf < x[k] < +inf Free (unbounded) variable +// l[k] <= x[k] < +inf Variable with lower bound +// -inf < x[k] <= u[k] Variable with upper bound +// l[k] <= x[k] <= u[k] Double-bounded variable +// l[k] = x[k] = u[k] Fixed variable +// +// Using vector-matrix notations the LP problem (1)-(3) can be written +// as follows: +// +// minimize (or maximize) +// +// z = c * x + c[0] (4) +// +// subject to equality constraints +// +// xR - A * xS = 0 (5) +// +// and bounds of variables +// +// l <= x <= u (6) +// +// where: +// xR - vector of auxiliary variables; +// xS - vector of structural variables; +// x = (xR, xS) - vector of all variables; +// z - objective function; +// c - vector of objective coefficients; +// c[0] - constant term of the objective function; +// A - matrix of constraint coefficients (has m rows +// and n columns); +// l - vector of lower bounds of variables; +// u - vector of upper bounds of variables. +// +// The simplex method makes no difference between auxiliary and +// structural variables, so it is convenient to think the system of +// equality constraints (5) written in a homogeneous form: +// +// (I | -A) * x = 0, (7) +// +// where (I | -A) is an augmented (m+n)xm constraint matrix, I is mxm +// unity matrix whose columns correspond to auxiliary variables, and A +// is the original mxn constraint matrix whose columns correspond to +// structural variables. Note that only the matrix A is stored. +----------------------------------------------------------------------*/ + int m; + /* number of rows (auxiliary variables), m > 0 */ + int n; + /* number of columns (structural variables), n > 0 */ + int *type; /* int type[1+m+n]; */ + /* type[0] is not used; + type[k], 1 <= k <= m+n, is the type of variable x[k]: */ +#define SSX_FR 0 /* free (unbounded) variable */ +#define SSX_LO 1 /* variable with lower bound */ +#define SSX_UP 2 /* variable with upper bound */ +#define SSX_DB 3 /* double-bounded variable */ +#define SSX_FX 4 /* fixed variable */ + mpq_t *lb; /* mpq_t lb[1+m+n]; alias: l */ + /* lb[0] is not used; + lb[k], 1 <= k <= m+n, is an lower bound of variable x[k]; + if x[k] has no lower bound, lb[k] is zero */ + mpq_t *ub; /* mpq_t ub[1+m+n]; alias: u */ + /* ub[0] is not used; + ub[k], 1 <= k <= m+n, is an upper bound of variable x[k]; + if x[k] has no upper bound, ub[k] is zero; + if x[k] is of fixed type, ub[k] is equal to lb[k] */ + int dir; + /* optimization direction (sense of the objective function): */ +#define SSX_MIN 0 /* minimization */ +#define SSX_MAX 1 /* maximization */ + mpq_t *coef; /* mpq_t coef[1+m+n]; alias: c */ + /* coef[0] is a constant term of the objective function; + coef[k], 1 <= k <= m+n, is a coefficient of the objective + function at variable x[k]; + note that auxiliary variables also may have non-zero objective + coefficients */ + int *A_ptr; /* int A_ptr[1+n+1]; */ + int *A_ind; /* int A_ind[A_ptr[n+1]]; */ + mpq_t *A_val; /* mpq_t A_val[A_ptr[n+1]]; */ + /* constraint matrix A (see (5)) in storage-by-columns format */ +/*---------------------------------------------------------------------- +// LP BASIS AND CURRENT BASIC SOLUTION +// +// The LP basis is defined by the following partition of the augmented +// constraint matrix (7): +// +// (B | N) = (I | -A) * Q, (8) +// +// where B is a mxm non-singular basis matrix whose columns correspond +// to basic variables xB, N is a mxn matrix whose columns correspond to +// non-basic variables xN, and Q is a permutation (m+n)x(m+n) matrix. +// +// From (7) and (8) it follows that +// +// (I | -A) * x = (I | -A) * Q * Q' * x = (B | N) * (xB, xN), +// +// therefore +// +// (xB, xN) = Q' * x, (9) +// +// where x is the vector of all variables in the original order, xB is +// a vector of basic variables, xN is a vector of non-basic variables, +// Q' = inv(Q) is a matrix transposed to Q. +// +// Current values of non-basic variables xN[j], j = 1, ..., n, are not +// stored; they are defined implicitly by their statuses as follows: +// +// 0, if xN[j] is free variable +// lN[j], if xN[j] is on its lower bound (10) +// uN[j], if xN[j] is on its upper bound +// lN[j] = uN[j], if xN[j] is fixed variable +// +// where lN[j] and uN[j] are lower and upper bounds of xN[j]. +// +// Current values of basic variables xB[i], i = 1, ..., m, are computed +// as follows: +// +// beta = - inv(B) * N * xN, (11) +// +// where current values of xN are defined by (10). +// +// Current values of simplex multipliers pi[i], i = 1, ..., m (which +// are values of Lagrange multipliers for equality constraints (7) also +// called shadow prices) are computed as follows: +// +// pi = inv(B') * cB, (12) +// +// where B' is a matrix transposed to B, cB is a vector of objective +// coefficients at basic variables xB. +// +// Current values of reduced costs d[j], j = 1, ..., n, (which are +// values of Langrange multipliers for active inequality constraints +// corresponding to non-basic variables) are computed as follows: +// +// d = cN - N' * pi, (13) +// +// where N' is a matrix transposed to N, cN is a vector of objective +// coefficients at non-basic variables xN. +----------------------------------------------------------------------*/ + int *stat; /* int stat[1+m+n]; */ + /* stat[0] is not used; + stat[k], 1 <= k <= m+n, is the status of variable x[k]: */ +#define SSX_BS 0 /* basic variable */ +#define SSX_NL 1 /* non-basic variable on lower bound */ +#define SSX_NU 2 /* non-basic variable on upper bound */ +#define SSX_NF 3 /* non-basic free variable */ +#define SSX_NS 4 /* non-basic fixed variable */ + int *Q_row; /* int Q_row[1+m+n]; */ + /* matrix Q in row-like format; + Q_row[0] is not used; + Q_row[i] = j means that q[i,j] = 1 */ + int *Q_col; /* int Q_col[1+m+n]; */ + /* matrix Q in column-like format; + Q_col[0] is not used; + Q_col[j] = i means that q[i,j] = 1 */ + /* if k-th column of the matrix (I | A) is k'-th column of the + matrix (B | N), then Q_row[k] = k' and Q_col[k'] = k; + if x[k] is xB[i], then Q_row[k] = i and Q_col[i] = k; + if x[k] is xN[j], then Q_row[k] = m+j and Q_col[m+j] = k */ + BFX *binv; + /* invertable form of the basis matrix B */ + mpq_t *bbar; /* mpq_t bbar[1+m]; alias: beta */ + /* bbar[0] is a value of the objective function; + bbar[i], 1 <= i <= m, is a value of basic variable xB[i] */ + mpq_t *pi; /* mpq_t pi[1+m]; */ + /* pi[0] is not used; + pi[i], 1 <= i <= m, is a simplex multiplier corresponding to + i-th row (equality constraint) */ + mpq_t *cbar; /* mpq_t cbar[1+n]; alias: d */ + /* cbar[0] is not used; + cbar[j], 1 <= j <= n, is a reduced cost of non-basic variable + xN[j] */ +/*---------------------------------------------------------------------- +// SIMPLEX TABLE +// +// Due to (8) and (9) the system of equality constraints (7) for the +// current basis can be written as follows: +// +// xB = A~ * xN, (14) +// +// where +// +// A~ = - inv(B) * N (15) +// +// is a mxn matrix called the simplex table. +// +// The revised simplex method uses only two components of A~, namely, +// pivot column corresponding to non-basic variable xN[q] chosen to +// enter the basis, and pivot row corresponding to basic variable xB[p] +// chosen to leave the basis. +// +// Pivot column alfa_q is q-th column of A~, so +// +// alfa_q = A~ * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q], (16) +// +// where N[q] is q-th column of the matrix N. +// +// Pivot row alfa_p is p-th row of A~ or, equivalently, p-th column of +// A~', a matrix transposed to A~, so +// +// alfa_p = A~' * e[p] = - N' * inv(B') * e[p] = - N' * rho_p, (17) +// +// where (*)' means transposition, and +// +// rho_p = inv(B') * e[p], (18) +// +// is p-th column of inv(B') or, that is the same, p-th row of inv(B). +----------------------------------------------------------------------*/ + int p; + /* number of basic variable xB[p], 1 <= p <= m, chosen to leave + the basis */ + mpq_t *rho; /* mpq_t rho[1+m]; */ + /* p-th row of the inverse inv(B); see (18) */ + mpq_t *ap; /* mpq_t ap[1+n]; */ + /* p-th row of the simplex table; see (17) */ + int q; + /* number of non-basic variable xN[q], 1 <= q <= n, chosen to + enter the basis */ + mpq_t *aq; /* mpq_t aq[1+m]; */ + /* q-th column of the simplex table; see (16) */ +/*--------------------------------------------------------------------*/ + int q_dir; + /* direction in which non-basic variable xN[q] should change on + moving to the adjacent vertex of the polyhedron: + +1 means that xN[q] increases + -1 means that xN[q] decreases */ + int p_stat; + /* non-basic status which should be assigned to basic variable + xB[p] when it has left the basis and become xN[q] */ + mpq_t delta; + /* actual change of xN[q] in the adjacent basis (it has the same + sign as q_dir) */ +/*--------------------------------------------------------------------*/ + int it_lim; + /* simplex iterations limit; if this value is positive, it is + decreased by one each time when one simplex iteration has been + performed, and reaching zero value signals the solver to stop + the search; negative value means no iterations limit */ + int it_cnt; + /* simplex iterations count; this count is increased by one each + time when one simplex iteration has been performed */ + double tm_lim; + /* searching time limit, in seconds; if this value is positive, + it is decreased each time when one simplex iteration has been + performed by the amount of time spent for the iteration, and + reaching zero value signals the solver to stop the search; + negative value means no time limit */ + double out_frq; + /* output frequency, in seconds; this parameter specifies how + frequently the solver sends information about the progress of + the search to the standard output */ +#if 0 /* 10/VI-2013 */ + glp_long tm_beg; +#else + double tm_beg; +#endif + /* starting time of the search, in seconds; the total time of the + search is the difference between xtime() and tm_beg */ +#if 0 /* 10/VI-2013 */ + glp_long tm_lag; +#else + double tm_lag; +#endif + /* the most recent time, in seconds, at which the progress of the + the search was displayed */ +}; + +#define ssx_create _glp_ssx_create +#define ssx_factorize _glp_ssx_factorize +#define ssx_get_xNj _glp_ssx_get_xNj +#define ssx_eval_bbar _glp_ssx_eval_bbar +#define ssx_eval_pi _glp_ssx_eval_pi +#define ssx_eval_dj _glp_ssx_eval_dj +#define ssx_eval_cbar _glp_ssx_eval_cbar +#define ssx_eval_rho _glp_ssx_eval_rho +#define ssx_eval_row _glp_ssx_eval_row +#define ssx_eval_col _glp_ssx_eval_col +#define ssx_chuzc _glp_ssx_chuzc +#define ssx_chuzr _glp_ssx_chuzr +#define ssx_update_bbar _glp_ssx_update_bbar +#define ssx_update_pi _glp_ssx_update_pi +#define ssx_update_cbar _glp_ssx_update_cbar +#define ssx_change_basis _glp_ssx_change_basis +#define ssx_delete _glp_ssx_delete + +#define ssx_phase_I _glp_ssx_phase_I +#define ssx_phase_II _glp_ssx_phase_II +#define ssx_driver _glp_ssx_driver + +SSX *ssx_create(int m, int n, int nnz); +/* create simplex solver workspace */ + +int ssx_factorize(SSX *ssx); +/* factorize the current basis matrix */ + +void ssx_get_xNj(SSX *ssx, int j, mpq_t x); +/* determine value of non-basic variable */ + +void ssx_eval_bbar(SSX *ssx); +/* compute values of basic variables */ + +void ssx_eval_pi(SSX *ssx); +/* compute values of simplex multipliers */ + +void ssx_eval_dj(SSX *ssx, int j, mpq_t dj); +/* compute reduced cost of non-basic variable */ + +void ssx_eval_cbar(SSX *ssx); +/* compute reduced costs of all non-basic variables */ + +void ssx_eval_rho(SSX *ssx); +/* compute p-th row of the inverse */ + +void ssx_eval_row(SSX *ssx); +/* compute pivot row of the simplex table */ + +void ssx_eval_col(SSX *ssx); +/* compute pivot column of the simplex table */ + +void ssx_chuzc(SSX *ssx); +/* choose pivot column */ + +void ssx_chuzr(SSX *ssx); +/* choose pivot row */ + +void ssx_update_bbar(SSX *ssx); +/* update values of basic variables */ + +void ssx_update_pi(SSX *ssx); +/* update simplex multipliers */ + +void ssx_update_cbar(SSX *ssx); +/* update reduced costs of non-basic variables */ + +void ssx_change_basis(SSX *ssx); +/* change current basis to adjacent one */ + +void ssx_delete(SSX *ssx); +/* delete simplex solver workspace */ + +int ssx_phase_I(SSX *ssx); +/* find primal feasible solution */ + +int ssx_phase_II(SSX *ssx); +/* find optimal solution */ + +int ssx_driver(SSX *ssx); +/* base driver to exact simplex method */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpssx01.c b/resources/3rdparty/glpk-4.57/src/glpssx01.c new file mode 100644 index 000000000..9b70444ec --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpssx01.c @@ -0,0 +1,839 @@ +/* glpssx01.c (simplex method, rational arithmetic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpssx.h" +#define xfault xerror + +/*---------------------------------------------------------------------- +// ssx_create - create simplex solver workspace. +// +// This routine creates the workspace used by simplex solver routines, +// and returns a pointer to it. +// +// Parameters m, n, and nnz specify, respectively, the number of rows, +// columns, and non-zero constraint coefficients. +// +// This routine only allocates the memory for the workspace components, +// so the workspace needs to be saturated by data. */ + +SSX *ssx_create(int m, int n, int nnz) +{ SSX *ssx; + int i, j, k; + if (m < 1) + xfault("ssx_create: m = %d; invalid number of rows\n", m); + if (n < 1) + xfault("ssx_create: n = %d; invalid number of columns\n", n); + if (nnz < 0) + xfault("ssx_create: nnz = %d; invalid number of non-zero const" + "raint coefficients\n", nnz); + ssx = xmalloc(sizeof(SSX)); + ssx->m = m; + ssx->n = n; + ssx->type = xcalloc(1+m+n, sizeof(int)); + ssx->lb = xcalloc(1+m+n, sizeof(mpq_t)); + for (k = 1; k <= m+n; k++) mpq_init(ssx->lb[k]); + ssx->ub = xcalloc(1+m+n, sizeof(mpq_t)); + for (k = 1; k <= m+n; k++) mpq_init(ssx->ub[k]); + ssx->coef = xcalloc(1+m+n, sizeof(mpq_t)); + for (k = 0; k <= m+n; k++) mpq_init(ssx->coef[k]); + ssx->A_ptr = xcalloc(1+n+1, sizeof(int)); + ssx->A_ptr[n+1] = nnz+1; + ssx->A_ind = xcalloc(1+nnz, sizeof(int)); + ssx->A_val = xcalloc(1+nnz, sizeof(mpq_t)); + for (k = 1; k <= nnz; k++) mpq_init(ssx->A_val[k]); + ssx->stat = xcalloc(1+m+n, sizeof(int)); + ssx->Q_row = xcalloc(1+m+n, sizeof(int)); + ssx->Q_col = xcalloc(1+m+n, sizeof(int)); + ssx->binv = bfx_create_binv(); + ssx->bbar = xcalloc(1+m, sizeof(mpq_t)); + for (i = 0; i <= m; i++) mpq_init(ssx->bbar[i]); + ssx->pi = xcalloc(1+m, sizeof(mpq_t)); + for (i = 1; i <= m; i++) mpq_init(ssx->pi[i]); + ssx->cbar = xcalloc(1+n, sizeof(mpq_t)); + for (j = 1; j <= n; j++) mpq_init(ssx->cbar[j]); + ssx->rho = xcalloc(1+m, sizeof(mpq_t)); + for (i = 1; i <= m; i++) mpq_init(ssx->rho[i]); + ssx->ap = xcalloc(1+n, sizeof(mpq_t)); + for (j = 1; j <= n; j++) mpq_init(ssx->ap[j]); + ssx->aq = xcalloc(1+m, sizeof(mpq_t)); + for (i = 1; i <= m; i++) mpq_init(ssx->aq[i]); + mpq_init(ssx->delta); + return ssx; +} + +/*---------------------------------------------------------------------- +// ssx_factorize - factorize the current basis matrix. +// +// This routine computes factorization of the current basis matrix B +// and returns the singularity flag. If the matrix B is non-singular, +// the flag is zero, otherwise non-zero. */ + +static int basis_col(void *info, int j, int ind[], mpq_t val[]) +{ /* this auxiliary routine provides row indices and numeric values + of non-zero elements in j-th column of the matrix B */ + SSX *ssx = info; + int m = ssx->m; + int n = ssx->n; + int *A_ptr = ssx->A_ptr; + int *A_ind = ssx->A_ind; + mpq_t *A_val = ssx->A_val; + int *Q_col = ssx->Q_col; + int k, len, ptr; + xassert(1 <= j && j <= m); + k = Q_col[j]; /* x[k] = xB[j] */ + xassert(1 <= k && k <= m+n); + /* j-th column of the matrix B is k-th column of the augmented + constraint matrix (I | -A) */ + if (k <= m) + { /* it is a column of the unity matrix I */ + len = 1, ind[1] = k, mpq_set_si(val[1], 1, 1); + } + else + { /* it is a column of the original constraint matrix -A */ + len = 0; + for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) + { len++; + ind[len] = A_ind[ptr]; + mpq_neg(val[len], A_val[ptr]); + } + } + return len; +} + +int ssx_factorize(SSX *ssx) +{ int ret; + ret = bfx_factorize(ssx->binv, ssx->m, basis_col, ssx); + return ret; +} + +/*---------------------------------------------------------------------- +// ssx_get_xNj - determine value of non-basic variable. +// +// This routine determines the value of non-basic variable xN[j] in the +// current basic solution defined as follows: +// +// 0, if xN[j] is free variable +// lN[j], if xN[j] is on its lower bound +// uN[j], if xN[j] is on its upper bound +// lN[j] = uN[j], if xN[j] is fixed variable +// +// where lN[j] and uN[j] are lower and upper bounds of xN[j]. */ + +void ssx_get_xNj(SSX *ssx, int j, mpq_t x) +{ int m = ssx->m; + int n = ssx->n; + mpq_t *lb = ssx->lb; + mpq_t *ub = ssx->ub; + int *stat = ssx->stat; + int *Q_col = ssx->Q_col; + int k; + xassert(1 <= j && j <= n); + k = Q_col[m+j]; /* x[k] = xN[j] */ + xassert(1 <= k && k <= m+n); + switch (stat[k]) + { case SSX_NL: + /* xN[j] is on its lower bound */ + mpq_set(x, lb[k]); break; + case SSX_NU: + /* xN[j] is on its upper bound */ + mpq_set(x, ub[k]); break; + case SSX_NF: + /* xN[j] is free variable */ + mpq_set_si(x, 0, 1); break; + case SSX_NS: + /* xN[j] is fixed variable */ + mpq_set(x, lb[k]); break; + default: + xassert(stat != stat); + } + return; +} + +/*---------------------------------------------------------------------- +// ssx_eval_bbar - compute values of basic variables. +// +// This routine computes values of basic variables xB in the current +// basic solution as follows: +// +// beta = - inv(B) * N * xN, +// +// where B is the basis matrix, N is the matrix of non-basic columns, +// xN is a vector of current values of non-basic variables. */ + +void ssx_eval_bbar(SSX *ssx) +{ int m = ssx->m; + int n = ssx->n; + mpq_t *coef = ssx->coef; + int *A_ptr = ssx->A_ptr; + int *A_ind = ssx->A_ind; + mpq_t *A_val = ssx->A_val; + int *Q_col = ssx->Q_col; + mpq_t *bbar = ssx->bbar; + int i, j, k, ptr; + mpq_t x, temp; + mpq_init(x); + mpq_init(temp); + /* bbar := 0 */ + for (i = 1; i <= m; i++) + mpq_set_si(bbar[i], 0, 1); + /* bbar := - N * xN = - N[1] * xN[1] - ... - N[n] * xN[n] */ + for (j = 1; j <= n; j++) + { ssx_get_xNj(ssx, j, x); + if (mpq_sgn(x) == 0) continue; + k = Q_col[m+j]; /* x[k] = xN[j] */ + if (k <= m) + { /* N[j] is a column of the unity matrix I */ + mpq_sub(bbar[k], bbar[k], x); + } + else + { /* N[j] is a column of the original constraint matrix -A */ + for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) + { mpq_mul(temp, A_val[ptr], x); + mpq_add(bbar[A_ind[ptr]], bbar[A_ind[ptr]], temp); + } + } + } + /* bbar := inv(B) * bbar */ + bfx_ftran(ssx->binv, bbar, 0); +#if 1 + /* compute value of the objective function */ + /* bbar[0] := c[0] */ + mpq_set(bbar[0], coef[0]); + /* bbar[0] := bbar[0] + sum{i in B} cB[i] * xB[i] */ + for (i = 1; i <= m; i++) + { k = Q_col[i]; /* x[k] = xB[i] */ + if (mpq_sgn(coef[k]) == 0) continue; + mpq_mul(temp, coef[k], bbar[i]); + mpq_add(bbar[0], bbar[0], temp); + } + /* bbar[0] := bbar[0] + sum{j in N} cN[j] * xN[j] */ + for (j = 1; j <= n; j++) + { k = Q_col[m+j]; /* x[k] = xN[j] */ + if (mpq_sgn(coef[k]) == 0) continue; + ssx_get_xNj(ssx, j, x); + mpq_mul(temp, coef[k], x); + mpq_add(bbar[0], bbar[0], temp); + } +#endif + mpq_clear(x); + mpq_clear(temp); + return; +} + +/*---------------------------------------------------------------------- +// ssx_eval_pi - compute values of simplex multipliers. +// +// This routine computes values of simplex multipliers (shadow prices) +// pi in the current basic solution as follows: +// +// pi = inv(B') * cB, +// +// where B' is a matrix transposed to the basis matrix B, cB is a vector +// of objective coefficients at basic variables xB. */ + +void ssx_eval_pi(SSX *ssx) +{ int m = ssx->m; + mpq_t *coef = ssx->coef; + int *Q_col = ssx->Q_col; + mpq_t *pi = ssx->pi; + int i; + /* pi := cB */ + for (i = 1; i <= m; i++) mpq_set(pi[i], coef[Q_col[i]]); + /* pi := inv(B') * cB */ + bfx_btran(ssx->binv, pi); + return; +} + +/*---------------------------------------------------------------------- +// ssx_eval_dj - compute reduced cost of non-basic variable. +// +// This routine computes reduced cost d[j] of non-basic variable xN[j] +// in the current basic solution as follows: +// +// d[j] = cN[j] - N[j] * pi, +// +// where cN[j] is an objective coefficient at xN[j], N[j] is a column +// of the augmented constraint matrix (I | -A) corresponding to xN[j], +// pi is the vector of simplex multipliers (shadow prices). */ + +void ssx_eval_dj(SSX *ssx, int j, mpq_t dj) +{ int m = ssx->m; + int n = ssx->n; + mpq_t *coef = ssx->coef; + int *A_ptr = ssx->A_ptr; + int *A_ind = ssx->A_ind; + mpq_t *A_val = ssx->A_val; + int *Q_col = ssx->Q_col; + mpq_t *pi = ssx->pi; + int k, ptr, end; + mpq_t temp; + mpq_init(temp); + xassert(1 <= j && j <= n); + k = Q_col[m+j]; /* x[k] = xN[j] */ + xassert(1 <= k && k <= m+n); + /* j-th column of the matrix N is k-th column of the augmented + constraint matrix (I | -A) */ + if (k <= m) + { /* it is a column of the unity matrix I */ + mpq_sub(dj, coef[k], pi[k]); + } + else + { /* it is a column of the original constraint matrix -A */ + mpq_set(dj, coef[k]); + for (ptr = A_ptr[k-m], end = A_ptr[k-m+1]; ptr < end; ptr++) + { mpq_mul(temp, A_val[ptr], pi[A_ind[ptr]]); + mpq_add(dj, dj, temp); + } + } + mpq_clear(temp); + return; +} + +/*---------------------------------------------------------------------- +// ssx_eval_cbar - compute reduced costs of all non-basic variables. +// +// This routine computes the vector of reduced costs pi in the current +// basic solution for all non-basic variables, including fixed ones. */ + +void ssx_eval_cbar(SSX *ssx) +{ int n = ssx->n; + mpq_t *cbar = ssx->cbar; + int j; + for (j = 1; j <= n; j++) + ssx_eval_dj(ssx, j, cbar[j]); + return; +} + +/*---------------------------------------------------------------------- +// ssx_eval_rho - compute p-th row of the inverse. +// +// This routine computes p-th row of the matrix inv(B), where B is the +// current basis matrix. +// +// p-th row of the inverse is computed using the following formula: +// +// rho = inv(B') * e[p], +// +// where B' is a matrix transposed to B, e[p] is a unity vector, which +// contains one in p-th position. */ + +void ssx_eval_rho(SSX *ssx) +{ int m = ssx->m; + int p = ssx->p; + mpq_t *rho = ssx->rho; + int i; + xassert(1 <= p && p <= m); + /* rho := 0 */ + for (i = 1; i <= m; i++) mpq_set_si(rho[i], 0, 1); + /* rho := e[p] */ + mpq_set_si(rho[p], 1, 1); + /* rho := inv(B') * rho */ + bfx_btran(ssx->binv, rho); + return; +} + +/*---------------------------------------------------------------------- +// ssx_eval_row - compute pivot row of the simplex table. +// +// This routine computes p-th (pivot) row of the current simplex table +// A~ = - inv(B) * N using the following formula: +// +// A~[p] = - N' * inv(B') * e[p] = - N' * rho[p], +// +// where N' is a matrix transposed to the matrix N, rho[p] is p-th row +// of the inverse inv(B). */ + +void ssx_eval_row(SSX *ssx) +{ int m = ssx->m; + int n = ssx->n; + int *A_ptr = ssx->A_ptr; + int *A_ind = ssx->A_ind; + mpq_t *A_val = ssx->A_val; + int *Q_col = ssx->Q_col; + mpq_t *rho = ssx->rho; + mpq_t *ap = ssx->ap; + int j, k, ptr; + mpq_t temp; + mpq_init(temp); + for (j = 1; j <= n; j++) + { /* ap[j] := - N'[j] * rho (inner product) */ + k = Q_col[m+j]; /* x[k] = xN[j] */ + if (k <= m) + mpq_neg(ap[j], rho[k]); + else + { mpq_set_si(ap[j], 0, 1); + for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) + { mpq_mul(temp, A_val[ptr], rho[A_ind[ptr]]); + mpq_add(ap[j], ap[j], temp); + } + } + } + mpq_clear(temp); + return; +} + +/*---------------------------------------------------------------------- +// ssx_eval_col - compute pivot column of the simplex table. +// +// This routine computes q-th (pivot) column of the current simplex +// table A~ = - inv(B) * N using the following formula: +// +// A~[q] = - inv(B) * N[q], +// +// where N[q] is q-th column of the matrix N corresponding to chosen +// non-basic variable xN[q]. */ + +void ssx_eval_col(SSX *ssx) +{ int m = ssx->m; + int n = ssx->n; + int *A_ptr = ssx->A_ptr; + int *A_ind = ssx->A_ind; + mpq_t *A_val = ssx->A_val; + int *Q_col = ssx->Q_col; + int q = ssx->q; + mpq_t *aq = ssx->aq; + int i, k, ptr; + xassert(1 <= q && q <= n); + /* aq := 0 */ + for (i = 1; i <= m; i++) mpq_set_si(aq[i], 0, 1); + /* aq := N[q] */ + k = Q_col[m+q]; /* x[k] = xN[q] */ + if (k <= m) + { /* N[q] is a column of the unity matrix I */ + mpq_set_si(aq[k], 1, 1); + } + else + { /* N[q] is a column of the original constraint matrix -A */ + for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) + mpq_neg(aq[A_ind[ptr]], A_val[ptr]); + } + /* aq := inv(B) * aq */ + bfx_ftran(ssx->binv, aq, 1); + /* aq := - aq */ + for (i = 1; i <= m; i++) mpq_neg(aq[i], aq[i]); + return; +} + +/*---------------------------------------------------------------------- +// ssx_chuzc - choose pivot column. +// +// This routine chooses non-basic variable xN[q] whose reduced cost +// indicates possible improving of the objective function to enter it +// in the basis. +// +// Currently the standard (textbook) pricing is used, i.e. that +// non-basic variable is preferred which has greatest reduced cost (in +// magnitude). +// +// If xN[q] has been chosen, the routine stores its number q and also +// sets the flag q_dir that indicates direction in which xN[q] has to +// change (+1 means increasing, -1 means decreasing). +// +// If the choice cannot be made, because the current basic solution is +// dual feasible, the routine sets the number q to 0. */ + +void ssx_chuzc(SSX *ssx) +{ int m = ssx->m; + int n = ssx->n; + int dir = (ssx->dir == SSX_MIN ? +1 : -1); + int *Q_col = ssx->Q_col; + int *stat = ssx->stat; + mpq_t *cbar = ssx->cbar; + int j, k, s, q, q_dir; + double best, temp; + /* nothing is chosen so far */ + q = 0, q_dir = 0, best = 0.0; + /* look through the list of non-basic variables */ + for (j = 1; j <= n; j++) + { k = Q_col[m+j]; /* x[k] = xN[j] */ + s = dir * mpq_sgn(cbar[j]); + if ((stat[k] == SSX_NF || stat[k] == SSX_NL) && s < 0 || + (stat[k] == SSX_NF || stat[k] == SSX_NU) && s > 0) + { /* reduced cost of xN[j] indicates possible improving of + the objective function */ + temp = fabs(mpq_get_d(cbar[j])); + xassert(temp != 0.0); + if (q == 0 || best < temp) + q = j, q_dir = - s, best = temp; + } + } + ssx->q = q, ssx->q_dir = q_dir; + return; +} + +/*---------------------------------------------------------------------- +// ssx_chuzr - choose pivot row. +// +// This routine looks through elements of q-th column of the simplex +// table and chooses basic variable xB[p] which should leave the basis. +// +// The choice is based on the standard (textbook) ratio test. +// +// If xB[p] has been chosen, the routine stores its number p and also +// sets its non-basic status p_stat which should be assigned to xB[p] +// when it has left the basis and become xN[q]. +// +// Special case p < 0 means that xN[q] is double-bounded variable and +// it reaches its opposite bound before any basic variable does that, +// so the current basis remains unchanged. +// +// If the choice cannot be made, because xN[q] can infinitely change in +// the feasible direction, the routine sets the number p to 0. */ + +void ssx_chuzr(SSX *ssx) +{ int m = ssx->m; + int n = ssx->n; + int *type = ssx->type; + mpq_t *lb = ssx->lb; + mpq_t *ub = ssx->ub; + int *Q_col = ssx->Q_col; + mpq_t *bbar = ssx->bbar; + int q = ssx->q; + mpq_t *aq = ssx->aq; + int q_dir = ssx->q_dir; + int i, k, s, t, p, p_stat; + mpq_t teta, temp; + mpq_init(teta); + mpq_init(temp); + xassert(1 <= q && q <= n); + xassert(q_dir == +1 || q_dir == -1); + /* nothing is chosen so far */ + p = 0, p_stat = 0; + /* look through the list of basic variables */ + for (i = 1; i <= m; i++) + { s = q_dir * mpq_sgn(aq[i]); + if (s < 0) + { /* xB[i] decreases */ + k = Q_col[i]; /* x[k] = xB[i] */ + t = type[k]; + if (t == SSX_LO || t == SSX_DB || t == SSX_FX) + { /* xB[i] has finite lower bound */ + mpq_sub(temp, bbar[i], lb[k]); + mpq_div(temp, temp, aq[i]); + mpq_abs(temp, temp); + if (p == 0 || mpq_cmp(teta, temp) > 0) + { p = i; + p_stat = (t == SSX_FX ? SSX_NS : SSX_NL); + mpq_set(teta, temp); + } + } + } + else if (s > 0) + { /* xB[i] increases */ + k = Q_col[i]; /* x[k] = xB[i] */ + t = type[k]; + if (t == SSX_UP || t == SSX_DB || t == SSX_FX) + { /* xB[i] has finite upper bound */ + mpq_sub(temp, bbar[i], ub[k]); + mpq_div(temp, temp, aq[i]); + mpq_abs(temp, temp); + if (p == 0 || mpq_cmp(teta, temp) > 0) + { p = i; + p_stat = (t == SSX_FX ? SSX_NS : SSX_NU); + mpq_set(teta, temp); + } + } + } + /* if something has been chosen and the ratio test indicates + exact degeneracy, the search can be finished */ + if (p != 0 && mpq_sgn(teta) == 0) break; + } + /* if xN[q] is double-bounded, check if it can reach its opposite + bound before any basic variable */ + k = Q_col[m+q]; /* x[k] = xN[q] */ + if (type[k] == SSX_DB) + { mpq_sub(temp, ub[k], lb[k]); + if (p == 0 || mpq_cmp(teta, temp) > 0) + { p = -1; + p_stat = -1; + mpq_set(teta, temp); + } + } + ssx->p = p; + ssx->p_stat = p_stat; + /* if xB[p] has been chosen, determine its actual change in the + adjacent basis (it has the same sign as q_dir) */ + if (p != 0) + { xassert(mpq_sgn(teta) >= 0); + if (q_dir > 0) + mpq_set(ssx->delta, teta); + else + mpq_neg(ssx->delta, teta); + } + mpq_clear(teta); + mpq_clear(temp); + return; +} + +/*---------------------------------------------------------------------- +// ssx_update_bbar - update values of basic variables. +// +// This routine recomputes the current values of basic variables for +// the adjacent basis. +// +// The simplex table for the current basis is the following: +// +// xB[i] = sum{j in 1..n} alfa[i,j] * xN[q], i = 1,...,m +// +// therefore +// +// delta xB[i] = alfa[i,q] * delta xN[q], i = 1,...,m +// +// where delta xN[q] = xN.new[q] - xN[q] is the change of xN[q] in the +// adjacent basis, and delta xB[i] = xB.new[i] - xB[i] is the change of +// xB[i]. This gives formulae for recomputing values of xB[i]: +// +// xB.new[p] = xN[q] + delta xN[q] +// +// (because xN[q] becomes xB[p] in the adjacent basis), and +// +// xB.new[i] = xB[i] + alfa[i,q] * delta xN[q], i != p +// +// for other basic variables. */ + +void ssx_update_bbar(SSX *ssx) +{ int m = ssx->m; + int n = ssx->n; + mpq_t *bbar = ssx->bbar; + mpq_t *cbar = ssx->cbar; + int p = ssx->p; + int q = ssx->q; + mpq_t *aq = ssx->aq; + int i; + mpq_t temp; + mpq_init(temp); + xassert(1 <= q && q <= n); + if (p < 0) + { /* xN[q] is double-bounded and goes to its opposite bound */ + /* nop */; + } + else + { /* xN[q] becomes xB[p] in the adjacent basis */ + /* xB.new[p] = xN[q] + delta xN[q] */ + xassert(1 <= p && p <= m); + ssx_get_xNj(ssx, q, temp); + mpq_add(bbar[p], temp, ssx->delta); + } + /* update values of other basic variables depending on xN[q] */ + for (i = 1; i <= m; i++) + { if (i == p) continue; + /* xB.new[i] = xB[i] + alfa[i,q] * delta xN[q] */ + if (mpq_sgn(aq[i]) == 0) continue; + mpq_mul(temp, aq[i], ssx->delta); + mpq_add(bbar[i], bbar[i], temp); + } +#if 1 + /* update value of the objective function */ + /* z.new = z + d[q] * delta xN[q] */ + mpq_mul(temp, cbar[q], ssx->delta); + mpq_add(bbar[0], bbar[0], temp); +#endif + mpq_clear(temp); + return; +} + +/*---------------------------------------------------------------------- +-- ssx_update_pi - update simplex multipliers. +-- +-- This routine recomputes the vector of simplex multipliers for the +-- adjacent basis. */ + +void ssx_update_pi(SSX *ssx) +{ int m = ssx->m; + int n = ssx->n; + mpq_t *pi = ssx->pi; + mpq_t *cbar = ssx->cbar; + int p = ssx->p; + int q = ssx->q; + mpq_t *aq = ssx->aq; + mpq_t *rho = ssx->rho; + int i; + mpq_t new_dq, temp; + mpq_init(new_dq); + mpq_init(temp); + xassert(1 <= p && p <= m); + xassert(1 <= q && q <= n); + /* compute d[q] in the adjacent basis */ + mpq_div(new_dq, cbar[q], aq[p]); + /* update the vector of simplex multipliers */ + for (i = 1; i <= m; i++) + { if (mpq_sgn(rho[i]) == 0) continue; + mpq_mul(temp, new_dq, rho[i]); + mpq_sub(pi[i], pi[i], temp); + } + mpq_clear(new_dq); + mpq_clear(temp); + return; +} + +/*---------------------------------------------------------------------- +// ssx_update_cbar - update reduced costs of non-basic variables. +// +// This routine recomputes the vector of reduced costs of non-basic +// variables for the adjacent basis. */ + +void ssx_update_cbar(SSX *ssx) +{ int m = ssx->m; + int n = ssx->n; + mpq_t *cbar = ssx->cbar; + int p = ssx->p; + int q = ssx->q; + mpq_t *ap = ssx->ap; + int j; + mpq_t temp; + mpq_init(temp); + xassert(1 <= p && p <= m); + xassert(1 <= q && q <= n); + /* compute d[q] in the adjacent basis */ + /* d.new[q] = d[q] / alfa[p,q] */ + mpq_div(cbar[q], cbar[q], ap[q]); + /* update reduced costs of other non-basic variables */ + for (j = 1; j <= n; j++) + { if (j == q) continue; + /* d.new[j] = d[j] - (alfa[p,j] / alfa[p,q]) * d[q] */ + if (mpq_sgn(ap[j]) == 0) continue; + mpq_mul(temp, ap[j], cbar[q]); + mpq_sub(cbar[j], cbar[j], temp); + } + mpq_clear(temp); + return; +} + +/*---------------------------------------------------------------------- +// ssx_change_basis - change current basis to adjacent one. +// +// This routine changes the current basis to the adjacent one swapping +// basic variable xB[p] and non-basic variable xN[q]. */ + +void ssx_change_basis(SSX *ssx) +{ int m = ssx->m; + int n = ssx->n; + int *type = ssx->type; + int *stat = ssx->stat; + int *Q_row = ssx->Q_row; + int *Q_col = ssx->Q_col; + int p = ssx->p; + int q = ssx->q; + int p_stat = ssx->p_stat; + int k, kp, kq; + if (p < 0) + { /* special case: xN[q] goes to its opposite bound */ + xassert(1 <= q && q <= n); + k = Q_col[m+q]; /* x[k] = xN[q] */ + xassert(type[k] == SSX_DB); + switch (stat[k]) + { case SSX_NL: + stat[k] = SSX_NU; + break; + case SSX_NU: + stat[k] = SSX_NL; + break; + default: + xassert(stat != stat); + } + } + else + { /* xB[p] leaves the basis, xN[q] enters the basis */ + xassert(1 <= p && p <= m); + xassert(1 <= q && q <= n); + kp = Q_col[p]; /* x[kp] = xB[p] */ + kq = Q_col[m+q]; /* x[kq] = xN[q] */ + /* check non-basic status of xB[p] which becomes xN[q] */ + switch (type[kp]) + { case SSX_FR: + xassert(p_stat == SSX_NF); + break; + case SSX_LO: + xassert(p_stat == SSX_NL); + break; + case SSX_UP: + xassert(p_stat == SSX_NU); + break; + case SSX_DB: + xassert(p_stat == SSX_NL || p_stat == SSX_NU); + break; + case SSX_FX: + xassert(p_stat == SSX_NS); + break; + default: + xassert(type != type); + } + /* swap xB[p] and xN[q] */ + stat[kp] = (char)p_stat, stat[kq] = SSX_BS; + Q_row[kp] = m+q, Q_row[kq] = p; + Q_col[p] = kq, Q_col[m+q] = kp; + /* update factorization of the basis matrix */ + if (bfx_update(ssx->binv, p)) + { if (ssx_factorize(ssx)) + xassert(("Internal error: basis matrix is singular", 0)); + } + } + return; +} + +/*---------------------------------------------------------------------- +// ssx_delete - delete simplex solver workspace. +// +// This routine deletes the simplex solver workspace freeing all the +// memory allocated to this object. */ + +void ssx_delete(SSX *ssx) +{ int m = ssx->m; + int n = ssx->n; + int nnz = ssx->A_ptr[n+1]-1; + int i, j, k; + xfree(ssx->type); + for (k = 1; k <= m+n; k++) mpq_clear(ssx->lb[k]); + xfree(ssx->lb); + for (k = 1; k <= m+n; k++) mpq_clear(ssx->ub[k]); + xfree(ssx->ub); + for (k = 0; k <= m+n; k++) mpq_clear(ssx->coef[k]); + xfree(ssx->coef); + xfree(ssx->A_ptr); + xfree(ssx->A_ind); + for (k = 1; k <= nnz; k++) mpq_clear(ssx->A_val[k]); + xfree(ssx->A_val); + xfree(ssx->stat); + xfree(ssx->Q_row); + xfree(ssx->Q_col); + bfx_delete_binv(ssx->binv); + for (i = 0; i <= m; i++) mpq_clear(ssx->bbar[i]); + xfree(ssx->bbar); + for (i = 1; i <= m; i++) mpq_clear(ssx->pi[i]); + xfree(ssx->pi); + for (j = 1; j <= n; j++) mpq_clear(ssx->cbar[j]); + xfree(ssx->cbar); + for (i = 1; i <= m; i++) mpq_clear(ssx->rho[i]); + xfree(ssx->rho); + for (j = 1; j <= n; j++) mpq_clear(ssx->ap[j]); + xfree(ssx->ap); + for (i = 1; i <= m; i++) mpq_clear(ssx->aq[i]); + xfree(ssx->aq); + mpq_clear(ssx->delta); + xfree(ssx); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/glpssx02.c b/resources/3rdparty/glpk-4.57/src/glpssx02.c new file mode 100644 index 000000000..4b3ea97d6 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/glpssx02.c @@ -0,0 +1,479 @@ +/* glpssx02.c (simplex method, rational arithmetic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpssx.h" + +static void show_progress(SSX *ssx, int phase) +{ /* this auxiliary routine displays information about progress of + the search */ + int i, def = 0; + for (i = 1; i <= ssx->m; i++) + if (ssx->type[ssx->Q_col[i]] == SSX_FX) def++; + xprintf("%s%6d: %s = %22.15g (%d)\n", phase == 1 ? " " : "*", + ssx->it_cnt, phase == 1 ? "infsum" : "objval", + mpq_get_d(ssx->bbar[0]), def); +#if 0 + ssx->tm_lag = utime(); +#else + ssx->tm_lag = xtime(); +#endif + return; +} + +/*---------------------------------------------------------------------- +// ssx_phase_I - find primal feasible solution. +// +// This routine implements phase I of the primal simplex method. +// +// On exit the routine returns one of the following codes: +// +// 0 - feasible solution found; +// 1 - problem has no feasible solution; +// 2 - iterations limit exceeded; +// 3 - time limit exceeded. +----------------------------------------------------------------------*/ + +int ssx_phase_I(SSX *ssx) +{ int m = ssx->m; + int n = ssx->n; + int *type = ssx->type; + mpq_t *lb = ssx->lb; + mpq_t *ub = ssx->ub; + mpq_t *coef = ssx->coef; + int *A_ptr = ssx->A_ptr; + int *A_ind = ssx->A_ind; + mpq_t *A_val = ssx->A_val; + int *Q_col = ssx->Q_col; + mpq_t *bbar = ssx->bbar; + mpq_t *pi = ssx->pi; + mpq_t *cbar = ssx->cbar; + int *orig_type, orig_dir; + mpq_t *orig_lb, *orig_ub, *orig_coef; + int i, k, ret; + /* save components of the original LP problem, which are changed + by the routine */ + orig_type = xcalloc(1+m+n, sizeof(int)); + orig_lb = xcalloc(1+m+n, sizeof(mpq_t)); + orig_ub = xcalloc(1+m+n, sizeof(mpq_t)); + orig_coef = xcalloc(1+m+n, sizeof(mpq_t)); + for (k = 1; k <= m+n; k++) + { orig_type[k] = type[k]; + mpq_init(orig_lb[k]); + mpq_set(orig_lb[k], lb[k]); + mpq_init(orig_ub[k]); + mpq_set(orig_ub[k], ub[k]); + } + orig_dir = ssx->dir; + for (k = 0; k <= m+n; k++) + { mpq_init(orig_coef[k]); + mpq_set(orig_coef[k], coef[k]); + } + /* build an artificial basic solution, which is primal feasible, + and also build an auxiliary objective function to minimize the + sum of infeasibilities for the original problem */ + ssx->dir = SSX_MIN; + for (k = 0; k <= m+n; k++) mpq_set_si(coef[k], 0, 1); + mpq_set_si(bbar[0], 0, 1); + for (i = 1; i <= m; i++) + { int t; + k = Q_col[i]; /* x[k] = xB[i] */ + t = type[k]; + if (t == SSX_LO || t == SSX_DB || t == SSX_FX) + { /* in the original problem x[k] has lower bound */ + if (mpq_cmp(bbar[i], lb[k]) < 0) + { /* which is violated */ + type[k] = SSX_UP; + mpq_set(ub[k], lb[k]); + mpq_set_si(lb[k], 0, 1); + mpq_set_si(coef[k], -1, 1); + mpq_add(bbar[0], bbar[0], ub[k]); + mpq_sub(bbar[0], bbar[0], bbar[i]); + } + } + if (t == SSX_UP || t == SSX_DB || t == SSX_FX) + { /* in the original problem x[k] has upper bound */ + if (mpq_cmp(bbar[i], ub[k]) > 0) + { /* which is violated */ + type[k] = SSX_LO; + mpq_set(lb[k], ub[k]); + mpq_set_si(ub[k], 0, 1); + mpq_set_si(coef[k], +1, 1); + mpq_add(bbar[0], bbar[0], bbar[i]); + mpq_sub(bbar[0], bbar[0], lb[k]); + } + } + } + /* now the initial basic solution should be primal feasible due + to changes of bounds of some basic variables, which turned to + implicit artifical variables */ + /* compute simplex multipliers and reduced costs */ + ssx_eval_pi(ssx); + ssx_eval_cbar(ssx); + /* display initial progress of the search */ + show_progress(ssx, 1); + /* main loop starts here */ + for (;;) + { /* display current progress of the search */ +#if 0 + if (utime() - ssx->tm_lag >= ssx->out_frq - 0.001) +#else + if (xdifftime(xtime(), ssx->tm_lag) >= ssx->out_frq - 0.001) +#endif + show_progress(ssx, 1); + /* we do not need to wait until all artificial variables have + left the basis */ + if (mpq_sgn(bbar[0]) == 0) + { /* the sum of infeasibilities is zero, therefore the current + solution is primal feasible for the original problem */ + ret = 0; + break; + } + /* check if the iterations limit has been exhausted */ + if (ssx->it_lim == 0) + { ret = 2; + break; + } + /* check if the time limit has been exhausted */ +#if 0 + if (ssx->tm_lim >= 0.0 && ssx->tm_lim <= utime() - ssx->tm_beg) +#else + if (ssx->tm_lim >= 0.0 && + ssx->tm_lim <= xdifftime(xtime(), ssx->tm_beg)) +#endif + { ret = 3; + break; + } + /* choose non-basic variable xN[q] */ + ssx_chuzc(ssx); + /* if xN[q] cannot be chosen, the sum of infeasibilities is + minimal but non-zero; therefore the original problem has no + primal feasible solution */ + if (ssx->q == 0) + { ret = 1; + break; + } + /* compute q-th column of the simplex table */ + ssx_eval_col(ssx); + /* choose basic variable xB[p] */ + ssx_chuzr(ssx); + /* the sum of infeasibilities cannot be negative, therefore + the auxiliary lp problem cannot have unbounded solution */ + xassert(ssx->p != 0); + /* update values of basic variables */ + ssx_update_bbar(ssx); + if (ssx->p > 0) + { /* compute p-th row of the inverse inv(B) */ + ssx_eval_rho(ssx); + /* compute p-th row of the simplex table */ + ssx_eval_row(ssx); + xassert(mpq_cmp(ssx->aq[ssx->p], ssx->ap[ssx->q]) == 0); + /* update simplex multipliers */ + ssx_update_pi(ssx); + /* update reduced costs of non-basic variables */ + ssx_update_cbar(ssx); + } + /* xB[p] is leaving the basis; if it is implicit artificial + variable, the corresponding residual vanishes; therefore + bounds of this variable should be restored to the original + values */ + if (ssx->p > 0) + { k = Q_col[ssx->p]; /* x[k] = xB[p] */ + if (type[k] != orig_type[k]) + { /* x[k] is implicit artificial variable */ + type[k] = orig_type[k]; + mpq_set(lb[k], orig_lb[k]); + mpq_set(ub[k], orig_ub[k]); + xassert(ssx->p_stat == SSX_NL || ssx->p_stat == SSX_NU); + ssx->p_stat = (ssx->p_stat == SSX_NL ? SSX_NU : SSX_NL); + if (type[k] == SSX_FX) ssx->p_stat = SSX_NS; + /* nullify the objective coefficient at x[k] */ + mpq_set_si(coef[k], 0, 1); + /* since coef[k] has been changed, we need to compute + new reduced cost of x[k], which it will have in the + adjacent basis */ + /* the formula d[j] = cN[j] - pi' * N[j] is used (note + that the vector pi is not changed, because it depends + on objective coefficients at basic variables, but in + the adjacent basis, for which the vector pi has been + just recomputed, x[k] is non-basic) */ + if (k <= m) + { /* x[k] is auxiliary variable */ + mpq_neg(cbar[ssx->q], pi[k]); + } + else + { /* x[k] is structural variable */ + int ptr; + mpq_t temp; + mpq_init(temp); + mpq_set_si(cbar[ssx->q], 0, 1); + for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) + { mpq_mul(temp, pi[A_ind[ptr]], A_val[ptr]); + mpq_add(cbar[ssx->q], cbar[ssx->q], temp); + } + mpq_clear(temp); + } + } + } + /* jump to the adjacent vertex of the polyhedron */ + ssx_change_basis(ssx); + /* one simplex iteration has been performed */ + if (ssx->it_lim > 0) ssx->it_lim--; + ssx->it_cnt++; + } + /* display final progress of the search */ + show_progress(ssx, 1); + /* restore components of the original problem, which were changed + by the routine */ + for (k = 1; k <= m+n; k++) + { type[k] = orig_type[k]; + mpq_set(lb[k], orig_lb[k]); + mpq_clear(orig_lb[k]); + mpq_set(ub[k], orig_ub[k]); + mpq_clear(orig_ub[k]); + } + ssx->dir = orig_dir; + for (k = 0; k <= m+n; k++) + { mpq_set(coef[k], orig_coef[k]); + mpq_clear(orig_coef[k]); + } + xfree(orig_type); + xfree(orig_lb); + xfree(orig_ub); + xfree(orig_coef); + /* return to the calling program */ + return ret; +} + +/*---------------------------------------------------------------------- +// ssx_phase_II - find optimal solution. +// +// This routine implements phase II of the primal simplex method. +// +// On exit the routine returns one of the following codes: +// +// 0 - optimal solution found; +// 1 - problem has unbounded solution; +// 2 - iterations limit exceeded; +// 3 - time limit exceeded. +----------------------------------------------------------------------*/ + +int ssx_phase_II(SSX *ssx) +{ int ret; + /* display initial progress of the search */ + show_progress(ssx, 2); + /* main loop starts here */ + for (;;) + { /* display current progress of the search */ +#if 0 + if (utime() - ssx->tm_lag >= ssx->out_frq - 0.001) +#else + if (xdifftime(xtime(), ssx->tm_lag) >= ssx->out_frq - 0.001) +#endif + show_progress(ssx, 2); + /* check if the iterations limit has been exhausted */ + if (ssx->it_lim == 0) + { ret = 2; + break; + } + /* check if the time limit has been exhausted */ +#if 0 + if (ssx->tm_lim >= 0.0 && ssx->tm_lim <= utime() - ssx->tm_beg) +#else + if (ssx->tm_lim >= 0.0 && + ssx->tm_lim <= xdifftime(xtime(), ssx->tm_beg)) +#endif + { ret = 3; + break; + } + /* choose non-basic variable xN[q] */ + ssx_chuzc(ssx); + /* if xN[q] cannot be chosen, the current basic solution is + dual feasible and therefore optimal */ + if (ssx->q == 0) + { ret = 0; + break; + } + /* compute q-th column of the simplex table */ + ssx_eval_col(ssx); + /* choose basic variable xB[p] */ + ssx_chuzr(ssx); + /* if xB[p] cannot be chosen, the problem has no dual feasible + solution (i.e. unbounded) */ + if (ssx->p == 0) + { ret = 1; + break; + } + /* update values of basic variables */ + ssx_update_bbar(ssx); + if (ssx->p > 0) + { /* compute p-th row of the inverse inv(B) */ + ssx_eval_rho(ssx); + /* compute p-th row of the simplex table */ + ssx_eval_row(ssx); + xassert(mpq_cmp(ssx->aq[ssx->p], ssx->ap[ssx->q]) == 0); +#if 0 + /* update simplex multipliers */ + ssx_update_pi(ssx); +#endif + /* update reduced costs of non-basic variables */ + ssx_update_cbar(ssx); + } + /* jump to the adjacent vertex of the polyhedron */ + ssx_change_basis(ssx); + /* one simplex iteration has been performed */ + if (ssx->it_lim > 0) ssx->it_lim--; + ssx->it_cnt++; + } + /* display final progress of the search */ + show_progress(ssx, 2); + /* return to the calling program */ + return ret; +} + +/*---------------------------------------------------------------------- +// ssx_driver - base driver to exact simplex method. +// +// This routine is a base driver to a version of the primal simplex +// method using exact (bignum) arithmetic. +// +// On exit the routine returns one of the following codes: +// +// 0 - optimal solution found; +// 1 - problem has no feasible solution; +// 2 - problem has unbounded solution; +// 3 - iterations limit exceeded (phase I); +// 4 - iterations limit exceeded (phase II); +// 5 - time limit exceeded (phase I); +// 6 - time limit exceeded (phase II); +// 7 - initial basis matrix is exactly singular. +----------------------------------------------------------------------*/ + +int ssx_driver(SSX *ssx) +{ int m = ssx->m; + int *type = ssx->type; + mpq_t *lb = ssx->lb; + mpq_t *ub = ssx->ub; + int *Q_col = ssx->Q_col; + mpq_t *bbar = ssx->bbar; + int i, k, ret; + ssx->tm_beg = xtime(); + /* factorize the initial basis matrix */ + if (ssx_factorize(ssx)) + { xprintf("Initial basis matrix is singular\n"); + ret = 7; + goto done; + } + /* compute values of basic variables */ + ssx_eval_bbar(ssx); + /* check if the initial basic solution is primal feasible */ + for (i = 1; i <= m; i++) + { int t; + k = Q_col[i]; /* x[k] = xB[i] */ + t = type[k]; + if (t == SSX_LO || t == SSX_DB || t == SSX_FX) + { /* x[k] has lower bound */ + if (mpq_cmp(bbar[i], lb[k]) < 0) + { /* which is violated */ + break; + } + } + if (t == SSX_UP || t == SSX_DB || t == SSX_FX) + { /* x[k] has upper bound */ + if (mpq_cmp(bbar[i], ub[k]) > 0) + { /* which is violated */ + break; + } + } + } + if (i > m) + { /* no basic variable violates its bounds */ + ret = 0; + goto skip; + } + /* phase I: find primal feasible solution */ + ret = ssx_phase_I(ssx); + switch (ret) + { case 0: + ret = 0; + break; + case 1: + xprintf("PROBLEM HAS NO FEASIBLE SOLUTION\n"); + ret = 1; + break; + case 2: + xprintf("ITERATIONS LIMIT EXCEEDED; SEARCH TERMINATED\n"); + ret = 3; + break; + case 3: + xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); + ret = 5; + break; + default: + xassert(ret != ret); + } + /* compute values of basic variables (actually only the objective + value needs to be computed) */ + ssx_eval_bbar(ssx); +skip: /* compute simplex multipliers */ + ssx_eval_pi(ssx); + /* compute reduced costs of non-basic variables */ + ssx_eval_cbar(ssx); + /* if phase I failed, do not start phase II */ + if (ret != 0) goto done; + /* phase II: find optimal solution */ + ret = ssx_phase_II(ssx); + switch (ret) + { case 0: + xprintf("OPTIMAL SOLUTION FOUND\n"); + ret = 0; + break; + case 1: + xprintf("PROBLEM HAS UNBOUNDED SOLUTION\n"); + ret = 2; + break; + case 2: + xprintf("ITERATIONS LIMIT EXCEEDED; SEARCH TERMINATED\n"); + ret = 4; + break; + case 3: + xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); + ret = 6; + break; + default: + xassert(ret != ret); + } +done: /* decrease the time limit by the spent amount of time */ + if (ssx->tm_lim >= 0.0) +#if 0 + { ssx->tm_lim -= utime() - ssx->tm_beg; +#else + { ssx->tm_lim -= xdifftime(xtime(), ssx->tm_beg); +#endif + if (ssx->tm_lim < 0.0) ssx->tm_lim = 0.0; + } + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/lux.c b/resources/3rdparty/glpk-4.57/src/lux.c new file mode 100644 index 000000000..38cb758cb --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/lux.c @@ -0,0 +1,1030 @@ +/* lux.c (LU-factorization, rational arithmetic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "lux.h" + +#define xfault xerror +#define dmp_create_poolx(size) dmp_create_pool() + +/*********************************************************************** +* lux_create - create LU-factorization +* +* SYNOPSIS +* +* #include "lux.h" +* LUX *lux_create(int n); +* +* DESCRIPTION +* +* The routine lux_create creates LU-factorization data structure for +* a matrix of the order n. Initially the factorization corresponds to +* the unity matrix (F = V = P = Q = I, so A = I). +* +* RETURNS +* +* The routine returns a pointer to the created LU-factorization data +* structure, which represents the unity matrix of the order n. */ + +LUX *lux_create(int n) +{ LUX *lux; + int k; + if (n < 1) + xfault("lux_create: n = %d; invalid parameter\n", n); + lux = xmalloc(sizeof(LUX)); + lux->n = n; + lux->pool = dmp_create_poolx(sizeof(LUXELM)); + lux->F_row = xcalloc(1+n, sizeof(LUXELM *)); + lux->F_col = xcalloc(1+n, sizeof(LUXELM *)); + lux->V_piv = xcalloc(1+n, sizeof(mpq_t)); + lux->V_row = xcalloc(1+n, sizeof(LUXELM *)); + lux->V_col = xcalloc(1+n, sizeof(LUXELM *)); + lux->P_row = xcalloc(1+n, sizeof(int)); + lux->P_col = xcalloc(1+n, sizeof(int)); + lux->Q_row = xcalloc(1+n, sizeof(int)); + lux->Q_col = xcalloc(1+n, sizeof(int)); + for (k = 1; k <= n; k++) + { lux->F_row[k] = lux->F_col[k] = NULL; + mpq_init(lux->V_piv[k]); + mpq_set_si(lux->V_piv[k], 1, 1); + lux->V_row[k] = lux->V_col[k] = NULL; + lux->P_row[k] = lux->P_col[k] = k; + lux->Q_row[k] = lux->Q_col[k] = k; + } + lux->rank = n; + return lux; +} + +/*********************************************************************** +* initialize - initialize LU-factorization data structures +* +* This routine initializes data structures for subsequent computing +* the LU-factorization of a given matrix A, which is specified by the +* formal routine col. On exit V = A and F = P = Q = I, where I is the +* unity matrix. */ + +static void initialize(LUX *lux, int (*col)(void *info, int j, + int ind[], mpq_t val[]), void *info, LUXWKA *wka) +{ int n = lux->n; + DMP *pool = lux->pool; + LUXELM **F_row = lux->F_row; + LUXELM **F_col = lux->F_col; + mpq_t *V_piv = lux->V_piv; + LUXELM **V_row = lux->V_row; + LUXELM **V_col = lux->V_col; + int *P_row = lux->P_row; + int *P_col = lux->P_col; + int *Q_row = lux->Q_row; + int *Q_col = lux->Q_col; + int *R_len = wka->R_len; + int *R_head = wka->R_head; + int *R_prev = wka->R_prev; + int *R_next = wka->R_next; + int *C_len = wka->C_len; + int *C_head = wka->C_head; + int *C_prev = wka->C_prev; + int *C_next = wka->C_next; + LUXELM *fij, *vij; + int i, j, k, len, *ind; + mpq_t *val; + /* F := I */ + for (i = 1; i <= n; i++) + { while (F_row[i] != NULL) + { fij = F_row[i], F_row[i] = fij->r_next; + mpq_clear(fij->val); + dmp_free_atom(pool, fij, sizeof(LUXELM)); + } + } + for (j = 1; j <= n; j++) F_col[j] = NULL; + /* V := 0 */ + for (k = 1; k <= n; k++) mpq_set_si(V_piv[k], 0, 1); + for (i = 1; i <= n; i++) + { while (V_row[i] != NULL) + { vij = V_row[i], V_row[i] = vij->r_next; + mpq_clear(vij->val); + dmp_free_atom(pool, vij, sizeof(LUXELM)); + } + } + for (j = 1; j <= n; j++) V_col[j] = NULL; + /* V := A */ + ind = xcalloc(1+n, sizeof(int)); + val = xcalloc(1+n, sizeof(mpq_t)); + for (k = 1; k <= n; k++) mpq_init(val[k]); + for (j = 1; j <= n; j++) + { /* obtain j-th column of matrix A */ + len = col(info, j, ind, val); + if (!(0 <= len && len <= n)) + xfault("lux_decomp: j = %d: len = %d; invalid column length" + "\n", j, len); + /* copy elements of j-th column to matrix V */ + for (k = 1; k <= len; k++) + { /* get row index of a[i,j] */ + i = ind[k]; + if (!(1 <= i && i <= n)) + xfault("lux_decomp: j = %d: i = %d; row index out of ran" + "ge\n", j, i); + /* check for duplicate indices */ + if (V_row[i] != NULL && V_row[i]->j == j) + xfault("lux_decomp: j = %d: i = %d; duplicate row indice" + "s not allowed\n", j, i); + /* check for zero value */ + if (mpq_sgn(val[k]) == 0) + xfault("lux_decomp: j = %d: i = %d; zero elements not al" + "lowed\n", j, i); + /* add new element v[i,j] = a[i,j] to V */ + vij = dmp_get_atom(pool, sizeof(LUXELM)); + vij->i = i, vij->j = j; + mpq_init(vij->val); + mpq_set(vij->val, val[k]); + vij->r_prev = NULL; + vij->r_next = V_row[i]; + vij->c_prev = NULL; + vij->c_next = V_col[j]; + if (vij->r_next != NULL) vij->r_next->r_prev = vij; + if (vij->c_next != NULL) vij->c_next->c_prev = vij; + V_row[i] = V_col[j] = vij; + } + } + xfree(ind); + for (k = 1; k <= n; k++) mpq_clear(val[k]); + xfree(val); + /* P := Q := I */ + for (k = 1; k <= n; k++) + P_row[k] = P_col[k] = Q_row[k] = Q_col[k] = k; + /* the rank of A and V is not determined yet */ + lux->rank = -1; + /* initially the entire matrix V is active */ + /* determine its row lengths */ + for (i = 1; i <= n; i++) + { len = 0; + for (vij = V_row[i]; vij != NULL; vij = vij->r_next) len++; + R_len[i] = len; + } + /* build linked lists of active rows */ + for (len = 0; len <= n; len++) R_head[len] = 0; + for (i = 1; i <= n; i++) + { len = R_len[i]; + R_prev[i] = 0; + R_next[i] = R_head[len]; + if (R_next[i] != 0) R_prev[R_next[i]] = i; + R_head[len] = i; + } + /* determine its column lengths */ + for (j = 1; j <= n; j++) + { len = 0; + for (vij = V_col[j]; vij != NULL; vij = vij->c_next) len++; + C_len[j] = len; + } + /* build linked lists of active columns */ + for (len = 0; len <= n; len++) C_head[len] = 0; + for (j = 1; j <= n; j++) + { len = C_len[j]; + C_prev[j] = 0; + C_next[j] = C_head[len]; + if (C_next[j] != 0) C_prev[C_next[j]] = j; + C_head[len] = j; + } + return; +} + +/*********************************************************************** +* find_pivot - choose a pivot element +* +* This routine chooses a pivot element v[p,q] in the active submatrix +* of matrix U = P*V*Q. +* +* It is assumed that on entry the matrix U has the following partially +* triangularized form: +* +* 1 k n +* 1 x x x x x x x x x x +* . x x x x x x x x x +* . . x x x x x x x x +* . . . x x x x x x x +* k . . . . * * * * * * +* . . . . * * * * * * +* . . . . * * * * * * +* . . . . * * * * * * +* . . . . * * * * * * +* n . . . . * * * * * * +* +* where rows and columns k, k+1, ..., n belong to the active submatrix +* (elements of the active submatrix are marked by '*'). +* +* Since the matrix U = P*V*Q is not stored, the routine works with the +* matrix V. It is assumed that the row-wise representation corresponds +* to the matrix V, but the column-wise representation corresponds to +* the active submatrix of the matrix V, i.e. elements of the matrix V, +* which does not belong to the active submatrix, are missing from the +* column linked lists. It is also assumed that each active row of the +* matrix V is in the set R[len], where len is number of non-zeros in +* the row, and each active column of the matrix V is in the set C[len], +* where len is number of non-zeros in the column (in the latter case +* only elements of the active submatrix are counted; such elements are +* marked by '*' on the figure above). +* +* Due to exact arithmetic any non-zero element of the active submatrix +* can be chosen as a pivot. However, to keep sparsity of the matrix V +* the routine uses Markowitz strategy, trying to choose such element +* v[p,q], which has smallest Markowitz cost (nr[p]-1) * (nc[q]-1), +* where nr[p] and nc[q] are the number of non-zero elements, resp., in +* p-th row and in q-th column of the active submatrix. +* +* In order to reduce the search, i.e. not to walk through all elements +* of the active submatrix, the routine exploits a technique proposed by +* I.Duff. This technique is based on using the sets R[len] and C[len] +* of active rows and columns. +* +* On exit the routine returns a pointer to a pivot v[p,q] chosen, or +* NULL, if the active submatrix is empty. */ + +static LUXELM *find_pivot(LUX *lux, LUXWKA *wka) +{ int n = lux->n; + LUXELM **V_row = lux->V_row; + LUXELM **V_col = lux->V_col; + int *R_len = wka->R_len; + int *R_head = wka->R_head; + int *R_next = wka->R_next; + int *C_len = wka->C_len; + int *C_head = wka->C_head; + int *C_next = wka->C_next; + LUXELM *piv, *some, *vij; + int i, j, len, min_len, ncand, piv_lim = 5; + double best, cost; + /* nothing is chosen so far */ + piv = NULL, best = DBL_MAX, ncand = 0; + /* if in the active submatrix there is a column that has the only + non-zero (column singleton), choose it as a pivot */ + j = C_head[1]; + if (j != 0) + { xassert(C_len[j] == 1); + piv = V_col[j]; + xassert(piv != NULL && piv->c_next == NULL); + goto done; + } + /* if in the active submatrix there is a row that has the only + non-zero (row singleton), choose it as a pivot */ + i = R_head[1]; + if (i != 0) + { xassert(R_len[i] == 1); + piv = V_row[i]; + xassert(piv != NULL && piv->r_next == NULL); + goto done; + } + /* there are no singletons in the active submatrix; walk through + other non-empty rows and columns */ + for (len = 2; len <= n; len++) + { /* consider active columns having len non-zeros */ + for (j = C_head[len]; j != 0; j = C_next[j]) + { /* j-th column has len non-zeros */ + /* find an element in the row of minimal length */ + some = NULL, min_len = INT_MAX; + for (vij = V_col[j]; vij != NULL; vij = vij->c_next) + { if (min_len > R_len[vij->i]) + some = vij, min_len = R_len[vij->i]; + /* if Markowitz cost of this element is not greater than + (len-1)**2, it can be chosen right now; this heuristic + reduces the search and works well in many cases */ + if (min_len <= len) + { piv = some; + goto done; + } + } + /* j-th column has been scanned */ + /* the minimal element found is a next pivot candidate */ + xassert(some != NULL); + ncand++; + /* compute its Markowitz cost */ + cost = (double)(min_len - 1) * (double)(len - 1); + /* choose between the current candidate and this element */ + if (cost < best) piv = some, best = cost; + /* if piv_lim candidates have been considered, there is a + doubt that a much better candidate exists; therefore it + is the time to terminate the search */ + if (ncand == piv_lim) goto done; + } + /* now consider active rows having len non-zeros */ + for (i = R_head[len]; i != 0; i = R_next[i]) + { /* i-th row has len non-zeros */ + /* find an element in the column of minimal length */ + some = NULL, min_len = INT_MAX; + for (vij = V_row[i]; vij != NULL; vij = vij->r_next) + { if (min_len > C_len[vij->j]) + some = vij, min_len = C_len[vij->j]; + /* if Markowitz cost of this element is not greater than + (len-1)**2, it can be chosen right now; this heuristic + reduces the search and works well in many cases */ + if (min_len <= len) + { piv = some; + goto done; + } + } + /* i-th row has been scanned */ + /* the minimal element found is a next pivot candidate */ + xassert(some != NULL); + ncand++; + /* compute its Markowitz cost */ + cost = (double)(len - 1) * (double)(min_len - 1); + /* choose between the current candidate and this element */ + if (cost < best) piv = some, best = cost; + /* if piv_lim candidates have been considered, there is a + doubt that a much better candidate exists; therefore it + is the time to terminate the search */ + if (ncand == piv_lim) goto done; + } + } +done: /* bring the pivot v[p,q] to the factorizing routine */ + return piv; +} + +/*********************************************************************** +* eliminate - perform gaussian elimination +* +* This routine performs elementary gaussian transformations in order +* to eliminate subdiagonal elements in the k-th column of the matrix +* U = P*V*Q using the pivot element u[k,k], where k is the number of +* the current elimination step. +* +* The parameter piv specifies the pivot element v[p,q] = u[k,k]. +* +* Each time when the routine applies the elementary transformation to +* a non-pivot row of the matrix V, it stores the corresponding element +* to the matrix F in order to keep the main equality A = F*V. +* +* The routine assumes that on entry the matrices L = P*F*inv(P) and +* U = P*V*Q are the following: +* +* 1 k 1 k n +* 1 1 . . . . . . . . . 1 x x x x x x x x x x +* x 1 . . . . . . . . . x x x x x x x x x +* x x 1 . . . . . . . . . x x x x x x x x +* x x x 1 . . . . . . . . . x x x x x x x +* k x x x x 1 . . . . . k . . . . * * * * * * +* x x x x _ 1 . . . . . . . . # * * * * * +* x x x x _ . 1 . . . . . . . # * * * * * +* x x x x _ . . 1 . . . . . . # * * * * * +* x x x x _ . . . 1 . . . . . # * * * * * +* n x x x x _ . . . . 1 n . . . . # * * * * * +* +* matrix L matrix U +* +* where rows and columns of the matrix U with numbers k, k+1, ..., n +* form the active submatrix (eliminated elements are marked by '#' and +* other elements of the active submatrix are marked by '*'). Note that +* each eliminated non-zero element u[i,k] of the matrix U gives the +* corresponding element l[i,k] of the matrix L (marked by '_'). +* +* Actually all operations are performed on the matrix V. Should note +* that the row-wise representation corresponds to the matrix V, but the +* column-wise representation corresponds to the active submatrix of the +* matrix V, i.e. elements of the matrix V, which doesn't belong to the +* active submatrix, are missing from the column linked lists. +* +* Let u[k,k] = v[p,q] be the pivot. In order to eliminate subdiagonal +* elements u[i',k] = v[i,q], i' = k+1, k+2, ..., n, the routine applies +* the following elementary gaussian transformations: +* +* (i-th row of V) := (i-th row of V) - f[i,p] * (p-th row of V), +* +* where f[i,p] = v[i,q] / v[p,q] is a gaussian multiplier. +* +* Additionally, in order to keep the main equality A = F*V, each time +* when the routine applies the transformation to i-th row of the matrix +* V, it also adds f[i,p] as a new element to the matrix F. +* +* IMPORTANT: On entry the working arrays flag and work should contain +* zeros. This status is provided by the routine on exit. */ + +static void eliminate(LUX *lux, LUXWKA *wka, LUXELM *piv, int flag[], + mpq_t work[]) +{ DMP *pool = lux->pool; + LUXELM **F_row = lux->F_row; + LUXELM **F_col = lux->F_col; + mpq_t *V_piv = lux->V_piv; + LUXELM **V_row = lux->V_row; + LUXELM **V_col = lux->V_col; + int *R_len = wka->R_len; + int *R_head = wka->R_head; + int *R_prev = wka->R_prev; + int *R_next = wka->R_next; + int *C_len = wka->C_len; + int *C_head = wka->C_head; + int *C_prev = wka->C_prev; + int *C_next = wka->C_next; + LUXELM *fip, *vij, *vpj, *viq, *next; + mpq_t temp; + int i, j, p, q; + mpq_init(temp); + /* determine row and column indices of the pivot v[p,q] */ + xassert(piv != NULL); + p = piv->i, q = piv->j; + /* remove p-th (pivot) row from the active set; it will never + return there */ + if (R_prev[p] == 0) + R_head[R_len[p]] = R_next[p]; + else + R_next[R_prev[p]] = R_next[p]; + if (R_next[p] == 0) + ; + else + R_prev[R_next[p]] = R_prev[p]; + /* remove q-th (pivot) column from the active set; it will never + return there */ + if (C_prev[q] == 0) + C_head[C_len[q]] = C_next[q]; + else + C_next[C_prev[q]] = C_next[q]; + if (C_next[q] == 0) + ; + else + C_prev[C_next[q]] = C_prev[q]; + /* store the pivot value in a separate array */ + mpq_set(V_piv[p], piv->val); + /* remove the pivot from p-th row */ + if (piv->r_prev == NULL) + V_row[p] = piv->r_next; + else + piv->r_prev->r_next = piv->r_next; + if (piv->r_next == NULL) + ; + else + piv->r_next->r_prev = piv->r_prev; + R_len[p]--; + /* remove the pivot from q-th column */ + if (piv->c_prev == NULL) + V_col[q] = piv->c_next; + else + piv->c_prev->c_next = piv->c_next; + if (piv->c_next == NULL) + ; + else + piv->c_next->c_prev = piv->c_prev; + C_len[q]--; + /* free the space occupied by the pivot */ + mpq_clear(piv->val); + dmp_free_atom(pool, piv, sizeof(LUXELM)); + /* walk through p-th (pivot) row, which already does not contain + the pivot v[p,q], and do the following... */ + for (vpj = V_row[p]; vpj != NULL; vpj = vpj->r_next) + { /* get column index of v[p,j] */ + j = vpj->j; + /* store v[p,j] in the working array */ + flag[j] = 1; + mpq_set(work[j], vpj->val); + /* remove j-th column from the active set; it will return there + later with a new length */ + if (C_prev[j] == 0) + C_head[C_len[j]] = C_next[j]; + else + C_next[C_prev[j]] = C_next[j]; + if (C_next[j] == 0) + ; + else + C_prev[C_next[j]] = C_prev[j]; + /* v[p,j] leaves the active submatrix, so remove it from j-th + column; however, v[p,j] is kept in p-th row */ + if (vpj->c_prev == NULL) + V_col[j] = vpj->c_next; + else + vpj->c_prev->c_next = vpj->c_next; + if (vpj->c_next == NULL) + ; + else + vpj->c_next->c_prev = vpj->c_prev; + C_len[j]--; + } + /* now walk through q-th (pivot) column, which already does not + contain the pivot v[p,q], and perform gaussian elimination */ + while (V_col[q] != NULL) + { /* element v[i,q] has to be eliminated */ + viq = V_col[q]; + /* get row index of v[i,q] */ + i = viq->i; + /* remove i-th row from the active set; later it will return + there with a new length */ + if (R_prev[i] == 0) + R_head[R_len[i]] = R_next[i]; + else + R_next[R_prev[i]] = R_next[i]; + if (R_next[i] == 0) + ; + else + R_prev[R_next[i]] = R_prev[i]; + /* compute gaussian multiplier f[i,p] = v[i,q] / v[p,q] and + store it in the matrix F */ + fip = dmp_get_atom(pool, sizeof(LUXELM)); + fip->i = i, fip->j = p; + mpq_init(fip->val); + mpq_div(fip->val, viq->val, V_piv[p]); + fip->r_prev = NULL; + fip->r_next = F_row[i]; + fip->c_prev = NULL; + fip->c_next = F_col[p]; + if (fip->r_next != NULL) fip->r_next->r_prev = fip; + if (fip->c_next != NULL) fip->c_next->c_prev = fip; + F_row[i] = F_col[p] = fip; + /* v[i,q] has to be eliminated, so remove it from i-th row */ + if (viq->r_prev == NULL) + V_row[i] = viq->r_next; + else + viq->r_prev->r_next = viq->r_next; + if (viq->r_next == NULL) + ; + else + viq->r_next->r_prev = viq->r_prev; + R_len[i]--; + /* and also from q-th column */ + V_col[q] = viq->c_next; + C_len[q]--; + /* free the space occupied by v[i,q] */ + mpq_clear(viq->val); + dmp_free_atom(pool, viq, sizeof(LUXELM)); + /* perform gaussian transformation: + (i-th row) := (i-th row) - f[i,p] * (p-th row) + note that now p-th row, which is in the working array, + does not contain the pivot v[p,q], and i-th row does not + contain the element v[i,q] to be eliminated */ + /* walk through i-th row and transform existing non-zero + elements */ + for (vij = V_row[i]; vij != NULL; vij = next) + { next = vij->r_next; + /* get column index of v[i,j] */ + j = vij->j; + /* v[i,j] := v[i,j] - f[i,p] * v[p,j] */ + if (flag[j]) + { /* v[p,j] != 0 */ + flag[j] = 0; + mpq_mul(temp, fip->val, work[j]); + mpq_sub(vij->val, vij->val, temp); + if (mpq_sgn(vij->val) == 0) + { /* new v[i,j] is zero, so remove it from the active + submatrix */ + /* remove v[i,j] from i-th row */ + if (vij->r_prev == NULL) + V_row[i] = vij->r_next; + else + vij->r_prev->r_next = vij->r_next; + if (vij->r_next == NULL) + ; + else + vij->r_next->r_prev = vij->r_prev; + R_len[i]--; + /* remove v[i,j] from j-th column */ + if (vij->c_prev == NULL) + V_col[j] = vij->c_next; + else + vij->c_prev->c_next = vij->c_next; + if (vij->c_next == NULL) + ; + else + vij->c_next->c_prev = vij->c_prev; + C_len[j]--; + /* free the space occupied by v[i,j] */ + mpq_clear(vij->val); + dmp_free_atom(pool, vij, sizeof(LUXELM)); + } + } + } + /* now flag is the pattern of the set v[p,*] \ v[i,*] */ + /* walk through p-th (pivot) row and create new elements in + i-th row, which appear due to fill-in */ + for (vpj = V_row[p]; vpj != NULL; vpj = vpj->r_next) + { j = vpj->j; + if (flag[j]) + { /* create new non-zero v[i,j] = 0 - f[i,p] * v[p,j] and + add it to i-th row and j-th column */ + vij = dmp_get_atom(pool, sizeof(LUXELM)); + vij->i = i, vij->j = j; + mpq_init(vij->val); + mpq_mul(vij->val, fip->val, work[j]); + mpq_neg(vij->val, vij->val); + vij->r_prev = NULL; + vij->r_next = V_row[i]; + vij->c_prev = NULL; + vij->c_next = V_col[j]; + if (vij->r_next != NULL) vij->r_next->r_prev = vij; + if (vij->c_next != NULL) vij->c_next->c_prev = vij; + V_row[i] = V_col[j] = vij; + R_len[i]++, C_len[j]++; + } + else + { /* there is no fill-in, because v[i,j] already exists in + i-th row; restore the flag, which was reset before */ + flag[j] = 1; + } + } + /* now i-th row has been completely transformed and can return + to the active set with a new length */ + R_prev[i] = 0; + R_next[i] = R_head[R_len[i]]; + if (R_next[i] != 0) R_prev[R_next[i]] = i; + R_head[R_len[i]] = i; + } + /* at this point q-th (pivot) column must be empty */ + xassert(C_len[q] == 0); + /* walk through p-th (pivot) row again and do the following... */ + for (vpj = V_row[p]; vpj != NULL; vpj = vpj->r_next) + { /* get column index of v[p,j] */ + j = vpj->j; + /* erase v[p,j] from the working array */ + flag[j] = 0; + mpq_set_si(work[j], 0, 1); + /* now j-th column has been completely transformed, so it can + return to the active list with a new length */ + C_prev[j] = 0; + C_next[j] = C_head[C_len[j]]; + if (C_next[j] != 0) C_prev[C_next[j]] = j; + C_head[C_len[j]] = j; + } + mpq_clear(temp); + /* return to the factorizing routine */ + return; +} + +/*********************************************************************** +* lux_decomp - compute LU-factorization +* +* SYNOPSIS +* +* #include "lux.h" +* int lux_decomp(LUX *lux, int (*col)(void *info, int j, int ind[], +* mpq_t val[]), void *info); +* +* DESCRIPTION +* +* The routine lux_decomp computes LU-factorization of a given square +* matrix A. +* +* The parameter lux specifies LU-factorization data structure built by +* means of the routine lux_create. +* +* The formal routine col specifies the original matrix A. In order to +* obtain j-th column of the matrix A the routine lux_decomp calls the +* routine col with the parameter j (1 <= j <= n, where n is the order +* of A). In response the routine col should store row indices and +* numerical values of non-zero elements of j-th column of A to the +* locations ind[1], ..., ind[len] and val[1], ..., val[len], resp., +* where len is the number of non-zeros in j-th column, which should be +* returned on exit. Neiter zero nor duplicate elements are allowed. +* +* The parameter info is a transit pointer passed to the formal routine +* col; it can be used for various purposes. +* +* RETURNS +* +* The routine lux_decomp returns the singularity flag. Zero flag means +* that the original matrix A is non-singular while non-zero flag means +* that A is (exactly!) singular. +* +* Note that LU-factorization is valid in both cases, however, in case +* of singularity some rows of the matrix V (including pivot elements) +* will be empty. +* +* REPAIRING SINGULAR MATRIX +* +* If the routine lux_decomp returns non-zero flag, it provides all +* necessary information that can be used for "repairing" the matrix A, +* where "repairing" means replacing linearly dependent columns of the +* matrix A by appropriate columns of the unity matrix. This feature is +* needed when the routine lux_decomp is used for reinverting the basis +* matrix within the simplex method procedure. +* +* On exit linearly dependent columns of the matrix U have the numbers +* rank+1, rank+2, ..., n, where rank is the exact rank of the matrix A +* stored by the routine to the member lux->rank. The correspondence +* between columns of A and U is the same as between columns of V and U. +* Thus, linearly dependent columns of the matrix A have the numbers +* Q_col[rank+1], Q_col[rank+2], ..., Q_col[n], where Q_col is an array +* representing the permutation matrix Q in column-like format. It is +* understood that each j-th linearly dependent column of the matrix U +* should be replaced by the unity vector, where all elements are zero +* except the unity diagonal element u[j,j]. On the other hand j-th row +* of the matrix U corresponds to the row of the matrix V (and therefore +* of the matrix A) with the number P_row[j], where P_row is an array +* representing the permutation matrix P in row-like format. Thus, each +* j-th linearly dependent column of the matrix U should be replaced by +* a column of the unity matrix with the number P_row[j]. +* +* The code that repairs the matrix A may look like follows: +* +* for (j = rank+1; j <= n; j++) +* { replace column Q_col[j] of the matrix A by column P_row[j] of +* the unity matrix; +* } +* +* where rank, P_row, and Q_col are members of the structure LUX. */ + +int lux_decomp(LUX *lux, int (*col)(void *info, int j, int ind[], + mpq_t val[]), void *info) +{ int n = lux->n; + LUXELM **V_row = lux->V_row; + LUXELM **V_col = lux->V_col; + int *P_row = lux->P_row; + int *P_col = lux->P_col; + int *Q_row = lux->Q_row; + int *Q_col = lux->Q_col; + LUXELM *piv, *vij; + LUXWKA *wka; + int i, j, k, p, q, t, *flag; + mpq_t *work; + /* allocate working area */ + wka = xmalloc(sizeof(LUXWKA)); + wka->R_len = xcalloc(1+n, sizeof(int)); + wka->R_head = xcalloc(1+n, sizeof(int)); + wka->R_prev = xcalloc(1+n, sizeof(int)); + wka->R_next = xcalloc(1+n, sizeof(int)); + wka->C_len = xcalloc(1+n, sizeof(int)); + wka->C_head = xcalloc(1+n, sizeof(int)); + wka->C_prev = xcalloc(1+n, sizeof(int)); + wka->C_next = xcalloc(1+n, sizeof(int)); + /* initialize LU-factorization data structures */ + initialize(lux, col, info, wka); + /* allocate working arrays */ + flag = xcalloc(1+n, sizeof(int)); + work = xcalloc(1+n, sizeof(mpq_t)); + for (k = 1; k <= n; k++) + { flag[k] = 0; + mpq_init(work[k]); + } + /* main elimination loop */ + for (k = 1; k <= n; k++) + { /* choose a pivot element v[p,q] */ + piv = find_pivot(lux, wka); + if (piv == NULL) + { /* no pivot can be chosen, because the active submatrix is + empty */ + break; + } + /* determine row and column indices of the pivot element */ + p = piv->i, q = piv->j; + /* let v[p,q] correspond to u[i',j']; permute k-th and i'-th + rows and k-th and j'-th columns of the matrix U = P*V*Q to + move the element u[i',j'] to the position u[k,k] */ + i = P_col[p], j = Q_row[q]; + xassert(k <= i && i <= n && k <= j && j <= n); + /* permute k-th and i-th rows of the matrix U */ + t = P_row[k]; + P_row[i] = t, P_col[t] = i; + P_row[k] = p, P_col[p] = k; + /* permute k-th and j-th columns of the matrix U */ + t = Q_col[k]; + Q_col[j] = t, Q_row[t] = j; + Q_col[k] = q, Q_row[q] = k; + /* eliminate subdiagonal elements of k-th column of the matrix + U = P*V*Q using the pivot element u[k,k] = v[p,q] */ + eliminate(lux, wka, piv, flag, work); + } + /* determine the rank of A (and V) */ + lux->rank = k - 1; + /* free working arrays */ + xfree(flag); + for (k = 1; k <= n; k++) mpq_clear(work[k]); + xfree(work); + /* build column lists of the matrix V using its row lists */ + for (j = 1; j <= n; j++) + xassert(V_col[j] == NULL); + for (i = 1; i <= n; i++) + { for (vij = V_row[i]; vij != NULL; vij = vij->r_next) + { j = vij->j; + vij->c_prev = NULL; + vij->c_next = V_col[j]; + if (vij->c_next != NULL) vij->c_next->c_prev = vij; + V_col[j] = vij; + } + } + /* free working area */ + xfree(wka->R_len); + xfree(wka->R_head); + xfree(wka->R_prev); + xfree(wka->R_next); + xfree(wka->C_len); + xfree(wka->C_head); + xfree(wka->C_prev); + xfree(wka->C_next); + xfree(wka); + /* return to the calling program */ + return (lux->rank < n); +} + +/*********************************************************************** +* lux_f_solve - solve system F*x = b or F'*x = b +* +* SYNOPSIS +* +* #include "lux.h" +* void lux_f_solve(LUX *lux, int tr, mpq_t x[]); +* +* DESCRIPTION +* +* The routine lux_f_solve solves either the system F*x = b (if the +* flag tr is zero) or the system F'*x = b (if the flag tr is non-zero), +* where the matrix F is a component of LU-factorization specified by +* the parameter lux, F' is a matrix transposed to F. +* +* On entry the array x should contain elements of the right-hand side +* vector b in locations x[1], ..., x[n], where n is the order of the +* matrix F. On exit this array will contain elements of the solution +* vector x in the same locations. */ + +void lux_f_solve(LUX *lux, int tr, mpq_t x[]) +{ int n = lux->n; + LUXELM **F_row = lux->F_row; + LUXELM **F_col = lux->F_col; + int *P_row = lux->P_row; + LUXELM *fik, *fkj; + int i, j, k; + mpq_t temp; + mpq_init(temp); + if (!tr) + { /* solve the system F*x = b */ + for (j = 1; j <= n; j++) + { k = P_row[j]; + if (mpq_sgn(x[k]) != 0) + { for (fik = F_col[k]; fik != NULL; fik = fik->c_next) + { mpq_mul(temp, fik->val, x[k]); + mpq_sub(x[fik->i], x[fik->i], temp); + } + } + } + } + else + { /* solve the system F'*x = b */ + for (i = n; i >= 1; i--) + { k = P_row[i]; + if (mpq_sgn(x[k]) != 0) + { for (fkj = F_row[k]; fkj != NULL; fkj = fkj->r_next) + { mpq_mul(temp, fkj->val, x[k]); + mpq_sub(x[fkj->j], x[fkj->j], temp); + } + } + } + } + mpq_clear(temp); + return; +} + +/*********************************************************************** +* lux_v_solve - solve system V*x = b or V'*x = b +* +* SYNOPSIS +* +* #include "lux.h" +* void lux_v_solve(LUX *lux, int tr, double x[]); +* +* DESCRIPTION +* +* The routine lux_v_solve solves either the system V*x = b (if the +* flag tr is zero) or the system V'*x = b (if the flag tr is non-zero), +* where the matrix V is a component of LU-factorization specified by +* the parameter lux, V' is a matrix transposed to V. +* +* On entry the array x should contain elements of the right-hand side +* vector b in locations x[1], ..., x[n], where n is the order of the +* matrix V. On exit this array will contain elements of the solution +* vector x in the same locations. */ + +void lux_v_solve(LUX *lux, int tr, mpq_t x[]) +{ int n = lux->n; + mpq_t *V_piv = lux->V_piv; + LUXELM **V_row = lux->V_row; + LUXELM **V_col = lux->V_col; + int *P_row = lux->P_row; + int *Q_col = lux->Q_col; + LUXELM *vij; + int i, j, k; + mpq_t *b, temp; + b = xcalloc(1+n, sizeof(mpq_t)); + for (k = 1; k <= n; k++) + mpq_init(b[k]), mpq_set(b[k], x[k]), mpq_set_si(x[k], 0, 1); + mpq_init(temp); + if (!tr) + { /* solve the system V*x = b */ + for (k = n; k >= 1; k--) + { i = P_row[k], j = Q_col[k]; + if (mpq_sgn(b[i]) != 0) + { mpq_set(x[j], b[i]); + mpq_div(x[j], x[j], V_piv[i]); + for (vij = V_col[j]; vij != NULL; vij = vij->c_next) + { mpq_mul(temp, vij->val, x[j]); + mpq_sub(b[vij->i], b[vij->i], temp); + } + } + } + } + else + { /* solve the system V'*x = b */ + for (k = 1; k <= n; k++) + { i = P_row[k], j = Q_col[k]; + if (mpq_sgn(b[j]) != 0) + { mpq_set(x[i], b[j]); + mpq_div(x[i], x[i], V_piv[i]); + for (vij = V_row[i]; vij != NULL; vij = vij->r_next) + { mpq_mul(temp, vij->val, x[i]); + mpq_sub(b[vij->j], b[vij->j], temp); + } + } + } + } + for (k = 1; k <= n; k++) mpq_clear(b[k]); + mpq_clear(temp); + xfree(b); + return; +} + +/*********************************************************************** +* lux_solve - solve system A*x = b or A'*x = b +* +* SYNOPSIS +* +* #include "lux.h" +* void lux_solve(LUX *lux, int tr, mpq_t x[]); +* +* DESCRIPTION +* +* The routine lux_solve solves either the system A*x = b (if the flag +* tr is zero) or the system A'*x = b (if the flag tr is non-zero), +* where the parameter lux specifies LU-factorization of the matrix A, +* A' is a matrix transposed to A. +* +* On entry the array x should contain elements of the right-hand side +* vector b in locations x[1], ..., x[n], where n is the order of the +* matrix A. On exit this array will contain elements of the solution +* vector x in the same locations. */ + +void lux_solve(LUX *lux, int tr, mpq_t x[]) +{ if (lux->rank < lux->n) + xfault("lux_solve: LU-factorization has incomplete rank\n"); + if (!tr) + { /* A = F*V, therefore inv(A) = inv(V)*inv(F) */ + lux_f_solve(lux, 0, x); + lux_v_solve(lux, 0, x); + } + else + { /* A' = V'*F', therefore inv(A') = inv(F')*inv(V') */ + lux_v_solve(lux, 1, x); + lux_f_solve(lux, 1, x); + } + return; +} + +/*********************************************************************** +* lux_delete - delete LU-factorization +* +* SYNOPSIS +* +* #include "lux.h" +* void lux_delete(LUX *lux); +* +* DESCRIPTION +* +* The routine lux_delete deletes LU-factorization data structure, +* which the parameter lux points to, freeing all the memory allocated +* to this object. */ + +void lux_delete(LUX *lux) +{ int n = lux->n; + LUXELM *fij, *vij; + int i; + for (i = 1; i <= n; i++) + { for (fij = lux->F_row[i]; fij != NULL; fij = fij->r_next) + mpq_clear(fij->val); + mpq_clear(lux->V_piv[i]); + for (vij = lux->V_row[i]; vij != NULL; vij = vij->r_next) + mpq_clear(vij->val); + } + dmp_delete_pool(lux->pool); + xfree(lux->F_row); + xfree(lux->F_col); + xfree(lux->V_piv); + xfree(lux->V_row); + xfree(lux->V_col); + xfree(lux->P_row); + xfree(lux->P_col); + xfree(lux->Q_row); + xfree(lux->Q_col); + xfree(lux); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/lux.h b/resources/3rdparty/glpk-4.57/src/lux.h new file mode 100644 index 000000000..6efce3636 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/lux.h @@ -0,0 +1,220 @@ +/* lux.h (LU-factorization, rational arithmetic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef LUX_H +#define LUX_H + +#include "dmp.h" +#include "glpgmp.h" + +/*********************************************************************** +* The structure LUX defines LU-factorization of a square matrix A, +* which is the following quartet: +* +* [A] = (F, V, P, Q), (1) +* +* where F and V are such matrices that +* +* A = F * V, (2) +* +* and P and Q are such permutation matrices that the matrix +* +* L = P * F * inv(P) (3) +* +* is lower triangular with unity diagonal, and the matrix +* +* U = P * V * Q (4) +* +* is upper triangular. All the matrices have the order n. +* +* The matrices F and V are stored in row/column-wise sparse format as +* row and column linked lists of non-zero elements. Unity elements on +* the main diagonal of the matrix F are not stored. Pivot elements of +* the matrix V (that correspond to diagonal elements of the matrix U) +* are also missing from the row and column lists and stored separately +* in an ordinary array. +* +* The permutation matrices P and Q are stored as ordinary arrays using +* both row- and column-like formats. +* +* The matrices L and U being completely defined by the matrices F, V, +* P, and Q are not stored explicitly. +* +* It is easy to show that the factorization (1)-(3) is some version of +* LU-factorization. Indeed, from (3) and (4) it follows that: +* +* F = inv(P) * L * P, +* +* V = inv(P) * U * inv(Q), +* +* and substitution into (2) gives: +* +* A = F * V = inv(P) * L * U * inv(Q). +* +* For more details see the program documentation. */ + +typedef struct LUX LUX; +typedef struct LUXELM LUXELM; +typedef struct LUXWKA LUXWKA; + +struct LUX +{ /* LU-factorization of a square matrix */ + int n; + /* the order of matrices A, F, V, P, Q */ + DMP *pool; + /* memory pool for elements of matrices F and V */ + LUXELM **F_row; /* LUXELM *F_row[1+n]; */ + /* F_row[0] is not used; + F_row[i], 1 <= i <= n, is a pointer to the list of elements in + i-th row of matrix F (diagonal elements are not stored) */ + LUXELM **F_col; /* LUXELM *F_col[1+n]; */ + /* F_col[0] is not used; + F_col[j], 1 <= j <= n, is a pointer to the list of elements in + j-th column of matrix F (diagonal elements are not stored) */ + mpq_t *V_piv; /* mpq_t V_piv[1+n]; */ + /* V_piv[0] is not used; + V_piv[p], 1 <= p <= n, is a pivot element v[p,q] corresponding + to a diagonal element u[k,k] of matrix U = P*V*Q (used on k-th + elimination step, k = 1, 2, ..., n) */ + LUXELM **V_row; /* LUXELM *V_row[1+n]; */ + /* V_row[0] is not used; + V_row[i], 1 <= i <= n, is a pointer to the list of elements in + i-th row of matrix V (except pivot elements) */ + LUXELM **V_col; /* LUXELM *V_col[1+n]; */ + /* V_col[0] is not used; + V_col[j], 1 <= j <= n, is a pointer to the list of elements in + j-th column of matrix V (except pivot elements) */ + int *P_row; /* int P_row[1+n]; */ + /* P_row[0] is not used; + P_row[i] = j means that p[i,j] = 1, where p[i,j] is an element + of permutation matrix P */ + int *P_col; /* int P_col[1+n]; */ + /* P_col[0] is not used; + P_col[j] = i means that p[i,j] = 1, where p[i,j] is an element + of permutation matrix P */ + /* if i-th row or column of matrix F is i'-th row or column of + matrix L = P*F*inv(P), or if i-th row of matrix V is i'-th row + of matrix U = P*V*Q, then P_row[i'] = i and P_col[i] = i' */ + int *Q_row; /* int Q_row[1+n]; */ + /* Q_row[0] is not used; + Q_row[i] = j means that q[i,j] = 1, where q[i,j] is an element + of permutation matrix Q */ + int *Q_col; /* int Q_col[1+n]; */ + /* Q_col[0] is not used; + Q_col[j] = i means that q[i,j] = 1, where q[i,j] is an element + of permutation matrix Q */ + /* if j-th column of matrix V is j'-th column of matrix U = P*V*Q, + then Q_row[j] = j' and Q_col[j'] = j */ + int rank; + /* the (exact) rank of matrices A and V */ +}; + +struct LUXELM +{ /* element of matrix F or V */ + int i; + /* row index, 1 <= i <= m */ + int j; + /* column index, 1 <= j <= n */ + mpq_t val; + /* numeric (non-zero) element value */ + LUXELM *r_prev; + /* pointer to previous element in the same row */ + LUXELM *r_next; + /* pointer to next element in the same row */ + LUXELM *c_prev; + /* pointer to previous element in the same column */ + LUXELM *c_next; + /* pointer to next element in the same column */ +}; + +struct LUXWKA +{ /* working area (used only during factorization) */ + /* in order to efficiently implement Markowitz strategy and Duff + search technique there are two families {R[0], R[1], ..., R[n]} + and {C[0], C[1], ..., C[n]}; member R[k] is a set of active + rows of matrix V having k non-zeros, and member C[k] is a set + of active columns of matrix V having k non-zeros (in the active + submatrix); each set R[k] and C[k] is implemented as a separate + doubly linked list */ + int *R_len; /* int R_len[1+n]; */ + /* R_len[0] is not used; + R_len[i], 1 <= i <= n, is the number of non-zero elements in + i-th row of matrix V (that is the length of i-th row) */ + int *R_head; /* int R_head[1+n]; */ + /* R_head[k], 0 <= k <= n, is the number of a first row, which is + active and whose length is k */ + int *R_prev; /* int R_prev[1+n]; */ + /* R_prev[0] is not used; + R_prev[i], 1 <= i <= n, is the number of a previous row, which + is active and has the same length as i-th row */ + int *R_next; /* int R_next[1+n]; */ + /* R_prev[0] is not used; + R_prev[i], 1 <= i <= n, is the number of a next row, which is + active and has the same length as i-th row */ + int *C_len; /* int C_len[1+n]; */ + /* C_len[0] is not used; + C_len[j], 1 <= j <= n, is the number of non-zero elements in + j-th column of the active submatrix of matrix V (that is the + length of j-th column in the active submatrix) */ + int *C_head; /* int C_head[1+n]; */ + /* C_head[k], 0 <= k <= n, is the number of a first column, which + is active and whose length is k */ + int *C_prev; /* int C_prev[1+n]; */ + /* C_prev[0] is not used; + C_prev[j], 1 <= j <= n, is the number of a previous column, + which is active and has the same length as j-th column */ + int *C_next; /* int C_next[1+n]; */ + /* C_next[0] is not used; + C_next[j], 1 <= j <= n, is the number of a next column, which + is active and has the same length as j-th column */ +}; + +#define lux_create _glp_lux_create +LUX *lux_create(int n); +/* create LU-factorization */ + +#define lux_decomp _glp_lux_decomp +int lux_decomp(LUX *lux, int (*col)(void *info, int j, int ind[], + mpq_t val[]), void *info); +/* compute LU-factorization */ + +#define lux_f_solve _glp_lux_f_solve +void lux_f_solve(LUX *lux, int tr, mpq_t x[]); +/* solve system F*x = b or F'*x = b */ + +#define lux_v_solve _glp_lux_v_solve +void lux_v_solve(LUX *lux, int tr, mpq_t x[]); +/* solve system V*x = b or V'*x = b */ + +#define lux_solve _glp_lux_solve +void lux_solve(LUX *lux, int tr, mpq_t x[]); +/* solve system A*x = b or A'*x = b */ + +#define lux_delete _glp_lux_delete +void lux_delete(LUX *lux); +/* delete LU-factorization */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/minisat/LICENSE b/resources/3rdparty/glpk-4.57/src/minisat/LICENSE new file mode 100644 index 000000000..8a6b9f362 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/minisat/LICENSE @@ -0,0 +1,20 @@ +MiniSat -- Copyright (c) 2005, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/resources/3rdparty/glpk-4.57/src/minisat/README b/resources/3rdparty/glpk-4.57/src/minisat/README new file mode 100644 index 000000000..c183c7d61 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/minisat/README @@ -0,0 +1,22 @@ +NOTE: Files in this subdirectory are NOT part of the GLPK package, but + are used with GLPK. + + The original code was modified according to GLPK requirements by + Andrew Makhorin . +************************************************************************ +MiniSat-C v1.14.1 +======================================== + +* Fixed some serious bugs. +* Tweaked to be Visual Studio friendly (by Alan Mishchenko). + This disabled reading of gzipped DIMACS files and signal handling, + but none of these features are essential (and easy to re-enable, if + wanted). + +MiniSat-C v1.14 +======================================== + +Ok, we get it. You hate C++. You hate templates. We agree; C++ is a +seriously messed up language. Although we are more pragmatic about the +quirks and maldesigns in C++, we sympathize with you. So here is a +pure C version of MiniSat, put together by Niklas Sorensson. diff --git a/resources/3rdparty/glpk-4.57/src/minisat/minisat.c b/resources/3rdparty/glpk-4.57/src/minisat/minisat.c new file mode 100644 index 000000000..f242d838a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/minisat/minisat.c @@ -0,0 +1,1299 @@ +/* minisat.c */ + +/* Modified by Andrew Makhorin , August 2011 */ + +/*********************************************************************** +* MiniSat -- Copyright (c) 2005, Niklas Sorensson +* http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat/ +* +* Permission is hereby granted, free of charge, to any person +* obtaining a copy of this software and associated documentation files +* (the "Software"), to deal in the Software without restriction, +* including without limitation the rights to use, copy, modify, merge, +* publish, distribute, sublicense, and/or sell copies of the Software, +* and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +***********************************************************************/ +/* Modified to compile with MS Visual Studio 6.0 by Alan Mishchenko */ + +#include "env.h" +#include "minisat.h" + +#if 1 /* by mao */ +static void *ymalloc(int size) +{ void *ptr; + xassert(size > 0); + ptr = malloc(size); + if (ptr == NULL) + xerror("MiniSat: no memory available\n"); + return ptr; +} + +static void *yrealloc(void *ptr, int size) +{ xassert(size > 0); + if (ptr == NULL) + ptr = malloc(size); + else + ptr = realloc(ptr, size); + if (ptr == NULL) + xerror("MiniSat: no memory available\n"); + return ptr; +} + +static void yfree(void *ptr) +{ xassert(ptr != NULL); + free(ptr); + return; +} + +#define assert xassert +#define printf xprintf +#define fflush(f) /* nop */ +#define malloc ymalloc +#define realloc yrealloc +#define free yfree +#define inline /* empty */ +#endif + +/*====================================================================*/ +/* Debug: */ + +#if 0 +#define VERBOSEDEBUG 1 +#endif + +/* For derivation output (verbosity level 2) */ +#define L_IND "%-*d" +#define L_ind solver_dlevel(s)*3+3,solver_dlevel(s) +#define L_LIT "%sx%d" +#define L_lit(p) lit_sign(p)?"~":"", (lit_var(p)) + +#if 0 /* by mao */ +/* Just like 'assert()' but expression will be evaluated in the release + version as well. */ +static inline void check(int expr) { assert(expr); } +#endif + +#if 0 /* by mao */ +static void printlits(lit* begin, lit* end) +{ + int i; + for (i = 0; i < end - begin; i++) + printf(L_LIT" ",L_lit(begin[i])); +} +#endif + +/*====================================================================*/ +/* Random numbers: */ + +/* Returns a random float 0 <= x < 1. Seed must never be 0. */ +static inline double drand(double* seed) { + int q; + *seed *= 1389796; + q = (int)(*seed / 2147483647); + *seed -= (double)q * 2147483647; + return *seed / 2147483647; } + +/* Returns a random integer 0 <= x < size. Seed must never be 0. */ +static inline int irand(double* seed, int size) { + return (int)(drand(seed) * size); } + +/*====================================================================*/ +/* Predeclarations: */ + +static void sort(void** array, int size, + int(*comp)(const void *, const void *)); + +/*====================================================================*/ +/* Clause datatype + minor functions: */ + +#if 0 /* by mao; see minisat.h */ +struct clause_t +{ + int size_learnt; + lit lits[0]; +}; +#endif + +#define clause_size(c) ((c)->size_learnt >> 1) + +#define clause_begin(c) ((c)->lits) + +#define clause_learnt(c) ((c)->size_learnt & 1) + +#define clause_activity(c) \ + (*((float*)&(c)->lits[(c)->size_learnt>>1])) + +#define clause_setactivity(c, a) \ + (void)(*((float*)&(c)->lits[(c)->size_learnt>>1]) = (a)) + +/*====================================================================*/ +/* Encode literals in clause pointers: */ + +#define clause_from_lit(l) \ + (clause*)((unsigned long)(l) + (unsigned long)(l) + 1) + +#define clause_is_lit(c) \ + ((unsigned long)(c) & 1) + +#define clause_read_lit(c) \ + (lit)((unsigned long)(c) >> 1) + +/*====================================================================*/ +/* Simple helpers: */ + +#define solver_dlevel(s) \ + (int)veci_size(&(s)->trail_lim) + +#define solver_read_wlist(s, l) \ + (vecp *)(&(s)->wlists[l]) + +static inline void vecp_remove(vecp* v, void* e) +{ + void** ws = vecp_begin(v); + int j = 0; + + for (; ws[j] != e ; j++); + assert(j < vecp_size(v)); + for (; j < vecp_size(v)-1; j++) ws[j] = ws[j+1]; + vecp_resize(v,vecp_size(v)-1); +} + +/*====================================================================*/ +/* Variable order functions: */ + +static inline void order_update(solver* s, int v) +{ /* updateorder */ + int* orderpos = s->orderpos; + double* activity = s->activity; + int* heap = veci_begin(&s->order); + int i = orderpos[v]; + int x = heap[i]; + int parent = (i - 1) / 2; + + assert(s->orderpos[v] != -1); + + while (i != 0 && activity[x] > activity[heap[parent]]){ + heap[i] = heap[parent]; + orderpos[heap[i]] = i; + i = parent; + parent = (i - 1) / 2; + } + heap[i] = x; + orderpos[x] = i; +} + +#define order_assigned(s, v) /* nop */ + +static inline void order_unassigned(solver* s, int v) +{ /* undoorder */ + int* orderpos = s->orderpos; + if (orderpos[v] == -1){ + orderpos[v] = veci_size(&s->order); + veci_push(&s->order,v); + order_update(s,v); + } +} + +static int order_select(solver* s, float random_var_freq) +{ /* selectvar */ + int* heap; + double* activity; + int* orderpos; + + lbool* values = s->assigns; + + /* Random decision: */ + if (drand(&s->random_seed) < random_var_freq){ + int next = irand(&s->random_seed,s->size); + assert(next >= 0 && next < s->size); + if (values[next] == l_Undef) + return next; + } + + /* Activity based decision: */ + + heap = veci_begin(&s->order); + activity = s->activity; + orderpos = s->orderpos; + + while (veci_size(&s->order) > 0){ + int next = heap[0]; + int size = veci_size(&s->order)-1; + int x = heap[size]; + + veci_resize(&s->order,size); + + orderpos[next] = -1; + + if (size > 0){ + double act = activity[x]; + + int i = 0; + int child = 1; + + while (child < size){ + if (child+1 < size + && activity[heap[child]] < activity[heap[child+1]]) + child++; + + assert(child < size); + + if (act >= activity[heap[child]]) + break; + + heap[i] = heap[child]; + orderpos[heap[i]] = i; + i = child; + child = 2 * child + 1; + } + heap[i] = x; + orderpos[heap[i]] = i; + } + + if (values[next] == l_Undef) + return next; + } + + return var_Undef; +} + +/*====================================================================*/ +/* Activity functions: */ + +static inline void act_var_rescale(solver* s) { + double* activity = s->activity; + int i; + for (i = 0; i < s->size; i++) + activity[i] *= 1e-100; + s->var_inc *= 1e-100; +} + +static inline void act_var_bump(solver* s, int v) { + double* activity = s->activity; + if ((activity[v] += s->var_inc) > 1e100) + act_var_rescale(s); + + /* printf("bump %d %f\n", v-1, activity[v]); */ + + if (s->orderpos[v] != -1) + order_update(s,v); + +} + +static inline void act_var_decay(solver* s) + { s->var_inc *= s->var_decay; } + +static inline void act_clause_rescale(solver* s) { + clause** cs = (clause**)vecp_begin(&s->learnts); + int i; + for (i = 0; i < vecp_size(&s->learnts); i++){ + float a = clause_activity(cs[i]); + clause_setactivity(cs[i], a * (float)1e-20); + } + s->cla_inc *= (float)1e-20; +} + +static inline void act_clause_bump(solver* s, clause *c) { + float a = clause_activity(c) + s->cla_inc; + clause_setactivity(c,a); + if (a > 1e20) act_clause_rescale(s); +} + +static inline void act_clause_decay(solver* s) + { s->cla_inc *= s->cla_decay; } + +/*====================================================================*/ +/* Clause functions: */ + +/* pre: size > 1 && no variable occurs twice + */ +static clause* clause_new(solver* s, lit* begin, lit* end, int learnt) +{ + int size; + clause* c; + int i; + + assert(end - begin > 1); + assert(learnt >= 0 && learnt < 2); + size = end - begin; + c = (clause*)malloc(sizeof(clause) + + sizeof(lit) * size + learnt * sizeof(float)); + c->size_learnt = (size << 1) | learnt; +#if 0 /* by mao; meaningless non-portable check */ + assert(((unsigned int)c & 1) == 0); +#endif + + for (i = 0; i < size; i++) + c->lits[i] = begin[i]; + + if (learnt) + *((float*)&c->lits[size]) = 0.0; + + assert(begin[0] >= 0); + assert(begin[0] < s->size*2); + assert(begin[1] >= 0); + assert(begin[1] < s->size*2); + + assert(lit_neg(begin[0]) < s->size*2); + assert(lit_neg(begin[1]) < s->size*2); + + /* vecp_push(solver_read_wlist(s,lit_neg(begin[0])),(void*)c); */ + /* vecp_push(solver_read_wlist(s,lit_neg(begin[1])),(void*)c); */ + + vecp_push(solver_read_wlist(s,lit_neg(begin[0])), + (void*)(size > 2 ? c : clause_from_lit(begin[1]))); + vecp_push(solver_read_wlist(s,lit_neg(begin[1])), + (void*)(size > 2 ? c : clause_from_lit(begin[0]))); + + return c; +} + +static void clause_remove(solver* s, clause* c) +{ + lit* lits = clause_begin(c); + assert(lit_neg(lits[0]) < s->size*2); + assert(lit_neg(lits[1]) < s->size*2); + + /* vecp_remove(solver_read_wlist(s,lit_neg(lits[0])),(void*)c); */ + /* vecp_remove(solver_read_wlist(s,lit_neg(lits[1])),(void*)c); */ + + assert(lits[0] < s->size*2); + vecp_remove(solver_read_wlist(s,lit_neg(lits[0])), + (void*)(clause_size(c) > 2 ? c : clause_from_lit(lits[1]))); + vecp_remove(solver_read_wlist(s,lit_neg(lits[1])), + (void*)(clause_size(c) > 2 ? c : clause_from_lit(lits[0]))); + + if (clause_learnt(c)){ + s->stats.learnts--; + s->stats.learnts_literals -= clause_size(c); + }else{ + s->stats.clauses--; + s->stats.clauses_literals -= clause_size(c); + } + + free(c); +} + +static lbool clause_simplify(solver* s, clause* c) +{ + lit* lits = clause_begin(c); + lbool* values = s->assigns; + int i; + + assert(solver_dlevel(s) == 0); + + for (i = 0; i < clause_size(c); i++){ + lbool sig = !lit_sign(lits[i]); sig += sig - 1; + if (values[lit_var(lits[i])] == sig) + return l_True; + } + return l_False; +} + +/*====================================================================*/ +/* Minor (solver) functions: */ + +void solver_setnvars(solver* s,int n) +{ + int var; + + if (s->cap < n){ + + while (s->cap < n) s->cap = s->cap*2+1; + + s->wlists = (vecp*) realloc(s->wlists, + sizeof(vecp)*s->cap*2); + s->activity = (double*) realloc(s->activity, + sizeof(double)*s->cap); + s->assigns = (lbool*) realloc(s->assigns, + sizeof(lbool)*s->cap); + s->orderpos = (int*) realloc(s->orderpos, + sizeof(int)*s->cap); + s->reasons = (clause**)realloc(s->reasons, + sizeof(clause*)*s->cap); + s->levels = (int*) realloc(s->levels, + sizeof(int)*s->cap); + s->tags = (lbool*) realloc(s->tags, + sizeof(lbool)*s->cap); + s->trail = (lit*) realloc(s->trail, + sizeof(lit)*s->cap); + } + + for (var = s->size; var < n; var++){ + vecp_new(&s->wlists[2*var]); + vecp_new(&s->wlists[2*var+1]); + s->activity [var] = 0; + s->assigns [var] = l_Undef; + s->orderpos [var] = veci_size(&s->order); + s->reasons [var] = (clause*)0; + s->levels [var] = 0; + s->tags [var] = l_Undef; + + /* does not hold because variables enqueued at top level will + not be reinserted in the heap + assert(veci_size(&s->order) == var); + */ + veci_push(&s->order,var); + order_update(s, var); + } + + s->size = n > s->size ? n : s->size; +} + +static inline bool enqueue(solver* s, lit l, clause* from) +{ + lbool* values = s->assigns; + int v = lit_var(l); + lbool val = values[v]; + lbool sig; +#ifdef VERBOSEDEBUG + printf(L_IND"enqueue("L_LIT")\n", L_ind, L_lit(l)); +#endif + + /* lbool */ sig = !lit_sign(l); sig += sig - 1; + if (val != l_Undef){ + return val == sig; + }else{ + /* New fact -- store it. */ + int* levels; + clause** reasons; +#ifdef VERBOSEDEBUG + printf(L_IND"bind("L_LIT")\n", L_ind, L_lit(l)); +#endif + /* int* */ levels = s->levels; + /* clause** */ reasons = s->reasons; + + values [v] = sig; + levels [v] = solver_dlevel(s); + reasons[v] = from; + s->trail[s->qtail++] = l; + + order_assigned(s, v); + return true; + } +} + +static inline void assume(solver* s, lit l){ + assert(s->qtail == s->qhead); + assert(s->assigns[lit_var(l)] == l_Undef); +#ifdef VERBOSEDEBUG + printf(L_IND"assume("L_LIT")\n", L_ind, L_lit(l)); +#endif + veci_push(&s->trail_lim,s->qtail); + enqueue(s,l,(clause*)0); +} + +static inline void solver_canceluntil(solver* s, int level) { + lit* trail; + lbool* values; + clause** reasons; + int bound; + int c; + + if (solver_dlevel(s) <= level) + return; + + trail = s->trail; + values = s->assigns; + reasons = s->reasons; + bound = (veci_begin(&s->trail_lim))[level]; + + for (c = s->qtail-1; c >= bound; c--) { + int x = lit_var(trail[c]); + values [x] = l_Undef; + reasons[x] = (clause*)0; + } + + for (c = s->qhead-1; c >= bound; c--) + order_unassigned(s,lit_var(trail[c])); + + s->qhead = s->qtail = bound; + veci_resize(&s->trail_lim,level); +} + +static void solver_record(solver* s, veci* cls) +{ + lit* begin = veci_begin(cls); + lit* end = begin + veci_size(cls); + clause* c = (veci_size(cls) > 1) ? clause_new(s,begin,end,1) + : (clause*)0; + enqueue(s,*begin,c); + + assert(veci_size(cls) > 0); + + if (c != 0) { + vecp_push(&s->learnts,c); + act_clause_bump(s,c); + s->stats.learnts++; + s->stats.learnts_literals += veci_size(cls); + } +} + +static double solver_progress(solver* s) +{ + lbool* values = s->assigns; + int* levels = s->levels; + int i; + + double progress = 0; + double F = 1.0 / s->size; + for (i = 0; i < s->size; i++) + if (values[i] != l_Undef) + progress += pow(F, levels[i]); + return progress / s->size; +} + +/*====================================================================*/ +/* Major methods: */ + +static bool solver_lit_removable(solver* s, lit l, int minl) +{ + lbool* tags = s->tags; + clause** reasons = s->reasons; + int* levels = s->levels; + int top = veci_size(&s->tagged); + + assert(lit_var(l) >= 0 && lit_var(l) < s->size); + assert(reasons[lit_var(l)] != 0); + veci_resize(&s->stack,0); + veci_push(&s->stack,lit_var(l)); + + while (veci_size(&s->stack) > 0){ + clause* c; + int v = veci_begin(&s->stack)[veci_size(&s->stack)-1]; + assert(v >= 0 && v < s->size); + veci_resize(&s->stack,veci_size(&s->stack)-1); + assert(reasons[v] != 0); + c = reasons[v]; + + if (clause_is_lit(c)){ + int v = lit_var(clause_read_lit(c)); + if (tags[v] == l_Undef && levels[v] != 0){ + if (reasons[v] != 0 + && ((1 << (levels[v] & 31)) & minl)){ + veci_push(&s->stack,v); + tags[v] = l_True; + veci_push(&s->tagged,v); + }else{ + int* tagged = veci_begin(&s->tagged); + int j; + for (j = top; j < veci_size(&s->tagged); j++) + tags[tagged[j]] = l_Undef; + veci_resize(&s->tagged,top); + return false; + } + } + }else{ + lit* lits = clause_begin(c); + int i, j; + + for (i = 1; i < clause_size(c); i++){ + int v = lit_var(lits[i]); + if (tags[v] == l_Undef && levels[v] != 0){ + if (reasons[v] != 0 + && ((1 << (levels[v] & 31)) & minl)){ + + veci_push(&s->stack,lit_var(lits[i])); + tags[v] = l_True; + veci_push(&s->tagged,v); + }else{ + int* tagged = veci_begin(&s->tagged); + for (j = top; j < veci_size(&s->tagged); j++) + tags[tagged[j]] = l_Undef; + veci_resize(&s->tagged,top); + return false; + } + } + } + } + } + + return true; +} + +static void solver_analyze(solver* s, clause* c, veci* learnt) +{ + lit* trail = s->trail; + lbool* tags = s->tags; + clause** reasons = s->reasons; + int* levels = s->levels; + int cnt = 0; + lit p = lit_Undef; + int ind = s->qtail-1; + lit* lits; + int i, j, minl; + int* tagged; + + veci_push(learnt,lit_Undef); + + do{ + assert(c != 0); + + if (clause_is_lit(c)){ + lit q = clause_read_lit(c); + assert(lit_var(q) >= 0 && lit_var(q) < s->size); + if (tags[lit_var(q)] == l_Undef && levels[lit_var(q)] > 0){ + tags[lit_var(q)] = l_True; + veci_push(&s->tagged,lit_var(q)); + act_var_bump(s,lit_var(q)); + if (levels[lit_var(q)] == solver_dlevel(s)) + cnt++; + else + veci_push(learnt,q); + } + }else{ + + if (clause_learnt(c)) + act_clause_bump(s,c); + + lits = clause_begin(c); + /* printlits(lits,lits+clause_size(c)); printf("\n"); */ + for (j = (p == lit_Undef ? 0 : 1); j < clause_size(c); j++){ + lit q = lits[j]; + assert(lit_var(q) >= 0 && lit_var(q) < s->size); + if (tags[lit_var(q)] == l_Undef + && levels[lit_var(q)] > 0){ + tags[lit_var(q)] = l_True; + veci_push(&s->tagged,lit_var(q)); + act_var_bump(s,lit_var(q)); + if (levels[lit_var(q)] == solver_dlevel(s)) + cnt++; + else + veci_push(learnt,q); + } + } + } + + while (tags[lit_var(trail[ind--])] == l_Undef); + + p = trail[ind+1]; + c = reasons[lit_var(p)]; + cnt--; + + }while (cnt > 0); + + *veci_begin(learnt) = lit_neg(p); + + lits = veci_begin(learnt); + minl = 0; + for (i = 1; i < veci_size(learnt); i++){ + int lev = levels[lit_var(lits[i])]; + minl |= 1 << (lev & 31); + } + + /* simplify (full) */ + for (i = j = 1; i < veci_size(learnt); i++){ + if (reasons[lit_var(lits[i])] == 0 + || !solver_lit_removable(s,lits[i],minl)) + lits[j++] = lits[i]; + } + + /* update size of learnt + statistics */ + s->stats.max_literals += veci_size(learnt); + veci_resize(learnt,j); + s->stats.tot_literals += j; + + /* clear tags */ + tagged = veci_begin(&s->tagged); + for (i = 0; i < veci_size(&s->tagged); i++) + tags[tagged[i]] = l_Undef; + veci_resize(&s->tagged,0); + +#ifdef DEBUG + for (i = 0; i < s->size; i++) + assert(tags[i] == l_Undef); +#endif + +#ifdef VERBOSEDEBUG + printf(L_IND"Learnt {", L_ind); + for (i = 0; i < veci_size(learnt); i++) + printf(" "L_LIT, L_lit(lits[i])); +#endif + if (veci_size(learnt) > 1){ + int max_i = 1; + int max = levels[lit_var(lits[1])]; + lit tmp; + + for (i = 2; i < veci_size(learnt); i++) + if (levels[lit_var(lits[i])] > max){ + max = levels[lit_var(lits[i])]; + max_i = i; + } + + tmp = lits[1]; + lits[1] = lits[max_i]; + lits[max_i] = tmp; + } +#ifdef VERBOSEDEBUG + { + int lev = veci_size(learnt) > 1 ? levels[lit_var(lits[1])] : 0; + printf(" } at level %d\n", lev); + } +#endif +} + +clause* solver_propagate(solver* s) +{ + lbool* values = s->assigns; + clause* confl = (clause*)0; + lit* lits; + + /* printf("solver_propagate\n"); */ + while (confl == 0 && s->qtail - s->qhead > 0){ + lit p = s->trail[s->qhead++]; + vecp* ws = solver_read_wlist(s,p); + clause **begin = (clause**)vecp_begin(ws); + clause **end = begin + vecp_size(ws); + clause **i, **j; + + s->stats.propagations++; + s->simpdb_props--; + + /* printf("checking lit %d: "L_LIT"\n", veci_size(ws), + L_lit(p)); */ + for (i = j = begin; i < end; ){ + if (clause_is_lit(*i)){ + *j++ = *i; + if (!enqueue(s,clause_read_lit(*i),clause_from_lit(p))){ + confl = s->binary; + (clause_begin(confl))[1] = lit_neg(p); + (clause_begin(confl))[0] = clause_read_lit(*i++); + + /* Copy the remaining watches: */ + while (i < end) + *j++ = *i++; + } + }else{ + lit false_lit; + lbool sig; + + lits = clause_begin(*i); + + /* Make sure the false literal is data[1]: */ + false_lit = lit_neg(p); + if (lits[0] == false_lit){ + lits[0] = lits[1]; + lits[1] = false_lit; + } + assert(lits[1] == false_lit); + /* printf("checking clause: "); + printlits(lits, lits+clause_size(*i)); + printf("\n"); */ + + /* If 0th watch is true, then clause is already + satisfied. */ + sig = !lit_sign(lits[0]); sig += sig - 1; + if (values[lit_var(lits[0])] == sig){ + *j++ = *i; + }else{ + /* Look for new watch: */ + lit* stop = lits + clause_size(*i); + lit* k; + for (k = lits + 2; k < stop; k++){ + lbool sig = lit_sign(*k); sig += sig - 1; + if (values[lit_var(*k)] != sig){ + lits[1] = *k; + *k = false_lit; + vecp_push(solver_read_wlist(s, + lit_neg(lits[1])),*i); + goto next; } + } + + *j++ = *i; + /* Clause is unit under assignment: */ + if (!enqueue(s,lits[0], *i)){ + confl = *i++; + /* Copy the remaining watches: */ + while (i < end) + *j++ = *i++; + } + } + } + next: + i++; + } + + s->stats.inspects += j - (clause**)vecp_begin(ws); + vecp_resize(ws,j - (clause**)vecp_begin(ws)); + } + + return confl; +} + +static inline int clause_cmp (const void* x, const void* y) { + return clause_size((clause*)x) > 2 + && (clause_size((clause*)y) == 2 + || clause_activity((clause*)x) + < clause_activity((clause*)y)) ? -1 : 1; } + +void solver_reducedb(solver* s) +{ + int i, j; + double extra_lim = s->cla_inc / vecp_size(&s->learnts); + /* Remove any clause below this activity */ + clause** learnts = (clause**)vecp_begin(&s->learnts); + clause** reasons = s->reasons; + + sort(vecp_begin(&s->learnts), vecp_size(&s->learnts), clause_cmp); + + for (i = j = 0; i < vecp_size(&s->learnts) / 2; i++){ + if (clause_size(learnts[i]) > 2 + && reasons[lit_var(*clause_begin(learnts[i]))] + != learnts[i]) + clause_remove(s,learnts[i]); + else + learnts[j++] = learnts[i]; + } + for (; i < vecp_size(&s->learnts); i++){ + if (clause_size(learnts[i]) > 2 + && reasons[lit_var(*clause_begin(learnts[i]))] + != learnts[i] + && clause_activity(learnts[i]) < extra_lim) + clause_remove(s,learnts[i]); + else + learnts[j++] = learnts[i]; + } + + /* printf("reducedb deleted %d\n", vecp_size(&s->learnts) - j); */ + + vecp_resize(&s->learnts,j); +} + +static lbool solver_search(solver* s, int nof_conflicts, + int nof_learnts) +{ + int* levels = s->levels; + double var_decay = 0.95; + double clause_decay = 0.999; + double random_var_freq = 0.02; + + int conflictC = 0; + veci learnt_clause; + + assert(s->root_level == solver_dlevel(s)); + + s->stats.starts++; + s->var_decay = (float)(1 / var_decay ); + s->cla_decay = (float)(1 / clause_decay); + veci_resize(&s->model,0); + veci_new(&learnt_clause); + + for (;;){ + clause* confl = solver_propagate(s); + if (confl != 0){ + /* CONFLICT */ + int blevel; + +#ifdef VERBOSEDEBUG + printf(L_IND"**CONFLICT**\n", L_ind); +#endif + s->stats.conflicts++; conflictC++; + if (solver_dlevel(s) == s->root_level){ + veci_delete(&learnt_clause); + return l_False; + } + + veci_resize(&learnt_clause,0); + solver_analyze(s, confl, &learnt_clause); + blevel = veci_size(&learnt_clause) > 1 + ? levels[lit_var(veci_begin(&learnt_clause)[1])] + : s->root_level; + blevel = s->root_level > blevel ? s->root_level : blevel; + solver_canceluntil(s,blevel); + solver_record(s,&learnt_clause); + act_var_decay(s); + act_clause_decay(s); + + }else{ + /* NO CONFLICT */ + int next; + + if (nof_conflicts >= 0 && conflictC >= nof_conflicts){ + /* Reached bound on number of conflicts: */ + s->progress_estimate = solver_progress(s); + solver_canceluntil(s,s->root_level); + veci_delete(&learnt_clause); + return l_Undef; } + + if (solver_dlevel(s) == 0) + /* Simplify the set of problem clauses: */ + solver_simplify(s); + + if (nof_learnts >= 0 + && vecp_size(&s->learnts) - s->qtail >= nof_learnts) + /* Reduce the set of learnt clauses: */ + solver_reducedb(s); + + /* New variable decision: */ + s->stats.decisions++; + next = order_select(s,(float)random_var_freq); + + if (next == var_Undef){ + /* Model found: */ + lbool* values = s->assigns; + int i; + for (i = 0; i < s->size; i++) + veci_push(&s->model,(int)values[i]); + solver_canceluntil(s,s->root_level); + veci_delete(&learnt_clause); + + /* + veci apa; veci_new(&apa); + for (i = 0; i < s->size; i++) + veci_push(&apa,(int)(s->model.ptr[i] == l_True + ? toLit(i) : lit_neg(toLit(i)))); + printf("model: "); + printlits((lit*)apa.ptr, + (lit*)apa.ptr + veci_size(&apa)); printf("\n"); + veci_delete(&apa); + */ + + return l_True; + } + + assume(s,lit_neg(toLit(next))); + } + } + +#if 0 /* by mao; unreachable code */ + return l_Undef; /* cannot happen */ +#endif +} + +/*====================================================================*/ +/* External solver functions: */ + +solver* solver_new(void) +{ + solver* s = (solver*)malloc(sizeof(solver)); + + /* initialize vectors */ + vecp_new(&s->clauses); + vecp_new(&s->learnts); + veci_new(&s->order); + veci_new(&s->trail_lim); + veci_new(&s->tagged); + veci_new(&s->stack); + veci_new(&s->model); + + /* initialize arrays */ + s->wlists = 0; + s->activity = 0; + s->assigns = 0; + s->orderpos = 0; + s->reasons = 0; + s->levels = 0; + s->tags = 0; + s->trail = 0; + + /* initialize other vars */ + s->size = 0; + s->cap = 0; + s->qhead = 0; + s->qtail = 0; + s->cla_inc = 1; + s->cla_decay = 1; + s->var_inc = 1; + s->var_decay = 1; + s->root_level = 0; + s->simpdb_assigns = 0; + s->simpdb_props = 0; + s->random_seed = 91648253; + s->progress_estimate = 0; + s->binary = (clause*)malloc(sizeof(clause) + + sizeof(lit)*2); + s->binary->size_learnt = (2 << 1); + s->verbosity = 0; + + s->stats.starts = 0; + s->stats.decisions = 0; + s->stats.propagations = 0; + s->stats.inspects = 0; + s->stats.conflicts = 0; + s->stats.clauses = 0; + s->stats.clauses_literals = 0; + s->stats.learnts = 0; + s->stats.learnts_literals = 0; + s->stats.max_literals = 0; + s->stats.tot_literals = 0; + + return s; +} + +void solver_delete(solver* s) +{ + int i; + for (i = 0; i < vecp_size(&s->clauses); i++) + free(vecp_begin(&s->clauses)[i]); + + for (i = 0; i < vecp_size(&s->learnts); i++) + free(vecp_begin(&s->learnts)[i]); + + /* delete vectors */ + vecp_delete(&s->clauses); + vecp_delete(&s->learnts); + veci_delete(&s->order); + veci_delete(&s->trail_lim); + veci_delete(&s->tagged); + veci_delete(&s->stack); + veci_delete(&s->model); + free(s->binary); + + /* delete arrays */ + if (s->wlists != 0){ + int i; + for (i = 0; i < s->size*2; i++) + vecp_delete(&s->wlists[i]); + + /* if one is different from null, all are */ + free(s->wlists); + free(s->activity ); + free(s->assigns ); + free(s->orderpos ); + free(s->reasons ); + free(s->levels ); + free(s->trail ); + free(s->tags ); + } + + free(s); +} + +bool solver_addclause(solver* s, lit* begin, lit* end) +{ + lit *i,*j; + int maxvar; + lbool* values; + lit last; + + if (begin == end) return false; + + /* printlits(begin,end); printf("\n"); */ + /* insertion sort */ + maxvar = lit_var(*begin); + for (i = begin + 1; i < end; i++){ + lit l = *i; + maxvar = lit_var(l) > maxvar ? lit_var(l) : maxvar; + for (j = i; j > begin && *(j-1) > l; j--) + *j = *(j-1); + *j = l; + } + solver_setnvars(s,maxvar+1); + + /* printlits(begin,end); printf("\n"); */ + values = s->assigns; + + /* delete duplicates */ + last = lit_Undef; + for (i = j = begin; i < end; i++){ + /* printf("lit: "L_LIT", value = %d\n", L_lit(*i), + (lit_sign(*i) ? -values[lit_var(*i)] : values[lit_var(*i)])); */ + lbool sig = !lit_sign(*i); sig += sig - 1; + if (*i == lit_neg(last) || sig == values[lit_var(*i)]) + return true; /* tautology */ + else if (*i != last && values[lit_var(*i)] == l_Undef) + last = *j++ = *i; + } + + /* printf("final: "); printlits(begin,j); printf("\n"); */ + + if (j == begin) /* empty clause */ + return false; + else if (j - begin == 1) /* unit clause */ + return enqueue(s,*begin,(clause*)0); + + /* create new clause */ + vecp_push(&s->clauses,clause_new(s,begin,j,0)); + + s->stats.clauses++; + s->stats.clauses_literals += j - begin; + + return true; +} + +bool solver_simplify(solver* s) +{ + clause** reasons; + int type; + + assert(solver_dlevel(s) == 0); + + if (solver_propagate(s) != 0) + return false; + + if (s->qhead == s->simpdb_assigns || s->simpdb_props > 0) + return true; + + reasons = s->reasons; + for (type = 0; type < 2; type++){ + vecp* cs = type ? &s->learnts : &s->clauses; + clause** cls = (clause**)vecp_begin(cs); + + int i, j; + for (j = i = 0; i < vecp_size(cs); i++){ + if (reasons[lit_var(*clause_begin(cls[i]))] != cls[i] && + clause_simplify(s,cls[i]) == l_True) + clause_remove(s,cls[i]); + else + cls[j++] = cls[i]; + } + vecp_resize(cs,j); + } + + s->simpdb_assigns = s->qhead; + /* (shouldn't depend on 'stats' really, but it will do for now) */ + s->simpdb_props = (int)(s->stats.clauses_literals + + s->stats.learnts_literals); + + return true; +} + +bool solver_solve(solver* s, lit* begin, lit* end) +{ + double nof_conflicts = 100; + double nof_learnts = solver_nclauses(s) / 3; + lbool status = l_Undef; + lbool* values = s->assigns; + lit* i; + + /* printf("solve: "); printlits(begin, end); printf("\n"); */ + for (i = begin; i < end; i++){ + switch (lit_sign(*i) ? -values[lit_var(*i)] + : values[lit_var(*i)]){ + case 1: /* l_True: */ + break; + case 0: /* l_Undef */ + assume(s, *i); + if (solver_propagate(s) == NULL) + break; + /* falltrough */ + case -1: /* l_False */ + solver_canceluntil(s, 0); + return false; + } + } + + s->root_level = solver_dlevel(s); + + if (s->verbosity >= 1){ + printf("==================================[MINISAT]============" + "=======================\n"); + printf("| Conflicts | ORIGINAL | LEARNT " + " | Progress |\n"); + printf("| | Clauses Literals | Limit Clauses Litera" + "ls Lit/Cl | |\n"); + printf("=======================================================" + "=======================\n"); + } + + while (status == l_Undef){ + double Ratio = (s->stats.learnts == 0)? 0.0 : + s->stats.learnts_literals / (double)s->stats.learnts; + + if (s->verbosity >= 1){ + printf("| %9.0f | %7.0f %8.0f | %7.0f %7.0f %8.0f %7.1f | %" + "6.3f %% |\n", + (double)s->stats.conflicts, + (double)s->stats.clauses, + (double)s->stats.clauses_literals, + (double)nof_learnts, + (double)s->stats.learnts, + (double)s->stats.learnts_literals, + Ratio, + s->progress_estimate*100); + fflush(stdout); + } + status = solver_search(s,(int)nof_conflicts, (int)nof_learnts); + nof_conflicts *= 1.5; + nof_learnts *= 1.1; + } + if (s->verbosity >= 1) + printf("=======================================================" + "=======================\n"); + + solver_canceluntil(s,0); + return status != l_False; +} + +int solver_nvars(solver* s) +{ + return s->size; +} + +int solver_nclauses(solver* s) +{ + return vecp_size(&s->clauses); +} + +int solver_nconflicts(solver* s) +{ + return (int)s->stats.conflicts; +} + +/*====================================================================*/ +/* Sorting functions (sigh): */ + +static inline void selectionsort(void** array, int size, + int(*comp)(const void *, const void *)) +{ + int i, j, best_i; + void* tmp; + + for (i = 0; i < size-1; i++){ + best_i = i; + for (j = i+1; j < size; j++){ + if (comp(array[j], array[best_i]) < 0) + best_i = j; + } + tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp; + } +} + +static void sortrnd(void** array, int size, + int(*comp)(const void *, const void *), + double* seed) +{ + if (size <= 15) + selectionsort(array, size, comp); + + else{ + void* pivot = array[irand(seed, size)]; + void* tmp; + int i = -1; + int j = size; + + for(;;){ + do i++; while(comp(array[i], pivot)<0); + do j--; while(comp(pivot, array[j])<0); + + if (i >= j) break; + + tmp = array[i]; array[i] = array[j]; array[j] = tmp; + } + + sortrnd(array , i , comp, seed); + sortrnd(&array[i], size-i, comp, seed); + } +} + +static void sort(void** array, int size, + int(*comp)(const void *, const void *)) +{ + double seed = 91648253; + sortrnd(array,size,comp,&seed); +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/minisat/minisat.h b/resources/3rdparty/glpk-4.57/src/minisat/minisat.h new file mode 100644 index 000000000..2733e8d63 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/minisat/minisat.h @@ -0,0 +1,230 @@ +/* minisat.h */ + +/* Modified by Andrew Makhorin , August 2011 */ + +/*********************************************************************** +* MiniSat -- Copyright (c) 2005, Niklas Sorensson +* http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat/ +* +* Permission is hereby granted, free of charge, to any person +* obtaining a copy of this software and associated documentation files +* (the "Software"), to deal in the Software without restriction, +* including without limitation the rights to use, copy, modify, merge, +* publish, distribute, sublicense, and/or sell copies of the Software, +* and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +***********************************************************************/ +/* Modified to compile with MS Visual Studio 6.0 by Alan Mishchenko */ + +#ifndef MINISAT_H +#define MINISAT_H + +/*====================================================================*/ +/* Simple types: */ + +typedef int bool; + +#define true 1 +#define false 0 + +typedef int lit; +#if 0 /* by mao */ +typedef char lbool; +#else +typedef int lbool; +#endif + +#define var_Undef (int)(-1) +#define lit_Undef (lit)(-2) + +#define l_Undef (lbool)0 +#define l_True (lbool)1 +#define l_False (lbool)(-1) + +#define toLit(v) (lit)((v) + (v)) +#define lit_neg(l) (lit)((l) ^ 1) +#define lit_var(l) (int)((l) >> 1) +#define lit_sign(l) (int)((l) & 1) + +/*====================================================================*/ +/* Vectors: */ + +/* vector of 32-bit intergers (added for 64-bit portability) */ +typedef struct /* veci_t */ { + int size; + int cap; + int* ptr; +} veci; + +#define veci_new(v) \ +{ (v)->size = 0; \ + (v)->cap = 4; \ + (v)->ptr = (int*)malloc(sizeof(int)*(v)->cap); \ +} + +#define veci_delete(v) free((v)->ptr) + +#define veci_begin(v) ((v)->ptr) + +#define veci_size(v) ((v)->size) + +#define veci_resize(v, k) (void)((v)->size = (k)) +/* only safe to shrink !! */ + +#define veci_push(v, e) \ +{ if ((v)->size == (v)->cap) \ + { int newsize = (v)->cap * 2+1; \ + (v)->ptr = (int*)realloc((v)->ptr,sizeof(int)*newsize); \ + (v)->cap = newsize; \ + } \ + (v)->ptr[(v)->size++] = (e); \ +} + +/* vector of 32- or 64-bit pointers */ +typedef struct /* vecp_t */ { + int size; + int cap; + void** ptr; +} vecp; + +#define vecp_new(v) \ +{ (v)->size = 0; \ + (v)->cap = 4; \ + (v)->ptr = (void**)malloc(sizeof(void*)*(v)->cap); \ +} + +#define vecp_delete(v) free((v)->ptr) + +#define vecp_begin(v) ((v)->ptr) + +#define vecp_size(v) ((v)->size) + +#define vecp_resize(v, k) (void)((v)->size = (k)) +/* only safe to shrink !! */ + +#define vecp_push(v, e) \ +{ if ((v)->size == (v)->cap) \ + { int newsize = (v)->cap * 2+1; \ + (v)->ptr = (void**)realloc((v)->ptr,sizeof(void*)*newsize); \ + (v)->cap = newsize; \ + } \ + (v)->ptr[(v)->size++] = (e); \ +} + +/*====================================================================*/ +/* Solver representation: */ + +typedef struct /* clause_t */ +{ + int size_learnt; + lit lits[1]; +} clause; + +typedef struct /* stats_t */ +{ + double starts, decisions, propagations, inspects, conflicts; + double clauses, clauses_literals, learnts, learnts_literals, + max_literals, tot_literals; +} stats; + +typedef struct /* solver_t */ +{ + int size; /* nof variables */ + int cap; /* size of varmaps */ + int qhead; /* Head index of queue. */ + int qtail; /* Tail index of queue. */ + + /* clauses */ + vecp clauses; /* List of problem constraints. + (contains: clause*) */ + vecp learnts; /* List of learnt clauses. + (contains: clause*) */ + + /* activities */ + double var_inc; /* Amount to bump next variable with. */ + double var_decay; /* INVERSE decay factor for variable + activity: stores 1/decay. */ + float cla_inc; /* Amount to bump next clause with. */ + float cla_decay; /* INVERSE decay factor for clause + activity: stores 1/decay. */ + + vecp* wlists; + double* activity; /* A heuristic measurement of the activity + of a variable. */ + lbool* assigns; /* Current values of variables. */ + int* orderpos; /* Index in variable order. */ + clause** reasons; + int* levels; + lit* trail; + + clause* binary; /* A temporary binary clause */ + lbool* tags; + veci tagged; /* (contains: var) */ + veci stack; /* (contains: var) */ + + veci order; /* Variable order. (heap) (contains: var) */ + veci trail_lim; /* Separator indices for different decision + levels in 'trail'. (contains: int) */ + veci model; /* If problem is solved, this vector + contains the model (contains: lbool). */ + + int root_level; /* Level of first proper decision. */ + int simpdb_assigns;/* Number of top-level assignments at last + 'simplifyDB()'. */ + int simpdb_props; /* Number of propagations before next + 'simplifyDB()'. */ + double random_seed; + double progress_estimate; + int verbosity; /* Verbosity level. + 0=silent, + 1=some progress report, + 2=everything */ + + stats stats; +} solver; + +/*====================================================================*/ +/* Public interface: */ + +#if 1 /* by mao; to keep namespace clean */ +#define solver_new _glp_minisat_new +#define solver_delete _glp_minisat_delete +#define solver_addclause _glp_minisat_addclause +#define solver_simplify _glp_minisat_simplify +#define solver_solve _glp_minisat_solve +#define solver_nvars _glp_minisat_nvars +#define solver_nclauses _glp_minisat_nclauses +#define solver_nconflicts _glp_minisat_nconflicts +#define solver_setnvars _glp_minisat_setnvars +#define solver_propagate _glp_minisat_propagate +#define solver_reducedb _glp_minisat_reducedb +#endif + +solver* solver_new(void); +void solver_delete(solver* s); + +bool solver_addclause(solver* s, lit* begin, lit* end); +bool solver_simplify(solver* s); +bool solver_solve(solver* s, lit* begin, lit* end); + +int solver_nvars(solver* s); +int solver_nclauses(solver* s); +int solver_nconflicts(solver* s); + +void solver_setnvars(solver* s,int n); + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/bignum.c b/resources/3rdparty/glpk-4.57/src/misc/bignum.c new file mode 100644 index 000000000..540dd9fdd --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/bignum.c @@ -0,0 +1,286 @@ +/* bignum.c (bignum arithmetic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2006-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "bignum.h" + +/*********************************************************************** +* Two routines below are intended to multiply and divide unsigned +* integer numbers of arbitrary precision. +* +* The routines assume that an unsigned integer number is represented in +* the positional numeral system with the base 2^16 = 65536, i.e. each +* "digit" of the number is in the range [0, 65535] and represented as +* a 16-bit value of the unsigned short type. In other words, a number x +* has the following representation: +* +* n-1 +* x = sum d[j] * 65536^j, +* j=0 +* +* where n is the number of places (positions), and d[j] is j-th "digit" +* of x, 0 <= d[j] <= 65535. +***********************************************************************/ + +/*********************************************************************** +* NAME +* +* bigmul - multiply unsigned integer numbers of arbitrary precision +* +* SYNOPSIS +* +* #include "bignum.h" +* void bigmul(int n, int m, unsigned short x[], unsigned short y[]); +* +* DESCRIPTION +* +* The routine bigmul multiplies unsigned integer numbers of arbitrary +* precision. +* +* n is the number of digits of multiplicand, n >= 1; +* +* m is the number of digits of multiplier, m >= 1; +* +* x is an array containing digits of the multiplicand in elements +* x[m], x[m+1], ..., x[n+m-1]. Contents of x[0], x[1], ..., x[m-1] are +* ignored on entry. +* +* y is an array containing digits of the multiplier in elements y[0], +* y[1], ..., y[m-1]. +* +* On exit digits of the product are stored in elements x[0], x[1], ..., +* x[n+m-1]. The array y is not changed. */ + +void bigmul(int n, int m, unsigned short x[], unsigned short y[]) +{ int i, j; + unsigned int t; + xassert(n >= 1); + xassert(m >= 1); + for (j = 0; j < m; j++) x[j] = 0; + for (i = 0; i < n; i++) + { if (x[i+m]) + { t = 0; + for (j = 0; j < m; j++) + { t += (unsigned int)x[i+m] * (unsigned int)y[j] + + (unsigned int)x[i+j]; + x[i+j] = (unsigned short)t; + t >>= 16; + } + x[i+m] = (unsigned short)t; + } + } + return; +} + +/*********************************************************************** +* NAME +* +* bigdiv - divide unsigned integer numbers of arbitrary precision +* +* SYNOPSIS +* +* #include "bignum.h" +* void bigdiv(int n, int m, unsigned short x[], unsigned short y[]); +* +* DESCRIPTION +* +* The routine bigdiv divides one unsigned integer number of arbitrary +* precision by another with the algorithm described in [1]. +* +* n is the difference between the number of digits of dividend and the +* number of digits of divisor, n >= 0. +* +* m is the number of digits of divisor, m >= 1. +* +* x is an array containing digits of the dividend in elements x[0], +* x[1], ..., x[n+m-1]. +* +* y is an array containing digits of the divisor in elements y[0], +* y[1], ..., y[m-1]. The highest digit y[m-1] must be non-zero. +* +* On exit n+1 digits of the quotient are stored in elements x[m], +* x[m+1], ..., x[n+m], and m digits of the remainder are stored in +* elements x[0], x[1], ..., x[m-1]. The array y is changed but then +* restored. +* +* REFERENCES +* +* 1. D. Knuth. The Art of Computer Programming. Vol. 2: Seminumerical +* Algorithms. Stanford University, 1969. */ + +void bigdiv(int n, int m, unsigned short x[], unsigned short y[]) +{ int i, j; + unsigned int t; + unsigned short d, q, r; + xassert(n >= 0); + xassert(m >= 1); + xassert(y[m-1] != 0); + /* special case when divisor has the only digit */ + if (m == 1) + { d = 0; + for (i = n; i >= 0; i--) + { t = ((unsigned int)d << 16) + (unsigned int)x[i]; + x[i+1] = (unsigned short)(t / y[0]); + d = (unsigned short)(t % y[0]); + } + x[0] = d; + goto done; + } + /* multiply dividend and divisor by a normalizing coefficient in + * order to provide the condition y[m-1] >= base / 2 */ + d = (unsigned short)(0x10000 / ((unsigned int)y[m-1] + 1)); + if (d == 1) + x[n+m] = 0; + else + { t = 0; + for (i = 0; i < n+m; i++) + { t += (unsigned int)x[i] * (unsigned int)d; + x[i] = (unsigned short)t; + t >>= 16; + } + x[n+m] = (unsigned short)t; + t = 0; + for (j = 0; j < m; j++) + { t += (unsigned int)y[j] * (unsigned int)d; + y[j] = (unsigned short)t; + t >>= 16; + } + } + /* main loop */ + for (i = n; i >= 0; i--) + { /* estimate and correct the current digit of quotient */ + if (x[i+m] < y[m-1]) + { t = ((unsigned int)x[i+m] << 16) + (unsigned int)x[i+m-1]; + q = (unsigned short)(t / (unsigned int)y[m-1]); + r = (unsigned short)(t % (unsigned int)y[m-1]); + if (q == 0) goto putq; else goto test; + } + q = 0; + r = x[i+m-1]; +decr: q--; /* if q = 0 then q-- = 0xFFFF */ + t = (unsigned int)r + (unsigned int)y[m-1]; + r = (unsigned short)t; + if (t > 0xFFFF) goto msub; +test: t = (unsigned int)y[m-2] * (unsigned int)q; + if ((unsigned short)(t >> 16) > r) goto decr; + if ((unsigned short)(t >> 16) < r) goto msub; + if ((unsigned short)t > x[i+m-2]) goto decr; +msub: /* now subtract divisor multiplied by the current digit of + * quotient from the current dividend */ + if (q == 0) goto putq; + t = 0; + for (j = 0; j < m; j++) + { t += (unsigned int)y[j] * (unsigned int)q; + if (x[i+j] < (unsigned short)t) t += 0x10000; + x[i+j] -= (unsigned short)t; + t >>= 16; + } + if (x[i+m] >= (unsigned short)t) goto putq; + /* perform correcting addition, because the current digit of + * quotient is greater by one than its correct value */ + q--; + t = 0; + for (j = 0; j < m; j++) + { t += (unsigned int)x[i+j] + (unsigned int)y[j]; + x[i+j] = (unsigned short)t; + t >>= 16; + } +putq: /* store the current digit of quotient */ + x[i+m] = q; + } + /* divide divisor and remainder by the normalizing coefficient in + * order to restore their original values */ + if (d > 1) + { t = 0; + for (i = m-1; i >= 0; i--) + { t = (t << 16) + (unsigned int)x[i]; + x[i] = (unsigned short)(t / (unsigned int)d); + t %= (unsigned int)d; + } + t = 0; + for (j = m-1; j >= 0; j--) + { t = (t << 16) + (unsigned int)y[j]; + y[j] = (unsigned short)(t / (unsigned int)d); + t %= (unsigned int)d; + } + } +done: return; +} + +/**********************************************************************/ + +#ifdef GLP_TEST +#include +#include +#include +#include "rng.h" + +#define N_MAX 7 +/* maximal number of digits in multiplicand */ + +#define M_MAX 5 +/* maximal number of digits in multiplier */ + +#define N_TEST 1000000 +/* number of tests */ + +int main(void) +{ RNG *rand; + int d, j, n, m, test; + unsigned short x[N_MAX], y[M_MAX], z[N_MAX+M_MAX]; + rand = rng_create_rand(); + for (test = 1; test <= N_TEST; test++) + { /* x[0,...,n-1] := multiplicand */ + n = 1 + rng_unif_rand(rand, N_MAX-1); + assert(1 <= n && n <= N_MAX); + for (j = 0; j < n; j++) + { d = rng_unif_rand(rand, 65536); + assert(0 <= d && d <= 65535); + x[j] = (unsigned short)d; + } + /* y[0,...,m-1] := multiplier */ + m = 1 + rng_unif_rand(rand, M_MAX-1); + assert(1 <= m && m <= M_MAX); + for (j = 0; j < m; j++) + { d = rng_unif_rand(rand, 65536); + assert(0 <= d && d <= 65535); + y[j] = (unsigned short)d; + } + if (y[m-1] == 0) y[m-1] = 1; + /* z[0,...,n+m-1] := x * y */ + for (j = 0; j < n; j++) z[m+j] = x[j]; + bigmul(n, m, z, y); + /* z[0,...,m-1] := z mod y, z[m,...,n+m-1] := z div y */ + bigdiv(n, m, z, y); + /* z mod y must be 0 */ + for (j = 0; j < m; j++) assert(z[j] == 0); + /* z div y must be x */ + for (j = 0; j < n; j++) assert(z[m+j] == x[j]); + } + fprintf(stderr, "%d tests successfully passed\n", N_TEST); + rng_delete_rand(rand); + return 0; +} +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/bignum.h b/resources/3rdparty/glpk-4.57/src/misc/bignum.h new file mode 100644 index 000000000..aebac374d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/bignum.h @@ -0,0 +1,37 @@ +/* bignum.h (arbitrary precision arithmetic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2006-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef BIGNUM_H +#define BIGNUM_H + +#define bigmul _glp_bigmul +void bigmul(int n, int m, unsigned short x[], unsigned short y[]); +/* multiply unsigned integer numbers of arbitrary precision */ + +#define bigdiv _glp_bigdiv +void bigdiv(int n, int m, unsigned short x[], unsigned short y[]); +/* divide unsigned integer numbers of arbitrary precision */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/dmp.c b/resources/3rdparty/glpk-4.57/src/misc/dmp.c new file mode 100644 index 000000000..a4882c861 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/dmp.c @@ -0,0 +1,243 @@ +/* dmp.c (dynamic memory pool) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "dmp.h" + +struct DMP +{ /* dynamic memory pool */ + void *avail[32]; + /* avail[k], 0 <= k <= 31, is a pointer to first available (free) + * atom of (k+1)*8 bytes long; at the beginning of each free atom + * there is a pointer to another free atom of the same size */ + void *block; + /* pointer to most recently allocated memory block; at the + * beginning of each allocated memory block there is a pointer to + * previously allocated memory block */ + int used; + /* number of bytes used in most recently allocated memory block */ + size_t count; + /* number of atoms which are currently in use */ +}; + +#define DMP_BLK_SIZE 8000 +/* size of memory blocks, in bytes, allocated for memory pools */ + +struct prefix +{ /* atom prefix (for debugging only) */ + DMP *pool; + /* dynamic memory pool */ + int size; + /* original atom size, in bytes */ +}; + +#define prefix_size ((sizeof(struct prefix) + 7) & ~7) +/* size of atom prefix rounded up to multiple of 8 bytes */ + +int dmp_debug; +/* debug mode flag */ + +/*********************************************************************** +* NAME +* +* dmp_create_pool - create dynamic memory pool +* +* SYNOPSIS +* +* #include "dmp.h" +* DMP *dmp_create_pool(void); +* +* DESCRIPTION +* +* The routine dmp_create_pool creates a dynamic memory pool. +* +* RETURNS +* +* The routine returns a pointer to the memory pool created. */ + +DMP *dmp_create_pool(void) +{ DMP *pool; + int k; + xassert(sizeof(void *) <= 8); + if (dmp_debug) + xprintf("dmp_create_pool: warning: debug mode is on\n"); + pool = talloc(1, DMP); + for (k = 0; k <= 31; k++) + pool->avail[k] = NULL; + pool->block = NULL; + pool->used = DMP_BLK_SIZE; + pool->count = 0; + return pool; +} + +/*********************************************************************** +* NAME +* +* dmp_get_atom - get free atom from dynamic memory pool +* +* SYNOPSIS +* +* #include "dmp.h" +* void *dmp_get_atom(DMP *pool, int size); +* +* DESCRIPTION +* +* The routine dmp_get_atom obtains a free atom (memory space) from the +* specified memory pool. +* +* The parameter size is the atom size, in bytes, 1 <= size <= 256. +* +* Note that the free atom contains arbitrary data, not binary zeros. +* +* RETURNS +* +* The routine returns a pointer to the free atom obtained. */ + +void *dmp_get_atom(DMP *pool, int size) +{ void *atom; + int k, need; + xassert(1 <= size && size <= 256); + /* round up atom size to multiple of 8 bytes */ + need = (size + 7) & ~7; + /* determine number of corresponding list of free atoms */ + k = (need >> 3) - 1; + /* obtain free atom */ + if (pool->avail[k] == NULL) + { /* corresponding list of free atoms is empty */ + /* if debug mode is on, add atom prefix size */ + if (dmp_debug) + need += prefix_size; + if (pool->used + need > DMP_BLK_SIZE) + { /* allocate new memory block */ + void *block = talloc(DMP_BLK_SIZE, char); + *(void **)block = pool->block; + pool->block = block; + pool->used = 8; /* sufficient to store pointer */ + } + /* allocate new atom in current memory block */ + atom = (char *)pool->block + pool->used; + pool->used += need; + } + else + { /* obtain atom from corresponding list of free atoms */ + atom = pool->avail[k]; + pool->avail[k] = *(void **)atom; + } + /* if debug mode is on, fill atom prefix */ + if (dmp_debug) + { ((struct prefix *)atom)->pool = pool; + ((struct prefix *)atom)->size = size; + atom = (char *)atom + prefix_size; + } + /* increase number of allocated atoms */ + pool->count++; + return atom; +} + +/*********************************************************************** +* NAME +* +* dmp_free_atom - return atom to dynamic memory pool +* +* SYNOPSIS +* +* #include "dmp.h" +* void dmp_free_atom(DMP *pool, void *atom, int size); +* +* DESCRIPTION +* +* The routine dmp_free_atom returns the specified atom (memory space) +* to the specified memory pool, making the atom free. +* +* The parameter size is the atom size, in bytes, 1 <= size <= 256. +* +* Note that the atom can be returned only to the pool, from which it +* was obtained, and its size must be exactly the same as on obtaining +* it from the pool. */ + +void dmp_free_atom(DMP *pool, void *atom, int size) +{ int k; + xassert(1 <= size && size <= 256); + /* determine number of corresponding list of free atoms */ + k = ((size + 7) >> 3) - 1; + /* if debug mode is on, check atom prefix */ + if (dmp_debug) + { atom = (char *)atom - prefix_size; + xassert(((struct prefix *)atom)->pool == pool); + xassert(((struct prefix *)atom)->size == size); + } + /* return atom to corresponding list of free atoms */ + *(void **)atom = pool->avail[k]; + pool->avail[k] = atom; + /* decrease number of allocated atoms */ + xassert(pool->count > 0); + pool->count--; + return; +} + +/*********************************************************************** +* NAME +* +* dmp_in_use - determine how many atoms are still in use +* +* SYNOPSIS +* +* #include "dmp.h" +* size_t dmp_in_use(DMP *pool); +* +* RETURNS +* +* The routine returns the number of atoms of the specified memory pool +* which are still in use. */ + +size_t dmp_in_use(DMP *pool) +{ return + pool->count; +} + +/*********************************************************************** +* NAME +* +* dmp_delete_pool - delete dynamic memory pool +* +* SYNOPSIS +* +* #include "dmp.h" +* void dmp_delete_pool(DMP *pool); +* +* DESCRIPTION +* +* The routine dmp_delete_pool deletes the specified dynamic memory +* pool freeing all the memory allocated to this object. */ + +void dmp_delete_pool(DMP *pool) +{ while (pool->block != NULL) + { void *block = pool->block; + pool->block = *(void **)block; + tfree(block); + } + tfree(pool); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/dmp.h b/resources/3rdparty/glpk-4.57/src/misc/dmp.h new file mode 100644 index 000000000..85fe7176a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/dmp.h @@ -0,0 +1,63 @@ +/* dmp.h (dynamic memory pool) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef DMP_H +#define DMP_H + +#include "stdc.h" + +typedef struct DMP DMP; + +#define dmp_debug _glp_dmp_debug +extern int dmp_debug; +/* debug mode flag */ + +#define dmp_create_pool _glp_dmp_create_pool +DMP *dmp_create_pool(void); +/* create dynamic memory pool */ + +#define dmp_talloc(pool, type) \ + ((type *)dmp_get_atom(pool, sizeof(type))) + +#define dmp_get_atom _glp_dmp_get_atom +void *dmp_get_atom(DMP *pool, int size); +/* get free atom from dynamic memory pool */ + +#define dmp_tfree(pool, atom) \ + dmp_free_atom(pool, atom, sizeof(*(atom))) + +#define dmp_free_atom _glp_dmp_free_atom +void dmp_free_atom(DMP *pool, void *atom, int size); +/* return atom to dynamic memory pool */ + +#define dmp_in_use _glp_dmp_in_use +size_t dmp_in_use(DMP *pool); +/* determine how many atoms are still in use */ + +#define dmp_delete_pool _glp_dmp_delete_pool +void dmp_delete_pool(DMP *pool); +/* delete dynamic memory pool */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/ffalg.c b/resources/3rdparty/glpk-4.57/src/misc/ffalg.c new file mode 100644 index 000000000..4ea2913db --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/ffalg.c @@ -0,0 +1,221 @@ +/* ffalg.c (Ford-Fulkerson algorithm) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2009-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "ffalg.h" + +/*********************************************************************** +* NAME +* +* ffalg - Ford-Fulkerson algorithm +* +* SYNOPSIS +* +* #include "ffalg.h" +* void ffalg(int nv, int na, const int tail[], const int head[], +* int s, int t, const int cap[], int x[], char cut[]); +* +* DESCRIPTION +* +* The routine ffalg implements the Ford-Fulkerson algorithm to find a +* maximal flow in the specified flow network. +* +* INPUT PARAMETERS +* +* nv is the number of nodes, nv >= 2. +* +* na is the number of arcs, na >= 0. +* +* tail[a], a = 1,...,na, is the index of tail node of arc a. +* +* head[a], a = 1,...,na, is the index of head node of arc a. +* +* s is the source node index, 1 <= s <= nv. +* +* t is the sink node index, 1 <= t <= nv, t != s. +* +* cap[a], a = 1,...,na, is the capacity of arc a, cap[a] >= 0. +* +* NOTE: Multiple arcs are allowed, but self-loops are not allowed. +* +* OUTPUT PARAMETERS +* +* x[a], a = 1,...,na, is optimal value of the flow through arc a. +* +* cut[i], i = 1,...,nv, is 1 if node i is labelled, and 0 otherwise. +* The set of arcs, whose one endpoint is labelled and other is not, +* defines the minimal cut corresponding to the maximal flow found. +* If the parameter cut is NULL, the cut information are not stored. +* +* REFERENCES +* +* L.R.Ford, Jr., and D.R.Fulkerson, "Flows in Networks," The RAND +* Corp., Report R-375-PR (August 1962), Chap. I "Static Maximal Flow," +* pp.30-33. */ + +void ffalg(int nv, int na, const int tail[], const int head[], + int s, int t, const int cap[], int x[], char cut[]) +{ int a, delta, i, j, k, pos1, pos2, temp, + *ptr, *arc, *link, *list; + /* sanity checks */ + xassert(nv >= 2); + xassert(na >= 0); + xassert(1 <= s && s <= nv); + xassert(1 <= t && t <= nv); + xassert(s != t); + for (a = 1; a <= na; a++) + { i = tail[a], j = head[a]; + xassert(1 <= i && i <= nv); + xassert(1 <= j && j <= nv); + xassert(i != j); + xassert(cap[a] >= 0); + } + /* allocate working arrays */ + ptr = xcalloc(1+nv+1, sizeof(int)); + arc = xcalloc(1+na+na, sizeof(int)); + link = xcalloc(1+nv, sizeof(int)); + list = xcalloc(1+nv, sizeof(int)); + /* ptr[i] := (degree of node i) */ + for (i = 1; i <= nv; i++) + ptr[i] = 0; + for (a = 1; a <= na; a++) + { ptr[tail[a]]++; + ptr[head[a]]++; + } + /* initialize arc pointers */ + ptr[1]++; + for (i = 1; i < nv; i++) + ptr[i+1] += ptr[i]; + ptr[nv+1] = ptr[nv]; + /* build arc lists */ + for (a = 1; a <= na; a++) + { arc[--ptr[tail[a]]] = a; + arc[--ptr[head[a]]] = a; + } + xassert(ptr[1] == 1); + xassert(ptr[nv+1] == na+na+1); + /* now the indices of arcs incident to node i are stored in + * locations arc[ptr[i]], arc[ptr[i]+1], ..., arc[ptr[i+1]-1] */ + /* initialize arc flows */ + for (a = 1; a <= na; a++) + x[a] = 0; +loop: /* main loop starts here */ + /* build augmenting tree rooted at s */ + /* link[i] = 0 means that node i is not labelled yet; + * link[i] = a means that arc a immediately precedes node i */ + /* initially node s is labelled as the root */ + for (i = 1; i <= nv; i++) + link[i] = 0; + link[s] = -1, list[1] = s, pos1 = pos2 = 1; + /* breadth first search */ + while (pos1 <= pos2) + { /* dequeue node i */ + i = list[pos1++]; + /* consider all arcs incident to node i */ + for (k = ptr[i]; k < ptr[i+1]; k++) + { a = arc[k]; + if (tail[a] == i) + { /* a = i->j is a forward arc from s to t */ + j = head[a]; + /* if node j has been labelled, skip the arc */ + if (link[j] != 0) continue; + /* if the arc does not allow increasing the flow through + * it, skip the arc */ + if (x[a] == cap[a]) continue; + } + else if (head[a] == i) + { /* a = i<-j is a backward arc from s to t */ + j = tail[a]; + /* if node j has been labelled, skip the arc */ + if (link[j] != 0) continue; + /* if the arc does not allow decreasing the flow through + * it, skip the arc */ + if (x[a] == 0) continue; + } + else + xassert(a != a); + /* label node j and enqueue it */ + link[j] = a, list[++pos2] = j; + /* check for breakthrough */ + if (j == t) goto brkt; + } + } + /* NONBREAKTHROUGH */ + /* no augmenting path exists; current flow is maximal */ + /* store minimal cut information, if necessary */ + if (cut != NULL) + { for (i = 1; i <= nv; i++) + cut[i] = (char)(link[i] != 0); + } + goto done; +brkt: /* BREAKTHROUGH */ + /* walk through arcs of the augmenting path (s, ..., t) found in + * the reverse order and determine maximal change of the flow */ + delta = 0; + for (j = t; j != s; j = i) + { /* arc a immediately precedes node j in the path */ + a = link[j]; + if (head[a] == j) + { /* a = i->j is a forward arc of the cycle */ + i = tail[a]; + /* x[a] may be increased until its upper bound */ + temp = cap[a] - x[a]; + } + else if (tail[a] == j) + { /* a = i<-j is a backward arc of the cycle */ + i = head[a]; + /* x[a] may be decreased until its lower bound */ + temp = x[a]; + } + else + xassert(a != a); + if (delta == 0 || delta > temp) delta = temp; + } + xassert(delta > 0); + /* increase the flow along the path */ + for (j = t; j != s; j = i) + { /* arc a immediately precedes node j in the path */ + a = link[j]; + if (head[a] == j) + { /* a = i->j is a forward arc of the cycle */ + i = tail[a]; + x[a] += delta; + } + else if (tail[a] == j) + { /* a = i<-j is a backward arc of the cycle */ + i = head[a]; + x[a] -= delta; + } + else + xassert(a != a); + } + goto loop; +done: /* free working arrays */ + xfree(ptr); + xfree(arc); + xfree(link); + xfree(list); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/ffalg.h b/resources/3rdparty/glpk-4.57/src/misc/ffalg.h new file mode 100644 index 000000000..7016f8fa6 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/ffalg.h @@ -0,0 +1,34 @@ +/* ffalg.h (Ford-Fulkerson algorithm) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2009-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef FFALG_H +#define FFALG_H + +#define ffalg _glp_ffalg +void ffalg(int nv, int na, const int tail[], const int head[], + int s, int t, const int cap[], int x[], char cut[]); +/* Ford-Fulkerson algorithm */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/fp2rat.c b/resources/3rdparty/glpk-4.57/src/misc/fp2rat.c new file mode 100644 index 000000000..4699bbd16 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/fp2rat.c @@ -0,0 +1,164 @@ +/* fp2rat.c (convert floating-point number to rational number) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "misc.h" + +/*********************************************************************** +* NAME +* +* fp2rat - convert floating-point number to rational number +* +* SYNOPSIS +* +* #include "misc.h" +* int fp2rat(double x, double eps, double *p, double *q); +* +* DESCRIPTION +* +* Given a floating-point number 0 <= x < 1 the routine fp2rat finds +* its "best" rational approximation p / q, where p >= 0 and q > 0 are +* integer numbers, such that |x - p / q| <= eps. +* +* RETURNS +* +* The routine fp2rat returns the number of iterations used to achieve +* the specified precision eps. +* +* EXAMPLES +* +* For x = sqrt(2) - 1 = 0.414213562373095 and eps = 1e-6 the routine +* gives p = 408 and q = 985, where 408 / 985 = 0.414213197969543. +* +* BACKGROUND +* +* It is well known that every positive real number x can be expressed +* as the following continued fraction: +* +* x = b[0] + a[1] +* ------------------------ +* b[1] + a[2] +* ----------------- +* b[2] + a[3] +* ---------- +* b[3] + ... +* +* where: +* +* a[k] = 1, k = 0, 1, 2, ... +* +* b[k] = floor(x[k]), k = 0, 1, 2, ... +* +* x[0] = x, +* +* x[k] = 1 / frac(x[k-1]), k = 1, 2, 3, ... +* +* To find the "best" rational approximation of x the routine computes +* partial fractions f[k] by dropping after k terms as follows: +* +* f[k] = A[k] / B[k], +* +* where: +* +* A[-1] = 1, A[0] = b[0], B[-1] = 0, B[0] = 1, +* +* A[k] = b[k] * A[k-1] + a[k] * A[k-2], +* +* B[k] = b[k] * B[k-1] + a[k] * B[k-2]. +* +* Once the condition +* +* |x - f[k]| <= eps +* +* has been satisfied, the routine reports p = A[k] and q = B[k] as the +* final answer. +* +* In the table below here is some statistics obtained for one million +* random numbers uniformly distributed in the range [0, 1). +* +* eps max p mean p max q mean q max k mean k +* ------------------------------------------------------------- +* 1e-1 8 1.6 9 3.2 3 1.4 +* 1e-2 98 6.2 99 12.4 5 2.4 +* 1e-3 997 20.7 998 41.5 8 3.4 +* 1e-4 9959 66.6 9960 133.5 10 4.4 +* 1e-5 97403 211.7 97404 424.2 13 5.3 +* 1e-6 479669 669.9 479670 1342.9 15 6.3 +* 1e-7 1579030 2127.3 3962146 4257.8 16 7.3 +* 1e-8 26188823 6749.4 26188824 13503.4 19 8.2 +* +* REFERENCES +* +* W. B. Jones and W. J. Thron, "Continued Fractions: Analytic Theory +* and Applications," Encyclopedia on Mathematics and Its Applications, +* Addison-Wesley, 1980. */ + +int fp2rat(double x, double eps, double *p, double *q) +{ int k; + double xk, Akm1, Ak, Bkm1, Bk, ak, bk, fk, temp; + xassert(0.0 <= x && x < 1.0); + for (k = 0; ; k++) + { xassert(k <= 100); + if (k == 0) + { /* x[0] = x */ + xk = x; + /* A[-1] = 1 */ + Akm1 = 1.0; + /* A[0] = b[0] = floor(x[0]) = 0 */ + Ak = 0.0; + /* B[-1] = 0 */ + Bkm1 = 0.0; + /* B[0] = 1 */ + Bk = 1.0; + } + else + { /* x[k] = 1 / frac(x[k-1]) */ + temp = xk - floor(xk); + xassert(temp != 0.0); + xk = 1.0 / temp; + /* a[k] = 1 */ + ak = 1.0; + /* b[k] = floor(x[k]) */ + bk = floor(xk); + /* A[k] = b[k] * A[k-1] + a[k] * A[k-2] */ + temp = bk * Ak + ak * Akm1; + Akm1 = Ak, Ak = temp; + /* B[k] = b[k] * B[k-1] + a[k] * B[k-2] */ + temp = bk * Bk + ak * Bkm1; + Bkm1 = Bk, Bk = temp; + } + /* f[k] = A[k] / B[k] */ + fk = Ak / Bk; +#if 0 + print("%.*g / %.*g = %.*g", + DBL_DIG, Ak, DBL_DIG, Bk, DBL_DIG, fk); +#endif + if (fabs(x - fk) <= eps) + break; + } + *p = Ak; + *q = Bk; + return k; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/gcd.c b/resources/3rdparty/glpk-4.57/src/misc/gcd.c new file mode 100644 index 000000000..95c48cc04 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/gcd.c @@ -0,0 +1,102 @@ +/* gcd.c (greatest common divisor) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "misc.h" + +/*********************************************************************** +* NAME +* +* gcd - find greatest common divisor of two integers +* +* SYNOPSIS +* +* #include "misc.h" +* int gcd(int x, int y); +* +* RETURNS +* +* The routine gcd returns gcd(x, y), the greatest common divisor of +* the two positive integers given. +* +* ALGORITHM +* +* The routine gcd is based on Euclid's algorithm. +* +* REFERENCES +* +* Don Knuth, The Art of Computer Programming, Vol.2: Seminumerical +* Algorithms, 3rd Edition, Addison-Wesley, 1997. Section 4.5.2: The +* Greatest Common Divisor, pp. 333-56. */ + +int gcd(int x, int y) +{ int r; + xassert(x > 0 && y > 0); + while (y > 0) + r = x % y, x = y, y = r; + return x; +} + +/*********************************************************************** +* NAME +* +* gcdn - find greatest common divisor of n integers +* +* SYNOPSIS +* +* #include "misc.h" +* int gcdn(int n, int x[]); +* +* RETURNS +* +* The routine gcdn returns gcd(x[1], x[2], ..., x[n]), the greatest +* common divisor of n positive integers given, n > 0. +* +* BACKGROUND +* +* The routine gcdn is based on the following identity: +* +* gcd(x, y, z) = gcd(gcd(x, y), z). +* +* REFERENCES +* +* Don Knuth, The Art of Computer Programming, Vol.2: Seminumerical +* Algorithms, 3rd Edition, Addison-Wesley, 1997. Section 4.5.2: The +* Greatest Common Divisor, pp. 333-56. */ + +int gcdn(int n, int x[]) +{ int d, j; + xassert(n > 0); + for (j = 1; j <= n; j++) + { xassert(x[j] > 0); + if (j == 1) + d = x[1]; + else + d = gcd(d, x[j]); + if (d == 1) + break; + } + return d; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/jd.c b/resources/3rdparty/glpk-4.57/src/misc/jd.c new file mode 100644 index 000000000..c9d631719 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/jd.c @@ -0,0 +1,152 @@ +/* jd.c (conversions between calendar date and Julian day number) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include +#include "jd.h" + +/*********************************************************************** +* NAME +* +* jday - convert calendar date to Julian day number +* +* SYNOPSIS +* +* #include "jd.h" +* int jday(int d, int m, int y); +* +* DESCRIPTION +* +* The routine jday converts a calendar date, Gregorian calendar, to +* corresponding Julian day number j. +* +* From the given day d, month m, and year y, the Julian day number j +* is computed without using tables. +* +* The routine is valid for 1 <= y <= 4000. +* +* RETURNS +* +* The routine jday returns the Julian day number, or negative value if +* the specified date is incorrect. +* +* REFERENCES +* +* R. G. Tantzen, Algorithm 199: conversions between calendar date and +* Julian day number, Communications of the ACM, vol. 6, no. 8, p. 444, +* Aug. 1963. */ + +int jday(int d, int m, int y) +{ int c, ya, j, dd; + if (!(1 <= d && d <= 31 && + 1 <= m && m <= 12 && + 1 <= y && y <= 4000)) + return -1; + if (m >= 3) + m -= 3; + else + m += 9, y--; + c = y / 100; + ya = y - 100 * c; + j = (146097 * c) / 4 + (1461 * ya) / 4 + (153 * m + 2) / 5 + d + + 1721119; + jdate(j, &dd, NULL, NULL); + if (d != dd) + return -1; + return j; +} + +/*********************************************************************** +* NAME +* +* jdate - convert Julian day number to calendar date +* +* SYNOPSIS +* +* #include "jd.h" +* int jdate(int j, int *d, int *m, int *y); +* +* DESCRIPTION +* +* The routine jdate converts a Julian day number j to corresponding +* calendar date, Gregorian calendar. +* +* The day d, month m, and year y are computed without using tables and +* stored in corresponding locations. +* +* The routine is valid for 1721426 <= j <= 3182395. +* +* RETURNS +* +* If the conversion is successful, the routine returns zero, otherwise +* non-zero. +* +* REFERENCES +* +* R. G. Tantzen, Algorithm 199: conversions between calendar date and +* Julian day number, Communications of the ACM, vol. 6, no. 8, p. 444, +* Aug. 1963. */ + +int jdate(int j, int *d_, int *m_, int *y_) +{ int d, m, y; + if (!(1721426 <= j && j <= 3182395)) + return 1; + j -= 1721119; + y = (4 * j - 1) / 146097; + j = (4 * j - 1) % 146097; + d = j / 4; + j = (4 * d + 3) / 1461; + d = (4 * d + 3) % 1461; + d = (d + 4) / 4; + m = (5 * d - 3) / 153; + d = (5 * d - 3) % 153; + d = (d + 5) / 5; + y = 100 * y + j; + if (m <= 9) + m += 3; + else m -= 9, + y++; + if (d_ != NULL) *d_ = d; + if (m_ != NULL) *m_ = m; + if (y_ != NULL) *y_ = y; + return 0; +} + +#ifdef GLP_TEST +#include +#include +#include + +int main(void) +{ int jbeg, jend, j, d, m, y; + jbeg = jday(1, 1, 1); + jend = jday(31, 12, 4000); + for (j = jbeg; j <= jend; j++) + { assert(jdate(j, &d, &m, &y) == 0); + assert(jday(d, m, y) == j); + } + printf("Routines jday and jdate work correctly.\n"); + return 0; +} +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/jd.h b/resources/3rdparty/glpk-4.57/src/misc/jd.h new file mode 100644 index 000000000..009d2daad --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/jd.h @@ -0,0 +1,32 @@ +/* jd.h (conversions between calendar date and Julian day number) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#define jday _glp_jday +int jday(int d, int m, int y); +/* convert calendar date to Julian day number */ + +#define jdate _glp_jdate +int jdate(int j, int *d, int *m, int *y); +/* convert Julian day number to calendar date */ + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/keller.c b/resources/3rdparty/glpk-4.57/src/misc/keller.c new file mode 100644 index 000000000..d64d3c1e2 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/keller.c @@ -0,0 +1,235 @@ +/* keller.c (cover edges by cliques, Kellerman's heuristic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2009-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "glpk.h" +#include "env.h" +#include "keller.h" + +/*********************************************************************** +* NAME +* +* kellerman - cover edges by cliques with Kellerman's heuristic +* +* SYNOPSIS +* +* #include "keller.h" +* int kellerman(int n, int (*func)(void *info, int i, int ind[]), +* void *info, glp_graph *H); +* +* DESCRIPTION +* +* The routine kellerman implements Kellerman's heuristic algorithm +* to find a minimal set of cliques which cover all edges of specified +* graph G = (V, E). +* +* The parameter n specifies the number of vertices |V|, n >= 0. +* +* Formal routine func specifies the set of edges E in the following +* way. Running the routine kellerman calls the routine func and passes +* to it parameter i, which is the number of some vertex, 1 <= i <= n. +* In response the routine func should store numbers of all vertices +* adjacent to vertex i to locations ind[1], ind[2], ..., ind[len] and +* return the value of len, which is the number of adjacent vertices, +* 0 <= len <= n. Self-loops are allowed, but ignored. Multiple edges +* are not allowed. +* +* The parameter info is a transit pointer (magic cookie) passed to the +* formal routine func as its first parameter. +* +* The result provided by the routine kellerman is the bipartite graph +* H = (V union C, F), which defines the covering found. (The program +* object of type glp_graph specified by the parameter H should be +* previously created with the routine glp_create_graph. On entry the +* routine kellerman erases the content of this object with the routine +* glp_erase_graph.) Vertices of first part V correspond to vertices of +* the graph G and have the same ordinal numbers 1, 2, ..., n. Vertices +* of second part C correspond to cliques and have ordinal numbers +* n+1, n+2, ..., n+k, where k is the total number of cliques in the +* edge covering found. Every edge f in F in the program object H is +* represented as arc f = (i->j), where i in V and j in C, which means +* that vertex i of the graph G is in clique C[j], 1 <= j <= k. (Thus, +* if two vertices of the graph G are in the same clique, these vertices +* are adjacent in G, and corresponding edge is covered by that clique.) +* +* RETURNS +* +* The routine Kellerman returns k, the total number of cliques in the +* edge covering found. +* +* REFERENCE +* +* For more details see: glpk/doc/notes/keller.pdf (in Russian). */ + +struct set +{ /* set of vertices */ + int size; + /* size (cardinality) of the set, 0 <= card <= n */ + int *list; /* int list[1+n]; */ + /* the set contains vertices list[1,...,size] */ + int *pos; /* int pos[1+n]; */ + /* pos[i] > 0 means that vertex i is in the set and + * list[pos[i]] = i; pos[i] = 0 means that vertex i is not in + * the set */ +}; + +int kellerman(int n, int (*func)(void *info, int i, int ind[]), + void *info, void /* glp_graph */ *H_) +{ glp_graph *H = H_; + struct set W_, *W = &W_, V_, *V = &V_; + glp_arc *a; + int i, j, k, m, t, len, card, best; + xassert(n >= 0); + /* H := (V, 0; 0), where V is the set of vertices of graph G */ + glp_erase_graph(H, H->v_size, H->a_size); + glp_add_vertices(H, n); + /* W := 0 */ + W->size = 0; + W->list = xcalloc(1+n, sizeof(int)); + W->pos = xcalloc(1+n, sizeof(int)); + memset(&W->pos[1], 0, sizeof(int) * n); + /* V := 0 */ + V->size = 0; + V->list = xcalloc(1+n, sizeof(int)); + V->pos = xcalloc(1+n, sizeof(int)); + memset(&V->pos[1], 0, sizeof(int) * n); + /* main loop */ + for (i = 1; i <= n; i++) + { /* W must be empty */ + xassert(W->size == 0); + /* W := { j : i > j and (i,j) in E } */ + len = func(info, i, W->list); + xassert(0 <= len && len <= n); + for (t = 1; t <= len; t++) + { j = W->list[t]; + xassert(1 <= j && j <= n); + if (j >= i) continue; + xassert(W->pos[j] == 0); + W->list[++W->size] = j, W->pos[j] = W->size; + } + /* on i-th iteration we need to cover edges (i,j) for all + * j in W */ + /* if W is empty, it is a special case */ + if (W->size == 0) + { /* set k := k + 1 and create new clique C[k] = { i } */ + k = glp_add_vertices(H, 1) - n; + glp_add_arc(H, i, n + k); + continue; + } + /* try to include vertex i into existing cliques */ + /* V must be empty */ + xassert(V->size == 0); + /* k is the number of cliques found so far */ + k = H->nv - n; + for (m = 1; m <= k; m++) + { /* do while V != W; since here V is within W, we can use + * equivalent condition: do while |V| < |W| */ + if (V->size == W->size) break; + /* check if C[m] is within W */ + for (a = H->v[n + m]->in; a != NULL; a = a->h_next) + { j = a->tail->i; + if (W->pos[j] == 0) break; + } + if (a != NULL) continue; + /* C[m] is within W, expand clique C[m] with vertex i */ + /* C[m] := C[m] union {i} */ + glp_add_arc(H, i, n + m); + /* V is a set of vertices whose incident edges are already + * covered by existing cliques */ + /* V := V union C[m] */ + for (a = H->v[n + m]->in; a != NULL; a = a->h_next) + { j = a->tail->i; + if (V->pos[j] == 0) + V->list[++V->size] = j, V->pos[j] = V->size; + } + } + /* remove from set W the vertices whose incident edges are + * already covered by existing cliques */ + /* W := W \ V, V := 0 */ + for (t = 1; t <= V->size; t++) + { j = V->list[t], V->pos[j] = 0; + if (W->pos[j] != 0) + { /* remove vertex j from W */ + if (W->pos[j] != W->size) + { int jj = W->list[W->size]; + W->list[W->pos[j]] = jj; + W->pos[jj] = W->pos[j]; + } + W->size--, W->pos[j] = 0; + } + } + V->size = 0; + /* now set W contains only vertices whose incident edges are + * still not covered by existing cliques; create new cliques + * to cover remaining edges until set W becomes empty */ + while (W->size > 0) + { /* find clique C[m], 1 <= m <= k, which shares maximal + * number of vertices with W; to break ties choose clique + * having smallest number m */ + m = 0, best = -1; + k = H->nv - n; + for (t = 1; t <= k; t++) + { /* compute cardinality of intersection of W and C[t] */ + card = 0; + for (a = H->v[n + t]->in; a != NULL; a = a->h_next) + { j = a->tail->i; + if (W->pos[j] != 0) card++; + } + if (best < card) + m = t, best = card; + } + xassert(m > 0); + /* set k := k + 1 and create new clique: + * C[k] := (W intersect C[m]) union { i }, which covers all + * edges incident to vertices from (W intersect C[m]) */ + k = glp_add_vertices(H, 1) - n; + for (a = H->v[n + m]->in; a != NULL; a = a->h_next) + { j = a->tail->i; + if (W->pos[j] != 0) + { /* vertex j is in both W and C[m]; include it in new + * clique C[k] */ + glp_add_arc(H, j, n + k); + /* remove vertex j from W, since edge (i,j) will be + * covered by new clique C[k] */ + if (W->pos[j] != W->size) + { int jj = W->list[W->size]; + W->list[W->pos[j]] = jj; + W->pos[jj] = W->pos[j]; + } + W->size--, W->pos[j] = 0; + } + } + /* include vertex i to new clique C[k] to cover edges (i,j) + * incident to all vertices j just removed from W */ + glp_add_arc(H, i, n + k); + } + } + /* free working arrays */ + xfree(W->list); + xfree(W->pos); + xfree(V->list); + xfree(V->pos); + /* return the number of cliques in the edge covering found */ + return H->nv - n; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/keller.h b/resources/3rdparty/glpk-4.57/src/misc/keller.h new file mode 100644 index 000000000..d7a5b3431 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/keller.h @@ -0,0 +1,34 @@ +/* keller.h (cover edges by cliques, Kellerman's heuristic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2009-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef KELLER_H +#define KELLER_H + +#define kellerman _glp_kellerman +int kellerman(int n, int (*func)(void *info, int i, int ind[]), + void *info, void /* glp_graph */ *H); +/* cover edges by cliques with Kellerman's heuristic */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/mc13d.c b/resources/3rdparty/glpk-4.57/src/misc/mc13d.c new file mode 100644 index 000000000..d8bab398d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/mc13d.c @@ -0,0 +1,314 @@ +/* mc13d.c (permutations to block triangular form) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* This code is the result of translation of the Fortran subroutines +* MC13D and MC13E associated with the following paper: +* +* I.S.Duff, J.K.Reid, Algorithm 529: Permutations to block triangular +* form, ACM Trans. on Math. Softw. 4 (1978), 189-192. +* +* Use of ACM Algorithms is subject to the ACM Software Copyright and +* License Agreement. See . +* +* The translation was made by Andrew Makhorin . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "mc13d.h" + +/*********************************************************************** +* NAME +* +* mc13d - permutations to block triangular form +* +* SYNOPSIS +* +* #include "mc13d.h" +* int mc13d(int n, const int icn[], const int ip[], const int lenr[], +* int ior[], int ib[], int lowl[], int numb[], int prev[]); +* +* DESCRIPTION +* +* Given the column numbers of the nonzeros in each row of the sparse +* matrix, the routine mc13d finds a symmetric permutation that makes +* the matrix block lower triangular. +* +* INPUT PARAMETERS +* +* n order of the matrix. +* +* icn array containing the column indices of the non-zeros. Those +* belonging to a single row must be contiguous but the ordering +* of column indices within each row is unimportant and wasted +* space between rows is permitted. +* +* ip ip[i], i = 1,2,...,n, is the position in array icn of the +* first column index of a non-zero in row i. +* +* lenr lenr[i], i = 1,2,...,n, is the number of non-zeros in row i. +* +* OUTPUT PARAMETERS +* +* ior ior[i], i = 1,2,...,n, gives the position on the original +* ordering of the row or column which is in position i in the +* permuted form. +* +* ib ib[i], i = 1,2,...,num, is the row number in the permuted +* matrix of the beginning of block i, 1 <= num <= n. +* +* WORKING ARRAYS +* +* arp working array of length [1+n], where arp[0] is not used. +* arp[i] is one less than the number of unsearched edges leaving +* node i. At the end of the algorithm it is set to a permutation +* which puts the matrix in block lower triangular form. +* +* ib working array of length [1+n], where ib[0] is not used. +* ib[i] is the position in the ordering of the start of the ith +* block. ib[n+1-i] holds the node number of the ith node on the +* stack. +* +* lowl working array of length [1+n], where lowl[0] is not used. +* lowl[i] is the smallest stack position of any node to which a +* path from node i has been found. It is set to n+1 when node i +* is removed from the stack. +* +* numb working array of length [1+n], where numb[0] is not used. +* numb[i] is the position of node i in the stack if it is on it, +* is the permuted order of node i for those nodes whose final +* position has been found and is otherwise zero. +* +* prev working array of length [1+n], where prev[0] is not used. +* prev[i] is the node at the end of the path when node i was +* placed on the stack. +* +* RETURNS +* +* The routine mc13d returns num, the number of blocks found. */ + +int mc13d(int n, const int icn[], const int ip[], const int lenr[], + int ior[], int ib[], int lowl[], int numb[], int prev[]) +{ int *arp = ior; + int dummy, i, i1, i2, icnt, ii, isn, ist, ist1, iv, iw, j, lcnt, + nnm1, num, stp; + /* icnt is the number of nodes whose positions in final ordering + * have been found. */ + icnt = 0; + /* num is the number of blocks that have been found. */ + num = 0; + nnm1 = n + n - 1; + /* Initialization of arrays. */ + for (j = 1; j <= n; j++) + { numb[j] = 0; + arp[j] = lenr[j] - 1; + } + for (isn = 1; isn <= n; isn++) + { /* Look for a starting node. */ + if (numb[isn] != 0) continue; + iv = isn; + /* ist is the number of nodes on the stack ... it is the stack + * pointer. */ + ist = 1; + /* Put node iv at beginning of stack. */ + lowl[iv] = numb[iv] = 1; + ib[n] = iv; + /* The body of this loop puts a new node on the stack or + * backtracks. */ + for (dummy = 1; dummy <= nnm1; dummy++) + { i1 = arp[iv]; + /* Have all edges leaving node iv been searched? */ + if (i1 >= 0) + { i2 = ip[iv] + lenr[iv] - 1; + i1 = i2 - i1; + /* Look at edges leaving node iv until one enters a new + * node or all edges are exhausted. */ + for (ii = i1; ii <= i2; ii++) + { iw = icn[ii]; + /* Has node iw been on stack already? */ + if (numb[iw] == 0) goto L70; + /* Update value of lowl[iv] if necessary. */ + if (lowl[iw] < lowl[iv]) lowl[iv] = lowl[iw]; + } + /* There are no more edges leaving node iv. */ + arp[iv] = -1; + } + /* Is node iv the root of a block? */ + if (lowl[iv] < numb[iv]) goto L60; + /* Order nodes in a block. */ + num++; + ist1 = n + 1 - ist; + lcnt = icnt + 1; + /* Peel block off the top of the stack starting at the top + * and working down to the root of the block. */ + for (stp = ist1; stp <= n; stp++) + { iw = ib[stp]; + lowl[iw] = n + 1; + numb[iw] = ++icnt; + if (iw == iv) break; + } + ist = n - stp; + ib[num] = lcnt; + /* Are there any nodes left on the stack? */ + if (ist != 0) goto L60; + /* Have all the nodes been ordered? */ + if (icnt < n) break; + goto L100; +L60: /* Backtrack to previous node on path. */ + iw = iv; + iv = prev[iv]; + /* Update value of lowl[iv] if necessary. */ + if (lowl[iw] < lowl[iv]) lowl[iv] = lowl[iw]; + continue; +L70: /* Put new node on the stack. */ + arp[iv] = i2 - ii - 1; + prev[iw] = iv; + iv = iw; + lowl[iv] = numb[iv] = ++ist; + ib[n+1-ist] = iv; + } + } +L100: /* Put permutation in the required form. */ + for (i = 1; i <= n; i++) + arp[numb[i]] = i; + return num; +} + +/**********************************************************************/ + +#ifdef GLP_TEST +#include "env.h" + +void test(int n, int ipp); + +int main(void) +{ /* test program for routine mc13d */ + test( 1, 0); + test( 2, 1); + test( 2, 2); + test( 3, 3); + test( 4, 4); + test( 5, 10); + test(10, 10); + test(10, 20); + test(20, 20); + test(20, 50); + test(50, 50); + test(50, 200); + return 0; +} + +void fa01bs(int max, int *nrand); + +void setup(int n, char a[1+50][1+50], int ip[], int icn[], int lenr[]); + +void test(int n, int ipp) +{ int ip[1+50], icn[1+1000], ior[1+50], ib[1+51], iw[1+150], + lenr[1+50]; + char a[1+50][1+50], hold[1+100]; + int i, ii, iblock, ij, index, j, jblock, jj, k9, num; + xprintf("\n\n\nMatrix is of order %d and has %d off-diagonal non-" + "zeros\n", n, ipp); + for (j = 1; j <= n; j++) + { for (i = 1; i <= n; i++) + a[i][j] = 0; + a[j][j] = 1; + } + for (k9 = 1; k9 <= ipp; k9++) + { /* these statements should be replaced by calls to your + * favorite random number generator to place two pseudo-random + * numbers between 1 and n in the variables i and j */ + for (;;) + { fa01bs(n, &i); + fa01bs(n, &j); + if (!a[i][j]) break; + } + a[i][j] = 1; + } + /* setup converts matrix a[i,j] to required sparsity-oriented + * storage format */ + setup(n, a, ip, icn, lenr); + num = mc13d(n, icn, ip, lenr, ior, ib, &iw[0], &iw[n], &iw[n+n]); + /* output reordered matrix with blocking to improve clarity */ + xprintf("\nThe reordered matrix which has %d block%s is of the fo" + "rm\n", num, num == 1 ? "" : "s"); + ib[num+1] = n + 1; + index = 100; + iblock = 1; + for (i = 1; i <= n; i++) + { for (ij = 1; ij <= index; ij++) + hold[ij] = ' '; + if (i == ib[iblock]) + { xprintf("\n"); + iblock++; + } + jblock = 1; + index = 0; + for (j = 1; j <= n; j++) + { if (j == ib[jblock]) + { hold[++index] = ' '; + jblock++; + } + ii = ior[i]; + jj = ior[j]; + hold[++index] = (char)(a[ii][jj] ? 'X' : '0'); + } + xprintf("%.*s\n", index, &hold[1]); + } + xprintf("\nThe starting point for each block is given by\n"); + for (i = 1; i <= num; i++) + { if ((i - 1) % 12 == 0) xprintf("\n"); + xprintf(" %4d", ib[i]); + } + xprintf("\n"); + return; +} + +void setup(int n, char a[1+50][1+50], int ip[], int icn[], int lenr[]) +{ int i, j, ind; + for (i = 1; i <= n; i++) + lenr[i] = 0; + ind = 1; + for (i = 1; i <= n; i++) + { ip[i] = ind; + for (j = 1; j <= n; j++) + { if (a[i][j]) + { lenr[i]++; + icn[ind++] = j; + } + } + } + return; +} + +double g = 1431655765.0; + +double fa01as(int i) +{ /* random number generator */ + g = fmod(g * 9228907.0, 4294967296.0); + if (i >= 0) + return g / 4294967296.0; + else + return 2.0 * g / 4294967296.0 - 1.0; +} + +void fa01bs(int max, int *nrand) +{ *nrand = (int)(fa01as(1) * (double)max) + 1; + return; +} +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/mc13d.h b/resources/3rdparty/glpk-4.57/src/misc/mc13d.h new file mode 100644 index 000000000..bdd57a19a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/mc13d.h @@ -0,0 +1,34 @@ +/* mc13d.h */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2009-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef MC13D_H +#define MC13D_H + +#define mc13d _glp_mc13d +int mc13d(int n, const int icn[], const int ip[], const int lenr[], + int ior[], int ib[], int lowl[], int numb[], int prev[]); +/* permutations to block triangular form */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/mc21a.c b/resources/3rdparty/glpk-4.57/src/misc/mc21a.c new file mode 100644 index 000000000..700d0f4e2 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/mc21a.c @@ -0,0 +1,301 @@ +/* mc21a.c (permutations for zero-free diagonal) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* This code is the result of translation of the Fortran subroutines +* MC21A and MC21B associated with the following paper: +* +* I.S.Duff, Algorithm 575: Permutations for zero-free diagonal, ACM +* Trans. on Math. Softw. 7 (1981), 387-390. +* +* Use of ACM Algorithms is subject to the ACM Software Copyright and +* License Agreement. See . +* +* The translation was made by Andrew Makhorin . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "mc21a.h" + +/*********************************************************************** +* NAME +* +* mc21a - permutations for zero-free diagonal +* +* SYNOPSIS +* +* #include "mc21a.h" +* int mc21a(int n, const int icn[], const int ip[], const int lenr[], +* int iperm[], int pr[], int arp[], int cv[], int out[]); +* +* DESCRIPTION +* +* Given the pattern of nonzeros of a sparse matrix, the routine mc21a +* attempts to find a permutation of its rows that makes the matrix have +* no zeros on its diagonal. +* +* INPUT PARAMETERS +* +* n order of matrix. +* +* icn array containing the column indices of the non-zeros. Those +* belonging to a single row must be contiguous but the ordering +* of column indices within each row is unimportant and wasted +* space between rows is permitted. +* +* ip ip[i], i = 1,2,...,n, is the position in array icn of the +* first column index of a non-zero in row i. +* +* lenr lenr[i], i = 1,2,...,n, is the number of non-zeros in row i. +* +* OUTPUT PARAMETER +* +* iperm contains permutation to make diagonal have the smallest +* number of zeros on it. Elements (iperm[i], i), i = 1,2,...,n, +* are non-zero at the end of the algorithm unless the matrix is +* structurally singular. In this case, (iperm[i], i) will be +* zero for n - numnz entries. +* +* WORKING ARRAYS +* +* pr working array of length [1+n], where pr[0] is not used. +* pr[i] is the previous row to i in the depth first search. +* +* arp working array of length [1+n], where arp[0] is not used. +* arp[i] is one less than the number of non-zeros in row i which +* have not been scanned when looking for a cheap assignment. +* +* cv working array of length [1+n], where cv[0] is not used. +* cv[i] is the most recent row extension at which column i was +* visited. +* +* out working array of length [1+n], where out[0] is not used. +* out[i] is one less than the number of non-zeros in row i +* which have not been scanned during one pass through the main +* loop. +* +* RETURNS +* +* The routine mc21a returns numnz, the number of non-zeros on diagonal +* of permuted matrix. */ + +int mc21a(int n, const int icn[], const int ip[], const int lenr[], + int iperm[], int pr[], int arp[], int cv[], int out[]) +{ int i, ii, in1, in2, j, j1, jord, k, kk, numnz; + /* Initialization of arrays. */ + for (i = 1; i <= n; i++) + { arp[i] = lenr[i] - 1; + cv[i] = iperm[i] = 0; + } + numnz = 0; + /* Main loop. */ + /* Each pass round this loop either results in a new assignment + * or gives a row with no assignment. */ + for (jord = 1; jord <= n; jord++) + { j = jord; + pr[j] = -1; + for (k = 1; k <= jord; k++) + { /* Look for a cheap assignment. */ + in1 = arp[j]; + if (in1 >= 0) + { in2 = ip[j] + lenr[j] - 1; + in1 = in2 - in1; + for (ii = in1; ii <= in2; ii++) + { i = icn[ii]; + if (iperm[i] == 0) goto L110; + } + /* No cheap assignment in row. */ + arp[j] = -1; + } + /* Begin looking for assignment chain starting with row j.*/ + out[j] = lenr[j] - 1; + /* Inner loop. Extends chain by one or backtracks. */ + for (kk = 1; kk <= jord; kk++) + { in1 = out[j]; + if (in1 >= 0) + { in2 = ip[j] + lenr[j] - 1; + in1 = in2 - in1; + /* Forward scan. */ + for (ii = in1; ii <= in2; ii++) + { i = icn[ii]; + if (cv[i] != jord) + { /* Column i has not yet been accessed during + * this pass. */ + j1 = j; + j = iperm[i]; + cv[i] = jord; + pr[j] = j1; + out[j1] = in2 - ii - 1; + goto L100; + } + } + } + /* Backtracking step. */ + j = pr[j]; + if (j == -1) goto L130; + } +L100: ; + } +L110: /* New assignment is made. */ + iperm[i] = j; + arp[j] = in2 - ii - 1; + numnz++; + for (k = 1; k <= jord; k++) + { j = pr[j]; + if (j == -1) break; + ii = ip[j] + lenr[j] - out[j] - 2; + i = icn[ii]; + iperm[i] = j; + } +L130: ; + } + /* If matrix is structurally singular, we now complete the + * permutation iperm. */ + if (numnz < n) + { for (i = 1; i <= n; i++) + arp[i] = 0; + k = 0; + for (i = 1; i <= n; i++) + { if (iperm[i] == 0) + out[++k] = i; + else + arp[iperm[i]] = i; + } + k = 0; + for (i = 1; i <= n; i++) + { if (arp[i] == 0) + iperm[out[++k]] = i; + } + } + return numnz; +} + +/**********************************************************************/ + +#ifdef GLP_TEST +#include "env.h" + +int sing; + +void ranmat(int m, int n, int icn[], int iptr[], int nnnp1, int *knum, + int iw[]); + +void fa01bs(int max, int *nrand); + +int main(void) +{ /* test program for the routine mc21a */ + /* these runs on random matrices cause all possible statements in + * mc21a to be executed */ + int i, iold, j, j1, j2, jj, knum, l, licn, n, nov4, num, numnz; + int ip[1+21], icn[1+1000], iperm[1+20], lenr[1+20], iw1[1+80]; + licn = 1000; + /* run on random matrices of orders 1 through 20 */ + for (n = 1; n <= 20; n++) + { nov4 = n / 4; + if (nov4 < 1) nov4 = 1; +L10: fa01bs(nov4, &l); + knum = l * n; + /* knum is requested number of non-zeros in random matrix */ + if (knum > licn) goto L10; + /* if sing is false, matrix is guaranteed structurally + * non-singular */ + sing = ((n / 2) * 2 == n); + /* call to subroutine to generate random matrix */ + ranmat(n, n, icn, ip, n+1, &knum, iw1); + /* knum is now actual number of non-zeros in random matrix */ + if (knum > licn) goto L10; + xprintf("n = %2d; nz = %4d; sing = %d\n", n, knum, sing); + /* set up array of row lengths */ + for (i = 1; i <= n; i++) + lenr[i] = ip[i+1] - ip[i]; + /* call to mc21a */ + numnz = mc21a(n, icn, ip, lenr, iperm, &iw1[0], &iw1[n], + &iw1[n+n], &iw1[n+n+n]); + /* testing to see if there are numnz non-zeros on the diagonal + * of the permuted matrix. */ + num = 0; + for (i = 1; i <= n; i++) + { iold = iperm[i]; + j1 = ip[iold]; + j2 = j1 + lenr[iold] - 1; + if (j2 < j1) continue; + for (jj = j1; jj <= j2; jj++) + { j = icn[jj]; + if (j == i) + { num++; + break; + } + } + } + if (num != numnz) + xprintf("Failure in mc21a, numnz = %d instead of %d\n", + numnz, num); + } + return 0; +} + +void ranmat(int m, int n, int icn[], int iptr[], int nnnp1, int *knum, + int iw[]) +{ /* subroutine to generate random matrix */ + int i, ii, inum, j, lrow, matnum; + inum = (*knum / n) * 2; + if (inum > n-1) inum = n-1; + matnum = 1; + /* each pass through this loop generates a row of the matrix */ + for (j = 1; j <= m; j++) + { iptr[j] = matnum; + if (!(sing || j > n)) + icn[matnum++] = j; + if (n == 1) continue; + for (i = 1; i <= n; i++) iw[i] = 0; + if (!sing) iw[j] = 1; + fa01bs(inum, &lrow); + lrow--; + if (lrow == 0) continue; + /* lrow off-diagonal non-zeros in row j of the matrix */ + for (ii = 1; ii <= lrow; ii++) + { for (;;) + { fa01bs(n, &i); + if (iw[i] != 1) break; + } + iw[i] = 1; + icn[matnum++] = i; + } + } + for (i = m+1; i <= nnnp1; i++) + iptr[i] = matnum; + *knum = matnum - 1; + return; +} + +double g = 1431655765.0; + +double fa01as(int i) +{ /* random number generator */ + g = fmod(g * 9228907.0, 4294967296.0); + if (i >= 0) + return g / 4294967296.0; + else + return 2.0 * g / 4294967296.0 - 1.0; +} + +void fa01bs(int max, int *nrand) +{ *nrand = (int)(fa01as(1) * (double)max) + 1; + return; +} +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/mc21a.h b/resources/3rdparty/glpk-4.57/src/misc/mc21a.h new file mode 100644 index 000000000..755f28b22 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/mc21a.h @@ -0,0 +1,34 @@ +/* mc21a.h (permutations for zero-free diagonal) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2009-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef MC21A_H +#define MC21A_H + +#define mc21a _glp_mc21a +int mc21a(int n, const int icn[], const int ip[], const int lenr[], + int iperm[], int pr[], int arp[], int cv[], int out[]); +/* permutations for zero-free diagonal */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/misc.h b/resources/3rdparty/glpk-4.57/src/misc/misc.h new file mode 100644 index 000000000..1ba1dc505 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/misc.h @@ -0,0 +1,61 @@ +/* misc.h (miscellaneous routines) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef MISC_H +#define MISC_H + +#define str2int _glp_str2int +int str2int(const char *str, int *val); +/* convert character string to value of int type */ + +#define str2num _glp_str2num +int str2num(const char *str, double *val); +/* convert character string to value of double type */ + +#define strspx _glp_strspx +char *strspx(char *str); +/* remove all spaces from character string */ + +#define strtrim _glp_strtrim +char *strtrim(char *str); +/* remove trailing spaces from character string */ + +#define gcd _glp_gcd +int gcd(int x, int y); +/* find greatest common divisor of two integers */ + +#define gcdn _glp_gcdn +int gcdn(int n, int x[]); +/* find greatest common divisor of n integers */ + +#define round2n _glp_round2n +double round2n(double x); +/* round floating-point number to nearest power of two */ + +#define fp2rat _glp_fp2rat +int fp2rat(double x, double eps, double *p, double *q); +/* convert floating-point number to rational number */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/okalg.c b/resources/3rdparty/glpk-4.57/src/misc/okalg.c new file mode 100644 index 000000000..8eecd6df8 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/okalg.c @@ -0,0 +1,382 @@ +/* okalg.c (out-of-kilter algorithm) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2009-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "okalg.h" + +/*********************************************************************** +* NAME +* +* okalg - out-of-kilter algorithm +* +* SYNOPSIS +* +* #include "okalg.h" +* int okalg(int nv, int na, const int tail[], const int head[], +* const int low[], const int cap[], const int cost[], int x[], +* int pi[]); +* +* DESCRIPTION +* +* The routine okalg implements the out-of-kilter algorithm to find a +* minimal-cost circulation in the specified flow network. +* +* INPUT PARAMETERS +* +* nv is the number of nodes, nv >= 0. +* +* na is the number of arcs, na >= 0. +* +* tail[a], a = 1,...,na, is the index of tail node of arc a. +* +* head[a], a = 1,...,na, is the index of head node of arc a. +* +* low[a], a = 1,...,na, is an lower bound to the flow through arc a. +* +* cap[a], a = 1,...,na, is an upper bound to the flow through arc a, +* which is the capacity of the arc. +* +* cost[a], a = 1,...,na, is a per-unit cost of the flow through arc a. +* +* NOTES +* +* 1. Multiple arcs are allowed, but self-loops are not allowed. +* +* 2. It is required that 0 <= low[a] <= cap[a] for all arcs. +* +* 3. Arc costs may have any sign. +* +* OUTPUT PARAMETERS +* +* x[a], a = 1,...,na, is optimal value of the flow through arc a. +* +* pi[i], i = 1,...,nv, is Lagrange multiplier for flow conservation +* equality constraint corresponding to node i (the node potential). +* +* RETURNS +* +* 0 optimal circulation found; +* +* 1 there is no feasible circulation; +* +* 2 integer overflow occured; +* +* 3 optimality test failed (logic error). +* +* REFERENCES +* +* L.R.Ford, Jr., and D.R.Fulkerson, "Flows in Networks," The RAND +* Corp., Report R-375-PR (August 1962), Chap. III "Minimal Cost Flow +* Problems," pp.113-26. */ + +static int overflow(int u, int v) +{ /* check for integer overflow on computing u + v */ + if (u > 0 && v > 0 && u + v < 0) return 1; + if (u < 0 && v < 0 && u + v > 0) return 1; + return 0; +} + +int okalg(int nv, int na, const int tail[], const int head[], + const int low[], const int cap[], const int cost[], int x[], + int pi[]) +{ int a, aok, delta, i, j, k, lambda, pos1, pos2, s, t, temp, ret, + *ptr, *arc, *link, *list; + /* sanity checks */ + xassert(nv >= 0); + xassert(na >= 0); + for (a = 1; a <= na; a++) + { i = tail[a], j = head[a]; + xassert(1 <= i && i <= nv); + xassert(1 <= j && j <= nv); + xassert(i != j); + xassert(0 <= low[a] && low[a] <= cap[a]); + } + /* allocate working arrays */ + ptr = xcalloc(1+nv+1, sizeof(int)); + arc = xcalloc(1+na+na, sizeof(int)); + link = xcalloc(1+nv, sizeof(int)); + list = xcalloc(1+nv, sizeof(int)); + /* ptr[i] := (degree of node i) */ + for (i = 1; i <= nv; i++) + ptr[i] = 0; + for (a = 1; a <= na; a++) + { ptr[tail[a]]++; + ptr[head[a]]++; + } + /* initialize arc pointers */ + ptr[1]++; + for (i = 1; i < nv; i++) + ptr[i+1] += ptr[i]; + ptr[nv+1] = ptr[nv]; + /* build arc lists */ + for (a = 1; a <= na; a++) + { arc[--ptr[tail[a]]] = a; + arc[--ptr[head[a]]] = a; + } + xassert(ptr[1] == 1); + xassert(ptr[nv+1] == na+na+1); + /* now the indices of arcs incident to node i are stored in + * locations arc[ptr[i]], arc[ptr[i]+1], ..., arc[ptr[i+1]-1] */ + /* initialize arc flows and node potentials */ + for (a = 1; a <= na; a++) + x[a] = 0; + for (i = 1; i <= nv; i++) + pi[i] = 0; +loop: /* main loop starts here */ + /* find out-of-kilter arc */ + aok = 0; + for (a = 1; a <= na; a++) + { i = tail[a], j = head[a]; + if (overflow(cost[a], pi[i] - pi[j])) + { ret = 2; + goto done; + } + lambda = cost[a] + (pi[i] - pi[j]); + if (x[a] < low[a] || (lambda < 0 && x[a] < cap[a])) + { /* arc a = i->j is out of kilter, and we need to increase + * the flow through this arc */ + aok = a, s = j, t = i; + break; + } + if (x[a] > cap[a] || (lambda > 0 && x[a] > low[a])) + { /* arc a = i->j is out of kilter, and we need to decrease + * the flow through this arc */ + aok = a, s = i, t = j; + break; + } + } + if (aok == 0) + { /* all arcs are in kilter */ + /* check for feasibility */ + for (a = 1; a <= na; a++) + { if (!(low[a] <= x[a] && x[a] <= cap[a])) + { ret = 3; + goto done; + } + } + for (i = 1; i <= nv; i++) + { temp = 0; + for (k = ptr[i]; k < ptr[i+1]; k++) + { a = arc[k]; + if (tail[a] == i) + { /* a is outgoing arc */ + temp += x[a]; + } + else if (head[a] == i) + { /* a is incoming arc */ + temp -= x[a]; + } + else + xassert(a != a); + } + if (temp != 0) + { ret = 3; + goto done; + } + } + /* check for optimality */ + for (a = 1; a <= na; a++) + { i = tail[a], j = head[a]; + lambda = cost[a] + (pi[i] - pi[j]); + if ((lambda > 0 && x[a] != low[a]) || + (lambda < 0 && x[a] != cap[a])) + { ret = 3; + goto done; + } + } + /* current circulation is optimal */ + ret = 0; + goto done; + } + /* now we need to find a cycle (t, a, s, ..., t), which allows + * increasing the flow along it, where a is the out-of-kilter arc + * just found */ + /* link[i] = 0 means that node i is not labelled yet; + * link[i] = a means that arc a immediately precedes node i */ + /* initially only node s is labelled */ + for (i = 1; i <= nv; i++) + link[i] = 0; + link[s] = aok, list[1] = s, pos1 = pos2 = 1; + /* breadth first search */ + while (pos1 <= pos2) + { /* dequeue node i */ + i = list[pos1++]; + /* consider all arcs incident to node i */ + for (k = ptr[i]; k < ptr[i+1]; k++) + { a = arc[k]; + if (tail[a] == i) + { /* a = i->j is a forward arc from s to t */ + j = head[a]; + /* if node j has been labelled, skip the arc */ + if (link[j] != 0) continue; + /* if the arc does not allow increasing the flow through + * it, skip the arc */ + if (x[a] >= cap[a]) continue; + if (overflow(cost[a], pi[i] - pi[j])) + { ret = 2; + goto done; + } + lambda = cost[a] + (pi[i] - pi[j]); + if (lambda > 0 && x[a] >= low[a]) continue; + } + else if (head[a] == i) + { /* a = i<-j is a backward arc from s to t */ + j = tail[a]; + /* if node j has been labelled, skip the arc */ + if (link[j] != 0) continue; + /* if the arc does not allow decreasing the flow through + * it, skip the arc */ + if (x[a] <= low[a]) continue; + if (overflow(cost[a], pi[j] - pi[i])) + { ret = 2; + goto done; + } + lambda = cost[a] + (pi[j] - pi[i]); + if (lambda < 0 && x[a] <= cap[a]) continue; + } + else + xassert(a != a); + /* label node j and enqueue it */ + link[j] = a, list[++pos2] = j; + /* check for breakthrough */ + if (j == t) goto brkt; + } + } + /* NONBREAKTHROUGH */ + /* consider all arcs, whose one endpoint is labelled and other is + * not, and determine maximal change of node potentials */ + delta = 0; + for (a = 1; a <= na; a++) + { i = tail[a], j = head[a]; + if (link[i] != 0 && link[j] == 0) + { /* a = i->j, where node i is labelled, node j is not */ + if (overflow(cost[a], pi[i] - pi[j])) + { ret = 2; + goto done; + } + lambda = cost[a] + (pi[i] - pi[j]); + if (x[a] <= cap[a] && lambda > 0) + if (delta == 0 || delta > + lambda) delta = + lambda; + } + else if (link[i] == 0 && link[j] != 0) + { /* a = j<-i, where node j is labelled, node i is not */ + if (overflow(cost[a], pi[i] - pi[j])) + { ret = 2; + goto done; + } + lambda = cost[a] + (pi[i] - pi[j]); + if (x[a] >= low[a] && lambda < 0) + if (delta == 0 || delta > - lambda) delta = - lambda; + } + } + if (delta == 0) + { /* there is no feasible circulation */ + ret = 1; + goto done; + } + /* increase potentials of all unlabelled nodes */ + for (i = 1; i <= nv; i++) + { if (link[i] == 0) + { if (overflow(pi[i], delta)) + { ret = 2; + goto done; + } + pi[i] += delta; + } + } + goto loop; +brkt: /* BREAKTHROUGH */ + /* walk through arcs of the cycle (t, a, s, ..., t) found in the + * reverse order and determine maximal change of the flow */ + delta = 0; + for (j = t;; j = i) + { /* arc a immediately precedes node j in the cycle */ + a = link[j]; + if (head[a] == j) + { /* a = i->j is a forward arc of the cycle */ + i = tail[a]; + lambda = cost[a] + (pi[i] - pi[j]); + if (lambda > 0 && x[a] < low[a]) + { /* x[a] may be increased until its lower bound */ + temp = low[a] - x[a]; + } + else if (lambda <= 0 && x[a] < cap[a]) + { /* x[a] may be increased until its upper bound */ + temp = cap[a] - x[a]; + } + else + xassert(a != a); + } + else if (tail[a] == j) + { /* a = i<-j is a backward arc of the cycle */ + i = head[a]; + lambda = cost[a] + (pi[j] - pi[i]); + if (lambda < 0 && x[a] > cap[a]) + { /* x[a] may be decreased until its upper bound */ + temp = x[a] - cap[a]; + } + else if (lambda >= 0 && x[a] > low[a]) + { /* x[a] may be decreased until its lower bound */ + temp = x[a] - low[a]; + } + else + xassert(a != a); + } + else + xassert(a != a); + if (delta == 0 || delta > temp) delta = temp; + /* check for end of the cycle */ + if (i == t) break; + } + xassert(delta > 0); + /* increase the flow along the cycle */ + for (j = t;; j = i) + { /* arc a immediately precedes node j in the cycle */ + a = link[j]; + if (head[a] == j) + { /* a = i->j is a forward arc of the cycle */ + i = tail[a]; + /* overflow cannot occur */ + x[a] += delta; + } + else if (tail[a] == j) + { /* a = i<-j is a backward arc of the cycle */ + i = head[a]; + /* overflow cannot occur */ + x[a] -= delta; + } + else + xassert(a != a); + /* check for end of the cycle */ + if (i == t) break; + } + goto loop; +done: /* free working arrays */ + xfree(ptr); + xfree(arc); + xfree(link); + xfree(list); + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/okalg.h b/resources/3rdparty/glpk-4.57/src/misc/okalg.h new file mode 100644 index 000000000..2f2d97403 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/okalg.h @@ -0,0 +1,35 @@ +/* okalg.h (out-of-kilter algorithm) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2009-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef OKALG_H +#define OKALG_H + +#define okalg _glp_okalg +int okalg(int nv, int na, const int tail[], const int head[], + const int low[], const int cap[], const int cost[], int x[], + int pi[]); +/* out-of-kilter algorithm */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/qmd.c b/resources/3rdparty/glpk-4.57/src/misc/qmd.c new file mode 100644 index 000000000..a3397dcf9 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/qmd.c @@ -0,0 +1,584 @@ +/* qmd.c (quotient minimum degree algorithm) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* THIS CODE IS THE RESULT OF TRANSLATION OF THE FORTRAN SUBROUTINES +* GENQMD, QMDRCH, QMDQT, QMDUPD, AND QMDMRG FROM THE BOOK: +* +* ALAN GEORGE, JOSEPH W-H LIU. COMPUTER SOLUTION OF LARGE SPARSE +* POSITIVE DEFINITE SYSTEMS. PRENTICE-HALL, 1981. +* +* THE TRANSLATION HAS BEEN DONE WITH THE PERMISSION OF THE AUTHORS +* OF THE ORIGINAL FORTRAN SUBROUTINES: ALAN GEORGE AND JOSEPH LIU, +* UNIVERSITY OF WATERLOO, WATERLOO, ONTARIO, CANADA. +* +* The translation was made by Andrew Makhorin . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "qmd.h" + +/*********************************************************************** +* NAME +* +* genqmd - GENeral Quotient Minimum Degree algorithm +* +* SYNOPSIS +* +* #include "qmd.h" +* void genqmd(int *neqns, int xadj[], int adjncy[], int perm[], +* int invp[], int deg[], int marker[], int rchset[], int nbrhd[], +* int qsize[], int qlink[], int *nofsub); +* +* PURPOSE +* +* This routine implements the minimum degree algorithm. It makes use +* of the implicit representation of the elimination graph by quotient +* graphs, and the notion of indistinguishable nodes. +* +* CAUTION +* +* The adjancy vector adjncy will be destroyed. +* +* INPUT PARAMETERS +* +* neqns - number of equations; +* (xadj, adjncy) - +* the adjancy structure. +* +* OUTPUT PARAMETERS +* +* perm - the minimum degree ordering; +* invp - the inverse of perm. +* +* WORKING PARAMETERS +* +* deg - the degree vector. deg[i] is negative means node i has been +* numbered; +* marker - a marker vector, where marker[i] is negative means node i +* has been merged with another nodeand thus can be ignored; +* rchset - vector used for the reachable set; +* nbrhd - vector used for neighborhood set; +* qsize - vector used to store the size of indistinguishable +* supernodes; +* qlink - vector used to store indistinguishable nodes, i, qlink[i], +* qlink[qlink[i]], ... are the members of the supernode +* represented by i. +* +* PROGRAM SUBROUTINES +* +* qmdrch, qmdqt, qmdupd. +***********************************************************************/ + +void genqmd(int *_neqns, int xadj[], int adjncy[], int perm[], + int invp[], int deg[], int marker[], int rchset[], int nbrhd[], + int qsize[], int qlink[], int *_nofsub) +{ int inode, ip, irch, j, mindeg, ndeg, nhdsze, node, np, num, + nump1, nxnode, rchsze, search, thresh; +# define neqns (*_neqns) +# define nofsub (*_nofsub) + /* Initialize degree vector and other working variables. */ + mindeg = neqns; + nofsub = 0; + for (node = 1; node <= neqns; node++) + { perm[node] = node; + invp[node] = node; + marker[node] = 0; + qsize[node] = 1; + qlink[node] = 0; + ndeg = xadj[node+1] - xadj[node]; + deg[node] = ndeg; + if (ndeg < mindeg) mindeg = ndeg; + } + num = 0; + /* Perform threshold search to get a node of min degree. + * Variable search point to where search should start. */ +s200: search = 1; + thresh = mindeg; + mindeg = neqns; +s300: nump1 = num + 1; + if (nump1 > search) search = nump1; + for (j = search; j <= neqns; j++) + { node = perm[j]; + if (marker[node] >= 0) + { ndeg = deg[node]; + if (ndeg <= thresh) goto s500; + if (ndeg < mindeg) mindeg = ndeg; + } + } + goto s200; + /* Node has minimum degree. Find its reachable sets by calling + * qmdrch. */ +s500: search = j; + nofsub += deg[node]; + marker[node] = 1; + qmdrch(&node, xadj, adjncy, deg, marker, &rchsze, rchset, &nhdsze, + nbrhd); + /* Eliminate all nodes indistinguishable from node. They are given + * by node, qlink[node], ... . */ + nxnode = node; +s600: num++; + np = invp[nxnode]; + ip = perm[num]; + perm[np] = ip; + invp[ip] = np; + perm[num] = nxnode; + invp[nxnode] = num; + deg[nxnode] = -1; + nxnode = qlink[nxnode]; + if (nxnode > 0) goto s600; + if (rchsze > 0) + { /* Update the degrees of the nodes in the reachable set and + * identify indistinguishable nodes. */ + qmdupd(xadj, adjncy, &rchsze, rchset, deg, qsize, qlink, + marker, &rchset[rchsze+1], &nbrhd[nhdsze+1]); + /* Reset marker value of nodes in reach set. Update threshold + * value for cyclic search. Also call qmdqt to form new + * quotient graph. */ + marker[node] = 0; + for (irch = 1; irch <= rchsze; irch++) + { inode = rchset[irch]; + if (marker[inode] >= 0) + { marker[inode] = 0; + ndeg = deg[inode]; + if (ndeg < mindeg) mindeg = ndeg; + if (ndeg <= thresh) + { mindeg = thresh; + thresh = ndeg; + search = invp[inode]; + } + } + } + if (nhdsze > 0) + qmdqt(&node, xadj, adjncy, marker, &rchsze, rchset, nbrhd); + } + if (num < neqns) goto s300; + return; +# undef neqns +# undef nofsub +} + +/*********************************************************************** +* NAME +* +* qmdrch - Quotient MD ReaCHable set +* +* SYNOPSIS +* +* #include "qmd.h" +* void qmdrch(int *root, int xadj[], int adjncy[], int deg[], +* int marker[], int *rchsze, int rchset[], int *nhdsze, +* int nbrhd[]); +* +* PURPOSE +* +* This subroutine determines the reachable set of a node through a +* given subset. The adjancy structure is assumed to be stored in a +* quotient graph format. +* +* INPUT PARAMETERS +* +* root - the given node not in the subset; +* (xadj, adjncy) - +* the adjancy structure pair; +* deg - the degree vector. deg[i] < 0 means the node belongs to the +* given subset. +* +* OUTPUT PARAMETERS +* +* (rchsze, rchset) - +* the reachable set; +* (nhdsze, nbrhd) - +* the neighborhood set. +* +* UPDATED PARAMETERS +* +* marker - the marker vector for reach and nbrhd sets. > 0 means the +* node is in reach set. < 0 means the node has been merged +* with others in the quotient or it is in nbrhd set. +***********************************************************************/ + +void qmdrch(int *_root, int xadj[], int adjncy[], int deg[], + int marker[], int *_rchsze, int rchset[], int *_nhdsze, + int nbrhd[]) +{ int i, istop, istrt, j, jstop, jstrt, nabor, node; +# define root (*_root) +# define rchsze (*_rchsze) +# define nhdsze (*_nhdsze) + /* Loop through the neighbors of root in the quotient graph. */ + nhdsze = 0; + rchsze = 0; + istrt = xadj[root]; + istop = xadj[root+1] - 1; + if (istop < istrt) return; + for (i = istrt; i <= istop; i++) + { nabor = adjncy[i]; + if (nabor == 0) return; + if (marker[nabor] == 0) + { if (deg[nabor] >= 0) + { /* Include nabor into the reachable set. */ + rchsze++; + rchset[rchsze] = nabor; + marker[nabor] = 1; + goto s600; + } + /* nabor has been eliminated. Find nodes reachable from + * it. */ + marker[nabor] = -1; + nhdsze++; + nbrhd[nhdsze] = nabor; +s300: jstrt = xadj[nabor]; + jstop = xadj[nabor+1] - 1; + for (j = jstrt; j <= jstop; j++) + { node = adjncy[j]; + nabor = - node; + if (node < 0) goto s300; + if (node == 0) goto s600; + if (marker[node] == 0) + { rchsze++; + rchset[rchsze] = node; + marker[node] = 1; + } + } + } +s600: ; + } + return; +# undef root +# undef rchsze +# undef nhdsze +} + +/*********************************************************************** +* NAME +* +* qmdqt - Quotient MD Quotient graph Transformation +* +* SYNOPSIS +* +* #include "qmd.h" +* void qmdqt(int *root, int xadj[], int adjncy[], int marker[], +* int *rchsze, int rchset[], int nbrhd[]); +* +* PURPOSE +* +* This subroutine performs the quotient graph transformation after a +* node has been eliminated. +* +* INPUT PARAMETERS +* +* root - the node just eliminated. It becomes the representative of +* the new supernode; +* (xadj, adjncy) - +* the adjancy structure; +* (rchsze, rchset) - +* the reachable set of root in the old quotient graph; +* nbrhd - the neighborhood set which will be merged with root to form +* the new supernode; +* marker - the marker vector. +* +* UPDATED PARAMETERS +* +* adjncy - becomes the adjncy of the quotient graph. +***********************************************************************/ + +void qmdqt(int *_root, int xadj[], int adjncy[], int marker[], + int *_rchsze, int rchset[], int nbrhd[]) +{ int inhd, irch, j, jstop, jstrt, link, nabor, node; +# define root (*_root) +# define rchsze (*_rchsze) + irch = 0; + inhd = 0; + node = root; +s100: jstrt = xadj[node]; + jstop = xadj[node+1] - 2; + if (jstop >= jstrt) + { /* Place reach nodes into the adjacent list of node. */ + for (j = jstrt; j <= jstop; j++) + { irch++; + adjncy[j] = rchset[irch]; + if (irch >= rchsze) goto s400; + } + } + /* Link to other space provided by the nbrhd set. */ + link = adjncy[jstop+1]; + node = - link; + if (link >= 0) + { inhd++; + node = nbrhd[inhd]; + adjncy[jstop+1] = - node; + } + goto s100; + /* All reachable nodes have been saved. End the adjacent list. + * Add root to the neighborhood list of each node in the reach + * set. */ +s400: adjncy[j+1] = 0; + for (irch = 1; irch <= rchsze; irch++) + { node = rchset[irch]; + if (marker[node] >= 0) + { jstrt = xadj[node]; + jstop = xadj[node+1] - 1; + for (j = jstrt; j <= jstop; j++) + { nabor = adjncy[j]; + if (marker[nabor] < 0) + { adjncy[j] = root; + goto s600; + } + } + } +s600: ; + } + return; +# undef root +# undef rchsze +} + +/*********************************************************************** +* NAME +* +* qmdupd - Quotient MD UPDate +* +* SYNOPSIS +* +* #include "qmd.h" +* void qmdupd(int xadj[], int adjncy[], int *nlist, int list[], +* int deg[], int qsize[], int qlink[], int marker[], int rchset[], +* int nbrhd[]); +* +* PURPOSE +* +* This routine performs degree update for a set of nodes in the minimum +* degree algorithm. +* +* INPUT PARAMETERS +* +* (xadj, adjncy) - +* the adjancy structure; +* (nlist, list) - +* the list of nodes whose degree has to be updated. +* +* UPDATED PARAMETERS +* +* deg - the degree vector; +* qsize - size of indistinguishable supernodes; +* qlink - linked list for indistinguishable nodes; +* marker - used to mark those nodes in reach/nbrhd sets. +* +* WORKING PARAMETERS +* +* rchset - the reachable set; +* nbrhd - the neighborhood set. +* +* PROGRAM SUBROUTINES +* +* qmdmrg. +***********************************************************************/ + +void qmdupd(int xadj[], int adjncy[], int *_nlist, int list[], + int deg[], int qsize[], int qlink[], int marker[], int rchset[], + int nbrhd[]) +{ int deg0, deg1, il, inhd, inode, irch, j, jstop, jstrt, mark, + nabor, nhdsze, node, rchsze; +# define nlist (*_nlist) + /* Find all eliminated supernodes that are adjacent to some nodes + * in the given list. Put them into (nhdsze, nbrhd). deg0 contains + * the number of nodes in the list. */ + if (nlist <= 0) return; + deg0 = 0; + nhdsze = 0; + for (il = 1; il <= nlist; il++) + { node = list[il]; + deg0 += qsize[node]; + jstrt = xadj[node]; + jstop = xadj[node+1] - 1; + for (j = jstrt; j <= jstop; j++) + { nabor = adjncy[j]; + if (marker[nabor] == 0 && deg[nabor] < 0) + { marker[nabor] = -1; + nhdsze++; + nbrhd[nhdsze] = nabor; + } + } + } + /* Merge indistinguishable nodes in the list by calling the + * subroutine qmdmrg. */ + if (nhdsze > 0) + qmdmrg(xadj, adjncy, deg, qsize, qlink, marker, °0, &nhdsze, + nbrhd, rchset, &nbrhd[nhdsze+1]); + /* Find the new degrees of the nodes that have not been merged. */ + for (il = 1; il <= nlist; il++) + { node = list[il]; + mark = marker[node]; + if (mark == 0 || mark == 1) + { marker[node] = 2; + qmdrch(&node, xadj, adjncy, deg, marker, &rchsze, rchset, + &nhdsze, nbrhd); + deg1 = deg0; + if (rchsze > 0) + { for (irch = 1; irch <= rchsze; irch++) + { inode = rchset[irch]; + deg1 += qsize[inode]; + marker[inode] = 0; + } + } + deg[node] = deg1 - 1; + if (nhdsze > 0) + { for (inhd = 1; inhd <= nhdsze; inhd++) + { inode = nbrhd[inhd]; + marker[inode] = 0; + } + } + } + } + return; +# undef nlist +} + +/*********************************************************************** +* NAME +* +* qmdmrg - Quotient MD MeRGe +* +* SYNOPSIS +* +* #include "qmd.h" +* void qmdmrg(int xadj[], int adjncy[], int deg[], int qsize[], +* int qlink[], int marker[], int *deg0, int *nhdsze, int nbrhd[], +* int rchset[], int ovrlp[]); +* +* PURPOSE +* +* This routine merges indistinguishable nodes in the minimum degree +* ordering algorithm. It also computes the new degrees of these new +* supernodes. +* +* INPUT PARAMETERS +* +* (xadj, adjncy) - +* the adjancy structure; +* deg0 - the number of nodes in the given set; +* (nhdsze, nbrhd) - +* the set of eliminated supernodes adjacent to some nodes in +* the set. +* +* UPDATED PARAMETERS +* +* deg - the degree vector; +* qsize - size of indistinguishable nodes; +* qlink - linked list for indistinguishable nodes; +* marker - the given set is given by those nodes with marker value set +* to 1. Those nodes with degree updated will have marker value +* set to 2. +* +* WORKING PARAMETERS +* +* rchset - the reachable set; +* ovrlp - temp vector to store the intersection of two reachable sets. +***********************************************************************/ + +void qmdmrg(int xadj[], int adjncy[], int deg[], int qsize[], + int qlink[], int marker[], int *_deg0, int *_nhdsze, int nbrhd[], + int rchset[], int ovrlp[]) +{ int deg1, head, inhd, iov, irch, j, jstop, jstrt, link, lnode, + mark, mrgsze, nabor, node, novrlp, rchsze, root; +# define deg0 (*_deg0) +# define nhdsze (*_nhdsze) + /* Initialization. */ + if (nhdsze <= 0) return; + for (inhd = 1; inhd <= nhdsze; inhd++) + { root = nbrhd[inhd]; + marker[root] = 0; + } + /* Loop through each eliminated supernode in the set + * (nhdsze, nbrhd). */ + for (inhd = 1; inhd <= nhdsze; inhd++) + { root = nbrhd[inhd]; + marker[root] = -1; + rchsze = 0; + novrlp = 0; + deg1 = 0; +s200: jstrt = xadj[root]; + jstop = xadj[root+1] - 1; + /* Determine the reachable set and its intersection with the + * input reachable set. */ + for (j = jstrt; j <= jstop; j++) + { nabor = adjncy[j]; + root = - nabor; + if (nabor < 0) goto s200; + if (nabor == 0) break; + mark = marker[nabor]; + if (mark == 0) + { rchsze++; + rchset[rchsze] = nabor; + deg1 += qsize[nabor]; + marker[nabor] = 1; + } + else if (mark == 1) + { novrlp++; + ovrlp[novrlp] = nabor; + marker[nabor] = 2; + } + } + /* From the overlapped set, determine the nodes that can be + * merged together. */ + head = 0; + mrgsze = 0; + for (iov = 1; iov <= novrlp; iov++) + { node = ovrlp[iov]; + jstrt = xadj[node]; + jstop = xadj[node+1] - 1; + for (j = jstrt; j <= jstop; j++) + { nabor = adjncy[j]; + if (marker[nabor] == 0) + { marker[node] = 1; + goto s1100; + } + } + /* Node belongs to the new merged supernode. Update the + * vectors qlink and qsize. */ + mrgsze += qsize[node]; + marker[node] = -1; + lnode = node; +s900: link = qlink[lnode]; + if (link > 0) + { lnode = link; + goto s900; + } + qlink[lnode] = head; + head = node; +s1100: ; + } + if (head > 0) + { qsize[head] = mrgsze; + deg[head] = deg0 + deg1 - 1; + marker[head] = 2; + } + /* Reset marker values. */ + root = nbrhd[inhd]; + marker[root] = 0; + if (rchsze > 0) + { for (irch = 1; irch <= rchsze; irch++) + { node = rchset[irch]; + marker[node] = 0; + } + } + } + return; +# undef deg0 +# undef nhdsze +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/qmd.h b/resources/3rdparty/glpk-4.57/src/misc/qmd.h new file mode 100644 index 000000000..e55d50f52 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/qmd.h @@ -0,0 +1,58 @@ +/* qmd.h (quotient minimum degree algorithm) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2001-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef QMD_H +#define QMD_H + +#define genqmd _glp_genqmd +void genqmd(int *neqns, int xadj[], int adjncy[], int perm[], + int invp[], int deg[], int marker[], int rchset[], int nbrhd[], + int qsize[], int qlink[], int *nofsub); +/* GENeral Quotient Minimum Degree algorithm */ + +#define qmdrch _glp_qmdrch +void qmdrch(int *root, int xadj[], int adjncy[], int deg[], + int marker[], int *rchsze, int rchset[], int *nhdsze, + int nbrhd[]); +/* Quotient MD ReaCHable set */ + +#define qmdqt _glp_qmdqt +void qmdqt(int *root, int xadj[], int adjncy[], int marker[], + int *rchsze, int rchset[], int nbrhd[]); +/* Quotient MD Quotient graph Transformation */ + +#define qmdupd _glp_qmdupd +void qmdupd(int xadj[], int adjncy[], int *nlist, int list[], + int deg[], int qsize[], int qlink[], int marker[], int rchset[], + int nbrhd[]); +/* Quotient MD UPDate */ + +#define qmdmrg _glp_qmdmrg +void qmdmrg(int xadj[], int adjncy[], int deg[], int qsize[], + int qlink[], int marker[], int *deg0, int *nhdsze, int nbrhd[], + int rchset[], int ovrlp[]); +/* Quotient MD MeRGe */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/relax4.c b/resources/3rdparty/glpk-4.57/src/misc/relax4.c new file mode 100644 index 000000000..f0a47d6d5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/relax4.c @@ -0,0 +1,2850 @@ +/* relax4.c (relaxation method of Bertsekas and Tseng) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* THIS CODE IS THE RESULT OF TRANSLATION OF THE FORTRAN CODE RELAX4. +* +* THE TRANSLATION HAS BEEN DONE WITH THE PERMISSION OF THE AUTHOR OF +* THE ORIGINAL FORTRAN CODE PROF. DIMITRI P. BERTSEKAS, MASSACHUSETTS +* INSTITUTE OF TECHNOLOGY, CAMBRIDGE, MASSACHUSETTS, USA. +* +* The translation was made by Andrew Makhorin . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "relax4.h" + +/*********************************************************************** +* WARNING +* +* A serious bug was *tentatively* fixed in this code (see #if/#endif +* marked by 'mao'). +* +* This bug is inherited from the original Fortran version of the +* RELAX-IV code. Unfortunately, the code is very intricate, so this +* bug is still under investigation. Thanks to Sylvain Fournier for bug +* report. +* +* RELAX-IV bug details +* -------------------- +* In the original RELAX-IV code there are four similar fragments in +* subroutines ascnt1 and ascnt2 like this: +* +* C +* C DECREASE THE PRICES OF THE SCANNED NODES BY DELPRC. +* C ADJUST FLOW TO MAINTAIN COMPLEMENTARY SLACKNESS WITH +* C THE PRICES. +* C +* NB = 0 +* DO 6 I=1,NSAVE +* . . . +* IF (RC(ARC).EQ.0) THEN +* DELX=DELX+U(ARC) +* NB = NB + 1 +* PRDCSR(NB) = ARC +* END IF +* . . . +* +* On some instances the variable NB becomes greater than N (the number +* of nodes) that leads to indexing error, because the array PRDCSR is +* declared as array of N elements (more precisely, as array of MAXNN +* elements, however, NB becomes even much greater than MAXNN). +***********************************************************************/ + +#define false 0 +#define true 1 + +/*********************************************************************** +* NAME +* +* RELAX-IV (version of October 1994) +* +* PURPOSE +* +* This routine implements the relaxation method of Bertsekas and Tseng +* (see [1], [2]) for linear cost ordinary network flow problems. +* +* [1] Bertsekas, D. P., "A Unified Framework for Primal-Dual Methods" +* Mathematical Programming, Vol. 32, 1985, pp. 125-145. +* [2] Bertsekas, D. P., and Tseng, P., "Relaxation Methods for +* Minimum Cost" Operations Research, Vol. 26, 1988, pp. 93-114. +* +* The relaxation method is also described in the books: +* +* [3] Bertsekas, D. P., "Linear Network Optimization: Algorithms and +* Codes" MIT Press, 1991. +* [4] Bertsekas, D. P. and Tsitsiklis, J. N., "Parallel and Distributed +* Computation: Numerical Methods", Prentice-Hall, 1989. +* [5] Bertsekas, D. P., "Network Optimization: Continuous and Discrete +* Models", Athena Scientific, 1998. +* +* RELEASE NOTE +* +* This version of relaxation code has option for a special crash +* procedure for the initial price-flow pair. This is recommended for +* difficult problems where the default initialization results in long +* running times. crash = 1 corresponds to an auction/shortest path +* method +* +* These initializations are recommended in the absence of any prior +* information on a favorable initial flow-price vector pair that +* satisfies complementary slackness. +* +* The relaxation portion of the code differs from the code RELAXT-III +* and other earlier relaxation codes in that it maintains the set of +* nodes with nonzero deficit in a fifo queue. Like its predecessor +* RELAXT-III, this code maintains a linked list of balanced (i.e., of +* zero reduced cost) arcs so to reduce the work in labeling and +* scanning. Unlike RELAXT-III, it does not use selectively shortest +* path iterations for initialization. +* +* SOURCE +* +* The original Fortran code was written by Dimitri P. Bertsekas and +* Paul Tseng, with a contribution by Jonathan Eckstein in the phase II +* initialization. The original Fortran routine AUCTION was written by +* Dimitri P. Bertsekas and is based on the method described in the +* paper: +* +* [6] Bertsekas, D. P., "An Auction/Sequential Shortest Path Algorithm +* for the Minimum Cost Flow Problem", LIDS Report P-2146, MIT, +* Nov. 1992. +* +* For inquiries about the original Fortran code, please contact: +* +* Dimitri P. Bertsekas +* Laboratory for information and decision systems +* Massachusetts Institute of Technology +* Cambridge, MA 02139 +* (617) 253-7267, dimitrib@mit.edu +* +* This code is the result of translation of the original Fortran code. +* The translation was made by Andrew Makhorin . +* +* USER GUIDELINES +* +* This routine is in the public domain to be used only for research +* purposes. It cannot be used as part of a commercial product, or to +* satisfy in any part commercial delivery requirements to government +* or industry, without prior agreement with the authors. Users are +* requested to acknowledge the authorship of the code, and the +* relaxation method. +* +* No modification should be made to this code other than the minimal +* necessary to make it compatible with specific platforms. +* +* INPUT PARAMETERS (see notes 1, 2, 4) +* +* n = number of nodes +* na = number of arcs +* large = a very large integer to represent infinity +* (see note 3) +* repeat = true if initialization is to be skipped +* (false otherwise) +* crash = 0 if default initialization is used +* 1 if auction initialization is used +* startn[j] = starting node for arc j, j = 1,...,na +* endn[j] = ending node for arc j, j = 1,...,na +* fou[i] = first arc out of node i, i = 1,...,n +* nxtou[j] = next arc out of the starting node of arc j, j = 1,...,na +* fin[i] = first arc into node i, i = 1,...,n +* nxtin[j] = next arc into the ending node of arc j, j = 1,...,na +* +* UPDATED PARAMETERS (see notes 1, 3, 4) +* +* rc[j] = reduced cost of arc j, j = 1,...,na +* u[j] = capacity of arc j on input +* and (capacity of arc j) - x[j] on output, j = 1,...,na +* dfct[i] = demand at node i on input +* and zero on output, i = 1,...,n +* +* OUTPUT PARAMETERS (see notes 1, 3, 4) +* +* x[j] = flow on arc j, j = 1,...,na +* nmultinode = number of multinode relaxation iterations in RELAX4 +* iter = number of relaxation iterations in RELAX4 +* num_augm = number of flow augmentation steps in RELAX4 +* num_ascnt = number of multinode ascent steps in RELAX4 +* nsp = number of auction/shortest path iterations +* +* WORKING PARAMETERS (see notes 1, 4, 5) +* +* label[1+n], prdcsr[1+n], save[1+na], tfstou[1+n], tnxtou[1+na], +* tfstin[1+n], tnxtin[1+na], nxtqueue[1+n], scan[1+n], mark[1+n], +* extend_arc[1+n], sb_level[1+n], sb_arc[1+n] +* +* RETURNS +* +* 0 = normal return +* 1,...,8 = problem is found to be infeasible +* +* NOTE 1 +* +* To run in limited memory systems, declare the arrays startn, endn, +* nxtin, nxtou, fin, fou, label, prdcsr, save, tfstou, tnxtou, tfstin, +* tnxtin, ddpos, ddneg, nxtqueue as short instead. +* +* NOTE 2 +* +* This routine makes no effort to initialize with a favorable x from +* amongst those flow vectors that satisfy complementary slackness with +* the initial reduced cost vector rc. If a favorable x is known, then +* it can be passed, together with the corresponding arrays u and dfct, +* to this routine directly. This, however, requires that the capacity +* tightening portion and the flow initialization portion of this +* routine (up to line labeled 90) be skipped. +* +* NOTE 3 +* +* All problem data should be less than large in magnitude, and large +* should be less than, say, 1/4 the largest int of the machine used. +* This will guard primarily against overflow in uncapacitated problems +* where the arc capacities are taken finite but very large. Note, +* however, that as in all codes operating with integers, overflow may +* occur if some of the problem data takes very large values. +* +* NOTE 4 +* +* [This note being specific to Fortran was removed.-A.M.] +* +* NOTE 5 +* +* ddpos and ddneg are arrays that give the directional derivatives for +* all positive and negative single-node price changes. These are used +* only in phase II of the initialization procedure, before the linked +* list of balanced arcs comes to play. Therefore, to reduce storage, +* they are equivalence to tfstou and tfstin, which are of the same size +* (number of nodes) and are used only after the tree comes into use. */ + +static void ascnt1(struct relax4_csa *csa, int dm, int *delx, + int *nlabel, int *feasbl, int *svitch, int nscan, int curnode, + int *prevnode); + +static void ascnt2(struct relax4_csa *csa, int dm, int *delx, + int *nlabel, int *feasbl, int *svitch, int nscan, int curnode, + int *prevnode); + +static int auction(struct relax4_csa *csa); + +int relax4(struct relax4_csa *csa) +{ /* input parameters */ + int n = csa->n; + int na = csa->na; + int large = csa->large; + int repeat = csa->repeat; + int crash = csa->crash; + int *startn = csa->startn; + int *endn = csa->endn; + int *fou = csa->fou; + int *nxtou = csa->nxtou; + int *fin = csa->fin; + int *nxtin = csa->nxtin; + /* updated parameters */ + int *rc = csa->rc; + int *u = csa->u; + int *dfct = csa->dfct; + /* output parameters */ + int *x = csa->x; +# define nmultinode (csa->nmultinode) +# define iter (csa->iter) +# define num_augm (csa->num_augm) +# define num_ascnt (csa->num_ascnt) +# define nsp (csa->nsp) + /* working parameters */ + int *label = csa->label; + int *prdcsr = csa->prdcsr; + int *save = csa->save; + int *tfstou = csa->tfstou; + int *tnxtou = csa->tnxtou; + int *tfstin = csa->tfstin; + int *tnxtin = csa->tnxtin; + int *nxtqueue = csa->nxtqueue; + char *scan = csa->scan; + char *mark = csa->mark; + int *ddpos = tfstou; + int *ddneg = tfstin; + /* local variables */ + int arc, augnod, capin, capout, defcit, delprc, delx, dm, dp, + dx, feasbl, i, ib, indef, j, lastqueue, maxcap, narc, nb, + nlabel, node, node2, node_def, naugnod, nscan, num_passes, + numnz, numnz_new, numpasses, nxtarc, nxtbrk, nxtnode, passes, + pchange, posit, prevnode, prvarc, quit, rdcost, scapin, + scapou, svitch, t, t1, t2, tmparc, tp, trc, ts; + /*--------------------------------------------------------------*/ + /* Initialization phase I */ + /* In this phase, we reduce the arc capacities by as much as + * possible without changing the problem; then we set the initial + * flow array x, together with the corresponding arrays u and + * dfct. */ + /* This phase and phase II (from here up to line labeled 90) can + * be skipped (by setting repeat to true) if the calling program + * places in common user-chosen values for the arc flows, the + * residual arc capacities, and the nodal deficits. When this is + * done, it is critical that the flow and the reduced cost for + * each arc satisfy complementary slackness and the dfct array + * properly correspond to the initial arc/flows. */ + if (repeat) + goto L90; + for (node = 1; node <= n; node++) + { node_def = dfct[node]; + ddpos[node] = node_def; + ddneg[node] = -node_def; + maxcap = 0; + scapou = 0; + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { if (scapou <= large - u[arc]) + scapou += u[arc]; + else + goto L10; + } + if (scapou <= large - node_def) + capout = scapou + node_def; + else + goto L10; + if (capout < 0) + { /* problem is infeasible */ + /* exogenous flow into node exceeds out capacity */ + return 1; + } + scapin = 0; + for (arc = fin[node]; arc > 0; arc = nxtin[arc]) + { if (u[arc] > capout) + u[arc] = capout; + if (maxcap < u[arc]) + maxcap = u[arc]; + if (scapin <= large - u[arc]) + scapin += u[arc]; + else + goto L10; + } + if (scapin <= large + node_def) + capin = scapin - node_def; + else + goto L10; + if (capin < 0) + { /* problem is infeasible */ + /* exogenous flow out of node exceeds in capacity */ + return 2; + } + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { if (u[arc] > capin) + u[arc] = capin; + } +L10: ; + } + /*--------------------------------------------------------------*/ + /* Initialization phase II */ + /* In this phase, we initialize the prices and flows by either + * calling the routine auction or by performing only single node + * (coordinate) relaxation iterations. */ + if (crash == 1) + { nsp = 0; + if (auction(csa) != 0) + { /* problem is found to be infeasible */ + return 3; + } + goto L70; + } + /* Initialize the arc flows to satisfy complementary slackness + * with the prices. u[arc] is the residual capacity of arc, and + * x[arc] is the flow. These two always add up to the total + * capacity for arc. Also compute the directional derivatives for + * each coordinate and compute the actual deficits. */ + for (arc = 1; arc <= na; arc++) + { x[arc] = 0; + if (rc[arc] <= 0) + { t = u[arc]; + t1 = startn[arc]; + t2 = endn[arc]; + ddpos[t1] += t; + ddneg[t2] += t; + if (rc[arc] < 0) + { x[arc] = t; + u[arc] = 0; + dfct[t1] += t; + dfct[t2] -= t; + ddneg[t1] -= t; + ddpos[t2] -= t; + } + } + } + /* Make 2 or 3 passes through all nodes, performing only single + * node relaxation iterations. The number of passes depends on the + * density of the network. */ + if (na > n * 10) + numpasses = 2; + else + numpasses = 3; + for (passes = 1; passes <= numpasses; passes++) + for (node = 1; node <= n; node++) + { if (dfct[node] == 0) + continue; + if (ddpos[node] <= 0) + { /* Compute delprc, the stepsize to the next breakpoint in + * the dual cost as the price of node is increased. + * [Since the reduced cost of all outgoing (resp., incoming) + * arcs will decrease (resp., increase) as the price of node + * is increased, the next breakpoint is the minimum of the + * positive reduced cost on outgoing arcs and of the + * negative reduced cost on incoming arcs.] */ + delprc = large; + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { trc = rc[arc]; + if ((trc > 0) && (trc < delprc)) + delprc = trc; + } + for (arc = fin[node]; arc > 0; arc = nxtin[arc]) + { trc = rc[arc]; + if ((trc < 0) && (trc > -delprc)) + delprc = -trc; + } + /* If no breakpoint is left and dual ascent is still + * possible, the problem is infeasible. */ + if (delprc >= large) + { if (ddpos[node] == 0) + continue; + return 4; + } + /* delprc is the stepsize to next breakpoint. Increase + * price of node by delprc and compute the stepsize to the + * next breakpoint in the dual cost. */ +L53: nxtbrk = large; + /* Look at all arcs out of node. */ + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { trc = rc[arc]; + if (trc == 0) + { t1 = endn[arc]; + t = u[arc]; + if (t > 0) + { dfct[node] += t; + dfct[t1] -= t; + x[arc] = t; + u[arc] = 0; + } + else + t = x[arc]; + ddneg[node] -= t; + ddpos[t1] -= t; + } + /* Decrease the reduced costs on all outgoing arcs. */ + trc -= delprc; + if ((trc > 0) && (trc < nxtbrk)) + nxtbrk = trc; + else if (trc == 0) + { /* Arc goes from inactive to balanced. Update the rate + * of dual ascent at node and at its neighbor. */ + ddpos[node] += u[arc]; + ddneg[endn[arc]] += u[arc]; + } + rc[arc] = trc; + } + /* Look at all arcs into node. */ + for (arc = fin[node]; arc > 0; arc = nxtin[arc]) + { trc = rc[arc]; + if (trc == 0) + { t1 = startn[arc]; + t = x[arc]; + if (t > 0) + { dfct[node] += t; + dfct[t1] -= t; + u[arc] = t; + x[arc] = 0; + } + else + t = u[arc]; + ddpos[t1] -= t; + ddneg[node] -= t; + } + /* Increase the reduced cost on all incoming arcs. */ + trc += delprc; + if ((trc < 0) && (trc > -nxtbrk)) + nxtbrk = -trc; + else if (trc == 0) + { /* Arc goes from active to balanced. Update the rate + * of dual ascent at node and at its neighbor. */ + ddneg[startn[arc]] += x[arc]; + ddpos[node] += x[arc]; + } + rc[arc] = trc; + } + /* If price of node can be increased further without + * decreasing the dual cost (even the dual cost doesn't + * increase), return to increase the price further. */ + if ((ddpos[node] <= 0) && (nxtbrk < large)) + { delprc = nxtbrk; + goto L53; + } + } + else if (ddneg[node] <= 0) + { /* Compute delprc, the stepsize to the next breakpoint in + * the dual cost as the price of node is decreased. + * [Since the reduced cost of all outgoing (resp., incoming) + * arcs will increase (resp., decrease) as the price of node + * is decreased, the next breakpoint is the minimum of the + * negative reduced cost on outgoing arcs and of the + * positive reduced cost on incoming arcs.] */ + delprc = large; + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { trc = rc[arc]; + if ((trc < 0) && (trc > -delprc)) + delprc = -trc; + } + for (arc = fin[node]; arc > 0; arc = nxtin[arc]) + { trc = rc[arc]; + if ((trc > 0) && (trc < delprc)) + delprc = trc; + } + /* If no breakpoint is left and dual ascent is still + * possible, the problem is infeasible. */ + if (delprc == large) + { if (ddneg[node] == 0) + continue; + return 5; + } + /* delprc is the stepsize to next breakpoint. Decrease + * price of node by delprc and compute the stepsize to the + * next breakpoint in the dual cost. */ +L63: nxtbrk = large; + /* Look at all arcs out of node. */ + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { trc = rc[arc]; + if (trc == 0) + { t1 = endn[arc]; + t = x[arc]; + if (t > 0) + { dfct[node] -= t; + dfct[t1] += t; + u[arc] = t; + x[arc] = 0; + } + else + t = u[arc]; + ddpos[node] -= t; + ddneg[t1] -= t; + } + /* Increase the reduced cost on all outgoing arcs. */ + trc += delprc; + if ((trc < 0) && (trc > -nxtbrk)) + nxtbrk = -trc; + else if (trc == 0) + { /* Arc goes from active to balanced. Update the rate + * of dual ascent at node and at its neighbor. */ + ddneg[node] += x[arc]; + ddpos[endn[arc]] += x[arc]; + } + rc[arc] = trc; + } + /* Look at all arcs into node. */ + for (arc = fin[node]; arc > 0; arc = nxtin[arc]) + { trc = rc[arc]; + if (trc == 0) + { t1 = startn[arc]; + t = u[arc]; + if (t > 0) + { dfct[node] -= t; + dfct[t1] += t; + x[arc] = t; + u[arc] = 0; + } + else + t = x[arc]; + ddneg[t1] -= t; + ddpos[node] -= t; + } + /* Decrease the reduced cost on all incoming arcs. */ + trc -= delprc; + if ((trc > 0) && (trc < nxtbrk)) + nxtbrk = trc; + else if (trc == 0) + { /* Arc goes from inactive to balanced. Update the rate + * of dual ascent at node and at its neighbor. */ + ddpos[startn[arc]] += u[arc]; + ddneg[node] += u[arc]; + } + rc[arc] = trc; + } + /* If price of node can be decreased further without + * decreasing the dual cost (even the dual cost doesn't + * increase), return to decrease the price further. */ + if ((ddneg[node] <= 0) && (nxtbrk < large)) + { delprc = nxtbrk; + goto L63; + } + } + } + /*--------------------------------------------------------------*/ +L70: /* Initialize tree data structure. */ + for (i = 1; i <= n; i++) + tfstou[i] = tfstin[i] = 0; + for (i = 1; i <= na; i++) + { tnxtin[i] = tnxtou[i] = -1; + if (rc[i] == 0) + { tnxtou[i] = tfstou[startn[i]]; + tfstou[startn[i]] = i; + tnxtin[i] = tfstin[endn[i]]; + tfstin[endn[i]] = i; + } + } +L90: /* Initialize other variables. */ + feasbl = true; + iter = 0; + nmultinode = 0; + num_augm = 0; + num_ascnt = 0; + num_passes = 0; + numnz = n; + numnz_new = 0; + svitch = false; + for (i = 1; i <= n; i++) + mark[i] = scan[i] = false; + nlabel = 0; + /* RELAX4 uses an adaptive strategy to decide whether to continue + * the scanning process after a multinode price change. + * The threshold parameter tp and ts that control this strategy + * are set in the next two lines. */ + tp = 10; + ts = n / 15; + /* Initialize the queue of nodes with nonzero deficit. */ + for (node = 1; node <= n - 1; node++) + nxtqueue[node] = node + 1; + nxtqueue[n] = 1; + node = lastqueue = n; + /*--------------------------------------------------------------*/ + /* Start the relaxation algorithm. */ +L100: /* Code for advancing the queue of nonzero deficit nodes. */ + prevnode = node; + node = nxtqueue[node]; + defcit = dfct[node]; + if (node == lastqueue) + { numnz = numnz_new; + numnz_new = 0; + lastqueue = prevnode; + num_passes++; + } + /* Code for deleting a node from the queue. */ + if (defcit == 0) + { nxtnode = nxtqueue[node]; + if (node == nxtnode) + return 0; + else + { nxtqueue[prevnode] = nxtnode; + nxtqueue[node] = 0; + node = nxtnode; + goto L100; + } + } + else + posit = (defcit > 0); + iter++; + numnz_new++; + if (posit) + { /* Attempt a single node iteration from node with positive + * deficit. */ + pchange = false; + indef = defcit; + delx = 0; + nb = 0; + /* Check outgoing (probably) balanced arcs from node. */ + for (arc = tfstou[node]; arc > 0; arc = tnxtou[arc]) + { if ((rc[arc] == 0) && (x[arc] > 0)) + { delx += x[arc]; + nb++; + save[nb] = arc; + } + } + /* Check incoming arcs. */ + for (arc = tfstin[node]; arc > 0; arc = tnxtin[arc]) + { if ((rc[arc] == 0) && (u[arc] > 0)) + { delx += u[arc]; + nb++; + save[nb] = -arc; + } + } + /* End of initial node scan. */ +L4018: /* If no price change is possible, exit. */ + if (delx > defcit) + { quit = (defcit < indef); + goto L4016; + } + /* RELAX4 searches along the ascent direction for the best + * price by checking the slope of the dual cost at successive + * break points. First, we compute the distance to the next + * break point. */ + delprc = large; + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { rdcost = rc[arc]; + if ((rdcost < 0) && (rdcost > -delprc)) + delprc = -rdcost; + } + for (arc = fin[node]; arc > 0; arc = nxtin[arc]) + { rdcost = rc[arc]; + if ((rdcost > 0) && (rdcost < delprc)) + delprc = rdcost; + } + /* Check if problem is infeasible. */ + if ((delx < defcit) && (delprc == large)) + { /* The dual cost can be decreased without bound. */ + return 6; + } + /* Skip flow adjustment if there is no flow to modify. */ + if (delx == 0) + goto L4014; + /* Adjust the flow on the balanced arcs incident to node to + * maintain complementary slackness after the price change. */ + for (j = 1; j <= nb; j++) + { arc = save[j]; + if (arc > 0) + { node2 = endn[arc]; + t1 = x[arc]; + dfct[node2] += t1; + if (nxtqueue[node2] == 0) + { nxtqueue[prevnode] = node2; + nxtqueue[node2] = node; + prevnode = node2; + } + u[arc] += t1; + x[arc] = 0; + } + else + { narc = -arc; + node2 = startn[narc]; + t1 = u[narc]; + dfct[node2] += t1; + if (nxtqueue[node2] == 0) + { nxtqueue[prevnode] = node2; + nxtqueue[node2] = node; + prevnode = node2; + } + x[narc] += t1; + u[narc] = 0; + } + } + defcit -= delx; +L4014: if (delprc == large) + { quit = true; + goto L4019; + } + /* Node corresponds to a dual ascent direction. Decrease the + * price of node by delprc and compute the stepsize to the next + * breakpoint in the dual cost. */ + nb = 0; + pchange = true; + dp = delprc; + delprc = large; + delx = 0; + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { rdcost = rc[arc] + dp; + rc[arc] = rdcost; + if (rdcost == 0) + { nb++; + save[nb] = arc; + delx += x[arc]; + } + if ((rdcost < 0) && (rdcost > -delprc)) + delprc = -rdcost; + } + for (arc = fin[node]; arc > 0; arc = nxtin[arc]) + { rdcost = rc[arc] - dp; + rc[arc] = rdcost; + if (rdcost == 0) + { nb++; + save[nb] = -arc; + delx += u[arc]; + } + if ((rdcost > 0) && (rdcost < delprc)) + delprc = rdcost; + } + /* Return to check if another price change is possible. */ + goto L4018; +L4016: /* Perform flow augmentation at node. */ + for (j = 1; j <= nb; j++) + { arc = save[j]; + if (arc > 0) + { /* arc is an outgoing arc from node. */ + node2 = endn[arc]; + t1 = dfct[node2]; + if (t1 < 0) + { /* Decrease the total deficit by decreasing flow of + * arc. */ + quit = true; + t2 = x[arc]; + dx = defcit; + if (dx > -t1) dx = -t1; + if (dx > t2) dx = t2; + defcit -= dx; + dfct[node2] = t1 + dx; + if (nxtqueue[node2] == 0) + { nxtqueue[prevnode] = node2; + nxtqueue[node2] = node; + prevnode = node2; + } + x[arc] = t2 - dx; + u[arc] += dx; + if (defcit == 0) + break; + } + } + else + { /* -arc is an incoming arc to node. */ + narc = -arc; + node2 = startn[narc]; + t1 = dfct[node2]; + if (t1 < 0) + { /* Decrease the total deficit by increasing flow of + * -arc. */ + quit = true; + t2 = u[narc]; + dx = defcit; + if (dx > -t1) dx = -t1; + if (dx > t2) dx = t2; + defcit -= dx; + dfct[node2] = t1 + dx; + if (nxtqueue[node2] == 0) + { nxtqueue[prevnode] = node2; + nxtqueue[node2] = node; + prevnode = node2; + } + x[narc] += dx; + u[narc] = t2 - dx; + if (defcit == 0) + break; + } + } + } +L4019: dfct[node] = defcit; + /* Reconstruct the linked list of balance arcs incident to this + * node. For each adjacent node, we add any newly balanced arcs + * to the list, but do not bother removing formerly balanced + * ones (they will be removed the next time each adjacent node + * is scanned). */ + if (pchange) + { arc = tfstou[node]; + tfstou[node] = 0; + while (arc > 0) + { nxtarc = tnxtou[arc]; + tnxtou[arc] = -1; + arc = nxtarc; + } + arc = tfstin[node]; + tfstin[node] = 0; + while (arc > 0) + { nxtarc = tnxtin[arc]; + tnxtin[arc] = -1; + arc = nxtarc; + } + /* Now add the currently balanced arcs to the list for this + * node (which is now empty), and the appropriate adjacent + * ones. */ + for (j = 1; j <= nb; j++) + { arc = save[j]; + if (arc < 0) + arc = -arc; + if (tnxtou[arc] < 0) + { tnxtou[arc] = tfstou[startn[arc]]; + tfstou[startn[arc]] = arc; + } + if (tnxtin[arc] < 0) + { tnxtin[arc] = tfstin[endn[arc]]; + tfstin[endn[arc]] = arc; + } + } + } + /* End of single node iteration for positive deficit node. */ + } + else + { /* Attempt a single node iteration from node with negative + * deficit. */ + pchange = false; + defcit = -defcit; + indef = defcit; + delx = 0; + nb = 0; + for (arc = tfstin[node]; arc > 0; arc = tnxtin[arc]) + { if ((rc[arc] == 0) && (x[arc] > 0)) + { delx += x[arc]; + nb++; + save[nb] = arc; + } + } + for (arc = tfstou[node]; arc > 0; arc = tnxtou[arc]) + { if ((rc[arc] == 0) && (u[arc] > 0)) + { delx += u[arc]; + nb++; + save[nb] = -arc; + } + } +L4028: if (delx >= defcit) + { quit = (defcit < indef); + goto L4026; + } + /* Compute distance to next breakpoint. */ + delprc = large; + for (arc = fin[node]; arc > 0; arc = nxtin[arc]) + { rdcost = rc[arc]; + if ((rdcost < 0) && (rdcost > -delprc)) + delprc = -rdcost; + } + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { rdcost = rc[arc]; + if ((rdcost > 0) && (rdcost < delprc)) + delprc = rdcost; + } + /* Check if problem is infeasible. */ + if ((delx < defcit) && (delprc == large)) + return 7; + if (delx == 0) + goto L4024; + /* Flow augmentation is possible. */ + for (j = 1; j <= nb; j++) + { arc = save[j]; + if (arc > 0) + { node2 = startn[arc]; + t1 = x[arc]; + dfct[node2] -= t1; + if (nxtqueue[node2] == 0) + { nxtqueue[prevnode] = node2; + nxtqueue[node2] = node; + prevnode = node2; + } + u[arc] += t1; + x[arc] = 0; + } + else + { narc = -arc; + node2 = endn[narc]; + t1 = u[narc]; + dfct[node2] -= t1; + if (nxtqueue[node2] == 0) + { nxtqueue[prevnode] = node2; + nxtqueue[node2] = node; + prevnode = node2; + } + x[narc] += t1; + u[narc] = 0; + } + } + defcit -= delx; +L4024: if (delprc == large) + { quit = true; + goto L4029; + } + /* Price increase at node is possible. */ + nb = 0; + pchange = true; + dp = delprc; + delprc = large; + delx = 0; + for (arc = fin[node]; arc > 0; arc = nxtin[arc]) + { rdcost = rc[arc] + dp; + rc[arc] = rdcost; + if (rdcost == 0) + { nb++; + save[nb] = arc; + delx += x[arc]; + } + if ((rdcost < 0) && (rdcost > -delprc)) + delprc = -rdcost; + } + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { rdcost = rc[arc] - dp; + rc[arc] = rdcost; + if (rdcost == 0) + { nb++; + save[nb] = -arc; + delx += u[arc]; + } + if ((rdcost > 0) && (rdcost < delprc)) + delprc = rdcost; + } + goto L4028; +L4026: /* Perform flow augmentation at node. */ + for (j = 1; j <= nb; j++) + { arc = save[j]; + if (arc > 0) + { /* arc is an incoming arc to node. */ + node2 = startn[arc]; + t1 = dfct[node2]; + if (t1 > 0) + { quit = true; + t2 = x[arc]; + dx = defcit; + if (dx > t1) dx = t1; + if (dx > t2) dx = t2; + defcit -= dx; + dfct[node2] = t1 - dx; + if (nxtqueue[node2] == 0) + { nxtqueue[prevnode] = node2; + nxtqueue[node2] = node; + prevnode = node2; + } + x[arc] = t2 - dx; + u[arc] += dx; + if (defcit == 0) + break; + } + } + else + { /* -arc is an outgoing arc from node. */ + narc = -arc; + node2 = endn[narc]; + t1 = dfct[node2]; + if (t1 > 0) + { quit = true; + t2 = u[narc]; + dx = defcit; + if (dx > t1) dx = t1; + if (dx > t2) dx = t2; + defcit -= dx; + dfct[node2] = t1 - dx; + if (nxtqueue[node2] == 0) + { nxtqueue[prevnode] = node2; + nxtqueue[node2] = node; + prevnode = node2; + } + x[narc] += dx; + u[narc] = t2 - dx; + if (defcit == 0) + break; + } + } + } +L4029: dfct[node] = -defcit; + /* Reconstruct the list of balanced arcs incident to node. */ + if (pchange) + { arc = tfstou[node]; + tfstou[node] = 0; + while (arc > 0) + { nxtarc = tnxtou[arc]; + tnxtou[arc] = -1; + arc = nxtarc; + } + arc = tfstin[node]; + tfstin[node] = 0; + while (arc > 0) + { nxtarc = tnxtin[arc]; + tnxtin[arc] = -1; + arc = nxtarc; + } + /* Now add the currently balanced arcs to the list for this + * node (which is now empty), and the appropriate adjacent + * ones. */ + for (j = 1; j <= nb; j++) + { arc = save[j]; + if (arc <= 0) + arc = -arc; + if (tnxtou[arc] < 0) + { tnxtou[arc] = tfstou[startn[arc]]; + tfstou[startn[arc]] = arc; + } + if (tnxtin[arc] < 0) + { tnxtin[arc] = tfstin[endn[arc]]; + tfstin[endn[arc]] = arc; + } + } + } + /* End of single node iteration for a negative deficit node. */ + } + if (quit || (num_passes <= 3)) + goto L100; + /* Do a multinode iteration from node. */ + nmultinode++; + /* If number of nonzero deficit nodes is small, continue labeling + * until a flow augmentation is done. */ + svitch = (numnz < tp); + /* Unmark nodes labeled earlier. */ + for (j = 1; j <= nlabel; j++) + { node2 = label[j]; + mark[node2] = scan[node2] = false; + } + /* Initialize labeling. */ + nlabel = 1; + label[1] = node; + mark[node] = true; + prdcsr[node] = 0; + /* Scan starting node. */ + scan[node] = true; + nscan = 1; + dm = dfct[node]; + delx = 0; + for (j = 1; j <= nb; j++) + { arc = save[j]; + if (arc > 0) + { if (posit) + node2 = endn[arc]; + else + node2 = startn[arc]; + if (!mark[node2]) + { nlabel++; + label[nlabel] = node2; + prdcsr[node2] = arc; + mark[node2] = true; + delx += x[arc]; + } + } + else + { narc = -arc; + if (posit) + node2 = startn[narc]; + else + node2 = endn[narc]; + if (!mark[node2]) + { nlabel++; + label[nlabel] = node2; + prdcsr[node2] = arc; + mark[node2] = true; + delx += u[narc]; + } + } + } +L4120:/* Start scanning a labeled but unscanned node. */ + nscan++; + /* Check to see if switch needs to be set to true so to continue + * scanning even after a price change. */ + svitch = svitch || ((nscan > ts) && (numnz < ts)); + /* Scanning will continue until either an overestimate of the + * residual capacity across the cut corresponding to the scanned + * set of nodes (called delx) exceeds the absolute value of the + * total deficit of the scanned nodes (called dm), or else an + * augmenting path is found. Arcs that are in the tree but are not + * balanced are removed as part of the scanning process. */ + i = label[nscan]; + scan[i] = true; + naugnod = 0; + if (posit) + { /* Scanning node i in case of positive deficit. */ + prvarc = 0; + arc = tfstou[i]; + while (arc > 0) + { /* arc is an outgoing arc from node. */ + if (rc[arc] == 0) + { if (x[arc] > 0) + { node2 = endn[arc]; + if (!mark[node2]) + { /* node2 is not labeled, so add node2 to the + labeled set. */ + prdcsr[node2] = arc; + if (dfct[node2] < 0) + { naugnod++; + save[naugnod] = node2; + } + nlabel++; + label[nlabel] = node2; + mark[node2] = true; + delx += x[arc]; + } + } + prvarc = arc; + arc = tnxtou[arc]; + } + else + { tmparc = arc; + arc = tnxtou[arc]; + tnxtou[tmparc] = -1; + if (prvarc == 0) + tfstou[i] = arc; + else + tnxtou[prvarc] = arc; + } + } + prvarc = 0; + arc = tfstin[i]; + while (arc > 0) + { /* arc is an incoming arc into node. */ + if (rc[arc] == 0) + { if (u[arc] > 0) + { node2 = startn[arc]; + if (!mark[node2]) + { /* node2 is not labeled, so add node2 to the + * labeled set. */ + prdcsr[node2] = -arc; + if (dfct[node2] < 0) + { naugnod++; + save[naugnod] = node2; + } + nlabel++; + label[nlabel] = node2; + mark[node2] = true; + delx += u[arc]; + } + } + prvarc = arc; + arc = tnxtin[arc]; + } + else + { tmparc = arc; + arc = tnxtin[arc]; + tnxtin[tmparc] = -1; + if (prvarc == 0) + tfstin[i] = arc; + else + tnxtin[prvarc] = arc; + } + } + /* Correct the residual capacity of the scanned node cut. */ + arc = prdcsr[i]; + if (arc > 0) + delx -= x[arc]; + else + delx -= u[-arc]; + /* End of scanning of node i for positive deficit case. */ + } + else + { /* Scanning node i for negative deficit case. */ + prvarc = 0; + arc = tfstin[i]; + while (arc > 0) + { if (rc[arc] == 0) + { if (x[arc] > 0) + { node2 = startn[arc]; + if (!mark[node2]) + { prdcsr[node2] = arc; + if (dfct[node2] > 0) + { naugnod++; + save[naugnod] = node2; + } + nlabel++; + label[nlabel] = node2; + mark[node2] = true; + delx += x[arc]; + } + } + prvarc = arc; + arc = tnxtin[arc]; + } + else + { tmparc = arc; + arc = tnxtin[arc]; + tnxtin[tmparc] = -1; + if (prvarc == 0) + tfstin[i] = arc; + else + tnxtin[prvarc] = arc; + } + } + prvarc = 0; + arc = tfstou[i]; + while (arc > 0) + { if (rc[arc] == 0) + { if (u[arc] > 0) + { node2 = endn[arc]; + if (!mark[node2]) + { prdcsr[node2] = -arc; + if (dfct[node2] > 0) + { naugnod++; + save[naugnod] = node2; + } + nlabel++; + label[nlabel] = node2; + mark[node2] = true; + delx += u[arc]; + } + } + prvarc = arc; + arc = tnxtou[arc]; + } + else + { tmparc = arc; + arc = tnxtou[arc]; + tnxtou[tmparc] = -1; + if (prvarc == 0) + tfstou[i] = arc; + else + tnxtou[prvarc] = arc; + } + } + arc = prdcsr[i]; + if (arc > 0) + delx -= x[arc]; + else + delx -= u[-arc]; + } + /* Add deficit of node scanned to dm. */ + dm += dfct[i]; + /* Check if the set of scanned nodes correspond to a dual ascent + * direction; if yes, perform a price adjustment step, otherwise + * continue labeling. */ + if (nscan < nlabel) + { if (svitch) + goto L4210; + if ((delx >= dm) && (delx >= -dm)) + goto L4210; + } + /* Try a price change. + * [Note that since delx - abs(dm) is an overestimate of ascent + * slope, we may occasionally try a direction that is not an + * ascent direction. In this case the ascnt routines return with + * quit = false, so we continue labeling nodes.] */ + if (posit) + { ascnt1(csa, dm, &delx, &nlabel, &feasbl, &svitch, nscan, node, + &prevnode); + num_ascnt++; + } + else + { ascnt2(csa, dm, &delx, &nlabel, &feasbl, &svitch, nscan, node, + &prevnode); + num_ascnt++; + } + if (!feasbl) + return 8; + if (!svitch) + goto L100; + /* Store those newly labeled nodes to which flow augmentation is + * possible. */ + naugnod = 0; + for (j = nscan + 1; j <= nlabel; j++) + { node2 = label[j]; + if (posit && (dfct[node2] < 0)) + { naugnod++; + save[naugnod] = node2; + } + else if ((!posit) && (dfct[node2] > 0)) + { naugnod++; + save[naugnod] = node2; + } + } +L4210:/* Check if flow augmentation is possible. If not, return to scan + * another node. */ + if (naugnod == 0) + goto L4120; + for (j = 1; j <= naugnod; j++) + { num_augm++; + augnod = save[j]; + if (posit) + { /* Do the augmentation from node with positive deficit. */ + dx = -dfct[augnod]; + ib = augnod; + while (ib != node) + { arc = prdcsr[ib]; + if (arc > 0) + { if (dx > x[arc]) dx = x[arc]; + ib = startn[arc]; + } + else + { if (dx > u[-arc]) dx = u[-arc]; + ib = endn[-arc]; + } + } + if (dx > dfct[node]) dx = dfct[node]; + if (dx > 0) + { /* Increase (decrease) the flow of all forward (backward) + * arcs in the flow augmenting path. Adjust node deficit + * accordingly. */ + if (nxtqueue[augnod] == 0) + { nxtqueue[prevnode] = augnod; + nxtqueue[augnod] = node; + prevnode = augnod; + } + dfct[augnod] += dx; + dfct[node] -= dx; + ib = augnod; + while (ib != node) + { arc = prdcsr[ib]; + if (arc > 0) + { x[arc] -= dx; + u[arc] += dx; + ib = startn[arc]; + } + else + { narc = -arc; + x[narc] += dx; + u[narc] -= dx; + ib = endn[narc]; + } + } + } + } + else + { /* Do the augmentation from node with negative deficit. */ + dx = dfct[augnod]; + ib = augnod; + while (ib != node) + { arc = prdcsr[ib]; + if (arc > 0) + { if (dx > x[arc]) dx = x[arc]; + ib = endn[arc]; + } + else + { if (dx > u[-arc]) dx = u[-arc]; + ib = startn[-arc]; + } + } + if (dx > -dfct[node]) dx = -dfct[node]; + if (dx > 0) + { /* Update the flow and deficits. */ + if (nxtqueue[augnod] == 0) + { nxtqueue[prevnode] = augnod; + nxtqueue[augnod] = node; + prevnode = augnod; + } + dfct[augnod] -= dx; + dfct[node] += dx; + ib = augnod; + while (ib != node) + { arc = prdcsr[ib]; + if (arc > 0) + { x[arc] -= dx; + u[arc] += dx; + ib = endn[arc]; + } + else + { narc = -arc; + x[narc] += dx; + u[narc] -= dx; + ib = startn[narc]; + } + } + } + } + if (dfct[node] == 0) + goto L100; + if (dfct[augnod] != 0) + svitch = false; + } + /* If node still has nonzero deficit and all newly labeled nodes + * have same sign for their deficit as node, we can continue + * labeling. In this case, continue labeling only when flow + * augmentation is done relatively infrequently. */ + if (svitch && (iter > 8 * num_augm)) + goto L4120; + /* Return to do another relaxation iteration. */ + goto L100; +# undef nmultinode +# undef iter +# undef num_augm +# undef num_ascnt +# undef nsp +} + +/*********************************************************************** +* NAME +* +* relax4_inidat - construct linked lists for network topology +* +* PURPOSE +* +* This routine constructs two linked lists for the network topology: +* one list (given by fou, nxtou) for the outgoing arcs of nodes and +* one list (given by fin, nxtin) for the incoming arcs of nodes. These +* two lists are required by RELAX4. +* +* INPUT PARAMETERS +* +* n = number of nodes +* na = number of arcs +* startn[j] = starting node for arc j, j = 1,...,na +* endn[j] = ending node for arc j, j = 1,...,na +* +* OUTPUT PARAMETERS +* +* fou[i] = first arc out of node i, i = 1,...,n +* nxtou[j] = next arc out of the starting node of arc j, j = 1,...,na +* fin[i] = first arc into node i, i = 1,...,n +* nxtin[j] = next arc into the ending node of arc j, j = 1,...,na +* +* WORKING PARAMETERS +* +* tempin[1+n], tempou[1+n] */ + +void relax4_inidat(struct relax4_csa *csa) +{ /* input parameters */ + int n = csa->n; + int na = csa->na; + int *startn = csa->startn; + int *endn = csa->endn; + /* output parameters */ + int *fou = csa->fou; + int *nxtou = csa->nxtou; + int *fin = csa->fin; + int *nxtin = csa->nxtin; + /* working parameters */ + int *tempin = csa->label; + int *tempou = csa->prdcsr; + /* local variables */ + int i, i1, i2; + for (i = 1; i <= n; i++) + { fin[i] = fou[i] = 0; + tempin[i] = tempou[i] = 0; + } + for (i = 1; i <= na; i++) + { nxtin[i] = nxtou[i] = 0; + i1 = startn[i]; + i2 = endn[i]; + if (fou[i1] != 0) + nxtou[tempou[i1]] = i; + else + fou[i1] = i; + tempou[i1] = i; + if (fin[i2] != 0) + nxtin[tempin[i2]] = i; + else + fin[i2] = i; + tempin[i2] = i; + } + return; +} + +/*********************************************************************** +* NAME +* +* ascnt1 - multi-node price adjustment for positive deficit case +* +* PURPOSE +* +* This subroutine performs the multi-node price adjustment step for +* the case where the scanned nodes have positive deficit. It first +* checks if decreasing the price of the scanned nodes increases the +* dual cost. If yes, then it decreases the price of all scanned nodes. +* There are two possibilities for price decrease: if switch = true, +* then the set of scanned nodes corresponds to an elementary direction +* of maximal rate of ascent, in which case the price of all scanned +* nodes are decreased until the next breakpoint in the dual cost is +* encountered. At this point, some arc becomes balanced and more +* node(s) are added to the labeled set and the subroutine is exited. +* If switch = false, then the price of all scanned nodes are decreased +* until the rate of ascent becomes negative (this corresponds to the +* price adjustment step in which both the line search and the +* degenerate ascent iteration are implemented). +* +* INPUT PARAMETERS +* +* dm = total deficit of scanned nodes +* switch = true if labeling is to continue after price change +* nscan = number of scanned nodes +* curnode = most recently scanned node +* n = number of nodes +* na = number of arcs +* large = a very large integer to represent infinity (see note 3) +* startn[i] = starting node for the i-th arc, i = 1,...,na +* endn[i] = ending node for the i-th arc, i = 1,...,na +* fou[i] = first arc leaving i-th node, i = 1,...,n +* nxtou[i] = next arc leaving the starting node of j-th arc, +* i = 1,...,na +* fin[i] = first arc entering i-th node, i = 1,...,n +* nxtin[i] = next arc entering the ending node of j-th arc, +* i = 1,...,na +* +* UPDATED PARAMETERS +* +* delx = a lower estimate of the total flow on balanced arcs in +* the scanned-nodes cut +* nlabel = number of labeled nodes +* feasbl = false if problem is found to be infeasible +* prevnode = the node before curnode in queue +* rc[j] = reduced cost of arc j, j = 1,...,na +* u[j] = residual capacity of arc j, j = 1,...,na +* x[j] = flow on arc j, j = 1,...,na +* dfct[i] = deficit at node i, i = 1,...,n +* label[k] = k-th node labeled, k = 1,...,nlabel +* prdcsr[i] = predecessor of node i in tree of labeled nodes (0 if i +* is unlabeled), i = 1,...,n +* tfstou[i] = first balanced arc out of node i, i = 1,...,n +* tnxtou[j] = next balanced arc out of the starting node of arc j, +* j = 1,...,na +* tfstin[i] = first balanced arc into node i, i = 1,...,n +* tnxtin[j] = next balanced arc into the ending node of arc j, +* j = 1,...,na +* nxtqueue[i] = node following node i in the fifo queue (0 if node is +* not in the queue), i = 1,...,n +* scan[i] = true if node i is scanned, i = 1,...,n +* mark[i] = true if node i is labeled, i = 1,...,n +* +* WORKING PARAMETERS +* +* save[1+na] */ + +static void ascnt1(struct relax4_csa *csa, int dm, int *delx, + int *nlabel, int *feasbl, int *svitch, int nscan, int curnode, + int *prevnode) +{ /* input parameters */ + int n = csa->n; + /* int na = csa->na; */ + int large = csa->large; + int *startn = csa->startn; + int *endn = csa->endn; + int *fou = csa->fou; + int *nxtou = csa->nxtou; + int *fin = csa->fin; + int *nxtin = csa->nxtin; + /* updated parameters */ +# define delx (*delx) +# define nlabel (*nlabel) +# define feasbl (*feasbl) +# define svitch (*svitch) +# define prevnode (*prevnode) + int *rc = csa->rc; + int *u = csa->u; + int *x = csa->x; + int *dfct = csa->dfct; + int *label = csa->label; + int *prdcsr = csa->prdcsr; + int *tfstou = csa->tfstou; + int *tnxtou = csa->tnxtou; + int *tfstin = csa->tfstin; + int *tnxtin = csa->tnxtin; + int *nxtqueue = csa->nxtqueue; + char *scan = csa->scan; + char *mark = csa->mark; + int *save = csa->save; + /* local variables */ + int arc, delprc, dlx, i, j, nb, node, node2, nsave, rdcost, t1, + t2, t3; + /* Store the arcs between the set of scanned nodes and its + * complement in save and compute delprc, the stepsize to the next + * breakpoint in the dual cost in the direction of decreasing + * prices of the scanned nodes. + * [The arcs are stored into save by looking at the arcs incident + * to either the set of scanned nodes or its complement, depending + * on whether nscan > n/2 or not. This improves the efficiency of + * storing.] */ + delprc = large; + dlx = 0; + nsave = 0; + if (nscan <= n / 2) + { for (i = 1; i <= nscan; i++) + { node = label[i]; + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { /* arc points from scanned node to an unscanned node. */ + node2 = endn[arc]; + if (!scan[node2]) + { nsave++; + save[nsave] = arc; + rdcost = rc[arc]; + if ((rdcost == 0) && (prdcsr[node2] != arc)) + dlx += x[arc]; + if ((rdcost < 0) && (rdcost > -delprc)) + delprc = -rdcost; + } + } + for (arc = fin[node]; arc > 0; arc = nxtin[arc]) + { /* arc points from unscanned node to scanned node. */ + node2 = startn[arc]; + if (!scan[node2]) + { nsave++; + save[nsave] = -arc; + rdcost = rc[arc]; + if ((rdcost == 0) && (prdcsr[node2] != -arc)) + dlx += u[arc]; + if ((rdcost > 0) && (rdcost < delprc)) + delprc = rdcost; + } + } + } + } + else + { for (node = 1; node <= n; node++) + { if (scan[node]) + continue; + for (arc = fin[node]; arc > 0; arc = nxtin[arc]) + { node2 = startn[arc]; + if (scan[node2]) + { nsave++; + save[nsave] = arc; + rdcost = rc[arc]; + if ((rdcost == 0) && (prdcsr[node] != arc)) + dlx += x[arc]; + if ((rdcost < 0) && (rdcost > -delprc)) + delprc = -rdcost; + } + } + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { node2 = endn[arc]; + if (scan[node2]) + { nsave++; + save[nsave] = -arc; + rdcost = rc[arc]; + if ((rdcost == 0) && (prdcsr[node] != -arc)) + dlx += u[arc]; + if ((rdcost > 0) && (rdcost < delprc)) + delprc = rdcost; + } + } + } + } + /* Check if the set of scanned nodes truly corresponds to a dual + * ascent direction. [Here delx + dlx is the exact sum of the flow + * on arcs from the scanned set to the unscanned set plus the + * (capacity - flow) on arcs from the unscanned set to the scanned + * set.] If this were not the case, set switch to true and exit + * subroutine. */ + if ((!svitch) && (delx + dlx >= dm)) + { svitch = true; + return; + } + delx += dlx; +L4: /* Check that the problem is feasible. */ + if (delprc == large) + { /* We can increase the dual cost without bound, so the primal + * problem is infeasible. */ + feasbl = false; + return; + } + /* Decrease the prices of the scanned nodes, add more nodes to + * the labeled set and check if a newly labeled node has negative + * deficit. */ + if (svitch) + { for (i = 1; i <= nsave; i++) + { arc = save[i]; + if (arc > 0) + { rc[arc] += delprc; + if (rc[arc] == 0) + { node2 = endn[arc]; + if (tnxtou[arc] < 0) + { tnxtou[arc] = tfstou[startn[arc]]; + tfstou[startn[arc]] = arc; + } + if (tnxtin[arc] < 0) + { tnxtin[arc] = tfstin[node2]; + tfstin[node2] = arc; + } + if (!mark[node2]) + { prdcsr[node2] = arc; + nlabel++; + label[nlabel] = node2; + mark[node2] = true; + } + } + } + else + { arc = -arc; + rc[arc] -= delprc; + if (rc[arc] == 0) + { node2 = startn[arc]; + if (tnxtou[arc] < 0) + { tnxtou[arc] = tfstou[node2]; + tfstou[node2] = arc; + } + if (tnxtin[arc] < 0) + { tnxtin[arc] = tfstin[endn[arc]]; + tfstin[endn[arc]] = arc; + } + if (!mark[node2]) + { prdcsr[node2] = -arc; + nlabel++; + label[nlabel] = node2; + mark[node2] = true; + } + } + } + } + return; + } + else + { /* Decrease the prices of the scanned nodes by delprc. Adjust + * flow to maintain complementary slackness with the prices. */ + nb = 0; + for (i = 1; i <= nsave; i++) + { arc = save[i]; + if (arc > 0) + { t1 = rc[arc]; + if (t1 == 0) + { t2 = x[arc]; + t3 = startn[arc]; + dfct[t3] -= t2; + if (nxtqueue[t3] == 0) + { nxtqueue[prevnode] = t3; + nxtqueue[t3] = curnode; + prevnode = t3; + } + t3 = endn[arc]; + dfct[t3] += t2; + if (nxtqueue[t3] == 0) + { nxtqueue[prevnode] = t3; + nxtqueue[t3] = curnode; + prevnode = t3; + } + u[arc] += t2; + x[arc] = 0; + } + rc[arc] = t1 + delprc; +#if 0 /* by mao; 26/IV-2013 */ + if (rc[arc] == 0) +#else + if (rc[arc] == 0 && nb < n) +#endif + { delx += x[arc]; + nb++; + prdcsr[nb] = arc; + } + } + else + { arc = -arc; + t1 = rc[arc]; + if (t1 == 0) + { t2 = u[arc]; + t3 = startn[arc]; + dfct[t3] += t2; + if (nxtqueue[t3] == 0) + { nxtqueue[prevnode] = t3; + nxtqueue[t3] = curnode; + prevnode = t3; + } + t3 = endn[arc]; + dfct[t3] -= t2; + if (nxtqueue[t3] == 0) + { nxtqueue[prevnode] = t3; + nxtqueue[t3] = curnode; + prevnode = t3; + } + x[arc] += t2; + u[arc] = 0; + } + rc[arc] = t1 - delprc; +#if 0 /* by mao; 26/IV-2013 */ + if (rc[arc] == 0) +#else + if (rc[arc] == 0 && nb < n) +#endif + { delx += u[arc]; + nb++; + prdcsr[nb] = arc; + } + } + } + } + if (delx <= dm) + { /* The set of scanned nodes still corresponds to a dual + * (possibly degenerate) ascent direction. Compute the stepsize + * delprc to the next breakpoint in the dual cost. */ + delprc = large; + for (i = 1; i <= nsave; i++) + { arc = save[i]; + if (arc > 0) + { rdcost = rc[arc]; + if ((rdcost < 0) && (rdcost > -delprc)) + delprc = -rdcost; + } + else + { arc = -arc; + rdcost = rc[arc]; + if ((rdcost > 0) && (rdcost < delprc)) + delprc = rdcost; + } + } + if ((delprc != large) || (delx < dm)) + goto L4; + } + /* Add new balanced arcs to the superset of balanced arcs. */ + for (i = 1; i <= nb; i++) + { arc = prdcsr[i]; + if (tnxtin[arc] == -1) + { j = endn[arc]; + tnxtin[arc] = tfstin[j]; + tfstin[j] = arc; + } + if (tnxtou[arc] == -1) + { j = startn[arc]; + tnxtou[arc] = tfstou[j]; + tfstou[j] = arc; + } + } + return; +# undef delx +# undef nlabel +# undef feasbl +# undef svitch +# undef prevnode +} + +/*********************************************************************** +* NAME +* +* ascnt2 - multi-node price adjustment for negative deficit case +* +* PURPOSE +* +* This routine is analogous to ascnt1 but for the case where the +* scanned nodes have negative deficit. */ + +static void ascnt2(struct relax4_csa *csa, int dm, int *delx, + int *nlabel, int *feasbl, int *svitch, int nscan, int curnode, + int *prevnode) +{ /* input parameters */ + int n = csa->n; + /* int na = csa->na; */ + int large = csa->large; + int *startn = csa->startn; + int *endn = csa->endn; + int *fou = csa->fou; + int *nxtou = csa->nxtou; + int *fin = csa->fin; + int *nxtin = csa->nxtin; + /* updated parameters */ +# define delx (*delx) +# define nlabel (*nlabel) +# define feasbl (*feasbl) +# define svitch (*svitch) +# define prevnode (*prevnode) + int *rc = csa->rc; + int *u = csa->u; + int *x = csa->x; + int *dfct = csa->dfct; + int *label = csa->label; + int *prdcsr = csa->prdcsr; + int *tfstou = csa->tfstou; + int *tnxtou = csa->tnxtou; + int *tfstin = csa->tfstin; + int *tnxtin = csa->tnxtin; + int *nxtqueue = csa->nxtqueue; + char *scan = csa->scan; + char *mark = csa->mark; + int *save = csa->save; + /* local variables */ + int arc, delprc, dlx, i, j, nb, node, node2, nsave, rdcost, t1, + t2, t3; + /* Store the arcs between the set of scanned nodes and its + * complement in save and compute delprc, the stepsize to the next + * breakpoint in the dual cost in the direction of increasing + * prices of the scanned nodes. */ + delprc = large; + dlx = 0; + nsave = 0; + if (nscan <= n / 2) + { for (i = 1; i <= nscan; i++) + { node = label[i]; + for (arc = fin[node]; arc > 0; arc = nxtin[arc]) + { node2 = startn[arc]; + if (!scan[node2]) + { nsave++; + save[nsave] = arc; + rdcost = rc[arc]; + if ((rdcost == 0) && (prdcsr[node2] != arc)) + dlx += x[arc]; + if ((rdcost < 0) && (rdcost > -delprc)) + delprc = -rdcost; + } + } + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { node2 = endn[arc]; + if (!scan[node2]) + { nsave++; + save[nsave] = -arc; + rdcost = rc[arc]; + if ((rdcost == 0) && (prdcsr[node2] != -arc)) + dlx += u[arc]; + if ((rdcost > 0) && (rdcost < delprc)) + delprc = rdcost; + } + } + } + } + else + { for (node = 1; node <= n; node++) + { if (scan[node]) + continue; + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { node2 = endn[arc]; + if (scan[node2]) + { nsave++; + save[nsave] = arc; + rdcost = rc[arc]; + if ((rdcost == 0) && (prdcsr[node] != arc)) + dlx += x[arc]; + if ((rdcost < 0) && (rdcost > -delprc)) + delprc = -rdcost; + } + } + for (arc = fin[node]; arc > 0; arc = nxtin[arc]) + { node2 = startn[arc]; + if (scan[node2]) + { nsave++; + save[nsave] = -arc; + rdcost = rc[arc]; + if ((rdcost == 0) && (prdcsr[node] != -arc)) + dlx += u[arc]; + if ((rdcost > 0) && (rdcost < delprc)) + delprc = rdcost; + } + } + } + } + if ((!svitch) && (delx + dlx >= -dm)) + { svitch = true; + return; + } + delx += dlx; + /* Check that the problem is feasible. */ +L4: if (delprc == large) + { feasbl = false; + return; + } + /* Increase the prices of the scanned nodes, add more nodes to + * the labeled set and check if a newly labeled node has positive + * deficit. */ + if (svitch) + { for (i = 1; i <= nsave; i++) + { arc = save[i]; + if (arc > 0) + { rc[arc] += delprc; + if (rc[arc] == 0) + { node2 = startn[arc]; + if (tnxtou[arc] < 0) + { tnxtou[arc] = tfstou[node2]; + tfstou[node2] = arc; + } + if (tnxtin[arc] < 0) + { tnxtin[arc] = tfstin[endn[arc]]; + tfstin[endn[arc]] = arc; + } + if (!mark[node2]) + { prdcsr[node2] = arc; + nlabel++; + label[nlabel] = node2; + mark[node2] = true; + } + } + } + else + { arc = -arc; + rc[arc] -= delprc; + if (rc[arc] == 0) + { node2 = endn[arc]; + if (tnxtou[arc] < 0) + { tnxtou[arc] = tfstou[startn[arc]]; + tfstou[startn[arc]] = arc; + } + if (tnxtin[arc] < 0) + { tnxtin[arc] = tfstin[node2]; + tfstin[node2] = arc; + } + if (!mark[node2]) + { prdcsr[node2] = -arc; + nlabel++; + label[nlabel] = node2; + mark[node2] = true; + } + } + } + } + return; + } + else + { nb = 0; + for (i = 1; i <= nsave; i++) + { arc = save[i]; + if (arc > 0) + { t1 = rc[arc]; + if (t1 == 0) + { t2 = x[arc]; + t3 = startn[arc]; + dfct[t3] -= t2; + if (nxtqueue[t3] == 0) + { nxtqueue[prevnode] = t3; + nxtqueue[t3] = curnode; + prevnode = t3; + } + t3 = endn[arc]; + dfct[t3] += t2; + if (nxtqueue[t3] == 0) + { nxtqueue[prevnode] = t3; + nxtqueue[t3] = curnode; + prevnode = t3; + } + u[arc] += t2; + x[arc] = 0; + } + rc[arc] = t1 + delprc; +#if 0 /* by mao; 26/IV-2013 */ + if (rc[arc] == 0) +#else + if (rc[arc] == 0 && nb < n) +#endif + { delx += x[arc]; + nb++; + prdcsr[nb] = arc; + } + } + else + { arc = -arc; + t1 = rc[arc]; + if (t1 == 0) + { t2 = u[arc]; + t3 = startn[arc]; + dfct[t3] += t2; + if (nxtqueue[t3] == 0) + { nxtqueue[prevnode] = t3; + nxtqueue[t3] = curnode; + prevnode = t3; + } + t3 = endn[arc]; + dfct[t3] -= t2; + if (nxtqueue[t3] == 0) + { nxtqueue[prevnode] = t3; + nxtqueue[t3] = curnode; + prevnode = t3; + } + x[arc] += t2; + u[arc] = 0; + } + rc[arc] = t1 - delprc; +#if 0 /* by mao; 26/IV-2013 */ + if (rc[arc] == 0) +#else + if (rc[arc] == 0 && nb < n) +#endif + { delx += u[arc]; + nb++; + prdcsr[nb] = arc; + } + } + } + } + if (delx <= -dm) + { delprc = large; + for (i = 1; i <= nsave; i++) + { arc = save[i]; + if (arc > 0) + { rdcost = rc[arc]; + if ((rdcost < 0) && (rdcost > -delprc)) + delprc = -rdcost; + } + else + { arc = -arc; + rdcost = rc[arc]; + if ((rdcost > 0) && (rdcost < delprc)) + delprc = rdcost; + } + } + if ((delprc != large) || (delx < -dm)) + goto L4; + } + /* Add new balanced arcs to the superset of balanced arcs. */ + for (i = 1; i <= nb; i++) + { arc = prdcsr[i]; + if (tnxtin[arc] == -1) + { j = endn[arc]; + tnxtin[arc] = tfstin[j]; + tfstin[j] = arc; + } + if (tnxtou[arc] == -1) + { j = startn[arc]; + tnxtou[arc] = tfstou[j]; + tfstou[j] = arc; + } + } + return; +# undef delx +# undef nlabel +# undef feasbl +# undef svitch +# undef prevnode +} + +/*********************************************************************** +* NAME +* +* auction - compute good initial flow and prices +* +* PURPOSE +* +* This subroutine uses a version of the auction algorithm for min +* cost network flow to compute a good initial flow and prices for the +* problem. +* +* INPUT PARAMETERS +* +* n = number of nodes +* na = number of arcs +* large = a very large integer to represent infinity (see note 3) +* startn[i] = starting node for the i-th arc, i = 1,...,na +* endn[i] = ending node for the i-th arc, i = 1,...,na +* fou[i] = first arc leaving i-th node, i = 1,...,n +* nxtou[i] = next arc leaving the starting node of j-th arc, +* i = 1,...,na +* fin[i] = first arc entering i-th node, i = 1,...,n +* nxtin[i] = next arc entering the ending node of j-th arc, +* i = 1,...,na +* +* UPDATED PARAMETERS +* +* rc[j] = reduced cost of arc j, j = 1,...,na +* u[j] = residual capacity of arc j, j = 1,...,na +* x[j] = flow on arc j, j = 1,...,na +* dfct[i] = deficit at node i, i = 1,...,n +* +* OUTPUT PARAMETERS +* +* nsp = number of auction/shortest path iterations +* +* WORKING PARAMETERS +* +* p[1+n], prdcsr[1+n], save[1+na], fpushf[1+n], nxtpushf[1+na], +* fpushb[1+n], nxtpushb[1+na], nxtqueue[1+n], extend_arc[1+n], +* sb_level[1+n], sb_arc[1+n], path_id[1+n] +* +* RETURNS +* +* 0 = normal return +* 1 = problem is found to be infeasible */ + +static int auction(struct relax4_csa *csa) +{ /* input parameters */ + int n = csa->n; + int na = csa->na; + int large = csa->large; + int *startn = csa->startn; + int *endn = csa->endn; + int *fou = csa->fou; + int *nxtou = csa->nxtou; + int *fin = csa->fin; + int *nxtin = csa->nxtin; + /* updated parameters */ +# define crash (csa->crash) + int *rc = csa->rc; + int *u = csa->u; + int *x = csa->x; + int *dfct = csa->dfct; + /* output parameters */ +# define nsp (csa->nsp) + /* working parameters */ + int *p = csa->label; + int *prdcsr = csa->prdcsr; + int *save = csa->save; + int *fpushf = csa->tfstou; + int *nxtpushf = csa->tnxtou; + int *fpushb = csa->tfstin; + int *nxtpushb = csa->tnxtin; + int *nxtqueue = csa->nxtqueue; + int *extend_arc = csa->extend_arc; + int *sb_level = csa->sb_level; + int *sb_arc = csa->sb_arc; + char *path_id = csa->mark; + /* local variables */ + int arc, bstlevel, end, eps, extarc, factor, flow, i, incr, + last, lastqueue, maxcost, mincost, nas, naug, new_level, node, + nolist, num_passes, nxtnode, pass, pend, pr_term, prd, + prevarc, prevlevel, prevnode, pstart, pterm, rdcost, red_cost, + resid, root, secarc, seclevel, start, term, thresh_dfct; + /* start initialization using auction */ + naug = 0; + pass = 0; + thresh_dfct = 0; + /* factor determines by how much epsilon is reduced at each + * minimization */ + factor = 3; + /* num_passes determines how many auction scaling phases are + * performed */ + num_passes = 1; + /* set arc flows to satisfy cs and calculate maxcost and + * mincost */ + maxcost = -large; + mincost = large; + for (arc = 1; arc <= na; arc++) + { start = startn[arc]; + end = endn[arc]; + rdcost = rc[arc]; + if (maxcost < rdcost) + maxcost = rdcost; + if (mincost > rdcost) + mincost = rdcost; + if (rdcost < 0) + { dfct[start] += u[arc]; + dfct[end] -= u[arc]; + x[arc] = u[arc]; + u[arc] = 0; + } + else + x[arc] = 0; + } + /* set initial epsilon */ + if ((maxcost - mincost) >= 8) + eps = (maxcost - mincost) / 8; + else + eps = 1; + /* set initial prices to zero */ + for (node = 1; node <= n; node++) + p[node] = 0; + /* Initialization using auction/shortest paths. */ +L100: /* Start of the first scaling phase. */ + pass++; + if ((pass == num_passes) || (eps == 1)) + crash = 0; + nolist = 0; + /* construct list of positive surplus nodes and queue of negative + * surplus nodes */ + for (node = 1; node <= n; node++) + { prdcsr[node] = 0; + path_id[node] = false; + extend_arc[node] = 0; + sb_level[node] = -large; + nxtqueue[node] = node + 1; + if (dfct[node] > 0) + { nolist++; + save[nolist] = node; + } + } + nxtqueue[n] = 1; + root = 1; + prevnode = lastqueue = n; + /* initialization with down iterations for negative surplus + * nodes */ + for (i = 1; i <= nolist; i++) + { node = save[i]; + nsp++; + /* build the list of arcs w/ room for pushing flow and find + * proper price for down iteration */ + bstlevel = -large; + fpushf[node] = 0; + for (arc = fou[node]; arc > 0; arc = nxtou[arc]) + { if (u[arc] > 0) + { if (fpushf[node] == 0) + { fpushf[node] = arc; + nxtpushf[arc] = 0; + last = arc; + } + else + { nxtpushf[last] = arc; + nxtpushf[arc] = 0; + last = arc; + } + } + if (x[arc] > 0) + { new_level = p[endn[arc]] + rc[arc]; + if (new_level > bstlevel) + { bstlevel = new_level; + extarc = arc; + } + } + } + fpushb[node] = 0; + for (arc = fin[node]; arc > 0; arc = nxtin[arc]) + { if (x[arc] > 0) + { if (fpushb[node] == 0) + { fpushb[node] = arc; + nxtpushb[arc] = 0; + last = arc; + } + else + { nxtpushb[last] = arc; + nxtpushb[arc] = 0; + last = arc; + } + } + if (u[arc] > 0) + { new_level = p[startn[arc]] - rc[arc]; + if (new_level > bstlevel) + { bstlevel = new_level; + extarc = -arc; + } + } + } + extend_arc[node] = extarc; + p[node] = bstlevel - eps; + } +L200: /* Start the augmentation cycles of the new scaling phase. */ + if (dfct[root] >= thresh_dfct) + goto L3000; + term = root; + path_id[root] = true; +L500: /* Main forward algorithm with root as origin. */ + /* start of a new forward iteration */ + pterm = p[term]; + extarc = extend_arc[term]; + if (extarc == 0) + { /* build the list of arcs w/ room for pushing flow */ + fpushf[term] = 0; + for (arc = fou[term]; arc > 0; arc = nxtou[arc]) + { if (u[arc] > 0) + { if (fpushf[term] == 0) + { fpushf[term] = arc; + nxtpushf[arc] = 0; + last = arc; + } + else + { nxtpushf[last] = arc; + nxtpushf[arc] = 0; + last = arc; + } + } + } + fpushb[term] = 0; + for (arc = fin[term]; arc > 0; arc = nxtin[arc]) + { if (x[arc] > 0) + { if (fpushb[term] == 0) + { fpushb[term] = arc; + nxtpushb[arc] = 0; + last = arc; + } + else + { nxtpushb[last] = arc; + nxtpushb[arc] = 0; + last = arc; + } + } + } + goto L600; + } + /* speculative path extension attempt */ + /* note: arc > 0 means that arc is oriented from the root to the + * destinations + * arc < 0 means that arc is oriented from the destinations to the + * root + * extarc = 0 or prdarc = 0, means the extension arc or the + * predecessor arc, respectively, has not been established */ + if (extarc > 0) + { if (u[extarc] == 0) + { seclevel = sb_level[term]; + goto L580; + } + end = endn[extarc]; + bstlevel = p[end] + rc[extarc]; + if (pterm >= bstlevel) + { if (path_id[end]) + goto L1200; + term = end; + prdcsr[term] = extarc; + path_id[term] = true; + /* if negative surplus node is found, do an augmentation */ + if (dfct[term] > 0) + goto L2000; + /* return for another iteration */ + goto L500; + } + } + else + { extarc = -extarc; + if (x[extarc] == 0) + { seclevel = sb_level[term]; + goto L580; + } + start = startn[extarc]; + bstlevel = p[start] - rc[extarc]; + if (pterm >= bstlevel) + { if (path_id[start]) + goto L1200; + term = start; + prdcsr[term] = -extarc; + path_id[term] = true; + /* if negative surplus node is found, do an augmentation */ + if (dfct[term] > 0) + goto L2000; + /* return for another iteration */ + goto L500; + } + } +L550: /* second best logic test applied to save a full node scan + * if old best level continues to be best go for another + * contraction */ + seclevel = sb_level[term]; + if (bstlevel <= seclevel) + goto L800; +L580: /* if second best can be used do either a contraction or start + * over with a speculative extension */ + if (seclevel > -large) + { extarc = sb_arc[term]; + if (extarc > 0) + { if (u[extarc] == 0) + goto L600; + bstlevel = p[endn[extarc]] + rc[extarc]; + } + else + { if (x[-extarc] == 0) + goto L600; + bstlevel = p[startn[-extarc]] - rc[-extarc]; + } + if (bstlevel == seclevel) + { sb_level[term] = -large; + extend_arc[term] = extarc; + goto L800; + } + } +L600: /* extension/contraction attempt was unsuccessful, so scan + * terminal node */ + nsp++; + bstlevel = seclevel = large; + for (arc = fpushf[term]; arc > 0; arc = nxtpushf[arc]) + { new_level = p[endn[arc]] + rc[arc]; + if (new_level < seclevel) + { if (new_level < bstlevel) + { seclevel = bstlevel; + bstlevel = new_level; + secarc = extarc; + extarc = arc; + } + else + { seclevel = new_level; + secarc = arc; + } + } + } + for (arc = fpushb[term]; arc > 0; arc = nxtpushb[arc]) + { new_level = p[startn[arc]] - rc[arc]; + if (new_level < seclevel) + { if (new_level < bstlevel) + { seclevel = bstlevel; + bstlevel = new_level; + secarc = extarc; + extarc = -arc; + } + else + { seclevel = new_level; + secarc = -arc; + } + } + } + sb_level[term] = seclevel; + sb_arc[term] = secarc; + extend_arc[term] = extarc; +L800: /* End of node scan. */ + /* if the terminal node is the root, adjust its price and change + * root */ + if (term == root) + { p[term] = bstlevel + eps; + if (p[term] >= large) + { /* no path to the destination */ + /* problem is found to be infeasible */ + return 1; + } + path_id[root] = false; + prevnode = root; + root = nxtqueue[root]; + goto L200; + } + /* check whether extension or contraction */ + prd = prdcsr[term]; + if (prd > 0) + { pr_term = startn[prd]; + prevlevel = p[pr_term] - rc[prd]; + } + else + { pr_term = endn[-prd]; + prevlevel = p[pr_term] + rc[-prd]; + } + if (prevlevel > bstlevel) + { /* path extension */ + if (prevlevel >= bstlevel + eps) + p[term] = bstlevel + eps; + else + p[term] = prevlevel; + if (extarc > 0) + { end = endn[extarc]; + if (path_id[end]) + goto L1200; + term = end; + } + else + { start = startn[-extarc]; + if (path_id[start]) + goto L1200; + term = start; + } + prdcsr[term] = extarc; + path_id[term] = true; + /* if negative surplus node is found, do an augmentation */ + if (dfct[term] > 0) + goto L2000; + /* return for another iteration */ + goto L500; + } + else + { /* path contraction */ + p[term] = bstlevel + eps; + path_id[term] = false; + term = pr_term; + if (pr_term != root) + { if (bstlevel <= pterm + eps) + goto L2000; + } + pterm = p[term]; + extarc = prd; + if (prd > 0) + bstlevel += eps + rc[prd]; + else + bstlevel += eps - rc[-prd]; + /* do a second best test and if that fails, do a full node + * scan */ + goto L550; + } +L1200:/* A cycle is about to form; do a retreat sequence. */ + node = term; +L1600:if (node != root) + { path_id[node] = false; + prd = prdcsr[node]; + if (prd > 0) + { pr_term = startn[prd]; + if (p[pr_term] == p[node] + rc[prd] + eps) + { node = pr_term; + goto L1600; + } + } + else + { pr_term = endn[-prd]; + if (p[pr_term] == p[node] - rc[-prd] + eps) + { node = pr_term; + goto L1600; + } + } + /* do a full scan and price rise at pr_term */ + nsp++; + bstlevel = seclevel = large; + for (arc = fpushf[pr_term]; arc > 0; arc = nxtpushf[arc]) + { new_level = p[endn[arc]] + rc[arc]; + if (new_level < seclevel) + { if (new_level < bstlevel) + { seclevel = bstlevel; + bstlevel = new_level; + secarc = extarc; + extarc = arc; + } + else + { seclevel = new_level; + secarc = arc; + } + } + } + for (arc = fpushb[pr_term]; arc > 0; arc = nxtpushb[arc]) + { new_level = p[startn[arc]] - rc[arc]; + if (new_level < seclevel) + { if (new_level < bstlevel) + { seclevel = bstlevel; + bstlevel = new_level; + secarc = extarc; + extarc = -arc; + } + else + { seclevel = new_level; + secarc = -arc; + } + } + } + sb_level[pr_term] = seclevel; + sb_arc[pr_term] = secarc; + extend_arc[pr_term] = extarc; + p[pr_term] = bstlevel + eps; + if (pr_term == root) + { prevnode = root; + path_id[root] = false; + root = nxtqueue[root]; + goto L200; + } + path_id[pr_term] = false; + prd = prdcsr[pr_term]; + if (prd > 0) + term = startn[prd]; + else + term = endn[-prd]; + if (term == root) + { prevnode = root; + path_id[root] = false; + root = nxtqueue[root]; + goto L200; + } + else + goto L2000; + } +L2000:/* End of auction/shortest path routine. */ + /* do augmentation from root and correct the push lists */ + incr = -dfct[root]; + for (node = root;;) + { extarc = extend_arc[node]; + path_id[node] = false; + if (extarc > 0) + { node = endn[extarc]; + if (incr > u[extarc]) + incr = u[extarc]; + } + else + { node = startn[-extarc]; + if (incr > x[-extarc]) + incr = x[-extarc]; + } + if (node == term) + break; + } + path_id[term] = false; + if (dfct[term] > 0) + { if (incr > dfct[term]) + incr = dfct[term]; + } + for (node = root;;) + { extarc = extend_arc[node]; + if (extarc > 0) + { end = endn[extarc]; + /* add arc to the reduced graph */ + if (x[extarc] == 0) + { nxtpushb[extarc] = fpushb[end]; + fpushb[end] = extarc; + new_level = p[node] - rc[extarc]; + if (sb_level[end] > new_level) + { sb_level[end] = new_level; + sb_arc[end] = -extarc; + } + } + x[extarc] += incr; + u[extarc] -= incr; + /* remove arc from the reduced graph */ + if (u[extarc] == 0) + { nas++; + arc = fpushf[node]; + if (arc == extarc) + fpushf[node] = nxtpushf[arc]; + else + { prevarc = arc; + arc = nxtpushf[arc]; + while (arc > 0) + { if (arc == extarc) + { nxtpushf[prevarc] = nxtpushf[arc]; + break; + } + prevarc = arc; + arc = nxtpushf[arc]; + } + } + } + node = end; + } + else + { extarc = -extarc; + start = startn[extarc]; + /* add arc to the reduced graph */ + if (u[extarc] == 0) + { nxtpushf[extarc] = fpushf[start]; + fpushf[start] = extarc; + new_level = p[node] + rc[extarc]; + if (sb_level[start] > new_level) + { sb_level[start] = new_level; + sb_arc[start] = extarc; + } + } + u[extarc] += incr; + x[extarc] -= incr; + /* remove arc from the reduced graph */ + if (x[extarc] == 0) + { nas++; + arc = fpushb[node]; + if (arc == extarc) + fpushb[node] = nxtpushb[arc]; + else + { prevarc = arc; + arc = nxtpushb[arc]; + while (arc > 0) + { if (arc == extarc) + { nxtpushb[prevarc] = nxtpushb[arc]; + break; + } + prevarc = arc; + arc = nxtpushb[arc]; + } + } + } + node = start; + } + if (node == term) + break; + } + dfct[term] -= incr; + dfct[root] += incr; + /* insert term in the queue if it has a large enough surplus */ + if (dfct[term] < thresh_dfct) + { if (nxtqueue[term] == 0) + { nxtnode = nxtqueue[root]; + if ((p[term] >= p[nxtnode]) && (root != nxtnode)) + { nxtqueue[root] = term; + nxtqueue[term] = nxtnode; + } + else + { nxtqueue[prevnode] = term; + nxtqueue[term] = root; + prevnode = term; + } + } + } + /* if root has a large enough surplus, keep it in the queue and + * return for another iteration */ + if (dfct[root] < thresh_dfct) + { prevnode = root; + root = nxtqueue[root]; + goto L200; + } +L3000:/* end of augmentation cycle */ + /* Check for termination of scaling phase. If scaling phase is not + * finished, advance the queue and return to take another node. */ + nxtnode = nxtqueue[root]; + if (root != nxtnode) + { nxtqueue[root] = 0; + nxtqueue[prevnode] = nxtnode; + root = nxtnode; + goto L200; + } + /* End of subproblem (scaling phase). */ + /* Reduce epsilon. */ + eps /= factor; + if (eps < 1) eps = 1; + thresh_dfct /= factor; + if (eps == 1) thresh_dfct = 0; + /* if another auction scaling phase remains, reset the flows & + * the push lists; else reset arc flows to satisfy cs and compute + * reduced costs */ + if (crash == 1) + { for (arc = 1; arc <= na; arc++) + { start = startn[arc]; + end = endn[arc]; + pstart = p[start]; + pend = p[end]; + if (pstart > pend + eps + rc[arc]) + { resid = u[arc]; + if (resid > 0) + { dfct[start] += resid; + dfct[end] -= resid; + x[arc] += resid; + u[arc] = 0; + } + } + else if (pstart < pend - eps + rc[arc]) + { flow = x[arc]; + if (flow > 0) + { dfct[start] -= flow; + dfct[end] += flow; + x[arc] = 0; + u[arc] += flow; + } + } + } + /* return for another phase */ + goto L100; + } + else + { crash = 1; + for (arc = 1; arc <= na; arc++) + { start = startn[arc]; + end = endn[arc]; + red_cost = rc[arc] + p[end] - p[start]; + if (red_cost < 0) + { resid = u[arc]; + if (resid > 0) + { dfct[start] += resid; + dfct[end] -= resid; + x[arc] += resid; + u[arc] = 0; + } + } + else if (red_cost > 0) + { flow = x[arc]; + if (flow > 0) + { dfct[start] -= flow; + dfct[end] += flow; + x[arc] = 0; + u[arc] += flow; + } + } + rc[arc] = red_cost; + } + } + return 0; +# undef crash +# undef nsp +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/relax4.h b/resources/3rdparty/glpk-4.57/src/misc/relax4.h new file mode 100644 index 000000000..f48b8508c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/relax4.h @@ -0,0 +1,102 @@ +/* relax4.h */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef RELAX4_H +#define RELAX4_H + +struct relax4_csa +{ /* common storage area */ + /* input parameters --------------------------------------------*/ + int n; + /* number of nodes */ + int na; + /* number of arcs */ + int large; + /* very large int to represent infinity */ + int repeat; + /* true if initialization is to be skipped (false otherwise) */ + int crash; + /* 0 if default initialization is used + * 1 if auction initialization is used */ + int *startn; /* int startn[1+na]; */ + /* startn[j] = starting node for arc j, j = 1,...,na */ + int *endn; /* int endn[1+na] */ + /* endn[j] = ending node for arc j, j = 1,...,na */ + int *fou; /* int fou[1+n]; */ + /* fou[i] = first arc out of node i, i = 1,...,n */ + int *nxtou; /* int nxtou[1+na]; */ + /* nxtou[j] = next arc out of the starting node of arc j, + * j = 1,...,na */ + int *fin; /* int fin[1+n]; */ + /* fin[i] = first arc into node i, i = 1,...,n */ + int *nxtin; /* int nxtin[1+na]; */ + /* nxtin[j] = next arc into the ending node of arc j, + * j = 1,...,na */ + /* updated parameters ------------------------------------------*/ + int *rc; /* int rc[1+na]; */ + /* rc[j] = reduced cost of arc j, j = 1,...,na */ + int *u; /* int u[1+na]; */ + /* u[j] = capacity of arc j on input + * and (capacity of arc j) - x(j) on output, j = 1,...,na */ + int *dfct; /* int dfct[1+n]; */ + /* dfct[i] = demand at node i on input + * and zero on output, i = 1,...,n */ + /* output parameters -------------------------------------------*/ + int *x; /* int x[1+na]; */ + /* x[j] = flow on arc j, j = 1,...,na */ + int nmultinode; + /* number of multinode relaxation iterations in RELAX4 */ + int iter; + /* number of relaxation iterations in RELAX4 */ + int num_augm; + /* number of flow augmentation steps in RELAX4 */ + int num_ascnt; + /* number of multinode ascent steps in RELAX4 */ + int nsp; + /* number of auction/shortest path iterations */ + /* working parameters ------------------------------------------*/ + int *label; /* int label, tempin, p[1+n]; */ + int *prdcsr; /* int prdcsr, tempou, price[1+n]; */ + int *save; /* int save[1+na]; */ + int *tfstou; /* int tfstou, fpushf[1+n]; */ + int *tnxtou; /* int tnxtou, nxtpushf[1+na]; */ + int *tfstin; /* int tfstin, fpushb[1+n]; */ + int *tnxtin; /* int tnxtin, nxtpushb[1+na]; */ + int *nxtqueue; /* int nxtqueue[1+n]; */ + char *scan; /* bool scan[1+n]; */ + char *mark; /* bool mark, path_id[1+n]; */ + /* working parameters used by routine auction only -------------*/ + int *extend_arc; /* int extend_arc[1+n]; */ + int *sb_level; /* int sb_level[1+n]; */ + int *sb_arc; /* int sb_arc[1+n]; */ +}; + +#define relax4 _glp_relax4 +int relax4(struct relax4_csa *csa); + +#define relax4_inidat _glp_relax4_inidat +void relax4_inidat(struct relax4_csa *csa); + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/rng.c b/resources/3rdparty/glpk-4.57/src/misc/rng.c new file mode 100644 index 000000000..e0acb53a2 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/rng.c @@ -0,0 +1,227 @@ +/* rng.c (pseudo-random number generator) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* This code is a modified version of the module GB_FLIP, a portable +* pseudo-random number generator. The original version of GB_FLIP is +* a part of The Stanford GraphBase developed by Donald E. Knuth (see +* http://www-cs-staff.stanford.edu/~knuth/sgb.html). +* +* Note that all changes concern only external names, so this modified +* version produces exactly the same results as the original version. +* +* Changes were made by Andrew Makhorin . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "rng.h" + +#if 0 +int A[56] = { -1 }; +#else +#define A (rand->A) +#endif +/* pseudo-random values */ + +#if 0 +int *fptr = A; +#else +#define fptr (rand->fptr) +#endif +/* the next A value to be exported */ + +#define mod_diff(x, y) (((x) - (y)) & 0x7FFFFFFF) +/* difference modulo 2^31 */ + +static int flip_cycle(RNG *rand) +{ /* this is an auxiliary routine to do 55 more steps of the basic + * recurrence, at high speed, and to reset fptr */ + int *ii, *jj; + for (ii = &A[1], jj = &A[32]; jj <= &A[55]; ii++, jj++) + *ii = mod_diff(*ii, *jj); + for (jj = &A[1]; ii <= &A[55]; ii++, jj++) + *ii = mod_diff(*ii, *jj); + fptr = &A[54]; + return A[55]; +} + +/*********************************************************************** +* NAME +* +* rng_create_rand - create pseudo-random number generator +* +* SYNOPSIS +* +* #include "rng.h" +* RNG *rng_create_rand(void); +* +* DESCRIPTION +* +* The routine rng_create_rand creates and initializes a pseudo-random +* number generator. +* +* RETURNS +* +* The routine returns a pointer to the generator created. */ + +RNG *rng_create_rand(void) +{ RNG *rand; + int i; + rand = talloc(1, RNG); + A[0] = -1; + for (i = 1; i <= 55; i++) A[i] = 0; + fptr = A; + rng_init_rand(rand, 1); + return rand; +} + +/*********************************************************************** +* NAME +* +* rng_init_rand - initialize pseudo-random number generator +* +* SYNOPSIS +* +* #include "rng.h" +* void rng_init_rand(RNG *rand, int seed); +* +* DESCRIPTION +* +* The routine rng_init_rand initializes the pseudo-random number +* generator. The parameter seed may be any integer number. Note that +* on creating the generator this routine is called with the parameter +* seed equal to 1. */ + +void rng_init_rand(RNG *rand, int seed) +{ int i; + int prev = seed, next = 1; + seed = prev = mod_diff(prev, 0); + A[55] = prev; + for (i = 21; i; i = (i + 21) % 55) + { A[i] = next; + next = mod_diff(prev, next); + if (seed & 1) + seed = 0x40000000 + (seed >> 1); + else + seed >>= 1; + next = mod_diff(next, seed); + prev = A[i]; + } + flip_cycle(rand); + flip_cycle(rand); + flip_cycle(rand); + flip_cycle(rand); + flip_cycle(rand); + return; +} + +/*********************************************************************** +* NAME +* +* rng_next_rand - obtain pseudo-random integer in the range [0, 2^31-1] +* +* SYNOPSIS +* +* #include "rng.h" +* int rng_next_rand(RNG *rand); +* +* RETURNS +* +* The routine rng_next_rand returns a next pseudo-random integer which +* is uniformly distributed between 0 and 2^31-1, inclusive. The period +* length of the generated numbers is 2^85 - 2^30. The low order bits of +* the generated numbers are just as random as the high-order bits. */ + +int rng_next_rand(RNG *rand) +{ return + *fptr >= 0 ? *fptr-- : flip_cycle(rand); +} + +/*********************************************************************** +* NAME +* +* rng_unif_rand - obtain pseudo-random integer in the range [0, m-1] +* +* SYNOPSIS +* +* #include "rng.h" +* int rng_unif_rand(RNG *rand, int m); +* +* RETURNS +* +* The routine rng_unif_rand returns a next pseudo-random integer which +* is uniformly distributed between 0 and m-1, inclusive, where m is any +* positive integer less than 2^31. */ + +#define two_to_the_31 ((unsigned int)0x80000000) + +int rng_unif_rand(RNG *rand, int m) +{ unsigned int t = two_to_the_31 - (two_to_the_31 % m); + int r; + xassert(m > 0); + do { r = rng_next_rand(rand); } while (t <= (unsigned int)r); + return r % m; +} + +/*********************************************************************** +* NAME +* +* rng_delete_rand - delete pseudo-random number generator +* +* SYNOPSIS +* +* #include "rng.h" +* void rng_delete_rand(RNG *rand); +* +* DESCRIPTION +* +* The routine rng_delete_rand frees all the memory allocated to the +* specified pseudo-random number generator. */ + +void rng_delete_rand(RNG *rand) +{ tfree(rand); + return; +} + +/**********************************************************************/ + +#ifdef GLP_TEST +/* To be sure that this modified version produces the same results as + * the original version, run this validation program. */ + +int main(void) +{ RNG *rand; + int j; + rand = rng_create_rand(); + rng_init_rand(rand, -314159); + if (rng_next_rand(rand) != 119318998) + { fprintf(stderr, "Failure on the first try!\n"); + return -1; + } + for (j = 1; j <= 133; j++) rng_next_rand(rand); + if (rng_unif_rand(rand, 0x55555555) != 748103812) + { fprintf(stderr, "Failure on the second try!\n"); + return -2; + } + fprintf(stderr, "OK, the random-number generator routines seem to" + " work!\n"); + rng_delete_rand(rand); + return 0; +} +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/rng.h b/resources/3rdparty/glpk-4.57/src/misc/rng.h new file mode 100644 index 000000000..49725e057 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/rng.h @@ -0,0 +1,67 @@ +/* rng.h (pseudo-random number generator) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2003-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef RNG_H +#define RNG_H + +typedef struct RNG RNG; + +struct RNG +{ /* Knuth's portable pseudo-random number generator */ + int A[56]; + /* pseudo-random values */ + int *fptr; + /* the next A value to be exported */ +}; + +#define rng_create_rand _glp_rng_create_rand +RNG *rng_create_rand(void); +/* create pseudo-random number generator */ + +#define rng_init_rand _glp_rng_init_rand +void rng_init_rand(RNG *rand, int seed); +/* initialize pseudo-random number generator */ + +#define rng_next_rand _glp_rng_next_rand +int rng_next_rand(RNG *rand); +/* obtain pseudo-random integer in the range [0, 2^31-1] */ + +#define rng_unif_rand _glp_rng_unif_rand +int rng_unif_rand(RNG *rand, int m); +/* obtain pseudo-random integer in the range [0, m-1] */ + +#define rng_delete_rand _glp_rng_delete_rand +void rng_delete_rand(RNG *rand); +/* delete pseudo-random number generator */ + +#define rng_unif_01 _glp_rng_unif_01 +double rng_unif_01(RNG *rand); +/* obtain pseudo-random number in the range [0, 1] */ + +#define rng_uniform _glp_rng_uniform +double rng_uniform(RNG *rand, double a, double b); +/* obtain pseudo-random number in the range [a, b] */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/rng1.c b/resources/3rdparty/glpk-4.57/src/misc/rng1.c new file mode 100644 index 000000000..b89f676f2 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/rng1.c @@ -0,0 +1,73 @@ +/* rng1.c (pseudo-random number generator) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2003-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "rng.h" + +/*********************************************************************** +* NAME +* +* rng_unif_01 - obtain pseudo-random number in the range [0, 1] +* +* SYNOPSIS +* +* #include "rng.h" +* double rng_unif_01(RNG *rand); +* +* RETURNS +* +* The routine rng_unif_01 returns a next pseudo-random number which is +* uniformly distributed in the range [0, 1]. */ + +double rng_unif_01(RNG *rand) +{ double x; + x = (double)rng_next_rand(rand) / 2147483647.0; + xassert(0.0 <= x && x <= 1.0); + return x; +} + +/*********************************************************************** +* NAME +* +* rng_uniform - obtain pseudo-random number in the range [a, b] +* +* SYNOPSIS +* +* #include "rng.h" +* double rng_uniform(RNG *rand, double a, double b); +* +* RETURNS +* +* The routine rng_uniform returns a next pseudo-random number which is +* uniformly distributed in the range [a, b]. */ + +double rng_uniform(RNG *rand, double a, double b) +{ double x; + xassert(a < b); + x = rng_unif_01(rand); + x = a * (1.0 - x) + b * x; + xassert(a <= x && x <= b); + return x; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/round2n.c b/resources/3rdparty/glpk-4.57/src/misc/round2n.c new file mode 100644 index 000000000..8a94c6162 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/round2n.c @@ -0,0 +1,64 @@ +/* round2n.c (round floating-point number to nearest power of two) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "misc.h" + +/*********************************************************************** +* NAME +* +* round2n - round floating-point number to nearest power of two +* +* SYNOPSIS +* +* #include "misc.h" +* double round2n(double x); +* +* RETURNS +* +* Given a positive floating-point value x the routine round2n returns +* 2^n such that |x - 2^n| is minimal. +* +* EXAMPLES +* +* round2n(10.1) = 2^3 = 8 +* round2n(15.3) = 2^4 = 16 +* round2n(0.01) = 2^(-7) = 0.0078125 +* +* BACKGROUND +* +* Let x = f * 2^e, where 0.5 <= f < 1 is a normalized fractional part, +* e is an integer exponent. Then, obviously, 0.5 * 2^e <= x < 2^e, so +* if x - 0.5 * 2^e <= 2^e - x, we choose 0.5 * 2^e = 2^(e-1), and 2^e +* otherwise. The latter condition can be written as 2 * x <= 1.5 * 2^e +* or 2 * f * 2^e <= 1.5 * 2^e or, finally, f <= 0.75. */ + +double round2n(double x) +{ int e; + double f; + xassert(x > 0.0); + f = frexp(x, &e); + return ldexp(1.0, f <= 0.75 ? e-1 : e); +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/str2int.c b/resources/3rdparty/glpk-4.57/src/misc/str2int.c new file mode 100644 index 000000000..cbd6e953f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/str2int.c @@ -0,0 +1,92 @@ +/* str2int.c (convert string to int) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "misc.h" +#include "stdc.h" + +/*********************************************************************** +* NAME +* +* str2int - convert character string to value of int type +* +* SYNOPSIS +* +* #include "misc.h" +* int str2int(const char *str, int *val); +* +* DESCRIPTION +* +* The routine str2int converts the character string str to a value of +* integer type and stores the value into location, which the parameter +* val points to (in the case of error content of this location is not +* changed). +* +* RETURNS +* +* The routine returns one of the following error codes: +* +* 0 - no error; +* 1 - value out of range; +* 2 - character string is syntactically incorrect. */ + +int str2int(const char *str, int *val_) +{ int d, k, s, val = 0; + /* scan optional sign */ + if (str[0] == '+') + s = +1, k = 1; + else if (str[0] == '-') + s = -1, k = 1; + else + s = +1, k = 0; + /* check for the first digit */ + if (!isdigit((unsigned char)str[k])) + return 2; + /* scan digits */ + while (isdigit((unsigned char)str[k])) + { d = str[k++] - '0'; + if (s > 0) + { if (val > INT_MAX / 10) + return 1; + val *= 10; + if (val > INT_MAX - d) + return 1; + val += d; + } + else /* s < 0 */ + { if (val < INT_MIN / 10) + return 1; + val *= 10; + if (val < INT_MIN + d) + return 1; + val -= d; + } + } + /* check for terminator */ + if (str[k] != '\0') + return 2; + /* conversion has been done */ + *val_ = val; + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/str2num.c b/resources/3rdparty/glpk-4.57/src/misc/str2num.c new file mode 100644 index 000000000..26c2f68f1 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/str2num.c @@ -0,0 +1,110 @@ +/* str2num.c (convert string to double) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "misc.h" +#include "stdc.h" + +/*********************************************************************** +* NAME +* +* str2num - convert character string to value of double type +* +* SYNOPSIS +* +* #include "misc.h" +* int str2num(const char *str, double *val); +* +* DESCRIPTION +* +* The routine str2num converts the character string str to a value of +* double type and stores the value into location, which the parameter +* val points to (in the case of error content of this location is not +* changed). +* +* RETURNS +* +* The routine returns one of the following error codes: +* +* 0 - no error; +* 1 - value out of range; +* 2 - character string is syntactically incorrect. */ + +int str2num(const char *str, double *val_) +{ int k; + double val; + /* scan optional sign */ + k = (str[0] == '+' || str[0] == '-' ? 1 : 0); + /* check for decimal point */ + if (str[k] == '.') + { k++; + /* a digit should follow it */ + if (!isdigit((unsigned char)str[k])) + return 2; + k++; + goto frac; + } + /* integer part should start with a digit */ + if (!isdigit((unsigned char)str[k])) + return 2; + /* scan integer part */ + while (isdigit((unsigned char)str[k])) + k++; + /* check for decimal point */ + if (str[k] == '.') k++; +frac: /* scan optional fraction part */ + while (isdigit((unsigned char)str[k])) + k++; + /* check for decimal exponent */ + if (str[k] == 'E' || str[k] == 'e') + { k++; + /* scan optional sign */ + if (str[k] == '+' || str[k] == '-') + k++; + /* a digit should follow E, E+ or E- */ + if (!isdigit((unsigned char)str[k])) + return 2; + } + /* scan optional exponent part */ + while (isdigit((unsigned char)str[k])) + k++; + /* check for terminator */ + if (str[k] != '\0') + return 2; + /* perform conversion */ + { char *endptr; + val = strtod(str, &endptr); + if (*endptr != '\0') + return 2; + } + /* check for overflow */ + if (!(-DBL_MAX <= val && val <= +DBL_MAX)) + return 1; + /* check for underflow */ + if (-DBL_MIN < val && val < +DBL_MIN) + val = 0.0; + /* conversion has been done */ + *val_ = val; + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/strspx.c b/resources/3rdparty/glpk-4.57/src/misc/strspx.c new file mode 100644 index 000000000..fe8a2a101 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/strspx.c @@ -0,0 +1,60 @@ +/* strspx.c (remove all spaces from string) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "misc.h" + +/*********************************************************************** +* NAME +* +* strspx - remove all spaces from character string +* +* SYNOPSIS +* +* #include "misc.h" +* char *strspx(char *str); +* +* DESCRIPTION +* +* The routine strspx removes all spaces from the character string str. +* +* RETURNS +* +* The routine returns a pointer to the character string. +* +* EXAMPLES +* +* strspx(" Errare humanum est ") => "Errarehumanumest" +* +* strspx(" ") => "" */ + +char *strspx(char *str) +{ char *s, *t; + for (s = t = str; *s; s++) + { if (*s != ' ') + *t++ = *s; + } + *t = '\0'; + return str; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/strtrim.c b/resources/3rdparty/glpk-4.57/src/misc/strtrim.c new file mode 100644 index 000000000..9992c4b0c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/strtrim.c @@ -0,0 +1,62 @@ +/* strtrim.c (remove trailing spaces from string) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "misc.h" +#include "stdc.h" + +/*********************************************************************** +* NAME +* +* strtrim - remove trailing spaces from character string +* +* SYNOPSIS +* +* #include "misc.h" +* char *strtrim(char *str); +* +* DESCRIPTION +* +* The routine strtrim removes trailing spaces from the character +* string str. +* +* RETURNS +* +* The routine returns a pointer to the character string. +* +* EXAMPLES +* +* strtrim("Errare humanum est ") => "Errare humanum est" +* +* strtrim(" ") => "" */ + +char *strtrim(char *str) +{ char *t; + for (t = strrchr(str, '\0') - 1; t >= str; t--) + { if (*t != ' ') + break; + *t = '\0'; + } + return str; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/triang.c b/resources/3rdparty/glpk-4.57/src/misc/triang.c new file mode 100644 index 000000000..99ba4d604 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/triang.c @@ -0,0 +1,311 @@ +/* triang.c (find maximal triangular part of rectangular matrix) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "triang.h" + +/*********************************************************************** +* triang - find maximal triangular part of rectangular matrix +* +* Given a mxn sparse matrix A this routine finds permutation matrices +* P and Q such that matrix A' = P * A * Q has the following structure: +* +* 1 s n +* 1 * . . . . . x x x x x +* * * . . . . x x x x x +* * * * . . . x x x x x +* * * * * . . x x x x x +* * * * * * . x x x x x +* s * * * * * * x x x x x +* x x x x x x x x x x x +* x x x x x x x x x x x +* m x x x x x x x x x x x +* +* where '*' are elements of the triangular part, '.' are structural +* zeros, 'x' are other elements. +* +* The formal routine mat specifies the original matrix A in both row- +* and column-wise format. If the routine mat is called with k = +i, +* 1 <= i <= m, it should store column indices and values of non-zero +* elements of i-th row of A in locations ind[1], ..., ind[len] and +* val[1], ..., val[len], resp., where len is the returned number of +* non-zeros in the row, 0 <= len <= n. Similarly, if the routine mat +* is called with k = -j, 1 <= j <= n, it should store row indices and +* values of non-zero elements of j-th column of A and return len, the +* number of non-zeros in the column, 0 <= len <= m. Should note that +* duplicate indices are not allowed. +* +* The parameter info is a transit pointer passed to the routine mat. +* +* The parameter tol is a tolerance. The routine triang guarantees that +* each diagonal element in the triangular part of matrix A' is not +* less in magnitude than tol * max, where max is the maximal magnitude +* of elements in corresponding column. +* +* On exit the routine triang stores information on the triangular part +* found in the arrays rn and cn. Elements rn[1], ..., rn[s] specify +* row numbers and elements cn[1], ..., cn[s] specify column numbers +* of the original matrix A, which correspond to rows/columns 1, ..., s +* of matrix A', where s is the size of the triangular part returned by +* the routine, 0 <= s <= min(m, n). The order of rows and columns that +* are not included in the triangular part remains unspecified. +* +* ALGORITHM +* +* The routine triang uses a simple greedy heuristic. +* +* At some step the matrix A' = P * A * Q has the following structure: +* +* 1 n +* 1 * . . . . . . . x x x +* * * . . . . . . x x x +* * * * . . . . . x x x +* * * * * . . . . x x x +* x x x x # # # # x x x +* x x x x # # # # x x x +* x x x x # # # # x x x +* x x x x # # # # x x x +* m x x x x # # # # x x x +* +* where '#' are elements of active submatrix. Initially P = Q = I, so +* the active submatrix is the original matrix A = A'. +* +* If some row has exactly one non-zero in the active submatrix (row +* singleton), the routine includes this row and corresponding column +* in the triangular part, and removes the column from the active +* submatrix. Otherwise, the routine simply removes a column having +* maximal number of non-zeros from the active submatrix in the hope +* that new row singleton(s) will appear. +* +* COMPLEXITY +* +* The time complexity of the routine triang is O(nnz), where nnz is +* number of non-zeros in the original matrix A. */ + +int triang(int m, int n, int (*mat)(void *info, int k, int ind[], + double val[]), void *info, double tol, int rn[], int cn[]) +{ int head, i, j, jj, k, kk, ks, len, len2, next_j, ns, size; + int *cind, *rind, *cnt, *ptr, *list, *prev, *next; + double *cval, *rval, *big; + char *flag; + /* allocate working arrays */ + cind = talloc(1+m, int); + cval = talloc(1+m, double); + rind = talloc(1+n, int); + rval = talloc(1+n, double); + cnt = ptr = talloc(1+m, int); + list = talloc(1+n, int); + prev = talloc(1+n, int); + next = talloc(1+n, int); + big = talloc(1+n, double); + flag = talloc(1+n, char); + /*--------------------------------------------------------------*/ + /* build linked lists of columns having equal lengths */ + /*--------------------------------------------------------------*/ + /* ptr[len], 0 <= len <= m, is number of first column of length + * len; + * next[j], 1 <= j <= n, is number of next column having the same + * length as column j; + * big[j], 1 <= j <= n, is maximal magnitude of elements in j-th + * column */ + for (len = 0; len <= m; len++) + ptr[len] = 0; + for (j = 1; j <= n; j++) + { /* get j-th column */ + len = mat(info, -j, cind, cval); + xassert(0 <= len && len <= m); + /* add this column to beginning of list ptr[len] */ + next[j] = ptr[len]; + ptr[len] = j; + /* determine maximal magnitude of elements in this column */ + big[j] = 0.0; + for (k = 1; k <= len; k++) + { if (big[j] < fabs(cval[k])) + big[j] = fabs(cval[k]); + } + } + /*--------------------------------------------------------------*/ + /* build doubly linked list of columns ordered by decreasing */ + /* column lengths */ + /*--------------------------------------------------------------*/ + /* head is number of first column in the list; + * prev[j], 1 <= j <= n, is number of column that precedes j-th + * column in the list; + * next[j], 1 <= j <= n, is number of column that follows j-th + * column in the list */ + head = 0; + for (len = 0; len <= m; len++) + { /* walk thru list of columns of length len */ + for (j = ptr[len]; j != 0; j = next_j) + { next_j = next[j]; + /* add j-th column to beginning of the column list */ + prev[j] = 0; + next[j] = head; + if (head != 0) + prev[head] = j; + head = j; + } + } + /*--------------------------------------------------------------*/ + /* build initial singleton list */ + /*--------------------------------------------------------------*/ + /* there are used two list of columns: + * 1) doubly linked list of active columns, in which all columns + * are ordered by decreasing column lengths; + * 2) singleton list; an active column is included in this list + * if it has at least one row singleton in active submatrix */ + /* flag[j], 1 <= j <= n, is a flag of j-th column: + * 0 j-th column is inactive; + * 1 j-th column is active; + * 2 j-th column is active and has row singleton(s) */ + /* initially all columns are active */ + for (j = 1; j <= n; j++) + flag[j] = 1; + /* initialize row counts and build initial singleton list */ + /* cnt[i], 1 <= i <= m, is number of non-zeros, which i-th row + * has in active submatrix; + * ns is size of singleton list; + * list[1], ..., list[ns] are numbers of active columns included + * in the singleton list */ + ns = 0; + for (i = 1; i <= m; i++) + { /* get i-th row */ + len = cnt[i] = mat(info, +i, rind, rval); + xassert(0 <= len && len <= n); + if (len == 1) + { /* a[i,j] is row singleton */ + j = rind[1]; + xassert(1 <= j && j <= n); + if (flag[j] != 2) + { /* include j-th column in singleton list */ + flag[j] = 2; + list[++ns] = j; + } + } + } + /*--------------------------------------------------------------*/ + /* main loop */ + /*--------------------------------------------------------------*/ + size = 0; /* size of triangular part */ + /* loop until active column list is non-empty, i.e. until the + * active submatrix has at least one column */ + while (head != 0) + { if (ns == 0) + { /* singleton list is empty */ + /* remove from the active submatrix a column of maximal + * length in the hope that some row singletons appear */ + j = head; + len = mat(info, -j, cind, cval); + xassert(0 <= len && len <= m); + goto drop; + } + /* take column j from the singleton list */ + j = list[ns--]; + xassert(flag[j] == 2); + /* j-th column has at least one row singleton in the active + * submatrix; choose one having maximal magnitude */ + len = mat(info, -j, cind, cval); + xassert(0 <= len && len <= m); + kk = 0; + for (k = 1; k <= len; k++) + { i = cind[k]; + xassert(1 <= i && i <= m); + if (cnt[i] == 1) + { /* a[i,j] is row singleton */ + if (kk == 0 || fabs(cval[kk]) < fabs(cval[k])) + kk = k; + } + } + xassert(kk > 0); + /* check magnitude of the row singleton chosen */ + if (fabs(cval[kk]) < tol * big[j]) + { /* all row singletons are too small in magnitude; drop j-th + * column */ + goto drop; + } + /* row singleton a[i,j] is ok; add i-th row and j-th column to + * the triangular part */ + size++; + rn[size] = cind[kk]; + cn[size] = j; +drop: /* remove j-th column from the active submatrix */ + xassert(flag[j]); + flag[j] = 0; + if (prev[j] == 0) + head = next[j]; + else + next[prev[j]] = next[j]; + if (next[j] == 0) + ; + else + prev[next[j]] = prev[j]; + /* decrease row counts */ + for (k = 1; k <= len; k++) + { i = cind[k]; + xassert(1 <= i && i <= m); + xassert(cnt[i] > 0); + cnt[i]--; + if (cnt[i] == 1) + { /* new singleton appeared in i-th row; determine number + * of corresponding column (it is the only active column + * in this row) */ + len2 = mat(info, +i, rind, rval); + xassert(0 <= len2 && len2 <= n); + ks = 0; + for (kk = 1; kk <= len2; kk++) + { jj = rind[kk]; + xassert(1 <= jj && jj <= n); + if (flag[jj]) + { xassert(ks == 0); + ks = kk; + } + } + xassert(ks > 0); + /* a[i,jj] is new row singleton */ + jj = rind[ks]; + if (flag[jj] != 2) + { /* include jj-th column in the singleton list */ + flag[jj] = 2; + list[++ns] = jj; + } + } + } + } + /* now all row counts should be zero */ + for (i = 1; i <= m; i++) + xassert(cnt[i] == 0); + /* deallocate working arrays */ + tfree(cind); + tfree(cval); + tfree(rind); + tfree(rval); + tfree(ptr); + tfree(list); + tfree(prev); + tfree(next); + tfree(big); + tfree(flag); + return size; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/triang.h b/resources/3rdparty/glpk-4.57/src/misc/triang.h new file mode 100644 index 000000000..1e50d44dc --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/triang.h @@ -0,0 +1,34 @@ +/* triang.h (find maximal triangular part of rectangular matrix) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef TRIANG_H +#define TRIANG_H + +#define triang _glp_triang +int triang(int m, int n, int (*mat)(void *info, int k, int ind[], + double val[]), void *info, double tol, int rn[], int cn[]); +/* find maximal triangular part of rectangular matrix */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/wclique.c b/resources/3rdparty/glpk-4.57/src/misc/wclique.c new file mode 100644 index 000000000..5daa69cff --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/wclique.c @@ -0,0 +1,242 @@ +/* wclique.c (maximum weight clique, Ostergard's algorithm) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Two subroutines sub() and wclique() below are intended to find a +* maximum weight clique in a given undirected graph. These subroutines +* are slightly modified version of the program WCLIQUE developed by +* Patric Ostergard and based +* on ideas from the article "P. R. J. Ostergard, A new algorithm for +* the maximum-weight clique problem, submitted for publication", which +* in turn is a generalization of the algorithm for unweighted graphs +* presented in "P. R. J. Ostergard, A fast algorithm for the maximum +* clique problem, submitted for publication". +* +* USED WITH PERMISSION OF THE AUTHOR OF THE ORIGINAL CODE. +* +* Changes were made by Andrew Makhorin . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "wclique.h" + +/*********************************************************************** +* NAME +* +* wclique - find maximum weight clique with Ostergard's algorithm +* +* SYNOPSIS +* +* #include "wclique.h" +* int wclique(int n, const int w[], const unsigned char a[], +* int ind[]); +* +* DESCRIPTION +* +* The routine wclique finds a maximum weight clique in an undirected +* graph with Ostergard's algorithm. +* +* INPUT PARAMETERS +* +* n is the number of vertices, n > 0. +* +* w[i], i = 1,...,n, is a weight of vertex i. +* +* a[*] is the strict (without main diagonal) lower triangle of the +* graph adjacency matrix in packed format. +* +* OUTPUT PARAMETER +* +* ind[k], k = 1,...,size, is the number of a vertex included in the +* clique found, 1 <= ind[k] <= n, where size is the number of vertices +* in the clique returned on exit. +* +* RETURNS +* +* The routine returns the clique size, i.e. the number of vertices in +* the clique. */ + +struct csa +{ /* common storage area */ + int n; + /* number of vertices */ + const int *wt; /* int wt[0:n-1]; */ + /* weights */ + const unsigned char *a; + /* adjacency matrix (packed lower triangle without main diag.) */ + int record; + /* weight of best clique */ + int rec_level; + /* number of vertices in best clique */ + int *rec; /* int rec[0:n-1]; */ + /* best clique so far */ + int *clique; /* int clique[0:n-1]; */ + /* table for pruning */ + int *set; /* int set[0:n-1]; */ + /* current clique */ +}; + +#define n (csa->n) +#define wt (csa->wt) +#define a (csa->a) +#define record (csa->record) +#define rec_level (csa->rec_level) +#define rec (csa->rec) +#define clique (csa->clique) +#define set (csa->set) + +#if 0 +static int is_edge(struct csa *csa, int i, int j) +{ /* if there is arc (i,j), the routine returns true; otherwise + * false; 0 <= i, j < n */ + int k; + xassert(0 <= i && i < n); + xassert(0 <= j && j < n); + if (i == j) return 0; + if (i < j) k = i, i = j, j = k; + k = (i * (i - 1)) / 2 + j; + return a[k / CHAR_BIT] & + (unsigned char)(1 << ((CHAR_BIT - 1) - k % CHAR_BIT)); +} +#else +#define is_edge(csa, i, j) ((i) == (j) ? 0 : \ + (i) > (j) ? is_edge1(i, j) : is_edge1(j, i)) +#define is_edge1(i, j) is_edge2(((i) * ((i) - 1)) / 2 + (j)) +#define is_edge2(k) (a[(k) / CHAR_BIT] & \ + (unsigned char)(1 << ((CHAR_BIT - 1) - (k) % CHAR_BIT))) +#endif + +static void sub(struct csa *csa, int ct, int table[], int level, + int weight, int l_weight) +{ int i, j, k, curr_weight, left_weight, *p1, *p2, *newtable; + newtable = xcalloc(n, sizeof(int)); + if (ct <= 0) + { /* 0 or 1 elements left; include these */ + if (ct == 0) + { set[level++] = table[0]; + weight += l_weight; + } + if (weight > record) + { record = weight; + rec_level = level; + for (i = 0; i < level; i++) rec[i] = set[i]; + } + goto done; + } + for (i = ct; i >= 0; i--) + { if ((level == 0) && (i < ct)) goto done; + k = table[i]; + if ((level > 0) && (clique[k] <= (record - weight))) + goto done; /* prune */ + set[level] = k; + curr_weight = weight + wt[k]; + l_weight -= wt[k]; + if (l_weight <= (record - curr_weight)) + goto done; /* prune */ + p1 = newtable; + p2 = table; + left_weight = 0; + while (p2 < table + i) + { j = *p2++; + if (is_edge(csa, j, k)) + { *p1++ = j; + left_weight += wt[j]; + } + } + if (left_weight <= (record - curr_weight)) continue; + sub(csa, p1 - newtable - 1, newtable, level + 1, curr_weight, + left_weight); + } +done: xfree(newtable); + return; +} + +int wclique(int n_, const int w[], const unsigned char a_[], int ind[]) +{ struct csa csa_, *csa = &csa_; + int i, j, p, max_wt, max_nwt, wth, *used, *nwt, *pos; + double timer; + n = n_; + xassert(n > 0); + wt = &w[1]; + a = a_; + record = 0; + rec_level = 0; + rec = &ind[1]; + clique = xcalloc(n, sizeof(int)); + set = xcalloc(n, sizeof(int)); + used = xcalloc(n, sizeof(int)); + nwt = xcalloc(n, sizeof(int)); + pos = xcalloc(n, sizeof(int)); + /* start timer */ + timer = xtime(); + /* order vertices */ + for (i = 0; i < n; i++) + { nwt[i] = 0; + for (j = 0; j < n; j++) + if (is_edge(csa, i, j)) nwt[i] += wt[j]; + } + for (i = 0; i < n; i++) + used[i] = 0; + for (i = n-1; i >= 0; i--) + { max_wt = -1; + max_nwt = -1; + for (j = 0; j < n; j++) + { if ((!used[j]) && ((wt[j] > max_wt) || (wt[j] == max_wt + && nwt[j] > max_nwt))) + { max_wt = wt[j]; + max_nwt = nwt[j]; + p = j; + } + } + pos[i] = p; + used[p] = 1; + for (j = 0; j < n; j++) + if ((!used[j]) && (j != p) && (is_edge(csa, p, j))) + nwt[j] -= wt[p]; + } + /* main routine */ + wth = 0; + for (i = 0; i < n; i++) + { wth += wt[pos[i]]; + sub(csa, i, pos, 0, 0, wth); + clique[pos[i]] = record; + if (xdifftime(xtime(), timer) >= 5.0 - 0.001) + { /* print current record and reset timer */ + xprintf("level = %d (%d); best = %d\n", i+1, n, record); + timer = xtime(); + } + } + xfree(clique); + xfree(set); + xfree(used); + xfree(nwt); + xfree(pos); + /* return the solution found */ + for (i = 1; i <= rec_level; i++) ind[i]++; + return rec_level; +} + +#undef n +#undef wt +#undef a +#undef record +#undef rec_level +#undef rec +#undef clique +#undef set + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/wclique.h b/resources/3rdparty/glpk-4.57/src/misc/wclique.h new file mode 100644 index 000000000..d52dc8052 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/wclique.h @@ -0,0 +1,33 @@ +/* wclique.h (maximum weight clique, Ostergard's algorithm) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2009-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef WCLIQUE_H +#define WCLIQUE_H + +#define wclique _glp_wclique +int wclique(int n, const int w[], const unsigned char a[], int ind[]); +/* find maximum weight clique with Ostergard's algorithm */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/wclique1.c b/resources/3rdparty/glpk-4.57/src/misc/wclique1.c new file mode 100644 index 000000000..c263a5e5a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/wclique1.c @@ -0,0 +1,317 @@ +/* wclique1.c (maximum weight clique, greedy heuristic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "wclique1.h" + +/*********************************************************************** +* NAME +* +* wclique1 - find maximum weight clique with greedy heuristic +* +* SYNOPSIS +* +* #include "wclique1.h" +* int wclique1(int n, const double w[], +* int (*func)(void *info, int i, int ind[]), void *info, int c[]); +* +* DESCRIPTION +* +* The routine wclique1 implements a sequential greedy heuristic to +* find maximum weight clique in a given (undirected) graph G = (V, E). +* +* The parameter n specifies the number of vertices |V| in the graph, +* n >= 0. +* +* The array w specifies vertex weights in locations w[i], i = 1,...,n. +* All weights must be non-negative. +* +* The formal routine func specifies the graph. For a given vertex i, +* 1 <= i <= n, it stores indices of all vertices adjacent to vertex i +* in locations ind[1], ..., ind[deg], where deg is the degree of +* vertex i, 0 <= deg < n, returned on exit. Note that self-loops and +* multiple edges are not allowed. +* +* The parameter info is a cookie passed to the routine func. +* +* On exit the routine wclique1 stores vertex indices included in +* the clique found to locations c[1], ..., c[size], where size is the +* clique size returned by the routine, 0 <= size <= n. +* +* RETURNS +* +* The routine wclique1 returns the size of the clique found. */ + +struct vertex { int i; double cw; }; + +static int fcmp(const void *xx, const void *yy) +{ const struct vertex *x = xx, *y = yy; + if (x->cw > y->cw) return -1; + if (x->cw < y->cw) return +1; + return 0; +} + +int wclique1(int n, const double w[], + int (*func)(void *info, int i, int ind[]), void *info, int c[]) +{ struct vertex *v_list; + int deg, c_size, d_size, i, j, k, kk, l, *ind, *c_list, *d_list, + size = 0; + double c_wght, d_wght, *sw, best = 0.0; + char *d_flag, *skip; + /* perform sanity checks */ + xassert(n >= 0); + for (i = 1; i <= n; i++) + xassert(w[i] >= 0.0); + /* if the graph is empty, nothing to do */ + if (n == 0) goto done; + /* allocate working arrays */ + ind = xcalloc(1+n, sizeof(int)); + v_list = xcalloc(1+n, sizeof(struct vertex)); + c_list = xcalloc(1+n, sizeof(int)); + d_list = xcalloc(1+n, sizeof(int)); + d_flag = xcalloc(1+n, sizeof(char)); + skip = xcalloc(1+n, sizeof(char)); + sw = xcalloc(1+n, sizeof(double)); + /* build the vertex list */ + for (i = 1; i <= n; i++) + { v_list[i].i = i; + /* compute the cumulative weight of each vertex i, which is + * cw[i] = w[i] + sum{j : (i,j) in E} w[j] */ + v_list[i].cw = w[i]; + deg = func(info, i, ind); + xassert(0 <= deg && deg < n); + for (k = 1; k <= deg; k++) + { j = ind[k]; + xassert(1 <= j && j <= n && j != i); + v_list[i].cw += w[j]; + } + } + /* sort the vertex list to access vertices in descending order of + * cumulative weights */ + qsort(&v_list[1], n, sizeof(struct vertex), fcmp); + /* initially all vertices are unmarked */ + memset(&skip[1], 0, sizeof(char) * n); + /* clear flags of all vertices */ + memset(&d_flag[1], 0, sizeof(char) * n); + /* look through all vertices of the graph */ + for (l = 1; l <= n; l++) + { /* take vertex i */ + i = v_list[l].i; + /* if this vertex was already included in one of previosuly + * constructed cliques, skip it */ + if (skip[i]) continue; + /* use vertex i as the initial clique vertex */ + c_size = 1; /* size of current clique */ + c_list[1] = i; /* list of vertices in current clique */ + c_wght = w[i]; /* weight of current clique */ + /* determine the candidate set D = { j : (i,j) in E } */ + d_size = func(info, i, d_list); + xassert(0 <= d_size && d_size < n); + d_wght = 0.0; /* weight of set D */ + for (k = 1; k <= d_size; k++) + { j = d_list[k]; + xassert(1 <= j && j <= n && j != i); + xassert(!d_flag[j]); + d_flag[j] = 1; + d_wght += w[j]; + } + /* check an upper bound to the final clique weight */ + if (c_wght + d_wght < best + 1e-5 * (1.0 + fabs(best))) + { /* skip constructing the current clique */ + goto next; + } + /* compute the summary weight of each vertex i in D, which is + * sw[i] = w[i] + sum{j in D and (i,j) in E} w[j] */ + for (k = 1; k <= d_size; k++) + { i = d_list[k]; + sw[i] = w[i]; + /* consider vertices adjacent to vertex i */ + deg = func(info, i, ind); + xassert(0 <= deg && deg < n); + for (kk = 1; kk <= deg; kk++) + { j = ind[kk]; + xassert(1 <= j && j <= n && j != i); + if (d_flag[j]) sw[i] += w[j]; + } + } + /* grow the current clique by adding vertices from D */ + while (d_size > 0) + { /* check an upper bound to the final clique weight */ + if (c_wght + d_wght < best + 1e-5 * (1.0 + fabs(best))) + { /* skip constructing the current clique */ + goto next; + } + /* choose vertex i in D having maximal summary weight */ + i = d_list[1]; + for (k = 2; k <= d_size; k++) + { j = d_list[k]; + if (sw[i] < sw[j]) i = j; + } + /* include vertex i in the current clique */ + c_size++; + c_list[c_size] = i; + c_wght += w[i]; + /* remove all vertices not adjacent to vertex i, including + * vertex i itself, from the candidate set D */ + deg = func(info, i, ind); + xassert(0 <= deg && deg < n); + for (k = 1; k <= deg; k++) + { j = ind[k]; + xassert(1 <= j && j <= n && j != i); + /* vertex j is adjacent to vertex i */ + if (d_flag[j]) + { xassert(d_flag[j] == 1); + /* mark vertex j to keep it in D */ + d_flag[j] = 2; + } + } + kk = d_size, d_size = 0; + for (k = 1; k <= kk; k++) + { j = d_list[k]; + if (d_flag[j] == 1) + { /* remove vertex j from D */ + d_flag[j] = 0; + d_wght -= w[j]; + } + else if (d_flag[j] == 2) + { /* keep vertex j in D */ + d_list[++d_size] = j; + d_flag[j] = 1; + } + else + xassert(d_flag != d_flag); + } + } + /* the current clique has been completely constructed */ + if (best < c_wght) + { best = c_wght; + size = c_size; + xassert(1 <= size && size <= n); + memcpy(&c[1], &c_list[1], size * sizeof(int)); + } +next: /* mark the current clique vertices in order not to use them + * as initial vertices anymore */ + for (k = 1; k <= c_size; k++) + skip[c_list[k]] = 1; + /* set D can be non-empty, so clean up vertex flags */ + for (k = 1; k <= d_size; k++) + d_flag[d_list[k]] = 0; + } + /* free working arrays */ + xfree(ind); + xfree(v_list); + xfree(c_list); + xfree(d_list); + xfree(d_flag); + xfree(skip); + xfree(sw); +done: /* return to the calling program */ + return size; +} + +/**********************************************************************/ + +#ifdef GLP_TEST +#include "glpk.h" +#include "rng.h" + +typedef struct { double w; } v_data; + +#define weight(v) (((v_data *)((v)->data))->w) + +glp_graph *G; + +char *flag; + +int func(void *info, int i, int ind[]) +{ glp_arc *e; + int j, k, deg = 0; + xassert(info == NULL); + xassert(1 <= i && i <= G->nv); + /* look through incoming arcs */ + for (e = G->v[i]->in; e != NULL; e = e->h_next) + { j = e->tail->i; /* j->i */ + if (j != i && !flag[j]) ind[++deg] = j, flag[j] = 1; + } + /* look through outgoing arcs */ + for (e = G->v[i]->out; e != NULL; e = e->t_next) + { j = e->head->i; /* i->j */ + if (j != i && !flag[j]) ind[++deg] = j, flag[j] = 1; + } + /* clear the flag array */ + xassert(deg < G->nv); + for (k = 1; k <= deg; k++) flag[ind[k]] = 0; + return deg; +} + +int main(int argc, char *argv[]) +{ RNG *rand; + int i, k, kk, size, *c, *ind, deg; + double *w, sum, t; + /* read graph in DIMACS format */ + G = glp_create_graph(sizeof(v_data), 0); + xassert(argc == 2); + xassert(glp_read_ccdata(G, offsetof(v_data, w), argv[1]) == 0); + /* print the number of connected components */ + xprintf("nc = %d\n", glp_weak_comp(G, -1)); + /* assign random weights unformly distributed in [1,100] */ + w = xcalloc(1+G->nv, sizeof(double)); + rand = rng_create_rand(); + for (i = 1; i <= G->nv; i++) +#if 0 + w[i] = weight(G->v[i]) = 1.0; +#else + w[i] = weight(G->v[i]) = rng_unif_rand(rand, 100) + 1; +#endif + /* write graph in DIMACS format */ + xassert(glp_write_ccdata(G, offsetof(v_data, w), "graph") == 0); + /* find maximum weight clique */ + c = xcalloc(1+G->nv, sizeof(int)); + flag = xcalloc(1+G->nv, sizeof(char)); + memset(&flag[1], 0, G->nv); + t = xtime(); + size = wclique1(G->nv, w, func, NULL, c); + xprintf("Time used: %.1f s\n", xdifftime(xtime(), t)); + /* check the clique found */ + ind = xcalloc(1+G->nv, sizeof(int)); + for (k = 1; k <= size; k++) + { i = c[k]; + deg = func(NULL, i, ind); + for (kk = 1; kk <= size; kk++) + flag[c[kk]] = 1; + flag[i] = 0; + for (kk = 1; kk <= deg; kk++) + flag[ind[kk]] = 0; + for (kk = 1; kk <= size; kk++) + xassert(flag[c[kk]] == 0); + } + /* compute the clique weight */ + sum = 0.0; + for (i = 1; i <= size; i++) + sum += w[c[i]]; + xprintf("size = %d; sum = %g\n", size, sum); + return 0; +} +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/misc/wclique1.h b/resources/3rdparty/glpk-4.57/src/misc/wclique1.h new file mode 100644 index 000000000..588f32571 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/misc/wclique1.h @@ -0,0 +1,34 @@ +/* wclique1.h (maximum weight clique, greedy heuristic) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2012-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef WCLIQUE1_H +#define WCLIQUE1_H + +#define wclique1 _glp_wclique1 +int wclique1(int n, const double w[], + int (*func)(void *info, int i, int ind[]), void *info, int c[]); +/* find maximum weight clique with greedy heuristic */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/prob.h b/resources/3rdparty/glpk-4.57/src/prob.h new file mode 100644 index 000000000..69dea0eb8 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/prob.h @@ -0,0 +1,280 @@ +/* prob.h (LP/MIP problem object) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef PROB_H +#define PROB_H + +#include "avl.h" +#include "bfd.h" +#include "dmp.h" +#include "glpk.h" + +typedef struct GLPROW GLPROW; +typedef struct GLPCOL GLPCOL; +typedef struct GLPAIJ GLPAIJ; + +#define GLP_PROB_MAGIC 0xD7D9D6C2 + +struct glp_prob +{ /* LP/MIP problem object */ + unsigned magic; + /* magic value used for debugging */ + DMP *pool; + /* memory pool to store problem object components */ + glp_tree *tree; + /* pointer to the search tree; set by the MIP solver when this + object is used in the tree as a core MIP object */ +#if 0 /* 08/III-2014 */ + void *parms; + /* reserved for backward compatibility */ +#endif + /*--------------------------------------------------------------*/ + /* LP/MIP data */ + char *name; + /* problem name (1 to 255 chars); NULL means no name is assigned + to the problem */ + char *obj; + /* objective function name (1 to 255 chars); NULL means no name + is assigned to the objective function */ + int dir; + /* optimization direction flag (objective "sense"): + GLP_MIN - minimization + GLP_MAX - maximization */ + double c0; + /* constant term of the objective function ("shift") */ + int m_max; + /* length of the array of rows (enlarged automatically) */ + int n_max; + /* length of the array of columns (enlarged automatically) */ + int m; + /* number of rows, 0 <= m <= m_max */ + int n; + /* number of columns, 0 <= n <= n_max */ + int nnz; + /* number of non-zero constraint coefficients, nnz >= 0 */ + GLPROW **row; /* GLPROW *row[1+m_max]; */ + /* row[i], 1 <= i <= m, is a pointer to i-th row */ + GLPCOL **col; /* GLPCOL *col[1+n_max]; */ + /* col[j], 1 <= j <= n, is a pointer to j-th column */ + AVL *r_tree; + /* row index to find rows by their names; NULL means this index + does not exist */ + AVL *c_tree; + /* column index to find columns by their names; NULL means this + index does not exist */ + /*--------------------------------------------------------------*/ + /* basis factorization (LP) */ + int valid; + /* the factorization is valid only if this flag is set */ + int *head; /* int head[1+m_max]; */ + /* basis header (valid only if the factorization is valid); + head[i] = k is the ordinal number of auxiliary (1 <= k <= m) + or structural (m+1 <= k <= m+n) variable which corresponds to + i-th basic variable xB[i], 1 <= i <= m */ +#if 0 /* 08/III-2014 */ + glp_bfcp *bfcp; + /* basis factorization control parameters; may be NULL */ +#endif + BFD *bfd; /* BFD bfd[1:m,1:m]; */ + /* basis factorization driver; may be NULL */ + /*--------------------------------------------------------------*/ + /* basic solution (LP) */ + int pbs_stat; + /* primal basic solution status: + GLP_UNDEF - primal solution is undefined + GLP_FEAS - primal solution is feasible + GLP_INFEAS - primal solution is infeasible + GLP_NOFEAS - no primal feasible solution exists */ + int dbs_stat; + /* dual basic solution status: + GLP_UNDEF - dual solution is undefined + GLP_FEAS - dual solution is feasible + GLP_INFEAS - dual solution is infeasible + GLP_NOFEAS - no dual feasible solution exists */ + double obj_val; + /* objective function value */ + int it_cnt; + /* simplex method iteration count; increases by one on performing + one simplex iteration */ + int some; + /* ordinal number of some auxiliary or structural variable having + certain property, 0 <= some <= m+n */ + /*--------------------------------------------------------------*/ + /* interior-point solution (LP) */ + int ipt_stat; + /* interior-point solution status: + GLP_UNDEF - interior solution is undefined + GLP_OPT - interior solution is optimal + GLP_INFEAS - interior solution is infeasible + GLP_NOFEAS - no feasible solution exists */ + double ipt_obj; + /* objective function value */ + /*--------------------------------------------------------------*/ + /* integer solution (MIP) */ + int mip_stat; + /* integer solution status: + GLP_UNDEF - integer solution is undefined + GLP_OPT - integer solution is optimal + GLP_FEAS - integer solution is feasible + GLP_NOFEAS - no integer solution exists */ + double mip_obj; + /* objective function value */ +}; + +struct GLPROW +{ /* LP/MIP row (auxiliary variable) */ + int i; + /* ordinal number (1 to m) assigned to this row */ + char *name; + /* row name (1 to 255 chars); NULL means no name is assigned to + this row */ + AVLNODE *node; + /* pointer to corresponding node in the row index; NULL means + that either the row index does not exist or this row has no + name assigned */ +#if 1 /* 20/IX-2008 */ + int level; + unsigned char origin; + unsigned char klass; +#endif + int type; + /* type of the auxiliary variable: + GLP_FR - free variable + GLP_LO - variable with lower bound + GLP_UP - variable with upper bound + GLP_DB - double-bounded variable + GLP_FX - fixed variable */ + double lb; /* non-scaled */ + /* lower bound; if the row has no lower bound, lb is zero */ + double ub; /* non-scaled */ + /* upper bound; if the row has no upper bound, ub is zero */ + /* if the row type is GLP_FX, ub is equal to lb */ + GLPAIJ *ptr; /* non-scaled */ + /* pointer to doubly linked list of constraint coefficients which + are placed in this row */ + double rii; + /* diagonal element r[i,i] of scaling matrix R for this row; + if the scaling is not used, r[i,i] is 1 */ + int stat; + /* status of the auxiliary variable: + GLP_BS - basic variable + GLP_NL - non-basic variable on lower bound + GLP_NU - non-basic variable on upper bound + GLP_NF - non-basic free variable + GLP_NS - non-basic fixed variable */ + int bind; + /* if the auxiliary variable is basic, head[bind] refers to this + row, otherwise, bind is 0; this attribute is valid only if the + basis factorization is valid */ + double prim; /* non-scaled */ + /* primal value of the auxiliary variable in basic solution */ + double dual; /* non-scaled */ + /* dual value of the auxiliary variable in basic solution */ + double pval; /* non-scaled */ + /* primal value of the auxiliary variable in interior solution */ + double dval; /* non-scaled */ + /* dual value of the auxiliary variable in interior solution */ + double mipx; /* non-scaled */ + /* primal value of the auxiliary variable in integer solution */ +}; + +struct GLPCOL +{ /* LP/MIP column (structural variable) */ + int j; + /* ordinal number (1 to n) assigned to this column */ + char *name; + /* column name (1 to 255 chars); NULL means no name is assigned + to this column */ + AVLNODE *node; + /* pointer to corresponding node in the column index; NULL means + that either the column index does not exist or the column has + no name assigned */ + int kind; + /* kind of the structural variable: + GLP_CV - continuous variable + GLP_IV - integer or binary variable */ + int type; + /* type of the structural variable: + GLP_FR - free variable + GLP_LO - variable with lower bound + GLP_UP - variable with upper bound + GLP_DB - double-bounded variable + GLP_FX - fixed variable */ + double lb; /* non-scaled */ + /* lower bound; if the column has no lower bound, lb is zero */ + double ub; /* non-scaled */ + /* upper bound; if the column has no upper bound, ub is zero */ + /* if the column type is GLP_FX, ub is equal to lb */ + double coef; /* non-scaled */ + /* objective coefficient at the structural variable */ + GLPAIJ *ptr; /* non-scaled */ + /* pointer to doubly linked list of constraint coefficients which + are placed in this column */ + double sjj; + /* diagonal element s[j,j] of scaling matrix S for this column; + if the scaling is not used, s[j,j] is 1 */ + int stat; + /* status of the structural variable: + GLP_BS - basic variable + GLP_NL - non-basic variable on lower bound + GLP_NU - non-basic variable on upper bound + GLP_NF - non-basic free variable + GLP_NS - non-basic fixed variable */ + int bind; + /* if the structural variable is basic, head[bind] refers to + this column; otherwise, bind is 0; this attribute is valid only + if the basis factorization is valid */ + double prim; /* non-scaled */ + /* primal value of the structural variable in basic solution */ + double dual; /* non-scaled */ + /* dual value of the structural variable in basic solution */ + double pval; /* non-scaled */ + /* primal value of the structural variable in interior solution */ + double dval; /* non-scaled */ + /* dual value of the structural variable in interior solution */ + double mipx; /* non-scaled */ + /* primal value of the structural variable in integer solution */ +}; + +struct GLPAIJ +{ /* constraint coefficient a[i,j] */ + GLPROW *row; + /* pointer to row, where this coefficient is placed */ + GLPCOL *col; + /* pointer to column, where this coefficient is placed */ + double val; + /* numeric (non-zero) value of this coefficient */ + GLPAIJ *r_prev; + /* pointer to previous coefficient in the same row */ + GLPAIJ *r_next; + /* pointer to next coefficient in the same row */ + GLPAIJ *c_prev; + /* pointer to previous coefficient in the same column */ + GLPAIJ *c_next; + /* pointer to next coefficient in the same column */ +}; + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/proxy/main.c b/resources/3rdparty/glpk-4.57/src/proxy/main.c new file mode 100644 index 000000000..a7d1e2b87 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/proxy/main.c @@ -0,0 +1,87 @@ +/* Last update: 08-May-2013 */ + +#include +#include +#include + +#include "glpk.h" +#include "proxy.h" + +/**********************************************************************/ +int main(int argc, char **argv) +/**********************************************************************/ +{ + glp_prob *lp; + int ncols, status; + double *initsol, zstar, *xstar; + + /* check arguments */ + if ( (argc == 1) || (argc > 3) ) { + printf("ERROR: Usage: ts <(possibly) xml initsols>\n" + ); + exit(1); + } + + /* creating the problem */ + lp = glp_create_prob(); + glp_set_prob_name(lp, "Proxy"); + + /* reading the problem */ + glp_term_out(GLP_OFF); +#if 0 /* by mao */ + status = glp_read_lp(lp, NULL, argv[1]); +#else + status = glp_read_mps(lp, GLP_MPS_FILE, NULL, argv[1]); +#endif + glp_term_out(GLP_ON); + if ( status ) { + printf("Problem %s does not exist!!!, status %d\n", + argv[1], status); + exit(1); + } + + ncols = glp_get_num_cols(lp); + + initsol = (double *) calloc(ncols+1, sizeof(double)); + + if (argc == 3) { + FILE *fp=fopen(argv[2],"r"); + char tmp[256]={0x0}; + int counter = 1; + while(fp!=NULL && fgets(tmp, sizeof(tmp),fp)!=NULL) + { + char *valini = strstr(tmp, "value"); + if (valini!=NULL){ + int num; + double dnum; + valini +=7; + sscanf(valini, "%d%*s",&num); + dnum = (double)num; + initsol[counter] = dnum; + counter++; + } + } + fclose(fp); + } + + xstar = (double *) calloc(ncols+1, sizeof(double)); + + if (argc == 3) { + status = proxy(lp, &zstar, xstar, initsol, 0.0, 0, 1); + } + else { + status = proxy(lp, &zstar, xstar, NULL, 0.0, 0, 1); + } + + printf("Status = %d; ZSTAR = %f\n",status,zstar); + /* + int i; + for (i=1; i< ncols+1; i++) { + printf("XSTAR[%d] = %f\n",i, xstar[i]); + } + */ + + glp_delete_prob(lp); + + return 0; +} diff --git a/resources/3rdparty/glpk-4.57/src/proxy/proxy.c b/resources/3rdparty/glpk-4.57/src/proxy/proxy.c new file mode 100644 index 000000000..31502a7f7 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/proxy/proxy.c @@ -0,0 +1,1061 @@ +/* proxy.c (proximity search heuristic algorithm) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Author: Giorgio Sartor <0gioker0@gmail.com>. +* +* Copyright (C) 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +* +************************************************************************ +* +* THIS CODE IS AN IMPLEMENTATION OF THE ALGORITHM PROPOSED IN +* +* M. Fischetti, M. Monaci, +* "Proximity Search for 0-1 Mixed-Integer Convex Programming" +* Technical Report DEI, University of Padua, March 2013. +* +* AVAILABLE AT +* http://www.dei.unipd.it/~fisch/papers/proximity_search.pdf +* +* THE CODE HAS BEEN WRITTEN BY GIORGIO SARTOR, " 0gioker0@gmail.com " +* +* BASIC IDEA: +* +* The initial feasible solution x_tilde is defined. This initial +* solution can be found by an ad-hoc heuristic and proxy can be used to +* refine it by exploiting an underlying MIP model whose solution from +* scratch turned out to be problematic. Otherwise, x_tilde can be found +* by running the GLPK mip solver until a first feasible solution is +* found, setting a conservative time limit of 10 minutes (by default). +* Time limit can be modified passing variable tlim [ms]. +* +* Then the cutoff tolerance "delta" is defined. The default tolerance +* is 1% of the last feasible solution obj value--rounded to integer if +* all the variables and obj coefficients are integer. +* +* Next, the objective function c' x is replaced by the Hamming distance +* between x (the actual obj coefficients) and x_tilde (the given +* solution). Distance is only computed wrt the binary variables. +* +* The GLPK solver is then invoked to hopefully find a new incumbent +* x_star with cost c' x_star <= c' x_tilde - delta. A crucial property +* here is that the root-node solution of the LP relaxation is expected +* to be not too different from x_tilde, as this latter solution would +* be optimal without the cutoff constraint, that for a small delta can +* typically be fulfilled with just local adjustments. +* +* If no new solution x_star is found within the time limit the +* algorithm stops. Of course, if the MIP solver proved infeasibility +* for the given delta, we have that c' x_tilde - delta is a valid lower +* bound (in case of minimazation) on the optimal value of the original +* MIP. +* +* The new solution x_star, if any, is possibly improved by solving a +* simplified problem (refinement) where all binary variables have been +* fixed to their value in x_star so as to find the best solution within +* the neighborhood. +* +* Finally, the approach is reapplied on x_star (that replaces x_tilde) +* so as to recenter the distance Hamming function and by modifying the +* cutoff tolerance delta. +* +* In this way, there will be a series of hopefully not-too-difficult +* sub-MIPs to solve, each leading to an improvement of the incumbent. +* More aggressive policies on the definition of tolerance delta can +* lead to a better performance, but would require an ad-hoc tuning. +* +************************************************************************ +* +* int proxy(glp_prob *lp, double *zstar, double *xstar, +* const double[] initsol, double rel_impr, int tlim, +* int verbose) +* +* lp : GLPK problem pointer to a MIP with binary variables +* +* zstar : the value of objective function of the best solution found +* +* xstar : best solution with components xstar[1],...,xstar[ncols] +* +* initsol : pointer to a initial feasible solution, see +* glp_ios_heur_sol +* If initsol = NULL, the procedure finds the first solution +* by itself. +* +* rel_impr : minimum relative obj improvement to be achieved at each +* internal step; if <= 0.0 a default value of 0.01 (1%) is +* used; for some problems (e.g., set covering with small +* integer costs) a more-conservative choice of 0.001 (0.1%) +* can lead to a better final solution; values larger than +* 0.05 (5%) are typically too aggressive and do not work +* well. +* +* tlim : time limit to find a new solution, in ms. +* If tlim = 0, it is set to its default value, 600000 ms +* +* verbose : if 1 the output is activated. If 0 only errors are +* displayed +* +* The procedure returns -1 if an error occurred, 0 otherwise (possibly, +* time limit) +* +***********************************************************************/ + +/**********************************************************************/ +/* 1. INCLUDE */ +/**********************************************************************/ + +#include "glpk.h" +#include "env.h" +#include "proxy.h" + +/**********************************************************************/ +/* 2. PARAMETERS AND CONSTANTS */ +/**********************************************************************/ + +#define TDAY 86400.0 +#define TRUE 1 +#define FALSE 0 +#define EPS 1e-6 +#define RINF 1e38 +#define MAXVAL 1e20 +#define MINVAL -1e20 +#if 0 /* by gioker */ + #define PROXY_DEBUG +#endif + +/**********************************************************************/ +/* 3. GLOBAL VARIABLES */ +/**********************************************************************/ + +struct csa { + +int integer_obj; /* TRUE if each feasible solution has an + integral cost */ +int b_vars_exist; /* TRUE if there is at least one binary + variable in the problem */ +int i_vars_exist; /* TRUE if there is at least one general + integer variable in the problem */ +const double *startsol; /* Pointer to the initial solution */ + +int *ckind; /* Store the kind of the structural variables + of the problem */ +double *clb; /* Store the lower bound on the structural + variables of the problem */ +double *cub; /* Store the upper bound on the structural + variables of the problem */ +double *true_obj; /* Store the obj coefficients of the problem */ + +int dir; /* Minimization or maximization problem */ +int ncols; /* Number of structural variables of the + problem */ + +time_t GLOtstart; /* starting time of the algorithm */ + +glp_prob *lp_ref; /* glp problem for refining only*/ + +}; + +/**********************************************************************/ +/* 4. FUNCTIONS PROTOTYPES */ +/**********************************************************************/ + +static void callback(glp_tree *tree, void *info); +static void get_info(struct csa *csa, glp_prob *lp); +static int is_integer(struct csa *csa); +static void check_integrality(struct csa *csa); +static int check_ref(struct csa *csa, glp_prob *lp, double *xref); +static double second(void); +static int add_cutoff(struct csa *csa, glp_prob *lp); +static void get_sol(struct csa *csa, glp_prob *lp, double *xstar); +static double elapsed_time(struct csa *csa); +static void redefine_obj(glp_prob *lp, double *xtilde, int ncols, + int *ckind, double *clb, double *cub); +static double update_cutoff(struct csa *csa, glp_prob *lp, + double zstar, int index, double rel_impr); +static double compute_delta(struct csa *csa, double z, + double rel_impr); +static double objval(int ncols, double *x, double *true_obj); +static void array_copy(int begin, int end, double *source, + double *destination); +static int do_refine(struct csa *csa, glp_prob *lp_ref, int ncols, + int *ckind, double *xref, int *tlim, int tref_lim, + int verbose); +static void deallocate(struct csa *csa, int refine); + +/**********************************************************************/ +/* 5. FUNCTIONS */ +/**********************************************************************/ + +int proxy(glp_prob *lp, double *zfinal, double *xfinal, + const double initsol[], double rel_impr, int tlim, + int verbose) + +{ struct csa csa_, *csa = &csa_; + glp_iocp parm; + glp_smcp parm_lp; + size_t tpeak; + int refine, tref_lim, err, cutoff_row, niter, status, i, tout; + double *xref, *xstar, zstar, tela, cutoff, zz; + + memset(csa, 0, sizeof(struct csa)); + + + /********** **********/ + /********** RETRIEVING PROBLEM INFO **********/ + /********** **********/ + + /* getting problem direction (min or max) */ + csa->dir = glp_get_obj_dir(lp); + + /* getting number of variables */ + csa->ncols = glp_get_num_cols(lp); + + /* getting kind, bounds and obj coefficient of each variable + information is stored in ckind, cub, clb, true_obj */ + get_info(csa, lp); + + /* checking if the objective function is always integral */ + check_integrality(csa); + + /* Proximity search cannot be used if there are no binary + variables */ + if (csa->b_vars_exist == FALSE) { + if (verbose) { + xprintf("The problem has not binary variables. Proximity se" + "arch cannot be used.\n"); + } + tfree(csa->ckind); + tfree(csa->clb); + tfree(csa->cub); + tfree(csa->true_obj); + return -1; + } + + /* checking if the problem needs refinement, i.e., not all + variables are binary. If so, the routine creates a copy of the + lp problem named lp_ref and initializes the solution xref to + zero. */ + xref = talloc(csa->ncols+1, double); +#if 0 /* by mao */ + memset(xref, 0, sizeof(double)*(csa->ncols+1)); +#endif + refine = check_ref(csa, lp, xref); +#ifdef PROXY_DEBUG + xprintf("REFINE = %d\n",refine); +#endif + + /* Initializing the solution */ + xstar = talloc(csa->ncols+1, double); +#if 0 /* by mao */ + memset(xstar, 0, sizeof(double)*(csa->ncols+1)); +#endif + + /********** **********/ + /********** FINDING FIRST SOLUTION **********/ + /********** **********/ + + if (verbose) { + xprintf("Applying PROXY heuristic...\n"); + } + + /* get the initial time */ + csa->GLOtstart = second(); + + /* setting the optimization parameters */ + glp_init_iocp(&parm); + glp_init_smcp(&parm_lp); +#if 0 /* by gioker */ + /* Preprocessing should be disabled because the mip passed + to proxy is already preprocessed */ + parm.presolve = GLP_ON; +#endif +#if 1 /* by mao */ + /* best projection backtracking seems to be more efficient to find + any integer feasible solution */ + parm.bt_tech = GLP_BT_BPH; +#endif + + /* Setting the default value of the minimum relative improvement + to 1% */ + if ( rel_impr <= 0.0 ) { + rel_impr = 0.01; + } + + /* Setting the default value of time limit to 10 minutes */ + if (tlim <= 0) { + tlim = INT_MAX; + } + if (verbose) { + xprintf("Proxy's time limit set to %d seconds.\n",tlim/1000); + xprintf("Proxy's relative improvement " + "set to %2.2lf %c.\n",rel_impr*100,37); + } + + parm_lp.tm_lim = tlim; + + parm.mip_gap = 9999999.9; /* to stop the optimization at the first + feasible solution found */ + + /* finding the first solution */ + if (verbose) { + xprintf("Searching for a feasible solution...\n"); + } + + /* verifying the existence of an input starting solution */ + if (initsol != NULL) { + csa->startsol = initsol; + parm.cb_func = callback; + parm.cb_info = csa; + if (verbose) { + xprintf("Input solution found.\n"); + } + } + + tout = glp_term_out(GLP_OFF); + err = glp_simplex(lp,&parm_lp); + glp_term_out(tout); + + status = glp_get_status(lp); + + if (status != GLP_OPT) { + if (verbose) { + xprintf("Proxy heuristic terminated.\n"); + } +#ifdef PROXY_DEBUG + /* For debug only */ + xprintf("GLP_SIMPLEX status = %d\n",status); + xprintf("GLP_SIMPLEX error code = %d\n",err); +#endif + tfree(xref); + tfree(xstar); + deallocate(csa, refine); + return -1; + } + + tela = elapsed_time(csa); + if (tlim-tela*1000 <= 0) { + if (verbose) { + xprintf("Time limit exceeded. Proxy could not " + "find optimal solution to LP relaxation.\n"); + xprintf("Proxy heuristic aborted.\n"); + } + tfree(xref); + tfree(xstar); + deallocate(csa, refine); + return -1; + } + + parm.tm_lim = tlim - tela*1000; + tref_lim = (tlim - tela *1000) / 20; + + tout = glp_term_out(GLP_OFF); + err = glp_intopt(lp, &parm); + glp_term_out(tout); + + status = glp_mip_status(lp); + + /***** If no solution was found *****/ + + if (status == GLP_NOFEAS || status == GLP_UNDEF) { + if (err == GLP_ETMLIM) { + if (verbose) { + xprintf("Time limit exceeded. Proxy could not " + "find an initial integer feasible solution.\n"); + xprintf("Proxy heuristic aborted.\n"); + } + } + else { + if (verbose) { + xprintf("Proxy could not " + "find an initial integer feasible solution.\n"); + xprintf("Proxy heuristic aborted.\n"); + } + } + tfree(xref); + tfree(xstar); + deallocate(csa, refine); + return -1; + } + + /* getting the first solution and its value */ + get_sol(csa, lp,xstar); + zstar = glp_mip_obj_val(lp); + + if (verbose) { + xprintf(">>>>> first solution = %e;\n", zstar); + } + + /* If a feasible solution was found but the time limit is + exceeded */ + if (err == GLP_ETMLIM) { + if (verbose) { + xprintf("Time limit exceeded. Proxy heuristic terminated.\n"); + } + goto done; + } + + tela = elapsed_time(csa); + tpeak = 0; + glp_mem_usage(NULL, NULL, NULL, &tpeak); + if (verbose) { + xprintf("Time used: %3.1lf secs. Memory used: %2.1lf Mb\n", + tela,(double)tpeak/1048576); + xprintf("Starting proximity search...\n"); + } + + /********** **********/ + /********** PREPARING THE PROBLEM FOR PROXY **********/ + /********** **********/ + + /* adding a dummy cutoff constraint */ + cutoff_row = add_cutoff(csa, lp); + + /* proximity search needs minimization direction + even if the problem is a maximization one */ + if (csa->dir == GLP_MAX) { + glp_set_obj_dir(lp, GLP_MIN); + } + + /********** **********/ + /********** STARTING PROXIMITY SEARCH **********/ + /********** **********/ + + + niter = 0; + + while (TRUE) { + niter++; + + /********** CHANGING THE OBJ FUNCTION **********/ + + redefine_obj(lp,xstar, csa->ncols, csa->ckind, csa->clb, + csa->cub); + + /********** UPDATING THE CUTOFF CONSTRAINT **********/ + + cutoff = update_cutoff(csa, lp,zstar, cutoff_row, rel_impr); + +#ifdef PROXY_DEBUG + xprintf("TRUE_OBJ[0] = %f\n",csa->true_obj[0]); + xprintf("ZSTAR = %f\n",zstar); + xprintf("CUTOFF = %f\n",cutoff); +#endif + + /********** SEARCHING FOR A BETTER SOLUTION **********/ + + tela = elapsed_time(csa); + if (tlim-tela*1000 <= 0) { + if (verbose) { + xprintf("Time limit exceeded. Proxy heuristic " + "terminated.\n"); + } + goto done; + } +#ifdef PROXY_DEBUG + xprintf("TELA = %3.1lf\n",tela*1000); + xprintf("TLIM = %3.1lf\n",tlim - tela*1000); +#endif + parm_lp.tm_lim = tlim -tela*1000; + + tout = glp_term_out(GLP_OFF); + err = glp_simplex(lp,&parm_lp); + glp_term_out(tout); + + status = glp_get_status(lp); + + if (status != GLP_OPT) { + if (status == GLP_NOFEAS) { + if (verbose) { + xprintf("Bound exceeded = %f. ",cutoff); + } + } + if (verbose) { + xprintf("Proxy heuristic terminated.\n"); + } +#ifdef PROXY_DEBUG + xprintf("GLP_SIMPLEX status = %d\n",status); + xprintf("GLP_SIMPLEX error code = %d\n",err); +#endif + goto done; + } + + tela = elapsed_time(csa); + if (tlim-tela*1000 <= 0) { + if (verbose) { + xprintf("Time limit exceeded. Proxy heuristic " + "terminated.\n"); + } + goto done; + } + parm.tm_lim = tlim - tela*1000; + parm.cb_func = NULL; +#if 0 /* by gioker */ + /* Preprocessing should be disabled because the mip passed + to proxy is already preprocessed */ + parm.presolve = GLP_ON; +#endif + tout = glp_term_out(GLP_OFF); + err = glp_intopt(lp, &parm); + glp_term_out(tout); + + /********** MANAGEMENT OF THE SOLUTION **********/ + + status = glp_mip_status(lp); + + /***** No feasible solutions *****/ + + if (status == GLP_NOFEAS) { + if (verbose) { + xprintf("Bound exceeded = %f. Proxy heuristic " + "terminated.\n",cutoff); + } + goto done; + } + + /***** Undefined solution *****/ + + if (status == GLP_UNDEF) { + if (err == GLP_ETMLIM) { + if (verbose) { + xprintf("Time limit exceeded. Proxy heuristic " + "terminated.\n"); + } + } + else { + if (verbose) { + xprintf("Proxy terminated unexpectedly.\n"); +#ifdef PROXY_DEBUG + xprintf("GLP_INTOPT error code = %d\n",err); +#endif + } + } + goto done; + } + + /***** Feasible solution *****/ + + if ((status == GLP_FEAS) || (status == GLP_OPT)) { + + /* getting the solution and computing its value */ + get_sol(csa, lp,xstar); + zz = objval(csa->ncols, xstar, csa->true_obj); + + /* Comparing the incumbent solution with the current best + one */ +#ifdef PROXY_DEBUG + xprintf("ZZ = %f\n",zz); + xprintf("ZSTAR = %f\n",zstar); + xprintf("REFINE = %d\n",refine); +#endif + if (((zzdir == GLP_MIN)) || + ((zz>zstar) && (csa->dir == GLP_MAX))) { + + /* refining (possibly) the solution */ + if (refine) { + + /* copying the incumbent solution in the refinement + one */ + array_copy(1, csa->ncols +1, xstar, xref); + err = do_refine(csa, csa->lp_ref, csa->ncols, + csa->ckind, xref, &tlim, tref_lim, verbose); + if (!err) { + double zref = objval(csa->ncols, xref, + csa->true_obj); + if (((zrefdir == GLP_MIN)) || + ((zref>zz) && (csa->dir == GLP_MAX))) { + zz = zref; + /* copying the refinement solution in the + incumbent one */ + array_copy(1, csa->ncols +1, xref, xstar); + } + } + } + zstar = zz; + tela = elapsed_time(csa); + if (verbose) { + xprintf(">>>>> it: %3d: mip = %e; elapsed time " + "%3.1lf sec.s\n", niter,zstar,tela); + } + } + } + } + +done: + tela = elapsed_time(csa); + glp_mem_usage(NULL, NULL, NULL, &tpeak); + if (verbose) { + xprintf("Time used: %3.1lf. Memory used: %2.1lf Mb\n", + tela,(double)tpeak/1048576); + } + + + /* Exporting solution and obj val */ + *zfinal = zstar; + + for (i=1; i < (csa->ncols + 1); i++) { + xfinal[i]=xstar[i]; + } + + /* Freeing allocated memory */ + tfree(xref); + tfree(xstar); + deallocate(csa, refine); + + return 0; +} + +/**********************************************************************/ +static void callback(glp_tree *tree, void *info){ +/**********************************************************************/ + struct csa *csa = info; + switch(glp_ios_reason(tree)) { + case GLP_IHEUR: + glp_ios_heur_sol(tree, csa->startsol); + break; + default: break; + } +} + +/**********************************************************************/ +static void get_info(struct csa *csa, glp_prob *lp) +/**********************************************************************/ +{ + int i; + + /* Storing helpful info of the problem */ + + csa->ckind = talloc(csa->ncols+1, int); +#if 0 /* by mao */ + memset(csa->ckind, 0, sizeof(int)*(csa->ncols+1)); +#endif + csa->clb = talloc(csa->ncols+1, double); +#if 0 /* by mao */ + memset(csa->clb, 0, sizeof(double)*(csa->ncols+1)); +#endif + csa->cub = talloc(csa->ncols+1, double); +#if 0 /* by mao */ + memset(csa->cub, 0, sizeof(double)*(csa->ncols+1)); +#endif + csa->true_obj = talloc(csa->ncols+1, double); +#if 0 /* by mao */ + memset(csa->true_obj, 0, sizeof(double)*(csa->ncols+1)); +#endif + for( i = 1 ; i < (csa->ncols + 1); i++ ) { + csa->ckind[i] = glp_get_col_kind(lp, i); + csa->clb[i] = glp_get_col_lb(lp, i); + csa->cub[i] = glp_get_col_ub(lp, i); + csa->true_obj[i] = glp_get_obj_coef(lp, i); + } + csa->true_obj[0] = glp_get_obj_coef(lp, 0); +} + +/**********************************************************************/ +static int is_integer(struct csa *csa) +/**********************************************************************/ +{ + int i; + csa->integer_obj = TRUE; + for ( i = 1; i < (csa->ncols + 1); i++ ) { + if (fabs(csa->true_obj[i]) > INT_MAX ) { + csa->integer_obj = FALSE; + } + if (fabs(csa->true_obj[i]) <= INT_MAX) { + double tmp, rem; + if (fabs(csa->true_obj[i]) - floor(fabs(csa->true_obj[i])) + < 0.5) { + tmp = floor(fabs(csa->true_obj[i])); + } + else { + tmp = ceil(fabs(csa->true_obj[i])); + } + rem = fabs(csa->true_obj[i]) - tmp; + rem = fabs(rem); + if (rem > EPS) { + csa->integer_obj = FALSE; + } + + } + } + return csa->integer_obj; +} + +/**********************************************************************/ +static void check_integrality(struct csa *csa) +/**********************************************************************/ +{ + /* + Checking if the problem has binary, integer or continuos variables. + integer_obj is TRUE if the problem has no continuous variables + and all the obj coefficients are integer (and < INT_MAX). + */ + + int i; + csa->integer_obj = is_integer(csa); + csa->b_vars_exist = FALSE; + csa->i_vars_exist = FALSE; + for ( i = 1; i < (csa->ncols + 1); i++ ) { + if ( csa->ckind[i] == GLP_IV ){ + csa->i_vars_exist = TRUE; + continue; + } + if ( csa->ckind[i] == GLP_BV ){ + csa->b_vars_exist =TRUE; + continue; + } + csa->integer_obj = FALSE; + } +} + +/**********************************************************************/ +static int check_ref(struct csa *csa, glp_prob *lp, double *xref) +/**********************************************************************/ +{ + /* + checking if the problem has continuos or integer variables. If so, + refinement is prepared. + */ + int refine = FALSE; + int i; + for ( i = 1; i < (csa->ncols + 1); i++ ) { + if ( csa->ckind[i] != GLP_BV) { + refine = TRUE; + break; + } + } + + /* possibly creating a mip clone for refinement only */ + if ( refine ) { + csa->lp_ref = glp_create_prob(); + glp_copy_prob(csa->lp_ref, lp, GLP_ON); + } + + return refine; +} + +/**********************************************************************/ +static double second(void) +/**********************************************************************/ +{ +#if 0 /* by mao */ + return ((double)clock()/(double)CLOCKS_PER_SEC); +#else + return xtime() / 1000.0; +#endif +} + +/**********************************************************************/ +static int add_cutoff(struct csa *csa, glp_prob *lp) +/**********************************************************************/ +{ + /* + Adding a cutoff constraint to set an upper bound (in case of + minimaztion) on the obj value of the next solution, i.e., the next + value of the true obj function that we would like to find + */ + + /* store non-zero coefficients in the objective function */ + int *obj_index = talloc(csa->ncols+1, int); +#if 0 /* by mao */ + memset(obj_index, 0, sizeof(int)*(csa->ncols+1)); +#endif + double *obj_value = talloc(csa->ncols+1, double); +#if 0 /* by mao */ + memset(obj_value, 0, sizeof(double)*(csa->ncols+1)); +#endif + int obj_nzcnt = 0; + int i, irow; + const char *rowname; + for ( i = 1; i < (csa->ncols + 1); i++ ) { + if ( fabs(csa->true_obj[i]) > EPS ) { + obj_nzcnt++; + obj_index[obj_nzcnt] = i; + obj_value[obj_nzcnt] = csa->true_obj[i]; + } + } + + irow = glp_add_rows(lp, 1); + rowname = "Cutoff"; + glp_set_row_name(lp, irow, rowname); + if (csa->dir == GLP_MIN) { + /* minimization problem */ + glp_set_row_bnds(lp, irow, GLP_UP, MAXVAL, MAXVAL); + } + else { + /* maximization problem */ + glp_set_row_bnds(lp, irow, GLP_LO, MINVAL, MINVAL); + } + + glp_set_mat_row(lp, irow, obj_nzcnt, obj_index, obj_value); + + tfree(obj_index); + tfree(obj_value); + + return irow; +} + +/**********************************************************************/ +static void get_sol(struct csa *csa, glp_prob *lp, double *xstar) +/**********************************************************************/ +{ + /* Retrieving and storing the coefficients of the solution */ + + int i; + for (i = 1; i < (csa->ncols +1); i++) { + xstar[i] = glp_mip_col_val(lp, i); + } +} + +/**********************************************************************/ +static double elapsed_time(struct csa *csa) +/**********************************************************************/ +{ + double tela = second() - csa->GLOtstart; + if ( tela < 0 ) tela += TDAY; + return(tela); +} + +/**********************************************************************/ +static void redefine_obj(glp_prob *lp, double *xtilde, int ncols, + int *ckind, double *clb, double *cub) +/**********************************************************************/ + +/* + Redefine the lp objective function obj as the distance-to-integrality + (Hamming distance) from xtilde (the incumbent feasible solution), wrt + to binary vars only + */ + +{ + int j; + double *delta = talloc(ncols+1, double); +#if 0 /* by mao */ + memset(delta, 0, sizeof(double)*(ncols+1)); +#endif + + for ( j = 1; j < (ncols +1); j++ ) { + delta[j] = 0.0; + /* skip continuous variables */ + if ( ckind[j] == GLP_CV ) continue; + + /* skip integer variables that have been fixed */ + if ( cub[j]-clb[j] < 0.5 ) continue; + + /* binary variable */ + if ( ckind[j] == GLP_BV ) { + if ( xtilde[j] > 0.5 ) { + delta[j] = -1.0; + } + else { + delta[j] = 1.0; + } + } + } + + /* changing the obj coeff. for all variables, including continuous + ones */ + for ( j = 1; j < (ncols +1); j++ ) { + glp_set_obj_coef(lp, j, delta[j]); + } + glp_set_obj_coef(lp, 0, 0.0); + + tfree(delta); +} + +/**********************************************************************/ +static double update_cutoff(struct csa *csa, glp_prob *lp, + double zstar, int cutoff_row, + double rel_impr) +/**********************************************************************/ +{ + /* + Updating the cutoff constraint with the value we would like to + find during the next optimization + */ + double cutoff; + zstar -= csa->true_obj[0]; + if (csa->dir == GLP_MIN) { + cutoff = zstar - compute_delta(csa, zstar, rel_impr); + glp_set_row_bnds(lp, cutoff_row, GLP_UP, cutoff, cutoff); + } + else { + cutoff = zstar + compute_delta(csa, zstar, rel_impr); + glp_set_row_bnds(lp, cutoff_row, GLP_LO, cutoff, cutoff); + } + + return cutoff; +} + +/**********************************************************************/ +static double compute_delta(struct csa *csa, double z, double rel_impr) +/**********************************************************************/ +{ + /* Computing the offset for the next best solution */ + + double delta = rel_impr * fabs(z); + if ( csa->integer_obj ) delta = ceil(delta); + + return(delta); +} + +/**********************************************************************/ +static double objval(int ncols, double *x, double *true_obj) +/**********************************************************************/ +{ + /* Computing the true cost of x (using the original obj coeff.s) */ + + int j; + double z = 0.0; + for ( j = 1; j < (ncols +1); j++ ) { + z += x[j] * true_obj[j]; + } + return z + true_obj[0]; +} + +/**********************************************************************/ +static void array_copy(int begin, int end, double *source, + double *destination) +/**********************************************************************/ +{ + int i; + for (i = begin; i < end; i++) { + destination[i] = source[i]; + } +} +/**********************************************************************/ +static int do_refine(struct csa *csa, glp_prob *lp_ref, int ncols, + int *ckind, double *xref, int *tlim, int tref_lim, + int verbose) +/**********************************************************************/ +{ + /* + Refinement is applied when the variables of the problem are not + all binary. Binary variables are fixed to their value and + remaining ones are optimized. If there are only continuos + variables (in addition to those binary) the problem becomes just + an LP. Otherwise, it remains a MIP but of smaller size. + */ + + int j, tout; + double refineStart = second(); + double val, tela, tlimit; + + if ( glp_get_num_cols(lp_ref) != ncols ) { + if (verbose) { + xprintf("Error in Proxy refinement: "); + xprintf("wrong number of columns (%d vs %d).\n", + ncols, glp_get_num_cols(lp_ref)); + } + return 1; + } + + val = -1.0; + + /* fixing all binary variables to their current value in xref */ + for ( j = 1; j < (ncols + 1); j++ ) { + if ( ckind[j] == GLP_BV ) { + val = 0.0; + if ( xref[j] > 0.5 ) val = 1.0; + glp_set_col_bnds(lp_ref, j, GLP_FX, val, val); + } + } + + /* re-optimizing (refining) if some bound has been changed */ + if ( val > -1.0 ) { + glp_iocp parm_ref; + glp_smcp parm_ref_lp; + int err, status; + + glp_init_iocp(&parm_ref); + parm_ref.presolve = GLP_ON; + glp_init_smcp(&parm_ref_lp); + /* + If there are no general integer variable the problem becomes + an LP (after fixing the binary variables) and can be solved + quickly. Otherwise the problem is still a MIP problem and a + timelimit has to be set. + */ + parm_ref.tm_lim = tref_lim; + if (parm_ref.tm_lim > *tlim) { + parm_ref.tm_lim = *tlim; + } + parm_ref_lp.tm_lim = parm_ref.tm_lim; +#ifdef PROXY_DEBUG + xprintf("***** REFINING *****\n"); +#endif + tout = glp_term_out(GLP_OFF); + if (csa->i_vars_exist == TRUE) { + err = glp_intopt(lp_ref, &parm_ref); + } + else { + err = glp_simplex(lp_ref, &parm_ref_lp); + } + glp_term_out(tout); + + if (csa->i_vars_exist == TRUE) { + status = glp_mip_status(lp_ref); + } + else { + status = glp_get_status(lp_ref); + } +#ifdef PROXY_DEBUG + xprintf("STATUS REFINING = %d\n",status); +#endif + if (status == GLP_UNDEF) { + if (err == GLP_ETMLIM) { +#ifdef PROXY_DEBUG + xprintf("Time limit exceeded on Proxy refining.\n"); +#endif + return 1; + } + } + for( j = 1 ; j < (ncols + 1); j++ ){ + if (ckind[j] != GLP_BV) { + if (csa->i_vars_exist == TRUE) { + xref[j] = glp_mip_col_val(lp_ref, j); + } + else{ + xref[j] = glp_get_col_prim(lp_ref, j); + } + } + } + } + tela = second() - refineStart; +#ifdef PROXY_DEBUG + xprintf("REFINE TELA = %3.1lf\n",tela*1000); +#endif + return 0; +} +/**********************************************************************/ +static void deallocate(struct csa *csa, int refine) +/**********************************************************************/ +{ + /* Deallocating routine */ + + if (refine) { + glp_delete_prob(csa->lp_ref); + } + + tfree(csa->ckind); + tfree(csa->clb); + tfree(csa->cub); + tfree(csa->true_obj); + +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/proxy/proxy.h b/resources/3rdparty/glpk-4.57/src/proxy/proxy.h new file mode 100644 index 000000000..a91e36f2d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/proxy/proxy.h @@ -0,0 +1,36 @@ +/* proxy.h (proximity search heuristic algorithm) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Author: Giorgio Sartor <0gioker0@gmail.com>. +* +* Copyright (C) 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef PROXY_H +#define PROXY_H + +#define proxy _glp_proxy +int proxy(glp_prob *lp, double *zstar, double *xstar, + const double initsol[], double rel_impr, int tlim, + int verbose); + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/proxy/proxy1.c b/resources/3rdparty/glpk-4.57/src/proxy/proxy1.c new file mode 100644 index 000000000..b05fe8e4f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/proxy/proxy1.c @@ -0,0 +1,58 @@ +/* proxy1.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "glpios.h" +#include "proxy.h" + +void ios_proxy_heur(glp_tree *T) +{ glp_prob *prob; + int j, status; + double *xstar, zstar; + /* this heuristic is applied only once on the root level */ + if (!(T->curr->level == 0 && T->curr->solved == 1)) + goto done; + prob = glp_create_prob(); + glp_copy_prob(prob, T->mip, 0); + xstar = xcalloc(1+prob->n, sizeof(double)); + for (j = 1; j <= prob->n; j++) + xstar[j] = 0.0; + if (T->mip->mip_stat != GLP_FEAS) + status = proxy(prob, &zstar, xstar, NULL, 0.0, + T->parm->ps_tm_lim, 1); + else + { double *xinit = xcalloc(1+prob->n, sizeof(double)); + for (j = 1; j <= prob->n; j++) + xinit[j] = T->mip->col[j]->mipx; + status = proxy(prob, &zstar, xstar, xinit, 0.0, + T->parm->ps_tm_lim, 1); + xfree(xinit); + } + if (status == 0) + glp_ios_heur_sol(T, xstar); + xfree(xstar); + glp_delete_prob(prob); +done: return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/simplex.h b/resources/3rdparty/glpk-4.57/src/simplex/simplex.h new file mode 100644 index 000000000..48205881d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/simplex.h @@ -0,0 +1,39 @@ +/* simplex.h */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef SIMPLEX_H +#define SIMPLEX_H + +#include "prob.h" + +#define spx_primal _glp_spx_primal +int spx_primal(glp_prob *P, const glp_smcp *parm); +/* driver to primal simplex method */ + +#define spy_dual _glp_spy_dual +int spy_dual(glp_prob *P, const glp_smcp *parm); +/* driver to dual simplex method */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spxat.c b/resources/3rdparty/glpk-4.57/src/simplex/spxat.c new file mode 100644 index 000000000..3570a18c9 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spxat.c @@ -0,0 +1,265 @@ +/* spxat.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "spxat.h" + +/*********************************************************************** +* spx_alloc_at - allocate constraint matrix in sparse row-wise format +* +* This routine allocates the memory for arrays needed to represent the +* constraint matrix in sparse row-wise format. */ + +void spx_alloc_at(SPXLP *lp, SPXAT *at) +{ int m = lp->m; + int n = lp->n; + int nnz = lp->nnz; + at->ptr = talloc(1+m+1, int); + at->ind = talloc(1+nnz, int); + at->val = talloc(1+nnz, double); + at->work = talloc(1+n, double); + return; +} + +/*********************************************************************** +* spx_build_at - build constraint matrix in sparse row-wise format +* +* This routine builds sparse row-wise representation of the constraint +* matrix A using its sparse column-wise representation stored in the +* lp object, and stores the result in the at object. */ + +void spx_build_at(SPXLP *lp, SPXAT *at) +{ int m = lp->m; + int n = lp->n; + int nnz = lp->nnz; + int *A_ptr = lp->A_ptr; + int *A_ind = lp->A_ind; + double *A_val = lp->A_val; + int *AT_ptr = at->ptr; + int *AT_ind = at->ind; + double *AT_val = at->val; + int i, k, ptr, end, pos; + /* calculate AT_ptr[i] = number of non-zeros in i-th row */ + memset(&AT_ptr[1], 0, m * sizeof(int)); + for (k = 1; k <= n; k++) + { ptr = A_ptr[k]; + end = A_ptr[k+1]; + for (; ptr < end; ptr++) + AT_ptr[A_ind[ptr]]++; + } + /* set AT_ptr[i] to position after last element in i-th row */ + AT_ptr[1]++; + for (i = 2; i <= m; i++) + AT_ptr[i] += AT_ptr[i-1]; + xassert(AT_ptr[m] == nnz+1); + AT_ptr[m+1] = nnz+1; + /* build row-wise representation and re-arrange AT_ptr[i] */ + for (k = n; k >= 1; k--) + { /* copy elements from k-th column to corresponding rows */ + ptr = A_ptr[k]; + end = A_ptr[k+1]; + for (; ptr < end; ptr++) + { pos = --AT_ptr[A_ind[ptr]]; + AT_ind[pos] = k; + AT_val[pos] = A_val[ptr]; + } + } + xassert(AT_ptr[1] == 1); + return; +} + +/*********************************************************************** +* spx_at_prod - compute product y := y + s * A'* x +* +* This routine computes the product: +* +* y := y + s * A'* x, +* +* where A' is a matrix transposed to the mxn-matrix A of constraint +* coefficients, x is a m-vector, s is a scalar, y is a n-vector. +* +* The routine uses the row-wise representation of the matrix A and +* computes the product as a linear combination: +* +* y := y + s * (A'[1] * x[1] + ... + A'[m] * x[m]), +* +* where A'[i] is i-th row of A, 1 <= i <= m. */ + +void spx_at_prod(SPXLP *lp, SPXAT *at, double y[/*1+n*/], double s, + const double x[/*1+m*/]) +{ int m = lp->m; + int *AT_ptr = at->ptr; + int *AT_ind = at->ind; + double *AT_val = at->val; + int i, ptr, end; + double t; + for (i = 1; i <= m; i++) + { if (x[i] != 0.0) + { /* y := y + s * (i-th row of A) * x[i] */ + t = s * x[i]; + ptr = AT_ptr[i]; + end = AT_ptr[i+1]; + for (; ptr < end; ptr++) + y[AT_ind[ptr]] += AT_val[ptr] * t; + } + } + return; +} + +/*********************************************************************** +* spx_nt_prod1 - compute product y := y + s * N'* x +* +* This routine computes the product: +* +* y := y + s * N'* x, +* +* where N' is a matrix transposed to the mx(n-m)-matrix N composed +* from non-basic columns of the constraint matrix A, x is a m-vector, +* s is a scalar, y is (n-m)-vector. +* +* If the flag ign is non-zero, the routine ignores the input content +* of the array y assuming that y = 0. */ + +void spx_nt_prod1(SPXLP *lp, SPXAT *at, double y[/*1+n-m*/], int ign, + double s, const double x[/*1+m*/]) +{ int m = lp->m; + int n = lp->n; + int *head = lp->head; + double *work = at->work; + int j, k; + for (k = 1; k <= n; k++) + work[k] = 0.0; + if (!ign) + { for (j = 1; j <= n-m; j++) + work[head[m+j]] = y[j]; + } + spx_at_prod(lp, at, work, s, x); + for (j = 1; j <= n-m; j++) + y[j] = work[head[m+j]]; + return; +} + +/*********************************************************************** +* spx_eval_trow1 - compute i-th row of simplex table +* +* This routine computes i-th row of the current simplex table +* T = (T[i,j]) = - inv(B) * N, 1 <= i <= m, using representation of +* the constraint matrix A in row-wise format. +* +* The vector rho = (rho[j]), which is i-th row of the basis inverse +* inv(B), should be previously computed with the routine spx_eval_rho. +* It is assumed that elements of this vector are stored in the array +* locations rho[1], ..., rho[m]. +* +* There exist two ways to compute the simplex table row. +* +* 1. T[i,j], j = 1,...,n-m, is computed as inner product: +* +* m +* T[i,j] = - sum a[i,k] * rho[i], +* i=1 +* +* where N[j] = A[k] is a column of the constraint matrix corresponding +* to non-basic variable xN[j]. The estimated number of operations in +* this case is: +* +* n1 = (n - m) * (nnz(A) / n), +* +* (n - m) is the number of columns of N, nnz(A) / n is the average +* number of non-zeros in one column of A and, therefore, of N. +* +* 2. The simplex table row is computed as part of a linear combination +* of rows of A with coefficients rho[i] != 0. The estimated number +* of operations in this case is: +* +* n2 = nnz(rho) * (nnz(A) / m), +* +* where nnz(rho) is the number of non-zeros in the vector rho, +* nnz(A) / m is the average number of non-zeros in one row of A. +* +* If n1 < n2, the routine computes the simples table row using the +* first way (like the routine spx_eval_trow). Otherwise, the routine +* uses the second way calling the routine spx_nt_prod1. +* +* On exit components of the simplex table row are stored in the array +* locations trow[1], ... trow[n-m]. */ + +void spx_eval_trow1(SPXLP *lp, SPXAT *at, const double rho[/*1+m*/], + double trow[/*1+n-m*/]) +{ int m = lp->m; + int n = lp->n; + int nnz = lp->nnz; + int i, j, nnz_rho; + double cnt1, cnt2; + /* determine nnz(rho) */ + nnz_rho = 0; + for (i = 1; i <= m; i++) + { if (rho[i] != 0.0) + nnz_rho++; + } + /* estimate the number of operations for both ways */ + cnt1 = (double)(n - m) * ((double)nnz / (double)n); + cnt2 = (double)nnz_rho * ((double)nnz / (double)m); + /* compute i-th row of simplex table */ + if (cnt1 < cnt2) + { /* as inner products */ + int *A_ptr = lp->A_ptr; + int *A_ind = lp->A_ind; + double *A_val = lp->A_val; + int *head = lp->head; + int k, ptr, end; + double tij; + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + /* compute t[i,j] = - N'[j] * pi */ + tij = 0.0; + ptr = A_ptr[k]; + end = A_ptr[k+1]; + for (; ptr < end; ptr++) + tij -= A_val[ptr] * rho[A_ind[ptr]]; + trow[j] = tij; + } + } + else + { /* as linear combination */ + spx_nt_prod1(lp, at, trow, 1, -1.0, rho); + } + return; +} + +/*********************************************************************** +* spx_free_at - deallocate constraint matrix in sparse row-wise format +* +* This routine deallocates the memory used for arrays of the program +* object at. */ + +void spx_free_at(SPXLP *lp, SPXAT *at) +{ xassert(lp == lp); + tfree(at->ptr); + tfree(at->ind); + tfree(at->val); + tfree(at->work); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spxat.h b/resources/3rdparty/glpk-4.57/src/simplex/spxat.h new file mode 100644 index 000000000..98d5b0033 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spxat.h @@ -0,0 +1,80 @@ +/* spxat.h */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef SPXAT_H +#define SPXAT_H + +#include "spxlp.h" + +typedef struct SPXAT SPXAT; + +struct SPXAT +{ /* mxn-matrix A of constraint coefficients in sparse row-wise + * format */ + int *ptr; /* int ptr[1+m+1]; */ + /* ptr[0] is not used; + * ptr[i], 1 <= i <= m, is starting position of i-th row in + * arrays ind and val; note that ptr[1] is always 1; + * ptr[m+1] indicates the position after the last element in + * arrays ind and val, i.e. ptr[m+1] = nnz+1, where nnz is the + * number of non-zero elements in matrix A; + * the length of i-th row (the number of non-zero elements in + * that row) can be calculated as ptr[i+1] - ptr[i] */ + int *ind; /* int ind[1+nnz]; */ + /* column indices */ + double *val; /* double val[1+nnz]; */ + /* non-zero element values */ + double *work; /* double work[1+n]; */ + /* working array */ +}; + +#define spx_alloc_at _glp_spx_alloc_at +void spx_alloc_at(SPXLP *lp, SPXAT *at); +/* allocate constraint matrix in sparse row-wise format */ + +#define spx_build_at _glp_spx_build_at +void spx_build_at(SPXLP *lp, SPXAT *at); +/* build constraint matrix in sparse row-wise format */ + +#define spx_at_prod _glp_spx_at_prod +void spx_at_prod(SPXLP *lp, SPXAT *at, double y[/*1+n*/], double s, + const double x[/*1+m*/]); +/* compute product y := y + s * A'* x */ + +#define spx_nt_prod1 _glp_spx_nt_prod1 +void spx_nt_prod1(SPXLP *lp, SPXAT *at, double y[/*1+n-m*/], int ign, + double s, const double x[/*1+m*/]); +/* compute product y := y + s * N'* x */ + +#define spx_eval_trow1 _glp_spx_eval_trow1 +void spx_eval_trow1(SPXLP *lp, SPXAT *at, const double rho[/*1+m*/], + double trow[/*1+n-m*/]); +/* compute i-th row of simplex table */ + +#define spx_free_at _glp_spx_free_at +void spx_free_at(SPXLP *lp, SPXAT *at); +/* deallocate constraint matrix in sparse row-wise format */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spxchuzc.c b/resources/3rdparty/glpk-4.57/src/simplex/spxchuzc.c new file mode 100644 index 000000000..c60ccabc9 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spxchuzc.c @@ -0,0 +1,381 @@ +/* spxchuzc.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "spxchuzc.h" + +/*********************************************************************** +* spx_chuzc_sel - select eligible non-basic variables +* +* This routine selects eligible non-basic variables xN[j], whose +* reduced costs d[j] have "wrong" sign, i.e. changing such xN[j] in +* feasible direction improves (decreases) the objective function. +* +* Reduced costs of non-basic variables should be placed in the array +* locations d[1], ..., d[n-m]. +* +* Non-basic variable xN[j] is considered eligible if: +* +* d[j] <= -eps[j] and xN[j] can increase +* +* d[j] >= +eps[j] and xN[j] can decrease +* +* for +* +* eps[j] = tol + tol1 * |cN[j]|, +* +* where cN[j] is the objective coefficient at xN[j], tol and tol1 are +* specified tolerances. +* +* On exit the routine stores indices j of eligible non-basic variables +* xN[j] to the array locations list[1], ..., list[num] and returns the +* number of such variables 0 <= num <= n-m. (If the parameter list is +* specified as NULL, no indices are stored.) */ + +int spx_chuzc_sel(SPXLP *lp, const double d[/*1+n-m*/], double tol, + double tol1, int list[/*1+n-m*/]) +{ int m = lp->m; + int n = lp->n; + double *c = lp->c; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + char *flag = lp->flag; + int j, k, num; + double ck, eps; + num = 0; + /* walk thru list of non-basic variables */ + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + if (l[k] == u[k]) + { /* xN[j] is fixed variable; skip it */ + continue; + } + /* determine absolute tolerance eps[j] */ + ck = c[k]; + eps = tol + tol1 * (ck >= 0.0 ? +ck : -ck); + /* check if xN[j] is eligible */ + if (d[j] <= -eps) + { /* xN[j] should be able to increase */ + if (flag[j]) + { /* but its upper bound is active */ + continue; + } + } + else if (d[j] >= +eps) + { /* xN[j] should be able to decrease */ + if (!flag[j] && l[k] != -DBL_MAX) + { /* but its lower bound is active */ + continue; + } + } + else /* -eps < d[j] < +eps */ + { /* xN[j] does not affect the objective function within the + * specified tolerance */ + continue; + } + /* xN[j] is eligible non-basic variable */ + num++; + if (list != NULL) + list[num] = j; + } + return num; +} + +/*********************************************************************** +* spx_chuzc_std - choose non-basic variable (Dantzig's rule) +* +* This routine chooses most eligible non-basic variable xN[q] +* according to Dantzig's ("standard") rule: +* +* d[q] = max |d[j]|, +* j in J +* +* where J <= {1, ..., n-m} is the set of indices of eligible non-basic +* variables, d[j] is the reduced cost of non-basic variable xN[j] in +* the current basis. +* +* Reduced costs of non-basic variables should be placed in the array +* locations d[1], ..., d[n-m]. +* +* Indices of eligible non-basic variables j in J should be placed in +* the array locations list[1], ..., list[num], where num = |J| > 0 is +* the total number of such variables. +* +* On exit the routine returns q, the index of the non-basic variable +* xN[q] chosen. */ + +int spx_chuzc_std(SPXLP *lp, const double d[/*1+n-m*/], int num, + const int list[]) +{ int m = lp->m; + int n = lp->n; + int j, q, t; + double abs_dj, abs_dq; + xassert(0 < num && num <= n-m); + q = 0, abs_dq = -1.0; + for (t = 1; t <= num; t++) + { j = list[t]; + abs_dj = (d[j] >= 0.0 ? +d[j] : -d[j]); + if (abs_dq < abs_dj) + q = j, abs_dq = abs_dj; + } + xassert(q != 0); + return q; +} + +/*********************************************************************** +* spx_alloc_se - allocate pricing data block +* +* This routine allocates the memory for arrays used in the pricing +* data block. */ + +void spx_alloc_se(SPXLP *lp, SPXSE *se) +{ int m = lp->m; + int n = lp->n; + se->valid = 0; + se->refsp = talloc(1+n, char); + se->gamma = talloc(1+n-m, double); + se->work = talloc(1+m, double); + return; +} + +/*********************************************************************** +* spx_reset_refsp - reset reference space +* +* This routine resets (re-initializes) the reference space composing +* it from variables which are non-basic in the current basis, and sets +* all weights gamma[j] to 1. */ + +void spx_reset_refsp(SPXLP *lp, SPXSE *se) +{ int m = lp->m; + int n = lp->n; + int *head = lp->head; + char *refsp = se->refsp; + double *gamma = se->gamma; + int j, k; + se->valid = 1; + memset(&refsp[1], 0, n * sizeof(char)); + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + refsp[k] = 1; + gamma[j] = 1.0; + } + return; +} + +/*********************************************************************** +* spx_eval_gamma_j - compute projected steepest edge weight directly +* +* This routine computes projected steepest edge weight gamma[j], +* 1 <= j <= n-m, for the current basis directly with the formula: +* +* m +* gamma[j] = delta[j] + sum eta[i] * T[i,j]**2, +* i=1 +* +* where T[i,j] is element of the current simplex table, and +* +* ( 1, if xB[i] is in the reference space +* eta[i] = { +* ( 0, otherwise +* +* ( 1, if xN[j] is in the reference space +* delta[j] = { +* ( 0, otherwise +* +* NOTE: For testing/debugging only. */ + +double spx_eval_gamma_j(SPXLP *lp, SPXSE *se, int j) +{ int m = lp->m; + int n = lp->n; + int *head = lp->head; + char *refsp = se->refsp; + double *tcol = se->work; + int i, k; + double gamma_j; + xassert(se->valid); + xassert(1 <= j && j <= n-m); + k = head[m+j]; /* x[k] = xN[j] */ + gamma_j = (refsp[k] ? 1.0 : 0.0); + spx_eval_tcol(lp, j, tcol); + for (i = 1; i <= m; i++) + { k = head[i]; /* x[k] = xB[i] */ + if (refsp[k]) + gamma_j += tcol[i] * tcol[i]; + } + return gamma_j; +} + +/*********************************************************************** +* spx_chuzc_pse - choose non-basic variable (projected steepest edge) +* +* This routine chooses most eligible non-basic variable xN[q] +* according to the projected steepest edge method: +* +* d[q]**2 d[j]**2 +* -------- = max -------- , +* gamma[q] j in J gamma[j] +* +* where J <= {1, ..., n-m} is the set of indices of eligible non-basic +* variable, d[j] is the reduced cost of non-basic variable xN[j] in +* the current basis, gamma[j] is the projected steepest edge weight. +* +* Reduced costs of non-basic variables should be placed in the array +* locations d[1], ..., d[n-m]. +* +* Indices of eligible non-basic variables j in J should be placed in +* the array locations list[1], ..., list[num], where num = |J| > 0 is +* the total number of such variables. +* +* On exit the routine returns q, the index of the non-basic variable +* xN[q] chosen. */ + +int spx_chuzc_pse(SPXLP *lp, SPXSE *se, const double d[/*1+n-m*/], + int num, const int list[]) +{ int m = lp->m; + int n = lp->n; + double *gamma = se->gamma; + int j, q, t; + double best, temp; + xassert(se->valid); + xassert(0 < num && num <= n-m); + q = 0, best = -1.0; + for (t = 1; t <= num; t++) + { j = list[t]; + /* FIXME */ + if (gamma[j] < DBL_EPSILON) + temp = 0.0; + else + temp = (d[j] * d[j]) / gamma[j]; + if (best < temp) + q = j, best = temp; + } + xassert(q != 0); + return q; +} + +/*********************************************************************** +* spx_update_gamma - update projected steepest edge weights exactly +* +* This routine updates the vector gamma = (gamma[j]) of projected +* steepest edge weights exactly, for the adjacent basis. +* +* On entry to the routine the content of the se object should be valid +* and should correspond to the current basis. +* +* The parameter 1 <= p <= m specifies basic variable xB[p] which +* becomes non-basic variable xN[q] in the adjacent basis. +* +* The parameter 1 <= q <= n-m specified non-basic variable xN[q] which +* becomes basic variable xB[p] in the adjacent basis. +* +* It is assumed that the array trow contains elements of p-th (pivot) +* row T'[p] of the simplex table in locations trow[1], ..., trow[n-m]. +* It is also assumed that the array tcol contains elements of q-th +* (pivot) column T[q] of the simple table in locations tcol[1], ..., +* tcol[m]. (These row and column should be computed for the current +* basis.) +* +* For details about the formulae used see the program documentation. +* +* The routine also computes the relative error: +* +* e = |gamma[q] - gamma'[q]| / (1 + |gamma[q]|), +* +* where gamma'[q] is the weight for xN[q] on entry to the routine, +* and returns e on exit. (If e happens to be large enough, the calling +* program may reset the reference space, since other weights also may +* be inaccurate.) */ + +double spx_update_gamma(SPXLP *lp, SPXSE *se, int p, int q, + const double trow[/*1+n-m*/], const double tcol[/*1+m*/]) +{ int m = lp->m; + int n = lp->n; + int *head = lp->head; + char *refsp = se->refsp; + double *gamma = se->gamma; + double *u = se->work; + int i, j, k, ptr, end; + double gamma_q, delta_q, e, r, s, t1, t2; + xassert(se->valid); + xassert(1 <= p && p <= m); + xassert(1 <= q && q <= n-m); + /* compute gamma[q] in current basis more accurately; also + * compute auxiliary vector u */ + k = head[m+q]; /* x[k] = xN[q] */ + gamma_q = delta_q = (refsp[k] ? 1.0 : 0.0); + for (i = 1; i <= m; i++) + { k = head[i]; /* x[k] = xB[i] */ + if (refsp[k]) + { gamma_q += tcol[i] * tcol[i]; + u[i] = tcol[i]; + } + else + u[i] = 0.0; + } + bfd_btran(lp->bfd, u); + /* compute relative error in gamma[q] */ + e = fabs(gamma_q - gamma[q]) / (1.0 + gamma_q); + /* compute new gamma[q] */ + gamma[q] = gamma_q / (tcol[p] * tcol[p]); + /* compute new gamma[j] for all j != q */ + for (j = 1; j <= n-m; j++) + { if (j == q) + continue; + if (-1e-9 < trow[j] && trow[j] < +1e-9) + { /* T[p,j] is close to zero; gamma[j] is not changed */ + continue; + } + /* compute r[j] = T[p,j] / T[p,q] */ + r = trow[j] / tcol[p]; + /* compute inner product s[j] = N'[j] * u, where N[j] = A[k] + * is constraint matrix column corresponding to xN[j] */ + s = 0.0; + k = head[m+j]; /* x[k] = xN[j] */ + ptr = lp->A_ptr[k]; + end = lp->A_ptr[k+1]; + for (; ptr < end; ptr++) + s += lp->A_val[ptr] * u[lp->A_ind[ptr]]; + /* compute new gamma[j] */ + t1 = gamma[j] + r * (r * gamma_q + s + s); + t2 = (refsp[k] ? 1.0 : 0.0) + delta_q * r * r; + gamma[j] = (t1 >= t2 ? t1 : t2); + } + return e; +} + +/*********************************************************************** +* spx_free_se - deallocate pricing data block +* +* This routine deallocates the memory used for arrays in the pricing +* data block. */ + +void spx_free_se(SPXLP *lp, SPXSE *se) +{ xassert(lp == lp); + tfree(se->refsp); + tfree(se->gamma); + tfree(se->work); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spxchuzc.h b/resources/3rdparty/glpk-4.57/src/simplex/spxchuzc.h new file mode 100644 index 000000000..c09cca9aa --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spxchuzc.h @@ -0,0 +1,85 @@ +/* spxchuzc.h */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef SPXCHUZC_H +#define SPXCHUZC_H + +#include "spxlp.h" + +#define spx_chuzc_sel _glp_spx_chuzc_sel +int spx_chuzc_sel(SPXLP *lp, const double d[/*1+n-m*/], double tol, + double tol1, int list[/*1+n-m*/]); +/* select eligible non-basic variables */ + +#define spx_chuzc_std _glp_spx_chuzc_std +int spx_chuzc_std(SPXLP *lp, const double d[/*1+n-m*/], int num, + const int list[]); +/* choose non-basic variable (Dantzig's rule) */ + +typedef struct SPXSE SPXSE; + +struct SPXSE +{ /* projected steepest edge and Devex pricing data block */ + int valid; + /* content validity flag */ + char *refsp; /* char refsp[1+n]; */ + /* refsp[0] is not used; + * refsp[k], 1 <= k <= n, is the flag meaning that variable x[k] + * is in the reference space */ + double *gamma; /* double gamma[1+n-m]; */ + /* gamma[0] is not used; + * gamma[j], 1 <= j <= n-m, is the weight for reduced cost d[j] + * of non-basic variable xN[j] in the current basis */ + double *work; /* double work[1+m]; */ + /* working array */ +}; + +#define spx_alloc_se _glp_spx_alloc_se +void spx_alloc_se(SPXLP *lp, SPXSE *se); +/* allocate pricing data block */ + +#define spx_reset_refsp _glp_spx_reset_refsp +void spx_reset_refsp(SPXLP *lp, SPXSE *se); +/* reset reference space */ + +#define spx_eval_gamma_j _glp_spx_eval_gamma_j +double spx_eval_gamma_j(SPXLP *lp, SPXSE *se, int j); +/* compute projeted steepest edge weight directly */ + +#define spx_chuzc_pse _glp_spx_chuzc_pse +int spx_chuzc_pse(SPXLP *lp, SPXSE *se, const double d[/*1+n-m*/], + int num, const int list[]); +/* choose non-basic variable (projected steepest edge) */ + +#define spx_update_gamma _glp_spx_update_gamma +double spx_update_gamma(SPXLP *lp, SPXSE *se, int p, int q, + const double trow[/*1+n-m*/], const double tcol[/*1+m*/]); +/* update projected steepest edge weights exactly */ + +#define spx_free_se _glp_spx_free_se +void spx_free_se(SPXLP *lp, SPXSE *se); +/* deallocate pricing data block */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spxchuzr.c b/resources/3rdparty/glpk-4.57/src/simplex/spxchuzr.c new file mode 100644 index 000000000..49db8bd14 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spxchuzr.c @@ -0,0 +1,388 @@ +/* spxchuzr.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "spxchuzr.h" + +/*********************************************************************** +* spx_chuzr_std - choose basic variable (textbook ratio test) +* +* This routine implements an improved textbook ratio test to choose +* basic variable xB[p]. +* +* The parameter phase specifies the search phase: +* +* 1 - searching for feasible basic solution. In this case the routine +* uses artificial bounds of basic variables that correspond to +* breakpoints of the penalty function: +* +* ( lB[i], if cB[i] = 0 +* ( +* lB'[i] = { uB[i], if cB[i] > 0 +* ( +* ( -inf, if cB[i] < 0 +* +* ( uB[i], if cB[i] = 0 +* ( +* uB'[i] = { +inf, if cB[i] > 0 +* ( +* ( lB[i], if cB[i] < 0 +* +* where lB[i] and uB[i] are original bounds of variable xB[i], +* cB[i] is the penalty (objective) coefficient of that variable. +* +* 2 - searching for optimal basic solution. In this case the routine +* uses original bounds of basic variables. +* +* Current values of basic variables should be placed in the array +* locations beta[1], ..., beta[m]. +* +* The parameter 1 <= q <= n-m specifies the index of non-basic +* variable xN[q] chosen. +* +* The parameter s specifies the direction in which xN[q] changes: +* s = +1.0 means xN[q] increases, and s = -1.0 means xN[q] decreases. +* (Thus, the corresponding ray parameter is theta = s (xN[q] - f[q]), +* where f[q] is the active bound of xN[q] in the current basis.) +* +* Elements of q-th simplex table column T[q] = (t[i,q]) corresponding +* to non-basic variable xN[q] should be placed in the array locations +* tcol[1], ..., tcol[m]. +* +* The parameter tol_piv specifies a tolerance for elements of the +* simplex table column T[q]. If |t[i,q]| < tol_piv, basic variable +* xB[i] is skipped, i.e. it is assumed that it does not depend on the +* ray parameter theta. +* +* The parameters tol and tol1 specify tolerances used to increase the +* choice freedom by simulating an artificial degeneracy as follows. +* If beta[i] <= lB[i] + delta[i], where delta[i] = tol + tol1 |lB[i]|, +* it is assumed that beta[i] is exactly the same as lB[i]. Similarly, +* if beta[i] >= uB[i] - delta[i], where delta[i] = tol + tol1 |uB[i]|, +* it is assumed that beta[i] is exactly the same as uB[i]. +* +* The routine determines the index 1 <= p <= m of basic variable xB[p] +* that reaches its (lower or upper) bound first on increasing the ray +* parameter theta, stores the bound flag (0 - lower bound or fixed +* value, 1 - upper bound) to the location pointed to by the pointer +* p_flag, and returns the index p. If non-basic variable xN[q] is +* double-bounded and reaches its opposite bound first, the routine +* returns (-1). And if the ray parameter may increase unlimitedly, the +* routine returns zero. +* +* Should note that the bound flag stored to the location pointed to by +* p_flag corresponds to the original (not artficial) bound of variable +* xB[p] and defines the active bound flag lp->flag[q] to be set in the +* adjacent basis for that basic variable. */ + +int spx_chuzr_std(SPXLP *lp, int phase, const double beta[/*1+m*/], + int q, double s, const double tcol[/*1+m*/], int *p_flag, + double tol_piv, double tol, double tol1) +{ int m = lp->m; + int n = lp->n; + double *c = lp->c; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + int i, i_flag, k, p; + double alfa, biga, delta, lk, uk, teta, teta_min; + xassert(phase == 1 || phase == 2); + xassert(1 <= q && q <= n-m); + xassert(s == +1.0 || s == -1.0); + /* determine initial teta_min */ + k = head[m+q]; /* x[k] = xN[q] */ + if (l[k] == -DBL_MAX || u[k] == +DBL_MAX) + { /* xN[q] has no opposite bound */ + p = 0, *p_flag = 0, teta_min = DBL_MAX, biga = 0.0; + } + else + { /* xN[q] have both lower and upper bounds */ + p = -1, *p_flag = 0, teta_min = fabs(l[k] - u[k]), biga = 1.0; + } + /* walk thru the list of basic variables */ + for (i = 1; i <= m; i++) + { k = head[i]; /* x[k] = xB[i] */ + /* determine alfa such that delta xB[i] = alfa * teta */ + alfa = s * tcol[i]; + if (alfa <= -tol_piv) + { /* xB[i] decreases */ + /* determine actual lower bound of xB[i] */ + if (phase == 1 && c[k] < 0.0) + { /* xB[i] has no actual lower bound */ + continue; + } + else if (phase == 1 && c[k] > 0.0) + { /* actual lower bound of xB[i] is its upper bound */ + lk = u[k]; + xassert(lk != +DBL_MAX); + i_flag = 1; + } + else + { /* actual lower bound of xB[i] is its original bound */ + lk = l[k]; + if (lk == -DBL_MAX) + continue; + i_flag = 0; + } + /* determine teta on which xB[i] reaches its lower bound */ + delta = tol + tol1 * (lk >= 0.0 ? +lk : -lk); + if (beta[i] <= lk + delta) + teta = 0.0; + else + teta = (lk - beta[i]) / alfa; + } + else if (alfa >= +tol_piv) + { /* xB[i] increases */ + /* determine actual upper bound of xB[i] */ + if (phase == 1 && c[k] < 0.0) + { /* actual upper bound of xB[i] is its lower bound */ + uk = l[k]; + xassert(uk != -DBL_MAX); + i_flag = 0; + } + else if (phase == 1 && c[k] > 0.0) + { /* xB[i] has no actual upper bound */ + continue; + } + else + { /* actual upper bound of xB[i] is its original bound */ + uk = u[k]; + if (uk == +DBL_MAX) + continue; + i_flag = 1; + } + /* determine teta on which xB[i] reaches its upper bound */ + delta = tol + tol1 * (uk >= 0.0 ? +uk : -uk); + if (beta[i] >= uk - delta) + teta = 0.0; + else + teta = (uk - beta[i]) / alfa; + } + else + { /* xB[i] does not depend on teta */ + continue; + } + /* choose basic variable xB[p] for which teta is minimal */ + xassert(teta >= 0.0); + alfa = (alfa >= 0.0 ? +alfa : -alfa); + if (teta_min > teta || (teta_min == teta && biga < alfa)) + p = i, *p_flag = i_flag, teta_min = teta, biga = alfa; + } + /* if xB[p] is fixed variable, adjust its bound flag */ + if (p > 0) + { k = head[p]; + if (l[k] == u[k]) + *p_flag = 0; + } + return p; +} + +/*********************************************************************** +* spx_chuzr_harris - choose basic variable (Harris' ratio test) +* +* This routine implements Harris' ratio test to choose basic variable +* xB[p]. +* +* All the parameters, except tol and tol1, as well as the returned +* value have the same meaning as for the routine spx_chuzr_std (see +* above). +* +* The parameters tol and tol1 specify tolerances on bound violations +* for basic variables. For the lower bound of basic variable xB[i] the +* tolerance is delta[i] = tol + tol1 |lB[i]|, and for the upper bound +* the tolerance is delta[i] = tol + tol1 |uB[i]|. */ + +int spx_chuzr_harris(SPXLP *lp, int phase, const double beta[/*1+m*/], + int q, double s, const double tcol[/*1+m*/], int *p_flag, + double tol_piv, double tol, double tol1) +{ int m = lp->m; + int n = lp->n; + double *c = lp->c; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + int i, i_flag, k, p; + double alfa, biga, delta, lk, uk, teta, teta_min; + xassert(phase == 1 || phase == 2); + xassert(1 <= q && q <= n-m); + xassert(s == +1.0 || s == -1.0); + /*--------------------------------------------------------------*/ + /* first pass: determine teta_min for relaxed bounds */ + /*--------------------------------------------------------------*/ + teta_min = DBL_MAX; + /* walk thru the list of basic variables */ + for (i = 1; i <= m; i++) + { k = head[i]; /* x[k] = xB[i] */ + /* determine alfa such that delta xB[i] = alfa * teta */ + alfa = s * tcol[i]; + if (alfa <= -tol_piv) + { /* xB[i] decreases */ + /* determine actual lower bound of xB[i] */ + if (phase == 1 && c[k] < 0.0) + { /* xB[i] has no actual lower bound */ + continue; + } + else if (phase == 1 && c[k] > 0.0) + { /* actual lower bound of xB[i] is its upper bound */ + lk = u[k]; + xassert(lk != +DBL_MAX); + } + else + { /* actual lower bound of xB[i] is its original bound */ + lk = l[k]; + if (lk == -DBL_MAX) + continue; + } + /* determine teta on which xB[i] reaches its relaxed lower + * bound */ + delta = tol + tol1 * (lk >= 0.0 ? +lk : -lk); + if (beta[i] < lk) + teta = - delta / alfa; + else + teta = ((lk - delta) - beta[i]) / alfa; + } + else if (alfa >= +tol_piv) + { /* xB[i] increases */ + /* determine actual upper bound of xB[i] */ + if (phase == 1 && c[k] < 0.0) + { /* actual upper bound of xB[i] is its lower bound */ + uk = l[k]; + xassert(uk != -DBL_MAX); + } + else if (phase == 1 && c[k] > 0.0) + { /* xB[i] has no actual upper bound */ + continue; + } + else + { /* actual upper bound of xB[i] is its original bound */ + uk = u[k]; + if (uk == +DBL_MAX) + continue; + } + /* determine teta on which xB[i] reaches its relaxed upper + * bound */ + delta = tol + tol1 * (uk >= 0.0 ? +uk : -uk); + if (beta[i] > uk) + teta = + delta / alfa; + else + teta = ((uk + delta) - beta[i]) / alfa; + } + else + { /* xB[i] does not depend on teta */ + continue; + } + xassert(teta >= 0.0); + if (teta_min > teta) + teta_min = teta; + } + /*--------------------------------------------------------------*/ + /* second pass: choose basic variable xB[p] */ + /*--------------------------------------------------------------*/ + k = head[m+q]; /* x[k] = xN[q] */ + if (l[k] != -DBL_MAX && u[k] != +DBL_MAX) + { /* xN[q] has both lower and upper bounds */ + if (fabs(l[k] - u[k]) <= teta_min) + { /* and reaches its opposite bound */ + p = -1, *p_flag = 0; + goto done; + } + } + if (teta_min == DBL_MAX) + { /* teta may increase unlimitedly */ + p = 0, *p_flag = 0; + goto done; + } + /* nothing is chosen so far */ + p = 0, *p_flag = 0, biga = 0.0; + /* walk thru the list of basic variables */ + for (i = 1; i <= m; i++) + { k = head[i]; /* x[k] = xB[i] */ + /* determine alfa such that delta xB[i] = alfa * teta */ + alfa = s * tcol[i]; + if (alfa <= -tol_piv) + { /* xB[i] decreases */ + /* determine actual lower bound of xB[i] */ + if (phase == 1 && c[k] < 0.0) + { /* xB[i] has no actual lower bound */ + continue; + } + else if (phase == 1 && c[k] > 0.0) + { /* actual lower bound of xB[i] is its upper bound */ + lk = u[k]; + xassert(lk != +DBL_MAX); + i_flag = 1; + } + else + { /* actual lower bound of xB[i] is its original bound */ + lk = l[k]; + if (lk == -DBL_MAX) + continue; + i_flag = 0; + } + /* determine teta on which xB[i] reaches its lower bound */ + teta = (lk - beta[i]) / alfa; + } + else if (alfa >= +tol_piv) + { /* xB[i] increases */ + /* determine actual upper bound of xB[i] */ + if (phase == 1 && c[k] < 0.0) + { /* actual upper bound of xB[i] is its lower bound */ + uk = l[k]; + xassert(uk != -DBL_MAX); + i_flag = 0; + } + else if (phase == 1 && c[k] > 0.0) + { /* xB[i] has no actual upper bound */ + continue; + } + else + { /* actual upper bound of xB[i] is its original bound */ + uk = u[k]; + if (uk == +DBL_MAX) + continue; + i_flag = 1; + } + /* determine teta on which xB[i] reaches its upper bound */ + teta = (uk - beta[i]) / alfa; + } + else + { /* xB[i] does not depend on teta */ + continue; + } + /* choose basic variable for which teta is not greater than + * teta_min determined for relaxed bounds and which has best + * (largest in magnitude) pivot */ + alfa = (alfa >= 0.0 ? +alfa : -alfa); + if (teta <= teta_min && biga < alfa) + p = i, *p_flag = i_flag, biga = alfa; + } + /* something must be chosen */ + xassert(1 <= p && p <= m); + /* if xB[p] is fixed variable, adjust its bound flag */ + k = head[p]; + if (l[k] == u[k]) + *p_flag = 0; +done: return p; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spxchuzr.h b/resources/3rdparty/glpk-4.57/src/simplex/spxchuzr.h new file mode 100644 index 000000000..74f6e444a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spxchuzr.h @@ -0,0 +1,43 @@ +/* spxchuzr.h */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef SPXCHUZR_H +#define SPXCHUZR_H + +#include "spxlp.h" + +#define spx_chuzr_std _glp_spx_chuzr_std +int spx_chuzr_std(SPXLP *lp, int phase, const double beta[/*1+m*/], + int q, double s, const double tcol[/*1+m*/], int *p_flag, + double tol_piv, double tol, double tol1); +/* choose basic variable (textbook ratio test) */ + +#define spx_chuzr_harris _glp_spx_chuzr_harris +int spx_chuzr_harris(SPXLP *lp, int phase, const double beta[/*1+m*/], + int q, double s, const double tcol[/*1+m*/], int *p_flag, + double tol_piv, double tol, double tol1); +/* choose basic variable (Harris' ratio test) */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spxlp.c b/resources/3rdparty/glpk-4.57/src/simplex/spxlp.c new file mode 100644 index 000000000..fe788d84d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spxlp.c @@ -0,0 +1,674 @@ +/* spxlp.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "spxlp.h" + +/*********************************************************************** +* spx_factorize - compute factorization of current basis matrix +* +* This routine computes factorization of the current basis matrix B. +* +* If the factorization has been successfully computed, the routine +* validates it and returns zero. Otherwise, the routine invalidates +* the factorization and returns the code provided by the factorization +* driver (bfd_factorize). */ + +static int jth_col(void *info, int j, int ind[], double val[]) +{ /* provide column B[j] */ + SPXLP *lp = info; + int m = lp->m; + int *A_ptr = lp->A_ptr; + int *head = lp->head; + int k, ptr, len; + xassert(1 <= j && j <= m); + k = head[j]; /* x[k] = xB[j] */ + ptr = A_ptr[k]; + len = A_ptr[k+1] - ptr; + memcpy(&ind[1], &lp->A_ind[ptr], len * sizeof(int)); + memcpy(&val[1], &lp->A_val[ptr], len * sizeof(double)); + return len; +} + +int spx_factorize(SPXLP *lp) +{ int ret; + ret = bfd_factorize(lp->bfd, lp->m, jth_col, lp); + lp->valid = (ret == 0); + return ret; +} + +/*********************************************************************** +* spx_eval_beta - compute current values of basic variables +* +* This routine computes vector beta = (beta[i]) of current values of +* basic variables xB = (xB[i]). (Factorization of the current basis +* matrix should be valid.) +* +* First the routine computes a modified vector of right-hand sides: +* +* n-m +* y = b - N * f = b - sum N[j] * f[j], +* j=1 +* +* where b = (b[i]) is the original vector of right-hand sides, N is +* a matrix composed from columns of the original constraint matrix A, +* which (columns) correspond to non-basic variables, f = (f[j]) is the +* vector of active bounds of non-basic variables xN = (xN[j]), +* N[j] = A[k] is a column of matrix A corresponding to non-basic +* variable xN[j] = x[k], f[j] is current active bound lN[j] = l[k] or +* uN[j] = u[k] of non-basic variable xN[j] = x[k]. The matrix-vector +* product N * f is computed as a linear combination of columns of N, +* so if f[j] = 0, column N[j] can be skipped. +* +* Then the routine performs FTRAN to compute the vector beta: +* +* beta = inv(B) * y. +* +* On exit the routine stores components of the vector beta to array +* locations beta[1], ..., beta[m]. */ + +void spx_eval_beta(SPXLP *lp, double beta[/*1+m*/]) +{ int m = lp->m; + int n = lp->n; + int *A_ptr = lp->A_ptr; + int *A_ind = lp->A_ind; + double *A_val = lp->A_val; + double *b = lp->b; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + char *flag = lp->flag; + int j, k, ptr, end; + double fj, *y; + /* compute y = b - N * xN */ + /* y := b */ + y = beta; + memcpy(&y[1], &b[1], m * sizeof(double)); + /* y := y - N * f */ + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + /* f[j] := active bound of xN[j] */ + fj = flag[j] ? u[k] : l[k]; + if (fj == 0.0 || fj == -DBL_MAX) + { /* either xN[j] has zero active bound or it is unbounded; + * in the latter case its value is assumed to be zero */ + continue; + } + /* y := y - N[j] * f[j] */ + ptr = A_ptr[k]; + end = A_ptr[k+1]; + for (; ptr < end; ptr++) + y[A_ind[ptr]] -= A_val[ptr] * fj; + } + /* compute beta = inv(B) * y */ + xassert(lp->valid); + bfd_ftran(lp->bfd, beta); + return; +} + +/*********************************************************************** +* spx_eval_obj - compute current value of objective function +* +* This routine computes the value of the objective function in the +* current basic solution: +* +* z = cB'* beta + cN'* f + c[0] = +* +* m n-m +* = sum cB[i] * beta[i] + sum cN[j] * f[j] + c[0], +* i=1 j=1 +* +* where cB = (cB[i]) is the vector of objective coefficients at basic +* variables, beta = (beta[i]) is the vector of current values of basic +* variables, cN = (cN[j]) is the vector of objective coefficients at +* non-basic variables, f = (f[j]) is the vector of current active +* bounds of non-basic variables, c[0] is the constant term of the +* objective function. +* +* It as assumed that components of the vector beta are stored in the +* array locations beta[1], ..., beta[m]. */ + +double spx_eval_obj(SPXLP *lp, const double beta[/*1+m*/]) +{ int m = lp->m; + int n = lp->n; + double *c = lp->c; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + char *flag = lp->flag; + int i, j, k; + double fj, z; + /* compute z = cB'* beta + cN'* f + c0 */ + /* z := c0 */ + z = c[0]; + /* z := z + cB'* beta */ + for (i = 1; i <= m; i++) + { k = head[i]; /* x[k] = xB[i] */ + z += c[k] * beta[i]; + } + /* z := z + cN'* f */ + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + /* f[j] := active bound of xN[j] */ + fj = flag[j] ? u[k] : l[k]; + if (fj == 0.0 || fj == -DBL_MAX) + { /* either xN[j] has zero active bound or it is unbounded; + * in the latter case its value is assumed to be zero */ + continue; + } + z += c[k] * fj; + } + return z; +} + +/*********************************************************************** +* spx_eval_pi - compute simplex multipliers in current basis +* +* This routine computes vector pi = (pi[i]) of simplex multipliers in +* the current basis. (Factorization of the current basis matrix should +* be valid.) +* +* The vector pi is computed by performing BTRAN: +* +* pi = inv(B') * cB, +* +* where cB = (cB[i]) is the vector of objective coefficients at basic +* variables xB = (xB[i]). +* +* On exit components of vector pi are stored in the array locations +* pi[1], ..., pi[m]. */ + +void spx_eval_pi(SPXLP *lp, double pi[/*1+m*/]) +{ int m = lp->m; + double *c = lp->c; + int *head = lp->head; + int i; + double *cB; + /* construct cB */ + cB = pi; + for (i = 1; i <= m; i++) + cB[i] = c[head[i]]; + /* compute pi = inv(B) * cB */ + bfd_btran(lp->bfd, pi); + return; +} + +/*********************************************************************** +* spx_eval_dj - compute reduced cost of j-th non-basic variable +* +* This routine computes reduced cost d[j] of non-basic variable +* xN[j] = x[k], 1 <= j <= n-m, in the current basic solution: +* +* d[j] = c[k] - A'[k] * pi, +* +* where c[k] is the objective coefficient at x[k], A[k] is k-th column +* of the constraint matrix, pi is the vector of simplex multipliers in +* the current basis. +* +* It as assumed that components of the vector pi are stored in the +* array locations pi[1], ..., pi[m]. */ + +double spx_eval_dj(SPXLP *lp, const double pi[/*1+m*/], int j) +{ int m = lp->m; + int n = lp->n; + int *A_ptr = lp->A_ptr; + int *A_ind = lp->A_ind; + double *A_val = lp->A_val; + int k, ptr, end; + double dj; + xassert(1 <= j && j <= n-m); + k = lp->head[m+j]; /* x[k] = xN[j] */ + /* dj := c[k] */ + dj = lp->c[k]; + /* dj := dj - A'[k] * pi */ + ptr = A_ptr[k]; + end = A_ptr[k+1]; + for (; ptr < end; ptr++) + dj -= A_val[ptr] * pi[A_ind[ptr]]; + return dj; +} + +/*********************************************************************** +* spx_eval_tcol - compute j-th column of simplex table +* +* This routine computes j-th column of the current simplex table +* T = (T[i,j]) = - inv(B) * N, 1 <= j <= n-m. (Factorization of the +* current basis matrix should be valid.) +* +* The simplex table column is computed by performing FTRAN: +* +* tcol = - inv(B) * N[j], +* +* where B is the current basis matrix, N[j] = A[k] is a column of the +* constraint matrix corresponding to non-basic variable xN[j] = x[k]. +* +* On exit components of the simplex table column are stored in the +* array locations tcol[1], ... tcol[m]. */ + +void spx_eval_tcol(SPXLP *lp, int j, double tcol[/*1+m*/]) +{ int m = lp->m; + int n = lp->n; + int *A_ptr = lp->A_ptr; + int *A_ind = lp->A_ind; + double *A_val = lp->A_val; + int *head = lp->head; + int i, k, ptr, end; + xassert(1 <= j && j <= n-m); + k = head[m+j]; /* x[k] = xN[j] */ + /* compute tcol = - inv(B) * N[j] */ + for (i = 1; i <= m; i++) + tcol[i] = 0.0; + ptr = A_ptr[k]; + end = A_ptr[k+1]; + for (; ptr < end; ptr++) + tcol[A_ind[ptr]] = -A_val[ptr]; + bfd_ftran(lp->bfd, tcol); + return; +} + +/*********************************************************************** +* spx_eval_rho - compute i-th row of basis matrix inverse +* +* This routine computes i-th row of the matrix inv(B), where B is +* the current basis matrix, 1 <= i <= m. (Factorization of the current +* basis matrix should be valid.) +* +* The inverse row is computed by performing BTRAN: +* +* rho = inv(B') * e[i], +* +* where e[i] is i-th column of unity matrix. +* +* On exit components of the row are stored in the array locations +* row[1], ..., row[m]. */ + +void spx_eval_rho(SPXLP *lp, int i, double rho[/*1+m*/]) +{ int m = lp->m; + int j; + xassert(1 <= i && i <= m); + /* compute rho = inv(B') * e[i] */ + for (j = 1; j <= m; j++) + rho[j] = 0.0; + rho[i] = 1.0; + bfd_btran(lp->bfd, rho); + return; +} + +/*********************************************************************** +* spx_eval_tij - compute element T[i,j] of simplex table +* +* This routine computes element T[i,j] of the current simplex table +* T = - inv(B) * N, 1 <= i <= m, 1 <= j <= n-m, with the following +* formula: +* +* T[i,j] = - N'[j] * rho, (1) +* +* where N[j] = A[k] is a column of the constraint matrix corresponding +* to non-basic variable xN[j] = x[k], rho is i-th row of the inverse +* matrix inv(B). +* +* It as assumed that components of the inverse row rho = (rho[j]) are +* stored in the array locations rho[1], ..., rho[m]. */ + +double spx_eval_tij(SPXLP *lp, const double rho[/*1+m*/], int j) +{ int m = lp->m; + int n = lp->n; + int *A_ptr = lp->A_ptr; + int *A_ind = lp->A_ind; + double *A_val = lp->A_val; + int k, ptr, end; + double tij; + xassert(1 <= j && j <= n-m); + k = lp->head[m+j]; /* x[k] = xN[j] */ + /* compute t[i,j] = - N'[j] * pi */ + tij = 0.0; + ptr = A_ptr[k]; + end = A_ptr[k+1]; + for (; ptr < end; ptr++) + tij -= A_val[ptr] * rho[A_ind[ptr]]; + return tij; +} + +/*********************************************************************** +* spx_eval_trow - compute i-th row of simplex table +* +* This routine computes i-th row of the current simplex table +* T = (T[i,j]) = - inv(B) * N, 1 <= i <= m. +* +* Elements of the row T[i] = (T[i,j]), j = 1, ..., n-m, are computed +* directly with the routine spx_eval_tij. +* +* The vector rho = (rho[j]), which is i-th row of the basis inverse +* inv(B), should be previously computed with the routine spx_eval_rho. +* It is assumed that elements of this vector are stored in the array +* locations rho[1], ..., rho[m]. +* +* On exit components of the simplex table row are stored in the array +* locations trow[1], ... trow[n-m]. +* +* NOTE: For testing/debugging only. */ + +void spx_eval_trow(SPXLP *lp, const double rho[/*1+m*/], double + trow[/*1+n-m*/]) +{ int m = lp->m; + int n = lp->n; + int j; + for (j = 1; j <= n-m; j++) + trow[j] = spx_eval_tij(lp, rho, j); + return; +} + +/*********************************************************************** +* spx_update_beta - update values of basic variables +* +* This routine updates the vector beta = (beta[i]) of values of basic +* variables xB = (xB[i]) for the adjacent basis. +* +* On entry to the routine components of the vector beta in the current +* basis should be placed in array locations beta[1], ..., beta[m]. +* +* The parameter 1 <= p <= m specifies basic variable xB[p] which +* becomes non-basic variable xN[q] in the adjacent basis. The special +* case p < 0 means that non-basic variable xN[q] goes from its current +* active bound to opposite one in the adjacent basis. +* +* If the flag p_flag is set, the active bound of xB[p] in the adjacent +* basis is set to its upper bound. (In this case xB[p] should have its +* upper bound and should not be fixed.) +* +* The parameter 1 <= q <= n-m specifies non-basic variable xN[q] which +* becomes basic variable xB[p] in the adjacent basis (if 1 <= p <= m), +* or goes to its opposite bound (if p < 0). (In the latter case xN[q] +* should have both lower and upper bounds and should not be fixed.) +* +* It is assumed that the array tcol contains elements of q-th (pivot) +* column T[q] of the simple table in locations tcol[1], ..., tcol[m]. +* (This column should be computed for the current basis.) +* +* First, the routine determines the increment of basic variable xB[p] +* in the adjacent basis (but only if 1 <= p <= m): +* +* ( - beta[p], if -inf < xB[p] < +inf +* ( +* delta xB[p] = { lB[p] - beta[p], if p_flag = 0 +* ( +* ( uB[p] - beta[p], if p_flag = 1 +* +* where beta[p] is the value of xB[p] in the current basis, lB[p] and +* uB[p] are its lower and upper bounds. Then, the routine determines +* the increment of non-basic variable xN[q] in the adjacent basis: +* +* ( delta xB[p] / T[p,q], if 1 <= p <= m +* ( +* delta xN[q] = { uN[q] - lN[q], if p < 0 and f[q] = lN[q] +* ( +* ( lN[q] - uN[q], if p < 0 and f[q] = uN[q] +* +* where T[p,q] is the pivot element of the simplex table, f[q] is the +* active bound of xN[q] in the current basis. +* +* If 1 <= p <= m, in the adjacent basis xN[q] becomes xB[p], so: +* +* new beta[p] = f[q] + delta xN[q]. +* +* Values of other basic variables xB[i] for 1 <= i <= m, i != p, are +* updated as follows: +* +* new beta[i] = beta[i] + T[i,q] * delta xN[q]. +* +* On exit the routine stores updated components of the vector beta to +* the same locations, where the input vector beta was stored. */ + +void spx_update_beta(SPXLP *lp, double beta[/*1+m*/], int p, + int p_flag, int q, const double tcol[/*1+m*/]) +{ int m = lp->m; + int n = lp->n; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + char *flag = lp->flag; + int i, k; + double delta_p, delta_q; + if (p < 0) + { /* special case: xN[q] goes to its opposite bound */ + xassert(1 <= q && q <= n-m); + /* xN[q] should be double-bounded variable */ + k = head[m+q]; /* x[k] = xN[q] */ + xassert(l[k] != -DBL_MAX && u[k] != +DBL_MAX && l[k] != u[k]); + /* determine delta xN[q] */ + if (flag[q]) + { /* xN[q] goes from its upper bound to its lower bound */ + delta_q = l[k] - u[k]; + } + else + { /* xN[q] goes from its lower bound to its upper bound */ + delta_q = u[k] - l[k]; + } + } + else + { /* xB[p] leaves the basis, xN[q] enters the basis */ + xassert(1 <= p && p <= m); + xassert(1 <= q && q <= n-m); + /* determine delta xB[p] */ + k = head[p]; /* x[k] = xB[p] */ + if (p_flag) + { /* xB[p] goes to its upper bound */ + xassert(l[k] != u[k] && u[k] != +DBL_MAX); + delta_p = u[k] - beta[p]; + } + else if (l[k] == -DBL_MAX) + { /* unbounded xB[p] becomes non-basic (unusual case) */ + xassert(u[k] == +DBL_MAX); + delta_p = 0.0 - beta[p]; + } + else + { /* xB[p] goes to its lower bound or becomes fixed */ + delta_p = l[k] - beta[p]; + } + /* determine delta xN[q] */ + delta_q = delta_p / tcol[p]; + /* compute new beta[p], which is the value of xN[q] in the + * adjacent basis */ + k = head[m+q]; /* x[k] = xN[q] */ + if (flag[q]) + { /* xN[q] has its upper bound active */ + xassert(l[k] != u[k] && u[k] != +DBL_MAX); + beta[p] = u[k] + delta_q; + } + else if (l[k] == -DBL_MAX) + { /* xN[q] is non-basic unbounded variable */ + xassert(u[k] == +DBL_MAX); + beta[p] = 0.0 + delta_q; + } + else + { /* xN[q] has its lower bound active or is fixed (latter + * case is unusual) */ + beta[p] = l[k] + delta_q; + } + } + /* compute new beta[i] for all i != p */ + for (i = 1; i <= m; i++) + { if (i != p) + beta[i] += tcol[i] * delta_q; + } + return; +} + +/*********************************************************************** +* spx_update_d - update reduced costs of non-basic variables +* +* This routine updates the vector d = (d[j]) of reduced costs of +* non-basic variables xN = (xN[j]) for the adjacent basis. +* +* On entry to the routine components of the vector d in the current +* basis should be placed in locations d[1], ..., d[n-m]. +* +* The parameter 1 <= p <= m specifies basic variable xB[p] which +* becomes non-basic variable xN[q] in the adjacent basis. +* +* The parameter 1 <= q <= n-m specified non-basic variable xN[q] which +* becomes basic variable xB[p] in the adjacent basis. +* +* It is assumed that the array trow contains elements of p-th (pivot) +* row T'[p] of the simplex table in locations trow[1], ..., trow[n-m]. +* It is also assumed that the array tcol contains elements of q-th +* (pivot) column T[q] of the simple table in locations tcol[1], ..., +* tcol[m]. (These row and column should be computed for the current +* basis.) +* +* First, the routine computes more accurate reduced cost d[q] in the +* current basis using q-th column of the simplex table: +* +* n-m +* d[q] = cN[q] + sum t[i,q] * cB[i], +* i=1 +* +* where cN[q] and cB[i] are objective coefficients at variables xN[q] +* and xB[i], resp. The routine also computes the relative error: +* +* e = |d[q] - d'[q]| / (1 + |d[q]|), +* +* where d'[q] is the reduced cost of xN[q] on entry to the routine, +* and returns e on exit. (If e happens to be large enough, the calling +* program may compute the reduced costs directly, since other reduced +* costs also may be inaccurate.) +* +* In the adjacent basis xB[p] becomes xN[q], so: +* +* new d[q] = d[q] / T[p,q], +* +* where T[p,q] is the pivot element of the simplex table (it is taken +* from column T[q] as more accurate). Reduced costs of other non-basic +* variables xN[j] for 1 <= j <= n-m, j != q, are updated as follows: +* +* new d[j] = d[j] + T[p,j] * new d[q]. +* +* On exit the routine stores updated components of the vector d to the +* same locations, where the input vector d was stored. */ + +double spx_update_d(SPXLP *lp, double d[/*1+n-m*/], int p, int q, + const double trow[/*1+n-m*/], const double tcol[/*1+m*/]) +{ int m = lp->m; + int n = lp->n; + double *c = lp->c; + int *head = lp->head; + int i, j, k; + double dq, e; + xassert(1 <= p && p <= m); + xassert(1 <= q && q <= n); + /* compute d[q] in current basis more accurately */ + k = head[m+q]; /* x[k] = xN[q] */ + dq = c[k]; + for (i = 1; i <= m; i++) + dq += tcol[i] * c[head[i]]; + /* compute relative error in d[q] */ + e = fabs(dq - d[q]) / (1.0 + fabs(dq)); + /* compute new d[q], which is the reduced cost of xB[p] in the + * adjacent basis */ + d[q] = (dq /= tcol[p]); + /* compute new d[j] for all j != q */ + for (j = 1; j <= n-m; j++) + { if (j != q) + d[j] -= trow[j] * dq; + } + return e; +} + +/*********************************************************************** +* spx_change_basis - change current basis to adjacent one +* +* This routine changes the current basis to the adjacent one making +* necessary changes in lp->head and lp->flag members. +* +* The parameters p, p_flag, and q have the same meaning as for the +* routine spx_update_beta. */ + +void spx_change_basis(SPXLP *lp, int p, int p_flag, int q) +{ int m = lp->m; + int n = lp->n; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + char *flag = lp->flag; + int k; + if (p < 0) + { /* special case: xN[q] goes to its opposite bound */ + xassert(1 <= q && q <= n-m); + /* xN[q] should be double-bounded variable */ + k = head[m+q]; /* x[k] = xN[q] */ + xassert(l[k] != -DBL_MAX && u[k] != +DBL_MAX && l[k] != u[k]); + /* change active bound flag */ + flag[q] = 1 - flag[q]; + } + else + { /* xB[p] leaves the basis, xN[q] enters the basis */ + xassert(1 <= p && p <= m); + xassert(p_flag == 0 || p_flag == 1); + xassert(1 <= q && q <= n-m); + k = head[p]; /* xB[p] = x[k] */ + if (p_flag) + { /* xB[p] goes to its upper bound */ + xassert(l[k] != u[k] && u[k] != +DBL_MAX); + } + /* swap xB[p] and xN[q] in the basis */ + head[p] = head[m+q], head[m+q] = k; + /* and set active bound flag for new xN[q] */ + lp->flag[q] = p_flag; + } + return; +} + +/*********************************************************************** +* spx_update_invb - update factorization of basis matrix +* +* This routine updates factorization of the basis matrix B when i-th +* column of B is replaced by k-th column of the constraint matrix A. +* +* The parameter 1 <= i <= m specifies the number of column of matrix B +* to be replaced by a new column. +* +* The parameter 1 <= k <= n specifies the number of column of matrix A +* to be used for replacement. +* +* If the factorization has been successfully updated, the routine +* validates it and returns zero. Otherwise, the routine invalidates +* the factorization and returns the code provided by the factorization +* driver (bfd_update). */ + +int spx_update_invb(SPXLP *lp, int i, int k) +{ int m = lp->m; + int n = lp->n; + int *A_ptr = lp->A_ptr; + int *A_ind = lp->A_ind; + double *A_val = lp->A_val; + int ptr, len, ret; + xassert(1 <= i && i <= m); + xassert(1 <= k && k <= n); + ptr = A_ptr[k]; + len = A_ptr[k+1] - ptr; + ret = bfd_update(lp->bfd, i, len, &A_ind[ptr-1], &A_val[ptr-1]); + lp->valid = (ret == 0); + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spxlp.h b/resources/3rdparty/glpk-4.57/src/simplex/spxlp.h new file mode 100644 index 000000000..e13528c4c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spxlp.h @@ -0,0 +1,214 @@ +/* spxlp.h */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef SPXLP_H +#define SPXLP_H + +#include "bfd.h" + +/*********************************************************************** +* The structure SPXLP describes LP problem and its current basis. +* +* It is assumed that LP problem has the following formulation (this is +* so called "working format"): +* +* z = c'* x + c0 -> min (1) +* +* A * x = b (2) +* +* l <= x <= u (3) +* +* where: +* +* x = (x[k]) is a n-vector of variables; +* +* z is an objective function; +* +* c = (c[k]) is a n-vector of objective coefficients; +* +* c0 is a constant term of the objective function; +* +* A = (a[i,k]) is a mxn-matrix of constraint coefficients; +* +* b = (b[i]) is a m-vector of right-hand sides; +* +* l = (l[k]) is a n-vector of lower bounds of variables; +* +* u = (u[k]) is a n-vector of upper bounds of variables. +* +* If variable x[k] has no lower (upper) bound, it is formally assumed +* that l[k] = -inf (u[k] = +inf). Variable having no bounds is called +* free (unbounded) variable. If l[k] = u[k], variable x[k] is assumed +* to be fixed. +* +* It is also assumed that matrix A has full row rank: rank(A) = m, +* i.e. all its rows are linearly independent, so m <= n. +* +* The (current) basis is defined by an appropriate permutation matrix +* P of order n such that: +* +* ( xB ) +* P * x = ( ), (4) +* ( xN ) +* +* where xB = (xB[i]) is a m-vector of basic variables, xN = (xN[j]) is +* a (n-m)-vector of non-basic variables. If a non-basic variable xN[j] +* has both lower and upper bounds, there is used an additional flag to +* indicate which bound is active. +* +* From (2) and (4) it follows that: +* +* A * P'* P * x = b <=> B * xB + N * xN = b, (5) +* +* where P' is a matrix transposed to P, and +* +* A * P' = (B | N). (6) +* +* Here B is the basis matrix, which is a square non-singular matrix +* of order m composed from columns of matrix A that correspond to +* basic variables xB, and N is a mx(n-m) matrix composed from columns +* of matrix A that correspond to non-basic variables xN. */ + +typedef struct SPXLP SPXLP; + +struct SPXLP +{ /* LP problem data and its (current) basis */ + int m; + /* number of equality constraints, m > 0 */ + int n; + /* number of variables, n >= m */ + int nnz; + /* number of non-zeros in constraint matrix A */ + /*--------------------------------------------------------------*/ + /* mxn-matrix A of constraint coefficients in sparse column-wise + * format */ + int *A_ptr; /* int A_ptr[1+n+1]; */ + /* A_ptr[0] is not used; + * A_ptr[k], 1 <= k <= n, is starting position of k-th column in + * arrays A_ind and A_val; note that A_ptr[1] is always 1; + * A_ptr[n+1] indicates the position after the last element in + * arrays A_ind and A_val, i.e. A_ptr[n+1] = nnz+1, where nnz is + * the number of non-zero elements in matrix A; + * the length of k-th column (the number of non-zero elements in + * that column) can be calculated as A_ptr[k+1] - A_ptr[k] */ + int *A_ind; /* int A_ind[1+nnz]; */ + /* row indices */ + double *A_val; /* double A_val[1+nnz]; */ + /* non-zero element values (constraint coefficients) */ + /*--------------------------------------------------------------*/ + /* principal vectors of LP formulation */ + double *b; /* double b[1+m]; */ + /* b[0] is not used; + * b[i], 1 <= i <= m, is the right-hand side of i-th equality + * constraint */ + double *c; /* double c[1+n]; */ + /* c[0] is the constant term of the objective function; + * c[k], 1 <= k <= n, is the objective function coefficient at + * variable x[k] */ + double *l; /* double l[1+n]; */ + /* l[0] is not used; + * l[k], 1 <= k <= n, is the lower bound of variable x[k]; + * if x[k] has no lower bound, l[k] = -DBL_MAX */ + double *u; /* double u[1+n]; */ + /* u[0] is not used; + * u[k], 1 <= k <= n, is the upper bound of variable u[k]; + * if x[k] has no upper bound, u[k] = +DBL_MAX; + * note that l[k] = u[k] means that x[k] is fixed variable */ + /*--------------------------------------------------------------*/ + /* LP basis */ + int *head; /* int head[1+n]; */ + /* basis header, which is permutation matrix P (4): + * head[0] is not used; + * head[i] = k means that xB[i] = x[k], 1 <= i <= m; + * head[m+j] = k, means that xN[j] = x[k], 1 <= j <= n-m */ + char *flag; /* char flag[1+n-m]; */ + /* flags of non-basic variables: + * flag[0] is not used; + * flag[j], 1 <= j <= n-m, indicates that non-basic variable + * xN[j] is non-fixed and has its upper bound active */ + /*--------------------------------------------------------------*/ + /* basis matrix B of order m stored in factorized form */ + int valid; + /* factorization validity flag */ + BFD *bfd; + /* driver to factorization of the basis matrix */ +}; + +#define spx_factorize _glp_spx_factorize +int spx_factorize(SPXLP *lp); +/* compute factorization of current basis matrix */ + +#define spx_eval_beta _glp_spx_eval_beta +void spx_eval_beta(SPXLP *lp, double beta[/*1+m*/]); +/* compute values of basic variables */ + +#define spx_eval_obj _glp_spx_eval_obj +double spx_eval_obj(SPXLP *lp, const double beta[/*1+m*/]); +/* compute value of objective function */ + +#define spx_eval_pi _glp_spx_eval_pi +void spx_eval_pi(SPXLP *lp, double pi[/*1+m*/]); +/* compute simplex multipliers */ + +#define spx_eval_dj _glp_spx_eval_dj +double spx_eval_dj(SPXLP *lp, const double pi[/*1+m*/], int j); +/* compute reduced cost of j-th non-basic variable */ + +#define spx_eval_tcol _glp_spx_eval_tcol +void spx_eval_tcol(SPXLP *lp, int j, double tcol[/*1+m*/]); +/* compute j-th column of simplex table */ + +#define spx_eval_rho _glp_spx_eval_rho +void spx_eval_rho(SPXLP *lp, int i, double rho[/*1+m*/]); +/* compute i-th row of basis matrix inverse */ + +#define spx_eval_tij _glp_spx_eval_tij +double spx_eval_tij(SPXLP *lp, const double rho[/*1+m*/], int j); +/* compute element T[i,j] of simplex table */ + +#define spx_eval_trow _glp_spx_eval_trow +void spx_eval_trow(SPXLP *lp, const double rho[/*1+m*/], double + trow[/*1+n-m*/]); +/* compute i-th row of simplex table */ + +#define spx_update_beta _glp_spx_update_beta +void spx_update_beta(SPXLP *lp, double beta[/*1+m*/], int p, + int p_flag, int q, const double tcol[/*1+m*/]); +/* update values of basic variables */ + +#define spx_update_d _glp_spx_update_d +double spx_update_d(SPXLP *lp, double d[/*1+n-m*/], int p, int q, + const double trow[/*1+n-m*/], const double tcol[/*1+m*/]); +/* update reduced costs of non-basic variables */ + +#define spx_change_basis _glp_spx_change_basis +void spx_change_basis(SPXLP *lp, int p, int p_flag, int q); +/* change current basis to adjacent one */ + +#define spx_update_invb _glp_spx_update_invb +int spx_update_invb(SPXLP *lp, int i, int k); +/* update factorization of basis matrix */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spxnt.c b/resources/3rdparty/glpk-4.57/src/simplex/spxnt.c new file mode 100644 index 000000000..cf3e1f2be --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spxnt.c @@ -0,0 +1,260 @@ +/* spxnt.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "spxnt.h" + +/*********************************************************************** +* spx_alloc_nt - allocate matrix N in sparse row-wise format +* +* This routine allocates the memory for arrays needed to represent the +* matrix N composed of non-basic columns of the constraint matrix A. */ + +void spx_alloc_nt(SPXLP *lp, SPXNT *nt) +{ int m = lp->m; + int nnz = lp->nnz; + nt->ptr = talloc(1+m, int); + nt->len = talloc(1+m, int); + nt->ind = talloc(1+nnz, int); + nt->val = talloc(1+nnz, double); + return; +} + +/*********************************************************************** +* spx_init_nt - initialize row pointers for matrix N +* +* This routine initializes (sets up) row pointers for the matrix N +* using column-wise representation of the constraint matrix A. +* +* This routine needs to be called only once. */ + +void spx_init_nt(SPXLP *lp, SPXNT *nt) +{ int m = lp->m; + int n = lp->n; + int nnz = lp->nnz; + int *A_ptr = lp->A_ptr; + int *A_ind = lp->A_ind; + int *NT_ptr = nt->ptr; + int *NT_len = nt->len; + int i, k, ptr, end; + /* calculate NT_len[i] = maximal number of non-zeros in i-th row + * of N = number of non-zeros in i-th row of A */ + memset(&NT_len[1], 0, m * sizeof(int)); + for (k = 1; k <= n; k++) + { ptr = A_ptr[k]; + end = A_ptr[k+1]; + for (; ptr < end; ptr++) + NT_len[A_ind[ptr]]++; + } + /* initialize row pointers NT_ptr[i], i = 1,...,n-m */ + NT_ptr[1] = 1; + for (i = 2; i <= m; i++) + NT_ptr[i] = NT_ptr[i-1] + NT_len[i-1]; + xassert(NT_ptr[m] + NT_len[m] == nnz+1); + return; +} + +/*********************************************************************** +* spx_nt_add_col - add column N[j] = A[k] to matrix N +* +* This routine adds elements of column N[j] = A[k], 1 <= j <= n-m, +* 1 <= k <= n, to the row-wise represntation of the matrix N. It is +* assumed (with no check) that elements of the specified column are +* missing in the row-wise represntation of N. */ + +void spx_nt_add_col(SPXLP *lp, SPXNT *nt, int j, int k) +{ int m = lp->m; + int n = lp->n; + int nnz = lp->nnz; + int *A_ptr = lp->A_ptr; + int *A_ind = lp->A_ind; + double *A_val = lp->A_val; + int *NT_ptr = nt->ptr; + int *NT_len = nt->len; + int *NT_ind = nt->ind; + double *NT_val = nt->val; + int i, ptr, end, pos; + xassert(1 <= j && j <= n-m); + xassert(1 <= k && k <= n); + ptr = A_ptr[k]; + end = A_ptr[k+1]; + for (; ptr < end; ptr++) + { i = A_ind[ptr]; + /* add element N[i,j] = A[i,k] to i-th row of matrix N */ + pos = NT_ptr[i] + (NT_len[i]++); + if (i < m) + xassert(pos < NT_ptr[i+1]); + else + xassert(pos <= nnz); + NT_ind[pos] = j; + NT_val[pos] = A_val[ptr]; + } + return; +} + +/*********************************************************************** +* spx_build_nt - build matrix N for current basis +* +* This routine builds the row-wise represntation of the matrix N +* for the current basis by adding columns of the constraint matrix A +* corresponding to non-basic variables. */ + +void spx_build_nt(SPXLP *lp, SPXNT *nt) +{ int m = lp->m; + int n = lp->n; + int *head = lp->head; + int *NT_len = nt->len; + int j, k; + /* N := 0 */ + memset(&NT_len[1], 0, m * sizeof(int)); + /* add non-basic columns N[j] = A[k] */ + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + spx_nt_add_col(lp, nt, j, k); + } + return; +} + +/*********************************************************************** +* spx_nt_del_col - remove column N[j] = A[k] from matrix N +* +* This routine removes elements of column N[j] = A[k], 1 <= j <= n-m, +* 1 <= k <= n, from the row-wise representation of the matrix N. It is +* assumed (with no check) that elements of the specified column are +* present in the row-wise representation of N. */ + +void spx_nt_del_col(SPXLP *lp, SPXNT *nt, int j, int k) +{ int m = lp->m; + int n = lp->n; + int *A_ptr = lp->A_ptr; + int *A_ind = lp->A_ind; + int *NT_ptr = nt->ptr; + int *NT_len = nt->len; + int *NT_ind = nt->ind; + double *NT_val = nt->val; + int i, ptr, end, ptr1, end1; + xassert(1 <= j && j <= n-m); + xassert(1 <= k && k <= n); + ptr = A_ptr[k]; + end = A_ptr[k+1]; + for (; ptr < end; ptr++) + { i = A_ind[ptr]; + /* find element N[i,j] = A[i,k] in i-th row of matrix N */ + ptr1 = NT_ptr[i]; + end1 = ptr1 + NT_len[i]; + for (; NT_ind[ptr1] != j; ptr1++) + /* nop */; + xassert(ptr1 < end1); + /* and remove it from i-th row element list */ + NT_len[i]--; + NT_ind[ptr1] = NT_ind[end1-1]; + NT_val[ptr1] = NT_val[end1-1]; + } + return; +} + +/*********************************************************************** +* spx_update_nt - update matrix N for adjacent basis +* +* This routine updates the row-wise represntation of matrix N for +* the adjacent basis, where column N[q], 1 <= q <= n-m, is replaced by +* column B[p], 1 <= p <= m, of the current basis matrix B. */ + +void spx_update_nt(SPXLP *lp, SPXNT *nt, int p, int q) +{ int m = lp->m; + int n = lp->n; + int *head = lp->head; + xassert(1 <= p && p <= m); + xassert(1 <= q && q <= n-m); + /* remove old column N[q] corresponding to variable xN[q] */ + spx_nt_del_col(lp, nt, q, head[m+q]); + /* add new column N[q] corresponding to variable xB[p] */ + spx_nt_add_col(lp, nt, q, head[p]); + return; +} + +/*********************************************************************** +* spx_nt_prod - compute product y := y + s * N'* x +* +* This routine computes the product: +* +* y := y + s * N'* x, +* +* where N' is a matrix transposed to the mx(n-m)-matrix N composed +* from non-basic columns of the constraint matrix A, x is a m-vector, +* s is a scalar, y is (n-m)-vector. +* +* If the flag ign is non-zero, the routine ignores the input content +* of the array y assuming that y = 0. +* +* The routine uses the row-wise representation of the matrix N and +* computes the product as a linear combination: +* +* y := y + s * (N'[1] * x[1] + ... + N'[m] * x[m]), +* +* where N'[i] is i-th row of N, 1 <= i <= m. */ + +void spx_nt_prod(SPXLP *lp, SPXNT *nt, double y[/*1+n-m*/], int ign, + double s, const double x[/*1+m*/]) +{ int m = lp->m; + int n = lp->n; + int *NT_ptr = nt->ptr; + int *NT_len = nt->len; + int *NT_ind = nt->ind; + double *NT_val = nt->val; + int i, j, ptr, end; + double t; + if (ign) + { /* y := 0 */ + for (j = 1; j <= n-m; j++) + y[j] = 0.0; + } + for (i = 1; i <= m; i++) + { if (x[i] != 0.0) + { /* y := y + s * (i-th row of N) * x[i] */ + t = s * x[i]; + ptr = NT_ptr[i]; + end = ptr + NT_len[i]; + for (; ptr < end; ptr++) + y[NT_ind[ptr]] += NT_val[ptr] * t; + } + } + return; +} + +/*********************************************************************** +* spx_free_nt - deallocate matrix N in sparse row-wise format +* +* This routine deallocates the memory used for arrays of the program +* object nt. */ + +void spx_free_nt(SPXLP *lp, SPXNT *nt) +{ xassert(lp == lp); + tfree(nt->ptr); + tfree(nt->len); + tfree(nt->ind); + tfree(nt->val); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spxnt.h b/resources/3rdparty/glpk-4.57/src/simplex/spxnt.h new file mode 100644 index 000000000..d2622404c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spxnt.h @@ -0,0 +1,89 @@ +/* spxnt.h */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef SPXNT_H +#define SPXNT_H + +#include "spxlp.h" + +typedef struct SPXNT SPXNT; + +struct SPXNT +{ /* mx(n-m)-matrix N composed of non-basic columns of constraint + * matrix A, in sparse row-wise format */ + int *ptr; /* int ptr[1+m]; */ + /* ptr[0] is not used; + * ptr[i], 1 <= i <= m, is starting position of i-th row in + * arrays ind and val; note that ptr[1] is always 1; + * these starting positions are set up *once* as if they would + * correspond to rows of matrix A stored without gaps, i.e. + * ptr[i+1] - ptr[i] is the number of non-zeros in i-th (i < m) + * row of matrix A, and (nnz+1) - ptr[m] is the number of + * non-zero in m-th (last) row of matrix A, where nnz is the + * total number of non-zeros in matrix A */ + int *len; /* int len[1+m]; */ + /* len[0] is not used; + * len[i], 1 <= i <= m, is the number of non-zeros in i-th row + * of current matrix N */ + int *ind; /* int ind[1+nnz]; */ + /* column indices */ + double *val; /* double val[1+nnz]; */ + /* non-zero element values */ +}; + +#define spx_alloc_nt _glp_spx_alloc_nt +void spx_alloc_nt(SPXLP *lp, SPXNT *nt); +/* allocate matrix N in sparse row-wise format */ + +#define spx_init_nt _glp_spx_init_nt +void spx_init_nt(SPXLP *lp, SPXNT *nt); +/* initialize row pointers for matrix N */ + +#define spx_nt_add_col _glp_spx_nt_add_col +void spx_nt_add_col(SPXLP *lp, SPXNT *nt, int j, int k); +/* add column N[j] = A[k] */ + +#define spx_build_nt _glp_spx_build_nt +void spx_build_nt(SPXLP *lp, SPXNT *nt); +/* build matrix N for current basis */ + +#define spx_nt_del_col _glp_spx_nt_del_col +void spx_nt_del_col(SPXLP *lp, SPXNT *nt, int j, int k); +/* remove column N[j] = A[k] from matrix N */ + +#define spx_update_nt _glp_spx_update_nt +void spx_update_nt(SPXLP *lp, SPXNT *nt, int p, int q); +/* update matrix N for adjacent basis */ + +#define spx_nt_prod _glp_spx_nt_prod +void spx_nt_prod(SPXLP *lp, SPXNT *nt, double y[/*1+n-m*/], int ign, + double s, const double x[/*1+m*/]); +/* compute product y := y + s * N'* x */ + +#define spx_free_nt _glp_spx_free_nt +void spx_free_nt(SPXLP *lp, SPXNT *nt); +/* deallocate matrix N in sparse row-wise format */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spxprim.c b/resources/3rdparty/glpk-4.57/src/simplex/spxprim.c new file mode 100644 index 000000000..b22133ff0 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spxprim.c @@ -0,0 +1,1139 @@ +/* spxprim.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "simplex.h" +#include "spxat.h" +#include "spxnt.h" +#include "spxchuzc.h" +#include "spxchuzr.h" +#include "spxprob.h" + +#define USE_AT 0 +/* 1 - use A in row-wise format + * 0 - use N in row-wise format */ + +#define EXCL 1 +/* 1 - exclude fixed non-basic variables + * 0 - don't exclude variables */ + +#define SHIFT 1 +/* 1 - shift bounds of variables toward zero + * 0 - don't shift bounds of variables */ + +#define CHECK_ACCURACY 0 +/* (for debugging) */ + +struct csa +{ /* common storage area */ + SPXLP *lp; + /* LP problem data and its (current) basis; this LP has m rows + * and n columns */ + int dir; + /* original optimization direction: + * +1 - minimization + * -1 - maximization */ + double *c; /* double c[1+n]; */ + /* copy of original objective coefficients */ + SPXAT *at; + /* mxn-matrix A of constraint coefficients, in sparse row-wise + * format (NULL if not used) */ + SPXNT *nt; + /* mx(n-m)-matrix N composed of non-basic columns of constraint + * matrix A, in sparse row-wise format (NULL if not used) */ + int phase; + /* search phase: + * 0 - not determined yet + * 1 - searching for primal feasible solution + * 2 - searching for optimal solution */ + double *beta; /* double beta[1+m]; */ + /* beta[i] is primal value of basic variable xB[i] */ + int beta_st; + /* status of the vector beta: + * 0 - undefined + * 1 - just computed + * 2 - updated */ + double *d; /* double d[1+n-m]; */ + /* d[j] is reduced cost of non-basic variable xN[j] */ + int d_st; + /* status of the vector d: + * 0 - undefined + * 1 - just computed + * 2 - updated */ + SPXSE *se; + /* projected steepest edge and Devex pricing data block (NULL if + * not used) */ + int num; + /* number of eligible non-basic variables */ + int *list; /* int list[1+n-m]; */ + /* list[1], ..., list[num] are indices j of eligible non-basic + * variables xN[j] */ + int q; + /* xN[q] is a non-basic variable chosen to enter the basis */ + double *tcol; /* double tcol[1+m]; */ + /* q-th (pivot) column of the simplex table */ + int p; + /* xB[p] is a basic variable chosen to leave the basis; + * p = 0 means that no basic variable reaches its bound; + * p < 0 means that non-basic variable xN[q] reaches its opposite + * bound before any basic variable */ + int p_flag; + /* if this flag is set, the active bound of xB[p] in the adjacent + * basis should be set to the upper bound */ + double *trow; /* double trow[1+n-m]; */ + /* p-th (pivot) row of the simplex table */ + double *work; /* double work[1+m]; */ + /* working array */ + int p_stat, d_stat; + /* primal and dual solution statuses */ + /*--------------------------------------------------------------*/ + /* control parameters (see struct glp_smcp) */ + int msg_lev; + /* message level */ + int harris; + /* ratio test technique: + * 0 - textbook ratio test + * 1 - Harris' two pass ratio test */ + double tol_bnd, tol_bnd1; + /* primal feasibility tolerances */ + double tol_dj, tol_dj1; + /* dual feasibility tolerances */ + double tol_piv; + /* pivot tolerance */ + int it_lim; + /* iteration limit */ + int tm_lim; + /* time limit, milliseconds */ + int out_frq; + /* display output frequency, iterations */ + int out_dly; + /* display output delay, milliseconds */ + /*--------------------------------------------------------------*/ + /* working parameters */ + double tm_beg; + /* time value at the beginning of the search */ + int it_beg; + /* simplex iteration count at the beginning of the search */ + int it_cnt; + /* simplex iteration count; it increases by one every time the + * basis changes (including the case when a non-basic variable + * jumps to its opposite bound) */ + int it_dpy; + /* simplex iteration count at most recent display output */ + int inv_cnt; + /* basis factorization count since most recent display output */ +}; + +/*********************************************************************** +* set_penalty - set penalty function coefficients +* +* This routine sets up objective coefficients of the penalty function, +* which is the sum of primal infeasibilities, as follows: +* +* if beta[i] < l[k] - eps1, set c[k] = -1, +* +* if beta[i] > u[k] + eps2, set c[k] = +1, +* +* otherwise, set c[k] = 0, +* +* where beta[i] is current value of basic variable xB[i] = x[k], l[k] +* and u[k] are original bounds of x[k], and +* +* eps1 = tol + tol1 * |l[k]|, +* +* eps2 = tol + tol1 * |u[k]|. +* +* The routine returns the number of non-zero objective coefficients, +* which is the number of basic variables violating their bounds. Thus, +* if the value returned is zero, the current basis is primal feasible +* within the specified tolerances. */ + +static int set_penalty(struct csa *csa, double tol, double tol1) +{ SPXLP *lp = csa->lp; + int m = lp->m; + int n = lp->n; + double *c = lp->c; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + double *beta = csa->beta; + int i, k, count = 0; + double t, eps; + /* reset objective coefficients */ + for (k = 0; k <= n; k++) + c[k] = 0.0; + /* walk thru the list of basic variables */ + for (i = 1; i <= m; i++) + { k = head[i]; /* x[k] = xB[i] */ + /* check lower bound */ + if ((t = l[k]) != -DBL_MAX) + { eps = tol + tol1 * (t >= 0.0 ? +t : -t); + if (beta[i] < t - eps) + { /* lower bound is violated */ + c[k] = -1.0, count++; + } + } + /* check upper bound */ + if ((t = u[k]) != +DBL_MAX) + { eps = tol + tol1 * (t >= 0.0 ? +t : -t); + if (beta[i] > t + eps) + { /* upper bound is violated */ + c[k] = +1.0, count++; + } + } + } + return count; +} + +/*********************************************************************** +* check_feas - check primal feasibility of basic solution +* +* This routine checks if the specified values of all basic variables +* beta = (beta[i]) are within their bounds. +* +* Let l[k] and u[k] be original bounds of basic variable xB[i] = x[k]. +* The actual bounds of x[k] are determined as follows: +* +* 1) if phase = 1 and c[k] < 0, x[k] violates its lower bound, so its +* actual bounds are artificial: -inf < x[k] <= l[k]; +* +* 2) if phase = 1 and c[k] > 0, x[k] violates its upper bound, so its +* actual bounds are artificial: u[k] <= x[k] < +inf; +* +* 3) in all other cases (if phase = 1 and c[k] = 0, or if phase = 2) +* actual bounds are original: l[k] <= x[k] <= u[k]. +* +* The parameters tol and tol1 are bound violation tolerances. The +* actual bounds l'[k] and u'[k] are considered as non-violated within +* the specified tolerance if +* +* l'[k] - eps1 <= beta[i] <= u'[k] + eps2, +* +* where eps1 = tol + tol1 * |l'[k]|, eps2 = tol + tol1 * |u'[k]|. +* +* The routine returns one of the following codes: +* +* 0 - solution is feasible (no actual bounds are violated); +* +* 1 - solution is infeasible, however, only artificial bounds are +* violated (this is possible only if phase = 1); +* +* 2 - solution is infeasible and at least one original bound is +* violated. */ + +static int check_feas(struct csa *csa, int phase, double tol, double + tol1) +{ SPXLP *lp = csa->lp; + int m = lp->m; + double *c = lp->c; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + double *beta = csa->beta; + int i, k, orig, ret = 0; + double lk, uk, eps; + xassert(phase == 1 || phase == 2); + /* walk thru the list of basic variables */ + for (i = 1; i <= m; i++) + { k = head[i]; /* x[k] = xB[i] */ + /* determine actual bounds of x[k] */ + if (phase == 1 && c[k] < 0.0) + { /* -inf < x[k] <= l[k] */ + lk = -DBL_MAX, uk = l[k]; + orig = 0; /* artificial bounds */ + } + else if (phase == 1 && c[k] > 0.0) + { /* u[k] <= x[k] < +inf */ + lk = u[k], uk = +DBL_MAX; + orig = 0; /* artificial bounds */ + } + else + { /* l[k] <= x[k] <= u[k] */ + lk = l[k], uk = u[k]; + orig = 1; /* original bounds */ + } + /* check actual lower bound */ + if (lk != -DBL_MAX) + { eps = tol + tol1 * (lk >= 0.0 ? +lk : -lk); + if (beta[i] < lk - eps) + { /* actual lower bound is violated */ + if (orig) + { ret = 2; + break; + } + ret = 1; + } + } + /* check actual upper bound */ + if (uk != +DBL_MAX) + { eps = tol + tol1 * (uk >= 0.0 ? +uk : -uk); + if (beta[i] > uk + eps) + { /* actual upper bound is violated */ + if (orig) + { ret = 2; + break; + } + ret = 1; + } + } + } + return ret; +} + +/*********************************************************************** +* adjust_penalty - adjust penalty function coefficients +* +* On searching for primal feasible solution it may happen that some +* basic variable xB[i] = x[k] has non-zero objective coefficient c[k] +* indicating that xB[i] violates its lower (if c[k] < 0) or upper (if +* c[k] > 0) original bound, but due to primal degenarcy the violation +* is close to zero. +* +* This routine identifies such basic variables and sets objective +* coefficients at these variables to zero that allows avoiding zero- +* step simplex iterations. +* +* The parameters tol and tol1 are bound violation tolerances. The +* original bounds l[k] and u[k] are considered as non-violated within +* the specified tolerance if +* +* l[k] - eps1 <= beta[i] <= u[k] + eps2, +* +* where beta[i] is value of basic variable xB[i] = x[k] in the current +* basis, eps1 = tol + tol1 * |l[k]|, eps2 = tol + tol1 * |u[k]|. +* +* The routine returns the number of objective coefficients which were +* set to zero. */ + +static int adjust_penalty(struct csa *csa, double tol, double tol1) +{ SPXLP *lp = csa->lp; + int m = lp->m; + double *c = lp->c; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + double *beta = csa->beta; + int i, k, count = 0; + double t, eps; + xassert(csa->phase == 1); + /* walk thru the list of basic variables */ + for (i = 1; i <= m; i++) + { k = head[i]; /* x[k] = xB[i] */ + if (c[k] < 0.0) + { /* x[k] violates its original lower bound l[k] */ + xassert((t = l[k]) != -DBL_MAX); + eps = tol + tol1 * (t >= 0.0 ? +t : -t); + if (beta[i] >= t - eps) + { /* however, violation is close to zero */ + c[k] = 0.0, count++; + } + } + else if (c[k] > 0.0) + { /* x[k] violates its original upper bound u[k] */ + xassert((t = u[k]) != +DBL_MAX); + eps = tol + tol1 * (t >= 0.0 ? +t : -t); + if (beta[i] <= t + eps) + { /* however, violation is close to zero */ + c[k] = 0.0, count++; + } + } + } + return count; +} + +#if CHECK_ACCURACY +/*********************************************************************** +* err_in_vec - compute maximal relative error between two vectors +* +* This routine computes and returns maximal relative error between +* n-vectors x and y: +* +* err_max = max |x[i] - y[i]| / (1 + |x[i]|). +* +* NOTE: This routine is intended only for debugginig purposes. */ + +static double err_in_vec(int n, const double x[], const double y[]) +{ int i; + double err, err_max; + err_max = 0.0; + for (i = 1; i <= n; i++) + { err = fabs(x[i] - y[i]) / (1.0 + fabs(x[i])); + if (err_max < err) + err_max = err; + } + return err_max; +} +#endif + +#if CHECK_ACCURACY +/*********************************************************************** +* err_in_beta - compute maximal relative error in vector beta +* +* This routine computes and returns maximal relative error in vector +* of values of basic variables beta = (beta[i]). +* +* NOTE: This routine is intended only for debugginig purposes. */ + +static double err_in_beta(struct csa *csa) +{ SPXLP *lp = csa->lp; + int m = lp->m; + double err, *beta; + beta = talloc(1+m, double); + spx_eval_beta(lp, beta); + err = err_in_vec(m, beta, csa->beta); + tfree(beta); + return err; +} +#endif + +#if CHECK_ACCURACY +/*********************************************************************** +* err_in_d - compute maximal relative error in vector d +* +* This routine computes and returns maximal relative error in vector +* of reduced costs of non-basic variables d = (d[j]). +* +* NOTE: This routine is intended only for debugginig purposes. */ + +static double err_in_d(struct csa *csa) +{ SPXLP *lp = csa->lp; + int m = lp->m; + int n = lp->n; + int j; + double err, *pi, *d; + pi = talloc(1+m, double); + d = talloc(1+n-m, double); + spx_eval_pi(lp, pi); + for (j = 1; j <= n-m; j++) + d[j] = spx_eval_dj(lp, pi, j); + err = err_in_vec(n-m, d, csa->d); + tfree(pi); + tfree(d); + return err; +} +#endif + +#if CHECK_ACCURACY +/*********************************************************************** +* err_in_gamma - compute maximal relative error in vector gamma +* +* This routine computes and returns maximal relative error in vector +* of projected steepest edge weights gamma = (gamma[j]). +* +* NOTE: This routine is intended only for debugginig purposes. */ + +static double err_in_gamma(struct csa *csa) +{ SPXLP *lp = csa->lp; + int m = lp->m; + int n = lp->n; + SPXSE *se = csa->se; + int j; + double err, *gamma; + xassert(se != NULL); + gamma = talloc(1+n-m, double); + for (j = 1; j <= n-m; j++) + gamma[j] = spx_eval_gamma_j(lp, se, j); + err = err_in_vec(n-m, gamma, se->gamma); + tfree(gamma); + return err; +} +#endif + +#if CHECK_ACCURACY +/*********************************************************************** +* check_accuracy - check accuracy of basic solution components +* +* This routine checks accuracy of current basic solution components. +* +* NOTE: This routine is intended only for debugginig purposes. */ + +static void check_accuracy(struct csa *csa) +{ double e_beta, e_d, e_gamma; + e_beta = err_in_beta(csa); + e_d = err_in_d(csa); + if (csa->se == NULL) + e_gamma = 0.; + else + e_gamma = err_in_gamma(csa); + xprintf("e_beta = %10.3e; e_d = %10.3e; e_gamma = %10.3e\n", + e_beta, e_d, e_gamma); + xassert(e_beta <= 1e-5 && e_d <= 1e-5 && e_gamma <= 1e-3); + return; +} +#endif + +/*********************************************************************** +* choose_pivot - choose xN[q] and xB[p] +* +* Given the list of eligible non-basic variables this routine first +* chooses non-basic variable xN[q]. This choice is always possible, +* because the list is assumed to be non-empty. Then the routine +* computes q-th column T[*,q] of the simplex table T[i,j] and chooses +* basic variable xB[p]. If the pivot T[p,q] is small in magnitude, +* the routine attempts to choose another xN[q] and xB[p] in order to +* avoid badly conditioned adjacent bases. */ + +static void choose_pivot(struct csa *csa) +{ SPXLP *lp = csa->lp; + int m = lp->m; + int n = lp->n; + double *beta = csa->beta; + double *d = csa->d; + SPXSE *se = csa->se; + int *list = csa->list; + int nnn, try, q, t, p_flag, p; + double *tcol = csa->work; + /* initial number of eligible non-basic variables */ + nnn = csa->num; + /* nothing has been chosen so far */ + csa->q = 0; + try = 0; +try: /* choose non-basic variable xN[q] */ + xassert(nnn > 0); + try++; + if (se == NULL) + { /* Dantzig's rule */ + q = spx_chuzc_std(lp, d, nnn, list); + } + else + { /* projected steepest edge */ + q = spx_chuzc_pse(lp, se, d, nnn, list); + } + xassert(1 <= q && q <= n-m); + /* compute q-th column of the simplex table */ + spx_eval_tcol(lp, q, tcol); + /* choose basic variable xB[p] */ + if (!csa->harris) + { /* textbook ratio test */ + p = spx_chuzr_std(lp, csa->phase, beta, q, + d[q] < 0.0 ? +1. : -1., tcol, &p_flag, csa->tol_piv, + .30 * csa->tol_bnd, .30 * csa->tol_bnd1); + } + else + { /* Harris' two-pass ratio test */ + p = spx_chuzr_harris(lp, csa->phase, beta, q, + d[q] < 0.0 ? +1. : -1., tcol, &p_flag , csa->tol_piv, + .50 * csa->tol_bnd, .50 * csa->tol_bnd1); + } + /* either keep previous choice or accept new choice depending on + * which one is better */ + if (csa->q == 0 || p <= 0 || + fabs(tcol[p]) > fabs(csa->tcol[csa->p])) + { csa->q = q; + memcpy(&csa->tcol[1], &tcol[1], m * sizeof(double)); + csa->p = p; + csa->p_flag = p_flag; + } + /* check if current choice is acceptable */ + if (csa->p <= 0 || fabs(csa->tcol[csa->p]) >= 0.001) + goto done; + if (nnn == 1) + goto done; + if (try == 5) + goto done; + /* try to choose other xN[q] and xB[p] */ + /* find xN[q] in the list */ + for (t = 1; t <= nnn; t++) + if (list[t] == q) break; + xassert(t <= nnn); + /* move xN[q] to the end of the list */ + list[t] = list[nnn], list[nnn] = q; + /* and exclude it from consideration */ + nnn--; + /* repeat the choice */ + goto try; +done: /* the choice has been made */ + return; +} + +/*********************************************************************** +* sum_infeas - compute sum of primal infeasibilities +* +* This routine compute the sum of primal infeasibilities, which is the +* current penalty function value. */ + +static double sum_infeas(SPXLP *lp, const double beta[/*1+m*/]) +{ int m = lp->m; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + int i, k; + double sum = 0.0; + for (i = 1; i <= m; i++) + { k = head[i]; /* x[k] = xB[i] */ + if (l[k] != -DBL_MAX && beta[i] < l[k]) + sum += l[k] - beta[i]; + if (u[k] != +DBL_MAX && beta[i] > u[k]) + sum += beta[i] - u[k]; + } + return sum; +} + +/*********************************************************************** +* display - display search progress +* +* This routine displays some information about the search progress +* that includes: +* +* search phase; +* +* number of simplex iterations performed by the solver; +* +* original objective value; +* +* sum of (scaled) primal infeasibilities; +* +* number of infeasibilities (phase I) or non-optimalities (phase II); +* +* number of basic factorizations since last display output. */ + +static void display(struct csa *csa, int spec) +{ int nnn, k; + double obj, sum, *save; + /* check if the display output should be skipped */ + if (csa->msg_lev < GLP_MSG_ON) goto skip; + if (csa->out_dly > 0 && + 1000.0 * xdifftime(xtime(), csa->tm_beg) < csa->out_dly) + goto skip; + if (csa->it_cnt == csa->it_dpy) goto skip; + if (!spec && csa->it_cnt % csa->out_frq != 0) goto skip; + /* compute original objective value */ + save = csa->lp->c; + csa->lp->c = csa->c; + obj = csa->dir * spx_eval_obj(csa->lp, csa->beta); + csa->lp->c = save; + /* compute sum of (scaled) primal infeasibilities */ + sum = sum_infeas(csa->lp, csa->beta); + /* compute number of infeasibilities/non-optimalities */ + switch (csa->phase) + { case 1: + nnn = 0; + for (k = 1; k <= csa->lp->n; k++) + if (csa->lp->c[k] != 0.0) nnn++; + break; + case 2: + xassert(csa->d_st); + nnn = spx_chuzc_sel(csa->lp, csa->d, csa->tol_dj, + csa->tol_dj1, NULL); + break; + default: + xassert(csa != csa); + } + /* display search progress */ + xprintf("%c%6d: obj = %17.9e inf = %11.3e (%d)", + csa->phase == 2 ? '*' : ' ', csa->it_cnt, obj, sum, nnn); + if (csa->inv_cnt) + { /* number of basis factorizations performed */ + xprintf(" %d", csa->inv_cnt); + csa->inv_cnt = 0; + } + xprintf("\n"); + csa->it_dpy = csa->it_cnt; +skip: return; +} + +/*********************************************************************** +* spx_primal - driver to primal simplex method +* +* This routine is a driver to the two-phase primal simplex method. +* +* On exit this routine returns one of the following codes: +* +* 0 LP instance has been successfully solved. +* +* GLP_EITLIM +* Iteration limit has been exhausted. +* +* GLP_ETMLIM +* Time limit has been exhausted. +* +* GLP_EFAIL +* The solver failed to solve LP instance. */ + +static int primal_simplex(struct csa *csa) +{ /* primal simplex method main logic routine */ + SPXLP *lp = csa->lp; + int m = lp->m; + int n = lp->n; + double *c = lp->c; + int *head = lp->head; + SPXAT *at = csa->at; + SPXNT *nt = csa->nt; + double *beta = csa->beta; + double *d = csa->d; + SPXSE *se = csa->se; + int *list = csa->list; + double *tcol = csa->tcol; + double *trow = csa->trow; + double *pi = csa->work; + double *rho = csa->work; + int msg_lev = csa->msg_lev; + double tol_bnd = csa->tol_bnd; + double tol_bnd1 = csa->tol_bnd1; + double tol_dj = csa->tol_dj; + double tol_dj1 = csa->tol_dj1; + int j, refct, ret; +loop: /* main loop starts here */ + /* compute factorization of the basis matrix */ + if (!lp->valid) + { double cond; + ret = spx_factorize(lp); + csa->inv_cnt++; + if (ret != 0) + { if (msg_lev >= GLP_MSG_ERR) + xprintf("Error: unable to factorize the basis matrix (%d" + ")\n", ret); + csa->p_stat = csa->d_stat = GLP_UNDEF; + ret = GLP_EFAIL; + goto fini; + } + /* check condition of the basis matrix */ + cond = bfd_condest(lp->bfd); + if (cond > 1.0 / DBL_EPSILON) + { if (msg_lev >= GLP_MSG_ERR) + xprintf("Error: basis matrix is singular to working prec" + "ision (cond = %.3g)\n", cond); + csa->p_stat = csa->d_stat = GLP_UNDEF; + ret = GLP_EFAIL; + goto fini; + } + if (cond > 0.001 / DBL_EPSILON) + { if (msg_lev >= GLP_MSG_ERR) + xprintf("Warning: basis matrix is ill-conditioned (cond " + "= %.3g)\n", cond); + } + /* invalidate basic solution components */ + csa->beta_st = csa->d_st = 0; + } + /* compute values of basic variables beta = (beta[i]) */ + if (!csa->beta_st) + { spx_eval_beta(lp, beta); + csa->beta_st = 1; /* just computed */ + /* determine the search phase, if not determined yet */ + if (!csa->phase) + { if (set_penalty(csa, 0.97 * tol_bnd, 0.97 * tol_bnd1)) + { /* current basic solution is primal infeasible */ + /* start to minimize the sum of infeasibilities */ + csa->phase = 1; + } + else + { /* current basic solution is primal feasible */ + /* start to minimize the original objective function */ + csa->phase = 2; + memcpy(c, csa->c, (1+n) * sizeof(double)); + } + /* working objective coefficients have been changed, so + * invalidate reduced costs */ + csa->d_st = 0; + } + /* make sure that the current basic solution remains primal + * feasible (or pseudo-feasible on phase I) */ + if (check_feas(csa, csa->phase, tol_bnd, tol_bnd1)) + { /* excessive bound violations due to round-off errors */ + if (msg_lev >= GLP_MSG_ERR) + xprintf("Warning: numerical instability (primal simplex," + " phase %s)\n", csa->phase == 1 ? "I" : "II"); + /* restart the search */ + lp->valid = 0; + csa->phase = 0; + goto loop; + } + } + /* at this point the search phase is determined */ + xassert(csa->phase == 1 || csa->phase == 2); + if (csa->phase == 1) + { /* adjust penalty function coefficients */ + if (adjust_penalty(csa, tol_bnd, tol_bnd1)) + { /* some coefficients were changed, so invalidate reduced + * costs of non-basic variables */ + csa->d_st = 0; + } + } + /* compute reduced costs of non-basic variables d = (d[j]) */ + if (!csa->d_st) + { spx_eval_pi(lp, pi); + for (j = 1; j <= n-m; j++) + d[j] = spx_eval_dj(lp, pi, j); + csa->d_st = 1; /* just computed */ + } + /* reset the reference space, if necessary */ + if (se != NULL && !se->valid) + spx_reset_refsp(lp, se), refct = 1000; + /* at this point the basis factorization and all basic solution + * components are valid */ + xassert(lp->valid && csa->beta_st && csa->d_st); +#if CHECK_ACCURACY + /* check accuracy of current basic solution components (only for + * debugging) */ + check_accuracy(csa); +#endif + /* check if the iteration limit has been exhausted */ + if (csa->it_cnt - csa->it_beg >= csa->it_lim) + { if (csa->beta_st != 1) + csa->beta_st = 0; + if (csa->d_st != 1) + csa->d_st = 0; + if (!(csa->beta_st && csa->d_st)) + goto loop; + display(csa, 1); + if (msg_lev >= GLP_MSG_ALL) + xprintf("ITERATION LIMIT EXCEEDED; SEARCH TERMINATED\n"); + csa->p_stat = (csa->phase == 2 ? GLP_FEAS : GLP_INFEAS); + csa->d_stat = GLP_UNDEF; /* will be set below */ + ret = GLP_EITLIM; + goto fini; + } + /* check if the time limit has been exhausted */ + if (1000.0 * xdifftime(xtime(), csa->tm_beg) >= csa->tm_lim) + { if (csa->beta_st != 1) + csa->beta_st = 0; + if (csa->d_st != 1) + csa->d_st = 0; + if (!(csa->beta_st && csa->d_st)) + goto loop; + display(csa, 1); + if (msg_lev >= GLP_MSG_ALL) + xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); + csa->p_stat = (csa->phase == 2 ? GLP_FEAS : GLP_INFEAS); + csa->d_stat = GLP_UNDEF; /* will be set below */ + ret = GLP_ETMLIM; + goto fini; + } + /* display the search progress */ + display(csa, 0); + /* select eligible non-basic variables */ + switch (csa->phase) + { case 1: + csa->num = spx_chuzc_sel(lp, d, 1e-8, 0.0, list); + break; + case 2: + csa->num = spx_chuzc_sel(lp, d, tol_dj, tol_dj1, list); + break; + default: + xassert(csa != csa); + } + /* check for optimality */ + if (csa->num == 0) + { if (csa->beta_st != 1) + csa->beta_st = 0; + if (csa->d_st != 1) + csa->d_st = 0; + if (!(csa->beta_st && csa->d_st)) + goto loop; + /* current basis is optimal */ + display(csa, 1); + switch (csa->phase) + { case 1: + /* check for primal feasibility */ + if (!check_feas(csa, 2, tol_bnd, tol_bnd1)) + { /* feasible solution found; switch to phase II */ + memcpy(c, csa->c, (1+n) * sizeof(double)); + csa->phase = 2; + csa->d_st = 0; + goto loop; + } + /* no feasible solution exists */ + if (msg_lev >= GLP_MSG_ALL) + xprintf("LP HAS NO PRIMAL FEASIBLE SOLUTION\n"); + csa->p_stat = GLP_NOFEAS; + csa->d_stat = GLP_UNDEF; /* will be set below */ + ret = 0; + goto fini; + case 2: + /* optimal solution found */ + if (msg_lev >= GLP_MSG_ALL) + xprintf("OPTIMAL LP SOLUTION FOUND\n"); + csa->p_stat = csa->d_stat = GLP_FEAS; + ret = 0; + goto fini; + default: + xassert(csa != csa); + } + } + /* choose xN[q] and xB[p] */ + choose_pivot(csa); + /* check for unboundedness */ + if (csa->p == 0) + { if (csa->beta_st != 1) + csa->beta_st = 0; + if (csa->d_st != 1) + csa->d_st = 0; + if (!(csa->beta_st && csa->d_st)) + goto loop; + display(csa, 1); + switch (csa->phase) + { case 1: + /* this should never happen */ + if (msg_lev >= GLP_MSG_ERR) + xprintf("Error: primal simplex failed\n"); + csa->p_stat = csa->d_stat = GLP_UNDEF; + ret = GLP_EFAIL; + goto fini; + case 2: + /* primal unboundedness detected */ + if (msg_lev >= GLP_MSG_ALL) + xprintf("LP HAS UNBOUNDED PRIMAL SOLUTION\n"); + csa->p_stat = GLP_FEAS; + csa->d_stat = GLP_NOFEAS; + ret = 0; + goto fini; + default: + xassert(csa != csa); + } + } + /* update values of basic variables for adjacent basis */ + spx_update_beta(lp, beta, csa->p, csa->p_flag, csa->q, tcol); + csa->beta_st = 2; + /* p < 0 means that xN[q] jumps to its opposite bound */ + if (csa->p < 0) + goto skip; + /* xN[q] enters and xB[p] leaves the basis */ + /* compute p-th row of inv(B) */ + spx_eval_rho(lp, csa->p, rho); + /* compute p-th (pivot) row of the simplex table */ + if (at != NULL) + spx_eval_trow1(lp, at, rho, trow); + else + spx_nt_prod(lp, nt, trow, 1, -1.0, rho); + /* FIXME: tcol[p] and trow[q] should be close to each other */ + xassert(trow[csa->q] != 0.0); + /* update reduced costs of non-basic variables for adjacent + * basis */ + if (spx_update_d(lp, d, csa->p, csa->q, trow, tcol) <= 1e-9) + { /* successful updating */ + csa->d_st = 2; + if (csa->phase == 1) + { /* adjust reduced cost of xN[q] in adjacent basis, since + * its penalty coefficient changes (see below) */ + d[csa->q] -= c[head[csa->p]]; + } + } + else + { /* new reduced costs are inaccurate */ + csa->d_st = 0; + } + if (csa->phase == 1) + { /* xB[p] leaves the basis replacing xN[q], so set its penalty + * coefficient to zero */ + c[head[csa->p]] = 0.0; + } + /* update steepest edge weights for adjacent basis, if used */ + if (se != NULL) + { if (refct > 0) + { if (spx_update_gamma(lp, se, csa->p, csa->q, trow, tcol) + <= 1e-3) + { /* successful updating */ + refct--; + } + else + { /* new weights are inaccurate; reset reference space */ + se->valid = 0; + } + } + else + { /* too many updates; reset reference space */ + se->valid = 0; + } + } + /* update matrix N for adjacent basis, if used */ + if (nt != NULL) + spx_update_nt(lp, nt, csa->p, csa->q); +skip: /* change current basis header to adjacent one */ + spx_change_basis(lp, csa->p, csa->p_flag, csa->q); + /* and update factorization of the basis matrix */ + if (csa->p > 0) + spx_update_invb(lp, csa->p, head[csa->p]); + /* simplex iteration complete */ + csa->it_cnt++; + goto loop; +fini: /* restore original objective function */ + memcpy(c, csa->c, (1+n) * sizeof(double)); + /* compute reduced costs of non-basic variables and determine + * solution dual status, if necessary */ + if (csa->p_stat != GLP_UNDEF && csa->d_stat == GLP_UNDEF) + { xassert(ret != GLP_EFAIL); + spx_eval_pi(lp, pi); + for (j = 1; j <= n-m; j++) + d[j] = spx_eval_dj(lp, pi, j); + csa->num = spx_chuzc_sel(lp, d, tol_dj, tol_dj1, NULL); + csa->d_stat = (csa->num == 0 ? GLP_FEAS : GLP_INFEAS); + } + return ret; +} + +int spx_primal(glp_prob *P, const glp_smcp *parm) +{ /* driver to primal simplex method */ + struct csa csa_, *csa = &csa_; + SPXLP lp; +#if USE_AT + SPXAT at; +#else + SPXNT nt; +#endif + SPXSE se; + int ret, *map, *daeh; + /* build working LP and its initial basis */ + memset(csa, 0, sizeof(struct csa)); + csa->lp = &lp; + spx_init_lp(csa->lp, P, EXCL); + spx_alloc_lp(csa->lp); + map = talloc(1+P->m+P->n, int); + spx_build_lp(csa->lp, P, EXCL, SHIFT, map); + spx_build_basis(csa->lp, P, map); + switch (P->dir) + { case GLP_MIN: + csa->dir = +1; + break; + case GLP_MAX: + csa->dir = -1; + break; + default: + xassert(P != P); + } + csa->c = talloc(1+csa->lp->n, double); + memcpy(csa->c, csa->lp->c, (1+csa->lp->n) * sizeof(double)); +#if USE_AT + /* build matrix A in row-wise format */ + csa->at = &at; + csa->nt = NULL; + spx_alloc_at(csa->lp, csa->at); + spx_build_at(csa->lp, csa->at); +#else + /* build matrix N in row-wise format for initial basis */ + csa->at = NULL; + csa->nt = &nt; + spx_alloc_nt(csa->lp, csa->nt); + spx_init_nt(csa->lp, csa->nt); + spx_build_nt(csa->lp, csa->nt); +#endif + /* allocate and initialize working components */ + csa->phase = 0; + csa->beta = talloc(1+csa->lp->m, double); + csa->beta_st = 0; + csa->d = talloc(1+csa->lp->n-csa->lp->m, double); + csa->d_st = 0; + switch (parm->pricing) + { case GLP_PT_STD: + csa->se = NULL; + break; + case GLP_PT_PSE: + csa->se = &se; + spx_alloc_se(csa->lp, csa->se); + break; + default: + xassert(parm != parm); + } + csa->list = talloc(1+csa->lp->n-csa->lp->m, int); + csa->tcol = talloc(1+csa->lp->m, double); + csa->trow = talloc(1+csa->lp->n-csa->lp->m, double); + csa->work = talloc(1+csa->lp->m, double); + /* initialize control parameters */ + csa->msg_lev = parm->msg_lev; + switch (parm->r_test) + { case GLP_RT_STD: + csa->harris = 0; + break; + case GLP_RT_HAR: + csa->harris = 1; + break; + default: + xassert(parm != parm); + } + csa->tol_bnd = parm->tol_bnd; + csa->tol_bnd1 = .001 * parm->tol_bnd; + csa->tol_dj = parm->tol_dj; + csa->tol_dj1 = .001 * parm->tol_dj; + csa->tol_piv = parm->tol_piv; + csa->it_lim = parm->it_lim; + csa->tm_lim = parm->tm_lim; + csa->out_frq = parm->out_frq; + csa->out_dly = parm->out_dly; + /* initialize working parameters */ + csa->tm_beg = xtime(); + csa->it_beg = csa->it_cnt = P->it_cnt; + csa->it_dpy = -1; + csa->inv_cnt = 0; + /* try to solve working LP */ + ret = primal_simplex(csa); + /* return basis factorization back to problem object */ + P->valid = csa->lp->valid; + P->bfd = csa->lp->bfd; + /* set solution status */ + P->pbs_stat = csa->p_stat; + P->dbs_stat = csa->d_stat; + /* if the solver failed, do not store basis header and basic + * solution components to problem object */ + if (ret == GLP_EFAIL) + goto skip; + /* convert working LP basis to original LP basis and store it to + * problem object */ + daeh = talloc(1+csa->lp->n, int); + spx_store_basis(csa->lp, P, map, daeh); + /* compute simplex multipliers for final basic solution found by + * the solver */ + spx_eval_pi(csa->lp, csa->work); + /* convert working LP solution to original LP solution and store + * it to problem object */ + spx_store_sol(csa->lp, P, SHIFT, map, daeh, csa->beta, csa->work, + csa->d); + tfree(daeh); + /* save simplex iteration count */ + P->it_cnt = csa->it_cnt; + /* report auxiliary/structural variable causing unboundedness */ + P->some = 0; + if (csa->p_stat == GLP_FEAS && csa->d_stat == GLP_NOFEAS) + { int k, kk; + /* xN[q] = x[k] causes unboundedness */ + xassert(1 <= csa->q && csa->q <= csa->lp->n - csa->lp->m); + k = csa->lp->head[csa->lp->m + csa->q]; + xassert(1 <= k && k <= csa->lp->n); + /* convert to number of original variable */ + for (kk = 1; kk <= P->m + P->n; kk++) + { if (abs(map[kk]) == k) + { P->some = kk; + break; + } + } + xassert(P->some != 0); + } +skip: /* deallocate working objects and arrays */ + spx_free_lp(csa->lp); + tfree(map); + tfree(csa->c); + if (csa->at != NULL) + spx_free_at(csa->lp, csa->at); + if (csa->nt != NULL) + spx_free_nt(csa->lp, csa->nt); + tfree(csa->beta); + tfree(csa->d); + if (csa->se != NULL) + spx_free_se(csa->lp, csa->se); + tfree(csa->list); + tfree(csa->tcol); + tfree(csa->trow); + tfree(csa->work); + /* return to calling program */ + return ret; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spxprob.c b/resources/3rdparty/glpk-4.57/src/simplex/spxprob.c new file mode 100644 index 000000000..4bebe2e74 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spxprob.c @@ -0,0 +1,679 @@ +/* spxprob.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "spxprob.h" + +/*********************************************************************** +* spx_init_lp - initialize working LP object +* +* This routine determines the number of equality constraints m, the +* number of variables n, and the number of non-zero elements nnz in +* the constraint matrix for the working LP, which corresponds to the +* original LP, and stores these dimensions to the working LP object. +* (The working LP object should be allocated by the calling routine.) +* +* If the flag excl is set, the routine assumes that non-basic fixed +* variables will be excluded from the working LP. */ + +void spx_init_lp(SPXLP *lp, glp_prob *P, int excl) +{ int i, j, m, n, nnz; + m = P->m; + xassert(m > 0); + n = 0; + nnz = P->nnz; + xassert(P->valid); + /* scan rows of original LP */ + for (i = 1; i <= m; i++) + { GLPROW *row = P->row[i]; + if (excl && row->stat == GLP_NS) + { /* skip non-basic fixed auxiliary variable */ + /* nop */ + } + else + { /* include auxiliary variable in working LP */ + n++; + nnz++; /* unity column */ + } + } + /* scan columns of original LP */ + for (j = 1; j <= P->n; j++) + { GLPCOL *col = P->col[j]; + if (excl && col->stat == GLP_NS) + { /* skip non-basic fixed structural variable */ + GLPAIJ *aij; + for (aij = col->ptr; aij != NULL; aij = aij->c_next) + nnz--; + } + else + { /* include structural variable in working LP */ + n++; + } + } + /* initialize working LP data block */ + memset(lp, 0, sizeof(SPXLP)); + lp->m = m; + xassert(n > 0); + lp->n = n; + lp->nnz = nnz; + return; +} + +/*********************************************************************** +* spx_alloc_lp - allocate working LP arrays +* +* This routine allocates the memory for all arrays in the working LP +* object. */ + +void spx_alloc_lp(SPXLP *lp) +{ int m = lp->m; + int n = lp->n; + int nnz = lp->nnz; + lp->A_ptr = talloc(1+n+1, int); + lp->A_ind = talloc(1+nnz, int); + lp->A_val = talloc(1+nnz, double); + lp->b = talloc(1+m, double); + lp->c = talloc(1+n, double); + lp->l = talloc(1+n, double); + lp->u = talloc(1+n, double); + lp->head = talloc(1+n, int); + lp->flag = talloc(1+n-m, char); + return; +} + +/*********************************************************************** +* spx_build_lp - convert original LP to working LP +* +* This routine converts components (except the current basis) of the +* original LP to components of the working LP and perform scaling of +* these components. Also, if the original LP is maximization, the +* routine changes the signs of the objective coefficients and constant +* term to opposite ones. +* +* If the flag excl is set, original non-basic fixed variables are +* *not* included in the working LP. Otherwise, all (auxiliary and +* structural) original variables are included in the working LP. Note +* that this flag should have the same value as it has in a call to the +* routine spx_init_lp. +* +* If the flag shift is set, the routine shift bounds of variables +* included in the working LP to make at least one bound to be zero. +* If a variable has both lower and upper bounds, the bound having +* smaller magnitude is shifted to zero. +* +* On exit the routine stores information about correspondence between +* numbers of variables in the original and working LPs to the array +* map, which should have 1+P->m+P->n locations (location [0] is not +* used), where P->m is the numbers of rows and P->n is the number of +* columns in the original LP: +* +* map[i] = +k, 1 <= i <= P->m, means that i-th auxiliary variable of +* the original LP corresponds to variable x[k] of the working LP; +* +* map[i] = -k, 1 <= i <= P->m, means that i-th auxiliary variable of +* the original LP corresponds to variable x[k] of the working LP, and +* the upper bound of that variable was shifted to zero; +* +* map[i] = 0, 1 <= i <= P->m, means that i-th auxiliary variable of +* the original LP was excluded from the working LP; +* +* map[P->m+j], 1 <= j <= P->n, has the same sense as above, however, +* for j-th structural variable of the original LP. */ + +void spx_build_lp(SPXLP *lp, glp_prob *P, int excl, int shift, + int map[/*1+P->m+P->n*/]) +{ int m = lp->m; + int n = lp->n; + int nnz = lp->nnz; + int *A_ptr = lp->A_ptr; + int *A_ind = lp->A_ind; + double *A_val = lp->A_val; + double *b = lp->b; + double *c = lp->c; + double *l = lp->l; + double *u = lp->u; + int i, j, k, kk, ptr, end; + double dir, delta; + /* working LP is always minimization */ + switch (P->dir) + { case GLP_MIN: + dir = +1.0; + break; + case GLP_MAX: + dir = -1.0; + break; + default: + xassert(P != P); + } + /* initialize constant term of the objective */ + c[0] = dir * P->c0; + k = 0; /* number of variable in working LP */ + ptr = 1; /* current available position in A_ind/A_val */ + /* process rows of original LP */ + xassert(P->m == m); + for (i = 1; i <= m; i++) + { GLPROW *row = P->row[i]; + if (excl && row->stat == GLP_NS) + { /* i-th auxiliary variable is non-basic and fixed */ + /* substitute its scaled value in working LP */ + xassert(row->type == GLP_FX); + map[i] = 0; + b[i] = - row->lb * row->rii; + } + else + { /* include i-th auxiliary variable in working LP */ + map[i] = ++k; + /* setup k-th column of working constraint matrix which is + * i-th column of unity matrix */ + A_ptr[k] = ptr; + A_ind[ptr] = i; + A_val[ptr] = 1.0; + ptr++; + /* initialize right-hand side of i-th equality constraint + * and setup zero objective coefficient at variable x[k] */ + b[i] = c[k] = 0.0; + /* setup scaled bounds of variable x[k] */ + switch (row->type) + { case GLP_FR: + l[k] = -DBL_MAX, u[k] = +DBL_MAX; + break; + case GLP_LO: + l[k] = row->lb * row->rii, u[k] = +DBL_MAX; + break; + case GLP_UP: + l[k] = -DBL_MAX, u[k] = row->ub * row->rii; + break; + case GLP_DB: + l[k] = row->lb * row->rii, u[k] = row->ub * row->rii; + xassert(l[k] != u[k]); + break; + case GLP_FX: + l[k] = u[k] = row->lb * row->rii; + break; + default: + xassert(row != row); + } + } + } + /* process columns of original LP */ + for (j = 1; j <= P->n; j++) + { GLPCOL *col = P->col[j]; + GLPAIJ *aij; + if (excl && col->stat == GLP_NS) + { /* j-th structural variable is non-basic and fixed */ + /* substitute its scaled value in working LP */ + xassert(col->type == GLP_FX); + map[m+j] = 0; + if (col->lb != 0.0) + { /* (note that sjj scale factor is cancelled) */ + for (aij = col->ptr; aij != NULL; aij = aij->c_next) + b[aij->row->i] += + (aij->row->rii * aij->val) * col->lb; + c[0] += (dir * col->coef) * col->lb; + } + } + else + { /* include j-th structural variable in working LP */ + map[m+j] = ++k; + /* setup k-th column of working constraint matrix which is + * scaled j-th column of original constraint matrix (-A) */ + A_ptr[k] = ptr; + for (aij = col->ptr; aij != NULL; aij = aij->c_next) + { A_ind[ptr] = aij->row->i; + A_val[ptr] = - aij->row->rii * aij->val * col->sjj; + ptr++; + } + /* setup scaled objective coefficient at variable x[k] */ + c[k] = dir * col->coef * col->sjj; + /* setup scaled bounds of variable x[k] */ + switch (col->type) + { case GLP_FR: + l[k] = -DBL_MAX, u[k] = +DBL_MAX; + break; + case GLP_LO: + l[k] = col->lb / col->sjj, u[k] = +DBL_MAX; + break; + case GLP_UP: + l[k] = -DBL_MAX, u[k] = col->ub / col->sjj; + break; + case GLP_DB: + l[k] = col->lb / col->sjj, u[k] = col->ub / col->sjj; + xassert(l[k] != u[k]); + break; + case GLP_FX: + l[k] = u[k] = col->lb / col->sjj; + break; + default: + xassert(col != col); + } + } + } + xassert(k == n); + xassert(ptr == nnz+1); + A_ptr[n+1] = ptr; + /* shift bounds of all variables of working LP (optionally) */ + if (shift) + { for (kk = 1; kk <= m+P->n; kk++) + { k = map[kk]; + if (k == 0) + { /* corresponding original variable was excluded */ + continue; + } + /* shift bounds of variable x[k] */ + if (l[k] == -DBL_MAX && u[k] == +DBL_MAX) + { /* x[k] is unbounded variable */ + delta = 0.0; + } + else if (l[k] != -DBL_MAX && u[k] == +DBL_MAX) + { /* shift lower bound to zero */ + delta = l[k]; + l[k] = 0.0; + } + else if (l[k] == -DBL_MAX && u[k] != +DBL_MAX) + { /* shift upper bound to zero */ + map[kk] = -k; + delta = u[k]; + u[k] = 0.0; + } + else if (l[k] != u[k]) + { /* x[k] is double bounded variable */ + if (fabs(l[k]) <= fabs(u[k])) + { /* shift lower bound to zero */ + delta = l[k]; + l[k] = 0.0, u[k] -= delta; + } + else + { /* shift upper bound to zero */ + map[kk] = -k; + delta = u[k]; + l[k] -= delta, u[k] = 0.0; + } + xassert(l[k] != u[k]); + } + else + { /* shift fixed value to zero */ + delta = l[k]; + l[k] = u[k] = 0.0; + } + /* substitute x[k] = x'[k] + delta into all constraints + * and the objective function of working LP */ + if (delta != 0.0) + { ptr = A_ptr[k]; + end = A_ptr[k+1]; + for (; ptr < end; ptr++) + b[A_ind[ptr]] -= A_val[ptr] * delta; + c[0] += c[k] * delta; + } + } + } + return; +} + +/*********************************************************************** +* spx_build_basis - convert original LP basis to working LP basis +* +* This routine converts the current basis of the original LP to +* corresponding initial basis of the working LP, and moves the basis +* factorization driver from the original LP object to the working LP +* object. +* +* The array map should contain information provided by the routine +* spx_build_lp. */ + +void spx_build_basis(SPXLP *lp, glp_prob *P, const int map[]) +{ int m = lp->m; + int n = lp->n; + int *head = lp->head; + char *flag = lp->flag; + int i, j, k, ii, jj; + /* original basis factorization should be valid that guarantees + * the basis is correct */ + xassert(P->m == m); + xassert(P->valid); + /* initialize basis header for working LP */ + memset(&head[1], 0, m * sizeof(int)); + jj = 0; + /* scan rows of original LP */ + xassert(P->m == m); + for (i = 1; i <= m; i++) + { GLPROW *row = P->row[i]; + /* determine ordinal number of x[k] in working LP */ + if ((k = map[i]) < 0) + k = -k; + if (k == 0) + { /* corresponding original variable was excluded */ + continue; + } + xassert(1 <= k && k <= n); + if (row->stat == GLP_BS) + { /* x[k] is basic variable xB[ii] */ + ii = row->bind; + xassert(1 <= ii && ii <= m); + xassert(head[ii] == 0); + head[ii] = k; + } + else + { /* x[k] is non-basic variable xN[jj] */ + jj++; + head[m+jj] = k; + flag[jj] = (row->stat == GLP_NU); + } + } + /* scan columns of original LP */ + for (j = 1; j <= P->n; j++) + { GLPCOL *col = P->col[j]; + /* determine ordinal number of x[k] in working LP */ + if ((k = map[m+j]) < 0) + k = -k; + if (k == 0) + { /* corresponding original variable was excluded */ + continue; + } + xassert(1 <= k && k <= n); + if (col->stat == GLP_BS) + { /* x[k] is basic variable xB[ii] */ + ii = col->bind; + xassert(1 <= ii && ii <= m); + xassert(head[ii] == 0); + head[ii] = k; + } + else + { /* x[k] is non-basic variable xN[jj] */ + jj++; + head[m+jj] = k; + flag[jj] = (col->stat == GLP_NU); + } + } + xassert(m+jj == n); + /* acquire basis factorization */ + lp->valid = 1; + lp->bfd = P->bfd; + P->valid = 0; + P->bfd = NULL; + return; +} + +/*********************************************************************** +* spx_store_basis - convert working LP basis to original LP basis +* +* This routine converts the current working LP basis to corresponding +* original LP basis. This operations includes determining and setting +* statuses of all rows (auxiliary variables) and columns (structural +* variables), and building the basis header. +* +* The array map should contain information provided by the routine +* spx_build_lp. +* +* On exit the routine fills the array daeh. This array should have +* 1+lp->n locations (location [0] is not used) and contain the inverse +* of the working basis header lp->head, i.e. head[k'] = k means that +* daeh[k] = k'. */ + +void spx_store_basis(SPXLP *lp, glp_prob *P, const int map[], + int daeh[/*1+n*/]) +{ int m = lp->m; + int n = lp->n; + int *head = lp->head; + char *flag = lp->flag; + int i, j, k, kk; + /* determine inverse of working basis header */ + for (kk = 1; kk <= n; kk++) + daeh[head[kk]] = kk; + /* set row statuses */ + xassert(P->m == m); + for (i = 1; i <= m; i++) + { GLPROW *row = P->row[i]; + if ((k = map[i]) < 0) + k = -k; + if (k == 0) + { /* non-basic fixed auxiliary variable was excluded */ + xassert(row->type == GLP_FX); + row->stat = GLP_NS; + row->bind = 0; + } + else + { /* auxiliary variable corresponds to variable x[k] */ + kk = daeh[k]; + if (kk <= m) + { /* x[k] = xB[kk] */ + P->head[kk] = i; + row->stat = GLP_BS; + row->bind = kk; + } + else + { /* x[k] = xN[kk-m] */ + switch (row->type) + { case GLP_FR: + row->stat = GLP_NF; + break; + case GLP_LO: + row->stat = GLP_NL; + break; + case GLP_UP: + row->stat = GLP_NU; + break; + case GLP_DB: + row->stat = (flag[kk-m] ? GLP_NU : GLP_NL); + break; + case GLP_FX: + row->stat = GLP_NS; + break; + default: + xassert(row != row); + } + row->bind = 0; + } + } + } + /* set column statuses */ + for (j = 1; j <= P->n; j++) + { GLPCOL *col = P->col[j]; + if ((k = map[m+j]) < 0) + k = -k; + if (k == 0) + { /* non-basic fixed structural variable was excluded */ + xassert(col->type == GLP_FX); + col->stat = GLP_NS; + col->bind = 0; + } + else + { /* structural variable corresponds to variable x[k] */ + kk = daeh[k]; + if (kk <= m) + { /* x[k] = xB[kk] */ + P->head[kk] = m+j; + col->stat = GLP_BS; + col->bind = kk; + } + else + { /* x[k] = xN[kk-m] */ + switch (col->type) + { case GLP_FR: + col->stat = GLP_NF; + break; + case GLP_LO: + col->stat = GLP_NL; + break; + case GLP_UP: + col->stat = GLP_NU; + break; + case GLP_DB: + col->stat = (flag[kk-m] ? GLP_NU : GLP_NL); + break; + case GLP_FX: + col->stat = GLP_NS; + break; + default: + xassert(col != col); + } + col->bind = 0; + } + } + } + return; +} + +/*********************************************************************** +* spx_store_sol - convert working LP solution to original LP solution +* +* This routine converts the current basic solution of the working LP +* (values of basic variables, simplex multipliers, reduced costs of +* non-basic variables) to corresponding basic solution of the original +* LP (values and reduced costs of auxiliary and structural variables). +* This conversion includes unscaling all basic solution components, +* computing reduced costs of excluded non-basic variables, recovering +* unshifted values of basic variables, changing the signs of reduced +* costs (if the original LP is maximization), and computing the value +* of the objective function. +* +* The flag shift should have the same value as it has in a call to the +* routine spx_build_lp. +* +* The array map should contain information provided by the routine +* spx_build_lp. +* +* The array daeh should contain information provided by the routine +* spx_store_basis. +* +* The arrays beta, pi, and d should contain basic solution components +* for the working LP: +* +* array locations beta[1], ..., beta[m] should contain values of basic +* variables beta = (beta[i]); +* +* array locations pi[1], ..., pi[m] should contain simplex multipliers +* pi = (pi[i]); +* +* array locations d[1], ..., d[n-m] should contain reduced costs of +* non-basic variables d = (d[j]). */ + +void spx_store_sol(SPXLP *lp, glp_prob *P, int shift, + const int map[], const int daeh[], const double beta[], + const double pi[], const double d[]) +{ int m = lp->m; + char *flag = lp->flag; + int i, j, k, kk; + double dir; + /* working LP is always minimization */ + switch (P->dir) + { case GLP_MIN: + dir = +1.0; + break; + case GLP_MAX: + dir = -1.0; + break; + default: + xassert(P != P); + } + /* compute row solution components */ + xassert(P->m == m); + for (i = 1; i <= m; i++) + { GLPROW *row = P->row[i]; + if ((k = map[i]) < 0) + k = -k; + if (k == 0) + { /* non-basic fixed auxiliary variable was excluded */ + xassert(row->type == GLP_FX); + row->prim = row->lb; + /* compute reduced cost d[k] = c[k] - A'[k] * pi as if x[k] + * would be non-basic in working LP */ + row->dual = - dir * pi[i] * row->rii; + } + else + { /* auxiliary variable corresponds to variable x[k] */ + kk = daeh[k]; + if (kk <= m) + { /* x[k] = xB[kk] */ + row->prim = beta[kk] / row->rii; + if (shift) + row->prim += (map[i] < 0 ? row->ub : row->lb); + row->dual = 0.0; + } + else + { /* x[k] = xN[kk-m] */ + row->prim = (flag[kk-m] ? row->ub : row->lb); + row->dual = (dir * d[kk-m]) * row->rii; + } + } + } + /* compute column solution components and objective value */ + P->obj_val = P->c0; + for (j = 1; j <= P->n; j++) + { GLPCOL *col = P->col[j]; + if ((k = map[m+j]) < 0) + k = -k; + if (k == 0) + { /* non-basic fixed structural variable was excluded */ + GLPAIJ *aij; + double dk; + xassert(col->type == GLP_FX); + col->prim = col->lb; + /* compute reduced cost d[k] = c[k] - A'[k] * pi as if x[k] + * would be non-basic in working LP */ + /* (note that sjj scale factor is cancelled) */ + dk = dir * col->coef; + for (aij = col->ptr; aij != NULL; aij = aij->c_next) + dk += (aij->row->rii * aij->val) * pi[aij->row->i]; + col->dual = dir * dk; + } + else + { /* structural variable corresponds to variable x[k] */ + kk = daeh[k]; + if (kk <= m) + { /* x[k] = xB[kk] */ + col->prim = beta[kk] * col->sjj; + if (shift) + col->prim += (map[m+j] < 0 ? col->ub : col->lb); + col->dual = 0.0; + } + else + { /* x[k] = xN[kk-m] */ + col->prim = (flag[kk-m] ? col->ub : col->lb); + col->dual = (dir * d[kk-m]) / col->sjj; + } + } + P->obj_val += col->coef * col->prim; + } + return; +} + +/*********************************************************************** +* spx_free_lp - deallocate working LP arrays +* +* This routine deallocates the memory used for arrays of the working +* LP object. */ + +void spx_free_lp(SPXLP *lp) +{ tfree(lp->A_ptr); + tfree(lp->A_ind); + tfree(lp->A_val); + tfree(lp->b); + tfree(lp->c); + tfree(lp->l); + tfree(lp->u); + tfree(lp->head); + tfree(lp->flag); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spxprob.h b/resources/3rdparty/glpk-4.57/src/simplex/spxprob.h new file mode 100644 index 000000000..b7d87fa72 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spxprob.h @@ -0,0 +1,64 @@ +/* spxprob.h */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef SPXPROB_H +#define SPXPROB_H + +#include "prob.h" +#include "spxlp.h" + +#define spx_init_lp _glp_spx_init_lp +void spx_init_lp(SPXLP *lp, glp_prob *P, int excl); +/* initialize working LP object */ + +#define spx_alloc_lp _glp_spx_alloc_lp +void spx_alloc_lp(SPXLP *lp); +/* allocate working LP arrays */ + +#define spx_build_lp _glp_spx_build_lp +void spx_build_lp(SPXLP *lp, glp_prob *P, int excl, int shift, + int map[/*1+P->m+P->n*/]); +/* convert original LP to working LP */ + +#define spx_build_basis _glp_spx_build_basis +void spx_build_basis(SPXLP *lp, glp_prob *P, const int map[]); +/* convert original LP basis to working LP basis */ + +#define spx_store_basis _glp_spx_store_basis +void spx_store_basis(SPXLP *lp, glp_prob *P, const int map[], + int daeh[/*1+n*/]); +/* convert working LP basis to original LP basis */ + +#define spx_store_sol _glp_spx_store_sol +void spx_store_sol(SPXLP *lp, glp_prob *P, int shift, + const int map[], const int daeh[], const double beta[], + const double pi[], const double d[]); +/* convert working LP solution to original LP solution */ + +#define spx_free_lp _glp_spx_free_lp +void spx_free_lp(SPXLP *lp); +/* deallocate working LP arrays */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spychuzc.c b/resources/3rdparty/glpk-4.57/src/simplex/spychuzc.c new file mode 100644 index 000000000..dbf8029bb --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spychuzc.c @@ -0,0 +1,222 @@ +/* spychuzc.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "spychuzc.h" + +/*********************************************************************** +* spy_chuzc_std - choose non-basic variable (dual textbook ratio test) +* +* This routine implements an improved dual textbook ratio test to +* choose non-basic variable xN[q]. +* +* Current reduced costs of non-basic variables should be placed in the +* array locations d[1], ..., d[n-m]. Note that d[j] is a value of dual +* basic variable lambdaN[j] in the current basis. +* +* The parameter s specifies the sign of bound violation for basic +* variable xB[p] chosen: s = +1.0 means that xB[p] violates its lower +* bound, so dual non-basic variable lambdaB[p] = lambda^+B[p] +* increases, and s = -1.0 means that xB[p] violates its upper bound, +* so dual non-basic variable lambdaB[p] = lambda^-B[p] decreases. +* (Thus, the dual ray parameter theta = s * lambdaB[p] >= 0.) +* +* Elements of p-th simplex table row t[p] = (t[p,j]) corresponding +* to basic variable xB[p] should be placed in the array locations +* trow[1], ..., trow[n-m]. +* +* The parameter tol_piv specifies a tolerance for elements of the +* simplex table row t[p]. If |t[p,j]| < tol_piv, dual basic variable +* lambdaN[j] is skipped, i.e. it is assumed that it does not depend on +* the dual ray parameter theta. +* +* The parameters tol and tol1 specify tolerances used to increase the +* choice freedom by simulating an artificial degeneracy as follows. +* If lambdaN[j] = lambda^+N[j] >= 0 and d[j] <= +delta[j], or if +* lambdaN[j] = lambda^-N[j] <= 0 and d[j] >= -delta[j], where +* delta[j] = tol + tol1 * |cN[j]|, cN[j] is objective coefficient at +* xN[j], then it is assumed that reduced cost d[j] is equal to zero. +* +* The routine determines the index 1 <= q <= n-m of non-basic variable +* xN[q], for which corresponding dual basic variable lambda^+N[j] or +* lambda^-N[j] reaches its zero bound first on increasing the dual ray +* parameter theta, and returns p on exit. And if theta may increase +* unlimitedly, the routine returns zero. */ + +int spy_chuzc_std(SPXLP *lp, const double d[/*1+n-m*/], + double s, const double trow[/*1+n-m*/], double tol_piv, + double tol, double tol1) +{ int m = lp->m; + int n = lp->n; + double *c = lp->c; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + char *flag = lp->flag; + int j, k, q; + double alfa, biga, delta, teta, teta_min; + xassert(s == +1.0 || s == -1.0); + /* nothing is chosen so far */ + q = 0, teta_min = DBL_MAX, biga = 0.0; + /* walk thru the list of non-basic variables */ + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + /* if xN[j] is fixed variable, skip it */ + if (l[k] == u[k]) + continue; + alfa = s * trow[j]; + if (alfa >= +tol_piv && !flag[j]) + { /* xN[j] is either free or has its lower bound active, so + * lambdaN[j] = d[j] >= 0 decreases down to zero */ + delta = tol + tol1 * (c[k] >= 0.0 ? +c[k] : -c[k]); + /* determine theta on which lambdaN[j] reaches zero */ + teta = (d[j] < +delta ? 0.0 : d[j] / alfa); + } + else if (alfa <= -tol_piv && (l[k] == -DBL_MAX || flag[j])) + { /* xN[j] is either free or has its upper bound active, so + * lambdaN[j] = d[j] <= 0 increases up to zero */ + delta = tol + tol1 * (c[k] >= 0.0 ? +c[k] : -c[k]); + /* determine theta on which lambdaN[j] reaches zero */ + teta = (d[j] > -delta ? 0.0 : d[j] / alfa); + } + else + { /* lambdaN[j] cannot reach zero on increasing theta */ + continue; + } + /* choose non-basic variable xN[q] by corresponding dual basic + * variable lambdaN[q] for which theta is minimal */ + xassert(teta >= 0.0); + alfa = (alfa >= 0.0 ? +alfa : -alfa); + if (teta_min > teta || (teta_min == teta && biga < alfa)) + q = j, teta_min = teta, biga = alfa; + } + return q; +} + +/*********************************************************************** +* spy_chuzc_harris - choose non-basic var. (dual Harris' ratio test) +* +* This routine implements dual Harris' ratio test to choose non-basic +* variable xN[q]. +* +* All the parameters, except tol and tol1, as well as the returned +* value have the same meaning as for the routine spx_chuzr_std (see +* above). +* +* The parameters tol and tol1 specify tolerances on zero bound +* violations for reduced costs of non-basic variables. For reduced +* cost d[j] the tolerance is delta[j] = tol + tol1 |cN[j]|, where +* cN[j] is objective coefficient at non-basic variable xN[j]. */ + +int spy_chuzc_harris(SPXLP *lp, const double d[/*1+n-m*/], + double s, const double trow[/*1+n-m*/], double tol_piv, + double tol, double tol1) +{ int m = lp->m; + int n = lp->n; + double *c = lp->c; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + char *flag = lp->flag; + int j, k, q; + double alfa, biga, delta, teta, teta_min; + xassert(s == +1.0 || s == -1.0); + /*--------------------------------------------------------------*/ + /* first pass: determine teta_min for relaxed bounds */ + /*--------------------------------------------------------------*/ + teta_min = DBL_MAX; + /* walk thru the list of non-basic variables */ + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + /* if xN[j] is fixed variable, skip it */ + if (l[k] == u[k]) + continue; + alfa = s * trow[j]; + if (alfa >= +tol_piv && !flag[j]) + { /* xN[j] is either free or has its lower bound active, so + * lambdaN[j] = d[j] >= 0 decreases down to zero */ + delta = tol + tol1 * (c[k] >= 0.0 ? +c[k] : -c[k]); + /* determine theta on which lambdaN[j] reaches -delta */ + teta = ((d[j] < 0.0 ? 0.0 : d[j]) + delta) / alfa; + } + else if (alfa <= -tol_piv && (l[k] == -DBL_MAX || flag[j])) + { /* xN[j] is either free or has its upper bound active, so + * lambdaN[j] = d[j] <= 0 increases up to zero */ + delta = tol + tol1 * (c[k] >= 0.0 ? +c[k] : -c[k]); + /* determine theta on which lambdaN[j] reaches +delta */ + teta = ((d[j] > 0.0 ? 0.0 : d[j]) - delta) / alfa; + } + else + { /* lambdaN[j] cannot reach zero on increasing theta */ + continue; + } + xassert(teta >= 0.0); + if (teta_min > teta) + teta_min = teta; + } + /*--------------------------------------------------------------*/ + /* second pass: choose non-basic variable xN[q] */ + /*--------------------------------------------------------------*/ + if (teta_min == DBL_MAX) + { /* theta may increase unlimitedly */ + q = 0; + goto done; + } + /* nothing is chosen so far */ + q = 0, biga = 0.0; + /* walk thru the list of non-basic variables */ + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + /* if xN[j] is fixed variable, skip it */ + if (l[k] == u[k]) + continue; + alfa = s * trow[j]; + if (alfa >= +tol_piv && !flag[j]) + { /* xN[j] is either free or has its lower bound active, so + * lambdaN[j] = d[j] >= 0 decreases down to zero */ + /* determine theta on which lambdaN[j] reaches zero */ + teta = d[j] / alfa; + } + else if (alfa <= -tol_piv && (l[k] == -DBL_MAX || flag[j])) + { /* xN[j] is either free or has its upper bound active, so + * lambdaN[j] = d[j] <= 0 increases up to zero */ + /* determine theta on which lambdaN[j] reaches zero */ + teta = d[j] / alfa; + } + else + { /* lambdaN[j] cannot reach zero on increasing theta */ + continue; + } + /* choose non-basic variable for which theta is not greater + * than theta_min determined for relaxed bounds and which has + * best (largest in magnitude) pivot */ + alfa = (alfa >= 0.0 ? +alfa : -alfa); + if (teta <= teta_min && biga < alfa) + q = j, biga = alfa; + } + /* something must be chosen */ + xassert(1 <= q && q <= n-m); +done: return q; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spychuzc.h b/resources/3rdparty/glpk-4.57/src/simplex/spychuzc.h new file mode 100644 index 000000000..751e64dda --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spychuzc.h @@ -0,0 +1,43 @@ +/* spychuzc.h */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef SPYCHUZC_H +#define SPYCHUZC_H + +#include "spxlp.h" + +#define spy_chuzc_std _glp_spy_chuzc_std +int spy_chuzc_std(SPXLP *lp, const double d[/*1+n-m*/], + double s, const double trow[/*1+n-m*/], double tol_piv, + double tol, double tol1); +/* choose non-basic variable (dual textbook ratio test) */ + +#define spy_chuzc_harris _glp_spy_chuzc_harris +int spy_chuzc_harris(SPXLP *lp, const double d[/*1+n-m*/], + double s, const double trow[/*1+n-m*/], double tol_piv, + double tol, double tol1); +/* choose non-basic variable (dual Harris' ratio test) */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spychuzr.c b/resources/3rdparty/glpk-4.57/src/simplex/spychuzr.c new file mode 100644 index 000000000..756ce3e6a --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spychuzr.c @@ -0,0 +1,406 @@ +/* spychuzr.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "spychuzr.h" + +/*********************************************************************** +* spy_chuzr_sel - select eligible basic variables +* +* This routine selects eligible basic variables xB[i], whose value +* beta[i] violates corresponding lower lB[i] or upper uB[i] bound. +* Positive bound violation rp[i] = lb[i] - beta[i] > 0 is the reduced +* cost of non-basic dual variable lambda^+B[i] >= 0, so increasing it +* increases the dual objective. Similarly, negative bound violation +* rn[i] = ub[i] - beta[i] < 0 is the reduced cost of non-basic dual +* variable lambda^-B[i] <= 0, so decreasing it also increases the dual +* objective. +* +* Current values of basic variables should be placed in the array +* locations beta[1], ..., beta[m]. +* +* Basic variable xB[i] is considered eligible, if: +* +* beta[i] <= lB[i] - eps1[i], or +* +* beta[i] >= uB[i] + eps2[i], +* +* for +* +* eps1[i] = tol + tol1 * |lB[i]|, +* +* eps2[i] = tol + tol2 * |uB[i]|, +* +* where lB[i] and uB[i] are, resp., lower and upper bounds of xB[i], +* tol and tol1 are specified tolerances. +* +* On exit the routine stores indices i of eligible basic variables +* xB[i] to the array locations list[1], ..., list[num] and returns the +* number of such variables 0 <= num <= m. (If the parameter list is +* specified as NULL, no indices are stored.) */ + +int spy_chuzr_sel(SPXLP *lp, const double beta[/*1+m*/], double tol, + double tol1, int list[/*1+m*/]) +{ int m = lp->m; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + int i, k, num; + double lk, uk, eps; + num = 0; + /* walk thru list of basic variables */ + for (i = 1; i <= m; i++) + { k = head[i]; /* x[k] = xB[i] */ + lk = l[k], uk = u[k]; + /* check if xB[i] is eligible */ + if (beta[i] < lk) + { /* determine absolute tolerance eps1[i] */ + eps = tol + tol1 * (lk >= 0.0 ? +lk : -lk); + if (beta[i] < lk - eps) + { /* lower bound is violated */ + num++; + if (list != NULL) + list[num] = i; + } + } + else if (beta[i] > uk) + { /* determine absolute tolerance eps2[i] */ + eps = tol + tol1 * (uk >= 0.0 ? +uk : -uk); + if (beta[i] > uk + eps) + { /* upper bound is violated */ + num++; + if (list != NULL) + list[num] = i; + } + } + } + return num; +} + +/*********************************************************************** +* spy_chuzr_std - choose basic variable (dual Dantzig's rule) +* +* This routine chooses most eligible basic variable xB[p] according +* to dual Dantzig's ("standard") rule: +* +* r[p] = max |r[i]|, +* i in I +* +* ( lB[i] - beta[i], if beta[i] < lB[i] +* ( +* r[i] = { 0, if lB[i] <= beta[i] <= uB[i] +* ( +* ( uB[i] - beta[i], if beta[i] > uB[i] +* +* where I <= {1, ..., m} is the set of indices of eligible basic +* variables, beta[i] is current value of xB[i], lB[i] and uB[i] are, +* resp., lower and upper bounds of xB[i], r[i] is bound violation. +* +* Current values of basic variables should be placed in the array +* locations beta[1], ..., beta[m]. +* +* Indices of eligible basic variables i in I should be placed in the +* array locations list[1], ..., list[num], where num = |J| > 0 is the +* total number of such variables. +* +* On exit the routine returns p, the index of the basic variable xB[p] +* chosen. */ + +int spy_chuzr_std(SPXLP *lp, const double beta[/*1+m*/], int num, + const int list[]) +{ int m = lp->m; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + int i, k, p, t; + double abs_ri, abs_rp; + xassert(0 < num && num <= m); + p = 0, abs_rp = -1.0; + for (t = 1; t <= num; t++) + { i = list[t]; + k = head[i]; /* x[k] = xB[i] */ + if (beta[i] < l[k]) + abs_ri = l[k] - beta[i]; + else if (beta[i] > u[k]) + abs_ri = beta[i] - u[k]; + else + xassert(t != t); + if (abs_rp < abs_ri) + p = i, abs_rp = abs_ri; + } + xassert(p != 0); + return p; +} + +/*********************************************************************** +* spy_alloc_se - allocate dual pricing data block +* +* This routine allocates the memory for arrays used in the dual +* pricing data block. */ + +void spy_alloc_se(SPXLP *lp, SPYSE *se) +{ int m = lp->m; + int n = lp->n; + se->valid = 0; + se->refsp = talloc(1+n, char); + se->gamma = talloc(1+m, double); + se->work = talloc(1+m, double); + return; +} + +/*********************************************************************** +* spy_reset_refsp - reset dual reference space +* +* This routine resets (re-initializes) the dual reference space +* composing it from dual variables which are non-basic (corresponding +* to basic primal variables) in the current basis, and sets all +* weights gamma[i] to 1. */ + +void spy_reset_refsp(SPXLP *lp, SPYSE *se) +{ int m = lp->m; + int n = lp->n; + int *head = lp->head; + char *refsp = se->refsp; + double *gamma = se->gamma; + int i, k; + se->valid = 1; + memset(&refsp[1], 0, n * sizeof(char)); + for (i = 1; i <= m; i++) + { k = head[i]; /* x[k] = xB[i] */ + refsp[k] = 1; + gamma[i] = 1.0; + } + return; +} + +/*********************************************************************** +* spy_eval_gamma_i - compute dual proj. steepest edge weight directly +* +* This routine computes dual projected steepest edge weight gamma[i], +* 1 <= i <= m, for the current basis directly with the formula: +* +* n-m +* gamma[i] = delta[i] + sum eta[j] * T[i,j]**2, +* j=1 +* +* where T[i,j] is element of the current simplex table, and +* +* ( 1, if lambdaN[j] is in the reference space +* eta[j] = { +* ( 0, otherwise +* +* ( 1, if lambdaB[i] is in the reference space +* delta[i] = { +* ( 0, otherwise +* +* Dual basic variable lambdaN[j] corresponds to primal non-basic +* variable xN[j], and dual non-basic variable lambdaB[j] corresponds +* to primal basic variable xB[i]. +* +* NOTE: For testing/debugging only. */ + +double spy_eval_gamma_i(SPXLP *lp, SPYSE *se, int i) +{ int m = lp->m; + int n = lp->n; + int *head = lp->head; + char *refsp = se->refsp; + double *rho = se->work; + int j, k; + double gamma_i, t_ij; + xassert(se->valid); + xassert(1 <= i && i <= m); + k = head[i]; /* x[k] = xB[i] */ + gamma_i = (refsp[k] ? 1.0 : 0.0); + spx_eval_rho(lp, i, rho); + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + if (refsp[k]) + { t_ij = spx_eval_tij(lp, rho, j); + gamma_i += t_ij * t_ij; + } + } + return gamma_i; +} + +/*********************************************************************** +* spy_chuzr_pse - choose basic variable (dual projected steepest edge) +* +* This routine chooses most eligible basic variable xB[p] according +* to the dual projected steepest edge method: +* +* r[p]**2 r[i]**2 +* -------- = max -------- , +* gamma[p] i in I gamma[i] +* +* ( lB[i] - beta[i], if beta[i] < lB[i] +* ( +* r[i] = { 0, if lB[i] <= beta[i] <= uB[i] +* ( +* ( uB[i] - beta[i], if beta[i] > uB[i] +* +* where I <= {1, ..., m} is the set of indices of eligible basic +* variables, beta[i] is current value of xB[i], lB[i] and uB[i] are, +* resp., lower and upper bounds of xB[i], r[i] is bound violation. +* +* Current values of basic variables should be placed in the array +* locations beta[1], ..., beta[m]. +* +* Indices of eligible basic variables i in I should be placed in the +* array locations list[1], ..., list[num], where num = |J| > 0 is the +* total number of such variables. +* +* On exit the routine returns p, the index of the basic variable xB[p] +* chosen. */ + +int spy_chuzr_pse(SPXLP *lp, SPYSE *se, const double beta[/*1+m*/], + int num, const int list[]) +{ int m = lp->m; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + double *gamma = se->gamma; + int i, k, p, t; + double best, ri, temp; + xassert(0 < num && num <= m); + p = 0, best = -1.0; + for (t = 1; t <= num; t++) + { i = list[t]; + k = head[i]; /* x[k] = xB[i] */ + if (beta[i] < l[k]) + ri = l[k] - beta[i]; + else if (beta[i] > u[k]) + ri = u[k] - beta[i]; + else + xassert(t != t); + /* FIXME */ + if (gamma[i] < DBL_EPSILON) + temp = 0.0; + else + temp = (ri * ri) / gamma[i]; + if (best < temp) + p = i, best = temp; + } + xassert(p != 0); + return p; +} + +/*********************************************************************** +* spy_update_gamma - update dual proj. steepest edge weights exactly +* +* This routine updates the vector gamma = (gamma[i]) of dual projected +* steepest edge weights exactly, for the adjacent basis. +* +* On entry to the routine the content of the se object should be valid +* and should correspond to the current basis. +* +* The parameter 1 <= p <= m specifies basic variable xB[p] which +* becomes non-basic variable xN[q] in the adjacent basis. +* +* The parameter 1 <= q <= n-m specified non-basic variable xN[q] which +* becomes basic variable xB[p] in the adjacent basis. +* +* It is assumed that the array trow contains elements of p-th (pivot) +* row T'[p] of the simplex table in locations trow[1], ..., trow[n-m]. +* It is also assumed that the array tcol contains elements of q-th +* (pivot) column T[q] of the simple table in locations tcol[1], ..., +* tcol[m]. (These row and column should be computed for the current +* basis.) +* +* For details about the formulae used see the program documentation. +* +* The routine also computes the relative error: +* +* e = |gamma[p] - gamma'[p]| / (1 + |gamma[p]|), +* +* where gamma'[p] is the weight for lambdaB[p] (which is dual +* non-basic variable corresponding to xB[p]) on entry to the routine, +* and returns e on exit. (If e happens to be large enough, the calling +* program may reset the reference space, since other weights also may +* be inaccurate.) */ + +double spy_update_gamma(SPXLP *lp, SPYSE *se, int p, int q, + const double trow[/*1+n-m*/], const double tcol[/*1+m*/]) +{ int m = lp->m; + int n = lp->n; + int *head = lp->head; + char *refsp = se->refsp; + double *gamma = se->gamma; + double *u = se->work; + int i, j, k, ptr, end; + double gamma_p, delta_p, e, r, t1, t2; + xassert(se->valid); + xassert(1 <= p && p <= m); + xassert(1 <= q && q <= n-m); + /* compute gamma[p] in current basis more accurately; also + * compute auxiliary vector u */ + k = head[p]; /* x[k] = xB[p] */ + gamma_p = delta_p = (refsp[k] ? 1.0 : 0.0); + for (i = 1; i <= m; i++) + u[i] = 0.0; + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + if (refsp[k] && trow[j] != 0.0) + { gamma_p += trow[j] * trow[j]; + /* u := u + T[p,j] * N[j], where N[j] = A[k] is constraint + * matrix column corresponding to xN[j] */ + ptr = lp->A_ptr[k]; + end = lp->A_ptr[k+1]; + for (; ptr < end; ptr++) + u[lp->A_ind[ptr]] += trow[j] * lp->A_val[ptr]; + } + } + bfd_ftran(lp->bfd, u); + /* compute relative error in gamma[p] */ + e = fabs(gamma_p - gamma[p]) / (1.0 + gamma_p); + /* compute new gamma[p] */ + gamma[p] = gamma_p / (tcol[p] * tcol[p]); + /* compute new gamma[i] for all i != p */ + for (i = 1; i <= m; i++) + { if (i == p) + continue; + /* compute r[i] = T[i,q] / T[p,q] */ + r = tcol[i] / tcol[p]; + /* compute new gamma[i] */ + t1 = gamma[i] + r * (r * gamma_p + u[i] + u[i]); + k = head[i]; /* x[k] = xB[i] */ + t2 = (refsp[k] ? 1.0 : 0.0) + delta_p * r * r; + gamma[i] = (t1 >= t2 ? t1 : t2); + } + return e; +} + +/*********************************************************************** +* spy_free_se - deallocate dual pricing data block +* +* This routine deallocates the memory used for arrays in the dual +* pricing data block. */ + +void spy_free_se(SPXLP *lp, SPYSE *se) +{ xassert(lp == lp); + tfree(se->refsp); + tfree(se->gamma); + tfree(se->work); + return; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spychuzr.h b/resources/3rdparty/glpk-4.57/src/simplex/spychuzr.h new file mode 100644 index 000000000..5be8192ef --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spychuzr.h @@ -0,0 +1,86 @@ +/* spychuzr.h */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef SPYCHUZR_H +#define SPYCHUZR_H + +#include "spxlp.h" + +#define spy_chuzr_sel _glp_spy_chuzr_sel +int spy_chuzr_sel(SPXLP *lp, const double beta[/*1+m*/], double tol, + double tol1, int list[/*1+m*/]); +/* select eligible basic variables */ + +#define spy_chuzr_std _glp_spy_chuzr_std +int spy_chuzr_std(SPXLP *lp, const double beta[/*1+m*/], int num, + const int list[]); +/* choose basic variable (dual Dantzig's rule) */ + +typedef struct SPYSE SPYSE; + +struct SPYSE +{ /* dual projected steepest edge and Devex pricing data block */ + int valid; + /* content validity flag */ + char *refsp; /* char refsp[1+n]; */ + /* refsp[0] is not used; + * refsp[k], 1 <= k <= n, is the flag meaning that dual variable + * lambda[k] is in the dual reference space */ + double *gamma; /* double gamma[1+m]; */ + /* gamma[0] is not used; + * gamma[i], 1 <= i <= m, is the weight for reduced cost r[i] + * of dual non-basic variable lambdaB[j] in the current basis + * (r[i] is bound violation for basic variable xB[i]) */ + double *work; /* double work[1+m]; */ + /* working array */ +}; + +#define spy_alloc_se _glp_spy_alloc_se +void spy_alloc_se(SPXLP *lp, SPYSE *se); +/* allocate dual pricing data block */ + +#define spy_reset_refsp _glp_spy_reset_refsp +void spy_reset_refsp(SPXLP *lp, SPYSE *se); +/* reset dual reference space */ + +#define spy_eval_gamma_i _glp_spy_eval_gamma_i +double spy_eval_gamma_i(SPXLP *lp, SPYSE *se, int i); +/* compute dual projected steepest edge weight directly */ + +#define spy_chuzr_pse _glp_spy_chuzr_pse +int spy_chuzr_pse(SPXLP *lp, SPYSE *se, const double beta[/*1+m*/], + int num, const int list[]); +/* choose basic variable (dual projected steepest edge) */ + +#define spy_update_gamma _glp_spy_update_gamma +double spy_update_gamma(SPXLP *lp, SPYSE *se, int p, int q, + const double trow[/*1+n-m*/], const double tcol[/*1+m*/]); +/* update dual projected steepest edge weights exactly */ + +#define spy_free_se _glp_spy_free_se +void spy_free_se(SPXLP *lp, SPYSE *se); +/* deallocate dual pricing data block */ + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/simplex/spydual.c b/resources/3rdparty/glpk-4.57/src/simplex/spydual.c new file mode 100644 index 000000000..9d08fbdc9 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/simplex/spydual.c @@ -0,0 +1,1221 @@ +/* spydual.c */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "simplex.h" +#include "spxat.h" +#include "spxnt.h" +#include "spxprob.h" +#include "spychuzc.h" +#include "spychuzr.h" + +#define USE_AT 1 +/* 1 - use A in row-wise format + * 0 - use N in row-wise format */ +/* (Looks like using A' provide more accuracy for dual simplex.) */ + +#define EXCL 1 +/* 1 - exclude fixed non-basic variables + * 0 - don't exclude variables */ + +#define SHIFT 1 +/* 1 - shift bounds of variables toward zero + * 0 - don't shift bounds of variables */ + +#define CHECK_ACCURACY 0 +/* (for debugging) */ + +struct csa +{ /* common storage area */ + SPXLP *lp; + /* LP problem data and its (current) basis; this LP has m rows + * and n columns */ + int dir; + /* original optimization direction: + * +1 - minimization + * -1 - maximization */ + double *b; /* double b[1+m]; */ + /* copy of original right-hand sides */ + double *l; /* double l[1+n]; */ + /* copy of original lower bounds */ + double *u; /* double u[1+n]; */ + /* copy of original upper bounds */ + SPXAT *at; + /* mxn-matrix A of constraint coefficients, in sparse row-wise + * format (NULL if not used) */ + SPXNT *nt; + /* mx(n-m)-matrix N composed of non-basic columns of constraint + * matrix A, in sparse row-wise format (NULL if not used) */ + int phase; + /* search phase: + * 0 - not determined yet + * 1 - searching for dual feasible solution + * 2 - searching for optimal solution */ + double *beta; /* double beta[1+m]; */ + /* beta[i] is primal value of basic variable xB[i] */ + int beta_st; + /* status of the vector beta: + * 0 - undefined + * 1 - just computed + * 2 - updated */ + double *d; /* double d[1+n-m]; */ + /* d[j] is reduced cost of non-basic variable xN[j] */ + int d_st; + /* status of the vector d: + * 0 - undefined + * 1 - just computed + * 2 - updated */ + SPYSE *se; + /* dual projected steepest edge and Devex pricing data block + * (NULL if not used) */ + int num; + /* number of eligible basic variables */ + int *list; /* int list[1+m]; */ + /* list[1], ..., list[num] are indices i of eligible basic + * variables xB[i] */ + int p; + /* xB[p] is a basic variable chosen to leave the basis */ + double *trow; /* double trow[1+n-m]; */ + /* p-th (pivot) row of the simplex table */ + int q; + /* xN[q] is a non-basic variable chosen to enter the basis */ + double *tcol; /* double tcol[1+m]; */ + /* q-th (pivot) column of the simplex table */ + double *work; /* double work[1+m]; */ + /* working array */ + double *work1; /* double work1[1+n-m]; */ + /* another working array */ + int p_stat, d_stat; + /* primal and dual solution statuses */ + /*--------------------------------------------------------------*/ + /* control parameters (see struct glp_smcp) */ + int msg_lev; + /* message level */ + int dualp; + /* if this flag is set, report failure in case of instability */ + int harris; + /* dual ratio test technique: + * 0 - textbook ratio test + * 1 - Harris' two pass ratio test */ + double tol_bnd, tol_bnd1; + /* primal feasibility tolerances */ + double tol_dj, tol_dj1; + /* dual feasibility tolerances */ + double tol_piv; + /* pivot tolerance */ + double obj_lim; + /* objective limit */ + int it_lim; + /* iteration limit */ + int tm_lim; + /* time limit, milliseconds */ + int out_frq; + /* display output frequency, iterations */ + int out_dly; + /* display output delay, milliseconds */ + /*--------------------------------------------------------------*/ + /* working parameters */ + double tm_beg; + /* time value at the beginning of the search */ + int it_beg; + /* simplex iteration count at the beginning of the search */ + int it_cnt; + /* simplex iteration count; it increases by one every time the + * basis changes */ + int it_dpy; + /* simplex iteration count at most recent display output */ + int inv_cnt; + /* basis factorization count since most recent display output */ +}; + +/*********************************************************************** +* check_flags - check correctness of active bound flags +* +* This routine checks that flags specifying active bounds of all +* non-basic variables are correct. +* +* NOTE: It is important to note that if bounds of variables have been +* changed, active bound flags should be corrected accordingly. */ + +static void check_flags(struct csa *csa) +{ SPXLP *lp = csa->lp; + int m = lp->m; + int n = lp->n; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + char *flag = lp->flag; + int j, k; + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + if (l[k] == -DBL_MAX && u[k] == +DBL_MAX) + xassert(!flag[j]); + else if (l[k] != -DBL_MAX && u[k] == +DBL_MAX) + xassert(!flag[j]); + else if (l[k] == -DBL_MAX && u[k] != +DBL_MAX) + xassert(flag[j]); + else if (l[k] == u[k]) + xassert(!flag[j]); + } + return; +} + +/*********************************************************************** +* set_art_bounds - set artificial right-hand sides and bounds +* +* This routine sets artificial right-hand sides and artificial bounds +* for all variables to minimize the sum of dual infeasibilities on +* phase I. Given current reduced costs d = (d[j]) this routine also +* sets active artificial bounds of non-basic variables to provide dual +* feasibility (this is always possible because all variables have both +* lower and upper artificial bounds). */ + +static void set_art_bounds(struct csa *csa) +{ SPXLP *lp = csa->lp; + int m = lp->m; + int n = lp->n; + double *b = lp->b; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + char *flag = lp->flag; + double *d = csa->d; + int i, j, k; + /* set artificial right-hand sides */ + for (i = 1; i <= m; i++) + b[i] = 0.0; + /* set artificial bounds depending on types of variables */ + for (k = 1; k <= n; k++) + { if (csa->l[k] == -DBL_MAX && csa->u[k] == +DBL_MAX) + { /* force free variables to enter the basis */ + l[k] = -1e3, u[k] = +1e3; + } + else if (csa->l[k] != -DBL_MAX && csa->u[k] == +DBL_MAX) + l[k] = 0.0, u[k] = +1.0; + else if (csa->l[k] == -DBL_MAX && csa->u[k] != +DBL_MAX) + l[k] = -1.0, u[k] = 0.0; + else + l[k] = u[k] = 0.0; + } + /* set active artificial bounds for non-basic variables */ + xassert(csa->d_st == 1); + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + flag[j] = (l[k] != u[k] && d[j] < 0.0); + } + /* invalidate values of basic variables, since active bounds of + * non-basic variables have been changed */ + csa->beta_st = 0; + return; +} + +/*********************************************************************** +* set_orig_bounds - restore original right-hand sides and bounds +* +* This routine restores original right-hand sides and original bounds +* for all variables. This routine also sets active original bounds for +* non-basic variables; for double-bounded non-basic variables current +* reduced costs d = (d[j]) are used to decide which bound (lower or +* upper) should be made active. */ + +void set_orig_bounds(struct csa *csa) +{ SPXLP *lp = csa->lp; + int m = lp->m; + int n = lp->n; + double *b = lp->b; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + char *flag = lp->flag; + double *d = csa->d; + int j, k; + /* restore original right-hand sides */ + memcpy(b, csa->b, (1+m) * sizeof(double)); + /* restore original bounds of all variables */ + memcpy(l, csa->l, (1+n) * sizeof(double)); + memcpy(u, csa->u, (1+n) * sizeof(double)); + /* set active original bounds for non-basic variables */ + xassert(csa->d_st == 1); + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + if (l[k] == -DBL_MAX && u[k] == +DBL_MAX) + flag[j] = 0; + else if (l[k] != -DBL_MAX && u[k] == +DBL_MAX) + flag[j] = 0; + else if (l[k] == -DBL_MAX && u[k] != +DBL_MAX) + flag[j] = 1; + else if (l[k] != u[k]) + flag[j] = (d[j] < 0.0); + else + flag[j] = 0; + } + /* invalidate values of basic variables, since active bounds of + * non-basic variables have been changed */ + csa->beta_st = 0; + return; +} + +/*********************************************************************** +* check_feas - check dual feasibility of basic solution +* +* This routine checks that reduced costs of all non-basic variables +* d = (d[j]) have correct signs. +* +* Reduced cost d[j] is considered as having correct sign within the +* specified tolerance depending on status of non-basic variable xN[j] +* if one of the following conditions is met: +* +* xN[j] is free -eps <= d[j] <= +eps +* +* xN[j] has its lower bound active d[j] >= -eps +* +* xN[j] has its upper bound active d[j] <= +eps +* +* xN[j] is fixed d[j] has any value +* +* where eps = tol + tol1 * |cN[j]|, cN[j] is the objective coefficient +* at xN[j]. (See also the routine spx_chuzc_sel.) +* +* The flag recov allows the routine to recover dual feasibility by +* changing active bounds of non-basic variables. (For example, if +* xN[j] has its lower bound active and d[j] < -eps, the feasibility +* can be recovered by making xN[j] active on its upper bound.) +* +* If the basic solution is dual feasible, the routine returns zero. +* If the basic solution is dual infeasible, but its dual feasibility +* can be recovered (or has been recovered, if the flag recov is set), +* the routine returns a negative value. Otherwise, the routine returns +* the number j of some non-basic variable xN[j], whose reduced cost +* d[j] is dual infeasible and cannot be recovered. */ + +static int check_feas(struct csa *csa, double tol, double tol1, + int recov) +{ SPXLP *lp = csa->lp; + int m = lp->m; + int n = lp->n; + double *c = lp->c; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + char *flag = lp->flag; + double *d = csa->d; + int j, k, ret = 0; + double eps; + /* reduced costs should be just computed */ + xassert(csa->d_st == 1); + /* walk thru list of non-basic variables */ + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + if (l[k] == u[k]) + { /* xN[j] is fixed variable; skip it */ + continue; + } + /* determine absolute tolerance eps[j] */ + eps = tol + tol1 * (c[k] >= 0.0 ? +c[k] : -c[k]); + /* check dual feasibility of xN[j] */ + if (d[j] > +eps) + { /* xN[j] should have its lower bound active */ + if (l[k] == -DBL_MAX || flag[j]) + { /* but it either has no lower bound or its lower bound + * is inactive */ + if (l[k] == -DBL_MAX) + { /* cannot recover, since xN[j] has no lower bound */ + ret = j; + break; + } + /* recovering is possible */ + if (recov) + flag[j] = 0; + ret = -1; + } + } + else if (d[j] < -eps) + { /* xN[j] should have its upper bound active */ + if (!flag[j]) + { /* but it either has no upper bound or its upper bound + * is inactive */ + if (u[k] == +DBL_MAX) + { /* cannot recover, since xN[j] has no upper bound */ + ret = j; + break; + } + /* recovering is possible */ + if (recov) + flag[j] = 1; + ret = -1; + } + } + } + if (recov && ret) + { /* invalidate values of basic variables, since active bounds + * of non-basic variables have been changed */ + csa->beta_st = 0; + } + return ret; +} + +#if CHECK_ACCURACY +/*********************************************************************** +* err_in_vec - compute maximal relative error between two vectors +* +* This routine computes and returns maximal relative error between +* n-vectors x and y: +* +* err_max = max |x[i] - y[i]| / (1 + |x[i]|). +* +* NOTE: This routine is intended only for debugginig purposes. */ + +static double err_in_vec(int n, const double x[], const double y[]) +{ int i; + double err, err_max; + err_max = 0.0; + for (i = 1; i <= n; i++) + { err = fabs(x[i] - y[i]) / (1.0 + fabs(x[i])); + if (err_max < err) + err_max = err; + } + return err_max; +} +#endif + +#if CHECK_ACCURACY +/*********************************************************************** +* err_in_beta - compute maximal relative error in vector beta +* +* This routine computes and returns maximal relative error in vector +* of values of basic variables beta = (beta[i]). +* +* NOTE: This routine is intended only for debugginig purposes. */ + +static double err_in_beta(struct csa *csa) +{ SPXLP *lp = csa->lp; + int m = lp->m; + double err, *beta; + beta = talloc(1+m, double); + spx_eval_beta(lp, beta); + err = err_in_vec(m, beta, csa->beta); + tfree(beta); + return err; +} +#endif + +#if CHECK_ACCURACY +/*********************************************************************** +* err_in_d - compute maximal relative error in vector d +* +* This routine computes and returns maximal relative error in vector +* of reduced costs of non-basic variables d = (d[j]). +* +* NOTE: This routine is intended only for debugginig purposes. */ + +static double err_in_d(struct csa *csa) +{ SPXLP *lp = csa->lp; + int m = lp->m; + int n = lp->n; + int j; + double err, *pi, *d; + pi = talloc(1+m, double); + d = talloc(1+n-m, double); + spx_eval_pi(lp, pi); + for (j = 1; j <= n-m; j++) + d[j] = spx_eval_dj(lp, pi, j); + err = err_in_vec(n-m, d, csa->d); + tfree(pi); + tfree(d); + return err; +} +#endif + +#if CHECK_ACCURACY +/*********************************************************************** +* err_in_gamma - compute maximal relative error in vector gamma +* +* This routine computes and returns maximal relative error in vector +* of projected steepest edge weights gamma = (gamma[j]). +* +* NOTE: This routine is intended only for debugginig purposes. */ + +static double err_in_gamma(struct csa *csa) +{ SPXLP *lp = csa->lp; + int m = lp->m; + int n = lp->n; + SPYSE *se = csa->se; + int i; + double err, *gamma; + xassert(se != NULL); +gamma = talloc(1+m, double); + for (i = 1; i <= m; i++) + gamma[i] = spy_eval_gamma_i(lp, se, i); + err = err_in_vec(m, gamma, se->gamma); + tfree(gamma); + return err; +} +#endif + +#if CHECK_ACCURACY +/*********************************************************************** +* check_accuracy - check accuracy of basic solution components +* +* This routine checks accuracy of current basic solution components. +* +* NOTE: This routine is intended only for debugginig purposes. */ + +static void check_accuracy(struct csa *csa) +{ double e_beta, e_d, e_gamma; + e_beta = err_in_beta(csa); + e_d = err_in_d(csa); + if (csa->se == NULL) + e_gamma = 0.; + else + e_gamma = err_in_gamma(csa); + xprintf("e_beta = %10.3e; e_d = %10.3e; e_gamma = %10.3e\n", + e_beta, e_d, e_gamma); + xassert(e_beta <= 1e-5 && e_d <= 1e-5 && e_gamma <= 1e-3); + return; +} +#endif + +/*********************************************************************** +* choose_pivot - choose xB[p] and xN[q] +* +* Given the list of eligible basic variables this routine first +* chooses basic variable xB[p]. This choice is always possible, +* because the list is assumed to be non-empty. Then the routine +* computes p-th row T[p,*] of the simplex table T[i,j] and chooses +* non-basic variable xN[q]. If the pivot T[p,q] is small in magnitude, +* the routine attempts to choose another xB[p] and xN[q] in order to +* avoid badly conditioned adjacent bases. */ + +static void choose_pivot(struct csa *csa) +{ SPXLP *lp = csa->lp; + int m = lp->m; + int n = lp->n; + double *l = lp->l; + int *head = lp->head; + SPXAT *at = csa->at; + SPXNT *nt = csa->nt; + double *beta = csa->beta; + double *d = csa->d; + SPYSE *se = csa->se; + int *list = csa->list; + double *rho = csa->work; + double *trow = csa->work1; + int nnn, try, k, p, q, t; + xassert(csa->beta_st); + xassert(csa->d_st); + /* initial number of eligible basic variables */ + nnn = csa->num; + /* nothing has been chosen so far */ + csa->p = 0; + try = 0; +try: /* choose basic variable xB[p] */ + xassert(nnn > 0); + try++; + if (se == NULL) + { /* dual Dantzig's rule */ + p = spy_chuzr_std(lp, beta, nnn, list); + } + else + { /* dual projected steepest edge */ + p = spy_chuzr_pse(lp, se, beta, nnn, list); + } + xassert(1 <= p && p <= m); + /* compute p-th row of inv(B) */ + spx_eval_rho(lp, p, rho); + /* compute p-th row of the simplex table */ + if (at != NULL) + spx_eval_trow1(lp, at, rho, trow); + else + spx_nt_prod(lp, nt, trow, 1, -1.0, rho); + /* choose non-basic variable xN[q] */ + k = head[p]; /* x[k] = xB[p] */ + if (!csa->harris) + q = spy_chuzc_std(lp, d, beta[p] < l[k] ? +1. : -1., trow, + csa->tol_piv, .30 * csa->tol_dj, .30 * csa->tol_dj1); + else + q = spy_chuzc_harris(lp, d, beta[p] < l[k] ? +1. : -1., trow, + csa->tol_piv, .35 * csa->tol_dj, .35 * csa->tol_dj1); + /* either keep previous choice or accept new choice depending on + * which one is better */ + if (csa->p == 0 || q == 0 || + fabs(trow[q]) > fabs(csa->trow[csa->q])) + { csa->p = p; + memcpy(&csa->trow[1], &trow[1], (n-m) * sizeof(double)); + csa->q = q; + } + /* check if current choice is acceptable */ + if (csa->q == 0 || fabs(csa->trow[csa->q]) >= 0.001) + goto done; + if (nnn == 1) + goto done; + if (try == 5) + goto done; + /* try to choose other xB[p] and xN[q] */ + /* find xB[p] in the list */ + for (t = 1; t <= nnn; t++) + if (list[t] == p) break; + xassert(t <= nnn); + /* move xB[p] to the end of the list */ + list[t] = list[nnn], list[nnn] = p; + /* and exclude it from consideration */ + nnn--; + /* repeat the choice */ + goto try; +done: /* the choice has been made */ + return; +} + +/*********************************************************************** +* display - display search progress +* +* This routine displays some information about the search progress +* that includes: +* +* search phase; +* +* number of simplex iterations performed by the solver; +* +* original objective value (only on phase II); +* +* sum of (scaled) dual infeasibilities for original bounds; +* +* number of dual infeasibilities (phase I) or primal infeasibilities +* (phase II); +* +* number of basic factorizations since last display output. */ + +static void display(struct csa *csa, int spec) +{ SPXLP *lp = csa->lp; + int m = lp->m; + int n = lp->n; + int *head = lp->head; + char *flag = lp->flag; + double *l = csa->l; /* original lower bounds */ + double *u = csa->u; /* original upper bounds */ + double *beta = csa->beta; + double *d = csa->d; + int j, k, nnn; + double sum; + /* check if the display output should be skipped */ + if (csa->msg_lev < GLP_MSG_ON) goto skip; + if (csa->out_dly > 0 && + 1000.0 * xdifftime(xtime(), csa->tm_beg) < csa->out_dly) + goto skip; + if (csa->it_cnt == csa->it_dpy) goto skip; + if (!spec && csa->it_cnt % csa->out_frq != 0) goto skip; + /* display search progress depending on search phase */ + switch (csa->phase) + { case 1: + /* compute sum and number of (scaled) dual infeasibilities + * for original bounds */ + sum = 0.0, nnn = 0; + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + if (d[j] > 0.0) + { /* xN[j] should have lower bound */ + if (l[k] == -DBL_MAX) + { sum += d[j]; + if (d[j] > +1e-7) + nnn++; + } + } + else if (d[j] < 0.0) + { /* xN[j] should have upper bound */ + if (u[k] == +DBL_MAX) + { sum -= d[j]; + if (d[j] < -1e-7) + nnn++; + } + } + } + /* on phase I variables have artificial bounds which are + * meaningless for original LP, so corresponding objective + * function value is also meaningless */ + xprintf(" %6d: %23s inf = %11.3e (%d)", + csa->it_cnt, "", sum, nnn); + break; + case 2: + /* compute sum of (scaled) dual infeasibilities */ + sum = 0.0, nnn = 0; + for (j = 1; j <= n-m; j++) + { k = head[m+j]; /* x[k] = xN[j] */ + if (d[j] > 0.0) + { /* xN[j] should have its lower bound active */ + if (l[k] == -DBL_MAX || flag[j]) + sum += d[j]; + } + else if (d[j] < 0.0) + { /* xN[j] should have its upper bound active */ + if (l[k] != u[k] && !flag[j]) + sum -= d[j]; + } + } + /* compute number of primal infeasibilities */ + nnn = spy_chuzr_sel(lp, beta, csa->tol_bnd, csa->tol_bnd1, + NULL); + xprintf("#%6d: obj = %17.9e inf = %11.3e (%d)", + csa->it_cnt, (double)csa->dir * spx_eval_obj(lp, beta), + sum, nnn); + break; + default: + xassert(csa != csa); + } + if (csa->inv_cnt) + { /* number of basis factorizations performed */ + xprintf(" %d", csa->inv_cnt); + csa->inv_cnt = 0; + } + xprintf("\n"); + csa->it_dpy = csa->it_cnt; +skip: return; +} + +/*********************************************************************** +* spy_dual - driver to dual simplex method +* +* This routine is a driver to the two-phase dual simplex method. +* +* On exit this routine returns one of the following codes: +* +* 0 LP instance has been successfully solved. +* +* GLP_EOBJLL +* Objective lower limit has been reached (maximization). +* +* GLP_EOBJUL +* Objective upper limit has been reached (minimization). +* +* GLP_EITLIM +* Iteration limit has been exhausted. +* +* GLP_ETMLIM +* Time limit has been exhausted. +* +* GLP_EFAIL +* The solver failed to solve LP instance. */ + +static int dual_simplex(struct csa *csa) +{ /* dual simplex method main logic routine */ + SPXLP *lp = csa->lp; + int m = lp->m; + int n = lp->n; + double *l = lp->l; + double *u = lp->u; + int *head = lp->head; + SPXNT *nt = csa->nt; + double *beta = csa->beta; + double *d = csa->d; + SPYSE *se = csa->se; + int *list = csa->list; + double *trow = csa->trow; + double *tcol = csa->tcol; + double *pi = csa->work; + int msg_lev = csa->msg_lev; + double tol_bnd = csa->tol_bnd; + double tol_bnd1 = csa->tol_bnd1; + double tol_dj = csa->tol_dj; + double tol_dj1 = csa->tol_dj1; + int j, k, p_flag, refct, ret; + check_flags(csa); +loop: /* main loop starts here */ + /* compute factorization of the basis matrix */ + if (!lp->valid) + { double cond; + ret = spx_factorize(lp); + csa->inv_cnt++; + if (ret != 0) + { if (msg_lev >= GLP_MSG_ERR) + xprintf("Error: unable to factorize the basis matrix (%d" + ")\n", ret); + csa->p_stat = csa->d_stat = GLP_UNDEF; + ret = GLP_EFAIL; + goto fini; + } + /* check condition of the basis matrix */ + cond = bfd_condest(lp->bfd); + if (cond > 1.0 / DBL_EPSILON) + { if (msg_lev >= GLP_MSG_ERR) + xprintf("Error: basis matrix is singular to working prec" + "ision (cond = %.3g)\n", cond); + csa->p_stat = csa->d_stat = GLP_UNDEF; + ret = GLP_EFAIL; + goto fini; + } + if (cond > 0.001 / DBL_EPSILON) + { if (msg_lev >= GLP_MSG_ERR) + xprintf("Warning: basis matrix is ill-conditioned (cond " + "= %.3g)\n", cond); + } + /* invalidate basic solution components */ + csa->beta_st = csa->d_st = 0; + } + /* compute reduced costs of non-basic variables d = (d[j]) */ + if (!csa->d_st) + { spx_eval_pi(lp, pi); + for (j = 1; j <= n-m; j++) + d[j] = spx_eval_dj(lp, pi, j); + csa->d_st = 1; /* just computed */ + /* determine the search phase, if not determined yet (this is + * performed only once at the beginning of the search for the + * original bounds) */ + if (!csa->phase) + { j = check_feas(csa, 0.97 * tol_dj, 0.97 * tol_dj1, 1); + if (j > 0) + { /* initial basic solution is dual infeasible and cannot + * be recovered */ + /* start to search for dual feasible solution */ + set_art_bounds(csa); + csa->phase = 1; + } + else + { /* initial basic solution is either dual feasible or its + * dual feasibility has been recovered */ + /* start to search for optimal solution */ + csa->phase = 2; + } + } + /* make sure that current basic solution is dual feasible */ + j = check_feas(csa, tol_dj, tol_dj1, 0); + if (j) + { /* dual feasibility is broken due to excessive round-off + * errors */ + if (bfd_get_count(lp->bfd)) + { /* try to provide more accuracy */ + lp->valid = 0; + goto loop; + } + if (msg_lev >= GLP_MSG_ERR) + xprintf("Warning: numerical instability (dual simplex, p" + "hase %s)\n", csa->phase == 1 ? "I" : "II"); + if (csa->dualp) + { /* do not continue the search; report failure */ + csa->p_stat = csa->d_stat = GLP_UNDEF; + ret = -1; /* special case of GLP_EFAIL */ + goto fini; + } + /* try to recover dual feasibility */ + j = check_feas(csa, 0.97 * tol_dj, 0.97 * tol_dj1, 1); + if (j > 0) + { /* dual feasibility cannot be recovered (this may happen + * only on phase II) */ + xassert(csa->phase == 2); + /* restart to search for dual feasible solution */ + set_art_bounds(csa); + csa->phase = 1; + } + } + } + /* at this point the search phase is determined */ + xassert(csa->phase == 1 || csa->phase == 2); + /* compute values of basic variables beta = (beta[i]) */ + if (!csa->beta_st) + { spx_eval_beta(lp, beta); + csa->beta_st = 1; /* just computed */ + } + /* reset the dual reference space, if necessary */ + if (se != NULL && !se->valid) + spy_reset_refsp(lp, se), refct = 1000; + /* at this point the basis factorization and all basic solution + * components are valid */ + xassert(lp->valid && csa->beta_st && csa->d_st); + check_flags(csa); +#if CHECK_ACCURACY + /* check accuracy of current basic solution components (only for + * debugging) */ + check_accuracy(csa); +#endif + /* check if the objective limit has been reached */ + if (csa->phase == 2 && csa->obj_lim != DBL_MAX + && spx_eval_obj(lp, beta) >= csa->obj_lim) + { if (csa->beta_st != 1) + csa->beta_st = 0; + if (csa->d_st != 1) + csa->d_st = 0; + if (!(csa->beta_st && csa->d_st)) + goto loop; + display(csa, 1); + if (msg_lev >= GLP_MSG_ALL) + xprintf("OBJECTIVE %s LIMIT REACHED; SEARCH TERMINATED\n", + csa->dir > 0 ? "UPPER" : "LOWER"); + csa->num = spy_chuzr_sel(lp, beta, tol_bnd, tol_bnd1, list); + csa->p_stat = (csa->num == 0 ? GLP_FEAS : GLP_INFEAS); + csa->d_stat = GLP_FEAS; + ret = (csa->dir > 0 ? GLP_EOBJUL : GLP_EOBJLL); + goto fini; + } + /* check if the iteration limit has been exhausted */ + if (csa->it_cnt - csa->it_beg >= csa->it_lim) + { if (csa->beta_st != 1) + csa->beta_st = 0; + if (csa->d_st != 1) + csa->d_st = 0; + if (!(csa->beta_st && csa->d_st)) + goto loop; + display(csa, 1); + if (msg_lev >= GLP_MSG_ALL) + xprintf("ITERATION LIMIT EXCEEDED; SEARCH TERMINATED\n"); + if (csa->phase == 1) + { set_orig_bounds(csa); + check_flags(csa); + spx_eval_beta(lp, beta); + } + csa->num = spy_chuzr_sel(lp, beta, tol_bnd, tol_bnd1, list); + csa->p_stat = (csa->num == 0 ? GLP_FEAS : GLP_INFEAS); + csa->d_stat = (csa->phase == 1 ? GLP_INFEAS : GLP_FEAS); + ret = GLP_EITLIM; + goto fini; + } + /* check if the time limit has been exhausted */ + if (1000.0 * xdifftime(xtime(), csa->tm_beg) >= csa->tm_lim) + { if (csa->beta_st != 1) + csa->beta_st = 0; + if (csa->d_st != 1) + csa->d_st = 0; + if (!(csa->beta_st && csa->d_st)) + goto loop; + display(csa, 1); + if (msg_lev >= GLP_MSG_ALL) + xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); + if (csa->phase == 1) + { set_orig_bounds(csa); + check_flags(csa); + spx_eval_beta(lp, beta); + } + csa->num = spy_chuzr_sel(lp, beta, tol_bnd, tol_bnd1, list); + csa->p_stat = (csa->num == 0 ? GLP_FEAS : GLP_INFEAS); + csa->d_stat = (csa->phase == 1 ? GLP_INFEAS : GLP_FEAS); + ret = GLP_EITLIM; + goto fini; + } + /* display the search progress */ + display(csa, 0); + /* select eligible basic variables */ + switch (csa->phase) + { case 1: + csa->num = spy_chuzr_sel(lp, beta, 1e-8, 0.0, list); + break; + case 2: + csa->num = spy_chuzr_sel(lp, beta, tol_bnd, tol_bnd1, list); + break; + default: + xassert(csa != csa); + } + /* check for optimality */ + if (csa->num == 0) + { if (csa->beta_st != 1) + csa->beta_st = 0; + if (csa->d_st != 1) + csa->d_st = 0; + if (!(csa->beta_st && csa->d_st)) + goto loop; + /* current basis is optimal */ + display(csa, 1); + switch (csa->phase) + { case 1: + /* check for dual feasibility */ + set_orig_bounds(csa); + check_flags(csa); + if (check_feas(csa, tol_dj, tol_dj1, 0) == 0) + { /* dual feasible solution found; switch to phase II */ + csa->phase = 2; + xassert(!csa->beta_st); + goto loop; + } + /* no dual feasible solution exists */ + if (msg_lev >= GLP_MSG_ALL) + xprintf("LP HAS NO DUAL FEASIBLE SOLUTION\n"); + spx_eval_beta(lp, beta); + csa->num = spy_chuzr_sel(lp, beta, tol_bnd, tol_bnd1, + list); + csa->p_stat = (csa->num == 0 ? GLP_FEAS : GLP_INFEAS); + csa->d_stat = GLP_NOFEAS; + ret = 0; + goto fini; + case 2: + /* optimal solution found */ + if (msg_lev >= GLP_MSG_ALL) + xprintf("OPTIMAL LP SOLUTION FOUND\n"); + csa->p_stat = csa->d_stat = GLP_FEAS; + ret = 0; + goto fini; + default: + xassert(csa != csa); + } + } + /* choose xB[p] and xN[q] */ + choose_pivot(csa); + /* check for dual unboundedness */ + if (csa->q == 0) + { if (csa->beta_st != 1) + csa->beta_st = 0; + if (csa->d_st != 1) + csa->d_st = 0; + if (!(csa->beta_st && csa->d_st)) + goto loop; + display(csa, 1); + switch (csa->phase) + { case 1: + /* this should never happen */ + if (msg_lev >= GLP_MSG_ERR) + xprintf("Error: dual simplex failed\n"); + csa->p_stat = csa->d_stat = GLP_UNDEF; + ret = GLP_EFAIL; + goto fini; + case 2: + /* dual unboundedness detected */ + if (msg_lev >= GLP_MSG_ALL) + xprintf("LP HAS NO PRIMAL FEASIBLE SOLUTION\n"); + csa->p_stat = GLP_NOFEAS; + csa->d_stat = GLP_FEAS; + ret = 0; + goto fini; + default: + xassert(csa != csa); + } + } + /* compute q-th column of the simplex table */ + spx_eval_tcol(lp, csa->q, tcol); + /* FIXME: tcol[p] and trow[q] should be close to each other */ + xassert(tcol[csa->p] != 0.0); + /* update values of basic variables for adjacent basis */ + k = head[csa->p]; /* x[k] = xB[p] */ + p_flag = (l[k] != u[k] && beta[csa->p] > u[k]); + spx_update_beta(lp, beta, csa->p, p_flag, csa->q, tcol); + csa->beta_st = 2; + /* update reduced costs of non-basic variables for adjacent + * basis */ + if (spx_update_d(lp, d, csa->p, csa->q, trow, tcol) <= 1e-9) + { /* successful updating */ + csa->d_st = 2; + } + else + { /* new reduced costs are inaccurate */ + csa->d_st = 0; + } + /* update steepest edge weights for adjacent basis, if used */ + if (se != NULL) + { if (refct > 0) + { if (spy_update_gamma(lp, se, csa->p, csa->q, trow, tcol) + <= 1e-3) + { /* successful updating */ + refct--; + } + else + { /* new weights are inaccurate; reset reference space */ + se->valid = 0; + } + } + else + { /* too many updates; reset reference space */ + se->valid = 0; + } + } + /* update matrix N for adjacent basis, if used */ + if (nt != NULL) + spx_update_nt(lp, nt, csa->p, csa->q); + /* change current basis header to adjacent one */ + spx_change_basis(lp, csa->p, p_flag, csa->q); + /* and update factorization of the basis matrix */ + if (csa->p > 0) + spx_update_invb(lp, csa->p, head[csa->p]); + /* dual simplex iteration complete */ + csa->it_cnt++; + goto loop; +fini: return ret; +} + +int spy_dual(glp_prob *P, const glp_smcp *parm) +{ /* driver to dual simplex method */ + struct csa csa_, *csa = &csa_; + SPXLP lp; +#if USE_AT + SPXAT at; +#else + SPXNT nt; +#endif + SPYSE se; + int ret, *map, *daeh; + /* build working LP and its initial basis */ + memset(csa, 0, sizeof(struct csa)); + csa->lp = &lp; + spx_init_lp(csa->lp, P, EXCL); + spx_alloc_lp(csa->lp); + map = talloc(1+P->m+P->n, int); + spx_build_lp(csa->lp, P, EXCL, SHIFT, map); + spx_build_basis(csa->lp, P, map); + switch (P->dir) + { case GLP_MIN: + csa->dir = +1; + break; + case GLP_MAX: + csa->dir = -1; + break; + default: + xassert(P != P); + } + csa->b = talloc(1+csa->lp->m, double); + memcpy(csa->b, csa->lp->b, (1+csa->lp->m) * sizeof(double)); + csa->l = talloc(1+csa->lp->n, double); + memcpy(csa->l, csa->lp->l, (1+csa->lp->n) * sizeof(double)); + csa->u = talloc(1+csa->lp->n, double); + memcpy(csa->u, csa->lp->u, (1+csa->lp->n) * sizeof(double)); +#if USE_AT + /* build matrix A in row-wise format */ + csa->at = &at; + csa->nt = NULL; + spx_alloc_at(csa->lp, csa->at); + spx_build_at(csa->lp, csa->at); +#else + /* build matrix N in row-wise format for initial basis */ + csa->at = NULL; + csa->nt = &nt; + spx_alloc_nt(csa->lp, csa->nt); + spx_init_nt(csa->lp, csa->nt); + spx_build_nt(csa->lp, csa->nt); +#endif + /* allocate and initialize working components */ + csa->phase = 0; + csa->beta = talloc(1+csa->lp->m, double); + csa->beta_st = 0; + csa->d = talloc(1+csa->lp->n-csa->lp->m, double); + csa->d_st = 0; + switch (parm->pricing) + { case GLP_PT_STD: + csa->se = NULL; + break; + case GLP_PT_PSE: + csa->se = &se; + spy_alloc_se(csa->lp, csa->se); + break; + default: + xassert(parm != parm); + } + csa->list = talloc(1+csa->lp->m, int); + csa->trow = talloc(1+csa->lp->n-csa->lp->m, double); + csa->tcol = talloc(1+csa->lp->m, double); + csa->work = talloc(1+csa->lp->m, double); + csa->work1 = talloc(1+csa->lp->n-csa->lp->m, double); + /* initialize control parameters */ + csa->msg_lev = parm->msg_lev; + csa->dualp = (parm->meth == GLP_DUALP); + switch (parm->r_test) + { case GLP_RT_STD: + csa->harris = 0; + break; + case GLP_RT_HAR: + csa->harris = 1; + break; + default: + xassert(parm != parm); + } + csa->tol_bnd = parm->tol_bnd; + csa->tol_bnd1 = .001 * parm->tol_bnd; + csa->tol_dj = parm->tol_dj; + csa->tol_dj1 = .001 * parm->tol_dj; + csa->tol_piv = parm->tol_piv; + switch (P->dir) + { case GLP_MIN: + csa->obj_lim = + parm->obj_ul; + break; + case GLP_MAX: + csa->obj_lim = - parm->obj_ll; + break; + default: + xassert(parm != parm); + } + csa->it_lim = parm->it_lim; + csa->tm_lim = parm->tm_lim; + csa->out_frq = parm->out_frq; + csa->out_dly = parm->out_dly; + /* initialize working parameters */ + csa->tm_beg = xtime(); + csa->it_beg = csa->it_cnt = P->it_cnt; + csa->it_dpy = -1; + csa->inv_cnt = 0; + /* try to solve working LP */ + ret = dual_simplex(csa); + /* return basis factorization back to problem object */ + P->valid = csa->lp->valid; + P->bfd = csa->lp->bfd; + /* set solution status */ + P->pbs_stat = csa->p_stat; + P->dbs_stat = csa->d_stat; + /* if the solver failed, do not store basis header and basic + * solution components to problem object */ + if (ret == GLP_EFAIL) + goto skip; + /* convert working LP basis to original LP basis and store it to + * problem object */ + daeh = talloc(1+csa->lp->n, int); + spx_store_basis(csa->lp, P, map, daeh); + /* compute simplex multipliers for final basic solution found by + * the solver */ + spx_eval_pi(csa->lp, csa->work); + /* convert working LP solution to original LP solution and store + * it to problem object */ + spx_store_sol(csa->lp, P, SHIFT, map, daeh, csa->beta, csa->work, + csa->d); + tfree(daeh); + /* save simplex iteration count */ + P->it_cnt = csa->it_cnt; + /* report auxiliary/structural variable causing unboundedness */ + P->some = 0; + if (csa->p_stat == GLP_NOFEAS && csa->d_stat == GLP_FEAS) + { int k, kk; + /* xB[p] = x[k] causes dual unboundedness */ + xassert(1 <= csa->p && csa->p <= csa->lp->m); + k = csa->lp->head[csa->p]; + xassert(1 <= k && k <= csa->lp->n); + /* convert to number of original variable */ + for (kk = 1; kk <= P->m + P->n; kk++) + { if (abs(map[kk]) == k) + { P->some = kk; + break; + } + } + xassert(P->some != 0); + } +skip: /* deallocate working objects and arrays */ + spx_free_lp(csa->lp); + tfree(map); + tfree(csa->b); + tfree(csa->l); + tfree(csa->u); + if (csa->at != NULL) + spx_free_at(csa->lp, csa->at); + if (csa->nt != NULL) + spx_free_nt(csa->lp, csa->nt); + tfree(csa->beta); + tfree(csa->d); + if (csa->se != NULL) + spy_free_se(csa->lp, csa->se); + tfree(csa->list); + tfree(csa->trow); + tfree(csa->tcol); + tfree(csa->work); + tfree(csa->work1); + /* return to calling program */ + return ret >= 0 ? ret : GLP_EFAIL; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/zlib/README b/resources/3rdparty/glpk-4.57/src/zlib/README new file mode 100644 index 000000000..2796312f1 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/README @@ -0,0 +1,45 @@ +NOTE: Files in this subdirectory are NOT part of the GLPK package, but + are used with GLPK. + + The original code was modified according to GLPK requirements by + Andrew Makhorin . + + The following files were rewritten: + gzguts.h, zconf.h, zutil.h. + + The following files were added: + zio.h, zio.c. + + Other files were not changed. +************************************************************************ +zlib general purpose compression library +version 1.2.5, April 19th, 2010 + +Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would + be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + +The data format used by the zlib library is described by RFCs (Request +for Comments) 1950 to 1952 in the files +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate +format) and rfc1952.txt (gzip format). diff --git a/resources/3rdparty/glpk-4.57/src/zlib/adler32.c b/resources/3rdparty/glpk-4.57/src/zlib/adler32.c new file mode 100644 index 000000000..65ad6a5ad --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/adler32.c @@ -0,0 +1,169 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2007 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#define local static + +local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); + +#define BASE 65521UL /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware */ +#ifdef NO_DIVIDE +# define MOD(a) \ + do { \ + if (a >= (BASE << 16)) a -= (BASE << 16); \ + if (a >= (BASE << 15)) a -= (BASE << 15); \ + if (a >= (BASE << 14)) a -= (BASE << 14); \ + if (a >= (BASE << 13)) a -= (BASE << 13); \ + if (a >= (BASE << 12)) a -= (BASE << 12); \ + if (a >= (BASE << 11)) a -= (BASE << 11); \ + if (a >= (BASE << 10)) a -= (BASE << 10); \ + if (a >= (BASE << 9)) a -= (BASE << 9); \ + if (a >= (BASE << 8)) a -= (BASE << 8); \ + if (a >= (BASE << 7)) a -= (BASE << 7); \ + if (a >= (BASE << 6)) a -= (BASE << 6); \ + if (a >= (BASE << 5)) a -= (BASE << 5); \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD4(a) \ + do { \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD4(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD4(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +local uLong adler32_combine_(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* the derivation of this formula is left as an exercise for the reader */ + rem = (unsigned)(len2 % BASE); + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} diff --git a/resources/3rdparty/glpk-4.57/src/zlib/compress.c b/resources/3rdparty/glpk-4.57/src/zlib/compress.c new file mode 100644 index 000000000..ea4dfbe9d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/compress.c @@ -0,0 +1,80 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; + int level; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; +} diff --git a/resources/3rdparty/glpk-4.57/src/zlib/crc32.c b/resources/3rdparty/glpk-4.57/src/zlib/crc32.c new file mode 100644 index 000000000..91be372d2 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/crc32.c @@ -0,0 +1,442 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +# ifdef STDC /* need ANSI C limits.h to determine sizes */ +# include +# define BYFOUR +# if (UINT_MAX == 0xffffffffUL) + typedef unsigned int u4; +# else +# if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long u4; +# else +# if (USHRT_MAX == 0xffffffffUL) + typedef unsigned short u4; +# else +# undef BYFOUR /* can't find a four-byte integer type! */ +# endif +# endif +# endif +# endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR +# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); +local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2); + + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local unsigned long FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const unsigned long FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + unsigned long c; + int n, k; + unsigned long poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0UL; + for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) + poly |= 1UL << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (unsigned long)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const unsigned long FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const unsigned long FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + uInt len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + u4 endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = (u4)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = REV((u4)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +local uLong crc32_combine_(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} + +uLong ZEXPORT crc32_combine64(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} diff --git a/resources/3rdparty/glpk-4.57/src/zlib/crc32.h b/resources/3rdparty/glpk-4.57/src/zlib/crc32.h new file mode 100644 index 000000000..8053b6117 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const unsigned long FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/resources/3rdparty/glpk-4.57/src/zlib/deflate.c b/resources/3rdparty/glpk-4.57/src/zlib/deflate.c new file mode 100644 index 000000000..5c4022f3d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/deflate.c @@ -0,0 +1,1834 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://www.ietf.org/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local block_state deflate_rle OF((deflate_state *s, int flush)); +local block_state deflate_huff OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->wrap == 2 || + (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) + return Z_STREAM_ERROR; + + s = strm->state; + if (s->wrap) + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > s->w_size) { + length = s->w_size; + dictionary += dictLength - length; /* use the tail of the dictionary */ + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + strm->state->bi_valid = bits; + strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if ((strategy != s->strategy || func != configuration_table[level].func) && + strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_BLOCK); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong complen, wraplen; + Bytef *str; + + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (strm == Z_NULL || strm->state == Z_NULL) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return conservative bound */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return complen + wraplen; + + /* default settings: return tight bound for that case */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_BLOCK || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + (s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush)); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy(dest, source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy(ds, ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, strm->next_in, len); + } +#endif + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#endif /* FASTEST */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest encodable run. + */ + if (s->lookahead < MAX_MATCH) { + fill_window(s); + if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (int)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} diff --git a/resources/3rdparty/glpk-4.57/src/zlib/deflate.h b/resources/3rdparty/glpk-4.57/src/zlib/deflate.h new file mode 100644 index 000000000..cbf0d1ea5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/deflate.h @@ -0,0 +1,342 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2010 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/resources/3rdparty/glpk-4.57/src/zlib/gzclose.c b/resources/3rdparty/glpk-4.57/src/zlib/gzclose.c new file mode 100644 index 000000000..caeb99a31 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/gzclose.c @@ -0,0 +1,25 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(file) + gzFile file; +{ +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff --git a/resources/3rdparty/glpk-4.57/src/zlib/gzguts.h b/resources/3rdparty/glpk-4.57/src/zlib/gzguts.h new file mode 100644 index 000000000..9d01ac7b7 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/gzguts.h @@ -0,0 +1,74 @@ +/* gzguts.h (zlib internal header definitions for gz* operations) */ + +/* Modified by Andrew Makhorin , April 2011 */ + +/* Copyright (C) 2004, 2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in + * zlib.h */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. */ + +#ifndef GZGUTS_H +#define GZGUTS_H + +#define ZLIB_INTERNAL + +#include +#include +#include +#include +#include +#include "zio.h" +#include "zlib.h" + +#define local static + +#define zstrerror() strerror(errno) + +#define GZBUFSIZE 8192 + +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 + +#define LOOK 0 +#define COPY 1 +#define GZIP 2 + +typedef struct +{ int mode; + int fd; + char *path; + z_off64_t pos; + unsigned size; + unsigned want; + unsigned char *in; + unsigned char *out; + unsigned char *next; + unsigned have; + int eof; + z_off64_t start; + z_off64_t raw; + int how; + int direct; + int level; + int strategy; + z_off64_t skip; + int seek; + int err; + char *msg; + z_stream strm; +} gz_state; + +typedef gz_state *gz_statep; + +void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); + +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/zlib/gzlib.c b/resources/3rdparty/glpk-4.57/src/zlib/gzlib.c new file mode 100644 index 000000000..603e60ed5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/gzlib.c @@ -0,0 +1,537 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif + +/* Local functions */ +local void gz_reset OF((gz_statep)); +local gzFile gz_open OF((const char *, int, const char *)); + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char ZLIB_INTERNAL *gz_strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(state) + gz_statep state; +{ + if (state->mode == GZ_READ) { /* for reading ... */ + state->have = 0; /* no output data available */ + state->eof = 0; /* not at end of file */ + state->how = LOOK; /* look for gzip header */ + state->direct = 1; /* default for empty file */ + } + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(path, fd, mode) + const char *path; + int fd; + const char *mode; +{ + gz_statep state; + + /* allocate gzFile structure to return */ + state = malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* save the path name for error messages */ + state->path = malloc(strlen(path) + 1); + if (state->path == NULL) { + free(state); + return NULL; + } + strcpy(state->path, path); + + /* open the file with the appropriate mode (or just use fd) */ + state->fd = fd != -1 ? fd : + open(path, +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | ( + state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))), + 0666); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) + state->mode = GZ_WRITE; /* simplify later checks */ + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(fd, mode) + int fd; + const char *mode; +{ + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; + sprintf(path, "", fd); /* for debugging */ + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(file, size) + gzFile file; + unsigned size; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if (size == 0) + return -1; + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(file, offset, whence) + gzFile file; + z_off64_t offset; + int whence; +{ + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->pos + offset >= state->raw) { + ret = LSEEK(state->fd, offset - state->have, SEEK_CUR); + if (ret == -1) + return -1; + state->have = 0; + state->eof = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->pos += offset; + return state->pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->have) || (z_off64_t)state->have > offset ? + (unsigned)offset : state->have; + state->have -= n; + state->next += n; + state->pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(file) + gzFile file; +{ + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(file) + gzFile file; +{ + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(file) + gzFile file; +{ + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? + (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(file, errnum) + gzFile file; + int *errnum; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->msg == NULL ? "" : state->msg; +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) + state->eof = 0; + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void ZLIB_INTERNAL gz_error(state, err, msg) + gz_statep state; + int err; + const char *msg; +{ + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, save as static string */ + if (err == Z_MEM_ERROR) { + state->msg = (char *)msg; + return; + } + + /* construct error message with path */ + if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { + state->err = Z_MEM_ERROR; + state->msg = (char *)"out of memory"; + return; + } + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); + return; +} + +#ifndef INT_MAX +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned ZLIB_INTERNAL gz_intmax() +{ + unsigned p, q; + + p = 1; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +} +#endif diff --git a/resources/3rdparty/glpk-4.57/src/zlib/gzread.c b/resources/3rdparty/glpk-4.57/src/zlib/gzread.c new file mode 100644 index 000000000..548201ab0 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/gzread.c @@ -0,0 +1,653 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004, 2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); +local int gz_avail OF((gz_statep)); +local int gz_next4 OF((gz_statep, unsigned long *)); +local int gz_head OF((gz_statep)); +local int gz_decomp OF((gz_statep)); +local int gz_make OF((gz_statep)); +local int gz_skip OF((gz_statep, z_off64_t)); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(state, buf, len, have) + gz_statep state; + unsigned char *buf; + unsigned len; + unsigned *have; +{ + int ret; + + *have = 0; + do { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + gz_avail() assumes that strm->avail_in == 0. */ +local int gz_avail(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + if (state->err != Z_OK) + return -1; + if (state->eof == 0) { + if (gz_load(state, state->in, state->size, + (unsigned *)&(strm->avail_in)) == -1) + return -1; + strm->next_in = state->in; + } + return 0; +} + +/* Get next byte from input, or -1 if end or error. */ +#define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \ + (strm->avail_in == 0 ? -1 : \ + (strm->avail_in--, *(strm->next_in)++))) + +/* Get a four-byte little-endian integer and return 0 on success and the value + in *ret. Otherwise -1 is returned and *ret is not modified. */ +local int gz_next4(state, ret) + gz_statep state; + unsigned long *ret; +{ + int ch; + unsigned long val; + z_streamp strm = &(state->strm); + + val = NEXT(); + val += (unsigned)NEXT() << 8; + val += (unsigned long)NEXT() << 16; + ch = NEXT(); + if (ch == -1) + return -1; + val += (unsigned long)ch << 24; + *ret = val; + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->have must be zero. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression, and the gzip header will be skipped so + that the next available input data is the raw deflate stream. If direct + copying, then leftover input data from the input buffer will be copied to + the output buffer. In that case, all further file reads will be directly to + either the output buffer or a user buffer. If decompressing, the inflate + state and the check value will be initialized. gz_head() will return 0 on + success or -1 on failure. Failures may include read errors or gzip header + errors. */ +local int gz_head(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + int flags; + unsigned len; + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = malloc(state->want); + state->out = malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get some data in the input buffer */ + if (strm->avail_in == 0) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for the gzip magic header bytes 31 and 139 */ + if (strm->next_in[0] == 31) { + strm->avail_in--; + strm->next_in++; + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in && strm->next_in[0] == 139) { + /* we have a gzip header, woo hoo! */ + strm->avail_in--; + strm->next_in++; + + /* skip rest of header */ + if (NEXT() != 8) { /* compression method */ + gz_error(state, Z_DATA_ERROR, "unknown compression method"); + return -1; + } + flags = NEXT(); + if (flags & 0xe0) { /* reserved flag bits */ + gz_error(state, Z_DATA_ERROR, "unknown header flags set"); + return -1; + } + NEXT(); /* modification time */ + NEXT(); + NEXT(); + NEXT(); + NEXT(); /* extra flags */ + NEXT(); /* operating system */ + if (flags & 4) { /* extra field */ + len = (unsigned)NEXT(); + len += (unsigned)NEXT() << 8; + while (len--) + if (NEXT() < 0) + break; + } + if (flags & 8) /* file name */ + while (NEXT() > 0) + ; + if (flags & 16) /* comment */ + while (NEXT() > 0) + ; + if (flags & 2) { /* header crc */ + NEXT(); + NEXT(); + } + /* an unexpected end of file is not checked for here -- it will be + noticed on the first request for uncompressed data */ + + /* set up for decompression */ + inflateReset(strm); + strm->adler = crc32(0L, Z_NULL, 0); + state->how = GZIP; + state->direct = 0; + return 0; + } + else { + /* not a gzip file -- save first byte (31) and fall to raw i/o */ + state->out[0] = 31; + state->have = 1; + } + } + + /* doing raw i/o, save start of raw data for seeking, copy any leftover + input to output -- this assumes that the output buffer is larger than + the input buffer, which also assures space for gzungetc() */ + state->raw = state->pos; + state->next = state->out; + if (strm->avail_in) { + memcpy(state->next + state->have, strm->next_in, strm->avail_in); + state->have += strm->avail_in; + strm->avail_in = 0; + } + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + If the end of the compressed data is reached, then verify the gzip trailer + check value and length (modulo 2^32). state->have and state->next are set + to point to the just decompressed data, and the crc is updated. If the + trailer is verified, state->how is reset to LOOK to look for the next gzip + stream or raw data, once state->have is depleted. Returns 0 on success, -1 + on failure. Failures may include invalid compressed data or a failed gzip + trailer verification. */ +local int gz_decomp(state) + gz_statep state; +{ + int ret; + unsigned had; + unsigned long crc, len; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_DATA_ERROR, "unexpected end of file"); + return -1; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output and crc check value */ + state->have = had - strm->avail_out; + state->next = strm->next_out - state->have; + strm->adler = crc32(strm->adler, state->next, state->have); + + /* check gzip trailer if at end of deflate stream */ + if (ret == Z_STREAM_END) { + if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) { + gz_error(state, Z_DATA_ERROR, "unexpected end of file"); + return -1; + } + if (crc != strm->adler) { + gz_error(state, Z_DATA_ERROR, "incorrect data check"); + return -1; + } + if (len != (strm->total_out & 0xffffffffL)) { + gz_error(state, Z_DATA_ERROR, "incorrect length check"); + return -1; + } + state->how = LOOK; /* ready for next stream, once have is 0 (leave + state->direct unchanged to remember how) */ + } + + /* good decompression */ + return 0; +} + +/* Make data and put in the output buffer. Assumes that state->have == 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for (and skipped if found) to determine wither to copy or decompress. + Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY + or GZIP unless the end of the input file has been reached and all data has + been processed. */ +local int gz_make(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + if (state->how == LOOK) { /* look for gzip header */ + if (gz_head(state) == -1) + return -1; + if (state->have) /* got some data from gz_head() */ + return 0; + } + if (state->how == COPY) { /* straight copy */ + if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1) + return -1; + state->next = state->out; + } + else if (state->how == GZIP) { /* decompress */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(state, len) + gz_statep state; + z_off64_t len; +{ + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->have) { + n = GT_OFF(state->have) || (z_off64_t)state->have > len ? + (unsigned)len : state->have; + state->have -= n; + state->next += n; + state->pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_make(state) == -1) + return -1; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + unsigned got, n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_BUF_ERROR, "requested length does not fit in int"); + return -1; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* first just try copying data from the output buffer */ + if (state->have) { + n = state->have > len ? len : state->have; + memcpy(buf, state->next, n); + state->next += n; + state->have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && strm->avail_in == 0) + break; + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || len < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_make(state) == -1) + return -1; + continue; /* no progress yet -- go back to memcpy() above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, buf, len, &n) == -1) + return -1; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + strm->avail_out = len; + strm->next_out = buf; + if (gz_decomp(state) == -1) + return -1; + n = state->have; + state->have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->pos += n; + } while (len); + + /* return number of bytes read into user buffer (will fit in int) */ + return (int)got; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzgetc(file) + gzFile file; +{ + int ret; + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->have) { + state->have--; + state->pos++; + return *(state->next)++; + } + + /* nothing there -- try gzread() */ + ret = gzread(file, buf, 1); + return ret < 1 ? -1 : buf[0]; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->have == 0) { + state->have = 1; + state->next = state->out + (state->size << 1) - 1; + state->next[0] = c; + state->pos--; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->have == (state->size << 1)) { + gz_error(state, Z_BUF_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->next == state->out) { + unsigned char *src = state->out + state->have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->next = dest; + } + state->have++; + state->next--; + state->next[0] = c; + state->pos--; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->have == 0) { + if (gz_make(state) == -1) + return NULL; /* error */ + if (state->have == 0) { /* end of file */ + if (buf == str) /* got bupkus */ + return NULL; + break; /* got something -- return it */ + } + } + + /* look for end-of-line in current output buffer */ + n = state->have > left ? left : state->have; + eol = memchr(state->next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->next, n); + state->have -= n; + state->next += n; + state->pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* found end-of-line or out of space -- terminate string and return it */ + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return 0; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->how == LOOK && state->have == 0) + (void)gz_head(state); + + /* return 1 if reading direct, 0 if decompressing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(file) + gzFile file; +{ + int ret; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : Z_OK; +} diff --git a/resources/3rdparty/glpk-4.57/src/zlib/gzwrite.c b/resources/3rdparty/glpk-4.57/src/zlib/gzwrite.c new file mode 100644 index 000000000..13c5558e0 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/gzwrite.c @@ -0,0 +1,531 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004, 2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_init OF((gz_statep)); +local int gz_comp OF((gz_statep, int)); +local int gz_zero OF((gz_statep, z_off64_t)); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on failure or 0 on success. */ +local int gz_init(state) + gz_statep state; +{ + int ret; + z_streamp strm = &(state->strm); + + /* allocate input and output buffers */ + state->in = malloc(state->want); + state->out = malloc(state->want); + if (state->in == NULL || state->out == NULL) { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + 15 + 16, 8, state->strategy); + if (ret != Z_OK) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer */ + strm->avail_out = state->size; + strm->next_out = state->out; + state->next = strm->next_out; + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file, otherwise 0. + flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, + then the deflate() state is reset to start a new gzip stream. */ +local int gz_comp(state, flush) + gz_statep state; + int flush; +{ + int ret, got; + unsigned have; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + have = (unsigned)(strm->next_out - state->next); + if (have && ((got = write(state->fd, state->next, have)) < 0 || + (unsigned)got != have)) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + } + state->next = strm->next_out; + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + deflateReset(strm); + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on error, 0 on success. */ +local int gz_zero(state, len) + gz_statep state; + z_off64_t len; +{ + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + unsigned put = len; + unsigned n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_BUF_ERROR, "requested length does not fit in int"); + return 0; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + if (strm->avail_in == 0) + strm->next_in = state->in; + n = state->size - strm->avail_in; + if (n > len) + n = len; + memcpy(strm->next_in + strm->avail_in, buf, n); + strm->avail_in += n; + state->pos += n; + buf = (char *)buf + n; + len -= n; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + strm->avail_in = len; + strm->next_in = (voidp)buf; + state->pos += len; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } + + /* input was all buffered or compressed (put will fit in int) */ + return (int)put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (strm->avail_in < state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + strm->next_in[strm->avail_in++] = c; + state->pos++; + return c; + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = c; + if (gzwrite(file, buf, 1) != 1) + return -1; + return c; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(file, str) + gzFile file; + const char *str; +{ + int ret; + unsigned len; + + /* write string */ + len = (unsigned)strlen(str); + ret = gzwrite(file, str, len); + return ret == 0 && len != 0 ? -1 : ret; +} + +#ifdef STDC +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) +{ + int size, len; + gz_statep state; + z_streamp strm; + va_list va; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(state->in, format, va); + va_end(va); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = vsprintf((char *)state->in, format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(state->in, size, format, va); + va_end(va); + len = strlen(state->in); +# else + len = vsnprintf((char *)(state->in), size, format, va); + va_end(va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->pos += len; + return len; +} + +#else /* !STDC */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(state->in); +# else + len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->pos += len; + return len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(file, flush) + gzFile file; + int flush; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* compress remaining data with requested flush */ + gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(file) + gzFile file; +{ + int ret = 0; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + ret += gz_zero(state, state->skip); + } + + /* flush, free memory, and close file */ + ret += gz_comp(state, Z_FINISH); + (void)deflateEnd(&(state->strm)); + free(state->out); + free(state->in); + gz_error(state, Z_OK, NULL); + free(state->path); + ret += close(state->fd); + free(state); + return ret ? Z_ERRNO : Z_OK; +} diff --git a/resources/3rdparty/glpk-4.57/src/zlib/inffast.c b/resources/3rdparty/glpk-4.57/src/zlib/inffast.c new file mode 100644 index 000000000..2f1d60b43 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/inffast.c @@ -0,0 +1,340 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2008, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = lcode[hold & lmask]; + dolen: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op == 0) { /* literal */ + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + PUP(out) = (unsigned char)(here.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = dcode[hold & dmask]; + dodist: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + PUP(out) = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + PUP(out) = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + PUP(out) = PUP(from); + } while (--len); + continue; + } +#endif + } + from = window - OFF; + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode[here.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode[here.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/resources/3rdparty/glpk-4.57/src/zlib/inffast.h b/resources/3rdparty/glpk-4.57/src/zlib/inffast.h new file mode 100644 index 000000000..e5c1aa4ca --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/resources/3rdparty/glpk-4.57/src/zlib/inffixed.h b/resources/3rdparty/glpk-4.57/src/zlib/inffixed.h new file mode 100644 index 000000000..75ed4b597 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. It + is part of the implementation of the compression library and + is subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/resources/3rdparty/glpk-4.57/src/zlib/inflate.c b/resources/3rdparty/glpk-4.57/src/zlib/inflate.c new file mode 100644 index 000000000..a8431abea --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/inflate.c @@ -0,0 +1,1480 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + strm->adler = 1; /* to support ill-conceived Java test suite */ + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset2(strm, windowBits) +z_streamp strm; +int windowBits; +{ + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->window = Z_NULL; + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, + state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + else if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = REVERSE(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + NEEDBITS(here.bits); + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + REVERSE(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long id; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary id */ + if (state->mode == DICT) { + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window */ + if (updatewindow(strm, strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + if (dictLength > state->wsize) { + zmemcpy(state->window, dictionary + dictLength - state->wsize, + state->wsize); + state->whave = state->wsize; + } + else { + zmemcpy(state->window + state->wsize - dictLength, dictionary, + dictLength); + state->whave = dictLength; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy(copy, state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->sane = !subvert; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + return Z_OK; +#else + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + state = (struct inflate_state FAR *)strm->state; + return ((long)(state->back) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} diff --git a/resources/3rdparty/glpk-4.57/src/zlib/inflate.h b/resources/3rdparty/glpk-4.57/src/zlib/inflate.h new file mode 100644 index 000000000..95f4986d4 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/inflate.h @@ -0,0 +1,122 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2009 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 10K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff --git a/resources/3rdparty/glpk-4.57/src/zlib/inftrees.c b/resources/3rdparty/glpk-4.57/src/zlib/inftrees.c new file mode 100644 index 000000000..11e9c52ac --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/inftrees.c @@ -0,0 +1,330 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.5 Copyright 1995-2010 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + here.op = (unsigned char)(extra[work[sym]]); + here.val = base[work[sym]]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + here.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = here; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/resources/3rdparty/glpk-4.57/src/zlib/inftrees.h b/resources/3rdparty/glpk-4.57/src/zlib/inftrees.h new file mode 100644 index 000000000..baa53a0b1 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/inftrees.h @@ -0,0 +1,62 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/resources/3rdparty/glpk-4.57/src/zlib/trees.c b/resources/3rdparty/glpk-4.57/src/zlib/trees.c new file mode 100644 index 000000000..56e9bb1c1 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/trees.c @@ -0,0 +1,1244 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2010 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local int detect_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void ZLIB_INTERNAL _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+last, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+last, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(s) + deflate_state *s; +{ + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/resources/3rdparty/glpk-4.57/src/zlib/trees.h b/resources/3rdparty/glpk-4.57/src/zlib/trees.h new file mode 100644 index 000000000..d35639d82 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/resources/3rdparty/glpk-4.57/src/zlib/uncompr.c b/resources/3rdparty/glpk-4.57/src/zlib/uncompr.c new file mode 100644 index 000000000..ad98be3a5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/uncompr.c @@ -0,0 +1,59 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/resources/3rdparty/glpk-4.57/src/zlib/zconf.h b/resources/3rdparty/glpk-4.57/src/zlib/zconf.h new file mode 100644 index 000000000..af6a4f0fe --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/zconf.h @@ -0,0 +1,168 @@ +/* zconf.h (configuration of the zlib compression library) */ + +/* Modified by Andrew Makhorin , April 2011 */ + +/* Copyright (C) 1995-2010 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in + * zlib.h */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* (file adler32.c) */ +#define adler32 _glp_zlib_adler32 +#define adler32_combine _glp_zlib_adler32_combine +#define adler32_combine64 _glp_zlib_adler32_combine64 + +/* (file compress.c) */ +#define compress2 _glp_zlib_compress2 +#define compress _glp_zlib_compress +#define compressBound _glp_zlib_compressBound + +/* (file crc32.c) */ +#define get_crc_table _glp_zlib_get_crc_table +#define crc32 _glp_zlib_crc32 +#define crc32_combine _glp_zlib_crc32_combine +#define crc32_combine64 _glp_zlib_crc32_combine64 + +/* (file deflate.c) */ +#define deflateInit_ _glp_zlib_deflateInit_ +#define deflateInit2_ _glp_zlib_deflateInit2_ +#define deflateSetDictionary _glp_zlib_deflateSetDictionary +#define deflateReset _glp_zlib_deflateReset +#define deflateSetHeader _glp_zlib_deflateSetHeader +#define deflatePrime _glp_zlib_deflatePrime +#define deflateParams _glp_zlib_deflateParams +#define deflateTune _glp_zlib_deflateTune +#define deflateBound _glp_zlib_deflateBound +#define deflate _glp_zlib_deflate +#define deflateEnd _glp_zlib_deflateEnd +#define deflateCopy _glp_zlib_deflateCopy +#define deflate_copyright _glp_zlib_deflate_copyright + +/* (file gzclose.c) */ +#define gzclose _glp_zlib_gzclose + +/* (file gzlib.c) */ +#define gzopen _glp_zlib_gzopen +#define gzopen64 _glp_zlib_gzopen64 +#define gzdopen _glp_zlib_gzdopen +#define gzbuffer _glp_zlib_gzbuffer +#define gzrewind _glp_zlib_gzrewind +#define gzseek64 _glp_zlib_gzseek64 +#define gzseek _glp_zlib_gzseek +#define gztell64 _glp_zlib_gztell64 +#define gztell _glp_zlib_gztell +#define gzoffset64 _glp_zlib_gzoffset64 +#define gzoffset _glp_zlib_gzoffset +#define gzeof _glp_zlib_gzeof +#define gzerror _glp_zlib_gzerror +#define gzclearerr _glp_zlib_gzclearerr +#define gz_error _glp_zlib_gz_error + +/* (file gzread.c) */ +#define gzread _glp_zlib_gzread +#define gzgetc _glp_zlib_gzgetc +#define gzungetc _glp_zlib_gzungetc +#define gzgets _glp_zlib_gzgets +#define gzdirect _glp_zlib_gzdirect +#define gzclose_r _glp_zlib_gzclose_r + +/* (file gzwrite.c) */ +#define gzwrite _glp_zlib_gzwrite +#define gzputc _glp_zlib_gzputc +#define gzputs _glp_zlib_gzputs +#define gzprintf _glp_zlib_gzprintf +#define gzflush _glp_zlib_gzflush +#define gzsetparams _glp_zlib_gzsetparams +#define gzclose_w _glp_zlib_gzclose_w + +/* (file infback.c) */ +#define inflateBackInit_ _glp_zlib_inflateBackInit_ +#define inflateBack _glp_zlib_inflateBack +#define inflateBackEnd _glp_zlib_inflateBackEnd + +/* (file inffast.c) */ +#define inflate_fast _glp_zlib_inflate_fast + +/* (file inflate.c) */ +#define inflateReset _glp_zlib_inflateReset +#define inflateReset2 _glp_zlib_inflateReset2 +#define inflateInit2_ _glp_zlib_inflateInit2_ +#define inflateInit_ _glp_zlib_inflateInit_ +#define inflatePrime _glp_zlib_inflatePrime +#define inflate _glp_zlib_inflate +#define inflateEnd _glp_zlib_inflateEnd +#define inflateSetDictionary _glp_zlib_inflateSetDictionary +#define inflateGetHeader _glp_zlib_inflateGetHeader +#define inflateSync _glp_zlib_inflateSync +#define inflateSyncPoint _glp_zlib_inflateSyncPoint +#define inflateCopy _glp_zlib_inflateCopy +#define inflateUndermine _glp_zlib_inflateUndermine +#define inflateMark _glp_zlib_inflateMark + +/* (file inftrees.c) */ +#define inflate_table _glp_zlib_inflate_table +#define inflate_copyright _glp_zlib_inflate_copyright + +/* (file trees.c) */ +#define _tr_init _glp_zlib_tr_init +#define _tr_stored_block _glp_zlib_tr_stored_block +#define _tr_align _glp_zlib_tr_align +#define _tr_flush_block _glp_zlib_tr_flush_block +#define _tr_tally _glp_zlib_tr_tally +#define _dist_code _glp_zlib_dist_code +#define _length_code _glp_zlib_length_code + +/* (file uncompr.c) */ +#define uncompress _glp_zlib_uncompress + +/* (file zutil.c) */ +#define zlibVersion _glp_zlib_zlibVersion +#define zlibCompileFlags _glp_zlib_zlibCompileFlags +#define zError _glp_zlib_zError +#define zcalloc _glp_zlib_zcalloc +#define zcfree _glp_zlib_zcfree +#define z_errmsg _glp_zlib_z_errmsg + +#define STDC 1 + +#define MAX_MEM_LEVEL 9 + +#define MAX_WBITS 15 + +#define OF(args) args + +#define ZEXTERN extern +#define ZEXPORT +#define ZEXPORTVA + +#define FAR + +typedef unsigned char Byte; +typedef unsigned int uInt; +typedef unsigned long uLong; + +typedef Byte Bytef; +typedef char charf; +typedef int intf; +typedef uInt uIntf; +typedef uLong uLongf; + +typedef void const *voidpc; +typedef void *voidpf; +typedef void *voidp; + +#define z_off_t long + +#define z_off64_t z_off_t + +#define NO_vsnprintf 1 + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/zlib/zio.c b/resources/3rdparty/glpk-4.57/src/zlib/zio.c new file mode 100644 index 000000000..a55b258a7 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/zio.c @@ -0,0 +1,92 @@ +/* zio.c (simulation of non-standard low-level i/o functions) */ + +/* Written by Andrew Makhorin , April 2011 + * For conditions of distribution and use, see copyright notice in + * zlib.h */ + +/* (reserved for copyright notice) */ + +#include +#include +#include "zio.h" + +static FILE *file[FOPEN_MAX]; +static int initialized = 0; + +static void initialize(void) +{ int fd; + assert(!initialized); + file[0] = stdin; + file[1] = stdout; + file[2] = stderr; + for (fd = 3; fd < FOPEN_MAX; fd++) + file[fd] = NULL; + initialized = 1; + return; +} + +int open(const char *path, int oflag, ...) +{ FILE *fp; + int fd; + if (!initialized) initialize(); + /* see file gzlib.c, function gz_open */ + if (oflag == O_RDONLY) + fp = fopen(path, "rb"); + else if (oflag == (O_WRONLY | O_CREAT | O_TRUNC)) + fp = fopen(path, "wb"); + else if (oflag == (O_WRONLY | O_CREAT | O_APPEND)) + fp = fopen(path, "ab"); + else + assert(oflag != oflag); + if (fp == NULL) + return -1; + for (fd = 0; fd < FOPEN_MAX; fd++) + if (file[fd] == NULL) break; + assert(fd < FOPEN_MAX); + file[fd] = fp; + return fd; +} + +long read(int fd, void *buf, unsigned long nbyte) +{ unsigned long count; + if (!initialized) initialize(); + assert(0 <= fd && fd < FOPEN_MAX); + assert(file[fd] != NULL); + count = fread(buf, 1, nbyte, file[fd]); + if (ferror(file[fd])) + return -1; + return count; +} + +long write(int fd, const void *buf, unsigned long nbyte) +{ unsigned long count; + if (!initialized) initialize(); + assert(0 <= fd && fd < FOPEN_MAX); + assert(file[fd] != NULL); + count = fwrite(buf, 1, nbyte, file[fd]); + if (count != nbyte) + return -1; + if (fflush(file[fd]) != 0) + return -1; + return count; +} + +long lseek(int fd, long offset, int whence) +{ if (!initialized) initialize(); + assert(0 <= fd && fd < FOPEN_MAX); + assert(file[fd] != NULL); + if (fseek(file[fd], offset, whence) != 0) + return -1; + return ftell(file[fd]); +} + +int close(int fd) +{ if (!initialized) initialize(); + assert(0 <= fd && fd < FOPEN_MAX); + assert(file[fd] != NULL); + fclose(file[fd]); + file[fd] = NULL; + return 0; +} + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/zlib/zio.h b/resources/3rdparty/glpk-4.57/src/zlib/zio.h new file mode 100644 index 000000000..1626c4ae4 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/zio.h @@ -0,0 +1,37 @@ +/* zio.h (simulation of non-standard low-level i/o functions) */ + +/* Written by Andrew Makhorin , April 2011 + * For conditions of distribution and use, see copyright notice in + * zlib.h */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. */ + +#ifndef ZIO_H +#define ZIO_H + +#define O_RDONLY 0x00 +#define O_WRONLY 0x01 +#define O_CREAT 0x10 +#define O_TRUNC 0x20 +#define O_APPEND 0x30 + +#define open _glp_zlib_open +int open(const char *path, int oflag, ...); + +#define read _glp_zlib_read +long read(int fd, void *buf, unsigned long nbyte); + +#define write _glp_zlib_write +long write(int fd, const void *buf, unsigned long nbyte); + +#define lseek _glp_zlib_lseek +long lseek(int fd, long offset, int whence); + +#define close _glp_zlib_close +int close(int fd); + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/src/zlib/zlib.h b/resources/3rdparty/glpk-4.57/src/zlib/zlib.h new file mode 100644 index 000000000..bfbba83e8 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/zlib.h @@ -0,0 +1,1613 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.5, April 19th, 2010 + + Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.5" +#define ZLIB_VERNUM 0x1250 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 5 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all the uncompressed data. (The size + of the uncompressed data may have been saved by the compressor for this + purpose.) The next operation on this stream must be inflateEnd to deallocate + the decompression state. The use of Z_FINISH is never required, but can be + used to inform inflate that a faster approach may be used for the single + inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK or Z_TREES is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any call + of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been + found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the + success case, the application may save the current current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef voidp gzFile; /* opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) Also "a" + can be used instead of "w" to request that the gzip stream that will be + written be appended to the file. "+" will result in an error, since reading + and writing to the same gzip file is not supported. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file was not in gzip format, gzread copies the given number of + bytes into the buffer. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream, or failing that, reading the rest + of the input file directly without decompression. The entire input file + will be read if gzread is called until it returns less than the requested + len. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. This state can change from + false to true while reading the input file if the end of a gzip stream is + reached, but is followed by data that is not another gzip stream. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the for the crc. Pre- and post-conditioning (one's + complement) is performed within this function so it shouldn't be done by the + application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# ifdef _LARGEFILE64_SOURCE + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/resources/3rdparty/glpk-4.57/src/zlib/zutil.c b/resources/3rdparty/glpk-4.57/src/zlib/zutil.c new file mode 100644 index 000000000..898ed345b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/zutil.c @@ -0,0 +1,318 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005, 2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#ifdef STDC +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void ZLIB_INTERNAL zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int ZLIB_INTERNAL zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void ZLIB_INTERNAL zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void ZLIB_INTERNAL zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/resources/3rdparty/glpk-4.57/src/zlib/zutil.h b/resources/3rdparty/glpk-4.57/src/zlib/zutil.h new file mode 100644 index 000000000..737bd38f5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/src/zlib/zutil.h @@ -0,0 +1,93 @@ +/* zutil.h (internal interface of the zlib compression library) */ + +/* Modified by Andrew Makhorin , April 2011 */ + +/* Copyright (C) 1995-2010 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in + * zlib.h */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#define ZLIB_INTERNAL + +#include "zlib.h" + +#include +#include +#include + +#define local static + +typedef unsigned char uch; +typedef uch uchf; +typedef unsigned short ush; +typedef ush ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm, err) \ + return (strm->msg = (char *)ERR_MSG(err), (err)) + +#define DEF_WBITS MAX_WBITS + +#if MAX_MEM_LEVEL >= 8 +#define DEF_MEM_LEVEL 8 +#else +#define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 + +#define MIN_MATCH 3 +#define MAX_MATCH 258 + +#define PRESET_DICT 0x20 + +#define OS_CODE 0x03 /* assume Unix */ + +#define HAVE_MEMCPY 1 +#define zmemcpy memcpy +#define zmemzero(dest, len) memset(dest, 0, len) + +#ifdef DEBUG +#include +extern int ZLIB_INTERNAL z_verbose; +extern void ZLIB_INTERNAL z_error OF((char *m)); +#define Assert(cond, msg) { if(!(cond)) z_error(msg); } +#define Trace(x) { if (z_verbose >= 0) fprintf x; } +#define Tracev(x) { if (z_verbose > 0) fprintf x; } +#define Tracevv(x) {if (z_verbose > 1) fprintf x; } +#define Tracec(c, x) {if (z_verbose > 0 && (c)) fprintf x; } +#define Tracecv(c, x) {if (z_verbose > 1 && (c)) fprintf x; } +#else +#define Assert(cond, msg) +#define Trace(x) +#define Tracev(x) +#define Tracevv(x) +#define Tracec(c, x) +#define Tracecv(c, x) +#endif + +voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); +void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) \ + (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) { if (p) ZFREE(s, p); } + +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC10.bat b/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC10.bat new file mode 100755 index 000000000..b0f693446 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC10.bat @@ -0,0 +1,11 @@ +rem Build GLPK with Microsoft Visual Studio Express 2010 + +rem NOTE: Make sure that HOME variable specifies correct path +set HOME="C:\Program Files\Microsoft Visual Studio 10.0\VC" + +call %HOME%\vcvarsall.bat x86 +copy config_VC config.h +%HOME%\bin\nmake.exe /f Makefile_VC +%HOME%\bin\nmake.exe /f Makefile_VC check + +pause diff --git a/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC10_DLL.bat b/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC10_DLL.bat new file mode 100755 index 000000000..e66f5cb39 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC10_DLL.bat @@ -0,0 +1,11 @@ +rem Build GLPK DLL with Microsoft Visual Studio Express 2010 + +rem NOTE: Make sure that HOME variable specifies correct path +set HOME="C:\Program Files\Microsoft Visual Studio 10.0\VC" + +call %HOME%\vcvarsall.bat x86 +copy config_VC config.h +%HOME%\bin\nmake.exe /f Makefile_VC_DLL +%HOME%\bin\nmake.exe /f Makefile_VC_DLL check + +pause diff --git a/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC14.bat b/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC14.bat new file mode 100755 index 000000000..02bb9add3 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC14.bat @@ -0,0 +1,11 @@ +rem Build GLPK with Microsoft Visual Studio Community 2015 + +rem NOTE: Make sure that HOME variable specifies correct path +set HOME="C:\Program Files\Microsoft Visual Studio 14.0\VC" + +call %HOME%\vcvarsall.bat x86 +copy config_VC config.h +%HOME%\bin\nmake.exe /f Makefile_VC +%HOME%\bin\nmake.exe /f Makefile_VC check + +pause diff --git a/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC14_DLL.bat b/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC14_DLL.bat new file mode 100755 index 000000000..baf4b112b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC14_DLL.bat @@ -0,0 +1,11 @@ +rem Build GLPK DLL with Microsoft Visual Studio Community 2015 + +rem NOTE: Make sure that HOME variable specifies correct path +set HOME="C:\Program Files\Microsoft Visual Studio 14.0\VC" + +call %HOME%\vcvarsall.bat x86 +copy config_VC config.h +%HOME%\bin\nmake.exe /f Makefile_VC_DLL +%HOME%\bin\nmake.exe /f Makefile_VC_DLL check + +pause diff --git a/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC9.bat b/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC9.bat new file mode 100755 index 000000000..9c5e8f83d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC9.bat @@ -0,0 +1,11 @@ +rem Build GLPK with Microsoft Visual Studio Express 2008 + +rem NOTE: Make sure that HOME variable specifies correct path +set HOME="C:\Program Files\Microsoft Visual Studio 9.0\VC" + +call %HOME%\bin\vcvars32.bat +copy config_VC config.h +%HOME%\bin\nmake.exe /f Makefile_VC +%HOME%\bin\nmake.exe /f Makefile_VC check + +pause diff --git a/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC9_DLL.bat b/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC9_DLL.bat new file mode 100755 index 000000000..f334c04af --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w32/Build_GLPK_with_VC9_DLL.bat @@ -0,0 +1,11 @@ +rem Build GLPK DLL with Microsoft Visual Studio Express 2008 + +rem NOTE: Make sure that HOME variable specifies correct path +set HOME="C:\Program Files\Microsoft Visual Studio 9.0\VC" + +call %HOME%\bin\vcvars32.bat +copy config_VC config.h +%HOME%\bin\nmake.exe /f Makefile_VC_DLL +%HOME%\bin\nmake.exe /f Makefile_VC_DLL check + +pause diff --git a/resources/3rdparty/glpk-4.57/w32/Makefile_VC b/resources/3rdparty/glpk-4.57/w32/Makefile_VC new file mode 100644 index 000000000..e4853f789 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w32/Makefile_VC @@ -0,0 +1,204 @@ +## Build GLPK with Microsoft Visual Studio Express ## + +CFLAGS = \ +/I. \ +/I..\src \ +/I..\src\amd \ +/I..\src\bflib \ +/I..\src\cglib \ +/I..\src\colamd \ +/I..\src\env \ +/I..\src\minisat \ +/I..\src\misc \ +/I..\src\proxy \ +/I..\src\simplex \ +/I..\src\zlib \ +/DHAVE_CONFIG_H=1 \ +/D_CRT_SECURE_NO_WARNINGS=1 \ +/nologo \ +/W3 \ +/O2 \ +/Zi + +OBJSET = \ +..\src\avl.obj \ +..\src\bfd.obj \ +..\src\bfx.obj \ +..\src\glpapi01.obj \ +..\src\glpapi02.obj \ +..\src\glpapi03.obj \ +..\src\glpapi04.obj \ +..\src\glpapi05.obj \ +..\src\glpapi06.obj \ +..\src\glpapi07.obj \ +..\src\glpapi08.obj \ +..\src\glpapi09.obj \ +..\src\glpapi10.obj \ +..\src\glpapi11.obj \ +..\src\glpapi12.obj \ +..\src\glpapi13.obj \ +..\src\glpapi14.obj \ +..\src\glpapi15.obj \ +..\src\glpapi16.obj \ +..\src\glpapi17.obj \ +..\src\glpapi18.obj \ +..\src\glpapi19.obj \ +..\src\glpapi20.obj \ +..\src\glpapi21.obj \ +..\src\glpcpx.obj \ +..\src\glpdmx.obj \ +..\src\glpgmp.obj \ +..\src\glphbm.obj \ +..\src\glpini01.obj \ +..\src\glpini02.obj \ +..\src\glpios01.obj \ +..\src\glpios02.obj \ +..\src\glpios03.obj \ +..\src\glpios04.obj \ +..\src\glpios05.obj \ +..\src\glpios06.obj \ +..\src\glpios07.obj \ +..\src\glpios08.obj \ +..\src\glpios09.obj \ +..\src\glpios10.obj \ +..\src\glpios11.obj \ +..\src\glpios12.obj \ +..\src\glpipm.obj \ +..\src\glpmat.obj \ +..\src\glpmpl01.obj \ +..\src\glpmpl02.obj \ +..\src\glpmpl03.obj \ +..\src\glpmpl04.obj \ +..\src\glpmpl05.obj \ +..\src\glpmpl06.obj \ +..\src\glpmps.obj \ +..\src\glpnet03.obj \ +..\src\glpnet04.obj \ +..\src\glpnet05.obj \ +..\src\glpnpp01.obj \ +..\src\glpnpp02.obj \ +..\src\glpnpp03.obj \ +..\src\glpnpp04.obj \ +..\src\glpnpp05.obj \ +..\src\glpnpp06.obj \ +..\src\glprgr.obj \ +..\src\glpscl.obj \ +..\src\glpsdf.obj \ +..\src\glpspm.obj \ +..\src\glpsql.obj \ +..\src\glpssx01.obj \ +..\src\glpssx02.obj \ +..\src\lux.obj \ +..\src\amd\amd_1.obj \ +..\src\amd\amd_2.obj \ +..\src\amd\amd_aat.obj \ +..\src\amd\amd_control.obj \ +..\src\amd\amd_defaults.obj \ +..\src\amd\amd_dump.obj \ +..\src\amd\amd_info.obj \ +..\src\amd\amd_order.obj \ +..\src\amd\amd_post_tree.obj \ +..\src\amd\amd_postorder.obj \ +..\src\amd\amd_preprocess.obj \ +..\src\amd\amd_valid.obj \ +..\src\bflib\btf.obj \ +..\src\bflib\btfint.obj \ +..\src\bflib\fhv.obj \ +..\src\bflib\fhvint.obj \ +..\src\bflib\ifu.obj \ +..\src\bflib\luf.obj \ +..\src\bflib\lufint.obj \ +..\src\bflib\scf.obj \ +..\src\bflib\scfint.obj \ +..\src\bflib\sgf.obj \ +..\src\bflib\sva.obj \ +..\src\cglib\cfg.obj \ +..\src\cglib\cfg1.obj \ +..\src\colamd\colamd.obj \ +..\src\env\alloc.obj \ +..\src\env\dlsup.obj \ +..\src\env\env.obj \ +..\src\env\error.obj \ +..\src\env\stdout.obj \ +..\src\env\stream.obj \ +..\src\env\time.obj \ +..\src\env\tls.obj \ +..\src\minisat\minisat.obj \ +..\src\misc\bignum.obj \ +..\src\misc\dmp.obj \ +..\src\misc\ffalg.obj \ +..\src\misc\fp2rat.obj \ +..\src\misc\gcd.obj \ +..\src\misc\jd.obj \ +..\src\misc\keller.obj \ +..\src\misc\mc13d.obj \ +..\src\misc\mc21a.obj \ +..\src\misc\okalg.obj \ +..\src\misc\qmd.obj \ +..\src\misc\relax4.obj \ +..\src\misc\rng.obj \ +..\src\misc\rng1.obj \ +..\src\misc\round2n.obj \ +..\src\misc\str2int.obj \ +..\src\misc\str2num.obj \ +..\src\misc\strspx.obj \ +..\src\misc\strtrim.obj \ +..\src\misc\triang.obj \ +..\src\misc\wclique.obj \ +..\src\misc\wclique1.obj \ +..\src\proxy\proxy.obj \ +..\src\proxy\proxy1.obj \ +..\src\simplex\spxat.obj \ +..\src\simplex\spxchuzc.obj \ +..\src\simplex\spxchuzr.obj \ +..\src\simplex\spxlp.obj \ +..\src\simplex\spxnt.obj \ +..\src\simplex\spxprim.obj \ +..\src\simplex\spxprob.obj \ +..\src\simplex\spychuzc.obj \ +..\src\simplex\spychuzr.obj \ +..\src\simplex\spydual.obj \ +..\src\zlib\adler32.obj \ +..\src\zlib\compress.obj \ +..\src\zlib\crc32.obj \ +..\src\zlib\deflate.obj \ +..\src\zlib\gzclose.obj \ +..\src\zlib\gzlib.obj \ +..\src\zlib\gzread.obj \ +..\src\zlib\gzwrite.obj \ +..\src\zlib\inffast.obj \ +..\src\zlib\inflate.obj \ +..\src\zlib\inftrees.obj \ +..\src\zlib\trees.obj \ +..\src\zlib\uncompr.obj \ +..\src\zlib\zio.obj \ +..\src\zlib\zutil.obj + +.c.obj: + cl.exe $(CFLAGS) /Fo$*.obj /c $*.c + +all: glpk.lib glpsol.exe + +glpk.lib: $(OBJSET) + lib.exe /out:glpk.lib \ + ..\src\*.obj \ + ..\src\amd\*.obj \ + ..\src\bflib\*.obj \ + ..\src\cglib\*.obj \ + ..\src\colamd\*.obj \ + ..\src\env\*.obj \ + ..\src\minisat\*.obj \ + ..\src\misc\*.obj \ + ..\src\proxy\*.obj \ + ..\src\simplex\*.obj \ + ..\src\zlib\*.obj + +glpsol.exe: ..\examples\glpsol.obj glpk.lib + cl.exe $(CFLAGS) /Feglpsol.exe \ + ..\examples\glpsol.obj glpk.lib + +check: glpsol.exe + .\glpsol.exe --version + .\glpsol.exe --mps ..\examples\plan.mps + +## eof ## diff --git a/resources/3rdparty/glpk-4.57/w32/Makefile_VC_DLL b/resources/3rdparty/glpk-4.57/w32/Makefile_VC_DLL new file mode 100644 index 000000000..53467e0b5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w32/Makefile_VC_DLL @@ -0,0 +1,205 @@ +## Build GLPK DLL with Microsoft Visual Studio Express ## + +CFLAGS = \ +/I. \ +/I..\src \ +/I..\src\amd \ +/I..\src\bflib \ +/I..\src\cglib \ +/I..\src\colamd \ +/I..\src\env \ +/I..\src\minisat \ +/I..\src\misc \ +/I..\src\proxy \ +/I..\src\simplex \ +/I..\src\zlib \ +/DHAVE_CONFIG_H=1 \ +/D_CRT_SECURE_NO_WARNINGS=1 \ +/nologo \ +/W3 \ +/O2 \ +/Zi + +OBJSET = \ +..\src\avl.obj \ +..\src\bfd.obj \ +..\src\bfx.obj \ +..\src\glpapi01.obj \ +..\src\glpapi02.obj \ +..\src\glpapi03.obj \ +..\src\glpapi04.obj \ +..\src\glpapi05.obj \ +..\src\glpapi06.obj \ +..\src\glpapi07.obj \ +..\src\glpapi08.obj \ +..\src\glpapi09.obj \ +..\src\glpapi10.obj \ +..\src\glpapi11.obj \ +..\src\glpapi12.obj \ +..\src\glpapi13.obj \ +..\src\glpapi14.obj \ +..\src\glpapi15.obj \ +..\src\glpapi16.obj \ +..\src\glpapi17.obj \ +..\src\glpapi18.obj \ +..\src\glpapi19.obj \ +..\src\glpapi20.obj \ +..\src\glpapi21.obj \ +..\src\glpcpx.obj \ +..\src\glpdmx.obj \ +..\src\glpgmp.obj \ +..\src\glphbm.obj \ +..\src\glpini01.obj \ +..\src\glpini02.obj \ +..\src\glpios01.obj \ +..\src\glpios02.obj \ +..\src\glpios03.obj \ +..\src\glpios04.obj \ +..\src\glpios05.obj \ +..\src\glpios06.obj \ +..\src\glpios07.obj \ +..\src\glpios08.obj \ +..\src\glpios09.obj \ +..\src\glpios10.obj \ +..\src\glpios11.obj \ +..\src\glpios12.obj \ +..\src\glpipm.obj \ +..\src\glpmat.obj \ +..\src\glpmpl01.obj \ +..\src\glpmpl02.obj \ +..\src\glpmpl03.obj \ +..\src\glpmpl04.obj \ +..\src\glpmpl05.obj \ +..\src\glpmpl06.obj \ +..\src\glpmps.obj \ +..\src\glpnet03.obj \ +..\src\glpnet04.obj \ +..\src\glpnet05.obj \ +..\src\glpnpp01.obj \ +..\src\glpnpp02.obj \ +..\src\glpnpp03.obj \ +..\src\glpnpp04.obj \ +..\src\glpnpp05.obj \ +..\src\glpnpp06.obj \ +..\src\glprgr.obj \ +..\src\glpscl.obj \ +..\src\glpsdf.obj \ +..\src\glpspm.obj \ +..\src\glpsql.obj \ +..\src\glpssx01.obj \ +..\src\glpssx02.obj \ +..\src\lux.obj \ +..\src\amd\amd_1.obj \ +..\src\amd\amd_2.obj \ +..\src\amd\amd_aat.obj \ +..\src\amd\amd_control.obj \ +..\src\amd\amd_defaults.obj \ +..\src\amd\amd_dump.obj \ +..\src\amd\amd_info.obj \ +..\src\amd\amd_order.obj \ +..\src\amd\amd_post_tree.obj \ +..\src\amd\amd_postorder.obj \ +..\src\amd\amd_preprocess.obj \ +..\src\amd\amd_valid.obj \ +..\src\bflib\btf.obj \ +..\src\bflib\btfint.obj \ +..\src\bflib\fhv.obj \ +..\src\bflib\fhvint.obj \ +..\src\bflib\ifu.obj \ +..\src\bflib\luf.obj \ +..\src\bflib\lufint.obj \ +..\src\bflib\scf.obj \ +..\src\bflib\scfint.obj \ +..\src\bflib\sgf.obj \ +..\src\bflib\sva.obj \ +..\src\cglib\cfg.obj \ +..\src\cglib\cfg1.obj \ +..\src\colamd\colamd.obj \ +..\src\env\alloc.obj \ +..\src\env\dlsup.obj \ +..\src\env\env.obj \ +..\src\env\error.obj \ +..\src\env\stdout.obj \ +..\src\env\stream.obj \ +..\src\env\time.obj \ +..\src\env\tls.obj \ +..\src\minisat\minisat.obj \ +..\src\misc\bignum.obj \ +..\src\misc\dmp.obj \ +..\src\misc\ffalg.obj \ +..\src\misc\fp2rat.obj \ +..\src\misc\gcd.obj \ +..\src\misc\jd.obj \ +..\src\misc\keller.obj \ +..\src\misc\mc13d.obj \ +..\src\misc\mc21a.obj \ +..\src\misc\okalg.obj \ +..\src\misc\qmd.obj \ +..\src\misc\relax4.obj \ +..\src\misc\rng.obj \ +..\src\misc\rng1.obj \ +..\src\misc\round2n.obj \ +..\src\misc\str2int.obj \ +..\src\misc\str2num.obj \ +..\src\misc\strspx.obj \ +..\src\misc\strtrim.obj \ +..\src\misc\triang.obj \ +..\src\misc\wclique.obj \ +..\src\misc\wclique1.obj \ +..\src\proxy\proxy.obj \ +..\src\proxy\proxy1.obj \ +..\src\simplex\spxat.obj \ +..\src\simplex\spxchuzc.obj \ +..\src\simplex\spxchuzr.obj \ +..\src\simplex\spxlp.obj \ +..\src\simplex\spxnt.obj \ +..\src\simplex\spxprim.obj \ +..\src\simplex\spxprob.obj \ +..\src\simplex\spychuzc.obj \ +..\src\simplex\spychuzr.obj \ +..\src\simplex\spydual.obj \ +..\src\zlib\adler32.obj \ +..\src\zlib\compress.obj \ +..\src\zlib\crc32.obj \ +..\src\zlib\deflate.obj \ +..\src\zlib\gzclose.obj \ +..\src\zlib\gzlib.obj \ +..\src\zlib\gzread.obj \ +..\src\zlib\gzwrite.obj \ +..\src\zlib\inffast.obj \ +..\src\zlib\inflate.obj \ +..\src\zlib\inftrees.obj \ +..\src\zlib\trees.obj \ +..\src\zlib\uncompr.obj \ +..\src\zlib\zio.obj \ +..\src\zlib\zutil.obj + +.c.obj: + cl.exe $(CFLAGS) /Fo$*.obj /c $*.c + +all: glpk_4_57.dll glpsol.exe + +glpk_4_57.dll: $(OBJSET) + cl.exe $(CFLAGS) /LD /Feglpk_4_57.dll \ + ..\src\*.obj \ + ..\src\amd\*.obj \ + ..\src\bflib\*.obj \ + ..\src\cglib\*.obj \ + ..\src\colamd\*.obj \ + ..\src\env\*.obj \ + ..\src\minisat\*.obj \ + ..\src\misc\*.obj \ + ..\src\proxy\*.obj \ + ..\src\simplex\*.obj \ + ..\src\zlib\*.obj \ + glpk_4_57.def + +glpsol.exe: ..\examples\glpsol.obj glpk_4_57.dll + cl.exe $(CFLAGS) /Feglpsol.exe \ + ..\examples\glpsol.obj glpk_4_57.lib + +check: glpsol.exe + .\glpsol.exe --version + .\glpsol.exe --mps ..\examples\plan.mps + +## eof ## diff --git a/resources/3rdparty/glpk-4.57/w32/config_VC b/resources/3rdparty/glpk-4.57/w32/config_VC new file mode 100644 index 000000000..581ab6e6e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w32/config_VC @@ -0,0 +1,13 @@ +/* GLPK configuration file (Microsoft Visual Studio Express) */ + +#define __WOE__ 1 + +#define ODBC_DLNAME "odbc32.dll" +/* ODBC shared library name if this feature is enabled */ + +#if 0 +#define MYSQL_DLNAME "libmysql.dll" +/* MySQL shared library name if this feature is enabled */ +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/w32/glpk_4_57.def b/resources/3rdparty/glpk-4.57/w32/glpk_4_57.def new file mode 100644 index 000000000..61076961c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w32/glpk_4_57.def @@ -0,0 +1,223 @@ +LIBRARY glpk_4_57 +VERSION 4.57 +DESCRIPTION "GNU Linear Programming Kit" +EXPORTS +glp_create_prob +glp_set_prob_name +glp_set_obj_name +glp_set_obj_dir +glp_add_rows +glp_add_cols +glp_set_row_name +glp_set_col_name +glp_set_row_bnds +glp_set_col_bnds +glp_set_obj_coef +glp_set_mat_row +glp_set_mat_col +glp_load_matrix +glp_check_dup +glp_sort_matrix +glp_del_rows +glp_del_cols +glp_copy_prob +glp_erase_prob +glp_delete_prob +glp_get_prob_name +glp_get_obj_name +glp_get_obj_dir +glp_get_num_rows +glp_get_num_cols +glp_get_row_name +glp_get_col_name +glp_get_row_type +glp_get_row_lb +glp_get_row_ub +glp_get_col_type +glp_get_col_lb +glp_get_col_ub +glp_get_obj_coef +glp_get_num_nz +glp_get_mat_row +glp_get_mat_col +glp_create_index +glp_find_row +glp_find_col +glp_delete_index +glp_set_rii +glp_set_sjj +glp_get_rii +glp_get_sjj +glp_scale_prob +glp_unscale_prob +glp_set_row_stat +glp_set_col_stat +glp_std_basis +glp_adv_basis +glp_cpx_basis +glp_simplex +glp_exact +glp_init_smcp +glp_get_status +glp_get_prim_stat +glp_get_dual_stat +glp_get_obj_val +glp_get_row_stat +glp_get_row_prim +glp_get_row_dual +glp_get_col_stat +glp_get_col_prim +glp_get_col_dual +glp_get_unbnd_ray +glp_get_it_cnt +glp_set_it_cnt +glp_interior +glp_init_iptcp +glp_ipt_status +glp_ipt_obj_val +glp_ipt_row_prim +glp_ipt_row_dual +glp_ipt_col_prim +glp_ipt_col_dual +glp_set_col_kind +glp_get_col_kind +glp_get_num_int +glp_get_num_bin +glp_intopt +glp_init_iocp +glp_mip_status +glp_mip_obj_val +glp_mip_row_val +glp_mip_col_val +glp_check_kkt +glp_print_sol +glp_read_sol +glp_write_sol +glp_print_ranges +glp_print_ipt +glp_read_ipt +glp_write_ipt +glp_print_mip +glp_read_mip +glp_write_mip +glp_bf_exists +glp_factorize +glp_bf_updated +glp_get_bfcp +glp_set_bfcp +glp_get_bhead +glp_get_row_bind +glp_get_col_bind +glp_ftran +glp_btran +glp_warm_up +glp_eval_tab_row +glp_eval_tab_col +glp_transform_row +glp_transform_col +glp_prim_rtest +glp_dual_rtest +glp_analyze_bound +glp_analyze_coef +glp_ios_reason +glp_ios_get_prob +glp_ios_tree_size +glp_ios_curr_node +glp_ios_next_node +glp_ios_prev_node +glp_ios_up_node +glp_ios_node_level +glp_ios_node_bound +glp_ios_best_node +glp_ios_mip_gap +glp_ios_node_data +glp_ios_row_attr +glp_ios_pool_size +glp_ios_add_row +glp_ios_del_row +glp_ios_clear_pool +glp_ios_can_branch +glp_ios_branch_upon +glp_ios_select_node +glp_ios_heur_sol +glp_ios_terminate +glp_init_mpscp +glp_read_mps +glp_write_mps +glp_init_cpxcp +glp_read_lp +glp_write_lp +glp_read_prob +glp_write_prob +glp_mpl_alloc_wksp +glp_mpl_read_model +glp_mpl_read_data +glp_mpl_generate +glp_mpl_build_prob +glp_mpl_postsolve +glp_mpl_free_wksp +glp_main +glp_read_cnfsat +glp_check_cnfsat +glp_write_cnfsat +glp_minisat1 +glp_intfeas1 +glp_init_env +glp_version +glp_free_env +glp_puts +glp_printf +glp_vprintf +glp_term_out +glp_term_hook +glp_open_tee +glp_close_tee +glp_error_ +glp_assert_ +glp_error_hook +glp_alloc +glp_realloc +glp_free +glp_mem_limit +glp_mem_usage +glp_create_graph +glp_set_graph_name +glp_add_vertices +glp_set_vertex_name +glp_add_arc +glp_del_vertices +glp_del_arc +glp_erase_graph +glp_delete_graph +glp_create_v_index +glp_find_vertex +glp_delete_v_index +glp_read_graph +glp_write_graph +glp_mincost_lp +glp_mincost_okalg +glp_mincost_relax4 +glp_maxflow_lp +glp_maxflow_ffalg +glp_check_asnprob +glp_asnprob_lp +glp_asnprob_okalg +glp_asnprob_hall +glp_cpp +glp_read_mincost +glp_write_mincost +glp_read_maxflow +glp_write_maxflow +glp_read_asnprob +glp_write_asnprob +glp_read_ccdata +glp_write_ccdata +glp_netgen +glp_netgen_prob +glp_gridgen +glp_rmfgen +glp_weak_comp +glp_strong_comp +glp_top_sort +glp_wclique_exact +;; end of file ;; diff --git a/resources/3rdparty/glpk-4.57/w32/readme.txt b/resources/3rdparty/glpk-4.57/w32/readme.txt new file mode 100644 index 000000000..10daeda4b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w32/readme.txt @@ -0,0 +1,24 @@ +This directory contains batch files and other stuff which you can use +to build GLPK for 32-bit Windows with the native C/C++ compilers. + +Before running the batch file do the following: + +1. Make sure that you have installed the compiler you are going to use + to build GLPK. + +2. Look into corresponding batch file (just right-click it and choose + 'Edit' in the popup menu; DO NOT choose 'Open'). Make sure that HOME + variable specifies correct path to the compiler directory; if not, + make necessary changes. + +To run the batch file just double-click it and wait a bit while the +Make utility does its job. The message 'OPTIMAL SOLUTION FOUND' in the +MS-DOS window means that all is OK. If you do not see it, something is +wrong. + +Once GLPK has been successfully built, there must appear two files in +this directory: + +glpk.lib, which is the GLPK object library, and + +glpsol.exe, which is the stand-alone GLPK LP/MIP solver. diff --git a/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC10.bat b/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC10.bat new file mode 100755 index 000000000..8e8a3e1e7 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC10.bat @@ -0,0 +1,11 @@ +rem Build GLPK with Microsoft Visual Studio Express 2010 + +rem NOTE: Make sure that HOME variable specifies correct path +set HOME="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC" + +call %HOME%\vcvarsall.bat x64 +copy config_VC config.h +%HOME%\bin\nmake.exe /f Makefile_VC +%HOME%\bin\nmake.exe /f Makefile_VC check + +pause diff --git a/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC10_DLL.bat b/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC10_DLL.bat new file mode 100755 index 000000000..0bbe697b3 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC10_DLL.bat @@ -0,0 +1,11 @@ +rem Build GLPK DLL with Microsoft Visual Studio Express 2010 + +rem NOTE: Make sure that HOME variable specifies correct path +set HOME="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC" + +call %HOME%\vcvarsall.bat x64 +copy config_VC config.h +%HOME%\bin\nmake.exe /f Makefile_VC_DLL +%HOME%\bin\nmake.exe /f Makefile_VC_DLL check + +pause diff --git a/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC14.bat b/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC14.bat new file mode 100755 index 000000000..33bdaeaa2 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC14.bat @@ -0,0 +1,11 @@ +rem Build GLPK with Microsoft Visual Studio Community 2015 + +rem NOTE: Make sure that HOME variable specifies correct path +set HOME="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC" + +call %HOME%\vcvarsall.bat x64 +copy config_VC config.h +%HOME%\bin\nmake.exe /f Makefile_VC +%HOME%\bin\nmake.exe /f Makefile_VC check + +pause diff --git a/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC14_DLL.bat b/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC14_DLL.bat new file mode 100755 index 000000000..25a6a87d8 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC14_DLL.bat @@ -0,0 +1,11 @@ +rem Build GLPK DLL with Microsoft Visual Studio Community 2015 + +rem NOTE: Make sure that HOME variable specifies correct path +set HOME="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC" + +call %HOME%\vcvarsall.bat x64 +copy config_VC config.h +%HOME%\bin\nmake.exe /f Makefile_VC_DLL +%HOME%\bin\nmake.exe /f Makefile_VC_DLL check + +pause diff --git a/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC9.bat b/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC9.bat new file mode 100755 index 000000000..9a32ef850 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC9.bat @@ -0,0 +1,11 @@ +rem Build GLPK with Microsoft Visual Studio Express 2008 + +rem NOTE: Make sure that HOME variable specifies correct path +set HOME="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC" + +call %HOME%\bin\vcvars64.bat +copy config_VC config.h +%HOME%\bin\nmake.exe /f Makefile_VC +%HOME%\bin\nmake.exe /f Makefile_VC check + +pause diff --git a/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC9_DLL.bat b/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC9_DLL.bat new file mode 100755 index 000000000..4d7c19719 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w64/Build_GLPK_with_VC9_DLL.bat @@ -0,0 +1,11 @@ +rem Build GLPK DLL with Microsoft Visual Studio Express 2008 + +rem NOTE: Make sure that HOME variable specifies correct path +set HOME="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC" + +call %HOME%\bin\vcvars64.bat +copy config_VC config.h +%HOME%\bin\nmake.exe /f Makefile_VC_DLL +%HOME%\bin\nmake.exe /f Makefile_VC_DLL check + +pause diff --git a/resources/3rdparty/glpk-4.57/w64/config_VC b/resources/3rdparty/glpk-4.57/w64/config_VC new file mode 100644 index 000000000..581ab6e6e --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w64/config_VC @@ -0,0 +1,13 @@ +/* GLPK configuration file (Microsoft Visual Studio Express) */ + +#define __WOE__ 1 + +#define ODBC_DLNAME "odbc32.dll" +/* ODBC shared library name if this feature is enabled */ + +#if 0 +#define MYSQL_DLNAME "libmysql.dll" +/* MySQL shared library name if this feature is enabled */ +#endif + +/* eof */ diff --git a/resources/3rdparty/glpk-4.57/w64/glpk_4_57.def b/resources/3rdparty/glpk-4.57/w64/glpk_4_57.def new file mode 100644 index 000000000..61076961c --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w64/glpk_4_57.def @@ -0,0 +1,223 @@ +LIBRARY glpk_4_57 +VERSION 4.57 +DESCRIPTION "GNU Linear Programming Kit" +EXPORTS +glp_create_prob +glp_set_prob_name +glp_set_obj_name +glp_set_obj_dir +glp_add_rows +glp_add_cols +glp_set_row_name +glp_set_col_name +glp_set_row_bnds +glp_set_col_bnds +glp_set_obj_coef +glp_set_mat_row +glp_set_mat_col +glp_load_matrix +glp_check_dup +glp_sort_matrix +glp_del_rows +glp_del_cols +glp_copy_prob +glp_erase_prob +glp_delete_prob +glp_get_prob_name +glp_get_obj_name +glp_get_obj_dir +glp_get_num_rows +glp_get_num_cols +glp_get_row_name +glp_get_col_name +glp_get_row_type +glp_get_row_lb +glp_get_row_ub +glp_get_col_type +glp_get_col_lb +glp_get_col_ub +glp_get_obj_coef +glp_get_num_nz +glp_get_mat_row +glp_get_mat_col +glp_create_index +glp_find_row +glp_find_col +glp_delete_index +glp_set_rii +glp_set_sjj +glp_get_rii +glp_get_sjj +glp_scale_prob +glp_unscale_prob +glp_set_row_stat +glp_set_col_stat +glp_std_basis +glp_adv_basis +glp_cpx_basis +glp_simplex +glp_exact +glp_init_smcp +glp_get_status +glp_get_prim_stat +glp_get_dual_stat +glp_get_obj_val +glp_get_row_stat +glp_get_row_prim +glp_get_row_dual +glp_get_col_stat +glp_get_col_prim +glp_get_col_dual +glp_get_unbnd_ray +glp_get_it_cnt +glp_set_it_cnt +glp_interior +glp_init_iptcp +glp_ipt_status +glp_ipt_obj_val +glp_ipt_row_prim +glp_ipt_row_dual +glp_ipt_col_prim +glp_ipt_col_dual +glp_set_col_kind +glp_get_col_kind +glp_get_num_int +glp_get_num_bin +glp_intopt +glp_init_iocp +glp_mip_status +glp_mip_obj_val +glp_mip_row_val +glp_mip_col_val +glp_check_kkt +glp_print_sol +glp_read_sol +glp_write_sol +glp_print_ranges +glp_print_ipt +glp_read_ipt +glp_write_ipt +glp_print_mip +glp_read_mip +glp_write_mip +glp_bf_exists +glp_factorize +glp_bf_updated +glp_get_bfcp +glp_set_bfcp +glp_get_bhead +glp_get_row_bind +glp_get_col_bind +glp_ftran +glp_btran +glp_warm_up +glp_eval_tab_row +glp_eval_tab_col +glp_transform_row +glp_transform_col +glp_prim_rtest +glp_dual_rtest +glp_analyze_bound +glp_analyze_coef +glp_ios_reason +glp_ios_get_prob +glp_ios_tree_size +glp_ios_curr_node +glp_ios_next_node +glp_ios_prev_node +glp_ios_up_node +glp_ios_node_level +glp_ios_node_bound +glp_ios_best_node +glp_ios_mip_gap +glp_ios_node_data +glp_ios_row_attr +glp_ios_pool_size +glp_ios_add_row +glp_ios_del_row +glp_ios_clear_pool +glp_ios_can_branch +glp_ios_branch_upon +glp_ios_select_node +glp_ios_heur_sol +glp_ios_terminate +glp_init_mpscp +glp_read_mps +glp_write_mps +glp_init_cpxcp +glp_read_lp +glp_write_lp +glp_read_prob +glp_write_prob +glp_mpl_alloc_wksp +glp_mpl_read_model +glp_mpl_read_data +glp_mpl_generate +glp_mpl_build_prob +glp_mpl_postsolve +glp_mpl_free_wksp +glp_main +glp_read_cnfsat +glp_check_cnfsat +glp_write_cnfsat +glp_minisat1 +glp_intfeas1 +glp_init_env +glp_version +glp_free_env +glp_puts +glp_printf +glp_vprintf +glp_term_out +glp_term_hook +glp_open_tee +glp_close_tee +glp_error_ +glp_assert_ +glp_error_hook +glp_alloc +glp_realloc +glp_free +glp_mem_limit +glp_mem_usage +glp_create_graph +glp_set_graph_name +glp_add_vertices +glp_set_vertex_name +glp_add_arc +glp_del_vertices +glp_del_arc +glp_erase_graph +glp_delete_graph +glp_create_v_index +glp_find_vertex +glp_delete_v_index +glp_read_graph +glp_write_graph +glp_mincost_lp +glp_mincost_okalg +glp_mincost_relax4 +glp_maxflow_lp +glp_maxflow_ffalg +glp_check_asnprob +glp_asnprob_lp +glp_asnprob_okalg +glp_asnprob_hall +glp_cpp +glp_read_mincost +glp_write_mincost +glp_read_maxflow +glp_write_maxflow +glp_read_asnprob +glp_write_asnprob +glp_read_ccdata +glp_write_ccdata +glp_netgen +glp_netgen_prob +glp_gridgen +glp_rmfgen +glp_weak_comp +glp_strong_comp +glp_top_sort +glp_wclique_exact +;; end of file ;; diff --git a/resources/3rdparty/glpk-4.57/w64/makefile_VC b/resources/3rdparty/glpk-4.57/w64/makefile_VC new file mode 100644 index 000000000..e4853f789 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w64/makefile_VC @@ -0,0 +1,204 @@ +## Build GLPK with Microsoft Visual Studio Express ## + +CFLAGS = \ +/I. \ +/I..\src \ +/I..\src\amd \ +/I..\src\bflib \ +/I..\src\cglib \ +/I..\src\colamd \ +/I..\src\env \ +/I..\src\minisat \ +/I..\src\misc \ +/I..\src\proxy \ +/I..\src\simplex \ +/I..\src\zlib \ +/DHAVE_CONFIG_H=1 \ +/D_CRT_SECURE_NO_WARNINGS=1 \ +/nologo \ +/W3 \ +/O2 \ +/Zi + +OBJSET = \ +..\src\avl.obj \ +..\src\bfd.obj \ +..\src\bfx.obj \ +..\src\glpapi01.obj \ +..\src\glpapi02.obj \ +..\src\glpapi03.obj \ +..\src\glpapi04.obj \ +..\src\glpapi05.obj \ +..\src\glpapi06.obj \ +..\src\glpapi07.obj \ +..\src\glpapi08.obj \ +..\src\glpapi09.obj \ +..\src\glpapi10.obj \ +..\src\glpapi11.obj \ +..\src\glpapi12.obj \ +..\src\glpapi13.obj \ +..\src\glpapi14.obj \ +..\src\glpapi15.obj \ +..\src\glpapi16.obj \ +..\src\glpapi17.obj \ +..\src\glpapi18.obj \ +..\src\glpapi19.obj \ +..\src\glpapi20.obj \ +..\src\glpapi21.obj \ +..\src\glpcpx.obj \ +..\src\glpdmx.obj \ +..\src\glpgmp.obj \ +..\src\glphbm.obj \ +..\src\glpini01.obj \ +..\src\glpini02.obj \ +..\src\glpios01.obj \ +..\src\glpios02.obj \ +..\src\glpios03.obj \ +..\src\glpios04.obj \ +..\src\glpios05.obj \ +..\src\glpios06.obj \ +..\src\glpios07.obj \ +..\src\glpios08.obj \ +..\src\glpios09.obj \ +..\src\glpios10.obj \ +..\src\glpios11.obj \ +..\src\glpios12.obj \ +..\src\glpipm.obj \ +..\src\glpmat.obj \ +..\src\glpmpl01.obj \ +..\src\glpmpl02.obj \ +..\src\glpmpl03.obj \ +..\src\glpmpl04.obj \ +..\src\glpmpl05.obj \ +..\src\glpmpl06.obj \ +..\src\glpmps.obj \ +..\src\glpnet03.obj \ +..\src\glpnet04.obj \ +..\src\glpnet05.obj \ +..\src\glpnpp01.obj \ +..\src\glpnpp02.obj \ +..\src\glpnpp03.obj \ +..\src\glpnpp04.obj \ +..\src\glpnpp05.obj \ +..\src\glpnpp06.obj \ +..\src\glprgr.obj \ +..\src\glpscl.obj \ +..\src\glpsdf.obj \ +..\src\glpspm.obj \ +..\src\glpsql.obj \ +..\src\glpssx01.obj \ +..\src\glpssx02.obj \ +..\src\lux.obj \ +..\src\amd\amd_1.obj \ +..\src\amd\amd_2.obj \ +..\src\amd\amd_aat.obj \ +..\src\amd\amd_control.obj \ +..\src\amd\amd_defaults.obj \ +..\src\amd\amd_dump.obj \ +..\src\amd\amd_info.obj \ +..\src\amd\amd_order.obj \ +..\src\amd\amd_post_tree.obj \ +..\src\amd\amd_postorder.obj \ +..\src\amd\amd_preprocess.obj \ +..\src\amd\amd_valid.obj \ +..\src\bflib\btf.obj \ +..\src\bflib\btfint.obj \ +..\src\bflib\fhv.obj \ +..\src\bflib\fhvint.obj \ +..\src\bflib\ifu.obj \ +..\src\bflib\luf.obj \ +..\src\bflib\lufint.obj \ +..\src\bflib\scf.obj \ +..\src\bflib\scfint.obj \ +..\src\bflib\sgf.obj \ +..\src\bflib\sva.obj \ +..\src\cglib\cfg.obj \ +..\src\cglib\cfg1.obj \ +..\src\colamd\colamd.obj \ +..\src\env\alloc.obj \ +..\src\env\dlsup.obj \ +..\src\env\env.obj \ +..\src\env\error.obj \ +..\src\env\stdout.obj \ +..\src\env\stream.obj \ +..\src\env\time.obj \ +..\src\env\tls.obj \ +..\src\minisat\minisat.obj \ +..\src\misc\bignum.obj \ +..\src\misc\dmp.obj \ +..\src\misc\ffalg.obj \ +..\src\misc\fp2rat.obj \ +..\src\misc\gcd.obj \ +..\src\misc\jd.obj \ +..\src\misc\keller.obj \ +..\src\misc\mc13d.obj \ +..\src\misc\mc21a.obj \ +..\src\misc\okalg.obj \ +..\src\misc\qmd.obj \ +..\src\misc\relax4.obj \ +..\src\misc\rng.obj \ +..\src\misc\rng1.obj \ +..\src\misc\round2n.obj \ +..\src\misc\str2int.obj \ +..\src\misc\str2num.obj \ +..\src\misc\strspx.obj \ +..\src\misc\strtrim.obj \ +..\src\misc\triang.obj \ +..\src\misc\wclique.obj \ +..\src\misc\wclique1.obj \ +..\src\proxy\proxy.obj \ +..\src\proxy\proxy1.obj \ +..\src\simplex\spxat.obj \ +..\src\simplex\spxchuzc.obj \ +..\src\simplex\spxchuzr.obj \ +..\src\simplex\spxlp.obj \ +..\src\simplex\spxnt.obj \ +..\src\simplex\spxprim.obj \ +..\src\simplex\spxprob.obj \ +..\src\simplex\spychuzc.obj \ +..\src\simplex\spychuzr.obj \ +..\src\simplex\spydual.obj \ +..\src\zlib\adler32.obj \ +..\src\zlib\compress.obj \ +..\src\zlib\crc32.obj \ +..\src\zlib\deflate.obj \ +..\src\zlib\gzclose.obj \ +..\src\zlib\gzlib.obj \ +..\src\zlib\gzread.obj \ +..\src\zlib\gzwrite.obj \ +..\src\zlib\inffast.obj \ +..\src\zlib\inflate.obj \ +..\src\zlib\inftrees.obj \ +..\src\zlib\trees.obj \ +..\src\zlib\uncompr.obj \ +..\src\zlib\zio.obj \ +..\src\zlib\zutil.obj + +.c.obj: + cl.exe $(CFLAGS) /Fo$*.obj /c $*.c + +all: glpk.lib glpsol.exe + +glpk.lib: $(OBJSET) + lib.exe /out:glpk.lib \ + ..\src\*.obj \ + ..\src\amd\*.obj \ + ..\src\bflib\*.obj \ + ..\src\cglib\*.obj \ + ..\src\colamd\*.obj \ + ..\src\env\*.obj \ + ..\src\minisat\*.obj \ + ..\src\misc\*.obj \ + ..\src\proxy\*.obj \ + ..\src\simplex\*.obj \ + ..\src\zlib\*.obj + +glpsol.exe: ..\examples\glpsol.obj glpk.lib + cl.exe $(CFLAGS) /Feglpsol.exe \ + ..\examples\glpsol.obj glpk.lib + +check: glpsol.exe + .\glpsol.exe --version + .\glpsol.exe --mps ..\examples\plan.mps + +## eof ## diff --git a/resources/3rdparty/glpk-4.57/w64/makefile_VC_DLL b/resources/3rdparty/glpk-4.57/w64/makefile_VC_DLL new file mode 100644 index 000000000..53467e0b5 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w64/makefile_VC_DLL @@ -0,0 +1,205 @@ +## Build GLPK DLL with Microsoft Visual Studio Express ## + +CFLAGS = \ +/I. \ +/I..\src \ +/I..\src\amd \ +/I..\src\bflib \ +/I..\src\cglib \ +/I..\src\colamd \ +/I..\src\env \ +/I..\src\minisat \ +/I..\src\misc \ +/I..\src\proxy \ +/I..\src\simplex \ +/I..\src\zlib \ +/DHAVE_CONFIG_H=1 \ +/D_CRT_SECURE_NO_WARNINGS=1 \ +/nologo \ +/W3 \ +/O2 \ +/Zi + +OBJSET = \ +..\src\avl.obj \ +..\src\bfd.obj \ +..\src\bfx.obj \ +..\src\glpapi01.obj \ +..\src\glpapi02.obj \ +..\src\glpapi03.obj \ +..\src\glpapi04.obj \ +..\src\glpapi05.obj \ +..\src\glpapi06.obj \ +..\src\glpapi07.obj \ +..\src\glpapi08.obj \ +..\src\glpapi09.obj \ +..\src\glpapi10.obj \ +..\src\glpapi11.obj \ +..\src\glpapi12.obj \ +..\src\glpapi13.obj \ +..\src\glpapi14.obj \ +..\src\glpapi15.obj \ +..\src\glpapi16.obj \ +..\src\glpapi17.obj \ +..\src\glpapi18.obj \ +..\src\glpapi19.obj \ +..\src\glpapi20.obj \ +..\src\glpapi21.obj \ +..\src\glpcpx.obj \ +..\src\glpdmx.obj \ +..\src\glpgmp.obj \ +..\src\glphbm.obj \ +..\src\glpini01.obj \ +..\src\glpini02.obj \ +..\src\glpios01.obj \ +..\src\glpios02.obj \ +..\src\glpios03.obj \ +..\src\glpios04.obj \ +..\src\glpios05.obj \ +..\src\glpios06.obj \ +..\src\glpios07.obj \ +..\src\glpios08.obj \ +..\src\glpios09.obj \ +..\src\glpios10.obj \ +..\src\glpios11.obj \ +..\src\glpios12.obj \ +..\src\glpipm.obj \ +..\src\glpmat.obj \ +..\src\glpmpl01.obj \ +..\src\glpmpl02.obj \ +..\src\glpmpl03.obj \ +..\src\glpmpl04.obj \ +..\src\glpmpl05.obj \ +..\src\glpmpl06.obj \ +..\src\glpmps.obj \ +..\src\glpnet03.obj \ +..\src\glpnet04.obj \ +..\src\glpnet05.obj \ +..\src\glpnpp01.obj \ +..\src\glpnpp02.obj \ +..\src\glpnpp03.obj \ +..\src\glpnpp04.obj \ +..\src\glpnpp05.obj \ +..\src\glpnpp06.obj \ +..\src\glprgr.obj \ +..\src\glpscl.obj \ +..\src\glpsdf.obj \ +..\src\glpspm.obj \ +..\src\glpsql.obj \ +..\src\glpssx01.obj \ +..\src\glpssx02.obj \ +..\src\lux.obj \ +..\src\amd\amd_1.obj \ +..\src\amd\amd_2.obj \ +..\src\amd\amd_aat.obj \ +..\src\amd\amd_control.obj \ +..\src\amd\amd_defaults.obj \ +..\src\amd\amd_dump.obj \ +..\src\amd\amd_info.obj \ +..\src\amd\amd_order.obj \ +..\src\amd\amd_post_tree.obj \ +..\src\amd\amd_postorder.obj \ +..\src\amd\amd_preprocess.obj \ +..\src\amd\amd_valid.obj \ +..\src\bflib\btf.obj \ +..\src\bflib\btfint.obj \ +..\src\bflib\fhv.obj \ +..\src\bflib\fhvint.obj \ +..\src\bflib\ifu.obj \ +..\src\bflib\luf.obj \ +..\src\bflib\lufint.obj \ +..\src\bflib\scf.obj \ +..\src\bflib\scfint.obj \ +..\src\bflib\sgf.obj \ +..\src\bflib\sva.obj \ +..\src\cglib\cfg.obj \ +..\src\cglib\cfg1.obj \ +..\src\colamd\colamd.obj \ +..\src\env\alloc.obj \ +..\src\env\dlsup.obj \ +..\src\env\env.obj \ +..\src\env\error.obj \ +..\src\env\stdout.obj \ +..\src\env\stream.obj \ +..\src\env\time.obj \ +..\src\env\tls.obj \ +..\src\minisat\minisat.obj \ +..\src\misc\bignum.obj \ +..\src\misc\dmp.obj \ +..\src\misc\ffalg.obj \ +..\src\misc\fp2rat.obj \ +..\src\misc\gcd.obj \ +..\src\misc\jd.obj \ +..\src\misc\keller.obj \ +..\src\misc\mc13d.obj \ +..\src\misc\mc21a.obj \ +..\src\misc\okalg.obj \ +..\src\misc\qmd.obj \ +..\src\misc\relax4.obj \ +..\src\misc\rng.obj \ +..\src\misc\rng1.obj \ +..\src\misc\round2n.obj \ +..\src\misc\str2int.obj \ +..\src\misc\str2num.obj \ +..\src\misc\strspx.obj \ +..\src\misc\strtrim.obj \ +..\src\misc\triang.obj \ +..\src\misc\wclique.obj \ +..\src\misc\wclique1.obj \ +..\src\proxy\proxy.obj \ +..\src\proxy\proxy1.obj \ +..\src\simplex\spxat.obj \ +..\src\simplex\spxchuzc.obj \ +..\src\simplex\spxchuzr.obj \ +..\src\simplex\spxlp.obj \ +..\src\simplex\spxnt.obj \ +..\src\simplex\spxprim.obj \ +..\src\simplex\spxprob.obj \ +..\src\simplex\spychuzc.obj \ +..\src\simplex\spychuzr.obj \ +..\src\simplex\spydual.obj \ +..\src\zlib\adler32.obj \ +..\src\zlib\compress.obj \ +..\src\zlib\crc32.obj \ +..\src\zlib\deflate.obj \ +..\src\zlib\gzclose.obj \ +..\src\zlib\gzlib.obj \ +..\src\zlib\gzread.obj \ +..\src\zlib\gzwrite.obj \ +..\src\zlib\inffast.obj \ +..\src\zlib\inflate.obj \ +..\src\zlib\inftrees.obj \ +..\src\zlib\trees.obj \ +..\src\zlib\uncompr.obj \ +..\src\zlib\zio.obj \ +..\src\zlib\zutil.obj + +.c.obj: + cl.exe $(CFLAGS) /Fo$*.obj /c $*.c + +all: glpk_4_57.dll glpsol.exe + +glpk_4_57.dll: $(OBJSET) + cl.exe $(CFLAGS) /LD /Feglpk_4_57.dll \ + ..\src\*.obj \ + ..\src\amd\*.obj \ + ..\src\bflib\*.obj \ + ..\src\cglib\*.obj \ + ..\src\colamd\*.obj \ + ..\src\env\*.obj \ + ..\src\minisat\*.obj \ + ..\src\misc\*.obj \ + ..\src\proxy\*.obj \ + ..\src\simplex\*.obj \ + ..\src\zlib\*.obj \ + glpk_4_57.def + +glpsol.exe: ..\examples\glpsol.obj glpk_4_57.dll + cl.exe $(CFLAGS) /Feglpsol.exe \ + ..\examples\glpsol.obj glpk_4_57.lib + +check: glpsol.exe + .\glpsol.exe --version + .\glpsol.exe --mps ..\examples\plan.mps + +## eof ## diff --git a/resources/3rdparty/glpk-4.57/w64/readme.txt b/resources/3rdparty/glpk-4.57/w64/readme.txt new file mode 100644 index 000000000..d5742d964 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/w64/readme.txt @@ -0,0 +1,24 @@ +This directory contains batch files and other stuff which you can use +to build GLPK for 64-bit Windows with the native C/C++ compilers. + +Before running the batch file do the following: + +1. Make sure that you have installed the compiler you are going to use + to build GLPK. + +2. Look into corresponding batch file (just right-click it and choose + 'Edit' in the popup menu; DO NOT choose 'Open'). Make sure that HOME + variable specifies correct path to the compiler directory; if not, + make necessary changes. + +To run the batch file just double-click it and wait a bit while the +Make utility does its job. The message 'OPTIMAL SOLUTION FOUND' in the +MS-DOS window means that all is OK. If you do not see it, something is +wrong. + +Once GLPK has been successfully built, there must appear two files in +this directory: + +glpk.lib, which is the GLPK object library, and + +glpsol.exe, which is the stand-alone GLPK LP/MIP solver. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index be3b825a0..78a65a203 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -109,6 +109,7 @@ endif(ADDITIONAL_LINK_DIRS) add_library(storm ${STORM_LIB_SOURCES} ${STORM_LIB_HEADERS} ${STORM_GENERATED_SOURCES}) # Adding headers for xcode add_dependencies(storm xercesc) add_dependencies(storm sylvan) +add_dependencies(storm glpk) add_executable(storm-main ${STORM_MAIN_SOURCES} ${STORM_MAIN_HEADERS}) target_link_libraries(storm-main storm) # Adding headers for xcode set_target_properties(storm-main PROPERTIES OUTPUT_NAME "storm") From 70ee3396d931c48ebe244d93f2400c1b50ff6fb2 Mon Sep 17 00:00:00 2001 From: sjunges Date: Fri, 12 Feb 2016 18:02:07 +0100 Subject: [PATCH 2/3] we said goodbye to glpk 4.53 Former-commit-id: 0d8fe9d5bce76c182f2598cfd6838d2f21c11be6 --- resources/3rdparty/glpk-4.53/AUTHORS | 33 - resources/3rdparty/glpk-4.53/CMakeLists.txt | 281 - resources/3rdparty/glpk-4.53/COPYING | 674 - resources/3rdparty/glpk-4.53/ChangeLog | 2747 --- resources/3rdparty/glpk-4.53/INSTALL | 209 - resources/3rdparty/glpk-4.53/Makefile.am | 7 - resources/3rdparty/glpk-4.53/Makefile.in | 759 - resources/3rdparty/glpk-4.53/NEWS | 1741 -- resources/3rdparty/glpk-4.53/README | 39 - resources/3rdparty/glpk-4.53/THANKS | 204 - resources/3rdparty/glpk-4.53/aclocal.m4 | 949 -- resources/3rdparty/glpk-4.53/config.guess | 1537 -- .../3rdparty/glpk-4.53/config.h.cmake.in | 27 - resources/3rdparty/glpk-4.53/config.h.in | 27 - resources/3rdparty/glpk-4.53/config.sub | 1789 -- resources/3rdparty/glpk-4.53/configure | 13839 ---------------- resources/3rdparty/glpk-4.53/configure.ac | 147 - resources/3rdparty/glpk-4.53/depcomp | 787 - resources/3rdparty/glpk-4.53/doc/cnfsat.pdf | Bin 59926 -> 0 bytes resources/3rdparty/glpk-4.53/doc/cnfsat.tex | 413 - resources/3rdparty/glpk-4.53/doc/glpk.pdf | Bin 478088 -> 0 bytes resources/3rdparty/glpk-4.53/doc/glpk.tex | 167 - resources/3rdparty/glpk-4.53/doc/glpk01.tex | 343 - resources/3rdparty/glpk-4.53/doc/glpk02.tex | 3428 ---- resources/3rdparty/glpk-4.53/doc/glpk03.tex | 1572 -- resources/3rdparty/glpk-4.53/doc/glpk04.tex | 1385 -- resources/3rdparty/glpk-4.53/doc/glpk05.tex | 1090 -- resources/3rdparty/glpk-4.53/doc/glpk06.tex | 441 - resources/3rdparty/glpk-4.53/doc/glpk07.tex | 258 - resources/3rdparty/glpk-4.53/doc/glpk08.tex | 738 - resources/3rdparty/glpk-4.53/doc/glpk09.tex | 424 - resources/3rdparty/glpk-4.53/doc/glpk10.tex | 166 - resources/3rdparty/glpk-4.53/doc/glpk11.tex | 203 - resources/3rdparty/glpk-4.53/doc/glpk12.tex | 707 - resources/3rdparty/glpk-4.53/doc/gmpl.pdf | Bin 216026 -> 0 bytes resources/3rdparty/glpk-4.53/doc/gmpl.tex | 4295 ----- resources/3rdparty/glpk-4.53/doc/graphs.pdf | Bin 214470 -> 0 bytes resources/3rdparty/glpk-4.53/doc/graphs.tex | 4150 ----- resources/3rdparty/glpk-4.53/doc/miplib2.txt | 135 - resources/3rdparty/glpk-4.53/doc/miplib3.txt | 143 - resources/3rdparty/glpk-4.53/doc/netlib.txt | 103 - .../3rdparty/glpk-4.53/doc/notes/dfeas.pdf | Bin 63866 -> 0 bytes .../3rdparty/glpk-4.53/doc/notes/gomory.pdf | Bin 75445 -> 0 bytes .../3rdparty/glpk-4.53/doc/notes/keller.pdf | Bin 85985 -> 0 bytes .../3rdparty/glpk-4.53/doc/notes/scaling.pdf | Bin 42382 -> 0 bytes .../3rdparty/glpk-4.53/doc/notes/updating.pdf | Bin 41817 -> 0 bytes resources/3rdparty/glpk-4.53/examples/INDEX | 52 - .../3rdparty/glpk-4.53/examples/Makefile.am | 15 - .../3rdparty/glpk-4.53/examples/Makefile.in | 558 - .../3rdparty/glpk-4.53/examples/assign.mod | 77 - resources/3rdparty/glpk-4.53/examples/bpp.mod | 83 - resources/3rdparty/glpk-4.53/examples/cal.mod | 49 - .../3rdparty/glpk-4.53/examples/cf12a.mod | 81 - .../3rdparty/glpk-4.53/examples/cf12b.mod | 88 - .../3rdparty/glpk-4.53/examples/cflsq.mod | 51 - .../3rdparty/glpk-4.53/examples/color.mod | 113 - .../3rdparty/glpk-4.53/examples/cplex/README | 44 - .../glpk-4.53/examples/cplex/concorde.txt | 121 - .../3rdparty/glpk-4.53/examples/cplex/cplex.c | 2130 --- .../3rdparty/glpk-4.53/examples/cplex/cplex.h | 301 - resources/3rdparty/glpk-4.53/examples/cpp.mod | 67 - .../3rdparty/glpk-4.53/examples/crypto.mod | 84 - .../glpk-4.53/examples/csv/distances.csv | 7 - .../glpk-4.53/examples/csv/markets.csv | 4 - .../glpk-4.53/examples/csv/parameters.csv | 2 - .../glpk-4.53/examples/csv/plants.csv | 3 - .../glpk-4.53/examples/csv/transp_csv.mod | 70 - .../dbf/ForestMgt_Model_I_GIS_dbf.mod | 226 - .../glpk-4.53/examples/dbf/Forest_Cost.dbf | Bin 1458 -> 0 bytes .../glpk-4.53/examples/dbf/NetRev_Table.dbf | Bin 11786 -> 0 bytes .../3rdparty/glpk-4.53/examples/dbf/README | 2 - .../glpk-4.53/examples/dbf/TCost_Table.dbf | Bin 11786 -> 0 bytes .../examples/dbf/Yield_Table_Vol.dbf | Bin 11786 -> 0 bytes .../glpk-4.53/examples/dbf/cultural_pres.dbf | Bin 96 -> 0 bytes .../glpk-4.53/examples/dbf/mgt_year.dbf | Bin 106 -> 0 bytes .../glpk-4.53/examples/dbf/stands.dbf | Bin 4323 -> 0 bytes .../glpk-4.53/examples/dbf/standtype.dbf | Bin 96 -> 0 bytes resources/3rdparty/glpk-4.53/examples/dea.mod | 222 - .../3rdparty/glpk-4.53/examples/diet.mod | 99 - .../3rdparty/glpk-4.53/examples/dist.mod | 565 - .../3rdparty/glpk-4.53/examples/egypt.mod | 519 - .../3rdparty/glpk-4.53/examples/fctp.mod | 93 - .../3rdparty/glpk-4.53/examples/food.mod | 127 - .../3rdparty/glpk-4.53/examples/food2.mod | 150 - resources/3rdparty/glpk-4.53/examples/gap.mod | 79 - .../3rdparty/glpk-4.53/examples/glpsol.c | 10 - .../3rdparty/glpk-4.53/examples/graph.mod | 98 - .../3rdparty/glpk-4.53/examples/hashi.mod | 168 - .../3rdparty/glpk-4.53/examples/huge.mod | 25 - .../3rdparty/glpk-4.53/examples/iptsamp.c | 17 - .../3rdparty/glpk-4.53/examples/jssp.mod | 114 - .../3rdparty/glpk-4.53/examples/magic.mod | 54 - .../3rdparty/glpk-4.53/examples/maxcut.mod | 85 - .../3rdparty/glpk-4.53/examples/maxflow.mod | 83 - .../3rdparty/glpk-4.53/examples/mfasp.mod | 62 - .../3rdparty/glpk-4.53/examples/mfvsp.mod | 62 - .../3rdparty/glpk-4.53/examples/min01ks.mod | 111 - .../3rdparty/glpk-4.53/examples/misp.mod | 665 - .../3rdparty/glpk-4.53/examples/misp1.dat | 1489 -- .../3rdparty/glpk-4.53/examples/misp2.dat | 3857 ----- .../3rdparty/glpk-4.53/examples/money.mod | 62 - .../3rdparty/glpk-4.53/examples/mplsamp1.c | 32 - .../3rdparty/glpk-4.53/examples/mplsamp2.c | 39 - .../3rdparty/glpk-4.53/examples/murtagh.mps | 600 - .../3rdparty/glpk-4.53/examples/mvcp.mod | 43 - .../3rdparty/glpk-4.53/examples/netgen.c | 141 - .../3rdparty/glpk-4.53/examples/numbrix.mod | 84 - .../3rdparty/glpk-4.53/examples/oldapi/README | 11 - .../3rdparty/glpk-4.53/examples/oldapi/lpx.c | 1505 -- .../3rdparty/glpk-4.53/examples/oldapi/lpx.h | 565 - .../glpk-4.53/examples/oldapi/lpxsamp.c | 51 - .../3rdparty/glpk-4.53/examples/pbn/9dom.dat | 65 - .../3rdparty/glpk-4.53/examples/pbn/README | 6 - .../3rdparty/glpk-4.53/examples/pbn/bucks.dat | 77 - .../3rdparty/glpk-4.53/examples/pbn/cat.dat | 67 - .../glpk-4.53/examples/pbn/dancer.dat | 42 - .../glpk-4.53/examples/pbn/dragon.dat | 61 - .../3rdparty/glpk-4.53/examples/pbn/edge.dat | 48 - .../glpk-4.53/examples/pbn/forever.dat | 77 - .../3rdparty/glpk-4.53/examples/pbn/knot.dat | 95 - .../3rdparty/glpk-4.53/examples/pbn/light.dat | 122 - .../3rdparty/glpk-4.53/examples/pbn/mum.dat | 101 - .../3rdparty/glpk-4.53/examples/pbn/pbn.mod | 268 - .../3rdparty/glpk-4.53/examples/pbn/pbn.pdf | Bin 43620 -> 0 bytes .../3rdparty/glpk-4.53/examples/pbn/pbn.tex | 279 - .../3rdparty/glpk-4.53/examples/pbn/petro.dat | 102 - .../3rdparty/glpk-4.53/examples/pbn/skid.dat | 66 - .../3rdparty/glpk-4.53/examples/pbn/swing.dat | 117 - resources/3rdparty/glpk-4.53/examples/plan.lp | 39 - .../3rdparty/glpk-4.53/examples/plan.mod | 39 - .../3rdparty/glpk-4.53/examples/plan.mps | 54 - .../3rdparty/glpk-4.53/examples/prod.mod | 331 - .../3rdparty/glpk-4.53/examples/qfit.mod | 49 - .../3rdparty/glpk-4.53/examples/queens.mod | 41 - .../3rdparty/glpk-4.53/examples/samp1.mps | 29 - .../3rdparty/glpk-4.53/examples/samp2.mps | 27 - .../3rdparty/glpk-4.53/examples/sample.asn | 40 - .../3rdparty/glpk-4.53/examples/sample.c | 52 - .../3rdparty/glpk-4.53/examples/sample.clq | 30 - .../3rdparty/glpk-4.53/examples/sample.cnf | 12 - .../3rdparty/glpk-4.53/examples/sample.col | 30 - .../3rdparty/glpk-4.53/examples/sample.max | 26 - .../3rdparty/glpk-4.53/examples/sample.min | 26 - resources/3rdparty/glpk-4.53/examples/sat.mod | 201 - .../glpk-4.53/examples/shiftcover.mod | 244 - .../3rdparty/glpk-4.53/examples/shikaku.mod | 107 - .../3rdparty/glpk-4.53/examples/sorting.mod | 67 - resources/3rdparty/glpk-4.53/examples/spp.mod | 67 - .../3rdparty/glpk-4.53/examples/spxsamp1.c | 18 - .../3rdparty/glpk-4.53/examples/spxsamp2.c | 20 - .../3rdparty/glpk-4.53/examples/sql/README | 5 - .../glpk-4.53/examples/sql/mysql_setup.sh | 6 - .../glpk-4.53/examples/sql/sudoku.sql | 101 - .../glpk-4.53/examples/sql/sudoku_mysql.mod | 113 - .../glpk-4.53/examples/sql/sudoku_odbc.mod | 111 - .../glpk-4.53/examples/sql/transp.sql | 45 - .../glpk-4.53/examples/sql/transp_mysql.mod | 71 - .../glpk-4.53/examples/sql/transp_odbc.mod | 72 - .../3rdparty/glpk-4.53/examples/stigler.mod | 411 - .../3rdparty/glpk-4.53/examples/sudoku.dat | 16 - .../3rdparty/glpk-4.53/examples/sudoku.mod | 84 - resources/3rdparty/glpk-4.53/examples/t1.cs | 99 - resources/3rdparty/glpk-4.53/examples/tas.mod | 486 - .../3rdparty/glpk-4.53/examples/todd.mod | 36 - .../3rdparty/glpk-4.53/examples/train.mod | 281 - .../3rdparty/glpk-4.53/examples/transp.mod | 63 - .../3rdparty/glpk-4.53/examples/trick.mod | 72 - resources/3rdparty/glpk-4.53/examples/tsp.mod | 335 - .../3rdparty/glpk-4.53/examples/xyacfs.mod | 56 - .../3rdparty/glpk-4.53/examples/yacfs.mod | 48 - .../3rdparty/glpk-4.53/examples/zebra.mod | 151 - resources/3rdparty/glpk-4.53/install-sh | 527 - resources/3rdparty/glpk-4.53/ltmain.sh | 9687 ----------- resources/3rdparty/glpk-4.53/m4/libtool.m4 | 7831 --------- resources/3rdparty/glpk-4.53/m4/ltoptions.m4 | 369 - resources/3rdparty/glpk-4.53/m4/ltsugar.m4 | 123 - resources/3rdparty/glpk-4.53/m4/ltversion.m4 | 23 - .../3rdparty/glpk-4.53/m4/lt~obsolete.m4 | 98 - resources/3rdparty/glpk-4.53/missing | 330 - .../glpk-4.53/resources/FindMySQL.cmake | 47 - .../glpk-4.53/resources/FindODBC.cmake | 60 - resources/3rdparty/glpk-4.53/src/Makefile.am | 167 - resources/3rdparty/glpk-4.53/src/Makefile.in | 1949 --- resources/3rdparty/glpk-4.53/src/amd/COPYING | 502 - resources/3rdparty/glpk-4.53/src/amd/README | 58 - resources/3rdparty/glpk-4.53/src/amd/amd.h | 67 - resources/3rdparty/glpk-4.53/src/amd/amd_1.c | 181 - resources/3rdparty/glpk-4.53/src/amd/amd_2.c | 1842 -- .../3rdparty/glpk-4.53/src/amd/amd_aat.c | 185 - .../3rdparty/glpk-4.53/src/amd/amd_control.c | 64 - .../3rdparty/glpk-4.53/src/amd/amd_defaults.c | 38 - .../3rdparty/glpk-4.53/src/amd/amd_dump.c | 180 - .../3rdparty/glpk-4.53/src/amd/amd_info.c | 120 - .../3rdparty/glpk-4.53/src/amd/amd_internal.h | 117 - .../3rdparty/glpk-4.53/src/amd/amd_order.c | 200 - .../glpk-4.53/src/amd/amd_post_tree.c | 121 - .../glpk-4.53/src/amd/amd_postorder.c | 207 - .../glpk-4.53/src/amd/amd_preprocess.c | 119 - .../3rdparty/glpk-4.53/src/amd/amd_valid.c | 93 - resources/3rdparty/glpk-4.53/src/avl.c | 406 - resources/3rdparty/glpk-4.53/src/avl.h | 74 - resources/3rdparty/glpk-4.53/src/bfd.c | 576 - resources/3rdparty/glpk-4.53/src/bfd.h | 73 - resources/3rdparty/glpk-4.53/src/bflib/fhv.c | 586 - resources/3rdparty/glpk-4.53/src/bflib/fhv.h | 114 - .../3rdparty/glpk-4.53/src/bflib/fhvint.c | 181 - .../3rdparty/glpk-4.53/src/bflib/fhvint.h | 74 - resources/3rdparty/glpk-4.53/src/bflib/ifu.c | 392 - resources/3rdparty/glpk-4.53/src/bflib/ifu.h | 99 - resources/3rdparty/glpk-4.53/src/bflib/luf.c | 575 - resources/3rdparty/glpk-4.53/src/bflib/luf.h | 213 - .../3rdparty/glpk-4.53/src/bflib/lufint.c | 218 - .../3rdparty/glpk-4.53/src/bflib/lufint.h | 73 - resources/3rdparty/glpk-4.53/src/bflib/sgf.c | 1407 -- resources/3rdparty/glpk-4.53/src/bflib/sgf.h | 203 - resources/3rdparty/glpk-4.53/src/bflib/sva.c | 568 - resources/3rdparty/glpk-4.53/src/bflib/sva.h | 161 - resources/3rdparty/glpk-4.53/src/bfx.c | 89 - resources/3rdparty/glpk-4.53/src/bfx.h | 67 - resources/3rdparty/glpk-4.53/src/cglib/cfg.c | 409 - resources/3rdparty/glpk-4.53/src/cglib/cfg.h | 130 - resources/3rdparty/glpk-4.53/src/cglib/cfg1.c | 703 - .../3rdparty/glpk-4.53/src/colamd/COPYING | 502 - .../3rdparty/glpk-4.53/src/colamd/README | 98 - .../3rdparty/glpk-4.53/src/colamd/colamd.c | 3622 ---- .../3rdparty/glpk-4.53/src/colamd/colamd.h | 69 - resources/3rdparty/glpk-4.53/src/draft.h | 32 - resources/3rdparty/glpk-4.53/src/env/alloc.c | 252 - resources/3rdparty/glpk-4.53/src/env/dlsup.c | 167 - resources/3rdparty/glpk-4.53/src/env/env.c | 237 - resources/3rdparty/glpk-4.53/src/env/env.h | 258 - resources/3rdparty/glpk-4.53/src/env/error.c | 170 - resources/3rdparty/glpk-4.53/src/env/stdc.h | 42 - resources/3rdparty/glpk-4.53/src/env/stdout.c | 262 - resources/3rdparty/glpk-4.53/src/env/stream.c | 475 - resources/3rdparty/glpk-4.53/src/env/time.c | 159 - resources/3rdparty/glpk-4.53/src/env/tls.c | 72 - resources/3rdparty/glpk-4.53/src/glpapi01.c | 1571 -- resources/3rdparty/glpk-4.53/src/glpapi02.c | 492 - resources/3rdparty/glpk-4.53/src/glpapi03.c | 167 - resources/3rdparty/glpk-4.53/src/glpapi04.c | 157 - resources/3rdparty/glpk-4.53/src/glpapi05.c | 169 - resources/3rdparty/glpk-4.53/src/glpapi06.c | 822 - resources/3rdparty/glpk-4.53/src/glpapi07.c | 456 - resources/3rdparty/glpk-4.53/src/glpapi08.c | 388 - resources/3rdparty/glpk-4.53/src/glpapi09.c | 786 - resources/3rdparty/glpk-4.53/src/glpapi10.c | 305 - resources/3rdparty/glpk-4.53/src/glpapi11.c | 1235 -- resources/3rdparty/glpk-4.53/src/glpapi12.c | 2237 --- resources/3rdparty/glpk-4.53/src/glpapi13.c | 706 - resources/3rdparty/glpk-4.53/src/glpapi14.c | 272 - resources/3rdparty/glpk-4.53/src/glpapi15.c | 615 - resources/3rdparty/glpk-4.53/src/glpapi16.c | 330 - resources/3rdparty/glpk-4.53/src/glpapi17.c | 1269 -- resources/3rdparty/glpk-4.53/src/glpapi18.c | 123 - resources/3rdparty/glpk-4.53/src/glpapi19.c | 133 - resources/3rdparty/glpk-4.53/src/glpapi20.c | 257 - resources/3rdparty/glpk-4.53/src/glpapi21.c | 1428 -- resources/3rdparty/glpk-4.53/src/glpcpx.c | 1262 -- resources/3rdparty/glpk-4.53/src/glpdmx.c | 1693 -- resources/3rdparty/glpk-4.53/src/glpgmp.c | 1116 -- resources/3rdparty/glpk-4.53/src/glpgmp.h | 190 - resources/3rdparty/glpk-4.53/src/glphbm.c | 529 - resources/3rdparty/glpk-4.53/src/glphbm.h | 127 - resources/3rdparty/glpk-4.53/src/glpini01.c | 155 - resources/3rdparty/glpk-4.53/src/glpini02.c | 270 - resources/3rdparty/glpk-4.53/src/glpios.h | 620 - resources/3rdparty/glpk-4.53/src/glpios01.c | 1602 -- resources/3rdparty/glpk-4.53/src/glpios02.c | 826 - resources/3rdparty/glpk-4.53/src/glpios03.c | 1438 -- resources/3rdparty/glpk-4.53/src/glpios04.c | 304 - resources/3rdparty/glpk-4.53/src/glpios05.c | 282 - resources/3rdparty/glpk-4.53/src/glpios06.c | 1448 -- resources/3rdparty/glpk-4.53/src/glpios07.c | 551 - resources/3rdparty/glpk-4.53/src/glpios08.c | 147 - resources/3rdparty/glpk-4.53/src/glpios09.c | 664 - resources/3rdparty/glpk-4.53/src/glpios10.c | 355 - resources/3rdparty/glpk-4.53/src/glpios11.c | 282 - resources/3rdparty/glpk-4.53/src/glpios12.c | 177 - resources/3rdparty/glpk-4.53/src/glpipm.c | 1144 -- resources/3rdparty/glpk-4.53/src/glpipm.h | 36 - resources/3rdparty/glpk-4.53/src/glpk.h | 1076 -- resources/3rdparty/glpk-4.53/src/glplpf.c | 1097 -- resources/3rdparty/glpk-4.53/src/glplpf.h | 216 - resources/3rdparty/glpk-4.53/src/glpmat.c | 924 -- resources/3rdparty/glpk-4.53/src/glpmat.h | 198 - resources/3rdparty/glpk-4.53/src/glpmpl.h | 2594 --- resources/3rdparty/glpk-4.53/src/glpmpl01.c | 4715 ------ resources/3rdparty/glpk-4.53/src/glpmpl02.c | 1203 -- resources/3rdparty/glpk-4.53/src/glpmpl03.c | 6085 ------- resources/3rdparty/glpk-4.53/src/glpmpl04.c | 1427 -- resources/3rdparty/glpk-4.53/src/glpmpl05.c | 563 - resources/3rdparty/glpk-4.53/src/glpmpl06.c | 1000 -- resources/3rdparty/glpk-4.53/src/glpmps.c | 1433 -- resources/3rdparty/glpk-4.53/src/glpnet03.c | 1020 -- resources/3rdparty/glpk-4.53/src/glpnet04.c | 769 - resources/3rdparty/glpk-4.53/src/glpnet05.c | 368 - resources/3rdparty/glpk-4.53/src/glpnpp.h | 638 - resources/3rdparty/glpk-4.53/src/glpnpp01.c | 938 -- resources/3rdparty/glpk-4.53/src/glpnpp02.c | 1434 -- resources/3rdparty/glpk-4.53/src/glpnpp03.c | 2862 ---- resources/3rdparty/glpk-4.53/src/glpnpp04.c | 1415 -- resources/3rdparty/glpk-4.53/src/glpnpp05.c | 810 - resources/3rdparty/glpk-4.53/src/glpnpp06.c | 1501 -- resources/3rdparty/glpk-4.53/src/glprgr.c | 165 - resources/3rdparty/glpk-4.53/src/glprgr.h | 34 - resources/3rdparty/glpk-4.53/src/glpscl.c | 478 - resources/3rdparty/glpk-4.53/src/glpsdf.c | 259 - resources/3rdparty/glpk-4.53/src/glpsdf.h | 63 - resources/3rdparty/glpk-4.53/src/glpspm.c | 847 - resources/3rdparty/glpk-4.53/src/glpspm.h | 165 - resources/3rdparty/glpk-4.53/src/glpspx.h | 40 - resources/3rdparty/glpk-4.53/src/glpspx01.c | 2971 ---- resources/3rdparty/glpk-4.53/src/glpspx02.c | 3118 ---- resources/3rdparty/glpk-4.53/src/glpsql.c | 1644 -- resources/3rdparty/glpk-4.53/src/glpsql.h | 64 - resources/3rdparty/glpk-4.53/src/glpssx.h | 426 - resources/3rdparty/glpk-4.53/src/glpssx01.c | 839 - resources/3rdparty/glpk-4.53/src/glpssx02.c | 479 - resources/3rdparty/glpk-4.53/src/glptsp.c | 667 - resources/3rdparty/glpk-4.53/src/glptsp.h | 104 - resources/3rdparty/glpk-4.53/src/lux.c | 1030 -- resources/3rdparty/glpk-4.53/src/lux.h | 220 - .../3rdparty/glpk-4.53/src/minisat/LICENSE | 20 - .../3rdparty/glpk-4.53/src/minisat/README | 22 - .../3rdparty/glpk-4.53/src/minisat/minisat.c | 1299 -- .../3rdparty/glpk-4.53/src/minisat/minisat.h | 230 - .../3rdparty/glpk-4.53/src/misc/bignum.c | 286 - .../3rdparty/glpk-4.53/src/misc/bignum.h | 37 - resources/3rdparty/glpk-4.53/src/misc/dmp.c | 243 - resources/3rdparty/glpk-4.53/src/misc/dmp.h | 63 - resources/3rdparty/glpk-4.53/src/misc/ffalg.c | 221 - resources/3rdparty/glpk-4.53/src/misc/ffalg.h | 34 - .../3rdparty/glpk-4.53/src/misc/fp2rat.c | 164 - resources/3rdparty/glpk-4.53/src/misc/gcd.c | 102 - resources/3rdparty/glpk-4.53/src/misc/jd.c | 152 - resources/3rdparty/glpk-4.53/src/misc/jd.h | 32 - .../3rdparty/glpk-4.53/src/misc/keller.c | 235 - .../3rdparty/glpk-4.53/src/misc/keller.h | 34 - resources/3rdparty/glpk-4.53/src/misc/mc13d.c | 314 - resources/3rdparty/glpk-4.53/src/misc/mc13d.h | 34 - resources/3rdparty/glpk-4.53/src/misc/mc21a.c | 301 - resources/3rdparty/glpk-4.53/src/misc/mc21a.h | 34 - resources/3rdparty/glpk-4.53/src/misc/misc.h | 61 - resources/3rdparty/glpk-4.53/src/misc/okalg.c | 382 - resources/3rdparty/glpk-4.53/src/misc/okalg.h | 35 - resources/3rdparty/glpk-4.53/src/misc/qmd.c | 584 - resources/3rdparty/glpk-4.53/src/misc/qmd.h | 58 - .../3rdparty/glpk-4.53/src/misc/relax4.c | 2850 ---- .../3rdparty/glpk-4.53/src/misc/relax4.h | 102 - resources/3rdparty/glpk-4.53/src/misc/rng.c | 227 - resources/3rdparty/glpk-4.53/src/misc/rng.h | 67 - resources/3rdparty/glpk-4.53/src/misc/rng1.c | 73 - .../3rdparty/glpk-4.53/src/misc/round2n.c | 64 - .../3rdparty/glpk-4.53/src/misc/str2int.c | 92 - .../3rdparty/glpk-4.53/src/misc/str2num.c | 110 - .../3rdparty/glpk-4.53/src/misc/strspx.c | 60 - .../3rdparty/glpk-4.53/src/misc/strtrim.c | 62 - .../3rdparty/glpk-4.53/src/misc/triang.c | 311 - .../3rdparty/glpk-4.53/src/misc/triang.h | 34 - .../3rdparty/glpk-4.53/src/misc/wclique.c | 242 - .../3rdparty/glpk-4.53/src/misc/wclique.h | 33 - .../3rdparty/glpk-4.53/src/misc/wclique1.c | 317 - .../3rdparty/glpk-4.53/src/misc/wclique1.h | 34 - resources/3rdparty/glpk-4.53/src/prob.h | 276 - resources/3rdparty/glpk-4.53/src/proxy/main.c | 87 - .../3rdparty/glpk-4.53/src/proxy/proxy.c | 1061 -- .../3rdparty/glpk-4.53/src/proxy/proxy.h | 36 - .../3rdparty/glpk-4.53/src/proxy/proxy1.c | 39 - resources/3rdparty/glpk-4.53/src/zlib/README | 45 - .../3rdparty/glpk-4.53/src/zlib/adler32.c | 169 - .../3rdparty/glpk-4.53/src/zlib/compress.c | 80 - resources/3rdparty/glpk-4.53/src/zlib/crc32.c | 442 - resources/3rdparty/glpk-4.53/src/zlib/crc32.h | 441 - .../3rdparty/glpk-4.53/src/zlib/deflate.c | 1834 -- .../3rdparty/glpk-4.53/src/zlib/deflate.h | 342 - .../3rdparty/glpk-4.53/src/zlib/gzclose.c | 25 - .../3rdparty/glpk-4.53/src/zlib/gzguts.h | 74 - resources/3rdparty/glpk-4.53/src/zlib/gzlib.c | 537 - .../3rdparty/glpk-4.53/src/zlib/gzread.c | 653 - .../3rdparty/glpk-4.53/src/zlib/gzwrite.c | 531 - .../3rdparty/glpk-4.53/src/zlib/inffast.c | 340 - .../3rdparty/glpk-4.53/src/zlib/inffast.h | 11 - .../3rdparty/glpk-4.53/src/zlib/inffixed.h | 94 - .../3rdparty/glpk-4.53/src/zlib/inflate.c | 1480 -- .../3rdparty/glpk-4.53/src/zlib/inflate.h | 122 - .../3rdparty/glpk-4.53/src/zlib/inftrees.c | 330 - .../3rdparty/glpk-4.53/src/zlib/inftrees.h | 62 - resources/3rdparty/glpk-4.53/src/zlib/trees.c | 1244 -- resources/3rdparty/glpk-4.53/src/zlib/trees.h | 128 - .../3rdparty/glpk-4.53/src/zlib/uncompr.c | 59 - resources/3rdparty/glpk-4.53/src/zlib/zconf.h | 168 - resources/3rdparty/glpk-4.53/src/zlib/zio.c | 92 - resources/3rdparty/glpk-4.53/src/zlib/zio.h | 37 - resources/3rdparty/glpk-4.53/src/zlib/zlib.h | 1613 -- resources/3rdparty/glpk-4.53/src/zlib/zutil.c | 318 - resources/3rdparty/glpk-4.53/src/zlib/zutil.h | 93 - .../glpk-4.53/w32/Build_GLPK_with_VC10.bat | 11 - .../w32/Build_GLPK_with_VC10_DLL.bat | 11 - .../glpk-4.53/w32/Build_GLPK_with_VC9.bat | 11 - .../glpk-4.53/w32/Build_GLPK_with_VC9_DLL.bat | 11 - resources/3rdparty/glpk-4.53/w32/Makefile_VC | 191 - .../3rdparty/glpk-4.53/w32/Makefile_VC_DLL | 192 - resources/3rdparty/glpk-4.53/w32/config_VC | 13 - .../3rdparty/glpk-4.53/w32/glpk_4_53.def | 223 - resources/3rdparty/glpk-4.53/w32/readme.txt | 24 - .../glpk-4.53/w64/Build_GLPK_with_VC10.bat | 11 - .../w64/Build_GLPK_with_VC10_DLL.bat | 11 - .../glpk-4.53/w64/Build_GLPK_with_VC9.bat | 11 - .../glpk-4.53/w64/Build_GLPK_with_VC9_DLL.bat | 11 - resources/3rdparty/glpk-4.53/w64/config_VC | 13 - .../3rdparty/glpk-4.53/w64/glpk_4_53.def | 223 - resources/3rdparty/glpk-4.53/w64/makefile_VC | 191 - .../3rdparty/glpk-4.53/w64/makefile_VC_DLL | 192 - resources/3rdparty/glpk-4.53/w64/readme.txt | 24 - 415 files changed, 207916 deletions(-) delete mode 100644 resources/3rdparty/glpk-4.53/AUTHORS delete mode 100644 resources/3rdparty/glpk-4.53/CMakeLists.txt delete mode 100644 resources/3rdparty/glpk-4.53/COPYING delete mode 100644 resources/3rdparty/glpk-4.53/ChangeLog delete mode 100644 resources/3rdparty/glpk-4.53/INSTALL delete mode 100644 resources/3rdparty/glpk-4.53/Makefile.am delete mode 100644 resources/3rdparty/glpk-4.53/Makefile.in delete mode 100644 resources/3rdparty/glpk-4.53/NEWS delete mode 100644 resources/3rdparty/glpk-4.53/README delete mode 100644 resources/3rdparty/glpk-4.53/THANKS delete mode 100644 resources/3rdparty/glpk-4.53/aclocal.m4 delete mode 100644 resources/3rdparty/glpk-4.53/config.guess delete mode 100644 resources/3rdparty/glpk-4.53/config.h.cmake.in delete mode 100644 resources/3rdparty/glpk-4.53/config.h.in delete mode 100644 resources/3rdparty/glpk-4.53/config.sub delete mode 100644 resources/3rdparty/glpk-4.53/configure delete mode 100644 resources/3rdparty/glpk-4.53/configure.ac delete mode 100644 resources/3rdparty/glpk-4.53/depcomp delete mode 100644 resources/3rdparty/glpk-4.53/doc/cnfsat.pdf delete mode 100644 resources/3rdparty/glpk-4.53/doc/cnfsat.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/glpk.pdf delete mode 100644 resources/3rdparty/glpk-4.53/doc/glpk.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/glpk01.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/glpk02.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/glpk03.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/glpk04.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/glpk05.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/glpk06.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/glpk07.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/glpk08.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/glpk09.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/glpk10.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/glpk11.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/glpk12.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/gmpl.pdf delete mode 100644 resources/3rdparty/glpk-4.53/doc/gmpl.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/graphs.pdf delete mode 100644 resources/3rdparty/glpk-4.53/doc/graphs.tex delete mode 100644 resources/3rdparty/glpk-4.53/doc/miplib2.txt delete mode 100644 resources/3rdparty/glpk-4.53/doc/miplib3.txt delete mode 100644 resources/3rdparty/glpk-4.53/doc/netlib.txt delete mode 100644 resources/3rdparty/glpk-4.53/doc/notes/dfeas.pdf delete mode 100644 resources/3rdparty/glpk-4.53/doc/notes/gomory.pdf delete mode 100644 resources/3rdparty/glpk-4.53/doc/notes/keller.pdf delete mode 100644 resources/3rdparty/glpk-4.53/doc/notes/scaling.pdf delete mode 100644 resources/3rdparty/glpk-4.53/doc/notes/updating.pdf delete mode 100644 resources/3rdparty/glpk-4.53/examples/INDEX delete mode 100644 resources/3rdparty/glpk-4.53/examples/Makefile.am delete mode 100644 resources/3rdparty/glpk-4.53/examples/Makefile.in delete mode 100644 resources/3rdparty/glpk-4.53/examples/assign.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/bpp.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/cal.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/cf12a.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/cf12b.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/cflsq.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/color.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/cplex/README delete mode 100644 resources/3rdparty/glpk-4.53/examples/cplex/concorde.txt delete mode 100644 resources/3rdparty/glpk-4.53/examples/cplex/cplex.c delete mode 100644 resources/3rdparty/glpk-4.53/examples/cplex/cplex.h delete mode 100644 resources/3rdparty/glpk-4.53/examples/cpp.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/crypto.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/csv/distances.csv delete mode 100644 resources/3rdparty/glpk-4.53/examples/csv/markets.csv delete mode 100644 resources/3rdparty/glpk-4.53/examples/csv/parameters.csv delete mode 100644 resources/3rdparty/glpk-4.53/examples/csv/plants.csv delete mode 100644 resources/3rdparty/glpk-4.53/examples/csv/transp_csv.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/dbf/ForestMgt_Model_I_GIS_dbf.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/dbf/Forest_Cost.dbf delete mode 100644 resources/3rdparty/glpk-4.53/examples/dbf/NetRev_Table.dbf delete mode 100644 resources/3rdparty/glpk-4.53/examples/dbf/README delete mode 100644 resources/3rdparty/glpk-4.53/examples/dbf/TCost_Table.dbf delete mode 100644 resources/3rdparty/glpk-4.53/examples/dbf/Yield_Table_Vol.dbf delete mode 100644 resources/3rdparty/glpk-4.53/examples/dbf/cultural_pres.dbf delete mode 100644 resources/3rdparty/glpk-4.53/examples/dbf/mgt_year.dbf delete mode 100644 resources/3rdparty/glpk-4.53/examples/dbf/stands.dbf delete mode 100644 resources/3rdparty/glpk-4.53/examples/dbf/standtype.dbf delete mode 100644 resources/3rdparty/glpk-4.53/examples/dea.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/diet.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/dist.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/egypt.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/fctp.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/food.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/food2.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/gap.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/glpsol.c delete mode 100644 resources/3rdparty/glpk-4.53/examples/graph.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/hashi.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/huge.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/iptsamp.c delete mode 100644 resources/3rdparty/glpk-4.53/examples/jssp.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/magic.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/maxcut.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/maxflow.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/mfasp.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/mfvsp.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/min01ks.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/misp.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/misp1.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/misp2.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/money.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/mplsamp1.c delete mode 100644 resources/3rdparty/glpk-4.53/examples/mplsamp2.c delete mode 100644 resources/3rdparty/glpk-4.53/examples/murtagh.mps delete mode 100644 resources/3rdparty/glpk-4.53/examples/mvcp.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/netgen.c delete mode 100644 resources/3rdparty/glpk-4.53/examples/numbrix.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/oldapi/README delete mode 100644 resources/3rdparty/glpk-4.53/examples/oldapi/lpx.c delete mode 100644 resources/3rdparty/glpk-4.53/examples/oldapi/lpx.h delete mode 100644 resources/3rdparty/glpk-4.53/examples/oldapi/lpxsamp.c delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/9dom.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/README delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/bucks.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/cat.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/dancer.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/dragon.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/edge.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/forever.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/knot.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/light.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/mum.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/pbn.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/pbn.pdf delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/pbn.tex delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/petro.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/skid.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/pbn/swing.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/plan.lp delete mode 100644 resources/3rdparty/glpk-4.53/examples/plan.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/plan.mps delete mode 100644 resources/3rdparty/glpk-4.53/examples/prod.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/qfit.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/queens.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/samp1.mps delete mode 100644 resources/3rdparty/glpk-4.53/examples/samp2.mps delete mode 100644 resources/3rdparty/glpk-4.53/examples/sample.asn delete mode 100644 resources/3rdparty/glpk-4.53/examples/sample.c delete mode 100644 resources/3rdparty/glpk-4.53/examples/sample.clq delete mode 100644 resources/3rdparty/glpk-4.53/examples/sample.cnf delete mode 100644 resources/3rdparty/glpk-4.53/examples/sample.col delete mode 100644 resources/3rdparty/glpk-4.53/examples/sample.max delete mode 100644 resources/3rdparty/glpk-4.53/examples/sample.min delete mode 100644 resources/3rdparty/glpk-4.53/examples/sat.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/shiftcover.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/shikaku.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/sorting.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/spp.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/spxsamp1.c delete mode 100644 resources/3rdparty/glpk-4.53/examples/spxsamp2.c delete mode 100644 resources/3rdparty/glpk-4.53/examples/sql/README delete mode 100644 resources/3rdparty/glpk-4.53/examples/sql/mysql_setup.sh delete mode 100644 resources/3rdparty/glpk-4.53/examples/sql/sudoku.sql delete mode 100644 resources/3rdparty/glpk-4.53/examples/sql/sudoku_mysql.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/sql/sudoku_odbc.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/sql/transp.sql delete mode 100644 resources/3rdparty/glpk-4.53/examples/sql/transp_mysql.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/sql/transp_odbc.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/stigler.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/sudoku.dat delete mode 100644 resources/3rdparty/glpk-4.53/examples/sudoku.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/t1.cs delete mode 100644 resources/3rdparty/glpk-4.53/examples/tas.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/todd.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/train.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/transp.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/trick.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/tsp.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/xyacfs.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/yacfs.mod delete mode 100644 resources/3rdparty/glpk-4.53/examples/zebra.mod delete mode 100644 resources/3rdparty/glpk-4.53/install-sh delete mode 100644 resources/3rdparty/glpk-4.53/ltmain.sh delete mode 100644 resources/3rdparty/glpk-4.53/m4/libtool.m4 delete mode 100644 resources/3rdparty/glpk-4.53/m4/ltoptions.m4 delete mode 100644 resources/3rdparty/glpk-4.53/m4/ltsugar.m4 delete mode 100644 resources/3rdparty/glpk-4.53/m4/ltversion.m4 delete mode 100644 resources/3rdparty/glpk-4.53/m4/lt~obsolete.m4 delete mode 100644 resources/3rdparty/glpk-4.53/missing delete mode 100644 resources/3rdparty/glpk-4.53/resources/FindMySQL.cmake delete mode 100644 resources/3rdparty/glpk-4.53/resources/FindODBC.cmake delete mode 100644 resources/3rdparty/glpk-4.53/src/Makefile.am delete mode 100644 resources/3rdparty/glpk-4.53/src/Makefile.in delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/COPYING delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/README delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/amd.h delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/amd_1.c delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/amd_2.c delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/amd_aat.c delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/amd_control.c delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/amd_defaults.c delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/amd_dump.c delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/amd_info.c delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/amd_internal.h delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/amd_order.c delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/amd_post_tree.c delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/amd_postorder.c delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/amd_preprocess.c delete mode 100644 resources/3rdparty/glpk-4.53/src/amd/amd_valid.c delete mode 100644 resources/3rdparty/glpk-4.53/src/avl.c delete mode 100644 resources/3rdparty/glpk-4.53/src/avl.h delete mode 100644 resources/3rdparty/glpk-4.53/src/bfd.c delete mode 100644 resources/3rdparty/glpk-4.53/src/bfd.h delete mode 100644 resources/3rdparty/glpk-4.53/src/bflib/fhv.c delete mode 100644 resources/3rdparty/glpk-4.53/src/bflib/fhv.h delete mode 100644 resources/3rdparty/glpk-4.53/src/bflib/fhvint.c delete mode 100644 resources/3rdparty/glpk-4.53/src/bflib/fhvint.h delete mode 100644 resources/3rdparty/glpk-4.53/src/bflib/ifu.c delete mode 100644 resources/3rdparty/glpk-4.53/src/bflib/ifu.h delete mode 100644 resources/3rdparty/glpk-4.53/src/bflib/luf.c delete mode 100644 resources/3rdparty/glpk-4.53/src/bflib/luf.h delete mode 100644 resources/3rdparty/glpk-4.53/src/bflib/lufint.c delete mode 100644 resources/3rdparty/glpk-4.53/src/bflib/lufint.h delete mode 100644 resources/3rdparty/glpk-4.53/src/bflib/sgf.c delete mode 100644 resources/3rdparty/glpk-4.53/src/bflib/sgf.h delete mode 100644 resources/3rdparty/glpk-4.53/src/bflib/sva.c delete mode 100644 resources/3rdparty/glpk-4.53/src/bflib/sva.h delete mode 100644 resources/3rdparty/glpk-4.53/src/bfx.c delete mode 100644 resources/3rdparty/glpk-4.53/src/bfx.h delete mode 100644 resources/3rdparty/glpk-4.53/src/cglib/cfg.c delete mode 100644 resources/3rdparty/glpk-4.53/src/cglib/cfg.h delete mode 100644 resources/3rdparty/glpk-4.53/src/cglib/cfg1.c delete mode 100644 resources/3rdparty/glpk-4.53/src/colamd/COPYING delete mode 100644 resources/3rdparty/glpk-4.53/src/colamd/README delete mode 100644 resources/3rdparty/glpk-4.53/src/colamd/colamd.c delete mode 100644 resources/3rdparty/glpk-4.53/src/colamd/colamd.h delete mode 100644 resources/3rdparty/glpk-4.53/src/draft.h delete mode 100644 resources/3rdparty/glpk-4.53/src/env/alloc.c delete mode 100644 resources/3rdparty/glpk-4.53/src/env/dlsup.c delete mode 100644 resources/3rdparty/glpk-4.53/src/env/env.c delete mode 100644 resources/3rdparty/glpk-4.53/src/env/env.h delete mode 100644 resources/3rdparty/glpk-4.53/src/env/error.c delete mode 100644 resources/3rdparty/glpk-4.53/src/env/stdc.h delete mode 100644 resources/3rdparty/glpk-4.53/src/env/stdout.c delete mode 100644 resources/3rdparty/glpk-4.53/src/env/stream.c delete mode 100644 resources/3rdparty/glpk-4.53/src/env/time.c delete mode 100644 resources/3rdparty/glpk-4.53/src/env/tls.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi01.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi02.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi03.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi04.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi05.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi06.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi07.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi08.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi09.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi10.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi11.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi12.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi13.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi14.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi15.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi16.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi17.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi18.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi19.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi20.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpapi21.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpcpx.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpdmx.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpgmp.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpgmp.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glphbm.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glphbm.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glpini01.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpini02.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpios.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glpios01.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpios02.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpios03.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpios04.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpios05.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpios06.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpios07.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpios08.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpios09.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpios10.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpios11.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpios12.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpipm.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpipm.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glpk.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glplpf.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glplpf.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glpmat.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpmat.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glpmpl.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glpmpl01.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpmpl02.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpmpl03.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpmpl04.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpmpl05.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpmpl06.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpmps.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpnet03.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpnet04.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpnet05.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpnpp.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glpnpp01.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpnpp02.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpnpp03.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpnpp04.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpnpp05.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpnpp06.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glprgr.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glprgr.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glpscl.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpsdf.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpsdf.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glpspm.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpspm.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glpspx.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glpspx01.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpspx02.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpsql.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpsql.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glpssx.h delete mode 100644 resources/3rdparty/glpk-4.53/src/glpssx01.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glpssx02.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glptsp.c delete mode 100644 resources/3rdparty/glpk-4.53/src/glptsp.h delete mode 100644 resources/3rdparty/glpk-4.53/src/lux.c delete mode 100644 resources/3rdparty/glpk-4.53/src/lux.h delete mode 100644 resources/3rdparty/glpk-4.53/src/minisat/LICENSE delete mode 100644 resources/3rdparty/glpk-4.53/src/minisat/README delete mode 100644 resources/3rdparty/glpk-4.53/src/minisat/minisat.c delete mode 100644 resources/3rdparty/glpk-4.53/src/minisat/minisat.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/bignum.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/bignum.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/dmp.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/dmp.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/ffalg.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/ffalg.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/fp2rat.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/gcd.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/jd.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/jd.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/keller.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/keller.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/mc13d.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/mc13d.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/mc21a.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/mc21a.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/misc.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/okalg.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/okalg.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/qmd.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/qmd.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/relax4.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/relax4.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/rng.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/rng.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/rng1.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/round2n.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/str2int.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/str2num.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/strspx.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/strtrim.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/triang.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/triang.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/wclique.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/wclique.h delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/wclique1.c delete mode 100644 resources/3rdparty/glpk-4.53/src/misc/wclique1.h delete mode 100644 resources/3rdparty/glpk-4.53/src/prob.h delete mode 100644 resources/3rdparty/glpk-4.53/src/proxy/main.c delete mode 100644 resources/3rdparty/glpk-4.53/src/proxy/proxy.c delete mode 100644 resources/3rdparty/glpk-4.53/src/proxy/proxy.h delete mode 100644 resources/3rdparty/glpk-4.53/src/proxy/proxy1.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/README delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/adler32.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/compress.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/crc32.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/crc32.h delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/deflate.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/deflate.h delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/gzclose.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/gzguts.h delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/gzlib.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/gzread.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/gzwrite.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/inffast.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/inffast.h delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/inffixed.h delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/inflate.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/inflate.h delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/inftrees.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/inftrees.h delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/trees.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/trees.h delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/uncompr.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/zconf.h delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/zio.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/zio.h delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/zlib.h delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/zutil.c delete mode 100644 resources/3rdparty/glpk-4.53/src/zlib/zutil.h delete mode 100644 resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC10.bat delete mode 100644 resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC10_DLL.bat delete mode 100644 resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC9.bat delete mode 100644 resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC9_DLL.bat delete mode 100644 resources/3rdparty/glpk-4.53/w32/Makefile_VC delete mode 100644 resources/3rdparty/glpk-4.53/w32/Makefile_VC_DLL delete mode 100644 resources/3rdparty/glpk-4.53/w32/config_VC delete mode 100644 resources/3rdparty/glpk-4.53/w32/glpk_4_53.def delete mode 100644 resources/3rdparty/glpk-4.53/w32/readme.txt delete mode 100644 resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC10.bat delete mode 100644 resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC10_DLL.bat delete mode 100644 resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC9.bat delete mode 100644 resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC9_DLL.bat delete mode 100644 resources/3rdparty/glpk-4.53/w64/config_VC delete mode 100644 resources/3rdparty/glpk-4.53/w64/glpk_4_53.def delete mode 100644 resources/3rdparty/glpk-4.53/w64/makefile_VC delete mode 100644 resources/3rdparty/glpk-4.53/w64/makefile_VC_DLL delete mode 100644 resources/3rdparty/glpk-4.53/w64/readme.txt diff --git a/resources/3rdparty/glpk-4.53/AUTHORS b/resources/3rdparty/glpk-4.53/AUTHORS deleted file mode 100644 index 8771f0d86..000000000 --- a/resources/3rdparty/glpk-4.53/AUTHORS +++ /dev/null @@ -1,33 +0,0 @@ -The GLPK package was developed and programmed by Andrew Makhorin, -Department for Applied Informatics, Moscow Aviation Institute, Moscow, -Russia. - -E-mail: - -Paper mail: 125871, Russia, Moscow, Volokolamskoye sh., 4, - Moscow Aviation Institute, Andrew O. Makhorin - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.2.2 (MingW32) - -mQGiBD8UdT8RBAC6yWYxoa1b7U973J0jBuQpgZnhXlGJJpMZgAW9efDBD17vhkJm -hPVOQBKRUeOOLcW3/a7NMoNLMdmF1Rgz1FPVy3RgBDsYj4Sp4RBCsX/o0xXh+jxe -gncr4bdN0Ruk03pezVtLi9oYygdxfI51SsjZ2vwYP6BhMwv+xrIgcnc4qwCgoCit -26mTd0FoGOmsQuipo6X5LaUD/1l7NqFIjiGdWthyG3TqsiK5Ew7xF3fLEABXKPjb -PMRTMucX8XXHmW8RUD1vP1uGDnEn6s+fjc3/RtaqKjqGMdLt4XgHQkImaVguNpSS -IxN3LaK600BgAbwSd1bomRqWNlczAM7469VvGG9ASpCBveUUrqwerHZcUbvngL62 -pIcqA/41dO0xYrOTqMRhuguYMgHL2xbwB2Aj2TqRwBm697DIS25B9nE+8UsbjGRx -q3EmeuHeZ5kN5RbESXkGUB8whIcYxvH16HRNmM1ZjmFoBVL2Z6S2gpa2ZUqsq7BZ -s+hriElm3dfOQCt79/o852uKWu5bSjw2yiemVA2T8tG4OoN6DrQjQW5kcmV3IE1h -a2hvcmluIDxtYW9AbWFpMi5yY25ldC5ydT6IWwQTEQIAGwUCPxR1PwYLCQgHAwID -FQIDAxYCAQIeAQIXgAAKCRDRe/IwWYHoGKpHAJ44MmzWKr8OiTc0Bb6/RD56aekp -3wCdGznQMCfWFkehQPbeNaB5yFIs+8a5AQ0EPxR1UBAEAO3U3H5M0iYv06C4kKty -6ReWyYH4CzMAfp2lPVUKzRSjPtoAJ6SkrBSKMT+U+DahxZ4K4HbinvHq3uvlwWax -xw0wKxJl4oY6EGE1Jqn3B//Ak47RaNMnrs9V739WT1YNRpQvh4wOCeMekBzksf43 -hm4dSV4PMQkLmrEeG2+BYaZnAAMFA/4tVHhjGRkxzcTcfHCB+Yo3PXeIQMuIs00c -VKCrNReLni/3BWZC0w9tFzZSdz+URXefPWDGuAC16vLCVOD06NcIQGutPe189dUn -Kf9Bl6qc9DyWsxSTdF/PbLqcLfEe9g7fHhIwdY+w/hSq2n3NEURMzHiMT1U3CvHd -As5IzV/yD4hGBBgRAgAGBQI/FHVQAAoJENF78jBZgegYRZEAmwReJkMSrbs0EQs2 -wjyTCMd5KDh3AKCR2/RvVad9RT3ShYnUiPPYTL2/Nw== -=OfLQ ------END PGP PUBLIC KEY BLOCK----- diff --git a/resources/3rdparty/glpk-4.53/CMakeLists.txt b/resources/3rdparty/glpk-4.53/CMakeLists.txt deleted file mode 100644 index 8302fa365..000000000 --- a/resources/3rdparty/glpk-4.53/CMakeLists.txt +++ /dev/null @@ -1,281 +0,0 @@ -cmake_minimum_required (VERSION 2.8.6) - -# Set project name -project (glpk CXX C) - -# Add the resources/cmake folder to Module Search Path for FindMySQL.cmake -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/resources/") - -# Add base folder for better inclusion paths -include_directories("${PROJECT_SOURCE_DIR}") -include_directories("${PROJECT_SOURCE_DIR}/src") -include_directories("${PROJECT_SOURCE_DIR}/src/amd") -include_directories("${PROJECT_SOURCE_DIR}/src/bflib") -include_directories("${PROJECT_SOURCE_DIR}/src/cglib") -include_directories("${PROJECT_SOURCE_DIR}/src/colamd") -include_directories("${PROJECT_SOURCE_DIR}/src/env") -include_directories("${PROJECT_SOURCE_DIR}/src/minisat") -include_directories("${PROJECT_SOURCE_DIR}/src/misc") -include_directories("${PROJECT_SOURCE_DIR}/src/proxy") -include_directories("${PROJECT_SOURCE_DIR}/src/zlib") - -############################################################# -## -## CMake options of GLPK -## -############################################################# -option(WITH_GLPK_EXAMPLES "Also build examples and standalone executables" OFF) -option(WITH_GMP "Use GNU MO bignum library" OFF) -option(ENABLE_DL "Enable shared library support" OFF) -option(ENABLE_ODBC "Enable MathProg ODBC support" OFF) -option(ENABLE_MYSQL "Enable MathProg MySQL support" OFF) -option(DEBUG "Sets whether the DEBUG mode is used" OFF) -set(ADDITIONAL_INCLUDE_DIRS "" CACHE STRING "Additional directories added to the include directories.") -set(ADDITIONAL_LINK_DIRS "" CACHE STRING "Additional directories added to the link directories.") - -MARK_AS_ADVANCED(WITH_GLPK_EXAMPLES WITH_GMP ENABLE_DL ENABLE_ODBC ENABLE_MYSQL) - -# If the DEBUG option was turned on, we will target a debug version and a release version otherwise -if (DEBUG) - set (CMAKE_BUILD_TYPE "DEBUG") -else() - set (CMAKE_BUILD_TYPE "RELEASE") -endif() -message(STATUS "GLPK - Building ${CMAKE_BUILD_TYPE} version.") -message(STATUS "GLPK - CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") -message(STATUS "GLPK - CMAKE_BUILD_TYPE (ENV): $ENV{CMAKE_BUILD_TYPE}") - - -############################################################# -## -## Compiler specific settings and definitions -## -############################################################# - -if(CMAKE_COMPILER_IS_GNUCC) - message(STATUS "GLPK - Using Compiler Configuration: GCC") - # Set standard flags for GCC - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-return-type -Wno-parentheses -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unused-value -Wno-unused-function -Wno-address -Wno-unused-label") - add_definitions(-DHAVE_CONFIG_H=1) -elseif(MSVC) - message(STATUS "GLPK - Using Compiler Configuration: MSVC") - add_definitions(/D_SCL_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS) - add_definitions(/D_VARIADIC_MAX=10) - add_definitions(/DNOMINMAX) - add_definitions(/DHAVE_CONFIG_H=1) -else(CLANG) - message(STATUS "GLPK - Using Compiler Configuration: Clang (LLVM)") - # As CLANG is not set as a variable, we need to set it in case we have not matched another compiler. - set (CLANG ON) - # Set standard flags for clang - set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -funroll-loops -O3") - - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-return-type -Wno-return-type-c-linkage -Wno-unused-label -Wno-unused-value -Wno-unused-function -Wno-unused-variable -Wno-logical-op-parentheses -Wno-macro-redefined -Wno-uninitialized -Wno-sometimes-uninitialized -Wno-self-assign") - - set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g") - add_definitions(-DHAVE_CONFIG_H=1) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -version-info=37:0:1 -export-symbols-regex='^glp_*'") -endif() - -############################################################# -## -## CMake-generated Config File for GLPK -## -############################################################# -include(CheckIncludeFiles) -include(CheckFunctionExists) -CHECK_INCLUDE_FILES(sys/time.h HAVE_SYS_TIME_H) -CHECK_FUNCTION_EXISTS(gettimeofday HAVE_GETTIMEOFDAY) -CHECK_INCLUDE_FILES(ltdl.h HAVE_LTDL) -CHECK_INCLUDE_FILES(dlfcn.h HAVE_DLFCN) -if(WITH_GMP) - message(STATUS "GLPK - Building with GMP Support") - CHECK_INCLUDE_FILE(gmp.h HAVE_GMP_H) - if (NOT HAVE_GMP_H) - message(SEND_ERROR "Could not find gmp.h!") - endif() - set(GLPK_HAVE_GMP "define") -else() - set(GLPK_HAVE_GMP "undef") -endif() - -if (UNIX AND NOT APPLE) - set(LIBIODBC "libiodbc.so") - set(LIBODBC "libodbc.so") - set(LIBMYSQL "libmysqlclient.so") -elseif(UNIX AND APPLE) - set(LIBIODBC "libiodbc.dylib") - set(LIBODBC "libodbc.dylib") - set(LIBMYSQL "libmysqlclient.dylib") -elseif(MSVC) - set(LIBIODBC "odbc32.lib") - set(LIBODBC "odbc32.lib") - set(LIBMYSQL "mysqlclient.lib") -endif() - -if(ENABLE_ODBC) - message(STATUS "GLPK - Building with ODBC Support") - find_package(ODBC REQUIRED) - if (NOT ENABLE_DL) - message(SEND_ERROR "ENABLE_ODBC required ENABLE_DL") - endif() - include_directories(ODBC_INCLUDE_DIRECTORIES) - set(GLPK_HAVE_ODBC "define") - set(GLPK_ODBC_DLNAME "${ODBC_LIBRARIES}") -else() - set(GLPK_HAVE_ODBC "undef") - set(GLPK_ODBC_DLNAME "") -endif() - -if(ENABLE_MYSQL) - message(STATUS "GLPK - Building with MySQL Support") - find_package(MySQL REQUIRED) - if (NOT ENABLE_DL) - message(SEND_ERROR "ENABLE_MYSQL required ENABLE_DL") - endif() - include_directories(MYSQL_INCLUDE_DIR) - set(GLPK_HAVE_MYSQL "define") - set(GLPK_MYSQL_DLNAME "${MYSQL_LIBRARIES}") -else() - set(GLPK_HAVE_MYSQL "undef") - set(GLPK_MYSQL_DLNAME "") -endif() - -# Convert to CMake Variables to be used in the Config File -if(HAVE_SYS_TIME_H) - set(GLPK_HAVE_SYS_TIME_H "define") -else() - set (GLPK_HAVE_SYS_TIME_H "undef") -endif() -if(HAVE_GETTIMEOFDAY) - set(GLPK_HAVE_GETTIMEOFDAY "define") -else() - set (GLPK_HAVE_GETTIMEOFDAY "undef") -endif() -if(HAVE_LTDL) - set(GLPK_HAVE_LTDL "define") -else() - set (GLPK_HAVE_LTDL "undef") -endif() -if(HAVE_DLFCN) - set(GLPK_HAVE_DLFCN "define") -else() - set (GLPK_HAVE_DLFCN "undef") -endif() - - -# Configure a header file to pass some of the CMake settings to the source code -configure_file ( - "${PROJECT_SOURCE_DIR}/config.h.cmake.in" - "${PROJECT_BINARY_DIR}/include/config.h" -) -# Add the binary dir include directory for config.h -include_directories("${PROJECT_BINARY_DIR}/include") - -############################################################# -## -## Source file aggregation and clustering -## -############################################################# -file(GLOB_RECURSE GLPK_LIB_HEADERS ${PROJECT_SOURCE_DIR}/src/*.h) -file(GLOB_RECURSE GLPK_LIB_SOURCES ${PROJECT_SOURCE_DIR}/src/*.c) - -file(GLOB_RECURSE GLPK_LIB_DEF ${PROJECT_SOURCE_DIR}/w64/*.def) - -set(GLPK_EXAMPLE_GLPSOL_SOURCES ${PROJECT_SOURCE_DIR}/examples/glpsol.c) -set(GLPK_EXAMPLE_IPTSAMP_SOURCES ${PROJECT_SOURCE_DIR}/examples/iptsamp.c) -set(GLPK_EXAMPLE_MPLSAMP1_SOURCES ${PROJECT_SOURCE_DIR}/examples/mplsamp1.c) -set(GLPK_EXAMPLE_MPLSAMP2_SOURCES ${PROJECT_SOURCE_DIR}/examples/mplsamp2.c) -set(GLPK_EXAMPLE_SAMPLE_SOURCES ${PROJECT_SOURCE_DIR}/examples/sample.c) -set(GLPK_EXAMPLE_SPXSAMP1_SOURCES ${PROJECT_SOURCE_DIR}/examples/spxsamp1.c) -set(GLPK_EXAMPLE_SPXSAMP2_SOURCES ${PROJECT_SOURCE_DIR}/examples/spxsamp2.c) -set(GLPK_EXAMPLE_NETGEN_SOURCES ${PROJECT_SOURCE_DIR}/examples/netgen.c) - -# Additional include files like the storm-config.h -file(GLOB_RECURSE GLPK_BUILD_HEADERS ${PROJECT_BINARY_DIR}/include/*.h) - -# Add custom additional include or link directories -if (ADDITIONAL_INCLUDE_DIRS) - message(STATUS "GLPK - Using additional include directories ${ADDITIONAL_INCLUDE_DIRS}") - include_directories(${ADDITIONAL_INCLUDE_DIRS}) -endif(ADDITIONAL_INCLUDE_DIRS) -if (ADDITIONAL_LINK_DIRS) - message(STATUS "GLPK - Using additional link directories ${ADDITIONAL_LINK_DIRS}") - link_directories(${ADDITIONAL_LINK_DIRS}) -endif(ADDITIONAL_LINK_DIRS) - -############################################################################### -## # -## Executable Creation # -## # -## All link_directories() calls MUST be made before this point # -## # -############################################################################### -if(WITH_GLPK_EXAMPLES) - add_executable(glpsol ${GLPK_EXAMPLE_GLPSOL_SOURCES}) - add_executable(iptsamp ${GLPK_EXAMPLE_IPTSAMP_SOURCES}) - add_executable(mplsamp1 ${GLPK_EXAMPLE_MPLSAMP1_SOURCES}) - add_executable(mplsamp2 ${GLPK_EXAMPLE_MPLSAMP2_SOURCES}) - add_executable(spxsamp1 ${GLPK_EXAMPLE_SPXSAMP1_SOURCES}) - add_executable(spxsamp2 ${GLPK_EXAMPLE_SPXSAMP2_SOURCES}) - add_executable(netgen ${GLPK_EXAMPLE_NETGEN_SOURCES}) - add_executable(sample ${GLPK_EXAMPLE_SAMPLE_SOURCES}) -endif() - -if(ENABLE_DL) - set(GLPK_BUILD_TYPE SHARED) -else() - set(GLPK_BUILD_TYPE STATIC) -endif() -if (NOT MSVC) - set(GLPK_LIB_DEF "") -endif() - -add_library(glpk ${GLPK_BUILD_TYPE} ${GLPK_LIB_SOURCES} ${GLPK_LIB_HEADERS} ${GLPK_LIB_DEF}) -IF(UNIX) - target_link_libraries(glpk m) -ENDIF(UNIX) -if(HAVE_LTDL) - target_link_libraries(glpk ltdl) -endif(HAVE_LTDL) -if(HAVE_DLFCN) - target_link_libraries(glpk dl) -endif(HAVE_DLFCN) - -if(WITH_GLPK_EXAMPLES) - # Dependency for the Executable - add_dependencies(glpsol glpk) - add_dependencies(iptsamp glpk) - add_dependencies(mplsamp1 glpk) - add_dependencies(mplsamp2 glpk) - add_dependencies(spxsamp1 glpk) - add_dependencies(spxsamp2 glpk) - add_dependencies(netgen glpk) - add_dependencies(sample glpk) - target_link_libraries(glpsol glpk) - target_link_libraries(iptsamp glpk) - target_link_libraries(mplsamp1 glpk) - target_link_libraries(mplsamp2 glpk) - target_link_libraries(spxsamp1 glpk) - target_link_libraries(spxsamp2 glpk) - target_link_libraries(netgen glpk) - target_link_libraries(sample glpk) -endif() - -############################################################# -## -## ODBC -## -############################################################# -if(ODBC_FOUND) - target_link_libraries(glpk ${ODBC_LIBRARIES}) -endif() - -############################################################# -## -## MySQL -## -############################################################# -if(MYSQL_FOUND) - target_link_libraries(glpk ${MYSQL_LIBRARIES}) -endif() diff --git a/resources/3rdparty/glpk-4.53/COPYING b/resources/3rdparty/glpk-4.53/COPYING deleted file mode 100644 index 94a9ed024..000000000 --- a/resources/3rdparty/glpk-4.53/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/resources/3rdparty/glpk-4.53/ChangeLog b/resources/3rdparty/glpk-4.53/ChangeLog deleted file mode 100644 index 1200edce6..000000000 --- a/resources/3rdparty/glpk-4.53/ChangeLog +++ /dev/null @@ -1,2747 +0,0 @@ -Thu Feb 13 12:00:00 2014 Andrew Makhorin - - * GLPK 4.53 (37:0:1) has been released. - - * src/glpmps.c (glp_read_mps) - The code was changed to remove free rows at the end. - - * src/glpcpx.c (glp_read_lp) - A bug was fixed (explicit bounds for binaries not set). Thanks - to Gabriel Hackebeil for bug report. - - * src/glpenv07.c (z_fgetc) - A bug was fixed (Z_STREAM_END -> Z_OK). Thanks to Achim Gaedke - for bug report. - - * src/glpenv07.c - Replaced by src/env/stream.c. - - * src/glpenv08.c - Replaced by src/env/dlsup.c. - - * src/bflib/ifu.h, src/bflib/ifu.c - Re-implemented. - - * src/glpscf.h, src/glpscf.c - Replaced by IFU. - - * src/glplpf.h, src/glplpf.c - Changed due to IFU. - - * src/glpbfd.c - Changed due to LPF. - - * src/glpapi06.c - Two API routines glp_get_it_cnt and glp_set_it_cnt were added. - Thanks to Joey Rios for suggestion. - - * src/glplpx.h, src/glplpx01.c, src/glplpx02.c, src/glplpx03.c - All obsolete API routines were completely removed. - - * examples/oldapi/lpx.h, examples/oldapi/lpx.c - A set of routines that simulate the old GLPK API (as defined - in 4.48) were added. Thanks to Jan Engelhardt - for suggestion. - - * src/zlib/* - zlib 1.2.7 was downgraded to zlib 1.2.5 (from glpk 4.50) due to - bugs detected in zlib 1.2.7 on some 64-bit platforms. Thanks to - Carlo Baldassi for bug report. - - * src/glpsql.c - Alignment bug was fixed. Thanks to Xypron - for suggestion. - - * src/glpsql.c - #include and #include were commented - out to fix a namespace bug on compiling with MariaDB. Thanks to - Xypron for suggestion. - -Sun Jul 28 12:00:00 2013 Andrew Makhorin - - * GLPK 4.52.1 (36:1:0) has been released. - - * src/Makefile.am - Version information bug was fixed. Thanks to Sebastien Villemot - for bug report. - - * src/proxy/proxy.c - A minor bug (incorrect use of glp_term_out) was fixed. - - * src/glpios03.c - The simple rounding heuristic routine was changed to check only - global constraints. - - * src/glpcpx.c - The code was changed to issue the warning message 'lower/upper - bound redefined' only once. - -Thu Jul 18 12:00:00 2013 Andrew Makhorin - - * GLPK 4.52 (36:0:1) has been released. - - * src/misc/wclique1.h, src/misc/wclique1.c - Greedy heuristic to find maximum weight clique was implemented. - - * src/cglib/cfg.h, src/cglib/cfg.c, src/cglib/cfg1.c - Conflict graph routines (used to generate clique cuts) were - implemented. - - * src/glpios08.c - New version of the clique cut generator was implemented. Now it - is able to efficiently process very large and/or dense conflict - graphs. Old rudimentary version was removed from the package. - - * examples/misp1.dat, examples/misp2.dat - Two data files for the maximum independent set problem (MISP) - were added to illustrate efficiency of using the clique cuts. - - * src/glpios03.c - Simple rounding heuristic applied for every node subproblem was - implemented. - - * proxy/proxy.c - Some bugs were fixed in the proximity search heuristic routine. - Thanks to Giorgio Sartor <0gioker0@gmail.com>. - - * src/glpapi21.c - New command-line option '--proxy [nnn]' was added to glpsol to - enable using the proximity search heuristic. - - * src/glpspx02.c - A feature was added to switch to the primal simplex in case of - stalling due to dual degeneracy (for GLP_DUALP only). - - * src/glpmps.c - A bug (incorrect processing of LI column indicator) was fixed - in the mps format reading routine. Thanks to Charles Brixko for - bug report. - -Wed Jun 19 12:00:00 2013 Andrew Makhorin - - * GLPK 4.51 (36:0:0) has been released. - - * src/bflib/sgf.c, src/bflib/sgf.h - Singleton and dense phases of sparse Gaussian factorizer were - implemented. - - * src/bflib/lufint.c, src/bflib/lufint.h - Interface routines to LU-factorization were added. - - * src/bflib/fhvint.c, src/bflib/fhvint.h - Interface routines to FHV-factorization were changed to use - lufint.c routines. - - * src/glplpf.c, src/glplpf.h - Routines implementing Schur-complement version of the LP basis - factorization were changed to use lufint.c routines. - - * src/glpbfd.c, src/glpbfd.h - Interface routines to the LP basis factorization were changed - due to changes in glplpf.c routines. - - * src/glpluf.c, src/glpluf.c - Old version of LU-factorization was removed from the package. - (This old version was used for 10 years since 3.0.6.) - - * src/misc/triang.c, src/misc/triang.h - Routine to find maximal triangular part of rectangular matrix - was added. - - * src/glpini01.c - The API routine glp_adv_basis that constructs advanced initial - LP basis was replaced by an improved version, which (unlike the - old version) takes into account numerical values of constraint - coefficients. - - * src/proxy/* - Routines that implement the proximity search heuristic for MIP - were added. Thanks to Giorgio Sartor <0gioker0@gmail.com> for - contribution. - - * src/glpk.h - iocp.ps_heur was added to enable/disable proxy heuristic. - - * glpsol - --proxy command-line option was added. - - * src/zlib/*.* - zlib general purpose compression library, version 1.2.7, - was ANSIfied and modified according to GLPK requirements and - included in the distribution as an external software module. - This version replaced the old one (1.2.5). For details please - see src/zlib/README. - - * src/glpk.h, src/env/time.c - The API routine glp_time was changed to return double rather - than glp_long. - - * src/glplib02.c - Routines that implement glp_long type (64-bit arithmetic) were - removed from the package. - - * src/glpk.h, src/env/alloc.c - New API routine glp_alloc was added. It makes obsolete two - API routines glp_malloc and glp_calloc which were replaced by - macros to use glp_alloc (hence 36:0:0). - - * src/glpios10.c - A bug was fixed that caused numerical instability in the FPUMP - heuristic (the bug was introduced in glpk 4.40). - -Fri May 24 12:00:00 2013 Andrew Makhorin - - * GLPK 4.50 (35:0:0) has been released - - * src/Makefile.am - Though API was not changed since 4.49, symbols _glp_lpx_* were - removed from the export list, hence 35:0:0. - - * src/glpfhv.h, src/glpfhv.c - Old routines for FHV-factorization were removed. - - * src/bflib/*.h, src/bflib/*.c - New version of basis factorization routines, including routines - for FHV-factorization, were added. - - * src/glpbfd.c - LP basis factorization driver was changed according to the new - routines for FHV-factorization. - - * doc/glpk.tex - Some clarifications about using the name index routines were - added. Thanks to Xypron for suggestion. - - * doc/gmpl.tex - Some typos were corrected. - Thanks to Jeffrey Kantor for report. - - * src/glprlx.c - A serious bug was *tentatively* fixed. This bug is inherited - from the original Fortran version of the RELAX-IV code. - Unfortunately, the code is very intricate, so this bug is still - under investigation. Thanks to Sylvain Fournier for bug report. - - RELAX-IV bug details - -------------------- - In the original RELAX-IV code there are four similar fragments - in subroutines ascnt1 and ascnt2 like this: - - C - C DECREASE THE PRICES OF THE SCANNED NODES BY DELPRC. - C ADJUST FLOW TO MAINTAIN COMPLEMENTARY SLACKNESS WITH - C THE PRICES. - C - NB = 0 - DO 6 I=1,NSAVE - . . . - IF (RC(ARC).EQ.0) THEN - DELX=DELX+U(ARC) - NB = NB + 1 - PRDCSR(NB) = ARC - END IF - . . . - - On some instances the variable NB becomes greater than N (the - number of nodes) that leads to indexing error, because the - array PRDCSR is declared as array of N elements (more - precisely, as array of MAXNN elements, however, NB becomes even - much greater than MAXNN). - -Tue Apr 16 12:00:00 2013 Andrew Makhorin - - * GLPK 4.49 (34:0:0) has been released - - * glprlx.c, glprlx.h - C version of the Fortran code RELAX-IV (relaxation method of - Bertsekas and Tseng) was added. - - * glpapi17.c - API routine glp_mincost_relax4, which is a driver to RELAX-IV - code, was added and documented. - - * glpnet03.c - API routine glp_netgen_prob (Klingman's standard network - problems) was added and documented. - - * glpapi12.c - A bug (wrong dual feasibility test) was fixed in API routine - glp_warm_up. Thanks to David T. Price - for bug report. - - * glpapi10.c - Obsolete API routine lpx_check_kkt was replaced by API routine - glp_check_kkt. - - * glpk.h - All old API routines whose names begin with 'lpx_' were removed - from API and no more available. - - * glpk.tex, graphs.tex - These documents were essentially reformatted. - -Mon Jan 28 12:00:00 2013 Andrew Makhorin - - * GLPK 4.48 (33:0:0) has been released - - * src/glpmps.c - A bug in glp_write_mps was fixed. Thanks to Raniere Gaia Costa - da Silva for bug report. - - * glpk.h - glp_prob declaration changed (now it is incomplete struct); - glp_tree declaration changed (now it is incomplete struct); - glp_tran declaration changed (now it is incomplete struct); - glp_long declaration removed; - glp_time declaration removed; - glp_difftime removed from API; - glp_data removed from API; - glp_sdf_* removed from API; - glp_mem_usage declaration changed (glp_long -> size_t); - glp_realloc declaration added (not documented yet). - - * glpenv.h, glpenv05.c - Dynamic memory allocation routines were reimplemented. - - * glpk.h, glpnet03.c - Routine glp_netgen_prob was added (not documented yet). - - * configure.ac - Check for gmp.h was added. Thanks to Heinrich Schuchardt for - suggestion. - - * w32/glpk.def, w64/glpk.def - Changes were made to export only API symbols. - -Fri Sep 09 12:00:00 2011 Andrew Makhorin - - * GLPK 4.47 (32:0:32) has been released - - * src/glpapi20.c - New API routine glp_infeas1 to solve 0-1 feasibility problem - was added and documented (see doc/cnfsat.pdf). - - * src/glpnpp06.c - Some new preprocessor routines for SAT-CNF encoding, which are - used by the routine glp_intfeas1, were added. - - * src/glpnpp.h - The header was modified due to additions. - - * src/glpapi21.c - The glpsol solver was modified to bypass model postprocessing - if the solution reported is neither optimal nor feasible. - - * src/glpapi21.c - New glpsol options (--minisat and --objbnd) were added. - - * examples/pbn/*.* - The paint-by-numbers puzzle model (pbn.mod) was modified to - print solution in PostScript format and to check for multiple - solutions. Some benchmark examples from encoded - in MathProg were included in the distribution. For more details - see examples/pbn/README and examples/pbn/pbn.pdf. - - * examples/Makefile.am - A minor bug was fixed to correctly build glpk in a separate - directory. Thanks to Marco Atzeri for - bug report. - -Tue Aug 09 12:00:00 2011 Andrew Makhorin - - * GLPK 4.46 (31:0:31) has been released - - * src/glpk.h, src/Makefile - glpk.h was relocated from 'include' to 'src', and 'include' - subdir was removed; src/Makefile.am was changed appropriately. - - * src/zlib/*.* - zlib general purpose compression library, version 1.2.5, - was ANSIfied and modified according to GLPK requirements and - included in the distribution as an external software module. - - For details see src/zlib/README. - - * src/glpdmx.c - The following new API routines were added: - glp_read_cnfsat - read CNF-SAT problem data in DIMACS format - glp_check_cnfsat - check for CNF-SAT problem instance - glp_write_cnfsat - write CNF-SAT problem data in DIMACS format - - * src/minisat/*.* - MiniSat, a CNF-SAT solver, version 1.14.1, was ANSIfied and - modified according to GLPK requirements and included in the - distribution as an external software module. - - For details see minisat/README and minisat/LICENSE. - - * src/glpapi19.c - The API routine glp_minisat1, which is a driver to the MiniSat - solver, was included in the package. - - * doc/satcnf.* - The document "CNF Satisfiability Problem" was included in the - package. It is a supplement to the GLPK Reference Manual. - - * src/glpapi20.c - New glpsol options (--cnf, --wcnf, and --minisat) was added. - - * glpsql.c - Some bugs were fixed. Thanks to Xypron . - -Sun Dec 05 12:00:00 2010 Andrew Makhorin - - * GLPK 4.45 (30:0:30) has been released - - * glplpx01.c - A bug (it_cnt) in routine reset_parms was fixed. - Thanks to Ali Baharev for report. - - * glpmpl03.c - A bug (print "text\") was fixed. - Thanks to Xypron for report. - - * glpsql.c - A precision bug was fixed. - Thanks to Xypron . - - * glpk.tex - Some typos were corrected. - Thanks to Robbie Morrison . - -Thu Jun 03 12:00:00 2010 Andrew Makhorin - - * GLPK 4.44 (29:0:29) has been released - - * glpapi14.c glpmpl.h glpmpl01.c glpmpl03.c glpmpl04.c - Implemented suffixes for variables and constraints. - - * glpmpl06.c - Made changes to allow comment records in CSV files. - - * glpapi17.c - Added and documented new API routine glp_cpp to solve Critical - Path Problem. - -Sat Feb 20 12:00:00 2010 Andrew Makhorin - - * GLPK 4.43 (28:0:28) has been released - - * glplib.h, glplib.c, glpenv.h, glpenv.c - The module glpenv was split into two modules glpenv and glplib. - - * glpenv01.c, glpenv03.c, glpenv04.c, glpenv06.c - The following new API routines were added and documented: - glp_init_env, glp_free_env, glp_open_tee, glp_close_tee, - glp_error (macro), glp_difftime. - - * glpapi16.c - New API routine glp_top_sort (topological sorting of ayclic - digraph) was added and documented. - - * glpapi17.c - A serious bug was fixed in the routine glp_asn_prob_hall. - - * glpnpp05.c - A bug was fixed in the LP/MIP preprocessor (hidden covering - inequalities). - - * glpsql.c - Some improvements were made in the table driver (NULL data). - Thanks to Xypron for contribution. - - * configure.ac - Changes were made to use .dylib rather than .so under Mac OS. - Thanks to Noli Sicad for testing - -Wed Jan 13 12:00:00 2010 Andrew Makhorin - - * GLPK 4.42 (27:0:27) has been released - - * glpapi01.c, glpapi11.c, glpapi12.c, glpdmx.c - The following new API routines were added and documented: - glp_check_dup (check for duplicate elements in sparse matrix); - glp_sort_matrix (sort elements of the constraint matrix); - glp_read_prob (read problem data in GLPK format); - glp_write_prob (write problem data in GLPK format); - glp_analyze_bound (analyze active bound of non-basic variable); - glp_analyze_coef (analyze obj. coefficient at basic variable); - glp_print_ranges (print sensitivity analysis report; replaces - lpx_print_sens_bnds). - - * glpapi20.c - New command-line options were added to glpsol: - --glp (read problem data in GLPK format); - --wglp (write problem data in GLPK format); - --lp (replaces --cpxlp); - --wlp (replaces --wcpxlp); - --ranges (print sensitivity analysis report). - - * glpapi06.c - In the routine glp_init_smcp default value of the parameter - out_frq was changed to 500 (it was 200). - - * glpipp.h, glpipp01.c, glpipp02.c - The old MIP preprocessor module was removed. - - * glpapi09.c - Now the MIP solver uses the new MIP preprocessor (NPP). - - * glplpx03.c - lpx_write_opb was disabled due to replacing IPP with NPP. - - * glpnet09.c - Kellerman's heuristic to cover edges by cliques was added. - - * glplib08.c - Recognition of special filenames "/dev/stdin", "/dev/stdout", - and "/dev/stderr" was added. - - * glpk.tex - Chapter "Graph and network routines" was carried out from the - reference manual as a separate document. - -Mon Dec 21 12:00:00 2009 Andrew Makhorin - - * GLPK 4.41 (26:0:26) has been released - - * glpapi12.c - The following new API routines were added: - glp_transform_row (replaces lpx_transform_row); - glp_transform_col (replaces lpx_transform_col); - glp_prim_rtest (replaces lpx_prim_ratio_test); - glp_dual_rtest (replaces lpx_dual_ratio_test). - Note that values returned by glp_prim_rtest and glp_dual_rtest - differ from the ones retutned by the deprecated routines. - - * glpnpp*.* - The LP/MIP preprocessor was essentially re-implemented. - - * glpios03.c - The feature to remove inactive cuts from the active subproblem - was implemented. - - * glpios11.c - The feature processing cuts stored in the cut pool was improved - (now it uses estimation of objective degradation). - - * glpscg.* - Obsolete implemetation of the conflict graph was removed. - - * glpmpl.h, glpmpl03.c, glpmpl04.c - FILE was replaced by XFILE to allow using GLPK I/O routines. - - * glpsql.c, examples/sql, doc/tables.tex - The SQL table driver was changed to allow multiple arguments - separated by semicolon in SQL statements. Thanks to Xypron - . - - * glpk.h, glpapi14.c - New API routine glp_time was added (not documented yet). - - * glpapi20.c - Two new options were added to glpsol: --seed value (initialize - pseudo-random number generator used in MathProg model with - specified seed value), and --ini filename (use as initial basis - previously saved with -w option). - - * examples/xyacfs.mod - Thanks to Nigel Galloway for - contribution. - - * examples/dbf/*.* - Thanks to Noli Sicad for contribution. - - * w32/*.*, w64/*.* - Scripts to build GLPK with Microsoft Visual Studio 2010 were - added. Thanks to Xypron for contribution - and testing. - -Tue Nov 03 12:00:00 2009 Andrew Makhorin - - * GLPK 4.40 (25:0:25) has been released - - * glpdmx.c - Two new API routines were added: - glp_read_ccdata (read graph in DIMACS clique/coloring format); - glp_write_ccdata (write graph in DIMACS clique/coloring format). - Also an example file examples/sample.col was added. - - * glpapi19.c, glpnet08.c - New API routine glp_wclique_exact was added. It is intended to - find a maximum weight clique with the exact algorithm developed - by Prof. P. Ostergard. - - * glpnpp02.c - A bug was fixed in the LP preprocessor (routine npp_empty_col). - Thanks to Stefan Vigerske for the - bug report. - - * glpios10.c - A bug was fixed and some improvements were made in the FPUMP - heuristic module. Thanks to Xypron . - - * glpapi12.c - A bug was fixed in the API routine glp_warm_up (dual - feasibility test was incorrect in maximization case). Thanks to - Uday Venkatadri for the bug report. - - * glpapi16.c - Two new API routines were added: - glp_del_vertices (remove vertices from graph); - glp_del_arc (remove arc from graph). - - * glpios09.c - The hybrid pseudocost branching heuristic was included in the - MIP solver. It is available on API level (iocp.br_tech should - be set to GLP_BR_PCH) and in the stand-alone solver glpsol - (via the command-line option --pcost). This heuristic may be - useful on solving hard MIP instances. - - * glpios03.c - The branching heuristic by Driebeck and Tomlin (used in the - MIP solver by default) was changed to switch to branching on - most fractional variable if an lower bound of degradation of - the objective is close to zero for all branching candidates. - -Sun Jul 26 12:00:00 2009 Andrew Makhorin - - * GLPK 4.39 (24:0:24) has been released - - * glpsdf.c - New API routines to read plain data files were added. - - * glpcpx.h, glpini.h, glpscl.h - These headers were removed. - - * glpcpx.c - API routines glp_read_lp and glp_write_lp to read/write files - in CPLEX LP format were re-implemented. Now glp_write_lp - correctly writes double-bounded (ranged) rows by introducing - slack variables rather than by duplicating the rows. The data - structure glp_cpxcp and routine glp_init_cpxcp were added. - - * amd/* - The 'xfree(NULL)' bug was fixed in the AMD routines. Thanks to - Niels Klitgord for the bug report. - - * glpapi16.c - New API routines glp_set_vertex_name, glp_create_v_index, - glp_find_vertex, and glp_delete_v_index were added. - - * glpdmx.c - New API routines glp_read_asnprob, glp_write_asnprob, - glp_read_ccformat, and glp_write_ccformat were added (the two - latter routines are not documented yet). - - * glpapi18.c - New API routines glp_check_asnprob, glp_asnprob_lp, - glp_asnprob_okalg, and glp_asnprob_hall were added. - - * glpini01.c, glpini02.c - The message "Crashing..." was changed to "Constructing initial - basis..." due to suggestion by Thomas Kahle . - - * glpapi14.c - New API routines glp_printf, glp_vprintf, glp_malloc, - glp_calloc, glp_free, and glp_assert were added. - - * glplpp.h, glplpp01.c, glplpp02.c - Old LP presolver routines were removed. Now glp_simplex uses - new preprocessing routines (see glpnpp). - - * glpapi12.c - New API routine glp_warm_up was added; it replaces the routine - lpx_warm_up. - -Sat May 02 12:00:00 2009 Andrew Makhorin - - * GLPK 4.38 (23:0:23) has been released - - * glpmps.c - API routines to read/write MPS files were re-implemented. - - * glpspx02.c - Some improvements were made in the dual simplex routine. - - * glpk.h - New structure glp_iptcp was added. - - * glpnpp.h, glpnpp01.c, glpnpp02.c - New LP/MIP preprocessor. Currently it includes only some basic - routines and used only in the interior-point solver. - - * glpapi08.c - API routine glp_interior was replaced by an improved version - (new LP/MIP preprocessor, new ordering algorithms). - - New API routine glp_init_iptcp was added. - - API routine glp_ipt_status may return two new statuses due to - changes in glp_interior. - - * glpsol.c - New command-line options were added (ordering algorithm used in - the interior-point solver). - - * amd/*.*, colamd/*.* - Two external software modules AMD and COLAMD/SYMAMD used in the - interior-point solver were included in the distribution. - - For details see amd/README and colamd/README. - - * glpnet03.c, glpnet04.c, glpnet05.c - A minor bug was fixed (_G => G_). Thanks to Nelson H. F. Beebe - for bug report. - -Sun Mar 29 12:00:00 2009 Andrew Makhorin - - * GLPK 4.37 (22:0:22) has been released - - * glpk.h - iocp.fp_heur was added to enable/disable fpump heuristic. - - * glpios10.c - ios_feas_pump was added (feasibility pump heuristic). - - * glpsol.c - --fpump command-line option was added. - - * glpsds.c - Plain data set routines were added to facilitate reading plain - data in application programs. Currently these routines are not - in API, though declared in glpk.h. - - * glpapi08.c - A bug was fixed in the internal routine restore. (Due to this - bug dual solution components were computed incorrectly if the - problem was scaled.) - - * glpapi10.c, glpapi11.c - The following new API routines were added: - glp_print_sol (replaces lpx_print_sol); - glp_print_ipt (replaces lpx_print_ips); - glp_print_mip (replaces lpx_print_mip); - _glp_check_kkt (replaces lpx_check_kkt, lpx_check_int). - Now the routine lpx_print_prob (deprecated) is equivalent to - the routine glp_write_lp. - - * glpapi18.c, glpapi19.c - The following new API routines were added: - glp_read_graph (read graph from plain text file); - glp_write_graph (write graph to plain text file); - glp_weak_comp (find all weakly connected components); - glp_strong_comp (find all strongly connected components). - - * configure.ac, Makefile.am - Changes were made: (a) to allow using autoreconf/autoheader; - (b) to allow building glpk in a directory other than its source - directory. Thanks to Marco Atzeri for - bug report. - - * examples/shiftcover.mod - An example model in MathProg was added. - Thanks to Larry D'Agostino - for contribution. - -Fri Feb 06 12:00:00 2009 Andrew Makhorin - - * GLPK 4.36 (21:0:21) has been released - - * glpnet06.c, glpnet07.c, glpapi19.c - The following new API routines were added: - glp_mincost_okalg find minimum-cost flow with out-of-kilter - algorithm - glp_maxflow_ffalg find maximal flow with Ford-Fulkerson - algorithm - - * glpsol.c - Two new command-line options were added: - --mincost read min-cost flow data in DIMACS format - --maxflow read maximum flow data in DIMACS format - - * doc/glpk.* - New edition of the reference manual was included. - - * glpk.h - Duplicate symbols were removed to allow using swig. - Thanks to Kelly Westbrooks and - Nigel Galloway for suggestion. - - * glpcpx.c - A minor defect was fixed in the routine glp_write_lp. - Thanks to Sebastien Briais for bug report. - - * glpsql.c - A minor bug was fixed. Thanks to Xypron - for patch. - - * examples/hashi.mod, examples/shikaku.mod - Two example models in MathProg were added. Thanks to Sebastian - Nowozin for contribution. - - * examples/qfit.mod, examples/yacfs.mod - Two example models in MathProg were added. Thanks to Nigel - Galloway for contribution. - -Fri Jan 09 12:00:00 2009 Andrew Makhorin - - * GLPK 4.35 (20:0:20) has been released - - * glpk.h, glpapi.c, glpnet.c - The following new API routines were added: - glp_create_graph create graph - glp_set_graph_name assign (change) graph name - glp_add_vertices add new vertices to graph - glp_add_arc add new arc to graph - glp_erase_graph erase graph content - glp_delete_graph delete graph - glp_read_mincost read minimum cost flow problem data in - DIMACS format - glp_write_mincost write minimum cost flow problem data in - DIMACS format - glp_mincost_lp convert minimum cost flow problem to LP - glp_netgen Klingman's network problem generator - glp_gridgen grid-like network problem generator - glp_read_maxflow read maximum flow problem data in DIMACS - format - glp_write_maxflow write maximum flow problem data in DIMACS - format - glp_maxflow_lp convert maximum flow problem to LP - glp_rmfgen Goldfarb's maximum flow problem generator - - * doc/glpk.* - New edition of the reference manual was included. - - * examples/sample.min, examples/sample.max - Two example data files in DIMACS format were added. - - * glplib04.c - The statement "if (c = '\n') fflush(stdout)" was added to the - internal routine xputc to provide "real-time" terminal output. - Thanks to Luiz Bettoni for - suggestion. - - * glpmpl05.c - A minor bug was fixed in the internal routine mpl_fn_time2str. - Thanks to Stefan Vigerske for bug report. - - * w32/makefile, w64/makefile - The flag -O2 (/O2) was added to some makefiles. - -Thu Dec 04 12:00:00 2008 Andrew Makhorin - - * GLPK 4.34 (19:0:19) has been released - - * src/glpios03.c - A bug was fixed in the internal routine branch_on. Thanks to - Nigel Galloway for bug report. - - * src/glpmpl05.c - Three new MathProg functions were included: - gmtime obtaining current calendar time - str2time converting character string to calendar time - time2str converting calendar time to character string - Thanks to Xypron . - - * doc/glpk.*, doc/gmpl.* - A new edition of the GLPK reference manual and GNU MathProg - language description were included. - -Thu Oct 30 12:00:00 2008 Andrew Makhorin - - * GLPK 4.33 (18:0:18) has been released - - * glpapi*.* - The following new API routines were added: - glp_copy_prob copy problem object content - glp_exact solve LP in exact arithmetic - (makes lpx_exact deprecated) - glp_get_unbnd_ray determine variable causing unboundedness - (makes lpx_get_ray_info deprecated) - glp_interior solve LP with interior-point method - (makes lpx_interior deprecated) - - * glpapi*.* - The following new API routines for processing models written in - the GNU Mathprog language were added to the package: - glp_mpl_alloc_wksp allocate the translator workspace - glp_mpl_read_model read and translate model section - glp_mpl_read_data read and translate data section - glp_mpl_generate generate the model - glp_mpl_build_prob build LP/MIP instance from the model - glp_mpl_postsolve postsolve the model - glp_mpl_free_wksp deallocate the translator workspace - (These routines make lpx_read_model deprecated.) - - * src/glpapi17.c, examples/glpsol.c - The stand-alone solver glpsol was re-implemented with new API - routines. - - * src/glpsql.c - Some bugs were fixed in the SQL table driver. Thanks to Xypron - . - - * examples/cplex/*.* - A crude implementation of CPLEX-like interface to GLPK API was - added to the package. See examples/cplex/README. - -Fri Oct 03 12:00:00 2008 Andrew Makhorin - - * GLPK 4.32 (17:0:17) has been released - - * glpmpl01.c - A bug was fixed. Due to this bug iterated expressions having - an indexing expression whose dummy indices are bound to some - values, i.e. like sum{(i+1,j,k-1) in E} x[i,j,k] are evaluated - incorrectly. Namely, current value of such expressions is not - invalidated when corresponding dummy indices (like i and k in - the example above) are changed, that erroneously results in the - same value evaluated for the first time. - - * glpios03.c - Euclidean reduction of the local objective bound was added in - the routine glpios03.c. - - * glpapi11.c - The following new branch-and-cut API routines were added: - glp_ios_row_attr determine additional row attributes; - glp_ios_pool_size determine current size of the cut pool; - glp_ios_add_row add constraint to the cut pool; - glp_ios_del_row delete constraint from the cut pool; - glp_ios_clear_pool delete all constraints from the cut pool. - - * glpapi08.c - The following new features were included in the branch-and-cut - solver (the API routine glp_intopt): - MIP presolver; - mixed cover cut generator; - clique cut generator. - Due to the MIP presolver glp_intopt may additionally return - GLP_ENOPFS and GLP_ENODFS, if primal or dual infeasibility of - LP relaxation is detected by the presolver. Also the return - code GLP_EMIPGAP was introduced to correctly indicate that the - mip gap tolerance is reached. - - * glplpx01.c - Now the obsolete API routines lpx_integer and lpx_intopt are - completely superseded by the API routine glp_intopt that makes - them deprecated. - - * glpmpl05.c - Now the table driver name "iODBC" can be specified as "ODBC". - - * glpmpl03.c - A bug fixed in the routine free_dca. - Thanks to Xypron . - - * glpsql.c - A bug was fixed in the SQL table driver. - Thanks to Xypron . - - * examples/glpsol.c - Changes were made to allow multiple MathProg data files. - - * doc/glpk.* - A new edition of the GLPK reference manual was included. - - * doc/tables.* - A new edition of the supplement "Using data tables in the GNU - MathProg language" was included. - -Tue Sep 02 12:00:00 2008 Andrew Makhorin - - * GLPK 4.31 (16:0:16) has been released - - * glpspx.h, glpspx01.c, glpspx02.c, glpapi06.c - The dual simplex solver (spx_dual_opt) was replaced by a new - implementation of the two-phase dual simplex method (spx_dual). - Old simplex method routines (spx_prim_opt, spx_prim_feas, and - spx_dual_opt) were removed from the package. - - * glpk.h, glpscl.h, glpscl.c, glpapi04.c - New API routine glp_scale_prob was added. It replaces routine - lpx_scale_prob which is deprecated. - - * glpk.h, glpini.h, glpini01.c, glpini02.c, glpapi05.c - New API routines glp_std_basis, glp_adv_basis, glp_cpx_basis - were added. They replace routines lpx_std_basis, lpx_adv_basis, - lpx_cpx_basis which are deprecated. - - * glpdmp.c - 8-byte data alignment was added to the module (sufficient for - both ILP32 and LP64 environments). - - * glplib07.c - 16-byte data alignment was added to the module to provide - compatibility with LP64 environment (8-byte is not sufficient - due to jmp_buf; thanks to Xypron for investigation). - - * glplpx16.c - New version of the routine lpx_write_pb was added. Thanks to - Oscar Gustafsson for the contribution. - - * w32/VC9, w64/VC9 - Makefiles and batch files were added to build GLPK under 32- - and 64-bit Windows with Microsoft Visual Studio Express 2008. - Thanks to Heinrich Schuchardt for - the contribution and testing. - - * w32/DM, w32/OWC - Makefiles and batch files were added to build GLPK with Digital - Mars C/C++ 8.50 and Open Watcom C/C++ 1.6 (32-bit Windows). - -Wed Aug 13 12:00:00 2008 Andrew Makhorin - - * GLPK 4.30 (15:0:15) has been released - - * glpspx.h, glpspx03.c, glpapi06.c - The primal simplex solver (spx_prim_opt, spx_prim_feas) was - replaced by a new implementation (spx_primal), which currently - provides the same features as the old version. - - * glpmpl01.c, glpmpl03.c - Some changes were made in the MathProg translator to allow <, - <=, >=, and > on comparing symbolic values. Thanks to Heinrich - Schuchardt for patches. - - * glplpx10.c - Internal routine set_d_eps in the exact LP solver was changed - to prevent approximation errors in case of integral data. - Thanks to Markus Pilz for bug report. - -XXX XXX XX 12:00:00 2008 Andrew Makhorin - - * GLPK 4.29 (14:0:14) has been released - - * configure.ac - The configure script was changed to disable optional features - by default. For details see file INSTALL. - - * glpipp02.c - A bug was fixed in the internal routine reduce_bounds. Thanks - to Anne-Laurence Putz for - the bug report. - - * glpapi01.c - New API routine glp_erase_prob was added. - - * glpapi13.c - New API routines glp_read_mps and glp_write_mps were added. - They replace API routines lpx_read_mps, lpx_read_freemps, - lpx_write_mps, and lpx_write_freemps, which are deprecated. - - * glpapi14.c - New API routines glp_read_lp and glp_write_lp were added. They - replace API routines lpx_read_cpxlp and lpx_write_cpxlp, which - are deprecated. - - * glpsql.c - Minor bug was fixed. Thanks to Xypron for - the bug report. - -Tue Mar 25 12:00:00 2008 Andrew Makhorin - - * GLPK 4.28 (13:0:13) has been released - - * glplib.h, glplib.c - Three wrapper routines xdlopen, xdlsym, and xdlclose, which - provide the shared library support, were added. A particular - version of these routines depends on the option --enable-dl - passed to the configure script (see file INSTALL for details). - Thanks to Rafael Laboissiere for useful - advices concerning the shared library support. - - * glpsql.c - A static linking to iODBC and MySQL libraries used in the - MathProg table drivers was replaced by a dynamic linking to - corresponding shared libraries. - Many thanks to Heinrich Schuchardt - for the contribution and to Vijay Patil - for testing this feature under Windows XP. - - * glpgmp.h, glpgmp.c - A bug (which appeared only on 64-bit platforms) was fixed. - Thanks to Axel Simon for the bug report. - - * glpapi.c - A bug was fixed in the api routine glp_add_cols. (If the basis - is valid, adding column keeps it valid, however, col->bind was - set to -1 rather to 0.) - Thanks to Cedric[FR] for the bug report. - - * glplib.c - 64-bit unsigned int type glp_ulong and corresponding routines - were replaced by 64-bit signed int type xlong_t. - - * glpk.h, glpapi.c - The type glp_ulong was replaced by glp_long. This affects only - the api routine glp_mem_usage. - - * glplib.c - Compressed data file support was added. This feature requires - the zlib data compression libraries and allows compressing and - decompressing .gz files "on the fly". - - * glpcli.h, glpcli.c - Command-line interface routines were added. (This feature is - incomplete so far.) - -Sun Mar 02 12:00:00 2008 Andrew Makhorin - - * GLPK 4.27 (12:0:12) has been released - - * glpsql.h, glpsql.c - Two MathProg table drivers for iODBC and MySQL contributed by - Heinrich Schuchardt were added to - the package. - - * glpmpl05.c - Mathprog table driver for xBASE was added to the package. - - * glpmpl03.c - A minor was fixed in the MathProg translator (if some field - specified in the table statement is missing in corresponding - input table, the bug causes abnormal termination). Thanks to - Heinrich Schuchardt for the bug - report. - - * glpmpl.h, glpmpl.c - STRING data type was replaced by plain character strings. - -Sun Feb 17 12:00:00 2008 Andrew Makhorin - - * GLPK 4.26 (11:0:11) has been released - - * glpmpl.h, glpmpl01.c, glpmpl03.c, glpmpl05.c - The table statement was implemented. Description of this new - feature is given in file doc/tables.txt. - - * glpios03.c - A bug causing zero divide error on computing euclidean norm of - the cut coefficient vector was fixed. - -Wed Dec 19 12:00:00 2007 Andrew Makhorin - - * GLPK 4.25 (10:0:10) has been released - - * glpapi10.c - Routines lpx_eval_tab_row and lpx_eval_tab_col were replaced by - glp_eval_tab_row and glp_eval_tab_col. - - * glpios03.c, glpios05.c - Gomory's mixed integer cuts were implemented. - - * glpscs.h, glpscs.c - Segmented character string routines are no longer used and were - removed from the package. - -Wed Nov 21 12:00:00 2007 Andrew Makhorin - - * GLPK 4.24 (9:0:9) has been released - - * src/glplpx16.c - A bug was fixed in the routine lpx_write_cpxlp. If a variable - x has upper bound and no lower bound, it should appear in the - bounds section as "-inf <= x <= u", not as "x <= u". Thanks to - Enric Rodriguez for the bug report. - - * src/glpios03.c, src/glpios04.c, src/glpios05.c - MIR (mixed integer rounding) cuts were implemented. - -Sun Oct 28 12:00:00 2007 Andrew Makhorin - - * GLPK 4.23 (8:0:8) has been released - - * src/glplib05.c, configure.ac - Check for vsnprintf was added. - - * include/glppds.h, src/glppds.c - A module to scan plain data was added. - - * src/glpapi09.c - The following new API routines were added: - glp_read_sol read basic solution from text file; - glp_write_sol write basic solution to text file; - glp_read_ipt read interior-point solution from text file; - glp_write_ipt write interior-point solution to text file; - glp_read_mip read MIP solution from text file; - glp_write_mip write MIP solution to text file. - - * src/glpapi12.c - Advanced API routine glp_free_env was added. - - * examples/glpsol.c - The following three command-line options were added: - --mipgap tol set relative MIP gap tolerance - -r filename read solution from filename - -w filename write solution to filename - -Wed Sep 19 12:00:00 2007 Andrew Makhorin - - * GLPK 4.22 (7:0:7) has been released - - * src/glpios02.c - A bug was fixed in the MIP preprocessor (ios_preprocess_node). - Thanks to Roberto Bagnara (Department of - Mathematics, University of Parma, Italy) for the bug report. - - * src/glpios02.c - A bug was fixed in the MIP preprocessor (col_implied_bounds), - due to which constraint coefficients with small magnitude could - lead to wrong implied bounds of structural variables. - - * src/glpipp02.c - A similar bug was fixed in the routine reduce_bounds. - - * src/glpapi01.c - A bug was fixed in the routines glp_set_mat_row and - glp_set_mat_col. (The bug appeared due to incorrect removing - zero elements from the row/column lists.) - - * src/glplpx14.c - A bug was fixed in the API routines lpx_read_mps and - lpx_read_freemps, due to which bounds of type LI specified in - BOUNDS section were incorrectly processed. - - * src/glplib05.c - A call to standard function vsprintf was replaced by a call to - vsnprintf for security reasons. Many thanks to Peter T. Breuer - and Rafael Laboissiere . - -Tue Aug 28 12:00:00 2007 Andrew Makhorin - - * GLPK 4.21 (6:0:6) has been released - - * glpscg.h, glpscg.c - Routines to maintain sparse cliqued graph were added. - - * glpios02.c - MIP preprocessing routines were added. - - * glpk.h, glpios.h, glpios03.c - New reasons for calling the callback routine were introduced - in the MIP solver. - - * glpapi08.c - Default backtracking strategy was changed to best local bound. - - * glpapi11.c - New API routine glp_term_out to enable/disable terminal output - was added. - - * glprng.h, glprng02.c - Two routines to generate uniformly distributed pseudo-random - floating-point numbers were added. - -Thu Jul 26 12:00:00 2007 Andrew Makhorin - - * GLPK 4.20 (5:0:5) has been released - - * glpk.h, glpapi08.c - The routine lpx_integer was replaced by an equivalent routine - glp_intopt. Also new API routine glp_init_iocp was added. - - * glpiet.h, glpiet.c - Routines implementing the implicit enumeration tree are - no longer used and therefore were removed from the package. - - * glpios.h, glpios01.c, glpios02, glpios03 - Routines implementing the integer optimization suite being - replaced by a new version were removed from the package. - - * glpmip.h, glpmip01.c, glpmip02.c - - Routines implementing the B&B method being replaced by a new - version were removed from the package. - - * glpios.h, glpios01.c, glpios02.c - - Routines implementing a new version of the integer optimization - suite (IOS) based on the B&B method were added to the package. - - * glpk.h, glpapi10.c - Branch-and-bound interface routines were added to the package. - - * examples/tspsol.c - The TSP solver based on old version of the integer optimization - suite is no more supported and was removed from the package. - - * glpipp02.c - An error in the routine reduce_bounds was fixed; thanks to - Graham Rockwell for the bug report. - - * glpk.latex - A new edition of the reference manual was included. - -Thu Jul 05 12:00:00 2007 Andrew Makhorin - - * GLPK 4.19 (4:0:4) has been released - - The principal change is upgrading to GPLv3. - - * glpapi01.c - A serious bug in the routine glp_del_cols was fixed; thanks to - Cedric[FR] for the bug report. The bug - appeared because on deleting non-basic columns the basis header - remained valid, however, contained invalid (old) column ordinal - numbers. - - * glpapi10.c - A new advanced API routine glp_mem_limit was added. - - * glplpx01.c - The case GLP_EBOUND was added to the routine lpx_simplex. - Thanks to Cameron Kellough for the - bug report. - - * glplpx19.c - An API routine lpx_write_pb to write the problem instance in - OPB (pseudo boolean) format format was added. Thanks to Oscar - Gustafsson for the contribution. - - * glpsol.c - Two new options --wpb and --wnpb were added to glpsol to write - the problem instance in OPB format. - -Mon Jun 25 12:00:00 2007 Andrew Makhorin - - * GLPK 4.18 (3:0:3) has been released - - * glplib.h - Type names ulong_t and uldiv_t were changed to glp_ulong and - glp_uldiv to avoid conflicts with standard type names on some - platforms. Thanks to Boris Wirtz - for the bug report. - - * glpbfd.*, glpfhv.*, glplpf.* - LP basis factorization routines were made tidy. - - * glpk.h, glpapi04.c - The following API routines were added: - glp_set_rii, glp_set_sjj, glp_get_rii, glp_get_sjj. - - * glpk.h, glpapi06.c - The routine lpx_simplex was replaced by an equivalent routine - glp_simplex. Also new API routine glp_init_smcp was added. - - * glpk.h, glpapi09.c - The following advanced API routines were added: - glp_bf_exists, glp_factorize, glp_bf_updated, glp_get_bfcp, - glp_set_bfcp, glp_get_bhead, glp_get_row_bind, glp_get_col_bind, - glp_ftran, glp_btran. - - * glpk.latex - A new edition of the reference manual was included. - - * examples/dea.mod, examples/food.mod, examples/food2.mod - Three examples in the MathProg language were added. - Thanks to Sebastian Nowozin . - -Sat May 26 12:00:00 2007 Andrew Makhorin - - * GLPK 4.17 (2:0:2) has been released - - * glpdmp.h, glpdmp.c - Memory pool routines were replaced by a new version. - - * glpscs.h, glpscs.c - Segmented string routines were replaced by a new version. - - * glplpx08.c, glplpx09.c - Now the MIP problem may have no integer columns. - - * glpapi01.c - The routines glp_set_mat_row, glp_set_mat_col, and glp_load_mat - were modified to allow zero elements (which are not stored in - the constraint matrix). - - * glpscf.h, glpscf.c - Schur complement factorization routines were implemented. - - * glplpf.h, glplpf.c - LP basis factorization routines based on LU-factorization and - Schur complement were implemented. - - * glplpx02.c, glplpx03.c - New control parameter LPX_K_BFTYPE was introduced to choose the - basis factorization type used by the simplex method routines. - - * glpsol.c - Three new command-line options were added to choose the basis - factorization type used by the simplex method routines: --luf, - --cbg, and --cgr. - - * glpk.latex - A new edition of the reference manual was included. - -Sat May 05 12:00:00 2007 Andrew Makhorin - - * GLPK 4.16 (1:0:1) has been released - - * glpk.h, glpapi.c, glplpx01.c, glplpx02.c - Names of a number basic api routines were changed and now have - the prefix 'glp_'. To keep backward compatibility these routines - are also available via their old names prefixed with 'lpx_'. - - * glplpx19.c - Three new api routines were added: glp_version, glp_term_hook, - and glp_mem_usage. - - * glpk.latex, gmpl.texi - A new edition of the reference manuals was included. - - * lpglpk40.c - This example program is no longer supported and therefore was - removed from the package. - -Sun Feb 18 12:00:00 2007 Andrew Makhorin - - * GLPK 4.15 (0:0:0) has been released - - * configure.ac, Makefile.am - Autotools specification files were changed to use GNU Libtool - that allows building the static as well as shared GLPK library. - Thanks to Rafael Laboissiere . - -Mon Feb 05 08:00:00 2007 Andrew Makhorin - - * GLPK 4.14 has been released - Now GLPK conforms to ILP32, LLP64, and LP64 programming models - (the latter seems to be the ultimate choice regarding 64-bit - architectures). Note that GLPK itself is a 32-bit application, - and the conformity only means that the package works correctly - on all these arenae. Nevertheless, on 64-bit platforms it is - possible to use more than 4GB of memory, if necessary. - - * Makefile - Starting from this release only the header glpk.h is needed to - be installed. - - * glplib01.c - Two routines bigmul and bigdiv which performs multiplication - and division of unsigned integers of arbitrary precision were - added. - - * glplib02.c - A set of 64-bit arithmetic routines were added. - - * glplib04.c - Some low-level library routines were improved and renamed. - - * glpcfg.h - The macro GLP_TM_SPEC were introduced to specify a version of - the time routine depending on the host environment. - -Mon Nov 13 12:00:00 2006 Andrew Makhorin - - * GLPK 4.13 has been released - - * configure.in - '-lm' bug was fixed. - - * glpbfx.h, glpbfx.c - Basis factorization interface routines based on exact (bignum) - arithmetic were implemented. - - * glpssx.h, glpssx1.c, glpssx2.c - Simplex method routines based on exact (bignum) arithmetic were - implemented. - - * glplpx6e.c - The routine lpx_exact, which is an easy-to-use driver to the - exact simplex method, was added. - - * glpsol.c - Two command-line options were added: '--exact' and '--xcheck'. - -Wed Nov 08 12:00:00 2006 Andrew Makhorin - - * GLPK 4.12 has been released - - * glpcfg.h - The package configuration file was added. - - * glplib2.c - Alternative version of the routines umalloc, ucalloc, and ufree - was provided. It does not limit the amount of allocated memory - to INT_MAX bytes and therefore can be used on platforms where - sizeof(void *) > sizeof(int). To enable this version one should - define the preprocessor variable GLP_HUGE_MEM. - - * glprng.c - The routine rng_create_rand was changed to initialize the - generator using seed = 1, not 0, to conform ISO C requirements. - - * glpgmp.h, glpgmp.c - A set of bignum arithmetic routines implementing operations on - integers and rationals was added. These routines are compatible - with the GNU MP library. - - NOTE: To attain a much better performance it is recommended to - use, if possible, the original GNU MP library rather than the - GLPK version, by defining the preprocessor variable GLP_USE_GMP. - - * glplux.h, glplux.c - A tentative implementation of sparse LU-factorization based on - exact (bignum) arithmetic was added. - - * glpssx.h, glpssx.c - A tentative implementation of some simplex method routines based - on exact (bignum) arithmetic was added. - - * glplpx6f.c - A preliminary implementation of the routine lpx_exact_check was - added. This routine checks the current basis for primal and dual - feasibility using exact (bignum) arithmetic. - - * examples/glpsol.c - The command-line option '--xcheck' was introduced to check the - current basis for feasibility using exact (bignum) arithmetic. - -Tue Jul 25 12:00:00 2006 Andrew Makhorin - - * GLPK 4.11 has been released. - - * include/glpbfi.h, src/glpbfi.c - Basis factorization interface routines were added. - - * include/glpluf.h, src/glpluf1.c - Hypersparse solution routines were added. - - * include/glpinv.h, src/glpinv1.c - Hypersparse solution routines (fake version) were added. - - * include/glpmpl.h, src/glpmpl.c - Built-in functions card, length, and substr were implemented. - Output redirection in the printf statement was implemented. - - * examples/graph.mod, examples/crypto.mod - Two example models illustrating new features of the modeling - language were included. - -Thu May 11 12:00:00 2006 Andrew Makhorin - - * GLPK 4.10 has been released. - - * src/glplpx8a.c - A fragment was added to the routines lpx_read_mps and - lpx_read_freemps to accept LI bound type (it is similar to LO, - however, additionally marks the column as integer). - - * include/glpbfi.h, src/glpbfi.c - The module glpbfi which implements the basis factorization - interface (BFI) was added. - - * src/glplpx7a.c - The routine lpx_cover_cut to generate mixed cover cuts was - added. - - * src/glplpx7b.c - The routine lpx_clique_cut to generate clique cuts and related - routines to maintain the conflict graph were added. - - * include/glplpx.h, src/glplpx5.c - The routine lpx_cpx_basis implementing Bixby's algorithm to - construct an initial LP basis was added. - - * examples/glpsol.c - Command-line option '--bib' was added which allows building - an initial LP basis using Bixby's algorithm. - Default command-line option '--mps' was changed to '--freemps'. - - * examples/cf12a.mod, examples/cf12b.mod - Two examples in MathProg (curve fitting problem) were added. - Thanks to Dr. Harley Mackenzie . - -Tue Jan 17 12:00:00 2006 Andrew Makhorin - - * GLPK 4.9 has been released. - - * glpipp.h, glpipp1.c, glpipp2.c - A MIP presolver were implemented (currently incomplete). It is - used internally in the routine lpx_intopt (see below). - - * glplpx6d.c, glplpx7a.c - An advanced branch-and-bound solver (the routine lpx_intopt) - were implemented. - - * glplpx6c.c - The routine lpx_check_int to check MIP feasibility conditions - was added. - - * glplpx8a.c - The routine lpx_print_mip was changed to print MIP feasibility - conditions. - - * glpmpl.h, glpmpl1.c, glpmpl3.c - The built-in functions sin, cos, atan, and atan2 were added to - the MathProg language. - - * doc/lang.* - Some typos were fixed. - Thanks to Minh Ha Duong (CIRED, CNRS). - -Wed Jan 12 12:00:00 2005 Andrew Makhorin - - * GLPK 4.8 has been released. - - * glpspx.h, glpspx1.c, glpspx2.c, glplpx6a.c - Simplex method routines were changed due to a new format of the - constraint matrix. - - * glpmat.h, glpmat.c - Sparse matrix routines were re-implemented using storage-by-rows - format. - - * glpipm.h, glpipm.c, glplpx6b.c - Interior-point method routines were changed due to a new format - of sparse matrices. - - * glpchol.h, glpchol.c - Old version of Cholesky factorization routines being replaced by - a new one (see glpmat.c) was removed from the package. - - * glplpx8c.c - Minor bug was fixed in api routine lpx_read_cpxlp. - -Mon Aug 23 12:00:00 2004 Andrew Makhorin - - * GLPK 4.7 has been released. - - * glplpx.h, glplpx1.c - New core API routines were added (but not documented yet): - lpx_order_matrix, lpx_create_index, lpx_find_row, lpx_find_col, - lpx_delete_index. - - * glplpx8a.c - API routine lpx_read_mps was re-implemented, and two new API - routines lpx_read_freemps and lpx_write_freemps were added to - support free MPS format. - - * glplpx8c.c - Two API routines lpx_read_cpxlp and lpx_write_cpxlp (formerly - named lpx_read_lpt and lpx_write_lpt) were re-implemented. - - * glpmps.h, glpmps.c - This module formerly used in lpx_read_mps was removed from the - package. - - * glplpt.h, glplpt.c - This module formerly used in lpx_read_lpt was removed from the - package. - - * glpmip.h, glpmip1.h, glpmip2.h - New MIP routines mip_best_node and mip_relative_gap were added - due to suggestion of Brady Hunsaker . - - * glpsol.c - The following new command-options were added: - --freemps to read problem data in free MPS format - --wfreemps to write problem data in free MPS format - --cpxlp to read problem data in CPLEX LP format - --wcpxlp to write problem data in CPLEX LP format - --bas to read LP basis from a text file in MPS format - --wbas to write LP basis to a text file in MPS format - --mostf to use "most fractional" branching heuristic - --bestb to use "best bound" backtracking heuristic - - * contrib/deli/*.* - GLPK Delphi interface module was temporarily removed from the - distribution due to licensing problems. - - * contrib/glpkmex/*.* - GLPK Matlab interface module was temporarily removed from the - distribution due to licensing problems. - - * contrib/jni/*.* - GLPK Java interface module was temporarily removed from the - distribution due to licensing problems. - -Wed Aug 04 12:00:00 2004 Andrew Makhorin - - * GLPK 4.6 has been released. - - * glpmpl.h, glpmpl1.c, glpmpl2.c, glpmpl3.c, glpmpl4.c - Three new statements were implemented in the GNU MathProg - language: solve, printf, and for. Also some bugs were fixed. - - * glplpx.h, glplpx8e.c - Two API routines were added: lpx_read_prob and lpx_write_prob, - which allow reading and writing problem data in GNU LP format. - - * glpsol.c - Three new command-line options were added: --glp (to read - problem data in GNU LP format), --wglp (to write problem data - in GNU LP format), and --name (to change problem name). - - * glprng.h, glprng.c - A portable pseudo-random number generator was implemented as a - separate module. - - * glplib4.c - The old implementation of a pseudo-random number generator was - removed from the package. - - * doc/lang.*, doc/refman.* - New edition of the GLPK documentation was included. - - * contrib/glpkmex/*.* - A new version of GLPKMEX was included in the distribution. For - more details see contrib/glpkmex/ChangeLog. - -Mon Jul 19 12:00:00 2004 Andrew Makhorin - - * GLPK 4.5 has been released. - - * glpmip.h, glpmip1.c, glpmip2.c, glplpx6c.c - New implementation of the branch-and-bound method was added. - It replaces the old implementation, which was removed from the - package. - - * glpies.h, glpies1.c, glpies2.c, glpies3.c - Modules used in the old implementation of the branch-and-bound - method were removed from the package. - - * glplib2.c - Now if the preprocessor variable GLPHUGEMEM is defined, other - version of the routines umalloc, ucalloc, and ufree is used on - compiling the package. This allows avoiding memory allocation - problems on platforms where sizeof(void *) > sizeof(int), for - example, where addresses are 64-bit while integers are 32-bit. - The modification was made due to a bug report provided by Karel - Zimmermann and Christophe Caron - . - -Sat Jan 17 12:00:00 2004 Andrew Makhorin - - * GLPK 4.4 has been released. - - * glplpx.h, glplpx*.c - All API routines were re-implemented using new data structures. - Some new API routines were added and some existing API routines - became obsolete as shown below: - - Obsolete API routine Equivalent new API routine - lpx_check_name (no more supported) - lpx_set_obj_c0 lpx_set_obj_coef - lpx_set_row_coef (no more supported) - lpx_set_col_coef lpx_set_obj_coef - lpx_load_mat (no more supported) - lpx_load_mat3 lpx_load_matrix - lpx_unmark_all (no more supported) - lpx_mark_row (no more supported) - lpx_mark_col (no more supported) - lpx_clear_mat (no more supported) - lpx_del_items lpx_del_rows, lpx_del_cols - lpx_get_row_bnds lpx_get_row_type, lpx_get_row_lb, - lpx_get_row_ub - lpx_get_col_bnds lpx_get_col_type, lpx_get_col_lb, - lpx_get_col_ub - lpx_get_obj_c0 lpx_get_obj_coef - lpx_get_row_coef (no more supported) - lpx_get_col_coef lpx_get_obj_coef - lpx_get_row_mark (no more supported) - lpx_get_col_mark (no more supported) - lpx_get_row_info lpx_get_row_stat, lpx_get_row_prim, - lpx_get_row_dual - lpx_get_col_info lpx_get_col_stat, lpx_get_col_prim, - lpx_get_col_dual - lpx_get_ips_stat lpx_ipt_status - lpx_get_ips_row lpx_ipt_row_prim, lpx_ipt_row_dual - lpx_get_ips_col lpx_ipt_col_prim, lpx_ipt_col_dual - lpx_get_ips_obj lpx_ipt_obj_val - lpx_get_mip_stat lpx_mip_status - lpx_get_mip_row lpx_mip_row_val - lpx_get_mip_col lpx_mip_col_val - lpx_get_mip_obj lpx_mip_obj_val - - Obsolete API routines were kept for backward compatibility, - however, they will be removed in the future. - - * doc/refman.* - New edition of the GLPK reference manual containing description - of all new API routines was included. - - * contrib/glpkmex/*.* - GLPKMEX, a Matlab MEX interface to GLPK package, contributed by - Nicolo Giorgetti was included. - - * doc/GLPK_FAQ.txt - GLPK FAQ contributed by Harley Mackenzie was - included. - -Fri Dec 12 12:00:00 2003 Andrew Makhorin - - * GLPK 4.3 has been released. - - * configure.in - The bug, due to which the standard math library is not linked on - some platforms, was fixed. - - * glpmpl3.c - The bug (0 ** y) was fixed in the routine fp_power. - - * glpmpl.h, glpmpl1.c, glpmpl3.c - Some new built-in functions (round, trunc, Irand224, Uniform01, - Uniform, Normal01, Normal) were added to the MathProg language. - - * glpmpl1.c - The MathProg syntax was changed to allow writing 'subj to'. - - * glplpx.h, glplpx1.c, glplpx2.c - The new api routine lpx_get_ray_info was added. - - * glplpx8a.c - The api routine lpx_print_sol was changed to print the number of - non-basic variable, which causes primal unboundness. - - * glpmps.c - The code was changed to avoid errors on compiling the package on - Mac OS X. Thanks to Andre Girard for - the bug report. - - * doc/lang.*, doc/refman.* - Several typos were fixed and some new material was added in the - glpk documentation. - -Fri Nov 14 12:00:00 2003 Andrew Makhorin - - * GLPK 4.2 has been released. - - * glpiet.h, glpiet.c, glpios.h, glpios1.c, glpios2.c, glpios3.c - A preliminary implementation of the Integer Optimization Suite - (IOS) was included in the package. Eventually IOS will replace - the Implicit Enumeration Suite (IES). - - * glplpx.h, glplpx6d.c - A dummy version of the integer optimization routine lpx_intopt - was included in the package. Later this routine will replace the - routine lpx_integer. - - * examples/glpsol.c - A new command-line option --int-opt was added to the solver to - call lpx_intopt rather than lpx_integer. - - * glpbcs.h, glpbcs1.c, glpbcs2.c - Being replaced by IOS routines (see above) the Branch-and-Cut - Framework (BCS) routines were removed from the package. - - * examples/tspsol.c - Stand-alone Symmetric TSP solver was completely re-programmed - using IOS routines. - - * glplib.h, glplib2.c, glplib4.c - The random-number generator was implemented. It is based on the - module GB_FLIB from the Stanford GraphBase originally developed - by Donald Knuth. - - * glphbsm.c, glplpx8a.c, glpmps.c - All calls to fopen/fclose were replaced by corresponding calls - to ufopen/ufclose due to bug reports provided by Morten Welinder - and . - - * glpmps.c - The code was made re-entrant. - - * glplpx8b.c - API routine lpx_print_sens_bnds for bounds sensitivity analysis - contributed by Brady Hunsaker was added - to the package. This feature is also available in glpsol via the - command-line option --bounds. - - * contrib/jni/*.* - New version of GLPK JNI (Java Native Interface) contributed by - Chris Rosebrugh was added to the package. - - * contrib/deli/*.* - GLPK DELI (Delphi Interface) contributed by Ivo van Baren - was added to the package. - - * glplpx3.c - Default method to scale the problem was changed to equilibration - scaling (lp->scale = 1 in lpx_reset_parms). - - * glplpx6a.c - Two minor (non-critical) typos were fixed due to report provided - by Andrew Hamilton-Wright . - - * glplpp2.c - An untested case (line 941) had been tested due to bug report - provided by Jiri Spitz . - - * w32bc5.mak, w32vc6.mak, w32vc6d.mak, d32dmc.mak - Several makefiles were added to allow building GLPK library for - some non-GNU 32-bit platforms. - -Sat Aug 23 12:00:00 2003 Andrew Makhorin - - * GLPK 4.1 has been released. - - * glpmpl1.c, glpmpl3.c - Some bugs were fixed in the MathProg translator due to the bug - reports provided by Giles Thompson : - conditional set expressions were incorrectly parsed; - dimen attribute was not set by default when a set was used - recursively in its own declaration; - logical expressions ... in if ... then ... else ... did not - work; - displaying set expressions did not free memory allocated for - temporary results. - - * glpmpl3.c (reduce_terms) - Implementation of summation of linear forms over domain was - improved to reduce complexity of that operation from O(n*n) to - O(n*log n). The improvement was made due to a report provided - by Sebastien de Menten . - - * glplpx6a.c (line 1056), glpmip1.c (line 641) - Two minor bugs were fixed due to the bug report provided by - Kendall Demaree . - - * glplpx.h, glplpx6a.c - The method of one artificial variable implemented in the routine - lpx_prim_art and used on the phase I in the glpk simplex solver - has a serious defect: for some lp instances it erroneously - reports that the problem has no primal feasible solution. This - error appears when the column of the artificial variable, which - enters the basis to make it primal feasible, has large - constraint coefficients, that leads to small reduced costs of - non-basic variables and premature termination of the search, - i.e. to wrong conclusion that the problem has no primal feasible - solution. To avoid this defect the routine lpx_prim_feas was - included. It implements the method of implicit artifical - variables (based on minimization of the sum of infeasibilities), - which is a bit slower but much more robust. The routine - lpx_prim_feas having the same functionality now is used instead - the routine lpx_prim_art. - - * glpinv.h, glpinv.c - The test used in the routine inv_update to detect low accuracy - after updating LU-factorization of the basis matrix was replaced - by a new, more robust test. - - * glplpx6c.c - Selecting an active node to be solved next in the routine - btrack_bestp was changed. Now, if any integer feasible solution - has not been found yet, the routine chooses an active node which - has the minimal sum of integer infeasibilities. - - * glpmip.h, glpmip1.c - The additional flag int_obj was included in the structure - MIPTREE used by the branch-and-bound. This flag is set in the - routine mip_create_tree and used in the routine is_better. It - means that the objective is integral, i.e. depends only on - integer variables with integer objective coefficients. The test - used in the routine check_integrality was also replaced by a - new, more reasonable one. - - * glplpx1.c - A minor bug was fixed in the routine lpx_check_name. - - * glpmpl.h, glpmpl4.c, glplpx8d.c - The flag skip_data was added to the parameter list of the - routine mpl_read_model. If this flag is set, the data section - in the model file is ignored. Corresponding change was made in - the routine lpx_read_model. Now, if both model and data files - are specified, the data section in the model file is ignored. - - * glplpx8c.c - A minor bug (wrong format used for writing free columns) in the - routine lpx_write_lpt was fixed due to the bug report provided - by Bernhard Schmidt - - * sample/glpsol.c - The command-line parameter --tmlim, which allows limiting the - solution time, was added. - - * doc/lang.*, doc/refman.* - New edition of the GLPK documentation was included. - - * java-binding/*.* - New version of the GLPK JNI (Java Native Interface) package was - included in the distribution. - - * sample/lpglpk40.c - A non-trivial example was added. It allows using GLPK as a base - LP solver for Concorde, a program for solving Traveling Salesman - Problem (TSP). For details see comments in lpglpk40.c. - - * sample/*.mod - Some examples of LP and MIP models written in GNU MathProg were - added. - -Tue May 06 12:00:00 2003 Andrew Makhorin - - * GLPK 4.0 has been released. - - * glpmpl.h, glpmpl1.c, glpmpl2.c, glpmpl3.c, glpmpl4.c - The model translator for the GNU MathProg modeling language was - implemented and included in the package. - - * glplpx.h, glplpx8d.c - The api routine lpx_read_model, which is an interface to the - MathProg translator, was included in the package. - - * glplpx.h, glplpx8a.c - The api routine lpx_print_prob for writing LP/MIP problem data - in plain text format was included in the package. - - * sample/glpsol.c - New version of the GLPK stand-alone LP/MIP solver that supports - the GNU MathProg modeling language was implemented. - - * doc/lang.latex, doc/lang.dvi, doc/lang.ps - The document "GLPK: Modeling Language GNU MathProg" was included - in the package. - - * doc/refman.latex, doc/refman.dvi, doc/refman.ps - New edition of the GLPK Reference Manual was included in the - package. - - * glplpx8c.c - A bug in the api routine lpx_write_lpt was fixed. Due to that - bug an addressing error occured in the routine if the objective - function has the non-zero constant term. - - * glplan.h, glplan1.c, glplan2.c, glplan3.c, glplan4.c, - * glplan5.c, glplan6.c, glplan7.c, glplan8.c, glplpx8b.c - All modules of the translator for the GLPK/L modeling language - were removed from the package, because GLPK/L being completely - superseded by GNU MathProg is no more supported. - -Tue Mar 25 12:00:00 2003 Andrew Makhorin - - * GLPK 3.3 has been released. - - * glplpp.h, glplpp1.c, glplpp2.c - An implementation of the built-in LP presolver was added to the - package. - - * glplpx.h - The flag presol was added to the structure LPX. This flag tells - the lpx_simplex whether the built-in LP presolver should be used - or not. By default this flag is off. Also three macros (namely - LPX_E_NOPFS, LPX_E_NODFS, and LPX_K_PRESOL) that concern using - the LP presolver were introduced. - - * glplpx3.c, glplpx6a.c - These modules was changed to use the built-in LP presolver. - - * sample/glpsol.c - Command line options --presol and --nopresol that concern using - the LP presolver were added to the stand-alone LP/MIP solver. - - * glplan1.c - This module was changed to allow declaring sets like A[1:10] in - the models written in the GLPK/L modeling language. - - * doc/refman.latex, doc/lang.latex - New editions of the documents "GLPK User's Guide" and "GLPK/L - Modeling Language" were included in the distribution. - - * java-binding/*.* - The package GLPK JNI (Java Native Interface) implementing Java - binding for GLPK was included in the distribution. This package - was developed and programmed by Yuri Victorovich . - -Tue Feb 18 12:00:00 2003 Andrew Makhorin - - * GLPK 3.2.4 has been released. - - * glplpx6b.c - The code was changed to allow auxiliary variables have non-zero - objective coefficients. - - Also a minor bug was fixed (the constant term was not considered - on displaying the objective function value). - - * sample/glpsol.c - The code was changed to fix a bug (the command-line option 'bfs' - was not recognized). The bug was fixed due to report provided by - Olivier . - - * glplpt.c - The code was changed to fix a bug (binary variables were treated - erroneously as integer ones). - - * glplpx6b.c - The code was changed to fix a bug (variables that have no lower - bounds were incorrectly processed on converting to the standard - formulation). The bug was fixed due to report kindly provided by - Kjell Eikland . - -Mon Nov 11 12:00:00 2002 Andrew Makhorin - - * GLPK 3.2.3 has been released. - - * glpmip.h, glpmip1.c - A preliminary implementation of the branch-and-bound driver - based on the implicit enumeration suite (glpies) was added to - the package. This module is not documented yet. - - * glplpx6c.c - A new implementation of the api routine lpx_integer which now - is based on the b&b driver (see glpmip above) was included in - the package. This new implementation has exactly the same - functionality as the old version and therefore all changes are - transparent to the api user. - - * glpbbm.h, glpbbm.c - * glprsm.h, glprsm1.c, glprsm2.c - * glplp.h, glplp.c - These modules were removed from the package, because they were - used only in the old version of the routine lpx_integer, which - was replaced by the new version (see glplpx6c above). - - * glplpx.h, glplpx6a.c - The api routine lpx_check_kkt was included in the package and - its description was added in the reference manual. This routine - allows checking Karush-Kuhn-Tucker optimality conditions for an - LP solution. - - * glplpx.h, glplpx8a.c - Now the api routine lpx_print_sol also prints information about - "solution quality" obtained via the api routine lpx_check_kkt. - - * glplpx.h, glplpx8a.c - New api routines lpx_read_bas and lpx_write_bas were included - in the package and documented. The routine lpx_write_bas allows - writing a current basis from an LP object to a text file in the - MPS format. The routine lpx_read_bas allows reading a basis - prepared in the MPS format from a text file into an LP object. - - * glplpt.c - The parsing routine which reads LP problem data prepared in the - CPLEX LP format was modified to allow specifying lower bounds - of variables also in the form 'variable >= lower bound' (in the - bounds section). This modification was made due to a notice - provided by Ivan Luzzi . - - * glplpx.h, glplpx8c.c - The api routine lpx_write_lpt which allows writing LP problem - data from an LP object to a text file using the CPLEX LP format - was included in the package and documented. - - * glplpx.h, glplpx3.c - The control parameter LPX_K_LPTORIG that affects the behavior - of the api routine lpx_write_lpt was introduced. - - * glplan6.c - The semantics of the language GLPK/L was changed to allow - selection in case when not all mute letters of a predicate (the - operand that follows the keyword 'where') are presented in a - parameter (the operand that precedes the keyword 'where'), i.e. - to allow writing something like this: - y[j] := sum(i, x[i] where p[i,j]); - The paragraph "Selection" in the langauge description (page 25) - was also correspondingly changed. This change of the language - semantics was undertaken due to a notice provided by Peter Lee - . - - * sample/hwd.lpm - A nice example of LP model written in GLPK/L and contributed by - Peter Lee was included in the package. - - * glplpx6b.c - The api routine lpx_interior was modified: a) to compute dual - values for all structural as well as auxiliary variables; b) to - allow specifying non-zero objective coefficients at auxiliary - variables. - - * sample/glpsol.c - Three new command-line options were added to the solver, which - are: --plain, --orig, and --wrlpt. - -Mon Oct 14 12:00:00 2002 Andrew Makhorin - - * GLPK 3.2.2 has been released. - - * glplpt.h, glplpt.c - A module that reads LP/MIP problem data in CPLEX LP format was - implemented. - - * glplpx8c.c - An api routine lpx_read_lpt that reads LP/MIP problem data in - CPLEX LP format was implemented. - - * sample/glpsol.c, sample/plan.lpt - A new command-line option '--lpt' that allows reading LP/MIP - problem data in CPLEX LP format was added to the solver. - - * doc/refman.latex, doc/refman.dvi, doc/refman.ps - A new edition of the Reference Manual was included. - - * source/*.c - Casting to (unsigned char) was added in some calls to the - classification functions (isalpha, etc.). The bug was fixed due - to report provided by Morten Welinder . - - * glplpx8a.c - The local routine mps_numb used in the routine lpx_write_mps - was modified to correctly format floating-point numbers that - have two digits in the decimal exponent. The bug was fixed due - to report provided by Vlahos Kiriakos . - - * glplan.h, glplan1.c, ..., glplan8.c - Several serious bugs were fixed in the language processor due - to reports provided by : - (a) a static search tree used to find sparse array elements was - sometimes overwritten that caused the message 'assertion failed' - to appear; the bug was fixed by creating separate search trees - in parsing routines; (b) a variable declared using the - predicate-controlled variable declaration statement had wrong - order of domain sets, because the variable array was built as - a copy of the predicate array; the bug was fixed by using the - internal routine transpose that coordinates mute letters (and - therefore domain sets) on copying sparse arrays; (c) sometimes - assignment statements like x[#a,#b,#c] := ... was incorrectly - processed; the bug was fixed by including an appropriate check - into the internal routine assign_stmt. - - * glp_simplex.c - An additional check to see if all lower bounds are not greater - than corresponding upper bounds was included in the routine to - prevent wrong results to appear. Such incorrectness sometimes - was not detected, namely, when variables with such bounds were - non-basic and never entered the basis. - - * glpspx1.c - Maximal number of simplex iterations before reinversion was - decreased from 100 to 50. This allowed to improve accuracy and, - that is more important, to reduce the solution time for many - serial lp problems approximately 1.5--2 times. - - * glpspx2.c - A check to see if all elements in the column chosen to enter - the basis are close to zero in the routine spx_prim_chuzr was - temporarily removed because this check gave wrong conclusion in - case when the corresponding non-basic variable had zero column - in the constraint matrix. An analogous check to see if all - elements in the row chosen to leave the basis are close to zero - in the routine spx_dual_chuzc was also temporarily removed on - the same reason. The bug was fixed due to reports provided by - Flavio Keidi Miyazawa and Vlahos Kiriakos - . - -Mon Aug 12 12:00:00 2002 Andrew Makhorin - - * GLPK 3.2.1 has been released. - - * glpbcs.h, glpbcs1.c, glpbcs2.c - * glpies.h, glpies1.c, glpies2.c, glpies3.c - A preliminary implementation of the branch-and-cut framework - was included in the package. - - * doc/brcut.txt - The document "GLPK: A Preliminary Implementation of the - Branch-And-Cut Framework" was included in the distribution. - - * sample/tspsol.c - An illustrative program for solving symmetric TSP based on the - branch-and-cut method was included in the package. - - * glpdmp.h, glpdmp.c - A new, re-enterable version of routines for managing dynamic - memory pools was included in the package. - - * glpavl.h, glpavl.c - A new, re-enterable version of routines for managing AVL search - trees was included in the package. - - * glplib.h, glplib2.c - Two new low-level routines ufopen and ufclose were included in - the package. - - * glplpx.h, glplpx7.c - The following new api routines were added: lpx_eval_activity, - lpx_eval_red_cost, lpx_reduce_form, lpx_mixed_gomory. - - * glptsp.h, glptsp.c - A module for reading TSP data using TSPLIB format was included - in the package. - -Mon Jul 15 12:00:00 2002 Andrew Makhorin - - * GLPK 3.2 has been released. - - * glplpx.h, glplpx1.c, glplpx2.c - The identifier 'class' (used as a member name in the structure - LPX and as an argument name in the routine lpx_set_class) was - changed to 'clss' in order to avoid conflicts with C++ reserved - words. - - * glpk.h, glplpx.h, glplpx1.c, glplpx2.c, glplpx6a.c, - * glplpx6b.c, glplpx6c.c, glplpx7.c, glplpx8.c - The following new api routines were added: lpx_set_obj_name, - lpx_get_obj_name, lpx_get_row_mark, lpx_get_col_mark, - lpx_transform_row, lpx_transform_col, lpx_prim_ratio_test, - lpx_dual_ratio_test, lpx_interior, lpx_get_ips_stat, - lpx_get_ips_row, lpx_get_ips_col, lpx_get_ips_obj, lpx_read_lpm, - lpx_write_mps, lpx_print_ips. - - * glpsol.c - The solver was completely re-programmed using new api routines. - - * lang.latex, lang.dvi, lang.ps - New edition of the document "GLPK: Modeling Language GLPK/L" - was included in the distribution. - - * refman.latex, refman.dvi, refman.ps - New edition of the document "GLPK: Reference Manual" (which - contains descriptions of all new api routines) was included in - the distribution. - - * glpapi.h, glpapi1.c, glpapi2.c, glpapi3.c, glpapi4.c - These files (which contain old api routines) were removed from - the package. - - * glpipm1.c, glpipm2.c - The file glpipm1.c was renamed to glpipm.c. The file glpipm2.c - was used only by old api routines and therefore was removed from - the package. - - * language.texinfo - Old version of the document "GLPK: Modeling Language GLPK/L" was - removed from the distribution. - -Mon May 27 12:00:00 2002 Andrew Makhorin - - * GLPK 3.1 has been released. - - * glplpx.h, glplpx1.c, glplpx2.c, glplpx3.c, glplpx4.c, - * glplpx5.c, glplpx6.c, glplpx7.c, glplpx8.c - A preliminary implementation of new API routines was completed. - - * refman.latex, refman.dvi, refman.ps - A draft edition of the document "GLPK Reference Manual", which - describes new API routines, was included. - - * glplib3.c - A bug in measuring long time intervals was fixed up. - - * glprsm3.c - This module contains some obsolete routines not longer used and - therefore it was removed from the package (into the subdirectory - 'oldsrc'). - - * glprsm.h - Some declarations related to the module 'glprsm3.c' (see above) - were removed. - - * guide.texinfo - The document "GLPK User's Guide" describing old API routines was - removed from the package (into the subdirectory 'oldsrc'). - - * newapi.txt - The document "New GLPK API Routines" was removed at all, because - it is superseded by the new reference manual (see above). - -Mon May 13 12:00:00 2002 Andrew Makhorin - - * GLPK 3.0.8 has been released. - - * glplpx.h, glplpx1.c, glplpx2.c, glplpx3.c, glplpx4.c, - * glplpx5.c, glplpx6.c, glplpx7.c - A preliminary (currently incomplete) implementation of new api - routines was included. - - * sample/newsamp.c - A sample program for the new api routines was included. - - * newapi.txt - A draft of the document "New GLPK API Routines" was included. - - * glpapi2.c, glpapi5.c, glpapi6.c - These modules (which contain the api routines glp_call_rsm1, - glp_simplex1, glp_pivot_in, glp_pivot_out) were removed from the - package (to the subdirectory 'oldsrc') since these routines are - functionally superseded by the new api routines. - - * glpk.h, glpapi2.c, glpapi3.c, glpapi4.c - The api routines glp_simplex2, glp_call_ipm1, glp_call_bbm1 were - renamed to glp_simplex, glp_interior, glp_integer, respectively. - - * sample/glpsol.c - Some command-line options (which got obsolete due to the recent - changes in api) were excluded. - - * doc/guide.texinfo - New edition of the document "GLPK User's Guide" was included in - the distribution to reflect the changes in some api routines. - - * doc/libref.texinfo - This document was removed from the package (to the subdirectory - 'oldsrc') since it describes the library routines, most of which - got obsolete and no longer used. - - * Makefile.in - A minor bug was fixed up due to bug report from Hans Schwengeler - . - -Mon Apr 22 12:00:00 2002 Andrew Makhorin - - * GLPK 3.0.7 has been released. - - * glpduff.h, glpduff.c, glpspx.h, glpspx1.c, glpspx2.c, - * glpapi7.c - These modules were replaced by a new implementation of the - simplex method and therefore they were removed from the package - (however they still can be found in the subdirectory 'oldsrc'). - - * glprsm1.c - The routine crash_aa was replaced by a new implementation and - therefore it was removed from the file 'glprsm1.c'. - - * glplpx.h, glplpx.c, glpspx.h, glpspx1.c, glpspx2.c, glpspx3.c, - * glpspx4.c, glpapi7.c - New (currently incomplete) implementation of the simplex method - components was included in the package. - -Thu Mar 28 12:00:00 2002 Andrew Makhorin - - * GLPK 3.0.6 has been released. - - * glpluf.h, glpluf.c, glpinv.h, glpinv.c - New version of LU-factorization and basis maintenance routines - (based on Forrest-Tomlin updating technique) was implemented. - - * glpeta.h, glpeta.c, glpfhv.h, glpfhv.c, glpgel.h, glpgel.c, - * glppfi.h, glppfi.c, glprfi.h, glprfi.c - These routines implement some other forms of the basis matrix. - Now they became obsolete being functionally superseded by the - new version of basis maintenance routines (see above) and were - removed from the package (however they still can be found in the - subdirectory 'oldsrc'). - - * glpbbm.c, glprsm.h, glprsm1.h, glprsm2.h, glpspx.h, glpspx2.c, - * glprsm2.c, glpsol.c - Necessary changes were made in order to use the new version of - basis maintenance routines. - -Tue Jan 29 12:00:00 2002 Andrew Makhorin - - * GLPK 3.0.5 has been released. - Structure of the package was re-organized in order to simplify - its maintenance. - - * doc/guide.texinfo - New edition of the document "GLPK User's Guide" was included in - the distribution. Now the document includes descriptions of some - additional API routines recently added to the package. - - * doc/newapi.txt - The document "Additional GLPK API Routines" was removed from the - distribution, because the corresponding material was included in - the user's guide (see above). - -Mon Dec 10 12:00:00 2001 Andrew Makhorin - - * GLPK 3.0.4 has been released. - - * glpspx.h, glpspx1.c, glpspx2.c, glpapi/glp_simplex2.h - A new, more efficient version of the two-phase primal simplex - method was implemented (advanced initial basis, projected - steepest edge, recursive computations of solution components). - - * glpapi/glp_call_bbm1.c - Now LP relaxation can be solved either using rsm1_driver(), or - using glp_simplex2(). The choice is controlled by the parameter - 'meth' (a member of struct bbm1). - - * sample/glpsol.c - The new implementation of the simplex method is now used by - default. The old version is available via --old-sim option. - - * glpmat/gm_scaling.c - Now this routine displays only two lines: an initial "quality" - and a final "quality". - - * glplp/prepro_lp.c - Identifiers 'fmin' and 'fmax' renamed to 'f_min' and 'f_max' in - order to avoid conflict with . The bug was fixed due to - report provided by Sami Farin . - -Wed Oct 03 12:00:00 2001 Andrew Makhorin - - * GLPK 3.0.3 has been released. - - * glprsm/harris_row.c, glprsm/harris_col.c - The relative tolerance used on the first pass of the two-pass - ratio test was replaced by the absolute tolerance. - - * glprsm/rsm_primal.c, glprsm/rsm_feas.c, glprsm/rsm_dual.c - The absolute tolerance passed to the two-pass ratio test routine - was decaresed (for both primal and dual simplex). - - These changes were made in order to improve numerical stability - of the simplex method. - - * glprsm/glp_call_rsm1.c, glprsm/glp_call_bbm1.c, - * glprsm/glp_simplex1, glprsm/glp_pivoting.c - Default form of the inverse was changed from RFI to AFI. - -Mon Sep 24 12:00:00 2001 Andrew Makhorin - - * GLPK 3.0.2 has been released. - - * glpfhv.h, glpfhv.c - New version of the basis maintaining routines was implemented. - These routines, which are based on so called FHV-factorization - (a variety of LU-factorization) and Gustavson's data structures, - perform the main operations on the basis matrix faster at the - expense of some worsening numerical accuracy. - - * glprsm.h, glprsm/afi.c - The routines, which implement AFI (Advanced Form of the - Inverse) based on FHV-factorization, were added to the package. - This new form is available via the parameter form = 3 (on API - level) or via the option --afi (in GLPSOL solver). - - * EFI was renamed to PFI - In order to correct terminology the acronym EFI (Elimination - Form of the Inverse) was replaced by PFI (Product Form of the - Inverse) everywhere in the source code and the documentation. - - * glpset/umalloc.c, glpset/ucalloc.c - * glpset/get_atom.c, glpset/get_atomv.c - These memory management routines were changed in order *not* to - clear allocated memory blocks by binary zeros. - -Wed Aug 01 12:00:00 2001 Andrew Makhorin - - * GLPK 3.0.1 has been released. - - * glpapi/old_api.c, glplp/extract_lp.c, store_lpsol.c - Old API routines were deleted from the package. - - * include/glpk.h, include/glpapi.h, include/glplp.h - Specifications of old API routines and data structures were - removed from the headers. - - * sample/glpsol.c - New version of the stand-alone solver GLPSOL that now uses new - API routines was implemented. - - * glpapi/glp_set_row_fctr.c, glpapi/glp_set_col_fctr.c, - * glpapi/glp_get_row_fctr.c, glpapi/glp_get_col_fctr.c, - * glpapi/glp_scale_prob.c - Scaling routines were added. - - * glpapi/glp_write_mps.c - The routine for writing problem data in MPS format was added. - - * glpapi/glp_simplex1.c - Comprehensive driver to the simplex method was added. - - * glpapi/glp_pivoting.c - The routines glp_pivot_in() and glp_pivot_out() intended for - basis maintaining were added. - - * glprsm/create_rsm.c, glprsm/delete_rsm.c, glprsm/scale_rsm.c, - * glprsm/build_basis.c - Additional low level routines related to the simplex method - were added. - - * glpk.h, glpapi.h, glprsm.h - Additional specifications for new routines and data structures - were added. - - * sample/lpglpk30.c - A non-trivial example was added. It allows using GLPK as a base - LP solver for Concorde, a program for solving Traveling Salesman - Problem (TSP). For details see comments in 'lpglpk30.c'. - - * doc/newapi.txt - The document "Additional GLPK API Routines" that describes some - new API routines was included. - -Thu Jul 19 12:00:00 2001 Andrew Makhorin - - * GLPK 3.0 has been released. - - Now GLPK is provided with new API, which is intended for using - the package in more complex algorithmic schemes. - - * glpapi/old_api.c - All routines related to old API were gathered in one file named - 'old_api.c'. - - * glpapi/*.c - These routines that implement new API were added to the package. - - * include/glpk.h, include/glpapi.h - Specifications of new API routines and data structures were - added to these headers. Specifications of old API routines and - data structures were locked by #ifdef GLP_OLD_API directive. - - * doc/guide.texinfo - New edition of the document "GLPK User's Guide" that correspond - to new API was included. - -Thu Jun 14 12:00:00 2001 Andrew Makhorin - - * GLPK 2.4.1 has been released. - - * doc/glpk_ml.texinfo - The new document "Modeling Language GLPK/L" was included. - - * doc/glpk_ug.texinfo - New edition of the document "GLPK User's Guide" was included. - - * doc/language.txt - The preliminary document "GLPK/L Modeling Language: A Brief - description" was removed from the distribution, because it has - been replaced by the new document "Modeling Language GLPK/L". - - * glplang/l_spar.c - The routine comparison() was re-programmed in order to - implement the relation operation as specified in the language - description. - - * glpmip.h, glpmip/*.c - The partition 'glpmip' was renamed to 'glpbbm'. - -Thu May 10 12:00:00 2001 Andrew Makhorin - - * GLPK 2.4 has been released. - - Now GLPK includes an implementation of a preliminary version of - the GLPK/L modeling language. - - * glplang.h, glplang/*.c - The header 'glplang.h' and a set of routines that implements - the GLPK/L language processor (the partition 'glplang') were - added to the package. - - * doc/language.txt - The document "GLPK/L Modeling Language: A Brief Description - (Supplement to GLPK User's Guide)" in plain text format was - included in the package (see the file 'language.txt' in the - subdirectory 'doc' of the distribution). - - * ex/model1.lpm, ex/model2.lpm - Two examples of model descriptions written in GLPK/L were added - to the package. - - * sample/glpsol.c - This program was modified in order: a) to allow processing - model description written in GLPK/L; b) to allow solving pure - LP problem using the interior point method. - - * sample/glpipm.c - This program was removed from the package, because its function - was passed to the GLPSOL solver. - - * Makefile.in - This file was changed in order to install the GLPSOL solver - executable. - -Mon Apr 09 12:00:00 2001 Andrew Makhorin - - * GLPK 2.3 has been released. - - * glpmip.h, glpmip/*.c - These routines (that implement the branch-and-bound method) were - re-programmed in order to improve robustness of implementation. - In particular, heuristic routines were carried out from the main - driver routine. - - Additional GLPK API routines were documented. - - New edition of the document "GLPK User's Guide" was included in - the package. - - The preliminary document "Mixed Integer Programming Using GLPK - Version 2.2 (Supplement to GLPK User's Guide)" was removed from - the package, because this material was included in GLPK User's - Guide. - -Thu Mar 15 12:00:00 2001 Andrew Makhorin - - * GLPK 2.2 has been released. - - Now GLPK includes a tentative implementation of the - branch-and-bound procedure based on the dual simplex method for - mixed integer linear programming (MIP). - - The preliminary document "Mixed Integer Programming Using GLPK - Version 2.2 (Supplement to GLPK User's Guide)" was included into - the package in plain text format (see the file 'mip.txt' in the - subdirectory 'doc' of the distribution). - - * glpmip.h, glpmip/*.c, glpapi/glp_integer.c - These routines (that implement the branch-and-bound method) were - added to the package. - - * sample/glpsol.c - This program was modified in order to allow solving LP and MIP - problems. - - * glprsm/rsm_primal.c, glprsm/rsm_dual.c, glprsm/rsm_feas.c, - * glprsm/rsm1_driver.c - These routines (which are drivers to basic components of the - revised simplex method) were added to the package. - -Mon Feb 19 12:00:00 2001 Andrew Makhorin - - * GLPK 2.1 has been released. - - * glprsm.h, glprsm/*.c - These routines (that implement components of the revised simplex - method) were re-programmed and documented. - - The document "GLPK Implementation of the Revised Simplex Method" - was included into the package. - -Thu Jan 25 12:00:00 2001 Andrew Makhorin - - * GLPK 2.0 has been released. - - Now GLPK includes a tentative implementation of the primal-dual - interior point method for large-scale linear programming (for - more details see the file `NEWS' in the distribution). A number - of routines related to the interior point method were added to - the package. - - * insist.c - The routine `insist' and the macro of the same name were - introduced into the package in order to replace the standard - macro `assert'. Some routines require the expression specified - in the `assert' macro to be evaluated, but compiling the package - with NDEBUG option prevents from that. This bug was fixed due to - bug report provided by Peter A. Huegler . - - * Makefile.in - Minor bug was fixed due to a patch provided by Alexandre Oliva - . - -Wed Jan 10 12:00:00 2001 Andrew Makhorin - - * GLPK 1.1.2 has been released. - - * umalloc.c, ufree.c, create_pool.c, get_atom.c, get_atomv.c - These routines were changed in order to fix a bug due to - report provided by Andrew Hood . Because of - this bug data alignment error occured on the Sparc computer. - -Tue Dec 14 12:00:00 2000 Andrew Makhorin - - * GLPK 1.1.1 has been released. - - Minor bug was fixed in `Makefile.in'. - - GLPK Library Reference was included. - -Mon Nov 27 12:00:00 2000 Andrew Makhorin - - * GLPK 1.1 has been released. - - Minor changes were made in order to co-ordinate GLPK routines - and their descriptions. - - GLPK User's Guide was included. - -Fri Oct 20 12:00:00 2000 Andrew Makhorin - - * GLPK 1.0 has been released. diff --git a/resources/3rdparty/glpk-4.53/INSTALL b/resources/3rdparty/glpk-4.53/INSTALL deleted file mode 100644 index 749f33d0a..000000000 --- a/resources/3rdparty/glpk-4.53/INSTALL +++ /dev/null @@ -1,209 +0,0 @@ -INSTALLING GLPK ON YOUR COMPUTER -******************************** - -Unpacking the distribution file -------------------------------- -The GLPK package (like all other GNU software) is distributed in the -form of a packed archive. It is one file named `glpk-X.Y.tar.gz', where -`X' is the major version number and `Y' is the minor version number; -for example, the archive name might be `glpk-4.15.tar.gz'. - -In order to prepare the distribution for installation you should: - -1. Copy the GLPK distribution file to a working directory. - -2. Unpack the distribution file with the following command: - - gzip -d glpk-X.Y.tar.gz - - After unpacking the distribution file is automatically renamed to - `glpk-X.Y.tar'. - -3. Unarchive the distribution file with the following command: - - tar -x < glpk-X.Y.tar - - It automatically creates the subdirectory `glpk-X.Y' containing the - GLPK distribution. - -Configuring the package ------------------------ -After unpacking and unarchiving the GLPK distribution you should -configure the package, i.e. automatically tune it for your platform. - -Normally, you should just `cd' to the directory `glpk-X.Y' and run the -`configure' script, e.g. - - ./configure - -The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It also creates file `config.h' containing platform-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, a file -`config.cache' that saves the results of its tests to speed up -reconfiguring, and a file `config.log' containing compiler output -(useful mainly for debugging `configure'). - -Running `configure' takes about a few seconds. While it is running, it -displays some messages that tell you what it is doing. If you don't want -to see the messages, run `configure' with its standard output redirected -to `dev/null'; for example, `./configure > /dev/null'. - -By default both static and shared versions of the GLPK library will be -compiled. Compilation of the shared librariy can be turned off by -specifying the `--disable-shared' option to `configure', e.g. - - ./configure --disable-shared - -If you encounter problems building the library try using the above -option, because some platforms do not support shared libraries. - -The GLPK package has some optional features listed below. By default -all these features are disabled. To enable a feature the corresponding -option should be passed to the configure script. - ---with-gmp Enable using the GNU MP bignum library - - This feature allows the exact simplex solver to use the GNU MP - bignum library. If it is disabled, the exact simplex solver uses the - GLPK bignum module, which provides the same functionality as GNU MP, - however, it is much less efficient. - - For details about the GNU MP bignum library see its web page at - . - ---with-zlib Enable using the zlib data compression library - - This feature allows GLPK API routines and the stand-alone solver to - read and write compressed data files performing compression and - decompression "on the fly" (compressed data files are recognized by - suffix `.gz' in the file name). It may be useful in case of large - MPS files to save the disk space. - - For details about the zlib compression library see its web page at - . - ---enable-dl The same as --enable-dl=ltdl ---enable-dl=ltdl Enable shared library support (GNU) ---enable-dl=dlfcn Enable shared library support (POSIX) - - Currently this feature is only needed to provide dynamic linking to - ODBC and MySQL shared libraries (see below). - - For details about the GNU shared library support see the manual at - . - ---enable-odbc Enable using ODBC table driver (libiodbc) ---enable-odbc=unix Enable using ODBC table driver (libodbc) - - This feature allows transmitting data between MathProg model objects - and relational databases accessed through ODBC. - - For more details about this feature see the supplement "Using Data - Tables in the GNU MathProg Modeling Language" (doc/tables.*). - ---enable-mysql Enable using MySQL table driver (libmysql) - - This feature allows transmitting data between MathProg model objects - and MySQL relational databases. - - For more details about this feature see the supplement "Using Data - Tables in the GNU MathProg Modeling Language" (doc/tables.*). - -Compiling the package ---------------------- -Normally, you can compile (build) the package by typing the command: - - make - -It reads `Makefile' generated by `configure' and performs all necessary -jobs. - -If you want, you can override the `make' variables CFLAGS and LDFLAGS -like this: - - make CFLAGS=-O2 LDFLAGS=-s - -To compile the package in a different directory from the one containing -the source code, you must use a version of `make' that supports `VPATH' -variable, such as GNU `make'. `cd' to the directory where you want the -object files and executables to go and run the `configure' script. -`configure' automatically checks for the source code in the directory -that `configure' is in and in `..'. If for some reason `configure' is -not in the source code directory that you are configuring, then it will -report that it can't find the source code. In that case, run `configure' -with the option `--srcdir=DIR', where DIR is the directory that contains -the source code. - -Some systems require unusual options for compilation or linking that -the `configure' script does not know about. You can give `configure' -initial values for variables by setting them in the environment. Using -a Bourne-compatible shell, you can do that on the command line like -this: - - CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure - -Or on systems that have the `env' program, you can do it like this: - - env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure - -Here are the `make' variables that you might want to override with -environment variables when running `configure'. - -For these variables, any value given in the environment overrides the -value that `configure' would choose: - -CC: C compiler program. The default is `cc'. - -INSTALL: Program used to install files. The default value is `install' - if you have it, otherwise `cp'. - -For these variables, any value given in the environment is added to the -value that `configure' chooses: - -DEFS: Configuration options, in the form `-Dfoo -Dbar ...'. - -LIBS: Libraries to link with, in the form `-lfoo -lbar ...'. - -Checking the package --------------------- -To check the package, i.e. to run some tests included in the package, -you can use the following command: - - make check - -Installing the package ----------------------- -Normally, to install the GLPK package you should type the following -command: - - make install - -By default, `make install' will install the package's files in -`usr/local/bin', `usr/local/lib', etc. You can specify an installation -prefix other than `/usr/local' by giving `configure' the option -`--prefix=PATH'. Alternately, you can do so by consistently giving a -value for the `prefix' variable when you run `make', e.g. - - make prefix=/usr/gnu - make prefix=/usr/gnu install - -After installing you can remove the program binaries and object files -from the source directory by typing `make clean'. To remove all files -that `configure' created (`Makefile', `config.status', etc.), just type -`make distclean'. - -The file `configure.ac' is used to create `configure' by a program -called `autoconf'. You only need it if you want to remake `configure' -using a newer version of `autoconf'. - -Uninstalling the package ------------------------- -To uninstall the GLPK package, i.e. to remove all the package's files -from the system places, you can use the following command: - - make uninstall - -======================================================================== diff --git a/resources/3rdparty/glpk-4.53/Makefile.am b/resources/3rdparty/glpk-4.53/Makefile.am deleted file mode 100644 index 5a040f49a..000000000 --- a/resources/3rdparty/glpk-4.53/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -## Process this file with automake to produce Makefile.in ## - -ACLOCAL_AMFLAGS=-I m4 - -SUBDIRS = src examples - -## eof ## diff --git a/resources/3rdparty/glpk-4.53/Makefile.in b/resources/3rdparty/glpk-4.53/Makefile.in deleted file mode 100644 index 5ae9553c6..000000000 --- a/resources/3rdparty/glpk-4.53/Makefile.in +++ /dev/null @@ -1,759 +0,0 @@ -# Makefile.in generated by automake 1.12.5 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2012 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ - esac; \ - test $$am__dry = yes; \ - } -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = . -DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(srcdir)/config.h.in \ - $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ - THANKS config.guess config.sub install-sh ltmain.sh missing -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -SOURCES = -DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ - cscope distdir dist dist-all distcheck -ETAGS = etags -CTAGS = ctags -CSCOPE = cscope -DIST_SUBDIRS = $(SUBDIRS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ - || { sleep 5 && rm -rf "$(distdir)"; }; \ - else :; fi -am__post_remove_distdir = $(am__remove_distdir) -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -DIST_TARGETS = dist-gzip -distuninstallcheck_listfiles = find . -type f -print -am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ - | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = src examples -all: config.h - $(MAKE) $(AM_MAKEFLAGS) all-recursive - -.SUFFIXES: -am--refresh: Makefile - @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): - -config.h: stamp-h1 - @if test ! -f $@; then rm -f stamp-h1; else :; fi - @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi - -stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status config.h -$(srcdir)/config.h.in: $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f stamp-h1 - touch $@ - -distclean-hdr: - -rm -f config.h stamp-h1 - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool config.lt - -# This directory's subdirectories are mostly independent; you can cd -# into them and run 'make' without going through this Makefile. -# To change the values of 'make' variables: instead of editing Makefiles, -# (1) if the variable is set in 'config.status', edit 'config.status' -# (which will cause the Makefiles to be regenerated when you run 'make'); -# (2) otherwise, pass the desired values on the 'make' command line. -$(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done -cscopelist-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \ - done - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) - -clean-cscope: - -rm -f cscope.files - -cscope.files: clean-cscope cscopelist-recursive cscopelist - -cscopelist: cscopelist-recursive $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files - -distdir: $(DISTFILES) - $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done - -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -755 \ - -exec chmod u+rwx,go+rx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r "$(distdir)" -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__post_remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) - -dist-lzip: distdir - tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) - -dist-xz: distdir - tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) - -dist-tarZ: distdir - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) - -dist-shar: distdir - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__post_remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) - -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lz*) \ - lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ - *.tar.xz*) \ - xz -dc $(distdir).tar.xz | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_inst - chmod a-w $(distdir) - test -d $(distdir)/_build || exit 0; \ - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ - $(AM_DISTCHECK_CONFIGURE_FLAGS) \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ - && cd "$$am__cwd" \ - || exit 1 - $(am__post_remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @test -n '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: trying to run $@ with an empty' \ - '$$(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - $(am__cd) '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am -check: check-recursive -all-am: Makefile config.h -installdirs: installdirs-recursive -installdirs-am: -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-hdr \ - distclean-libtool distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: - -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ - cscopelist-recursive ctags-recursive install-am install-strip \ - tags-recursive - -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am am--refresh check check-am clean clean-cscope \ - clean-generic clean-libtool cscope cscopelist \ - cscopelist-recursive ctags ctags-recursive dist dist-all \ - dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ dist-xz \ - dist-zip distcheck distclean distclean-generic distclean-hdr \ - distclean-libtool distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ - ps ps-am tags tags-recursive uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/resources/3rdparty/glpk-4.53/NEWS b/resources/3rdparty/glpk-4.53/NEWS deleted file mode 100644 index 5bbadf21a..000000000 --- a/resources/3rdparty/glpk-4.53/NEWS +++ /dev/null @@ -1,1741 +0,0 @@ -GLPK 4.53 (release date: Feb 13, 2014) - - The API routine glp_read_mps was changed to remove free rows. - - A bug was fixed in the API routine glp_read_lp. Thanks to - Gabriel Hackebeil for bug report. - - The zlib compression library used by some GLPK routines and - included in the package was downgraded from 1.2.7 to 1.2.5 (as - in GLPK 4.50) because of addressability bugs on some 64-bit - platforms. Thanks to Carlo Baldassi - for bug report. - - A bug was fixed in a routine that reads gzipped files. Thanks - to Achim Gaedke for bug report. - - Two API routines glp_get_it_cnt and glp_set_it_cnt were added. - Thanks to Joey Rios for suggestion. - - All obsolete GLPK API routines (prefixed with lpx) were removed - from the package. - - A set of routines that simulate the old GLPK API (as defined - in 4.48) were added; see examples/oldapi/api/lpx.c. Thanks to - Jan Engelhardt for suggestion. - - A namespace bug was fixed in the SQL table drive module. Thanks - to Dennis Schridde for bug report. - -GLPK 4.52.1 (release date: Jul 28, 2013) - - This is a bug-fix release. - - A version information bug in Makefile.am was fixed. Thanks to - Sebastien Villemot for bug report. - -GLPK 4.52 (release date: Jul 18, 2013) - - The clique cut generator was essentially reimplemented, and now - it is able to process very large and/or dense conflict graphs. - - A simple rounding heuristic was added to the MIP optimizer. - - Some bugs were fixed in the proximity search heuristic routine. - Thanks to Giorgio Sartor <0gioker0@gmail.com>. - - New command-line option '--proxy [nnn]' was added to glpsol to - enable using the proximity search heuristic. - - A bug (incorrect processing of LI column indicator) was fixed - in the mps format reading routine. Thanks to Charles Brixko for - bug report. - -GLPK 4.51 (release date: Jun 19, 2013) - - Singleton and dense phases were implemented on computing - LU-factorization with Gaussian elimination. The singleton phase - is a feature that allows processing row and column singletons - on initial elimination steps more efficiently. The dense phase - is a feature used on final elimination steps when the active - submatrix becomes relatively dense. It significantly reduces - the time needed, especially if the active submatrix fits in CPU - cache, and improves numerical accuracy due to full pivoting. - - The API routine glp_adv_basis that constructs advanced initial - LP basis was replaced by an improved version, which (unlike the - old version) takes into account numerical values of constraint - coefficients. - - The proximity search heuristic for MIP was included in the GLPK - integer optimizer glp_intopt. On API level the heuristic can be - enabled by setting the parameter ps_heur in glp_iocp to GLP_ON. - This feature is also available in the solver glpsol through - command-line option '--proxy'. Many thanks to Giorgio Sartor - <0gioker0@gmail.com> for contribution. - - A bug was fixed that caused numerical instability in the FPUMP - heuristic. - -GLPK 4.50 (release date: May 24, 2013) - - A new version of LU-factorization routines were added. - Currently this version provides the same functionality as the - old one, however, the new version allows further improving. - - Old routines for FHV-factorization used to update the basis - factorization were replaced by a new version conforming to the - new version of LU-factorization. - - Some clarifications about using the name index routines were - added. Thanks to Xypron for suggestion. - - Some typos were corrected in the MathProg language reference. - Thanks to Jeffrey Kantor for report. - - A serious bug (out-of-range indexing error) was *tentatively* - fixed in the routine glp_relax4. Unfortunatly, this bug is - inherited from the original Fortran version of the RELAX-IV - code (for details please see ChangeLog), and since the code is - very intricate, the bug is still under investigation. Thanks to - Sylvain Fournier for bug report. - -GLPK 4.49 (release date: Apr 16, 2013) - - The new API routine glp_mincost_relax4, which is a driver to - relaxation method of Bertsekas and Tseng (RELAX-IV), was added - to the package. RELAX-IV is a code for solving minimum cost - flow problems. On large instances it is 100-1000 times faster - than the standard primal simplex method. Prof. Bertsekas, the - author of the original RELAX-IV Fortran code, kindly permitted - to include a C translation of his code in GLPK under GPLv3. - - A bug (wrong dual feasibility test) was fixed in API routine - glp_warm_up. Thanks to David T. Price - for bug report. - - Obsolete API routine lpx_check_kkt was replaced by new routine - glp_check_kkt. - - IMPORTANT: All old API routines whose names begin with 'lpx_' - were removed from API level and NO MORE AVAILABLE. - -GLPK 4.48 (release date: Jan 28, 2013) - - This is a maintainer release. - - Some minor changes in API (glpk.h) were made. For details - please see ChangeLog. - - Some bugs/typos were fixed. Thanks to - Raniere Gaia Costa da Silva, - Heinrich Schuchardt , and - Robbie Morrison for reports. - -GLPK 4.47 (release date: Sep 09, 2011) - - The new API routine glp_intfeas1 was added to the package. - This routine is a tentative implementation of the integer (0-1) - feasibility solver based on the CNF-SAT solver (which currently - is MiniSat). It may be used in the same way as glp_intopt to - find either any integer feasible solution or a solution, for - which the objective function is not worse than the specified - value. Detailed description of this routine can be found in the - document "CNF Satisfiability Problem", which is included in the - distribution (see doc/cnfsat.pdf). - - The following two options were added to glpsol: - - --minisat translate 0-1 feasibility problem to CNF-SAT - problem and solve it with glp_intfeas1/MiniSat - (if the problem instance is already in CNF-SAT - format, no translation is performed) - - --objbnd bound add inequality obj <= bound (minimization) or - obj >= bound (maximization) to 0-1 feasibility - problem (this option assumes --minisat) - - The paint-by-numbers puzzle model (pbn.mod) included in the - distribution is a nice example of the 0-1 feasibility problem, - which can be efficiently solved with glp_intfeas1/MiniSat. This - model along with a brief instruction (pbn.pdf) and benchmark - examples from encoded in GNU MathProg (*.dat) can - be found in subdirectory examples/pbn/. - - The glpsol lp/mip solver was modified to bypass postprocessing - of MathProg models if the solution reported is neither optimal - nor feasible. - - A minor bug in examples/Makefile.am was fixed to correctly - build glpk in a separate directory. Thanks to Marco Atzeri - for bug report and patch. - -GLPK 4.46 (release date: Aug 09, 2011) - - The following new API routines were added: - - glp_read_cnfsat read CNF-SAT problem data in DIMACS format - glp_check_cnfsat check for CNF-SAT problem instance - glp_write_cnfsat write CNF-SAT problem data in DIMACS format - glp_minisat1 solve CNF-SAT problem instance with MiniSat - - The routine glp_minisat1 is a driver to MiniSat, a CNF-SAT - solver developed by Niklas Een and Niklas Sorensson, Chalmers - University of Technology, Sweden. This routine is similar to - the routine glp_intopt, however, it is intended to solve a 0-1 - programming problem instance, which is the MIP translation of - a CNF-SAT problem instance. - - Detailed description of these new API routines can be found in - the document "CNF Satisfiability Problem", which is included in - the distribution (see files doc/cnfsat.tex and doc/cnfsat.pdf). - - The following new glpsol command-line options were added: - - --cnf filename read CNF-SAT problem instance in DIMACS - format from filename and translate it to MIP - --wcnf filename write CNF-SAT problem instance in DIMACS - format to filename - --minisat solve CNF-SAT problem instance with MiniSat - solver - - The zlib compression library (version 1.2.5) was ANSIfied, - modified according to GLPK requirements and included in the - distribution as an external software module. Thus, now this - feature is platform independent. - - Some bugs were fixed in the SQL table driver. Thanks to Xypron - . - -GLPK 4.45 (release date: Dec 05, 2010) - - This is a bug-fix release. - - Several bugs/typos were fixed. Thanks to - Xypron , - Robbie Morrison , and - Ali Baharev for reports. - - Some glpk documents was re-formatted and merged into a single - document. Now the glpk documentation consists of the following - three main documents (all included in the distribution): - - GLPK: Reference Manual - - GLPK: Graph and Network Routines - - Modeling Language GNU MathProg: Language Reference - -GLPK 4.44 (release date: Jun 03, 2010) - - The following suffixes for variables and constraints were - implemented in the MathProg language: - - .lb (lower bound), - .ub (upper bound), - .status (status in the solution), - .val (primal value), and - .dual (dual value). - - Thanks to Xypron for draft implementation - and testing. - - Now the MathProg language allows comment records (marked by - '#' in the very first position) in CSV data files read with the - table statements. Note that the comment records may appear only - in the beginning of a CSV data file. - - The API routine glp_cpp to solve the Critical Path Problem was - added and documented. - -GLPK 4.43 (release date: Feb 20, 2010) - - This is a maintainer release. - - `configure.ac' was changed to allow building the package under - Mac OS and Darwin with ODBC support. - Thanks to Xypron for suggestions and Noli - Sicad for testing. - - The SQL table driver was improved to process NULL data. Thanks - to Xypron . - - Some bugs were fixed in the LP/MIP preprocessor. - -GLPK 4.42 (release date: Jan 13, 2010) - - The following new API routines were added: - - glp_check_dup check for duplicate elements in sparse - matrix - glp_sort_matrix sort elements of the constraint matrix - glp_read_prob read problem data in GLPK format - glp_write_prob write problem data in GLPK format - glp_analyze_bound analyze active bound of non-basic variable - glp_analyze_coef analyze objective coefficient at basic - variable - glp_print_ranges print sensitivity analysis report (this - routine replaces lpx_print_sens_bnds and - makes it deprecated) - - For description of these new routines and the GLPK LP/MIP - format see a new edition of the reference manual included in - the distribution. (Chapter "Graph and network API routines" was - carried out from the main reference manual and included in the - distribution as a separate document.) - - The following new command-line options were added to the stand- - alone solver glpsol: - --glp filename read problem data in GLPK format - --wglp filename write problem data in GLPK format - --ranges filename print sensitivity analysis report (this - option replaces --bounds) - - Now all GLPK routines performing file I/O support special - filenames "/dev/stdin", "/dev/stdout", and "/dev/stderr", which - can be specified in the same way as regular filenames. This - feature is plaform-independent. - -GLPK 4.41 (release date: Dec 21, 2009) - - The following new API routies were added: - - glp_transform_row transform explicitly specified row - glp_transform_col transform explicitly specified column - glp_prim_rtest perform primal ratio test - glp_dual_rtest perform dual ratio test - - For description of these new routines see a new edition of the - reference manual included in the distribution. - - The following API routines are deprecated: lpx_transform_row, - lpx_transform_col, lpx_prim_ratio_test, lpx_dual_ratio_test. - - Some improvements were made in the MIP solver (glp_intopt). - - The SQL table driver used to read/write data in MathProg models - was changed to allow multiple arguments separated by semicolon - in SQL statements. Thanks to Xypron . - - Two new options were added to the glpsol stand-alone solver: - --seed value (to initialize the pseudo-random number generator - used in MathProg models with specified value), and - --ini filename (to use a basis previously saved with -w option - as an initial basis on solving similar LP's). - - Two new MathProg example models were included. Thanks to - Nigel Galloway and Noli Sicad - for contribution. - - Scripts to build GLPK with Microsoft Visual Studio 2010 for - both 32-bit and 64-bit Windows were included. Thanks to Xypron - for contribution and testing. - -GLPK 4.40 (release date: Nov 03, 2009) - - The following new API routines were added: - - glp_del_vertices remove vertices from graph - glp_del_arc remove arc from graph - glp_wclique_exact find maximum weight clique with the exact - algorithm developed by Prof. P. Ostergard - glp_read_ccdata read graph in DIMACS clique/coloring - format - glp_write_ccdata write graph in DIMACS clique/coloring - format - - For description of these new routines see a new edition of the - reference manual included in the distribution. - - The hybrid pseudocost branching heuristic was included in the - MIP solver. It is available on API level (iocp.br_tech should - be set to GLP_BR_PCH) and in the stand-alone solver glpsol - (via the command-line option --pcost). This heuristic may be - useful on solving hard MIP instances. - - The branching heuristic by Driebeck and Tomlin (used in the - MIP solver by default) was changed to switch to branching on - most fractional variable if an lower bound of degradation of - the objective is close to zero for all branching candidates. - - A bug was fixed in the LP preprocessor (routine npp_empty_col). - Thanks to Stefan Vigerske for the - bug report. - - A bug was fixed and some improvements were made in the FPUMP - heuristic module. Thanks to Xypron . - - A bug was fixed in the API routine glp_warm_up (dual - feasibility test was incorrect in maximization case). Thanks to - Uday Venkatadri for the bug report. - -GLPK 4.39 (release date: Jul 26, 2009) - - The following new API routines were added: - - glp_warm_up "warm up" LP basis - glp_set_vertex_name assign (change) vertex name - glp_create_v_index create vertex name index - glp_find_vertex find vertex by its name - glp_delete_v_index delete vertex name index - glp_read_asnprob read assignment problem data in DIMACS - format - glp_write_asnprob write assignment problem data in DIMACS - format - glp_check_asnprob check correctness of assignment problem - data - glp_asnprob_lp convert assignment problem to LP - glp_asnprob_okalg solve assignment problem with the - out-of-kilter algorithm - glp_asnprob_hall find bipartite matching of maxumum - cardinality with Hall's algorithm - - Also were added some API routines to read plain data files. - - The API routines glp_read_lp and glp_write_lp to read/write - files in CPLEX LP format were re-implemented. Now glp_write_lp - correctly writes double-bounded (ranged) rows by introducing - slack variables rather than by duplicating the rows. - - For description of these new routines see a new edition of the - reference manual included in the distribution. - - The 'xfree(NULL)' bug was fixed in the AMD routines. Thanks to - Niels Klitgord for bug report. - - The message "Crashing..." was changed to "Constructing initial - basis..." due to suggestion by Thomas Kahle . - - Some typos were corrected in glpsol output messages. Thanks to - Xypron for patch. - -GLPK 4.38 (release date: May 02, 2009) - - API routines glp_read_mps and glp_write_mps were improved. - - Some improvements were made in the dual simplex routines. - - Two external software modules AMD and COLAMD were included in - the distribution (for more details please see src/amd/README - and src/colamd/README). Now they are used in the interior-point - solver to reorder the matrix prior to Cholesky factorization. - - API routine glp_ipt_status may return two new statuses due to - changes in the routine glp_interior. For details please see the - reference manual included in the distribution. - - A minor bug was fixed in the graph/network routines. Thanks to - Nelson H. F. Beebe for bug report. - -GLPK 4.37 (release date: Mar 29, 2009) - - The 0-1 Feasibility Pump heuristic was included in the GLPK - integer optimizer glp_intopt. On API level the heuristic can be - enabled by setting the parameter fp_heur in glp_iocp to GLP_ON. - This feature is also available in the solver glpsol through - command-line option '--fpump'. For more details please see the - reference manual included in the distribution. - - The following new API routines were added: - - glp_print_sol write basic solution in printable format - glp_print_ipt write interior-point solution in printable - format - glp_print_mip write MIP solution in printable format - glp_read_graph read (di)graph from plain text file - glp_write_graph write (di)graph to plain text file - glp_weak_comp find all weakly connected components - glp_strong_comp find all strongly connected components - - The following API routines are deprecated: lpx_print_sol, - lpx_print_ips, lpx_print_mip, lpx_print_prob (the latter is - equivalent to glp_write_lp). - - A bug was fixed in the interior-point solver (glp_interior) to - correctly compute dual solution components when the problem is - scaled. - - The files configure.ac and Makefile.am were changed: - (a) to allow using autoreconf/autoheader; - (b) to allow building the package in a directory other than its - source directory. - Thanks to Marco Atzeri for bug report. - - An example model in the GNU MathProg language was added. - Thanks to Larry D'Agostino for - contribution. - -GLPK 4.36 (release date: Feb 06, 2009) - - The following new API routines were added to the package: - - glp_mincost_okalg find minimum-cost flow with out-of-kilter - algorithm - glp_maxflow_ffalg find maximal flow with Ford-Fulkerson - algorithm - - For detailed description of these new routines and related data - structures see chapter "Graph and Network API Routines" in a new - edition of the reference manual included in the distribution. - - The following two new command-line options were added to the - solver glpsol: - - --mincost read min-cost flow data in DIMACS format - --maxflow read maximum flow data in DIMACS format - - Duplicate symbols in the header glpk.h were removed to allow - using swig. - Thanks to Kelly Westbrooks and - Nigel Galloway for suggestion. - - A minor defect was fixed in the routine glp_write_lp. - Thanks to Sebastien Briais for bug report. - - A minor bug was fixed in the SQL module. - Thanks to Xypron for patch. - - Some new example models in the GNU MathProg modeling language - were added. Thanks to Sebastian Nowozin and - Nigel Galloway for contribution. - -GLPK 4.35 (release date: Jan 09, 2009) - - The following new API routines were added to the package: - - glp_create_graph create graph - glp_set_graph_name assign (change) graph name - glp_add_vertices add new vertices to graph - glp_add_arc add new arc to graph - glp_erase_graph erase graph content - glp_delete_graph delete graph - glp_read_mincost read minimum cost flow problem data in - DIMACS format - glp_write_mincost write minimum cost flow problem data in - DIMACS format - glp_mincost_lp convert minimum cost flow problem to LP - glp_netgen Klingman's network problem generator - glp_gridgen grid-like network problem generator - glp_read_maxflow read maximum flow problem data in DIMACS - format - glp_write_maxflow write maximum flow problem data in DIMACS - format - glp_maxflow_lp convert maximum flow problem to LP - glp_rmfgen Goldfarb's maximum flow problem generator - - For detailed description of these new routines and related data - structures see chapter "Graph and Network API Routines" in a new - edition of the reference manual included in the distribution. - - A minor change were made in the internal routine xputc. Thanks - to Luiz Bettoni for suggestion. - - A minor bug was fixed in the internal routine mpl_fn_time2str. - Thanks to Stefan Vigerske for bug report. - -GLPK 4.34 (release date: Dec 04, 2008) - - The GNU MathProg modeling language was supplemented with three - new built-in functions: - - gmtime obtaining current calendar time - str2time converting character string to calendar time - time2str converting calendar time to character string - - (Thanks to Xypron .) - - For detailed description of these functions see Appendix A in - the document "Modeling Language GNU MathProg", a new edition of - which was included in the distribution. - - A bug was fixed in the MIP solver. Thanks to Nigel Galloway - for bug report. - - A new makefile was added to build the GLPK DLL with Microsoft - Visual Studio Express 2008 for 64-bit Windows. Thanks to Xypron - for contribution and testing. - -GLPK 4.33 (release date: Oct 30, 2008) - - The following new API routines were added to the package: - glp_copy_prob copy problem object content - glp_exact solve LP in exact arithmetic - (makes lpx_exact deprecated) - glp_get_unbnd_ray determine variable causing unboundedness - (makes lpx_get_ray_info deprecated) - glp_interior solve LP with interior-point method - (makes lpx_interior deprecated) - - The following new API routines for processing models written in - the GNU Mathprog language were added to the package: - glp_mpl_alloc_wksp allocate the translator workspace - glp_mpl_read_model read and translate model section - glp_mpl_read_data read and translate data section - glp_mpl_generate generate the model - glp_mpl_build_prob build LP/MIP instance from the model - glp_mpl_postsolve postsolve the model - glp_mpl_free_wksp deallocate the translator workspace - (These routines make lpx_read_model deprecated.) - - For description of all these new API routines see the reference - manual included in the distribution. - - A crude implementation of CPLEX-like interface to GLPK API was - added to the package. Currently it allows using GLPK as a core - LP solver for Concorde, a well known computer code for solving - the symmetric TSP. For details see examples/cplex/README. - - Some bugs were fixed in the SQL table driver. Thanks to Xypron - . - -GLPK 4.32 (release date: Oct 03, 2008) - - The following new features were included in the MIP solver - (the API routine glp_intopt): - - * MIP presolver - * mixed cover cut generator - * clique cut generator - * Euclidean reduction of the objective value - - Due to changes the routine glp_intopt may additionally return - GLP_ENOPFS, GLP_ENODFS, and GLP_EMIPGAP. - - The API routines lpx_integer are lpx_intopt are deprecated, - since they are completely superseded by glp_intopt. - - The following new branch-and-cut API routines were added: - glp_ios_row_attr determine additional row attributes - glp_ios_pool_size determine current size of the cut pool - glp_ios_add_row add constraint to the cut pool - glp_ios_del_row delete constraint from the cut pool - glp_ios_clear_pool delete all constraints from the cut pool - - For description of these new routines see the reference manual - included in the distribution. - - The stand-alone solver glpsol was changed to allow multiple - data files. - - A new edition of the supplement "Using Data Tables in the GNU - MathProg Modeling Language" was included. - - As usual, some bugs were fixed (in the MathProg translator). - Thanks to Xypron . - -GLPK 4.31 (release date: Sep 02, 2008) - - The core LP solver based on the dual simplex method was - re-implemented and now it provides both phases I and II. - - The following new API routines were added: - glp_scale_prob automatic scaling of problem data - glp_std_basis construct standard initial LP basis - glp_adv_basis construct advanced initial LP basis - glp_cpx_basis construct Bixby's initial LP basis - - For description of these new routines see the reference manual - included in the distribution. - - The following API routines are deprecated: - lpx_scale_prob, lpx_std_basis, lpx_adv_basis, lpx_cpx_basis. - - Necessary changes were made in memory allocation routines to - resolve portability issues for 64-bit platforms. - - New version of the routine lpx_write_pb to write problem data - in OPB (pseudo boolean format) was added to the package. Thanks - to Oscar Gustafsson for the contribution. - - Two new makefiles were added to build the package for 32- and - 64-bit Windows with Microsoft Visual Studio Express 2008. - Thanks to Heinrich Schuchardt (aka - Xypron) for the contribution and testing. - - Two new makefiles were added to build the package with Digital - Mars C/C++ 8.50 and Open Watcom C/C++ 1.6 (for 32-bit Windows). - -GLPK 4.30 (release date: Aug 13, 2008) - - The core LP solver based on the primal simplex method was - re-implemented to allow its further improvements. Currently the - new version provides the same features as the old one, however, - it is a bit faster and more numerically stable. - - Some changes were made in the MathProg translator to allow <, - <=, >=, and > on comparing symbolic values. Thanks to Heinrich - Schuchardt for patches. - - Internal routine set_d_eps in the exact LP solver was changed - to prevent approximation errors in case of integral data. - Thanks to Markus Pilz for bug report. - -GLPK 4.29 (release date: Jul 06, 2008) - - The configure script was changed to disable all optional - features by default. For details please see file INSTALL. - - The following new API routines were added: - glp_erase_prob erase problem object content - glp_read_mps read problem data in MPS format - glp_write_mps write problem data in MPS format - glp_read_lp read problem data in CPLEX LP format - glp_write_lp write problem data in CPLEX LP format - - For description of these new routines see the reference manual - included in the distribution. - - The following API routines are deprecated: - lpx_read_mps, lpx_read_freemps, lpx_write_mps, - lpx_write_freemps, lpx_read_cpxlp, and lpx_write_cpxlp. - - Two bugs were fixed. Thanks to - Anne-Laurence Putz and - Xypron for bug report. - -GLPK 4.28 (release date: Mar 25, 2008) - - The iODBC and MySQL table drivers, which allows transmitting - data between MathProg model objects and relational databases, - were re-implemented to replace a static linking by a dynamic - linking to corresponding shared libraries. - Many thanks to Heinrich Schuchardt - for the contribution, Rafael Laboissiere - for useful advices concerning the shared library support under - GNU/Linux, and Vijay Patil for testing - this feature under Windows XP. - - A new optional feature was added to the package. This feature - is based on the zlib data compression library and allows GLPK - API routines and the stand-alone solver to read and write - compressed data files performing compression/decompression "on - the fly" (compressed data files are recognized by suffix `.gz' - in the file name). It may be useful in case of large MPS files - to save the disk space (up to ten times). - - The `configure' script was re-implemented. Now it supports the - following specific options: - - --with-gmp Enable using the GNU MP bignum library - --without-gmp Disable using the GNU MP bignum library - --with-zlib Enable using the zlib data compression - library - --without-zlib Disable using the zlib data compression - library - --enable-dl Enable shared library support (auto check) - --enable-dl=ltdl Enable shared library support (GNU) - --enable-dl=dlfcn Enable shared library support (POSIX) - --disable-dl Disable shared library support - --enable-odbc Enable using ODBC table driver - --disable-odbc Disable using ODBC table driver - --enable-mysql Enable using MySQL table driver - --disable-mysql Disable using MySQL table driver - - For more details please see file INSTALL. - -GLPK 4.27 (release date: Mar 02, 2008) - - Three new table drivers were added to the MathProg translator: - - xBASE built-in table driver, which allows reading and writing - data in .dbf format (only C and N fields are supported); - - MySQL table driver, which provides connection to a MySQL - database; - - iODBC table driver, which provides connection to a database - through ODBC. - - The MySQL and iODBC table drivers were contributed to GLPK by - Heinrich Schuchardt . - - The table driver is a program module which allows transmitting - data between MathProg model objects and external data tables. - - For detailed description of the table statement and table - drivers see the document "Using Data Tables in the GNU MathProg - Modeling Language" (file doc/tables.txt) included in the - distribution. Some examples which demonstrate using MySQL and - iODBC table drivers can be found in subdirectory examples/sql. - -GLPK 4.26 (release date: Feb 17, 2008) - - The table statement was implemented in the GNU MathProg - modeling language. This new feature allows reading data from - external tables into model objects such as sets and parameters - as well as writing results of computations to external tables. - - A table is a (unordered) set of records, where each record - consists of the same number of fields, and each field is - provided with a unique symbolic name called the field name. - - Currently the GLPK package has the only built-in table driver, - which supports tables in the CSV (comma-separated values) file - format. This format is very simple and supported by almost all - spreadsheets and database management systems. - - Detailed description of the table statement and CSV format can - be found in file doc/tables.txt, included in the distribution. - -GLPK 4.25 (release date: Dec 19, 2007) - - A tentative implementation of Gomory's mixed integer cuts was - included in the branch-and-cut solver. To enable generating - Gomory's cuts the control parameter gmi_cuts passed to the - routine glp_intopt should be set to GLP_ON. This feature is - also available in the solver glpsol through command-line option - '--gomory'. For more details please see the reference manual - included in the distribution. - -GLPK 4.24 (release date: Nov 21, 2007) - - A tentative implementation of MIR (mixed integer rounding) cuts - was included in the MIP solver. To enable generating MIR cuts - the control parameter mir_cuts passed to the routine glp_intopt - should be set to GLP_ON. This feature is also available in the - stand-alone solver glpsol via command-line option '--mir'. For - more details please see the reference manual included in the - distribution. - - The implementation is mainly based on the following two papers: - - 1. H. Marchand and L. A. Wolsey. Aggregation and mixed integer - rounding to solve MIPs. CORE discussion paper 9839, CORE, - Universite catholique de Louvain, June 1998. - - 2. G. Andreello, A. Caprara, and M. Fischetti. Embedding cuts - in a Branch&Cut framework. Preliminary draft, October 2003. - - MIR cuts can be generated on any level of the search tree that - makes the GLPK MIP solver to be a real branch-and-cut solver. - - A bug was fixed in the routine lpx_write_cpxlp. If a variable - x has upper bound and no lower bound, it should appear in the - bounds section as "-inf <= x <= u", not as "x <= u". Thanks to - Enric Rodriguez for the bug report. - -GLPK 4.23 (release date: Oct 28, 2007) - - The following new API routines were added: - - glp_read_sol read basic solution from text file - glp_write_sol write basic solution to text file - glp_read_ipt read interior-point solution from text file - glp_write_ipt write interior-point solution to text file - glp_read_mip read MIP solution from text file - glp_write_mip write MIP solution to text file - - For description of these routines and corresponding file - formats see Chapter "API Routines", Section "Utility routines" - in the reference manual included in the distribution. - - Advanced API routine glp_free_env was added. It may be used by - the application program to free all resources allocated by GLPK - routines. - - The following three new command-line options were added to the - solver glpsol: - - --mipgap tol set relative MIP gap tolerance - -r filename read solution from filename - -w filename write solution to filename - -GLPK 4.22 (release date: Sep 19, 2007) - - This is a maintainer release. - - A bug was fixed in the MIP preprocessor (ios_preprocess_node). - Thanks to Roberto Bagnara (Department of - Mathematics, University of Parma, Italy) for the bug report. - - A bug was fixed in the MIP preprocessor (col_implied_bounds), - due to which constraint coefficients with small magnitude could - lead to wrong implied bounds of structural variables. - - A similar bug was fixed in the routine reduce_bounds. - - A bug was fixed in the routines glp_set_mat_row and - glp_set_mat_col. (The bug appeared due to incorrect removing - zero elements from the row/column lists.) - - A bug was fixed in the API routines lpx_read_mps and - lpx_read_freemps, due to which bounds of type LI specified in - BOUNDS section were incorrectly processed. - - A call to standard function vsprintf was replaced by a call to - vsnprintf for security reasons. Many thanks to Peter T. Breuer - and Rafael Laboissiere . - -GLPK 4.21 (release date: Aug 28, 2007) - - Additional reasons for calling the callback routine used in the - MIP solver (glp_intopt) were introduced. Currently the following - reasons are supported: - - * request for subproblem selection - * request for preprocessing - * request for row generation - * request for heuristic solution - * request for cut generation - * request for branching - * better integer solution found - - A basic preprocessing component used to improve subproblem - formulations by tightening bounds of variables was included in - the MIP solver. Depending on the control parameter pp_tech - passed to the routine glp_intopt the preprocessing can be - performed either on the root level or on all levels (default) - or can be disabled. - - Backtracking heuristic used by default in the MIP solver was - changed to the "best local bound". - - For more details see Chapter "Advanced API routines", Section - "Branch-and-bound interface routines" in a new edition of the - reference manual included in the distribution. - -GLPK 4.20 (release date: Jul 26, 2007) - - API routine lpx_integer was replaced by API routine glp_intopt, - which provides equivalent functionality and additionally allows - the application to control the solution process by means of the - user-written callback routine, which is called by the solver at - various points of the branch-and-bound algorithm. Besides, the - new MIP solver allows generating "lazy" constraints and cutting - planes on all levels of the branch-and-bound tree, not only on - the root level. The routine lpx_integer is also still available - for the backward compatibility. - - The following new advanced API routines, which may be called - from the B&B callback routine, were included in the package: - - glp_ios_reason determine reason for calling callback - routine - glp_ios_get_prob access the problem object - glp_ios_tree_size determine size of the branch-and-bound tree - glp_ios_curr_node determine current active subproblem - glp_ios_next_node determine next active subproblem - glp_ios_prev_node determine previous active subproblem - glp_ios_up_node determine parent subproblem - glp_ios_node_level determine subproblem level - glp_ios_node_bound determine subproblem local bound - glp_ios_mip_gap compute relative MIP gap - glp_ios_heur_sol provide solution found by heuristic - glp_ios_terminate terminate the solution process - - For description of these routines see Chapter "Advanced API - routines", Section "Branch-and-bound interface routines" in a - new edition of the reference manual, which was included in the - distribution. - - Old version of the integer optimization suite (IOS) as well as - TSP solver tspsol based on it are no longer supported and were - removed from the package. - - A minor error in the MIP presolver was fixed; thanks to Graham - Rockwell for the bug report. - -GLPK 4.19 (release date: Jul 05, 2007) - - The principal change is upgrading to GPLv3. - - A serious bug in the routine glp_del_cols was fixed; thanks to - Cedric[FR] for the bug report. The bug - appeared because on deleting non-basic columns the basis header - remained valid, however, contained invalid (old) column ordinal - numbers. - - A new advanced API routine glp_mem_limit was added. - - The case GLP_EBOUND was added to the routine lpx_simplex. - Thanks to Cameron Kellough for the - bug report. - - An API routine lpx_write_pb to write the problem instance in - OPB (pseudo boolean) format format was added. Thanks to Oscar - Gustafsson for the contribution. - - Two new options --wpb and --wnpb were added to glpsol to write - the problem instance in OPB format. - -GLPK 4.18 (release date: Jun 25, 2007) - - The following new API routines were added: - - glp_set_rii set (change) row scale factor - glp_set_sjj set (change) column scale factor - glp_get_rii retrieve row scale factor - glp_get_sjj retrieve column scale factor - glp_simplex solve LP problem with the simplex method - (this routine replaces lpx_simplex, which is - also available for backward compatibility) - glp_init_smcp initialize simplex method control params - glp_bf_exists check if the basis factorization exists - glp_factorize compute the basis factorization - glp_bf_updated check if the basis factorization has been - updated - glp_get_bfcp retrieve basis factorization control params - glp_set_bfcp change basis factorization control params - glp_get_bhead retrieve the basis header information - glp_get_row_bind retrieve row index in the basis header - glp_get_col_bind retrieve column index in the basis header - glp_ftran perform forward transformation - glp_btran perform backward transformation - - For description of all these routines see a new edition of the - reference manual included in the distribution. - - Type names ulong_t and uldiv_t were changed to glp_ulong and - glp_uldiv to avoid conflicts with standard type names on some - platforms. Thanks to Boris Wirtz - for the bug report. - - Some new examples in the MathProg language were added. Thanks - to Sebastian Nowozin . - -GLPK 4.17 (release date: May 26, 2007) - - API routines glp_set_mat_row, glp_set_mat_col, and glp_load_mat - were modified to allow zero constraint coefficients (which are - not stored in the constraint matrix). Note that constraint - coefficients with duplicate row/column indices are not allowed. - - Another form of LP basis factorization was implemented in the - package. It is based on LU-factorization of an initial basis - and Schur complement to reflect changes in the basis. Currently - the implementation is incomplete and provides only updating the - factorization on replacing a column of the basis matrix. On API - level the user can set the control parameter LPX_K_BFTYPE to - choose between the folloiwng forms of LP basis factorization to - be used in the simplex method routines: - 1) LU + Forrest-Tomlin update; - 2) LU + Schur complement + Bartels-Golub update; - 3) LU + Schur complement + Givens rotation update. - The GLPK implementation is similar to LUSOL/LUMOD developed by - Michael A. Saunders. - - The user can choose the form of LP basis factorzation used by - the simplex method routines by specifying the folloiwng options - of glpsol: --luf, --cbg, --cgr. - -GLPK 4.16 (release date: May 05, 2007) - - A number of basic GLPK API routines, which now are in the - stable stable, were renamed to be prefixed with 'glp_'. Note - that all these routines are available via their old names - prefixed with 'lpx_' that keeps the downward compatibility with - older versions of the package. - - Three new GLPK API routines were added to the package: - glp_version, glp_term_hook, and glp_mem_usage; for more details - see a new edition of the GLPK reference manual included in the - distribution. The routine glp_version reports the actual version - of the GLPK library and also can be used (along with the header - glpk.h) in Autotools specification files to check if the GLPK - library has been installed. - - The header glpk.h was changed to conform to C++ environment. - -GLPK 4.15 (release date: Feb 18, 2007) - - Autotools specification files (configure.ac, Makefile.am) were - changed to use GNU Libtool. This allows building the static as - well as shared GLPK library. - -GLPK 4.14 (release date: Feb 05, 2007) - - Now GLPK conforms to ILP32, LLP64, and LP64 programming models - (the latter seems to be the ultimate choice regarding 64-bit - architectures). Note that GLPK itself is a 32-bit application, - and the conformity only means that the package works correctly - on all these arenae. Nevertheless, on 64-bit platforms it is - possible to use more than 4GB of memory, if necessary. - -GLPK 4.13 (release date: Nov 13, 2006) - - A tentative implementation of the "exact" simplex method based - on bignum (rational) arithmetic was included in the package. - - On API level this new feature is available through the routine - lpx_exact, which is similar to the routine lpx_simplex. - - In the solver glpsol this feature is available through two new - command-line options: --exact and --xcheck. If the '--exact' - option is specified, glpsol solves LP instance using the exact - simplex method; in case of MIP it is used to obtain optimal - solution of LP relaxation. If the --xcheck option is specified, - LP instance (or LP relaxation) is solved using the standard - (floating-point) simplex method, however, then glpsol calls the - exact simplex routine to make sure that the final LP basis is - exactly optimal, and if it is not, to perform some additional - simplex iterations in exact arithmetic. - -GLPK 4.12 (release date: Nov 08, 2006) - - A tentative implementation of some simplex method routines - based on exact (bignum) arithmetic was included in the package. - Currently these routines provide computing LU-factorization of - the basis matrix and computing components of basic solution. - - These routines were used to implement a routine, which checks - primal and dual feasibility of basic solution exactly, i.e. in - rational numbers, without round-off errors. In glpsol this - feature is available through the command-line option --xcheck. - - GLPK has its own low-level routines implementing operations on - integer and rational numbers that makes it independent on other - software packages. However, to attain a much better performance - it is highly recommended to install (before configuring GLPK) - the GNU Multiple Precision Arithmetic Library (GMP). Using GMP - makes computations 100-200 times faster. - -GLPK 4.11 (release date: Jul 25, 2006) - - Three new built-in functions in the modeling language were - implemented: card (cardinality of set), length (length of - character string), and substr (substring of character string). - Another improvement concerns the printf statement which now - allows redirecting its output to a specified file. These new - features are illustrated in example models crypto.mod and - graph.mod included in the distribution. For more details see - the document "Modeling Language GNU MathProg". - - Four batch files (along with corresponding makefiles) were - included in the distribution to simplify building GLPK under - MS Windows; see them in subdirectory 'w32'. - -GLPK 4.10 (release date: May 11, 2006) - - Cutting planes of two new classes were implemented: mixed cover - cuts and clique cuts. On API level this feature can be enabled - by setting control parameter LPX_K_USECUTS passed to the routine - lpx_intopt. In glpsol this feature is available through the - command-line options --cover and --clique. For more details see - the reference manual. - - Now the routines lpx_read_mps and lpx_read_freemps support LI - bound type. It is similar to LO, however, indicates the column - as of integer kind. - -GLPK 4.9 (release date: Jan 17, 2006) - - An advanced MIP solver was implemented. It includes: - - - basic presolving technique (removing free, singleton and - redundant rows, improving bounds of columns, removing fixed - columns, reducing constraint coefficents); - - - generating cutting planes to improve LP relaxation (currently - only Gomory's mixed integer cuts are implemented); - - - using the branch-and-bound method to solve resultant MIP; - - - recovering solution of the original MIP. - - The solver is available on API level via the routine lpx_intopt - (see the reference manual). It is similar to the routine - lpx_integer, however, does not require initial solution of LP - relaxation. - - The solver is also available in the command-line utility glpsol - via two options: --intopt (only presolving) and --cuts (assumes - --intopt plus generating cuts). - - Note that efficiency of the MIP solver strongly depends on the - internal structure of the problem to be solved. For some hard - instances it is very efficient, but for other instances it may - be significantly worse than the standard branch-and-bound. - - For some comparative benchmarks see doc/bench1.txt. - - Well, what else... - - Three built-in functions were added to MathProg: sin, cos, and - atan (the latter allows one or two arguments). - - Some bugs were fixed. - - Several new examples in MathProg were included: color.mod - (graph coloring problem), tsp.mod (traveling salesman problem), - and pbn.mod (paint-by-numbers puzzle). - -GLPK 4.8 (release date: Jan 12, 2005) - - Core simplex method and interior-point method routines were - re-implemented and now they use a new, "storage-by-rows" sparse - matrix format (unlike previous versions where linked lists were - used to represent sparse matrices). For details see ChangeLog. - - Also a minor bug was fixed in API routine lpx_read_cpxlp. - -GLPK 4.7 (release date: Aug 23, 2004) - - Now GLPK supports free MPS format. Two new API routines - lpx_read_freemps (to read problem data in free MPS format) and - lpx_write_freemps (to write problem data in free MPS format) - were added. This feature is also available in the solver glpsol - via new command-line options --freemps and --wfreemps. For more - details see the GLPK reference manual. - - API routines lpx_read_cpxlp and lpx_write_cpxlp for reading and - writing problem data in CPLEX LP format were re-implemented to - allow long symbolic names (up to 255 characters). - - The following three modules were temporarily removed from the - GLPK distribution due to licensing problems: DELI (an interface - module to Delphi), GLPKMEX (an interface module to Matlab), and - JNI (an interface module to Java). - -GLPK 4.6 (release date: Aug 04, 2004) - - Three new statements were implemented in the GNU MathProg - language: solve, printf, and for. Their detailed description can - be found in the GLPK documentation included in the distribution. - (See also a sample model, examples/queens.mod, which illustrates - using these new statements.) - - Two new API routines were added to the package: lpx_read_prob - and lpx_write_prob. They allow reading/writing problem data in - GNU LP low-level text format. - - Three new command-line options were implemented in the LP/MIP - solver glpsol: --glp (to read problem data in GNU LP format), - --wglp (to write problem data in GNU LP format), and --name (to - change problem name). Now glpsol also supports processing models - where the new statements (see above) are used. - - A new version of GLPKMEX, a Matlab MEX interface to GLPK, was - included. For more details see contrib/glpkmex/ChangeLog. - -GLPK 4.5 (release date: Jul 19, 2004) - - The branch-and-bound solver was completely re-implemented. - - Some modifications were made in memory allocation routines that - allows using the package on 64-bit platforms. - - For more details see ChangeLog. - -GLPK 4.4 (release date: Jan 17, 2004) - - All API routines were re-implemented using new data structures. - The new implementation provides the same specifications and - functionality of API routines as the old one, however, it has - some important advantages, in particular: - * linked lists are used everywhere that allows creating and - modifying the problem object as efficiently as possible - * all data stored in the problem object are non-scaled (even if - the internal scaling is used) that prevents distortion of the - original problem data - * solution components obtained by the solver remain available - even if the problem object has been modified - * no solver-specific data are used in the new data structures - that allows attaching any external lp/mip solver using GLPK - API as an uniform interface - Note that some API routines became obsolete being replaced by - new, more convenient routines. These obsolete routines are kept - for backward compatibility, however, they will be removed in - the future. For more details please see ChangeLog and the GLPK - Reference Manual. - - New edition of the GLPK Reference Manual was included in the - distribution. - - GLPKMEX, a Matlab MEX interface to GLPK package, contributed by - Nicolo Giorgetti was included in the - distribution. - - GLPK FAQ contributed by Harley Mackenzie was - included in the distribution. - -GLPK 4.3 (release date: Dec 12, 2003) - - The bug, due to which the standard math library is not linked - on building the package on some platforms, was fixed. - - The following new built-in functions were added to the MathProg - language: round, trunc, Irand224, Uniform01, Uniform, Normal01, - Normal. For details see the language description. - - The MathProg syntax was changed to allow writing 'subj to' that - means 'subject to'. - - The new api routine lpx_get_ray_info was added. It is intended - to determine which (non-basic) variable causes unboundness. For - details see the reference manual. - - The module glpmps.c was changed to avoid compilation errors on - building the package on Mac OS X. - - Several typos was fixed and some new material was added to the - GLPK documentation. - -GLPK 4.2 (release date: Nov 14, 2003) - - A preliminary implementation of the Integer Optimization Suite - (IOS) was included in the package. The Branch-and-Cut Framework - being completely superseded by IOS was removed from the package. - - New API routine lpx_print_sens_bnds intended for bounds - sensitivity analysis was contributed to GLPK by Brady Hunsaker - . This function is also available in - the solver glpsol (via command-line option --bounds). - - An improved version of GLPK JNI (Java Native Interface) was - contributed by Chris Rosebrugh . - - GLPK DELI (Delphi Interface) was contributed by Ivo van Baren - . - - Several makefiles were added to allow compiling GLPK on some - non-GNU 32-bit platforms: - * Windows single-threaded static library, Visual C++ 6.0 - * Windows multi-threaded dynamic library, Visual C++ 6.0 - * Windows single-threaded static library, Borland C++ 5.2 - * DOS single-threaded static library, Digital Mars C++ 7.50 - - And, of course, some bugs were fixed. - - For more details see ChangeLog. - -GLPK 4.1 (release date: Aug 23, 2003) - - Some improvements were made in the lp/mip solver routines and - several bugs were fixed in the model translator. - - For more details see ChangeLog. - -GLPK 4.0 (release date: May 06, 2003) - - Now GLPK supports the GNU MathProg modeling language, which is - a subset of the AMPL modeling language. - - The document "GLPK: Modeling Language GNU MathProg" included in - the distribution is a complete description of GNU MathProg. (See - the files lang.latex, lang.dvi, and lang.ps in the subdirectory - 'doc'. See also some examples in the subdirectory 'sample'.) - - New version of the solver glpsol, which supports models written - in GNU MathProg, was implemented. (Brief instructions how to use - glpsol can be found in the GNU MathProg documentation.) - - The GLPK/L modeling language is no more supported. The reason is - that GNU MathProg being much more powerful completely supersedes - all features of GLPK/L. - -GLPK 3.3 (release date: Mar 25, 2003) - - LP PRESOLVER - ------------ - - Now the routine lpx_simplex (which is a driver to the simplex - method for solving LP) is provided with the built-in LP - presolver, which is a program that transforms the original LP - problem to an equivalent LP problem, which may be easier for - solving with the simplex method than the original one. Once the - transformed LP has been solver, the presolver transforms its - basic solution back to a corresponding basic solution of the - original problem. For details about this feature please see the - GLPK reference manual. - - Currently the LP presolver implements the following features: - * removing empty rows; - * removing empty columns; - * removing free rows; - * removing fixed columns; - * removing row singletons, which have the form of equations; - * removing row singletons, which have the form of inequalities; - * removing column singletons, which are implied slack variables; - * fixing and removing column singletons, which are implied free - variables; - * removing forcing rows that involves fixing and removing the - corresponding columns; - * checking for primal and dual infeasibilities. - - The LP presolver is also used by default in the stand-alone - program glpsol. In order *not* to use it, the option --nopresol - should be specified in the command-line. - - CHANGES IN GLPK/L - ----------------- - - The syntax and semantics of the GLPK/L modeling language was - changed to allow declaration of "interval" sets. This means that - now the user can declare a set, for example, as: - - set task = [8:11]; - - that is exactly equivalent to the following declaration: - - set task = (task_8, task_9, task_10, task_11); - - For details see the language description. - - JAVA INTERFACE - -------------- - - Now GLPK includes the package GLPK JNI (Java Native Interface) - that implements Java binding for GLPK. It allows Java programs - to utilize GLPK in solving LP and MIP problems. For details see - a brief user's guide in the subdirectory contrib/java-binding. - This package was developed and programmed by Yuri Victorovich - , who contributed it to GLPK. - -GLPK 3.2.4 (release date: Feb 18, 2003) - - This is a bug-fix release. For details see ChangeLog. - -GLPK 3.2.3 (release date: Nov 11, 2002) - - A new implementation of the api routine lpx_integer which now - is based on the b&b driver (which is based on the implicit - enumeration suite) was included in the package. This new - implementation has exactly the same functionality as the old - version, so all changes are transparent to the api user. - - Four new api routines were included in the package: - lpx_check_kkt checks Karush-Kuhn-Tucker optmality conditions; - lpx_read_bas reads predifined basis in MPS format; - lpx_write_bas writes current basis in MPS format; - lpx_write_lpt writes problem data in CPLEX LP format. - - Also other minor improvements were made (for details see the - file 'ChangeLog'). - -GLPK 3.2.2 (release date: Oct 14, 2002) - - The api routine lpx_read_lpt was included in the package. It - is similar to the routine lpx_read_mps and intended to read - LP/MIP data prepared in CPLEX LP format. Description of this - format is given in the GLPK reference manual, a new edition of - which was also included in the distribution (see the files - 'refman.latex', 'refman.dvi', 'refman.ps' in the subdirectory - 'doc'). In order to use data files in CPLEX LP format with the - solver glpsol the option '--lpt' should be specified in the - command line. - - Several bugs were fixed and some minor improvements were made - (for details see the file 'ChangeLog'). - -GLPK 3.2.1 (release date: Aug 12, 2002) - - Now GLPK includes a preliminary implementation of the - branch-and-cut framework, which is a set of data structures and - routines intended for developing branch-and-cut methods for - solving mixed-integer and combinatorial optimization problems. - - Detailed decsription of the branch-and-cut framework is given in - the document "GLPK: A Preliminary Implementation of the - Branch-And-Cut Framework" included in the distribution (see the - file 'brcut.txt' in the subdirectory 'doc'). - - In order to illustrate how the GLPK branch-and-cut framework - can be used for solving a particular optimization problem there - is an example included in the package. This is a stand-alone - program, TSPSOL, which is intended for solving to optimality the - symmetric Traveling Salesman Problem (TSP), a classical problem - of the combinatorial optimization (see the file 'tspsol.c' in - the subdirectory 'sample'). - -GLPK 3.2 (release date: Jul 15, 2002) - - New edition of the document "GLPK: Reference Manual" was - included (see the files 'refman.latex', 'refman.dvi', and - 'refman.ps' in the subdirectory 'doc'). - - New edition of the document "GLPK: Modeling Language GLPK/L" was - included (see the files 'lang.latex', 'lang.dvi', and 'lang.ps' - in the subdirectory 'doc'). - - The following new API routines were added to the package: - - lpx_transform_row (transform explicitly specified row); - lpx_transform_col (transform explicitly specified column); - lpx_prim_ratio_test (perform primal ratio test); - lpx_dual_ratio_test (perform dual ratio test); - lpx_interior (solve LP problem using interior point method); - lpx_get_ips_stat (query status of interior point solution); - lpx_get_ips_row (obtain row interior point solution); - lpx_get_ips_col (obtain column interior point solution); - lpx_get_ips_obj (obtain interior point value of obj.func.); - lpx_read_lpm (read LP/MIP model written in GLPK/L); - lpx_write_mps (write problem data using MPS format); - lpx_print_ips (print interior point solution). - - Detailed description of all these new API routines are given in - the new edition of the reference manual. - - New version of the stand-alone solver glpsol (which is based on - the new API) was implemented. - - So long as the new API (introduced in glpk 3.0) now provides - all the functions, which were provided by the old API, the old - API routines were removed from the package at all. - -GLPK 3.1 (release date: May 27, 2002) - - A preliminary implementation of new API routines was completed - and included in the package. - - These new API routines provide much more flexible interaction - between the application program, LP/MIP problem instances, and - solver routines. Based on completely changed data structures - they are, however, similar to the API routines and provide the - same functionality. Please note that three routines, namely, - solving LPs using interior point method, reading model written - in the GLPK/L modeling language, and writing problem data in - the MPS format, are not implemented in the new API, however, - these routines are planned to be implemented in the next version - of the package. - - A description of the new API routines is given in the document - "GLPK Reference Manual", a draft edition of which is included - in the package (see the files 'refman.latex', 'refman.dvi', and - 'refman.ps' in the subdirectory 'doc'). - - Although the old API routines are kept in the package, they are - no longer supported and will be removed in the future. - -GLPK 3.0.8 (release date: May 13, 2002) - - A preliminary implementation of new API routines was included - in the package. These new API routines are intended to provide - much more flexible interaction between the application program, - LP/MIP problem and solver routines. See the document "New GLPK - API Routines" (the file 'newapi.txt' in the subdirectory 'doc') - also included in the package. - - The api routines glp_simplex2, glp_call_ipm1, glp_call_bbm1 were - renamed, respectively, to glp_simplex, glp_interior, glp_integer - in order to reflect changes in implementation. The api routines - glp_call_rsm1, glp_simplex1, glp_pivot_in, glp_pivout_out were - removed from the package since they are completely supreseded by - the new API routines (however, these routines still can be found - in the subdirectory 'oldsrc'). Please consult a new edition of - the document "GLPK User's Guide" about all these changes in the - existing api routines. - - The document "GLPK Library Reference" was removed from the - package (into the subdirectory 'oldsrc') since it describes the - obsolete library routines, most of which are no longer used. - -GLPK 3.0.7 (release date: Apr 22, 2002) - - A new, more efficient implementation of the primal/dual simplex - method was included in the package. Due to some improvements the - simplex-based solver allows solving many LP problems faster and - provides more reliable results. Note that the new implementation - is currently incomplete and available only via the api routine - glp_simplex2. - - All the changes are transparent on API level. - -GLPK 3.0.6 (release date: Mar 28, 2002) - - New version of LU-factorization and basis maintenance routines - (based on Forrest-Tomlin updating technique) was implemented. - Since these new routines functionally supersede some routines - (which implement other forms of the basis matrix) and make them - obsolete, the latter were removed from the package (they still - can be found in the subdirectory 'oldsrc'). - - All the changes are transparent on API level. - -GLPK 3.0.5 (release date: Jan 29, 2002) - - New edition of the document "GLPK User's Guide" was included in - the distribution. Now it describes all additional API routines, - which were recently added to the package. - - Structure of the package was re-organized in order to make its - maintenance easier (all small files in the subdurectory 'source' - were merged in bigger units). These changes are transparent for - the user. - -GLPK 3.0.4 (release date: Dec 10, 2001) - - A new, more efficient implementation of the two-phase primal - simplex method was included in the package. Due to some new - features (an advanced initial basis, projected steepest edge, - recursive updating values and reduced costs) the new LP solver - is faster and numerically more stable than the old one. - - The new LP solver is available as API routine glp_simplex2 and - has the same purpose as API routine glp_call_rsm1. For detailed - specification see the file 'newapi.txt' in the directory 'doc'. - - Now the new LP solver is also used by default to solve an - initial LP problem in the branch-and-bound routine glp_call_bbm1 - instead the routine rsm1_driver. Note that the branch-and-bound - procedure itself is still based on rsm1_driver. - - The new LP solver is also used as default solver in GLPSOL for - solving LP and MIP problems. In order to choose the old solver - the option '--old-sim' can be specified in the command line. - -GLPK 3.0.3 (release date: Oct 03, 2001) - - Some minor changes were made in the simplex method routines in - order to improve numerical stability of the method. - -GLPK 3.0.2 (release date: Sep 24, 2001) - - A new implementation of the basis maintaining routines was - included in the package. These routines, which are based on so - called FHV-factorization (a variety of LU-factorization) of the - basis matrix and Gustavson's data structures, allows performing - the main operations faster at the expense of some worsening - numerical accuracy. - - AFI (Advanced Form of the Inverse), which is the form of the - basis matrix based on FHV-factorization, is available via the - parameter form = 3 (on API level) or via the option --afi (in - GLPSOL solver). - -GLPK 3.0.1 (release date: Aug 01, 2001) - - Old GLPK API routines have been removed from the package. - - New GLPK API routines were added: - - - scaling routines; - - - a routine for writing problem data in MPS format; - - - a comprehensive driver to the simplex method; - - - basis maintaining routines. - - A description of the new API routines is given in the document - "Additional GLPK API Routines". This document is included into - the distribution in plain text format (see the file 'newapi.txt' - in the subdirectory 'doc'). - - Now the distribution includes a non-trivial example of using - GLPK as a base LP solver for Concorde, a well known program that - solves Traveling Salesman Problem (TSP). For further details see - comments in the file 'sample/lpglpk30.c'. - -GLPK 3.0 (release date: Jul 19, 2001) - - Now GLPK is provided with new API, which being more flexible - can be used in more complex algorithmic schemes. - - New edition of the document "GLPK User's Guide" is included in - the distribution. Now it completely corresponds to the new GLPK - API routines. - - Old API routines are not removed yet from the package, however - they became obsolete and therefore should not be used. Since now - the header glpk.h corresponds to new API, in order to compile - existing programs that use old GLPK API routines the statement - - #define GLP_OLD_API - - should be inserted before the statement - - #include "glpk.h" - -GLPK 2.4.1 (release date: Jun 14, 2001) - - The document "Modeling language GLPK/L" is included into the - distribution in texinfo format. - - New edition of the document "GLPK User's Guide" is included in - the distribution. Now it describes all additional API routines - which were recently added to the package. - -GLPK 2.4 (release date: May 10, 2001) - - Now GLPK includes an implementation of a preliminary version - of the GLPK/L modeling language. This language is intended for - writing mathematcal programming models. The name GLPK/L is - derived from GNU Linear Programming Kit Language. - - A brief description of the GLPK/L language is given in the - document "GLPK/L Modeling Language: A Brief Description". This - document is included into the distribution in plain text format - (see the file 'language.txt' in the subdirectory 'doc'). - - The language processor (which is a program that analyzes model - description written in GLPK/L and translates it to internal data - structures) is available as the GLPK API routine. - - The stand-alone solver GLPSOL now is able: a) to process model - descriptions written in the GLPK/L language; b) to solve pure LP - problems using the interior point method (therefore the program - GLPIPM was removed from the package). - -GLPK 2.3 (release date: Apr 09, 2001) - - New edition of the document "GLPK User's Guide" is included in - the distribution. Now it describes all additional API routines - which were recently added to the package. - - The MIP solver was fully re-programmed in order to improve its - robustness and performance. In particular, a basis recovering - procedure was implemented (this procedure allows switching to - the primal simplex method in case when the dual simplex method - fails). - -GLPK 2.2 (release date: Mar 15, 2001) - - Now GLPK includes a tentative implementation of the - branch-and-bound procedure based on the dual simplex method for - mixed integer linear programming (MIP). - - Complete description of this new feature of the package is given - in the preliminary document "Mixed Integer Linear Programming - Using GLPK Version 2.2 (Supplement to GLPK User's Guide)". This - document is included into the distribution in plain text format - (see the file 'mip.txt' in the subdirectory 'doc'). - - The MIP solver (glp_integer) can be used as GLPK API routine in - the same way as the pure LP solver (glp_simplex). - - The stand-alone program 'glpsol' is now able to solve LP as well - as MIP problems. - - Note that the current version of GLPK MIP solver is based on - easiest heuristics for branching and backtrackng. Therefore the - solver is fit mainly for MIP problems which are not very hard - and have few integer variables. - -GLPK 2.1 (release date: Feb 19, 2001) - - The document "GLPK Implementation of the Revised Simplex Method" - is included into the distribution. This document describes most - of routines related to the revised simplex method. - -GLPK 2.0 (release date: Jan 25, 2001) - - Now GLPK includes a tentative implementation of the primal-dual - interior point method for large-scale linear programming. - - The interior point solver can be used as GLPK API routine in the - same manner as the simplex method solver (glp_simplex): - - ret = glp_interior(); - - Note that currently the interior point solver implemented in - GLPK doesn't include many important features, in particular: - - * it can't process dense columns; therefore if the problem has - dense columns, the solving will be extremely inefficient; - - * it has no special features against numerical unstability; - some problems may cause premature termination of the solving - when the matrix A*D*A' becomes ill-conditioned; - - * it computes only values of primal (auxiliary and structural) - variables and doesn't compute values of dual variables (i.e. - reduced costs) which are just set to zero; - - * it doesn't identify optimal basis corresponding to the found - interior point solution; all variables in the found solution - are just marked as basic variables. - - GLPK also includes a stand-alone program 'glpipm' which is a - demo based on the interior point method. It may be used in the - same way as the program 'glpsol' that is based on the simplex - method. diff --git a/resources/3rdparty/glpk-4.53/README b/resources/3rdparty/glpk-4.53/README deleted file mode 100644 index 2e7feb08b..000000000 --- a/resources/3rdparty/glpk-4.53/README +++ /dev/null @@ -1,39 +0,0 @@ - Olga K. gewidmet - -GLPK (GNU Linear Programming Kit) Version 4.53 - -Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -2009, 2010, 2011, 2013, 2014 Andrew Makhorin, Department for Applied -Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -reserved. E-mail: . - -GLPK is part of the GNU Project released under the aegis of GNU. - -GLPK is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at your -option) any later version. - -See the file COPYING for the GNU General Public License. - -See the file INSTALL for compilation and installation instructions. - -The GLPK package is a set of routines written in ANSI C and organized -in the form of a callable library. This package is intended for solving -large-scale linear programming (LP), mixed integer linear programming -(MIP), and other related problems. - -The GLPK package includes the following main components: - -* implementation of the simplex method; -* implementation of the exact simplex method based on bignum (rational) - arithmetic; -* implementation of the primal-dual interior-point method; -* implementation of the branch-and-cut method; -* application program interface (API); -* GNU MathProg modeling language (a subset of AMPL); -* GLPSOL, a stand-alone LP/MIP solver. - -See GLPK webpage . - -Please report bugs to . diff --git a/resources/3rdparty/glpk-4.53/THANKS b/resources/3rdparty/glpk-4.53/THANKS deleted file mode 100644 index 6cbd95613..000000000 --- a/resources/3rdparty/glpk-4.53/THANKS +++ /dev/null @@ -1,204 +0,0 @@ -Achim Gaedke for bug report. - -Alexandre Oliva for bug report. - -Andre Girard for bug report. - -Andrew Hamilton-Wright for bug report. - -Andrew Hood for bug report. - -Anne-Laurence Putz for bug -report. - -Axel Simon for bug report. - -Bernhard Schmidt for bug report. - -Boris Wirtz for bug report. - -Brady Hunsaker for contribution of a routine -for bounds sensitivity analysis. - -Brady Hunsaker for some suggestions concerning -MIP routines. - -Cameron Kellough for bug report. - -Carlo Baldassi for bug report. - -Cedric[FR] for bug report. - -Charles Brixko for bug report. - -Chris Rosebrugh for contribution of a new version of -GLPK JNI (Java Native Interface). - -Christophe Caron for bug report. - -David T. Price for bug report. - -Dennis Schridde for bug report. - -Enric Rodriguez for bug report. - -Flavio Keidi Miyazawa for bug report. - -Gabriel Hackebeil for bug report. - -Giles Thompson for bug report. - -Giorgio Sartor <0gioker0@gmail.com> for contribution of routines that -implement the proximity search heuristic for MIP. - -Graham Rockwell for bug report. - -Hans Schwengeler for bug report. - -Harley Mackenzie for contribution of GLPK FAQ. - -Dr. Harley Mackenzie for two example MathProg -models (curve fitting problem). - -Heinrich Schuchardt for contribution of -makefiles and testing the package under 64-bit Windows. - -Heinrich Schuchardt for contribution of -two MathProg table drivers for iODBC and MySQL. - -Heinrich Schuchardt for some patches for -the MathProg translator. - -Heinrich Schuchardt for testing the package on -32- and 64-bit MS Windows platforms. - -Ivan Luzzi for comments concerning CPLEX LP format. - -Ivo van Baren for contribution of GLPK DELI -(Delphi Interface). - -Jan Engelhardt for some suggestions. - -Jeffrey Kantor for reporting typos in the MathProg -language reference. - -Jiri Spitz for bug report. - -Joey Rios for some suggestions. - -Jonathan Senning for bug report. - -Karel Zimmermann for bug report. - -Kelly Westbrooks for suggestions. - -Kendall Demaree for bug report. - -Kjell Eikland for bug report. - -Larry D'Agostino for example model in -MathProg. - -Luiz Bettoni for some suggestions. - -Marco Atzeri for bug report. - -Marco Atzeri for bug report. - -Markus Pilz for bug report. - -Minh Ha Duong for fixing doc typos. - -Morten Welinder for bug report. - -Morten Welinder for bug report. - -Nelson H. F. Beebe for bug report. - -Nicolo Giorgetti for contribution of GLPKMEX, -a Matlab MEX interface. - -Niels Klitgord for bug report. - -Nigel Galloway for an example MathProg -model. - -Nigel Galloway for an example program -in C#. - -Nigel Galloway for bug report. - -Nigel Galloway for example models in -MathProg. - -Noli Sicad for testing glpk under Mac OS. - -Noli Sicad for example model in MathProg. - -Olivier for bug report. - -Oscar Gustafsson for contribution of a routine to -write data in OPB (pseudo boolean) format. - -Peter T. Breuer for bug report. - -Peter A. Huegler for bug report. - -Peter Ingerfeld for bug report. - -Peter Lee for example LP model and bug report. - -Pietro Scionti for report typos found in -the reference manual. - -Rafael Laboissiere for useful advices concerning -shared library support under GNU/Linux. - -Raniere Gaia Costa da Silva for bug report. - -Robbie Morrison for correcting the glpk manual. - -Robert Wood for example model in MathProg. - -Roberto Bagnara (Department of Mathematics, -University of Parma, Italy) for bug report. - -Sami Farin for bug report. - -Sebastian Nowozin for example models in MathProg. - -Sebastien Briais for bug report. - -Sebastien de Menten for bug report. - -Sebastien Villemot for bug report. - -Stefan Vigerske for bug report. - -Stefan Vigerske for bug report. - -Sylvain Fournier for bug report. - -Thomas Kahle for some suggestions. - -Uday Venkatadri for bug report. - -Vijay Patil for testing the package under -Windows XP. - -Vlahos Kiriakos for bug report. - -Xypron for bug fixing and some improvments in the -FPUMP module. - -Xypron for bug patch. - -Xypron for contribution and testing batch scripts -to build Glpk with MS Visual Studio 2010. - -Xypron for improving the SQL table driver. - -Xypron for testing GLPK on 64-bit platforms and -for maintaining Windows versions of the package. - -Yuri Victorovich for contribution of GLPK Java binding. diff --git a/resources/3rdparty/glpk-4.53/aclocal.m4 b/resources/3rdparty/glpk-4.53/aclocal.m4 deleted file mode 100644 index 636b7ac2f..000000000 --- a/resources/3rdparty/glpk-4.53/aclocal.m4 +++ /dev/null @@ -1,949 +0,0 @@ -# generated automatically by aclocal 1.12.5 -*- Autoconf -*- - -# Copyright (C) 1996-2012 Free Software Foundation, Inc. - -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, -[m4_warning([this file was generated for autoconf 2.69. -You have another version of autoconf. It may work, but is not guaranteed to. -If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically 'autoreconf'.])]) - -# Copyright (C) 2002-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -# (This private macro should not be called outside this file.) -AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.12' -dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to -dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.12.5], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl -]) - -# _AM_AUTOCONF_VERSION(VERSION) -# ----------------------------- -# aclocal traces this macro to find the Autoconf version. -# This is a private macro too. Using m4_define simplifies -# the logic in aclocal, which can simply ignore this definition. -m4_define([_AM_AUTOCONF_VERSION], []) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. -# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.12.5])dnl -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to -# '$srcdir', '$srcdir/..', or '$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is '.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[dnl Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50])dnl -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ([2.52])dnl - m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE])dnl -AC_SUBST([$1_FALSE])dnl -_AM_SUBST_NOTMAKE([$1_TRUE])dnl -_AM_SUBST_NOTMAKE([$1_FALSE])dnl -m4_define([_AM_COND_VALUE_$1], [$2])dnl -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - -# Copyright (C) 1999-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - - -# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], - [$1], [CXX], [depcc="$CXX" am_compiler_list=], - [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], - [$1], [UPC], [depcc="$UPC" am_compiler_list=], - [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - am__universal=false - m4_case([$1], [CC], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac], - [CXX], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac]) - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES. -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE([dependency-tracking], [dnl -AS_HELP_STRING( - [--enable-dependency-tracking], - [do not reject slow dependency extractors]) -AS_HELP_STRING( - [--disable-dependency-tracking], - [speeds up one-time build])]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH])dnl -_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl -AC_SUBST([am__nodep])dnl -_AM_SUBST_NOTMAKE([am__nodep])dnl -]) - -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[{ - # Autoconf 2.62 quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.62])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[AC_DIAGNOSE([obsolete], -[$0: two- and three-arguments forms are deprecated. For more info, see: -http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_INIT_AUTOMAKE-invocation]) -m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl -dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if( - m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), - [ok:ok],, - [m4_fatal([AC_INIT should be called with package and version arguments])])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) - AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) -AM_MISSING_PROG([AUTOCONF], [autoconf]) -AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) -AM_MISSING_PROG([AUTOHEADER], [autoheader]) -AM_MISSING_PROG([MAKEINFO], [makeinfo]) -AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES([CC])], - [m4_define([AC_PROG_CC], - m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES([CXX])], - [m4_define([AC_PROG_CXX], - m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES([OBJC])], - [m4_define([AC_PROG_OBJC], - m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl -dnl Support for Objective C++ was only introduced in Autoconf 2.65, -dnl but we still cater to Autoconf 2.62. -m4_ifdef([AC_PROG_OBJCXX], -[AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], - [_AM_DEPENDENCIES([OBJCXX])], - [m4_define([AC_PROG_OBJCXX], - m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])])dnl -]) -_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl -dnl The 'parallel-tests' driver may need to know about EXEEXT, so add the -dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro -dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. -AC_CONFIG_COMMANDS_PRE(dnl -[m4_provide_if([_AM_COMPILER_EXEEXT], - [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl -]) - -dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not -dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further -dnl mangled by Autoconf and run in a shell conditional statement. -m4_define([_AC_COMPILER_EXEEXT], -m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_arg=$1 -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi -AC_SUBST([install_sh])]) - -# Copyright (C) 2003-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MAKE_INCLUDE() -# ----------------- -# Check to see how make treats includes. -AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([missing])dnl -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - AC_MSG_WARN(['missing' script is too old or missing]) -fi -]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# -------------------- -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) - -# _AM_SET_OPTIONS(OPTIONS) -# ------------------------ -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[[\\\"\#\$\&\'\`$am_lf]]*) - AC_MSG_ERROR([unsafe absolute working directory name]);; -esac -case $srcdir in - *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken - alias in your environment]) - fi - if test "$[2]" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT([yes]) -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi -AC_CONFIG_COMMANDS_PRE( - [AC_MSG_CHECKING([that generated files are newer than configure]) - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - AC_MSG_RESULT([done])]) -rm -f conftest.file -]) - -# Copyright (C) 2001-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor 'install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in "make install-strip", and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Copyright (C) 2006-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) - -# AM_SUBST_NOTMAKE(VARIABLE) -# -------------------------- -# Public sister of _AM_SUBST_NOTMAKE. -AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004-2012 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of 'v7', 'ustar', or 'pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AC_SUBST([AMTAR], ['$${TAR-tar}']) -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of '-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir - -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - -m4_include([m4/libtool.m4]) -m4_include([m4/ltoptions.m4]) -m4_include([m4/ltsugar.m4]) -m4_include([m4/ltversion.m4]) -m4_include([m4/lt~obsolete.m4]) diff --git a/resources/3rdparty/glpk-4.53/config.guess b/resources/3rdparty/glpk-4.53/config.guess deleted file mode 100644 index 872b96a16..000000000 --- a/resources/3rdparty/glpk-4.53/config.guess +++ /dev/null @@ -1,1537 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012 Free Software Foundation, Inc. - -timestamp='2012-09-25' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner. Please send patches (context -# diff format) to and include a ChangeLog -# entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm*:riscos:*:*|arm*:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH="x86_64" - fi - fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[4567]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep -q __LP64__ - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - IA64) - echo ia64-unknown-interix${UNAME_RELEASE} - exit ;; - esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - echo ${UNAME_MACHINE}-unknown-linux-gnu - else - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi - else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf - fi - fi - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - padre:Linux:*:*) - echo sparc-unknown-linux-gnu - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} - exit ;; - NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; - x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx - exit ;; -esac - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/resources/3rdparty/glpk-4.53/config.h.cmake.in b/resources/3rdparty/glpk-4.53/config.h.cmake.in deleted file mode 100644 index ebde8d1b6..000000000 --- a/resources/3rdparty/glpk-4.53/config.h.cmake.in +++ /dev/null @@ -1,27 +0,0 @@ -/* config.h.in (GLPK configuration template file) */ - -#@GLPK_HAVE_SYS_TIME_H@ HAVE_SYS_TIME_H -/* defined if the header can be used */ - -#@GLPK_HAVE_GETTIMEOFDAY@ HAVE_GETTIMEOFDAY -/* defined if the gettimeofday function can be used */ - -#@GLPK_HAVE_GMP@ HAVE_GMP -/* defined if the GNU MP bignum library is available */ -/* requires and -lgmp */ - -#@GLPK_HAVE_LTDL@ HAVE_LTDL -/* defined if the GNU Libtool shared library support is enabled */ -/* requires and -lltdl */ - -#@GLPK_HAVE_DLFCN@ HAVE_DLFCN -/* defined if the POSIX shared library support is enabled */ -/* requires */ - -#@GLPK_HAVE_ODBC@ ODBC_DLNAME @GLPK_ODBC_DLNAME@ -/* ODBC shared library name if this feature is enabled */ - -#@GLPK_HAVE_MYSQL@ MYSQL_DLNAME @GLPK_MYSQL_DLNAME@ -/* MySQL shared library name if this feature is enabled */ - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/config.h.in b/resources/3rdparty/glpk-4.53/config.h.in deleted file mode 100644 index 2849bf9c4..000000000 --- a/resources/3rdparty/glpk-4.53/config.h.in +++ /dev/null @@ -1,27 +0,0 @@ -/* config.h.in (GLPK configuration template file) */ - -#undef HAVE_SYS_TIME_H -/* defined if the header can be used */ - -#undef HAVE_GETTIMEOFDAY -/* defined if the gettimeofday function can be used */ - -#undef HAVE_GMP -/* defined if the GNU MP bignum library is available */ -/* requires and -lgmp */ - -#undef HAVE_LTDL -/* defined if the GNU Libtool shared library support is enabled */ -/* requires and -lltdl */ - -#undef HAVE_DLFCN -/* defined if the POSIX shared library support is enabled */ -/* requires */ - -#undef ODBC_DLNAME -/* ODBC shared library name if this feature is enabled */ - -#undef MYSQL_DLNAME -/* MySQL shared library name if this feature is enabled */ - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/config.sub b/resources/3rdparty/glpk-4.53/config.sub deleted file mode 100644 index 89b128630..000000000 --- a/resources/3rdparty/glpk-4.53/config.sub +++ /dev/null @@ -1,1789 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012 Free Software Foundation, Inc. - -timestamp='2012-10-10' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Please send patches to . Submit a context -# diff and a properly formatted GNU ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze*) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*178) - os=-lynxos178 - ;; - -lynx*5) - os=-lynxos5 - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc \ - | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | be32 | be64 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 \ - | ns16k | ns32k \ - | open8 \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown - ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none - ;; - xscaleeb) - basic_machine=armeb-unknown - ;; - - xscaleel) - basic_machine=armel-unknown - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i386-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tile*) - basic_machine=$basic_machine-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux - ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; - -nacl*) - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - score-*) - os=-elf - ;; - spu-*) - os=-elf - ;; - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - hexagon-*) - os=-elf - ;; - tic54x-*) - os=-coff - ;; - tic55x-*) - os=-coff - ;; - tic6x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -cnk*|-aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/resources/3rdparty/glpk-4.53/configure b/resources/3rdparty/glpk-4.53/configure deleted file mode 100644 index 049242a6b..000000000 --- a/resources/3rdparty/glpk-4.53/configure +++ /dev/null @@ -1,13839 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for GLPK 4.53. -# -# Report bugs to . -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 - - test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( - ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' - ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO - ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO - PATH=/empty FPATH=/empty; export PATH FPATH - test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ - || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org and bug-glpk@gnu.org -$0: about your system, including any error possibly output -$0: before this message. Then install a modern shell, or -$0: manually run the script under such a shell if you do -$0: have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - -SHELL=${CONFIG_SHELL-/bin/sh} - - -test -n "$DJDIR" || exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='GLPK' -PACKAGE_TARNAME='glpk' -PACKAGE_VERSION='4.53' -PACKAGE_STRING='GLPK 4.53' -PACKAGE_BUGREPORT='bug-glpk@gnu.org' -PACKAGE_URL='' - -ac_unique_file="src/glpk.h" -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='am__EXEEXT_FALSE -am__EXEEXT_TRUE -LTLIBOBJS -LIBOBJS -CPP -OTOOL64 -OTOOL -LIPO -NMEDIT -DSYMUTIL -MANIFEST_TOOL -RANLIB -ac_ct_AR -AR -DLLTOOL -OBJDUMP -LN_S -NM -ac_ct_DUMPBIN -DUMPBIN -LD -FGREP -EGREP -GREP -SED -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build -LIBTOOL -am__fastdepCC_FALSE -am__fastdepCC_TRUE -CCDEPMODE -am__nodep -AMDEPBACKSLASH -AMDEP_FALSE -AMDEP_TRUE -am__quote -am__include -DEPDIR -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -am__untar -am__tar -AMTAR -am__leading_dot -SET_MAKE -AWK -mkdir_p -MKDIR_P -INSTALL_STRIP_PROGRAM -STRIP -install_sh -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -CYGPATH_W -am__isrc -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -with_gmp -enable_dl -enable_odbc -enable_mysql -enable_dependency_tracking -enable_shared -enable_static -with_pic -enable_fast_install -with_gnu_ld -with_sysroot -enable_libtool_lock -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures GLPK 4.53 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/glpk] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of GLPK 4.53:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-dl enable shared library support [[default=no]] - --enable-odbc enable MathProg ODBC support [[default=no]] - --enable-mysql enable MathProg MySQL support [[default=no]] - --enable-dependency-tracking - do not reject slow dependency extractors - --disable-dependency-tracking - speeds up one-time build - --enable-shared[=PKGS] build shared libraries [default=yes] - --enable-static[=PKGS] build static libraries [default=yes] - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-gmp use GNU MP bignum library [[default=no]] - --with-pic try to use only PIC/non-PIC objects [default=use - both] - --with-gnu-ld assume the C compiler uses GNU ld [default=no] - --with-sysroot=DIR Search for dependent libraries within DIR - (or the compiler's sysroot if not specified). - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CPP C preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to . -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -GLPK configure 4.53 -generated by GNU Autoconf 2.69 - -Copyright (C) 2012 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case declares $2. - For example, HP-UX 11i declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## ------------------------------- ## -## Report this to bug-glpk@gnu.org ## -## ------------------------------- ##" - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by GLPK $as_me 4.53, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - - - -am__api_version='1.12' - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi - -rm -f conftest.file - -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='glpk' - VERSION='4.53' - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -mkdir_p='$(MKDIR_P)' - -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AMTAR='$${TAR-tar}' - -am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' - - - - - - -ac_config_headers="$ac_config_headers config.h" - - - -# Check whether --with-gmp was given. -if test "${with_gmp+set}" = set; then : - withval=$with_gmp; case $withval in - yes | no) ;; - *) as_fn_error $? "invalid value \`$withval' for --with-gmp" "$LINENO" 5;; - esac -else - with_gmp=no -fi - - -# Check whether --enable-dl was given. -if test "${enable_dl+set}" = set; then : - enableval=$enable_dl; case $enableval in - yes | ltdl | dlfcn | no) ;; - *) as_fn_error $? "invalid value \`$enableval' for --enable-dl" "$LINENO" 5;; - esac -else - enable_dl=no -fi - - -# Check whether --enable-odbc was given. -if test "${enable_odbc+set}" = set; then : - enableval=$enable_odbc; case $enableval in - yes | unix | no) ;; - *) as_fn_error $? "invalid value \`$enableval' for --enable-odbc" "$LINENO" 5;; - esac -else - enable_odbc=no -fi - - -# Check whether --enable-mysql was given. -if test "${enable_mysql+set}" = set; then : - enableval=$enable_mysql; case $enableval in - yes | no) ;; - *) as_fn_error $? "invalid value \`$enableval' for --enable-mysql" "$LINENO" 5;; - esac -else - enable_mysql=no -fi - - - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - - -case `pwd` in - *\ * | *\ *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 -$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; -esac - - - -macro_version='2.4' -macro_revision='1.3294' - - - - - - - - - - - - - -ltmain="$ac_aux_dir/ltmain.sh" - -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - -# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 -$as_echo_n "checking how to print strings... " >&6; } -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "" -} - -case "$ECHO" in - printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 -$as_echo "printf" >&6; } ;; - print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 -$as_echo "print -r" >&6; } ;; - *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 -$as_echo "cat" >&6; } ;; -esac - - - - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -$as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for ac_i in 1 2 3 4 5 6 7; do - ac_script="$ac_script$as_nl$ac_script" - done - echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed - { ac_script=; unset ac_script;} - if test -z "$SED"; then - ac_path_SED_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_SED" || continue -# Check for GNU ac_path_SED and select it if it is found. - # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in -*GNU*) - ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo '' >> "conftest.nl" - "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_SED_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_SED="$ac_path_SED" - ac_path_SED_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_SED_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_SED"; then - as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 - fi -else - ac_cv_path_SED=$SED -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 -$as_echo "$ac_cv_path_SED" >&6; } - SED="$ac_cv_path_SED" - rm -f conftest.sed - -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 -$as_echo_n "checking for fgrep... " >&6; } -if ${ac_cv_path_FGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 - then ac_cv_path_FGREP="$GREP -F" - else - if test -z "$FGREP"; then - ac_path_FGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in fgrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_FGREP" || continue -# Check for GNU ac_path_FGREP and select it if it is found. - # Check for GNU $ac_path_FGREP -case `"$ac_path_FGREP" --version 2>&1` in -*GNU*) - ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'FGREP' >> "conftest.nl" - "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_FGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_FGREP="$ac_path_FGREP" - ac_path_FGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_FGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_FGREP"; then - as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_FGREP=$FGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 -$as_echo "$ac_cv_path_FGREP" >&6; } - FGREP="$ac_cv_path_FGREP" - - -test -z "$GREP" && GREP=grep - - - - - - - - - - - - - - - - - - - -# Check whether --with-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 -$as_echo_n "checking for ld used by $CC... " >&6; } - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -$as_echo_n "checking for GNU ld... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -$as_echo_n "checking for non-GNU ld... " >&6; } -fi -if ${lt_cv_path_LD+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &5 -$as_echo "$LD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 -$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if ${lt_cv_prog_gnu_ld+:} false; then : - $as_echo_n "(cached) " >&6 -else - # I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 &5 -$as_echo "$lt_cv_prog_gnu_ld" >&6; } -with_gnu_ld=$lt_cv_prog_gnu_ld - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 -$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } -if ${lt_cv_path_NM+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 -$as_echo "$lt_cv_path_NM" >&6; } -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$DUMPBIN"; then : - # Let the user override the test. - else - if test -n "$ac_tool_prefix"; then - for ac_prog in dumpbin "link -dump" - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DUMPBIN"; then - ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DUMPBIN=$ac_cv_prog_DUMPBIN -if test -n "$DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 -$as_echo "$DUMPBIN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$DUMPBIN" && break - done -fi -if test -z "$DUMPBIN"; then - ac_ct_DUMPBIN=$DUMPBIN - for ac_prog in dumpbin "link -dump" -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DUMPBIN"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN -if test -n "$ac_ct_DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 -$as_echo "$ac_ct_DUMPBIN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_DUMPBIN" && break -done - - if test "x$ac_ct_DUMPBIN" = x; then - DUMPBIN=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DUMPBIN=$ac_ct_DUMPBIN - fi -fi - - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in - *COFF*) - DUMPBIN="$DUMPBIN -symbols" - ;; - *) - DUMPBIN=: - ;; - esac - fi - - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 -$as_echo_n "checking the name lister ($NM) interface... " >&6; } -if ${lt_cv_nm_interface+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&5 - (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&5 - (eval echo "\"\$as_me:$LINENO: output\"" >&5) - cat conftest.out >&5 - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest* -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 -$as_echo "$lt_cv_nm_interface" >&6; } - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } -fi - -# find the maximum length of command line arguments -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 -$as_echo_n "checking the maximum length of command line arguments... " >&6; } -if ${lt_cv_sys_max_cmd_len+:} false; then : - $as_echo_n "(cached) " >&6 -else - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - mint*) - # On MiNT this can take a long time and run out of memory. - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ - = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac - -fi - -if test -n $lt_cv_sys_max_cmd_len ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 -$as_echo "$lt_cv_sys_max_cmd_len" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; } -fi -max_cmd_len=$lt_cv_sys_max_cmd_len - - - - - - -: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 -$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 -$as_echo "$xsi_shell" >&6; } - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 -$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } -lt_shell_append=no -( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 -$as_echo "$lt_shell_append" >&6; } - - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi - - - - - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 -$as_echo_n "checking how to convert $build file names to $host format... " >&6; } -if ${lt_cv_to_host_file_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 - ;; - esac - ;; - *-*-cygwin* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin - ;; - esac - ;; - * ) # unhandled hosts (and "normal" native builds) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; -esac - -fi - -to_host_file_cmd=$lt_cv_to_host_file_cmd -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 -$as_echo "$lt_cv_to_host_file_cmd" >&6; } - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 -$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } -if ${lt_cv_to_tool_file_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - #assume ordinary cross tools, or native build. -lt_cv_to_tool_file_cmd=func_convert_file_noop -case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 - ;; - esac - ;; -esac - -fi - -to_tool_file_cmd=$lt_cv_to_tool_file_cmd -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 -$as_echo "$lt_cv_to_tool_file_cmd" >&6; } - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 -$as_echo_n "checking for $LD option to reload object files... " >&6; } -if ${lt_cv_ld_reload_flag+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_reload_flag='-r' -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 -$as_echo "$lt_cv_ld_reload_flag" >&6; } -reload_flag=$lt_cv_ld_reload_flag -case $reload_flag in -"" | " "*) ;; -*) reload_flag=" $reload_flag" ;; -esac -reload_cmds='$LD$reload_flag -o $output$reload_objs' -case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - if test "$GCC" != yes; then - reload_cmds=false - fi - ;; - darwin*) - if test "$GCC" = yes; then - reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' - else - reload_cmds='$LD$reload_flag -o $output$reload_objs' - fi - ;; -esac - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. -set dummy ${ac_tool_prefix}objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OBJDUMP"; then - ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OBJDUMP=$ac_cv_prog_OBJDUMP -if test -n "$OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 -$as_echo "$OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OBJDUMP"; then - ac_ct_OBJDUMP=$OBJDUMP - # Extract the first word of "objdump", so it can be a program name with args. -set dummy objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OBJDUMP"; then - ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OBJDUMP="objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP -if test -n "$ac_ct_OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 -$as_echo "$ac_ct_OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OBJDUMP" = x; then - OBJDUMP="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OBJDUMP=$ac_ct_OBJDUMP - fi -else - OBJDUMP="$ac_cv_prog_OBJDUMP" -fi - -test -z "$OBJDUMP" && OBJDUMP=objdump - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 -$as_echo_n "checking how to recognize dependent libraries... " >&6; } -if ${lt_cv_deplibs_check_method+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. - -case $host_os in -aix[4-9]*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi[45]*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin*) - # func_win32_libid is a shell function defined in ltmain.sh - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - ;; - -mingw* | pw32*) - # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump', - # unless we find 'file', for example because we are cross-compiling. - # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. - if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc*) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -haiku*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[3-9]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 -$as_echo "$lt_cv_deplibs_check_method" >&6; } - -file_magic_glob= -want_nocaseglob=no -if test "$build" = "$host"; then - case $host_os in - mingw* | pw32*) - if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then - want_nocaseglob=yes - else - file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` - fi - ;; - esac -fi - -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - - - - - - - - - - - - - - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. -set dummy ${ac_tool_prefix}dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DLLTOOL"; then - ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DLLTOOL=$ac_cv_prog_DLLTOOL -if test -n "$DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 -$as_echo "$DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DLLTOOL"; then - ac_ct_DLLTOOL=$DLLTOOL - # Extract the first word of "dlltool", so it can be a program name with args. -set dummy dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DLLTOOL"; then - ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DLLTOOL="dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL -if test -n "$ac_ct_DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 -$as_echo "$ac_ct_DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DLLTOOL" = x; then - DLLTOOL="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DLLTOOL=$ac_ct_DLLTOOL - fi -else - DLLTOOL="$ac_cv_prog_DLLTOOL" -fi - -test -z "$DLLTOOL" && DLLTOOL=dlltool - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 -$as_echo_n "checking how to associate runtime and link libraries... " >&6; } -if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_sharedlib_from_linklib_cmd='unknown' - -case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL - case `$DLLTOOL --help 2>&1` in - *--identify-strict*) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib - ;; - *) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback - ;; - esac - ;; -*) - # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" - ;; -esac - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 -$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } -sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd -test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO - - - - - - - - -if test -n "$ac_tool_prefix"; then - for ac_prog in ar - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -$as_echo "$AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AR" && break - done -fi -if test -z "$AR"; then - ac_ct_AR=$AR - for ac_prog in ar -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -$as_echo "$ac_ct_AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_AR" && break -done - - if test "x$ac_ct_AR" = x; then - AR="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AR=$ac_ct_AR - fi -fi - -: ${AR=ar} -: ${AR_FLAGS=cru} - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 -$as_echo_n "checking for archiver @FILE support... " >&6; } -if ${lt_cv_ar_at_file+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ar_at_file=no - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - echo conftest.$ac_objext > conftest.lst - lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 - (eval $lt_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test "$ac_status" -eq 0; then - # Ensure the archiver fails upon bogus file names. - rm -f conftest.$ac_objext libconftest.a - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 - (eval $lt_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test "$ac_status" -ne 0; then - lt_cv_ar_at_file=@ - fi - fi - rm -f conftest.* libconftest.a - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 -$as_echo "$lt_cv_ar_at_file" >&6; } - -if test "x$lt_cv_ar_at_file" = xno; then - archiver_list_spec= -else - archiver_list_spec=$lt_cv_ar_at_file -fi - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -test -z "$STRIP" && STRIP=: - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -test -z "$RANLIB" && RANLIB=: - - - - - - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi - -case $host_os in - darwin*) - lock_old_archive_extraction=yes ;; - *) - lock_old_archive_extraction=no ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# Check for command to grab the raw symbol name followed by C symbol from nm. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 -$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } -if ${lt_cv_sys_global_symbol_pipe+:} false; then : - $as_echo_n "(cached) " >&6 -else - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[BCDEGRST]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([_A-Za-z][_A-Za-z0-9]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[BCDT]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[ABCDGISTW]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[ABCDEGRST]' - fi - ;; -irix* | nonstopux*) - symcode='[BCDEGRST]' - ;; -osf*) - symcode='[BCDEGQRST]' - ;; -solaris*) - symcode='[BDRT]' - ;; -sco3.2v5*) - symcode='[DT]' - ;; -sysv4.2uw2*) - symcode='[DT]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[ABDT]' - ;; -sysv4) - symcode='[DFNSTU]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[ABCDGIRSTW]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK '"\ -" {last_section=section; section=\$ 3};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - # Now try to grab the symbols. - nlist=conftest.nm - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 - (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT_DLSYM_CONST -#elif defined(__osf__) -/* This system does not cope well with relocations in const data. */ -# define LT_DLSYM_CONST -#else -# define LT_DLSYM_CONST const -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -LT_DLSYM_CONST struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_globsym_save_LIBS=$LIBS - lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS=$lt_globsym_save_LIBS - CFLAGS=$lt_globsym_save_CFLAGS - else - echo "cannot find nm_test_func in $nlist" >&5 - fi - else - echo "cannot find nm_test_var in $nlist" >&5 - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 - fi - else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done - -fi - -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 -$as_echo "failed" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 -$as_echo "ok" >&6; } -fi - -# Response file support. -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - nm_file_list_spec='@' -elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then - nm_file_list_spec='@' -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 -$as_echo_n "checking for sysroot... " >&6; } - -# Check whether --with-sysroot was given. -if test "${with_sysroot+set}" = set; then : - withval=$with_sysroot; -else - with_sysroot=no -fi - - -lt_sysroot= -case ${with_sysroot} in #( - yes) - if test "$GCC" = yes; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` - fi - ;; #( - /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` - ;; #( - no|'') - ;; #( - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 -$as_echo "${with_sysroot}" >&6; } - as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 - ;; -esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 -$as_echo "${lt_sysroot:-no}" >&6; } - - - - - -# Check whether --enable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then : - enableval=$enable_libtool_lock; -fi - -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '#line '$LINENO' "configure"' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 -$as_echo_n "checking whether the C compiler needs -belf... " >&6; } -if ${lt_cv_cc_needs_belf+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_cc_needs_belf=yes -else - lt_cv_cc_needs_belf=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 -$as_echo "$lt_cv_cc_needs_belf" >&6; } - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -sparc*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) LD="${LD-ld} -m elf64_sparc" ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. -set dummy ${ac_tool_prefix}mt; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$MANIFEST_TOOL"; then - ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL -if test -n "$MANIFEST_TOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 -$as_echo "$MANIFEST_TOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_MANIFEST_TOOL"; then - ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL - # Extract the first word of "mt", so it can be a program name with args. -set dummy mt; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_MANIFEST_TOOL"; then - ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL -if test -n "$ac_ct_MANIFEST_TOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 -$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_MANIFEST_TOOL" = x; then - MANIFEST_TOOL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL - fi -else - MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" -fi - -test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 -$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } -if ${lt_cv_path_mainfest_tool+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_path_mainfest_tool=no - echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 - $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out - cat conftest.err >&5 - if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes - fi - rm -f conftest* -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 -$as_echo "$lt_cv_path_mainfest_tool" >&6; } -if test "x$lt_cv_path_mainfest_tool" != xyes; then - MANIFEST_TOOL=: -fi - - - - - - - case $host_os in - rhapsody* | darwin*) - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. -set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DSYMUTIL"; then - ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DSYMUTIL=$ac_cv_prog_DSYMUTIL -if test -n "$DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 -$as_echo "$DSYMUTIL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DSYMUTIL"; then - ac_ct_DSYMUTIL=$DSYMUTIL - # Extract the first word of "dsymutil", so it can be a program name with args. -set dummy dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DSYMUTIL"; then - ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL -if test -n "$ac_ct_DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 -$as_echo "$ac_ct_DSYMUTIL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DSYMUTIL" = x; then - DSYMUTIL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DSYMUTIL=$ac_ct_DSYMUTIL - fi -else - DSYMUTIL="$ac_cv_prog_DSYMUTIL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. -set dummy ${ac_tool_prefix}nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NMEDIT"; then - ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -NMEDIT=$ac_cv_prog_NMEDIT -if test -n "$NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 -$as_echo "$NMEDIT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_NMEDIT"; then - ac_ct_NMEDIT=$NMEDIT - # Extract the first word of "nmedit", so it can be a program name with args. -set dummy nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_NMEDIT"; then - ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_NMEDIT="nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT -if test -n "$ac_ct_NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 -$as_echo "$ac_ct_NMEDIT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_NMEDIT" = x; then - NMEDIT=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - NMEDIT=$ac_ct_NMEDIT - fi -else - NMEDIT="$ac_cv_prog_NMEDIT" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. -set dummy ${ac_tool_prefix}lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$LIPO"; then - ac_cv_prog_LIPO="$LIPO" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_LIPO="${ac_tool_prefix}lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -LIPO=$ac_cv_prog_LIPO -if test -n "$LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 -$as_echo "$LIPO" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_LIPO"; then - ac_ct_LIPO=$LIPO - # Extract the first word of "lipo", so it can be a program name with args. -set dummy lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_LIPO"; then - ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_LIPO="lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO -if test -n "$ac_ct_LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 -$as_echo "$ac_ct_LIPO" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_LIPO" = x; then - LIPO=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - LIPO=$ac_ct_LIPO - fi -else - LIPO="$ac_cv_prog_LIPO" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OTOOL"; then - ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OTOOL="${ac_tool_prefix}otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OTOOL=$ac_cv_prog_OTOOL -if test -n "$OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 -$as_echo "$OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL"; then - ac_ct_OTOOL=$OTOOL - # Extract the first word of "otool", so it can be a program name with args. -set dummy otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OTOOL"; then - ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OTOOL="otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL -if test -n "$ac_ct_OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 -$as_echo "$ac_ct_OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OTOOL" = x; then - OTOOL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL=$ac_ct_OTOOL - fi -else - OTOOL="$ac_cv_prog_OTOOL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OTOOL64"; then - ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OTOOL64=$ac_cv_prog_OTOOL64 -if test -n "$OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 -$as_echo "$OTOOL64" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL64"; then - ac_ct_OTOOL64=$OTOOL64 - # Extract the first word of "otool64", so it can be a program name with args. -set dummy otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OTOOL64"; then - ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OTOOL64="otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 -if test -n "$ac_ct_OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 -$as_echo "$ac_ct_OTOOL64" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OTOOL64" = x; then - OTOOL64=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL64=$ac_ct_OTOOL64 - fi -else - OTOOL64="$ac_cv_prog_OTOOL64" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 -$as_echo_n "checking for -single_module linker flag... " >&6; } -if ${lt_cv_apple_cc_single_mod+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&5 - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&5 - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 -$as_echo "$lt_cv_apple_cc_single_mod" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 -$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } -if ${lt_cv_ld_exported_symbols_list+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_ld_exported_symbols_list=yes -else - lt_cv_ld_exported_symbols_list=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 -$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 -$as_echo_n "checking for -force_load linker flag... " >&6; } -if ${lt_cv_ld_force_load+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_force_load=no - cat > conftest.c << _LT_EOF -int forced_loaded() { return 2;} -_LT_EOF - echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 - $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 - echo "$AR cru libconftest.a conftest.o" >&5 - $AR cru libconftest.a conftest.o 2>&5 - echo "$RANLIB libconftest.a" >&5 - $RANLIB libconftest.a 2>&5 - cat > conftest.c << _LT_EOF -int main() { return 0;} -_LT_EOF - echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 - $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err - _lt_result=$? - if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then - lt_cv_ld_force_load=yes - else - cat conftest.err >&5 - fi - rm -f conftest.err libconftest.a conftest conftest.c - rm -rf conftest.dSYM - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 -$as_echo "$lt_cv_ld_force_load" >&6; } - case $host_os in - rhapsody* | darwin1.[012]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[91]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[012]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -for ac_header in dlfcn.h -do : - ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default -" -if test "x$ac_cv_header_dlfcn_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_DLFCN_H 1 -_ACEOF - -fi - -done - - - - - -# Set options - - - - enable_dlopen=no - - - enable_win32_dll=no - - - # Check whether --enable-shared was given. -if test "${enable_shared+set}" = set; then : - enableval=$enable_shared; p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_shared=yes -fi - - - - - - - - - - # Check whether --enable-static was given. -if test "${enable_static+set}" = set; then : - enableval=$enable_static; p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_static=yes -fi - - - - - - - - - - -# Check whether --with-pic was given. -if test "${with_pic+set}" = set; then : - withval=$with_pic; pic_mode="$withval" -else - pic_mode=default -fi - - -test -z "$pic_mode" && pic_mode=default - - - - - - - - # Check whether --enable-fast-install was given. -if test "${enable_fast_install+set}" = set; then : - enableval=$enable_fast_install; p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_fast_install=yes -fi - - - - - - - - - - - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' - - - - - - - - - - - - - - - - - - - - - - - - - - -test -z "$LN_S" && LN_S="ln -s" - - - - - - - - - - - - - - -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 -$as_echo_n "checking for objdir... " >&6; } -if ${lt_cv_objdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 -$as_echo "$lt_cv_objdir" >&6; } -objdir=$lt_cv_objdir - - - - - -cat >>confdefs.h <<_ACEOF -#define LT_OBJDIR "$lt_cv_objdir/" -_ACEOF - - - - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` - - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 -$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/${ac_tool_prefix}file; then - lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - - - -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 -$as_echo_n "checking for file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/file; then - lt_cv_path_MAGIC_CMD="$ac_dir/file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - else - MAGIC_CMD=: - fi -fi - - fi - ;; -esac - -# Use C for the default configuration in the libtool script - -lt_save_CC="$CC" -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -objext=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* - -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* - - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - -lt_prog_compiler_no_builtin_flag= - -if test "$GCC" = yes; then - case $cc_basename in - nvcc*) - lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; - *) - lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; - esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 -$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } -if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_rtti_exceptions=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_rtti_exceptions=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 -$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } - -if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then - lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" -else - : -fi - -fi - - - - - - - lt_prog_compiler_wl= -lt_prog_compiler_pic= -lt_prog_compiler_static= - - - if test "$GCC" = yes; then - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_static='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - lt_prog_compiler_pic='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic='-fno-common' - ;; - - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - lt_prog_compiler_static= - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - ;; - - interix[3-9]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - lt_prog_compiler_can_build_shared=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic=-Kconform_pic - fi - ;; - - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - - case $cc_basename in - nvcc*) # Cuda Compiler Driver 2.2 - lt_prog_compiler_wl='-Xlinker ' - lt_prog_compiler_pic='-Xcompiler -fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - lt_prog_compiler_wl='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - else - lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - lt_prog_compiler_wl='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - lt_prog_compiler_wl='-Wl,' - # PIC (with -KPIC) is the default. - lt_prog_compiler_static='-non_shared' - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='--shared' - lt_prog_compiler_static='--static' - ;; - nagfor*) - # NAG Fortran compiler - lt_prog_compiler_wl='-Wl,-Wl,,' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-Bstatic' - ;; - ccc*) - lt_prog_compiler_wl='-Wl,' - # All Alpha code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - xl* | bgxl* | bgf* | mpixl*) - # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-qpic' - lt_prog_compiler_static='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ F* | *Sun*Fortran*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='' - ;; - *Sun\ C*) - # Sun C 5.9 - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='-Wl,' - ;; - esac - ;; - esac - ;; - - newsos6) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - lt_prog_compiler_wl='-Wl,' - # All OSF/1 code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - - rdos*) - lt_prog_compiler_static='-non_shared' - ;; - - solaris*) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - lt_prog_compiler_wl='-Qoption ld ';; - *) - lt_prog_compiler_wl='-Wl,';; - esac - ;; - - sunos4*) - lt_prog_compiler_wl='-Qoption ld ' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_prog_compiler_pic='-Kconform_pic' - lt_prog_compiler_static='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - unicos*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_can_build_shared=no - ;; - - uts4*) - lt_prog_compiler_pic='-pic' - lt_prog_compiler_static='-Bstatic' - ;; - - *) - lt_prog_compiler_can_build_shared=no - ;; - esac - fi - -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic= - ;; - *) - lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" - ;; -esac - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 -$as_echo_n "checking for $compiler option to produce PIC... " >&6; } -if ${lt_cv_prog_compiler_pic+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic=$lt_prog_compiler_pic -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 -$as_echo "$lt_cv_prog_compiler_pic" >&6; } -lt_prog_compiler_pic=$lt_cv_prog_compiler_pic - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 -$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } -if ${lt_cv_prog_compiler_pic_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic_works=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic -DPIC" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_pic_works=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 -$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } - -if test x"$lt_cv_prog_compiler_pic_works" = xyes; then - case $lt_prog_compiler_pic in - "" | " "*) ;; - *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; - esac -else - lt_prog_compiler_pic= - lt_prog_compiler_can_build_shared=no -fi - -fi - - - - - - - - - - - -# -# Check to make sure the static flag actually works. -# -wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 -$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if ${lt_cv_prog_compiler_static_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_static_works=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_tmp_static_flag" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_static_works=yes - fi - else - lt_cv_prog_compiler_static_works=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 -$as_echo "$lt_cv_prog_compiler_static_works" >&6; } - -if test x"$lt_cv_prog_compiler_static_works" = xyes; then - : -else - lt_prog_compiler_static= -fi - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } - - - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 -$as_echo_n "checking if we can lock with hard links... " >&6; } - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 -$as_echo "$hard_links" >&6; } - if test "$hard_links" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } - - runpath_var= - allow_undefined_flag= - always_export_symbols=no - archive_cmds= - archive_expsym_cmds= - compiler_needs_object=no - enable_shared_with_static_runtimes=no - export_dynamic_flag_spec= - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - hardcode_automatic=no - hardcode_direct=no - hardcode_direct_absolute=no - hardcode_libdir_flag_spec= - hardcode_libdir_flag_spec_ld= - hardcode_libdir_separator= - hardcode_minus_L=no - hardcode_shlibpath_var=unsupported - inherit_rpath=no - link_all_deplibs=unknown - module_cmds= - module_expsym_cmds= - old_archive_from_new_cmds= - old_archive_from_expsyms_cmds= - thread_safe_flag_spec= - whole_archive_flag_spec= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - include_expsyms= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - ld_shlibs=yes - - # On some targets, GNU ld is compatible enough with the native linker - # that we're better off using the native interface for both. - lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then - case $host_os in - aix*) - # The AIX port of GNU ld has always aspired to compatibility - # with the native linker. However, as the warning in the GNU ld - # block says, versions before 2.19.5* couldn't really create working - # shared libraries, regardless of the interface used. - case `$LD -v 2>&1` in - *\ \(GNU\ Binutils\)\ 2.19.5*) ;; - *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; - *\ \(GNU\ Binutils\)\ [3-9]*) ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - fi - - if test "$lt_use_gnu_ld_interface" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *GNU\ gold*) supports_anon_versioning=yes ;; - *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[3-9]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.19, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to install binutils -*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. -*** You will then need to restart the configuration process. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - export_dynamic_flag_spec='${wl}--export-all-symbols' - allow_undefined_flag=unsupported - always_export_symbols=no - enable_shared_with_static_runtimes=yes - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' - exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - ld_shlibs=no - fi - ;; - - haiku*) - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - link_all_deplibs=yes - ;; - - interix[3-9]*) - hardcode_direct=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag=' $pic_flag' - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group f77 and f90 compilers - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - whole_archive_flag_spec= - tmp_sharedflag='--shared' ;; - xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - nvcc*) # Cuda Compiler Driver 2.2 - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - compiler_needs_object=yes - ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - compiler_needs_object=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf* | bgf* | bgxlf* | mpixlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' - hardcode_libdir_flag_spec= - hardcode_libdir_flag_spec_ld='-rpath $libdir' - archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - ld_shlibs=no - fi - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test "$ld_shlibs" = no; then - runpath_var= - hardcode_libdir_flag_spec= - export_dynamic_flag_spec= - whole_archive_flag_spec= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix[4-9]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global - # defined symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds='' - hardcode_direct=yes - hardcode_direct_absolute=yes - hardcode_libdir_separator=':' - link_all_deplibs=yes - file_list_spec='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - export_dynamic_flag_spec='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - if ${lt_cv_aix_libpath_+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_="/usr/lib:/lib" - fi - -fi - - aix_libpath=$lt_cv_aix_libpath_ -fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - if ${lt_cv_aix_libpath_+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_="/usr/lib:/lib" - fi - -fi - - aix_libpath=$lt_cv_aix_libpath_ -fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag=' ${wl}-bernotok' - allow_undefined_flag=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec='$convenience' - fi - archive_cmds_need_lc=yes - # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - bsdi[45]*) - export_dynamic_flag_spec=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - case $cc_basename in - cl*) - # Native MSVC - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - always_export_symbols=yes - file_list_spec='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, )='true' - enable_shared_with_static_runtimes=yes - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' - # Don't use ranlib - old_postinstall_cmds='chmod 644 $oldlib' - postlink_cmds='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # Assume MSVC wrapper - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_from_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' - enable_shared_with_static_runtimes=yes - ;; - esac - ;; - - darwin* | rhapsody*) - - - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes - hardcode_shlibpath_var=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - else - whole_archive_flag_spec='' - fi - link_all_deplibs=yes - allow_undefined_flag="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all - archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else - ld_shlibs=no - fi - - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - freebsd1*) - ld_shlibs=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9*) - if test "$GCC" = yes; then - archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - export_dynamic_flag_spec='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld='+b $libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - - # Older versions of the 11.00 compiler do not understand -b yet - # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 -$as_echo_n "checking if $CC understands -b... " >&6; } -if ${lt_cv_prog_compiler__b+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler__b=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -b" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler__b=yes - fi - else - lt_cv_prog_compiler__b=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 -$as_echo "$lt_cv_prog_compiler__b" >&6; } - -if test x"$lt_cv_prog_compiler__b" = xyes; then - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' -else - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' -fi - - ;; - esac - fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - - case $host_cpu in - hppa*64*|ia64*) - hardcode_direct=no - hardcode_shlibpath_var=no - ;; - *) - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - # This should be the same for all languages, so no per-tag cache variable. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 -$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } -if ${lt_cv_irix_exported_symbol+:} false; then : - $as_echo_n "(cached) " >&6 -else - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int foo (void) { return 0; } -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_irix_exported_symbol=yes -else - lt_cv_irix_exported_symbol=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 -$as_echo "$lt_cv_irix_exported_symbol" >&6; } - if test "$lt_cv_irix_exported_symbol" = yes; then - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - fi - else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - inherit_rpath=yes - link_all_deplibs=yes - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - newsos6) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_shlibpath_var=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - hardcode_direct=yes - hardcode_shlibpath_var=no - hardcode_direct_absolute=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - else - ld_shlibs=no - fi - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - archive_cmds_need_lc='no' - hardcode_libdir_separator=: - ;; - - solaris*) - no_undefined_flag=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' - fi - ;; - esac - link_all_deplibs=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds='$CC -r -o $output$reload_objs' - hardcode_direct=no - ;; - motorola) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - no_undefined_flag='${wl}-z,text' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - no_undefined_flag='${wl}-z,text' - allow_undefined_flag='${wl}-z,nodefs' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-R,$libdir' - hardcode_libdir_separator=':' - link_all_deplibs=yes - export_dynamic_flag_spec='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - export_dynamic_flag_spec='${wl}-Blargedynsym' - ;; - esac - fi - fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 -$as_echo "$ld_shlibs" >&6; } -test "$ld_shlibs" = no && can_build_shared=no - -with_gnu_ld=$with_gnu_ld - - - - - - - - - - - - - - - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 -$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } -if ${lt_cv_archive_cmds_need_lc+:} false; then : - $as_echo_n "(cached) " >&6 -else - $RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl - pic_flag=$lt_prog_compiler_pic - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag - allow_undefined_flag= - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 - (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - then - lt_cv_archive_cmds_need_lc=no - else - lt_cv_archive_cmds_need_lc=yes - fi - allow_undefined_flag=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 -$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } - archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc - ;; - esac - fi - ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 -$as_echo_n "checking dynamic linker characteristics... " >&6; } - -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` - case $lt_search_path_spec in - *\;*) - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` - ;; - *) - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` - ;; - esac - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[lt_foo]++; } - if (lt_freq[lt_foo] == 1) { print lt_foo; } -}'` - # AWK program above erroneously prepends '/' to C:/dos/paths - # for these hosts. - case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([A-Za-z]:\),\1,g'` ;; - esac - sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[4-9]*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[45]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec="$LIB" - if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[123]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ - freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -haiku*) - version_type=linux - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[3-9]*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - if ${lt_cv_shlibpath_overrides_runpath+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ - LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : - lt_cv_shlibpath_overrides_runpath=yes -fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - -fi - - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 -$as_echo "$dynamic_linker" >&6; } -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 -$as_echo_n "checking how to hardcode library paths into programs... " >&6; } -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || - test -n "$runpath_var" || - test "X$hardcode_automatic" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$hardcode_direct" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && - test "$hardcode_minus_L" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 -$as_echo "$hardcode_action" >&6; } - -if test "$hardcode_action" = relink || - test "$inherit_rpath" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - - - - - - - if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" -if test "x$ac_cv_func_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 -$as_echo_n "checking for shl_load in -ldld... " >&6; } -if ${ac_cv_lib_dld_shl_load+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char shl_load (); -int -main () -{ -return shl_load (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dld_shl_load=yes -else - ac_cv_lib_dld_shl_load=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 -$as_echo "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" -else - ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 -$as_echo_n "checking for dlopen in -lsvld... " >&6; } -if ${ac_cv_lib_svld_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_svld_dlopen=yes -else - ac_cv_lib_svld_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 -$as_echo "$ac_cv_lib_svld_dlopen" >&6; } -if test "x$ac_cv_lib_svld_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 -$as_echo_n "checking for dld_link in -ldld... " >&6; } -if ${ac_cv_lib_dld_dld_link+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dld_link (); -int -main () -{ -return dld_link (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dld_dld_link=yes -else - ac_cv_lib_dld_dld_link=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 -$as_echo "$ac_cv_lib_dld_dld_link" >&6; } -if test "x$ac_cv_lib_dld_dld_link" = xyes; then : - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 -$as_echo_n "checking whether a program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisbility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 -$as_echo "$lt_cv_dlopen_self" >&6; } - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 -$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self_static+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisbility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 -$as_echo "$lt_cv_dlopen_self_static" >&6; } - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - - - - - - - - - - - - - - - - -striplib= -old_striplib= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 -$as_echo_n "checking whether stripping libraries is possible... " >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; - esac -fi - - - - - - - - - - - - - # Report which library types will actually be built - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 -$as_echo_n "checking if libtool supports shared libraries... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 -$as_echo "$can_build_shared" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 -$as_echo_n "checking whether to build shared libraries... " >&6; } - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[4-9]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 -$as_echo "$enable_shared" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 -$as_echo_n "checking whether to build static libraries... " >&6; } - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 -$as_echo "$enable_static" >&6; } - - - - -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC="$lt_save_CC" - - - - - - - - - - - - - - ac_config_commands="$ac_config_commands libtool" - - - - -# Only expand once: - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for exp in -lm" >&5 -$as_echo_n "checking for exp in -lm... " >&6; } -if ${ac_cv_lib_m_exp+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lm $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char exp (); -int -main () -{ -return exp (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_m_exp=yes -else - ac_cv_lib_m_exp=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_exp" >&5 -$as_echo "$ac_cv_lib_m_exp" >&6; } -if test "x$ac_cv_lib_m_exp" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBM 1 -_ACEOF - - LIBS="-lm $LIBS" - -fi - - -ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_time_h" = xyes; then : - -$as_echo "#define HAVE_SYS_TIME_H 1" >>confdefs.h - -fi - - - -ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" -if test "x$ac_cv_func_gettimeofday" = xyes; then : - -$as_echo "#define HAVE_GETTIMEOFDAY 1" >>confdefs.h - -fi - - -if test "$with_gmp" = "yes"; then - ac_fn_c_check_header_mongrel "$LINENO" "gmp.h" "ac_cv_header_gmp_h" "$ac_includes_default" -if test "x$ac_cv_header_gmp_h" = xyes; then : - -else - as_fn_error $? "gmp.h header not found" "$LINENO" 5 -fi - - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use GNU MP bignum library" >&5 -$as_echo_n "checking whether to use GNU MP bignum library... " >&6; } -if test "$with_gmp" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -$as_echo "#define HAVE_GMP 1" >>confdefs.h - - LIBS="-lgmp $LIBS" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable shared library support" >&5 -$as_echo_n "checking whether to enable shared library support... " >&6; } -if test "$enable_dl" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ltdl" >&5 -$as_echo "ltdl" >&6; } - -$as_echo "#define HAVE_LTDL 1" >>confdefs.h - - LIBS="-lltdl $LIBS" -elif test "$enable_dl" = "ltdl"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ltdl" >&5 -$as_echo "ltdl" >&6; } - -$as_echo "#define HAVE_LTDL 1" >>confdefs.h - - LIBS="-lltdl $LIBS" -elif test "$enable_dl" = "dlfcn"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: dlfcn" >&5 -$as_echo "dlfcn" >&6; } - -$as_echo "#define HAVE_DLFCN 1" >>confdefs.h - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -case $host_os in - darwin* | macosx*) - LIBIODBC="libiodbc.dylib" - LIBODBC="libodbc.dylib" - LIBMYSQL="libmysqlclient.dylib" - ;; - *) - LIBIODBC="libiodbc.so" - LIBODBC="libodbc.so" - LIBMYSQL="libmysqlclient.so" - ;; -esac - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable MathProg ODBC support" >&5 -$as_echo_n "checking whether to enable MathProg ODBC support... " >&6; } -if test "$enable_odbc" = "yes"; then - if test "$enable_dl" = "no"; then - as_fn_error $? "--enable-odbc requires --enable-dl" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -cat >>confdefs.h <<_ACEOF -#define ODBC_DLNAME "$LIBIODBC" -_ACEOF - -elif test "$enable_odbc" = "unix"; then - if test "$enable_dl" = "no"; then - as_fn_error $? "--enable-odbc requires --enable-dl" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unix" >&5 -$as_echo "unix" >&6; } - -cat >>confdefs.h <<_ACEOF -#define ODBC_DLNAME "$LIBODBC" -_ACEOF - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable MathProg MySQL support" >&5 -$as_echo_n "checking whether to enable MathProg MySQL support... " >&6; } -if test "$enable_mysql" = "yes"; then - if test "$enable_dl" = "no"; then - as_fn_error $? "--enable-mysql requires --enable-dl" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - CPPFLAGS="-I/usr/include/mysql $CPPFLAGS" - -cat >>confdefs.h <<_ACEOF -#define MYSQL_DLNAME "$LIBMYSQL" -_ACEOF - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -ac_config_files="$ac_config_files src/Makefile examples/Makefile Makefile" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 -$as_echo_n "checking that generated files are newer than configure... " >&6; } - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 -$as_echo "done" >&6; } - if test -n "$EXEEXT"; then - am__EXEEXT_TRUE= - am__EXEEXT_FALSE='#' -else - am__EXEEXT_TRUE='#' - am__EXEEXT_FALSE= -fi - -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - as_fn_error $? "conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by GLPK $as_me 4.53, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - -Report bugs to ." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -GLPK config.status 4.53 -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -AWK='$AWK' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" - - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' -macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' -enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' -enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' -pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' -enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' -SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' -ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' -host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' -host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' -host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' -build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' -build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' -build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' -SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' -Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' -GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' -EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' -FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' -LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' -NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' -LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' -max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' -ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' -exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' -lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' -lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' -lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' -lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' -lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' -reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' -reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' -OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' -deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' -file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' -file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' -want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' -DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' -sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' -AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' -AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' -archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' -STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' -RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' -old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' -old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' -lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' -CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' -CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' -compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' -GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' -nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' -lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' -objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' -MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' -lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' -need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' -MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' -DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' -NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' -LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' -OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' -OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' -libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' -shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' -extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' -enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' -export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' -whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' -compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' -old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' -archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' -module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' -module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' -with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' -allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' -no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' -hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' -hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' -hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' -hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' -hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' -inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' -link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' -always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' -export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' -exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' -include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' -prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' -postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' -file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' -variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' -need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' -need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' -version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' -runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' -libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' -library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' -soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' -install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' -postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' -postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' -finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' -hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' -sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' -sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' -hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' -enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' -old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' -striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' - -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in SHELL \ -ECHO \ -SED \ -GREP \ -EGREP \ -FGREP \ -LD \ -NM \ -LN_S \ -lt_SP2NL \ -lt_NL2SP \ -reload_flag \ -OBJDUMP \ -deplibs_check_method \ -file_magic_cmd \ -file_magic_glob \ -want_nocaseglob \ -DLLTOOL \ -sharedlib_from_linklib_cmd \ -AR \ -AR_FLAGS \ -archiver_list_spec \ -STRIP \ -RANLIB \ -CC \ -CFLAGS \ -compiler \ -lt_cv_sys_global_symbol_pipe \ -lt_cv_sys_global_symbol_to_cdecl \ -lt_cv_sys_global_symbol_to_c_name_address \ -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ -nm_file_list_spec \ -lt_prog_compiler_no_builtin_flag \ -lt_prog_compiler_pic \ -lt_prog_compiler_wl \ -lt_prog_compiler_static \ -lt_cv_prog_compiler_c_o \ -need_locks \ -MANIFEST_TOOL \ -DSYMUTIL \ -NMEDIT \ -LIPO \ -OTOOL \ -OTOOL64 \ -shrext_cmds \ -export_dynamic_flag_spec \ -whole_archive_flag_spec \ -compiler_needs_object \ -with_gnu_ld \ -allow_undefined_flag \ -no_undefined_flag \ -hardcode_libdir_flag_spec \ -hardcode_libdir_flag_spec_ld \ -hardcode_libdir_separator \ -exclude_expsyms \ -include_expsyms \ -file_list_spec \ -variables_saved_for_relink \ -libname_spec \ -library_names_spec \ -soname_spec \ -install_override_mode \ -finish_eval \ -old_striplib \ -striplib; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in reload_cmds \ -old_postinstall_cmds \ -old_postuninstall_cmds \ -old_archive_cmds \ -extract_expsyms_cmds \ -old_archive_from_new_cmds \ -old_archive_from_expsyms_cmds \ -archive_cmds \ -archive_expsym_cmds \ -module_cmds \ -module_expsym_cmds \ -export_symbols_cmds \ -prelink_cmds \ -postlink_cmds \ -postinstall_cmds \ -postuninstall_cmds \ -finish_cmds \ -sys_lib_search_path_spec \ -sys_lib_dlsearch_path_spec; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -ac_aux_dir='$ac_aux_dir' -xsi_shell='$xsi_shell' -lt_shell_append='$lt_shell_append' - -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - - - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile' - - - - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; - "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; - "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' >$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi -# Compute "$ac_file"'s index in $config_headers. -_am_arg="$ac_file" -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || -$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$_am_arg" : 'X\(//\)[^/]' \| \ - X"$_am_arg" : 'X\(//\)$' \| \ - X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$_am_arg" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'`/stamp-h$_am_stamp_count - ;; - - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Autoconf 2.62 quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} - ;; - "libtool":C) - - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, -# Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - -# The names of the tagged configurations supported by this script. -available_tags="" - -# ### BEGIN LIBTOOL CONFIG - -# Which release of libtool.m4 was used? -macro_version=$macro_version -macro_revision=$macro_revision - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# What type of objects to build. -pic_mode=$pic_mode - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# An echo program that protects backslashes. -ECHO=$lt_ECHO - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="\$SED -e 1s/^X//" - -# A grep program that handles long lines. -GREP=$lt_GREP - -# An ERE matcher. -EGREP=$lt_EGREP - -# A literal string matcher. -FGREP=$lt_FGREP - -# A BSD- or MS-compatible name lister. -NM=$lt_NM - -# Whether we need soft or hard links. -LN_S=$lt_LN_S - -# What is the maximum length of a command? -max_cmd_len=$max_cmd_len - -# Object file suffix (normally "o"). -objext=$ac_objext - -# Executable file suffix (normally ""). -exeext=$exeext - -# whether the shell understands "unset". -lt_unset=$lt_unset - -# turn spaces into newlines. -SP2NL=$lt_lt_SP2NL - -# turn newlines into spaces. -NL2SP=$lt_lt_NL2SP - -# convert \$build file names to \$host format. -to_host_file_cmd=$lt_cv_to_host_file_cmd - -# convert \$build files to toolchain format. -to_tool_file_cmd=$lt_cv_to_tool_file_cmd - -# An object symbol dumper. -OBJDUMP=$lt_OBJDUMP - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method = "file_magic". -file_magic_cmd=$lt_file_magic_cmd - -# How to find potential files when deplibs_check_method = "file_magic". -file_magic_glob=$lt_file_magic_glob - -# Find potential files using nocaseglob when deplibs_check_method = "file_magic". -want_nocaseglob=$lt_want_nocaseglob - -# DLL creation program. -DLLTOOL=$lt_DLLTOOL - -# Command to associate shared and link libraries. -sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd - -# The archiver. -AR=$lt_AR - -# Flags to create an archive. -AR_FLAGS=$lt_AR_FLAGS - -# How to feed a file listing to the archiver. -archiver_list_spec=$lt_archiver_list_spec - -# A symbol stripping program. -STRIP=$lt_STRIP - -# Commands used to install an old-style archive. -RANLIB=$lt_RANLIB -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Whether to use a lock for old archive extraction. -lock_old_archive_extraction=$lock_old_archive_extraction - -# A C compiler. -LTCC=$lt_CC - -# LTCC compiler flags. -LTCFLAGS=$lt_CFLAGS - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration. -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair. -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# Transform the output of nm in a C name address pair when lib prefix is needed. -global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix - -# Specify filename containing input files for \$NM. -nm_file_list_spec=$lt_nm_file_list_spec - -# The root where to search for dependent libraries,and in which our libraries should be installed. -lt_sysroot=$lt_sysroot - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# Used to examine libraries when file_magic_cmd begins with "file". -MAGIC_CMD=$MAGIC_CMD - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Manifest tool. -MANIFEST_TOOL=$lt_MANIFEST_TOOL - -# Tool to manipulate archived DWARF debug symbol files on Mac OS X. -DSYMUTIL=$lt_DSYMUTIL - -# Tool to change global to local symbols on Mac OS X. -NMEDIT=$lt_NMEDIT - -# Tool to manipulate fat objects and archives on Mac OS X. -LIPO=$lt_LIPO - -# ldd/readelf like tool for Mach-O binaries on Mac OS X. -OTOOL=$lt_OTOOL - -# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. -OTOOL64=$lt_OTOOL64 - -# Old archive suffix (normally "a"). -libext=$libext - -# Shared library suffix (normally ".so"). -shrext_cmds=$lt_shrext_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at link time. -variables_saved_for_relink=$lt_variables_saved_for_relink - -# Do we need the "lib" prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Library versioning type. -version_type=$version_type - -# Shared library runtime path variable. -runpath_var=$runpath_var - -# Shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Permission mode override for installation of shared libraries. -install_override_mode=$lt_install_override_mode - -# Command to use after installation of a shared archive. -postinstall_cmds=$lt_postinstall_cmds - -# Command to use after uninstallation of a shared archive. -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# As "finish_cmds", except a single script fragment to be evaled but -# not shown. -finish_eval=$lt_finish_eval - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Compile-time system search path for libraries. -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries. -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - - -# The linker used to build libraries. -LD=$lt_LD - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# Commands used to build an old-style archive. -old_archive_cmds=$lt_old_archive_cmds - -# A language specific compiler. -CC=$lt_compiler - -# Is the compiler the GNU compiler? -with_gcc=$GCC - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc - -# Whether or not to disallow shared libs when runtime libs are static. -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Whether the compiler copes with passing no objects directly. -compiler_needs_object=$lt_compiler_needs_object - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds - -# Commands used to build a loadable module if different from building -# a shared archive. -module_cmds=$lt_module_cmds -module_expsym_cmds=$lt_module_expsym_cmds - -# Whether we are building with GNU ld or not. -with_gnu_ld=$lt_with_gnu_ld - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that enforces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# If ld is used when linking, flag to hardcode \$libdir into a binary -# during linking. This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld - -# Whether we need a single "-rpath" flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary. -hardcode_direct=$hardcode_direct - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \${shlibpath_var} if the -# library is relocated. -hardcode_direct_absolute=$hardcode_direct_absolute - -# Set to "yes" if using the -LDIR flag during linking hardcodes DIR -# into the resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR -# into the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Set to "yes" if building a shared library automatically hardcodes DIR -# into the library and all subsequent libraries and executables linked -# against it. -hardcode_automatic=$hardcode_automatic - -# Set to yes if linker adds runtime paths of dependent libraries -# to runtime path list. -inherit_rpath=$inherit_rpath - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Set to "yes" if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# Commands necessary for linking programs (against libraries) with templates. -prelink_cmds=$lt_prelink_cmds - -# Commands necessary for finishing linking programs. -postlink_cmds=$lt_postlink_cmds - -# Specify filename containing input files. -file_list_spec=$lt_file_list_spec - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - -ltmain="$ac_aux_dir/ltmain.sh" - - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - if test x"$xsi_shell" = xyes; then - sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ -func_dirname ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_basename ()$/,/^} # func_basename /c\ -func_basename ()\ -{\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ -func_dirname_and_basename ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ -func_stripname ()\ -{\ -\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ -\ # positional parameters, so assign one to ordinary parameter first.\ -\ func_stripname_result=${3}\ -\ func_stripname_result=${func_stripname_result#"${1}"}\ -\ func_stripname_result=${func_stripname_result%"${2}"}\ -} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ -func_split_long_opt ()\ -{\ -\ func_split_long_opt_name=${1%%=*}\ -\ func_split_long_opt_arg=${1#*=}\ -} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ -func_split_short_opt ()\ -{\ -\ func_split_short_opt_arg=${1#??}\ -\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ -} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ -func_lo2o ()\ -{\ -\ case ${1} in\ -\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ -\ *) func_lo2o_result=${1} ;;\ -\ esac\ -} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_xform ()$/,/^} # func_xform /c\ -func_xform ()\ -{\ - func_xform_result=${1%.*}.lo\ -} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_arith ()$/,/^} # func_arith /c\ -func_arith ()\ -{\ - func_arith_result=$(( $* ))\ -} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_len ()$/,/^} # func_len /c\ -func_len ()\ -{\ - func_len_result=${#1}\ -} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - -fi - -if test x"$lt_shell_append" = xyes; then - sed -e '/^func_append ()$/,/^} # func_append /c\ -func_append ()\ -{\ - eval "${1}+=\\${2}"\ -} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ -func_append_quoted ()\ -{\ -\ func_quote_for_eval "${2}"\ -\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ -} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 -$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} -fi - - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" - - ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - - diff --git a/resources/3rdparty/glpk-4.53/configure.ac b/resources/3rdparty/glpk-4.53/configure.ac deleted file mode 100644 index 7f3de1878..000000000 --- a/resources/3rdparty/glpk-4.53/configure.ac +++ /dev/null @@ -1,147 +0,0 @@ -dnl Process this file with autoconf to produce a configure script - -AC_INIT([GLPK], [4.53], [bug-glpk@gnu.org]) - -AC_CONFIG_SRCDIR([src/glpk.h]) - -AC_CONFIG_MACRO_DIR([m4]) - -AM_INIT_AUTOMAKE - -AC_CONFIG_HEADERS([config.h]) - -AC_ARG_WITH(gmp, -AC_HELP_STRING([--with-gmp], - [use GNU MP bignum library [[default=no]]]), - [case $withval in - yes | no) ;; - *) AC_MSG_ERROR([invalid value `$withval' for --with-gmp]);; - esac], - [with_gmp=no]) - -AC_ARG_ENABLE(dl, -AC_HELP_STRING([--enable-dl], - [enable shared library support [[default=no]]]), - [case $enableval in - yes | ltdl | dlfcn | no) ;; - *) AC_MSG_ERROR([invalid value `$enableval' for --enable-dl]);; - esac], - [enable_dl=no]) - -AC_ARG_ENABLE(odbc, -AC_HELP_STRING([--enable-odbc], - [enable MathProg ODBC support [[default=no]]]), - [case $enableval in - yes | unix | no) ;; - *) AC_MSG_ERROR([invalid value `$enableval' for --enable-odbc]);; - esac], - [enable_odbc=no]) - -AC_ARG_ENABLE(mysql, -AC_HELP_STRING([--enable-mysql], - [enable MathProg MySQL support [[default=no]]]), - [case $enableval in - yes | no) ;; - *) AC_MSG_ERROR([invalid value `$enableval' for --enable-mysql]);; - esac], - [enable_mysql=no]) - -dnl Disable unnecessary libtool tests -define([AC_LIBTOOL_LANG_CXX_CONFIG], [:]) -define([AC_LIBTOOL_LANG_F77_CONFIG], [:]) -define([AC_LIBTOOL_LANG_GCJ_CONFIG], [:]) - -dnl Check for programs -AC_PROG_CC -AC_PROG_INSTALL -AC_PROG_LIBTOOL - -dnl Check for math library -AC_CHECK_LIB([m], [exp]) - -dnl Check for header -AC_CHECK_HEADER([sys/time.h], - AC_DEFINE([HAVE_SYS_TIME_H], [1], [N/A])) - -dnl Check for gettimeofday function -AC_CHECK_FUNC([gettimeofday], - AC_DEFINE([HAVE_GETTIMEOFDAY], [1], [N/A])) - -dnl Check for header -if test "$with_gmp" = "yes"; then - AC_CHECK_HEADER([gmp.h], [], - [AC_MSG_ERROR([gmp.h header not found])]) -fi - -AC_MSG_CHECKING([whether to use GNU MP bignum library]) -if test "$with_gmp" = "yes"; then - AC_MSG_RESULT([yes]) - AC_DEFINE([HAVE_GMP], [1], [N/A]) - LIBS="-lgmp $LIBS" -else - AC_MSG_RESULT([no]) -fi - -AC_MSG_CHECKING([whether to enable shared library support]) -if test "$enable_dl" = "yes"; then - AC_MSG_RESULT([ltdl]) - AC_DEFINE([HAVE_LTDL], [1], [N/A]) - LIBS="-lltdl $LIBS" -elif test "$enable_dl" = "ltdl"; then - AC_MSG_RESULT([ltdl]) - AC_DEFINE([HAVE_LTDL], [1], [N/A]) - LIBS="-lltdl $LIBS" -elif test "$enable_dl" = "dlfcn"; then - AC_MSG_RESULT([dlfcn]) - AC_DEFINE([HAVE_DLFCN], [1], [N/A]) -else - AC_MSG_RESULT([no]) -fi - -case $host_os in - darwin* | macosx*) - LIBIODBC="libiodbc.dylib" - LIBODBC="libodbc.dylib" - LIBMYSQL="libmysqlclient.dylib" - ;; - *) - LIBIODBC="libiodbc.so" - LIBODBC="libodbc.so" - LIBMYSQL="libmysqlclient.so" - ;; -esac - -AC_MSG_CHECKING([whether to enable MathProg ODBC support]) -if test "$enable_odbc" = "yes"; then - if test "$enable_dl" = "no"; then - AC_MSG_ERROR([--enable-odbc requires --enable-dl]) - fi - AC_MSG_RESULT([yes]) - AC_DEFINE_UNQUOTED([ODBC_DLNAME], ["$LIBIODBC"], [N/A]) -elif test "$enable_odbc" = "unix"; then - if test "$enable_dl" = "no"; then - AC_MSG_ERROR([--enable-odbc requires --enable-dl]) - fi - AC_MSG_RESULT([unix]) - AC_DEFINE_UNQUOTED([ODBC_DLNAME], ["$LIBODBC"], [N/A]) -else - AC_MSG_RESULT([no]) -fi - -AC_MSG_CHECKING([whether to enable MathProg MySQL support]) -if test "$enable_mysql" = "yes"; then - if test "$enable_dl" = "no"; then - AC_MSG_ERROR([--enable-mysql requires --enable-dl]) - fi - AC_MSG_RESULT([yes]) - CPPFLAGS="-I/usr/include/mysql $CPPFLAGS" - AC_DEFINE_UNQUOTED([MYSQL_DLNAME], ["$LIBMYSQL"], [N/A]) -else - AC_MSG_RESULT([no]) -fi - -AC_CONFIG_FILES( - [src/Makefile examples/Makefile Makefile]) -AC_OUTPUT - -dnl eof diff --git a/resources/3rdparty/glpk-4.53/depcomp b/resources/3rdparty/glpk-4.53/depcomp deleted file mode 100644 index e1f51f482..000000000 --- a/resources/3rdparty/glpk-4.53/depcomp +++ /dev/null @@ -1,787 +0,0 @@ -#! /bin/sh -# depcomp - compile a program generating dependencies as side-effects - -scriptversion=2012-07-12.20; # UTC - -# Copyright (C) 1999-2012 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Alexandre Oliva . - -case $1 in - '') - echo "$0: No command. Try '$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: depcomp [--help] [--version] PROGRAM [ARGS] - -Run PROGRAMS ARGS to compile a file, generating dependencies -as side-effects. - -Environment variables: - depmode Dependency tracking mode. - source Source file read by 'PROGRAMS ARGS'. - object Object file output by 'PROGRAMS ARGS'. - DEPDIR directory where to store dependencies. - depfile Dependency file to output. - tmpdepfile Temporary file to use when outputting dependencies. - libtool Whether libtool is used (yes/no). - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "depcomp $scriptversion" - exit $? - ;; -esac - -# A tabulation character. -tab=' ' -# A newline character. -nl=' -' - -if test -z "$depmode" || test -z "$source" || test -z "$object"; then - echo "depcomp: Variables source, object and depmode must be set" 1>&2 - exit 1 -fi - -# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. -depfile=${depfile-`echo "$object" | - sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} -tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} - -rm -f "$tmpdepfile" - -# Avoid interferences from the environment. -gccflag= dashmflag= - -# Some modes work just like other modes, but use different flags. We -# parameterize here, but still list the modes in the big case below, -# to make depend.m4 easier to write. Note that we *cannot* use a case -# here, because this file can only contain one case statement. -if test "$depmode" = hp; then - # HP compiler uses -M and no extra arg. - gccflag=-M - depmode=gcc -fi - -if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout -fi - -cygpath_u="cygpath -u -f -" -if test "$depmode" = msvcmsys; then - # This is just like msvisualcpp but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvisualcpp -fi - -if test "$depmode" = msvc7msys; then - # This is just like msvc7 but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvc7 -fi - -if test "$depmode" = xlc; then - # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. - gccflag=-qmakedep=gcc,-MF - depmode=gcc -fi - -case "$depmode" in -gcc3) -## gcc 3 implements dependency tracking that does exactly what -## we want. Yay! Note: for some reason libtool 1.4 doesn't like -## it if -MD -MP comes after the -MF stuff. Hmm. -## Unfortunately, FreeBSD c89 acceptance of flags depends upon -## the command line argument order; so add the flags where they -## appear in depend2.am. Note that the slowdown incurred here -## affects only configure: in makefiles, %FASTDEP% shortcuts this. - for arg - do - case $arg in - -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; - *) set fnord "$@" "$arg" ;; - esac - shift # fnord - shift # $arg - done - "$@" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - mv "$tmpdepfile" "$depfile" - ;; - -gcc) -## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. -## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. -## (see the conditional assignment to $gccflag above). -## There are various ways to get dependency output from gcc. Here's -## why we pick this rather obscure method: -## - Don't want to use -MD because we'd like the dependencies to end -## up in a subdir. Having to rename by hand is ugly. -## (We might end up doing this anyway to support other compilers.) -## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). Also, it might not be -## supported by the other compilers which use the 'gcc' depmode. -## - Using -M directly means running the compiler twice (even worse -## than renaming). - if test -z "$gccflag"; then - gccflag=-MD, - fi - "$@" -Wp,"$gccflag$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. - sed -e 's/^[^:]*: / /' \ - -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the "deleted header file" problem. -## The problem is that when a header file which appears in a .P file -## is deleted, the dependency causes make to die (because there is -## typically no way to rebuild the header). We avoid this by adding -## dummy dependencies for each header file. Too bad gcc doesn't do -## this for us directly. - tr ' ' "$nl" < "$tmpdepfile" | -## Some versions of gcc put a space before the ':'. On the theory -## that the space means something, we add a space to the output as -## well. hp depmode also adds that space, but also prefixes the VPATH -## to the object. Take care to not repeat it in the output. -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -sgi) - if test "$libtool" = yes; then - "$@" "-Wp,-MDupdate,$tmpdepfile" - else - "$@" -MDupdate "$tmpdepfile" - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - - if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files - echo "$object : \\" > "$depfile" - - # Clip off the initial element (the dependent). Don't try to be - # clever and replace this with sed code, as IRIX sed won't handle - # lines with more than a fixed number of characters (4096 in - # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like '#:fec' to the end of the - # dependency line. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr "$nl" ' ' >> "$depfile" - echo >> "$depfile" - - # The second pass generates a dummy entry for each header file. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -xlc) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -aix) - # The C for AIX Compiler uses -M and outputs the dependencies - # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts '$object:' at the - # start of each line; $object doesn't have directory information. - # Version 6 uses the directory in both cases. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.u - tmpdepfile2=$base.u - tmpdepfile3=$dir.libs/$base.u - "$@" -Wc,-M - else - tmpdepfile1=$dir$base.u - tmpdepfile2=$dir$base.u - tmpdepfile3=$dir$base.u - "$@" -M - fi - stat=$? - - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - # Each line is of the form 'foo.o: dependent.h'. - # Do two passes, one to just change these to - # '$object: dependent.h' and one to simply 'dependent.h:'. - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -icc) - # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'. - # However on - # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using '\': - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - # tcc 0.9.26 (FIXME still under development at the moment of writing) - # will emit a similar output, but also prepend the continuation lines - # with horizontal tabulation characters. - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each line is of the form 'foo.o: dependent.h', - # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'. - # Do two passes, one to just change these to - # '$object: dependent.h' and one to simply 'dependent.h:'. - sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \ - < "$tmpdepfile" > "$depfile" - sed ' - s/[ '"$tab"'][ '"$tab"']*/ /g - s/^ *// - s/ *\\*$// - s/^[^:]*: *// - /^$/d - /:$/d - s/$/ :/ - ' < "$tmpdepfile" >> "$depfile" - rm -f "$tmpdepfile" - ;; - -## The order of this option in the case statement is important, since the -## shell code in configure will try each of these formats in the order -## listed in this file. A plain '-MD' option would be understood by many -## compilers, so we must ensure this comes after the gcc and icc options. -pgcc) - # Portland's C compiler understands '-MD'. - # Will always output deps to 'file.d' where file is the root name of the - # source file under compilation, even if file resides in a subdirectory. - # The object file name does not affect the name of the '.d' file. - # pgcc 10.2 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using '\' : - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - # Use the source, not the object, to determine the base name, since - # that's sadly what pgcc will do too. - base=`echo "$source" | sed -e 's|^.*/||' -e 's/\.[-_a-zA-Z0-9]*$//'` - tmpdepfile="$base.d" - - # For projects that build the same source file twice into different object - # files, the pgcc approach of using the *source* file root name can cause - # problems in parallel builds. Use a locking strategy to avoid stomping on - # the same $tmpdepfile. - lockdir="$base.d-lock" - trap "echo '$0: caught signal, cleaning up...' >&2; rm -rf $lockdir" 1 2 13 15 - numtries=100 - i=$numtries - while test $i -gt 0 ; do - # mkdir is a portable test-and-set. - if mkdir $lockdir 2>/dev/null; then - # This process acquired the lock. - "$@" -MD - stat=$? - # Release the lock. - rm -rf $lockdir - break - else - ## the lock is being held by a different process, - ## wait until the winning process is done or we timeout - while test -d $lockdir && test $i -gt 0; do - sleep 1 - i=`expr $i - 1` - done - fi - i=`expr $i - 1` - done - trap - 1 2 13 15 - if test $i -le 0; then - echo "$0: failed to acquire lock after $numtries attempts" >&2 - echo "$0: check lockdir '$lockdir'" >&2 - exit 1 - fi - - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each line is of the form `foo.o: dependent.h', - # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp2) - # The "hp" stanza above does not work with aCC (C++) and HP's ia64 - # compilers, which have integrated preprocessors. The correct option - # to use with these is +Maked; it writes dependencies to a file named - # 'foo.d', which lands next to the object file, wherever that - # happens to be. - # Much of this is similar to the tru64 case; see comments there. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir.libs/$base.d - "$@" -Wc,+Maked - else - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir$base.d - "$@" +Maked - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" - # Add 'dependent.h:' lines. - sed -ne '2,${ - s/^ *// - s/ \\*$// - s/$/:/ - p - }' "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" "$tmpdepfile2" - ;; - -tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in 'foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - - if test "$libtool" = yes; then - # With Tru64 cc, shared objects can also be used to make a - # static library. This mechanism is used in libtool 1.4 series to - # handle both shared and static libraries in a single compilation. - # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. - # - # With libtool 1.5 this exception was removed, and libtool now - # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 - tmpdepfile2=$dir$base.o.d # libtool 1.5 - tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 - tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.o.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - tmpdepfile4=$dir$base.d - "$@" -MD - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -msvc7) - if test "$libtool" = yes; then - showIncludes=-Wc,-showIncludes - else - showIncludes=-showIncludes - fi - "$@" $showIncludes > "$tmpdepfile" - stat=$? - grep -v '^Note: including file: ' "$tmpdepfile" - if test "$stat" = 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - # The first sed program below extracts the file names and escapes - # backslashes for cygpath. The second sed program outputs the file - # name when reading, but also accumulates all include files in the - # hold buffer in order to output them again at the end. This only - # works with sed implementations that can handle large buffers. - sed < "$tmpdepfile" -n ' -/^Note: including file: *\(.*\)/ { - s//\1/ - s/\\/\\\\/g - p -}' | $cygpath_u | sort -u | sed -n ' -s/ /\\ /g -s/\(.*\)/'"$tab"'\1 \\/p -s/.\(.*\) \\/\1:/ -H -$ { - s/.*/'"$tab"'/ - G - p -}' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvc7msys) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -#nosideeffect) - # This comment above is used by automake to tell side-effect - # dependency tracking mechanisms from slower ones. - -dashmstdout) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - # Remove '-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for ':' - # in the target name. This is to cope with DOS-style filenames: - # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. - "$@" $dashmflag | - sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - tr ' ' "$nl" < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -dashXmstdout) - # This case only exists to satisfy depend.m4. It is never actually - # run, as this mode is specially recognized in the preamble. - exit 1 - ;; - -makedepend) - "$@" || exit $? - # Remove any Libtool call - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - # X makedepend - shift - cleared=no eat=no - for arg - do - case $cleared in - no) - set ""; shift - cleared=yes ;; - esac - if test $eat = yes; then - eat=no - continue - fi - case "$arg" in - -D*|-I*) - set fnord "$@" "$arg"; shift ;; - # Strip any option that makedepend may not understand. Remove - # the object too, otherwise makedepend will parse it as a source file. - -arch) - eat=yes ;; - -*|$object) - ;; - *) - set fnord "$@" "$arg"; shift ;; - esac - done - obj_suffix=`echo "$object" | sed 's/^.*\././'` - touch "$tmpdepfile" - ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" - rm -f "$depfile" - # makedepend may prepend the VPATH from the source file name to the object. - # No need to regex-escape $object, excess matching of '.' is harmless. - sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" "$tmpdepfile".bak - ;; - -cpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - # Remove '-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - "$@" -E | - sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - cat < "$tmpdepfile" >> "$depfile" - sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvisualcpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - IFS=" " - for arg - do - case "$arg" in - -o) - shift - ;; - $object) - shift - ;; - "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; - *) - set fnord "$@" "$arg" - shift - shift - ;; - esac - done - "$@" -E 2>/dev/null | - sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" - echo "$tab" >> "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvcmsys) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -none) - exec "$@" - ;; - -*) - echo "Unknown depmode $depmode" 1>&2 - exit 1 - ;; -esac - -exit 0 - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/resources/3rdparty/glpk-4.53/doc/cnfsat.pdf b/resources/3rdparty/glpk-4.53/doc/cnfsat.pdf deleted file mode 100644 index d7ff1932fe4de6ed4e0831b6c1b9c47db02e85a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59926 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 CJ^;)B diff --git a/resources/3rdparty/glpk-4.53/doc/cnfsat.tex b/resources/3rdparty/glpk-4.53/doc/cnfsat.tex deleted file mode 100644 index 4a2c3bbab..000000000 --- a/resources/3rdparty/glpk-4.53/doc/cnfsat.tex +++ /dev/null @@ -1,413 +0,0 @@ -%* cnfsat.tex *% - -\documentclass[11pt,draft]{article} -\usepackage{amssymb} -\usepackage{indentfirst} - -\setlength{\textwidth}{6.5in} -\setlength{\textheight}{8.5in} -\setlength{\oddsidemargin}{0in} -\setlength{\topmargin}{0in} -\setlength{\headheight}{0in} -\setlength{\headsep}{0in} -\setlength{\footskip}{0.5in} -\setlength{\parindent}{16pt} -\setlength{\parskip}{5pt} -\setlength{\topsep}{0pt} -\setlength{\partopsep}{0pt} -\setlength{\itemsep}{\parskip} -\setlength{\parsep}{0pt} -\setlength{\leftmargini}{\parindent} -\renewcommand{\labelitemi}{---} - -\def\para#1{\noindent{\bf#1}} -\def\synopsis{\para{Synopsis}} -\def\description{\para{Description}} -\def\returns{\para{Returns}} - -\newenvironment{retlist} -{ \def\arraystretch{1.5} - \noindent - \begin{tabular}{@{}p{1in}@{}p{5.5in}@{}} -} -{\end{tabular}} - -\begin{document} - -\title{\bf CNF Satisfiability Problem} - -\author{Andrew Makhorin {\tt}} - -\date{August 2011} - -\maketitle - -\section{Introduction} - -The {\it Satisfiability Problem (SAT)} is a classic combinatorial -problem. Given a Boolean formula of $n$ variables -$$f(x_1,x_2,\dots,x_n),\eqno(1.1)$$ -this problem is to find such values of the variables, on which the -formula takes on the value {\it true}. - -The {\it CNF Satisfiability Problem (CNF-SAT)} is a version of the -Satisfiability Problem, where the Boolean formula (1.1) is specified -in the {\it Conjunctive Normal Form (CNF)}, that means that it is a -conjunction of {\it clauses}, where a clause is a disjunction of -{\it literals}, and a literal is a variable or its negation. -For example: -$$(x_1\vee x_2)\;\&\;(\neg x_2\vee x_3\vee\neg x_4)\;\&\;(\neg -x_1\vee x_4).\eqno(1.2)$$ -Here $x_1$, $x_2$, $x_3$, $x_4$ are Boolean variables to be assigned, -$\neg$ means -negation (logical {\it not}), $\vee$ means disjunction (logical -{\it or}), and $\&$ means conjunction (logical {\it and}). One may -note that the formula (1.2) is {\it satisfiable}, because on -$x_1$ = {\it true}, $x_2$ = {\it false}, $x_3$ = {\it false}, and -$x_4$ = {\it true} it takes on the value {\it true}. If a formula -is not satisfiable, it is called {\it unsatisfiable}, that means that -it takes on the value {\it false} on any values of its variables. - -Any CNF-SAT problem can be easily translated to a 0-1 programming -problem as follows.\linebreak A Boolean variable $x$ can be modeled by -a binary variable in a natural way: $x=1$ means that $x$ takes on the -value {\it true}, and $x=0$ means that $x$ takes on the value -{\it false}. Then, if a literal is a negated variable, i.e. $t=\neg x$, -it can be expressed as $t=1-x$. Since a formula in CNF is a conjunction -of clauses, to provide its satisfiability we should require all its -clauses to take on the value {\it true}. A particular clause is -a disjunction of literals: -$$t\vee t'\vee t''\dots ,\eqno(1.3)$$ -so it takes on the value {\it true} iff at least one of its literals -takes on the value {\it true}, that can be expressed as the following -inequality constraint: -$$t+t'+t''+\dots\geq 1.\eqno(1.4)$$ -Note that no objective function is used in this case, because only -a feasible solution needs to be found. - -For example, the formula (1.2) can be translated to the following -constraints: -$$\begin{array}{c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c} -x_1&+&x_2&&&&&\geq&1\\ -&&(1-x_2)&+&x_3&+&(1-x_4)&\geq&1\\ -(1-x_1)&&&&&+&x_4&\geq&1\\ -\end{array}$$ -$$x_1, x_2, x_3, x_4\in\{0,1\}$$ -Carrying out all constant terms to the right-hand side gives -corresponding 0-1 programming problem in the standard format: -$$\begin{array}{r@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }r} -x_1&+&x_2&&&&&\geq&1\\ -&-&x_2&+&x_3&-&x_4&\geq&-1\\ --x_1&&&&&+&x_4&\geq&0\\ -\end{array}$$ -$$x_1, x_2, x_3, x_4\in\{0,1\}$$ - -In general case translation of a CNF-SAT problem results in the -following 0-1 programming problem: -$$\sum_{j\in J^+_i}x_j-\sum_{j\in J^-_i}x_j\geq 1-|J^-_i|, -\ \ \ i=1,\dots,m\eqno(1.5)$$ -$$x_j\in\{0,1\},\ \ \ j=1,\dots,n\eqno(1.6)$$ -where $n$ is the number of variables, $m$ is the number of clauses -(inequality constraints),\linebreak $J^+_i\subseteq\{1,\dots,n\}$ is -a subset of variables, whose literals in $i$-th clause do not have -negation, and $J^-_i\subseteq\{1,\dots,n\}$ is a subset of variables, -whose literals in $i$-th clause are negations of that variables. It is -assumed that $J^+_i\cap J^-_i=\varnothing$ for all $i$. - -\section{GLPK API Routines} - -\subsection{glp\_read\_cnfsat --- read CNF-SAT problem data in DIMACS -format} - -\synopsis - -\begin{verbatim} - int glp_read_cnfsat(glp_prob *P, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_read_cnfsat| reads the CNF-SAT problem data from -a text file in DIMACS format and automatically translates the data to -corresponding 0-1 programming problem instance (1.5)--(1.6). - -The parameter \verb|P| specifies the problem object, to which the -0-1 programming problem instance should be stored. Note that before -reading data the current content of the problem object is completely -erased with the routine \verb|glp_erase_prob|. - -The character string \verb|fname| specifies the name of a text file -to be read in. (If the file name ends with the suffix `\verb|.gz|', -the file is assumed to be compressed, in which case the routine -decompresses it ``on the fly''.) - -\newpage - -\returns - -If the operation was successful, the routine returns zero. Otherwise, -it prints an error message and returns non-zero. - -\para{DIMACS CNF-SAT problem format}\footnote{This material is based on -the paper ``Satisfiability Suggested Format'', which is publicly -available at {\tt http://dimacs.rutgers.edu/}.} - -The DIMACS input file is a plain ASCII text file. It contains lines of -several types described below. A line is terminated with an end-of-line -character. Fields in each line are separated by at least one blank -space. - -\para{Comment lines.} Comment lines give human-readable information -about the file and are ignored by programs. Comment lines can appear -anywhere in the file. Each comment line begins with a lower-case -character \verb|c|. - -\begin{verbatim} - c This is a comment line -\end{verbatim} - -\para{Problem line.} There is one problem line per data file. The -problem line must appear before any clause lines. It has the following -format: - -\begin{verbatim} - p cnf VARIABLES CLAUSES -\end{verbatim} - -\noindent -The lower-case character \verb|p| signifies that this is a problem -line. The three character problem designator \verb|cnf| identifies the -file as containing specification information for the CNF-SAT problem. -The \verb|VARIABLES| field contains an integer value specifying $n$, -the number of variables in the instance. The \verb|CLAUSES| field -contains an integer value specifying $m$, the number of clauses in the -instance. - -\para{Clauses.} The clauses appear immediately after the problem -line. The variables are assumed to be numbered from 1 up to $n$. It is -not necessary that every variable appears in the instance. Each clause -is represented by a sequence of numbers separated by either a space, -tab, or new-line character. The non-negated version of a variable $j$ -is represented by $j$; the negated version is represented by $-j$. Each -clause is terminated by the value 0. Unlike many formats that represent -the end of a clause by a new-line character, this format allows clauses -to be on multiple lines. - -\para{Example.} Below here is an example of the data file in DIMACS -format corresponding to the CNF-SAT problem (1.2). - -\begin{footnotesize} -\begin{verbatim} -c sample.cnf -c -c This is an example of the CNF-SAT problem data -c in DIMACS format. -c -p cnf 4 3 -1 2 0 --4 3 --2 0 --1 4 0 -c -c eof -\end{verbatim} -\end{footnotesize} - -\newpage - -\subsection{glp\_check\_cnfsat --- check for CNF-SAT problem instance} - -\synopsis - -\begin{verbatim} - int glp_check_cnfsat(glp\_prob *P); -\end{verbatim} - -\description - -The routine \verb|glp_check_cnfsat| checks if the specified problem -object \verb|P| contains a 0-1 programming problem instance in the -format (1.5)--(1.6) and therefore encodes a CNF-SAT problem instance. - -\returns - -If the specified problem object has the format (1.5)--(1.6), the -routine returns zero, otherwise non-zero. - -\subsection{glp\_write\_cnfsat --- write CNF-SAT problem data in DIMACS -format} - -\synopsis - -\begin{verbatim} - int glp_write_cnfsat(glp_prob *P, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_write_cnfsat| automatically translates the -specified 0-1 programming problem instance (1.5)--(1.6) to a CNF-SAT -problem instance and writes the problem data to a text file in DIMACS -format. - -The parameter \verb|P| is the problem object, which should specify -a 0-1 programming problem instance in the format (1.5)--(1.6). - -The character string \verb|fname| specifies a name of the output text -file to be written. (If the file name ends with suffix `\verb|.gz|', -the file is assumed to be compressed, in which case the routine -performs automatic compression on writing that file.) - -\returns - -If the operation was successful, the routine returns zero. Otherwise, -it prints an error message and returns non-zero. - -\subsection{glp\_minisat1 --- solve CNF-SAT problem instance with -MiniSat solver} - -\synopsis - -\begin{verbatim} - int glp_minisat1(glp_prob *P); -\end{verbatim} - -\description - -The routine \verb|glp_minisat1| is a driver to MiniSat, a CNF-SAT -solver developed by Niklas E\'en and Niklas S\"orensson, Chalmers -University of Technology, Sweden.\footnote{The MiniSat software module -is {\it not} part of GLPK, but is used with GLPK and included in the -distribution.} - -\newpage - -It is assumed that the specified problem object \verb|P| contains -a 0-1 programming problem instance in the format (1.5)--(1.6) and -therefore encodes a CNF-SAT problem instance. - -If the problem instance has been successfully solved to the end, the -routine \verb|glp_minisat1| returns 0. In this case the routine -\verb|glp_mip_status| can be used to determine the solution status: - -\begin{itemize} -\item {\tt GLP\_OPT} means that the solver found an integer feasible -solution and therefore the corresponding CNF-SAT instance is -satisfiable; - -\item {\tt GLP\_NOFEAS} means that no integer feasible solution exists -and therefore the corresponding CNF-SAT instance is unsatisfiable. -\end{itemize} - -If an integer feasible solution was found, corresponding values of -binary variables can be retrieved with the routine -\verb|glp_mip_col_val|. - -\returns - -\begin{retlist} -0 & The MIP problem instance has been successfully solved. (This code -does {\it not} necessarily mean that the solver has found feasible -solution. It only means that the solution process was successful.)\\ - -{\tt GLP\_EDATA} & The specified problem object contains a MIP -instance which does {\it not} have the format (1.5)--(1.6).\\ - -{\tt GLP\_EFAIL} & The solution process was unsuccessful because of -the solver failure.\\ -\end{retlist} - -\subsection{glp\_intfeas1 --- solve integer feasibility problem} - -\synopsis - -\begin{verbatim} - int glp_intfeas1(glp_prob *P, int use_bound, int obj_bound); -\end{verbatim} - -\description - -The routine \verb|glp_intfeas1| is a tentative implementation of -an integer feasibility solver based on a CNF-SAT solver (currently -it is MiniSat; see Subsection 2.4). - -If the parameter \verb|use_bound| is zero, the routine searches for -{\it any} integer feasibile solution to the specified integer -programming problem. Note that in this case the objective function is -ignored. - -If the parameter \verb|use_bound| is non-zero, the routine searches for -an integer feasible solution, which provides a value of the objective -function not worse than \verb|obj_bound|. In other word, the parameter -\verb|obj_bound| specifies an upper (in case of minimization) or lower -(in case of maximization) bound to the objective function. - -If the specified problem has been successfully solved to the end, the -routine \verb|glp_intfeas1| returns 0. In this case the routine -\verb|glp_mip_status| can be used to determine the solution status: - -\begin{itemize} -\item {\tt GLP\_FEAS} means that the solver found an integer feasible -solution; - -\item {\tt GLP\_NOFEAS} means that the problem has no integer feasible -solution (if {\tt use\_bound} is zero) or it has no integer feasible -solution, which is not worse than {\tt obj\_bound} (if {\tt use\_bound} -is non-zero). -\end{itemize} - -\newpage - -If an integer feasible solution was found, corresponding values of -variables (columns) can be retrieved with the routine -\verb|glp_mip_col_val|. - -\para{Usage Notes} - -The integer programming problem specified by the parameter \verb|P| -should satisfy to the following requirements: - -\begin{enumerate} -\item All variables (columns) should be either binary ({\tt GLP\_BV}) -or fixed at integer values ({\tt GLP\_FX}). - -\item All constraint and objective coefficients should be integer -numbers in the range\linebreak $[-2^{31},\ +2^{31}-1]$. -\end{enumerate} - -Though there are no special requirements to the constraints, -currently the routine \verb|glp_intfeas1| is efficient mainly for -problems, where most constraints (rows) fall into the following three -classes: - -\begin{enumerate} -\item Covering inequalities -$$\sum_{j}t_j\geq 1,$$ -where $t_j=x_j$ or $t_j=1-x_j$, $x_j$ is a binary variable. - -\item Packing inequalities -$$\sum_{j}t_j\leq 1.$$ - -\item Partitioning equalities (SOS1 constraints) -$$\sum_{j}t_j=1.$$ -\end{enumerate} - -\returns - -\begin{retlist} -0 & The problem has been successfully solved. (This code does -{\it not} necessarily mean that the solver has found an integer -feasible solution. It only means that the solution process was -successful.) \\ - -{\tt GLP\_EDATA} & The specified problem object does not satisfy -to the requirements listed in Paragraph `Usage Notes'. \\ - -{\tt GLP\_ERANGE} & An integer overflow occured on translating the -specified problem to a CNF-SAT problem. \\ - -{\tt GLP\_EFAIL} & The solution process was unsuccessful because of -the solver failure. \\ -\end{retlist} - -\end{document} diff --git a/resources/3rdparty/glpk-4.53/doc/glpk.pdf b/resources/3rdparty/glpk-4.53/doc/glpk.pdf deleted file mode 100644 index 670f58b3c56502d8749e805bbcd9b796fe2a4bc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 478088 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%0D+S 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 qGs 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�N~&evmRlE^te5Ju+ouTbJ+BkeG-}K! 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
  • jQrz7)i5d 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. -% -% GLPK is free software: you can redistribute it and/or modify it -% under the terms of the GNU General Public License as published by -% the Free Software Foundation, either version 3 of the License, or -% (at your option) any later version. -% -% GLPK is distributed in the hope that it will be useful, but WITHOUT -% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License -% along with GLPK. If not, see . -%*********************************************************************** - -\documentclass[11pt]{report} -\usepackage{amssymb} -\usepackage[dvipdfm,linktocpage,colorlinks,linkcolor=blue, -urlcolor=blue]{hyperref} -\usepackage{indentfirst} -\usepackage{lscape} -\usepackage[all]{xy} - -\setlength{\textwidth}{6.5in} -\setlength{\textheight}{8.5in} -\setlength{\oddsidemargin}{0in} -\setlength{\topmargin}{0in} -\setlength{\headheight}{0in} -\setlength{\headsep}{0in} -\setlength{\footskip}{0.5in} -\setlength{\parindent}{16pt} -\setlength{\parskip}{5pt} -\setlength{\topsep}{0pt} -\setlength{\partopsep}{0pt} -\setlength{\itemsep}{\parskip} -\setlength{\parsep}{0pt} -\setlength{\leftmargini}{\parindent} -\renewcommand{\labelitemi}{---} - -\def\para#1{\noindent{\bf#1}} -\def\synopsis{\para{Synopsis}} -\def\description{\para{Description}} -\def\returns{\para{Returns}} - -\renewcommand\contentsname{\sf\bfseries Contents} -\renewcommand\chaptername{\sf\bfseries Chapter} -\renewcommand\appendixname{\sf\bfseries Appendix} - -\newenvironment{retlist} -{ \def\arraystretch{1.5} - \noindent - \begin{tabular}{@{}p{1in}@{}p{5.5in}@{}} -} -{\end{tabular}} - -\begin{document} - -\thispagestyle{empty} - -\begin{center} - -\vspace*{1.5in} - -\begin{huge} -\sf\bfseries GNU Linear Programming Kit -\end{huge} - -\vspace{0.5in} - -\begin{LARGE} -\sf Reference Manual -\end{LARGE} - -\vspace{0.5in} - -\begin{LARGE} -\sf for GLPK Version 4.52 -\end{LARGE} - -\vspace{0.5in} -\begin{Large} -\sf (DRAFT, July 2013) -\end{Large} -\end{center} - -\newpage - -\vspace*{1in} - -\vfill - -\noindent -The GLPK package is part of the GNU Project released under the aegis of -GNU. - -\noindent -Copyright \copyright{} 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, -2008, 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -reserved. - -\noindent -Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -02110-1301, USA. - -\noindent -Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - -\noindent -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that -the entire resulting derived work is distributed under the terms of -a permission notice identical to this one. - -\noindent -Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -{\setlength{\parskip}{0pt} -\tableofcontents -} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\include{glpk01} - -\include{glpk02} - -\include{glpk03} - -\include{glpk04} - -\include{glpk05} - -\include{glpk06} - -\appendix - -\include{glpk07} - -\include{glpk08} - -\include{glpk09} - -\include{glpk10} - -\include{glpk11} - -\include{glpk12} - -\end{document} diff --git a/resources/3rdparty/glpk-4.53/doc/glpk01.tex b/resources/3rdparty/glpk-4.53/doc/glpk01.tex deleted file mode 100644 index 29ed67cce..000000000 --- a/resources/3rdparty/glpk-4.53/doc/glpk01.tex +++ /dev/null @@ -1,343 +0,0 @@ -%* glpk01.tex *% - -\chapter{Introduction} - -GLPK (\underline{G}NU \underline{L}inear \underline{P}rogramming -\underline{K}it) is a set of routines written in the ANSI C programming -language and organized in the form of a callable library. It is -intended for solving linear programming (LP), mixed integer programming -(MIP), and other related problems. - -\section{LP problem} -\label{seclp} - -GLPK assumes the following formulation of {\it linear programming (LP)} -problem: - -\medskip\noindent -\hspace{.5in} minimize (or maximize) -$$z = c_1x_{m+1} + c_2x_{m+2} + \dots + c_nx_{m+n} + c_0 \eqno (1.1)$$ -\hspace{.5in} subject to linear constraints -$$ -\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r} -x_1&=&a_{11}x_{m+1}&+&a_{12}x_{m+2}&+ \dots +&a_{1n}x_{m+n} \\ -x_2&=&a_{21}x_{m+1}&+&a_{22}x_{m+2}&+ \dots +&a_{2n}x_{m+n} \\ -\multicolumn{7}{c} -{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .} \\ -x_m&=&a_{m1}x_{m+1}&+&a_{m2}x_{m+2}&+ \dots +&a_{mn}x_{m+n} \\ -\end{array} \eqno (1.2) -$$ -\hspace{.5in} and bounds of variables -$$ -\begin{array}{r@{\:}c@{\:}c@{\:}c@{\:}l} -l_1&\leq&x_1&\leq&u_1 \\ -l_2&\leq&x_2&\leq&u_2 \\ -\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .}\\ -l_{m+n}&\leq&x_{m+n}&\leq&u_{m+n} \\ -\end{array} \eqno (1.3) -$$ - -\medskip\noindent -where: $x_1, x_2, \dots, x_m$ are auxiliary variables; -$x_{m+1}, x_{m+2}, \dots, x_{m+n}$ are structural variables; -$z$ is the objective function; -$c_1, c_2, \dots, c_n$ are objective coefficients; -$c_0$ is the constant term (``shift'') of the objective function; -$a_{11}, a_{12}, \dots, a_{mn}$ are constraint coefficients; -$l_1, l_2, \dots, l_{m+n}$ are lower bounds of variables; -$u_1, u_2, \dots, u_{m+n}$ are upper bounds of variables. - -Auxiliary variables are also called {\it rows}, because they correspond -to rows of the constraint matrix (i.e. a matrix built of the constraint -coefficients). Similarly, structural variables are also called -{\it columns}, because they correspond to columns of the constraint -matrix. - -Bounds of variables can be finite as well as infinite. Besides, lower -and upper bounds can be equal to each other. Thus, the following types -of variables are possible: - -\begin{center} -\begin{tabular}{r@{}c@{}ll} -\multicolumn{3}{c}{Bounds of variable} & Type of variable \\ -\hline -$-\infty <$ &$\ x_k\ $& $< +\infty$ & Free (unbounded) variable \\ -$l_k \leq$ &$\ x_k\ $& $< +\infty$ & Variable with lower bound \\ -$-\infty <$ &$\ x_k\ $& $\leq u_k$ & Variable with upper bound \\ -$l_k \leq$ &$\ x_k\ $& $\leq u_k$ & Double-bounded variable \\ -$l_k =$ &$\ x_k\ $& $= u_k$ & Fixed variable \\ -\end{tabular} -\end{center} - -\noindent -Note that the types of variables shown above are applicable to -structural as well as to auxiliary variables. - -To solve the LP problem (1.1)---(1.3) is to find such values of all -structural and auxiliary variables, which: - -\vspace*{-10pt} - -\begin{itemize}\setlength{\itemsep}{0pt} -\item satisfy to all the linear constraints (1.2), and - -\item are within their bounds (1.3), and - -\item provide smallest (in case of minimization) or largest (in case of -maximization) value of the objective function (1.1). -\end{itemize} - -\section{MIP problem} - -{\it Mixed integer linear programming (MIP)} problem is an LP problem -in which some variables are additionally required to be integer. - -GLPK assumes that MIP problem has the same formulation as ordinary -(pure) LP problem (1.1)---(1.3), i.e. includes auxiliary and structural -variables, which may have lower and/or upper bounds. However, in case -of MIP problem some variables may be required to be integer. This -additional constraint means that a value of each {\it integer variable} -must be only integer number. (Should note that GLPK allows only -structural variables to be of integer kind.) - -\section{Using the package} - -\subsection{Brief example} - -In order to understand what GLPK is from the user's standpoint, -consider the following simple LP problem: - -\medskip - -\noindent -\hspace{.5in} maximize -$$z = 10 x_1 + 6 x_2 + 4 x_3$$ -\hspace{.5in} subject to -$$ -\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r} -x_1 &+&x_2 &+&x_3 &\leq 100 \\ -10 x_1 &+& 4 x_2 & +&5 x_3 & \leq 600 \\ -2 x_1 &+& 2 x_2 & +& 6 x_3 & \leq 300 \\ -\end{array} -$$ -\hspace{.5in} where all variables are non-negative -$$x_1 \geq 0, \ x_2 \geq 0, \ x_3 \geq 0$$ - -At first, this LP problem should be transformed to the standard form -(1.1)---(1.3). This can be easily done by introducing auxiliary -variables, by one for each original inequality constraint. Thus, the -problem can be reformulated as follows: - -\medskip - -\noindent -\hspace{.5in} maximize -$$z = 10 x_1 + 6 x_2 + 4 x_3$$ -\hspace{.5in} subject to -$$ -\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r} -p& = &x_1 &+&x_2 &+&x_3 \\ -q& = &10 x_1 &+& 4 x_2 &+& 5 x_3 \\ -r& = &2 x_1 &+& 2 x_2 &+& 6 x_3 \\ -\end{array} -$$ -\hspace{.5in} and bounds of variables -$$ -\begin{array}{ccc} -\nonumber -\infty < p \leq 100 && 0 \leq x_1 < +\infty \\ -\nonumber -\infty < q \leq 600 && 0 \leq x_2 < +\infty \\ -\nonumber -\infty < r \leq 300 && 0 \leq x_3 < +\infty \\ -\end{array} -$$ - -\medskip - -where $p, q, r$ are auxiliary variables (rows), and $x_1, x_2, x_3$ are -structural variables (columns). - -The example C program shown below uses GLPK API routines in order to -solve this LP problem.\footnote{If you just need to solve LP or MIP -instance, you may write it in MPS or CPLEX LP format and then use the -GLPK stand-alone solver to obtain a solution. This is much less -time-consuming than programming in C with GLPK API routines.} - -\begin{footnotesize} -\begin{verbatim} -/* sample.c */ - -#include -#include -#include - -int main(void) -{ glp_prob *lp; - int ia[1+1000], ja[1+1000]; - double ar[1+1000], z, x1, x2, x3; -s1: lp = glp_create_prob(); -s2: glp_set_prob_name(lp, "sample"); -s3: glp_set_obj_dir(lp, GLP_MAX); -s4: glp_add_rows(lp, 3); -s5: glp_set_row_name(lp, 1, "p"); -s6: glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 100.0); -s7: glp_set_row_name(lp, 2, "q"); -s8: glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 600.0); -s9: glp_set_row_name(lp, 3, "r"); -s10: glp_set_row_bnds(lp, 3, GLP_UP, 0.0, 300.0); -s11: glp_add_cols(lp, 3); -s12: glp_set_col_name(lp, 1, "x1"); -s13: glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0); -s14: glp_set_obj_coef(lp, 1, 10.0); -s15: glp_set_col_name(lp, 2, "x2"); -s16: glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0); -s17: glp_set_obj_coef(lp, 2, 6.0); -s18: glp_set_col_name(lp, 3, "x3"); -s19: glp_set_col_bnds(lp, 3, GLP_LO, 0.0, 0.0); -s20: glp_set_obj_coef(lp, 3, 4.0); -s21: ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */ -s22: ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */ -s23: ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */ -s24: ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */ -s25: ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */ -s26: ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */ -s27: ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */ -s28: ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */ -s29: ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */ -s30: glp_load_matrix(lp, 9, ia, ja, ar); -s31: glp_simplex(lp, NULL); -s32: z = glp_get_obj_val(lp); -s33: x1 = glp_get_col_prim(lp, 1); -s34: x2 = glp_get_col_prim(lp, 2); -s35: x3 = glp_get_col_prim(lp, 3); -s36: printf("\nz = %g; x1 = %g; x2 = %g; x3 = %g\n", - z, x1, x2, x3); -s37: glp_delete_prob(lp); - return 0; -} - -/* eof */ -\end{verbatim} -\end{footnotesize} - -The statement \verb|s1| creates a problem object. Being created the -object is initially empty. The statement \verb|s2| assigns a symbolic -name to the problem object. - -The statement \verb|s3| calls the routine \verb|glp_set_obj_dir| in -order to set the optimization direction flag, where \verb|GLP_MAX| -means maximization. - -The statement \verb|s4| adds three rows to the problem object. - -The statement \verb|s5| assigns the symbolic name `\verb|p|' to the -first row, and the statement \verb|s6| sets the type and bounds of the -first row, where \verb|GLP_UP| means that the row has an upper bound. -The statements \verb|s7|, \verb|s8|, \verb|s9|, \verb|s10| are used in -the same way in order to assign the symbolic names `\verb|q|' and -`\verb|r|' to the second and third rows and set their types and bounds. - -The statement \verb|s11| adds three columns to the problem object. - -The statement \verb|s12| assigns the symbolic name `\verb|x1|' to the -first column, the statement \verb|s13| sets the type and bounds of the -first column, where \verb|GLP_LO| means that the column has an lower -bound, and the statement \verb|s14| sets the objective coefficient for -the first column. The statements \verb|s15|---\verb|s20| are used in -the same way in order to assign the symbolic names `\verb|x2|' and -`\verb|x3|' to the second and third columns and set their types, -bounds, and objective coefficients. - -The statements \verb|s21|---\verb|s29| prepare non-zero elements of the -constraint matrix (i.e. constraint coefficients). Row indices of each -element are stored in the array \verb|ia|, column indices are stored in -the array \verb|ja|, and numerical values of corresponding elements are -stored in the array \verb|ar|. Then the statement \verb|s30| calls -the routine \verb|glp_load_matrix|, which loads information from these -three arrays into the problem object. - -Now all data have been entered into the problem object, and therefore -the statement \verb|s31| calls the routine \verb|glp_simplex|, which is -a driver to the simplex method, in order to solve the LP problem. This -routine finds an optimal solution and stores all relevant information -back into the problem object. - -The statement \verb|s32| obtains a computed value of the objective -function, and the statements \verb|s33|---\verb|s35| obtain computed -values of structural variables (columns), which correspond to the -optimal basic solution found by the solver. - -The statement \verb|s36| writes the optimal solution to the standard -output. The printout may look like follows: - -\begin{footnotesize} -\begin{verbatim} -* 0: objval = 0.000000000e+00 infeas = 0.000000000e+00 (0) -* 2: objval = 7.333333333e+02 infeas = 0.000000000e+00 (0) -OPTIMAL SOLUTION FOUND - -z = 733.333; x1 = 33.3333; x2 = 66.6667; x3 = 0 -\end{verbatim} -\end{footnotesize} - -Finally, the statement \verb|s37| calls the routine -\verb|glp_delete_prob|, which frees all the memory allocated to the -problem object. - -\subsection{Compiling} - -The GLPK package has the only header file \verb|glpk.h|, which should -be available on compiling a C (or C++) program using GLPK API routines. - -If the header file is installed in the default location -\verb|/usr/local/include|, the following typical command may be used to -compile, say, the example C program described above with the GNU C -compiler: - -\begin{verbatim} - $ gcc -c sample.c -\end{verbatim} - -If \verb|glpk.h| is not in the default location, the corresponding -directory containing it should be made known to the C compiler through -\verb|-I| option, for example: - -\begin{verbatim} - $ gcc -I/foo/bar/glpk-4.15/include -c sample.c -\end{verbatim} - -In any case the compilation results in an object file \verb|sample.o|. - -\subsection{Linking} - -The GLPK library is a single file \verb|libglpk.a|. (On systems which -support shared libraries there may be also a shared version of the -library \verb|libglpk.so|.) - -If the library is installed in the default -location \verb|/usr/local/lib|, the following typical command may be -used to link, say, the example C program described above against with -the library: - -\begin{verbatim} - $ gcc sample.o -lglpk -lm -\end{verbatim} - -If the GLPK library is not in the default location, the corresponding -directory containing it should be made known to the linker through -\verb|-L| option, for example: - -\begin{verbatim} - $ gcc -L/foo/bar/glpk-4.15 sample.o -lglpk -lm -\end{verbatim} - -Depending on configuration of the package linking against with the GLPK -library may require optional libraries, in which case these libraries -should be also made known to the linker, for example: - -\begin{verbatim} - $ gcc sample.o -lglpk -lgmp -lm -\end{verbatim} - -For more details about configuration options of the GLPK package see -Appendix \ref{install}, page \pageref{install}. - -%* eof *% diff --git a/resources/3rdparty/glpk-4.53/doc/glpk02.tex b/resources/3rdparty/glpk-4.53/doc/glpk02.tex deleted file mode 100644 index c2663026e..000000000 --- a/resources/3rdparty/glpk-4.53/doc/glpk02.tex +++ /dev/null @@ -1,3428 +0,0 @@ -%* glpk02.tex *% - -\chapter{Basic API Routines} - -\section{General conventions} - -\subsection{Library header} - -All GLPK API data types and routines are defined in the header file -\verb|glpk.h|. It should be included in all source files which use -GLPK API, either directly or indirectly through some other header file -as follows: - -\begin{verbatim} - #include -\end{verbatim} - -\subsection{Error handling} - -If some GLPK API routine detects erroneous or incorrect data passed by -the application program, it writes appropriate diagnostic messages to -the terminal and then abnormally terminates the application program. -In most practical cases this allows to simplify programming by avoiding -numerous checks of return codes. Thus, in order to prevent crashing the -application program should check all data, which are suspected to be -incorrect, before calling GLPK API routines. - -Should note that this kind of error handling is used only in cases of -incorrect data passed by the application program. If, for example, the -application program calls some GLPK API routine to read data from an -input file and these data are incorrect, the GLPK API routine reports -about error in the usual way by means of the return code. - -\subsection{Thread safety} - -The standard version of GLPK API is {\it not} thread safe and therefore -should not be used in multi-threaded programs. - -\subsection{Array indexing} - -Normally all GLPK API routines start array indexing from 1, not from 0 -(except the specially stipulated cases). This means, for example, that -if some vector $x$ of the length $n$ is passed as an array to some GLPK -API routine, the latter expects vector components to be placed in -locations \verb|x[1]|, \verb|x[2]|, \dots, \verb|x[n]|, and the -location \verb|x[0]| normally is not used. - -To avoid indexing errors it is most convenient and most reliable to -declare the array \verb|x| as follows: - -\begin{verbatim} - double x[1+n]; -\end{verbatim} - -\noindent -or to allocate it as follows: - -\begin{verbatim} - double *x; - . . . - x = calloc(1+n, sizeof(double)); - . . . -\end{verbatim} - -\noindent -In both cases one extra location \verb|x[0]| is reserved that allows -passing the array to GLPK routines in a usual way. - -\section{Problem object} - -All GLPK API routines deal with so called {\it problem object}, which -is a program object of type \verb|glp_prob| and intended to represent -a particular LP or MIP instance. - -The type \verb|glp_prob| is a data structure declared in the header -file \verb|glpk.h| as follows: - -\begin{verbatim} - typedef struct glp_prob glp_prob; -\end{verbatim} - -Problem objects (i.e. program objects of the \verb|glp_prob| type) are -allocated and managed internally by the GLPK API routines. The -application program should never use any members of the \verb|glp_prob| -structure directly and should deal only with pointers to these objects -(that is, \verb|glp_prob *| values). - -The problem object consists of the following segments: - -\vspace*{-8pt} - -\begin{itemize}\setlength{\itemsep}{0pt} -\item problem segment, - -\item basis segment, - -\item interior-point segment, and - -\item MIP segment. -\end{itemize} - -\subsection{Problem segment} - -The {\it problem segment} contains original LP/MIP data, which -corresponds to the problem formulation (1.1)---(1.3) (see Section -\ref{seclp}, page \pageref{seclp}). This segment includes the following -components: - -\vspace*{-8pt} - -\begin{itemize}\setlength{\itemsep}{0pt} -\item rows (auxiliary variables), - -\item columns (structural variables), - -\item objective function, and - -\item constraint matrix. -\end{itemize} - -\vspace*{-7pt} - -Rows and columns have the same set of the following attributes: - -\vspace*{-7pt} - -\begin{itemize}\setlength{\itemsep}{0pt} -\item ordinal number, - -\item symbolic name (1 up to 255 arbitrary graphic characters), - -\item type (free, lower bound, upper bound, double bound, fixed), - -\item numerical values of lower and upper bounds, - -\item scale factor. -\end{itemize} - -\vspace*{-7pt} - -{\it Ordinal numbers} are intended for referencing rows and columns. -Row ordinal numbers are integers $1, 2, \dots, m$, and column ordinal -numbers are integers $1, 2, \dots, n$, where $m$ and $n$ are, -respectively, the current number of rows and columns in the problem -object. - -{\it Symbolic names} are intended for informational purposes. They also -can be used for referencing rows and columns. - -{\it Types and bounds} of rows (auxiliary variables) and columns -(structural variables) are explained above (see Section \ref{seclp}, -page \pageref{seclp}). - -{\it Scale factors} are used internally for scaling rows and columns of -the constraint matrix. - -Information about the {\it objective function} includes numerical -values of objective coefficients and a flag, which defines the -optimization direction (i.e. minimization or maximization). - -The {\it constraint matrix} is a $m \times n$ rectangular matrix built -of constraint coefficients $a_{ij}$, which defines the system of linear -constraints (1.2) (see Section \ref{seclp}, page \pageref{seclp}). This -matrix is stored in the problem object in both row-wise and column-wise -sparse formats. - -Once the problem object has been created, the application program can -access and modify any components of the problem segment in arbitrary -order. - -\subsection{Basis segment} - -The {\it basis segment} of the problem object keeps information related -to the current basic solution. It includes: - -\vspace*{-8pt} - -\begin{itemize}\setlength{\itemsep}{0pt} -\item row and column statuses, - -\item basic solution statuses, - -\item factorization of the current basis matrix, and - -\item basic solution components. -\end{itemize} - -\vspace*{-8pt} - -The {\it row and column statuses} define which rows and columns are -basic and which are non-basic. These statuses may be assigned either by -the application program of by some API routines. Note that these -statuses are always defined independently on whether the corresponding -basis is valid or not. - -The {\it basic solution statuses} include the {\it primal status} and -the {\it dual status}, which are set by the simplex-based solver once -the problem has been solved. The primal status shows whether a primal -basic solution is feasible, infeasible, or undefined. The dual status -shows the same for a dual basic solution. - -The {\it factorization of the basis matrix} is some factorized form -(like {\it LU}-factorization) of the current basis matrix (defined by -the current row and column statuses). The factorization is used by -simplex-based solvers and kept when the solver terminates the search. -This feature allows efficiently reoptimizing the problem after some -modifications (for example, after changing some bounds or objective -coefficients). It also allows performing the post-optimal analysis (for -example, computing components of the simplex table, etc.). - -The {\it basic solution components} include primal and dual values of -all auxiliary and structural variables for the most recently obtained -basic solution. - -\subsection{Interior-point segment} - -The {\it interior-point segment} contains interior-point solution -components, which include the solution status, and primal and dual -values of all auxiliary and structural variables. - -\subsection{MIP segment} - -The {\it MIP segment} is used only for MIP problems. This segment -includes: - -\vspace*{-8pt} - -\begin{itemize}\setlength{\itemsep}{0pt} -\item column kinds, - -\item MIP solution status, and - -\item MIP solution components. -\end{itemize} - -\vspace*{-8pt} - -The {\it column kinds} define which columns (i.e. structural variables) -are integer and which are continuous. - -The {\it MIP solution status} is set by the MIP solver and shows whether -a MIP solution is integer optimal, integer feasible (non-optimal), or -undefined. - -The {\it MIP solution components} are computed by the MIP solver and -include primal values of all auxiliary and structural variables for the -most recently obtained MIP solution. - -Note that in case of MIP problem the basis segment corresponds to -the optimal solution of LP relaxation, which is also available to the -application program. - -Currently the search tree is not kept in the MIP segment, so if the -search has been terminated, it cannot be continued. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Problem creating and modifying routines} - -\subsection{glp\_create\_prob --- create problem object} - -\synopsis - -\begin{verbatim} - glp_prob *glp_create_prob(void); -\end{verbatim} - -\description - -The routine \verb|glp_create_prob| creates a new problem object, which -initially is ``empty'', i.e. has no rows and columns. - -\returns - -The routine returns a pointer to the created object, which should be -used in any subsequent operations on this object. - -\subsection{glp\_set\_prob\_name --- assign (change) problem name} - -\synopsis - -\begin{verbatim} - void glp_set_prob_name(glp_prob *P, const char *name); -\end{verbatim} - -\description - -The routine \verb|glp_set_prob_name| assigns a given symbolic -\verb|name| (1 up to 255 characters) to the specified problem object. - -If the parameter \verb|name| is \verb|NULL| or empty string, the -routine erases an existing symbolic name of the problem object. - -\subsection{glp\_set\_obj\_name --- assign (change) objective function -name} - -\synopsis - -\begin{verbatim} - void glp_set_obj_name(glp_prob *P, const char *name); -\end{verbatim} - -\description - -The routine \verb|glp_set_obj_name| assigns a given symbolic -\verb|name| (1 up to 255 characters) to the objective function of the -specified problem object. - -If the parameter \verb|name| is \verb|NULL| or empty string, the -routine erases an existing symbolic name of the objective function. - -\newpage - -\subsection{glp\_set\_obj\_dir --- set (change) optimization direction -flag} - -\synopsis - -\begin{verbatim} - void glp_set_obj_dir(glp_prob *P, int dir); -\end{verbatim} - -\description - -The routine \verb|glp_set_obj_dir| sets (changes) the optimization -direction flag (i.e. ``sense'' of the objective function) as specified -by the parameter \verb|dir|: - -\verb|GLP_MIN| means minimization; - -\verb|GLP_MAX| means maximization. - -\noindent -(Note that by default the problem is minimization.) - -\subsection{glp\_add\_rows --- add new rows to problem object} - -\synopsis - -\begin{verbatim} - int glp_add_rows(glp_prob *P, int nrs); -\end{verbatim} - -\description - -The routine \verb|glp_add_rows| adds \verb|nrs| rows (constraints) to -the specified problem object. New rows are always added to the end of -the row list, so the ordinal numbers of existing rows are not changed. - -Being added each new row is initially free (unbounded) and has empty -list of the constraint coefficients. - -\returns - -The routine \verb|glp_add_rows| returns the ordinal number of the first -new row added to the problem object. - -\subsection{glp\_add\_cols --- add new columns to problem object} - -\synopsis - -\begin{verbatim} - int glp_add_cols(glp_prob *P, int ncs); -\end{verbatim} - -\description - -The routine \verb|glp_add_cols| adds \verb|ncs| columns (structural -variables) to the specified problem object. New columns are always -added to the end of the column list, so the ordinal numbers of existing -columns are not changed. - -Being added each new column is initially fixed at zero and has empty -list of the constraint coefficients. - -\returns - -The routine \verb|glp_add_cols| returns the ordinal number of the first -new column added to the problem object. - -\subsection{glp\_set\_row\_name --- assign (change) row name} - -\synopsis - -\begin{verbatim} - void glp_set_row_name(glp_prob *P, int i, const char *name); -\end{verbatim} - -\description - -The routine \verb|glp_set_row_name| assigns a given symbolic -\verb|name| (1 up to 255 characters) to \verb|i|-th row (auxiliary -variable) of the specified problem object. - -If the parameter \verb|name| is \verb|NULL| or empty string, the -routine erases an existing name of $i$-th row. - -\subsection{glp\_set\_col\_name --- assign (change) column name} - -\synopsis - -\begin{verbatim} - void glp_set_col_name(glp_prob *P, int j, const char *name); -\end{verbatim} - -\description - -The routine \verb|glp_set_col_name| assigns a given symbolic -\verb|name| (1 up to 255 characters) to \verb|j|-th column (structural -variable) of the specified problem object. - -If the parameter \verb|name| is \verb|NULL| or empty string, the -routine erases an existing name of $j$-th column. - -\subsection{glp\_set\_row\_bnds --- set (change) row bounds} - -\synopsis - -{\tt void glp\_set\_row\_bnds(glp\_prob *P, int i, int type, -double lb, double ub);} - -\description - -The routine \verb|glp_set_row_bnds| sets (changes) the type and bounds -of \verb|i|-th row (auxiliary variable) of the specified problem -object. - -The parameters \verb|type|, \verb|lb|, and \verb|ub| specify the type, -lower bound, and upper bound, respectively, as follows: - -\begin{center} -\begin{tabular}{cr@{}c@{}ll} -Type & \multicolumn{3}{c}{Bounds} & Comment \\ -\hline -\verb|GLP_FR| & $-\infty <$ &$\ x\ $& $< +\infty$ - & Free (unbounded) variable \\ -\verb|GLP_LO| & $lb \leq$ &$\ x\ $& $< +\infty$ - & Variable with lower bound \\ -\verb|GLP_UP| & $-\infty <$ &$\ x\ $& $\leq ub$ - & Variable with upper bound \\ -\verb|GLP_DB| & $lb \leq$ &$\ x\ $& $\leq ub$ - & Double-bounded variable \\ -\verb|GLP_FX| & $lb =$ &$\ x\ $& $= ub$ - & Fixed variable \\ -\end{tabular} -\end{center} - -\noindent -where $x$ is the auxiliary variable associated with $i$-th row. - -If the row has no lower bound, the parameter \verb|lb| is ignored. If -the row has no upper bound, the parameter \verb|ub| is ignored. If the -row is an equality constraint (i.e. the corresponding auxiliary -variable is of fixed type), only the parameter \verb|lb| is used while -the parameter \verb|ub| is ignored. - -Being added to the problem object each row is initially free, i.e. its -type is \verb|GLP_FR|. - -\subsection{glp\_set\_col\_bnds --- set (change) column bounds} - -\synopsis - -{\tt void glp\_set\_col\_bnds(glp\_prob *P, int j, int type, -double lb, double ub);} - -\description - -The routine \verb|glp_set_col_bnds| sets (changes) the type and bounds -of \verb|j|-th column (structural variable) of the specified problem -object. - -The parameters \verb|type|, \verb|lb|, and \verb|ub| specify the type, -lower bound, and upper bound, respectively, as follows: - -\begin{center} -\begin{tabular}{cr@{}c@{}ll} -Type & \multicolumn{3}{c}{Bounds} & Comment \\ -\hline -\verb|GLP_FR| & $-\infty <$ &$\ x\ $& $< +\infty$ - & Free (unbounded) variable \\ -\verb|GLP_LO| & $lb \leq$ &$\ x\ $& $< +\infty$ - & Variable with lower bound \\ -\verb|GLP_UP| & $-\infty <$ &$\ x\ $& $\leq ub$ - & Variable with upper bound \\ -\verb|GLP_DB| & $lb \leq$ &$\ x\ $& $\leq ub$ - & Double-bounded variable \\ -\verb|GLP_FX| & $lb =$ &$\ x\ $& $= ub$ - & Fixed variable \\ -\end{tabular} -\end{center} - -\noindent -where $x$ is the structural variable associated with $j$-th column. - -If the column has no lower bound, the parameter \verb|lb| is ignored. -If the column has no upper bound, the parameter \verb|ub| is ignored. -If the column is of fixed type, only the parameter \verb|lb| is used -while the parameter \verb|ub| is ignored. - -Being added to the problem object each column is initially fixed at -zero, i.e. its type is \verb|GLP_FX| and both bounds are 0. - -\subsection{glp\_set\_obj\_coef --- set (change) objective coefficient -or constant term} - -\synopsis - -\begin{verbatim} - void glp_set_obj_coef(glp_prob *P, int j, double coef); -\end{verbatim} - -\description - -The routine \verb|glp_set_obj_coef| sets (changes) the objective -coefficient at \verb|j|-th column (structural variable). A new value of -the objective coefficient is specified by the parameter \verb|coef|. - -If the parameter \verb|j| is 0, the routine sets (changes) the constant -term (``shift'') of the objective function. - -\newpage - -\subsection{glp\_set\_mat\_row --- set (replace) row of the constraint -matrix} - -\synopsis - -\begin{verbatim} - void glp_set_mat_row(glp_prob *P, int i, int len, const int ind[], - const double val[]); -\end{verbatim} - -\description - -The routine \verb|glp_set_mat_row| stores (replaces) the contents of -\verb|i|-th row of the constraint matrix of the specified problem -object. - -Column indices and numerical values of new row elements should be -placed in locations\linebreak \verb|ind[1]|, \dots, \verb|ind[len]| and -\verb|val[1]|, \dots, \verb|val[len]|, respectively, where -$0 \leq$ \verb|len| $\leq n$ is the new length of $i$-th row, $n$ is -the current number of columns in the problem object. Elements with -identical column indices are not allowed. Zero elements are allowed, -but they are not stored in the constraint matrix. - -If the parameter \verb|len| is 0, the parameters \verb|ind| and/or -\verb|val| can be specified as \verb|NULL|. - -\subsection{glp\_set\_mat\_col --- set (replace) column of the -constr\-aint matrix} - -\synopsis - -\begin{verbatim} - void glp_set_mat_col(glp_prob *P, int j, int len, const int ind[], - const double val[]); -\end{verbatim} - -\description - -The routine \verb|glp_set_mat_col| stores (replaces) the contents of -\verb|j|-th column of the constraint matrix of the specified problem -object. - -Row indices and numerical values of new column elements should be -placed in locations\linebreak \verb|ind[1]|, \dots, \verb|ind[len]| and -\verb|val[1]|, \dots, \verb|val[len]|, respectively, where -$0 \leq$ \verb|len| $\leq m$ is the new length of $j$-th column, $m$ is -the current number of rows in the problem object. Elements with -identical row indices are not allowed. Zero elements are allowed, but -they are not stored in the constraint matrix. - -If the parameter \verb|len| is 0, the parameters \verb|ind| and/or -\verb|val| can be specified as \verb|NULL|. - -\subsection{glp\_load\_matrix --- load (replace) the whole constraint -matrix} - -\synopsis - -\begin{verbatim} - void glp_load_matrix(glp_prob *P, int ne, const int ia[], - const int ja[], const double ar[]); -\end{verbatim} - -\description - -The routine \verb|glp_load_matrix| loads the constraint matrix passed -in the arrays \verb|ia|, \verb|ja|, and \verb|ar| into the specified -problem object. Before loading the current contents of the constraint -matrix is destroyed. - -Constraint coefficients (elements of the constraint matrix) should be -specified as triplets (\verb|ia[k]|, \verb|ja[k]|, \verb|ar[k]|) for -$k=1,\dots,ne$, where \verb|ia[k]| is the row index, \verb|ja[k]| is -the column index, and \verb|ar[k]| is a numeric value of corresponding -constraint coefficient. The parameter \verb|ne| specifies the total -number of (non-zero) elements in the matrix to be loaded. Coefficients -with identical indices are not allowed. Zero coefficients are allowed, -however, they are not stored in the constraint matrix. - -If the parameter \verb|ne| is 0, the parameters \verb|ia|, \verb|ja|, -and/or \verb|ar| can be specified as \verb|NULL|. - -\subsection{glp\_check\_dup --- check for duplicate elements in sparse -matrix} - -\synopsis - -{\tt int glp\_check\_dup(int m, int n, int ne, const int ia[], -const int ja[]);} - -\description - -The routine \verb|glp_check_dup checks| for duplicate elements (that -is, elements with identical indices) in a sparse matrix specified in -the coordinate format. - -The parameters $m$ and $n$ specifies, respectively, the number of rows -and columns in the matrix, $m\geq 0$, $n\geq 0$. - -The parameter {\it ne} specifies the number of (structurally) non-zero -elements in the matrix,\linebreak {\it ne} $\geq 0$. - -Elements of the matrix are specified as doublets $(ia[k],ja[k])$ for -$k=1,\dots,ne$, where $ia[k]$ is a row index, $ja[k]$ is a column -index. - -The routine \verb|glp_check_dup| can be used prior to a call to the -routine \verb|glp_load_matrix| to check that the constraint matrix to -be loaded has no duplicate elements. - -\returns - -\begin{retlist} -0& the matrix representation is correct;\\ -$-k$& indices $ia[k]$ or/and $ja[k]$ are out of range;\\ -$+k$& element $(ia[k],ja[k])$ is duplicate.\\ -\end{retlist} - -\subsection{glp\_sort\_matrix --- sort elements of the constraint -matrix} - -\synopsis - -\begin{verbatim} - void glp_sort_matrix(glp_prob *P); -\end{verbatim} - -\description - -The routine \verb|glp_sort_matrix| sorts elements of the constraint -matrix by rebuilding its row and column linked lists. - -On exit from the routine the constraint matrix is not changed, however, -elements in the row linked lists become ordered by ascending column -indices, and the elements in the column linked lists become ordered by -ascending row indices. - -\subsection{glp\_del\_rows --- delete rows from problem object} - -\synopsis - -\begin{verbatim} - void glp_del_rows(glp_prob *P, int nrs, const int num[]); -\end{verbatim} - -\description - -The routine \verb|glp_del_rows| deletes rows from the specified problem -object. Ordinal numbers of rows to be deleted should be placed in -locations \verb|num[1]|, \dots, \verb|num[nrs]|, where ${\tt nrs}>0$. - -Note that deleting rows involves changing ordinal numbers of other -rows remaining in the problem object. New ordinal numbers of the -remaining rows are assigned under the assumption that the original -order of rows is not changed. Let, for example, before deletion there -be five rows $a$, $b$, $c$, $d$, $e$ with ordinal numbers 1, 2, 3, 4, -5, and let rows $b$ and $d$ have been deleted. Then after deletion the -remaining rows $a$, $c$, $e$ are assigned new oridinal numbers 1, 2, 3. - -\subsection{glp\_del\_cols --- delete columns from problem object} - -\synopsis - -\begin{verbatim} - void glp_del_cols(glp_prob *P, int ncs, const int num[]); -\end{verbatim} - -\description - -The routine \verb|glp_del_cols| deletes columns from the specified -problem object. Ordinal numbers of columns to be deleted should be -placed in locations \verb|num[1]|, \dots, \verb|num[ncs]|, where -${\tt ncs}>0$. - -Note that deleting columns involves changing ordinal numbers of other -columns remaining in\linebreak the problem object. New ordinal numbers -of the remaining columns are assigned under the assumption that the -original order of columns is not changed. Let, for example, before -deletion there be six columns $p$, $q$, $r$, $s$, $t$, $u$ with -ordinal numbers 1, 2, 3, 4, 5, 6, and let columns $p$, $q$, $s$ have -been deleted. Then after deletion the remaining columns $r$, $t$, $u$ -are assigned new ordinal numbers 1, 2, 3. - -\subsection{glp\_copy\_prob --- copy problem object content} - -\synopsis - -\begin{verbatim} - void glp_copy_prob(glp_prob *dest, glp_prob *prob, int names); -\end{verbatim} - -\description - -The routine \verb|glp_copy_prob| copies the content of the problem -object \verb|prob| to the problem object \verb|dest|. - -The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, -the routine also copies all symbolic names; otherwise, if it is -\verb|GLP_OFF|, no symbolic names are copied. - -\newpage - -\subsection{glp\_erase\_prob --- erase problem object content} - -\synopsis - -\begin{verbatim} - void glp_erase_prob(glp_prob *P); -\end{verbatim} - -\description - -The routine \verb|glp_erase_prob| erases the content of the specified -problem object. The effect of this operation is the same as if the -problem object would be deleted with the routine \verb|glp_delete_prob| -and then created anew with the routine \verb|glp_create_prob|, with the -only exception that the pointer to the problem object remains valid. - -\subsection{glp\_delete\_prob --- delete problem object} - -\synopsis - -\begin{verbatim} - void glp_delete_prob(glp_prob *P); -\end{verbatim} - -\description - -The routine \verb|glp_delete_prob| deletes a problem object, which the -parameter \verb|lp| points to, freeing all the memory allocated to this -object. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Problem retrieving routines} - -\subsection{glp\_get\_prob\_name --- retrieve problem name} - -\synopsis - -\begin{verbatim} - const char *glp_get_prob_name(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_get_prob_name| returns a pointer to an internal -buffer, which contains symbolic name of the problem. However, if the -problem has no assigned name, the routine returns \verb|NULL|. - -\subsection{glp\_get\_obj\_name --- retrieve objective function name} - -\synopsis - -\begin{verbatim} - const char *glp_get_obj_name(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_get_obj_name| returns a pointer to an internal -buffer, which contains symbolic name assigned to the objective -function. However, if the objective function has no assigned name, the -routine returns \verb|NULL|. - -\subsection{glp\_get\_obj\_dir --- retrieve optimization direction -flag} - -\synopsis - -\begin{verbatim} - int glp_get_obj_dir(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_get_obj_dir| returns the optimization direction -flag (i.e. ``sense'' of the objective function): - -\verb|GLP_MIN| means minimization; - -\verb|GLP_MAX| means maximization. - -\subsection{glp\_get\_num\_rows --- retrieve number of rows} - -\synopsis - -\begin{verbatim} - int glp_get_num_rows(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_get_num_rows| returns the current number of rows -in the specified problem object. - -\subsection{glp\_get\_num\_cols --- retrieve number of columns} - -\synopsis - -\begin{verbatim} - int glp_get_num_cols(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_get_num_cols| returns the current number of -columns in the specified problem object. - -\subsection{glp\_get\_row\_name --- retrieve row name} - -\synopsis - -\begin{verbatim} - const char *glp_get_row_name(glp_prob *P, int i); -\end{verbatim} - -\returns - -The routine \verb|glp_get_row_name| returns a pointer to an internal -buffer, which contains a symbolic name assigned to \verb|i|-th row. -However, if the row has no assigned name, the routine returns -\verb|NULL|. - -\subsection{glp\_get\_col\_name --- retrieve column name} - -\synopsis - -\begin{verbatim} - const char *glp_get_col_name(glp_prob *P, int j); -\end{verbatim} - -\returns - -The routine \verb|glp_get_col_name| returns a pointer to an internal -buffer, which contains a symbolic name assigned to \verb|j|-th column. -However, if the column has no assigned name, the routine returns -\verb|NULL|. - -\subsection{glp\_get\_row\_type --- retrieve row type} - -\synopsis - -\begin{verbatim} - int glp_get_row_type(glp_prob *P, int i); -\end{verbatim} - -\returns - -The routine \verb|glp_get_row_type| returns the type of \verb|i|-th -row, i.e. the type of corresponding auxiliary variable, as follows: - -\verb|GLP_FR| --- free (unbounded) variable; - -\verb|GLP_LO| --- variable with lower bound; - -\verb|GLP_UP| --- variable with upper bound; - -\verb|GLP_DB| --- double-bounded variable; - -\verb|GLP_FX| --- fixed variable. - -\subsection{glp\_get\_row\_lb --- retrieve row lower bound} - -\synopsis - -\begin{verbatim} - double glp_get_row_lb(glp_prob *P, int i); -\end{verbatim} - -\returns - -The routine \verb|glp_get_row_lb| returns the lower bound of -\verb|i|-th row, i.e. the lower bound of corresponding auxiliary -variable. However, if the row has no lower bound, the routine returns -\verb|-DBL_MAX|. - -\vspace*{-4pt} - -\subsection{glp\_get\_row\_ub --- retrieve row upper bound} - -\synopsis - -\begin{verbatim} - double glp_get_row_ub(glp_prob *P, int i); -\end{verbatim} - -\returns - -The routine \verb|glp_get_row_ub| returns the upper bound of -\verb|i|-th row, i.e. the upper bound of corresponding auxiliary -variable. However, if the row has no upper bound, the routine returns -\verb|+DBL_MAX|. - -\vspace*{-4pt} - -\subsection{glp\_get\_col\_type --- retrieve column type} - -\synopsis - -\begin{verbatim} - int glp_get_col_type(glp_prob *P, int j); -\end{verbatim} - -\returns - -The routine \verb|glp_get_col_type| returns the type of \verb|j|-th -column, i.e. the type of corresponding structural variable, as follows: - -\verb|GLP_FR| --- free (unbounded) variable; - -\verb|GLP_LO| --- variable with lower bound; - -\verb|GLP_UP| --- variable with upper bound; - -\verb|GLP_DB| --- double-bounded variable; - -\verb|GLP_FX| --- fixed variable. - -\vspace*{-4pt} - -\subsection{glp\_get\_col\_lb --- retrieve column lower bound} - -\synopsis - -\begin{verbatim} - double glp_get_col_lb(glp_prob *P, int j); -\end{verbatim} - -\returns - -The routine \verb|glp_get_col_lb| returns the lower bound of -\verb|j|-th column, i.e. the lower bound of corresponding structural -variable. However, if the column has no lower bound, the routine -returns \verb|-DBL_MAX|. - -\subsection{glp\_get\_col\_ub --- retrieve column upper bound} - -\synopsis - -\begin{verbatim} - double glp_get_col_ub(glp_prob *P, int j); -\end{verbatim} - -\returns - -The routine \verb|glp_get_col_ub| returns the upper bound of -\verb|j|-th column, i.e. the upper bound of corresponding structural -variable. However, if the column has no upper bound, the routine -returns \verb|+DBL_MAX|. - -\subsection{glp\_get\_obj\_coef --- retrieve objective coefficient or -constant term} - -\synopsis - -\begin{verbatim} - double glp_get_obj_coef(glp_prob *P, int j); -\end{verbatim} - -\returns - -The routine \verb|glp_get_obj_coef| returns the objective coefficient -at \verb|j|-th structural variable (column). - -If the parameter \verb|j| is 0, the routine returns the constant term -(``shift'') of the objective function. - -\subsection{glp\_get\_num\_nz --- retrieve number of constraint -coefficients} - -\synopsis - -\begin{verbatim} - int glp_get_num_nz(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_get_num_nz| returns the number of non-zero -elements in the constraint matrix of the specified problem object. - -\subsection{glp\_get\_mat\_row --- retrieve row of the constraint -matrix} - -\synopsis - -\begin{verbatim} - int glp_get_mat_row(glp_prob *P, int i, int ind[], double val[]); -\end{verbatim} - -\description - -The routine \verb|glp_get_mat_row| scans (non-zero) elements of -\verb|i|-th row of the constraint matrix of the specified problem -object and stores their column indices and numeric values to locations -\verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, \dots, -\verb|val[len]|, respectively, where $0\leq{\tt len}\leq n$ is the -number of elements in $i$-th row, $n$ is the number of columns. - -The parameter \verb|ind| and/or \verb|val| can be specified as -\verb|NULL|, in which case corresponding information is not stored. - -\newpage - -\returns - -The routine \verb|glp_get_mat_row| returns the length \verb|len|, i.e. -the number of (non-zero) elements in \verb|i|-th row. - -\subsection{glp\_get\_mat\_col --- retrieve column of the constraint -matrix} - -\synopsis - -\begin{verbatim} - int glp_get_mat_col(glp_prob *P, int j, int ind[], double val[]); -\end{verbatim} - -\description - -The routine \verb|glp_get_mat_col| scans (non-zero) elements of -\verb|j|-th column of the constraint matrix of the specified problem -object and stores their row indices and numeric values to locations -\linebreak \verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, -\dots, \verb|val[len]|, respectively, where $0\leq{\tt len}\leq m$ is -the number of elements in $j$-th column, $m$ is the number of rows. - -The parameter \verb|ind| and/or \verb|val| can be specified as -\verb|NULL|, in which case corresponding information is not stored. - -\returns - -The routine \verb|glp_get_mat_col| returns the length \verb|len|, i.e. -the number of (non-zero) elements in \verb|j|-th column. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Row and column searching routines} - -Sometimes it may be necessary to find rows and/or columns by their -names (assigned with the routines \verb|glp_set_row_name| and -\verb|glp_set_col_name|). Though a particular row/column can be found -by its name using simple enumeration of all rows/columns, in case of -large instances such a {\it linear} search may take too long time. - -To significantly reduce the search time the application program may -create the row/column name index, which is an auxiliary data structure -implementing a {\it binary} search. Even in worst cases the search -takes logarithmic time, i.e. the time needed to find a particular row -(or column) by its name is $O(\log_2m)$ (or $O(\log_2n)$), where $m$ -and $n$ are, resp., the number of rows and columns in the problem -object. - -It is important to note that: - -1. On creating the problem object with the routine -\verb|glp_create_prob| the name index is {\it not} created. - -2. The name index can be created (destroyed) at any time with the -routine \verb|glp_create_index| (\verb|glp_delete_index|). Having been -created the name index becomes part of the corresponding problem -object. - -3. The time taken to create the name index is $O[(m+n)\log_2(m+n)]$, -so it is recommended to create the index only once, for example, just -after the problem object was created. - -4. If the name index exists, it is automatically updated every time -the name of a row/column is assigned/changed. The update operation -takes logarithmic time. - -5. If the name index does not exist, the application should not call -the routines \verb|glp_find_row| and \verb|glp_find_col|. Otherwise, -an error message will be issued and abnormal program termination will -occur. - -6. On destroying the problem object with the routine -\verb|glp_delete_prob|, the name index, if exists, is automatically -destroyed. - -\subsection{glp\_create\_index --- create the name index} - -\synopsis - -\begin{verbatim} - void glp_create_index(glp_prob *P); -\end{verbatim} - -\description - -The routine \verb|glp_create_index| creates the name index for the -specified problem object. The name index is an auxiliary data -structure, which is intended to quickly (i.e. for logarithmic time) -find rows and columns by their names. - -This routine can be called at any time. If the name index already -exists, the routine does nothing. - -\newpage - -\subsection{glp\_find\_row --- find row by its name} - -\synopsis - -\begin{verbatim} - int glp_find_row(glp_prob *P, const char *name); -\end{verbatim} - -\returns - -The routine \verb|glp_find_row| returns the ordinal number of a row, -which is assigned the specified symbolic \verb|name|. If no such row -exists, the routine returns 0. - -\subsection{glp\_find\_col --- find column by its name} - -\synopsis - -\begin{verbatim} - int glp_find_col(glp_prob *P, const char *name); -\end{verbatim} - -\returns - -The routine \verb|glp_find_col| returns the ordinal number of a column, -which is assigned the specified symbolic \verb|name|. If no such column -exists, the routine returns 0. - -\subsection{glp\_delete\_index --- delete the name index} - -\synopsis - -\begin{verbatim} - void glp_delete_index(glp_prob *P); -\end{verbatim} - -\description - -The routine \verb|glp_delete_index| deletes the name index previously -created by the routine\linebreak \verb|glp_create_index| and frees the -memory allocated to this auxiliary data structure. - -This routine can be called at any time. If the name index does not -exist, the routine does nothing. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Problem scaling routines} - -\subsection{Background} - -In GLPK the {\it scaling} means a linear transformation applied to the -constraint matrix to improve its numerical properties.\footnote{In many -cases a proper scaling allows making the constraint matrix to be better -conditioned, i.e. decreasing its condition number, that makes -computations numerically more stable.} - -The main equality is the following: -$$\widetilde{A}=RAS,\eqno(2.1)$$ -where $A=(a_{ij})$ is the original constraint matrix, $R=(r_{ii})>0$ is -a diagonal matrix used to scale rows (constraints), $S=(s_{jj})>0$ is a -diagonal matrix used to scale columns (variables), $\widetilde{A}$ is -the scaled constraint matrix. - -From (2.1) it follows that in the {\it scaled} problem instance each -original constraint coefficient $a_{ij}$ is replaced by corresponding -scaled constraint coefficient: -$$\widetilde{a}_{ij}=r_{ii}a_{ij}s_{jj}.\eqno(2.2)$$ - -Note that the scaling is performed internally and therefore -transparently to the user. This means that on API level the user always -deal with unscaled data. - -Scale factors $r_{ii}$ and $s_{jj}$ can be set or changed at any time -either directly by the application program in a problem specific way -(with the routines \verb|glp_set_rii| and \verb|glp_set_sjj|), or by -some API routines intended for automatic scaling. - -\subsection{glp\_set\_rii --- set (change) row scale factor} - -\synopsis - -\begin{verbatim} - void glp_set_rii(glp_prob *P, int i, double rii); -\end{verbatim} - -\description - -The routine \verb|glp_set_rii| sets (changes) the scale factor $r_{ii}$ -for $i$-th row of the specified problem object. - -\subsection{glp\_set\_sjj --- set (change) column scale factor} - -\synopsis - -\begin{verbatim} - void glp_set_sjj(glp_prob *P, int j, double sjj); -\end{verbatim} - -\description - -The routine \verb|glp_set_sjj| sets (changes) the scale factor $s_{jj}$ -for $j$-th column of the specified problem object. - -\subsection{glp\_get\_rii --- retrieve row scale factor} - -\synopsis - -\begin{verbatim} - double glp_get_rii(glp_prob *P, int i); -\end{verbatim} - -\returns - -The routine \verb|glp_get_rii| returns current scale factor $r_{ii}$ -for $i$-th row of the specified problem object. - -\vspace*{-6pt} - -\subsection{glp\_get\_sjj --- retrieve column scale factor} - -\vspace*{-4pt} - -\synopsis - -\begin{verbatim} - double glp_get_sjj(glp_prob *P, int j); -\end{verbatim} - -\returns - -The routine \verb|glp_get_sjj| returns current scale factor $s_{jj}$ -for $j$-th column of the specified problem object. - -\vspace*{-6pt} - -\subsection{glp\_scale\_prob --- scale problem data} - -\vspace*{-4pt} - -\synopsis - -\begin{verbatim} - void glp_scale_prob(glp_prob *P, int flags); -\end{verbatim} - -\description - -The routine \verb|glp_scale_prob| performs automatic scaling of problem -data for the specified problem object. - -The parameter \verb|flags| specifies scaling options used by the -routine. The options can be combined with the bitwise OR operator and -may be the following: - -\verb|GLP_SF_GM | --- perform geometric mean scaling; - -\verb|GLP_SF_EQ | --- perform equilibration scaling; - -\verb|GLP_SF_2N | --- round scale factors to nearest power of two; - -\verb|GLP_SF_SKIP| --- skip scaling, if the problem is well scaled. - -The parameter \verb|flags| may be also specified as \verb|GLP_SF_AUTO|, -in which case the routine chooses the scaling options automatically. - -\vspace*{-6pt} - -\subsection{glp\_unscale\_prob --- unscale problem data} - -\vspace*{-4pt} - -\synopsis - -\begin{verbatim} - void glp_unscale_prob(glp_prob *P); -\end{verbatim} - -The routine \verb|glp_unscale_prob| performs unscaling of problem data -for the specified problem object. - -``Unscaling'' means replacing the current scaling matrices $R$ and $S$ -by unity matrices that cancels the scaling effect. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{LP basis constructing routines} - -\subsection{Background} - -To start the search the simplex method needs a valid initial basis. -In GLPK the basis is completely defined by a set of {\it statuses} -assigned to {\it all} (auxiliary and structural) variables, where the -status may be one of the following: - -\verb|GLP_BS| --- basic variable; - -\verb|GLP_NL| --- non-basic variable having active lower bound; - -\verb|GLP_NU| --- non-basic variable having active upper bound; - -\verb|GLP_NF| --- non-basic free variable; - -\verb|GLP_NS| --- non-basic fixed variable. - -The basis is {\it valid}, if the basis matrix, which is a matrix built -of columns of the augmented constraint matrix $(I\:|-A)$ corresponding -to basic variables, is non-singular. This, in particular, means that -the number of basic variables must be the same as the number of rows in -the problem object. (For more details see Section \ref{lpbasis}, page -\pageref{lpbasis}.) - -Any initial basis may be constructed (or restored) with the API -routines \verb|glp_set_row_stat| and \verb|glp_set_col_stat| by -assigning appropriate statuses to auxiliary and structural variables. -Another way to construct an initial basis is to use API routines like -\verb|glp_adv_basis|, which implement so called -{\it crashing}.\footnote{This term is from early linear programming -systems and means a heuristic to construct a valid initial basis.} Note -that on normal exit the simplex solver remains the basis valid, so in -case of reoptimization there is no need to construct an initial basis -from scratch. - -\subsection{glp\_set\_row\_stat --- set (change) row status} - -\synopsis - -\begin{verbatim} - void glp_set_row_stat(glp_prob *P, int i, int stat); -\end{verbatim} - -\description - -The routine \verb|glp_set_row_stat| sets (changes) the current status -of \verb|i|-th row (auxiliary variable) as specified by the parameter -\verb|stat|: - -\verb|GLP_BS| --- make the row basic (make the constraint inactive); - -\verb|GLP_NL| --- make the row non-basic (make the constraint active); - -\verb|GLP_NU| --- make the row non-basic and set it to the upper bound; -if the row is not double-bounded, this status is equivalent to -\verb|GLP_NL| (only in case of this routine); - -\verb|GLP_NF| --- the same as \verb|GLP_NL| (only in case of this -routine); - -\verb|GLP_NS| --- the same as \verb|GLP_NL| (only in case of this -routine). - -\newpage - -\subsection{glp\_set\_col\_stat --- set (change) column status} - -\synopsis - -\begin{verbatim} - void glp_set_col_stat(glp_prob *P, int j, int stat); -\end{verbatim} - -\description - -The routine \verb|glp_set_col_stat sets| (changes) the current status -of \verb|j|-th column (structural variable) as specified by the -parameter \verb|stat|: - -\verb|GLP_BS| --- make the column basic; - -\verb|GLP_NL| --- make the column non-basic; - -\verb|GLP_NU| --- make the column non-basic and set it to the upper -bound; if the column is not double-bounded, this status is equivalent -to \verb|GLP_NL| (only in case of this routine); - -\verb|GLP_NF| --- the same as \verb|GLP_NL| (only in case of this -routine); - -\verb|GLP_NS| --- the same as \verb|GLP_NL| (only in case of this -routine). - -\subsection{glp\_std\_basis --- construct standard initial LP basis} - -\synopsis - -\begin{verbatim} - void glp_std_basis(glp_prob *P); -\end{verbatim} - -\description - -The routine \verb|glp_std_basis| constructs the ``standard'' (trivial) -initial LP basis for the specified problem object. - -In the ``standard'' LP basis all auxiliary variables (rows) are basic, -and all structural variables (columns) are non-basic (so the -corresponding basis matrix is unity). - -\subsection{glp\_adv\_basis --- construct advanced initial LP basis} - -\synopsis - -\begin{verbatim} - void glp_adv_basis(glp_prob *P, int flags); -\end{verbatim} - -\description - -The routine \verb|glp_adv_basis| constructs an advanced initial LP -basis for the specified problem object. - -The parameter \verb|flags| is reserved for use in the future and must -be specified as zero. - -In order to construct the advanced initial LP basis the routine does -the following: - -1) includes in the basis all non-fixed auxiliary variables; - -2) includes in the basis as many non-fixed structural variables as -possible keeping the triangular form of the basis matrix; - -3) includes in the basis appropriate (fixed) auxiliary variables to -complete the basis. - -As a result the initial LP basis has as few fixed variables as possible -and the corresponding basis matrix is triangular. - -\subsection{glp\_cpx\_basis --- construct Bixby's initial LP basis} - -\synopsis - -\begin{verbatim} - void glp_cpx_basis(glp_prob *P); -\end{verbatim} - -\description - -The routine \verb|glp_cpx_basis| constructs an initial basis for the -specified problem object with the algorithm proposed by -R.~Bixby.\footnote{Robert E. Bixby, ``Implementing the Simplex Method: -The Initial Basis.'' ORSA Journal on Computing, Vol. 4, No. 3, 1992, -pp. 267-84.} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Simplex method routines} - -The {\it simplex method} is a well known efficient numerical procedure -to solve LP problems. - -On each iteration the simplex method transforms the original system of -equaility constraints (1.2) resolving them through different sets of -variables to an equivalent system called {\it the simplex table} (or -sometimes {\it the simplex tableau}), which has the following form: -$$ -\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r} -z&=&d_1(x_N)_1&+&d_2(x_N)_2&+ \dots +&d_n(x_N)_n \\ -(x_B)_1&=&\xi_{11}(x_N)_1& +& \xi_{12}(x_N)_2& + \dots +& - \xi_{1n}(x_N)_n \\ -(x_B)_2&=& \xi_{21}(x_N)_1& +& \xi_{22}(x_N)_2& + \dots +& - \xi_{2n}(x_N)_n \\ -\multicolumn{7}{c} -{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .} \\ -(x_B)_m&=&\xi_{m1}(x_N)_1& +& \xi_{m2}(x_N)_2& + \dots +& - \xi_{mn}(x_N)_n \\ -\end{array} \eqno (2.3) -$$ -where: $(x_B)_1, (x_B)_2, \dots, (x_B)_m$ are basic variables; -$(x_N)_1, (x_N)_2, \dots, (x_N)_n$ are non-basic variables; -$d_1, d_2, \dots, d_n$ are reduced costs; -$\xi_{11}, \xi_{12}, \dots, \xi_{mn}$ are coefficients of the -simplex table. (May note that the original LP problem (1.1)---(1.3) -also has the form of a simplex table, where all equalities are resolved -through auxiliary variables.) - -From the linear programming theory it is known that if an optimal -solution of the LP problem (1.1)---(1.3) exists, it can always be -written in the form (2.3), where non-basic variables are set on their -bounds while values of the objective function and basic variables are -determined by the corresponding equalities of the simplex table. - -A set of values of all basic and non-basic variables determined by the -simplex table is called {\it basic solution}. If all basic variables -are within their bounds, the basic solution is called {\it (primal) -feasible}, otherwise it is called {\it (primal) infeasible}. A feasible -basic solution, which provides a smallest (in case of minimization) or -a largest (in case of maximization) value of the objective function is -called {\it optimal}. Therefore, for solving LP problem the simplex -method tries to find its optimal basic solution. - -Primal feasibility of some basic solution may be stated by simple -checking if all basic variables are within their bounds. Basic solution -is optimal if additionally the following optimality conditions are -satisfied for all non-basic variables: -\begin{center} -\begin{tabular}{lcc} -Status of $(x_N)_j$ & Minimization & Maximization \\ -\hline -$(x_N)_j$ is free & $d_j = 0$ & $d_j = 0$ \\ -$(x_N)_j$ is on its lower bound & $d_j \geq 0$ & $d_j \leq 0$ \\ -$(x_N)_j$ is on its upper bound & $d_j \leq 0$ & $d_j \geq 0$ \\ -\end{tabular} -\end{center} -In other words, basic solution is optimal if there is no non-basic -variable, which changing in the feasible direction (i.e. increasing if -it is free or on its lower bound, or decreasing if it is free or on its -upper bound) can improve (i.e. decrease in case of minimization or -increase in case of maximization) the objective function. - -If all non-basic variables satisfy to the optimality conditions shown -above (independently on whether basic variables are within their bounds -or not), the basic solution is called {\it dual feasible}, otherwise it -is called {\it dual infeasible}. - -It may happen that some LP problem has no primal feasible solution due -to incorrect\linebreak formulation --- this means that its constraints -conflict with each other. It also may happen that some LP problem has -unbounded solution again due to incorrect formulation --- this means -that some non-basic variable can improve the objective function, i.e. -the optimality conditions are violated, and at the same time this -variable can infinitely change in the feasible direction meeting -no resistance from basic variables. (May note that in the latter case -the LP problem has no dual feasible solution.) - -\subsection{glp\_simplex --- solve LP problem with the primal or dual -simplex method} - -\synopsis - -\begin{verbatim} - int glp_simplex(glp_prob *P, const glp_smcp *parm); -\end{verbatim} - -\description - -The routine \verb|glp_simplex| is a driver to the LP solver based on -the simplex method. This routine retrieves problem data from the -specified problem object, calls the solver to solve the problem -instance, and stores results of computations back into the problem -object. - -The simplex solver has a set of control parameters. Values of the -control parameters can be passed in the structure \verb|glp_smcp|, -which the parameter \verb|parm| points to. For detailed description of -this structure see paragraph ``Control parameters'' below. -Before specifying some control parameters the application program -should initialize the structure \verb|glp_smcp| by default values of -all control parameters using the routine \verb|glp_init_smcp| (see the -next subsection). This is needed for backward compatibility, because in -the future there may appear new members in the structure -\verb|glp_smcp|. - -The parameter \verb|parm| can be specified as \verb|NULL|, in which -case the solver uses default settings. - -\returns - -\begin{retlist} -0 & The LP problem instance has been successfully solved. (This code -does {\it not} necessarily mean that the solver has found optimal -solution. It only means that the solution process was successful.) \\ - -\verb|GLP_EBADB| & Unable to start the search, because the initial -basis specified in the problem object is invalid---the number of basic -(auxiliary and structural) variables is not the same as the number of -rows in the problem object.\\ - -\verb|GLP_ESING| & Unable to start the search, because the basis matrix -corresponding to the initial basis is singular within the working -precision.\\ - -\verb|GLP_ECOND| & Unable to start the search, because the basis matrix -corresponding to the initial basis is ill-conditioned, i.e. its -condition number is too large.\\ - -\verb|GLP_EBOUND| & Unable to start the search, because some -double-bounded (auxiliary or structural) variables have incorrect -bounds.\\ - -\verb|GLP_EFAIL| & The search was prematurely terminated due to the -solver failure.\\ - -\verb|GLP_EOBJLL| & The search was prematurely terminated, because the -objective function being maximized has reached its lower limit and -continues decreasing (the dual simplex only).\\ -\end{retlist} - -\begin{retlist} -\verb|GLP_EOBJUL| & The search was prematurely terminated, because the -objective function being minimized has reached its upper limit and -continues increasing (the dual simplex only).\\ - -\verb|GLP_EITLIM| & The search was prematurely terminated, because the -simplex iteration limit has been exceeded.\\ - -\verb|GLP_ETMLIM| & The search was prematurely terminated, because the -time limit has been exceeded.\\ - -\verb|GLP_ENOPFS| & The LP problem instance has no primal feasible -solution (only if the LP presolver is used).\\ - -\verb|GLP_ENODFS| & The LP problem instance has no dual feasible -solution (only if the LP presolver is used).\\ -\end{retlist} - -\para{Built-in LP presolver} - -The simplex solver has {\it built-in LP presolver}. It is a subprogram -that transforms the original LP problem specified in the problem object -to an equivalent LP problem, which may be easier for solving with the -simplex method than the original one. This is attained mainly due to -reducing the problem size and improving its numeric properties (for -example, by removing some inactive constraints or by fixing some -non-basic variables). Once the transformed LP problem has been solved, -the presolver transforms its basic solution back to the corresponding -basic solution of the original problem. - -Presolving is an optional feature of the routine \verb|glp_simplex|, -and by default it is disabled. In order to enable the LP presolver the -control parameter \verb|presolve| should be set to \verb|GLP_ON| (see -paragraph ``Control parameters'' below). Presolving may be used when -the problem instance is solved for the first time. However, on -performing re-optimization the presolver should be disabled. - -The presolving procedure is transparent to the API user in the sense -that all necessary processing is performed internally, and a basic -solution of the original problem recovered by the presolver is the same -as if it were computed directly, i.e. without presolving. - -Note that the presolver is able to recover only optimal solutions. If -a computed solution is infeasible or non-optimal, the corresponding -solution of the original problem cannot be recovered and therefore -remains undefined. If you need to know a basic solution even if it is -infeasible or non-optimal, the presolver should be disabled. - -\para{Terminal output} - -Solving large problem instances may take a long time, so the solver -reports some information about the current basic solution, which is sent -to the terminal. This information has the following format: - -\begin{verbatim} - nnn: obj = xxx infeas = yyy (ddd) -\end{verbatim} - -\noindent -where: `\verb|nnn|' is the iteration number, `\verb|xxx|' is the -current value of the objective function (it is is unscaled and has -correct sign); `\verb|yyy|' is the current sum of primal or dual -infeasibilities (it is scaled and therefore may be used only for visual -estimating), `\verb|ddd|' is the current number of fixed basic -variables. - -The symbol preceding the iteration number indicates which phase of the -simplex method is in effect: - -{\it Blank} means that the solver is searching for primal feasible -solution using the primal simplex or for dual feasible solution using -the dual simplex; - -{\it Asterisk} (\verb|*|) means that the solver is searching for -optimal solution using the primal simplex; - -{\it Vertical dash} (\verb/|/) means that the solver is searching for -optimal solution using the dual simplex. - -\para{Control parameters} - -This paragraph describes all control parameters currently used in the -simplex solver. Symbolic names of control parameters are names of -corresponding members in the structure \verb|glp_smcp|. - -\bigskip - -{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL}) - -Message level for terminal output: - -\verb|GLP_MSG_OFF| --- no output; - -\verb|GLP_MSG_ERR| --- error and warning messages only; - -\verb|GLP_MSG_ON | --- normal output; - -\verb|GLP_MSG_ALL| --- full output (including informational messages). - -\bigskip - -{\tt int meth} (default: {\tt GLP\_PRIMAL}) - -Simplex method option: - -\verb|GLP_PRIMAL| --- use two-phase primal simplex; - -\verb|GLP_DUAL | --- use two-phase dual simplex; - -\verb|GLP_DUALP | --- use two-phase dual simplex, and if it fails, -switch to the primal simplex. - -\bigskip - -{\tt int pricing} (default: {\tt GLP\_PT\_PSE}) - -Pricing technique: - -\verb|GLP_PT_STD| --- standard (``textbook''); - -\verb|GLP_PT_PSE| --- projected steepest edge. - -\bigskip - -{\tt int r\_test} (default: {\tt GLP\_RT\_HAR}) - -Ratio test technique: - -\verb|GLP_RT_STD| --- standard (``textbook''); - -\verb|GLP_RT_HAR| --- Harris' two-pass ratio test. - -\bigskip - -{\tt double tol\_bnd} (default: {\tt 1e-7}) - -Tolerance used to check if the basic solution is primal feasible. -(Do not change this parameter without detailed understanding its -purpose.) - -\newpage - -{\tt double tol\_dj} (default: {\tt 1e-7}) - -Tolerance used to check if the basic solution is dual feasible. -(Do not change this parameter without detailed understanding its -purpose.) - -\bigskip - -{\tt double tol\_piv} (default: {\tt 1e-10}) - -Tolerance used to choose eligble pivotal elements of the simplex table. -(Do not change this parameter without detailed understanding its -purpose.) - -\bigskip - -{\tt double obj\_ll} (default: {\tt -DBL\_MAX}) - -Lower limit of the objective function. If the objective function -reaches this limit and continues decreasing, the solver terminates the -search. (Used in the dual simplex only.) - -\bigskip - -{\tt double obj\_ul} (default: {\tt +DBL\_MAX}) - -Upper limit of the objective function. If the objective function -reaches this limit and continues increasing, the solver terminates the -search. (Used in the dual simplex only.) - -\bigskip - -{\tt int it\_lim} (default: {\tt INT\_MAX}) - -Simplex iteration limit. - -\bigskip - -{\tt int tm\_lim} (default: {\tt INT\_MAX}) - -Searching time limit, in milliseconds. - -\bigskip - -{\tt int out\_frq} (default: {\tt 500}) - -Output frequency, in iterations. This parameter specifies how -frequently the solver sends information about the solution process to -the terminal. - -\bigskip - -{\tt int out\_dly} (default: {\tt 0}) - -Output delay, in milliseconds. This parameter specifies how long the -solver should delay sending information about the solution process to -the terminal. - -\bigskip - -{\tt int presolve} (default: {\tt GLP\_OFF}) - -LP presolver option: - -\verb|GLP_ON | --- enable using the LP presolver; - -\verb|GLP_OFF| --- disable using the LP presolver. - -\newpage - -\para{Example 1} - -The following example main program reads LP problem instance in fixed -MPS format from file \verb|25fv47.mps|,\footnote{This instance in fixed -MPS format can be found in the Netlib LP collection; see -{\tt ftp://ftp.netlib.org/lp/data/}.} constructs an advanced initial -basis, solves the instance with the primal simplex method (by default), -and writes the solution to file \verb|25fv47.txt|. - -\begin{footnotesize} -\begin{verbatim} -/* spxsamp1.c */ - -#include -#include -#include - -int main(void) -{ glp_prob *P; - P = glp_create_prob(); - glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); - glp_adv_basis(P, 0); - glp_simplex(P, NULL); - glp_print_sol(P, "25fv47.txt"); - glp_delete_prob(P); - return 0; -} - -/* eof */ -\end{verbatim} -\end{footnotesize} - -Below here is shown the terminal output from this example program. - -\begin{footnotesize} -\begin{verbatim} -Reading problem data from `25fv47.mps'... -Problem: 25FV47 -Objective: R0000 -822 rows, 1571 columns, 11127 non-zeros -6919 records were read -Crashing... -Size of triangular part = 799 - 0: obj = 1.627307307e+04 infeas = 5.194e+04 (23) - 200: obj = 1.474901610e+04 infeas = 1.233e+04 (19) - 400: obj = 1.343909995e+04 infeas = 3.648e+03 (13) - 600: obj = 1.756052217e+04 infeas = 4.179e+02 (7) -* 775: obj = 1.789251591e+04 infeas = 4.982e-14 (1) -* 800: obj = 1.663354510e+04 infeas = 2.857e-14 (1) -* 1000: obj = 1.024935068e+04 infeas = 1.958e-12 (1) -* 1200: obj = 7.860174791e+03 infeas = 2.810e-29 (1) -* 1400: obj = 6.642378184e+03 infeas = 2.036e-16 (1) -* 1600: obj = 6.037014568e+03 infeas = 0.000e+00 (1) -* 1800: obj = 5.662171307e+03 infeas = 6.447e-15 (1) -* 2000: obj = 5.528146165e+03 infeas = 9.764e-13 (1) -* 2125: obj = 5.501845888e+03 infeas = 0.000e+00 (1) -OPTIMAL SOLUTION FOUND -Writing basic solution to `25fv47.txt'... -\end{verbatim} -\end{footnotesize} - -\newpage - -\para{Example 2} - -The following example main program solves the same LP problem instance -as in Example 1 above, however, it uses the dual simplex method, which -starts from the standard initial basis. - -\begin{footnotesize} -\begin{verbatim} -/* spxsamp2.c */ - -#include -#include -#include - -int main(void) -{ glp_prob *P; - glp_smcp parm; - P = glp_create_prob(); - glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); - glp_init_smcp(&parm); - parm.meth = GLP_DUAL; - glp_simplex(P, &parm); - glp_print_sol(P, "25fv47.txt"); - glp_delete_prob(P); - return 0; -} - -/* eof */ -\end{verbatim} -\end{footnotesize} - -Below here is shown the terminal output from this example program. - -\begin{footnotesize} -\begin{verbatim} -Reading problem data from `25fv47.mps'... -Problem: 25FV47 -Objective: R0000 -822 rows, 1571 columns, 11127 non-zeros -6919 records were read - 0: infeas = 1.223e+03 (516) - 200: infeas = 7.000e+00 (471) - 240: infeas = 1.106e-14 (461) -| 400: obj = -5.394267152e+03 infeas = 5.571e-16 (391) -| 600: obj = -4.586395752e+03 infeas = 1.389e-15 (340) -| 800: obj = -4.158268146e+03 infeas = 1.640e-15 (264) -| 1000: obj = -3.725320045e+03 infeas = 5.181e-15 (245) -| 1200: obj = -3.104802163e+03 infeas = 1.019e-14 (210) -| 1400: obj = -2.584190499e+03 infeas = 8.865e-15 (178) -| 1600: obj = -2.073852927e+03 infeas = 7.867e-15 (142) -| 1800: obj = -1.164037407e+03 infeas = 8.792e-15 (109) -| 2000: obj = -4.370590250e+02 infeas = 2.591e-14 (85) -| 2200: obj = 1.068240144e+03 infeas = 1.025e-13 (70) -| 2400: obj = 1.607481126e+03 infeas = 3.272e-14 (67) -| 2600: obj = 3.038230551e+03 infeas = 4.850e-14 (52) -| 2800: obj = 4.316238187e+03 infeas = 2.622e-14 (36) -| 3000: obj = 5.443842629e+03 infeas = 3.976e-15 (11) -| 3060: obj = 5.501845888e+03 infeas = 8.806e-15 (2) -OPTIMAL SOLUTION FOUND -Writing basic solution to `25fv47.txt'... -\end{verbatim} -\end{footnotesize} - -\newpage - -\subsection{glp\_exact --- solve LP problem in exact arithmetic} - -\synopsis - -\begin{verbatim} - int glp_exact(glp_prob *P, const glp_smcp *parm); -\end{verbatim} - -\description - -The routine \verb|glp_exact| is a tentative implementation of the -primal two-phase simplex method based on exact (rational) arithmetic. -It is similar to the routine \verb|glp_simplex|, however, for all -internal computations it uses arithmetic of rational numbers, which is -exact in mathematical sense, i.e. free of round-off errors unlike -floating-point arithmetic. - -Note that the routine \verb|glp_exact| uses only two control parameters -passed in the structure \verb|glp_smcp|, namely, \verb|it_lim| and -\verb|tm_lim|. - -\returns - -\begin{retlist} -0 & The LP problem instance has been successfully solved. (This code -does {\it not} necessarily mean that the solver has found optimal -solution. It only means that the solution process was successful.) \\ - -\verb|GLP_EBADB| & Unable to start the search, because the initial basis -specified in the problem object is invalid---the number of basic -(auxiliary and structural) variables is not the same as the number of -rows in the problem object.\\ - -\verb|GLP_ESING| & Unable to start the search, because the basis matrix -corresponding to the initial basis is exactly singular.\\ - -\verb|GLP_EBOUND| & Unable to start the search, because some -double-bounded (auxiliary or structural) variables have incorrect -bounds.\\ - -\verb|GLP_EFAIL| & The problem instance has no rows/columns.\\ - -\verb|GLP_EITLIM| & The search was prematurely terminated, because the -simplex iteration limit has been exceeded.\\ - -\verb|GLP_ETMLIM| & The search was prematurely terminated, because the -time limit has been exceeded.\\ -\end{retlist} - -\para{Note} - -Computations in exact arithmetic are very time-consuming, so solving -LP problem with the routine \verb|glp_exact| from the very beginning is -not a good idea. It is much better at first to find an optimal basis -with the routine \verb|glp_simplex| and only then to call -\verb|glp_exact|, in which case only a few simplex iterations need to -be performed in exact arithmetic. - -\newpage - -\subsection{glp\_init\_smcp --- initialize simplex solver control -parameters} - -\synopsis - -\begin{verbatim} - int glp_init_smcp(glp_smcp *parm); -\end{verbatim} - -\description - -The routine \verb|glp_init_smcp| initializes control parameters, which -are used by the simplex solver, with default values. - -Default values of the control parameters are stored in -a \verb|glp_smcp| structure, which the parameter \verb|parm| points to. - -\subsection{glp\_get\_status --- determine generic status of basic -solution} - -\synopsis - -\begin{verbatim} - int glp_get_status(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_get_status| reports the generic status of the -current basic solution for the specified problem object as follows: - -\verb|GLP_OPT | --- solution is optimal; - -\verb|GLP_FEAS | --- solution is feasible; - -\verb|GLP_INFEAS| --- solution is infeasible; - -\verb|GLP_NOFEAS| --- problem has no feasible solution; - -\verb|GLP_UNBND | --- problem has unbounded solution; - -\verb|GLP_UNDEF | --- solution is undefined. - -More detailed information about the status of basic solution can be -retrieved with the routines \verb|glp_get_prim_stat| and -\verb|glp_get_dual_stat|. - -\subsection{glp\_get\_prim\_stat --- retrieve status of primal basic -solution} - -\synopsis - -\begin{verbatim} - int glp_get_prim_stat(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_get_prim_stat| reports the status of the primal -basic solution for the specified problem object as follows: - -\verb|GLP_UNDEF | --- primal solution is undefined; - -\verb|GLP_FEAS | --- primal solution is feasible; - -\verb|GLP_INFEAS| --- primal solution is infeasible; - -\verb|GLP_NOFEAS| --- no primal feasible solution exists. - -\subsection{glp\_get\_dual\_stat --- retrieve status of dual basic -solution} - -\synopsis - -\begin{verbatim} - int glp_get_dual_stat(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_get_dual_stat| reports the status of the dual -basic solution for the specified problem object as follows: - -\verb|GLP_UNDEF | --- dual solution is undefined; - -\verb|GLP_FEAS | --- dual solution is feasible; - -\verb|GLP_INFEAS| --- dual solution is infeasible; - -\verb|GLP_NOFEAS| --- no dual feasible solution exists. - -\subsection{glp\_get\_obj\_val --- retrieve objective value} - -\synopsis - -\begin{verbatim} - double glp_get_obj_val(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_get_obj_val| returns current value of the -objective function. - -\subsection{glp\_get\_row\_stat --- retrieve row status} - -\synopsis - -\begin{verbatim} - int glp_get_row_stat(glp_prob *P, int i); -\end{verbatim} - -\returns - -The routine \verb|glp_get_row_stat| returns current status assigned to -the auxiliary variable associated with \verb|i|-th row as follows: - -\verb|GLP_BS| --- basic variable; - -\verb|GLP_NL| --- non-basic variable on its lower bound; - -\verb|GLP_NU| --- non-basic variable on its upper bound; - -\verb|GLP_NF| --- non-basic free (unbounded) variable; - -\verb|GLP_NS| --- non-basic fixed variable. - -\newpage - -\subsection{glp\_get\_row\_prim --- retrieve row primal value} - -\synopsis - -\begin{verbatim} - double glp_get_row_prim(glp_prob *P, int i); -\end{verbatim} - -\returns - -The routine \verb|glp_get_row_prim| returns primal value of the -auxiliary variable associated with \verb|i|-th row. - -\subsection{glp\_get\_row\_dual --- retrieve row dual value} - -\synopsis - -\begin{verbatim} - double glp_get_row_dual(glp_prob *P, int i); -\end{verbatim} - -\returns - -The routine \verb|glp_get_row_dual| returns dual value (i.e. reduced -cost) of the auxiliary variable associated with \verb|i|-th row. - -\subsection{glp\_get\_col\_stat --- retrieve column status} - -\synopsis - -\begin{verbatim} - int glp_get_col_stat(glp_prob *P, int j); -\end{verbatim} - -\returns - -The routine \verb|glp_get_col_stat| returns current status assigned to -the structural variable associated with \verb|j|-th column as follows: - -\verb|GLP_BS| --- basic variable; - -\verb|GLP_NL| --- non-basic variable on its lower bound; - -\verb|GLP_NU| --- non-basic variable on its upper bound; - -\verb|GLP_NF| --- non-basic free (unbounded) variable; - -\verb|GLP_NS| --- non-basic fixed variable. - -\subsection{glp\_get\_col\_prim --- retrieve column primal value} - -\synopsis - -\begin{verbatim} - double glp_get_col_prim(glp_prob *P, int j); -\end{verbatim} - -\returns - -The routine \verb|glp_get_col_prim| returns primal value of the -structural variable associated with \verb|j|-th column. - -\newpage - -\subsection{glp\_get\_col\_dual --- retrieve column dual value} - -\synopsis - -\begin{verbatim} - double glp_get_col_dual(glp_prob *P, int j); -\end{verbatim} - -\returns - -The routine \verb|glp_get_col_dual| returns dual value (i.e. reduced -cost) of the structural variable associated with \verb|j|-th column. - -\subsection{glp\_get\_unbnd\_ray --- determine variable causing -unboundedness} - -\synopsis - -\begin{verbatim} - int glp_get_unbnd_ray(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_get_unbnd_ray| returns the number $k$ of -a variable, which causes primal or dual unboundedness. -If $1\leq k\leq m$, it is $k$-th auxiliary variable, and if -$m+1\leq k\leq m+n$, it is $(k-m)$-th structural variable, where $m$ is -the number of rows, $n$ is the number of columns in the problem object. -If such variable is not defined, the routine returns 0. - -\para{Note} - -If it is not exactly known which version of the simplex solver -detected unboundedness, i.e. whether the unboundedness is primal or -dual, it is sufficient to check the status of the variable -with the routine \verb|glp_get_row_stat| or \verb|glp_get_col_stat|. -If the variable is non-basic, the unboundedness is primal, otherwise, -if the variable is basic, the unboundedness is dual (the latter case -means that the problem has no primal feasible dolution). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Interior-point method routines} - -{\it Interior-point methods} (also known as {\it barrier methods}) are -more modern and powerful numerical methods for large-scale linear -programming. Such methods are especially efficient for very sparse LP -problems and allow solving such problems much faster than the simplex -method. - -In brief, the GLPK interior-point solver works as follows. - -At first, the solver transforms the original LP to a {\it working} LP -in the standard format: - -\medskip - -\noindent -\hspace{.5in} minimize -$$z = c_1x_{m+1} + c_2x_{m+2} + \dots + c_nx_{m+n} + c_0 \eqno (2.4)$$ -\hspace{.5in} subject to linear constraints -$$ -\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}l} -a_{11}x_{m+1}&+&a_{12}x_{m+2}&+ \dots +&a_{1n}x_{m+n}&=&b_1 \\ -a_{21}x_{m+1}&+&a_{22}x_{m+2}&+ \dots +&a_{2n}x_{m+n}&=&b_2 \\ -\multicolumn{7}{c} -{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .} \\ -a_{m1}x_{m+1}&+&a_{m2}x_{m+2}&+ \dots +&a_{mn}x_{m+n}&=&b_m \\ -\end{array} \eqno (2.5) -$$ -\hspace{.5in} and non-negative variables -$$x_1\geq 0,\ \ x_2\geq 0,\ \ \dots,\ \ x_n\geq 0 \eqno(2.6)$$ -where: $z$ is the objective function; $x_1$, \dots, $x_n$ are variables; -$c_1$, \dots, $c_n$ are objective coefficients; $c_0$ is a constant term -of the objective function; $a_{11}$, \dots, $a_{mn}$ are constraint -coefficients; $b_1$, \dots, $b_m$ are right-hand sides. - -Using vector and matrix notations the working LP (2.4)---(2.6) can be -written as follows: -$$z=c^Tx+c_0\ \rightarrow\ \min,\eqno(2.7)$$ -$$Ax=b,\eqno(2.8)$$ -$$x\geq 0,\eqno(2.9)$$ -where: $x=(x_j)$ is $n$-vector of variables, $c=(c_j)$ is $n$-vector of -objective coefficients, $A=(a_{ij})$ is $m\times n$-matrix of -constraint coefficients, and $b=(b_i)$ is $m$-vector of right-hand -sides. - -Karush--Kuhn--Tucker optimality conditions for LP (2.7)---(2.9) are the -following: -$$Ax=b,\eqno(2.10)$$ -$$A^T\pi+\lambda=c,\eqno(2.11)$$ -$$\lambda^Tx=0,\eqno(2.12)$$ -$$x\geq 0,\ \ \lambda\geq 0,\eqno(2.13)$$ -where: -$\pi$ is $m$-vector of Lagrange multipliers (dual variables) for -equality constraints (2.8),\linebreak $\lambda$ is $n$-vector of -Lagrange multipliers (dual variables) for non-negativity constraints -(2.9),\linebreak (2.10) is the primal feasibility condition, (2.11) is -the dual feasibility condition, (2.12) is the primal-dual -complementarity condition, and (2.13) is the non-negativity conditions. - -The main idea of the primal-dual interior-point method is based on -finding a point in the primal-dual space (i.e. in the space of all -primal and dual variables $x$, $\pi$, and $\lambda$), which satisfies -to all optimality conditions (2.10)---(2.13). Obviously, $x$-component -of such point then provides an optimal solution to the working LP -(2.7)---(2.9). - -To find the optimal point $(x^*,\pi^*,\lambda^*)$ the interior-point -method attempts to solve the system of equations (2.10)---(2.12), which -is closed in the sense that the number of variables $x_j$, $\pi_i$, and -$\lambda_j$ and the number equations are the same and equal to $m+2n$. -Due to condition (2.12) this system of equations is non-linear, so it -can be solved with a version of {\it Newton's method} provided with -additional rules to keep the current point within the positive orthant -as required by the non-negativity conditions (2.13). - -Finally, once the optimal point $(x^*,\pi^*,\lambda^*)$ has been found, -the solver performs inverse transformations to recover corresponding -solution to the original LP passed to the solver from the application -program. - -\subsection{glp\_interior --- solve LP problem with the interior-point -method} - -\synopsis - -\begin{verbatim} - int glp_interior(glp_prob *P, const glp_iptcp *parm); -\end{verbatim} - -\description - -The routine \verb|glp_interior| is a driver to the LP solver based on -the primal-dual interior-point method. This routine retrieves problem -data from the specified problem object, calls the solver to solve the -problem instance, and stores results of computations back into the -problem object. - -The interior-point solver has a set of control parameters. Values of -the control parameters can be passed in the structure \verb|glp_iptcp|, -which the parameter \verb|parm| points to. For detailed description of -this structure see paragraph ``Control parameters'' below. Before -specifying some control parameters the application program should -initialize the structure \verb|glp_iptcp| by default values of all -control parameters using the routine \verb|glp_init_iptcp| (see the -next subsection). This is needed for backward compatibility, because in -the future there may appear new members in the structure -\verb|glp_iptcp|. - -The parameter \verb|parm| can be specified as \verb|NULL|, in which -case the solver uses default settings. - -\returns - -\begin{retlist} -0 & The LP problem instance has been successfully solved. (This code -does {\it not} necessarily mean that the solver has found optimal -solution. It only means that the solution process was successful.) \\ - -\verb|GLP_EFAIL| & The problem has no rows/columns.\\ - -\verb|GLP_ENOCVG| & Very slow convergence or divergence.\\ - -\verb|GLP_EITLIM| & Iteration limit exceeded.\\ - -\verb|GLP_EINSTAB| & Numerical instability on solving Newtonian -system.\\ -\end{retlist} - -\newpage - -\para{Comments} - -The routine \verb|glp_interior| implements an easy version of -the primal-dual interior-point method based on Mehrotra's -technique.\footnote{S. Mehrotra. On the implementation of a primal-dual -interior point method. SIAM J. on Optim., 2(4), pp. 575-601, 1992.} - -Note that currently the GLPK interior-point solver does not include -many important features, in particular: - -\vspace*{-8pt} - -\begin{itemize} -\item it is not able to process dense columns. Thus, if the constraint -matrix of the LP problem has dense columns, the solving process may be -inefficient; - -\item it has no features against numerical instability. For some LP -problems premature termination may happen if the matrix $ADA^T$ becomes -singular or ill-conditioned; - -\item it is not able to identify the optimal basis, which corresponds -to the interior-point solution found. -\end{itemize} - -\vspace*{-8pt} - -\para{Terminal output} - -Solving large LP problems may take a long time, so the solver reports -some information about every interior-point iteration,\footnote{Unlike -the simplex method the interior point method usually needs 30---50 -iterations (independently on the problem size) in order to find an -optimal solution.} which is sent to the terminal. This information has -the following format: - -\begin{verbatim} -nnn: obj = fff; rpi = ppp; rdi = ddd; gap = ggg -\end{verbatim} - -\noindent where: \verb|nnn| is iteration number, \verb|fff| is the -current value of the objective function (in the case of maximization it -has wrong sign), \verb|ppp| is the current relative primal -infeasibility (cf. (2.10)): -$$\frac{\|Ax^{(k)}-b\|}{1+\|b\|},\eqno(2.14)$$ -\verb|ddd| is the current relative dual infeasibility (cf. (2.11)): -$$\frac{\|A^T\pi^{(k)}+\lambda^{(k)}-c\|}{1+\|c\|},\eqno(2.15)$$ -\verb|ggg| is the current primal-dual gap (cf. (2.12)): -$$\frac{|c^Tx^{(k)}-b^T\pi^{(k)}|}{1+|c^Tx^{(k)}|},\eqno(2.16)$$ -and $[x^{(k)},\pi^{(k)},\lambda^{(k)}]$ is the current point on $k$-th -iteration, $k=0,1,2,\dots$\ . Note that all solution components are -internally scaled, so information sent to the terminal is suitable only -for visual inspection. - -\newpage - -\para{Control parameters} - -This paragraph describes all control parameters currently used in the -interior-point solver. Symbolic names of control parameters are names of -corresponding members in the structure \verb|glp_iptcp|. - -\bigskip - -{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL}) - -Message level for terminal output: - -\verb|GLP_MSG_OFF|---no output; - -\verb|GLP_MSG_ERR|---error and warning messages only; - -\verb|GLP_MSG_ON |---normal output; - -\verb|GLP_MSG_ALL|---full output (including informational messages). - -\bigskip - -{\tt int ord\_alg} (default: {\tt GLP\_ORD\_AMD}) - -Ordering algorithm used prior to Cholesky factorization: - -\verb|GLP_ORD_NONE |---use natural (original) ordering; - -\verb|GLP_ORD_QMD |---quotient minimum degree (QMD); - -\verb|GLP_ORD_AMD |---approximate minimum degree (AMD); - -\verb|GLP_ORD_SYMAMD|---approximate minimum degree (SYMAMD). - -\bigskip - -\para{Example} - -The following main program reads LP problem instance in fixed MPS -format from file\linebreak \verb|25fv47.mps|,\footnote{This instance in -fixed MPS format can be found in the Netlib LP collection; see -{\tt ftp://ftp.netlib.org/lp/data/}.} solves it with the interior-point -solver, and writes the solution to file \verb|25fv47.txt|. - -\begin{footnotesize} -\begin{verbatim} -/* iptsamp.c */ - -#include -#include -#include - -int main(void) -{ glp_prob *P; - P = glp_create_prob(); - glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); - glp_interior(P, NULL); - glp_print_ipt(P, "25fv47.txt"); - glp_delete_prob(P); - return 0; -} - -/* eof */ -\end{verbatim} -\end{footnotesize} - -\newpage - -Below here is shown the terminal output from this example program. - -\begin{footnotesize} -\begin{verbatim} -Reading problem data from `25fv47.mps'... -Problem: 25FV47 -Objective: R0000 -822 rows, 1571 columns, 11127 non-zeros -6919 records were read -Original LP has 822 row(s), 1571 column(s), and 11127 non-zero(s) -Working LP has 821 row(s), 1876 column(s), and 10705 non-zero(s) -Matrix A has 10705 non-zeros -Matrix S = A*A' has 11895 non-zeros (upper triangle) -Minimal degree ordering... -Computing Cholesky factorization S = L'*L... -Matrix L has 35411 non-zeros -Guessing initial point... -Optimization begins... - 0: obj = 1.823377629e+05; rpi = 1.3e+01; rdi = 1.4e+01; gap = 9.3e-01 - 1: obj = 9.260045192e+04; rpi = 5.3e+00; rdi = 5.6e+00; gap = 6.8e+00 - 2: obj = 3.596999742e+04; rpi = 1.5e+00; rdi = 1.2e+00; gap = 1.8e+01 - 3: obj = 1.989627568e+04; rpi = 4.7e-01; rdi = 3.0e-01; gap = 1.9e+01 - 4: obj = 1.430215557e+04; rpi = 1.1e-01; rdi = 8.6e-02; gap = 1.4e+01 - 5: obj = 1.155716505e+04; rpi = 2.3e-02; rdi = 2.4e-02; gap = 6.8e+00 - 6: obj = 9.660273208e+03; rpi = 6.7e-03; rdi = 4.6e-03; gap = 3.9e+00 - 7: obj = 8.694348283e+03; rpi = 3.7e-03; rdi = 1.7e-03; gap = 2.0e+00 - 8: obj = 8.019543639e+03; rpi = 2.4e-03; rdi = 3.9e-04; gap = 1.0e+00 - 9: obj = 7.122676293e+03; rpi = 1.2e-03; rdi = 1.5e-04; gap = 6.6e-01 - 10: obj = 6.514534518e+03; rpi = 6.1e-04; rdi = 4.3e-05; gap = 4.1e-01 - 11: obj = 6.361572203e+03; rpi = 4.8e-04; rdi = 2.2e-05; gap = 3.0e-01 - 12: obj = 6.203355508e+03; rpi = 3.2e-04; rdi = 1.7e-05; gap = 2.6e-01 - 13: obj = 6.032943411e+03; rpi = 2.0e-04; rdi = 9.3e-06; gap = 2.1e-01 - 14: obj = 5.796553021e+03; rpi = 9.8e-05; rdi = 3.2e-06; gap = 1.0e-01 - 15: obj = 5.667032431e+03; rpi = 4.4e-05; rdi = 1.1e-06; gap = 5.6e-02 - 16: obj = 5.613911867e+03; rpi = 2.5e-05; rdi = 4.1e-07; gap = 3.5e-02 - 17: obj = 5.560572626e+03; rpi = 9.9e-06; rdi = 2.3e-07; gap = 2.1e-02 - 18: obj = 5.537276001e+03; rpi = 5.5e-06; rdi = 8.4e-08; gap = 1.1e-02 - 19: obj = 5.522746942e+03; rpi = 2.2e-06; rdi = 4.0e-08; gap = 6.7e-03 - 20: obj = 5.509956679e+03; rpi = 7.5e-07; rdi = 1.8e-08; gap = 2.9e-03 - 21: obj = 5.504571733e+03; rpi = 1.6e-07; rdi = 5.8e-09; gap = 1.1e-03 - 22: obj = 5.502576367e+03; rpi = 3.4e-08; rdi = 1.0e-09; gap = 2.5e-04 - 23: obj = 5.502057119e+03; rpi = 8.1e-09; rdi = 3.0e-10; gap = 7.7e-05 - 24: obj = 5.501885996e+03; rpi = 9.4e-10; rdi = 1.2e-10; gap = 2.4e-05 - 25: obj = 5.501852464e+03; rpi = 1.4e-10; rdi = 1.2e-11; gap = 3.0e-06 - 26: obj = 5.501846549e+03; rpi = 1.4e-11; rdi = 1.2e-12; gap = 3.0e-07 - 27: obj = 5.501845954e+03; rpi = 1.4e-12; rdi = 1.2e-13; gap = 3.0e-08 - 28: obj = 5.501845895e+03; rpi = 1.5e-13; rdi = 1.2e-14; gap = 3.0e-09 -OPTIMAL SOLUTION FOUND -Writing interior-point solution to `25fv47.txt'... -\end{verbatim} -\end{footnotesize} - -\newpage - -\subsection{glp\_init\_iptcp --- initialize interior-point solver -control parameters} - -\synopsis - -\begin{verbatim} - int glp_init_iptcp(glp_iptcp *parm); -\end{verbatim} - -\description - -The routine \verb|glp_init_iptcp| initializes control parameters, which -are used by the interior-point solver, with default values. - -Default values of the control parameters are stored in the structure -\verb|glp_iptcp|, which the parameter \verb|parm| points to. - -\subsection{glp\_ipt\_status --- determine solution status} - -\synopsis - -\begin{verbatim} - int glp_ipt_status(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_ipt_status| reports the status of a solution -found by the interior-point solver as follows: - -\verb|GLP_UNDEF | --- interior-point solution is undefined; - -\verb|GLP_OPT | --- interior-point solution is optimal; - -\verb|GLP_INFEAS| --- interior-point solution is infeasible; - -\verb|GLP_NOFEAS| --- no feasible primal-dual solution exists. - -\subsection{glp\_ipt\_obj\_val --- retrieve objective value} - -\synopsis - -\begin{verbatim} - double glp_ipt_obj_val(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_ipt_obj_val| returns value of the objective -function for interior-point solution. - -\subsection{glp\_ipt\_row\_prim --- retrieve row primal value} - -\synopsis - -\begin{verbatim} - double glp_ipt_row_prim(glp_prob *P, int i); -\end{verbatim} - -\returns - -The routine \verb|glp_ipt_row_prim| returns primal value of the -auxiliary variable associated with \verb|i|-th row. - -\newpage - -\subsection{glp\_ipt\_row\_dual --- retrieve row dual value} - -\synopsis - -\begin{verbatim} - double glp_ipt_row_dual(glp_prob *P, int i); -\end{verbatim} - -\returns - -The routine \verb|glp_ipt_row_dual| returns dual value (i.e. reduced -cost) of the auxiliary variable associated with \verb|i|-th row. - -\subsection{glp\_ipt\_col\_prim --- retrieve column primal value} - -\synopsis - -\begin{verbatim} - double glp_ipt_col_prim(glp_prob *P, int j); -\end{verbatim} - -\returns - -The routine \verb|glp_ipt_col_prim| returns primal value of the -structural variable associated with \verb|j|-th column. - -\subsection{glp\_ipt\_col\_dual --- retrieve column dual value} - -\synopsis - -\begin{verbatim} - double glp_ipt_col_dual(glp_prob *P, int j); -\end{verbatim} - -\returns - -The routine \verb|glp_ipt_col_dual| returns dual value (i.e. reduced -cost) of the structural variable associated with \verb|j|-th column. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Mixed integer programming routines} - -\subsection{glp\_set\_col\_kind --- set (change) column kind} - -\synopsis - -\begin{verbatim} - void glp_set_col_kind(glp_prob *P, int j, int kind); -\end{verbatim} - -\description - -The routine \verb|glp_set_col_kind| sets (changes) the kind of -\verb|j|-th column (structural variable) as specified by the parameter -\verb|kind|: - -\verb|GLP_CV| --- continuous variable; - -\verb|GLP_IV| --- integer variable; - -\verb|GLP_BV| --- binary variable. - -Setting a column to \verb|GLP_BV| has the same effect as if it were -set to \verb|GLP_IV|, its lower bound were set 0, and its upper bound -were set to 1. - -\subsection{glp\_get\_col\_kind --- retrieve column kind} - -\synopsis - -\begin{verbatim} - int glp_get_col_kind(glp_prob *P, int j); -\end{verbatim} - -\returns - -The routine \verb|glp_get_col_kind| returns the kind of \verb|j|-th -column (structural variable) as follows: - -\verb|GLP_CV| --- continuous variable; - -\verb|GLP_IV| --- integer variable; - -\verb|GLP_BV| --- binary variable. - -\subsection{glp\_get\_num\_int --- retrieve number of integer columns} - -\synopsis - -\begin{verbatim} - int glp_get_num_int(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_get_num_int| returns the number of columns -(structural variables), which are marked as integer. Note that this -number {\it does} include binary columns. - -\newpage - -\subsection{glp\_get\_num\_bin --- retrieve number of binary columns} - -\synopsis - -\begin{verbatim} - int glp_get_num_bin(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_get_num_bin| returns the number of columns -(structural variables), which are marked as integer and whose lower -bound is zero and upper bound is one. - -\subsection{glp\_intopt --- solve MIP problem with the branch-and-cut -method} - -\synopsis - -\begin{verbatim} - int glp_intopt(glp_prob *P, const glp_iocp *parm); -\end{verbatim} - -\description - -The routine \verb|glp_intopt| is a driver to the MIP solver based on -the branch-and-cut method, which is a hybrid of branch-and-bound and -cutting plane methods. - -If the presolver is disabled (see paragraph ``Control parameters'' -below), on entry to the routine \verb|glp_intopt| the problem object, -which the parameter \verb|mip| points to, should contain optimal -solution to LP relaxation (it can be obtained, for example, with the -routine \verb|glp_simplex|). Otherwise, if the presolver is enabled, it -is not necessary. - -The MIP solver has a set of control parameters. Values of the control -parameters can be passed in the structure \verb|glp_iocp|, which the -parameter \verb|parm| points to. For detailed description of this -structure see paragraph ``Control parameters'' below. Before specifying -some control parameters the application program should initialize the -structure \verb|glp_iocp| by default values of all control parameters -using the routine \verb|glp_init_iocp| (see the next subsection). This -is needed for backward compatibility, because in the future there may -appear new members in the structure \verb|glp_iocp|. - -The parameter \verb|parm| can be specified as \verb|NULL|, in which case -the solver uses default settings. - -Note that the GLPK branch-and-cut solver is not perfect, so it is -unable to solve hard or very large scale MIP instances for a reasonable -time. - -\returns - -\begin{retlist} -0 & The MIP problem instance has been successfully solved. (This code -does {\it not} necessarily mean that the solver has found optimal -solution. It only means that the solution process was successful.) \\ - -\verb|GLP_EBOUND| & Unable to start the search, because some -double-bounded variables have incorrect bounds or some integer -variables have non-integer (fractional) bounds.\\ - -\verb|GLP_EROOT| & Unable to start the search, because optimal basis -for initial LP relaxation is not provided. (This code may appear only -if the presolver is disabled.)\\ - -\verb|GLP_ENOPFS| & Unable to start the search, because LP relaxation -of the MIP problem instance has no primal feasible solution. (This code -may appear only if the presolver is enabled.)\\ -\end{retlist} - -\newpage - -\begin{retlist} -\verb|GLP_ENODFS| & Unable to start the search, because LP relaxation -of the MIP problem instance has no dual feasible solution. In other -word, this code means that if the LP relaxation has at least one primal -feasible solution, its optimal solution is unbounded, so if the MIP -problem has at least one integer feasible solution, its (integer) -optimal solution is also unbounded. (This code may appear only if the -presolver is enabled.)\\ - -\verb|GLP_EFAIL| & The search was prematurely terminated due to the -solver failure.\\ - -\verb|GLP_EMIPGAP| & The search was prematurely terminated, because the -relative mip gap tolerance has been reached.\\ - -\verb|GLP_ETMLIM| & The search was prematurely terminated, because the -time limit has been exceeded.\\ - -\verb|GLP_ESTOP| & The search was prematurely terminated by application. -(This code may appear only if the advanced solver interface is used.)\\ -\end{retlist} - -\para{Built-in MIP presolver} - -The branch-and-cut solver has {\it built-in MIP presolver}. It is -a subprogram that transforms the original MIP problem specified in the -problem object to an equivalent MIP problem, which may be easier for -solving with the branch-and-cut method than the original one. For -example, the presolver can remove redundant constraints and variables, -whose optimal values are known, perform bound and coefficient reduction, -etc. Once the transformed MIP problem has been solved, the presolver -transforms its solution back to corresponding solution of the original -problem. - -Presolving is an optional feature of the routine \verb|glp_intopt|, and -by default it is disabled. In order to enable the MIP presolver, the -control parameter \verb|presolve| should be set to \verb|GLP_ON| (see -paragraph ``Control parameters'' below). - -\para{Advanced solver interface} - -The routine \verb|glp_intopt| allows the user to control the -branch-and-cut search by passing to the solver a user-defined callback -routine. For more details see Chapter ``Branch-and-Cut API Routines''. - -\para{Terminal output} - -Solving a MIP problem may take a long time, so the solver reports some -information about best known solutions, which is sent to the terminal. -This information has the following format: - -\begin{verbatim} -+nnn: mip = xxx yyy gap (ppp; qqq) -\end{verbatim} - -\noindent -where: `\verb|nnn|' is the simplex iteration number; `\verb|xxx|' is a -value of the objective function for the best known integer feasible -solution (if no integer feasible solution has been found yet, -`\verb|xxx|' is the text `\verb|not found yet|'); `\verb|rho|' is the -string `\verb|>=|' (in case of minimization) or `\verb|<=|' (in case of -maximization); `\verb|yyy|' is a global bound for exact integer optimum -(i.e. the exact integer optimum is always in the range from `\verb|xxx|' -to `\verb|yyy|'); `\verb|gap|' is the relative mip gap, in percents, -computed as $gap=|xxx-yyy|/(|xxx|+{\tt DBL\_EPSILON})\cdot 100\%$ (if -$gap$ is greater than $999.9\%$, it is not printed); `\verb|ppp|' is the -number of subproblems in the active list, `\verb|qqq|' is the number of -subproblems which have been already fathomed and therefore removed from -the branch-and-bound search tree. - -\newpage - -\subsubsection{Control parameters} - -This paragraph describes all control parameters currently used in the -MIP solver. Symbolic names of control parameters are names of -corresponding members in the structure \verb|glp_iocp|. - -\bigskip\vspace*{-2pt} - -{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL}) - -Message level for terminal output: - -\verb|GLP_MSG_OFF| --- no output; - -\verb|GLP_MSG_ERR| --- error and warning messages only; - -\verb|GLP_MSG_ON | --- normal output; - -\verb|GLP_MSG_ALL| --- full output (including informational messages). - -\bigskip\vspace*{-2pt} - -{\tt int br\_tech} (default: {\tt GLP\_BR\_DTH}) - -Branching technique option: - -\verb|GLP_BR_FFV| --- first fractional variable; - -\verb|GLP_BR_LFV| --- last fractional variable; - -\verb|GLP_BR_MFV| --- most fractional variable; - -\verb|GLP_BR_DTH| --- heuristic by Driebeck and Tomlin; - -\verb|GLP_BR_PCH| --- hybrid pseudo-cost heuristic. - -\bigskip\vspace*{-2pt} - -{\tt int bt\_tech} (default: {\tt GLP\_BT\_BLB}) - -Backtracking technique option: - -\verb|GLP_BT_DFS| --- depth first search; - -\verb|GLP_BT_BFS| --- breadth first search; - -\verb|GLP_BT_BLB| --- best local bound; - -\verb|GLP_BT_BPH| --- best projection heuristic. - -\bigskip\vspace*{-2pt} - -{\tt int pp\_tech} (default: {\tt GLP\_PP\_ALL}) - -Preprocessing technique option: - -\verb|GLP_PP_NONE| --- disable preprocessing; - -\verb|GLP_PP_ROOT| --- perform preprocessing only on the root level; - -\verb|GLP_PP_ALL | --- perform preprocessing on all levels. - -\bigskip\vspace*{-2pt} - -{\tt int fp\_heur} (default: {\tt GLP\_OFF}) - -Feasibility pump heuristic option: - -\verb|GLP_ON | --- enable applying the feasibility pump heuristic; - -\verb|GLP_OFF| --- disable applying the feasibility pump heuristic. - -\newpage - -{\tt int ps\_heur} (default: {\tt GLP\_OFF}) - -Proximity search heuristic\footnote{The Fischetti--Monaci Proximity -Search (a.k.a. Proxy) heuristic. This algorithm is often capable of -rapidly improving a feasible solution of a MIP problem with binary -variables. It allows to quickly obtain suboptimal solutions in some -problems which take too long time to be solved to optimality.} option: - -\verb|GLP_ON | --- enable applying the proximity search heuristic; - -\verb|GLP_OFF| --- disable applying the proximity search pump heuristic. - -\bigskip - -{\tt int ps\_tm\_lim} (default: {\tt 60000}) - -Time limit, in milliseconds, for the proximity search heuristic (see -above). - -\bigskip - -{\tt int gmi\_cuts} (default: {\tt GLP\_OFF}) - -Gomory's mixed integer cut option: - -\verb|GLP_ON | --- enable generating Gomory's cuts; - -\verb|GLP_OFF| --- disable generating Gomory's cuts. - -\bigskip - -{\tt int mir\_cuts} (default: {\tt GLP\_OFF}) - -Mixed integer rounding (MIR) cut option: - -\verb|GLP_ON | --- enable generating MIR cuts; - -\verb|GLP_OFF| --- disable generating MIR cuts. - -\bigskip - -{\tt int cov\_cuts} (default: {\tt GLP\_OFF}) - -Mixed cover cut option: - -\verb|GLP_ON | --- enable generating mixed cover cuts; - -\verb|GLP_OFF| --- disable generating mixed cover cuts. - -\bigskip - -{\tt int clq\_cuts} (default: {\tt GLP\_OFF}) - -Clique cut option: - -\verb|GLP_ON | --- enable generating clique cuts; - -\verb|GLP_OFF| --- disable generating clique cuts. - -\bigskip - -{\tt double tol\_int} (default: {\tt 1e-5}) - -Absolute tolerance used to check if optimal solution to the current LP -relaxation is integer feasible. (Do not change this parameter without -detailed understanding its purpose.) - -\newpage - -{\tt double tol\_obj} (default: {\tt 1e-7}) - -Relative tolerance used to check if the objective value in optimal -solution to the current LP relaxation is not better than in the best -known integer feasible solution. (Do not change this parameter without -detailed understanding its purpose.) - -\bigskip - -{\tt double mip\_gap} (default: {\tt 0.0}) - -The relative mip gap tolerance. If the relative mip gap for currently -known best integer feasible solution falls below this tolerance, the -solver terminates the search. This allows obtainig suboptimal integer -feasible solutions if solving the problem to optimality takes too long -time. - -\bigskip - -{\tt int tm\_lim} (default: {\tt INT\_MAX}) - -Searching time limit, in milliseconds. - -\bigskip - -{\tt int out\_frq} (default: {\tt 5000}) - -Output frequency, in milliseconds. This parameter specifies how -frequently the solver sends information about the solution process to -the terminal. - -\bigskip - -{\tt int out\_dly} (default: {\tt 10000}) - -Output delay, in milliseconds. This parameter specifies how long the -solver should delay sending information about solution of the current -LP relaxation with the simplex method to the terminal. - -\bigskip - -{\tt void (*cb\_func)(glp\_tree *tree, void *info)} -(default: {\tt NULL}) - -Entry point to the user-defined callback routine. \verb|NULL| means -the advanced solver interface is not used. For more details see Chapter -``Branch-and-Cut API Routines''. - -\bigskip - -{\tt void *cb\_info} (default: {\tt NULL}) - -Transit pointer passed to the routine \verb|cb_func| (see above). - -\bigskip - -{\tt int cb\_size} (default: {\tt 0}) - -The number of extra (up to 256) bytes allocated for each node of the -branch-and-bound tree to store application-specific data. On creating -a node these bytes are initialized by binary zeros. - -\bigskip - -{\tt int presolve} (default: {\tt GLP\_OFF}) - -MIP presolver option: - -\verb|GLP_ON | --- enable using the MIP presolver; - -\verb|GLP_OFF| --- disable using the MIP presolver. - -\newpage - -{\tt int binarize} (default: {\tt GLP\_OFF}) - -Binarization option (used only if the presolver is enabled): - -\verb|GLP_ON | --- replace general integer variables by binary ones; - -\verb|GLP_OFF| --- do not use binarization. - -\subsection{glp\_init\_iocp --- initialize integer optimizer control -parameters} - -\synopsis - -\begin{verbatim} - void glp_init_iocp(glp_iocp *parm); -\end{verbatim} - -\description - -The routine \verb|glp_init_iocp| initializes control parameters, which -are used by the branch-and-cut solver, with default values. - -Default values of the control parameters are stored in -a \verb|glp_iocp| structure, which the parameter \verb|parm| points to. - -\subsection{glp\_mip\_status --- determine status of MIP solution} - -\synopsis - -\begin{verbatim} - int glp_mip_status(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_mip_status| reports the status of a MIP solution -found by the MIP solver as follows: - -\verb|GLP_UNDEF | --- MIP solution is undefined; - -\verb|GLP_OPT | --- MIP solution is integer optimal; - -\verb|GLP_FEAS | --- MIP solution is integer feasible, however, its -optimality (or non-optimality) has not been proven, perhaps due to -premature termination of the search; - -\verb|GLP_NOFEAS| --- problem has no integer feasible solution (proven -by the solver). - -\subsection{glp\_mip\_obj\_val --- retrieve objective value} - -\synopsis - -\begin{verbatim} - double glp_mip_obj_val(glp_prob *P); -\end{verbatim} - -\returns - -The routine \verb|glp_mip_obj_val| returns value of the objective -function for MIP solution. - -\subsection{glp\_mip\_row\_val --- retrieve row value} - -\synopsis - -\begin{verbatim} - double glp_mip_row_val(glp_prob *P, int i); -\end{verbatim} - -\returns - -The routine \verb|glp_mip_row_val| returns value of the auxiliary -variable associated with \verb|i|-th row for MIP solution. - -\subsection{glp\_mip\_col\_val --- retrieve column value} - -\synopsis - -\begin{verbatim} - double glp_mip_col_val(glp_prob *P, int j); -\end{verbatim} - -\returns - -The routine \verb|glp_mip_col_val| returns value of the structural -variable associated with \verb|j|-th column for MIP solution. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Additional routines} - -\subsection{glp\_check\_kkt --- check feasibility/optimality -conditions} - -\synopsis - -{\parskip=0pt -\tt void glp\_check\_kkt(glp\_prob *P, int sol, int cond, -double *ae\_max, int *ae\_ind, - -\hspace{105pt}double *re\_max, int *re\_ind);} - -\description - -The routine \verb|glp_check_kkt| allows to check -feasibility/optimality conditions for the current solution stored in -the specified problem object. (For basic and interior-point solutions -these conditions are known as {\it Karush--Kuhn--Tucker optimality -conditions}.) - -The parameter \verb|sol| specifies which solution should be checked: - -\verb|GLP_SOL| --- basic solution; - -\verb|GLP_IPT| --- interior-point solution; - -\verb|GLP_MIP| --- mixed integer solution. - -The parameter \verb|cond| specifies which condition should be checked: - -\verb|GLP_KKT_PE| --- check primal equality constraints (KKT.PE); - -\verb|GLP_KKT_PB| --- check primal bound constraints (KKT.PB); - -\verb|GLP_KKT_DE| --- check dual equality constraints (KKT.DE). This -conditions can be checked only for basic or interior-point solution; - -\verb|GLP_KKT_DB| --- check dual bound constraints (KKT.DB). This -conditions can be checked only for basic or interior-point solution. - -Detailed explanations of these conditions are given below in paragraph -``Background''. - -On exit the routine stores the following information to locations -specified by parameters \verb|ae_max|, \verb|ae_ind|, \verb|re_max|, -and \verb|re_ind| (if some parameter is a null pointer, corresponding -information is not stored): - -\verb|ae_max| --- largest absolute error; - -\verb|ae_ind| --- number of row (KKT.PE), column (KKT.DE), or variable -(KKT.PB, KKT.DB) with the largest absolute error; - -\verb|re_max| --- largest relative error; - -\verb|re_ind| --- number of row (KKT.PE), column (KKT.DE), or variable -(KKT.PB, KKT.DB) with the largest relative error. - -Row (auxiliary variable) numbers are in the range 1 to $m$, where $m$ -is the number of rows in the problem object. Column (structural -variable) numbers are in the range 1 to $n$, where $n$ is the number -of columns in the problem object. Variable numbers are in the range -1 to $m+n$, where variables with numbers 1 to $m$ correspond to rows, -and variables with numbers $m+1$ to $m+n$ correspond to columns. If -the error reported is exact zero, corresponding row, column or variable -number is set to zero. - -\para{Background} - -\def\arraystretch{1.5} - -The first condition checked by the routine is the following: -$$x_R - A x_S = 0, \eqno{\rm (KKT.PE)}$$ -where $x_R$ is the subvector of auxiliary variables (rows), $x_S$ is -the subvector of structural variables (columns), $A$ is the constraint -matrix. This condition expresses the requirement that all primal -variables should satisfy to the system of equality constraints of the -original LP problem. In case of exact arithmetic this condition would -be satisfied for any basic solution; however, in case of inexact -(floating-point) arithmetic, this condition shows how accurate the -primal solution is, that depends on accuracy of a representation of the -basis matrix used by the simplex method, or on accuracy provided by the -interior-point method. - -To check the condition (KKT.PE) the routine computes the vector of -residuals: -$$g = x_R - A x_S,$$ -and determines component of this vector that correspond to largest -absolute and relative errors: -$${\tt ae\_max}=\max_{1\leq i\leq m}|g_i|,$$ -$${\tt re\_max}=\max_{1\leq i\leq m}\frac{|g_i|}{1+|(x_R)_i|}.$$ - -The second condition checked by the routine is the following: -$$l_k \leq x_k \leq u_k {\rm \ \ \ for\ all}\ k=1,\dots,m+n, -\eqno{\rm (KKT.PB)}$$ -where $x_k$ is auxiliary ($1\leq k\leq m$) or structural -($m+1\leq k\leq m+n$) variable, $l_k$ and $u_k$ are, respectively, -lower and upper bounds of the variable $x_k$ (including cases of -infinite bounds). This condition expresses the requirement that all -primal variables shoudl satisfy to bound constraints of the original -LP problem. In case of basic solution all non-basic variables are -placed on their active bounds, so actually the condition (KKT.PB) needs -to be checked for basic variables only. If the primal solution has -sufficient accuracy, this condition shows its primal feasibility. - -To check the condition (KKT.PB) the routine computes a vector of -residuals: -$$ -h_k = \left\{ -\begin{array}{ll} -0, & {\rm if}\ l_k \leq x_k \leq u_k \\ -x_k - l_k, & {\rm if}\ x_k < l_k \\ -x_k - u_k, & {\rm if}\ x_k > u_k \\ -\end{array} -\right. -$$ -for all $k=1,\dots,m+n$, and determines components of this vector that -correspond to largest absolute and relative errors: -$${\tt ae\_max}=\max_{1\leq k \leq m+n}|h_k|,$$ -$${\tt re\_max}=\max_{1\leq k \leq m+n}\frac{|h_k|}{1+|x_k|}.$$ - -The third condition checked by the routine is: -$${\rm grad}\;Z = c = (\tilde{A})^T \pi + d,$$ -where $Z$ is the objective function, $c$ is the vector of objective -coefficients, $(\tilde{A})^T$ is a matrix transposed to the expanded -constraint matrix $\tilde{A} = (I|-A)$, $\pi$ is a vector of Lagrange -multipliers that correspond to equality constraints of the original LP -problem, $d$ is a vector of Lagrange multipliers that correspond to -bound constraints for all (auxiliary and structural) variables of the -original LP problem. Geometrically the third condition expresses the -requirement that the gradient of the objective function should belong -to the orthogonal complement of a linear subspace defined by the -equality and active bound constraints, i.e. that the gradient is -a linear combination of normals to the constraint hyperplanes, where -Lagrange multipliers $\pi$ and $d$ are coefficients of that linear -combination. - -To eliminate the vector $\pi$ rewrite the third condition as: -$$ -\left(\begin{array}{@{}c@{}}I \\ -A^T\end{array}\right) \pi = -\left(\begin{array}{@{}c@{}}d_R \\ d_S\end{array}\right) + -\left(\begin{array}{@{}c@{}}c_R \\ c_S\end{array}\right), -$$ -or, equivalently, -$$ -\left\{ -\begin{array}{r@{}c@{}c} -\pi + d_R&\ =\ &c_R, \\ --A^T\pi + d_S&\ =\ &c_S. \\ -\end{array} -\right. -$$ - -Then substituting the vector $\pi$ from the first equation into the -second we finally have: -$$A^T (d_R - c_R) + (d_S - c_S) = 0, \eqno{\rm(KKT.DE)}$$ -where $d_R$ is the subvector of reduced costs of auxiliary variables -(rows), $d_S$ is the subvector of reduced costs of structural variables -(columns), $c_R$ and $c_S$ are subvectors of objective coefficients at, -respectively, auxiliary and structural variables, $A^T$ is a matrix -transposed to the constraint matrix of the original LP problem. In case -of exact arithmetic this condition would be satisfied for any basic -solution; however, in case of inexact (floating-point) arithmetic, this -condition shows how accurate the dual solution is, that depends on -accuracy of a representation of the basis matrix used by the simplex -method, or on accuracy provided by the interior-point method. - -To check the condition (KKT.DE) the routine computes a vector of -residuals: -$$u = A^T (d_R - c_R) + (d_S - c_S),$$ -and determines components of this vector that correspond to largest -absolute and relative errors: -$${\tt ae\_max}=\max_{1\leq j\leq n}|u_j|,$$ -$${\tt re\_max}=\max_{1\leq j\leq n}\frac{|u_j|}{1+|(d_S)_j-(c_S)_j|}.$$ - -\newpage - -The fourth condition checked by the routine is the following: -$$ -\left\{ -\begin{array}{l@{\ }r@{\ }c@{\ }c@{\ }c@{\ }l@{\ }c@{\ }c@{\ }c@{\ }l} -{\rm if} & -\infty & < & x_k & < & +\infty, -& {\rm then} & d_k & = & 0 \\ -{\rm if} & l_k & \leq & x_k & < & +\infty, -& {\rm then} & d_k & \geq & 0\ {\rm(minimization)} \\ -&&&&&& & d_k & \leq & 0\ {\rm(maximization)} \\ -{\rm if} & -\infty & < & x_k & \leq & u_k, -& {\rm then} & d_k & \leq & 0\ {\rm(minimization)} \\ -&&&&&& & d_k & \geq & 0\ {\rm(maximization)} \\ -{\rm if} & l_k & \leq & x_k & \leq & u_k, -& {\rm then} & d_k & {\rm is} & {\rm of\ any\ sign} \\ -\end{array}\right.\eqno{\rm(KKT.DB)} -$$ -for all $k=1,\dots,m+n$, where $d_k$ is a reduced cost (Lagrange -multiplier) of auxiliary ($1\leq k\leq m$) or structural -($m+1\leq k\leq m+n$) variable $x_k$. Geometrically this condition -expresses the requirement that constraints of the original problem must -``hold'' the point preventing its movement along the anti-gradient (in -case of minimization) or the gradient (in case of maximization) of the -objective function. In case of basic solution reduced costs of all -basic variables are placed on their active (zero) bounds, so actually -the condition (KKT.DB) needs to be checked for non-basic variables -only. If the dual solution has sufficient accuracy, this condition -shows the dual feasibility of the solution. - -To check the condition (KKT.DB) the routine computes a vector of -residuals: -$$ -v_k = \left\{ -\begin{array}{ll} -0, & {\rm if}\ d_k\ {\rm has\ correct\ sign} \\ -|d_k|, & {\rm if}\ d_k\ {\rm has\ wrong\ sign} \\ -\end{array} -\right. -$$ -for all $k=1,\dots,m+n$, and determines components of this vector that -correspond to largest absolute and relative errors: -$${\tt ae\_max}=\max_{1\leq k\leq m+n}|v_k|,$$ -$${\tt re\_max}=\max_{1\leq k\leq m+n}\frac{|v_k|}{1+|d_k - c_k|}.$$ - -Note that the complete set of Karush-Kuhn-Tucker optimality conditions -also includes the fifth, so called {\it complementary slackness -condition}, which expresses the requirement that at least either -a primal variable $x_k$ or its dual counterpart $d_k$ should be on its -bound for all $k=1,\dots,m+n$. Currently checking this condition is -not implemented yet. - -\def\arraystretch{1} - -%* eof *% diff --git a/resources/3rdparty/glpk-4.53/doc/glpk03.tex b/resources/3rdparty/glpk-4.53/doc/glpk03.tex deleted file mode 100644 index 82848a14b..000000000 --- a/resources/3rdparty/glpk-4.53/doc/glpk03.tex +++ /dev/null @@ -1,1572 +0,0 @@ -%* glpk03.tex *% - -\chapter{Utility API routines} - -\section{Problem data reading/writing routines} - -\subsection{glp\_read\_mps --- read problem data in MPS format} - -\synopsis - -\begin{verbatim} - int glp_read_mps(glp_prob *P, int fmt, const glp_mpscp *parm, - const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_read_mps| reads problem data in MPS format from a -text file. (The MPS format is described in Appendix \ref{champs}, page -\pageref{champs}.) - -The parameter \verb|fmt| specifies the MPS format version as follows: - -\verb|GLP_MPS_DECK| --- fixed (ancient) MPS format; - -\verb|GLP_MPS_FILE| --- free (modern) MPS format. - -The parameter \verb|parm| is reserved for use in the future and should -be specified as \verb|NULL|. - -The character string \verb|fname| specifies a name of the text file to -be read in. (If the file name ends with suffix `\verb|.gz|', the file -is assumed to be compressed, in which case the routine -\verb|glp_read_mps| decompresses it ``on the fly''.) - -Note that before reading data the current content of the problem object -is completely erased with the routine \verb|glp_erase_prob|. - -\returns - -If the operation was successful, the routine \verb|glp_read_mps| -returns zero. Otherwise, it prints an error message and returns -non-zero. - -\newpage - -\subsection{glp\_write\_mps --- write problem data in MPS format} - -\synopsis - -\begin{verbatim} - int glp_write_mps(glp_prob *P, int fmt, const glp_mpscp *parm, - const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_write_mps| writes problem data in MPS format to -a text file. (The MPS format is described in Appendix \ref{champs}, -page \pageref{champs}.) - -The parameter \verb|fmt| specifies the MPS format version as follows: - -\verb|GLP_MPS_DECK| --- fixed (ancient) MPS format; - -\verb|GLP_MPS_FILE| --- free (modern) MPS format. - -The parameter \verb|parm| is reserved for use in the future and should -be specified as \verb|NULL|. - -The character string \verb|fname| specifies a name of the text file to -be written out. (If the file name ends with suffix `\verb|.gz|', the -file is assumed to be compressed, in which case the routine -\verb|glp_write_mps| performs automatic compression on writing it.) - -\returns - -If the operation was successful, the routine \verb|glp_write_mps| -returns zero. Otherwise, it prints an error message and returns -non-zero. - -\subsection{glp\_read\_lp --- read problem data in CPLEX LP format} - -\synopsis - -{\tt int glp\_read\_lp(glp\_prob *P, const glp\_cpxcp *parm, -const char *fname);} - -\description - -The routine \verb|glp_read_lp| reads problem data in CPLEX LP format -from a text file. (The CPLEX LP format is described in Appendix -\ref{chacplex}, page \pageref{chacplex}.) - -The parameter \verb|parm| is reserved for use in the future and should -be specified as \verb|NULL|. - -The character string \verb|fname| specifies a name of the text file to -be read in. (If the file name ends with suffix `\verb|.gz|', the file -is assumed to be compressed, in which case the routine -\verb|glp_read_lp| decompresses it ``on the fly''.) - -Note that before reading data the current content of the problem object -is completely erased with the routine \verb|glp_erase_prob|. - -\returns - -If the operation was successful, the routine \verb|glp_read_lp| returns -zero. Otherwise, it prints an error message and returns non-zero. - -\newpage - -\subsection{glp\_write\_lp --- write problem data in CPLEX LP format} - -\synopsis - -{\tt int glp\_write\_lp(glp\_prob *P, const glp\_cpxcp *parm, -const char *fname);} - -\description - -The routine \verb|glp_write_lp| writes problem data in CPLEX LP format -to a text file. (The CPLEX LP format is described in Appendix -\ref{chacplex}, page \pageref{chacplex}.) - -The parameter \verb|parm| is reserved for use in the future and should -be specified as \verb|NULL|. - -The character string \verb|fname| specifies a name of the text file to -be written out. (If the file name ends with suffix `\verb|.gz|', the -file is assumed to be compressed, in which case the routine -\verb|glp_write_lp| performs automatic compression on writing it.) - -\returns - -If the operation was successful, the routine \verb|glp_write_lp| -returns zero. Otherwise, it prints an error message and returns -non-zero. - -\subsection{glp\_read\_prob --- read problem data in GLPK format} - -\synopsis - -\begin{verbatim} - int glp_read_prob(glp_prob *P, int flags, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_read_prob| reads problem data in the GLPK LP/MIP -format from a text file. (For description of the GLPK LP/MIP format see -below.) - -The parameter \verb|flags| is reserved for use in the future and should -be specified as zero. - -The character string \verb|fname| specifies a name of the text file to -be read in. (If the file name ends with suffix `\verb|.gz|', the file -is assumed to be compressed, in which case the routine -\verb|glp_read_prob| decompresses it ``on the fly''.) - -Note that before reading data the current content of the problem object -is completely erased with the routine \verb|glp_erase_prob|. - -\returns - -If the operation was successful, the routine \verb|glp_read_prob| -returns zero. Otherwise, it prints an error message and returns -non-zero. - -\newpage - -\para{GLPK LP/MIP format} - -The GLPK LP/MIP format is a DIMACS-like format.\footnote{The DIMACS -formats were developed by the Center for Discrete Mathematics and -Theoretical Computer Science (DIMACS) to facilitate exchange of problem -data. For details see: {\tt }. } -The file in this format is a plain ASCII text file containing lines of -several types described below. A line is terminated with the -end-of-line character. Fields in each line are separated by at least -one blank space. Each line begins with a one-character designator to -identify the line type. - -The first line of the data file must be the problem line (except -optional comment lines, which may precede the problem line). The last -line of the data file must be the end line. Other lines may follow in -arbitrary order, however, duplicate lines are not allowed. - -\para{Comment lines.} Comment lines give human-readable -information about the data file and are ignored by GLPK routines. -Comment lines can appear anywhere in the data file. Each comment line -begins with the lower-case character \verb|c|. - -\begin{verbatim} - c This is an example of comment line -\end{verbatim} - -\para{Problem line.} There must be exactly one problem line in the -data file. This line must appear before any other lines except comment -lines and has the following format: - -\begin{verbatim} - p CLASS DIR ROWS COLS NONZ -\end{verbatim} - -The lower-case letter \verb|p| specifies that this is the problem line. - -The \verb|CLASS| field defines the problem class and can contain either -the keyword \verb|lp| (that means linear programming problem) or -\verb|mip| (that means mixed integer programming problem). - -The \verb|DIR| field defines the optimization direction (that is, the -objective function sense) and can contain either the keyword \verb|min| -(that means minimization) or \verb|max| (that means maximization). - -The \verb|ROWS|, \verb|COLS|, and \verb|NONZ| fields contain -non-negative integer values specifying, respectively, the number of -rows (constraints), columns (variables), and non-zero constraint -coefficients in the problem instance. Note that \verb|NONZ| value does -not account objective coefficients. - -\para{Row descriptors.} There must be at most one row descriptor line -in the data file for each row (constraint). This line has one of the -following formats: - -\begin{verbatim} - i ROW f - i ROW l RHS - i ROW u RHS - i ROW d RHS1 RHS2 - i ROW s RHS -\end{verbatim} - -The lower-case letter \verb|i| specifies that this is the row -descriptor line. - -The \verb|ROW| field specifies the row ordinal number, an integer -between 1 and $m$, where $m$ is the number of rows in the problem -instance. - -The next lower-case letter specifies the row type as follows: - -\verb|f| --- free (unbounded) row: $-\infty<\sum a_jx_j<+\infty$; - -\verb|l| --- inequality constraint of `$\geq$' type: -$\sum a_jx_j\geq b$; - -\verb|u| --- inequality constraint of `$\leq$' type: -$\sum a_jx_j\leq b$; - -\verb|d| --- double-sided inequality constraint: -$b_1\leq\sum a_jx_j\leq b_2$; - -\verb|s| --- equality constraint: $\sum a_jx_j=b$. - -The \verb|RHS| field contains a floaing-point value specifying the -row right-hand side. The \verb|RHS1| and \verb|RHS2| fields contain -floating-point values specifying, respectively, the lower and upper -right-hand sides for the double-sided row. - -If for some row its descriptor line does not appear in the data file, -by default that row is assumed to be an equality constraint with zero -right-hand side. - -\para{Column descriptors.} There must be at most one column descriptor -line in the data file for each column (variable). This line has one of -the following formats depending on the problem class specified in the -problem line: - -\begin{tabular}{@{}l@{\hspace*{40pt}}l} -LP class & MIP class \\ -\hline -\verb|j COL f| & \verb|j COL KIND f| \\ -\verb|j COL l BND| & \verb|j COL KIND l BND| \\ -\verb|j COL u BND| & \verb|j COL KIND u BND| \\ -\verb|j COL d BND1 BND2| & \verb|j COL KIND d BND1 BND2| \\ -\verb|j COL s BND| & \verb|j COL KIND s BND| \\ -\end{tabular} - -The lower-case letter \verb|j| specifies that this is the column -descriptor line. - -The \verb|COL| field specifies the column ordinal number, an integer -between 1 and $n$, where $n$ is the number of columns in the problem -instance. - -The \verb|KIND| field is used only for MIP problems and specifies the -column kind as follows: - -\verb|c| --- continuous column; - -\verb|i| --- integer column; - -\verb|b| --- binary column (in this case all remaining fields must be -omitted). - -The next lower-case letter specifies the column type as follows: - -\verb|f| --- free (unbounded) column: $-\infty -#include -#include - -int main(void) -{ glp_prob *lp; - glp_tran *tran; - int ret; - lp = glp_create_prob(); - tran = glp_mpl_alloc_wksp(); - ret = glp_mpl_read_model(tran, "egypt.mod", 0); - if (ret != 0) - { fprintf(stderr, "Error on translating model\n"); - goto skip; - } - ret = glp_mpl_generate(tran, NULL); - if (ret != 0) - { fprintf(stderr, "Error on generating model\n"); - goto skip; - } - glp_mpl_build_prob(tran, lp); - ret = glp_write_mps(lp, GLP_MPS_FILE, NULL, "egypt.mps"); - if (ret != 0) - fprintf(stderr, "Error on writing MPS file\n"); -skip: glp_mpl_free_wksp(tran); - glp_delete_prob(lp); - return 0; -} - -/* eof */ -\end{verbatim} -\end{small} - -\newpage - -\subsubsection*{Example 2} - -In this example the program reads model section from file -\verb|sudoku.mod|\footnote{This is an example model which is included -in the GLPK distribution along with alternative data file -{\tt sudoku.dat}.} ignoring data section in this file, reads alternative -data section from file \verb|sudoku.dat|, solves the problem instance -and passes the solution found back to the model. - -\bigskip - -\begin{small} -\begin{verbatim} -/* mplsamp2.c */ - -#include -#include -#include - -int main(void) -{ glp_prob *mip; - glp_tran *tran; - int ret; - mip = glp_create_prob(); - tran = glp_mpl_alloc_wksp(); - ret = glp_mpl_read_model(tran, "sudoku.mod", 1); - if (ret != 0) - { fprintf(stderr, "Error on translating model\n"); - goto skip; - } - ret = glp_mpl_read_data(tran, "sudoku.dat"); - if (ret != 0) - { fprintf(stderr, "Error on translating data\n"); - goto skip; - } - ret = glp_mpl_generate(tran, NULL); - if (ret != 0) - { fprintf(stderr, "Error on generating model\n"); - goto skip; - } - glp_mpl_build_prob(tran, mip); - glp_simplex(mip, NULL); - glp_intopt(mip, NULL); - ret = glp_mpl_postsolve(tran, mip, GLP_MIP); - if (ret != 0) - fprintf(stderr, "Error on postsolving model\n"); -skip: glp_mpl_free_wksp(tran); - glp_delete_prob(mip); - return 0; -} - -/* eof */ -\end{verbatim} -\end{small} - -\newpage - -\subsection{glp\_mpl\_alloc\_wksp --- allocate the translator -workspace} - -\synopsis - -\begin{verbatim} - glp_tran *glp_mpl_alloc_wksp(void); -\end{verbatim} - -\description - -The routine \verb|glp_mpl_alloc_wksp| allocates the MathProg translator -work\-space. (Note that multiple instances of the workspace may be -allocated, if necessary.) - -\returns - -The routine returns a pointer to the workspace, which should be used in -all subsequent operations. - -\subsection{glp\_mpl\_read\_model --- read and translate model section} - -\synopsis - -\begin{verbatim} - int glp_mpl_read_model(glp_tran *tran, const char *fname, int skip); -\end{verbatim} - -\description - -The routine \verb|glp_mpl_read_model| reads model section and, -optionally, data section, which may follow the model section, from a -text file, whose name is the character string \verb|fname|, performs -translation of model statements and data blocks, and stores all the -information in the workspace. - -The parameter \verb|skip| is a flag. If the input file contains the -data section and this flag is non-zero, the data section is not read as -if there were no data section and a warning message is printed. This -allows reading data section(s) from other file(s). - -\returns - -If the operation is successful, the routine returns zero. Otherwise -the routine prints an error message and returns non-zero. - -\subsection{glp\_mpl\_read\_data --- read and translate data section} - -\synopsis - -\begin{verbatim} - int glp_mpl_read_data(glp_tran *tran, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_mpl_read_data| reads data section from a text -file, whose name is the character string \verb|fname|, performs -translation of data blocks, and stores the data read in the translator -workspace. If necessary, this routine may be called more than once. - -\returns - -If the operation is successful, the routine returns zero. Otherwise -the routine prints an error message and returns non-zero. - -\newpage - -\subsection{glp\_mpl\_generate --- generate the model} - -\synopsis - -\begin{verbatim} - int glp_mpl_generate(glp_tran *tran, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_mpl_generate| generates the model using its -description stored in the translator workspace. This operation means -generating all variables, constraints, and objectives, executing check -and display statements, which precede the solve statement (if it is -presented). - -The character string \verb|fname| specifies the name of an output text -file, to which output produced by display statements should be written. -If \verb|fname| is \verb|NULL|, the output is sent to the terminal. - -\returns - -If the operation is successful, the routine returns zero. Otherwise -the routine prints an error message and returns non-zero. - -\vspace*{-6pt} - -\subsection{glp\_mpl\_build\_prob --- build problem instance from the -model} - -\synopsis - -\begin{verbatim} - void glp_mpl_build_prob(glp_tran *tran, glp_prob *P); -\end{verbatim} - -\description - -The routine \verb|glp_mpl_build_prob| obtains all necessary information -from the translator work\-space and stores it in the specified problem -object \verb|P|. Note that before building the current content of the -problem object is erased with the routine \verb|glp_erase_prob|. - -\vspace*{-6pt} - -\subsection{glp\_mpl\_postsolve --- postsolve the model} - -\synopsis - -\begin{verbatim} - int glp_mpl_postsolve(glp_tran *tran, glp_prob *P, int sol); -\end{verbatim} - -\description - -The routine \verb|glp_mpl_postsolve| copies the solution from the -specified problem object \verb|prob| to the translator workspace and -then executes all the remaining model statements, which follow the -solve statement. - -The parameter \verb|sol| specifies which solution should be copied -from the problem object to the workspace as follows: - -\verb|GLP_SOL| --- basic solution; - -\verb|GLP_IPT| --- interior-point solution; - -\verb|GLP_MIP| --- mixed integer solution. - -\returns - -If the operation is successful, the routine returns zero. Otherwise -the routine prints an error message and returns non-zero. - -\subsection{glp\_mpl\_free\_wksp --- free the translator workspace} - -\synopsis - -\begin{verbatim} - void glp_mpl_free_wksp(glp_tran *tran); -\end{verbatim} - -\description - -The routine \verb|glp_mpl_free_wksp| frees all the memory allocated to -the translator workspace. It also frees all other resources, which are -still used by the translator. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Problem solution reading/writing routines} - -\subsection{glp\_print\_sol --- write basic solution in printable -format} - -\synopsis - -\begin{verbatim} - int glp_print_sol(glp_prob *P, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_print_sol writes| the current basic solution of -an LP problem, which is specified by the pointer \verb|P|, to a text -file, whose name is the character string \verb|fname|, in printable -format. - -Information reported by the routine \verb|glp_print_sol| is intended -mainly for visual analysis. - -\returns - -If no errors occurred, the routine returns zero. Otherwise the routine -prints an error message and returns non-zero. - -\subsection{glp\_read\_sol --- read basic solution from text file} - -\synopsis - -\begin{verbatim} - int glp_read_sol(glp_prob *P, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_read_sol| reads basic solution from a text file -whose name is specified by the parameter \verb|fname| into the problem -object. - -For the file format see description of the routine -\verb|glp_write_sol|. - -\returns - -On success the routine returns zero, otherwise non-zero. - -\subsection{glp\_write\_sol --- write basic solution to text file} - -\synopsis - -\begin{verbatim} - int glp_write_sol(glp_prob *P, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_write_sol| writes the current basic solution to -a text file whose name is specified by the parameter \verb|fname|. This -file can be read back with the routine \verb|glp_read_sol|. - -\returns - -On success the routine returns zero, otherwise non-zero. - -\newpage - -\para{File format} - -The file created by the routine \verb|glp_write_sol| is a plain text -file, which contains the following information: - -\begin{verbatim} - m n - p_stat d_stat obj_val - r_stat[1] r_prim[1] r_dual[1] - . . . - r_stat[m] r_prim[m] r_dual[m] - c_stat[1] c_prim[1] c_dual[1] - . . . - c_stat[n] c_prim[n] c_dual[n] -\end{verbatim} - -\noindent -where: - -\noindent -$m$ is the number of rows (auxiliary variables); - -\noindent -$n$ is the number of columns (structural variables); - -\noindent -\verb|p_stat| is the primal status of the basic solution\\ -(\verb|GLP_UNDEF| = 1, \verb|GLP_FEAS| = 2, \verb|GLP_INFEAS| = 3, or -\verb|GLP_NOFEAS| = 4); - -\noindent -\verb|d_stat| is the dual status of the basic solution\\ -(\verb|GLP_UNDEF| = 1, \verb|GLP_FEAS| = 2, \verb|GLP_INFEAS| = 3, or -\verb|GLP_NOFEAS| = 4); - -\noindent -\verb|obj_val| is the objective value; - -\noindent -\verb|r_stat[i]|, $i=1,\dots,m$, is the status of $i$-th row\\ -(\verb|GLP_BS| = 1, \verb|GLP_NL| = 2, \verb|GLP_NU| = 3, -\verb|GLP_NF| = 4, or \verb|GLP_NS| = 5); - -\noindent -\verb|r_prim[i]|, $i=1,\dots,m$, is the primal value of $i$-th row; - -\noindent -\verb|r_dual[i]|, $i=1,\dots,m$, is the dual value of $i$-th row; - -\noindent -\verb|c_stat[j]|, $j=1,\dots,n$, is the status of $j$-th column\\ -(\verb|GLP_BS| = 1, \verb|GLP_NL| = 2, \verb|GLP_NU| = 3, -\verb|GLP_NF| = 4, or \verb|GLP_NS| = 5); - -\noindent -\verb|c_prim[j]|, $j=1,\dots,n$, is the primal value of $j$-th column; - -\noindent -\verb|c_dual[j]|, $j=1,\dots,n$, is the dual value of $j$-th column. - -\subsection{glp\_print\_ipt --- write interior-point solution in -printable format} - -\synopsis - -\begin{verbatim} - int glp_print_ipt(glp_prob *P, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_print_ipt| writes the current interior point -solution of an LP problem, which the parameter \verb|P| points to, to -a text file, whose name is the character string \verb|fname|, in -printable format. - -Information reported by the routine \verb|glp_print_ipt| is intended -mainly for visual analysis. - -\newpage - -\returns - -If no errors occurred, the routine returns zero. Otherwise the routine -prints an error message and returns non-zero. - -\subsection{glp\_read\_ipt --- read interior-point solution from text -file} - -\synopsis - -\begin{verbatim} - int glp_read_ipt(glp_prob *P, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_read_ipt| reads interior-point solution from -a text file whose name is specified by the parameter \verb|fname| into -the problem object. - -For the file format see description of the routine -\verb|glp_write_ipt|. - -\returns - -On success the routine returns zero, otherwise non-zero. - -\subsection{glp\_write\_ipt --- write interior-point solution to text -file} - -\synopsis - -\begin{verbatim} - int glp_write_ipt(glp_prob *P, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_write_ipt| writes the current interior-point -solution to a text file whose name is specified by the parameter -\verb|fname|. This file can be read back with the routine -\verb|glp_read_ipt|. - -\returns - -On success the routine returns zero, otherwise non-zero. - -\para{File format} - -The file created by the routine \verb|glp_write_ipt| is a plain text -file, which contains the following information: - -\begin{verbatim} - m n - stat obj_val - r_prim[1] r_dual[1] - . . . - r_prim[m] r_dual[m] - c_prim[1] c_dual[1] - . . . - c_prim[n] c_dual[n] -\end{verbatim} - -\noindent -where: - -\noindent -$m$ is the number of rows (auxiliary variables); - -\noindent -$n$ is the number of columns (structural variables); - -\noindent -\verb|stat| is the solution status (\verb|GLP_UNDEF| = 1 or -\verb|GLP_OPT| = 5); - -\noindent -\verb|obj_val| is the objective value; - -\noindent -\verb|r_prim[i]|, $i=1,\dots,m$, is the primal value of $i$-th row; - -\noindent -\verb|r_dual[i]|, $i=1,\dots,m$, is the dual value of $i$-th row; - -\noindent -\verb|c_prim[j]|, $j=1,\dots,n$, is the primal value of $j$-th column; - -\noindent -\verb|c_dual[j]|, $j=1,\dots,n$, is the dual value of $j$-th column. - -\subsection{glp\_print\_mip --- write MIP solution in printable format} - -\synopsis - -\begin{verbatim} - int glp_print_mip(glp_prob *P, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_print_mip| writes a best known integer solution -of a MIP problem, which is specified by the pointer \verb|P|, to -a text file, whose name is the character string \verb|fname|, in -printable format. - -Information reported by the routine \verb|glp_print_mip| is intended -mainly for visual analysis. - -\returns - -If no errors occurred, the routine returns zero. Otherwise the routine -prints an error message and returns non-zero. - -\subsection{glp\_read\_mip --- read MIP solution from text file} - -\synopsis - -\begin{verbatim} - int glp_read_mip(glp_prob *P, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_read_mip| reads MIP solution from a text file -whose name is specified by the parameter \verb|fname| into the problem -object. - -For the file format see description of the routine -\verb|glp_write_mip|. - -\returns - -On success the routine returns zero, otherwise non-zero. - -\newpage - -\subsection{glp\_write\_mip --- write MIP solution to text file} - -\synopsis - -\begin{verbatim} - int glp_write_mip(glp_prob *P, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_write_mip| writes the current MIP solution to -a text file whose name is specified by the parameter \verb|fname|. This -file can be read back with the routine \verb|glp_read_mip|. - -\returns - -On success the routine returns zero, otherwise non-zero. - -\para{File format} - -The file created by the routine \verb|glp_write_sol| is a plain text -file, which contains the following information: - -\begin{verbatim} - m n - stat obj_val - r_val[1] - . . . - r_val[m] - c_val[1] - . . . - c_val[n] -\end{verbatim} - -\noindent -where: - -\noindent -$m$ is the number of rows (auxiliary variables); - -\noindent -$n$ is the number of columns (structural variables); - -\noindent -\verb|stat| is the solution status\\(\verb|GLP_UNDEF| = 1, -\verb|GLP_FEAS| = 2, \verb|GLP_NOFEAS| = 4, or \verb|GLP_OPT| = 5); - -\noindent -\verb|obj_val| is the objective value; - -\noindent -\verb|r_val[i]|, $i=1,\dots,m$, is the value of $i$-th row; - -\noindent -\verb|c_val[j]|, $j=1,\dots,n$, is the value of $j$-th column. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Post-optimal analysis routines} - -\subsection{glp\_print\_ranges --- print sensitivity analysis report} - -\synopsis - -{\tt int glp\_print\_ranges(glp\_prob *P, int len, const int list[], -int flags,\\ -\hspace*{134pt}const char *fname);} - -\description - -The routine \verb|glp_print_ranges| performs sensitivity analysis of -current optimal basic solution and writes the analysis report in -human-readable format to a text file, whose name is the character -string {\it fname}. (Detailed description of the report structure is -given below.) - -The parameter {\it len} specifies the length of the row/column list. - -The array {\it list} specifies ordinal number of rows and columns to be -analyzed. The ordinal numbers should be passed in locations -{\it list}[1], {\it list}[2], \dots, {\it list}[{\it len}]. Ordinal -numbers from 1 to $m$ refer to rows, and ordinal numbers from $m+1$ to -$m+n$ refer to columns, where $m$ and $n$ are, resp., the total number -of rows and columns in the problem object. Rows and columns appear in -the analysis report in the same order as they follow in the array list. - -It is allowed to specify $len=0$, in which case the array {\it list} is -not used (so it can be specified as \verb|NULL|), and the routine -performs analysis for all rows and columns of the problem object. - -The parameter {\it flags} is reserved for use in the future and must be -specified as zero. - -On entry to the routine \verb|glp_print_ranges| the current basic -solution must be optimal and the basis factorization must exist. -The application program can check that with the routine -\verb|glp_bf_exists|, and if the factorization does -not exist, compute it with the routine \verb|glp_factorize|. Note that -if the LP preprocessor is not used, on normal exit from the simplex -solver routine \verb|glp_simplex| the basis factorization always exists. - -\returns - -If the operation was successful, the routine \verb|glp_print_ranges| -returns zero. Otherwise, it prints an error message and returns -non-zero. - -\para{Analysis report example} - -An example of the sensitivity analysis report is shown on the next two -pages. This example corresponds to the example of LP problem described -in Subsection ``Example of MPS file''. - -\para{Structure of the analysis report} - -For each row and column specified in the array {\it list} the routine -prints two lines containing generic information and analysis -information, which depends on the status of corresponding row or column. - -Note that analysis of a row is analysis of its auxiliary variable, -which is equal to the row linear form $\sum a_jx_j$, and analysis of -a column is analysis of corresponding structural variable. Therefore, -formally, on performing the sensitivity analysis there is no difference -between rows and columns. - -\newpage - -\begin{landscape} -\begin{footnotesize} -\begin{verbatim} -GLPK 4.42 - SENSITIVITY ANALYSIS REPORT Page 1 - -Problem: PLAN -Objective: VALUE = 296.2166065 (MINimum) - - No. Row name St Activity Slack Lower bound Activity Obj coef Obj value at Limiting - Marginal Upper bound range range break point variable ------- ------------ -- ------------- ------------- ------------- ------------- ------------- ------------- ------------ - 1 VALUE BS 296.21661 -296.21661 -Inf 299.25255 -1.00000 . MN - . +Inf 296.21661 +Inf +Inf - - 2 YIELD NS 2000.00000 . 2000.00000 1995.06864 -Inf 296.28365 BIN3 - -.01360 2000.00000 2014.03479 +Inf 296.02579 CU - - 3 FE NU 60.00000 . -Inf 55.89016 -Inf 306.77162 BIN4 - -2.56823 60.00000 62.69978 2.56823 289.28294 BIN3 - - 4 CU BS 83.96751 16.03249 -Inf 93.88467 -.30613 270.51157 MN - . 100.00000 79.98213 .21474 314.24798 BIN5 - - 5 MN NU 40.00000 . -Inf 34.42336 -Inf 299.25255 BIN4 - -.54440 40.00000 41.68691 .54440 295.29825 BIN3 - - 6 MG BS 19.96029 10.03971 -Inf 24.74427 -1.79618 260.36433 BIN1 - . 30.00000 9.40292 .28757 301.95652 MN - - 7 AL NL 1500.00000 . 1500.00000 1485.78425 -.25199 292.63444 CU - .25199 +Inf 1504.92126 +Inf 297.45669 BIN3 - - 8 SI NL 250.00000 50.00000 250.00000 235.32871 -.48520 289.09812 CU - .48520 300.00000 255.06073 +Inf 298.67206 BIN3 -\end{verbatim} -\end{footnotesize} -\end{landscape} - -\newpage - -\begin{landscape} -\begin{footnotesize} -\begin{verbatim} -GLPK 4.42 - SENSITIVITY ANALYSIS REPORT Page 2 - -Problem: PLAN -Objective: VALUE = 296.2166065 (MINimum) - - No. Column name St Activity Obj coef Lower bound Activity Obj coef Obj value at Limiting - Marginal Upper bound range range break point variable ------- ------------ -- ------------- ------------- ------------- ------------- ------------- ------------- ------------ - 1 BIN1 NL . .03000 . -28.82475 -.22362 288.90594 BIN4 - .25362 200.00000 33.88040 +Inf 304.80951 BIN4 - - 2 BIN2 BS 665.34296 .08000 . 802.22222 .01722 254.44822 BIN1 - . 2500.00000 313.43066 .08863 301.95652 MN - - 3 BIN3 BS 490.25271 .17000 400.00000 788.61314 .15982 291.22807 MN - . 800.00000 -347.42857 .17948 300.86548 BIN5 - - 4 BIN4 BS 424.18773 .12000 100.00000 710.52632 .10899 291.54745 MN - . 700.00000 -256.15524 .14651 307.46010 BIN1 - - 5 BIN5 NL . .15000 . -201.78739 .13544 293.27940 BIN3 - .01456 1500.00000 58.79586 +Inf 297.07244 BIN3 - - 6 ALUM BS 299.63899 .21000 . 358.26772 .18885 289.87879 AL - . +Inf 112.40876 .22622 301.07527 MN - - 7 SILICON BS 120.57762 .38000 . 124.27093 .14828 268.27586 BIN5 - . +Inf 85.54745 .46667 306.66667 MN - -End of report -\end{verbatim} -\end{footnotesize} -\end{landscape} - -\newpage - -\noindent -{\it Generic information} - -{\tt No.} is the row or column ordinal number in the problem object. -Rows are numbered from 1 to $m$, and columns are numbered from 1 to $n$, -where $m$ and $n$ are, resp., the total number of rows and columns in -the problem object. - -{\tt Row name} is the symbolic name assigned to the row. If the row has -no name assigned, this field contains blanks. - -{\tt Column name} is the symbolic name assigned to the column. If the -column has no name assigned, this field contains blanks. - -{\tt St} is the status of the row or column in the optimal solution: - -{\tt BS} --- non-active constraint (row), basic column; - -{\tt NL} --- inequality constraint having its lower right-hand side -active (row), non-basic column having its lower bound active; - -{\tt NU} --- inequality constraint having its upper right-hand side -active (row), non-basic column having its upper bound active; - -{\tt NS} --- active equality constraint (row), non-basic fixed column. - -{\tt NF} --- active free row, non-basic free (unbounded) column. (This -case means that the optimal solution is dual degenerate.) - -{\tt Activity} is the (primal) value of the auxiliary variable (row) or -structural variable (column) in the optimal solution. - -{\tt Slack} is the (primal) value of the row slack variable. - -{\tt Obj coef} is the objective coefficient of the column (structural -variable). - -{\tt Marginal} is the reduced cost (dual activity) of the auxiliary -variable (row) or structural variable (column). - -{\tt Lower bound} is the lower right-hand side (row) or lower bound -(column). If the row or column has no lower bound, this field contains -{\tt -Inf}. - -{\tt Upper bound} is the upper right-hand side (row) or upper bound -(column). If the row or column has no upper bound, this field contains -{\tt +Inf}. - -\noindent -{\it Sensitivity analysis of active bounds} - -The sensitivity analysis of active bounds is performed only for rows, -which are active constraints, and only for non-basic columns, because -inactive constraints and basic columns have no active bounds. - -For every auxiliary (row) or structural (column) non-basic variable the -routine starts changing its active bound in both direction. The first -of the two lines in the report corresponds to decreasing, and the -second line corresponds to increasing of the active bound. Since the -variable being analyzed is non-basic, its activity, which is equal to -its active bound, also starts changing. This changing leads to changing -of basic (auxiliary and structural) variables, which depend on the -non-basic variable. The current basis remains primal feasible and -therefore optimal while values of all basic variables are primal -feasible, i.e. are within their bounds. Therefore, if some basic -variable called the {\it limiting variable} reaches its (lower or -upper) bound first, before any other basic variables, it thereby limits -further changing of the non-basic variable, because otherwise the -current basis would become primal infeasible. The point, at which this -happens, is called the {\it break point}. Note that there are two break -points: the lower break point, which corresponds to decreasing of the -non-basic variable, and the upper break point, which corresponds to -increasing of the non-basic variable. - -In the analysis report values of the non-basic variable (i.e. of its -active bound) being analyzed at both lower and upper break points are -printed in the field `{\tt Activity range}'. Corresponding values of -the objective function are printed in the field `{\tt Obj value at -break point}', and symbolic names of corresponding limiting basic -variables are printed in the field `{\tt Limiting variable}'. -If the active bound can decrease or/and increase unlimitedly, the field -`{\tt Activity range}' contains {\tt -Inf} or/and {\tt +Inf}, resp. - -For example (see the example report above), row SI is a double-sided -constraint, which is active on its lower bound (right-hand side), and -its activity in the optimal solution being equal to the lower bound is -250. The activity range for this row is $[235.32871,255.06073]$. This -means that the basis remains optimal while the lower bound is -increasing up to 255.06073, and further increasing is limited by -(structural) variable BIN3. If the lower bound reaches this upper break -point, the objective value becomes equal to 298.67206. - -Note that if the basis does not change, the objective function depends -on the non-basic variable linearly, and the per-unit change of the -objective function is the reduced cost (marginal value) of the -non-basic variable. - -\noindent -{\it Sensitivity analysis of objective coefficients at non-basic -variables} - -The sensitivity analysis of the objective coefficient at a non-basic -variable is quite simple, because in this case change in the objective -coefficient leads to equivalent change in the reduced cost (marginal -value). - -For every auxiliary (row) or structural (column) non-basic variable the -routine starts changing its objective coefficient in both direction. -(Note that auxiliary variables are not included in the objective -function and therefore always have zero objective coefficients.) The -first of the two lines in the report corresponds to decreasing, and the -second line corresponds to increasing of the objective coefficient. -This changing leads to changing of the reduced cost of the non-basic -variable to be analyzed and does affect reduced costs of all other -non-basic variables. The current basis remains dual feasible and -therefore optimal while the reduced cost keeps its sign. Therefore, if -the reduced cost reaches zero, it limits further changing of the -objective coefficient (if only the non-basic variable is non-fixed). - -In the analysis report minimal and maximal values of the objective -coefficient, on which the basis remains optimal, are printed in the -field `\verb|Obj coef range|'. If the objective coefficient can -decrease or/and increase unlimitedly, this field contains {\tt -Inf} -or/and {\tt +Inf}, resp. - -For example (see the example report above), column BIN5 is non-basic -having its lower bound active. Its objective coefficient is 0.15, and -reduced cost in the optimal solution 0.01456. The column lower bound -remains active while the column reduced cost remains non-negative, -thus, minimal value of the objective coefficient, on which the current -basis still remains optimal, is $0.15-0.01456=0.13644$, that is -indicated in the field `\verb|Obj coef range|'. - -\newpage - -{\parskip=0pt -\noindent -{\it Sensitivity analysis of objective coefficients at basic variables} - -\medskip - -To perform sensitivity analysis for every auxiliary (row) or structural -(column) variable the routine starts changing its objective coefficient -in both direction. (Note that auxiliary variables are not included in -the objective function and therefore always have zero objective -coefficients.) The first of the two lines in the report corresponds to -decreasing, and the second line corresponds to increasing of the -objective coefficient. This changing leads to changing of reduced costs -of non-basic variables. The current basis remains dual feasible and -therefore optimal while reduced costs of all non-basic variables -(except fixed variables) keep their signs. Therefore, if the reduced -cost of some non-basic non-fixed variable called the {\it limiting -variable} reaches zero first, before reduced cost of any other -non-basic non-fixed variable, it thereby limits further changing of the -objective coefficient, because otherwise the current basis would become -dual infeasible (non-optimal). The point, at which this happens, is -called the {\it break point}. Note that there are two break points: the -lower break point, which corresponds to decreasing of the objective -coefficient, and the upper break point, which corresponds to increasing -of the objective coefficient. Let the objective coefficient reach its -limit value and continue changing a bit further in the same direction -that makes the current basis dual infeasible (non-optimal). Then the -reduced cost of the non-basic limiting variable becomes ``a bit'' dual -infeasible that forces the limiting variable to enter the basis -replacing there some basic variable, which leaves the basis to keep its -primal feasibility. It should be understood that if we change the -current basis in this way exactly at the break point, both the current -and adjacent bases will be optimal with the same objective value, -because at the break point the limiting variable has zero reduced cost. -On the other hand, in the adjacent basis the value of the limiting -variable changes, because there it becomes basic, that leads to -changing of the value of the basic variable being analyzed. Note that -on determining the adjacent basis the bounds of the analyzed basic -variable are ignored as if it were a free (unbounded) variable, so it -cannot leave the current basis. - -In the analysis report lower and upper limits of the objective -coefficient at the basic variable being analyzed, when the basis -remains optimal, are printed in the field `{\tt Obj coef range}'. -Corresponding values of the objective function at both lower and upper -break points are printed in the field `{\tt Obj value at break point}', -symbolic names of corresponding non-basic limiting variables are -printed in the field `{\tt Limiting variable}', and values of the basic -variable, which it would take on in the adjacent bases (as was -explained above) are printed in the field `{\tt Activity range}'. -If the objective coefficient can increase or/and decrease unlimitedly, -the field `{\tt Obj coef range}' contains {\tt -Inf} and/or {\tt +Inf}, -resp. It also may happen that no dual feasible adjacent basis exists -(i.e. on entering the basis the limiting variable can increase or -decrease unlimitedly), in which case the field `{\tt Activity range}' -contains {\tt -Inf} and/or {\tt +Inf}. - -For example (see the example report above), structural variable -(column) BIN3 is basic, its optimal value is 490.25271, and its -objective coefficient is 0.17. The objective coefficient range for this -column is $[0.15982,0.17948]$. This means that the basis remains -optimal while the objective coefficient is decreasing down to 0.15982, -and further decreasing is limited by (auxiliary) variable MN. If we -make the objective coefficient a bit less than 0.15982, the limiting -variable MN will enter the basis, and in that adjacent basis the -structural variable BIN3 will take on new optimal value 788.61314. At -the lower break point, where the objective coefficient is exactly -0.15982, the objective function takes on the value 291.22807 in both -the current and adjacent bases. - -Note that if the basis does not change, the objective function depends -on the objective coefficient at the basic variable linearly, and the -per-unit change of the objective function is the value of the basic -variable. -} - -%* eof *% diff --git a/resources/3rdparty/glpk-4.53/doc/glpk04.tex b/resources/3rdparty/glpk-4.53/doc/glpk04.tex deleted file mode 100644 index 5c5ed3073..000000000 --- a/resources/3rdparty/glpk-4.53/doc/glpk04.tex +++ /dev/null @@ -1,1385 +0,0 @@ -%* glpk04.tex *% - -\chapter{Advanced API Routines} - -\section{Background} -\label{basbgd} - -Using vector and matrix notations the LP problem (1.1)---(1.3) (see -Section \ref{seclp}, page \pageref{seclp}) can be stated as follows: - -\noindent -\hspace{.5in} minimize (or maximize) -$$z=c^Tx_S+c_0\eqno(3.1)$$ -\hspace{.5in} subject to linear constraints -$$x_R=Ax_S\eqno(3.2)$$ -\hspace{.5in} and bounds of variables -$$ -\begin{array}{l@{\ }c@{\ }l@{\ }c@{\ }l} -l_R&\leq&x_R&\leq&u_R\\ -l_S&\leq&x_S&\leq&u_S\\ -\end{array}\eqno(3.3) -$$ -where: - -$x_R=(x_1,\dots,x_m)$ is the vector of auxiliary variables; - -$x_S=(x_{m+1},\dots,x_{m+n})$ is the vector of structural variables; - -$z$ is the objective function; - -$c=(c_1,\dots,c_n)$ is the vector of objective coefficients; - -$c_0$ is the constant term (``shift'') of the objective function; - -$A=(a_{11},\dots,a_{mn})$ is the constraint matrix; - -$l_R=(l_1,\dots,l_m)$ is the vector of lower bounds of auxiliary -variables; - -$u_R=(u_1,\dots,u_m)$ is the vector of upper bounds of auxiliary -variables; - -$l_S=(l_{m+1},\dots,l_{m+n})$ is the vector of lower bounds of -structural variables; - -$u_S=(u_{m+1},\dots,u_{m+n})$ is the vector of upper bounds of -structural variables. - -From the simplex method's standpoint there is no difference between -auxiliary and structural variables. This allows combining all these -variables into one vector that leads to the following problem -statement: - -\noindent -\hspace{.5in} minimize (or maximize) -$$z=(0\ |\ c)^Tx+c_0\eqno(3.4)$$ -\hspace{.5in} subject to linear constraints -$$(I\ |-\!A)x=0\eqno(3.5)$$ -\hspace{.5in} and bounds of variables -$$l\leq x\leq u\eqno(3.6)$$ -where: - -$x=(x_R\ |\ x_S)$ is the $(m+n)$-vector of (all) variables; - -$(0\ |\ c)$ is the $(m+n)$-vector of objective -coefficients;\footnote{Subvector 0 corresponds to objective -coefficients at auxiliary variables.} - -$(I\ |-\!A)$ is the {\it augmented} constraint -$m\times(m+n)$-matrix;\footnote{Note that due to auxiliary variables -matrix $(I\ |-\!A)$ contains the unity submatrix and therefore has full -rank. This means, in particular, that the system (3.5) has no linearly -dependent constraints.} - -$l=(l_R\ |\ l_S)$ is the $(m+n)$-vector of lower bounds of (all) -variables; - -$u=(u_R\ |\ u_S)$ is the $(m+n)$-vector of upper bounds of (all) -variables. - -By definition an {\it LP basic solution} geometrically is a point in -the space of all variables, which is the intersection of hyperplanes -corresponding to active constraints\footnote{A constraint is called -{\it active} if at a given point it is satisfied as equality, otherwise -it is called {\it inactive}.}. The space of all variables has the -dimension $m+n$, therefore, to define some basic solution we have to -define $m+n$ active constraints. Note that $m$ constraints (3.5) being -linearly independent equalities are always active, so remaining $n$ -active constraints can be chosen only from bound constraints (3.6). - -A variable is called {\it non-basic}, if its (lower or upper) bound is -active, otherwise it is called {\it basic}. Since, as was said above, -exactly $n$ bound constraints must be active, in any basic solution -there are always $n$ non-basic variables and $m$ basic variables. -(Note that a free variable also can be non-basic. Although such -variable has no bounds, we can think it as the difference between two -non-negative variables, which both are non-basic in this case.) - -Now consider how to determine numeric values of all variables for a -given basic solution. - -Let $\Pi$ be an appropriate permutation matrix of the order $(m+n)$. -Then we can write: -$$\left(\begin{array}{@{}c@{}}x_B\\x_N\\\end{array}\right)= -\Pi\left(\begin{array}{@{}c@{}}x_R\\x_S\\\end{array}\right)=\Pi x, -\eqno(3.7)$$ -where $x_B$ is the vector of basic variables, $x_N$ is the vector of -non-basic variables, $x=(x_R\ |\ x_S)$ is the vector of all variables -in the original order. In this case the system of linear constraints -(3.5) can be rewritten as follows: -$$(I\ |-\!A)\Pi^T\Pi x=0\ \ \ \Rightarrow\ \ \ (B\ |\ N) -\left(\begin{array}{@{}c@{}}x_B\\x_N\\\end{array}\right)=0,\eqno(3.8)$$ -where -$$(B\ |\ N)=(I\ |-\!A)\Pi^T.\eqno(3.9)$$ - -\newpage - -Matrix $B$ is a square non-singular $m\times m$-matrix, which is -composed from columns of the augmented constraint matrix corresponding -to basic variables. It is called the {\it basis matrix} or simply the -{\it basis}. Matrix $N$ is a rectangular $m\times n$-matrix, which is -composed from columns of the augmented constraint matrix corresponding -to non-basic variables. - -From (3.8) it follows that: -$$Bx_B+Nx_N=0,\eqno(3.10)$$ -therefore, -$$x_B=-B^{-1}Nx_N.\eqno(3.11)$$ -Thus, the formula (3.11) shows how to determine numeric values of basic -variables $x_B$ assuming that non-basic variables $x_N$ are fixed on -their active bounds. - -The $m\times n$-matrix -$$\Xi=-B^{-1}N,\eqno(3.12)$$ -which appears in (3.11), is called the {\it simplex -tableau}.\footnote{This definition corresponds to the GLPK -implementation.} It shows how basic variables depend on non-basic -variables: -$$x_B=\Xi x_N.\eqno(3.13)$$ - -The system (3.13) is equivalent to the system (3.5) in the sense that -they both define the same set of points in the space of (primal) -variables, which satisfy to these systems. If, moreover, values of all -basic variables satisfy to their bound constraints (3.3), the -corresponding basic solution is called {\it (primal) feasible}, -otherwise {\it (primal) infeasible}. It is understood that any (primal) -feasible basic solution satisfy to all constraints (3.2) and (3.3). - -The LP theory says that if LP has optimal solution, it has (at least -one) basic feasible solution, which corresponds to the optimum. And the -most natural way to determine whether a given basic solution is optimal -or not is to use the Karush---Kuhn---Tucker optimality conditions. - -\def\arraystretch{1.5} - -For the problem statement (3.4)---(3.6) the optimality conditions are -the following:\footnote{These conditions can be appiled to any solution, -not only to a basic solution.} -$$(I\ |-\!A)x=0\eqno(3.14)$$ -$$(I\ |-\!A)^T\pi+\lambda_l+\lambda_u=\nabla z=(0\ |\ c)^T\eqno(3.15)$$ -$$l\leq x\leq u\eqno(3.16)$$ -$$\lambda_l\geq 0,\ \ \lambda_u\leq 0\ \ \mbox{(minimization)} -\eqno(3.17)$$ -$$\lambda_l\leq 0,\ \ \lambda_u\geq 0\ \ \mbox{(maximization)} -\eqno(3.18)$$ -$$(\lambda_l)_k(x_k-l_k)=0,\ \ (\lambda_u)_k(x_k-u_k)=0,\ \ k=1,2,\dots, -m+n\eqno(3.19)$$ -where: -$\pi=(\pi_1,\pi_2,\dots,\pi_m)$ is a $m$-vector of Lagrange -multipliers for equality constraints (3.5); -$\lambda_l=[(\lambda_l)_1,(\lambda_l)_2,\dots,(\lambda_l)_n]$ is a -$n$-vector of Lagrange multipliers for lower bound constraints (3.6); -$\lambda_u=[(\lambda_u)_1,(\lambda_u)_2,\dots,(\lambda_u)_n]$ is a -$n$-vector of Lagrange multipliers for upper bound constraints (3.6). - -\newpage - -Condition (3.14) is the {\it primal} (original) system of equality -constraints (3.5). - -Condition (3.15) is the {\it dual} system of equality constraints. -It requires the gradient of the objective function to be a linear -combination of normals to the planes defined by constraints of the -original problem. - -Condition (3.16) is the primal (original) system of bound constraints -(3.6). - -Condition (3.17) (or (3.18) in case of maximization) is the dual system -of bound constraints. - -Condition (3.19) is the {\it complementary slackness condition}. It -requires, for each original (auxiliary or structural) variable $x_k$, -that either its (lower or upper) bound must be active, or zero bound of -the corresponding Lagrange multiplier ($(\lambda_l)_k$ or -$(\lambda_u)_k$) must be active. - -In GLPK two multipliers $(\lambda_l)_k$ and $(\lambda_u)_k$ for each -primal (original) variable $x_k$, $k=1,2,\dots,\linebreak m+n$, are -combined into one multiplier: -$$\lambda_k=(\lambda_l)_k+(\lambda_u)_k,\eqno(3.20)$$ -which is called a {\it dual variable} for $x_k$. This {\it cannot} lead -to the ambiguity, because both lower and upper bounds of $x_k$ cannot be -active at the same time,\footnote{If $x_k$ is a fixed variable, we can -think it as double-bounded variable $l_k\leq x_k\leq u_k$, where -$l_k=u_k.$} so at least one of $(\lambda_l)_k$ and $(\lambda_u)_k$ must -be equal to zero, and because these multipliers have different signs, -the combined multiplier, which is their sum, uniquely defines each of -them. - -\def\arraystretch{1} - -Using dual variables $\lambda_k$ the dual system of bound constraints -(3.17) and (3.18) can be written in the form of so called {\it ``rule of -signs''} as follows: - -\medskip - -\begin{center} -\begin{tabular}{|@{\,}c@{$\,$}|@{$\,$}c@{$\,$}|@{$\,$}c@{$\,$}| -@{$\,$}c|c@{$\,$}|@{$\,$}c@{$\,$}|@{$\,$}c@{$\,$}|} -\hline -Original bound&\multicolumn{3}{c|}{Minimization}&\multicolumn{3}{c|} -{Maximization}\\ -\cline{2-7} -constraint&$(\lambda_l)_k$&$(\lambda_u)_k$&$(\lambda_l)_k+ -(\lambda_u)_k$&$(\lambda_l)_k$&$(\lambda_u)_k$&$(\lambda_l)_k+ -(\lambda_u)_k$\\ -\hline -$-\infty= {\tt piv\_tol}\cdot\max|u_{i*}|$, i.e. if it is not very -small in the magnitude among other elements in the same row. Decreasing -this parameter may lead to better sparsity at the expense of numerical -accuracy, and vice versa. - -\medskip - -{\tt int piv\_lim} (default: {\tt 4}) - -This parameter is used on computing $LU$-factorization of the basis -matrix and specifies how many pivot candidates needs to be considered -on choosing a pivot element, \verb|piv_lim| $\geq$ 1. If \verb|piv_lim| -candidates have been considered, the pivoting routine prematurely -terminates the search with the best candidate found. - -\newpage - -{\tt int suhl} (default: {\tt GLP\_ON}) - -This parameter is used on computing $LU$-factorization of the basis -matrix. Being set to {\tt GLP\_ON} it enables applying the following -heuristic proposed by Uwe Suhl: if a column of the active submatrix has -no eligible pivot candidates, it is no more considered until it becomes -a column singleton. In many cases this allows reducing the time needed -for pivot searching. To disable this heuristic the parameter -\verb|suhl| should be set to {\tt GLP\_OFF}. - -\medskip - -{\tt double eps\_tol} (default: {\tt 1e-15}) - -Epsilon tolerance, \verb|eps_tol| $\geq$ 0, used on computing -$LU$-factorization of the basis matrix. If an element of the active -submatrix of factor $U$ is less than \verb|eps_tol| in the magnitude, -it is replaced by exact zero. - -\medskip - -{\tt double max\_gro} (default: {\tt 1e+10}) - -Maximal growth of elements of factor $U$, \verb|max_gro| $\geq$ 1, -allowable on computing $LU$-factorization of the basis matrix. If on -some elimination step the ratio $u_{big}/b_{max}$ (where $u_{big}$ is -the largest magnitude of elements of factor $U$ appeared in its active -submatrix during all the factorization process, $b_{max}$ is the -largest magnitude of elements of the basis matrix to be factorized), -the basis matrix is considered as ill-conditioned. - -\medskip - -{\tt int nfs\_max} (default: {\tt 100}) - -Maximal number of additional row-like factors (entries of the eta -file), \verb|nfs_max| $\geq$ 1, which can be added to -$LU$-factorization of the basis matrix on updating it with the -Forrest--Tomlin technique. This parameter is used only once, before -$LU$-factorization is computed for the first time, to allocate working -arrays. As a rule, each update adds one new factor (however, some -updates may need no addition), so this parameter limits the number of -updates between refactorizations. - -\medskip - -{\tt double upd\_tol} (default: {\tt 1e-6}) - -Update tolerance, 0 $<$ \verb|upd_tol| $<$ 1, used on updating -$LU$-factorization of the basis matrix with the Forrest--Tomlin -technique. If after updating the magnitude of some diagonal element -$u_{kk}$ of factor $U$ becomes less than -${\tt upd\_tol}\cdot\max(|u_{k*}|, |u_{*k}|)$, the factorization is -considered as inaccurate. - -\medskip - -{\tt int nrs\_max} (default: {\tt 100}) - -Maximal number of additional rows and columns, \verb|nrs_max| $\geq$ 1, -which can be added to $LU$-factorization of the basis matrix on -updating it with the Schur complement technique. This parameter is used -only once, before $LU$-factorization is computed for the first time, to -allocate working arrays. As a rule, each update adds one new row and -column (however, some updates may need no addition), so this parameter -limits the number of updates between refactorizations. - -\medskip - -{\tt int rs\_size} (default: {\tt 0}) - -The initial size of the Sparse Vector Area, in non-zeros, used to -store non-zero elements of additional rows and columns introduced on -updating $LU$-factorization of the basis matrix with the Schur -complement technique. If this parameter is set to 0, the initial SVA -size is determined automatically. - -\newpage - -\subsection{glp\_get\_bhead --- retrieve the basis header information} - -\synopsis - -\begin{verbatim} - int glp_get_bhead(glp_prob *P, int k); -\end{verbatim} - -\description - -The routine \verb|glp_get_bhead| returns the basis header information -for the current basis associated with the specified problem object. - -\returns - -If basic variable $(x_B)_k$, $1\leq k\leq m$, is $i$-th auxiliary -variable ($1\leq i\leq m$), the routine returns $i$. Otherwise, if -$(x_B)_k$ is $j$-th structural variable ($1\leq j\leq n$), the routine -returns $m+j$. Here $m$ is the number of rows and $n$ is the number of -columns in the problem object. - -\para{Comments} - -Sometimes the application program may need to know which original -(auxiliary and structural) variable correspond to a given basic -variable, or, that is the same, which column of the augmented -constraint matrix $(I\ |-\!A)$ correspond to a given column of the -basis matrix $B$. - -\def\arraystretch{1} - -The correspondence is defined as follows:\footnote{For more details see -Subsection \ref{basbgd}, page \pageref{basbgd}.} -$$\left(\begin{array}{@{}c@{}}x_B\\x_N\\\end{array}\right)= -\Pi\left(\begin{array}{@{}c@{}}x_R\\x_S\\\end{array}\right) -\ \ \Leftrightarrow -\ \ \left(\begin{array}{@{}c@{}}x_R\\x_S\\\end{array}\right)= -\Pi^T\left(\begin{array}{@{}c@{}}x_B\\x_N\\\end{array}\right),$$ -where $x_B$ is the vector of basic variables, $x_N$ is the vector of -non-basic variables, $x_R$ is the vector of auxiliary variables -following in their original order,\footnote{The original order of -auxiliary and structural variables is defined by the ordinal numbers -of corresponding rows and columns in the problem object.} $x_S$ is the -vector of structural variables following in their original order, $\Pi$ -is a permutation matrix (which is a component of the basis -factorization). - -Thus, if $(x_B)_k=(x_R)_i$ is $i$-th auxiliary variable, the routine -returns $i$, and if $(x_B)_k=(x_S)_j$ is $j$-th structural variable, -the routine returns $m+j$, where $m$ is the number of rows in the -problem object. - -\subsection{glp\_get\_row\_bind --- retrieve row index in the basis -header} - -\synopsis - -\begin{verbatim} - int glp_get_row_bind(glp_prob *P, int i); -\end{verbatim} - -\returns - -The routine \verb|glp_get_row_bind| returns the index $k$ of basic -variable $(x_B)_k$, $1\leq k\leq m$, which is $i$-th auxiliary variable -(that is, the auxiliary variable corresponding to $i$-th row), -$1\leq i\leq m$, in the current basis associated with the specified -problem object, where $m$ is the number of rows. However, if $i$-th -auxiliary variable is non-basic, the routine returns zero. - -\newpage - -\para{Comments} - -The routine \verb|glp_get_row_bind| is an inversion of the routine -\verb|glp_get_bhead|; that is, if \linebreak -\verb|glp_get_bhead|$(P,k)$ returns $i$, -\verb|glp_get_row_bind|$(P,i)$ returns $k$, and vice versa. - -\subsection{glp\_get\_col\_bind --- retrieve column index in the basis -header} - -\synopsis - -\begin{verbatim} - int glp_get_col_bind(glp_prob *P, int j); -\end{verbatim} - -\returns - -The routine \verb|glp_get_col_bind| returns the index $k$ of basic -variable $(x_B)_k$, $1\leq k\leq m$, which is $j$-th structural -variable (that is, the structural variable corresponding to $j$-th -column), $1\leq j\leq n$, in the current basis associated with the -specified problem object, where $m$ is the number of rows, $n$ is the -number of columns. However, if $j$-th structural variable is non-basic, -the routine returns zero. - -\para{Comments} - -The routine \verb|glp_get_col_bind| is an inversion of the routine -\verb|glp_get_bhead|; that is, if \linebreak -\verb|glp_get_bhead|$(P,k)$ returns $m+j$, -\verb|glp_get_col_bind|$(P,j)$ returns $k$, and vice versa. - -\subsection{glp\_ftran --- perform forward transformation} - -\synopsis - -\begin{verbatim} - void glp_ftran(glp_prob *P, double x[]); -\end{verbatim} - -\description - -The routine \verb|glp_ftran| performs forward transformation (FTRAN), -i.e. it solves the system $Bx=b$, where $B$ is the basis matrix -associated with the specified problem object, $x$ is the vector of -unknowns to be computed, $b$ is the vector of right-hand sides. - -On entry to the routine elements of the vector $b$ should be stored in -locations \verb|x[1]|, \dots, \verb|x[m]|, where $m$ is the number of -rows. On exit the routine stores elements of the vector $x$ in the same -locations. - -\subsection{glp\_btran --- perform backward transformation} - -\synopsis - -\begin{verbatim} - void glp_btran(glp_prob *P, double x[]); -\end{verbatim} - -\description - -The routine \verb|glp_btran| performs backward transformation (BTRAN), -i.e. it solves the system $B^Tx=b$, where $B^T$ is a matrix transposed -to the basis matrix $B$ associated with the specified problem object, -$x$ is the vector of unknowns to be computed, $b$ is the vector of -right-hand sides. - -\newpage - -On entry to the routine elements of the vector $b$ should be stored in -locations \verb|x[1]|, \dots, \verb|x[m]|, where $m$ is the number of -rows. On exit the routine stores elements of the vector $x$ in the same -locations. - -\subsection{glp\_warm\_up --- ``warm up'' LP basis} - -\synopsis - -\begin{verbatim} - int glp_warm_up(glp_prob *P); -\end{verbatim} - -\description - -The routine \verb|glp_warm_up| ``warms up'' the LP basis for the -specified problem object using current statuses assigned to rows and -columns (that is, to auxiliary and structural variables). - -This operation includes computing factorization of the basis matrix -(if it does not exist), computing primal and dual components of basic -solution, and determining the solution status. - -\returns - -\begin{retlist} -0 & The operation has been successfully performed.\\ - -\verb|GLP_EBADB| & The basis matrix is invalid, because the number of -basic (auxiliary and structural) variables is not the same as the -number of rows in the problem object.\\ - -\verb|GLP_ESING| & The basis matrix is singular within the working -precision.\\ - -\verb|GLP_ECOND| & The basis matrix is ill-conditioned, i.e. its -condition number is too large.\\ -\end{retlist} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Simplex tableau routines} - -\subsection{glp\_eval\_tab\_row --- compute row of the tableau} - -\synopsis - -\begin{verbatim} - int glp_eval_tab_row(glp_prob *P, int k, int ind[], double val[]); -\end{verbatim} - -\description - -The routine \verb|glp_eval_tab_row| computes a row of the current -simplex tableau (see Subsection 3.1.1, formula (3.12)), which (row) -corresponds to some basic variable specified by the parameter $k$ as -follows: if $1\leq k\leq m$, the basic variable is $k$-th auxiliary -variable, and if $m+1\leq k\leq m+n$, the basic variable is $(k-m)$-th -structural variable, where $m$ is the number of rows and $n$ is the -number of columns in the specified problem object. The basis -factorization must exist. - -The computed row shows how the specified basic variable depends on -non-basic variables: -$$x_k=(x_B)_i=\xi_{i1}(x_N)_1+\xi_{i2}(x_N)_2+\dots+\xi_{in}(x_N)_n,$$ -where $\xi_{i1}$, $\xi_{i2}$, \dots, $\xi_{in}$ are elements of the -simplex table row, $(x_N)_1$, $(x_N)_2$, \dots, $(x_N)_n$ are non-basic -(auxiliary and structural) variables. - -The routine stores column indices and corresponding numeric values of -non-zero elements of the computed row in unordered sparse format in -locations \verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, -\dots, \verb|val[len]|, respectively, where $0\leq{\tt len}\leq n$ is -the number of non-zero elements in the row returned on exit. - -Element indices stored in the array \verb|ind| have the same sense as -index $k$, i.e. indices 1 to $m$ denote auxiliary variables while -indices $m+1$ to $m+n$ denote structural variables (all these variables -are obviously non-basic by definition). - -\returns - -The routine \verb|glp_eval_tab_row| returns \verb|len|, which is the -number of non-zero elements in the simplex table row stored in the -arrays \verb|ind| and \verb|val|. - -\para{Comments} - -A row of the simplex table is computed as follows. At first, the -routine checks that the specified variable $x_k$ is basic and uses the -permutation matrix $\Pi$ (3.7) to determine index $i$ of basic variable -$(x_B)_i$, which corresponds to $x_k$. - -The row to be computed is $i$-th row of the matrix $\Xi$ (3.12), -therefore: -$$\xi_i=e_i^T\Xi=-e_i^TB^{-1}N=-(B^{-T}e_i)^TN,$$ -where $e_i$ is $i$-th unity vector. So the routine performs BTRAN to -obtain $i$-th row of the inverse $B^{-1}$: -$$\varrho_i=B^{-T}e_i,$$ -and then computes elements of the simplex table row as inner products: -$$\xi_{ij}=-\varrho_i^TN_j,\ \ j=1,2,\dots,n,$$ -where $N_j$ is $j$-th column of matrix $N$ (3.9), which (column) -corresponds to non-basic variable $(x_N)_j$. The permutation matrix -$\Pi$ is used again to convert indices $j$ of non-basic columns to -original ordinal numbers of auxiliary and structural variables. - -\subsection{glp\_eval\_tab\_col --- compute column of the tableau} - -\synopsis - -\begin{verbatim} - int glp_eval_tab_col(glp_prob *P, int k, int ind[], double val[]); -\end{verbatim} - -\description - -The routine \verb|glp_eval_tab_col| computes a column of the current -simplex tableau (see Subsection 3.1.1, formula (3.12)), which (column) -corresponds to some non-basic variable specified by the parameter $k$: -if $1\leq k\leq m$, the non-basic variable is $k$-th auxiliary -variable, and if $m+1\leq k\leq m+n$, the non-basic variable is -$(k-m)$-th structural variable, where $m$ is the number of rows and $n$ -is the number of columns in the specified problem object. The basis -factorization must exist. - -The computed column shows how basic variables depends on the specified -non-basic variable $x_k=(x_N)_j$: -$$ -\begin{array}{r@{\ }c@{\ }l@{\ }l} -(x_B)_1&=&\dots+\xi_{1j}(x_N)_j&+\dots\\ -(x_B)_2&=&\dots+\xi_{2j}(x_N)_j&+\dots\\ -.\ \ .&.&.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\\ -(x_B)_m&=&\dots+\xi_{mj}(x_N)_j&+\dots\\ -\end{array} -$$ -where $\xi_{1j}$, $\xi_{2j}$, \dots, $\xi_{mj}$ are elements of the -simplex table column, $(x_B)_1$, $(x_B)_2$, \dots, $(x_B)_m$ are basic -(auxiliary and structural) variables. - -The routine stores row indices and corresponding numeric values of -non-zero elements of the computed column in unordered sparse format in -locations \verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, -\dots, \verb|val[len]|, respectively, where $0\leq{\tt len}\leq m$ is -the number of non-zero elements in the column returned on exit. - -Element indices stored in the array \verb|ind| have the same sense as -index $k$, i.e. indices 1 to $m$ denote auxiliary variables while -indices $m+1$ to $m+n$ denote structural variables (all these variables -are obviously basic by definition). - -\returns - -The routine \verb|glp_eval_tab_col| returns \verb|len|, which is the -number of non-zero elements in the simplex table column stored in the -arrays \verb|ind| and \verb|val|. - -\para{Comments} - -A column of the simplex table is computed as follows. At first, the -routine checks that the specified variable $x_k$ is non-basic and uses -the permutation matrix $\Pi$ (3.7) to determine index $j$ of non-basic -variable $(x_N)_j$, which corresponds to $x_k$. - -The column to be computed is $j$-th column of the matrix $\Xi$ (3.12), -therefore: -$$\Xi_j=\Xi e_j=-B^{-1}Ne_j=-B^{-1}N_j,$$ -where $e_j$ is $j$-th unity vector, $N_j$ is $j$-th column of matrix -$N$ (3.9). So the routine performs FTRAN to transform $N_j$ to the -simplex table column $\Xi_j=(\xi_{ij})$ and uses the permutation matrix -$\Pi$ to convert row indices $i$ to original ordinal numbers of -auxiliary and structural variables. - -\subsection{glp\_transform\_row --- transform explicitly specified row} - -\synopsis - -\begin{verbatim} - int glp_transform_row(glp_prob *P, int len, int ind[], double val[]); -\end{verbatim} - -\description - -The routine \verb|glp_transform_row| performs the same operation as the -routine \verb|glp_eval_tab_row| with exception that the row to be -transformed is specified explicitly as a sparse vector. - -The explicitly specified row may be thought as a linear form: -$$x=a_1x_{m+1}+a_2x_{m+2}+\dots+a_nx_{m+n},$$ -where $x$ is an auxiliary variable for this row, $a_j$ are coefficients -of the linear form, $x_{m+j}$ are structural variables. - -On entry column indices and numerical values of non-zero coefficients -$a_j$ of the specified row should be placed in locations \verb|ind[1]|, -\dots, \verb|ind[len]| and \verb|val[1]|, \dots, \verb|val[len]|, where -\verb|len| is number of non-zero coefficients. - -This routine uses the system of equality constraints and the current -basis in order to express the auxiliary variable $x$ through the current -non-basic variables (as if the transformed row were added to the problem -object and the auxiliary variable $x$ were basic), i.e. the resultant -row has the form: -$$x=\xi_1(x_N)_1+\xi_2(x_N)_2+\dots+\xi_n(x_N)_n,$$ -where $\xi_j$ are influence coefficients, $(x_N)_j$ are non-basic -(auxiliary and structural) variables, $n$ is the number of columns in -the problem object. - -On exit the routine stores indices and numerical values of non-zero -coefficients $\xi_j$ of the resultant row in locations \verb|ind[1]|, -\dots, \verb|ind[len']| and \verb|val[1]|, \dots, \verb|val[len']|, -where $0\leq{\tt len'}\leq n$ is the number of non-zero coefficients in -the resultant row returned by the routine. Note that indices of -non-basic variables stored in the array \verb|ind| correspond to -original ordinal numbers of variables: indices 1 to $m$ mean auxiliary -variables and indices $m+1$ to $m+n$ mean structural ones. - -\returns - -The routine \verb|glp_transform_row| returns \verb|len'|, the number of -non-zero coefficients in the resultant row stored in the arrays -\verb|ind| and \verb|val|. - -\newpage - -\subsection{glp\_transform\_col --- transform explicitly specified -column} - -\synopsis - -\begin{verbatim} - int glp_transform_col(glp_prob *P, int len, int ind[], double val[]); -\end{verbatim} - -\description - -The routine \verb|glp_transform_col| performs the same operation as the -routine \verb|glp_eval_tab_col| with exception that the column to be -transformed is specified explicitly as a sparse vector. - -The explicitly specified column may be thought as it were added to -the original system of equality constraints: -$$ -\begin{array}{l@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r} -x_1&=&a_{11}x_{m+1}&+\dots+&a_{1n}x_{m+n}&+&a_1x \\ -x_2&=&a_{21}x_{m+1}&+\dots+&a_{2n}x_{m+n}&+&a_2x \\ -\multicolumn{7}{c} -{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\ -x_m&=&a_{m1}x_{m+1}&+\dots+&a_{mn}x_{m+n}&+&a_mx \\ -\end{array} -$$ -where $x_i$ are auxiliary variables, $x_{m+j}$ are structural variables -(presented in the problem object), $x$ is a structural variable for the -explicitly specified column, $a_i$ are constraint coefficients at $x$. - -On entry row indices and numerical values of non-zero coefficients -$a_i$ of the specified column should be placed in locations -\verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, \dots, -\verb|val[len]|, where \verb|len| is number of non-zero coefficients. - -This routine uses the system of equality constraints and the current -basis in order to express the current basic variables through the -structural variable $x$ (as if the transformed column were added to the -problem object and the variable $x$ were non-basic): -$$ -\begin{array}{l@{\ }c@{\ }r} -(x_B)_1&=\dots+&\xi_{1}x\\ -(x_B)_2&=\dots+&\xi_{2}x\\ -\multicolumn{3}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .}\\ -(x_B)_m&=\dots+&\xi_{m}x\\ -\end{array} -$$ -where $\xi_i$ are influence coefficients, $x_B$ are basic (auxiliary -and structural) variables, $m$ is the number of rows in the problem -object. - -On exit the routine stores indices and numerical values of non-zero -coefficients $\xi_i$ of the resultant column in locations \verb|ind[1]|, -\dots, \verb|ind[len']| and \verb|val[1]|, \dots, \verb|val[len']|, -where $0\leq{\tt len'}\leq m$ is the number of non-zero coefficients in -the resultant column returned by the routine. Note that indices of basic -variables stored in the array \verb|ind| correspond to original ordinal -numbers of variables, i.e. indices 1 to $m$ mean auxiliary variables, -indices $m+1$ to $m+n$ mean structural ones. - -\returns - -The routine \verb|glp_transform_col| returns \verb|len'|, the number of -non-zero coefficients in the resultant column stored in the arrays -\verb|ind| and \verb|val|. - -\newpage - -\subsection{glp\_prim\_rtest --- perform primal ratio test} - -\synopsis - -\begin{verbatim} - int glp_prim_rtest(glp_prob *P, int len, const int ind[], const double val[], - int dir, double eps); -\end{verbatim} - -\description - -The routine \verb|glp_prim_rtest| performs the primal ratio test using -an explicitly specified column of the simplex table. - -The current basic solution associated with the LP problem object must -be primal feasible. - -The explicitly specified column of the simplex table shows how the -basic variables $x_B$ depend on some non-basic variable $x$ (which is -not necessarily presented in the problem object): -$$ -\begin{array}{l@{\ }c@{\ }r} -(x_B)_1&=\dots+&\xi_{1}x\\ -(x_B)_2&=\dots+&\xi_{2}x\\ -\multicolumn{3}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .}\\ -(x_B)_m&=\dots+&\xi_{m}x\\ -\end{array} -$$ - -The column is specifed on entry to the routine in sparse format. -Ordinal numbers of basic variables $(x_B)_i$ should be placed in -locations \verb|ind[1]|, \dots, \verb|ind[len]|, where ordinal number -1 to $m$ denote auxiliary variables, and ordinal numbers $m+1$ to $m+n$ -denote structural variables. The corresponding non-zero coefficients -$\xi_i$ should be placed in locations -\verb|val[1]|, \dots, \verb|val[len]|. The arrays \verb|ind| and -\verb|val| are not changed by the routine. - -The parameter \verb|dir| specifies direction in which the variable $x$ -changes on entering the basis: $+1$ means increasing, $-1$ means -decreasing. - -The parameter \verb|eps| is an absolute tolerance (small positive -number, say, $10^{-9}$) used by the routine to skip $\xi_i$'s whose -magnitude is less than \verb|eps|. - -The routine determines which basic variable (among those specified in -\verb|ind[1]|, \dots, \verb|ind[len]|) reaches its (lower or upper) -bound first before any other basic variables do, and which, therefore, -should leave the basis in order to keep primal feasibility. - -\returns - -The routine \verb|glp_prim_rtest| returns the index, \verb|piv|, in the -arrays \verb|ind| and \verb|val| corresponding to the pivot element -chosen, $1\leq$ \verb|piv| $\leq$ \verb|len|. If the adjacent basic -solution is primal unbounded, and therefore the choice cannot be made, -the routine returns zero. - -\para{Comments} - -If the non-basic variable $x$ is presented in the LP problem object, -the input column can be computed with the routine -\verb|glp_eval_tab_col|; otherwise, it can be computed with the routine -\verb|glp_transform_col|. - -\newpage - -\subsection{glp\_dual\_rtest --- perform dual ratio test} - -\synopsis - -\begin{verbatim} - int glp_dual_rtest(glp_prob *P, int len, const int ind[], const double val[], - int dir, double eps); -\end{verbatim} - -\description - -The routine \verb|glp_dual_rtest| performs the dual ratio test using -an explicitly specified row of the simplex table. - -The current basic solution associated with the LP problem object must -be dual feasible. - -The explicitly specified row of the simplex table is a linear form -that shows how some basic variable $x$ (which is not necessarily -presented in the problem object) depends on non-basic variables $x_N$: -$$x=\xi_1(x_N)_1+\xi_2(x_N)_2+\dots+\xi_n(x_N)_n.$$ - -The row is specified on entry to the routine in sparse format. Ordinal -numbers of non-basic variables $(x_N)_j$ should be placed in locations -\verb|ind[1]|, \dots, \verb|ind[len]|, where ordinal numbers 1 to $m$ -denote auxiliary variables, and ordinal numbers $m+1$ to $m+n$ denote -structural variables. The corresponding non-zero coefficients $\xi_j$ -should be placed in locations \verb|val[1]|, \dots, \verb|val[len]|. -The arrays \verb|ind| and \verb|val| are not changed by the routine. - -The parameter \verb|dir| specifies direction in which the variable $x$ -changes on leaving the basis: $+1$ means that $x$ goes on its lower -bound, so its reduced cost (dual variable) is increasing (minimization) -or decreasing (maximization); $-1$ means that $x$ goes on its upper -bound, so its reduced cost is decreasing (minimization) or increasing -(maximization). - -The parameter \verb|eps| is an absolute tolerance (small positive -number, say, $10^{-9}$) used by the routine to skip $\xi_j$'s whose -magnitude is less than \verb|eps|. - -The routine determines which non-basic variable (among those specified -in \verb|ind[1]|, \dots,\linebreak \verb|ind[len]|) should enter the -basis in order to keep dual feasibility, because its reduced cost -reaches the (zero) bound first before this occurs for any other -non-basic variables. - -\returns - -The routine \verb|glp_dual_rtest| returns the index, \verb|piv|, in the -arrays \verb|ind| and \verb|val| corresponding to the pivot element -chosen, $1\leq$ \verb|piv| $\leq$ \verb|len|. If the adjacent basic -solution is dual unbounded, and therefore the choice cannot be made, -the routine returns zero. - -\para{Comments} - -If the basic variable $x$ is presented in the LP problem object, the -input row can be computed\linebreak with the routine -\verb|glp_eval_tab_row|; otherwise, it can be computed with the routine -\linebreak \verb|glp_transform_row|. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Post-optimal analysis routines} - -\subsection{glp\_analyze\_bound --- analyze active bound of non-basic -variable} - -\synopsis - -\begin{verbatim} - void glp_analyze_bound(glp_prob *P, int k, double *limit1, int *var1, - double *limit2, int *var2); -\end{verbatim} - -\description - -The routine \verb|glp_analyze_bound| analyzes the effect of varying the -active bound of specified non-basic variable. - -The non-basic variable is specified by the parameter $k$, where -$1\leq k\leq m$ means auxiliary variable of corresponding row, and -$m+1\leq k\leq m+n$ means structural variable (column). - -Note that the current basic solution must be optimal, and the basis -factorization must exist. - -Results of the analysis have the following meaning. - -\verb|value1| is the minimal value of the active bound, at which the -basis still remains primal feasible and thus optimal. \verb|-DBL_MAX| -means that the active bound has no lower limit. - -\verb|var1| is the ordinal number of an auxiliary (1 to $m$) or -structural ($m+1$ to $m+n$) basic variable, which reaches its bound -first and thereby limits further decreasing the active bound being -analyzed. if \verb|value1| = \verb|-DBL_MAX|, \verb|var1| is set to 0. - -\verb|value2| is the maximal value of the active bound, at which the -basis still remains primal feasible and thus optimal. \verb|+DBL_MAX| -means that the active bound has no upper limit. - -\verb|var2| is the ordinal number of an auxiliary (1 to $m$) or -structural ($m+1$ to $m+n$) basic variable, which reaches its bound -first and thereby limits further increasing the active bound being -analyzed. if \verb|value2| = \verb|+DBL_MAX|, \verb|var2| is set to 0. - -The parameters \verb|value1|, \verb|var1|, \verb|value2|, \verb|var2| -can be specified as \verb|NULL|, in which case corresponding information -is not stored. - -\subsection{glp\_analyze\_coef --- analyze objective coefficient at -basic variable} - -\synopsis - -\begin{verbatim} - void glp_analyze_coef(glp_prob *P, int k, - double *coef1, int *var1, double *value1, - double *coef2, int *var2, double *value2); -\end{verbatim} - -\description - -The routine \verb|glp_analyze_coef| analyzes the effect of varying the -objective coefficient at specified basic variable. - -The basic variable is specified by the parameter $k$, where -$1\leq k\leq m$ means auxiliary variable of corresponding row, and -$m+1\leq k\leq m+n$ means structural variable (column). - -Note that the current basic solution must be optimal, and the basis -factorization must exist. - -Results of the analysis have the following meaning. - -\verb|coef1| is the minimal value of the objective coefficient, at -which the basis still remains dual feasible and thus optimal. -\verb|-DBL_MAX| means that the objective coefficient has no lower -limit. - -\verb|var1| is the ordinal number of an auxiliary (1 to $m$) or -structural ($m+1$ to $m+n$) non-basic variable, whose reduced cost -reaches its zero bound first and thereby limits further decreasing the -objective coefficient being analyzed. -If \verb|coef1| = \verb|-DBL_MAX|, \verb|var1| is set to 0. - -\verb|value1| is value of the basic variable being analyzed in an -adjacent basis, which is defined as follows. Let the objective -coefficient reach its minimal value (\verb|coef1|) and continue -decreasing. Then the reduced cost of the limiting non-basic variable -(\verb|var1|) becomes dual infeasible and the current basis becomes -non-optimal that forces the limiting non-basic variable to enter the -basis replacing there some basic variable that leaves the basis to keep -primal feasibility. Should note that on determining the adjacent basis -current bounds of the basic variable being analyzed are ignored as if -it were free (unbounded) variable, so it cannot leave the basis. It may -happen that no dual feasible adjacent basis exists, in which case -\verb|value1| is set to \verb|-DBL_MAX| or \verb|+DBL_MAX|. - -\verb|coef2| is the maximal value of the objective coefficient, at -which the basis still remains dual feasible and thus optimal. -\verb|+DBL_MAX| means that the objective coefficient has no upper -limit. - -\verb|var2| is the ordinal number of an auxiliary (1 to $m$) or -structural ($m+1$ to $m+n$) non-basic variable, whose reduced cost -reaches its zero bound first and thereby limits further increasing the -objective coefficient being analyzed. -If \verb|coef2| = \verb|+DBL_MAX|, \verb|var2| is set to 0. - -\verb|value2| is value of the basic variable being analyzed in an -adjacent basis, which is defined exactly in the same way as -\verb|value1| above with exception that now the objective coefficient -is increasing. - -The parameters \verb|coef1|, \verb|var1|, \verb|value1|, \verb|coef2|, -\verb|var2|, \verb|value2| can be specified as \verb|NULL|, in which -case corresponding information is not stored. - -%* eof *% diff --git a/resources/3rdparty/glpk-4.53/doc/glpk05.tex b/resources/3rdparty/glpk-4.53/doc/glpk05.tex deleted file mode 100644 index d15123e3f..000000000 --- a/resources/3rdparty/glpk-4.53/doc/glpk05.tex +++ /dev/null @@ -1,1090 +0,0 @@ -%* glpk05.tex *% - -\chapter{Branch-and-Cut API Routines} - -\section{Introduction} - -\subsection{Using the callback routine} - -The GLPK MIP solver based on the branch-and-cut method allows the -application program to control the solution process. This is attained -by means of the user-defined callback routine, which is called by the -solver at various points of the branch-and-cut algorithm. - -The callback routine passed to the MIP solver should be written by the -user and has the following specification:\footnote{The name -{\tt foo\_bar} used here is a placeholder for the callback routine -name.} - -\begin{verbatim} - void foo_bar(glp_tree *T, void *info); -\end{verbatim} - -\noindent -where \verb|tree| is a pointer to the data structure \verb|glp_tree|, -which should be used on subsequent calls to branch-and-cut interface -routines, and \verb|info| is a transit pointer passed to the routine -\verb|glp_intopt|, which may be used by the application program to pass -some external data to the callback routine. - -The callback routine is passed to the MIP solver through the control -parameter structure \verb|glp_iocp| (see Chapter ``Basic API -Routines'', Section ``Mixed integer programming routines'', Subsection -``Solve MIP problem with the branch-and-cut method'') as follows: - -\begin{verbatim} - glp_prob *mip; - glp_iocp parm; - . . . - glp_init_iocp(&parm); - . . . - parm.cb_func = foo_bar; - parm.cb_info = ... ; - ret = glp_intopt(mip, &parm); - . . . -\end{verbatim} - -To determine why it is being called by the MIP solver the callback -routine should use the routine \verb|glp_ios_reason| (described in this -section below), which returns a code indicating the reason for calling. -Depending on the reason the callback routine may perform necessary -actions to control the solution process. - -The reason codes, which correspond to various point of the -branch-and-cut algorithm implemented in the MIP solver, are described -in Subsection ``Reasons for calling the callback routine'' below. - -To ignore calls for reasons, which are not processed by the callback -routine, it should simply return to the MIP solver doing nothing. For -example: - -\begin{verbatim} -void foo_bar(glp_tree *T, void *info) -{ . . . - switch (glp_ios_reason(T)) - { case GLP_IBRANCH: - . . . - break; - case GLP_ISELECT: - . . . - break; - default: - /* ignore call for other reasons */ - break; - } - return; -} -\end{verbatim} - -To control the solution process as well as to obtain necessary -information the callback routine may use the branch-and-cut API -routines described in this chapter. Names of all these routines begin -with `\verb|glp_ios_|'. - -\subsection{Branch-and-cut algorithm} - -This section gives a schematic description of the branch-and-cut -algorithm as it is implemented in the GLPK MIP solver. - -{\it 1. Initialization} - -Set $L:=\{P_0\}$, where $L$ is the {\it active list} (i.e. the list of -active subproblems), $P_0$ is the original MIP problem to be solved. - -Set $z^{\it best}:=+\infty$ (in case of minimization) or -$z^{\it best}:=-\infty$ (in case of maximization), where $z^{\it best}$ -is {\it incumbent value}, i.e. an upper (minimization) or lower -(maximization) global bound for $z^{\it opt}$, the optimal objective -value for $P^0$. - -{\it 2. Subproblem selection} - -If $L=\varnothing$ then GO TO 9. - -Select $P\in L$, i.e. make active subproblem $P$ current. - -\newpage - -{\it 3. Solving LP relaxation} - -Solve $P^{\it LP}$, which is LP relaxation of $P$. - -If $P^{\it LP}$ has no primal feasible solution then GO TO 8. - -Let $z^{\it LP}$ be the optimal objective value for $P^{\it LP}$. - -If $z^{\it LP}\geq z^{\it best}$ (minimization) or -$z^{\it LP}\leq z^{\rm best}$ (), GO TO 8. - -{\it 4. Adding ``lazy'' constraints} - -Let $x^{\it LP}$ be the optimal solution to $P^{\it LP}$. - -If there are ``lazy'' constraints (i.e. essential constraints not -included in the original MIP problem $P_0$), which are violated at the -optimal point $x^{\it LP}$, add them to $P$, and GO TO 3. - -{\it 5. Check for integrality} - -Let $x_j$ be a variable, which is required to be integer, and let -$x^{\it LP}_j\in x^{\it LP}$ be its value in the optimal solution to -$P^{\it LP}$. - -If $x^{\it LP}_j$ are integral for all integer variables, then a better -integer feasible solution is found. Store its components, set -$z^{\it best}:=z^{\it LP}$, and GO TO 8. - -{\it 6. Adding cutting planes} - -If there are cutting planes (i.e. valid constraints for $P$), -which are violated at the optimal point $x^{\it LP}$, add them to $P$, -and GO TO 3. - -{\it 7. Branching} - -Select {\it branching variable} $x_j$, i.e. a variable, which is -required to be integer, and whose value $x^{\it LP}_j\in x^{\it LP}$ is -fractional in the optimal solution to $P^{\it LP}$. - -Create new subproblem $P^D$ (so called {\it down branch}), which is -identical to the current subproblem $P$ with exception that the upper -bound of $x_j$ is replaced by $\lfloor x^{\it LP}_j\rfloor$. (For -example, if $x^{\it LP}_j=3.14$, the new upper bound of $x_j$ in the -down branch will be $\lfloor 3.14\rfloor=3$.) - -Create new subproblem $P^U$ (so called {\it up branch}), which is -identical to the current subproblem $P$ with exception that the lower -bound of $x_j$ is replaced by $\lceil x^{\it LP}_j\rceil$. (For example, -if $x^{\it LP}_j=3.14$, the new lower bound of $x_j$ in the up branch -will be $\lceil 3.14\rceil=4$.) - -Set $L:=(L\backslash\{P\})\cup\{P^D,P^U\}$, i.e. remove the current -subproblem $P$ from the active list $L$ and add two new subproblems -$P^D$ and $P^U$ to it. Then GO TO 2. - -{\it 8. Pruning} - -Remove from the active list $L$ all subproblems (including the current -one), whose local bound $\widetilde{z}$ is not better than the global -bound $z^{\it best}$, i.e. set $L:=L\backslash\{P\}$ for all $P$, where -$\widetilde{z}\geq z^{\it best}$ (in case of minimization) or -$\widetilde{z}\leq z^{\it best}$ (in case of maximization), and then -GO TO 2. - -The local bound $\widetilde{z}$ for subproblem $P$ is an lower -(minimization) or upper (maximization) bound for integer optimal -solution to {\it this} subproblem (not to the original problem). This -bound is local in the sense that only subproblems in the subtree rooted -at node $P$ cannot have better integer feasible solutions. Note that -the local bound is not necessarily the optimal objective value to LP -relaxation $P^{\it LP}$. - -{\it 9. Termination} - -If $z^{\it best}=+\infty$ (in case of minimization) or -$z^{\it best}=-\infty$ (in case of maximization), the original problem -$P_0$ has no integer feasible solution. Otherwise, the last integer -feasible solution stored on step 5 is the integer optimal solution to -the original problem $P_0$ with $z^{\it opt}=z^{\it best}$. STOP. - -\subsection{The search tree} - -On the branching step of the branch-and-cut algorithm the current -subproblem is divided into two\footnote{In more general cases the -current subproblem may be divided into more than two subproblems. -However, currently such feature is not used in GLPK.} new subproblems, -so the set of all subproblems can be represented in the form of a rooted -tree, which is called the {\it search} or {\it branch-and-bound} tree. -An example of the search tree is shown on Fig.~1. Each node of the -search tree corresponds to a subproblem, so the terms `node' and -`subproblem' may be used synonymously. - -\begin{figure}[t] -\noindent\hfil -\xymatrix @R=20pt @C=10pt -{&&&&&&*+<14pt>[o][F=]{A}\ar@{-}[dllll]\ar@{-}[dr]\ar@{-}[drrrr]&&&&\\ -&&*+<14pt>[o][F=]{B}\ar@{-}[dl]\ar@{-}[dr]&&&&&*+<14pt>[o][F=]{C} -\ar@{-}[dll]\ar@{-}[dr]\ar@{-}[drrr]&&&*+<14pt>[o][F-]{\times}\\ -&*+<14pt>[o][F-]{\times}\ar@{-}[dl]\ar@{-}[d]\ar@{-}[dr]&& -*+<14pt>[o][F-]{D}&&*+<14pt>[o][F=]{E}\ar@{-}[dl]\ar@{-}[dr]&&& -*+<14pt>[o][F=]{F}\ar@{-}[dl]\ar@{-}[dr]&&*+<14pt>[o][F-]{G}\\ -*+<14pt>[o][F-]{\times}&*+<14pt>[o][F-]{\times}&*+<14pt>[o][F-]{\times} -&&*+<14pt>[][F-]{H}&&*+<14pt>[o][F-]{I}&*+<14pt>[o][F-]{\times}&& -*+<14pt>[o][F-]{J}&\\} - -\bigskip - -\noindent\hspace{.8in} -\xymatrix @R=11pt -{*+<20pt>[][F-]{}&*\txt{\makebox[1in][l]{Current}}&& -*+<20pt>[o][F-]{}&*\txt{\makebox[1in][l]{Active}}\\ -*+<20pt>[o][F=]{}&*\txt{\makebox[1in][l]{Non-active}}&& -*+<14pt>[o][F-]{\times}&*\txt{\makebox[1in][l]{Fathomed}}\\ -} - -\bigskip - -\begin{center} -Fig. 1. An example of the search tree. -\end{center} -\end{figure} - -In GLPK each node may have one of the following four statuses: - -\vspace*{-8pt} - -\begin{itemize} -\item {\it current node} is the active node currently being -processed; - -\item {\it active node} is a leaf node, which still has to be -processed; - -\item {\it non-active node} is a node, which has been processed, -but not fathomed; - -\item {\it fathomed node} is a node, which has been processed and -fathomed. -\end{itemize} - -\vspace*{-8pt} - -In the data structure representing the search tree GLPK keeps only -current, active, and non-active nodes. Once a node has been fathomed, -it is removed from the tree data structure. - -Being created each node of the search tree is assigned a distinct -positive integer called the {\it subproblem reference number}, which -may be used by the application program to specify a particular node of -the tree. The root node corresponding to the original problem to be -solved is always assigned the reference number 1. - -\subsection{Current subproblem} - -The current subproblem is a MIP problem corresponding to the current -node of the search tree. It is represented as the GLPK problem object -(\verb|glp_prob|) that allows the application program using API -routines to access its content in the standard way. If the MIP -presolver is not used, it is the original problem object passed to the -routine \verb|glp_intopt|; otherwise, it is an internal problem object -built by the MIP presolver. - -Note that the problem object is used by the MIP solver itself during -the solution process for various purposes (to solve LP relaxations, to -perfom branching, etc.), and even if the MIP presolver is not used, the -current content of the problem object may differ from its original -content. For example, it may have additional rows, bounds of some rows -and columns may be changed, etc. In particular, LP segment of the -problem object corresponds to LP relaxation of the current subproblem. -However, on exit from the MIP solver the content of the problem object -is restored to its original state. - -To obtain information from the problem object the application program -may use any API routines, which do not change the object. Using API -routines, which change the problem object, is restricted to stipulated -cases. - -\subsection{The cut pool} - -The {\it cut pool} is a set of cutting plane constraints maintained by -the MIP solver. It is used by the GLPK cut generation routines and may -be used by the application program in the same way, i.e. rather than -to add cutting plane constraints directly to the problem object the -application program may store them to the cut pool. In the latter case -the solver looks through the cut pool, selects efficient constraints, -and adds them to the problem object. - -\subsection{Reasons for calling the callback routine} - -The callback routine may be called by the MIP solver for the following -reasons. - -\para{Request for subproblem selection} - -The callback routine is called with the reason code \verb|GLP_ISELECT| -if the current subproblem has been fathomed and therefore there is no -current subproblem. - -In response the callback routine may select some subproblem from the -active list and pass its reference number to the solver using the -routine \verb|glp_ios_select_node|, in which case the solver continues -the search from the specified active subproblem. If no selection is -made by the callback routine, the solver uses a backtracking technique -specified by the control parameter \verb|bt_tech|. - -To explore the active list (i.e. active nodes of the branch-and-bound -tree) the callback routine may use the routines \verb|glp_ios_next_node| -and \verb|glp_ios_prev_node|. - -\para{Request for preprocessing} - -The callback routine is called with the reason code \verb|GLP_IPREPRO| -if the current subproblem has just been selected from the active list -and its LP relaxation is not solved yet. - -In response the callback routine may perform some preprocessing of the -current subproblem like tightening bounds of some variables or removing -bounds of some redundant constraints. - -\para{Request for row generation} - -The callback routine is called with the reason code \verb|GLP_IROWGEN| -if LP relaxation of the current subproblem has just been solved to -optimality and its objective value is better than the best known -integer feasible solution. - -In response the callback routine may add one or more ``lazy'' -constraints (rows), which are violated by the current optimal solution -of LP relaxation, using API routines \verb|glp_add_rows|, -\verb|glp_set_row_name|, \verb|glp_set_row_bnds|, and -\verb|glp_set_mat_row|, in which case the solver will perform -re-optimization of LP relaxation. If there are no violated constraints, -the callback routine should just return. - -Note that components of optimal solution to LP relaxation can be -obtained with API\linebreak routines \verb|glp_get_obj_val|, -\verb|glp_get_row_prim|, \verb|glp_get_row_dual|, -\verb|glp_get_col_prim|, and\linebreak \verb|glp_get_col_dual|. - -\para{Request for heuristic solution} - -The callback routine is called with the reason code \verb|GLP_IHEUR| -if LP relaxation of the current subproblem being solved to optimality -is integer infeasible (i.e. values of some structural variables of -integer kind are fractional), though its objective value is better than -the best known integer feasible solution. - -In response the callback routine may try applying a primal heuristic -to find an integer feasible solution,\footnote{Integer feasible to the -original MIP problem, not to the current subproblem.} which is better -than the best known one. In case of success the callback routine may -store such better solution in the problem object using the routine -\verb|glp_ios_heur_sol|. - -\para{Request for cut generation} - -The callback routine is called with the reason code \verb|GLP_ICUTGEN| -if LP relaxation of the current subproblem being solved to optimality -is integer infeasible (i.e. values of some structural variables of -integer kind are fractional), though its objective value is better than -the best known integer feasible solution. - -In response the callback routine may reformulate the {\it current} -subproblem (before it will be splitted up due to branching) by adding -to the problem object one or more {\it cutting plane constraints}, -which cut off the fractional optimal point from the MIP -polytope.\footnote{Since these constraints are added to the current -subproblem, they may be globally as well as locally valid.} - -Adding cutting plane constraints may be performed in two ways. -One way is the same as for the reason code \verb|GLP_IROWGEN| (see -above), in which case the callback routine adds new rows corresponding -to cutting plane constraints directly to the current subproblem. - -The other way is to add cutting plane constraints to the -{\it cut pool}, a set of cutting plane constraints maintained by the -solver, rather than directly to the current subproblem. In this case -after return from the callback routine the solver looks through the -cut pool, selects efficient cutting plane constraints, adds them to the -current subproblem, drops other constraints, and then performs -re-optimization. - -\para{Request for branching} - -The callback routine is called with the reason code \verb|GLP_IBRANCH| -if LP relaxation of the current subproblem being solved to optimality -is integer infeasible (i.e. values of some structural variables of -integer kind are fractional), though its objective value is better than -the best known integer feasible solution. - -In response the callback routine may choose some variable suitable for -branching (i.e. integer variable, whose value in optimal solution to -LP relaxation of the current subproblem is fractional) and pass its -ordinal number to the solver using the routine -\verb|glp_ios_branch_upon|, in which case the solver splits the current -subproblem in two new subproblems and continues the search. -If no choice is made by the callback routine, the solver uses -a branching technique specified by the control parameter \verb|br_tech|. - -\para{Better integer solution found} - -The callback routine is called with the reason code \verb|GLP_IBINGO| -if LP relaxation of the current subproblem being solved to optimality -is integer feasible (i.e. values of all structural variables of integer -kind are integral within the working precision) and its objective value -is better than the best known integer feasible solution. - -Optimal solution components for LP relaxation can be obtained in the -same way as for the reason code \verb|GLP_IROWGEN| (see above). - -Components of the new MIP solution can be obtained with API routines -\verb|glp_mip_obj_val|, \verb|glp_mip_row_val|, and -\verb|glp_mip_col_val|. Note, however, that due to row/cut generation -there may be additional rows in the problem object. - -The difference between optimal solution to LP relaxation and -corresponding MIP solution is that in the former case some structural -variables of integer kind (namely, basic variables) may have values, -which are close to nearest integers within the working precision, while -in the latter case all such variables have exact integral values. - -The reason \verb|GLP_IBINGO| is intended only for informational -purposes, so the callback routine should not modify the problem object -in this case. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Basic routines} - -\subsection{glp\_ios\_reason --- determine reason for calling the -callback routine} - -\synopsis - -\begin{verbatim} - int glp_ios_reason(glp_tree *T); -\end{verbatim} - -\returns - -The routine \verb|glp_ios_reason| returns a code, which indicates why -the user-defined callback routine is being called: - -\verb|GLP_ISELECT| --- request for subproblem selection; - -\verb|GLP_IPREPRO| --- request for preprocessing; - -\verb|GLP_IROWGEN| --- request for row generation; - -\verb|GLP_IHEUR | --- request for heuristic solution; - -\verb|GLP_ICUTGEN| --- request for cut generation; - -\verb|GLP_IBRANCH| --- request for branching; - -\verb|GLP_IBINGO | --- better integer solution found. - -\subsection{glp\_ios\_get\_prob --- access the problem object} - -\synopsis - -\begin{verbatim} - glp_prob *glp_ios_get_prob(glp_tree *T); -\end{verbatim} - -\description - -The routine \verb|glp_ios_get_prob| can be called from the user-defined -callback routine to access the problem object, which is used by the MIP -solver. It is the original problem object passed to the routine -\verb|glp_intopt| if the MIP presolver is not used; otherwise it is an -internal problem object built by the presolver. - -\returns - -The routine \verb|glp_ios_get_prob| returns a pointer to the problem -object used by the MIP solver. - -\para{Comments} - -To obtain various information about the problem instance the callback -routine can access the problem object (i.e. the object of type -\verb|glp_prob|) using the routine \verb|glp_ios_get_prob|. It is the -original problem object passed to the routine \verb|glp_intopt| if the -MIP presolver is not used; otherwise it is an internal problem object -built by the presolver. - -\newpage - -\subsection{glp\_ios\_row\_attr --- determine additional row -attributes} - -\synopsis - -\begin{verbatim} - void glp_ios_row_attr(glp_tree *T, int i, glp_attr *attr); -\end{verbatim} - -\description - -The routine \verb|glp_ios_row_attr| retrieves additional attributes of -$i$-th row of the current subproblem and stores them in the structure -\verb|glp_attr|, which the parameter \verb|attr| points to. - -The structure \verb|glp_attr| has the following fields: - -\medskip - -{\tt int level} - -Subproblem level at which the row was created. (If \verb|level| = 0, -the row was added either to the original problem object passed to the -routine \verb|glp_intopt| or to the root subproblem on generating -``lazy'' or/and cutting plane constraints.) - -\medskip - -{\tt int origin} - -The row origin flag: - -\verb|GLP_RF_REG | --- regular constraint; - -\verb|GLP_RF_LAZY| --- ``lazy'' constraint; - -\verb|GLP_RF_CUT | --- cutting plane constraint. - -\medskip - -{\tt int klass} - -The row class descriptor, which is a number passed to the routine -\verb|glp_ios_add_row| as its third parameter. If the row is a cutting -plane constraint generated by the solver, its class may be the -following: - -\verb|GLP_RF_GMI | --- Gomory's mixed integer cut; - -\verb|GLP_RF_MIR | --- mixed integer rounding cut; - -\verb|GLP_RF_COV | --- mixed cover cut; - -\verb|GLP_RF_CLQ | --- clique cut. - -\subsection{glp\_ios\_mip\_gap --- compute relative MIP gap} - -\synopsis - -\begin{verbatim} - double glp_ios_mip_gap(glp_tree *T); -\end{verbatim} - -\description - -The routine \verb|glp_ios_mip_gap| computes the relative MIP gap (also -called {\it duality gap}) with the following formula: -$${\tt gap} = \frac{|{\tt best\_mip} - {\tt best\_bnd}|} -{|{\tt best\_mip}| + {\tt DBL\_EPSILON}}$$ -where \verb|best_mip| is the best integer feasible solution found so -far, \verb|best_bnd| is the best (global) bound. If no integer feasible -solution has been found yet, \verb|gap| is set to \verb|DBL_MAX|. - -\returns - -The routine \verb|glp_ios_mip_gap| returns the relative MIP gap. - -\para{Comments} - -The relative MIP gap is used to measure the quality of the best integer -feasible solution found so far, because the optimal solution value -$z^*$ for the original MIP problem always lies in the range -$${\tt best\_bnd}\leq z^*\leq{\tt best\_mip}$$ -in case of minimization, or in the range -$${\tt best\_mip}\leq z^*\leq{\tt best\_bnd}$$ -in case of maximization. - -To express the relative MIP gap in percents the value returned by the -routine \verb|glp_ios_mip_gap| should be multiplied by 100\%. - -\subsection{glp\_ios\_node\_data --- access application-specific data} - -\synopsis - -\begin{verbatim} - void *glp_ios_node_data(glp_tree *T, int p); -\end{verbatim} - -\description - -The routine \verb|glp_ios_node_data| allows the application accessing -a memory block allocated for the subproblem (which may be active or -inactive), whose reference number is $p$. - -The size of the block is defined by the control parameter -\verb|cb_size| passed to the routine \verb|glp_intopt|. The block is -initialized by binary zeros on creating corresponding subproblem, and -its contents is kept until the subproblem will be removed from the -tree. - -The application may use these memory blocks to store specific data for -each subproblem. - -\returns - -The routine \verb|glp_ios_node_data| returns a pointer to the memory -block for the specified subproblem. Note that if \verb|cb_size| = 0, -the routine returns a null pointer. - -\subsection{glp\_ios\_select\_node --- select subproblem to continue -the search} - -\synopsis - -\begin{verbatim} - void glp_ios_select_node(glp_tree *T, int p); -\end{verbatim} - -\description - -The routine \verb|glp_ios_select_node| can be called from the -user-defined callback routine in response to the reason -\verb|GLP_ISELECT| to select an active subproblem, whose reference -number\linebreak is $p$. The search will be continued from the -subproblem selected. - -\newpage - -\subsection{glp\_ios\_heur\_sol --- provide solution found by -heuristic} - -\synopsis - -\begin{verbatim} - int glp_ios_heur_sol(glp_tree *T, const double x[]); -\end{verbatim} - -\description - -The routine \verb|glp_ios_heur_sol| can be called from the user-defined -callback routine in response to the reason \verb|GLP_IHEUR| to provide -an integer feasible solution found by a primal heuristic. - -Primal values of {\it all} variables (columns) found by the heuristic -should be placed in locations $x[1]$, \dots, $x[n]$, where $n$ is the -number of columns in the original problem object. Note that the routine -\verb|glp_ios_heur_sol| does {\it not} check primal feasibility of the -solution provided. - -Using the solution passed in the array $x$ the routine computes value -of the objective function. If the objective value is better than the -best known integer feasible solution, the routine computes values of -auxiliary variables (rows) and stores all solution components in the -problem object. - -\returns - -If the provided solution is accepted, the routine -\verb|glp_ios_heur_sol| returns zero. Otherwise, if the provided -solution is rejected, the routine returns non-zero. - -\vspace*{-5pt} - -\subsection{glp\_ios\_can\_branch --- check if can branch upon -specified variable} - -\synopsis - -\begin{verbatim} - int glp_ios_can_branch(glp_tree *T, int j); -\end{verbatim} - -\returns - -If $j$-th variable (column) can be used to branch upon, the routine -returns non-zero, otherwise zero. - -\vspace*{-5pt} - -\subsection{glp\_ios\_branch\_upon --- choose variable to branch upon} - -\synopsis - -\begin{verbatim} - void glp_ios_branch_upon(glp_tree *T, int j, int sel); -\end{verbatim} - -\description - -The routine \verb|glp_ios_branch_upon| can be called from the -user-defined callback routine in response to the reason -\verb|GLP_IBRANCH| to choose a branching variable, whose ordinal number -\linebreak is $j$. Should note that only variables, for which the -routine \verb|glp_ios_can_branch| returns non-zero, can be used to -branch upon. - -The parameter \verb|sel| is a flag that indicates which branch -(subproblem) should be selected next to continue the search: - -\verb|GLP_DN_BRNCH| --- select down-branch; - -\verb|GLP_UP_BRNCH| --- select up-branch; - -\verb|GLP_NO_BRNCH| --- use general selection technique. - -\para{Comments} - -On branching the solver removes the current active subproblem from the -active list and creates two new subproblems ({\it down-} and {\it -up-branches}), which are added to the end of the active list. Note that -the down-branch is created before the up-branch, so the last active -subproblem will be the up-branch. - -The down- and up-branches are identical to the current subproblem with -exception that in the down-branch the upper bound of $x_j$, the variable -chosen to branch upon, is replaced by $\lfloor x_j^*\rfloor$, while in -the up-branch the lower bound of $x_j$ is replaced by -$\lceil x_j^*\rceil$, where $x_j^*$ is the value of $x_j$ in optimal -solution to LP relaxation of the current subproblem. For example, if -$x_j^*=3.14$, the new upper bound of $x_j$ in the down-branch is -$\lfloor 3.14\rfloor=3$, and the new lower bound in the up-branch is -$\lceil 3.14\rceil=4$.) - -Additionally the callback routine may select either down- or up-branch, -from which the solver will continue the search. If none of the branches -is selected, a general selection technique will be used. - -\subsection{glp\_ios\_terminate --- terminate the solution process} - -\synopsis - -\begin{verbatim} - void glp_ios_terminate(glp_tree *T); -\end{verbatim} - -\description - -The routine \verb|glp_ios_terminate| sets a flag indicating that the -MIP solver should prematurely terminate the search. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{The search tree exploring routines} - -\subsection{glp\_ios\_tree\_size --- determine size of the search tree} - -\synopsis - -\begin{verbatim} - void glp_ios_tree_size(glp_tree *T, int *a_cnt, int *n_cnt, int *t_cnt); -\end{verbatim} - -\description - -The routine \verb|glp_ios_tree_size| stores the following three counts -which characterize the current size of the search tree: - -\verb|a_cnt| is the current number of active nodes, i.e. the current -size of the active list; - -\verb|n_cnt| is the current number of all (active and inactive) nodes; - -\verb|t_cnt| is the total number of nodes including those which have -been already removed from the tree. This count is increased whenever -a new node appears in the tree and never decreased. - -If some of the parameters \verb|a_cnt|, \verb|n_cnt|, \verb|t_cnt| is -a null pointer, the corresponding count is not stored. - -\subsection{glp\_ios\_curr\_node --- determine current active -subproblem} - -\synopsis - -\begin{verbatim} - int glp_ios_curr_node(glp_tree *T); -\end{verbatim} - -\returns - -The routine \verb|glp_ios_curr_node| returns the reference number of -the current active subproblem. However, if the current subproblem does -not exist, the routine returns zero. - -\subsection{glp\_ios\_next\_node --- determine next active subproblem} - -\synopsis - -\begin{verbatim} - int glp_ios_next_node(glp_tree *T, int p); -\end{verbatim} - -\returns - -If the parameter $p$ is zero, the routine \verb|glp_ios_next_node| -returns the reference number of the first active subproblem. However, -if the tree is empty, zero is returned. - -If the parameter $p$ is not zero, it must specify the reference number -of some active subproblem, in which case the routine returns the -reference number of the next active subproblem. However, if there is -no next active subproblem in the list, zero is returned. - -All subproblems in the active list are ordered chronologically, i.e. -subproblem $A$ precedes subproblem $B$ if $A$ was created before $B$. - -\newpage - -\subsection{glp\_ios\_prev\_node --- determine previous active -subproblem} - -\synopsis - -\begin{verbatim} - int glp_ios_prev_node(glp_tree *T, int p); -\end{verbatim} - -\returns - -If the parameter $p$ is zero, the routine \verb|glp_ios_prev_node| -returns the reference number of the last active subproblem. However, if -the tree is empty, zero is returned. - -If the parameter $p$ is not zero, it must specify the reference number -of some active subproblem, in which case the routine returns the -reference number of the previous active subproblem. However, if there -is no previous active subproblem in the list, zero is returned. - -All subproblems in the active list are ordered chronologically, i.e. -subproblem $A$ precedes subproblem $B$ if $A$ was created before $B$. - -\subsection{glp\_ios\_up\_node --- determine parent subproblem} - -\synopsis - -\begin{verbatim} - int glp_ios_up_node(glp_tree *T, int p); -\end{verbatim} - -\returns - -The parameter $p$ must specify the reference number of some (active or -inactive) subproblem, in which case the routine \verb|iet_get_up_node| -returns the reference number of its parent subproblem. However, if the -specified subproblem is the root of the tree and, therefore, has -no parent, the routine returns zero. - -\subsection{glp\_ios\_node\_level --- determine subproblem level} - -\synopsis - -\begin{verbatim} - int glp_ios_node_level(glp_tree *T, int p); -\end{verbatim} - -\returns - -The routine \verb|glp_ios_node_level| returns the level of the -subproblem, whose reference number is $p$, in the branch-and-bound -tree. (The root subproblem has level 0, and the level of any other -subproblem is the level of its parent plus one.) - -\subsection{glp\_ios\_node\_bound --- determine subproblem local bound} - -\synopsis - -\begin{verbatim} - double glp_ios_node_bound(glp_tree *T, int p); -\end{verbatim} - -\returns - -The routine \verb|glp_ios_node_bound| returns the local bound for -(active or inactive) subproblem, whose reference number is $p$. - -\para{Comments} - -The local bound for subproblem $p$ is an lower (minimization) or upper -(maximization) bound for integer optimal solution to {\it this} -subproblem (not to the original problem). This bound is local in the -sense that only subproblems in the subtree rooted at node $p$ cannot -have better integer feasible solutions. - -On creating a subproblem (due to the branching step) its local bound is -inherited from its parent and then may get only stronger (never weaker). -For the root subproblem its local bound is initially set to -\verb|-DBL_MAX| (minimization) or \verb|+DBL_MAX| (maximization) and -then improved as the root LP relaxation has been solved. - -Note that the local bound is not necessarily the optimal objective -value to corresponding LP relaxation. - -\subsection{glp\_ios\_best\_node --- find active subproblem with best -local bound} - -\synopsis - -\begin{verbatim} - int glp_ios_best_node(glp_tree *T); -\end{verbatim} - -\returns - -The routine \verb|glp_ios_best_node| returns the reference number of -the active subproblem, whose local bound is best (i.e. smallest in case -of minimization or largest in case of maximization). However, if the -tree is empty, the routine returns zero. - -\para{Comments} - -The best local bound is an lower (minimization) or upper (maximization) -bound for integer optimal solution to the original MIP problem. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{The cut pool routines} - -\subsection{glp\_ios\_pool\_size --- determine current size of the cut -pool} - -\synopsis - -\begin{verbatim} - int glp_ios_pool_size(glp_tree *T); -\end{verbatim} - -\returns - -The routine \verb|glp_ios_pool_size| returns the current size of the -cut pool, that is, the number of cutting plane constraints currently -added to it. - -\subsection{glp\_ios\_add\_row --- add constraint to the cut pool} - -\synopsis - -\begin{verbatim} - int glp_ios_add_row(glp_tree *T, const char *name, int klass, int flags, - int len, const int ind[], const double val[], int type, double rhs); -\end{verbatim} - -\description - -The routine \verb|glp_ios_add_row| adds specified row (cutting plane -constraint) to the cut pool. - -The cutting plane constraint should have the following format: -$$\sum_{j\in J}a_jx_j\left\{\begin{array}{@{}c@{}}\geq\\\leq\\ -\end{array}\right\}b,$$ -where $J$ is a set of indices (ordinal numbers) of structural -variables, $a_j$ are constraint coefficients, $x_j$ are structural -variables, $b$ is the right-hand side. - -The parameter \verb|name| specifies a symbolic name assigned to the -constraint (1 up to 255 characters). If it is \verb|NULL| or an empty -string, no name is assigned. - -The parameter \verb|klass| specifies the constraint class, which must -be either zero or a number in the range from 101 to 200. -The application may use this attribute to distinguish between cutting -plane constraints of different classes.\footnote{Constraint classes -numbered from 1 to 100 are reserved for GLPK cutting plane generators.} - -The parameter \verb|flags| currently is not used and must be zero. - -Ordinal numbers of structural variables (i.e. column indices) $j\in J$ -and numerical values of corresponding constraint coefficients $a_j$ -should be placed in locations \verb|ind[1]|, \dots, \verb|ind[len]| and -\verb|val[1]|, \dots, \verb|val[len]|, respectively, where -${\tt len}=|J|$ is the number of constraint coefficients, -$0\leq{\tt len}\leq n$, and $n$ is the number of columns in the problem -object. Coefficients with identical column indices are not allowed. -Zero coefficients are allowed, however, they are ignored. - -The parameter \verb|type| specifies the constraint type as follows: - -\verb|GLP_LO| means inequality constraint $\Sigma a_jx_j\geq b$; - -\verb|GLP_UP| means inequality constraint $\Sigma a_jx_j\leq b$; - -The parameter \verb|rhs| specifies the right-hand side $b$. - -All cutting plane constraints in the cut pool are identified by their -ordinal numbers 1, 2, \dots, $size$, where $size$ is the current size -of the cut pool. New constraints are always added to the end of the cut -pool, thus, ordinal numbers of previously added constraints are not -changed. - -\returns - -The routine \verb|glp_ios_add_row| returns the ordinal number of the -cutting plane constraint added, which is the new size of the cut pool. - -\para{Example} - -\begin{verbatim} -/* generate triangle cutting plane: - x[i] + x[j] + x[k] <= 1 */ -. . . -/* add the constraint to the cut pool */ -ind[1] = i, val[1] = 1.0; -ind[2] = j, val[2] = 1.0; -ind[3] = k, val[3] = 1.0; -glp_ios_add_row(tree, NULL, TRIANGLE_CUT, 0, 3, ind, val, GLP_UP, 1.0); -\end{verbatim} - -\para{Comments} - -Cutting plane constraints added to the cut pool are intended to be then -added only to the {\it current} subproblem, so these constraints can be -globally as well as locally valid. However, adding a constraint to the -cut pool does not mean that it will be added to the current -subproblem---it depends on the solver's decision: if the constraint -seems to be efficient, it is moved from the pool to the current -subproblem, otherwise it is simply dropped.\footnote{Globally valid -constraints could be saved and then re-used for other subproblems, but -currently such feature is not implemented.} - -Normally, every time the callback routine is called for cut generation, -the cut pool is empty. On the other hand, the solver itself can -generate cutting plane constraints (like Gomory's or mixed integer -rounding cuts), in which case the cut pool may be non-empty. - -\subsection{glp\_ios\_del\_row --- remove constraint from the cut pool} - -\synopsis - -\begin{verbatim} - void glp_ios_del_row(glp_tree *T, int i); -\end{verbatim} - -\description - -The routine \verb|glp_ios_del_row| deletes $i$-th row (cutting plane -constraint) from the cut pool, where $1\leq i\leq size$ is the ordinal -number of the constraint in the pool, $size$ is the current size of the -cut pool. - -Note that deleting a constraint from the cut pool leads to changing -ordinal numbers of other constraints remaining in the pool. New ordinal -numbers of the remaining constraints are assigned under assumption that -the original order of constraints is not changed. Let, for example, -there be four constraints $a$, $b$, $c$ and $d$ in the cut pool, which -have ordinal numbers 1, 2, 3 and 4, respectively, and let constraint -$b$ have been deleted. Then after deletion the remaining constraint $a$, -$c$ and $d$ are assigned new ordinal numbers 1, 2 and 3, respectively. - -To find the constraint to be deleted the routine \verb|glp_ios_del_row| -uses ``smart'' linear search, so it is recommended to remove -constraints in a natural or reverse order and avoid removing them in -a random order. - -\para{Example} - -\begin{verbatim} -/* keep first 10 constraints in the cut pool and remove other - constraints */ -while (glp_ios_pool_size(tree) > 10) - glp_ios_del_row(tree, glp_ios_pool_size(tree)); -\end{verbatim} - -\subsection{glp\_ios\_clear\_pool --- remove all constraints from the -cut pool} - -\synopsis - -\begin{verbatim} - void glp_ios_clear_pool(glp_tree *T); -\end{verbatim} - -\description - -The routine \verb|glp_ios_clear_pool| makes the cut pool empty deleting -all existing rows (cutting plane constraints) from it. - -%* eof *% diff --git a/resources/3rdparty/glpk-4.53/doc/glpk06.tex b/resources/3rdparty/glpk-4.53/doc/glpk06.tex deleted file mode 100644 index 71eb8197d..000000000 --- a/resources/3rdparty/glpk-4.53/doc/glpk06.tex +++ /dev/null @@ -1,441 +0,0 @@ -%* glpk06.tex *% - -\chapter{Miscellaneous API Routines} - -\section{GLPK environment routines} - -\subsection{glp\_init\_env --- initialize GLPK environment} - -\synopsis - -\begin{verbatim} - int glp_init_env(void); -\end{verbatim} - -\description - -The routine \verb|glp_init_env| initializes the GLPK environment. -Normally the application program does not need to call this routine, -because it is called automatically on the first call to any API -routine. - -\returns - -\begin{retlist} -0 & initialization successful;\\ -1 & environment is already initialized;\\ -2 & initialization failed (insufficient memory);\\ -3 & initialization failed (unsupported programming model).\\ -\end{retlist} - -\subsection{glp\_version --- determine library version} - -\synopsis - -\begin{verbatim} - const char *glp_version(void); -\end{verbatim} - -\returns - -The routine \verb|glp_version| returns a pointer to a null-terminated -character string, which specifies the version of the GLPK library in -the form \verb|"X.Y"|, where `\verb|X|' is the major version number, -and `\verb|Y|' is the minor version number, for example, \verb|"4.16"|. - -\newpage - -\subsection{glp\_free\_env --- free GLPK environment} - -\synopsis - -\begin{verbatim} - int glp_free_env(void); -\end{verbatim} - -\description - -The routine \verb|glp_free_env| frees all resources used by GLPK -routines (memory blocks, etc.) which are currently still in use. - -Normally the application program does not need to call this routine, -because GLPK routines always free all unused resources. However, if -the application program even has deleted all problem objects, there -will be several memory blocks still allocated for the internal library -needs. For some reasons the application program may want GLPK to free -this memory, in which case it should call \verb|glp_free_env|. - -Note that a call to \verb|glp_free_env| invalidates all problem objects -which still exist. - -\returns - -\begin{retlist} -0 & termination successful;\\ -1 & environment is inactive (was not initialized).\\ -\end{retlist} - -\subsection{glp\_printf --- write formatted output to terminal} - -\synopsis - -\begin{verbatim} - void glp_printf(const char *fmt, ...); -\end{verbatim} - -\description - -The routine \verb|glp_printf| uses the format control string -\verb|fmt| to format its parameters and writes the formatted output to -the terminal. - -This routine is a replacement of the standard C function -\verb|printf| and used by all GLPK routines to perform terminal -output. The application program may use \verb|glp_printf| for the same -purpose that allows controlling its terminal output with the routines -\verb|glp_term_out| and \verb|glp_term_hook|. - -\subsection{glp\_vprintf --- write formatted output to terminal} - -\synopsis - -\begin{verbatim} - void glp_vprintf(const char *fmt, va_list arg); -\end{verbatim} - -\description - -The routine \verb|glp_vprintf| uses the format control string -\verb|fmt| to format its parameters specified by the list \verb|arg| -and writes the formatted output to the terminal. - -This routine is a replacement of the standard C function -\verb|vprintf| and used by all GLPK routines to perform terminal -output. The application program may use \verb|glp_vprintf| for the same -purpose that allows controlling its terminal output with the routines -\verb|glp_term_out| and \verb|glp_term_hook|. - -\newpage - -\subsection{glp\_term\_out --- enable/disable terminal output} - -\synopsis - -\begin{verbatim} - int glp_term_out(int flag); -\end{verbatim} - -\description - -Depending on the parameter flag the routine \verb|glp_term_out| enables -or disables terminal output performed by glpk routines: - -\verb|GLP_ON | --- enable terminal output; - -\verb|GLP_OFF| --- disable terminal output. - -\returns - -The routine \verb|glp_term_out| returns the previous value of the -terminal output flag. - -\subsection{glp\_term\_hook --- intercept terminal output} - -\synopsis - -\begin{verbatim} - void glp_term_hook(int (*func)(void *info, const char *s), void *info); -\end{verbatim} - -\description - -The routine \verb|glp_term_hook| installs the user-defined hook routine -to intercept all terminal output performed by GLPK routines. - -%This feature can be used to redirect the terminal output to other -%destination, for example, to a file or a text window. - -The parameter {\it func} specifies the user-defined hook routine. It is -called from an internal printing routine, which passes to it two -parameters: {\it info} and {\it s}. The parameter {\it info} is a -transit pointer specified in corresponding call to the routine -\verb|glp_term_hook|; it may be used to pass some additional information -to the hook routine. The parameter {\it s} is a pointer to the null -terminated character string, which is intended to be written to the -terminal. If the hook routine returns zero, the printing routine writes -the string {\it s} to the terminal in a usual way; otherwise, if the -hook routine returns non-zero, no terminal output is performed. - -To uninstall the hook routine both parameters {\it func} and {\it info} -should be specified as \verb|NULL|. - -\para{Example} - -\begin{footnotesize} -\begin{verbatim} -static int hook(void *info, const char *s) -{ FILE *foo = info; - fputs(s, foo); - return 1; -} - -int main(void) -{ FILE *foo; - . . . - glp_term_hook(hook, foo); /* redirect terminal output */ - . . . - glp_term_hook(NULL, NULL); /* resume terminal output */ - . . . -} -\end{verbatim} -\end{footnotesize} - -\newpage - -\subsection{glp\_open\_tee --- start copying terminal output} - -\synopsis - -\begin{verbatim} - int glp_open_tee(const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_open_tee| starts copying all the terminal output -to an output text file, whose name is specified by the character string -\verb|fname|. - -\returns - -\begin{retlist} -0 & operation successful;\\ -1 & copying terminal output is already active;\\ -2 & unable to create output file.\\ -\end{retlist} - -\subsection{glp\_close\_tee --- stop copying terminal output} - -\synopsis - -\begin{verbatim} - int glp_close_tee(void); -\end{verbatim} - -\description - -The routine \verb|glp_close_tee| stops copying the terminal output to -the output text file previously open by the routine \verb|glp_open_tee| -closing that file. - -\returns - -\begin{retlist} -0 & operation successful;\\ -1 & copying terminal output was not started.\\ -\end{retlist} - -\subsection{glp\_error --- display error message and terminate -execution} - -\synopsis - -\begin{verbatim} - void glp_error(const char *fmt, ...); -\end{verbatim} - -\description - -The routine \verb|glp_error| (implemented as a macro) formats its -parameters using the format control string \verb|fmt|, writes the -formatted message to the terminal, and then abnormally terminates the -program. - -\newpage - -\subsection{glp\_assert --- check logical condition} - -\synopsis - -\begin{verbatim} - void glp_assert(int expr); -\end{verbatim} - -\description - -The routine \verb|glp_assert| (implemented as a macro) checks -a logical condition specified by the expression \verb|expr|. If the -condition is true (non-zero), the routine does nothing; otherwise, if -the condition is false (zero), the routine prints an error message and -abnormally terminates the program. - -This routine is a replacement of the standard C function \verb|assert| -and used by all GLPK routines to check program logic. The application -program may use \verb|glp_assert| for the same purpose. - -\subsection{glp\_error\_hook --- install hook to intercept abnormal -termination} - -\synopsis - -\begin{verbatim} - void glp_error_hook(void (*func)(void *info), void *info); -\end{verbatim} - -\description - -The routine \verb|glp_error_hook| installs a user-defined hook routine -to intercept abnormal termination. - -The parameter \verb|func| specifies the user-defined hook routine. It -is called from the routine \verb|glp_error| before the latter calls the -abort function to abnormally terminate the application program because -of fatal error. The parameter \verb|info| is a transit pointer, -specified in the corresponding call to the routine -\verb|glp_error_hook|; it may be used to pass some information to the -hook routine. - -To uninstall the hook routine the parameters \verb|func| and \verb|info| -should be specified as \verb|NULL|. - -If the hook routine returns, the application program is abnormally -terminated. To prevent abnormal termnation the hook routine may perform -a global jump using the standard function \verb|longjmp|, in which case -the application program {\it must} call the routine \verb|glp_free_env|. - -\subsection{glp\_malloc --- allocate memory block} - -\synopsis - -\begin{verbatim} - void *glp_malloc(int size); -\end{verbatim} - -\description - -The routine \verb|glp_malloc| dynamically allocates a memory block of -\verb|size| bytes long. Note that: - -1) the parameter \verb|size| must be positive; - -2) being allocated the memory block contains arbitrary data, that is, -it is {\it not} initialized by binary zeros; - -3) if the block cannot be allocated due to insufficient memory, the -routine prints an error message and abnormally terminates the program. - -This routine is a replacement of the standard C function \verb|malloc| -and used by all GLPK routines for dynamic memory allocation. The -application program may use \verb|glp_malloc| for the same purpose. - -\returns - -The routine \verb|glp_malloc| returns a pointer to the memory block -allocated. To free this block the routine \verb|glp_free| (not the -standard C function \verb|free|!) must be used. - -\subsection{glp\_calloc --- allocate memory block} - -\synopsis - -\begin{verbatim} - void *glp_calloc(int n, int size); -\end{verbatim} - -\description - -The routine \verb|glp_calloc| dynamically allocates a memory block of -\verb|n|$\times$\verb|size| bytes long. Note that: - -1) both parameters \verb|n| and \verb|size| must be positive; - -2) being allocated the memory block contains arbitrary data, that is, -it is {\it not} initialized by binary zeros; - -3) if the block cannot be allocated due to insufficient memory, the -routine prints an error message and abnormally terminates the program. - -This routine is a replacement of the standard C function \verb|calloc| -(with exception that the block is not cleaned) and used by all GLPK -routines for dynamic memory allocation. The application program may use -\verb|glp_calloc| for the same purpose. - -\returns - -The routine \verb|glp_calloc| returns a pointer to the memory block -allocated. To free this block the routine \verb|glp_free| (not the -standard C function \verb|free|!) must be used. - -\subsection{glp\_free --- free memory block} - -\synopsis - -\begin{verbatim} - void glp_free(void *ptr); -\end{verbatim} - -\description - -The routine \verb|glp_free| deallocates a memory block pointed to by -\verb|ptr|, which was previously allocated by the routine -\verb|glp_malloc| or \verb|glp_calloc|. Note that the pointer -\verb|ptr| must be valid and must not be \verb|NULL|. - -This routine is a replacement of the standard C function \verb|free| -and used by all GLPK routines for dynamic memory allocation. The -application program may use \verb|glp_free| for the same purpose. - -\newpage - -\subsection{glp\_mem\_usage --- get memory usage information} - -\synopsis - -\begin{verbatim} - void glp_mem_usage(int *count, int *cpeak, size_t *total, size_t *tpeak); -\end{verbatim} - -\description - -The routine \verb|glp_mem_usage| reports some information about -utilization of the memory by the routines \verb|glp_malloc|, -\verb|glp_calloc|, and \verb|glp_free|. Information is stored to -locations specified by corresponding parameters (see below). Any -parameter can be specified as \verb|NULL|, in which case corresponding -information is not stored. - -\verb|*count| is the number of currently allocated memory blocks. - -\verb|*cpeak| is the peak value of \verb|*count| reached since the -initialization of the GLPK library environment. - -\verb|*total| is the total amount, in bytes, of currently allocated -memory blocks. - -\verb|*tpeak| is the peak value of \verb|*total| reached since the -initialization of the GLPK library envirionment. - -\para{Example} - -\begin{footnotesize} -\begin{verbatim} -glp_mem_usage(&count, NULL, NULL, NULL); -printf("%d memory block(s) are still allocated\n", count); -\end{verbatim} -\end{footnotesize} - -\subsection{glp\_mem\_limit --- set memory usage limit} - -\synopsis - -\begin{verbatim} - void glp_mem_limit(int limit); -\end{verbatim} - -\description - -The routine \verb|glp_mem_limit| limits the amount of memory available -for dynamic allocation (with the routines \verb|glp_malloc| and -\verb|glp_calloc|) to \verb|limit| megabytes. - -%* eof *% diff --git a/resources/3rdparty/glpk-4.53/doc/glpk07.tex b/resources/3rdparty/glpk-4.53/doc/glpk07.tex deleted file mode 100644 index 004fe2ec8..000000000 --- a/resources/3rdparty/glpk-4.53/doc/glpk07.tex +++ /dev/null @@ -1,258 +0,0 @@ -%* glpk07.tex *% - -\chapter{Installing GLPK on Your Computer} -\label{install} - -\section{Downloading the distribution tarball} - -The distribution tarball of the most recent version of the GLPK -package can be found on \url{http://ftp.gnu.org/gnu/glpk/} [via http] -and \url{ftp://ftp.gnu.org/gnu/glpk/} [via FTP]. It can also be found -on one of the FTP mirrors; see \url{http://www.gnu.org/prep/ftp.html}. -Please use a mirror if possible. - -To make sure that the GLPK distribution tarball you have downloaded is -intact you need to download the corresponding `\verb|.sig|' file and -run a command like this: - -\begin{verbatim} - gpg --verify glpk-4.38.tar.gz.sig -\end{verbatim} - -\noindent -If that command fails because you do not have the required public key, -run the following command to import it: - -\begin{verbatim} - gpg --keyserver keys.gnupg.net --recv-keys 5981E818 -\end{verbatim} - -\noindent -and then re-run the previous command. - -\section{Unpacking the distribution tarball} - -The GLPK package (like all other GNU software) is distributed in the -form of packed archive. This is one file named \verb|glpk-X.Y.tar.gz|, -where {\it X} is the major version number and {\it Y} is the minor -version number. - -In order to prepare the distribution for installation you need to copy -the GLPK distribution file to a working subdirectory and then unpack -and unarchive the distribution file with the following command: - -\begin{verbatim} - tar zx < glpk-X.Y.tar -\end{verbatim} - -\newpage - -\section{Configuring the package} - -After unpacking and unarchiving the GLPK distribution you should -configure the package,\linebreak i.e. automatically tune it for your -platform. - -Normally, you should just \verb|cd| to the subdirectory \verb|glpk-X.Y| -and run the configure script, e.g. - -\begin{verbatim} - ./configure -\end{verbatim} - -The `\verb|configure|' shell script attempts to guess correct values -for various system-dependent variables used during compilation. It uses -those values to create a `\verb|Makefile|' in each directory of the -package. It also creates file `\verb|config.h|' containing -platform-dependent definitions. Finally, it creates a shell script -`\verb|config.status|' that you can run in the future to recreate the -current configuration, a file `\verb|config.cache|' that saves the -results of its tests to speed up reconfiguring, and a file -`\verb|config.log|' containing compiler output (useful mainly for -debugging `\verb|configure|'). - -Running `\verb|configure|' takes about a minute. While it is running, -it displays some informational messages that tell you what it -is doing. If you don't want to see these messages, run -`\verb|configure|' with its standard output redirected to -`\verb|dev/null|'; for example, `\verb|./configure > /dev/null|'. - -By default both static and shared versions of the GLPK library will be -compiled. Compilation of the shared librariy can be turned off by -specifying the `\verb|--disable-shared|' option to `\verb|configure|': - -\begin{verbatim} - ./configure --disable-shared -\end{verbatim} - -\noindent -If you encounter problems building the library try using the above -option, because some platforms do not support shared libraries. - -The GLPK package has some optional features listed below. By default -all these features are disabled. To enable a feature the corresponding -option should be passed to the configure script. - -\verb|--with-gmp | Enable using the GNU MP bignum library - -This feature allows the exact simplex solver to use the GNU MP bignum -library. If it is disabled, the exact simplex solver uses the GLPK -bignum module, which provides the same functionality as GNU MP, however, -it is much less efficient. - -For details about the GNU MP bignum library see its web page at -\url{http://gmplib.org/}. - -\verb|--enable-dl | The same as `\verb|--enable-dl=ltdl|' - -\verb|--enable-dl=ltdl | Enable shared library support (GNU) - -\verb|--enable-dl=dlfcn | Enable shared library support (POSIX) - -Currently this feature is only needed to provide dynamic linking to -ODBC and MySQL shared libraries (see below). - -For details about the GNU shared library support see the manual at -\url{http://www.gnu.org/software/libtool/manual/}. - -\verb|--enable-odbc | -Enable using ODBC table driver (\verb|libiodbc|) - -\verb|--enable-odbc=unix | -Enable using ODBC table driver (\verb|libodbc|) - -This feature allows transmitting data between MathProg model objects -and relational databases accessed through ODBC. - -For more details about this feature see the supplement ``Using Data -Tables in the GNU MathProg Modeling Language'' (\verb|doc/tables.pdf|). - -\verb|--enable-mysql | -Enable using MySQL table driver (\verb|libmysql|) - -This feature allows transmitting data between MathProg model objects -and MySQL relational databases. - -For more details about this feature see the supplement ``Using Data -Tables in the GNU MathProg Modeling Language'' (\verb|doc/tables.pdf|). - -\section{Compiling the package} - -Normally, you can compile (build) the package by typing the command: - -\begin{verbatim} - make -\end{verbatim} - -\noindent -It reads `\verb|Makefile|' generated by `\verb|configure|' and performs -all necessary jobs. - -If you want, you can override the `\verb|make|' variables \verb|CFLAGS| -and \verb|LDFLAGS| like this: - -\begin{verbatim} - make CFLAGS=-O2 LDFLAGS=-s -\end{verbatim} - -To compile the package in a different directory from the one containing -the source code, you must use a version of `\verb|make|' that supports -`\verb|VPATH|' variable, such as GNU `\verb|make|'. `\verb|cd|' to the -directory where you want the object files and executables to go and run -the `\verb|configure|' script. `\verb|configure|' automatically checks -for the source code in the directory that `\verb|configure|' is in and -in `\verb|..|'. If for some reason `\verb|configure|' is not in the -source code directory that you are configuring, then it will report -that it can't find the source code. In that case, run `\verb|configure|' -with the option `\verb|--srcdir=DIR|', where \verb|DIR| is the -directory that contains the source code. - -Some systems require unusual options for compilation or linking that -the `\verb|configure|' script does not know about. You can give -`\verb|configure|' initial values for variables by setting them in the -environment. Using a Bourne-compatible shell, you can do that on the -command line like this: - -\begin{verbatim} - CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure -\end{verbatim} - -\noindent -Or on systems that have the `\verb|env|' program, you can do it like -this: - -\begin{verbatim} - env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure -\end{verbatim} - -Here are the `\verb|make|' variables that you might want to override -with environment variables when running `\verb|configure|'. - -For these variables, any value given in the environment overrides the -value that `\verb|configure|' would choose: - -\verb|CC | C compiler program. The default is `\verb|cc|'. - -\verb|INSTALL | Program used to install files. The default value is -`\verb|install|' if you have it,\\ -\verb| | otherwise `\verb|cp|'. - -For these variables, any value given in the environment is added to the -value that `\verb|configure|' chooses: - -\verb|DEFS | Configuration options, in the form -`\verb|-Dfoo -Dbar| \dots'. - -\verb|LIBS | Libraries to link with, in the form -`\verb|-lfoo -lbar| \dots'. - -\section{Checking the package} - -To check the package, i.e. to run some tests included in the package, -you can use the following command: - -\begin{verbatim} - make check -\end{verbatim} - -\section{Installing the package} - -Normally, to install the GLPK package you should type the following -command: - -\begin{verbatim} - make install -\end{verbatim} - -\noindent -By default, `\verb|make install|' will install the package's files in -`\verb|usr/local/bin|', `\verb|usr/local/lib|', etc. You can specify an -installation prefix other than `\verb|/usr/local|' by giving -`\verb|configure|' the option `\verb|--prefix=PATH|'. Alternately, you -can do so by consistently giving a value for the `\verb|prefix|' -variable when you run `\verb|make|', e.g. - -\begin{verbatim} - make prefix=/usr/gnu - make prefix=/usr/gnu install -\end{verbatim} - -After installing you can remove the program binaries and object files -from the source directory by typing `\verb|make clean|'. To remove all -files that `\verb|configure|' created (`\verb|Makefile|', -`\verb|config.status|', etc.), just type `\verb|make distclean|'. - -The file `\verb|configure.ac|' is used to create `\verb|configure|' by -a program called `\verb|autoconf|'. You only need it if you want to -remake `\verb|configure|' using a newer version of `\verb|autoconf|'. - -\section{Uninstalling the package} - -To uninstall the GLPK package, i.e. to remove all the package's files -from the system places, you can use the following command: - -\begin{verbatim} - make uninstall -\end{verbatim} - -%* eof *% diff --git a/resources/3rdparty/glpk-4.53/doc/glpk08.tex b/resources/3rdparty/glpk-4.53/doc/glpk08.tex deleted file mode 100644 index e56a8e892..000000000 --- a/resources/3rdparty/glpk-4.53/doc/glpk08.tex +++ /dev/null @@ -1,738 +0,0 @@ -%* glpk08.tex *% - -\chapter{MPS Format} -\label{champs} - -\section{Fixed MPS Format} -\label{secmps} - -The MPS format\footnote{The MPS format was developed in 1960's by IBM -as input format for their mathematical programming system MPS/360. -Today the MPS format is a most widely used format understood by most -mathematical programming packages. This appendix describes only the -features of the MPS format, which are implemented in the GLPK package.} -is intended for coding LP/MIP problem data. This format assumes the -formulation of LP/MIP problem (1.1)---(1.3) (see Section \ref{seclp}, -page \pageref{seclp}). - -{\it MPS file} is a text file, which contains two types of -cards\footnote{In 1960's MPS file was a deck of 80-column punched -cards, so the author decided to keep the word ``card'', which may be -understood as ``line of text file''.}: indicator cards and data cards. - -Indicator cards determine a kind of succeeding data. Each indicator -card has one word in uppercase letters beginning in column 1. - -Data cards contain problem data. Each data card is divided into six -fixed fields: - -\begin{center} -\begin{tabular}{lcccccc} -& Field 1 & Field 2 & Field 3 & Field 4 & Field 5 & Feld 6 \\ -\hline -Columns & 2---3 & 5---12 & 15---22 & 25---36 & 40---47 & 50---61 \\ -Contents & Code & Name & Name & Number & Name & Number \\ -\end{tabular} -\end{center} - -On a particular data card some fields may be optional. - -Names are used to identify rows, columns, and some vectors (see below). - -Aligning the indicator code in the field 1 to the left margin is -optional. - -All names specified in the fields 2, 3, and 5 should contain from 1 up -to 8 arbitrary characters (except control characters). If a name is -placed in the field 3 or 5, its first character should not be the dollar -sign `\verb|$|'. If a name contains spaces, the spaces are ignored. - -All numerical values in the fields 4 and 6 should be coded in the form -$sxx$\verb|E|$syy$, where $s$ is the plus `\verb|+|' or the minus -`\verb|-|' sign, $xx$ is a real number with optional decimal point, -$yy$ is an integer decimal exponent. Any number should contain up to 12 -characters. If the sign $s$ is omitted, the plus sign is assumed. The -exponent part is optional. If a number contains spaces, the spaces are -ignored. - -\newpage - -If a card has the asterisk `\verb|*|' in the column 1, this card is -considered as a comment and ignored. Besides, if the first character in -the field 3 or 5 is the dollar sign `\verb|$|', all characters from the -dollar sign to the end of card are considered as a comment and ignored. - -MPS file should contain cards in the following order: - -\vspace*{-8pt} - -\begin{itemize} -\item NAME indicator card; - -\item ROWS indicator card; - -\item data cards specifying rows (constraints); - -\item COLUMNS indicator card; - -\item data cards specifying columns (structural variables) and -constraint coefficients; - -\item RHS indicator card; - -\item data cards specifying right-hand sides of constraints; - -\item RANGES indicator card; - -\item data cards specifying ranges for double-bounded constraints; - -\item BOUNDS indicator card; - -\item data cards specifying types and bounds of structural -variables; - -\item ENDATA indicator card. -\end{itemize} - -\vspace*{-8pt} - -{\it Section} is a group of cards consisting of an indicator card and -data cards succeeding this indicator card. For example, the ROWS section -consists of the ROWS indicator card and data cards specifying rows. - -The sections RHS, RANGES, and BOUNDS are optional and may be omitted. - -\section{Free MPS Format} - -{\it Free MPS format} is an improved version of the standard (fixed) -MPS format described above.\footnote{This format was developed in the -beginning of 1990's by IBM as an alternative to the standard fixed MPS -format for Optimization Subroutine Library (OSL).} Note that all -changes in free MPS format concern only the coding of data while the -structure of data is the same for both fixed and free versions of the -MPS format. - -In free MPS format indicator and data records\footnote{{\it Record} in -free MPS format has the same meaning as {\it card} in fixed MPS format.} -may have arbitrary length not limited to 80 characters. Fields of data -records have no predefined positions, i.e. the fields may begin in any -position, except position 1, which must be blank, and must be separated -from each other by one or more blanks. However, the fields must appear -in the same order as in fixed MPS format. - -\newpage - -Symbolic names in fields 2, 3, and 5 may be longer than 8 -characters\footnote{GLPK allows symbolic names having up to 255 -characters.} and must not contain embedded blanks. - -Numeric values in fields 4 and 6 are limited to 12 characters and must -not contain embedded blanks. - -Only six fields on each data record are used. Any other fields are -ignored. - -If the first character of any field (not necessarily fields 3 and 5) -is the dollar sign (\$), all characters from the dollar sign to the end -of record are considered as a comment and ignored. - -\section{NAME indicator card} - -The NAME indicator card should be the first card in the MPS file -(except optional comment cards, which may precede the NAME card). This -card should contain the word \verb|NAME| in the columns 1---4 and the -problem name in the field 3. The problem name is optional and may be -omitted. - -\section{ROWS section} -\label{secrows} - -The ROWS section should start with the indicator card, which contains -the word \verb|ROWS| in the columns 1---4. - -Each data card in the ROWS section specifies one row (constraint) of -the problem. All these data cards have the following format. - -`\verb|N|' in the field 1 means that the row is free (unbounded): -$$-\infty < x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n} -< +\infty;$$ - -`\verb|L|' in the field 1 means that the row is of ``less than or equal -to'' type: -$$-\infty < x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n} -\leq b_i;$$ - -`\verb|G|' in the field 1 means that the row is of ``greater than or -equal to'' type: -$$b_i \leq x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n} -< +\infty;$$ - -`\verb|E|' in the field 1 means that the row is of ``equal to'' type: -$$x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n} \leq -b_i,$$ -where $b_i$ is a right-hand side. Note that each constraint has a -corresponding implictly defined auxiliary variable ($x_i$ above), whose -value is a value of the corresponding linear form, therefore row bounds -can be considered as bounds of such auxiliary variable. - -The filed 2 specifies a row name (which is considered as the name of -the corresponding auxiliary variable). - -\newpage - -The fields 3, 4, 5, and 6 are not used and should be empty. - -Numerical values of all non-zero right-hand sides $b_i$ should be -specified in the RHS section (see below). All double-bounded (ranged) -constraints should be specified in the RANGES section (see below). - -\section{COLUMNS section} - -The COLUMNS section should start with the indicator card, which -contains the word \verb|COLUMNS| in the columns 1---7. - -Each data card in the COLUMNS section specifies one or two constraint -coefficients $a_{ij}$ and also introduces names of columns, i.e. names -of structural variables. All these data cards have the following -format. - -The field 1 is not used and should be empty. - -The field 2 specifies a column name. If this field is empty, the column -name from the immediately preceeding data card is assumed. - -The field 3 specifies a row name defined in the ROWS section. - -The field 4 specifies a numerical value of the constraint coefficient -$a_{ij}$, which is placed in the corresponding row and column. - -The fields 5 and 6 are optional. If they are used, they should contain -a second pair ``row name---constraint coefficient'' for the same column. - -Elements of the constraint matrix (i.e. constraint coefficients) should -be enumerated in the column wise manner: all elements for the current -column should be specified before elements for the next column. However, -the order of rows in the COLUMNS section may differ from the order of -rows in the ROWS section. - -Constraint coefficients not specified in the COLUMNS section are -considered as zeros. Therefore zero coefficients may be omitted, -although it is allowed to explicitly specify them. - -\section{RHS section} - -The RHS section should start with the indicator card, which contains the -word \verb|RHS| in the columns 1---3. - -Each data card in the RHS section specifies one or two right-hand sides -$b_i$ (see Section \ref{secrows}, page \pageref{secrows}). All these -data cards have the following format. - -The field 1 is not used and should be empty. - -The field 2 specifies a name of the right-hand side (RHS) -vector\footnote{This feature allows the user to specify several RHS -vectors in the same MPS file. However, before solving the problem a -particular RHS vector should be chosen.}. If this field is empty, the -RHS vector name from the immediately preceeding data card is assumed. - -\newpage - -The field 3 specifies a row name defined in the ROWS section. - -The field 4 specifies a right-hand side $b_i$ for the row, whose name is -specified in the field 3. Depending on the row type $b_i$ is a lower -bound (for the row of \verb|G| type), an upper bound (for the row of -\verb|L| type), or a fixed value (for the row of \verb|E| -type).\footnote{If the row is of {\tt N} type, $b_i$ is considered as -a constant term of the corresponding linear form. Should note, however, -this convention is non-standard.} - -The fields 5 and 6 are optional. If they are used, they should contain -a second pair ``row name---right-hand side'' for the same RHS vector. - -All right-hand sides for the current RHS vector should be specified -before right-hand sides for the next RHS vector. However, the order of -rows in the RHS section may differ from the order of rows in the ROWS -section. - -Right-hand sides not specified in the RHS section are considered as -zeros. Therefore zero right-hand sides may be omitted, although it is -allowed to explicitly specify them. - -\section{RANGES section} - -The RANGES section should start with the indicator card, which contains -the word \verb|RANGES| in the columns 1---6. - -Each data card in the RANGES section specifies one or two ranges for -double-side constraints, i.e. for constraints that are of the types -\verb|L| and \verb|G| at the same time: -$$l_i \leq x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n} -\leq u_i,$$ -where $l_i$ is a lower bound, $u_i$ is an upper bound. All these data -cards have the following format. - -The field 1 is not used and should be empty. - -The field 2 specifies a name of the range vector\footnote{This feature -allows the user to specify several range vectors in the same MPS file. -However, before solving the problem a particular range vector should be -chosen.}. If this field is empty, the range vector name from the -immediately preceeding data card is assumed. - -The field 3 specifies a row name defined in the ROWS section. - -The field 4 specifies a range value $r_i$ (see the table below) for the -row, whose name is specified in the field 3. - -The fields 5 and 6 are optional. If they are used, they should contain -a second pair ``row name---range value'' for the same range vector. - -All range values for the current range vector should be specified before -range values for the next range vector. However, the order of rows in -the RANGES section may differ from the order of rows in the ROWS -section. - -For each double-side constraint specified in the RANGES section its -lower and upper bounds are determined as follows: - -\newpage - -\begin{center} -\begin{tabular}{cccc} -Row type & Sign of $r_i$ & Lower bound & Upper bound \\ -\hline -{\tt G} & $+$ or $-$ & $b_i$ & $b_i + |r_i|$ \\ -{\tt L} & $+$ or $-$ & $b_i - |r_i|$ & $b_i$ \\ -{\tt E} & $+$ & $b_i$ & $b_i + |r_i|$ \\ -{\tt E} & $-$ & $b_i - |r_i|$ & $b_i$ \\ -\end{tabular} -\end{center} - -\noindent -where $b_i$ is a right-hand side specified in the RHS section (if $b_i$ -is not specified, it is considered as zero), $r_i$ is a range value -specified in the RANGES section. - -\section{BOUNDS section} -\label{secbounds} - -The BOUNDS section should start with the indicator card, which contains -the word \verb|BOUNDS| in the columns 1---6. - -Each data card in the BOUNDS section specifies one (lower or upper) -bound for one structural variable (column). All these data cards have -the following format. - -The indicator in the field 1 specifies the bound type: - -\verb|LO| --- lower bound; - -\verb|UP| --- upper bound; - -\verb|FX| --- fixed variable (lower and upper bounds are equal); - -\verb|FR| --- free variable (no bounds); - -\verb|MI| --- no lower bound (lower bound is ``minus infinity''); - -\verb|PL| --- no upper bound (upper bound is ``plus infinity''). - -The field 2 specifies a name of the bound vector\footnote{This feature -allows the user to specify several bound vectors in the same MPS file. -However, before solving the problem a particular bound vector should be -chosen.}. If this field is empty, the bound vector name from the -immediately preceeding data card is assumed. - -The field 3 specifies a column name defined in the COLUMNS section. - -The field 4 specifies a bound value. If the bound type in the field 1 -differs from \verb|LO|, \verb|UP|, and \verb|FX|, the value in the field -4 is ignored and may be omitted. - -The fields 5 and 6 are not used and should be empty. - -All bound values for the current bound vector should be specified before -bound values for the next bound vector. However, the order of columns in -the BOUNDS section may differ from the order of columns in the COLUMNS -section. Specification of a lower bound should precede specification of -an upper bound for the same column (if both the lower and upper bounds -are explicitly specified). - -By default, all columns (structural variables) are non-negative, i.e. -have zero lower bound and no upper bound. Lower ($l_j$) and upper -($u_j$) bounds of some column (structural variable $x_j$) are set in the -following way, where $s_j$ is a corresponding bound value explicitly -specified in the BOUNDS section: - -\newpage - -\verb|LO| sets $l_j$ to $s_j$; - -\verb|UP| sets $u_j$ to $s_j$; - -\verb|FX| sets both $l_j$ and $u_j$ to $s_j$; - -\verb|FR| sets $l_j$ to $-\infty$ and $u_j$ to $+\infty$; - -\verb|MI| sets $l_j$ to $-\infty$; - -\verb|PL| sets $u_j$ to $+\infty$. - -\section{ENDATA indicator card} - -The ENDATA indicator card should be the last card of MPS file (except -optional comment cards, which may follow the ENDATA card). This card -should contain the word \verb|ENDATA| in the columns 1---6. - -\section{Specifying objective function} - -It is impossible to explicitly specify the objective function and -optimization direction in the MPS file. However, the following implicit -rule is used by default: the first row of \verb|N| type is considered -as a row of the objective function (i.e. the objective function is the -corresponding auxiliary variable), which should be {\it minimized}. - -GLPK also allows specifying a constant term of the objective function -as a right-hand side of the corresponding row in the RHS section. - -\section{Example of MPS file} -\label{secmpsex} - -To illustrate what the MPS format is, consider the following example of -LP problem: - -\def\arraystretch{1.2} - -\noindent\hspace{.5in}minimize -$$ -value = .03\ bin_1 + .08\ bin_2 + .17\ bin_3 + .12\ bin_4 + .15\ bin_5 -+ .21\ al + .38\ si -$$ -\noindent\hspace{.5in}subject to linear constraints -$$ -\begin{array}{@{}l@{\:}l@{}} -yield &= \ \ \ \ \;bin_1 + \ \ \ \ \;bin_2 + \ \ \ \ \;bin_3 + - \ \ \ \ \;bin_4 + \ \ \ \ \;bin_5 + \ \ \ \ \;al + - \ \ \ \ \;si \\ -FE &= .15\ bin_1 + .04\ bin_2 + .02\ bin_3 + .04\ bin_4 + .02\ bin_5 - + .01\ al + .03\ si \\ -CU &= .03\ bin_1 + .05\ bin_2 + .08\ bin_3 + .02\ bin_4 + .06\ bin_5 - + .01\ al \\ -MN &= .02\ bin_1 + .04\ bin_2 + .01\ bin_3 + .02\ bin_4 + .02\ bin_5 - \\ -MG &= .02\ bin_1 + .03\ bin_2 -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ + .01\ bin_5 \\ -AL &= .70\ bin_1 + .75\ bin_2 + .80\ bin_3 + .75\ bin_4 + .80\ bin_5 - + .97\ al \\ -SI &= .02\ bin_1 + .06\ bin_2 + .08\ bin_3 + .12\ bin_4 + .02\ bin_5 - + .01\ al + .97\ si \\ -\end{array} -$$ - -\newpage - -\noindent\hspace{.5in}and bounds of (auxiliary and structural) -variables -$$ -\begin{array}{r@{\ }l@{\ }l@{\ }l@{\ }rcr@{\ }l@{\ }l@{\ }l@{\ }r} -&&yield&=&2000&&0&\leq&bin_1&\leq&200\\ --\infty&<&FE&\leq&60&&0&\leq&bin_2&\leq&2500\\ --\infty&<&CU&\leq&100&&400&\leq&bin_3&\leq&800\\ --\infty&<&MN&\leq&40&&100&\leq&bin_4&\leq&700\\ --\infty&<&MG&\leq&30&&0&\leq&bin_5&\leq&1500\\ -1500&\leq&AL&<&+\infty&&0&\leq&al&<&+\infty\\ -250&\leq&SI&\leq&300&&0&\leq&si&<&+\infty\\ -\end{array} -$$ - -\def\arraystretch{1} - -A complete MPS file which specifies data for this example is shown -below (the first two comment lines show card positions). - -\bigskip - -\begin{footnotesize} -\begin{verbatim} -*000000001111111111222222222233333333334444444444555555555566 -*234567890123456789012345678901234567890123456789012345678901 -NAME PLAN -ROWS - N VALUE - E YIELD - L FE - L CU - L MN - L MG - G AL - L SI -COLUMNS - BIN1 VALUE .03000 YIELD 1.00000 - FE .15000 CU .03000 - MN .02000 MG .02000 - AL .70000 SI .02000 - BIN2 VALUE .08000 YIELD 1.00000 - FE .04000 CU .05000 - MN .04000 MG .03000 - AL .75000 SI .06000 - BIN3 VALUE .17000 YIELD 1.00000 - FE .02000 CU .08000 - MN .01000 AL .80000 - SI .08000 - BIN4 VALUE .12000 YIELD 1.00000 - FE .04000 CU .02000 - MN .02000 AL .75000 - SI .12000 - BIN5 VALUE .15000 YIELD 1.00000 - FE .02000 CU .06000 - MN .02000 MG .01000 - AL .80000 SI .02000 - ALUM VALUE .21000 YIELD 1.00000 - FE .01000 CU .01000 - AL .97000 SI .01000 - SILICON VALUE .38000 YIELD 1.00000 - FE .03000 SI .97000 -RHS - RHS1 YIELD 2000.00000 FE 60.00000 - CU 100.00000 MN 40.00000 - SI 300.00000 - MG 30.00000 AL 1500.00000 -RANGES - RNG1 SI 50.00000 -BOUNDS - UP BND1 BIN1 200.00000 - UP BIN2 2500.00000 - LO BIN3 400.00000 - UP BIN3 800.00000 - LO BIN4 100.00000 - UP BIN4 700.00000 - UP BIN5 1500.00000 -ENDATA -\end{verbatim} -\end{footnotesize} - -\vspace*{-6pt} - -\section{MIP features} - -\vspace*{-4pt} - -The MPS format provides two ways for introducing integer variables into -the problem. - -The first way is most general and based on using special marker cards -INTORG and INTEND. These marker cards are placed in the COLUMNS section. -The INTORG card indicates the start of a group of integer variables -(columns), and the card INTEND indicates the end of the group. The MPS -file may contain arbitrary number of the marker cards. - -The marker cards have the same format as the data cards (see Section -\ref{secmps}, page \pageref{secmps}). - -The fields 1, 2, and 6 are not used and should be empty. - -The field 2 should contain a marker name. This name may be arbitrary. - -The field 3 should contain the word \verb|'MARKER'| (including -apostrophes). - -The field 5 should contain either the word \verb|'INTORG'| (including -apostrophes) for the marker card, which begins a group of integer -columns, or the word \verb|'INTEND'| (including apostrophes) for the -marker card, which ends the group. - -The second way is less general but more convenient in some cases. It -allows the user declaring integer columns using three additional types -of bounds, which are specified in the field 1 of data cards in the -BOUNDS section (see Section \ref{secbounds}, page \pageref{secbounds}): - -\verb|LI| --- lower integer. This bound type specifies that the -corresponding column (structural variable), whose name is specified in -field 3, is of integer kind. In this case an lower bound of the -column should be specified in field 4 (like in the case of \verb|LO| -bound type). - -\verb|UI| --- upper integer. This bound type specifies that the -corresponding column (structural variable), whose name is specified in -field 3, is of integer kind. In this case an upper bound of the -column should be specified in field 4 (like in the case of \verb|UP| -bound type). - -\verb|BV| --- binary variable. This bound type specifies that the -corresponding column (structural variable), whose name is specified in -the field 3, is of integer kind, its lower bound is zero, and its upper -bound is one (thus, such variable being of integer kind can have only -two values zero and one). In this case a numeric value specified in the -field 4 is ignored and may be omitted. - -Consider the following example of MIP problem: - -\noindent -\hspace{1in} minimize -$$Z = 3 x_1 + 7 x_2 - x_3 + x4$$ -\hspace{1in} subject to linear constraints -$$ -\begin{array}{c} -\nonumber r_1 = 2 x_1 - \ \ x_2 + \ \ x_3 - \ \;x_4 \\ -\nonumber r_2 = \ \;x_1 - \ \;x_2 - 6 x_3 + 4 x_4 \\ -\nonumber r_3 = 5 x_1 + 3 x_2 \ \ \ \ \ \ \ \ \ + \ \ x_4 \\ -\end{array} -$$ -\hspace{1in} and bound of variables -$$ -\begin{array}{cccl} -\nonumber 1 \leq r_1 < +\infty && 0 \leq x_1 \leq 4 &{\rm(continuous)}\\ -\nonumber 8 \leq r_2 < +\infty && 2 \leq x_2 \leq 5 &{\rm(integer)} \\ -\nonumber 5 \leq r_3 < +\infty && 0 \leq x_3 \leq 1 &{\rm(integer)} \\ -\nonumber && 3 \leq x_4 \leq 8 &{\rm(continuous)}\\ -\end{array} -$$ - -The corresponding MPS file may look like the following: - -\medskip - -\begin{footnotesize} -\begin{verbatim} -NAME SAMP1 -ROWS - N Z - G R1 - G R2 - G R3 -COLUMNS - X1 R1 2.0 R2 1.0 - X1 R3 5.0 Z 3.0 - MARK0001 'MARKER' 'INTORG' - X2 R1 -1.0 R2 -1.0 - X2 R3 3.0 Z 7.0 - X3 R1 1.0 R2 -6.0 - X3 Z -1.0 - MARK0002 'MARKER' 'INTEND' - X4 R1 -1.0 R2 4.0 - X4 R3 1.0 Z 1.0 -RHS - RHS1 R1 1.0 - RHS1 R2 8.0 - RHS1 R3 5.0 -BOUNDS - UP BND1 X1 4.0 - LO BND1 X2 2.0 - UP BND1 X2 5.0 - UP BND1 X3 1.0 - LO BND1 X4 3.0 - UP BND1 X4 8.0 -ENDATA -\end{verbatim} -\end{footnotesize} - -\newpage - -The same example may be coded without INTORG/INTEND markers using the -bound type UI for the variable $x_2$ and the bound type BV for the -variable $x_3$: - -\medskip - -\begin{footnotesize} -\begin{verbatim} -NAME SAMP2 -ROWS - N Z - G R1 - G R2 - G R3 -COLUMNS - X1 R1 2.0 R2 1.0 - X1 R3 5.0 Z 3.0 - X2 R1 -1.0 R2 -1.0 - X2 R3 3.0 Z 7.0 - X3 R1 1.0 R2 -6.0 - X3 Z -1.0 - X4 R1 -1.0 R2 4.0 - X4 R3 1.0 Z 1.0 -RHS - RHS1 R1 1.0 - RHS1 R2 8.0 - RHS1 R3 5.0 -BOUNDS - UP BND1 X1 4.0 - LO BND1 X2 2.0 - UI BND1 X2 5.0 - BV BND1 X3 - LO BND1 X4 3.0 - UP BND1 X4 8.0 -ENDATA -\end{verbatim} -\end{footnotesize} - -%\section{Specifying predefined basis} -%\label{secbas} -% -%The MPS format can also be used to specify some predefined basis for an -%LP problem, i.e. to specify which rows and columns are basic and which -%are non-basic. -% -%The order of a basis file in the MPS format is: -% -%$\bullet$ NAME indicator card; -% -%$\bullet$ data cards (can appear in arbitrary order); -% -%$\bullet$ ENDATA indicator card. -% -%Each data card specifies either a pair "basic column---non-basic row" -%or a non-basic column. All the data cards have the following format. -% -%`\verb|XL|' in the field 1 means that a column, whose name is given in -%the field 2, is basic, and a row, whose name is given in the field 3, -%is non-basic and placed on its lower bound. -% -%`\verb|XU|' in the field 1 means that a column, whose name is given in -%the field 2, is basic, and a row, whose name is given in the field 3, -%is non-basic and placed on its upper bound. -% -%`\verb|LL|' in the field 1 means that a column, whose name is given in -%the field 3, is non-basic and placed on its lower bound. -% -%`\verb|UL|' in the field 1 means that a column, whose name is given in -%the field 3, is non-basic and placed on its upper bound. -% -%The field 2 contains a column name. -% -%If the indicator given in the field 1 is `\verb|XL|' or `\verb|XU|', -%the field 3 contains a row name. Otherwise, if the indicator is -%`\verb|LL|' or `\verb|UL|', the field 3 is not used and should be -%empty. -% -%The field 4, 5, and 6 are not used and should be empty. -% -%A basis file in the MPS format acts like a patch: it doesn't specify -%a basis completely, instead that it is just shows in what a given basis -%differs from the "standard" basis, where all rows (auxiliary variables) -%are assumed to be basic and all columns (structural variables) are -%assumed to be non-basic. -% -%As an example here is a basis file that specifies an optimal basis -%for the example LP problem given in Section \ref{secmpsex}, -%Page \pageref{secmpsex}: -% -%\pagebreak -% -%\begin{verbatim} -%*000000001111111111222222222233333333334444444444555555555566 -%*234567890123456789012345678901234567890123456789012345678901 -%NAME PLAN -% XL BIN2 YIELD -% XL BIN3 FE -% XL BIN4 MN -% XL ALUM AL -% XL SILICON SI -% LL BIN1 -% LL BIN5 -%ENDATA -%\end{verbatim} - -%* eof *% diff --git a/resources/3rdparty/glpk-4.53/doc/glpk09.tex b/resources/3rdparty/glpk-4.53/doc/glpk09.tex deleted file mode 100644 index d04865d9d..000000000 --- a/resources/3rdparty/glpk-4.53/doc/glpk09.tex +++ /dev/null @@ -1,424 +0,0 @@ -%* glpk09.tex *% - -\chapter{CPLEX LP Format} -\label{chacplex} - -\section{Prelude} - -The CPLEX LP format\footnote{The CPLEX LP format was developed in -the end of 1980's by CPLEX Optimization, Inc. as an input format for -the CPLEX linear programming system. Although the CPLEX LP format is -not as widely used as the MPS format, being row-oriented it is more -convenient for coding mathematical programming models by human. This -appendix describes only the features of the CPLEX LP format which are -implemented in the GLPK package.} is intended for coding LP/MIP problem -data. It is a row-oriented format that assumes the formulation of -LP/MIP problem (1.1)---(1.3) (see Section \ref{seclp}, page -\pageref{seclp}). - -CPLEX LP file is a plain text file written in CPLEX LP format. Each -text line of this file may contain up to 255 characters\footnote{GLPK -allows text lines of arbitrary length.}. Blank lines are ignored. -If a line contains the backslash character ($\backslash$), this -character and everything that follows it until the end of line are -considered as a comment and also ignored. - -An LP file is coded by the user using the following elements: keywords, -symbolic names, numeric constants, delimiters, and blanks. - -{\it Keywords} which may be used in the LP file are the following: - -\begin{verbatim} - minimize minimum min - maximize maximum max - subject to such that s.t. st. st - bounds bound - general generals gen - integer integers int - binary binaries bin - infinity inf - free - end -\end{verbatim} - -\noindent -All the keywords are case insensitive. Keywords given above on the same -line are equivalent. Any keyword (except \verb|infinity|, \verb|inf|, -and \verb|free|) being used in the LP file must start at the beginning -of a text line. - -\newpage - -{\it Symbolic names} are used to identify the objective function, -constraints (rows), and variables (columns). All symbolic names are case -sensitive and may contain up to 16 alphanumeric characters\footnote{GLPK -allows symbolic names having up to 255 characters.} (\verb|a|, \dots, -\verb|z|, \verb|A|, \dots, \verb|Z|, \verb|0|, \dots, \verb|9|) as well -as the following characters: - -\begin{verbatim} - ! " # $ % & ( ) / , . ; ? @ _ ` ' { } | ~ -\end{verbatim} - -\noindent -with exception that no symbolic name can begin with a digit or -a period. - -{\it Numeric constants} are used to denote constraint and objective -coefficients, right-hand sides of constraints, and bounds of variables. -They are coded in the standard form $xx$\verb|E|$syy$, where $xx$ is -a real number with optional decimal point, $s$ is a sign (\verb|+| or -\verb|-|), $yy$ is an integer decimal exponent. Numeric constants may -contain arbitrary number of characters. The exponent part is optional. -The letter `\verb|E|' can be coded as `\verb|e|'. If the sign $s$ is -omitted, plus is assumed. - -{\it Delimiters} that may be used in the LP file are the following: - -\begin{verbatim} - : - + - - - < <= =< - > >= => - = -\end{verbatim} - -\noindent -Delimiters given above on the same line are equivalent. The meaning of -the delimiters will be explained below. - -{\it Blanks} are non-significant characters. They may be used freely to -improve readability of the LP file. Besides, blanks should be used to -separate elements from each other if there is no other way to do that -(for example, to separate a keyword from a following symbolic name). - -The order of an LP file is: - -\vspace*{-8pt} - -\begin{itemize} -\item objective function definition; - -\item constraints section; - -\item bounds section; - -\item general, integer, and binary sections (can appear in arbitrary -order); - -\item end keyword. -\end{itemize} - -\vspace*{-8pt} - -These components are discussed in following sections. - -\section{Objective function definition} - -The objective function definition must appear first in the LP file. -It defines the objective function and specifies the optimization -direction. - -The objective function definition has the following form: -$$ -\left\{ -\begin{array}{@{}c@{}} -{\tt minimize} \\ {\tt maximize} -\end{array} -\right\}\ f\ {\tt :}\ s\ c\ x\ s\ c\ x\ \dots\ s\ c\ x -$$ -where $f$ is a symbolic name of the objective function, $s$ is a sign -\verb|+| or \verb|-|, $c$ is a numeric constant that denotes an -objective coefficient, $x$ is a symbolic name of a variable. - -If necessary, the objective function definition can be continued on as -many text lines as desired. - -The name of the objective function is optional and may be omitted -(together with the semicolon that follows it). In this case the default -name `\verb|obj|' is assigned to the objective function. - -If the very first sign $s$ is omitted, the sign plus is assumed. Other -signs cannot be omitted. - -If some objective coefficient $c$ is omitted, 1 is assumed. - -Symbolic names $x$ used to denote variables are recognized by context -and therefore needn't to be declared somewhere else. - -Here is an example of the objective function definition: - -\begin{verbatim} - Minimize Z : - x1 + 2 x2 - 3.5 x3 + 4.997e3x(4) + x5 + x6 + - x7 - .01x8 -\end{verbatim} - -\section{Constraints section} - -The constraints section must follow the objective function definition. -It defines a system of equality and/or inequality constraints. - -The constraint section has the following form: - -\begin{center} -\begin{tabular}{l} -\verb|subject to| \\ -{\it constraint}$_1$ \\ -{\it constraint}$_2$ \\ -\hspace{20pt}\dots \\ -{\it constraint}$_m$ \\ -\end{tabular} -\end{center} - -\noindent where {\it constraint}$_i, i=1,\dots,m,$ is a particular -constraint definition. - -Each constraint definition can be continued on as many text lines as -desired. However, each constraint definition must begin on a new line -except the very first constraint definition which can begin on the same -line as the keyword `\verb|subject to|'. - -Constraint definitions have the following form: -$$ -r\ {\tt:}\ s\ c\ x\ s\ c\ x\ \dots\ s\ c\ x -\ \left\{ -\begin{array}{@{}c@{}} -\mbox{\tt<=} \\ \mbox{\tt>=} \\ \mbox{\tt=} -\end{array} -\right\}\ b -$$ -where $r$ is a symbolic name of a constraint, $s$ is a sign \verb|+| or -\verb|-|, $c$ is a numeric constant that denotes a constraint -coefficient, $x$ is a symbolic name of a variable, $b$ is a right-hand -side. - -The name $r$ of a constraint (which is the name of the corresponding -auxiliary variable) is optional and may be omitted (together with the -semicolon that follows it). In this case the default names like -`\verb|r.nnn|' are assigned to unnamed constraints. - -The linear form $s\ c\ x\ s\ c\ x\ \dots\ s\ c\ x$ in the left-hand -side of a constraint definition has exactly the same meaning as in the -case of the objective function definition (see above). - -After the linear form one of the following delimiters that indicates -the constraint sense must be specified: - -\verb|<=| \ means `less than or equal to' - -\verb|>=| \ means `greater than or equal to' - -\verb|= | \ means `equal to' - -The right hand side $b$ is a numeric constant with an optional sign. - -Here is an example of the constraints section: - -\begin{verbatim} - Subject To - one: y1 + 3 a1 - a2 - b >= 1.5 - y2 + 2 a3 + 2 - a4 - b >= -1.5 - two : y4 + 3 a1 + 4 a5 - b <= +1 - .20y5 + 5 a2 - b = 0 - 1.7 y6 - a6 + 5 a777 - b >= 1 -\end{verbatim} - -Should note that it is impossible to express ranged constraints in the -CPLEX LP format. Each a ranged constraint can be coded as two -constraints with identical linear forms in the left-hand side, one of -which specifies a lower bound and other does an upper one of the -original ranged constraint. Another way is to introduce a slack -double-bounded variable; for example, the -constraint -$$10\leq x+2y+3z\leq 50$$ -can be written as follows: -$$x+2y+3z+t=50,$$ -where $0\leq t\leq 40$ is a slack variable. - -\section{Bounds section} - -The bounds section is intended to define bounds of variables. This -section is optional; if it is specified, it must follow the constraints -section. If the bound section is omitted, all variables are assumed to -be non-negative (i.e. that they have zero lower bound and no upper -bound). - -The bounds section has the following form: - -\begin{center} -\begin{tabular}{l} -\verb|bounds| \\ -{\it definition}$_1$ \\ -{\it definition}$_2$ \\ -\hspace{20pt}\dots \\ -{\it definition}$_p$ \\ -\end{tabular} -\end{center} - -\noindent -where {\it definition}$_k, k=1,\dots,p,$ is a particular bound -definition. - -Each bound definition must begin on a new line\footnote{The GLPK -implementation allows several bound definitions to be placed on the -same line.} except the very first bound definition which can begin on -the same line as the keyword `\verb|bounds|'. - -\newpage - -Syntactically constraint definitions can have one of the following six -forms: - -\begin{center} -\begin{tabular}{ll} -$x$ \verb|>=| $l$ & specifies a lower bound \\ -$l$ \verb|<=| $x$ & specifies a lower bound \\ -$x$ \verb|<=| $u$ & specifies an upper bound \\ -$l$ \verb|<=| $x$ \verb|<=| $u$ &specifies both lower and upper bounds\\ -$x$ \verb|=| $t$ &specifies a fixed value \\ -$x$ \verb|free| &specifies free variable -\end{tabular} -\end{center} - -\noindent -where $x$ is a symbolic name of a variable, $l$ is a numeric constant -with an optional sign that defines a lower bound of the variable or -\verb|-inf| that means that the variable has no lower bound, $u$ is a -numeric constant with an optional sign that defines an upper bound of -the variable or \verb|+inf| that means that the variable has no upper -bound, $t$ is a numeric constant with an optional sign that defines a -fixed value of the variable. - -By default all variables are non-negative, i.e. have zero lower bound -and no upper bound. Therefore definitions of these default bounds can -be omitted in the bounds section. - -Here is an example of the bounds section: - -\begin{verbatim} - Bounds - -inf <= a1 <= 100 - -100 <= a2 - b <= 100 - x2 = +123.456 - x3 free -\end{verbatim} - -\section{General, integer, and binary sections} - -The general, integer, and binary sections are intended to define -some variables as integer or binary. All these sections are optional -and needed only in case of MIP problems. If they are specified, they -must follow the bounds section or, if the latter is omitted, the -constraints section. - -All the general, integer, and binary sections have the same form as -follows: - -\begin{center} -\begin{tabular}{l} -$ -\left\{ -\begin{array}{@{}l@{}} -\verb|general| \\ -\verb|integer| \\ -\verb|binary | \\ -\end{array} -\right\} -$ \\ -\hspace{10pt}$x_1$ \\ -\hspace{10pt}$x_2$ \\ -\hspace{10pt}\dots \\ -\hspace{10pt}$x_q$ \\ -\end{tabular} -\end{center} - -\noindent -where $x_k$ is a symbolic name of variable, $k=1,\dots,q$. - -Each symbolic name must begin on a new line\footnote{The GLPK -implementation allows several symbolic names to be placed on the same -line.} except the very first symbolic name which can begin on the same -line as the keyword `\verb|general|', `\verb|integer|', or -`\verb|binary|'. - -\newpage - -If a variable appears in the general or the integer section, it is -assumed to be general integer variable. If a variable appears in the -binary section, it is assumed to be binary variable, i.e. an integer -variable whose lower bound is zero and upper bound is one. (Note that -if bounds of a variable are specified in the bounds section and then -the variable appears in the binary section, its previously specified -bounds are ignored.) - -Here is an example of the integer section: - -\begin{verbatim} - Integer - z12 - z22 - z35 -\end{verbatim} - -\section{End keyword} - -The keyword `\verb|end|' is intended to end the LP file. It must begin -on a separate line and no other elements (except comments and blank -lines) must follow it. Although this keyword is optional, it is strongly -recommended to include it in the LP file. - -\section{Example of CPLEX LP file} - -Here is a complete example of CPLEX LP file that corresponds to the -example given in Section \ref{secmpsex}, page \pageref{secmpsex}. - -\medskip - -\begin{footnotesize} -\begin{verbatim} -\* plan.lp *\ - -Minimize - value: .03 bin1 + .08 bin2 + .17 bin3 + .12 bin4 + .15 bin5 + - .21 alum + .38 silicon - -Subject To - yield: bin1 + bin2 + bin3 + bin4 + bin5 + - alum + silicon = 2000 - - fe: .15 bin1 + .04 bin2 + .02 bin3 + .04 bin4 + .02 bin5 + - .01 alum + .03 silicon <= 60 - - cu: .03 bin1 + .05 bin2 + .08 bin3 + .02 bin4 + .06 bin5 + - .01 alum <= 100 - - mn: .02 bin1 + .04 bin2 + .01 bin3 + .02 bin4 + .02 bin5 <= 40 - - mg: .02 bin1 + .03 bin2 + .01 bin5 <= 30 - - al: .70 bin1 + .75 bin2 + .80 bin3 + .75 bin4 + .80 bin5 + - .97 alum >= 1500 - - si1: .02 bin1 + .06 bin2 + .08 bin3 + .12 bin4 + .02 bin5 + - .01 alum + .97 silicon >= 250 - - si2: .02 bin1 + .06 bin2 + .08 bin3 + .12 bin4 + .02 bin5 + - .01 alum + .97 silicon <= 300 - -Bounds - bin1 <= 200 - bin2 <= 2500 - 400 <= bin3 <= 800 - 100 <= bin4 <= 700 - bin5 <= 1500 - -End - -\* eof *\ -\end{verbatim} -\end{footnotesize} - -%* eof *% diff --git a/resources/3rdparty/glpk-4.53/doc/glpk10.tex b/resources/3rdparty/glpk-4.53/doc/glpk10.tex deleted file mode 100644 index 3499d04bf..000000000 --- a/resources/3rdparty/glpk-4.53/doc/glpk10.tex +++ /dev/null @@ -1,166 +0,0 @@ -%* glpk10.tex *% - -\chapter{Stand-alone LP/MIP Solver} -\label{chaglpsol} - -The GLPK package includes the program \verb|glpsol|, which is a -stand-alone LP/MIP solver. This program can be invoked from the command -line to read LP/MIP problem data in any format supported by GLPK, solve -the problem, and write its solution to an output text file. - -\para{Usage} - -\verb|glpsol| [{\it options\dots}] [{\it filename}] - -\para{General options} - -\begin{verbatim} - --mps read LP/MIP problem in fixed MPS format - --freemps read LP/MIP problem in free MPS format (default) - --lp read LP/MIP problem in CPLEX LP format - --glp read LP/MIP problem in GLPK format - --math read LP/MIP model written in GNU MathProg modeling - language - -m filename, --model filename - read model section and optional data section from - filename (same as --math) - -d filename, --data filename - read data section from filename (for --math only); - if model file also has data section, it is ignored - -y filename, --display filename - send display output to filename (for --math only); - by default the output is sent to terminal - --seed value initialize pseudo-random number generator used in - MathProg model with specified seed (any integer); - if seed value is ?, some random seed will be used - --mincost read min-cost flow problem in DIMACS format - --maxflow read maximum flow problem in DIMACS format - --cnf read CNF-SAT problem in DIMACS format - --simplex use simplex method (default) - --interior use interior point method (LP only) - -r filename, --read filename - read solution from filename rather to find it with - the solver - --min minimization - --max maximization - --scale scale problem (default) - --noscale do not scale problem - -o filename, --output filename - write solution to filename in printable format - -w filename, --write filename - write solution to filename in plain text format - --ranges filename - write sensitivity analysis report to filename in - printable format (simplex only) - --tmlim nnn limit solution time to nnn seconds - --memlim nnn limit available memory to nnn megabytes - --check do not solve problem, check input data only - --name probname change problem name to probname - --wmps filename write problem to filename in fixed MPS format - --wfreemps filename - write problem to filename in free MPS format - --wlp filename write problem to filename in CPLEX LP format - --wglp filename write problem to filename in GLPK format - --wcnf filename write problem to filename in DIMACS CNF-SAT format - --log filename write copy of terminal output to filename - -h, --help display this help information and exit - -v, --version display program version and exit -\end{verbatim} - -\para{LP basis factorization options} - -\begin{verbatim} - --luf LU + Forrest-Tomlin update - (faster, less stable; default) - --cbg LU + Schur complement + Bartels-Golub update - (slower, more stable) - --cgr LU + Schur complement + Givens rotation update - (slower, more stable) -\end{verbatim} - -\para{Options specific to the simplex solver} - -\begin{verbatim} - --primal use primal simplex (default) - --dual use dual simplex - --std use standard initial basis of all slacks - --adv use advanced initial basis (default) - --bib use Bixby's initial basis - --ini filename use as initial basis previously saved with -w - (disables LP presolver) - --steep use steepest edge technique (default) - --nosteep use standard "textbook" pricing - --relax use Harris' two-pass ratio test (default) - --norelax use standard "textbook" ratio test - --presol use presolver (default; assumes --scale and --adv) - --nopresol do not use presolver - --exact use simplex method based on exact arithmetic - --xcheck check final basis using exact arithmetic -\end{verbatim} - -\para{Options specific to the interior-point solver} - -\begin{verbatim} - --nord use natural (original) ordering - --qmd use quotient minimum degree ordering - --amd use approximate minimum degree ordering (default) - --symamd use approximate minimum degree ordering -\end{verbatim} - -\para{Options specific to the MIP solver} - -\begin{verbatim} - --nomip consider all integer variables as continuous - (allows solving MIP as pure LP) - --first branch on first integer variable - --last branch on last integer variable - --mostf branch on most fractional variable - --drtom branch using heuristic by Driebeck and Tomlin - (default) - --pcost branch using hybrid pseudocost heuristic (may be - useful for hard instances) - --dfs backtrack using depth first search - --bfs backtrack using breadth first search - --bestp backtrack using the best projection heuristic - --bestb backtrack using node with best local bound - (default) - --intopt use MIP presolver (default) - --nointopt do not use MIP presolver - --binarize replace general integer variables by binary ones - (assumes --intopt) - --fpump apply feasibility pump heuristic - --proxy [nnn] apply proximity search heuristic (nnn is time limit - in seconds; default is 60) - --gomory generate Gomory's mixed integer cuts - --mir generate MIR (mixed integer rounding) cuts - --cover generate mixed cover cuts - --clique generate clique cuts - --cuts generate all cuts above - --mipgap tol set relative mip gap tolerance to tol - --minisat translate integer feasibility problem to CNF-SAT - and solve it with MiniSat solver -\end{verbatim} - -\newpage - -\begin{verbatim} - --objbnd bound add inequality obj <= bound (minimization) or - obj >= bound (maximization) to integer feasibility - problem (assumes --minisat) -\end{verbatim} - -For description of the MPS format see Appendix \ref{champs}, page -\pageref{champs}. - -For description of the CPLEX LP format see Appendix \ref{chacplex}, -page \pageref{chacplex}. - -For description of the modeling language see the document ``Modeling -Language GNU MathProg: Language Reference'' included in the GLPK -distribution. - -For description of the DIMACS min-cost flow problem format and DIMACS -maximum flow problem format see the document ``GLPK: Graph and Network -Routines'' included in the GLPK distribution. - -%* eof *% diff --git a/resources/3rdparty/glpk-4.53/doc/glpk11.tex b/resources/3rdparty/glpk-4.53/doc/glpk11.tex deleted file mode 100644 index d45ab3d29..000000000 --- a/resources/3rdparty/glpk-4.53/doc/glpk11.tex +++ /dev/null @@ -1,203 +0,0 @@ -%* glpk11.tex *% - -\chapter{External Software Modules Used In GLPK} - -In the GLPK package there are used some external software modules -listed in this Appendix. Note that these modules are {\it not} part of -GLPK, but are used with GLPK and included in the distribution. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\section{AMD} - -\noindent -AMD Version 2.2, Copyright {\copyright} 2007 by Timothy A. Davis, -Patrick R. Amestoy, and Iain S. Duff. All Rights Reserved. - -\para{Description} - -AMD is a set of routines for pre-ordering sparse matrices prior to -Cholesky or LU factorization, using the approximate minimum degree -ordering algorithm. - -\para{License} - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2.1 of -the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 -USA. - -Permission is hereby granted to use or copy this program under the -terms of the GNU LGPL, provided that the Copyright, this License, -and the Availability of the original version is retained on all -copies. User documentation of any code that uses this code or any -modified version of this code must cite the Copyright, this License, -the Availability note, and ``Used by permission.'' Permission to -modify the code and to distribute modified code is granted, provided -the Copyright, this License, and the Availability note are retained, -and a notice that the code was modified is included. - -AMD is available under alternate licences; contact T. Davis for -details. - -\para{Availability} - -\noindent -\url{http://www.cise.ufl.edu/research/sparse/amd} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\section{COLAMD/SYMAMD} - -\noindent -COLAMD/SYMAMD Version 2.7, Copyright {\copyright} 1998-2007, Timothy A. -Davis, All Rights Reserved. - -\para{Description} - -colamd: an approximate minimum degree column ordering algorithm, for -LU factorization of symmetric or unsymmetric matrices, QR factorization, -least squares, interior point methods for linear programming problems, -and other related problems. - -symamd: an approximate minimum degree ordering algorithm for Cholesky -factorization of symmetric matrices. - -\para{Authors} - -The authors of the code itself are Stefan I. Larimore and Timothy A. -Davis (davis at cise.ufl.edu), University of Florida. The algorithm -was developed in collaboration with John Gilbert, Xerox PARC, and -Esmond Ng, Oak Ridge National Laboratory. - -\para{License} - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2.1 of -the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 -USA. - -Permission is hereby granted to use or copy this program under the -terms of the GNU LGPL, provided that the Copyright, this License, -and the Availability of the original version is retained on all -copies. User documentation of any code that uses this code or any -modified version of this code must cite the Copyright, this License, -the Availability note, and ``Used by permission.'' Permission to -modify the code and to distribute modified code is granted, provided -the Copyright, this License, and the Availability note are retained, -and a notice that the code was modified is included. - -COLAMD is also available under alternate licenses, contact T. Davis for -details. - -\para{Availability} - -\noindent -\url{http://www.cise.ufl.edu/research/sparse/colamd} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\section{MiniSat} - -\noindent -MiniSat-C v1.14.1, Copyright {\copyright} 2005, Niklas Sorensson. - -\para{Description} - -MiniSat is a minimalistic implementation of a Chaff-like SAT solver -based on the two-literal watch scheme for fast BCP and clause learning -by conflict analysis. - -\para{License} - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -\para{Availability} - -\noindent -\url{http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\section{zlib} - -\noindent -zlib version 1.2.5, Copyright {\copyright} 1995--2010 Jean-loup Gailly -and Mark Adler. - -\para{Description} - -zlib is a general purpose data compression library. All the code is -thread safe. The data format used by the zlib library is described by -RFCs (Request for Comments) 1950 to 1952 in the files -\verb|rfc1950.txt| (zlib format), \verb|rfc1951.txt| (deflate format) -and \verb|rfc1952.txt| (gzip format). - -\para{License} - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would - be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not - be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source - distribution. - -\hfill Jean-loup Gailly - -\hfill Mark Adler - -\para{Availability} - -\noindent -\url{http://www.zlib.net/} - -%* eof *% diff --git a/resources/3rdparty/glpk-4.53/doc/glpk12.tex b/resources/3rdparty/glpk-4.53/doc/glpk12.tex deleted file mode 100644 index 2c2b1b7a6..000000000 --- a/resources/3rdparty/glpk-4.53/doc/glpk12.tex +++ /dev/null @@ -1,707 +0,0 @@ -%* glpk12.tex *% - -\begin{footnotesize} - -\chapter*{\sf\bfseries GNU General Public License} -\addcontentsline{toc}{chapter}{GNU General Public License} - -\begin{center} -{\bf Version 3, 29 June 2007} -\end{center} - -\begin{quotation} -\noindent -Copyright {\copyright} 2007 Free Software Foundation, Inc. -\verb|| -\end{quotation} - -\begin{quotation} -\noindent -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -\end{quotation} - -\section*{Preamble} - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - -\section*{TERMS AND CONDITIONS} - -\subsubsection*{0. Definitions.} - - ``This License'' refers to version 3 of the GNU General Public -License. - - ``Copyright'' also means copyright-like laws that apply to other kinds -of works, such as semiconductor masks. - - ``The Program'' refers to any copyrightable work licensed under this -License. Each licensee is addressed as ``you''. ``Licensees'' and -``recipients'' may be individuals or organizations. - - To ``modify'' a work means to copy from or adapt all or part of the -work in a fashion requiring copyright permission, other than the making -of an exact copy. The resulting work is called a ``modified version'' -of the earlier work or a work ``based on'' the earlier work. - - A ``covered work'' means either the unmodified Program or a work based -on the Program. - - To ``propagate'' a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To ``convey'' a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays ``Appropriate Legal Notices'' -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - -\subsubsection*{1. Source Code.} - - The ``source code'' for a work means the preferred form of the work -for making modifications to it. ``Object code'' means any non-source -form of a work. - - A ``Standard Interface'' means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The ``System Libraries'' of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -``Major Component'', in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The ``Corresponding Source'' for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - -\subsubsection*{2. Basic Permissions.} - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - -\subsubsection*{3. Protecting Users' Legal Rights From -Anti-Circumvention Law.} - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - -\subsubsection*{4. Conveying Verbatim Copies.} - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - -\subsubsection*{5. Conveying Modified Source Versions.} - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - ``keep intact all notices''. - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -``aggregate'' if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - -\subsubsection*{6. Conveying Non-Source Forms.} - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A ``User Product'' is either (1) a ``consumer product'', which means -any tangible personal property which is normally used for personal, -family, or household purposes, or (2) anything designed or sold for -incorporation into a dwelling. In determining whether a product is a -consumer product, doubtful cases shall be resolved in favor of coverage. -For a particular product received by a particular user, ``normally -used'' refers to a typical or common use of that class of product, -regardless of the status of the particular user or of the way in which -the particular user actually uses, or expects or is expected to use, the -product. A product is a consumer product regardless of whether the -product has substantial commercial, industrial or non-consumer uses, -unless such uses represent the only significant mode of use of the -product. - - ``Installation Information'' for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product -from a modified version of its Corresponding Source. The information -must suffice to ensure that the continued functioning of the modified -object code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to -a network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - -\subsubsection*{7. Additional Terms.} - - ``Additional permissions'' are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders -of that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered ``further -restrictions'' within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - -\subsubsection*{8. Termination.} - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - -\subsubsection*{9. Acceptance Not Required for Having Copies.} - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - -\subsubsection*{10. Automatic Licensing of Downstream Recipients.} - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An ``entity transaction'' is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - -\subsubsection*{11. Patents.} - - A ``contributor'' is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's ``contributor version''. - - A contributor's ``essential patent claims'' are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, ``control'' includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a ``patent license'' is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To ``grant'' such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. ``Knowingly relying'' means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is ``discriminatory'' if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - -\subsubsection*{12. No Surrender of Others' Freedom.} - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not convey it at all. For example, if you agree to terms that -obligate you to collect a royalty for further conveying from those to -whom you convey the Program, the only way you could satisfy both those -terms and this License would be to refrain entirely from conveying the -Program. - -\subsubsection*{13. Use with the GNU Affero General Public License.} - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - -\subsubsection*{14. Revised Versions of this License.} - - The Free Software Foundation may publish revised and/or new versions -of the GNU General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in -detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License ``or any later version'' applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - -\subsubsection*{15. Disclaimer of Warranty.} - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM ``AS IS'' WITHOUT -WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE -OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU -ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - -\subsubsection*{16. Limitation of Liability.} - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR -CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES -ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT -NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES -SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE -WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN -ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -\subsubsection*{17. Interpretation of Sections 15 and 16.} - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - -\section*{END OF TERMS AND CONDITIONS} - -\newpage - -\section*{How to Apply These Terms to Your New Programs} - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the ``copyright'' line and a pointer to where the full notice is found. - -\begin{verbatim} - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -\end{verbatim} - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - -\begin{verbatim} - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. -\end{verbatim} - -\noindent -The hypothetical commands `show w' and `show c' should show the -appropriate parts of the General Public License. Of course, your -program's commands might be different; for a GUI interface, you would -use an ``about box''. - - You should also get your employer (if you work as a programmer) or -school, if any, to sign a ``copyright disclaimer'' for the program, if -necessary. For more information on this, and how to apply and follow the -GNU GPL, see \verb||. - - The GNU General Public License does not permit incorporating your -program into proprietary programs. If your program is a subroutine -library, you may consider it more useful to permit linking proprietary -applications with the library. If this is what you want to do, use the -GNU Lesser General Public License instead of this License. But first, -please read \verb||. - -\end{footnotesize} - -%* eof *% diff --git a/resources/3rdparty/glpk-4.53/doc/gmpl.pdf b/resources/3rdparty/glpk-4.53/doc/gmpl.pdf deleted file mode 100644 index dfd72fc3c2b688fb7c73aeb09974a7cf5aecb99d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 216026 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. -% -% GLPK is free software: you can redistribute it and/or modify it -% under the terms of the GNU General Public License as published by -% the Free Software Foundation, either version 3 of the License, or -% (at your option) any later version. -% -% GLPK is distributed in the hope that it will be useful, but WITHOUT -% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License -% along with GLPK. If not, see . -%*********************************************************************** - -\documentclass[11pt]{report} -\usepackage{amssymb} -\usepackage[dvipdfm,linktocpage,colorlinks,linkcolor=blue, -urlcolor=blue]{hyperref} -\usepackage{indentfirst} - -\setlength{\textwidth}{6.5in} -\setlength{\textheight}{8.5in} -\setlength{\oddsidemargin}{0in} -\setlength{\topmargin}{0in} -\setlength{\headheight}{0in} -\setlength{\headsep}{0in} -\setlength{\footskip}{0.5in} -\setlength{\parindent}{16pt} -\setlength{\parskip}{5pt} -\setlength{\topsep}{0pt} -\setlength{\partopsep}{0pt} -\setlength{\itemsep}{\parskip} -\setlength{\parsep}{0pt} -\setlength{\leftmargini}{\parindent} -\renewcommand{\labelitemi}{---} - -\def\para#1{\noindent{\bf#1}} - -\renewcommand\contentsname{\sf\bfseries Contents} -\renewcommand\chaptername{\sf\bfseries Chapter} -\renewcommand\appendixname{\sf\bfseries Appendix} - -\begin{document} - -\thispagestyle{empty} - -\begin{center} - -\vspace*{1.5in} - -\begin{huge} -\sf\bfseries Modeling Language GNU MathProg -\end{huge} - -\vspace{0.5in} - -\begin{LARGE} -\sf Language Reference -\end{LARGE} - -\vspace{0.5in} - -\begin{LARGE} -\sf for GLPK Version 4.50 -\end{LARGE} - -\vspace{0.5in} -\begin{Large} -\sf (DRAFT, May 2013) -\end{Large} - -\end{center} - -\newpage - -\vspace*{1in} - -\vfill - -\noindent -The GLPK package is part of the GNU Project released under the aegis of -GNU. - -\noindent -Copyright \copyright{} 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, -2008, 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -reserved. - -\noindent -Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, -MA 02110-1301, USA. - -\noindent -Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - -\noindent -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that -the entire resulting derived work is distributed under the terms of -a permission notice identical to this one. - -\noindent -Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -{\setlength{\parskip}{0pt} -\tableofcontents -} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\chapter{Introduction} - -{\it GNU MathProg} is a modeling language intended for describing -linear mathematical programming models.\footnote{The GNU MathProg -language is a subset of the AMPL language. Its GLPK implementation is -mainly based on the paper: {\it Robert Fourer}, {\it David M. Gay}, and -{\it Brian W. Kernighan}, ``A Modeling Language for Mathematical -Programming.'' {\it Management Science} 36 (1990), pp.~519-54.} - -Model descriptions written in the GNU MathProg language consist of -a set of statements and data blocks constructed by the user from the -language elements described in this document. - -In a process called {\it translation}, a program called the {\it model -translator} analyzes the model description and translates it into -internal data structures, which may be then used either for generating -mathematical programming problem instance or directly by a program -called the {\it solver} to obtain numeric solution of the problem. - -\section{Linear programming problem} -\label{problem} - -In MathProg the linear programming (LP) problem is stated as follows: - -\medskip - -\noindent\hspace{1in}minimize (or maximize) -$$z=c_1x_1+c_2x_2+\dots+c_nx_n+c_0\eqno(1.1)$$ -\noindent\hspace{1in}subject to linear constraints -$$ -\begin{array}{l@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }l} -L_1&\leq&a_{11}x_1&+&a_{12}x_2&+\dots+&a_{1n}x_n&\leq&U_1\\ -L_2&\leq&a_{21}x_1&+&a_{22}x_2&+\dots+&a_{2n}x_n&\leq&U_2\\ -\multicolumn{9}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\ -L_m&\leq&a_{m1}x_1&+&a_{m2}x_2&+\dots+&a_{mn}x_n&\leq&U_m\\ -\end{array}\eqno(1.2) -$$ -\noindent\hspace{1in}and bounds of variables -$$ -\begin{array}{l@{\ }c@{\ }c@{\ }c@{\ }l} -l_1&\leq&x_1&\leq&u_1\\ -l_2&\leq&x_2&\leq&u_2\\ -\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .}\\ -l_n&\leq&x_n&\leq&u_n\\ -\end{array}\eqno(1.3) -$$ - -\newpage - -\noindent -where $x_1$, $x_2$, \dots, $x_n$ are variables; $z$ is the objective -function; $c_1$, $c_2$, \dots, $c_n$ are objective coefficients; $c_0$ -is the constant term (``shift'') of the objective function; $a_{11}$, -$a_{12}$, \dots, $a_{mn}$ are constraint coefficients; $L_1$, $L_2$, -\dots, $L_m$ are lower constraint bounds; $U_1$, $U_2$, \dots, $U_m$ -are upper constraint bounds; $l_1$, $l_2$, \dots, $l_n$ are lower -bounds of variables; $u_1$, $u_2$, \dots, $u_n$ are upper bounds of -variables. - -Bounds of variables and constraint bounds can be finite as well as -infinite. Besides, lower bounds can be equal to corresponding upper -bounds. Thus, the following types of variables and constraints are -allowed: - -\medskip - -{\def\arraystretch{1.4} -\noindent\hspace{54pt} -\begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }l@{\hspace*{39.5pt}}l} -$-\infty$&$<$&$x$&$<$&$+\infty$&Free (unbounded) variable\\ -$l$&$\leq$&$x$&$<$&$+\infty$&Variable with lower bound\\ -$-\infty$&$<$&$x$&$\leq$&$u$&Variable with upper bound\\ -$l$&$\leq$&$x$&$\leq$&$u$&Double-bounded variable\\ -$l$&$=$&$x$&=&$u$&Fixed variable\\ -\end{tabular} - -\noindent\hfil -\begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }ll} -$-\infty$&$<$&$\sum a_jx_j$&$<$&$+\infty$&Free (unbounded) linear -form\\ -$L$&$\leq$&$\sum a_jx_j$&$<$&$+\infty$&Inequality constraint ``greater -than or equal to''\\ -$-\infty$&$<$&$\sum a_jx_j$&$\leq$&$U$&Inequality constraint ``less -than or equal to''\\ -$L$&$\leq$&$\sum a_jx_j$&$\leq$&$U$&Double-bounded inequality -constraint\\ -$L$&$=$&$\sum a_jx_j$&=&$U$&Equality constraint\\ -\end{tabular} -} - -\medskip - -In addition to pure LP problems MathProg also allows mixed integer -linear programming (MIP) problems, where some or all variables are -restricted to be integer or binary. - -\section{Model objects} - -In MathProg the model is described in terms of sets, parameters, -variables, constraints, and objectives, which are called {\it model -objects}. - -The user introduces particular model objects using the language -statements. Each model object is provided with a symbolic name which -uniquely identifies the object and is intended for referencing -purposes. - -Model objects, including sets, can be multidimensional arrays built -over indexing sets. Formally, $n$-dimensional array $A$ is the mapping: -$$A:\Delta\rightarrow\Xi,\eqno(1.4)$$ -where $\Delta\subseteq S_1\times\dots\times S_n$ is a subset of the -Cartesian product of indexing sets, $\Xi$ is a set of array members. -In MathProg the set $\Delta$ is called the {\it subscript domain}. Its -members are $n$-tuples $(i_1,\dots,i_n)$, where $i_1\in S_1$, \dots, -$i_n\in S_n$. - -If $n=0$, the Cartesian product above has exactly one member (namely, -0-tuple), so it is convenient to think scalar objects as 0-dimensional -arrays having one member. - -\newpage - -The type of array members is determined by the type of corresponding -model object as follows: - -\medskip - -\noindent\hfil -\begin{tabular}{@{}ll@{}} -Model object&Array member\\ -\hline -Set&Elemental plain set\\ -Parameter&Number or symbol\\ -Variable&Elemental variable\\ -Constraint&Elemental constraint\\ -Objective&Elemental objective\\ -\end{tabular} - -\medskip - -In order to refer to a particular object member the object should be -provided with {\it subscripts}. For example, if $a$ is a 2-dimensional -parameter defined over $I\times J$, a reference to its particular -member can be written as $a[i,j]$, where $i\in I$ and $j\in J$. It is -understood that scalar objects being 0-dimensional need no subscripts. - -\section{Structure of model description} - -It is sometimes desirable to write a model which, at various points, -may require different data for each problem instance to be solved using -that model. For this reason in MathProg the model description consists -of two parts: the {\it model section} and the {\it data section}. - -The model section is a main part of the model description that contains -declarations of model objects and is common for all problems based on -the corresponding model. - -The data section is an optional part of the model description that -contains data specific for a particular problem instance. - -Depending on what is more convenient the model and data sections can be -placed either in one file or in two separate files. The latter feature -allows having arbitrary number of different data sections to be used -with the same model section. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\chapter{Coding model description} -\label{coding} - -The model description is coded in a plain text format using ASCII -character set. Characters valid in the model description are the -following: - -\begin{itemize} -\item alphabetic characters:\\ -\verb|A B C D E F G H I J K L M N O P Q R S T U V W X Y Z|\\ -\verb|a b c d e f g h i j k l m n o p q r s t u v w x y z _| -\item numeric characters:\\ -\verb|0 1 2 3 4 5 6 7 8 9| -\item special characters:\\ -\verb?! " # & ' ( ) * + , - . / : ; < = > [ ] ^ { | } ~? -\item white-space characters:\\ -\verb|SP HT CR NL VT FF| -\end{itemize} - -Within string literals and comments any ASCII characters (except -control characters) are valid. - -White-space characters are non-significant. They can be used freely -between lexical units to improve readability of the model description. -They are also used to separate lexical units from each other if there -is no other way to do that. - -Syntactically model description is a sequence of lexical units in the -following categories: - -\begin{itemize} -\item symbolic names; -\item numeric literals; -\item string literals; -\item keywords; -\item delimiters; -\item comments. -\end{itemize} - -The lexical units of the language are discussed below. - -\newpage - -\section{Symbolic names} - -A {\it symbolic name} consists of alphabetic and numeric characters, -the first of which should be alphabetic. All symbolic names are -distinct (case sensitive). - -\para{Examples} - -\begin{verbatim} -alpha123 -This_is_a_name -_P123_abc_321 -\end{verbatim} - -Symbolic names are used to identify model objects (sets, parameters, -variables, constraints, objectives) and dummy indices. - -All symbolic names (except names of dummy indices) should be unique, -i.e. the model description should have no objects with identical names. -Symbolic names of dummy indices should be unique within the scope, -where they are valid. - -\section{Numeric literals} - -A {\it numeric literal} has the form {\it xx}{\tt E}{\it syy}, where -{\it xx} is a number with optional decimal point, {\it s} is the sign -{\tt+} or {\tt-}, {\it yy} is a decimal exponent. The letter {\tt E} is -case insensitive and can be coded as {\tt e}. - -\para{Examples} - -\begin{verbatim} -123 -3.14159 -56.E+5 -.78 -123.456e-7 -\end{verbatim} - -Numeric literals are used to represent numeric quantities. They have -obvious fixed meaning. - -\section{String literals} - -A {\it string literal} is a sequence of arbitrary characters enclosed -either in single quotes or in double quotes. Both these forms are -equivalent. - -If a single quote is part of a string literal enclosed in single -quotes, it should be coded twice. Analogously, if a double quote is -part of a string literal enclosed in double quotes, it should be coded -twice. - -\para{Examples} - -\begin{verbatim} -'This is a string' -"This is another string" -'That''s all' -"""Hello there,"" said the captain." -\end{verbatim} - -String literals are used to represent symbolic quantities. - -\section{Keywords} - -A {\it keyword} is a sequence of alphabetic characters and possibly -some special characters. - -All keywords fall into two categories: {\it reserved keywords}, which -cannot be used as symbolic names, and {\it non-reserved keywords}, -which are recognized by context and therefore can be used as symbolic -names. - -The reserved keywords are the following: - -\noindent\hfil -\begin{tabular}{@{}p{.7in}p{.7in}p{.7in}p{.7in}@{}} -{\tt and}&{\tt else}&{\tt mod}&{\tt union}\\ -{\tt by}&{\tt if}&{\tt not}&{\tt within}\\ -{\tt cross}&{\tt in}&{\tt or}\\ -{\tt diff}&{\tt inter}&{\tt symdiff}\\ -{\tt div}&{\tt less}&{\tt then}\\ -\end{tabular} - -Non-reserved keywords are described in following sections. - -All the keywords have fixed meaning, which will be explained on -discussion of corresponding syntactic constructions, where the keywords -are used. - -\section{Delimiters} - -A {\it delimiter} is either a single special character or a sequence of -two special characters as follows: - -\noindent\hfil -\begin{tabular}{@{}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in} -p{.3in}p{.3in}@{}} -{\tt+}&{\tt**}&{\tt<=}&{\tt>}&{\tt\&\&}&{\tt:}&{\tt|}&{\tt[}& -{\tt>>}\\ -{\tt-}&{\tt\textasciicircum}&{\tt=}&{\tt<>}&{\tt||}&{\tt;}& -{\tt\char126}&{\tt]}&{\tt<-}\\ -{\tt*}&{\tt\&}&{\tt==}&{\tt!=}&{\tt.}&{\tt:=}&{\tt(}&{\tt\{}\\ -{\tt/}&{\tt<}&{\tt>=}&{\tt!}&{\tt,}&{\tt..}&{\tt)}&{\tt\}}\\ -\end{tabular} - -If the delimiter consists of two characters, there should be no spaces -between the characters. - -All the delimiters have fixed meaning, which will be explained on -discussion corresponding syntactic constructions, where the delimiters -are used. - -\section{Comments} - -For documenting purposes the model description can be provided with -{\it comments}, which may have two different forms. The first form is -a {\it single-line comment}, which begins with the character {\tt\#} -and extends until end of line. The second form is a {\it comment -sequence}, which is a sequence of any characters enclosed within -{\tt/*} and {\tt*/}. - -\para{Examples} - -\begin{verbatim} -param n := 10; # This is a comment -/* This is another comment */ -\end{verbatim} - -Comments are ignored by the model translator and can appear anywhere in -the model description, where white-space characters are allowed. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\chapter{Expressions} - -An {\it expression} is a rule for computing a value. In model -description expressions are used as constituents of certain statements. - -In general case expressions consist of operands and operators. - -Depending on the type of the resultant value all expressions fall into -the following categories: - -\vspace*{-8pt} - -\begin{itemize} -\item numeric expressions; -\item symbolic expressions; -\item indexing expressions; -\item set expressions; -\item logical expressions; -\item linear expressions. -\end{itemize} - -\vspace*{-8pt} - -\section{Numeric expressions} - -A {\it numeric expression} is a rule for computing a single numeric -value represented as a floating-point number. - -The primary numeric expression may be a numeric literal, dummy index, -unsubscripted parameter, subscripted parameter, built-in function -reference, iterated numeric expression, conditional numeric expression, -or another numeric expression enclosed in parentheses. - -\para{Examples} - -\noindent -\begin{tabular}{@{}ll@{}} -\verb|1.23 |&(numeric literal)\\ -\verb|j|&(dummy index)\\ -\verb|time|&(unsubscripted parameter)\\ -\verb|a['May 2003',j+1]|&(subscripted parameter)\\ -\verb|abs(b[i,j])|&(function reference)\\ -\end{tabular} - -\newpage - -\noindent -\begin{tabular}{@{}ll@{}} -\verb|sum{i in S diff T} alpha[i] * b[i,j]|&(iterated expression)\\ -\verb|if i in I then 2 * p else q[i+1]|&(conditional expression)\\ -\verb|(b[i,j] + .5 * c)|&(parenthesized expression)\\ -\end{tabular} - -More general numeric expressions containing two or more primary numeric -expressions may be constructed by using certain arithmetic operators. - -\para{Examples} - -\begin{verbatim} -j+1 -2 * a[i-1,j+1] - b[i,j] -sum{j in J} a[i,j] * x[j] + sum{k in K} b[i,k] * x[k] -(if i in I and p >= 1 then 2 * p else q[i+1]) / (a[i,j] + 1.5) -\end{verbatim} - -\subsection{Numeric literals} - -If the primary numeric expression is a numeric literal, the resultant -value is obvious. - -\subsection{Dummy indices} - -If the primary numeric expression is a dummy index, the resultant value -is current value assigned to that dummy index. - -\subsection{Unsubscripted parameters} - -If the primary numeric expression is an unsubscripted parameter (which -should be 0-dimen\-sional), the resultant value is the value of that -parameter. - -\subsection{Subscripted parameters} - -The primary numeric expression, which refers to a subscripted -parameter, has the following syntactic form: -$$ -\mbox{{\it name}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,} $i_n${\tt]}} -$$ -where {\it name} is the symbolic name of the parameter, $i_1$, $i_2$, -\dots, $i_n$ are subscripts. - -Each subscript should be a numeric or symbolic expression. The number -of subscripts in the subscript list should be the same as the dimension -of the parameter with which the subscript list is associated. - -Actual values of subscript expressions are used to identify -a particular member of the parameter that determines the resultant -value of the primary expression. - -\newpage - -\subsection{Function references} - -In MathProg there exist the following built-in functions which may be -used in numeric expressions: - -\begin{tabular}{@{}p{112pt}p{328pt}@{}} -{\tt abs(}$x${\tt)}&$|x|$, absolute value of $x$\\ -{\tt atan(}$x${\tt)}&$\arctan x$, principal value of the arc tangent of -$x$ (in radians)\\ -{\tt atan(}$y${\tt,} $x${\tt)}&$\arctan y/x$, principal value of the -arc tangent of $y/x$ (in radians). In this case the signs of both -arguments $y$ and $x$ are used to determine the quadrant of the -resultant value\\ -{\tt card(}$X${\tt)}&$|X|$, cardinality (the number of elements) of -set $X$\\ -{\tt ceil(}$x${\tt)}&$\lceil x\rceil$, smallest integer not less than -$x$ (``ceiling of $x$'')\\ -{\tt cos(}$x${\tt)}&$\cos x$, cosine of $x$ (in radians)\\ -{\tt exp(}$x${\tt)}&$e^x$, base-$e$ exponential of $x$\\ -{\tt floor(}$x${\tt)}&$\lfloor x\rfloor$, largest integer not greater -than $x$ (``floor of $x$'')\\ -{\tt gmtime()}&the number of seconds elapsed since 00:00:00~Jan~1, 1970, -Coordinated Universal Time (for details see Section \ref{gmtime}, -page \pageref{gmtime})\\ -{\tt length(}$s${\tt)}&$|s|$, length of character string $s$\\ -{\tt log(}$x${\tt)}&$\log x$, natural logarithm of $x$\\ -{\tt log10(}$x${\tt)}&$\log_{10}x$, common (decimal) logarithm of $x$\\ -{\tt max(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&the largest -of values $x_1$, $x_2$, \dots, $x_n$\\ -{\tt min(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&the smallest -of values $x_1$, $x_2$, \dots, $x_n$\\ -{\tt round(}$x${\tt)}&rounding $x$ to nearest integer\\ -{\tt round(}$x${\tt,} $n${\tt)}&rounding $x$ to $n$ fractional decimal -digits\\ -{\tt sin(}$x${\tt)}&$\sin x$, sine of $x$ (in radians)\\ -{\tt sqrt(}$x${\tt)}&$\sqrt{x}$, non-negative square root of $x$\\ -{\tt str2time(}$s${\tt,} $f${\tt)}&converting character string $s$ to -calendar time (for details see Section \ref{str2time}, page -\pageref{str2time})\\ -{\tt trunc(}$x${\tt)}&truncating $x$ to nearest integer\\ -{\tt trunc(}$x${\tt,} $n${\tt)}&truncating $x$ to $n$ fractional -decimal digits\\ -{\tt Irand224()}&generating pseudo-random integer uniformly distributed -in $[0,2^{24})$\\ -{\tt Uniform01()}&generating pseudo-random number uniformly distributed -in $[0,1)$\\ -{\tt Uniform(}$a${\tt,} $b${\tt)}&generating pseudo-random number -uniformly distributed in $[a,b)$\\ -{\tt Normal01()}&generating Gaussian pseudo-random variate with -$\mu=0$ and $\sigma=1$\\ -{\tt Normal(}$\mu${\tt,} $\sigma${\tt)}&generating Gaussian -pseudo-random variate with given $\mu$ and $\sigma$\\ -\end{tabular} - -Arguments of all built-in functions, except {\tt card}, {\tt length}, -and {\tt str2time}, should be numeric expressions. The argument of -{\tt card} should be a set expression. The argument of {\tt length} and -both arguments of {\tt str2time} should be symbolic expressions. - -The resultant value of the numeric expression, which is a function -reference, is the result of applying the function to its argument(s). - -Note that each pseudo-random generator function has a latent argument -(i.e. some internal state), which is changed whenever the function has -been applied. Thus, if the function is applied repeatedly even to -identical arguments, due to the side effect different resultant values -are always produced. - -\newpage - -\subsection{Iterated expressions} -\label{itexpr} - -An {\it iterated numeric expression} is a primary numeric expression, -which has the following syntactic form: -$$\mbox{\it iterated-operator indexing-expression integrand}$$ -where {\it iterated-operator} is the symbolic name of the iterated -operator to be performed (see below), {\it indexing-expression} is an -indexing expression which introduces dummy indices and controls -iterating, {\it integrand} is a numeric expression that participates in -the operation. - -In MathProg there exist four iterated operators, which may be used in -numeric expressions: - -{\def\arraystretch{2} -\noindent\hfil -\begin{tabular}{@{}lll@{}} -{\tt sum}&summation&$\displaystyle\sum_{(i_1,\dots,i_n)\in\Delta} -f(i_1,\dots,i_n)$\\ -{\tt prod}&production&$\displaystyle\prod_{(i_1,\dots,i_n)\in\Delta} -f(i_1,\dots,i_n)$\\ -{\tt min}&minimum&$\displaystyle\min_{(i_1,\dots,i_n)\in\Delta} -f(i_1,\dots,i_n)$\\ -{\tt max}&maximum&$\displaystyle\max_{(i_1,\dots,i_n)\in\Delta} -f(i_1,\dots,i_n)$\\ -\end{tabular} -} - -\noindent where $i_1$, \dots, $i_n$ are dummy indices introduced in -the indexing expression, $\Delta$ is the domain, a set of $n$-tuples -specified by the indexing expression which defines particular values -assigned to the dummy indices on performing the iterated operation, -$f(i_1,\dots,i_n)$ is the integrand, a numeric expression whose -resultant value depends on the dummy indices. - -The resultant value of an iterated numeric expression is the result of -applying of the iterated operator to its integrand over all $n$-tuples -contained in the domain. - -\subsection{Conditional expressions} -\label{ifthen} - -A {\it conditional numeric expression} is a primary numeric expression, -which has one of the following two syntactic forms: -$$ -{\def\arraystretch{1.4} -\begin{array}{l} -\mbox{{\tt if} $b$ {\tt then} $x$ {\tt else} $y$}\\ -\mbox{{\tt if} $b$ {\tt then} $x$}\\ -\end{array} -} -$$ -where $b$ is an logical expression, $x$ and $y$ are numeric -expressions. - -The resultant value of the conditional expression depends on the value -of the logical expression that follows the keyword {\tt if}. If it -takes on the value {\it true}, the value of the conditional expression -is the value of the expression that follows the keyword {\tt then}. -Otherwise, if the logical expression takes on the value {\it false}, -the value of the conditional expression is the value of the expression -that follows the keyword {\it else}. If the second, reduced form of the -conditional expression is used and the logical expression takes on the -value {\it false}, the resultant value of the conditional expression is -zero. - -\newpage - -\subsection{Parenthesized expressions} - -Any numeric expression may be enclosed in parentheses that -syntactically makes it a primary numeric expression. - -Parentheses may be used in numeric expressions, as in algebra, to -specify the desired order in which operations are to be performed. -Where parentheses are used, the expression within the parentheses is -evaluated before the resultant value is used. - -The resultant value of the parenthesized expression is the same as the -value of the expression enclosed within parentheses. - -\subsection{Arithmetic operators} - -In MathProg there exist the following arithmetic operators, which may -be used in numeric expressions: - -\begin{tabular}{@{}ll@{}} -{\tt +} $x$&unary plus\\ -{\tt -} $x$&unary minus\\ -$x$ {\tt +} $y$&addition\\ -$x$ {\tt -} $y$&subtraction\\ -$x$ {\tt less} $y$&positive difference (if $x1$, the second form should be used. - -If the first form of the indexing entry is used, the index $i$ can be -a dummy index only (see below). If the second form is used, the indices -$i_1$, $i_2$, \dots, $i_n$ can be either dummy indices or some numeric -or symbolic expressions, where at least one index should be a dummy -index. The third, reduced form of the indexing entry has the same -effect as if there were $i$ (if $S$ is 1-dimensional) or -$i_1$, $i_2$, \dots, $i_n$ (if $S$ is $n$-dimensional) all specified as -dummy indices. - -A {\it dummy index} is an auxiliary model object, which acts like an -individual variable. Values assigned to dummy indices are components of -$n$-tuples from basic sets, i.e. some numeric and symbolic quantities. - -For referencing purposes dummy indices can be provided with symbolic -names. However, unlike other model objects (sets, parameters, etc.) -dummy indices need not be explicitly declared. Each {\it undeclared} -symbolic name being used in the indexing position of an indexing entry -is recognized as the symbolic name of corresponding dummy index. - -Symbolic names of dummy indices are valid only within the scope of the -indexing expression, where the dummy indices were introduced. Beyond -the scope the dummy indices are completely inaccessible, so the same -symbolic names may be used for other purposes, in particular, to -represent dummy indices in other indexing expressions. - -The scope of indexing expression, where implicit declarations of dummy -indices are valid, depends on the context, in which the indexing -expression is used: - -\vspace*{-8pt} - -\begin{itemize} -\item If the indexing expression is used in iterated operator, its -scope extends until the end of the integrand. -\item If the indexing expression is used as a primary set expression, -its scope extends until the end of that indexing expression. -\item If the indexing expression is used to define the subscript domain -in declarations of some model objects, its scope extends until the end -of the corresponding statement. -\end{itemize} - -\vspace*{-8pt} - -The indexing mechanism implemented by means of indexing expressions is -best explained by some examples discussed below. - -Let there be given three sets: -$$ -{\def\arraystretch{1.4} -\begin{array}{l} -A=\{4,7,9\},\\ -B=\{(1,Jan),(1,Feb),(2,Mar),(2,Apr),(3,May),(3,Jun)\},\\ -C=\{a,b,c\},\\ -\end{array} -} -$$ -where $A$ and $C$ consist of 1-tuples (singlets), $B$ consists of -2-tuples (doublets). Consider the following indexing expression: -$$\mbox{{\tt\{i in A, (j,k) in B, l in C\}}}$$ -where {\tt i}, {\tt j}, {\tt k}, and {\tt l} are dummy indices. - -\newpage - -Although MathProg is not a procedural language, for any indexing -expression an equivalent algorithmic description can be given. In -particular, the algorithmic description of the indexing expression -above could look like follows: - -\noindent\hfil -\begin{tabular}{@{}l@{}} -{\bf for all} $i\in A$ {\bf do}\\ -\hspace{16pt}{\bf for all} $(j,k)\in B$ {\bf do}\\ -\hspace{32pt}{\bf for all} $l\in C$ {\bf do}\\ -\hspace{48pt}{\it action};\\ -\end{tabular} - -\noindent where the dummy indices $i$, $j$, $k$, $l$ are consecutively -assigned corresponding components of $n$-tuples from the basic sets $A$, -$B$, $C$, and {\it action} is some action that depends on the context, -where the indexing expression is used. For example, if the action were -printing current values of dummy indices, the printout would look like -follows: - -\noindent\hfil -\begin{tabular}{@{}llll@{}} -$i=4$&$j=1$&$k=Jan$&$l=a$\\ -$i=4$&$j=1$&$k=Jan$&$l=b$\\ -$i=4$&$j=1$&$k=Jan$&$l=c$\\ -$i=4$&$j=1$&$k=Feb$&$l=a$\\ -$i=4$&$j=1$&$k=Feb$&$l=b$\\ -\multicolumn{4}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\ -$i=9$&$j=3$&$k=Jun$&$l=b$\\ -$i=9$&$j=3$&$k=Jun$&$l=c$\\ -\end{tabular} - -Let the example indexing expression be used in the following iterated -operation: -$$\mbox{{\tt sum\{i in A, (j,k) in B, l in C\} p[i,j,k,l]}}$$ -where {\tt p} is a 4-dimensional numeric parameter or some numeric -expression whose resultant value depends on {\tt i}, {\tt j}, {\tt k}, -and {\tt l}. In this case the action is summation, so the resultant -value of the primary numeric expression is: -$$\sum_{i\in A,(j,k)\in B,l\in C}(p_{ijkl}).$$ - -Now let the example indexing expression be used as a primary set -expression. In this case the action is gathering all 4-tuples -(quadruplets) of the form $(i,j,k,l)$ in one set, so the resultant -value of such operation is simply the Cartesian product of the basic -sets: -$$A\times B\times C=\{(i,j,k,l):i\in A,(j,k)\in B,l\in C\}.$$ -Note that in this case the same indexing expression might be written in -the reduced form: -$$\mbox{{\tt\{A, B, C\}}}$$ -because the dummy indices $i$, $j$, $k$, and $l$ are not referenced and -therefore their symbolic names need not be specified. - -\newpage - -Finally, let the example indexing expression be used as the subscript -domain in the declaration of a 4-dimensional model object, say, -a numeric parameter: -$$\mbox{{\tt param p\{i in A, (j,k) in B, l in C\}} \dots {\tt;}}$$ - -\noindent In this case the action is generating the parameter members, -where each member has the form $p[i,j,k,l]$. - -As was said above, some indices in the second form of indexing entries -may be numeric or symbolic expressions, not only dummy indices. In this -case resultant values of such expressions play role of some logical -conditions to select only that $n$-tuples from the Cartesian product of -basic sets that satisfy these conditions. - -Consider, for example, the following indexing expression: -$$\mbox{{\tt\{i in A, (i-1,k) in B, l in C\}}}$$ -where {\tt i}, {\tt k}, {\tt l} are dummy indices, and {\tt i-1} is -a numeric expression. The algorithmic decsription of this indexing -expression is the following: - -\noindent\hfil -\begin{tabular}{@{}l@{}} -{\bf for all} $i\in A$ {\bf do}\\ -\hspace{16pt}{\bf for all} $(j,k)\in B$ {\bf and} $j=i-1$ {\bf do}\\ -\hspace{32pt}{\bf for all} $l\in C$ {\bf do}\\ -\hspace{48pt}{\it action};\\ -\end{tabular} - -\noindent Thus, if this indexing expression were used as a primary set -expression, the resultant set would be the following: -$$\{(4,May,a),(4,May,b),(4,May,c),(4,Jun,a),(4,Jun,b),(4,Jun,c)\}.$$ -Should note that in this case the resultant set consists of 3-tuples, -not of 4-tuples, because in the indexing expression there is no dummy -index that corresponds to the first component of 2-tuples from the set -$B$. - -The general rule is: the number of components of $n$-tuples defined by -an indexing expression is the same as the number of dummy indices in -that expression, where the correspondence between dummy indices and -components on $n$-tuples in the resultant set is positional, i.e. the -first dummy index corresponds to the first component, the second dummy -index corresponds to the second component, etc. - -In some cases it is needed to select a subset from the Cartesian -product of some sets. This may be attained by using an optional logical -predicate, which is specified in the indexing expression. - -Consider, for example, the following indexing expression: -$$\mbox{{\tt\{i in A, (j,k) in B, l in C: i <= 5 and k <> 'Mar'\}}}$$ -where the logical expression following the colon is a predicate. The -algorithmic description of this indexing expression is the following: - -\noindent\hfil -\begin{tabular}{@{}l@{}} -{\bf for all} $i\in A$ {\bf do}\\ -\hspace{16pt}{\bf for all} $(j,k)\in B$ {\bf do}\\ -\hspace{32pt}{\bf for all} $l\in C$ {\bf do}\\ -\hspace{48pt}{\bf if} $i\leq 5$ {\bf and} $k\neq`Mar'$ {\bf then}\\ -\hspace{64pt}{\it action};\\ -\end{tabular} - -\noindent Thus, if this indexing expression were used as a primary set -expression, the resultant set would be the following: -$$\{(4,1,Jan,a),(4,1,Feb,a),(4,2,Apr,a),\dots,(4,3,Jun,c)\}.$$ - -If no predicate is specified in the indexing expression, one, which -takes on the value {\it true}, is assumed. - -\section{Set expressions} - -A {\it set expression} is a rule for computing an elemental set, i.e. -a collection of $n$-tuples, where components of $n$-tuples are numeric -and symbolic quantities. - -The primary set expression may be a literal set, unsubscripted set, -subscripted set, ``arithmetic'' set, indexing expression, iterated set -expression, conditional set expression, or another set expression -enclosed in parentheses. - -\para{Examples} - -\noindent -\begin{tabular}{@{}ll@{}} -\verb|{(123,'aaa'), (i+1,'bbb'), (j-1,'ccc')}| &(literal set)\\ -\verb|I| &(unsubscripted set)\\ -\verb|S[i-1,j+1]| &(subscripted set)\\ -\verb|1..t-1 by 2| &(``arithmetic'' set)\\ -\verb|{t in 1..T, (t+1,j) in S: (t,j) in F}| &(indexing expression)\\ -\verb|setof{i in I, j in J}(i+1,j-1)| &(iterated set expression)\\ -\verb|if i < j then S[i,j] else F diff S[i,j]| &(conditional set -expression)\\ -\verb|(1..10 union 21..30)| &(parenthesized set expression)\\ -\end{tabular} - -More general set expressions containing two or more primary set -expressions may be constructed by using certain set operators. - -\para{Examples} - -\begin{verbatim} -(A union B) inter (I cross J) -1..10 cross (if i < j then {'a', 'b', 'c'} else {'d', 'e', 'f'}) -\end{verbatim} - -\subsection{Literal sets} - -A {\it literal set} is a primary set expression, which has the -following two syntactic forms: -$$ -{\def\arraystretch{1.4} -\begin{array}{l} -\mbox{{\tt\{}$e_1${\tt,} $e_2${\tt,} \dots{\tt,} $e_m${\tt\}}}\\ -\mbox{{\tt\{(}$e_{11}${\tt,} \dots{\tt,} $e_{1n}${\tt),} -{\tt(}$e_{21}${\tt,} \dots{\tt,} $e_{2n}${\tt),} \dots{\tt,} -{\tt(}$e_{m1}${\tt,} \dots{\tt,} $e_{mn}${\tt)\}}}\\ -\end{array} -} -$$ -where $e_1$, \dots, $e_m$, $e_{11}$, \dots, $e_{mn}$ are numeric or -symbolic expressions. - -If the first form is used, the resultant set consists of 1-tuples -(singlets) enumerated within the curly braces. It is allowed to specify -an empty set as {\tt\{\ \}}, which has no 1-tuples. If the second form -is used, the resultant set consists of $n$-tuples enumerated within the -curly braces, where a particular $n$-tuple consists of corresponding -components enumerated within the parentheses. All $n$-tuples should -have the same number of components. - -\subsection{Unsubscripted sets} - -If the primary set expression is an unsubscripted set (which should be -0-dimen\-sional), the resultant set is an elemental set associated with -the corresponding set object. - -\subsection{Subscripted sets} - -The primary set expression, which refers to a subscripted set, has the -following syntactic form: -$$\mbox{{\it name}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,} -$i_n${\tt]}}$$ -where {\it name} is the symbolic name of the set object, $i_1$, $i_2$, -\dots, $i_n$ are subscripts. - -Each subscript should be a numeric or symbolic expression. The number -of subscripts in the subscript list should be the same as the dimension -of the set object with which the subscript list is associated. - -Actual values of subscript expressions are used to identify a -particular member of the set object that determines the resultant set. - -\subsection{``Arithmetic'' sets} - -The primary set expression, which is an ``arithmetic'' set, has the -following two syntactic forms: -$$ -{\def\arraystretch{1.4} -\begin{array}{l} -\mbox{$t_0$ {\tt..} $t_1$ {\tt by} $\delta t$}\\ -\mbox{$t_0$ {\tt..} $t_1$}\\ -\end{array} -} -$$ -where $t_0$, $t_1$, and $\delta t$ are numeric expressions (the value -of $\delta t$ should not be zero). The second form is equivalent to the -first form, where $\delta t=1$. - -If $\delta t>0$, the resultant set is determined as follows: -$$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_0\leq t\leq t_1)\}.$$ -Otherwise, if $\delta t<0$, the resultant set is determined as follows: -$$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_1\leq t\leq t_0)\}.$$ - -\subsection{Indexing expressions} - -If the primary set expression is an indexing expression, the resultant -set is determined as described above in Section \ref{indexing}, page -\pageref{indexing}. - -\newpage - -\subsection{Iterated expressions} - -An {\it iterated set expression} is a primary set expression, which has -the following syntactic form: -$$\mbox{{\tt setof} {\it indexing-expression} {\it integrand}}$$ -where {\it indexing-expression} is an indexing expression, which -introduces dummy indices and controls iterating, {\it integrand} is -either a single numeric or symbolic expression or a list of numeric and -symbolic expressions separated by commae and enclosed in parentheses. - -If the integrand is a single numeric or symbolic expression, the -resultant set consists of 1-tuples and is determined as follows: -$$\{x:(i_1,\dots,i_n)\in\Delta\},$$ -\noindent where $x$ is a value of the integrand, $i_1$, \dots, $i_n$ -are dummy indices introduced in the indexing expression, $\Delta$ is -the domain, a set of $n$-tuples specified by the indexing expression, -which defines particular values assigned to the dummy indices on -performing the iterated operation. - -If the integrand is a list containing $m$ numeric and symbolic -expressions, the resultant set consists of $m$-tuples and is determined -as follows: -$$\{(x_1,\dots,x_m):(i_1,\dots,i_n)\in\Delta\},$$ -where $x_1$, \dots, $x_m$ are values of the expressions in the -integrand list, $i_1$, \dots, $i_n$ and $\Delta$ have the same meaning -as above. - -\subsection{Conditional expressions} - -A {\it conditional set expression} is a primary set expression that has -the following syntactic form: -$$\mbox{{\tt if} $b$ {\tt then} $X$ {\tt else} $Y$}$$ -where $b$ is an logical expression, $X$ and $Y$ are set expressions, -which should define sets of the same dimension. - -The resultant value of the conditional expression depends on the value -of the logical expression that follows the keyword {\tt if}. If it -takes on the value {\it true}, the resultant set is the value of the -expression that follows the keyword {\tt then}. Otherwise, if the -logical expression takes on the value {\it false}, the resultant set is -the value of the expression that follows the keyword {\tt else}. - -\subsection{Parenthesized expressions} - -Any set expression may be enclosed in parentheses that syntactically -makes it a primary set expression. - -Parentheses may be used in set expressions, as in algebra, to specify -the desired order in which operations are to be performed. Where -parentheses are used, the expression within the parentheses is -evaluated before the resultant value is used. - -The resultant value of the parenthesized expression is the same as the -value of the expression enclosed within parentheses. - -\newpage - -\subsection{Set operators} - -In MathProg there exist the following set operators, which may be used -in set expressions: - -\begin{tabular}{@{}ll@{}} -$X$ {\tt union} $Y$&union $X\cup Y$\\ -$X$ {\tt diff} $Y$&difference $X\backslash Y$\\ -$X$ {\tt symdiff} $Y$&symmetric difference -$X\oplus Y=(X\backslash Y)\cup(Y\backslash X)$\\ -$X$ {\tt inter} $Y$&intersection $X\cap Y$\\ -$X$ {\tt cross} $Y$&cross (Cartesian) product $X\times Y$\\ -\end{tabular} - -\noindent where $X$ and Y are set expressions, which should define sets -of identical dimension (except the Cartesian product). - -If the expression includes more than one set operator, all operators -are performed from left to right according to the hierarchy of -operations (see below). - -The resultant value of the expression, which contains set operators, is -the result of applying the operators to their operands. - -The dimension of the resultant set, i.e. the dimension of $n$-tuples, -of which the resultant set consists of, is the same as the dimension of -the operands, except the Cartesian product, where the dimension of the -resultant set is the sum of the dimensions of its operands. - -\subsection{Hierarchy of operations} - -The following list shows the hierarchy of operations in set -expressions: - -\noindent\hfil -\begin{tabular}{@{}ll@{}} -Operation&Hierarchy\\ -\hline -Evaluation of numeric operations&1st-7th\\ -Evaluation of symbolic operations&8th-9th\\ -Evaluation of iterated or ``arithmetic'' set ({\tt setof}, {\tt..})& -10th\\ -Cartesian product ({\tt cross})&11th\\ -Intersection ({\tt inter})&12th\\ -Union and difference ({\tt union}, {\tt diff}, {\tt symdiff})&13th\\ -Conditional evaluation ({\tt if} \dots {\tt then} \dots {\tt else})& -14th\\ -\end{tabular} - -This hierarchy has the same meaning as was explained above for numeric -expressions (see Subsection \ref{hierarchy}, page \pageref{hierarchy}). - -\newpage - -\section{Logical expressions} - -A {\it logical expression} is a rule for computing a single logical -value, which can be either {\it true} or {\it false}. - -The primary logical expression may be a numeric expression, relational -expression, iterated logical expression, or another logical expression -enclosed in parentheses. - -\para{Examples} - -\noindent -\begin{tabular}{@{}ll@{}} -\verb|i+1| &(numeric expression)\\ -\verb|a[i,j] < 1.5| &(relational expression)\\ -\verb|s[i+1,j-1] <> 'Mar' & year | &(relational expression)\\ -\verb|(i+1,'Jan') not in I cross J| &(relational expression)\\ -\verb|S union T within A[i] inter B[j]| &(relational expression)\\ -\verb|forall{i in I, j in J} a[i,j] < .5 * b[i]| &(iterated logical -expression)\\ -\verb|(a[i,j] < 1.5 or b[i] >= a[i,j])| &(parenthesized logical -expression)\\ -\end{tabular} - -More general logical expressions containing two or more primary logical -expressions may be constructed by using certain logical operators. - -\para{Examples} - -\begin{verbatim} -not (a[i,j] < 1.5 or b[i] >= a[i,j]) and (i,j) in S -(i,j) in S or (i,j) not in T diff U -\end{verbatim} - -\vspace*{-8pt} - -\subsection{Numeric expressions} - -The resultant value of the primary logical expression, which is a -numeric expression, is {\it true}, if the resultant value of the -numeric expression is non-zero. Otherwise the resultant value of the -logical expression is {\it false}. - -\vspace*{-8pt} - -\subsection{Relational operators} - -In MathProg there exist the following relational operators, which may -be used in logical expressions: - -\begin{tabular}{@{}ll@{}} -$x$ {\tt<} $y$&test on $x=} $y$&test on $x\geq y$\\ -$x$ {\tt>} $y$&test on $x>y$\\ -$x$ {\tt<>} $y$, $x$ {\tt!=} $y$&test on $x\neq y$\\ -$x$ {\tt in} $Y$&test on $x\in Y$\\ -{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt in} $Y$&test on -$(x_1,\dots,x_n)\in Y$\\ -$x$ {\tt not} {\tt in} $Y$, $x$ {\tt!in} $Y$&test on $x\not\in Y$\\ -{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt not} {\tt in} $Y$, -{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt !in} $Y$&test on -$(x_1,\dots,x_n)\not\in Y$\\ -$X$ {\tt within} $Y$&test on $X\subseteq Y$\\ -$X$ {\tt not} {\tt within} $Y$, $X$ {\tt !within} $Y$&test on -$X\not\subseteq Y$\\ -\end{tabular} - -\noindent where $x$, $x_1$, \dots, $x_n$, $y$ are numeric or symbolic -expressions, $X$ and $Y$ are set expression. - -\newpage - -1. In the operations {\tt in}, {\tt not in}, and {\tt !in} the -number of components in the first operands should be the same as the -dimension of the second operand. - -2. In the operations {\tt within}, {\tt not within}, and {\tt !within} -both operands should have identical dimension. - -All the relational operators listed above have their conventional -mathematical meaning. The resultant value is {\it true}, if -corresponding relation is satisfied for its operands, otherwise -{\it false}. (Note that symbolic values are ordered lexicographically, -and any numeric value precedes any symbolic value.) - -\subsection{Iterated expressions} - -An {\it iterated logical expression} is a primary logical expression, -which has the following syntactic form: -$$\mbox{{\it iterated-operator} {\it indexing-expression} -{\it integrand}}$$ -where {\it iterated-operator} is the symbolic name of the iterated -operator to be performed (see below), {\it indexing-expression} is an -indexing expression which introduces dummy indices and controls -iterating, {\it integrand} is a numeric expression that participates in -the operation. - -In MathProg there exist two iterated operators, which may be used in -logical expressions: - -{\def\arraystretch{1.4} -\noindent\hfil -\begin{tabular}{@{}lll@{}} -{\tt forall}&$\forall$-quantification&$\displaystyle -\forall(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\ -{\tt exists}&$\exists$-quantification&$\displaystyle -\exists(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\ -\end{tabular} -} - -\noindent where $i_1$, \dots, $i_n$ are dummy indices introduced in -the indexing expression, $\Delta$ is the domain, a set of $n$-tuples -specified by the indexing expression which defines particular values -assigned to the dummy indices on performing the iterated operation, -$f(i_1,\dots,i_n)$ is the integrand, a logical expression whose -resultant value depends on the dummy indices. - -For $\forall$-quantification the resultant value of the iterated -logical expression is {\it true}, if the value of the integrand is -{\it true} for all $n$-tuples contained in the domain, otherwise -{\it false}. - -For $\exists$-quantification the resultant value of the iterated -logical expression is {\it false}, if the value of the integrand is -{\it false} for all $n$-tuples contained in the domain, otherwise -{\it true}. - -\subsection{Parenthesized expressions} - -Any logical expression may be enclosed in parentheses that -syntactically makes it a primary logical expression. - -Parentheses may be used in logical expressions, as in algebra, to -specify the desired order in which operations are to be performed. -Where parentheses are used, the expression within the parentheses is -evaluated before the resultant value is used. - -The resultant value of the parenthesized expression is the same as the -value of the expression enclosed within parentheses. - -\newpage - -\subsection{Logical operators} - -In MathProg there exist the following logical operators, which may be -used in logical expressions: - -\begin{tabular}{@{}ll@{}} -{\tt not} $x$, {\tt!}$x$&negation $\neg\ x$\\ -$x$ {\tt and} $y$, $x$ {\tt\&\&} $y$&conjunction (logical ``and'') -$x\;\&\;y$\\ -$x$ {\tt or} $y$, $x$ {\tt||} $y$&disjunction (logical ``or'') -$x\vee y$\\ -\end{tabular} - -\noindent where $x$ and $y$ are logical expressions. - -If the expression includes more than one logical operator, all -operators are performed from left to right according to the hierarchy -of the operations (see below). The resultant value of the expression, -which contains logical operators, is the result of applying the -operators to their operands. - -\subsection{Hierarchy of operations} - -The following list shows the hierarchy of operations in logical -expressions: - -\noindent\hfil -\begin{tabular}{@{}ll@{}} -Operation&Hierarchy\\ -\hline -Evaluation of numeric operations&1st-7th\\ -Evaluation of symbolic operations&8th-9th\\ -Evaluation of set operations&10th-14th\\ -Relational operations ({\tt<}, {\tt<=}, etc.)&15th\\ -Negation ({\tt not}, {\tt!})&16th\\ -Conjunction ({\tt and}, {\tt\&\&})&17th\\ -$\forall$- and $\exists$-quantification ({\tt forall}, {\tt exists})& -18th\\ -Disjunction ({\tt or}, {\tt||})&19th\\ -\end{tabular} - -This hierarchy has the same meaning as was explained above for numeric -expressions (see Subsection \ref{hierarchy}, page \pageref{hierarchy}). - -\section{Linear expressions} - -An {\it linear expression} is a rule for computing so called -a {\it linear form} or simply a {\it formula}, which is a linear (or -affine) function of elemental variables. - -The primary linear expression may be an unsubscripted variable, -subscripted variable, iterated linear expression, conditional linear -expression, or another linear expression enclosed in parentheses. - -It is also allowed to use a numeric expression as the primary linear -expression, in which case the resultant value of the numeric expression -is automatically converted to a formula that includes the constant term -only. - -\para{Examples} - -\noindent -\begin{tabular}{@{}ll@{}} -\verb|z| &(unsubscripted variable)\\ -\verb|x[i,j]| &(subscripted variable)\\ -\verb|sum{j in J} (a[i,j] * x[i,j] + 3 * y[i-1])| & -(iterated linear expression)\\ -\verb|if i in I then x[i,j] else 1.5 * z + 3.25| & -(conditional linear expression)\\ -\verb|(a[i,j] * x[i,j] + y[i-1] + .1)| & -(parenthesized linear expression)\\ -\end{tabular} - -More general linear expressions containing two or more primary linear -expressions may be constructed by using certain arithmetic operators. - -\para{Examples} - -\begin{verbatim} -2 * x[i-1,j+1] + 3.5 * y[k] + .5 * z -(- x[i,j] + 3.5 * y[k]) / sum{t in T} abs(d[i,j,t]) -\end{verbatim} - -\vspace*{-5pt} - -\subsection{Unsubscripted variables} - -If the primary linear expression is an unsubscripted variable (which -should be 0-dimensional), the resultant formula is that unsubscripted -variable. - -\vspace*{-5pt} - -\subsection{Subscripted variables} - -The primary linear expression, which refers to a subscripted variable, -has the following syntactic form: -$$\mbox{{\it name}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,} -$i_n${\tt]}}$$ -where {\it name} is the symbolic name of the model variable, $i_1$, -$i_2$, \dots, $i_n$ are subscripts. - -Each subscript should be a numeric or symbolic expression. The number -of subscripts in the subscript list should be the same as the dimension -of the model variable with which the subscript list is associated. - -Actual values of the subscript expressions are used to identify a -particular member of the model variable that determines the resultant -formula, which is an elemental variable associated with corresponding -member. - -\vspace*{-5pt} - -\subsection{Iterated expressions} - -An {\it iterated linear expression} is a primary linear expression, -which has the following syntactic form: -$$\mbox{{\tt sum} {\it indexing-expression} {\it integrand}}$$ -where {\it indexing-expression} is an indexing expression, which -introduces dummy indices and controls iterating, {\it integrand} is -a linear expression that participates in the operation. - -The iterated linear expression is evaluated exactly in the same way as -the iterated numeric expression (see Subection \ref{itexpr}, page -\pageref{itexpr}) with exception that the integrand participated in the -summation is a formula, not a numeric value. - -\vspace*{-5pt} - -\subsection{Conditional expressions} - -A {\it conditional linear expression} is a primary linear expression, -which has one of the following two syntactic forms: -$$ -{\def\arraystretch{1.4} -\begin{array}{l} -\mbox{{\tt if} $b$ {\tt then} $f$ {\tt else} $g$}\\ -\mbox{{\tt if} $b$ {\tt then} $f$}\\ -\end{array} -} -$$ -where $b$ is an logical expression, $f$ and $g$ are linear expressions. - -\newpage - -The conditional linear expression is evaluated exactly in the same way -as the conditional numeric expression (see Subsection \ref{ifthen}, -page \pageref{ifthen}) with exception that operands participated in the -operation are formulae, not numeric values. - -\subsection{Parenthesized expressions} - -Any linear expression may be enclosed in parentheses that syntactically -makes it a primary linear expression. - -Parentheses may be used in linear expressions, as in algebra, to -specify the desired order in which operations are to be performed. -Where parentheses are used, the expression within the parentheses is -evaluated before the resultant formula is used. - -The resultant value of the parenthesized expression is the same as the -value of the expression enclosed within parentheses. - -\subsection{Arithmetic operators} - -In MathProg there exists the following arithmetic operators, which may -be used in linear expressions: - -\begin{tabular}{@{}ll@{}} -{\tt+} $f$&unary plus\\ -{\tt-} $f$&unary minus\\ -$f$ {\tt+} $g$&addition\\ -$f$ {\tt-} $g$&subtraction\\ -$x$ {\tt*} $f$, $f$ {\tt*} $x$&multiplication\\ -$f$ {\tt/} $x$&division -\end{tabular} - -\noindent where $f$ and $g$ are linear expressions, $x$ is a numeric -expression (more precisely, a linear expression containing only the -constant term). - -If the expression includes more than one arithmetic operator, all -operators are performed from left to right according to the hierarchy -of operations (see below). The resultant value of the expression, which -contains arithmetic operators, is the result of applying the operators -to their operands. - -\subsection{Hierarchy of operations} - -The hierarchy of arithmetic operations used in linear expressions is -the same as for numeric expressions (see Subsection \ref{hierarchy}, -page \pageref{hierarchy}). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\chapter{Statements} - -{\it Statements} are basic units of the model description. In MathProg -all statements are divided into two categories: declaration statements -and functional statements. - -{\it Declaration statements} (set statement, parameter statement, -variable statement, constraint statement, objective statement) are used -to declare model objects of certain kinds and define certain properties -of such objects. - -{\it Functional statements} (solve statement, check statement, display -statement, printf statement, loop statement, table statement) are -intended for performing some specific actions. - -Note that declaration statements may follow in arbitrary order, which -does not affect the result of translation. However, any model object -should be declared before it is referenced in other statements. - -\section{Set statement} - -\noindent -\framebox[468pt][l]{ -\parbox[c][24pt]{468pt}{ -\hspace{6pt} {\tt set} {\it name} {\it alias} {\it domain} {\tt,} -{\it attrib} {\tt,} \dots {\tt,} {\it attrib} {\tt;} -}} - -\medskip - -\noindent -{\it name} is a symbolic name of the set; - -\noindent -{\it alias} is an optional string literal, which specifies an alias of -the set; - -\noindent -{\it domain} is an optional indexing expression, which specifies -a subscript domain of the set; - -\noindent -{\it attrib}, \dots, {\it attrib} are optional attributes of the set. -(Commae preceding attributes may be omitted.) - -\para{Optional attributes} - -\vspace*{-8pt} - -\begin{description} -\item[{\tt dimen} $n$]\hspace*{0pt}\\ -specifies the dimension of $n$-tuples which the set consists of; -\item[{\tt within} {\it expression}]\hspace*{0pt}\\ -specifies a superset which restricts the set or all its members -(elemental sets) to be within that superset; -\item[{\tt:=} {\it expression}]\hspace*{0pt}\\ -specifies an elemental set assigned to the set or its members; -\item[{\tt default} {\it expression}]\hspace*{0pt}\\ -specifies an elemental set assigned to the set or its members whenever -no appropriate data are available in the data section. -\end{description} - -\vspace*{-8pt} - -\para{Examples} - -\begin{verbatim} -set nodes; -set arcs within nodes cross nodes; -set step{s in 1..maxiter} dimen 2 := if s = 1 then arcs else step[s-1] - union setof{k in nodes, (i,k) in step[s-1], (k,j) in step[s-1]}(i,j); -set A{i in I, j in J}, within B[i+1] cross C[j-1], within D diff E, - default {('abc',123), (321,'cba')}; -\end{verbatim} - -The set statement declares a set. If the subscript domain is not -specified, the set is a simple set, otherwise it is an array of -elemental sets. - -The {\tt dimen} attribute specifies the dimension of $n$-tuples, which -the set (if it is a simple set) or its members (if the set is an array -of elemental sets) consist of, where $n$ should be an unsigned integer -from 1 to 20. At most one {\tt dimen} attribute can be specified. If -the {\tt dimen} attribute is not specified, the dimension of $n$-tuples -is implicitly determined by other attributes (for example, if there is -a set expression that follows {\tt:=} or the keyword {\tt default}, the -dimension of $n$-tuples of corresponding elemental set is used). -If no dimension information is available, {\tt dimen 1} is assumed. - -The {\tt within} attribute specifies a set expression whose resultant -value is a superset used to restrict the set (if it is a simple set) or -its members (if the set is an array of elemental sets) to be within -that superset. Arbitrary number of {\tt within} attributes may be -specified in the same set statement. - -The assign ({\tt:=}) attribute specifies a set expression used to -evaluate elemental set(s) assigned to the set (if it is a simple set) -or its members (if the set is an array of elemental sets). If the -assign attribute is specified, the set is {\it computable} and -therefore needs no data to be provided in the data section. If the -assign attribute is not specified, the set should be provided with data -in the data section. At most one assign or default attribute can be -specified for the same set. - -The {\tt default} attribute specifies a set expression used to evaluate -elemental set(s) assigned to the set (if it is a simple set) or its -members (if the set is an array of elemental sets) whenever -no appropriate data are available in the data section. If neither -assign nor default attribute is specified, missing data will cause an -error. - -\newpage - -\section{Parameter statement} - -\noindent -\framebox[468pt][l]{ -\parbox[c][24pt]{468pt}{ -\hspace{6pt} {\tt param} {\it name} {\it alias} {\it domain} {\tt,} -{\it attrib} {\tt,} \dots {\tt,} {\it attrib} {\tt;} -}} - -\medskip - -\noindent -{\it name} is a symbolic name of the parameter; - -\noindent -{\it alias} is an optional string literal, which specifies an alias of -the parameter; - -\noindent -{\it domain} is an optional indexing expression, which specifies -a subscript domain of the parameter; - -\noindent -{\it attrib}, \dots, {\it attrib} are optional attributes of the -parameter. (Commae preceding attributes may be omitted.) - -\para{Optional attributes} - -\vspace*{-8pt} - -\begin{description} -\item[{\tt integer}]\hspace*{0pt}\\ -specifies that the parameter is integer; -\item[{\tt binary}]\hspace*{0pt}\\ -specifies that the parameter is binary; -\item[{\tt symbolic}]\hspace*{0pt}\\ -specifies that the parameter is symbolic; -\item[{\it relation expression}]\hspace*{0pt}\\ -(where {\it relation} is one of: {\tt<}, {\tt<=}, {\tt=}, {\tt==}, -{\tt>=}, {\tt>}, {\tt<>}, {\tt!=})\\ -specifies a condition that restricts the parameter or its members to -satisfy that condition; -\item[{\tt in} {\it expression}]\hspace*{0pt}\\ -specifies a superset that restricts the parameter or its members to be -in that superset; -\item[{\tt:=} {\it expression}]\hspace*{0pt}\\ -specifies a value assigned to the parameter or its members; -\item[{\tt default} {\it expression}]\hspace*{0pt}\\ -specifies a value assigned to the parameter or its members whenever -no appropriate data are available in the data section. -\end{description} - -\vspace*{-8pt} - -\para{Examples} - -\begin{verbatim} -param units{raw, prd} >= 0; -param profit{prd, 1..T+1}; -param N := 20 integer >= 0 <= 100; -param comb 'n choose k' {n in 0..N, k in 0..n} := - if k = 0 or k = n then 1 else comb[n-1,k-1] + comb[n-1,k]; -param p{i in I, j in J}, integer, >= 0, <= i+j, in A[i] symdiff B[j], - in C[i,j], default 0.5 * (i + j); -param month symbolic default 'May' in {'Mar', 'Apr', 'May'}; -\end{verbatim} - -The parameter statement declares a parameter. If a subscript domain is -not specified, the parameter is a simple (scalar) parameter, otherwise -it is a $n$-dimensional array. - -The type attributes {\tt integer}, {\tt binary}, and {\tt symbolic} -qualify the type of values that can be assigned to the parameter as -shown below: - -\noindent\hfil -\begin{tabular}{@{}ll@{}} -Type attribute&Assigned values\\ -\hline -(not specified)&Any numeric values\\ -{\tt integer}&Only integer numeric values\\ -{\tt binary}&Either 0 or 1\\ -{\tt symbolic}&Any numeric and symbolic values\\ -\end{tabular} - -The {\tt symbolic} attribute cannot be specified along with other type -attributes. Being specified it should precede all other attributes. - -The condition attribute specifies an optional condition that restricts -values assigned to the parameter to satisfy that condition. This -attribute has the following syntactic forms: - -\begin{tabular}{@{}ll@{}} -{\tt<} $v$&check for $x=} $v$&check for $x\geq v$\\ -{\tt>} $v$&check for $x\geq v$\\ -{\tt<>} $v$, {\tt!=} $v$&check for $x\neq v$\\ -\end{tabular} - -\noindent where $x$ is a value assigned to the parameter, $v$ is the -resultant value of a numeric or symbolic expression specified in the -condition attribute. Arbitrary number of condition attributes can be -specified for the same parameter. If a value being assigned to the -parameter during model evaluation violates at least one of specified -conditions, an error is raised. (Note that symbolic values are ordered -lexicographically, and any numeric value precedes any symbolic value.) - -The {\tt in} attribute is similar to the condition attribute and -specifies a set expression whose resultant value is a superset used to -restrict numeric or symbolic values assigned to the parameter to be in -that superset. Arbitrary number of the {\tt in} attributes can be -specified for the same parameter. If a value being assigned to the -parameter during model evaluation is not in at least one of specified -supersets, an error is raised. - -The assign ({\tt:=}) attribute specifies a numeric or symbolic -expression used to compute a value assigned to the parameter (if it is -a simple parameter) or its member (if the parameter is an array). If -the assign attribute is specified, the parameter is {\it computable} -and therefore needs no data to be provided in the data section. If the -assign attribute is not specified, the parameter should be provided -with data in the data section. At most one assign or {\tt default} -attribute can be specified for the same parameter. - -The {\tt default} attribute specifies a numeric or symbolic expression -used to compute a value assigned to the parameter or its member -whenever no appropriate data are available in the data section. If -neither assign nor {\tt default} attribute is specified, missing data -will cause an error. - -\newpage - -\section{Variable statement} - -\noindent -\framebox[468pt][l]{ -\parbox[c][24pt]{468pt}{ -\hspace{6pt} {\tt var} {\it name} {\it alias} {\it domain} {\tt,} -{\it attrib} {\tt,} \dots {\tt,} {\it attrib} {\tt;} -}} - -\medskip - -\noindent -{\it name} is a symbolic name of the variable; - -\noindent -{\it alias} is an optional string literal, which specifies an alias of -the variable; - -\noindent -{\it domain} is an optional indexing expression, which specifies -a subscript domain of the variable; - -\noindent -{\it attrib}, \dots, {\it attrib} are optional attributes of the -variable. (Commae preceding attributes may be omitted.) - -\para{Optional attributes} - -\vspace*{-8pt} - -\begin{description} -\item[{\tt integer}]\hspace*{0pt}\\ -restricts the variable to be integer; -\item[{\tt binary}]\hspace*{0pt}\\ -restricts the variable to be binary; -\item[{\tt>=} {\it expression}]\hspace*{0pt}\\ -specifies an lower bound of the variable; -\item[{\tt<=} {\it expression}]\hspace*{0pt}\\ -specifies an upper bound of the variable; -\item[{\tt=} {\it expression}]\hspace*{0pt}\\ -specifies a fixed value of the variable; -\end{description} - -\vspace*{-8pt} - -\para{Examples} - -\begin{verbatim} -var x >= 0; -var y{I,J}; -var make{p in prd}, integer, >= commit[p], <= market[p]; -var store{raw, 1..T+1} >= 0; -var z{i in I, j in J} >= i+j; -\end{verbatim} - -The variable statement declares a variable. If a subscript domain is -not specified, the variable is a simple (scalar) variable, otherwise it -is a $n$-dimensional array of elemental variables. - -Elemental variable(s) associated with the model variable (if it is a -simple variable) or its members (if it is an array) correspond to the -variables in the LP/MIP problem formulation (see Section \ref{problem}, -page \pageref{problem}). Note that only elemental variables actually -referenced in some constraints and/or objectives are included in the -LP/MIP problem instance to be generated. - -The type attributes {\tt integer} and {\tt binary} restrict the -variable to be integer or binary, respectively. If no type attribute is -specified, the variable is continuous. If all variables in the model -are continuous, the corresponding problem is of LP class. If there is -at least one integer or binary variable, the problem is of MIP class. - -The lower bound ({\tt>=}) attribute specifies a numeric expression for -computing an lower bound of the variable. At most one lower bound can -be specified. By default all variables (except binary ones) have no -lower bound, so if a variable is required to be non-negative, its zero -lower bound should be explicitly specified. - -The upper bound ({\tt<=}) attribute specifies a numeric expression for -computing an upper bound of the variable. At most one upper bound -attribute can be specified. - -The fixed value ({\tt=}) attribute specifies a numeric expression for -computing a value, at which the variable is fixed. This attribute -cannot be specified along with the bound attributes. - -\section{Constraint statement} - -\noindent -\framebox[468pt][l]{ -\parbox[c][106pt]{468pt}{ -\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:} -{\it expression} {\tt,} {\tt=} {\it expression} {\tt;} - -\medskip - -\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:} -{\it expression} {\tt,} {\tt<=} {\it expression} {\tt;} - -\medskip - -\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:} -{\it expression} {\tt,} {\tt>=} {\it expression} {\tt;} - -\medskip - -\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:} -{\it expression} {\tt,} {\tt<=} {\it expression} {\tt,} {\tt<=} -{\it expression} {\tt;} - -\medskip - -\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:} -{\it expression} {\tt,} {\tt>=} {\it expression} {\tt,} {\tt>=} -{\it expression} {\tt;} -}} - -\medskip - -\noindent -{\it name} is a symbolic name of the constraint; - -\noindent -{\it alias} is an optional string literal, which specifies an alias of -the constraint; - -\noindent -{\it domain} is an optional indexing expression, which specifies -a subscript domain of the constraint; - -\noindent -{\it expression} is a linear expression used to compute a component of -the constraint. (Commae following expressions may be omitted.) - -\noindent -(The keyword {\tt s.t.} may be written as {\tt subject to} or as -{\tt subj to}, or may be omitted at all.) - -\para{Examples} - -\begin{verbatim} -s.t. r: x + y + z, >= 0, <= 1; -limit{t in 1..T}: sum{j in prd} make[j,t] <= max_prd; -subject to balance{i in raw, t in 1..T}: - store[i,t+1] - store[i,t] - sum{j in prd} units[i,j] * make[j,t]; -subject to rlim 'regular-time limit' {t in time}: - sum{p in prd} pt[p] * rprd[p,t] <= 1.3 * dpp[t] * crews[t]; -\end{verbatim} - -The constraint statement declares a constraint. If a subscript domain -is not specified, the\linebreak constraint is a simple (scalar) -constraint, otherwise it is a $n$-dimensional array of elemental -constraints. - -Elemental constraint(s) associated with the model constraint (if it is -a simple constraint) or its members (if it is an array) correspond to -the linear constraints in the LP/MIP problem formulation (see -Section \ref{problem}, page \pageref{problem}). - -If the constraint has the form of equality or single inequality, i.e. -includes two expressions, one of which follows the colon and other -follows the relation sign {\tt=}, {\tt<=}, or {\tt>=}, both expressions -in the statement can be linear expressions. If the constraint has the -form of double inequality,\linebreak i.e. includes three expressions, -the middle expression can be a linear expression while the leftmost and -rightmost ones can be only numeric expressions. - -Generating the model is, roughly speaking, generating its constraints, -which are always evaluated for the entire subscript domain. Evaluation -of the constraints leads, in turn, to evaluation of other model objects -such as sets, parameters, and variables. - -Constructing an actual linear constraint included in the problem -instance, which (constraint) corresponds to a particular elemental -constraint, is performed as follows. - -If the constraint has the form of equality or single inequality, -evaluation of both linear expressions gives two resultant linear forms: -$$\begin{array}{r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r} -f&=&a_1x_1&+&a_2x_2&+\dots+&a_nx_n&+&a_0,\\ -g&=&b_1x_1&+&a_2x_2&+\dots+&a_nx_n&+&b_0,\\ -\end{array}$$ -where $x_1$, $x_2$, \dots, $x_n$ are elemental variables; $a_1$, $a_2$, -\dots, $a_n$, $b_1$, $b_2$, \dots, $b_n$ are numeric coefficients; -$a_0$ and $b_0$ are constant terms. Then all linear terms of $f$ and -$g$ are carried to the left-hand side, and the constant terms are -carried to the right-hand side, that gives the final elemental -constraint in the standard form: -$$(a_1-b_1)x_1+(a_2-b_2)x_2+\dots+(a_n-b_n)x_n\left\{ -\begin{array}{@{}c@{}}=\\\leq\\\geq\\\end{array}\right\}b_0-a_0.$$ - -If the constraint has the form of double inequality, evaluation of the -middle linear expression gives the resultant linear form: -$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$ -and evaluation of the leftmost and rightmost numeric expressions gives -two numeric values $l$ and $u$, respectively. Then the constant term of -the linear form is carried to both left-hand and right-handsides that -gives the final elemental constraint in the standard form: -$$l-a_0\leq a_1x_1+a_2x_2+\dots+a_nx_n\leq u-a_0.$$ - -\section{Objective statement} - -\noindent -\framebox[468pt][l]{ -\parbox[c][44pt]{468pt}{ -\hspace{6pt} {\tt minimize} {\it name} {\it alias} {\it domain} {\tt:} -{\it expression} {\tt;} - -\medskip - -\hspace{6pt} {\tt maximize} {\it name} {\it alias} {\it domain} {\tt:} -{\it expression} {\tt;} -}} - -\medskip - -\noindent -{\it name} is a symbolic name of the objective; - -\noindent -{\it alias} is an optional string literal, which specifies an alias of -the objective; - -\noindent -{\it domain} is an optional indexing expression, which specifies -a subscript domain of the objective; - -\noindent -{\it expression} is a linear expression used to compute the linear form -of the objective. - -\newpage - -\para{Examples} - -\begin{verbatim} -minimize obj: x + 1.5 * (y + z); -maximize total_profit: sum{p in prd} profit[p] * make[p]; -\end{verbatim} - -The objective statement declares an objective. If a subscript domain is -not specified, the objective is a simple (scalar) objective. Otherwise -it is a $n$-dimensional array of elemental objectives. - -Elemental objective(s) associated with the model objective (if it is a -simple objective) or its members (if it is an array) correspond to -general linear constraints in the LP/MIP problem formulation (see -Section \ref{problem}, page \pageref{problem}). However, unlike -constraints the corresponding linear forms are free (unbounded). - -Constructing an actual linear constraint included in the problem -instance, which (constraint) corresponds to a particular elemental -constraint, is performed as follows. The linear expression specified in -the objective statement is evaluated that, gives the resultant linear -form: -$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$ -where $x_1$, $x_2$, \dots, $x_n$ are elemental variables; $a_1$, $a_2$, -\dots, $a_n$ are numeric coefficients; $a_0$ is the constant term. Then -the linear form is used to construct the final elemental constraint in -the standard form: -$$-\infty= 0 and y >= 0; -check sum{i in ORIG} supply[i] = sum{j in DEST} demand[j]; -check{i in I, j in 1..10}: S[i,j] in U[i] union V[j]; -\end{verbatim} - -The check statement allows checking the resultant value of an logical -expression specified in the statement. If the value is {\it false}, an -error is reported. - -If the subscript domain is not specified, the check is performed only -once. Specifying the subscript domain allows performing multiple check -for every $n$-tuple in the domain set. In the latter case the logical -expression may include dummy indices introduced in corresponding -indexing expression. - -\section{Display statement} - -\noindent -\framebox[468pt][l]{ -\parbox[c][24pt]{468pt}{ -\hspace{6pt} {\tt display} {\it domain} {\tt:} {\it item} {\tt,} -\dots {\tt,} {\it item} {\tt;} -}} - -\medskip - -\noindent -{\it domain} is an optional indexing expression, which specifies -a subscript domain of the display statement; - -\noindent -{\it item}, \dots, {\it item} are items to be displayed. (The colon -preceding the first item may be omitted.) - -\para{Examples} - -\begin{verbatim} -display: 'x =', x, 'y =', y, 'z =', z; -display sqrt(x ** 2 + y ** 2 + z ** 2); -display{i in I, j in J}: i, j, a[i,j], b[i,j]; -\end{verbatim} - -The display statement evaluates all items specified in the statement -and writes their values on the standard output (terminal) in plain text -format. - -If a subscript domain is not specified, items are evaluated and then -displayed only once. Specifying the subscript domain causes items to be -evaluated and displayed for every $n$-tuple in the domain set. In the -latter case items may include dummy indices introduced in corresponding -indexing expression. - -An item to be displayed can be a model object (set, parameter, v -ariable, constraint, objective) or an expression. - -If the item is a computable object (i.e. a set or parameter provided -with the assign attribute), the object is evaluated over the entire -domain and then its content (i.e. the content of the object array) is -displayed. Otherwise, if the item is not a computable object, only its -current content (i.e. members actually generated during the model -evaluation) is displayed. - -If the item is an expression, the expression is evaluated and its -resultant value is displayed. - -\section{Printf statement} - -\noindent -\framebox[468pt][l]{ -\parbox[c][64pt]{468pt}{ -\hspace{6pt} {\tt printf} {\it domain} {\tt:} {\it format} {\tt,} -{\it expression} {\tt,} \dots {\tt,} {\it expression} {\tt;} - -\medskip - -\hspace{6pt} {\tt printf} {\it domain} {\tt:} {\it format} {\tt,} -{\it expression} {\tt,} \dots {\tt,} {\it expression} {\tt>} -{\it filename} {\tt;} - -\medskip - -\hspace{6pt} {\tt printf} {\it domain} {\tt:} {\it format} {\tt,} -{\it expression} {\tt,} \dots {\tt,} {\it expression} {\tt>>} -{\it filename} {\tt;} -}} - -\medskip - -\noindent -{\it domain} is an optional indexing expression, which specifies -a subscript domain of the printf statement; - -\noindent -{\it format} is a symbolic expression whose value specifies a format -control string. (The colon preceding the format expression may be -omitted.) - -\noindent -{\it expression}, \dots, {\it expression} are zero or more expressions -whose values have to be formatted and printed. Each expression should -be of numeric, symbolic, or logical type. - -\noindent -{\it filename} is a symbolic expression whose value specifies a name -of a text file, to which the output is redirected. The flag {\tt>} -means creating a new empty file while the flag {\tt>>} means appending -the output to an existing file. If no file name is specified, the -output is written on the standard output (terminal). - -\para{Examples} - -\begin{verbatim} -printf 'Hello, world!\n'; -printf: "x = %.3f; y = %.3f; z = %.3f\n", x, y, z > "result.txt"; -printf{i in I, j in J}: "flow from %s to %s is %d\n", i, j, x[i,j] - >> result_file & ".txt"; -printf{i in I} 'total flow from %s is %g\n', i, sum{j in J} x[i,j]; -printf{k in K} "x[%s] = " & (if x[k] < 0 then "?" else "%g"), - k, x[k]; -\end{verbatim} - -The printf statement is similar to the display statement, however, it -allows formatting data to be written. - -If a subscript domain is not specified, the printf statement is -executed only once. Specifying a subscript domain causes executing the -printf statement for every $n$-tuple in the domain set. In the latter -case the format and expression may include dummy indices introduced in -corresponding indexing expression. - -The format control string is a value of the symbolic expression -{\it format} specified in the printf statement. It is composed of zero -or more directives as follows: ordinary characters (not {\tt\%}), which -are copied unchanged to the output stream, and conversion -specifications, each of which causes evaluating corresponding -expression specified in the printf statement, formatting it, and -writing its resultant value to the output stream. - -Conversion specifications that may be used in the format control string -are the following:\linebreak {\tt d}, {\tt i}, {\tt f}, {\tt F}, -{\tt e}, {\tt E}, {\tt g}, {\tt G}, and {\tt s}. These specifications -have the same syntax and semantics as in the C programming language. - -\section{For statement} - -\noindent -\framebox[468pt][l]{ -\parbox[c][44pt]{468pt}{ -\hspace{6pt} {\tt for} {\it domain} {\tt:} {\it statement} {\tt;} - -\medskip - -\hspace{6pt} {\tt for} {\it domain} {\tt:} {\tt\{} {\it statement} -\dots {\it statement} {\tt\}} {\tt;} -}} - -\medskip - -\noindent -{\it domain} is an indexing expression which specifies a subscript -domain of the for statement. (The colon following the indexing -expression may be omitted.) - -\noindent -{\it statement} is a statement, which should be executed under control -of the for statement; - -\noindent -{\it statement}, \dots, {\it statement} is a sequence of statements -(enclosed in curly braces), which should be executed under control of -the for statement. - -Only the following statements can be used within the for statement: -check, display, printf, and another for. - -\para{Examples} - -\begin{verbatim} -for {(i,j) in E: i != j} -{ printf "flow from %s to %s is %g\n", i, j, x[i,j]; - check x[i,j] >= 0; -} -for {i in 1..n} -{ for {j in 1..n} printf " %s", if x[i,j] then "Q" else "."; - printf("\n"); -} -for {1..72} printf("*"); -\end{verbatim} - -The for statement causes a statement or a sequence of statements -specified as part of the for statement to be executed for every -$n$-tuple in the domain set. Thus, statements within the for statement -may include dummy indices introduced in corresponding indexing -expression. - -\newpage - -\section{Table statement} - -\noindent -\framebox[468pt][l]{ -\parbox[c][80pt]{468pt}{ -\hspace{6pt} {\tt table} {\it name} {\it alias} {\tt IN} {\it driver} -{\it arg} \dots {\it arg} {\tt:} - -\hspace{6pt} {\tt\ \ \ \ \ } {\it set} {\tt<-} {\tt[} {\it fld} {\tt,} -\dots {\tt,} {\it fld} {\tt]} {\tt,} {\it par} {\tt\textasciitilde} -{\it fld} {\tt,} \dots {\tt,} {\it par} {\tt\textasciitilde} {\it fld} -{\tt;} - -\medskip - -\hspace{6pt} {\tt table} {\it name} {\it alias} {\it domain} {\tt OUT} -{\it driver} {\it arg} \dots {\it arg} {\tt:} - -\hspace{6pt} {\tt\ \ \ \ \ } {\it expr} {\tt\textasciitilde} {\it fld} -{\tt,} \dots {\tt,} {\it expr} {\tt\textasciitilde} {\it fld} {\tt;} -}} - -\medskip - -\noindent -{\it name} is a symbolic name of the table; - -\noindent -{\it alias} is an optional string literal, which specifies an alias of -the table; - -\noindent -{\it domain} is an indexing expression, which specifies a subscript -domain of the (output) table; - -\noindent -{\tt IN} means reading data from the input table; - -\noindent -{\tt OUT} means writing data to the output table; - -\noindent -{\it driver} is a symbolic expression, which specifies the driver used -to access the table (for details see Appendix \ref{drivers}, page -\pageref{drivers}); - -\noindent -{\it arg} is an optional symbolic expression, which is an argument -pass\-ed to the table driver. This symbolic expression should not -include dummy indices specified in the domain; - -\noindent -{\it set} is the name of an optional simple set called {\it control -set}. It can be omitted along with the delimiter {\tt<-}; - -\noindent -{\it fld} is a field name. Within square brackets at least one field -should be specified. The field name following a parameter name or -expression is optional and can be omitted along with the -delimiter~{\tt\textasciitilde}, in which case the name of corresponding -model object is used as the field name; - -\noindent -{\it par} is a symbolic name of a model parameter; - -\noindent -{\it expr} is a numeric or symbolic expression. - -\para{Examples} - -\begin{verbatim} -table data IN "CSV" "data.csv": S <- [FROM,TO], d~DISTANCE, - c~COST; -table result{(f,t) in S} OUT "CSV" "result.csv": f~FROM, t~TO, - x[f,t]~FLOW; -\end{verbatim} - -The table statement allows reading data from a table into model -objects such as sets and (non-scalar) parameters as well as writing -data from the model to a table. - -\newpage - -\subsection{Table structure} - -A {\it data table} is an (unordered) set of {\it records}, where each -record consists of the same number of {\it fields}, and each field is -provided with a unique symbolic name called the {\it field name}. For -example: - -\bigskip - -\begin{tabular}{@{\hspace*{42mm}}c@{\hspace*{11mm}}c@{\hspace*{10mm}}c -@{\hspace*{9mm}}c} -First&Second&&Last\\ -field&field&.\ \ .\ \ .&field\\ -$\downarrow$&$\downarrow$&&$\downarrow$\\ -\end{tabular} - -\begin{tabular}{ll@{}} -Table header&$\rightarrow$\\ -First record&$\rightarrow$\\ -Second record&$\rightarrow$\\ -\\ -\hfil .\ \ .\ \ .\\ -\\ -Last record&$\rightarrow$\\ -\end{tabular} -\begin{tabular}{|l|l|c|c|} -\hline -{\tt FROM}&{\tt TO}&{\tt DISTANCE}&{\tt COST}\\ -\hline -{\tt Seattle} &{\tt New-York}&{\tt 2.5}&{\tt 0.12}\\ -{\tt Seattle} &{\tt Chicago} &{\tt 1.7}&{\tt 0.08}\\ -{\tt Seattle} &{\tt Topeka} &{\tt 1.8}&{\tt 0.09}\\ -{\tt San-Diego}&{\tt New-York}&{\tt 2.5}&{\tt 0.15}\\ -{\tt San-Diego}&{\tt Chicago} &{\tt 1.8}&{\tt 0.10}\\ -{\tt San-Diego}&{\tt Topeka} &{\tt 1.4}&{\tt 0.07}\\ -\hline -\end{tabular} - -\subsection{Reading data from input table} - -The input table statement causes reading data from the specified table -record by record. - -Once a next record has been read, numeric or symbolic values of fields, -whose names are enclosed in square brackets in the table statement, are -gathered into $n$-tuple, and if the control set is specified in the -table statement, this $n$-tuple is added to it. Besides, a numeric or -symbolic value of each field associated with a model parameter is -assigned to the parameter member identified by subscripts, which are -components of the $n$-tuple just read. - -For example, the following input table statement: - -\noindent\hfil -\verb|table data IN "...": S <- [FROM,TO], d~DISTANCE, c~COST;| - -\noindent -causes reading values of four fields named {\tt FROM}, {\tt TO}, -{\tt DISTANCE}, and {\tt COST} from each record of the specified table. -Values of fields {\tt FROM} and {\tt TO} give a pair $(f,t)$, which is -added to the control set {\tt S}. The value of field {\tt DISTANCE} is -assigned to parameter member ${\tt d}[f,t]$, and the value of field -{\tt COST} is assigned to parameter member ${\tt c}[f,t]$. - -Note that the input table may contain extra fields whose names are not -specified in the table statement, in which case values of these fields -on reading the table are ignored. - -\subsection{Writing data to output table} - -The output table statement causes writing data to the specified table. -Note that some drivers (namely, CSV and xBASE) destroy the output table -before writing data, i.e. delete all its existing records. - -Each $n$-tuple in the specified domain set generates one record written -to the output table. Values of fields are numeric or symbolic values of -corresponding expressions specified in the table statement. These -expressions are evaluated for each $n$-tuple in the domain set and, -thus, may include dummy indices introduced in the corresponding indexing -expression. - -For example, the following output table statement: - -\noindent\hfil -\verb|table result{(f,t) in S} OUT "...": f~FROM, t~TO, x[f,t]~FLOW;| - -\noindent -causes writing records, by one record for each pair $(f,t)$ in set -{\tt S}, to the output table, where each record consists of three -fields named {\tt FROM}, {\tt TO}, and {\tt FLOW}. The values written -to fields {\tt FROM} and {\tt TO} are current values of dummy indices -{\tt f} and {\tt t}, and the value written to field {\tt FLOW} is -a value of member ${\tt x}[f,t]$ of corresponding subscripted parameter -or variable. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\chapter{Model data} - -{\it Model data} include elemental sets, which are ``values'' of model -sets, and numeric and symbolic values of model parameters. - -In MathProg there are two different ways to saturate model sets and -parameters with data. One way is simply providing necessary data using -the assign attribute. However, in many cases it is more practical to -separate the model itself and particular data needed for the model. For -the latter reason in MathProg there is another way, when the model -description is divided into two parts: model section and data section. - -A {\it model section} is a main part of the model description that -contains declarations of all model objects and is common for all -problems based on that model. - -A {\it data section} is an optional part of the model description that -contains model data specific for a particular problem. - -In MathProg model and data sections can be placed either in one text -file or in two separate text files. - -1. If both model and data sections are placed in one file, the file is -composed as follows: - -\bigskip - -\noindent\hfil -\framebox{\begin{tabular}{l} -{\it statement}{\tt;}\\ -{\it statement}{\tt;}\\ -\hfil.\ \ .\ \ .\\ -{\it statement}{\tt;}\\ -{\tt data;}\\ -{\it data block}{\tt;}\\ -{\it data block}{\tt;}\\ -\hfil.\ \ .\ \ .\\ -{\it data block}{\tt;}\\ -{\tt end;} -\end{tabular}} - -\newpage - -2. If the model and data sections are placed in two separate files, the -files are composed as follows: - -\bigskip - -\noindent\hfil -\begin{tabular}{@{}c@{}} -\framebox{\begin{tabular}{l} -{\it statement}{\tt;}\\ -{\it statement}{\tt;}\\ -\hfil.\ \ .\ \ .\\ -{\it statement}{\tt;}\\ -{\tt end;}\\ -\end{tabular}}\\ -\\\\Model file\\ -\end{tabular} -\hspace{32pt} -\begin{tabular}{@{}c@{}} -\framebox{\begin{tabular}{l} -{\tt data;}\\ -{\it data block}{\tt;}\\ -{\it data block}{\tt;}\\ -\hfil.\ \ .\ \ .\\ -{\it data block}{\tt;}\\ -{\tt end;}\\ -\end{tabular}}\\ -\\Data file\\ -\end{tabular} - -\bigskip - -Note: If the data section is placed in a separate file, the keyword -{\tt data} is optional and may be omitted along with the semicolon that -follows it. - -\section{Coding data section} - -The {\it data section} is a sequence of data blocks in various formats, -which are discussed in following sections. The order, in which data -blocks follow in the data section, may be arbitrary, not necessarily -the same, in which corresponding model objects follow in the model -section. - -The rules of coding the data section are commonly the same as the rules -of coding the model description (see Section \ref{coding}, page -\pageref{coding}), i.e. data blocks are composed from basic lexical -units such as symbolic names, numeric and string literals, keywords, -delimiters, and comments. However, for the sake of convenience and for -improving readability there is one deviation from the common rule: if -a string literal consists of only alphanumeric characters (including -the underscore character), the signs {\tt+} and {\tt-}, and/or the -decimal point, it may be coded without bordering by (single or double) -quotes. - -All numeric and symbolic material provided in the data section is coded -in the form of numbers and symbols, i.e. unlike the model section -no expressions are allowed in the data section. Nevertheless, the signs -{\tt+} and {\tt-} can precede numeric literals to allow coding signed -numeric quantities, in which case there should be no white-space -characters between the sign and following numeric literal (if there is -at least one white-space, the sign and following numeric literal are -recognized as two different lexical units). - -\newpage - -\section{Set data block} - -\noindent -\framebox[468pt][l]{ -\parbox[c][44pt]{468pt}{ -\hspace{6pt} {\tt set} {\it name} {\tt,} {\it record} {\tt,} \dots -{\tt,} {\it record} {\tt;} - -\medskip - -\hspace{6pt} {\tt set} {\it name} {\tt[} {\it symbol} {\tt,} \dots -{\tt,} {\it symbol} {\tt]} {\tt,} {\it record} {\tt,} \dots {\tt,} -{\it record} {\tt;} -}} - -\medskip - -\noindent -{\it name} is a symbolic name of the set; - -\noindent -{\it symbol}, \dots, {\it symbol} are subscripts, which specify -a particular member of the set (if the set is an array, i.e. a set of -sets); - -\noindent -{\it record}, \dots, {\it record} are data records. - -\noindent -Commae preceding data records may be omitted. - -\para{Data records} - -\vspace*{-8pt} - -\begin{description} -\item[{\tt :=}]\hspace*{0pt}\\ -is a non-significant data record, which may be used freely to improve -readability; -\item[{\tt(} {\it slice} {\tt)}]\hspace*{0pt}\\ -specifies a slice; -\item[{\it simple-data}]\hspace*{0pt}\\ -specifies set data in the simple format; -\item[{\tt:} {\it matrix-data}]\hspace*{0pt}\\ -specifies set data in the matrix format; -\item[{\tt(tr)} {\tt:} {\it matrix-data}]\hspace*{0pt}\\ -specifies set data in the transposed matrix format. (In this case the -colon following the keyword {\tt(tr)} may be omitted.) -\end{description} - -\vspace*{-8pt} - -\para{Examples} - -\begin{verbatim} -set month := Jan Feb Mar Apr May Jun; -set month "Jan", "Feb", "Mar", "Apr", "May", "Jun"; -set A[3,Mar] := (1,2) (2,3) (4,2) (3,1) (2,2) (4,4) (3,4); -set A[3,'Mar'] := 1 2 2 3 4 2 3 1 2 2 4 4 2 4; -set A[3,'Mar'] : 1 2 3 4 := - 1 - + - - - 2 - + + - - 3 + - - + - 4 - + - + ; -set B := (1,2,3) (1,3,2) (2,3,1) (2,1,3) (1,2,2) (1,1,1) (2,1,1); -set B := (*,*,*) 1 2 3, 1 3 2, 2 3 1, 2 1 3, 1 2 2, 1 1 1, 2 1 1; -set B := (1,*,2) 3 2 (2,*,1) 3 1 (1,2,3) (2,1,3) (1,1,1); -set B := (1,*,*) : 1 2 3 := - 1 + - - - 2 - + + - 3 - + - - (2,*,*) : 1 2 3 := - 1 + - + - 2 - - - - 3 + - - ; -\end{verbatim} - -\noindent(In these examples {\tt month} is a simple set of singlets, -{\tt A} is a 2-dimensional array of doublets, and {\tt B} is a simple -set of triplets. Data blocks for the same set are equivalent in the -sense that they specify the same data in different formats.) - -The {\it set data block} is used to specify a complete elemental set, -which is assigned to a set (if it is a simple set) or one of its -members (if the set is an array of sets).\footnote{There is another way -to specify data for a simple set along with data for parameters. This -feature is discussed in the next section.} - -Data blocks can be specified only for non-computable sets, i.e. for -sets, which have no assign attribute ({\tt:=}) in the corresponding set -statements. - -If the set is a simple set, only its symbolic name should be specified -in the header of the data block. Otherwise, if the set is a -$n$-dimensional array, its symbolic name should be provided with a -complete list of subscripts separated by commae and enclosed in square -brackets to specify a particular member of the set array. The number of -subscripts should be the same as the dimension of the set array, where -each subscript should be a number or symbol. - -An elemental set defined in the set data block is coded as a sequence -of data records described below.\footnote{{\it Data record} is simply a -technical term. It does not mean that data records have any special -formatting.} - -\subsection{Assign data record} - -The {\it assign data record} ({\tt:=}) is a non-signficant element. -It may be used for improving readability of data blocks. - -\subsection{Slice data record} - -The {\it slice data record} is a control record, which specifies a -{\it slice} of the elemental set defined in the data block. It has the -following syntactic form: -$$\mbox{{\tt(} $s_1$ {\tt,} $s_2$ {\tt,} \dots {\tt,} $s_n$ {\tt)}}$$ -where $s_1$, $s_2$, \dots, $s_n$ are components of the slice. - -Each component of the slice can be a number or symbol or the asterisk -({\tt*}). The number of components in the slice should be the same as -the dimension of $n$-tuples in the elemental set to be defined. For -instance, if the elemental set contains 4-tuples (quadruplets), the -slice should have four components. The number of asterisks in the slice -is called the {\it slice dimension}. - -The effect of using slices is the following. If a $m$-dimensional slice -(i.e. a slice having $m$ asterisks) is specified in the data block, all -subsequent data records should specify tuples of the dimension~$m$. -Whenever a $m$-tuple is encountered, each asterisk in the slice is -replaced by corresponding components of the $m$-tuple that gives the -resultant $n$-tuple, which is included in the elemental set to be -defined. For example, if the slice $(a,*,1,2,*)$ is in effect, and -2-tuple $(3,b)$ is encountered in a subsequent data record, the -resultant 5-tuple included in the elemental set is $(a,3,1,2,b)$. - -The slice having no asterisks itself defines a complete $n$-tuple, -which is included in the elemental set. - -Being once specified the slice effects until either a new slice or the -end of data block is encountered. Note that if no slice is specified in -the data block, one, components of which are all asterisks, is assumed. - -\subsection{Simple data record} - -The {\it simple data record} defines one $n$-tuple in a simple format -and has the following syntactic form: -$$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$}$$ -where $t_1$, $t_2$, \dots, $t_n$ are components of the $n$-tuple. Each -component can be a number or symbol. Commae between components are -optional and may be omitted. - -\subsection{Matrix data record} - -The {\it matrix data record} defines several 2-tuples (doublets) in -a matrix format and has the following syntactic form: -$$\begin{array}{cccccc} -\mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\ -r_1&a_{11}&a_{12}&\dots&a_{1n}&\\ -r_2&a_{21}&a_{22}&\dots&a_{2n}&\\ -\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\ -r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\ -\end{array}$$ -where $r_1$, $r_2$, \dots, $r_m$ are numbers and/or symbols -corresponding to rows of the matrix; $c_1$, $c_2$, \dots, $c_n$ are -numbers and/or symbols corresponding to columns of the matrix, $a_{11}$, -$a_{12}$, \dots, $a_{mn}$ are matrix elements, which can be either -{\tt+} or {\tt-}. (In this data record the delimiter {\tt:} preceding -the column list and the delimiter {\tt:=} following the column list -cannot be omitted.) - -Each element $a_{ij}$ of the matrix data block (where $1\leq i\leq m$, -$1\leq j\leq n$) corresponds to 2-tuple $(r_i,c_j)$. If $a_{ij}$ is the -plus sign ({\tt+}), that 2-tuple (or a longer $n$-tuple, if a slice is -used) is included in the elemental set. Otherwise, if $a_{ij}$ is the -minus sign ({\tt-}), that 2-tuple is not included in the elemental set. - -Since the matrix data record defines 2-tuples, either the elemental set -should consist of 2-tuples or the slice currently used should be -2-dimensional. - -\newpage - -\subsection{Transposed matrix data record} - -The {\it transposed matrix data record} has the following syntactic -form: -$$\begin{array}{cccccc} -\mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\ -r_1&a_{11}&a_{12}&\dots&a_{1n}&\\ -r_2&a_{21}&a_{22}&\dots&a_{2n}&\\ -\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\ -r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\ -\end{array}$$ -(In this case the delimiter {\tt:} following the keyword {\tt(tr)} is -optional and may be omitted.) - -This data record is completely analogous to the matrix data record (see -above) with only exception that in this case each element $a_{ij}$ of -the matrix corresponds to 2-tuple $(c_j,r_i)$ rather than $(r_i,c_j)$. - -Being once specified the {\tt(tr)} indicator affects all subsequent -data records until either a slice or the end of data block is -encountered. - -\section{Parameter data block} - -\noindent -\framebox[468pt][l]{ -\parbox[c][88pt]{468pt}{ -\hspace{6pt} {\tt param} {\it name} {\tt,} {\it record} {\tt,} \dots -{\tt,} {\it record} {\tt;} - -\medskip - -\hspace{6pt} {\tt param} {\it name} {\tt default} {\it value} {\tt,} -{\it record} {\tt,} \dots {\tt,} {\it record} {\tt;} - -\medskip - -\hspace{6pt} {\tt param} {\tt:} {\it tabbing-data} {\tt;} - -\medskip - -\hspace{6pt} {\tt param} {\tt default} {\it value} {\tt:} -{\it tabbing-data} {\tt;} -}} - -\medskip - -\noindent -{\it name} is a symbolic name of the parameter; - -\noindent -{\it value} is an optional default value of the parameter; - -\noindent -{\it record}, \dots, {\it record} are data records; - -\noindent -{\it tabbing-data} specifies parameter data in the tabbing format. - -\noindent -Commae preceding data records may be omitted. - -\para{Data records} - -\vspace*{-8pt} - -\begin{description} -\item[{\tt :=}]\hspace*{0pt}\\ -is a non-significant data record, which may be used freely to improve -readability; -\item[{\tt[} {\it slice} {\tt]}]\hspace*{0pt}\\ -specifies a slice; -\item[{\it plain-data}]\hspace*{0pt}\\ -specifies parameter data in the plain format; -\item[{\tt:} {\it tabular-data}]\hspace*{0pt}\\ -specifies parameter data in the tabular format; -\item[{\tt(tr)} {\tt:} {\it tabular-data}]\hspace*{0pt}\\ -specifies set data in the transposed tabular format. (In this case the -colon following the keyword {\tt(tr)} may be omitted.) -\end{description} - -\vspace*{-8pt} - -\para{Examples} - -\begin{verbatim} -param T := 4; -param month := 1 Jan 2 Feb 3 Mar 4 Apr 5 May; -param month := [1] 'Jan', [2] 'Feb', [3] 'Mar', [4] 'Apr', [5] 'May'; -param init_stock := iron 7.32 nickel 35.8; -param init_stock [*] iron 7.32, nickel 35.8; -param cost [iron] .025 [nickel] .03; -param value := iron -.1, nickel .02; -param : init_stock cost value := - iron 7.32 .025 -.1 - nickel 35.8 .03 .02 ; -param : raw : init stock cost value := - iron 7.32 .025 -.1 - nickel 35.8 .03 .02 ; -param demand default 0 (tr) - : FRA DET LAN WIN STL FRE LAF := - bands 300 . 100 75 . 225 250 - coils 500 750 400 250 . 850 500 - plate 100 . . 50 200 . 250 ; -param trans_cost := - [*,*,bands]: FRA DET LAN WIN STL FRE LAF := - GARY 30 10 8 10 11 71 6 - CLEV 22 7 10 7 21 82 13 - PITT 19 11 12 10 25 83 15 - [*,*,coils]: FRA DET LAN WIN STL FRE LAF := - GARY 39 14 11 14 16 82 8 - CLEV 27 9 12 9 26 95 17 - PITT 24 14 17 13 28 99 20 - [*,*,plate]: FRA DET LAN WIN STL FRE LAF := - GARY 41 15 12 16 17 86 8 - CLEV 29 9 13 9 28 99 18 - PITT 26 14 17 13 31 104 20 ; -\end{verbatim} - -The {\it parameter data block} is used to specify complete data for a -parameter (or parameters, if data are specified in the tabbing format). - -Data blocks can be specified only for non-computable parameters, i.e. -for parameters, which have no assign attribute ({\tt:=}) in the -corresponding parameter statements. - -Data defined in the parameter data block are coded as a sequence of -data records described below. Additionally the data block can be -provided with the optional {\tt default} attribute, which specifies a -default numeric or symbolic value of the parameter (parameters). This -default value is assigned to the parameter or its members when -no appropriate value is defined in the parameter data block. The -{\tt default} attribute cannot be used, if it is already specified in -the corresponding parameter statement. - -\subsection{Assign data record} - -The {\it assign data record} ({\tt:=}) is a non-signficant element. -It may be used for improving readability of data blocks. - -\subsection{Slice data record} - -The {\it slice data record} is a control record, which specifies a -{\it slice} of the parameter array. It has the following syntactic -form: -$$\mbox{{\tt[} $s_1$ {\tt,} $s_2$ {\tt,} \dots {\tt,} $s_n$ {\tt]}}$$ -where $s_1$, $s_2$, \dots, $s_n$ are components of the slice. - -Each component of the slice can be a number or symbol or the asterisk -({\tt*}). The number of components in the slice should be the same as -the dimension of the parameter. For instance, if the parameter is a -4-dimensional array, the slice should have four components. The number -of asterisks in the slice is called the {\it slice dimension}. - -The effect of using slices is the following. If a $m$-dimensional slice -(i.e. a slice having $m$ asterisks) is specified in the data block, all -subsequent data records should specify subscripts of the parameter -members as if the parameter were $m$-dimensional, not $n$-dimensional. - -Whenever $m$ subscripts are encountered, each asterisk in the slice is -replaced by corresponding subscript that gives $n$ subscripts, which -define the actual parameter member. For example, if the slice -$[a,*,1,2,*]$ is in effect, and subscripts 3 and $b$ are encountered in -a subsequent data record, the complete subscript list used to choose a -parameter member is $[a,3,1,2,b]$. - -It is allowed to specify a slice having no asterisks. Such slice itself -defines a complete subscript list, in which case the next data record -should define only a single value of corresponding parameter member. - -Being once specified the slice effects until either a new slice or the -end of data block is encountered. Note that if no slice is specified in -the data block, one, components of which are all asterisks, is assumed. - -\subsection{Plain data record} - -The {\it plain data record} defines a subscript list and a single value -in the plain format. This record has the following syntactic form: -$$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$ {\tt,} $v$}$$ -where $t_1$, $t_2$, \dots, $t_n$ are subscripts, and $v$ is a value. -Each subscript as well as the value can be a number or symbol. Commae -following subscripts are optional and may be omitted. - -In case of 0-dimensional parameter or slice the plain data record has -no subscripts and consists of a single value only. - -\subsection{Tabular data record} - -The {\it tabular data record} defines several values, where each value -is provided with two subscripts. This record has the following -syntactic form: -$$\begin{array}{cccccc} -\mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\ -r_1&a_{11}&a_{12}&\dots&a_{1n}&\\ -r_2&a_{21}&a_{22}&\dots&a_{2n}&\\ -\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\ -r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\ -\end{array}$$ -where $r_1$, $r_2$, \dots, $r_m$ are numbers and/or symbols -corresponding to rows of the table; $c_1$, $c_2$, \dots, $c_n$ are -numbers and/or symbols corresponding to columns of the table, $a_{11}$, -$a_{12}$, \dots, $a_{mn}$ are table elements. Each element can be a -number or symbol or the single decimal point ({\tt.}). (In this data -record the delimiter {\tt:} preceding the column list and the delimiter -{\tt:=} following the column list cannot be omitted.) - -Each element $a_{ij}$ of the tabular data block ($1\leq i\leq m$, -$1\leq j\leq n$) defines two subscripts, where the first subscript is -$r_i$, and the second one is $c_j$. These subscripts are used in -conjunction with the current slice to form the complete subscript list -that identifies a particular member of the parameter array. If $a_{ij}$ -is a number or symbol, this value is assigned to the parameter member. -However, if $a_{ij}$ is the single decimal point, the member is -assigned a default value specified either in the parameter data block -or in the parameter statement, or, if no default value is specified, -the member remains undefined. - -Since the tabular data record provides two subscripts for each value, -either the parameter or the slice currently used should be -2-dimensional. - -\subsection{Transposed tabular data record} - -The {\it transposed tabular data record} has the following syntactic -form: -$$\begin{array}{cccccc} -\mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\ -r_1&a_{11}&a_{12}&\dots&a_{1n}&\\ -r_2&a_{21}&a_{22}&\dots&a_{2n}&\\ -\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\ -r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\ -\end{array}$$ -(In this case the delimiter {\tt:} following the keyword {\tt(tr)} is -optional and may be omitted.) - -This data record is completely analogous to the tabular data record -(see above) with only exception that the first subscript defined by -element $a_{ij}$ is $c_j$ while the second one is $r_i$. - -Being once specified the {\tt(tr)} indicator affects all subsequent -data records until either a slice or the end of data block is -encountered. - -\newpage - -\subsection{Tabbing data format} - -The parameter data block in the {\it tabbing format} has the following -syntactic form: -$$ -\begin{array}{*{8}{l}} -\multicolumn{4}{l} -{{\tt param}\ {\tt default}\ value\ {\tt :}\ s\ {\tt :}}& -p_1\ \ \verb|,|&p_2\ \ \verb|,|&\dots\ \verb|,|&p_r\ \ \verb|:=|\\ -r_{11}\ \verb|,|& r_{12}\ \verb|,|& \dots\ \verb|,|& r_{1n}\ \verb|,|& -a_{11}\ \verb|,|& a_{12}\ \verb|,|& \dots\ \verb|,|& a_{1r}\ \verb|,|\\ -r_{21}\ \verb|,|& r_{22}\ \verb|,|& \dots\ \verb|,|& r_{2n}\ \verb|,|& -a_{21}\ \verb|,|& a_{22}\ \verb|,|& \dots\ \verb|,|& a_{2r}\ \verb|,|\\ -\dots & \dots & \dots & \dots & \dots & \dots & \dots & \dots \\ -r_{m1}\ \verb|,|& r_{m2}\ \verb|,|& \dots\ \verb|,|& r_{mn}\ \verb|,|& -a_{m1}\ \verb|,|& a_{m2}\ \verb|,|& \dots\ \verb|,|& a_{mr}\ \verb|;|\\ -\end{array} -$$ - -1. The keyword {\tt default} may be omitted along with a value -following it. - -2. Symbolic name $s$ may be omitted along with the colon following it. - -3. All comae are optional and may be omitted. - -The data block in the tabbing format shown above is exactly equivalent -to the following data blocks: - -\verb|set| $s$\ \verb|:=|\ $ -\verb|(|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|) | -\verb|(|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|) | -\dots -\verb| (|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|);|$ - -\verb|param| $p_1$\ \verb|default|\ $value$\ \verb|:=| - -$\verb| | -\verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{11} -\verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{21} -\verb| |\dots -\verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{m1} -\verb|;| -$ - -\verb|param| $p_2$\ \verb|default|\ $value$\ \verb|:=| - -$\verb| | -\verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{12} -\verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{22} -\verb| |\dots -\verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{m2} -\verb|;| -$ - -\verb| |.\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ . - -\verb|param| $p_r$\ \verb|default|\ $value$\ \verb|:=| - -$\verb| | -\verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{1r} -\verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{2r} -\verb| |\dots -\verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{mr} -\verb|;| -$ - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\appendix - -\chapter{Using suffixes} - -\vspace*{-12pt} - -Suffixes can be used to retrieve additional values associated with -model variables, constraints, and objectives. - -A {\it suffix} consists of a period ({\tt.}) followed by a non-reserved -keyword. For example, if {\tt x} is a two-dimensional variable, -{\tt x[i,j].lb} is a numeric value equal to the lower bound of -elemental variable {\tt x[i,j]}, which (value) can be used everywhere -in expressions like a numeric parameter. - -For model variables suffixes have the following meaning: - -\begin{tabular}{@{}ll@{}} -{\tt.lb}&lower bound\\ -{\tt.ub}&upper bound\\ -{\tt.status}&status in the solution:\\ -&0 --- undefined\\ -&1 --- basic\\ -&2 --- non-basic on lower bound\\ -&3 --- non-basic on upper bound\\ -&4 --- non-basic free (unbounded) variable\\ -&5 --- non-basic fixed variable\\ -{\tt.val}&primal value in the solution\\ -{\tt.dual}&dual value (reduced cost) in the solution\\ -\end{tabular} - -For model constraints and objectives suffixes have the following -meaning: - -\begin{tabular}{@{}ll@{}} -{\tt.lb}&lower bound of the linear form\\ -{\tt.ub}&upper bound of the linear form\\ -{\tt.status}&status in the solution:\\ -&0 --- undefined\\ -&1 --- non-active\\ -&2 --- active on lower bound\\ -&3 --- active on upper bound\\ -&4 --- active free (unbounded) row\\ -&5 --- active equality constraint\\ -{\tt.val}&primal value of the linear form in the solution\\ -{\tt.dual}&dual value (reduced cost) of the linear form in the -solution\\ -\end{tabular} - -Note that suffixes {\tt.status}, {\tt.val}, and {\tt.dual} can be used -only below the solve statement. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\chapter{Date and time functions} - -\noindent\hfil -\begin{tabular}{c} -by Andrew Makhorin \verb||\\ -and Heinrich Schuchardt \verb||\\ -\end{tabular} - -\section{Obtaining current calendar time} -\label{gmtime} - -To obtain the current calendar time in MathProg there exists the -function {\tt gmtime}. It has no arguments and returns the number of -seconds elapsed since 00:00:00 on January 1, 1970, Coordinated -Universal Time (UTC). For example: - -\begin{verbatim} - param utc := gmtime(); -\end{verbatim} - -MathProg has no function to convert UTC time returned by the function -{\tt gmtime} to {\it local} calendar times. Thus, if you need to -determine the current local calendar time, you have to add to the UTC -time returned the time offset from UTC expressed in seconds. For -example, the time in Berlin during the winter is one hour ahead of UTC -that corresponds to the time offset +1~hour~= +3600~secs, so the -current winter calendar time in Berlin may be determined as follows: - -\begin{verbatim} - param now := gmtime() + 3600; -\end{verbatim} - -\noindent Similarly, the summer time in Chicago (Central Daylight Time) -is five hours behind UTC, so the corresponding current local calendar -time may be determined as follows: - -\begin{verbatim} - param now := gmtime() - 5 * 3600; -\end{verbatim} - -Note that the value returned by {\tt gmtime} is volatile, i.e. being -called several times this function may return different values. - -\section{Converting character string to calendar time} -\label{str2time} - -The function {\tt str2time(}{\it s}{\tt,} {\it f}{\tt)} converts a -character string (timestamp) specified by its first argument {\it s}, -which should be a symbolic expression, to the calendar time suitable -for arithmetic calculations. The conversion is controlled by the -specified format string {\it f} (the second argument), which also -should be a symbolic expression. - -\newpage - -The result of conversion returned by {\tt str2time} has the same -meaning as values returned by the function {\tt gmtime} (see Subsection -\ref{gmtime}, page \pageref{gmtime}). Note that {\tt str2time} does -{\tt not} correct the calendar time returned for the local timezone, -i.e. being applied to 00:00:00 on January 1, 1970 it always returns 0. - -For example, the model statements: - -\begin{verbatim} - param s, symbolic, := "07/14/98 13:47"; - param t := str2time(s, "%m/%d/%y %H:%M"); - display t; -\end{verbatim} - -\noindent produce the following printout: - -\begin{verbatim} - t = 900424020 -\end{verbatim} - -\noindent where the calendar time printed corresponds to 13:47:00 on -July 14, 1998. - -The format string passed to the function {\tt str2time} consists of -conversion specifiers and ordinary characters. Each conversion -specifier begins with a percent ({\tt\%}) character followed by a -letter. - -The following conversion specifiers may be used in the format string: - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%b}&The abbreviated month name (case insensitive). At least three -first letters of the month name should appear in the input string.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%d}&The day of the month as a decimal number (range 1 to 31). -Leading zero is permitted, but not required.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%h}&The same as {\tt\%b}.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%H}&The hour as a decimal number, using a 24-hour clock (range 0 -to 23). Leading zero is permitted, but not required.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%m}&The month as a decimal number (range 1 to 12). Leading zero is -permitted, but not required.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%M}&The minute as a decimal number (range 0 to 59). Leading zero -is permitted, but not required.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%S}&The second as a decimal number (range 0 to 60). Leading zero -is permitted, but not required.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%y}&The year without a century as a decimal number (range 0 to 99). -Leading zero is permitted, but not required. Input values in the range -0 to 68 are considered as the years 2000 to 2068 while the values 69 to -99 as the years 1969 to 1999.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%z}&The offset from GMT in ISO 8601 format.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%\%}&A literal {\tt\%} character.\\ -\end{tabular} - -All other (ordinary) characters in the format string should have a -matching character in the input string to be converted. Exceptions are -spaces in the input string which can match zero or more space -characters in the format string. - -\newpage - -If some date and/or time component(s) are missing in the format and, -therefore, in the input string, the function {\tt str2time} uses their -default values corresponding to 00:00:00 on January 1, 1970, that is, -the default value of the year is 1970, the default value of the month -is January, etc. - -The function {\tt str2time} is applicable to all calendar times in the -range 00:00:00 on January 1, 0001 to 23:59:59 on December 31, 4000 of -the Gregorian calendar. - -\section{Converting calendar time to character string} -\label{time2str} - -The function {\tt time2str(}{\it t}{\tt,} {\it f}{\tt)} converts the -calendar time specified by its first argument {\it t}, which should be -a numeric expression, to a character string (symbolic value). The -conversion is controlled by the specified format string {\it f} (the -second argument), which should be a symbolic expression. - -The calendar time passed to {\tt time2str} has the same meaning as -values returned by the function {\tt gmtime} (see Subsection -\ref{gmtime}, page \pageref{gmtime}). Note that {\tt time2str} does -{\it not} correct the specified calendar time for the local timezone, -i.e. the calendar time 0 always corresponds to 00:00:00 on January 1, -1970. - -For example, the model statements: - -\begin{verbatim} - param s, symbolic, := time2str(gmtime(), "%FT%TZ"); - display s; -\end{verbatim} - -\noindent may produce the following printout: - -\begin{verbatim} - s = '2008-12-04T00:23:45Z' -\end{verbatim} - -\noindent which is a timestamp in the ISO format. - -The format string passed to the function {\tt time2str} consists of -conversion specifiers and ordinary characters. Each conversion -specifier begins with a percent ({\tt\%}) character followed by a -letter. - -The following conversion specifiers may be used in the format string: - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%a}&The abbreviated (2-character) weekday name.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%A}&The full weekday name.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%b}&The abbreviated (3-character) month name.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%B}&The full month name.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%C}&The century of the year, that is the greatest integer not -greater than the year divided by~100.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%d}&The day of the month as a decimal number (range 01 to 31).\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%D}&The date using the format \verb|%m/%d/%y|.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%e}&The day of the month like with \verb|%d|, but padded with -blank rather than zero.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%F}&The date using the format \verb|%Y-%m-%d|.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%g}&The year corresponding to the ISO week number, but without the -century (range 00 to~99). This has the same format and value as -\verb|%y|, except that if the ISO week number (see \verb|%V|) belongs -to the previous or next year, that year is used instead.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%G}&The year corresponding to the ISO week number. This has the -same format and value as \verb|%Y|, except that if the ISO week number -(see \verb|%V|) belongs to the previous or next year, that year is used -instead. -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%h}&The same as \verb|%b|.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%H}&The hour as a decimal number, using a 24-hour clock (range 00 -to 23).\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%I}&The hour as a decimal number, using a 12-hour clock (range 01 -to 12).\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%j}&The day of the year as a decimal number (range 001 to 366).\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%k}&The hour as a decimal number, using a 24-hour clock like -\verb|%H|, but padded with blank rather than zero.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%l}&The hour as a decimal number, using a 12-hour clock like -\verb|%I|, but padded with blank rather than zero. -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%m}&The month as a decimal number (range 01 to 12).\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%M}&The minute as a decimal number (range 00 to 59).\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%p}&Either {\tt AM} or {\tt PM}, according to the given time value. -Midnight is treated as {\tt AM} and noon as {\tt PM}.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%P}&Either {\tt am} or {\tt pm}, according to the given time value. -Midnight is treated as {\tt am} and noon as {\tt pm}.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%R}&The hour and minute in decimal numbers using the format -\verb|%H:%M|.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%S}&The second as a decimal number (range 00 to 59).\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%T}&The time of day in decimal numbers using the format -\verb|%H:%M:%S|.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%u}&The day of the week as a decimal number (range 1 to 7), Monday -being 1.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%U}&The week number of the current year as a decimal number (range -00 to 53), starting with the first Sunday as the first day of the first -week. Days preceding the first Sunday in the year are considered to be -in week 00. -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%V}&The ISO week number as a decimal number (range 01 to 53). ISO -weeks start with Monday and end with Sunday. Week 01 of a year is the -first week which has the majority of its days in that year; this is -equivalent to the week containing January 4. Week 01 of a year can -contain days from the previous year. The week before week 01 of a year -is the last week (52 or 53) of the previous year even if it contains -days from the new year. In other word, if 1 January is Monday, Tuesday, -Wednesday or Thursday, it is in week 01; if 1 January is Friday, -Saturday or Sunday, it is in week 52 or 53 of the previous year.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%w}&The day of the week as a decimal number (range 0 to 6), Sunday -being 0.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%W}&The week number of the current year as a decimal number (range -00 to 53), starting with the first Monday as the first day of the first -week. Days preceding the first Monday in the year are considered to be -in week 00.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%y}&The year without a century as a decimal number (range 00 to -99), that is the year modulo~100.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%Y}&The year as a decimal number, using the Gregorian calendar.\\ -\end{tabular} - -\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} -{\tt\%\%}&A literal \verb|%| character.\\ -\end{tabular} - -All other (ordinary) characters in the format string are simply copied -to the resultant string. - -The first argument (calendar time) passed to the function {\tt time2str} -should be in the range from $-62135596800$ to $+64092211199$ that -corresponds to the period from 00:00:00 on January 1, 0001 to 23:59:59 -on December 31, 4000 of the Gregorian calendar. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\chapter{Table drivers} -\label{drivers} - -\noindent\hfil -\begin{tabular}{c} -by Andrew Makhorin \verb||\\ -and Heinrich Schuchardt \verb||\\ -\end{tabular} - -\bigskip\bigskip - -The {\it table driver} is a program module which provides transmitting -data between MathProg model objects and data tables. - -Currently the GLPK package has four table drivers: - -\vspace*{-8pt} - -\begin{itemize} -\item built-in CSV table driver; -\item built-in xBASE table driver; -\item ODBC table driver; -\item MySQL table driver. -\end{itemize} - -\vspace*{-8pt} - -\section{CSV table driver} - -The CSV table driver assumes that the data table is represented in the -form of a plain text file in the CSV (comma-separated values) file -format as described below. - -To choose the CSV table driver its name in the table statement should -be specified as \verb|"CSV"|, and the only argument should specify the -name of a plain text file containing the table. For example: - -\begin{verbatim} - table data IN "CSV" "data.csv": ... ; -\end{verbatim} - -The filename suffix may be arbitrary, however, it is recommended to use -the suffix `\verb|.csv|'. - -On reading input tables the CSV table driver provides an implicit field -named \verb|RECNO|, which contains the current record number. This -field can be specified in the input table statement as if there were -the actual field named \verb|RECNO| in the CSV file. For example: - -\begin{verbatim} - table list IN "CSV" "list.csv": num <- [RECNO], ... ; -\end{verbatim} - -\newpage - -\subsection*{CSV format\footnote{This material is based on the RFC -document 4180.}} - -The CSV (comma-separated values) format is a plain text file format -defined as follows. - -1. Each record is located on a separate line, delimited by a line -break. For example: - -\begin{verbatim} - aaa,bbb,ccc\n - xxx,yyy,zzz\n -\end{verbatim} - -\noindent -where \verb|\n| means the control character \verb|LF| ({\tt 0x0A}). - -2. The last record in the file may or may not have an ending line -break. For example: - -\begin{verbatim} - aaa,bbb,ccc\n - xxx,yyy,zzz -\end{verbatim} - -3. There should be a header line appearing as the first line of the -file in the same format as normal record lines. This header should -contain names corresponding to the fields in the file. The number of -field names in the header line should be the same as the number of -fields in the records of the file. For example: - -\begin{verbatim} - name1,name2,name3\n - aaa,bbb,ccc\n - xxx,yyy,zzz\n -\end{verbatim} - -4. Within the header and each record there may be one or more fields -separated by commas. Each line should contain the same number of fields -throughout the file. Spaces are considered as part of a field and -therefore not ignored. The last field in the record should not be -followed by a comma. For example: - -\begin{verbatim} - aaa,bbb,ccc\n -\end{verbatim} - -5. Fields may or may not be enclosed in double quotes. For example: - -\begin{verbatim} - "aaa","bbb","ccc"\n - zzz,yyy,xxx\n -\end{verbatim} - -6. If a field is enclosed in double quotes, each double quote which is -part of the field should be coded twice. For example: - -\begin{verbatim} - "aaa","b""bb","ccc"\n -\end{verbatim} - -\para{Example} - -\begin{verbatim} -FROM,TO,DISTANCE,COST -Seattle,New-York,2.5,0.12 -Seattle,Chicago,1.7,0.08 -Seattle,Topeka,1.8,0.09 -San-Diego,New-York,2.5,0.15 -San-Diego,Chicago,1.8,0.10 -San-Diego,Topeka,1.4,0.07 -\end{verbatim} - -\newpage - -\section{xBASE table driver} - -The xBASE table driver assumes that the data table is stored in the -.dbf file format. - -To choose the xBASE table driver its name in the table statement should -be specified as \verb|"xBASE"|, and the first argument should specify -the name of a .dbf file containing the table. For the output table there -should be the second argument defining the table format in the form -\verb|"FF...F"|, where \verb|F| is either {\tt C({\it n})}, -which specifies a character field of length $n$, or -{\tt N({\it n}{\rm [},{\it p}{\rm ]})}, which specifies a numeric field -of length $n$ and precision $p$ (by default $p$ is 0). - -The following is a simple example which illustrates creating and -reading a .dbf file: - -\begin{verbatim} -table tab1{i in 1..10} OUT "xBASE" "foo.dbf" - "N(5)N(10,4)C(1)C(10)": 2*i+1 ~ B, Uniform(-20,+20) ~ A, - "?" ~ FOO, "[" & i & "]" ~ C; -set S, dimen 4; -table tab2 IN "xBASE" "foo.dbf": S <- [B, C, RECNO, A]; -display S; -end; -\end{verbatim} - -\section{ODBC table driver} - -The ODBC table driver allows connecting to SQL databases using an -implementation of the ODBC interface based on the Call Level Interface -(CLI).\footnote{The corresponding software standard is defined in -ISO/IEC 9075-3:2003.} - -\para{Debian GNU/Linux.} -Under Debian GNU/Linux the ODBC table driver uses the iODBC -package,\footnote{See {\tt}.} which should be -installed before building the GLPK package. The installation can be -effected with the following command: - -\begin{verbatim} - sudo apt-get install libiodbc2-dev -\end{verbatim} - -Note that on configuring the GLPK package to enable using the iODBC -library the option `\verb|--enable-odbc|' should be passed to the -configure script. - -The individual databases should be entered for systemwide usage in -\verb|/etc/odbc.ini| and\linebreak \verb|/etc/odbcinst.ini|. Database -connections to be used by a single user are specified by files in the -home directory (\verb|.odbc.ini| and \verb|.odbcinst.ini|). - -\para{Microsoft Windows.} -Under Microsoft Windows the ODBC table driver uses the Microsoft ODBC -library. To enable this feature the symbol: - -\begin{verbatim} - #define ODBC_DLNAME "odbc32.dll" -\end{verbatim} - -\noindent -should be defined in the GLPK configuration file `\verb|config.h|'. - -Data sources can be created via the Administrative Tools from the -Control Panel. - -To choose the ODBC table driver its name in the table statement should -be specified as \verb|'ODBC'| or \verb|'iODBC'|. - -\newpage - -The argument list is specified as follows. - -The first argument is the connection string passed to the ODBC library, -for example: - -\verb|'DSN=glpk;UID=user;PWD=password'|, or - -\verb|'DRIVER=MySQL;DATABASE=glpkdb;UID=user;PWD=password'|. - -Different parts of the string are separated by semicolons. Each part -consists of a pair {\it fieldname} and {\it value} separated by the -equal sign. Allowable fieldnames depend on the ODBC library. Typically -the following fieldnames are allowed: - -\verb|DATABASE | database; - -\verb|DRIVER | ODBC driver; - -\verb|DSN | name of a data source; - -\verb|FILEDSN | name of a file data source; - -\verb|PWD | user password; - -\verb|SERVER | database; - -\verb|UID | user name. - -The second argument and all following are considered to be SQL -statements - -SQL statements may be spread over multiple arguments. If the last -character of an argument is a semicolon this indicates the end of -a SQL statement. - -The arguments of a SQL statement are concatenated separated by space. -The eventual trailing semicolon will be removed. - -All but the last SQL statement will be executed directly. - -For IN-table the last SQL statement can be a SELECT command starting -with the capitalized letters \verb|'SELECT '|. If the string does not -start with \verb|'SELECT '| it is considered to be a table name and a -SELECT statement is automatically generated. - -For OUT-table the last SQL statement can contain one or multiple -question marks. If it contains a question mark it is considered a -template for the write routine. Otherwise the string is considered a -table name and an INSERT template is automatically generated. - -The writing routine uses the template with the question marks and -replaces the first question mark by the first output parameter, the -second question mark by the second output parameter and so forth. Then -the SQL command is issued. - -The following is an example of the output table statement: - -\begin{verbatim} -table ta { l in LOCATIONS } OUT - 'ODBC' - 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword' - 'DROP TABLE IF EXISTS result;' - 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );' - 'INSERT INTO result 'VALUES ( 4, ?, ? )' : - l ~ LOC, quantity[l] ~ QUAN; -\end{verbatim} - -\newpage - -\noindent -Alternatively it could be written as follows: - -\begin{verbatim} -table ta { l in LOCATIONS } OUT - 'ODBC' - 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword' - 'DROP TABLE IF EXISTS result;' - 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );' - 'result' : - l ~ LOC, quantity[l] ~ QUAN, 4 ~ ID; -\end{verbatim} - -Using templates with `\verb|?|' supports not only INSERT, but also -UPDATE, DELETE, etc. For example: - -\begin{verbatim} -table ta { l in LOCATIONS } OUT - 'ODBC' - 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword' - 'UPDATE result SET DATE = ' & date & ' WHERE ID = 4;' - 'UPDATE result SET QUAN = ? WHERE LOC = ? AND ID = 4' : - quantity[l], l; -\end{verbatim} - -\section{MySQL table driver} - -The MySQL table driver allows connecting to MySQL databases. - -\para{Debian GNU/Linux.} -Under Debian GNU/Linux the MySQL table driver uses the MySQL -package,\footnote{For download development files see -{\tt}.} which should be -installed before building the GLPK package. The installation can be -effected with the following command: - -\begin{verbatim} - sudo apt-get install libmysqlclient15-dev -\end{verbatim} - -Note that on configuring the GLPK package to enable using the MySQL -library the option `\verb|--enable-mysql|' should be passed to the -configure script. - -\para{Microsoft Windows.} -Under Microsoft Windows the MySQL table driver also uses the MySQL -library. To enable this feature the symbol: - -\begin{verbatim} - #define MYSQL_DLNAME "libmysql.dll" -\end{verbatim} - -\noindent -should be defined in the GLPK configuration file `\verb|config.h|'. - -To choose the MySQL table driver its name in the table statement should -be specified as \verb|'MySQL'|. - -The argument list is specified as follows. - -The first argument specifies how to connect the data base in the DSN -style, for example: - -\verb|'Database=glpk;UID=glpk;PWD=gnu'|. - -Different parts of the string are separated by semicolons. Each part -consists of a pair {\it fieldname} and {\it value} separated by the -equal sign. The following fieldnames are allowed: - -\newpage - -\verb|Server | server running the database (defaulting to localhost); - -\verb|Database | name of the database; - -\verb|UID | user name; - -\verb|PWD | user password; - -\verb|Port | port used by the server (defaulting to 3306). - -The second argument and all following are considered to be SQL -statements. - -SQL statements may be spread over multiple arguments. If the last -character of an argument is a semicolon this indicates the end of -a SQL statement. - -The arguments of a SQL statement are concatenated separated by space. -The eventual trailing semicolon will be removed. - -All but the last SQL statement will be executed directly. - -For IN-table the last SQL statement can be a SELECT command starting -with the capitalized letters \verb|'SELECT '|. If the string does not -start with \verb|'SELECT '| it is considered to be a table name and a -SELECT statement is automatically generated. - -For OUT-table the last SQL statement can contain one or multiple -question marks. If it contains a question mark it is considered a -template for the write routine. Otherwise the string is considered a -table name and an INSERT template is automatically generated. - -The writing routine uses the template with the question marks and -replaces the first question mark by the first output parameter, the -second question mark by the second output parameter and so forth. Then -the SQL command is issued. - -The following is an example of the output table statement: - -\begin{verbatim} -table ta { l in LOCATIONS } OUT - 'MySQL' - 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword' - 'DROP TABLE IF EXISTS result;' - 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );' - 'INSERT INTO result VALUES ( 4, ?, ? )' : - l ~ LOC, quantity[l] ~ QUAN; -\end{verbatim} - -\noindent -Alternatively it could be written as follows: - -\begin{verbatim} -table ta { l in LOCATIONS } OUT - 'MySQL' - 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword' - 'DROP TABLE IF EXISTS result;' - 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );' - 'result' : - l ~ LOC, quantity[l] ~ QUAN, 4 ~ ID; -\end{verbatim} - -\newpage - -Using templates with `\verb|?|' supports not only INSERT, but also -UPDATE, DELETE, etc. For example: - -\begin{verbatim} -table ta { l in LOCATIONS } OUT - 'MySQL' - 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword' - 'UPDATE result SET DATE = ' & date & ' WHERE ID = 4;' - 'UPDATE result SET QUAN = ? WHERE LOC = ? AND ID = 4' : - quantity[l], l; -\end{verbatim} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\chapter{Solving models with glpsol} - -The GLPK package\footnote{{\tt http://www.gnu.org/software/glpk/}} -includes the program {\tt glpsol}, a stand-alone LP/MIP solver. This -program can be launched from the command line or from the shell to -solve models written in the GNU MathProg modeling language. - -To tell the solver that the input file contains a model description you -need to specify the option \verb|--model| in the command line. -For example: - -\begin{verbatim} - glpsol --model foo.mod -\end{verbatim} - -Sometimes it is necessary to use the data section placed in a separate -file, in which case you may use the following command: - -\begin{verbatim} - glpsol --model foo.mod --data foo.dat -\end{verbatim} - -\noindent Note that if the model file also contains the data section, -that section is ignored. - -It is also allowed to specify more than one file containing the data -section, for example: - -\begin{verbatim} - glpsol --model foo.mod --data foo1.dat --data foo2.dat -\end{verbatim} - -If the model description contains some display and/or printf -statements, by default the output is sent to the terminal. If you need -to redirect the output to a file, you may use the following command: - -\begin{verbatim} - glpsol --model foo.mod --display foo.out -\end{verbatim} - -If you need to look at the problem, which has been generated by the -model translator, you may use the option \verb|--wlp| as follows: - -\begin{verbatim} - glpsol --model foo.mod --wlp foo.lp -\end{verbatim} - -\noindent In this case the problem data is written to file -\verb|foo.lp| in CPLEX LP format suitable for visual analysis. - -Sometimes it is needed merely to check the model description not -solving the generated problem instance. In this case you may specify -the option \verb|--check|, for example: - -\begin{verbatim} - glpsol --check --model foo.mod --wlp foo.lp -\end{verbatim} - -\newpage - -If you need to write a numeric solution obtained by the solver to -a file, you may use the following command: - -\begin{verbatim} - glpsol --model foo.mod --output foo.sol -\end{verbatim} - -\noindent in which case the solution is written to file \verb|foo.sol| -in a plain text format suitable for visual analysis. - -The complete list of the \verb|glpsol| options can be found in the -GLPK reference manual included in the GLPK distribution. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\chapter{Example model description} - -\section{Model description written in MathProg} - -Below here is a complete example of the model description written in -the GNU MathProg modeling language. - -\bigskip - -\begin{verbatim} -# A TRANSPORTATION PROBLEM -# -# This problem finds a least cost shipping schedule that meets -# requirements at markets and supplies at factories. -# -# References: -# Dantzig G B, "Linear Programming and Extensions." -# Princeton University Press, Princeton, New Jersey, 1963, -# Chapter 3-3. - -set I; -/* canning plants */ - -set J; -/* markets */ - -param a{i in I}; -/* capacity of plant i in cases */ - -param b{j in J}; -/* demand at market j in cases */ - -param d{i in I, j in J}; -/* distance in thousands of miles */ - -param f; -/* freight in dollars per case per thousand miles */ - -param c{i in I, j in J} := f * d[i,j] / 1000; -/* transport cost in thousands of dollars per case */ - -var x{i in I, j in J} >= 0; -/* shipment quantities in cases */ - -minimize cost: sum{i in I, j in J} c[i,j] * x[i,j]; -/* total transportation costs in thousands of dollars */ - -s.t. supply{i in I}: sum{j in J} x[i,j] <= a[i]; -/* observe supply limit at plant i */ - -s.t. demand{j in J}: sum{i in I} x[i,j] >= b[j]; -/* satisfy demand at market j */ - -data; - -set I := Seattle San-Diego; - -set J := New-York Chicago Topeka; - -param a := Seattle 350 - San-Diego 600; - -param b := New-York 325 - Chicago 300 - Topeka 275; - -param d : New-York Chicago Topeka := - Seattle 2.5 1.7 1.8 - San-Diego 2.5 1.8 1.4 ; - -param f := 90; - -end; -\end{verbatim} - -\newpage - -\section{Generated LP problem instance} - -Below here is the result of the translation of the example model -produced by the solver \verb|glpsol| and written in CPLEX LP format -with the option \verb|--wlp|. - -\medskip - -\begin{verbatim} -\* Problem: transp *\ - -Minimize - cost: + 0.225 x(Seattle,New~York) + 0.153 x(Seattle,Chicago) - + 0.162 x(Seattle,Topeka) + 0.225 x(San~Diego,New~York) - + 0.162 x(San~Diego,Chicago) + 0.126 x(San~Diego,Topeka) - -Subject To - supply(Seattle): + x(Seattle,New~York) + x(Seattle,Chicago) - + x(Seattle,Topeka) <= 350 - supply(San~Diego): + x(San~Diego,New~York) + x(San~Diego,Chicago) - + x(San~Diego,Topeka) <= 600 - demand(New~York): + x(Seattle,New~York) + x(San~Diego,New~York) >= 325 - demand(Chicago): + x(Seattle,Chicago) + x(San~Diego,Chicago) >= 300 - demand(Topeka): + x(Seattle,Topeka) + x(San~Diego,Topeka) >= 275 - -End -\end{verbatim} - -\section{Optimal LP solution} - -Below here is the optimal solution of the generated LP problem instance -found by the solver \verb|glpsol| and written in plain text format -with the option \verb|--output|. - -\medskip - -\begin{footnotesize} -\begin{verbatim} -Problem: transp -Rows: 6 -Columns: 6 -Non-zeros: 18 -Status: OPTIMAL -Objective: cost = 153.675 (MINimum) - - No. Row name St Activity Lower bound Upper bound Marginal ------- ------------ -- ------------- ------------- ------------- ------------- - 1 cost B 153.675 - 2 supply[Seattle] - NU 350 350 < eps - 3 supply[San-Diego] - B 550 600 - 4 demand[New-York] - NL 325 325 0.225 - 5 demand[Chicago] - NL 300 300 0.153 - 6 demand[Topeka] - NL 275 275 0.126 - - No. Column name St Activity Lower bound Upper bound Marginal ------- ------------ -- ------------- ------------- ------------- ------------- - 1 x[Seattle,New-York] - B 50 0 - 2 x[Seattle,Chicago] - B 300 0 - 3 x[Seattle,Topeka] - NL 0 0 0.036 - 4 x[San-Diego,New-York] - B 275 0 - 5 x[San-Diego,Chicago] - NL 0 0 0.009 - 6 x[San-Diego,Topeka] - B 275 0 - -End of output -\end{verbatim} -\end{footnotesize} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section*{Acknowledgements} -\addcontentsline{toc}{chapter}{Acknowledgements} - -The authors would like to thank the following people, who kindly read, -commented, and corrected the draft of this document: - -\noindent Juan Carlos Borras \verb|| - -\noindent Harley Mackenzie \verb|| - -\noindent Robbie Morrison \verb|| - -\end{document} diff --git a/resources/3rdparty/glpk-4.53/doc/graphs.pdf b/resources/3rdparty/glpk-4.53/doc/graphs.pdf deleted file mode 100644 index 896dd7cd6c0ef05a34448aa05d00f9647a3ca929..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214470 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

    T7^^|zgghqWanB#-vH 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 AzyJUM diff --git a/resources/3rdparty/glpk-4.53/doc/graphs.tex b/resources/3rdparty/glpk-4.53/doc/graphs.tex deleted file mode 100644 index cddb7518e..000000000 --- a/resources/3rdparty/glpk-4.53/doc/graphs.tex +++ /dev/null @@ -1,4150 +0,0 @@ -%* graphs.tex *% - -%*********************************************************************** -% This code is part of GLPK (GNU Linear Programming Kit). -% -% Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -% 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -% Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -% reserved. E-mail: . -% -% GLPK is free software: you can redistribute it and/or modify it -% under the terms of the GNU General Public License as published by -% the Free Software Foundation, either version 3 of the License, or -% (at your option) any later version. -% -% GLPK is distributed in the hope that it will be useful, but WITHOUT -% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License -% along with GLPK. If not, see . -%*********************************************************************** - -\documentclass[11pt]{report} -\usepackage{amssymb} -\usepackage[dvipdfm,linktocpage,colorlinks,linkcolor=blue, -urlcolor=blue]{hyperref} -\usepackage{indentfirst} -\usepackage[all]{xy} - -\setlength{\textwidth}{6.5in} -\setlength{\textheight}{8.5in} -\setlength{\oddsidemargin}{0in} -\setlength{\topmargin}{0in} -\setlength{\headheight}{0in} -\setlength{\headsep}{0in} -\setlength{\footskip}{0.5in} -\setlength{\parindent}{16pt} -\setlength{\parskip}{5pt} -\setlength{\topsep}{0pt} -\setlength{\partopsep}{0pt} -\setlength{\itemsep}{\parskip} -\setlength{\parsep}{0pt} -\setlength{\leftmargini}{\parindent} -\renewcommand{\labelitemi}{---} - -\def\para#1{\noindent{\bf#1}} -\def\synopsis{\para{Synopsis}} -\def\description{\para{Description}} -\def\returns{\para{Returns}} - -\renewcommand\contentsname{\sf\bfseries Contents} -\renewcommand\chaptername{\sf\bfseries Chapter} -\renewcommand\appendixname{\sf\bfseries Appendix} - -\newenvironment{retlist} -{ \def\arraystretch{1.5} - \noindent - \begin{tabular}{@{}p{1in}@{}p{5.5in}@{}} -} -{\end{tabular}} - -\begin{document} - -\thispagestyle{empty} - -\begin{center} - -\vspace*{1.5in} - -\begin{huge} -\sf\bfseries GNU Linear Programming Kit -\end{huge} - -\vspace{0.5in} - -\begin{LARGE} -\sf Graph and Network Routines -\end{LARGE} - -\vspace{0.5in} - -\begin{LARGE} -\sf for GLPK Version 4.49 -\end{LARGE} - -\vspace{0.5in} -\begin{Large} -\sf (DRAFT, April 2013) -\end{Large} -\end{center} - -\newpage - -\vspace*{1in} - -\vfill - -\noindent -The GLPK package is part of the GNU Project released under the aegis of -GNU. - -\noindent -Copyright \copyright{} 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, -2008, 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -reserved. - -\noindent -Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -02110-1301, USA. - -\noindent -Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - -\noindent -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -entire resulting derived work is distributed under the terms of -a permission notice identical to this one. - -\noindent -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -{\setlength{\parskip}{0pt} -\tableofcontents -} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\chapter{Basic Graph API Routines} - -\section{Graph program object} - -In GLPK the base program object used to represent graphs and networks -is a directed graph (digraph). - -Formally, {\it digraph} (or simply, {\it graph}) is a pair $G=(V,A)$, -where $V$ is a set of {\it vertices}, and $A$ is a set -{\it arcs}.\footnote{$A$ may be a multiset.} Each arc $a\in A$ is an -ordered pair of vertices $a=(x,y)$, where $x\in V$ is called {\it tail -vertex} of arc $a$, and $y\in V$ is called its {\it head vertex}. - -Representation of a graph in the program includes three structs defined -by typedef in the header \verb|glpk.h|: - -\vspace*{-8pt} - -\begin{itemize} -\item \verb|glp_graph|, which represents the graph in a whole, - -\item \verb|glp_vertex|, which represents a vertex of the graph, and - -\item \verb|glp_arc|, which represents an arc of the graph. -\end{itemize} - -\vspace*{-8pt} - -All these three structs are ``semi-opaque'', i.e. the application -program can directly access their fields through pointers, however, -changing the fields directly is not allowed --- all changes should be -performed only with appropriate GLPK API routines. - -\newenvironment{comment} -{\addtolength{\leftskip}{16pt}\noindent} -{\par\addtolength{\leftskip}{-16pt}} - -\para{\bf glp\_graph.} The struct \verb|glp_graph| has the following -fields available to the application program: - -\noindent -\verb|char *name;| - -\begin{comment}Symbolic name assigned to the graph. It is a pointer to -a null terminated character string of length from 1 to 255 characters. -If no name is assigned to the graph, this field contains \verb|NULL|. -\end{comment} - -\noindent -\verb|int nv;| - -\begin{comment}The number of vertices in the graph, $nv\geq 0$. -\end{comment} - -\noindent -\verb|int na;| - -\begin{comment}The number of arcs in the graph, $na\geq 0$. -\end{comment} - -\newpage - -\noindent -\verb|glp_vertex **v;| - -\begin{comment}Pointer to an array containing the list of vertices. -Element $v[0]$ is not used. Element $v[i]$, $1\leq i\leq nv$, is a -pointer to $i$-th vertex of the graph. Note that on adding new vertices -to the graph the field $v$ may be altered due to reallocation. However, -pointers $v[i]$ are not changed while corresponding vertices exist in -the graph. -\end{comment} - -\noindent -\verb|int v_size;| - -\begin{comment}Size of vertex data blocks, in bytes, -$0\leq v\_size\leq 256$. (See also the field \verb|data| in the struct -\verb|glp_vertex|.) -\end{comment} - -\noindent -\verb|int a_size;| - -\begin{comment}Size of arc data blocks, in bytes, -$0\leq v\_size\leq 256$. (See also the field \verb|data| in the struct -\verb|glp_arc|.) -\end{comment} - -\para{\bf glp\_vertex.} The struct \verb|glp_vertex| has the following -fields available to the application program: - -\noindent -\verb|int i;| - -\begin{comment}Ordinal number of the vertex, $1\leq i\leq nv$. Note -that element $v[i]$ in the struct \verb|glp_graph| points to the vertex, -whose ordinal number is $i$. -\end{comment} - -\noindent -\verb|char *name;| - -\begin{comment}Symbolic name assigned to the vertex. It is a pointer to -a null terminated character string of length from 1 to 255 characters. -If no name is assigned to the vertex, this field contains \verb|NULL|. -\end{comment} - -\noindent -\verb|void *data;| - -\begin{comment}Pointer to a data block associated with the vertex. This -data block is automatically allocated on creating a new vertex and freed -on deleting the vertex. If $v\_size=0$, the block is not allocated, and -this field contains \verb|NULL|. -\end{comment} - -\noindent -\verb|void *temp;| - -\begin{comment}Working pointer, which may be used freely for any -purposes. The application program can change this field directly. -\end{comment} - -\noindent -\verb|glp_arc *in;| - -\begin{comment}Pointer to the (unordered) list of incoming arcs. If the -vertex has no incoming arcs, this field contains \verb|NULL|. -\end{comment} - -\noindent -\verb|glp_arc *out;| - -\begin{comment}Pointer to the (unordered) list of outgoing arcs. If the -vertex has no outgoing arcs, this field contains \verb|NULL|. -\end{comment} - -\para{\bf glp\_arc.} The struct \verb|glp_arc| has the following fields -available to the application program: - -\noindent -\verb|glp_vertex *tail;| - -\begin{comment}Pointer to a vertex, which is tail endpoint of the arc. -\end{comment} - -\noindent -\verb|glp_vertex *head;| - -\begin{comment}Pointer to a vertex, which is head endpoint of the arc. -\end{comment} - -\newpage - -\noindent -\verb|void *data;| - -\begin{comment}Pointer to a data block associated with the arc. This -data block is automatically allocated on creating a new arc and freed on -deleting the arc. If $v\_size=0$, the block is not allocated, and this -field contains \verb|NULL|. -\end{comment} - -\noindent -\verb|void *temp;| - -\begin{comment}Working pointer, which may be used freely for any -purposes. The application program can change this field directly. -\end{comment} - -\noindent -\verb|glp_arc *t_next;| - -\begin{comment}Pointer to another arc, which has the same tail endpoint -as this one. \verb|NULL| in this field indicates the end of the list of -outgoing arcs. -\end{comment} - -\noindent -\verb|glp_arc *h_next;| - -\begin{comment}Pointer to another arc, which has the same head endpoint -as this one. \verb|NULL| in this field indicates the end of the list of -incoming arcs. -\end{comment} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Graph creating and modifying routines} - -\subsection{glp\_create\_graph --- create graph} - -\synopsis - -\begin{verbatim} - glp_graph *glp_create_graph(int v_size, int a_size); -\end{verbatim} - -\description - -The routine \verb|glp_create_graph| creates a new graph, which -initially is empty, i.e. has no vertices and arcs. - -The parameter \verb|v_size| specifies the size of vertex data blocks, -in bytes, $0\leq v\_size\leq 256$. - -The parameter \verb|a_size| specifies the size of arc data blocks, in -bytes, $0\leq a\_size\leq 256$. - -\returns - -The routine returns a pointer to the graph object created. - -\subsection{glp\_set\_graph\_name --- assign (change) graph name} - -\synopsis - -\begin{verbatim} - void glp_set_graph_name(glp_graph *G, const char *name); -\end{verbatim} - -\description - -The routine \verb|glp_set_graph_name| assigns a symbolic name specified -by the character string \verb|name| (1 to 255 chars) to the graph. - -If the parameter \verb|name| is \verb|NULL| or an empty string, the -routine erases the existing symbolic name of the graph. - -\subsection{glp\_add\_vertices --- add new vertices to graph} - -\synopsis - -\begin{verbatim} - int glp_add_vertices(glp_graph *G, int nadd); -\end{verbatim} - -\description - -The routine \verb|glp_add_vertices| adds \verb|nadd| vertices to the -specified graph. New vertices are always added to the end of the vertex -list, so ordinal numbers of existing vertices remain unchanged. Note -that this operation may change the field \verb|v| in the struct -\verb|glp_graph| (pointer to the vertex array) due to reallocation. - -Being added each new vertex is isolated, i.e. has no incident arcs. - -If the size of vertex data blocks specified on creating the graph is -non-zero, the routine also allocates a memory block of that size for -each new vertex added, fills it by binary zeros, and stores a pointer -to it in the field \verb|data| of the struct \verb|glp_vertex|. -Otherwise, if the block size is zero, the field \verb|data| is set to -\verb|NULL|. - -\returns - -The routine \verb|glp_add_vertices| returns the ordinal number of the -first new vertex added to the graph. - -\subsection{glp\_set\_vertex\_name --- assign (change) vertex name} - -\synopsis - -\begin{verbatim} - void glp_set_vertex_name(glp_graph *G, int i, const char *name); -\end{verbatim} - -\description - -The routine \verb|glp_set_vertex_name| assigns a given symbolic name -(1 up to 255 characters) to \verb|i|-th vertex of the specified graph. - -If the parameter \verb|name| is \verb|NULL| or empty string, the -routine erases an existing name of \verb|i|-th vertex. - -\subsection{glp\_add\_arc --- add new arc to graph} - -\synopsis - -\begin{verbatim} - glp_arc *glp_add_arc(glp_graph *G, int i, int j); -\end{verbatim} - -\description - -The routine \verb|glp_add_arc| adds one new arc to the specified graph. - -The parameters \verb|i| and \verb|j| specify the ordinal numbers of, -resp., tail and head endpoints (vertices) of the arc. Note that -self-loops and multiple arcs are allowed. - -If the size of arc data blocks specified on creating the graph is -non-zero, the routine also allocates a memory block of that size, fills -it by binary zeros, and stores a pointer to it in the field \verb|data| -of the struct \verb|glp_arc|. Otherwise, if the block size is zero, the -field \verb|data| is set to \verb|NULL|. - -\subsection{glp\_del\_vertices --- delete vertices from graph} - -\synopsis - -\begin{verbatim} - void glp_del_vertices(glp_graph *G, int ndel, const int num[]); -\end{verbatim} - -\description - -The routine \verb|glp_del_vertices| deletes vertices along with all -incident arcs from the specified graph. Ordinal numbers of vertices to -be deleted should be placed in locations \verb|num[1]|, \dots, -\verb|num[ndel]|, \verb|ndel| $>0$. - -Note that deleting vertices involves changing ordinal numbers of other -vertices remaining in the graph. New ordinal numbers of the remaining -vertices are assigned under the assumption that the original order of -vertices is not changed. - -\newpage - -\subsection{glp\_del\_arc --- delete arc from graph} - -\synopsis - -\begin{verbatim} - void glp_del_arc(glp_graph *G, glp_arc *a); -\end{verbatim} - -\description - -The routine \verb|glp_del_arc| deletes an arc from the specified graph. -The arc to be deleted must exist. - -\subsection{glp\_erase\_graph --- erase graph content} - -\synopsis - -\begin{verbatim} - void glp_erase_graph(glp_graph *G, int v_size, int a_size); -\end{verbatim} - -\description - -The routine \verb|glp_erase_graph| erases the content of the specified -graph. The effect of this operation is the same as if the graph would -be deleted with the routine \verb|glp_delete_graph| and then created -anew with the routine \verb|glp_create_graph|, with exception that the -pointer to the graph remains valid. - -The parameters \verb|v_size| and \verb|a_size| have the same meaning as -for \verb|glp_create_graph|. - -\subsection{glp\_delete\_graph --- delete graph} - -\synopsis - -\begin{verbatim} - void glp_delete_graph(glp_graph *G); -\end{verbatim} - -\description - -The routine \verb|glp_delete_graph| deletes the specified graph and -frees all the memory allocated to this program object. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Graph searching routines} - -\subsection{glp\_create\_v\_index --- create vertex name index} - -\synopsis - -\begin{verbatim} - void glp_create_v_index(glp_graph *G); -\end{verbatim} - -\description - -The routine \verb|glp_create_v_index| creates the name index for the -specified graph. The name index is an auxiliary data structure, which -is intended to quickly (i.e. for logarithmic time) find vertices by -their names. - -This routine can be called at any time. If the name index already -exists, the routine does nothing. - -\subsection{glp\_find\_vertex --- find vertex by its name} - -\synopsis - -\begin{verbatim} - int glp_find_vertex(glp_graph *G, const char *name); -\end{verbatim} - -\returns - -The routine \verb|glp_find_vertex| returns the ordinal number of -a vertex, which is assigned (by the routine \verb|glp_set_vertex_name|) -the specified symbolic \verb|name|. If no such vertex exists, the -routine returns 0. - -\subsection{glp\_delete\_v\_index --- delete vertex name index} - -\synopsis - -\begin{verbatim} - void glp_delete_v_index(glp_graph *G); -\end{verbatim} - -\description - -The routine \verb|glp_delete_v_index| deletes the name index previously -created by the routine \verb|glp_create_v_index| and frees the memory -allocated to this auxiliary data structure. - -This routine can be called at any time. If the name index does not -exist, the routine does nothing. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Graph reading/writing routines} - -\subsection{glp\_read\_graph --- read graph from plain text file} - -\synopsis - -\begin{verbatim} - int glp_read_graph(glp_graph *G, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_read_graph| reads a graph from a plain text file, -whose name is specified by the parameter \verb|fname|. Note that before -reading data the current content of the graph object is completely -erased with the routine \verb|glp_erase_graph|. - -For the file format see description of the routine -\verb|glp_write_graph|. - -\returns - -If the operation was successful, the routine returns zero. Otherwise -it prints an error message and returns non-zero. - -\subsection{glp\_write\_graph --- write graph to plain text file} - -\synopsis - -\begin{verbatim} - int glp_write_graph(glp_graph *G, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_write_graph| writes the graph to a plain text -file, whose name is specified by the parameter \verb|fname|. - -\returns - -If the operation was successful, the routine returns zero. Otherwise -it prints an error message and returns non-zero. - -\para{File format} - -The file created by the routine \verb|glp_write_graph| is a plain text -file, which contains the following information: - -\begin{verbatim} - nv na - i[1] j[1] - i[2] j[2] - . . . - i[na] j[na] -\end{verbatim} - -\noindent -where: \verb|nv| is the number of vertices (nodes); \verb|na| is the -number of arcs; \verb|i[k]|, $k=1,\dots,na$, is the index of tail -vertex of arc $k$; \verb|j[k]|, $k=1,\dots,na$, is the index of head -vertex of arc $k$. - -\newpage - -\subsection{glp\_read\_ccdata --- read graph from text file in DIMACS -clique/coloring\\format} - -\synopsis - -\begin{verbatim} - int glp_read_ccdata(glp_graph *G, int v_wgt, const char *fname); -\end{verbatim} - -\description - -The routine {\tt glp\_read\_ccdata} reads a graph from a text file in -DIMACS clique/coloring format. (Though this format is originally -designed to represent data for the minimal vertex coloring and maximal -clique problems, it may be used to represent general undirected and -directed graphs, because the routine allows reading self-loops and -multiple edges/arcs keeping the order of vertices specified for each -edge/arc of the graph.) - -The parameter {\tt G} specifies the graph object to be read in. Note -that before reading data the current content of the graph object is -completely erased with the routine {\tt glp\_erase\_graph}. - -The parameter {\tt v\_wgt} specifies an offset of the field of type -{\tt double} in the vertex data block, to which the routine stores the -vertex weight. If {\tt v\_wgt} $<0$, the vertex weights are not stored. - -The character string {\tt fname} specifies the name of a text file to -be read in. (If the file name ends with the suffix `\verb|.gz|', the -file is assumed to be compressed, in which case the routine -decompresses it ``on the fly''.) - -\returns - -If the operation was successful, the routine returns zero. Otherwise, -it prints an error message and returns non-zero. - -\para{DIMACS clique/coloring format\footnote{This material is -based on the paper ``Clique and Coloring Problems Graph Format'', which -is publically available at \url{http://dimacs.rutgers.edu/Challenges}.}} - -The DIMACS input file is a plain ASCII text file. It contains -{\it lines} of several types described below. A line is terminated with -an end-of-line character. Fields in each line are separated by at least -one blank space. Each line begins with a one-character designator to -identify the line type. - -Note that DIMACS requires all numerical quantities to be integers in -the range $[-2^{31},2^{31}-1]$ while GLPK allows the quantities to be -floating-point numbers. - -\para{Comment lines.} Comment lines give human-readable information -about the file and are ignored by programs. Comment lines can appear -anywhere in the file. Each comment line begins with a lower-case -character \verb|c|. - -\begin{verbatim} - c This is a comment line -\end{verbatim} - -\para{Problem line.} There is one problem line per data file. -The problem line must appear before any node or edge descriptor lines. -It has the following format: - -\begin{verbatim} - p edge NODES EDGES -\end{verbatim} - -\noindent -The lower-case letter \verb|p| signifies that this is a problem line. -The four-character problem designator \verb|edge| identifies the file -as containing data for the minimal vertex coloring or maximal clique -problem. The \verb|NODES| field contains an integer value specifying -the number of vertices in the graph. The \verb|EDGES| field contains an -integer value specifying the number of edges (arcs) in the graph. - -\para{Vertex descriptors.} These lines give the weight assigned to -a vertex of the graph. There is one vertex descriptor line for each -vertex, with the following format. Vertices without a descriptor take -on a default value of 1. - -\begin{verbatim} - n ID VALUE -\end{verbatim} - -\noindent -The lower-case character \verb|n| signifies that this is a vertex -descriptor line. The \verb|ID| field gives a vertex identification -number, an integer between 1 and $n$, where $n$ is the number of -vertices in the graph. The \verb|VALUE| field gives a vertex weight, -which can either positive or negative (or zero). - -\para{Edge descriptors.} There is one edge descriptor line for each -edge (arc) of the graph, each with the following format: - -\begin{verbatim} - e I J -\end{verbatim} - -\noindent -The lower-case character \verb|e| signifies that this is an edge -descriptor line. For an edge (arc) $(i,j)$ the fields \verb|I| and -\verb|J| specify its endpoints. - -\para{Example.} The following example of an undirected graph: - -\bigskip - -\noindent\hfil -\xymatrix %@C=32pt -{&{v_1}\ar@{-}[ldd]\ar@{-}[dd]\ar@{-}[rd]\ar@{-}[rr]&&{v_2}\ar@{-}[ld] -\ar@{-}[dd]\ar@{-}[rdd]&\\ -&&{v_7}\ar@{-}[ld]\ar@{-}[rd]&&\\ -{v_6}\ar@{-}[r]\ar@{-}[rdd]&{v_{10}}\ar@{-}[rr]\ar@{-}[rd]\ar@{-}[dd]&& -{v_8}\ar@{-}[ld]\ar@{-}[dd]\ar@{-}[r]&{v_3}\ar@{-}[ldd]\\ -&&{v_9}\ar@{-}[ld]\ar@{-}[rd]&&\\ -&{v_5}\ar@{-}[rr]&&{v_4}&\\ -} - -\bigskip - -\noindent -might be coded in DIMACS clique/coloring format as follows: - -\begin{footnotesize} -\begin{verbatim} -c sample.col -c -c This is an example of the vertex coloring problem data -c in DIMACS format. -c -p edge 10 21 -c -e 1 2 -e 1 6 -e 1 7 -e 1 10 -e 2 3 -e 2 7 -e 2 8 -e 3 4 -e 3 8 -e 4 5 -e 4 8 -e 4 9 -e 5 6 -e 5 9 -e 5 10 -e 6 10 -e 7 8 -e 7 10 -e 8 9 -e 8 10 -e 9 10 -c -c eof -\end{verbatim} -\end{footnotesize} - -\subsection{glp\_write\_ccdata --- write graph to text file in DIMACS -clique/coloring\\format} - -\synopsis - -\begin{verbatim} - int glp_write_ccdata(glp_graph *G, int v_wgt, const char *fname); -\end{verbatim} - -\description - -The routine {\tt glp\_write\_ccdata} writes the graph object specified -by the parameter {\tt G} to a text file in DIMACS clique/coloring -format. (Though this format is originally designed to represent data -for the minimal vertex coloring and maximal clique problems, it may be -used to represent general undirected and directed graphs, because the -routine allows writing self-loops and multiple edges/arcs keeping the -order of vertices specified for each edge/arc of the graph.) - -The parameter {\tt v\_wgt} specifies an offset of the field of type -{\tt double} in the vertex data block, which contains the vertex -weight. If {\tt v\_wgt} $<0$, it is assumed that the weight of each -vertex is 1. - -The character string {\tt fname} specifies a name of the text file to -be written out. (If the file name ends with suffix `\verb|.gz|', the -file is assumed to be compressed, in which case the routine performs -automatic compression on writing it.) - -\returns - -If the operation was successful, the routine returns zero. Otherwise, -it prints an error message and returns non-zero. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Graph analysis routines} - -\subsection{glp\_weak\_comp --- find all weakly connected components of -graph} - -\synopsis - -\begin{verbatim} - int glp_weak_comp(glp_graph *G, int v_num); -\end{verbatim} - -\description - -The routine \verb|glp_weak_comp| finds all weakly connected components -of the specified graph. - -The parameter \verb|v_num| specifies an offset of the field of type -\verb|int| in the vertex data block, to which the routine stores the -number of a weakly connected component containing that vertex. If -\verb|v_num| $<0$, no component numbers are stored. - -The components are numbered in arbitrary order from 1 to \verb|nc|, -where \verb|nc| is the total number of components found, -$0\leq$ \verb|nc| $\leq|V|$. - -\returns - -The routine returns \verb|nc|, the total number of components found. - -\subsection{glp\_strong\_comp --- find all strongly connected -components of graph} - -\synopsis - -\begin{verbatim} - int glp_strong_comp(glp_graph *G, int v_num); -\end{verbatim} - -\description - -The routine \verb|glp_strong_comp| finds all strongly connected -components of the specified graph. - -The parameter \verb|v_num| specifies an offset of the field of type -\verb|int| in the vertex data block, to which the routine stores the -number of a strongly connected component containing that vertex. If -\verb|v_num| $<0$, no component numbers are stored. - -The components are numbered in arbitrary order from 1 to \verb|nc|, -where \verb|nc| is the total number of components found, -$0\leq$ \verb|nc| $\leq|V|$. However, the component numbering has the -property that for every arc $(i\rightarrow j)$ in the graph the -condition $num(i)\geq num(j)$ holds. - -\returns - -The routine returns \verb|nc|, the total number of components found. - -\para{References} - -I.~S.~Duff, J.~K.~Reid, Algorithm 529: Permutations to block triangular -form, ACM Trans. on Math. Softw. 4 (1978), 189-92. - -\newpage - -\para{Example} - -The following program reads a graph from a plain text file -`\verb|graph.txt|' and finds all its strongly connected components. - -\begin{footnotesize} -\begin{verbatim} -#include -#include -#include -#include - -typedef struct { int num; } v_data; - -#define vertex(v) ((v_data *)((v)->data)) - -int main(void) -{ glp_graph *G; - int i, nc; - G = glp_create_graph(sizeof(v_data), 0); - glp_read_graph(G, "graph.txt"); - nc = glp_strong_comp(G, offsetof(v_data, num)); - printf("nc = %d\n", nc); - for (i = 1; i <= G->nv; i++) - printf("num[%d] = %d\n", i, vertex(G->v[i])->num); - glp_delete_graph(G); - return 0; -} -\end{verbatim} -\end{footnotesize} - -\noindent -If the file `\verb|graph.txt|' contains the following graph: - -\medskip - -\noindent\hfil -\xymatrix -{1\ar[r]&2\ar[r]&3\ar[r]\ar[dd]&4\ar[dd]\\ -5\ar[u]&6\ar[l]\\ -7\ar[u]&&8\ar[lu]\ar[ll]\ar[r]&9\ar[r]&10\ar[r]\ar[d]&11\ar[d]\\ -12\ar[u]\ar[rru]\ar@/_/[rr]&&13\ar[ll]\ar[u]\ar[rr]&&14\ar[lu]&15\ar[l] -\\ -} - -\medskip\medskip - -\noindent -the program output may look like follows: - -\begin{footnotesize} -\begin{verbatim} -Reading graph from `graph.txt'... -Graph has 15 vertices and 30 arcs -31 lines were read -nc = 4 -num[1] = 3 -num[2] = 3 -num[3] = 3 -num[4] = 2 -num[5] = 3 -num[6] = 3 -num[7] = 3 -num[8] = 3 -num[9] = 1 -num[10] = 1 -num[11] = 1 -num[12] = 4 -num[13] = 4 -num[14] = 1 -num[15] = 1 -\end{verbatim} -\end{footnotesize} - -\subsection{glp\_top\_sort --- topological sorting of acyclic digraph} - -\synopsis - -\begin{verbatim} - int glp_top_sort(glp_graph *G, int v_num); -\end{verbatim} - -\description - -The routine \verb|glp_top_sort| performs topological sorting of -vertices of the specified acyclic digraph. - -The parameter \verb|v_num| specifies an offset of the field of type -\verb|int| in the vertex data block, to which the routine stores the -vertex number assigned. If \verb|v_num| $<0$, vertex numbers are not -stored. - -The vertices are numbered from 1 to $n$, where $n$ is the total number -of vertices in the graph. The vertex numbering has the property that -for every arc $(i\rightarrow j)$ in the graph the condition -$num(i) -#include -#include -#include - -typedef struct { int num; } v_data; - -#define vertex(v) ((v_data *)((v)->data)) - -int main(void) -{ glp_graph *G; - int i, cnt; - G = glp_create_graph(sizeof(v_data), 0); - glp_read_graph(G, "graph.txt"); - cnt = glp_top_sort(G, offsetof(v_data, num)); - printf("cnt = %d\n", cnt); - for (i = 1; i <= G->nv; i++) - printf("num[%d] = %d\n", i, vertex(G->v[i])->num); - glp_delete_graph(G); - return 0; -} -\end{verbatim} -\end{footnotesize} - -\noindent -If the file `\verb|graph.txt|' contains the following graph: - -\medskip - -\noindent\hfil -\xymatrix @=20pt -{ -1\ar[rrr]&&&2\ar[r]\ar[rddd]&3\ar[rd]&&&&\\ -&&&4\ar[ru]&&5\ar[r]&6\ar[rd]\ar[dd]&&\\ -7\ar[r]&8\ar[r]&9\ar[ruu]\ar[ru]\ar[r]\ar[rd]&10\ar[rr]\ar[rru]&& -11\ar[ru]&&12\ar[r]&13\\ -&&&14\ar[r]&15\ar[rrru]\ar[rr]&&16\ar[rru]\ar[rr]&&17\\ -} - -\medskip\medskip - -\noindent -the program output may look like follows: - -\begin{footnotesize} -\begin{verbatim} -Reading graph from `graph.txt'... -Graph has 17 vertices and 23 arcs -24 lines were read -cnt = 0 -num[1] = 8 -num[2] = 9 -num[3] = 10 -num[4] = 4 -num[5] = 11 -num[6] = 12 -num[7] = 1 -num[8] = 2 -num[9] = 3 -num[10] = 5 -num[11] = 6 -num[12] = 14 -num[13] = 16 -num[14] = 7 -num[15] = 13 -num[16] = 15 -num[17] = 17 -\end{verbatim} -\end{footnotesize} - -\noindent -The output corresponds to the following vertex numbering: - -\medskip - -\noindent\hfil -\xymatrix @=20pt -{ -8\ar[rrr]&&&9\ar[r]\ar[rddd]&10\ar[rd]&&&&\\ -&&&4\ar[ru]&&11\ar[r]&12\ar[rd]\ar[dd]&&\\ -1\ar[r]&2\ar[r]&3\ar[ruu]\ar[ru]\ar[r]\ar[rd]&5\ar[rr]\ar[rru]&& -6\ar[ru]&&14\ar[r]&16\\ -&&&7\ar[r]&13\ar[rrru]\ar[rr]&&15\ar[rru]\ar[rr]&&17\\ -} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\chapter{Network optimization API routines} - -\section{Minimum cost flow problem} - -\subsection{Background} - -The {\it minimum cost flow problem} (MCFP) is stated as follows. Let -there be given a directed graph (flow network) $G=(V,A)$, where $V$ is -a set of vertices (nodes), and $A\subseteq V\times V$ is a set of arcs. -Let for each node $i\in V$ there be given a quantity $b_i$ having the -following meaning: - -if $b_i>0$, then $|b_i|$ is a {\it supply} at node $i$, which shows -how many flow units are {\it generated} at node $i$ (or, equivalently, -entering the network through node $i$ from outside); - -if $b_i<0$, then $|b_i|$ is a {\it demand} at node $i$, which shows how -many flow units are {\it lost} at node $i$ (or, equivalently, leaving -the network through node $i$ to outside); - -if $b_i=0$, then $i$ is a {\it transshipment} node, at which the flow -is conserved, i.e. neither generated nor lost. - -Let also for each arc $a=(i,j)\in A$ there be given the following three -quantities: - -$l_{ij}$, a (non-negative) lower bound to the flow through arc $(i,j)$; - -$u_{ij}$, an upper bound to the flow through arc $(i,j)$, which is the -{\it arc capacity}; - -$c_{ij}$, a per-unit cost of the flow through arc $(i,j)$. - -The problem is to find flows $x_{ij}$ through every arc of the network, -which satisfy the specified bounds and the conservation constraints at -all nodes, and minimize the total flow cost. Here the conservation -constraint at a node means that the total flow entering this node -through its incoming arcs plus the supply at this node must be equal to -the total flow leaving this node through its outgoing arcs plus the -demand at this node. - -An example of the minimum cost flow problem is shown on Fig.~1. - -\newpage - -\noindent\hfil -\xymatrix @C=48pt -{_{20}\ar@{~>}[d]& -v_2\ar[r]|{_{0,10,\$2}}\ar[dd]|{_{0,9,\$3}}& -v_3\ar[dd]|{_{2,12,\$1}}\ar[r]|{_{0,18,\$0}}& -v_8\ar[rd]|{_{0,20,\$9}}&\\ -v_1\ar[ru]|{_{0,14,\$0}}\ar[rd]|{_{0,23,\$0}}&&& -v_6\ar[d]|{_{0,7,\$0}}\ar[u]|{_{4,8,\$0}}& -v_9\ar@{~>}[d]\\ -&v_4\ar[r]|{_{0,26,\$0}}& -v_5\ar[luu]|{_{0,11,\$1}}\ar[ru]|{_{0,25,\$5}}\ar[r]|{_{0,4,\$7}}& -v_7\ar[ru]|{_{0,15,\$3}}&_{20}\\ -} - -\noindent\hfil -\begin{tabular}{ccc} -\xymatrix @C=48pt{v_i\ar[r]|{\ l,u,\$c\ }&v_j\\}& -\xymatrix{\hbox{\footnotesize supply}\ar@{~>}[r]&v_i\\}& -\xymatrix{v_i\ar@{~>}[r]&\hbox{\footnotesize demand}\\}\\ -\end{tabular} - -\noindent\hfil -Fig.~1. An example of the minimum cost flow problem. - -\medskip - -The minimum cost flow problem can be naturally formulated as the -following LP problem: - -\noindent -\hspace{1in}minimize -$$z=\sum_{(i,j)\in A}c_{ij}x_{ij}\eqno(1)$$ -\hspace{1in}subject to -$$\sum_{(i,j)\in A}x_{ij}-\sum_{(j,i)\in A}x_{ji}=b_i\ \ \ \hbox -{for all}\ i\in V\eqno(2)$$ -$$l_{ij}\leq x_{ij}\leq u_{ij}\ \ \ \hbox{for all}\ (i,j)\in A -\eqno(3)$$ - -\subsection{glp\_read\_mincost --- read minimum cost flow problem data -in DIMACS\\format} - -\synopsis - -\begin{verbatim} - int glp_read_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, - int a_cost, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_read_mincost| reads the minimum cost flow problem -data from a text file in DIMACS format. - -The parameter \verb|G| specifies the graph object, to which the problem -data have to be stored. Note that before reading data the current -content of the graph object is completely erased with the routine -\verb|glp_erase_graph|. - -The parameter \verb|v_rhs| specifies an offset of the field of type -\verb|double| in the vertex data block, to which the routine stores -$b_i$, the supply/demand value. If \verb|v_rhs| $<0$, the value is not -stored. - -The parameter \verb|a_low| specifies an offset of the field of type -\verb|double| in the arc data block, to which the routine stores -$l_{ij}$, the lower bound to the arc flow. If \verb|a_low| $<0$, the -lower bound is not stored. - -The parameter \verb|a_cap| specifies an offset of the field of type -\verb|double| in the arc data block, to which the routine stores -$u_{ij}$, the upper bound to the arc flow (the arc capacity). If -\verb|a_cap| $<0$, the upper bound is not stored. - -The parameter \verb|a_cost| specifies an offset of the field of type -\verb|double| in the arc data block, to which the routine stores -$c_{ij}$, the per-unit cost of the arc flow. If \verb|a_cost| $<0$, the -cost is not stored. - -The character string \verb|fname| specifies the name of a text file to -be read in. (If the file name name ends with the suffix `\verb|.gz|', -the file is assumed to be compressed, in which case the routine -decompresses it ``on the fly''.) - -\returns - -If the operation was successful, the routine returns zero. Otherwise, -it prints an error message and returns non-zero. - -\para{Example} - -\begin{footnotesize} -\begin{verbatim} -typedef struct -{ /* vertex data block */ - ... - double rhs; - ... -} v_data; - -typedef struct -{ /* arc data block */ - ... - double low, cap, cost; - ... -} a_data; - -int main(void) -{ glp_graph *G; - int ret; - G = glp_create_graph(sizeof(v_data), sizeof(a_data)); - ret = glp_read_mincost(G, offsetof(v_data, rhs), - offsetof(a_data, low), offsetof(a_data, cap), - offsetof(a_data, cost), "sample.min"); - if (ret != 0) goto ... - ... -} -\end{verbatim} -\end{footnotesize} - -\para{DIMACS minimum cost flow problem format\footnote{This -material is based on the paper ``The First DIMACS International -Algorithm Implementation Challenge: Problem Definitions and -Specifications'', which is publically available at -\url{http://dimacs.rutgers.edu/Challenges}.}} -\label{subsecmincost} - -The DIMACS input file is a plain ASCII text file. It contains -{\it lines} of several types described below. A line is terminated with -an end-of-line character. Fields in each line are separated by at least -one blank space. Each line begins with a one-character designator to -identify the line type. - -Note that DIMACS requires all numerical quantities to be integers in -the range $[-2^{31},\ 2^{31}-1]$ while GLPK allows the quantities to be -floating-point numbers. - -\para{Comment lines.} Comment lines give human-readable information -about the file and are ignored by programs. Comment lines can appear -anywhere in the file. Each comment line begins with a lower-case -character \verb|c|. - -\begin{verbatim} - c This is a comment line -\end{verbatim} - -\newpage - -\para{Problem line.} There is one problem line per data file. The -problem line must appear before any node or arc descriptor lines. It -has the following format: - -\begin{verbatim} - p min NODES ARCS -\end{verbatim} - -\noindent -The lower-case character \verb|p| signifies that this is a problem line. -The three-character problem designator \verb|min| identifies the file as -containing specification information for the minimum cost flow problem. -The \verb|NODES| field contains an integer value specifying the number -of nodes in the network. The \verb|ARCS| field contains an integer value -specifying the number of arcs in the network. - -\para{Node descriptors.} All node descriptor lines must appear before -all arc descriptor lines. The node descriptor lines describe supply and -demand nodes, but not transshipment nodes. That is, only nodes with -non-zero node supply/demand values appear. There is one node descriptor -line for each such node, with the following format: - -\begin{verbatim} - n ID FLOW -\end{verbatim} - -\noindent -The lower-case character \verb|n| signifies that this is a node -descriptor line. The \verb|ID| field gives a node identification -number, an integer between 1 and \verb|NODES|. The \verb|FLOW| field -gives the amount of supply (if positive) or demand (if negative) at -node \verb|ID|. - -\para{Arc descriptors.} There is one arc descriptor line for each arc -in the network. Arc descriptor lines are of the following format: - -\begin{verbatim} - a SRC DST LOW CAP COST -\end{verbatim} - -\noindent -The lower-case character \verb|a| signifies that this is an arc -descriptor line. For a directed arc $(i,j)$ the \verb|SRC| field gives -the identification number $i$ for the tail endpoint, and the \verb|DST| -field gives the identification number $j$ for the head endpoint. -Identification numbers are integers between 1 and \verb|NODES|. The -\verb|LOW| field specifies the minimum amount of flow that can be sent -along arc $(i,j)$, and the \verb|CAP| field gives the maximum amount of -flow that can be sent along arc $(i,j)$ in a feasible flow. The -\verb|COST| field contains the per-unit cost of flow sent along arc -$(i,j)$. - -\para{Example.} Below here is an example of the data file in DIMACS -format corresponding to the minimum cost flow problem shown on Fig~1. - -\begin{footnotesize} -\begin{verbatim} -c sample.min -c -c This is an example of the minimum cost flow problem data -c in DIMACS format. -c -p min 9 14 -c -n 1 20 -n 9 -20 -c -a 1 2 0 14 0 -a 1 4 0 23 0 -a 2 3 0 10 2 -a 2 4 0 9 3 -a 3 5 2 12 1 -a 3 8 0 18 0 -a 4 5 0 26 0 -a 5 2 0 11 1 -a 5 6 0 25 5 -a 5 7 0 4 7 -a 6 7 0 7 0 -a 6 8 4 8 0 -a 7 9 0 15 3 -a 8 9 0 20 9 -c -c eof -\end{verbatim} -\end{footnotesize} - -\subsection{glp\_write\_mincost --- write minimum cost flow problem -data in DIMACS\\format} - -\synopsis - -\begin{verbatim} - int glp_write_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, - int a_cost, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_write_mincost| writes the minimum cost flow -problem data to a text file in DIMACS format. - -The parameter \verb|G| is the graph (network) program object, which -specifies the minimum cost flow problem instance. - -The parameter \verb|v_rhs| specifies an offset of the field of type -\verb|double| in the vertex data block, which contains $b_i$, the -supply/demand value. If \verb|v_rhs| $<0$, it is assumed that $b_i=0$ -for all nodes. - -The parameter \verb|a_low| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $l_{ij}$, the lower -bound to the arc flow. If \verb|a_low| $<0$, it is assumed that -$l_{ij}=0$ for all arcs. - -The parameter \verb|a_cap| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $u_{ij}$, the upper -bound to the arc flow (the arc capacity). If the upper bound is -specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e. -the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that -$u_{ij}=1$ for all arcs. - -The parameter \verb|a_cost| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $c_{ij}$, the -per-unit cost of the arc flow. If \verb|a_cost| $<0$, it is assumed -that $c_{ij}=0$ for all arcs. - -The character string \verb|fname| specifies a name of the text file to -be written out. (If the file name ends with suffix `\verb|.gz|', the -file is assumed to be compressed, in which case the routine performs -automatic compression on writing it.) - -\returns - -If the operation was successful, the routine returns zero. Otherwise, -it prints an error message and returns non-zero. - -\newpage - -\subsection{glp\_mincost\_lp --- convert minimum cost flow problem -to LP} - -\synopsis - -\begin{verbatim} - void glp_mincost_lp(glp_prob *P, glp_graph *G, int names, int v_rhs, - int a_low, int a_cap, int a_cost); -\end{verbatim} - -\description - -The routine \verb|glp_mincost_lp| builds LP problem (1)---(3), which -corresponds to the specified minimum cost flow problem. - -The parameter \verb|P| is the resultant LP problem object to be built. -Note that on entry its current content is erased with the routine -\verb|glp_erase_prob|. - -The parameter \verb|G| is the graph (network) program object, which -specifies the minimum cost flow problem instance. - -The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, the -routine uses symbolic names of the graph object components to assign -symbolic names to the LP problem object components. If the flag is -\verb|GLP_OFF|, no symbolic names are assigned. - -The parameter \verb|v_rhs| specifies an offset of the field of type -\verb|double| in the vertex data block, which contains $b_i$, the -supply/demand value. If \verb|v_rhs| $<0$, it is assumed that $b_i=0$ -for all nodes. - -The parameter \verb|a_low| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $l_{ij}$, the lower -bound to the arc flow. If \verb|a_low| $<0$, it is assumed that -$l_{ij}=0$ for all arcs. - -The parameter \verb|a_cap| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $u_{ij}$, the upper -bound to the arc flow (the arc capacity). If the upper bound is -specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e. -the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that -$u_{ij}=1$ for all arcs. - -The parameter \verb|a_cost| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $c_{ij}$, the -per-unit cost of the arc flow. If \verb|a_cost| $<0$, it is assumed that -$c_{ij}=0$ for all arcs. - -\para{Example} - -The example program below reads the minimum cost problem instance in -DIMACS format from file `\verb|sample.min|', converts the instance to -LP, and then writes the resultant LP in CPLEX format to file -`\verb|mincost.lp|'. - -\begin{footnotesize} -\begin{verbatim} -#include -#include - -typedef struct { double rhs; } v_data; -typedef struct { double low, cap, cost; } a_data; - -int main(void) -{ glp_graph *G; - glp_prob *P; - G = glp_create_graph(sizeof(v_data), sizeof(a_data)); - glp_read_mincost(G, offsetof(v_data, rhs), - offsetof(a_data, low), offsetof(a_data, cap), - offsetof(a_data, cost), "sample.min"); - P = glp_create_prob(); - glp_mincost_lp(P, G, GLP_ON, offsetof(v_data, rhs), - offsetof(a_data, low), offsetof(a_data, cap), - offsetof(a_data, cost)); - glp_delete_graph(G); - glp_write_lp(P, NULL, "mincost.lp"); - glp_delete_prob(P); - return 0; -} -\end{verbatim} -\end{footnotesize} - -If `\verb|sample.min|' is the example data file from the subsection -describing \verb|glp_read_mincost|, file `\verb|mincost.lp|' may look -like follows: - -\begin{footnotesize} -\begin{verbatim} -Minimize - obj: + 3 x(2,4) + 2 x(2,3) + x(3,5) + 7 x(5,7) + 5 x(5,6) - + x(5,2) + 3 x(7,9) + 9 x(8,9) - -Subject To - r_1: + x(1,2) + x(1,4) = 20 - r_2: - x(5,2) + x(2,3) + x(2,4) - x(1,2) = 0 - r_3: + x(3,5) + x(3,8) - x(2,3) = 0 - r_4: + x(4,5) - x(2,4) - x(1,4) = 0 - r_5: + x(5,2) + x(5,6) + x(5,7) - x(4,5) - x(3,5) = 0 - r_6: + x(6,7) + x(6,8) - x(5,6) = 0 - r_7: + x(7,9) - x(6,7) - x(5,7) = 0 - r_8: + x(8,9) - x(6,8) - x(3,8) = 0 - r_9: - x(8,9) - x(7,9) = -20 - -Bounds - 0 <= x(1,4) <= 23 - 0 <= x(1,2) <= 14 - 0 <= x(2,4) <= 9 - 0 <= x(2,3) <= 10 - 0 <= x(3,8) <= 18 - 2 <= x(3,5) <= 12 - 0 <= x(4,5) <= 26 - 0 <= x(5,7) <= 4 - 0 <= x(5,6) <= 25 - 0 <= x(5,2) <= 11 - 4 <= x(6,8) <= 8 - 0 <= x(6,7) <= 7 - 0 <= x(7,9) <= 15 - 0 <= x(8,9) <= 20 - -End -\end{verbatim} -\end{footnotesize} - -\newpage - -\subsection{glp\_mincost\_okalg --- solve minimum cost flow problem -with out-of-kilter\\algorithm} - -\synopsis - -\begin{verbatim} - int glp_mincost_okalg(glp_graph *G, int v_rhs, int a_low, int a_cap, - int a_cost, double *sol, int a_x, int v_pi); -\end{verbatim} - -\description - -The routine \verb|glp_mincost_okalg| finds optimal solution to the -minimum cost flow problem with the out-of-kilter -algorithm.\footnote{GLPK implementation of the out-of-kilter algorithm -is based on the following book: L.~R.~Ford,~Jr., and D.~R.~Fulkerson, -``Flows in Networks,'' The RAND Corp., Report R-375-PR (August 1962), -Chap. III ``Minimal Cost Flow Problems,'' pp.~113-26.} Note that this -routine requires all the problem data to be integer-valued. - -The parameter \verb|G| is a graph (network) program object which -specifies the minimum cost flow problem instance to be solved. - -The parameter \verb|v_rhs| specifies an offset of the field of type -\verb|double| in the vertex data block, which contains $b_i$, the -supply/demand value. This value must be integer in the range -[$-$\verb|INT_MAX|, $+$\verb|INT_MAX|]. If \verb|v_rhs| $<0$, it is -assumed that $b_i=0$ for all nodes. - -The parameter \verb|a_low| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $l_{ij}$, the lower -bound to the arc flow. This bound must be integer in the range -[$0$, \verb|INT_MAX|]. If \verb|a_low| $<0$, it is assumed that -$l_{ij}=0$ for all arcs. - -The parameter \verb|a_cap| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $u_{ij}$, the upper -bound to the arc flow (the arc capacity). This bound must be integer in -the range [$l_{ij}$, \verb|INT_MAX|]. If \verb|a_cap| $<0$, it is -assumed that $u_{ij}=1$ for all arcs. - -The parameter \verb|a_cost| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $c_{ij}$, the -per-unit cost of the arc flow. This value must be integer in the range -[$-$\verb|INT_MAX|, $+$\verb|INT_MAX|]. If \verb|a_cost| $<0$, it is -assumed that $c_{ij}=0$ for all arcs. - -The parameter \verb|sol| specifies a location, to which the routine -stores the objective value (that is, the total cost) found. If -\verb|sol| is NULL, the objective value is not stored. - -The parameter \verb|a_x| specifies an offset of the field of type -\verb|double| in the arc data block, to which the routine stores -$x_{ij}$, the arc flow found. If \verb|a_x| $<0$, the arc flow value is -not stored. - -The parameter \verb|v_pi| specifies an offset of the field of type -\verb|double| in the vertex data block, to which the routine stores -$\pi_i$, the node potential, which is the Lagrange multiplier for the -corresponding flow conservation equality constraint (see (2) in -Subsection ``Background''). If necessary, the application program may -use the node potentials to compute $\lambda_{ij}$, reduced costs of the -arc flows $x_{ij}$, which are the Lagrange multipliers for the arc flow -bound constraints (see (3) ibid.), using the following formula: -$$\lambda_{ij}=c_{ij}-(\pi_i-\pi_j),$$ -where $c_{ij}$ is the per-unit cost for arc $(i,j)$. - -\newpage - -Note that all solution components (the objective value, arc flows, and -node potentials) computed by the routine are always integer-valued. - -\returns - -\begin{retlist} -0 & Optimal solution found.\\ - -\verb|GLP_ENOPFS| & No (primal) feasible solution exists.\\ - -\verb|GLP_EDATA| & Unable to start the search, because some problem -data are either not integer-valued or out of range. This code is also -returned if the total supply, which is the sum of $b_i$ over all source -nodes (nodes with $b_i>0$), exceeds \verb|INT_MAX|.\\ - -\verb|GLP_ERANGE| & The search was prematurely terminated because of -integer overflow.\\ - -\verb|GLP_EFAIL| & An error has been detected in the program logic. -(If this code is returned for your problem instance, please report to -\verb||.)\\ -\end{retlist} - -\para{Comments} - -By design the out-of-kilter algorithm is applicable only to networks, -where $b_i=0$ for {\it all} nodes, i.e. actually this algorithm finds a -minimal cost {\it circulation}. Due to this requirement the routine -\verb|glp_mincost_okalg| converts the original network to a network -suitable for the out-of-kilter algorithm in the following -way:\footnote{The conversion is performed internally and does not change -the original network program object passed to the routine.} - -1) it adds two auxiliary nodes $s$ and $t$; - -2) for each original node $i$ with $b_i>0$ the routine adds auxiliary -supply arc $(s\rightarrow i)$, flow $x_{si}$ through which is costless -($c_{si}=0$) and fixed to $+b_i$ ($l_{si}=u_{si}=+b_i$); - -3) for each original node $i$ with $b_i<0$ the routine adds auxiliary -demand arc $(i\rightarrow t)$, flow $x_{it}$ through which is costless -($c_{it}=0$) and fixed to $-b_i$ ($l_{it}=u_{it}=-b_i$); - -4) finally, the routine adds auxiliary feedback arc $(t\rightarrow s)$, -flow $x_{ts}$ through which is also costless ($c_{ts}=0$) and fixed to -$F$ ($l_{ts}=u_{ts}=F$), where $\displaystyle F=\sum_{b_i>0}b_i$ is the -total supply. - -\para{Example} - -The example program below reads the minimum cost problem instance in -DIMACS format from file `\verb|sample.min|', solves it by using the -routine \verb|glp_mincost_okalg|, and writes the solution found on the -standard output. - -\begin{footnotesize} -\begin{verbatim} -#include -#include -#include -#include - -typedef struct { double rhs, pi; } v_data; -typedef struct { double low, cap, cost, x; } a_data; - -#define node(v) ((v_data *)((v)->data)) -#define arc(a) ((a_data *)((a)->data)) - -int main(void) -{ glp_graph *G; - glp_vertex *v, *w; - glp_arc *a; - int i, ret; - double sol; - G = glp_create_graph(sizeof(v_data), sizeof(a_data)); - glp_read_mincost(G, offsetof(v_data, rhs), - offsetof(a_data, low), offsetof(a_data, cap), - offsetof(a_data, cost), "sample.min"); - ret = glp_mincost_okalg(G, offsetof(v_data, rhs), - offsetof(a_data, low), offsetof(a_data, cap), - offsetof(a_data, cost), &sol, offsetof(a_data, x), - offsetof(v_data, pi)); - printf("ret = %d; sol = %5g\n", ret, sol); - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - printf("node %d: pi = %5g\n", i, node(v)->pi); - for (a = v->out; a != NULL; a = a->t_next) - { w = a->head; - printf("arc %d->%d: x = %5g; lambda = %5g\n", - v->i, w->i, arc(a)->x, - arc(a)->cost - (node(v)->pi - node(w)->pi)); - } - } - glp_delete_graph(G); - return 0; -} -\end{verbatim} -\end{footnotesize} - -If `\verb|sample.min|' is the example data file from the subsection -describing \verb|glp_read_mincost|, the output may look like follows: - -\begin{footnotesize} -\begin{verbatim} -Reading min-cost flow problem data from `sample.min'... -Flow network has 9 nodes and 14 arcs -24 lines were read -ret = 0; sol = 213 -node 1: pi = -12 -arc 1->4: x = 13; lambda = 0 -arc 1->2: x = 7; lambda = 0 -node 2: pi = -12 -arc 2->4: x = 0; lambda = 3 -arc 2->3: x = 7; lambda = 0 -node 3: pi = -14 -arc 3->8: x = 5; lambda = 0 -arc 3->5: x = 2; lambda = 3 -node 4: pi = -12 -arc 4->5: x = 13; lambda = 0 -node 5: pi = -12 -arc 5->7: x = 4; lambda = -1 -arc 5->6: x = 11; lambda = 0 -arc 5->2: x = 0; lambda = 1 -node 6: pi = -17 -arc 6->8: x = 4; lambda = 3 -arc 6->7: x = 7; lambda = -3 -node 7: pi = -20 -arc 7->9: x = 11; lambda = 0 -node 8: pi = -14 -arc 8->9: x = 9; lambda = 0 -node 9: pi = -23 -\end{verbatim} -\end{footnotesize} - -\subsection{glp\_mincost\_relax4 --- solve minimum cost flow problem -with relaxation\\method of Bertsekas and Tseng (RELAX-IV)} - -\synopsis - -\begin{verbatim} - int glp_mincost_relax4(glp_graph *G, int v_rhs, int a_low, int a_cap, - int a_cost, int crash, double *sol, int a_x, int a_rc); -\end{verbatim} - -\description - -The routine \verb|glp_mincost_relax4| finds optimal solution to the -minimum cost flow problem with the relaxation method RELAX-IV developed -by Bertsekas and Tseng.\footnote{GLPK implementation of this method is -based on a C translation of the original Fortran code {\tt RELAX4} -written by Dimitri P. Bertsekas and Paul Tseng, with a contribution by -Jonathan Eckstein in the phase II initialization.} This method is one -of most efficient methods for network optimization. - -Note that this routine requires all the problem data to be -integer-valued. - -The parameter \verb|G| is a graph (network) program object which -specifies the minimum cost flow problem instance to be solved. - -The parameter \verb|v_rhs| specifies an offset of the field of type -\verb|double| in the vertex data block, which contains $b_i$, the -supply/demand value. This value must be integer in the range -[$-$\verb|INT_MAX|/4, $+$\verb|INT_MAX|/4]. If \verb|v_rhs| $<0$, it is -assumed that $b_i=0$ for all nodes. - -The parameter \verb|a_low| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $l_{ij}$, the lower -bound to the arc flow. This bound must be integer in the range -{\linebreak} [$0$, \verb|INT_MAX|/4]. If \verb|a_low| $<0$, it is -assumed that $l_{ij}=0$ for all arcs. - -The parameter \verb|a_cap| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $u_{ij}$, the upper -bound to the arc flow (the arc capacity). This bound must be integer in -the range [$l_{ij}$, \verb|INT_MAX|/4]. If \verb|a_cap| $<0$, it is -assumed that $u_{ij}=1$ for all arcs. - -The parameter \verb|a_cost| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $c_{ij}$, the -per-unit cost of the arc flow. This value must be integer in the range -[$-$\verb|INT_MAX|/4, $+$\verb|INT_MAX|/4]. If \verb|a_cost| $<0$, it -is assumed that $c_{ij}=0$ for all arcs. - -The parameter \verb|crash| is option specifying initialization method: - -0 --- default initialization is used; - -1 --- auction initialization is used. - -\noindent -If \verb|crash| = 1, initialization is performed with a special crash -procedure based on an auction/shorest path method. This option is -recommended for difficult problems where the default initialization -results in long running times. - -The parameter \verb|sol| specifies a location, to which the routine -stores the objective value (that is, the total cost) found. If -\verb|sol| is NULL, the objective value is not stored. - -\newpage - -The parameter \verb|a_x| specifies an offset of the field of type -\verb|double| in the arc data block, to which the routine stores -$x_{ij}$, the arc flow found. If \verb|a_x| $<0$, the arc flow value is -not stored. - -The parameter \verb|a_rc| specifies an offset of the field of type -\verb|double| in the arc data block, to which the routine stores -the reduced cost for corresponding arc flow (see (3) in Subsection -``Background''). If \verb|a_rc| $<0$, the reduced cost is not stored. - -Note that all solution components (the objective value, arc flows, and -node potentials) computed by the routine are always integer-valued. - -\returns - -\begin{retlist} -0 & Optimal solution found.\\ - -\verb|GLP_ENOPFS| & No (primal) feasible solution exists.\\ - -\verb|GLP_EDATA| & Unable to start the search, because some problem -data are either not integer-valued or out of range.\\ - -\verb|GLP_ERANGE| & Unable to start the search because of integer -overflow.\\ -\end{retlist} - -\para{Example} - -The example program below reads the minimum cost problem instance in -DIMACS format from file `\verb|sample.min|', solves it by using the -routine \verb|glp_mincost_relax4|, and writes the solution found on the -standard output. - -\begin{footnotesize} -\begin{verbatim} -#include -#include -#include -#include - -typedef struct { double rhs; } v_data; -typedef struct { double low, cap, cost, x, rc; } a_data; - -#define node(v) ((v_data *)((v)->data)) -#define arc(a) ((a_data *)((a)->data)) - -int main(void) -{ glp_graph *G; - glp_vertex *v, *w; - glp_arc *a; - int i, ret; - double sol; - G = glp_create_graph(sizeof(v_data), sizeof(a_data)); - glp_read_mincost(G, offsetof(v_data, rhs), - offsetof(a_data, low), offsetof(a_data, cap), - offsetof(a_data, cost), "sample.min"); - ret = glp_mincost_relax4(G, offsetof(v_data, rhs), - offsetof(a_data, low), offsetof(a_data, cap), - offsetof(a_data, cost), 0, &sol, offsetof(a_data, x), - offsetof(a_data, rc)); - printf("ret = %d; sol = %5g\n", ret, sol); - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { w = a->head; - printf("arc %d->%d: x = %5g; rc = %5g\n", - v->i, w->i, arc(a)->x, arc(a)->rc); - } - } - glp_delete_graph(G); - return 0; -} -\end{verbatim} -\end{footnotesize} - -If `\verb|sample.min|' is the example data file from the subsection -describing \verb|glp_read_mincost|, the output may look like follows: - -\begin{footnotesize} -\begin{verbatim} -Reading min-cost flow problem data from `sample.min'... -Flow network has 9 nodes and 14 arcs -24 lines were read -ret = 0; sol = 213 -arc 1->4: x = 13; rc = 0 -arc 1->2: x = 7; rc = 0 -arc 2->4: x = 0; rc = 3 -arc 2->3: x = 7; rc = 0 -arc 3->8: x = 5; rc = 0 -arc 3->5: x = 2; rc = 3 -arc 4->5: x = 13; rc = 0 -arc 5->7: x = 4; rc = -1 -arc 5->6: x = 11; rc = 0 -arc 5->2: x = 0; rc = 1 -arc 6->8: x = 4; rc = 3 -arc 6->7: x = 7; rc = -3 -arc 7->9: x = 11; rc = 0 -arc 8->9: x = 9; rc = 0 -\end{verbatim} -\end{footnotesize} - -\subsection{glp\_netgen --- Klingman's network problem generator} - -\synopsis - -\begin{verbatim} - int glp_netgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, - const int parm[1+15]); -\end{verbatim} - -\description - -The routine \verb|glp_netgen| is a GLPK version of the network problem -generator developed by Dr.~Darwin~Klingman.\footnote{D.~Klingman, -A.~Napier, and J.~Stutz. NETGEN: A program for generating large scale -capacitated assignment, transportation, and minimum cost flow networks. -Management Science 20 (1974), 814-20.} It can create capacitated and -uncapacitated minimum cost flow (or transshipment), transportation, and -assignment problems. - -The parameter \verb|G| specifies the graph object, to which the -generated problem data have to be stored. Note that on entry the graph -object is erased with the routine \verb|glp_erase_graph|. - -The parameter \verb|v_rhs| specifies an offset of the field of type -\verb|double| in the vertex data block, to which the routine stores the -supply or demand value. If \verb|v_rhs| $<0$, the value is not stored. - -The parameter \verb|a_cap| specifies an offset of the field of type -\verb|double| in the arc data block, to which the routine stores the -arc capacity. If \verb|a_cap| $<0$, the capacity is not stored. - -\newpage - -The parameter \verb|a_cost| specifies an offset of the field of type -\verb|double| in the arc data block, to which the routine stores the -per-unit cost if the arc flow. If \verb|a_cost| $<0$, the cost is not -stored. - -The array \verb|parm| contains description of the network to be -generated: - -\begin{tabular}{@{}lll@{}} -\verb|parm[0] |& ¬ used\\ -\verb|parm[1] |&\verb|iseed |&8-digit positive random number seed\\ -\verb|parm[2] |&\verb|nprob |&8-digit problem id number\\ -\verb|parm[3] |&\verb|nodes |&total number of nodes\\ -\verb|parm[4] |&\verb|nsorc |&total number of source nodes -(including transshipment nodes)\\ -\verb|parm[5] |&\verb|nsink |&total number of sink nodes -(including transshipment nodes)\\ -\verb|parm[6] |&\verb|iarcs |&number of arc\\ -\verb|parm[7] |&\verb|mincst|&minimum cost for arcs\\ -\verb|parm[8] |&\verb|maxcst|&maximum cost for arcs\\ -\verb|parm[9] |&\verb|itsup |&total supply\\ -\verb|parm[10]|&\verb|ntsorc|&number of transshipment source nodes\\ -\verb|parm[11]|&\verb|ntsink|&number of transshipment sink nodes\\ -\verb|parm[12]|&\verb|iphic |&percentage of skeleton arcs to be given -the maximum cost\\ -\verb|parm[13]|&\verb|ipcap |&percentage of arcs to be capacitated\\ -\verb|parm[14]|&\verb|mincap|&minimum upper bound for capacitated arcs\\ -\verb|parm[15]|&\verb|maxcap|&maximum upper bound for capacitated arcs\\ -\end{tabular} - -\returns - -If the instance was successfully generated, the routine -\verb|glp_netgen| returns zero; otherwise, if specified parameters are -inconsistent, the routine returns a non-zero error code. - -\para{Notes} - -1. The routine generates a transportation problem if: -$${\tt nsorc}+{\tt nsink}={\tt nodes}, -\ {\tt ntsorc}=0,\ \mbox{and}\ {\tt ntsink}=0.$$ - -2. The routine generates an assignment problem if the requirements for -a transportation problem are met and: -$${\tt nsorc}={\tt nsink}\ \mbox{and}\ {\tt itsup}={\tt nsorc}.$$ - -3. The routine always generates connected graphs. So, if the number of -requested arcs has been reached and the generated instance is not fully -connected, the routine generates a few remaining arcs to ensure -connectedness. Thus, the actual number of arcs generated by the routine -may be greater than the requested number of arcs. - -\subsection{glp\_netgen\_prob --- Klingman's standard network problem -instance} - -\synopsis - -\begin{verbatim} - void glp_netgen_prob(int nprob, int parm[1+15]); -\end{verbatim} - -\description - -The routine \verb|glp_netgen_prob| provides the set of parameters for -Klingman's network problem generator (see the routine -\verb|glp_netgen|), which describe a standard network problem instance. - -The parameter \verb|nprob| ($101\leq$ \verb|nprob| $\leq 150$) -specifies the problem instance number. - -The array \verb|parm| contains description of the network, provided by -the routine. (For detailed description of these parameters see comments -to the routine \verb|glp_netgen|.) - -\para{Problem characteristics} - -The table below shows characteristics of Klingman's standard network -problem instances. -$$ -\begin{array}{crrr} -{\rm Problem} & {\rm Nodes} & {\rm Arcs} & {\rm Optimum} \\ -\hline -101 & 5000 & 25336 & 6191726 \\ -102 & 5000 & 25387 & 72337144 \\ -103 & 5000 & 25355 & 218947553 \\ -104 & 5000 & 25344 & -19100371 \\ -105 & 5000 & 25332 & 31192578 \\ -106 & 5000 & 12870 & 4314276 \\ -107 & 5000 & 37832 & 7393769 \\ -108 & 5000 & 50309 & 8405738 \\ -109 & 5000 & 75299 & 9190300 \\ -110 & 5000 & 12825 & 8975048 \\ -111 & 5000 & 37828 & 4747532 \\ -112 & 5000 & 50325 & 4012671 \\ -113 & 5000 & 75318 & 2979725 \\ -114 & 5000 & 26514 & 5821181 \\ -115 & 5000 & 25962 & 6353310 \\ -116 & 5000 & 25304 & 5915426 \\ -117 & 5000 & 12816 & 4420560 \\ -118 & 5000 & 37797 & 7045842 \\ -119 & 5000 & 50301 & 7724179 \\ -120 & 5000 & 75330 & 8455200 \\ -121 & 5000 & 25000 & 66366360 \\ -122 & 5000 & 25000 & 30997529 \\ -123 & 5000 & 25000 & 23388777 \\ -124 & 5000 & 25000 & 17803443 \\ -125 & 5000 & 25000 & 14119622 \\ -\end{array} -\hspace{.5in} -\begin{array}{crrr} -{\rm Problem} & {\rm Nodes} & {\rm Arcs} & {\rm Optimum} \\ -\hline -126 & 5000 & 12500 & 18802218 \\ -127 & 5000 & 37500 & 27674647 \\ -128 & 5000 & 50000 & 30906194 \\ -129 & 5000 & 75000 & 40905209 \\ -130 & 5000 & 12500 & 38939608 \\ -131 & 5000 & 37500 & 16752978 \\ -132 & 5000 & 50000 & 13302951 \\ -133 & 5000 & 75000 & 9830268 \\ -134 & 1000 & 25000 & 3804874 \\ -135 & 2500 & 25000 & 11729616 \\ -136 & 7500 & 25000 & 33318101 \\ -137 & 10000 & 25000 & 46426030 \\ -138 & 5000 & 25000 & 60710879 \\ -139 & 5000 & 25000 & 32729682 \\ -140 & 5000 & 25000 & 27183831 \\ -141 & 5000 & 25000 & 19963286 \\ -142 & 5000 & 25000 & 20243457 \\ -143 & 5000 & 25000 & 18586777 \\ -144 & 5000 & 25000 & 2504591 \\ -145 & 5000 & 25000 & 215956138 \\ -146 & 5000 & 25000 & 2253113811 \\ -147 & 5000 & 25000 & -427908373 \\ -148 & 5000 & 25000 & -92965318 \\ -149 & 5000 & 25000 & 86051224 \\ -150 & 5000 & 25000 & 619314919 \\ -\end{array} -$$ - -\subsection{glp\_gridgen --- grid-like network problem generator} - -\synopsis - -\begin{verbatim} - int glp_gridgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, - const int parm[1+14]); -\end{verbatim} - -\description - -The routine \verb|glp_gridgen| is a GLPK version of the grid-like -network problem generator developed by Yusin Lee and Jim -Orlin.\footnote{Y.~Lee and J.~Orlin. GRIDGEN generator., 1991. The -original code is publically available from -\url{ftp://dimacs.rutgers.edu/pub/netflow/generators/network/gridgen}.} - -\newpage - -The parameter \verb|G| specifies the graph object, to which the -generated problem data have to be stored. Note that on entry the graph -object is erased with the routine \verb|glp_erase_graph|. - -The parameter \verb|v_rhs| specifies an offset of the field of type -\verb|double| in the vertex data block, to which the routine stores the -supply or demand value. If \verb|v_rhs| $<0$, the value is not stored. - -The parameter \verb|a_cap| specifies an offset of the field of type -\verb|double| in the arc data block, to which the routine stores the -arc capacity. If \verb|a_cap| $<0$, the capacity is not stored. - -The parameter \verb|a_cost| specifies an offset of the field of type -\verb|double| in the arc data block, to which the routine stores the -per-unit cost if the arc flow. If \verb|a_cost| $<0$, the cost is not -stored. - -The array \verb|parm| contains parameters of the network to be -generated: - -\begin{tabular}{@{}ll@{}} -\verb|parm[0] |¬ used\\ -\verb|parm[1] |&two-ways arcs indicator:\\ - &1 --- if links in both direction should be generated\\ - &0 --- otherwise\\ -\verb|parm[2] |&random number seed (a positive integer)\\ -\verb|parm[3] |&number of nodes (the number of nodes generated might -be slightly different to\\&make the network a grid)\\ -\verb|parm[4] |&grid width\\ -\verb|parm[5] |&number of sources\\ -\verb|parm[6] |&number of sinks\\ -\verb|parm[7] |&average degree\\ -\verb|parm[8] |&total flow\\ -\verb|parm[9] |&distribution of arc costs: -1 --- uniform, 2 --- exponential\\ -\verb|parm[10]|&lower bound for arc cost (uniform), -$100\lambda$ (exponential)\\ -\verb|parm[11]|&upper bound for arc cost (uniform), -not used (exponential)\\ -\verb|parm[12]|&distribution of arc capacities: -1 --- uniform, 2 --- exponential\\ -\verb|parm[13]|&lower bound for arc capacity (uniform), -$100\lambda$ (exponential)\\ -\verb|parm[14]|&upper bound for arc capacity (uniform), -not used (exponential)\\ -\end{tabular} - -\returns - -If the instance was successfully generated, the routine -\verb|glp_gridgen| returns zero; otherwise, if specified parameters are -inconsistent, the routine returns a non-zero error code. - -\para{Comments\footnote{This material is based on comments -to the original version of GRIDGEN.}} - -This network generator generates a grid-like network plus a super node. -In additional to the arcs connecting the nodes in the grid, there is an -arc from each supply node to the super node and from the super node to -each demand node to guarantee feasiblity. These arcs have very high -costs and very big capacities. - -The idea of this network generator is as follows: First, a grid of -$n_1\times n_2$ is generated. For example, $5\times 3$. The nodes are -numbered as 1 to 15, and the supernode is numbered as -$n_1\times n_2+1$. Then arcs between adjacent nodes are generated. -For these arcs, the user is allowed to specify either to generate -two-way arcs or one-way arcs. If two-way arcs are to be generated, two -arcs, one in each direction, will be generated between each adjacent -node pairs. Otherwise, only one arc will be generated. If this is the -case, the arcs will be generated in alterntive directions as shown -below. - -\medskip - -\noindent\hfil -\xymatrix -{1\ar[r]\ar[d]&2\ar[r]&3\ar[r]\ar[d]&4\ar[r]&5\ar[d]\\ -6\ar[d]&7\ar[l]\ar[u]&8\ar[l]\ar[d]&9\ar[l]\ar[u]&10\ar[l]\ar[d]\\ -11\ar[r]&12\ar[r]\ar[u]&13\ar[r]&14\ar[r]\ar[u]&15\\ -} - -\medskip - -Then the arcs between the super node and the source/sink nodes are -added as mentioned before. If the number of arcs still doesn't reach -the requirement, additional arcs will be added by uniformly picking -random node pairs. There is no checking to prevent multiple arcs -between any pair of nodes. However, there will be no self-arcs (arcs -that poins back to its tail node) in the network. - -The source and sink nodes are selected uniformly in the network, and -the imbalances of each source/sink node are also assigned by uniform -distribution. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Maximum flow problem} - -\subsection{Background} - -The {\it maximum flow problem} (MAXFLOW) is stated as follows. Let -there be given a directed graph (flow network) $G=(V,A)$, where $V$ is -a set of vertices (nodes), and $A\subseteq V\times V$ is a set of arcs. -Let also for each arc $a=(i,j)\in A$ there be given its capacity -$u_{ij}$. The problem is, for given {\it source} node $s\in V$ and -{\it sink} node $t\in V$, to find flows $x_{ij}$ through every arc of -the network, which satisfy the specified arc capacities and the -conservation constraints at all nodes, and maximize the total flow $F$ -through the network from $s$ to $t$. Here the conservation constraint -at a node means that the total flow entering this node through its -incoming arcs (plus $F$, if it is the source node) must be equal to the -total flow leaving this node through its outgoing arcs (plus $F$, if it -is the sink node). An example of the maximum flow problem, -where $s=v_1$ and $t=v_9$, is shown on Fig.~2. - -\medskip - -\noindent\hfil -\xymatrix @C=48pt -{_{F}\ar@{~>}[d]& -v_2\ar[r]|{_{10}}\ar[dd]|{_{9}}& -v_3\ar[dd]|{_{12}}\ar[r]|{_{18}}& -v_8\ar[rd]|{_{20}}&\\ -v_1\ar[ru]|{_{14}}\ar[rd]|{_{23}}&&& -v_6\ar[d]|{_{7}}\ar[u]|{_{8}}& -v_9\ar@{~>}[d]\\ -&v_4\ar[r]|{_{26}}& -v_5\ar[luu]|{_{11}}\ar[ru]|{_{25}}\ar[r]|{_{4}}& -v_7\ar[ru]|{_{15}}&_{F}\\ -} - -\medskip - -\noindent\hfil -Fig.~2. An example of the maximum flow problem. - -\medskip - -The maximum flow problem can be naturally formulated as the following -LP problem: - -\noindent -\hspace{1in}maximize -$$F\eqno(4)$$ -\hspace{1in}subject to -$$\sum_{(i,j)\in A}x_{ij}-\sum_{(j,i)\in A}x_{ji}=\left\{ -\begin{array}{@{\ }rl} -+F,&\hbox{for}\ i=s\\ - 0,&\hbox{for all}\ i\in V\backslash\{s,t\}\\ --F,&\hbox{for}\ i=t\\ -\end{array} -\right.\eqno(5) -$$ -$$0\leq x_{ij}\leq u_{ij}\ \ \ \hbox{for all}\ (i,j)\in A -\eqno(6)$$ - -\noindent -where $F\geq 0$ is an additional variable playing the role of the -objective. - -Another LP formulation of the maximum flow problem, which does not -include the variable $F$, is the following: - -\noindent -\hspace{1in}maximize -$$z=\sum_{(s,j)\in A}x_{sj}-\sum_{(j,s)\in A}x_{js}\ (=F)\eqno(7)$$ -\hspace{1in}subject to -$$\sum_{(i,j)\in A}x_{ij}-\sum_{(j,i)\in A}x_{ji}\left\{ -\begin{array}{@{\ }rl} -\geq 0,&\hbox{for}\ i=s\\ -=0,&\hbox{for all}\ i\in V\backslash\{s,t\}\\ -\leq 0,&\hbox{for}\ i=t\\ -\end{array} -\right.\eqno(8) -$$ -$$0\leq x_{ij}\leq u_{ij}\ \ \ \hbox{for all}\ (i,j)\in A -\eqno(9)$$ - -\subsection{glp\_read\_maxflow --- read maximum flow problem data in -DIMACS\\format} - -\synopsis - -\begin{verbatim} - int glp_read_maxflow(glp_graph *G, int *s, int *t, int a_cap, - const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_read_maxflow| reads the maximum flow problem -data from a text file in DIMACS format. - -The parameter \verb|G| specifies the graph object, to which the problem -data have to be stored. Note that before reading data the current -content of the graph object is completely erased with the routine -\verb|glp_erase_graph|. - -The pointer \verb|s| specifies a location, to which the routine stores -the ordinal number of the source node. If \verb|s| is \verb|NULL|, the -source node number is not stored. - -The pointer \verb|t| specifies a location, to which the routine stores -the ordinal number of the sink node. If \verb|t| is \verb|NULL|, the -sink node number is not stored. - -The parameter \verb|a_cap| specifies an offset of the field of type -\verb|double| in the arc data block, to which the routine stores -$u_{ij}$, the arc capacity. If \verb|a_cap| $<0$, the arc capacity is -not stored. - -The character string \verb|fname| specifies the name of a text file to -be read in. (If the file name name ends with the suffix `\verb|.gz|', -the file is assumed to be compressed, in which case the routine -decompresses it ``on the fly''.) - -\returns - -If the operation was successful, the routine returns zero. Otherwise, -it prints an error message and returns non-zero. - -\para{Example} - -\begin{footnotesize} -\begin{verbatim} -typedef struct -{ /* arc data block */ - ... - double cap; - ... -} a_data; - -int main(void) -{ glp_graph *G; - int s, t, ret; - G = glp_create_graph(..., sizeof(a_data)); - ret = glp_read_maxflow(G, &s, &t, offsetof(a_data, cap), - "sample.max"); - if (ret != 0) goto ... - ... -} -\end{verbatim} -\end{footnotesize} - -\newpage - -\para{DIMACS maximum flow problem format\footnote{This material is -based on the paper ``The First DIMACS International Algorithm -Implementation Challenge: Problem Definitions and Specifications'', -which is publically available at -\url{http://dimacs.rutgers.edu/Challenges/}.}} -\label{subsecmaxflow} - -The DIMACS input file is a plain ASCII text file. It contains -{\it lines} of several types described below. A line is terminated with -an end-of-line character. Fields in each line are separated by at least -one blank space. Each line begins with a one-character designator to -identify the line type. - -Note that DIMACS requires all numerical quantities to be integers in -the range $[-2^{31},\ 2^{31}-1]$ while GLPK allows the quantities to be -floating-point numbers. - -\para{Comment lines.} Comment lines give human-readable information -about the file and are ignored by programs. Comment lines can appear -anywhere in the file. Each comment line begins with a lower-case -character \verb|c|. - -\begin{verbatim} - c This is a comment line -\end{verbatim} - -\para{Problem line.} There is one problem line per data file. The -problem line must appear before any node or arc descriptor lines. -It has the following format: - -\begin{verbatim} - p max NODES ARCS -\end{verbatim} - -\noindent -The lower-case character \verb|p| signifies that this is a problem line. -The three-character problem designator \verb|max| identifies the file as -containing specification information for the maximum flow problem. The -\verb|NODES| field contains an integer value specifying the number of -nodes in the network. The \verb|ARCS| field contains an integer value -specifying the number of arcs in the network. - -\para{Node descriptors.} Two node descriptor lines for the source and -sink nodes must appear before all arc descriptor lines. They may appear -in either order, each with the following format: - -\begin{verbatim} - n ID WHICH -\end{verbatim} - -\noindent -The lower-case character \verb|n| signifies that this a node descriptor -line. The \verb|ID| field gives a node identification number, -an integer between 1 and \verb|NODES|. The \verb|WHICH| field gives -either a lower-case \verb|s| or \verb|t|, designating the source and -sink, respectively. - -\para{Arc descriptors.} There is one arc descriptor line for each arc -in the network. Arc descriptor lines are of the following format: - -\begin{verbatim} - a SRC DST CAP -\end{verbatim} - -\noindent -The lower-case character \verb|a| signifies that this is an arc -descriptor line. For a directed arc $(i,j)$ the \verb|SRC| field gives -the identification number $i$ for the tail endpoint, and the \verb|DST| -field gives the identification number $j$ for the head endpoint. -Identification numbers are integers between 1 and \verb|NODES|. The -\verb|CAP| field gives the arc capacity, i.e. maximum amount of flow -that can be sent along arc $(i,j)$ in a feasible flow. - -\para{Example.} Below here is an example of the data file in DIMACS -format corresponding to the maximum flow problem shown on Fig~2. - -\begin{footnotesize} -\begin{verbatim} -c sample.max -c -c This is an example of the maximum flow problem data -c in DIMACS format. -c -p max 9 14 -c -n 1 s -n 9 t -c -a 1 2 14 -a 1 4 23 -a 2 3 10 -a 2 4 9 -a 3 5 12 -a 3 8 18 -a 4 5 26 -a 5 2 11 -a 5 6 25 -a 5 7 4 -a 6 7 7 -a 6 8 8 -a 7 9 15 -a 8 9 20 -c -c eof -\end{verbatim} -\end{footnotesize} - -\subsection{glp\_write\_maxflow --- write maximum flow problem data in -DIMACS\\format} - -\synopsis - -\begin{verbatim} - int glp_write_maxflow(glp_graph *G, int s, int t, int a_cap, - const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_write_maxflow| writes the maximum flow problem -data to a text file in DIMACS format. - -The parameter \verb|G| is the graph (network) program object, which -specifies the maximum flow problem instance. - -The parameter \verb|s| specifies the ordinal number of the source node. - -The parameter \verb|t| specifies the ordinal number of the sink node. - -The parameter \verb|a_cap| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $u_{ij}$, the upper -bound to the arc flow (the arc capacity). If the upper bound is -specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e. -the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that -$u_{ij}=1$ for all arcs. - -The character string \verb|fname| specifies a name of the text file to -be written out. (If the file name ends with suffix `\verb|.gz|', the -file is assumed to be compressed, in which case the routine performs -automatic compression on writing it.) - -\returns - -If the operation was successful, the routine returns zero. Otherwise, -it prints an error message and returns non-zero. - -\newpage - -\subsection{glp\_maxflow\_lp --- convert maximum flow problem to LP} - -\synopsis - -\begin{verbatim} - void glp_maxflow_lp(glp_prob *P, glp_graph *G, int names, int s, int t, - int a_cap); -\end{verbatim} - -\description - -The routine \verb|glp_maxflow_lp| builds LP problem (7)---(9), which -corresponds to the specified maximum flow problem. - -The parameter \verb|P| is the resultant LP problem object to be built. -Note that on entry its current content is erased with the routine -\verb|glp_erase_prob|. - -The parameter \verb|G| is the graph (network) program object, which -specifies the maximum flow problem instance. - -The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, the -routine uses symbolic names of the graph object components to assign -symbolic names to the LP problem object components. If the flag is -\verb|GLP_OFF|, no symbolic names are assigned. - -The parameter \verb|s| specifies the ordinal number of the source node. - -The parameter \verb|t| specifies the ordinal number of the sink node. - -The parameter \verb|a_cap| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $u_{ij}$, the upper -bound to the arc flow (the arc capacity). If the upper bound is -specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e. -the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that -$u_{ij}=1$ for all arcs. - -\para{Example} - -The example program below reads the maximum flow problem in DIMACS -format from file `\verb|sample.max|', converts the instance to LP, and -then writes the resultant LP in CPLEX format to file -`\verb|maxflow.lp|'. - -\begin{footnotesize} -\begin{verbatim} -#include -#include - -int main(void) -{ glp_graph *G; - glp_prob *P; - int s, t; - G = glp_create_graph(0, sizeof(double)); - glp_read_maxflow(G, &s, &t, 0, "sample.max"); - P = glp_create_prob(); - glp_maxflow_lp(P, G, GLP_ON, s, t, 0); - glp_delete_graph(G); - glp_write_lp(P, NULL, "maxflow.lp"); - glp_delete_prob(P); - return 0; -} -\end{verbatim} -\end{footnotesize} - -If `\verb|sample.max|' is the example data file from the previous -subsection, the output `\verb|maxflow.lp|' may look like follows: - -\newpage - -\begin{footnotesize} -\begin{verbatim} -Maximize - obj: + x(1,4) + x(1,2) - -Subject To - r_1: + x(1,2) + x(1,4) >= 0 - r_2: - x(5,2) + x(2,3) + x(2,4) - x(1,2) = 0 - r_3: + x(3,5) + x(3,8) - x(2,3) = 0 - r_4: + x(4,5) - x(2,4) - x(1,4) = 0 - r_5: + x(5,2) + x(5,6) + x(5,7) - x(4,5) - x(3,5) = 0 - r_6: + x(6,7) + x(6,8) - x(5,6) = 0 - r_7: + x(7,9) - x(6,7) - x(5,7) = 0 - r_8: + x(8,9) - x(6,8) - x(3,8) = 0 - r_9: - x(8,9) - x(7,9) <= 0 - -Bounds - 0 <= x(1,4) <= 23 - 0 <= x(1,2) <= 14 - 0 <= x(2,4) <= 9 - 0 <= x(2,3) <= 10 - 0 <= x(3,8) <= 18 - 0 <= x(3,5) <= 12 - 0 <= x(4,5) <= 26 - 0 <= x(5,7) <= 4 - 0 <= x(5,6) <= 25 - 0 <= x(5,2) <= 11 - 0 <= x(6,8) <= 8 - 0 <= x(6,7) <= 7 - 0 <= x(7,9) <= 15 - 0 <= x(8,9) <= 20 - -End -\end{verbatim} -\end{footnotesize} - -\subsection{glp\_maxflow\_ffalg --- solve maximum flow problem with -Ford-Fulkerson\\algorithm} - -\synopsis - -\begin{verbatim} - int glp_maxflow_ffalg(glp_graph *G, int s, int t, int a_cap, double *sol, - int a_x, int v_cut); -\end{verbatim} - -\description - -The routine \verb|glp_mincost_ffalg| finds optimal solution to the -maximum flow problem with the Ford-Fulkerson algorithm.\footnote{GLPK -implementation of the Ford-Fulkerson algorithm is based on the -following book: L.~R.~Ford,~Jr., and D.~R.~Fulkerson, ``Flows in -Networks,'' The RAND Corp., Report R-375-PR (August 1962), Chap. I -``Static Maximal Flow,'' pp.~30-33.} Note that this routine requires -all the problem data to be integer-valued. - -The parameter \verb|G| is a graph (network) program object which -specifies the maximum flow problem instance to be solved. - -The parameter $s$ specifies the ordinal number of the source node. - -\newpage - -The parameter $t$ specifies the ordinal number of the sink node. - -The parameter \verb|a_cap| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $u_{ij}$, the upper -bound to the arc flow (the arc capacity). This bound must be integer in -the range [0, \verb|INT_MAX|]. If \verb|a_cap| $<0$, it is assumed that -$u_{ij}=1$ for all arcs. - -The parameter \verb|sol| specifies a location, to which the routine -stores the objective value (that is, the total flow from $s$ to $t$) -found. If \verb|sol| is NULL, the objective value is not stored. - -The parameter \verb|a_x| specifies an offset of the field of type -\verb|double| in the arc data block, to which the routine stores -$x_{ij}$, the arc flow found. If \verb|a_x| $<0$, the arc flow values -are not stored. - -The parameter \verb|v_cut| specifies an offset of the field of type -\verb|int| in the vertex data block, to which the routine stores node -flags corresponding to the optimal solution found: if the node flag is -1, the node is labelled, and if the node flag is 0, the node is -unlabelled. The calling program may use these node flags to determine -the {\it minimal cut}, which is a subset of arcs whose one endpoint is -labelled and other is not. If \verb|v_cut| $<0$, the node flags are not -stored. - -Note that all solution components (the objective value and arc flows) -computed by the routine are always integer-valued. - -\returns - -\begin{retlist} -0 & Optimal solution found.\\ - -\verb|GLP_EDATA| & Unable to start the search, because some problem -data are either not integer-valued or out of range.\\ -\end{retlist} - -\para{Example} - -The example program shown below reads the maximum flow problem instance -in DIMACS format from file `\verb|sample.max|', solves it using the -routine \verb|glp_maxflow_ffalg|, and write the solution found to the -standard output. - -\begin{footnotesize} -\begin{verbatim} -#include -#include -#include -#include - -typedef struct { int cut; } v_data; -typedef struct { double cap, x; } a_data; - -#define node(v) ((v_data *)((v)->data)) -#define arc(a) ((a_data *)((a)->data)) - -int main(void) -{ glp_graph *G; - glp_vertex *v, *w; - glp_arc *a; - int i, s, t, ret; - double sol; - G = glp_create_graph(sizeof(v_data), sizeof(a_data)); - glp_read_maxflow(G, &s, &t, offsetof(a_data, cap), - "sample.max"); - ret = glp_maxflow_ffalg(G, s, t, offsetof(a_data, cap), - &sol, offsetof(a_data, x), offsetof(v_data, cut)); - printf("ret = %d; sol = %5g\n", ret, sol); - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { w = a->head; - printf("x[%d->%d] = %5g (%d)\n", v->i, w->i, - arc(a)->x, node(v)->cut ^ node(w)->cut); - } - } - glp_delete_graph(G); - return 0; -} -\end{verbatim} -\end{footnotesize} - -If `\verb|sample.max|' is the example data file from the subsection -describing \verb|glp_read_maxflow|, the output may look like follows: - -\begin{footnotesize} -\begin{verbatim} -Reading maximum flow problem data from `sample.max'... -Flow network has 9 nodes and 14 arcs -24 lines were read -ret = 0; sol = 29 -x[1->4] = 19 (0) -x[1->2] = 10 (0) -x[2->4] = 0 (0) -x[2->3] = 10 (1) -x[3->8] = 10 (0) -x[3->5] = 0 (1) -x[4->5] = 19 (0) -x[5->7] = 4 (1) -x[5->6] = 15 (0) -x[5->2] = 0 (0) -x[6->8] = 8 (1) -x[6->7] = 7 (1) -x[7->9] = 11 (0) -x[8->9] = 18 (0) -\end{verbatim} -\end{footnotesize} - -\subsection{glp\_rmfgen --- Goldfarb's maximum flow problem generator} - -\synopsis - -\begin{verbatim} - int glp_rmfgen(glp_graph *G, int *s, int *t, int a_cap, const int parm[1+5]); -\end{verbatim} - -\description - -The routine \verb|glp_rmfgen| is a GLPK version of the maximum flow -problem generator developed by D.~Goldfarb and -M.~Grigoriadis.\footnote{D.~Goldfarb and M.~D.~Grigoriadis, -``A computational comparison of the Dinic and network simplex methods -for maximum flow.'' Annals of Op. Res. 13 (1988), -pp.~83-123.}$^{,}$\footnote{U.~Derigs and W.~Meier, ``Implementing -Goldberg's max-flow algorithm: A computational investigation.'' -Zeitschrift f\"ur Operations Research 33 (1989), -pp.~383-403.}$^{,}$\footnote{The original code of RMFGEN implemented by -Tamas Badics is publically available from -\url{ftp://dimacs.rutgers.edu/pub/netflow/generators/network/genrmf}.} - -The parameter \verb|G| specifies the graph object, to which the -generated problem data have to be stored. Note that on entry the graph -object is erased with the routine \verb|glp_erase_graph|. - -\newpage - -The pointers \verb|s| and \verb|t| specify locations, to which the -routine stores the source and sink node numbers, respectively. If -\verb|s| or \verb|t| is \verb|NULL|, corresponding node number is not -stored. - -The parameter \verb|a_cap| specifies an offset of the field of type -\verb|double| in the arc data block, to which the routine stores the arc -capacity. If \verb|a_cap| $<0$, the capacity is not stored. - -The array \verb|parm| contains description of the network to be -generated: - -\begin{tabular}{@{}lll@{}} -\verb|parm[0]|& ¬ used\\ -\verb|parm[1]|&\verb|seed|&random number seed (a positive integer)\\ -\verb|parm[2]|&\verb|a |&frame size\\ -\verb|parm[3]|&\verb|b |&depth\\ -\verb|parm[4]|&\verb|c1 |&minimal arc capacity\\ -\verb|parm[5]|&\verb|c2 |&maximal arc capacity\\ -\end{tabular} - -\returns - -If the instance was successfully generated, the routine -\verb|glp_netgen| returns zero; otherwise, if specified parameters are -inconsistent, the routine returns a non-zero error code. - -\para{Comments\footnote{This material is based on comments to the -original version of RMFGEN.}} - -The generated network is as follows. It has $b$ pieces of frames of -size $a\times a$. (So alltogether the number of vertices is -$a\times a\times b$.) - -In each frame all the vertices are connected with their neighbours -(forth and back). In addition the vertices of a frame are connected -one to one with the vertices of next frame using a random permutation -of those vertices. - -The source is the lower left vertex of the first frame, the sink is -the upper right vertex of the $b$-th frame. - -\begin{verbatim} - t - +-------+ - | .| - | . | - / | / | - +-------+/ -+ b - | | |/. - a | -v- |/ - | | |/ - +-------+ 1 - s a -\end{verbatim} - -The capacities are randomly chosen integers from the range of -$[c_1,c_2]$ in the case of interconnecting edges, and $c_2\cdot a^2$ -for the in-frame edges. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Assignment problem} - -\subsection{Background} - -Let there be given an undirected bipartite graph $G=(R\cup S,E)$, where -$R$ and $S$ are disjoint sets of vertices (nodes), and -$E\subseteq R\times S$ is a set of edges. Let also for each edge -$e=(i,j)\in E$ there be given its cost $c_{ij}$. A {\it matching} -(which in case of bipartite graph is also called {\it assignment}) -$M\subseteq E$ in $G$ is a set of pairwise non-adjacent edges, that is, -no two edges in $M$ share a common vertex. A matching, which matches -all vertices of the graph, is called a {\it perfect matching}. -Obviously, a perfect matching in bipartite graph $G=(R\cup S,E)$ -defines some bijection $R\leftrightarrow S$. - -The {\it assignment problem} has two different variants. In the first -variant the problem is to find matching (assignment) $M$, which -maximizes the sum: -$$\sum_{(i,j)\in M}c_{ij}\eqno(10)$$ -(so this variant is also called the {\it maximum weighted bipartite -matching problem} or, if all $c_{ij}=1$, the {\it maximum cardinality -bipartite matching problem}). In the second, classic variant the -problem is to find {\it perfect} matching (assignment) $M$, which -minimizes or maximizes the sum (10). - -An example of the assignment problem, which is the maximum weighted -bipartite matching problem, is shown on Fig. 3. - -The maximum weighted bipartite matching problem can be naturally -formulated as the following LP problem: - -\noindent -\hspace{1in}maximize -$$z=\sum_{(i,j)\in E}c_{ij}x_{ij}\eqno(11)$$ -\hspace{1in}subject to -$$\sum_{(i,j)\in E}x_{ij}\leq 1\ \ \ \hbox{for all}\ i\in R\eqno(12)$$ -$$\sum_{(i,j)\in E}x_{ij}\leq 1\ \ \ \hbox{for all}\ j\in S\eqno(13)$$ -$$\ \ \ \ \ \ \ \ 0\leq x_{ij}\leq 1\ \ \ \hbox{for all}\ (i,j)\in E -\eqno(14)$$ - -\noindent -where $x_{ij}=1$ means that $(i,j)\in M$, and $x_{ij}=0$ means that -$(i,j)\notin M$.\footnote{The constraint matrix of LP formulation -(11)---(14) is totally unimodular, due to which $x_{ij}\in\{0,1\}$ for -any basic solution.} - -\newpage - -\noindent\hfil -\xymatrix @C=48pt -{v_1\ar@{-}[rr]|{_{13}}\ar@{-}[rrd]|{_{21}}\ar@{-}[rrddd]|(.2){_{20}}&& -v_9\\ -v_2\ar@{-}[rr]|{_{12}}\ar@{-}[rrdd]|(.3){_{8}} -\ar@{-}[rrddd]|(.4){_{26}}&&v_{10}\\ -v_3\ar@{-}[rr]|(.2){_{22}}\ar@{-}[rrdd]|(.3){_{11}}&&v_{11}\\ -v_4\ar@{-}[rruuu]|(.6){_{12}}\ar@{-}[rr]|(.2){_{36}} -\ar@{-}[rrdd]|(.7){_{25}}&&v_{12}\\ -v_5\ar@{-}[rruu]|(.42){_{41}}\ar@{-}[rru]|(.4){_{40}} -\ar@{-}[rr]|(.75){_{11}}\ar@{-}[rrd]|(.6){_{4}}\ar@{-}[rrdd]|{_{8}} -\ar@{-}[rrddd]|{_{35}}\ar@{-}[rrdddd]|{_{32}}&&v_{13}\\ -v_6\ar@{-}[rruuuuu]|(.7){_{13}}&&v_{14}\\ -v_7\ar@{-}[rruuuuu]|(.15){_{19}}&&v_{15}\\ -v_8\ar@{-}[rruuuuuu]|(.25){_{39}}\ar@{-}[rruuuuu]|(.65){_{15}}&& -v_{16}\\ -&&v_{17}\\ -} - -\medskip - -\noindent\hfil -Fig.~3. An example of the assignment problem. - -\medskip - -Similarly, the perfect assignment problem can be naturally formulated -as the following LP problem: - -\noindent -\hspace{1in}minimize (or maximize) -$$z=\sum_{(i,j)\in E}c_{ij}x_{ij}\eqno(15)$$ -\hspace{1in}subject to -$$\sum_{(i,j)\in E}x_{ij}=1\ \ \ \hbox{for all}\ i\in R\eqno(16)$$ -$$\sum_{(i,j)\in E}x_{ij}=1\ \ \ \hbox{for all}\ j\in S\eqno(17)$$ -$$\ \ \ \ \ \ \ \ 0\leq x_{ij}\leq 1\ \ \ \hbox{for all}\ (i,j)\in E -\eqno(18)$$ - -\noindent -where variables $x_{ij}$ have the same meaning as for (11)---(14) -above. - -In GLPK an undirected bipartite graph $G=(R\cup S,E)$ is represented as -directed graph $\overline{G}=(V,A)$, where $V=R\cup S$ and -$A=\{(i,j):(i,j)\in E\}$, i.e. every edge $(i,j)\in E$ in $G$ -corresponds to arc $(i\rightarrow j)\in A$ in $\overline{G}$. - -\subsection{glp\_read\_asnprob --- read assignment problem data in -DIMACS format} - -\synopsis - -\begin{verbatim} - int glp_read_asnprob(glp_graph *G, int v_set, int a_cost, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_read_asnprob| reads the assignment problem data -from a text file in DIMACS format. - -The parameter \verb|G| specifies the graph object, to which the problem -data have to be stored. Note that before reading data the current -content of the graph object is completely erased with the routine -\verb|glp_erase_graph|. - -The parameter \verb|v_set| specifies an offset of the field of type -\verb|int| in the vertex data block, to which the routine stores the -node set indicator: - -0 --- the node is in set $R$; - -1 --- the node is in set $S$. - -\noindent -If \verb|v_set| $<0$, the node set indicator is not stored. - -The parameter \verb|a_cost| specifies an offset of the field of type -\verb|double| in the arc data block, to which the routine stores the -edge cost $c_{ij}$. If \verb|a_cost| $<0$, the edge cost is not stored. - -The character string \verb|fname| specifies the name of a text file to -be read in. (If the file name name ends with the suffix `\verb|.gz|', -the file is assumed to be compressed, in which case the routine -decompresses it ``on the fly''.) - -\returns - -If the operation was successful, the routine returns zero. Otherwise, -it prints an error message and returns non-zero. - -\para{Example.} Below here is an example program that read the -assignment problem data in DIMACS format from a text file -`\verb|sample.asn|'. - -\begin{footnotesize} -\begin{verbatim} -typedef struct -{ /* vertex data block */ - ... - int set; - ... -} v_data; - -typedef struct -{ /* arc data block */ - ... - double cost; - ... -} a_data; - -int main(void) -{ glp_graph *G; - int ret; - G = glp_create_graph(sizeof(v_data), sizeof(a_data)); - ret = glp_read_asnprob(G, offsetof(v_data, set), - offsetof(a_data, cost), "sample.asn"); - if (ret != 0) goto ... - ... -} -\end{verbatim} -\end{footnotesize} - -\para{DIMACS assignment problem format\footnote{This material is based -on the paper ``The First DIMACS International Algorithm Implementation -Challenge: Problem Definitions and Specifications'', which is -publically available at \url{http://dimacs.rutgers.edu/Challenges/}.}} -\label{subsecasnprob} - -The DIMACS input file is a plain ASCII text file. It contains -{\it lines} of several types described below. A line is terminated with -an end-of-line character. Fields in each line are separated by at least -one blank space. Each line begins with a one-character designator to -identify the line type. - -Note that DIMACS requires all numerical quantities to be integers in -the range $[-2^{31},\ 2^{31}-1]$ while GLPK allows the quantities to be -floating-point numbers. - -\para{Comment lines.} Comment lines give human-readable information -about the file and are ignored by programs. Comment lines can appear -anywhere in the file. Each comment line begins with a lower-case -character \verb|c|. - -\begin{verbatim} - c This is a comment line -\end{verbatim} - -\para{Problem line.} There is one problem line per data file. The -problem line must appear before any node or arc descriptor lines. It -has the following format: - -\begin{verbatim} - p asn NODES EDGES -\end{verbatim} - -\noindent -The lower-case character \verb|p| signifies that this is a problem line. -The three-character problem designator \verb|asn| identifies the file as -containing specification information for the assignment problem. -The \verb|NODES| field contains an integer value specifying the total -number of nodes in the graph (i.e. in both sets $R$ and $S$). The -\verb|EDGES| field contains an integer value specifying the number of -edges in the graph. - -\para{Node descriptors.} All node descriptor lines must appear before -all edge descriptor lines. The node descriptor lines lists the nodes in -set $R$ only, and all other nodes are assumed to be in set $S$. There -is one node descriptor line for each such node, with the following -format: - -\begin{verbatim} - n ID -\end{verbatim} - -\noindent -The lower-case character \verb|n| signifies that this is a node -descriptor line. The \verb|ID| field gives a node identification number, -an integer between 1 and \verb|NODES|. - -\para{Edge descriptors.} There is one edge descriptor line for each -edge in the graph. Edge descriptor lines are of the following format: - -\begin{verbatim} - a SRC DST COST -\end{verbatim} - -\noindent -The lower-case character \verb|a| signifies that this is an edge -descriptor line. For each edge $(i,j)$, where $i\in R$ and $j\in S$, -the \verb|SRC| field gives the identification number of vertex $i$, and -the \verb|DST| field gives the identification number of vertex $j$. -Identification numbers are integers between 1 and \verb|NODES|. The -\verb|COST| field contains the cost of edge $(i,j)$. - -\para{Example.} Below here is an example of the data file in DIMACS -format corresponding to the assignment problem shown on Fig~3. - -\begin{footnotesize} -\begin{verbatim} -c sample.asn -c -c This is an example of the assignment problem data -c in DIMACS format. -c -p asn 17 22 -c -n 1 -n 2 -n 3 -n 4 -n 5 -n 6 -n 7 -n 8 -c -a 1 9 13 -a 1 10 21 -a 1 12 20 -a 2 10 12 -a 2 12 8 -a 2 13 26 -a 3 11 22 -a 3 13 11 -a 4 9 12 -a 4 12 36 -a 4 14 25 -a 5 11 41 -a 5 12 40 -a 5 13 11 -a 5 14 4 -a 5 15 8 -a 5 16 35 -a 5 17 32 -a 6 9 13 -a 7 10 19 -a 8 10 39 -a 8 11 15 -c -c eof -\end{verbatim} -\end{footnotesize} - -\newpage - -\subsection{glp\_write\_asnprob --- write assignment problem data in -DIMACS format} - -\synopsis - -\begin{verbatim} - int glp_write_asnprob(glp_graph *G, int v_set, int a_cost, const char *fname); -\end{verbatim} - -\description - -The routine \verb|glp_write_asnprob| writes the assignment problem data -to a text file in DIMACS format. - -The parameter \verb|G| is the graph program object, which specifies the -assignment problem instance. - -The parameter \verb|v_set| specifies an offset of the field of type -\verb|int| in the vertex data block, which contains the node set -indicator: - -0 --- the node is in set $R$; - -1 --- the node is in set $S$. - -\noindent -If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs -is in set $R$, and a node having no outgoing arcs is in set $S$. - -The parameter \verb|a_cost| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $c_{ij}$, the edge -cost. If \verb|a_cost| $<0$, it is assumed that $c_{ij}=1$ for all -edges. - -The character string \verb|fname| specifies a name of the text file to -be written out. (If the file name ends with suffix `\verb|.gz|', the -file is assumed to be compressed, in which case the routine performs -automatic compression on writing it.) - -\para{Note} - -The routine \verb|glp_write_asnprob| does not check that the specified -graph object correctly represents a bipartite graph. To make sure that -the problem data are correct, use the routine \verb|glp_check_asnprob|. - -\returns - -If the operation was successful, the routine returns zero. Otherwise, -it prints an error message and returns non-zero. - -\vspace*{-4pt} - -\subsection{glp\_check\_asnprob --- check correctness of assignment -problem data} - -\synopsis - -\begin{verbatim} - int glp_check_asnprob(glp_graph *G, int v_set); -\end{verbatim} - -\description - -The routine \verb|glp_check_asnprob| checks that the specified graph -object \verb|G| correctly represents a bipartite graph. - -The parameter \verb|v_set| specifies an offset of the field of type -\verb|int| in the vertex data block, which contains the node set -indicator: - -0 --- the node is in set $R$; - -1 --- the node is in set $S$. - -\noindent -If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs -is in set $R$, and a node having no outgoing arcs is in set $S$. - -\returns - -0 --- the data are correct; - -1 --- the set indicator of some node is 0, however, that node has one -or more incoming arcs; - -2 --- the set indicator of some node is 1, however, that node has one -or more outgoing arcs; - -3 --- the set indicator of some node is invalid (neither 0 nor 1); - -4 --- some node has both incoming and outgoing arcs. - -\subsection{glp\_asnprob\_lp --- convert assignment problem to LP} - -\synopsis - -\begin{verbatim} - int glp_asnprob_lp(glp_prob *P, int form, glp_graph *G, int names, int v_set, - int a_cost); -\end{verbatim} - -\description - -The routine \verb|glp_asnprob_lp| builds LP problem, which corresponds -to the specified assignment problem. - -The parameter \verb|P| is the resultant LP problem object to be built. -Note that on entry its current content is erased with the routine -\verb|glp_erase_prob|. - -The parameter \verb|form| defines which LP formulation should be used: - -\verb|GLP_ASN_MIN| --- perfect matching (15)---(18), minimization; - -\verb|GLP_ASN_MAX| --- perfect matching (15)---(18), maximization; - -\verb|GLP_ASN_MMP| --- maximum weighted matching (11)---(14). - -The parameter \verb|G| is the graph program object, which specifies the -assignment problem instance. - -The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, the -routine uses symbolic names of the graph object components to assign -symbolic names to the LP problem object components. If the \verb|flag| -is \verb|GLP_OFF|, no symbolic names are assigned. - -The parameter \verb|v_set| specifies an offset of the field of type -\verb|int| in the vertex data block, which contains the node set -indicator: - -0 --- the node is in set $R$; - -1 --- the node is in set $S$. - -\noindent -If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs -is in set $R$, and a node having no outgoing arcs is in set $S$. - -The parameter \verb|a_cost| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $c_{ij}$, the edge -cost. If \verb|a_cost| $<0$, it is assumed that $c_{ij}=1$ for all -edges. - -\newpage - -\returns - -If the LP problem has been successfully built, the routine -\verb|glp_asnprob_lp| returns zero, otherwise, non-zero (see the -routine \verb|glp_check_asnprob|). - -\para{Example} - -The example program below reads the assignment problem instance in -DIMACS format from file `\verb|sample.asn|', converts the instance to -LP (11)---(14), and writes the resultant LP in CPLEX format to file -`\verb|matching.lp|'. - -\begin{footnotesize} -\begin{verbatim} -#include -#include - -typedef struct { int set; } v_data; -typedef struct { double cost; } a_data; - -int main(void) -{ glp_graph *G; - glp_prob *P; - G = glp_create_graph(sizeof(v_data), sizeof(a_data)); - glp_read_asnprob(G, offsetof(v_data, set), - offsetof(a_data, cost), "sample.asn"); - P = glp_create_prob(); - glp_asnprob_lp(P, GLP_ASN_MMP, G, GLP_ON, - offsetof(v_data, set), offsetof(a_data, cost)); - glp_delete_graph(G); - glp_write_lp(P, NULL, "matching.lp"); - glp_delete_prob(P); - return 0; -} -\end{verbatim} -\end{footnotesize} - -If `\verb|sample.asn|' is the example data file from the subsection -describing \verb|glp_read_asnprob|, file `\verb|matching.lp|' may look -like follows: - -\begin{footnotesize} -\begin{verbatim} -Maximize - obj: + 20 x(1,12) + 21 x(1,10) + 13 x(1,9) + 26 x(2,13) + 8 x(2,12) - + 12 x(2,10) + 11 x(3,13) + 22 x(3,11) + 25 x(4,14) + 36 x(4,12) - + 12 x(4,9) + 32 x(5,17) + 35 x(5,16) + 8 x(5,15) + 4 x(5,14) - + 11 x(5,13) + 40 x(5,12) + 41 x(5,11) + 13 x(6,9) + 19 x(7,10) - + 15 x(8,11) + 39 x(8,10) - -Subject To - r_1: + x(1,9) + x(1,10) + x(1,12) <= 1 - r_2: + x(2,10) + x(2,12) + x(2,13) <= 1 - r_3: + x(3,11) + x(3,13) <= 1 - r_4: + x(4,9) + x(4,12) + x(4,14) <= 1 - r_5: + x(5,11) + x(5,12) + x(5,13) + x(5,14) + x(5,15) + x(5,16) - + x(5,17) <= 1 - r_6: + x(6,9) <= 1 - r_7: + x(7,10) <= 1 - r_8: + x(8,10) + x(8,11) <= 1 - r_9: + x(6,9) + x(4,9) + x(1,9) <= 1 - r_10: + x(8,10) + x(7,10) + x(2,10) + x(1,10) <= 1 - r_11: + x(8,11) + x(5,11) + x(3,11) <= 1 - r_12: + x(5,12) + x(4,12) + x(2,12) + x(1,12) <= 1 - r_13: + x(5,13) + x(3,13) + x(2,13) <= 1 - r_14: + x(5,14) + x(4,14) <= 1 - r_15: + x(5,15) <= 1 - r_16: + x(5,16) <= 1 - r_17: + x(5,17) <= 1 - -Bounds - 0 <= x(1,12) <= 1 - 0 <= x(1,10) <= 1 - 0 <= x(1,9) <= 1 - 0 <= x(2,13) <= 1 - 0 <= x(2,12) <= 1 - 0 <= x(2,10) <= 1 - 0 <= x(3,13) <= 1 - 0 <= x(3,11) <= 1 - 0 <= x(4,14) <= 1 - 0 <= x(4,12) <= 1 - 0 <= x(4,9) <= 1 - 0 <= x(5,17) <= 1 - 0 <= x(5,16) <= 1 - 0 <= x(5,15) <= 1 - 0 <= x(5,14) <= 1 - 0 <= x(5,13) <= 1 - 0 <= x(5,12) <= 1 - 0 <= x(5,11) <= 1 - 0 <= x(6,9) <= 1 - 0 <= x(7,10) <= 1 - 0 <= x(8,11) <= 1 - 0 <= x(8,10) <= 1 - -End -\end{verbatim} -\end{footnotesize} - -\subsection{glp\_asnprob\_okalg --- solve assignment problem with -out-of-kilter\\algorithm} - -\synopsis - -\begin{verbatim} - int glp_asnprob_okalg(int form, glp_graph *G, int v_set, int a_cost, - double *sol, int a_x); -\end{verbatim} - -\description - -The routine \verb|glp_mincost_okalg| finds optimal solution to the -assignment problem with the out-of-kilter -algorithm.\footnote{GLPK implementation of the out-of-kilter algorithm -is based on the following book: L.~R.~Ford,~Jr., and D.~R.~Fulkerson, -``Flows in Networks,'' The RAND Corp., Report R-375-PR (August 1962), -Chap. III ``Minimal Cost Flow Problems,'' pp.~113-26.} Note that this -routine requires all the problem data to be integer-valued. - -The parameter \verb|form| defines which LP formulation should be used: - -\verb|GLP_ASN_MIN| --- perfect matching (15)---(18), minimization; - -\verb|GLP_ASN_MAX| --- perfect matching (15)---(18), maximization; - -\verb|GLP_ASN_MMP| --- maximum weighted matching (11)---(14). - -\newpage - -The parameter \verb|G| is the graph program object, which specifies the -assignment problem instance. - -The parameter \verb|v_set| specifies an offset of the field of type -\verb|int| in the vertex data block, which contains the node set -indicator: - -0 --- the node is in set $R$; - -1 --- the node is in set $S$. - -\noindent -If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs -is in set $R$, and a node having no outgoing arcs is in set $S$. - -The parameter \verb|a_cost| specifies an offset of the field of type -\verb|double| in the arc data block, which contains $c_{ij}$, the edge -cost. This value must be integer in the range [\verb|-INT_MAX|, -\verb|+INT_MAX|]. If \verb|a_cost| $<0$, it is assumed that $c_{ij}=1$ -for all edges. - -The parameter \verb|sol| specifies a location, to which the routine -stores the objective value (that is, the total cost) found. -If \verb|sol| is \verb|NULL|, the objective value is not stored. - -The parameter \verb|a_x| specifies an offset of the field of type -\verb|int| in the arc data block, to which the routine stores $x_{ij}$. -If \verb|a_x| $<0$, this value is not stored. - -\returns - -\begin{retlist} -0 & Optimal solution found.\\ - -\verb|GLP_ENOPFS| & No (primal) feasible solution exists.\\ - -\verb|GLP_EDATA| & Unable to start the search, because the assignment -problem data are either incorrect (this error is detected by the -routine \verb|glp_check_asnprob|), not integer-valued or out of range.\\ - -\verb|GLP_ERANGE| & The search was prematurely terminated because of -integer overflow.\\ - -\verb|GLP_EFAIL| & An error has been detected in the program logic. -(If this code is returned for your problem instance, please report to -\verb||.)\\ -\end{retlist} - -\para{Comments} - -Since the out-of-kilter algorithm is designed to find a minimal cost -circulation, the routine \verb|glp_asnprob_okalg| converts the original -graph to a network suitable for this algorithm in the following -way:\footnote{The conversion is performed internally and does not -change the original graph program object passed to the routine.} - -1) it replaces each edge $(i,j)$ by arc $(i\rightarrow j)$, -flow $x_{ij}$ through which has zero lower bound ($l_{ij}=0$), unity -upper bound ($u_{ij}=1$), and per-unit cost $+c_{ij}$ (in case of -\verb|GLP_ASN_MIN|), or $-c_{ij}$ (in case of \verb|GLP_ASN_MAX| and -\verb|GLP_ASN_MMP|); - -2) then it adds one auxiliary feedback node $k$; - -3) for each original node $i\in R$ the routine adds auxiliary supply -arc $(k\rightarrow i)$, flow $x_{ki}$ through which is costless -($c_{ki}=0$) and either fixed at 1 ($l_{ki}=u_{ki}=1$, in case of -\verb|GLP_ASN_MIN| and \verb|GLP_ASN_MAX|) or has zero lower bound and -unity upper bound ($l_{ij}=0$, $u_{ij}=1$, in case of -\verb|GLP_ASN_MMP|); - -\newpage - -4) similarly, for each original node $j\in S$ the routine adds -auxiliary demand arc $(j\rightarrow k)$, flow $x_{jk}$ through which is -costless ($c_{jk}=0$) and either fixed at 1 ($l_{jk}=u_{jk}=1$, in case -of \verb|GLP_ASN_MIN| and \verb|GLP_ASN_MAX|) or has zero lower bound -and unity upper bound ($l_{jk}=0$, $u_{jk}=1$, in case of -\verb|GLP_ASN_MMP|). - -\para{Example} - -The example program shown below reads the assignment problem instance -in DIMACS format from file `\verb|sample.asn|', solves it by using the -routine \verb|glp_asnprob_okalg|, and writes the solution found to the -standard output. - -\begin{footnotesize} -\begin{verbatim} -#include -#include -#include -#include - -typedef struct { int set; } v_data; -typedef struct { double cost; int x; } e_data; - -#define node(v) ((v_data *)((v)->data)) -#define edge(e) ((e_data *)((e)->data)) - -int main(void) -{ glp_graph *G; - glp_vertex *v; - glp_arc *e; - int i, ret; - double sol; - G = glp_create_graph(sizeof(v_data), sizeof(e_data)); - glp_read_asnprob(G, offsetof(v_data, set), - offsetof(e_data, cost), "sample.asn"); - ret = glp_asnprob_okalg(GLP_ASN_MMP, G, - offsetof(v_data, set), offsetof(e_data, cost), &sol, - offsetof(e_data, x)); - printf("ret = %d; sol = %5g\n", ret, sol); - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (e = v->out; e != NULL; e = e->t_next) - printf("edge %2d %2d: x = %d; c = %g\n", - e->tail->i, e->head->i, edge(e)->x, edge(e)->cost); - } - glp_delete_graph(G); - return 0; -} -\end{verbatim} -\end{footnotesize} - -If `\verb|sample.asn|' is the example data file from the subsection -describing \verb|glp_read_asnprob|, the output may look like follows: - -\begin{footnotesize} -\begin{verbatim} -Reading assignment problem data from `sample.asn'... -Assignment problem has 8 + 9 = 17 nodes and 22 arcs -38 lines were read -ret = 0; sol = 180 -edge 1 12: x = 1; c = 20 -edge 1 10: x = 0; c = 21 -edge 1 9: x = 0; c = 13 -edge 2 13: x = 1; c = 26 -edge 2 12: x = 0; c = 8 -edge 2 10: x = 0; c = 12 -edge 3 13: x = 0; c = 11 -edge 3 11: x = 1; c = 22 -edge 4 14: x = 1; c = 25 -edge 4 12: x = 0; c = 36 -edge 4 9: x = 0; c = 12 -edge 5 17: x = 0; c = 32 -edge 5 16: x = 1; c = 35 -edge 5 15: x = 0; c = 8 -edge 5 14: x = 0; c = 4 -edge 5 13: x = 0; c = 11 -edge 5 12: x = 0; c = 40 -edge 5 11: x = 0; c = 41 -edge 6 9: x = 1; c = 13 -edge 7 10: x = 0; c = 19 -edge 8 11: x = 0; c = 15 -edge 8 10: x = 1; c = 39 -\end{verbatim} -\end{footnotesize} - -\subsection{glp\_asnprob\_hall --- find bipartite matching of maximum -cardinality} - -\synopsis - -\begin{verbatim} - int glp_asnprob_hall(glp_graph *G, int v_set, int a_x); -\end{verbatim} - -\description - -The routine \verb|glp_asnprob_hall| finds a matching of maximal -cardinality in the specified bipartite graph. It uses a version of the -Fortran routine \verb|MC21A| developed by -I.~S.~Duff\footnote{I.~S.~Duff, Algorithm 575: Permutations for -zero-free diagonal, ACM Trans. on Math. Softw. 7 (1981),\linebreak -pp.~387-390.}, which implements Hall's algorithm.\footnote{M.~Hall, -``An Algorithm for Distinct Representatives,'' Am. Math. Monthly 63 -(1956), pp.~716-717.} - -The parameter \verb|G| is a pointer to the graph program object. - -The parameter \verb|v_set| specifies an offset of the field of type -\verb|int| in the vertex data block, which contains the node set -indicator: - -0 --- the node is in set $R$; - -1 --- the node is in set $S$. - -\noindent -If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs -is in set $R$, and a node having no outgoing arcs is in set $S$. - -The parameter \verb|a_x| specifies an offset of the field of type -\verb|int| in the arc data block, to which the routine stores $x_{ij}$. -If \verb|a_x| $<0$, this value is not stored. - -\returns - -The routine \verb|glp_asnprob_hall| returns the cardinality of the -matching found. However, if the specified graph is incorrect (as -detected by the routine \verb|glp_check_asnprob|), this routine returns -a negative value. - -\newpage - -\para{Comments} - -The same solution may be obtained with the routine -\verb|glp_asnprob_okalg| (for LP formulation \verb|GLP_ASN_MMP| and -all edge costs equal to 1). However, the routine -\verb|glp_asnprob_hall| is much faster. - -\para{Example} - -The example program shown below reads the assignment problem instance -in DIMACS format from file `\verb|sample.asn|', finds a bipartite -matching of maximal cardinality by using the routine -\verb|glp_asnprob_hall|, and writes the solution found to the standard -output. - -\begin{footnotesize} -\begin{verbatim} -#include -#include -#include -#include - -typedef struct { int set; } v_data; -typedef struct { int x; } e_data; - -#define node(v) ((v_data *)((v)->data)) -#define edge(e) ((e_data *)((e)->data)) - -int main(void) -{ glp_graph *G; - glp_vertex *v; - glp_arc *e; - int i, card; - G = glp_create_graph(sizeof(v_data), sizeof(e_data)); - glp_read_asnprob(G, offsetof(v_data, set), -1, - "sample.asn"); - card = glp_asnprob_hall(G, offsetof(v_data, set), - offsetof(e_data, x)); - printf("card = %d\n", card); - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (e = v->out; e != NULL; e = e->t_next) - printf("edge %2d %2d: x = %d\n", - e->tail->i, e->head->i, edge(e)->x); - } - glp_delete_graph(G); - return 0; -} -\end{verbatim} -\end{footnotesize} - -If `\verb|sample.asn|' is the example data file from the subsection -describing \verb|glp_read_asnprob|, the output may look like follows: - -\begin{footnotesize} -\begin{verbatim} -Reading assignment problem data from `sample.asn'... -Assignment problem has 8 + 9 = 17 nodes and 22 arcs -38 lines were read -card = 7 -edge 1 12: x = 1 -edge 1 10: x = 0 -edge 1 9: x = 0 -edge 2 13: x = 1 -edge 2 12: x = 0 -edge 2 10: x = 0 -edge 3 13: x = 0 -edge 3 11: x = 1 -edge 4 14: x = 1 -edge 4 12: x = 0 -edge 4 9: x = 0 -edge 5 17: x = 1 -edge 5 16: x = 0 -edge 5 15: x = 0 -edge 5 14: x = 0 -edge 5 13: x = 0 -edge 5 12: x = 0 -edge 5 11: x = 0 -edge 6 9: x = 1 -edge 7 10: x = 1 -edge 8 11: x = 0 -edge 8 10: x = 0 -\end{verbatim} -\end{footnotesize} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\newpage - -\section{Critical path problem} - -\subsection{Background} - -The {\it critical path problem} (CPP) is stated as follows. Let there -be given a project $J$, which is a set of jobs (tasks, activities, -etc.). Performing each job $i\in J$ requires time $t_i\geq 0$. Besides, -over the set $J$ there is given a precedence relation -$R\subseteq J\times J$, where $(i,j)\in R$ means that job $i$ -immediately precedes job $j$, i.e. performing job $j$ cannot start -until job $i$ has been completely performed. The problem is to find -starting times $x_i$ for each job $i\in J$, which satisfy to the -precedence relation and minimize the total duration (makespan) of the -project. - -The following is an example of the critical path problem: - -\bigskip - -\begin{center} -\begin{tabular}{|c|l|c|c|} -\hline -Job&Desription&Time&Predecessors\\ -\hline -A&Excavate&3&---\\ -B&Lay foundation&4&A\\ -C&Rough plumbing&3&B\\ -D&Frame&10&B\\ -E&Finish exterior&8&D\\ -F&Install HVAC&4&D\\ -G&Rough electric&6&D\\ -H&Sheet rock&8&C, E, F, G\\ -I&Install cabinets&5&H\\ -J&Paint&5&H\\ -K&Final plumbing&4&I\\ -L&Final electric&2&J\\ -M&Install flooring&4&K, L\\ -\hline -\end{tabular} -\end{center} - -\bigskip - -Obviously, the project along with the precedence relation can be -represented as a directed graph $G=(J,R)$ called {\it project network}, -where each node $i\in J$ corresponds to a job, and arc -$(i\rightarrow j)\in R$ means that job $i$ immediately precedes job -$j$.\footnote{There exists another network representation of the -critical path problem, where jobs correspond to arcs while nodes -correspond to events introduced to express the precedence relation. -That representation, however, is much less convenient than the one, -where jobs are represented as nodes of the network.} The project network -for the example above is shown on Fig.~4. - -May note that the project network must be acyclic; otherwise, it would -be impossible to satisfy to the precedence relation for any job that -belongs to a cycle. - -\newpage - -\hspace*{.5in} -\xymatrix -{&&&C|3\ar[rd]&&I|5\ar[r]&K|4\ar[rd]&\\ -A|3\ar[r]&B|4\ar[rru]\ar[rd]&&E|8\ar[r]&H|8\ar[ru]\ar[rd]&&&M|4\\ -&&D|10\ar[ru]\ar[r]\ar[rd]&F|4\ar[ru]&&J|5\ar[r]&L|2\ar[ru]&\\ -&&&G|6\ar[ruu]&&&&\\ -} - -\medskip - -\noindent\hfil -Fig.~4. An example of the project network. - -\medskip - -The critical path problem can be naturally formulated as the following -LP problem: - -\medskip - -\noindent -\hspace{.5in}minimize -$$z\eqno(19)$$ -\hspace{.5in}subject to -$$x_i+t_i\leq z\ \ \ \hbox{for all}\ i\in J\ \ \ \ \eqno(20)$$ -$$x_i+t_i\leq x_j\ \ \ \hbox{for all}\ (i,j)\in R\eqno(21)$$ -$$x_i\geq 0\ \ \ \ \ \ \ \hbox{for all}\ i\in J\ \ \eqno(22)$$ - -The inequality constraints (21), which are active in the optimal -solution, define so called {\it critical path} having the following -property: the minimal project duration $z$ can be decreased only by -decreasing the times $t_j$ for jobs on the critical path, and delaying -any critical job delays the entire project. - -\subsection{glp\_cpp --- solve critical path problem} - -\synopsis - -\begin{verbatim} - double glp_cpp(glp_graph *G, int v_t, int v_es, int v_ls); -\end{verbatim} - -\description - -The routine \verb|glp_cpp| solves the critical path problem represented -in the form of the project network. - -The parameter \verb|G| is a pointer to the graph object, which -specifies the project network. This graph must be acyclic. Multiple -arcs are allowed being considered as single arcs. - -The parameter \verb|v_t| specifies an offset of the field of type -\verb|double| in the vertex data block, which contains time $t_i\geq 0$ -needed to perform corresponding job $j\in J$. If \verb|v_t| $<0$, it is -assumed that $t_i=1$ for all jobs. - -The parameter \verb|v_es| specifies an offset of the field of type -\verb|double| in the vertex data block, to which the routine stores -the {\it earliest start time} for corresponding job. If \verb|v_es| -$<0$, this time is not stored. - -\newpage - -The parameter \verb|v_ls| specifies an offset of the field of type -\verb|double| in the vertex data block, to which the routine stores -the {\it latest start time} for corresponding job. If \verb|v_ls| -$<0$, this time is not stored. - -The difference between the latest and earliest start times of some job -is called its {\it time reserve}. Delaying a job within its time -reserve does not affect the project duration, so if the time reserve is -zero, the corresponding job is critical. - -\para{Returns} - -The routine \verb|glp_cpp| returns the minimal project duration, i.e. -minimal time needed to perform all jobs in the project. - -\para{Example} - -The example program below solves the critical path problem shown on -Fig.~4 by using the routine \verb|glp_cpp| and writes the solution -found on the standard output. - -\begin{footnotesize} -\begin{verbatim} -#include -#include -#include -#include - -typedef struct { double t, es, ls; } v_data; - -#define node(v) ((v_data *)((v)->data)) - -int main(void) -{ glp_graph *G; - int i; - double t, es, ef, ls, lf, total; - G = glp_create_graph(sizeof(v_data), 0); - glp_add_vertices(G, 13); - node(G->v[1])->t = 3; /* A: Excavate */ - node(G->v[2])->t = 4; /* B: Lay foundation */ - node(G->v[3])->t = 3; /* C: Rough plumbing */ - node(G->v[4])->t = 10; /* D: Frame */ - node(G->v[5])->t = 8; /* E: Finish exterior */ - node(G->v[6])->t = 4; /* F: Install HVAC */ - node(G->v[7])->t = 6; /* G: Rough elecrtic */ - node(G->v[8])->t = 8; /* H: Sheet rock */ - node(G->v[9])->t = 5; /* I: Install cabinets */ - node(G->v[10])->t = 5; /* J: Paint */ - node(G->v[11])->t = 4; /* K: Final plumbing */ - node(G->v[12])->t = 2; /* L: Final electric */ - node(G->v[13])->t = 4; /* M: Install flooring */ - glp_add_arc(G, 1, 2); /* A precedes B */ - glp_add_arc(G, 2, 3); /* B precedes C */ - glp_add_arc(G, 2, 4); /* B precedes D */ - glp_add_arc(G, 4, 5); /* D precedes E */ - glp_add_arc(G, 4, 6); /* D precedes F */ - glp_add_arc(G, 4, 7); /* D precedes G */ - glp_add_arc(G, 3, 8); /* C precedes H */ - glp_add_arc(G, 5, 8); /* E precedes H */ - glp_add_arc(G, 6, 8); /* F precedes H */ - glp_add_arc(G, 7, 8); /* G precedes H */ - glp_add_arc(G, 8, 9); /* H precedes I */ - glp_add_arc(G, 8, 10); /* H precedes J */ - glp_add_arc(G, 9, 11); /* I precedes K */ - glp_add_arc(G, 10, 12); /* J precedes L */ - glp_add_arc(G, 11, 13); /* K precedes M */ - glp_add_arc(G, 12, 13); /* L precedes M */ - total = glp_cpp(G, offsetof(v_data, t), offsetof(v_data, es), - offsetof(v_data, ls)); - printf("Minimal project duration is %.2f\n\n", total); - printf("Job Time ES EF LS LF\n"); - printf("--- ------ ------ ------ ------ ------\n"); - for (i = 1; i <= G->nv; i++) - { t = node(G->v[i])->t; - es = node(G->v[i])->es; - ef = es + node(G->v[i])->t; - ls = node(G->v[i])->ls; - lf = ls + node(G->v[i])->t; - printf("%3d %6.2f %s %6.2f %6.2f %6.2f %6.2f\n", - i, t, ls - es < 0.001 ? "*" : " ", es, ef, ls, lf); - } - glp_delete_graph(G); - return 0; -} -\end{verbatim} -\end{footnotesize} - -The output from the example program shown below includes job number, -the time needed to perform a job, earliest start time (\verb|ES|), -earliest finish time (\verb|EF|), latest start time (\verb|LS|), and -latest finish time (\verb|LF|) for each job in the project. Critical -jobs are marked by asterisks. - -\begin{footnotesize} -\begin{verbatim} -Minimal project duration is 46.00 - -Job Time ES EF LS LF ---- ------ ------ ------ ------ ------ - 1 3.00 * 0.00 3.00 0.00 3.00 - 2 4.00 * 3.00 7.00 3.00 7.00 - 3 3.00 7.00 10.00 22.00 25.00 - 4 10.00 * 7.00 17.00 7.00 17.00 - 5 8.00 * 17.00 25.00 17.00 25.00 - 6 4.00 17.00 21.00 21.00 25.00 - 7 6.00 17.00 23.00 19.00 25.00 - 8 8.00 * 25.00 33.00 25.00 33.00 - 9 5.00 * 33.00 38.00 33.00 38.00 - 10 5.00 33.00 38.00 35.00 40.00 - 11 4.00 * 38.00 42.00 38.00 42.00 - 12 2.00 38.00 40.00 40.00 42.00 - 13 4.00 * 42.00 46.00 42.00 46.00 -\end{verbatim} -\end{footnotesize} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\chapter{Graph Optimization API Routines} - -\section{Maximum clique problem} - -\subsection{Background} - -The {\it maximum clique problem (MCP)} is a classic combinatorial -optimization problem. Given an undirected graph $G=(V,E)$, where $V$ is -a set of vertices, and $E$ is a set of edges, this problem is to find -the largest {\it clique} $C\subseteq G$, i.e. the largest induced -complete subgraph. A generalization of this problem is the {\it maximum -weight clique problem (MWCP)}, which is to find a clique $C\subseteq G$ -of the largest weight $\displaystyle\sum_{v\in C}w(v)\rightarrow\max$, -where $w(v)$ is a weight of vertex $v\in V$. - -An example of the maximum weight clique problem is shown on Fig.~5. - -\begin{figure} -\noindent\hfil -\begin{tabular}{c} -{\xymatrix %@C=16pt -{&&&{v_1}\ar@{-}[lllddd]\ar@{-}[llddddd]\ar@{-}[dddddd] -\ar@{-}[rrrddd]&&&\\ -&{v_2}\ar@{-}[rrrr]\ar@{-}[rrrrdddd]\ar@{-}[rrddddd]\ar@{-}[dddd]&&&& -{v_3}\ar@{-}[llllldd]\ar@{-}[lllldddd]\ar@{-}[dddd]&\\ -&&&&&&\\ -{v_4}\ar@{-}[rrrrrr]\ar@{-}[rrrddd]&&&&&&{v_5}\ar@{-}[lllddd] -\ar@{-}[ldd]\\ -&&&&&&\\ -&{v_6}\ar@{-}[rrrr]&&&&{v_7}&\\ -&&&{v_8}&&&\\ -}} -\end{tabular} -\begin{tabular}{r@{\ }c@{\ }l} -$w(v_1)$&=&3\\$w(v_2)$&=&4\\$w(v_3)$&=&8\\$w(v_4)$&=&1\\ -$w(v_5)$&=&5\\$w(v_6)$&=&2\\$w(v_7)$&=&1\\$w(v_8)$&=&3\\ -\end{tabular} - -\bigskip - -\begin{center} -Fig.~5. An example of the maximum weight clique problem. -\end{center} -\end{figure} - -\subsection{glp\_wclique\_exact --- find maximum weight clique with -exact algorithm} - -\synopsis - -\begin{verbatim} - int glp_wclique_exact(glp_graph *G, int v_wgt, double *sol, int v_set); -\end{verbatim} - -\description - -The routine {\tt glp\_wclique\_exact} finds a maximum weight clique in -the specified undirected graph with the exact algorithm developed by -Patric \"Osterg{\aa}rd.\footnote{P.~R.~J.~\"Osterg{\aa}rd, A new -algorithm for the maximum-weight clique problem, Nordic J. of -Computing, Vol.~8, No.~4, 2001, pp.~424--36.} - -The parameter {\tt G} is the program object, which specifies -an undirected graph. Each arc $(x\rightarrow y)$ in {\tt G} is -considered as edge $(x,y)$, self-loops are ignored, and multiple edges, -if present, are replaced (internally) by simple edges. - -The parameter {\tt v\_wgt} specifies an offset of the field of type -{\tt double} in the vertex data block, which contains a weight of -corresponding vertex. Vertex weights must be integer-valued in the -range $[0,$ {\tt INT\_MAX}$]$. If {\tt v\_wgt} $<0$, it is assumed that -all vertices of the graph have the weight 1. - -\newpage - -The parameter {\tt sol} specifies a location, to which the routine -stores the weight of the clique found (the clique weight is the sum -of weights of all vertices included in the clique.) If {\tt sol} is -{\tt NULL}, the solution is not stored. - -The parameter {\tt v\_set} specifies an offset of the field of type -{\tt int} in the vertex data block, to which the routines stores a -vertex flag: 1 means that the corresponding vertex is included in the -clique found, and 0 otherwise. If {\tt v\_set} $<0$, vertex flags are -not stored. - -\returns - -\begin{retlist} -0 & Optimal solution found.\\ - -\verb|GLP_EDATA| & Unable to start the search, because some vertex -weights are either not integer-valued or out of range. This code is -also returned if the sum of weights of all vertices exceeds -{\tt INT\_MAX}. \\ -\end{retlist} - -\para{Notes} - -1. The routine {\it glp\_wclique\_exact} finds exact solution. Since -both MCP and MWCP problems are NP-complete, the algorithm may require -exponential time in worst cases. - -2. Internally the specified graph is converted to an adjacency matrix -in {\it dense} format. This requires about $|V|^2/16$ bytes of memory, -where $|V|$ is the number of vertices in the graph. - -\para{Example} - -The example program shown below reads a MWCP instance in DIMACS -clique/coloring format from file `\verb|sample.clq|', finds the clique -of largest weight, and writes the solution found on the standard -output. - -\newpage - -\begin{footnotesize} -\begin{verbatim} -#include -#include -#include -#include - -typedef struct { double wgt; int set; } v_data; - -#define vertex(v) ((v_data *)((v)->data)) - -int main(void) -{ glp_graph *G; - glp_vertex *v; - int i, ret; - double sol; - G = glp_create_graph(sizeof(v_data), 0); - glp_read_ccdata(G, offsetof(v_data, wgt), "sample.clq"); - ret = glp_wclique_exact(G, offsetof(v_data, wgt), &sol, - offsetof(v_data, set)); - printf("ret = %d; sol = %g\n", ret, sol); - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - printf("vertex %d: weight = %g, flag = %d\n", - i, vertex(v)->wgt, vertex(v)->set); - } - glp_delete_graph(G); - return 0; -} -\end{verbatim} -\end{footnotesize} - -For the example shown on Fig.~5 the data file may look like follows: - -\begin{footnotesize} -\begin{verbatim} -c sample.clq -c -c This is an example of the maximum weight clique -c problem in DIMACS clique/coloring format. -c -p edge 8 16 -n 1 3 -n 2 4 -n 3 8 -n 5 5 -n 6 2 -n 8 3 -e 1 4 -e 1 5 -e 1 6 -e 1 8 -e 2 3 -e 2 6 -e 2 7 -e 2 8 -e 3 4 -e 3 6 -e 3 7 -e 4 5 -e 4 8 -e 5 7 -e 5 8 -e 6 7 -c -c eof -\end{verbatim} -\end{footnotesize} - -The corresponding output from the example program is the following: - -\begin{footnotesize} -\begin{verbatim} -Reading graph from `sample.clq'... -Graph has 8 vertices and 16 edges -28 lines were read -ret = 0; sol = 15 -vertex 1: weight = 3, flag = 0 -vertex 2: weight = 4, flag = 1 -vertex 3: weight = 8, flag = 1 -vertex 4: weight = 1, flag = 0 -vertex 5: weight = 5, flag = 0 -vertex 6: weight = 2, flag = 1 -vertex 7: weight = 1, flag = 1 -vertex 8: weight = 3, flag = 0 -\end{verbatim} -\end{footnotesize} - -\end{document} diff --git a/resources/3rdparty/glpk-4.53/doc/miplib2.txt b/resources/3rdparty/glpk-4.53/doc/miplib2.txt deleted file mode 100644 index 762c83f89..000000000 --- a/resources/3rdparty/glpk-4.53/doc/miplib2.txt +++ /dev/null @@ -1,135 +0,0 @@ -Solver: GLPSOL 4.40 (options used: --pcost) -Computer: Intel Pentium 4, 3.0 GHz -Platform: Cygwin 1.5.25 -Compiler: GCC 3.4.4 (options used: -O3) -Test set: MIPLIB 2.0 - -Problem Optimal Solution Cuts Used Nodes Iters Time,s Mem,MB --------- ---------------- --------- -------- ------ ------ ------ -air01 +6.796000000e+03 3 41 < 1 1.2 -air02 +7.810000000e+03 43 201 6 13.8 -air03 +3.401600000e+05 33 414 12 21.0 -air04 +5.613700000e+04 1901 109800 396 32.4 -air05 +2.637400000e+04 6445 201649 452 45.0 -air06 +4.964900000e+04 11 6868 31 18.1 -bell3a +8.784303160e+05 --gomory 7965 42363 17 6.1 -bell3b +1.178616062e+07 --gomory 6031 30467 19 3.2 -bell4 +1.854148420e+07 --gomory 7203 25019 16 2.9 -bell5 +8.966406492e+06 --gomory 5605 18555 8 1.5 -bm23 +3.400000000e+01 373 878 < 1 0.2 -cracpb1 +2.219900000e+04 47 5258 2 1.3 -dcmulti +1.881820000e+05 743 3366 2 1.1 -diamond infeasible 3 4 < 1 0.1 -dsbmip -3.051981750e+02 --mir 217 46088 24 4.5 -egout +5.681007000e+02 91 137 < 1 0.3 -enigma +0.000000000e+00 16419 55071 6 3.2 -fixnet3 +5.197300000e+04 81 380 < 1 1.4 -fixnet4 +8.936000000e+03 211 1095 1 1.4 -fixnet6 +3.983000000e+03 1031 3136 2 1.7 -flugpl +1.201500000e+06 397 231 < 1 0.1 -gen +1.123133627e+05 195 3991 1 1.7 -khb05250 +1.069402260e+08 2163 14498 5 2.8 -l152lav +4.722000000e+03 7419 95299 68 12.0 -lp4l +2.967000000e+03 173 1331 2 1.7 -lseu +1.120000000e+03 10821 31954 5 2.5 -misc01 +5.635000000e+02 769 4593 1 0.5 -misc02 +1.690000000e+03 29 282 < 1 0.2 -misc03 +3.360000000e+03 957 6742 2 1.1 -misc04 +2.666699247e+03 17 2052 1 7.0 -misc05 +2.984500000e+03 293 2520 1 1.1 -misc06 +1.285086074e+04 57 941 < 1 2.7 -misc07 +2.810000000e+03 --mir 66075 579129 424 33.4 -mod008 +3.070000000e+02 8185 24245 8 2.3 -mod010 +6.548000000e+03 315 6283 7 5.3 -mod011 -mod013 +2.809500000e+02 545 1155 < 1 0.3 -modglob +2.074050809e+07 --mir 5197 31985 20 2.8 -noswot -p0033 +3.089000000e+03 305 955 < 1 0.2 -p0040 +6.202700000e+04 17 66 < 1 0.1 -p0201 +7.615000000e+03 521 3660 1 0.9 -p0282 +2.584110000e+05 623 1204 1 0.8 -p0291 +5.223749000e+03 71 154 < 1 0.7 -p0548 +8.691000000e+03 7617 23556 9 2.9 -p2756 +3.124000000e+03 --mir 3911 15157 57 10.9 -p6000 -2.451377000e+06 19209 40906 570 15.8 -pipex +7.882630000e+02 1569 2469 < 1 0.4 -qiu -1.328731369e+02 80473 1918742 1174 69.2 -rentacar +3.035676098e+07 43 1649 3 12.1 -rgn +8.219999924e+01 3325 18700 2 1.2 -sample2 +3.750000000e+02 163 347 < 1 0.2 -sentoy -7.772000000e+03 335 723 < 1 0.4 -set1al +1.586975000e+04 --mir 17 532 < 1 1.5 -set1ch -set1cl +6.484250000e+03 --mir 1 502 < 1 1.1 -stein15 +9.000000000e+00 87 375 < 1 0.2 -stein27 +1.800000000e+01 3255 15327 2 1.0 -stein45 +3.000000000e+01 52301 389140 139 19.2 -stein9 +5.000000000e+00 17 45 < 1 0.1 -vpm1 +2.000000000e+01 --mir 9 836 < 1 0.9 - -PROBLEM CHARACTERISTICS - -Problem Rows Cols ( Int 0/1) Nonz Best Solution --------- ------ ---------------------- ------ -------------------------- -air01 24 771 ( all all) 4986 6796 (opt) -air02 51 6774 ( all all) 68329 7810 (opt) -air03 125 10757 ( all all) 101785 340160 (opt) -air04 824 8904 ( all all) 81869 56138 (opt) -air05 427 7195 ( all all) 59316 26402 (not opt) -air06 826 8627 ( all all) 79433 49649 (opt) -bell3a 124 133 ( 71 39) 441 878430.32 (opt) -bell3b 124 133 ( 71 39) 441 11786160.62 (opt) -bell4 106 117 ( 64 34) 385 18541484.20 (opt) -bell5 92 104 ( 58 30) 340 8966406.49 (opt) -bm23 21 27 ( all all) 505 34 (opt) -cracpb1 144 572 ( all all) 4730 22199 (opt) -dcmulti 291 548 ( 75 all) 1833 188182.0000 (opt) -diamond 5 2 ( all all) 9 integer infeasible -dsbmip 1855 1886 ( 192 160) 9768 -305.198 (opt) -egout 99 141 ( 55 all) 392 568.101 (opt) -enigma 22 100 ( all all) 298 0.0 (opt) -fixnet3 479 878 ( 378 all) 2631 51973 (opt) -fixnet4 479 878 ( 378 all) 2621 8936 (opt) -fixnet6 479 878 ( 378 all) 2550 3983 (opt) -flugpl 19 18 ( 11 none) 64 1201500 (opt) -gen 781 870 ( 150 144) 3174 112313 (opt) -khb05250 102 1350 ( 24 all) 3973 106940226 (opt) -l152lav 98 1989 ( all all) 11911 4750 (not opt) -lp4l 86 1086 ( all all) 5763 2967 (opt) -lseu 29 89 ( all all) 394 1120 (opt) -misc01 55 83 ( 82 all) 746 563.5 (opt) -misc02 40 59 ( 58 all) 414 1690 (opt) -misc03 97 160 ( 159 all) 2054 3360 (opt) -misc04 1726 4897 ( 30 all) 17253 2666.699 (opt) -misc05 301 136 ( 74 all) 2946 2984.5 (opt) -misc06 821 1808 ( 112 all) 5860 12850.8607 (opt) -misc07 213 260 ( 259 all) 8620 2810 (not opt) -mod008 7 319 ( all all) 1562 307 (opt) -mod010 147 2655 ( all all) 13858 6548 (opt) -mod011 4482 10958 ( 96 all) 37425 -54558535 (opt) -mod013 63 96 ( 48 all) 288 280.95 (opt) -modglob 292 422 ( 98 all) 1390 20740508 (opt) -noswot 183 128 ( 100 75) 760 -43 (opt) -p0033 17 33 ( all all) 131 3089 (opt) -p0040 24 40 ( all all) 150 62027 (opt) -p0201 134 201 ( all all) 2124 7615 (opt) -p0282 242 282 ( all all) 2248 258411 (opt) -p0291 253 291 ( all all) 349 5223.7490 (opt) -p0548 177 548 ( all all) 2127 8691 (opt) -p2756 756 2756 ( all all) 11103 3124 (opt) -p6000 2177 6000 ( all all) 54238 -2451377 (opt) -pipex 26 48 ( all all) 240 788.263 (opt) -qiu 1193 840 ( 48 all) 3432 -132.873137 (opt) -rentacar 6804 9557 ( 55 all) 42019 30356761 (opt) -rgn 25 180 ( 100 all) 540 82.1999 (opt) -sample2 46 67 ( 21 all) 179 375 (opt) -sentoy 31 60 ( all all) 1860 -7772 (opt) -set1al 493 712 ( 240 all) 1884 15869.7 (opt) -set1ch 493 712 ( 240 all) 1884 54537.7 (opt) -set1cl 493 712 ( 240 all) 1884 6484.25 (opt) -stein15 37 15 ( all all) 135 9 (opt) -stein27 119 27 ( all all) 405 18 (opt) -stein45 332 45 ( all all) 1079 30 (opt) -stein9 14 9 ( all all) 54 5 (opt) -vpm1 235 378 ( 168 all) 917 20 (opt) diff --git a/resources/3rdparty/glpk-4.53/doc/miplib3.txt b/resources/3rdparty/glpk-4.53/doc/miplib3.txt deleted file mode 100644 index ad7884bb2..000000000 --- a/resources/3rdparty/glpk-4.53/doc/miplib3.txt +++ /dev/null @@ -1,143 +0,0 @@ -Solver: GLPSOL 4.40 -Computer: Intel Pentium 4, 3.0 GHz -Platform: Cygwin 1.5.25 -Compiler: GCC 3.4.4 (options used: -O3) -Test set: MIPLIB 3.0 - -Problem Optimal Solution Options Used Nodes Iters Time,s Mem,MB --------- ---------------- ---------------- -------- ------ ------ ------ -10teams +9.240000000e+02 --pcost --gomory 6013 349276 207 12.7 -air03 +3.401600000e+05 --pcost 33 414 12 21.0 -air04 +5.613700000e+04 --pcost 1901 109800 396 32.4 -air05 +2.637400000e+04 --pcost 6445 201649 452 45.0 -arki001 -bell3a +8.784303160e+05 --pcost --gomory 7965 42363 17 6.1 -bell5 +8.966406492e+06 --pcost --gomory 5605 18555 8 1.5 -blend2 +7.598985000e+00 --pcost 7185 24256 7 2.1 -cap6000 -2.451377000e+06 --pcost 19209 40906 569 15.8 -dano3mip -danoint -dcmulti +1.881820000e+05 --pcost 743 3366 2 1.1 -dsbmip -3.051981750e+02 --pcost --mir 217 46088 24 4.5 -egout +5.681007000e+02 --pcost 91 137 < 1 0.3 -enigma +0.000000000e+00 --pcost 16419 55071 6 3.2 -fast0507 -fiber +4.059351800e+05 --pcost --mir 407 3108 4 2.4 -fixnet6 +3.983000000e+03 --pcost 1031 3136 2 1.7 -flugpl +1.201500000e+06 --pcost 397 231 < 1 0.1 -gen +1.123133627e+05 --pcost 195 3991 1 1.7 -gesa2 +2.577985637e+07 --pcost --mir 59 2723 4 4.1 -gesa2_o +2.577985637e+07 --pcost --mir 69 2588 5 3.7 -gesa3 +2.799104265e+07 --pcost --mir 93 2774 5 3.7 -gesa3_o +2.799104265e+07 --pcost --mir 117 3271 6 3.6 -gt2 +2.116600000e+04 --pcost 5613 26115 2 1.2 -harp2 -khb05250 +1.069402260e+08 --pcost 2163 14498 5 2.8 -l152lav +4.722000000e+03 --pcost 7419 95299 68 12.0 -lseu +1.120000000e+03 --pcost 10821 31954 5 2.5 -marksh1 -marksh2 -mas74 -mas76 -misc03 +3.360000000e+03 --pcost 957 6742 2 1.1 -misc06 +1.285086074e+04 --pcost 57 941 < 1 2.7 -misc07 +2.810000000e+03 --pcost --mir 66075 579129 424 33.4 -mitre -mkc -mod008 +3.070000000e+02 --pcost 8185 24245 8 2.3 -mod010 +6.548000000e+03 --pcost 315 6283 7 5.3 -mod011 -modglob +2.074050809e+07 --pcost --mir 5197 31985 20 2.8 -noswot -nw04 +1.686200000e+04 (none) 361 5544 345 138.3 -p0033 +3.089000000e+03 --pcost 305 955 < 1 0.2 -p0201 +7.615000000e+03 --pcost 521 3660 1 0.9 -p0282 +2.584110000e+05 --pcost 623 1204 1 0.8 -p0548 +8.691000000e+03 --pcost 7617 23556 9 2.9 -p2756 +3.124000000e+03 --pcost --mir 3911 15157 57 10.9 -pk1 -pp08a +7.350000000e+03 --pcost --mir 663 9196 4 1.3 -pp08acut +7.350000000e+03 --pcost --mir 17233 260160 154 21.1 -qiu -1.328731369e+02 --pcost 80473 1918742 1174 69.2 -qnet1 +1.602969268e+04 --pcost --mir 183 20352 16 3.6 -qnet1_o +1.602969268e+04 --pcost --mir 75 7645 9 3.3 -rentacar +3.035676098e+07 --pcost 43 1649 3 12.1 -rgn +8.219999924e+01 --pcost 3325 18700 2 1.2 -rout -set1ch -seymour -stein27 +1.800000000e+01 --pcost 3255 15327 2 1.0 -stein45 +3.000000000e+01 --pcost 52301 389140 139 19.2 -swath -vpm1 +2.000000000e+01 --pcost --mir 9 836 < 1 0.9 -vpm2 +1.375000000e+01 --pcost --mir 11729 164856 91 9.2 - -PROBLEM CHARACTERISTICS - -Problem Rows Cols ( Int 0/1) Nonz Best Solution --------- ------ ---------------------- ------ -------------------------- -10teams 230 2025 ( 1800 all) 12150 924 (opt) -air03 125 10757 ( all all) 101785 340160 (opt) -air04 824 8904 ( all all) 81869 56138 (opt) -air05 427 7195 ( all all) 59316 26402 (not opt) -arki001 1048 1388 ( 538 415) 20439 7580813.0459 (not opt) -bell3a 124 133 ( 71 39) 441 878430.32 (opt) -bell5 92 104 ( 58 30) 340 8966406.49 (opt) -blend2 274 353 ( 264 231) 1409 7.598985 (opt) -cap6000 2176 6000 ( all all) 48249 -2451377 (opt) -dano3mip 3202 13873 ( 552 all) 79655 728.1111 (not opt) -danoint 664 521 ( 56 all) 3232 65.67 (opt) -dcmulti 291 548 ( 75 all) 1833 188182.0000 (opt) -dsbmip 1855 1886 ( 192 160) 9768 -305.198 (opt) -egout 99 141 ( 55 all) 392 568.101 (opt) -enigma 22 100 ( all all) 298 0.0 (opt) -fast0507 507 63009 ( all all) 409439 174 (opt) -fiber 363 1298 ( 1254 all) 2944 405935.18000 (opt) -fixnet6 479 878 ( 378 all) 2550 3983 (opt) -flugpl 19 18 ( 11 none) 64 1201500 (opt) -gen 781 870 ( 150 144) 3174 112313 (opt) -gesa2 1392 1224 ( 408 240) 5064 25779856.372 (opt) -gesa2_o 1248 1224 ( 720 384) 3672 25779856.372 (opt) -gesa3 1368 1152 ( 384 216) 4944 27991042.648 (opt) -gesa3_o 1224 1152 ( 672 336) 3624 27991042.648 (opt) -gt2 29 188 ( all 24) 376 21166.000 (opt) -harp2 112 2993 ( all all) 5840 -73899798.00 (opt) -khb05250 102 1350 ( 24 all) 3973 106940226 (opt) -l152lav 98 1989 ( all all) 11911 4750 (not opt) -lseu 29 89 ( all all) 394 1120 (opt) -marksh1 7 62 ( 50 all) 324 -marksh2 8 74 ( 60 all) 448 -mas74 13 151 ( 150 all) 1705 11801.1857 (opt) -mas76 12 151 ( 150 all) 1639 40005.0541 (opt) -misc03 97 160 ( 159 all) 2054 3360 (opt) -misc06 821 1808 ( 112 all) 5860 12850.8607 (opt) -misc07 213 260 ( 259 all) 8620 2810 (not opt) -mitre 2054 10724 ( all all) 39704 115155 (opt) -mkc 3412 5325 ( 5323 all) 20621 -mod008 7 319 ( all all) 1562 307 (opt) -mod010 147 2655 ( all all) 13858 6548 (opt) -mod011 4482 10958 ( 96 all) 37425 -54558535 (opt) -modglob 292 422 ( 98 all) 1390 20740508 (opt) -noswot 183 128 ( 100 75) 760 -43 (opt) -nw04 36 87482 ( all all) 636666 16862 (opt) -p0033 17 33 ( all all) 131 3089 (opt) -p0201 134 201 ( all all) 2124 7615 (opt) -p0282 242 282 ( all all) 2248 258411 (opt) -p0548 177 548 ( all all) 2127 8691 (opt) -p2756 756 2756 ( all all) 11103 3124 (opt) -pk1 45 86 ( 55 all) 915 11 (opt) -pp08a 136 240 ( 64 all) 480 7350 (opt) -pp08acut 246 240 ( 64 all) 839 7350 (opt) -qiu 1193 840 ( 48 all) 3432 -132.873137 (opt) -qnet1 503 1541 ( 1417 1288) 4622 16029.692681 (opt) -qnet1_o 456 1541 ( 1417 1288) 4214 16029.692681 (opt) -rentacar 6804 9557 ( 55 all) 42019 30356761 (opt) -rgn 25 180 ( 100 all) 540 82.1999 (opt) -rout 291 556 ( 315 300) 2431 1077.56 (opt) -set1ch 493 712 ( 240 all) 1884 54537.7 (opt) -seymour 4944 1372 ( all all) 33549 423 (not opt) -stein27 119 27 ( all all) 405 18 (opt) -stein45 332 45 ( all all) 1079 30 (opt) -swath 885 6805 ( 6724 all) 34966 -vpm1 235 378 ( 168 all) 917 20 (opt) -vpm2 234 378 ( 168 all) 917 13.75 (opt) diff --git a/resources/3rdparty/glpk-4.53/doc/netlib.txt b/resources/3rdparty/glpk-4.53/doc/netlib.txt deleted file mode 100644 index a5c01ca80..000000000 --- a/resources/3rdparty/glpk-4.53/doc/netlib.txt +++ /dev/null @@ -1,103 +0,0 @@ -Solver: GLPSOL 4.40 (default options used) -Computer: Intel Pentium 4, 3.0 GHz -Platform: Cygwin 1.5.25 -Compiler: GCC 3.4.4 (options used: -O3) -Test set: Netlib LP collection - -Problem Rows Cols Nonz Optimum Iters Time,s Mem,MB --------- ----- ----- ------ ---------------- ------ ------ ------ -25fv47 822 1571 11127 +5.501845888e+03 1651 < 1 2.1 -80bau3b 2263 9799 29063 +9.872241924e+05 5358 3 6.4 -adlittle 57 97 465 +2.254949632e+05 71 < 1 0.1 -afiro 28 32 88 -4.647531429e+02 10 < 1 0.1 -agg 489 163 2541 -3.599176729e+07 100 < 1 0.5 -agg2 517 302 4515 -2.023925236e+07 178 < 1 0.8 -agg3 517 302 4531 +1.031211594e+07 182 < 1 0.8 -bandm 306 472 2659 -1.586280185e+02 252 < 1 0.6 -beaconfd 174 262 3476 +3.359248581e+04 61 < 1 0.4 -blend 75 83 521 -3.081214985e+01 41 < 1 0.1 -bnl1 644 1175 6129 +1.977629562e+03 581 < 1 1.4 -bnl2 2325 3489 16124 +1.811236540e+03 1730 1 3.7 -boeing1 351 384 3865 -3.352135675e+02 419 < 1 0.7 -boeing2 167 143 1339 -3.150187280e+02 161 < 1 0.3 -bore3d 234 315 1525 +1.373080394e+03 38 < 1 0.3 -brandy 221 249 2150 +1.518509896e+03 191 < 1 0.5 -capri 272 353 1786 +2.690012914e+03 203 < 1 0.4 -cycle 1904 2857 21322 -5.226393025e+00 953 < 1 3.5 -czprob 930 3523 14173 +2.185196699e+06 754 < 1 2.6 -d2q06c 2172 5167 35674 +1.227842108e+05 5368 7 6.2 -d6cube 416 6184 43888 +3.154916667e+02 6596 6 6.0 -degen2 445 534 4449 -1.435178000e+03 506 < 1 1.0 -degen3 1504 1818 26230 -9.872940000e+02 2205 2 4.1 -dfl001 6072 12230 41873 +1.126639605e+07 39863 117 11.0 -e226 224 282 2767 -2.586492907e+01 206 < 1 0.5 -etamacro 401 688 2489 -7.557152333e+02 444 < 1 0.7 -fffff800 525 854 6235 +5.556795648e+05 167 < 1 1.0 -finnis 498 614 2714 +1.727910656e+05 338 < 1 0.6 -fit1d 25 1026 14430 -9.146378092e+03 488 < 1 1.7 -fit1p 628 1677 10894 +9.146378092e+03 1379 < 1 1.9 -fit2d 26 10500 138018 -6.846429329e+04 5751 16 15.8 -fit2p 3001 13525 60784 +6.846429329e+04 11960 17 11.3 -forplan 162 421 4916 -6.642189613e+02 170 < 1 0.7 -ganges 1310 1681 7021 -1.095857361e+05 724 < 1 1.9 -gfrd-pnc 617 1092 3467 +6.902236000e+06 416 < 1 1.0 -greenbea 2393 5405 31499 -7.255524813e+07 3012 3 5.8 -greenbeb 2393 5405 31499 -4.302260261e+06 2153 2 5.8 -grow15 301 645 5665 -1.068709413e+08 358 < 1 1.1 -grow22 441 946 8318 -1.608343365e+08 606 < 1 1.6 -grow7 141 301 2633 -4.778781181e+07 159 < 1 0.5 -israel 175 142 2358 -8.966448219e+05 123 < 1 0.4 -kb2 44 41 291 -1.749900130e+03 38 < 1 0.1 -lotfi 154 308 1086 -2.526470606e+01 104 < 1 0.3 -maros 847 1443 10006 -5.806374370e+04 703 < 1 1.8 -maros-r7 3137 9408 151120 +1.497185166e+06 2340 5 16.7 -modszk1 688 1620 4158 +3.206197291e+02 705 < 1 1.4 -nesm 663 2923 13988 +1.407603649e+07 2240 1 2.4 -perold 626 1376 6026 -9.380755278e+03 1103 < 1 1.5 -pilot 1442 3652 43220 -5.574831533e+02 5726 11 7.8 -pilot-ja 941 1988 14706 -6.113136466e+03 1697 1 2.5 -pilot-we 723 2789 9218 -2.720107533e+06 1382 1 2.3 -pilot4 411 1000 5145 -2.581139259e+03 532 < 1 1.3 -pilot87 2031 4883 73804 +3.017103744e+02 7573 28 12.2 -pilotnov 976 2172 13129 -4.497276188e+03 988 1 2.5 -recipe 92 180 752 -2.666160000e+02 17 < 1 0.2 -sc105 106 103 281 -5.220206121e+01 51 < 1 0.2 -sc205 206 203 552 -5.220206121e+01 124 < 1 0.3 -sc50a 51 48 131 -6.457507706e+01 25 < 1 0.1 -sc50b 51 48 119 -7.000000000e+01 30 < 1 0.1 -scagr25 472 500 2029 -1.475343306e+07 352 < 1 0.7 -scagr7 130 140 553 -2.331389824e+06 94 < 1 0.2 -scfxm1 331 457 2612 +1.841675903e+04 281 < 1 0.6 -scfxm2 661 914 5229 +3.666026156e+04 587 < 1 1.1 -scfxm3 991 1371 7846 +5.490125455e+04 881 < 1 1.7 -scorpion 389 358 1708 +1.878124823e+03 146 < 1 0.4 -scrs8 491 1169 4029 +9.042969538e+02 545 < 1 1.1 -scsd1 78 760 3148 +8.666666674e+00 91 < 1 0.6 -scsd6 148 1350 5666 +5.050000008e+01 182 < 1 1.0 -scsd8 398 2750 11334 +9.049999999e+02 397 < 1 2.1 -sctap1 301 480 2052 +1.412250000e+03 196 < 1 0.5 -sctap2 1091 1880 8124 +1.724807143e+03 425 < 1 1.7 -sctap3 1481 2480 10734 +1.424000000e+03 729 < 1 2.4 -seba 516 1028 4874 +1.571160000e+04 883 < 1 1.0 -share1b 118 225 1182 -7.658931858e+04 167 < 1 0.3 -share2b 97 79 730 -4.157322407e+02 87 < 1 0.2 -shell 537 1775 4900 +1.208825346e+09 467 < 1 1.2 -ship04l 403 2118 8450 +1.793324538e+06 373 < 1 1.5 -ship04s 403 1458 5810 +1.798714700e+06 262 < 1 1.0 -ship08l 779 4283 17085 +1.909055211e+06 516 < 1 2.9 -ship08s 779 2387 9501 +1.920098211e+06 274 < 1 1.7 -ship12l 1152 5427 21597 +1.470187919e+06 686 < 1 3.7 -ship12s 1152 2763 10941 +1.489236134e+06 383 < 1 2.0 -sierra 1228 2036 9252 +1.539436218e+07 857 < 1 2.1 -stair 357 467 3857 -2.512669512e+02 399 < 1 1.0 -standata 360 1075 3038 +1.257699500e+03 140 < 1 0.7 -standgub 362 1184 3147 +1.257699500e+03 140 < 1 0.8 -standmps 468 1075 3686 +1.406017500e+03 299 < 1 0.9 -stocfor1 118 111 474 -4.113197622e+04 24 < 1 0.2 -stocfor2 2158 2031 9492 -3.902440854e+04 499 < 1 2.6 -stocfor3 16676 15695 74004 -3.997678394e+04 4456 11 19.7 -truss 1001 8806 36642 +4.588158472e+05 4744 4 6.5 -tuff 334 587 4523 +2.921477651e-01 61 < 1 0.8 -vtp-base 199 203 914 +1.298314625e+05 69 < 1 0.2 -wood1p 245 2594 70216 +1.442902412e+00 326 < 1 7.1 -woodw 1099 8405 37478 +1.304476333e+00 1093 < 1 6.0 diff --git a/resources/3rdparty/glpk-4.53/doc/notes/dfeas.pdf b/resources/3rdparty/glpk-4.53/doc/notes/dfeas.pdf deleted file mode 100644 index 35f5d3aa5c71ec885b00186fc93c3c608bc6b9d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63866 zcma%iV~{S*vh~=uvB$Q}J+^Jzwyiz3ZQHhO&mP;~yyx66;@-IT$NBSgKGm6PRb^#F zR%UmT$O((mFwn9Hf(@7cI zm^zseFtBnk@$y1BIyo5YTSK|6H>pd;qOc)!pQy5zJdke;AGP=kixack39ShgO2P3X z2@eMF3kbYEmeo(#JV%*&fQ6|PST|id@N`r99-&=>Km_{|1fUU;-|owNI8j~kfB_0v z*zG^bA|^?xOy(vq3v7OUT{N;GJPo^lly%+ueLvc;>e&rye3;_}GoCxUo8op?@bRUL zx&Ml|H!1mSq$Ze)8L7(qZVWEQEDwV!M-HDM{Oi-<{VOVYIZ{1Ps`q?dRxZ}1rlLMv z8J}_M#!A~cdxD^Aa{Qe!uEkNk$}_eJU~$a2L^O^tY>m8(g{mxR@bixGW`anZfUe_L zJPHxGk#o5bQGgU7IMrO>pJB8ziL|~eM~Hc{2l=GF=F2tc;=x~yYH^e{^AaK+`OnLL ze@P{fXaY9o%_Q^%JZMbnNT$@Ats=T0t>s6aDrrkJ2f@J~t{7mvqrbEXyNc4yD$Eq% z1Xns|#6LDSB0?`4i-g8`#%2KsH%S!M3-aZD#eC)}*KIL2HsnVML0LQU<_(ZDPRI!& zWD2P#7gS?lfv$720MDHcHCb0!nM5}kpgi(3_lB^5EUsa;Kd&+FsEgLs`W6xv86tlz`w!lQr) zftE(?ba^n%Gf0SW9|+*(1STUs4@u1%AK>%F2!oqnhTNu)R|^4=Wu27m8j zqz?*jN%{4?Hqu9{Ar1^a>N;QP=UeDCoh+-!TbZO9((>hU$S(qZvxXx!ucP6<%6>9x znB|;x$eiRw`nl`%_WDN`egQrUL-nkLZGldOvw!3w0vBhoVK@DYEb|(DXNoho)0}v0 zY&VvKM(swJ--N)N`D96tiU?Li!xW|p#_5>N*R;5}xEkYBBJ%XKyx>*I8CShLNTFuN zH58`5bnu8s6?TBS7B90Kuh805bNOUm(dB;R;?72Y>KCqk8)sRKiDWSLi~AG*U$@~X z=c`Hgz*3G-H|ZivZATBblXArnTd;{+;aTibRfRTC*5S;6XtI4f;_}ewTU@IztiQ%B z`p88tma9f@E=a8IjiJ)30nyLcwYR9O+xY#(a$_-2rXJ@hz-DWCh|8$rnUYfxgblTz zSW^1%PH-;zUXsYnl+!BfP=RzKJe#SWV!TRGF!t61%ED{L_$rnhM`ogGqIm@mE>k?? zOjA({4DJv-GcHAh6^`N-8;Z_pu!b`ysV3f;I&4K`?Wk~!CQ^)+;J7Xf(q4IYfwaeZ z!{M~Wqc{%umyVk5EPLR=rQ+MvyJGbZZ#_6g-35h3Pn;pjSNPeVyeSQgCmBQ({-flm z2#(c$#B(Mv7fFBC@r?S<%{m++w+J!<7WW!55?hPSavPOWWiV*jcQRX{U+3-##lu(2 zg%#!)9#bdX6AUtgB*i5n=F?$QJQ#P{Hdi@)Dm9Z&&Uv_zR)c4W;Py==Icz^F~2IiF5ut2idMd*%ge8=04dJVFUJ;c|~i3z)9PSnM?4>tpOxLVfbM&pAf`#Jzg@PVvgJPyoFVU{ok z`_SjiZ6@#>mc3Pe)=skAfc_A0D;lair=dBL%oqj9w;tBub_ab9c# z;BqEh&SiP6xJ|<&r!N0)tcu)NoTF<49C)V6+|(}1n{A8RwJpMyC0DZjy2E^R3DI7z zt#))wEThc?`Unjmvey4#*6sOp?p!51Dx%5EO)5xZ3xA#6^$AF3@%lBC!S|JX&F94z zhM(Ve9@yQPa$1`10;JphO0d)I%YhV3Ze=7NGoJsLH2km!;m21)uaV>Ph%cEbZ3ty- zWAtBn>PPw~voSLNCn=7Jo{90lr?@Fiaa)oW#Ge$`DC^UI>fB1F;w9#H7`H*tF2Z3X z;D?b0z&kWr18+&R_F2Bem;g9{A+G(APK_3+j30S*;l*OVEP%Ht!bAG{`^WJL z#62P7bboz&;~>kTc=&t{n&UV9Ztp0@9D@2bY~{9H3Mb8E@+F*FQ55G-C< z(<|425W3loR23~Wx3fQ3&7ws_Zz#XNYNmR~3dB_?e;~L8sd5SjKo<>_h;i(TO`ablEEZZ9qinEju{92R=l zBjH455U5SXf~KhHPjz5JRYaAfxgU+dqGf6--M5AinMKM8#kU5am>8@;Gld^wRg25_ zykuIr-SCnj75fTIAkb|4zqQMwc3dD>oeGxKK=?qQGASoyeVb6 zDEQSTma>E~{t&qBDP0R={@`;n#h)hE{Y(sbSdfd_@MnpNSB*{q{Rrc+P|N5RMy}#G z8dc}C;fAfoGBD+^{y-(>O$RZC>>^AkI1`9}uhPQGva+F^spsL`%t< zyAD!jjRGvpt}A~p@u-_Zgrhz~$PZ>xGCqZ$E<1RP+{X(2ddvdoMQQR>#;!3mB50Ck zm}A-F7{``}Di7$x*9O81(WSpLMI_rzlLiB9gT>9S2k?A&7p?>DT10E6rm^q zix-hHBoB#DV~6bh>7i2I_GYYL;GVI3m0WHfS2p1BDp_ zA!;QWm<|Ab&_@>qo`MCQy~Y&q>m1vV?4g^_o5g31>ulrSkiIb1tv`~NH~Rc z<$Q=z2xV_xvrv;?Pq;3i8W;dC#d}7~HST;3v&%qZk4wQzpg=L+T{Acr`~%O_naw*z zVtIx*EHGQns2x2wlsWrR^1?RHUi%=MRmqRMTUs}RKYr#0sFPQ_JYLrqn_Db&gWmbeFaw#G5Q~lV$ zUm@0U54DEmhf(x2Rf@vq*yzMDLVJe&I~+~1q|@iD{nz29ZppeQiw+qC3=Y!vP&Zm+2rV3t2B|2Jkf~4 zfJM!5d30o+D~tQt=Up5h7h+;2&C$TdTM?MZibA%Mrxhx*^8tnF zv2aJ%`}P$f=vcJJhHv;rQxWuwJV|!H)abGEuM6VXL&6g64l@b~aD@7hp&p@Gjb3TT z4oUZP((GMTdq-8!zUyKI9+&2EhUvub^3XH8MtIIi>)69O&)br~z)ajkx$BGjOYy}C z@ei*Kc|IhTe!m>KJzNUaN%|Ul$gyao_~&CMEsDrJ^@yh5;8|CnT6jX&S4zv1pcI7V znZ0!zo)e~{EL9J5f9XNIpD`-a2Vl|GZhb8jB8ybbY{-U1w4q)YYfpx*ULR10QJOoL zrih5$I)?fs^#5WPSws(cajbSzdZV<$o`wPAP81%@b>H0qRx~qBqfq1M$ZP5QeC<=M zRyC`Q`?afYPr9kH^vW)^Z}rUOcZAMkS8b*Ee*T6R`|SM4f3Rz&sUM&zbFH0x4w~IL zUnhmc-lu)gTvEm6;_Vr2dO=OP^E4c*W$tNMbf8-4)ZIL9VUTwBvZIsa zKOM|>7$yhO(I&s39OALS{B=xv^K2CmQ7o>?=AR{f-)k%}Pp8-@t>+jd1)_@x@fv$x zwb%x#@d5$szPil+!ojVz+Iv;x$dYiuEAumTe@kOU$b?@IbkrUWzrkpl@ zbkeMSdhqjuqv!%En#usc09gJ?@#=;>TG=DY5MHprx28Bj(?yUurl~4^_g#68nA*?s zEz3SKBt^Yvl`cf_dJ!9wgJ%4+)KF#n(8n;}sd97M zrOUZO^cP-pEtLDdEG_0sreV^Frnc>I2eZ%YqvDtk0lrw0_73*m>~KEr_Zq`}n*#Io zO1bPur7{Sw>qy;g5xeOQc-WqxU=P3Kl$^wPln>DvP>$BFtb}PXE6STLH-{U0CW0(4 zp6^%HZ}4EA=7|5JI{42TU>po=|Ghdm(&)0KWS`IzG34UEjmymylK4&T zMgUc)I(sxT!t~^J$#cD};~)=(lI1WK!*h_fp*e0DJ1!}pc2%-eejWaKP4#8@bOYf-YY^VaJoq#g zg0!E7Cu1(6@>vHV3!25BuX?1q6mp}lm z-v(sVd|#;#wlEjCccGP<)KNRP>hF9b_z10=#YgjKj(cbpo{+h7{;G(IYjPbhZ6G0n z0`zKq;VLgCx&fn|2u)Jx0%C{_EP^51YRf6c$pjJrL!XeVqNF{+hfHS`Cb4?lLXR;I zN-UZjJvftSzPHT^=G)PT*#!>+5XY?UH5n#V3~;%q5U6N>x#3&@=LUvL0j=`m zG7)&Ah{boVvgyFAuv|S8pyKV`Y<8g=Qc`1!vmdj|v-u<4B;LYs{ zPLzmqY%i~g)Zp|^DdmIuB(Xw0aZUG{ZBu-V0Mdq=In`nHv~U51LOs!Q5SAYbHepQ|DepEB(crNhfBr;=5(QSEX7nbc#D>8Ea^~6OihR6u<*sZ$TQtCpTHt z5Khi)_|ml03*1r?dX9axM3D05zP?2hze9ch@Vq{vIGh8*O8XQ`ODfePXqb7j}lZ> z!8|?jLDXArEBXTXi5q2>WhkP-I1q<;qB$iGMY7;QzUjQ`5l9vC0E$pGSdDN|j59)4 z0KoDatC&xhSb}P|D7=1znO?9P?=@RJeV)#j8@`oT7=u?NCZfT$ztOpueq!X^$lcL1 zS(jrJ6}mKfzGTbT1#W2-$Ng|wddqRNprY5F{H7v5phLDlQ9=#oR$@?d7-!E%ltbtF zX^Z6v=Z|o$p`;D^-+8MeKY2r0NL&`V*1$()u@gM9fv;22>S;W-g-sP_+^33*B-N)) z+LHB-HtlN`suwv?5{|6F3I$^^AUevw+EAG88oki~b)P&q=-KQA`YUfl~d1|o3-J!#oE=p5+`ZqkT!@4ab*vVmJf7oTl7}{`q1?0|ZRggdM zHAPW$SkYau+buEQ>~P#mE*SghsJ*=!2f!HziEq>2=XN`>(Y{-)oQY9V=-HE&vpPu% zNK2Y4nHgrOwo2%`wWbBYms54jWadgy{uYhXerc$Ah3E`^6 zAV`BJ3oR=AI_`*+DBF04=$I#50d7QRRO)=?5$KSXSHyrm`WnO7W13zVONv6gy+S`~f+C68%|OF| z9|7dyvvx!?C6oe;AJOV<5YHdw2+CHGNeF#h<3FTsj5q<;sg`EGIdo#RwluVEJglhf z7pKu0HL8C!-*|E2uJ>GkhtXs= z{cZ-%8t9$|ciWo#_6TDXoMsHg+r)8Kq_cqA!GV=WYqnjmdaR{UPQV$XBorres0Dm4a$Pt{~%L(b9If@>Y8D%F$$%{1gfi<8^^ zILiq^{C$9-@Hx{c8y09io8`SsqaY7^ZJCxyA+y%QPAcD7|EPhRSQPXq;&rS}N{Nkr zOZ9cp`dedzVj@M1!OyCs?j+J7u6opzq}R!obI@ki;8BUfh5PrV7FS_&8*5m}v03?~ zb;6q{Auu&+!MYv()6@`Tr(6MYW50UlC^Z>I7o)-L6qtKPf{R+_eN@0eN&>P+JHC$rt!HXN9Or>21(%45Y6Sp^zEf`)T$-}(19v>2#*rX z%kXp_DWw*x{H41RMrKK9AmoHQT!oQmq-!05mB#7&duj=`n0ns&BKk;~tiU7xT5(EYvSaH zDV}=$$I-4EG2uWWfQRrLe);kyldN6gNzY6sP*Og!))eV()OS;t?c6OGpeueiNIFPL zn7qE19F-V9lF)stXF^v*PYi*nMQigq3wp~Kzdqlk91YxEZrp7=qb1iTpQg0KVHhBqM}_3W#zzw$4MLGKmg{rjU0DE^I?Pc%Wa<^2~zj~f@~)>1*g!4jGU70RacSjataF=yoihWC6^ zI5t7;(^ghFSS2%TcM1ZV9d?n> zYe;5xBdC=K$_oM2*_cS;6}{_&z|4-IYIOV4eIqjfBRdsn^}lb{QG)w?MT;=8)S{vU z*@49Byu@Dl#py2~w@WOk1&aID00uW0Xn zkI!;fN{h%c^hc@sHCwlV8t;eoU2K!MqU2`?Aq-pi!W{v{4PZaOtP3UpD0Y%Wotq5X zOQknFEi?R_E-<&3$uZin6&nOpCV*4Ez!coB9E+!;c|eYo9j0Fi$=V`opF zNli{7`xx*&flNwL+XB$P{7FTkr^5C4T2-z#{;_>?`A~XTjKHik*u{L z@(;Ku#l-pDqu;Uo)F~TKvGmf}#603kqE0H1t-ah6PuGyTyrQ5jOC`RahgmEXLX)s8 zWmqyhVM2slB&su&gB77C0TVf6N;E%98+=+c^mre+>;kPQhcdq|(USyd=|uGrm)Rc< z{1!ag+d4wCBG=)K<-ebH$%T6Q;$by2=qU*{;@Gp$Q+dD1h6-GlCnbM7Sq?|vS(F!O z`+Q?sRInI42m5s+s0%Ee6E>cdixmn7>I?YHc>%wyA;NzGe+rvH-b^{<=UP~%KY11% zBOBU-|8{$5FgwKEYtC8)R(u@BIP`{8J|qnv!A|cCmnFR$!`2tAsn3#5l=oZWqxg9^Os2nd z<1}Z3GiRw|AZlXCo26`82U;_i%_(eNqQsLp1e;IC4f;h~FAM-TZcyj8s^M=f<&kN1 zeb_2I@Q9?bF@BxUkiNW@+-I|s?%d%?RR@(p=C~{w_NEYNN?)a0Wlc58a}!<>Bk%EnOAEz9jdSw(-c=qp*d z8H-8Yu@LFT_9>CU4Q@=bDaW#P)ST?d@7Y+hVoBCf|4nh5L`QzZrlo^%1;IZ(&Ej<; z^{_0ai6cgsZ`xdylAx=a`RA8F}#qec5wF-U9bTo>m8gliFZ>4tJPa=k7 zf=ynpn^IZWPtW5*ExmkAqhI>5e3vbQ)pXPj3i26o8eRB%@~SZLRo7KZ zarg<&Gzo*7uVWH)ON7M)9qQf8+@^*bXw7L$ctt ziXN`Jb`sThq^1sACvV3;>?L@$DQ>p@wLz%6Aix4ie>x!Vh=wF1ezWsyD~;!B+OG3u zT#bSE!sB`=uj+Q-e!EP&+Hj@G zMSXw;CJ#U4xGT=x@=HGr=X5M?3JafOkpTo^Cr9PYEAxvORC8{Kg`& z7eBoe=S{T_SbrspK{$Id&ZZNE#DSZK?l7tE@B|Uf9KFQ2^Z;g)zG+%R+RNYysWR*> zZi=j&Ah^XnA%#VO9!21x6mm-AyuEUXIrT;cS43um=dBg5io}ECz2PF(Ls(-^0P!TN z07ZPtRV;q?oEJYpmdWJZE2Nc@A}Sye=MY#v%d*=S7zqR>f88+TNsHl)@3++L53?D4M%xxqcp!J**)9pbiWZacHn=b#d?s% z@sWMpRD1&+Kbyh-AE!8`|Kt?M#L7(n-y1Pgnq&1wY=~R;s6!D~z0Nd6CfL8|LAvzz zY6ErBO!^S0Av$lyzr2zHL(0c1%U1#kIkzudWwYo1D6}gak7<_R%X}Ta@%d8PQ4VE& z-F}{hE+A^~e7fDu;o`}d=Irl%oV`OnT+GXSb9}x&T%JAK%I5Uk-Y&)@51d{0kW#oR z@OFKk=;|D;_7LkYk9K{zkNsmg7`=^AU`b0F^T3BMU>sjzL+ z2R6lDmlwLm(pzu_65Z*29q2RCUob6l{0e(@y2=5{|8QF9^5Um&SLHkyQH1>+ROPww z$Mc!=eSH0l27k%2V68)aWA6L3(9P}Xf$OATUR~FQ^ZhlWzDcRJCGmD+#gzQ$k0N*C zIABu^dYihOjcCKouE}=m8t*`!Z-0yRBkbKIW_ukccATJ%E6*8KIuG;I| z9rO_X7jjj%Pf6pI6YZl|mwaqb`~yvV?b0S6U5*z(a!DFUF>dAQp3`8n|2r_FsjCP5 zGs%uk4uZX#E9AAKu|p5hC9(cAdzQJ7d>*;_8#j2f~Or5Vi;BUwfzKTt#A|VpQ zgdkT?1IT5m8S4+oC(IrIMX{qvBu>3`0j)*$(&Dky?A{>vU7Wbv{}+kKd+ zAqL1t8}Q&Z-YNiix+3^I5a|CDSdJ990{j?l&21yPE~~QT`S3|vH^9QgJ8qukrEd#P zFz$&vRPh5JtE%O7ci`$^+j7|GDrC2HhQ~*>$WnlKdqis8>^(Y)*6PDk|NZG93?atHGhF=^RT$=4}^aeiX)OY zAXZj%QaB+tT5c`XBZ(cU=mV&klitNC)TCvw78Z6QdhHeL*vgAGOD1y=f^ArfZ9TD9;SR~1c;spND&$^i5g`Wk;L?Hy>qT2~Q{|&KmE}+r}gu(@N8+|nE z4{@)GgWecF4bNGD!b}usjF9Ed!GRVlQ%REr-r-)@4SgJ8l{J1ITd5y2tToP6gyAN^WS>aOe)r^=(+oF@PC0_vu0Wueu*_+5EUlT{*~kJdOV z7ouyx_O%=X`3nT(%1mmL_GDL5kct8g2_aA5`k9?{sM((&6EGGDK@YH|Q}c>j5UM~d z)WS3YSWMlSTv5<)q~b>9I1qYDu_XGVssLg?d4c>O^BMxkT-7*o({)NQ2WzD`a^rO> zF(3?7;>O}CzrhvJPl)I~TTo)aC@3Ti?^Viw-J0ZH*AYPKEhUg2Z&dv^Ak!u4zjX?B zBz|;Qh#RLpOf>xDg#<6O0NepZVIdo0+gE;cEyR+{E?Itbv5-hKJYmHF3POa#Rkkd| zfKFKo)7-=#g=acMQN!meyCQxjD3Z@yVWa$`O^KudZS`M*;&%BDg);H@c=InL-HRVC z0Sy-7HdYHUGiU1xLP)*EIC82;&3|M2Pv{8!OqEbxqxrw+)0(P6i2Zbg1P#L~LWoy> zrdH)s^KYwY$$wih-?z&P&;R`V@K^tTTF2G@qCHqw5&41qmB;e;XGVBR@wA4kWFl*k z7-;!oXhaf!`6*QjYZv~NA#CG;<{D5bsN031gk@C<`5ziZptyK09%{|2gyEByC7f0p zRq_LinvlE`HNveas?406ku?#+mJ~F@v)P*doUZ){c&tA{pMoavptJ=^bx|W2MCK7( z8R}Y|ngZ3_0cjHwkH(LXGB05yWF~TsU@vYa!e}IEM#5<&NHy1oq!F)kUfei;s3K`W z;;~w|+%(TzhI&RsOm66*)pV$mA1ZA_!l~v!HLtjKxXfajzA53h?LPacNQ=(epA4xZ5TSBNNWLLtd2eNvw`9X#G z4w=k@>Xkyx!_tprCi&Mx9Ca7!nNT*aj=$Aul^Crvvers1%Mj{Wn{@;gY>|2d)f`(N z3xDmRO5yxCRtaPDx@HNZM#0Xa3RY9gqDmuJPgxbSjcr+#8EDVXSSZ_~3bV)0*t;Bm z+K0A9k-eIPCBTe+EP2&pl?nMj1c@4Dx=ZsK@!9vqO~1B`B`rlfA~KdE_#=~-BbFgD zmL-G$f5t3V3stZpiyHIiQlu@4x=|%9M5s{fLlz~xBa;`gddKRiM)bgK#j3i)c;(bS=ynJ;LRStc(=49BsR{dr5KDMPL5L=gGGasLPB=upT)gaA#_ z0=8RRM4(XR9G5#mL&)wIN@wVz$LAd)b9y*G!{l$T*U|2iqj#u{4Zh{~-|O$lcu+P^ zSH^;8f#{9royzSG@m62NCvqk4!d=j1-$uTjyrH|gps(NBH)q;mFTmG=6rbN;i2!Hg z?B%)xZg(s>6Z*5zKoc1?PIFw__lwZBw;H$deXa63Cr}JeePB2rcH&pr5i(kcgN`q* zu8L?oBApF`w*pjJW)Nw|&z3Q3$z(`+Ixb00eU81-s*pE3qWN82Xl@l-XEJh3?@>Ml2 zT+G8pJ;&>2Y-rAI=#`^up$SzaZT0{AjQUijPVwmZE>Bb%xxIhCQa>t14gh$`(_37$6FyTGZ$ z6;07s_B?niCw3?8I_YfOt=WXKzlM#S?)V&@?fyogQ0tdtb+^LsR!*P~s|SD6P2U(B zehT=;t16pMJX=es?zY)X!GM#E0$%fN^qi=V0JiSMyI>3N&ai7l!_5VCBE4+!63A=B zc7aE0Qz2PPvi17Y(l8*jkLSU+ktsxLRJAKu3!lfiXW4D52lq8-^3!4VktMeySuK{w z0}8s7;Ma)k?b7)5v$pJQip8KBW7Ssb?;eu!yj9ce8~U&OQGl1IlAZ}cgQ@MUDmt@SCc9^X z_JbK)CtuN}oT-}<=b(gnBeK{BsDYvix`I^U`sGU*_cj^N;%hv1Gna!SxHpZg4WAh@ z9FQBYnJe4LM;~2MA?^ApT-jld%Q93=I+^ea21iz1e3*{G=j^!aMcgW0CVVQ6FZO$V zXJe#pIpB%;K;(~v>>$n>?$WW3G$Xwa8;L$nV0>Mfm;&YoNsjq_QzlnBpcD7%u{2S4 zD>P%j`dxb${cPDO4vwRJV;O2I>z=|CS3ZIXx>6)+b)mz|6*--F0>D3ThTSo@`COhl zm(4*sU~>IFwH5s$YawUH2s66@Ug+48)r^wacV6f4TMYLzw1m4mDF#98KBoYT=_ek@ z@-hBTKxYPT!FKcC~tbQW=G!5HU57?FtN!E{iE4KXNzE`2<+O%=0m4v$3rWb ze9ra)lhs2ajf<(v)Ixw7IjC+EL99iCjURo(xGNi~!b4P~b#MBOe7Sq#T*|_9HIA;U zhcusSz`sc@j_(p@s^=8cQtm|<*+ZAO|4L%j7<#=&egowpR~7sp)hGLZQhhQqvaQh5J7MBg~=Otk!n`=VtdNd1cvR-z3F9Wk3 zToBQM4Q0xN{a?55g?lRkut?u!eHVS699}Q%UhnLkZoq*+`n|BR-h=5{fA5+4u%=o;f3v|wVaWp z@rmb}yTKEE$WVEs<3y5DqQyQo-j^XP?-G6azUa+}GOxOa^-bUosFd2p_dllycM4Jqj8f^MT}HRW+L|-IvTs<+f6^ z)lSlnvrW{FV=d~%EuSn@FGZf0@+zLNyiKq9%KNGrRspdpg2$V`T0UuRC!Pnb*{-Q|+;B|!%y@ET z(!cXuSif^r`AlhCK2?ScTOc8N7IdaxekG)(GMd9ux%hruf48QA=9O~m9zUy1nPuXM z#sNjR*Ro7i7)Ojuc>eD#@Usps zS6jXxh+=}SeMJXy40CbU=6ll*Vj!EL&{Veb`B)^-HxWm!>OKg-6Y3jN_shtwEC`QL~N~ zO-lV~GvD=OFNHDN-+x+{v=2#A*yoB41d;tQv=MN4x1|$Twg@RwFlUJ+FJGgVCm;JKoHc?6DLOejar=Nwi8K(N5^8 zsJ>i4!8{!MhZrTDnk0$k7!9^UHFV5CrU{`b&l-YFK*|uwII%{nr0N{0qbUQrg={&5 zY(P4rDH~E;m?_Az8bn$^o;Eu)F{A)JB4aHL>p-PXdHgiMNgstgAXA7UQlR`gm3|8X z4h!hwk$%deakgd1wb1lWB?c>|%&||Ffh;Nu6|zG~`f%0}vG6$XssTMOC;og@X6FIQ z!tbMV0gE!LOc=Ybf);!kS6@V>Fj!zjckn^z$mX0i#z4P>KX_EiOsR!6T%zw@--2Wa zoYX>t9HhHG8KC5wlvJkSh=}^BQKB|;X7s3R${XhOYYeQO9+_B<+Lc*BQEozx(OJQ< z5h1JWk3W|-Gs&zlzq=}Cx`Y;Hjcl#yr|KHsT2%3@B$hongJm4Oqz6>Al_tGx_fPLV ztezxZl%qt~*}~HLw`s)%Zqc><@P@JGP$L%`c^%_60Og=&j8XU;Ncu^VZgo9=Md5b z?~AIz6qKEY&+P6&`0M zHw*0sL}#q%laHpYAjO|VOwPz|14f*C1Wo`!zb_m|7x$CX<-OR6IH3VZ=){Anwrkjc zTQAs9Y+*EBO24AT3<7eRKVv#S`ANikQ&K+*p})uDeHZhu=3!1sf2u(h&yZsgT0%xD zl=uOw_yUuFtl{&%xJ%8S>LO`vwcmh!aG-~!PqA|RIv_kvl_5fY42Z<_d9;nq6^o!< zP00Bb5Ruiev#O|2MqZ_P+0Lf9bpX`6r;A?mn|?{>4@klvU4(oymmp& zLhDR;Axi8He|)j#1_j5b`Oo-&Hwv!yv929m-%gZ=lpwm8GFKwF?7cGA24zXWo+i{f zx+K;XAX*>4XHC-S;*5QicLkpuL8d$=HeF206_I=CWG|0$xtK5gKHDrg!hiZYc0?ZD zz{(D!=dIpjspxaY+^+RINz;=j!iA1p5!P4_X^^b2Y}M2T{=3;pxr2gLo*>lxA@hol zmERVpN$mJ&qBuc!l=ny10u?cbJ2CXn9nBGATj57fsyW=P)$`<5J+;GHNV4w)=ygW_ zvT$gO~I^DhJ6{5qkFTP_=%>o~lW2$M;0>qNaQ^S;XUuSO>b^Es?RRrs~T6CgJ1i<>vHe zH1ctXIB5>dY#d#~e$BN;d;+g&o3}6f7iR>pjPGyR7B`k^BbS#jHL~M{=eOOIy^%fb zw)cwuIP#DP}rFd8n2a%drio4i`*+i{R|*<73MyGAqy25PTk{q0b@GawVB0CpP8AcsNi2 z$It*h6?jnm;u%<2tBUe#b#WYPuniV@lEzhfa)D`*Ph!T;9I@ec*M-`A03YvnArdO@n}m^GIo;{ zru$j7wME^i>QqEt0wGtt8BpU;LC^90L9P&D7Kmb2^ZvS`gkl42xdphDk-P}hd z_meF1Py82$Pfynw3wrjT9vi_?$jzdLpH$79 z7Ffy4{GqONdxqV|HIgY$sK+@Sbm2jfwkU7TI|++$vOlIdqy)pX-PW!MBG_ilGx-bQ?kH(;EB z=~z(T7E*uQR?tyjgFY{jUJdOyfL;yZDF&gK1{kJaiwfq0>v%qms@P;zxz;P_ou4X>FZJ^pn&}C-NPn+eMIT0c$I~*g_AIRy@nYmK={al>;P{)Hd>Xh07o9`)Y7$GD~P2tntpx#a1hycuC4pBI?17wDqgxm<1W zbX9)m8*cncqlY^NAWPq%`#MCdHJ;0S!KUiw!}k#Ix4I z?O_A{A=Tqac%Ya0`dudXujP&kO*FL|ldyLU6&@snLT@TWLtNKA1{wp5ywq?c0 zuGCp3af?Dz(E4#ecfU|Gx0|=5ouTy}0iK7|U(!oSR|YVhqT0yypMoq3FbLH*c>vPG zyRX7}N}>5#@ELr2_Sp6N!nfgZ05Hz_2w2Gk-s9JNC^WJbCX>bdY=~+HT=byWnkjS- zJc7_ejt=urFNNsNxh`E8=y>v>u8p{V4bSa<=Mr5t0fSXXbJ~E+r?0?NdA(OQIExQ1Nd%xPJR3tPFk6ZKbr&PI~QYU?@F<|xR;V{l9jhFHJKhIG&>~5 zH3A9fQ^t~V+abxPKZl^v3apn8FX2Vlx>O(~J(GR){IVLA>AqwBlV(PU_1h*@JB+*nb!rhUXj9-j>CSCpOft#<(zM2(atAg>U(czVuE~q6>XN`fj zP|2agus$Acoq?9H4zPa=Gy(vxR^S*DE%%BtMbc%e<5xAhlpHT4FVc;AXA6R0M0UvQ z^|{3;@^V{GIjzCtQ^z!;*cXyu+B@)A9dl*RA10VI_{>}BwUS}i%&$;?Khj-2zj0^n z{)ph&IuFd$;pfp2V0Xdne+1f@7q=X3@Qs(bUY8Wfe8OO6eW&yo{^|zo^B;%3DGwGl zJkoUi`H-A{&dNecVsG6w>ps|?sgHAN9bl8M^%^|6*sa|%Q(*|a3n94a(Cz*}aE-^C z`!Dp#e{YI|_5Z+_s7oarvcPsfP&-JMlj&$SA074rm8*x3_|d)(+X4P(0Q4F3)00Ny z{&&J7EVq>Pl#46PMU|XlaZEyn)%Qs;sFI|M$B+K|J6o4K4!P-+&CA*IN1z_EEVXFD zzSGB5%G(?W4bI_=9)Wk@r&x}@29UK6He*h!SWL5gpmO%mEkB73-N+M#ufaE7fmW2{ zPzn>6DiZNL-#hBGP3`C>%NV)RYIgro2VIp2OGU3V27mkXc_?1Pz(|oA<`?n+4LfmJ z)2GLW4*)NH>jc3zpDR>?pT=&8x86TnrAz&z2~kby3)tKSWAXBEXuuxh`7%)1ds;TJ z!`?4yOU)-_T4jzhMoO%38%dbUbiN2$a%f^nCSbe}RZLi=1%V2IHFi{|p7;a`dDn;ls?KSS{Q) zFux{v%MBH%P-*Ets7&(vCEEgm^v~)NVO;ol%`$u_1h}sm8IvmuDcpihvk1V;P z4iSjt7J9gohTDa6o{xn9{5g4Nz@N*>#C8%nS=cWApu!-%Co*zgvpJ>Np)$q$0@(ch zT(Gzhkz!)~JY_ZGlPpvtFne}z5{dYR?)c3Byyn6K6kYBFW{%i`O`wW+y`^P+6~qx^ zPWnD7Is{_0N-F>SC0n3D<|Z_AP|~SOr3#%A@MjA%8{HFqD2gD_IGiOMrw;I{!oh7d zmeYjX7C`6{$>}LIL>0bAIt8B4TZFc?CE)x@-dWh{TG2~25CvMIrxg3qO@YO1M-WEP zoc_W*gTH!|mE#2)L<>*J3xu{x4cUABJaB1douN7{%YF}YaBVi9noU`Ze)szPt<-zpbFbd_Ao$*!fgslVJTuoZ8K zHSJe?Qyx`@Znfb{7S0w$g$KVBouakt!VBldJGy3aIe;l*B=3GHs9~#UI@Qv2-Z-~5%)_K#tg3^+6@kOd5aMwb zQh@W%|AH!%|(#J4=ODNphR!a)s;JY8g-hUFR~I9Js!5S zDwwU)M-Gp!&yoNK)9FheGeE`##psYY8Z3lG6(<-^>KwfcbB$v~cDRix*u74Rz{k^Y zZtG_sQ-3}LxWzSk1*XuB_OZTHawN7X3OeutD6hNZDNw}-!oyt|WG37GGIB`^lg7+l02-+oxv?f(JwOav7 zKxR8*46&fhmehpk*9N3R^rgdh7Ji3ICaeeNx1mN{GrHv!R1Oa!7~*)1Eb7?liE_+Q zH@r?1z{Z4`E#&tgecOxW@jrS_EGv`=ep6yIz0azW*xk%@lRMm z#4y1_E<)TDvcP6&hz27BN$Q`(zk@agi*Rmy?gYO&yr)NMJJjA=?d5?whsTkl6z{wE zCZbZ_7AW4jt`{)z)r78dMf&titc^M>B$pTP`o+An!wJ+YBfMlw;8}x zLID;WIQ*~1{@WF{Zn-u|KA4IlB8#LfsjeKOtH77>G8ro!^xt5rAPq48_wR?5^?%u8 zC1(RCcROQx<$oVWq5lU|>)&Mp%YVA%Ays!flohNMz;icPq|{|-Ioy(>371nkxKM80 zm_(is<8CT4awZvXsI@-GJ&}_}vX^H3(^d8L02fUy?FJBz7t1b5tQ{8QDnFqF2#a}o zGZqu6kmD?Q`{Zm=)Veeb^OY{1dC%L_^hfuLXU_|sRA_vH2&lm1TCIhQtj_enOx1R3 z2g$|U%c&UksxN#Q3y3GpJr;MM!h;MIa7DD``oo(boI zh$EDN$#5qD?KmK=;jTzAsJL$*(h1>`&)z(uGv8ore@H528!X0{l-~uIrU#}ToxHam z^i>0xC;1oDOJ$&^YX2YZz3i@k@c@~>gV$?eqyK6GMQ5S`ogUC$E~!wZnnZbWqMDRU zNqu5lsc2R9*^<(~HYO%~B9aqcGZh|o4M|*xWYRC#h@uJ%8LS5tU5n(>FTeqXu}8)e zm~xBclP^RffsB+-GKZ^>s4jXMUnr5OPSu^RmGNmDPI<)j#^jFuCqz~erfh*Z+;mfX zfF75Gr&U8Suq}Y%N_IXeIYat!xst-~L}q^?VgH~-RotR|F1xfXG8o;Gx>2!(6VzHd z;_o5!1bkXExMe=8k#UrDC^*IeCZlQt6n@&xQhQI1zse zkuvS3r0Ez|EzMJTR|MPM~F>KweI^pik2*I;LID8(iC%(sqR(Ops_}Sv8XZSp8dGzNU|@+g<^YWBQoaz3svY$K|eJ zJ=NTAEz++>7=X0hbHexQ&YECvmrlOwCD?)ZK@beqz^DBl#h5N`_GY@!N zdwfe-j$~HIG*aZ8Yl+JHYPu;U$+pM4=t8T7w^DJ*+=*5DNxR-R>}}aQaS{$Ywmuz& zqKNPoLJMDw0}(oqo5!Q4Pi;l*-NIZqtYJ+FLbSZBNPyPO2x3kucdKAs=~lLHEoDYs zgBpZph`6@nlFdf9=P_z7fqa;=JU~}Z7(b!`EQFh?KTH~EO9maX$q3@T6SV77;?3)W1ju3X$TrMrXYSgS)-bYKf zPzSG{+!cWmKB&H?8-|oNxhJkD+?1|>F?7XecKQfTrlJZ1?c@|>w~sgv^3F!Y`}?|- znGfO-wPiD8b%eiJ)YIw(ixcyo{(u&VE={2$yrY4%59Sc&HuUOkLpc5ujh*a0%bqs2 z*S4*bTL<3YA5lQHt+xVXEt`5sBI~BS*Nt}vo?*XtL@c(tx1~3d-0{OcEzdqdG^y0Z zTB7ZV_gLJ=aTh$L3R_-*(E&0qjV?8EKi+=2DK4VyF6 zg<_zEGLdjw7OeY?c&r4ojduP@#B%{H+b7|x8K(5s#`H~uPqJIz-V2t}nWK#d%i-Vr z%L~+Srd5@}qZr*nKf%4L)2_szLKa?*|1N|Uqtu1(b>nN%*S(zb-Cvp@7hfz_?ilqr z81FqV=PUp*a9wCt-vnpXBfKZvg@yg|oOgxlap9z(uBI`N;UDd5e=n7x@$+=a#*xUo z15u!Yp$b6Z?(A7qnFoF%@?_K$j+2Y^`FZVczXbG(FZ+cjJ3PknX+J@b411BuB@2a+K+HzD@+NN%)alXYyK76KM! z_-YxJ#>i-r%OcvPiozsJoX0-{A=lj&ET=m(lRY!@Y6g@oB-cMSu*Xa@vKn+fMwF3O z2l<5pn{4uQoIiiU4}m#vj`rHX{v{ zaLMqnTwOg~4W!8@|1nBYP*L;-1!|EXsy_#46jUyU&j?TvuMRC)28CwMQdr}4Kn8zu z;f)H9shC9755UQ>+FvoVDY6LD`y~EzirMOmM}ejNy52t*WL41sl`f#Gwxn1wQ3Ghx z39WF&`pmNG1wkrbz??mc6t$j9br5zz0^h#C<_lzw-hUi;^_%q@J)}hB8s_vEzRJLaA5)cCI#vNQd@lIy^ zX4>9`__M=(VDrcM#y?HxiFdxqlG@l>us<~ycYK5Tuj0j}=fT<9%{j*#A6@jy<`vG+ zLMItn?L95ywqFHlM)o%+-vz?mJLAJG&0743M4MLk({#YkFEms;yZ=Hg z{fAfo?~5f?2DbkcOU^3Z@=9vxGbp2;6phI&3$2C^7Oopr%}uXRP1mYOw29@kp(?^h zLh=kykbZ%PkbYiq3H0&&z=46Fzye@(xq=vjfbm7iG8^lnjsi*$deh zk-Z#QZrkH&+wDxxo14ssk1e6v{s9e80UBwktwv7HgP}&+GEKG0$SAlkO+2k}Xu1px zFGiYIWsdFe8k%T^&sfAemIx6mZ{o)8TQ{>Pz-VQq@nrq(8|E?!C}U2;Yuk}MPQ20! zE@CpZ1)lcW8yFb1fuY*ql)p-yquvpXdWQ-85LUESF9Sb2U(MND((B299hEYQKkB_q$3mN^*7FWnw|8(@+mVxnKH(k%3_hDCqfqwa9G!)BBT#NR{rDtd$A| z6P;iW>jTdrTQKZmx4-XycN=5W-^8mNYFkh{)87vo@*&6Uu)0tDkea6q+D+$?-#AP( z#Y0o%MY|38^voLd?-lQZ*b~EugViY$3uO|LbnPw@^)R-PB zL-VK%#Gw3iVxQ&@^Mb%BYQ~Dgy;jI1YE%z=J^UcmB6g}cQt2nbC8vfJqSzYSpOk z5IWEw?fzhh4$}cSKYX=5vGAnao@-{XRUITnOh`>g4T-s(w{y`d2MqTj=K9k#6I8`e z7_JznKN|@kg`P)X%3iD*8Wx!HVYYpa@zwOZqK0ccbDGdG%@TtXCr;TtKf`?FnD~$YgN_9lB7HetsV7j|KZeg`gj1MIJ@wsS@u5Y;U z^~4gHXHa|&5$d`((I}WyFs`wP*QESCmWKZ#+qI?&tAXRO#W z)X|!mp|`Br3!5@BopZyCgENV4$Di9M!>DNY8v(hD^@3UFqz4}A_jnEEbR+vK>dW|| zXO7M%u_YdX;){t%SmP6bR>|X!CR7o=`@!`=XTOV|F7qe}v_RPNamWkF z0y0#BF%)h|Hc07Ut`%9~J;TftS#qWE%Qraj!hc#`310-=nNl|GG>kpAt#rP&#W(; z(GSw93I7J%crZ@{vWOBzv-yATQuFJ}1Ct6?_v+Wn>+wniEY1FcQ=S#+URjtOaQ!Q^ z1FHP1hRm2t0)5)ujwwGo%F&;kw8Xd=vbdPJErX;x?TNRG4?$?#DR$^p4rf)7g1BCT}=W8Yrs~J8(kJzHP=_G>dXwu=lI$LMF!6e)x5EMe~ILf^5rExgUa zB#$wh9=3>K)3MI+_A4)_`q-RaQqvvdh=s#I^i+V0Lrv4%rkNFsLgq(FW`Q;XsL+{r z$Ys80o&e;cMQ6^3F5AhoX@IAalA>eFoNc|73;^O$o`MtCUcxR7&_#A`$aeBQ+WMMB zYkAmV7ChaXFvD9Y$1RszDVq(4ik2Za zcS^%KYw{I(Gb~t^0qb-DKl{|w3~_Ay_-t*}z2oDTS7ae~*x>O1V3z(GIaWX_{g51+%eKh)Jc@kI?3*SomqHgZJja0{k}z@^T^6zu4A8uQ z8}`7W2CdG|HXnwr*Q0vDI+~aOa!fV9#lQ`Aqd1>_pVm(zn#w8m)dLWn6a@-@;Jd2zN>i-$e6B<%Uf6-lP8%XB;`-#Fn z6Q94v&7a;KN>q<_L4T_cw7N9v@@(070ij;-tc+je2Yzhv3+Hk6B5mN=+%|a47K*jed?DFZdgyuyrz&mEpIl771rt&fOUUuK(EUkMK=7Yo+%NMjdxP55nn)YtHwOV5bs}I-rem5uX6|GQ$VmWNZ9zd zXJ3`|1Xn~D5H4pVl%uu~tC9|F8EqV%s$}7Zux*JT=i(~$Wul)Idox==ibYDt__&e7 z-StZZ#M=%(!Mn_f@K4ou&&!Sl&VEzYbF|E_qv1Nm`Vkd?q)?k+c|5)>#Wsbw{A-f7 zr0*U15QY@}`6V{@DkY5h8Hb4-Gxw<2Cq88lsc=mgE<{SN?kv$Q-ZdhN3hQ_#w4~fJ zg=Ixz_@&df-BMlB!smKAI&@}-8K|( zoAXux^GXe4NQ*8t5F__Zur0%P@L$M7&i{{I8Y|=f#-}$l($m-1Gcr1Kes*$tepq&S zhKp|e1+{wo{g9%s@#@HXfq)fEP#?*6nCdgi{DWv3=XpAGpA#aH?B^FJfGE!Nc?=P! z3&vl_CH`8C2tqw895>ut7B)m$CXzO^))q#J1r9#!0S+!Y{RWmKl6Hng3XMIM4jr7F ze9Q$c3J#tO9o@!XG#2I#-OWE##*fD@8!c$(<6vSTQRE*iBPt=`m(=a!?%t+jU{j~# zqtKpJ94+W>A`vVoZ((ntpkWd2uj!)`=C5mDQx3fP+e2@jldmNg^%Nd#=QD9JpC=b4 z4HGlfuUdO}b-H(QbTr@nOAKOX#&KuDm5KL_a_V#8$FuG9GH5FTJ;_CF;-_s?ReN1q zvA))`nP(^F$P(i-Hht!`YmedqVc-TiUkUKhPVVG5naycf?e)?*{GBd=UlCp+GW9d< z&Trtb(@B}|Q7n6zvHmB>(Bq<0t8IrWow>*Iar#UveuY+JO<}Nw?b5;^Vyf?8=gx&86~Sms;m@!3Su=w(acFL2GhB`RBn- zc7N}DZ*P07DZ%qZ3m>2G`0HC9^w$jY0QLX9sM!7^zx3bs9LyX{{~Ho|NzL6&$+(@b z#C+y0wu?x%ZJbkmQ9%G*1E8f&0|^;QlQf_IcWY&~m|8oYO`@SwW1~>Q6C;{hr^r@Cgz$+i&3;PW!2Gff3QA}Cr(di|;rZzD6Q!)mz)8Z!NWPjXPB-c+7{T8{; z!VFhXZVmn6kQBWz`(vFO#WG8_F0E-sZC!BX1g9;bz(UknzRLhis#1(`7F`v(#CNe$@YvF5RbZfNRX`NDNIrzEgS6GqZxAsQA(;fOfL>2q|JP~6{ z#U^{5_fSX~LF~pp@q@H=OQpu15^T_K9{k|Js4Bs&N_ab4W2wQ4yagrIxmPsKfV35X z41CVY5scKe!i!17KK0N&Tw~qhg5Hnqm7Ls3s(zgMm#EU|wwOGvx2jk)?!9@Tl5sjC{szt#K?9E10b$=lNF?L897?p0V!FG9Gsx zL_0LMlC|(uXJ$qMap3;oB|>a}N6aoLKHUrt=afWY$+VMKBStrgF3f)wDh^q7nVC@05uCJCa}#cnSKCTSlz+Kz$UHJLw-I+-H#=qaUi_s)iJM zY*C=|{_uHSXp|sC{m+2@L5nC^2$jPoK-#0@;@%p=UL~gF*s$U6L3y345_{t4q(>i= z-%_~kKCDbg^p9c&=-f_aye+gXB8=VaJ}s}8VNtcG7E8HA;HtVw`jZg(l7k0dk;sXn zq=y1|O`T0np28BIchm7M`moaxqc46x>J-=>OJytqs?%q6>hW16^lzT z^gaf62NCo2^UO*PkUF^MJ;o{J^jIrUQXtDgt_GlzFIHDV5Yb6&|7d?%nEjF&`td~d z4)M<#Q}g?1#&_=2$wEM=D^`|-o*Nw=?q?Alj$DcfhxfEn@Wa^$yg}P90NIx8GVhgd z_&DCZR)cO}HApUh_>UU+CuTk{u$dn?hVKfu@0yp*@h}Slva8h)rFyTuu9fUQ`ApVF z(VR!2%>5jyi_*JwZec~dsi?yR4gJC z9r`skasXK+1Cfs89AhM`WS6FmSjQ@mZKrLeZ;%AH}Dl(l(eZ$|R@DP=Gc zn3p=+gHaD7kqDC)>q;WUpX_1*_RnN5x=3gGV-uLOdg@50(?Z(?E_^1HwxA&QAdO)w zLd!HsG?v>`^l;n_bxUXa9^=AqzZGbM6k2NSiJ1G7RIaa{+j(6$39g?yEI8g~NN5o; z3DyF|vup*E@RJ!%DQ8j!We};6#e`idc!yd9K!~$?~bm$ z)Mgx0Scwkjf_VT9-eZv;XgQ8DRrzjB7`E+Wr#S-BkIo^vQF+{jc#h5 zIo2(hSv1FL3}&nNLWLiA4pPaSVmxK2hEjSsiK)YC%t=Yfn#CGW*@k@vjbVyP6~^3Z z5YD1?`Bw%t^gZ9DlatM@I2+nkA=4}RkY1u%R+dp!K|<+eHLQvE{VL6sFzqI{R=z z-pxQa*H_!w!#0FD?qu}4Lj!!i4>)(XGCGmZK?fx(_~;T&SP*j*8w(EGP$gq3`t^oL zDez^%mC#WFnpKR*AWG0f*@}cJ?NqD?OJsPbqrj@>%Z(0IdYfmJJ8$a>C984K-4$BM z4~0z0GkWEX?^H!HH~Sq}XD1^+xmlBz8c!%QNmYI)yJhL&FJYR7WrvNCiZxXpn4}`6 zZ+yU#7VUg>OBz~a7@3=!cq>}^)GaEhqcX^#ZNX40HX%0PIhnLnOiTB>k6r7hXPon2 z9xq604Hae8YpRwtbzIW@d7(Kr`qX)XuxOO)Cgz_IB#5vM^c%pmq7eX^$J}Kz=XGah zwdpYLNxJ}tDC()knZ>EPNt9%zsv!IF zdNy_(>A7i66zhkaU|?zXo(%|&9Jm&DL>nu|U&kP|1eN)kF7xV^mWRQqqA7WS7}d4& z`}f4&NaVzNiaYjpAfmpXv#d(F!SgH6?;~Ft^&cO=0M~(a1D)1h8yWUPha`>H%9`*v z(^PJE6rcS`v$4_{Okai7%Sl&sj)##AWj5okxYRTkGp~xgiifLdW7bZB4e`O($fksFvIjKy(YBt<#WcR9p|( zrRuF37zI*p0z&DxGi9Tp^(*<58O9nJ-QyDUP^@fbHVRM{q@)>?8=9;8x(E2b=cyt! zsbtr487(Ag#ll@?JK~aZcXQ~dRaBFOh~ip~o&K%QmbQTpa{WxoAa;g|y|;S|rDfag zcF<%*zYZq6nTE2jFc5Kk&}WTfcgvMrM`*#CYGhqBT$7|@Qt zN{ipV@okIP_E4F_{JU9L4%kqys8VAc?l^)VhvTXBjn^P~FRgiIt zgr=gUk}Bw!1Je12HP0S5HlKhYN~v@g@`?RGx%^mlJto<91inFANeB0=*jPJ#P6dE) zGHXt=34~17)6UwBL(fw^I3|y!n9$Aqd!&HgP~M)TUk@%Yyp^XIeY%Ud94^Nz{lC4CN2wJbpj;w&keRBfjp@*3 zJ7%&r7Zg`i7r=$79((h&G|`c;*QV%47h2tK=X1{^x8ZC8GF}m|jMvE*@Uvk_NUI-I z@Nw4Gvw`FgVlA`!OM`%h&21U3!9U2+_cL+8-kTd9W(*RsW#H^!WmTJbK4zjD{MMfe z46AE%7cY{)iFx`cnhc)zeSfS;J2YHPJsI~#z<(IxF&-M!M?(Z%?MI3il0fp4AhsYj zLTe9AsTwyl2hpiN{il4~HiBi&2mWkgSQ+ltOcPWlnzhTN`KMOHc-ep~+wyiQ1$+}c zntXddUVDwu%J~e&ZakYnZ@|>>tBn!08K?cr!%D{FEcC^S=niIhwKl_Hc$_I2xJLHS z2!K%;-6v))W-dn3BDJMKJ6rr^DC%}#W6(am8l3c>IIw4Ja`xcj$(rIOwsMKkUR))e zG^Gl+t(A69Fka_|wt(t@MIUhFOfz<0i47)sIs_QV2fw@ppC$@r1k*yV_3{$6?d zTKUnwO1dEZbE0u`;*))XOVQWs2OOR+N|Vv#@pgG6SCiRea2I&Dpabc}KGvhYtIO2e z!!r2O%ijsx^P^{WwPO;(OM)0U*^}c1&%w)cyT;+~1)WVyAO{bL(#gQj4|RG-4O5r5ogU8fGH1 zz2uL+;_b6UpDh^#eKu~V+rJ{g)#ad3n%}peqgLp5e8x^vYs0SsoC>x8x&t1WeC^iaxi|U%PD*p6aDnQ>zLyBojs=ob-#-FGj6V9OlB{Me*m zaX=C*Hrwg@uG}>@1BvfxcwP=1GyF*id!(Dm;M9k=zC?dWplys6TfI1o_Tk6Y8U%E| zSg#)Cop4a0Ap?ic3 z;lpzjvl;@ey;SiKMdBv0HC5lY1XXO3L+HK5DoqOgd5dw6)9E@|FtK1P_ULGD&+XNN z2j^DmFGfypO~J@5WW#iM9k3;<#v~6aY1<)bOaT$28FsGyUmYu9saZ&tegn#8AtGw4 z2D3?QS-0t59sxkBKGtVI)~Mqg=nnCv^XG6}vwoWi*P|cQ@Rox$zp_DJ)6{v+D0!sg zQL7b?C(xJ?_a)Tyj4L&)rt69rvE&go<4gRH3I6)qv z@aNHfULhhyj5{lxqR~?S-kJEsqc}|`t|IKk%K3a|N8?=^%JO@s#Or{rOS+*n*38?4 z*2u&|(3Z+%`Vi!dfj)SliD(58ae9CsRScsyc6rebI50U+ApWatV(FAb5DQxqPgz~w z_`zOabvlhLE;)}dF3YLsSI^TST!R`>*Fz-@Y*8n<)kngQW?bqTOx1H&(xo;zN}Eti zf~FKq!k`(;Z>tK{p!_f$E*K_Qjb70q^$qu*59z$=-B>vdj5k_d>5vx9K>w7hM554(h}Y@#HbV>{+w&u#A(=p(J0SRLuRpb9Snfwi z(cB0 zKtZ^cmizbM>B5F%d^|&t;L0{XNY4jm(CzI|pc&X$=`&N>(%vjOgrra7o{re|!d~Co;&>!bhQlxT^T{dP<^y}&=L zBuE9Fjkx!)4tfWJ$u8f=uHEFH)R+u7w0g!7PHddyet3?g+{cCA z1=uW=E98QJpWNAwfYfiurFQ}cqU(A&(XDbJ&K1Gx+&$umK8xC4nwm$CtqT=O@kM9* z_822OqC(y6LBT#RT-bqPx6mF5yi|YaqD7FTyYh9E5N`T6t^>qq&@0fatbhz_&7?_? zJUoPsmp7Yg!SbOC##z8D5{AXQ7yrsy&epyH7tqLawG!8=t>Qh&XeV{}u`Xx_2WJ&= zOSz&7_p_xI_?QEXlBuLpz+m+D@+KF)#*&ub2+Bn3NP2Q|1LZJuG2Y`4y-Ap6?G_w9 z`rqE$m+!S_L22*Hg;nEeV&rI3mhV}2Y1rE}P#(7Dmsjp4iY>SH(*?a5F)@Q`9bcyHx=CsHQx=EL&1o-9oJkh#I9*rrW-pIVnGi> zyj7w?^n#TZP_E`}SyFm|-~)cEqbmNG-ZUY0r@feuK5;Jy|Kl*0W;EZ--Q1Ab7hCpf z%Y)DWWNkgHulhsVq<(5a5QtRk9EKBBleFQiyd`A*=nntFR{Zqr5@7Mc?U{TtF`jZelWdS;Ua-{TQNV>m5?+ zc*+YO9f4qLm8?vXRH%y7n0=ec1%K1`loBIbU+?}H2vx(^H?YZ`k{M+>vhPg12giV7 zm%7)V5fa^;4nt!CquyKGeA*u0k09z>52s_S>t?*=WCK3Anes!4q<-bguRNOhReLmA zHld)zsa~f)r5dIx=0jLRSVh%f=6zrgb5DYE$n;bBD{bqQd2bxzv%z=F)Y{w2r8;Nk zw#o0uN#bVbrf%!6&}GZ8hobHdmqN*mIMwAI!d%*n?vLW?mbWR{UKf8I2GE99N!b34 zDnp^7a$v0Mu*H5WPb|)ZA6h{|BtsQ+COEklIN$raZHAO|kvwz`9T(e3mQ8|&QD7!@ zWKrR|=JX;ixA4BJ{obAk>xNW;v_ha*`#jNBEc_+PD-2S)h-Y7g>j|EOg*y1es(pj5 zZ}>!@v>{pTg1JWU+C;$tNL)}EeS@kaMI^dQPC$hHGC8E0jFCKb$XZ)&G zMdCKr0gTWltG=dMZw^^;nLtMZL=(|2xIG0`v>Wlw0}1~bOP&*gemq8}<>@J=BgD;( z$vO3;Ed1P~hMU;JZRhW0RLd~^Ehl72I8r#zU5t}EX-dGBlNf($*I3jp01~iTQn^;L z)d%83i(xwyaJw3qb$372dps|pj?VwO=O2+ZMceHS_6Ky^w_v6h%=n2#ERu2^d5cbfVBhKHr+4eJozA==OH4QQX-q+e)!0co}UAt3DHPI;+P>Nh3?I-YrUouUg?7d^KG{?w zyDLF0tm?qPlCaS^P_Ga-0U~c1cyi}W9aTHmTBBD@++ot1r=;Li7uuvEIx!{H)x(*# zN&qy74j#wMC^_yvn;huc2JJY~9c>o- z_}(*|X`22fd*ofNf?oRDH**VgM%`pQp~o+d=3#ZIt!E3Dhs;>LLdtHfun5!M3XwV4 zKy!o@W6uECw{wZhkC8#j-`c;t*)lQt#5;bbM#{51LmQF-CLv7f`3~qf4 zO=BuDG~TT0`IK{_?5>S5NCZ*Q3t~=6DD1Bcr7J@pNyPX0kad5^E*F{AuM8B@D;Z_i zp5;!TDyU^`o^rtzJ2Vumiiq9$Q{VPmcEY+M4Dl^*@xl)o^YRs|gF0wkA*$knvBe>k zg-y2<2TBez-GW-CV%TcxO*P6gT-?QAdq1n^eG1ssh) zQNj^(JhE~ zyMHAE<6}kX4jueWvwodDMbO#+J;J)*b)O2LOVq-W*p7D4$K$jCE z&ERtH2?2^ALacpvaO4hYY*f-M4-$U1!B_|Zem{Bn5~Tpe7NSR;_MA00p!S8s`;u(! z`QU4ryWD1L=gYmy%OQ-#ELFh+^lvui^^pU?1!~G=dzO=Q5rRPa?w8!kAXymj9I0Z2 zTo=%5Z~8$z)GBq*vg)5KABD4a{rSTC*{BcZo_Q_(tsC^pcV{@)J|Ly3OXgZb_A=8? zeMj{On;pG;H^c(%O8Cx}3jyNT<3I6hLN!YIel;*HrdKOxRTA!X8)=Yr?8L~B~ zk8F9(T+xbDi&DnKk_YIW7JP1WJQHTGaOy}An;IomZa18qvj7mM!+`%hM z?^ediWTw<6#Edw88uKp9nu<8aGSuBV-%s~7i}0KRsB5m!<*ouUyRyj=9V?K)o?CeU zr=gD-9;F$l#k1dTpTG~e`KsDSbORs7FI_Y)3<^JvhXSdsbviPmLKB1gc1stVY#tSi z?W8qAQj$qD@McUPHkLs%hctG652nQLai>CR+;ctzM|?7~ZrERh<4Z^74$e$b%H#pU z;?0Gq)@9)onh=-GSZxOQEMV9bezdvNeHw~jDZ7K=Qg*+hldoK;(GTe(bh?eNFPjor zEB$>?hqK4|K}NA}7*LOnF3>Dw2T=Ft#5wTb$Q_5EA9>OvmkZF`Xwm~#?rQof6J;z5 z@$WJ?`I&MVAFE>QrFkhP+8q9pDTST9i>cWRu(sCQ-+WG!8Z+y={LmHJNoXomqR2Q0 zIs5)4p3!ki2o`zMP_Q=4sDN38xr#V>sDmxOliH}WJ2u^a@Pg{v@hWUGLa;29iE~!) z%*9F1nA*Dhh?u$6)RP2(3?d9pKz2~ zARoR+iU=DxZ)vy3eXr&RFBOOGn*L2C#r6yUD`UBkWFmltT`3_~T0T@o%28)(8~5&f z9~W0LxK%mW3Xe(Lv;gxXHD)Bg4?B5w*n7t(;#w?#j1c?h-`Rh#QaovluxA%{ixYqc z-8b!{Ea5R&+tV27ogRSkP=|=1)?o22vT7&$l=p3FSp_2!Tgx@z!xORns<&jk7xVPZ zNvy%Dq*g(?%iAklY`(o)I6A7u?}TOGezcL0&c>mh=j(cQB*_8gx#C_hu^+J?Y2Pb5 zs42oX+fN{O6Q*A8X1*xt!%NF(9?>_FzXF~g2dkVqULkV{1vuq%qj7$_tb0@7VKkh% zB9El|p&)-sX&`d`QS2B`8Wkqd>~M36EUQ=cXkB>huoE{NDu7xTog4hMI$|?_5K?63 zP(#v~2QI_$L6wf`9}Gc~%nbL`PN6fkdrQ*^C%0FBE7+ebntP8i=XD_GAnNS@l^-k5V%*^GOf3F~udlPVrxHgS0C0kBri=mn1sSMC}vzjs6eL-hoFHsOi>hyHDG;ZQHhO+qP}n zwr$(C-KUK?lT7B`H}ht4^CkNiRCab%YOnPy>KWSE$}J7Fn;i=!WK$v9temQ3$DYD9 z!A!fe+u_yW*5Oqf@Szse5?Jc$1m@(@%*R9EoU+(#fYk}=)ezoP2{fx3%<(X7k5h-x zGISG^N}EF}t{xc4{zH}&tVlRM_e2;Gu7&Tl^v(~9R(Mc-VkhDRmlfR#Aa@OI_wHAu zw0{hn53O5dYg9p3TfN2W$c$^3PpaN`%knr=rQalr3g`LXO3|Z5NW-q49oDq^dp#(e zb{9h)s@_+cB}E!xLst40FK$$#DFA;4?rYWX8#k7oTCh)5=WlN3; zdI?)KH!<7vTF`2NFm*M9LGEueM^#WfPPLtC6K;Zh>fPm+>sI6vse&XT*;=1Q1-o`E zw_NbM3yKWXgu<4TPFy-Pv?qj1&R1V_(?^L(vm^>|&d0c96FGnhb_TGJp-MzsZ2s9_ zLay|*dcs9gq@6nc85toCd6+mc4;Rwwb+v-`zWf-#U^{6U=_5QII2ne6)|2J08&y*L z(@=Cl-8^L)6JjQ0B{IIxqH~Ydc+7S(Zq0c$@-m<*@M%(3E&cu_LiZug|B|@h#d*hS zA<(l`$NdfFIq&sfP?0w3p-l|)$mDqJh+N4yN)!5HtaTis0!oa_VlAU8qA1x*?BtZy zp5=wbZ59Qm+H2PXg;#H4Y{8`JZgVZOX*HK}|He)v9XBmc_nRgGiLT&$ja4*7{+CZG z8s2?jPZr7x6Nr^Pqto-o71xZxIGtFCwaeU06eOXse?<6(+$)Q%knM({_Ixp2;pWIK z#tu)e6+CG%QB2j5NC)H;(W&50(ET%}b#9BVDRpy_+C=orrM;ev5EDqz5V)22@5bT@ zD;^;L#zb)-tyWSGf|8cQxF@xGTzQRozo@Xqq_atdJzbBF%^ja|OtOSHquaec+vY@j zs5^4Vd;e?^2uYWU_4=C?J_)h1lsE+3h=Mu!lBVrdRU-e;%xnCCf8}rZG$;Z2TAyIB zm}%c5`M$jC^q4!nC&Z556Dwvk7+;*=gZZCd+%4f>HlFXcM}hfsqv$nV?Xi?4n|aN7 zu>7-2wkzldd86+P| z7$Fgzs3xAaFUQ-8y9|&qKW1#4@i6IArfG-XQtBlzTQYpY1XR?C7H7k~owFmSQ?X88 zv9Enh6$LXbAidspfXVDy^cSrEFdIu;+!Y14e9LuJm?Dn-zQCcCh&LrFRV{AcR#MX0 znLYlaF6m07)*c|)lj8=1`vicRgZP2%T2%4aHD+Gx8_h)T7ShZESd=ArY$W0&SZMj< zG~qC;dAzm%Y1rFR=Zcu(^{~;t&&iS!qnF(jzSc0%qJpf!mLoJ07N~ldv2;^$DJuE1 z4%WGvO>y)<0H(OysE$J=Ex7`E9@4xr@GTdHOTeXK0)vEMwJ}sA6uqRaFvT*zGfzRM zYmtB~9-X+`VXCNKi{aP|V(0LFH(pNpE3HtP!vV4y-74Wyw?bR)Rb%1VE@6=r1k}i= zw5+kna=1|^L~6X@7+EQO5S^%n@ z?S!3#;O*-G2R}|)q{%Bd=@$QJ31JCgeJC(6G!Y+JbwSakn=G#)&3Sm5W2 z9P*$efA+lG#Fv69Fy|SF%ODV^ZfN^k@q;cWm=hiSX}%8EHgC^t&rN|y&z&b+wvdDg=J_IX*sEiWN5El{4^euUM=YGV^iZvh2t7XZwZ z%*smW{WLk#L0s+cv-yvegl9A0d*bVQN;|W0mHJ8drdvg#w@v!}7 zfiXg|U|j7i38utFxV5zPY6grcycxHL%j+eq z$6HOwtGK<(KHKotT}#{C6-0z93t3On=M-3?<6Y&EbR;EP#86++QZk7xZjPa*&T3KL zMWQd3FY1S%QP?jk#bw*_$&*dQFXPAWP${Uc#xqMl1#P4}Mr1GIW0mn~gK-k}*JPpaPu+ zY8%wLNAvPN<=H2$)R)okj>pMmT|r|ihux17xJD(d+-15M!4fy73nIe;xHzo)w>7OeYk43To58 zlxh|dag3${R=Spe>DqwlGQxZ!K+NxNFwEI~!{dT-CWm2SWQ!EA)Oj|fjeE5lGtN;c zdw+jTrj7Yg+|`CP&kc(@HWkk|eEPj0)~`Nu)AKTn$M-{cvhXW>dFm~umJxF_tWI(C zn?QD>v~NQ@bG!;5F{Q8~ft}r#TKNxVFW^!(MM%H#>OgQE#^fY)(oY*FkSEa2=$QJwU5NIyx_&*d&~kRx0RmR&yr$OxxL@V_LhV%<;EHa=HQ$ zCkklhM^pNIo?7BUElo!Ul*>0#8g`b9uX@9R7lhx%f z3m#CxhhYCuWHK1X+l=cU#eeoE?1{D9>UJxtFhmGd?FkOb7u2uP?@e^_&o z1^V^rx}>SP^$~m6*Eb^DbA1qqr>EQ^(#aupbp$_OkP@uudCUqR85?-W{DD681oXV< zNROmO%p%gH)diiSaQ@%5lh4)O$4*p_m(|^>FA&U6@RMHmV8gnR4vo_AqWT`-Q3!yZ z8l*CGRCaIkwS%cpouEEkZ)qAARV|) z=eOrye+(s=N~NAkO~KFT0t5)5*#3aN2wIak~4)l^7m|Czc>Jz25D1`>a)4`Ug3omC5LA`hY)sQ`;-1 zP0f+3mmu!a$NWT$^WhbBKg&rUgIv-jhHzYBQgS%Bu3$I%6FWS`J{`?1HJoIu?R~hd z_vPr@!$wJ)coqdGnS3buMTIB@cN%^I`uG)CLP0T=q@Yi zfCke92S{GJShsX_W~yX05i2721Yu#cyd2Ru=c2TxI2B}ZOuEc8p)RpGVT5~#IMFU4 zW4N>-Ttk|BUV4-oB7-or2IEbPg-y5K6YtqK@{?#Z$*F2J^NZ|uK|5V(T}EvA0LI8e zl!nvcv6FPL4~-yhSA?wIQ3FZ%K~c#B(N#Md2Vk3jR-U)T%w9;ELE+7m98iXj$Pjo zAa5?~=gYkbF4utWiC=@0cZxk0vel!MtLdG$NKdHN&)o))RnF2m7#sUF>zG-&6#S+m z<15&w@NGx;x%%FSLwbI@vn@*B=&(AnJnV^T&C)GS^BX-l9Edb> zW>D+HfsMrGEn!F7HZ7=R%aE$LR@5Aa<~{`TX6Lt%$1I^%s!x`ojf3oL?Q{1He@#NP zk8BVcW=;XsI7#?+2LF@-kh~GFh}OBVD-l_&w5oxik-_6L=(FxJ)1;7IgWjVS{z7%9*Nr7F_aYlty&AZwyGA6JgHKSfR`X6r|-w42xjPVji;N5_{}D!Z$xC;0 zMA)Y|lAHrwD@E26j{@Lw@$5BIrvPAV)UFQQD<)RV!EL~oN`97Bs(Lt~3P91j*7b8< zqacRP12J04{m%B-P0b<%%TpCFtE^y|{fCYo_cAMKDo<|FLN6lj<-ytgqV;w`+k{(y zVj-0A9njrxb{_eI)l_;|+Ip;@M#wj0PJ`xy?mO&|!$Y8;`Mp{omYJOxDqzU#y|g@~ zL{QR6D9*ll*cZ<DM1M=6mDD#ewAwXk2+B3$PCSk_cP&&Rw_$;(d9N z9eF#Wf`YQZq65oE%Z|yY*!pR!%h2}{zhMO2|f_uvq2zy19zp;gQ$0#o{xteCY@U#$2EC9PZ z448lTqurnn6eTj&b8jx6KgD9D23)et19*_%Wy{{#Y3E8t-0{sGf;)K*)!n&W+qkw8 z1h?(l=2NM##)EN7{>tw0foMqTF3#5xY6ol=BM*7?mjtyZr9lu>E7h^-Yu)$CevrSwHMq z2eTE`afymJALSflQR>Gj}XY8w`*l3lTwQ0 zmPG^_>GIN?kF)V^Tx%P8yPM)kgR}Jm&wKz6??cC35u$9F{!)$ZP+VJine=^}1T!|o z?;7u}!~I|w^gOH}Ge28W*eqk5_?O+|k`eCRH?%g>@ZOu(Xz3#4)bVyh%#_K9!QXWE zCF#8^#0MUh4XzdDeaxQB(?x&u$E1cyO|7?RH&RCmsz(5G(?-?|!m0CTnG?Zb#4REW z*L(UE2b-J&5O{udb$N>${q5M#N%>CR4&DfB0qny({7tS4oD+e-p4l_(5-Z1Mm%v_u zW+j($x@owQPQGq$u4Khj^Qv)A8*bV5<{kl)_qN;Rt+Q_nBN(2=`+Pi?q+?q!XEiEn z5t_BDiQ?mCK7k;gTV_>=nH)W%fzmC368J??sx~bbO*drV;1pu?8=MreJ#6?D2%+(c z%lU>2_XAaDzw1w%&npId0gk3sq|8Z4em*m=i&$~n$$3Z30FZUtdq&ITVpUf+V?L_& z*;|Pc*OHQ})$21~H|7mEC3F6ksE~q*CoS2c@p05^5JGZ3lyFXh>UlBemXb~Uq@4usoTx&^>iXo1U2;9 zJ$URSTvojr*tc#RS{zcPm~Nd4>OVX)M+O(IHvrtNTcLWi-k`RVSUlfhuV|r1+xyvA zXJHVJJ{BGh_Se*F0+T$S3Jod&ubPH5=fx*w3=p#XmikJyZ50d}Pzx)ShKVCO4>K!N z*$xUPi>cGmk-+$TDWB#^&``XazDTBKlXHl^kmrxK~z(hw+-+PPR~4;u8#6* zwdI2I!P6?bXDzUt%XjjrXp_MEY}chAc^Fh$WdXjtO5I?RHZUhsiaM&nl6NmaqUa%e zgIy;*uc-*TfvAvRH;sX*+}H4QITZomPR1u*wSAM`e;IoJw=ACj^P!iCmF<5A#MG!* zDgOh+^b*8-{o}xRmd%gJaJCe+N&=2iwyGwql8GbKK!FH{cO&BdlaUMWPK4qIc9TSa zr0@fVKrrSXcJY>4+Ef)ST7p}&{AD@s@O)!nQ#V_!X8AQ;?X;?MncaEi+WUFw-9vzX zc?ssnPjB~CiGRIpx%+&pd9ZJ@nU3lIKzpBa!ft1SxRn8XO~o05>R7wpBZLUJLgq!3 zBi%TROR{;;;fmVeX1-*))1A+|%FAF{g&mQx~ zm0Y}fKt9F}0|J-A--1GB5ctYe5yvHhDY3cg=IJnhyKhP-5|nt%DRa>Y!MC`*M-hLIJ3n(uY1kFPrP0 zRY&s?=U2?2!W$(LWM0#Cpv+tCAWV%tLyf^`Ex$TQZ#{adg{sM{ zW)TEvBp(*Fc34T)8u^13!KDvxibXIY%2k`?pJ70fe;$J61yalA)M(1d7yYB-Le_7b z^XqP4o7g34hhi}WldyF#C)k*1?nd_4xcvGqNv0Ws56q`$NJp{j3_$nuNMT&IdL-BT zpMIu#yyw3*DmpS2G7HwVGDbVO(7-rl{+(Xt0cq&Gn{N-AeBG#Ho#xD6TgH*N2jUC7 z&BFo|l=8V*LW#Nd5$GX#+RS(S3erqI zu#7FrUAcJbkjU5kJsll&cCuD=&UL;md5!N$_YEx{dqtqZJ(~V@nA_ix?NtyWcXU62 z=ZVywmnlsUHZgbnL}*2*elJC*WC9XAiODGKJdF%88~kC!lN+(q2P2EPKwI}Om-7=H z^y<6UTg-iJh%XUK8%Twv7(mYS?=$iia3JkttwFQxx4rb78X{=@^CxJ;?iF<%KmZ;F zYpDqNXAx*+>Vd%#trk)?{SFqoL->|L$)E|HCpK=t%F}pN*=V#@C1?5B9!y5F zovuXS+ZZx=eHScl|R_?(-hbtKFiNwHjMALFj8AVgZFTc6e(y0j&O_ zzLxkws3!iO+zMAL`M`0%snMweOO}_4{q?lI zJCATp_IQ>d)y>RNXeaG5!@&Gh;W%32V5Wua#Ra|9y2 zM?5vzY(BLPTiB?kpR(@1`5-z>AwUxCu&5qhsy@{O{(T8UUrQz$ZrxNu9$^q0$@^jp zY+~YHtu^YMca9#q@OuqKzY{sP?|$&Vcfq;|?JsnQJbg*#%?b4omFz7JT0)UXHXCUL>T6fO08F$^55fEXb1hl}DzdC8>XBJ5S}ifGjg~&TEX#owepefI zy?M8awH34e-s2M!(#sENc1{lwh)cUcou*osoVy^(pA=**5l=8P3>T1P3l6 zo0UcnCr!_jCMQG*fjqg1K}unBbO>pnKv${+4FQYCMK;=&L-u+DPT%g%-R&1HR|Err zhBcyeldC!1CjZJZpFA5Rc}i=c3Qd(faipqC&Pz5&(~X2V+45i64~f@pp0c~Ur*B?9 z*pd}R%$U<$v=5^iCNE9S`|6ey(%?tGKl7W3bt zD);n4W|r3k$&}s}?X+8+S}bu58(k?27EEULK{jS?jlKE$nvOcZ^~IeH6DHg1awglI z7OOMUqt?(+ol(-JiN&3TT`OywHkXX)8`j5rrlW!0Slc9<^>zohw3*f4ZyK%8(9p}R znbi+osWT>*tQeu4R@$RD8P%i_ThE#Hvbr@>Yb&;_XsX34HA|}--OhmUHL^j=(PwDPH$oL`P*aaA44ezAUoHuk|P^|}~ zxNoHzqZPmTA=^h**o{L9`$l+FklC1@(TgNA;dg3$Z@8E>?VYOC`gx|x+wEFQJ)U-> zJWWvXnj#-WaQLv`6QkDiPS;;NQaEz#sabC$Ppmwqh z=5Y#+C)Qhr@WgCD1d;aStOtO*BW@wSdRRN)<_KRjv81R%XH?4vFif?)hHL!+TucD) z$6+BzQ=sAEWS-bOhHwQ!f=E(s`srk)sT-IsaV~3YQv4~oCq_6Uc*MbMwHlf{#_bVe z>Nt~ii}Vz^L|zO|GU`VT{s+kMguD$6uD1cwzf;*T7Vre98N@ueT|(*%4f#d9Detrn|KHrXLFRlYsmNXHc&dUE`H-sdMPPwo#12zu3YI2~sG#W1j>ei9hE4 z4?uVj?VML}<(hxPKwjJWVn2)MW@stzE|&WEIJ`teD}=efcLagfZ!o`C_<4e6cMj42cs-B;Dfm zvvbGL!q-!?Qr-xEl5pGR-FbGOF={{B9||kYR<7KLy^(5-y6-gjS?|(fPxMtMBhKTV z%jm~O07p_`orWN$2I!;3T_e&6AQdP`MG<`E-)DXcwFUg%YFi>e-ORTJglN~~WL!Y5 zOgly2*$Ce2^emIpQe|`?aXy&7MLN$+P^kxq1jApUc=r>yCPva7!iSHwaqrl+CAL{M zfw)1gZ7h=l;2eA*2>rOz@%JPa)L(GAzm+lVz@AZg=%9R2+wbGyRbfw(h(WVo75MAo z0)nz5sk6eQ9C7EzoB?T_K=~noJO-h^t5c5c`8{?1h~WbxFc6kOEEc^OTG%K!ofJ(j zrlS0sneKH>{m$dBeZ~BMhs47l1ItzA1@Gisdb-@)#`wQ9=js>|P@NGelB3z(w^6;tWn>LuE6Mmzxj55 zFs~x@;MA9I6aK^{TmFp@rv78Wd4Rel|4mCk~o5$_Hmoh;nIUAdQa0RD@X~!J{Z&TVw9H z)89&!GO0>Pc{Zsr1MCAFD=~KcrEL(aAk&t&*tPkmtvLWm8$nk)J^Gj+!ZeKOW!G0K z?gA~IC&9~$jd$^;wT6rsJEfaL!GMXDTefJ4U_@)j8UPyfBo2cEsp zUXR2xK}0A}fkfj8sxdvknvR>1)IUR6EFUvcLEjE*qea{AKmmloJH_>4q}M6XB~Uj# zt|NXUjXEF#th`MTA7!i#b4!SbpTzRbd{X5SjrSatkNXMJDJoPq&Wm?>teT$~o8ybq ztJcQo;A83^GuNxjW{sKH)fYldz0wEsW`l68FZhv@b;4&~oHD9SQEJ~|{W{B?C@ znbyok7c83Tb$+Ls{HH~q#2MtXC@oq*C*BwGdzPmD z#mJ@P!g>+{h#xz{Sq&iLO~pn!6(*nhmjSSw4<|YmhO}GE3S^KTNpR4({teO*Q!oRy z$_jPTfmaOG84XOj2hLN|TLdqhi#*)I1P>)wOvn9o>85SZ!-4=Q1Y=l~z<+*&;V=dj zgEgu&5RMf;2aJmYf+$wk`p_D6DkoRqH%G3sMN``5JXxZyfj9=zae7)ajT2t9Oz++z z1Ry|XR%u&_Dg|pMHWoxrC;}Y}bihwO?$uEJ*(Ov)n0YS?qU4V#A%1~x+qL8Y4T)=F z)>VVyJ)RUC{DRF-K0wE(?&mMHR$7!0|1UD>K%X7{PiT8Ed6(|*m_+m!q~AF3I9K<@ zTAD@gM(ktMAr|JA$W*t*PgKb?&>YbLmdWT(gVV-_%jBp%cH$Qt9ps7B@n*LCM~*xv z85-$B_vx_B9LH7QK_-C@VtlzRvPq$)a!r(D^`ZgFcF*rS9h49`{!S=c7S<4wwG1qW}Mm;oUq)gpr&a;uZ#7$^1nDS z6(tsVrPaUHiC2!t}B{a&*4G!HEQsd9n*XTYm5dU-m5w~-T~@Tv*7H8 z?tvp)py27RrO8~kFtz$8d$8tt|$qr+S5Wdmj(uS`5<)SWc(QRT816%3- z18~~yEbw1S_&*6)VPItYk2q4FL@#M2H{>zDHkz9j$}B^0+O*cu2ol8Va)EnTUQ}LDHXt!^SZ@Cw7-C1*TtyjZ~W6)QYGLYzNty zS(-knR<8umZ!^DbC%?1pC$3kg-ZOgPG9s9vVY}`4KC7u0kq!?mH=2g3glWp#h_I+n za#vzmP5xqJQO)uMYfTD;G--$>KB<-gG-a*dLc<6R28T7%BzIT?aqa_gN)6G~gf($M zheW7FVW4A%2!`sh0~eL#j+b{w$*3qYYwiQuzmPAHu@A4QxzGfJz+>d>6tiu+>? z*sd435S`De%Bd-wUPU(%1&frj>4Ubdw9>5`j1Jp4Kf)nPD(M#5iOEUnCe!sBjn%&= zw00H+MT41V_bKhmRUxsASAX0LDyGibHdQM?HlonhR#!{8CaV^Ab`M!9ELJxa^&OO=elMA|y2j*4DSbKcOZNRkc* zW8?yg>I;(&I@9MEcT$$bIx|j8qs$1(WSyqE_N><6%+I6=J~Y5}kfj7|KaVqjWr?*k z(7zV%f*`;H??lDxL^$p8L(2?HfwF@s{t>t8O^!An%0go}AY=ZC6pjujbgmEkBN)^H zI0*me$$PhTMOny+ye~QSy5Owx{E@X2$eeV16v2a)w&=C5$l}%FG3cGg251k?T8|C8 zk$Z~p24h9?tfOH~1|MTD#dOKU-4D35#GvuU!73T;(%;592o)NHYjb2CFS$qHOuGEq%qhMvim2>i z8@!!6k_v!n<82*HY4EG2AK8A91}Wc^rnZ#BEkRotN!AOl4N^y9RVf3(2ET_om*PH?BdAxS(j+9RThhAuH1%^c;P4qrpX0eG2w3JPa7nZj?X z^AI0K$dr|N!h9O*1OfBgKmqsKcI8skzJU>4mD9lFfriGgtOco-bz!x_CIkF+4CEmo zx@F)kdIr1`HnFca`PwehIH)5HYa=w6jJ^dpK{SZ4yw%)S7VELP0)+Z8|axz~B z0LuVfN_sf{qR`!gORJKUr&B%7v^Yh!p6~iqP}Q~KdGF`Lk1f=iIi7HHYMRGXp^^c71^pj9=(4Zk99j0HKk#QOXft_j8JLq+n@Us{vic`{e-+c7z1))Tdf#?5xZJ*+z(~qs;E;%jxP174^n|CcBA ze-gvM%<&%!o&T4!3kwqt1qrwOe{*)3fg#shf1lzFSiU-<|AxT~!D)=*IZE>#XZVFT zjq^MkzRwL2PxbfTi@^*39REL<-FSU&g5iEBW`*Jg8%sk62}=c22UlA|iO_(6hTMNl zUMF7x69rRG(TG6N#?ruol9GIrAI4+tc#OT8gwg+PoFc z4j;XZ-o|f~%82)vlo=M97Mqh5TGI4iAX_|1*p>84^D5*!jA z^JFFmBWCi85AZ_-fB*&iz;dy&?ix>}+DvrOOlVfiwG!Js+D;|XXzarVF;oS_g8(t} z3r-blKp0yIHD$+Zo8X#ps>(m$X)ydDYhzP)x3z%fbB7kqxrl@xu? zJs6!QWk}=2RYMw)f-+DuC1Ol*PjioQj|kI0Wt2>7no=PR5i?Pi##5M1rgM&tIMe$~ z12~0t40lg$>)SH!G5ih?y25+{d_sJJe8O<0=?vEzuhlnHGm=tpGSb{m=x9Wa?>sy# zmCEL@Ud-Z1dK2Ri0IEn?}4E*0Yzm5jKp~XC7OYO%zAUyLx|^M#B(#@ z+ne(5Py6?000uAt0}%lM5tV|X0!|?Ox6=d!WCnUX4K<#D63;}1Z?-yJAt&o6kei&C zfLoMauZ@dSB%WI@nv0zAmE^|=!)1%j6p@3-9Fs9St#8T%ospKFwxJ?Tj5IgCt~8xB z?Qu%;f^)k0%|}l-LkP^2jWO^Q2x%h9WWWr3Yld6MK_8JZ_!XKlN}cafpRF-~xna0E z3}j_0wXV22sHuUaHJaLlVojnovbkZ|8d_s=weHy(U}K!MZn`?qS}(gg(%NWKo%Of= zraEnBNcatjCOm=BW7>>a2elsR#XX+dUHE=>Uu(!yuu;f&j^@a=@JxXjQsg@^?W=&L-UZ| z3KPEQaCp?PJcDu>6*Ume>V~sPcSchhGs~KC5`*zul`&wvSwMGpqBUw+{K1D}j*8eF z*?U;}^A-2!CgGbB>5mA&%r=`8rlGBq+x{Qsg4(!kNYl?Dctf1LQgQs^Fs!bGy?$p@S zxR@^Ozt+Iv&ql2A0lEij%(njcj!iyJJ8vzeTebnY#H(pa1*H-08~3*d5!co57>RS*k%b)lX1s}=1&_}kqE8)l+0*XGm7RO*%ESXeeYcO0n>z+ zF?R<#or5DH>0E6HZ(VCG&EjI1vM&ptPAV;forf8eBiGl_8aOg&&LSF@Ty(}bi{BKD=1m6glMM5yxMK6I*) zgnIa^`6sYUnIR7b^hij(=Rbdj7ufVxuICU$9TT|EwcsI4B%LO8GbMa0kO+M#w>lh^4cR~x1oFTmdkF%fw zr@YtX@hYGaoI<8p=tOPzT2DZipgg6}(-Hu6fE;`SIP=%mL*Pi+hY?8LORG8i zTS!h&fE4h_+0ukSYnfHh?l zRc)`fmo~O`ELGB~rkK6jg5B({cjtQ=2w1wi=W~HO)O)v*C#J+h&?@*LHB1&@9|N9a zSMF+j?RGvlC3AF?0%p#a2aw3(@HiaLhXbPgdkni_IIx~lfR2w(&@7iRTQqAB)WV+z zQ!1mSODgm0>+$tsCPbX=?JV&2E>Fx&%}LG62?TC_m*M|4b-2^u4~oCW4$g(zWMRhr zPwmm&P-**D0`nWjPRZ?3Jo}}S`FKsWQ!=v(4{_dtyKkiJuV*?ab2s8m*zn<*)B=7D zi4J7}(LjR{M0DZS7^rCxeu;=^mNm_74{98mc%BcCfQPUO7ZeR#s+Mcums&T9&xv4< zSekpEeE1A%yRK5LN%DH_%`+{1jnJL_SsTgAz#nXLEEk7P=DCnPx(E|avoCbd=p zsOCzm#aavzD0peIf^;^zE#Yg9S~U$h^Krk@?LvO1VU*dP+|np7w>4;VQnW80y77~j z^SEigUHGjRiDX@&L9P<${&3{bu%2P9Ei zHP1XpP((w!o)=INfBi^&a)c~fykfLK7lH~EW$Nw`OJF28>C!^uEpDA@H4H9L$61ZL zypM0<0P?7`B;8Q+*N+cDc+;@9w_f*lr5G=4?MNkMX-fc#gy(H7=WL{Sx*IH+s)N(q zDAo*+$~xMcT}Y@yOd2evr1k#cWq%Kj?JPob+!Ar^&^?}o9N(it^dxO>emj_PXL9_B zT8V0xa)asyJl=c{{8YSJK9()W#dBj4eEzQie|H z_j-|WQ_7`|p9t*gg%4ENv_`D?B-HGOof?2p9e2esdhf+bUt8s&Cjc@Yie-) z5t}e1>ve2a@83r@L_9t$B#>gBR(ac0zr`2qWHc{_39|#Fe-hOe;*%o?^1d_00g~VY z>kx8-WlNQvv+Ln?CD%J7)ryxeS=1e$lHa5(@I2Q<0wGR+A;i*DxU~vFe$9d$T&#-& z6>rhi0qU|Re~T(GuSZq_0tQ4{IVY6W)?d}eLtjEJk6w z1C##R=CS zHjB4e`V4aR)7eid>X0-WH5#M8g9d_0$v9E)3MKqKzsjgW+vWX!sy8j;a>g#c@U8 z?o-z`(@|F()TuX;6Sy=w3TpD0c)Vy#$(vOTBXNXy{KLrW|A$>l?w*!dwu47AGr?y3 zbR;KRS4)wU-^0hoV`bxt^%1{2EGI=p_J^sqq>)|+UXEx!C{|a-hL7vCdQ;{w+qgE$ zWe-0zY5*j`nu23;qo$S8anH%`tpuGjsD(tOo^)K=ZQXy>^wU6>Hee2DkorN zm8A^|4{#Wq3#@$iEAcC;KaiX#qzEYVUGTM{#rS77@d=Jmc=1+=@B~Gw?g1&#TE>ec z7tdnL!+mRR46BR^?eP(I3h$m@v~>ZvjyZ1iyXgd86L!W72hCa6&kgh>tM*|NlyXHI zx_QU($;r7hrp((WPF2zBZND&PI{hE#{(qRUkkNRJ?Z8EN5opIYOjpQ5;pBaB*9lGJ z7z$X6naxN09GbY!23}u7k?^oS7`A3cmd`%0#rLYxe z`tK)~XuMe8w2h25;R& zBuQ3VWJY;T-dzpCEe2$@ZG%M_Fx^flKv?RRl5K!4XxWPRfcx8@r9WbK+Oa%jIekmYuRg~R-OBLC zU@}E(S&Ojs70a7Bb>L*RSgY3elg|;K5bf&^ZC84PY5!c9(n`g>3@7TvefV=(k|~db zpZbaWaQRg%Dn`-&kdPu*$}$u8K^0{#Qa__KGs^~-;8>g0vP+>9y6IJEshU;39U>ib z(G2B+7767dq6vUdQZmw?k>UE>ILHF6`aBT-F3;Q~b(Zb?oy9*W){}9y${Oaj8LoyO z$rmlqa20L!pe2effNQu26|HH$5x{Yqx_?rd9v|@~oV-y&0ClH#ssp+U^3R zosrg_?1FDh%f#4y&)hc!r###`v@*<1ck4d0$gNOctWZc_PJvOmmpLAgQS$icUV9a{ z8C9`hxR7X8_bk?&&m(NLE}76Gnvn7qrG^|S4`f&05@N5PC6TO=oSqd;we|RZc;$pB ztYKX$<-VbIkch=8ji5+V`gj4sZpd< z_q;M<2)f2~KWDZe;yy7a*ZB}_;czWR#%Q-F6Xe`3p1;v^ul+uzKJwzA{ zB?z%)F54(YTeqCzkcj=QL8E$x{%kUF6dB+_}9~0${ey+R*sj= z9YL+OH6I4S__)Fwg)y6M#lcUU25jY^7Cn7%gez-Hr8|8%fgt7|;aG&kO4V*yd;6!bBx3k}yS-IveFJfEKK#9M z+AyFNtv^v_r+(2e9ZtfT!5$$-0d874A%gt+Vx1Gkb?SMx-Q=-#@1@|CeQ=EJ`IcJ3 zySaJ~3oJjY4;_nIrl3+(71@b?XZz-;-?I5>wKWGN<%fw#Eopc;3Z$nXH-*w?nA=5w ziSLJ^f_7?)QH9h$A$pjwAgrJhiM%2PSP|&*@D~mEc@1b?XOs0)Z>Jim4@g3tcEHST zmdvy>wn2?<3+TZJ{_qu|Z6T|RGMe!4e+m34EY(gT?r#!(Flvwti+|(Pv@mOS--G1a zwbQn3U}0L`0{NE3g(4(PP0O#rB6zh+))#pNxcapP6{m<@bD^RDBvN%%P(z=6+X>7{ zlB|P=a#QC?TZ%nS=Y<;RyMFxSg;pB$O~Fzwu2o$rVT6*y?P4V4so=SBDPa5FhJaatrCy;+RhOXtcnQPfaNC_yhH9X-F03C+KCzuj zsrUjyZhr@DUl*TJy6&JkZs;9{MRhvy^+RcDu9?(C%;v4%w&hWDGwwvr#^QbHS^C_dC>P@ib&w}!um_3 zVblE^*4G~h8v(~<83wokbxxvhTZkKTX3I3xLa4Az7iyL;(0u(Ymn_QDZDC-Jzvn7DqR^XLTAy4)rp4zAdfQ~+U&aEIkoC4Z+ zKgB!mpFIGgI$z_+5c;N}*ea~uZ;Uugh+tHWw5J|RzkcH76F)9 zp`EU0rC8ufg)*?5xR>o^3PL~33kpA_N{)`Tethm%2KclEuKHU0gp#mULd2c*lS|Fb zoOti{fHKN1QGor~Y{Pnyg*!KwW18(SyzO%&ByN$C*imF%+Dv z1Dxg-UxluMu5vinQ#qWC#;cWSNoAq)uKuR+;rV!xB*-r;Ns|8TjR-N4+RxP?SGAO4 z!j8^sM8#b|p==&7U{d{nUA>xHv1^`FUQs?fXJ3CqzioFJSm;#hlKI&nFMC$SZ0Qo2 zLvQwO`SE(@8JI%|AzGpc`)39PFyeK}?_j-n$L))eE}^sLOQHp_8+8N=1O?LDslnG< zgA0twe4!yHAHuv&gkNh9-H-I#r}X(}Eu7-O3#;5n4J9L|kJd|2o=ze%Rx*}2VPH5H z#p&oUu!wYEj8MwC*iJ@XiHzMrGjdjwhF8f$pZ-5cjKjv3_pUsgLmXlA zpX9d1vpX8oys;At73s}*h&+VNW}C%3hIzutA`x$9{WURfOmQkol2xwvRr;SOn#drd z|K4U``%mWfF)}c*|J4eXp=2tnsDkb()#s)HDCW{|BmI-99vR0dC&!Qnk2TZW-*1TM zxQ;KZ8I9{&a1vnkI0px}0S535I<;C_LJUn3 z?r25}JJo@#)#13H<0FBgRcZAt4<{;#t3Gf;a%i5iTv-X|Jl`pzqrZ3oW3L@WN^mZz zJT@{95tFJiHkhGkZ9)+^>1}QL^H}GcWxP#1 z2BKXzj)cyha((ICEnycl=TLe7r)>&7O+S*@`&>=-{M`A*dzluq*1Ez4n2lo2qC0#H zLp&%fVZojiU|XBVV*lZjG!Gq3EUad`lU>;d?tKG#iC$}z8A3ww^pwT&`=*u+OPqOZ z9N94GjZ+TR-#n&J5cW_Fu4|d~>G$XL=^GIF;2cT>!*YR5EPu&rX%UF$U!(soyv~N7RU9$P!l{XUJOSlZec65K|xx2r7&K5XsYjO)TAhi^v8)o z?+Hj-q4d{G4+W<0AypEwjB&MbwR%pX39bRsB~V+;!A2cEFurv6en?= z)~{Lj>=)A5074jr&Cap7h5DWKKX=%ZBx!R-7F38(H18Zo1-n*@!H3Y^e2STqMTm6;Wo3a zJI^f|UizazijZGpAq$|76NZg&8eB5f!VcLk>2|N#4;t02_V}#cQZj3PbFaN4;uTI6 zWVPsz@g_nn?CfQ_M!ke}C~hAK9w%udmQ|7iSDxRxnb?j%Ut&M9yY*n|m`_17d(v?}pq?SEOQvH6f^YzW;yJLOR>zs5_ z7Vv(dR_7>uSFU)Ux#^>JChR(w_PF=lIT#t&Dt&XUwps}YNj7fS*rJh(Qiaxor6-;> z@f}H7G7Yv;2*nQ;t)1;#rwL>8)^e=`EyPn3luSRzycwrXqq-WN=Ny0k6Lf0e+i$5a z-qX(TtROm#FV>1HRJgh#c#aXN`Z8A_PU{-pn;VGE{Q}nJR{@cahm)l!-l?W4`T;(4 zhUG0%SU<8^qKcTWUq?OKGiiPG$V(9^;rB}VoPF^@PP7;@Ls5vI?N@bF1!UF$Y2Q(1oa(khT;xADNX?_Nl**y@Kh z4wzcj!%X;)C?#*6S()wZ%riKZ3bCa_)FQVq$k5Ty(9ux%Fp@XLtKBciKc)~=u@rGY z$exG7!MF@pj+7=TC8~yjdxw8>OzB)#m4g%>ZX7#1_=>tj&bbH`ujVDe`fkxNyipLO zoxDg*bd{uX8*<%d)Tc!Jc4z-4u4nAZ^Lmc_gu!NC?MlbU*cKb-WbcN5Ft-~fT8+2P z3WDIN>>59_{9RW^PoG|r|Ie@isYaE`ZMH2cAc2TW`1Le>!pg$~-Wo(f2r0YZ8F(Y7 zW`vC~YjW-s?UbV;X$Yq>+91Kq0AHZ?u>27vGjR{+b-n1;*yenUk-Ur?<=GH#z>jD~ z$a#J7jE(ZXX3AF8CNiIUDt8xtj<3M@F1mQ_)B%>CrqaKTV+y$= zerK_EN%sVOSA>Neq6c-90VSJon`6(VXQ=h%Pbr@{-to%jhMP2!=~Vdm%%@B~`!ht< zj4CQ$JeyEtk0nn47l}5E+NI~jxf-ayCm^VowcEU{2z(L8SQo1yMm1lk`86kFyzYrM zu2T!}s#r-U3uEZcrOnsWjI&AV;g|ju&N4G?d2w6c;E-;Hj_T1$;{_uVUm{s~=%~W) z3cE3Ty>$=kN_~{JvaY>c^fUHxm0MUu@LfmWi8p+Lpd|22nT9$e1R9gjQ?S}__+gWNyOP{DK zl9Br#O`|ALIF+rVzgXw=%p{LC3(&y7xm30d_lck_ep_0$ai@_&RSpb8UFu~0r8(g* zdgp&bM@ScOgv^p4U6&;O$$YR?JI%HB4}9e>QqTWy>pBzT-(-p;kqk1uyg&h076HO> zr4juO-J9D$XcBzgy5S)V(TLH&xVjeAIa1Ul1vNeNE#4uZX+-7YD9JC-CJ_Q zTYk|zK?Hfgx=KJukSpXo?mtXh+7qWrP788NSKQiIZN?*aas@d<7zcKhpbeE8f-k8z z7}nG=xJ@c^G*YqSG44&8q&9G~`y+N*JI)+d@3@5O{)ApQSjAE7r&Ri2x#~D+KNu@E zw$YZFCq_0tjb02u)pX*d6Pb8ipF3IKvid8d8Wx;7uFA}QxF!1Nqu_=q_dfUW_EpXd1F|PqscC3eg3ipg;Zu2=riitJ;tchlu61aeTv@|%aY|K9$x1af)J2r zli%(?p!c81)tCT(Gim%cdQb>=4)Aw#Uvjltpc|<aAV41i=HQRoFR@zk zzr<>c^z>XvU@-_UeEV9!h$Ya(-)a26tA5917pGi>gAIRxg$+-?gP{y#oMRG41;jF= z!P3x7IHHEb!cwE**eirF#-ZGyx}!)i%G;wzc&Fn8Y`^V~&&P^`!=;7C#)43Jyx-p1 zb@Z?6b-d*|a7y6@+>Xb>24v6g&ga(7qk=cRwIhRf^{*>}N5?(z`rCV2@tKO5#rRr# zikr#dO^b!E@($h5(=#yEK7Sr>zq&}f^gJnWc4cKwJqwtT-62F>9pr8~)l6tEcbLeT zI#s+~X>B>xO`L11%Fk-4Q$4voU2U8<6l{=?z_b~UdO_SSo3%+`(41FI$&Qr@DCo(cNy1rlF^*v77&w^R(4{XJJ|M!x`afc70m z_e5O52O?bX2Gg%a1Z5&33d;}l$*lSN24?chdRpn>rQ*xN=*r z_S$i}F23zk7{6(IrM*l%F-#0qg2QW9(JF3{vzegME+-&$U2UXBiaTm5W7Qk63v1k~n z7&$4k263#7^pQnnvfF$NA24lPv2})h9CGB57cExo%~p=j^k&v&J1mrfhb30gC1+3! zsdR1!&6QuhbTDDmy~AG^{Y&s?G}Xr*5>yrx^vb=YZN;uY7x_sDr1~E1^zUG@|0hK_ zfZ-pNqNvyKPhT3th5rJRp6TDgtp697jh}YE5)5^9k5R#5Xx{K^`G5q?fT0E{3BDN# z3!{s{fpY5~y?wP~V&@6Lx8CCCbGZVt-`4xN0DRf#!UDqIz7c%;6)jvCzU2Oy65F}* zWKBu+TB1RF?{Olq1GnYk)s7-%#53LDG@A*I<3(EQRCMH+pa5v7Px0QikAKT^{B!IPEw{Y#i-M#5un=f9x@UZ8X=;%q{QTs_QLAI z^u%iKd1tcmw2j9cOT%1SMAOhwL&H!-h*jiUnnaR$lf=_YUJ|_aPiN21g}n`H_D-tL zME18dp?B7#C+o-XfdVQO8ufNFshu}X_RiV>o^&IRsjG~d_zNc!);1iBJAfPBq!^bb zH`n@A%cI>GyHNmmhz9g01~5>lMULJ-p#7gv7#3#czn-`VP0EQX$l(m#*f+KuYBE(I zC(s2Kpd0-tP)q)m>Q4)eg=d?oXvhI+z~dK>wQd6Xl2E)BCCV zJq8*L*)N|u_&CS@D8|I?^Z;}#=?71^AfZ1)Vn$i1Y4Ot0*}dbcU{d{TPsWI<404vw zv*frjlygBe5BVrR4x{YNO zjg4_G;NfHam?<2KlV7}*O2M+hMlzyjoH1nV6pW*+rLU)kMffX1#1h@VnjXVkR_INa zF*X;FFDM4$9|Osp2ks8Cwe4Z|GwlzV(`oPXQfRcr93D9A%eO1A5?@h`5lnmz`~ar> zL>$r}5a3UISTWyC-mFlbJvqFx4_>Lwduw!} zyufKzgeJtj>anHT_I~|L(`O1kOII+D9cIKJsZb8+CXZixW^Xd+UDfrY9XYGZNf6Vw z;)xDQ`=e2L~%9ku1d*mEE{?9 zPt;@*56{QWA(J!cSyZNHh8pgsw+!;C^cKZeH+6Y4 z>3klXEbtK@LP4fF8JdcV1%AxX;qZrxJY!UnUXg#z*nXX!1qdk-{IT-I2a*$K_YQ0y zH(HlK75N|$V#>L{M(IY^?i#HP2O)iBEGJ?6C2&nRyh#7OnaPy?iRLQhst zuawlJbQf#A+9!r(6@4t;6iR~i*ugVnHd2-%AGb}mz;YC&VSNkW3X+to6aKTVyrWt#^b=-`BnQ1BP#H0NEQ`(oB-;qXs3F*`|qO?kW z$>bpm-t03r^#L+Rhl=v8ro5MKjA~sr@Nh~zp9J#!6b2i14I3`dQdp#E$n>JN+QCBv zw4gDU2tz!Iy5YNOjyA`Q+EbE+kG z1ibN5X5a+C*pTL)p)knykul>QI4Gk4A$xRN% zE(z^yT6jLN9!n6Prd0}na!0Adl;oXj*I9g-1a**ItLkLr#JSZ25fB6Pd~Tghl)dkxZSV#2=%t?U)ss&a^ysL)l zd>H}hc)mbQ186HhNcLai!_W%eR8A<`-*Y3q@o$UNhQx=(CHN!)ko2Y|5;f$G8$4b&3L&jRpj)`K9r znb_bN6MU$LeMBMo@p(nBp>t+iUtSwLC6=2Ys>fh5kr?RtMxv3dfhLWJR_umbv7=$e zybD5$5!eRdDWHiFMdF%;J+3BXJe5~}${dEIRE@S-E0wBLENMZz(h2bVCVRbQg=uL+ zSgSp{7wNV$D_(lf=k`LU-%wX~T%fx_X8tyl{GHCzOCufJ-F(#}(zi0K0N2kLRK=nY zrJJv6KMX_94!zKJGs9-Bilf3f(;nfzYI|~TgunBkp$kZrk1k=McOCv58q*8f0g`U zPx?2m{ug738lqt59z+Zs7;ipSwC+8!p6)M$ee#M^06qO86Ft4%BwaD}sN@v6+_dPT zB7J>5U`dXik-l2dW?YJ9R8o3e;aZA%M07%m8raSb)%PxrNkM`V4Pe12E)HFO|L_$S z{D5p9_HY|EdjW7n9c7YWMD>*qQwSTCS3q6Ay%R@$L$+5y>$X|~jhlRF0WTma5rXb~ zp(qh@;T2(Epf>=zi^5w!BT0tzIOQE#*Ug`mwzyJu>Xa*|6k0iY=7&pXvvLP z`Ozb`zfwIW<57kSh`~cb?cm!U3k0|W)g*zHd>`xf>8knx2*R_Nh;%Yi*()x0sR#tm zrDF>DhH(r*0yjBl2G$FA${uW3^+q!&9arprbuYq7C`dy^D=uj#`?O@PF+d@D zE+Eim3f8#9Y~AS6Q=|M2rX~!OYkkH_XXGb9P=wvdb~z^sScHLJs=bk{GkfFIL%UQR`wpE7kPFJ!B2b zB#!VmLfhv@Cc#%$(t)CB-0r0;WFdJ-y36yp4O_hB4yN%e{SHZ7CdENAvSeF#ypb|x zA&C7T6O9^TsOc0~QX&PZ|D2>9DRJxfbhIG+usU1GZ=?V`ET6g{#1a1)UkdVCO(s8c zbKJS(qiijK%)3m?bZ!pQdju|e01TcZDLBSBZ;m&)evW81^YvHn{GfZBdz;aaU^bT5 z5|g4D$O_aZFNUaRl1T&zY|t=g+U!uYCT={AoE#WUdAF178_1wyR2rNf>U3vV+yK=ZCK8E?FV14Xx2G9g6b=Zyu6jF1f>#wX z@>~E24KtBgLX}2*-oS3y?{T|_hoWXa)W#V?LjoDZ8p-!(HEY}r`v^hFHJGz^0SvOZ ze1IS34lBPiKgD$n4*Fa)zTx@tNZquYfbV<_5e{D}udopKxEz@~Bv|&Z_3H&4FWk#b zO}b++^S-92ptkE|MS@d(a26Rf`c%q(yK+R+65%~*X8Ck8U!0E8SZkF9QJqrZRauV@ zcV}ledlyEnc04?*D|neAFPgx;s5qxNIS$K$x#x+yBc6ofkr9pLMA2;FQS^I~U63LY zA^=22jTcS5QY|#IR=eSXgl@`CX=UE?zEp z=-SDHFS=YS4~Vnoq)u3{X+ay{y;VZXVXETDd9?cTDvebb3S1KlVTbtY7 z;*4N?{l?5(QR4^|6_rZ9()Uf+ry`ZQk;Ms}s*)I}E;w{gHtpjMtp%ELtf;HsZG($-m;?{1GLUr}&f%ULqh!S*EYSu$Cq1a)a=7bALq z3|=u#r($;Gj14nwADE7Kc%=Ri-n+)z(&vrn-R>OX;&mxcOMpJxy07h^{z%rQX@CQ@ z;P4l4^E+T%$W7ZWeZyC%TI>J$@IIdxi!zQ+E%$wC+OYYDKPwM`O~|tNE287VQFw{t z`yPH+sgKTGxV&3^wO;nCYI{$sa$&NqaFY70(ne=%=*1lO_!Y2er1A1Xp8zsQUO(?n zWbJR=x_Y3psze@(wWsbyEOb#rmm`UHW%i}z9Cc!oK(eUoX#S;xATH@bp)5<2F1VtYs1g^F1LzQERF84L=43lpD*Ju4R+Tm zb$Tn|o{42QXIJDLM~Nb-QcBcQU>rY{ybnDD+rLK^%#$`L2`U+I>PwQj3Fndw(1$1J zr8(C2gv2pE-f_5i2Xrmim0yokg~qVG1bjCULr@D?TzakE#>$*^#CN;8(X}ia;>zVS z>GlcC8Xe>xR+-q#2+88am@bvdYJ?N6Uj)T9_8isae(Qcv>jRnSRUGtjQKv{KWRE+Y zDH9xRJ+)Wc6KYF1M&b|0!_#QMF$LYF-w#txqZ@~+N!6l#C`@IQp!o!)O4WRD-wm8I z|1=k14?X-7#_T=}lr0@Fqi+=&J>f6}R;#H1O5 z!^|QHVGz1%nQT!*=wfShUee`w)7k6A9qZraD>RH@>c6jfH(>H9oyd@#j&mb2@A$|jv z2Xi*pcW$niw<>V0X+kd~ti~*(>$w=g*!PzAfw|Uj34^3EL991Bm*;))w}k+Ub+%;p^v0Sd-pZWG#*#X4 z$3H*kGjO7Q4`PUQ?7Js$+<24-oNvkAD^YqF{;0Q*JxZN#sD8?uY%1Q9IGm47oN=~y zsD84j_qr7c;vD%%FHS|t#N2`7VDZPZ(Xs{MB$dXY6O~K1^nYI9ShlS^kIPvWO;LB(fLXz=p1 zv3*0v>*PVl{b|&xXSJFwk$e9K>eS!}EWtux_A0XZ@jf@FC(*KY!TXDSYPtp9#$t8m zAG%-Z-EE`RMztl^AWTSJ@Uu8HM;|hiah2QbrlrR>zse!2$E)hd_FlxsCb?l48`BYP z;QFj{SJpk#8ppH}26|r36As>xGLZby?q{pAozdLXPs(dyj&VHvQOkq%aF z!(zvOC667mIzmbYx9{N>p%fnqv@~1O{T!k;^ey%__{2oVKUzq3%h{TKP0FMzy_;bi zQ&-E$kUN)r8$c5J6g(Ks= znH69X#WJxd`ltj5jJ;5n^Ej8LssMHF{TI_sc{~5ht=YtUiIw7ZHKzWN7=O(?BCUMTD>=-qJC#L8ckf@ zKVMt4H{r4};fDJUZG@gUu0>L^q@Zc5@3abTMSWkhr)sQot7%}4ggT|9yPZKcFUL6h ztrzH-T4_qQIE*MjrJ2-?!jGkZ%hBEUaQNV!Sk+`~y(Mj3w3IaWVxB)g7o`&S^4fE- z_1!SKZ)9yn(ni{=%ZK2sOm=Bo)KO|5>z%}WrFTEoFxEI^_DJ2TtQL?^P_iyiqB$n2 zm{@61*`k@}MRb6!PTwL}a$+r}7CBL2k*HsXlUB1DzF=5ROXPt0WlhjZJg+rKB59*u zF&z0R@rYS5#o@lVQwN{r_*~v+jQjKKT1{k_gMYE6{`W9PA`8O5u6*;d^gbb8vsS(T zy$)tz{L8udf02Auc|#*Qd24G2{D0k%rxUX>vc~^c`qS7v$qx)t@{PluO#?J(iY(dvs%;L5aT+F{M?D(KEj@5hFt(A%zGo z!xAT+#tq$$zK$HF>D)36633zM0Z8(b4Psbk`C3I0PDngwWxk09!^X)mO83(L)>r+O z6-0@hLO5rDj;X`pz2AK@T_3I4dj{dp=4sOXnI93gb4#hn!c=J%X{l^0DMp;Qxj z)?Sj77pxV-vqdDc{Y6{qRG`Wun?Ufp&`$qOLn(4Y_Y@-Pk(tWIy`Z%Jq@@%Z16YZf z7Dgee>IuNz98%UEyr#%3DyZ1d{Qjwki>FuW%Jor-bsaCuyz8Q|;E$12idm(t1hZLQ zs@!f}!g9SM*AOQ?E9IUa1tuB|8%w~*KR67QLX5;Ha5xO2Mo484A$U`#KmH^2j{WrC dk+*mFW#`~*XJ`b?!o97h+@ka5{4;!6Jc&?h|ipiEo}TbG4{ zkV5MU5<#&UCu5GjFMF!tC@AahYVw<2V`dqJr!UCQ_AA4zmaA(F~?<@7Zx z=a7FH-P&4@Rns_YVuQoMSFKDE$Dw8HpzTuDR1yW8{nJ8%c;^&MyqPQB{%M)mTF;ET z&9Vs%;9;WQPZ+%BOxYCj^!|(;9r4gsB0uPz3co$~$jpU20p;_RjdMbzs4E=$73P6^ z9duTxul5;+G$_#6kc7#N0AZa!LL7W>U>9f|wDvyxcds|Hk&)Zm(fd3{3Y#WbaE3_n zXpbSP&#Hkw0bj2%rj|UJD*7$tm`H`ueNi08nz+D2)9_Zukd229WNAMW@~aPAir6m_ zWVdz0kGyhpSQFTv?$jJU9rbo$h^*nkf^mNXvL48s>r>Fun~n%R|FnRh#>y!EaKg?m zH|Vq85JwUC+<|tPe%ihF&UO7Y?QkbuU#uQq3rVXDy>6W>$ERx;= zm!7XyM}vU!5(2|Rcch}-93A9lLdnRSQdi)u{HR+zQA@N%uKc11-pNPy8XINc&pUA_ z<~$OFBg!xX#24VWUJQ(5U|$mxs@? zwHhU7un%2ThNvSEo05gIa+#Rt=v`;(pt(oFr;<$-PTmD4j$Au~He)yrAUZr)nLPG& zPq4}FOd^FErTQiWN}&5v6RHK(g#w9(J(BoykL^eTB$QY&<`M2mRn0|(A4YjU>}A3= zwbKCW%|Rhe0ub~oa^l#{^yRIgV_e#Z=`3d zJaDUq%X&Q@=X?QV>N;#>k!bmOnj;SM5|{84nyb5lkk`S==snWf1N6XrStGy;zW06VggKLK0y1op`? z^+8>M8>+${Hg#O=GhF@{rY;ShK?avdsxqJU%(HTsPQKFDs%RSkw_hmN_1B2^?~w{r z2|UG}MH;m@eu{MLu%{1$K6PrT(q#B~or)4|VJ9g;JE_14O7w|$*XPJidzo93?e0vK znc;-7OND(IOPEDPBqz|Ud-;>l(xRwSAu4tPY9Y<%WQS-*UhyZ?a!O^HOr#jNpG+yAxdF^Swm)i4VHgZ zG57wxh1^)|4#MTfp&>O>?=O%-8nnP`VfihU{K#lYk?-8uoHvzUnC^=v-O20M%luYP ztKv;mQSVtcTuVD1xH2OPuG04{$aoY=i(6n;%E_hdTzeXf0_3B(Dy}?}QyIIliGN73 z+!!b0aXt-Sq6r9?bi=Vw&%%*axK0*-&HB4hK*&?zXYLO*TOJyW6QCSR{8R@6USA%b zRS1%WH*v_%y)M?t>@1F?fsHGB=y9l-^HfHtLXxv0Mj?6VV?AH1Q!jZp*PIUX{>`Ku zuZrWhWJ|||9zT6D|D3Ke2a6N5rVlS1wA)bFe_(aEE#$UX3eLq)jWNz&;>*T5Z}$s7 zhE#4}Q(y5*R|EUoJ>GZ<8E{;8S1iJVF@1knv0fm2WXp=*riCg_EGD*ZCt8F*mzbxU z&xS=EX<3Ymwr8hnA*FDac*3L)#xmMDdq}D8>H^j;eb{9xeAi5!y4bgBJQ1?&tIY&S zdPzO@%nhz>3)xHs3osb+VUju=LsSul+J_$2EEd|Ov%8kWUvHY3mN!e27PmGrbI#b$ zCk^V(iYL2H>f07xnnTuJl25)Ud?sf%x1?!{Mv}h_{MUrSyqrv<7&&LrP(!x2Y2F`r z{G;ITU3DfLI#?WKucOst9?69696?pbWa#eqOOaU2;;{hAbDeP*y zWTebHsOqA!r>cZknrHN@-a>3jw2sZ`SrXs9l=DtdY^=GN5**u#sxSLI>v31aIfbkI zycBLYsIHif_lLrssbGK=Em?!nQZ)<@_{v$6i7}7zX z$R4_C?5_;I+CPonQUb3ISYTYGIPewACN!L7`iS+TB+jP(;urN7qDpCRZXBWRSZ@{Z z8?$qkKI_>))B`)qk=ZzItDt5h^T*Ew3s=70i!kpzYWm%HEdV>u9Xoe%3G$vMN^KPB z&EQ@3@AeRF1_dUJ!E=4CX_b!Ua-Y~1Jdt$Y?ZK~t-}Vv^=K)7MxxBi#z25JH3V-M! zT%e-;kME;4fp2I?&F7!zuG^oA-QNd^0Y5Cb-5XD%rs4el8IZm1PqFW(pBPe@QufTm zhmw)3i|bl*A{MU$ zx#yGS;V-V6@WqD+rEPf z-H{7uDzk+Q?L%5eQS)_*=9u@pPj{>Z^(Kcu|p8C$F5@0?_Y)$)4RoP*gwNw4|SCf@X!9g9V2*eZq=1kBob{K zu84OkZS5lRWOMuuC?d13GJS*sdnM(yT8JJJY zJ3Wgoq2i%+YH)CjX6A9UP>O=~aY$|IRgXHOiQRy7Jn0UC3uT*6h&ckR_51GH$&*x%b? zoG$`TpMor$yd@CwYjic}Ytu={(Ea`QgVv~BHGvgHk|edcunVKdeSpr!ppFGIBq$d} z{9Mt!T=OmE`@e)MZUOy&`F>QAibKKpiB}3Tb1ftR@MZt9JnidDWH)Zu@*$%Ne2u60 zxtFIGc_V#~ge-aveZ-oNEp%b6m_3@1^THYidg48FcYdqSo)64@o49>Zi}Is&ydRYn z-6ZCrcg==cFJt{xBx;$h-Z9QXZG04btBd4Km2q(-nTtV^|8<#)fvJFI!+%vrR=mcB z77`hFq&~Tl`|WXdnKTP4&w>_@ppUf3sIAhm-B@$)o)Hiqfl@4SHTJUU{2@!x= zg84%imfnhIn7J2yR^FYl3B{Bf19Pgv8`pJb4sU7NWqenN5Z%!6M@LW!3XfeF6&$js zcZLD`xRuJ0mz>OYL0}7M8Sium14q8 zl}R!cLcx+TJR;{W>8cJjZP;r!qswP)bmnLj=1M_#lp-Yx&9dY#yu=_)!jtKGo5<+z zor(vwa%m6%8=bsjJ%vc30uVaX@ zyFj~(I{W4&=f{J9dGpuXZJr+pCoSxi7hl$N1E5`U%J%GV0;&%7V)>KGc@RW>zM!p& z5}kRsu=^V*mK!4&_H|S>uL0O*fHW%F6@U_v5}vD{)_@_yRqg6)35g&L;7dkZmLkWC zT8ZWvQB*OZih`J zFK!`s=+FHJuupRA&pLWxM|t%k;}0Opx2=f@PZ;Ob>=grlL|zTkLtjr0-ifb|*>3yd9@{ z{JyD-(-#fbY|T5;6Zq=VH!}aII)&s(Lf8S5U0u4Xrd4h|2JM%0m^lHSW}59+dG98D zdTMQU$rC*kgCI9F$f^Ci`1{%3uFV$f>+bE7@wB-r;b$Nadvf=P-6RUbJe|9C#|~GW z^)Un;skqm;C>(d4#|QXK%|S*dh(T2yJ+#LNyJA#o)Ap5T4ayfFmt5RGFliLo(N@)9 zX$w3ln#nY59lM)!4h3QB7Y!gbx|R2pywCd+%&HeZe@5?i#Wlu~AXnXJx=n9ws_i=d z!6W``Vw-t0DcmlZO?pdUdU!5W-Gyfz5TWqe85p$wST$&Xr2Ol6VV#*{BY0=}=ukJH zL>~Jw&h;%p76>oTQM=^v@EH9Tr%&)}!x!Z~0Ngh0&_D9$jBC)+9s`sz+Cd0OF5Ksl za|htKan2Ev7uMLtts&FpM)qI=gMFv!7s%z}S|ZlugtPiknEe7n=j)0@J{CNFF)!jf zXSzgHTygIu?!~*usxi8DXViblx|Ftw&YXJFh3J2V_covS-us&t{|Fg_+^W(!DB(Ef27?A=xS35++2B{FliE&9)- zT(ut@=QJn`u^nR@3SpVX^7GB;{hj#*7WvLX|6g#)@n7MRm5J$p;8IH}4xbIF_mSq~ zO+15r7gN$vFc1_{bQq7=#L-_=QWT&--#=G2skQZerTgHS2q_FzqUYvO<+$>yy20X& zwJvxdz>dX_B@)JgIK<&Ll(tt9pmf1N~sR~ zc#?(nIkNMP6EX0z1N~MN>5)bOy*OBWeX&ZO4+$oZlz86D!{L(zi8*qcG)}hP5X@u* zWg*ve&)CBefg;WyBL&WcAui1fVfR3jUgF<3_p^q?4MD9vD64RtWJOF5RH#>yGgsK@ zq9kq%CtMvBdeiU{YmOxFGcO-NKCnj+CQ}U$rOu{Py{|2R4XR3aZYaF(!!@!$AG2Rk znIfVsFdawH*ij~6ekP(8%dpH$L|-b_W`{7e-sEXsfDYPE?A>Drz_coTUC3Ipr!Rlu z%2sL~v@=>zXx5L#VcgJaLWMCb_D7qcCo3?*Ac4N(gb)J}5%~&_!yjNW!5EeF9;}8L zg%8fw?&r$2pOJAKN5Z^fF(TiyJZhsd>^De z{(5dZFofeIl za-Rs_8mmT5k`amF3r_#%VrYmovJMh`4rJ7cXk-gLdc4Aj+5%=Y7-yhvFntruv=!2D zmSqlIz?fXGKE~bKgUb)6@5uAT zW*?t|*P3b={BU5fzh5DKhS`TG0M8)2QE|n=u>@zcs+^cHsMqjF!x360FEs6%6t>7m zw@_~YXK=G*(%zy+rTlSLQE(xRDyynRyi;5y!uwTfk!+ZM`FJ1HWbD!$1X84iFcEVV zk2@O=>ft!VaXcDuVpkx*M6fRDXK2`(jT`j)2>#KO^&LM>UT=iDE;`9ok*#DRucwl7 zFwbiBXD$6LNsmUlo@*z=DvTW(#e3u{@+2AEOwy`!h=>4kh%}1Q0j8U(d#U;7!i+L0 zyO^|R*qC0n0Z?a@G~--pK`l9?eDZQ8?#&EggO1_6_78|Nwk@f0dsl^2M1FSBX>8iS z*TNb?Mx_?tW^2K6Ef#^j+>LeE`6$A4MB9YAZ}>a$yGE_WI>f+a-eHK@*SgN}5S?WD z0Zo$cs!68C`rP=KBc|MP_&8ohd{u{J2z7-<4FXRF)_d!3-%wAg*Sr*XR*ku{jhK58 zH#>`#&1k>*1~o&b_>{>ER*^nq^u;5m{=3CwqIE)3$XlZTMdc#Y9U;IwgS2o+1xM7B*$}f;t7eGhw}06aZmQ`2xaKjaQbg8@OY%B5Bz$Wi;)p`vA`MMxvl)n#b)dD z5y{0(PxZk;+pA5BL-8!r^oUrW%`%J*S|5+@? zeycs}4ty*fMN?$BhJN-4Mq2Aul_`c51}~cO6(HU~5k91gO2+qb%xifnPal8b)EBQ6 zPQba94Scnm{rhU&PZJQ$v8^zzROvp{8YK3g$5oVEe46fzYHZB32UETSeCm%okW-c^ zx}bWF*om{_KsSpTjGhu>TgGbK_5zgckHuI3S`HOsYoBC5J<<_EjZz|OL&;-UJ63Kk zZ`&#=i~J;4s-%##`+i$7i^;4w0raf#}?KX4VX3)i)fAYxgkm- zw!m|KxO8a!9irZUDx*p?MofDh)r_OH^~@MH6gwd$lwN{VlgTe$J1Qa`<{#tg?EHRA z7mC`#%G(ebP8aC26Hq%NTs0dagwc_L^zENoZIT?F)R4IjTqC-3eYNgG0R8N)GOYfX~#R%P>Xoa&_jX?r7 z8G3+9v#B)^+oX?9OjDrGlI}^Tj9JP#&DK1%uS$>Lv!M@Wn5OJfz6;<1SGI23wB>e< zPA(Pen3XJ%oeR~xDZiCiahN6QG)p8{T4mcq5W@tMi^h0oyeV(AzS_U!DUuHoCFm%< zkP6vCSaJ-WtSoFn*2KA>F7BlrD7hVv@!a=-PpMemw!JbCNW2avu6-5E0_dr;8AHHa@wXpH@qwW2#VR*#3+~pX49;4z@e9^ zi#U60vepJjr^pwxJ7EC2gKganyR#2+5GwW;*Y1$Q&o))>zuh6In(E#!oKZh6n03%X z|BYF3O}Sy#RWpLU2G~5;;tkLQ#D8aG-7ohI(zED_hU+vAkSRn(k2U8)GQKu#0v4A(pXn9 zQqM)&3{;nIx6kyJVE7`8NXn>qVyw`mr$ViMxSHZY<$%k+jkZsD`U_MiFpcg_Gt95m zKUeLAXYC=>GaI=-dme2VTJNQXG+iG8P?n65m5^C{aDua~LYWq^Jo7=$XU~k~ZYtGxdMv0TOUgb~l^AhJ;+lNd0$zK>m6~ z;6t)E0((dL`Tix1inDFhT9j;R`a2yfF55Wa>HU1g|K;iriuk*)KQf@{`*y!{u!R^V z@S{rL&ocLYFf<2Ql93dav@m@!6qe`9nOl-5KX_<|?)$VfhUf?Dq|E|}_ef70J@lJf zC(;i4h{51>IwN%G$GKm{+usapk1?7znQr%hwG|6oD%LwO7bI(5>fHNvso!ZNm^Shc zDtlrCx)UDe)Tj5ymT`yC_ThvDGDG4`7$gXc8<>SU_T8j;=uYZQ1l#FUIL>u3J^)e8 zV*KvbTjMp&qG)c&DV+@4cuGR&-TgFM{x221KACmXqIHwfbv=r!`}v>#sT9r>B0c#x zs4Z{SEpJlxCii#JVliZa0OL&7w5YNqXI}3`@~`zKR^qSI14tKazp19?gQisvxM1v6 zg2(Z@80e;Eca&4kr5`~BIf-{4GPY3Y4XGGByfLOToC2<+Z(z5H2iMq(FK6Gvo&#Ie zHzwX3;fN;=-?&HnTk0Euyk98#S-IwU3yfKIcVA7hvJ426U5!uehy z7~3eYHXv!NY?srsq6@;7AZ+pRh1wq9c!Z#*mkc22~m>%lHl=7j-)7_@D{FA5os{{^C zocuN>Xes9*DxtLeAPJIEKVWJ-&r33f9B6Vpm>qZcH7xlJZhXG@tbN}6e(Y)SnWuG} zACypzF3wsUQ5?G-!mOqZru(`rEIr8JP;)QGL;b=6EsP@AOPDNePo2zr!w{<-NAg(6 zDpx^vMNWk(T_flcnd5<&DG97$D=JY+frkk_Xz@KrWq!b3L>PE@hKs|8AawlP{mPSWAA+C@g}ah6(I(- zseV2R0~rqt&mASUJ~!Ts!|aqlZcQt41qofHgOc~U69frXBZLVlN`U>1*aHt|&ynUm zf2Fx>y-4xnpk0` zDTW3cUdF1ZXxmwtS*DP?jPw>aZ+W7FIKM##OE_YLi#te?(GY~-!~)5=?6xmARrr)y ztvK&Exo`mgi-Qnpx3s{$YblWs=|0q5vGL?hG0hdFPJwzom;GNh3xehjXrjs&WQ6~G zTHzT8ef#1VH}f=<-uE)Jw1ILER93M?sXl@5`yl2?G7G>b;~%{!h+mBn_aOkc7kNBn zHu6DD`qO4eSkff}(USV;B}4Iw6O#>=>Sj(q0n*viCf+$^O0|2Eupw3p;j53NRK)`< z_%+QTe7$tW0DMJ)%Mc5bJr>&>4dGi=Vg&y}Q2`aQJCu)`-%xt^X)RPMp$iBeag3Kk zVRth}2bv2WLeehjv*VpI-)l*=<2eaX-@nYM_3*m;!2D4RIrC}uxOsvVFT9v5V_?msw~8B=%( z-rmq7S4++q`QI7+5OFO({{r=V8W8w|B5VgEGMT*$7=kdUMRy}!^K3T}8Y3(0Z&OI7 zT`NR;zR1hmm=E$TdEy8RD)E+&L#xT+6VXID?A=BIRT(~)IMFvH zy!e**Kwx(q)oC&YudK=S`aq`0Ma51PX&wemSQRN<#E7aVVk3W20F_y2nga-Ha}zvx zJ!c}u-!qB|WKx_2LZUenb6L96lNH@^YCJ{WEC4SXcwwaHts3KXaD zH16OC5t~j`={R`2D%QS3S@qdSJr!Pmu`GZ5Ht6V&noP@q7~nB_0$$T?*NuLw+ZCJp zPzw|`Ej|=y15a7p`~d5!1(>u)m27NuwNH<#NvmfyxXfBG$%K zBEERyqnm0lj)~Q^tF>i9(NGtw8bfJb!ngywhxw+S^M^`dH=pys> znt|>6HXx9ujIzzOr2{S0dz#vzge1^)QSnwZM=fW>11o#0ale%-a9c-! zeWrk&Wo1EiSgM5%FO|YX1Cs6>4}f6mV%J_9is_}F6Cax68~NoOl`9|qJX`c+RW93R zR8B+o@%AO8-*BB~b#)@QEcTO5H;$$z@F*f+8^e4f55O|NuLl&U9PMq}pI=%he>39a#DAQ+>!B4(T4{LfK2j7BM-L*dS zI7pi2IzDQhtJLT(1G#@U|MVt8YR`FWl#TCCseB{JCPUGP9xXq2*3i@Fg}a?3j-#7=nn zkVp_Wr3gMk=;D?KZu%BsnNzpA#PaCW9;P9j8~T9GOf8DQ#_!2IVBwiWJf5hUT8pQ` zAmC2#8$SR;@X10or5efNp4n#{SYKZQo9pt-PTK0GtMbUv`hs}&pk+Ia0$rDYof!(G zQUKT;!~hLsOZk%!AaXhq*dJpSfT)l1D(@m1fyCojHBdkm0H3g#o`4UyO~DGoSpi2i zhm_}7wAffKo1=SeZO-aDEE&NXuB;)ydWdNH%_q5hqMGBa9K>*txSfByFy|S=hy}y!Z zZk-l1!+IV$(=iA%kDM-Wwek?2({%q*2pV5Oa1G$IWW`lP0`c!+v2K9jwC+T=B+pWhRh35dN1 zK~LEh_#G+k{UMW#29C6x{`ItP78uhPU`{{OBF)>;>W0++0pWhk@JY$#G(a=ksUGMr z22#aLw*4$Kr>Su^fGMdY5U+7uWQbG%rq-<-L4;j3~bJs!89GoZ^ylcch zW~#{pS*pNfDjh23LlV}`W3Gvkrf4So%@XZgW6=$pPVP<8t5kuqYqrP+@=N;EMp5M!J{ql0J4ad#Hsz5fRf~Z4xN56HaagE zM6|KVn^m1Cl2kJXw+Kyp1ZykiG>^BMq?T&}`q;LadP+DRb4=(na}7b16Uei4Uz`St zP4Quz$@Gvnx}l2`aa6lvx%hEW%MufODTp6S(!GwyMw%=oHEaPal}r+v&=|N$k&^oU zQ(7kKMx%XXC#$a%za&?0syuSdd{63XWVTpY(=3vgi46CB;i^U{q{SwjWtn#j4dfL_ zL(;yqS;k$^bW zyk`)QhWf8jGs@eT1BhdBpn{G5v+ZDu0t_XxKft=IDm5ynLP>h9i>5MiXf zGiraw(%qe{`ILL=&+{i1&n}Cr`vgceTk#$ikFl{nCE}`~#2@kw!$S^a9@huT?fr$B z^#Y}MDJVy()!lmz#h0mrt+$M#qwo3PH(}3+5l*Q~xP1UCO97%@j0d#j)~S0} zCbpOcCGb`M-KTvr7X0u^qNTouw<;Mgs;9vata|D2U^EX185Uwnev`9pHJbk!UyGmJ zXpvpXceCbzdMeL?>NLtg4gB<{)nA$p8UYGuoj9<9LU`UO8gsNXt&%lE7beCt9gdoU_}c`zzpw8}N( z3}Zrmz)e_+R|#^puGojP?AW)nuqR&;lQy8@{9eW11klOjAg7=Juk4)7L@`w0! z##pD-u4J+Iz^URKdRG{}YB~p`O@_stZqbC0|8BZMZGe+{@)5J)-20-dyG_@@-jNk13poP45+U&TPY? zU;2+m0uimc-RTgnDiun)^gX_E&aGnab8faM#LqgNMoY1tr&D#+;8{Q8X+Hs~lY~?*MDIYLzA>_kQA8DTV#uiD$jD32fgTM7QuXO)d?sph- zo@tNNj5G1apifhAL9cN5wcrr=Am)BF;zS==PN@AZ3*_HQMY*rHf3-EmTRIuLZt7+ z7HOaDXleTb+yT!WcJ{ zLEww+37`NIb}`T;6S$~INrt)H4_ZC7rcc-9;H(QCOBk765d&{Q{(q}+F^QQP1LR8P zGiIXZla+{7Jug^e=cy(@@So~1ay0w#{DRPoH1J%Ya;T~d9x}C6=<(p_x9oS{6)p5+ zeYQ)Vh>^e}-yK4thq9o$T@bn4P%7t5HXb>L5H6Lqp?~G(m$kAA;mTNpt9viIS3Gut zB@%V#T2|+mzbY+3soB*wv(Jf@L`-!Xw>RHl>+^me^?uC_wA!{>z?AvP&J4ci-*V8P zTX0#mFtc<<>16q1l^7SOaOxZmM@F*7%zix_@87PI%Hrzkd~v9BX?3#71Cy&+Z7r#p zQPAG49(KTmn`N`We7bb4uu{Z=_}LTBzZ<(;HJVoI)hby4FPJ-RY!sgMEK%sZKHmzC zDqK(}%=jQEduqHk@Ur zcT?dU-&dRQ-(B2|-g^2(qWNBPP-!X>VSySJS}80@PIjfsWC(PY(?yztu_-B(SHMl` zjfQHb3Q+S^F|~^tey-sw?qp>F>`bOMhreEYaY?GD1^`SgIA2alfAh* z`nuZRu4jlU+7^!|96jC+cLx`rpO+J|UH-n#(Wo|tIi$OXubmCVx2rFX$@$ZM{_a+L=zft&kJ-}02+B$t=?MDokWug#+91MypU}+CA zoEHn~enVA#x;lLZ=M|gb`dlXibaDM$)STwXr3^5uTxcc#KCXibDGM8XgG3b|#yYjy z)|s0*E?M$BZD%vHJySa?b9_5Us7 zNlU`L#r>@)QC&w*!@aDvnW`mnpLsrV2M6vJmyTz&UCS^#NbY)3?NJ&3yAcaCLtXSw zbW~y9JfUnZdA~#D9X)@I76ZMTToRb;FxA)F)93h9mclerQS;D`!@1f5ZFWpvNR87h zsR#b(V7HE`l5VXcr=h16JhIvgx5SQV>44r(r)lh|C?wr=3&Qoi+s%Y5(2g=Fsf+1M zIUdnWQ<4cfF(_=$kaWBVC_g!Z{c+dSw&Y`fi;ZXY4j0a5(s`FDXBefK5Y$86hjZ7nBw8E;XcmtAR^HddfD!i zRhwaQW!CG1QZxpu;J(CMhwSj7iGF?VD2ro%T97ny)e-8~lzf#Zh>xYp+KzCkA;hFp zqFR>?DW@6Xibdv)M-k1$dfIYd4MU<3E9|JDb%p1HQar$Vp+*BGS7zHN)RuNhB#9BM z@>XQX0dod$1!61`ZXj0!;u+%~bgKN@stQmHE-NG{@zH0=^=L50f9(568c;D!)+Lme zvUm#dZ-I_TDwzOQ#8ARRn+tO9s1k5E z@19?K@8zkPiA80BPEVQIP5Sf>KZS;L<73%tpsly-v9iHd7@V_Y;Epuw97L z6JWsxM;i9`t*$mkfz#n5_902_Wg&An)(I57|FZxbKDk2J&j95?f`XaGezY05`pXBs zq>h*sytxjG7G%&mx~Je=>o8O!ANLpA00Glz=~Vo&@P`8AnD~_uWlwOwo6!q3(Dl6x zp2PwIPRx>bBP~k&if5Y=(AU_NDt9rsD|Q~q4*_U+WzslWrCGgynL+uR`kpJze$6uf+5L4^So6Y#2!)3h6iMZ-W zV~zDFrvU$u&G8oL63}2w**H zNNW@Qhc3!^FAA*?c8e}Kv?_oxSvlXW#3O(DQ`e)e>>?Vzh z6R`D}X$(2an?oN;IrDtb1*rsxFRKz@41P6utPz-8hc)y5p-MzqpK{UrN5Lq(r3sy? z*qpOAx{MaD28Rs;^ww6!XG0Nb6k1fvYa+>~%Rg6H$X<9y4)4^CLfvR!eo%n|(1F)N zNa$cNpTW@uO8#kRFH{rN0M=ZUfilIzti8o7EWywfTmhk^y{}HnjG&r1>!u72l6c}~ zU7cjmww|yAq3EC1!@9t@x)MrHRFWz0K}uzBHb;y5w0?^pFScNVNx0B|X%*i1hg*uy zh8H*bDRr7|lt=ljMR{Rfz(U?BN8lA2h~Gp0CLG9TS>@hLjF5Lfj(R-h92yHlpVM4^ z6v0WY-lD+*1Vq(kNIz%(cEZ~eOEK>h|}|BN1fmcl9S*TkrixVKL;zin*2-F-~+ zaAU=Eu4{TDXxdqijKfF~9tM^{mqs=ZnJW~H--sWD|M`5FqrUIc-gT#OkgR9!-RQs#Op z>)CJ{{SmgBHW@3+4*F|tu(WnfN2?Ir)CJ!%JDu8}I%K)}Ts6Qh3d`36k1ae(HvHxk z5C46uC3rf}L{B(HBQVKNxPsuUnVvLHG)KV^NhfULMeuB#u*Hp-!!#n+-K4bxfq;_f z8M$2!U~~?4(>u4LHC4 z5qIy|dk$Lt=VaVu!oWtC|3r~v$^}d~=z5OznL~+*ST#L^A_0D^;$PrtKwmCR{e%>C zmEl=%DDf5CJq1z9KC}?_n}+5WaYX|4kQ~mM1j5ja$z_5rQ3` z4oKV(8UFfXX!@r?US#-i_URXrNxH7plqu5@L24@tF5Zy8IqmQW7a(B3xY95%O{y1a zPM(=Flfx&Mx>aP{!6lhmG@`;VGh`b#Zx-nr&BH|%7D>-_=PS?sly&}IYvQZ5@OGl> zl3bLnOo78Nb<@_R+k;{N(`)h$U8MK!i zX2HgjR@(<{p%lWwzwK?9fPyZ1a(B^Whg`lUKIRo>^?L zc}Q9GJc;JxJ51)cDY+$Kw~PK}?cjAS$#E_$O>Z&MzUiW9yI=URt~nJHLa%?N~gzu|3%(VQr*dPE|Osuc3$Ypxk%P2q=g}hB9(28;s#IxD_{7;(p!@9 zIqg8Wg;pk0?SNSN7S) zO+URb+QMytS>%JQ0cD<{|)VBFoD?!pHntkUF z3@iAiSUjs;0LUd?B*y>YbFfwpe#F59-zW!GJ{ZQFL2tuEWPZQHhO+j{%`boP_; zklmC%3NcN38ZL@z=10B<1Hew7%Fyv)pKIo3>OfJHxr90qWFo-`~@hJ2>Dq& z)OVDX_5EP@y0&<~gkk>uyYq2j!8HMF@6x$h6u`{$_4TzEAgMcB4ug&HZT&g`^N+%^ ze61jTfre9WF}|0M-Ih(^Q&lM-rSt|Gh6?6FrGcQv@#rArQ%H==vwApvjCLWfV^0AI z=A!L`Nk?c4=jf>gf*Y#qqQ@m5tv(`I7U}?>kH?X-%F0{JZvg{!NC%u)P$U5z9kx1q zXw)JeQg?uKM|7gix&RP+nv@dbX_&rwm^iQ0q;VTEp4P4eO7e?LqH@E!I5oMGv0Ik- z0_kMHkcX~d$9NLk2_>mJ8Nrqv1Ckq_0N;mT-(hfzIC}9TO=r$D<#Etw3hW^TMJGvY z1F#1t2xOZ6cbq|OFX$r&g8+enKrf`#{RsVoSnus}2M2Z=B*kte=sD#5AAwCsqmuit zufN^hG6Xp9H^ieiImHAN{yy2?tU#x?I+FgD?+idxd9|Id2JfctoLQ4?9BEi1;lhtA zFvZ%W!2N<0^~oXV06DPzoj~tAqT#A*@z#(a6zpPPhdBM@4rX1zjx9qgN>^83z_4eh zc+dH{As-2LoeJ&B1++PZ9tUuEPq#qH4HWRSAda2*N#ecT_o7wmrD=D@%8(Q?)xPCY$m`#D+Nv zas++4krfb?8QD?$($RgkF04Nz)6eC~O8#!l&}ws}K)>@5Cnx9Vg&A>nK9hHT4Y7JW zWFQlPPM*BMhVa8c|#*s6+Tyq~53lf0prwmRY zGS+5`Eh-pC=HuPAI+F>{ar1h`Pu>RxIu@su9Z|B*kmMUJEy6dcY_Ec9O_hpQoJcZ& zAZJ-(_H&lTwPqpG`mbz7?wozYRUd6h6K;j+#N4L~Kd+>ro9x%t4HK!JlE*DZtVN#? zR?u;uh?Q}iX>>)piUkAKuBm#?&m$XDq)d2?;T-pDV2x0>C0W;%g|LkDu2`tz+d0p( z^T#y(4_DwW9)9Z012RMs=Bc28q&N3M)g>&|bSp_q&}@oXKC5BB?wS(TOS2LuOtjYy zVed%otm|`=WZ1A;JD{B}^P)kdxIELs6=uSgdKcvZPjR$WD2nRt@PrK1lBa>Of-d_q z?sepa0mq|RTPh+ODpGEIk!l9PZztmOo0jpjPUt(Gw%k3j{gC$l8;%G~6n+0~0%+ z2@Ruk$eW!|$H2%Mb{)G>zL3|1X!!lpu&UO8CGjxPuA0vMNo@dSjPQpr`tP08_nzsJ97+3j9X_%K%W(MFsbNM%+!!sKekHVl` zr5#75`*_;5^h{@1Tmr}FWQ=5L>qwCOsoaX4b08&R{I!z}Y!C)TNjMq0;FYVT!(GS$ z8xjfO%yLn6{Eb!uMd2jAIHQ^>Q!TnRVJbn*B~8#SG?7_}GlGMs2;FByT8LO@^qeNQ zk4@WMNi_2wQDx=*dtjsH+qqC_OvWXnf_E~?HOc%Ik4eoNsvyZ@FvvRkE}&JR@e*P# z8RIPF;CDe0nN3DJivQ<^s%oZX@j5cs>`Y&sxp<^hNQx;_c8;ZTIqRirnZ7;d=7@Qe z+7W9G@i9X+;hc@0NxcoYpScY6%n`^~$m3pbslRN!o;_sv{#{ zn|}(dU&_8sDdEouGJZ#M>8B%K##8MNQ~K@ynahSxEvO@RFG<~S;YkXyDTpb)?&Y@Q zc4Ux7FL#tp7||_uYj=tUbGU1oB=zZHW+tN9fF*4ey6AuR4?>P3G_~P?kxKC4Cj5RkA<2N= z8axl;BWy6+JNb->smcoQU?!_+29JH9`+Ldv7fK2){{Mo1|CKC&nT_c`>CaoKLw1M(cIyo~rb;;QKy4ij z3Y<-teH_$qAKrEUWo+R0QGmP(hs&i=juFN*BG3a05mI5$tw+EHn(Z|jaR?ZO`c5Au zY2X+OY4FpP`zoL~YKg5mmDY}iQ?@YPu5mju@m`})1oMskn9C+ja4i`_iX3iA=?+(G zh{T=r!MZ@PVo7>_R*_e$YDTw57}KM$b&0Q_${@L&l^QSquGdO`bC_f#pau{{e*q#r z*WbTpKU*y?R{GSHQaK>}+e61i<-Bd>JG5XpTc?RS)lo-VrV}qcT{}y&X_f42jvsI6 zI*zTC%BA_ieyveBB}USyqb24yr@}e4LnVI|Ghf$)FqwlP@U~V-=GIEfN#>$wqh_U5W3&@W=GM5Qr+=fF zbQ8AMwpYE)+pP)c0rRHoM0<>iMcF(?K@q^BBr(aKM3tv8$*W9^s#k(94=*paEY%#B zXe;F$msx@_g@B?Ih}AF7jm<9$6i^UY2|nwC3D^)SB$9Cky%OCMk0uy=%6kd&7|4dj zi6P8DkZ&p!Ocbw#kRQCtb$PK=ziDCaL`~x&;{LvZR*>adKVU6nl($$8K=(Bh$u**O zmmp{FCRR8>Y)GLCWOBmVg>CbWy?Y|6&8X=0@4%^&K^B}tvDdvxYG&$>e|30%iPNSMj7SMnU?7_Z^@6 zmBZjQS{1^+Nws6jy2LCXITEB7>xfULW7M$dQ+EW8(H~s3ixBSrcG4z~Ts^S#sNrT- z`o?W#Ql&rer(lWjH<(a!wRBoyY#kbE?L?XNHbZ3(s2Sr0k_H`u&o@vf#FiY#K8?w- zq7+v4z2$C~tzygVKRj$Yx*GLS9CJm85X~fT-$VUQjWE}ymI%R1I_t1MTnp!nYQe1y zV@sX%*yXDPihLyk1z*-@H-NbUeNng4GCR??;lmAf4KH8O=Ly%N-=K2$U$&Idw4nv0 z(s9;*98!=W(0env@-%=OYL4^v!WYPtuwyzSi(AWGsNKvx;=J!tAsQG>rP!OCUDUDR z?pax?ys4I#)rd-rD;V_HC6x{aa&`{0gmm~Ba}1+OAcZ|B=jw1IuV6~a$V3%b-j=%k zgyo@p$Z=YhTU|EMtWZxcCJ)Q}PR^^ep7P#h4}`RE%Nvgs?6m_)H~6$C3@Gi@`3 zH}!-keJJmwkiev;l#1cR@iH1mZFAFTh5hglp$x`hQ)GjTFIY9+qAT+TS|EtL7t@X8 z&J}eA%UvC@Oj9FHss2oi8aS+QJtzZLjV|XND5;}ZDT_TyU>q&@A+oZUjId|);i4Up zJGZ=Q*vEbfFBTTQSDnk!rtwEj*++7GYKK>6#4dd-YM@`B$ByFsoasuxRrk@*R+h=` zy%eH~m4IuMpKGI!k5uV$b1n8-mf-I?1}maTRb%pU`bFMZqt#6B;YC7M&YBK<$_HdetWwV>WSOhSAl_$F-FU>>U;wA(=YM`n+(oPaF!l(_gJ!81xiPL7zYj+ z255QPZkxYEiuHjB`O-=XlQSyQft`3h2Wy+~OgK+$%2Cn+FAwusM0_%wBf+F27!>>c z5i8t~54WFApZYUI%+;}o$d4~cq?sACd&l;K0hUgz$^&30CBD~Hu5Q*(_HZHD)w+F_ ztAdn4ZUavBLELZCz*sb)g;Ggob!G79(k|cbdu;CBdjC#{n8a4AeeZ~q1D;3IR&1|V ziXZ<(f<0NXNd{_sJudRe((KyXGJXhIhGt95(M_mc+-(JEDk$@9%3%yT9I7&!I*ePq zr)-`yOAj@84#C@R zN?w9`?TrJn4B4iLKJ(aSzUum&Oz0f zxmGm$Fn3iwZ!hS$q2~uie?PTJsEBGn~>=DtSa>^V>q2 zFYyn9_o{wPDXoC*Z7;iOr*C)T&^Yksj}z8%U^0s z>a5)$kCp|aKBd8-DWx~wx0x&-q^RD~YTG6u0~K{t?oH%+PGO;mhAN29wO54{Ih^j$ zMDQrVeu$ZKLbyNa^S@5eR$rJ7y%%+^c<*?OzMcDvO?i_vB9}XpTs8Oe^+Ji7d!U?N zgjgZMBcshF8AlVAt_$1?UV%|No?Dkc z+jzGva@*b^Ag9pMmcha!GZFanL|chK>Tf8{KMD0YKwK|Z8Q~K>+`2>?Y%!wS?Ve;b zr-@gZdQT$SfxG;sIh7nuWN9+Mok5euH?`xMwjJj2ybheKrdu!)7inmX$eI~gj;mr3 zlADx{^#u_p&ezC06H1Anonle-NzX>Gts3mDj5ql`!>o81Pg_%kXI@b;37hP}Ue;^* zuO-=g*KdK@cB3ZQj>^>r7nt^JjZ5w8FU?PlH#TReT$Yt8w!LPp9FJN3MP-j0ZhCb; z*~>2C-&ly=p7wR*Ue2$O$}Ss(@;E@t?YEp?O86SCzF{UQ&~URA74K| zUpqu$qv8RiV`DYsr#Wr3iR*PC->_>Fk-%(#{ynC9@Hd< z-pGbDf@7*uuE+k_-I8h0N~C{A}8lD3JNQaSN!WIrK@3$PV zkmSU?@HCL0#23-1q7~;7PIXPm7x2Ek9=}po$hRpdwiuhox)VMQ9Xg%N&+)n|Wp%-W zr3JJc2zOupK)ZMIhxPD}a;YJ3dh;-BQnZ**9BuFIc);DaZW9?3?CXf34LH35+N5KW z7$W*&{_NwKC(TOa9WH|x`rTmZ@}<)WbU5V4y6V8Vc+fJWVyE@3Z1lpjVfyi*@f=X1@4>r1chNeSvJ)uhIT_DSZF%R!OuGQ?F z0^A)q0~s%x^^1x(p9bJYIplb^k0J_N^v(X^aL6-e?L%+2`Q$6f$X9AFG~YlF4n zVZiNUEuRQ=_6_5=3Qc(++j4eQ(_w>gi$k8c73L=46Vpxrmqt_ZlWN^x+h+1{ywsOl z$$<0TYpRN2^t*H;0b#Q8{ z+EnDdLe6#o;`2tDIUSh;R!Wk%t~P^B#F6$%0O>*VHS-RJ)_J-;-unJu=Sb^ znoM&1xn=6n#drPAkbhp;1Z)$??j4*^-J-m@`Y~f>`Vrq%hzB(j^J+%Kw{nPBF(BCV zas_w#z?l<7R+^J0@AQW;k@t#-=$W{!ymYi*LhMSt>Kon6e`Q=*8Gz`2^LE0|Y$>Ve zl~sUF_CvD>`43-kd(=!bbJ9uX5Mz4G3-61ni%>0Vd?jk!V3H%e{cP9;(^c?{r;B<;7?Cv-jatn4>Ls84 zQ|!JxJ6NUbtoNWkoOBWjU);!50?jdcn*uHn7YiC*Av2XlThwudC^bp52$?UMcIm*C z#YF>S@UjYfU8CWJR`+s&hkX3ZgMG!E3$nl*;-jR$o_h|wqO9pMQGB*<@FTmcBB_J0 zFb_MaFD+d@CZXvQqvGDM1kZ20jF>pm`i7I(4arJXYt<&^*PtL2T@Gh-jFVJYO+#A#U$2&Tei$vo-@$zbk995`|(4j zP3c$QmneS|RjkB7$li(%XgGylnlY*8*{x0^U@5{gx; zmdhVUDFFITT@;VAKO)EDLaB%DCXKDL&H-IgfemBp<~FvLf0_U|6Psw$;a?w|FW}Fb zDu2L~8Iz!sGCv5{q)Plg`F-TxgCk)qFj&~4RIKcpJ9Owy(hdSsc7TQhF_Pz>J*X*& zXQcx#Z4@o;@D++Fsbf08ENX*9`kXuPKzfb=f0-Z%G#NBn;k#&7VcDjsW)Ct?2}%Tv zN{_6`WGdyn-Rjz(SIlbNfTx8~P6Pj(EJ5_(;e@eG3kC@7xu1$1#va9&{E&KSYnM_Wu-hb3DBIl72Vz4}={g5_&A-q;H9S zJ0Z5!h&hKKzs0MzS2XZu;Yq-hlz_7)kS!lUQ>cqXzk1^ADM2C=fp`@p_Y;$?P zh2qnw(;nJ-N9m%FqprDs@MYPDdhX`Z3r0}JF3{bdG)3ShMIFg3MP^qklv5=wo&65r zsVOcZKf~hC+$%C6PlD0R?J62t+J|cV=iAP#dvgTI|D#~!V)c8GK@)rYXgu8h6TT*X z8~(nzt7NEae??@Zku6Hb#sv0}>*kT@+*X}Gtf+BCL9=1v|B__`9;`@&aKlKH7&s;oG;Cp|RGrDXkBf#UFcVD8h~X zhx&Y;f0?>6y;??g>Jx-PLOE{PAvTNhB^Ws)uCQ-Qb`Lc-m=P%&!>FLDjxl8Q&NqgG zM;AcPzHQB>buIVB{wqA!?*E2Mw*ScN_^;uT?SBdbRAP3dlngLOX4cX+6i#U7*2kwg z1dPU&M`BGu}d>ED5FKKxIA)u!0?2s?Jrx0h-8UBTdCjw-<#cDN;DNfCAY~{QGMGI| zH|SAg;%>pfrMtAfw&axUA+6u39}?^YIy$K_!=?p{wfuC!Y8=p6%%u8nkN1nkFsC5; z#sE%1US*0{pflePQ?Oge(?F5}AZ*wn;u&(+clKf4SA}c1tsn-}bj0C-egI^g|Dbt% zI>ds$6Ii+LX^4VLv@Zv03_X1zC1OOUM3zDn}LibB{Z1+!#Y6%s* zh4{4)31ObdlNi4X)ndRnVqkh4TDBNVr{qApuX6-677+1^7*Q4;Bc&vP(rYtiun4gd zl}!q%K>CS4y?7o7tJ^QmN>}SHnFQB9o>^|EE1N*bZa*1h{L-IqF69F3)m11M1Ek8G zkfp@sjyMZ#B_c}+nIoi#f3N>0hs-vLOm`~9aRfDXlo!md?VX*cCsq6ZatZ!Jd;MQu z0ww_S|LCw+sX{p`nV?UTTzT@DB!uXrx*=Sg<`UA%=SGej{+3^pswfhXx&q!xao&k% zbGM1lVDWr$rf9Z^NY-ptG_Q!{F(XxnR%MrIis+r!#vTZbe4VCRcw1P zi`V%1?mD6I_cKpF*IX!RUH<#=s&Y%&BaL;BE)Ll*#qtpMCZz@*Dm+|#II29{-hBOC zFmTcx6)h*OzI)PQ-zE!|T1sMOI(#Cti;t#M}Jzs8c+6Z>+Tt$5hauh*4pq4 zrf)Cx?8R-62nui7D(l&u#Ext?$90_3(>m`-ls52*k>G35Lp~q`+mGa3$mMi+VzUzS zWRcf48*|0^>$;ko5#J(Ui4nr<~Z)>rq9U{FEGN3 zAxt*a;NA{IxRL1Z-F%o<$7_jeg@5BR#`AE;n~wbYN1dw|8&X($@_cVjE4;G?+DZH} z7sdwcg_kn^ux!^ZccMMTpS3O~2u)8EcpoA-`L^msV(fy+q=Ml_{hK9W;&?BE5T`~K zv&FjoK=L&$m5Tbj<>+;Qn?z6`o10)%n@1llEj_!2S@mG#t?Lp^cH=+O=3>^mE7xWw zBa+lsH4FPruJpyxdB@y&N3(6*tYHJ5@jT2LCI`#Ab#l!Lkf-+N z^r9=j!7baVyLG^r{m(CK{P9}@WJ+6LjQBp8hY{iDj!8%_0miGI(6hV}NK6 z9)=(qC9_k#h9_Q>QJItgMJt5G+{y)qV7FTfPs_mE_WBUNmV}NjZGYaT*Yn?} z#?y>bJiI_y?V7n|(>-;JXF-Ddo_y~VXHiHoA=s_qJ_*UEb%FVQFC@VwU z=U?@m<6%${6zr8hM!dVKsgZjoSx)74HLo7!SS3sHqjg%tM-f8Pz=Awtx-XhcWa zp4P0Mn7UB-^hIN=b=5@g_g+NY0p`q8oGJiO_54lE(DDf~D!uk6E6ibHTG3E|8@F>U}FRYoB{;soRww5x8U8z!tdSoI6c3k;_SmNtakX2c(!3Hd@p{@iAwoCq!s+r+5?T+biN5is z(GOZivAfE!VX`}hr;Pdu8_mrO&7I$|)dO2Y8S4-i9)AN)?7fPYE~o@zXiUI4=nw8; zMI45u_SWKVxr16v;18cH;raRMJ$r!${JxS*J>|UFb89qDs+~D{oIgFc-4pR30G)R! zD+C97tpRd|QEqw%9MqZoE3IwGOU}TTiWDi7OV(|Q0}Bm^_nI(3Nh*oIF?D^>A`Y=Nint*)}agjBo5VZAA}a9$H>A|*&C)K$_ZbIVQJCFY9a=vUidrG95`Dx(5t z>{=*|Stu7&(iCYZ78_3B5A<&;P3rxEk=Z(dQ%PD{w{-I~b8W2}l((jwYp=c|%dEI^ z-nOHli`gH&=%3c>=4&E}8lPH9$ExMjt+2b|Sof~{FmI}A&l@*oz>)EYNaiAbdqXNm zm1J?`Zv#tug4LsW;vRp61xvyPv14UXVOvmA;)%a`M%b73#rg0k|FweU^u zb)?$3%-D;g><;VdFDWN)Hd{3Isv(AzmRx#a-1yqbTE|$&cIO|lDQlI?x{?0mCtw@9 zWEmT69s1sK-p;vm;kEOWf@w9?^sY(!5?Dz2qgqJTLPFb3LHwp@k^5T_UF2<;51&=9 zs8qgm+-<6i2JKUhlSYC&%h}^)WSmn*2YYj_|0@1Cejs|TBLRdU{t`av7Q8cXgZ~TK z&;9#BU9(A*pOy_HxuF%$4Sng=>9}*L0R!e<4~(8(S6^KKt6laP9{61ih1~`Zgocup#?cjw7k(d28jA7c5d~vhGJ*)Ah_&d? zf~aFn)xfu!Z8}@FLV}io)E&&-%#E}jj1`iY-qQf{S;DPC$$@aum^m18J*Bgxro^#- zwfOIeXfFk9DD!EU9D|t#Rc?Gall8o={HA^v9?HY~W|)+Nqfh;Xr6_Mv5i^fB>UgJ# zw>eqoTbYBBpTZ4^it5hEVAnip+5;_7bYrV}?Y{_Il-tYqY&&Ac?H=HI&Ve>_I5f^U zYfzp^QCQ;6#lK}*@aA9r<)c$Px94UJxuQSILbR9s&72!5IA4`w!8lmm@f0W|A@nif zS8#0wHrIE=S*D`A+77Qv6!EE7@ry7o^Lp~mb+oGZn1o+<%b$N#Juu1TcF;mE%7`%M z;V#c?nqT^SSjJ^+b;W0f8b))k+R(ZsWx1u)h#{#3sfQQsH@+_Flyx8%kYPzE z4$-Ad2#PTtm7h?N%qz%mt!r-0&abV{ty@?nU`8g1ZW~~<1kj9i41ulL(AB;S276Iq z2IwnUDk_*lUkb|krZ7k!ywUFKJ6=$IVZb_L;X+hAV_vQE_~}wqI9vZ_*3iA$H0+~4 zzgi;2uqZUAH&_Y}JCH%?YDA&Xe#Xw^r9||IwZQ*PIOiurU0m zl4Z#Q%1ue--IcEBMH^87Cm(IZa|jL;4bfNu$rx=7W38o`W^2An;)TrfzE~oiWov^} zCWCEDO6vCq9W*5&G37YregG#`^a0erl%I#J#;9oKgUFqS&z_SHU%8LNwnWdJhiuok zFQ1z>17Q$|aLkZ4v+H(|2Q^x}4#(~AA(UY`&*`5QiEc9Doq3>c6M^mzh_$ius7jd}xKLQjtYkP8ts(XMsomQ>8if{GPwx5dxDulOU5Mlj^3(%vot8 zG$zYT2GT4Elg5me!-I(ovcnUXhR@6tsV%7wlV+1K8$}!a@gzB6;&RX%NNB7EpRZ6# zz!(ef^x1d>t*MBuZfy2<+Pj91yTrGPgS|>9AaXLW+^i0UyM~Ip#QJ82z0-q!I0?Wp za?qb9j=RTW{uvZMpL$9l7(ndBpqr`4>fVz2Prv<_Ne=YE+_d`cn!Wdpen%ES6AQ(W zzNY(^ZWe-;?OeQ23z_jTy!!Ky5Q};}?Y=_L z{}?hmDIOcUQT#P7)j@)K=52PrP z>*gwUyS%JB3H_!uC*28*$dtxP*T!q4fciZ!;H zKWb|;#>8sQo&>%JjvXo)t$1~CjL}dl{S8_@Ys?5EpSe3p?G20&*1zy82ISKVMK|E4 z??s)4jE!=C@CrRjV<2J%hu@Cj*Gi9Ox-TnuNe-k(AYIWCj&p8c=Q@k$wVt>*iaXRO zDWRN5f`rlN>|v065|tVhw5-vxh8v2O;;wyi;;!di7sTzq|9c>M?GTIvid%*%2^)n# zpwEc66zpyRY17eLUH8!vfcSACSB4fDV|njS1F41kD|(h}88~Z68Z7fEvTU z|IDexkbP>vOtcjXr7f&%5W4G$fp%8;<^^wDbVAiUSfyGGce&v<<~l#I%asG_ed#1I zE|;_J3*I{OEbA^YDsb)~rK{Vlzg7N3y;2=d7FwPpNqguwTna>c0%OYKCTh=Ak$k>v zc5K1Y7NXsbonbRt{9%EoXF z;ElYDl+R$aojlL3$5!8%Z4Elr^xP-CPV~IeNp$K!Si$!>tfH8tPn03jNV;1nSPFjc z8^$_?6L&??n@Z&ls!Nji9$1-Y8)gpuo~wK<$=TEMH<6heX(eu+R@$cV<0@dA8!TJ9 zT7!ZL>g%(z+x6e^4hjT)^_m}9kRD1#cB%_5zHzzvR=S0Mc{}}DD2{>8K~&2+cj%}% z&p??leABD<|Cay~Zy^Y;gZQ#|fI-^&Zox(@*%K^hHe{j5{VUAV(wrFow$?q?Y7~S{ z)bb3`*5?H8NXx(1x{;qqt+L_xZmiZw_CDG@C`%T6njFOO(A_;2$g%*NC3A$jPje@C zmn%@-H|X38frHU^h}z6{>EO~zK<$npY)Ia`_Lthf{BD<$ws>R{i+P8X;h&&TFBh1d zudNC<#5OVc+Kfje3r0pn7(l|!axzD{IJ;u9H!>u%3xYV z1yqIV-|`tOqVHmGr;XrnVsykN{`1oqfmQRScIMkUO%MR)j*Z#Y25Ymm=m7gw@P;LN zX_y&hlXE5mAR6v?2l83{r*1KAK>G2E5$?;_{)Hg{`T+tdIJ&K-PrF-QUU!ut28)oD zt_yccW-3O8B2fj3Wv_yPvlIE_^nA10ScK6SF;g@IQ)?o3C|QLzbjvW@P5<3>^g-t9 zNPBcX&+Nb+5c4g+BSsIZ?nZKRDl>B2U`Vx_-PdSNU~yXV3N*6cxBbJCF{D6edX{;D zcR?HMpIV$t|Kiv;Uhk5m{Jl-Nfa;xW@-QN;fUQcKns0vgC}u5?>j3QCTgN{O)K(ZF zQyTB9@JvA-Lq|kPmM+OKts(R2;CZ+}_=5iXn=u_T_+AAcl~cOr!A#YlG9g3lVg?*E z)Qha2itnx~!OmAHt_ST~^&tB=ZXDm*hWyM0rnJF#n+1H6Jx_S1(+3@HfZsgrb!2T! zc`QZgsuyMJ3lw{Jt>62162aPZTn7CW1)!-;Zewlgwk#SHNISonY2lf*xxEhEGTM3# zoBhBlEhB7Q1yA!vV_N#WuG>HS)Ds$#}xSz0CpB|D9`D93@1MxOU z6UZ&p&Aq1Ads3vB2>TJM3HDxcYf!Rs7x?#)ZLuX;7$1XxUHqw`0p9lW-qVp99a7`8 zUz(EonsmJo-6>x|_6Kr_cGoXc?`E>*HwQrvUzz;XaG#-C9zT4&m@Qe3^wan6qV8!% zdT*xQsD~e)v=S1E6U|J!m7-R8ekCN7Eb10!O-tyHx4QF$B4~*WRDKuMDxpxh43q*; zZO$MZo0DreIvTiFBgB_-Vli5w5O&oF<6$upOp7!1|tF@1+^dT9fQsNFnuW_KN(brLhJTHS#)BJUZ3F5`LS5Q?NC+-HZQNV-9n(_x8nOi|C-CuV zyGWK1*GOYb-C=seL>_oKeR9i+-fg#%Z=cKNmSf^Gbb19$c53f3re*!_p`xP_>IJ0~ ziYjr9>T&rJYUcdz)$g_E8D~`+q*VYjl{2f~zz?d<&G9}&ly2wRg%-70IyRZ2N7(+r zgjNtR=+QHkl)HtKNN7{ofJZa-rBwv-mEsC|tiwDU;><^1p9!>2C{HfTGdVFX%N0SWRz&5bIETKW=OwuSybc4vmg@a<^czS%{fvCqIlS+;se|z$>;2 z^~&d!OVG#iD!<8c3;gC$Q9CZ*Cok{ET7_PCho{!1Yi=@XkN;rV(k=sFSLt(Du%lqFeVZpEYdco0dlAO#&?N4cSkrXN)R$Hf)95X<}_ia1B= zcA^r3+r#y`E@;@KHWG*ZVu{fU+!&MDFJpRqVG1882lp>+X-%0=-u&e*<3x5~3rp0@ zdV$PbGUfCX`EKGaZzBb>iJQxV4HDYxlr8K^z-@o`kY?vP9&oIh~1%ZI`Pl)`&WVXJQ$Um&; zZ1*fAA%?y@abQ1IwZa+6mbrCAzQ#%J`WTU=x%uUlrLfFyhDh)QB*bbu^6eQTGj*~Q z!qBech?J+gXt_+Ku$I*b`W7d{HBN znR!M^QbF#)E?YBsc(q0LNNB&!So>d-u#;YJ80RAWdnAdKdapR%LH zE#McNaWW&DVqqMjysKIl?iDCFOHwdj+@b(x#+dH6F{8@Qp^OQ*OYv3K@xmf^Dkz!s z4$t`&(=uvnk%f*xs~ap@fye@>x>CK3=5Bw%)#lteAmH{X@mZ@clwKooyFtJ9t&7X8 zxH6LaTEG{c;oBnk_euqF${U&}I!UlmLQBepD={%y<0^&070l_z;Ck>$UaPEYP}8)t z0A>rRBCH79@q3N`X7bQ%NL^D;-n?<%U`*|;f(b=U@w@~ao_foODU zO!cTox-|uoJ;9!uJebPq-brN*Jcq8aYi^%i-m>;*oPX!~=-T*`$$j35YZPby4L`=k z@PSn_`{8}BI58f7Wq;`sl?gGHh>A&C7W{;pp3KNhK8m_#>|Pxf{Rj8hr4<|W?)Y6< zP1~!S+heX8&F+ID2BAW>X|Kr_Nbw;>yavS{ILrZg(VR zf8@+8ZsMBC8S4fY4y;H4NYd8R+D_!~G0zV1zJqVywN0)#*Ex$gVsOVjgYz=XCQc}qnN$2k=Cz>KSV74&DhJWnN2DO>=4Qgi!UK+D1?dfW{KyA z0r@p>W8sPGZOM01z;$^6qd}dGcy5vG|Ksc(n?wPYF5TU>ZQHhO+uCj0wr$(CZQHi( z?z`vH%!xTMapV09nN^WhnJb_5W`Up%{o}`?oW|u=WrFj;NHgT<>QdO#@z?iz>z4ZF z*WbajPpgORIJ!0WVb)KeC)QiI;pS|i1?_yX^8Ar5G1(Z!CqjDkG6)ehbc5j&X^-!1 z)(hE-Q@zFFXgpRf?Hzo|-#r>DmWD6)heA6vQ$ zYPuA#ZEXi>h(Xzuc}{)$k=mfumTfVr4695`HM$0T3gpeTO&;^2f)4KN!VO8 zh1sBz8hQYKB6(wfR4yX#nHEfB4mh@om6w2m#bqQN<@R13nv8xmFx1%~<>zLk>QUHv zlY`HtDy1MqM?)b1^}I1DJ>#kxI2egG$}Y*0NmD7~Xqu`=_viVccIk!tcT3R^QoFOv zr$o+yoW<{_+tfqs;!b6j??4*pqG~l1;)vr3`md_@n4Z6@%&iBzp%}ui_nrVkN4bDZ zzffd>MA?Ok4_4z1o*JPH4C7C5V$R~LeZ*~lr9jh@L^6AMXiiK`q#27erPE4o*Lp>m0B-!D! z8wf_UX`=H0)t$pa2}^_K`My;i#vJ-b46KnnFFDm4q~Bj9^Xq50njhfRy^9g=$BvYw z*&vPI-s#%znGSEcPCI|@A+6LmUYicepL_Nm!g@lt+2?&MFumPhf&SnMSuHh_aex|l zjb>7kY;@EWrxR3?4p9$F;BFb>cM2R%Br@7>*))gfZ5K!g;s4kit6q)z;ku z&-*-xG?G^cCWEhyB91KtL`nqT#ZSZj5pQ`B4#TrtEwR|+{dX@y(!r&y3~yZ4EVb_1 z-{trcq|o^~PC*~;P(4rEWt96^7^kMBPI>R_6x3G%1EQZ1GmfUwsk2+>LBj;|IkERKf064H8;_y0E>B@Ni=C z<`s77ZAw*Zu4lp%4;qD!M8Fp#JGr75**##`Q@OJs%fFM$Dl=}#De7%nePr^@#T6-h zgFP@}%)!RMA{pG=3~jf2e%#c9iJmn3Ff48Z?eA`i@VFi(EmP6z>*@pIA*(bD@& zxTm&luera#XOEN$Uc-8>Unp_6*nI?2=m=dUGylZbW}TwTxz^5XLkn5`WMzwQv8b zIJJd2?xo9?>^E-&gEzq6E0$}z8o&uc2% z(mXP+w5_(KDkrCERZ~4mIaNN|P${MyJH{25&$!}X7Em&k?s+K02zT0ZpMm!} zf1tXJ>>Wi>Cpa(fP=LO*YaM$Vknw^RHZRt&$kwcWn6-G1TjB55E}v9`>bC81+JYLR zbB%;Xww3Htw`$;;&2s92-P)hTa7?9*(xIvPt3sKrNKaY4WK@%m;_D7cYl_-EMlpAk zP9gP{Oy9}qJ@nr#^X}RzqtFV43#~{;saUkUF4smASfNisdxTG3xu& z#Q&rpp?8@NV#X;6-tr1QN`zG_-+8rvZe(UeCptT3!y$XPKAq@1E=$h?{s1di+ne#@LCT$GlQio$#)cfnIux0dI0#!d_}{38na zpG{JFmF(wbTF!U0-w#~*>(7{JCyI}&(1*O-R^aUemrisBrqe#))bi9!W}$jEgAa$X zPzp(HS%=?9VMygaNS^qF+|1e*?e)oS(1zo`p6U+G7yQoQ#5uY})suRAX4Pm)B6VD% zcoyov4Za_`!~@rYw;?vsQiT)G3{HZFz1|*z8}p~nJ^p8yjcdSh;ci*z_=X@;dNAj$Ty6#%?Q8v49XKqCUc)hoN`fY`z15_j{)H^cek#VBsnc zz60mIXmEhCx%{|V57+T%WE3ZMQ5)5;VBY&f*qk3z3_>jkcws zq7QxFLnIQ6)59s2%WYhpo5kw#zb0op)E4qB*MJeFLE{B-kq~;s*r9BjS9R!7GOYBE zr^IdNQO*1o%-w8MA7bv7X!@eJV&M?UR7sA4;%PuX-V(Ap-N*`*o(u@91mVt zF*mpw!zaQ5SPuv4KpcPt5;SqE4~HNqIQhEdHF36nTdoi|l~hFX z@60B30q_K19Zhg{$6SQebjKy790VE|+SOL2A#b=I$+WV1HXTYf*pw0sgv9dbyS){^ zshpuM^vrW`Efh5$`2o@~Brc@aG0&^i2!I%?*N2x&AbnH08Y>hN8JUz=uaaNxQuDqQ zw=>@izC_9{>mENmeU{P-p>mS?SJcK6faT8~ogd8|Bk)A7YIuW#K;{pN49d2l3ux}Cwb z-qCa0aa$wS*8#Db6pfX#0VOSt)6kaMec%p7E~i(&lf&dw%Q)*g|OV3WG|** zQ9d1K)lT9o$ZgU;VC=P6t!)$O^E6!Vtcqjpb$%O)-CT=BN$(T#u->k_|2pT-%rK&^8oRrMW-4ybe z^5u;aIv$Oc(@d05#H`~|$f;5wzh8J|DEHOAF(l zQ(!N1nfh(rNF~&wu&8FULL9SCDw>HnRbe*5Tm#^G;_{P{Y-EOdgSK#1kNwT2?4#qj z3(>3AjnKq=+8^K+Cd+j4^w3#j7{*MrTfMJR{Qh~M+p3QuSq1ANKWia z{9IEuDc9;NRmg0-d%Nu@-VN0Y{@H!o?-a@WaCRQ%w*2ai`tfbF{CP$824)`~mnR>L zR}1t(nzEqLa0=k?A2`lHVa8fFqkBSkU2Wph+|Y+}b>G?n;l{W}+Wc(}Nufjv25HKM z4alt@-Q8%Hm&bojFkz_l%bc8mo`KB2RX@0WcRgK(^R1-3oCA48%XTX3U@Uj639fMW zV%wZ8Ve&|2w-2Gs7tVk&;9@OrcwSfDx2t`o34(hI_$Dl?mu*$S4=t0Z-Zds9dA_5b z%ml0vs~#q?{g$5UbvgeH5b`cc){8{DT432X-6nXuP`O9(LLrmbb6;;nDtLT;|KQ$J zzEXUANjWeJcfv(Oa{Aow@AvI+N{?KL{PnTmgY}b@44*lC601?YiJQh&xP2 zC-ycxjn+dk%p0>$P>MMy2H-F`rvD{EY(;Pi--^cT7jWAfRsPPCaHDtk^F=3>mcT1l zJAabgv*{u|7qrWNnn+H8vbP*8qsBU5z=mK0Bz}|jx&ot(sxIj*Wy_`AGWBRHJ z7FFLVp@+XPp3xh=cbbzOxlgzc7;5>gQEvccIF_~IKB0nQK>Ezik%SDNAl;L{~I_hsWY?Ych+UL3}Q*sdy6 zN1}jE=JIZwu=f(sppj}>L*QdCa~p{hSRn|E7P|Scx$EzI3n$W*N`Y(ov3~mn-M~wJ z`7h#@{}HBzjpaYqbgTatrbP|Ymmuy{SeT%P!ooXWiR%VjU98?l{8AMGp&F{wugU-- z{0h;ZKOq)4UPU;8UmhG>TsQ~-<<+@jrA0GYl}oa6r5NOP@$x(!EmdP?%9rW1>oNQB z=6mP%b9?voICYY!su}_}md!Bxv_b~UtHi^-*50w1dJ1xIBQ*kzgY}9%z&m#|rqvLG z_cQ0&EnrW^b&v4gp@`&%egcv2AYhwOY#?K_(D?rshT$BHTRTY>d48v8Zl* z#s(L+v6Q2;v%`bkGlGbC-XQ;eW+#844BWmf$ur#XMG8DJCa#1-E(47unRF(bfrx}; zm_#}2Dgi%So8CRcQL>47!d*t#A;{QLxa~0^$gTXbLf$^;(Q<~iwoomAU4b+@j@^?i zNKE{IqsArCO$kD6^F4?UK|Bc2K$w}JWka&ap(qrgB?xDqpB+)qkXZo97k`H+D~w@C z-4MGU{xJ+>$nZeP5TrihjzAUZGCX=nohm>~9f?2~F81j7VMfbc^WS)J($|Wnwa1hQ zX$=Au>H)Ypz{r@~J;t!?HUtEY%iz-Hlc=)EG`mjqcR_B{(<>sjXVjh9OdwG=8Yj+( z`T>L)XYK&Vi~%zoo05tjNYld9U$x%~thKnZ-VUf`V#F&A=5g{q>~QS_8rR)a1VesU zWFx!4*RT*8whPGIyp2GNXoV09kJ({m_?n*r5)zqEKA?j1I#q(~Ub+v#56z}O_dsFI zUW>JiUxFe6G9sO^?e*B4m^+|~5+1Lo^h)n4y-+N4x=d=+$a>1lg;TOrAyHoq=FF)) zj$}ZlOrs9ULQxT)C9;3IEqzKdI4KEpjYM!O6CX;^nX_ztc&$+~eLpzSe|0BT^5fkK zyhC(w`YTgG4~+L|4F{69j@`Ub>MG&u{SJbf(t)e(Zf?txf@cnF_ks(LS!c%{sHf15 zxJNW}(86d#=p6&yZ_y5bHu-5eZ+|xlGauuh_(PiVF)+9e5w&0O{WN`XB`nbIz#=f* zn#tJ#lf-9QY@1GW(K#=kaVK{+NImaB90$y~DaS)aM3k~|J8g|!Ao7JaZQ3<|*d~A? z#YripHJqA$b$)M8DbeT_AF_vz0aAmwOBU`sLL0%c1TH5^0I)T44R_OR#_shJ#M)VE zxc{T+gPe4=;NPyBq24A%-VI*HB|(53>x|ZA^y&dRS$o!|Oi556HN{#e>ZUmG`$5;< zb-H`|q`*r?x7DtSa6Uxy*vmObp%GZa&m+^*c;A3ta2kK;9KN^bZ8=pIcdKbm+DBhDMhvCd;tAC}Slrb1aD1)fOl0bpSXIfT_6uVb+@p%erMhgyo`gwP zL6${|w(S-tMju}ZuR3yIR28von{hUby+6wtWs!0*(~vIT<{SqEpP#R}4BGZ>-47$7 zA8a25^`xvxNNt~-Wb_Yte56Dw4sw4jv-a{{$eo<90|T>?v?SzI+$+y+kQRkkaud7R z1IPDCnb@#$-BGTQ#Rv<-Ml>x|JEqH%D?qRcn+wIL2MUX ziYrHnHscyxL z3<5tyxu=mu+7BKY)`9aL6hU2F1Pq!?At1(B#-=`@EZ=l2y5CGk74+r^FK?B57H60B zC~Z)A1^sRGchWcN_bDrx(YLF{1jFQk^cCHI4-mc$F$=+=d`aWg#t3q z$cyoNxMB@w$VU9Rz~Y;PBUQlT)?y8_!hPa1%~SDVFCbFMRd{Jn&p?+fjDLJBc8N4t zMxPbAszAL8V%&F>dNZZDmV}Df#37Ce8A*P1cW7)p4W64D z9Ej6gO3rNokPYAu@5);Z;m)fU1mrUs@mgjyZ+&*1neDLsnEB8VV~ zeyEdaNX$~hvxA_WmY0`endR(SUg*N_(mciLT^P&n-XGX_*Vi z=UM)4#jaBL3g`>udnJQOq}B)3xTn#uhIS=GPnPL1t~xzdvMz;H&Yj~r9wYXbC-EzF zdw=U@3XOvq7w_fl)m&*{&JBR9cq`6Eus-C&(*{TfbTsDj2gvN@*itnA4ZY)$MhCft ztqF_#dtIkhn2gw`s8*ODmV&)2Pym3~iQm&$%k6Vy`-k718bY0RrFivrv#=6PK*YyU ze}5+>$Kgh7(~)sYrzsd2m$OCSJ>8+$O`*w{2Uy7wPhy5iJ6USZq~^TjVGi4akYk#P z(`@l1MHe*2^@%9fux7RLSagYd?yu9D zaub<}UUyB${bcYpRNWx7^qxYL9ek`0clhIKz06oml@%8`hm;~p8S*_XRYU6^664-9 zcktm^a5hK%f8Ep4@<$8%A7~?qX6b5@^C4=0OnqraW z+(vE(_x>1{_&ak1Pd}T4Go%CKaEb5`;zi!Vp76`-)mi})P%&d?3=wr)1GomkShFhM z&=o~D;l|dVGpr^P2X<;fs`1^LoHn~2uWd|F({DNVO98+OQONgrJ1}YcYK>(EPQ9BN zgsVi{c<0qd?y$!mzc^r9NjJ;5Av|?hs;hRzgx2uKj>6v=9k;h%fv;X953z#}K5=Xx zDM1Rhh8obF9-pPLZ7M?r=x9+n>;a;>LFB1H*t8#ON;X)coS%RoXxRY(Cvf0Pq)y^& zJ5cq?SdQx4O%wbbLQP;DD zjSHbvND3qhmEp?basLdbP6&JB%nohH^0-1u@;KihsjNB{3q@rI-AW9lU06?aBns8f z@}h8qU_+@7cXCDLk$ebr4ir=K2P%$P8cG_<#-zqGivyLqU@v3Qb*DprARg!El9fP} z?UVuu%6d+Tui(F#AR@Jt>!28M_1;=N1D-vLU!@!-+QSD7@+vA7p4rv9H4|%?@@Zz{ zJ%GU%Ho2o|E*UYQpPx0V*1`Xh*FB=FzB`v+(RfC;c%mYRf{vLn>+^gqT#D#!0!ofg zM#iKty`6*!C1(chxw#yjvgDj)B!xxpneP8wA$os23<|KLEs$YF2gjDQv97bS9<6Ux zZF+eXlFwE63maGUg#2Hg#_a!F_bqB}STt`$ino0 z>b!O0CT#-g;YD75A~Z@WC~+kUMFqtvki$hj2&o&GU-)TIHW~l+@1kvzN77nlW6XAA z?v|BJYC=NImnu{VKy}A$?G^nUgy+N#B9?&Ertehw`Af7+Oi8QUyNE#GVY#`f_O7m- zp@qoTyh_OdILaHPjTRkeAj>~a*Kk(8UJw|j4z{Pt0 zO_s^>JCaBeiecQ*HZ>?a?SS2UVosg|fBb+ww5q}(AmP`O3s_{e5zj*0MS6AI2`~3C z`PE+!2M@59-3Qj|!6$QpqZ9fDp>93RnGG-Lw^>VGyvwva*@e>g=MS=yljr{(K{opT z9l`(K%6SG>`u~Wiv$C%h(kVtyBhDvggM0;MmP@ma4AES}5HRq>h~%3J1i1=96A6TX z!_+?dFW_dlJ?5PO8OP>rHqLJtj-p~_NwGvWqJKHFaE1(3b_J?Dne)a{L`9jRR(W!V z@5XJyY@K%tP;o}dqW7!!Zujjg_pRfsCv&m9JhRN|jobZjOZR5(PD^RCb#;DITiktAYKdK?#Kr3=K~nlrAycMHe$sE4@52hYr4)uh0aKKXj#lZ6G$ zvaqwfj*3_~`zZw)i^QW-80;bfrkOwLIXO;YXnEigK}Dh_X`z{*ju%ot&(!w6w)IL3vganN*?2I92M!+@^&Wyz?8A z0Ry;msT>$P4s_T)b13YAEDR~oXz(Dt{Ae_=Xp;o|ur#Q19xM!_K_a>Y^l(0HqI9t{ zz92O-Ho`q;Q;Rk1wP+{H;C=o4ejEOXVVwR#f07;+aLy@vNL-&Bvb>ONM_lz%qr!(~ zHm)qJPzfSCFhC9*+U}q!vv>d8A7BD_Ja#7X?oct7LLfq6e~D7bG78?ERO-J9!bHQ7 zI}xPabG1}6Z8Sg=GIBdoEiE>P;HODeKb#noPcV1r?CaI%eNV)F>S5qy2XFU+->cPp_UmDGh-v*w{N%YAT6~^y6h0~pgOAVKTQu5{F4+;Fj0vD*n&;eGJ3iF(0PZUeDnda-<;vI zHax7+l(=K{6gSCekaUoIr{%iirx_Puj*|{?UQJ$oDz}fH5p$W-Acr1JHuX}Zd_RIO z*(jLK7>Yh%c_5(w=>U5BWF)&Velh7rFYi5sbIclHS$OVt@`mI9RlQHeVw3SbAQzgc zzkLK8kdF`(eoAmd?Q7Azcxien2jupnS5U7B+-RQ{xMrsYM(uJ0T$NviA{bG01ASVN zXoM!`D|!n(tgD{@V^C2w#Urgrz-UJmp4DyUN!v{N^Qw+sUMz2G)HIB|e)^&H1Y%~U z@f3ftjrwRR8k!yGON6+R-p!me)n>+MtZ1nXr&{^^>UGSI-790VcHp|#siR^o(V#29 z6mR^cLkm=CcJja8-%>h3kH3pFDTEn|h>#M3=^M9`3Ng-OFd=PyqRxiu_&YddGf>#A zdC*~nTj<|{AYlWSotifLLp%wE5OP8V*l|MR$6$UcIJR+*!-l7zZPfe`s?^q{Ua+=E z7RDs-qqzkIgHH{w-<2Hmk?rT817pheB=4$Nb~7EL*b`fIbK3#&=p(B-91}>?3`_>$ z%KM$X*h;`C)1cKDPhRh?tM24L5mZz0_0oFi-4(dWl-<k*OJMtaPgrMN#dPj1nyXV7|-FDTJ0(@-pHolo{68u?(|^<<9r^x$l^weKl*-GBMFyDE87)Y;*yx~7HTnU7fPq?3f)EMz z>ly1s|u-<9}0VB!`W@C z&UQh31lG<>1S$US%TEl^#-A({5$sf68%5c}qhi4X7ycASU4GpZ5TVN7XBUyxN<9hc z*&Q`fU!>Bp?RlBzch3zaruhywUINaI6s*WuKKD~Ll_up$ zZ(MJW6%Y`RV@D&`)8p!VCOcABNQsB&G}#}fAB3{5YqJM0>aUa|vPX9iP(B$RkpJmd4%}isBu&j2#r2#_yfh7nPA?(J)xf%T0l!me=F5h-RdD(?}&` zWhUc^CmSFcABWO4B2j6*+$Jv^OTU-sya?b40l@(08uP=@@Xiu^U)O;nOJu`EYe7r zYO^*EHU}9tFSoZnI+i?OC5c=(5CzKQ`)Fa6Bc@F#LKz}CDlS1eLVS~x*&CJzw18wu z)I_b%Xbs;O@XVAvDOJ+w!mfy;EHLJdFx|s&C(TI* zRgx-aS<<|4w!mr5@krbdCz0nW(^=8=hM?cC*gaB>T{?e_z?28w#&ZX!w6<>Xz`(vKaXH|EZwFjKJY}gs21>!$Fx?npX)3(jyc6D?g zLuChLQ`DP^&@<=$gSf@N1!{vqvq~isEDxaAIAP=bn#N5GiuU#dE;piOuAbWB;u^C? z(;V>!#kSR$>7?t`%I7Q?Q!2BSZZOA4qREEFi-wNH`7|WT+E2Au=PeF^ZD|citxgEO z!xgAEst`cuY-W9Gs7?zxe_sTr%U^1j+1D{T_HxZF!&8zu)DyKW{H&PDvUlk4_CQ3P zJZM%)))eM1v`stAs66@F8jV$8URMv{zie9m3AV(v!~joTXUyv4L6HYF6B+TJhQ6}e z-sypGk36$8+>}+1JXmZ~JH2IRzl(>beLbLgd&d>D;!edjbQD#eCLImNuf5++k>j>NaI2P+qQK;{pPoadB}qK&k@ z2kzgR`Gx#lFp|ee900r|e?WYs?8x!_R!v6IU(?=yd!)K33WCrEk?e`=Jm7KnQO(*} z2_$DeqD)^bjT3CRx*uj&mhdFjoDpug@gu_{E|1l8bGwglmAo5 zCKtK^@a%Hb)87}PO)J>N_F3%;TMQ6^ku!3vT|K*wy86E(+tN zbfr;8U`Ge_F*LQ#W8<={ArQ=ciMDu7ye7pGuXj=fD#;@{r$}jk$@A%I42`!M#mbMH zHZ>F=cBRIS8`dBaKZM1h<)haI?qQ~W_I^Ej@YAdljxwBsr@auhNwhHL^Mnrx*nJ9w?$-1ygF1iJZSCUVbu>fA5mX&{K|pFO)h`1aA))aB#L;lZXIMSb~6ry9&Dno z2f>+wf0o3bGR77gOk65@ko<~UL%bpJVXR!o$#n8tJy znE#rZ{1ua1qyUFxV^4qlE60HBKd)@V>VOd23fbnxns=W`gBW&PA}qOFXm*_{Fm0!V z>sqcT2}i>;a*^~GBfcQ<{H(><<=IJ8jz|%rV;PmCak&CQ0KS6SB@+y4tu9XyjIP)(XVeZ)Y$6F? zsSSVZt;sFSG^KFpGf6U0_U@x+%i%u}mN(M@$hI zwsQM`-wl#WJXSHfC!)(!R9c!;PvZQTY8t8mmFG1?bslez@P|zouVjD@%)4ZnwIl9dxdy+tY<LiMs9ymMz065#3$;v07X&>R3=TaJ3K7z0IV2VXFmysC zsIUzdAhloOc%r-WCAr%=Dmiu~4?~&PK&!O6`_*pNjHF!!6{)c0NIf6K!qTF<$CiQQ z?P~V7-<&cTl_||ofQU+lg?!qADTy!`j53&J)tY8MvIw!V3;wQxf6%Hf&8qmjT+gZx zibM!c`xij&%*@>S$`ZTbotoC~52iwce3JE)gxn;)*)hHeza^V$y3UCU(vd*0VvR!L z3o>r@$_L+3~trKEDHT`DA0e%F|K z(9TiUKfo8sX8%PW}YC%|`)M|liDwuI>lQdVW|-q1Nv z7m|>=dtfZfVC5N^fTVsj>247N)wFzoIK)y`lZA@lTt(y4uv9xAB(f*8NnH3zjzpUX zwJGBHF`ZA(gm!gm}SPFXXZ#&#yXNrEVYD`ZUP1(6nRyb zN170Hg}fI=frk#ppw63DzH~ds-n~ZqE8~tRXfG5Llj9P_xdOpn#<`8HHD3$8+smy- z?W?h+&a;7s+xsUzo(E1R70!HIY0~V!@6<73ny?;HUKU~gME$j$w9UDEo=?>23?E0! zh7V;OdV#p(vA3yVlLj>%Ny1f&i3RU0hJ{W{rI^!tSHE<=(JK`boK5u~zi9=KjG&-5 zjR!8=hyHv+T#xX+cX6{1>uBem@dB@jsEQL`mc~3WRaLb=bNkWGAQu)F61P?X{1OQQ z$q>il2Wr3>nnK>ANLa9tjeFII^VB-^3Mykf(K~O$hyT=wW2?AKB#x43HzDdk$bM74 zTPGL(nE#4(^6@EZ@im{So3I<|$L{N^v$jni5>1iHL9N)j*9*XHVt%2J*A^Fd3asjq zXWy%~Yb^%K=8s@82|P>SJSr^(R&a{pwDC|GL7C zeZqVzfc&X%3QNxb$shRB1ZQJPf0VK^s-!StLUU&gAxB50#yF`ja|jx(=b4u4yg&zX z`(_n{dQgRGMts^ani=tPI!=l%SiLNW-(vzUQGGZ;mbJO}qZ=NkmhXUV5Y$K}_#U^f z0}cLVA0b8{#KHxBRidvNMrLWayBNI_qglQ(DhxtZHOGa575HR(IX+g*WKx=>VH>U# zcfmD?eSMwS-dWH6TN08@!52mZCuJlFjjNYG5bR1AoQ`<29qxofgY~EPSC3vV?yM0r zOj40~;3{nsLir;dgMnZ%RR_T5ObJ1C2deIsH$2Opl574CBvNB;@&Y3ca-@?P6RQ$c)1CwC+k()Ws)sj~RrPFbpMCyc!0Z$k zUX7$uEu`UEm1`!fMO~7db2iKRbU>$?KWk3Yn=h4FCndktSp&H*&o2ND%NgNWkjd>G z4^JAy5OrwN-Kuw7`zmJ`RZs|9c;rGoVC?VybVHWjVZV2Av3$d(=3+{NgO~cDqGhS4 z=fxoMVH4a9C-R}azuh#;8ph?*Tg7q6+S}(dAk5xaVrWs^=@=Ro)ipI@YJz@r~NbalYjDO;2m!S(mJ#Y~5te;B&603^=&^ z5ek9h`U`(YtLeCb$(ySRBkhjC-D42890(u$KY@M&om!H-BWkKht@ACCxKNVLmySuh zNk`=irdK1J55BiR{qw*2I^6hesbUcjV^?)9I`lk?7KD_4W5vHRGpOZ{Elnttq+0rU zo8B7Ey!Q>xDlE<8Z&j~k){}FSQ!>S&J$tL4>}cNdHZEP-$L*pvhLb5JT-JAZMi=NH zdIN8HZTpQBq!q$+F7My!$dSiMJVzi32~&UzN7Y2cGz!R?#J1DmU4+FBJ!ikrur-Ld z{!4@5e*)NH;9&m`kfnDLl$Fvc%4n_8>N~#80syV->W2rvmM)ZeKEIzz0Y(!P@$vk_ z6r_6^cNxy8OBOI!3ld*#toOIikc9LBKQ@?g^)7xO1{iz zjptyClsZY1>|%0^6QB3OE7$MuJ030pJUlnd!OF@?0cCJWnS{>kLsxLa3aE9rRiZYL+T~GmL$i!zbya~R zL8?pvn#{@qX>f%ImD=P)rp2)Z$!NwWWPMH`0#h7^oID#U8PYT`qy^C7 zj7-84*FDGE;-K!xGr9>9&TkV(I!Gz?4ivmFZrC(A!@ofj##y9O1K^Vq-=*VDfjKF+ z`vsmP(_mz1UI{4hkQox}o1vFyO+s@st5OZKQ@HU-ws9EUF?h@oxhxOpO5gQtJu93M z!qNyag%^@pevJ1$Tlw1gHrT?qYEjh8JV7oN)=mX${! zR0LjzA1~U^d29y?@zp}jyZhlxh|Ec}b|;9S)l#H=|JbV99@Nuu*CREBi5&0I*KY>r z*$jHRUy*4qmN(%SWJtCT|BsEh6P5wqd63K6>AX8Rrr_S=+jh@mn;7FavX7!0Q*&cR z5UgdQj;Vsn3O|>}`)hP+FSiTZzH>-)7QqZ{YN5%sO*Y~jt{A0|;E3;5=6y*&oWYy* zbv(_tcB9-m8h*kp$Ex2 zw+kc{vB9Bu;A}=YUQ5(1*TS*C!DZdEtA~0_N|!QoWz_U$Y;GJN%=eFgt2!b}CypXf z8@7uzOQ-Y!y}HVtFlsLkK8)QWa(MQac!F|P^*a^*7xl~_Q+-&_D@LG-4C{H9CiRnq!02r^?xmXA4bmk%dH5Sw_1%p7fY8?7=Bh^h`qr>5X~HfkM# zR3GZmjl0*+PNUnn9Wov8Qw;sJi-x!zr=||9DkDRm#s%{%Xj3cFhPM6{N$4IR5AYe3 z0VFM_l3&0UvP-6bh(#aZbWV5EAQZ!0N4Ha2V}3@Xfo2GsPjs#hGe+Fe-Wm}=eJi`v zuPMJ3ZRez@MrtD)_6Vm7ESL4NHoxU$>^5P3D(=IJ*WgrqkSI^Sl;4XO!M@AzlQEWA z87rD5o%WyUUAUg=%9)jo2K9#I>RY!#gFh++T*oVvS!Bah9$sh6IVuZ!K-1+G0uL zN#i6nJbX$GheY6*pyYuCraHt9bqm1@23|8{D;C=%{R(=kdcfMv%rm2I5A8~xm63tl zKke7Jvi_8Pam9eQo%3^h?@y&K`h67QL~A2vZ;fhDq$h=pO84$zogPYdX-kg|ik-W? zg6+xvWh|A&{sqdL_t7DNuvM-fXu%l~t@B5)=A3`p+5SxsQ&Lo+0xN0_N+c!@1lk9> zFC4X}^$M!7!l6m7@vG)aa<~lbgtZRjl(&4gwWQ=~bu9eOR^93AKP&Hv-34))tF z-`@FaUPK)N6BEO82M@TTomNKGbxDnq0*G7$I$HWB1_nGQ^ zs+LeYIAc*P$o7Ki^aG~$nc|Ms3X0nwoqf(VdHl@JU%6l9Y(@@+xfDb7}+qq;q*(J`NMhY@AqKU<#g*AMTwD?JaFS5 zss3Tzx^{YTKETa!Jy;YFK>Y53$9)7D zdzR9#B&kTM_@a$gVMwj}NO7KETT|L`H@hrY^vi1tT9$km+;Rs(s3%uWi*c-s_6buE5M)RGu=VTor(vf zG0v*12Yk}SIoMrN7o$sBbCHZ$_7R}cAVlh9X+QMn;c*zdP$z?pl62t8oyV3H>F;pY zs!hRXPP%2oU)g5nFEDr5&7J>p{{ANhR?Lk5asG^q^$iU4jg61&p`7d?9T!|)U>g41 z%Pji7esexGhChcg55i%L;5A6|9i{n(HI6aT(|5rG$H%@49O(eSmqQYxYXzaJqhoML zQf|ONM?FJBM`b-iQARQ@GD#vcC$OME)6h&iBS%3)Q=?!zDn&9TB0VB|AxSYR{-d+{ zWnl;JeH~3LB}jt6WJV<<08)8>KRh^e4{aHCe-$`!$>0P(OeH`E=Pey96*Md%gS38i zA%gS{Z7GAqB|h^9Ir`WLm`hm12iW>ZS}5SoNl0%%hwz`?(}Oe6Gch*2$$ifEzdmL? z1l*Ro`0(-M-iI#9p5Wo`PKxy28fLcFdCnIs+-Sb`h`8JUv^2Q)m-YfE5Y84J>ItTsnTuq<~@A<(3;wv{YFOqr`A%!PffyB zt@^hkIownAssB1}g6&(Y!O5c|8GQm(pHQtlUEFe5TVsS=rZ}YHK}{pxXC{w2p#UnTLu}9$2cv$>($M+ zp@M@|6l{#QI~g0uX@fkrFuP0GtbR2_9#nF&PNsZ9fIUHlY@c_?FV1`U%d3}Lwe;0C zgKxWr#Ty`a8?t={*5BIE@#qoV&P>`gpB$XuMFV+s&y>B3V)H;~E4y2;Rt7FqYj`n4 zZsz;IkCb0_f^mF)Ik5@ypS7rmfd{cjPOAKpv&3APudkI!Q}!1^4)QF*IC}B%LhsG@ zz$Ux`!Qbt|iSf^2Ax?2gv}m)y&*?1Z_~act3sKwuLP}+4{2%DOI2iup%IL(|N@JN| zkKX#fco-FT1cw;Lyd<6Tqn*)5^by+#vj$$lS&fA$Z0^+Su2@b!@0r;{8U;Gc_9ykT zLaU2zw9~97XfRE;T*Zdh{`)*hXGuk2FktSsl}Y84a^u`nB9zkQ+&+5y(DCl>z5*nT z3j_SIx|Xr- zE0{$((&UcN8)NXw`Ll}p5FUVdJkk0V&2v#vp{!E}1MvUxc8*P&McbCnN>(~6ZQHhOJ1d>} zrfu7{ZQHhO+pe^`&h6+M=kz@vI?jiV*gs%L?6KEeYpyY#Y5S}G*pR1V2hN8*YF!>l z)5lzLWsjPv=B&OUhZF*Gf&YoWK5opq!SP}p}2$jfrsMCiMFlk zg4i&~ebma%N6@!y7YG_g=T!XsLv2GEoP}n~1ipZxcgUpxL|705KlQK!_2&WKJ91qb z%ad4xZ5CL5KimVH0z!nl!Wqk9P^mA&@%P@cmYz)F?V(dYEcP-pdXR!PmmPbN_k#Ch zn%o7_QY|N%nDumCLdB8clNiR~!FQ81UC;ZGq8aAy`lTC}z}j)1fE99dB8+suh6%v0 zJ7jp0k*25K@Fb$|Yp?j{+RwDh3Fh{g7Fp@&r~yNg+tgybEaJZi2#8}-VIgF$dVXgH zi8ru^?AJX(TK3)gx?|!FWL+bf9$m1?Gx&iG1%kI_-+N;@YckX_m)87@OP0Uh><@x3 zr~Oue?_AL6zB?kNwdzSuh%bLpx!xRjndogy&B(2-oXhXGDrhHBI0|93N$R_KsKv$? z1sb^bT_9PW2d;WN<8N$FJUAh%qFC6SUU*s`dklV0B0Sx3$2G35D@BNhzTHT^Uzw1T zFS#%sA@1Ny0#5kOraK$aXRA#!*4Z6!QuDW#m-+6j&b-ON5~-Zt?vxBk>Q%!Oj;N{m1Q(c&HK%l)taa=EW^rWx5B_r&rhoa*|GP9khK1YS z!!7}0P#d`?qpzv&oS z)aiQ2w`7&X^0*s_g$T%-*qchJSw#A1_-cgv=or{keq8?Ip+C#a(UOO94EaCBGDsQ* zW|Dt}*3i;K4`5_8=l)(0aHF>R9RC@)1LiYK|GjzJCG7YVe_bRM(Oz-%ZC|H?=7fey zdzMWz^Q>fg<&UR$kKt43t%j_vxwgSmmSH%3sd0bQak3(9c^#vUP>1iiJyJDMGM&Y3 zF+T~pbG14<1(|Cs>D=KU*29VS>53ft}o{y zC*)%;w`EgQf;few`JU0iQC@B_e$+8x(j;rWqt;ww=@Vpb;B9E^AR}d^<-#HMdYR5) zpU`n4ox$sNeAonSBCXM&_jU-j&|$v8)P9cDL|hJ7nM&ib7{+e9&Mq#|Mrto^vbjv} z>r?A|DfvWf-U(k=J8DfWDf>Fv%N!h78W`xxvEY0D0^{c9pM3w!`w2unJ3aVsw8r`$ zXpN15p5dR*0b3ew>Pjokd_Oo&*cbhnX`I>HtAv`GW!Yz#ei9;x|1{zs z24##*iuH4YBaTH#Lk7)kYH})HDQj-ltXY3ro^IgUp7QYG`q|aIveNzj)pp~7XWM;$ zch%Jpyz^GIv;Iro>rEcmPw%$=6NB7v@HRpYo zqE-5s*cGa|D(^DAF|7Q1?`*Jls6oqF^N=2~|-gIfaAL5(($*B2syzGPF{SMay#( zbGS#!M@*KKLknIM$^Y^#l@=}9o0BvpYm&`E!}w$SDF6W{^iq$asDrBd$>^aSLjC~* z^A{9|%T<>rBu7bv90x=3mlR0q73kWB5CY;bB{D|krVvN|;MtYm4eo`1 z0Xsq@O@xQF#z|?uJL5kxWb7IYjH3eX6ZkgqyZ^$}yY1(3IclYL#fpiAzyx5!Nwpd~ zb4nzs>95Ol7igoJw~JU7gD#>%qVgp0WIT6JQ+*UpIFAf0=%;XA={2##^Qk#lexiR2 z0!k>ZK%zK6epH~JR9V8gy%S~1DZCwh8i+%Wz8=H}4xy7EX=NL-nuRhz%O*D-t6#RT zXP11Tpa)hlPijF9e;jDY7FOu^)zscf{ zh_vcDLPOj`A>2&=g=M9-4r-5bm-wRS;N{hEJ6X&IL{NiD@GsB}{C38cH6n zp;#zr{L86GBn^+LtoAOR5joMS!8vv^}k6q_yjr zqc}q`PzUAo{Mh?6y@S8QS4gM75MOSpmY>i4Qp9+4juju= zC0mqX@%?!mv~Cuk$1Y|7IX~3J^~=oF#3hZr z+F#Acfk}1!c#Z&V+A$@#DzL8UQsX-?QNwBK{qVfpb@NB&%d%7YI>4I;mbWJXJT#-p zRE(lAr6W`-hy^E!$=4o;?mIy`z5`f`PxwO)R89WKtW#WEaEzsHCi{(2EB^Jw9{;Go?0~7<1P4pf~mt?n|^%}ZKv1Y@y$r5qLO-s`86si=sXTSrO><2saANj9)VUH=vB`hVP@;D}iFg@LuI42#cs8jiVHUmc_--AYh&o*>f?s=@m zi1efNJDmR7snqF@D#xe3C?OFV1X& zT!eN()nwc-H{NDCMP+K7OeCyZIwSW3>=dbqBI5Qz#1%lEo!m((Tu1-A%|EjhgCs(p z&k^i#K+RuV_UmbM0_rBKq|4uM=e6;gf2XDU8(HE>#wyK5pUJEfSFT^_*4-OIDN?P# zVb`UH$&Crc zCD;Sa?5s_1Td*3xxaxDLv7UK`p@o)>@`H=$U|a-#thVOi6r!jA3Q*& zml+UqogZ1rS+l+QE4O;gIAZqwe~85y$HTD1I=~}<;B~lRAcls`2N6In9UK+wmnH(X zjQ)mqCXDcR)cK|F50kI<%1!nEGMklQZ+bn_MoRFqbH1tXlH_v~4nm&4B=U%BMzCU6 zsQ3qX1v0k$I+89#7mIMJL?iy(Kgq>zpVKcto*f80 z;-zPnql%~(Rwt4GlZwqOWV3zfjDw<+ba~IdoW9+R0r5I*EG5q)DFIwZ)P_4EjW6VxTA$)J`sF& z9$||*jn=i`*?B+zD8vQ?8)z|5ZpY`)&d_%GY~T4?{qlNwiAU;+Bw`NH{OC0(m@gax&79 zC1RQZ2e$3%cU21M=q$_vf*A1m_w28n5N8)d!Ou!}7+hqkIZ1rnRg6Y%nw_EdpIfXd zYvohdzu{ZM7=-6QS#jSwPc9X7bQePWuC_+d;twKxt=7vT4hc3+SERMeCOeDPrv`Um z=o;)awsl>}>5qiE$4sE>DDF|*#t&QvFI*ooT$Ra+g(}Zb!6bUZXxTK%tA%qA!C+??ayMDqX3N)Sbc-x4jZnzJPjRv%e}wgqk_IdyC%tD&yh11 zohUn`wX(H&nJ-70P6hsSVDhjlYiFnwHxLiZ>KJrp*wokrKU)`W8=uz)w2Q|qq%!9M zPG~3AT~~r+q^?ZdfT{9}rMn+u3Ek4_m0wwKpE$hzxh;q;2rY=N(wZHC9htN825waBKiG2OR*$7p0x()Mz7zSvr=@OVJVu{tzGkXdkrIxA)$NVm30( zr(5x;V+LJ~IiV3CSRmnpFO%Bd>HVM=reF39O<*EUo5tymzi@CTgc^CdB`}-Z?3Tx^ zKOYbJ#ZYJi&~WVY1|Geug&=xRiodQQTsB2K!D}}TtgN`}^ZA1p^?!dUJF|k^M*zHX z2BF{+&nN7~f8p}XIy30nsNGZ2*GQz85R;Wm=<}FHn`t@X3UzH4xE!}KmM3r$QLU(H z+k1B5@q#d;^Lg1eMhy|&g%B$DvqOhlw7HyF>{Q&!Z~9asKkwZ%!z*>&@QK&*z7XH8 zX7NQNs>>bXEy5T^5K)z!8&Y-IOSS7&mHo0w^UJR=!#f@4Xf^}E-vou7s+;`* zrr|DW(-OS%gRmM>vuLU$j zEot_vOY;xbXo&z8S6GJ5eDYS}1y> zP$1l_h^iI=CgW!p*=?`gAw2w>J-T~l4-gu>Y8KN`I<=nu6{i+z3d}IOlcvFH`-@XA zV4-3PE93B8xr!reb~-(iZ~^1_D1yZe-~(-FbLn|4;_um~T-eyU1hw;%E!|;^6tSCz?1tD+f%g1n=_WhEl8VJha z&m)D#xw1GQ$f{m4siM1ayvZhtDKY~jFXQmuk&>`Lg$D{VWGOE1DIBY8D`;GA1}p5Q zV1<^gli-6ANx?K}bd)?PZ4TcrHQp-wFsfVzQGF;{6sZucrhx3cM+D?{H+^o?mGdta zI3&xmZYpag?F>=K4geV!uM$kD$JhEgEXK`T)FNpv{%%oPMzsy5p=pI`_Q@qVKaLG{ zL;`zv1X&0-=w7E;OppG+$;g6nW*M7OygrJZR5tz>Ch42SY4_@i+nf}#g2ebn!360c z?0h_`Kf~LzAgo>&5-QkJM3pLI^m^~=*q*2bWN5K;@+pQbqMa{z{J4LAljT_BZLHB> z50(jI1jdC;p#q-Lw-nHGjm&*R_!CCdi#GREsvktg`)4wfPK-CtjNnUt#%nV7qbRU0L9d8qD zouSMaxH??TFewdVevQzzEL5Qr7*zn@%Uu$5ze5!$*ghkmM5-lh;rY=dnJ`J*l}DgPK30HWJ57CN?MyRbKp>b>E}tp-{b;hzNEx~vVfFI4Jk;#z zu=10vW>EY(X-+Y%D6D5;qy}<%l4A!69Wkk)Mq5zfOIP1xLA&9+D=?`x1X7N^dM^-a z-*lmds6MVvd)4O-ytd@(er((abf~BK)29=)Y}C9a{MG3J@u`aTH$;SfpXv}4Fy>U- zYg2?iFLk8kZ_|g7KiQ2>>OEKSwO8H6--?<(iPGQw&F{nu37TXZE$yZ_f&Klquk#%_ zH#e--J2@XNypL=MdyBG#_f-h`tcI5hzIaArI>Yd}45f5XtwFf^fhh{#Ci1!;rq4Vv z-S63C=xCwq7<)(XzsZ5>Hc{AX>Ay)DfIs*uV5AEAjrKzm#Z$p7bmV#rsDtw}_i?!o zj0YVWdyla8;JUpaRlJC~av6TTJr z(#8FpLsG!|!0*9cCb5ptlZ!(QXd?WS!V2MmygYvm;rwefZCVuv1%DqN>ay`(4ttk9 z;lD_U@YZbF3cr#WxN14kMQC2!p#xJi2tDCuFiPf1k4{z(een*f%c=M{)9U{zt=Y_) zbZS{<7_y+UXWJaa)$9>+%L%Er#0PIw{r@z@ zUW)$_brN!@a#9pGVLwY*RbCciSP~-^d@-PP|@6I>@uq(96@J zuPJV=szb^^Mx$LOGZPzF${LnJJ0lT{Y@wOAps5T6r`kG{riei{C9Yh(fwwW{1@AF? z@R+jRWAoj7-x2l|hzz|O$WZXBFLP{o~iE73DR5*;n?wF>_wZM{w ztM<5l`DV=g^uf%%o`QVaz$+&4?|ye%`oaRjT2;4Eu|^7+bX1Wo!`)x2)|PgSTKIm<%Pom&MIaC8%6_@{lKpc4`7KhLhU`X*UD38U@BH>rVq2BpmD|+# zLZ2!_O5Y%2o)9cGvlf?CoPoeLPH*`7aCE-6Mu*;j4_&XpVfc^|5Fcf9$$q-PM?gUE zfj_7thKwG(m0>(v+fS!EA{PsIplc@lW&@^e>?5t7VR)HhQVM2EQJ3SYkK&yfKPX&K!E&wQf9=BAqXeKu4Xz{hb$QILc06?0dv_K zA+*`(MAx~rTjg-g$`;R0akjFTnrEM^Z4f;ZMFw&V*T_yD7ajM~*BY{RFv-*3hR$7W z5i8y;)DtkEWvZRLHZ7#%W~Q?@mcjb)^S5ypSdi?sQhPBzQ`pD|`mA5F=R=PL;@Ps) zk~^56=50*M?2}Z#?6VgliEe4~cax^<$QZR1xA{#NylPx-#|7+$TY;z$cmPcWYxR1kB!Lp?D3XSeac7W-i8!*4 z@mhEBRp<>v&1d&9g;Cf1A0LBlo{I03V}f%-Mrx8%#7M+!DR-mgMTloN-G^Pd~D?)7s+lfK3~QyuZY ztLzIGJGVZ*(1gu8ZlxHD`Az1KM8&0~=FC~rV~;XYg6Vc92^DUvuCql?@vWyBKxK+< z($h6lRAk1viX={iQKt;F$!Mv?cYfbI|z+G2aW*euD?y zP#B2%uAsS!uCC1*21((K9T0;v%3#Fy(Qa3-3yzX34q1j(dnT~uMf;zYht^*SxyWrk zZdQj?${WwAF9v;ebU`^Rg&Evb%Q^eZztuIZ>R3{+?#T%TX2l^6a2iZ<7)+-6h)Vn< z0uvvTjLJe~;Q?p@Jl&l_BgFFx;54VI}(Yhh7p?8!uYVd1h^GOsZ ztiMx!x)qlEZJ0TKpo3^86lfp{=-YllX9q!<;8juSx#^>{;=_+3WhO`*W#oreJ!|=1wqOCK|AG2TD zCoV@G=5W~0_bWyi2Q)JA_eRs9lc7Wo!;0UTzh3PgWQ4M5Vr(=~1o1(S7WU+FrPQ`=ZUJvt zt+E?_%%l(KJ*xGw^;)JWfh1_T-O^Qfg-*7U;4XLePbUa{i{=K8eES9c`V*lfe2AKJ za<|8^Ok`-X=`-{*+9J3>p-rLK@;i#U5M$xvIjM&6LQTZ-Xt?({hgnTy=T`x_#rSaC zfp3)hnxuW6$)9!jjxgNUH++EZA1O2|w(e^cj-|HoY=igts|&o<3 z4@FVerJ_uM>ECskWiMhxH*SiKdSChWS(z# z6v;FN!oRbwp_{Y!pBK+t?(Q)Jamw=#+iO>rJoXT<8=Y0_T#=EojnrSoxKH#pt?faJ zG2}@x7aTVhwW0=7A2C8Q+{g(R)ClsTJb{B*Q;I_1K6Ke0MiqaA$v#Y3qyTR{s}yMh z@GjY!xU|aC)AK;q4KoTT**I1*R)F8J4Nh@YMaJMi?^Tneraywi+B=0iyaju_|6cUg z5R5z7QKt#$5-hpt+cl@UPN&F#|@ zd9V?SNr-2cFV9mzDKWqY9jSncOuu2)G<1)n7|hHx#rNG4;|lB`4R!z%F45t`eI&TC zr>FgNZDhT`aJ^IAG{cD)Ru0oCK9QU18XK?<@raqSa(M5d-xO2BsyxfpgP<(;YM_+w zENe|3rt;f+14ErgpIzb2%`xNuwt2(3oZ;aENPG?U|Kj6&(dDE>`206Fg8#&2`hTVh zF)}c5{PT@qmWr9YvKp$l%z%d)b1Ao$2kBe3W^@9hf&xQ9H0E6E;Gi+G@h1K-%37XU zy3Q$pZ)JThs)#KL!cqTI#F zcg^#h<{i|d&-e5tfW0o znmufg*8s~Ygx~6Li$qq`3dd{4(u5c#ZpOb+s7bV_v3TSmIRTpR_VXtT1O`gU*}3rH zrn@N!?B7Jc(Ygi#Qan6@scs0!0yGf4GeS{+DSS*OiWc<@U0LttF7Nu9J07c!yw<&k zNwKF&m9lI+7aJ7;ijA%~$fp*{{s=_RcalV5f5ka_P;$P?4x5;d%9lekww6MK=SrN~ z;C54j3$>8mImulPF6bR0S3%i6YMovALHQ_lNd zgc04hh#!0yoE(f?)mALh$x}N26DdhVE^l2`?AI{Qf*LZVz~LzRR`|W)NA@Y(u>k%! z+Mn1=>dJ`8n!RJIfAET9Quvzm%G!m2GH0GengY>Qk~?jCQ0sX5l5`*>b`eS2RRJWD z6!{x_C_4j9Oav_$Pj|>}Wl(^&G^w-#CCQ%OAz^e-C4%{)ASv1>b@}l+0l?Ky4PKi6@jNRnM+|K8F zzfh1tm-qqHt*oO**KxLeXOQz z>Pj=UJrU=ZF%p4co1V2BD25fHx$eQ&Zkn&^$DAAY;^R#M0oDK>2kW z0-M6o`k-y7rV`Rr&RqhdkuKVs#%l1g!d*V&~FEm^6m5k@ZvLP4@C8+(0pB> zJlR96#))Yc9j`V(?&`dv=DM(faP?VC zkgO$xCQw)OQ~t-)m%->Z*5whak4{J#&g>Q*xbB^E@nK<|#KvLc@n z$HyZogMj%(1KNdk&8a6Kh>X^cn(U1T5yNJkH8|9Bv0>p@o^4&u_Rxx(CPv?jjy$

    H2o_h;BuI(gM| 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 Yc|v_X!FIT!LSkZ~xNL07+A6sJ3*O;Z_W%F@ diff --git a/resources/3rdparty/glpk-4.53/doc/notes/keller.pdf b/resources/3rdparty/glpk-4.53/doc/notes/keller.pdf deleted file mode 100644 index 3aa69388b23722a2de031d594cec1fca03cc68f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85985 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�)t%lZ zfa$j-!m`jaGEO5T%u|Jq#up!y)lw8%v=>ifJD*IOrXH`u9(~YtiC&;eUut^*bXnuT z{#BY*G}B>;=y+phD6dOB2~Q}4BB6@h%-1TVQ?qCjTlg4B^sD%IK2cKG_Ys+q$ zCje2Lb+c>jDA>OlpCo#cH+1QfMu6lD+OwBcYlm0TT+|5-O^3C0l>*iJeJX75L1wlw z?Ge_QU_x=nv>2ftL}(kS&F6sdEmK9`3L8e_kTe_?Bm9wcTrk`Ez8L8p7Eo%S`3AND z&4A4H!EkmdYbiDxKlFy&DJN%qqc^IUdRz3oHzA%mJm zF37Km1GW_5;Jyh9#{FOx(1OvwUpHL~OfCs+1gPLyho9b1g7(guG$)mMCD#fuCanj2aC5C6_}5fe$-`XeD0c*0 z!b8~#zB^%V0&FPjF7PaJ=uA=J^-*U`R<M3y{3ety-C8MmN6IkJ_|~!pGcpNu6x94uzTs*y6KRsF z_%D0RLT7GI|~_JWH0ar4w$9xo5+_4mK!HJX4xs~!z&aWigFK>o2}K* z^c0P=gB!=}+qc_tKLYkNl)ZcF#?ZG2{-r(6>eeVIb^SLgHvV<}(OL+aEz^z3fdOr1 zKWEU0**DqOuncsX{xE4wpwbInA-Hj-OEiOs;?J*51FUlZ|)waEq7f{#S9Y-TVc z(^m3OE~1xNBvGb811^Gm_}tRWrmb+GJ`MKAW7#>(Hs}i)J*R6kjm*XX3{dVM#SsC? zq;e~CS0J3XWJ})1GN}(P&o60;tT!7F=StL1O6V%+C^K0`uxOGylZ5zMvt9wDX)dSEYvY0m(1 zbVTdP7?(7-i!<@pb`6TT>J|E5Ij>eK`kpL1G_H+-ggxBz9cag#!Mfy0KI@e96AE{QKf6KeQM+=AQRZ0UaSg<`tqTpT23PNP1fc8`p{3i`#p)Ma5eGOR zwO)kc)as%>l?l^}shz&x=fC8~b~XPUmNWmaV!RpH82(F)ceR?eBNoe_pP5?ry~r9v z=ay*uPSCY=OJ~`Lgq;|cB>ld{aX+@z zp8aE6JT7*4W@Z~oh7w`pIZrF88dxUVw%1NI8rtN*&Wgjn87|mIeO@+He~S;>+Szqs ze}|P2g+@)HA!z78<_!+wM88Q)yk>${eUSSEqFRF~ zIc+WB!kBXqJf@{~hGT<1Js6UvBsdU9#lXc{D41o;<5M407`j!Cn@%r@5MnPTq~4rf zjSMq0<#7AZb$Uig)n*3KlL*uW+iIS+SZ75=;SR0W1?+}-1H@f%OewR-O{^thoJS4< z6p0{-h(StQCou{namc(%a*2x2gt&rnV3DCeT*o+7 zqiFOqPpOE=gzW8z94xNXe-OQ5KJ}@PoG-m8T9`YVviQDjtQuSGbX8gTehu6ELrROp zv28L*BLm6wb7tv?=&MsrXH%=c)JR4~=xGQr73O=B9?Wz5MdO23~k-tUeBERElqJH@aRh7)OWU2X}k%9VjaHzn!GVrK! zO%7eZiK!DCy<%lI@MqkA=`PAaNCB9bZNrFwc+b&4f+WCLh3t}??E9i9q9_pG^z(dl zVHic`c!5d6L>~dJI9&AE7W8-mCV`xbXQvkAAp~R|V*N8p96F&AGX#Q}B0T-iUWB$j zH7-Yjr8;67l765~<(-_Q#zJq%CGqIq{0EqbWuLw0ktXcOFE z7EF$48T|Yz;)^!L75I_vF7rW#P%h*v2+HS8=l~cgZsN9kgyh`OxW-_Pgoj^vPD7Q? zEq8A7caP8tkwy_ay)Gi?3v+}wZpLin!KDg6M!UjqcJxqWc7oaoe7+)PZsbb zvdau>{`&8g>>l<3$2>ciM?6e=AFSDzAF2vnW3Qc9FwK4VSwzi^4|PD4(A6d4mqdxA zSa60BI}{Sw3Xk-A*V4F*NLIbmzZeSb?3ds93lO{ffym3rs!c;C zxUudu$rsonRd+h8v;Wn|Ii|)2YM?6=ikY)J&ARvwC7%-0$}8sK*m?s%F`ctLeOgC| zZH)LKjMKprEQIuOVB-^e+W>pF!tCQINma#Qc<5$9b3jU22B5<}iz09bgb$(oeCWX& zx&IkAI4%#tS>&=w(|>&(kVC&5)QQ4--UCwEy1H%Q{Y&D+mx5CbkkP9z(wak4+pv!1 z^-I6GFmUem@>8=3G8du7t*fJ>HH__q1@p2z{E|VqL=(ad2*OQ}2M!Wt7x%;ia`)g; z1L>cN{mZr=l~Y>TiO{nj7KYw`tJ_NTmm*Wpi!Jg7S7=DQ=_G6=YawHo;Is00Ic&nP zAr{W-mbR8&u>S|-h@iPb`Yx$o09nYo-r3a|P%6mv4uSR-SQ@K{0tSwGdoMJSBzlT` z|5BPwWF}P9F99s61rD)O&CUyUxQ-0LA0*A+R{ye4m8j~K4FQn2!9)U4UbmK9nsU;h zF;}GAx{aE9!ca(^+x;7B!<|FZ1mYGWLm~l6TiIv3S=A_4*}S&d^6w_ zWF5BSck;ppOUlOWTSITm5;a5=jRCT7wQ@Lf2e${|Np2-(b>Ss-OiX! z>EFd5^nciA!N|f5rjWB5|gS;!qofg*0>ZYQ@S{QBFGr*5I;X~MisU^x15rlvJ+K@9O2ndAfK`g z{CHgoXmj!Mwr}@^&+YfF=db6kWdzxuJMxH(p8fVyHnLLgo|j-2suR*FNtm8Yys%Ty zlOWKO2Vi)}F@uL0qWy6`YUp3!STPJ=EUiXdh#JXKN2*)8EkqXNLC>%PLIXT^W?KFE z1{Tf6$75wq%f+4=BB8@nMiMU9nQSIgor9#iqeR64MPFD*+2Ei!nSrc0dOqSHCqzWS z0qx@=3IYbBWOh2@pce_4ck%!CsFMU&B?wN4Kb{Wpq-&+=5>t&+?CHZykm*`)Ji>k7>DHOmA#JHGZYmbW z_SA`W0^ewsY4a7??m!0Pe@mBiex$H$bFTEo={93i4L6ms)2llas3$%cBE`!@) z1uQbL@hnT!PnT2AV+(WWU+unW^GE>lEC!^*kC7L)NhBq7=5rfU~ z@qhvHO)L-91$&$fqmZnsqI`TDesGWz78x1%hIzJb%SmqYvd9Mw==(NVaAp{n-Aup* z!w%4ZX*CA6ncWg-K<0pn4RHXpQE5AuC+PM`ycS=(NumNO9eKVze6k}41eE2NNpNPA zmk4|e9Z*1<zOXt6!MVMU5llU8;%ov-XjW)Q_CaI4eZu>eW5KjmEuI=?SS$HNwt?P- znI|J8=B~Maw-MuPMx>!jtXWyUkd*JBwxzVPap2P2lGKi3K(m0}1QzCskaNf2r_i9% zmFI84NmF?G1`7k$t4B(}Hf~$3GUW7*Y-<16z7~$aP1^+cRDZh(T?^wH%_-9!!;J07 z3g0L?q&-)_R6bn%SEEFMPd7`hn~=vQJ%u~OWH8w8uICF0b+1e^Z2*X2;LDUg7l5j& zI9F7>(s6bxWhf(#1HD&8E4)eMf>K>{V`jPx;M!r#%QA!oZT??S zR`3Ws_|Lbj6QDD%p|)`qqY`GNo>L!IKy;(b4){BzE9@Ex3$8)b^YgRHW}o={-rC&S z9$(e-i-#nzWQT~mb8_Vkxr+Y)p&?)3F6cJzCPRH>RfSzZj7xWrfP{FAL`G^#>I{!L zp|iAgv`H-BYXqEzwr!a9p6_3scK9fi8wWWpql2zc;H5Pq+d4Kj_lyi}*y8BpnTD9F z?{%C_YZh4JGN7CC>VL}CaGN?53b-WfzdYFyQ2u>J0r=;^NW584>N`7nuqw@k@(|x-&lg4vE z&VuIy8O+8Dq)IUo)yr^a&+M98%ed_Y1zPd*x{Q5U!k@f$xVG=e-Zt+btae{UHZ}|c zl}?$>f-`Zk{4zZP4zo{yF|rYo3S>x+-SE0RGk6d;*8n&;AJ;JFV3`rc=~?DkSkx?8 zoD+H8R#>ll-0_B?WUI-Wc)M7;c(xV)xH$BTxYw#j{@4fHyTvH4SE9Ci>|VaUdl#a$UfIl%Eg9gl z7@{i;a*74Cu*xF0q47l?Kk3 zKXUCgqAd(Oo-_*h?IOog=c?WTJ0W-<_krwEUf9{>W-@_^>p9#iSv&)`2XM~t;qbO4 z(cf28G@jj_om1HmFLORB-Zb#@47cL7z%K9@3CD$=2N3fK-Bp1QnVW- z)XC^~90(jvohoMlxi};6TgZ5#fgCN=e=Yh_tk262jGCSW*V|?aT`zg)_gElUpcf$M zaQm~Iw+&%x0AEtUJ>iJluF1n?jN(ilyl&jdacu>TY&{U-otoQoTnxz?St^RuyPr{UqmHO5o&~J zc*F4G<^`kB{^6Qm>6fQ%A4}fA8TsO3Q;al9QG{`*r#%YTLiK*0sqehH_Z5Ap1w+=p zfunXg@G4vtOH|_eBX)-~D=OV6B2p(Gzbl*-hCKUknE`PE4j=EEu8#8y%Kw1>*#B?v zA1nQTQ65FBK+7qrV)m%+?GOdD3|SeDp0sRllrK|KMreG>-8ZXLlUpQH+6pK7JwOP$ z5fl3#^&Y|Qrw8#9zx9DXFMrf@7^qiTqjXfRtn*r5S6yFZ%?-wQ9txIjs++pZOr_i2 ze7$bn{{G(n&J>r=$wic$lN}uH=yG?POj3|jLUm5L!H;F0=iZUQI&ZQesA-O6U5eub%i@79qBvM~ zz69w(@cmua5C@u{pWjlKR%e?&9+jCrrXvt3_j>odZ#Wn!%3CD1&C-ngmG?wmC|r7f z)_D*haSXQ>)6#tO?xo|}sdRLI?Aa}flkM|(GTcy z77|OnT|zsFaH}(WGn4Y|cc%s`?j4*tIj}Xs!C~oYWHOcrc#e)JZ#c@3VGHJdmkZMI z%?!5%)sA5oxxGCqs}1Ot7Nhd+jS)!K-sr2VAXRhJWqW$aQCc^}Qoq)r*0cXIGnMs+X}JoDA*2YD>EXksfC=`Ak$> zYm!=8L=rj)UObT&NxA-xXWdTP4aj2(_k!KC;RbAj&rOMD8XvsCu9lvGnwwa%4iav* zg@PDERE)NFklztG=0`M~cfyh!dI8f_Xp zlw&&Ee45^50;_~S3}zUk6%?khUw$RbQ*{!*Y9E$W4v`Re!`Ef#N3z+0DV@X~+ zmP$=DiI#XQIp(n3Igzv)?5KK($RPU0DthFS#$Unb#pT`zP`kd2N9a^P7zoQIc$e_Q zHXOlol@l`o12+c4LV-^-{+31U?v9wJV1hLcZ}~4>G@}M*YkU1(;2B|m3tWm#YuQ7$ za@%U6&L|Jn1Z##aP{EKQYQ1Z@Ar_d*7MKc(xgMOW3P*vAJ-XTNi(37z7U7^`04Ibn z|Fsn(8Z!%fsWa08(`N)J%ME9*y)5K;9p|%{J;c5@?#A3QUjc5$-ESdKJK z0BY-Kcfuw<9o|mwu=$(%nIiG;M4vxBu#f@}cv5JjRBT2Zr|$W6?jZ|h;fxpB z*qch)a_Bdt!Gi^Zd(IcaUns(Q_N1;rV>ejTLlU=o`XM(2g#BZqKqV(7@DH&^YOJt7 zZ1sMF-hxYalYf_58+!)pp?d-uTFpvB5GfHGvfH zv}s^0?@xEeaD52B&hA|r7_y`VJ*)1brN;PvQsiV_c=}aUDcdfHOY*DNER0U%uF`05 z_=-Scz%j}3T26)Tc^Jd{m&(n`y2(N3<#!!Z$@dknJ}mHBHJO2;{@o}Ie8 z>Ln!nw38W`>h-kM1zW!=liD8Dl!_kKdVIXV`^z4lCSVr8p7!#y)NAUoY^^~+ zg!G8vsUug-E2i1uZFsN(@;8)P*2eP!JUMl5Hq15L6aL%na&iUj zpeTU3eU=U8euTo;9mcs`bKJx<^VM+~E_B=Al9PnP;pQwfbXN14HFLNhDOR|IR+|yM zY>WZ#;7+`ya@|Geg785Q?b5bZ;t&Q?I#?&OL#2Vj=dhwExdW9i}l!QK|NdBbdd`a2ln}SCNb25Rtw~aa1mNvELr*w!r2J_$i~%G7qfZ= zwRfeRNP`}11kkm4+4T?4C~nrq<5~a;$mQIye|9UhihnMW@GmwrXOCcAGI2Y@{r&L8 zntJj;{NIEKqV;XK(_^t*9L#Xke!;Kqes}hWNTB-z)8$$zAVS2N54yh)DSKgD@OO84 z?m;s{@kUX5ILQI7N>DrZAoUTxmA3udKX~E46?b|E#Qm{koxn(%XTC3cAw6*~ecbg0 z>DOkp5+`5@0q5odkqgHmGz*BJDW8w&SJo%q*s*BMB)QXkV1{-_Y-uC=?98a45QD9l ztS3e#1(Vb^#GLg$_BWZ4Ov)Pv68klOwd}5lLv@YwXU>8+pY}(|Xtyqj6M_}?Q~6Do zKp}%$cHd>mFavnXjAsQBr&5hsi9Hmy=k~1UVKO<%*QhzzO^^A;;VDI5x;2`H*USMOI03g>+ejZcx z)!!U>FX1sl@EW4{j?#R_n1275#(SO(Kjemrr}+EF3;g-Z_;msvuM5gw#QFEF<_|E{ zoN)X|OL_P(Nx4Y+@OpbV2?iM0hzA&$=*&B4vPk+l1_>1Acm`BRO3Dc*lqeWj3RFxx zfAM&@J5&$B0$qeCp?(LW5;fUHb@I1;OhtP`TcM%OvxR#%_Sh2b zD=uU9t$UyR5q|I%u|QGdvxCgZaVm$yu*U1PYvd>#PMyrewt zq$+8dwcto?Y}1#0x1FI6KZ%JbIf)rri5a;ejhRSyZagM+eRZKr|IGew5uUbHTzTM- zW-^&dXVk6nwD`QJIls2#Vs)uH+@sR@TJ!Hz-9o<&$`;O$lqzz*}5;(pW&8vZcC0>5!|GK>O@L^sB8 zhC~L^QTIf>xlQ-utS*aYCew$Xw4>?r#ohMOjvH6s-R|DcPCSzPrzAP#=dsBCTB|LD zHoe=C)PU6YPdexBM_1ZJ_Eb-H)xX(HJi)^I2Zv4H8XvcrMlPv0;@* zd_%|afOzB75gCM@U*p4-t2XOMsOfPv)HIdm=h*CyKd)>z*kLiz+AU7!4W)SKliMQ^ z$2Nn%{`D5cn`+mrKwBZ3md^^U^#j&z+p3-2D*xXB+R_1>+zR3H@bkivJ=fofacZoGOwiQ;?86C(m<}ki{VX$8=AWIaCBNDxy{-G$<%5u_y~I zD>x^NauX*F2{p(w3KqM+xuF+VHH|s8n8v0~U2=NI-5c|gorK0nrLzoQbPs%9Eh#H{ zmIO<^=J4`LO}98;I8cxh7qth(vRuz+D3mG=P24szxhr8EZT!T z@z>d2gf9HV7!yL)1P|{xI1f3HhLchX6RhOD9iNtrH5dX0)I6`*TY|tF+;>M zcekF#Zg$c$(6xMd!$2-2*g19KDgdgh9K8J^q-O>#m# zuKr28yCevy*^U28(#%fE%Z!eQB(o=9!-eyy2TbJk1BUP}*`2;t&|+?%dIQ^C>kQRH zOH2O+62GW!?Cx+m##;Qx)<;)T!XGALB-lb#U@_0Chd_F!#Pl#^J@muf)aRA5>e#&>bANeL8Du3 zt4}9@ABi5cuFmgVgraz8I6TR#bMt0b*JA8QBmv1%XWf%e`z8MuAH1wk_bZrULqf7sZ~OsV=ty^ z2ACItzaDPF3;Ruhc4Nwt=RNb~6+7fG$gHniw$GnUg>(}iF)sxerehZNwa^3}^bHnuij&4rnX!LP(E!@`uv;H=qD9Rogq+o@P1Sad31 z^;f`zo-5q>xqgrVCad!IlRkW>)#E-IFh5Uj5fz`{?r6_&ADpcRh6<-wcrN3)bX)PA zR0iiKfBTU@;MJVG_TNVCrP)w+`)Jx0A44lmcdgsOR3Sqkc-th#OoP)p7mqp|%KqeH znH2GQ^|o4;-7sebwkmuQ`Ls400CEHSQ2Ha4;Xta_2iMo(xVQ*sliUNp6J0cJnA9b+ zcDj96=jN)FmDq5v%I@3RW9AH~FXZG#90|rqqmN0Y6wcD`*#ck)Jb?R`kDW9UXi9w$ z?w4TC?mL~pM45jQUPJx?l>Y;^pKm{3UVBcswXJy7Hl=FaRB1Z|3!CGdWlSf0t=|xt zu(-(lf{99$Udt8*9b4akwFx58{7}bJI6ZH1xtB-MOWK$bCZa>9J7xt9xjiyrgS)oM zI@J#{fyqbf%I3@!vS}Z@ZEAqHx~&tA+b|AyI_Usv2u7t#@gn7I&PwJrdSsMr(jX!C z5X^sY5Aw(>Qz;q}C`sk{nj9&0S=p%sdYe!ijG>IRmMmE16_6sWV|N9Av=>H6!NbGB zqmv3?M5mn>fC&fhNjSNrf?j>q*)+xRWTG*bLc`(Nem*1Iv;B_6^?Y5_^sPHsW>1e1 zH)9GwQKC%g%|b?*h5!R%OYf|*GXS@6Jy+9s3P+3;`1C1GS3O|bJ>-Zt1fx#^Hq4b3 zyWxFj2Tz-slr7xr2}onW4;@$1u>b>yY95rX37l{kLmCP^p63{ZU#qiWx8T$>C}Wg9 zs_7}s!%v^%15In5xq`4R-Z=25Ru-A)SWhlxESB0wg+W_R&kbPu?;R8{Shjf61tzSt z6^YV?urcS%*0zglyw)tU(sGLimaJ~IF#KDDTKb5CB5)+Kw)Vee*+H68HuRqv?{hT=v@k7)8E_Ri=2O2C5wdz2*t_|aQO7DtT@I3JW1s?hHo{ta z{)JfjL%$U_k76gJ zFLM;Z?CqWMOPb`&DVrU#o31YFXIY@xVGDg+OmA@4AZJrgeWfZQU_h%vR8lOUas|yt z#I|w)i;uHcrINv@Y=fZ@viqOkOSlzzWp5JurdeP*za`H~oXOLoV0r?8BM+lBG*{DS z8naESo>w|1JQPLL+vlgCOTB$>29WuC)F>0;t;@dAi2pP}aV-MCat3CYVaTDGOECLW zxl}=E=v1vBCnI0jt+n>d&%ME~Z1II)nnLql&xpl->Pe-RQ4yxDdzRJ*Ty7QB*Dyyy z8}{k85*thJBh)u!5XuR~_l#K81bQr_EL8oKlH@|SKp)sw7RIRzoo{mB)~X+19#kBfXrmEQm!~jGUQj1a6jiMt@N7dh-!3^d z_3rx2KR?n`)|9cTJPz!7J2u`BO!vkz->NPfLKXsO+sNPikj(!!``VXx2y1JQE3__Y z5%N+L_Soa$y}#Xsim-HGf_@2?e|lUPEccA-j!+^bJOCD1z_lLo>T^BX5~~%(r%6Ui z4rg3yw`UPu4RS~g&ZZw?N@&Z}WIKcf=nD{vG%_jCN=?6R0u3OpZFRU`_3iCHy4yw~ zvcZcjW0GTwr$(CZQHhOJE_>VQ*kQk z8g}=(gI+y8e_+37bMAnZT_HP3pft3|VK;h_vape*#lRTHE~xLFX1h%KJsSu~w30uiMqW^G;Z|ZQ zkCg715_n>VW@hm$3M9&j?Hth^75FA36df2+&!}J@iE^oMPzJpHAeVqDsnHhgt!k{wIIx6F(e$|wh?a7tF` zyd;d`X3t1L-U0&yMlDLXCJZAm4L>zg|Rn9s34KC+%+Tj6goSH1ZF+>O%h#+lxGba{NxW6s(`gwFtAyH4#ZI_^;ZA+vv|XCQ+NV`qtukVDgu7mK z^anI;Ms{5FHRKwz`3?60(CPypGZY#WR{OK}8B{&~Lp=iqI<=%!ng%t$Bo#a1^mX^M z^>Ae$_K2{(6~nk$`8raD_*X89I)g-AlyZ!0Yy|&amOH5^&arUD@tB!mk&d3!3!;WS zyS1)!XVuKQ-u{6t6?DctBk(nz1ag3*1xrXNOTUG7MjDx5DQV z&9CaUT{*0GL)CFmVD3xb((tDKKio$D4L$dNzKyt8+5d;zv*HEmfveipHWp`25eh~J zCgqk{Xp@E{MMEt}R1)q|&c%1D+GewnWICNz!+`Iq*+kE=(PTQk(|E**UM?7bm4u{3 zM4S!JMu$0}6gPBy`)zJRJJ57}%0K_}FX1EZ_a~+_^Umk_@9rI*VGc4WCsx=_x8q6_ zdcCMXr=R3t{q5A*Lwr$U#WIBjG2%Bc2!H z=ZoH-xy+bdGau|pPllLaM=@u=dCxG`Y}Wkd9MsW`vB)zhPNTS-;e8kQlunWh{ zXP|Uv;B-U4=AfW+kWn~U$;{0pRx}H<%|q?-T+gZ(l$(XEW)S%Jd0IZM7cQGcs^<}) zbMR3(dB_~xB=)Zp2Dpd=orT?Ip(XQBlXxk~Jmn-Fa}tiZh$o$elg>iO=HVstaFcjB z$UN;N9=8*YJO4e1B%RIWeays!W`Y>n$qBy9Cd8nMI|z-COZLAx5( zYK*TzDfPpr!Lb^AGwRjot3lXCm^v(UjpUYrI=ZThr6f7}PII02&s3Xf=yH&ITfLVT z*C3gQIP#$I3yvV~qr9UuPgoNZi{)jx961jccaPKLDf=Y&T%U1V??`@K-Q{@f;~+ii zbiU0WJ$hu|NAh6G7s%RU^}Bd;r?h$7+1~U0`?(u_SmBtG-6dRoUQc+y=XASR8_)N> z?(M(Mf}CHG@wP~q{{66g^h9u%iS~CShSE+B<6q`~@=tk0d5e6!zt+P{ka=Go3GV0X zy?6z`#^LCcVE|>H>M8lyH@-4KGmFwgJWHfH%KJ0)Ew;yLT9SH2s?@QQ86K-0Z8H$l zJgC`<#i?)p#PDiNTuMNV33^Y#60cs%rH4yb-?}J`;?aF_x_-(oD z)vD4C^Oykx0Em-EE3X?HoRoY>e_+}Yc8pg6WYh<5`jZ606D#nO3Jt3>3#%I0 zarKH5x>0J`-7&1t+t&RkKWWdL$Rbfff+&!O>K zC})Qt3iK~NOTKOE2F~?)X)Bp~%8%$=7XiZoluVViD-rBlyQ{CcrxSufPVh|y&Z50)WdV3-hbb)! zXazHePe{gxS}B=00QW@(E6_$3p;`~>HhPYq2f_MJEUuwkMCmh?NNoW1wKZiOd)+{R z*u$6NH(YoFPO})%FXKQk*uD^_VvYJqg)@0mm)}@?UYPZm_31V0QEw2ndC$#(3mUHM zQ!(AMbL`^eHvOe%>i9MM8lDrUZC&)GCI5T?1uDV-<`iVLekGqP%M_H2J0~6iSiezJ zBuK&VCqZ=2?yv~iWlF_GPIamPR46<1U~-VT`y+5cD>@((ov7Yugg)_R@3Kc>va2#23Oxd5RDP_ zij^(}P!_UU1*E~q9fW;o#6xT#e^)_5)o3}U7OgxA8J^+h>>xYfT}wC8QLKPzWIi2E=@>rHa3my5p#YZ?y|Qqgu2{(!g4vC|W&js(q= z=NG00w$fLQPoVS+-dUCgGWPRN3tQcX2p1*{8i@WGcNkeC9CE<%;eOiGiQZDPa@~@+ zEnNeJln-*Bl&8ec;jve`Zi%_n>7Q3$SpWSNVFfVrCxs1g1PE{}(v!{g9&P>`HxK;#5y7@{Vcbq_i}VDa=BN-7VXW7AFG=SQZbE$uUvRra4j$kCON(Z>8|d=Bh>Ri z(u|xn6lA7?v9nqdS-9{s zG6rxvKk-}$`X^i5S>XV^V^0Jb=#KrqV8Rh*eXhhVP>h^8MRet3cGuppM1P)-E|brg1-`xP8Oc))i2 zj%H4pd73bfNB|i#yL$s#MSa6pB?o}tgAWO76oh2gTTV>L&Q(gb5EYEsUA&^+^;Y1$ zy?v#JfAZkuuBL#P?h{J?+s9|11LKF5&yBre^N7P^eA9uFqSq)sQ!B*WgV>8+Kx6s* zXNNcu2AL;3eeP~=0Pk9>6?Co?6X%l;$Z+mY;y#`3KVygBifSwV%Pi71W((0vNISbV z-ABG9bRPrSmAUfb^41HcL$-84RyYc)hlX4r-_d1m%3N6wN$r&Ft*ZL+s)TJL#gM9o zDb_RLm2;2}1jBx>K}Y=Z{)Rah(h}G3=kb$|gRZ9X)89kq0+#<`c#|P~xF3A{p=lIc zlWV1uU*EMg-wkCHv;1?Fv_Cd`Oq7W8YLTkR*v-TS{AzHO zuT%W7JJz=#9k6o0d)MpuJP#kwh&LupQHD?_@KDZO@!CnA7%T1q%;^yFdGqRkIxitX z7Gr#_WMSvsd90NGAq1g8G||Bvghq=wFr; zL@S zHBt`Pd+-QI7`%hP9Sp-hG))9Xz8mE%SVV`72%zeAL=c#Grm1CNaB&18tN^{lWYR4a0}ur7(pyzqG$ zo)5w@K!=W$YS)12jb`x&&{rHs1u62L`fWtV z15*U~9E+Ht`9STuA3<`$#AU@b*@KLJ#W~)`SO5g!UV>>n1n@p>KT9a7?{%1mO~)*e z$~_Qlc#8e@kS>W0lijc`M+VauJMQ_KbSjlGt(U9Q=k~eCD>-A!oQn7{(act@p9LGJ|C?cnG>oD zqG^@xpzLMs6)|7Yf@fFZ7|_$z4bt)!(e@3WJ)mPwFKE5lEDQ}RBVO&&auXih=Qi27 zCnI}3>4?%g+C=3}0s-k$y%Xe31fU2eC(@_iZFl-=ADZQ=4Y$dX&B$dgNT^^|-1oTs zc`gS1tW^s~Mj97PpdU4$^Fn(Nss$MtbG7!p<&?ffOIAj_A}i-EtOqPo-9%3)^cQ(pt_V^ds~` zvziB+_T34vv0ffqtl%L%oOrn?QCTiI5s}pbl1I_egs)&;4ZsEZw$q0$(dZFf63_FS zk&JrCH7NHh*Rz^fla3_=pvK+8?18Jp$trJKrlD!WTnvXYQ5M~|WtMC9Ij=Zj zPx7Ud<6E5@Kk!C&W`@CsjQWl)1w%}*EMraz=INROrXg@*>&ejsN9FyMb7FSNbH_PeC5@ z>X5X4SiWsSS&(M&zG%US9d7Tk?)zl@bp-ol&C~yTO$4a~XBM;X2`rs&#}^bNqI=?Y z`}cK3l2amw`wH37YqcL+UaryY_n=-;<&u_&5S{@1?kc;yd#RSvod*H%RfPOJ%hRZX z@)bS8VMHxIR9)CGx=3^@xJx9!APt?l8(BOfB{8LL9eRR9XF`I+r{k&O-A7*Ad%vI) z@nkLj4T!V6D)&mNk!&jo@f&5nE;RrQ$UG=gWAGJpkimbh}-)QjeW@#-bS;@h1ABxO>KQW0xa9EMkv zS<$o$Gk}nGs295Bd+@WX3NoVCT?i|i6}6J}-tBg?-MHR?QRzs?kffz$dH$1O0lEWG zzmRN=LZlZTAzLaT2~?;^G>r~>1VqV zY}xpj=p+L!L8@3vmQ{Npri8k*DzI-uOVRnM88jd0@i0`i0!{5&r%QomH7d3| zI#y~^Fhk{EqJHO-NfXEusUCdi9~N-b_O_cn zg1#$S?YN*zan#ndl7DA)0G4Pyzg#4PkeZ&tuX{@9`PcVL;C0NsqjOH>o|0{U{u*(y z^XFfrZ^}VXdsIzMUYx#*M+qNcvrT7XH#LvvPg6eM5;h*VouMw{^X+i58KOyWxC6xV=RWtVvR_j3L{IJVq3yCoRJMuLs^lOPTw$ zRa8&tZfbr_Z{s8BawAeSL>x=`Y+JqgUY{>tJ;COlZIzlSGgH4 zo9`4FiXNF)HvMOXmI;C1IA^3hn7&!weX%F=(!V6p5^SydVo0+ImNX=C2YrET(G&DQ zj3Vn1*-S;z8Q4rRW1tC9W%4_6twB3H2wSTxz}?)~&Q{E0@MBq&FtQL+{Gd6f?EVds(~h8KzND=S2~N5L@Z zEcGID*gq%Zm+Se+`II7Sh+as-vf-oVPKY-t08B{`in{16SzEoTXWiwSf~Z14u8;_Q z5v<6FV?}=eR{b5)t(2cBEAcFao$UFEFNWnKevzo~FdUOV7~`-x4Dp%<0&kepqx!E|?)LgKhDp$F+Hkrn+(%7r zf^^f1!r*7H25il6HdT#os)}K2xD)OK$=zLPxD&ST>9bpw&L7O%ijZD>ALS*Vt4biZ z>*)LaR-)l8Cl}dq*z*h7^Y`@3=NX7MG*(2rLTSedccCvxApdzgMH*`AhMQF>QPlET ze>6G}>8y4_ZFjK`lWisCAhIgz-X@cb7h^X2ry*ty$PK79^xD5x)`uTJ!R@QA;93jj1jmrOm0hTpDROwc9WZyNZinXoh#yH( zuj+MWSFjdu%{a(#9TNiI|8n5InhE3E(q2;)`RpLl71aCfqaYZ4#AJJzUUux(LRAwkT z6E=nEf$7ceHW+KLdh{k7ku76|zW0D4tO}Y67$7Zr)8{pTjxW#-7zTTRh7$8ubAAoM z@1HjCNt!EIeqGqvqzOTh)z5|#me=m1dzATqnDJKiUCytMLBtvJ>aJYA)Y5PXo`VHV z6$=d%%oA%?6>OY~0c_+2n* zxloR0KptY5m^mZKCpLfl=ZU|mz3KhJ6s&QAwlzsV4?Kt7xAF?(gmL zcgD&;8bNJ&`aVf?9U7QKhYeUyK2T~}loqTf${9p_&V**Wfs!L0UyHT%BgFWc!CoGM z{a1N)b#JDqOqwqvygbrMTb0)(+Bd@a+GZwnMG~5W*vNt!%u@r_98L;Y`^unYdHPW1 zfdd|GV~~a2()c1y&;cgX!;DQ;fMy`m(vmqBHWc8ki_Vs+L%4?!kJST{n}rU<86rss zNWH+2nh*2wZO2$iBM_v6Y8sC;VlM3uZAZ*y`fRya zc75gtR=qQ|lZ6?OA&58k>t2r`Z-+1EdE9<4=z(qxVMOwNEqu5!?Qty^lvoUuyoyyW zJAW1-CVs!!8bc$eJUvhemfateB@l6N_$evgI23FXsQ#smn>`v z$?+(an?t{-1VQWx67x(iO8Y4UZ-D)MV`=+!)U*~dmNTy9ov5Tu3L;X_D@T?K&Mgvf zB{tJH5;rn8ko`mIn=A1|yd_^&yP}qc`Rws|peJyQQu&RH`1Puqt%aDWlqQyGQlt8L z45c6EL_?JdQ>rDF2^FH93PSd_O!y^Mm_Q=aEgr89HHWH&F<4L|-cCDC-%h_CdzwJv zrzX{T&p0RfY24v`!vdHo&NzPB6=AT*x7s)XHx-N&+KRlbm^5K1l} znPT;e6&uX0SjTL{?1f91*5`x9I((57IHF6xvu>h=8s{$nIWopsg zOYoHlfz*NU)NjM^?&nU^;8UHf6I&+$J;7Ks1X!=y&!m5(pbfh!quEnAbKS=ChQCg4 zPx)qd*q&GX>f=qS{$2mRfA(WLMa|OC(Kince9S|Va8^qrTNEo*ELR@1-xg`x7`9rH zLR3YyL$An2xgX+ic4jZ`6DNdpJM_QfsX)c`&afk8JiGLOmI4Qo6fa#>(t!moD+kim z(@jZ~O*S@QzeP4*H=jR#_xb3vVvnECCxw^!Ewg zTAR645CO0gUyh?8ML-e5$koXtjS*2#_loKioyl&3>ARMBBu^`kxy$abwp!C<(bLgn zZ;ujmbOpA~XrXY9-+gpECD+AYpCH7~8XJ8NoxO~bfvQQ-R7X2Vr1$b$3rHn=M&cEu zTbgcR+i;-vr5@OXuG?X?;Tvhi?iHy=YkBvUyaAnncv#Q_V$N z8S7)-fgT<3>3;)>4>xc{bjOsg1>+xf zPZZzb`5l?@3~LMSY=Hg{a$cJH*B!1DW7Kc?*#74@tpO)+L%Nn$}6=pq{f2gF^ zwnWVmB>@xGW@2!;k}TalgW4!H+?@I8cVr)dx|>|hj+(=dW2UuFZy2c}z$pbp0@}(% zyL1}&FcXmAal-Dcr9rh$^))mc-33JETYf@>t^_W5_8zGGZ~{kbeV4s{fxmKpeMDrw zdl;v3Wl4{izsRJ9jgN^#nlK?-s-mJc?>v9s`$((}-u4tkvSQAZpk%<%m@V8xWY z290HXP&}3|32!u`o5ll~#tWL)Q`GI*h2Okm+zEUr(f$VIMg1 zKW*BQ&;Qc72|lt@@*W6O5yzXvim1&-Ijl?{JcVug%^lx3v@e93oLHXOeUoSo)M>r7 z%a4Ntb+!xouk+u>KM|8To!1KY&^kzZFz8ifKszam2dqk>?=^k9x?{_XVGI2!f{`Y2 zp=A8Vvv#M$6b=7G!bnVACwx7rudc1Btf{T3ed3DNiAD|+Um|>%*m10?L3bZN?_M(7^hT$;V(+vK`|_Cmw4zG1`FeaL9n(;`Ch(DjB0CdV$5 z+eUDeZ9^gi1+V(Dkv;7%0M$|$gNN;bt#c0vKsCIgXeP61b5wq8RsI%j-*d8X*trka z*LQ{l<7o6h_%^KmE21_Y;gU`DP+O$Wk#No9-YaHO9UX%91e8}z^R#$RUo>nj;HTaW zcXbcD_5;fo#G$CzUstJdIPq1!`_o^8<1Na%3}o)j3}(vo?(}9Kq}eMQMv;LkS|f@Z zTBIm(4e49f>zd1Ei*G>a={WU$g2s9P>64JgInhP~8w5@Q3?G!gKfWiYB}5B7d)aD< z3)G2)iQ9|*XQ6Fm{?mTxgtk956@EnX%6!M7q6^UM-3Z_4>4C_=oMw{`O70e>A-%_rNxL8gM?m_^lKTKMDa(wDN{yEu4McQ7Eb(^}S-@ zYB9F%>hZge_eI^ymF~kAfy-eTk#W#*M#Ke2LdjIB)vH#`m<-;6B@rxY!Nf?R>f(Sf zV~#Q)iw~F7)}wM#%bK=w&wYIlapDS+P(O(gAZ2N{hd^Yr2{WNHyac=eqcxQ+4H^Fje>$~q$WYy~C*s22J#*(UVc;FskpkQ2`lzLC&~0&g^?oB-mtnKU7D#WMstk-+Z674g7ElXUtf z4IX+LOar8g3 zjMX!gB$7;k!|ZokdKxa$i`@%~=f;2tXnXmX>gMv!?#-Pex9kgxU|*<}Iabsm%d>U@ zcxHcCG^Y{8Q^!Z-yFdwk!NCa3?tSB1QDqsf`JR)%#OooOoh=KW+95o{{eXhEh824BVODy)^=ZfLtN^Dg2C^Aw!|NfsJAOp$(&;Jl|`hQItaj>)euL6hz z?g_fSW?U2WSRow9zXfkiw+RDQsuHt`MIv&er`~q2saBCgr9CDJFhRV zyPv&#pJ1X^G{i_yOYJwCjgG1>+t)ccuF*|nKbmSoTlRlqa45+Af06mqOYCMRm4r-s zD^*rsDgPvDsVU8@mMV=Z>e10OldEe|(8{VF5y+d~rkSTrqG8KyPDiIn zHH~M`sZgrKI8IZeOQ1!d%V%X&RxP2M*(Rw?ps6Z(&$K>aF+El8EM1z(UdP<-F`bs4 zrb$)$WfsS)UzK3kl1zwBN7)p~Hgps8l~N=L#vI#`TM+pfsW}2VVq=8R7~&D4AyPx0 zN4AQJ8xbpt@PO7B*+CnMgj6{KSCoN;QX`wmm_y@3`P?hnS=3oXo4h9T9it*oT&9!T z_1zY0shlLkeHnBWRJ|5zvDMJgT%<}-U6C-UMa#{jt<6LImGa{YtL3R1usRxI!AR>T z>&V%!QJRqcYudX42*B;5$1~nUmq2G-U2Ld&PI=052E)`{%pc0w$GzGiNX9 zIu?dshUDNJr3B+Mmw*zC$iU??$C$COK=f*iLGTg|0v{ftoO(SW=Ap&}F1rh&85$0o zyM9o9BQRKuBa^?YoQ0WNfY{^0`GAV2OUS0Z3my%WJzK8btaAiu`!72qSW^8y?YmQ7 zntoK-BM2b>8*3LEi{M{M?EcJv($}j&iGoSHRxDVi)9dDL)ow?l7j)v+Z+$UMK+eDB z;!jXnPXC{iN%_F9tIiW%Nf82LP`=97;9x7T{hV1WDRi<036SSMFkOsn*tceNuHqH5QI zy7Bl6lVmCcx+}XO%iZALyorLry&x_)y2$?YUR%nfpO_|iA%HGAhABua=O=0vn#NDZ z_G>cp=Syn7^_jG+s`1pUQ9-jvJ)v9e333tuyDZZ5h=UV;Dzr+v#N5|Lj29O4`=kZ4 zFI=4Wr!Zx4V%lki`l8-G=+fkdX4a8Ucn*D{J9%6K>owG8eDgMTn#;#V#MU*_($s9s zW9N9jbhcr|_`3&@Sn~q3qczWwi6AV*4uNlAj{L#hDmn<4`xy3&uEg8IQvbifJ%@*@ zr@b$AVZE{34`YyL3b5k1<8~u^!ZUBw2{%O1zuX2Ep6sOQwP~fZOqX`6NvA|0hStq1 z*28;k>oqZM|BT$X<|5~c-7WK1-LRPayIH2^FUD~%dsk88fqL+O;{0&wm$O1}BX%F5 znN5%q%79=TL0zJ7GaQ|qWLI5Ld=wY8lxcyg9P`SR^a@)p!PRej=7~SYpQ-f4za76# z9@!qE)#KJbJAtOd0?GM0K2$nmsA(B!B(n{dg0#+BJ1-EdMG;jMw6&qx{Y+}q9!;8j zl{j}fvHplGTOZ4)5L_F-1Vb#>m~A_)2(mBB$4H|3;%EfxKJ2dVk-Mb^TZT|LaPq~P ze8jGB7?K@S-H+uQ(;l`N*ZN}S=wZxDgt%yIi&Y8FQANQ-^@kr8Y1=}^D!_0zFKUdB zk4uq(PeN!fZ+=r`BfkhOmmAZ&=rJUhZ`b79D_!^?jqti;bGBM{hPcO`NF*cB)jhbc z!x4tv)k9u&jDHV-{<379*}N0XA1UB^e_$pvWUFD0z`tg&hsu@cBL8cQr#_kqny?7P zkpDXx7H4%d>B+caKf+)?iD`qgOE?BxPI_gCSEO~tf;Ce}`mmvpxK2o(xk|Q2?>FPs zIwiiIJ27Pf$3VjP~(^*53MYT;7}Ed_tfsV}Y-&xKQ>H@_+?$l@aDU29wUWNlvHD20xWz2U>Si~=Fz~Cw zF3*MAn_wjDHL&HACaH@&V{}G^a)W)Hr@~uUM;D%G4)Tu=v$NZ8mHY3BMP%Yj!d$Yr zRW|DBsj2DZ!OK+-^`2-g<}?Zf7m%~7d(m7WnYknKzul+O@0k$2h@3SSbZ0h~Z%zf( znDRPUQWh0f6;0={C*B@SX8C(L}58CYO$d$?FsK6eExRSjc)@JD28@wMtoP~@8f))Q3 z6Rw96;G#6Ml9loSS_Fe9_K~r9=_sbdIpd#VrMy``rr z6IvwVNSpFhD$+7k#Eu%sVLr$MQqL~u@#rF)eI#h(Kqv-~0Xk#?cy?l zcHRVN5}pA5>a+a8OYCwv`BLJ~CJ(FS{yB5^$SFa;J$?5C*`M*>et)8NQx06QvHfz* z9(+XIFZQ#2c-^Npp0w%jM@}6R^{Mk`VPkWZ1lUIL*wSRXX&YUhY;EdTTAp9({(y~9 zL_hxrdHnxbd}3$k{2v{FT2FTum6O%)Oc|CliO7Tl3la|sA}MqcOmN}=z(sEv$I@1U z@Kl0HQsxG0vKS6^vLr>Qqyz{tAW-3#5L!n-0NO*41NtxIZOWcbzdau4hUM&49*5>JU<%twGx z9$a}86Qb%j`{$UF{`CEs{Q7RXd6y;JdXoKcsC6*9CP$IWtZ;S4<(Znbor#H<2sw`p z6l$y!@eS{c%L7;*N~|&4*(K}j41X1Ke0YU-Gu+3)KO#QGmG*~pF+|_*oD*j6bGtYx z*w`F<-}RtkVscFJ(3z=-y6i&^i*=3J#=tx2UJ@P=_D=52yQ+zL)LaSQG5N1C8k|v>gsjv~pp51IxiO>TRyoYgW6w~c4x-AN6KSkx z`_F@j7|w%u!#UTs>!u z3*WViT>bfKk+Eyf|6%a!T|KV<^4qHLNy6MeJ&>Wb{@J6pOxH|H#e0QZD5B{Kjam^l&R< z!Z^65j00e=>=9*CZ$kWe~YN8D00b z!lf&gQBgkPyz*>*23p5nfQAQOlB$<_-?r6MzOp6&eQH_N3a80U)A=f?{H^M zwL>gv;4#S^WHddrK!w~O-y7K6z{XcG`ufwO8Z2OFBP6O2eA<9!Cft%q`&n^mqSTPU z09H5)hkmtpnI|#5#G{~?P#-=_!*EdCm>8@>VO6x=s{Vkxy)iIrc~MxRqGs}qzNO6% zRu-@=vc8x#gb{j^Mf>*lFt1iF62JJ=Z2|jB-Y?Yu5o$+)(-n=NtH9>Z+DIa2M?b6C z1~F3_8~RP1WCb+JlI`w_s;^(m37Ny*ji-GQ$gV!C=Q~JK4j50h%Ab1XoUg`-sY{10 zkrp~ux?yK&C9w}31vkt3n(hERgt{RD0e>?`E0Is={{7F_GX5k~h}V7NZ?T)nC$v0V z&v3b!P7Ud>Pa1c3qCUF)nN1J?7%Hw87?j0%1v^`Ji{w?t0LEnE-YJ!k}DRM zhR|g9Diu!!itE%Ji%h;4xD52$%KIQoQ=xo-sn%>mvUMCFbUcL2yK5&u8pY-7wp$;J z2G4G$|3l1_qwg(C^-mcPVTUmAnB*5HyF#@SCVS|V8}3$N?G4m*nS!0sPHX6Fls%zV zc*GUeb!T=cAPe=P@>u0e>`VcJK1Bh*vK+z4<$@jOCUEG(+UNEAVnP0@2FqXkJG%pf z<9^+FNn{A>YQWmr04cm$Be{#Y7?{)N{mXr{Gb;x!G_EMCGE!O_mjlwrP-ORG%BA=p zn5Rwf!wj5jfpF6trf0XAY2=(piT z;)r|^fke3 zk%5NM>?UJw;qs+#@92|`)32{3MkQ|{dsd|FQgJ4e5u_H;%`_brnoJLl4HGe?+VYr~ zCntKLMlhxIGOeC0iB!Sj$=`#b!1hY#yf1g*zTiWK7;)I~Cxo+gG@ZS#&9_*ijB*Cp ztse^4dNmuk-V)zHlu@{E@LT`HIQHwsnJp$mo+g_}K&jsq2DsxX**76QY+h4?&*$5e>cFP#3K;VP;v?v zHw`MXVF;-+cq?09-z;{cY#T4_l;f;oo@1hz6k!1A5*&c~GR-{Xq>;UUa&Uxv1^=6K z={0|NK`-Iwh5FjAntL*lpYT505HuuD&LU96;HVljmA*CH4TD259AHQHL!L^|#%nCO_#j}Jq|^E%e|b$Mp00+sLc_KD(AHuM;WumVE%!H9U?NZPFMH@4 zpXQ_hEsSK;od0A}9wzX393ZQ}y5>+PxukGdmj>Z7W8NIY`iXtmY@vcRInw^@bq>1P zH(BkR3Rmso6)UUuW)niYQXkc}QZYbLzkuUZC5Hzzy~BR5Q%Db)`$o9hR2{BL@RvCot-nm>2`Djz z3LcS2dbj&`X@EVYF2xdw9dPGZa$nQ)W{(*7>b}uSd7GlMSzQ(&g9NFd#jVHImHS%) z&a!C6_lMJO9#ua_Q0z!J=Z%ymfi|EAO$fYT)mDu-S^>f9NM3p)0?n40-~tgn!?a&MLLBn`J&#ANt%t=7tZT8wD<#s?_9QN zH5jW5_(00em!ccCS>!UPlQ9$dSJ>!VD!;(!Gg!u}C+e%){gKh@TNF-N#rx%tt5xrK zaDSSf%)iJ=K~za6i~w}VXjIRf;M@0iaRmLfZjB8pStwBmhS1nQux+a8xUiNDp3`Z6 z;GEK0c#go^HWWO5RkUrKAbfxS?z;Ynrz&>S4a((Vbl*T9_A{WJ;0!Ls55u1$Pwlk) zXMwJe&mbOJ*l}z)bz7RN+cnb~D7&re;g}!*CVXUz7D}o7j1!~Q8WQ5uDtBcld?#i0 zDO|-I%gg(7R<}KS0h)}N-J)$#>z9<1g)_$AH_ec z*CjLr*2^-!3kn+_3Rca)c(4$bX-3TWqA&foPD+kT&;z82v7VY?71tKGH1|A(Ubf#b zj?x>f*Dx0zhddfTxExHP=wJlX69q}Q<+)F>e#f#}xFi#m`XKCp(UWLwr#khBZ47 z#0@l_6DQbD2)rX7xB44FV;pGf?|xzIWk|LqIX!;-7iaI-q-oS`Yo=|h(zb0@+Rm)B zZQHhO+qP{yX;<1tSD)_a-aF3w;lz%(f5D0wbKP^SF~>FRhPI8?&;%h5SU*F+cPAa; zeHH~LA8SapXpd%{3LawL_gj8)I zin>O@A&+DF705N+fjk|9n|~`4o)S+@{^-Kk%r`rj5e5(9r9<|1eYrv6E89U{TW-X3 z>QKrkD&)#9nUtGBkclqEQhnLqe1^gt=GwCoKuTam%qcUY>0v*iID@U* zR7;riJgNg@OiDTK$&SnnW6@X1afBYYV{XlBxb04Ui*U8{=lxxxS$UjcaHxZWJk#70 zV&1__iLA5jcP3rBALIkwVyxn?q*uA*5md6P2Pyl{R&hMwV+By~%}HABr!hyg^_Y0x z-?uF-mwo-;Uvd9d81!6`k}vDYpk0(CJzNV4FsS`~yXo44qsvD8OQFRsR&43d>Nnf< zS>z$${rrwR7l#6+!5eONQIzdc;Y4HS=fI8kufLd+v1RMgwYa*+*$4Tx9l_35EjS=* zSirs$@YpL-eu35`M#j1#Admagpj4tyWG* zWGe{H{kOw=Q=!>Z!t|xgN|&-^ zoY)G!SLURZm339d&vuxfQVWHui?sxf{GS(}+mG@6-q+6P%1UMmEv8`|C%4C*FVnJC znv3iGVJA$w`+5@h4;p?z+v*39eM(-cjyhi4pHcbc|S&6+m_76I$c(KFS(iJlk2 z_h!M8?2xY-bjWr%?=*tJ*zAS{qZ;`oBH-AT?P19d_Fjby)szEVQ#f-cPe%l4yU8T` z%=N6X2U_fEM<|oIQ?qJS=bg5CPaj{&D_}Wadu?k#=D%n&ukUw~U))DSzQoL%jWWP> zPg$s(Bvi)>VI>Xa47A%WpBlbwmq91xmOnTIhf22rKv#wKak2&912p}hAXP?Mi8KSh z&4eTz8YTl{UbJZCcx(?Uy(U_JjYwn79uDK$NCel|YptQ36)A=Z!Cnvb2ey({Nf;34 zoTBDp|5A%sn)$cA$8=@AW;%-R^s0mBI@Ji;E&*QLmls%U(|9#AEnfaTwBxKCl%^)I`fl@bk)0?^S4|iU|(Ks zwsPy%;GZ+|>#_fw{yT^+4W2mtz0#qo(rwEVHl@)HzdC<%)TqCNk`9#{h4RJa{dn5n z41cm*W3&Ddv2;v9kejkQhBy+!>(G+(>Rpu?TKm=!4e_NY;-akF7TuxA)pcf{PIrBT zTS!A9oRXlJa6)O7Q_?78k5<)XL{=$#e^mWAL9oiI)V5}4x6<-$FhlY@-9Q5hNEHf{ z_BK@G$R^W{CV7G7b&UP3$aonB(@JA z+E62Z9ngNH!i@<>8ar!v>6gAqR6r>`Cv`Uz>+zWfU3uyE=Y_{r=X~(Dh3mO1 z(pLgOG0PBWu1e#NKDRUK!g&Eocyq2$06}SO?{112!Vb7%Ap@`sn_{QP@;}0kA=slCs4i7Vj7vz?z(z zmIWWC?q(s~oYVrSR;1^hS)SNH2yaW7ux}5`S%)Og<5g(p=Fs+`RNLRAjT-COlU8)S zo^tsiKjLSYw;-y$E9|o3Ckxy-ChM>Lpr^2auGhaB2ZEk{oC~`9u-~QQ+s!zC16&IY zpIB@{wav2@bjfR@{+YukE`KyT-GwLKyST;)ikIKAeRsu;fbZw4y3ajuF!*e<+meBI|2WkNaD5!Le!}#|?cSP? zp^Ok9Gwi+)LwrZZN;C+xY`;yml0yW^6-7yhP|_DNPw3cES(-!Dyr3MZmx}CV8#7o| z=QBs4QfK4PEf5$5l06%}{dycq>E^l^HBBF=LAcK$mI>}hz1ua9blK3(<#?Xmj`8`& zdqGEspf2q;tb5_tB@4;j{uvQKvnRFovQ)GW((85Ohp#jVaf;k0T~lfLX!UoEXW2xm zlm|$yT;L1%Ugz>NTNublt{B@$PA$H!y$Pa(EG+oVGJ}Jqh%Zxfz2$_Kb3X|rR;CM~pF1Q}V-WPpz zT;-b<&`0oAC+D?;#M{h0RqtN^!4b$D8DPi^@Cm2IzAwa1ABolG@OmGv2E79DeYj*$ z7h(|?3T;yEhnIl4e?6>ktKDhUt1Z1+v1;DHOe#6x?4Gf!p$0guj`}og+Ur_RLx>c{ zd}uj`G&H}-Et#5B?2x|A4&&o4kLdRJ&d^hqeL1JwX0Wp_suP&<_~JCKj1)A}7dY8A z5;b8(5_ws<2G|6iW2oC|r+#DZ>`x(TMrBzaB&%dIZw(>Yee`OY$@$wW1hKP>#8|uF zN5X50acimQTDk>9NWrevtd0hUxJg?DDA@=}#db2%GWhaNIO9i@%4myZe| zixz2TDTi(cb(*4I(Hd6qPdzi+p3hxom#f<5hkOew)}-CLcKtvn9`Bp}_s1so|4G6# zD2p0EG1KEsvGa&@=zn1y|+4!w~3hG;66 z^DrxWtghPU<@e&-mq$Qhwpxvc5cXid5ZeX=vqty+^G!kdtHN`}52NqNCxpPO#OVnXXZFVD zSe~cvNM?+-tLkc7#mu#RquD`FG)qTcZ+e;vNlvyCAXuT=c4Ia2hlIUdIWUdS`MCcGPL_hsunRD%0;4%aMcAw4OzcT~gZ`%iO+>hQ`Vc zgYVJR#?H;ipC@`b4_6mC8#&NZ;aS;PH?ALUo}{6Z&tR*1A~WULEG}?7)UoLX`)a(s zbxzmVpu?kfPFsYTJNs@tg0VSh`#`R^;}d&FMpy0_ zhFs$oX#d&;6S!j?jzF1eydbdQ&}D+@o?*$p<^64=Lf(d9=lfV%k7iV!LUK~{P_ z%IRsyT~0_81s8JI&?(8(t?=9~WU{KpVeQe@C4R6DtVkgxb$a8-(9M_$l1hKFv53hAOK26_rKL$lmyTL#Nt7xVQ`J4bL1BF%dD&ar zht8V12En{Pw?-=fhBYZz=D|_711(;BBPK2O?%6SR?ml!MbJwR#4K;99@HVEo<5H%H zPX_=B;3Y*S&CME{lJ@-YRD+AbeoDb<)nNB@Px;-*vCJ>5r>Z5VXD+?t1SW?weo)d! zpW`ke9=kA76%?9B#9V=$c}R8^);}x+k?UlHg;B|vSuq>Df|Gx%!p^kwpF=Ic?$Dd9 zVT+SqzMgHptO0v;hX-$QwM0pZ&^mqUPa=Tjik? zhA8DOLc5bd|7YrU4Op~=5k?X(wD_?%XSMHl^S>_e%E$ESwz8+W!%1Ggq?=gH%^8zh z$sMw%X9|dWNbhQYu2y&h>jGMrSdb1&{YtrY%J94W8RvzcE;`d1X?uuZST6$$<&a)i zQv)hj@HWkUyyJBfPp7!XN9+ikMao~g3q(Po%&%5yRr5;%$LrzNsqxF(H5-z+oU|T4 zg3*cD_w-Y?Hgi^YHY=7no9|f32W`+`Xd>iO7g4lK)XTpEmc7*l)uqgt* z!yF?rjnP&NpJK4r$k_usa`WsVbza6@mdjAaWf#S%4d=Idcm9DdAd(T2LC%{xyqk}X zpFq#$`krl|0X}-*93*Y0l`HyH(ZL+AX`BxnBMVxdV+HitNQ9kcH_8Vkj>~M{k}M=E ztj!HVjHJri(%OXM8dl%iQClK(B)71Ay=+k`Iqvo*9u1ne$JbFq?+qijc|CSI%&`PP z5t76dFkuO?JZRGpo)4ZTX;%cq=ID|So&z6I=C@!9RLp+PMjGB1Da6ujkriWeN%CWW zagNixN!)*ND{~qo@G_QiZ&HD^QfYK!PPjUs9 z?47D>`5WO{TRgHV6bQI(<#Gsf?(*WcgZ?G7dG+x5*U6y&^aYY{ga56U(yUY7)-Qd` z+vm?-EmoxfoI25c5QB}=y3U>`Cl_Akn!t%9M` zN5Cg#!SiH<>3oE2rUwanIGZYpuHz&j2sJcfU41AdJEg7cY&r! z0`9U+S1VcyFv^OX9-+aq-#iP-&nM%<*_wZ>3&thMop@bH+~33uKN-g6;D>Fp(nCZ1 zrpUJ_pu&A%J+rlneYYL#*Avo*XyZ=?cYv!sVP+#P6bYtPo|=V@*4T;VYESNuCCP{V zVNxcuDt2-q=Ga4@83wb*H0*S@l~=E3@R*sjtVP9uAhwL>ush8iqe_EPDp<4GO~3=` zj8n9GDBs^(V`siyAD)IvZu(!2lE#a-O?! ziE{Ruzx->NXmY0Oet+jI@q9!Dy)sX8PhFAyq`%!pbeG>G6ux`>+YWDNnePKFk zO+4x)$uoM8_NCw-Y@4l*l)8$3tE`2WL1f}gDSFrI7`dP1Msz0yJfF)D9Clg zvC$j>N=tUc7ff;9fz!eDfEt}d_Ey(b!w-ab$e6}6^(y|rGZeTSj^rVQ>2q!YVkkB* zp7Q&q4D#y&Ci0?CJG|5UzJ3hpqgX5h0K(e!(@)PXFJ;9O-@22s9Y-SEo1_3`xHr1j0kdcG z5mQN?W?~OPlz}ZcY%&6I<1Ig}SOT9F8XT0!^#cKn&PSUF>`iMyOi;PKud$VTp0{*082A-nwge z-NG1T#vAgJducm7bkeRNP-L6mI#tycs*)zGelJbymE71U4$qFWo|OzQ0MBvmo!bz}07 zPNm*j6x>246 zH*9MH@)og>bvhlpy0YDku+Q$h&W6HIwXHNw1ro;c5^G{Wv z{AF|dO$D$KHe#gYD3g}2KO%VoCt~YtobV?t)>kK{t$GJ-EMhk>)?4~3=2Jw1(}4h) z0YvrZ9UUnQA&Z$_%fp0CUpOF|&5cv*WWXi418m?BF8;$VKYI~5dL)eQh|;q}fubQs z#j$4(469o4@i{97m&Ja-gn^@$A`++)2KmA*pOWxrTbTYjZ!q-4@tuK)#;&2fHt9n0E{yp{hVI8bC zxV|YWo3?;TjI`(b-tQKR>Va_I7=O&1KWgSfqBla_(X0nT(*1fpPaHEogjEriIUcL zSZ#b5u(X1hdDv}Z=>#UV@!lLBrXRGp*6X{fq;m8r!i|rs0%Cw~NhlBxt~q~6>+*Qx z*5*%ng~CRFxc78AeDo}rS@Dl>&gr1Nj<{OrAS;)`Npiy9lzGLzOC_?QYAU@3;5W*1 zyzW95lq!XWC_s!-mTEB|8rHV6ct%9PUi}Hf^ro!7r((*Cp!IBMD2Z2vI?iIR)bpS^xTdf(7NJ~jZ z->0^uFc?m{n;5>JALw#2t@EX(AkKL+sO^ddW(3{oFK~^zGR8qO_khUzwL^Y9H+%(^ z4AUqys3^0pfM~2YQKEvLIYLwKmtJcz&Wj?(s9j&`NkA3)G z?{qxbrM1ag6Sr)cI#t!mMx=Yx!IaC!T#8J|mJ4U%lW+5mX_z;X{5t1mW`!}&Z>q=~ z#w59H3a>EQ1e3*ZVp(~|xxma!HU)PDBbjU9>3N~_hA8M72*TQJB0WvVAe0eWXN9K| zzJ$iDYLdZ(P3X&3G%P(=uDzWi^MxVDQq0y&9N&=^FeS$>>7S%ox~#QfNJ=eFvjs0s zggh{&M!zDdVG5B)C|7H!E9jO;CZ8LKNXnt$Q}i0#U2wYW`9_rsnx-l^=6SLKoGhTkVzhX{B?^+-6YrWrKn+f>3G{?$<;UABdI@yOnBoOCD zV>c350^*y{kuES&1q^Arbug9&7B-g@^(H)A^b;IhboK)*brkawixe7bA{#m!9o>uz zS~MISEjpf)aujnC>I0fLsx-5b6RNa-HeSfy=h5_Xq7*oMR&-(_2#wFz{k>z)@RniE zXQ4BX?5~jf=|s4Y{N;n?!p3DZ@V3ux6!5;`Efw(iq$j~(Ctq733rWj_Ks#S4OGSLp zd4fhG*mFZWp)JMe4%nf-A(W4c8cU#kGoqIBi z#D1&i_5pG0r-km+vAw$;Uy+7mfocM{myIA?BoWuPXMK-g+t+QTfVeby7%w4 zq0eYgyo)qit)@<6MOPtT)y7$g-5cv&GCf{DhFzbzhtBgs?Wwq&o8B1*z-@SAplZI) zX5x8C)d_5l>(2h=BxDUgQ2l_5M%d z)R`DLIsR+;)+Fl6Xq(`T&RNjlX^zMn&TRc%z}hA^uqH>aUyw-zU!N3j10U@af|TGF zw(#MHSvWV&PfJTn>A|B%PBXoMg*Q*;b5UhwBkuq}zE({J5bfC$ zy);7UQK5X%VO$C#1$+65+z50PyyODr+uV`AzCnnE6=m%1jm`R!QgV72^lF%tT-aJz z8=5RJ8#p-J{Ky*^czDt{%ZV#GsZB_Tlowlyr6eEHAP(9)D`SgehG#)rSZgK#O=TS& zT+$VbCKVN#FK#9%GcL|_L=-NhE23(sVaqYBiq$F!!{nZ;r6*OYIDE27!7{qCN-R|llExP=Ka2*! zp^EgtszFOdz4NtxBlAFwHM6Fg=6h^BU`hmD3&MrEM$0N3OI+M20xOr4pf}5aik^WQ zf<@yK|3+h&APnDn7|YgjS>fr3)dlqjM`K``lBRd6R@%E@mQb|5ByvvbPm+zpW8fNQ zcr-l&Jv|URTH~tp!1)Q{T!X%JecFvU3N2S$BZpu6U08gM-qiH1>$|&q_0-BzWLN%x ztXFIosb^dbXmolDqOkhFLTC^!ubk2S6XdRx4u-uTr0IDR!a))e-pdP9Q$wGpSsGp& zJRu|nCm*|8)EJE1<+{#s+AHnw=wJ}Z(pOtPEi2|6J9M|OFP+p`q3jNwtTuj3=6K${ z5nEE{SFg$6ncBAHA~8;@91vf}!@0qR_9c6NmeYH&7b7R5)5YwDTVGK?9)c!E znN$(F#9jkHfROPO^LhI=iYlH`OeEDmaV4h?F}F{D<78$TD;G0R`~Cf@bEa25t`5oF6acZSjCa<8v}e}FVBumaVa0l~N^eNs>QJ8`-BJQ`h~XK&hk> z|9|L7Z2v#dTin9h*~F1S+}gm|MAXE{&e()O#>Cdl*_@D>h5f(wAYFw4%OOU%o(~%5 zODqyOP!mX0N-6^`XILjMbGz6YC2=OgDQnA3E zHpycXvww)4In71x`6%gz)JkY2_J6D8gnXcp2)p*}ZpJ;ga6f3v?bfDo3-}Ly3w6*U z81${oL@+4#H!$^pk3tDP_sC@j>gl_wv<{_(`*{3=mjb)4MN$OM&3+w(lLL{NWQ-oi zWfiM(auF@SvJe_1r}m$BlA15~?UbH*zLD@6j2M_K7P`xC!N*jd-B`%a?$miLp(Yl! z>)?8SPiSJQQhfuRIfi5aGGRkIXy=kk@k>Laln{N)< zZB%DSG~Cdz)KaY64hw%Vh6j``Le$;^YzkT` z3ydbdIZ>PFzBQ+}62H9cJYWIZ+#?yZ953B=vmaYdxewV7e=<>Es4`2VaB*Vsx4dp+ zHbKMUY?Y39SKj}UB>9=pPw(p$y{=jK$^!SP^)sM0#_eK!>#Ed87Md>=X4mM&H+5m4 zNY{{wt8}GP7yf;d)}sUHG<_(1ZQl@JcbL+-Z7%z64QI4uPYmZ+s#|JDXD?1;n>|Yv zE$A~@YAu_}P5tHU(VT0coWTj&DOSx~zVd8bI)h#xu5kS4HFoL{R#dbyZ<_TcWl*h2 zva77Dq)k$%L{q)b;hrs5qHbs6YQCifmHZww6g68>o|>V! zd}JBLlTB5~rX+S@=20@Ty<)04>v{gqrUd9!8K`soyT4^2PKAw%1F)E~u;s56c~}e7 zuX25_fs8=t02zCcc0F?x-vO^k7HDJXrM}zW@l-v?QKoZA#E!&*P6=o=qQv*s$@{m< z{1Xqa-i8=owCa(4nbS*^M}A4e@5DZg{lhwnJOEI+Hb7QS5M&8^S{ba)9-Irj>w}xU z4$cjXAX2&pD^8No@~=j*M#-b3`+{mR`F7CR$;P6>re6#x>{+%no|M>dA%jREzHVnS zoL;yiB{>Eh?g0&5*$CL{Bzz6{zF0x5S;P7c?>h5ektFBQ4MI?YywkVp4u?O*S-e?E zUfzug@g9Ol{Dsy$*W7E(W2%t+qx?X~u27!=JHsOaH{X#bTR3O%5QK31*ZFHd`$)Nd zVInKJzdSg9%*tk>tKEgrN@^X{vdlA&&(gqt4+1qc81VVW zzdzAxARwszoT-FB-SpGkDRqO}2^ov=7?&S}IE6sfLD2eIN=#)K_HQm91(L=XcWcK} zO{+)}2Ni!4qF%?kHM-t9ySbR|W@RRJa!0u0kD|AZZ2&`s4hF&PujQWf$u1sR{K><( z4ez5N>ZZe}*V5#r8@+Hav4RJHxh%X0?D9jr>@x?I4$l#7fH2XE;64|KnNv}JA*a-L zgj4zQ^5HrZfTiriqq-wklsR+I8#IA5pjS_jlA_RNViY};x zt>lx(IVbZ?nYJ9^TVkDyAHPD!=P)Jg2Hd9ms+Xz$BuzFg9(156w{_Zp5m`Xgs-5ner zxEKN=tVz8D_xwVvdUxpEry8^28weNN`fQ!C-T(vUyB$TskhqDbhm+f{-{`-H!MYrx7wcFl$@!@2xw5?jlZ zj{vVTqnKKwdlYO|-l zFH$j-(@eUx6zHj}hhgN*1=G{B^w{x?{s<;vTw;NO_!j-t`s{u?2ODbH+~sz%FJyJp zP1Fw)n3Rd!4p}hU9v08xZ|P^ruvAgG32kG6{EqYkW|>8DE2*ttU-2TtzF9Kmc$Wz_ z1*kUXs716&kC0#2LTy=cA0l^*c(ytpkVX-gCI5RdaWMT4iiwGl{l8uGCdsnaxMFBy zryjB>fvAZXZ4u@b5yN3m)fC4>X;5h6n$)7yoi7>U<=Y~SYPJVm&NiolNxlknFY zdFkQD7it46o#NiY&yAqgHaXozEn%W8DXJUJy1XxbHcuVCpCwv7XS?z5dyJ%XGba6( z8JnqTXmW}Owo-|n8U8qbdhkTx$%lDQCoB>Rjw*7YHn(m0A!*i>X7uNoxQc2H|p zlB{aZU(^whtoYlUX=xzklw)J@L;Y4&KWl6T=M+hgS=`-BcmADue6J+5ik|Cyg_HYq z1`-49oSoxV+3A3C2=7n6V1U6eDOOUf=1A5fUd=Gi7Es$rBuCk)I7$SYlxCg*pRt^a z*egxI5+;cj1Ap0k&Y>~(U9B*pX0%k1+U^-;tGS{*s>Vm6JGZhtit~kSKisa(5+7w9 z@4MlTW(}fN(javMn#(lFqmWLoSy11w?7vm`0z?sGUE|!*Ppr~Jj4Wa$h}H@6 z+K^DLN`hH}hg$?q!)ib(`* z-IAg)R5ZvX%4~%Lhva)$sxpCnttsjGm_IjnsQUi3D zm6e6iNtPerjUZB&|Im3@{s*0hmFvH4-2ZLa(>}Jj5HYeRf1Y zg~1IWYK{^({?j=#{%@U=@6qt>A9;GJzyDSON%Z^Z|Ha(L>+=!~_rtI%7B|>f8ahZ? zDw;aD+8RoR1_U(Z1_UHH`3jjRntF;y1d2D71{Rc*bi@WG1O$`>8qq6QI2z^#GAKAu zD?r946(MEkWoKw9Rpc8aDJm)Hm(=O~`BR&gu3ep`muy>BQKXQonOK07td*^$lA2k# zmzt+uxR;imRSEPQj-T#4J4Z(e-YGJ`AwbqbiFhU~Zc4Z?+dn-154HG@a4%ob0_*#G z#_TiUU02cB!o=>S*fy4{$!sR=CRdN8p+mq>XgKiJgP@H*kK66OT9SprdG0h_kFQFq zwxg@1r{k(Eu|RZg`rCzX$?H^}e}^y3NNy&2vhuu>y5oA5DwOYv5B{ry&!sOVSBh2M z{L1e7q`b10D(!|oZ-u+VM{lFI@e92&;w>g+hK;VpX8RcLxXJ2dT=qJb#peAeBWaC3 zo5^G*@NW{P%uS`u+*zgFa$|7%`C8b647bsGk2a(f=P0s4N`J|1HmK zM%_zAS-qD(Y-|J2<|reb^NhzMM_^QAG;&e2!ry#Vj!vspz>f@u3?&H_FY1AcBJ4Vj z3No362PK+IjEpXJHMF@(HDWMoQPZ~KS%zq4+Hu~#NOEx~<)#-W&uo** z$EAIp$)glyzy{`){wX}DK$DW{lkSm+SI$#fE1&zzP`Xnfdd`E=Z?Wub3GoDbu4u{D zk{elEc&4-|n6@B}vq0XN&Ax=ODFra+xyq+GliHM2Us!n*dPmX~SzB~j9uh*61y{ta z$Wh^P$x(ycCP>CuM(L(77J@>MH7jLu(TC?m;E<0@cXn}HOx{q=ES=5J;9GuTJ-N&XGaHfpiS_-hMZ#Y;XtrXoc86Bd?;E+cCN-}$L!;f6nwokRkC3|lq*ja3 z(OGq_9gB}A8Z@u{xKs7lGK0B?t0~7Q%xYe!Y6-gRa2&Q7l|+)%wg+hRpR!;eC95~4 z!k8OG6|tB%bhLFtM$cUOa8t;kBvy$Ocd zQClWG845~UZt+v4 zr*S#za&PF*etH$TXf?U~J7`b3J^HUTE1ScsuPK&~@!22MBx}iLav=_qv5f*S)UVLO z-wMzB+@HltP&}UK6fu7so4RhD_1gc*OIrUH$`T}&;{PykNGjrNA*!L(2{Me8QnR2a zf_T3(+(&JJJ8vzqAN{t!;)~sTTU|PR1%6W_TqBcIo{CMVG8(ul3&oJ2pVpXY(2c}V z<)BEn%v5BtRQ)yGD4b2pPws*D=?bV~aMCgjW9xv0@2_KY`lPYtMJ1nWGdQo0v+d&? zM0j~y{awtqSD(K-5_P2?H`tz%bl@zHpkSPi_|Qv5h+{>1S%zIgjV>8HEjBqg+pK|u zn}FMD(z*EKae``z6BY~R=J(Mpss-K&m~6dwlLbmimx{+2or><_%0V;pN{$w`_s(heMc@AxTsYWXaKb+G?5| z?qVx~yFlZmQYS>B%-h{-LZTJNPHJY$_|2A`e_9amDjSDRP{Dh^Q7*hvY6->zaEbWb zcCF{xNFSakc?}Mmka!#Q22)EZQ-$fpjQF}UE~T3K5%q;o{uh~jAtdl`NnejHvk z3Fd*Ra#WyCzG1Wc%}vcK7^7m|$JZdopS*(YL-sytm1j=lqB?>;4>tRY$LaZTB57>y z5s~B!S-H6X-#m4oDEG(Lz(LVLQBko0i;N$$R>{mt219Py5($bE?N&yBe=`$ndW zn*f~r@1+ulH%hx|A%{8&-(6ICIU*!h1D~gBd4#e-gdl-U5=3|R#G^BDLlBLY`8oU%uZz!NUw&NJWpkyXp5rh%Z5 zSM@n}Rmu_XR##tVD}QCH%o|uW>^|`;wCC%2B3RvnZoa3J?1>F*jgh*k7Ntd`n;uLa zw0zdFegSURKx20gka@Q9;B3J=@bH+I8tJ6!Ua^-&HP2ZKFA)u4v>I22-`s+o=us@< zS%g0s@FzQ&sumry5cFWwp2LVQcIW!GxidD|jW~Q|n(MK&z_&&B4?W8i6f{9Ut_Vwp zN{2w+SN^UE{}8mGj=ftb>4)H7V7aZCvzB95d@f5wu58TOjaxit@J{L+`s+CvCzF4_ z-@VZB_y!pozctQr&4${)7>#4NN zU&jbZpaXLV48Eqs?5U+nDK~4v>sN~1cFDi&cS#hh#i7>&m_n@<8SkB)FzqVK?boe$ zSjOh?c$O$xn^`;Z&A}H316>5_XH6GVQj2(><%T7e`G?8{VUi6d z>sM9qc*8S^04tef<0Y0Mjx)QCyM#8+4nfC0<`6cMiu}`x7Y|>6 zTh~TKpt%CswpE|*KFOu@rBC0Nyk7E$-$?4zLM1y&k_xve4E!j##kagCkU9gg!!iMtHpEw`>^uCIK)L&40JzPqk_m5ULB$f>X2s3%t+CZ2 z-eh@GIBWi8o!#U$!a1c=O2fGE*t^|)>VI3XmRzd*D!wpm=~gY-= zWd2?hqk70WL>}Y=`S*Ns`d}X31DG2DvCwG37AOp+z$)g{g5dUt{4=(~^a&vAIZ8hm zc7tQo$~Y)i&wTczg>DXZV8(2zhSJCd?~bLl-TOI~@;5Og9Pj*XYJe)b74kcAPM&yD z4r>zqQ0VkGftp17d_hWytgKe*w~b}hkjBqtowr#Y!1b_!l(rRbvEZ&W<19YO;NAVN zZnL+OL{`MukDQTl^i&ew#w79?j5qI?$%a%usvBHg)Eb(9`GywVG77f6r%ve-PslzjzQXwOVRb{12*8xLmBd6sl9=yyfG2$7fv3 zN_k~9&bKz0h;aP=%Q>3;24ah2F@B8Na+K$k7qT)Y z+&#g&U3W%~ZdegNjNh|kl8r4Nu<;5>d z0C+~m__5GDZ`Ss(S3OF4L>HD)+XscBs@{sBbMg9EWJ~ypZg-H&-;9@gDpI_JmqsW` zHK4rwz+hcXQB_9oihhc!(XyJk21<#*8sTXlyTa||ln!nA!%f~FA&jjJ3wgUi`M4`+ zzocwqq220iv@iYu?yTE2FDOMvDE~d&Pcg)YS-DCUaim>IaINx|O=-D6u?f4j(UkG) zD#lmrxH8-Le?WNL@xDNg_1^8^w5tMkdEIyB^rn*gohWItBqFPe1D#Er#hulh56UF- z%5+#b9}$lHZFI{GszCzZ#Fk&EfdI>-_wCML7j;b{?lKizLUmo%s0_BCN^y@0#1Y3T z3BK8AACGpv5oFz%Ei16LSZ6|XTS>NCvklGeNQl69Zf;SeD|_dXaCQ#cXV#5e8Qo2<0v_Un*$Up+)^U^soh zdv%OXErA!c2#N6yWf5N&svh`@Vv)$oWMgM*>n`pY$+`nIR`ELj$^@+$N{4#H%U|#G1?qK6aXXBL6fi8|vKexg!LYcy zB*NP#bPv+x8}fz|7t7lDVPl(xn-I!7z=~b{_8YvcD$~2_qJCOsdoWxZX^$L|CohY8 zg5Ral;yk%emY*#|oB3xY66&=3#`K55#pa{@Ka98kqxV;KX0HD#^5-aP+bgf3_cUI5 zA;wB5z=FHLyd<(4Fxvo!and=!j~p3bGAbBdl5@I3K^*S2IoFX&x90lVN~TtanMk&h zPK^$p>^p=XE<r^1LA- zT2iV+oM67vtK0Q*g#LZmUo|qK$zWG;Y9>|RED1@-=Q6NfoKwuUfQciq%8X~xomtUTT* zsY5nHW6s>1k&o_7-_j8|PP!g6y$AJ&Jq)~?<2Fa!eSUp6 zhdN`fz1e$1=P5Vm-l+?ZvX;`8tag@%O!YiiMY(dOh{4}4x^CD_BRw=>1>c7dZq;o{kXraWi0`7(=RUnsTDV6?>h*FELv zY3#c+pm$#YQ8w$Y?$EyGEp0?e&313ZBg&9H%MQV!8we?^nIMRI`*k~1&qGI@I(Wr*Dy_A{M3&M;2`=5Au7}U7v zhU=*vAZPpI8-GbEtv81|uiG}mEgl##0VP)ZndV5=J6has2S!GhZhMGZU5s8DZ!0$@ zVoym$PXHKvf&J20szzNP9nX2{vkNoZ zP?@s^=Zz<=2nR(Pqoy^~LOBN7Jn ze{%`jN>9}Baggzf^r>0&BwKTQQro2lEeD-Ri$6T0cQn@6=H$Th)_cqcAW<|cG%lRH zy38%w8=GR+Jd+>clA5bG&AgxTg<4PiL9Dl*{JzwfK3IAhr*IjgF#)(*6!lDKfp%n! zDjUwI86d%D&=R_9V-w-Hr+AS6Rj#OAc5kC^VH*_Ol-|)BHf2TwcDYW7j!`08zWi^- zz?Q1h+AZc^*3Y-!PzpMzk56_h;v}dGjAfz1UJRMOO^)KYy819v-U+AutFEI=3EaJ{ zw?v3T(_|Io&S(^-6B2wqw4)+d+PHNEjSs)oOQvuZL9ChlLO@v~zT4Awg|6ff#+ds% zv8Sc>{vi~ZD5l%vu!;=x1)o|9{@H@UpWg+`bI$18pET}2#u*ieyS87|!t=+x`*R6s znundnM9t2hCo#`sV{rG}2?31jJQ$_!H~&hAVA|2BW`>#E6NoLtINlSn<^pe~w%?E_^1-Td0RG4g2m)JzIyy9E(ihz7{(#Ns zVGc|S3hwWb{Ue|$p0G@Pfx#?y{v}3V6LNKueQ>aA-~ZFG(Cg{sOe>)%L?~&~O7^*= zJY`@tmw5#L%rRg?dV~yU)Mk8Q|777Xe9G3bJ2CFc*WO=*v_%#L{4DeIv|XspBBO++ zm9eW0{sf>nf%cFaK{z55vi2+nKXx&}WBtvfdHLZm6t)%VU_J~NJ;&wgN4dUGJG_be zwS4XcjGQ4-`EMrH|KwDfiIM3)Cf2l?yPKkM$1MI+79o&;A(IYsIVKrdfM1eui-0;3 zc~UWw`8nu$PjHcC0*!fM*ZL;Od5(>fct*-fiX1sm0p4mlB^{ezK@1~IWZ9wC9+YF+ z=(~(W8*+ExE6*#>>{tAw*X;PK&+X^W&Tgky=w1}|BtE#oLJIX|il~STEUY#Tz2(VQ z`&B3Vjyl#YrD0cN`%dU61H;K7>6q)!i$z}|7L2_Q!zUB>5YHj$KB*~&54e_p)+o3E z)@}Hy$&_Y?$>GbJQn`S2jk!HE7KhKn!gQK;czC19OcwL+jKK@lufa|BaHT8i;}_KL zi96$Wx359a8zY;&7JdAHIAH@Dg1`v-#5?pU z(y8Q(Y8EeiYFK5KrD3h3tv%XIEZSHo8zmbhdw!O37IRi}mUGr~7M%>6DWfSAX#g4N zQc%bo0^b=pw?1A}P&geTN-;I{!|Q%N*18E8kVyo;?^&QdDeCo!7xpxGIiB=F?k|cj6|{ zq8p>zF83GpZ=t9XqA!sSqVEEcu%hu$su=~UwBYQcYjTMx9~bs&@;^Hgz9;pyXMXIB z?0F2z!Sz&qLj%w45sv|G#*nb@>&)KdaWP07@OaGC4ns$2ckwIK37}*XS?=FZyWyCk zXZmt{I3P{SL63t_*6jE!|HV7;%uCjh2uMt&1(xC-AvK8!zQodmNtYhtbr>c_@sJUp zd-rQtvw$%`80o@{oVUX?u2hL-MY87^SHfm0xJuDwRyVNuX-)huvI-yyr(`}>=H%k= zG&G8t=4uWgT%@rm%^@jMlAnF^r+_oMzszo0OtpAG)jUGTg5fP_X5mvy#1B8w`Q#&R zoe92i9J-Fc(Wo#3d^0;lhVAuIr3L9;kP^)m4#?A-X*iwK-k3xIZ630oA&Q&2JEI#c zHt!D&JWnR58b>5qYYhpMT1<$>ck|*6Gg|V2V|A8OQu89J^wOgi7*`Uu>amB9 z;kN|R4Hx~bE2iziik@h`a}$y4lhf0~bKzAOVp$Hxg8EyR!lpVI1V``t@END=P;*p! z*Q4H+@RW7`krXCq$78{Cm&}WfEwc2>81kS%ElPIRXQfXhVs&}tiZSlsd7rUCZS{2r z40pGL=a+;#Qr1?+bVDwU7)U^0J;|sVTML1%<=?>%Irq?9$!3P zOrLIPh^QM#Tvw0Z#p}X$U^PR|!gvXbz0E4;i?kC6TQqtIN(e(+uIrC@j$e}V%L5|V z@w#=B@^5L!+}cxVF>$_Ku=Z;`6M`&Q)?7p+HirO#fP=knPMEPGeM-GGgy(Wh9}Mu5 zDZrbW!eR3LU|qDmofcfj67Ce7odX{*UOEKRVhC*>v>>elj$T5_iAalCI zvbulw(i)^+hu>fqjUo>eLI%}W0TZ%r=Z& zCjfJe-$)z+6aNZ$LQc^`1d!NN4bd0|QK~{jok^^eNPpkqNKkiKVb9GsdRG(9>u|a_ zd0Dh`$}JT6D(y1`rey5kT|iy#YVuoklSCx#CR9mI zHYG`uQc{}|R8nP3c7)P(s*g~(gO7QY$wV;cCsH}Si61!;O|eEzMoUAxg2afW6zIw= zDY483vvtlY>5Rj4Bodv&#{>dWfOux#bxgkV%){btv(tlxbgV7p4SObTiJM_oLBGOJ z?bZ1<7VrTi*h7zNmhL}!33qTqYl#wkX zi?qnHkzW%c3yE3k8NdUgj00w@J&)bC=A2$p>R|3;MaU9io2q8_X=4@e$Z@Q>N#+NH5ECE)G#aYlVd~6S8#Wy$kePl{uhkN@hG|c|{7wTNgUFZrBoj z*8x`8xjo#?Q_&jpk!=5vMj?nc5%)QSTPdGN_u3keGeO+39C%{IDPSop7D6>I;jiX1 z@Gi~O?p-5#)icV!!50FO`q~Ti4Lo_9Vxrmo`ipAD1Y7IR;c`1dg-DPYO)(0hC+q3i z_^0)pa#fF)lXBuTu18r{Sn&t5#l_q_FIBuqI&sT85PpNAJ7eA5X=NkmQ)CG%O;A=cZLb4&ws~SYBWmLh$ce4wD@nF z#7t;5NL)Ng*?{FQ@G=eqU*0=UQ~k184bcLYxuHi5W`&i!uI zc(|I6oSL34J^e)3k9gcPHtvf2MrUn1gpWLI0(_qpKy`T z>?m0moTEcT@{y}HAoH}BuJ1N!@2;btn^{KtBav09Q_ToLNUG7NoTBS1#KVBZJc~>C zhO~+wj`ENgBE^Zxnk3=`^JVnEQqkPJ9LXZi1ZwxxPbmm;2e96tI)eOe%efVya0mL= zX3{pWn>C-}#}wAo^C$le+OVle1kjeE zm{5|4kElqCFdJrngPb!&0fU^|_lK0SqZn%LzsXJSI8wNsf(fh@&PQWPIlUN3=6=q- zPfaBl@!mbY{G4H8Ky`4&U{s?*7Fp~e4EV;yd9%AKDy}G)uv(_K;pc}*8IoU2-XaXo zmN$#^OF7w&CF|l?byTy0t+7c|)D#aD)Fc8@HZSk+8XS=B*N>Ell!#E0puRv^VnxHK zOR`Q%3aa*dZHw^y`R+!FwEw-mi}RgkU~U*Osi~!WQ=4ok^Md+VERy=q&QwGfgxFyP8X3y)(X{q zc1p@w2eZTLppar5Sg1B4LX#VnmrSDfJK@XSnzhi>-74&qV>$STql z)TFMqKFJ&G-gH$Py6$W`V$9N@sF1daxfVM5viuhnQ`?{9F~qCT6A`qvSv;GnL;GH` zwKKYi^85OWpV^x5{)_dUDI=O>=2O-rf((lVS?IO|cAvA=l?(W*0oi<3#-D6$K4n>T zW<`QA`hh(0(dw2z&z6b)Q1zezn4&rYd)omr<3@wIefO7GFXr|jJy4pnNGLbzhoBEr zCB_SBP0E<1WG&%uQ6)`>8aIXyyHRng*{xuyNw6b0m@q3Dss3xb1~`zb@H zN<8&~Ot4}!DaDZB*Y3W`>sXWJlq3OrdXbF0(S+I2&`zFZE3((}!I1f)U(EK&1u8zG z@r_68a`g6@(O9t$s}1hzz4g*Ni%=oG0BIW}ws}={h=X8zO_Yh$(#)Mwy&Z*-Phnf% z0?9+IsC~G5U8dQyeX;B%neCMDEF0JC*WC3~$~p-c{69jr=`5_T`U7&G|iuT=G1 z$lc(UoOx`Uv|)6)B?g+`j-no&dfwT@7(~B>_OGno6lXW zjq=4i(Z*9k&F*4|j5Dalope&89O2l6!cXXxpl2%5?oH?(h(6g6ua&9XoKn-y)&<@|6;EwP&&8dS zmk<;GaRUa`1_+*9ENOMFs_h?!JS7)&MgPTrrZjtmLKkPYU?rn}mp2r+5<#re@FokTo;T zXUg#KRR?_&bl=D=Xl>=n-cW94cxul>#DYTS_WHNCL{}f>;Wyx>2J8PufMWZfQ1eXx z8LIdH`AHvNTwovmF1|p!JTNl>gr^06)yM5C{T2^?2!`y3QXRswm*753@eZjQp`)Sc zKm?4Pe&IdT1B597AVfv}1Lx7v*+DKeI20YBBq$;kCI8X$|Mv*`u*YY-BujG{3-~$Z zs29G1Z2$21c;m-dn4VlmPS)SE-KjT7A%@?-zxC=)Cr>xw+uvA^6rLQ%8XcS*l$F<9 zL=z|+IUmyt)AyT4txLB1yDAUc9hm|rr^>5N&LBcbsxB@rtoBQ?HaRq`<(;jbH(8md z#3f8R&Tlkx)A!pqoqewDw;vDNvt;9kH&oM{hL`+25Rt zuI%l$+oRtlEOu0r$l8d!qz#;5hpiK~FS}B`$45vV-?B_HhkKN{zl-)bo3};hSDEcB zj9k6cduXAm`Q>2n0ndJH!p zr&l~96!mn@auFFOU5SAjQGt9Gpa1wX4`dKm>W?ReAb^l?MRde3Ae0jUNfPiDX1m$W zQK6vT$`*KKEFeU~+ zNLMe(h&rvE_I^3FgdRC6D<<`KI}-_u5;7(doFpP}kRaH3;N5in<#t4rn-qaQS~jF+ zG8bH1(ePaPiJ*JvhgjwbDkMCGi_^kNLE-~*(jk&!SwwUa#rHS;lJar23OzTCjpsa` zPXB^Xf8wZ)j+iQFRm#2Vq*zoy!9Xny4TU5)xGtyY?&bfz%J;7oNrV19Dc9$wm6pQd zyiZOjSb!APdB0;PZg)Q(9yCp=n#Sg7l!#Z&%1r%~^<7{L`$1+@Vd6Q!p6@J(E#QfM z6Yydc$O~l^2Jn~q9dC-dMC z7z!g0a+oJ32@p4o5iJ{C&vACQ7G@uU0Y-iMY#QVZ=jb^^3# z$I#|-o8)M^*+K@DREXB${5 zQewEASGkCBQY%rD3vm>W5(TpYmUfut_b5jpB7Rr2bb4vY`{!t(6KeF%S*!SN>aGaF z@c1DeT~3H1K(QT%Dr!Rinf+w=y>3Pg^wJMpam}z37Mrc*^WmOW7Dxmx3LZ2YF@y+` zejTWFLAA$mwgvl};f!{(XX9h6$;0-}#CHoH%YRXhBJAFMT-%G@P1$09D~2R>w0^mB za2?7wfZA5QL5v&hk)pKNnryDtP7p$#U3$8KyXxqLoUPdEi@1!cSx!;`xmGH{xIf^e zS<`i$(`%2gQ_|(=q>6eR9(4b#pt50h&+#`WQ#$))x(?lDiX*2%-MG@asu^y4n{sp4 z6U+t<38KD7Xr0MTzxf2jVDF(71^TbmCJUdoZmTkmgLYOupFV`10bW|Q5$KDgqa5nq ziit)Sml`!oWV5+smuY3^X5;cQx~((wMy6k0`t_gRN9@S)HLNa_H)hKW(!M>hC{$Rl&j_Z|pFmDRhr549sh)B5&E5|4T1WHjjX%CG^-YDfxH6J; z%xz72cqB7r$(iLc(l9-kddztYm3aV4GZi{jvKnydvJ`3XCk{#X`b|tAhdW8?U?K_vzHs1<8(F4Ftv%ft}_@ZDAjo} zM&g-Z7+6hi)a~8+KPM!aOa$%M(6gon+Z!BhK~t`CmKjhJ^hMSe{yK<@rT)YR4yGJ_ zduOt~y1NV@gHze}SSV{G$q7fWjWN)WsaKQDR8EI#jakcIshx&)Lj&(0J?|&zV69@h z!lGyS$A^m%>Ar$6771rzW>DMUVONhlcipk8cJHVWFZyj1fDnv+Z$U?GdF6&S(q3yH z5G3r~M4xW#5!E}i2CbzatrO+Td88(Ld3U%PlfVjR7zig9R4i!$8PQbEt7*7R#SWRa zOG~rFUU5-E;B0l<+*_7k2y;;zvC{h5+=Co?q<4;mdH-&tvhbD$XiVUcSJqh{nD<)* zi3G5=sdR|Dgl&UzpV&O}2Y*9bqU2{CI8As9oiF!7CECYt;d(W&!aTwrxIr!hVm*)L zoaT447$U=R%w;-{s2)NOra~(Ip^uYj(NIG|*0Tn?CiUtTQfTh>bT#CSRwVw+wX4Y| zOc#S;le8vYQLw1NKrP2H5fM1{(4>s@J?=AUQ3TuMw8Cb9b(?Cce{vAm2-Fpi2JK$g zBN2e!)SLIOk5^->>&(Q!q}_eei^3irnrvpju4X`L%)|2HX6;2ZWkhx;RDd(@mG%ag1P^hEzzf6MKNgQv(D??KQT(a7v-`(%%o~54UQz`B1ll2br-=1zYG_EIw^~HA zm~>~Ztnu6o*?i92jZV$XmS~YZxw%Ji1-j(hd$Yy$#$j%V`@=`uVnVWm*b71v45Lw9 z*n(>>B|DG!>xi?`l(>}g z?n5VSr*}@;2Vfs;tEYfGPCEYa*Yc=OccMC!B640lJd|X2M_Su|5ljYb$GHRBCN&cr zSZms&Fu`Unh}F(Hk7ZTft%4jxUxYS9-|W&0Jn$3$FA$PFjh*77^_)qAxp^^&wEhlg zu$TKj!}~+P@V%2z*`hfFjNSD$Z^@ZxY$K{^X0rWLdcu7=?0veC#H;CVZ0=vep17G+ z(c%W;7_#x|l@%A*H+|D|+Fgm2Bk~6Gep>F&)Y;FP#{|o7;+`!a_jL+%BPYn@0t+MWy2o|T^}fY`%` z{-OmH)MBJAg5T|q;CpE2501i+lg{}HkViiWd- zZfwl}$zt;7S`{i;>RDy#Qf9_N@1GrI(G;C34%pK@htK#z&)1f3{{s7lhb2w_;#;ED zh4b_n3hQ5=TbSnBU_h*6Se|9v)zESvVqk1E#EYHBB6jVpBN^A!`Z(XYDe)eeX@2mc z1E7}LGrnj2jj{u~F=VXBK;0h^H-BA#$d%Kvae5gy60^Faj>aGRdsv?4$aQ23_TBk(sp1M%eqtmSm5-;P{+p|v zi(fUjg_ek1s7H&`6VnH0<9uV(B-4EYt(_ZAOUDj@T3MWGWy(s^WWDm0 z%1PBOGNX8bkwkHXH94goi|L?LY8u44;4V<{Bz|P-#bU87CH6Viscn)u54@^ zzy+aF+w|<~Q16rJU?GQ|!l90!9 z@BQ)^h%YoLJzq$S4PW>LxQgVW#%Z-_C|7~xR*8}l44eV$cd)JeaiA;SKJR@|JJ+AW zFfKMp(T3QyL)+T)X~Fu6G6O+%<9v7OI1nrC!0Bn&WhStHCyS7mF0_k)!_m=<7X2kM8052KY+5TfQYF34CQc}+F!9VK3 zOaX9D88P>oExw*_DTYTkQpWfr~uPdz17iXC}P;l>4cFn#Sbe@j>MARW|!!Z=eF3Q+Yy~xs|qdqpiH;;f2Beltg-( zh2ufh7LBC#Y^KXoyfK5#XWxAZvx6fgi(rzF@xM_gw8Pie(H}2 zgCiy(-7DQIgJXJV`uh~niM$DXW19K^*9es{j%f=0WID1G`6JOI(j#R_l=?W=bd|vk z#_$n+VVYSE{q01V`g`I-?zrobFSp0`Sw0YPg%IkxuoZJokaX}N)bPOVh!<;%{?)U+ z>d3BqlI{`thk?Mikj+6~ktT_7q&@t*hBS=1LWV&>Tf^R}?gFlB%-5*1NWKkSc-{y~ z%H?a78I85hywV{Vu3wBFDTFoKhyyTn?cn{%>NZa+tXG?&)XLpfJE)lxGe8RJ4i!rp zG&Dz*LHl;jLdrskf~&RnFy-8(^9%F!z!pHW7ojOM`z3&8?t%nHpRam;nY8qY(b&@8 z^vZF<#Rgdl93hK9VI*S3PCIz><8qK{7mj28@`|rvx&tXs_>o;VQqcWZLqEYOrna z*5$SyO*VpoYk7|0YBXP%B=MfdkRaLVnz=WlUbg)64$sejhF`|yd|V!$N0CQF3fB!% zp>RF4dZ3Or>tmiLTzg4>5y>;Koj@-G{0bG?l>ORh^d5fSwoAvR`A7iwWfC>Tf8OJ0 zk3zv?G6XnsLf|m8-a-O*^1TM+z)D0q(WmmRnwv6y9`_9&(Beh|qgKbx`bC>Mra|Qb zZF0P;tb>gIaouR`z^{z zG_Xf-Tx^|OJ#3i{Vn6Ws4dE9bNa!}FVj!*CTLccz$EX7jse-r>g6uNcEB1xy(6u?- z0CQ}0A|sCkm?7k}EWvYSJu;ADpgApDFQlA5KXEGY)p&W1U1QNHq{L3%B%D8+x4Oz zs^MTlzExv%czoX1Hi3x~c(MG*gv?pqQ(=;(I9M*9|2rNUSX5$9aySxR7-er7TrhI|}l|iY`)wauHLkIR2m-tK=!E+?V5W_`TRN3)UR){yN%$M&Cz<-;f5(7 zymM%%g+*;=#9T7+4XK)LV;&}NkmxZE`!afq^$c#$@Rq(Obwr*lM=Kt$m=BIN_urhA z)3Emh)a7^Dg7Qg)wbOtk2C3OipbJg%LY_~UZfJr0u66+?bWwL?l~_yz-@*xD$crcy zfw7xo7-EFSb`03Q2B>04Yi2jSD5D;CowPijHnMiT@uol!BbL%Hrn55r_0J|WEoH)V z1_~~YuQKm3LlO4z_J(08$2#y3>y@zowqXd3W&$Ca(9T+_c{X>iF*O2ykTL>NEF4_Y zqeMReAx+zE%DH!aZR9+F7SEaD+ggEFt2dGi?R(}M!l7r{$L&}+);h0|mGg3KkfVETDshW(7Oz%Pz6#9o@ ztGHwl?29jiM96j#%Agt%@v2axN`D${yXyn!+;=0rGJ}2Tm;s98mRq*oI5-2Q$Z^0$ zLr7O~Ti=KIF^j2Qm(*x%P0vM*JD}7|`#MIT+VWSLa^luXTr8do5m56XGPP&Wsgv;L zrOnV}oU8SohreBRWda}Wg8Y)4!sqY;mTrE;ybbKL3E69GTOGLqm{obydu7@~as7#$W!CAZ zzFKBXt+}_JgDLOGYD`9VU=duCy5GTHU>fQc=_!7vozcx6egD}%g7CEN>UxFV<#V*ozNxE8(#iP z{T8U0TARb6^CF2eMZ>5j@(|`}ZN5G*`sQADLpVA|=kmiOZ}c!m)S$p0llQX1R|-%% z+>iQdyWLIlfwevNmb*(Gn{4~@;-f&7VICLTL&{k-Nt#0SdQ`(44LD3tCHvjX)ngm|{r zzXUMry#ev^ObaYSY`7h8c;>hxUH8{VK3{W7@6Shmw~S{56^Hu;lDcb!u;P}Z1f!4- z`_lvY4b&v=7$PL953As+9>={LrwdcbkLcH>+5 z8Hn}+asOn8w=_>|t>&uXCiL4NrL7NfAI&CBeIcb*jwN=)P4%+7+Dkcu#;uyYp60fUK49s$ zrSP1>uhX-z?+jFvz4ZsA%n;h(+@|%}BNaA*8cLum%i1oVEM8Dx%x=p1Xm6Ln#mcwk zx}M$lkvsG(Zb7*cHmMuUguxkaAL}$9)y6Gc;X?JIs%4tE^Rj4{kv4iN$jWgpC!gPT z*mpdRn>!o7X*CwE$&-?WLkq+)rX`tnC!-6QKi|=zl`hLKRuHx!%Xa}Dmnu>@hMmmP z1iZlK7}O?n`t%0kce|y)>Ks*r)q-24Lm9@%4|!ZU%IMY@{tVIhu2;Px<#KF1Q>`u% zElCk339@pvYg7*mv1J%*`4H-yAOrBF0>mp87KzQ-*w*3_QMgT(8ku}6bc1V?YBzBsRtx6DP#{kL5+h&MgMJe{Lby742*ww$OFoqgRt41j zl@Xid(Ks0S^RRHG)8cx(doN-&vsf1jicJIyf`W56O0LOEFUv2>bGqW$tvjbr2CSG6 zA;orY%Ywx5VwMyzYoT3EAQI>CEVdC3T2mFJi>MWDAyA5*cRV{sB`N=FF7jndG7UquG3j8T4`mt|aS81}%wc?)Rg+@!vO3%%o{(d)*L?o~GP-gvPC zBrBe)pRNfIeu809ky+me;DLfwhnc!?A|-_m;ZziP>&pV1d!MAdA91dQlcOe7X{`<$ zR{1c~kJaA0_BjvQ&LLl4f7yKtu0S6~i4F)C=&o|G{BC-KwF)`L~B=r1Z^;w#yQD^?RW;MXSa)wdKtgB(vQ zxKFHZH`3bdZD69zuEx~$i*n~*CBY}A;llysmT3f}bLIgPSB%NS%*%Hl*%i0ikyY?n#ofopX$JB*h%T?U0rm$eVy|6*5R58CNnLu3##mQsO<>UDnj~ z`%L*6`as>oUru3C#m(P}8=R&28jZq*=FP-GyW<2N6l~F3PWuP@lU`xhOYXwO%SA`n zR~gM0)3WC}9Ak)3>HQ;{8683T{bIx$|32N;oyx@vY-KO`?aku$3bGy+Ex6E{<1sX~ zvL~fs3r<#?X6ztfJG`z=Oh=9R%G(p#e5I*W8H@mpeRYPQGwCT zhLRw|2ai7%sS{KcEmf?x09FE;T+I3&*@WgTgDB-Ert;4M!=7VF2oVMsS8Gx`x8;{9 z8+z5c?-gF6;Y~apJY7A`mUT6lpn1ew_W7q4tIIo;)A=WPq(Pr@90*bh`nrT;|EeX- z=1-nF<|2(mct{zKwD@T!AYR&nS>QMdN37;63|uCXR^(jx{ia~?)enu|>EH83N02{8 zqU~cbKabN24d4Hj;j&s>mVUpN{DK0pBBTE|n?BqBzv=()9R!SY{}GC#9WVXQK>!#0 z$}>!rC>)GWJ`RKrk41#?EiVoO@DfLWY>3`4c70iIj-svS?c=r+m0Q?=(u{)=#&b=C zsg;M@)W9a|N(s-=1)VVrQN~YmIaBLk1syrjy3*B3DBvU>(U_8m@pOIcQGS4g^s?V~ ztPhvqtQ&bkPs_H_k&8Ep#`kpmbu!GOr&v}#NNtX*lJBfj*Parsn$bzm%T}P{*U0ti zVxKnFJiOk7U|nfD#xUbJRzYD}w%qGGDmVZ9(Ai8Csp!hEf6rsOetwnqcp#+Z&I6wc zcHr%W#{S`r)M3$gF zegC>3D;%#r{F;LVpvLCU+u7BHC=o^+PGBM>9EA}1*dm+e9-C$j#+E%0${?CQqrH?x z&%sH-BiT;D^IdXXc2g(~cM?bfC|UGROk~lNNH^_A!FOcXYRdh=D8WPBL4Sii&F5v2 zw8Rzj@aDVrMAiiS88E6*2BB2QVEd=^os!T5CIuYwA*CnWd>%I8@Z?EX??;Hqr+$>I5*A(8KMqz#z{V4xK$2Y_*n=bG(`80$5iT=WWO`l9n0c>*{NWd*onP@ti^Xu9P8=t(G07Eq6y} zcRNeQ7QQhsZ_u|_D%A7Le{%ZCLZ(0GVss9*wG~$g%`;w`RzH>6WqJC>qhT|O`?*Ir zl=BINy13QUR1bo{Eb$UUZNg_Ur6AKgeWzmBhI1YHcC==#yOcT*e4|s8=D)X%^g z?d+i&|D#2MKF#5{mxH}`%n9ro3Ybw;ZtgKID9^+@n~u7P2ldidQ;ig5AI6S_^UlbJ z{{=o}LFQblM_(gCilTj0MO9fuVGXSH*59iFueJ4l-2xts2Y;bx6`YjWT3+hTfs>fl zIOrCc`Z);f)vOcXA7pjpjd~?EU34O}3}H|9F?z0vyo4_4A)I_(`6paYi+)fxHx3nz z)&r}kP!(C8zMdLP?;^%HtlEi9z+r4GRl0zn+q8rl4TJU%4e^+)?mHC^Ji#W75&7{6 zW0Gto7waiMgM7#ohk@YFk`UelQA>KcW99>cbjV*3yR(=>mUm%x-a#rWq)RpRk;+r5 z`IQNjQsEC<_ZTT+!bV6}^qJ^NgyIk(VF>5#gJm@S9ZdFspsr-L$$!(W%)02&CuaU5 za@ApH%NPS*SNe4O}gMD6sSLSC z`ZCGIWFgd`A)FGLtL(T-Yg|n;C(iLH3ZxMMskE8K^YsCFMQa=eC2G~8$NonlVFnpx zX!*1kle6-E7VEtj?nqfAL6sflsfFf%0$Lb%+W3y=fQ4=HtLV;+(|!kh z`?-6b2OqO&UI22Etuw*1rou~MDqyN7KA2ZN!o> zfWq;PT$4%zBks)`A7$%KD~YoT^{U$xM0;ktW52XTBn2euDlu2f-mYo4-#w|2g9c3w zg`zAL%GZ8eE+h8`l-dif9#|b@n)0S3OEPVc8@FCJW*OC2e@0uyj1^sVSWn3XY8y-z z-xh=9vOqL9ve0}ivt{vW3)|G#DLzewj@w7eM%6sBEr(6U-(M1UMkw^)qAx+H0riSD z>Y)ye%m|9l4GT>9k&#luwZBH|7&9KcMWLKK*V8cL633#ti`fb3b`liyWAl~-6AI$9 z98$oY|5Ocqts)5wc560UCJpWu_wBhUI&?2?s{%6el1c)dOKSn8Sw<-~SfkZkS;~~R z(1+~%&181hTjyeduL(F+nP4xSp1M;De~FUehU zaNAZB*4D@S({bpTroq<41Qd=g3ZOly=`Y79kbnU8G7?vNomsKl5kH zpZA%lV40tsTac)r+i5#FJ5xPVwYF!Lfcwwtg5@3FY&l-;+}YW_IfhWmgY(zq-L~{P zu;sAxmRpniD_#!toY>mgx>8UqTxqhjv2a--nW%}6n*)E+FP~_PqcxSQ#61*glZS6^ zc|%5~*N2f#;~$Q3DO^ZX7h5isU61jR*Lv8 zs{b5I7x-sc609n8<2v*NV^#VmGE;%HqkFRWTL`As_kv&;uo7kls?89}k*<3wzAW?x^kj?TxUn{0{5@Z4iK zEn^4;*;MmaXN)x~-G**ew9T?lrtE+6?#7JRon}+_oXK4PUe38C4;G}*icoT(7Lu(9 zx#5MG88KVxEk;~HUw`5+#$0NdjDhPAK7N{gnOuT5ymI=@?_#7)=tkY%p$=1srRn+= zAvZWSf8sC1tY&e$rDON{w!V&1zFq9AoH8)(dZaUdkykf|@VYBkGk^5tHL<&uAa7}Y zybjD(Mci^Yma*Q76wcGAo7fLF?oQ@bo!^m~Q}{MiUCWjrw=q_K_T!^&iPMI2b6#p{ z*8V^H&#}5(Q1E-LbN}li(S=?y3!X9Qt=%w3d%x6-s+}_=rfDxZ^T}mpelfA76+ z`1A#b>%ZMkz2=_wta#$3mf*5pS$g)qjlMlnUEe>;UH>-E=Iyyl$HRYDyYJs$TllAL z&sO`m#rlzVW4A4QxTZYo?7lXh?B+`+S|nN}Vp!|^eSRV0Uehw?_jMOK#7s7QzOb=;)Bc_1GBTHR z9x3j-?saKyCtp+V^87Y$$M}`zyfG=l(_`M(Rjl~7Y>C{iE8YAm>xFgkLC974e$2nZ@b@DrZLyzP20Nqy0fo+ z`BvLGs!!N>@9_b*La)o~0}VWvhcNF7dz1I_9>3N0PYX}h?s@kjBmM6am3iXUMxMVe z9-Ta|v{m=~t}u^^SmUm(Of}x$_uXtvt}J_SD|6{dr&%YHZhiaq{yzZj1s-mbs*0IX#URu&t--~pw`)P}wj_tmGc&i`ZzdN<%0%w(Xg)Oa3 zx<2V@vdAyTDH$mt>!y}&D|ycz`#Z5Aq|%}IdqZArZF#XeTkE^fm-EaP7+T$yl&f=N z70>(?^E%Se`}+!&vukGAeb^-xd-vR>zsKHOUjFjzmscfKza2Xse)*JB^t-a)m%iGo zn;-tU})NEUIa`{c3OpUVMuAR3sv5|{!s60(3E>>onN$FC*Jazl;E@I(j4DQ zmsE6fFI`&pG3U}*wUcI^+dMbGdX3t%I+m=y_0vCw4o9H$v;fmkckR!dzPQ} z(>pj>FgrAc21pzG!9ALYpwu+|p#1z21<={yLHeF~Y55AEZV!;@5^a-`W|U-@m}-`i zmTY2VZe(haVqubIo@|ktW|WwcoRn-wSVgRUaAs91m!YA7et5K@g0X^8EWRESYX8;r zg0=qPLW!dvi&u$Uy|(q$tyRCb=9OySTIC)4Pm!(LH%YjgQNJNPVMEds30ma z6D4LGQQG$C$;O&bXDjP2^D`7#iVL``@;B4=8mX~Anb31O&{9vh$V)9X zDvg7M!SuwI>$jX+jIK>-b$N6^Y`V_0;-bbAdACjdtDY{3QM)#&tn{={(&v-YYF@9wXw9wlGj)%au2#ypjMkFF&?sy=V!RCR6bY>)lF-{&8e-sW=h#Kcl# zN!yKiipk;E_-5K{&6_N{$@|+0yPNv#PdCU+OfGWrJC!+el5tVkxzlT6CTTDE%=3rg g#wMd`%;+vINh~S>Hht2#EKE(zEVxuvUH#p-0N-)Ki2wiq diff --git a/resources/3rdparty/glpk-4.53/doc/notes/scaling.pdf b/resources/3rdparty/glpk-4.53/doc/notes/scaling.pdf deleted file mode 100644 index 732f614db5924bfca19b6a9bc2b0c95f79f83c2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42382 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 diff --git a/resources/3rdparty/glpk-4.53/doc/notes/updating.pdf b/resources/3rdparty/glpk-4.53/doc/notes/updating.pdf deleted file mode 100644 index 65b0966aaf08b0fd4f0bc298062d86b82527cda7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41817 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/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ - esac; \ - test $$am__dry = yes; \ - } -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -bin_PROGRAMS = glpsol$(EXEEXT) -subdir = examples -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(top_srcdir)/depcomp -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__installdirs = "$(DESTDIR)$(bindir)" -PROGRAMS = $(bin_PROGRAMS) -am_glpsol_OBJECTS = glpsol.$(OBJEXT) -glpsol_OBJECTS = $(am_glpsol_OBJECTS) -glpsol_LDADD = $(LDADD) -glpsol_DEPENDENCIES = ../src/libglpk.la -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(glpsol_SOURCES) -DIST_SOURCES = $(glpsol_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -AM_CPPFLAGS = -I$(srcdir)/../src -LDADD = ../src/libglpk.la -glpsol_SOURCES = glpsol.c -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu examples/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p || test -f $$p1; \ - then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list -glpsol$(EXEEXT): $(glpsol_OBJECTS) $(glpsol_DEPENDENCIES) $(EXTRA_glpsol_DEPENDENCIES) - @rm -f glpsol$(EXEEXT) - $(LINK) $(glpsol_OBJECTS) $(glpsol_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glpsol.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -cscopelist: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(PROGRAMS) -installdirs: - for dir in "$(DESTDIR)$(bindir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-binPROGRAMS - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-binPROGRAMS - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ - clean-generic clean-libtool cscopelist ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-binPROGRAMS install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-binPROGRAMS - - -check: glpsol$(EXEEXT) - ./glpsol$(EXEEXT) --version - ./glpsol$(EXEEXT) --mps $(srcdir)/plan.mps - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/resources/3rdparty/glpk-4.53/examples/assign.mod b/resources/3rdparty/glpk-4.53/examples/assign.mod deleted file mode 100644 index 6f700bb16..000000000 --- a/resources/3rdparty/glpk-4.53/examples/assign.mod +++ /dev/null @@ -1,77 +0,0 @@ -/* ASSIGN, Assignment Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* The assignment problem is one of the fundamental combinatorial - optimization problems. - - In its most general form, the problem is as follows: - - There are a number of agents and a number of tasks. Any agent can be - assigned to perform any task, incurring some cost that may vary - depending on the agent-task assignment. It is required to perform all - tasks by assigning exactly one agent to each task in such a way that - the total cost of the assignment is minimized. - - (From Wikipedia, the free encyclopedia.) */ - -param m, integer, > 0; -/* number of agents */ - -param n, integer, > 0; -/* number of tasks */ - -set I := 1..m; -/* set of agents */ - -set J := 1..n; -/* set of tasks */ - -param c{i in I, j in J}, >= 0; -/* cost of allocating task j to agent i */ - -var x{i in I, j in J}, >= 0; -/* x[i,j] = 1 means task j is assigned to agent i - note that variables x[i,j] are binary, however, there is no need to - declare them so due to the totally unimodular constraint matrix */ - -s.t. phi{i in I}: sum{j in J} x[i,j] <= 1; -/* each agent can perform at most one task */ - -s.t. psi{j in J}: sum{i in I} x[i,j] = 1; -/* each task must be assigned exactly to one agent */ - -minimize obj: sum{i in I, j in J} c[i,j] * x[i,j]; -/* the objective is to find a cheapest assignment */ - -solve; - -printf "\n"; -printf "Agent Task Cost\n"; -printf{i in I} "%5d %5d %10g\n", i, sum{j in J} j * x[i,j], - sum{j in J} c[i,j] * x[i,j]; -printf "----------------------\n"; -printf " Total: %10g\n", sum{i in I, j in J} c[i,j] * x[i,j]; -printf "\n"; - -data; - -/* These data correspond to an example from [Christofides]. */ - -/* Optimal solution is 76 */ - -param m := 8; - -param n := 8; - -param c : 1 2 3 4 5 6 7 8 := - 1 13 21 20 12 8 26 22 11 - 2 12 36 25 41 40 11 4 8 - 3 35 32 13 36 26 21 13 37 - 4 34 54 7 8 12 22 11 40 - 5 21 6 45 18 24 34 12 48 - 6 42 19 39 15 14 16 28 46 - 7 16 34 38 3 34 40 22 24 - 8 26 20 5 17 45 31 37 43 ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/bpp.mod b/resources/3rdparty/glpk-4.53/examples/bpp.mod deleted file mode 100644 index 8dd354ed8..000000000 --- a/resources/3rdparty/glpk-4.53/examples/bpp.mod +++ /dev/null @@ -1,83 +0,0 @@ -/* BPP, Bin Packing Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* Given a set of items I = {1,...,m} with weight w[i] > 0, the Bin - Packing Problem (BPP) is to pack the items into bins of capacity c - in such a way that the number of bins used is minimal. */ - -param m, integer, > 0; -/* number of items */ - -set I := 1..m; -/* set of items */ - -param w{i in 1..m}, > 0; -/* w[i] is weight of item i */ - -param c, > 0; -/* bin capacity */ - -/* We need to estimate an upper bound of the number of bins sufficient - to contain all items. The number of items m can be used, however, it - is not a good idea. To obtain a more suitable estimation an easy - heuristic is used: we put items into a bin while it is possible, and - if the bin is full, we use another bin. The number of bins used in - this way gives us a more appropriate estimation. */ - -param z{i in I, j in 1..m} := -/* z[i,j] = 1 if item i is in bin j, otherwise z[i,j] = 0 */ - - if i = 1 and j = 1 then 1 - /* put item 1 into bin 1 */ - - else if exists{jj in 1..j-1} z[i,jj] then 0 - /* if item i is already in some bin, do not put it into bin j */ - - else if sum{ii in 1..i-1} w[ii] * z[ii,j] + w[i] > c then 0 - /* if item i does not fit into bin j, do not put it into bin j */ - - else 1; - /* otherwise put item i into bin j */ - -check{i in I}: sum{j in 1..m} z[i,j] = 1; -/* each item must be exactly in one bin */ - -check{j in 1..m}: sum{i in I} w[i] * z[i,j] <= c; -/* no bin must be overflowed */ - -param n := sum{j in 1..m} if exists{i in I} z[i,j] then 1; -/* determine the number of bins used by the heuristic; obviously it is - an upper bound of the optimal solution */ - -display n; - -set J := 1..n; -/* set of bins */ - -var x{i in I, j in J}, binary; -/* x[i,j] = 1 means item i is in bin j */ - -var used{j in J}, binary; -/* used[j] = 1 means bin j contains at least one item */ - -s.t. one{i in I}: sum{j in J} x[i,j] = 1; -/* each item must be exactly in one bin */ - -s.t. lim{j in J}: sum{i in I} w[i] * x[i,j] <= c * used[j]; -/* if bin j is used, it must not be overflowed */ - -minimize obj: sum{j in J} used[j]; -/* objective is to minimize the number of bins used */ - -data; - -/* The optimal solution is 3 bins */ - -param m := 6; - -param w := 1 50, 2 60, 3 30, 4 70, 5 50, 6 40; - -param c := 100; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/cal.mod b/resources/3rdparty/glpk-4.53/examples/cal.mod deleted file mode 100644 index 2555182e0..000000000 --- a/resources/3rdparty/glpk-4.53/examples/cal.mod +++ /dev/null @@ -1,49 +0,0 @@ -/* cal.mod - print an ASCII calendar of the given year */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -param year, integer, >= 0001, <= 3999, default 2010; - -param first_day{m in 1..12}, integer, >= 0, <= 6, := - time2str(str2time(year & "-" & m & "-01", "%Y-%m-%d"), "%w"); - -param days_in_month{m in 1..12}, integer, >= 28, <= 31, := - (str2time(year + (if m < 12 then 0 else 1) & "-" & - (if m < 12 then m+1 else 1) & "-01", "%Y-%m-%d") - - str2time(year & "-" & m & "-01", "%Y-%m-%d")) / 86400; - -param foo{m in 1..12, k in 0..5, d in 0..6}, integer, := - 7 * k + d + 1 - first_day[m]; - -param cal{m in 1..12, k in 0..5, d in 0..6}, integer, := - if 1 <= foo[m,k,d] and foo[m,k,d] <= days_in_month[m] then - foo[m,k,d]; - -printf "\n"; -printf "%33s%04d\n", "", year; -printf "\n"; -for {t in 1..12 by 3} -{ for {m in t..t+2} - { printf "%7s%-14s", "", time2str(str2time(m, "%m"), "%B"); - printf{0..0: m < t+2} " "; - } - printf "\n"; - for {m in t..t+2} - { printf " S M Tu W Th F S"; - printf{0..0: m < t+2} " "; - } - printf "\n"; - for {k in 0..5} - { for {m in t..t+2} - { for {d in 0..6} - { printf{0..0: cal[m,k,d] = 0} " "; - printf{0..0: cal[m,k,d] != 0} " %2d", cal[m,k,d]; - } - printf{0..0: m < t+2} " "; - } - printf "\n"; - } -} -printf "\n"; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/cf12a.mod b/resources/3rdparty/glpk-4.53/examples/cf12a.mod deleted file mode 100644 index 61a76c050..000000000 --- a/resources/3rdparty/glpk-4.53/examples/cf12a.mod +++ /dev/null @@ -1,81 +0,0 @@ -/* - - Curve fitting problem 12.11(a) H P Williams "Model Building in Mathematical Programming" - - Dr. H J Mackenzie - HARD software - hjm@hardsoftware.com - - 2006-01-05 - - */ - -# set of points - -set I; - -# independent variable - -param x {i in I}; - -# dependent variable - -param y {i in I}; - -# output input values - -printf {i in I} "x = %.1f; y = %.1f\n", x[i], y[i]; - -# define equation variables - -var a; - -var b; - -var u {i in I}, >= 0; - -var v {i in I}, >= 0; - -# define objective function - -minimize error: sum {i in I} u[i] + sum {i in I} v[i]; - -# define equation constraint - -s.t. equation {i in I} : b * x[i] + a + u[i] - v[i] = y[i]; - -solve; - -printf "y = %.4fx + %.4f\n", b, a; - -/* - * - * DATA section - * - */ - -data; - -param : I : x y := - 1 0 1 - 2 0.5 0.9 - 3 1 0.7 - 4 1.5 1.5 - 5 1.9 2 - 6 2.5 2.4 - 7 3 3.2 - 8 3.5 2 - 9 4 2.7 - 10 4.5 3.5 - 11 5 1 - 12 5.5 4 - 13 6 3.6 - 14 6.6 2.7 - 15 7 5.7 - 16 7.6 4.6 - 17 8.5 6 - 18 9 6.8 - 19 10 7.3 -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/cf12b.mod b/resources/3rdparty/glpk-4.53/examples/cf12b.mod deleted file mode 100644 index 56f1ba106..000000000 --- a/resources/3rdparty/glpk-4.53/examples/cf12b.mod +++ /dev/null @@ -1,88 +0,0 @@ -/* - - Curve fitting problem 12.11(b) H P Williams "Model Building in Mathematical Programming" - - Dr. H J Mackenzie - HARD software - hjm@hardsoftware.com - - 2006-01-23 - - */ - -# set of points - -set I; - -# independent variable - -param x {i in I}; - -# dependent variable - -param y {i in I}; - -# output input values - -printf {i in I} "x = %.1f; y = %.1f\n", x[i], y[i]; - -# define equation variables - -var a; - -var b; - -var u {i in I}, >= 0; - -var v {i in I}, >= 0; - -var z; - -# define objective function - -minimize deviation: z; - -# define equation constraint - -s.t. equation {i in I} : b * x[i] + a + u[i] - v[i] = y[i]; - -# define deviation constrains - -s.t. u_deviation {i in I} : z - u[i] >= 0; -s.t. v_deviation {i in I} : z - v[i] >= 0; - -solve; - -printf "y = %.4fx + %.4f Max deviation = %.4f\n", b, a, z; - -/* - * - * DATA section - * - */ - -data; - -param : I : x y := - 1 0 1 - 2 0.5 0.9 - 3 1 0.7 - 4 1.5 1.5 - 5 1.9 2 - 6 2.5 2.4 - 7 3 3.2 - 8 3.5 2 - 9 4 2.7 - 10 4.5 3.5 - 11 5 1 - 12 5.5 4 - 13 6 3.6 - 14 6.6 2.7 - 15 7 5.7 - 16 7.6 4.6 - 17 8.5 6 - 18 9 6.8 - 19 10 7.3 -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/cflsq.mod b/resources/3rdparty/glpk-4.53/examples/cflsq.mod deleted file mode 100644 index 4af4d029b..000000000 --- a/resources/3rdparty/glpk-4.53/examples/cflsq.mod +++ /dev/null @@ -1,51 +0,0 @@ -/*Curve fitting problem by Least Squares - Nigel_Galloway@operamail.com - October 1st., 2007 -*/ -set Sample; -param Sx {z in Sample}; -param Sy {z in Sample}; - -var X; -var Y; -var Ex{z in Sample}; -var Ey{z in Sample}; - -/* sum of variances is zero for Sx*/ -variencesX{z in Sample}: X + Ex[z] = Sx[z]; -zumVariancesX: sum{z in Sample} Ex[z] = 0; -/* sum of variances is zero for Sy*/ -variencesY{z in Sample}: Y + Ey[z] = Sy[z]; -zumVariancesY: sum{z in Sample} Ey[z] = 0; - -solve; - -param b1 := (sum{z in Sample} Ex[z]*Ey[z])/(sum{z in Sample} Ex[z]*Ex[z]); -printf "\nbest linear fit is:\n\ty = %f %s %fx\n\n", Y-b1*X, if b1 < 0 then "-" else "+", abs(b1); - -data; - -param: -Sample: Sx Sy := - 1 0 1 - 2 0.5 0.9 - 3 1 0.7 - 4 1.5 1.5 - 5 1.9 2 - 6 2.5 2.4 - 7 3 3.2 - 8 3.5 2 - 9 4 2.7 - 10 4.5 3.5 - 11 5 1 - 12 5.5 4 - 13 6 3.6 - 14 6.6 2.7 - 15 7 5.7 - 16 7.6 4.6 - 17 8.5 6 - 18 9 6.8 - 19 10 7.3 -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/color.mod b/resources/3rdparty/glpk-4.53/examples/color.mod deleted file mode 100644 index 9a279c387..000000000 --- a/resources/3rdparty/glpk-4.53/examples/color.mod +++ /dev/null @@ -1,113 +0,0 @@ -/* COLOR, Graph Coloring Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* Given an undirected loopless graph G = (V, E), where V is a set of - nodes, E <= V x V is a set of arcs, the Graph Coloring Problem is to - find a mapping (coloring) F: V -> C, where C = {1, 2, ... } is a set - of colors whose cardinality is as small as possible, such that - F(i) != F(j) for every arc (i,j) in E, that is adjacent nodes must - be assigned different colors. */ - -param n, integer, >= 2; -/* number of nodes */ - -set V := {1..n}; -/* set of nodes */ - -set E, within V cross V; -/* set of arcs */ - -check{(i,j) in E}: i != j; -/* there must be no loops */ - -/* We need to estimate an upper bound of the number of colors |C|. - The number of nodes |V| can be used, however, for sparse graphs such - bound is not very good. To obtain a more suitable estimation we use - an easy "greedy" heuristic. Let nodes 1, ..., i-1 are already - assigned some colors. To assign a color to node i we see if there is - an existing color not used for coloring nodes adjacent to node i. If - so, we use this color, otherwise we introduce a new color. */ - -set EE := setof{(i,j) in E} (i,j) union setof{(i,j) in E} (j,i); -/* symmetrisized set of arcs */ - -param z{i in V, case in 0..1} := -/* z[i,0] = color index assigned to node i - z[i,1] = maximal color index used for nodes 1, 2, ..., i-1 which are - adjacent to node i */ -( if case = 0 then - ( /* compute z[i,0] */ - min{c in 1..z[i,1]} - ( if not exists{j in V: j < i and (i,j) in EE} z[j,0] = c then - c - else - z[i,1] + 1 - ) - ) - else - ( /* compute z[i,1] */ - if not exists{j in V: j < i} (i,j) in EE then - 1 - else - max{j in V: j < i and (i,j) in EE} z[j,0] - ) -); - -check{(i,j) in E}: z[i,0] != z[j,0]; -/* check that all adjacent nodes are assigned distinct colors */ - -param nc := max{i in V} z[i,0]; -/* number of colors used by the heuristic; obviously, it is an upper - bound of the optimal solution */ - -display nc; - -var x{i in V, c in 1..nc}, binary; -/* x[i,c] = 1 means that node i is assigned color c */ - -var u{c in 1..nc}, binary; -/* u[c] = 1 means that color c is used, i.e. assigned to some node */ - -s.t. map{i in V}: sum{c in 1..nc} x[i,c] = 1; -/* each node must be assigned exactly one color */ - -s.t. arc{(i,j) in E, c in 1..nc}: x[i,c] + x[j,c] <= u[c]; -/* adjacent nodes cannot be assigned the same color */ - -minimize obj: sum{c in 1..nc} u[c]; -/* objective is to minimize the number of colors used */ - -data; - -/* These data correspond to the instance myciel3.col from: - http://mat.gsia.cmu.edu/COLOR/instances.html */ - -/* The optimal solution is 4 */ - -param n := 11; - -set E := - 1 2 - 1 4 - 1 7 - 1 9 - 2 3 - 2 6 - 2 8 - 3 5 - 3 7 - 3 10 - 4 5 - 4 6 - 4 10 - 5 8 - 5 9 - 6 11 - 7 11 - 8 11 - 9 11 - 10 11 -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/cplex/README b/resources/3rdparty/glpk-4.53/examples/cplex/README deleted file mode 100644 index 38bb8b4d3..000000000 --- a/resources/3rdparty/glpk-4.53/examples/cplex/README +++ /dev/null @@ -1,44 +0,0 @@ -The program module in this subdirectory is a crude implementation of -CPLEX-like interface to GLPK API. It consists of two files: cplex.c and -cplex.h. - -NOTE that this module is NOT a clean room implementation of the CPLEX -callable library. It only implements a CPLEX-like interface to the GLPK -API routines, and its main purpose is to provide possibility to build -and run applications which normally use the CPLEX callable library. - -This module approximately corresponds to CPLEX 9.0. - -Currently this module can be used as a linear programming solver for -Concorde, the state-of-the-art computer code for solving the symmetric -traveling salesman problem (TSP) developed by David Applegate, Robert -Bixby, Vasek Chvatal, and William Cook. For details about Concorde see -its web page at http://www.tsp.gatech.edu/concorde.html. - -To build Concorde along with GLPK you need to do the following: - -1. Configure, build, and install GLPK. - -2. Download the Concorde tarball co031219.tgz (version Dec 19, 2003), - unpack and unarchive it. - -3. Copy files cplex.h and cplex.c to subdirectory concorde/LP/. - -4. Create file named lpglpk.c in subdirectory concorde/LP/. This file - must contain the following two lines: - - #include "cplex.c" - #include "lpcplex8.c" - -5. Configure Concorde in usual way (./configure) and then build it with - the following command: - - make CPPFLAGS=-I. LPSOLVER_INTERFACE=lpglpk.c LPSOLVER_LIB=-lglpk - - The Concorde executable can be found in subdirectory concorde/TSP/. - -Please note that currently this GLPK interface module does not support -some important features (namely, CPXgetijdiv, CPXmdleave, CPXpivotin, -CPXpivotout, and CPXstrongbranch), so large (more than 1000 nodes) TSP -instances cannot be solved in a reasonable time, and some instances may -cause abnormal termination of Concorde (if CPXgetijdiv is called). diff --git a/resources/3rdparty/glpk-4.53/examples/cplex/concorde.txt b/resources/3rdparty/glpk-4.53/examples/cplex/concorde.txt deleted file mode 100644 index c6f7aec9b..000000000 --- a/resources/3rdparty/glpk-4.53/examples/cplex/concorde.txt +++ /dev/null @@ -1,121 +0,0 @@ -Solver: Concorde-03.12.19 (options used: -s 99) - http://www.tsp.gatech.edu/concorde.html -LP Solver: GLPK 4.34 (CPLEX-like interface module examples/cplex) -Computer: Intel Pentium 4 CPU 3GHz, 2GB of RAM -Platform: Cygwin 1.5.24 (Windows XP 5.1 Build 2600 Service Pack 4) -Compiler: GCC 3.4.4 (options used: -O2) -Test set: http://www.iwr.uni-heidelberg.de/groups/comopt/software/ - TSPLIB95/ - -Problem Solution B&B Time, s ---------- -------- --- ------- -a280 2579 1 3.09 -ali535 202339 1 21.88 -att48 10628 1 0.20 -att532 27686 7 74.31 -bayg29 1610 1 0.08 -bays29 2020 1 0.08 -berlin52 7542 1 0.11 -bier127 118282 1 0.62 -brazil58 25395 1 0.23 -brd14051 -brg180 1950 1 0.34 -burma14 3323 1 0.06 -ch130 6110 1 0.92 -ch150 6528 1 1.69 -d1291 -d15112 -d1655 -d18512 -d198 15780 3 4.92 -d2103 -d493 35002 5 123.89 -d657 48913 11 148.17 -dantzig42 699 1 0.08 -dsj1000 18660188 13 251.00 -eil101 (failed due to CPXgetijdiv) -eil51 426 1 0.17 -eil76 538 1 0.11 -fl1400 -fl1577 -fl3795 -fl417 11861 1 47.20 -fnl4461 -fri26 937 1 0.05 -gil262 2378 3 10.39 -gr120 6942 1 0.66 -gr137 69853 1 2.09 -gr17 2085 1 0.03 -gr202 40160 1 3.97 -gr21 2707 1 0.03 -gr229 134602 7 19.45 -gr24 1272 1 0.03 -gr431 171414 9 40.67 -gr48 5046 1 0.22 -gr666 294358 3 40.23 -gr96 55209 1 1.22 -hk48 11461 1 0.08 -kroA100 21282 1 0.41 -kroA150 26524 1 2.09 -kroA200 29368 1 2.44 -kroB100 22141 1 1.20 -kroB150 26130 1 1.66 -kroB200 29437 1 1.41 -kroC100 20749 1 0.42 -kroD100 21294 1 0.50 -kroE100 22068 1 0.94 -lin105 14379 1 0.23 -lin318 42029 1 4.28 -nrw1379 -p654 34643 1 17.08 -pa561 2763 15 370.70 -pcb1173 56892 11 370.30 -pcb3038 -pcb442 59778 13 35.86 -pla33810 -pla7397 -pla85900 -pr1002 259045 1 23.08 -pr107 44303 1 0.38 -pr124 59030 1 1.23 -pr136 96772 1 2.19 -pr144 58537 1 0.89 -pr152 73682 1 2.73 -pr226 80369 1 2.72 -pr2392 -pr264 49135 1 1.61 -pr299 48191 3 14.52 -pr439 107217 15 117.75 -pr76 108159 1 0.95 -rat195 2323 5 12.91 -rat575 6773 19 202.52 -rat783 8806 1 37.92 -rat99 1211 1 0.50 -rd100 7910 1 0.28 -rd400 15281 11 74.41 -rl11849 -rl1304 -rl1323 -rl1889 -rl5915 -rl5934 -si1032 92650 1 82.09 -si175 21407 3 8.97 -si535 48450 1 71.28 -st70 675 1 0.20 -swiss42 1273 1 0.06 -ts225 126643 1 21.25 -tsp225 3916 1 10.14 -u1060 224094 13 507.44 -u1432 -u159 42080 1 0.41 -u1817 -u2152 -u2319 -u574 36905 1 32.84 -u724 41910 19 238.42 -ulysses16 6859 1 0.19 -ulysses22 7013 1 0.47 -usa13509 -vm1084 239297 9 543.38 -vm1748 diff --git a/resources/3rdparty/glpk-4.53/examples/cplex/cplex.c b/resources/3rdparty/glpk-4.53/examples/cplex/cplex.c deleted file mode 100644 index ef9e2dffe..000000000 --- a/resources/3rdparty/glpk-4.53/examples/cplex/cplex.c +++ /dev/null @@ -1,2130 +0,0 @@ -/* cplex.c (CPLEX-like interface to GLPK API) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include -#include -#include -#include -#include -#include -#include "cplex.h" - -struct CPXENV -{ /* environment block */ - CPXLP *list; - /* linked list of problem objects */ - int *intparam; /* int intparam[]; */ - /* integer control parameters */ - double *dblparam; /* double dblparam[]; */ - /* floating-point control parameters */ -}; - -struct CPXLP -{ /* problem object */ - CPXENV *env; - /* pointer to environment block */ - glp_prob *prob; - /* pointer to underlying GLPK problem object */ - int rflen; - /* length of the array rflag */ - char *rflag; /* char rflag[rflen]; */ - /* rflag[i], i = 0,...,nrows-1, is a flag of i-th row: */ -#define RF_NOT_RANGED 0 /* not ranged */ -#define RF_RANGED_POS 1 /* ranged, RHS = lower bound */ -#define RF_RANGED_NEG 2 /* ranged, RHS = upper bound */ - int stat; - /* solution status reported by CPXgetstat; zero means no solution - exists */ - int meth; - /* method indicator reported by CPXgetmethod */ - int iwlen; - /* length of the working array */ - int *iwork; /* int iwork[iwlen] */ - /* working array initialized by binary zeros */ - CPXLP *link; - /* pointer to another problem object */ -}; - -struct intparam -{ int which; - int defv; - int minv; - int maxv; -}; - -struct dblparam -{ int which; - double defv; - double minv; - double maxv; -}; - -struct errstring -{ int code; - const char *string; -}; - -#define BIGINT 2100000000 -#define BIGDBL 1e75 - -static const struct intparam intparam[] = -{ {CPX_PARAM_ADVIND, 0, 0, 2}, - {CPX_PARAM_AGGIND, -1, -1, BIGINT}, - {CPX_PARAM_DATACHECK, CPX_OFF, CPX_OFF, CPX_ON}, - {CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO, CPX_DPRIIND_AUTO, - CPX_DPRIIND_DEVEX}, - {CPX_PARAM_FASTMIP, CPX_OFF, CPX_OFF, CPX_ON}, /* ??? */ - {CPX_PARAM_ITLIM, BIGINT, 0, BIGINT}, - {CPX_PARAM_PERIND, CPX_OFF, CPX_OFF, CPX_ON}, - {CPX_PARAM_PPRIIND, CPX_PPRIIND_AUTO, CPX_PPRIIND_PARTIAL, - CPX_PPRIIND_FULL}, - {CPX_PARAM_PREIND, CPX_ON, CPX_OFF, CPX_ON}, - {CPX_PARAM_REINV, 0, 0, 10000}, - {CPX_PARAM_SCRIND, CPX_OFF, CPX_OFF, CPX_ON}, - {CPX_PARAM_SIMDISPLAY, 1, 0, 2}, -}; - -static const struct dblparam dblparam[] = -{ {CPX_PARAM_EPOPT, 1e-6, 1e-9, 1e-1}, - {CPX_PARAM_EPPER, 1e-6, 1e-8, BIGDBL}, - {CPX_PARAM_EPRHS, 1e-6, 1e-9, 1e-1}, - {CPX_PARAM_OBJLLIM, -BIGDBL, -BIGDBL, +BIGDBL}, - {CPX_PARAM_OBJULIM, +BIGDBL, -BIGDBL, +BIGDBL}, -}; - -static const struct errstring errstring[] = -{ {CPXERR_ARRAY_NOT_ASCENDING, "Array entry %d not ascending"}, - {CPXERR_BAD_ARGUMENT, "Invalid argument"}, - {CPXERR_BAD_CTYPE, "Invalid ctype entry %d"}, - {CPXERR_BAD_FILETYPE, "Invalid filetype"}, - {CPXERR_BAD_LUB, "Invalid bound change indicator entry %d"}, - {CPXERR_BAD_PARAM_NUM, "Invalid parameter number"}, - {CPXERR_BAD_SENSE, "Invalid sense entry %d"}, - {CPXERR_BAD_STATUS, "Invalid status entry %d for basis specificat" - "ion"}, - {CPXERR_COL_INDEX_RANGE, "Column index %d out of range"}, - {CPXERR_COUNT_RANGE, "Count entry %d negative or larger than allo" - "wed"}, - {CPXERR_DUP_ENTRY, "Duplicate entry"}, - {CPXERR_FAIL_OPEN_WRITE, "Could not open file '%s' for writing"}, - {CPXERR_INDEX_RANGE, "Index is outside range of valid values"}, - {CPXERR_NEGATIVE_SURPLUS, "Insufficient array length"}, - {CPXERR_NO_BASIC_SOLN, "No basic solution exists"}, - {CPXERR_NO_ENVIRONMENT, "No environment exists"}, - {CPXERR_NO_FILENAME, "File name not specified"}, - {CPXERR_NO_MEMORY, "Out of memory"}, - {CPXERR_NO_PROBLEM, "No problem exists"}, - {CPXERR_NO_SOLN, "No solution exists"}, - {CPXERR_NOT_FIXED, "Only fixed variables are pivoted out"}, - {CPXERR_NULL_NAME, "Null pointer %d in name array"}, - {CPXERR_NULL_POINTER, "Null pointer for required data"}, - {CPXERR_PARAM_TOO_BIG, "Parameter value too big"}, - {CPXERR_PARAM_TOO_SMALL, "Parameter value too small"}, - {CPXERR_ROW_INDEX_RANGE, "Row index %d out of range"}, -}; - -/**********************************************************************/ - -#define xassert glp_assert -#define xprintf glp_printf -#define xmalloc glp_malloc -#define xcalloc glp_calloc -#define xfree glp_free - -/**********************************************************************/ - -static int findintparam(int whichparam) -{ int k, card; - card = sizeof(intparam) / sizeof(struct intparam); - for (k = 0; k < card; k++) - if (intparam[k].which == whichparam) return k; - return -1; -} - -static int getintparam(CPXENV *env, int whichparam) -{ int k; - xassert(env != NULL); - k = findintparam(whichparam); - xassert(k >= 0); - return env->intparam[k]; -} - -static int finddblparam(int whichparam) -{ int k, card; - card = sizeof(dblparam) / sizeof(struct dblparam); - for (k = 0; k < card; k++) - if (dblparam[k].which == whichparam) return k; - return -1; -} - -static double getdblparam(CPXENV *env, int whichparam) -{ int k; - xassert(env != NULL); - k = finddblparam(whichparam); - xassert(k >= 0); - return env->dblparam[k]; -} - -static const char *finderrstring(int errcode) -{ int k, card; - card = sizeof(errstring) / sizeof(struct errstring); - for (k = 0; k < card; k++) - { if (errstring[k].code == errcode) - return errstring[k].string; - } - return NULL; -} - -static int error(CPXENV *env, int errcode, ...) -{ va_list arg; - char buffer[510]; - xassert(env != NULL); - if (getintparam(env, CPX_PARAM_SCRIND) == CPX_ON) - { xassert(CPXgeterrorstring(env, errcode, buffer) == buffer); - va_start(arg, errcode); - vprintf(buffer, arg); - va_end(arg); - } - return errcode; -} - -static int checkenv(CPXENV *env) -{ int errcode; - if (env == NULL) - errcode = CPXERR_NO_ENVIRONMENT; - else - errcode = 0; - return errcode; -} - -static checklp(CPXENV *env, CPXLP *lp) -{ int errcode; - errcode = checkenv(env); - if (errcode) goto done; - if (lp == NULL) - errcode = error(env, CPXERR_NO_PROBLEM); -done: return errcode; -} - -static void invalidate(CPXLP *lp) -{ lp->stat = 0; - lp->meth = CPX_ALG_NONE; - return; -} - -static void enlargerflag(CPXLP *lp) -{ int m; - xassert(lp != NULL); - m = glp_get_num_rows(lp->prob); - if (lp->rflen < m) - { int rflen = lp->rflen; - char *rflag = lp->rflag; - while (lp->rflen < m) - { lp->rflen += lp->rflen; - xassert(lp->rflen > 0); - } - lp->rflag = xcalloc(lp->rflen, sizeof(char)); - memcpy(lp->rflag, rflag, rflen); - xfree(rflag); - } - return; -} - -static void enlargeiwork(CPXLP *lp, int len) -{ xassert(len >= 0); - if (lp->iwlen < len) - { xfree(lp->iwork); - while (lp->iwlen < len) - { lp->iwlen += lp->iwlen; - xassert(lp->iwlen > 0); - } - lp->iwork = xcalloc(lp->iwlen, sizeof(int)); - memset(lp->iwork, 0, lp->iwlen * sizeof(int)); - } - return; -} - -/**********************************************************************/ - -int CPXaddcols(CPXENV *env, CPXLP *lp, int ccnt, int nzcnt, - const double obj[], const int cmatbeg[], const int cmatind[], - const double cmatval[], const double lb[], const double ub[], - char *colname[]) -{ int j, k, m, n, beg, end, type, errcode; - double lbnd, ubnd; - errcode = checklp(env, lp); - if (errcode) goto done; - if (ccnt < 0 || nzcnt < 0) - { errcode = error(env, CPXERR_BAD_ARGUMENT); - goto done; - } - if (ccnt > 0) - { if (cmatbeg == NULL || cmatind == NULL || cmatval == NULL) - { errcode = error(env, CPXERR_NULL_POINTER); - goto done; - } - } - m = glp_get_num_rows(lp->prob); - n = glp_get_num_cols(lp->prob); - enlargeiwork(lp, m); - for (j = 0; j < ccnt; j++) - { beg = cmatbeg[j]; - if (j > 0 && !(cmatbeg[j-1] <= beg)) - { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, j); - goto done; - } - if (!(0 <= beg && beg <= nzcnt)) - { errcode = error(env, CPXERR_INDEX_RANGE); - goto done; - } - end = (j < ccnt-1 ? cmatbeg[j+1] : nzcnt); - for (k = beg; k < end; k++) - { if (!(0 <= cmatind[k] && cmatind[k] < m)) - { errcode = error(env, CPXERR_ROW_INDEX_RANGE, k); - goto done; - } - } - errcode = 0; - for (k = beg; k < end; k++) - { if (lp->iwork[cmatind[k]]) - { errcode = error(env, CPXERR_DUP_ENTRY); - break; - } - lp->iwork[cmatind[k]] = 1; - } - for (k = beg; k < end; k++) - lp->iwork[cmatind[k]] = 0; - if (errcode) goto done; - if (colname != NULL) - { if (colname[j] == NULL) - { errcode = error(env, CPXERR_NULL_NAME, j); - goto done; - } - } - } - errcode = 0; - invalidate(lp); - if (ccnt > 0) - glp_add_cols(lp->prob, ccnt); - for (j = 0; j < ccnt; j++) - { if (colname != NULL) - glp_set_col_name(lp->prob, n+j+1, colname[j]); - lbnd = (lb == NULL ? 0.0 : lb[j]); - ubnd = (ub == NULL ? +CPX_INFBOUND : ub[j]); - if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) - type = GLP_FR; - else if (ubnd >= +CPX_INFBOUND) - type = GLP_LO; - else if (lbnd <= -CPX_INFBOUND) - type = GLP_UP; - else if (lbnd != ubnd) - type = GLP_DB; - else - type = GLP_FX; - glp_set_col_bnds(lp->prob, n+j+1, type, lbnd, ubnd); - if (obj != NULL) - glp_set_obj_coef(lp->prob, n+j+1, obj[j]); - beg = cmatbeg[j]; - end = (j < ccnt-1 ? cmatbeg[j+1] : nzcnt); - for (k = beg; k < end; k++) - lp->iwork[k-beg] = cmatind[k]+1; - glp_set_mat_col(lp->prob, n+j+1, end-beg, lp->iwork-1, - cmatval+beg-1); - for (k = beg; k < end; k++) - lp->iwork[k-beg] = 0; - } -done: return errcode; -} - -int CPXaddrows(CPXENV *env, CPXLP *lp, int ccnt, int rcnt, int nzcnt, - const double rhs[], const char sense[], const int rmatbeg[], - const int rmatind[], const double rmatval[], char *colname[], - char *rowname[]) -{ int i, j, k, m, n, beg, end, type, errcode; - double temp; - errcode = checklp(env, lp); - if (errcode) goto done; - if (ccnt < 0 || rcnt < 0 || nzcnt < 0) - { errcode = error(env, CPXERR_BAD_ARGUMENT); - goto done; - } - if (rcnt > 0) - { if (rmatbeg == NULL || rmatind == NULL || rmatval == NULL) - { errcode = error(env, CPXERR_NULL_POINTER); - goto done; - } - } - m = glp_get_num_rows(lp->prob); - n = glp_get_num_cols(lp->prob); - enlargeiwork(lp, n+ccnt); - for (i = 0; i < rcnt; i++) - { if (sense != NULL) - { if (!(sense[i] == 'L' || sense[i] == 'E' || - sense[i] == 'G' || sense[i] == 'R')) - { errcode = error(env, CPXERR_BAD_SENSE, i); - goto done; - } - } - beg = rmatbeg[i]; - if (i > 0 && !(rmatbeg[i-1] <= beg)) - { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, i); - goto done; - } - if (!(0 <= beg && beg <= nzcnt)) - { errcode = error(env, CPXERR_INDEX_RANGE); - goto done; - } - end = (i < rcnt-1 ? rmatbeg[i+1] : nzcnt); - for (k = beg; k < end; k++) - { if (!(0 <= rmatind[k] && rmatind[k] < n+ccnt)) - { errcode = error(env, CPXERR_COL_INDEX_RANGE, k); - goto done; - } - } - errcode = 0; - for (k = beg; k < end; k++) - { if (lp->iwork[rmatind[k]]) - { errcode = error(env, CPXERR_DUP_ENTRY); - break; - } - lp->iwork[rmatind[k]] = 1; - } - for (k = beg; k < end; k++) - lp->iwork[rmatind[k]] = 0; - if (errcode) goto done; - if (rowname != NULL) - { if (rowname[i] == NULL) - { errcode = error(env, CPXERR_NULL_NAME, i); - goto done; - } - } - } - for (j = 0; j < ccnt; j++) - { if (colname != NULL) - { if (colname[j] == NULL) - { errcode = error(env, CPXERR_NULL_NAME, j); - goto done; - } - } - } - errcode = 0; - invalidate(lp); - if (rcnt > 0) - glp_add_rows(lp->prob, rcnt); - if (ccnt > 0) - glp_add_cols(lp->prob, ccnt); - enlargerflag(lp); - for (i = 0; i < rcnt; i++) - { if (rowname != NULL) - glp_set_row_name(lp->prob, m+i+1, rowname[i]); - temp = (rhs == NULL ? 0.0 : rhs[i]); - if (sense == NULL || sense[i] == 'E') - { lp->rflag[m+i] = RF_NOT_RANGED; - type = GLP_FX; - } - else if (sense[i] == 'L') - { lp->rflag[m+i] = RF_NOT_RANGED; - type = GLP_UP; - } - else if (sense[i] == 'G') - { lp->rflag[m+i] = RF_NOT_RANGED; - type = GLP_LO; - } - else if (sense[i] == 'R') - { lp->rflag[m+i] = RF_RANGED_POS; - type = GLP_FX; - } - else - xassert(sense != sense); - glp_set_row_bnds(lp->prob, m+i+1, type, temp, temp); - beg = rmatbeg[i]; - end = (i < rcnt-1 ? rmatbeg[i+1] : nzcnt); - for (k = beg; k < end; k++) - lp->iwork[k-beg] = rmatind[k]+1; - glp_set_mat_row(lp->prob, m+i+1, end-beg, lp->iwork-1, - rmatval+beg-1); - for (k = beg; k < end; k++) - lp->iwork[k-beg] = 0; - } - for (j = 0; j < ccnt; j++) - { if (colname != NULL) - glp_set_col_name(lp->prob, n+j+1, colname[j]); - glp_set_col_bnds(lp->prob, n+j+1, GLP_LO, 0.0, 0.0); - } -done: return errcode; -} - -int CPXbaropt(CPXENV *env, CPXLP *lp) -{ xassert(env == env); - xassert(lp == lp); - xprintf("CPXbaropt: not implemented yet\n"); - exit(EXIT_FAILURE); - return -1; -} - -int CPXbinvrow(CPXENV *env, CPXLP *lp, int i, double y[]) -{ xassert(env == env); - xassert(lp == lp); - xassert(i == i); - xassert(y == y); - xprintf("CPXbinvrow: not implemented yet\n"); - exit(EXIT_FAILURE); - return -1; -} - -int CPXchgbds(CPXENV *env, CPXLP *lp, int cnt, const int indices[], - const char lu[], const double bd[]) -{ int j, n, type, errcode; - double lbnd, ubnd; - errcode = checklp(env, lp); - if (errcode) goto done; - if (cnt < 0) - { errcode = error(env, CPXERR_BAD_ARGUMENT); - goto done; - } - if (cnt > 0) - { if (indices == NULL || lu == NULL || bd == NULL) - { errcode = error(env, CPXERR_NULL_POINTER); - goto done; - } - } - n = glp_get_num_cols(lp->prob); - for (j = 0; j < cnt; j++) - { if (!(0 <= indices[j] && indices[j] < n)) - { errcode = error(env, CPXERR_COL_INDEX_RANGE, j); - goto done; - } - if (!(lu[j] == 'L' || lu[j] == 'U' || lu[j] == 'B')) - { errcode = error(env, CPXERR_BAD_LUB, j); - goto done; - } - } - errcode = 0; - invalidate(lp); - for (j = 0; j < cnt; j++) - { type = glp_get_col_type(lp->prob, indices[j]+1); - lbnd = glp_get_col_lb(lp->prob, indices[j]+1); - ubnd = glp_get_col_ub(lp->prob, indices[j]+1); - if (type == GLP_FR || type == GLP_UP) - lbnd = -CPX_INFBOUND; - if (type == GLP_FR || type == GLP_LO) - ubnd = +CPX_INFBOUND; - if (lu[j] == 'L') - lbnd = bd[j]; - else if (lu[j] == 'U') - ubnd = bd[j]; - else if (lu[j] == 'B') - lbnd = ubnd = bd[j]; - else - xassert(lu != lu); - if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) - type = GLP_FR; - else if (ubnd >= +CPX_INFBOUND) - type = GLP_LO; - else if (lbnd <= -CPX_INFBOUND) - type = GLP_UP; - else if (lbnd != ubnd) - type = GLP_DB; - else - type = GLP_FX; - glp_set_col_bnds(lp->prob, indices[j]+1, type, lbnd, ubnd); - } -done: return errcode; -} - -int CPXchgcoeflist(CPXENV *env, CPXLP *lp, int numcoefs, - const int rowlist[], const int collist[], const double vallist[]) -{ int i, j, k, m, n, rcnt, ccnt, len, ptr, errcode; - int *head, *next, *ind; - double *val; - errcode = checklp(env, lp); - if (errcode) goto done; - if (numcoefs < 0) - { errcode = error(env, CPXERR_BAD_ARGUMENT); - goto done; - } - if (numcoefs == 0) - { errcode = 0; - goto done; - } - if (rowlist == NULL || collist == NULL || vallist == NULL) - { errcode = error(env, CPXERR_NULL_POINTER); - goto done; - } - /* check triplets and determine the number of rows and columns - to be changed */ - m = glp_get_num_rows(lp->prob); - n = glp_get_num_cols(lp->prob); - enlargeiwork(lp, m); - enlargeiwork(lp, n); - rcnt = ccnt = 0; - for (k = 0; k < numcoefs; k++) - { i = rowlist[k]; - if (!(0 <= i && i < m)) - { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i); - goto done; - } - if (!(lp->iwork[i] & 0x01)) - rcnt++, lp->iwork[i] |= 0x01; - j = collist[k]; - if (!(0 <= j && j < n)) - { errcode = error(env, CPXERR_COL_INDEX_RANGE, j); - goto done; - } - if (!(lp->iwork[j] & 0x02)) - ccnt++, lp->iwork[j] |= 0x02; - } - memset(lp->iwork, 0, m * sizeof(int)); - memset(lp->iwork, 0, n * sizeof(int)); - errcode = 0; - invalidate(lp); - if (rcnt <= ccnt) - { /* change the matrix by rows */ - /* build the linked list of triplets: - head[i] is a pointer to first triplet for row i - next[k] is a pointer to next triplet for the same row */ - head = xcalloc(m, sizeof(int)); - for (i = 0; i < m; i++) - head[i] = -1; - next = xcalloc(numcoefs, sizeof(int)); - for (k = 0; k < numcoefs; k++) - { i = rowlist[k]; - next[k] = head[i]; - head[i] = k; - } - /* check duplicate columns */ - for (i = 0; i < m; i++) - { for (k = head[i]; k >= 0; k = next[k]) - { j = collist[k]; - if (lp->iwork[j]) - { xfree(head); - xfree(next); - errcode = error(env, CPXERR_DUP_ENTRY); - goto done; - } - lp->iwork[j] = 1; - } - for (k = head[i]; k >= 0; k = next[k]) - lp->iwork[collist[k]] = 0; - } - /* perform operation */ - ind = xcalloc(1+n, sizeof(int)); - val = xcalloc(1+n, sizeof(double)); - for (i = 0; i < m; i++) - { if (head[i] < 0) continue; - len = glp_get_mat_row(lp->prob, i+1, ind, val); - for (ptr = 1; ptr <= len; ptr++) - { j = ind[ptr]-1; - xassert(lp->iwork[j] == 0); - lp->iwork[j] = ptr; - } - for (k = head[i]; k >= 0; k = next[k]) - { j = collist[k]; - if (lp->iwork[j] == 0) - lp->iwork[j] = ++len; - ptr = lp->iwork[j]; - ind[ptr] = j+1, val[ptr] = vallist[k]; - } - glp_set_mat_row(lp->prob, i+1, len, ind, val); - for (ptr = 1; ptr <= len; ptr++) - lp->iwork[ind[ptr]-1] = 0; - } - } - else - { /* change the matrix by columns */ - /* build the linked lists of triplets: - head[j] is a pointer to first triplet for column j - next[k] is a pointer to next triplet for the same column */ - head = xcalloc(n, sizeof(int)); - for (j = 0; j < n; j++) - head[j] = -1; - next = xcalloc(numcoefs, sizeof(int)); - for (k = 0; k < numcoefs; k++) - { j = collist[k]; - next[k] = head[j]; - head[j] = k; - } - /* check duplicate rows */ - for (j = 0; j < n; j++) - { for (k = head[j]; k >= 0; k = next[k]) - { i = rowlist[k]; - if (lp->iwork[i]) - { xfree(head); - xfree(next); - errcode = error(env, CPXERR_DUP_ENTRY); - goto done; - } - lp->iwork[i] = 1; - } - for (k = head[j]; k >= 0; k = next[k]) - lp->iwork[rowlist[k]] = 0; - } - /* perform operation */ - ind = xcalloc(1+m, sizeof(int)); - val = xcalloc(1+m, sizeof(double)); - for (j = 0; j < n; j++) - { if (head[j] < 0) continue; - len = glp_get_mat_col(lp->prob, j+1, ind, val); - for (ptr = 1; ptr <= len; ptr++) - { i = ind[ptr]-1; - xassert(lp->iwork[i] == 0); - lp->iwork[i] = ptr; - } - for (k = head[j]; k >= 0; k = next[k]) - { i = rowlist[k]; - if (lp->iwork[i] == 0) - lp->iwork[i] = ++len; - ptr = lp->iwork[i]; - ind[ptr] = i+1, val[ptr] = vallist[k]; - } - glp_set_mat_col(lp->prob, j+1, len, ind, val); - for (ptr = 1; ptr <= len; ptr++) - lp->iwork[ind[ptr]-1] = 0; - } - } - xfree(head); - xfree(next); - xfree(ind); - xfree(val); -done: return errcode; -} - -void CPXchgobjsen(CPXENV *env, CPXLP *lp, int maxormin) -{ int errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - if (!(maxormin == CPX_MIN || maxormin == CPX_MAX)) - { errcode = error(env, CPXERR_BAD_ARGUMENT); - goto done; - } - errcode = 0; - invalidate(lp); - if (maxormin == CPX_MIN) - glp_set_obj_dir(lp->prob, GLP_MIN); - else - glp_set_obj_dir(lp->prob, GLP_MAX); -done: xassert(errcode == errcode); - return; -} - -int CPXchgsense(CPXENV *env, CPXLP *lp, int cnt, const int indices[], - const char sense[]) -{ int i, m, type, errcode; - double rhs; - errcode = checklp(env, lp); - if (errcode) goto done; - if (cnt < 0) - { errcode = error(env, CPXERR_BAD_ARGUMENT); - goto done; - } - if (cnt > 0 && (indices == NULL || sense == NULL)) - { errcode = error(env, CPXERR_NULL_POINTER); - goto done; - } - m = glp_get_num_rows(lp->prob); - for (i = 0; i < cnt; i++) - { if (!(0 <= indices[i] && indices[i] < m)) - { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i); - goto done; - } - if (!(sense[i] == 'L' || sense[i] == 'E' || sense[i] == 'G' || - sense[i] == 'R')) - { errcode = error(env, CPXERR_BAD_SENSE, i); - goto done; - } - } - errcode = 0; - invalidate(lp); - for (i = 0; i < cnt; i++) - { type = glp_get_row_type(lp->prob, indices[i]+1); - if (lp->rflag[indices[i]] == RF_NOT_RANGED) - { if (type == GLP_LO || type == GLP_FX) - rhs = glp_get_row_lb(lp->prob, indices[i]+1); - else if (type == GLP_UP) - rhs = glp_get_row_ub(lp->prob, indices[i]+1); - else - xassert(type != type); - } - else if (lp->rflag[indices[i]] == RF_RANGED_POS) - { xassert(type == GLP_DB || type == GLP_FX); - rhs = glp_get_row_lb(lp->prob, indices[i]+1); - } - else if (lp->rflag[indices[i]] == RF_RANGED_NEG) - { xassert(type == GLP_DB); - rhs = glp_get_row_ub(lp->prob, indices[i]+1); - } - else - xassert(lp != lp); - if (sense[i] == 'L') - { lp->rflag[indices[i]] = RF_NOT_RANGED; - type = GLP_UP; - } - else if (sense[i] == 'E') - { lp->rflag[indices[i]] = RF_NOT_RANGED; - type = GLP_FX; - } - else if (sense[i] == 'G') - { lp->rflag[indices[i]] = RF_NOT_RANGED; - type = GLP_LO; - } - else if (sense[i] == 'R') - { lp->rflag[indices[i]] = RF_RANGED_POS; - type = GLP_FX; - } - else - xassert(sense != sense); - glp_set_row_bnds(lp->prob, indices[i]+1, type, rhs, rhs); - } -done: return errcode; -} - -int CPXcloseCPLEX(CPXENV **_env) -{ CPXENV *env; - CPXLP *lp; - int errcode; - if (_env == NULL) - { errcode = CPXERR_NULL_POINTER; - goto done; - } - env = *_env; - errcode = checkenv(env); - if (errcode) goto done; - while (env->list != NULL) - { lp = env->list; - errcode = CPXfreeprob(env, &lp); - xassert(!errcode); - } - xfree(env->intparam); - xfree(env->dblparam); - xfree(env); - *_env = NULL; - errcode = 0; -done: return errcode; -} - -int CPXcopybase(CPXENV *env, CPXLP *lp, const int cstat[], - const int rstat[]) -{ int i, j, m, n, stat, errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - m = glp_get_num_rows(lp->prob); - n = glp_get_num_cols(lp->prob); - if (m > 0 && rstat == NULL || n > 0 && cstat == NULL) - { errcode = error(env, CPXERR_NULL_POINTER); - goto done; - } - for (i = 0; i < m; i++) - { if (!(rstat[i] == CPX_AT_LOWER || rstat[i] == CPX_BASIC || - rstat[i] == CPX_AT_UPPER)) - { errcode = error(env, CPXERR_BAD_STATUS, i); - goto done; - } - } - for (j = 0; j < n; j++) - { if (!(cstat[j] == CPX_AT_LOWER || cstat[j] == CPX_BASIC || - cstat[j] == CPX_AT_UPPER || cstat[j] == CPX_FREE_SUPER)) - { errcode = error(env, CPXERR_BAD_STATUS, j); - goto done; - } - } - errcode = 0; - invalidate(lp); - for (i = 0; i < m; i++) - { if (rstat[i] == CPX_AT_LOWER) - stat = GLP_NL; - else if (rstat[i] == CPX_BASIC) - stat = GLP_BS; - else if (rstat[i] == CPX_AT_UPPER) - stat = GLP_NU; - else - xassert(rstat != rstat); - glp_set_row_stat(lp->prob, i+1, stat); - } - for (j = 0; j < n; j++) - { if (cstat[j] == CPX_AT_LOWER) - stat = GLP_NL; - else if (cstat[j] == CPX_BASIC) - stat = GLP_BS; - else if (cstat[j] == CPX_AT_UPPER) - stat = GLP_NU; - else if (cstat[j] == CPX_FREE_SUPER) - stat = GLP_NF; - else - xassert(cstat != cstat); - glp_set_col_stat(lp->prob, j+1, stat); - } -done: return errcode; -} - -int CPXcopybasednorms(CPXENV *env, CPXLP *lp, const int cstat[], - const int rstat[], const double dnorm[]) -{ int errcode; - errcode = CPXcopybase(env, lp, cstat, rstat); - xassert(dnorm == dnorm); - return errcode; -} - -int CPXcopylp(CPXENV *env, CPXLP *lp, int numcols, int numrows, - int objsen, const double obj[], const double rhs[], - const char sense[], const int matbeg[], const int matcnt[], - const int matind[], const double matval[], const double lb[], - const double ub[], const double rngval[]) -{ int errcode; - errcode = CPXcopylpwnames(env, lp, numcols, numrows, objsen, obj, - rhs, sense, matbeg, matcnt, matind, matval, lb, ub, rngval, - NULL, NULL); - return errcode; -} - -int CPXcopylpwnames(CPXENV *env, CPXLP *lp, int numcols, int numrows, - int objsen, const double obj[], const double rhs[], - const char sense[], const int matbeg[], const int matcnt[], - const int matind[], const double matval[], const double lb[], - const double ub[], const double rngval[], char *colname[], - char *rowname[]) -{ int i, j, k, beg, end, type, errcode; - double lbnd, ubnd; - char name[255+1]; - errcode = checklp(env, lp); - if (errcode) goto done; - if (numcols < 0 || numrows < 0) - { errcode = error(env, CPXERR_BAD_ARGUMENT); - goto done; - } - if (!(objsen == CPX_MIN || objsen == CPX_MAX)) - { errcode = error(env, CPXERR_BAD_ARGUMENT); - goto done; - } - if (numcols > 0) - { if (matbeg == NULL || matcnt == NULL || matind == NULL || - matval == NULL) - { errcode = error(env, CPXERR_NULL_POINTER); - goto done; - } - } - for (i = 0; i < numrows; i++) - { if (sense != NULL) - { if (!(sense[i] == 'L' || sense[i] == 'E' || - sense[i] == 'G' || sense[i] == 'R')) - { errcode = error(env, CPXERR_BAD_SENSE, i); - goto done; - } - } - if (rowname != NULL) - { if (rowname[i] == NULL) - { errcode = error(env, CPXERR_NULL_NAME, i); - goto done; - } - } - } - enlargeiwork(lp, numrows); - for (j = 0; j < numcols; j++) - { beg = matbeg[j]; - if (j > 0 && !(matbeg[j-1] <= beg)) - { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, j); - goto done; - } - if (beg < 0) - { errcode = error(env, CPXERR_INDEX_RANGE); - goto done; - } - end = beg + matcnt[j]; - if (!(beg <= end) || j < numcols-1 && !(end <= matbeg[j+1])) - { errcode = error(env, CPXERR_COUNT_RANGE, j); - goto done; - } - for (k = beg; k < end; k++) - { if (!(0 <= matind[k] && matind[k] < numrows)) - { errcode = error(env, CPXERR_ROW_INDEX_RANGE, k); - goto done; - } - } - errcode = 0; - for (k = beg; k < end; k++) - { if (lp->iwork[matind[k]]) - { errcode = error(env, CPXERR_DUP_ENTRY); - break; - } - lp->iwork[matind[k]] = 1; - } - for (k = beg; k < end; k++) - lp->iwork[matind[k]] = 0; - if (errcode) goto done; - if (colname != NULL) - { if (colname[j] != NULL) - { errcode = error(env, CPXERR_NULL_NAME, j); - goto done; - } - } - } - errcode = 0; - invalidate(lp); - if (glp_get_prob_name(lp->prob) == NULL) - name[0] = '\0'; - else - strcpy(name, glp_get_prob_name(lp->prob)); - glp_erase_prob(lp->prob); - glp_set_prob_name(lp->prob, name); - if (objsen == CPX_MIN) - glp_set_obj_dir(lp->prob, GLP_MIN); - else if (objsen == CPX_MAX) - glp_set_obj_dir(lp->prob, GLP_MAX); - else - xassert(objsen != objsen); - if (numrows > 0) - glp_add_rows(lp->prob, numrows); - enlargerflag(lp); - for (i = 0; i < numrows; i++) - { if (rowname != NULL) - glp_set_row_name(lp->prob, i+1, rowname[i]); - lbnd = ubnd = (rhs == NULL ? 0.0 : rhs[i]); - if (sense == NULL || sense[i] == 'E') - { lp->rflag[i] = RF_NOT_RANGED; - type = GLP_FX; - } - else if (sense[i] == 'L') - { lp->rflag[i] = RF_NOT_RANGED; - type = GLP_UP; - } - else if (sense[i] == 'G') - { lp->rflag[i] = RF_NOT_RANGED; - type = GLP_LO; - } - else if (sense[i] == 'R') - { if (rngval == NULL || rngval[i] == 0.0) - { lp->rflag[i] = RF_RANGED_POS; - type = GLP_FX; - } - else if (rngval[i] > 0.0) - { lp->rflag[i] = RF_RANGED_POS; - type = GLP_DB; - ubnd += rngval[i]; - } - else /* rngval[i] < 0.0 */ - { lp->rflag[i] = RF_RANGED_NEG; - type = GLP_DB; - lbnd += rngval[i]; - } - } - else - xassert(sense != sense); - glp_set_row_bnds(lp->prob, i+1, type, lbnd, ubnd); - } - if (numcols > 0) - glp_add_cols(lp->prob, numcols); - for (j = 0; j < numcols; j++) - { if (colname != NULL) - glp_set_col_name(lp->prob, j+1, colname[j]); - lbnd = (lb == NULL ? 0.0 : lb[j]); - ubnd = (ub == NULL ? +CPX_INFBOUND : ub[j]); - if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) - type = GLP_FR; - else if (ubnd >= +CPX_INFBOUND) - type = GLP_LO; - else if (lbnd <= -CPX_INFBOUND) - type = GLP_UP; - else if (lbnd != ubnd) - type = GLP_DB; - else - type = GLP_FX; - glp_set_col_bnds(lp->prob, j+1, type, lbnd, ubnd); - if (obj != NULL) - glp_set_obj_coef(lp->prob, j+1, obj[j]); - beg = matbeg[j]; - end = beg + matcnt[j]; - for (k = beg; k < end; k++) - lp->iwork[k-beg] = matind[k]+1; - glp_set_mat_col(lp->prob, j+1, end-beg, lp->iwork-1, - matval+beg-1); - for (k = beg; k < end; k++) - lp->iwork[k-beg] = 0; - } -done: return errcode; -} - -CPXLP *CPXcreateprob(CPXENV *env, int *status, const char *probname) -{ CPXLP *lp = NULL; - int errcode; - errcode = checkenv(env); - if (errcode) goto done; - lp = xmalloc(sizeof(struct CPXLP)); - lp->env = env; - lp->prob = glp_create_prob(); - glp_set_prob_name(lp->prob, probname); - lp->rflen = 100; - lp->rflag = xcalloc(lp->rflen, sizeof(char)); - lp->iwlen = 100; - lp->iwork = xcalloc(lp->iwlen, sizeof(int)); - memset(lp->iwork, 0, lp->iwlen * sizeof(int)); - lp->link = env->list; - env->list = lp; - invalidate(lp); -done: if (status != NULL) *status = errcode; - return lp; -} - -int CPXdelcols(CPXENV *env, CPXLP *lp, int begin, int end) -{ int j, n, errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - n = glp_get_num_cols(lp->prob); - if (!(0 <= begin && begin <= end && end < n)) - { errcode = error(env, CPXERR_INDEX_RANGE); - goto done; - } - errcode = 0; - invalidate(lp); - enlargeiwork(lp, end-begin+1); - for (j = begin; j <= end; j++) - lp->iwork[j-begin] = j+1; - glp_del_cols(lp->prob, end-begin+1, lp->iwork-1); - for (j = begin; j <= end; j++) - lp->iwork[j-begin] = 0; -done: return errcode; -} - -int CPXdelrows(CPXENV *env, CPXLP *lp, int begin, int end) -{ int i, m, errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - m = glp_get_num_rows(lp->prob); - if (!(0 <= begin && begin <= end && end < m)) - { errcode = error(env, CPXERR_INDEX_RANGE); - goto done; - } - errcode = 0; - invalidate(lp); - enlargeiwork(lp, end-begin+1); - for (i = begin; i <= end; i++) - lp->iwork[i-begin] = i+1; - glp_del_rows(lp->prob, end-begin+1, lp->iwork-1); - for (i = begin; i <= end; i++) - lp->iwork[i-begin] = 0; - for (i = end+1; i < m; i++) - lp->rflag[i-(end-begin+1)] = lp->rflag[i]; -done: return errcode; -} - -int CPXdelsetcols(CPXENV *env, CPXLP *lp, int delstat[]) -{ xassert(env == env); - xassert(lp == lp); - xassert(delstat == delstat); - xprintf("CPXdelsetcols: not implemented yet\n"); - exit(EXIT_FAILURE); - return -1; -} - -int CPXdelsetrows(CPXENV *env, CPXLP *lp, int delstat[]) -{ int i, m, cnt, ind, errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - m = glp_get_num_rows(lp->prob); - if (m > 0 && delstat == NULL) - { errcode = error(env, CPXERR_NULL_POINTER); - goto done; - } - errcode = 0; - invalidate(lp); - enlargeiwork(lp, m); - cnt = ind = 0; - for (i = 0; i < m; i++) - { if (delstat[i] == 1) - { delstat[i] = -1; - lp->iwork[cnt++] = i+1; - } - else - { delstat[i] = ind; - lp->rflag[ind++] = lp->rflag[i]; - } - } - if (cnt > 0) - glp_del_rows(lp->prob, cnt, lp->iwork-1); - for (i = 0; i < cnt; i++) - lp->iwork[i] = 0; -done: return errcode; -} - -int CPXdualopt(CPXENV *env, CPXLP *lp); - -int CPXfreeprob(CPXENV *env, CPXLP **_lp) -{ CPXLP *lp; - int errcode; - errcode = checkenv(env); - if (errcode) goto done; - if (_lp == NULL) - { errcode = error(env, CPXERR_NULL_POINTER); - goto done; - } - lp = *_lp; - errcode = checklp(env, lp); - if (errcode) goto done; - errcode = 0; - env = lp->env; - if (env->list == lp) - env->list = lp->link; - else - { CPXLP *pp; - for (pp = env->list; pp != NULL; pp = pp->link) - if (pp->link == lp) break; - xassert(pp != NULL); - pp->link = lp->link; - } - glp_delete_prob(lp->prob); - xfree(lp->rflag); - xfree(lp->iwork); - xfree(lp); - *_lp = NULL; -done: return errcode; -} - -int CPXgetbase(CPXENV *env, CPXLP *lp, int cstat[], int rstat[]) -{ int i, j, m, n, stat, errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - if (!lp->stat) - { errcode = error(env, CPXERR_NO_SOLN); - goto done; - } - if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) - ; - else - { errcode = error(env, CPXERR_NO_BASIC_SOLN); - goto done; - } - errcode = 0; - if (rstat != NULL) - { m = glp_get_num_rows(lp->prob); - for (i = 0; i < m; i++) - { stat = glp_get_row_stat(lp->prob, i+1); - if (stat == GLP_BS) - rstat[i] = CPX_BASIC; - else if (lp->rflag[i] == RF_NOT_RANGED || stat != GLP_NU) - rstat[i] = CPX_AT_LOWER; - else - rstat[i] = CPX_AT_UPPER; - } - } - if (cstat != NULL) - { n = glp_get_num_cols(lp->prob); - for (j = 0; j < n; j++) - { stat = glp_get_col_stat(lp->prob, j+1); - if (stat == GLP_BS) - cstat[j] = CPX_BASIC; - else if (stat == GLP_NU) - cstat[j] = CPX_AT_UPPER; - else if (stat == GLP_NF) - cstat[j] = CPX_FREE_SUPER; - else - cstat[j] = CPX_AT_LOWER; - } - } -done: return errcode; -} - -int CPXgetbasednorms(CPXENV *env, CPXLP *lp, int cstat[], int rstat[], - double dnorm[]) -{ int i, m, errcode; - errcode = CPXgetbase(env, lp, cstat, rstat); - if (errcode) goto done; - if (dnorm != NULL) - { m = glp_get_num_rows(lp->prob); - for (i = 0; i < m; i++) dnorm[i] = 1.0; - } -done: return errcode; -} - -int CPXgetbhead(CPXENV *env, CPXLP *lp, int head[], double x[]) -{ xassert(env == env); - xassert(lp == lp); - xassert(head == head); - xassert(x == x); - xprintf("CPXgetbhead: not implemented yet\n"); - exit(EXIT_FAILURE); - return -1; -} - -int CPXgetdblparam(CPXENV *env, int whichparam, double *value) -{ int k, errcode; - errcode = checkenv(env); - if (errcode) goto done; - k = finddblparam(whichparam); - if (k < 0) - { errcode = error(env, CPXERR_BAD_PARAM_NUM); - goto done; - } - errcode = 0; - if (value != NULL) - *value = env->dblparam[k]; -done: return errcode; -} - -int CPXgetdj(CPXENV *env, CPXLP *lp, double dj[], int begin, int end) -{ int j, n, errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - n = glp_get_num_cols(lp->prob); - if (!(0 <= begin && begin <= end && end < n)) - { errcode = error(env, CPXERR_INDEX_RANGE); - goto done; - } - if (!lp->stat) - { errcode = error(env, CPXERR_NO_SOLN); - goto done; - } - errcode = 0; - if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) - { if (dj != NULL) - { for (j = begin; j <= end; j++) - dj[j-begin] = glp_get_col_dual(lp->prob, j+1); - } - } - else - xassert(lp != lp); -done: return errcode; -} - -char *CPXgeterrorstring(CPXENV *env, int errcode, char *buffer) -{ const char *string; - xassert(env == env); - string = finderrstring(errcode); - if (string == NULL) - buffer = NULL; - else - sprintf(buffer, "CPLEX Error %5d: %s.\n", errcode, string); - return buffer; -} - -int CPXgetijdiv(CPXENV *env, CPXLP *lp, int *idiv, int *jdiv) -{ xassert(env == env); - xassert(lp == lp); - xassert(idiv == idiv); - xassert(jdiv == jdiv); - xprintf("CPXgetijdiv: not implemented yet\n"); - exit(EXIT_FAILURE); - return -1; -} - -int CPXgetintparam(CPXENV *env, int whichparam, int *value) -{ int k, errcode; - errcode = checkenv(env); - if (errcode) goto done; - k = findintparam(whichparam); - if (k < 0) - { errcode = error(env, CPXERR_BAD_PARAM_NUM); - goto done; - } - errcode = 0; - if (value != NULL) - *value = env->intparam[k]; -done: return errcode; -} - -int CPXgetlb(CPXENV *env, CPXLP *lp, double lb[], int begin, int end) -{ xassert(env == env); - xassert(lp == lp); - xassert(lb == lb); - xassert(begin == begin); - xassert(end == end); - xprintf("CPXgetlb: not implemented yet\n"); - exit(EXIT_FAILURE); - return -1; -} - -int CPXgetmethod(CPXENV *env, CPXLP *lp) -{ int method; - if (checklp(env, lp)) - method = CPX_ALG_NONE; - else - method = lp->meth; - return method; -} - -int CPXgetnumcols(CPXENV *env, CPXLP *lp) -{ int numcols; - if (checklp(env, lp)) - numcols = 0; - else - numcols = glp_get_num_cols(lp->prob); - return numcols; -} - -int CPXgetnumnz(CPXENV *env, CPXLP *lp) -{ int numnz; - if (checklp(env, lp)) - numnz = 0; - else - numnz = glp_get_num_nz(lp->prob); - return numnz; -} - -int CPXgetnumrows(CPXENV *env, CPXLP *lp) -{ int numrows; - if (checklp(env, lp)) - numrows = 0; - else - numrows = glp_get_num_rows(lp->prob); - return numrows; -} - -int CPXgetobjval(CPXENV *env, CPXLP *lp, double *objval) -{ int errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - if (!lp->stat) - { errcode = error(env, CPXERR_NO_SOLN); - goto done; - } - errcode = 0; - if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) - { if (objval != NULL) - *objval = glp_get_obj_val(lp->prob); - } - else - xassert(lp != lp); -done: return errcode; -} - -int CPXgetpi(CPXENV *env, CPXLP *lp, double pi[], int begin, int end) -{ int i, m, errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - m = glp_get_num_rows(lp->prob); - if (!(0 <= begin && begin <= end && end < m)) - { errcode = error(env, CPXERR_INDEX_RANGE); - goto done; - } - if (!lp->stat) - { errcode = error(env, CPXERR_NO_SOLN); - goto done; - } - errcode = 0; - if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) - { if (pi != NULL) - { for (i = begin; i <= end; i++) - pi[i-begin] = glp_get_row_dual(lp->prob, i+1); - } - } - else - xassert(lp != lp); -done: return errcode; -} - -int CPXgetsense(CPXENV *env, CPXLP *lp, char sense[], int begin, - int end) -{ xassert(env == env); - xassert(lp == lp); - xassert(sense == sense); - xassert(begin == begin); - xassert(end == end); - xprintf("CPXgetsense: not implemented yet\n"); - exit(EXIT_FAILURE); - return -1; -} - -int CPXgetslack(CPXENV *env, CPXLP *lp, double slack[], int begin, - int end) -{ int i, m, type, errcode; - double temp; - errcode = checklp(env, lp); - if (errcode) goto done; - m = glp_get_num_rows(lp->prob); - if (!(0 <= begin && begin <= end && end < m)) - { errcode = error(env, CPXERR_INDEX_RANGE); - goto done; - } - if (!lp->stat) - { errcode = error(env, CPXERR_NO_SOLN); - goto done; - } - errcode = 0; - if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) - { if (slack != NULL) - { for (i = begin; i <= end; i++) - { type = glp_get_row_type(lp->prob, i+1); - temp = glp_get_row_prim(lp->prob, i+1); - if (lp->rflag[i] == RF_NOT_RANGED) - { if (type == GLP_LO || type == GLP_FX) - slack[i-begin] = - glp_get_row_lb(lp->prob, i+1) - temp; - else if (type == GLP_UP) - slack[i-begin] = - glp_get_row_ub(lp->prob, i+1) - temp; - else - xassert(type != type); - } - else if (lp->rflag[i] == RF_RANGED_POS) - { xassert(type == GLP_DB || type == GLP_FX); - slack[i-begin] = - temp - glp_get_row_lb(lp->prob, i+1); - } - else if (lp->rflag[i] == RF_RANGED_NEG) - { xassert(type == GLP_DB); - slack[i-begin] = - temp - glp_get_row_ub(lp->prob, i+1); - } - else - xassert(lp != lp); - } - } - } - else - xassert(lp != lp); -done: return errcode; -} - -int CPXgetstat(CPXENV *env, CPXLP *lp) -{ int stat; - if (checklp(env, lp)) - stat = 0; - else - stat = lp->stat; - return stat; -} - -int CPXgetub(CPXENV *env, CPXLP *lp, double ub[], int begin, int end) -{ xassert(env == env); - xassert(lp == lp); - xassert(ub == ub); - xassert(begin == begin); - xassert(end == end); - xprintf("CPXgetub: not implemented yet\n"); - exit(EXIT_FAILURE); - return -1; -} - -int CPXgetweight(CPXENV *env, CPXLP *lp, int rcnt, const int rmatbeg[], - const int rmatind[], const double rmatval[], double weight[], - int dpriind) -{ xassert(env == env); - xassert(lp == lp); - xassert(rcnt == rcnt); - xassert(rmatbeg == rmatbeg); - xassert(rmatind == rmatind); - xassert(rmatval == rmatval); - xassert(weight == weight); - xassert(dpriind == dpriind); - xprintf("CPXgetweight: not implemented yet\n"); - exit(EXIT_FAILURE); - return -1; -} - -int CPXgetx(CPXENV *env, CPXLP *lp, double x[], int begin, int end) -{ int j, n, errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - n = glp_get_num_cols(lp->prob); - if (!(0 <= begin && begin <= end && end < n)) - { errcode = error(env, CPXERR_INDEX_RANGE); - goto done; - } - if (!lp->stat) - { errcode = error(env, CPXERR_NO_SOLN); - goto done; - } - errcode = 0; - if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) - { if (x != NULL) - { for (j = begin; j <= end; j++) - x[j-begin] = glp_get_col_prim(lp->prob, j+1); - } - } - else - xassert(lp != lp); -done: return errcode; -} - -int CPXinfodblparam(CPXENV *env, int whichparam, double *defvalue, - double *minvalue, double *maxvalue) -{ int k, errcode; - errcode = checkenv(env); - if (errcode) goto done; - k = finddblparam(whichparam); - if (k < 0) - { errcode = error(env, CPXERR_BAD_PARAM_NUM); - goto done; - } - errcode = 0; - if (defvalue != NULL) - *defvalue = dblparam[k].defv; - if (minvalue != NULL) - *minvalue = dblparam[k].minv; - if (maxvalue != NULL) - *maxvalue = dblparam[k].maxv; -done: return errcode; -} - -int CPXinfointparam(CPXENV *env, int whichparam, int *defvalue, - int *minvalue, int *maxvalue) -{ int k, errcode; - errcode = checkenv(env); - if (errcode) goto done; - k = findintparam(whichparam); - if (k < 0) - { errcode = error(env, CPXERR_BAD_PARAM_NUM); - goto done; - } - errcode = 0; - if (defvalue != NULL) - *defvalue = intparam[k].defv; - if (minvalue != NULL) - *minvalue = intparam[k].minv; - if (maxvalue != NULL) - *maxvalue = intparam[k].maxv; -done: return errcode; -} - -int CPXmdleave(const CPXENV *env, CPXLP *lp, const int goodlist[], - int goodlen, double downratio[], double upratio[]) -{ int k; - xassert(env == env); - xassert(lp == lp); - xassert(goodlist == goodlist); - xassert(goodlen >= 0); - xassert(downratio != NULL); - xassert(upratio != NULL); - /* not implemented yet */ - for (k = 0; k < goodlen; k++) - downratio[k] = upratio[k] = 0.0; - return 0; -} - -int CPXnewcols(CPXENV *env, CPXLP *lp, int ccnt, const double obj[], - const double lb[], const double ub[], const char ctype[], - char *colname[]) -{ int j, n, kind, type, errcode; - double lbnd, ubnd; - errcode = checklp(env, lp); - if (errcode) goto done; - if (ccnt < 0) - { errcode = error(env, CPXERR_BAD_ARGUMENT); - goto done; - } - for (j = 0; j < ccnt; j++) - { if (ctype != NULL) - { if (!(ctype[j] == 'C' || ctype[j] == 'B' || - ctype[j] == 'I')) - { errcode = error(env, CPXERR_BAD_CTYPE, j); - goto done; - } - } - if (colname != NULL) - { if (colname[j] == NULL) - { errcode = error(env, CPXERR_NULL_NAME, j); - goto done; - } - } - } - errcode = 0; - invalidate(lp); - n = glp_get_num_cols(lp->prob); - if (ccnt > 0) - glp_add_cols(lp->prob, ccnt); - for (j = 0; j < ccnt; j++) - { if (colname != NULL) - glp_set_col_name(lp->prob, n+j+1, colname[j]); - if (obj != NULL) - glp_set_obj_coef(lp->prob, n+j+1, obj[j]); - lbnd = (lb == NULL ? 0.0 : lb[j]); - ubnd = (ub == NULL ? 0.0 : ub[j]); - if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) - type = GLP_FR; - else if (ubnd >= +CPX_INFBOUND) - type = GLP_LO; - else if (lbnd <= -CPX_INFBOUND) - type = GLP_UP; - else if (lbnd != ubnd) - type = GLP_DB; - else - type = GLP_FX; - glp_set_col_bnds(lp->prob, n+j+1, type, lbnd, ubnd); - if (ctype != NULL) - { if (ctype[j] == 'C') - kind = GLP_CV; - else if (ctype[j] == 'B') - kind = GLP_BV; - else if (ctype[j] == 'I') - kind = GLP_IV; - else - xassert(ctype != ctype); - glp_set_col_kind(lp->prob, n+j+1, kind); - } - } -done: return errcode; -} - -int CPXnewrows(CPXENV *env, CPXLP *lp, int rcnt, const double rhs[], - const char sense[], const double rngval[], char *rowname[]) -{ int i, m, type, errcode; - double lbnd, ubnd; - errcode = checklp(env, lp); - if (errcode) goto done; - if (rcnt < 0) - { errcode = error(env, CPXERR_BAD_ARGUMENT); - goto done; - } - for (i = 0; i < rcnt; i++) - { if (sense != NULL) - { if (!(sense[i] == 'L' || sense[i] == 'E' || - sense[i] == 'G' || sense[i] == 'R')) - { errcode = error(env, CPXERR_BAD_SENSE, i); - goto done; - } - } - if (rowname != NULL) - { if (rowname[i] == NULL) - { errcode = error(env, CPXERR_NULL_NAME, i); - goto done; - } - } - } - errcode = 0; - invalidate(lp); - m = glp_get_num_rows(lp->prob); - if (rcnt > 0) - glp_add_rows(lp->prob, rcnt); - enlargerflag(lp); - for (i = 0; i < rcnt; i++) - { if (rowname != NULL) - glp_set_row_name(lp->prob, m+i+1, rowname[i]); - lbnd = ubnd = (rhs == NULL ? 0.0 : rhs[i]); - if (sense == NULL || sense[i] == 'E') - { lp->rflag[m+i] = RF_NOT_RANGED; - type = GLP_FX; - } - else if (sense[i] == 'L') - { lp->rflag[m+i] = RF_NOT_RANGED; - type = GLP_UP; - } - else if (sense[i] == 'G') - { lp->rflag[m+i] = RF_NOT_RANGED; - type = GLP_LO; - } - else if (sense[i] == 'R') - { if (rngval == NULL || rngval[i] == 0.0) - { lp->rflag[m+i] = RF_RANGED_POS; - type = GLP_FX; - } - else if (rngval[i] > 0.0) - { lp->rflag[m+i] = RF_RANGED_POS; - type = GLP_DB; - ubnd += rngval[i]; - } - else /* rngval[i] < 0.0 */ - { lp->rflag[m+i] = RF_RANGED_NEG; - type = GLP_DB; - lbnd += rngval[i]; - } - } - else - xassert(sense != sense); - glp_set_row_bnds(lp->prob, m+i+1, type, lbnd, ubnd); - } -done: return errcode; -} - -CPXENV *CPXopenCPLEX(int *status) -{ CPXENV *env; - int k, card; - env = xmalloc(sizeof(CPXENV)); - env->list = NULL; - card = sizeof(intparam) / sizeof(struct intparam); - env->intparam = xcalloc(card, sizeof(int)); - for (k = 0; k < card; k++) - env->intparam[k] = intparam[k].defv; - card = sizeof(dblparam) / sizeof(struct dblparam); - env->dblparam = xcalloc(card, sizeof(double)); - for (k = 0; k < card; k++) - env->dblparam[k] = dblparam[k].defv; - if (status != NULL) *status = 0; - return env; -} - -int CPXpivotin(CPXENV *env, CPXLP *lp, const int rlist[], int rlen) -{ int i, m, errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - if (rlen < 0) - { errcode = error(env, CPXERR_BAD_ARGUMENT); - goto done; - } - if (rlen > 0 && rlist == NULL) - { errcode = error(env, CPXERR_NULL_POINTER); - goto done; - } - m = glp_get_num_rows(lp->prob); - for (i = 0; i < rlen; i++) - { if (!(0 <= rlist[i] && rlist[i] < m)) - { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i); - goto done; - } - } - errcode = 0; - for (i = 0; i < rlen; i++) - { if (glp_get_row_type(lp->prob, rlist[i]+1) != GLP_FX) - { if (glp_get_row_stat(lp->prob, rlist[i]+1) != GLP_BS) - { /* not implemented yet */ - break; - } - } - } -done: return errcode; -} - -int CPXpivotout(CPXENV *env, CPXLP *lp, const int clist[], int clen) -{ int j, n, errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - if (clen < 0) - { errcode = error(env, CPXERR_BAD_ARGUMENT); - goto done; - } - if (clen > 0 && clist == NULL) - { errcode = error(env, CPXERR_NULL_POINTER); - goto done; - } - n = glp_get_num_cols(lp->prob); - for (j = 0; j < clen; j++) - { if (!(0 <= clist[j] && clist[j] < n)) - { errcode = error(env, CPXERR_COL_INDEX_RANGE, j); - goto done; - } - if (glp_get_col_type(lp->prob, clist[j]+1) != GLP_FX) - { errcode = error(env, CPXERR_NOT_FIXED); - goto done; - } - } - errcode = 0; - for (j = 0; j < clen; j++) - { if (glp_get_col_stat(lp->prob, clist[j]+1) == GLP_BS) - { /* not implemented yet */ - break; - } - } -done: return errcode; -} - -int CPXprimopt(CPXENV *env, CPXLP *lp); - -int CPXsavwrite(CPXENV *env, CPXLP *lp, const char *filename) -{ xassert(env == env); - xassert(lp == lp); - xassert(filename == filename); - xprintf("CPXsavwrite: not implemented yet\n"); - exit(EXIT_FAILURE); - return -1; -} - -int CPXsetdblparam(CPXENV *env, int whichparam, double newvalue) -{ int k, errcode; - errcode = checkenv(env); - if (errcode) goto done; - k = finddblparam(whichparam); - if (k < 0) - { errcode = error(env, CPXERR_BAD_PARAM_NUM); - goto done; - } - if (newvalue < dblparam[k].minv) - { errcode = error(env, CPXERR_PARAM_TOO_SMALL); - goto done; - } - if (newvalue > dblparam[k].maxv) - { errcode = error(env, CPXERR_PARAM_TOO_BIG); - goto done; - } - errcode = 0; - env->dblparam[k] = newvalue; -done: return errcode; -} - -int CPXsetintparam(CPXENV *env, int whichparam, int newvalue) -{ int k, errcode; - errcode = checkenv(env); - if (errcode) goto done; - k = findintparam(whichparam); - if (k < 0) - { errcode = error(env, CPXERR_BAD_PARAM_NUM); - goto done; - } - if (newvalue < intparam[k].minv) - { errcode = error(env, CPXERR_PARAM_TOO_SMALL); - goto done; - } - if (newvalue > intparam[k].maxv) - { errcode = error(env, CPXERR_PARAM_TOO_BIG); - goto done; - } - errcode = 0; - env->intparam[k] = newvalue; -done: return errcode; -} - -int CPXsolninfo(CPXENV *env, CPXLP *lp, int *solnmethod, int *solntype, - int *pfeasind, int *dfeasind) -{ int type, pfeas, dfeas, errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - errcode = 0; - if (!lp->stat) - type = CPX_NO_SOLN, pfeas = dfeas = 0; - else if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) - { type = CPX_BASIC_SOLN; - pfeas = (glp_get_prim_stat(lp->prob) == GLP_FEAS); - dfeas = (glp_get_dual_stat(lp->prob) == GLP_FEAS); - } - else - xassert(lp != lp); - if (solnmethod != NULL) - *solnmethod = lp->meth; - if (solntype != NULL) - *solntype = type; - if (pfeasind != NULL) - *pfeasind = pfeas; - if (dfeasind != NULL) - *dfeasind = dfeas; -done: return errcode; -} - -int CPXsolution(CPXENV *env, CPXLP *lp, int *lpstat, double *objval, - double x[], double pi[], double slack[], double dj[]) -{ int m, n, errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - if (!lp->stat) - { errcode = error(env, CPXERR_NO_SOLN); - goto done; - } - errcode = 0; - m = glp_get_num_rows(lp->prob); - n = glp_get_num_cols(lp->prob); - if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) - { if (lpstat != NULL) - *lpstat = CPXgetstat(env, lp); - if (objval != NULL) - xassert(CPXgetobjval(env, lp, objval) == 0); - if (x != NULL) - xassert(CPXgetx(env, lp, x, 0, n-1) == 0); - if (pi != NULL) - xassert(CPXgetpi(env, lp, pi, 0, m-1) == 0); - if (slack != NULL) - xassert(CPXgetslack(env, lp, slack, 0, m-1) == 0); - if (dj != NULL) - xassert(CPXgetdj(env, lp, dj, 0, n-1) == 0); - } - else - xassert(lp != lp); -done: return errcode; -} - -int CPXstrongbranch(CPXENV *env, CPXLP *lp, const int goodlist[], - int goodlen, double downpen[], double uppen[], int itlim) -{ int k; - xassert(env == env); - xassert(lp == lp); - xassert(goodlist == goodlist); - xassert(goodlen >= 0); - xassert(downpen != NULL); - xassert(uppen != NULL); - xassert(itlim == itlim); - /* not implemented yet */ - for (k = 0; k < goodlen; k++) - downpen[k] = uppen[k] = 0.0; - return 0; -} - -static int xstrcasecmp(const char *s1, const char *s2) -{ int c1, c2; - for (;;) - { c1 = toupper((unsigned char)*s1++); - c2 = toupper((unsigned char)*s2++); - if (c1 == '\0' || c1 != c2) break; - } - return c1 - c2; -} - -static void getfiletype(const char *filename, char type[3+1]) -{ /* determine filetype from filename */ - int beg, end; - beg = end = strlen(filename); - while (beg > 0 && filename[beg-1] != '.' && end - beg < 3) - beg--; - if (beg > 0 && filename[beg-1] == '.' && - xstrcasecmp(&filename[beg], "gz") == 0) - { end = --beg; - while (beg > 0 && filename[beg-1] != '.' && end - beg < 3) - beg--; - } - if (beg > 0 && filename[beg-1] == '.') - { memcpy(type, &filename[beg], end - beg); - type[end - beg] = '\0'; - } - else - type[0] = '\0'; - return; -} - -int CPXwriteprob(CPXENV *env, CPXLP *lp, const char *filename, - const char *filetype) -{ glp_prob *copy; - int errcode; - char type[3+1]; - errcode = checklp(env, lp); - if (errcode) goto done; - if (filename == NULL) - { errcode = error(env, CPXERR_NO_FILENAME); - goto done; - } - if (filetype == NULL) - getfiletype(filename, type), filetype = type; - if (xstrcasecmp(filetype, "MPS") == 0) - { glp_term_out(GLP_OFF); - errcode = glp_write_mps(lp->prob, GLP_MPS_FILE, NULL, filename) - ; - glp_term_out(GLP_ON); - } - else if (xstrcasecmp(filetype, "LP") == 0) - { glp_term_out(GLP_OFF); - errcode = glp_write_lp(lp->prob, NULL, filename); - glp_term_out(GLP_ON); - } - else if (xstrcasecmp(filetype, "RMP") == 0 || - xstrcasecmp(filetype, "REW") == 0) - { copy = glp_create_prob(); - glp_copy_prob(copy, lp->prob, GLP_OFF); - glp_term_out(GLP_OFF); - errcode = glp_write_mps(copy, GLP_MPS_DECK, NULL, filename); - glp_term_out(GLP_ON); - glp_delete_prob(copy); - } - else if (xstrcasecmp(filetype, "RLP") == 0) - { copy = glp_create_prob(); - glp_copy_prob(copy, lp->prob, GLP_OFF); - glp_term_out(GLP_OFF); - errcode = glp_write_lp(copy, NULL, filename); - glp_term_out(GLP_ON); - glp_delete_prob(copy); - } - else - { errcode = error(env, CPXERR_BAD_FILETYPE); - goto done; - } - if (errcode) - errcode = error(env, CPXERR_FAIL_OPEN_WRITE, filename); -done: return errcode; -} - -/**********************************************************************/ - -static int solvelp(CPXENV *env, CPXLP *lp, int meth) -{ glp_smcp parm; - int errcode; - errcode = checklp(env, lp); - if (errcode) goto done; - errcode = 0; - invalidate(lp); - glp_init_smcp(&parm); - switch (meth) - { case CPX_ALG_PRIMAL: - parm.meth = GLP_PRIMAL; - break; - case CPX_ALG_DUAL: - parm.meth = GLP_DUAL; - break; - default: - xassert(meth != meth); - } - switch (getintparam(env, CPX_PARAM_SIMDISPLAY)) - { case 0: - parm.msg_lev = GLP_MSG_OFF; - break; - case 1: - parm.msg_lev = GLP_MSG_ALL; - break; - case 2: - parm.msg_lev = GLP_MSG_ALL; - parm.out_frq = 1; - break; - default: - xassert(env != env); - } - xassert(getdblparam == getdblparam); - switch (getintparam(env, CPX_PARAM_ADVIND)) - { case 0: - glp_term_out(GLP_OFF); - glp_adv_basis(lp->prob, 0); - glp_term_out(GLP_ON); - break; - case 1: - case 2: - break; - default: - xassert(env != env); - } - if (!glp_bf_exists(lp->prob)) - { if (glp_factorize(lp->prob) != 0) - { glp_term_out(GLP_OFF); - glp_adv_basis(lp->prob, 0); - glp_term_out(GLP_ON); - if (glp_factorize(lp->prob) != 0) - glp_std_basis(lp->prob); - } - } - xassert(glp_simplex(lp->prob, &parm) == 0); - switch (glp_get_status(lp->prob)) - { case GLP_OPT: - lp->stat = CPX_STAT_OPTIMAL; - lp->meth = meth; - break; - case GLP_NOFEAS: - lp->stat = CPX_STAT_INFEASIBLE; - lp->meth = meth; - break; - case GLP_UNBND: - lp->stat = CPX_STAT_UNBOUNDED; - lp->meth = meth; - break; - default: - xassert(lp != lp); - } -done: return errcode; -} - -int CPXprimopt(CPXENV *env, CPXLP *lp) -{ int errcode; - errcode = solvelp(env, lp, CPX_ALG_PRIMAL); - return errcode; -} - -int CPXdualopt(CPXENV *env, CPXLP *lp) -{ int errcode; - errcode = solvelp(env, lp, CPX_ALG_DUAL); - return errcode; -} - -int CPXlpopt(CPXENV *env, CPXLP *lp) -{ int errcode; - errcode = solvelp(env, lp, CPX_ALG_PRIMAL); - return errcode; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/examples/cplex/cplex.h b/resources/3rdparty/glpk-4.53/examples/cplex/cplex.h deleted file mode 100644 index 94c3b204c..000000000 --- a/resources/3rdparty/glpk-4.53/examples/cplex/cplex.h +++ /dev/null @@ -1,301 +0,0 @@ -/* cplex.h (CPLEX-like interface to GLPK API) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef _CPLEX_H -#define _CPLEX_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct CPXENV CPXENV, *CPXENVptr; -typedef struct CPXLP CPXLP, *CPXLPptr; - -#define CPX_VERSION 900 - -#define CPX_OFF 0 -#define CPX_ON 1 - -#define CPX_INFBOUND 1e20 - -/* error codes: */ -#define CPXERR_NO_MEMORY 1001 -#define CPXERR_NO_ENVIRONMENT 1002 -#define CPXERR_BAD_ARGUMENT 1003 -#define CPXERR_NULL_POINTER 1004 -#define CPXERR_NO_PROBLEM 1009 -#define CPXERR_BAD_PARAM_NUM 1013 -#define CPXERR_PARAM_TOO_SMALL 1014 -#define CPXERR_PARAM_TOO_BIG 1015 -#define CPXERR_INDEX_RANGE 1200 -#define CPXERR_COL_INDEX_RANGE 1201 -#define CPXERR_ROW_INDEX_RANGE 1203 -#define CPXERR_NEGATIVE_SURPLUS 1207 -#define CPXERR_BAD_SENSE 1215 -#define CPXERR_NO_SOLN 1217 -#define CPXERR_NOT_FIXED 1221 -#define CPXERR_DUP_ENTRY 1222 -#define CPXERR_NULL_NAME 1224 -#define CPXERR_ARRAY_NOT_ASCENDING 1226 -#define CPXERR_COUNT_RANGE 1227 -#define CPXERR_BAD_LUB 1229 -#define CPXERR_BAD_STATUS 1253 -#define CPXERR_NO_BASIC_SOLN 1261 -#define CPXERR_NO_FILENAME 1421 -#define CPXERR_FAIL_OPEN_WRITE 1422 -#define CPXERR_BAD_FILETYPE 1424 -#define CPXERR_BAD_CTYPE 3021 - -/* control parameters: */ -#define CPX_PARAM_ADVIND 1001 -#define CPX_PARAM_AGGIND 1003 -#define CPX_PARAM_DPRIIND 1009 -#define CPX_PARAM_EPOPT 1014 -#define CPX_PARAM_EPPER 1015 -#define CPX_PARAM_EPRHS 1016 -#define CPX_PARAM_FASTMIP 1017 /* ??? */ -#define CPX_PARAM_SIMDISPLAY 1019 -#define CPX_PARAM_ITLIM 1020 -#define CPX_PARAM_OBJLLIM 1025 -#define CPX_PARAM_OBJULIM 1026 -#define CPX_PARAM_PERIND 1027 -#define CPX_PARAM_PPRIIND 1029 -#define CPX_PARAM_PREIND 1030 -#define CPX_PARAM_REINV 1031 -#define CPX_PARAM_SCRIND 1035 -#define CPX_PARAM_DATACHECK 1056 - -/* CPX_PARAM_DPRIIND: */ -#define CPX_DPRIIND_AUTO 0 -#define CPX_DPRIIND_FULL 1 -#define CPX_DPRIIND_STEEP 2 -#define CPX_DPRIIND_FULL_STEEP 3 -#define CPX_DPRIIND_STEEPQSTART 4 -#define CPX_DPRIIND_DEVEX 5 - -/* CPX_PARAM_PPRIIND: */ -#define CPX_PPRIIND_PARTIAL (-1) -#define CPX_PPRIIND_AUTO 0 -#define CPX_PPRIIND_DEVEX 1 -#define CPX_PPRIIND_STEEP 2 -#define CPX_PPRIIND_STEEPQSTART 3 -#define CPX_PPRIIND_FULL 4 - -/* CPXgetprobtype: */ -#define CPXPROB_LP 0 -#define CPXPROB_MIP 1 -#define CPXPROB_RELAXED 2 -#define CPXPROB_FIXED 3 -#define CPXPROB_QP 5 -#define CPXPROB_ZEROEDQP 6 - -/* CPXgetobjsen: */ -#define CPX_MIN 1 -#define CPX_MAX (-1) - -/* CPXgetbase: */ -#define CPX_AT_LOWER 0 -#define CPX_BASIC 1 -#define CPX_AT_UPPER 2 -#define CPX_FREE_SUPER 3 - -/* CPXgetstat: */ -#define CPX_STAT_OPTIMAL 1 -#define CPX_STAT_UNBOUNDED 2 -#define CPX_STAT_INFEASIBLE 3 -#define CPX_STAT_INForUNBD 4 -#define CPX_STAT_OPTIMAL_INFEAS 5 -#define CPX_STAT_ABORT_IT_LIM 10 -#define CPX_STAT_ABORT_OBJ_LIM 12 - -/* CPXgetmethod: */ -#define CPX_ALG_NONE 0 -#define CPX_ALG_PRIMAL 1 -#define CPX_ALG_DUAL 2 -#define CPX_ALG_BARRIER 4 - -/* CPXsolninfo: */ -#define CPX_NO_SOLN 0 -#define CPX_BASIC_SOLN 1 -#define CPX_NONBASIC_SOLN 2 -#define CPX_PRIMAL_SOLN 3 - -int CPXaddcols(CPXENV *env, CPXLP *lp, int ccnt, int nzcnt, - const double obj[], const int cmatbeg[], const int cmatind[], - const double cmatval[], const double lb[], const double ub[], - char *colname[]); - -int CPXaddrows(CPXENV *env, CPXLP *lp, int ccnt, int rcnt, int nzcnt, - const double rhs[], const char sense[], const int rmatbeg[], - const int rmatind[], const double rmatval[], char *colname[], - char *rowname[]); - -int CPXbaropt(CPXENV *env, CPXLP *lp); - -int CPXbinvrow(CPXENV *env, CPXLP *lp, int i, double y[]); - -int CPXchgbds(CPXENV *env, CPXLP *lp, int cnt, const int indices[], - const char lu[], const double bd[]); - -int CPXchgcoeflist(CPXENV *env, CPXLP *lp, int numcoefs, - const int rowlist[], const int collist[], const double vallist[]); - -void CPXchgobjsen(CPXENV *env, CPXLP *lp, int maxormin); - -int CPXchgsense(CPXENV *env, CPXLP *lp, int cnt, const int indices[], - const char sense[]); - -int CPXcloseCPLEX(CPXENV **env); - -int CPXcopybase(CPXENV *env, CPXLP *lp, const int cstat[], - const int rstat[]); - -int CPXcopybasednorms(CPXENV *env, CPXLP *lp, const int cstat[], - const int rstat[], const double dnorm[]); - -int CPXcopylp(CPXENV *env, CPXLP *lp, int numcols, int numrows, - int objsen, const double obj[], const double rhs[], - const char sense[], const int matbeg[], const int matcnt[], - const int matind[], const double matval[], const double lb[], - const double ub[], const double rngval[]); - -int CPXcopylpwnames(CPXENV *env, CPXLP *lp, int numcols, int numrows, - int objsen, const double obj[], const double rhs[], - const char sense[], const int matbeg[], const int matcnt[], - const int matind[], const double matval[], const double lb[], - const double ub[], const double rngval[], char *colname[], - char *rowname[]); - -CPXLP *CPXcreateprob(CPXENV *env, int *status, const char *probname); - -int CPXdelcols(CPXENV *env, CPXLP *lp, int begin, int end); - -int CPXdelrows(CPXENV *env, CPXLP *lp, int begin, int end); - -int CPXdelsetcols(CPXENV *env, CPXLP *lp, int delstat[]); - -int CPXdelsetrows(CPXENV *env, CPXLP *lp, int delstat[]); - -int CPXdualopt(CPXENV *env, CPXLP *lp); - -int CPXfreeprob(CPXENV *env, CPXLP **lp); - -int CPXgetbase(CPXENV *env, CPXLP *lp, int cstat[], int rstat[]); - -int CPXgetbasednorms(CPXENV *env, CPXLP *lp, int cstat[], int rstat[], - double dnorm[]); - -int CPXgetbhead(CPXENV *env, CPXLP *lp, int head[], double x[]); - -int CPXgetdblparam(CPXENV *env, int whichparam, double *value); - -int CPXgetdj(CPXENV *env, CPXLP *lp, double dj[], int begin, int end); - -char *CPXgeterrorstring(CPXENV *env, int errcode, char *buffer); - -int CPXgetijdiv(CPXENV *env, CPXLP *lp, int *idiv, int *jdiv); - -int CPXgetintparam(CPXENV *env, int whichparam, int *value); - -int CPXgetlb(CPXENV *env, CPXLP *lp, double lb[], int begin, int end); - -int CPXgetmethod(CPXENV *env, CPXLP *lp); - -int CPXgetnumcols(CPXENV *env, CPXLP *lp); - -int CPXgetnumnz(CPXENV *env, CPXLP *lp); - -int CPXgetnumrows(CPXENV *env, CPXLP *lp); - -int CPXgetobjval(CPXENV *env, CPXLP *lp, double *objval); - -int CPXgetpi(CPXENV *env, CPXLP *lp, double pi[], int begin, int end); - -int CPXgetsense(CPXENV *env, CPXLP *lp, char sense[], int begin, - int end); - -int CPXgetslack(CPXENV *env, CPXLP *lp, double slack[], int begin, - int end); - -int CPXgetstat(CPXENV *env, CPXLP *lp); - -int CPXgetub(CPXENV *env, CPXLP *lp, double ub[], int begin, int end); - -int CPXgetweight(CPXENV *env, CPXLP *lp, int rcnt, const int rmatbeg[], - const int rmatind[], const double rmatval[], double weight[], - int dpriind); - -int CPXgetx(CPXENV *env, CPXLP *lp, double x[], int begin, int end); - -int CPXinfodblparam(CPXENV *env, int whichparam, double *defvalue, - double *minvalue, double *maxvalue); - -int CPXinfointparam(CPXENV *env, int whichparam, int *defvalue, - int *minvalue, int *maxvalue); - -int CPXlpopt(CPXENV *env, CPXLP *lp); - -int CPXmdleave(const CPXENV *env, CPXLP *lp, const int goodlist[], - int goodlen, double downratio[], double upratio[]); - -int CPXnewcols(CPXENV *env, CPXLP *lp, int ccnt, const double obj[], - const double lb[], const double ub[], const char ctype[], - char *colname[]); - -int CPXnewrows(CPXENV *env, CPXLP *lp, int rcnt, const double rhs[], - const char sense[], const double rngval[], char *rowname[]); - -CPXENV *CPXopenCPLEX(int *status); - -int CPXpivotin(CPXENV *env, CPXLP *lp, const int rlist[], int rlen); - -int CPXpivotout(CPXENV *env, CPXLP *lp, const int clist[], int clen); - -int CPXprimopt(CPXENV *env, CPXLP *lp); - -int CPXsavwrite(CPXENV *env, CPXLP *lp, const char *filename); - -int CPXsetdblparam(CPXENV *env, int whichparam, double newvalue); - -int CPXsetintparam(CPXENV *env, int whichparam, int newvalue); - -int CPXsolninfo(CPXENV *env, CPXLP *lp, int *solnmethod, int *solntype, - int *pfeasind, int *dfeasind); - -int CPXsolution(CPXENV *env, CPXLP *lp, int *lpstat, double *objval, - double x[], double pi[], double slack[], double dj[]); - -int CPXstrongbranch(CPXENV *env, CPXLP *lp, const int goodlist[], - int goodlen, double downpen[], double uppen[], int itlim); - -int CPXwriteprob(CPXENV *env, CPXLP *lp, const char *filename, - const char *filetype); - -#ifdef __cplusplus -} -#endif - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/examples/cpp.mod b/resources/3rdparty/glpk-4.53/examples/cpp.mod deleted file mode 100644 index af3f1208b..000000000 --- a/resources/3rdparty/glpk-4.53/examples/cpp.mod +++ /dev/null @@ -1,67 +0,0 @@ -/* CPP, Critical Path Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* Note: Reduced costs of auxiliary variables phi[j,k] (see below) - can be only zero or one. The critical path is defined by the - constraints, whose reduced cost is one. */ - -set J; -/* set of jobs (activities) */ - -set P{j in J}, in J, default {}; -/* P[j] is a subset of jobs that immediately precede job j */ - -param t{j in J}, >= 0; -/* duration required to perform job j */ - -var x{j in J}, >= 0; -/* starting time of job j */ - -s.t. phi{j in J, k in P[j]}: x[j] >= x[k] + t[k]; -/* job j can start only after all immediately preceding jobs have been - completely performed */ - -var z; -/* project makespan */ - -s.t. fin{j in J}: z >= x[j] + t[j]; -/* which is the maximum of the completion times of all the jobs */ - -minimize obj: z; -/* the objective is make z as small as possible */ - -data; - -/* The optimal solution is 46 */ - -param : J : t := - A 3 /* Excavate */ - B 4 /* Lay foundation */ - C 3 /* Rough plumbing */ - D 10 /* Frame */ - E 8 /* Finish exterior */ - F 4 /* Install HVAC */ - G 6 /* Rough electric */ - H 8 /* Sheet rock */ - I 5 /* Install cabinets */ - J 5 /* Paint */ - K 4 /* Final plumbing */ - L 2 /* Final electric */ - M 4 /* Install flooring */ -; - -set P[B] := A; -set P[C] := B; -set P[D] := B; -set P[E] := D; -set P[F] := D; -set P[G] := D; -set P[H] := C E F G; -set P[I] := H; -set P[J] := H; -set P[K] := I; -set P[L] := J; -set P[M] := K L; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/crypto.mod b/resources/3rdparty/glpk-4.53/examples/crypto.mod deleted file mode 100644 index bad50325f..000000000 --- a/resources/3rdparty/glpk-4.53/examples/crypto.mod +++ /dev/null @@ -1,84 +0,0 @@ -/* CRYPTO, a crypto-arithmetic puzzle */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* This problem comes from the newsgroup rec.puzzle. - The numbers from 1 to 26 are assigned to the letters of the alphabet. - The numbers beside each word are the total of the values assigned to - the letters in the word (e.g. for LYRE: L, Y, R, E might be to equal - 5, 9, 20 and 13, or any other combination that add up to 47). - Find the value of each letter under the equations: - - BALLET 45 GLEE 66 POLKA 59 SONG 61 - CELLO 43 JAZZ 58 QUARTET 50 SOPRANO 82 - CONCERT 74 LYRE 47 SAXOPHONE 134 THEME 72 - FLUTE 30 OBOE 53 SCALE 51 VIOLIN 100 - FUGUE 50 OPERA 65 SOLO 37 WALTZ 34 - - Solution: - A, B,C, D, E,F, G, H, I, J, K,L,M, N, O, P,Q, R, S,T,U, V,W, X, Y, Z - 5,13,9,16,20,4,24,21,25,17,23,2,8,12,10,19,7,11,15,3,1,26,6,22,14,18 - - Reference: - Koalog Constraint Solver , - Simple problems, the crypto-arithmetic puzzle ALPHACIPHER. */ - -set LETTERS := -{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' -}; -/* set of letters */ - -set VALUES := 1..card(LETTERS); -/* set of values assigned to the letters */ - -set WORDS; -/* set of words */ - -param total{word in WORDS}; -/* total[word] is the total of the values assigned to the letters in - the word */ - -var x{i in LETTERS, j in VALUES}, binary; -/* x[i,j] = 1 means that letter i is assigned value j */ - -s.t. phi{i in LETTERS}: sum{j in VALUES} x[i,j] = 1; - -s.t. psi{j in VALUES}: sum{i in LETTERS} x[i,j] = 1; - -s.t. eqn{word in WORDS}: sum{k in 1..length(word), j in VALUES} - j * x[substr(word,k,1), j] = total[word]; - -solve; - -printf{i in LETTERS} " %s", i; -printf "\n"; - -printf{i in LETTERS} " %2d", sum{j in VALUES} j * x[i,j]; -printf "\n"; - -data; - -param : WORDS : total := - BALLET 45 - CELLO 43 - CONCERT 74 - FLUTE 30 - FUGUE 50 - GLEE 66 - JAZZ 58 - LYRE 47 - OBOE 53 - OPERA 65 - POLKA 59 - QUARTET 50 - SAXOPHONE 134 - SCALE 51 - SOLO 37 - SONG 61 - SOPRANO 82 - THEME 72 - VIOLIN 100 - WALTZ 34 ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/csv/distances.csv b/resources/3rdparty/glpk-4.53/examples/csv/distances.csv deleted file mode 100644 index 8c7b419de..000000000 --- a/resources/3rdparty/glpk-4.53/examples/csv/distances.csv +++ /dev/null @@ -1,7 +0,0 @@ -plant,market,distance -"Seattle","New York",2.5 -"Seattle","Chicago",1.7 -"Seattle","Topeka",1.8 -"San Diego","New York",2.5 -"San Diego","Chicago",1.8 -"San Diego","Topeka",1.4 diff --git a/resources/3rdparty/glpk-4.53/examples/csv/markets.csv b/resources/3rdparty/glpk-4.53/examples/csv/markets.csv deleted file mode 100644 index d04dec82c..000000000 --- a/resources/3rdparty/glpk-4.53/examples/csv/markets.csv +++ /dev/null @@ -1,4 +0,0 @@ -market,demand -"New York",325. -"Chicago",300. -"Topeka",275. diff --git a/resources/3rdparty/glpk-4.53/examples/csv/parameters.csv b/resources/3rdparty/glpk-4.53/examples/csv/parameters.csv deleted file mode 100644 index c7c37e9af..000000000 --- a/resources/3rdparty/glpk-4.53/examples/csv/parameters.csv +++ /dev/null @@ -1,2 +0,0 @@ -parameter,value -"transport cost",90. diff --git a/resources/3rdparty/glpk-4.53/examples/csv/plants.csv b/resources/3rdparty/glpk-4.53/examples/csv/plants.csv deleted file mode 100644 index 292f45f12..000000000 --- a/resources/3rdparty/glpk-4.53/examples/csv/plants.csv +++ /dev/null @@ -1,3 +0,0 @@ -plant,capacity -"Seattle",350. -"San Diego",600. diff --git a/resources/3rdparty/glpk-4.53/examples/csv/transp_csv.mod b/resources/3rdparty/glpk-4.53/examples/csv/transp_csv.mod deleted file mode 100644 index d970bf61b..000000000 --- a/resources/3rdparty/glpk-4.53/examples/csv/transp_csv.mod +++ /dev/null @@ -1,70 +0,0 @@ -# A TRANSPORTATION PROBLEM -# -# This problem finds a least cost shipping schedule that meets -# requirements at markets and supplies at factories. -# -# References: -# Dantzig G B, "Linear Programming and Extensions." -# Princeton University Press, Princeton, New Jersey, 1963, -# Chapter 3-3. - -set I; -/* canning plants */ - -set J; -/* markets */ - -set K dimen 2; -/* transportation lane */ - -set L; -/* parameters */ - -param a{i in I}; -/* capacity of plant i in cases */ - -param b{j in J}; -/* demand at market j in cases */ - -param d{i in I, j in J}; -/* distance in thousands of miles */ - -param e{l in L}; -/* parameters */ - -param f; -/* freight in dollars per case per thousand miles */ - -table tab_plant IN "CSV" "plants.csv" : - I <- [plant], a ~ capacity; - -table tab_market IN "CSV" "markets.csv" : - J <- [market], b ~ demand; - -table tab_distance IN "CSV" "distances.csv" : - K <- [plant, market], d ~ distance; - -table tab_parameter IN "CSV" "parameters.csv" : - L <- [parameter], e ~ value ; - -param c{i in I, j in J} := e['transport cost'] * d[i,j] / 1000; -/* transport cost in thousands of dollars per case */ - -var x{(i,j) in K} >= 0; -/* shipment quantities in cases */ - -minimize cost: sum{(i,j) in K} c[i,j] * x[i,j]; -/* total transportation costs in thousands of dollars */ - -s.t. supply{i in I}: sum{(i,j) in K} x[i,j] <= a[i]; -/* observe supply limit at plant i */ - -s.t. demand{j in J}: sum{(i,j) in K} x[i,j] >= b[j]; -/* satisfy demand at market j */ - -solve; - -table tab_result{(i,j) in K} OUT "CSV" "result.csv" : - i ~ plant, j ~ market, x[i,j] ~ shipment; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/dbf/ForestMgt_Model_I_GIS_dbf.mod b/resources/3rdparty/glpk-4.53/examples/dbf/ForestMgt_Model_I_GIS_dbf.mod deleted file mode 100644 index 204846763..000000000 --- a/resources/3rdparty/glpk-4.53/examples/dbf/ForestMgt_Model_I_GIS_dbf.mod +++ /dev/null @@ -1,226 +0,0 @@ -# Model I Forest Estate Modelling using GLPK/MathProg -# Reading and writing dbf files - -# by Noli Sicad --- nsicad@gmail.com -# 18 December 2009 - -# Forest Management 4th Edition -# by Lawrence Davis, K. Norman Johnson, Pete Bettinger, Theodore Howard -# Chapter 11 - Daniel Pickett -# http://warnell.forestry.uga.edu/Warnell/Bettinger/mgtbook/index.htm - -# Model I Formulation - -/* Note: This is not the full LP model mentioned in the book. -Some of the constraints are deliberately omitted in this model for the purpose of clarity. - -The features of MathProg in this example are: -* reading and writing dbf from regular dbf files, -* reading dbf file (database of shapefile (stands.shp)) (e.g. area parameter), -* using the area data in the constraints and -* writing dbf file from result of LP model. - -Model I - Harvest Scheduling formulation for Sustainable Forest Management (SFM) - -Features are: -* Net Present Value for the objective function (Revenue - Cost) -* Harvest Constraints by period - Sustainable Yield per Period -* Even-Flow Constraint / Volume - Harvest Flow Constraint - Alpha (1-Apha) -* Even-Flow Constraint / Volume - Harvest Flow Constraint - Beta (1 +Beta) -* Forest / Land Constraint -- Total Area of the forest -* Forest Stand Constraint -- Individual stands - -What is next? -- Forest Mgt Carbon Accounting for Climate Change - -Note: The model file that the data containing in -the dbf files is public domain material (so it is compatible with the -GNU GPL) and data can be found in -http://warnell.forestry.uga.edu/Warnell/Bettinger/mgtbook/index.htm - -# Noli Sicad --- nsicad@gmail.com - -*/ - -set G_STAND_TYPE; # A, B, C - -set I_CULTURAL_PRES; -set J_MGT_YEAR; - -param K_PERIOD; -param Forest_Cost{G_STAND_TYPE,I_CULTURAL_PRES, J_MGT_YEAR}; # cost - -param Yield_Table_Vol{G_STAND_TYPE, I_CULTURAL_PRES, J_MGT_YEAR, 1..K_PERIOD} >= 0; - - -param Alpha >= 0; -param Beta >= 0; - -param TCost_Table{G_STAND_TYPE, I_CULTURAL_PRES, J_MGT_YEAR, 1..K_PERIOD} >= 0; - -param NetRev_Table{G_STAND_TYPE, I_CULTURAL_PRES, J_MGT_YEAR, 1..K_PERIOD}; - - -var XForestLand{g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} >= 0; - - -#reading dbf tables -table tab IN "xBASE" "standtype.dbf": G_STAND_TYPE <- [STAND]; -display G_STAND_TYPE; - - -table tab2 IN "xBASE" "cultural_pres.dbf": I_CULTURAL_PRES <- [CUL_PRES]; -display I_CULTURAL_PRES; - -table tab3 IN "xBASE" "mgt_year.dbf": J_MGT_YEAR <- [MGT_YEAR]; -display J_MGT_YEAR; - -/* -param Forest_Cost{G_STAND_TYPE,I_CULTURAL_PRES, J_MGT_YEAR} default 0; # cost -*/ - -set S1, dimen 3; -table tab4 IN "xBASE" "Forest_Cost.dbf": S1 <- [STAND, CUL_PRES, MGT_YEAR],Forest_Cost ~FCOST; -display Forest_Cost; - -set S2, dimen 4; -table tab5 IN "xBASE" "Yield_Table_Vol.dbf": S2 <- [STAND, CUL_PRES, MGT_YEAR, PERIOD],Yield_Table_Vol ~YIELD; -display Yield_Table_Vol; - -set S3, dimen 4; -table tab5 IN "xBASE" "TCost_Table.dbf": S3 <- [STAND, CUL_PRES, MGT_YEAR, PERIOD],TCost_Table ~TCOST; -display TCost_Table; - - -set S4, dimen 4; -table tab5 IN "xBASE" "NetRev_Table.dbf": S4 <- [STAND, CUL_PRES, MGT_YEAR, PERIOD],NetRev_Table ~NETREV; -display NetRev_Table; - - -param MGT; - -param Area_Stand_Indi{g in G_STAND_TYPE, m in 1..MGT} default 0; - -set ST, dimen 2; -table tab5 IN "xBASE" "stands.dbf": ST <- [VEG_TYPE, MGT], Area_Stand_Indi ~ACRES; -display Area_Stand_Indi; - -param Area_Stand_Type{g in G_STAND_TYPE}:= sum {m in 1..MGT } Area_Stand_Indi[g,m]; -display Area_Stand_Type; - - -param Total_Area := sum {g in G_STAND_TYPE, m in 1..MGT } Area_Stand_Indi[g,m]; -display Total_Area; - -param Harvest_Min_Vol_Period; - - -var NetPresentValue; - -# Objective function -maximize Net_Present_Value: NetPresentValue; - -subject to NPV: - NetPresentValue = sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Forest_Cost[g,i,j] * XForestLand[g,i,j]; - -# Harvest Constraint by Period -subject to Harvest_Period_H {k in 1..K_PERIOD}: - sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] >= Harvest_Min_Vol_Period; - - -#Even-Flow Constraint / Volume - Harvest Flow Constraint - Alpha -subject to Even_Flow_Constaints_Alpha {k in 6..K_PERIOD-1}: - (1 - Alpha) * sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] - - sum {g in G_STAND_TYPE,i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k+1] * XForestLand[g,i,j] <= 0; - -# Even-Flow Constraint / Volume - Harvest Flow Constraint - Beta -subject to Even_Flow_Constaints_Beta {k in 6..K_PERIOD-1}: - (1 + Beta) * sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] - - sum {g in G_STAND_TYPE,i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k+1] * XForestLand[g,i,j] >= 0; - -# Forest / Land Constraints -subject to Total_Area_Constraint: - sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} XForestLand[g,i,j] <= Total_Area; -display Total_Area; - -# Forest / Land Constraints for A B C -subject to Area {g in G_STAND_TYPE}: - sum {i in I_CULTURAL_PRES,j in J_MGT_YEAR} XForestLand[g,i,j] = Area_Stand_Type[g]; - - - -solve; -#RESULT SECTION -printf '#################################\n'; -printf 'Forest Management Model I - Noli Sicad\n'; -printf '\n'; -printf 'Net Present Value = %.2f\n', NetPresentValue; -printf '\n'; - -printf '\n'; -printf 'Variables\n'; -printf 'Stand_Type Age_Class Mgt_Presc Sign Value \n'; -printf{g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR}:'%5s %10s %11s = %10.2f\n', g,i,j, XForestLand[g,i,j]; -printf '\n'; - -printf 'Constraints\n'; -printf 'Period Harvest Sign \n'; -for {k in 1..K_PERIOD} { - printf '%5s %10.2f >= %.3f\n', k, sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j], Harvest_Min_Vol_Period; - } - -# xbase (dbf) output -table Harvest{k in 1..K_PERIOD} OUT "xBASE" "HarvestArea1.dbf" "N(5)N(15,2)" : k ~ Period, (sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j]) ~ H_Area; - -# xbase (dbf) read -set S, dimen 2; -table tab2 IN "xBASE" "HarvestArea1.dbf": S <- [Period, H_Area]; -display S; - - - - -printf '\n'; -printf 'Constraint\n'; -printf 'Harvest Period\n'; -printf 'Type AgeClass PrescMgt Period Value\n'; -printf{g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR, k in 1..K_PERIOD}:'%5s %11s %11s %5s %10.2f\n', g,i,j, k, (Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j]); - - -printf 'Even_Flow_Constaint_Alpha (1-Alpha)\n'; -printf 'Period Sign \n'; -for {k in 6..K_PERIOD-1} { - printf "%s %10.2f <= %s\n", k, ((1 - Alpha) * sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k] * XForestLand[g,i,j] - sum {g in G_STAND_TYPE,i in I_CULTURAL_PRES, j in J_MGT_YEAR} Yield_Table_Vol[g,i,j,k+1] * XForestLand[g,i,j]),0; - } -printf '\n'; - - -# Forest / Land Constraints -printf '\n'; -printf 'Total Area Constraint\n'; -printf 'Type AgeClass PrescMgt Value Sign Total_Area \n'; -printf '%5s <= %.3f\n',sum {g in G_STAND_TYPE, i in I_CULTURAL_PRES, j in J_MGT_YEAR} XForestLand[g,i,j], Total_Area; - -printf 'Area\n'; -printf 'Area Value Sign Areas_Stand\n'; -for {g in G_STAND_TYPE} { - printf '%5s %10.2f <= %.3f\n', g, sum {i in I_CULTURAL_PRES,j in J_MGT_YEAR} XForestLand[g,i,j], Area_Stand_Type[g]; - } - - -#DATA SECTION - -data; - -# Most of the data has been moved to dbf format - -param MGT:=31; - -param K_PERIOD:= 7; - -param Alpha:= 0.20; -param Beta:= 0.20; - -param Harvest_Min_Vol_Period:= 12000; - -end; - diff --git a/resources/3rdparty/glpk-4.53/examples/dbf/Forest_Cost.dbf b/resources/3rdparty/glpk-4.53/examples/dbf/Forest_Cost.dbf deleted file mode 100644 index acb8dcb19300f8c5d1b4a5e7a63db53daadf93d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1458 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 diff --git a/resources/3rdparty/glpk-4.53/examples/dbf/Yield_Table_Vol.dbf b/resources/3rdparty/glpk-4.53/examples/dbf/Yield_Table_Vol.dbf deleted file mode 100644 index b0d051ba77e25f794cf00870bc2205d85e781817..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11786 zcmb7}v2N8s5Jdxs1_{wqy)TI3gd|Xg5D*ds6ri9=Nrgng5At6WI9?#2`u5`8-}5i)Pws1i$GfxL-_P{@+t2GC)4y=} zjp*oj|KOme4{_{4q>t`IKf9$5Ph#%lTY8r(Ik^*kdQ00%XkoX5L0gH^h>lK8msp>x zNCuUL!3~wb;D#=fL9GM^Z6)k08&sNSa#vnyL`To}k5}`J_1Skas5A_2=n@94Z_S+y zveIl&>10r8*5!OFjp$jXlR;#guMP}a-%7(^=lk$Z`=F!81|3at#7S_23_6kD;rdrXUe&8 zY_|`#F0tMj%(-dM`PSSpXniXUgVs0imTXYzWKe0=<(w#usM`mdZ>-P0X)x!eLFZd@ z!(iw8MZFJhpvMMX?y*5fvkP_N=&?aZ(_qe>4AMe1gRK&!8M#WhUOf-G+{vKkP6m}u z29-_*IT_iY(mazhs5GNYCxgsZ-No(dD4h%{oeZ+lY*6WBP-)iX3@Xhi(`g2ot$H48 zzLj1Xd^vBt%O|`SPtR}O(@J_}u%uT8OB!8Fhq02C!7}%121^r!b%(~0qo^$iAugZzWKe0=<$NoRXj;B!>#h#gXWz-7(lBU!D-DC4@AhQM@3Sg{jvgCy z^w^-I*@gOc^w^-I#|9k@gPre2(?T|=G$Yp~*Uj_b|EY47B!ike8B{tMR5}^tWMqR% z^Gwd5(u^{l3^H4F7q_dUbTX)PGRR7^L8X&HrCFCVs5GNYrx|26^E}wy4N8vgN_~>bTqrjm5dF# z++%}|hQZEvqiLaaprgkI9X&Sa zXm+6n9X&Sa=10spWKij3Q0ZillaUQ7%`-WJN;ArI tGRSPzKG?2~(#fFG$sjAu29-_*m1bSepwf&ooo0~Ps(rBeR=PL%^be03!(;#e diff --git a/resources/3rdparty/glpk-4.53/examples/dbf/cultural_pres.dbf b/resources/3rdparty/glpk-4.53/examples/dbf/cultural_pres.dbf deleted file mode 100644 index 76c8dfab5a64567d2c045041e7e8c94922c090a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96 xcmZS13NU|?`$-~y7Ez&X?>J|M_77%1ZhlI28G!m9uShA@VL5u9Zy1pqn72h#um diff --git a/resources/3rdparty/glpk-4.53/examples/dbf/mgt_year.dbf b/resources/3rdparty/glpk-4.53/examples/dbf/mgt_year.dbf deleted file mode 100644 index 043ba5a0d7cf4c384ad401cdf102bd7509eaeb15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 106 zcmZS13IU|?`$-~y7Ez}Gz_KGM}O2q@zWlI28G!mE&*UJ_qmr~m|DmJys~3}=}D GSyBKKG!E_n diff --git a/resources/3rdparty/glpk-4.53/examples/dbf/stands.dbf b/resources/3rdparty/glpk-4.53/examples/dbf/stands.dbf deleted file mode 100644 index 5ecfd2429cbfd621346f6d951d07ce3c443ab339..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4323 zcmb_fOK&4Z5YB4hwg|+L3-b#~T~+-&I>AIMZB|hdkoM#wrW6JQ_QaBD z*)u)UkFV?XRn7aaAAbD#=H}*~cYovhx^14eoBsB*-9Nnl@0`c&)5nMH%l7H!=H&S1 z?rHnnmYf{_eS5!q`SQ5MlslXDeVe<#-u?Dz_t>_m>*w)@`i9R~sox)Ne;se?__y!IW4k}UY(D?ex+nL?`No2i`+v7AOH5gP zB4x$HqLMO|;HLu;rl|6CpXN{gTTmtWpK@WW~E5@*>e+6$V@Rt%&0Zg3N}33vB3u@zzb^%h~fFM*#`+fk$d9{(VO&T(T~ zfg=Sq-y6zj&N)&}rA}oLL_xej`nPRAdA^u{FmZt4Jp!*u&u|uKLYwp~p28cR-;{sO z_QUf%HG%dDs9_G2kRUGI$A8;&?oy~Uud?w%QtubcGUHL{A$;<72&52GU-7~IN1zd0hHp4$lNWZfY-1Ne?lXNSEl?X{Y*Ph zyipHB?8te*M=j=Vwh9fJ;9RbSuhLHuV$N+Eut3jnvCeuaGb7`5RU!SrFRp;ECN?wE zWF7_rLnGk$R9N@Ydq9fsX9ZbG@&60_WP3r(n~5ca?A##TC2K_7Tew;a8Oiq=_=D{y z>BVf1BdLS69jcm^a#D(UFP zkLB+C_R!$kU?bgA#gC(8~Hu0jGH_2YQg?uzG{^>RsYenP=z11PlN?WOiB zeDH55ze+z_wqvmsTRtGdX_{e0pb3e})Pi0E#J2-5}i@5d~swYz^=@-a34ndHTv$?KJo)LMr3o2wp@oa(u7#I3vwO zqeN>Z5;EWw@aDrf0!SU5<7SGtaxlqJ5pb+1%{jp4QAKAP~kAi&~L#)94*d>Q@ZzNn4oem#Xz193NU|?`$-~y7EAUMR)&jljv45B#El<+DzD!_mfjG^ERV@Ux30vrbK diff --git a/resources/3rdparty/glpk-4.53/examples/dea.mod b/resources/3rdparty/glpk-4.53/examples/dea.mod deleted file mode 100644 index ba610735a..000000000 --- a/resources/3rdparty/glpk-4.53/examples/dea.mod +++ /dev/null @@ -1,222 +0,0 @@ -/* Data Envelopment Analysis (DEA) - * - * DEA quantifies the relative efficiency of decision making units (DMUs) by - * finding the efficient frontier in multiple input multiple output data. The - * inputs are resources (eg. number of employees, available machines, ...), - * the outputs are productive outputs (eg. contracts made, total sales, ...). - * The method is non-parametric. More details are available in the paper - * below. - * - * Models according to: Seiford, Threall, "Recent developments in DEA", 1990. - * - * Implementation: Sebastian Nowozin - */ - -### SETS ### - -set dmus; # Decision Making Units (DMU) -set inputs; # Input parameters -set outputs; # Output parameters - - -### PARAMETERS ### - -param input_data{dmus,inputs} >= 0; -param output_data{dmus,outputs} >= 0; - - -### PROGRAM ### - -var theta{dmus} >= 0; -var lambda{dmus,dmus} >= 0; - -minimize inefficiency: sum{td in dmus} theta[td]; - -s.t. output_lower_limit{o in outputs, td in dmus}: - sum{d in dmus} lambda[d,td]*output_data[d,o] >= output_data[td,o]; -s.t. input_upper_limit{i in inputs, td in dmus}: - sum{d in dmus} lambda[d,td]*input_data[d,i] <= theta[td]*input_data[td,i]; - - s.t. PI1{td in dmus}: - sum{d in dmus} lambda[d,td] = 1; -/* -possibilities: - i) (no constraint) - ii) s.t. PI1{td in dmus}: - sum{d in dmus} lambda[d,td] <= 1; - iii) s.t. PI1{td in dmus}: - sum{d in dmus} lambda[d,td] >= 1; -*/ - - -### SOLVE AND PRINT SOLUTION ### - -solve; - -printf "DMU\tEfficiency\n"; -for {td in dmus} { - printf "%s\t%1.4f\n", td, theta[td]; -} - -### DATA ### - -data; - -set dmus := 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 - 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 - 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 - 61 62 63 64 65 66 67 68 69 ; -set inputs := AvgInventory LaborCost OperatingCost Population ; -set outputs := PrescrVol kDollarValue ; - -param input_data default 0.0 : - - AvgInventory LaborCost OperatingCost Population := - -1 8000 17030 1280 1410 -2 9000 25890 2779 1523 -3 13694 29076 2372 1354 -4 4250 17506 1385 822 -5 6500 23208 639 746 -6 7000 12946 802 1281 -7 4500 18001 1130 1016 -8 5000 14473 1097 1070 -9 27000 31760 5559 1694 -10 21560 50972 15010 1910 -11 15000 39523 4799 1745 -12 8500 13076 3489 1353 -13 35000 35427 1704 500 -14 18000 27554 2882 1016 -15 59750 53848 14208 2500 -16 19200 38253 1480 2293 -17 40000 109404 83016 2718 -18 8466 18198 1278 2877 -19 16000 40891 7599 4150 -20 10000 45444 5556 4421 -21 25000 35623 2121 3883 -22 14000 20192 5515 3519 -23 12500 34973 10475 32366 -24 17260 32284 14498 3393 -25 7000 17920 7585 4489 -26 14000 42094 3742 2217 -27 16400 35422 14236 4641 -28 13000 19100 3529 5968 -29 30000 72167 8656 8715 -30 12530 19970 1714 5968 -31 31500 39183 4919 5607 -32 10000 32048 3483 7324 -33 22000 68877 12279 8685 -34 10000 29812 3332 8685 -35 16000 47686 2507 5420 -36 10000 33415 4738 7703 -37 9000 12359 4603 4665 -38 16439 23614 2989 6317 -39 14500 36069 1793 31839 -40 39000 76307 9539 15619 -41 24927 40706 12661 30213 -42 13858 39267 4609 34719 -43 33375 29509 11323 31839 -44 29044 44482 5542 34719 -45 32257 61365 20550 32366 -46 8800 49671 3306 43561 -47 47000 40425 10396 31263 -48 12000 33034 4915 31263 -49 28000 69163 4688 15173 -50 13300 28931 16735 73064 -51 13500 29758 4260 62309 -52 24000 40927 8285 23166 -53 16000 40403 2131 99836 -54 17000 38730 2539 60348 -55 25000 35978 2502 99836 -56 16000 37509 6278 99836 -57 20000 46950 10715 85925 -58 14000 35966 3144 85925 -59 22000 68318 8015 108987 -60 21879 69537 7778 108987 -61 15000 25425 2812 201404 -62 10000 19508 2454 201404 -63 20000 28191 3367 201404 -64 18000 37073 8624 108987 -65 19051 23763 3496 201404 -66 15000 28642 3366 201404 -67 10000 35919 3868 201404 -68 24000 54653 26494 108987 -69 1800 6276 3413 60348 - ; - -param output_data default 0.0 : - - PrescrVol kDollarValue := - -1 12293 61.00 -2 18400 92.00 -3 16789 92.65 -4 10700 45.00 -5 9800 50.00 -6 6500 29.00 -7 8200 56.00 -8 8680 45.00 -9 33800 183.00 -10 23710 156.00 -11 24000 120.00 -12 17500 75.00 -13 25000 130.00 -14 26000 122.00 -15 26830 178.513 -16 16600 106.00 -17 90000 450.00 -18 11140 73.624 -19 25868 136.00 -20 32700 191.295 -21 29117 152.864 -22 18000 100.00 -23 11100 60.00 -24 23030 137.778 -25 10656 58.00 -26 24682 152.095 -27 26908 120.00 -28 16464 80.00 -29 57000 321.00 -30 17532 94.747 -31 30035 168.00 -32 16000 100.00 -33 63700 277.00 -34 18000 90.00 -35 27339 139.134 -36 19500 116.00 -37 13000 80.00 -38 15370 102.00 -39 18446 90.00 -40 56000 260.00 -41 73845 364.951 -42 28600 145.00 -43 27000 243.00 -44 52423 279.816 -45 73759 363.388 -46 20500 80.00 -47 27100 115.00 -48 15000 110.00 -49 50895 277.852 -50 19707 128.00 -51 17994 78.80 -52 36135 167.222 -53 30000 153.00 -54 26195 125.00 -55 28000 216.00 -56 24658 152.551 -57 36850 190.00 -58 29250 183.69 -59 50000 250.00 -60 40078 265.443 -61 20200 110.00 -62 12500 75.00 -63 30890 195.00 -64 31000 175.00 -65 31277 192.992 -66 11500 75.00 -67 30000 175.668 -68 38383 190.00 -69 2075 8.650 - ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/diet.mod b/resources/3rdparty/glpk-4.53/examples/diet.mod deleted file mode 100644 index 6d36391af..000000000 --- a/resources/3rdparty/glpk-4.53/examples/diet.mod +++ /dev/null @@ -1,99 +0,0 @@ -# STIGLER'S NUTRITION MODEL -# -# This model determines a least cost diet which meets the daily -# allowances of nutrients for a moderately active man weighing 154 lbs. -# -# References: -# Dantzig G B, "Linear Programming and Extensions." -# Princeton University Press, Princeton, New Jersey, 1963, -# Chapter 27-1. - -set N; -/* nutrients */ - -set F; -/* foods */ - -param b{N}; -/* required daily allowances of nutrients */ - -param a{F,N}; -/* nutritive value of foods (per dollar spent) */ - -var x{f in F} >= 0; -/* dollars of food f to be purchased daily */ - -s.t. nb{n in N}: sum{f in F} a[f,n] * x[f] = b[n]; -/* nutrient balance (units) */ - -minimize cost: sum{f in F} x[f]; -/* total food bill (dollars) */ - -data; - -param : N : b := - Calorie 3 /* thousands */ - Protein 70 /* grams */ - Calcium 0.8 /* grams */ - Iron 12 /* milligrams */ - Vitamin-A 5 /* thousands IUs */ - Vitamin-B1 1.8 /* milligrams */ - Vitamin-B2 2.7 /* milligrams */ - Niacin 18 /* milligrams */ - Vitamin-C 75 /* milligrams */ ; - -set F := Wheat Cornmeal Cannedmilk Margarine Cheese Peanut-B Lard - Liver Porkroast Salmon Greenbeans Cabbage Onions Potatoes - Spinach Sweet-Pot Peaches Prunes Limabeans Navybeans; - -param a default 0 - -: Calorie Protein Calcium Iron Vitamin-A Vitamin-B1 := -# (1000) (g) (g) (mg) (1000IU) (mg) - -Wheat 44.7 1411 2.0 365 . 55.4 -Cornmeal 36 897 1.7 99 30.9 17.4 -Cannedmilk 8.4 422 15.1 9 26 3 -Margarine 20.6 17 .6 6 55.8 .2 -Cheese 7.4 448 16.4 19 28.1 .8 -Peanut-B 15.7 661 1 48 . 9.6 -Lard 41.7 . . . .2 . -Liver 2.2 333 .2 139 169.2 6.4 -Porkroast 4.4 249 .3 37 . 18.2 -Salmon 5.8 705 6.8 45 3.5 1 -Greenbeans 2.4 138 3.7 80 69 4.3 -Cabbage 2.6 125 4 36 7.2 9 -Onions 5.8 166 3.8 59 16.6 4.7 -Potatoes 14.3 336 1.8 118 6.7 29.4 -Spinach 1.1 106 . 138 918.4 5.7 -Sweet-Pot 9.6 138 2.7 54 290.7 8.4 -Peaches 8.5 87 1.7 173 86.8 1.2 -Prunes 12.8 99 2.5 154 85.7 3.9 -Limabeans 17.4 1055 3.7 459 5.1 26.9 -Navybeans 26.9 1691 11.4 792 . 38.4 - -: Vitamin-B2 Niacin Vitamin-C := -# (mg) (mg) (mg) - -Wheat 33.3 441 . -Cornmeal 7.9 106 . -Cannedmilk 23.5 11 60 -Margarine . . . -Cheese 10.3 4 . -Peanut-B 8.1 471 . -Lard .5 5 . -Liver 50.8 316 525 -Porkroast 3.6 79 . -Salmon 4.9 209 . -Greenbeans 5.8 37 862 -Cabbage 4.5 26 5369 -Onions 5.9 21 1184 -Potatoes 7.1 198 2522 -Spinach 13.8 33 2755 -Sweet-Pot 5.4 83 1912 -Peaches 4.3 55 57 -Prunes 4.3 65 257 -Limabeans 38.2 93 . -Navybeans 24.6 217 . ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/dist.mod b/resources/3rdparty/glpk-4.53/examples/dist.mod deleted file mode 100644 index f3d66b513..000000000 --- a/resources/3rdparty/glpk-4.53/examples/dist.mod +++ /dev/null @@ -1,565 +0,0 @@ -# DIST, a product distribution model -# -# References: -# Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language -# for Mathematical Programming." Management Science 36 (1990) 519-554. - -### SHIPPING SETS AND PARAMETERS ### - -set whse 'warehouses'; # Locations from which demand is satisfied - -set dctr 'distribution centers' within whse; - - # Locations from which product may be shipped - -param sc 'shipping cost' {dctr,whse} >= 0; - - # Shipping costs, to whse from dctr, in $ / 100 lb - -param huge 'largest shipping cost' > 0; - - # Largest cost allowed for a usable shipping route - -param msr 'minimum size restriction' {dctr,whse} logical; - - # True indicates a minimum-size restriction on - # direct shipments using this dctr --> whse route - -param dsr 'direct shipment requirement' {dctr} >= 0; - - # Minimum total demand, in pallets, needed to - # allow shipment on routes subject to the - # minimum size restriction - -### PLANT SETS AND PARAMETERS ### - -set fact 'factories' within dctr; - - # Locations where product is manufactured - -param rtmin 'regular-time total minimum' >= 0; - - # Lower limit on (average) total regular-time - # crews employed at all factories - -param rtmax 'regular-time total maximum' >= rtmin; - - # Upper limit on (average) total regular-time - # crews employed at all factories - -param otmin 'overtime total minimum' >= 0; - - # Lower limit on total overtime hours at all factories - -param otmax 'overtime total maximum' >= otmin; - - # Upper limit on total overtime hours at all factories - -param rmin 'regular-time minimums' {fact} >= 0; - - # Lower limits on (average) regular-time crews - -param rmax 'regular-time maximums' {f in fact} >= rmin[f]; - - # Upper limits on (average) regular-time crews - -param omin 'overtime minimums' {fact} >= 0; - - # Lower limits on overtime hours - -param omax 'overtime maximums' {f in fact} >= omin[f]; - - # Upper limits on overtime hours - -param hd 'hours per day' {fact} >= 0; - - # Regular-time hours per working day - -param dp 'days in period' {fact} > 0; - - # Working days in the current planning period - -### PRODUCT SETS AND PARAMETERS ### - -set prd 'products'; # Elements of the product group - -param wt 'weight' {prd} > 0; - - # Weight in 100 lb / 1000 cases - -param cpp 'cases per pallet' {prd} > 0; - - # Cases of product per shipping pallet - -param tc 'transshipment cost' {prd} >= 0; - - # Transshipment cost in $ / 1000 cases - -param pt 'production time' {prd,fact} >= 0; - - # Crew-hours to produce 1000 cases - -param rpc 'regular-time production cost' {prd,fact} >= 0; - - # Cost of production on regular time, - # in $ / 1000 cases - -param opc 'overtime production cost' {prd,fact} >= 0; - - # Cost of production on overtime, in $ / 1000 cases - -### DEMAND SETS AND PARAMETERS ### - -param dt 'total demand' {prd} >= 0; - - # Total demands for products, in 1000s - -param ds 'demand shares' {prd,whse} >= 0.0, <= 1.0; - - # Historical demand data, from which each - # warehouse's share of total demand is deduced - -param dstot {p in prd} := sum {w in whse} ds[p,w]; - - # Total of demand shares; should be 1, but often isn't - -param dem 'demand' {p in prd, w in whse} := dt[p] * ds[p,w] / dstot[p]; - - # Projected demands to be satisfied, in 1000s - -set rt 'shipping routes available' := - - {d in dctr, w in whse: - d <> w and sc[d,w] < huge and - (w in dctr or sum {p in prd} dem[p,w] > 0) and - not (msr[d,w] and sum {p in prd} 1000*dem[p,w]/cpp[p] < dsr[d]) }; - - # List of ordered pairs that represent routes - # on which shipments are allowed - -### VARIABLES ### - -var Rprd 'regular-time production' {prd,fact} >= 0; - - # Regular-time production of each product - # at each factory, in 1000s of cases - -var Oprd 'overtime production' {prd,fact} >= 0; - - # Overtime production of each product - # at each factory, in 1000s of cases - -var Ship 'shipments' {prd,rt} >= 0; - - # Shipments of each product on each allowed route, - # in 1000s of cases - -var Trans 'transshipments' {prd,dctr} >= 0; - - # Transshipments of each product at each - # distribution center, in 1000s of cases - -### OBJECTIVE ### - -minimize cost: sum {p in prd, f in fact} rpc[p,f] * Rprd[p,f] + - sum {p in prd, f in fact} opc[p,f] * Oprd[p,f] + - sum {p in prd, (d,w) in rt} sc[d,w] * wt[p] * Ship[p,d,w] + - sum {p in prd, d in dctr} tc[p] * Trans[p,d]; - - # Total cost: regular production, overtime - # production, shipping, and transshipment - -### CONSTRAINTS ### - -rtlim 'regular-time total limits': - - rtmin <= sum {p in prd, f in fact} - (pt[p,f] * Rprd[p,f]) / (dp[f] * hd[f]) <= rtmax; - - # Total crews must lie between limits - -otlim 'overtime total limits': - - otmin <= sum {p in prd, f in fact} pt[p,f] * Oprd[p,f] <= otmax; - - # Total overtime must lie between limits - -rlim 'regular-time limits' {f in fact}: - - rmin[f] <= sum {p in prd} - (pt[p,f] * Rprd[p,f]) / (dp[f] * hd[f]) <= rmax[f]; - - # Crews at each factory must lie between limits - -olim 'overtime limits' {f in fact}: - - omin[f] <= sum {p in prd} pt[p,f] * Oprd[p,f] <= omax[f]; - - # Overtime at each factory must lie between limits - -noRprd 'no regular production' {p in prd, f in fact: rpc[p,f] = 0}: - - Rprd[p,f] = 0; - -noOprd 'no overtime production' {p in prd, f in fact: opc[p,f] = 0}: - - Oprd[p,f] = 0; # Do not produce where specified cost is zero - -bal 'material balance' {p in prd, w in whse}: - - sum {(v,w) in rt} - Ship [p,v,w] + (if w in fact then Rprd[p,w] + Oprd[p,w]) = - - dem[p,w] + (if w in dctr then sum {(w,v) in rt} Ship[p,w,v]); - - # Demand is satisfied by shipment into warehouse - # plus production (if it is a factory) - # minus shipment out (if it is a distn. center) - -trdef 'transshipment definition' {p in prd, d in dctr}: - - Trans[p,d] >= sum {(d,w) in rt} Ship [p,d,w] - - (if d in fact then Rprd[p,d] + Oprd[p,d]); - - # Transshipment at a distribution center is - # shipments out less production (if any) - -### DATA -- 3 PRODUCTS ### - -data; - -set prd := 18REG 24REG 24PRO ; - -set whse := w01 w02 w03 w04 w05 w06 w08 w09 w12 w14 w15 w17 - w18 w19 w20 w21 w24 w25 w26 w27 w28 w29 w30 w31 - w32 w33 w34 w35 w36 w37 w38 w39 w40 w41 w42 w43 - w44 w45 w46 w47 w48 w49 w50 w51 w53 w54 w55 w56 - w57 w59 w60 w61 w62 w63 w64 w65 w66 w68 w69 w71 - w72 w73 w74 w75 w76 w77 w78 w79 w80 w81 w82 w83 - w84 w85 w86 w87 w89 w90 w91 w92 w93 w94 w95 w96 - w98 x22 x23 ; - -set dctr := w01 w02 w03 w04 w05 w62 w76 w96 ; - -set fact := w01 w05 w96 ; - -param huge := 99. ; - -param rtmin := 0.0 ; -param rtmax := 8.0 ; - -param otmin := 0.0 ; -param otmax := 96.0 ; - -param rmin := w01 0.00 w05 0.00 w96 0.00 ; -param rmax := w01 3.00 w05 2.00 w96 3.00 ; - -param omin := w01 0.0 w05 0.0 w96 0.0 ; -param omax := w01 48.0 w05 0.0 w96 48.0 ; - -param hd := w01 8.0 w05 8.0 w96 8.0 ; - -param dp := w01 19.0 w05 19.0 w96 19.0 ; - -param wt := 18REG 47.3 24REG 63.0 24PRO 63.0 ; - -param tc := 18REG 40.00 24REG 45.00 24PRO 45.00 ; - -param dt := 18REG 376.0 24REG 172.4 24PRO 316.3 ; - -param cpp := 18REG 102. 24REG 91. 24PRO 91. ; - -param dsr := w01 96. w02 96. w03 96. w04 96. w05 96. - w62 96. w76 96. w96 96. ; - -param pt (tr) : - - 18REG 24REG 24PRO := - -w01 1.194 1.429 1.429 -w05 1.194 1.509 1.509 -w96 0.000 1.600 1.600 ; - -param rpc (tr) : - - 18REG 24REG 24PRO := - -w01 2119. 2653. 2617. -w05 2489. 3182. 3176. -w96 0. 2925. 2918. ; - -param opc (tr) : - - 18REG 24REG 24PRO := - -w01 2903. 3585. 3579. -w05 0. 0. 0. -w96 0. 3629. 3622. ; - -param sc default 99.99 (tr) : - - w01 w02 w03 w04 w05 w62 w76 w96 := - -w01 . 2.97 1.14 2.08 2.37 1.26 2.42 1.43 -w02 4.74 . 4.17 6.12 7.41 3.78 7.04 5.21 -w03 2.45 4.74 . 3.67 2.84 0.90 2.41 2.55 -w04 1.74 5.03 2.43 . 3.19 2.45 2.69 0.58 -w05 2.70 5.16 2.84 2.85 . 3.26 3.34 2.71 -w06 1.99 4.17 2.13 2.19 2.52 2.06 2.00 1.51 -w08 0.21 2.92 1.24 2.07 2.29 1.25 2.32 1.55 -w09 0.66 3.76 1.41 2.47 1.82 1.66 . 1.87 -w12 1.38 3.83 1.68 2.53 2.39 . 1.96 1.94 -w14 2.47 1.58 2.40 3.59 3.85 2.25 . 3.05 -w15 1.06 4.95 2.48 1.39 3.41 1.96 . 1.02 -w17 0.88 3.39 1.46 2.00 2.67 1.45 . 1.46 -w18 7.90 6.57 7.79 9.59 10.81 . . 6.70 -w19 1.42 4.12 1.96 1.99 3.52 1.88 . 1.26 -w20 3.03 1.59 2.34 4.76 3.98 1.88 . 3.73 -w24 1.58 2.80 2.27 2.87 3.19 1.31 . 2.05 -w25 1.51 5.05 2.74 0.57 2.98 . 2.95 0.27 -w26 1.75 3.61 2.70 1.54 4.07 3.52 . 1.03 -w27 2.48 6.87 3.17 1.59 2.08 3.45 . 0.99 -w28 2.05 6.83 2.97 1.13 2.91 . . 1.26 -w29 4.03 3.68 4.46 3.20 5.50 . . 3.20 -w30 2.48 5.78 2.99 2.24 1.79 3.10 . 1.39 -w31 2.34 5.41 2.87 1.67 1.66 . . 1.39 -w32 14.36 . . . . . . . -w33 3.87 4.27 5.11 3.48 5.66 4.03 . 3.05 -w34 3.26 4.80 3.21 2.70 4.14 . . 1.77 -w35 2.34 2.84 2.89 3.35 3.78 2.68 . 2.52 -w36 2.43 5.69 2.96 2.95 1.02 2.61 1.07 2.54 -w37 2.23 4.64 2.41 1.99 4.30 2.61 . 1.44 -w38 4.66 4.36 5.23 3.04 4.46 . . 3.82 -w39 1.11 3.51 1.10 2.53 3.07 1.12 . 2.23 -w40 2.99 4.78 4.23 1.57 3.92 . . 1.80 -w41 4.93 4.00 5.43 4.45 6.31 . . 3.81 -w42 3.86 6.55 5.03 2.11 4.41 . . 2.63 -w43 4.61 4.45 3.77 1.22 4.31 . . 2.35 -w44 2.05 4.48 1.06 3.70 3.46 1.10 . 3.21 -w45 0.92 3.42 1.58 3.04 1.82 1.94 . 2.52 -w46 1.36 2.44 0.95 3.08 2.78 0.39 2.16 2.37 -w47 1.30 3.39 1.60 2.49 4.29 2.04 . 1.68 -w48 1.65 3.78 1.03 2.97 2.21 1.31 . 2.74 -w49 1.96 3.00 1.50 3.24 3.68 1.00 . 2.99 -w50 0.90 4.14 1.60 1.95 3.61 1.61 . 1.52 -w51 1.59 3.95 0.25 2.96 2.58 1.00 2.41 2.71 -w53 1.59 3.79 1.28 3.12 3.10 0.89 . 2.98 -w54 1.72 4.36 1.61 2.92 2.34 1.91 1.97 3.05 -w55 2.45 2.73 2.21 4.47 4.30 2.57 . 4.48 -w56 1.10 3.73 1.59 2.74 2.33 1.45 . 2.44 -w57 0.95 3.39 1.37 2.30 2.47 1.15 . 1.95 -w59 3.29 5.35 3.32 3.81 1.52 3.38 1.34 4.08 -w60 2.41 6.12 2.46 3.65 2.35 . 1.37 4.06 -w61 3.32 5.50 3.41 3.38 1.23 . 0.99 4.28 -w62 1.12 3.00 0.82 3.22 2.95 . 3.33 2.53 -w63 3.59 6.36 3.25 4.12 1.84 3.59 1.46 4.03 -w64 1.85 4.45 2.17 3.43 2.13 2.03 . 4.02 -w65 2.78 4.79 2.81 2.94 1.54 2.90 1.07 2.94 -w66 3.90 5.79 3.05 3.65 1.36 3.39 1.22 3.57 -w68 2.61 5.20 2.90 2.34 1.68 3.19 1.48 2.31 -w69 2.94 5.21 2.78 3.43 0.21 3.26 0.68 2.54 -w71 2.06 4.98 2.38 2.44 1.59 2.97 1.05 2.55 -w72 2.61 5.50 2.83 3.12 1.35 3.23 0.88 2.99 -w73 8.52 6.16 8.03 8.83 10.44 7.38 10.26 . -w74 6.11 5.46 9.07 9.38 10.80 . . 8.25 -w75 2.66 4.94 2.87 3.69 1.52 3.15 1.24 4.00 -w76 1.99 5.26 2.23 3.36 0.58 3.17 . 2.50 -w77 4.32 3.07 5.05 3.88 6.04 . . 4.15 -w78 5.60 2.59 5.78 5.56 7.10 . . 5.60 -w79 4.25 2.32 4.93 4.57 6.04 . . 4.58 -w80 5.94 4.00 5.60 7.02 9.46 . . 7.51 -w81 5.39 2.21 5.10 6.22 6.46 . . 6.58 -w82 8.80 5.69 9.29 9.88 11.69 8.63 11.52 . -w83 4.40 . 5.24 5.21 5.81 3.91 7.04 5.33 -w84 5.87 5.43 6.17 5.70 7.63 . . 5.70 -w85 3.90 3.65 3.38 4.57 5.64 3.05 . 5.04 -w86 5.48 2.10 5.70 6.37 7.33 . . 6.19 -w87 8.88 5.54 9.50 9.71 11.64 8.85 11.68 . -w89 4.62 4.01 4.03 6.30 6.30 3.81 . 7.77 -w90 4.35 2.72 4.61 4.01 5.60 . . 3.20 -w91 7.61 4.42 7.83 6.85 8.79 . . 7.66 -w92 7.15 2.69 6.91 7.20 . . . 7.06 -w93 3.17 3.95 4.37 3.74 5.05 . . 2.40 -w94 1.21 3.07 0.90 2.74 3.17 . 2.63 2.39 -w95 5.82 3.29 6.55 7.06 11.47 . . 7.83 -w96 1.77 5.20 2.72 0.59 3.47 2.48 . . -w98 3.04 1.92 3.64 3.70 4.90 3.05 . 3.88 -x22 4.08 6.25 4.15 4.30 1.77 . 1.77 . -x23 3.39 5.74 3.55 4.08 1.69 . 1.47 . ; - -param msr (tr) : - - w01 w02 w03 w04 w05 w62 w76 w96 := - -w01 0 0 0 0 0 0 1 0 -w02 0 0 0 0 0 0 1 0 -w03 0 0 0 0 0 0 1 0 -w04 0 0 0 0 0 0 1 0 -w05 0 0 0 0 0 0 0 0 -w06 0 1 1 1 1 1 1 1 -w08 0 1 1 1 1 1 1 1 -w09 0 1 1 1 1 1 0 1 -w12 0 1 1 1 1 0 1 1 -w14 1 1 1 1 1 0 0 1 -w15 0 1 1 1 1 1 0 1 -w17 0 1 1 1 1 1 0 1 -w18 0 1 1 1 1 0 0 1 -w19 0 1 1 1 1 0 0 1 -w20 1 1 1 1 1 0 0 1 -w24 0 1 1 1 1 0 0 1 -w25 0 1 1 1 1 0 1 0 -w26 1 1 1 0 1 1 0 1 -w27 1 1 1 0 1 1 0 1 -w28 1 1 1 0 1 0 0 1 -w29 0 1 1 1 1 0 0 1 -w30 1 1 1 0 1 1 0 1 -w31 1 1 1 0 1 0 0 1 -w32 0 0 0 0 0 0 0 0 -w33 1 0 1 1 1 1 0 1 -w34 1 1 1 0 1 0 0 1 -w35 1 1 1 1 1 0 0 1 -w36 0 1 1 1 0 1 1 1 -w37 1 1 1 0 1 1 0 1 -w38 1 1 1 0 1 0 0 1 -w39 0 1 1 1 1 1 0 1 -w40 1 1 1 0 1 0 0 1 -w41 1 0 1 1 1 0 0 1 -w42 1 1 1 0 1 0 0 1 -w43 1 1 1 0 1 0 0 1 -w44 1 1 1 1 1 0 0 1 -w45 0 1 1 1 1 1 0 1 -w46 0 1 1 1 1 0 1 1 -w47 0 1 1 1 1 1 0 1 -w48 0 1 1 1 1 0 0 1 -w49 1 1 1 1 1 0 0 1 -w50 0 1 1 1 1 1 0 1 -w51 0 1 1 1 1 0 1 1 -w53 1 1 1 1 1 0 0 1 -w54 0 1 1 1 1 1 1 1 -w55 0 1 1 1 1 0 0 1 -w56 0 1 1 1 1 1 0 1 -w57 0 1 1 1 1 1 0 1 -w59 0 1 1 1 0 1 1 1 -w60 0 1 1 1 1 0 1 1 -w61 0 1 1 1 0 0 1 1 -w62 0 0 0 0 0 0 1 0 -w63 0 1 1 1 0 1 1 1 -w64 0 1 1 1 1 1 0 1 -w65 0 1 1 1 0 1 1 1 -w66 0 1 1 1 0 1 1 1 -w68 0 1 1 1 0 1 1 1 -w69 0 1 1 1 0 1 1 1 -w71 0 1 1 1 0 1 1 1 -w72 0 1 1 1 0 1 1 1 -w73 0 1 1 1 0 1 1 0 -w74 0 1 1 1 0 0 0 1 -w75 0 1 1 1 0 1 1 1 -w76 0 0 0 0 0 0 0 0 -w77 1 0 1 1 1 0 0 1 -w78 1 0 1 1 1 0 0 1 -w79 1 0 1 1 1 0 0 1 -w80 1 0 1 1 1 0 0 1 -w81 1 0 1 1 1 0 0 1 -w82 1 0 1 1 1 1 1 0 -w83 1 0 1 1 1 0 1 1 -w84 1 0 1 1 1 0 0 1 -w85 1 1 1 1 1 0 0 1 -w86 1 0 1 1 1 0 0 1 -w87 1 0 1 1 1 1 1 0 -w89 1 0 1 1 1 1 0 1 -w90 0 1 1 1 1 0 0 1 -w91 1 0 1 1 1 0 0 1 -w92 1 0 1 1 1 0 0 1 -w93 1 1 1 0 1 0 0 1 -w94 0 0 1 1 1 0 1 1 -w95 1 0 1 1 1 0 0 1 -w96 0 0 0 0 0 0 0 0 -w98 1 0 1 1 1 1 0 1 -x22 1 1 1 1 0 0 1 0 -x23 1 1 1 1 0 0 1 0 ; - -param ds default 0.000 (tr) : - - 18REG 24REG 24PRO := - -w01 0.000 0.000 0.008 -w02 0.004 0.000 0.000 -w03 0.000 0.000 0.000 -w04 0.010 0.002 0.000 -w05 0.000 0.000 0.000 -w06 0.010 0.008 0.008 -w08 0.030 0.024 0.024 -w09 0.014 0.018 0.020 -w12 0.014 0.012 0.010 -w14 0.007 0.007 0.012 -w15 0.010 0.019 0.018 -w17 0.013 0.010 0.011 -w19 0.015 0.012 0.009 -w20 0.012 0.021 0.022 -w21 0.000 0.000 0.000 -w24 0.012 0.022 0.018 -w25 0.019 0.025 0.020 -w26 0.006 0.015 0.021 -w27 0.008 0.010 0.015 -w28 0.011 0.016 0.019 -w29 0.008 0.020 0.013 -w30 0.011 0.013 0.015 -w31 0.011 0.013 0.017 -w32 0.006 0.000 0.000 -w33 0.000 0.015 0.014 -w34 0.008 0.007 0.005 -w35 0.002 0.006 0.014 -w36 0.015 0.013 0.005 -w37 0.017 0.016 0.015 -w38 0.015 0.009 0.012 -w39 0.007 0.017 0.022 -w40 0.009 0.014 0.020 -w41 0.003 0.014 0.011 -w42 0.017 0.011 0.012 -w43 0.009 0.013 0.011 -w44 0.002 0.012 0.012 -w45 0.016 0.025 0.028 -w46 0.038 0.062 0.040 -w47 0.007 0.010 0.010 -w48 0.003 0.015 0.016 -w49 0.005 0.016 0.017 -w50 0.011 0.008 0.007 -w51 0.010 0.022 0.021 -w53 0.004 0.026 0.020 -w54 0.020 0.017 0.025 -w55 0.004 0.019 0.028 -w56 0.004 0.010 0.008 -w57 0.014 0.020 0.018 -w59 0.012 0.006 0.007 -w60 0.019 0.010 0.009 -w61 0.028 0.010 0.012 -w62 0.000 0.000 0.000 -w63 0.070 0.027 0.037 -w64 0.009 0.004 0.005 -w65 0.022 0.015 0.016 -w66 0.046 0.017 0.020 -w68 0.005 0.012 0.016 -w69 0.085 0.036 0.039 -w71 0.011 0.013 0.010 -w72 0.089 0.031 0.034 -w75 0.026 0.012 0.010 -w77 0.001 0.004 0.002 -w78 0.002 0.004 0.002 -w79 0.001 0.004 0.002 -w80 0.001 0.001 0.002 -w81 0.001 0.003 0.002 -w83 0.009 0.010 0.008 -w84 0.001 0.002 0.002 -w85 0.001 0.004 0.005 -w86 0.001 0.002 0.002 -w87 0.002 0.003 0.000 -w89 0.001 0.001 0.002 -w90 0.006 0.017 0.013 -w91 0.002 0.010 0.013 -w92 0.000 0.003 0.002 -w93 0.002 0.006 0.007 -w95 0.001 0.007 0.007 -w96 0.000 0.000 0.000 -w98 0.006 0.005 0.002 ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/egypt.mod b/resources/3rdparty/glpk-4.53/examples/egypt.mod deleted file mode 100644 index b051d4a73..000000000 --- a/resources/3rdparty/glpk-4.53/examples/egypt.mod +++ /dev/null @@ -1,519 +0,0 @@ -# EGYPT, a static model of fertilizer production -# -# References: -# Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language -# for Mathematical Programming." Management Science 36 (1990) 519-554. - -### SETS ### - -set center; # Locations from which final product may be shipped -set port within center; # Locations at which imports can be received -set plant within center; # Locations of plants - -set region; # Demand regions - -set unit; # Productive units -set proc; # Processes - -set nutr; # Nutrients - -set c_final; # Final products (fertilizers) -set c_inter; # Intermediate products -set c_ship within c_inter; # Intermediates for shipment -set c_raw; # Domestic raw materials and miscellaneous inputs - -set commod := c_final union c_inter union c_raw; - - # All commodities - -### PARAMETERS ### - -param cf75 {region,c_final} >= 0; - - # Consumption of fertilizer 1974-75 (1000 tpy) - -param fn {c_final,nutr} >= 0; - - # Nutrient content of fertilizers - -param cn75 {r in region, n in nutr} := sum {c in c_final} cf75[r,c] * fn[c,n]; - - # Consumption of nutrients 1974-75 (1000 tpy) - -param road {region,center} >= 0; - - # Road distances - -param rail_half {plant,plant} >= 0; -param rail {p1 in plant, p2 in plant} := - if rail_half[p1,p2] > 0 then rail_half[p1,p2] else rail_half[p2,p1]; - - # Interplant rail distances (kms) - -param impd_barg {plant} >= 0; -param impd_road {plant} >= 0; - - # Import distances (kms) by barge and road - -param tran_final {pl in plant, r in region} := - if road[r,pl] > 0 then .5 + .0144 * road[r,pl] else 0; - -param tran_import {r in region, po in port} := - if road[r,po] > 0 then .5 + .0144 * road[r,po] else 0; - -param tran_inter {p1 in plant, p2 in plant} := - if rail[p1,p2] > 0 then 3.5 + .03 * rail[p1,p2] else 0; - -param tran_raw {pl in plant} := - (if impd_barg[pl] > 0 then 1.0 + .0030 * impd_barg[pl] else 0) - + (if impd_road[pl] > 0 then 0.5 + .0144 * impd_road[pl] else 0); - - # Transport cost (le per ton) for: - # final products, imported final products, - # interplant shipment, imported raw materials - -param io {commod,proc}; # Input-output coefficients - -param util {unit,proc} >= 0; - - # Capacity utilization coefficients - -param p_imp {commod} >= 0; # Import Price (cif US$ per ton 1975) - -param p_r {c_raw} >= 0; -param p_pr {plant,c_raw} >= 0; - -param p_dom {pl in plant, c in c_raw} := - if p_r[c] > 0 then p_r[c] else p_pr[pl,c]; - - # Domestic raw material prices - -param dcap {plant,unit} >= 0; - - # Design capacity of plants (t/day) - -param icap {u in unit, pl in plant} := 0.33 * dcap[pl,u]; - - # Initial capacity of plants (t/day) - -param exch := 0.4; # Exchange rate - -param util_pct := 0.85; # Utilization percent for initial capacity - -### DERIVED SETS OF "POSSIBILITIES" ### - -set m_pos {pl in plant} := {u in unit: icap[u,pl] > 0}; - - # At each plant, set of units for which there is - # initial capacity - -set p_cap {pl in plant} := - {pr in proc: forall {u in unit: util[u,pr] > 0} u in m_pos[pl] }; - - # At each plant, set of processes for which - # all necessary units have some initial capacity - -set p_except {plant} within proc; - - # At each plant, list of processes that are - # arbitrarily ruled out - -set p_pos {pl in plant} := p_cap[pl] diff p_except[pl]; - - # At each plant, set of possible processes - -set cp_pos {c in commod} := {pl in plant: sum {pr in p_pos[pl]} io[c,pr] > 0}; - -set cc_pos {c in commod} := {pl in plant: sum {pr in p_pos[pl]} io[c,pr] < 0}; - -set c_pos {c in commod} := cp_pos[c] union cc_pos[c]; - - # For each commodity, set of plants that can - # produce it (cp_pos) or consume it (cc_pos), - # and their union (c_pos) - -### VARIABLES ### - -var Z {pl in plant, p_pos[pl]} >= 0; - - # Z[pl,pr] is level of process pr at plant pl - -var Xf {c in c_final, cp_pos[c], region} >= 0; - - # Xf[c,pl,r] is amount of final product c - # shipped from plant pl to region r - -var Xi {c in c_ship, cp_pos[c], cc_pos[c]} >= 0; - - # Xi[c,p1,p2] is amount of intermediate c - # shipped from plant p1 to plant p2 - -var Vf {c_final,region,port} >= 0; - - # Vf[c,r,po] is amount of final product c - # imported by region r from port po - -var Vr {c in c_raw, cc_pos[c]} >= 0; - - # Vr[c,pl] is amount of raw material c - # imported for use at plant pl - -var U {c in c_raw, cc_pos[c]} >= 0; - - # U[c,pl] is amount of raw material c - # purchased domestically for use at plant pl - -var Psip; # Domestic recurrent cost -var Psil; # Transport cost -var Psii; # Import cost - -### OBJECTIVE ### - -minimize Psi: Psip + Psil + Psii; - -### CONSTRAINTS ### - -subject to mbd {n in nutr, r in region}: - - sum {c in c_final} fn[c,n] * - (sum {po in port} Vf[c,r,po] + - sum {pl in cp_pos[c]} Xf[c,pl,r]) >= cn75[r,n]; - - # Total nutrients supplied to a region by all - # final products (sum of imports plus internal - # shipments from plants) must meet requirements - -subject to mbdb {c in c_final, r in region: cf75[r,c] > 0}: - - sum {po in port} Vf[c,r,po] + - sum {pl in cp_pos[c]} Xf[c,pl,r] >= cf75[r,c]; - - # Total of each final product supplied to each - # region (as in previous constraint) must meet - # requirements - -subject to mb {c in commod, pl in plant}: - - sum {pr in p_pos[pl]} io[c,pr] * Z[pl,pr] - - + ( if c in c_ship then - ( if pl in cp_pos[c] then sum {p2 in cc_pos[c]} Xi[c,pl,p2] ) - - ( if pl in cc_pos[c] then sum {p2 in cp_pos[c]} Xi[c,p2,pl] )) - - + ( if (c in c_raw and pl in cc_pos[c]) then - (( if p_imp[c] > 0 then Vr[c,pl] ) - + ( if p_dom[pl,c] > 0 then U[c,pl] ))) - - >= if (c in c_final and pl in cp_pos[c]) then sum {r in region} Xf[c,pl,r]; - - # For each commodity at each plant: sum of - # (1) production or consumption at plant, - # (2) inter-plant shipments in or out, - # (3) import and domestic purchases (raw only) - # is >= 0 for raw materials and intermediates; - # is >= the total shipped for final products - -subject to cc {pl in plant, u in m_pos[pl]}: - - sum {pr in p_pos[pl]} util[u,pr] * Z[pl,pr] <= util_pct * icap[u,pl]; - - # For each productive unit at each plant, - # total utilization by all processes - # may not exceed the unit's capacity - -subject to ap: - - Psip = sum {c in c_raw, pl in cc_pos[c]} p_dom[pl,c] * U[c,pl]; - - # Psip is the cost of domestic raw materials, - # summed over all plants that consume them - -subject to al: - - Psil = sum {c in c_final} ( - - sum {pl in cp_pos[c], r in region} - tran_final[pl,r] * Xf[c,pl,r] - - + sum {po in port, r in region} tran_import[r,po] * Vf[c,r,po] ) - - + sum {c in c_ship, p1 in cp_pos[c], p2 in cc_pos[c]} - tran_inter[p1,p2] * Xi[c,p1,p2] - - + sum {c in c_raw, pl in cc_pos[c]: p_imp[c] > 0} - tran_raw[pl] * Vr[c,pl]; - - # Total transport cost is sum of shipping costs for - # (1) all final products from all plants, - # (2) all imports of final products, - # (3) all intermediates shipped between plants, - # (4) all imports of raw materials - -subject to ai: - - Psii / exch = sum {c in c_final, r in region, po in port} - p_imp[c] * Vf[c,r,po] - - + sum {c in c_raw, pl in cc_pos[c]} p_imp[c] * Vr[c,pl]; - - # Total import cost -- at exchange rate -- - # is sum of import costs for final products - # in each region and raw materials at each plant - -### DATA ### - -data; - -set center := ASWAN HELWAN ASSIOUT KAFR_EL_ZT ABU_ZAABAL ABU_KIR TALKHA SUEZ ; - -set port := ABU_KIR ; - -set plant := ASWAN HELWAN ASSIOUT KAFR_EL_ZT ABU_ZAABAL ; - -set region := ALEXANDRIA BEHERA GHARBIA KAFR_EL_SH DAKAHLIA DAMIETTA - SHARKIA ISMAILIA SUEZ MENOUFIA KALUBIA GIZA BENI_SUEF FAYOUM - MINIA ASSIOUT NEW_VALLEY SOHAG QUENA ASWAN ; - -set unit := SULF_A_S SULF_A_P NITR_ACID AMM_ELEC AMM_C_GAS C_AMM_NITR - AMM_SULF SSP ; - -set proc := SULF_A_S SULF_A_P NITR_ACID AMM_ELEC AMM_C_GAS CAN_310 CAN_335 - AMM_SULF SSP_155 ; - -set nutr := N P205 ; - -set c_final := UREA CAN_260 CAN_310 CAN_335 AMM_SULF DAP SSP_155 C_250_55 - C_300_100 ; - -set c_inter := AMMONIA NITR_ACID SULF_ACID ; - -set c_ship := AMMONIA SULF_ACID ; - -set c_raw := EL_ASWAN COKE_GAS PHOS_ROCK LIMESTONE EL_SULFUR PYRITES - ELECTRIC BF_GAS WATER STEAM BAGS ; - -set p_except[ASWAN] := CAN_335 ; -set p_except[HELWAN] := CAN_310 ; -set p_except[ASSIOUT] := ; -set p_except[KAFR_EL_ZT] := ; -set p_except[ABU_ZAABAL] := ; - -param cf75 default 0.0 : - - CAN_260 CAN_310 CAN_335 AMM_SULF UREA := - -ALEXANDRIA . . 5.0 3.0 1.0 -ASSIOUT 1.0 20.0 26.0 1.0 27.0 -ASWAN . 40.0 . . . -BEHERA 1.0 . 25.0 90.0 35.0 -BENI_SUEF 1.0 . 15.0 1.0 20.0 -DAKAHLIA 1.0 . 26.0 60.0 20.0 -DAMIETTA . . 2.0 15.0 8.0 -FAYOUM 1.0 . 20.0 6.0 20.0 -GHARBIA . . 17.0 60.0 28.0 -GIZA . . 40.0 6.0 2.0 -ISMAILIA . . 4.0 6.0 2.0 -KAFR_EL_SH 1.0 . 10.0 45.0 22.0 -KALUBIA . . 25.0 16.0 7.0 -MENOUFIA 1.0 . 24.0 21.0 30.0 -MINIA 2.0 15.0 35.0 1.0 41.0 -NEW_VALLEY . . . . 1.0 -QUENA . 95.0 2.0 . 3.0 -SHARKIA 1.0 . 31.0 50.0 28.0 -SOHAG . 65.0 3.0 . 7.0 -SUEZ . . 1.0 . . - - : SSP_155 C_250_55 C_300_100 DAP := - -ALEXANDRIA 8.0 . . . -ASSIOUT 35.0 5.0 .1 . -ASWAN 8.0 . . . -BEHERA 64.0 1.0 .1 .1 -BENI_SUEF 13.0 3.0 . . -DAKAHLIA 52.0 1.0 . . -DAMIETTA 5.0 . . . -FAYOUM 17.0 1.0 . . -GHARBIA 57.0 1.0 .2 .1 -GIZA 14.0 1.0 .1 . -ISMAILIA 4.0 . . . -KAFR_EL_SH 25.0 2.0 .1 . -KALUBIA 22.0 1.0 . .1 -MENOUFIA 33.0 2.0 .1 .1 -MINIA 50.0 3.0 .2 .1 -NEW_VALLEY 1.0 . . . -QUENA 8.0 . . . -SHARKIA 43.0 1.0 .1 . -SOHAG 20.0 1.0 . . -SUEZ 1.0 . . . ; - -param fn default 0.0 : N P205 := - - AMM_SULF .206 . - CAN_260 .26 . - CAN_310 .31 . - CAN_335 .335 . - C_250_55 .25 .055 - C_300_100 .30 .10 - DAP .18 .46 - SSP_155 . .15 - UREA .46 . ; - -param road default 0.0 : - - ABU_KIR ABU_ZAABAL ASSIOUT ASWAN HELWAN KAFR_EL_ZT SUEZ TALKHA := - -ALEXANDRIA 16 210 607 1135 244 119 362 187 -ASSIOUT 616 420 . 518 362 504 527 518 -ASWAN 1134 938 518 . 880 1022 1045 1036 -BEHERA 76 50 547 1065 184 42 288 120 -BENI_SUEF 359 163 257 775 105 248 270 261 -DAKAHLIA 208 138 515 1033 152 58 219 3 -DAMIETTA 267 216 596 1114 233 131 286 66 -FAYOUM 341 145 308 826 88 230 252 243 -GHARBIA 150 65 485 1003 122 20 226 55 -GIZA 287 48 372 890 .9 133 169 146 -ISMAILIA 365 142 536 1054 173 241 89 146 -KAFR_EL_SH 145 105 525 1043 162 20 266 35 -KALUBIA 190 97 439 957 76 66 180 81 -MENOUFIA 157 154 472 990 109 33 213 90 -MINIA 384 288 132 650 230 372 394 386 -NEW_VALLEY 815 619 199 519 561 703 726 717 -QUENA 858 662 242 276 604 746 769 760 -SHARKIA 240 60 473 991 110 78 214 58 -SOHAG 715 519 99 419 461 603 626 617 -SUEZ 370 224 541 1059 178 246 . 298 ; - -param rail_half default 0 : - - KAFR_EL_ZT ABU_ZAABAL HELWAN ASSIOUT := - -ABU_ZAABAL 85 . . . -HELWAN 142 57 . . -ASSIOUT 504 420 362 . -ASWAN 1022 938 880 518 ; - -param : impd_barg impd_road := - -ABU_ZAABAL 210 .1 -ASSIOUT 583 0 -ASWAN 1087 10 -HELWAN 183 0 -KAFR_EL_ZT 104 6 ; - -param io default 0.0 := - - [*,AMM_C_GAS] AMMONIA 1.0 - BF_GAS -609. - COKE_GAS -2.0 - ELECTRIC -1960. - STEAM -4. - WATER -700. - - [*,AMM_ELEC] AMMONIA 1.0 - EL_ASWAN -12.0 - - [*,AMM_SULF] AMMONIA -.26 - AMM_SULF 1.0 - BAGS -22. - ELECTRIC -19. - SULF_ACID -.76 - WATER -17. - - [*,CAN_310] AMMONIA -.20 - BAGS -23. - CAN_310 1.0 - LIMESTONE -.12 - NITR_ACID -.71 - STEAM -.4 - WATER -49. - - [*,CAN_335] AMMONIA -.21 - BAGS -23. - CAN_335 1.0 - LIMESTONE -.04 - NITR_ACID -.76 - STEAM -.4 - WATER -49. - - [*,NITR_ACID] AMMONIA -.292 - ELECTRIC -231. - NITR_ACID 1.0 - WATER -.6 - - [*,SSP_155] BAGS -22. - ELECTRIC -14. - PHOS_ROCK -.62 - SSP_155 1.0 - SULF_ACID -.41 - WATER -6. - - [*,SULF_A_P] ELECTRIC -75. - PYRITES -.826 - SULF_ACID 1.0 - WATER -60. - - [*,SULF_A_S] ELECTRIC -50. - EL_SULFUR -.334 - SULF_ACID 1.0 - WATER -20. ; - -param util default 0 := - - [*,*] SULF_A_S SULF_A_S 1 SULF_A_P SULF_A_P 1 - NITR_ACID NITR_ACID 1 AMM_ELEC AMM_ELEC 1 - AMM_C_GAS AMM_C_GAS 1 SSP SSP_155 1 - C_AMM_NITR CAN_310 1 C_AMM_NITR CAN_335 1 - AMM_SULF AMM_SULF 1 ; - -param p_imp default 0.0 := - - PYRITES 17.5 AMM_SULF 75. - EL_SULFUR 55. DAP 175. - UREA 150. SSP_155 80. - CAN_260 75. C_250_55 100. - CAN_310 90. C_300_100 130. - CAN_335 100. ; - -param p_r default 0.0 := - - ELECTRIC .007 - BF_GAS .007 - WATER .031 - STEAM 1.25 - BAGS .28 ; - -param p_pr default 0.0 := - - [HELWAN,COKE_GAS] 16.0 - [ASWAN,EL_ASWAN] 1.0 - - [*,LIMESTONE] ASWAN 1.2 - HELWAN 1.2 - - [*,PHOS_ROCK] ABU_ZAABAL 4.0 - ASSIOUT 3.5 - KAFR_EL_ZT 5.0 ; - -param dcap default 0.0 := - - [ABU_ZAABAL,*] SSP 600 - SULF_A_P 227 - SULF_A_S 242 - - [ASSIOUT,*] SSP 600 - SULF_A_S 250 - - [ASWAN,*] AMM_ELEC 450 - C_AMM_NITR 1100 - NITR_ACID 800 - - [HELWAN,*] AMM_C_GAS 172 - AMM_SULF 24 - C_AMM_NITR 364 - NITR_ACID 282 - - [KAFR_EL_ZT,*] SSP 600 - SULF_A_P 50 - SULF_A_S 200 ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/fctp.mod b/resources/3rdparty/glpk-4.53/examples/fctp.mod deleted file mode 100644 index 9d6382da6..000000000 --- a/resources/3rdparty/glpk-4.53/examples/fctp.mod +++ /dev/null @@ -1,93 +0,0 @@ -/* FCTP, Fixed-Charge Transportation Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* The Fixed-Charge Transportation Problem (FCTP) is obtained from - classical transportation problem by imposing a fixed cost on each - transportation link if there is a positive flow on that link. */ - -param m, integer, > 0; -/* number of sources */ - -param n, integer, > 0; -/* number of customers */ - -set I := 1..m; -/* set of sources */ - -set J := 1..n; -/* set of customers */ - -param supply{i in I}, >= 0; -/* supply at source i */ - -param demand{j in J}, >= 0; -/* demand at customer j */ - -param varcost{i in I, j in J}, >= 0; -/* variable cost (a cost per one unit shipped from i to j) */ - -param fixcost{i in I, j in J}, >= 0; -/* fixed cost (a cost for shipping any amount from i to j) */ - -var x{i in I, j in J}, >= 0; -/* amount shipped from source i to customer j */ - -s.t. f{i in I}: sum{j in J} x[i,j] = supply[i]; -/* observe supply at source i */ - -s.t. g{j in J}: sum{i in I} x[i,j] = demand[j]; -/* satisfy demand at customer j */ - -var y{i in I, j in J}, binary; -/* y[i,j] = 1 means some amount is shipped from i to j */ - -s.t. h{i in I, j in J}: x[i,j] <= min(supply[i], demand[j]) * y[i,j]; -/* if y[i,j] is 0, force x[i,j] to be 0 (may note that supply[i] and - demand[j] are implicit upper bounds for x[i,j] as follows from the - constraints f[i] and g[j]) */ - -minimize cost: sum{i in I, j in J} varcost[i,j] * x[i,j] + - sum{i in I, j in J} fixcost[i,j] * y[i,j]; -/* total transportation costs */ - -data; - -/* These data correspond to the instance bal8x12 from [Balinski]. */ - -/* The optimal solution is 471.55 */ - -param m := 8; - -param n := 12; - -param supply := 1 15.00, 2 20.00, 3 45.00, 4 35.00, - 5 25.00, 6 35.00, 7 10.00, 8 25.00; - -param demand := 1 20.00, 2 15.00, 3 20.00, 4 15.00, - 5 5.00, 6 20.00, 7 30.00, 8 10.00, - 9 35.00, 10 25.00, 11 10.00, 12 5.00; - -param varcost - : 1 2 3 4 5 6 7 8 9 10 11 12 := - 1 0.69 0.64 0.71 0.79 1.70 2.83 2.02 5.64 5.94 5.94 5.94 7.68 - 2 1.01 0.75 0.88 0.59 1.50 2.63 2.26 5.64 5.85 5.62 5.85 4.94 - 3 1.05 1.06 1.08 0.64 1.22 2.37 1.66 5.64 5.91 5.62 5.91 4.94 - 4 1.94 1.50 1.56 1.22 1.98 1.98 1.36 6.99 6.99 6.99 6.99 3.68 - 5 1.61 1.40 1.61 1.33 1.68 2.83 1.54 4.26 4.26 4.26 4.26 2.99 - 6 5.29 5.94 6.08 5.29 5.96 6.77 5.08 0.31 0.21 0.17 0.31 1.53 - 7 5.29 5.94 6.08 5.29 5.96 6.77 5.08 0.55 0.35 0.40 0.19 1.53 - 8 5.29 6.08 6.08 5.29 5.96 6.45 5.08 2.43 2.30 2.33 1.81 2.50 ; - -param fixcost - : 1 2 3 4 5 6 7 8 9 10 11 12 := - 1 11.0 16.0 18.0 17.0 10.0 20.0 17.0 13.0 15.0 12.0 14.0 14.0 - 2 14.0 17.0 17.0 13.0 15.0 13.0 16.0 11.0 20.0 11.0 15.0 10.0 - 3 12.0 13.0 20.0 17.0 13.0 15.0 16.0 13.0 12.0 13.0 10.0 18.0 - 4 16.0 19.0 16.0 11.0 15.0 12.0 18.0 12.0 18.0 13.0 13.0 14.0 - 5 19.0 18.0 15.0 16.0 12.0 14.0 20.0 19.0 11.0 17.0 16.0 18.0 - 6 13.0 20.0 20.0 17.0 15.0 12.0 14.0 11.0 12.0 19.0 15.0 16.0 - 7 11.0 12.0 15.0 10.0 17.0 11.0 11.0 16.0 10.0 18.0 17.0 12.0 - 8 17.0 10.0 20.0 12.0 17.0 20.0 16.0 15.0 10.0 12.0 16.0 18.0 ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/food.mod b/resources/3rdparty/glpk-4.53/examples/food.mod deleted file mode 100644 index cb1aa05ad..000000000 --- a/resources/3rdparty/glpk-4.53/examples/food.mod +++ /dev/null @@ -1,127 +0,0 @@ -/* Food Manufacture 1, section 12.1 in - * Williams, "Model Building in Mathematical Programming" - * - * Sebastian Nowozin - */ - -set oils; -set month; - -/* Buying prices of the raw oils in the next six month. */ -param buyingprices{month,oils}; - -/* Actual amount bought in each month. */ -var buys{month,oils} >= 0; - -/* Stock for each oil. */ -var stock{month,oils} >= 0; - -/* Price of the produced product */ -param productprice >= 0; -param storagecost; - -param oilhardness{oils} >= 0; - -/* Actual amount of output oil produced in each month */ -var production{m in month} >= 0; -var useoil{m in month, o in oils} >= 0; - -maximize totalprofit: - sum{m in month} productprice*production[m] - - sum{m in month, o in oils} buyingprices[m,o]*buys[m,o] - - sum{m in month, o in oils} storagecost*stock[m,o]; - -/* Constraints */ - -/* 1. Starting stock */ -s.t. startstock{o in oils}: - stock[1,o] = 500; -s.t. endstock{o in oils}: - stock[6,o] + buys[6,o] - useoil[6,o] >= 500; - -/* 2. Stock constraints */ -s.t. stocklimit{m in month, o in oils}: - stock[m,o] <= 1000; - -s.t. production1{m in month, o in oils}: - useoil[m,o] <= stock[m,o] + buys[m,o]; -s.t. production2{m1 in month, m2 in month, o in oils : m2 = m1+1}: - stock[m2,o] = stock[m1,o] + buys[m1,o] - useoil[m1,o]; - -s.t. production3a{m in month}: - sum{o in oils} oilhardness[o]*useoil[m,o] >= 3*production[m]; -s.t. production3b{m in month}: - sum{o in oils} oilhardness[o]*useoil[m,o] <= 6*production[m]; - -s.t. production4{m in month}: - production[m] = sum{o in oils} useoil[m,o]; - -/* 3. Refining constraints */ -s.t. refine1{m in month}: - useoil[m,"VEG1"]+useoil[m,"VEG2"] <= 200; -s.t. refine2{m in month}: - useoil[m,"OIL1"]+useoil[m,"OIL2"]+useoil[m,"OIL3"] <= 250; - -solve; - -for {m in month} { - printf "Month %d\n", m; - printf "PRODUCE %4.2f tons, hardness %4.2f\n", production[m], - (sum{o in oils} oilhardness[o]*useoil[m,o]) / (sum{o in oils} useoil[m,o]); - - printf "\tVEG1\tVEG2\tOIL1\tOIL2\tOIL3\n"; - printf "STOCK"; - printf "%d", m; - for {o in oils} { - printf "\t%4.2f", stock[m,o]; - } - printf "\nBUY"; - for {o in oils} { - printf "\t%4.2f", buys[m,o]; - } - printf "\nUSE"; - printf "%d", m; - for {o in oils} { - printf "\t%4.2f", useoil[m,o]; - } - printf "\n"; - printf "\n"; -} -printf "Total profit: %4.2f\n", - (sum{m in month} productprice*production[m] - - sum{m in month, o in oils} buyingprices[m,o]*buys[m,o] - - sum{m in month, o in oils} storagecost*stock[m,o]); -printf " turnover: %4.2f\n", - sum{m in month} productprice*production[m]; -printf " buying costs: %4.2f\n", - sum{m in month, o in oils} buyingprices[m,o]*buys[m,o]; -printf " storage costs: %4.2f\n", - sum{m in month, o in oils} storagecost*stock[m,o]; - - -data; - -param : oils : oilhardness := - VEG1 8.8 - VEG2 6.1 - OIL1 2.0 - OIL2 4.2 - OIL3 5.0 ; - -set month := 1 2 3 4 5 6; - -param buyingprices - -: VEG1 VEG2 OIL1 OIL2 OIL3 := - -1 110 120 130 110 115 -2 130 130 110 90 115 -3 110 140 130 100 95 -4 120 110 120 120 125 -5 100 120 150 110 105 -6 90 100 140 80 135 ; - -param productprice := 150; -param storagecost := 5; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/food2.mod b/resources/3rdparty/glpk-4.53/examples/food2.mod deleted file mode 100644 index 694b59462..000000000 --- a/resources/3rdparty/glpk-4.53/examples/food2.mod +++ /dev/null @@ -1,150 +0,0 @@ -/* Food Manufacture 2, section 12.2 in - * Williams, "Model Building in Mathematical Programming" - * - * Sebastian Nowozin - */ - -set oils; -set month; - -/* Buying prices of the raw oils in the next six month. */ -param buyingprices{month,oils}; - -/* Actual amount bought in each month. */ -var buys{month,oils} >= 0; - -/* Stock for each oil. */ -var stock{month,oils} >= 0; - -/* Price of the produced product */ -param productprice >= 0; -param storagecost; - -param oilhardness{oils} >= 0; -param M >= 0; - -/* Actual amount of output oil produced in each month */ -var production{m in month} >= 0; -var useoil{m in month, o in oils} >= 0, <= M; -var useoilb{m in month, o in oils}, binary; - -maximize totalprofit: - sum{m in month} productprice*production[m] - - sum{m in month, o in oils} buyingprices[m,o]*buys[m,o] - - sum{m in month, o in oils} storagecost*stock[m,o]; - -/* Constraints */ - -/* 1. Starting stock */ -s.t. startstock{o in oils}: - stock[1,o] = 500; -s.t. endstock{o in oils}: - stock[6,o] + buys[6,o] - useoil[6,o] >= 500; - -/* 2. Stock constraints */ -s.t. stocklimit{m in month, o in oils}: - stock[m,o] <= 1000; - -s.t. production1{m in month, o in oils}: - useoil[m,o] <= stock[m,o] + buys[m,o]; -s.t. production2{m1 in month, m2 in month, o in oils : m2 = m1+1}: - stock[m2,o] = stock[m1,o] + buys[m1,o] - useoil[m1,o]; - -s.t. production3a{m in month}: - sum{o in oils} oilhardness[o]*useoil[m,o] >= 3*production[m]; -s.t. production3b{m in month}: - sum{o in oils} oilhardness[o]*useoil[m,o] <= 6*production[m]; - -s.t. production4{m in month}: - production[m] = sum{o in oils} useoil[m,o]; - -/* 3. Refining constraints */ -s.t. refine1{m in month}: - useoil[m,"VEG1"]+useoil[m,"VEG2"] <= 200; -s.t. refine2{m in month}: - useoil[m,"OIL1"]+useoil[m,"OIL2"]+useoil[m,"OIL3"] <= 250; - -/* 4. Additional conditions: - * i) The food may never be made up of more than three oils every month - */ -s.t. useoilb_calc{m in month, o in oils}: - M*useoilb[m,o] >= useoil[m,o]; -s.t. useoilb_limit{m in month}: - sum{o in oils} useoilb[m,o] <= 3; - -/* ii) If an oil is used in a month, at least 20 tons must be used. - */ -s.t. useminimum{m in month, o in oils}: - 20*useoilb[m,o] <= useoil[m,o]; - -/* iii) If either of VEG1 or VEG2 is used in a month, OIL2 must also be used - */ -s.t. use_oil2a{m in month}: - useoilb[m,"VEG1"] <= useoilb[m,"OIL3"]; -s.t. use_oil2b{m in month}: - useoilb[m,"VEG2"] <= useoilb[m,"OIL3"]; - -solve; - -for {m in month} { - printf "Month %d\n", m; - printf "PRODUCE %4.2f tons, hardness %4.2f\n", production[m], - (sum{o in oils} oilhardness[o]*useoil[m,o]) / (sum{o in oils} useoil[m,o]); - - printf "\tVEG1\tVEG2\tOIL1\tOIL2\tOIL3\n"; - printf "STOCK"; - printf "%d", m; - for {o in oils} { - printf "\t%4.2f", stock[m,o]; - } - printf "\nBUY"; - for {o in oils} { - printf "\t%4.2f", buys[m,o]; - } - printf "\nUSE"; - printf "%d", m; - for {o in oils} { - printf "\t%4.2f", useoil[m,o]; - } - printf "\n"; - printf "\n"; -} -printf "Total profit: %4.2f\n", - (sum{m in month} productprice*production[m] - - sum{m in month, o in oils} buyingprices[m,o]*buys[m,o] - - sum{m in month, o in oils} storagecost*stock[m,o]); -printf " turnover: %4.2f\n", - sum{m in month} productprice*production[m]; -printf " buying costs: %4.2f\n", - sum{m in month, o in oils} buyingprices[m,o]*buys[m,o]; -printf " storage costs: %4.2f\n", - sum{m in month, o in oils} storagecost*stock[m,o]; - - -data; - -param : oils : oilhardness := - VEG1 8.8 - VEG2 6.1 - OIL1 2.0 - OIL2 4.2 - OIL3 5.0 ; - -set month := 1 2 3 4 5 6; - -param buyingprices - -: VEG1 VEG2 OIL1 OIL2 OIL3 := - -1 110 120 130 110 115 -2 130 130 110 90 115 -3 110 140 130 100 95 -4 120 110 120 120 125 -5 100 120 150 110 105 -6 90 100 140 80 135 ; - -param productprice := 150; -param storagecost := 5; -param M := 1000; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/gap.mod b/resources/3rdparty/glpk-4.53/examples/gap.mod deleted file mode 100644 index 22cdefa9f..000000000 --- a/resources/3rdparty/glpk-4.53/examples/gap.mod +++ /dev/null @@ -1,79 +0,0 @@ -/* GAP, Generalized Assignment Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* The Generalized Assignment Problem (GAP) is to assign a set of jobs - to a set of agents subject to the constraints that each job must be - assigned exactly to one agent and the total resources consumed by all - jobs assigned to an agent must not exceed the agent's capacity. */ - -param m, integer, > 0; -/* number of agents */ - -param n, integer, > 0; -/* number of jobs */ - -set I := 1..m; -/* set of agents */ - -set J := 1..n; -/* set of jobs */ - -param a{i in I, j in J}, >= 0; -/* resource consumed in allocating job j to agent i */ - -param b{i in I}, >= 0; -/* resource capacity of agent i */ - -param c{i in I, j in J}, >= 0; -/* cost of allocating job j to agent i */ - -var x{i in I, j in J}, binary; -/* x[i,j] = 1 means job j is assigned to agent i */ - -s.t. one{j in J}: sum{i in I} x[i,j] = 1; -/* job j must be assigned exactly to one agent */ - -s.t. lim{i in I}: sum{j in J} a[i,j] * x[i,j] <= b[i]; -/* total amount of resources consumed by all jobs assigned to agent i - must not exceed the agent's capacity */ - -minimize obj: sum{i in I, j in J} c[i,j] * x[i,j]; -/* the objective is to find cheapest assignment (note that gap can also - be formulated as maximization problem) */ - -data; - -/* These data correspond to the instance c515-1 (gap1) from: - - I.H. Osman, "Heuristics for the Generalised Assignment Problem: - Simulated Annealing and Tabu Search Approaches", OR Spektrum, Volume - 17, 211-225, 1995 - - D. Cattrysse, M. Salomon and L.N. Van Wassenhove, "A set partitioning - heuristic for the generalized assignment problem", European Journal - of Operational Research, Volume 72, 167-174, 1994 */ - -/* The optimal solution is 261 (minimization) or 336 (maximization) */ - -param m := 5; - -param n := 15; - -param a : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 := - 1 8 15 14 23 8 16 8 25 9 17 25 15 10 8 24 - 2 15 7 23 22 11 11 12 10 17 16 7 16 10 18 22 - 3 21 20 6 22 24 10 24 9 21 14 11 14 11 19 16 - 4 20 11 8 14 9 5 6 19 19 7 6 6 13 9 18 - 5 8 13 13 13 10 20 25 16 16 17 10 10 5 12 23 ; - -param b := 1 36, 2 34, 3 38, 4 27, 5 33; - -param c : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 := - 1 17 21 22 18 24 15 20 18 19 18 16 22 24 24 16 - 2 23 16 21 16 17 16 19 25 18 21 17 15 25 17 24 - 3 16 20 16 25 24 16 17 19 19 18 20 16 17 21 24 - 4 19 19 22 22 20 16 19 17 21 19 25 23 25 25 25 - 5 18 19 15 15 21 25 16 16 23 15 22 17 19 22 24 ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/glpsol.c b/resources/3rdparty/glpk-4.53/examples/glpsol.c deleted file mode 100644 index b1014500e..000000000 --- a/resources/3rdparty/glpk-4.53/examples/glpsol.c +++ /dev/null @@ -1,10 +0,0 @@ -/* glpsol.c */ - -#include - -int main(int argc, const char *argv[]) -{ /* stand-alone LP/MIP solver */ - return glp_main(argc, argv); -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/examples/graph.mod b/resources/3rdparty/glpk-4.53/examples/graph.mod deleted file mode 100644 index bdcc969ac..000000000 --- a/resources/3rdparty/glpk-4.53/examples/graph.mod +++ /dev/null @@ -1,98 +0,0 @@ -/* graph.mod - graph visualization */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* This model creates a picture in EPS format to visualize a graph. */ - -param file, symbolic, default "graph.eps"; -/* output file to write the picture */ - -param R, default 2; -/* radius to draw vertices, in mm */ - -param n, integer, > 0; -/* number of vertices */ - -set V, default 1..n; -/* set of vertices */ - -set E, within V cross V; -/* set of edges */ - -param x{i in V}, default 50 * cos((i - 1) / card(V) * 8 * atan(1)); -param y{i in V}, default 50 * sin((i - 1) / card(V) * 8 * atan(1)); -/* x[i] and y[i] are coordinates of node i, in mm */ - -param x0 := (min{i in V} x[i]) - R - 3.0; -param y0 := (min{i in V} y[i]) - R - 3.0; -param x1 := (max{i in V} x[i]) + R + 3.0; -param y1 := (max{i in V} y[i]) + R + 3.0; - -printf "%%!PS-Adobe-3.0 EPSF-3.0\n" > file; -printf "%%%%BoundingBox: 0 0 %d %d\n", - (72 / 25.4) * (x1 - x0), (72 / 25.4) * (y1 - y0) >> file; -printf "/Helvetica findfont 6 scalefont setfont\n" >> file; -printf "/mm { 72 mul 25.4 div } def\n" >> file; - -for {(i,j) in E} -{ printf "newpath\n" >> file; - printf "%g mm %g mm moveto\n", x[i] - x0, y[i] - y0 >> file; - printf "%g mm %g mm lineto\n", x[j] - x0, y[j] - y0 >> file; - printf "closepath\n" >> file; - printf "stroke\n" >> file; -} - -for {i in V} -{ printf "newpath\n" >> file; - printf "%g mm %g mm %g mm 0 360 arc\n", - x[i] - x0, y[i] - y0, R >> file; - printf "closepath\n" >> file; - printf "gsave 1 1 1 setrgbcolor fill grestore\n" >> file; - printf "stroke\n" >> file; - printf "%g mm %g mm moveto\n", - x[i] - (if i <= 9 then 1.2 else 1.8) - x0, - y[i] - 0.8 - y0 >> file; - printf "( %d ) show\n", i >> file; -} - -printf "showpage\n" >> file; -printf "%%%%EOF\n" >> file; - -data; - -param -: V : x y := - 1 0 40 - 2 38 12 - 3 24 -32 - 4 -24 -32 - 5 -38 12 - 6 -19 26 - 7 19 26 - 8 31 -10 - 9 0 -32 - 10 -31 -10 - 11 -9 12 - 12 9 12 - 13 14 -5 - 14 0 -15 - 15 -14 -5 - 16 0 0 ; - -set E := - (1,*) 6 10 16 12 7 - (2,*) 7 6 16 13 8 - (3,*) 8 7 16 14 9 - (4,*) 9 8 16 15 10 - (5,*) 10 9 16 11 6 - (6,*) 14 - (7,*) 15 - (8,*) 11 - (9,*) 12 - (10,*) 13 - (11,*) 12 15 - (12,*) 13 - (13,*) 14 - (14,*) 15 ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/hashi.mod b/resources/3rdparty/glpk-4.53/examples/hashi.mod deleted file mode 100644 index 48e8d9f7f..000000000 --- a/resources/3rdparty/glpk-4.53/examples/hashi.mod +++ /dev/null @@ -1,168 +0,0 @@ -/* A solver for the Japanese number-puzzle Hashiwokakero - * (http://en.wikipedia.org/wiki/Hashiwokakero) - * - * Sebastian Nowozin , 13th January 2009 - */ - -param n := 25; -set rows := 1..n; -set cols := 1..n; -param givens{rows, cols}, integer, >= 0, <= 8, default 0; - -/* Set of vertices as (row,col) coordinates */ -set V := { (i,j) in { rows, cols }: givens[i,j] != 0 }; - -/* Set of feasible horizontal edges from (i,j) to (k,l) rightwards */ -set Eh := { (i,j,k,l) in { V, V }: - i = k and j < l and # Same row and left to right - card({ (s,t) in V: s = i and t > j and t < l }) = 0 # No vertex inbetween - }; - -/* Set of feasible vertical edges from (i,j) to (k,l) downwards */ -set Ev := { (i,j,k,l) in { V, V }: - j = l and i < k and # Same column and top to bottom - card({ (s,t) in V: t = j and s > i and s < k }) = 0 # No vertex inbetween - }; - -set E := Eh union Ev; - -/* Indicators: use edge once/twice */ -var xe1{E}, binary; -var xe2{E}, binary; - -/* Constraint: Do not use edge or do use once or do use twice */ -s.t. edge_sel{(i,j,k,l) in E}: - xe1[i,j,k,l] + xe2[i,j,k,l] <= 1; - -/* Constraint: There must be as many edges used as the node value */ -s.t. satisfy_vertex_demand{(s,t) in V}: - sum{(i,j,k,l) in E: (i = s and j = t) or (k = s and l = t)} - (xe1[i,j,k,l] + 2.0*xe2[i,j,k,l]) = givens[s,t]; - -/* Constraint: No crossings */ -s.t. no_crossing1{(i,j,k,l) in Eh, (s,t,u,v) in Ev: - s < i and u > i and j < t and l > t}: - xe1[i,j,k,l] + xe1[s,t,u,v] <= 1; -s.t. no_crossing2{(i,j,k,l) in Eh, (s,t,u,v) in Ev: - s < i and u > i and j < t and l > t}: - xe1[i,j,k,l] + xe2[s,t,u,v] <= 1; -s.t. no_crossing3{(i,j,k,l) in Eh, (s,t,u,v) in Ev: - s < i and u > i and j < t and l > t}: - xe2[i,j,k,l] + xe1[s,t,u,v] <= 1; -s.t. no_crossing4{(i,j,k,l) in Eh, (s,t,u,v) in Ev: - s < i and u > i and j < t and l > t}: - xe2[i,j,k,l] + xe2[s,t,u,v] <= 1; - - -/* Model connectivity by auxiliary network flow problem: - * One vertex becomes a target node and all other vertices send a unit flow - * to it. The edge selection variables xe1/xe2 are VUB constraints and - * therefore xe1/xe2 select the feasible graph for the max-flow problems. - */ -set node_target := { (s,t) in V: - card({ (i,j) in V: i < s or (i = s and j < t) }) = 0}; -set node_sources := { (s,t) in V: (s,t) not in node_target }; - -var flow_forward{ E }, >= 0; -var flow_backward{ E }, >= 0; -s.t. flow_conservation{ (s,t) in node_target, (p,q) in V }: - /* All incoming flows */ - - sum{(i,j,k,l) in E: k = p and l = q} flow_forward[i,j,k,l] - - sum{(i,j,k,l) in E: i = p and j = q} flow_backward[i,j,k,l] - /* All outgoing flows */ - + sum{(i,j,k,l) in E: k = p and l = q} flow_backward[i,j,k,l] - + sum{(i,j,k,l) in E: i = p and j = q} flow_forward[i,j,k,l] - = 0 + (if (p = s and q = t) then card(node_sources) else -1); - -/* Variable-Upper-Bound (VUB) constraints: xe1/xe2 bound the flows. - */ -s.t. connectivity_vub1{(i,j,k,l) in E}: - flow_forward[i,j,k,l] <= card(node_sources)*(xe1[i,j,k,l] + xe2[i,j,k,l]); -s.t. connectivity_vub2{(i,j,k,l) in E}: - flow_backward[i,j,k,l] <= card(node_sources)*(xe1[i,j,k,l] + xe2[i,j,k,l]); - -/* A feasible solution is enough - */ -minimize cost: 0; - -solve; - -/* Output solution graphically */ -printf "\nSolution:\n"; -for { row in rows } { - for { col in cols } { - /* First print this cell information: givens or space */ - printf{0..0: givens[row,col] != 0} "%d", givens[row,col]; - printf{0..0: givens[row,col] = 0 and - card({(i,j,k,l) in Eh: i = row and col >= j and col < l and - xe1[i,j,k,l] = 1}) = 1} "-"; - printf{0..0: givens[row,col] = 0 and - card({(i,j,k,l) in Eh: i = row and col >= j and col < l and - xe2[i,j,k,l] = 1}) = 1} "="; - printf{0..0: givens[row,col] = 0 - and card({(i,j,k,l) in Ev: j = col and row >= i and row < k and - xe1[i,j,k,l] = 1}) = 1} "|"; - printf{0..0: givens[row,col] = 0 - and card({(i,j,k,l) in Ev: j = col and row >= i and row < k and - xe2[i,j,k,l] = 1}) = 1} '"'; - printf{0..0: givens[row,col] = 0 - and card({(i,j,k,l) in Eh: i = row and col >= j and col < l and - (xe1[i,j,k,l] = 1 or xe2[i,j,k,l] = 1)}) = 0 - and card({(i,j,k,l) in Ev: j = col and row >= i and row < k and - (xe1[i,j,k,l] = 1 or xe2[i,j,k,l] = 1)}) = 0} " "; - - /* Now print any edges */ - printf{(i,j,k,l) in Eh: i = row and col >= j and col < l and xe1[i,j,k,l] = 1} "-"; - printf{(i,j,k,l) in Eh: i = row and col >= j and col < l and xe2[i,j,k,l] = 1} "="; - - printf{(i,j,k,l) in Eh: i = row and col >= j and col < l and - xe1[i,j,k,l] = 0 and xe2[i,j,k,l] = 0} " "; - printf{0..0: card({(i,j,k,l) in Eh: i = row and col >= j and col < l}) = 0} " "; - } - printf "\n"; - for { col in cols } { - printf{(i,j,k,l) in Ev: j = col and row >= i and row < k and xe1[i,j,k,l] = 1} "|"; - printf{(i,j,k,l) in Ev: j = col and row >= i and row < k and xe2[i,j,k,l] = 1} '"'; - printf{(i,j,k,l) in Ev: j = col and row >= i and row < k and - xe1[i,j,k,l] = 0 and xe2[i,j,k,l] = 0} " "; - /* No vertical edges: skip also a field */ - printf{0..0: card({(i,j,k,l) in Ev: j = col and row >= i and row < k}) = 0} " "; - printf " "; - } - printf "\n"; -} - -data; - -/* This is a difficult 25x25 Hashiwokakero. - */ -param givens : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 -25 := - 1 2 . 2 . 2 . . 2 . 2 . . 2 . . . . 2 . 2 . 2 . 2 . - 2 . 1 . . . . 2 . . . 4 . . 5 . 2 . . 1 . 2 . 2 . 1 - 3 2 . . 5 . 4 . . 3 . . . . . 1 . . 4 . 5 . 1 . 1 . - 4 . . . . . . . . . . . 1 . 3 . . 1 . . . . . . . . - 5 2 . . 6 . 6 . . 8 . 5 . 2 . . 3 . 5 . 7 . . 2 . . - 6 . 1 . . . . . . . . . 1 . . 2 . . . . . 1 . . . 3 - 7 2 . . . . 5 . . 6 . 4 . . 2 . . . 2 . 5 . 4 . 2 . - 8 . 2 . 2 . . . . . . . . . . . 3 . . 3 . . . 1 . 2 - 9 . . . . . . . . . . 4 . 2 . 2 . . 1 . . . 3 . 1 . - 10 2 . 3 . . 6 . . 2 . . . . . . . . . . 3 . . . . . - 11 . . . . 1 . . 2 . . 5 . . 1 . 4 . 3 . . . . 2 . 4 - 12 . . 2 . . 1 . . . . . . 5 . 4 . . . . 4 . 3 . . . - 13 2 . . . 3 . 1 . . . . . . . . 3 . . 5 . 5 . . 2 . - 14 . . . . . 2 . 5 . . 7 . 5 . 3 . 1 . . 1 . . 1 . 4 - 15 2 . 5 . 3 . . . . 1 . 2 . 1 . . . . 2 . 4 . . 2 . - 16 . . . . . 1 . . . . . . . . . . 2 . . 2 . 1 . . 3 - 17 2 . 6 . 6 . . 2 . . 2 . 2 . 5 . . . . . 2 . . . . - 18 . . . . . 1 . . . 3 . . . . . 1 . . 1 . . 4 . 3 . - 19 . . 4 . 5 . . 2 . . . 2 . . 6 . 6 . . 3 . . . . 3 - 20 2 . . . . . . . . . 2 . . 1 . . . . . . 1 . . 1 . - 21 . . 3 . . 3 . 5 . 5 . . 4 . 6 . 7 . . 4 . 6 . . 4 - 22 2 . . . 3 . 5 . 2 . 1 . . . . . . . . . . . . . . - 23 . . . . . . . . . 1 . . . . . . 3 . 2 . . 5 . . 5 - 24 2 . 3 . 3 . 5 . 4 . 3 . 3 . 4 . . 2 . 2 . . . 1 . - 25 . 1 . 2 . 2 . . . 2 . 2 . . . 2 . . . . 2 . 2 . 2 - ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/huge.mod b/resources/3rdparty/glpk-4.53/examples/huge.mod deleted file mode 100644 index a7d17e4c5..000000000 --- a/resources/3rdparty/glpk-4.53/examples/huge.mod +++ /dev/null @@ -1,25 +0,0 @@ -/*Arithmetic Mean of a large number of Integers - - or - solve a very large constraint matrix - over 1 million rows and columns - Nigel_Galloway@operamail.com - March 18th., 2008. -*/ - -param e := 20; -/* set Sample := {-2**e..2**e-1}; */ -set Sample := {1..2**e-1}; - -var Mean; -var E{z in Sample}; - -/* sum of variances is zero */ -zumVariance: sum{z in Sample} E[z] = 0; - -/* Mean + variance[n] = Sample[n] */ -variances{z in Sample}: Mean + E[z] = z; - -solve; - -printf "The arithmetic mean of the integers from 1 to %d is %f\n", 2**e-1, Mean; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/iptsamp.c b/resources/3rdparty/glpk-4.53/examples/iptsamp.c deleted file mode 100644 index d622d7361..000000000 --- a/resources/3rdparty/glpk-4.53/examples/iptsamp.c +++ /dev/null @@ -1,17 +0,0 @@ -/* iptsamp.c */ - -#include -#include -#include - -int main(void) -{ glp_prob *P; - P = glp_create_prob(); - glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); - glp_interior(P, NULL); - glp_print_ipt(P, "25fv47.txt"); - glp_delete_prob(P); - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/examples/jssp.mod b/resources/3rdparty/glpk-4.53/examples/jssp.mod deleted file mode 100644 index 7ee51b989..000000000 --- a/resources/3rdparty/glpk-4.53/examples/jssp.mod +++ /dev/null @@ -1,114 +0,0 @@ -/* JSSP, Job-Shop Scheduling Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* The Job-Shop Scheduling Problem (JSSP) is to schedule a set of jobs - on a set of machines, subject to the constraint that each machine can - handle at most one job at a time and the fact that each job has a - specified processing order through the machines. The objective is to - schedule the jobs so as to minimize the maximum of their completion - times. - - Reference: - D. Applegate and W. Cook, "A Computational Study of the Job-Shop - Scheduling Problem", ORSA J. On Comput., Vol. 3, No. 2, Spring 1991, - pp. 149-156. */ - -param n, integer, > 0; -/* number of jobs */ - -param m, integer, > 0; -/* number of machines */ - -set J := 1..n; -/* set of jobs */ - -set M := 1..m; -/* set of machines */ - -param sigma{j in J, t in 1..m}, in M; -/* permutation of the machines, which represents the processing order - of j through the machines: j must be processed first on sigma[j,1], - then on sigma[j,2], etc. */ - -check{j in J, t1 in 1..m, t2 in 1..m: t1 <> t2}: - sigma[j,t1] != sigma[j,t2]; -/* sigma must be permutation */ - -param p{j in J, a in M}, >= 0; -/* processing time of j on a */ - -var x{j in J, a in M}, >= 0; -/* starting time of j on a */ - -s.t. ord{j in J, t in 2..m}: - x[j, sigma[j,t]] >= x[j, sigma[j,t-1]] + p[j, sigma[j,t-1]]; -/* j can be processed on sigma[j,t] only after it has been completely - processed on sigma[j,t-1] */ - -/* The disjunctive condition that each machine can handle at most one - job at a time is the following: - - x[i,a] >= x[j,a] + p[j,a] or x[j,a] >= x[i,a] + p[i,a] - - for all i, j in J, a in M. This condition is modeled through binary - variables Y as shown below. */ - -var Y{i in J, j in J, a in M}, binary; -/* Y[i,j,a] is 1 if i scheduled before j on machine a, and 0 if j is - scheduled before i */ - -param K := sum{j in J, a in M} p[j,a]; -/* some large constant */ - -display K; - -s.t. phi{i in J, j in J, a in M: i <> j}: - x[i,a] >= x[j,a] + p[j,a] - K * Y[i,j,a]; -/* x[i,a] >= x[j,a] + p[j,a] iff Y[i,j,a] is 0 */ - -s.t. psi{i in J, j in J, a in M: i <> j}: - x[j,a] >= x[i,a] + p[i,a] - K * (1 - Y[i,j,a]); -/* x[j,a] >= x[i,a] + p[i,a] iff Y[i,j,a] is 1 */ - -var z; -/* so-called makespan */ - -s.t. fin{j in J}: z >= x[j, sigma[j,m]] + p[j, sigma[j,m]]; -/* which is the maximum of the completion times of all the jobs */ - -minimize obj: z; -/* the objective is to make z as small as possible */ - -data; - -/* These data correspond to the instance ft06 (mt06) from: - - H. Fisher, G.L. Thompson (1963), Probabilistic learning combinations - of local job-shop scheduling rules, J.F. Muth, G.L. Thompson (eds.), - Industrial Scheduling, Prentice Hall, Englewood Cliffs, New Jersey, - 225-251 */ - -/* The optimal solution is 55 */ - -param n := 6; - -param m := 6; - -param sigma : 1 2 3 4 5 6 := - 1 3 1 2 4 6 5 - 2 2 3 5 6 1 4 - 3 3 4 6 1 2 5 - 4 2 1 3 4 5 6 - 5 3 2 5 6 1 4 - 6 2 4 6 1 5 3 ; - -param p : 1 2 3 4 5 6 := - 1 3 6 1 7 6 3 - 2 10 8 5 4 10 10 - 3 9 1 5 4 7 8 - 4 5 5 5 3 8 9 - 5 3 3 9 1 5 4 - 6 10 3 1 3 4 9 ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/magic.mod b/resources/3rdparty/glpk-4.53/examples/magic.mod deleted file mode 100644 index d1e64d018..000000000 --- a/resources/3rdparty/glpk-4.53/examples/magic.mod +++ /dev/null @@ -1,54 +0,0 @@ -/* MAGIC, Magic Square */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* In recreational mathematics, a magic square of order n is an - arrangement of n^2 numbers, usually distinct integers, in a square, - such that n numbers in all rows, all columns, and both diagonals sum - to the same constant. A normal magic square contains the integers - from 1 to n^2. - - (From Wikipedia, the free encyclopedia.) */ - -param n, integer, > 0, default 4; -/* square order */ - -set N := 1..n^2; -/* integers to be placed */ - -var x{i in 1..n, j in 1..n, k in N}, binary; -/* x[i,j,k] = 1 means that cell (i,j) contains integer k */ - -s.t. a{i in 1..n, j in 1..n}: sum{k in N} x[i,j,k] = 1; -/* each cell must be assigned exactly one integer */ - -s.t. b{k in N}: sum{i in 1..n, j in 1..n} x[i,j,k] = 1; -/* each integer must be assigned exactly to one cell */ - -var s; -/* the magic sum */ - -s.t. r{i in 1..n}: sum{j in 1..n, k in N} k * x[i,j,k] = s; -/* the sum in each row must be the magic sum */ - -s.t. c{j in 1..n}: sum{i in 1..n, k in N} k * x[i,j,k] = s; -/* the sum in each column must be the magic sum */ - -s.t. d: sum{i in 1..n, k in N} k * x[i,i,k] = s; -/* the sum in the diagonal must be the magic sum */ - -s.t. e: sum{i in 1..n, k in N} k * x[i,n-i+1,k] = s; -/* the sum in the co-diagonal must be the magic sum */ - -solve; - -printf "\n"; -printf "Magic sum is %d\n", s; -printf "\n"; -for{i in 1..n} -{ printf{j in 1..n} "%3d", sum{k in N} k * x[i,j,k]; - printf "\n"; -} -printf "\n"; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/maxcut.mod b/resources/3rdparty/glpk-4.53/examples/maxcut.mod deleted file mode 100644 index db30b92e5..000000000 --- a/resources/3rdparty/glpk-4.53/examples/maxcut.mod +++ /dev/null @@ -1,85 +0,0 @@ -/* MAXCUT, Maximum Cut Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* The Maximum Cut Problem in a network G = (V, E), where V is a set - of nodes, E is a set of edges, is to find the partition of V into - disjoint sets V1 and V2, which maximizes the sum of edge weights - w(e), where edge e has one endpoint in V1 and other endpoint in V2. - - Reference: - Garey, M.R., and Johnson, D.S. (1979), Computers and Intractability: - A guide to the theory of NP-completeness [Network design, Cuts and - Connectivity, Maximum Cut, ND16]. */ - -set E, dimen 2; -/* set of edges */ - -param w{(i,j) in E}, >= 0, default 1; -/* w[i,j] is weight of edge (i,j) */ - -set V := (setof{(i,j) in E} i) union (setof{(i,j) in E} j); -/* set of nodes */ - -var x{i in V}, binary; -/* x[i] = 0 means that node i is in set V1 - x[i] = 1 means that node i is in set V2 */ - -/* We need to include in the objective function only that edges (i,j) - from E, for which x[i] != x[j]. This can be modeled through binary - variables s[i,j] as follows: - - s[i,j] = x[i] xor x[j] = (x[i] + x[j]) mod 2, (1) - - where s[i,j] = 1 iff x[i] != x[j], that leads to the following - objective function: - - z = sum{(i,j) in E} w[i,j] * s[i,j]. (2) - - To describe "exclusive or" (1) we could think that s[i,j] is a minor - bit of the sum x[i] + x[j]. Then introducing binary variables t[i,j], - which represent a major bit of the sum x[i] + x[j], we can write: - - x[i] + x[j] = s[i,j] + 2 * t[i,j]. (3) - - An easy check shows that conditions (1) and (3) are equivalent. - - Note that condition (3) can be simplified by eliminating variables - s[i,j]. Indeed, from (3) it follows that: - - s[i,j] = x[i] + x[j] - 2 * t[i,j]. (4) - - Since the expression in the right-hand side of (4) is integral, this - condition can be rewritten in the equivalent form: - - 0 <= x[i] + x[j] - 2 * t[i,j] <= 1. (5) - - (One might note that (5) means t[i,j] = x[i] and x[j].) - - Substituting s[i,j] from (4) to (2) leads to the following objective - function: - - z = sum{(i,j) in E} w[i,j] * (x[i] + x[j] - 2 * t[i,j]), (6) - - which does not include variables s[i,j]. */ - -var t{(i,j) in E}, binary; -/* t[i,j] = x[i] and x[j] = (x[i] + x[j]) div 2 */ - -s.t. xor{(i,j) in E}: 0 <= x[i] + x[j] - 2 * t[i,j] <= 1; -/* see (4) */ - -maximize z: sum{(i,j) in E} w[i,j] * (x[i] + x[j] - 2 * t[i,j]); -/* see (6) */ - -data; - -/* In this example the network has 15 nodes and 22 edges. */ - -/* Optimal solution is 20 */ - -set E := - 1 2, 1 5, 2 3, 2 6, 3 4, 3 8, 4 9, 5 6, 5 7, 6 8, 7 8, 7 12, 8 9, - 8 12, 9 10, 9 14, 10 11, 10 14, 11 15, 12 13, 13 14, 14 15; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/maxflow.mod b/resources/3rdparty/glpk-4.53/examples/maxflow.mod deleted file mode 100644 index 20dfc3ee2..000000000 --- a/resources/3rdparty/glpk-4.53/examples/maxflow.mod +++ /dev/null @@ -1,83 +0,0 @@ -/* MAXFLOW, Maximum Flow Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* The Maximum Flow Problem in a network G = (V, E), where V is a set - of nodes, E within V x V is a set of arcs, is to maximize the flow - from one given node s (source) to another given node t (sink) subject - to conservation of flow constraints at each node and flow capacities - on each arc. */ - -param n, integer, >= 2; -/* number of nodes */ - -set V, default {1..n}; -/* set of nodes */ - -set E, within V cross V; -/* set of arcs */ - -param a{(i,j) in E}, > 0; -/* a[i,j] is capacity of arc (i,j) */ - -param s, symbolic, in V, default 1; -/* source node */ - -param t, symbolic, in V, != s, default n; -/* sink node */ - -var x{(i,j) in E}, >= 0, <= a[i,j]; -/* x[i,j] is elementary flow through arc (i,j) to be found */ - -var flow, >= 0; -/* total flow from s to t */ - -s.t. node{i in V}: -/* node[i] is conservation constraint for node i */ - - sum{(j,i) in E} x[j,i] + (if i = s then flow) - /* summary flow into node i through all ingoing arcs */ - - = /* must be equal to */ - - sum{(i,j) in E} x[i,j] + (if i = t then flow); - /* summary flow from node i through all outgoing arcs */ - -maximize obj: flow; -/* objective is to maximize the total flow through the network */ - -solve; - -printf{1..56} "="; printf "\n"; -printf "Maximum flow from node %s to node %s is %g\n\n", s, t, flow; -printf "Starting node Ending node Arc capacity Flow in arc\n"; -printf "------------- ----------- ------------ -----------\n"; -printf{(i,j) in E: x[i,j] != 0}: "%13s %11s %12g %11g\n", i, j, - a[i,j], x[i,j]; -printf{1..56} "="; printf "\n"; - -data; - -/* These data correspond to an example from [Christofides]. */ - -/* Optimal solution is 29 */ - -param n := 9; - -param : E : a := - 1 2 14 - 1 4 23 - 2 3 10 - 2 4 9 - 3 5 12 - 3 8 18 - 4 5 26 - 5 2 11 - 5 6 25 - 5 7 4 - 6 7 7 - 6 8 8 - 7 9 15 - 8 9 20; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/mfasp.mod b/resources/3rdparty/glpk-4.53/examples/mfasp.mod deleted file mode 100644 index b4382818a..000000000 --- a/resources/3rdparty/glpk-4.53/examples/mfasp.mod +++ /dev/null @@ -1,62 +0,0 @@ -/* MFASP, Minimum Feedback Arc Set Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* The Minimum Feedback Arc Set Problem for a given directed graph - G = (V, E), where V is a set of vertices and E is a set of arcs, is - to find a minimal subset of arcs, which being removed from the graph - make it acyclic. - - Reference: - Garey, M.R., and Johnson, D.S. (1979), Computers and Intractability: - A guide to the theory of NP-completeness [Graph Theory, Covering and - Partitioning, Minimum Feedback Arc Set, GT9]. */ - -param n, integer, >= 0; -/* number of vertices */ - -set V, default 1..n; -/* set of vertices */ - -set E, within V cross V, -default setof{i in V, j in V: i <> j and Uniform(0,1) <= 0.15} (i,j); -/* set of arcs */ - -printf "Graph has %d vertices and %d arcs\n", card(V), card(E); - -var x{(i,j) in E}, binary; -/* x[i,j] = 1 means that (i->j) is a feedback arc */ - -/* It is known that a digraph G = (V, E) is acyclic if and only if its - vertices can be assigned numbers from 1 to |V| in such a way that - k[i] + 1 <= k[j] for every arc (i->j) in E, where k[i] is a number - assigned to vertex i. We may use this condition to require that the - digraph G = (V, E \ E'), where E' is a subset of feedback arcs, is - acyclic. */ - -var k{i in V}, >= 1, <= card(V); -/* k[i] is a number assigned to vertex i */ - -s.t. r{(i,j) in E}: k[j] - k[i] >= 1 - card(V) * x[i,j]; -/* note that x[i,j] = 1 leads to a redundant constraint */ - -minimize obj: sum{(i,j) in E} x[i,j]; -/* the objective is to minimize the cardinality of a subset of feedback - arcs */ - -solve; - -printf "Minimum feedback arc set:\n"; -printf{(i,j) in E: x[i,j]} "%d %d\n", i, j; - -data; - -/* The optimal solution is 3 */ - -param n := 15; - -set E := 1 2, 2 3, 3 4, 3 8, 4 9, 5 1, 6 5, 7 5, 8 6, 8 7, 8 9, 9 10, - 10 11, 10 14, 11 15, 12 7, 12 8, 12 13, 13 8, 13 12, 13 14, - 14 9, 15 14; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/mfvsp.mod b/resources/3rdparty/glpk-4.53/examples/mfvsp.mod deleted file mode 100644 index a03009dea..000000000 --- a/resources/3rdparty/glpk-4.53/examples/mfvsp.mod +++ /dev/null @@ -1,62 +0,0 @@ -/* MFVSP, Minimum Feedback Vertex Set Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* The Minimum Feedback Vertex Set Problem for a given directed graph - G = (V, E), where V is a set of vertices and E is a set of arcs, is - to find a minimal subset of vertices, which being removed from the - graph make it acyclic. - - Reference: - Garey, M.R., and Johnson, D.S. (1979), Computers and Intractability: - A guide to the theory of NP-completeness [Graph Theory, Covering and - Partitioning, Minimum Feedback Vertex Set, GT8]. */ - -param n, integer, >= 0; -/* number of vertices */ - -set V, default 1..n; -/* set of vertices */ - -set E, within V cross V, -default setof{i in V, j in V: i <> j and Uniform(0,1) <= 0.15} (i,j); -/* set of arcs */ - -printf "Graph has %d vertices and %d arcs\n", card(V), card(E); - -var x{i in V}, binary; -/* x[i] = 1 means that i is a feedback vertex */ - -/* It is known that a digraph G = (V, E) is acyclic if and only if its - vertices can be assigned numbers from 1 to |V| in such a way that - k[i] + 1 <= k[j] for every arc (i->j) in E, where k[i] is a number - assigned to vertex i. We may use this condition to require that the - digraph G = (V, E \ E'), where E' is a subset of feedback arcs, is - acyclic. */ - -var k{i in V}, >= 1, <= card(V); -/* k[i] is a number assigned to vertex i */ - -s.t. r{(i,j) in E}: k[j] - k[i] >= 1 - card(V) * (x[i] + x[j]); -/* note that x[i] = 1 or x[j] = 1 leads to a redundant constraint */ - -minimize obj: sum{i in V} x[i]; -/* the objective is to minimize the cardinality of a subset of feedback - vertices */ - -solve; - -printf "Minimum feedback vertex set:\n"; -printf{i in V: x[i]} "%d\n", i; - -data; - -/* The optimal solution is 3 */ - -param n := 15; - -set E := 1 2, 2 3, 3 4, 3 8, 4 9, 5 1, 6 5, 7 5, 8 6, 8 7, 8 9, 9 10, - 10 11, 10 14, 11 15, 12 7, 12 8, 12 13, 13 8, 13 12, 13 14, - 14 9, 15 14; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/min01ks.mod b/resources/3rdparty/glpk-4.53/examples/min01ks.mod deleted file mode 100644 index 4baa3f406..000000000 --- a/resources/3rdparty/glpk-4.53/examples/min01ks.mod +++ /dev/null @@ -1,111 +0,0 @@ -/* min01ks.mod - finding minimal equivalent 0-1 knapsack inequality */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* It is obvious that for a given 0-1 knapsack inequality - - a[1] x[1] + ... + a[n] x[n] <= b, x[j] in {0, 1} (1) - - there exist infinitely many equivalent inequalities with exactly the - same feasible solutions. - - Given a[j]'s and b this model allows to find an inequality - - alfa[1] x[1] + ... + alfa[n] x[n] <= beta, x[j] in {0, 1}, (2) - - which is equivalent to (1) and where alfa[j]'s and beta are smallest - non-negative integers. - - This model has the following formulation: - - minimize - - z = |alfa[1]| + ... + |alfa[n]| + |beta| = (3) - - = alfa[1] + ... + alfa[n] + beta - - subject to - - alfa[1] x[1] + ... + alfa[n] x[n] <= beta (4) - - for all x satisfying to (1) - - alfa[1] x[1] + ... + alfa[n] x[n] >= beta + 1 (5) - - for all x not satisfying to (1) - - alfa[1], ..., alfa[n], beta are non-negative integers. - - Note that this model has n+1 variables and 2^n constraints. - - It is interesting, as noticed in [1] and explained in [2], that - in most cases LP relaxation of the MIP formulation above has integer - optimal solution. - - References - - 1. G.H.Bradley, P.L.Hammer, L.Wolsey, "Coefficient Reduction for - Inequalities in 0-1 Variables", Math.Prog.7 (1974), 263-282. - - 2. G.J.Koehler, "A Study on Coefficient Reduction of Binary Knapsack - Inequalities", University of Florida, 2001. */ - -param n, integer, > 0; -/* number of variables in the knapsack inequality */ - -set N := 1..n; -/* set of knapsack items */ - -/* all binary n-vectors are numbered by 0, 1, ..., 2^n-1, where vector - 0 is 00...00, vector 1 is 00...01, etc. */ - -set U := 0..2^n-1; -/* set of numbers of all binary n-vectors */ - -param x{i in U, j in N}, binary, := (i div 2^(j-1)) mod 2; -/* x[i,j] is j-th component of i-th binary n-vector */ - -param a{j in N}, >= 0; -/* original coefficients */ - -param b, >= 0; -/* original right-hand side */ - -set D := setof{i in U: sum{j in N} a[j] * x[i,j] <= b} i; -/* set of numbers of binary n-vectors, which (vectors) are feasible, - i.e. satisfy to the original knapsack inequality (1) */ - -var alfa{j in N}, integer, >= 0; -/* coefficients to be found */ - -var beta, integer, >= 0; -/* right-hand side to be found */ - -minimize z: sum{j in N} alfa[j] + beta; /* (3) */ - -phi{i in D}: sum{j in N} alfa[j] * x[i,j] <= beta; /* (4) */ - -psi{i in U diff D}: sum{j in N} alfa[j] * x[i,j] >= beta + 1; /* (5) */ - -solve; - -printf "\nOriginal 0-1 knapsack inequality:\n"; -for {j in 1..n} printf (if j = 1 then "" else " + ") & "%g x%d", - a[j], j; -printf " <= %g\n", b; -printf "\nMinimized equivalent inequality:\n"; -for {j in 1..n} printf (if j = 1 then "" else " + ") & "%g x%d", - alfa[j], j; -printf " <= %g\n\n", beta; - -data; - -/* These data correspond to the very first example from [1]. */ - -param n := 8; - -param a := [1]65, [2]64, [3]41, [4]22, [5]13, [6]12, [7]8, [8]2; - -param b := 80; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/misp.mod b/resources/3rdparty/glpk-4.53/examples/misp.mod deleted file mode 100644 index b2b1f6b94..000000000 --- a/resources/3rdparty/glpk-4.53/examples/misp.mod +++ /dev/null @@ -1,665 +0,0 @@ -/* MISP, Maximum Independent Set Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* Let G = (V,E) be an undirected graph with vertex set V and edge set - * E. Vertices u, v in V are non-adjacent if (u,v) not in E. A subset - * of the vertices S within V is independent if all vertices in S are - * pairwise non-adjacent. The Maximum Independent Set Problem (MISP) is - * to find an independent set having the largest cardinality. */ - -param n, integer, > 0; -/* number of vertices */ - -set V := 1..n; -/* set of vertices */ - -set E within V cross V; -/* set of edges */ - -var x{i in V}, binary; -/* x[i] = 1 means vertex i belongs to independent set */ - -s.t. edge{(i,j) in E}: x[i] + x[j] <= 1; -/* if there is edge (i,j), vertices i and j cannot belong to the same - independent set */ - -maximize obj: sum{i in V} x[i]; -/* the objective is to maximize the cardinality of independent set */ - -data; - -/* These data corresponds to the test instance from: - * - * M.G.C. Resende, T.A.Feo, S.H.Smith, "Algorithm 787 -- FORTRAN - * subroutines for approximate solution of the maximum independent set - * problem using GRASP," Trans. on Math. Softw., Vol. 24, No. 4, - * December 1998, pp. 386-394. */ - -/* The optimal solution is 7. */ - -param n := 50; - -set E := - 1 2 - 1 3 - 1 5 - 1 7 - 1 8 - 1 12 - 1 15 - 1 16 - 1 19 - 1 20 - 1 21 - 1 22 - 1 28 - 1 30 - 1 34 - 1 35 - 1 37 - 1 41 - 1 42 - 1 47 - 1 50 - 2 3 - 2 5 - 2 6 - 2 7 - 2 8 - 2 9 - 2 10 - 2 13 - 2 17 - 2 19 - 2 20 - 2 21 - 2 23 - 2 25 - 2 26 - 2 29 - 2 31 - 2 35 - 2 36 - 2 44 - 2 45 - 2 46 - 2 50 - 3 5 - 3 6 - 3 8 - 3 9 - 3 10 - 3 11 - 3 14 - 3 16 - 3 23 - 3 24 - 3 26 - 3 27 - 3 28 - 3 29 - 3 30 - 3 31 - 3 34 - 3 35 - 3 36 - 3 39 - 3 41 - 3 42 - 3 43 - 3 44 - 3 50 - 4 6 - 4 7 - 4 9 - 4 10 - 4 11 - 4 13 - 4 14 - 4 15 - 4 17 - 4 21 - 4 22 - 4 23 - 4 24 - 4 25 - 4 27 - 4 28 - 4 30 - 4 31 - 4 33 - 4 34 - 4 35 - 4 36 - 4 37 - 4 38 - 4 40 - 4 41 - 4 42 - 4 46 - 4 49 - 5 6 - 5 11 - 5 14 - 5 21 - 5 24 - 5 25 - 5 28 - 5 35 - 5 38 - 5 39 - 5 41 - 5 44 - 5 49 - 5 50 - 6 8 - 6 9 - 6 10 - 6 13 - 6 14 - 6 16 - 6 17 - 6 19 - 6 22 - 6 23 - 6 26 - 6 27 - 6 30 - 6 34 - 6 35 - 6 38 - 6 39 - 6 40 - 6 41 - 6 44 - 6 45 - 6 47 - 6 50 - 7 8 - 7 9 - 7 10 - 7 11 - 7 13 - 7 15 - 7 16 - 7 18 - 7 20 - 7 22 - 7 23 - 7 24 - 7 25 - 7 33 - 7 35 - 7 36 - 7 38 - 7 43 - 7 45 - 7 46 - 7 47 - 8 10 - 8 11 - 8 13 - 8 16 - 8 17 - 8 18 - 8 19 - 8 20 - 8 21 - 8 22 - 8 23 - 8 24 - 8 25 - 8 26 - 8 33 - 8 35 - 8 36 - 8 39 - 8 42 - 8 44 - 8 48 - 8 49 - 9 12 - 9 14 - 9 17 - 9 19 - 9 20 - 9 23 - 9 28 - 9 30 - 9 31 - 9 32 - 9 33 - 9 34 - 9 38 - 9 39 - 9 42 - 9 44 - 9 45 - 9 46 - 10 11 - 10 13 - 10 15 - 10 16 - 10 17 - 10 20 - 10 21 - 10 22 - 10 23 - 10 25 - 10 26 - 10 27 - 10 28 - 10 30 - 10 31 - 10 32 - 10 37 - 10 38 - 10 41 - 10 43 - 10 44 - 10 45 - 10 50 - 11 12 - 11 14 - 11 15 - 11 18 - 11 21 - 11 24 - 11 25 - 11 26 - 11 29 - 11 32 - 11 33 - 11 35 - 11 36 - 11 37 - 11 39 - 11 40 - 11 42 - 11 43 - 11 45 - 11 47 - 11 49 - 11 50 - 12 13 - 12 16 - 12 17 - 12 19 - 12 24 - 12 25 - 12 26 - 12 30 - 12 31 - 12 32 - 12 34 - 12 36 - 12 37 - 12 39 - 12 41 - 12 44 - 12 47 - 12 48 - 12 49 - 13 15 - 13 16 - 13 18 - 13 19 - 13 20 - 13 22 - 13 23 - 13 24 - 13 27 - 13 28 - 13 29 - 13 31 - 13 33 - 13 35 - 13 36 - 13 37 - 13 44 - 13 47 - 13 49 - 13 50 - 14 15 - 14 16 - 14 17 - 14 18 - 14 19 - 14 20 - 14 21 - 14 26 - 14 28 - 14 29 - 14 30 - 14 31 - 14 32 - 14 34 - 14 35 - 14 36 - 14 38 - 14 39 - 14 41 - 14 44 - 14 46 - 14 47 - 14 48 - 15 18 - 15 21 - 15 22 - 15 23 - 15 25 - 15 28 - 15 29 - 15 30 - 15 33 - 15 34 - 15 36 - 15 37 - 15 38 - 15 39 - 15 40 - 15 43 - 15 44 - 15 46 - 15 50 - 16 17 - 16 19 - 16 20 - 16 25 - 16 26 - 16 29 - 16 35 - 16 38 - 16 39 - 16 40 - 16 41 - 16 42 - 16 44 - 17 18 - 17 19 - 17 21 - 17 22 - 17 23 - 17 25 - 17 26 - 17 28 - 17 29 - 17 33 - 17 37 - 17 44 - 17 45 - 17 48 - 18 20 - 18 24 - 18 27 - 18 28 - 18 31 - 18 32 - 18 34 - 18 35 - 18 36 - 18 37 - 18 38 - 18 45 - 18 48 - 18 49 - 18 50 - 19 22 - 19 24 - 19 28 - 19 29 - 19 36 - 19 37 - 19 39 - 19 41 - 19 43 - 19 45 - 19 48 - 19 49 - 20 21 - 20 22 - 20 24 - 20 25 - 20 26 - 20 27 - 20 29 - 20 30 - 20 31 - 20 33 - 20 34 - 20 35 - 20 38 - 20 39 - 20 41 - 20 42 - 20 43 - 20 44 - 20 45 - 20 46 - 20 48 - 20 49 - 21 22 - 21 23 - 21 29 - 21 31 - 21 35 - 21 38 - 21 42 - 21 46 - 21 47 - 22 23 - 22 26 - 22 27 - 22 28 - 22 29 - 22 30 - 22 39 - 22 40 - 22 41 - 22 42 - 22 44 - 22 45 - 22 46 - 22 47 - 22 49 - 22 50 - 23 28 - 23 31 - 23 32 - 23 33 - 23 34 - 23 35 - 23 36 - 23 39 - 23 40 - 23 41 - 23 42 - 23 44 - 23 45 - 23 48 - 23 49 - 23 50 - 24 25 - 24 27 - 24 29 - 24 30 - 24 31 - 24 33 - 24 34 - 24 38 - 24 42 - 24 43 - 24 44 - 24 49 - 24 50 - 25 26 - 25 27 - 25 29 - 25 30 - 25 33 - 25 34 - 25 36 - 25 38 - 25 40 - 25 41 - 25 42 - 25 44 - 25 46 - 25 47 - 25 48 - 25 49 - 26 28 - 26 31 - 26 32 - 26 33 - 26 37 - 26 38 - 26 39 - 26 40 - 26 41 - 26 42 - 26 45 - 26 47 - 26 48 - 26 49 - 27 29 - 27 30 - 27 33 - 27 34 - 27 35 - 27 39 - 27 40 - 27 46 - 27 48 - 28 29 - 28 37 - 28 40 - 28 42 - 28 44 - 28 46 - 28 47 - 28 50 - 29 35 - 29 38 - 29 39 - 29 41 - 29 42 - 29 48 - 30 31 - 30 32 - 30 35 - 30 37 - 30 38 - 30 40 - 30 43 - 30 45 - 30 46 - 30 47 - 30 48 - 31 33 - 31 35 - 31 38 - 31 40 - 31 41 - 31 42 - 31 44 - 31 46 - 31 47 - 31 50 - 32 33 - 32 35 - 32 39 - 32 40 - 32 46 - 32 49 - 32 50 - 33 34 - 33 36 - 33 37 - 33 40 - 33 42 - 33 43 - 33 44 - 33 45 - 33 50 - 34 35 - 34 36 - 34 37 - 34 38 - 34 40 - 34 43 - 34 44 - 34 49 - 34 50 - 35 36 - 35 38 - 35 41 - 35 42 - 35 43 - 35 45 - 35 46 - 35 47 - 35 49 - 35 50 - 36 37 - 36 39 - 36 40 - 36 41 - 36 42 - 36 43 - 36 48 - 36 50 - 37 38 - 37 41 - 37 43 - 37 46 - 37 47 - 37 48 - 37 49 - 37 50 - 38 41 - 38 45 - 38 46 - 38 48 - 38 49 - 38 50 - 39 43 - 39 46 - 39 47 - 39 48 - 39 49 - 40 43 - 40 45 - 40 48 - 40 50 - 41 42 - 41 43 - 41 44 - 41 45 - 41 46 - 41 48 - 41 49 - 42 43 - 42 44 - 42 46 - 42 48 - 42 49 - 43 45 - 43 46 - 43 48 - 43 50 - 44 45 - 44 48 - 45 46 - 45 47 - 45 48 - 46 49 - 47 49 - 47 50 - 48 49 - 48 50 - 49 50 -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/misp1.dat b/resources/3rdparty/glpk-4.53/examples/misp1.dat deleted file mode 100644 index 2c2ed1ba5..000000000 --- a/resources/3rdparty/glpk-4.53/examples/misp1.dat +++ /dev/null @@ -1,1489 +0,0 @@ -/* misp1.dat (data for misp.mod to illustrate clique cuts) */ - -/* These data corresponds to the test instance 1dc.128 (graphs from - * single-deletion-correcting codes) from: - * - * N.J.A.Sloane, "Challenge Problems: Independent Sets In Graphs." - * http://neilsloane.com/doc/graphs.html (June 2013). */ - -/* Optimal solution is 16. */ - -data; - -param n := 128; - -set E := /* 1471 edges */ - 1 2 - 1 3 - 1 5 - 1 9 - 1 17 - 1 33 - 1 65 - 2 3 - 2 4 - 2 5 - 2 6 - 2 9 - 2 10 - 2 17 - 2 18 - 2 33 - 2 34 - 2 65 - 2 66 - 3 4 - 3 5 - 3 6 - 3 7 - 3 9 - 3 10 - 3 11 - 3 17 - 3 18 - 3 19 - 3 33 - 3 34 - 3 35 - 3 65 - 3 66 - 3 67 - 4 6 - 4 7 - 4 8 - 4 10 - 4 12 - 4 18 - 4 20 - 4 34 - 4 36 - 4 66 - 4 68 - 5 6 - 5 7 - 5 9 - 5 10 - 5 11 - 5 13 - 5 17 - 5 19 - 5 21 - 5 33 - 5 35 - 5 37 - 5 65 - 5 67 - 5 69 - 6 7 - 6 8 - 6 10 - 6 11 - 6 12 - 6 14 - 6 18 - 6 19 - 6 20 - 6 22 - 6 34 - 6 35 - 6 36 - 6 38 - 6 66 - 6 67 - 6 68 - 6 70 - 7 8 - 7 11 - 7 12 - 7 13 - 7 14 - 7 15 - 7 19 - 7 20 - 7 23 - 7 35 - 7 36 - 7 39 - 7 67 - 7 68 - 7 71 - 8 12 - 8 14 - 8 15 - 8 16 - 8 20 - 8 24 - 8 36 - 8 40 - 8 68 - 8 72 - 9 10 - 9 11 - 9 13 - 9 17 - 9 18 - 9 19 - 9 21 - 9 25 - 9 33 - 9 37 - 9 41 - 9 65 - 9 69 - 9 73 - 10 11 - 10 12 - 10 13 - 10 14 - 10 18 - 10 19 - 10 20 - 10 21 - 10 22 - 10 26 - 10 34 - 10 37 - 10 38 - 10 42 - 10 66 - 10 69 - 10 70 - 10 74 - 11 12 - 11 13 - 11 14 - 11 15 - 11 19 - 11 21 - 11 22 - 11 23 - 11 27 - 11 35 - 11 37 - 11 38 - 11 39 - 11 43 - 11 67 - 11 69 - 11 70 - 11 71 - 11 75 - 12 14 - 12 15 - 12 16 - 12 20 - 12 22 - 12 23 - 12 24 - 12 28 - 12 36 - 12 38 - 12 40 - 12 44 - 12 68 - 12 70 - 12 72 - 12 76 - 13 14 - 13 15 - 13 21 - 13 23 - 13 25 - 13 26 - 13 27 - 13 29 - 13 37 - 13 39 - 13 45 - 13 69 - 13 71 - 13 77 - 14 15 - 14 16 - 14 22 - 14 23 - 14 24 - 14 26 - 14 27 - 14 28 - 14 30 - 14 38 - 14 39 - 14 40 - 14 46 - 14 70 - 14 71 - 14 72 - 14 78 - 15 16 - 15 23 - 15 24 - 15 27 - 15 29 - 15 30 - 15 31 - 15 39 - 15 40 - 15 47 - 15 71 - 15 72 - 15 79 - 16 24 - 16 28 - 16 30 - 16 31 - 16 32 - 16 40 - 16 48 - 16 72 - 16 80 - 17 18 - 17 19 - 17 21 - 17 25 - 17 33 - 17 34 - 17 35 - 17 37 - 17 41 - 17 49 - 17 65 - 17 73 - 17 81 - 18 19 - 18 20 - 18 21 - 18 22 - 18 25 - 18 26 - 18 34 - 18 35 - 18 36 - 18 38 - 18 41 - 18 42 - 18 50 - 18 66 - 18 73 - 18 74 - 18 82 - 19 20 - 19 21 - 19 22 - 19 23 - 19 25 - 19 26 - 19 27 - 19 35 - 19 37 - 19 38 - 19 39 - 19 41 - 19 42 - 19 43 - 19 51 - 19 67 - 19 73 - 19 74 - 19 75 - 19 83 - 20 22 - 20 23 - 20 24 - 20 26 - 20 28 - 20 36 - 20 38 - 20 39 - 20 40 - 20 42 - 20 44 - 20 52 - 20 68 - 20 74 - 20 76 - 20 84 - 21 22 - 21 23 - 21 25 - 21 26 - 21 27 - 21 29 - 21 37 - 21 41 - 21 42 - 21 43 - 21 45 - 21 53 - 21 69 - 21 73 - 21 75 - 21 77 - 21 85 - 22 23 - 22 24 - 22 26 - 22 27 - 22 28 - 22 30 - 22 38 - 22 42 - 22 43 - 22 44 - 22 46 - 22 54 - 22 70 - 22 74 - 22 75 - 22 76 - 22 78 - 22 86 - 23 24 - 23 27 - 23 28 - 23 29 - 23 30 - 23 31 - 23 39 - 23 43 - 23 44 - 23 45 - 23 46 - 23 47 - 23 55 - 23 71 - 23 75 - 23 76 - 23 79 - 23 87 - 24 28 - 24 30 - 24 31 - 24 32 - 24 40 - 24 44 - 24 46 - 24 47 - 24 48 - 24 56 - 24 72 - 24 76 - 24 80 - 24 88 - 25 26 - 25 27 - 25 29 - 25 41 - 25 45 - 25 49 - 25 50 - 25 51 - 25 53 - 25 57 - 25 73 - 25 77 - 25 89 - 26 27 - 26 28 - 26 29 - 26 30 - 26 42 - 26 45 - 26 46 - 26 50 - 26 51 - 26 52 - 26 54 - 26 58 - 26 74 - 26 77 - 26 78 - 26 90 - 27 28 - 27 29 - 27 30 - 27 31 - 27 43 - 27 45 - 27 46 - 27 47 - 27 51 - 27 53 - 27 54 - 27 55 - 27 59 - 27 75 - 27 77 - 27 78 - 27 79 - 27 91 - 28 30 - 28 31 - 28 32 - 28 44 - 28 46 - 28 48 - 28 52 - 28 54 - 28 55 - 28 56 - 28 60 - 28 76 - 28 78 - 28 80 - 28 92 - 29 30 - 29 31 - 29 45 - 29 47 - 29 53 - 29 57 - 29 58 - 29 59 - 29 61 - 29 77 - 29 79 - 29 93 - 30 31 - 30 32 - 30 46 - 30 47 - 30 48 - 30 54 - 30 58 - 30 59 - 30 60 - 30 62 - 30 78 - 30 79 - 30 80 - 30 94 - 31 32 - 31 47 - 31 48 - 31 55 - 31 59 - 31 61 - 31 62 - 31 63 - 31 79 - 31 80 - 31 95 - 32 48 - 32 56 - 32 60 - 32 62 - 32 63 - 32 64 - 32 80 - 32 96 - 33 34 - 33 35 - 33 37 - 33 41 - 33 49 - 33 65 - 33 66 - 33 67 - 33 69 - 33 73 - 33 81 - 33 97 - 34 35 - 34 36 - 34 37 - 34 38 - 34 41 - 34 42 - 34 49 - 34 50 - 34 66 - 34 67 - 34 68 - 34 70 - 34 74 - 34 81 - 34 82 - 34 98 - 35 36 - 35 37 - 35 38 - 35 39 - 35 41 - 35 42 - 35 43 - 35 49 - 35 50 - 35 51 - 35 67 - 35 69 - 35 70 - 35 71 - 35 75 - 35 81 - 35 82 - 35 83 - 35 99 - 36 38 - 36 39 - 36 40 - 36 42 - 36 44 - 36 50 - 36 52 - 36 68 - 36 70 - 36 71 - 36 72 - 36 76 - 36 82 - 36 84 - 36 100 - 37 38 - 37 39 - 37 41 - 37 42 - 37 43 - 37 45 - 37 49 - 37 51 - 37 53 - 37 69 - 37 73 - 37 74 - 37 75 - 37 77 - 37 81 - 37 83 - 37 85 - 37 101 - 38 39 - 38 40 - 38 42 - 38 43 - 38 44 - 38 46 - 38 50 - 38 51 - 38 52 - 38 54 - 38 70 - 38 74 - 38 75 - 38 76 - 38 78 - 38 82 - 38 83 - 38 84 - 38 86 - 38 102 - 39 40 - 39 43 - 39 44 - 39 45 - 39 46 - 39 47 - 39 51 - 39 52 - 39 55 - 39 71 - 39 75 - 39 77 - 39 78 - 39 79 - 39 83 - 39 84 - 39 87 - 39 103 - 40 44 - 40 46 - 40 47 - 40 48 - 40 52 - 40 56 - 40 72 - 40 76 - 40 78 - 40 79 - 40 80 - 40 84 - 40 88 - 40 104 - 41 42 - 41 43 - 41 45 - 41 49 - 41 50 - 41 51 - 41 53 - 41 57 - 41 73 - 41 81 - 41 82 - 41 83 - 41 85 - 41 89 - 41 105 - 42 43 - 42 44 - 42 45 - 42 46 - 42 50 - 42 51 - 42 52 - 42 53 - 42 54 - 42 58 - 42 74 - 42 82 - 42 83 - 42 84 - 42 85 - 42 86 - 42 90 - 42 106 - 43 44 - 43 45 - 43 46 - 43 47 - 43 51 - 43 53 - 43 54 - 43 55 - 43 59 - 43 75 - 43 83 - 43 85 - 43 86 - 43 87 - 43 91 - 43 107 - 44 46 - 44 47 - 44 48 - 44 52 - 44 54 - 44 55 - 44 56 - 44 60 - 44 76 - 44 84 - 44 86 - 44 87 - 44 88 - 44 92 - 44 108 - 45 46 - 45 47 - 45 53 - 45 55 - 45 57 - 45 58 - 45 59 - 45 61 - 45 77 - 45 85 - 45 87 - 45 89 - 45 90 - 45 91 - 45 93 - 45 109 - 46 47 - 46 48 - 46 54 - 46 55 - 46 56 - 46 58 - 46 59 - 46 60 - 46 62 - 46 78 - 46 86 - 46 87 - 46 88 - 46 90 - 46 91 - 46 92 - 46 94 - 46 110 - 47 48 - 47 55 - 47 56 - 47 59 - 47 61 - 47 62 - 47 63 - 47 79 - 47 87 - 47 88 - 47 91 - 47 93 - 47 94 - 47 95 - 47 111 - 48 56 - 48 60 - 48 62 - 48 63 - 48 64 - 48 80 - 48 88 - 48 92 - 48 94 - 48 95 - 48 96 - 48 112 - 49 50 - 49 51 - 49 53 - 49 57 - 49 81 - 49 89 - 49 97 - 49 98 - 49 99 - 49 101 - 49 105 - 49 113 - 50 51 - 50 52 - 50 53 - 50 54 - 50 57 - 50 58 - 50 82 - 50 89 - 50 90 - 50 98 - 50 99 - 50 100 - 50 102 - 50 106 - 50 114 - 51 52 - 51 53 - 51 54 - 51 55 - 51 57 - 51 58 - 51 59 - 51 83 - 51 89 - 51 90 - 51 91 - 51 99 - 51 101 - 51 102 - 51 103 - 51 107 - 51 115 - 52 54 - 52 55 - 52 56 - 52 58 - 52 60 - 52 84 - 52 90 - 52 92 - 52 100 - 52 102 - 52 103 - 52 104 - 52 108 - 52 116 - 53 54 - 53 55 - 53 57 - 53 58 - 53 59 - 53 61 - 53 85 - 53 89 - 53 91 - 53 93 - 53 101 - 53 105 - 53 106 - 53 107 - 53 109 - 53 117 - 54 55 - 54 56 - 54 58 - 54 59 - 54 60 - 54 62 - 54 86 - 54 90 - 54 91 - 54 92 - 54 94 - 54 102 - 54 106 - 54 107 - 54 108 - 54 110 - 54 118 - 55 56 - 55 59 - 55 60 - 55 61 - 55 62 - 55 63 - 55 87 - 55 91 - 55 92 - 55 95 - 55 103 - 55 107 - 55 109 - 55 110 - 55 111 - 55 119 - 56 60 - 56 62 - 56 63 - 56 64 - 56 88 - 56 92 - 56 96 - 56 104 - 56 108 - 56 110 - 56 111 - 56 112 - 56 120 - 57 58 - 57 59 - 57 61 - 57 89 - 57 93 - 57 105 - 57 113 - 57 114 - 57 115 - 57 117 - 57 121 - 58 59 - 58 60 - 58 61 - 58 62 - 58 90 - 58 93 - 58 94 - 58 106 - 58 114 - 58 115 - 58 116 - 58 118 - 58 122 - 59 60 - 59 61 - 59 62 - 59 63 - 59 91 - 59 93 - 59 94 - 59 95 - 59 107 - 59 115 - 59 117 - 59 118 - 59 119 - 59 123 - 60 62 - 60 63 - 60 64 - 60 92 - 60 94 - 60 96 - 60 108 - 60 116 - 60 118 - 60 119 - 60 120 - 60 124 - 61 62 - 61 63 - 61 93 - 61 95 - 61 109 - 61 117 - 61 121 - 61 122 - 61 123 - 61 125 - 62 63 - 62 64 - 62 94 - 62 95 - 62 96 - 62 110 - 62 118 - 62 122 - 62 123 - 62 124 - 62 126 - 63 64 - 63 95 - 63 96 - 63 111 - 63 119 - 63 123 - 63 125 - 63 126 - 63 127 - 64 96 - 64 112 - 64 120 - 64 124 - 64 126 - 64 127 - 64 128 - 65 66 - 65 67 - 65 69 - 65 73 - 65 81 - 65 97 - 66 67 - 66 68 - 66 69 - 66 70 - 66 73 - 66 74 - 66 81 - 66 82 - 66 97 - 66 98 - 67 68 - 67 69 - 67 70 - 67 71 - 67 73 - 67 74 - 67 75 - 67 81 - 67 82 - 67 83 - 67 97 - 67 98 - 67 99 - 68 70 - 68 71 - 68 72 - 68 74 - 68 76 - 68 82 - 68 84 - 68 98 - 68 100 - 69 70 - 69 71 - 69 73 - 69 74 - 69 75 - 69 77 - 69 81 - 69 83 - 69 85 - 69 97 - 69 99 - 69 101 - 70 71 - 70 72 - 70 74 - 70 75 - 70 76 - 70 78 - 70 82 - 70 83 - 70 84 - 70 86 - 70 98 - 70 99 - 70 100 - 70 102 - 71 72 - 71 75 - 71 76 - 71 77 - 71 78 - 71 79 - 71 83 - 71 84 - 71 87 - 71 99 - 71 100 - 71 103 - 72 76 - 72 78 - 72 79 - 72 80 - 72 84 - 72 88 - 72 100 - 72 104 - 73 74 - 73 75 - 73 77 - 73 81 - 73 82 - 73 83 - 73 85 - 73 89 - 73 97 - 73 101 - 73 105 - 74 75 - 74 76 - 74 77 - 74 78 - 74 82 - 74 83 - 74 84 - 74 85 - 74 86 - 74 90 - 74 98 - 74 101 - 74 102 - 74 106 - 75 76 - 75 77 - 75 78 - 75 79 - 75 83 - 75 85 - 75 86 - 75 87 - 75 91 - 75 99 - 75 101 - 75 102 - 75 103 - 75 107 - 76 78 - 76 79 - 76 80 - 76 84 - 76 86 - 76 87 - 76 88 - 76 92 - 76 100 - 76 102 - 76 104 - 76 108 - 77 78 - 77 79 - 77 85 - 77 87 - 77 89 - 77 90 - 77 91 - 77 93 - 77 101 - 77 103 - 77 109 - 78 79 - 78 80 - 78 86 - 78 87 - 78 88 - 78 90 - 78 91 - 78 92 - 78 94 - 78 102 - 78 103 - 78 104 - 78 110 - 79 80 - 79 87 - 79 88 - 79 91 - 79 93 - 79 94 - 79 95 - 79 103 - 79 104 - 79 111 - 80 88 - 80 92 - 80 94 - 80 95 - 80 96 - 80 104 - 80 112 - 81 82 - 81 83 - 81 85 - 81 89 - 81 97 - 81 98 - 81 99 - 81 101 - 81 105 - 81 113 - 82 83 - 82 84 - 82 85 - 82 86 - 82 89 - 82 90 - 82 98 - 82 99 - 82 100 - 82 102 - 82 105 - 82 106 - 82 114 - 83 84 - 83 85 - 83 86 - 83 87 - 83 89 - 83 90 - 83 91 - 83 99 - 83 101 - 83 102 - 83 103 - 83 105 - 83 106 - 83 107 - 83 115 - 84 86 - 84 87 - 84 88 - 84 90 - 84 92 - 84 100 - 84 102 - 84 103 - 84 104 - 84 106 - 84 108 - 84 116 - 85 86 - 85 87 - 85 89 - 85 90 - 85 91 - 85 93 - 85 101 - 85 105 - 85 106 - 85 107 - 85 109 - 85 117 - 86 87 - 86 88 - 86 90 - 86 91 - 86 92 - 86 94 - 86 102 - 86 106 - 86 107 - 86 108 - 86 110 - 86 118 - 87 88 - 87 91 - 87 92 - 87 93 - 87 94 - 87 95 - 87 103 - 87 107 - 87 108 - 87 109 - 87 110 - 87 111 - 87 119 - 88 92 - 88 94 - 88 95 - 88 96 - 88 104 - 88 108 - 88 110 - 88 111 - 88 112 - 88 120 - 89 90 - 89 91 - 89 93 - 89 105 - 89 109 - 89 113 - 89 114 - 89 115 - 89 117 - 89 121 - 90 91 - 90 92 - 90 93 - 90 94 - 90 106 - 90 109 - 90 110 - 90 114 - 90 115 - 90 116 - 90 118 - 90 122 - 91 92 - 91 93 - 91 94 - 91 95 - 91 107 - 91 109 - 91 110 - 91 111 - 91 115 - 91 117 - 91 118 - 91 119 - 91 123 - 92 94 - 92 95 - 92 96 - 92 108 - 92 110 - 92 112 - 92 116 - 92 118 - 92 119 - 92 120 - 92 124 - 93 94 - 93 95 - 93 109 - 93 111 - 93 117 - 93 121 - 93 122 - 93 123 - 93 125 - 94 95 - 94 96 - 94 110 - 94 111 - 94 112 - 94 118 - 94 122 - 94 123 - 94 124 - 94 126 - 95 96 - 95 111 - 95 112 - 95 119 - 95 123 - 95 125 - 95 126 - 95 127 - 96 112 - 96 120 - 96 124 - 96 126 - 96 127 - 96 128 - 97 98 - 97 99 - 97 101 - 97 105 - 97 113 - 98 99 - 98 100 - 98 101 - 98 102 - 98 105 - 98 106 - 98 113 - 98 114 - 99 100 - 99 101 - 99 102 - 99 103 - 99 105 - 99 106 - 99 107 - 99 113 - 99 114 - 99 115 - 100 102 - 100 103 - 100 104 - 100 106 - 100 108 - 100 114 - 100 116 - 101 102 - 101 103 - 101 105 - 101 106 - 101 107 - 101 109 - 101 113 - 101 115 - 101 117 - 102 103 - 102 104 - 102 106 - 102 107 - 102 108 - 102 110 - 102 114 - 102 115 - 102 116 - 102 118 - 103 104 - 103 107 - 103 108 - 103 109 - 103 110 - 103 111 - 103 115 - 103 116 - 103 119 - 104 108 - 104 110 - 104 111 - 104 112 - 104 116 - 104 120 - 105 106 - 105 107 - 105 109 - 105 113 - 105 114 - 105 115 - 105 117 - 105 121 - 106 107 - 106 108 - 106 109 - 106 110 - 106 114 - 106 115 - 106 116 - 106 117 - 106 118 - 106 122 - 107 108 - 107 109 - 107 110 - 107 111 - 107 115 - 107 117 - 107 118 - 107 119 - 107 123 - 108 110 - 108 111 - 108 112 - 108 116 - 108 118 - 108 119 - 108 120 - 108 124 - 109 110 - 109 111 - 109 117 - 109 119 - 109 121 - 109 122 - 109 123 - 109 125 - 110 111 - 110 112 - 110 118 - 110 119 - 110 120 - 110 122 - 110 123 - 110 124 - 110 126 - 111 112 - 111 119 - 111 120 - 111 123 - 111 125 - 111 126 - 111 127 - 112 120 - 112 124 - 112 126 - 112 127 - 112 128 - 113 114 - 113 115 - 113 117 - 113 121 - 114 115 - 114 116 - 114 117 - 114 118 - 114 121 - 114 122 - 115 116 - 115 117 - 115 118 - 115 119 - 115 121 - 115 122 - 115 123 - 116 118 - 116 119 - 116 120 - 116 122 - 116 124 - 117 118 - 117 119 - 117 121 - 117 122 - 117 123 - 117 125 - 118 119 - 118 120 - 118 122 - 118 123 - 118 124 - 118 126 - 119 120 - 119 123 - 119 124 - 119 125 - 119 126 - 119 127 - 120 124 - 120 126 - 120 127 - 120 128 - 121 122 - 121 123 - 121 125 - 122 123 - 122 124 - 122 125 - 122 126 - 123 124 - 123 125 - 123 126 - 123 127 - 124 126 - 124 127 - 124 128 - 125 126 - 125 127 - 126 127 - 126 128 - 127 128 -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/misp2.dat b/resources/3rdparty/glpk-4.53/examples/misp2.dat deleted file mode 100644 index c9a61161e..000000000 --- a/resources/3rdparty/glpk-4.53/examples/misp2.dat +++ /dev/null @@ -1,3857 +0,0 @@ -/* misp2.dat (data for misp.mod to illustrate clique cuts) */ - -/* These data corresponds to the test instance 1dc.256 (graphs from - * single-deletion-correcting codes) from: - * - * N.J.A.Sloane, "Challenge Problems: Independent Sets In Graphs." - * http://neilsloane.com/doc/graphs.html (June 2013). */ - -/* Optimal solution is 30. */ - -data; - -param n := 256; - -set E := /* 3839 edges */ - 1 2 - 1 3 - 1 5 - 1 9 - 1 17 - 1 33 - 1 65 - 1 129 - 2 3 - 2 4 - 2 5 - 2 6 - 2 9 - 2 10 - 2 17 - 2 18 - 2 33 - 2 34 - 2 65 - 2 66 - 2 129 - 2 130 - 3 4 - 3 5 - 3 6 - 3 7 - 3 9 - 3 10 - 3 11 - 3 17 - 3 18 - 3 19 - 3 33 - 3 34 - 3 35 - 3 65 - 3 66 - 3 67 - 3 129 - 3 130 - 3 131 - 4 6 - 4 7 - 4 8 - 4 10 - 4 12 - 4 18 - 4 20 - 4 34 - 4 36 - 4 66 - 4 68 - 4 130 - 4 132 - 5 6 - 5 7 - 5 9 - 5 10 - 5 11 - 5 13 - 5 17 - 5 19 - 5 21 - 5 33 - 5 35 - 5 37 - 5 65 - 5 67 - 5 69 - 5 129 - 5 131 - 5 133 - 6 7 - 6 8 - 6 10 - 6 11 - 6 12 - 6 14 - 6 18 - 6 19 - 6 20 - 6 22 - 6 34 - 6 35 - 6 36 - 6 38 - 6 66 - 6 67 - 6 68 - 6 70 - 6 130 - 6 131 - 6 132 - 6 134 - 7 8 - 7 11 - 7 12 - 7 13 - 7 14 - 7 15 - 7 19 - 7 20 - 7 23 - 7 35 - 7 36 - 7 39 - 7 67 - 7 68 - 7 71 - 7 131 - 7 132 - 7 135 - 8 12 - 8 14 - 8 15 - 8 16 - 8 20 - 8 24 - 8 36 - 8 40 - 8 68 - 8 72 - 8 132 - 8 136 - 9 10 - 9 11 - 9 13 - 9 17 - 9 18 - 9 19 - 9 21 - 9 25 - 9 33 - 9 37 - 9 41 - 9 65 - 9 69 - 9 73 - 9 129 - 9 133 - 9 137 - 10 11 - 10 12 - 10 13 - 10 14 - 10 18 - 10 19 - 10 20 - 10 21 - 10 22 - 10 26 - 10 34 - 10 37 - 10 38 - 10 42 - 10 66 - 10 69 - 10 70 - 10 74 - 10 130 - 10 133 - 10 134 - 10 138 - 11 12 - 11 13 - 11 14 - 11 15 - 11 19 - 11 21 - 11 22 - 11 23 - 11 27 - 11 35 - 11 37 - 11 38 - 11 39 - 11 43 - 11 67 - 11 69 - 11 70 - 11 71 - 11 75 - 11 131 - 11 133 - 11 134 - 11 135 - 11 139 - 12 14 - 12 15 - 12 16 - 12 20 - 12 22 - 12 23 - 12 24 - 12 28 - 12 36 - 12 38 - 12 40 - 12 44 - 12 68 - 12 70 - 12 72 - 12 76 - 12 132 - 12 134 - 12 136 - 12 140 - 13 14 - 13 15 - 13 21 - 13 23 - 13 25 - 13 26 - 13 27 - 13 29 - 13 37 - 13 39 - 13 45 - 13 69 - 13 71 - 13 77 - 13 133 - 13 135 - 13 141 - 14 15 - 14 16 - 14 22 - 14 23 - 14 24 - 14 26 - 14 27 - 14 28 - 14 30 - 14 38 - 14 39 - 14 40 - 14 46 - 14 70 - 14 71 - 14 72 - 14 78 - 14 134 - 14 135 - 14 136 - 14 142 - 15 16 - 15 23 - 15 24 - 15 27 - 15 29 - 15 30 - 15 31 - 15 39 - 15 40 - 15 47 - 15 71 - 15 72 - 15 79 - 15 135 - 15 136 - 15 143 - 16 24 - 16 28 - 16 30 - 16 31 - 16 32 - 16 40 - 16 48 - 16 72 - 16 80 - 16 136 - 16 144 - 17 18 - 17 19 - 17 21 - 17 25 - 17 33 - 17 34 - 17 35 - 17 37 - 17 41 - 17 49 - 17 65 - 17 73 - 17 81 - 17 129 - 17 137 - 17 145 - 18 19 - 18 20 - 18 21 - 18 22 - 18 25 - 18 26 - 18 34 - 18 35 - 18 36 - 18 38 - 18 41 - 18 42 - 18 50 - 18 66 - 18 73 - 18 74 - 18 82 - 18 130 - 18 137 - 18 138 - 18 146 - 19 20 - 19 21 - 19 22 - 19 23 - 19 25 - 19 26 - 19 27 - 19 35 - 19 37 - 19 38 - 19 39 - 19 41 - 19 42 - 19 43 - 19 51 - 19 67 - 19 73 - 19 74 - 19 75 - 19 83 - 19 131 - 19 137 - 19 138 - 19 139 - 19 147 - 20 22 - 20 23 - 20 24 - 20 26 - 20 28 - 20 36 - 20 38 - 20 39 - 20 40 - 20 42 - 20 44 - 20 52 - 20 68 - 20 74 - 20 76 - 20 84 - 20 132 - 20 138 - 20 140 - 20 148 - 21 22 - 21 23 - 21 25 - 21 26 - 21 27 - 21 29 - 21 37 - 21 41 - 21 42 - 21 43 - 21 45 - 21 53 - 21 69 - 21 73 - 21 75 - 21 77 - 21 85 - 21 133 - 21 137 - 21 139 - 21 141 - 21 149 - 22 23 - 22 24 - 22 26 - 22 27 - 22 28 - 22 30 - 22 38 - 22 42 - 22 43 - 22 44 - 22 46 - 22 54 - 22 70 - 22 74 - 22 75 - 22 76 - 22 78 - 22 86 - 22 134 - 22 138 - 22 139 - 22 140 - 22 142 - 22 150 - 23 24 - 23 27 - 23 28 - 23 29 - 23 30 - 23 31 - 23 39 - 23 43 - 23 44 - 23 45 - 23 46 - 23 47 - 23 55 - 23 71 - 23 75 - 23 76 - 23 79 - 23 87 - 23 135 - 23 139 - 23 140 - 23 143 - 23 151 - 24 28 - 24 30 - 24 31 - 24 32 - 24 40 - 24 44 - 24 46 - 24 47 - 24 48 - 24 56 - 24 72 - 24 76 - 24 80 - 24 88 - 24 136 - 24 140 - 24 144 - 24 152 - 25 26 - 25 27 - 25 29 - 25 41 - 25 45 - 25 49 - 25 50 - 25 51 - 25 53 - 25 57 - 25 73 - 25 77 - 25 89 - 25 137 - 25 141 - 25 153 - 26 27 - 26 28 - 26 29 - 26 30 - 26 42 - 26 45 - 26 46 - 26 50 - 26 51 - 26 52 - 26 54 - 26 58 - 26 74 - 26 77 - 26 78 - 26 90 - 26 138 - 26 141 - 26 142 - 26 154 - 27 28 - 27 29 - 27 30 - 27 31 - 27 43 - 27 45 - 27 46 - 27 47 - 27 51 - 27 53 - 27 54 - 27 55 - 27 59 - 27 75 - 27 77 - 27 78 - 27 79 - 27 91 - 27 139 - 27 141 - 27 142 - 27 143 - 27 155 - 28 30 - 28 31 - 28 32 - 28 44 - 28 46 - 28 48 - 28 52 - 28 54 - 28 55 - 28 56 - 28 60 - 28 76 - 28 78 - 28 80 - 28 92 - 28 140 - 28 142 - 28 144 - 28 156 - 29 30 - 29 31 - 29 45 - 29 47 - 29 53 - 29 57 - 29 58 - 29 59 - 29 61 - 29 77 - 29 79 - 29 93 - 29 141 - 29 143 - 29 157 - 30 31 - 30 32 - 30 46 - 30 47 - 30 48 - 30 54 - 30 58 - 30 59 - 30 60 - 30 62 - 30 78 - 30 79 - 30 80 - 30 94 - 30 142 - 30 143 - 30 144 - 30 158 - 31 32 - 31 47 - 31 48 - 31 55 - 31 59 - 31 61 - 31 62 - 31 63 - 31 79 - 31 80 - 31 95 - 31 143 - 31 144 - 31 159 - 32 48 - 32 56 - 32 60 - 32 62 - 32 63 - 32 64 - 32 80 - 32 96 - 32 144 - 32 160 - 33 34 - 33 35 - 33 37 - 33 41 - 33 49 - 33 65 - 33 66 - 33 67 - 33 69 - 33 73 - 33 81 - 33 97 - 33 129 - 33 145 - 33 161 - 34 35 - 34 36 - 34 37 - 34 38 - 34 41 - 34 42 - 34 49 - 34 50 - 34 66 - 34 67 - 34 68 - 34 70 - 34 74 - 34 81 - 34 82 - 34 98 - 34 130 - 34 145 - 34 146 - 34 162 - 35 36 - 35 37 - 35 38 - 35 39 - 35 41 - 35 42 - 35 43 - 35 49 - 35 50 - 35 51 - 35 67 - 35 69 - 35 70 - 35 71 - 35 75 - 35 81 - 35 82 - 35 83 - 35 99 - 35 131 - 35 145 - 35 146 - 35 147 - 35 163 - 36 38 - 36 39 - 36 40 - 36 42 - 36 44 - 36 50 - 36 52 - 36 68 - 36 70 - 36 71 - 36 72 - 36 76 - 36 82 - 36 84 - 36 100 - 36 132 - 36 146 - 36 148 - 36 164 - 37 38 - 37 39 - 37 41 - 37 42 - 37 43 - 37 45 - 37 49 - 37 51 - 37 53 - 37 69 - 37 73 - 37 74 - 37 75 - 37 77 - 37 81 - 37 83 - 37 85 - 37 101 - 37 133 - 37 145 - 37 147 - 37 149 - 37 165 - 38 39 - 38 40 - 38 42 - 38 43 - 38 44 - 38 46 - 38 50 - 38 51 - 38 52 - 38 54 - 38 70 - 38 74 - 38 75 - 38 76 - 38 78 - 38 82 - 38 83 - 38 84 - 38 86 - 38 102 - 38 134 - 38 146 - 38 147 - 38 148 - 38 150 - 38 166 - 39 40 - 39 43 - 39 44 - 39 45 - 39 46 - 39 47 - 39 51 - 39 52 - 39 55 - 39 71 - 39 75 - 39 77 - 39 78 - 39 79 - 39 83 - 39 84 - 39 87 - 39 103 - 39 135 - 39 147 - 39 148 - 39 151 - 39 167 - 40 44 - 40 46 - 40 47 - 40 48 - 40 52 - 40 56 - 40 72 - 40 76 - 40 78 - 40 79 - 40 80 - 40 84 - 40 88 - 40 104 - 40 136 - 40 148 - 40 152 - 40 168 - 41 42 - 41 43 - 41 45 - 41 49 - 41 50 - 41 51 - 41 53 - 41 57 - 41 73 - 41 81 - 41 82 - 41 83 - 41 85 - 41 89 - 41 105 - 41 137 - 41 145 - 41 149 - 41 153 - 41 169 - 42 43 - 42 44 - 42 45 - 42 46 - 42 50 - 42 51 - 42 52 - 42 53 - 42 54 - 42 58 - 42 74 - 42 82 - 42 83 - 42 84 - 42 85 - 42 86 - 42 90 - 42 106 - 42 138 - 42 146 - 42 149 - 42 150 - 42 154 - 42 170 - 43 44 - 43 45 - 43 46 - 43 47 - 43 51 - 43 53 - 43 54 - 43 55 - 43 59 - 43 75 - 43 83 - 43 85 - 43 86 - 43 87 - 43 91 - 43 107 - 43 139 - 43 147 - 43 149 - 43 150 - 43 151 - 43 155 - 43 171 - 44 46 - 44 47 - 44 48 - 44 52 - 44 54 - 44 55 - 44 56 - 44 60 - 44 76 - 44 84 - 44 86 - 44 87 - 44 88 - 44 92 - 44 108 - 44 140 - 44 148 - 44 150 - 44 152 - 44 156 - 44 172 - 45 46 - 45 47 - 45 53 - 45 55 - 45 57 - 45 58 - 45 59 - 45 61 - 45 77 - 45 85 - 45 87 - 45 89 - 45 90 - 45 91 - 45 93 - 45 109 - 45 141 - 45 149 - 45 151 - 45 157 - 45 173 - 46 47 - 46 48 - 46 54 - 46 55 - 46 56 - 46 58 - 46 59 - 46 60 - 46 62 - 46 78 - 46 86 - 46 87 - 46 88 - 46 90 - 46 91 - 46 92 - 46 94 - 46 110 - 46 142 - 46 150 - 46 151 - 46 152 - 46 158 - 46 174 - 47 48 - 47 55 - 47 56 - 47 59 - 47 61 - 47 62 - 47 63 - 47 79 - 47 87 - 47 88 - 47 91 - 47 93 - 47 94 - 47 95 - 47 111 - 47 143 - 47 151 - 47 152 - 47 159 - 47 175 - 48 56 - 48 60 - 48 62 - 48 63 - 48 64 - 48 80 - 48 88 - 48 92 - 48 94 - 48 95 - 48 96 - 48 112 - 48 144 - 48 152 - 48 160 - 48 176 - 49 50 - 49 51 - 49 53 - 49 57 - 49 81 - 49 89 - 49 97 - 49 98 - 49 99 - 49 101 - 49 105 - 49 113 - 49 145 - 49 153 - 49 177 - 50 51 - 50 52 - 50 53 - 50 54 - 50 57 - 50 58 - 50 82 - 50 89 - 50 90 - 50 98 - 50 99 - 50 100 - 50 102 - 50 106 - 50 114 - 50 146 - 50 153 - 50 154 - 50 178 - 51 52 - 51 53 - 51 54 - 51 55 - 51 57 - 51 58 - 51 59 - 51 83 - 51 89 - 51 90 - 51 91 - 51 99 - 51 101 - 51 102 - 51 103 - 51 107 - 51 115 - 51 147 - 51 153 - 51 154 - 51 155 - 51 179 - 52 54 - 52 55 - 52 56 - 52 58 - 52 60 - 52 84 - 52 90 - 52 92 - 52 100 - 52 102 - 52 103 - 52 104 - 52 108 - 52 116 - 52 148 - 52 154 - 52 156 - 52 180 - 53 54 - 53 55 - 53 57 - 53 58 - 53 59 - 53 61 - 53 85 - 53 89 - 53 91 - 53 93 - 53 101 - 53 105 - 53 106 - 53 107 - 53 109 - 53 117 - 53 149 - 53 153 - 53 155 - 53 157 - 53 181 - 54 55 - 54 56 - 54 58 - 54 59 - 54 60 - 54 62 - 54 86 - 54 90 - 54 91 - 54 92 - 54 94 - 54 102 - 54 106 - 54 107 - 54 108 - 54 110 - 54 118 - 54 150 - 54 154 - 54 155 - 54 156 - 54 158 - 54 182 - 55 56 - 55 59 - 55 60 - 55 61 - 55 62 - 55 63 - 55 87 - 55 91 - 55 92 - 55 95 - 55 103 - 55 107 - 55 109 - 55 110 - 55 111 - 55 119 - 55 151 - 55 155 - 55 156 - 55 159 - 55 183 - 56 60 - 56 62 - 56 63 - 56 64 - 56 88 - 56 92 - 56 96 - 56 104 - 56 108 - 56 110 - 56 111 - 56 112 - 56 120 - 56 152 - 56 156 - 56 160 - 56 184 - 57 58 - 57 59 - 57 61 - 57 89 - 57 93 - 57 105 - 57 113 - 57 114 - 57 115 - 57 117 - 57 121 - 57 153 - 57 157 - 57 185 - 58 59 - 58 60 - 58 61 - 58 62 - 58 90 - 58 93 - 58 94 - 58 106 - 58 114 - 58 115 - 58 116 - 58 118 - 58 122 - 58 154 - 58 157 - 58 158 - 58 186 - 59 60 - 59 61 - 59 62 - 59 63 - 59 91 - 59 93 - 59 94 - 59 95 - 59 107 - 59 115 - 59 117 - 59 118 - 59 119 - 59 123 - 59 155 - 59 157 - 59 158 - 59 159 - 59 187 - 60 62 - 60 63 - 60 64 - 60 92 - 60 94 - 60 96 - 60 108 - 60 116 - 60 118 - 60 119 - 60 120 - 60 124 - 60 156 - 60 158 - 60 160 - 60 188 - 61 62 - 61 63 - 61 93 - 61 95 - 61 109 - 61 117 - 61 121 - 61 122 - 61 123 - 61 125 - 61 157 - 61 159 - 61 189 - 62 63 - 62 64 - 62 94 - 62 95 - 62 96 - 62 110 - 62 118 - 62 122 - 62 123 - 62 124 - 62 126 - 62 158 - 62 159 - 62 160 - 62 190 - 63 64 - 63 95 - 63 96 - 63 111 - 63 119 - 63 123 - 63 125 - 63 126 - 63 127 - 63 159 - 63 160 - 63 191 - 64 96 - 64 112 - 64 120 - 64 124 - 64 126 - 64 127 - 64 128 - 64 160 - 64 192 - 65 66 - 65 67 - 65 69 - 65 73 - 65 81 - 65 97 - 65 129 - 65 130 - 65 131 - 65 133 - 65 137 - 65 145 - 65 161 - 65 193 - 66 67 - 66 68 - 66 69 - 66 70 - 66 73 - 66 74 - 66 81 - 66 82 - 66 97 - 66 98 - 66 130 - 66 131 - 66 132 - 66 134 - 66 138 - 66 146 - 66 161 - 66 162 - 66 194 - 67 68 - 67 69 - 67 70 - 67 71 - 67 73 - 67 74 - 67 75 - 67 81 - 67 82 - 67 83 - 67 97 - 67 98 - 67 99 - 67 131 - 67 133 - 67 134 - 67 135 - 67 139 - 67 147 - 67 161 - 67 162 - 67 163 - 67 195 - 68 70 - 68 71 - 68 72 - 68 74 - 68 76 - 68 82 - 68 84 - 68 98 - 68 100 - 68 132 - 68 134 - 68 135 - 68 136 - 68 140 - 68 148 - 68 162 - 68 164 - 68 196 - 69 70 - 69 71 - 69 73 - 69 74 - 69 75 - 69 77 - 69 81 - 69 83 - 69 85 - 69 97 - 69 99 - 69 101 - 69 133 - 69 137 - 69 138 - 69 139 - 69 141 - 69 149 - 69 161 - 69 163 - 69 165 - 69 197 - 70 71 - 70 72 - 70 74 - 70 75 - 70 76 - 70 78 - 70 82 - 70 83 - 70 84 - 70 86 - 70 98 - 70 99 - 70 100 - 70 102 - 70 134 - 70 138 - 70 139 - 70 140 - 70 142 - 70 150 - 70 162 - 70 163 - 70 164 - 70 166 - 70 198 - 71 72 - 71 75 - 71 76 - 71 77 - 71 78 - 71 79 - 71 83 - 71 84 - 71 87 - 71 99 - 71 100 - 71 103 - 71 135 - 71 139 - 71 141 - 71 142 - 71 143 - 71 151 - 71 163 - 71 164 - 71 167 - 71 199 - 72 76 - 72 78 - 72 79 - 72 80 - 72 84 - 72 88 - 72 100 - 72 104 - 72 136 - 72 140 - 72 142 - 72 143 - 72 144 - 72 152 - 72 164 - 72 168 - 72 200 - 73 74 - 73 75 - 73 77 - 73 81 - 73 82 - 73 83 - 73 85 - 73 89 - 73 97 - 73 101 - 73 105 - 73 137 - 73 145 - 73 146 - 73 147 - 73 149 - 73 153 - 73 161 - 73 165 - 73 169 - 73 201 - 74 75 - 74 76 - 74 77 - 74 78 - 74 82 - 74 83 - 74 84 - 74 85 - 74 86 - 74 90 - 74 98 - 74 101 - 74 102 - 74 106 - 74 138 - 74 146 - 74 147 - 74 148 - 74 150 - 74 154 - 74 162 - 74 165 - 74 166 - 74 170 - 74 202 - 75 76 - 75 77 - 75 78 - 75 79 - 75 83 - 75 85 - 75 86 - 75 87 - 75 91 - 75 99 - 75 101 - 75 102 - 75 103 - 75 107 - 75 139 - 75 147 - 75 149 - 75 150 - 75 151 - 75 155 - 75 163 - 75 165 - 75 166 - 75 167 - 75 171 - 75 203 - 76 78 - 76 79 - 76 80 - 76 84 - 76 86 - 76 87 - 76 88 - 76 92 - 76 100 - 76 102 - 76 104 - 76 108 - 76 140 - 76 148 - 76 150 - 76 151 - 76 152 - 76 156 - 76 164 - 76 166 - 76 168 - 76 172 - 76 204 - 77 78 - 77 79 - 77 85 - 77 87 - 77 89 - 77 90 - 77 91 - 77 93 - 77 101 - 77 103 - 77 109 - 77 141 - 77 149 - 77 153 - 77 154 - 77 155 - 77 157 - 77 165 - 77 167 - 77 173 - 77 205 - 78 79 - 78 80 - 78 86 - 78 87 - 78 88 - 78 90 - 78 91 - 78 92 - 78 94 - 78 102 - 78 103 - 78 104 - 78 110 - 78 142 - 78 150 - 78 154 - 78 155 - 78 156 - 78 158 - 78 166 - 78 167 - 78 168 - 78 174 - 78 206 - 79 80 - 79 87 - 79 88 - 79 91 - 79 93 - 79 94 - 79 95 - 79 103 - 79 104 - 79 111 - 79 143 - 79 151 - 79 155 - 79 157 - 79 158 - 79 159 - 79 167 - 79 168 - 79 175 - 79 207 - 80 88 - 80 92 - 80 94 - 80 95 - 80 96 - 80 104 - 80 112 - 80 144 - 80 152 - 80 156 - 80 158 - 80 159 - 80 160 - 80 168 - 80 176 - 80 208 - 81 82 - 81 83 - 81 85 - 81 89 - 81 97 - 81 98 - 81 99 - 81 101 - 81 105 - 81 113 - 81 145 - 81 161 - 81 162 - 81 163 - 81 165 - 81 169 - 81 177 - 81 209 - 82 83 - 82 84 - 82 85 - 82 86 - 82 89 - 82 90 - 82 98 - 82 99 - 82 100 - 82 102 - 82 105 - 82 106 - 82 114 - 82 146 - 82 162 - 82 163 - 82 164 - 82 166 - 82 169 - 82 170 - 82 178 - 82 210 - 83 84 - 83 85 - 83 86 - 83 87 - 83 89 - 83 90 - 83 91 - 83 99 - 83 101 - 83 102 - 83 103 - 83 105 - 83 106 - 83 107 - 83 115 - 83 147 - 83 163 - 83 165 - 83 166 - 83 167 - 83 169 - 83 170 - 83 171 - 83 179 - 83 211 - 84 86 - 84 87 - 84 88 - 84 90 - 84 92 - 84 100 - 84 102 - 84 103 - 84 104 - 84 106 - 84 108 - 84 116 - 84 148 - 84 164 - 84 166 - 84 167 - 84 168 - 84 170 - 84 172 - 84 180 - 84 212 - 85 86 - 85 87 - 85 89 - 85 90 - 85 91 - 85 93 - 85 101 - 85 105 - 85 106 - 85 107 - 85 109 - 85 117 - 85 149 - 85 165 - 85 169 - 85 170 - 85 171 - 85 173 - 85 181 - 85 213 - 86 87 - 86 88 - 86 90 - 86 91 - 86 92 - 86 94 - 86 102 - 86 106 - 86 107 - 86 108 - 86 110 - 86 118 - 86 150 - 86 166 - 86 170 - 86 171 - 86 172 - 86 174 - 86 182 - 86 214 - 87 88 - 87 91 - 87 92 - 87 93 - 87 94 - 87 95 - 87 103 - 87 107 - 87 108 - 87 109 - 87 110 - 87 111 - 87 119 - 87 151 - 87 167 - 87 171 - 87 172 - 87 173 - 87 174 - 87 175 - 87 183 - 87 215 - 88 92 - 88 94 - 88 95 - 88 96 - 88 104 - 88 108 - 88 110 - 88 111 - 88 112 - 88 120 - 88 152 - 88 168 - 88 172 - 88 174 - 88 175 - 88 176 - 88 184 - 88 216 - 89 90 - 89 91 - 89 93 - 89 105 - 89 109 - 89 113 - 89 114 - 89 115 - 89 117 - 89 121 - 89 153 - 89 169 - 89 173 - 89 177 - 89 178 - 89 179 - 89 181 - 89 185 - 89 217 - 90 91 - 90 92 - 90 93 - 90 94 - 90 106 - 90 109 - 90 110 - 90 114 - 90 115 - 90 116 - 90 118 - 90 122 - 90 154 - 90 170 - 90 173 - 90 174 - 90 178 - 90 179 - 90 180 - 90 182 - 90 186 - 90 218 - 91 92 - 91 93 - 91 94 - 91 95 - 91 107 - 91 109 - 91 110 - 91 111 - 91 115 - 91 117 - 91 118 - 91 119 - 91 123 - 91 155 - 91 171 - 91 173 - 91 174 - 91 175 - 91 179 - 91 181 - 91 182 - 91 183 - 91 187 - 91 219 - 92 94 - 92 95 - 92 96 - 92 108 - 92 110 - 92 112 - 92 116 - 92 118 - 92 119 - 92 120 - 92 124 - 92 156 - 92 172 - 92 174 - 92 176 - 92 180 - 92 182 - 92 183 - 92 184 - 92 188 - 92 220 - 93 94 - 93 95 - 93 109 - 93 111 - 93 117 - 93 121 - 93 122 - 93 123 - 93 125 - 93 157 - 93 173 - 93 175 - 93 181 - 93 185 - 93 186 - 93 187 - 93 189 - 93 221 - 94 95 - 94 96 - 94 110 - 94 111 - 94 112 - 94 118 - 94 122 - 94 123 - 94 124 - 94 126 - 94 158 - 94 174 - 94 175 - 94 176 - 94 182 - 94 186 - 94 187 - 94 188 - 94 190 - 94 222 - 95 96 - 95 111 - 95 112 - 95 119 - 95 123 - 95 125 - 95 126 - 95 127 - 95 159 - 95 175 - 95 176 - 95 183 - 95 187 - 95 189 - 95 190 - 95 191 - 95 223 - 96 112 - 96 120 - 96 124 - 96 126 - 96 127 - 96 128 - 96 160 - 96 176 - 96 184 - 96 188 - 96 190 - 96 191 - 96 192 - 96 224 - 97 98 - 97 99 - 97 101 - 97 105 - 97 113 - 97 161 - 97 177 - 97 193 - 97 194 - 97 195 - 97 197 - 97 201 - 97 209 - 97 225 - 98 99 - 98 100 - 98 101 - 98 102 - 98 105 - 98 106 - 98 113 - 98 114 - 98 162 - 98 177 - 98 178 - 98 194 - 98 195 - 98 196 - 98 198 - 98 202 - 98 210 - 98 226 - 99 100 - 99 101 - 99 102 - 99 103 - 99 105 - 99 106 - 99 107 - 99 113 - 99 114 - 99 115 - 99 163 - 99 177 - 99 178 - 99 179 - 99 195 - 99 197 - 99 198 - 99 199 - 99 203 - 99 211 - 99 227 - 100 102 - 100 103 - 100 104 - 100 106 - 100 108 - 100 114 - 100 116 - 100 164 - 100 178 - 100 180 - 100 196 - 100 198 - 100 199 - 100 200 - 100 204 - 100 212 - 100 228 - 101 102 - 101 103 - 101 105 - 101 106 - 101 107 - 101 109 - 101 113 - 101 115 - 101 117 - 101 165 - 101 177 - 101 179 - 101 181 - 101 197 - 101 201 - 101 202 - 101 203 - 101 205 - 101 213 - 101 229 - 102 103 - 102 104 - 102 106 - 102 107 - 102 108 - 102 110 - 102 114 - 102 115 - 102 116 - 102 118 - 102 166 - 102 178 - 102 179 - 102 180 - 102 182 - 102 198 - 102 202 - 102 203 - 102 204 - 102 206 - 102 214 - 102 230 - 103 104 - 103 107 - 103 108 - 103 109 - 103 110 - 103 111 - 103 115 - 103 116 - 103 119 - 103 167 - 103 179 - 103 180 - 103 183 - 103 199 - 103 203 - 103 205 - 103 206 - 103 207 - 103 215 - 103 231 - 104 108 - 104 110 - 104 111 - 104 112 - 104 116 - 104 120 - 104 168 - 104 180 - 104 184 - 104 200 - 104 204 - 104 206 - 104 207 - 104 208 - 104 216 - 104 232 - 105 106 - 105 107 - 105 109 - 105 113 - 105 114 - 105 115 - 105 117 - 105 121 - 105 169 - 105 177 - 105 181 - 105 185 - 105 201 - 105 209 - 105 210 - 105 211 - 105 213 - 105 217 - 105 233 - 106 107 - 106 108 - 106 109 - 106 110 - 106 114 - 106 115 - 106 116 - 106 117 - 106 118 - 106 122 - 106 170 - 106 178 - 106 181 - 106 182 - 106 186 - 106 202 - 106 210 - 106 211 - 106 212 - 106 214 - 106 218 - 106 234 - 107 108 - 107 109 - 107 110 - 107 111 - 107 115 - 107 117 - 107 118 - 107 119 - 107 123 - 107 171 - 107 179 - 107 181 - 107 182 - 107 183 - 107 187 - 107 203 - 107 211 - 107 213 - 107 214 - 107 215 - 107 219 - 107 235 - 108 110 - 108 111 - 108 112 - 108 116 - 108 118 - 108 119 - 108 120 - 108 124 - 108 172 - 108 180 - 108 182 - 108 184 - 108 188 - 108 204 - 108 212 - 108 214 - 108 215 - 108 216 - 108 220 - 108 236 - 109 110 - 109 111 - 109 117 - 109 119 - 109 121 - 109 122 - 109 123 - 109 125 - 109 173 - 109 181 - 109 183 - 109 189 - 109 205 - 109 213 - 109 217 - 109 218 - 109 219 - 109 221 - 109 237 - 110 111 - 110 112 - 110 118 - 110 119 - 110 120 - 110 122 - 110 123 - 110 124 - 110 126 - 110 174 - 110 182 - 110 183 - 110 184 - 110 190 - 110 206 - 110 214 - 110 218 - 110 219 - 110 220 - 110 222 - 110 238 - 111 112 - 111 119 - 111 120 - 111 123 - 111 125 - 111 126 - 111 127 - 111 175 - 111 183 - 111 184 - 111 191 - 111 207 - 111 215 - 111 219 - 111 221 - 111 222 - 111 223 - 111 239 - 112 120 - 112 124 - 112 126 - 112 127 - 112 128 - 112 176 - 112 184 - 112 192 - 112 208 - 112 216 - 112 220 - 112 222 - 112 223 - 112 224 - 112 240 - 113 114 - 113 115 - 113 117 - 113 121 - 113 177 - 113 185 - 113 209 - 113 225 - 113 226 - 113 227 - 113 229 - 113 233 - 113 241 - 114 115 - 114 116 - 114 117 - 114 118 - 114 121 - 114 122 - 114 178 - 114 185 - 114 186 - 114 210 - 114 226 - 114 227 - 114 228 - 114 230 - 114 234 - 114 242 - 115 116 - 115 117 - 115 118 - 115 119 - 115 121 - 115 122 - 115 123 - 115 179 - 115 185 - 115 186 - 115 187 - 115 211 - 115 227 - 115 229 - 115 230 - 115 231 - 115 235 - 115 243 - 116 118 - 116 119 - 116 120 - 116 122 - 116 124 - 116 180 - 116 186 - 116 188 - 116 212 - 116 228 - 116 230 - 116 231 - 116 232 - 116 236 - 116 244 - 117 118 - 117 119 - 117 121 - 117 122 - 117 123 - 117 125 - 117 181 - 117 185 - 117 187 - 117 189 - 117 213 - 117 229 - 117 233 - 117 234 - 117 235 - 117 237 - 117 245 - 118 119 - 118 120 - 118 122 - 118 123 - 118 124 - 118 126 - 118 182 - 118 186 - 118 187 - 118 188 - 118 190 - 118 214 - 118 230 - 118 234 - 118 235 - 118 236 - 118 238 - 118 246 - 119 120 - 119 123 - 119 124 - 119 125 - 119 126 - 119 127 - 119 183 - 119 187 - 119 188 - 119 191 - 119 215 - 119 231 - 119 235 - 119 237 - 119 238 - 119 239 - 119 247 - 120 124 - 120 126 - 120 127 - 120 128 - 120 184 - 120 188 - 120 192 - 120 216 - 120 232 - 120 236 - 120 238 - 120 239 - 120 240 - 120 248 - 121 122 - 121 123 - 121 125 - 121 185 - 121 189 - 121 217 - 121 233 - 121 241 - 121 242 - 121 243 - 121 245 - 121 249 - 122 123 - 122 124 - 122 125 - 122 126 - 122 186 - 122 189 - 122 190 - 122 218 - 122 234 - 122 242 - 122 243 - 122 244 - 122 246 - 122 250 - 123 124 - 123 125 - 123 126 - 123 127 - 123 187 - 123 189 - 123 190 - 123 191 - 123 219 - 123 235 - 123 243 - 123 245 - 123 246 - 123 247 - 123 251 - 124 126 - 124 127 - 124 128 - 124 188 - 124 190 - 124 192 - 124 220 - 124 236 - 124 244 - 124 246 - 124 247 - 124 248 - 124 252 - 125 126 - 125 127 - 125 189 - 125 191 - 125 221 - 125 237 - 125 245 - 125 249 - 125 250 - 125 251 - 125 253 - 126 127 - 126 128 - 126 190 - 126 191 - 126 192 - 126 222 - 126 238 - 126 246 - 126 250 - 126 251 - 126 252 - 126 254 - 127 128 - 127 191 - 127 192 - 127 223 - 127 239 - 127 247 - 127 251 - 127 253 - 127 254 - 127 255 - 128 192 - 128 224 - 128 240 - 128 248 - 128 252 - 128 254 - 128 255 - 128 256 - 129 130 - 129 131 - 129 133 - 129 137 - 129 145 - 129 161 - 129 193 - 130 131 - 130 132 - 130 133 - 130 134 - 130 137 - 130 138 - 130 145 - 130 146 - 130 161 - 130 162 - 130 193 - 130 194 - 131 132 - 131 133 - 131 134 - 131 135 - 131 137 - 131 138 - 131 139 - 131 145 - 131 146 - 131 147 - 131 161 - 131 162 - 131 163 - 131 193 - 131 194 - 131 195 - 132 134 - 132 135 - 132 136 - 132 138 - 132 140 - 132 146 - 132 148 - 132 162 - 132 164 - 132 194 - 132 196 - 133 134 - 133 135 - 133 137 - 133 138 - 133 139 - 133 141 - 133 145 - 133 147 - 133 149 - 133 161 - 133 163 - 133 165 - 133 193 - 133 195 - 133 197 - 134 135 - 134 136 - 134 138 - 134 139 - 134 140 - 134 142 - 134 146 - 134 147 - 134 148 - 134 150 - 134 162 - 134 163 - 134 164 - 134 166 - 134 194 - 134 195 - 134 196 - 134 198 - 135 136 - 135 139 - 135 140 - 135 141 - 135 142 - 135 143 - 135 147 - 135 148 - 135 151 - 135 163 - 135 164 - 135 167 - 135 195 - 135 196 - 135 199 - 136 140 - 136 142 - 136 143 - 136 144 - 136 148 - 136 152 - 136 164 - 136 168 - 136 196 - 136 200 - 137 138 - 137 139 - 137 141 - 137 145 - 137 146 - 137 147 - 137 149 - 137 153 - 137 161 - 137 165 - 137 169 - 137 193 - 137 197 - 137 201 - 138 139 - 138 140 - 138 141 - 138 142 - 138 146 - 138 147 - 138 148 - 138 149 - 138 150 - 138 154 - 138 162 - 138 165 - 138 166 - 138 170 - 138 194 - 138 197 - 138 198 - 138 202 - 139 140 - 139 141 - 139 142 - 139 143 - 139 147 - 139 149 - 139 150 - 139 151 - 139 155 - 139 163 - 139 165 - 139 166 - 139 167 - 139 171 - 139 195 - 139 197 - 139 198 - 139 199 - 139 203 - 140 142 - 140 143 - 140 144 - 140 148 - 140 150 - 140 151 - 140 152 - 140 156 - 140 164 - 140 166 - 140 168 - 140 172 - 140 196 - 140 198 - 140 200 - 140 204 - 141 142 - 141 143 - 141 149 - 141 151 - 141 153 - 141 154 - 141 155 - 141 157 - 141 165 - 141 167 - 141 173 - 141 197 - 141 199 - 141 205 - 142 143 - 142 144 - 142 150 - 142 151 - 142 152 - 142 154 - 142 155 - 142 156 - 142 158 - 142 166 - 142 167 - 142 168 - 142 174 - 142 198 - 142 199 - 142 200 - 142 206 - 143 144 - 143 151 - 143 152 - 143 155 - 143 157 - 143 158 - 143 159 - 143 167 - 143 168 - 143 175 - 143 199 - 143 200 - 143 207 - 144 152 - 144 156 - 144 158 - 144 159 - 144 160 - 144 168 - 144 176 - 144 200 - 144 208 - 145 146 - 145 147 - 145 149 - 145 153 - 145 161 - 145 162 - 145 163 - 145 165 - 145 169 - 145 177 - 145 193 - 145 201 - 145 209 - 146 147 - 146 148 - 146 149 - 146 150 - 146 153 - 146 154 - 146 162 - 146 163 - 146 164 - 146 166 - 146 169 - 146 170 - 146 178 - 146 194 - 146 201 - 146 202 - 146 210 - 147 148 - 147 149 - 147 150 - 147 151 - 147 153 - 147 154 - 147 155 - 147 163 - 147 165 - 147 166 - 147 167 - 147 169 - 147 170 - 147 171 - 147 179 - 147 195 - 147 201 - 147 202 - 147 203 - 147 211 - 148 150 - 148 151 - 148 152 - 148 154 - 148 156 - 148 164 - 148 166 - 148 167 - 148 168 - 148 170 - 148 172 - 148 180 - 148 196 - 148 202 - 148 204 - 148 212 - 149 150 - 149 151 - 149 153 - 149 154 - 149 155 - 149 157 - 149 165 - 149 169 - 149 170 - 149 171 - 149 173 - 149 181 - 149 197 - 149 201 - 149 203 - 149 205 - 149 213 - 150 151 - 150 152 - 150 154 - 150 155 - 150 156 - 150 158 - 150 166 - 150 170 - 150 171 - 150 172 - 150 174 - 150 182 - 150 198 - 150 202 - 150 203 - 150 204 - 150 206 - 150 214 - 151 152 - 151 155 - 151 156 - 151 157 - 151 158 - 151 159 - 151 167 - 151 171 - 151 172 - 151 173 - 151 174 - 151 175 - 151 183 - 151 199 - 151 203 - 151 204 - 151 207 - 151 215 - 152 156 - 152 158 - 152 159 - 152 160 - 152 168 - 152 172 - 152 174 - 152 175 - 152 176 - 152 184 - 152 200 - 152 204 - 152 208 - 152 216 - 153 154 - 153 155 - 153 157 - 153 169 - 153 173 - 153 177 - 153 178 - 153 179 - 153 181 - 153 185 - 153 201 - 153 205 - 153 217 - 154 155 - 154 156 - 154 157 - 154 158 - 154 170 - 154 173 - 154 174 - 154 178 - 154 179 - 154 180 - 154 182 - 154 186 - 154 202 - 154 205 - 154 206 - 154 218 - 155 156 - 155 157 - 155 158 - 155 159 - 155 171 - 155 173 - 155 174 - 155 175 - 155 179 - 155 181 - 155 182 - 155 183 - 155 187 - 155 203 - 155 205 - 155 206 - 155 207 - 155 219 - 156 158 - 156 159 - 156 160 - 156 172 - 156 174 - 156 176 - 156 180 - 156 182 - 156 183 - 156 184 - 156 188 - 156 204 - 156 206 - 156 208 - 156 220 - 157 158 - 157 159 - 157 173 - 157 175 - 157 181 - 157 185 - 157 186 - 157 187 - 157 189 - 157 205 - 157 207 - 157 221 - 158 159 - 158 160 - 158 174 - 158 175 - 158 176 - 158 182 - 158 186 - 158 187 - 158 188 - 158 190 - 158 206 - 158 207 - 158 208 - 158 222 - 159 160 - 159 175 - 159 176 - 159 183 - 159 187 - 159 189 - 159 190 - 159 191 - 159 207 - 159 208 - 159 223 - 160 176 - 160 184 - 160 188 - 160 190 - 160 191 - 160 192 - 160 208 - 160 224 - 161 162 - 161 163 - 161 165 - 161 169 - 161 177 - 161 193 - 161 194 - 161 195 - 161 197 - 161 201 - 161 209 - 161 225 - 162 163 - 162 164 - 162 165 - 162 166 - 162 169 - 162 170 - 162 177 - 162 178 - 162 194 - 162 195 - 162 196 - 162 198 - 162 202 - 162 209 - 162 210 - 162 226 - 163 164 - 163 165 - 163 166 - 163 167 - 163 169 - 163 170 - 163 171 - 163 177 - 163 178 - 163 179 - 163 195 - 163 197 - 163 198 - 163 199 - 163 203 - 163 209 - 163 210 - 163 211 - 163 227 - 164 166 - 164 167 - 164 168 - 164 170 - 164 172 - 164 178 - 164 180 - 164 196 - 164 198 - 164 199 - 164 200 - 164 204 - 164 210 - 164 212 - 164 228 - 165 166 - 165 167 - 165 169 - 165 170 - 165 171 - 165 173 - 165 177 - 165 179 - 165 181 - 165 197 - 165 201 - 165 202 - 165 203 - 165 205 - 165 209 - 165 211 - 165 213 - 165 229 - 166 167 - 166 168 - 166 170 - 166 171 - 166 172 - 166 174 - 166 178 - 166 179 - 166 180 - 166 182 - 166 198 - 166 202 - 166 203 - 166 204 - 166 206 - 166 210 - 166 211 - 166 212 - 166 214 - 166 230 - 167 168 - 167 171 - 167 172 - 167 173 - 167 174 - 167 175 - 167 179 - 167 180 - 167 183 - 167 199 - 167 203 - 167 205 - 167 206 - 167 207 - 167 211 - 167 212 - 167 215 - 167 231 - 168 172 - 168 174 - 168 175 - 168 176 - 168 180 - 168 184 - 168 200 - 168 204 - 168 206 - 168 207 - 168 208 - 168 212 - 168 216 - 168 232 - 169 170 - 169 171 - 169 173 - 169 177 - 169 178 - 169 179 - 169 181 - 169 185 - 169 201 - 169 209 - 169 210 - 169 211 - 169 213 - 169 217 - 169 233 - 170 171 - 170 172 - 170 173 - 170 174 - 170 178 - 170 179 - 170 180 - 170 181 - 170 182 - 170 186 - 170 202 - 170 210 - 170 211 - 170 212 - 170 213 - 170 214 - 170 218 - 170 234 - 171 172 - 171 173 - 171 174 - 171 175 - 171 179 - 171 181 - 171 182 - 171 183 - 171 187 - 171 203 - 171 211 - 171 213 - 171 214 - 171 215 - 171 219 - 171 235 - 172 174 - 172 175 - 172 176 - 172 180 - 172 182 - 172 183 - 172 184 - 172 188 - 172 204 - 172 212 - 172 214 - 172 215 - 172 216 - 172 220 - 172 236 - 173 174 - 173 175 - 173 181 - 173 183 - 173 185 - 173 186 - 173 187 - 173 189 - 173 205 - 173 213 - 173 215 - 173 217 - 173 218 - 173 219 - 173 221 - 173 237 - 174 175 - 174 176 - 174 182 - 174 183 - 174 184 - 174 186 - 174 187 - 174 188 - 174 190 - 174 206 - 174 214 - 174 215 - 174 216 - 174 218 - 174 219 - 174 220 - 174 222 - 174 238 - 175 176 - 175 183 - 175 184 - 175 187 - 175 189 - 175 190 - 175 191 - 175 207 - 175 215 - 175 216 - 175 219 - 175 221 - 175 222 - 175 223 - 175 239 - 176 184 - 176 188 - 176 190 - 176 191 - 176 192 - 176 208 - 176 216 - 176 220 - 176 222 - 176 223 - 176 224 - 176 240 - 177 178 - 177 179 - 177 181 - 177 185 - 177 209 - 177 217 - 177 225 - 177 226 - 177 227 - 177 229 - 177 233 - 177 241 - 178 179 - 178 180 - 178 181 - 178 182 - 178 185 - 178 186 - 178 210 - 178 217 - 178 218 - 178 226 - 178 227 - 178 228 - 178 230 - 178 234 - 178 242 - 179 180 - 179 181 - 179 182 - 179 183 - 179 185 - 179 186 - 179 187 - 179 211 - 179 217 - 179 218 - 179 219 - 179 227 - 179 229 - 179 230 - 179 231 - 179 235 - 179 243 - 180 182 - 180 183 - 180 184 - 180 186 - 180 188 - 180 212 - 180 218 - 180 220 - 180 228 - 180 230 - 180 231 - 180 232 - 180 236 - 180 244 - 181 182 - 181 183 - 181 185 - 181 186 - 181 187 - 181 189 - 181 213 - 181 217 - 181 219 - 181 221 - 181 229 - 181 233 - 181 234 - 181 235 - 181 237 - 181 245 - 182 183 - 182 184 - 182 186 - 182 187 - 182 188 - 182 190 - 182 214 - 182 218 - 182 219 - 182 220 - 182 222 - 182 230 - 182 234 - 182 235 - 182 236 - 182 238 - 182 246 - 183 184 - 183 187 - 183 188 - 183 189 - 183 190 - 183 191 - 183 215 - 183 219 - 183 220 - 183 223 - 183 231 - 183 235 - 183 237 - 183 238 - 183 239 - 183 247 - 184 188 - 184 190 - 184 191 - 184 192 - 184 216 - 184 220 - 184 224 - 184 232 - 184 236 - 184 238 - 184 239 - 184 240 - 184 248 - 185 186 - 185 187 - 185 189 - 185 217 - 185 221 - 185 233 - 185 241 - 185 242 - 185 243 - 185 245 - 185 249 - 186 187 - 186 188 - 186 189 - 186 190 - 186 218 - 186 221 - 186 222 - 186 234 - 186 242 - 186 243 - 186 244 - 186 246 - 186 250 - 187 188 - 187 189 - 187 190 - 187 191 - 187 219 - 187 221 - 187 222 - 187 223 - 187 235 - 187 243 - 187 245 - 187 246 - 187 247 - 187 251 - 188 190 - 188 191 - 188 192 - 188 220 - 188 222 - 188 224 - 188 236 - 188 244 - 188 246 - 188 247 - 188 248 - 188 252 - 189 190 - 189 191 - 189 221 - 189 223 - 189 237 - 189 245 - 189 249 - 189 250 - 189 251 - 189 253 - 190 191 - 190 192 - 190 222 - 190 223 - 190 224 - 190 238 - 190 246 - 190 250 - 190 251 - 190 252 - 190 254 - 191 192 - 191 223 - 191 224 - 191 239 - 191 247 - 191 251 - 191 253 - 191 254 - 191 255 - 192 224 - 192 240 - 192 248 - 192 252 - 192 254 - 192 255 - 192 256 - 193 194 - 193 195 - 193 197 - 193 201 - 193 209 - 193 225 - 194 195 - 194 196 - 194 197 - 194 198 - 194 201 - 194 202 - 194 209 - 194 210 - 194 225 - 194 226 - 195 196 - 195 197 - 195 198 - 195 199 - 195 201 - 195 202 - 195 203 - 195 209 - 195 210 - 195 211 - 195 225 - 195 226 - 195 227 - 196 198 - 196 199 - 196 200 - 196 202 - 196 204 - 196 210 - 196 212 - 196 226 - 196 228 - 197 198 - 197 199 - 197 201 - 197 202 - 197 203 - 197 205 - 197 209 - 197 211 - 197 213 - 197 225 - 197 227 - 197 229 - 198 199 - 198 200 - 198 202 - 198 203 - 198 204 - 198 206 - 198 210 - 198 211 - 198 212 - 198 214 - 198 226 - 198 227 - 198 228 - 198 230 - 199 200 - 199 203 - 199 204 - 199 205 - 199 206 - 199 207 - 199 211 - 199 212 - 199 215 - 199 227 - 199 228 - 199 231 - 200 204 - 200 206 - 200 207 - 200 208 - 200 212 - 200 216 - 200 228 - 200 232 - 201 202 - 201 203 - 201 205 - 201 209 - 201 210 - 201 211 - 201 213 - 201 217 - 201 225 - 201 229 - 201 233 - 202 203 - 202 204 - 202 205 - 202 206 - 202 210 - 202 211 - 202 212 - 202 213 - 202 214 - 202 218 - 202 226 - 202 229 - 202 230 - 202 234 - 203 204 - 203 205 - 203 206 - 203 207 - 203 211 - 203 213 - 203 214 - 203 215 - 203 219 - 203 227 - 203 229 - 203 230 - 203 231 - 203 235 - 204 206 - 204 207 - 204 208 - 204 212 - 204 214 - 204 215 - 204 216 - 204 220 - 204 228 - 204 230 - 204 232 - 204 236 - 205 206 - 205 207 - 205 213 - 205 215 - 205 217 - 205 218 - 205 219 - 205 221 - 205 229 - 205 231 - 205 237 - 206 207 - 206 208 - 206 214 - 206 215 - 206 216 - 206 218 - 206 219 - 206 220 - 206 222 - 206 230 - 206 231 - 206 232 - 206 238 - 207 208 - 207 215 - 207 216 - 207 219 - 207 221 - 207 222 - 207 223 - 207 231 - 207 232 - 207 239 - 208 216 - 208 220 - 208 222 - 208 223 - 208 224 - 208 232 - 208 240 - 209 210 - 209 211 - 209 213 - 209 217 - 209 225 - 209 226 - 209 227 - 209 229 - 209 233 - 209 241 - 210 211 - 210 212 - 210 213 - 210 214 - 210 217 - 210 218 - 210 226 - 210 227 - 210 228 - 210 230 - 210 233 - 210 234 - 210 242 - 211 212 - 211 213 - 211 214 - 211 215 - 211 217 - 211 218 - 211 219 - 211 227 - 211 229 - 211 230 - 211 231 - 211 233 - 211 234 - 211 235 - 211 243 - 212 214 - 212 215 - 212 216 - 212 218 - 212 220 - 212 228 - 212 230 - 212 231 - 212 232 - 212 234 - 212 236 - 212 244 - 213 214 - 213 215 - 213 217 - 213 218 - 213 219 - 213 221 - 213 229 - 213 233 - 213 234 - 213 235 - 213 237 - 213 245 - 214 215 - 214 216 - 214 218 - 214 219 - 214 220 - 214 222 - 214 230 - 214 234 - 214 235 - 214 236 - 214 238 - 214 246 - 215 216 - 215 219 - 215 220 - 215 221 - 215 222 - 215 223 - 215 231 - 215 235 - 215 236 - 215 237 - 215 238 - 215 239 - 215 247 - 216 220 - 216 222 - 216 223 - 216 224 - 216 232 - 216 236 - 216 238 - 216 239 - 216 240 - 216 248 - 217 218 - 217 219 - 217 221 - 217 233 - 217 237 - 217 241 - 217 242 - 217 243 - 217 245 - 217 249 - 218 219 - 218 220 - 218 221 - 218 222 - 218 234 - 218 237 - 218 238 - 218 242 - 218 243 - 218 244 - 218 246 - 218 250 - 219 220 - 219 221 - 219 222 - 219 223 - 219 235 - 219 237 - 219 238 - 219 239 - 219 243 - 219 245 - 219 246 - 219 247 - 219 251 - 220 222 - 220 223 - 220 224 - 220 236 - 220 238 - 220 240 - 220 244 - 220 246 - 220 247 - 220 248 - 220 252 - 221 222 - 221 223 - 221 237 - 221 239 - 221 245 - 221 249 - 221 250 - 221 251 - 221 253 - 222 223 - 222 224 - 222 238 - 222 239 - 222 240 - 222 246 - 222 250 - 222 251 - 222 252 - 222 254 - 223 224 - 223 239 - 223 240 - 223 247 - 223 251 - 223 253 - 223 254 - 223 255 - 224 240 - 224 248 - 224 252 - 224 254 - 224 255 - 224 256 - 225 226 - 225 227 - 225 229 - 225 233 - 225 241 - 226 227 - 226 228 - 226 229 - 226 230 - 226 233 - 226 234 - 226 241 - 226 242 - 227 228 - 227 229 - 227 230 - 227 231 - 227 233 - 227 234 - 227 235 - 227 241 - 227 242 - 227 243 - 228 230 - 228 231 - 228 232 - 228 234 - 228 236 - 228 242 - 228 244 - 229 230 - 229 231 - 229 233 - 229 234 - 229 235 - 229 237 - 229 241 - 229 243 - 229 245 - 230 231 - 230 232 - 230 234 - 230 235 - 230 236 - 230 238 - 230 242 - 230 243 - 230 244 - 230 246 - 231 232 - 231 235 - 231 236 - 231 237 - 231 238 - 231 239 - 231 243 - 231 244 - 231 247 - 232 236 - 232 238 - 232 239 - 232 240 - 232 244 - 232 248 - 233 234 - 233 235 - 233 237 - 233 241 - 233 242 - 233 243 - 233 245 - 233 249 - 234 235 - 234 236 - 234 237 - 234 238 - 234 242 - 234 243 - 234 244 - 234 245 - 234 246 - 234 250 - 235 236 - 235 237 - 235 238 - 235 239 - 235 243 - 235 245 - 235 246 - 235 247 - 235 251 - 236 238 - 236 239 - 236 240 - 236 244 - 236 246 - 236 247 - 236 248 - 236 252 - 237 238 - 237 239 - 237 245 - 237 247 - 237 249 - 237 250 - 237 251 - 237 253 - 238 239 - 238 240 - 238 246 - 238 247 - 238 248 - 238 250 - 238 251 - 238 252 - 238 254 - 239 240 - 239 247 - 239 248 - 239 251 - 239 253 - 239 254 - 239 255 - 240 248 - 240 252 - 240 254 - 240 255 - 240 256 - 241 242 - 241 243 - 241 245 - 241 249 - 242 243 - 242 244 - 242 245 - 242 246 - 242 249 - 242 250 - 243 244 - 243 245 - 243 246 - 243 247 - 243 249 - 243 250 - 243 251 - 244 246 - 244 247 - 244 248 - 244 250 - 244 252 - 245 246 - 245 247 - 245 249 - 245 250 - 245 251 - 245 253 - 246 247 - 246 248 - 246 250 - 246 251 - 246 252 - 246 254 - 247 248 - 247 251 - 247 252 - 247 253 - 247 254 - 247 255 - 248 252 - 248 254 - 248 255 - 248 256 - 249 250 - 249 251 - 249 253 - 250 251 - 250 252 - 250 253 - 250 254 - 251 252 - 251 253 - 251 254 - 251 255 - 252 254 - 252 255 - 252 256 - 253 254 - 253 255 - 254 255 - 254 256 - 255 256 -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/money.mod b/resources/3rdparty/glpk-4.53/examples/money.mod deleted file mode 100644 index e43ef390b..000000000 --- a/resources/3rdparty/glpk-4.53/examples/money.mod +++ /dev/null @@ -1,62 +0,0 @@ -/* MONEY, a crypto-arithmetic puzzle */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* This is the classic example of a crypto-arithmetic puzzle published - in the Strand Magazine by Henry Dudeney: - - S E N D - + - M O R E - --------- - M O N E Y - - In this puzzle the same letters mean the same digits. The question - is: how to replace all the letters with the respective digits that - makes the calculation correct? - - The solution to this puzzle is: - O = 0, M = 1, Y = 2, E = 5, N = 6, D = 7, R = 8, and S = 9. - - References: - H. E. Dudeney, in Strand Magazine vol. 68 (July 1924), pp. 97, 214. - - (From Wikipedia, the free encyclopedia.) */ - -set LETTERS := { 'D', 'E', 'M', 'N', 'O', 'R', 'S', 'Y' }; -/* set of letters */ - -set DIGITS := 0..9; -/* set of digits */ - -var x{i in LETTERS, d in DIGITS}, binary; -/* x[i,d] = 1 means that letter i is digit d */ - -s.t. one{i in LETTERS}: sum{d in DIGITS} x[i,d] = 1; -/* each letter must correspond exactly to one digit */ - -s.t. alldiff{d in DIGITS}: sum{i in LETTERS} x[i,d] <= 1; -/* different letters must correspond to different digits; note that - some digits may not correspond to any letters at all */ - -var dig{i in LETTERS}; -/* dig[i] is a digit corresponding to letter i */ - -s.t. map{i in LETTERS}: dig[i] = sum{d in DIGITS} d * x[i,d]; - -var carry{1..3}, binary; -/* carry bits */ - -s.t. sum1: dig['D'] + dig['E'] = dig['Y'] + 10 * carry[1]; -s.t. sum2: dig['N'] + dig['R'] + carry[1] = dig['E'] + 10 * carry[2]; -s.t. sum3: dig['E'] + dig['O'] + carry[2] = dig['N'] + 10 * carry[3]; -s.t. sum4: dig['S'] + dig['M'] + carry[3] = dig['O'] + 10 * dig['M']; -s.t. note: dig['M'] >= 1; /* M must not be 0 */ - -solve; -/* solve the puzzle */ - -display dig; -/* and display its solution */ - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/mplsamp1.c b/resources/3rdparty/glpk-4.53/examples/mplsamp1.c deleted file mode 100644 index 7c5e47d4d..000000000 --- a/resources/3rdparty/glpk-4.53/examples/mplsamp1.c +++ /dev/null @@ -1,32 +0,0 @@ -/* mplsamp1.c */ - -#include -#include -#include - -int main(void) -{ glp_prob *lp; - glp_tran *tran; - int ret; - lp = glp_create_prob(); - tran = glp_mpl_alloc_wksp(); - ret = glp_mpl_read_model(tran, "egypt.mod", 0); - if (ret != 0) - { fprintf(stderr, "Error on translating model\n"); - goto skip; - } - ret = glp_mpl_generate(tran, NULL); - if (ret != 0) - { fprintf(stderr, "Error on generating model\n"); - goto skip; - } - glp_mpl_build_prob(tran, lp); - ret = glp_write_mps(lp, GLP_MPS_FILE, NULL, "egypt.mps"); - if (ret != 0) - fprintf(stderr, "Error on writing MPS file\n"); -skip: glp_mpl_free_wksp(tran); - glp_delete_prob(lp); - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/examples/mplsamp2.c b/resources/3rdparty/glpk-4.53/examples/mplsamp2.c deleted file mode 100644 index 0ff6ad0ff..000000000 --- a/resources/3rdparty/glpk-4.53/examples/mplsamp2.c +++ /dev/null @@ -1,39 +0,0 @@ -/* mplsamp2.c */ - -#include -#include -#include - -int main(void) -{ glp_prob *mip; - glp_tran *tran; - int ret; - mip = glp_create_prob(); - tran = glp_mpl_alloc_wksp(); - ret = glp_mpl_read_model(tran, "sudoku.mod", 1); - if (ret != 0) - { fprintf(stderr, "Error on translating model\n"); - goto skip; - } - ret = glp_mpl_read_data(tran, "sudoku.dat"); - if (ret != 0) - { fprintf(stderr, "Error on translating data\n"); - goto skip; - } - ret = glp_mpl_generate(tran, NULL); - if (ret != 0) - { fprintf(stderr, "Error on generating model\n"); - goto skip; - } - glp_mpl_build_prob(tran, mip); - glp_simplex(mip, NULL); - glp_intopt(mip, NULL); - ret = glp_mpl_postsolve(tran, mip, GLP_MIP); - if (ret != 0) - fprintf(stderr, "Error on postsolving model\n"); -skip: glp_mpl_free_wksp(tran); - glp_delete_prob(mip); - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/examples/murtagh.mps b/resources/3rdparty/glpk-4.53/examples/murtagh.mps deleted file mode 100644 index c03741b51..000000000 --- a/resources/3rdparty/glpk-4.53/examples/murtagh.mps +++ /dev/null @@ -1,600 +0,0 @@ -*NAME: OIL -*ROWS: 74 -*COLUMNS: 81 -*NONZERO: 504 -*OPT SOLN: 126.057 -*SOURCE: Bruce Murtagh, "Advanced Linear Programming" -*APPLICATION: oil refinery model -*COMMENTS: problem is maximization -* -NAME OIL REFINERY EXAMPLE -ROWS - N PROFIT - L MVOLBOL - L MVOLCOL - E MVOLLNC - E MVOLLNB - E MVOLSRK - E MVOLSRD - E MVOLVBB - E MVOLVBC - E MVOLRCR - E MVOLHVO - E UBALKWH - E UBALH2O - E UBALSTM - E UBALFUL - E MVOLB95 - E MVOLB90 - E MVOLLHG - E MVOLC3S - E MVOLNC4 - E MVOLLSR - E MVOLHSR - E MVOLIC4 - L VCAPSGP - E MVOLRFG - E MSCFHYL - E MVOLR90 - E MVOLR95 - E MVOLF90 - E MVOLF95 - L VCAPRFG - E MVOLLCO - E MVOLHHG - E MVOLHCD - L VCAPHVO - L VCAPHOL - E MVOLC3U - E MVOLC4U - E MVOLFCG - E MVOLSLR - L VCAPCCU - E MVOLLA3 - E MVOLLA4 - L VCAPALK - L XLPRPRE - L XHPRPRE - L XTELPRE - L XRVPPRE - L X200PRE - L X230PRE - E EVOLPRE - L XPSCPRE - L XRSCREG - L XLPRINT - L XHPRINT - L XTELINT - L XRVPINT - L X200INT - L X230INT - E EVOLINT - L XLPRREG - L XHPRREG - L XTELREG - L XRVPREG - L X200REG - L X230REG - E EVOLREG - E EVOLLPG - E EVOLJP4 - L XRVXJP4 - L XRVNJP4 - E EVOLDSL - E EVOLRSD - L XVISRSD -COLUMNS - VCRDBOL MVOLBOL 1.0 - VCRDBOL MVOLLNB -.537 - VCRDBOL MVOLSRK -.131 - VCRDBOL MVOLSRD -.1155 - VCRDBOL MVOLVBB -.037 - VCRDBOL MVOLRCR -.0365 - VCRDBOL MVOLHVO -.143 - VCRDBOL UBALKWH .302 - VCRDBOL UBALH2O .150 - VCRDBOL UBALSTM .003 - VCRDBOL UBALFUL .0587 - VCRDBOL PROFIT -12.8 - VCRDCOL MVOLCOL 1. - VCRDCOL MVOLLNC -.2931 - VCRDCOL MVOLSRK -.1170 - VCRDCOL MVOLSRD -.0649 - VCRDCOL MVOLVBC -.18 - VCRDCOL MVOLRCR -.1233 - VCRDCOL MVOLHVO -.2217 - VCRDCOL UBALKWH .384 - VCRDCOL UBALH2O .185 - VCRDCOL UBALSTM .003 - VCRDCOL UBALFUL .1053 - VCRDCOL PROFIT -11.48 - VSGPLNC MVOLLNC 1. - VSGPLNC MVOLC3S -.0112 - VSGPLNC MVOLNC4 -.0378 - VSGPLNC MVOLLSR -.1502 - VSGPLNC MVOLHSR -.7953 - VSGPLNC MVOLIC4 -.0099 - VSGPLNC UBALKWH .721 - VSGPLNC UBALH2O .185 - VSGPLNC UBALSTM .013 - VSGPLNC UBALFUL .0488 - VSGPLNC VCAPSGP 1. - VSGPLNB MVOLLNB 1. - VSGPLNB MVOLC3S -.0277 - VSGPLNB MVOLNC4 -.0563 - VSGPLNB MVOLLSR -.199 - VSGPLNB MVOLHSR -.6873 - VSGPLNB MVOLIC4 -.017 - VSGPLNB UBALKWH .495 - VSGPLNB UBALH2O .209 - VSGPLNB UBALSTM .013 - VSGPLNB UBALFUL .0506 - VSGPLNB VCAPSGP 1. - VSGPLHG MVOLLHG 1.0 - VSGPLHG MVOLC3S -.175 - VSGPLHG MVOLNC4 -.27 - VSGPLHG MVOLLSR -.028 - VSGPLHG MVOLIC4 -.455 - VSGPLHG UBALKWH .495 - VSGPLHG UBALH2O .209 - VSGPLHG UBALSTM .013 - VSGPLHG UBALFUL .0448 - VSGPB95 MVOLB95 1. - VSGPB95 MVOLC3S -.2836 - VSGPB95 MVOLNC4 -.3285 - VSGPB95 MVOLLSR -.0241 - VSGPB95 MVOLIC4 -.2502 - VSGPB95 UBALKWH .495 - VSGPB95 UBALH2O .209 - VSGPB95 UBALSTM .013 - VSGPB95 UBALFUL .0506 - VSGPB90 MVOLB90 1. - VSGPB90 MVOLC3S -.271 - VSGPB90 MVOLNC4 -.3289 - VSGPB90 MVOLLSR -.0255 - VSGPB90 MVOLIC4 -.2656 - VSGPB90 UBALKWH .495 - VSGPB90 UBALH2O .209 - VSGPB90 UBALSTM .013 - VSGPB90 UBALFUL .0506 - VH2RHSR MVOLHSR 1. - VH2RHSR MVOLRFG -1. - VH2RHSR MSCFHYL .0327 - VH2RHSR UBALKWH .793 - VH2RHSR UBALH2O .045 - VH2RHSR UBALFUL .094 - VH2RHSR PROFIT -.0176 - VRFFRF1 MVOLRFG 1.0 - VRFFRF1 MVOLR90 -1.0 - VRFFRF2 MVOLRFG 1.0 - VRFFRF2 MVOLR95 -1.0 - VRFFHH1 MVOLR90 -1.0 - VRFFHH1 MVOLHHG 1.0 - VRFFHH2 MVOLR95 -1.0 - VRFFHH2 MVOLHHG 1.0 - VRFGR90 MVOLR90 1.0 - VRFGR90 MVOLB90 -.0404 - VRFGR90 MVOLF90 -0.8564 - VRFGR90 MSCFHYL -0.8239 - VRFGR90 UBALKWH .792 - VRFGR90 UBALH2O .297 - VRFGR90 UBALSTM 0.0063 - VRFGR90 UBALFUL -0.156 - VRFGR90 VCAPRFG 1.0 - VRFGR90 PROFIT -0.1512 - VRFGR95 MVOLR95 1.0 - VRFGR95 MVOLB95 -0.0588 - VRFGR95 MVOLF95 -0.8145 - VRFGR95 MSCFHYL -.7689 - VRFGR95 UBALKWH 1.03 - VRFGR95 UBALH2O .387 - VRFGR95 UBALSTM 0.008 - VRFGR95 UBALFUL -.2112 - VRFGR95 VCAPRFG 1.3 - VRFGR95 PROFIT -0.304 - VHOLLCO MVOLLCO 1.0 - VHOLLCO MVOLHHG -.6627 - VHOLLCO MVOLLHG -0.2414 - VHOLLCO MVOLHCD -.2930 - VHOLLCO MSCFHYL 2.3 - VHOLLCO UBALFUL -.2054 - VHOLLCO UBALH2O 0.826 - VHOLLCO UBALKWH 14.61 - VHOLLCO VCAPHOL 1.0 - VHOLLCO PROFIT -0.2112 - VHOLSRD MVOLSRD 1.0 - VHOLSRD MVOLHHG -.6627 - VHOLSRD MVOLLHG -0.2414 - VHOLSRD MVOLHCD -.2930 - VHOLSRD MSCFHYL 2.3 - VHOLSRD UBALFUL -.2054 - VHOLSRD UBALH2O 0.826 - VHOLSRD UBALKWH 14.61 - VHOLSRD VCAPHOL 1.0 - VHOLSRD PROFIT -0.2112 - VHOLRCR MVOLRCR 1.0 - VHOLRCR MVOLHHG -.5875 - VHOLRCR MVOLLHG -0.3321 - VHOLRCR MVOLHCD -.3620 - VHOLRCR MSCFHYL 2.3 - VHOLRCR UBALFUL -.2054 - VHOLRCR UBALH2O 0.826 - VHOLRCR UBALKWH 14.61 - VHOLRCR VCAPHOL 1.0 - VHOLRCR PROFIT -0.2112 - VHOLHVO MVOLHVO 1.0 - VHOLHVO MVOLHHG -.5875 - VHOLHVO MVOLLHG -0.3321 - VHOLHVO MVOLHCD -.3620 - VHOLHVO MSCFHYL 2.3 - VHOLHVO UBALFUL -.2054 - VHOLHVO UBALH2O 0.826 - VHOLHVO UBALKWH 14.61 - VHOLHVO VCAPHVO 1.0 - VHOLHVO VCAPHOL 1.0 - VHOLHVO PROFIT -0.2112 - VCCUSRK MVOLSRK 1.0 - VCCUSRK MVOLNC4 -0.0184 - VCCUSRK MVOLC3S -0.0303 - VCCUSRK MVOLIC4 -0.0564 - VCCUSRK MVOLC3U -0.0655 - VCCUSRK MVOLC4U -0.0780 - VCCUSRK MVOLFCG -0.4750 - VCCUSRK MVOLLCO -0.3050 - VCCUSRK UBALSTM -.0654 - VCCUSRK UBALFUL -.2703 - VCCUSRK UBALH2O .632 - VCCUSRK UBALKWH .6807 - VCCUSRK VCAPCCU 1. - VCCUSRK PROFIT -.2112 - VCCUSRD MVOLSRD 1. - VCCUSRD MVOLNC4 -.0184 - VCCUSRD MVOLC3S -.0303 - VCCUSRD MVOLIC4 -.0564 - VCCUSRD MVOLC3U -.0655 - VCCUSRD MVOLC4U -.0780 - VCCUSRD MVOLFCG -.4750 - VCCUSRD MVOLLCO -.3050 - VCCUSRD UBALSTM -.0654 - VCCUSRD UBALFUL -.2703 - VCCUSRD UBALH2O 0.632 - VCCUSRD UBALKWH .6807 - VCCUSRD VCAPCCU 1. - VCCUSRD PROFIT -.2112 - VCCURCR MVOLRCR 1.0 - VCCURCR MVOLNC4 -.0185 - VCCURCR MVOLC3S -.0328 - VCCURCR MVOLIC4 -.0568 - VCCURCR MVOLC3U -.0658 - VCCURCR MVOLC4U -.0806 - VCCURCR MVOLFCG -.4934 - VCCURCR MVOLLCO -.2922 - VCCURCR MVOLSLR -.0096 - VCCURCR UBALSTM -.0654 - VCCURCR UBALFUL -.2703 - VCCURCR UBALH2O 0.632 - VCCURCR UBALKWH .6807 - VCCURCR VCAPCCU 1. - VCCURCR PROFIT -.2112 - VCCUHVO MVOLHVO 1.0 - VCCUHVO MVOLNC4 -.0185 - VCCUHVO MVOLC3S -.0328 - VCCUHVO MVOLIC4 -.0568 - VCCUHVO MVOLC3U -.0658 - VCCUHVO MVOLC4U -.0806 - VCCUHVO MVOLFCG -.4934 - VCCUHVO MVOLLCO -.2922 - VCCUHVO MVOLSLR -.0096 - VCCUHVO UBALSTM -.0654 - VCCUHVO UBALFUL -.2703 - VCCUHVO UBALH2O 0.632 - VCCUHVO UBALKWH .6807 - VCCUHVO VCAPHVO 1. - VCCUHVO VCAPCCU 1. - VCCUHVO PROFIT -.2112 - VALKLA3 MVOLIC4 .7600 - VALKLA3 MVOLC3U .5714 - VALKLA3 MVOLLA3 -1.0 - VALKLA3 UBALSTM .1869 - VALKLA3 UBALFUL .2796 - VALKLA3 UBALH2O 2.241 - VALKLA3 UBALKWH 2.766 - VALKLA3 VCAPALK 1.0 - VALKLA3 PROFIT -.512 - VALKLA4 MVOLIC4 .6571 - VALKLA4 MVOLC4U .5714 - VALKLA4 MVOLC3S -.0571 - VALKLA4 MVOLNC4 -.0114 - VALKLA4 MVOLLA4 -1.0 - VALKLA4 UBALSTM .1724 - VALKLA4 UBALFUL .2579 - VALKLA4 UBALH2O 2.067 - VALKLA4 UBALKWH 2.552 - VALKLA4 VCAPALK 1.0 - VALKLA4 PROFIT -.472 - VALKIC4 MVOLIC4 1.0 - VALKIC4 MVOLNC4 -1.0 - VALKC3U MVOLC3U 1.0 - VALKC3U MVOLC3S -1.0 - VALKC4U MVOLC4U 1.0 - VALKC4U MVOLNC4 -1.0 - UTILC3S MVOLC3S 1. - UTILC3S UBALFUL -3.814 - UTILNC4 MVOLNC4 1. - UTILNC4 UBALFUL -4.316 - UTILIC4 MVOLIC4 1. - UTILIC4 UBALFUL -4.153 - UTILC3U MVOLC3U 1. - UTILC3U UBALFUL -3.808 - UTILC4U MVOLC4U 1. - UTILC4U UBALFUL -4.44 - UTILHYL MSCFHYL 1. - UTILHYL UBALFUL -.305 - UTILSTM UBALSTM -1. - UTILSTM UBALFUL 1.42 - UTILSTM PROFIT -.16 - PURCPC4 MVOLIC4 -.5 - PURCPC4 MVOLNC4 -.5 - PURCPC4 PROFIT -12. - PURCH2O UBALH2O -1. - PURCH2O PROFIT -.0528 - PURCKWH UBALKWH -1. - PURCKWH PROFIT -.04 - PURCFUL UBALFUL -1. - PURCFUL PROFIT -1.6 - PURCFLR UBALFUL 1. - BLPGC3S MVOLC3S 1.0 - BLPGC3S EVOLLPG -1.0 - BLPGNC4 MVOLNC4 1.0 - BLPGNC4 EVOLLPG -1.0 - SELLLPG EVOLLPG 1.0 - SELLLPG PROFIT 11.0 - BUP4LSR MVOLLSR 1.0 - BUP4LSR EVOLJP4 -1.0 - BUP4LSR XRVXJP4 14.0 - BUP4LSR XRVNJP4 -14.0 - BUP4HSR MVOLHSR 1.0 - BUP4HSR EVOLJP4 -1.0 - BUP4HSR XRVXJP4 0.8 - BUP4HSR XRVNJP4 -0.8 - SELLJP4 EVOLJP4 1.0 - SELLJP4 XRVXJP4 -3.0 - SELLJP4 XRVNJP4 2.0 - SELLJP4 PROFIT 16.8 - BDSLSRK MVOLSRK 1.0 - BDSLSRK EVOLDSL -1.0 - BDSLSRD MVOLSRD 1.0 - BDSLSRD EVOLDSL -1.0 - SELLDSL EVOLDSL 1.0 - SELLDSL PROFIT 14.4 - BPRELSR MVOLLSR 1. - BPRELSR XLPRPRE -7.95 - BPRELSR XHPRPRE -8.70 - BPRELSR XTELPRE -3.00 - BPRELSR XRVPPRE 14.00 - BPRELSR X200PRE 1. - BPRELSR X230PRE -1. - BPRELSR EVOLPRE -1. - BPREHCD MVOLHCD 1.0 - BPREHCD XLPRPRE -8.84 - BPREHCD XHPRPRE -9.45 - BPREHCD XTELPRE -3.00 - BPREHCD XRVPPRE 12.00 - BPREHCD X200PRE 1. - BPREHCD X230PRE -1. - BPREHCD EVOLPRE -1. - BPREF95 MVOLF95 1.0 - BPREF95 XLPRPRE -9.43 - BPREF95 XHPRPRE -9.57 - BPREF95 XTELPRE -3. - BPREF95 XRVPPRE 3.5 - BPREF95 X200PRE .233 - BPREF95 X230PRE -.358 - BPREF95 EVOLPRE -1. - BPREF90 MVOLF90 1.0 - BPREF90 XLPRPRE -9.03 - BPREF90 XHPRPRE -9.32 - BPREF90 XTELPRE -3.0 - BPREF90 XRVPPRE 3.5 - BPREF90 X200PRE .205 - BPREF90 X230PRE -.333 - BPREF90 EVOLPRE -1. - BPREFCG MVOLFCG 1.0 - BPREFCG XLPRPRE -9.23 - BPREFCG XHPRPRE -9.22 - BPREFCG XTELPRE -3. - BPREFCG XRVPPRE 6. - BPREFCG X200PRE .381 - BPREFCG X230PRE -.509 - BPREFCG EVOLPRE -1. - BPRELA3 MVOLLA3 1.0 - BPRELA3 XLPRPRE -9.4 - BPRELA3 XHPRPRE -9.85 - BPRELA3 XTELPRE -3.0 - BPRELA3 XRVPPRE 2.5 - BPRELA3 X200PRE 0.39 - BPRELA3 X230PRE -0.77 - BPRELA3 EVOLPRE -1.0 - BPRELA4 MVOLLA4 1.0 - BPRELA4 XLPRPRE -9.74 - BPRELA4 XHPRPRE -10.1 - BPRELA4 XTELPRE -3.0 - BPRELA4 XRVPPRE 3.3 - BPRELA4 X200PRE 0.233 - BPRELA4 X230PRE -0.58 - BPRELA4 EVOLPRE -1.0 - BPRENC4 MVOLNC4 1.0 - BPRENC4 XLPRPRE -9.74 - BPRENC4 XHPRPRE -9.9 - BPRENC4 XTELPRE -3.0 - BPRENC4 XRVPPRE 66.0 - BPRENC4 X200PRE 1.0 - BPRENC4 X230PRE -1.0 - BPRENC4 EVOLPRE -1.0 - BPRETEL XLPRPRE -0.493 - BPRETEL XHPRPRE -0.165 - BPRETEL XTELPRE 1.0 - BPRETEL PROFIT -0.3696 - SELLPRE XLPRPRE 10.03 - SELLPRE XHPRPRE 10.03 - SELLPRE XRVPPRE -9.5 - SELLPRE X200PRE -0.5 - SELLPRE X230PRE 0.5 - SELLPRE XPSCPRE 0.64 - SELLPRE XRSCREG 0.35 - SELLPRE EVOLPRE 1.0 - SELLPRE PROFIT 21.44 - BINTLSR MVOLLSR 1.0 - BINTLSR XLPRINT -7.98 - BINTLSR XHPRINT -8.58 - BINTLSR XTELINT -3.0 - BINTLSR XRVPINT 14.0 - BINTLSR X200INT 1.0 - BINTLSR X230INT -1.0 - BINTLSR EVOLINT -1.0 - BINTHCD MVOLHCD 1. - BINTHCD XLPRINT -8.87 - BINTHCD XHPRINT -9.33 - BINTHCD XTELINT -3.0 - BINTHCD XRVPINT 12.0 - BINTHCD X200INT 1.0 - BINTHCD X230INT -1. - BINTHCD EVOLINT -1.0 - BINTF95 MVOLF95 1. - BINTF95 XLPRINT -9.46 - BINTF95 XHPRINT -9.45 - BINTF95 XTELINT -3.0 - BINTF95 XRVPINT 3.5 - BINTF95 X200INT .233 - BINTF95 X230INT -.358 - BINTF95 EVOLINT -1.0 - BINTF90 MVOLF90 1. - BINTF90 XLPRINT -9.06 - BINTF90 XHPRINT -9.20 - BINTF90 XTELINT -3.0 - BINTF90 XRVPINT 3.5 - BINTF90 X200INT .205 - BINTF90 X230INT -.333 - BINTF90 EVOLINT -1.0 - BINTFCG MVOLFCG 1. - BINTFCG XLPRINT -9.26 - BINTFCG XHPRINT -9.13 - BINTFCG XTELINT -3.0 - BINTFCG XRVPINT 6. - BINTFCG X200INT .318 - BINTFCG X230INT -.509 - BINTFCG EVOLINT -1.0 - BINTNC4 MVOLNC4 1. - BINTNC4 XLPRINT -9.77 - BINTNC4 XHPRINT -9.78 - BINTNC4 XTELINT -3.0 - BINTNC4 XRVPINT 66. - BINTNC4 X200INT 1.0 - BINTNC4 X230INT -1. - BINTNC4 EVOLINT -1.0 - BINTTEL XLPRINT -.435 - BINTTEL XHPRINT -.208 - BINTTEL XTELINT 1. - BINTTEL PROFIT -.3696 - SELLINT XLPRINT 9.65 - SELLINT XHPRINT 9.65 - SELLINT XRVPINT -9.5 - SELLINT X200INT -0.5 - SELLINT X230INT 0.5 - SELLINT XPSCPRE -.36 - SELLINT XRSCREG 0.35 - SELLINT EVOLINT 1.0 - SELLINT PROFIT 20.32 - BREGLSR MVOLLSR 1.0 - BREGLSR XLPRREG -7.99 - BREGLSR XHPRREG -8.59 - BREGLSR XTELREG -3.0 - BREGLSR XRVPREG 14.0 - BREGLSR X200REG 1.0 - BREGLSR X230REG -1.0 - BREGLSR EVOLREG -1.0 - BREGHCD MVOLHCD 1.0 - BREGHCD XLPRREG -8.88 - BREGHCD XHPRREG -9.34 - BREGHCD XTELREG -3.0 - BREGHCD XRVPREG 12.0 - BREGHCD X200REG 1.0 - BREGHCD X230REG -1.0 - BREGHCD EVOLREG -1.0 - BREGF95 MVOLF95 1.0 - BREGF95 XLPRREG -9.47 - BREGF95 XHPRREG -9.46 - BREGF95 XTELREG -3.0 - BREGF95 XRVPREG 3.5 - BREGF95 X200REG .233 - BREGF95 X230REG -0.358 - BREGF95 EVOLREG -1.0 - BREGF90 MVOLF90 1.0 - BREGF90 XLPRREG -9.07 - BREGF90 XHPRREG -9.21 - BREGF90 XTELREG -3.0 - BREGF90 XRVPREG 3.5 - BREGF90 X200REG .205 - BREGF90 X230REG -0.333 - BREGF90 EVOLREG -1.0 - BREGFCG MVOLFCG 1.0 - BREGFCG XLPRREG -9.27 - BREGFCG XHPRREG -9.14 - BREGFCG XTELREG -3.0 - BREGFCG XRVPREG 6.0 - BREGFCG X200REG 0.318 - BREGFCG X230REG -0.509 - BREGFCG EVOLREG -1.0 - BREGNC4 MVOLNC4 1.0 - BREGNC4 XLPRREG -9.78 - BREGNC4 XHPRREG -9.79 - BREGNC4 XTELREG -3.0 - BREGNC4 XRVPREG 66.0 - BREGNC4 X200REG 1.0 - BREGNC4 X230REG -1.0 - BREGNC4 EVOLREG -1.0 - BREGTEL XLPRREG -0.426 - BREGTEL XHPRREG -.204 - BREGTEL XTELREG 1.0 - BREGTEL PROFIT -0.3696 - SELLREG XLPRREG 9.05 - SELLREG XHPRREG 9.05 - SELLREG XRVPREG -9.5 - SELLREG X200REG -0.5 - SELLREG X230REG 0.5 - SELLREG XPSCPRE -0.36 - SELLREG XRSCREG -0.65 - SELLREG EVOLREG 1.0 - SELLREG PROFIT 18.04 - BRSDVBB MVOLVBB 1.0 - BRSDVBB EVOLRSD -1.0 - BRSDVBB XVISRSD 10.1 - BRSDVBC MVOLVBC 1.0 - BRSDVBC EVOLRSD -1.0 - BRSDVBC XVISRSD 12.63 - BRSDRCR MVOLRCR 1.0 - BRSDRCR EVOLRSD -1.0 - BRSDRCR XVISRSD 6.9 - BRSDHVO MVOLHVO 1.0 - BRSDHVO EVOLRSD -1.0 - BRSDHVO XVISRSD 8.05 - BRSDHVO VCAPHVO 1.0 - BRSDSLR MVOLSLR 1.0 - BRSDSLR EVOLRSD -1.0 - BRSDSLR XVISRSD 8.05 - BRSDLCO MVOLLCO 1.0 - BRSDLCO EVOLRSD -1.0 - BRSDLCO XVISRSD 4.4 - SELLRSD EVOLRSD 1.0 - SELLRSD XVISRSD -10.1 - SELLRSD PROFIT 8.00 -RHS - LIMITMAX MVOLBOL 26.316 - LIMITMAX MVOLCOL 21.052 - LIMITMAX VCAPSGP 23.25 - LIMITMAX VCAPHVO 5.25 - LIMITMAX VCAPRFG 13.455 - LIMITMAX VCAPHOL 3.87 - LIMITMAX VCAPCCU 7.26 - LIMITMAX VCAPALK 10. -ENDATA diff --git a/resources/3rdparty/glpk-4.53/examples/mvcp.mod b/resources/3rdparty/glpk-4.53/examples/mvcp.mod deleted file mode 100644 index e016bda28..000000000 --- a/resources/3rdparty/glpk-4.53/examples/mvcp.mod +++ /dev/null @@ -1,43 +0,0 @@ -/* MVCP, Minimum Vertex Cover Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* The Minimum Vertex Cover Problem in a network G = (V, E), where V - is a set of nodes, E is a set of arcs, is to find a subset V' within - V such that each edge (i,j) in E has at least one its endpoint in V' - and which minimizes the sum of node weights w(i) over V'. - - Reference: - Garey, M.R., and Johnson, D.S. (1979), Computers and Intractability: - A guide to the theory of NP-completeness [Graph Theory, Covering and - Partitioning, Minimum Vertex Cover, GT1]. */ - -set E, dimen 2; -/* set of edges */ - -set V := (setof{(i,j) in E} i) union (setof{(i,j) in E} j); -/* set of nodes */ - -param w{i in V}, >= 0, default 1; -/* w[i] is weight of vertex i */ - -var x{i in V}, binary; -/* x[i] = 1 means that node i is included into V' */ - -s.t. cov{(i,j) in E}: x[i] + x[j] >= 1; -/* each edge (i,j) must have node i or j (or both) in V' */ - -minimize z: sum{i in V} w[i] * x[i]; -/* we need to minimize the sum of node weights over V' */ - -data; - -/* These data correspond to an example from [Papadimitriou]. */ - -/* Optimal solution is 6 (greedy heuristic gives 13) */ - -set E := a1 b1, b1 c1, a1 b2, b2 c2, a2 b3, b3 c3, a2 b4, b4 c4, a3 b5, - b5 c5, a3 b6, b6 c6, a4 b1, a4 b2, a4 b3, a5 b4, a5 b5, a5 b6, - a6 b1, a6 b2, a6 b3, a6 b4, a7 b2, a7 b3, a7 b4, a7 b5, a7 b6; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/netgen.c b/resources/3rdparty/glpk-4.53/examples/netgen.c deleted file mode 100644 index eebb2c867..000000000 --- a/resources/3rdparty/glpk-4.53/examples/netgen.c +++ /dev/null @@ -1,141 +0,0 @@ -/* netgen.c */ - -/* This main program generates 50 original NETGEN instances of the - minimum cost flow problem and writes them in DIMACS format to the - current directory. */ - -#include -#include -#include -#include - -static int parm[50][15] = -{ {13502460, 101, - 5000, 2500, 2500, 25000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, - },{4281922, 102, - 5000, 2500, 2500, 25000, 1, 100, 2500000, 0, 0, 0, 100, 1, 1000, - },{44820113, 103, - 5000, 2500, 2500, 25000, 1, 100, 6250000, 0, 0, 0, 100, 1, 1000, - },{13450451, 104, - 5000, 2500, 2500, 25000, -100, -1, 250000, 0, 0, 0, 100, 1, 1000, - },{14719436, 105, - 5000, 2500, 2500, 25000, 101, 200, 250000, 0, 0, 0, 100, 1, 1000, - },{17365786, 106, - 5000, 2500, 2500, 12500, 1, 100, 125000, 0, 0, 0, 100, 1, 1000, - },{19540113, 107, - 5000, 2500, 2500, 37500, 1, 100, 375000, 0, 0, 0, 100, 1, 1000, - },{19560313, 108, - 5000, 2500, 2500, 50000, 1, 100, 500000, 0, 0, 0, 100, 1, 1000, - },{2403509, 109, - 5000, 2500, 2500, 75000, 1, 100, 750000, 0, 0, 0, 100, 1, 1000, - },{92480414, 110, - 5000, 2500, 2500, 12500, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, - },{4230140, 111, - 5000, 2500, 2500, 37500, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, - },{10032490, 112, - 5000, 2500, 2500, 50000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, - },{17307474, 113, - 5000, 2500, 2500, 75000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, - },{4925114, 114, - 5000, 500, 4500, 25000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, - },{19842704, 115, - 5000, 1500, 3500, 25000, 1, 100, 250000, 0, 0, 0, 100, 1, 1000, - },{88392060, 116, - 5000, 2500, 2500, 25000, 1, 100, 250000, 0, 0, 0, 0, 1, 1000, - },{12904407, 117, - 5000, 2500, 2500, 12500, 1, 100, 125000, 0, 0, 0, 0, 1, 1000, - },{11811811, 118, - 5000, 2500, 2500, 37500, 1, 100, 375000, 0, 0, 0, 0, 1, 1000, - },{90023593, 119, - 5000, 2500, 2500, 50000, 1, 100, 500000, 0, 0, 0, 0, 1, 1000, - },{93028922, 120, - 5000, 2500, 2500, 75000, 1, 100, 750000, 0, 0, 0, 0, 1, 1000, - },{72707401, 121, - 5000, 50, 50, 25000, 1, 100, 250000, 50, 50, 0, 100, 1, 1000, - },{93040771, 122, - 5000, 250, 250, 25000, 1, 100, 250000, 250, 250, 0, 100, 1, 1000, - },{70220611, 123, - 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, - },{52774811, 124, - 5000, 1000, 1000, 25000, 1, 100, 250000, 1000, 1000, 0, 100, 1, - 1000, - },{22492311, 125, - 5000, 1500, 1500, 25000, 1, 100, 250000, 1500, 1500, 0, 100, 1, - 1000, - },{35269337, 126, - 5000, 500, 500, 12500, 1, 100, 125000, 500, 500, 0, 100, 1, 1000, - },{30140502, 127, - 5000, 500, 500, 37500, 1, 100, 375000, 500, 500, 0, 100, 1, 1000, - },{49205455, 128, - 5000, 500, 500, 50000, 1, 100, 500000, 500, 500, 0, 100, 1, 1000, - },{42958341, 129, - 5000, 500, 500, 75000, 1, 100, 750000, 500, 500, 0, 100, 1, 1000, - },{25440925, 130, - 5000, 500, 500, 12500, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, - },{75294924, 131, - 5000, 500, 500, 37500, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, - },{4463965, 132, - 5000, 500, 500, 50000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, - },{13390427, 133, - 5000, 500, 500, 75000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, - },{95250971, 134, - 1000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, - },{54830522, 135, - 2500, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, - },{520593, 136, - 7500, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, - },{52900925, 137, - 10000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 1000, - },{22603395, 138, - 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 50, - },{55253099, 139, - 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 250, - },{75357001, 140, - 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 500, - },{10072459, 141, - 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 2500, - },{55728492, 142, - 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 100, 1, 5000, - },{593043, 143, - 5000, 500, 500, 25000, 1, 100, 250000, 500, 500, 0, 0, 1, 1000, - },{94236572, 144, - 5000, 500, 500, 25000, 1, 10, 250000, 500, 500, 0, 100, 1, 1000, - },{94882955, 145, - 5000, 500, 500, 25000, 1, 1000, 250000, 500, 500, 0, 100, 1, 1000, - },{48489922, 146, - 5000, 500, 500, 25000, 1, 10000, 250000, 500, 500, 0, 100, 1, - 1000, - },{75578374, 147, - 5000, 500, 500, 25000, -100, -1, 250000, 500, 500, 0, 100, 1, - 1000, - },{44821152, 148, - 5000, 500, 500, 25000, -50, 49, 250000, 500, 500, 0, 100, 1, 1000, - },{45224103, 149, - 5000, 500, 500, 25000, 101, 200, 250000, 500, 500, 0, 100, 1, - 1000, - },{63491741, 150, - 5000, 500, 500, 25000, 1001, 1100, 250000, 500, 500, 0, 100, 1, - 1000, - } -}; - -typedef struct { double rhs; } v_data; -typedef struct { double cap, cost; } a_data; - -int main(void) -{ glp_graph *G; - int k; - char fname[100+1]; - G = glp_create_graph(sizeof(v_data), sizeof(a_data)); - for (k = 1; k <= 50; k++) - { sprintf(fname, "netgn%03d.min", parm[k-1][1]); - glp_netgen(G, offsetof(v_data, rhs), offsetof(a_data, cap), - offsetof(a_data, cost), &parm[k-1][-1]); - glp_write_mincost(G, offsetof(v_data, rhs), -1, - offsetof(a_data, cap), offsetof(a_data, cost), fname); - } - glp_delete_graph(G); - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/examples/numbrix.mod b/resources/3rdparty/glpk-4.53/examples/numbrix.mod deleted file mode 100644 index b36fbfd04..000000000 --- a/resources/3rdparty/glpk-4.53/examples/numbrix.mod +++ /dev/null @@ -1,84 +0,0 @@ -/* Numbrix, Number Placement Puzzle */ - -/* Written in GNU MathProg by Robert Wood */ - -/* Numbrix is a logic-based number-placement puzzle.[1] - * The objective is to fill the grid so that each cell contains - * digits in sequential order taking a horizontal or vertical - * path; diagonal paths are not allowed. The puzzle setter - * provides a grid often with the outer most cells completed. - * - * Completed Numbrix puzzles are usually a square of numbers - * in order from 1 to 64 (8x8 grid) or from 1 to 81 (9x9 grid), - * following a continuous path in sequence. - * - * The modern puzzle was invented by Marilyn vos Savant in 2008 - * and published by Parade Magazine under the name "Numbrix", - * near her weekly Ask Marilyn article. - * - * http://en.wikipedia.org/wiki/Numbrix */ - -set I := {1..9}; -set J := {1..9}; -set VALS := {1..81}; - -param givens{I, J}, integer, >= 0, <= 81, default 0; -/* the "givens" */ - -param neighbors{i in I,j in J, i2 in I, j2 in J} , binary := -(if abs(i - i2) + abs(j -j2) == 1 then - 1 - else - 0 -); -/* defines which spots are the boards are neighbors */ - -var x{i in I, j in J, k in VALS}, binary; -/* x[i,j,k] = 1 means cell [i,j] is assigned number k */ - -s.t. fa{i in I, j in J, k in VALS: givens[i,j] != 0}: - x[i,j,k] = (if givens[i,j] = k then 1 else 0); -/* assign pre-defined numbers using the "givens" */ - -s.t. fb{i in I, j in J}: sum{k in VALS} x[i,j,k] = 1; -/* each cell must be assigned exactly one number */ - -s.t. singleNum {k in VALS}: sum{i in I, j in J} x[i,j,k] = 1; -/* a value can only occur once */ - -s.t. neighborContraint {i in I, j in J, k in 1..80}: - x[i,j,k] <= sum{i2 in I, j2 in J} x[i2,j2,k+1] * neighbors[i,j,i2,j2]; -/* each cell must have a neighbor with the next higher value */ - - -/* there is no need for an objective function here */ - - -solve; - -for {i in I} -{ for {0..0: i = 1 or i = 4 or i = 7} - printf " +----------+----------+----------+\n"; - for {j in J} - { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); - printf " %2d", sum{k in VALS} x[i,j,k] * k; - for {0..0: j = 9} printf(" |\n"); - } - for {0..0: i = 9} - printf " +----------+----------+----------+\n"; -} - -data; - -param givens : 1 2 3 4 5 6 7 8 9 := - 1 . . . . . . . . . - 2 . 11 12 15 18 21 62 61 . - 3 . 6 . . . . . 60 . - 4 . 33 . . . . . 57 . - 5 . 32 . . . . . 56 . - 6 . 37 . . . . . 73 . - 7 . 38 . . . . . 72 . - 8 . 43 44 47 48 51 76 77 . - 9 . . . . . . . . . ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/oldapi/README b/resources/3rdparty/glpk-4.53/examples/oldapi/README deleted file mode 100644 index e52ee2c09..000000000 --- a/resources/3rdparty/glpk-4.53/examples/oldapi/README +++ /dev/null @@ -1,11 +0,0 @@ -The program module in this subdirectory contains an implementation of -the old GLPK API as it was defined in GLPK 4.48. - -To compile an existing project using the old GLPK API you need to add -to the project two files lpx.h and lpx.c. - -Please note that you may mix calls to old and new GLPK API routines in -the same project (except calls to glp_create_prob and glp_delete_prob). - -The file lpxsamp.c is an example that illustrates using the old GLPK -API routines. diff --git a/resources/3rdparty/glpk-4.53/examples/oldapi/lpx.c b/resources/3rdparty/glpk-4.53/examples/oldapi/lpx.c deleted file mode 100644 index c508306b0..000000000 --- a/resources/3rdparty/glpk-4.53/examples/oldapi/lpx.c +++ /dev/null @@ -1,1505 +0,0 @@ -/* lpx.c (old GLPK API) */ - -/* Written by Andrew Makhorin , August 2013. */ - -/* This file contains routines that implement the old GLPK API as it -* was defined in GLPK 4.48. -* -* To compile an existing project using these routines you need to add -* to the project this file and the header lpx.h. -* -* Please note that you may mix calls to old and new GLPK API routines -* (except calls to glp_create_prob and glp_delete_prob). */ - -#include -#include -#include "lpx.h" - -#define xassert glp_assert -#define xerror glp_error - -struct CPS -{ /* control parameters */ - LPX *lp; - /* pointer to corresponding problem object */ - int msg_lev; - /* level of messages output by the solver: - 0 - no output - 1 - error messages only - 2 - normal output - 3 - full output (includes informational messages) */ - int scale; - /* scaling option: - 0 - no scaling - 1 - equilibration scaling - 2 - geometric mean scaling - 3 - geometric mean scaling, then equilibration scaling */ - int dual; - /* dual simplex option: - 0 - use primal simplex - 1 - use dual simplex */ - int price; - /* pricing option (for both primal and dual simplex): - 0 - textbook pricing - 1 - steepest edge pricing */ - double relax; - /* relaxation parameter used in the ratio test; if it is zero, - the textbook ratio test is used; if it is non-zero (should be - positive), Harris' two-pass ratio test is used; in the latter - case on the first pass basic variables (in the case of primal - simplex) or reduced costs of non-basic variables (in the case - of dual simplex) are allowed to slightly violate their bounds, - but not more than (relax * tol_bnd) or (relax * tol_dj) (thus, - relax is a percentage of tol_bnd or tol_dj) */ - double tol_bnd; - /* relative tolerance used to check if the current basic solution - is primal feasible */ - double tol_dj; - /* absolute tolerance used to check if the current basic solution - is dual feasible */ - double tol_piv; - /* relative tolerance used to choose eligible pivotal elements of - the simplex table in the ratio test */ - int round; - /* solution rounding option: - 0 - report all computed values and reduced costs "as is" - 1 - if possible (allowed by the tolerances), replace computed - values and reduced costs which are close to zero by exact - zeros */ - double obj_ll; - /* lower limit of the objective function; if on the phase II the - objective function reaches this limit and continues decreasing, - the solver stops the search */ - double obj_ul; - /* upper limit of the objective function; if on the phase II the - objective function reaches this limit and continues increasing, - the solver stops the search */ - int it_lim; - /* simplex iterations limit; if this value is positive, it is - decreased by one each time when one simplex iteration has been - performed, and reaching zero value signals the solver to stop - the search; negative value means no iterations limit */ - double tm_lim; - /* searching time limit, in seconds; if this value is positive, - it is decreased each time when one simplex iteration has been - performed by the amount of time spent for the iteration, and - reaching zero value signals the solver to stop the search; - negative value means no time limit */ - int out_frq; - /* output frequency, in iterations; this parameter specifies how - frequently the solver sends information about the solution to - the standard output */ - double out_dly; - /* output delay, in seconds; this parameter specifies how long - the solver should delay sending information about the solution - to the standard output; zero value means no delay */ - int branch; /* MIP */ - /* branching heuristic: - 0 - branch on first variable - 1 - branch on last variable - 2 - branch using heuristic by Driebeck and Tomlin - 3 - branch on most fractional variable */ - int btrack; /* MIP */ - /* backtracking heuristic: - 0 - select most recent node (depth first search) - 1 - select earliest node (breadth first search) - 2 - select node using the best projection heuristic - 3 - select node with best local bound */ - double tol_int; /* MIP */ - /* absolute tolerance used to check if the current basic solution - is integer feasible */ - double tol_obj; /* MIP */ - /* relative tolerance used to check if the value of the objective - function is not better than in the best known integer feasible - solution */ - int mps_info; /* lpx_write_mps */ - /* if this flag is set, the routine lpx_write_mps outputs several - comment cards that contains some information about the problem; - otherwise the routine outputs no comment cards */ - int mps_obj; /* lpx_write_mps */ - /* this parameter tells the routine lpx_write_mps how to output - the objective function row: - 0 - never output objective function row - 1 - always output objective function row - 2 - output objective function row if and only if the problem - has no free rows */ - int mps_orig; /* lpx_write_mps */ - /* if this flag is set, the routine lpx_write_mps uses original - row and column symbolic names; otherwise the routine generates - plain names using ordinal numbers of rows and columns */ - int mps_wide; /* lpx_write_mps */ - /* if this flag is set, the routine lpx_write_mps uses all data - fields; otherwise the routine keeps fields 5 and 6 empty */ - int mps_free; /* lpx_write_mps */ - /* if this flag is set, the routine lpx_write_mps omits column - and vector names everytime if possible (free style); otherwise - the routine never omits these names (pedantic style) */ - int mps_skip; /* lpx_write_mps */ - /* if this flag is set, the routine lpx_write_mps skips empty - columns (i.e. which has no constraint coefficients); otherwise - the routine outputs all columns */ - int lpt_orig; /* lpx_write_lpt */ - /* if this flag is set, the routine lpx_write_lpt uses original - row and column symbolic names; otherwise the routine generates - plain names using ordinal numbers of rows and columns */ - int presol; /* lpx_simplex */ - /* LP presolver option: - 0 - do not use LP presolver - 1 - use LP presolver */ - int binarize; /* lpx_intopt */ - /* if this flag is set, the routine lpx_intopt replaces integer - columns by binary ones */ - int use_cuts; /* lpx_intopt */ - /* if this flag is set, the routine lpx_intopt tries generating - cutting planes: - LPX_C_COVER - mixed cover cuts - LPX_C_CLIQUE - clique cuts - LPX_C_GOMORY - Gomory's mixed integer cuts - LPX_C_ALL - all cuts */ - double mip_gap; /* MIP */ - /* relative MIP gap tolerance */ - struct CPS *link; - /* pointer to CPS for another problem object */ -}; - -static struct CPS *cps_ptr = NULL; -/* initial pointer to CPS linked list */ - -static struct CPS *find_cps(LPX *lp) -{ /* find CPS for specified problem object */ - struct CPS *cps; - for (cps = cps_ptr; cps != NULL; cps = cps->link) - if (cps->lp == lp) break; - /* if cps is NULL (not found), the problem object was created - with glp_create_prob rather than with lpx_create_prob */ - xassert(cps != NULL); - return cps; -} - -static void reset_cps(struct CPS *cps) -{ /* reset control parameters to default values */ - cps->msg_lev = 3; - cps->scale = 1; - cps->dual = 0; - cps->price = 1; - cps->relax = 0.07; - cps->tol_bnd = 1e-7; - cps->tol_dj = 1e-7; - cps->tol_piv = 1e-9; - cps->round = 0; - cps->obj_ll = -DBL_MAX; - cps->obj_ul = +DBL_MAX; - cps->it_lim = -1; - cps->tm_lim = -1.0; - cps->out_frq = 200; - cps->out_dly = 0.0; - cps->branch = 2; - cps->btrack = 3; - cps->tol_int = 1e-5; - cps->tol_obj = 1e-7; - cps->mps_info = 1; - cps->mps_obj = 2; - cps->mps_orig = 0; - cps->mps_wide = 1; - cps->mps_free = 0; - cps->mps_skip = 0; - cps->lpt_orig = 0; - cps->presol = 0; - cps->binarize = 0; - cps->use_cuts = 0; - cps->mip_gap = 0.0; - return; -} - -LPX *lpx_create_prob(void) -{ /* create problem object */ - LPX *lp; - struct CPS *cps; - lp = glp_create_prob(); - cps = glp_alloc(1, sizeof(struct CPS)); - cps->lp = lp; - reset_cps(cps); - cps->link = cps_ptr; - cps_ptr = cps; - return lp; -} - -void lpx_set_prob_name(LPX *lp, const char *name) -{ /* assign (change) problem name */ - glp_set_prob_name(lp, name); - return; -} - -void lpx_set_obj_name(LPX *lp, const char *name) -{ /* assign (change) objective function name */ - glp_set_obj_name(lp, name); - return; -} - -void lpx_set_obj_dir(LPX *lp, int dir) -{ /* set (change) optimization direction flag */ - glp_set_obj_dir(lp, dir - LPX_MIN + GLP_MIN); - return; -} - -int lpx_add_rows(LPX *lp, int nrs) -{ /* add new rows to problem object */ - return glp_add_rows(lp, nrs); -} - -int lpx_add_cols(LPX *lp, int ncs) -{ /* add new columns to problem object */ - return glp_add_cols(lp, ncs); -} - -void lpx_set_row_name(LPX *lp, int i, const char *name) -{ /* assign (change) row name */ - glp_set_row_name(lp, i, name); - return; -} - -void lpx_set_col_name(LPX *lp, int j, const char *name) -{ /* assign (change) column name */ - glp_set_col_name(lp, j, name); - return; -} - -void lpx_set_row_bnds(LPX *lp, int i, int type, double lb, double ub) -{ /* set (change) row bounds */ - glp_set_row_bnds(lp, i, type - LPX_FR + GLP_FR, lb, ub); - return; -} - -void lpx_set_col_bnds(LPX *lp, int j, int type, double lb, double ub) -{ /* set (change) column bounds */ - glp_set_col_bnds(lp, j, type - LPX_FR + GLP_FR, lb, ub); - return; -} - -void lpx_set_obj_coef(glp_prob *lp, int j, double coef) -{ /* set (change) obj. coefficient or constant term */ - glp_set_obj_coef(lp, j, coef); - return; -} - -void lpx_set_mat_row(LPX *lp, int i, int len, const int ind[], - const double val[]) -{ /* set (replace) row of the constraint matrix */ - glp_set_mat_row(lp, i, len, ind, val); - return; -} - -void lpx_set_mat_col(LPX *lp, int j, int len, const int ind[], - const double val[]) -{ /* set (replace) column of the constraint matrix */ - glp_set_mat_col(lp, j, len, ind, val); - return; -} - -void lpx_load_matrix(LPX *lp, int ne, const int ia[], const int ja[], - const double ar[]) -{ /* load (replace) the whole constraint matrix */ - glp_load_matrix(lp, ne, ia, ja, ar); - return; -} - -void lpx_del_rows(LPX *lp, int nrs, const int num[]) -{ /* delete specified rows from problem object */ - glp_del_rows(lp, nrs, num); - return; -} - -void lpx_del_cols(LPX *lp, int ncs, const int num[]) -{ /* delete specified columns from problem object */ - glp_del_cols(lp, ncs, num); - return; -} - -void lpx_delete_prob(LPX *lp) -{ /* delete problem object */ - struct CPS *cps = find_cps(lp); - if (cps_ptr == cps) - cps_ptr = cps->link; - else - { struct CPS *prev; - for (prev = cps_ptr; prev != NULL; prev = prev->link) - if (prev->link == cps) break; - xassert(prev != NULL); - prev->link = cps->link; - } - glp_free(cps); - glp_delete_prob(lp); - return; -} - -const char *lpx_get_prob_name(LPX *lp) -{ /* retrieve problem name */ - return glp_get_prob_name(lp); -} - -const char *lpx_get_obj_name(LPX *lp) -{ /* retrieve objective function name */ - return glp_get_obj_name(lp); -} - -int lpx_get_obj_dir(LPX *lp) -{ /* retrieve optimization direction flag */ - return glp_get_obj_dir(lp) - GLP_MIN + LPX_MIN; -} - -int lpx_get_num_rows(LPX *lp) -{ /* retrieve number of rows */ - return glp_get_num_rows(lp); -} - -int lpx_get_num_cols(LPX *lp) -{ /* retrieve number of columns */ - return glp_get_num_cols(lp); -} - -const char *lpx_get_row_name(LPX *lp, int i) -{ /* retrieve row name */ - return glp_get_row_name(lp, i); -} - -const char *lpx_get_col_name(LPX *lp, int j) -{ /* retrieve column name */ - return glp_get_col_name(lp, j); -} - -int lpx_get_row_type(LPX *lp, int i) -{ /* retrieve row type */ - return glp_get_row_type(lp, i) - GLP_FR + LPX_FR; -} - -double lpx_get_row_lb(glp_prob *lp, int i) -{ /* retrieve row lower bound */ - double lb; - lb = glp_get_row_lb(lp, i); - if (lb == -DBL_MAX) lb = 0.0; - return lb; -} - -double lpx_get_row_ub(glp_prob *lp, int i) -{ /* retrieve row upper bound */ - double ub; - ub = glp_get_row_ub(lp, i); - if (ub == +DBL_MAX) ub = 0.0; - return ub; -} - -void lpx_get_row_bnds(glp_prob *lp, int i, int *typx, double *lb, - double *ub) -{ /* retrieve row bounds */ - if (typx != NULL) *typx = lpx_get_row_type(lp, i); - if (lb != NULL) *lb = lpx_get_row_lb(lp, i); - if (ub != NULL) *ub = lpx_get_row_ub(lp, i); - return; -} - -int lpx_get_col_type(LPX *lp, int j) -{ /* retrieve column type */ - return glp_get_col_type(lp, j) - GLP_FR + LPX_FR; -} - -double lpx_get_col_lb(glp_prob *lp, int j) -{ /* retrieve column lower bound */ - double lb; - lb = glp_get_col_lb(lp, j); - if (lb == -DBL_MAX) lb = 0.0; - return lb; -} - -double lpx_get_col_ub(glp_prob *lp, int j) -{ /* retrieve column upper bound */ - double ub; - ub = glp_get_col_ub(lp, j); - if (ub == +DBL_MAX) ub = 0.0; - return ub; -} - -void lpx_get_col_bnds(glp_prob *lp, int j, int *typx, double *lb, - double *ub) -{ /* retrieve column bounds */ - if (typx != NULL) *typx = lpx_get_col_type(lp, j); - if (lb != NULL) *lb = lpx_get_col_lb(lp, j); - if (ub != NULL) *ub = lpx_get_col_ub(lp, j); - return; -} - -double lpx_get_obj_coef(LPX *lp, int j) -{ /* retrieve obj. coefficient or constant term */ - return glp_get_obj_coef(lp, j); -} - -int lpx_get_num_nz(LPX *lp) -{ /* retrieve number of constraint coefficients */ - return glp_get_num_nz(lp); -} - -int lpx_get_mat_row(LPX *lp, int i, int ind[], double val[]) -{ /* retrieve row of the constraint matrix */ - return glp_get_mat_row(lp, i, ind, val); -} - -int lpx_get_mat_col(LPX *lp, int j, int ind[], double val[]) -{ /* retrieve column of the constraint matrix */ - return glp_get_mat_col(lp, j, ind, val); -} - -void lpx_create_index(LPX *lp) -{ /* create the name index */ - glp_create_index(lp); - return; -} - -int lpx_find_row(LPX *lp, const char *name) -{ /* find row by its name */ - return glp_find_row(lp, name); -} - -int lpx_find_col(LPX *lp, const char *name) -{ /* find column by its name */ - return glp_find_col(lp, name); -} - -void lpx_delete_index(LPX *lp) -{ /* delete the name index */ - glp_delete_index(lp); - return; -} - -void lpx_scale_prob(LPX *lp) -{ /* scale problem data */ - switch (lpx_get_int_parm(lp, LPX_K_SCALE)) - { case 0: - /* no scaling */ - glp_unscale_prob(lp); - break; - case 1: - /* equilibration scaling */ - glp_scale_prob(lp, GLP_SF_EQ); - break; - case 2: - /* geometric mean scaling */ - glp_scale_prob(lp, GLP_SF_GM); - break; - case 3: - /* geometric mean scaling, then equilibration scaling */ - glp_scale_prob(lp, GLP_SF_GM | GLP_SF_EQ); - break; - default: - xassert(lp != lp); - } - return; -} - -void lpx_unscale_prob(LPX *lp) -{ /* unscale problem data */ - glp_unscale_prob(lp); - return; -} - -void lpx_set_row_stat(LPX *lp, int i, int stat) -{ /* set (change) row status */ - glp_set_row_stat(lp, i, stat - LPX_BS + GLP_BS); - return; -} - -void lpx_set_col_stat(LPX *lp, int j, int stat) -{ /* set (change) column status */ - glp_set_col_stat(lp, j, stat - LPX_BS + GLP_BS); - return; -} - -void lpx_std_basis(LPX *lp) -{ /* construct standard initial LP basis */ - glp_std_basis(lp); - return; -} - -void lpx_adv_basis(LPX *lp) -{ /* construct advanced initial LP basis */ - glp_adv_basis(lp, 0); - return; -} - -void lpx_cpx_basis(LPX *lp) -{ /* construct Bixby's initial LP basis */ - glp_cpx_basis(lp); - return; -} - -static void fill_smcp(LPX *lp, glp_smcp *parm) -{ glp_init_smcp(parm); - switch (lpx_get_int_parm(lp, LPX_K_MSGLEV)) - { case 0: parm->msg_lev = GLP_MSG_OFF; break; - case 1: parm->msg_lev = GLP_MSG_ERR; break; - case 2: parm->msg_lev = GLP_MSG_ON; break; - case 3: parm->msg_lev = GLP_MSG_ALL; break; - default: xassert(lp != lp); - } - switch (lpx_get_int_parm(lp, LPX_K_DUAL)) - { case 0: parm->meth = GLP_PRIMAL; break; - case 1: parm->meth = GLP_DUAL; break; - default: xassert(lp != lp); - } - switch (lpx_get_int_parm(lp, LPX_K_PRICE)) - { case 0: parm->pricing = GLP_PT_STD; break; - case 1: parm->pricing = GLP_PT_PSE; break; - default: xassert(lp != lp); - } - if (lpx_get_real_parm(lp, LPX_K_RELAX) == 0.0) - parm->r_test = GLP_RT_STD; - else - parm->r_test = GLP_RT_HAR; - parm->tol_bnd = lpx_get_real_parm(lp, LPX_K_TOLBND); - parm->tol_dj = lpx_get_real_parm(lp, LPX_K_TOLDJ); - parm->tol_piv = lpx_get_real_parm(lp, LPX_K_TOLPIV); - parm->obj_ll = lpx_get_real_parm(lp, LPX_K_OBJLL); - parm->obj_ul = lpx_get_real_parm(lp, LPX_K_OBJUL); - if (lpx_get_int_parm(lp, LPX_K_ITLIM) < 0) - parm->it_lim = INT_MAX; - else - parm->it_lim = lpx_get_int_parm(lp, LPX_K_ITLIM); - if (lpx_get_real_parm(lp, LPX_K_TMLIM) < 0.0) - parm->tm_lim = INT_MAX; - else - parm->tm_lim = - (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_TMLIM)); - parm->out_frq = lpx_get_int_parm(lp, LPX_K_OUTFRQ); - parm->out_dly = - (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_OUTDLY)); - switch (lpx_get_int_parm(lp, LPX_K_PRESOL)) - { case 0: parm->presolve = GLP_OFF; break; - case 1: parm->presolve = GLP_ON; break; - default: xassert(lp != lp); - } - return; -} - -int lpx_simplex(LPX *lp) -{ /* easy-to-use driver to the simplex method */ - glp_smcp parm; - int ret; - fill_smcp(lp, &parm); - ret = glp_simplex(lp, &parm); - switch (ret) - { case 0: ret = LPX_E_OK; break; - case GLP_EBADB: - case GLP_ESING: - case GLP_ECOND: - case GLP_EBOUND: ret = LPX_E_FAULT; break; - case GLP_EFAIL: ret = LPX_E_SING; break; - case GLP_EOBJLL: ret = LPX_E_OBJLL; break; - case GLP_EOBJUL: ret = LPX_E_OBJUL; break; - case GLP_EITLIM: ret = LPX_E_ITLIM; break; - case GLP_ETMLIM: ret = LPX_E_TMLIM; break; - case GLP_ENOPFS: ret = LPX_E_NOPFS; break; - case GLP_ENODFS: ret = LPX_E_NODFS; break; - default: xassert(ret != ret); - } - return ret; -} - -int lpx_exact(LPX *lp) -{ /* easy-to-use driver to the exact simplex method */ - glp_smcp parm; - int ret; - fill_smcp(lp, &parm); - ret = glp_exact(lp, &parm); - switch (ret) - { case 0: ret = LPX_E_OK; break; - case GLP_EBADB: - case GLP_ESING: - case GLP_EBOUND: - case GLP_EFAIL: ret = LPX_E_FAULT; break; - case GLP_EITLIM: ret = LPX_E_ITLIM; break; - case GLP_ETMLIM: ret = LPX_E_TMLIM; break; - default: xassert(ret != ret); - } - return ret; -} - -int lpx_get_status(glp_prob *lp) -{ /* retrieve generic status of basic solution */ - int status; - switch (glp_get_status(lp)) - { case GLP_OPT: status = LPX_OPT; break; - case GLP_FEAS: status = LPX_FEAS; break; - case GLP_INFEAS: status = LPX_INFEAS; break; - case GLP_NOFEAS: status = LPX_NOFEAS; break; - case GLP_UNBND: status = LPX_UNBND; break; - case GLP_UNDEF: status = LPX_UNDEF; break; - default: xassert(lp != lp); - } - return status; -} - -int lpx_get_prim_stat(glp_prob *lp) -{ /* retrieve status of primal basic solution */ - return glp_get_prim_stat(lp) - GLP_UNDEF + LPX_P_UNDEF; -} - -int lpx_get_dual_stat(glp_prob *lp) -{ /* retrieve status of dual basic solution */ - return glp_get_dual_stat(lp) - GLP_UNDEF + LPX_D_UNDEF; -} - -double lpx_get_obj_val(LPX *lp) -{ /* retrieve objective value (basic solution) */ - return glp_get_obj_val(lp); -} - -int lpx_get_row_stat(LPX *lp, int i) -{ /* retrieve row status (basic solution) */ - return glp_get_row_stat(lp, i) - GLP_BS + LPX_BS; -} - -double lpx_get_row_prim(LPX *lp, int i) -{ /* retrieve row primal value (basic solution) */ - return glp_get_row_prim(lp, i); -} - -double lpx_get_row_dual(LPX *lp, int i) -{ /* retrieve row dual value (basic solution) */ - return glp_get_row_dual(lp, i); -} - -void lpx_get_row_info(glp_prob *lp, int i, int *tagx, double *vx, - double *dx) -{ /* obtain row solution information */ - if (tagx != NULL) *tagx = lpx_get_row_stat(lp, i); - if (vx != NULL) *vx = lpx_get_row_prim(lp, i); - if (dx != NULL) *dx = lpx_get_row_dual(lp, i); - return; -} - -int lpx_get_col_stat(LPX *lp, int j) -{ /* retrieve column status (basic solution) */ - return glp_get_col_stat(lp, j) - GLP_BS + LPX_BS; -} - -double lpx_get_col_prim(LPX *lp, int j) -{ /* retrieve column primal value (basic solution) */ - return glp_get_col_prim(lp, j); -} - -double lpx_get_col_dual(glp_prob *lp, int j) -{ /* retrieve column dual value (basic solution) */ - return glp_get_col_dual(lp, j); -} - -void lpx_get_col_info(glp_prob *lp, int j, int *tagx, double *vx, - double *dx) -{ /* obtain column solution information */ - if (tagx != NULL) *tagx = lpx_get_col_stat(lp, j); - if (vx != NULL) *vx = lpx_get_col_prim(lp, j); - if (dx != NULL) *dx = lpx_get_col_dual(lp, j); - return; -} - -int lpx_get_ray_info(LPX *lp) -{ /* determine what causes primal unboundness */ - return glp_get_unbnd_ray(lp); -} - -void lpx_check_kkt(LPX *lp, int scaled, LPXKKT *kkt) -{ /* check Karush-Kuhn-Tucker conditions */ - int m = glp_get_num_rows(lp); - int ae_ind, re_ind; - double ae_max, re_max; - xassert(scaled == scaled); - glp_check_kkt(lp, GLP_SOL, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, - &re_ind); - kkt->pe_ae_max = ae_max; - kkt->pe_ae_row = ae_ind; - kkt->pe_re_max = re_max; - kkt->pe_re_row = re_ind; - if (re_max <= 1e-9) - kkt->pe_quality = 'H'; - else if (re_max <= 1e-6) - kkt->pe_quality = 'M'; - else if (re_max <= 1e-3) - kkt->pe_quality = 'L'; - else - kkt->pe_quality = '?'; - glp_check_kkt(lp, GLP_SOL, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, - &re_ind); - kkt->pb_ae_max = ae_max; - kkt->pb_ae_ind = ae_ind; - kkt->pb_re_max = re_max; - kkt->pb_re_ind = re_ind; - if (re_max <= 1e-9) - kkt->pb_quality = 'H'; - else if (re_max <= 1e-6) - kkt->pb_quality = 'M'; - else if (re_max <= 1e-3) - kkt->pb_quality = 'L'; - else - kkt->pb_quality = '?'; - glp_check_kkt(lp, GLP_SOL, GLP_KKT_DE, &ae_max, &ae_ind, &re_max, - &re_ind); - kkt->de_ae_max = ae_max; - if (ae_ind == 0) - kkt->de_ae_col = 0; - else - kkt->de_ae_col = ae_ind - m; - kkt->de_re_max = re_max; - if (re_ind == 0) - kkt->de_re_col = 0; - else - kkt->de_re_col = ae_ind - m; - if (re_max <= 1e-9) - kkt->de_quality = 'H'; - else if (re_max <= 1e-6) - kkt->de_quality = 'M'; - else if (re_max <= 1e-3) - kkt->de_quality = 'L'; - else - kkt->de_quality = '?'; - glp_check_kkt(lp, GLP_SOL, GLP_KKT_DB, &ae_max, &ae_ind, &re_max, - &re_ind); - kkt->db_ae_max = ae_max; - kkt->db_ae_ind = ae_ind; - kkt->db_re_max = re_max; - kkt->db_re_ind = re_ind; - if (re_max <= 1e-9) - kkt->db_quality = 'H'; - else if (re_max <= 1e-6) - kkt->db_quality = 'M'; - else if (re_max <= 1e-3) - kkt->db_quality = 'L'; - else - kkt->db_quality = '?'; - kkt->cs_ae_max = 0.0, kkt->cs_ae_ind = 0; - kkt->cs_re_max = 0.0, kkt->cs_re_ind = 0; - kkt->cs_quality = 'H'; - return; -} - -int lpx_warm_up(LPX *lp) -{ /* "warm up" LP basis */ - int ret; - ret = glp_warm_up(lp); - if (ret == 0) - ret = LPX_E_OK; - else if (ret == GLP_EBADB) - ret = LPX_E_BADB; - else if (ret == GLP_ESING) - ret = LPX_E_SING; - else if (ret == GLP_ECOND) - ret = LPX_E_SING; - else - xassert(ret != ret); - return ret; -} - -int lpx_eval_tab_row(LPX *lp, int k, int ind[], double val[]) -{ /* compute row of the simplex tableau */ - return glp_eval_tab_row(lp, k, ind, val); -} - -int lpx_eval_tab_col(LPX *lp, int k, int ind[], double val[]) -{ /* compute column of the simplex tableau */ - return glp_eval_tab_col(lp, k, ind, val); -} - -int lpx_transform_row(LPX *lp, int len, int ind[], double val[]) -{ /* transform explicitly specified row */ - return glp_transform_row(lp, len, ind, val); -} - -int lpx_transform_col(LPX *lp, int len, int ind[], double val[]) -{ /* transform explicitly specified column */ - return glp_transform_col(lp, len, ind, val); -} - -int lpx_prim_ratio_test(LPX *lp, int len, const int ind[], - const double val[], int how, double tol) -{ /* perform primal ratio test */ - int piv; - piv = glp_prim_rtest(lp, len, ind, val, how, tol); - xassert(0 <= piv && piv <= len); - return piv == 0 ? 0 : ind[piv]; -} - -int lpx_dual_ratio_test(LPX *lp, int len, const int ind[], - const double val[], int how, double tol) -{ /* perform dual ratio test */ - int piv; - piv = glp_dual_rtest(lp, len, ind, val, how, tol); - xassert(0 <= piv && piv <= len); - return piv == 0 ? 0 : ind[piv]; -} - -int lpx_interior(LPX *lp) -{ /* easy-to-use driver to the interior-point method */ - int ret; - ret = glp_interior(lp, NULL); - switch (ret) - { case 0: ret = LPX_E_OK; break; - case GLP_EFAIL: ret = LPX_E_FAULT; break; - case GLP_ENOFEAS: ret = LPX_E_NOFEAS; break; - case GLP_ENOCVG: ret = LPX_E_NOCONV; break; - case GLP_EITLIM: ret = LPX_E_ITLIM; break; - case GLP_EINSTAB: ret = LPX_E_INSTAB; break; - default: xassert(ret != ret); - } - return ret; -} - -int lpx_ipt_status(glp_prob *lp) -{ /* retrieve status of interior-point solution */ - int status; - switch (glp_ipt_status(lp)) - { case GLP_UNDEF: status = LPX_T_UNDEF; break; - case GLP_OPT: status = LPX_T_OPT; break; - default: xassert(lp != lp); - } - return status; -} - -double lpx_ipt_obj_val(LPX *lp) -{ /* retrieve objective value (interior point) */ - return glp_ipt_obj_val(lp); -} - -double lpx_ipt_row_prim(LPX *lp, int i) -{ /* retrieve row primal value (interior point) */ - return glp_ipt_row_prim(lp, i); -} - -double lpx_ipt_row_dual(LPX *lp, int i) -{ /* retrieve row dual value (interior point) */ - return glp_ipt_row_dual(lp, i); -} - -double lpx_ipt_col_prim(LPX *lp, int j) -{ /* retrieve column primal value (interior point) */ - return glp_ipt_col_prim(lp, j); -} - -double lpx_ipt_col_dual(LPX *lp, int j) -{ /* retrieve column dual value (interior point) */ - return glp_ipt_col_dual(lp, j); -} - -void lpx_set_class(LPX *lp, int klass) -{ /* set problem class */ - xassert(lp == lp); - if (!(klass == LPX_LP || klass == LPX_MIP)) - xerror("lpx_set_class: invalid problem class\n"); - return; -} - -int lpx_get_class(LPX *lp) -{ /* determine problem klass */ - return glp_get_num_int(lp) == 0 ? LPX_LP : LPX_MIP; -} - -void lpx_set_col_kind(LPX *lp, int j, int kind) -{ /* set (change) column kind */ - glp_set_col_kind(lp, j, kind - LPX_CV + GLP_CV); - return; -} - -int lpx_get_col_kind(LPX *lp, int j) -{ /* retrieve column kind */ - return glp_get_col_kind(lp, j) == GLP_CV ? LPX_CV : LPX_IV; -} - -int lpx_get_num_int(LPX *lp) -{ /* retrieve number of integer columns */ - return glp_get_num_int(lp); -} - -int lpx_get_num_bin(LPX *lp) -{ /* retrieve number of binary columns */ - return glp_get_num_bin(lp); -} - -static int solve_mip(LPX *lp, int presolve) -{ glp_iocp parm; - int ret; - glp_init_iocp(&parm); - switch (lpx_get_int_parm(lp, LPX_K_MSGLEV)) - { case 0: parm.msg_lev = GLP_MSG_OFF; break; - case 1: parm.msg_lev = GLP_MSG_ERR; break; - case 2: parm.msg_lev = GLP_MSG_ON; break; - case 3: parm.msg_lev = GLP_MSG_ALL; break; - default: xassert(lp != lp); - } - switch (lpx_get_int_parm(lp, LPX_K_BRANCH)) - { case 0: parm.br_tech = GLP_BR_FFV; break; - case 1: parm.br_tech = GLP_BR_LFV; break; - case 2: parm.br_tech = GLP_BR_DTH; break; - case 3: parm.br_tech = GLP_BR_MFV; break; - default: xassert(lp != lp); - } - switch (lpx_get_int_parm(lp, LPX_K_BTRACK)) - { case 0: parm.bt_tech = GLP_BT_DFS; break; - case 1: parm.bt_tech = GLP_BT_BFS; break; - case 2: parm.bt_tech = GLP_BT_BPH; break; - case 3: parm.bt_tech = GLP_BT_BLB; break; - default: xassert(lp != lp); - } - parm.tol_int = lpx_get_real_parm(lp, LPX_K_TOLINT); - parm.tol_obj = lpx_get_real_parm(lp, LPX_K_TOLOBJ); - if (lpx_get_real_parm(lp, LPX_K_TMLIM) < 0.0 || - lpx_get_real_parm(lp, LPX_K_TMLIM) > 1e6) - parm.tm_lim = INT_MAX; - else - parm.tm_lim = - (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_TMLIM)); - parm.mip_gap = lpx_get_real_parm(lp, LPX_K_MIPGAP); - if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_GOMORY) - parm.gmi_cuts = GLP_ON; - else - parm.gmi_cuts = GLP_OFF; - if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_MIR) - parm.mir_cuts = GLP_ON; - else - parm.mir_cuts = GLP_OFF; - if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_COVER) - parm.cov_cuts = GLP_ON; - else - parm.cov_cuts = GLP_OFF; - if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_CLIQUE) - parm.clq_cuts = GLP_ON; - else - parm.clq_cuts = GLP_OFF; - parm.presolve = presolve; - if (lpx_get_int_parm(lp, LPX_K_BINARIZE)) - parm.binarize = GLP_ON; - ret = glp_intopt(lp, &parm); - switch (ret) - { case 0: ret = LPX_E_OK; break; - case GLP_ENOPFS: ret = LPX_E_NOPFS; break; - case GLP_ENODFS: ret = LPX_E_NODFS; break; - case GLP_EBOUND: - case GLP_EROOT: ret = LPX_E_FAULT; break; - case GLP_EFAIL: ret = LPX_E_SING; break; - case GLP_EMIPGAP: ret = LPX_E_MIPGAP; break; - case GLP_ETMLIM: ret = LPX_E_TMLIM; break; - default: xassert(ret != ret); - } - return ret; -} - -int lpx_integer(LPX *lp) -{ /* easy-to-use driver to the branch-and-bound method */ - return solve_mip(lp, GLP_OFF); -} - -int lpx_intopt(LPX *lp) -{ /* easy-to-use driver to the branch-and-bound method */ - return solve_mip(lp, GLP_ON); -} - -int lpx_mip_status(glp_prob *lp) -{ /* retrieve status of MIP solution */ - int status; - switch (glp_mip_status(lp)) - { case GLP_UNDEF: status = LPX_I_UNDEF; break; - case GLP_OPT: status = LPX_I_OPT; break; - case GLP_FEAS: status = LPX_I_FEAS; break; - case GLP_NOFEAS: status = LPX_I_NOFEAS; break; - default: xassert(lp != lp); - } - return status; -} - -double lpx_mip_obj_val(LPX *lp) -{ /* retrieve objective value (MIP solution) */ - return glp_mip_obj_val(lp); -} - -double lpx_mip_row_val(LPX *lp, int i) -{ /* retrieve row value (MIP solution) */ - return glp_mip_row_val(lp, i); -} - -double lpx_mip_col_val(LPX *lp, int j) -{ /* retrieve column value (MIP solution) */ - return glp_mip_col_val(lp, j); -} - -void lpx_check_int(LPX *lp, LPXKKT *kkt) -{ /* check integer feasibility conditions */ - int ae_ind, re_ind; - double ae_max, re_max; - glp_check_kkt(lp, GLP_MIP, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, - &re_ind); - kkt->pe_ae_max = ae_max; - kkt->pe_ae_row = ae_ind; - kkt->pe_re_max = re_max; - kkt->pe_re_row = re_ind; - if (re_max <= 1e-9) - kkt->pe_quality = 'H'; - else if (re_max <= 1e-6) - kkt->pe_quality = 'M'; - else if (re_max <= 1e-3) - kkt->pe_quality = 'L'; - else - kkt->pe_quality = '?'; - glp_check_kkt(lp, GLP_MIP, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, - &re_ind); - kkt->pb_ae_max = ae_max; - kkt->pb_ae_ind = ae_ind; - kkt->pb_re_max = re_max; - kkt->pb_re_ind = re_ind; - if (re_max <= 1e-9) - kkt->pb_quality = 'H'; - else if (re_max <= 1e-6) - kkt->pb_quality = 'M'; - else if (re_max <= 1e-3) - kkt->pb_quality = 'L'; - else - kkt->pb_quality = '?'; - return; -} - -void lpx_reset_parms(LPX *lp) -{ /* reset control parameters to default values */ - struct CPS *cps = find_cps(lp); - reset_cps(cps); - return; -} - -void lpx_set_int_parm(LPX *lp, int parm, int val) -{ /* set (change) integer control parameter */ - struct CPS *cps = find_cps(lp); - switch (parm) - { case LPX_K_MSGLEV: - if (!(0 <= val && val <= 3)) - xerror("lpx_set_int_parm: MSGLEV = %d; invalid value\n", - val); - cps->msg_lev = val; - break; - case LPX_K_SCALE: - if (!(0 <= val && val <= 3)) - xerror("lpx_set_int_parm: SCALE = %d; invalid value\n", - val); - cps->scale = val; - break; - case LPX_K_DUAL: - if (!(val == 0 || val == 1)) - xerror("lpx_set_int_parm: DUAL = %d; invalid value\n", - val); - cps->dual = val; - break; - case LPX_K_PRICE: - if (!(val == 0 || val == 1)) - xerror("lpx_set_int_parm: PRICE = %d; invalid value\n", - val); - cps->price = val; - break; - case LPX_K_ROUND: - if (!(val == 0 || val == 1)) - xerror("lpx_set_int_parm: ROUND = %d; invalid value\n", - val); - cps->round = val; - break; - case LPX_K_ITLIM: - cps->it_lim = val; - break; - case LPX_K_ITCNT: - glp_set_it_cnt(lp, val); - break; - case LPX_K_OUTFRQ: - if (!(val > 0)) - xerror("lpx_set_int_parm: OUTFRQ = %d; invalid value\n", - val); - cps->out_frq = val; - break; - case LPX_K_BRANCH: - if (!(val == 0 || val == 1 || val == 2 || val == 3)) - xerror("lpx_set_int_parm: BRANCH = %d; invalid value\n", - val); - cps->branch = val; - break; - case LPX_K_BTRACK: - if (!(val == 0 || val == 1 || val == 2 || val == 3)) - xerror("lpx_set_int_parm: BTRACK = %d; invalid value\n", - val); - cps->btrack = val; - break; - case LPX_K_MPSINFO: - if (!(val == 0 || val == 1)) - xerror("lpx_set_int_parm: MPSINFO = %d; invalid value\n", - val); - cps->mps_info = val; - break; - case LPX_K_MPSOBJ: - if (!(val == 0 || val == 1 || val == 2)) - xerror("lpx_set_int_parm: MPSOBJ = %d; invalid value\n", - val); - cps->mps_obj = val; - break; - case LPX_K_MPSORIG: - if (!(val == 0 || val == 1)) - xerror("lpx_set_int_parm: MPSORIG = %d; invalid value\n", - val); - cps->mps_orig = val; - break; - case LPX_K_MPSWIDE: - if (!(val == 0 || val == 1)) - xerror("lpx_set_int_parm: MPSWIDE = %d; invalid value\n", - val); - cps->mps_wide = val; - break; - case LPX_K_MPSFREE: - if (!(val == 0 || val == 1)) - xerror("lpx_set_int_parm: MPSFREE = %d; invalid value\n", - val); - cps->mps_free = val; - break; - case LPX_K_MPSSKIP: - if (!(val == 0 || val == 1)) - xerror("lpx_set_int_parm: MPSSKIP = %d; invalid value\n", - val); - cps->mps_skip = val; - break; - case LPX_K_LPTORIG: - if (!(val == 0 || val == 1)) - xerror("lpx_set_int_parm: LPTORIG = %d; invalid value\n", - val); - cps->lpt_orig = val; - break; - case LPX_K_PRESOL: - if (!(val == 0 || val == 1)) - xerror("lpx_set_int_parm: PRESOL = %d; invalid value\n", - val); - cps->presol = val; - break; - case LPX_K_BINARIZE: - if (!(val == 0 || val == 1)) - xerror("lpx_set_int_parm: BINARIZE = %d; invalid value\n" - , val); - cps->binarize = val; - break; - case LPX_K_USECUTS: - if (val & ~LPX_C_ALL) - xerror("lpx_set_int_parm: USECUTS = 0x%X; invalid value\n", - val); - cps->use_cuts = val; - break; - case LPX_K_BFTYPE: - { glp_bfcp parm; - glp_get_bfcp(lp, &parm); - switch (val) - { case 1: - parm.type = GLP_BF_FT; break; - case 2: - parm.type = GLP_BF_BG; break; - case 3: - parm.type = GLP_BF_GR; break; - default: - xerror("lpx_set_int_parm: BFTYPE = %d; invalid val" - "ue\n", val); - } - glp_set_bfcp(lp, &parm); - } - break; - default: - xerror("lpx_set_int_parm: parm = %d; invalid parameter\n", - parm); - } - return; -} - -int lpx_get_int_parm(LPX *lp, int parm) -{ /* query integer control parameter */ - struct CPS *cps = find_cps(lp); - int val = 0; - switch (parm) - { case LPX_K_MSGLEV: - val = cps->msg_lev; break; - case LPX_K_SCALE: - val = cps->scale; break; - case LPX_K_DUAL: - val = cps->dual; break; - case LPX_K_PRICE: - val = cps->price; break; - case LPX_K_ROUND: - val = cps->round; break; - case LPX_K_ITLIM: - val = cps->it_lim; break; - case LPX_K_ITCNT: - val = glp_get_it_cnt(lp); break; - case LPX_K_OUTFRQ: - val = cps->out_frq; break; - case LPX_K_BRANCH: - val = cps->branch; break; - case LPX_K_BTRACK: - val = cps->btrack; break; - case LPX_K_MPSINFO: - val = cps->mps_info; break; - case LPX_K_MPSOBJ: - val = cps->mps_obj; break; - case LPX_K_MPSORIG: - val = cps->mps_orig; break; - case LPX_K_MPSWIDE: - val = cps->mps_wide; break; - case LPX_K_MPSFREE: - val = cps->mps_free; break; - case LPX_K_MPSSKIP: - val = cps->mps_skip; break; - case LPX_K_LPTORIG: - val = cps->lpt_orig; break; - case LPX_K_PRESOL: - val = cps->presol; break; - case LPX_K_BINARIZE: - val = cps->binarize; break; - case LPX_K_USECUTS: - val = cps->use_cuts; break; - case LPX_K_BFTYPE: - { glp_bfcp parm; - glp_get_bfcp(lp, &parm); - switch (parm.type) - { case GLP_BF_FT: - val = 1; break; - case GLP_BF_BG: - val = 2; break; - case GLP_BF_GR: - val = 3; break; - default: - xassert(lp != lp); - } - } - break; - default: - xerror("lpx_get_int_parm: parm = %d; invalid parameter\n", - parm); - } - return val; -} - -void lpx_set_real_parm(LPX *lp, int parm, double val) -{ /* set (change) real control parameter */ - struct CPS *cps = find_cps(lp); - switch (parm) - { case LPX_K_RELAX: - if (!(0.0 <= val && val <= 1.0)) - xerror("lpx_set_real_parm: RELAX = %g; invalid value\n", - val); - cps->relax = val; - break; - case LPX_K_TOLBND: - if (!(DBL_EPSILON <= val && val <= 0.001)) - xerror("lpx_set_real_parm: TOLBND = %g; invalid value\n", - val); - cps->tol_bnd = val; - break; - case LPX_K_TOLDJ: - if (!(DBL_EPSILON <= val && val <= 0.001)) - xerror("lpx_set_real_parm: TOLDJ = %g; invalid value\n", - val); - cps->tol_dj = val; - break; - case LPX_K_TOLPIV: - if (!(DBL_EPSILON <= val && val <= 0.001)) - xerror("lpx_set_real_parm: TOLPIV = %g; invalid value\n", - val); - cps->tol_piv = val; - break; - case LPX_K_OBJLL: - cps->obj_ll = val; - break; - case LPX_K_OBJUL: - cps->obj_ul = val; - break; - case LPX_K_TMLIM: - cps->tm_lim = val; - break; - case LPX_K_OUTDLY: - cps->out_dly = val; - break; - case LPX_K_TOLINT: - if (!(DBL_EPSILON <= val && val <= 0.001)) - xerror("lpx_set_real_parm: TOLINT = %g; invalid value\n", - val); - cps->tol_int = val; - break; - case LPX_K_TOLOBJ: - if (!(DBL_EPSILON <= val && val <= 0.001)) - xerror("lpx_set_real_parm: TOLOBJ = %g; invalid value\n", - val); - cps->tol_obj = val; - break; - case LPX_K_MIPGAP: - if (val < 0.0) - xerror("lpx_set_real_parm: MIPGAP = %g; invalid value\n", - val); - cps->mip_gap = val; - break; - default: - xerror("lpx_set_real_parm: parm = %d; invalid parameter\n", - parm); - } - return; -} - -double lpx_get_real_parm(LPX *lp, int parm) -{ /* query real control parameter */ - struct CPS *cps = find_cps(lp); - double val = 0.0; - switch (parm) - { case LPX_K_RELAX: - val = cps->relax; - break; - case LPX_K_TOLBND: - val = cps->tol_bnd; - break; - case LPX_K_TOLDJ: - val = cps->tol_dj; - break; - case LPX_K_TOLPIV: - val = cps->tol_piv; - break; - case LPX_K_OBJLL: - val = cps->obj_ll; - break; - case LPX_K_OBJUL: - val = cps->obj_ul; - break; - case LPX_K_TMLIM: - val = cps->tm_lim; - break; - case LPX_K_OUTDLY: - val = cps->out_dly; - break; - case LPX_K_TOLINT: - val = cps->tol_int; - break; - case LPX_K_TOLOBJ: - val = cps->tol_obj; - break; - case LPX_K_MIPGAP: - val = cps->mip_gap; - break; - default: - xerror("lpx_get_real_parm: parm = %d; invalid parameter\n", - parm); - } - return val; -} - -LPX *lpx_read_mps(const char *fname) -{ /* read problem data in fixed MPS format */ - LPX *lp = lpx_create_prob(); - if (glp_read_mps(lp, GLP_MPS_DECK, NULL, fname)) - lpx_delete_prob(lp), lp = NULL; - return lp; -} - -int lpx_write_mps(LPX *lp, const char *fname) -{ /* write problem data in fixed MPS format */ - return glp_write_mps(lp, GLP_MPS_DECK, NULL, fname); -} - -int lpx_read_bas(LPX *lp, const char *fname) -{ /* read LP basis in fixed MPS format */ - xassert(lp == lp); - xassert(fname == fname); - xerror("lpx_read_bas: operation not supported\n"); - return 0; -} - -int lpx_write_bas(LPX *lp, const char *fname) -{ /* write LP basis in fixed MPS format */ - xassert(lp == lp); - xassert(fname == fname); - xerror("lpx_write_bas: operation not supported\n"); - return 0; -} - -LPX *lpx_read_freemps(const char *fname) -{ /* read problem data in free MPS format */ - LPX *lp = lpx_create_prob(); - if (glp_read_mps(lp, GLP_MPS_FILE, NULL, fname)) - lpx_delete_prob(lp), lp = NULL; - return lp; -} - -int lpx_write_freemps(LPX *lp, const char *fname) -{ /* write problem data in free MPS format */ - return glp_write_mps(lp, GLP_MPS_FILE, NULL, fname); -} - -LPX *lpx_read_cpxlp(const char *fname) -{ /* read problem data in CPLEX LP format */ - LPX *lp; - lp = lpx_create_prob(); - if (glp_read_lp(lp, NULL, fname)) - lpx_delete_prob(lp), lp = NULL; - return lp; -} - -int lpx_write_cpxlp(LPX *lp, const char *fname) -{ /* write problem data in CPLEX LP format */ - return glp_write_lp(lp, NULL, fname); -} - -LPX *lpx_read_model(const char *model, const char *data, const char - *output) -{ /* read LP/MIP model written in GNU MathProg language */ - LPX *lp = NULL; - glp_tran *tran; - /* allocate the translator workspace */ - tran = glp_mpl_alloc_wksp(); - /* read model section and optional data section */ - if (glp_mpl_read_model(tran, model, data != NULL)) goto done; - /* read separate data section, if required */ - if (data != NULL) - if (glp_mpl_read_data(tran, data)) goto done; - /* generate the model */ - if (glp_mpl_generate(tran, output)) goto done; - /* build the problem instance from the model */ - lp = lpx_create_prob(); - glp_mpl_build_prob(tran, lp); -done: /* free the translator workspace */ - glp_mpl_free_wksp(tran); - /* bring the problem object to the calling program */ - return lp; -} - -int lpx_print_prob(LPX *lp, const char *fname) -{ /* write problem data in plain text format */ - return glp_write_lp(lp, NULL, fname); -} - -int lpx_print_sol(LPX *lp, const char *fname) -{ /* write LP problem solution in printable format */ - return glp_print_sol(lp, fname); -} - -int lpx_print_sens_bnds(LPX *lp, const char *fname) -{ /* write bounds sensitivity information */ - if (glp_get_status(lp) == GLP_OPT && !glp_bf_exists(lp)) - glp_factorize(lp); - return glp_print_ranges(lp, 0, NULL, 0, fname); -} - -int lpx_print_ips(LPX *lp, const char *fname) -{ /* write interior point solution in printable format */ - return glp_print_ipt(lp, fname); -} - -int lpx_print_mip(LPX *lp, const char *fname) -{ /* write MIP problem solution in printable format */ - return glp_print_mip(lp, fname); -} - -int lpx_is_b_avail(glp_prob *lp) -{ /* check if LP basis is available */ - return glp_bf_exists(lp); -} - -int lpx_main(int argc, const char *argv[]) -{ /* stand-alone LP/MIP solver */ - return glp_main(argc, argv); -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/examples/oldapi/lpx.h b/resources/3rdparty/glpk-4.53/examples/oldapi/lpx.h deleted file mode 100644 index 54af27eec..000000000 --- a/resources/3rdparty/glpk-4.53/examples/oldapi/lpx.h +++ /dev/null @@ -1,565 +0,0 @@ -/* lpx.h (old GLPK API) */ - -/* Written by Andrew Makhorin , August 2013. */ - -#ifndef LPX_H -#define LPX_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define LPX glp_prob - -/* problem class: */ -#define LPX_LP 100 /* linear programming (LP) */ -#define LPX_MIP 101 /* mixed integer programming (MIP) */ - -/* type of auxiliary/structural variable: */ -#define LPX_FR 110 /* free variable */ -#define LPX_LO 111 /* variable with lower bound */ -#define LPX_UP 112 /* variable with upper bound */ -#define LPX_DB 113 /* double-bounded variable */ -#define LPX_FX 114 /* fixed variable */ - -/* optimization direction flag: */ -#define LPX_MIN 120 /* minimization */ -#define LPX_MAX 121 /* maximization */ - -/* status of primal basic solution: */ -#define LPX_P_UNDEF 132 /* primal solution is undefined */ -#define LPX_P_FEAS 133 /* solution is primal feasible */ -#define LPX_P_INFEAS 134 /* solution is primal infeasible */ -#define LPX_P_NOFEAS 135 /* no primal feasible solution exists */ - -/* status of dual basic solution: */ -#define LPX_D_UNDEF 136 /* dual solution is undefined */ -#define LPX_D_FEAS 137 /* solution is dual feasible */ -#define LPX_D_INFEAS 138 /* solution is dual infeasible */ -#define LPX_D_NOFEAS 139 /* no dual feasible solution exists */ - -/* status of auxiliary/structural variable: */ -#define LPX_BS 140 /* basic variable */ -#define LPX_NL 141 /* non-basic variable on lower bound */ -#define LPX_NU 142 /* non-basic variable on upper bound */ -#define LPX_NF 143 /* non-basic free variable */ -#define LPX_NS 144 /* non-basic fixed variable */ - -/* status of interior-point solution: */ -#define LPX_T_UNDEF 150 /* interior solution is undefined */ -#define LPX_T_OPT 151 /* interior solution is optimal */ - -/* kind of structural variable: */ -#define LPX_CV 160 /* continuous variable */ -#define LPX_IV 161 /* integer variable */ - -/* status of integer solution: */ -#define LPX_I_UNDEF 170 /* integer solution is undefined */ -#define LPX_I_OPT 171 /* integer solution is optimal */ -#define LPX_I_FEAS 172 /* integer solution is feasible */ -#define LPX_I_NOFEAS 173 /* no integer solution exists */ - -/* status codes reported by the routine lpx_get_status: */ -#define LPX_OPT 180 /* optimal */ -#define LPX_FEAS 181 /* feasible */ -#define LPX_INFEAS 182 /* infeasible */ -#define LPX_NOFEAS 183 /* no feasible */ -#define LPX_UNBND 184 /* unbounded */ -#define LPX_UNDEF 185 /* undefined */ - -/* exit codes returned by solver routines: */ -#define LPX_E_OK 200 /* success */ -#define LPX_E_EMPTY 201 /* empty problem */ -#define LPX_E_BADB 202 /* invalid initial basis */ -#define LPX_E_INFEAS 203 /* infeasible initial solution */ -#define LPX_E_FAULT 204 /* unable to start the search */ -#define LPX_E_OBJLL 205 /* objective lower limit reached */ -#define LPX_E_OBJUL 206 /* objective upper limit reached */ -#define LPX_E_ITLIM 207 /* iterations limit exhausted */ -#define LPX_E_TMLIM 208 /* time limit exhausted */ -#define LPX_E_NOFEAS 209 /* no feasible solution */ -#define LPX_E_INSTAB 210 /* numerical instability */ -#define LPX_E_SING 211 /* problems with basis matrix */ -#define LPX_E_NOCONV 212 /* no convergence (interior) */ -#define LPX_E_NOPFS 213 /* no primal feas. sol. (LP presolver) */ -#define LPX_E_NODFS 214 /* no dual feas. sol. (LP presolver) */ -#define LPX_E_MIPGAP 215 /* relative mip gap tolerance reached */ - -/* control parameter identifiers: */ -#define LPX_K_MSGLEV 300 /* lp->msg_lev */ -#define LPX_K_SCALE 301 /* lp->scale */ -#define LPX_K_DUAL 302 /* lp->dual */ -#define LPX_K_PRICE 303 /* lp->price */ -#define LPX_K_RELAX 304 /* lp->relax */ -#define LPX_K_TOLBND 305 /* lp->tol_bnd */ -#define LPX_K_TOLDJ 306 /* lp->tol_dj */ -#define LPX_K_TOLPIV 307 /* lp->tol_piv */ -#define LPX_K_ROUND 308 /* lp->round */ -#define LPX_K_OBJLL 309 /* lp->obj_ll */ -#define LPX_K_OBJUL 310 /* lp->obj_ul */ -#define LPX_K_ITLIM 311 /* lp->it_lim */ -#define LPX_K_ITCNT 312 /* lp->it_cnt */ -#define LPX_K_TMLIM 313 /* lp->tm_lim */ -#define LPX_K_OUTFRQ 314 /* lp->out_frq */ -#define LPX_K_OUTDLY 315 /* lp->out_dly */ -#define LPX_K_BRANCH 316 /* lp->branch */ -#define LPX_K_BTRACK 317 /* lp->btrack */ -#define LPX_K_TOLINT 318 /* lp->tol_int */ -#define LPX_K_TOLOBJ 319 /* lp->tol_obj */ -#define LPX_K_MPSINFO 320 /* lp->mps_info */ -#define LPX_K_MPSOBJ 321 /* lp->mps_obj */ -#define LPX_K_MPSORIG 322 /* lp->mps_orig */ -#define LPX_K_MPSWIDE 323 /* lp->mps_wide */ -#define LPX_K_MPSFREE 324 /* lp->mps_free */ -#define LPX_K_MPSSKIP 325 /* lp->mps_skip */ -#define LPX_K_LPTORIG 326 /* lp->lpt_orig */ -#define LPX_K_PRESOL 327 /* lp->presol */ -#define LPX_K_BINARIZE 328 /* lp->binarize */ -#define LPX_K_USECUTS 329 /* lp->use_cuts */ -#define LPX_K_BFTYPE 330 /* lp->bfcp->type */ -#define LPX_K_MIPGAP 331 /* lp->mip_gap */ - -#define LPX_C_COVER 0x01 /* mixed cover cuts */ -#define LPX_C_CLIQUE 0x02 /* clique cuts */ -#define LPX_C_GOMORY 0x04 /* Gomory's mixed integer cuts */ -#define LPX_C_MIR 0x08 /* mixed integer rounding cuts */ -#define LPX_C_ALL 0xFF /* all cuts */ - -typedef struct -{ /* this structure contains results reported by the routines which - checks Karush-Kuhn-Tucker conditions (for details see comments - to those routines) */ - /*--------------------------------------------------------------*/ - /* xR - A * xS = 0 (KKT.PE) */ - double pe_ae_max; - /* largest absolute error */ - int pe_ae_row; - /* number of row with largest absolute error */ - double pe_re_max; - /* largest relative error */ - int pe_re_row; - /* number of row with largest relative error */ - int pe_quality; - /* quality of primal solution: - 'H' - high - 'M' - medium - 'L' - low - '?' - primal solution is wrong */ - /*--------------------------------------------------------------*/ - /* l[k] <= x[k] <= u[k] (KKT.PB) */ - double pb_ae_max; - /* largest absolute error */ - int pb_ae_ind; - /* number of variable with largest absolute error */ - double pb_re_max; - /* largest relative error */ - int pb_re_ind; - /* number of variable with largest relative error */ - int pb_quality; - /* quality of primal feasibility: - 'H' - high - 'M' - medium - 'L' - low - '?' - primal solution is infeasible */ - /*--------------------------------------------------------------*/ - /* A' * (dR - cR) + (dS - cS) = 0 (KKT.DE) */ - double de_ae_max; - /* largest absolute error */ - int de_ae_col; - /* number of column with largest absolute error */ - double de_re_max; - /* largest relative error */ - int de_re_col; - /* number of column with largest relative error */ - int de_quality; - /* quality of dual solution: - 'H' - high - 'M' - medium - 'L' - low - '?' - dual solution is wrong */ - /*--------------------------------------------------------------*/ - /* d[k] >= 0 or d[k] <= 0 (KKT.DB) */ - double db_ae_max; - /* largest absolute error */ - int db_ae_ind; - /* number of variable with largest absolute error */ - double db_re_max; - /* largest relative error */ - int db_re_ind; - /* number of variable with largest relative error */ - int db_quality; - /* quality of dual feasibility: - 'H' - high - 'M' - medium - 'L' - low - '?' - dual solution is infeasible */ - /*--------------------------------------------------------------*/ - /* (x[k] - bound of x[k]) * d[k] = 0 (KKT.CS) */ - double cs_ae_max; - /* largest absolute error */ - int cs_ae_ind; - /* number of variable with largest absolute error */ - double cs_re_max; - /* largest relative error */ - int cs_re_ind; - /* number of variable with largest relative error */ - int cs_quality; - /* quality of complementary slackness: - 'H' - high - 'M' - medium - 'L' - low - '?' - primal and dual solutions are not complementary */ -} LPXKKT; - -LPX *lpx_create_prob(void); -/* create problem object */ - -void lpx_set_prob_name(LPX *lp, const char *name); -/* assign (change) problem name */ - -void lpx_set_obj_name(LPX *lp, const char *name); -/* assign (change) objective function name */ - -void lpx_set_obj_dir(LPX *lp, int dir); -/* set (change) optimization direction flag */ - -int lpx_add_rows(LPX *lp, int nrs); -/* add new rows to problem object */ - -int lpx_add_cols(LPX *lp, int ncs); -/* add new columns to problem object */ - -void lpx_set_row_name(LPX *lp, int i, const char *name); -/* assign (change) row name */ - -void lpx_set_col_name(LPX *lp, int j, const char *name); -/* assign (change) column name */ - -void lpx_set_row_bnds(LPX *lp, int i, int type, double lb, double ub); -/* set (change) row bounds */ - -void lpx_set_col_bnds(LPX *lp, int j, int type, double lb, double ub); -/* set (change) column bounds */ - -void lpx_set_obj_coef(glp_prob *lp, int j, double coef); -/* set (change) obj. coefficient or constant term */ - -void lpx_set_mat_row(LPX *lp, int i, int len, const int ind[], - const double val[]); -/* set (replace) row of the constraint matrix */ - -void lpx_set_mat_col(LPX *lp, int j, int len, const int ind[], - const double val[]); -/* set (replace) column of the constraint matrix */ - -void lpx_load_matrix(LPX *lp, int ne, const int ia[], const int ja[], - const double ar[]); -/* load (replace) the whole constraint matrix */ - -void lpx_del_rows(LPX *lp, int nrs, const int num[]); -/* delete specified rows from problem object */ - -void lpx_del_cols(LPX *lp, int ncs, const int num[]); -/* delete specified columns from problem object */ - -void lpx_delete_prob(LPX *lp); -/* delete problem object */ - -const char *lpx_get_prob_name(LPX *lp); -/* retrieve problem name */ - -const char *lpx_get_obj_name(LPX *lp); -/* retrieve objective function name */ - -int lpx_get_obj_dir(LPX *lp); -/* retrieve optimization direction flag */ - -int lpx_get_num_rows(LPX *lp); -/* retrieve number of rows */ - -int lpx_get_num_cols(LPX *lp); -/* retrieve number of columns */ - -const char *lpx_get_row_name(LPX *lp, int i); -/* retrieve row name */ - -const char *lpx_get_col_name(LPX *lp, int j); -/* retrieve column name */ - -int lpx_get_row_type(LPX *lp, int i); -/* retrieve row type */ - -double lpx_get_row_lb(LPX *lp, int i); -/* retrieve row lower bound */ - -double lpx_get_row_ub(LPX *lp, int i); -/* retrieve row upper bound */ - -void lpx_get_row_bnds(LPX *lp, int i, int *typx, double *lb, - double *ub); -/* retrieve row bounds */ - -int lpx_get_col_type(LPX *lp, int j); -/* retrieve column type */ - -double lpx_get_col_lb(LPX *lp, int j); -/* retrieve column lower bound */ - -double lpx_get_col_ub(LPX *lp, int j); -/* retrieve column upper bound */ - -void lpx_get_col_bnds(LPX *lp, int j, int *typx, double *lb, - double *ub); -/* retrieve column bounds */ - -double lpx_get_obj_coef(LPX *lp, int j); -/* retrieve obj. coefficient or constant term */ - -int lpx_get_num_nz(LPX *lp); -/* retrieve number of constraint coefficients */ - -int lpx_get_mat_row(LPX *lp, int i, int ind[], double val[]); -/* retrieve row of the constraint matrix */ - -int lpx_get_mat_col(LPX *lp, int j, int ind[], double val[]); -/* retrieve column of the constraint matrix */ - -void lpx_create_index(LPX *lp); -/* create the name index */ - -int lpx_find_row(LPX *lp, const char *name); -/* find row by its name */ - -int lpx_find_col(LPX *lp, const char *name); -/* find column by its name */ - -void lpx_delete_index(LPX *lp); -/* delete the name index */ - -void lpx_scale_prob(LPX *lp); -/* scale problem data */ - -void lpx_unscale_prob(LPX *lp); -/* unscale problem data */ - -void lpx_set_row_stat(LPX *lp, int i, int stat); -/* set (change) row status */ - -void lpx_set_col_stat(LPX *lp, int j, int stat); -/* set (change) column status */ - -void lpx_std_basis(LPX *lp); -/* construct standard initial LP basis */ - -void lpx_adv_basis(LPX *lp); -/* construct advanced initial LP basis */ - -void lpx_cpx_basis(LPX *lp); -/* construct Bixby's initial LP basis */ - -int lpx_simplex(LPX *lp); -/* easy-to-use driver to the simplex method */ - -int lpx_exact(LPX *lp); -/* easy-to-use driver to the exact simplex method */ - -int lpx_get_status(LPX *lp); -/* retrieve generic status of basic solution */ - -int lpx_get_prim_stat(LPX *lp); -/* retrieve primal status of basic solution */ - -int lpx_get_dual_stat(LPX *lp); -/* retrieve dual status of basic solution */ - -double lpx_get_obj_val(LPX *lp); -/* retrieve objective value (basic solution) */ - -int lpx_get_row_stat(LPX *lp, int i); -/* retrieve row status (basic solution) */ - -double lpx_get_row_prim(LPX *lp, int i); -/* retrieve row primal value (basic solution) */ - -double lpx_get_row_dual(LPX *lp, int i); -/* retrieve row dual value (basic solution) */ - -void lpx_get_row_info(LPX *lp, int i, int *tagx, double *vx, - double *dx); -/* obtain row solution information */ - -int lpx_get_col_stat(LPX *lp, int j); -/* retrieve column status (basic solution) */ - -double lpx_get_col_prim(LPX *lp, int j); -/* retrieve column primal value (basic solution) */ - -double lpx_get_col_dual(glp_prob *lp, int j); -/* retrieve column dual value (basic solution) */ - -void lpx_get_col_info(LPX *lp, int j, int *tagx, double *vx, - double *dx); -/* obtain column solution information (obsolete) */ - -int lpx_get_ray_info(LPX *lp); -/* determine what causes primal unboundness */ - -void lpx_check_kkt(LPX *lp, int scaled, LPXKKT *kkt); -/* check Karush-Kuhn-Tucker conditions */ - -int lpx_warm_up(LPX *lp); -/* "warm up" LP basis */ - -int lpx_eval_tab_row(LPX *lp, int k, int ind[], double val[]); -/* compute row of the simplex table */ - -int lpx_eval_tab_col(LPX *lp, int k, int ind[], double val[]); -/* compute column of the simplex table */ - -int lpx_transform_row(LPX *lp, int len, int ind[], double val[]); -/* transform explicitly specified row */ - -int lpx_transform_col(LPX *lp, int len, int ind[], double val[]); -/* transform explicitly specified column */ - -int lpx_prim_ratio_test(LPX *lp, int len, const int ind[], - const double val[], int how, double tol); -/* perform primal ratio test */ - -int lpx_dual_ratio_test(LPX *lp, int len, const int ind[], - const double val[], int how, double tol); -/* perform dual ratio test */ - -int lpx_interior(LPX *lp); -/* easy-to-use driver to the interior point method */ - -int lpx_ipt_status(LPX *lp); -/* retrieve status of interior-point solution */ - -double lpx_ipt_obj_val(LPX *lp); -/* retrieve objective value (interior point) */ - -double lpx_ipt_row_prim(LPX *lp, int i); -/* retrieve row primal value (interior point) */ - -double lpx_ipt_row_dual(LPX *lp, int i); -/* retrieve row dual value (interior point) */ - -double lpx_ipt_col_prim(LPX *lp, int j); -/* retrieve column primal value (interior point) */ - -double lpx_ipt_col_dual(LPX *lp, int j); -/* retrieve column dual value (interior point) */ - -void lpx_set_class(LPX *lp, int klass); -/* set problem class */ - -int lpx_get_class(LPX *lp); -/* determine problem klass */ - -void lpx_set_col_kind(LPX *lp, int j, int kind); -/* set (change) column kind */ - -int lpx_get_col_kind(LPX *lp, int j); -/* retrieve column kind */ - -int lpx_get_num_int(LPX *lp); -/* retrieve number of integer columns */ - -int lpx_get_num_bin(LPX *lp); -/* retrieve number of binary columns */ - -int lpx_integer(LPX *lp); -/* easy-to-use driver to the branch-and-bound method */ - -int lpx_intopt(LPX *lp); -/* easy-to-use driver to the branch-and-bound method */ - -int lpx_mip_status(LPX *lp); -/* retrieve status of MIP solution */ - -double lpx_mip_obj_val(LPX *lp); -/* retrieve objective value (MIP solution) */ - -double lpx_mip_row_val(LPX *lp, int i); -/* retrieve row value (MIP solution) */ - -double lpx_mip_col_val(LPX *lp, int j); -/* retrieve column value (MIP solution) */ - -void lpx_check_int(LPX *lp, LPXKKT *kkt); -/* check integer feasibility conditions */ - -void lpx_reset_parms(LPX *lp); -/* reset control parameters to default values */ - -void lpx_set_int_parm(LPX *lp, int parm, int val); -/* set (change) integer control parameter */ - -int lpx_get_int_parm(LPX *lp, int parm); -/* query integer control parameter */ - -void lpx_set_real_parm(LPX *lp, int parm, double val); -/* set (change) real control parameter */ - -double lpx_get_real_parm(LPX *lp, int parm); -/* query real control parameter */ - -LPX *lpx_read_mps(const char *fname); -/* read problem data in fixed MPS format */ - -int lpx_write_mps(LPX *lp, const char *fname); -/* write problem data in fixed MPS format */ - -int lpx_read_bas(LPX *lp, const char *fname); -/* read LP basis in fixed MPS format */ - -int lpx_write_bas(LPX *lp, const char *fname); -/* write LP basis in fixed MPS format */ - -LPX *lpx_read_freemps(const char *fname); -/* read problem data in free MPS format */ - -int lpx_write_freemps(LPX *lp, const char *fname); -/* write problem data in free MPS format */ - -LPX *lpx_read_cpxlp(const char *fname); -/* read problem data in CPLEX LP format */ - -int lpx_write_cpxlp(LPX *lp, const char *fname); -/* write problem data in CPLEX LP format */ - -LPX *lpx_read_model(const char *model, const char *data, - const char *output); -/* read LP/MIP model written in GNU MathProg language */ - -int lpx_print_prob(LPX *lp, const char *fname); -/* write problem data in plain text format */ - -int lpx_print_sol(LPX *lp, const char *fname); -/* write LP problem solution in printable format */ - -int lpx_print_sens_bnds(LPX *lp, const char *fname); -/* write bounds sensitivity information */ - -int lpx_print_ips(LPX *lp, const char *fname); -/* write interior point solution in printable format */ - -int lpx_print_mip(LPX *lp, const char *fname); -/* write MIP problem solution in printable format */ - -int lpx_is_b_avail(LPX *lp); -/* check if LP basis is available */ - -int lpx_main(int argc, const char *argv[]); -/* stand-alone LP/MIP solver */ - -#ifdef __cplusplus -} -#endif - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/examples/oldapi/lpxsamp.c b/resources/3rdparty/glpk-4.53/examples/oldapi/lpxsamp.c deleted file mode 100644 index dd081482f..000000000 --- a/resources/3rdparty/glpk-4.53/examples/oldapi/lpxsamp.c +++ /dev/null @@ -1,51 +0,0 @@ -/* lpxsamp.c */ - -#include -#include -#include "lpx.h" - -int main(void) -{ LPX *lp; - int ia[1+1000], ja[1+1000]; - double ar[1+1000], Z, x1, x2, x3; -s1: lp = lpx_create_prob(); -s2: lpx_set_prob_name(lp, "sample"); -s3: lpx_set_obj_dir(lp, LPX_MAX); -s4: lpx_add_rows(lp, 3); -s5: lpx_set_row_name(lp, 1, "p"); -s6: lpx_set_row_bnds(lp, 1, LPX_UP, 0.0, 100.0); -s7: lpx_set_row_name(lp, 2, "q"); -s8: lpx_set_row_bnds(lp, 2, LPX_UP, 0.0, 600.0); -s9: lpx_set_row_name(lp, 3, "r"); -s10: lpx_set_row_bnds(lp, 3, LPX_UP, 0.0, 300.0); -s11: lpx_add_cols(lp, 3); -s12: lpx_set_col_name(lp, 1, "x1"); -s13: lpx_set_col_bnds(lp, 1, LPX_LO, 0.0, 0.0); -s14: lpx_set_obj_coef(lp, 1, 10.0); -s15: lpx_set_col_name(lp, 2, "x2"); -s16: lpx_set_col_bnds(lp, 2, LPX_LO, 0.0, 0.0); -s17: lpx_set_obj_coef(lp, 2, 6.0); -s18: lpx_set_col_name(lp, 3, "x3"); -s19: lpx_set_col_bnds(lp, 3, LPX_LO, 0.0, 0.0); -s20: lpx_set_obj_coef(lp, 3, 4.0); -s21: ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */ -s22: ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */ -s23: ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */ -s24: ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */ -s25: ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */ -s26: ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */ -s27: ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */ -s28: ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */ -s29: ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */ -s30: lpx_load_matrix(lp, 9, ia, ja, ar); -s31: lpx_simplex(lp); -s32: Z = lpx_get_obj_val(lp); -s33: x1 = lpx_get_col_prim(lp, 1); -s34: x2 = lpx_get_col_prim(lp, 2); -s35: x3 = lpx_get_col_prim(lp, 3); -s36: printf("\nZ = %g; x1 = %g; x2 = %g; x3 = %g\n", Z, x1, x2, x3); -s37: lpx_delete_prob(lp); - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/9dom.dat b/resources/3rdparty/glpk-4.53/examples/pbn/9dom.dat deleted file mode 100644 index 80ece7af5..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/9dom.dat +++ /dev/null @@ -1,65 +0,0 @@ -/* 9dom.dat */ - -/*********************************************************************** -* Web Paint-by-Number Puzzle #8098 from . -* Copyright (C) 2010 by Josh Greifer. Used by permission. -* -* Domino Logic III (Abstract pattern) -* -* created by Josh Greifer -* Apr 5, 2010 -* -* Encoded in GNU MathProg by Andrew Makhorin . -***********************************************************************/ - -data; - -param m := 19; - -param n := 19; - -param row : 1 2 := - 1 3 . - 2 1 . - 3 3 1 - 4 1 . - 5 3 1 - 6 1 . - 7 3 1 - 8 1 . - 9 3 1 - 10 1 . - 11 3 1 - 12 1 . - 13 3 1 - 14 1 . - 15 3 1 - 16 1 . - 17 3 1 - 18 1 . - 19 1 . -; - -param col : 1 2 := - 1 1 . - 2 1 . - 3 1 3 - 4 1 . - 5 1 3 - 6 1 . - 7 1 3 - 8 1 . - 9 1 3 - 10 1 . - 11 1 3 - 12 1 . - 13 1 3 - 14 1 . - 15 1 3 - 16 1 . - 17 1 3 - 18 1 . - 19 3 . -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/README b/resources/3rdparty/glpk-4.53/examples/pbn/README deleted file mode 100644 index 43dc82ce3..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/README +++ /dev/null @@ -1,6 +0,0 @@ -This subdirectory contains examples, which illustrate how to use -GLPK and the GNU MathProg modeling language for practical solving the -paint-by-numbers puzzle. - -For details please see the document "Solving Paint-By-Numbers Puzzles -with GLPK" included in this subdirectory (file pbn.pdf). diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/bucks.dat b/resources/3rdparty/glpk-4.53/examples/pbn/bucks.dat deleted file mode 100644 index 5dfc4f100..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/bucks.dat +++ /dev/null @@ -1,77 +0,0 @@ -/* bucks.dat */ - -/*********************************************************************** -* Web Paint-by-Number Puzzle #27 from . -* Copyright (C) 2004 by Jan Wolter. Used by permission. -* -* Party at the Right [Political] -* -* created by Jan Wolter -* Apr 6, 2004 -* -* Encoded in GNU MathProg by Andrew Makhorin . -***********************************************************************/ - -data; - -param m := 23; - -param n := 27; - -param row : 1 2 3 4 5 6 7 8 := - 1 11 . . . . . . . - 2 17 . . . . . . . - 3 3 5 5 3 . . . . - 4 2 2 2 1 . . . . - 5 2 1 3 1 3 1 4 . - 6 3 3 3 3 . . . . - 7 5 1 3 1 3 1 3 . - 8 3 2 2 4 . . . . - 9 5 5 5 5 . . . . - 10 23 . . . . . . . - 11 . . . . . . . . - 12 23 . . . . . . . - 13 1 1 . . . . . . - 14 1 1 . . . . . . - 15 1 2 1 . . . . . - 16 1 1 1 1 . . . . - 17 1 1 1 1 . . . . - 18 1 10 1 2 1 . . . - 19 1 1 1 1 1 1 3 . - 20 1 1 1 1 1 1 1 1 - 21 1 1 1 1 1 1 1 . - 22 1 1 1 1 2 2 . . - 23 5 5 3 . . . . . -; - -param col : 1 2 3 4 5 6 := - 1 4 12 . . . . - 2 6 1 1 . . . - 3 8 1 1 . . . - 4 3 2 2 1 1 . - 5 2 1 1 2 1 6 - 6 1 1 1 1 . . - 7 3 1 1 2 1 1 - 8 3 2 3 1 1 . - 9 10 1 1 . . . - 10 4 2 2 1 1 . - 11 3 1 1 2 1 1 - 12 2 1 1 1 . . - 13 3 1 1 2 1 1 - 14 3 2 3 1 6 . - 15 10 1 1 . . . - 16 4 2 2 1 1 . - 17 3 1 1 2 1 1 - 18 1 1 1 9 . . - 19 2 1 1 2 1 1 - 20 2 2 3 1 3 . - 21 8 1 5 . . . - 22 6 1 1 . . . - 23 4 9 1 . . . - 24 1 1 . . . . - 25 2 1 . . . . - 26 1 1 . . . . - 27 4 . . . . . -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/cat.dat b/resources/3rdparty/glpk-4.53/examples/pbn/cat.dat deleted file mode 100644 index a6554117d..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/cat.dat +++ /dev/null @@ -1,67 +0,0 @@ -/* cat.dat */ - -/*********************************************************************** -* Web Paint-by-Number Puzzle #6 from . -* Copyright (C) 2004 by Jan Wolter. Used by permission. -* -* Scardy Cat -* -* created by Jan Wolter -* Mar 24, 2004 -* -* Encoded in GNU MathProg by Andrew Makhorin . -***********************************************************************/ - -data; - -param m := 20; - -param n := 20; - -param row : 1 2 3 4 := - 1 2 . . . - 2 2 . . . - 3 1 . . . - 4 1 . . . - 5 1 3 . . - 6 2 5 . . - 7 1 7 1 1 - 8 1 8 2 2 - 9 1 9 5 . - 10 2 16 . . - 11 1 17 . . - 12 7 11 . . - 13 5 5 3 . - 14 5 4 . . - 15 3 3 . . - 16 2 2 . . - 17 2 1 . . - 18 1 1 . . - 19 2 2 . . - 20 2 2 . . -; - -param col : 1 2 3 := - 1 5 . . - 2 5 3 . - 3 2 3 4 - 4 1 7 2 - 5 8 . . - 6 9 . . - 7 9 . . - 8 8 . . - 9 7 . . - 10 8 . . - 11 9 . . - 12 10 . . - 13 13 . . - 14 6 2 . - 15 4 . . - 16 6 . . - 17 6 . . - 18 5 . . - 19 6 . . - 20 6 . . -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/dancer.dat b/resources/3rdparty/glpk-4.53/examples/pbn/dancer.dat deleted file mode 100644 index 42e3057a4..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/dancer.dat +++ /dev/null @@ -1,42 +0,0 @@ -/* dancer.dat */ - -/*********************************************************************** -* Web Paint-by-Number Puzzle #1 from . -* Copyright (C) 2004 by Jan Wolter. Used by permission. -* -* Demo Puzzle from Front Page -* -* created by Jan Wolter -* Mar 24, 2004 -* -* Encoded in GNU MathProg by Andrew Makhorin . -***********************************************************************/ - -data; - -param m := 10; - -param n := 5; - -param row : 1 2 3 := - 1 2 . . - 2 2 1 . - 3 1 1 . - 4 3 . . - 5 1 1 . - 6 1 1 . - 7 2 . . - 8 1 1 . - 9 1 2 . - 10 2 . . -; - -param col : 1 2 3 := - 1 2 1 . - 2 2 1 3 - 3 7 . . - 4 1 3 . - 5 2 1 . -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/dragon.dat b/resources/3rdparty/glpk-4.53/examples/pbn/dragon.dat deleted file mode 100644 index d2b8b14de..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/dragon.dat +++ /dev/null @@ -1,61 +0,0 @@ -/* dragon.dat */ - -/*********************************************************************** -* Hard 20x20 paint-by-numbers puzzle designed by Won Yoon Jo -* from the article "Painting by Numbers" by Robert A. Bosch (2000), -* . -* -* Encoded in GNU MathProg by Andrew Makhorin . -***********************************************************************/ - -data; - -param m := 20; - -param n := 20; - -param row : 1 2 3 4 5 := - 1 7 1 . . . - 2 1 1 2 . . - 3 2 1 2 . . - 4 1 2 2 . . - 5 4 2 3 . . - 6 3 1 4 . . - 7 3 1 3 . . - 8 2 1 4 . . - 9 2 9 . . . - 10 2 1 5 . . - 11 2 7 . . . - 12 14 . . . . - 13 8 2 . . . - 14 6 2 2 . . - 15 2 8 1 3 . - 16 1 5 5 2 . - 17 1 3 2 4 1 - 18 3 1 2 4 1 - 19 1 1 3 1 3 - 20 2 1 1 2 . ; - -param col : 1 2 3 4 5 := - 1 1 1 1 2 . - 2 3 1 2 1 1 - 3 1 4 2 1 1 - 4 1 3 2 4 . - 5 1 4 6 1 . - 6 1 11 1 . . - 7 5 1 6 2 . - 8 14 . . . . - 9 7 2 . . . - 10 7 2 . . . - 11 6 1 1 . . - 12 9 2 . . . - 13 3 1 1 1 . - 14 3 1 3 . . - 15 2 1 3 . . - 16 2 1 5 . . - 17 3 2 2 . . - 18 3 3 2 . . - 19 2 3 2 . . - 20 2 6 . . . ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/edge.dat b/resources/3rdparty/glpk-4.53/examples/pbn/edge.dat deleted file mode 100644 index cdd1864e9..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/edge.dat +++ /dev/null @@ -1,48 +0,0 @@ -/* edge.dat */ - -/*********************************************************************** -* Web Paint-by-Number Puzzle #23 from . -* Copyright (C) 2004 by Jan Wolter. Used by permission. -* -* Nonrepresentational Test Pattern -* -* created by Jan Wolter -* Apr 5, 2004 -* -* Encoded in GNU MathProg by Andrew Makhorin . -***********************************************************************/ - -data; - -param m := 11; - -param n := 10; - -param row : 1 := - 1 1 - 2 3 - 3 1 - 4 2 - 5 1 - 6 3 - 7 3 - 8 1 - 9 2 - 10 2 - 11 4 -; - -param col : 1 2 := - 1 1 . - 2 3 . - 3 1 . - 4 2 2 - 5 2 . - 6 4 . - 7 1 . - 8 3 . - 9 3 . - 10 1 . -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/forever.dat b/resources/3rdparty/glpk-4.53/examples/pbn/forever.dat deleted file mode 100644 index e3bebf75f..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/forever.dat +++ /dev/null @@ -1,77 +0,0 @@ -/* forever.dat */ - -/*********************************************************************** -* Web Paint-by-Number Puzzle #6574 from . -* Copyright (C) 2009 by Gator. Used by permission. -* -* Lasts Forever -* -* created by Gator -* Aug 24, 2009 -* -* Encoded in GNU MathProg by Andrew Makhorin . -***********************************************************************/ - -data; - -param m := 25; - -param n := 25; - -param row : 1 2 3 4 5 6 7 8 := - 1 1 2 2 2 2 2 1 . - 2 1 2 2 2 2 2 1 1 - 3 1 1 . . . . . . - 4 1 1 . . . . . . - 5 1 3 1 . . . . . - 6 1 13 1 . . . . . - 7 1 13 1 . . . . . - 8 1 13 1 . . . . . - 9 1 4 4 1 . . . . - 10 1 4 3 4 1 . . . - 11 1 4 5 4 1 . . . - 12 1 7 1 . . . . . - 13 1 7 1 . . . . . - 14 1 7 1 . . . . . - 15 1 7 1 . . . . . - 16 1 1 5 1 . . . . - 17 1 2 6 1 . . . . - 18 1 4 6 1 . . . . - 19 1 6 6 1 . . . . - 20 1 3 1 . . . . . - 21 1 1 1 . . . . . - 22 1 1 . . . . . . - 23 1 1 . . . . . . - 24 1 1 2 2 2 2 2 1 - 25 1 2 2 2 2 2 1 . -; - -param col : 1 2 3 4 5 6 7 8 := - 1 1 2 2 2 2 2 1 . - 2 1 1 2 2 2 2 2 1 - 3 1 1 . . . . . . - 4 1 1 . . . . . . - 5 1 1 . . . . . . - 6 1 2 1 . . . . . - 7 1 6 1 1 . . . . - 8 1 6 2 1 . . . . - 9 1 6 3 1 . . . . - 10 1 4 8 1 . . . . - 11 1 3 5 2 1 . . . - 12 1 4 8 2 1 . . . - 13 1 4 9 2 1 . . . - 14 1 4 11 1 . . . . - 15 1 3 9 1 . . . . - 16 1 4 8 1 . . . . - 17 1 6 3 1 . . . . - 18 1 6 2 1 . . . . - 19 1 6 1 1 . . . . - 20 1 2 1 . . . . . - 21 1 1 . . . . . . - 22 1 1 . . . . . . - 23 1 1 . . . . . . - 24 1 2 2 2 2 2 1 1 - 25 1 2 2 2 2 2 1 . -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/knot.dat b/resources/3rdparty/glpk-4.53/examples/pbn/knot.dat deleted file mode 100644 index b9e12d796..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/knot.dat +++ /dev/null @@ -1,95 +0,0 @@ -/* knot.dat */ - -/*********************************************************************** -* Web Paint-by-Number Puzzle #16 from . -* Copyright (C) 2004 by Jan Wolter. Used by permission. -* -* Probably Not -* -* created by Jan Wolter -* Mar 27, 2004 -* -* Encoded in GNU MathProg by Andrew Makhorin . -***********************************************************************/ - -data; - -param m := 34; - -param n := 34; - -param row : 1 2 3 4 5 6 7 8 := - 1 1 1 . . . . . . - 2 2 2 . . . . . . - 3 3 3 . . . . . . - 4 2 1 1 2 . . . . - 5 2 1 1 2 . . . . - 6 1 1 1 1 . . . . - 7 1 1 1 1 . . . . - 8 18 . . . . . . . - 9 2 1 1 1 1 2 . . - 10 1 1 1 1 1 1 . . - 11 1 1 1 1 1 1 . . - 12 26 . . . . . . . - 13 2 1 1 1 1 1 1 2 - 14 2 1 1 2 2 1 1 2 - 15 2 1 1 2 2 1 1 2 - 16 14 14 . . . . . . - 17 1 1 1 1 . . . . - 18 1 1 1 1 . . . . - 19 14 14 . . . . . . - 20 2 1 1 2 2 1 1 2 - 21 2 1 1 2 2 1 1 2 - 22 2 1 1 1 1 1 1 2 - 23 26 . . . . . . . - 24 1 1 1 1 1 1 . . - 25 1 1 1 1 1 1 . . - 26 2 1 1 1 1 2 . . - 27 18 . . . . . . . - 28 1 1 1 1 . . . . - 29 1 1 1 1 . . . . - 30 2 1 1 2 . . . . - 31 2 1 1 2 . . . . - 32 3 3 . . . . . . - 33 2 2 . . . . . . - 34 1 1 . . . . . . -; - -param col : 1 2 3 4 5 6 7 8 := - 1 1 1 . . . . . . - 2 2 2 . . . . . . - 3 3 3 . . . . . . - 4 2 1 1 2 . . . . - 5 2 1 1 2 . . . . - 6 1 1 1 1 . . . . - 7 1 1 1 1 . . . . - 8 18 . . . . . . . - 9 2 1 1 1 1 2 . . - 10 1 1 1 1 1 1 . . - 11 1 1 1 1 1 1 . . - 12 26 . . . . . . . - 13 2 1 1 1 1 1 1 2 - 14 2 1 1 2 2 1 1 2 - 15 2 1 1 2 2 1 1 2 - 16 14 14 . . . . . . - 17 1 1 1 1 . . . . - 18 1 1 1 1 . . . . - 19 14 14 . . . . . . - 20 2 1 1 2 2 1 1 2 - 21 2 1 1 2 2 1 1 2 - 22 2 1 1 1 1 1 1 2 - 23 26 . . . . . . . - 24 1 1 1 1 1 1 . . - 25 1 1 1 1 1 1 . . - 26 2 1 1 1 1 2 . . - 27 18 . . . . . . . - 28 1 1 1 1 . . . . - 29 1 1 1 1 . . . . - 30 2 1 1 2 . . . . - 31 2 1 1 2 . . . . - 32 3 3 . . . . . . - 33 2 2 . . . . . . - 34 1 1 . . . . . . -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/light.dat b/resources/3rdparty/glpk-4.53/examples/pbn/light.dat deleted file mode 100644 index 1ffc5d460..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/light.dat +++ /dev/null @@ -1,122 +0,0 @@ -/* light.dat */ - -/*********************************************************************** -* Web Paint-by-Number Puzzle #803 from . -* Copyright (C) 2007 by Robert Kummerfeldt. Used by permission. -* -* You light up my life -* -* created by Robert Kummerfeldt -* Mar 15, 2007 -* -* Encoded in GNU MathProg by Andrew Makhorin . -***********************************************************************/ - -data; - -param m := 45; - -param n := 50; - -param row : 1 2 3 4 := - 1 . . . . - 2 1 . . . - 3 1 . . . - 4 3 . . . - 5 2 2 . . - 6 1 1 . . - 7 7 . . . - 8 1 1 . . - 9 1 3 1 . - 10 1 3 1 . - 11 1 1 . . - 12 11 . . . - 13 1 1 . . - 14 1 1 . . - 15 2 2 . . - 16 1 1 . . - 17 1 1 . . - 18 1 1 . . - 19 1 1 . . - 20 2 2 . . - 21 1 1 . . - 22 1 1 . . - 23 1 1 . . - 24 1 1 . . - 25 1 1 . . - 26 1 1 . . - 27 1 1 . . - 28 1 1 . . - 29 1 1 . . - 30 1 1 . . - 31 2 2 . . - 32 1 1 . . - 33 1 1 . . - 34 1 1 . . - 35 1 1 . . - 36 1 1 . . - 37 1 4 1 . - 38 1 1 1 1 - 39 1 1 1 1 - 40 1 1 1 1 - 41 1 1 1 1 - 42 25 . . . - 43 6 5 . . - 44 5 6 . . - 45 4 5 . . -; - -param col : 1 2 3 4 5 := - 1 1 . . . . - 2 1 . . . . - 3 1 . . . . - 4 2 . . . . - 5 1 . . . . - 6 1 . . . . - 7 1 . . . . - 8 2 . . . . - 9 1 . . . . - 10 1 . . . . - 11 1 . . . . - 12 1 . . . . - 13 2 . . . . - 14 1 . . . . - 15 1 . . . . - 16 1 . . . . - 17 5 . . . . - 18 7 1 . . . - 19 6 1 . . . - 20 6 1 . . . - 21 1 6 1 . . - 22 4 1 . . . - 23 7 1 . . . - 24 1 1 1 1 . - 25 2 1 2 1 1 - 26 3 1 2 1 1 - 27 2 1 2 1 1 - 28 1 1 1 1 . - 29 7 6 . . . - 30 4 1 1 . . - 31 1 6 1 1 . - 32 6 6 . . . - 33 6 1 . . . - 34 5 1 . . . - 35 7 . . . . - 36 1 . . . . - 37 2 . . . . - 38 1 . . . . - 39 1 . . . . - 40 1 . . . . - 41 2 . . . . - 42 1 . . . . - 43 1 . . . . - 44 1 . . . . - 45 1 . . . . - 46 2 . . . . - 47 1 . . . . - 48 1 . . . . - 49 1 . . . . - 50 1 . . . . -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/mum.dat b/resources/3rdparty/glpk-4.53/examples/pbn/mum.dat deleted file mode 100644 index a1baf5090..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/mum.dat +++ /dev/null @@ -1,101 +0,0 @@ -/* mum.dat */ - -/*********************************************************************** -* Web Paint-by-Number Puzzle #65 from . -* Copyright (C) 2004 by Jan Wolter. Used by permission. -* -* Mum's the Word [has only one solution] -* -* created by Jan Wolter -* Jul 10, 2004 -* -* Encoded in GNU MathProg by Andrew Makhorin . -***********************************************************************/ - -data; - -param m := 40; - -param n := 34; - -param row : 1 2 3 4 5 6 7 8 9 := - 1 12 . . . . . . . . - 2 5 2 5 . . . . . . - 3 5 2 2 5 . . . . . - 4 1 2 2 2 2 2 1 . . - 5 4 2 2 4 2 2 4 . . - 6 4 2 2 4 2 2 4 . . - 7 1 2 2 2 2 2 1 . . - 8 6 2 2 2 2 2 6 . . - 9 6 2 2 2 2 2 6 . . - 10 1 14 1 . . . . . . - 11 10 10 . . . . . . . - 12 8 3 3 8 . . . . . - 13 1 1 2 1 1 2 1 1 . - 14 9 2 2 2 2 9 . . . - 15 9 9 . . . . . . . - 16 1 1 1 1 1 1 . . . - 17 12 2 12 . . . . . . - 18 12 12 . . . . . . . - 19 1 1 4 1 1 . . . . - 20 14 14 . . . . . . . - 21 12 12 . . . . . . . - 22 2 1 4 1 2 . . . . - 23 9 4 9 . . . . . . - 24 1 7 4 7 1 . . . . - 25 1 1 1 4 1 1 1 . . - 26 1 7 4 7 1 . . . . - 27 1 7 4 7 1 . . . . - 28 1 2 1 2 1 2 1 . . - 29 1 7 2 7 1 . . . . - 30 1 1 6 2 6 1 1 . . - 31 1 1 1 1 2 1 1 1 1 - 32 1 1 6 2 6 1 1 . . - 33 1 1 5 5 1 1 . . . - 34 1 1 1 8 1 1 1 . . - 35 1 1 4 4 1 1 . . . - 36 1 2 6 2 1 . . . . - 37 2 4 4 2 . . . . . - 38 2 6 2 . . . . . . - 39 4 4 . . . . . . . - 40 6 . . . . . . . . -; - -param col : 1 2 3 4 5 6 7 8 9 10 11 12 := - 1 5 . . . . . . . . . . . - 2 3 2 1 . . . . . . . . . - 3 3 2 2 1 . . . . . . . . - 4 3 2 2 2 2 . . . . . . . - 5 3 2 2 2 2 3 . . . . . . - 6 1 2 2 2 2 2 16 . . . . . - 7 1 2 2 2 2 2 2 1 2 . . . - 8 1 2 2 2 2 2 2 13 1 . . . - 9 3 2 2 2 2 2 2 4 1 1 . . - 10 6 5 2 2 2 2 6 1 1 . . . - 11 1 7 3 2 2 2 2 2 1 1 1 . - 12 3 4 1 2 2 2 2 2 2 1 1 1 - 13 6 1 2 3 2 2 2 2 1 1 1 . - 14 1 7 2 16 1 1 . . . . . . - 15 1 4 1 1 1 1 1 1 1 1 1 . - 16 1 2 1 3 1 1 6 1 1 1 1 . - 17 2 7 1 1 11 1 1 1 1 . . . - 18 2 7 1 1 11 1 1 1 1 . . . - 19 1 2 1 3 1 1 6 1 1 1 1 . - 20 1 4 1 1 1 1 1 1 1 1 1 . - 21 1 7 2 16 1 1 . . . . . . - 22 6 1 2 3 2 2 2 2 1 1 1 . - 23 3 4 1 2 2 2 2 2 2 1 1 1 - 24 1 7 3 2 2 2 2 2 1 1 1 . - 25 6 5 2 2 2 2 6 1 1 . . . - 26 3 2 2 2 2 2 2 4 1 1 . . - 27 1 2 2 2 2 2 2 13 1 . . . - 28 1 2 2 2 2 2 2 1 2 . . . - 29 1 2 2 2 2 2 16 . . . . . - 30 3 2 2 2 2 3 . . . . . . - 31 3 2 2 2 2 . . . . . . . - 32 3 2 2 1 . . . . . . . . - 33 3 2 1 . . . . . . . . . - 34 5 . . . . . . . . . . . -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/pbn.mod b/resources/3rdparty/glpk-4.53/examples/pbn/pbn.mod deleted file mode 100644 index f9616f104..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/pbn.mod +++ /dev/null @@ -1,268 +0,0 @@ -/* PBN, Paint-By-Numbers Puzzle */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* NOTE: See also the document "Solving Paint-By-Numbers Puzzles with - GLPK", which is included in the GLPK distribution. */ - -/* A paint-by-numbers puzzle consists of an m*n grid of pixels (the - canvas) together with m+n cluster-size sequences, one for each row - and column. The goal is to paint the canvas with a picture that - satisfies the following constraints: - - 1. Each pixel must be blank or white. - - 2. If a row or column has cluster-size sequence s1, s2, ..., sk, - then it must contain k clusters of black pixels - the first with - s1 black pixels, the second with s2 black pixels, and so on. - - It should be noted that "first" means "leftmost" for rows and - "topmost" for columns, and that rows and columns need not begin or - end with black pixels. - - Example: - 1 1 - 1 1 - 2 1 1 1 1 1 2 3 - 3 2 1 2 1 2 3 4 8 9 - - 3 6 # # # . # # # # # # - 1 4 # . . . . . # # # # - 1 1 3 . . # . # . . # # # - 2 . . . . . . . . # # - 3 3 . . # # # . . # # # - 1 4 # . . . . . # # # # - 2 5 # # . . . # # # # # - 2 5 # # . . . # # # # # - 1 1 . . . # . . . . . # - 3 . . # # # . . . . . - - (In Russia such puzzles are known as "Japanese crosswords".) - - References: - Robert A. Bosch, "Painting by Numbers", 2000. - */ - -/*--------------------------------------------------------------------*/ -/* Main part based on the formulation proposed by Robert Bosch. */ - -param m, integer, >= 1; -/* the number of rows */ - -param n, integer, >= 1; -/* the number of columns */ - -param row{i in 1..m, 1..n div 2}, integer, >= 0, default 0; -/* the cluster-size sequence for row i (raw data) */ - -param col{j in 1..n, 1..m div 2}, integer, >= 0, default 0; -/* the cluster-size sequence for column j (raw data) */ - -param kr{i in 1..m} := sum{t in 1..n div 2: row[i,t] > 0} 1; -/* the number of clusters in row i */ - -param kc{j in 1..n} := sum{t in 1..m div 2: col[j,t] > 0} 1; -/* the number of clusters in column j */ - -param sr{i in 1..m, t in 1..kr[i]} := row[i,t], integer, >= 1; -/* the cluster-size sequence for row i */ - -param sc{j in 1..n, t in 1..kc[j]} := col[j,t], integer, >= 1; -/* the cluster-size sequence for column j */ - -check{i in 1..m}: sum{t in 1..kr[i]} sr[i,t] <= n - (kr[i] - 1); -/* check that the sum of the cluster sizes in each row is valid */ - -check{j in 1..n}: sum{t in 1..kc[j]} sc[j,t] <= m - (kc[j] - 1); -/* check that the sum of the cluster sizes in each column is valid */ - -check: sum{i in 1..m, t in 1..kr[i]} sr[i,t] = - sum{j in 1..n, t in 1..kc[j]} sc[j,t]; -/* check that the sum of the cluster sizes in all rows is equal to the - sum of the cluster sizes in all columns */ - -param er{i in 1..m, t in 1..kr[i]} := - if t = 1 then 1 else er[i,t-1] + sr[i,t-1] + 1; -/* the smallest value of j such that row i's t-th cluster can be - placed in row i with its leftmost pixel occupying pixel j */ - -param lr{i in 1..m, t in 1..kr[i]} := - if t = kr[i] then n + 1 - sr[i,t] else lr[i,t+1] - sr[i,t] - 1; -/* the largest value of j such that row i's t-th cluster can be - placed in row i with its leftmost pixel occupying pixel j */ - -param ec{j in 1..n, t in 1..kc[j]} := - if t = 1 then 1 else ec[j,t-1] + sc[j,t-1] + 1; -/* the smallest value of i such that column j's t-th cluster can be - placed in column j with its topmost pixel occupying pixel i */ - -param lc{j in 1..n, t in 1..kc[j]} := - if t = kc[j] then m + 1 - sc[j,t] else lc[j,t+1] - sc[j,t] - 1; -/* the largest value of i such that column j's t-th cluster can be - placed in column j with its topmost pixel occupying pixel i */ - -var z{i in 1..m, j in 1..n}, binary; -/* z[i,j] = 1, if row i's j-th pixel is painted black - z[i,j] = 0, if row i's j-th pixel is painted white */ - -var y{i in 1..m, t in 1..kr[i], j in er[i,t]..lr[i,t]}, binary; -/* y[i,t,j] = 1, if row i's t-th cluster is placed in row i with its - leftmost pixel occupying pixel j - y[i,t,j] = 0, if not */ - -var x{j in 1..n, t in 1..kc[j], i in ec[j,t]..lc[j,t]}, binary; -/* x[j,t,i] = 1, if column j's t-th cluster is placed in column j with - its topmost pixel occupying pixel i - x[j,t,i] = 0, if not */ - -s.t. fa{i in 1..m, t in 1..kr[i]}: - sum{j in er[i,t]..lr[i,t]} y[i,t,j] = 1; -/* row i's t-th cluster must appear in row i exactly once */ - -s.t. fb{i in 1..m, t in 1..kr[i]-1, j in er[i,t]..lr[i,t]}: - y[i,t,j] <= sum{jp in j+sr[i,t]+1..lr[i,t+1]} y[i,t+1,jp]; -/* row i's (t+1)-th cluster must be placed to the right of its t-th - cluster */ - -s.t. fc{j in 1..n, t in 1..kc[j]}: - sum{i in ec[j,t]..lc[j,t]} x[j,t,i] = 1; -/* column j's t-th cluster must appear in column j exactly once */ - -s.t. fd{j in 1..n, t in 1..kc[j]-1, i in ec[j,t]..lc[j,t]}: - x[j,t,i] <= sum{ip in i+sc[j,t]+1..lc[j,t+1]} x[j,t+1,ip]; -/* column j's (t+1)-th cluster must be placed below its t-th cluster */ - -s.t. fe{i in 1..m, j in 1..n}: - z[i,j] <= sum{t in 1..kr[i], jp in er[i,t]..lr[i,t]: - j-sr[i,t]+1 <= jp and jp <= j} y[i,t,jp]; -/* the double coverage constraint stating that if row i's j-th pixel - is painted black, then at least one of row i's clusters must be - placed in such a way that it covers row i's j-th pixel */ - -s.t. ff{i in 1..m, j in 1..n}: - z[i,j] <= sum{t in 1..kc[j], ip in ec[j,t]..lc[j,t]: - i-sc[j,t]+1 <= ip and ip <= i} x[j,t,ip]; -/* the double coverage constraint making sure that if row i's j-th - pixel is painted black, then at least one of column j's clusters - covers it */ - -s.t. fg{i in 1..m, j in 1..n, t in 1..kr[i], jp in er[i,t]..lr[i,t]: - j-sr[i,t]+1 <= jp and jp <= j}: z[i,j] >= y[i,t,jp]; -/* the constraint to prevent white pixels from being covered by the - row clusters */ - -s.t. fh{i in 1..m, j in 1..n, t in 1..kc[j], ip in ec[j,t]..lc[j,t]: - i-sc[j,t]+1 <= ip and ip <= i}: z[i,j] >= x[j,t,ip]; -/* the constraint to prevent white pixels from being covered by the - column clusters */ - -/* this is a feasibility problem, so no objective is needed */ - -/*--------------------------------------------------------------------*/ -/* The following part is used only to check for multiple solutions. */ - -param zz{i in 1..m, j in 1..n}, binary, default 0; -/* zz[i,j] is z[i,j] for a previously found solution */ - -s.t. fz{1..1 : sum{i in 1..m, j in 1..n} zz[i,j] > 0}: - sum{i in 1..m, j in 1..n} - (if zz[i,j] then (1 - z[i,j]) else z[i,j]) >= 1; -/* the constraint to forbid finding a solution, which is identical to - the previously found one; this constraint is included in the model - only if the previously found solution specified by the parameter zz - is provided in the data section */ - -solve; - -/*--------------------------------------------------------------------*/ -/* Print solution to the standard output. */ - -for {i in 1..m} -{ printf{j in 1..n} " %s", if z[i,j] then "#" else "."; - printf "\n"; -} - -/*--------------------------------------------------------------------*/ -/* Write solution to a text file in PostScript format. */ - -param ps, symbolic, default "solution.ps"; - -printf "%%!PS-Adobe-3.0\n" > ps; -printf "%%%%Creator: GLPK (pbn.mod)\n" >> ps; -printf "%%%%BoundingBox: 0 0 %d %d\n", - 6 * (n + 2), 6 * (m + 2) >> ps; -printf "%%%%EndComments\n" >> ps; -printf "<> setpagedevice\n", - 6 * (n + 2), 6 * (m + 2) >> ps; -printf "0.1 setlinewidth\n" >> ps; -printf "/A { 2 copy 2 copy 2 copy newpath moveto exch 6 add exch line" & - "to\n" >> ps; -printf "exch 6 add exch 6 add lineto 6 add lineto closepath } bind de" & - "f\n" >> ps; -printf "/W { A stroke } def\n" >> ps; -printf "/B { A fill } def\n" >> ps; -printf {i in 1..m, j in 1..n} "%d %d %s\n", - (j - 1) * 6 + 6, (m - i) * 6 + 6, - if z[i,j] then "B" else "W" >> ps; -printf "%%%%EOF\n" >> ps; - -printf "Solution has been written to file %s\n", ps; - -/*--------------------------------------------------------------------*/ -/* Write solution to a text file in the form of MathProg data section, - which can be used later to check for multiple solutions. */ - -param dat, symbolic, default "solution.dat"; - -printf "data;\n" > dat; -printf "\n" >> dat; -printf "param zz :" >> dat; -printf {j in 1..n} " %d", j >> dat; -printf " :=\n" >> dat; -for {i in 1..m} -{ printf " %2d", i >> dat; - printf {j in 1..n} " %s", if z[i,j] then "1" else "." >> dat; - printf "\n" >> dat; -} -printf ";\n" >> dat; -printf "\n" >> dat; -printf "end;\n" >> dat; - -printf "Solution has also been written to file %s\n", dat; - -/*--------------------------------------------------------------------*/ -/* The following data correspond to the example above. */ - -data; - -param m := 10; - -param n := 10; - -param row : 1 2 3 := - 1 3 6 . - 2 1 4 . - 3 1 1 3 - 4 2 . . - 5 3 3 . - 6 1 4 . - 7 2 5 . - 8 2 5 . - 9 1 1 . - 10 3 . . -; - -param col : 1 2 3 4 := - 1 2 3 . . - 2 1 2 . . - 3 1 1 1 1 - 4 1 2 . . - 5 1 1 1 1 - 6 1 2 . . - 7 2 3 . . - 8 3 4 . . - 9 8 . . . - 10 9 . . . -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/pbn.pdf b/resources/3rdparty/glpk-4.53/examples/pbn/pbn.pdf deleted file mode 100644 index 8342189cf63c09063f6184a909e0d4a4379e8c80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43620 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

    sLks zR~J@bAf`?hPGD5fcPwoRtAc*nYe?%RUb=%#aAtov&Tw_bdzMO&ofb`coAEpO%4znfaADqzk6!Lj-T;l0EET?>} z$Lqxe2lt;hLIwk=f`x)mM=ckdTBbluaHRif{k2wskKbouc;WBQZ>X^dQAIDEO#qp2 z5szfv7X2eP*3V=o9`r}!xQ9-xM8eDKO1(=PmrSJu%)Buy18{ltQCutjGM7LrZ%T1+ zqS->;vEIwRiT^ks>y#o7!^u2YIxi{6Y#(_YDf`Ty_mLu;S4566zJnB=!fzQGU*<4M zTL5#8q!BqNzh#!W5&Md_W7Zle_&M+E^cTd*4i zqrXgGTtD|-q(??bjY!=HiyQZ0%xT#xw%{n=m^HE>}Z@h%c`%}sf2vD#a{+!X3 zI7v_pi}#}aHY}XL3(|M&*7rZv_P>vrXM$#b2)G_KgFChgU_u%l_myU$vSgL!6)m}; z)z8H!%K|rzBs(DyI{X&KP*F`e+n~-piYzI?nH`KKJd}#CXMsN-k`vkg1lD`prnl0c z81Rt#2}uJ~pNyN9{227qWNp^p*pHn^qdt^izAlWkZPp*?_?(>hWF9_YRK7c~&aJV&pa91U0m z55BnrfzqsMPyp#EP_a@T!HKx)n(Vb1@rltX%N@K7>`OP%Gg8i^J>=pDt6GT1>4e-V zblaI+g6S(hW8)$Mbg{)LzyE zfS~EO_8F3>P5BX!CfWiRiJw;>AEV>sv;PKlL4LD4N+UZ{?)T z7Vaf*CeKo4N6a^3&36NVzE7HQn zNsUm-g^#Q2gY~#JbTO~qDnDQI6~hYlk>F8Ol_71H|L zn8#=`#&jASfo#zHP_-2hO^4?HkcJ(euAu8rRemYZUP@qmDV57AqxMV0L3`(QPiUT} z7sMnXXr(!1u%coM`!L$Sfl&T=?ty>El97hK4BMt2A!}jvwa)ixXwA`rP4yezJLh3f zu!ibHdq4Tpff&W$Zq#yPEk7La%#1dh4w+J=l5#Alz&2lC#lwEk5j&X7fkP_{=!SW9 zk3usggAG?alJpg?mBY3ysrNd8K?nR6?Lva1RcJMN#?G=o+-^G zzPFz|la{#GkX&dWWg&aHc^?%V&+)h}Juy;gVs>!b7{ttnt__kVd^EPZwmrh2HL{(9JT z1Ny-~rha5yxNy#*A*i}e?!4Q%`1fAJNOa}lE6NISe@uqz-^B4Q-}cA%kRGrf!mFns z-Zg#ofJ67)TzC@%h@|MFj(lZ_ruRNgvdPT3l%phy+rLTmtCR5W0A)aVdQkPB6X>Bc5U&a6)Lk(&WbF}+ly;c#^ zI>`u3x&D|~gz80as=iN^g9)1$mk}1Q<N(3!4efB~${zxfhO2^_gpZ6_wXzs)gU3QW8%uIgvml{46`+4k zDo$Q$YAk1DqUPao>Agsvopkb&hanUCT#d9EXHcGv0O8w`V-rfXxcy=o&kplM%f*wofo+LTf-18N9!c%Ejd z*lTzt995}lF2nd0kuE6)@vH5vDU~W}tRJ?O7XJ0`s>fDgQ_O0FTC+B);Qgi03%YuH zCw%=>UjILw^8Y`VKtt*r8yI()*>cp=Vc~>!5Mk@>T1o+0tBXc+t|a z)kNw$rSuy*@$>7FmpAop((lgi>P=|c7ax4*L>3MT!bM_a?150+vI-6nH6L@oo&5`q z%elIz>TcJF?Dr_dr6g(sy6d!Ww+vbcGNz$+Flr$6rLwc3@h%Id@-qey0zADi5(MIg z2n{)`NussEzNvQ^3p!z~g`UuDI-bk|cMA={fesrfj(Prh><tWKw$g5HlW%#-_0p`)k#%xl=p<5}Fe2JpNv{i^A+8M`L#Og7VG9?50t`FuF#%@4R>@ zU1oJ<(3J>aTBA7y(WnZ?N0YkQR5{y^|JELs9sWpsV!K-3!%c8PLmVs-VtM6ILW@=1 z;OwPlmKk9Z^KiEzY-%19<%_LNJ#j(9U4|*C!kdu*UrV4tn9ba9@2Co>)kyyNyUZp~ zKC-$k3!SCuv#<)s;LsAGZN%8`m?9Q_n@+Q$R)w8mWa+4QhyP3OBD0zu!d!LjcEPq3 zCT0wAoDTOpf=8$uP`PMNSs-8NCM7+#lBCH8vaCoxW-LJrTk{wFB5PKX9f$euI?oUb zJ1r9;N74_DJsqz0*ph&M* zwjNKQgwmrw2BWZ*c=`1#PJ_vfjE;|t@`BlfXiv z6(ONZtkEExg8eWvAhz0Tb|US1s|kWdsNL3RiazgEVmX(-wJOB=mxulwa3SGycibBM()V=?_SvUi;I>bx$ZWIxSnQ z)SIt|YKem{yYEqQC6AMP^}twDDCR;RPfZ8Sy05J`PPw(w1t2-&(>@SUMcIl}y6?P; zbL&vQJrjpzB8;H7;>{2+()io=7+ndX5kgU0n6NcqO1Y=R_AzQgba$v$Q6Ch*^Ql@N z+&)sp8e12$6&X3G>aGe_E64MVxbFD+pn_ zvB`GBaRcyq+UH!s9fFC&K!m~h_*)K+x_B}aTaJ{5mx=Gz6414YM!#Not z{IFhmoVx2r*aFWK`q5B`J@FFWOoAAtF3cDH60n=!`h~{EiTK_<%9Jl)vw^!T} zQBu1RVn7v0(kO$-?NUq&p76hxBrVZRE1));AW5Gzg_~A$5o?KojAq==QIJ!PL?<4w z`OJyxv5os}w#avjj8rOj56%%TSCecK74<^#_%$|>uY{0Q6aZLujusStxy>U zKZ@{H@5dOSHou$sX%?1zZnMQT&3`#Hfl~(puYKgl9)10C#6H7X7@` z(p3_Og%IrJZXqjaiu;fUDD#HW-wfi!DjrKQLz~)U7_dE|v^~LHJ$WI1={Yf7^0W!lO1*s>*G*f@1T*LR(KeyY8i@z1PWLnU&u=mDg>4ea}KRg6pI~s(j zBR@(ZTs#=iuVJ-0pNx6dJoyJ!AFVCcDDFTyDs+d?@IsODsuHuLP+Mair@ zY!)s=Fkc87re3arXxOe)@dJ)7rZ>8`P9K*}3~6*UH`Rb9G=6I2_#>6atj!JSDc)If zL2hzhMlGigXkLKXE{&N8*?4MErPZ<0FV8Gjvg=T-<`EbB1zP7!6 zgIQ}Pb###V7E_Z2xxm1NI7fC?N8(Dhkqh9`>IcyA*faA;6}UXB`{-StJn5D*I@(mU z=*AS_mJ97e-xY;;DiK=iLaLz&xO>y=XB40w59=$l05&5=yy7Fo&hiUv#TUwlo?&c$ zgv<9v@*`AJkos@Bd=~0{qJ%DXz>5FfUgNY|V0KMv)lc+GzMr+FHRkJR+nRwK-p-Up z-wE%yc~%uX&dvFmDLZP$JUw4inLMt^(AFts(Ym~_l10lupC2J|l)(1H+f6-NwA3nH zanMFS-bdVx%TnM{lfRFH;jDh#NyBL!yvA>xhyD3y*HP7eEXnf;7FmAh2)jv&>g1H) z`_a6b*Mlh(nPSoz&QYlTMA(scgqvGp%EG+vn_{>A7DKH9n4GH}%LvjagYCc+_!^b* zHMTXz2E+lYa;e?Zmw4L#M4%}4Tq>k(k{@evWI@b*J?5%c^FX0QKqbOE;o|@>c>YF$ z@x_tmR)l2BKhY1LDE?@k9KcQLw=wVbF|^n$8Vu+qufqFAWZfd~vD5!>hocwAa9kEc z3Os#@i{aH^p++UVo0y}uu=(og^q7ya zS4Ui}zUFs$=99aXJOkaj)6%|%ZMEx7605jjbah}>u8OH7y>gYf9y z9qA6?EO8F0bh7zOXoIxW{R~h)-B~y+V7?@B+>J!?UR7P93s5M#)*q9sXPo%teISI~ z8t7>FqAFt5qM~38ny{v~cn%s(G~Ti1th*i&ee*^V z2CTI|jexo2^L`pJIft7t=aV34R~zuieIPoeQi`7xdSBjpkshV63&mc1yf2+}%he50 zxFv@3vIr3hK&(q-!{T{7P)d_Mk1#dsG2s9lY z!CID}Ko3wMm_|+BHim9iam|HoEkvWm;Df?p79Y8A-qH7lO%WY8MXyjioV6>6xu9s> zxigZwRqSOzd5Ianlv~$@~(7 zc<`y9e~&|)3eF4L=w^QV!3Q}lspX<)qnEWtfGSJ2Os~H9>d!Ev*6x}YP9NMyDH*Q# z=o5>d&^tTPaNp2$nxahT$MlW7zC~sq?~Lf^`tgTPqScU( z?ZKwm?`+vG7`Ar*#Q%c@`~P_{W#jno7A*ZA_!i58FdyJ)1q(eeUT!m4g-tBU9;S@U zfsM_uM`NlZHfYh-&s=xrsv89+>6H;1hHC<7J1#WXS3?L0j(KvWLRi+Xu((Z^Dt*km z%Dd|PyqTnc&Ql8Xb=5D~E!H0mHT2?Pd^>}x; zWo2;CBTp_5h(SnPq&ktP1Jc>O?Dk9UTO1rT+{r3eh>nMoS9^}I`A5D55V)j*R*GYy zG;Qaw@3e=kIcyWPjb=~WWBW1Gaet{5YBT8+&kWj{Vg-+BSd4L56!+<;7pp#pQ!`)} zak7vYE>~bI>cz83?)-|;D5Z*SUSp;)py`ncLr3R=pTiOpKOS%`LsO5o8E`j+=|yAz z52y97sRD&H(<{Ryx_Q8-FZP%0AC8O*BPVKd0LQcjSrmh7K!76nm@;p4kL%9f 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 bxw!*e-Mw5bED<=^S$S9y{xQFlr4arX?90%$ diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/pbn.tex b/resources/3rdparty/glpk-4.53/examples/pbn/pbn.tex deleted file mode 100644 index c73a441b0..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/pbn.tex +++ /dev/null @@ -1,279 +0,0 @@ -%* pbn.tex *% - -\documentclass[11pt,draft]{article} -\usepackage{amssymb} - -\begin{document} - -\title{Solving Paint-By-Numbers Puzzles with GLPK} - -\author{Andrew Makhorin {\tt}} - -\date{August 2011} - -\maketitle - -\section{Introduction$^1$} - -\footnotetext[1]{This section is based on the material from [1].} - -A {\it paint-by-numbers} puzzle consists of an $m\times n$ grid of -pixels (the {\it canvas}) together with $m+n$ {\it cluster-size -sequences}, one for each row and column. The goal is to paint the canvas -with a picture that satisfies the following constraints: - -1. Each pixel must be blank or white. - -2. If a row or column has cluster-size sequence $s_1$, $s_2$, \dots, -$s_k$, then it must contain $k$ clusters of black pixels---the first -with $s_1$ black pixels, the second with $s_2$ black pixels, and so on. - -It should be noted that ``first'' means ``leftmost'' for rows and -``topmost'' for columns, and that rows and columns need not begin or end -with black pixels. - -\subsubsection*{Example} - -\def\arraystretch{.8} - -\begin{center} -\begin{tabular}{*{3}{@{$\;\;$}c}c*{10}{@{\ }c}@{}} - & & && & &1& &1& & & & & \\ - & & && & &1& &1& & & & & \\ - & & &&2&1&1&1&1&1&2&3& & \\ - & & &&3&2&1&2&1&2&3&4&8&9\\ -\\ - &3&6&&$\blacksquare$&$\blacksquare$&$\blacksquare$&$\square$& -$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$& -$\blacksquare$&$\blacksquare$\\ - &1&4&&$\blacksquare$&$\square$&$\square$&$\square$&$\square$& -$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$\\ -1&1&3&&$\square$&$\square$&$\blacksquare$&$\square$&$\blacksquare$& -$\square$&$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$\\ - & &2&&$\square$&$\square$&$\square$&$\square$&$\square$&$\square$& -$\square$&$\square$&$\blacksquare$&$\blacksquare$\\ - &3&3&&$\square$&$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$& -$\square$&$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$\\ - &1&4&&$\blacksquare$&$\square$&$\square$&$\square$&$\square$&$\square$& -$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$\\ - &2&5&&$\blacksquare$&$\blacksquare$&$\square$&$\square$&$\square$& -$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$& -$\blacksquare$\\ - &2&5&&$\blacksquare$&$\blacksquare$&$\square$&$\square$&$\square$& -$\blacksquare$&$\blacksquare$&$\blacksquare$&$\blacksquare$& -$\blacksquare$\\ - &1&1&&$\square$&$\square$&$\square$&$\blacksquare$&$\square$&$\square$& -$\square$&$\square$&$\square$&$\blacksquare$\\ - & &3&&$\square$&$\square$&$\blacksquare$&$\blacksquare$&$\blacksquare$& -$\square$&$\square$&$\square$&$\square$&$\square$\\ -\end{tabular} -\end{center} - -\def\arraystretch{1} - -\section{Solving a puzzle} - -The Paint-By-Numbers puzzle can be formulated as a 0-1 integer -feasibility problem. The formulation used in GLPK was proposed in [1]. - -For solving puzzles there are used two components, which both are -coded in the GNU MathProg modeling language [2]: the model section and -the data section. The model section is common for all puzzles and -placed in file \verb|pbn.mod|. This file is included in the GLPK -distribution and can be found in subdirectory \verb|examples/pbn|. - -To solve a particular puzzle the user only needs to prepare the data -section, which defines input data to the puzzle. The data section for -the example puzzle from the previous section may look like follows -(here \verb|m| is the number of rows, and \verb|n| is the number of -columns): - -\begin{footnotesize} -\begin{verbatim} -data; - -param m := 10; - -param n := 10; - -param row : 1 2 3 := - 1 3 6 . - 2 1 4 . - 3 1 1 3 - 4 2 . . - 5 3 3 . - 6 1 4 . - 7 2 5 . - 8 2 5 . - 9 1 1 . - 10 3 . . -; - -param col : 1 2 3 4 := - 1 2 3 . . - 2 1 2 . . - 3 1 1 1 1 - 4 1 2 . . - 5 1 1 1 1 - 6 1 2 . . - 7 2 3 . . - 8 3 4 . . - 9 8 . . . - 10 9 . . . -; - -end; -\end{verbatim} -\end{footnotesize} - -\newpage - -Let the data section for a puzzle be placed in file \verb|foo.dat|. -Then to solve the puzzle the user should enter the following command: - -\begin{verbatim} - glpsol --minisat -m pbn.mod -d foo.dat -\end{verbatim} - -\noindent -This command invokes \verb|glpsol|, the GLPK LP/MIP stand-alone solver, -which reads the model section from file \verb|pbn.mod|, the data section -from file \verb|foo.dat|, translates them to an internal representation, -and solves the resulting 0-1 integer feasibility problem. The option -\verb|--minisat| tells \verb|glpsol| to translate the feasibility -problem to a CNF satisfiability problem and then use the MiniSat solver -[3] to solve it. - -If a solution to the puzzle has been found, that is indicated by the -message \verb|SATISFIABLE|, \verb|glpsol| prints the solution to the -standard output (terminal), writes it to file \verb|solution.ps| in the -PostScript format, and also writes it to file \verb|solution.dat| in the -form of MathProg data section, which can be used later to check for -multiple solutions, if necessary (for details see the next section). -The message \verb|UNSATISFIABLE| means that the puzzle has no solution. - -Usually the time taken to solve a puzzle of moderate size (up to 50 rows -and columns) varies from several seconds to several minutes. However, -hard or large puzzles may require much more time. - -Data sections for some example puzzles included in the GLPK distribution -can be found in subdirectory \verb|examples/pbn|. - -\section{Checking for multiple solutions} - -Sometimes the user may be interested to know if the puzzle has exactly -one (unique) solution or it has multiple solutions. To check that the -user should solve the puzzle as explained above in the previous section -and then enter the following command: - -\begin{verbatim} - glpsol --minisat -m pbn.mod -d foo.dat -d solution.dat -\end{verbatim} - -\noindent -In this case \verb|glpsol| reads an additional data section from file -\verb|solution.dat|, which contains the previously found solution, -activates an additional constraint in the model section to forbid -finding the solution specified in the additional data section, and -attempts to find another solution. The message \verb|UNSATISFIABLE| -reported by \verb|glpsol| will mean that the puzzle has a unique -solution, while the message \verb|SATISFIABLE| will mean that the puzzle -has at least two different solutions. - -\newpage - -\section{Solution times} - -The table on the next page shows solution times on a sample set of -the paint-by-numbers puzzles from the \verb|| website. -This sample set was used in the survey [4] to compare efficiency of -existing PBN solvers. - -The authors of some puzzles from the sample set have given permission -for their puzzles to be freely redistributed as long as the original -attribution and copyright statement are retained. In the table these -puzzles are marked by an asterisk (*). The files containing the -MathProg data sections for these puzzles are included in the GLPK -distribution and can be found in subdirectory \verb|examples/pbn|. - -All runs were performed on Intel Pentium 4 (CPU 3GHz, 2GB of RAM). -The C compiler used was GCC 3.4.4 with default optimization options. - -The column `Sol.Time' shows the time, in seconds, taken by the -\verb|glpsol| solver to find a solution to corresponding puzzle. The -column `Chk.Time' shows the time, in seconds, taken by \verb|glpsol| to -check for multiple solutions, i.e. either to prove that the puzzle has -a unique solution or find another solution to the puzzle. Both these -times do not include the time used to translate the MathProg model and -data sections into an internal MIP representation, but include the time -used to translate the 0-1 feasibility problem to a CNF satisfiability -problem. - -\begin{thebibliography}{10} - -\bibitem{1} -Robert A. Bosch, ``Painting by Numbers'', 2000.\\ -\verb||. - -\bibitem{2} -GLPK: Modeling Language GNU MathProg. Language Reference. (This -document is included in the GLPK distribution and can be found in -subdirectory \verb|doc|.) - -\bibitem{3} -Niklas E\'en, Niklas S\"orensson, ``An Extensible SAT-solver'', -Chalmers University of Technology, Sweden. \verb||. - -\bibitem{4} -Jan Wolter, ``Survey of Paint-by-Number Puzzle Solvers''.\\ -\verb||. - -\end{thebibliography} - -\newpage - -\begin{table} -\caption{Solution times on the sample set of puzzles from [4]} -\begin{center} -\begin{tabular}{@{}lllcrr@{}} -\hline -\multicolumn{2}{c}{Puzzle}&Size&Notes&Sol.Time, s&Chk.Time, s\\ -\hline -\#1&Dancer* &$10\times 5$&L&$<1$&$<1$\\ -\#6&Cat* &$20\times 20$&L&$<1$&$<1$\\ -\#21&Skid* &$25\times 14$&L, B&$<1$&$<1$\\ -\#27&Bucks* &$23\times 27$&B&$<1$&$<1$\\ -\#23&Edge* &$11\times 10$&&$<1$&$<1$\\ -\#2413&Smoke &$20\times 20$&&$<1$&$<1$\\ -\#16&Knot* &$34\times 34$&L&1&1\\ -\#529&Swing* &$45\times 45$&L&1&1\\ -\#65&Mum* &$40\times 34$&&1&1\\ -\#7604&DiCap &$55\times 55$&&10&10\\ -\#1694&Tragic &$50\times 45$&&3&3\\ -\#1611&Merka &$60\times 55$&B&4&4\\ -\#436&Petro* &$35\times 40$&&1&1\\ -\#4645&M\&M &$70\times 50$&B&5&6\\ -\#3541&Signed &$50\times 60$&&7&7\\ -\#803&Light* &$45\times 50$&B&1&1\\ -\#6574&Forever*&$25\times 25$&&1&1\\ -\#2040&Hot &$60\times 55$&&6&6\\ -\#6739&Karate &$40\times 40$&M&2&2\\ -\#8098&9-Dom* &$19\times 19$&&1&2\\ -\#2556&Flag &$45\times 65$&M, B&2&2\\ -\#2712&Lion &$47\times 47$&M&11&12\\ -\#10088&Marley &$63\times 52$&M&135&226\\ -\#9892&Nature &$40\times 50$&M&850&1053\\ -\hline -\end{tabular} - -\begin{tabular}{@{}lp{102mm}@{}} -*&Puzzle designer has given permission to redistribute the puzzle.\\ -L&Puzzle is line solvable. That is, it can be solved one line at a -time.\\ -B&Puzzle contains blank rows or columns.\\ -M&Puzzle has multiple solutions.\\ -\end{tabular} -\end{center} -\end{table} - -\end{document} diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/petro.dat b/resources/3rdparty/glpk-4.53/examples/pbn/petro.dat deleted file mode 100644 index 15ccc4a16..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/petro.dat +++ /dev/null @@ -1,102 +0,0 @@ -/* petro.dat */ - -/*********************************************************************** -* Web Paint-by-Number Puzzle #436 from . -* Copyright (C) 2006 by Jan Wolter. Used by permission. -* -* Old Stone Face -* -* created by Jan Wolter -* Jun 17, 2006 -* -* Encoded in GNU MathProg by Andrew Makhorin . -***********************************************************************/ - -data; - -param m := 35; - -param n := 40; - -param row : 1 2 3 4 5 6 7 8 9 := - 1 2 2 . . . . . . . - 2 2 3 2 . . . . . . - 3 3 3 3 2 . . . . . - 4 3 3 3 3 . . . . . - 5 2 3 3 3 3 2 . . . - 6 3 3 3 3 3 3 . . . - 7 4 2 3 2 2 4 . . . - 8 4 2 2 2 2 3 1 . . - 9 3 1 2 2 2 3 3 . . - 10 3 2 2 2 2 2 4 . . - 11 3 2 15 2 4 . . . . - 12 5 19 4 . . . . . . - 13 6 4 3 3 . . . . . - 14 6 4 4 . . . . . . - 15 2 4 6 2 . . . . . - 16 2 2 3 3 3 2 . . . - 17 9 2 2 2 3 9 . . . - 18 10 2 2 2 2 2 10 . . - 19 4 2 3 3 2 2 3 2 5 - 20 2 5 2 4 2 . . . . - 21 5 3 2 2 5 . . . . - 22 6 3 2 3 7 . . . . - 23 6 8 9 7 . . . . . - 24 4 8 7 5 . . . . . - 25 4 . . . . . . . . - 26 2 . . . . . . . . - 27 2 . . . . . . . . - 28 14 . . . . . . . . - 29 16 . . . . . . . . - 30 3 3 . . . . . . . - 31 2 2 . . . . . . . - 32 2 2 . . . . . . . - 33 4 4 . . . . . . . - 34 16 . . . . . . . . - 35 12 . . . . . . . . -; - -param col : 1 2 3 4 5 6 7 := - 1 1 . . . . . . - 2 3 2 . . . . . - 3 2 3 3 . . . . - 4 3 3 3 . . . . - 5 3 3 3 3 . . . - 6 4 2 2 2 . . . - 7 3 3 2 3 . . . - 8 3 2 2 2 . . . - 9 3 2 6 . . . . - 10 2 9 . . . . . - 11 2 3 3 . . . . - 12 4 4 3 2 4 . . - 13 7 2 5 2 6 . . - 14 12 2 3 2 3 2 . - 15 3 1 2 2 2 3 . - 16 2 2 3 2 2 2 . - 17 6 2 6 2 2 2 . - 18 12 4 3 2 2 . . - 19 12 2 2 2 . . . - 20 2 6 2 . . . . - 21 2 6 5 2 . . . - 22 10 9 2 2 . . . - 23 12 3 3 2 2 . . - 24 6 2 2 2 2 2 2 - 25 2 2 3 2 2 2 . - 26 4 3 2 2 2 3 . - 27 7 3 3 2 3 2 . - 28 5 3 5 2 6 . . - 29 4 3 3 3 4 . . - 30 3 5 3 . . . . - 31 3 9 . . . . . - 32 4 2 6 . . . . - 33 4 2 2 2 . . . - 34 4 2 2 3 . . . - 35 3 2 2 3 . . . - 36 3 3 3 . . . . - 37 3 3 3 . . . . - 38 4 3 3 . . . . - 39 2 3 3 . . . . - 40 2 1 . . . . . -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/skid.dat b/resources/3rdparty/glpk-4.53/examples/pbn/skid.dat deleted file mode 100644 index 865c73b37..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/skid.dat +++ /dev/null @@ -1,66 +0,0 @@ -/* skid.dat */ - -/*********************************************************************** -* Web Paint-by-Number Puzzle #21 from . -* Copyright (C) 2004 by Jan Wolter. Used by permission. -* -* Slippery Conditions -* -* created by Jan Wolter -* Apr 4, 2004 -* -* Encoded in GNU MathProg by Andrew Makhorin . -***********************************************************************/ - -data; - -param m := 25; - -param n := 14; - -param row : 1 2 3 := - 1 9 . . - 2 1 1 . - 3 1 1 1 - 4 1 3 1 - 5 13 . . - 6 13 . . - 7 13 . . - 8 13 . . - 9 2 2 . - 10 2 2 . - 11 . . . - 12 2 2 . - 13 2 2 . - 14 2 2 . - 15 2 2 . - 16 2 2 . - 17 2 2 . - 18 2 2 . - 19 2 2 . - 20 2 2 . - 21 2 2 . - 22 2 2 . - 23 2 2 . - 24 2 2 . - 25 2 2 . -; - -param col : 1 2 3 4 5 := - 1 2 . . . . - 2 4 6 . . . - 3 9 4 4 2 . - 4 1 6 2 6 . - 5 1 5 2 . . - 6 1 6 . . . - 7 1 5 . . . - 8 1 4 . . . - 9 1 4 . . . - 10 1 4 2 . . - 11 1 4 6 . . - 12 1 6 4 4 2 - 13 9 2 6 . . - 14 4 2 . . . -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/pbn/swing.dat b/resources/3rdparty/glpk-4.53/examples/pbn/swing.dat deleted file mode 100644 index 547e0dbd8..000000000 --- a/resources/3rdparty/glpk-4.53/examples/pbn/swing.dat +++ /dev/null @@ -1,117 +0,0 @@ -/* swing.dat */ - -/*********************************************************************** -* Web Paint-by-Number Puzzle #529 from . -* Copyright (C) 2006 by Jan Wolter. Used by permission. -* -* Swing -* -* created by Jan Wolter -* Sep 28, 2006 -* -* Encoded in GNU MathProg by Andrew Makhorin . -***********************************************************************/ - -data; - -param m := 45; - -param n := 45; - -param row : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 := - 1 7 1 1 1 1 1 . . . . . . . . - 2 3 1 3 1 4 1 4 1 5 1 5 1 2 . - 3 1 1 1 3 1 4 1 4 1 5 1 5 1 2 - 4 2 1 2 1 1 1 1 6 2 . . . . . - 5 3 30 1 5 . . . . . . . . . . - 6 1 5 8 1 1 7 1 1 3 . . . . . - 7 3 4 8 1 5 1 2 . . . . . . . - 8 3 20 6 6 . . . . . . . . . . - 9 3 3 7 2 5 1 . . . . . . . . - 10 3 3 1 1 9 1 1 5 6 . . . . . - 11 2 3 8 1 3 4 2 . . . . . . . - 12 5 3 1 10 4 5 2 . . . . . . . - 13 1 2 3 8 4 6 . . . . . . . . - 14 2 2 3 11 10 . . . . . . . . . - 15 2 2 3 10 7 . . . . . . . . . - 16 2 3 1 7 12 2 . . . . . . . . - 17 2 3 1 4 11 2 . . . . . . . . - 18 4 1 2 1 11 2 . . . . . . . . - 19 9 1 2 9 . . . . . . . . . . - 20 6 2 1 4 11 . . . . . . . . . - 21 2 5 1 2 6 6 . . . . . . . . - 22 6 2 4 8 4 . . . . . . . . . - 23 4 2 16 1 . . . . . . . . . . - 24 2 2 15 2 . . . . . . . . . . - 25 3 2 15 4 . . . . . . . . . . - 26 3 3 13 4 . . . . . . . . . . - 27 4 12 9 . . . . . . . . . . . - 28 1 9 10 . . . . . . . . . . . - 29 2 1 17 7 2 . . . . . . . . . - 30 2 2 8 3 8 2 . . . . . . . . - 31 2 3 6 3 8 2 . . . . . . . . - 32 2 4 5 4 7 2 . . . . . . . . - 33 2 5 5 4 6 . . . . . . . . . - 34 4 4 5 4 9 . . . . . . . . . - 35 1 4 6 4 4 . . . . . . . . . - 36 4 3 6 4 3 2 . . . . . . . . - 37 2 1 2 7 4 4 2 . . . . . . . - 38 2 2 2 9 5 5 2 . . . . . . . - 39 2 2 2 10 6 6 . . . . . . . . - 40 3 2 1 9 18 . . . . . . . . . - 41 8 4 23 . . . . . . . . . . . - 42 1 2 1 2 2 1 1 1 2 . . . . . - 43 2 1 4 2 1 4 1 5 1 3 1 2 . . - 44 2 1 5 4 4 1 5 1 3 1 2 . . . - 45 1 10 1 1 1 . . . . . . . . . -; - -param col : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 := - 1 7 1 1 1 1 1 . . . . . . . . - 2 2 2 4 1 4 1 5 1 4 1 4 1 2 . - 3 3 1 4 1 4 1 14 4 1 2 . . . . - 4 1 1 5 1 2 3 4 1 . . . . . . - 5 3 13 1 10 . . . . . . . . . . - 6 1 9 4 . . . . . . . . . . . - 7 6 7 2 2 . . . . . . . . . . - 8 8 4 1 4 . . . . . . . . . . - 9 2 8 3 2 5 3 . . . . . . . . - 10 10 1 3 7 2 . . . . . . . . . - 11 8 6 2 8 1 2 . . . . . . . . - 12 1 1 2 2 8 1 1 . . . . . . . - 13 2 1 1 1 2 1 3 1 3 3 1 . . . - 14 2 1 1 1 5 4 2 1 . . . . . . - 15 2 1 1 1 1 7 2 1 . . . . . . - 16 2 1 1 2 9 1 2 1 . . . . . . - 17 4 6 12 1 3 . . . . . . . . . - 18 16 13 3 2 . . . . . . . . . . - 19 12 21 2 . . . . . . . . . . . - 20 2 13 23 . . . . . . . . . . . - 21 2 14 19 . . . . . . . . . . . - 22 2 14 20 2 . . . . . . . . . . - 23 2 13 7 2 8 2 . . . . . . . . - 24 12 8 1 7 2 . . . . . . . . . - 25 5 1 1 1 2 8 1 5 2 . . . . . - 26 2 1 1 1 9 1 1 4 . . . . . . - 27 2 1 1 1 6 1 3 5 . . . . . . - 28 2 2 1 5 6 2 . . . . . . . . - 29 2 1 3 1 3 7 3 2 . . . . . . - 30 2 3 2 1 1 2 4 4 2 . . . . . - 31 2 2 1 1 2 3 1 8 2 . . . . . - 32 9 3 1 7 2 . . . . . . . . . - 33 12 4 1 6 2 . . . . . . . . . - 34 7 4 1 2 5 . . . . . . . . . - 35 2 6 6 5 6 . . . . . . . . . - 36 8 8 6 3 . . . . . . . . . . - 37 3 10 8 4 2 . . . . . . . . . - 38 5 11 9 5 2 . . . . . . . . . - 39 3 1 12 16 2 . . . . . . . . . - 40 3 1 12 16 . . . . . . . . . . - 41 5 2 13 21 . . . . . . . . . . - 42 6 1 3 3 1 1 . . . . . . . . - 43 5 1 3 1 3 1 1 2 1 4 1 3 1 3 - 44 5 1 3 1 3 1 4 1 4 1 3 1 3 . - 45 1 1 1 1 1 1 . . . . . . . . -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/plan.lp b/resources/3rdparty/glpk-4.53/examples/plan.lp deleted file mode 100644 index cab649449..000000000 --- a/resources/3rdparty/glpk-4.53/examples/plan.lp +++ /dev/null @@ -1,39 +0,0 @@ -\* plan.lp *\ - -Minimize - value: .03 bin1 + .08 bin2 + .17 bin3 + .12 bin4 + .15 bin5 + - .21 alum + .38 silicon - -Subject To - yield: bin1 + bin2 + bin3 + bin4 + bin5 + - alum + silicon = 2000 - - fe: .15 bin1 + .04 bin2 + .02 bin3 + .04 bin4 + .02 bin5 + - .01 alum + .03 silicon <= 60 - - cu: .03 bin1 + .05 bin2 + .08 bin3 + .02 bin4 + .06 bin5 + - .01 alum <= 100 - - mn: .02 bin1 + .04 bin2 + .01 bin3 + .02 bin4 + .02 bin5 <= 40 - - mg: .02 bin1 + .03 bin2 + .01 bin5 <= 30 - - al: .70 bin1 + .75 bin2 + .80 bin3 + .75 bin4 + .80 bin5 + - .97 alum >= 1500 - - si1: .02 bin1 + .06 bin2 + .08 bin3 + .12 bin4 + .02 bin5 + - .01 alum + .97 silicon >= 250 - - si2: .02 bin1 + .06 bin2 + .08 bin3 + .12 bin4 + .02 bin5 + - .01 alum + .97 silicon <= 300 - -Bounds - bin1 <= 200 - bin2 <= 2500 - 400 <= bin3 <= 800 - 100 <= bin4 <= 700 - bin5 <= 1500 - -End - -\* eof *\ diff --git a/resources/3rdparty/glpk-4.53/examples/plan.mod b/resources/3rdparty/glpk-4.53/examples/plan.mod deleted file mode 100644 index effe8383c..000000000 --- a/resources/3rdparty/glpk-4.53/examples/plan.mod +++ /dev/null @@ -1,39 +0,0 @@ -/* plan.mod */ - -var bin1, >= 0, <= 200; -var bin2, >= 0, <= 2500; -var bin3, >= 400, <= 800; -var bin4, >= 100, <= 700; -var bin5, >= 0, <= 1500; -var alum, >= 0; -var silicon, >= 0; - -minimize - -value: .03 * bin1 + .08 * bin2 + .17 * bin3 + .12 * bin4 + .15 * bin5 + - .21 * alum + .38 * silicon; - -subject to - -yield: bin1 + bin2 + bin3 + bin4 + bin5 + alum + silicon = 2000; - -fe: .15 * bin1 + .04 * bin2 + .02 * bin3 + .04 * bin4 + .02 * bin5 + - .01 * alum + .03 * silicon <= 60; - -cu: .03 * bin1 + .05 * bin2 + .08 * bin3 + .02 * bin4 + .06 * bin5 + - .01 * alum <= 100; - -mn: .02 * bin1 + .04 * bin2 + .01 * bin3 + .02 * bin4 + .02 * bin5 - <= 40; - -mg: .02 * bin1 + .03 * bin2 + .01 * bin5 <= 30; - -al: .70 * bin1 + .75 * bin2 + .80 * bin3 + .75 * bin4 + .80 * bin5 + - .97 * alum >= 1500; - -si: 250 <= .02 * bin1 + .06 * bin2 + .08 * bin3 + .12 * bin4 + - .02 * bin5 + .01 * alum + .97 * silicon <= 300; - -end; - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/examples/plan.mps b/resources/3rdparty/glpk-4.53/examples/plan.mps deleted file mode 100644 index b6bb09458..000000000 --- a/resources/3rdparty/glpk-4.53/examples/plan.mps +++ /dev/null @@ -1,54 +0,0 @@ -*000000001111111111222222222233333333334444444444555555555566 -*234567890123456789012345678901234567890123456789012345678901 -NAME PLAN -ROWS - N VALUE - E YIELD - L FE - L CU - L MN - L MG - G AL - L SI -COLUMNS - BIN1 VALUE .03000 YIELD 1.00000 - FE .15000 CU .03000 - MN .02000 MG .02000 - AL .70000 SI .02000 - BIN2 VALUE .08000 YIELD 1.00000 - FE .04000 CU .05000 - MN .04000 MG .03000 - AL .75000 SI .06000 - BIN3 VALUE .17000 YIELD 1.00000 - FE .02000 CU .08000 - MN .01000 AL .80000 - SI .08000 - BIN4 VALUE .12000 YIELD 1.00000 - FE .04000 CU .02000 - MN .02000 AL .75000 - SI .12000 - BIN5 VALUE .15000 YIELD 1.00000 - FE .02000 CU .06000 - MN .02000 MG .01000 - AL .80000 SI .02000 - ALUM VALUE .21000 YIELD 1.00000 - FE .01000 CU .01000 - AL .97000 SI .01000 - SILICON VALUE .38000 YIELD 1.00000 - FE .03000 SI .97000 -RHS - RHS1 YIELD 2000.00000 FE 60.00000 - CU 100.00000 MN 40.00000 - SI 300.00000 - MG 30.00000 AL 1500.00000 -RANGES - RNG1 SI 50.00000 -BOUNDS - UP BND1 BIN1 200.00000 - UP BIN2 2500.00000 - LO BIN3 400.00000 - UP BIN3 800.00000 - LO BIN4 100.00000 - UP BIN4 700.00000 - UP BIN5 1500.00000 -ENDATA diff --git a/resources/3rdparty/glpk-4.53/examples/prod.mod b/resources/3rdparty/glpk-4.53/examples/prod.mod deleted file mode 100644 index aa793f76e..000000000 --- a/resources/3rdparty/glpk-4.53/examples/prod.mod +++ /dev/null @@ -1,331 +0,0 @@ -# PROD, a multiperiod production model -# -# References: -# Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language -# for Mathematical Programming." Management Science 36 (1990) 519-554. - -### PRODUCTION SETS AND PARAMETERS ### - -set prd 'products'; # Members of the product group - -param pt 'production time' {prd} > 0; - - # Crew-hours to produce 1000 units - -param pc 'production cost' {prd} > 0; - - # Nominal production cost per 1000, used - # to compute inventory and shortage costs - -### TIME PERIOD SETS AND PARAMETERS ### - -param first > 0 integer; - # Index of first production period to be modeled - -param last > first integer; - - # Index of last production period to be modeled - -set time 'planning horizon' := first..last; - -### EMPLOYMENT PARAMETERS ### - -param cs 'crew size' > 0 integer; - - # Workers per crew - -param sl 'shift length' > 0; - - # Regular-time hours per shift - -param rtr 'regular time rate' > 0; - - # Wage per hour for regular-time labor - -param otr 'overtime rate' > rtr; - - # Wage per hour for overtime labor - -param iw 'initial workforce' >= 0 integer; - - # Crews employed at start of first period - -param dpp 'days per period' {time} > 0; - - # Regular working days in a production period - -param ol 'overtime limit' {time} >= 0; - - # Maximum crew-hours of overtime in a period - -param cmin 'crew minimum' {time} >= 0; - - # Lower limit on average employment in a period - -param cmax 'crew maximum' {t in time} >= cmin[t]; - - # Upper limit on average employment in a period - -param hc 'hiring cost' {time} >= 0; - - # Penalty cost of hiring a crew - -param lc 'layoff cost' {time} >= 0; - - # Penalty cost of laying off a crew - -### DEMAND PARAMETERS ### - -param dem 'demand' {prd,first..last+1} >= 0; - - # Requirements (in 1000s) - # to be met from current production and inventory - -param pro 'promoted' {prd,first..last+1} logical; - - # true if product will be the subject - # of a special promotion in the period - -### INVENTORY AND SHORTAGE PARAMETERS ### - -param rir 'regular inventory ratio' >= 0; - - # Proportion of non-promoted demand - # that must be in inventory the previous period - -param pir 'promotional inventory ratio' >= 0; - - # Proportion of promoted demand - # that must be in inventory the previous period - -param life 'inventory lifetime' > 0 integer; - - # Upper limit on number of periods that - # any product may sit in inventory - -param cri 'inventory cost ratio' {prd} > 0; - - # Inventory cost per 1000 units is - # cri times nominal production cost - -param crs 'shortage cost ratio' {prd} > 0; - - # Shortage cost per 1000 units is - # crs times nominal production cost - -param iinv 'initial inventory' {prd} >= 0; - - # Inventory at start of first period; age unknown - -param iil 'initial inventory left' {p in prd, t in time} - := iinv[p] less sum {v in first..t} dem[p,v]; - - # Initial inventory still available for allocation - # at end of period t - -param minv 'minimum inventory' {p in prd, t in time} - := dem[p,t+1] * (if pro[p,t+1] then pir else rir); - - # Lower limit on inventory at end of period t - -### VARIABLES ### - -var Crews{first-1..last} >= 0; - - # Average number of crews employed in each period - -var Hire{time} >= 0; # Crews hired from previous to current period - -var Layoff{time} >= 0; # Crews laid off from previous to current period - -var Rprd 'regular production' {prd,time} >= 0; - - # Production using regular-time labor, in 1000s - -var Oprd 'overtime production' {prd,time} >= 0; - - # Production using overtime labor, in 1000s - -var Inv 'inventory' {prd,time,1..life} >= 0; - - # Inv[p,t,a] is the amount of product p that is - # a periods old -- produced in period (t+1)-a -- - # and still in storage at the end of period t - -var Short 'shortage' {prd,time} >= 0; - - # Accumulated unsatisfied demand at the end of period t - -### OBJECTIVE ### - -minimize cost: - - sum {t in time} rtr * sl * dpp[t] * cs * Crews[t] + - sum {t in time} hc[t] * Hire[t] + - sum {t in time} lc[t] * Layoff[t] + - sum {t in time, p in prd} otr * cs * pt[p] * Oprd[p,t] + - sum {t in time, p in prd, a in 1..life} cri[p] * pc[p] * Inv[p,t,a] + - sum {t in time, p in prd} crs[p] * pc[p] * Short[p,t]; - - # Full regular wages for all crews employed, plus - # penalties for hiring and layoffs, plus - # wages for any overtime worked, plus - # inventory and shortage costs - - # (All other production costs are assumed - # to depend on initial inventory and on demands, - # and so are not included explicitly.) - -### CONSTRAINTS ### - -rlim 'regular-time limit' {t in time}: - - sum {p in prd} pt[p] * Rprd[p,t] <= sl * dpp[t] * Crews[t]; - - # Hours needed to accomplish all regular-time - # production in a period must not exceed - # hours available on all shifts - -olim 'overtime limit' {t in time}: - - sum {p in prd} pt[p] * Oprd[p,t] <= ol[t]; - - # Hours needed to accomplish all overtime - # production in a period must not exceed - # the specified overtime limit - -empl0 'initial crew level': Crews[first-1] = iw; - - # Use given initial workforce - -empl 'crew levels' {t in time}: Crews[t] = Crews[t-1] + Hire[t] - Layoff[t]; - - # Workforce changes by hiring or layoffs - -emplbnd 'crew limits' {t in time}: cmin[t] <= Crews[t] <= cmax[t]; - - # Workforce must remain within specified bounds - -dreq1 'first demand requirement' {p in prd}: - - Rprd[p,first] + Oprd[p,first] + Short[p,first] - - Inv[p,first,1] = dem[p,first] less iinv[p]; - -dreq 'demand requirements' {p in prd, t in first+1..last}: - - Rprd[p,t] + Oprd[p,t] + Short[p,t] - Short[p,t-1] - + sum {a in 1..life} (Inv[p,t-1,a] - Inv[p,t,a]) - = dem[p,t] less iil[p,t-1]; - - # Production plus increase in shortage plus - # decrease in inventory must equal demand - -ireq 'inventory requirements' {p in prd, t in time}: - - sum {a in 1..life} Inv[p,t,a] + iil[p,t] >= minv[p,t]; - - # Inventory in storage at end of period t - # must meet specified minimum - -izero 'impossible inventories' {p in prd, v in 1..life-1, a in v+1..life}: - - Inv[p,first+v-1,a] = 0; - - # In the vth period (starting from first) - # no inventory may be more than v periods old - # (initial inventories are handled separately) - -ilim1 'new-inventory limits' {p in prd, t in time}: - - Inv[p,t,1] <= Rprd[p,t] + Oprd[p,t]; - - # New inventory cannot exceed - # production in the most recent period - -ilim 'inventory limits' {p in prd, t in first+1..last, a in 2..life}: - - Inv[p,t,a] <= Inv[p,t-1,a-1]; - - # Inventory left from period (t+1)-p - # can only decrease as time goes on - -### DATA ### - -data; - -set prd := 18REG 24REG 24PRO ; - -param first := 1 ; -param last := 13 ; -param life := 2 ; - -param cs := 18 ; -param sl := 8 ; -param iw := 8 ; - -param rtr := 16.00 ; -param otr := 43.85 ; -param rir := 0.75 ; -param pir := 0.80 ; - -param : pt pc cri crs iinv := - - 18REG 1.194 2304. 0.015 1.100 82.0 - 24REG 1.509 2920. 0.015 1.100 792.2 - 24PRO 1.509 2910. 0.015 1.100 0.0 ; - -param : dpp ol cmin cmax hc lc := - - 1 19.5 96.0 0.0 8.0 7500 7500 - 2 19.0 96.0 0.0 8.0 7500 7500 - 3 20.0 96.0 0.0 8.0 7500 7500 - 4 19.0 96.0 0.0 8.0 7500 7500 - 5 19.5 96.0 0.0 8.0 15000 15000 - 6 19.0 96.0 0.0 8.0 15000 15000 - 7 19.0 96.0 0.0 8.0 15000 15000 - 8 20.0 96.0 0.0 8.0 15000 15000 - 9 19.0 96.0 0.0 8.0 15000 15000 - 10 20.0 96.0 0.0 8.0 15000 15000 - 11 20.0 96.0 0.0 8.0 7500 7500 - 12 18.0 96.0 0.0 8.0 7500 7500 - 13 18.0 96.0 0.0 8.0 7500 7500 ; - -param dem (tr) : - - 18REG 24REG 24PRO := - - 1 63.8 1212.0 0.0 - 2 76.0 306.2 0.0 - 3 88.4 319.0 0.0 - 4 913.8 208.4 0.0 - 5 115.0 298.0 0.0 - 6 133.8 328.2 0.0 - 7 79.6 959.6 0.0 - 8 111.0 257.6 0.0 - 9 121.6 335.6 0.0 - 10 470.0 118.0 1102.0 - 11 78.4 284.8 0.0 - 12 99.4 970.0 0.0 - 13 140.4 343.8 0.0 - 14 63.8 1212.0 0.0 ; - -param pro (tr) : - - 18REG 24REG 24PRO := - - 1 0 1 0 - 2 0 0 0 - 3 0 0 0 - 4 1 0 0 - 5 0 0 0 - 6 0 0 0 - 7 0 1 0 - 8 0 0 0 - 9 0 0 0 - 10 1 0 1 - 11 0 0 0 - 12 0 0 0 - 13 0 1 0 - 14 0 1 0 ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/qfit.mod b/resources/3rdparty/glpk-4.53/examples/qfit.mod deleted file mode 100644 index f168c4b52..000000000 --- a/resources/3rdparty/glpk-4.53/examples/qfit.mod +++ /dev/null @@ -1,49 +0,0 @@ -/*Quadratic Curve Fitting Solution - - Find a plausable quadratic fit to a sample of points - - Nigel_Galloway@operamail.com - February 1st., 2009 -*/ -set Sample; -param Sx {z in Sample}; -param Sy {z in Sample}; - -var a; -var b; -var c; - -equalz1 :sum{z in Sample} a*Sx[z]*Sx[z]*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z]*Sx[z]*Sx[z] + sum{z in Sample} c*Sx[z]*Sx[z] = sum{z in Sample} Sy[z]*Sx[z]*Sx[z]; -equalz2 :sum{z in Sample} a*Sx[z]*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z]*Sx[z] + sum{z in Sample} c*Sx[z] = sum{z in Sample} Sy[z]*Sx[z]; -equalz3 :sum{z in Sample} a*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z] + sum{z in Sample} c = sum{z in Sample} Sy[z]; - -solve; - -printf "\nbest quadratic fit is:\n\ty = %f %s %fx %s %fx^2\n\n", c, if b < 0 then "-" else "+", abs(b), if a < 0 then "-" else "+", abs(a); - -data; - -param: -Sample: Sx Sy := - 1 0 1 - 2 0.5 0.9 - 3 1 0.7 - 4 1.5 1.5 - 5 1.9 2 - 6 2.5 2.4 - 7 3 3.2 - 8 3.5 2 - 9 4 2.7 - 10 4.5 3.5 - 11 5 1 - 12 5.5 4 - 13 6 3.6 - 14 6.6 2.7 - 15 7 5.7 - 16 7.6 4.6 - 17 8.5 6 - 18 9 6.8 - 19 10 7.3 -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/queens.mod b/resources/3rdparty/glpk-4.53/examples/queens.mod deleted file mode 100644 index 3f446ce4c..000000000 --- a/resources/3rdparty/glpk-4.53/examples/queens.mod +++ /dev/null @@ -1,41 +0,0 @@ -/* QUEENS, a classic combinatorial optimization problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* The Queens Problem is to place as many queens as possible on the 8x8 - (or more generally, nxn) chess board in a way that they do not fight - each other. This problem is probably as old as the chess game itself, - and thus its origin is not known, but it is known that Gauss studied - this problem. */ - -param n, integer, > 0, default 8; -/* size of the chess board */ - -var x{1..n, 1..n}, binary; -/* x[i,j] = 1 means that a queen is placed in square [i,j] */ - -s.t. a{i in 1..n}: sum{j in 1..n} x[i,j] <= 1; -/* at most one queen can be placed in each row */ - -s.t. b{j in 1..n}: sum{i in 1..n} x[i,j] <= 1; -/* at most one queen can be placed in each column */ - -s.t. c{k in 2-n..n-2}: sum{i in 1..n, j in 1..n: i-j == k} x[i,j] <= 1; -/* at most one queen can be placed in each "\"-diagonal */ - -s.t. d{k in 3..n+n-1}: sum{i in 1..n, j in 1..n: i+j == k} x[i,j] <= 1; -/* at most one queen can be placed in each "/"-diagonal */ - -maximize obj: sum{i in 1..n, j in 1..n} x[i,j]; -/* objective is to place as many queens as possible */ - -/* solve the problem */ -solve; - -/* and print its optimal solution */ -for {i in 1..n} -{ for {j in 1..n} printf " %s", if x[i,j] then "Q" else "."; - printf("\n"); -} - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/samp1.mps b/resources/3rdparty/glpk-4.53/examples/samp1.mps deleted file mode 100644 index dd60d1843..000000000 --- a/resources/3rdparty/glpk-4.53/examples/samp1.mps +++ /dev/null @@ -1,29 +0,0 @@ -NAME SAMP1 -ROWS - N Z - G R1 - G R2 - G R3 -COLUMNS - X1 R1 2.0 R2 1.0 - X1 R3 5.0 Z 3.0 - MARK0001 'MARKER' 'INTORG' - X2 R1 -1.0 R2 -1.0 - X2 R3 3.0 Z 7.0 - X3 R1 1.0 R2 -6.0 - X3 Z -1.0 - MARK0002 'MARKER' 'INTEND' - X4 R1 -1.0 R2 4.0 - X4 R3 1.0 Z 1.0 -RHS - RHS1 R1 1.0 - RHS1 R2 8.0 - RHS1 R3 5.0 -BOUNDS - UP BND1 X1 4.0 - LO BND1 X2 2.0 - UP BND1 X2 5.0 - UP BND1 X3 1.0 - LO BND1 X4 3.0 - UP BND1 X4 8.0 -ENDATA diff --git a/resources/3rdparty/glpk-4.53/examples/samp2.mps b/resources/3rdparty/glpk-4.53/examples/samp2.mps deleted file mode 100644 index d2da1a31d..000000000 --- a/resources/3rdparty/glpk-4.53/examples/samp2.mps +++ /dev/null @@ -1,27 +0,0 @@ -NAME SAMP2 -ROWS - N Z - G R1 - G R2 - G R3 -COLUMNS - X1 R1 2.0 R2 1.0 - X1 R3 5.0 Z 3.0 - X2 R1 -1.0 R2 -1.0 - X2 R3 3.0 Z 7.0 - X3 R1 1.0 R2 -6.0 - X3 Z -1.0 - X4 R1 -1.0 R2 4.0 - X4 R3 1.0 Z 1.0 -RHS - RHS1 R1 1.0 - RHS1 R2 8.0 - RHS1 R3 5.0 -BOUNDS - UP BND1 X1 4.0 - LO BND1 X2 2.0 - UI BND1 X2 5.0 - BV BND1 X3 - LO BND1 X4 3.0 - UP BND1 X4 8.0 -ENDATA diff --git a/resources/3rdparty/glpk-4.53/examples/sample.asn b/resources/3rdparty/glpk-4.53/examples/sample.asn deleted file mode 100644 index edb0aafd9..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sample.asn +++ /dev/null @@ -1,40 +0,0 @@ -c sample.asn -c -c This is an example of the assignment problem data -c in DIMACS format. -c -p asn 17 22 -c -n 1 -n 2 -n 3 -n 4 -n 5 -n 6 -n 7 -n 8 -c -a 1 9 13 -a 1 10 21 -a 1 12 20 -a 2 10 12 -a 2 12 8 -a 2 13 26 -a 3 11 22 -a 3 13 11 -a 4 9 12 -a 4 12 36 -a 4 14 25 -a 5 11 41 -a 5 12 40 -a 5 13 11 -a 5 14 4 -a 5 15 8 -a 5 16 35 -a 5 17 32 -a 6 9 13 -a 7 10 19 -a 8 10 39 -a 8 11 15 -c -c eof diff --git a/resources/3rdparty/glpk-4.53/examples/sample.c b/resources/3rdparty/glpk-4.53/examples/sample.c deleted file mode 100644 index 468a6a354..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sample.c +++ /dev/null @@ -1,52 +0,0 @@ -/* sample.c */ - -#include -#include -#include - -int main(void) -{ glp_prob *lp; - int ia[1+1000], ja[1+1000]; - double ar[1+1000], z, x1, x2, x3; -s1: lp = glp_create_prob(); -s2: glp_set_prob_name(lp, "sample"); -s3: glp_set_obj_dir(lp, GLP_MAX); -s4: glp_add_rows(lp, 3); -s5: glp_set_row_name(lp, 1, "p"); -s6: glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 100.0); -s7: glp_set_row_name(lp, 2, "q"); -s8: glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 600.0); -s9: glp_set_row_name(lp, 3, "r"); -s10: glp_set_row_bnds(lp, 3, GLP_UP, 0.0, 300.0); -s11: glp_add_cols(lp, 3); -s12: glp_set_col_name(lp, 1, "x1"); -s13: glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0); -s14: glp_set_obj_coef(lp, 1, 10.0); -s15: glp_set_col_name(lp, 2, "x2"); -s16: glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0); -s17: glp_set_obj_coef(lp, 2, 6.0); -s18: glp_set_col_name(lp, 3, "x3"); -s19: glp_set_col_bnds(lp, 3, GLP_LO, 0.0, 0.0); -s20: glp_set_obj_coef(lp, 3, 4.0); -s21: ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */ -s22: ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */ -s23: ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */ -s24: ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */ -s25: ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */ -s26: ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */ -s27: ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */ -s28: ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */ -s29: ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */ -s30: glp_load_matrix(lp, 9, ia, ja, ar); -s31: glp_simplex(lp, NULL); -s32: z = glp_get_obj_val(lp); -s33: x1 = glp_get_col_prim(lp, 1); -s34: x2 = glp_get_col_prim(lp, 2); -s35: x3 = glp_get_col_prim(lp, 3); -s36: printf("\nz = %g; x1 = %g; x2 = %g; x3 = %g\n", - z, x1, x2, x3); -s37: glp_delete_prob(lp); - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/examples/sample.clq b/resources/3rdparty/glpk-4.53/examples/sample.clq deleted file mode 100644 index 741f71272..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sample.clq +++ /dev/null @@ -1,30 +0,0 @@ -c sample.clq -c -c This is an example of the Maximum Weight Clique -c Problem in DIMACS clique/coloring format. -c -p edge 8 16 -n 1 3 -n 2 4 -n 3 8 -n 5 5 -n 6 2 -n 8 3 -e 1 4 -e 1 5 -e 1 6 -e 1 8 -e 2 3 -e 2 6 -e 2 7 -e 2 8 -e 3 4 -e 3 6 -e 3 7 -e 4 5 -e 4 8 -e 5 7 -e 5 8 -e 6 7 -c -c eof diff --git a/resources/3rdparty/glpk-4.53/examples/sample.cnf b/resources/3rdparty/glpk-4.53/examples/sample.cnf deleted file mode 100644 index 508f15046..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sample.cnf +++ /dev/null @@ -1,12 +0,0 @@ -c sample.cnf -c -c This is an example of the CNF-SAT problem data -c in DIMACS format. -c -p cnf 4 3 -1 2 0 --4 3 --2 0 --1 4 0 -c -c eof diff --git a/resources/3rdparty/glpk-4.53/examples/sample.col b/resources/3rdparty/glpk-4.53/examples/sample.col deleted file mode 100644 index 132f6e578..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sample.col +++ /dev/null @@ -1,30 +0,0 @@ -c sample.col -c -c This is an example of the vertex coloring problem data -c in DIMACS format. -c -p edge 10 21 -c -e 1 2 -e 1 6 -e 1 7 -e 1 10 -e 2 3 -e 2 7 -e 2 8 -e 3 4 -e 3 8 -e 4 5 -e 4 8 -e 4 9 -e 5 6 -e 5 9 -e 5 10 -e 6 10 -e 7 8 -e 7 10 -e 8 9 -e 8 10 -e 9 10 -c -c eof diff --git a/resources/3rdparty/glpk-4.53/examples/sample.max b/resources/3rdparty/glpk-4.53/examples/sample.max deleted file mode 100644 index 6b8042297..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sample.max +++ /dev/null @@ -1,26 +0,0 @@ -c sample.max -c -c This is an example of the maximum flow problem data -c in DIMACS format. -c -p max 9 14 -c -n 1 s -n 9 t -c -a 1 2 14 -a 1 4 23 -a 2 3 10 -a 2 4 9 -a 3 5 12 -a 3 8 18 -a 4 5 26 -a 5 2 11 -a 5 6 25 -a 5 7 4 -a 6 7 7 -a 6 8 8 -a 7 9 15 -a 8 9 20 -c -c eof diff --git a/resources/3rdparty/glpk-4.53/examples/sample.min b/resources/3rdparty/glpk-4.53/examples/sample.min deleted file mode 100644 index 5ebf58b1f..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sample.min +++ /dev/null @@ -1,26 +0,0 @@ -c sample.min -c -c This is an example of the minimum cost flow problem data -c in DIMACS format. -c -p min 9 14 -c -n 1 20 -n 9 -20 -c -a 1 2 0 14 0 -a 1 4 0 23 0 -a 2 3 0 10 2 -a 2 4 0 9 3 -a 3 5 2 12 1 -a 3 8 0 18 0 -a 4 5 0 26 0 -a 5 2 0 11 1 -a 5 6 0 25 5 -a 5 7 0 4 7 -a 6 7 0 7 0 -a 6 8 4 8 0 -a 7 9 0 15 3 -a 8 9 0 20 9 -c -c eof diff --git a/resources/3rdparty/glpk-4.53/examples/sat.mod b/resources/3rdparty/glpk-4.53/examples/sat.mod deleted file mode 100644 index 84ba95249..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sat.mod +++ /dev/null @@ -1,201 +0,0 @@ -/* SAT, Satisfiability Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -param m, integer, > 0; -/* number of clauses */ - -param n, integer, > 0; -/* number of variables */ - -set C{1..m}; -/* clauses; each clause C[i], i = 1, ..., m, is disjunction of some - variables or their negations; in the data section each clause is - coded as a set of indices of corresponding variables, where negative - indices mean negation; for example, the clause (x3 or not x7 or x11) - is coded as the set { 3, -7, 11 } */ - -var x{1..n}, binary; -/* main variables */ - -/* To solve the satisfiability problem means to determine all variables - x[j] such that conjunction of all clauses C[1] and ... and C[m] takes - on the value true, i.e. all clauses are satisfied. - - Let the clause C[i] be (t or t' or ... or t''), where t, t', ..., t'' - are either variables or their negations. The condition of satisfying - C[i] can be most naturally written as: - - t + t' + ... + t'' >= 1, (1) - - where t, t', t'' have to be replaced by either x[j] or (1 - x[j]). - The formulation (1) leads to the mip problem with no objective, i.e. - to a feasibility problem. - - Another, more practical way is to write the condition for C[i] as: - - t + t' + ... + t'' + y[i] >= 1, (2) - - where y[i] is an auxiliary binary variable, and minimize the sum of - y[i]. If the sum is zero, all y[i] are also zero, and therefore all - clauses are satisfied. If the sum is minimal but non-zero, its value - shows the number of clauses which cannot be satisfied. */ - -var y{1..m}, binary, >= 0; -/* auxiliary variables */ - -s.t. c{i in 1..m}: - sum{j in C[i]} (if j > 0 then x[j] else (1 - x[-j])) + y[i] >= 1; -/* the condition (2) */ - -minimize unsat: sum{i in 1..m} y[i]; -/* number of unsatisfied clauses */ - -data; - -/* These data correspond to the instance hole6 (pigeon hole problem for - 6 holes) from SATLIB, the Satisfiability Library, which is part of - the collection at the Forschungsinstitut fuer anwendungsorientierte - Wissensverarbeitung in Ulm Germany */ - -/* The optimal solution is 1 (one clause cannot be satisfied) */ - -param m := 133; - -param n := 42; - -set C[1] := -1 -7; -set C[2] := -1 -13; -set C[3] := -1 -19; -set C[4] := -1 -25; -set C[5] := -1 -31; -set C[6] := -1 -37; -set C[7] := -7 -13; -set C[8] := -7 -19; -set C[9] := -7 -25; -set C[10] := -7 -31; -set C[11] := -7 -37; -set C[12] := -13 -19; -set C[13] := -13 -25; -set C[14] := -13 -31; -set C[15] := -13 -37; -set C[16] := -19 -25; -set C[17] := -19 -31; -set C[18] := -19 -37; -set C[19] := -25 -31; -set C[20] := -25 -37; -set C[21] := -31 -37; -set C[22] := -2 -8; -set C[23] := -2 -14; -set C[24] := -2 -20; -set C[25] := -2 -26; -set C[26] := -2 -32; -set C[27] := -2 -38; -set C[28] := -8 -14; -set C[29] := -8 -20; -set C[30] := -8 -26; -set C[31] := -8 -32; -set C[32] := -8 -38; -set C[33] := -14 -20; -set C[34] := -14 -26; -set C[35] := -14 -32; -set C[36] := -14 -38; -set C[37] := -20 -26; -set C[38] := -20 -32; -set C[39] := -20 -38; -set C[40] := -26 -32; -set C[41] := -26 -38; -set C[42] := -32 -38; -set C[43] := -3 -9; -set C[44] := -3 -15; -set C[45] := -3 -21; -set C[46] := -3 -27; -set C[47] := -3 -33; -set C[48] := -3 -39; -set C[49] := -9 -15; -set C[50] := -9 -21; -set C[51] := -9 -27; -set C[52] := -9 -33; -set C[53] := -9 -39; -set C[54] := -15 -21; -set C[55] := -15 -27; -set C[56] := -15 -33; -set C[57] := -15 -39; -set C[58] := -21 -27; -set C[59] := -21 -33; -set C[60] := -21 -39; -set C[61] := -27 -33; -set C[62] := -27 -39; -set C[63] := -33 -39; -set C[64] := -4 -10; -set C[65] := -4 -16; -set C[66] := -4 -22; -set C[67] := -4 -28; -set C[68] := -4 -34; -set C[69] := -4 -40; -set C[70] := -10 -16; -set C[71] := -10 -22; -set C[72] := -10 -28; -set C[73] := -10 -34; -set C[74] := -10 -40; -set C[75] := -16 -22; -set C[76] := -16 -28; -set C[77] := -16 -34; -set C[78] := -16 -40; -set C[79] := -22 -28; -set C[80] := -22 -34; -set C[81] := -22 -40; -set C[82] := -28 -34; -set C[83] := -28 -40; -set C[84] := -34 -40; -set C[85] := -5 -11; -set C[86] := -5 -17; -set C[87] := -5 -23; -set C[88] := -5 -29; -set C[89] := -5 -35; -set C[90] := -5 -41; -set C[91] := -11 -17; -set C[92] := -11 -23; -set C[93] := -11 -29; -set C[94] := -11 -35; -set C[95] := -11 -41; -set C[96] := -17 -23; -set C[97] := -17 -29; -set C[98] := -17 -35; -set C[99] := -17 -41; -set C[100] := -23 -29; -set C[101] := -23 -35; -set C[102] := -23 -41; -set C[103] := -29 -35; -set C[104] := -29 -41; -set C[105] := -35 -41; -set C[106] := -6 -12; -set C[107] := -6 -18; -set C[108] := -6 -24; -set C[109] := -6 -30; -set C[110] := -6 -36; -set C[111] := -6 -42; -set C[112] := -12 -18; -set C[113] := -12 -24; -set C[114] := -12 -30; -set C[115] := -12 -36; -set C[116] := -12 -42; -set C[117] := -18 -24; -set C[118] := -18 -30; -set C[119] := -18 -36; -set C[120] := -18 -42; -set C[121] := -24 -30; -set C[122] := -24 -36; -set C[123] := -24 -42; -set C[124] := -30 -36; -set C[125] := -30 -42; -set C[126] := -36 -42; -set C[127] := 6 5 4 3 2 1; -set C[128] := 12 11 10 9 8 7; -set C[129] := 18 17 16 15 14 13; -set C[130] := 24 23 22 21 20 19; -set C[131] := 30 29 28 27 26 25; -set C[132] := 36 35 34 33 32 31; -set C[133] := 42 41 40 39 38 37; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/shiftcover.mod b/resources/3rdparty/glpk-4.53/examples/shiftcover.mod deleted file mode 100644 index 1e036c8a2..000000000 --- a/resources/3rdparty/glpk-4.53/examples/shiftcover.mod +++ /dev/null @@ -1,244 +0,0 @@ -/* File: shiftcover.mod */ - -/* WORKFORCE SHIFT COVERAGE assignment problem */ - -/* Written by Larry D'Agostino - - Maximize Productivity with Industrial Engineer and Operations Research Tools - http://industrialengineertools.blogspot.com - - -/* The WORKFORCE SHIFT COVERAGE is an assigment problem that determines - the schedule of crew given available time and shifts. - - The objective is to cover the available time given hourly demand with the minimum - number of crew members. - - This is a set covering problem that is very common among finding crew - and shift allocations. Notice in the data section the workforce shift allocation - per day of the week.*/ - - -/* ----- Model PARAMTERS and SETS -----*/ - -param numhrs; -/* number of hours of operations in a given day */ - -param dys; -/* number of days in a week */ - -set S; -/* set of crew shifts */ - -set H := 1..numhrs; -/* set of hours of a day*/ - -set D; -/* set of days of a week*/ - -param dmnd{h in H, d in D}; -/* demand for crew members given h hour and d day */ - -param shifts{d in D, h in H, s in S}; -/* shifts to assign to crew members given d day, h hour, and s shift schedule - -/*----- Model VARIABLES -----*/ - -var crew{s in S}, integer, >=0; -/* number of crew assigned to shift S */ - - -/*----- Model CONSTRAINTS -----*/ - -s.t. Coverage{h in H, d in D}: sum{s in S} crew[s]*shifts[d,h,s] >= dmnd[h,d]; -/* number of crew to cover with a shift given hourly demand and day */ - - -/*----- Model OBJECTIVE -----*/ - -minimize obj: sum{s in S} crew[s]; -/* minimize number of crew to cover demand*/ - -solve; -display crew; - -printf "\n"; -printf "Total Crew: %3d\n\n", sum{s in S} crew[s]; - - - -printf "\n\n"; -printf "Weekly Crew Schedule\n\n"; -printf "Hour "; -printf{d in D} " %s ", d; -printf "\n"; -for {h in H} { - printf " %2s ",h; - printf{d in D} " %3d ", sum{s in S} crew[s]*shifts[d,h,s]; - printf "\n"; -} -printf"\n"; - - - -data; - -param numhrs := 16; - -set D := SUN, MON, TUE, WED, THU, FRI, SAT; - -set S := Sh1, Sh2, Sh3, Sh4, Sh5, Sh6, Sh7, Sh8, Sh9; - -param dmnd : SUN MON TUE WED THU FRI SAT := -1 0 3 3 4 3 2 0 -2 0 14 14 16 14 12 12 -3 0 24 24 27 24 20 15 -4 0 28 28 32 28 23 15 -5 0 33 33 37 33 24 16 -6 0 34 34 38 34 24 15 -7 0 35 35 39 35 25 11 -8 0 35 35 40 35 27 0 -9 0 34 34 39 34 25 0 -10 0 31 31 35 31 24 0 -11 2 24 24 27 24 25 0 -12 3 19 19 21 19 21 0 -13 2 24 24 27 24 13 0 -14 2 16 16 18 16 0 0 -15 0 7 7 7 7 0 0 -16 0 5 5 5 5 0 0; - - -param shifts := -['SUN',*,*]: - Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := -1 0 0 0 0 0 0 0 0 0 -2 0 0 0 0 0 0 0 0 0 -3 0 0 0 0 0 0 0 0 0 -4 0 0 0 0 0 0 0 0 0 -5 0 0 0 0 0 0 0 0 0 -6 0 0 0 0 0 0 0 0 0 -7 0 0 0 0 0 0 0 0 0 -8 0 0 0 0 0 0 0 0 0 -9 0 0 0 0 0 0 0 0 0 -10 0 0 0 0 0 0 0 0 0 -11 0 0 0 0 0 0 0 0 1 -12 0 0 0 0 0 0 0 0 1 -13 0 0 0 0 0 0 0 0 1 -14 0 0 0 0 0 0 0 0 1 -15 0 0 0 0 0 0 0 0 0 -16 0 0 0 0 0 0 0 0 0 - - -['MON',*,*]: - Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := -1 1 0 0 0 0 0 0 0 0 -2 1 1 0 0 0 0 0 0 0 -3 1 1 1 0 0 0 0 0 0 -4 1 1 1 1 0 0 0 0 0 -5 0 1 1 1 1 0 0 0 0 -6 1 0 1 1 1 1 0 0 1 -7 1 1 0 1 1 1 1 0 1 -8 1 1 1 0 1 1 1 1 1 -9 1 1 1 1 0 1 1 1 1 -10 0 1 1 1 1 0 1 1 1 -11 0 0 1 1 1 1 0 1 0 -12 0 0 0 1 1 1 1 0 1 -13 0 0 0 0 1 1 1 1 1 -14 0 0 0 0 0 1 1 1 1 -15 0 0 0 0 0 0 1 1 1 -16 0 0 0 0 0 0 0 1 1 - -['TUE',*,*]: - Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := -1 1 0 0 0 0 0 0 0 0 -2 1 1 0 0 0 0 0 0 0 -3 1 1 1 0 0 0 0 0 0 -4 1 1 1 1 0 0 0 0 0 -5 0 1 1 1 1 0 0 0 0 -6 1 0 1 1 1 1 0 0 1 -7 1 1 0 1 1 1 1 0 1 -8 1 1 1 0 1 1 1 1 1 -9 1 1 1 1 0 1 1 1 1 -10 0 1 1 1 1 0 1 1 1 -11 0 0 1 1 1 1 0 1 0 -12 0 0 0 1 1 1 1 0 1 -13 0 0 0 0 1 1 1 1 1 -14 0 0 0 0 0 1 1 1 1 -15 0 0 0 0 0 0 1 1 1 -16 0 0 0 0 0 0 0 1 1 - -['WED',*,*]: - Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := -1 1 0 0 0 0 0 0 0 0 -2 1 1 0 0 0 0 0 0 0 -3 1 1 1 0 0 0 0 0 0 -4 1 1 1 1 0 0 0 0 0 -5 0 1 1 1 1 0 0 0 0 -6 1 0 1 1 1 1 0 0 1 -7 1 1 0 1 1 1 1 0 1 -8 1 1 1 0 1 1 1 1 1 -9 1 1 1 1 0 1 1 1 1 -10 0 1 1 1 1 0 1 1 1 -11 0 0 1 1 1 1 0 1 0 -12 0 0 0 1 1 1 1 0 1 -13 0 0 0 0 1 1 1 1 1 -14 0 0 0 0 0 1 1 1 1 -15 0 0 0 0 0 0 1 1 1 -16 0 0 0 0 0 0 0 1 1 - -['THU',*,*]: - Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := -1 1 0 0 0 0 0 0 0 0 -2 1 1 0 0 0 0 0 0 0 -3 1 1 1 0 0 0 0 0 0 -4 1 1 1 1 0 0 0 0 0 -5 0 1 1 1 1 0 0 0 0 -6 1 0 1 1 1 1 0 0 0 -7 1 1 0 1 1 1 1 0 0 -8 1 1 1 0 1 1 1 1 0 -9 1 1 1 1 0 1 1 1 0 -10 0 1 1 1 1 0 1 1 0 -11 0 0 1 1 1 1 0 1 0 -12 0 0 0 1 1 1 1 0 0 -13 0 0 0 0 1 1 1 1 0 -14 0 0 0 0 0 1 1 1 0 -15 0 0 0 0 0 0 1 1 0 -16 0 0 0 0 0 0 0 1 0 - -['FRI',*,*]: - Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := -1 1 0 0 0 0 0 0 0 0 -2 1 1 0 0 0 0 0 0 0 -3 1 1 1 0 0 0 0 0 0 -4 1 1 1 1 0 0 0 0 0 -5 0 1 1 1 1 0 0 0 0 -6 1 0 1 1 1 1 0 0 0 -7 1 1 0 1 1 1 1 0 0 -8 1 1 1 0 1 1 1 1 0 -9 1 1 1 1 0 1 1 1 0 -10 0 1 1 1 1 0 1 1 0 -11 0 0 1 1 1 1 0 1 0 -12 0 0 0 1 1 1 1 0 0 -13 0 0 0 0 1 1 1 1 0 -14 0 0 0 0 0 1 1 1 0 -15 0 0 0 0 0 0 1 1 0 -16 0 0 0 0 0 0 0 1 0 - -['SAT',*,*]: - Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := -1 0 0 0 0 0 0 0 0 0 -2 0 0 0 0 0 0 0 0 1 -3 0 0 0 0 0 0 0 0 1 -4 0 0 0 0 0 0 0 0 1 -5 0 0 0 0 0 0 0 0 1 -6 0 0 0 0 0 0 0 0 1 -7 0 0 0 0 0 0 0 0 1 -8 0 0 0 0 0 0 0 0 0 -9 0 0 0 0 0 0 0 0 0 -10 0 0 0 0 0 0 0 0 0 -11 0 0 0 0 0 0 0 0 0 -12 0 0 0 0 0 0 0 0 0 -13 0 0 0 0 0 0 0 0 0 -14 0 0 0 0 0 0 0 0 0 -15 0 0 0 0 0 0 0 0 0 -16 0 0 0 0 0 0 0 0 0; diff --git a/resources/3rdparty/glpk-4.53/examples/shikaku.mod b/resources/3rdparty/glpk-4.53/examples/shikaku.mod deleted file mode 100644 index 19cf5ddbe..000000000 --- a/resources/3rdparty/glpk-4.53/examples/shikaku.mod +++ /dev/null @@ -1,107 +0,0 @@ -/* A solver for the Japanese number-puzzle Shikaku - * http://en.wikipedia.org/wiki/Shikaku - * - * Sebastian Nowozin , 27th January 2009 - */ - -param ndim := 10; -set rows := 1..ndim; -set rows1 := 1..(ndim+1); -set cols := 1..ndim; -set cols1 := 1..(ndim+1); -param givens{rows, cols}, integer, >= 0, default 0; - -/* Set of vertices as (row,col) coordinates */ -set V := { (i,j) in { rows, cols }: givens[i,j] != 0 }; - -/* Set of all feasible boxes of the right size: only this boxes are possible. - * The box contains (i,j) and ranges from (k,l) to (m,n) - */ -set B := { (i,j,k,l,m,n) in { V, rows, cols, rows1, cols1 }: - i >= k and i < m and j >= l and j < n and /* Contains (i,j) */ - ((m-k)*(n-l)) = givens[i,j] and /* Right size */ - card({ (s,t) in V: s >= k and s < m and t >= l and t < n }) = 1 - /* Contains only (i,j), no other number */ -}; - -var x{B}, binary; - -/* Cover each square exactly once */ -s.t. cover_once{ (s,t) in { rows, cols } }: - sum{(i,j,k,l,m,n) in B: s >= k and s < m and t >= l and t < n} - x[i,j,k,l,m,n] = 1; - -minimize cost: 0; - -solve; - -/* Output solution graphically */ -printf "\nSolution:\n"; -for { row in rows1 } { - for { col in cols1 } { - printf{0..0: card({(i,j,k,l,m,n) in B: - col >= l and col <= n and (row = k or row = m) and - x[i,j,k,l,m,n] = 1}) > 0 and - card({(i,j,k,l,m,n) in B: - row >= k and row <= m and (col = l or col = n) and - x[i,j,k,l,m,n] = 1}) > 0} "+"; - printf{0..0: card({(i,j,k,l,m,n) in B: - col >= l and col <= n and (row = k or row = m) and - x[i,j,k,l,m,n] = 1}) = 0 and - card({(i,j,k,l,m,n) in B: - row >= k and row <= m and (col = l or col = n) and - x[i,j,k,l,m,n] = 1}) > 0} "|"; - printf{0..0: card({(i,j,k,l,m,n) in B: - row >= k and row <= m and (col = l or col = n) and - x[i,j,k,l,m,n] = 1}) = 0 and - card({(i,j,k,l,m,n) in B: - col >= l and col <= n and (row = k or row = m) and - x[i,j,k,l,m,n] = 1}) > 0} "-"; - printf{0..0: card({(i,j,k,l,m,n) in B: - row >= k and row <= m and (col = l or col = n) and - x[i,j,k,l,m,n] = 1}) = 0 and - card({(i,j,k,l,m,n) in B: - col >= l and col <= n and (row = k or row = m) and - x[i,j,k,l,m,n] = 1}) = 0} " "; - - printf{0..0: card({(i,j,k,l,m,n) in B: - col >= l and col < n and (row = k or row = m) and - x[i,j,k,l,m,n] = 1}) > 0} "---"; - printf{0..0: card({(i,j,k,l,m,n) in B: - col >= l and col < n and (row = k or row = m) and - x[i,j,k,l,m,n] = 1}) = 0} " "; - } - printf "\n"; - - for { (col,p) in { cols, 1 }: card({ s in rows: s = row }) = 1 } { - printf{0..0: card({(i,j,k,l,m,n) in B: - row >= k and row < m and (col = l or col = n) and - x[i,j,k,l,m,n] = 1}) > 0} "|"; - printf{0..0: card({(i,j,k,l,m,n) in B: - row >= k and row < m and (col = l or col = n) and - x[i,j,k,l,m,n] = 1}) = 0} " "; - printf{0..0: card({ (i,j) in V: i = row and j = col}) > 0} " %2d", givens[row,col]; - printf{0..0: card({ (i,j) in V: i = row and j = col}) = 0} " ."; - } - printf{0..0: card({ r in rows: r = row }) = 1} "|\n"; -} - -data; - -/* This Shikaku is from - * http://www.emn.fr/x-info/sdemasse/gccat/KShikaku.html#uid5449 - */ -param givens : 1 2 3 4 5 6 7 8 9 10 := - 1 9 . . . 12 . . 5 . . - 2 . . . . . . . . . . - 3 . . . . . . . . . 6 - 4 8 . 6 . 8 . . . . . - 5 . . . . . . . . . . - 6 . . . . . . . . . . - 7 . . . . . 6 . 8 . 12 - 8 4 . . . . . . . . . - 9 . . . . . . . . . . - 10 . . 3 . . 9 . . . 4 - ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/sorting.mod b/resources/3rdparty/glpk-4.53/examples/sorting.mod deleted file mode 100644 index 8f82b1fc5..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sorting.mod +++ /dev/null @@ -1,67 +0,0 @@ -/* sorting.mod - how to sort arrays in MathProg */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -# Sometimes it is necessary to print parameters or variables in the -# order of ascending or descending their values. Suppose, for example, -# that we have the following subscripted parameter: - -set I := 1..12; - -param a{i in I} := Uniform(2, 7); - -# If we print all its members: - -printf{i in I} "a[%d] = %g\n", i, a[i]; - -# the output may look like follows: -# -# a[1] = 2.64156 -# a[2] = 2.04798 -# a[3] = 2.14843 -# a[4] = 4.76896 -# a[5] = 6.09132 -# a[6] = 3.27780 -# a[7] = 4.06113 -# a[8] = 4.05898 -# a[9] = 6.63120 -# a[10] = 6.50318 -# a[11] = 3.46065 -# a[12] = 4.69845 -# -# However, we would like the parameter members to appear in the order -# of ascending their values. -# -# Introduce the following auxiliary parameter: - -param pos{i in I} := - 1 + card({j in I: a[j] < a[i] or a[j] = a[i] and j < i}); - -# where pos[i] = k means that in the sorted list member a[i] would -# have k-th position, 1 <= k <= |I|. Then introduce another auxiliary -# parameter: - -param ind{k in 1..card(I)} := sum{i in I: pos[i] = k} i; - -# where ind[k] = i iff pos[k] = i. -# -# Now, the following statement: - -printf{k in 1..card(I)} "a[%d] = %g\n", ind[k], a[ind[k]]; - -# prints the parameter members in the desired order: -# -# a[2] = 2.04798 -# a[3] = 2.14843 -# a[1] = 2.64156 -# a[6] = 3.27780 -# a[11] = 3.46065 -# a[8] = 4.05898 -# a[7] = 4.06113 -# a[12] = 4.69845 -# a[4] = 4.76896 -# a[5] = 6.09132 -# a[10] = 6.50318 -# a[9] = 6.63120 - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/spp.mod b/resources/3rdparty/glpk-4.53/examples/spp.mod deleted file mode 100644 index 53008f62c..000000000 --- a/resources/3rdparty/glpk-4.53/examples/spp.mod +++ /dev/null @@ -1,67 +0,0 @@ -/* SPP, Shortest Path Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* Given a directed graph G = (V,E), its edge lengths c(i,j) for all - (i,j) in E, and two nodes s, t in V, the Shortest Path Problem (SPP) - is to find a directed path from s to t whose length is minimal. */ - -param n, integer, > 0; -/* number of nodes */ - -set E, within {i in 1..n, j in 1..n}; -/* set of edges */ - -param c{(i,j) in E}; -/* c[i,j] is length of edge (i,j); note that edge lengths are allowed - to be of any sign (positive, negative, or zero) */ - -param s, in {1..n}; -/* source node */ - -param t, in {1..n}; -/* target node */ - -var x{(i,j) in E}, >= 0; -/* x[i,j] = 1 means that edge (i,j) belong to shortest path; - x[i,j] = 0 means that edge (i,j) does not belong to shortest path; - note that variables x[i,j] are binary, however, there is no need to - declare them so due to the totally unimodular constraint matrix */ - -s.t. r{i in 1..n}: sum{(j,i) in E} x[j,i] + (if i = s then 1) = - sum{(i,j) in E} x[i,j] + (if i = t then 1); -/* conservation conditions for unity flow from s to t; every feasible - solution is a path from s to t */ - -minimize Z: sum{(i,j) in E} c[i,j] * x[i,j]; -/* objective function is the path length to be minimized */ - -data; - -/* Optimal solution is 20 that corresponds to the following shortest - path: s = 1 -> 2 -> 4 -> 8 -> 6 = t */ - -param n := 8; - -param s := 1; - -param t := 6; - -param : E : c := - 1 2 1 - 1 4 8 - 1 7 6 - 2 4 2 - 3 2 14 - 3 4 10 - 3 5 6 - 3 6 19 - 4 5 8 - 4 8 13 - 5 8 12 - 6 5 7 - 7 4 5 - 8 6 4 - 8 7 10; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/spxsamp1.c b/resources/3rdparty/glpk-4.53/examples/spxsamp1.c deleted file mode 100644 index 715642341..000000000 --- a/resources/3rdparty/glpk-4.53/examples/spxsamp1.c +++ /dev/null @@ -1,18 +0,0 @@ -/* spxsamp1.c */ - -#include -#include -#include - -int main(void) -{ glp_prob *P; - P = glp_create_prob(); - glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); - glp_adv_basis(P, 0); - glp_simplex(P, NULL); - glp_print_sol(P, "25fv47.txt"); - glp_delete_prob(P); - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/examples/spxsamp2.c b/resources/3rdparty/glpk-4.53/examples/spxsamp2.c deleted file mode 100644 index f952e740e..000000000 --- a/resources/3rdparty/glpk-4.53/examples/spxsamp2.c +++ /dev/null @@ -1,20 +0,0 @@ -/* spxsamp2.c */ - -#include -#include -#include - -int main(void) -{ glp_prob *P; - glp_smcp parm; - P = glp_create_prob(); - glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); - glp_init_smcp(&parm); - parm.meth = GLP_DUAL; - glp_simplex(P, &parm); - glp_print_sol(P, "25fv47.txt"); - glp_delete_prob(P); - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/examples/sql/README b/resources/3rdparty/glpk-4.53/examples/sql/README deleted file mode 100644 index f78ec1574..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sql/README +++ /dev/null @@ -1,5 +0,0 @@ -This subdirectory contains files which demonstrate using data tables -in MathProg models for MySQL and iODBC. - -Script mysql_setup.sh is used to load the data from the *.sql files to -a MySQL database. Change the username, if necessary. diff --git a/resources/3rdparty/glpk-4.53/examples/sql/mysql_setup.sh b/resources/3rdparty/glpk-4.53/examples/sql/mysql_setup.sh deleted file mode 100644 index 1dce8edd9..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sql/mysql_setup.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -# This file can be used to create database glpk in MySQL. -echo MySQL is called for user root. -mysql -f -u root -p < sudoku.sql -echo MySQL is called for user root. -mysql -f -u root -p < transp.sql diff --git a/resources/3rdparty/glpk-4.53/examples/sql/sudoku.sql b/resources/3rdparty/glpk-4.53/examples/sql/sudoku.sql deleted file mode 100644 index 2fe40d777..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sql/sudoku.sql +++ /dev/null @@ -1,101 +0,0 @@ -CREATE DATABASE glpk; -CREATE USER glpk@localhost IDENTIFIED BY 'gnu'; -GRANT ALL PRIVILEGES ON glpk.* TO glpk@localhost; -USE glpk; -DROP TABLE sudoku; -CREATE TABLE sudoku ( - ID INT , - COL INT , - LIN INT , - VAL INT , - PRIMARY KEY ( ID, COL, LIN ) - ); -DROP TABLE sudoku_solution; -CREATE TABLE sudoku_solution ( - ID INT , - COL INT , - LIN INT , - VAL INT , - PRIMARY KEY ( ID, COL, LIN ) - ); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 1, 5); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 2, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 3, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 4, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 5, 4); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 6, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 7, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 8, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 1, 9, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 1, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 2, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 3, 3); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 4, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 5, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 6, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 7, 6); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 8, 2); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 2, 9, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 1, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 2, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 3, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 4, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 5, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 6, 9); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 7, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 8, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 3, 9, 4); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 1, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 2, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 3, 6); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 4, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 5, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 6, 7); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 7, 2); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 8, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 4, 9, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 1, 8); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 2, 1); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 3, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 4, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 5, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 6, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 7, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 8, 4); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 5, 9, 3); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 1, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 2, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 3, 9); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 4, 1); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 5, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 6, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 7, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 8, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 6, 9, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 1, 7); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 2, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 3, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 4, 5); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 5, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 6, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 7, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 8, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 7, 9, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 1, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 2, 9); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 3, 2); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 4, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 5, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 6, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 7, 8); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 8, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 8, 9, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 1, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 2, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 3, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 4, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 5, 3); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 6, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 7, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 8, 0); -INSERT INTO sudoku (ID, COL, LIN, VAL) VALUES (1, 9, 9, 6); diff --git a/resources/3rdparty/glpk-4.53/examples/sql/sudoku_mysql.mod b/resources/3rdparty/glpk-4.53/examples/sql/sudoku_mysql.mod deleted file mode 100644 index 6e56f2c6d..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sql/sudoku_mysql.mod +++ /dev/null @@ -1,113 +0,0 @@ -/* SUDOKU, Number Placement Puzzle */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* This example shows how to use the table statement. - The sudoku to be solves is read from file sudoku_in.csv. - The solution is written to sudoku_out.csv. - The file format is CSV as defined in - RFC 4180 - Common Format and MIME Type for - Comma-Separated Values (CSV) Files */ - -/* Sudoku, also known as Number Place, is a logic-based placement - puzzle. The aim of the canonical puzzle is to enter a numerical - digit from 1 through 9 in each cell of a 9x9 grid made up of 3x3 - subgrids (called "regions"), starting with various digits given in - some cells (the "givens"). Each row, column, and region must contain - only one instance of each numeral. - - Example: - - +-------+-------+-------+ - | 5 3 . | . 7 . | . . . | - | 6 . . | 1 9 5 | . . . | - | . 9 8 | . . . | . 6 . | - +-------+-------+-------+ - | 8 . . | . 6 . | . . 3 | - | 4 . . | 8 . 3 | . . 1 | - | 7 . . | . 2 . | . . 6 | - +-------+-------+-------+ - | . 6 . | . . . | 2 8 . | - | . . . | 4 1 9 | . . 5 | - | . . . | . 8 . | . 7 9 | - +-------+-------+-------+ - - (From Wikipedia, the free encyclopedia.) */ -set fields dimen 2; - -param id; - -param givens{1..9, 1..9}, integer, >= 0, <= 9, default 0; -/* the "givens" */ - -/* -table ti IN 'MySQL' 'Database=glpk;UID=glpk;PWD=gnu' - 'sudoku' : - fields <- [COL, LIN], givens ~ VAL; -*/ -table ti IN 'MySQL' 'Database=glpk;UID=glpk;PWD=gnu' - 'SELECT * FROM sudoku WHERE ID = ' & id : - fields <- [COL, LIN], givens ~ VAL; - -var x{i in 1..9, j in 1..9, k in 1..9}, binary; -/* x[i,j,k] = 1 means cell [i,j] is assigned number k */ - -s.t. fa{i in 1..9, j in 1..9, k in 1..9: givens[i,j] != 0}: - x[i,j,k] = (if givens[i,j] = k then 1 else 0); -/* assign pre-defined numbers using the "givens" */ - -s.t. fb{i in 1..9, j in 1..9}: sum{k in 1..9} x[i,j,k] = 1; -/* each cell must be assigned exactly one number */ - -s.t. fc{i in 1..9, k in 1..9}: sum{j in 1..9} x[i,j,k] = 1; -/* cells in the same row must be assigned distinct numbers */ - -s.t. fd{j in 1..9, k in 1..9}: sum{i in 1..9} x[i,j,k] = 1; -/* cells in the same column must be assigned distinct numbers */ - -s.t. fe{I in 1..9 by 3, J in 1..9 by 3, k in 1..9}: - sum{i in I..I+2, j in J..J+2} x[i,j,k] = 1; -/* cells in the same region must be assigned distinct numbers */ - -/* there is no need for an objective function here */ - -solve; - -table ta{(i,j) in fields} OUT - 'MySQL' 'Database=glpk;UID=glpk;PWD=gnu' - 'DELETE FROM sudoku_solution' - 'WHERE ID = ' & id & ';' - 'INSERT INTO sudoku_solution' - '(ID, COL, LIN, VAL)' - 'VALUES(?, ?, ?, ?);' : - id ~ ID, i ~ COL, j ~ LIN, (sum{k in 1..9} x[i,j,k] * k) ~ VAL; - -printf "\nSudoku to be solved\n"; -for {i in 1..9} -{ for {0..0: i = 1 or i = 4 or i = 7} - printf " +-------+-------+-------+\n"; - for {j in 1..9} - { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); - printf " %d", givens[i,j]; - for {0..0: j = 9} printf(" |\n"); - } - for {0..0: i = 9} - printf " +-------+-------+-------+\n"; - } -printf "\nSolution\n"; -for {i in 1..9} -{ for {0..0: i = 1 or i = 4 or i = 7} - printf " +-------+-------+-------+\n"; - for {j in 1..9} - { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); - printf " %d", sum{k in 1..9} x[i,j,k] * k; - for {0..0: j = 9} printf(" |\n"); - } - for {0..0: i = 9} - printf " +-------+-------+-------+\n"; -} - -data; - -param id := 1; -end; diff --git a/resources/3rdparty/glpk-4.53/examples/sql/sudoku_odbc.mod b/resources/3rdparty/glpk-4.53/examples/sql/sudoku_odbc.mod deleted file mode 100644 index 9ffa3ab06..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sql/sudoku_odbc.mod +++ /dev/null @@ -1,111 +0,0 @@ -/* SUDOKU, Number Placement Puzzle */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* This example shows how to use the table statement. - The sudoku to be solves is read from file sudoku_in.csv. - The solution is written to sudoku_out.csv. - The file format is CSV as defined in - RFC 4180 - Common Format and MIME Type for - Comma-Separated Values (CSV) Files */ - -/* Sudoku, also known as Number Place, is a logic-based placement - puzzle. The aim of the canonical puzzle is to enter a numerical - digit from 1 through 9 in each cell of a 9x9 grid made up of 3x3 - subgrids (called "regions"), starting with various digits given in - some cells (the "givens"). Each row, column, and region must contain - only one instance of each numeral. - - Example: - - +-------+-------+-------+ - | 5 3 . | . 7 . | . . . | - | 6 . . | 1 9 5 | . . . | - | . 9 8 | . . . | . 6 . | - +-------+-------+-------+ - | 8 . . | . 6 . | . . 3 | - | 4 . . | 8 . 3 | . . 1 | - | 7 . . | . 2 . | . . 6 | - +-------+-------+-------+ - | . 6 . | . . . | 2 8 . | - | . . . | 4 1 9 | . . 5 | - | . . . | . 8 . | . 7 9 | - +-------+-------+-------+ - - (From Wikipedia, the free encyclopedia.) */ -set fields dimen 2; - -param id; - -param givens{1..9, 1..9}, integer, >= 0, <= 9, default 0; -/* the "givens" */ - -table ti IN 'iODBC' - 'DSN=glpk;UID=glpk;PWD=gnu' - 'SELECT * FROM sudoku' - 'WHERE ID = ' & id : - fields <- [COL, LIN], givens ~ VAL; - -var x{i in 1..9, j in 1..9, k in 1..9}, binary; -/* x[i,j,k] = 1 means cell [i,j] is assigned number k */ - -s.t. fa{i in 1..9, j in 1..9, k in 1..9: givens[i,j] != 0}: - x[i,j,k] = (if givens[i,j] = k then 1 else 0); -/* assign pre-defined numbers using the "givens" */ - -s.t. fb{i in 1..9, j in 1..9}: sum{k in 1..9} x[i,j,k] = 1; -/* each cell must be assigned exactly one number */ - -s.t. fc{i in 1..9, k in 1..9}: sum{j in 1..9} x[i,j,k] = 1; -/* cells in the same row must be assigned distinct numbers */ - -s.t. fd{j in 1..9, k in 1..9}: sum{i in 1..9} x[i,j,k] = 1; -/* cells in the same column must be assigned distinct numbers */ - -s.t. fe{I in 1..9 by 3, J in 1..9 by 3, k in 1..9}: - sum{i in I..I+2, j in J..J+2} x[i,j,k] = 1; -/* cells in the same region must be assigned distinct numbers */ - -/* there is no need for an objective function here */ - - -solve; - -table ta {(i, j) in {i1 in 1..9} cross {i2 in 1..9}} OUT - 'iODBC' 'DSN=glpk;UID=glpk;PWD=gnu' - 'DELETE FROM sudoku_solution' - 'WHERE ID = ' & id & ';' - 'INSERT INTO sudoku_solution' - '(ID, COL, LIN, VAL)' - 'VALUES(?, ?, ?, ?);' : - id ~ ID, i ~ COL, j ~ LIN, (sum{k in 1..9} x[i,j,k] * k) ~ VAL; - -printf "\nSudoku to be solved\n"; -for {i in 1..9} -{ for {0..0: i = 1 or i = 4 or i = 7} - printf " +-------+-------+-------+\n"; - for {j in 1..9} - { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); - printf " %d", givens[i,j]; - for {0..0: j = 9} printf(" |\n"); - } - for {0..0: i = 9} - printf " +-------+-------+-------+\n"; - } -printf "\nSolution\n"; -for {i in 1..9} -{ for {0..0: i = 1 or i = 4 or i = 7} - printf " +-------+-------+-------+\n"; - for {j in 1..9} - { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); - printf " %d", sum{k in 1..9} x[i,j,k] * k; - for {0..0: j = 9} printf(" |\n"); - } - for {0..0: i = 9} - printf " +-------+-------+-------+\n"; -} - -data; - -param id := 1; -end; diff --git a/resources/3rdparty/glpk-4.53/examples/sql/transp.sql b/resources/3rdparty/glpk-4.53/examples/sql/transp.sql deleted file mode 100644 index 873733303..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sql/transp.sql +++ /dev/null @@ -1,45 +0,0 @@ -CREATE DATABASE glpk; -CREATE USER glpk@localhost IDENTIFIED BY 'gnu'; -GRANT ALL PRIVILEGES ON glpk.* TO glpk@localhost; -USE glpk; -# production capacity -DROP TABLE transp_capa; -CREATE TABLE transp_capa ( - PLANT TEXT(127), - CAPA REAL, - PRIMARY KEY ( PLANT(127) ) - ); -INSERT INTO transp_capa ( PLANT, CAPA ) VALUES ( 'Seattle', 350 ); -INSERT INTO transp_capa ( PLANT, CAPA ) VALUES ( 'San Diego', 600 ); -# demand -DROP TABLE transp_demand; -CREATE TABLE transp_demand ( - MARKET TEXT(127), - DEMAND REAL, - PRIMARY KEY ( MARKET(127) ) - ); -INSERT INTO transp_demand ( MARKET, DEMAND ) VALUES ( 'New York', 325 ); -INSERT INTO transp_demand ( MARKET, DEMAND ) VALUES ( 'Chicago', 300 ); -INSERT INTO transp_demand ( MARKET, DEMAND ) VALUES ( 'Topeka', 275 ); -# distance -DROP TABLE transp_dist; -CREATE TABLE transp_dist ( - LOC1 TEXT(127), - LOC2 TEXT(127), - DIST REAL, - PRIMARY KEY ( LOC1(127), LOC2(127) ) - ); -INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'Seattle', 'New York', 2.5 ); -INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'Seattle', 'Chicago', 1.7 ); -INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'Seattle', 'Topeka', 1.8 ); -INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'San Diego', 'New York', 2.5 ); -INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'San Diego', 'Chicago', 1.8 ); -INSERT INTO transp_dist ( LOC1, LOC2, DIST ) VALUES ( 'San Diego', 'Topeka', 1.4 ); -# result -DROP TABLE transp_result; -CREATE TABLE transp_result ( - LOC1 TEXT(127), - LOC2 TEXT(127), - QUANTITY REAL, - PRIMARY KEY ( LOC1(127), LOC2(127) ) - ); diff --git a/resources/3rdparty/glpk-4.53/examples/sql/transp_mysql.mod b/resources/3rdparty/glpk-4.53/examples/sql/transp_mysql.mod deleted file mode 100644 index f375fa395..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sql/transp_mysql.mod +++ /dev/null @@ -1,71 +0,0 @@ -# A TRANSPORTATION PROBLEM -# -# This problem finds a least cost shipping schedule that meets -# requirements at markets and supplies at factories. -# -# References: -# Dantzig G B, "Linear Programming and Extensions." -# Princeton University Press, Princeton, New Jersey, 1963, -# Chapter 3-3. - -set I; -/* canning plants */ - -param a{i in I}; -/* capacity of plant i in cases */ - -table plants IN "MySQL" - 'Database=glpk;UID=glpk;PWD=gnu' - 'SELECT PLANT, CAPA AS CAPACITY FROM transp_capa' : - I <- [ PLANT ], a ~ CAPACITY; - -set J; -/* markets */ - -param b{j in J}; -/* demand at market j in cases */ - -table markets IN "MySQL" - 'Database=glpk;UID=glpk;PWD=gnu' - 'transp_demand' : - J <- [ MARKET ], b ~ DEMAND; - -param d{i in I, j in J}; -/* distance in thousands of miles */ - -table dist IN "MySQL" - 'Database=glpk;UID=glpk;PWD=gnu' - 'transp_dist' : - [ LOC1, LOC2 ], d ~ DIST; - -param f; -/* freight in dollars per case per thousand miles */ - -param c{i in I, j in J} := f * d[i,j] / 1000; -/* transport cost in thousands of dollars per case */ - -var x{i in I, j in J} >= 0; -/* shipment quantities in cases */ - -minimize cost: sum{i in I, j in J} c[i,j] * x[i,j]; -/* total transportation costs in thousands of dollars */ - -s.t. supply{i in I}: sum{j in J} x[i,j] <= a[i]; -/* observe supply limit at plant i */ - -s.t. demand{j in J}: sum{i in I} x[i,j] >= b[j]; -/* satisfy demand at market j */ - -solve; - -table result{i in I, j in J: x[i,j]} OUT "MySQL" - 'Database=glpk;UID=glpk;PWD=gnu' - 'DELETE FROM transp_result;' - 'INSERT INTO transp_result VALUES (?,?,?)' : - i ~ LOC1, j ~ LOC2, x[i,j] ~ QUANTITY; - -data; - -param f := 90; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/sql/transp_odbc.mod b/resources/3rdparty/glpk-4.53/examples/sql/transp_odbc.mod deleted file mode 100644 index 36d807e41..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sql/transp_odbc.mod +++ /dev/null @@ -1,72 +0,0 @@ -# A TRANSPORTATION PROBLEM -# -# This problem finds a least cost shipping schedule that meets -# requirements at markets and supplies at factories. -# -# References: -# Dantzig G B, "Linear Programming and Extensions." -# Princeton University Press, Princeton, New Jersey, 1963, -# Chapter 3-3. - -set I; -/* canning plants */ - -param a{i in I}; -/* capacity of plant i in cases */ - -table plants IN "iODBC" - 'DSN=glpk;UID=glpk;PWD=gnu' - 'SELECT PLANT, CAPA AS CAPACITY' - 'FROM transp_capa' : - I <- [ PLANT ], a ~ CAPACITY; - -set J; -/* markets */ - -param b{j in J}; -/* demand at market j in cases */ - -table markets IN "iODBC" - 'DSN=glpk;UID=glpk;PWD=gnu' - 'transp_demand' : - J <- [ MARKET ], b ~ DEMAND; - -param d{i in I, j in J}; -/* distance in thousands of miles */ - -table dist IN "iODBC" - 'DSN=glpk;UID=glpk;PWD=gnu' - 'transp_dist' : - [ LOC1, LOC2 ], d ~ DIST; - -param f; -/* freight in dollars per case per thousand miles */ - -param c{i in I, j in J} := f * d[i,j] / 1000; -/* transport cost in thousands of dollars per case */ - -var x{i in I, j in J} >= 0; -/* shipment quantities in cases */ - -minimize cost: sum{i in I, j in J} c[i,j] * x[i,j]; -/* total transportation costs in thousands of dollars */ - -s.t. supply{i in I}: sum{j in J} x[i,j] <= a[i]; -/* observe supply limit at plant i */ - -s.t. demand{j in J}: sum{i in I} x[i,j] >= b[j]; -/* satisfy demand at market j */ - -solve; - -table result{i in I, j in J: x[i,j]} OUT "iODBC" - 'DSN=glpk;UID=glpk;PWD=gnu' - 'DELETE FROM transp_result;' - 'INSERT INTO transp_result VALUES (?,?,?)' : - i ~ LOC1, j ~ LOC2, x[i,j] ~ QUANTITY; - -data; - -param f := 90; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/stigler.mod b/resources/3rdparty/glpk-4.53/examples/stigler.mod deleted file mode 100644 index 20c5d9d13..000000000 --- a/resources/3rdparty/glpk-4.53/examples/stigler.mod +++ /dev/null @@ -1,411 +0,0 @@ -/* STIGLER, original Stigler's 1939 diet problem */ - -/* The Stigler Diet is an optimization problem named for George Stigler, - a 1982 Nobel Laureate in economics, who posed the following problem: - For a moderately active man weighing 154 pounds, how much of each of - 77 foods should be eaten on a daily basis so that the man's intake of - nine nutrients will be at least equal to the recommended dietary - allowances (RDSs) suggested by the National Research Council in 1943, - with the cost of the diet being minimal? - - The nutrient RDAs required to be met in Stigler's experiment were - calories, protein, calcium, iron, vitamin A, thiamine, riboflavin, - niacin, and ascorbic acid. The result was an annual budget allocated - to foods such as evaporated milk, cabbage, dried navy beans, and beef - liver at a cost of approximately $0.11 a day in 1939 U.S. dollars. - - While the name "Stigler Diet" was applied after the experiment by - outsiders, according to Stigler, "No one recommends these diets for - anyone, let alone everyone." The Stigler diet has been much ridiculed - for its lack of variety and palatability, however his methodology has - received praise and is considered to be some of the earliest work in - linear programming. - - The Stigler diet question is a linear programming problem. Lacking - any sophisticated method of solving such a problem, Stigler was - forced to utilize heuristic methods in order to find a solution. The - diet question originally asked in which quantities a 154 pound male - would have to consume 77 different foods in order to fulfill the - recommended intake of 9 different nutrients while keeping expense at - a minimum. Through "trial and error, mathematical insight and - agility," Stigler was able to eliminate 62 of the foods from the - original 77 (these foods were removed based because they lacked - nutrients in comparison to the remaining 15). From the reduced list, - Stigler calculated the required amounts of each of the remaining 15 - foods to arrive at a cost-minimizing solution to his question. - According to Stigler's calculations, the annual cost of his solution - was $39.93 in 1939 dollars. When corrected for inflation using the - consumer price index, the cost of the diet in 2005 dollars is - $561.43. The specific combination of foods and quantities is as - follows: - - Stigler's 1939 Diet - - Food Annual Quantities Annual Cost - ---------------- ----------------- ----------- - Wheat Flour 370 lb. $13.33 - Evaporated Milk 57 cans 3.84 - Cabbage 111 lb. 4.11 - Spinach 23 lb. 1.85 - Dried Navy Beans 285 lb. 16.80 - ---------------------------------------------- - Total Annual Cost $39.93 - - The 9 nutrients that Stigler's diet took into consideration and their - respective recommended daily amounts were: - - Table of nutrients considered in Stigler's diet - - Nutrient Daily Recommended Intake - ------------------------- ------------------------ - Calories 3,000 Calories - Protein 70 grams - Calcium .8 grams - Iron 12 milligrams - Vitamin A 5,000 IU - Thiamine (Vitamin B1) 1.8 milligrams - Riboflavin (Vitamin B2) 2.7 milligrams - Niacin 18 milligrams - Ascorbic Acid (Vitamin C) 75 milligrams - - Seven years after Stigler made his initial estimates, the development - of George Dantzig's Simplex algorithm made it possible to solve the - problem without relying on heuristic methods. The exact value was - determined to be $39.69 (using the original 1939 data). Dantzig's - algorithm describes a method of traversing the vertices of a polytope - of N+1 dimensions in order to find the optimal solution to a specific - situation. - - (From Wikipedia, the free encyclopedia.) */ - -/* Translated from GAMS by Andrew Makhorin . - - For the original GAMS model stigler1939.gms see [3]. - - References: - - 1. George J. Stigler, "The Cost of Subsistence," J. Farm Econ. 27, - 1945, pp. 303-14. - - 2. National Research Council, "Recommended Daily Allowances," Reprint - and Circular Series No. 115, January, 1943. - - 3. Erwin Kalvelagen, "Model building with GAMS," Chapter 2, "Building - linear programming models," pp. 128-34. */ - -set C; -/* commodities */ - -check card(C) = 77; -/* there must be 77 commodities */ - -set N; -/* nutrients */ - -param data{c in C, {"price", "weight"} union N}; -/* nutritive values per dollar of expenditure */ - -param allowance{n in N}; -/* recommended daily allowance for a moderately active man */ - -var x{c in C}, >= 0; -/* dollars of food to be purchased daily */ - -s.t. nb{n in N}: sum{c in C} data[c,n] * x[c] >= allowance[n]; -/* nutrient balance */ - -minimize cost: sum{c in C} x[c]; -/* total food bill */ - -solve; - -param days := 365.25; -/* days in a year */ - -param commodity{c in C}, symbolic; - -param unit{c in C}, symbolic; - -printf "\n"; -printf "MINIMUM COST ANNUAL DIET\n"; -printf "\n"; -printf " Commodity Unit Quantity Cost \n"; -printf "------------------------- ---------- ---------- ----------\n"; -printf{c in C: x[c] != 0} "%-25s %10s %10.2f $%7.2f\n", commodity[c], - unit[c], 100 * days * x[c] / data[c,"price"], days * x[c]; -printf " -----------------\n"; -printf " Total: $%7.2f\n", - days * sum{c in C} x[c]; -printf "\n"; - -data; - -param : C : commodity unit := -flour "Wheat Flour (Enriched)" "10 lb." -macaroni "Macaroni" "1 lb." -cereal "Wheat Cereal (Enriched)" "28 oz." -cornflakes "Corn Flakes" "8 oz." -cornmeal "Corn Meal" "1 lb." -grits "Hominy Grits" "24 oz." -rice "Rice" "1 lb." -oats "Rolled Oats" "1 lb." -whitebread "White Bread (Enriched)" "1 lb." -wheatbread "Whole Wheat Bread" "1 lb." -ryebread "Rye Bread" "1 lb." -poundcake "Pound Cake" "1 lb." -crackers "Soda Crackers" "1 lb." -milk "Milk" "1 qt." -evapmild "Evaporated Milk (can)" "14.5 oz." -butter "Butter" "1 lb." -margarine "Oleomargarine" "1 lb." -eggs "Eggs" "1 doz." -cheese "Cheese (Cheddar)" "1 lb." -cream "Cream" "1/2 pt." -peanutbutter "Peanut Butter" "1 lb." -mayonnaise "Mayonnaise" "1/2 pt." -crisco "Crisco" "1 lb." -lard "Lard" "1 lb." -sirloinsteak "Sirloin Steak" "1 lb." -roundsteak "Round Steak" "1 lb." -ribroast "Rib Roast" "1 lb." -chuckroast "Chuck Roast" "1 lb." -plate "Plate" "1 lb." -liver "Liver (Beef)" "1 lb." -lambleg "Leg of Lamb" "1 lb." -lambchops "Lamb Chops (Rib)" "1 lb." -porkchops "Pork Chops" "1 lb." -porkroast "Pork Loin Roast" "1 lb." -bacon "Bacon" "1 lb." -ham "Ham - smoked" "1 lb." -saltpork "Salt Pork" "1 lb." -chicken "Roasting Chicken" "1 lb." -veal "Veal Cutlets" "1 lb." -salmon "Salmon, Pink (can)" "16 oz." -apples "Apples" "1 lb." -bananas "Bananas" "1 lb." -lemons "Lemons" "1 doz." -oranges "Oranges" "1 doz." -greenbeans "Green Beans" "1 lb." -cabbage "Cabbage" "1 lb." -carrots "Carrots" "1 bunch" -celery "Celery" "1 stalk" -lettuce "Lettuce" "1 head" -onions "Onions" "1 lb." -potatoes "Potatoes" "15 lb." -spinach "Spinach" "1 lb." -sweetpotato "Sweet Potatoes" "1 lb." -peaches "Peaches (can)" "No. 2 1/2" -pears "Pears (can)" "No. 2 1/2" -pineapple "Pineapple (can)" "No. 2 1/2" -asparagus "Asparagus (can)" "No. 2" -cannedgrbn "Grean Beans (can)" "No. 2" -porkbeans "Pork and Beans (can)" "16 oz." -corn "Corn (can)" "No. 2" -peas "Peas (can)" "No. 2" -tomatoes "Tomatoes (can)" "No. 2" -tomatosoup "Tomato Soup (can)" "10 1/2 oz." -driedpeach "Peaches, Dried" "1 lb." -prunes "Prunes, Dried" "1 lb." -raisins "Raisins, Dried" "15 oz." -driedpeas "Peas, Dried" "1 lb." -limabeans "Lima Beans, Dried" "1 lb." -navybeans "Navy Beans, Dried" "1 lb." -coffee "Coffee" "1 lb." -tea "Tea" "1/4 lb." -cocoa "Cocoa" "8 oz." -chocolate "Chocolate" "8 oz." -sugar "Sugar" "10 lb." -cornsirup "Corn Sirup" "24 oz." -molasses "Molasses" "18 oz." -strawberry "Strawberry Preserve" "1 lb." -; - -set N := -calories /* Calories, unit = 1000 */ -protein /* Protein, unit = grams */ -calcium /* Calcium, unit = grams */ -iron /* Iron, unit = milligrams */ -vitaminA /* Vitamin A, unit = 1000 International Units */ -thiamine /* Thiamine, Vit. B1, unit = milligrams */ -riboflavin /* Riboflavin, Vit. B2, unit = milligrams */ -niacin /* Niacin (Nicotinic Acid), unit = milligrams */ -ascorbicAcid /* Ascorbic Acid, Vit. C, unit = milligrams */ -; - -param data -: price weight calories protein calcium iron := -# aug. 15 edible -# 1939 per $1 -# (cents) (grams) (1000) (grams) (grams) (mg.) -flour 36.0 12600 44.7 1411 2.0 365 -macaroni 14.1 3217 11.6 418 .7 54 -cereal 24.2 3280 11.8 377 14.4 175 -cornflakes 7.1 3194 11.4 252 .1 56 -cornmeal 4.6 9861 36.0 897 1.7 99 -grits 8.5 8005 28.6 680 .8 80 -rice 7.5 6048 21.2 460 .6 41 -oats 7.1 6389 25.3 907 5.1 341 -whitebread 7.9 5742 15.6 488 2.5 115 -wheatbread 9.1 4985 12.2 484 2.7 125 -ryebread 9.2 4930 12.4 439 1.1 82 -poundcake 24.8 1829 8.0 130 .4 31 -crackers 15.1 3004 12.5 288 .5 50 -milk 11.0 8867 6.1 310 10.5 18 -evapmild 6.7 6035 8.4 422 15.1 9 -butter 20.8 1473 10.8 9 .2 3 -margarine 16.1 2817 20.6 17 .6 6 -eggs 32.6 1857 2.9 238 1.0 52 -cheese 24.2 1874 7.4 448 16.4 19 -cream 14.1 1689 3.5 49 1.7 3 -peanutbutter 17.9 2534 15.7 661 1.0 48 -mayonnaise 16.7 1198 8.6 18 .2 8 -crisco 20.3 2234 20.1 0 .0 0 -lard 9.8 4628 41.7 0 .0 0 -sirloinsteak 39.6 1145 2.9 166 .1 34 -roundsteak 36.4 1246 2.2 214 .1 32 -ribroast 29.2 1553 3.4 213 .1 33 -chuckroast 22.6 2007 3.6 309 .2 46 -plate 14.6 3107 8.5 404 .2 62 -liver 26.8 1692 2.2 333 .2 139 -lambleg 27.6 1643 3.1 245 .1 20 -lambchops 36.6 1239 3.3 140 .1 15 -porkchops 30.7 1477 3.5 196 .2 80 -porkroast 24.2 1874 4.4 249 .3 37 -bacon 25.6 1772 10.4 152 .2 23 -ham 27.4 1655 6.7 212 .2 31 -saltpork 16.0 2835 18.8 164 .1 26 -chicken 30.3 1497 1.8 184 .1 30 -veal 42.3 1072 1.7 156 .1 24 -salmon 13.0 3489 5.8 705 6.8 45 -apples 4.4 9072 5.8 27 .5 36 -bananas 6.1 4982 4.9 60 .4 30 -lemons 26.0 2380 1.0 21 .5 14 -oranges 30.9 4439 2.2 40 1.1 18 -greenbeans 7.1 5750 2.4 138 3.7 80 -cabbage 3.7 8949 2.6 125 4.0 36 -carrots 4.7 6080 2.7 73 2.8 43 -celery 7.3 3915 .9 51 3.0 23 -lettuce 8.2 2247 .4 27 1.1 22 -onions 3.6 11844 5.8 166 3.8 59 -potatoes 34.0 16810 14.3 336 1.8 118 -spinach 8.1 4592 1.1 106 .0 138 -sweetpotato 5.1 7649 9.6 138 2.7 54 -peaches 16.8 4894 3.7 20 .4 10 -pears 20.4 4030 3.0 8 .3 8 -pineapple 21.3 3993 2.4 16 .4 8 -asparagus 27.7 1945 .4 33 .3 12 -cannedgrbn 10.0 5386 1.0 54 2.0 65 -porkbeans 7.1 6389 7.5 364 4.0 134 -corn 10.4 5452 5.2 136 .2 16 -peas 13.8 4109 2.3 136 .6 45 -tomatoes 8.6 6263 1.3 63 .7 38 -tomatosoup 7.6 3917 1.6 71 .6 43 -driedpeach 15.7 2889 8.5 87 1.7 173 -prunes 9.0 4284 12.8 99 2.5 154 -raisins 9.4 4524 13.5 104 2.5 136 -driedpeas 7.9 5742 20.0 1367 4.2 345 -limabeans 8.9 5097 17.4 1055 3.7 459 -navybeans 5.9 7688 26.9 1691 11.4 792 -coffee 22.4 2025 .0 0 .0 0 -tea 17.4 652 .0 0 .0 0 -cocoa 8.6 2637 8.7 237 3.0 72 -chocolate 16.2 1400 8.0 77 1.3 39 -sugar 51.7 8773 34.9 0 .0 0 -cornsirup 13.7 4996 14.7 0 .5 74 -molasses 13.6 3752 9.0 0 10.3 244 -strawberry 20.5 2213 6.4 11 .4 7 - -: vitaminA thiamine riboflavin niacin ascorbicAcid := -# (1000 IU) (mg.) (mg.) (mg.) (mg.) -flour .0 55.4 33.3 441 0 -macaroni .0 3.2 1.9 68 0 -cereal .0 14.4 8.8 114 0 -cornflakes .0 13.5 2.3 68 0 -cornmeal 30.9 17.4 7.9 106 0 -grits .0 10.6 1.6 110 0 -rice .0 2.0 4.8 60 0 -oats .0 37.1 8.9 64 0 -whitebread .0 13.8 8.5 126 0 -wheatbread .0 13.9 6.4 160 0 -ryebread .0 9.9 3.0 66 0 -poundcake 18.9 2.8 3.0 17 0 -crackers .0 .0 .0 0 0 -milk 16.8 4.0 16.0 7 177 -evapmild 26.0 3.0 23.5 11 60 -butter 44.2 .0 .2 2 0 -margarine 55.8 .2 .0 0 0 -eggs 18.6 2.8 6.5 1 0 -cheese 28.1 .8 10.3 4 0 -cream 16.9 .6 2.5 0 17 -peanutbutter .0 9.6 8.1 471 0 -mayonnaise 2.7 .4 .5 0 0 -crisco .0 .0 .0 0 0 -lard .2 .0 .5 5 0 -sirloinsteak .2 2.1 2.9 69 0 -roundsteak .4 2.5 2.4 87 0 -ribroast .0 .0 2.0 0 0 -chuckroast .4 1.0 4.0 120 0 -plate .0 .9 .0 0 0 -liver 169.2 6.4 50.8 316 525 -lambleg .0 2.8 3.0 86 0 -lambchops .0 1.7 2.7 54 0 -porkchops .0 17.4 2.7 60 0 -porkroast .0 18.2 3.6 79 0 -bacon .0 1.8 1.8 71 0 -ham .0 9.9 3.3 50 0 -saltpork .0 1.4 1.8 0 0 -chicken .1 .9 1.8 68 46 -veal .0 1.4 2.4 57 0 -salmon 3.5 1.0 4.9 209 0 -apples 7.3 3.6 2.7 5 544 -bananas 17.4 2.5 3.5 28 498 -lemons .0 .5 .0 4 952 -oranges 11.1 3.6 1.3 10 1993 -greenbeans 69.0 4.3 5.8 37 862 -cabbage 7.2 9.0 4.5 26 5369 -carrots 188.5 6.1 4.3 89 608 -celery .9 1.4 1.4 9 313 -lettuce 112.4 1.8 3.4 11 449 -onions 16.6 4.7 5.9 21 1184 -potatoes 6.7 29.4 7.1 198 2522 -spinach 918.4 5.7 13.8 33 2755 -sweetpotato 290.7 8.4 5.4 83 1912 -peaches 21.5 .5 1.0 31 196 -pears .8 .8 .8 5 81 -pineapple 2.0 2.8 .8 7 399 -asparagus 16.3 1.4 2.1 17 272 -cannedgrbn 53.9 1.6 4.3 32 431 -porkbeans 3.5 8.3 7.7 56 0 -corn 12.0 1.6 2.7 42 218 -peas 34.9 4.9 2.5 37 370 -tomatoes 53.2 3.4 2.5 36 1253 -tomatosoup 57.9 3.5 2.4 67 862 -driedpeach 86.8 1.2 4.3 55 57 -prunes 85.7 3.9 4.3 65 257 -raisins 4.5 6.3 1.4 24 136 -driedpeas 2.9 28.7 18.4 162 0 -limabeans 5.1 26.9 38.2 93 0 -navybeans .0 38.4 24.6 217 0 -coffee .0 4.0 5.1 50 0 -tea .0 .0 2.3 42 0 -cocoa .0 2.0 11.9 40 0 -chocolate .0 .9 3.4 14 0 -sugar .0 .0 .0 0 0 -cornsirup .0 .0 .0 5 0 -molasses .0 1.9 7.5 146 0 -strawberry .2 .2 .4 3 0 -; - -param allowance := -calories 3 -protein 70 -calcium .8 -iron 12 -vitaminA 5 -thiamine 1.8 -riboflavin 2.7 -niacin 18 -ascorbicAcid 75 -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/sudoku.dat b/resources/3rdparty/glpk-4.53/examples/sudoku.dat deleted file mode 100644 index 074ff4f8f..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sudoku.dat +++ /dev/null @@ -1,16 +0,0 @@ -/* sudoku.dat, a hard Sudoku puzzle which causes branching */ - -data; - -param givens : 1 2 3 4 5 6 7 8 9 := - 1 1 . . . . . 7 . . - 2 . 2 . . . . 5 . . - 3 6 . . 3 8 . . . . - 4 . 7 8 . . . . . . - 5 . . . 6 . 9 . . . - 6 . . . . . . 1 4 . - 7 . . . . 2 5 . . 9 - 8 . . 3 . . . . 6 . - 9 . . 4 . . . . . 2 ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/sudoku.mod b/resources/3rdparty/glpk-4.53/examples/sudoku.mod deleted file mode 100644 index 61f2fe2bf..000000000 --- a/resources/3rdparty/glpk-4.53/examples/sudoku.mod +++ /dev/null @@ -1,84 +0,0 @@ -/* SUDOKU, Number Placement Puzzle */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* Sudoku, also known as Number Place, is a logic-based placement - puzzle. The aim of the canonical puzzle is to enter a numerical - digit from 1 through 9 in each cell of a 9x9 grid made up of 3x3 - subgrids (called "regions"), starting with various digits given in - some cells (the "givens"). Each row, column, and region must contain - only one instance of each numeral. - - Example: - - +-------+-------+-------+ - | 5 3 . | . 7 . | . . . | - | 6 . . | 1 9 5 | . . . | - | . 9 8 | . . . | . 6 . | - +-------+-------+-------+ - | 8 . . | . 6 . | . . 3 | - | 4 . . | 8 . 3 | . . 1 | - | 7 . . | . 2 . | . . 6 | - +-------+-------+-------+ - | . 6 . | . . . | 2 8 . | - | . . . | 4 1 9 | . . 5 | - | . . . | . 8 . | . 7 9 | - +-------+-------+-------+ - - (From Wikipedia, the free encyclopedia.) */ - -param givens{1..9, 1..9}, integer, >= 0, <= 9, default 0; -/* the "givens" */ - -var x{i in 1..9, j in 1..9, k in 1..9}, binary; -/* x[i,j,k] = 1 means cell [i,j] is assigned number k */ - -s.t. fa{i in 1..9, j in 1..9, k in 1..9: givens[i,j] != 0}: - x[i,j,k] = (if givens[i,j] = k then 1 else 0); -/* assign pre-defined numbers using the "givens" */ - -s.t. fb{i in 1..9, j in 1..9}: sum{k in 1..9} x[i,j,k] = 1; -/* each cell must be assigned exactly one number */ - -s.t. fc{i in 1..9, k in 1..9}: sum{j in 1..9} x[i,j,k] = 1; -/* cells in the same row must be assigned distinct numbers */ - -s.t. fd{j in 1..9, k in 1..9}: sum{i in 1..9} x[i,j,k] = 1; -/* cells in the same column must be assigned distinct numbers */ - -s.t. fe{I in 1..9 by 3, J in 1..9 by 3, k in 1..9}: - sum{i in I..I+2, j in J..J+2} x[i,j,k] = 1; -/* cells in the same region must be assigned distinct numbers */ - -/* there is no need for an objective function here */ - -solve; - -for {i in 1..9} -{ for {0..0: i = 1 or i = 4 or i = 7} - printf " +-------+-------+-------+\n"; - for {j in 1..9} - { for {0..0: j = 1 or j = 4 or j = 7} printf(" |"); - printf " %d", sum{k in 1..9} x[i,j,k] * k; - for {0..0: j = 9} printf(" |\n"); - } - for {0..0: i = 9} - printf " +-------+-------+-------+\n"; -} - -data; - -/* These data correspond to the example above. */ - -param givens : 1 2 3 4 5 6 7 8 9 := - 1 5 3 . . 7 . . . . - 2 6 . . 1 9 5 . . . - 3 . 9 8 . . . . 6 . - 4 8 . . . 6 . . . 3 - 5 4 . . 8 . 3 . . 1 - 6 7 . . . 2 . . . 6 - 7 . 6 . . . . 2 8 . - 8 . . . 4 1 9 . . 5 - 9 . . . . 8 . . 7 9 ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/t1.cs b/resources/3rdparty/glpk-4.53/examples/t1.cs deleted file mode 100644 index d07780f4e..000000000 --- a/resources/3rdparty/glpk-4.53/examples/t1.cs +++ /dev/null @@ -1,99 +0,0 @@ -/*Find the minimum value which satisfies the linear inequality: - a*x + b*y >= 1 {a,b,x,y Integers} {a,b > 0} {a,b entered on command line} - - Nigel_Galloway@operamail.com - February 2008 -*/ -using System; -using System.Runtime.InteropServices; - -unsafe class GLPK{ - double *lp; - public int a; - public int b; - - const string glpkLibrary = "libglpk.so"; - readonly int GLP_FR = 1; - readonly int GLP_IV = 2; - readonly int GLP_DB = 4; - struct ConstraintMatrix{ - public fixed int ia[3]; - public fixed int ja[3]; - public fixed double ar[3]; - } - [DllImport(glpkLibrary, SetLastError=true)] - static extern double* glp_create_prob(); - [DllImport(glpkLibrary, SetLastError=true)] - static extern void glp_add_rows(double* lp, int rows); - [DllImport(glpkLibrary, SetLastError=true)] - static extern void glp_add_cols(double* lp, int cols); - [DllImport(glpkLibrary, SetLastError=true)] - static extern void glp_set_col_bnds(double* lp, int col, int bound_type, double lower_bound, double upper_bound); - [DllImport(glpkLibrary, SetLastError=true)] - static extern void glp_set_col_kind(double* lp, int col, int kind); - [DllImport(glpkLibrary, SetLastError=true)] - static extern void glp_load_matrix(double* lp, int elements, int* ia, int* ja, double* ar); - public GLPK(int a, int b){ - this.a = a; - this.b = b; - lp = glp_create_prob(); - //Col 1 is x, Col 2 is y - glp_add_rows(lp, 1); - glp_add_cols(lp, 2); - glp_set_col_bnds(lp, 1, GLP_FR, 0.0, 0.0); - glp_set_col_bnds(lp, 2, GLP_FR, 0.0, 0.0); - glp_set_col_kind(lp, 1, GLP_IV); - glp_set_col_kind(lp, 2, GLP_IV); - //Row 1 is a*x + b*y - ConstraintMatrix CM = new ConstraintMatrix(); - CM.ia[1]=1; CM.ja[1]=1; CM.ar[1]=a; - CM.ia[2]=1; CM.ja[2]=2; CM.ar[2]=b; - glp_load_matrix(lp, 2, CM.ia, CM.ja, CM.ar); - Console.WriteLine("Hello Nigel"); - } - - [DllImport(glpkLibrary, SetLastError=true)] - static extern void glp_set_row_bnds(double* lp, int row, int bound_type, double lower_bound, double upper_bound); - [DllImport(glpkLibrary, SetLastError=true)] - static extern void glp_simplex(double* lp, void* options); - [DllImport(glpkLibrary, SetLastError=true)] - static extern void glp_intopt(double* lp, void* options); - [DllImport(glpkLibrary, SetLastError=true)] - static extern double glp_mip_col_val(double* lp, int col); - public int betterGuess(int upper_bound){ - //Find a new guess less than the old guess: 1 <= (a*x + b*y) <= (old guess - 1) - glp_set_row_bnds(lp, 1, GLP_DB, 1.0, ((double)upper_bound)-0.5); - glp_simplex(lp, null); - glp_intopt(lp, null); - int x = (int)glp_mip_col_val(lp, 1); - int y = (int)glp_mip_col_val(lp, 2); - int nextGuess = a*x + b*y; - Console.WriteLine("x = {0}, y = {1}, a*x + b*y = {2}",x,y,nextGuess); - return nextGuess; - } - - [DllImport(glpkLibrary, SetLastError=true)] - static extern void glp_delete_prob(double* lp); - ~GLPK(){ - glp_delete_prob(lp); - Console.WriteLine("Goodbye Nigel"); - } - -} - -class test{ - static bool isMinimum(int a, int b, int guess){ - Console.WriteLine("Trying {0}",guess); - if (a%guess > 0) return false; - if (b%guess > 0) return false; - Console.WriteLine("Solution is {0}",guess); - return true; - } - - public static void Main(string[] args){ - Console.WriteLine("a = {0}, b = {1}",args[0], args[1]); - GLPK lp = new GLPK(Int32.Parse(args[0]),Int32.Parse(args[1])); - int guess = (lp.a > lp.b) ? lp.b : lp.a; - while (!isMinimum(lp.a,lp.b,guess)) guess = lp.betterGuess(guess); - } -} diff --git a/resources/3rdparty/glpk-4.53/examples/tas.mod b/resources/3rdparty/glpk-4.53/examples/tas.mod deleted file mode 100644 index dbb5ac2da..000000000 --- a/resources/3rdparty/glpk-4.53/examples/tas.mod +++ /dev/null @@ -1,486 +0,0 @@ -/* TAS, Tail Assignment Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* The Tail Assignment Problem (TAS) is to construct rosters for a set - of aircrafts (tails), which cover all flights for a given scheduling - period. - - This model includes only flight connection constraints while other - constraints (for example, maintenance constraints) are ignored. Such - simplification allows using a single commodity network to model the - problem, where commodity corresponds to the set of aircrafts. - - Nodes of the network are activities. They include all flights plus - two dummy nodes (activities): source node, s, corresponding to - initial activity of each aircraft, and sink node t, corresponding to - final activity of each aircraft. Arc v->v' exists in the network if - and only if the same aircraft is able to operate activity v and then - immediately activity v'. In partucular, arcs s->f and f->t exist for - all flights f. Arcs f->f', where f and f' are some flights, exist - only if the connection time (which is the difference between the - departure time of f' and the arrival time of f) is not less than a - given minimal connection time. - - Reference: - M. Groenkvist, "The Tail Assignment Problem," Dept. of Comp. Sci. - and Eng., Chalmers University of Technology and Goeteborg University, - Goeteborg, Sweden, August 2005. */ - -######################################################################## - -param nf, integer, > 0; -/* number of flights */ - -set F := 1..nf; -/* set of flights (for a given period from timetable) */ - -param hub{f in F}, in {1, 2}; -/* hub[f] = 1: Sheremetyevo-1 - hub[f] = 2: Sheremetyevo-2 */ - -param dest{f in F}, symbolic; -/* destination airport (IATA code) */ - -param fno1{f in F}, integer; -/* first leg flight number */ - -param dep1{f in F}, integer, >= 0; -/* departure time from Sheremetyevo airport, in minutes */ - -check{f in F: f < nf}: dep1[f] <= dep1[f+1]; -/* all flights must be ordered by ascending of the departure time */ - -param arr1{f in F}, integer, >= 0; -/* arrival time to destination airport, in minutes */ - -param fno2{f in F}, integer; -/* second leg flight number */ - -param dep2{f in F}, integer, >= 0; -/* departure time from destination airport, in minutes */ - -param arr2{f in F}, integer, >= 0; -/* arrival time to Sheremetyevo airport, in minutes */ - -param mct1, integer, >= 0, default 80; -/* minimal connection time (within SVO1 or SVO2), in minutes */ - -param mct2, integer, >= 0, default 150; -/* minimal connection time (between SVO1 and SVO2), in minutes */ - -set E := setof{f in F, ff in F: arr2[f] + (if hub[f] = hub[ff] then - mct1 else mct2) <= dep1[ff]} (f, ff); -/* connection network; arc f->ff is in E, iff the same aircraft can be - assigned to flight f and then immediately to flight ff */ - -var s{f in F}, >= 0; -/* s[f] is a flow from source node to node f */ - -var x{(f,ff) in E}, >= 0; -/* x[f,ff] is a flow from node f to node ff */ - -var t{f in F}, >= 0; -/* t[f] is a flow from node f to sink node */ - -s.t. into{f in F}: s[f] + sum{(ff,f) in E} x[ff,f] = 1; -/* exactly one aircraft must come into each node f */ - -s.t. from{f in F}: t[f] + sum{(f,ff) in E} x[f,ff] = 1; -/* exactly one aircraft must come from each node f */ - -minimize obj: sum{f in F} s[f]; -/* minimize the number aircrafts sufficient to cover all flights */ - -solve; - -######################################################################## - -param na := floor(sum{f in F} s[f] + .5); -/* minimal number of aircrafts found */ - -printf "At least %d aircrafts needed\n", na; - -set A := 1..na; -/* set of aircrafts */ - -printf "Building rosters...\n"; - -param tail{f in F}, in A, := -/* tail[f] is the number of an aircraft assigned to flight f */ - - if f = 1 then 1 - /* assign aircraft 1 to the earliest flight */ - - else if s[f] >= 0.9 then (max{ff in 1..f-1} tail[ff]) + 1 - /* if f is the first flight in a roster, assign to it a next - aircraft */ - - else sum{(ff,f) in E} tail[ff] * (if x[ff,f] >= 0.9 then 1); - /* otherwise, assign to flight f the same aircraft, which is - assigned to a preceding flight in the roster */ - -######################################################################## - -param file, symbolic, default "tas.ps"; -/* file to output the assignment chart in postscript format */ - -param title, symbolic, default "(no title)"; -/* chart title */ - -param left, default 25; -/* left margin, in mm */ - -param top, default 25; -/* top margin, in mm */ - -param right, default 20; -/* right margin, in mm */ - -param bottom, default 15; -/* bottom margin, in mm */ - -param sx := 297 - left - right; -/* chart area horizontal size, in mm */ - -param sy := 210 - top - bottom; -/* chart area vertical size, in mm */ - -param gap, default sy / (na - 1); -/* gap between rosters, in mm */ - -printf "Writing assignment chart to %s...\n", file; - -printf "%%!PS-Adobe-3.0\n" > file; -printf "%%%%Title: Tail Assignment Chart\n" >> file; -printf "%%%%Creator: GLPK MathProg\n" >> file; -printf "%%%%BoundingBox: 0 0 595 842\n" >> file; -printf "%%%%EndComments\n" >> file; -printf "<> setpagedevice\n" >> file; -printf "72 25.4 div dup scale\n" >> file; -printf "210 %.3f sub %.3f translate\n", bottom, left >> file; -printf "90 rotate\n" >> file; - -printf "/HelveticaBold findfont 5 scalefont setfont\n" >> file; -printf "%.3f %.3f moveto (%s) dup show\n", 0, sy + 5, title >> file; - -param period := floor((max{f in F} arr2[f]) / 60. + .5); -/* period duration, in hours */ - -/* vertical bars */ -printf ".8 .8 .8 setrgbcolor\n" >> file; -for {tt in 0..period} -{ printf "%s setlinewidth\n", - if tt mod 24 = 0 then ".5" else "0" >> file; - printf "newpath %.3f %.3f moveto %.3f %.3f lineto stroke\n", - tt * (sx / period), 0, tt * (sx / period), - sy + (if tt mod 24 = 0 then 2) >> file; -} - -/* rosters */ -for {a in A} -{ printf "0 0 0 setrgbcolor\n" >> file; - printf "0 setlinewidth\n" >> file; - printf "newpath %.3f %.3f moveto %.3f %.3f lineto stroke\n", - 0, sy - gap * (a - 1), sx, sy - gap * (a - 1) >> file; - printf "/Dingbats findfont 4 scalefont setfont\n" >> file; - printf "%.3f %.3f moveto <28> dup show\n", - -4, sy - gap * (a - 1) - 1.4, a >> file; - printf "/Helvetica findfont 3 scalefont setfont\n" >> file; - printf "%.3f %.3f moveto (%2d) dup show\n", - -9, sy - gap * (a - 1) - 1.2, a >> file; - for {f in F: tail[f] == a} - { printf "0 0 %s setrgbcolor\n", - if hub[f] = 1 then "0" else ".8" >> file; - printf "1 setlinewidth\n" >> file; - printf "newpath %.3f %.3f moveto %.3f %.3f lineto stroke\n", - dep1[f] / 60 * (sx / period), sy - gap * (a - 1), - arr2[f] / 60 * (sx / period), sy - gap * (a - 1) >> file; - printf "/Helvetica findfont 1.8 scalefont setfont\n" >> file; - printf "%.3f %.3f moveto (%02d:%02d %s) dup show\n", - dep1[f] / 60 * (sx / period), sy - gap * (a - 1) + .8, - (dep1[f] mod 1440) div 60, (dep1[f] mod 1440) mod 60, - dest[f] >> file; - printf "%.3f %.3f moveto (%d %02d:%02d) dup show\n", - dep1[f] / 60 * (sx / period), sy - gap * (a - 1) - 2.1, - fno1[f], - (arr2[f] mod 1440) div 60, (arr2[f] mod 1440) mod 60 >> file; - } -} - -printf "showpage\n" >> file; -printf "%%%%EOF\n" >> file; - -######################################################################## - -data; - -param title := "Tu-154 [from 2008-08-18 to 2008-08-24]"; - -param nf := 261; - -param : hub dest fno1 dep1 arr1 fno2 dep2 arr2 := - 1 1 IKT 743 195 520 744 610 970 - 2 1 OMS 815 205 405 816 485 700 - 3 1 CEK 897 205 360 898 430 595 - 4 1 KRR 763 260 400 764 480 610 - 5 2 SIP 133 280 420 134 500 620 - 6 2 BUD 131 290 450 132 520 675 - 7 1 AAQ 701 305 440 702 510 640 - 8 1 MRV 785 310 440 786 520 650 - 9 2 WAW 101 355 475 102 540 660 - 10 2 GYD 147 370 550 148 675 860 - 11 1 AER 869 385 530 870 655 795 - 12 1 KRR 765 430 560 766 630 760 - 13 1 AAQ 703 520 660 704 740 850 - 14 1 LED 845 530 620 846 690 775 - 15 1 KRR 767 540 675 768 765 895 - 16 2 KBP 183 665 760 184 850 940 - 17 1 MRV 787 755 905 788 985 1135 - 18 1 KRR 771 810 940 772 1030 1165 - 19 1 LED 849 825 900 850 960 1095 - 20 2 IST 209 880 1050 210 1120 1280 - 21 1 AER 873 885 1030 874 1760 1900 - 22 1 ASF 711 995 1145 712 1640 1795 - 23 2 ULN 563 995 1335 564 1415 1815 - 24 2 OTP 151 1020 1175 152 1800 1940 - 25 2 BEY 509 1025 1265 510 1350 1580 - 26 2 OSL 211 1060 1220 212 1860 2015 - 27 1 IKT 739 1085 1420 740 1510 1870 - 28 1 KRR 773 1095 1240 774 1620 1765 - 29 1 SGC 877 1120 1315 878 1395 1625 - 30 1 LED 857 1150 1230 858 1610 1690 - 31 1 CEK 899 1230 1385 900 1455 1620 - 32 1 PEE 821 1235 1390 822 1450 1600 - 33 2 TBS 197 1240 1405 198 1560 1715 - 34 1 UFA 891 1275 1405 892 1475 1610 - 35 1 KJA 781 1300 1570 782 1680 1990 - 36 1 IKT 743 1635 1960 744 2050 2410 - 37 1 OMS 815 1645 1845 816 1925 2140 - 38 1 CEK 897 1645 1800 898 1870 2035 - 39 1 KRR 763 1700 1840 764 1920 2050 - 40 2 SIP 133 1720 1860 134 1940 2060 - 41 2 BUD 131 1730 1890 132 1960 2115 - 42 1 AAQ 701 1745 1880 702 1950 2080 - 43 1 MRV 785 1750 1880 786 1960 2090 - 44 2 WAW 101 1795 1915 102 1980 2100 - 45 2 GYD 147 1810 1990 148 2115 2300 - 46 1 AER 869 1825 1970 870 2095 2235 - 47 2 EVN 193 1850 2030 194 2105 2275 - 48 1 KRR 765 1870 2000 766 2070 2200 - 49 1 AAQ 703 1960 2100 704 2180 2290 - 50 1 LED 845 1970 2060 846 2130 2215 - 51 1 KRR 767 1980 2115 768 2205 2335 - 52 2 KBP 183 2105 2200 184 2290 2380 - 53 1 MRV 787 2195 2345 788 2425 2575 - 54 1 KRR 771 2250 2380 772 2470 2605 - 55 1 LED 849 2265 2340 850 2400 2535 - 56 2 IST 209 2320 2490 210 2560 2720 - 57 1 AER 873 2325 2470 874 3200 3340 - 58 2 ULN 563 2435 2775 564 2855 3255 - 59 1 ASF 711 2435 2585 712 3080 3235 - 60 2 DAM 517 2465 2705 518 2790 3020 - 61 2 OSL 211 2500 2660 212 3300 3455 - 62 2 KBP 185 2510 2610 186 3160 3250 - 63 1 IKT 739 2525 2860 740 2950 3310 - 64 1 KRR 773 2535 2680 774 3060 3205 - 65 1 SGC 877 2560 2755 878 2835 3065 - 66 1 LED 857 2590 2670 858 3050 3130 - 67 1 CEK 899 2670 2825 900 2895 3060 - 68 1 PEE 821 2675 2830 822 2890 3040 - 69 2 TBS 197 2680 2845 198 3000 3155 - 70 1 UFA 891 2715 2845 892 2915 3050 - 71 1 KJA 781 2740 3010 782 3120 3430 - 72 1 IKT 743 3075 3400 744 3490 3850 - 73 1 CEK 897 3085 3240 898 3310 3475 - 74 1 OMS 815 3085 3285 816 3365 3580 - 75 1 KRR 763 3140 3280 764 3360 3490 - 76 2 SIP 133 3160 3300 134 3380 3500 - 77 2 BUD 131 3170 3330 132 3400 3555 - 78 1 AAQ 701 3185 3320 702 3390 3520 - 79 1 MRV 785 3190 3320 786 3400 3530 - 80 2 WAW 101 3235 3355 102 3420 3540 - 81 2 FRU 181 3245 3495 182 3590 3860 - 82 2 GYD 147 3250 3430 148 3555 3740 - 83 1 AER 869 3265 3410 870 3535 3675 - 84 1 KRR 765 3310 3440 766 3510 3640 - 85 1 AAQ 703 3400 3540 704 3620 3730 - 86 1 LED 845 3410 3500 846 3570 3655 - 87 1 KRR 767 3420 3555 768 3645 3775 - 88 2 KBP 183 3545 3640 184 3730 3820 - 89 1 MRV 787 3635 3785 788 3865 4015 - 90 1 KRR 771 3690 3820 772 3910 4045 - 91 1 LED 849 3705 3780 850 3840 3975 - 92 2 IST 209 3760 3930 210 4000 4160 - 93 1 AER 873 3765 3910 874 4640 4780 - 94 2 ULN 563 3875 4215 564 4295 4695 - 95 1 ASF 711 3875 4025 712 4520 4675 - 96 2 OTP 151 3900 4055 152 4680 4820 - 97 2 BEY 509 3905 4145 510 4230 4460 - 98 2 OSL 211 3940 4100 212 4740 4895 - 99 2 KBP 185 3950 4050 186 4600 4690 - 100 1 IKT 739 3965 4300 740 4390 4750 - 101 1 KRR 773 3975 4120 774 4500 4645 - 102 1 SGC 877 4000 4195 878 4275 4505 - 103 1 LED 857 4030 4110 858 4490 4570 - 104 1 CEK 899 4110 4265 900 4335 4500 - 105 1 PEE 821 4115 4270 822 4330 4480 - 106 2 TBS 197 4120 4285 198 4440 4595 - 107 1 UFA 891 4155 4285 892 4355 4490 - 108 1 KJA 781 4180 4450 782 4560 4870 - 109 1 IKT 743 4515 4840 744 4930 5290 - 110 1 OMS 815 4525 4725 816 4805 5020 - 111 1 CEK 897 4525 4680 898 4750 4915 - 112 1 KRR 763 4580 4720 764 4800 4930 - 113 2 SIP 133 4600 4740 134 4820 4940 - 114 2 BUD 131 4610 4770 132 4840 4995 - 115 1 AAQ 701 4625 4760 702 4830 4960 - 116 1 MRV 785 4630 4760 786 4840 4970 - 117 2 WAW 101 4675 4795 102 4860 4980 - 118 2 GYD 147 4690 4870 148 4995 5180 - 119 1 AER 869 4705 4850 870 4975 5115 - 120 2 EVN 193 4730 4910 194 4985 5155 - 121 1 KRR 765 4750 4880 766 4950 5080 - 122 1 AAQ 703 4840 4980 704 5060 5170 - 123 1 LED 845 4850 4940 846 5010 5095 - 124 1 KRR 767 4860 4995 768 5085 5215 - 125 2 KBP 183 4985 5080 184 5170 5260 - 126 1 MRV 787 5075 5225 788 5305 5455 - 127 1 KRR 771 5130 5260 772 5350 5485 - 128 1 LED 849 5145 5220 850 5280 5415 - 129 2 IST 209 5200 5370 210 5440 5600 - 130 1 AER 873 5205 5350 874 6080 6220 - 131 1 ASF 711 5315 5465 712 5960 6115 - 132 2 ULN 563 5315 5655 564 5735 6135 - 133 2 DAM 517 5345 5585 518 5670 5900 - 134 2 OSL 211 5380 5540 212 6180 6335 - 135 2 KBP 185 5390 5490 186 6040 6130 - 136 1 IKT 739 5405 5740 740 5830 6190 - 137 1 KRR 773 5415 5560 774 5940 6085 - 138 1 SGC 877 5440 5635 878 5715 5945 - 139 1 LED 857 5470 5550 858 5930 6010 - 140 1 CEK 899 5550 5705 900 5775 5940 - 141 1 PEE 821 5555 5710 822 5770 5920 - 142 2 TBS 197 5560 5725 198 5880 6035 - 143 1 UFA 891 5595 5725 892 5795 5930 - 144 1 KJA 781 5620 5890 782 6000 6310 - 145 1 IKT 743 5955 6280 744 6370 6730 - 146 1 OMS 815 5965 6165 816 6245 6460 - 147 1 CEK 897 5965 6120 898 6190 6355 - 148 1 KRR 763 6020 6160 764 6240 6370 - 149 2 SIP 133 6040 6180 134 6260 6380 - 150 2 BUD 131 6050 6210 132 6280 6435 - 151 1 AAQ 701 6065 6200 702 6270 6400 - 152 1 MRV 785 6070 6200 786 6280 6410 - 153 2 WAW 101 6115 6235 102 6300 6420 - 154 2 FRU 181 6125 6375 182 6470 6740 - 155 2 GYD 147 6130 6310 148 6435 6620 - 156 1 AER 869 6145 6290 870 6415 6555 - 157 2 EVN 193 6170 6350 194 6425 6595 - 158 1 KRR 765 6190 6320 766 6390 6520 - 159 1 AAQ 703 6280 6420 704 6500 6610 - 160 1 LED 845 6290 6380 846 6450 6535 - 161 1 KRR 767 6300 6435 768 6525 6655 - 162 2 KBP 183 6425 6520 184 6610 6700 - 163 2 AYT 223 6500 6690 224 6750 6940 - 164 1 AER 867 6510 6660 868 6730 6880 - 165 1 MRV 787 6515 6665 788 6745 6895 - 166 1 KRR 771 6570 6700 772 6790 6925 - 167 1 LED 849 6585 6660 850 6720 6855 - 168 2 IST 209 6640 6810 210 6880 7040 - 169 1 AER 873 6645 6790 874 7520 7660 - 170 1 ASF 711 6755 6905 712 7400 7555 - 171 2 ULN 563 6755 7095 564 7175 7575 - 172 2 OTP 151 6780 6935 152 7560 7700 - 173 2 BEY 509 6785 7025 510 7110 7340 - 174 2 OSL 211 6820 6980 212 7620 7775 - 175 2 KBP 185 6830 6930 186 7480 7570 - 176 1 IKT 739 6845 7180 740 7270 7630 - 177 1 KRR 773 6855 7000 774 7380 7525 - 178 1 SGC 877 6880 7075 878 7155 7385 - 179 1 LED 857 6910 6990 858 7370 7450 - 180 1 CEK 899 6990 7145 900 7215 7380 - 181 1 PEE 821 6995 7150 822 7210 7360 - 182 2 TBS 197 7000 7165 198 7320 7475 - 183 1 UFA 891 7035 7165 892 7235 7370 - 184 1 KJA 781 7060 7330 782 7440 7750 - 185 1 IKT 743 7395 7720 744 7810 8170 - 186 1 CEK 897 7405 7560 898 7630 7795 - 187 1 KRR 763 7460 7600 764 7680 7810 - 188 2 SIP 133 7480 7620 134 7700 7820 - 189 2 BUD 131 7490 7650 132 7720 7875 - 190 1 AAQ 701 7505 7640 702 7710 7840 - 191 1 MRV 785 7510 7640 786 7720 7850 - 192 2 IST 207 7545 7720 208 7795 7985 - 193 2 WAW 101 7555 7675 102 7740 7860 - 194 2 GYD 147 7570 7750 148 7875 8060 - 195 1 AER 869 7585 7730 870 7855 7995 - 196 2 AYT 221 7610 7800 222 7895 8085 - 197 2 EVN 193 7610 7790 194 7865 8035 - 198 1 KRR 765 7630 7760 766 7830 7960 - 199 1 AAQ 703 7720 7860 704 7940 8050 - 200 1 LED 845 7730 7820 846 7890 7975 - 201 1 KRR 767 7740 7875 768 7965 8095 - 202 2 KBP 183 7865 7960 184 8050 8140 - 203 2 AYT 223 7940 8130 224 8190 8380 - 204 1 MRV 787 7955 8105 788 8185 8335 - 205 1 KRR 771 8010 8140 772 8230 8365 - 206 1 LED 849 8025 8100 850 8160 8295 - 207 2 IST 209 8080 8250 210 8320 8480 - 208 1 AER 873 8085 8230 874 8960 9100 - 209 1 ASF 711 8195 8345 712 8840 8995 - 210 2 ULN 563 8195 8535 564 8615 9015 - 211 1 KJA 779 8230 8500 780 8575 8870 - 212 2 OSL 211 8260 8420 212 9060 9215 - 213 2 KBP 185 8270 8370 186 8920 9010 - 214 1 IKT 739 8285 8620 740 8710 9070 - 215 1 KRR 773 8295 8440 774 8820 8965 - 216 1 SGC 877 8320 8515 878 8595 8825 - 217 1 LED 857 8350 8430 858 8810 8890 - 218 1 CEK 899 8430 8585 900 8655 8820 - 219 1 PEE 821 8435 8590 822 8650 8800 - 220 2 TBS 197 8440 8605 198 8760 8915 - 221 1 UFA 891 8475 8605 892 8675 8810 - 222 1 KJA 781 8500 8770 782 8880 9190 - 223 1 IKT 743 8835 9160 744 9250 9610 - 224 1 OMS 815 8845 9045 816 9125 9340 - 225 1 CEK 897 8845 9000 898 9070 9235 - 226 1 KRR 763 8900 9040 764 9120 9250 - 227 2 SIP 133 8920 9060 134 9140 9260 - 228 2 BUD 131 8930 9090 132 9160 9315 - 229 1 AAQ 701 8945 9080 702 9150 9280 - 230 1 MRV 785 8950 9080 786 9160 9290 - 231 2 IST 207 8985 9160 208 9235 9425 - 232 2 WAW 101 8995 9115 102 9180 9300 - 233 2 FRU 181 9005 9255 182 9350 9620 - 234 2 GYD 147 9010 9190 148 9315 9500 - 235 1 AER 869 9025 9170 870 9295 9435 - 236 2 EVN 193 9050 9230 194 9305 9475 - 237 1 KRR 765 9070 9200 766 9270 9400 - 238 1 AAQ 703 9160 9300 704 9380 9490 - 239 1 LED 845 9170 9260 846 9330 9415 - 240 1 KRR 767 9180 9315 768 9405 9535 - 241 2 KBP 183 9305 9400 184 9490 9580 - 242 2 AYT 223 9380 9570 224 9630 9820 - 243 1 MRV 787 9395 9545 788 9625 9775 - 244 1 KRR 771 9450 9580 772 9670 9805 - 245 1 LED 849 9465 9540 850 9600 9735 - 246 2 IST 209 9520 9690 210 9760 9920 - 247 1 AER 873 9525 9670 874 10400 10540 - 248 1 ASF 711 9635 9785 712 10280 10435 - 249 2 ULN 563 9635 9975 564 10055 10455 - 250 2 OTP 151 9660 9815 152 10440 10580 - 251 2 DAM 517 9665 9905 518 9990 10220 - 252 2 OSL 211 9700 9860 212 10500 10655 - 253 2 KBP 185 9710 9810 186 10360 10450 - 254 1 IKT 739 9725 10060 740 10150 10510 - 255 1 KRR 773 9735 9880 774 10260 10405 - 256 1 SGC 877 9760 9955 878 10035 10265 - 257 1 LED 857 9790 9870 858 10250 10330 - 258 1 CEK 899 9870 10025 900 10095 10260 - 259 1 PEE 821 9875 10030 822 10090 10240 - 260 1 UFA 891 9915 10045 892 10115 10250 - 261 1 KJA 781 9940 10210 782 10320 10630 -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/todd.mod b/resources/3rdparty/glpk-4.53/examples/todd.mod deleted file mode 100644 index c0ef44b4c..000000000 --- a/resources/3rdparty/glpk-4.53/examples/todd.mod +++ /dev/null @@ -1,36 +0,0 @@ -/* TODD, a class of hard instances of zero-one knapsack problems */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* Chvatal describes a class of instances of zero-one knapsack problems - due to Todd. He shows that a wide class of algorithms - including all - based on branch and bound or dynamic programming - find it difficult - to solve problems in the Todd class. More exactly, the time required - by these algorithms to solve instances of problems that belong to the - Todd class grows as an exponential function of the problem size. - - Reference: - Chvatal V. (1980), Hard knapsack problems, Op. Res. 28, 1402-1411. */ - -param n > 0 integer; - -param log2_n := log(n) / log(2); - -param k := floor(log2_n); - -param a{j in 1..n} := 2 ** (k + n + 1) + 2 ** (k + n + 1 - j) + 1; - -param b := 0.5 * floor(sum{j in 1..n} a[j]); - -var x{1..n} binary; - -maximize obj: sum{j in 1..n} a[j] * x[j]; - -s.t. cap: sum{j in 1..n} a[j] * x[j] <= b; - -data; - -param n := 15; -/* change this parameter to choose a particular instance */ - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/train.mod b/resources/3rdparty/glpk-4.53/examples/train.mod deleted file mode 100644 index a17520ea1..000000000 --- a/resources/3rdparty/glpk-4.53/examples/train.mod +++ /dev/null @@ -1,281 +0,0 @@ -# TRAIN, a model of railroad passenger car allocation -# -# References: -# Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language -# for Mathematical Programming." Management Science 36 (1990) 519-554. - -### SCHEDULE SETS AND PARAMETERS ### - -set cities; - -set links within {c1 in cities, c2 in cities: c1 <> c2}; - - # Set of cities, and set of intercity links - -param last > 0 integer; # Number of time intervals in a day - -set times := 1..last; # Set of time intervals in a day - -set schedule within - {c1 in cities, t1 in times, - c2 in cities, t2 in times: (c1,c2) in links}; - - # Member (c1,t1,c2,t2) of this set represents - # a train that leaves city c1 at time t1 - # and arrives in city c2 at time t2 - -### DEMAND PARAMETERS ### - -param section > 0 integer; - - # Maximum number of cars in one section of a train - -param demand {schedule} > 0; - - # For each scheduled train: - # the smallest number of cars that - # can meet demand for the train - -param low {(c1,t1,c2,t2) in schedule} := ceil(demand[c1,t1,c2,t2]); - - # Minimum number of cars needed to meet demand - -param high {(c1,t1,c2,t2) in schedule} - - := max (2, min (ceil(2*demand[c1,t1,c2,t2]), - section*ceil(demand[c1,t1,c2,t2]/section) )); - - # Maximum number of cars allowed on a train: - # 2 if demand is for less than one car; - # otherwise, lesser of - # number of cars needed to hold twice the demand, and - # number of cars in minimum number of sections needed - -### DISTANCE PARAMETERS ### - -param dist_table {links} >= 0 default 0.0; - -param distance {(c1,c2) in links} > 0 - := if dist_table[c1,c2] > 0 then dist_table[c1,c2] else dist_table[c2,c1]; - - # Inter-city distances: distance[c1,c2] is miles - # between city c1 and city c2 - -### VARIABLES ### - -var U 'cars stored' {cities,times} >= 0; - - # u[c,t] is the number of unused cars stored - # at city c in the interval beginning at time t - -var X 'cars in train' {schedule} >= 0; - - # x[c1,t1,c2,t2] is the number of cars assigned to - # the scheduled train that leaves c1 at t1 and - # arrives in c2 at t2 - -### OBJECTIVES ### - -minimize cars: - sum {c in cities} U[c,last] + - sum {(c1,t1,c2,t2) in schedule: t2 < t1} X[c1,t1,c2,t2]; - - # Number of cars in the system: - # sum of unused cars and cars in trains during - # the last time interval of the day - -minimize miles: - sum {(c1,t1,c2,t2) in schedule} distance[c1,c2] * X[c1,t1,c2,t2]; - - # Total car-miles run by all scheduled trains in a day - -### CONSTRAINTS ### - -account {c in cities, t in times}: - - U[c,t] = U[c, if t > 1 then t-1 else last] + - - sum {(c1,t1,c,t) in schedule} X[c1,t1,c,t] - - sum {(c,t,c2,t2) in schedule} X[c,t,c2,t2]; - - # For every city and time: - # unused cars in the present interval must equal - # unused cars in the previous interval, - # plus cars just arriving in trains, - # minus cars just leaving in trains - -satisfy {(c1,t1,c2,t2) in schedule}: - - low[c1,t1,c2,t2] <= X[c1,t1,c2,t2] <= high[c1,t1,c2,t2]; - - # For each scheduled train: - # number of cars must meet demand, - # but must not be so great that unnecessary - # sections are run - -### DATA ### - -data; - -set cities := BO NY PH WA ; - -set links := (BO,NY) (NY,PH) (PH,WA) - (NY,BO) (PH,NY) (WA,PH) ; - -param dist_table := [*,*] BO NY 232 - NY PH 90 - PH WA 135 ; - -param last := 48 ; - -param section := 14 ; - -set schedule := - - (WA,*,PH,*) 2 5 6 9 8 11 10 13 - 12 15 13 16 14 17 15 18 - 16 19 17 20 18 21 19 22 - 20 23 21 24 22 25 23 26 - 24 27 25 28 26 29 27 30 - 28 31 29 32 30 33 31 34 - 32 35 33 36 34 37 35 38 - 36 39 37 40 38 41 39 42 - 40 43 41 44 42 45 44 47 - 46 1 - - (PH,*,NY,*) 1 3 5 7 9 11 11 13 - 13 15 14 16 15 17 16 18 - 17 19 18 20 19 21 20 22 - 21 23 22 24 23 25 24 26 - 25 27 26 28 27 29 28 30 - 29 31 30 32 31 33 32 34 - 33 35 34 36 35 37 36 38 - 37 39 38 40 39 41 40 42 - 41 43 42 44 43 45 44 46 - 45 47 47 1 - - (NY,*,BO,*) 10 16 12 18 14 20 15 21 - 16 22 17 23 18 24 19 25 - 20 26 21 27 22 28 23 29 - 24 30 25 31 26 32 27 33 - 28 34 29 35 30 36 31 37 - 32 38 33 39 34 40 35 41 - 36 42 37 43 38 44 39 45 - 40 46 41 47 42 48 43 1 - 44 2 45 3 46 4 48 6 - - (BO,*,NY,*) 7 13 9 15 11 17 12 18 - 13 19 14 20 15 21 16 22 - 17 23 18 24 19 25 20 26 - 21 27 22 28 23 29 24 30 - 25 31 26 32 27 33 28 34 - 29 35 30 36 31 37 32 38 - 33 39 34 40 35 41 36 42 - 37 43 38 44 39 45 40 46 - 41 47 43 1 45 3 47 5 - - (NY,*,PH,*) 1 3 12 14 13 15 14 16 - 15 17 16 18 17 19 18 20 - 19 21 20 22 21 23 22 24 - 23 25 24 26 25 27 26 28 - 27 29 28 30 29 31 30 32 - 31 33 32 34 33 35 34 36 - 35 37 36 38 37 39 38 40 - 39 41 40 42 41 43 42 44 - 43 45 44 46 45 47 46 48 - 47 1 - - (PH,*,WA,*) 1 4 14 17 15 18 16 19 - 17 20 18 21 19 22 20 23 - 21 24 22 25 23 26 24 27 - 25 28 26 29 27 30 28 31 - 29 32 30 33 31 34 32 35 - 33 36 34 37 35 38 36 39 - 37 40 38 41 39 42 40 43 - 41 44 42 45 43 46 44 47 - 45 48 46 1 47 2 ; - -param demand := - - [WA,*,PH,*] 2 5 .55 6 9 .01 8 11 .01 - 10 13 .13 12 15 1.59 13 16 1.69 - 14 17 5.19 15 18 3.55 16 19 6.29 - 17 20 4.00 18 21 5.80 19 22 3.40 - 20 23 4.88 21 24 2.92 22 25 4.37 - 23 26 2.80 24 27 4.23 25 28 2.88 - 26 29 4.33 27 30 3.11 28 31 4.64 - 29 32 3.44 30 33 4.95 31 34 3.73 - 32 35 5.27 33 36 3.77 34 37 4.80 - 35 38 3.31 36 39 3.89 37 40 2.65 - 38 41 3.01 39 42 2.04 40 43 2.31 - 41 44 1.52 42 45 1.75 44 47 1.88 - 46 1 1.05 - - [PH,*,NY,*] 1 3 1.05 5 7 .43 9 11 .20 - 11 13 .21 13 15 .40 14 16 6.49 - 15 17 16.40 16 18 9.48 17 19 17.15 - 18 20 9.31 19 21 15.20 20 22 8.21 - 21 23 13.32 22 24 7.35 23 25 11.83 - 24 26 6.61 25 27 10.61 26 28 6.05 - 27 29 9.65 28 30 5.61 29 31 9.25 - 30 32 5.40 31 33 8.24 32 34 4.84 - 33 35 7.44 34 36 4.44 35 37 6.80 - 36 38 4.11 37 39 6.25 38 40 3.69 - 39 41 5.55 40 42 3.29 41 43 4.77 - 42 44 2.91 43 45 4.19 44 46 2.53 - 45 47 4.00 47 1 1.65 - - [NY,*,BO,*] 10 16 1.23 12 18 3.84 14 20 4.08 - 15 21 1.47 16 22 2.96 17 23 1.60 - 18 24 2.95 19 25 1.71 20 26 2.81 - 21 27 1.77 22 28 2.87 23 29 1.84 - 24 30 2.95 25 31 1.91 26 32 3.12 - 27 33 1.93 28 34 3.31 29 35 2.00 - 30 36 3.40 31 37 2.08 32 38 3.41 - 33 39 2.69 34 40 4.45 35 41 2.32 - 36 42 3.40 37 43 1.80 38 44 2.63 - 39 45 1.52 40 46 2.23 41 47 1.25 - 42 48 1.79 43 1 .97 44 2 1.28 - 45 3 .48 46 4 .68 48 6 .08 - - [BO,*,NY,*] 7 13 .03 9 15 1.29 11 17 4.59 - 12 18 2.56 13 19 3.92 14 20 2.37 - 15 21 3.81 16 22 2.24 17 23 3.51 - 18 24 2.13 19 25 3.28 20 26 2.05 - 21 27 3.15 22 28 1.99 23 29 3.09 - 24 30 1.93 25 31 3.19 26 32 1.91 - 27 33 3.21 28 34 1.85 29 35 3.21 - 30 36 1.71 31 37 3.04 32 38 2.08 - 33 39 3.13 34 40 1.96 35 41 2.53 - 36 42 1.43 37 43 2.04 38 44 1.12 - 39 45 1.71 40 46 .91 41 47 1.32 - 43 1 1.80 45 3 1.13 47 5 .23 - - [NY,*,PH,*] 1 3 .04 12 14 4.68 13 15 5.61 - 14 16 3.56 15 17 5.81 16 18 3.81 - 17 19 6.31 18 20 4.07 19 21 7.33 - 20 22 4.55 21 23 7.37 22 24 4.73 - 23 25 7.61 24 26 4.92 25 27 7.91 - 26 28 5.19 27 29 8.40 28 30 5.53 - 29 31 9.32 30 32 5.51 31 33 10.33 - 32 34 9.21 33 35 18.95 34 36 11.23 - 35 37 16.85 36 38 7.29 37 39 10.89 - 38 40 5.41 39 41 8.21 40 42 4.52 - 41 43 6.99 42 44 3.92 43 45 6.21 - 44 46 3.44 45 47 5.17 46 48 2.55 - 47 1 1.24 - - [PH,*,WA,*] 1 4 .20 14 17 4.49 15 18 3.53 - 16 19 2.67 17 20 3.83 18 21 3.01 - 19 22 4.12 20 23 3.15 21 24 4.67 - 22 25 3.20 23 26 4.23 24 27 2.87 - 25 28 3.84 26 29 2.60 27 30 3.80 - 28 31 2.77 29 32 4.31 30 33 3.16 - 31 34 4.88 32 35 3.45 33 36 5.55 - 34 37 3.52 35 38 6.11 36 39 3.32 - 37 40 5.53 38 41 3.03 39 42 4.51 - 40 43 2.53 41 44 3.39 42 45 1.93 - 43 46 2.52 44 47 1.20 45 48 1.75 - 46 1 .88 47 2 .87 ; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/transp.mod b/resources/3rdparty/glpk-4.53/examples/transp.mod deleted file mode 100644 index a7cb939ae..000000000 --- a/resources/3rdparty/glpk-4.53/examples/transp.mod +++ /dev/null @@ -1,63 +0,0 @@ -# A TRANSPORTATION PROBLEM -# -# This problem finds a least cost shipping schedule that meets -# requirements at markets and supplies at factories. -# -# References: -# Dantzig G B, "Linear Programming and Extensions." -# Princeton University Press, Princeton, New Jersey, 1963, -# Chapter 3-3. - -set I; -/* canning plants */ - -set J; -/* markets */ - -param a{i in I}; -/* capacity of plant i in cases */ - -param b{j in J}; -/* demand at market j in cases */ - -param d{i in I, j in J}; -/* distance in thousands of miles */ - -param f; -/* freight in dollars per case per thousand miles */ - -param c{i in I, j in J} := f * d[i,j] / 1000; -/* transport cost in thousands of dollars per case */ - -var x{i in I, j in J} >= 0; -/* shipment quantities in cases */ - -minimize cost: sum{i in I, j in J} c[i,j] * x[i,j]; -/* total transportation costs in thousands of dollars */ - -s.t. supply{i in I}: sum{j in J} x[i,j] <= a[i]; -/* observe supply limit at plant i */ - -s.t. demand{j in J}: sum{i in I} x[i,j] >= b[j]; -/* satisfy demand at market j */ - -data; - -set I := Seattle San-Diego; - -set J := New-York Chicago Topeka; - -param a := Seattle 350 - San-Diego 600; - -param b := New-York 325 - Chicago 300 - Topeka 275; - -param d : New-York Chicago Topeka := - Seattle 2.5 1.7 1.8 - San-Diego 2.5 1.8 1.4 ; - -param f := 90; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/trick.mod b/resources/3rdparty/glpk-4.53/examples/trick.mod deleted file mode 100644 index df5717b8a..000000000 --- a/resources/3rdparty/glpk-4.53/examples/trick.mod +++ /dev/null @@ -1,72 +0,0 @@ -/* TRICK, A Transportation Design Problem */ - -/* Translated from the Mosel modeling language to GNU MathProg by - Andrew Makhorin */ - -/* This example model is described in the article "Formulations and - Reformulations in Integer Programming" by Michael Trick (it is - publicly available at http://mat.gsia.cmu.edu/trick/formul04.pdf). - - This model demonstrates an amazing effect when including in the - formulation an additional constraint, which is redundant even for - LP relaxation, makes the model easy for solving with the B&B. */ - -set TRUCKS := 1..10; - -set PACKAGES := 1..20; - -param capacity{TRUCKS}; - -param size{PACKAGES}; - -param cost{TRUCKS}; - -param can_use{PACKAGES, TRUCKS}; - -var x{PACKAGES, TRUCKS}, binary; - -var y{TRUCKS}, binary; - -minimize total: sum{i in TRUCKS} cost[i] * y[i]; - -f1{i in TRUCKS}: - sum{j in PACKAGES} size[j] * x[j,i] <= capacity[i] * y[i]; - -f2{i in TRUCKS, j in PACKAGES}: - x[j,i] <= y[i]; - -f3{j in PACKAGES}: - sum{i in TRUCKS} can_use[j,i] * x[j,i] = 1; - -redundant_constraint: - sum{i in TRUCKS} capacity[i] * y[i] >= sum{j in PACKAGES} size[j]; - -data; - -param capacity := - [1] 100 [2] 200 [3] 100 [4] 200 [5] 100 [6] 200 [7] 100 [8] 200 - [9] 100 [10] 200; - -param size := - [1] 17 [2] 21 [3] 54 [4] 45 [5] 87 [6] 34 [7] 23 [8] 45 [9] 12 - [10] 43 [11] 54 [12] 39 [13] 31 [14] 26 [15] 75 [16] 48 [17] 16 - [18] 32 [19] 45 [20] 55; - -param cost := - [1] 1 [2] 1.8 [3] 1 [4] 1.8 [5] 1 [6] 1.8 [7] 1 [8] 1.8 [9] 1 - [10] 1.8; - -param can_use (tr): - 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 := - 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 - 2 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 0 0 0 - 3 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 - 4 0 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 - 5 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 0 - 6 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 0 0 0 0 - 7 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 0 0 - 8 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 - 9 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 - 10 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/tsp.mod b/resources/3rdparty/glpk-4.53/examples/tsp.mod deleted file mode 100644 index 358245dae..000000000 --- a/resources/3rdparty/glpk-4.53/examples/tsp.mod +++ /dev/null @@ -1,335 +0,0 @@ -/* TSP, Traveling Salesman Problem */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -/* The Traveling Salesman Problem (TSP) is stated as follows. - Let a directed graph G = (V, E) be given, where V = {1, ..., n} is - a set of nodes, E <= V x V is a set of arcs. Let also each arc - e = (i,j) be assigned a number c[i,j], which is the length of the - arc e. The problem is to find a closed path of minimal length going - through each node of G exactly once. */ - -param n, integer, >= 3; -/* number of nodes */ - -set V := 1..n; -/* set of nodes */ - -set E, within V cross V; -/* set of arcs */ - -param c{(i,j) in E}; -/* distance from node i to node j */ - -var x{(i,j) in E}, binary; -/* x[i,j] = 1 means that the salesman goes from node i to node j */ - -minimize total: sum{(i,j) in E} c[i,j] * x[i,j]; -/* the objective is to make the path length as small as possible */ - -s.t. leave{i in V}: sum{(i,j) in E} x[i,j] = 1; -/* the salesman leaves each node i exactly once */ - -s.t. enter{j in V}: sum{(i,j) in E} x[i,j] = 1; -/* the salesman enters each node j exactly once */ - -/* Constraints above are not sufficient to describe valid tours, so we - need to add constraints to eliminate subtours, i.e. tours which have - disconnected components. Although there are many known ways to do - that, I invented yet another way. The general idea is the following. - Let the salesman sell, say, cars, starting the travel from node 1, - where he has n cars. If we require the salesman to sell exactly one - car in each node, he will need to go through all nodes to satisfy - this requirement, thus, all subtours will be eliminated. */ - -var y{(i,j) in E}, >= 0; -/* y[i,j] is the number of cars, which the salesman has after leaving - node i and before entering node j; in terms of the network analysis, - y[i,j] is a flow through arc (i,j) */ - -s.t. cap{(i,j) in E}: y[i,j] <= (n-1) * x[i,j]; -/* if arc (i,j) does not belong to the salesman's tour, its capacity - must be zero; it is obvious that on leaving a node, it is sufficient - to have not more than n-1 cars */ - -s.t. node{i in V}: -/* node[i] is a conservation constraint for node i */ - - sum{(j,i) in E} y[j,i] - /* summary flow into node i through all ingoing arcs */ - - + (if i = 1 then n) - /* plus n cars which the salesman has at starting node */ - - = /* must be equal to */ - - sum{(i,j) in E} y[i,j] - /* summary flow from node i through all outgoing arcs */ - - + 1; - /* plus one car which the salesman sells at node i */ - -solve; - -printf "Optimal tour has length %d\n", - sum{(i,j) in E} c[i,j] * x[i,j]; -printf("From node To node Distance\n"); -printf{(i,j) in E: x[i,j]} " %3d %3d %8g\n", - i, j, c[i,j]; - -data; - -/* These data correspond to the symmetric instance ulysses16 from: - - Reinelt, G.: TSPLIB - A travelling salesman problem library. - ORSA-Journal of the Computing 3 (1991) 376-84; - http://elib.zib.de/pub/Packages/mp-testdata/tsp/tsplib */ - -/* The optimal solution is 6859 */ - -param n := 16; - -param : E : c := - 1 2 509 - 1 3 501 - 1 4 312 - 1 5 1019 - 1 6 736 - 1 7 656 - 1 8 60 - 1 9 1039 - 1 10 726 - 1 11 2314 - 1 12 479 - 1 13 448 - 1 14 479 - 1 15 619 - 1 16 150 - 2 1 509 - 2 3 126 - 2 4 474 - 2 5 1526 - 2 6 1226 - 2 7 1133 - 2 8 532 - 2 9 1449 - 2 10 1122 - 2 11 2789 - 2 12 958 - 2 13 941 - 2 14 978 - 2 15 1127 - 2 16 542 - 3 1 501 - 3 2 126 - 3 4 541 - 3 5 1516 - 3 6 1184 - 3 7 1084 - 3 8 536 - 3 9 1371 - 3 10 1045 - 3 11 2728 - 3 12 913 - 3 13 904 - 3 14 946 - 3 15 1115 - 3 16 499 - 4 1 312 - 4 2 474 - 4 3 541 - 4 5 1157 - 4 6 980 - 4 7 919 - 4 8 271 - 4 9 1333 - 4 10 1029 - 4 11 2553 - 4 12 751 - 4 13 704 - 4 14 720 - 4 15 783 - 4 16 455 - 5 1 1019 - 5 2 1526 - 5 3 1516 - 5 4 1157 - 5 6 478 - 5 7 583 - 5 8 996 - 5 9 858 - 5 10 855 - 5 11 1504 - 5 12 677 - 5 13 651 - 5 14 600 - 5 15 401 - 5 16 1033 - 6 1 736 - 6 2 1226 - 6 3 1184 - 6 4 980 - 6 5 478 - 6 7 115 - 6 8 740 - 6 9 470 - 6 10 379 - 6 11 1581 - 6 12 271 - 6 13 289 - 6 14 261 - 6 15 308 - 6 16 687 - 7 1 656 - 7 2 1133 - 7 3 1084 - 7 4 919 - 7 5 583 - 7 6 115 - 7 8 667 - 7 9 455 - 7 10 288 - 7 11 1661 - 7 12 177 - 7 13 216 - 7 14 207 - 7 15 343 - 7 16 592 - 8 1 60 - 8 2 532 - 8 3 536 - 8 4 271 - 8 5 996 - 8 6 740 - 8 7 667 - 8 9 1066 - 8 10 759 - 8 11 2320 - 8 12 493 - 8 13 454 - 8 14 479 - 8 15 598 - 8 16 206 - 9 1 1039 - 9 2 1449 - 9 3 1371 - 9 4 1333 - 9 5 858 - 9 6 470 - 9 7 455 - 9 8 1066 - 9 10 328 - 9 11 1387 - 9 12 591 - 9 13 650 - 9 14 656 - 9 15 776 - 9 16 933 - 10 1 726 - 10 2 1122 - 10 3 1045 - 10 4 1029 - 10 5 855 - 10 6 379 - 10 7 288 - 10 8 759 - 10 9 328 - 10 11 1697 - 10 12 333 - 10 13 400 - 10 14 427 - 10 15 622 - 10 16 610 - 11 1 2314 - 11 2 2789 - 11 3 2728 - 11 4 2553 - 11 5 1504 - 11 6 1581 - 11 7 1661 - 11 8 2320 - 11 9 1387 - 11 10 1697 - 11 12 1838 - 11 13 1868 - 11 14 1841 - 11 15 1789 - 11 16 2248 - 12 1 479 - 12 2 958 - 12 3 913 - 12 4 751 - 12 5 677 - 12 6 271 - 12 7 177 - 12 8 493 - 12 9 591 - 12 10 333 - 12 11 1838 - 12 13 68 - 12 14 105 - 12 15 336 - 12 16 417 - 13 1 448 - 13 2 941 - 13 3 904 - 13 4 704 - 13 5 651 - 13 6 289 - 13 7 216 - 13 8 454 - 13 9 650 - 13 10 400 - 13 11 1868 - 13 12 68 - 13 14 52 - 13 15 287 - 13 16 406 - 14 1 479 - 14 2 978 - 14 3 946 - 14 4 720 - 14 5 600 - 14 6 261 - 14 7 207 - 14 8 479 - 14 9 656 - 14 10 427 - 14 11 1841 - 14 12 105 - 14 13 52 - 14 15 237 - 14 16 449 - 15 1 619 - 15 2 1127 - 15 3 1115 - 15 4 783 - 15 5 401 - 15 6 308 - 15 7 343 - 15 8 598 - 15 9 776 - 15 10 622 - 15 11 1789 - 15 12 336 - 15 13 287 - 15 14 237 - 15 16 636 - 16 1 150 - 16 2 542 - 16 3 499 - 16 4 455 - 16 5 1033 - 16 6 687 - 16 7 592 - 16 8 206 - 16 9 933 - 16 10 610 - 16 11 2248 - 16 12 417 - 16 13 406 - 16 14 449 - 16 15 636 -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/xyacfs.mod b/resources/3rdparty/glpk-4.53/examples/xyacfs.mod deleted file mode 100644 index 5a0b22e0e..000000000 --- a/resources/3rdparty/glpk-4.53/examples/xyacfs.mod +++ /dev/null @@ -1,56 +0,0 @@ -/*Extended Yet Another Curve Fitting Solution (The poor man's RMA) - - An extension of yacfs.mod adding a Weight parameter: - When set to 1 the model produces best fit by least squares with all error in y and none in x (YonX); - When set to zero the model produces best fit by least squares with all error in x and none in y (XonY); - When set to 0.5 the model assumes equal error in x and y producing results similar to fitting by Reduced Major Axis Analysis. - - Nigel_Galloway@operamail.com - November 5th., 2009 -*/ -set Sample; -param Sx {z in Sample}; -param Sy {z in Sample}; -param Weight := 0.5; - -var a; -var b; -var p; -var q; - -XonY1 :sum{z in Sample} q*Sy[z]*Sy[z] + sum{z in Sample} p*Sy[z] = sum{z in Sample} Sy[z]*Sx[z]; -XonY2 :sum{z in Sample} q*Sy[z] + sum{z in Sample} p = sum{z in Sample} Sx[z]; -YonX1 :sum{z in Sample} a*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z] = sum{z in Sample} Sy[z]*Sx[z]; -YonX2 :sum{z in Sample} a*Sx[z] + sum{z in Sample} b = sum{z in Sample} Sy[z]; - -solve; - -param W := Weight*a + (1-Weight)*(1/q); -printf "\nbest linear fit is:\n\ty = %f %s %fx\n\n", b*Weight - (1-Weight)*(p/q), if W < 0 then "-" else "+", abs(W); - -data; - -param: -Sample: Sx Sy := - 1 0 1 - 2 0.5 0.9 - 3 1 0.7 - 4 1.5 1.5 - 5 1.9 2 - 6 2.5 2.4 - 7 3 3.2 - 8 3.5 2 - 9 4 2.7 - 10 4.5 3.5 - 11 5 1 - 12 5.5 4 - 13 6 3.6 - 14 6.6 2.7 - 15 7 5.7 - 16 7.6 4.6 - 17 8.5 6 - 18 9 6.8 - 19 10 7.3 -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/yacfs.mod b/resources/3rdparty/glpk-4.53/examples/yacfs.mod deleted file mode 100644 index 270f2a083..000000000 --- a/resources/3rdparty/glpk-4.53/examples/yacfs.mod +++ /dev/null @@ -1,48 +0,0 @@ -/*Yet Another Curve Fitting Solution - - Obviously this solution produces the same answer - as examples/cflsq.mod - - Nigel_Galloway@operamail.com - February 1st., 2009 -*/ -set Sample; -param Sx {z in Sample}; -param Sy {z in Sample}; - -var a; -var b; - -equalz1 :sum{z in Sample} a*Sx[z]*Sx[z] + sum{z in Sample} b*Sx[z] = sum{z in Sample} Sy[z]*Sx[z]; -equalz2 :sum{z in Sample} a*Sx[z] + sum{z in Sample} b = sum{z in Sample} Sy[z]; - -solve; - -printf "\nbest linear fit is:\n\ty = %f %s %fx\n\n", b, if a < 0 then "-" else "+", abs(a); - -data; - -param: -Sample: Sx Sy := - 1 0 1 - 2 0.5 0.9 - 3 1 0.7 - 4 1.5 1.5 - 5 1.9 2 - 6 2.5 2.4 - 7 3 3.2 - 8 3.5 2 - 9 4 2.7 - 10 4.5 3.5 - 11 5 1 - 12 5.5 4 - 13 6 3.6 - 14 6.6 2.7 - 15 7 5.7 - 16 7.6 4.6 - 17 8.5 6 - 18 9 6.8 - 19 10 7.3 -; - -end; diff --git a/resources/3rdparty/glpk-4.53/examples/zebra.mod b/resources/3rdparty/glpk-4.53/examples/zebra.mod deleted file mode 100644 index 66f8c1aaf..000000000 --- a/resources/3rdparty/glpk-4.53/examples/zebra.mod +++ /dev/null @@ -1,151 +0,0 @@ -/* ZEBRA, Who Owns the Zebra? */ - -/* Written in GNU MathProg by Andrew Makhorin */ - -######################################################################## -# The Zebra Puzzle is a well-known logic puzzle. -# -# It is often called "Einstein's Puzzle" or "Einstein's Riddle" -# because it is said to have been invented by Albert Einstein as a boy, -# with the common claim that Einstein said "only 2 percent of the -# world's population can solve". It is also sometimes attributed to -# Lewis Carroll. However, there is no known evidence for Einstein's or -# Carroll's authorship. -# -# There are several versions of this puzzle. The version below is -# quoted from the first known publication in Life International -# magazine on December 17, 1962. -# -# 1. There are five houses. -# 2. The Englishman lives in the red house. -# 3. The Spaniard owns the dog. -# 4. Coffee is drunk in the green house. -# 5. The Ukrainian drinks tea. -# 6. The green house is immediately to the right of the ivory house. -# 7. The Old Gold smoker owns snails. -# 8. Kools are smoked in the yellow house. -# 9. Milk is drunk in the middle house. -# 10. The Norwegian lives in the first house. -# 11. The man who smokes Chesterfields lives in the house next to the -# man with the fox. -# 12. Kools are smoked in the house next to the house where the horse -# is kept. -# 13. The Lucky Strike smoker drinks orange juice. -# 14. The Japanese smokes Parliaments. -# 15. The Norwegian lives next to the blue house. -# -# Now, who drinks water? Who owns the zebra? -# -# In the interest of clarity, it must be added that each of the five -# houses is painted a different color, and their inhabitants are of -# different national extractions, own different pets, drink different -# beverages and smoke different brands of American cigarettes. One -# other thing: In statement 6, right means your right. -# -# (From Wikipedia, the free encyclopedia.) -######################################################################## - -set HOUSE := { 1..5 }; - -set COLOR := { "blue", "green", "ivory", "red", "yellow" }; - -set NATIONALITY := { "Englishman", "Japanese", "Norwegian", "Spaniard", - "Ukranian" }; - -set DRINK := { "coffee", "milk", "orange_juice", "tea", "water" }; - -set SMOKE := { "Chesterfield", "Kools", "Lucky_Strike", "Old_Gold", - "Parliament" }; - -set PET := { "dog", "fox", "horse", "snails", "zebra" }; - -var color{HOUSE, COLOR}, binary; -c1{h in HOUSE}: sum{c in COLOR} color[h,c] = 1; -c2{c in COLOR}: sum{h in HOUSE} color[h,c] = 1; - -var nationality{HOUSE, NATIONALITY}, binary; -n1{h in HOUSE}: sum{n in NATIONALITY} nationality[h,n] = 1; -n2{n in NATIONALITY}: sum{h in HOUSE} nationality[h,n] = 1; - -var drink{HOUSE, DRINK}, binary; -d1{h in HOUSE}: sum{d in DRINK} drink[h,d] = 1; -d2{d in DRINK}: sum{h in HOUSE} drink[h,d] = 1; - -var smoke{HOUSE, SMOKE}, binary; -s1{h in HOUSE}: sum{s in SMOKE} smoke[h,s] = 1; -s2{s in SMOKE}: sum{h in HOUSE} smoke[h,s] = 1; - -var pet{HOUSE, PET}, binary; -p1{h in HOUSE}: sum{p in PET} pet[h,p] = 1; -p2{p in PET}: sum{h in HOUSE} pet[h,p] = 1; - -/* the Englishman lives in the red house */ -f2{h in HOUSE}: nationality[h,"Englishman"] = color[h,"red"]; - -/* the Spaniard owns the dog */ -f3{h in HOUSE}: nationality[h,"Spaniard"] = pet[h,"dog"]; - -/* coffee is drunk in the green house */ -f4{h in HOUSE}: drink[h,"coffee"] = color[h,"green"]; - -/* the Ukrainian drinks tea */ -f5{h in HOUSE}: nationality[h,"Ukranian"] = drink[h,"tea"]; - -/* the green house is immediately to the right of the ivory house */ -f6{h in HOUSE}: - color[h,"green"] = if h = 1 then 0 else color[h-1,"ivory"]; - -/* the Old Gold smoker owns snails */ -f7{h in HOUSE}: smoke[h,"Old_Gold"] = pet[h,"snails"]; - -/* Kools are smoked in the yellow house */ -f8{h in HOUSE}: smoke[h,"Kools"] = color[h,"yellow"]; - -/* milk is drunk in the middle house */ -f9: drink[3,"milk"] = 1; - -/* the Norwegian lives in the first house */ -f10: nationality[1,"Norwegian"] = 1; - -/* the man who smokes Chesterfields lives in the house next to the man - with the fox */ -f11{h in HOUSE}: - (1 - smoke[h,"Chesterfield"]) + - (if h = 1 then 0 else pet[h-1,"fox"]) + - (if h = 5 then 0 else pet[h+1,"fox"]) >= 1; - -/* Kools are smoked in the house next to the house where the horse is - kept */ -f12{h in HOUSE}: - (1 - smoke[h,"Kools"]) + - (if h = 1 then 0 else pet[h-1,"horse"]) + - (if h = 5 then 0 else pet[h+1,"horse"]) >= 1; - -/* the Lucky Strike smoker drinks orange juice */ -f13{h in HOUSE}: smoke[h,"Lucky_Strike"] = drink[h,"orange_juice"]; - -/* the Japanese smokes Parliaments */ -f14{h in HOUSE}: nationality[h,"Japanese"] = smoke[h,"Parliament"]; - -/* the Norwegian lives next to the blue house */ -f15{h in HOUSE}: - (1 - nationality[h,"Norwegian"]) + - (if h = 1 then 0 else color[h-1,"blue"]) + - (if h = 5 then 0 else color[h+1,"blue"]) >= 1; - -solve; - -printf "\n"; -printf "HOUSE COLOR NATIONALITY DRINK SMOKE PET\n"; -for {h in HOUSE} -{ printf "%5d", h; - printf{c in COLOR: color[h,c]} " %-6s", c; - printf{n in NATIONALITY: nationality[h,n]} " %-11s", n; - printf{d in DRINK: drink[h,d]} " %-12s", d; - printf{s in SMOKE: smoke[h,s]} " %-12s", s; - printf{p in PET: pet[h,p]} " %-6s", p; - printf "\n"; -} -printf "\n"; - -end; diff --git a/resources/3rdparty/glpk-4.53/install-sh b/resources/3rdparty/glpk-4.53/install-sh deleted file mode 100644 index 377bb8687..000000000 --- a/resources/3rdparty/glpk-4.53/install-sh +++ /dev/null @@ -1,527 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2011-11-20.07; # UTC - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# 'make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -nl=' -' -IFS=" "" $nl" - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -chgrpprog=${CHGRPPROG-chgrp} -chmodprog=${CHMODPROG-chmod} -chownprog=${CHOWNPROG-chown} -cmpprog=${CMPPROG-cmp} -cpprog=${CPPROG-cp} -mkdirprog=${MKDIRPROG-mkdir} -mvprog=${MVPROG-mv} -rmprog=${RMPROG-rm} -stripprog=${STRIPPROG-strip} - -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -chgrpcmd= -chmodcmd=$chmodprog -chowncmd= -mvcmd=$mvprog -rmcmd="$rmprog -f" -stripcmd= - -src= -dst= -dir_arg= -dst_arg= - -copy_on_change=false -no_target_directory= - -usage="\ -Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: - --help display this help and exit. - --version display version info and exit. - - -c (ignored) - -C install only if different (preserve the last data modification time) - -d create directories instead of installing files. - -g GROUP $chgrpprog installed files to GROUP. - -m MODE $chmodprog installed files to MODE. - -o USER $chownprog installed files to USER. - -s $stripprog installed files. - -t DIRECTORY install into DIRECTORY. - -T report an error if DSTFILE is a directory. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG - RMPROG STRIPPROG -" - -while test $# -ne 0; do - case $1 in - -c) ;; - - -C) copy_on_change=true;; - - -d) dir_arg=true;; - - -g) chgrpcmd="$chgrpprog $2" - shift;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; - - -o) chowncmd="$chownprog $2" - shift;; - - -s) stripcmd=$stripprog;; - - -t) dst_arg=$2 - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - shift;; - - -T) no_target_directory=true;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac - shift -done - -if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dst_arg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dst_arg" - shift # fnord - fi - shift # arg - dst_arg=$arg - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call 'install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - do_exit='(exit $ret); exit $ret' - trap "ret=129; $do_exit" 1 - trap "ret=130; $do_exit" 2 - trap "ret=141; $do_exit" 13 - trap "ret=143; $do_exit" 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names problematic for 'test' and other utilities. - case $src in - -* | [=\(\)!]) src=./$src;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dst_arg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - dst=$dst_arg - - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dst=$dstdir/`basename "$src"` - dstdir_status=0 - else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - - test -d "$dstdir" - dstdir_status=$? - fi - fi - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # The umask is ridiculous, or mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix='/';; - [-=\(\)!]*) prefix='./';; - *) prefix='';; - esac - - eval "$initialize_posix_glob" - - oIFS=$IFS - IFS=/ - $posix_glob set -f - set fnord $dstdir - shift - $posix_glob set +f - IFS=$oIFS - - prefixes= - - for d - do - test X"$d" = X && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && - { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && - { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # If -C, don't bother to copy if it wouldn't change the file. - if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && - set X $old && old=:$2:$4:$5:$6 && - set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - - test "$old" = "$new" && - $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 - then - rm -f "$dsttmp" - else - # Rename the file to the real destination. - $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - fi || exit 1 - - trap '' 0 - fi -done - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/resources/3rdparty/glpk-4.53/ltmain.sh b/resources/3rdparty/glpk-4.53/ltmain.sh deleted file mode 100644 index fcebbcb5f..000000000 --- a/resources/3rdparty/glpk-4.53/ltmain.sh +++ /dev/null @@ -1,9687 +0,0 @@ - -# libtool (GNU libtool) 2.4 -# Written by Gordon Matzigkeit , 1996 - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, -# 2007, 2008, 2009, 2010 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# GNU Libtool is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, -# or obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -# Usage: $progname [OPTION]... [MODE-ARG]... -# -# Provide generalized library-building support services. -# -# --config show all configuration variables -# --debug enable verbose shell tracing -# -n, --dry-run display commands without modifying any files -# --features display basic configuration information and exit -# --mode=MODE use operation mode MODE -# --preserve-dup-deps don't remove duplicate dependency libraries -# --quiet, --silent don't print informational messages -# --no-quiet, --no-silent -# print informational messages (default) -# --tag=TAG use configuration variables from tag TAG -# -v, --verbose print more informational messages than default -# --no-verbose don't print the extra informational messages -# --version print version information -# -h, --help, --help-all print short, long, or detailed help message -# -# MODE must be one of the following: -# -# clean remove files from the build directory -# compile compile a source file into a libtool object -# execute automatically set library path, then run a program -# finish complete the installation of libtool libraries -# install install libraries or executables -# link create a library or an executable -# uninstall remove libraries from an installed directory -# -# MODE-ARGS vary depending on the MODE. When passed as first option, -# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. -# Try `$progname --help --mode=MODE' for a more detailed description of MODE. -# -# When reporting a bug, please describe a test case to reproduce it and -# include the following information: -# -# host-triplet: $host -# shell: $SHELL -# compiler: $LTCC -# compiler flags: $LTCFLAGS -# linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.4 -# automake: $automake_version -# autoconf: $autoconf_version -# -# Report bugs to . -# GNU libtool home page: . -# General help using GNU software: . - -PROGRAM=libtool -PACKAGE=libtool -VERSION=2.4 -TIMESTAMP="" -package_revision=1.3294 - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' -} - -# NLS nuisances: We save the old values to restore during execute mode. -lt_user_locale= -lt_safe_locale= -for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES -do - eval "if test \"\${$lt_var+set}\" = set; then - save_$lt_var=\$$lt_var - $lt_var=C - export $lt_var - lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" - lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" - fi" -done -LC_ALL=C -LANGUAGE=C -export LANGUAGE LC_ALL - -$lt_unset CDPATH - - -# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh -# is ksh but when the shell is invoked as "sh" and the current value of -# the _XPG environment variable is not equal to 1 (one), the special -# positional parameter $0, within a function call, is the name of the -# function. -progpath="$0" - - - -: ${CP="cp -f"} -test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} -: ${EGREP="/usr/bin/grep -E"} -: ${FGREP="/usr/bin/grep -F"} -: ${GREP="/usr/bin/grep"} -: ${LN_S="ln -s"} -: ${MAKE="make"} -: ${MKDIR="mkdir"} -: ${MV="mv -f"} -: ${RM="rm -f"} -: ${SED="/usr/bin/sed"} -: ${SHELL="${CONFIG_SHELL-/bin/sh}"} -: ${Xsed="$SED -e 1s/^X//"} - -# Global variables: -EXIT_SUCCESS=0 -EXIT_FAILURE=1 -EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. -EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. - -exit_status=$EXIT_SUCCESS - -# Make sure IFS has a sensible default -lt_nl=' -' -IFS=" $lt_nl" - -dirname="s,/[^/]*$,," -basename="s,^.*/,," - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} # func_dirname may be replaced by extended shell implementation - - -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "${1}" | $SED "$basename"` -} # func_basename may be replaced by extended shell implementation - - -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi - func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` -} # func_dirname_and_basename may be replaced by extended shell implementation - - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} # func_stripname may be replaced by extended shell implementation - - -# These SED scripts presuppose an absolute path with a trailing slash. -pathcar='s,^/\([^/]*\).*$,\1,' -pathcdr='s,^/[^/]*,,' -removedotparts=':dotsl - s@/\./@/@g - t dotsl - s,/\.$,/,' -collapseslashes='s@/\{1,\}@/@g' -finalslash='s,/*$,/,' - -# func_normal_abspath PATH -# Remove doubled-up and trailing slashes, "." path components, -# and cancel out any ".." path components in PATH after making -# it an absolute path. -# value returned in "$func_normal_abspath_result" -func_normal_abspath () -{ - # Start from root dir and reassemble the path. - func_normal_abspath_result= - func_normal_abspath_tpath=$1 - func_normal_abspath_altnamespace= - case $func_normal_abspath_tpath in - "") - # Empty path, that just means $cwd. - func_stripname '' '/' "`pwd`" - func_normal_abspath_result=$func_stripname_result - return - ;; - # The next three entries are used to spot a run of precisely - # two leading slashes without using negated character classes; - # we take advantage of case's first-match behaviour. - ///*) - # Unusual form of absolute path, do nothing. - ;; - //*) - # Not necessarily an ordinary path; POSIX reserves leading '//' - # and for example Cygwin uses it to access remote file shares - # over CIFS/SMB, so we conserve a leading double slash if found. - func_normal_abspath_altnamespace=/ - ;; - /*) - # Absolute path, do nothing. - ;; - *) - # Relative path, prepend $cwd. - func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath - ;; - esac - # Cancel out all the simple stuff to save iterations. We also want - # the path to end with a slash for ease of parsing, so make sure - # there is one (and only one) here. - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` - while :; do - # Processed it all yet? - if test "$func_normal_abspath_tpath" = / ; then - # If we ascended to the root using ".." the result may be empty now. - if test -z "$func_normal_abspath_result" ; then - func_normal_abspath_result=/ - fi - break - fi - func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$pathcar"` - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$pathcdr"` - # Figure out what to do with it - case $func_normal_abspath_tcomponent in - "") - # Trailing empty path component, ignore it. - ;; - ..) - # Parent dir; strip last assembled component from result. - func_dirname "$func_normal_abspath_result" - func_normal_abspath_result=$func_dirname_result - ;; - *) - # Actual path component, append it. - func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent - ;; - esac - done - # Restore leading double-slash if one was found on entry. - func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result -} - -# func_relative_path SRCDIR DSTDIR -# generates a relative path from SRCDIR to DSTDIR, with a trailing -# slash if non-empty, suitable for immediately appending a filename -# without needing to append a separator. -# value returned in "$func_relative_path_result" -func_relative_path () -{ - func_relative_path_result= - func_normal_abspath "$1" - func_relative_path_tlibdir=$func_normal_abspath_result - func_normal_abspath "$2" - func_relative_path_tbindir=$func_normal_abspath_result - - # Ascend the tree starting from libdir - while :; do - # check if we have found a prefix of bindir - case $func_relative_path_tbindir in - $func_relative_path_tlibdir) - # found an exact match - func_relative_path_tcancelled= - break - ;; - $func_relative_path_tlibdir*) - # found a matching prefix - func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" - func_relative_path_tcancelled=$func_stripname_result - if test -z "$func_relative_path_result"; then - func_relative_path_result=. - fi - break - ;; - *) - func_dirname $func_relative_path_tlibdir - func_relative_path_tlibdir=${func_dirname_result} - if test "x$func_relative_path_tlibdir" = x ; then - # Have to descend all the way to the root! - func_relative_path_result=../$func_relative_path_result - func_relative_path_tcancelled=$func_relative_path_tbindir - break - fi - func_relative_path_result=../$func_relative_path_result - ;; - esac - done - - # Now calculate path; take care to avoid doubling-up slashes. - func_stripname '' '/' "$func_relative_path_result" - func_relative_path_result=$func_stripname_result - func_stripname '/' '/' "$func_relative_path_tcancelled" - if test "x$func_stripname_result" != x ; then - func_relative_path_result=${func_relative_path_result}/${func_stripname_result} - fi - - # Normalisation. If bindir is libdir, return empty string, - # else relative path ending with a slash; either way, target - # file name can be directly appended. - if test ! -z "$func_relative_path_result"; then - func_stripname './' '' "$func_relative_path_result/" - func_relative_path_result=$func_stripname_result - fi -} - -# The name of this program: -func_dirname_and_basename "$progpath" -progname=$func_basename_result - -# Make sure we have an absolute path for reexecution: -case $progpath in - [\\/]*|[A-Za-z]:\\*) ;; - *[\\/]*) - progdir=$func_dirname_result - progdir=`cd "$progdir" && pwd` - progpath="$progdir/$progname" - ;; - *) - save_IFS="$IFS" - IFS=: - for progdir in $PATH; do - IFS="$save_IFS" - test -x "$progdir/$progname" && break - done - IFS="$save_IFS" - test -n "$progdir" || progdir=`pwd` - progpath="$progdir/$progname" - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed="${SED}"' -e 1s/^X//' -sed_quote_subst='s/\([`"$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution that turns a string into a regex matching for the -# string literally. -sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' - -# Sed substitution that converts a w32 file name or path -# which contains forward slashes, into one that contains -# (escaped) backslashes. A very naive implementation. -lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' - -# Re-`\' parameter expansions in output of double_quote_subst that were -# `\'-ed in input to the same. If an odd number of `\' preceded a '$' -# in input to double_quote_subst, that '$' was protected from expansion. -# Since each input `\' is now two `\'s, look for any number of runs of -# four `\'s followed by two `\'s and then a '$'. `\' that '$'. -bs='\\' -bs2='\\\\' -bs4='\\\\\\\\' -dollar='\$' -sed_double_backslash="\ - s/$bs4/&\\ -/g - s/^$bs2$dollar/$bs&/ - s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g - s/\n//g" - -# Standard options: -opt_dry_run=false -opt_help=false -opt_quiet=false -opt_verbose=false -opt_warning=: - -# func_echo arg... -# Echo program name prefixed message, along with the current mode -# name if it has been set yet. -func_echo () -{ - $ECHO "$progname: ${opt_mode+$opt_mode: }$*" -} - -# func_verbose arg... -# Echo program name prefixed message in verbose mode only. -func_verbose () -{ - $opt_verbose && func_echo ${1+"$@"} - - # A bug in bash halts the script if the last line of a function - # fails when set -e is in force, so we need another command to - # work around that: - : -} - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} - -# func_error arg... -# Echo program name prefixed message to standard error. -func_error () -{ - $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 -} - -# func_warning arg... -# Echo program name prefixed warning message to standard error. -func_warning () -{ - $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 - - # bash bug again: - : -} - -# func_fatal_error arg... -# Echo program name prefixed message to standard error, and exit. -func_fatal_error () -{ - func_error ${1+"$@"} - exit $EXIT_FAILURE -} - -# func_fatal_help arg... -# Echo program name prefixed message to standard error, followed by -# a help hint, and exit. -func_fatal_help () -{ - func_error ${1+"$@"} - func_fatal_error "$help" -} -help="Try \`$progname --help' for more information." ## default - - -# func_grep expression filename -# Check whether EXPRESSION matches any line of FILENAME, without output. -func_grep () -{ - $GREP "$1" "$2" >/dev/null 2>&1 -} - - -# func_mkdir_p directory-path -# Make sure the entire path to DIRECTORY-PATH is available. -func_mkdir_p () -{ - my_directory_path="$1" - my_dir_list= - - if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then - - # Protect directory names starting with `-' - case $my_directory_path in - -*) my_directory_path="./$my_directory_path" ;; - esac - - # While some portion of DIR does not yet exist... - while test ! -d "$my_directory_path"; do - # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. - my_dir_list="$my_directory_path:$my_dir_list" - - # If the last portion added has no slash in it, the list is done - case $my_directory_path in */*) ;; *) break ;; esac - - # ...otherwise throw away the child directory and loop - my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` - done - my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` - - save_mkdir_p_IFS="$IFS"; IFS=':' - for my_dir in $my_dir_list; do - IFS="$save_mkdir_p_IFS" - # mkdir can fail with a `File exist' error if two processes - # try to create one of the directories concurrently. Don't - # stop in that case! - $MKDIR "$my_dir" 2>/dev/null || : - done - IFS="$save_mkdir_p_IFS" - - # Bail out if we (or some other process) failed to create a directory. - test -d "$my_directory_path" || \ - func_fatal_error "Failed to create \`$1'" - fi -} - - -# func_mktempdir [string] -# Make a temporary directory that won't clash with other running -# libtool processes, and avoids race conditions if possible. If -# given, STRING is the basename for that directory. -func_mktempdir () -{ - my_template="${TMPDIR-/tmp}/${1-$progname}" - - if test "$opt_dry_run" = ":"; then - # Return a directory name, but don't create it in dry-run mode - my_tmpdir="${my_template}-$$" - else - - # If mktemp works, use that first and foremost - my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` - - if test ! -d "$my_tmpdir"; then - # Failing that, at least try and use $RANDOM to avoid a race - my_tmpdir="${my_template}-${RANDOM-0}$$" - - save_mktempdir_umask=`umask` - umask 0077 - $MKDIR "$my_tmpdir" - umask $save_mktempdir_umask - fi - - # If we're not in dry-run mode, bomb out on failure - test -d "$my_tmpdir" || \ - func_fatal_error "cannot create temporary directory \`$my_tmpdir'" - fi - - $ECHO "$my_tmpdir" -} - - -# func_quote_for_eval arg -# Aesthetically quote ARG to be evaled later. -# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT -# is double-quoted, suitable for a subsequent eval, whereas -# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters -# which are still active within double quotes backslashified. -func_quote_for_eval () -{ - case $1 in - *[\\\`\"\$]*) - func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; - *) - func_quote_for_eval_unquoted_result="$1" ;; - esac - - case $func_quote_for_eval_unquoted_result in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and and variable - # expansion for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" - ;; - *) - func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" - esac -} - - -# func_quote_for_expand arg -# Aesthetically quote ARG to be evaled later; same as above, -# but do not quote variable references. -func_quote_for_expand () -{ - case $1 in - *[\\\`\"]*) - my_arg=`$ECHO "$1" | $SED \ - -e "$double_quote_subst" -e "$sed_double_backslash"` ;; - *) - my_arg="$1" ;; - esac - - case $my_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting and command substitution for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - my_arg="\"$my_arg\"" - ;; - esac - - func_quote_for_expand_result="$my_arg" -} - - -# func_show_eval cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. -func_show_eval () -{ - my_cmd="$1" - my_fail_exp="${2-:}" - - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } - - if ${opt_dry_run-false}; then :; else - eval "$my_cmd" - my_status=$? - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" - fi - fi -} - - -# func_show_eval_locale cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. Use the saved locale for evaluation. -func_show_eval_locale () -{ - my_cmd="$1" - my_fail_exp="${2-:}" - - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } - - if ${opt_dry_run-false}; then :; else - eval "$lt_user_locale - $my_cmd" - my_status=$? - eval "$lt_safe_locale" - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" - fi - fi -} - -# func_tr_sh -# Turn $1 into a string suitable for a shell variable name. -# Result is stored in $func_tr_sh_result. All characters -# not in the set a-zA-Z0-9_ are replaced with '_'. Further, -# if $1 begins with a digit, a '_' is prepended as well. -func_tr_sh () -{ - case $1 in - [0-9]* | *[!a-zA-Z0-9_]*) - func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` - ;; - * ) - func_tr_sh_result=$1 - ;; - esac -} - - -# func_version -# Echo version message to standard output and exit. -func_version () -{ - $opt_debug - - $SED -n '/(C)/!b go - :more - /\./!{ - N - s/\n# / / - b more - } - :go - /^# '$PROGRAM' (GNU /,/# warranty; / { - s/^# // - s/^# *$// - s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ - p - }' < "$progpath" - exit $? -} - -# func_usage -# Echo short help message to standard output and exit. -func_usage () -{ - $opt_debug - - $SED -n '/^# Usage:/,/^# *.*--help/ { - s/^# // - s/^# *$// - s/\$progname/'$progname'/ - p - }' < "$progpath" - echo - $ECHO "run \`$progname --help | more' for full usage" - exit $? -} - -# func_help [NOEXIT] -# Echo long help message to standard output and exit, -# unless 'noexit' is passed as argument. -func_help () -{ - $opt_debug - - $SED -n '/^# Usage:/,/# Report bugs to/ { - :print - s/^# // - s/^# *$// - s*\$progname*'$progname'* - s*\$host*'"$host"'* - s*\$SHELL*'"$SHELL"'* - s*\$LTCC*'"$LTCC"'* - s*\$LTCFLAGS*'"$LTCFLAGS"'* - s*\$LD*'"$LD"'* - s/\$with_gnu_ld/'"$with_gnu_ld"'/ - s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ - s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ - p - d - } - /^# .* home page:/b print - /^# General help using/b print - ' < "$progpath" - ret=$? - if test -z "$1"; then - exit $ret - fi -} - -# func_missing_arg argname -# Echo program name prefixed message to standard error and set global -# exit_cmd. -func_missing_arg () -{ - $opt_debug - - func_error "missing argument for $1." - exit_cmd=exit -} - - -# func_split_short_opt shortopt -# Set func_split_short_opt_name and func_split_short_opt_arg shell -# variables after splitting SHORTOPT after the 2nd character. -func_split_short_opt () -{ - my_sed_short_opt='1s/^\(..\).*$/\1/;q' - my_sed_short_rest='1s/^..\(.*\)$/\1/;q' - - func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` - func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` -} # func_split_short_opt may be replaced by extended shell implementation - - -# func_split_long_opt longopt -# Set func_split_long_opt_name and func_split_long_opt_arg shell -# variables after splitting LONGOPT at the `=' sign. -func_split_long_opt () -{ - my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' - my_sed_long_arg='1s/^--[^=]*=//' - - func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` - func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` -} # func_split_long_opt may be replaced by extended shell implementation - -exit_cmd=: - - - - - -magic="%%%MAGIC variable%%%" -magic_exe="%%%MAGIC EXE variable%%%" - -# Global variables. -nonopt= -preserve_args= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" -extracted_archives= -extracted_serial=0 - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "${1}=\$${1}\${2}" -} # func_append may be replaced by extended shell implementation - -# func_append_quoted var value -# Quote VALUE and append to the end of shell variable VAR, separated -# by a space. -func_append_quoted () -{ - func_quote_for_eval "${2}" - eval "${1}=\$${1}\\ \$func_quote_for_eval_result" -} # func_append_quoted may be replaced by extended shell implementation - - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=`expr "${@}"` -} # func_arith may be replaced by extended shell implementation - - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` -} # func_len may be replaced by extended shell implementation - - -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` -} # func_lo2o may be replaced by extended shell implementation - - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` -} # func_xform may be replaced by extended shell implementation - - -# func_fatal_configuration arg... -# Echo program name prefixed message to standard error, followed by -# a configuration failure hint, and exit. -func_fatal_configuration () -{ - func_error ${1+"$@"} - func_error "See the $PACKAGE documentation for more information." - func_fatal_error "Fatal configuration error." -} - - -# func_config -# Display the configuration for all the tags in this script. -func_config () -{ - re_begincf='^# ### BEGIN LIBTOOL' - re_endcf='^# ### END LIBTOOL' - - # Default configuration. - $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" - - # Now print the configurations for the tags. - for tagname in $taglist; do - $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" - done - - exit $? -} - -# func_features -# Display the features supported by this script. -func_features () -{ - echo "host: $host" - if test "$build_libtool_libs" = yes; then - echo "enable shared libraries" - else - echo "disable shared libraries" - fi - if test "$build_old_libs" = yes; then - echo "enable static libraries" - else - echo "disable static libraries" - fi - - exit $? -} - -# func_enable_tag tagname -# Verify that TAGNAME is valid, and either flag an error and exit, or -# enable the TAGNAME tag. We also add TAGNAME to the global $taglist -# variable here. -func_enable_tag () -{ - # Global variable: - tagname="$1" - - re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" - re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" - sed_extractcf="/$re_begincf/,/$re_endcf/p" - - # Validate tagname. - case $tagname in - *[!-_A-Za-z0-9,/]*) - func_fatal_error "invalid tag name: $tagname" - ;; - esac - - # Don't test for the "default" C tag, as we know it's - # there but not specially marked. - case $tagname in - CC) ;; - *) - if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then - taglist="$taglist $tagname" - - # Evaluate the configuration. Be careful to quote the path - # and the sed script, to avoid splitting on whitespace, but - # also don't use non-portable quotes within backquotes within - # quotes we have to do it in 2 steps: - extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` - eval "$extractedcf" - else - func_error "ignoring unknown tag $tagname" - fi - ;; - esac -} - -# func_check_version_match -# Ensure that we are using m4 macros, and libtool script from the same -# release of libtool. -func_check_version_match () -{ - if test "$package_revision" != "$macro_revision"; then - if test "$VERSION" != "$macro_version"; then - if test -z "$macro_version"; then - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from an older release. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - fi - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, -$progname: but the definition of this LT_INIT comes from revision $macro_revision. -$progname: You should recreate aclocal.m4 with macros from revision $package_revision -$progname: of $PACKAGE $VERSION and run autoconf again. -_LT_EOF - fi - - exit $EXIT_MISMATCH - fi -} - - -# Shorthand for --mode=foo, only valid as the first argument -case $1 in -clean|clea|cle|cl) - shift; set dummy --mode clean ${1+"$@"}; shift - ;; -compile|compil|compi|comp|com|co|c) - shift; set dummy --mode compile ${1+"$@"}; shift - ;; -execute|execut|execu|exec|exe|ex|e) - shift; set dummy --mode execute ${1+"$@"}; shift - ;; -finish|finis|fini|fin|fi|f) - shift; set dummy --mode finish ${1+"$@"}; shift - ;; -install|instal|insta|inst|ins|in|i) - shift; set dummy --mode install ${1+"$@"}; shift - ;; -link|lin|li|l) - shift; set dummy --mode link ${1+"$@"}; shift - ;; -uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) - shift; set dummy --mode uninstall ${1+"$@"}; shift - ;; -esac - - - -# Option defaults: -opt_debug=: -opt_dry_run=false -opt_config=false -opt_preserve_dup_deps=false -opt_features=false -opt_finish=false -opt_help=false -opt_help_all=false -opt_silent=: -opt_verbose=: -opt_silent=false -opt_verbose=false - - -# Parse options once, thoroughly. This comes as soon as possible in the -# script to make things like `--version' happen as quickly as we can. -{ - # this just eases exit handling - while test $# -gt 0; do - opt="$1" - shift - case $opt in - --debug|-x) opt_debug='set -x' - func_echo "enabling shell trace mode" - $opt_debug - ;; - --dry-run|--dryrun|-n) - opt_dry_run=: - ;; - --config) - opt_config=: -func_config - ;; - --dlopen|-dlopen) - optarg="$1" - opt_dlopen="${opt_dlopen+$opt_dlopen -}$optarg" - shift - ;; - --preserve-dup-deps) - opt_preserve_dup_deps=: - ;; - --features) - opt_features=: -func_features - ;; - --finish) - opt_finish=: -set dummy --mode finish ${1+"$@"}; shift - ;; - --help) - opt_help=: - ;; - --help-all) - opt_help_all=: -opt_help=': help-all' - ;; - --mode) - test $# = 0 && func_missing_arg $opt && break - optarg="$1" - opt_mode="$optarg" -case $optarg in - # Valid mode arguments: - clean|compile|execute|finish|install|link|relink|uninstall) ;; - - # Catch anything else as an error - *) func_error "invalid argument for $opt" - exit_cmd=exit - break - ;; -esac - shift - ;; - --no-silent|--no-quiet) - opt_silent=false -func_append preserve_args " $opt" - ;; - --no-verbose) - opt_verbose=false -func_append preserve_args " $opt" - ;; - --silent|--quiet) - opt_silent=: -func_append preserve_args " $opt" - opt_verbose=false - ;; - --verbose|-v) - opt_verbose=: -func_append preserve_args " $opt" -opt_silent=false - ;; - --tag) - test $# = 0 && func_missing_arg $opt && break - optarg="$1" - opt_tag="$optarg" -func_append preserve_args " $opt $optarg" -func_enable_tag "$optarg" - shift - ;; - - -\?|-h) func_usage ;; - --help) func_help ;; - --version) func_version ;; - - # Separate optargs to long options: - --*=*) - func_split_long_opt "$opt" - set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} - shift - ;; - - # Separate non-argument short options: - -\?*|-h*|-n*|-v*) - func_split_short_opt "$opt" - set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} - shift - ;; - - --) break ;; - -*) func_fatal_help "unrecognized option \`$opt'" ;; - *) set dummy "$opt" ${1+"$@"}; shift; break ;; - esac - done - - # Validate options: - - # save first non-option argument - if test "$#" -gt 0; then - nonopt="$opt" - shift - fi - - # preserve --debug - test "$opt_debug" = : || func_append preserve_args " --debug" - - case $host in - *cygwin* | *mingw* | *pw32* | *cegcc*) - # don't eliminate duplications in $postdeps and $predeps - opt_duplicate_compiler_generated_deps=: - ;; - *) - opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps - ;; - esac - - $opt_help || { - # Sanity checks first: - func_check_version_match - - if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then - func_fatal_configuration "not configured to build any kind of library" - fi - - # Darwin sucks - eval std_shrext=\"$shrext_cmds\" - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$opt_dlopen" && test "$opt_mode" != execute; then - func_error "unrecognized option \`-dlopen'" - $ECHO "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$progname --help --mode=$opt_mode' for more information." - } - - - # Bail if the options were screwed - $exit_cmd $EXIT_FAILURE -} - - - - -## ----------- ## -## Main. ## -## ----------- ## - -# func_lalib_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_lalib_p () -{ - test -f "$1" && - $SED -e 4q "$1" 2>/dev/null \ - | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 -} - -# func_lalib_unsafe_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. -# This function implements the same check as func_lalib_p without -# resorting to external programs. To this end, it redirects stdin and -# closes it afterwards, without saving the original file descriptor. -# As a safety measure, use it only where a negative result would be -# fatal anyway. Works if `file' does not exist. -func_lalib_unsafe_p () -{ - lalib_p=no - if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then - for lalib_p_l in 1 2 3 4 - do - read lalib_p_line - case "$lalib_p_line" in - \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; - esac - done - exec 0<&5 5<&- - fi - test "$lalib_p" = yes -} - -# func_ltwrapper_script_p file -# True iff FILE is a libtool wrapper script -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_script_p () -{ - func_lalib_p "$1" -} - -# func_ltwrapper_executable_p file -# True iff FILE is a libtool wrapper executable -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_executable_p () -{ - func_ltwrapper_exec_suffix= - case $1 in - *.exe) ;; - *) func_ltwrapper_exec_suffix=.exe ;; - esac - $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 -} - -# func_ltwrapper_scriptname file -# Assumes file is an ltwrapper_executable -# uses $file to determine the appropriate filename for a -# temporary ltwrapper_script. -func_ltwrapper_scriptname () -{ - func_dirname_and_basename "$1" "" "." - func_stripname '' '.exe' "$func_basename_result" - func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" -} - -# func_ltwrapper_p file -# True iff FILE is a libtool wrapper script or wrapper executable -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_p () -{ - func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" -} - - -# func_execute_cmds commands fail_cmd -# Execute tilde-delimited COMMANDS. -# If FAIL_CMD is given, eval that upon failure. -# FAIL_CMD may read-access the current command in variable CMD! -func_execute_cmds () -{ - $opt_debug - save_ifs=$IFS; IFS='~' - for cmd in $1; do - IFS=$save_ifs - eval cmd=\"$cmd\" - func_show_eval "$cmd" "${2-:}" - done - IFS=$save_ifs -} - - -# func_source file -# Source FILE, adding directory component if necessary. -# Note that it is not necessary on cygwin/mingw to append a dot to -# FILE even if both FILE and FILE.exe exist: automatic-append-.exe -# behavior happens only for exec(3), not for open(2)! Also, sourcing -# `FILE.' does not work on cygwin managed mounts. -func_source () -{ - $opt_debug - case $1 in - */* | *\\*) . "$1" ;; - *) . "./$1" ;; - esac -} - - -# func_resolve_sysroot PATH -# Replace a leading = in PATH with a sysroot. Store the result into -# func_resolve_sysroot_result -func_resolve_sysroot () -{ - func_resolve_sysroot_result=$1 - case $func_resolve_sysroot_result in - =*) - func_stripname '=' '' "$func_resolve_sysroot_result" - func_resolve_sysroot_result=$lt_sysroot$func_stripname_result - ;; - esac -} - -# func_replace_sysroot PATH -# If PATH begins with the sysroot, replace it with = and -# store the result into func_replace_sysroot_result. -func_replace_sysroot () -{ - case "$lt_sysroot:$1" in - ?*:"$lt_sysroot"*) - func_stripname "$lt_sysroot" '' "$1" - func_replace_sysroot_result="=$func_stripname_result" - ;; - *) - # Including no sysroot. - func_replace_sysroot_result=$1 - ;; - esac -} - -# func_infer_tag arg -# Infer tagged configuration to use if any are available and -# if one wasn't chosen via the "--tag" command line option. -# Only attempt this if the compiler in the base compile -# command doesn't match the default compiler. -# arg is usually of the form 'gcc ...' -func_infer_tag () -{ - $opt_debug - if test -n "$available_tags" && test -z "$tagname"; then - CC_quoted= - for arg in $CC; do - func_append_quoted CC_quoted "$arg" - done - CC_expanded=`func_echo_all $CC` - CC_quoted_expanded=`func_echo_all $CC_quoted` - case $@ in - # Blanks in the command may have been stripped by the calling shell, - # but not from the CC environment variable when configure was run. - " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ - " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; - # Blanks at the start of $base_compile will cause this to fail - # if we don't check for them as well. - *) - for z in $available_tags; do - if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" - CC_quoted= - for arg in $CC; do - # Double-quote args containing other shell metacharacters. - func_append_quoted CC_quoted "$arg" - done - CC_expanded=`func_echo_all $CC` - CC_quoted_expanded=`func_echo_all $CC_quoted` - case "$@ " in - " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ - " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) - # The compiler in the base compile command matches - # the one in the tagged configuration. - # Assume this is the tagged configuration we want. - tagname=$z - break - ;; - esac - fi - done - # If $tagname still isn't set, then no tagged configuration - # was found and let the user know that the "--tag" command - # line option must be used. - if test -z "$tagname"; then - func_echo "unable to infer tagged configuration" - func_fatal_error "specify a tag with \`--tag'" -# else -# func_verbose "using $tagname tagged configuration" - fi - ;; - esac - fi -} - - - -# func_write_libtool_object output_name pic_name nonpic_name -# Create a libtool object file (analogous to a ".la" file), -# but don't create it if we're doing a dry run. -func_write_libtool_object () -{ - write_libobj=${1} - if test "$build_libtool_libs" = yes; then - write_lobj=\'${2}\' - else - write_lobj=none - fi - - if test "$build_old_libs" = yes; then - write_oldobj=\'${3}\' - else - write_oldobj=none - fi - - $opt_dry_run || { - cat >${write_libobj}T </dev/null` - if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then - func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | - $SED -e "$lt_sed_naive_backslashify"` - else - func_convert_core_file_wine_to_w32_result= - fi - fi -} -# end: func_convert_core_file_wine_to_w32 - - -# func_convert_core_path_wine_to_w32 ARG -# Helper function used by path conversion functions when $build is *nix, and -# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly -# configured wine environment available, with the winepath program in $build's -# $PATH. Assumes ARG has no leading or trailing path separator characters. -# -# ARG is path to be converted from $build format to win32. -# Result is available in $func_convert_core_path_wine_to_w32_result. -# Unconvertible file (directory) names in ARG are skipped; if no directory names -# are convertible, then the result may be empty. -func_convert_core_path_wine_to_w32 () -{ - $opt_debug - # unfortunately, winepath doesn't convert paths, only file names - func_convert_core_path_wine_to_w32_result="" - if test -n "$1"; then - oldIFS=$IFS - IFS=: - for func_convert_core_path_wine_to_w32_f in $1; do - IFS=$oldIFS - func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" - if test -n "$func_convert_core_file_wine_to_w32_result" ; then - if test -z "$func_convert_core_path_wine_to_w32_result"; then - func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" - else - func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" - fi - fi - done - IFS=$oldIFS - fi -} -# end: func_convert_core_path_wine_to_w32 - - -# func_cygpath ARGS... -# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when -# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) -# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or -# (2), returns the Cygwin file name or path in func_cygpath_result (input -# file name or path is assumed to be in w32 format, as previously converted -# from $build's *nix or MSYS format). In case (3), returns the w32 file name -# or path in func_cygpath_result (input file name or path is assumed to be in -# Cygwin format). Returns an empty string on error. -# -# ARGS are passed to cygpath, with the last one being the file name or path to -# be converted. -# -# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH -# environment variable; do not put it in $PATH. -func_cygpath () -{ - $opt_debug - if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then - func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` - if test "$?" -ne 0; then - # on failure, ensure result is empty - func_cygpath_result= - fi - else - func_cygpath_result= - func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" - fi -} -#end: func_cygpath - - -# func_convert_core_msys_to_w32 ARG -# Convert file name or path ARG from MSYS format to w32 format. Return -# result in func_convert_core_msys_to_w32_result. -func_convert_core_msys_to_w32 () -{ - $opt_debug - # awkward: cmd appends spaces to result - func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | - $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` -} -#end: func_convert_core_msys_to_w32 - - -# func_convert_file_check ARG1 ARG2 -# Verify that ARG1 (a file name in $build format) was converted to $host -# format in ARG2. Otherwise, emit an error message, but continue (resetting -# func_to_host_file_result to ARG1). -func_convert_file_check () -{ - $opt_debug - if test -z "$2" && test -n "$1" ; then - func_error "Could not determine host file name corresponding to" - func_error " \`$1'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback: - func_to_host_file_result="$1" - fi -} -# end func_convert_file_check - - -# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH -# Verify that FROM_PATH (a path in $build format) was converted to $host -# format in TO_PATH. Otherwise, emit an error message, but continue, resetting -# func_to_host_file_result to a simplistic fallback value (see below). -func_convert_path_check () -{ - $opt_debug - if test -z "$4" && test -n "$3"; then - func_error "Could not determine the host path corresponding to" - func_error " \`$3'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback. This is a deliberately simplistic "conversion" and - # should not be "improved". See libtool.info. - if test "x$1" != "x$2"; then - lt_replace_pathsep_chars="s|$1|$2|g" - func_to_host_path_result=`echo "$3" | - $SED -e "$lt_replace_pathsep_chars"` - else - func_to_host_path_result="$3" - fi - fi -} -# end func_convert_path_check - - -# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG -# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT -# and appending REPL if ORIG matches BACKPAT. -func_convert_path_front_back_pathsep () -{ - $opt_debug - case $4 in - $1 ) func_to_host_path_result="$3$func_to_host_path_result" - ;; - esac - case $4 in - $2 ) func_append func_to_host_path_result "$3" - ;; - esac -} -# end func_convert_path_front_back_pathsep - - -################################################## -# $build to $host FILE NAME CONVERSION FUNCTIONS # -################################################## -# invoked via `$to_host_file_cmd ARG' -# -# In each case, ARG is the path to be converted from $build to $host format. -# Result will be available in $func_to_host_file_result. - - -# func_to_host_file ARG -# Converts the file name ARG from $build format to $host format. Return result -# in func_to_host_file_result. -func_to_host_file () -{ - $opt_debug - $to_host_file_cmd "$1" -} -# end func_to_host_file - - -# func_to_tool_file ARG LAZY -# converts the file name ARG from $build format to toolchain format. Return -# result in func_to_tool_file_result. If the conversion in use is listed -# in (the comma separated) LAZY, no conversion takes place. -func_to_tool_file () -{ - $opt_debug - case ,$2, in - *,"$to_tool_file_cmd",*) - func_to_tool_file_result=$1 - ;; - *) - $to_tool_file_cmd "$1" - func_to_tool_file_result=$func_to_host_file_result - ;; - esac -} -# end func_to_tool_file - - -# func_convert_file_noop ARG -# Copy ARG to func_to_host_file_result. -func_convert_file_noop () -{ - func_to_host_file_result="$1" -} -# end func_convert_file_noop - - -# func_convert_file_msys_to_w32 ARG -# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic -# conversion to w32 is not available inside the cwrapper. Returns result in -# func_to_host_file_result. -func_convert_file_msys_to_w32 () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - func_convert_core_msys_to_w32 "$1" - func_to_host_file_result="$func_convert_core_msys_to_w32_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_msys_to_w32 - - -# func_convert_file_cygwin_to_w32 ARG -# Convert file name ARG from Cygwin to w32 format. Returns result in -# func_to_host_file_result. -func_convert_file_cygwin_to_w32 () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - # because $build is cygwin, we call "the" cygpath in $PATH; no need to use - # LT_CYGPATH in this case. - func_to_host_file_result=`cygpath -m "$1"` - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_cygwin_to_w32 - - -# func_convert_file_nix_to_w32 ARG -# Convert file name ARG from *nix to w32 format. Requires a wine environment -# and a working winepath. Returns result in func_to_host_file_result. -func_convert_file_nix_to_w32 () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - func_convert_core_file_wine_to_w32 "$1" - func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_nix_to_w32 - - -# func_convert_file_msys_to_cygwin ARG -# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. -# Returns result in func_to_host_file_result. -func_convert_file_msys_to_cygwin () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - func_convert_core_msys_to_w32 "$1" - func_cygpath -u "$func_convert_core_msys_to_w32_result" - func_to_host_file_result="$func_cygpath_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_msys_to_cygwin - - -# func_convert_file_nix_to_cygwin ARG -# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed -# in a wine environment, working winepath, and LT_CYGPATH set. Returns result -# in func_to_host_file_result. -func_convert_file_nix_to_cygwin () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. - func_convert_core_file_wine_to_w32 "$1" - func_cygpath -u "$func_convert_core_file_wine_to_w32_result" - func_to_host_file_result="$func_cygpath_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_nix_to_cygwin - - -############################################# -# $build to $host PATH CONVERSION FUNCTIONS # -############################################# -# invoked via `$to_host_path_cmd ARG' -# -# In each case, ARG is the path to be converted from $build to $host format. -# The result will be available in $func_to_host_path_result. -# -# Path separators are also converted from $build format to $host format. If -# ARG begins or ends with a path separator character, it is preserved (but -# converted to $host format) on output. -# -# All path conversion functions are named using the following convention: -# file name conversion function : func_convert_file_X_to_Y () -# path conversion function : func_convert_path_X_to_Y () -# where, for any given $build/$host combination the 'X_to_Y' value is the -# same. If conversion functions are added for new $build/$host combinations, -# the two new functions must follow this pattern, or func_init_to_host_path_cmd -# will break. - - -# func_init_to_host_path_cmd -# Ensures that function "pointer" variable $to_host_path_cmd is set to the -# appropriate value, based on the value of $to_host_file_cmd. -to_host_path_cmd= -func_init_to_host_path_cmd () -{ - $opt_debug - if test -z "$to_host_path_cmd"; then - func_stripname 'func_convert_file_' '' "$to_host_file_cmd" - to_host_path_cmd="func_convert_path_${func_stripname_result}" - fi -} - - -# func_to_host_path ARG -# Converts the path ARG from $build format to $host format. Return result -# in func_to_host_path_result. -func_to_host_path () -{ - $opt_debug - func_init_to_host_path_cmd - $to_host_path_cmd "$1" -} -# end func_to_host_path - - -# func_convert_path_noop ARG -# Copy ARG to func_to_host_path_result. -func_convert_path_noop () -{ - func_to_host_path_result="$1" -} -# end func_convert_path_noop - - -# func_convert_path_msys_to_w32 ARG -# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic -# conversion to w32 is not available inside the cwrapper. Returns result in -# func_to_host_path_result. -func_convert_path_msys_to_w32 () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # Remove leading and trailing path separator characters from ARG. MSYS - # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; - # and winepath ignores them completely. - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result="$func_convert_core_msys_to_w32_result" - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_msys_to_w32 - - -# func_convert_path_cygwin_to_w32 ARG -# Convert path ARG from Cygwin to w32 format. Returns result in -# func_to_host_file_result. -func_convert_path_cygwin_to_w32 () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_cygwin_to_w32 - - -# func_convert_path_nix_to_w32 ARG -# Convert path ARG from *nix to w32 format. Requires a wine environment and -# a working winepath. Returns result in func_to_host_file_result. -func_convert_path_nix_to_w32 () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_nix_to_w32 - - -# func_convert_path_msys_to_cygwin ARG -# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. -# Returns result in func_to_host_file_result. -func_convert_path_msys_to_cygwin () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_cygpath -u -p "$func_convert_core_msys_to_w32_result" - func_to_host_path_result="$func_cygpath_result" - func_convert_path_check : : \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" : "$1" - fi -} -# end func_convert_path_msys_to_cygwin - - -# func_convert_path_nix_to_cygwin ARG -# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a -# a wine environment, working winepath, and LT_CYGPATH set. Returns result in -# func_to_host_file_result. -func_convert_path_nix_to_cygwin () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # Remove leading and trailing path separator characters from - # ARG. msys behavior is inconsistent here, cygpath turns them - # into '.;' and ';.', and winepath ignores them completely. - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" - func_to_host_path_result="$func_cygpath_result" - func_convert_path_check : : \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" : "$1" - fi -} -# end func_convert_path_nix_to_cygwin - - -# func_mode_compile arg... -func_mode_compile () -{ - $opt_debug - # Get the compilation command and the source file. - base_compile= - srcfile="$nonopt" # always keep a non-empty value in "srcfile" - suppress_opt=yes - suppress_output= - arg_mode=normal - libobj= - later= - pie_flag= - - for arg - do - case $arg_mode in - arg ) - # do not "continue". Instead, add this to base_compile - lastarg="$arg" - arg_mode=normal - ;; - - target ) - libobj="$arg" - arg_mode=normal - continue - ;; - - normal ) - # Accept any command-line options. - case $arg in - -o) - test -n "$libobj" && \ - func_fatal_error "you cannot specify \`-o' more than once" - arg_mode=target - continue - ;; - - -pie | -fpie | -fPIE) - func_append pie_flag " $arg" - continue - ;; - - -shared | -static | -prefer-pic | -prefer-non-pic) - func_append later " $arg" - continue - ;; - - -no-suppress) - suppress_opt=no - continue - ;; - - -Xcompiler) - arg_mode=arg # the next one goes into the "base_compile" arg list - continue # The current "srcfile" will either be retained or - ;; # replaced later. I would guess that would be a bug. - - -Wc,*) - func_stripname '-Wc,' '' "$arg" - args=$func_stripname_result - lastarg= - save_ifs="$IFS"; IFS=',' - for arg in $args; do - IFS="$save_ifs" - func_append_quoted lastarg "$arg" - done - IFS="$save_ifs" - func_stripname ' ' '' "$lastarg" - lastarg=$func_stripname_result - - # Add the arguments to base_compile. - func_append base_compile " $lastarg" - continue - ;; - - *) - # Accept the current argument as the source file. - # The previous "srcfile" becomes the current argument. - # - lastarg="$srcfile" - srcfile="$arg" - ;; - esac # case $arg - ;; - esac # case $arg_mode - - # Aesthetically quote the previous argument. - func_append_quoted base_compile "$lastarg" - done # for arg - - case $arg_mode in - arg) - func_fatal_error "you must specify an argument for -Xcompile" - ;; - target) - func_fatal_error "you must specify a target with \`-o'" - ;; - *) - # Get the name of the library object. - test -z "$libobj" && { - func_basename "$srcfile" - libobj="$func_basename_result" - } - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - case $libobj in - *.[cCFSifmso] | \ - *.ada | *.adb | *.ads | *.asm | \ - *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ - *.[fF][09]? | *.for | *.java | *.obj | *.sx | *.cu | *.cup) - func_xform "$libobj" - libobj=$func_xform_result - ;; - esac - - case $libobj in - *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; - *) - func_fatal_error "cannot determine name of library object from \`$libobj'" - ;; - esac - - func_infer_tag $base_compile - - for arg in $later; do - case $arg in - -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" - build_old_libs=no - continue - ;; - - -static) - build_libtool_libs=no - build_old_libs=yes - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - esac - done - - func_quote_for_eval "$libobj" - test "X$libobj" != "X$func_quote_for_eval_result" \ - && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ - && func_warning "libobj name \`$libobj' may not contain shell special characters." - func_dirname_and_basename "$obj" "/" "" - objname="$func_basename_result" - xdir="$func_dirname_result" - lobj=${xdir}$objdir/$objname - - test -z "$base_compile" && \ - func_fatal_help "you must specify a compilation command" - - # Delete any leftover library objects. - if test "$build_old_libs" = yes; then - removelist="$obj $lobj $libobj ${libobj}T" - else - removelist="$lobj $libobj ${libobj}T" - fi - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2* | cegcc*) - pic_mode=default - ;; - esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" - else - output_obj= - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then - until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do - func_echo "Waiting for $lockfile to be removed" - sleep 2 - done - elif test "$need_locks" = warn; then - if test -f "$lockfile"; then - $ECHO "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - func_append removelist " $output_obj" - $ECHO "$srcfile" > "$lockfile" - fi - - $opt_dry_run || $RM $removelist - func_append removelist " $lockfile" - trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 - - func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 - srcfile=$func_to_tool_file_result - func_quote_for_eval "$srcfile" - qsrcfile=$func_quote_for_eval_result - - # Only build a PIC object if we are building libtool libraries. - if test "$build_libtool_libs" = yes; then - # Without this assignment, base_compile gets emptied. - fbsd_hideous_sh_bug=$base_compile - - if test "$pic_mode" != no; then - command="$base_compile $qsrcfile $pic_flag" - else - # Don't build PIC code - command="$base_compile $qsrcfile" - fi - - func_mkdir_p "$xdir$objdir" - - if test -z "$output_obj"; then - # Place PIC objects in $objdir - func_append command " -o $lobj" - fi - - func_show_eval_locale "$command" \ - 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' - - if test "$need_locks" = warn && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $ECHO "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed, then go on to compile the next one - if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then - func_show_eval '$MV "$output_obj" "$lobj"' \ - 'error=$?; $opt_dry_run || $RM $removelist; exit $error' - fi - - # Allow error messages only from the first compilation. - if test "$suppress_opt" = yes; then - suppress_output=' >/dev/null 2>&1' - fi - fi - - # Only build a position-dependent object if we build old libraries. - if test "$build_old_libs" = yes; then - if test "$pic_mode" != yes; then - # Don't build PIC code - command="$base_compile $qsrcfile$pie_flag" - else - command="$base_compile $qsrcfile $pic_flag" - fi - if test "$compiler_c_o" = yes; then - func_append command " -o $obj" - fi - - # Suppress compiler output if we already did a PIC compilation. - func_append command "$suppress_output" - func_show_eval_locale "$command" \ - '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' - - if test "$need_locks" = warn && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $ECHO "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed - if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then - func_show_eval '$MV "$output_obj" "$obj"' \ - 'error=$?; $opt_dry_run || $RM $removelist; exit $error' - fi - fi - - $opt_dry_run || { - func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" - - # Unlock the critical section if it was locked - if test "$need_locks" != no; then - removelist=$lockfile - $RM "$lockfile" - fi - } - - exit $EXIT_SUCCESS -} - -$opt_help || { - test "$opt_mode" = compile && func_mode_compile ${1+"$@"} -} - -func_mode_help () -{ - # We need to display help for each of the modes. - case $opt_mode in - "") - # Generic help is extracted from the usage comments - # at the start of this file. - func_help - ;; - - clean) - $ECHO \ -"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - - compile) - $ECHO \ -"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -no-suppress do not suppress compiler output for multiple passes - -prefer-pic try to build PIC objects only - -prefer-non-pic try to build non-PIC objects only - -shared do not build a \`.o' file suitable for static linking - -static only build a \`.o' file suitable for static linking - -Wc,FLAG pass FLAG directly to the compiler - -COMPILE-COMMAND is a command to be used in creating a \`standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." - ;; - - execute) - $ECHO \ -"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to \`-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - - finish) - $ECHO \ -"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." - ;; - - install) - $ECHO \ -"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. - -The following components of INSTALL-COMMAND are treated specially: - - -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - - link) - $ECHO \ -"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -bindir BINDIR specify path to binaries directory (for systems where - libraries must be found in the PATH setting at runtime) - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -objectlist FILE Use a list of object files found in FILE to specify objects - -precious-files-regex REGEX - don't remove output files matching REGEX - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -shared only do dynamic linking of libtool libraries - -shrext SUFFIX override the standard shared library file extension - -static do not do any dynamic linking of uninstalled libtool libraries - -static-libtool-libs - do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -weak LIBNAME declare that the target provides the LIBNAME interface - -Wc,FLAG - -Xcompiler FLAG pass linker-specific FLAG directly to the compiler - -Wl,FLAG - -Xlinker FLAG pass linker-specific FLAG directly to the linker - -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) - -All other options (arguments beginning with \`-') are ignored. - -Every other argument is treated as a filename. Files ending in \`.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. - -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file -is created, otherwise an executable program is created." - ;; - - uninstall) - $ECHO \ -"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - - *) - func_fatal_help "invalid operation mode \`$opt_mode'" - ;; - esac - - echo - $ECHO "Try \`$progname --help' for more information about other modes." -} - -# Now that we've collected a possible --mode arg, show help if necessary -if $opt_help; then - if test "$opt_help" = :; then - func_mode_help - else - { - func_help noexit - for opt_mode in compile link execute install finish uninstall clean; do - func_mode_help - done - } | sed -n '1p; 2,$s/^Usage:/ or: /p' - { - func_help noexit - for opt_mode in compile link execute install finish uninstall clean; do - echo - func_mode_help - done - } | - sed '1d - /^When reporting/,/^Report/{ - H - d - } - $x - /information about other modes/d - /more detailed .*MODE/d - s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' - fi - exit $? -fi - - -# func_mode_execute arg... -func_mode_execute () -{ - $opt_debug - # The first argument is the command name. - cmd="$nonopt" - test -z "$cmd" && \ - func_fatal_help "you must specify a COMMAND" - - # Handle -dlopen flags immediately. - for file in $opt_dlopen; do - test -f "$file" \ - || func_fatal_help "\`$file' is not a file" - - dir= - case $file in - *.la) - func_resolve_sysroot "$file" - file=$func_resolve_sysroot_result - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$lib' is not a valid libtool archive" - - # Read the libtool library. - dlname= - library_names= - func_source "$file" - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && \ - func_warning "\`$file' was not linked with \`-export-dynamic'" - continue - fi - - func_dirname "$file" "" "." - dir="$func_dirname_result" - - if test -f "$dir/$objdir/$dlname"; then - func_append dir "/$objdir" - else - if test ! -f "$dir/$dlname"; then - func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" - fi - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - func_dirname "$file" "" "." - dir="$func_dirname_result" - ;; - - *) - func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic="$magic" - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -* | *.la | *.lo ) ;; - *) - # Do a test to see if this is really a libtool program. - if func_ltwrapper_script_p "$file"; then - func_source "$file" - # Transform arg to wrapped name. - file="$progdir/$program" - elif func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - func_source "$func_ltwrapper_scriptname_result" - # Transform arg to wrapped name. - file="$progdir/$program" - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - func_append_quoted args "$file" - done - - if test "X$opt_dry_run" = Xfalse; then - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved environment variables - for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES - do - eval "if test \"\${save_$lt_var+set}\" = set; then - $lt_var=\$save_$lt_var; export $lt_var - else - $lt_unset $lt_var - fi" - done - - # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" - echo "export $shlibpath_var" - fi - $ECHO "$cmd$args" - exit $EXIT_SUCCESS - fi -} - -test "$opt_mode" = execute && func_mode_execute ${1+"$@"} - - -# func_mode_finish arg... -func_mode_finish () -{ - $opt_debug - libs= - libdirs= - admincmds= - - for opt in "$nonopt" ${1+"$@"} - do - if test -d "$opt"; then - func_append libdirs " $opt" - - elif test -f "$opt"; then - if func_lalib_unsafe_p "$opt"; then - func_append libs " $opt" - else - func_warning "\`$opt' is not a valid libtool archive" - fi - - else - func_fatal_error "invalid argument \`$opt'" - fi - done - - if test -n "$libs"; then - if test -n "$lt_sysroot"; then - sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` - sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" - else - sysroot_cmd= - fi - - # Remove sysroot references - if $opt_dry_run; then - for lib in $libs; do - echo "removing references to $lt_sysroot and \`=' prefixes from $lib" - done - else - tmpdir=`func_mktempdir` - for lib in $libs; do - sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ - > $tmpdir/tmp-la - mv -f $tmpdir/tmp-la $lib - done - ${RM}r "$tmpdir" - fi - fi - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - func_execute_cmds "$finish_cmds" 'admincmds="$admincmds -'"$cmd"'"' - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $opt_dry_run || eval "$cmds" || func_append admincmds " - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - $opt_silent && exit $EXIT_SUCCESS - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - echo "----------------------------------------------------------------------" - echo "Libraries have been installed in:" - for libdir in $libdirs; do - $ECHO " $libdir" - done - echo - echo "If you ever happen to want to link against installed libraries" - echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use the \`-LLIBDIR'" - echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - echo " - add LIBDIR to the \`$shlibpath_var' environment variable" - echo " during execution" - fi - if test -n "$runpath_var"; then - echo " - add LIBDIR to the \`$runpath_var' environment variable" - echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - $ECHO " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - $ECHO " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - echo - - echo "See any operating system documentation about shared libraries for" - case $host in - solaris2.[6789]|solaris2.1[0-9]) - echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" - echo "pages." - ;; - *) - echo "more information, such as the ld(1) and ld.so(8) manual pages." - ;; - esac - echo "----------------------------------------------------------------------" - fi - exit $EXIT_SUCCESS -} - -test "$opt_mode" = finish && func_mode_finish ${1+"$@"} - - -# func_mode_install arg... -func_mode_install () -{ - $opt_debug - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || - # Allow the use of GNU shtool's install command. - case $nonopt in *shtool*) :;; *) false;; esac; then - # Aesthetically quote it. - func_quote_for_eval "$nonopt" - install_prog="$func_quote_for_eval_result " - arg=$1 - shift - else - install_prog= - arg=$nonopt - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - func_quote_for_eval "$arg" - func_append install_prog "$func_quote_for_eval_result" - install_shared_prog=$install_prog - case " $install_prog " in - *[\\\ /]cp\ *) install_cp=: ;; - *) install_cp=false ;; - esac - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=no - stripme= - no_mode=: - for arg - do - arg2= - if test -n "$dest"; then - func_append files " $dest" - dest=$arg - continue - fi - - case $arg in - -d) isdir=yes ;; - -f) - if $install_cp; then :; else - prev=$arg - fi - ;; - -g | -m | -o) - prev=$arg - ;; - -s) - stripme=" -s" - continue - ;; - -*) - ;; - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - if test "x$prev" = x-m && test -n "$install_override_mode"; then - arg2=$install_override_mode - no_mode=false - fi - prev= - else - dest=$arg - continue - fi - ;; - esac - - # Aesthetically quote the argument. - func_quote_for_eval "$arg" - func_append install_prog " $func_quote_for_eval_result" - if test -n "$arg2"; then - func_quote_for_eval "$arg2" - fi - func_append install_shared_prog " $func_quote_for_eval_result" - done - - test -z "$install_prog" && \ - func_fatal_help "you must specify an install program" - - test -n "$prev" && \ - func_fatal_help "the \`$prev' option requires an argument" - - if test -n "$install_override_mode" && $no_mode; then - if $install_cp; then :; else - func_quote_for_eval "$install_override_mode" - func_append install_shared_prog " -m $func_quote_for_eval_result" - fi - fi - - if test -z "$files"; then - if test -z "$dest"; then - func_fatal_help "no file or destination specified" - else - func_fatal_help "you must specify a destination" - fi - fi - - # Strip any trailing slash from the destination. - func_stripname '' '/' "$dest" - dest=$func_stripname_result - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" - destname= - else - func_dirname_and_basename "$dest" "" "." - destdir="$func_dirname_result" - destname="$func_basename_result" - - # Not a directory, so check to see that there is only one file specified. - set dummy $files; shift - test "$#" -gt 1 && \ - func_fatal_help "\`$dest' is not a directory" - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - func_fatal_help "\`$destdir' must be an absolute directory name" - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - func_append staticlibs " $file" - ;; - - *.la) - func_resolve_sysroot "$file" - file=$func_resolve_sysroot_result - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$file' is not a valid libtool archive" - - library_names= - old_library= - relink_command= - func_source "$file" - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) func_append current_libdirs " $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) func_append future_libdirs " $libdir" ;; - esac - fi - - func_dirname "$file" "/" "" - dir="$func_dirname_result" - func_append dir "$objdir" - - if test -n "$relink_command"; then - # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` - - # Don't allow the user to place us outside of our expected - # location b/c this prevents finding dependent libraries that - # are installed to the same prefix. - # At present, this check doesn't affect windows .dll's that - # are installed into $libdir/../bin (currently, that works fine) - # but it's something to keep an eye on. - test "$inst_prefix_dir" = "$destdir" && \ - func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" - - if test -n "$inst_prefix_dir"; then - # Stick the inst_prefix_dir data into the link command. - relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` - else - relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` - fi - - func_warning "relinking \`$file'" - func_show_eval "$relink_command" \ - 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' - fi - - # See the names of the shared library. - set dummy $library_names; shift - if test -n "$1"; then - realname="$1" - shift - - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T - - # Install the shared library and build the symlinks. - func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ - 'exit $?' - tstripme="$stripme" - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - case $realname in - *.dll.a) - tstripme="" - ;; - esac - ;; - esac - if test -n "$tstripme" && test -n "$striplib"; then - func_show_eval "$striplib $destdir/$realname" 'exit $?' - fi - - if test "$#" -gt 0; then - # Delete the old symlinks, and create new ones. - # Try `ln -sf' first, because the `ln' binary might depend on - # the symlink we replace! Solaris /bin/ln does not understand -f, - # so we also need to try rm && ln -s. - for linkname - do - test "$linkname" != "$realname" \ - && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" - done - fi - - # Do each command in the postinstall commands. - lib="$destdir/$realname" - func_execute_cmds "$postinstall_cmds" 'exit $?' - fi - - # Install the pseudo-library for information purposes. - func_basename "$file" - name="$func_basename_result" - instname="$dir/$name"i - func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' - - # Maybe install the static library, too. - test -n "$old_library" && func_append staticlibs " $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - func_lo2o "$destfile" - staticdest=$func_lo2o_result - ;; - *.$objext) - staticdest="$destfile" - destfile= - ;; - *) - func_fatal_help "cannot copy a libtool object to \`$destfile'" - ;; - esac - - # Install the libtool object if requested. - test -n "$destfile" && \ - func_show_eval "$install_prog $file $destfile" 'exit $?' - - # Install the old object if enabled. - if test "$build_old_libs" = yes; then - # Deduce the name of the old-style object file. - func_lo2o "$file" - staticobj=$func_lo2o_result - func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' - fi - exit $EXIT_SUCCESS - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" - fi - - # If the file is missing, and there is a .exe on the end, strip it - # because it is most likely a libtool script we actually want to - # install - stripped_ext="" - case $file in - *.exe) - if test ! -f "$file"; then - func_stripname '' '.exe' "$file" - file=$func_stripname_result - stripped_ext=".exe" - fi - ;; - esac - - # Do a test to see if this is really a libtool program. - case $host in - *cygwin* | *mingw*) - if func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - wrapper=$func_ltwrapper_scriptname_result - else - func_stripname '' '.exe' "$file" - wrapper=$func_stripname_result - fi - ;; - *) - wrapper=$file - ;; - esac - if func_ltwrapper_script_p "$wrapper"; then - notinst_deplibs= - relink_command= - - func_source "$wrapper" - - # Check the variables that should have been set. - test -z "$generated_by_libtool_version" && \ - func_fatal_error "invalid libtool wrapper script \`$wrapper'" - - finalize=yes - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - func_source "$lib" - fi - libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test - if test -n "$libdir" && test ! -f "$libfile"; then - func_warning "\`$lib' has not been installed in \`$libdir'" - finalize=no - fi - done - - relink_command= - func_source "$wrapper" - - outputname= - if test "$fast_install" = no && test -n "$relink_command"; then - $opt_dry_run || { - if test "$finalize" = yes; then - tmpdir=`func_mktempdir` - func_basename "$file$stripped_ext" - file="$func_basename_result" - outputname="$tmpdir/$file" - # Replace the output file specification. - relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` - - $opt_silent || { - func_quote_for_expand "$relink_command" - eval "func_echo $func_quote_for_expand_result" - } - if eval "$relink_command"; then : - else - func_error "error: relink \`$file' with the above command before installing it" - $opt_dry_run || ${RM}r "$tmpdir" - continue - fi - file="$outputname" - else - func_warning "cannot relink \`$file'" - fi - } - else - # Install the binary that we compiled earlier. - file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyway - case $install_prog,$host in - */usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - func_stripname '' '.exe' "$destfile" - destfile=$func_stripname_result - ;; - esac - ;; - esac - func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' - $opt_dry_run || if test -n "$outputname"; then - ${RM}r "$tmpdir" - fi - ;; - esac - done - - for file in $staticlibs; do - func_basename "$file" - name="$func_basename_result" - - # Set up the ranlib parameters. - oldlib="$destdir/$name" - - func_show_eval "$install_prog \$file \$oldlib" 'exit $?' - - if test -n "$stripme" && test -n "$old_striplib"; then - func_show_eval "$old_striplib $oldlib" 'exit $?' - fi - - # Do each command in the postinstall commands. - func_execute_cmds "$old_postinstall_cmds" 'exit $?' - done - - test -n "$future_libdirs" && \ - func_warning "remember to run \`$progname --finish$future_libdirs'" - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - $opt_dry_run && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' - else - exit $EXIT_SUCCESS - fi -} - -test "$opt_mode" = install && func_mode_install ${1+"$@"} - - -# func_generate_dlsyms outputname originator pic_p -# Extract symbols from dlprefiles and create ${outputname}S.o with -# a dlpreopen symbol table. -func_generate_dlsyms () -{ - $opt_debug - my_outputname="$1" - my_originator="$2" - my_pic_p="${3-no}" - my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` - my_dlsyms= - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - my_dlsyms="${my_outputname}S.c" - else - func_error "not configured to extract global symbols from dlpreopened files" - fi - fi - - if test -n "$my_dlsyms"; then - case $my_dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${my_outputname}.nm" - - func_show_eval "$RM $nlist ${nlist}S ${nlist}T" - - # Parse the name list into a source file. - func_verbose "creating $output_objdir/$my_dlsyms" - - $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ -/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ -/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) -#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" -#endif - -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT_DLSYM_CONST -#elif defined(__osf__) -/* This system does not cope well with relocations in const data. */ -# define LT_DLSYM_CONST -#else -# define LT_DLSYM_CONST const -#endif - -/* External symbol declarations for the compiler. */\ -" - - if test "$dlself" = yes; then - func_verbose "generating symbol list for \`$output'" - - $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` - for progfile in $progfiles; do - func_to_tool_file "$progfile" func_convert_file_msys_to_w32 - func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" - $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $opt_dry_run || { - eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - } - fi - - if test -n "$export_symbols_regex"; then - $opt_dry_run || { - eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - } - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols="$output_objdir/$outputname.exp" - $opt_dry_run || { - $RM $export_symbols - eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - case $host in - *cygwin* | *mingw* | *cegcc* ) - eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' - ;; - esac - } - else - $opt_dry_run || { - eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' - eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - case $host in - *cygwin* | *mingw* | *cegcc* ) - eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' - ;; - esac - } - fi - fi - - for dlprefile in $dlprefiles; do - func_verbose "extracting global C symbols from \`$dlprefile'" - func_basename "$dlprefile" - name="$func_basename_result" - case $host in - *cygwin* | *mingw* | *cegcc* ) - # if an import library, we need to obtain dlname - if func_win32_import_lib_p "$dlprefile"; then - func_tr_sh "$dlprefile" - eval "curr_lafile=\$libfile_$func_tr_sh_result" - dlprefile_dlbasename="" - if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then - # Use subshell, to avoid clobbering current variable values - dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` - if test -n "$dlprefile_dlname" ; then - func_basename "$dlprefile_dlname" - dlprefile_dlbasename="$func_basename_result" - else - # no lafile. user explicitly requested -dlpreopen . - $sharedlib_from_linklib_cmd "$dlprefile" - dlprefile_dlbasename=$sharedlib_from_linklib_result - fi - fi - $opt_dry_run || { - if test -n "$dlprefile_dlbasename" ; then - eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' - else - func_warning "Could not compute DLL name from $name" - eval '$ECHO ": $name " >> "$nlist"' - fi - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | - $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" - } - else # not an import lib - $opt_dry_run || { - eval '$ECHO ": $name " >> "$nlist"' - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" - } - fi - ;; - *) - $opt_dry_run || { - eval '$ECHO ": $name " >> "$nlist"' - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" - } - ;; - esac - done - - $opt_dry_run || { - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $MV "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if $GREP -v "^: " < "$nlist" | - if sort -k 3 /dev/null 2>&1; then - sort -k 3 - else - sort +2 - fi | - uniq > "$nlist"S; then - : - else - $GREP -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' - else - echo '/* NONE */' >> "$output_objdir/$my_dlsyms" - fi - - echo >> "$output_objdir/$my_dlsyms" "\ - -/* The mapping between symbol names and symbols. */ -typedef struct { - const char *name; - void *address; -} lt_dlsymlist; -extern LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[]; -LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[] = -{\ - { \"$my_originator\", (void *) 0 }," - - case $need_lib_prefix in - no) - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" - ;; - *) - eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" - ;; - esac - echo >> "$output_objdir/$my_dlsyms" "\ - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_${my_prefix}_LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - } # !$opt_dry_run - - pic_flag_for_symtable= - case "$compile_command " in - *" -static "*) ;; - *) - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; - *-*-hpux*) - pic_flag_for_symtable=" $pic_flag" ;; - *) - if test "X$my_pic_p" != Xno; then - pic_flag_for_symtable=" $pic_flag" - fi - ;; - esac - ;; - esac - symtab_cflags= - for arg in $LTCFLAGS; do - case $arg in - -pie | -fpie | -fPIE) ;; - *) func_append symtab_cflags " $arg" ;; - esac - done - - # Now compile the dynamic symbol file. - func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' - - # Clean up the generated files. - func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' - - # Transform the symbol file into the correct name. - symfileobj="$output_objdir/${my_outputname}S.$objext" - case $host in - *cygwin* | *mingw* | *cegcc* ) - if test -f "$output_objdir/$my_outputname.def"; then - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` - else - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` - fi - ;; - *) - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` - ;; - esac - ;; - *) - func_fatal_error "unknown suffix for \`$my_dlsyms'" - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` - fi -} - -# func_win32_libid arg -# return the library type of file 'arg' -# -# Need a lot of goo to handle *both* DLLs and import libs -# Has to be a shell function in order to 'eat' the argument -# that is supplied when $file_magic_command is called. -# Despite the name, also deal with 64 bit binaries. -func_win32_libid () -{ - $opt_debug - win32_libid_type="unknown" - win32_fileres=`file -L $1 2>/dev/null` - case $win32_fileres in - *ar\ archive\ import\ library*) # definitely import - win32_libid_type="x86 archive import" - ;; - *ar\ archive*) # could be an import, or static - # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. - if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | - $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then - func_to_tool_file "$1" func_convert_file_msys_to_w32 - win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | - $SED -n -e ' - 1,100{ - / I /{ - s,.*,import, - p - q - } - }'` - case $win32_nmres in - import*) win32_libid_type="x86 archive import";; - *) win32_libid_type="x86 archive static";; - esac - fi - ;; - *DLL*) - win32_libid_type="x86 DLL" - ;; - *executable*) # but shell scripts are "executable" too... - case $win32_fileres in - *MS\ Windows\ PE\ Intel*) - win32_libid_type="x86 DLL" - ;; - esac - ;; - esac - $ECHO "$win32_libid_type" -} - -# func_cygming_dll_for_implib ARG -# -# Platform-specific function to extract the -# name of the DLL associated with the specified -# import library ARG. -# Invoked by eval'ing the libtool variable -# $sharedlib_from_linklib_cmd -# Result is available in the variable -# $sharedlib_from_linklib_result -func_cygming_dll_for_implib () -{ - $opt_debug - sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` -} - -# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs -# -# The is the core of a fallback implementation of a -# platform-specific function to extract the name of the -# DLL associated with the specified import library LIBNAME. -# -# SECTION_NAME is either .idata$6 or .idata$7, depending -# on the platform and compiler that created the implib. -# -# Echos the name of the DLL associated with the -# specified import library. -func_cygming_dll_for_implib_fallback_core () -{ - $opt_debug - match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` - $OBJDUMP -s --section "$1" "$2" 2>/dev/null | - $SED '/^Contents of section '"$match_literal"':/{ - # Place marker at beginning of archive member dllname section - s/.*/====MARK====/ - p - d - } - # These lines can sometimes be longer than 43 characters, but - # are always uninteresting - /:[ ]*file format pe[i]\{,1\}-/d - /^In archive [^:]*:/d - # Ensure marker is printed - /^====MARK====/p - # Remove all lines with less than 43 characters - /^.\{43\}/!d - # From remaining lines, remove first 43 characters - s/^.\{43\}//' | - $SED -n ' - # Join marker and all lines until next marker into a single line - /^====MARK====/ b para - H - $ b para - b - :para - x - s/\n//g - # Remove the marker - s/^====MARK====// - # Remove trailing dots and whitespace - s/[\. \t]*$// - # Print - /./p' | - # we now have a list, one entry per line, of the stringified - # contents of the appropriate section of all members of the - # archive which possess that section. Heuristic: eliminate - # all those which have a first or second character that is - # a '.' (that is, objdump's representation of an unprintable - # character.) This should work for all archives with less than - # 0x302f exports -- but will fail for DLLs whose name actually - # begins with a literal '.' or a single character followed by - # a '.'. - # - # Of those that remain, print the first one. - $SED -e '/^\./d;/^.\./d;q' -} - -# func_cygming_gnu_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is a GNU/binutils-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_gnu_implib_p () -{ - $opt_debug - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` - test -n "$func_cygming_gnu_implib_tmp" -} - -# func_cygming_ms_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is an MS-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_ms_implib_p () -{ - $opt_debug - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` - test -n "$func_cygming_ms_implib_tmp" -} - -# func_cygming_dll_for_implib_fallback ARG -# Platform-specific function to extract the -# name of the DLL associated with the specified -# import library ARG. -# -# This fallback implementation is for use when $DLLTOOL -# does not support the --identify-strict option. -# Invoked by eval'ing the libtool variable -# $sharedlib_from_linklib_cmd -# Result is available in the variable -# $sharedlib_from_linklib_result -func_cygming_dll_for_implib_fallback () -{ - $opt_debug - if func_cygming_gnu_implib_p "$1" ; then - # binutils import library - sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` - elif func_cygming_ms_implib_p "$1" ; then - # ms-generated import library - sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` - else - # unknown - sharedlib_from_linklib_result="" - fi -} - - -# func_extract_an_archive dir oldlib -func_extract_an_archive () -{ - $opt_debug - f_ex_an_ar_dir="$1"; shift - f_ex_an_ar_oldlib="$1" - if test "$lock_old_archive_extraction" = yes; then - lockfile=$f_ex_an_ar_oldlib.lock - until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do - func_echo "Waiting for $lockfile to be removed" - sleep 2 - done - fi - func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ - 'stat=$?; rm -f "$lockfile"; exit $stat' - if test "$lock_old_archive_extraction" = yes; then - $opt_dry_run || rm -f "$lockfile" - fi - if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then - : - else - func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" - fi -} - - -# func_extract_archives gentop oldlib ... -func_extract_archives () -{ - $opt_debug - my_gentop="$1"; shift - my_oldlibs=${1+"$@"} - my_oldobjs="" - my_xlib="" - my_xabs="" - my_xdir="" - - for my_xlib in $my_oldlibs; do - # Extract the objects. - case $my_xlib in - [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; - *) my_xabs=`pwd`"/$my_xlib" ;; - esac - func_basename "$my_xlib" - my_xlib="$func_basename_result" - my_xlib_u=$my_xlib - while :; do - case " $extracted_archives " in - *" $my_xlib_u "*) - func_arith $extracted_serial + 1 - extracted_serial=$func_arith_result - my_xlib_u=lt$extracted_serial-$my_xlib ;; - *) break ;; - esac - done - extracted_archives="$extracted_archives $my_xlib_u" - my_xdir="$my_gentop/$my_xlib_u" - - func_mkdir_p "$my_xdir" - - case $host in - *-darwin*) - func_verbose "Extracting $my_xabs" - # Do not bother doing anything if just a dry run - $opt_dry_run || { - darwin_orig_dir=`pwd` - cd $my_xdir || exit $? - darwin_archive=$my_xabs - darwin_curdir=`pwd` - darwin_base_archive=`basename "$darwin_archive"` - darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` - if test -n "$darwin_arches"; then - darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` - darwin_arch= - func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" - for darwin_arch in $darwin_arches ; do - func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" - $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" - cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" - func_extract_an_archive "`pwd`" "${darwin_base_archive}" - cd "$darwin_curdir" - $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" - done # $darwin_arches - ## Okay now we've a bunch of thin objects, gotta fatten them up :) - darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` - darwin_file= - darwin_files= - for darwin_file in $darwin_filelist; do - darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` - $LIPO -create -output "$darwin_file" $darwin_files - done # $darwin_filelist - $RM -rf unfat-$$ - cd "$darwin_orig_dir" - else - cd $darwin_orig_dir - func_extract_an_archive "$my_xdir" "$my_xabs" - fi # $darwin_arches - } # !$opt_dry_run - ;; - *) - func_extract_an_archive "$my_xdir" "$my_xabs" - ;; - esac - my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` - done - - func_extract_archives_result="$my_oldobjs" -} - - -# func_emit_wrapper [arg=no] -# -# Emit a libtool wrapper script on stdout. -# Don't directly open a file because we may want to -# incorporate the script contents within a cygwin/mingw -# wrapper executable. Must ONLY be called from within -# func_mode_link because it depends on a number of variables -# set therein. -# -# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR -# variable will take. If 'yes', then the emitted script -# will assume that the directory in which it is stored is -# the $objdir directory. This is a cygwin/mingw-specific -# behavior. -func_emit_wrapper () -{ - func_emit_wrapper_arg1=${1-no} - - $ECHO "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='$sed_quote_subst' - -# Be Bourne compatible -if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variables: - generated_by_libtool_version='$macro_version' - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$ECHO are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - file=\"\$0\"" - - qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` - $ECHO "\ - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$1 -_LTECHO_EOF' -} - ECHO=\"$qECHO\" - fi - -# Very basic option parsing. These options are (a) specific to -# the libtool wrapper, (b) are identical between the wrapper -# /script/ and the wrapper /executable/ which is used only on -# windows platforms, and (c) all begin with the string "--lt-" -# (application programs are unlikely to have options which match -# this pattern). -# -# There are only two supported options: --lt-debug and -# --lt-dump-script. There is, deliberately, no --lt-help. -# -# The first argument to this parsing function should be the -# script's $0 value, followed by "$@". -lt_option_debug= -func_parse_lt_options () -{ - lt_script_arg0=\$0 - shift - for lt_opt - do - case \"\$lt_opt\" in - --lt-debug) lt_option_debug=1 ;; - --lt-dump-script) - lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` - test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. - lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` - cat \"\$lt_dump_D/\$lt_dump_F\" - exit 0 - ;; - --lt-*) - \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 - exit 1 - ;; - esac - done - - # Print the debug banner immediately: - if test -n \"\$lt_option_debug\"; then - echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 - fi -} - -# Used when --lt-debug. Prints its arguments to stdout -# (redirection is the responsibility of the caller) -func_lt_dump_args () -{ - lt_dump_args_N=1; - for lt_arg - do - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" - lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` - done -} - -# Core function for launching the target application -func_exec_program_core () -{ -" - case $host in - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2* | *-cegcc*) - $ECHO "\ - if test -n \"\$lt_option_debug\"; then - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 - func_lt_dump_args \${1+\"\$@\"} 1>&2 - fi - exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} -" - ;; - - *) - $ECHO "\ - if test -n \"\$lt_option_debug\"; then - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 - func_lt_dump_args \${1+\"\$@\"} 1>&2 - fi - exec \"\$progdir/\$program\" \${1+\"\$@\"} -" - ;; - esac - $ECHO "\ - \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 - exit 1 -} - -# A function to encapsulate launching the target application -# Strips options in the --lt-* namespace from \$@ and -# launches target application with the remaining arguments. -func_exec_program () -{ - for lt_wr_arg - do - case \$lt_wr_arg in - --lt-*) ;; - *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; - esac - shift - done - func_exec_program_core \${1+\"\$@\"} -} - - # Parse options - func_parse_lt_options \"\$0\" \${1+\"\$@\"} - - # Find the directory that this script lives in. - thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` - done - - # Usually 'no', except on cygwin/mingw when embedded into - # the cwrapper. - WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 - if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then - # special case for '.' - if test \"\$thisdir\" = \".\"; then - thisdir=\`pwd\` - fi - # remove .libs from thisdir - case \"\$thisdir\" in - *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; - $objdir ) thisdir=. ;; - esac - fi - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test "$fast_install" = yes; then - $ECHO "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $MKDIR \"\$progdir\" - else - $RM \"\$progdir/\$file\" - fi" - - $ECHO "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - $ECHO \"\$relink_command_output\" >&2 - $RM \"\$progdir/\$file\" - exit 1 - fi - fi - - $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $RM \"\$progdir/\$program\"; - $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $RM \"\$progdir/\$file\" - fi" - else - $ECHO "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - $ECHO "\ - - if test -f \"\$progdir/\$program\"; then" - - # fixup the dll searchpath if we need to. - # - # Fix the DLL searchpath if we need to. Do this before prepending - # to shlibpath, because on Windows, both are PATH and uninstalled - # libraries must come first. - if test -n "$dllsearchpath"; then - $ECHO "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $ECHO "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed - $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` - - export $shlibpath_var -" - fi - - $ECHO "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. - func_exec_program \${1+\"\$@\"} - fi - else - # The program doesn't exist. - \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 - \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 - \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 - exit 1 - fi -fi\ -" -} - - -# func_emit_cwrapperexe_src -# emit the source code for a wrapper executable on stdout -# Must ONLY be called from within func_mode_link because -# it depends on a number of variable set therein. -func_emit_cwrapperexe_src () -{ - cat < -#include -#ifdef _MSC_VER -# include -# include -# include -#else -# include -# include -# ifdef __CYGWIN__ -# include -# endif -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -/* declarations of non-ANSI functions */ -#if defined(__MINGW32__) -# ifdef __STRICT_ANSI__ -int _putenv (const char *); -# endif -#elif defined(__CYGWIN__) -# ifdef __STRICT_ANSI__ -char *realpath (const char *, char *); -int putenv (char *); -int setenv (const char *, const char *, int); -# endif -/* #elif defined (other platforms) ... */ -#endif - -/* portability defines, excluding path handling macros */ -#if defined(_MSC_VER) -# define setmode _setmode -# define stat _stat -# define chmod _chmod -# define getcwd _getcwd -# define putenv _putenv -# define S_IXUSR _S_IEXEC -# ifndef _INTPTR_T_DEFINED -# define _INTPTR_T_DEFINED -# define intptr_t int -# endif -#elif defined(__MINGW32__) -# define setmode _setmode -# define stat _stat -# define chmod _chmod -# define getcwd _getcwd -# define putenv _putenv -#elif defined(__CYGWIN__) -# define HAVE_SETENV -# define FOPEN_WB "wb" -/* #elif defined (other platforms) ... */ -#endif - -#if defined(PATH_MAX) -# define LT_PATHMAX PATH_MAX -#elif defined(MAXPATHLEN) -# define LT_PATHMAX MAXPATHLEN -#else -# define LT_PATHMAX 1024 -#endif - -#ifndef S_IXOTH -# define S_IXOTH 0 -#endif -#ifndef S_IXGRP -# define S_IXGRP 0 -#endif - -/* path handling portability macros */ -#ifndef DIR_SEPARATOR -# define DIR_SEPARATOR '/' -# define PATH_SEPARATOR ':' -#endif - -#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ - defined (__OS2__) -# define HAVE_DOS_BASED_FILE_SYSTEM -# define FOPEN_WB "wb" -# ifndef DIR_SEPARATOR_2 -# define DIR_SEPARATOR_2 '\\' -# endif -# ifndef PATH_SEPARATOR_2 -# define PATH_SEPARATOR_2 ';' -# endif -#endif - -#ifndef DIR_SEPARATOR_2 -# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) -#else /* DIR_SEPARATOR_2 */ -# define IS_DIR_SEPARATOR(ch) \ - (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) -#endif /* DIR_SEPARATOR_2 */ - -#ifndef PATH_SEPARATOR_2 -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) -#else /* PATH_SEPARATOR_2 */ -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) -#endif /* PATH_SEPARATOR_2 */ - -#ifndef FOPEN_WB -# define FOPEN_WB "w" -#endif -#ifndef _O_BINARY -# define _O_BINARY 0 -#endif - -#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) -#define XFREE(stale) do { \ - if (stale) { free ((void *) stale); stale = 0; } \ -} while (0) - -#if defined(LT_DEBUGWRAPPER) -static int lt_debug = 1; -#else -static int lt_debug = 0; -#endif - -const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ - -void *xmalloc (size_t num); -char *xstrdup (const char *string); -const char *base_name (const char *name); -char *find_executable (const char *wrapper); -char *chase_symlinks (const char *pathspec); -int make_executable (const char *path); -int check_executable (const char *path); -char *strendzap (char *str, const char *pat); -void lt_debugprintf (const char *file, int line, const char *fmt, ...); -void lt_fatal (const char *file, int line, const char *message, ...); -static const char *nonnull (const char *s); -static const char *nonempty (const char *s); -void lt_setenv (const char *name, const char *value); -char *lt_extend_str (const char *orig_value, const char *add, int to_end); -void lt_update_exe_path (const char *name, const char *value); -void lt_update_lib_path (const char *name, const char *value); -char **prepare_spawn (char **argv); -void lt_dump_script (FILE *f); -EOF - - cat <= 0) - && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) - return 1; - else - return 0; -} - -int -make_executable (const char *path) -{ - int rval = 0; - struct stat st; - - lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", - nonempty (path)); - if ((!path) || (!*path)) - return 0; - - if (stat (path, &st) >= 0) - { - rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); - } - return rval; -} - -/* Searches for the full path of the wrapper. Returns - newly allocated full path name if found, NULL otherwise - Does not chase symlinks, even on platforms that support them. -*/ -char * -find_executable (const char *wrapper) -{ - int has_slash = 0; - const char *p; - const char *p_next; - /* static buffer for getcwd */ - char tmp[LT_PATHMAX + 1]; - int tmp_len; - char *concat_name; - - lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", - nonempty (wrapper)); - - if ((wrapper == NULL) || (*wrapper == '\0')) - return NULL; - - /* Absolute path? */ -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') - { - concat_name = xstrdup (wrapper); - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } - else - { -#endif - if (IS_DIR_SEPARATOR (wrapper[0])) - { - concat_name = xstrdup (wrapper); - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - } -#endif - - for (p = wrapper; *p; p++) - if (*p == '/') - { - has_slash = 1; - break; - } - if (!has_slash) - { - /* no slashes; search PATH */ - const char *path = getenv ("PATH"); - if (path != NULL) - { - for (p = path; *p; p = p_next) - { - const char *q; - size_t p_len; - for (q = p; *q; q++) - if (IS_PATH_SEPARATOR (*q)) - break; - p_len = q - p; - p_next = (*q == '\0' ? q : q + 1); - if (p_len == 0) - { - /* empty path: current directory */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", - nonnull (strerror (errno))); - tmp_len = strlen (tmp); - concat_name = - XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - } - else - { - concat_name = - XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, p, p_len); - concat_name[p_len] = '/'; - strcpy (concat_name + p_len + 1, wrapper); - } - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } - } - /* not found in PATH; assume curdir */ - } - /* Relative path | not found in path: prepend cwd */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", - nonnull (strerror (errno))); - tmp_len = strlen (tmp); - concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - return NULL; -} - -char * -chase_symlinks (const char *pathspec) -{ -#ifndef S_ISLNK - return xstrdup (pathspec); -#else - char buf[LT_PATHMAX]; - struct stat s; - char *tmp_pathspec = xstrdup (pathspec); - char *p; - int has_symlinks = 0; - while (strlen (tmp_pathspec) && !has_symlinks) - { - lt_debugprintf (__FILE__, __LINE__, - "checking path component for symlinks: %s\n", - tmp_pathspec); - if (lstat (tmp_pathspec, &s) == 0) - { - if (S_ISLNK (s.st_mode) != 0) - { - has_symlinks = 1; - break; - } - - /* search backwards for last DIR_SEPARATOR */ - p = tmp_pathspec + strlen (tmp_pathspec) - 1; - while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) - p--; - if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) - { - /* no more DIR_SEPARATORS left */ - break; - } - *p = '\0'; - } - else - { - lt_fatal (__FILE__, __LINE__, - "error accessing file \"%s\": %s", - tmp_pathspec, nonnull (strerror (errno))); - } - } - XFREE (tmp_pathspec); - - if (!has_symlinks) - { - return xstrdup (pathspec); - } - - tmp_pathspec = realpath (pathspec, buf); - if (tmp_pathspec == 0) - { - lt_fatal (__FILE__, __LINE__, - "could not follow symlinks for %s", pathspec); - } - return xstrdup (tmp_pathspec); -#endif -} - -char * -strendzap (char *str, const char *pat) -{ - size_t len, patlen; - - assert (str != NULL); - assert (pat != NULL); - - len = strlen (str); - patlen = strlen (pat); - - if (patlen <= len) - { - str += len - patlen; - if (strcmp (str, pat) == 0) - *str = '\0'; - } - return str; -} - -void -lt_debugprintf (const char *file, int line, const char *fmt, ...) -{ - va_list args; - if (lt_debug) - { - (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); - va_start (args, fmt); - (void) vfprintf (stderr, fmt, args); - va_end (args); - } -} - -static void -lt_error_core (int exit_status, const char *file, - int line, const char *mode, - const char *message, va_list ap) -{ - fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); - vfprintf (stderr, message, ap); - fprintf (stderr, ".\n"); - - if (exit_status >= 0) - exit (exit_status); -} - -void -lt_fatal (const char *file, int line, const char *message, ...) -{ - va_list ap; - va_start (ap, message); - lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); - va_end (ap); -} - -static const char * -nonnull (const char *s) -{ - return s ? s : "(null)"; -} - -static const char * -nonempty (const char *s) -{ - return (s && !*s) ? "(empty)" : nonnull (s); -} - -void -lt_setenv (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_setenv) setting '%s' to '%s'\n", - nonnull (name), nonnull (value)); - { -#ifdef HAVE_SETENV - /* always make a copy, for consistency with !HAVE_SETENV */ - char *str = xstrdup (value); - setenv (name, str, 1); -#else - int len = strlen (name) + 1 + strlen (value) + 1; - char *str = XMALLOC (char, len); - sprintf (str, "%s=%s", name, value); - if (putenv (str) != EXIT_SUCCESS) - { - XFREE (str); - } -#endif - } -} - -char * -lt_extend_str (const char *orig_value, const char *add, int to_end) -{ - char *new_value; - if (orig_value && *orig_value) - { - int orig_value_len = strlen (orig_value); - int add_len = strlen (add); - new_value = XMALLOC (char, add_len + orig_value_len + 1); - if (to_end) - { - strcpy (new_value, orig_value); - strcpy (new_value + orig_value_len, add); - } - else - { - strcpy (new_value, add); - strcpy (new_value + add_len, orig_value); - } - } - else - { - new_value = xstrdup (add); - } - return new_value; -} - -void -lt_update_exe_path (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", - nonnull (name), nonnull (value)); - - if (name && *name && value && *value) - { - char *new_value = lt_extend_str (getenv (name), value, 0); - /* some systems can't cope with a ':'-terminated path #' */ - int len = strlen (new_value); - while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) - { - new_value[len-1] = '\0'; - } - lt_setenv (name, new_value); - XFREE (new_value); - } -} - -void -lt_update_lib_path (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", - nonnull (name), nonnull (value)); - - if (name && *name && value && *value) - { - char *new_value = lt_extend_str (getenv (name), value, 0); - lt_setenv (name, new_value); - XFREE (new_value); - } -} - -EOF - case $host_os in - mingw*) - cat <<"EOF" - -/* Prepares an argument vector before calling spawn(). - Note that spawn() does not by itself call the command interpreter - (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : - ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&v); - v.dwPlatformId == VER_PLATFORM_WIN32_NT; - }) ? "cmd.exe" : "command.com"). - Instead it simply concatenates the arguments, separated by ' ', and calls - CreateProcess(). We must quote the arguments since Win32 CreateProcess() - interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a - special way: - - Space and tab are interpreted as delimiters. They are not treated as - delimiters if they are surrounded by double quotes: "...". - - Unescaped double quotes are removed from the input. Their only effect is - that within double quotes, space and tab are treated like normal - characters. - - Backslashes not followed by double quotes are not special. - - But 2*n+1 backslashes followed by a double quote become - n backslashes followed by a double quote (n >= 0): - \" -> " - \\\" -> \" - \\\\\" -> \\" - */ -#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" -#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" -char ** -prepare_spawn (char **argv) -{ - size_t argc; - char **new_argv; - size_t i; - - /* Count number of arguments. */ - for (argc = 0; argv[argc] != NULL; argc++) - ; - - /* Allocate new argument vector. */ - new_argv = XMALLOC (char *, argc + 1); - - /* Put quoted arguments into the new argument vector. */ - for (i = 0; i < argc; i++) - { - const char *string = argv[i]; - - if (string[0] == '\0') - new_argv[i] = xstrdup ("\"\""); - else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) - { - int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); - size_t length; - unsigned int backslashes; - const char *s; - char *quoted_string; - char *p; - - length = 0; - backslashes = 0; - if (quote_around) - length++; - for (s = string; *s != '\0'; s++) - { - char c = *s; - if (c == '"') - length += backslashes + 1; - length++; - if (c == '\\') - backslashes++; - else - backslashes = 0; - } - if (quote_around) - length += backslashes + 1; - - quoted_string = XMALLOC (char, length + 1); - - p = quoted_string; - backslashes = 0; - if (quote_around) - *p++ = '"'; - for (s = string; *s != '\0'; s++) - { - char c = *s; - if (c == '"') - { - unsigned int j; - for (j = backslashes + 1; j > 0; j--) - *p++ = '\\'; - } - *p++ = c; - if (c == '\\') - backslashes++; - else - backslashes = 0; - } - if (quote_around) - { - unsigned int j; - for (j = backslashes; j > 0; j--) - *p++ = '\\'; - *p++ = '"'; - } - *p = '\0'; - - new_argv[i] = quoted_string; - } - else - new_argv[i] = (char *) string; - } - new_argv[argc] = NULL; - - return new_argv; -} -EOF - ;; - esac - - cat <<"EOF" -void lt_dump_script (FILE* f) -{ -EOF - func_emit_wrapper yes | - $SED -e 's/\([\\"]\)/\\\1/g' \ - -e 's/^/ fputs ("/' -e 's/$/\\n", f);/' - - cat <<"EOF" -} -EOF -} -# end: func_emit_cwrapperexe_src - -# func_emit_exe_manifest -# emit a Win32 UAC manifest for executable on stdout -# Must ONLY be called from within func_mode_link because -# it depends on a number of variable set therein. -func_emit_exe_manifest () -{ - cat < - - - - - - - - - - - - -EOF -} - -# func_win32_import_lib_p ARG -# True if ARG is an import lib, as indicated by $file_magic_cmd -func_win32_import_lib_p () -{ - $opt_debug - case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in - *import*) : ;; - *) false ;; - esac -} - -# func_mode_link arg... -func_mode_link () -{ - $opt_debug - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - # It is impossible to link a dll without this setting, and - # we shouldn't force the makefile maintainer to figure out - # which system we are compiling for in order to pass an extra - # flag for every libtool invocation. - # allow_undefined=no - - # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll which has undefined symbols, in which case not - # even a static library is built. For now, we need to specify - # -no-undefined on the libtool link line when we can be certain - # that all symbols are satisfied, otherwise we get a static library. - allow_undefined=yes - ;; - *) - allow_undefined=yes - ;; - esac - libtool_args=$nonopt - base_compile="$nonopt $@" - compile_command=$nonopt - finalize_command=$nonopt - - compile_rpath= - finalize_rpath= - compile_shlibpath= - finalize_shlibpath= - convenience= - old_convenience= - deplibs= - old_deplibs= - compiler_flags= - linker_flags= - dllsearchpath= - lib_search_path=`pwd` - inst_prefix_dir= - new_inherited_linker_flags= - - avoid_version=no - bindir= - dlfiles= - dlprefiles= - dlself=no - export_dynamic=no - export_symbols= - export_symbols_regex= - generated= - libobjs= - ltlibs= - module=no - no_install=no - objs= - non_pic_objects= - precious_files_regex= - prefer_static_libs=no - preload=no - prev= - prevarg= - release= - rpath= - xrpath= - perm_rpath= - temp_rpath= - thread_safe=no - vinfo= - vinfo_number=no - weak_libs= - single_module="${wl}-single_module" - func_infer_tag $base_compile - - # We need to know -static, to get the right output filenames. - for arg - do - case $arg in - -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" - build_old_libs=no - break - ;; - -all-static | -static | -static-libtool-libs) - case $arg in - -all-static) - if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then - func_warning "complete static linking is impossible in this configuration" - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - -static) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=built - ;; - -static-libtool-libs) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - esac - build_libtool_libs=no - build_old_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test "$#" -gt 0; do - arg="$1" - shift - func_quote_for_eval "$arg" - qarg=$func_quote_for_eval_unquoted_result - func_append libtool_args " $func_quote_for_eval_result" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - func_append compile_command " @OUTPUT@" - func_append finalize_command " @OUTPUT@" - ;; - esac - - case $prev in - bindir) - bindir="$arg" - prev= - continue - ;; - dlfiles|dlprefiles) - if test "$preload" = no; then - # Add the symbol object into the linking commands. - func_append compile_command " @SYMFILE@" - func_append finalize_command " @SYMFILE@" - preload=yes - fi - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test "$dlself" = no; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test "$prev" = dlprefiles; then - dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test "$prev" = dlfiles; then - func_append dlfiles " $arg" - else - func_append dlprefiles " $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols="$arg" - test -f "$arg" \ - || func_fatal_error "symbol file \`$arg' does not exist" - prev= - continue - ;; - expsyms_regex) - export_symbols_regex="$arg" - prev= - continue - ;; - framework) - case $host in - *-*-darwin*) - case "$deplibs " in - *" $qarg.ltframework "*) ;; - *) func_append deplibs " $qarg.ltframework" # this is fixed later - ;; - esac - ;; - esac - prev= - continue - ;; - inst_prefix) - inst_prefix_dir="$arg" - prev= - continue - ;; - objectlist) - if test -f "$arg"; then - save_arg=$arg - moreargs= - for fil in `cat "$save_arg"` - do -# func_append moreargs " $fil" - arg=$fil - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if func_lalib_unsafe_p "$arg"; then - pic_object= - non_pic_object= - - # Read the .lo file - func_source "$arg" - - if test -z "$pic_object" || - test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" - fi - - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - func_append dlfiles " $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - func_append dlprefiles " $pic_object" - prev= - fi - - # A PIC object. - func_append libobjs " $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" - func_append non_pic_objects " $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if $opt_dry_run; then - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - func_lo2o "$arg" - pic_object=$xdir$objdir/$func_lo2o_result - non_pic_object=$xdir$func_lo2o_result - func_append libobjs " $pic_object" - func_append non_pic_objects " $non_pic_object" - else - func_fatal_error "\`$arg' is not a valid libtool object" - fi - fi - done - else - func_fatal_error "link input file \`$arg' does not exist" - fi - arg=$save_arg - prev= - continue - ;; - precious_regex) - precious_files_regex="$arg" - prev= - continue - ;; - release) - release="-$arg" - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - func_fatal_error "only absolute run-paths are allowed" - ;; - esac - if test "$prev" = rpath; then - case "$rpath " in - *" $arg "*) ;; - *) func_append rpath " $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) func_append xrpath " $arg" ;; - esac - fi - prev= - continue - ;; - shrext) - shrext_cmds="$arg" - prev= - continue - ;; - weak) - func_append weak_libs " $arg" - prev= - continue - ;; - xcclinker) - func_append linker_flags " $qarg" - func_append compiler_flags " $qarg" - prev= - func_append compile_command " $qarg" - func_append finalize_command " $qarg" - continue - ;; - xcompiler) - func_append compiler_flags " $qarg" - prev= - func_append compile_command " $qarg" - func_append finalize_command " $qarg" - continue - ;; - xlinker) - func_append linker_flags " $qarg" - func_append compiler_flags " $wl$qarg" - prev= - func_append compile_command " $wl$qarg" - func_append finalize_command " $wl$qarg" - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n "$prev" - - prevarg="$arg" - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - # See comment for -static flag below, for more details. - func_append compile_command " $link_static_flag" - func_append finalize_command " $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - func_fatal_error "\`-allow-undefined' must not be used because it is the default" - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -bindir) - prev=bindir - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - func_fatal_error "more than one -exported-symbols argument is not allowed" - fi - if test "X$arg" = "X-export-symbols"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - -framework) - prev=framework - continue - ;; - - -inst-prefix-dir) - prev=inst_prefix - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix* | /*-*-irix*) - func_append compile_command " $arg" - func_append finalize_command " $arg" - ;; - esac - continue - ;; - - -L*) - func_stripname "-L" '' "$arg" - if test -z "$func_stripname_result"; then - if test "$#" -gt 0; then - func_fatal_error "require no space between \`-L' and \`$1'" - else - func_fatal_error "need path for \`-L' option" - fi - fi - func_resolve_sysroot "$func_stripname_result" - dir=$func_resolve_sysroot_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - test -z "$absdir" && \ - func_fatal_error "cannot determine absolute directory name of \`$dir'" - dir="$absdir" - ;; - esac - case "$deplibs " in - *" -L$dir "* | *" $arg "*) - # Will only happen for absolute or sysroot arguments - ;; - *) - # Preserve sysroot, but never include relative directories - case $dir in - [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; - *) func_append deplibs " -L$dir" ;; - esac - func_append lib_search_path " $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$dir:"*) ;; - ::) dllsearchpath=$dir;; - *) func_append dllsearchpath ":$dir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - ::) dllsearchpath=$testbindir;; - *) func_append dllsearchpath ":$testbindir";; - esac - ;; - esac - continue - ;; - - -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-os2*) - # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C and math libraries are in the System framework - func_append deplibs " System.ltframework" - continue - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - test "X$arg" = "X-lc" && continue - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - test "X$arg" = "X-lc" && continue - ;; - esac - elif test "X$arg" = "X-lc_r"; then - case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - func_append deplibs " $arg" - continue - ;; - - -module) - module=yes - continue - ;; - - # Tru64 UNIX uses -model [arg] to determine the layout of C++ - # classes, name mangling, and exception handling. - # Darwin uses the -arch flag to determine output architecture. - -model|-arch|-isysroot|--sysroot) - func_append compiler_flags " $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - prev=xcompiler - continue - ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) - func_append compiler_flags " $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - case "$new_inherited_linker_flags " in - *" $arg "*) ;; - * ) func_append new_inherited_linker_flags " $arg" ;; - esac - continue - ;; - - -multi_module) - single_module="${wl}-multi_module" - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) - # The PATH hackery in wrapper scripts is required on Windows - # and Darwin in order for the loader to find any dlls it needs. - func_warning "\`-no-install' is ignored for $host" - func_warning "assuming \`-no-fast-install' instead" - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -objectlist) - prev=objectlist - continue - ;; - - -o) prev=output ;; - - -precious-files-regex) - prev=precious_regex - continue - ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - func_stripname '-R' '' "$arg" - dir=$func_stripname_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - =*) - func_stripname '=' '' "$dir" - dir=$lt_sysroot$func_stripname_result - ;; - *) - func_fatal_error "only absolute run-paths are allowed" - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) func_append xrpath " $dir" ;; - esac - continue - ;; - - -shared) - # The effects of -shared are defined in a previous loop. - continue - ;; - - -shrext) - prev=shrext - continue - ;; - - -static | -static-libtool-libs) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - - -version-number) - prev=vinfo - vinfo_number=yes - continue - ;; - - -weak) - prev=weak - continue - ;; - - -Wc,*) - func_stripname '-Wc,' '' "$arg" - args=$func_stripname_result - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - func_quote_for_eval "$flag" - func_append arg " $func_quote_for_eval_result" - func_append compiler_flags " $func_quote_for_eval_result" - done - IFS="$save_ifs" - func_stripname ' ' '' "$arg" - arg=$func_stripname_result - ;; - - -Wl,*) - func_stripname '-Wl,' '' "$arg" - args=$func_stripname_result - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - func_quote_for_eval "$flag" - func_append arg " $wl$func_quote_for_eval_result" - func_append compiler_flags " $wl$func_quote_for_eval_result" - func_append linker_flags " $func_quote_for_eval_result" - done - IFS="$save_ifs" - func_stripname ' ' '' "$arg" - arg=$func_stripname_result - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - -XCClinker) - prev=xcclinker - continue - ;; - - # -msg_* for osf cc - -msg_*) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - - # Flags to be passed through unchanged, with rationale: - # -64, -mips[0-9] enable 64-bit mode for the SGI compiler - # -r[0-9][0-9]* specify processor for the SGI compiler - # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler - # +DA*, +DD* enable 64-bit mode for the HP compiler - # -q* compiler args for the IBM compiler - # -m*, -t[45]*, -txscale* architecture-specific flags for GCC - # -F/path path to uninstalled frameworks, gcc on darwin - # -p, -pg, --coverage, -fprofile-* profiling flags for GCC - # @file GCC response files - # -tp=* Portland pgcc target processor selection - # --sysroot=* for sysroot support - # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization - # -{shared,static}-libgcc, -static-{libgfortran|libstdc++} - # link against specified runtime library - # -fstack-protector* stack protector flags for GCC - -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ - -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ - -O*|-flto*|-fwhopr*|-fuse-linker-plugin| \ - -shared-libgcc|-static-libgcc|-static-libgfortran|-static-libstdc++| \ - -fstack-protector*) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - func_append compile_command " $arg" - func_append finalize_command " $arg" - func_append compiler_flags " $arg" - continue - ;; - - # Some other compiler flag. - -* | +*) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - - *.$objext) - # A standard object. - func_append objs " $arg" - ;; - - *.lo) - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if func_lalib_unsafe_p "$arg"; then - pic_object= - non_pic_object= - - # Read the .lo file - func_source "$arg" - - if test -z "$pic_object" || - test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" - fi - - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - func_append dlfiles " $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - func_append dlprefiles " $pic_object" - prev= - fi - - # A PIC object. - func_append libobjs " $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" - func_append non_pic_objects " $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if $opt_dry_run; then - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - func_lo2o "$arg" - pic_object=$xdir$objdir/$func_lo2o_result - non_pic_object=$xdir$func_lo2o_result - func_append libobjs " $pic_object" - func_append non_pic_objects " $non_pic_object" - else - func_fatal_error "\`$arg' is not a valid libtool object" - fi - fi - ;; - - *.$libext) - # An archive. - func_append deplibs " $arg" - func_append old_deplibs " $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - func_resolve_sysroot "$arg" - if test "$prev" = dlfiles; then - # This library was specified with -dlopen. - func_append dlfiles " $func_resolve_sysroot_result" - prev= - elif test "$prev" = dlprefiles; then - # The library was specified with -dlpreopen. - func_append dlprefiles " $func_resolve_sysroot_result" - prev= - else - func_append deplibs " $func_resolve_sysroot_result" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - func_append compile_command " $arg" - func_append finalize_command " $arg" - fi - done # argument parsing loop - - test -n "$prev" && \ - func_fatal_help "the \`$prevarg' option requires an argument" - - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - func_append compile_command " $arg" - func_append finalize_command " $arg" - fi - - oldlibs= - # calculate the name of the file, without its directory - func_basename "$output" - outputname="$func_basename_result" - libobjs_save="$libobjs" - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - func_dirname "$output" "/" "" - output_objdir="$func_dirname_result$objdir" - func_to_tool_file "$output_objdir/" - tool_output_objdir=$func_to_tool_file_result - # Create the object directory. - func_mkdir_p "$output_objdir" - - # Determine the type of output - case $output in - "") - func_fatal_help "you must specify an output file" - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - specialdeplibs= - - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - if $opt_preserve_dup_deps ; then - case "$libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append libs " $deplib" - done - - if test "$linkmode" = lib; then - libs="$predeps $libs $compiler_lib_search_path $postdeps" - - # Compute libraries that are listed more than once in $predeps - # $postdeps and mark them as special (i.e., whose duplicates are - # not to be eliminated). - pre_post_deps= - if $opt_duplicate_compiler_generated_deps; then - for pre_post_dep in $predeps $postdeps; do - case "$pre_post_deps " in - *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; - esac - func_append pre_post_deps " $pre_post_dep" - done - fi - pre_post_deps= - fi - - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - notinst_path= # paths that contain not-installed libtool libraries - - case $linkmode in - lib) - passes="conv dlpreopen link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=no - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - - for pass in $passes; do - # The preopen pass in lib mode reverses $deplibs; put it back here - # so that -L comes before libs that need it for instance... - if test "$linkmode,$pass" = "lib,link"; then - ## FIXME: Find the place where the list is rebuilt in the wrong - ## order, and fix it there properly - tmp_deplibs= - for deplib in $deplibs; do - tmp_deplibs="$deplib $tmp_deplibs" - done - deplibs="$tmp_deplibs" - fi - - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan"; then - libs="$deplibs" - deplibs= - fi - if test "$linkmode" = prog; then - case $pass in - dlopen) libs="$dlfiles" ;; - dlpreopen) libs="$dlprefiles" ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; - esac - fi - if test "$linkmode,$pass" = "lib,dlpreopen"; then - # Collect and forward deplibs of preopened libtool libs - for lib in $dlprefiles; do - # Ignore non-libtool-libs - dependency_libs= - func_resolve_sysroot "$lib" - case $lib in - *.la) func_source "$func_resolve_sysroot_result" ;; - esac - - # Collect preopened libtool deplibs, except any this library - # has declared as weak libs - for deplib in $dependency_libs; do - func_basename "$deplib" - deplib_base=$func_basename_result - case " $weak_libs " in - *" $deplib_base "*) ;; - *) func_append deplibs " $deplib" ;; - esac - done - done - libs="$dlprefiles" - fi - if test "$pass" = dlopen; then - # Collect dlpreopened libraries - save_deplibs="$deplibs" - deplibs= - fi - - for deplib in $libs; do - lib= - found=no - case $deplib in - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - func_append compiler_flags " $deplib" - if test "$linkmode" = lib ; then - case "$new_inherited_linker_flags " in - *" $deplib "*) ;; - * ) func_append new_inherited_linker_flags " $deplib" ;; - esac - fi - fi - continue - ;; - -l*) - if test "$linkmode" != lib && test "$linkmode" != prog; then - func_warning "\`-l' is ignored for archives/objects" - continue - fi - func_stripname '-l' '' "$deplib" - name=$func_stripname_result - if test "$linkmode" = lib; then - searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" - else - searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" - fi - for searchdir in $searchdirs; do - for search_ext in .la $std_shrext .so .a; do - # Search the libtool library - lib="$searchdir/lib${name}${search_ext}" - if test -f "$lib"; then - if test "$search_ext" = ".la"; then - found=yes - else - found=no - fi - break 2 - fi - done - done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - else # deplib is a libtool library - # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, - # We need to do some special things here, and not later. - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $deplib "*) - if func_lalib_p "$lib"; then - library_names= - old_library= - func_source "$lib" - for l in $old_library $library_names; do - ll="$l" - done - if test "X$ll" = "X$old_library" ; then # only static version available - found=no - func_dirname "$lib" "" "." - ladir="$func_dirname_result" - lib=$ladir/$old_library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - fi - ;; - *) ;; - esac - fi - fi - ;; # -l - *.ltframework) - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - if test "$linkmode" = lib ; then - case "$new_inherited_linker_flags " in - *" $deplib "*) ;; - * ) func_append new_inherited_linker_flags " $deplib" ;; - esac - fi - fi - continue - ;; - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test "$pass" = conv && continue - newdependency_libs="$deplib $newdependency_libs" - func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - prog) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - if test "$pass" = scan; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - *) - func_warning "\`-L' is ignored for archives/objects" - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test "$pass" = link; then - func_stripname '-R' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - dir=$func_resolve_sysroot_result - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) func_append xrpath " $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) - func_resolve_sysroot "$deplib" - lib=$func_resolve_sysroot_result - ;; - *.$libext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - # Linking convenience modules into shared libraries is allowed, - # but linking other static libraries is non-portable. - case " $dlpreconveniencelibs " in - *" $deplib "*) ;; - *) - valid_a_lib=no - case $deplibs_check_method in - match_pattern*) - set dummy $deplibs_check_method; shift - match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - valid_a_lib=yes - fi - ;; - pass_all) - valid_a_lib=yes - ;; - esac - if test "$valid_a_lib" != yes; then - echo - $ECHO "*** Warning: Trying to link with static lib archive $deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because the file extensions .$libext of this argument makes me believe" - echo "*** that it is just a static archive that I should not use here." - else - echo - $ECHO "*** Warning: Linking the shared library $output against the" - $ECHO "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - fi - ;; - esac - continue - ;; - prog) - if test "$pass" != link; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - elif test "$linkmode" = prog; then - if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - func_append newdlprefiles " $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - func_append newdlfiles " $deplib" - fi - fi - continue - ;; - %DEPLIBS%) - alldeplibs=yes - continue - ;; - esac # case $deplib - - if test "$found" = yes || test -f "$lib"; then : - else - func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" - fi - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$lib" \ - || func_fatal_error "\`$lib' is not a valid libtool archive" - - func_dirname "$lib" "" "." - ladir="$func_dirname_result" - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - inherited_linker_flags= - # If the library was installed with an old release of libtool, - # it will not redefine variables installed, or shouldnotlink - installed=yes - shouldnotlink=no - avoidtemprpath= - - - # Read the .la file - func_source "$lib" - - # Convert "-framework foo" to "foo.ltframework" - if test -n "$inherited_linker_flags"; then - tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` - for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do - case " $new_inherited_linker_flags " in - *" $tmp_inherited_linker_flag "*) ;; - *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; - esac - done - fi - dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test "$linkmode" != prog && test "$linkmode" != lib; }; then - test -n "$dlopen" && func_append dlfiles " $dlopen" - test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" - fi - - if test "$pass" = conv; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - func_fatal_error "cannot find name of link library for \`$lib'" - fi - # It is a libtool convenience library, so add in its objects. - func_append convenience " $ladir/$objdir/$old_library" - func_append old_convenience " $ladir/$objdir/$old_library" - elif test "$linkmode" != prog && test "$linkmode" != lib; then - func_fatal_error "\`$lib' is not a convenience library" - fi - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if $opt_preserve_dup_deps ; then - case "$tmp_libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append tmp_libs " $deplib" - done - continue - fi # $pass = conv - - - # Get the name of the library we link against. - linklib= - if test -n "$old_library" && - { test "$prefer_static_libs" = yes || - test "$prefer_static_libs,$installed" = "built,no"; }; then - linklib=$old_library - else - for l in $old_library $library_names; do - linklib="$l" - done - fi - if test -z "$linklib"; then - func_fatal_error "cannot find name of link library for \`$lib'" - fi - - # This library was specified with -dlopen. - if test "$pass" = dlopen; then - if test -z "$libdir"; then - func_fatal_error "cannot -dlopen a convenience library: \`$lib'" - fi - if test -z "$dlname" || - test "$dlopen_support" != yes || - test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. We also need to preload any - # dependent libraries so libltdl's deplib preloader doesn't - # bomb out in the load deplibs phase. - func_append dlprefiles " $lib $dependency_libs" - else - func_append newdlfiles " $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - func_warning "cannot determine absolute directory name of \`$ladir'" - func_warning "passing it literally to the linker, although it might fail" - abs_ladir="$ladir" - fi - ;; - esac - func_basename "$lib" - laname="$func_basename_result" - - # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then - if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - func_warning "library \`$lib' was moved." - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" - else - dir="$lt_sysroot$libdir" - absdir="$lt_sysroot$libdir" - fi - test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes - else - if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then - dir="$ladir" - absdir="$abs_ladir" - # Remove this search path later - func_append notinst_path " $abs_ladir" - else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" - # Remove this search path later - func_append notinst_path " $abs_ladir" - fi - fi # $installed = yes - func_stripname 'lib' '.la' "$laname" - name=$func_stripname_result - - # This library was specified with -dlpreopen. - if test "$pass" = dlpreopen; then - if test -z "$libdir" && test "$linkmode" = prog; then - func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" - fi - case "$host" in - # special handling for platforms with PE-DLLs. - *cygwin* | *mingw* | *cegcc* ) - # Linker will automatically link against shared library if both - # static and shared are present. Therefore, ensure we extract - # symbols from the import library if a shared library is present - # (otherwise, the dlopen module name will be incorrect). We do - # this by putting the import library name into $newdlprefiles. - # We recover the dlopen module name by 'saving' the la file - # name in a special purpose variable, and (later) extracting the - # dlname from the la file. - if test -n "$dlname"; then - func_tr_sh "$dir/$linklib" - eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" - func_append newdlprefiles " $dir/$linklib" - else - func_append newdlprefiles " $dir/$old_library" - # Keep a list of preopened convenience libraries to check - # that they are being used correctly in the link pass. - test -z "$libdir" && \ - func_append dlpreconveniencelibs " $dir/$old_library" - fi - ;; - * ) - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - func_append newdlprefiles " $dir/$old_library" - # Keep a list of preopened convenience libraries to check - # that they are being used correctly in the link pass. - test -z "$libdir" && \ - func_append dlpreconveniencelibs " $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - func_append newdlprefiles " $dir/$dlname" - else - func_append newdlprefiles " $dir/$linklib" - fi - ;; - esac - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test "$linkmode" = lib; then - deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" # used for prog,scan pass - fi - continue - fi - - - if test "$linkmode" = prog && test "$pass" != link; then - func_append newlib_search_path " $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - esac - # Need to link against all dependency_libs? - if test "$linkalldeplibs" = yes; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - if $opt_preserve_dup_deps ; then - case "$tmp_libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append tmp_libs " $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - if test "$linkmode,$pass" = "prog,link"; then - if test -n "$library_names" && - { { test "$prefer_static_libs" = no || - test "$prefer_static_libs,$installed" = "built,yes"; } || - test -z "$old_library"; }; then - # We need to hardcode the library path - if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath:" in - *"$absdir:"*) ;; - *) func_append temp_rpath "$absdir:" ;; - esac - fi - - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) func_append compile_rpath " $absdir" ;; - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - ;; - esac - fi # $linkmode,$pass = prog,link... - - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - fi - - link_static=no # Whether the deplib will be linked statically - use_static_libs=$prefer_static_libs - if test "$use_static_libs" = built && test "$installed" = yes; then - use_static_libs=no - fi - if test -n "$library_names" && - { test "$use_static_libs" = no || test -z "$old_library"; }; then - case $host in - *cygwin* | *mingw* | *cegcc*) - # No point in relinking DLLs because paths are not encoded - func_append notinst_deplibs " $lib" - need_relink=no - ;; - *) - if test "$installed" = no; then - func_append notinst_deplibs " $lib" - need_relink=yes - fi - ;; - esac - # This is a shared library - - # Warn about portability, can't link against -module's on some - # systems (darwin). Don't bleat about dlopened modules though! - dlopenmodule="" - for dlpremoduletest in $dlprefiles; do - if test "X$dlpremoduletest" = "X$lib"; then - dlopenmodule="$dlpremoduletest" - break - fi - done - if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then - echo - if test "$linkmode" = prog; then - $ECHO "*** Warning: Linking the executable $output against the loadable module" - else - $ECHO "*** Warning: Linking the shared library $output against the loadable module" - fi - $ECHO "*** $linklib is not portable!" - fi - if test "$linkmode" = lib && - test "$hardcode_into_libs" = yes; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) func_append compile_rpath " $absdir" ;; - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - ;; - esac - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - shift - realname="$1" - shift - libname=`eval "\\$ECHO \"$libname_spec\""` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname="$dlname" - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin* | mingw* | *cegcc*) - func_arith $current - $age - major=$func_arith_result - versuffix="-$major" - ;; - esac - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" - func_basename "$soroot" - soname="$func_basename_result" - func_stripname 'lib' '.dll' "$soname" - newlib=libimp-$func_stripname_result.a - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - func_verbose "extracting exported symbol list from \`$soname'" - func_execute_cmds "$extract_expsyms_cmds" 'exit $?' - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - func_verbose "generating import library for \`$soname'" - func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n "$old_archive_from_expsyms_cmds" - - if test "$linkmode" = prog || test "$opt_mode" != relink; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" - case $host in - *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; - *-*-sysv4*uw2*) add_dir="-L$dir" ;; - *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ - *-*-unixware7*) add_dir="-L$dir" ;; - *-*-darwin* ) - # if the lib is a (non-dlopened) module then we can not - # link against it, someone is ignoring the earlier warnings - if /usr/bin/file -L $add 2> /dev/null | - $GREP ": [^:]* bundle" >/dev/null ; then - if test "X$dlopenmodule" != "X$lib"; then - $ECHO "*** Warning: lib $linklib is a module, not a shared library" - if test -z "$old_library" ; then - echo - echo "*** And there doesn't seem to be a static archive available" - echo "*** The link will probably fail, sorry" - else - add="$dir/$old_library" - fi - elif test -n "$old_library"; then - add="$dir/$old_library" - fi - fi - esac - elif test "$hardcode_minus_L" = no; then - case $host in - *-*-sunos*) add_shlibpath="$dir" ;; - esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - relink) - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$dir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - func_append add_dir " -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test "$lib_linked" != yes; then - func_fatal_configuration "unsupported hardcode properties" - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) func_append compile_shlibpath "$add_shlibpath:" ;; - esac - fi - if test "$linkmode" = prog; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && - test "$hardcode_minus_L" != yes && - test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) func_append finalize_shlibpath "$libdir:" ;; - esac - fi - fi - fi - - if test "$linkmode" = prog || test "$opt_mode" = relink; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) func_append finalize_shlibpath "$libdir:" ;; - esac - add="-l$name" - elif test "$hardcode_automatic" = yes; then - if test -n "$inst_prefix_dir" && - test -f "$inst_prefix_dir$libdir/$linklib" ; then - add="$inst_prefix_dir$libdir/$linklib" - else - add="$libdir/$linklib" - fi - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - func_append add_dir " -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - fi - - if test "$linkmode" = prog; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test "$linkmode" = prog; then - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test "$build_libtool_libs" = yes; then - # Not a shared library - if test "$deplibs_check_method" != pass_all; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - echo - $ECHO "*** Warning: This system can not link to static lib archive $lib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then - echo "*** But as you try to build a module library, libtool will still create " - echo "*** a static module, that should work as long as the dlopening application" - echo "*** is linked with the -dlopen flag to resolve symbols at runtime." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test "$linkmode" = lib; then - if test -n "$dependency_libs" && - { test "$hardcode_into_libs" != yes || - test "$build_old_libs" = yes || - test "$link_static" = yes; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) func_stripname '-R' '' "$libdir" - temp_xrpath=$func_stripname_result - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) func_append xrpath " $temp_xrpath";; - esac;; - *) func_append temp_deplibs " $libdir";; - esac - done - dependency_libs="$temp_deplibs" - fi - - func_append newlib_search_path " $absdir" - # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - case $deplib in - -L*) func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result";; - *) func_resolve_sysroot "$deplib" ;; - esac - if $opt_preserve_dup_deps ; then - case "$tmp_libs " in - *" $func_resolve_sysroot_result "*) - func_append specialdeplibs " $func_resolve_sysroot_result" ;; - esac - fi - func_append tmp_libs " $func_resolve_sysroot_result" - done - - if test "$link_all_deplibs" != no; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - path= - case $deplib in - -L*) path="$deplib" ;; - *.la) - func_resolve_sysroot "$deplib" - deplib=$func_resolve_sysroot_result - func_dirname "$deplib" "" "." - dir=$func_dirname_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - func_warning "cannot determine absolute directory name of \`$dir'" - absdir="$dir" - fi - ;; - esac - if $GREP "^installed=no" $deplib > /dev/null; then - case $host in - *-*-darwin*) - depdepl= - eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names" ; then - for tmp in $deplibrary_names ; do - depdepl=$tmp - done - if test -f "$absdir/$objdir/$depdepl" ; then - depdepl="$absdir/$objdir/$depdepl" - darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` - if test -z "$darwin_install_name"; then - darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` - fi - func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" - func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" - path= - fi - fi - ;; - *) - path="-L$absdir/$objdir" - ;; - esac - else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" - test "$absdir" != "$libdir" && \ - func_warning "\`$deplib' seems to be moved" - - path="-L$absdir" - fi - ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$path $deplibs" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - if test "$pass" = link; then - if test "$linkmode" = "prog"; then - compile_deplibs="$new_inherited_linker_flags $compile_deplibs" - finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" - else - compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - fi - fi - dependency_libs="$newdependency_libs" - if test "$pass" = dlpreopen; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test "$pass" != dlopen; then - if test "$pass" != conv; then - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) func_append lib_search_path " $dir" ;; - esac - done - newlib_search_path= - fi - - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else - vars="compile_deplibs finalize_deplibs" - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - # FIXME: Pedantically, this is the right thing to do, so - # that some nasty dependency loop isn't accidentally - # broken: - #new_libs="$deplib $new_libs" - # Pragmatically, this seems to cause very few problems in - # practice: - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - -R*) ;; - *) - # And here is the reason: when a library appears more - # than once as an explicit dependence of a library, or - # is implicitly linked in more than once by the - # compiler, it is considered special, and multiple - # occurrences thereof are not removed. Compare this - # with having the same library being listed as a - # dependency of multiple other libraries: in this case, - # we know (pedantically, we assume) the library does not - # need to be listed more than once, so we keep only the - # last copy. This is not always right, but it is rare - # enough that we require users that really mean to play - # such unportable linking tricks to link the library - # using -Wl,-lname, so that libtool does not consider it - # for duplicate removal. - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) func_append tmp_libs " $deplib" ;; - esac - ;; - *) func_append tmp_libs " $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - # Last step: remove runtime libs from dependency_libs - # (they stay in deplibs) - tmp_libs= - for i in $dependency_libs ; do - case " $predeps $postdeps $compiler_lib_search_path " in - *" $i "*) - i="" - ;; - esac - if test -n "$i" ; then - func_append tmp_libs " $i" - fi - done - dependency_libs=$tmp_libs - done # for pass - if test "$linkmode" = prog; then - dlfiles="$newdlfiles" - fi - if test "$linkmode" = prog || test "$linkmode" = lib; then - dlprefiles="$newdlprefiles" - fi - - case $linkmode in - oldlib) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for archives" - fi - - case " $deplibs" in - *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for archives" ;; - esac - - test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for archives" - - test -n "$xrpath" && \ - func_warning "\`-R' is ignored for archives" - - test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for archives" - - test -n "$release" && \ - func_warning "\`-release' is ignored for archives" - - test -n "$export_symbols$export_symbols_regex" && \ - func_warning "\`-export-symbols' is ignored for archives" - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs="$output" - func_append objs "$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form `libNAME.la'. - case $outputname in - lib*) - func_stripname 'lib' '.la' "$outputname" - name=$func_stripname_result - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - ;; - *) - test "$module" = no && \ - func_fatal_help "libtool library \`$output' must begin with \`lib'" - - if test "$need_lib_prefix" != no; then - # Add the "lib" prefix for modules if required - func_stripname '' '.la' "$outputname" - name=$func_stripname_result - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - else - func_stripname '' '.la' "$outputname" - libname=$func_stripname_result - fi - ;; - esac - - if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" - else - echo - $ECHO "*** Warning: Linking the shared library $output against the non-libtool" - $ECHO "*** objects $objs is not portable!" - func_append libobjs " $objs" - fi - fi - - test "$dlself" != no && \ - func_warning "\`-dlopen self' is ignored for libtool libraries" - - set dummy $rpath - shift - test "$#" -gt 1 && \ - func_warning "ignoring multiple \`-rpath's for a libtool library" - - install_libdir="$1" - - oldlibs= - if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then - # Building a libtool convenience library. - # Some compilers have problems with a `.al' extension so - # convenience libraries should have the same extension an - # archive normally would. - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for convenience libraries" - - test -n "$release" && \ - func_warning "\`-release' is ignored for convenience libraries" - else - - # Parse the version information argument. - save_ifs="$IFS"; IFS=':' - set dummy $vinfo 0 0 0 - shift - IFS="$save_ifs" - - test -n "$7" && \ - func_fatal_help "too many parameters to \`-version-info'" - - # convert absolute version numbers to libtool ages - # this retains compatibility with .la files and attempts - # to make the code below a bit more comprehensible - - case $vinfo_number in - yes) - number_major="$1" - number_minor="$2" - number_revision="$3" - # - # There are really only two kinds -- those that - # use the current revision as the major version - # and those that subtract age and use age as - # a minor version. But, then there is irix - # which has an extra 1 added just for fun - # - case $version_type in - darwin|linux|osf|windows|none) - func_arith $number_major + $number_minor - current=$func_arith_result - age="$number_minor" - revision="$number_revision" - ;; - freebsd-aout|freebsd-elf|qnx|sunos) - current="$number_major" - revision="$number_minor" - age="0" - ;; - irix|nonstopux) - func_arith $number_major + $number_minor - current=$func_arith_result - age="$number_minor" - revision="$number_minor" - lt_irix_increment=no - ;; - esac - ;; - no) - current="$1" - revision="$2" - age="$3" - ;; - esac - - # Check that each of the things are valid numbers. - case $current in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "CURRENT \`$current' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - case $revision in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "REVISION \`$revision' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - case $age in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "AGE \`$age' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - if test "$age" -gt "$current"; then - func_error "AGE \`$age' is greater than the current interface number \`$current'" - func_fatal_error "\`$vinfo' is not valid version information" - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - func_arith $current - $age - major=.$func_arith_result - versuffix="$major.$age.$revision" - # Darwin ld doesn't like 0 for these options... - func_arith $current + 1 - minor_current=$func_arith_result - xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - ;; - - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current" - ;; - - irix | nonstopux) - if test "X$lt_irix_increment" = "Xno"; then - func_arith $current - $age - else - func_arith $current - $age + 1 - fi - major=$func_arith_result - - case $version_type in - nonstopux) verstring_prefix=nonstopux ;; - *) verstring_prefix=sgi ;; - esac - verstring="$verstring_prefix$major.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test "$loop" -ne 0; do - func_arith $revision - $loop - iface=$func_arith_result - func_arith $loop - 1 - loop=$func_arith_result - verstring="$verstring_prefix$major.$iface:$verstring" - done - - # Before this point, $major must not contain `.'. - major=.$major - versuffix="$major.$revision" - ;; - - linux) - func_arith $current - $age - major=.$func_arith_result - versuffix="$major.$age.$revision" - ;; - - osf) - func_arith $current - $age - major=.$func_arith_result - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$age - while test "$loop" -ne 0; do - func_arith $current - $loop - iface=$func_arith_result - func_arith $loop - 1 - loop=$func_arith_result - verstring="$verstring:${iface}.0" - done - - # Make executables depend on our current version. - func_append verstring ":${current}.0" - ;; - - qnx) - major=".$current" - versuffix=".$current" - ;; - - sunos) - major=".$current" - versuffix=".$current.$revision" - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. - func_arith $current - $age - major=$func_arith_result - versuffix="-$major" - ;; - - *) - func_fatal_configuration "unknown library version type \`$version_type'" - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring= - ;; - *) - verstring="0.0" - ;; - esac - if test "$need_version" = no; then - versuffix= - else - versuffix=".0.0" - fi - fi - - # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then - major= - versuffix= - verstring="" - fi - - # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - func_warning "undefined symbols not allowed in $host shared libraries" - build_libtool_libs=no - build_old_libs=yes - fi - else - # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" - fi - - fi - - func_generate_dlsyms "$libname" "$libname" "yes" - func_append libobjs " $symfileobj" - test "X$libobjs" = "X " && libobjs= - - if test "$opt_mode" != relink; then - # Remove our outputs, but don't remove object files since they - # may have been created when compiling PIC objects. - removelist= - tempremovelist=`$ECHO "$output_objdir/*"` - for p in $tempremovelist; do - case $p in - *.$objext | *.gcno) - ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) - if test "X$precious_files_regex" != "X"; then - if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 - then - continue - fi - fi - func_append removelist " $p" - ;; - *) ;; - esac - done - test -n "$removelist" && \ - func_show_eval "${RM}r \$removelist" - fi - - # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then - func_append oldlibs " $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - #for path in $notinst_path; do - # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` - # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` - # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` - #done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - func_replace_sysroot "$libdir" - func_append temp_xrpath " -R$func_replace_sysroot_result" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - done - if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) func_append dlfiles " $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) func_append dlprefiles " $lib" ;; - esac - done - - if test "$build_libtool_libs" = yes; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - func_append deplibs " System.ltframework" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test "$build_libtool_need_lc" = "yes"; then - func_append deplibs " -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release="" - versuffix="" - major="" - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behavior. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $opt_dry_run || $RM conftest.c - cat > conftest.c </dev/null` - $nocaseglob - else - potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` - fi - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null | - $GREP " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib="$potent_lib" - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | - $SED -e 10q | - $EGREP "$file_magic_regex" > /dev/null; then - func_append newdeplibs " $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - $ECHO "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $ECHO "*** with $libname but no candidates were found. (...for file magic test)" - else - $ECHO "*** with $libname and none of the candidates passed a file format test" - $ECHO "*** using a file magic. Last file checked: $potlib" - fi - fi - ;; - *) - # Add a -L argument. - func_append newdeplibs " $a_deplib" - ;; - esac - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method; shift - match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - for a_deplib in $deplibs; do - case $a_deplib in - -l*) - func_stripname -l '' "$a_deplib" - name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $a_deplib "*) - func_append newdeplibs " $a_deplib" - a_deplib="" - ;; - esac - fi - if test -n "$a_deplib" ; then - libname=`eval "\\$ECHO \"$libname_spec\""` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check above in file_magic test - if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ - $EGREP "$match_pattern_regex" > /dev/null; then - func_append newdeplibs " $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - $ECHO "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" - else - $ECHO "*** with $libname and none of the candidates passed a file format test" - $ECHO "*** using a regex pattern. Last file checked: $potlib" - fi - fi - ;; - *) - # Add a -L argument. - func_append newdeplibs " $a_deplib" - ;; - esac - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs="" - tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - for i in $predeps $postdeps ; do - # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` - done - fi - case $tmp_deplibs in - *[!\ \ ]*) - echo - if test "X$deplibs_check_method" = "Xnone"; then - echo "*** Warning: inter-library dependencies are not supported in this platform." - else - echo "*** Warning: inter-library dependencies are not known to be supported." - fi - echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - ;; - esac - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library with the System framework - newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` - ;; - esac - - if test "$droppeddeps" = yes; then - if test "$module" = yes; then - echo - echo "*** Warning: libtool could not satisfy all declared inter-library" - $ECHO "*** dependencies of module $libname. Therefore, libtool will create" - echo "*** a static module, that should work as long as the dlopening" - echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - echo "*** The inter-library dependencies that have been dropped here will be" - echo "*** automatically added whenever a program is linked with this library" - echo "*** or is declared to -dlopen it." - - if test "$allow_undefined" = no; then - echo - echo "*** Since this library must not contain undefined symbols," - echo "*** because either the platform does not support them or" - echo "*** it was explicitly requested with -no-undefined," - echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - # Time to change all our "foo.ltframework" stuff back to "-framework foo" - case $host in - *-*-darwin*) - newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - ;; - esac - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $deplibs " in - *" -L$path/$objdir "*) - func_append new_libs " -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) func_append new_libs " $deplib" ;; - esac - ;; - *) func_append new_libs " $deplib" ;; - esac - done - deplibs="$new_libs" - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - if test "$hardcode_into_libs" = yes; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath="$finalize_rpath" - test "$opt_mode" != relink && rpath="$compile_rpath$rpath" - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - func_replace_sysroot "$libdir" - libdir=$func_replace_sysroot_result - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append dep_rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) func_apped perm_rpath " $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - if test -n "$hardcode_libdir_flag_spec_ld"; then - eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" - else - eval dep_rpath=\"$hardcode_libdir_flag_spec\" - fi - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - func_append rpath "$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath="$finalize_shlibpath" - test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval shared_ext=\"$shrext_cmds\" - eval library_names=\"$library_names_spec\" - set dummy $library_names - shift - realname="$1" - shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - if test -z "$dlname"; then - dlname=$soname - fi - - lib="$output_objdir/$realname" - linknames= - for link - do - func_append linknames " $link" - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` - test "X$libobjs" = "X " && libobjs= - - delfiles= - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" - export_symbols="$output_objdir/$libname.uexp" - func_append delfiles " $export_symbols" - fi - - orig_export_symbols= - case $host_os in - cygwin* | mingw* | cegcc*) - if test -n "$export_symbols" && test -z "$export_symbols_regex"; then - # exporting using user supplied symfile - if test "x`$SED 1q $export_symbols`" != xEXPORTS; then - # and it's NOT already a .def file. Must figure out - # which of the given symbols are data symbols and tag - # them as such. So, trigger use of export_symbols_cmds. - # export_symbols gets reassigned inside the "prepare - # the list of exported symbols" if statement, so the - # include_expsyms logic still works. - orig_export_symbols="$export_symbols" - export_symbols= - always_export_symbols=yes - fi - fi - ;; - esac - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $opt_dry_run || $RM $export_symbols - cmds=$export_symbols_cmds - save_ifs="$IFS"; IFS='~' - for cmd1 in $cmds; do - IFS="$save_ifs" - # Take the normal branch if the nm_file_list_spec branch - # doesn't work or if tool conversion is not needed. - case $nm_file_list_spec~$to_tool_file_cmd in - *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) - try_normal_branch=yes - eval cmd=\"$cmd1\" - func_len " $cmd" - len=$func_len_result - ;; - *) - try_normal_branch=no - ;; - esac - if test "$try_normal_branch" = yes \ - && { test "$len" -lt "$max_cmd_len" \ - || test "$max_cmd_len" -le -1; } - then - func_show_eval "$cmd" 'exit $?' - skipped_export=false - elif test -n "$nm_file_list_spec"; then - func_basename "$output" - output_la=$func_basename_result - save_libobjs=$libobjs - save_output=$output - output=${output_objdir}/${output_la}.nm - func_to_tool_file "$output" - libobjs=$nm_file_list_spec$func_to_tool_file_result - func_append delfiles " $output" - func_verbose "creating $NM input file list: $output" - for obj in $save_libobjs; do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" - done > "$output" - eval cmd=\"$cmd1\" - func_show_eval "$cmd" 'exit $?' - output=$save_output - libobjs=$save_libobjs - skipped_export=false - else - # The command line is too long to execute in one step. - func_verbose "using reloadable object file for export list..." - skipped_export=: - # Break out early, otherwise skipped_export may be - # set to false by a later but shorter cmd. - break - fi - done - IFS="$save_ifs" - if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then - func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - func_show_eval '$MV "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" - $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' - fi - - if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then - # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" - # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine - # though. Also, the filter scales superlinearly with the number of - # global variables. join(1) would be nice here, but unfortunately - # isn't a blessed tool. - $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - func_append delfiles " $export_symbols $output_objdir/$libname.filter" - export_symbols=$output_objdir/$libname.def - $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols - fi - - tmp_deplibs= - for test_deplib in $deplibs; do - case " $convenience " in - *" $test_deplib "*) ;; - *) - func_append tmp_deplibs " $test_deplib" - ;; - esac - done - deplibs="$tmp_deplibs" - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec" && - test "$compiler_needs_object" = yes && - test -z "$libobjs"; then - # extract the archives, so we have objects to list. - # TODO: could optimize this to just extract one archive. - whole_archive_flag_spec= - fi - if test -n "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - test "X$libobjs" = "X " && libobjs= - else - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $convenience - func_append libobjs " $func_extract_archives_result" - test "X$libobjs" = "X " && libobjs= - fi - fi - - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - func_append linker_flags " $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test "$opt_mode" = relink; then - $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - eval test_cmds=\"$module_expsym_cmds\" - cmds=$module_expsym_cmds - else - eval test_cmds=\"$module_cmds\" - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval test_cmds=\"$archive_expsym_cmds\" - cmds=$archive_expsym_cmds - else - eval test_cmds=\"$archive_cmds\" - cmds=$archive_cmds - fi - fi - - if test "X$skipped_export" != "X:" && - func_len " $test_cmds" && - len=$func_len_result && - test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - : - else - # The command line is too long to link in one step, link piecewise - # or, if using GNU ld and skipped_export is not :, use a linker - # script. - - # Save the value of $output and $libobjs because we want to - # use them later. If we have whole_archive_flag_spec, we - # want to use save_libobjs as it was before - # whole_archive_flag_spec was expanded, because we can't - # assume the linker understands whole_archive_flag_spec. - # This may have to be revisited, in case too many - # convenience libraries get linked in and end up exceeding - # the spec. - if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - fi - save_output=$output - func_basename "$output" - output_la=$func_basename_result - - # Clear the reloadable object creation command queue and - # initialize k to one. - test_cmds= - concat_cmds= - objlist= - last_robj= - k=1 - - if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then - output=${output_objdir}/${output_la}.lnkscript - func_verbose "creating GNU ld script: $output" - echo 'INPUT (' > $output - for obj in $save_libobjs - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" >> $output - done - echo ')' >> $output - func_append delfiles " $output" - func_to_tool_file "$output" - output=$func_to_tool_file_result - elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then - output=${output_objdir}/${output_la}.lnk - func_verbose "creating linker input file list: $output" - : > $output - set x $save_libobjs - shift - firstobj= - if test "$compiler_needs_object" = yes; then - firstobj="$1 " - shift - fi - for obj - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" >> $output - done - func_append delfiles " $output" - func_to_tool_file "$output" - output=$firstobj\"$file_list_spec$func_to_tool_file_result\" - else - if test -n "$save_libobjs"; then - func_verbose "creating reloadable object files..." - output=$output_objdir/$output_la-${k}.$objext - eval test_cmds=\"$reload_cmds\" - func_len " $test_cmds" - len0=$func_len_result - len=$len0 - - # Loop over the list of objects to be linked. - for obj in $save_libobjs - do - func_len " $obj" - func_arith $len + $func_len_result - len=$func_arith_result - if test "X$objlist" = X || - test "$len" -lt "$max_cmd_len"; then - func_append objlist " $obj" - else - # The command $test_cmds is almost too long, add a - # command to the queue. - if test "$k" -eq 1 ; then - # The first file doesn't have a previous command to add. - reload_objs=$objlist - eval concat_cmds=\"$reload_cmds\" - else - # All subsequent reloadable object files will link in - # the last one created. - reload_objs="$objlist $last_robj" - eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" - fi - last_robj=$output_objdir/$output_la-${k}.$objext - func_arith $k + 1 - k=$func_arith_result - output=$output_objdir/$output_la-${k}.$objext - objlist=" $obj" - func_len " $last_robj" - func_arith $len0 + $func_len_result - len=$func_arith_result - fi - done - # Handle the remaining objects by creating one last - # reloadable object file. All subsequent reloadable object - # files will link in the last one created. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - reload_objs="$objlist $last_robj" - eval concat_cmds=\"\${concat_cmds}$reload_cmds\" - if test -n "$last_robj"; then - eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" - fi - func_append delfiles " $output" - - else - output= - fi - - if ${skipped_export-false}; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $opt_dry_run || $RM $export_symbols - libobjs=$output - # Append the command to create the export file. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" - if test -n "$last_robj"; then - eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" - fi - fi - - test -n "$save_libobjs" && - func_verbose "creating a temporary reloadable object file: $output" - - # Loop through the commands generated above and execute them. - save_ifs="$IFS"; IFS='~' - for cmd in $concat_cmds; do - IFS="$save_ifs" - $opt_silent || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" - } - $opt_dry_run || eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then - ( cd "$output_objdir" && \ - $RM "${realname}T" && \ - $MV "${realname}U" "$realname" ) - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - - if test -n "$export_symbols_regex" && ${skipped_export-false}; then - func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - func_show_eval '$MV "${export_symbols}T" "$export_symbols"' - fi - fi - - if ${skipped_export-false}; then - if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" - $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' - fi - - if test -n "$orig_export_symbols"; then - # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" - # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine - # though. Also, the filter scales superlinearly with the number of - # global variables. join(1) would be nice here, but unfortunately - # isn't a blessed tool. - $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - func_append delfiles " $export_symbols $output_objdir/$libname.filter" - export_symbols=$output_objdir/$libname.def - $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols - fi - fi - - libobjs=$output - # Restore the value of output. - output=$save_output - - if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - test "X$libobjs" = "X " && libobjs= - fi - # Expand the library linking commands again to reset the - # value of $libobjs for piecewise linking. - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - cmds=$module_expsym_cmds - else - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - cmds=$archive_expsym_cmds - else - cmds=$archive_cmds - fi - fi - fi - - if test -n "$delfiles"; then - # Append the command to remove temporary files to $cmds. - eval cmds=\"\$cmds~\$RM $delfiles\" - fi - - # Add any objects from preloaded convenience libraries - if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $dlprefiles - func_append libobjs " $func_extract_archives_result" - test "X$libobjs" = "X " && libobjs= - fi - - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $opt_silent || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" - } - $opt_dry_run || eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then - ( cd "$output_objdir" && \ - $RM "${realname}T" && \ - $MV "${realname}U" "$realname" ) - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - - # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then - $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? - - if test -n "$convenience"; then - if test -z "$whole_archive_flag_spec"; then - func_show_eval '${RM}r "$gentop"' - fi - fi - - exit $EXIT_SUCCESS - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then - # On all known operating systems, these are identical. - dlname="$soname" - fi - fi - ;; - - obj) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for objects" - fi - - case " $deplibs" in - *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for objects" ;; - esac - - test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for objects" - - test -n "$xrpath" && \ - func_warning "\`-R' is ignored for objects" - - test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for objects" - - test -n "$release" && \ - func_warning "\`-release' is ignored for objects" - - case $output in - *.lo) - test -n "$objs$old_deplibs" && \ - func_fatal_error "cannot build library object \`$output' from non-libtool objects" - - libobj=$output - func_lo2o "$libobj" - obj=$func_lo2o_result - ;; - *) - libobj= - obj="$output" - ;; - esac - - # Delete the old objects. - $opt_dry_run || $RM $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec and hope we can get by with - # turning comma into space.. - wl= - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" - reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` - else - gentop="$output_objdir/${obj}x" - func_append generated " $gentop" - - func_extract_archives $gentop $convenience - reload_conv_objs="$reload_objs $func_extract_archives_result" - fi - fi - - # If we're not building shared, we need to use non_pic_objs - test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" - - # Create the old-style object. - reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test - - output="$obj" - func_execute_cmds "$reload_cmds" 'exit $?' - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - exit $EXIT_SUCCESS - fi - - if test "$build_libtool_libs" != yes; then - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - # $show "echo timestamp > $libobj" - # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? - exit $EXIT_SUCCESS - fi - - if test -n "$pic_flag" || test "$pic_mode" != default; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output="$libobj" - func_execute_cmds "$reload_cmds" 'exit $?' - fi - - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - exit $EXIT_SUCCESS - ;; - - prog) - case $host in - *cygwin*) func_stripname '' '.exe' "$output" - output=$func_stripname_result.exe;; - esac - test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for programs" - - test -n "$release" && \ - func_warning "\`-release' is ignored for programs" - - test "$preload" = yes \ - && test "$dlopen_support" = unknown \ - && test "$dlopen_self" = unknown \ - && test "$dlopen_self_static" = unknown && \ - func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` - finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` - ;; - esac - - case $host in - *-*-darwin*) - # Don't allow lazy linking, it breaks C++ global constructors - # But is supposedly fixed on 10.4 or later (yay!). - if test "$tagname" = CXX ; then - case ${MACOSX_DEPLOYMENT_TARGET-10.0} in - 10.[0123]) - func_append compile_command " ${wl}-bind_at_load" - func_append finalize_command " ${wl}-bind_at_load" - ;; - esac - fi - # Time to change all our "foo.ltframework" stuff back to "-framework foo" - compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - ;; - esac - - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $compile_deplibs " in - *" -L$path/$objdir "*) - func_append new_libs " -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $compile_deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) func_append new_libs " $deplib" ;; - esac - ;; - *) func_append new_libs " $deplib" ;; - esac - done - compile_deplibs="$new_libs" - - - func_append compile_command " $compile_deplibs" - func_append finalize_command " $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) func_append perm_rpath " $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$libdir:"*) ;; - ::) dllsearchpath=$libdir;; - *) func_append dllsearchpath ":$libdir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - ::) dllsearchpath=$testbindir;; - *) func_append dllsearchpath ":$testbindir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath="$rpath" - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) func_append finalize_perm_rpath " $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath="$rpath" - - if test -n "$libobjs" && test "$build_old_libs" = yes; then - # Transform all the library objects into standard objects. - compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` - finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` - fi - - func_generate_dlsyms "$outputname" "@PROGRAM@" "no" - - # template prelinking step - if test -n "$prelink_cmds"; then - func_execute_cmds "$prelink_cmds" 'exit $?' - fi - - wrappers_required=yes - case $host in - *cegcc* | *mingw32ce*) - # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. - wrappers_required=no - ;; - *cygwin* | *mingw* ) - if test "$build_libtool_libs" != yes; then - wrappers_required=no - fi - ;; - *) - if test "$need_relink" = no || test "$build_libtool_libs" != yes; then - wrappers_required=no - fi - ;; - esac - if test "$wrappers_required" = no; then - # Replace the output file specification. - compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" - - # We have no uninstalled library dependencies, so finalize right now. - exit_status=0 - func_show_eval "$link_command" 'exit_status=$?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - # Delete the generated files. - if test -f "$output_objdir/${outputname}S.${objext}"; then - func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' - fi - - exit $exit_status - fi - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - func_append rpath "$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - func_append rpath "$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test "$no_install" = yes; then - # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" - # Replace the output file specification. - link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $opt_dry_run || $RM $output - # Link the executable and exit - func_show_eval "$link_command" 'exit $?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - exit $EXIT_SUCCESS - fi - - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - - func_warning "this platform does not like uninstalled shared libraries" - func_warning "\`$output' will be relinked during installation" - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi - - # Replace the output file specification. - link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname - - func_show_eval "$link_command" 'exit $?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output_objdir/$outputname" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - # Now create the wrapper script. - func_verbose "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" - fi - done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - fi - - # Only actually do things if not in dry run mode. - $opt_dry_run || { - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) func_stripname '' '.exe' "$output" - output=$func_stripname_result ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) - exeext=.exe - func_stripname '' '.exe' "$outputname" - outputname=$func_stripname_result ;; - *) exeext= ;; - esac - case $host in - *cygwin* | *mingw* ) - func_dirname_and_basename "$output" "" "." - output_name=$func_basename_result - output_path=$func_dirname_result - cwrappersource="$output_path/$objdir/lt-$output_name.c" - cwrapper="$output_path/$output_name.exe" - $RM $cwrappersource $cwrapper - trap "$RM $cwrappersource $cwrapper $cwrapper.manifest; exit $EXIT_FAILURE" 1 2 15 - - func_emit_cwrapperexe_src > $cwrappersource - - # The wrapper executable is built using the $host compiler, - # because it contains $host paths and files. If cross- - # compiling, it, like the target executable, must be - # executed on the $host or under an emulation environment. - $opt_dry_run || { - $LTCC $LTCFLAGS -o $cwrapper $cwrappersource - $STRIP $cwrapper - } - - # Now, create the wrapper script for func_source use: - func_ltwrapper_scriptname $cwrapper - $RM $func_ltwrapper_scriptname_result - trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 - $opt_dry_run || { - # note: this script will not be executed, so do not chmod. - if test "x$build" = "x$host" ; then - # Create the UAC manifests first if necessary (but the - # manifest files must have executable permission regardless). - case $output_name in - *instal*|*patch*|*setup*|*update*) - func_emit_exe_manifest > $cwrapper.manifest - func_emit_exe_manifest > $output_path/$objdir/$output_name.exe.manifest - chmod +x $cwrapper.manifest - chmod +x $output_path/$objdir/$output_name.exe.manifest - ;; - esac - $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result - else - func_emit_wrapper no > $func_ltwrapper_scriptname_result - fi - } - ;; - * ) - $RM $output - trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 - - func_emit_wrapper no > $output - chmod +x $output - ;; - esac - } - exit $EXIT_SUCCESS - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save $symfileobj" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" - build_libtool_libs=no - else - oldobjs="$old_deplibs $non_pic_objects" - if test "$preload" = yes && test -f "$symfileobj"; then - func_append oldobjs " $symfileobj" - fi - fi - addlibs="$old_convenience" - fi - - if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $addlibs - func_append oldobjs " $func_extract_archives_result" - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then - cmds=$old_archive_from_new_cmds - else - - # Add any objects from preloaded convenience libraries - if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $dlprefiles - func_append oldobjs " $func_extract_archives_result" - fi - - # POSIX demands no paths to be encoded in archives. We have - # to avoid creating archives with duplicate basenames if we - # might have to extract them afterwards, e.g., when creating a - # static archive out of a convenience library, or when linking - # the entirety of a libtool archive into another (currently - # not supported by libtool). - if (for obj in $oldobjs - do - func_basename "$obj" - $ECHO "$func_basename_result" - done | sort | sort -uc >/dev/null 2>&1); then - : - else - echo "copying selected object files to avoid basename conflicts..." - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - func_mkdir_p "$gentop" - save_oldobjs=$oldobjs - oldobjs= - counter=1 - for obj in $save_oldobjs - do - func_basename "$obj" - objbase="$func_basename_result" - case " $oldobjs " in - " ") oldobjs=$obj ;; - *[\ /]"$objbase "*) - while :; do - # Make sure we don't pick an alternate name that also - # overlaps. - newobj=lt$counter-$objbase - func_arith $counter + 1 - counter=$func_arith_result - case " $oldobjs " in - *[\ /]"$newobj "*) ;; - *) if test ! -f "$gentop/$newobj"; then break; fi ;; - esac - done - func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" - func_append oldobjs " $gentop/$newobj" - ;; - *) func_append oldobjs " $obj" ;; - esac - done - fi - eval cmds=\"$old_archive_cmds\" - - func_len " $cmds" - len=$func_len_result - if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - cmds=$old_archive_cmds - elif test -n "$archiver_list_spec"; then - func_verbose "using command file archive linking..." - for obj in $oldobjs - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" - done > $output_objdir/$libname.libcmd - func_to_tool_file "$output_objdir/$libname.libcmd" - oldobjs=" $archiver_list_spec$func_to_tool_file_result" - cmds=$old_archive_cmds - else - # the command line is too long to link in one step, link in parts - func_verbose "using piecewise archive linking..." - save_RANLIB=$RANLIB - RANLIB=: - objlist= - concat_cmds= - save_oldobjs=$oldobjs - oldobjs= - # Is there a better way of finding the last object in the list? - for obj in $save_oldobjs - do - last_oldobj=$obj - done - eval test_cmds=\"$old_archive_cmds\" - func_len " $test_cmds" - len0=$func_len_result - len=$len0 - for obj in $save_oldobjs - do - func_len " $obj" - func_arith $len + $func_len_result - len=$func_arith_result - func_append objlist " $obj" - if test "$len" -lt "$max_cmd_len"; then - : - else - # the above command should be used before it gets too long - oldobjs=$objlist - if test "$obj" = "$last_oldobj" ; then - RANLIB=$save_RANLIB - fi - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" - objlist= - len=$len0 - fi - done - RANLIB=$save_RANLIB - oldobjs=$objlist - if test "X$oldobjs" = "X" ; then - eval cmds=\"\$concat_cmds\" - else - eval cmds=\"\$concat_cmds~\$old_archive_cmds\" - fi - fi - fi - func_execute_cmds "$cmds" 'exit $?' - done - - test -n "$generated" && \ - func_show_eval "${RM}r$generated" - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" - func_verbose "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - if test "$hardcode_automatic" = yes ; then - relink_command= - fi - - # Only create the output if not a dry run. - $opt_dry_run || { - for installed in no yes; do - if test "$installed" = yes; then - if test -z "$install_libdir"; then - break - fi - output="$output_objdir/$outputname"i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - func_basename "$deplib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" - func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" - ;; - -L*) - func_stripname -L '' "$deplib" - func_replace_sysroot "$func_stripname_result" - func_append newdependency_libs " -L$func_replace_sysroot_result" - ;; - -R*) - func_stripname -R '' "$deplib" - func_replace_sysroot "$func_stripname_result" - func_append newdependency_libs " -R$func_replace_sysroot_result" - ;; - *) func_append newdependency_libs " $deplib" ;; - esac - done - dependency_libs="$newdependency_libs" - newdlfiles= - - for lib in $dlfiles; do - case $lib in - *.la) - func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" - func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" - ;; - *) func_append newdlfiles " $lib" ;; - esac - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - *.la) - # Only pass preopened files to the pseudo-archive (for - # eventual linking with the app. that links it) if we - # didn't already link the preopened objects directly into - # the library: - func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" - func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" - ;; - esac - done - dlprefiles="$newdlprefiles" - else - newdlfiles= - for lib in $dlfiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - func_append newdlfiles " $abs" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - func_append newdlprefiles " $abs" - done - dlprefiles="$newdlprefiles" - fi - $RM $output - # place dlname in correct position for cygwin - # In fact, it would be nice if we could use this code for all target - # systems that can't hard-code library paths into their executables - # and that have no shared library path variable independent of PATH, - # but it turns out we can't easily determine that from inspecting - # libtool variables, so we have to hard-code the OSs to which it - # applies here; at the moment, that means platforms that use the PE - # object format with DLL files. See the long comment at the top of - # tests/bindir.at for full details. - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) - # If a -bindir argument was supplied, place the dll there. - if test "x$bindir" != x ; - then - func_relative_path "$install_libdir" "$bindir" - tdlname=$func_relative_path_result$dlname - else - # Otherwise fall back on heuristic. - tdlname=../bin/$dlname - fi - ;; - esac - $ECHO > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Linker flags that can not go in dependency_libs. -inherited_linker_flags='$new_inherited_linker_flags' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Names of additional weak libraries provided by this library -weak_library_names='$weak_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Should we warn about portability when linking against -modules? -shouldnotlink=$module - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test "$installed" = no && test "$need_relink" = yes; then - $ECHO >> $output "\ -relink_command=\"$relink_command\"" - fi - done - } - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' - ;; - esac - exit $EXIT_SUCCESS -} - -{ test "$opt_mode" = link || test "$opt_mode" = relink; } && - func_mode_link ${1+"$@"} - - -# func_mode_uninstall arg... -func_mode_uninstall () -{ - $opt_debug - RM="$nonopt" - files= - rmforce= - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - for arg - do - case $arg in - -f) func_append RM " $arg"; rmforce=yes ;; - -*) func_append RM " $arg" ;; - *) func_append files " $arg" ;; - esac - done - - test -z "$RM" && \ - func_fatal_help "you must specify an RM program" - - rmdirs= - - for file in $files; do - func_dirname "$file" "" "." - dir="$func_dirname_result" - if test "X$dir" = X.; then - odir="$objdir" - else - odir="$dir/$objdir" - fi - func_basename "$file" - name="$func_basename_result" - test "$opt_mode" = uninstall && odir="$dir" - - # Remember odir for removal later, being careful to avoid duplicates - if test "$opt_mode" = clean; then - case " $rmdirs " in - *" $odir "*) ;; - *) func_append rmdirs " $odir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if { test -L "$file"; } >/dev/null 2>&1 || - { test -h "$file"; } >/dev/null 2>&1 || - test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif test "$rmforce" = yes; then - continue - fi - - rmfiles="$file" - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if func_lalib_p "$file"; then - func_source $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - func_append rmfiles " $odir/$n" - done - test -n "$old_library" && func_append rmfiles " $odir/$old_library" - - case "$opt_mode" in - clean) - case " $library_names " in - *" $dlname "*) ;; - *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; - esac - test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" - ;; - uninstall) - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' - fi - # FIXME: should reinstall the best remaining shared library. - ;; - esac - fi - ;; - - *.lo) - # Possibly a libtool object, so verify it. - if func_lalib_p "$file"; then - - # Read the .lo file - func_source $dir/$name - - # Add PIC object to the list of files to remove. - if test -n "$pic_object" && - test "$pic_object" != none; then - func_append rmfiles " $dir/$pic_object" - fi - - # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" && - test "$non_pic_object" != none; then - func_append rmfiles " $dir/$non_pic_object" - fi - fi - ;; - - *) - if test "$opt_mode" = clean ; then - noexename=$name - case $file in - *.exe) - func_stripname '' '.exe' "$file" - file=$func_stripname_result - func_stripname '' '.exe' "$name" - noexename=$func_stripname_result - # $file with .exe has already been added to rmfiles, - # add $file without .exe - func_append rmfiles " $file" - ;; - esac - # Do a test to see if this is a libtool program. - if func_ltwrapper_p "$file"; then - if func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - relink_command= - func_source $func_ltwrapper_scriptname_result - func_append rmfiles " $func_ltwrapper_scriptname_result" - else - relink_command= - func_source $dir/$noexename - fi - - # note $name still contains .exe if it was in $file originally - # as does the version of $file that was added into $rmfiles - func_append rmfiles " $odir/$name $odir/${name}S.${objext}" - func_append rmfiles " ${name}.manifest $objdir/${name}.manifest" - if test "$fast_install" = yes && test -n "$relink_command"; then - func_append rmfiles " $odir/lt-$name $objdir/lt-${name}.manifest" - fi - if test "X$noexename" != "X$name" ; then - func_append rmfiles " $odir/lt-${noexename}.c" - fi - fi - fi - ;; - esac - func_show_eval "$RM $rmfiles" 'exit_status=1' - done - - # Try to remove the ${objdir}s in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - func_show_eval "rmdir $dir >/dev/null 2>&1" - fi - done - - exit $exit_status -} - -{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && - func_mode_uninstall ${1+"$@"} - -test -z "$opt_mode" && { - help="$generic_help" - func_fatal_help "you must specify a MODE" -} - -test -z "$exec_cmd" && \ - func_fatal_help "invalid operation mode \`$opt_mode'" - -if test -n "$exec_cmd"; then - eval exec "$exec_cmd" - exit $EXIT_FAILURE -fi - -exit $exit_status - - -# The TAGs below are defined such that we never get into a situation -# in which we disable both kinds of libraries. Given conflicting -# choices, we go for a static library, that is the most portable, -# since we can't tell whether shared libraries were disabled because -# the user asked for that or because the platform doesn't support -# them. This is particularly important on AIX, because we don't -# support having both static and shared libraries enabled at the same -# time on that platform, so we default to a shared-only configuration. -# If a disable-shared tag is given, we'll fallback to a static-only -# configuration. But we'll never go from static-only to shared-only. - -# ### BEGIN LIBTOOL TAG CONFIG: disable-shared -build_libtool_libs=no -build_old_libs=yes -# ### END LIBTOOL TAG CONFIG: disable-shared - -# ### BEGIN LIBTOOL TAG CONFIG: disable-static -build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` -# ### END LIBTOOL TAG CONFIG: disable-static - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: -# vi:sw=2 - diff --git a/resources/3rdparty/glpk-4.53/m4/libtool.m4 b/resources/3rdparty/glpk-4.53/m4/libtool.m4 deleted file mode 100644 index 6aebb63b5..000000000 --- a/resources/3rdparty/glpk-4.53/m4/libtool.m4 +++ /dev/null @@ -1,7831 +0,0 @@ -# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, -# Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -m4_define([_LT_COPYING], [dnl -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, -# Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -]) - -# serial 57 LT_INIT - - -# LT_PREREQ(VERSION) -# ------------------ -# Complain and exit if this libtool version is less that VERSION. -m4_defun([LT_PREREQ], -[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, - [m4_default([$3], - [m4_fatal([Libtool version $1 or higher is required], - 63)])], - [$2])]) - - -# _LT_CHECK_BUILDDIR -# ------------------ -# Complain if the absolute build directory name contains unusual characters -m4_defun([_LT_CHECK_BUILDDIR], -[case `pwd` in - *\ * | *\ *) - AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; -esac -]) - - -# LT_INIT([OPTIONS]) -# ------------------ -AC_DEFUN([LT_INIT], -[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT -AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -AC_BEFORE([$0], [LT_LANG])dnl -AC_BEFORE([$0], [LT_OUTPUT])dnl -AC_BEFORE([$0], [LTDL_INIT])dnl -m4_require([_LT_CHECK_BUILDDIR])dnl - -dnl Autoconf doesn't catch unexpanded LT_ macros by default: -m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl -m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl -dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 -dnl unless we require an AC_DEFUNed macro: -AC_REQUIRE([LTOPTIONS_VERSION])dnl -AC_REQUIRE([LTSUGAR_VERSION])dnl -AC_REQUIRE([LTVERSION_VERSION])dnl -AC_REQUIRE([LTOBSOLETE_VERSION])dnl -m4_require([_LT_PROG_LTMAIN])dnl - -_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) - -dnl Parse OPTIONS -_LT_SET_OPTIONS([$0], [$1]) - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -_LT_SETUP - -# Only expand once: -m4_define([LT_INIT]) -])# LT_INIT - -# Old names: -AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) -AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PROG_LIBTOOL], []) -dnl AC_DEFUN([AM_PROG_LIBTOOL], []) - - -# _LT_CC_BASENAME(CC) -# ------------------- -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -m4_defun([_LT_CC_BASENAME], -[for cc_temp in $1""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` -]) - - -# _LT_FILEUTILS_DEFAULTS -# ---------------------- -# It is okay to use these file commands and assume they have been set -# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. -m4_defun([_LT_FILEUTILS_DEFAULTS], -[: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} -])# _LT_FILEUTILS_DEFAULTS - - -# _LT_SETUP -# --------- -m4_defun([_LT_SETUP], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl - -_LT_DECL([], [host_alias], [0], [The host system])dnl -_LT_DECL([], [host], [0])dnl -_LT_DECL([], [host_os], [0])dnl -dnl -_LT_DECL([], [build_alias], [0], [The build system])dnl -_LT_DECL([], [build], [0])dnl -_LT_DECL([], [build_os], [0])dnl -dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -dnl -AC_REQUIRE([AC_PROG_LN_S])dnl -test -z "$LN_S" && LN_S="ln -s" -_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl -dnl -AC_REQUIRE([LT_CMD_MAX_LEN])dnl -_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl -_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl -dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl -m4_require([_LT_CMD_RELOAD])dnl -m4_require([_LT_CHECK_MAGIC_METHOD])dnl -m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl -m4_require([_LT_CMD_OLD_ARCHIVE])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_WITH_SYSROOT])dnl - -_LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi -]) -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -_LT_CHECK_OBJDIR - -m4_require([_LT_TAG_COMPILER])dnl - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -_LT_CC_BASENAME([$compiler]) - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - _LT_PATH_MAGIC - fi - ;; -esac - -# Use C for the default configuration in the libtool script -LT_SUPPORTED_TAG([CC]) -_LT_LANG_C_CONFIG -_LT_LANG_DEFAULT_CONFIG -_LT_CONFIG_COMMANDS -])# _LT_SETUP - - -# _LT_PREPARE_SED_QUOTE_VARS -# -------------------------- -# Define a few sed substitution that help us do robust quoting. -m4_defun([_LT_PREPARE_SED_QUOTE_VARS], -[# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([["`\\]]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' -]) - -# _LT_PROG_LTMAIN -# --------------- -# Note that this code is called both from `configure', and `config.status' -# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# `config.status' has no value for ac_aux_dir unless we are using Automake, -# so we pass a copy along to make sure it has a sensible value anyway. -m4_defun([_LT_PROG_LTMAIN], -[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl -_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain="$ac_aux_dir/ltmain.sh" -])# _LT_PROG_LTMAIN - - -## ------------------------------------- ## -## Accumulate code for creating libtool. ## -## ------------------------------------- ## - -# So that we can recreate a full libtool script including additional -# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the `libtool' -# label. - - -# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) -# ---------------------------------------- -# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL_INIT], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_INIT], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_INIT]) - - -# _LT_CONFIG_LIBTOOL([COMMANDS]) -# ------------------------------ -# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) - - -# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) -# ----------------------------------------------------- -m4_defun([_LT_CONFIG_SAVE_COMMANDS], -[_LT_CONFIG_LIBTOOL([$1]) -_LT_CONFIG_LIBTOOL_INIT([$2]) -]) - - -# _LT_FORMAT_COMMENT([COMMENT]) -# ----------------------------- -# Add leading comment marks to the start of each line, and a trailing -# full-stop to the whole comment if one is not present already. -m4_define([_LT_FORMAT_COMMENT], -[m4_ifval([$1], [ -m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], - [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) -)]) - - - -## ------------------------ ## -## FIXME: Eliminate VARNAME ## -## ------------------------ ## - - -# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) -# ------------------------------------------------------------------- -# CONFIGNAME is the name given to the value in the libtool script. -# VARNAME is the (base) name used in the configure script. -# VALUE may be 0, 1 or 2 for a computed quote escaped value based on -# VARNAME. Any other value will be used directly. -m4_define([_LT_DECL], -[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], - [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], - [m4_ifval([$1], [$1], [$2])]) - lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) - m4_ifval([$4], - [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) - lt_dict_add_subkey([lt_decl_dict], [$2], - [tagged?], [m4_ifval([$5], [yes], [no])])]) -]) - - -# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) -# -------------------------------------------------------- -m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) - - -# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_tag_varnames], -[_lt_decl_filter([tagged?], [yes], $@)]) - - -# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) -# --------------------------------------------------------- -m4_define([_lt_decl_filter], -[m4_case([$#], - [0], [m4_fatal([$0: too few arguments: $#])], - [1], [m4_fatal([$0: too few arguments: $#: $1])], - [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], - [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], - [lt_dict_filter([lt_decl_dict], $@)])[]dnl -]) - - -# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) -# -------------------------------------------------- -m4_define([lt_decl_quote_varnames], -[_lt_decl_filter([value], [1], $@)]) - - -# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_dquote_varnames], -[_lt_decl_filter([value], [2], $@)]) - - -# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_varnames_tagged], -[m4_assert([$# <= 2])dnl -_$0(m4_quote(m4_default([$1], [[, ]])), - m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), - m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) -m4_define([_lt_decl_varnames_tagged], -[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) - - -# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_all_varnames], -[_$0(m4_quote(m4_default([$1], [[, ]])), - m4_if([$2], [], - m4_quote(lt_decl_varnames), - m4_quote(m4_shift($@))))[]dnl -]) -m4_define([_lt_decl_all_varnames], -[lt_join($@, lt_decl_varnames_tagged([$1], - lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl -]) - - -# _LT_CONFIG_STATUS_DECLARE([VARNAME]) -# ------------------------------------ -# Quote a variable value, and forward it to `config.status' so that its -# declaration there will have the same value as in `configure'. VARNAME -# must have a single quote delimited value for this to work. -m4_define([_LT_CONFIG_STATUS_DECLARE], -[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) - - -# _LT_CONFIG_STATUS_DECLARATIONS -# ------------------------------ -# We delimit libtool config variables with single quotes, so when -# we write them to config.status, we have to be sure to quote all -# embedded single quotes properly. In configure, this macro expands -# each variable declared with _LT_DECL (and _LT_TAGDECL) into: -# -# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' -m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], -[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), - [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAGS -# ---------------- -# Output comment and list of tags supported by the script -m4_defun([_LT_LIBTOOL_TAGS], -[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags="_LT_TAGS"dnl -]) - - -# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) -# ----------------------------------- -# Extract the dictionary values for VARNAME (optionally with TAG) and -# expand to a commented shell variable setting: -# -# # Some comment about what VAR is for. -# visible_name=$lt_internal_name -m4_define([_LT_LIBTOOL_DECLARE], -[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], - [description])))[]dnl -m4_pushdef([_libtool_name], - m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl -m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), - [0], [_libtool_name=[$]$1], - [1], [_libtool_name=$lt_[]$1], - [2], [_libtool_name=$lt_[]$1], - [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl -m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl -]) - - -# _LT_LIBTOOL_CONFIG_VARS -# ----------------------- -# Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' -# script. Tagged libtool config variables (even for the LIBTOOL CONFIG -# section) are produced by _LT_LIBTOOL_TAG_VARS. -m4_defun([_LT_LIBTOOL_CONFIG_VARS], -[m4_foreach([_lt_var], - m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAG_VARS(TAG) -# ------------------------- -m4_define([_LT_LIBTOOL_TAG_VARS], -[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) - - -# _LT_TAGVAR(VARNAME, [TAGNAME]) -# ------------------------------ -m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) - - -# _LT_CONFIG_COMMANDS -# ------------------- -# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of -# variables for single and double quote escaping we saved from calls -# to _LT_DECL, we can put quote escaped variables declarations -# into `config.status', and then the shell code to quote escape them in -# for loops in `config.status'. Finally, any additional code accumulated -# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. -m4_defun([_LT_CONFIG_COMMANDS], -[AC_PROVIDE_IFELSE([LT_OUTPUT], - dnl If the libtool generation code has been placed in $CONFIG_LT, - dnl instead of duplicating it all over again into config.status, - dnl then we will have config.status run $CONFIG_LT later, so it - dnl needs to know what name is stored there: - [AC_CONFIG_COMMANDS([libtool], - [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], - dnl If the libtool generation code is destined for config.status, - dnl expand the accumulated commands and init code now: - [AC_CONFIG_COMMANDS([libtool], - [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) -])#_LT_CONFIG_COMMANDS - - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], -[ - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -_LT_CONFIG_STATUS_DECLARATIONS -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$[]1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_quote_varnames); do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_dquote_varnames); do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -_LT_OUTPUT_LIBTOOL_INIT -]) - -# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) -# ------------------------------------ -# Generate a child script FILE with all initialization necessary to -# reuse the environment learned by the parent script, and make the -# file executable. If COMMENT is supplied, it is inserted after the -# `#!' sequence but before initialization text begins. After this -# macro, additional text can be appended to FILE to form the body of -# the child script. The macro ends with non-zero status if the -# file could not be fully written (such as if the disk is full). -m4_ifdef([AS_INIT_GENERATED], -[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], -[m4_defun([_LT_GENERATED_FILE_INIT], -[m4_require([AS_PREPARE])]dnl -[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl -[lt_write_fail=0 -cat >$1 <<_ASEOF || lt_write_fail=1 -#! $SHELL -# Generated by $as_me. -$2 -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$1 <<\_ASEOF || lt_write_fail=1 -AS_SHELL_SANITIZE -_AS_PREPARE -exec AS_MESSAGE_FD>&1 -_ASEOF -test $lt_write_fail = 0 && chmod +x $1[]dnl -m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT - -# LT_OUTPUT -# --------- -# This macro allows early generation of the libtool script (before -# AC_OUTPUT is called), incase it is used in configure for compilation -# tests. -AC_DEFUN([LT_OUTPUT], -[: ${CONFIG_LT=./config.lt} -AC_MSG_NOTICE([creating $CONFIG_LT]) -_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], -[# Run this file to recreate a libtool stub with the current configuration.]) - -cat >>"$CONFIG_LT" <<\_LTEOF -lt_cl_silent=false -exec AS_MESSAGE_LOG_FD>>config.log -{ - echo - AS_BOX([Running $as_me.]) -} >&AS_MESSAGE_LOG_FD - -lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, -for use in further configure time tests before the real libtool is -generated. - -Usage: $[0] [[OPTIONS]] - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - -Report bugs to ." - -lt_cl_version="\ -m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl -m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) -configured by $[0], generated by m4_PACKAGE_STRING. - -Copyright (C) 2010 Free Software Foundation, Inc. -This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." - -while test $[#] != 0 -do - case $[1] in - --version | --v* | -V ) - echo "$lt_cl_version"; exit 0 ;; - --help | --h* | -h ) - echo "$lt_cl_help"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --quiet | --q* | --silent | --s* | -q ) - lt_cl_silent=: ;; - - -*) AC_MSG_ERROR([unrecognized option: $[1] -Try \`$[0] --help' for more information.]) ;; - - *) AC_MSG_ERROR([unrecognized argument: $[1] -Try \`$[0] --help' for more information.]) ;; - esac - shift -done - -if $lt_cl_silent; then - exec AS_MESSAGE_FD>/dev/null -fi -_LTEOF - -cat >>"$CONFIG_LT" <<_LTEOF -_LT_OUTPUT_LIBTOOL_COMMANDS_INIT -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AC_MSG_NOTICE([creating $ofile]) -_LT_OUTPUT_LIBTOOL_COMMANDS -AS_EXIT(0) -_LTEOF -chmod +x "$CONFIG_LT" - -# configure is writing to config.log, but config.lt does its own redirection, -# appending to config.log, which fails on DOS, as config.log is still kept -# open by configure. Here we exec the FD to /dev/null, effectively closing -# config.log, so it can be properly (re)opened and appended to by config.lt. -lt_cl_success=: -test "$silent" = yes && - lt_config_lt_args="$lt_config_lt_args --quiet" -exec AS_MESSAGE_LOG_FD>/dev/null -$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false -exec AS_MESSAGE_LOG_FD>>config.log -$lt_cl_success || AS_EXIT(1) -])# LT_OUTPUT - - -# _LT_CONFIG(TAG) -# --------------- -# If TAG is the built-in tag, create an initial libtool script with a -# default configuration from the untagged config vars. Otherwise add code -# to config.status for appending the configuration named by TAG from the -# matching tagged config vars. -m4_defun([_LT_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_CONFIG_SAVE_COMMANDS([ - m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl - m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -_LT_COPYING -_LT_LIBTOOL_TAGS - -# ### BEGIN LIBTOOL CONFIG -_LT_LIBTOOL_CONFIG_VARS -_LT_LIBTOOL_TAG_VARS -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - _LT_PROG_LTMAIN - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - _LT_PROG_REPLACE_SHELLFNS - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" -], -[cat <<_LT_EOF >> "$ofile" - -dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded -dnl in a comment (ie after a #). -# ### BEGIN LIBTOOL TAG CONFIG: $1 -_LT_LIBTOOL_TAG_VARS(_LT_TAG) -# ### END LIBTOOL TAG CONFIG: $1 -_LT_EOF -])dnl /m4_if -], -[m4_if([$1], [], [ - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile'], []) -])dnl /_LT_CONFIG_SAVE_COMMANDS -])# _LT_CONFIG - - -# LT_SUPPORTED_TAG(TAG) -# --------------------- -# Trace this macro to discover what tags are supported by the libtool -# --tag option, using: -# autoconf --trace 'LT_SUPPORTED_TAG:$1' -AC_DEFUN([LT_SUPPORTED_TAG], []) - - -# C support is built-in for now -m4_define([_LT_LANG_C_enabled], []) -m4_define([_LT_TAGS], []) - - -# LT_LANG(LANG) -# ------------- -# Enable libtool support for the given language if not already enabled. -AC_DEFUN([LT_LANG], -[AC_BEFORE([$0], [LT_OUTPUT])dnl -m4_case([$1], - [C], [_LT_LANG(C)], - [C++], [_LT_LANG(CXX)], - [Java], [_LT_LANG(GCJ)], - [Fortran 77], [_LT_LANG(F77)], - [Fortran], [_LT_LANG(FC)], - [Windows Resource], [_LT_LANG(RC)], - [m4_ifdef([_LT_LANG_]$1[_CONFIG], - [_LT_LANG($1)], - [m4_fatal([$0: unsupported language: "$1"])])])dnl -])# LT_LANG - - -# _LT_LANG(LANGNAME) -# ------------------ -m4_defun([_LT_LANG], -[m4_ifdef([_LT_LANG_]$1[_enabled], [], - [LT_SUPPORTED_TAG([$1])dnl - m4_append([_LT_TAGS], [$1 ])dnl - m4_define([_LT_LANG_]$1[_enabled], [])dnl - _LT_LANG_$1_CONFIG($1)])dnl -])# _LT_LANG - - -# _LT_LANG_DEFAULT_CONFIG -# ----------------------- -m4_defun([_LT_LANG_DEFAULT_CONFIG], -[AC_PROVIDE_IFELSE([AC_PROG_CXX], - [LT_LANG(CXX)], - [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) - -AC_PROVIDE_IFELSE([AC_PROG_F77], - [LT_LANG(F77)], - [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) - -AC_PROVIDE_IFELSE([AC_PROG_FC], - [LT_LANG(FC)], - [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) - -dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal -dnl pulling things in needlessly. -AC_PROVIDE_IFELSE([AC_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([LT_PROG_GCJ], - [LT_LANG(GCJ)], - [m4_ifdef([AC_PROG_GCJ], - [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([A][M_PROG_GCJ], - [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([LT_PROG_GCJ], - [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) - -AC_PROVIDE_IFELSE([LT_PROG_RC], - [LT_LANG(RC)], - [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) -])# _LT_LANG_DEFAULT_CONFIG - -# Obsolete macros: -AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) -AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) -AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) -AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) -AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_CXX], []) -dnl AC_DEFUN([AC_LIBTOOL_F77], []) -dnl AC_DEFUN([AC_LIBTOOL_FC], []) -dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) -dnl AC_DEFUN([AC_LIBTOOL_RC], []) - - -# _LT_TAG_COMPILER -# ---------------- -m4_defun([_LT_TAG_COMPILER], -[AC_REQUIRE([AC_PROG_CC])dnl - -_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl -_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl -_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl -_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC -])# _LT_TAG_COMPILER - - -# _LT_COMPILER_BOILERPLATE -# ------------------------ -# Check for compiler boilerplate output or warnings with -# the simple compiler test code. -m4_defun([_LT_COMPILER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* -])# _LT_COMPILER_BOILERPLATE - - -# _LT_LINKER_BOILERPLATE -# ---------------------- -# Check for linker boilerplate output or warnings with -# the simple link test code. -m4_defun([_LT_LINKER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* -])# _LT_LINKER_BOILERPLATE - -# _LT_REQUIRED_DARWIN_CHECKS -# ------------------------- -m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ - case $host_os in - rhapsody* | darwin*) - AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) - AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) - AC_CHECK_TOOL([LIPO], [lipo], [:]) - AC_CHECK_TOOL([OTOOL], [otool], [:]) - AC_CHECK_TOOL([OTOOL64], [otool64], [:]) - _LT_DECL([], [DSYMUTIL], [1], - [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) - _LT_DECL([], [NMEDIT], [1], - [Tool to change global to local symbols on Mac OS X]) - _LT_DECL([], [LIPO], [1], - [Tool to manipulate fat objects and archives on Mac OS X]) - _LT_DECL([], [OTOOL], [1], - [ldd/readelf like tool for Mach-O binaries on Mac OS X]) - _LT_DECL([], [OTOOL64], [1], - [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) - - AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], - [lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi]) - AC_CACHE_CHECK([for -exported_symbols_list linker flag], - [lt_cv_ld_exported_symbols_list], - [lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [lt_cv_ld_exported_symbols_list=yes], - [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS="$save_LDFLAGS" - ]) - AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], - [lt_cv_ld_force_load=no - cat > conftest.c << _LT_EOF -int forced_loaded() { return 2;} -_LT_EOF - echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD - echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD - $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD - echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD - $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD - cat > conftest.c << _LT_EOF -int main() { return 0;} -_LT_EOF - echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err - _lt_result=$? - if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then - lt_cv_ld_force_load=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -f conftest.err libconftest.a conftest conftest.c - rm -rf conftest.dSYM - ]) - case $host_os in - rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[[012]]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac -]) - - -# _LT_DARWIN_LINKER_FEATURES -# -------------------------- -# Checks for linker and compiler features on darwin -m4_defun([_LT_DARWIN_LINKER_FEATURES], -[ - m4_require([_LT_REQUIRED_DARWIN_CHECKS]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_automatic, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='' - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - m4_if([$1], [CXX], -[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi -],[]) - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi -]) - -# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) -# ---------------------------------- -# Links a minimal program and checks the executable -# for the system default hardcoded library path. In most cases, -# this is /usr/lib:/lib, but when the MPI compilers are used -# the location of the communication and MPI libs are included too. -# If we don't find anything, use the default library path according -# to the aix ld manual. -# Store the results from the different compilers for each TAGNAME. -# Allow to override them for all tags through lt_cv_aix_libpath. -m4_defun([_LT_SYS_MODULE_PATH_AIX], -[m4_require([_LT_DECL_SED])dnl -if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], - [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ - lt_aix_libpath_sed='[ - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }]' - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi],[]) - if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" - fi - ]) - aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) -fi -])# _LT_SYS_MODULE_PATH_AIX - - -# _LT_SHELL_INIT(ARG) -# ------------------- -m4_define([_LT_SHELL_INIT], -[m4_divert_text([M4SH-INIT], [$1 -])])# _LT_SHELL_INIT - - - -# _LT_PROG_ECHO_BACKSLASH -# ----------------------- -# Find how we can fake an echo command that does not interpret backslash. -# In particular, with Autoconf 2.60 or later we add some code to the start -# of the generated configure script which will find a shell with a builtin -# printf (which we can use as an echo command). -m4_defun([_LT_PROG_ECHO_BACKSLASH], -[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -AC_MSG_CHECKING([how to print strings]) -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$[]1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} - -case "$ECHO" in - printf*) AC_MSG_RESULT([printf]) ;; - print*) AC_MSG_RESULT([print -r]) ;; - *) AC_MSG_RESULT([cat]) ;; -esac - -m4_ifdef([_AS_DETECT_SUGGESTED], -[_AS_DETECT_SUGGESTED([ - test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( - ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' - ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO - ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - PATH=/empty FPATH=/empty; export PATH FPATH - test "X`printf %s $ECHO`" = "X$ECHO" \ - || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) - -_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) -_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) -])# _LT_PROG_ECHO_BACKSLASH - - -# _LT_WITH_SYSROOT -# ---------------- -AC_DEFUN([_LT_WITH_SYSROOT], -[AC_MSG_CHECKING([for sysroot]) -AC_ARG_WITH([sysroot], -[ --with-sysroot[=DIR] Search for dependent libraries within DIR - (or the compiler's sysroot if not specified).], -[], [with_sysroot=no]) - -dnl lt_sysroot will always be passed unquoted. We quote it here -dnl in case the user passed a directory name. -lt_sysroot= -case ${with_sysroot} in #( - yes) - if test "$GCC" = yes; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` - fi - ;; #( - /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` - ;; #( - no|'') - ;; #( - *) - AC_MSG_RESULT([${with_sysroot}]) - AC_MSG_ERROR([The sysroot must be an absolute path.]) - ;; -esac - - AC_MSG_RESULT([${lt_sysroot:-no}]) -_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl -[dependent libraries, and in which our libraries should be installed.])]) - -# _LT_ENABLE_LOCK -# --------------- -m4_defun([_LT_ENABLE_LOCK], -[AC_ARG_ENABLE([libtool-lock], - [AS_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_PUSH(C) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -sparc*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) LD="${LD-ld} -m elf64_sparc" ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" -])# _LT_ENABLE_LOCK - - -# _LT_PROG_AR -# ----------- -m4_defun([_LT_PROG_AR], -[AC_CHECK_TOOLS(AR, [ar], false) -: ${AR=ar} -: ${AR_FLAGS=cru} -_LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) - -AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], - [lt_cv_ar_at_file=no - AC_COMPILE_IFELSE([AC_LANG_PROGRAM], - [echo conftest.$ac_objext > conftest.lst - lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' - AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -eq 0; then - # Ensure the archiver fails upon bogus file names. - rm -f conftest.$ac_objext libconftest.a - AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -ne 0; then - lt_cv_ar_at_file=@ - fi - fi - rm -f conftest.* libconftest.a - ]) - ]) - -if test "x$lt_cv_ar_at_file" = xno; then - archiver_list_spec= -else - archiver_list_spec=$lt_cv_ar_at_file -fi -_LT_DECL([], [archiver_list_spec], [1], - [How to feed a file listing to the archiver]) -])# _LT_PROG_AR - - -# _LT_CMD_OLD_ARCHIVE -# ------------------- -m4_defun([_LT_CMD_OLD_ARCHIVE], -[_LT_PROG_AR - -AC_CHECK_TOOL(STRIP, strip, :) -test -z "$STRIP" && STRIP=: -_LT_DECL([], [STRIP], [1], [A symbol stripping program]) - -AC_CHECK_TOOL(RANLIB, ranlib, :) -test -z "$RANLIB" && RANLIB=: -_LT_DECL([], [RANLIB], [1], - [Commands used to install an old-style archive]) - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi - -case $host_os in - darwin*) - lock_old_archive_extraction=yes ;; - *) - lock_old_archive_extraction=no ;; -esac -_LT_DECL([], [old_postinstall_cmds], [2]) -_LT_DECL([], [old_postuninstall_cmds], [2]) -_LT_TAGDECL([], [old_archive_cmds], [2], - [Commands used to build an old-style archive]) -_LT_DECL([], [lock_old_archive_extraction], [0], - [Whether to use a lock for old archive extraction]) -])# _LT_CMD_OLD_ARCHIVE - - -# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------------------- -# Check whether the given compiler option works -AC_DEFUN([_LT_COMPILER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - fi - $RM conftest* -]) - -if test x"[$]$2" = xyes; then - m4_if([$5], , :, [$5]) -else - m4_if([$6], , :, [$6]) -fi -])# _LT_COMPILER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) - - -# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------- -# Check whether the given linker option works -AC_DEFUN([_LT_LINKER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $3" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&AS_MESSAGE_LOG_FD - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - else - $2=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" -]) - -if test x"[$]$2" = xyes; then - m4_if([$4], , :, [$4]) -else - m4_if([$5], , :, [$5]) -fi -])# _LT_LINKER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) - - -# LT_CMD_MAX_LEN -#--------------- -AC_DEFUN([LT_CMD_MAX_LEN], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -# find the maximum length of command line arguments -AC_MSG_CHECKING([the maximum length of command line arguments]) -AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - mint*) - # On MiNT this can take a long time and run out of memory. - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ - = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac -]) -if test -n $lt_cv_sys_max_cmd_len ; then - AC_MSG_RESULT($lt_cv_sys_max_cmd_len) -else - AC_MSG_RESULT(none) -fi -max_cmd_len=$lt_cv_sys_max_cmd_len -_LT_DECL([], [max_cmd_len], [0], - [What is the maximum length of a command?]) -])# LT_CMD_MAX_LEN - -# Old name: -AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) - - -# _LT_HEADER_DLFCN -# ---------------- -m4_defun([_LT_HEADER_DLFCN], -[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl -])# _LT_HEADER_DLFCN - - -# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ---------------------------------------------------------------- -m4_defun([_LT_TRY_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "$cross_compiling" = yes; then : - [$4] -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -[#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisbility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -}] -_LT_EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_dlunknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_TRY_DLOPEN_SELF - - -# LT_SYS_DLOPEN_SELF -# ------------------ -AC_DEFUN([LT_SYS_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ]) - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -_LT_DECL([dlopen_support], [enable_dlopen], [0], - [Whether dlopen is supported]) -_LT_DECL([dlopen_self], [enable_dlopen_self], [0], - [Whether dlopen of programs is supported]) -_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], - [Whether dlopen of statically linked programs is supported]) -])# LT_SYS_DLOPEN_SELF - -# Old name: -AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) - - -# _LT_COMPILER_C_O([TAGNAME]) -# --------------------------- -# Check to see if options -c and -o are simultaneously supported by compiler. -# This macro does not hard code the compiler like AC_PROG_CC_C_O. -m4_defun([_LT_COMPILER_C_O], -[m4_require([_LT_DECL_SED])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - fi - fi - chmod u+w . 2>&AS_MESSAGE_LOG_FD - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* -]) -_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], - [Does compiler simultaneously support -c and -o options?]) -])# _LT_COMPILER_C_O - - -# _LT_COMPILER_FILE_LOCKS([TAGNAME]) -# ---------------------------------- -# Check to see if we can do hard links to lock some files if needed -m4_defun([_LT_COMPILER_FILE_LOCKS], -[m4_require([_LT_ENABLE_LOCK])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_COMPILER_C_O([$1]) - -hard_links="nottested" -if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi -_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) -])# _LT_COMPILER_FILE_LOCKS - - -# _LT_CHECK_OBJDIR -# ---------------- -m4_defun([_LT_CHECK_OBJDIR], -[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], -[rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null]) -objdir=$lt_cv_objdir -_LT_DECL([], [objdir], [0], - [The name of the directory that contains temporary libtool files])dnl -m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", - [Define to the sub-directory in which libtool stores uninstalled libraries.]) -])# _LT_CHECK_OBJDIR - - -# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) -# -------------------------------------- -# Check hardcoding attributes. -m4_defun([_LT_LINKER_HARDCODE_LIBPATH], -[AC_MSG_CHECKING([how to hardcode library paths into programs]) -_LT_TAGVAR(hardcode_action, $1)= -if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || - test -n "$_LT_TAGVAR(runpath_var, $1)" || - test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then - # Linking always hardcodes the temporary library directory. - _LT_TAGVAR(hardcode_action, $1)=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - _LT_TAGVAR(hardcode_action, $1)=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - _LT_TAGVAR(hardcode_action, $1)=unsupported -fi -AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) - -if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || - test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi -_LT_TAGDECL([], [hardcode_action], [0], - [How to hardcode a shared library path into an executable]) -])# _LT_LINKER_HARDCODE_LIBPATH - - -# _LT_CMD_STRIPLIB -# ---------------- -m4_defun([_LT_CMD_STRIPLIB], -[m4_require([_LT_DECL_EGREP]) -striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac -fi -_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) -_LT_DECL([], [striplib], [1]) -])# _LT_CMD_STRIPLIB - - -# _LT_SYS_DYNAMIC_LINKER([TAG]) -# ----------------------------- -# PORTME Fill in your ld.so characteristics -m4_defun([_LT_SYS_DYNAMIC_LINKER], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_OBJDUMP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -AC_MSG_CHECKING([dynamic linker characteristics]) -m4_if([$1], - [], [ -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` - case $lt_search_path_spec in - *\;*) - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` - ;; - *) - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` - ;; - esac - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[[lt_foo]]++; } - if (lt_freq[[lt_foo]] == 1) { print lt_foo; } -}'` - # AWK program above erroneously prepends '/' to C:/dos/paths - # for these hosts. - case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; - esac - sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[[4-9]]*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[[45]]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec="$LIB" - if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[[123]]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[[01]]* | freebsdelf3.[[01]]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ - freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -haiku*) - version_type=linux - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[[3-9]]*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], - [lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ - LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], - [lt_cv_shlibpath_overrides_runpath=yes])]) - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - ]) - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - -_LT_DECL([], [variables_saved_for_relink], [1], - [Variables whose values should be saved in libtool wrapper scripts and - restored at link time]) -_LT_DECL([], [need_lib_prefix], [0], - [Do we need the "lib" prefix for modules?]) -_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) -_LT_DECL([], [version_type], [0], [Library versioning type]) -_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) -_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) -_LT_DECL([], [shlibpath_overrides_runpath], [0], - [Is shlibpath searched before the hard-coded library search path?]) -_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) -_LT_DECL([], [library_names_spec], [1], - [[List of archive names. First name is the real one, the rest are links. - The last name is the one that the linker finds with -lNAME]]) -_LT_DECL([], [soname_spec], [1], - [[The coded name of the library, if different from the real name]]) -_LT_DECL([], [install_override_mode], [1], - [Permission mode override for installation of shared libraries]) -_LT_DECL([], [postinstall_cmds], [2], - [Command to use after installation of a shared archive]) -_LT_DECL([], [postuninstall_cmds], [2], - [Command to use after uninstallation of a shared archive]) -_LT_DECL([], [finish_cmds], [2], - [Commands used to finish a libtool library installation in a directory]) -_LT_DECL([], [finish_eval], [1], - [[As "finish_cmds", except a single script fragment to be evaled but - not shown]]) -_LT_DECL([], [hardcode_into_libs], [0], - [Whether we should hardcode library paths into libraries]) -_LT_DECL([], [sys_lib_search_path_spec], [2], - [Compile-time system search path for libraries]) -_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], - [Run-time system search path for libraries]) -])# _LT_SYS_DYNAMIC_LINKER - - -# _LT_PATH_TOOL_PREFIX(TOOL) -# -------------------------- -# find a file program which can recognize shared library -AC_DEFUN([_LT_PATH_TOOL_PREFIX], -[m4_require([_LT_DECL_EGREP])dnl -AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in -[[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="m4_if([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -_LT_DECL([], [MAGIC_CMD], [0], - [Used to examine libraries when file_magic_cmd begins with "file"])dnl -])# _LT_PATH_TOOL_PREFIX - -# Old name: -AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) - - -# _LT_PATH_MAGIC -# -------------- -# find a file program which can recognize a shared library -m4_defun([_LT_PATH_MAGIC], -[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) - else - MAGIC_CMD=: - fi -fi -])# _LT_PATH_MAGIC - - -# LT_PATH_LD -# ---------- -# find the pathname to the GNU or non-GNU linker -AC_DEFUN([LT_PATH_LD], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_PROG_ECHO_BACKSLASH])dnl - -AC_ARG_WITH([gnu-ld], - [AS_HELP_STRING([--with-gnu-ld], - [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], - [with_gnu_ld=no])dnl - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc*) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -haiku*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[[3-9]]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac -]) - -file_magic_glob= -want_nocaseglob=no -if test "$build" = "$host"; then - case $host_os in - mingw* | pw32*) - if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then - want_nocaseglob=yes - else - file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` - fi - ;; - esac -fi - -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - -_LT_DECL([], [deplibs_check_method], [1], - [Method to check whether dependent libraries are shared objects]) -_LT_DECL([], [file_magic_cmd], [1], - [Command to use when deplibs_check_method = "file_magic"]) -_LT_DECL([], [file_magic_glob], [1], - [How to find potential files when deplibs_check_method = "file_magic"]) -_LT_DECL([], [want_nocaseglob], [1], - [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) -])# _LT_CHECK_MAGIC_METHOD - - -# LT_PATH_NM -# ---------- -# find the pathname to a BSD- or MS-compatible name lister -AC_DEFUN([LT_PATH_NM], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi]) -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$DUMPBIN"; then : - # Let the user override the test. - else - AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in - *COFF*) - DUMPBIN="$DUMPBIN -symbols" - ;; - *) - DUMPBIN=: - ;; - esac - fi - AC_SUBST([DUMPBIN]) - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm -AC_SUBST([NM]) -_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl - -AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], - [lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) - cat conftest.out >&AS_MESSAGE_LOG_FD - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest*]) -])# LT_PATH_NM - -# Old names: -AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) -AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_PROG_NM], []) -dnl AC_DEFUN([AC_PROG_NM], []) - -# _LT_CHECK_SHAREDLIB_FROM_LINKLIB -# -------------------------------- -# how to determine the name of the shared library -# associated with a specific link library. -# -- PORTME fill in with the dynamic library characteristics -m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], -[m4_require([_LT_DECL_EGREP]) -m4_require([_LT_DECL_OBJDUMP]) -m4_require([_LT_DECL_DLLTOOL]) -AC_CACHE_CHECK([how to associate runtime and link libraries], -lt_cv_sharedlib_from_linklib_cmd, -[lt_cv_sharedlib_from_linklib_cmd='unknown' - -case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL - case `$DLLTOOL --help 2>&1` in - *--identify-strict*) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib - ;; - *) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback - ;; - esac - ;; -*) - # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" - ;; -esac -]) -sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd -test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO - -_LT_DECL([], [sharedlib_from_linklib_cmd], [1], - [Command to associate shared and link libraries]) -])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB - - -# _LT_PATH_MANIFEST_TOOL -# ---------------------- -# locate the manifest tool -m4_defun([_LT_PATH_MANIFEST_TOOL], -[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) -test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], - [lt_cv_path_mainfest_tool=no - echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD - $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out - cat conftest.err >&AS_MESSAGE_LOG_FD - if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes - fi - rm -f conftest*]) -if test "x$lt_cv_path_mainfest_tool" != xyes; then - MANIFEST_TOOL=: -fi -_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl -])# _LT_PATH_MANIFEST_TOOL - - -# LT_LIB_M -# -------- -# check for math library -AC_DEFUN([LT_LIB_M], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, cos, LIBM="-lm") - ;; -esac -AC_SUBST([LIBM]) -])# LT_LIB_M - -# Old name: -AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_CHECK_LIBM], []) - - -# _LT_COMPILER_NO_RTTI([TAGNAME]) -# ------------------------------- -m4_defun([_LT_COMPILER_NO_RTTI], -[m4_require([_LT_TAG_COMPILER])dnl - -_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - -if test "$GCC" = yes; then - case $cc_basename in - nvcc*) - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; - *) - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; - esac - - _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], - lt_cv_prog_compiler_rtti_exceptions, - [-fno-rtti -fno-exceptions], [], - [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) -fi -_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], - [Compiler flag to turn off builtin functions]) -])# _LT_COMPILER_NO_RTTI - - -# _LT_CMD_GLOBAL_SYMBOLS -# ---------------------- -m4_defun([_LT_CMD_GLOBAL_SYMBOLS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([LT_PATH_NM])dnl -AC_REQUIRE([LT_PATH_LD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_TAG_COMPILER])dnl - -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output from $compiler object]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], -[ -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[[ABCDEGRST]]' - fi - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris*) - symcode='[[BDRT]]' - ;; -sco3.2v5*) - symcode='[[DT]]' - ;; -sysv4.2uw2*) - symcode='[[DT]]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[[ABDT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[[ABCDGIRSTW]]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK ['"\ -" {last_section=section; section=\$ 3};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx]" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if AC_TRY_EVAL(ac_compile); then - # Now try to grab the symbols. - nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT@&t@_DLSYM_CONST -#elif defined(__osf__) -/* This system does not cope well with relocations in const data. */ -# define LT@&t@_DLSYM_CONST -#else -# define LT@&t@_DLSYM_CONST const -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -LT@&t@_DLSYM_CONST struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[[]] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_globsym_save_LIBS=$LIBS - lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS=$lt_globsym_save_LIBS - CFLAGS=$lt_globsym_save_CFLAGS - else - echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD - fi - else - echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi - -# Response file support. -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - nm_file_list_spec='@' -elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then - nm_file_list_spec='@' -fi - -_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], - [Take the output of nm and produce a listing of raw symbols and C names]) -_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], - [Transform the output of nm in a proper C declaration]) -_LT_DECL([global_symbol_to_c_name_address], - [lt_cv_sys_global_symbol_to_c_name_address], [1], - [Transform the output of nm in a C name address pair]) -_LT_DECL([global_symbol_to_c_name_address_lib_prefix], - [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], - [Transform the output of nm in a C name address pair when lib prefix is needed]) -_LT_DECL([], [nm_file_list_spec], [1], - [Specify filename containing input files for $NM]) -]) # _LT_CMD_GLOBAL_SYMBOLS - - -# _LT_COMPILER_PIC([TAGNAME]) -# --------------------------- -m4_defun([_LT_COMPILER_PIC], -[m4_require([_LT_TAG_COMPILER])dnl -_LT_TAGVAR(lt_prog_compiler_wl, $1)= -_LT_TAGVAR(lt_prog_compiler_pic, $1)= -_LT_TAGVAR(lt_prog_compiler_static, $1)= - -m4_if([$1], [CXX], [ - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - _LT_TAGVAR(lt_prog_compiler_static, $1)= - ;; - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - case $host_os in - aix[[4-9]]*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - dgux*) - case $cc_basename in - ec++*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - fi - ;; - aCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - interix*) - # This is c89, which is MS Visual C++ (no shared libs) - # Anyone wants to do a port? - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - KCC*) - # KAI C++ Compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - icpc* ) - # Intel C++, used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) - # IBM XL 8.0, 9.0 on PPC and BlueGene - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - esac - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd*) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - cxx*) - # Digital/Compaq C++ - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - lcc*) - # Lucid - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - *) - ;; - esac - ;; - vxworks*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -], -[ - if test "$GCC" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - _LT_TAGVAR(lt_prog_compiler_static, $1)= - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - - case $cc_basename in - nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Xcompiler -fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - hpux9* | hpux10* | hpux11*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC (with -KPIC) is the default. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' - _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' - ;; - nagfor*) - # NAG Fortran compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - ccc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All Alpha code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xl* | bgxl* | bgf* | mpixl*) - # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ F* | *Sun*Fortran*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='' - ;; - *Sun\ C*) - # Sun C 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - esac - ;; - esac - ;; - - newsos6) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All OSF/1 code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - rdos*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - solaris*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; - *) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; - esac - ;; - - sunos4*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - unicos*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - - uts4*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -]) -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" - ;; -esac - -AC_CACHE_CHECK([for $compiler option to produce PIC], - [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) -_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], - [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], - [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], - [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in - "" | " "*) ;; - *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; - esac], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) -fi -_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], - [Additional compiler flags for building library objects]) - -_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], - [How to pass a linker flag through the compiler]) -# -# Check to make sure the static flag actually works. -# -wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" -_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], - _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), - $lt_tmp_static_flag, - [], - [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) -_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], - [Compiler flag to prevent dynamic linking]) -])# _LT_COMPILER_PIC - - -# _LT_LINKER_SHLIBS([TAGNAME]) -# ---------------------------- -# See if the linker supports building shared libraries. -m4_defun([_LT_LINKER_SHLIBS], -[AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -m4_require([_LT_PATH_MANIFEST_TOOL])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -m4_if([$1], [CXX], [ - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - case $host_os in - aix[[4-9]]*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global defined - # symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" - ;; - cygwin* | mingw* | cegcc*) - case $cc_basename in - cl*) ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] - ;; - esac - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac -], [ - runpath_var= - _LT_TAGVAR(allow_undefined_flag, $1)= - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(archive_cmds, $1)= - _LT_TAGVAR(archive_expsym_cmds, $1)= - _LT_TAGVAR(compiler_needs_object, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(hardcode_automatic, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= - _LT_TAGVAR(hardcode_libdir_separator, $1)= - _LT_TAGVAR(hardcode_minus_L, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(inherit_rpath, $1)=no - _LT_TAGVAR(link_all_deplibs, $1)=unknown - _LT_TAGVAR(module_cmds, $1)= - _LT_TAGVAR(module_expsym_cmds, $1)= - _LT_TAGVAR(old_archive_from_new_cmds, $1)= - _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= - _LT_TAGVAR(thread_safe_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - _LT_TAGVAR(include_expsyms, $1)= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. -dnl Note also adjust exclude_expsyms for C++ above. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - _LT_TAGVAR(ld_shlibs, $1)=yes - - # On some targets, GNU ld is compatible enough with the native linker - # that we're better off using the native interface for both. - lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then - case $host_os in - aix*) - # The AIX port of GNU ld has always aspired to compatibility - # with the native linker. However, as the warning in the GNU ld - # block says, versions before 2.19.5* couldn't really create working - # shared libraries, regardless of the interface used. - case `$LD -v 2>&1` in - *\ \(GNU\ Binutils\)\ 2.19.5*) ;; - *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; - *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - fi - - if test "$lt_use_gnu_ld_interface" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *GNU\ gold*) supports_anon_versioning=yes ;; - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[[3-9]]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.19, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to install binutils -*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. -*** You will then need to restart the configuration process. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag=' $pic_flag' - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - _LT_TAGVAR(whole_archive_flag_spec, $1)= - tmp_sharedflag='--shared' ;; - xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf* | bgf* | bgxlf* | mpixlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' - _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - sunos4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - - if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then - runpath_var= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - _LT_TAGVAR(hardcode_direct, $1)=unsupported - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global - # defined symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - bsdi[[45]]*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - case $cc_basename in - cl*) - # Native MSVC - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' - # Don't use ranlib - _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' - _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # Assume MSVC wrapper - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - esac - ;; - - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - freebsd1*) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - hpux9*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - m4_if($1, [], [ - # Older versions of the 11.00 compiler do not understand -b yet - # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) - _LT_LINKER_OPTION([if $CC understands -b], - _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], - [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) - ;; - esac - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - # This should be the same for all languages, so no per-tag cache variable. - AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], - [lt_cv_irix_exported_symbol], - [save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - AC_LINK_IFELSE( - [AC_LANG_SOURCE( - [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], - [C++], [[int foo (void) { return 0; }]], - [Fortran 77], [[ - subroutine foo - end]], - [Fortran], [[ - subroutine foo - end]])])], - [lt_cv_irix_exported_symbol=yes], - [lt_cv_irix_exported_symbol=no]) - LDFLAGS="$save_LDFLAGS"]) - if test "$lt_cv_irix_exported_symbol" = yes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - fi - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - newsos6) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac - fi - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - solaris*) - _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - fi - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4) - case $host_vendor in - sni) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' - _LT_TAGVAR(hardcode_direct, $1)=no - ;; - motorola) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4.3*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - _LT_TAGVAR(ld_shlibs, $1)=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' - ;; - esac - fi - fi -]) -AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld - -_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl -_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl -_LT_DECL([], [extract_expsyms_cmds], [2], - [The commands to extract the exported symbol list from a shared archive]) - -# -# Do we need to explicitly link libc? -# -case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in -x|xyes) - # Assume -lc should be added - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $_LT_TAGVAR(archive_cmds, $1) in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_CACHE_CHECK([whether -lc should be explicitly linked in], - [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), - [$RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile) 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) - pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) - _LT_TAGVAR(allow_undefined_flag, $1)= - if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) - then - lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no - else - lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes - fi - _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - ]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) - ;; - esac - fi - ;; -esac - -_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], - [Whether or not to add -lc for building shared libraries]) -_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], - [enable_shared_with_static_runtimes], [0], - [Whether or not to disallow shared libs when runtime libs are static]) -_LT_TAGDECL([], [export_dynamic_flag_spec], [1], - [Compiler flag to allow reflexive dlopens]) -_LT_TAGDECL([], [whole_archive_flag_spec], [1], - [Compiler flag to generate shared objects directly from archives]) -_LT_TAGDECL([], [compiler_needs_object], [1], - [Whether the compiler copes with passing no objects directly]) -_LT_TAGDECL([], [old_archive_from_new_cmds], [2], - [Create an old-style archive from a shared archive]) -_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], - [Create a temporary old-style archive to link instead of a shared archive]) -_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) -_LT_TAGDECL([], [archive_expsym_cmds], [2]) -_LT_TAGDECL([], [module_cmds], [2], - [Commands used to build a loadable module if different from building - a shared archive.]) -_LT_TAGDECL([], [module_expsym_cmds], [2]) -_LT_TAGDECL([], [with_gnu_ld], [1], - [Whether we are building with GNU ld or not]) -_LT_TAGDECL([], [allow_undefined_flag], [1], - [Flag that allows shared libraries with undefined symbols to be built]) -_LT_TAGDECL([], [no_undefined_flag], [1], - [Flag that enforces no undefined symbols]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], - [Flag to hardcode $libdir into a binary during linking. - This must work even if $libdir does not exist]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], - [[If ld is used when linking, flag to hardcode $libdir into a binary - during linking. This must work even if $libdir does not exist]]) -_LT_TAGDECL([], [hardcode_libdir_separator], [1], - [Whether we need a single "-rpath" flag with a separated argument]) -_LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary]) -_LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting ${shlibpath_var} if the - library is relocated]) -_LT_TAGDECL([], [hardcode_minus_L], [0], - [Set to "yes" if using the -LDIR flag during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_shlibpath_var], [0], - [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_automatic], [0], - [Set to "yes" if building a shared library automatically hardcodes DIR - into the library and all subsequent libraries and executables linked - against it]) -_LT_TAGDECL([], [inherit_rpath], [0], - [Set to yes if linker adds runtime paths of dependent libraries - to runtime path list]) -_LT_TAGDECL([], [link_all_deplibs], [0], - [Whether libtool must link a program against all its dependency libraries]) -_LT_TAGDECL([], [always_export_symbols], [0], - [Set to "yes" if exported symbols are required]) -_LT_TAGDECL([], [export_symbols_cmds], [2], - [The commands to list exported symbols]) -_LT_TAGDECL([], [exclude_expsyms], [1], - [Symbols that should not be listed in the preloaded symbols]) -_LT_TAGDECL([], [include_expsyms], [1], - [Symbols that must always be exported]) -_LT_TAGDECL([], [prelink_cmds], [2], - [Commands necessary for linking programs (against libraries) with templates]) -_LT_TAGDECL([], [postlink_cmds], [2], - [Commands necessary for finishing linking programs]) -_LT_TAGDECL([], [file_list_spec], [1], - [Specify filename containing input files]) -dnl FIXME: Not yet implemented -dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], -dnl [Compiler flag to generate thread safe objects]) -])# _LT_LINKER_SHLIBS - - -# _LT_LANG_C_CONFIG([TAG]) -# ------------------------ -# Ensure that the configuration variables for a C compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_C_CONFIG], -[m4_require([_LT_DECL_EGREP])dnl -lt_save_CC="$CC" -AC_LANG_PUSH(C) - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - -_LT_TAG_COMPILER -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - LT_SYS_DLOPEN_SELF - _LT_CMD_STRIPLIB - - # Report which library types will actually be built - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_CONFIG($1) -fi -AC_LANG_POP -CC="$lt_save_CC" -])# _LT_LANG_C_CONFIG - - -# _LT_LANG_CXX_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a C++ compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_CXX_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_PATH_MANIFEST_TOOL])dnl -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - AC_PROG_CXXCPP -else - _lt_caught_CXX_error=yes -fi - -AC_LANG_PUSH(C++) -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(compiler_needs_object, $1)=no -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the CXX compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="int some_variable = 0;" - - # Code to be used in simple link tests - lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_CFLAGS=$CFLAGS - lt_save_LD=$LD - lt_save_GCC=$GCC - GCC=$GXX - lt_save_with_gnu_ld=$with_gnu_ld - lt_save_path_LD=$lt_cv_path_LD - if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx - else - $as_unset lt_cv_prog_gnu_ld - fi - if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX - else - $as_unset lt_cv_path_LD - fi - test -z "${LDCXX+set}" || LD=$LDCXX - CC=${CXX-"c++"} - CFLAGS=$CXXFLAGS - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - # We don't want -fno-exception when compiling C++ code, so set the - # no_builtin_flag separately - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - else - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - fi - - if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - LT_PATH_LD - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - GXX=no - with_gnu_ld=no - wlarc= - fi - - # PORTME: fill in a description of your system's C++ link characteristics - AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) - _LT_TAGVAR(ld_shlibs, $1)=yes - case $host_os in - aix3*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GXX" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to - # export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty - # executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared - # libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - cygwin* | mingw* | pw32* | cegcc*) - case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - # Don't use ranlib - _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' - _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - func_to_tool_file "$lt_outputfile"~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # g++ - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - freebsd[[12]]*) - # C++ shared libraries reported to be fairly broken before - # switch to ELF - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - freebsd-elf*) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - - freebsd* | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - gnu*) - ;; - - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - esac - fi - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' - fi - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc* | ecpc* ) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - case `$CC -V` in - *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) - _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' - _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ - $RANLIB $oldlib' - _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - *) # Version 6 and above use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - ;; - cxx*) - # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' - ;; - xl* | mpixl* | bgxl*) - # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - - # Not sure whether something based on - # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 - # would be better. - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - esac - ;; - esac - ;; - - lynxos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - m88k*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - - *nto* | *qnx*) - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - openbsd2*) - # C++ shared libraries are fairly broken - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - fi - output_verbose_link_cmd=func_echo_all - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - case $host in - osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; - *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; - esac - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - case $host in - osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - ;; - *) - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - case $host in - osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - psos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(archive_cmds_need_lc,$1)=yes - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. - # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' - if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - fi - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - ;; - esac - fi - ;; - esac - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ - '"$_LT_TAGVAR(old_archive_cmds, $1)" - _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ - '"$_LT_TAGVAR(reload_cmds, $1)" - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - vxworks*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - - _LT_TAGVAR(GCC, $1)="$GXX" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS - LDCXX=$LD - LD=$lt_save_LD - GCC=$lt_save_GCC - with_gnu_ld=$lt_save_with_gnu_ld - lt_cv_path_LDCXX=$lt_cv_path_LD - lt_cv_path_LD=$lt_save_path_LD - lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld - lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes - -AC_LANG_POP -])# _LT_LANG_CXX_CONFIG - - -# _LT_FUNC_STRIPNAME_CNF -# ---------------------- -# func_stripname_cnf prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# -# This function is identical to the (non-XSI) version of func_stripname, -# except this one can be used by m4 code that may be executed by configure, -# rather than the libtool script. -m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl -AC_REQUIRE([_LT_DECL_SED]) -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) -func_stripname_cnf () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} # func_stripname_cnf -])# _LT_FUNC_STRIPNAME_CNF - -# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) -# --------------------------------- -# Figure out "hidden" library dependencies from verbose -# compiler output when linking a shared library. -# Parse the compiler output and extract the necessary -# objects, libraries and library flags. -m4_defun([_LT_SYS_HIDDEN_LIBDEPS], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl -# Dependencies to place before and after the object being linked: -_LT_TAGVAR(predep_objects, $1)= -_LT_TAGVAR(postdep_objects, $1)= -_LT_TAGVAR(predeps, $1)= -_LT_TAGVAR(postdeps, $1)= -_LT_TAGVAR(compiler_lib_search_path, $1)= - -dnl we can't use the lt_simple_compile_test_code here, -dnl because it contains code intended for an executable, -dnl not a library. It's possible we should let each -dnl tag define a new lt_????_link_test_code variable, -dnl but it's only used here... -m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF -int a; -void foo (void) { a = 0; } -_LT_EOF -], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF -class Foo -{ -public: - Foo (void) { a = 0; } -private: - int a; -}; -_LT_EOF -], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer*4 a - a=0 - return - end -_LT_EOF -], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer a - a=0 - return - end -_LT_EOF -], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF -public class foo { - private int a; - public void bar (void) { - a = 0; - } -}; -_LT_EOF -]) - -_lt_libdeps_save_CFLAGS=$CFLAGS -case "$CC $CFLAGS " in #( -*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; -*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; -esac - -dnl Parse the compiler output and extract the necessary -dnl objects, libraries and library flags. -if AC_TRY_EVAL(ac_compile); then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - for p in `eval "$output_verbose_link_cmd"`; do - case ${prev}${p} in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test $p = "-L" || - test $p = "-R"; then - prev=$p - continue - fi - - # Expand the sysroot to ease extracting the directories later. - if test -z "$prev"; then - case $p in - -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; - -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; - -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; - esac - fi - case $p in - =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; - esac - if test "$pre_test_object_deps_done" = no; then - case ${prev} in - -L | -R) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" - else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)="${prev}${p}" - else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" - fi - fi - prev= - ;; - - *.lto.$objext) ;; # Ignore GCC LTO objects - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test "$pre_test_object_deps_done" = no; then - if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)="$p" - else - _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" - fi - else - if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)="$p" - else - _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling $1 test program" -fi - -$RM -f confest.$objext -CFLAGS=$_lt_libdeps_save_CFLAGS - -# PORTME: override above test on systems where it is broken -m4_if([$1], [CXX], -[case $host_os in -interix[[3-9]]*) - # Interix 3.5 installs completely hosed .la files for C++, so rather than - # hack all around it, let's just trust "g++" to DTRT. - _LT_TAGVAR(predep_objects,$1)= - _LT_TAGVAR(postdep_objects,$1)= - _LT_TAGVAR(postdeps,$1)= - ;; - -linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; - -solaris*) - case $cc_basename in - CC* | sunCC*) - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; -esac -]) - -case " $_LT_TAGVAR(postdeps, $1) " in -*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; -esac - _LT_TAGVAR(compiler_lib_search_dirs, $1)= -if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` -fi -_LT_TAGDECL([], [compiler_lib_search_dirs], [1], - [The directories searched by this compiler when creating a shared library]) -_LT_TAGDECL([], [predep_objects], [1], - [Dependencies to place before and after the objects being linked to - create a shared library]) -_LT_TAGDECL([], [postdep_objects], [1]) -_LT_TAGDECL([], [predeps], [1]) -_LT_TAGDECL([], [postdeps], [1]) -_LT_TAGDECL([], [compiler_lib_search_path], [1], - [The library search path used internally by the compiler when linking - a shared library]) -])# _LT_SYS_HIDDEN_LIBDEPS - - -# _LT_LANG_F77_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a Fortran 77 compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_F77_CONFIG], -[AC_LANG_PUSH(Fortran 77) -if test -z "$F77" || test "X$F77" = "Xno"; then - _lt_disable_F77=yes -fi - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for f77 test sources. -ac_ext=f - -# Object file extension for compiled f77 test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the F77 compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_F77" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - lt_save_CFLAGS=$CFLAGS - CC=${F77-"f77"} - CFLAGS=$FFLAGS - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - GCC=$G77 - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$G77" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC="$lt_save_CC" - CFLAGS="$lt_save_CFLAGS" -fi # test "$_lt_disable_F77" != yes - -AC_LANG_POP -])# _LT_LANG_F77_CONFIG - - -# _LT_LANG_FC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for a Fortran compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_FC_CONFIG], -[AC_LANG_PUSH(Fortran) - -if test -z "$FC" || test "X$FC" = "Xno"; then - _lt_disable_FC=yes -fi - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for fc test sources. -ac_ext=${ac_fc_srcext-f} - -# Object file extension for compiled fc test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the FC compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_FC" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - lt_save_CFLAGS=$CFLAGS - CC=${FC-"f95"} - CFLAGS=$FCFLAGS - compiler=$CC - GCC=$ac_cv_fc_compiler_gnu - - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS -fi # test "$_lt_disable_FC" != yes - -AC_LANG_POP -])# _LT_LANG_FC_CONFIG - - -# _LT_LANG_GCJ_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Java Compiler compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_GCJ_CONFIG], -[AC_REQUIRE([LT_PROG_GCJ])dnl -AC_LANG_SAVE - -# Source file extension for Java test sources. -ac_ext=java - -# Object file extension for compiled Java test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}" - -# Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC=yes -CC=${GCJ-"gcj"} -CFLAGS=$GCJFLAGS -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" -_LT_CC_BASENAME([$compiler]) - -# GCJ did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_GCJ_CONFIG - - -# _LT_LANG_RC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for the Windows resource compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_RC_CONFIG], -[AC_REQUIRE([LT_PROG_RC])dnl -AC_LANG_SAVE - -# Source file extension for RC test sources. -ac_ext=rc - -# Object file extension for compiled RC test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' - -# Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC= -CC=${RC-"windres"} -CFLAGS= -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) -_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - -if test -n "$compiler"; then - : - _LT_CONFIG($1) -fi - -GCC=$lt_save_GCC -AC_LANG_RESTORE -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_RC_CONFIG - - -# LT_PROG_GCJ -# ----------- -AC_DEFUN([LT_PROG_GCJ], -[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], - [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], - [AC_CHECK_TOOL(GCJ, gcj,) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" - AC_SUBST(GCJFLAGS)])])[]dnl -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_GCJ], []) - - -# LT_PROG_RC -# ---------- -AC_DEFUN([LT_PROG_RC], -[AC_CHECK_TOOL(RC, windres,) -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_RC], []) - - -# _LT_DECL_EGREP -# -------------- -# If we don't have a new enough Autoconf to choose the best grep -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_EGREP], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_REQUIRE([AC_PROG_FGREP])dnl -test -z "$GREP" && GREP=grep -_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) -_LT_DECL([], [EGREP], [1], [An ERE matcher]) -_LT_DECL([], [FGREP], [1], [A literal string matcher]) -dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too -AC_SUBST([GREP]) -]) - - -# _LT_DECL_OBJDUMP -# -------------- -# If we don't have a new enough Autoconf to choose the best objdump -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_OBJDUMP], -[AC_CHECK_TOOL(OBJDUMP, objdump, false) -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) -AC_SUBST([OBJDUMP]) -]) - -# _LT_DECL_DLLTOOL -# ---------------- -# Ensure DLLTOOL variable is set. -m4_defun([_LT_DECL_DLLTOOL], -[AC_CHECK_TOOL(DLLTOOL, dlltool, false) -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) -AC_SUBST([DLLTOOL]) -]) - -# _LT_DECL_SED -# ------------ -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -m4_defun([_LT_DECL_SED], -[AC_PROG_SED -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" -_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) -_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], - [Sed that helps us avoid accidentally triggering echo(1) options like -n]) -])# _LT_DECL_SED - -m4_ifndef([AC_PROG_SED], [ -############################################################ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -############################################################ - -m4_defun([AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -IFS=$as_save_IFS -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break - lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_SUBST([SED]) -AC_MSG_RESULT([$SED]) -])#AC_PROG_SED -])#m4_ifndef - -# Old name: -AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_SED], []) - - -# _LT_CHECK_SHELL_FEATURES -# ------------------------ -# Find out whether the shell is Bourne or XSI compatible, -# or has some other useful features. -m4_defun([_LT_CHECK_SHELL_FEATURES], -[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -AC_MSG_RESULT([$xsi_shell]) -_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) - -AC_MSG_CHECKING([whether the shell understands "+="]) -lt_shell_append=no -( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -AC_MSG_RESULT([$lt_shell_append]) -_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi -_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac -_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl -_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl -])# _LT_CHECK_SHELL_FEATURES - - -# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) -# ------------------------------------------------------ -# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and -# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. -m4_defun([_LT_PROG_FUNCTION_REPLACE], -[dnl { -sed -e '/^$1 ()$/,/^} # $1 /c\ -$1 ()\ -{\ -m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) -} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: -]) - - -# _LT_PROG_REPLACE_SHELLFNS -# ------------------------- -# Replace existing portable implementations of several shell functions with -# equivalent extended shell implementations where those features are available.. -m4_defun([_LT_PROG_REPLACE_SHELLFNS], -[if test x"$xsi_shell" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl - func_split_long_opt_name=${1%%=*} - func_split_long_opt_arg=${1#*=}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl - func_split_short_opt_arg=${1#??} - func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) - - _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) - - _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) - - _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) -fi - -if test x"$lt_shell_append" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) - - _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl - func_quote_for_eval "${2}" -dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ - eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) -fi -]) - -# _LT_PATH_CONVERSION_FUNCTIONS -# ----------------------------- -# Determine which file name conversion functions should be used by -# func_to_host_file (and, implicitly, by func_to_host_path). These are needed -# for certain cross-compile configurations and native mingw. -m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_MSG_CHECKING([how to convert $build file names to $host format]) -AC_CACHE_VAL(lt_cv_to_host_file_cmd, -[case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 - ;; - esac - ;; - *-*-cygwin* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin - ;; - esac - ;; - * ) # unhandled hosts (and "normal" native builds) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; -esac -]) -to_host_file_cmd=$lt_cv_to_host_file_cmd -AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) -_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], - [0], [convert $build file names to $host format])dnl - -AC_MSG_CHECKING([how to convert $build file names to toolchain format]) -AC_CACHE_VAL(lt_cv_to_tool_file_cmd, -[#assume ordinary cross tools, or native build. -lt_cv_to_tool_file_cmd=func_convert_file_noop -case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 - ;; - esac - ;; -esac -]) -to_tool_file_cmd=$lt_cv_to_tool_file_cmd -AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) -_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], - [0], [convert $build files to toolchain format])dnl -])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/resources/3rdparty/glpk-4.53/m4/ltoptions.m4 b/resources/3rdparty/glpk-4.53/m4/ltoptions.m4 deleted file mode 100644 index 17cfd51c0..000000000 --- a/resources/3rdparty/glpk-4.53/m4/ltoptions.m4 +++ /dev/null @@ -1,369 +0,0 @@ -# Helper functions for option handling. -*- Autoconf -*- -# -# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 7 ltoptions.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) - - -# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) -# ------------------------------------------ -m4_define([_LT_MANGLE_OPTION], -[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) - - -# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) -# --------------------------------------- -# Set option OPTION-NAME for macro MACRO-NAME, and if there is a -# matching handler defined, dispatch to it. Other OPTION-NAMEs are -# saved as a flag. -m4_define([_LT_SET_OPTION], -[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl -m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), - _LT_MANGLE_DEFUN([$1], [$2]), - [m4_warning([Unknown $1 option `$2'])])[]dnl -]) - - -# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) -# ------------------------------------------------------------ -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -m4_define([_LT_IF_OPTION], -[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) - - -# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) -# ------------------------------------------------------- -# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME -# are set. -m4_define([_LT_UNLESS_OPTIONS], -[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), - [m4_define([$0_found])])])[]dnl -m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 -])[]dnl -]) - - -# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) -# ---------------------------------------- -# OPTION-LIST is a space-separated list of Libtool options associated -# with MACRO-NAME. If any OPTION has a matching handler declared with -# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about -# the unknown option and exit. -m4_defun([_LT_SET_OPTIONS], -[# Set options -m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [_LT_SET_OPTION([$1], _LT_Option)]) - -m4_if([$1],[LT_INIT],[ - dnl - dnl Simply set some default values (i.e off) if boolean options were not - dnl specified: - _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no - ]) - _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no - ]) - dnl - dnl If no reference was made to various pairs of opposing options, then - dnl we run the default mode handler for the pair. For example, if neither - dnl `shared' nor `disable-shared' was passed, we enable building of shared - dnl archives by default: - _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) - _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], - [_LT_ENABLE_FAST_INSTALL]) - ]) -])# _LT_SET_OPTIONS - - -## --------------------------------- ## -## Macros to handle LT_INIT options. ## -## --------------------------------- ## - -# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) -# ----------------------------------------- -m4_define([_LT_MANGLE_DEFUN], -[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) - - -# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) -# ----------------------------------------------- -m4_define([LT_OPTION_DEFINE], -[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl -])# LT_OPTION_DEFINE - - -# dlopen -# ------ -LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes -]) - -AU_DEFUN([AC_LIBTOOL_DLOPEN], -[_LT_SET_OPTION([LT_INIT], [dlopen]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `dlopen' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) - - -# win32-dll -# --------- -# Declare package support for building win32 dll's. -LT_OPTION_DEFINE([LT_INIT], [win32-dll], -[enable_win32_dll=yes - -case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - ;; -esac - -test -z "$AS" && AS=as -_LT_DECL([], [AS], [1], [Assembler program])dnl - -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl - -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl -])# win32-dll - -AU_DEFUN([AC_LIBTOOL_WIN32_DLL], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -_LT_SET_OPTION([LT_INIT], [win32-dll]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `win32-dll' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) - - -# _LT_ENABLE_SHARED([DEFAULT]) -# ---------------------------- -# implement the --enable-shared flag, and supports the `shared' and -# `disable-shared' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_SHARED], -[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([shared], - [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], - [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) - - _LT_DECL([build_libtool_libs], [enable_shared], [0], - [Whether or not to build shared libraries]) -])# _LT_ENABLE_SHARED - -LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) -]) - -AC_DEFUN([AC_DISABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], [disable-shared]) -]) - -AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) -AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_SHARED], []) -dnl AC_DEFUN([AM_DISABLE_SHARED], []) - - - -# _LT_ENABLE_STATIC([DEFAULT]) -# ---------------------------- -# implement the --enable-static flag, and support the `static' and -# `disable-static' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_STATIC], -[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([static], - [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], - [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_static=]_LT_ENABLE_STATIC_DEFAULT) - - _LT_DECL([build_old_libs], [enable_static], [0], - [Whether or not to build static libraries]) -])# _LT_ENABLE_STATIC - -LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) -]) - -AC_DEFUN([AC_DISABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], [disable-static]) -]) - -AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) -AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_STATIC], []) -dnl AC_DEFUN([AM_DISABLE_STATIC], []) - - - -# _LT_ENABLE_FAST_INSTALL([DEFAULT]) -# ---------------------------------- -# implement the --enable-fast-install flag, and support the `fast-install' -# and `disable-fast-install' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_FAST_INSTALL], -[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([fast-install], - [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], - [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) - -_LT_DECL([fast_install], [enable_fast_install], [0], - [Whether or not to optimize for fast installation])dnl -])# _LT_ENABLE_FAST_INSTALL - -LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) - -# Old names: -AU_DEFUN([AC_ENABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `fast-install' option into LT_INIT's first parameter.]) -]) - -AU_DEFUN([AC_DISABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `disable-fast-install' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) -dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) - - -# _LT_WITH_PIC([MODE]) -# -------------------- -# implement the --with-pic flag, and support the `pic-only' and `no-pic' -# LT_INIT options. -# MODE is either `yes' or `no'. If omitted, it defaults to `both'. -m4_define([_LT_WITH_PIC], -[AC_ARG_WITH([pic], - [AS_HELP_STRING([--with-pic], - [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [pic_mode="$withval"], - [pic_mode=default]) - -test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) - -_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl -])# _LT_WITH_PIC - -LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) - -# Old name: -AU_DEFUN([AC_LIBTOOL_PICMODE], -[_LT_SET_OPTION([LT_INIT], [pic-only]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `pic-only' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) - -## ----------------- ## -## LTDL_INIT Options ## -## ----------------- ## - -m4_define([_LTDL_MODE], []) -LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], - [m4_define([_LTDL_MODE], [nonrecursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [recursive], - [m4_define([_LTDL_MODE], [recursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [subproject], - [m4_define([_LTDL_MODE], [subproject])]) - -m4_define([_LTDL_TYPE], []) -LT_OPTION_DEFINE([LTDL_INIT], [installable], - [m4_define([_LTDL_TYPE], [installable])]) -LT_OPTION_DEFINE([LTDL_INIT], [convenience], - [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/resources/3rdparty/glpk-4.53/m4/ltsugar.m4 b/resources/3rdparty/glpk-4.53/m4/ltsugar.m4 deleted file mode 100644 index 9000a057d..000000000 --- a/resources/3rdparty/glpk-4.53/m4/ltsugar.m4 +++ /dev/null @@ -1,123 +0,0 @@ -# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- -# -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 6 ltsugar.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) - - -# lt_join(SEP, ARG1, [ARG2...]) -# ----------------------------- -# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their -# associated separator. -# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier -# versions in m4sugar had bugs. -m4_define([lt_join], -[m4_if([$#], [1], [], - [$#], [2], [[$2]], - [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) -m4_define([_lt_join], -[m4_if([$#$2], [2], [], - [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) - - -# lt_car(LIST) -# lt_cdr(LIST) -# ------------ -# Manipulate m4 lists. -# These macros are necessary as long as will still need to support -# Autoconf-2.59 which quotes differently. -m4_define([lt_car], [[$1]]) -m4_define([lt_cdr], -[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], - [$#], 1, [], - [m4_dquote(m4_shift($@))])]) -m4_define([lt_unquote], $1) - - -# lt_append(MACRO-NAME, STRING, [SEPARATOR]) -# ------------------------------------------ -# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. -# Note that neither SEPARATOR nor STRING are expanded; they are appended -# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). -# No SEPARATOR is output if MACRO-NAME was previously undefined (different -# than defined and empty). -# -# This macro is needed until we can rely on Autoconf 2.62, since earlier -# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. -m4_define([lt_append], -[m4_define([$1], - m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) - - - -# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) -# ---------------------------------------------------------- -# Produce a SEP delimited list of all paired combinations of elements of -# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list -# has the form PREFIXmINFIXSUFFIXn. -# Needed until we can rely on m4_combine added in Autoconf 2.62. -m4_define([lt_combine], -[m4_if(m4_eval([$# > 3]), [1], - [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl -[[m4_foreach([_Lt_prefix], [$2], - [m4_foreach([_Lt_suffix], - ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, - [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) - - -# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) -# ----------------------------------------------------------------------- -# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited -# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. -m4_define([lt_if_append_uniq], -[m4_ifdef([$1], - [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], - [lt_append([$1], [$2], [$3])$4], - [$5])], - [lt_append([$1], [$2], [$3])$4])]) - - -# lt_dict_add(DICT, KEY, VALUE) -# ----------------------------- -m4_define([lt_dict_add], -[m4_define([$1($2)], [$3])]) - - -# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) -# -------------------------------------------- -m4_define([lt_dict_add_subkey], -[m4_define([$1($2:$3)], [$4])]) - - -# lt_dict_fetch(DICT, KEY, [SUBKEY]) -# ---------------------------------- -m4_define([lt_dict_fetch], -[m4_ifval([$3], - m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), - m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) - - -# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) -# ----------------------------------------------------------------- -m4_define([lt_if_dict_fetch], -[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], - [$5], - [$6])]) - - -# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) -# -------------------------------------------------------------- -m4_define([lt_dict_filter], -[m4_if([$5], [], [], - [lt_join(m4_quote(m4_default([$4], [[, ]])), - lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), - [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl -]) diff --git a/resources/3rdparty/glpk-4.53/m4/ltversion.m4 b/resources/3rdparty/glpk-4.53/m4/ltversion.m4 deleted file mode 100644 index 9bf776f09..000000000 --- a/resources/3rdparty/glpk-4.53/m4/ltversion.m4 +++ /dev/null @@ -1,23 +0,0 @@ -# ltversion.m4 -- version numbers -*- Autoconf -*- -# -# Copyright (C) 2004 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# @configure_input@ - -# serial 3294 ltversion.m4 -# This file is part of GNU Libtool - -m4_define([LT_PACKAGE_VERSION], [2.4]) -m4_define([LT_PACKAGE_REVISION], [1.3294]) - -AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4' -macro_revision='1.3294' -_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) -_LT_DECL(, macro_revision, 0) -]) diff --git a/resources/3rdparty/glpk-4.53/m4/lt~obsolete.m4 b/resources/3rdparty/glpk-4.53/m4/lt~obsolete.m4 deleted file mode 100644 index c573da90c..000000000 --- a/resources/3rdparty/glpk-4.53/m4/lt~obsolete.m4 +++ /dev/null @@ -1,98 +0,0 @@ -# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- -# -# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004. -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 5 lt~obsolete.m4 - -# These exist entirely to fool aclocal when bootstrapping libtool. -# -# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) -# which have later been changed to m4_define as they aren't part of the -# exported API, or moved to Autoconf or Automake where they belong. -# -# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN -# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us -# using a macro with the same name in our local m4/libtool.m4 it'll -# pull the old libtool.m4 in (it doesn't see our shiny new m4_define -# and doesn't know about Autoconf macros at all.) -# -# So we provide this file, which has a silly filename so it's always -# included after everything else. This provides aclocal with the -# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything -# because those macros already exist, or will be overwritten later. -# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. -# -# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. -# Yes, that means every name once taken will need to remain here until -# we give up compatibility with versions before 1.7, at which point -# we need to keep only those names which we still refer to. - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) - -m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) -m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) -m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) -m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) -m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) -m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) -m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) -m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) -m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) -m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) -m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) -m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) -m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) -m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) -m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) -m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) -m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) -m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) -m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) -m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) -m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) -m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) -m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) -m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) -m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) -m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) -m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) -m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) -m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) -m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) -m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) -m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) -m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) -m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) -m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) -m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) -m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) -m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) -m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) -m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) -m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) -m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) -m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) -m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) -m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) -m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) -m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) -m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) -m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) -m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) -m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) -m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) -m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/resources/3rdparty/glpk-4.53/missing b/resources/3rdparty/glpk-4.53/missing deleted file mode 100644 index 9a5564823..000000000 --- a/resources/3rdparty/glpk-4.53/missing +++ /dev/null @@ -1,330 +0,0 @@ -#! /bin/sh -# Common stub for a few missing GNU programs while installing. - -scriptversion=2012-01-06.18; # UTC - -# Copyright (C) 1996-2012 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try '$0 --help' for more information" - exit 1 -fi - -run=: -sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' -sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - -# In the cases where this matters, 'missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -msg="missing on your system" - -case $1 in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Handle 'PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails - -Supported PROGRAM values: - aclocal touch file 'aclocal.m4' - autoconf touch file 'configure' - autoheader touch file 'config.h.in' - autom4te touch the output file, or create a stub one - automake touch all 'Makefile.in' files - bison create 'y.tab.[ch]', if possible, from existing .[ch] - flex create 'lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create 'lex.yy.c', if possible, from existing .c - makeinfo touch the output file - yacc create 'y.tab.[ch]', if possible, from existing .[ch] - -Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and -'g' are ignored when checking the name. - -Send bug reports to ." - exit $? - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing $scriptversion (GNU Automake)" - exit $? - ;; - - -*) - echo 1>&2 "$0: Unknown '$1' option" - echo 1>&2 "Try '$0 --help' for more information" - exit 1 - ;; - -esac - -# normalize program name to check for. -program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). This is about non-GNU programs, so use $1 not -# $program. -case $1 in - lex*|yacc*) - # Not GNU programs, they don't have --version. - ;; - - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running '$TOOL --version' or '$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case $program in - aclocal*) - echo 1>&2 "\ -WARNING: '$1' is $msg. You should only need it if - you modified 'acinclude.m4' or '${configure_ac}'. You might want - to install the Automake and Perl packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf*) - echo 1>&2 "\ -WARNING: '$1' is $msg. You should only need it if - you modified '${configure_ac}'. You might want to install the - Autoconf and GNU m4 packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader*) - echo 1>&2 "\ -WARNING: '$1' is $msg. You should only need it if - you modified 'acconfig.h' or '${configure_ac}'. You might want - to install the Autoconf and GNU m4 packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case $f in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: '$1' is $msg. You should only need it if - you modified 'Makefile.am', 'acinclude.m4' or '${configure_ac}'. - You might want to install the Automake and Perl packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te*) - echo 1>&2 "\ -WARNING: '$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get '$1' as part of Autoconf from any GNU - archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison*|yacc*) - echo 1>&2 "\ -WARNING: '$1' $msg. You should only need it if - you modified a '.y' file. You may need the Bison package - in order for those modifications to take effect. You can get - Bison from any GNU archive site." - rm -f y.tab.c y.tab.h - if test $# -ne 1; then - eval LASTARG=\${$#} - case $LASTARG in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if test ! -f y.tab.h; then - echo >y.tab.h - fi - if test ! -f y.tab.c; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex*|flex*) - echo 1>&2 "\ -WARNING: '$1' is $msg. You should only need it if - you modified a '.l' file. You may need the Flex package - in order for those modifications to take effect. You can get - Flex from any GNU archive site." - rm -f lex.yy.c - if test $# -ne 1; then - eval LASTARG=\${$#} - case $LASTARG in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if test ! -f lex.yy.c; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man*) - echo 1>&2 "\ -WARNING: '$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - Help2man package in order for those modifications to take - effect. You can get Help2man from any GNU archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit $? - fi - ;; - - makeinfo*) - echo 1>&2 "\ -WARNING: '$1' is $msg. You should only need it if - you modified a '.texi' or '.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy 'make' (AIX, - DU, IRIX). You might want to install the Texinfo package or - the GNU make package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n ' - /^@setfilename/{ - s/.* \([^ ]*\) *$/\1/ - p - q - }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; - - *) - echo 1>&2 "\ -WARNING: '$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the 'README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing '$1' program." - exit 1 - ;; -esac - -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/resources/3rdparty/glpk-4.53/resources/FindMySQL.cmake b/resources/3rdparty/glpk-4.53/resources/FindMySQL.cmake deleted file mode 100644 index 939582362..000000000 --- a/resources/3rdparty/glpk-4.53/resources/FindMySQL.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# - Find mysqlclient -# Find the native MySQL includes and library -# -# MYSQL_INCLUDE_DIR - where to find mysql.h, etc. -# MYSQL_LIBRARIES - List of libraries when using MySQL. -# MYSQL_FOUND - True if MySQL found. - -IF (MYSQL_INCLUDE_DIR) - # Already in cache, be silent - SET(MYSQL_FIND_QUIETLY TRUE) -ENDIF (MYSQL_INCLUDE_DIR) - -FIND_PATH(MYSQL_INCLUDE_DIR mysql.h - /usr/local/include/mysql - /usr/include/mysql -) - -SET(MYSQL_NAMES mysqlclient mysqlclient_r) -FIND_LIBRARY(MYSQL_LIBRARY - NAMES ${MYSQL_NAMES} - PATHS /usr/lib /usr/local/lib - PATH_SUFFIXES mysql -) - -IF (MYSQL_INCLUDE_DIR AND MYSQL_LIBRARY) - SET(MYSQL_FOUND TRUE) - SET( MYSQL_LIBRARIES ${MYSQL_LIBRARY} ) -ELSE (MYSQL_INCLUDE_DIR AND MYSQL_LIBRARY) - SET(MYSQL_FOUND FALSE) - SET( MYSQL_LIBRARIES ) -ENDIF (MYSQL_INCLUDE_DIR AND MYSQL_LIBRARY) - -IF (MYSQL_FOUND) - IF (NOT MYSQL_FIND_QUIETLY) - MESSAGE(STATUS "Found MySQL: ${MYSQL_LIBRARY}") - ENDIF (NOT MYSQL_FIND_QUIETLY) -ELSE (MYSQL_FOUND) - IF (MYSQL_FIND_REQUIRED) - MESSAGE(STATUS "Looked for MySQL libraries named ${MYSQL_NAMES}.") - MESSAGE(FATAL_ERROR "Could NOT find MySQL library") - ENDIF (MYSQL_FIND_REQUIRED) -ENDIF (MYSQL_FOUND) - -MARK_AS_ADVANCED( - MYSQL_LIBRARY - MYSQL_INCLUDE_DIR -) \ No newline at end of file diff --git a/resources/3rdparty/glpk-4.53/resources/FindODBC.cmake b/resources/3rdparty/glpk-4.53/resources/FindODBC.cmake deleted file mode 100644 index dacb1f6c6..000000000 --- a/resources/3rdparty/glpk-4.53/resources/FindODBC.cmake +++ /dev/null @@ -1,60 +0,0 @@ -# -# Find the ODBC driver manager includes and library. -# -# ODBC is an open standard for connecting to different databases in a -# semi-vendor-independent fashion. First you install the ODBC driver -# manager. Then you need a driver for each separate database you want -# to connect to (unless a generic one works). VTK includes neither -# the driver manager nor the vendor-specific drivers: you have to find -# those yourself. -# -# This module defines -# ODBC_INCLUDE_DIRECTORIES, where to find sql.h -# ODBC_LIBRARIES, the libraries to link against to use ODBC -# ODBC_FOUND. If false, you cannot build anything that requires MySQL. - -find_path(ODBC_INCLUDE_DIRECTORIES - NAMES sql.h - HINTS - /usr/include - /usr/include/odbc - /usr/local/include - /usr/local/include/odbc - /usr/local/odbc/include - "C:/Program Files/ODBC/include" - "C:/Program Files/Microsoft SDKs/Windows/v7.0/include" - "C:/Program Files (x86)/Microsoft SDKs/Windows/v7.1A/include" - "C:/Program Files/Microsoft SDKs/Windows/v6.0a/include" - "C:/ODBC/include" - DOC "Specify the directory containing sql.h." -) - -find_library(ODBC_LIBRARIES - NAMES iodbc odbc odbcinst odbc32 - HINTS - /usr/lib - /usr/lib/odbc - /usr/local/lib - /usr/local/lib/odbc - /usr/local/odbc/lib - "C:/Program Files/ODBC/lib" - "C:/ODBC/lib/debug" - "C:/Program Files (x86)/Microsoft SDKs/Windows/v7.1A/Lib" - "C:/Program Files (x86)/Microsoft SDKs/Windows/v7.0A/Lib" - DOC "Specify the ODBC driver manager library here." -) - -# MinGW find usually fails -if(MINGW) - set(ODBC_INCLUDE_DIRECTORIES ".") - set(ODBC_LIBRARIES odbc32) -endif() - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(ODBC - DEFAULT_MSG - ODBC_INCLUDE_DIRECTORIES - ODBC_LIBRARIES - ) - -mark_as_advanced(ODBC_FOUND ODBC_LIBRARIES ODBC_INCLUDE_DIRECTORIES) \ No newline at end of file diff --git a/resources/3rdparty/glpk-4.53/src/Makefile.am b/resources/3rdparty/glpk-4.53/src/Makefile.am deleted file mode 100644 index b4f050f71..000000000 --- a/resources/3rdparty/glpk-4.53/src/Makefile.am +++ /dev/null @@ -1,167 +0,0 @@ -## Process this file with automake to produce Makefile.in ## - -include_HEADERS = glpk.h - -lib_LTLIBRARIES = libglpk.la - -libglpk_la_CPPFLAGS = \ --I$(srcdir) \ --I$(srcdir)/amd \ --I$(srcdir)/bflib \ --I$(srcdir)/cglib \ --I$(srcdir)/colamd \ --I$(srcdir)/env \ --I$(srcdir)/minisat \ --I$(srcdir)/misc \ --I$(srcdir)/proxy \ --I$(srcdir)/zlib - -libglpk_la_LDFLAGS = \ --version-info 37:0:1 \ --export-symbols-regex '^glp_*' - -libglpk_la_SOURCES = \ -avl.c \ -bfd.c \ -bfx.c \ -glpapi01.c \ -glpapi02.c \ -glpapi03.c \ -glpapi04.c \ -glpapi05.c \ -glpapi06.c \ -glpapi07.c \ -glpapi08.c \ -glpapi09.c \ -glpapi10.c \ -glpapi11.c \ -glpapi12.c \ -glpapi13.c \ -glpapi14.c \ -glpapi15.c \ -glpapi16.c \ -glpapi17.c \ -glpapi18.c \ -glpapi19.c \ -glpapi20.c \ -glpapi21.c \ -glpcpx.c \ -glpdmx.c \ -glpgmp.c \ -glphbm.c \ -glpini01.c \ -glpini02.c \ -glpios01.c \ -glpios02.c \ -glpios03.c \ -glpios04.c \ -glpios05.c \ -glpios06.c \ -glpios07.c \ -glpios08.c \ -glpios09.c \ -glpios10.c \ -glpios11.c \ -glpios12.c \ -glpipm.c \ -glplpf.c \ -glpmat.c \ -glpmpl01.c \ -glpmpl02.c \ -glpmpl03.c \ -glpmpl04.c \ -glpmpl05.c \ -glpmpl06.c \ -glpmps.c \ -glpnet03.c \ -glpnet04.c \ -glpnet05.c \ -glpnpp01.c \ -glpnpp02.c \ -glpnpp03.c \ -glpnpp04.c \ -glpnpp05.c \ -glpnpp06.c \ -glprgr.c \ -glpscl.c \ -glpsdf.c \ -glpspm.c \ -glpspx01.c \ -glpspx02.c \ -glpsql.c \ -glpssx01.c \ -glpssx02.c \ -glptsp.c \ -lux.c \ -amd/amd_1.c \ -amd/amd_2.c \ -amd/amd_aat.c \ -amd/amd_control.c \ -amd/amd_defaults.c \ -amd/amd_dump.c \ -amd/amd_info.c \ -amd/amd_order.c \ -amd/amd_post_tree.c \ -amd/amd_postorder.c \ -amd/amd_preprocess.c \ -amd/amd_valid.c \ -bflib/fhv.c \ -bflib/fhvint.c \ -bflib/ifu.c \ -bflib/luf.c \ -bflib/lufint.c \ -bflib/sgf.c \ -bflib/sva.c \ -cglib/cfg.c \ -cglib/cfg1.c \ -colamd/colamd.c \ -env/alloc.c \ -env/dlsup.c \ -env/env.c \ -env/error.c \ -env/stdout.c \ -env/stream.c \ -env/time.c \ -env/tls.c \ -minisat/minisat.c \ -misc/bignum.c \ -misc/dmp.c \ -misc/ffalg.c \ -misc/fp2rat.c \ -misc/gcd.c \ -misc/jd.c \ -misc/keller.c \ -misc/mc13d.c \ -misc/mc21a.c \ -misc/okalg.c \ -misc/qmd.c \ -misc/relax4.c \ -misc/rng.c \ -misc/rng1.c \ -misc/round2n.c \ -misc/str2int.c \ -misc/str2num.c \ -misc/strspx.c \ -misc/strtrim.c \ -misc/triang.c \ -misc/wclique.c \ -misc/wclique1.c \ -proxy/proxy.c \ -proxy/proxy1.c \ -zlib/adler32.c \ -zlib/compress.c \ -zlib/crc32.c \ -zlib/deflate.c \ -zlib/gzclose.c \ -zlib/gzlib.c \ -zlib/gzread.c \ -zlib/gzwrite.c \ -zlib/inffast.c \ -zlib/inflate.c \ -zlib/inftrees.c \ -zlib/trees.c \ -zlib/uncompr.c \ -zlib/zio.c \ -zlib/zutil.c - -## eof ## diff --git a/resources/3rdparty/glpk-4.53/src/Makefile.in b/resources/3rdparty/glpk-4.53/src/Makefile.in deleted file mode 100644 index caab6d29a..000000000 --- a/resources/3rdparty/glpk-4.53/src/Makefile.in +++ /dev/null @@ -1,1949 +0,0 @@ -# Makefile.in generated by automake 1.12.5 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2012 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - -VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ - esac; \ - test $$am__dry = yes; \ - } -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src -DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(top_srcdir)/depcomp -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" -LTLIBRARIES = $(lib_LTLIBRARIES) -libglpk_la_LIBADD = -am_libglpk_la_OBJECTS = libglpk_la-avl.lo libglpk_la-bfd.lo \ - libglpk_la-bfx.lo libglpk_la-glpapi01.lo \ - libglpk_la-glpapi02.lo libglpk_la-glpapi03.lo \ - libglpk_la-glpapi04.lo libglpk_la-glpapi05.lo \ - libglpk_la-glpapi06.lo libglpk_la-glpapi07.lo \ - libglpk_la-glpapi08.lo libglpk_la-glpapi09.lo \ - libglpk_la-glpapi10.lo libglpk_la-glpapi11.lo \ - libglpk_la-glpapi12.lo libglpk_la-glpapi13.lo \ - libglpk_la-glpapi14.lo libglpk_la-glpapi15.lo \ - libglpk_la-glpapi16.lo libglpk_la-glpapi17.lo \ - libglpk_la-glpapi18.lo libglpk_la-glpapi19.lo \ - libglpk_la-glpapi20.lo libglpk_la-glpapi21.lo \ - libglpk_la-glpcpx.lo libglpk_la-glpdmx.lo libglpk_la-glpgmp.lo \ - libglpk_la-glphbm.lo libglpk_la-glpini01.lo \ - libglpk_la-glpini02.lo libglpk_la-glpios01.lo \ - libglpk_la-glpios02.lo libglpk_la-glpios03.lo \ - libglpk_la-glpios04.lo libglpk_la-glpios05.lo \ - libglpk_la-glpios06.lo libglpk_la-glpios07.lo \ - libglpk_la-glpios08.lo libglpk_la-glpios09.lo \ - libglpk_la-glpios10.lo libglpk_la-glpios11.lo \ - libglpk_la-glpios12.lo libglpk_la-glpipm.lo \ - libglpk_la-glplpf.lo libglpk_la-glpmat.lo \ - libglpk_la-glpmpl01.lo libglpk_la-glpmpl02.lo \ - libglpk_la-glpmpl03.lo libglpk_la-glpmpl04.lo \ - libglpk_la-glpmpl05.lo libglpk_la-glpmpl06.lo \ - libglpk_la-glpmps.lo libglpk_la-glpnet03.lo \ - libglpk_la-glpnet04.lo libglpk_la-glpnet05.lo \ - libglpk_la-glpnpp01.lo libglpk_la-glpnpp02.lo \ - libglpk_la-glpnpp03.lo libglpk_la-glpnpp04.lo \ - libglpk_la-glpnpp05.lo libglpk_la-glpnpp06.lo \ - libglpk_la-glprgr.lo libglpk_la-glpscl.lo libglpk_la-glpsdf.lo \ - libglpk_la-glpspm.lo libglpk_la-glpspx01.lo \ - libglpk_la-glpspx02.lo libglpk_la-glpsql.lo \ - libglpk_la-glpssx01.lo libglpk_la-glpssx02.lo \ - libglpk_la-glptsp.lo libglpk_la-lux.lo libglpk_la-amd_1.lo \ - libglpk_la-amd_2.lo libglpk_la-amd_aat.lo \ - libglpk_la-amd_control.lo libglpk_la-amd_defaults.lo \ - libglpk_la-amd_dump.lo libglpk_la-amd_info.lo \ - libglpk_la-amd_order.lo libglpk_la-amd_post_tree.lo \ - libglpk_la-amd_postorder.lo libglpk_la-amd_preprocess.lo \ - libglpk_la-amd_valid.lo libglpk_la-fhv.lo libglpk_la-fhvint.lo \ - libglpk_la-ifu.lo libglpk_la-luf.lo libglpk_la-lufint.lo \ - libglpk_la-sgf.lo libglpk_la-sva.lo libglpk_la-cfg.lo \ - libglpk_la-cfg1.lo libglpk_la-colamd.lo libglpk_la-alloc.lo \ - libglpk_la-dlsup.lo libglpk_la-env.lo libglpk_la-error.lo \ - libglpk_la-stdout.lo libglpk_la-stream.lo libglpk_la-time.lo \ - libglpk_la-tls.lo libglpk_la-minisat.lo libglpk_la-bignum.lo \ - libglpk_la-dmp.lo libglpk_la-ffalg.lo libglpk_la-fp2rat.lo \ - libglpk_la-gcd.lo libglpk_la-jd.lo libglpk_la-keller.lo \ - libglpk_la-mc13d.lo libglpk_la-mc21a.lo libglpk_la-okalg.lo \ - libglpk_la-qmd.lo libglpk_la-relax4.lo libglpk_la-rng.lo \ - libglpk_la-rng1.lo libglpk_la-round2n.lo libglpk_la-str2int.lo \ - libglpk_la-str2num.lo libglpk_la-strspx.lo \ - libglpk_la-strtrim.lo libglpk_la-triang.lo \ - libglpk_la-wclique.lo libglpk_la-wclique1.lo \ - libglpk_la-proxy.lo libglpk_la-proxy1.lo libglpk_la-adler32.lo \ - libglpk_la-compress.lo libglpk_la-crc32.lo \ - libglpk_la-deflate.lo libglpk_la-gzclose.lo \ - libglpk_la-gzlib.lo libglpk_la-gzread.lo libglpk_la-gzwrite.lo \ - libglpk_la-inffast.lo libglpk_la-inflate.lo \ - libglpk_la-inftrees.lo libglpk_la-trees.lo \ - libglpk_la-uncompr.lo libglpk_la-zio.lo libglpk_la-zutil.lo -libglpk_la_OBJECTS = $(am_libglpk_la_OBJECTS) -libglpk_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libglpk_la_LDFLAGS) $(LDFLAGS) -o $@ -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(libglpk_la_SOURCES) -DIST_SOURCES = $(libglpk_la_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -HEADERS = $(include_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -include_HEADERS = glpk.h -lib_LTLIBRARIES = libglpk.la -libglpk_la_CPPFLAGS = \ --I$(srcdir) \ --I$(srcdir)/amd \ --I$(srcdir)/bflib \ --I$(srcdir)/cglib \ --I$(srcdir)/colamd \ --I$(srcdir)/env \ --I$(srcdir)/minisat \ --I$(srcdir)/misc \ --I$(srcdir)/proxy \ --I$(srcdir)/zlib - -libglpk_la_LDFLAGS = \ --version-info 37:0:1 \ --export-symbols-regex '^glp_*' - -libglpk_la_SOURCES = \ -avl.c \ -bfd.c \ -bfx.c \ -glpapi01.c \ -glpapi02.c \ -glpapi03.c \ -glpapi04.c \ -glpapi05.c \ -glpapi06.c \ -glpapi07.c \ -glpapi08.c \ -glpapi09.c \ -glpapi10.c \ -glpapi11.c \ -glpapi12.c \ -glpapi13.c \ -glpapi14.c \ -glpapi15.c \ -glpapi16.c \ -glpapi17.c \ -glpapi18.c \ -glpapi19.c \ -glpapi20.c \ -glpapi21.c \ -glpcpx.c \ -glpdmx.c \ -glpgmp.c \ -glphbm.c \ -glpini01.c \ -glpini02.c \ -glpios01.c \ -glpios02.c \ -glpios03.c \ -glpios04.c \ -glpios05.c \ -glpios06.c \ -glpios07.c \ -glpios08.c \ -glpios09.c \ -glpios10.c \ -glpios11.c \ -glpios12.c \ -glpipm.c \ -glplpf.c \ -glpmat.c \ -glpmpl01.c \ -glpmpl02.c \ -glpmpl03.c \ -glpmpl04.c \ -glpmpl05.c \ -glpmpl06.c \ -glpmps.c \ -glpnet03.c \ -glpnet04.c \ -glpnet05.c \ -glpnpp01.c \ -glpnpp02.c \ -glpnpp03.c \ -glpnpp04.c \ -glpnpp05.c \ -glpnpp06.c \ -glprgr.c \ -glpscl.c \ -glpsdf.c \ -glpspm.c \ -glpspx01.c \ -glpspx02.c \ -glpsql.c \ -glpssx01.c \ -glpssx02.c \ -glptsp.c \ -lux.c \ -amd/amd_1.c \ -amd/amd_2.c \ -amd/amd_aat.c \ -amd/amd_control.c \ -amd/amd_defaults.c \ -amd/amd_dump.c \ -amd/amd_info.c \ -amd/amd_order.c \ -amd/amd_post_tree.c \ -amd/amd_postorder.c \ -amd/amd_preprocess.c \ -amd/amd_valid.c \ -bflib/fhv.c \ -bflib/fhvint.c \ -bflib/ifu.c \ -bflib/luf.c \ -bflib/lufint.c \ -bflib/sgf.c \ -bflib/sva.c \ -cglib/cfg.c \ -cglib/cfg1.c \ -colamd/colamd.c \ -env/alloc.c \ -env/dlsup.c \ -env/env.c \ -env/error.c \ -env/stdout.c \ -env/stream.c \ -env/time.c \ -env/tls.c \ -minisat/minisat.c \ -misc/bignum.c \ -misc/dmp.c \ -misc/ffalg.c \ -misc/fp2rat.c \ -misc/gcd.c \ -misc/jd.c \ -misc/keller.c \ -misc/mc13d.c \ -misc/mc21a.c \ -misc/okalg.c \ -misc/qmd.c \ -misc/relax4.c \ -misc/rng.c \ -misc/rng1.c \ -misc/round2n.c \ -misc/str2int.c \ -misc/str2num.c \ -misc/strspx.c \ -misc/strtrim.c \ -misc/triang.c \ -misc/wclique.c \ -misc/wclique1.c \ -proxy/proxy.c \ -proxy/proxy1.c \ -zlib/adler32.c \ -zlib/compress.c \ -zlib/crc32.c \ -zlib/deflate.c \ -zlib/gzclose.c \ -zlib/gzlib.c \ -zlib/gzread.c \ -zlib/gzwrite.c \ -zlib/inffast.c \ -zlib/inflate.c \ -zlib/inftrees.c \ -zlib/trees.c \ -zlib/uncompr.c \ -zlib/zio.c \ -zlib/zutil.c - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } -libglpk.la: $(libglpk_la_OBJECTS) $(libglpk_la_DEPENDENCIES) $(EXTRA_libglpk_la_DEPENDENCIES) - $(libglpk_la_LINK) -rpath $(libdir) $(libglpk_la_OBJECTS) $(libglpk_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-adler32.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-alloc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_1.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_2.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_aat.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_control.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_defaults.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_dump.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_info.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_order.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_post_tree.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_postorder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_preprocess.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-amd_valid.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-avl.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-bfd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-bfx.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-bignum.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-cfg.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-cfg1.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-colamd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-compress.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-crc32.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-deflate.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-dlsup.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-dmp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-env.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-error.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-ffalg.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-fhv.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-fhvint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-fp2rat.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-gcd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi01.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi02.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi03.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi04.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi05.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi06.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi07.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi08.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi09.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi10.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi11.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi12.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi13.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi14.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi15.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi16.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi17.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi18.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi19.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi20.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpapi21.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpcpx.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpdmx.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpgmp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glphbm.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpini01.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpini02.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios01.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios02.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios03.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios04.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios05.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios06.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios07.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios08.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios09.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios10.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios11.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpios12.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpipm.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glplpf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmat.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmpl01.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmpl02.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmpl03.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmpl04.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmpl05.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmpl06.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpmps.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnet03.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnet04.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnet05.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnpp01.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnpp02.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnpp03.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnpp04.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnpp05.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpnpp06.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glprgr.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpscl.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpsdf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpspm.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpspx01.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpspx02.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpsql.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpssx01.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glpssx02.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-glptsp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-gzclose.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-gzlib.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-gzread.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-gzwrite.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-ifu.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-inffast.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-inflate.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-inftrees.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-jd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-keller.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-luf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-lufint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-lux.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-mc13d.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-mc21a.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-minisat.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-okalg.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-proxy.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-proxy1.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-qmd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-relax4.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-rng.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-rng1.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-round2n.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-sgf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-stdout.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-str2int.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-str2num.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-stream.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-strspx.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-strtrim.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-sva.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-time.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-tls.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-trees.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-triang.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-uncompr.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-wclique.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-wclique1.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-zio.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libglpk_la-zutil.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -libglpk_la-avl.lo: avl.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-avl.lo -MD -MP -MF $(DEPDIR)/libglpk_la-avl.Tpo -c -o libglpk_la-avl.lo `test -f 'avl.c' || echo '$(srcdir)/'`avl.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-avl.Tpo $(DEPDIR)/libglpk_la-avl.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='avl.c' object='libglpk_la-avl.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-avl.lo `test -f 'avl.c' || echo '$(srcdir)/'`avl.c - -libglpk_la-bfd.lo: bfd.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-bfd.lo -MD -MP -MF $(DEPDIR)/libglpk_la-bfd.Tpo -c -o libglpk_la-bfd.lo `test -f 'bfd.c' || echo '$(srcdir)/'`bfd.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-bfd.Tpo $(DEPDIR)/libglpk_la-bfd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bfd.c' object='libglpk_la-bfd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-bfd.lo `test -f 'bfd.c' || echo '$(srcdir)/'`bfd.c - -libglpk_la-bfx.lo: bfx.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-bfx.lo -MD -MP -MF $(DEPDIR)/libglpk_la-bfx.Tpo -c -o libglpk_la-bfx.lo `test -f 'bfx.c' || echo '$(srcdir)/'`bfx.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-bfx.Tpo $(DEPDIR)/libglpk_la-bfx.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bfx.c' object='libglpk_la-bfx.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-bfx.lo `test -f 'bfx.c' || echo '$(srcdir)/'`bfx.c - -libglpk_la-glpapi01.lo: glpapi01.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi01.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi01.Tpo -c -o libglpk_la-glpapi01.lo `test -f 'glpapi01.c' || echo '$(srcdir)/'`glpapi01.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi01.Tpo $(DEPDIR)/libglpk_la-glpapi01.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi01.c' object='libglpk_la-glpapi01.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi01.lo `test -f 'glpapi01.c' || echo '$(srcdir)/'`glpapi01.c - -libglpk_la-glpapi02.lo: glpapi02.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi02.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi02.Tpo -c -o libglpk_la-glpapi02.lo `test -f 'glpapi02.c' || echo '$(srcdir)/'`glpapi02.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi02.Tpo $(DEPDIR)/libglpk_la-glpapi02.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi02.c' object='libglpk_la-glpapi02.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi02.lo `test -f 'glpapi02.c' || echo '$(srcdir)/'`glpapi02.c - -libglpk_la-glpapi03.lo: glpapi03.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi03.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi03.Tpo -c -o libglpk_la-glpapi03.lo `test -f 'glpapi03.c' || echo '$(srcdir)/'`glpapi03.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi03.Tpo $(DEPDIR)/libglpk_la-glpapi03.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi03.c' object='libglpk_la-glpapi03.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi03.lo `test -f 'glpapi03.c' || echo '$(srcdir)/'`glpapi03.c - -libglpk_la-glpapi04.lo: glpapi04.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi04.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi04.Tpo -c -o libglpk_la-glpapi04.lo `test -f 'glpapi04.c' || echo '$(srcdir)/'`glpapi04.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi04.Tpo $(DEPDIR)/libglpk_la-glpapi04.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi04.c' object='libglpk_la-glpapi04.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi04.lo `test -f 'glpapi04.c' || echo '$(srcdir)/'`glpapi04.c - -libglpk_la-glpapi05.lo: glpapi05.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi05.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi05.Tpo -c -o libglpk_la-glpapi05.lo `test -f 'glpapi05.c' || echo '$(srcdir)/'`glpapi05.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi05.Tpo $(DEPDIR)/libglpk_la-glpapi05.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi05.c' object='libglpk_la-glpapi05.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi05.lo `test -f 'glpapi05.c' || echo '$(srcdir)/'`glpapi05.c - -libglpk_la-glpapi06.lo: glpapi06.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi06.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi06.Tpo -c -o libglpk_la-glpapi06.lo `test -f 'glpapi06.c' || echo '$(srcdir)/'`glpapi06.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi06.Tpo $(DEPDIR)/libglpk_la-glpapi06.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi06.c' object='libglpk_la-glpapi06.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi06.lo `test -f 'glpapi06.c' || echo '$(srcdir)/'`glpapi06.c - -libglpk_la-glpapi07.lo: glpapi07.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi07.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi07.Tpo -c -o libglpk_la-glpapi07.lo `test -f 'glpapi07.c' || echo '$(srcdir)/'`glpapi07.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi07.Tpo $(DEPDIR)/libglpk_la-glpapi07.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi07.c' object='libglpk_la-glpapi07.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi07.lo `test -f 'glpapi07.c' || echo '$(srcdir)/'`glpapi07.c - -libglpk_la-glpapi08.lo: glpapi08.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi08.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi08.Tpo -c -o libglpk_la-glpapi08.lo `test -f 'glpapi08.c' || echo '$(srcdir)/'`glpapi08.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi08.Tpo $(DEPDIR)/libglpk_la-glpapi08.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi08.c' object='libglpk_la-glpapi08.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi08.lo `test -f 'glpapi08.c' || echo '$(srcdir)/'`glpapi08.c - -libglpk_la-glpapi09.lo: glpapi09.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi09.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi09.Tpo -c -o libglpk_la-glpapi09.lo `test -f 'glpapi09.c' || echo '$(srcdir)/'`glpapi09.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi09.Tpo $(DEPDIR)/libglpk_la-glpapi09.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi09.c' object='libglpk_la-glpapi09.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi09.lo `test -f 'glpapi09.c' || echo '$(srcdir)/'`glpapi09.c - -libglpk_la-glpapi10.lo: glpapi10.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi10.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi10.Tpo -c -o libglpk_la-glpapi10.lo `test -f 'glpapi10.c' || echo '$(srcdir)/'`glpapi10.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi10.Tpo $(DEPDIR)/libglpk_la-glpapi10.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi10.c' object='libglpk_la-glpapi10.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi10.lo `test -f 'glpapi10.c' || echo '$(srcdir)/'`glpapi10.c - -libglpk_la-glpapi11.lo: glpapi11.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi11.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi11.Tpo -c -o libglpk_la-glpapi11.lo `test -f 'glpapi11.c' || echo '$(srcdir)/'`glpapi11.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi11.Tpo $(DEPDIR)/libglpk_la-glpapi11.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi11.c' object='libglpk_la-glpapi11.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi11.lo `test -f 'glpapi11.c' || echo '$(srcdir)/'`glpapi11.c - -libglpk_la-glpapi12.lo: glpapi12.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi12.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi12.Tpo -c -o libglpk_la-glpapi12.lo `test -f 'glpapi12.c' || echo '$(srcdir)/'`glpapi12.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi12.Tpo $(DEPDIR)/libglpk_la-glpapi12.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi12.c' object='libglpk_la-glpapi12.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi12.lo `test -f 'glpapi12.c' || echo '$(srcdir)/'`glpapi12.c - -libglpk_la-glpapi13.lo: glpapi13.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi13.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi13.Tpo -c -o libglpk_la-glpapi13.lo `test -f 'glpapi13.c' || echo '$(srcdir)/'`glpapi13.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi13.Tpo $(DEPDIR)/libglpk_la-glpapi13.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi13.c' object='libglpk_la-glpapi13.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi13.lo `test -f 'glpapi13.c' || echo '$(srcdir)/'`glpapi13.c - -libglpk_la-glpapi14.lo: glpapi14.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi14.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi14.Tpo -c -o libglpk_la-glpapi14.lo `test -f 'glpapi14.c' || echo '$(srcdir)/'`glpapi14.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi14.Tpo $(DEPDIR)/libglpk_la-glpapi14.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi14.c' object='libglpk_la-glpapi14.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi14.lo `test -f 'glpapi14.c' || echo '$(srcdir)/'`glpapi14.c - -libglpk_la-glpapi15.lo: glpapi15.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi15.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi15.Tpo -c -o libglpk_la-glpapi15.lo `test -f 'glpapi15.c' || echo '$(srcdir)/'`glpapi15.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi15.Tpo $(DEPDIR)/libglpk_la-glpapi15.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi15.c' object='libglpk_la-glpapi15.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi15.lo `test -f 'glpapi15.c' || echo '$(srcdir)/'`glpapi15.c - -libglpk_la-glpapi16.lo: glpapi16.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi16.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi16.Tpo -c -o libglpk_la-glpapi16.lo `test -f 'glpapi16.c' || echo '$(srcdir)/'`glpapi16.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi16.Tpo $(DEPDIR)/libglpk_la-glpapi16.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi16.c' object='libglpk_la-glpapi16.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi16.lo `test -f 'glpapi16.c' || echo '$(srcdir)/'`glpapi16.c - -libglpk_la-glpapi17.lo: glpapi17.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi17.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi17.Tpo -c -o libglpk_la-glpapi17.lo `test -f 'glpapi17.c' || echo '$(srcdir)/'`glpapi17.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi17.Tpo $(DEPDIR)/libglpk_la-glpapi17.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi17.c' object='libglpk_la-glpapi17.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi17.lo `test -f 'glpapi17.c' || echo '$(srcdir)/'`glpapi17.c - -libglpk_la-glpapi18.lo: glpapi18.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi18.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi18.Tpo -c -o libglpk_la-glpapi18.lo `test -f 'glpapi18.c' || echo '$(srcdir)/'`glpapi18.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi18.Tpo $(DEPDIR)/libglpk_la-glpapi18.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi18.c' object='libglpk_la-glpapi18.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi18.lo `test -f 'glpapi18.c' || echo '$(srcdir)/'`glpapi18.c - -libglpk_la-glpapi19.lo: glpapi19.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi19.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi19.Tpo -c -o libglpk_la-glpapi19.lo `test -f 'glpapi19.c' || echo '$(srcdir)/'`glpapi19.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi19.Tpo $(DEPDIR)/libglpk_la-glpapi19.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi19.c' object='libglpk_la-glpapi19.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi19.lo `test -f 'glpapi19.c' || echo '$(srcdir)/'`glpapi19.c - -libglpk_la-glpapi20.lo: glpapi20.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi20.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi20.Tpo -c -o libglpk_la-glpapi20.lo `test -f 'glpapi20.c' || echo '$(srcdir)/'`glpapi20.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi20.Tpo $(DEPDIR)/libglpk_la-glpapi20.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi20.c' object='libglpk_la-glpapi20.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi20.lo `test -f 'glpapi20.c' || echo '$(srcdir)/'`glpapi20.c - -libglpk_la-glpapi21.lo: glpapi21.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpapi21.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpapi21.Tpo -c -o libglpk_la-glpapi21.lo `test -f 'glpapi21.c' || echo '$(srcdir)/'`glpapi21.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpapi21.Tpo $(DEPDIR)/libglpk_la-glpapi21.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpapi21.c' object='libglpk_la-glpapi21.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpapi21.lo `test -f 'glpapi21.c' || echo '$(srcdir)/'`glpapi21.c - -libglpk_la-glpcpx.lo: glpcpx.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpcpx.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpcpx.Tpo -c -o libglpk_la-glpcpx.lo `test -f 'glpcpx.c' || echo '$(srcdir)/'`glpcpx.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpcpx.Tpo $(DEPDIR)/libglpk_la-glpcpx.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpcpx.c' object='libglpk_la-glpcpx.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpcpx.lo `test -f 'glpcpx.c' || echo '$(srcdir)/'`glpcpx.c - -libglpk_la-glpdmx.lo: glpdmx.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpdmx.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpdmx.Tpo -c -o libglpk_la-glpdmx.lo `test -f 'glpdmx.c' || echo '$(srcdir)/'`glpdmx.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpdmx.Tpo $(DEPDIR)/libglpk_la-glpdmx.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpdmx.c' object='libglpk_la-glpdmx.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpdmx.lo `test -f 'glpdmx.c' || echo '$(srcdir)/'`glpdmx.c - -libglpk_la-glpgmp.lo: glpgmp.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpgmp.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpgmp.Tpo -c -o libglpk_la-glpgmp.lo `test -f 'glpgmp.c' || echo '$(srcdir)/'`glpgmp.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpgmp.Tpo $(DEPDIR)/libglpk_la-glpgmp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpgmp.c' object='libglpk_la-glpgmp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpgmp.lo `test -f 'glpgmp.c' || echo '$(srcdir)/'`glpgmp.c - -libglpk_la-glphbm.lo: glphbm.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glphbm.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glphbm.Tpo -c -o libglpk_la-glphbm.lo `test -f 'glphbm.c' || echo '$(srcdir)/'`glphbm.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glphbm.Tpo $(DEPDIR)/libglpk_la-glphbm.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glphbm.c' object='libglpk_la-glphbm.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glphbm.lo `test -f 'glphbm.c' || echo '$(srcdir)/'`glphbm.c - -libglpk_la-glpini01.lo: glpini01.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpini01.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpini01.Tpo -c -o libglpk_la-glpini01.lo `test -f 'glpini01.c' || echo '$(srcdir)/'`glpini01.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpini01.Tpo $(DEPDIR)/libglpk_la-glpini01.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpini01.c' object='libglpk_la-glpini01.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpini01.lo `test -f 'glpini01.c' || echo '$(srcdir)/'`glpini01.c - -libglpk_la-glpini02.lo: glpini02.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpini02.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpini02.Tpo -c -o libglpk_la-glpini02.lo `test -f 'glpini02.c' || echo '$(srcdir)/'`glpini02.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpini02.Tpo $(DEPDIR)/libglpk_la-glpini02.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpini02.c' object='libglpk_la-glpini02.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpini02.lo `test -f 'glpini02.c' || echo '$(srcdir)/'`glpini02.c - -libglpk_la-glpios01.lo: glpios01.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios01.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios01.Tpo -c -o libglpk_la-glpios01.lo `test -f 'glpios01.c' || echo '$(srcdir)/'`glpios01.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios01.Tpo $(DEPDIR)/libglpk_la-glpios01.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios01.c' object='libglpk_la-glpios01.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios01.lo `test -f 'glpios01.c' || echo '$(srcdir)/'`glpios01.c - -libglpk_la-glpios02.lo: glpios02.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios02.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios02.Tpo -c -o libglpk_la-glpios02.lo `test -f 'glpios02.c' || echo '$(srcdir)/'`glpios02.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios02.Tpo $(DEPDIR)/libglpk_la-glpios02.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios02.c' object='libglpk_la-glpios02.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios02.lo `test -f 'glpios02.c' || echo '$(srcdir)/'`glpios02.c - -libglpk_la-glpios03.lo: glpios03.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios03.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios03.Tpo -c -o libglpk_la-glpios03.lo `test -f 'glpios03.c' || echo '$(srcdir)/'`glpios03.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios03.Tpo $(DEPDIR)/libglpk_la-glpios03.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios03.c' object='libglpk_la-glpios03.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios03.lo `test -f 'glpios03.c' || echo '$(srcdir)/'`glpios03.c - -libglpk_la-glpios04.lo: glpios04.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios04.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios04.Tpo -c -o libglpk_la-glpios04.lo `test -f 'glpios04.c' || echo '$(srcdir)/'`glpios04.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios04.Tpo $(DEPDIR)/libglpk_la-glpios04.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios04.c' object='libglpk_la-glpios04.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios04.lo `test -f 'glpios04.c' || echo '$(srcdir)/'`glpios04.c - -libglpk_la-glpios05.lo: glpios05.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios05.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios05.Tpo -c -o libglpk_la-glpios05.lo `test -f 'glpios05.c' || echo '$(srcdir)/'`glpios05.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios05.Tpo $(DEPDIR)/libglpk_la-glpios05.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios05.c' object='libglpk_la-glpios05.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios05.lo `test -f 'glpios05.c' || echo '$(srcdir)/'`glpios05.c - -libglpk_la-glpios06.lo: glpios06.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios06.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios06.Tpo -c -o libglpk_la-glpios06.lo `test -f 'glpios06.c' || echo '$(srcdir)/'`glpios06.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios06.Tpo $(DEPDIR)/libglpk_la-glpios06.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios06.c' object='libglpk_la-glpios06.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios06.lo `test -f 'glpios06.c' || echo '$(srcdir)/'`glpios06.c - -libglpk_la-glpios07.lo: glpios07.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios07.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios07.Tpo -c -o libglpk_la-glpios07.lo `test -f 'glpios07.c' || echo '$(srcdir)/'`glpios07.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios07.Tpo $(DEPDIR)/libglpk_la-glpios07.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios07.c' object='libglpk_la-glpios07.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios07.lo `test -f 'glpios07.c' || echo '$(srcdir)/'`glpios07.c - -libglpk_la-glpios08.lo: glpios08.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios08.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios08.Tpo -c -o libglpk_la-glpios08.lo `test -f 'glpios08.c' || echo '$(srcdir)/'`glpios08.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios08.Tpo $(DEPDIR)/libglpk_la-glpios08.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios08.c' object='libglpk_la-glpios08.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios08.lo `test -f 'glpios08.c' || echo '$(srcdir)/'`glpios08.c - -libglpk_la-glpios09.lo: glpios09.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios09.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios09.Tpo -c -o libglpk_la-glpios09.lo `test -f 'glpios09.c' || echo '$(srcdir)/'`glpios09.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios09.Tpo $(DEPDIR)/libglpk_la-glpios09.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios09.c' object='libglpk_la-glpios09.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios09.lo `test -f 'glpios09.c' || echo '$(srcdir)/'`glpios09.c - -libglpk_la-glpios10.lo: glpios10.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios10.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios10.Tpo -c -o libglpk_la-glpios10.lo `test -f 'glpios10.c' || echo '$(srcdir)/'`glpios10.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios10.Tpo $(DEPDIR)/libglpk_la-glpios10.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios10.c' object='libglpk_la-glpios10.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios10.lo `test -f 'glpios10.c' || echo '$(srcdir)/'`glpios10.c - -libglpk_la-glpios11.lo: glpios11.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios11.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios11.Tpo -c -o libglpk_la-glpios11.lo `test -f 'glpios11.c' || echo '$(srcdir)/'`glpios11.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios11.Tpo $(DEPDIR)/libglpk_la-glpios11.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios11.c' object='libglpk_la-glpios11.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios11.lo `test -f 'glpios11.c' || echo '$(srcdir)/'`glpios11.c - -libglpk_la-glpios12.lo: glpios12.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpios12.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpios12.Tpo -c -o libglpk_la-glpios12.lo `test -f 'glpios12.c' || echo '$(srcdir)/'`glpios12.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpios12.Tpo $(DEPDIR)/libglpk_la-glpios12.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpios12.c' object='libglpk_la-glpios12.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpios12.lo `test -f 'glpios12.c' || echo '$(srcdir)/'`glpios12.c - -libglpk_la-glpipm.lo: glpipm.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpipm.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpipm.Tpo -c -o libglpk_la-glpipm.lo `test -f 'glpipm.c' || echo '$(srcdir)/'`glpipm.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpipm.Tpo $(DEPDIR)/libglpk_la-glpipm.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpipm.c' object='libglpk_la-glpipm.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpipm.lo `test -f 'glpipm.c' || echo '$(srcdir)/'`glpipm.c - -libglpk_la-glplpf.lo: glplpf.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glplpf.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glplpf.Tpo -c -o libglpk_la-glplpf.lo `test -f 'glplpf.c' || echo '$(srcdir)/'`glplpf.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glplpf.Tpo $(DEPDIR)/libglpk_la-glplpf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glplpf.c' object='libglpk_la-glplpf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glplpf.lo `test -f 'glplpf.c' || echo '$(srcdir)/'`glplpf.c - -libglpk_la-glpmat.lo: glpmat.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmat.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmat.Tpo -c -o libglpk_la-glpmat.lo `test -f 'glpmat.c' || echo '$(srcdir)/'`glpmat.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmat.Tpo $(DEPDIR)/libglpk_la-glpmat.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmat.c' object='libglpk_la-glpmat.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmat.lo `test -f 'glpmat.c' || echo '$(srcdir)/'`glpmat.c - -libglpk_la-glpmpl01.lo: glpmpl01.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmpl01.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmpl01.Tpo -c -o libglpk_la-glpmpl01.lo `test -f 'glpmpl01.c' || echo '$(srcdir)/'`glpmpl01.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmpl01.Tpo $(DEPDIR)/libglpk_la-glpmpl01.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmpl01.c' object='libglpk_la-glpmpl01.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmpl01.lo `test -f 'glpmpl01.c' || echo '$(srcdir)/'`glpmpl01.c - -libglpk_la-glpmpl02.lo: glpmpl02.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmpl02.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmpl02.Tpo -c -o libglpk_la-glpmpl02.lo `test -f 'glpmpl02.c' || echo '$(srcdir)/'`glpmpl02.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmpl02.Tpo $(DEPDIR)/libglpk_la-glpmpl02.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmpl02.c' object='libglpk_la-glpmpl02.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmpl02.lo `test -f 'glpmpl02.c' || echo '$(srcdir)/'`glpmpl02.c - -libglpk_la-glpmpl03.lo: glpmpl03.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmpl03.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmpl03.Tpo -c -o libglpk_la-glpmpl03.lo `test -f 'glpmpl03.c' || echo '$(srcdir)/'`glpmpl03.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmpl03.Tpo $(DEPDIR)/libglpk_la-glpmpl03.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmpl03.c' object='libglpk_la-glpmpl03.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmpl03.lo `test -f 'glpmpl03.c' || echo '$(srcdir)/'`glpmpl03.c - -libglpk_la-glpmpl04.lo: glpmpl04.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmpl04.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmpl04.Tpo -c -o libglpk_la-glpmpl04.lo `test -f 'glpmpl04.c' || echo '$(srcdir)/'`glpmpl04.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmpl04.Tpo $(DEPDIR)/libglpk_la-glpmpl04.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmpl04.c' object='libglpk_la-glpmpl04.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmpl04.lo `test -f 'glpmpl04.c' || echo '$(srcdir)/'`glpmpl04.c - -libglpk_la-glpmpl05.lo: glpmpl05.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmpl05.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmpl05.Tpo -c -o libglpk_la-glpmpl05.lo `test -f 'glpmpl05.c' || echo '$(srcdir)/'`glpmpl05.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmpl05.Tpo $(DEPDIR)/libglpk_la-glpmpl05.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmpl05.c' object='libglpk_la-glpmpl05.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmpl05.lo `test -f 'glpmpl05.c' || echo '$(srcdir)/'`glpmpl05.c - -libglpk_la-glpmpl06.lo: glpmpl06.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmpl06.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmpl06.Tpo -c -o libglpk_la-glpmpl06.lo `test -f 'glpmpl06.c' || echo '$(srcdir)/'`glpmpl06.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmpl06.Tpo $(DEPDIR)/libglpk_la-glpmpl06.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmpl06.c' object='libglpk_la-glpmpl06.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmpl06.lo `test -f 'glpmpl06.c' || echo '$(srcdir)/'`glpmpl06.c - -libglpk_la-glpmps.lo: glpmps.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpmps.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpmps.Tpo -c -o libglpk_la-glpmps.lo `test -f 'glpmps.c' || echo '$(srcdir)/'`glpmps.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpmps.Tpo $(DEPDIR)/libglpk_la-glpmps.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpmps.c' object='libglpk_la-glpmps.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpmps.lo `test -f 'glpmps.c' || echo '$(srcdir)/'`glpmps.c - -libglpk_la-glpnet03.lo: glpnet03.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnet03.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnet03.Tpo -c -o libglpk_la-glpnet03.lo `test -f 'glpnet03.c' || echo '$(srcdir)/'`glpnet03.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnet03.Tpo $(DEPDIR)/libglpk_la-glpnet03.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnet03.c' object='libglpk_la-glpnet03.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnet03.lo `test -f 'glpnet03.c' || echo '$(srcdir)/'`glpnet03.c - -libglpk_la-glpnet04.lo: glpnet04.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnet04.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnet04.Tpo -c -o libglpk_la-glpnet04.lo `test -f 'glpnet04.c' || echo '$(srcdir)/'`glpnet04.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnet04.Tpo $(DEPDIR)/libglpk_la-glpnet04.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnet04.c' object='libglpk_la-glpnet04.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnet04.lo `test -f 'glpnet04.c' || echo '$(srcdir)/'`glpnet04.c - -libglpk_la-glpnet05.lo: glpnet05.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnet05.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnet05.Tpo -c -o libglpk_la-glpnet05.lo `test -f 'glpnet05.c' || echo '$(srcdir)/'`glpnet05.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnet05.Tpo $(DEPDIR)/libglpk_la-glpnet05.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnet05.c' object='libglpk_la-glpnet05.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnet05.lo `test -f 'glpnet05.c' || echo '$(srcdir)/'`glpnet05.c - -libglpk_la-glpnpp01.lo: glpnpp01.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnpp01.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnpp01.Tpo -c -o libglpk_la-glpnpp01.lo `test -f 'glpnpp01.c' || echo '$(srcdir)/'`glpnpp01.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnpp01.Tpo $(DEPDIR)/libglpk_la-glpnpp01.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnpp01.c' object='libglpk_la-glpnpp01.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnpp01.lo `test -f 'glpnpp01.c' || echo '$(srcdir)/'`glpnpp01.c - -libglpk_la-glpnpp02.lo: glpnpp02.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnpp02.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnpp02.Tpo -c -o libglpk_la-glpnpp02.lo `test -f 'glpnpp02.c' || echo '$(srcdir)/'`glpnpp02.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnpp02.Tpo $(DEPDIR)/libglpk_la-glpnpp02.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnpp02.c' object='libglpk_la-glpnpp02.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnpp02.lo `test -f 'glpnpp02.c' || echo '$(srcdir)/'`glpnpp02.c - -libglpk_la-glpnpp03.lo: glpnpp03.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnpp03.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnpp03.Tpo -c -o libglpk_la-glpnpp03.lo `test -f 'glpnpp03.c' || echo '$(srcdir)/'`glpnpp03.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnpp03.Tpo $(DEPDIR)/libglpk_la-glpnpp03.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnpp03.c' object='libglpk_la-glpnpp03.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnpp03.lo `test -f 'glpnpp03.c' || echo '$(srcdir)/'`glpnpp03.c - -libglpk_la-glpnpp04.lo: glpnpp04.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnpp04.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnpp04.Tpo -c -o libglpk_la-glpnpp04.lo `test -f 'glpnpp04.c' || echo '$(srcdir)/'`glpnpp04.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnpp04.Tpo $(DEPDIR)/libglpk_la-glpnpp04.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnpp04.c' object='libglpk_la-glpnpp04.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnpp04.lo `test -f 'glpnpp04.c' || echo '$(srcdir)/'`glpnpp04.c - -libglpk_la-glpnpp05.lo: glpnpp05.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnpp05.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnpp05.Tpo -c -o libglpk_la-glpnpp05.lo `test -f 'glpnpp05.c' || echo '$(srcdir)/'`glpnpp05.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnpp05.Tpo $(DEPDIR)/libglpk_la-glpnpp05.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnpp05.c' object='libglpk_la-glpnpp05.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnpp05.lo `test -f 'glpnpp05.c' || echo '$(srcdir)/'`glpnpp05.c - -libglpk_la-glpnpp06.lo: glpnpp06.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpnpp06.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpnpp06.Tpo -c -o libglpk_la-glpnpp06.lo `test -f 'glpnpp06.c' || echo '$(srcdir)/'`glpnpp06.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpnpp06.Tpo $(DEPDIR)/libglpk_la-glpnpp06.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpnpp06.c' object='libglpk_la-glpnpp06.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpnpp06.lo `test -f 'glpnpp06.c' || echo '$(srcdir)/'`glpnpp06.c - -libglpk_la-glprgr.lo: glprgr.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glprgr.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glprgr.Tpo -c -o libglpk_la-glprgr.lo `test -f 'glprgr.c' || echo '$(srcdir)/'`glprgr.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glprgr.Tpo $(DEPDIR)/libglpk_la-glprgr.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glprgr.c' object='libglpk_la-glprgr.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glprgr.lo `test -f 'glprgr.c' || echo '$(srcdir)/'`glprgr.c - -libglpk_la-glpscl.lo: glpscl.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpscl.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpscl.Tpo -c -o libglpk_la-glpscl.lo `test -f 'glpscl.c' || echo '$(srcdir)/'`glpscl.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpscl.Tpo $(DEPDIR)/libglpk_la-glpscl.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpscl.c' object='libglpk_la-glpscl.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpscl.lo `test -f 'glpscl.c' || echo '$(srcdir)/'`glpscl.c - -libglpk_la-glpsdf.lo: glpsdf.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpsdf.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpsdf.Tpo -c -o libglpk_la-glpsdf.lo `test -f 'glpsdf.c' || echo '$(srcdir)/'`glpsdf.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpsdf.Tpo $(DEPDIR)/libglpk_la-glpsdf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpsdf.c' object='libglpk_la-glpsdf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpsdf.lo `test -f 'glpsdf.c' || echo '$(srcdir)/'`glpsdf.c - -libglpk_la-glpspm.lo: glpspm.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpspm.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpspm.Tpo -c -o libglpk_la-glpspm.lo `test -f 'glpspm.c' || echo '$(srcdir)/'`glpspm.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpspm.Tpo $(DEPDIR)/libglpk_la-glpspm.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpspm.c' object='libglpk_la-glpspm.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpspm.lo `test -f 'glpspm.c' || echo '$(srcdir)/'`glpspm.c - -libglpk_la-glpspx01.lo: glpspx01.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpspx01.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpspx01.Tpo -c -o libglpk_la-glpspx01.lo `test -f 'glpspx01.c' || echo '$(srcdir)/'`glpspx01.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpspx01.Tpo $(DEPDIR)/libglpk_la-glpspx01.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpspx01.c' object='libglpk_la-glpspx01.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpspx01.lo `test -f 'glpspx01.c' || echo '$(srcdir)/'`glpspx01.c - -libglpk_la-glpspx02.lo: glpspx02.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpspx02.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpspx02.Tpo -c -o libglpk_la-glpspx02.lo `test -f 'glpspx02.c' || echo '$(srcdir)/'`glpspx02.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpspx02.Tpo $(DEPDIR)/libglpk_la-glpspx02.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpspx02.c' object='libglpk_la-glpspx02.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpspx02.lo `test -f 'glpspx02.c' || echo '$(srcdir)/'`glpspx02.c - -libglpk_la-glpsql.lo: glpsql.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpsql.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpsql.Tpo -c -o libglpk_la-glpsql.lo `test -f 'glpsql.c' || echo '$(srcdir)/'`glpsql.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpsql.Tpo $(DEPDIR)/libglpk_la-glpsql.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpsql.c' object='libglpk_la-glpsql.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpsql.lo `test -f 'glpsql.c' || echo '$(srcdir)/'`glpsql.c - -libglpk_la-glpssx01.lo: glpssx01.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpssx01.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpssx01.Tpo -c -o libglpk_la-glpssx01.lo `test -f 'glpssx01.c' || echo '$(srcdir)/'`glpssx01.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpssx01.Tpo $(DEPDIR)/libglpk_la-glpssx01.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpssx01.c' object='libglpk_la-glpssx01.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpssx01.lo `test -f 'glpssx01.c' || echo '$(srcdir)/'`glpssx01.c - -libglpk_la-glpssx02.lo: glpssx02.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glpssx02.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glpssx02.Tpo -c -o libglpk_la-glpssx02.lo `test -f 'glpssx02.c' || echo '$(srcdir)/'`glpssx02.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glpssx02.Tpo $(DEPDIR)/libglpk_la-glpssx02.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glpssx02.c' object='libglpk_la-glpssx02.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glpssx02.lo `test -f 'glpssx02.c' || echo '$(srcdir)/'`glpssx02.c - -libglpk_la-glptsp.lo: glptsp.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-glptsp.lo -MD -MP -MF $(DEPDIR)/libglpk_la-glptsp.Tpo -c -o libglpk_la-glptsp.lo `test -f 'glptsp.c' || echo '$(srcdir)/'`glptsp.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-glptsp.Tpo $(DEPDIR)/libglpk_la-glptsp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glptsp.c' object='libglpk_la-glptsp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-glptsp.lo `test -f 'glptsp.c' || echo '$(srcdir)/'`glptsp.c - -libglpk_la-lux.lo: lux.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-lux.lo -MD -MP -MF $(DEPDIR)/libglpk_la-lux.Tpo -c -o libglpk_la-lux.lo `test -f 'lux.c' || echo '$(srcdir)/'`lux.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-lux.Tpo $(DEPDIR)/libglpk_la-lux.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lux.c' object='libglpk_la-lux.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-lux.lo `test -f 'lux.c' || echo '$(srcdir)/'`lux.c - -libglpk_la-amd_1.lo: amd/amd_1.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_1.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_1.Tpo -c -o libglpk_la-amd_1.lo `test -f 'amd/amd_1.c' || echo '$(srcdir)/'`amd/amd_1.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_1.Tpo $(DEPDIR)/libglpk_la-amd_1.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_1.c' object='libglpk_la-amd_1.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_1.lo `test -f 'amd/amd_1.c' || echo '$(srcdir)/'`amd/amd_1.c - -libglpk_la-amd_2.lo: amd/amd_2.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_2.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_2.Tpo -c -o libglpk_la-amd_2.lo `test -f 'amd/amd_2.c' || echo '$(srcdir)/'`amd/amd_2.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_2.Tpo $(DEPDIR)/libglpk_la-amd_2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_2.c' object='libglpk_la-amd_2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_2.lo `test -f 'amd/amd_2.c' || echo '$(srcdir)/'`amd/amd_2.c - -libglpk_la-amd_aat.lo: amd/amd_aat.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_aat.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_aat.Tpo -c -o libglpk_la-amd_aat.lo `test -f 'amd/amd_aat.c' || echo '$(srcdir)/'`amd/amd_aat.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_aat.Tpo $(DEPDIR)/libglpk_la-amd_aat.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_aat.c' object='libglpk_la-amd_aat.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_aat.lo `test -f 'amd/amd_aat.c' || echo '$(srcdir)/'`amd/amd_aat.c - -libglpk_la-amd_control.lo: amd/amd_control.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_control.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_control.Tpo -c -o libglpk_la-amd_control.lo `test -f 'amd/amd_control.c' || echo '$(srcdir)/'`amd/amd_control.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_control.Tpo $(DEPDIR)/libglpk_la-amd_control.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_control.c' object='libglpk_la-amd_control.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_control.lo `test -f 'amd/amd_control.c' || echo '$(srcdir)/'`amd/amd_control.c - -libglpk_la-amd_defaults.lo: amd/amd_defaults.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_defaults.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_defaults.Tpo -c -o libglpk_la-amd_defaults.lo `test -f 'amd/amd_defaults.c' || echo '$(srcdir)/'`amd/amd_defaults.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_defaults.Tpo $(DEPDIR)/libglpk_la-amd_defaults.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_defaults.c' object='libglpk_la-amd_defaults.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_defaults.lo `test -f 'amd/amd_defaults.c' || echo '$(srcdir)/'`amd/amd_defaults.c - -libglpk_la-amd_dump.lo: amd/amd_dump.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_dump.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_dump.Tpo -c -o libglpk_la-amd_dump.lo `test -f 'amd/amd_dump.c' || echo '$(srcdir)/'`amd/amd_dump.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_dump.Tpo $(DEPDIR)/libglpk_la-amd_dump.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_dump.c' object='libglpk_la-amd_dump.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_dump.lo `test -f 'amd/amd_dump.c' || echo '$(srcdir)/'`amd/amd_dump.c - -libglpk_la-amd_info.lo: amd/amd_info.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_info.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_info.Tpo -c -o libglpk_la-amd_info.lo `test -f 'amd/amd_info.c' || echo '$(srcdir)/'`amd/amd_info.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_info.Tpo $(DEPDIR)/libglpk_la-amd_info.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_info.c' object='libglpk_la-amd_info.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_info.lo `test -f 'amd/amd_info.c' || echo '$(srcdir)/'`amd/amd_info.c - -libglpk_la-amd_order.lo: amd/amd_order.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_order.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_order.Tpo -c -o libglpk_la-amd_order.lo `test -f 'amd/amd_order.c' || echo '$(srcdir)/'`amd/amd_order.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_order.Tpo $(DEPDIR)/libglpk_la-amd_order.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_order.c' object='libglpk_la-amd_order.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_order.lo `test -f 'amd/amd_order.c' || echo '$(srcdir)/'`amd/amd_order.c - -libglpk_la-amd_post_tree.lo: amd/amd_post_tree.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_post_tree.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_post_tree.Tpo -c -o libglpk_la-amd_post_tree.lo `test -f 'amd/amd_post_tree.c' || echo '$(srcdir)/'`amd/amd_post_tree.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_post_tree.Tpo $(DEPDIR)/libglpk_la-amd_post_tree.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_post_tree.c' object='libglpk_la-amd_post_tree.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_post_tree.lo `test -f 'amd/amd_post_tree.c' || echo '$(srcdir)/'`amd/amd_post_tree.c - -libglpk_la-amd_postorder.lo: amd/amd_postorder.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_postorder.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_postorder.Tpo -c -o libglpk_la-amd_postorder.lo `test -f 'amd/amd_postorder.c' || echo '$(srcdir)/'`amd/amd_postorder.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_postorder.Tpo $(DEPDIR)/libglpk_la-amd_postorder.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_postorder.c' object='libglpk_la-amd_postorder.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_postorder.lo `test -f 'amd/amd_postorder.c' || echo '$(srcdir)/'`amd/amd_postorder.c - -libglpk_la-amd_preprocess.lo: amd/amd_preprocess.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_preprocess.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_preprocess.Tpo -c -o libglpk_la-amd_preprocess.lo `test -f 'amd/amd_preprocess.c' || echo '$(srcdir)/'`amd/amd_preprocess.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_preprocess.Tpo $(DEPDIR)/libglpk_la-amd_preprocess.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_preprocess.c' object='libglpk_la-amd_preprocess.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_preprocess.lo `test -f 'amd/amd_preprocess.c' || echo '$(srcdir)/'`amd/amd_preprocess.c - -libglpk_la-amd_valid.lo: amd/amd_valid.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-amd_valid.lo -MD -MP -MF $(DEPDIR)/libglpk_la-amd_valid.Tpo -c -o libglpk_la-amd_valid.lo `test -f 'amd/amd_valid.c' || echo '$(srcdir)/'`amd/amd_valid.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-amd_valid.Tpo $(DEPDIR)/libglpk_la-amd_valid.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amd/amd_valid.c' object='libglpk_la-amd_valid.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-amd_valid.lo `test -f 'amd/amd_valid.c' || echo '$(srcdir)/'`amd/amd_valid.c - -libglpk_la-fhv.lo: bflib/fhv.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-fhv.lo -MD -MP -MF $(DEPDIR)/libglpk_la-fhv.Tpo -c -o libglpk_la-fhv.lo `test -f 'bflib/fhv.c' || echo '$(srcdir)/'`bflib/fhv.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-fhv.Tpo $(DEPDIR)/libglpk_la-fhv.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/fhv.c' object='libglpk_la-fhv.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-fhv.lo `test -f 'bflib/fhv.c' || echo '$(srcdir)/'`bflib/fhv.c - -libglpk_la-fhvint.lo: bflib/fhvint.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-fhvint.lo -MD -MP -MF $(DEPDIR)/libglpk_la-fhvint.Tpo -c -o libglpk_la-fhvint.lo `test -f 'bflib/fhvint.c' || echo '$(srcdir)/'`bflib/fhvint.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-fhvint.Tpo $(DEPDIR)/libglpk_la-fhvint.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/fhvint.c' object='libglpk_la-fhvint.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-fhvint.lo `test -f 'bflib/fhvint.c' || echo '$(srcdir)/'`bflib/fhvint.c - -libglpk_la-ifu.lo: bflib/ifu.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-ifu.lo -MD -MP -MF $(DEPDIR)/libglpk_la-ifu.Tpo -c -o libglpk_la-ifu.lo `test -f 'bflib/ifu.c' || echo '$(srcdir)/'`bflib/ifu.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-ifu.Tpo $(DEPDIR)/libglpk_la-ifu.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/ifu.c' object='libglpk_la-ifu.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-ifu.lo `test -f 'bflib/ifu.c' || echo '$(srcdir)/'`bflib/ifu.c - -libglpk_la-luf.lo: bflib/luf.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-luf.lo -MD -MP -MF $(DEPDIR)/libglpk_la-luf.Tpo -c -o libglpk_la-luf.lo `test -f 'bflib/luf.c' || echo '$(srcdir)/'`bflib/luf.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-luf.Tpo $(DEPDIR)/libglpk_la-luf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/luf.c' object='libglpk_la-luf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-luf.lo `test -f 'bflib/luf.c' || echo '$(srcdir)/'`bflib/luf.c - -libglpk_la-lufint.lo: bflib/lufint.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-lufint.lo -MD -MP -MF $(DEPDIR)/libglpk_la-lufint.Tpo -c -o libglpk_la-lufint.lo `test -f 'bflib/lufint.c' || echo '$(srcdir)/'`bflib/lufint.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-lufint.Tpo $(DEPDIR)/libglpk_la-lufint.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/lufint.c' object='libglpk_la-lufint.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-lufint.lo `test -f 'bflib/lufint.c' || echo '$(srcdir)/'`bflib/lufint.c - -libglpk_la-sgf.lo: bflib/sgf.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-sgf.lo -MD -MP -MF $(DEPDIR)/libglpk_la-sgf.Tpo -c -o libglpk_la-sgf.lo `test -f 'bflib/sgf.c' || echo '$(srcdir)/'`bflib/sgf.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-sgf.Tpo $(DEPDIR)/libglpk_la-sgf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/sgf.c' object='libglpk_la-sgf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-sgf.lo `test -f 'bflib/sgf.c' || echo '$(srcdir)/'`bflib/sgf.c - -libglpk_la-sva.lo: bflib/sva.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-sva.lo -MD -MP -MF $(DEPDIR)/libglpk_la-sva.Tpo -c -o libglpk_la-sva.lo `test -f 'bflib/sva.c' || echo '$(srcdir)/'`bflib/sva.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-sva.Tpo $(DEPDIR)/libglpk_la-sva.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bflib/sva.c' object='libglpk_la-sva.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-sva.lo `test -f 'bflib/sva.c' || echo '$(srcdir)/'`bflib/sva.c - -libglpk_la-cfg.lo: cglib/cfg.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-cfg.lo -MD -MP -MF $(DEPDIR)/libglpk_la-cfg.Tpo -c -o libglpk_la-cfg.lo `test -f 'cglib/cfg.c' || echo '$(srcdir)/'`cglib/cfg.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-cfg.Tpo $(DEPDIR)/libglpk_la-cfg.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cglib/cfg.c' object='libglpk_la-cfg.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-cfg.lo `test -f 'cglib/cfg.c' || echo '$(srcdir)/'`cglib/cfg.c - -libglpk_la-cfg1.lo: cglib/cfg1.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-cfg1.lo -MD -MP -MF $(DEPDIR)/libglpk_la-cfg1.Tpo -c -o libglpk_la-cfg1.lo `test -f 'cglib/cfg1.c' || echo '$(srcdir)/'`cglib/cfg1.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-cfg1.Tpo $(DEPDIR)/libglpk_la-cfg1.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cglib/cfg1.c' object='libglpk_la-cfg1.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-cfg1.lo `test -f 'cglib/cfg1.c' || echo '$(srcdir)/'`cglib/cfg1.c - -libglpk_la-colamd.lo: colamd/colamd.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-colamd.lo -MD -MP -MF $(DEPDIR)/libglpk_la-colamd.Tpo -c -o libglpk_la-colamd.lo `test -f 'colamd/colamd.c' || echo '$(srcdir)/'`colamd/colamd.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-colamd.Tpo $(DEPDIR)/libglpk_la-colamd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='colamd/colamd.c' object='libglpk_la-colamd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-colamd.lo `test -f 'colamd/colamd.c' || echo '$(srcdir)/'`colamd/colamd.c - -libglpk_la-alloc.lo: env/alloc.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-alloc.lo -MD -MP -MF $(DEPDIR)/libglpk_la-alloc.Tpo -c -o libglpk_la-alloc.lo `test -f 'env/alloc.c' || echo '$(srcdir)/'`env/alloc.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-alloc.Tpo $(DEPDIR)/libglpk_la-alloc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/alloc.c' object='libglpk_la-alloc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-alloc.lo `test -f 'env/alloc.c' || echo '$(srcdir)/'`env/alloc.c - -libglpk_la-dlsup.lo: env/dlsup.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-dlsup.lo -MD -MP -MF $(DEPDIR)/libglpk_la-dlsup.Tpo -c -o libglpk_la-dlsup.lo `test -f 'env/dlsup.c' || echo '$(srcdir)/'`env/dlsup.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-dlsup.Tpo $(DEPDIR)/libglpk_la-dlsup.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/dlsup.c' object='libglpk_la-dlsup.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-dlsup.lo `test -f 'env/dlsup.c' || echo '$(srcdir)/'`env/dlsup.c - -libglpk_la-env.lo: env/env.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-env.lo -MD -MP -MF $(DEPDIR)/libglpk_la-env.Tpo -c -o libglpk_la-env.lo `test -f 'env/env.c' || echo '$(srcdir)/'`env/env.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-env.Tpo $(DEPDIR)/libglpk_la-env.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/env.c' object='libglpk_la-env.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-env.lo `test -f 'env/env.c' || echo '$(srcdir)/'`env/env.c - -libglpk_la-error.lo: env/error.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-error.lo -MD -MP -MF $(DEPDIR)/libglpk_la-error.Tpo -c -o libglpk_la-error.lo `test -f 'env/error.c' || echo '$(srcdir)/'`env/error.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-error.Tpo $(DEPDIR)/libglpk_la-error.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/error.c' object='libglpk_la-error.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-error.lo `test -f 'env/error.c' || echo '$(srcdir)/'`env/error.c - -libglpk_la-stdout.lo: env/stdout.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-stdout.lo -MD -MP -MF $(DEPDIR)/libglpk_la-stdout.Tpo -c -o libglpk_la-stdout.lo `test -f 'env/stdout.c' || echo '$(srcdir)/'`env/stdout.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-stdout.Tpo $(DEPDIR)/libglpk_la-stdout.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/stdout.c' object='libglpk_la-stdout.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-stdout.lo `test -f 'env/stdout.c' || echo '$(srcdir)/'`env/stdout.c - -libglpk_la-stream.lo: env/stream.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-stream.lo -MD -MP -MF $(DEPDIR)/libglpk_la-stream.Tpo -c -o libglpk_la-stream.lo `test -f 'env/stream.c' || echo '$(srcdir)/'`env/stream.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-stream.Tpo $(DEPDIR)/libglpk_la-stream.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/stream.c' object='libglpk_la-stream.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-stream.lo `test -f 'env/stream.c' || echo '$(srcdir)/'`env/stream.c - -libglpk_la-time.lo: env/time.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-time.lo -MD -MP -MF $(DEPDIR)/libglpk_la-time.Tpo -c -o libglpk_la-time.lo `test -f 'env/time.c' || echo '$(srcdir)/'`env/time.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-time.Tpo $(DEPDIR)/libglpk_la-time.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/time.c' object='libglpk_la-time.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-time.lo `test -f 'env/time.c' || echo '$(srcdir)/'`env/time.c - -libglpk_la-tls.lo: env/tls.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-tls.lo -MD -MP -MF $(DEPDIR)/libglpk_la-tls.Tpo -c -o libglpk_la-tls.lo `test -f 'env/tls.c' || echo '$(srcdir)/'`env/tls.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-tls.Tpo $(DEPDIR)/libglpk_la-tls.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='env/tls.c' object='libglpk_la-tls.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-tls.lo `test -f 'env/tls.c' || echo '$(srcdir)/'`env/tls.c - -libglpk_la-minisat.lo: minisat/minisat.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-minisat.lo -MD -MP -MF $(DEPDIR)/libglpk_la-minisat.Tpo -c -o libglpk_la-minisat.lo `test -f 'minisat/minisat.c' || echo '$(srcdir)/'`minisat/minisat.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-minisat.Tpo $(DEPDIR)/libglpk_la-minisat.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='minisat/minisat.c' object='libglpk_la-minisat.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-minisat.lo `test -f 'minisat/minisat.c' || echo '$(srcdir)/'`minisat/minisat.c - -libglpk_la-bignum.lo: misc/bignum.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-bignum.lo -MD -MP -MF $(DEPDIR)/libglpk_la-bignum.Tpo -c -o libglpk_la-bignum.lo `test -f 'misc/bignum.c' || echo '$(srcdir)/'`misc/bignum.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-bignum.Tpo $(DEPDIR)/libglpk_la-bignum.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/bignum.c' object='libglpk_la-bignum.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-bignum.lo `test -f 'misc/bignum.c' || echo '$(srcdir)/'`misc/bignum.c - -libglpk_la-dmp.lo: misc/dmp.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-dmp.lo -MD -MP -MF $(DEPDIR)/libglpk_la-dmp.Tpo -c -o libglpk_la-dmp.lo `test -f 'misc/dmp.c' || echo '$(srcdir)/'`misc/dmp.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-dmp.Tpo $(DEPDIR)/libglpk_la-dmp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/dmp.c' object='libglpk_la-dmp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-dmp.lo `test -f 'misc/dmp.c' || echo '$(srcdir)/'`misc/dmp.c - -libglpk_la-ffalg.lo: misc/ffalg.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-ffalg.lo -MD -MP -MF $(DEPDIR)/libglpk_la-ffalg.Tpo -c -o libglpk_la-ffalg.lo `test -f 'misc/ffalg.c' || echo '$(srcdir)/'`misc/ffalg.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-ffalg.Tpo $(DEPDIR)/libglpk_la-ffalg.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/ffalg.c' object='libglpk_la-ffalg.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-ffalg.lo `test -f 'misc/ffalg.c' || echo '$(srcdir)/'`misc/ffalg.c - -libglpk_la-fp2rat.lo: misc/fp2rat.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-fp2rat.lo -MD -MP -MF $(DEPDIR)/libglpk_la-fp2rat.Tpo -c -o libglpk_la-fp2rat.lo `test -f 'misc/fp2rat.c' || echo '$(srcdir)/'`misc/fp2rat.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-fp2rat.Tpo $(DEPDIR)/libglpk_la-fp2rat.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/fp2rat.c' object='libglpk_la-fp2rat.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-fp2rat.lo `test -f 'misc/fp2rat.c' || echo '$(srcdir)/'`misc/fp2rat.c - -libglpk_la-gcd.lo: misc/gcd.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-gcd.lo -MD -MP -MF $(DEPDIR)/libglpk_la-gcd.Tpo -c -o libglpk_la-gcd.lo `test -f 'misc/gcd.c' || echo '$(srcdir)/'`misc/gcd.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-gcd.Tpo $(DEPDIR)/libglpk_la-gcd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/gcd.c' object='libglpk_la-gcd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-gcd.lo `test -f 'misc/gcd.c' || echo '$(srcdir)/'`misc/gcd.c - -libglpk_la-jd.lo: misc/jd.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-jd.lo -MD -MP -MF $(DEPDIR)/libglpk_la-jd.Tpo -c -o libglpk_la-jd.lo `test -f 'misc/jd.c' || echo '$(srcdir)/'`misc/jd.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-jd.Tpo $(DEPDIR)/libglpk_la-jd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/jd.c' object='libglpk_la-jd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-jd.lo `test -f 'misc/jd.c' || echo '$(srcdir)/'`misc/jd.c - -libglpk_la-keller.lo: misc/keller.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-keller.lo -MD -MP -MF $(DEPDIR)/libglpk_la-keller.Tpo -c -o libglpk_la-keller.lo `test -f 'misc/keller.c' || echo '$(srcdir)/'`misc/keller.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-keller.Tpo $(DEPDIR)/libglpk_la-keller.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/keller.c' object='libglpk_la-keller.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-keller.lo `test -f 'misc/keller.c' || echo '$(srcdir)/'`misc/keller.c - -libglpk_la-mc13d.lo: misc/mc13d.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-mc13d.lo -MD -MP -MF $(DEPDIR)/libglpk_la-mc13d.Tpo -c -o libglpk_la-mc13d.lo `test -f 'misc/mc13d.c' || echo '$(srcdir)/'`misc/mc13d.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-mc13d.Tpo $(DEPDIR)/libglpk_la-mc13d.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/mc13d.c' object='libglpk_la-mc13d.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-mc13d.lo `test -f 'misc/mc13d.c' || echo '$(srcdir)/'`misc/mc13d.c - -libglpk_la-mc21a.lo: misc/mc21a.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-mc21a.lo -MD -MP -MF $(DEPDIR)/libglpk_la-mc21a.Tpo -c -o libglpk_la-mc21a.lo `test -f 'misc/mc21a.c' || echo '$(srcdir)/'`misc/mc21a.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-mc21a.Tpo $(DEPDIR)/libglpk_la-mc21a.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/mc21a.c' object='libglpk_la-mc21a.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-mc21a.lo `test -f 'misc/mc21a.c' || echo '$(srcdir)/'`misc/mc21a.c - -libglpk_la-okalg.lo: misc/okalg.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-okalg.lo -MD -MP -MF $(DEPDIR)/libglpk_la-okalg.Tpo -c -o libglpk_la-okalg.lo `test -f 'misc/okalg.c' || echo '$(srcdir)/'`misc/okalg.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-okalg.Tpo $(DEPDIR)/libglpk_la-okalg.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/okalg.c' object='libglpk_la-okalg.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-okalg.lo `test -f 'misc/okalg.c' || echo '$(srcdir)/'`misc/okalg.c - -libglpk_la-qmd.lo: misc/qmd.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-qmd.lo -MD -MP -MF $(DEPDIR)/libglpk_la-qmd.Tpo -c -o libglpk_la-qmd.lo `test -f 'misc/qmd.c' || echo '$(srcdir)/'`misc/qmd.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-qmd.Tpo $(DEPDIR)/libglpk_la-qmd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/qmd.c' object='libglpk_la-qmd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-qmd.lo `test -f 'misc/qmd.c' || echo '$(srcdir)/'`misc/qmd.c - -libglpk_la-relax4.lo: misc/relax4.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-relax4.lo -MD -MP -MF $(DEPDIR)/libglpk_la-relax4.Tpo -c -o libglpk_la-relax4.lo `test -f 'misc/relax4.c' || echo '$(srcdir)/'`misc/relax4.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-relax4.Tpo $(DEPDIR)/libglpk_la-relax4.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/relax4.c' object='libglpk_la-relax4.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-relax4.lo `test -f 'misc/relax4.c' || echo '$(srcdir)/'`misc/relax4.c - -libglpk_la-rng.lo: misc/rng.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-rng.lo -MD -MP -MF $(DEPDIR)/libglpk_la-rng.Tpo -c -o libglpk_la-rng.lo `test -f 'misc/rng.c' || echo '$(srcdir)/'`misc/rng.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-rng.Tpo $(DEPDIR)/libglpk_la-rng.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/rng.c' object='libglpk_la-rng.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-rng.lo `test -f 'misc/rng.c' || echo '$(srcdir)/'`misc/rng.c - -libglpk_la-rng1.lo: misc/rng1.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-rng1.lo -MD -MP -MF $(DEPDIR)/libglpk_la-rng1.Tpo -c -o libglpk_la-rng1.lo `test -f 'misc/rng1.c' || echo '$(srcdir)/'`misc/rng1.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-rng1.Tpo $(DEPDIR)/libglpk_la-rng1.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/rng1.c' object='libglpk_la-rng1.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-rng1.lo `test -f 'misc/rng1.c' || echo '$(srcdir)/'`misc/rng1.c - -libglpk_la-round2n.lo: misc/round2n.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-round2n.lo -MD -MP -MF $(DEPDIR)/libglpk_la-round2n.Tpo -c -o libglpk_la-round2n.lo `test -f 'misc/round2n.c' || echo '$(srcdir)/'`misc/round2n.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-round2n.Tpo $(DEPDIR)/libglpk_la-round2n.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/round2n.c' object='libglpk_la-round2n.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-round2n.lo `test -f 'misc/round2n.c' || echo '$(srcdir)/'`misc/round2n.c - -libglpk_la-str2int.lo: misc/str2int.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-str2int.lo -MD -MP -MF $(DEPDIR)/libglpk_la-str2int.Tpo -c -o libglpk_la-str2int.lo `test -f 'misc/str2int.c' || echo '$(srcdir)/'`misc/str2int.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-str2int.Tpo $(DEPDIR)/libglpk_la-str2int.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/str2int.c' object='libglpk_la-str2int.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-str2int.lo `test -f 'misc/str2int.c' || echo '$(srcdir)/'`misc/str2int.c - -libglpk_la-str2num.lo: misc/str2num.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-str2num.lo -MD -MP -MF $(DEPDIR)/libglpk_la-str2num.Tpo -c -o libglpk_la-str2num.lo `test -f 'misc/str2num.c' || echo '$(srcdir)/'`misc/str2num.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-str2num.Tpo $(DEPDIR)/libglpk_la-str2num.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/str2num.c' object='libglpk_la-str2num.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-str2num.lo `test -f 'misc/str2num.c' || echo '$(srcdir)/'`misc/str2num.c - -libglpk_la-strspx.lo: misc/strspx.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-strspx.lo -MD -MP -MF $(DEPDIR)/libglpk_la-strspx.Tpo -c -o libglpk_la-strspx.lo `test -f 'misc/strspx.c' || echo '$(srcdir)/'`misc/strspx.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-strspx.Tpo $(DEPDIR)/libglpk_la-strspx.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/strspx.c' object='libglpk_la-strspx.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-strspx.lo `test -f 'misc/strspx.c' || echo '$(srcdir)/'`misc/strspx.c - -libglpk_la-strtrim.lo: misc/strtrim.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-strtrim.lo -MD -MP -MF $(DEPDIR)/libglpk_la-strtrim.Tpo -c -o libglpk_la-strtrim.lo `test -f 'misc/strtrim.c' || echo '$(srcdir)/'`misc/strtrim.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-strtrim.Tpo $(DEPDIR)/libglpk_la-strtrim.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/strtrim.c' object='libglpk_la-strtrim.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-strtrim.lo `test -f 'misc/strtrim.c' || echo '$(srcdir)/'`misc/strtrim.c - -libglpk_la-triang.lo: misc/triang.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-triang.lo -MD -MP -MF $(DEPDIR)/libglpk_la-triang.Tpo -c -o libglpk_la-triang.lo `test -f 'misc/triang.c' || echo '$(srcdir)/'`misc/triang.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-triang.Tpo $(DEPDIR)/libglpk_la-triang.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/triang.c' object='libglpk_la-triang.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-triang.lo `test -f 'misc/triang.c' || echo '$(srcdir)/'`misc/triang.c - -libglpk_la-wclique.lo: misc/wclique.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-wclique.lo -MD -MP -MF $(DEPDIR)/libglpk_la-wclique.Tpo -c -o libglpk_la-wclique.lo `test -f 'misc/wclique.c' || echo '$(srcdir)/'`misc/wclique.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-wclique.Tpo $(DEPDIR)/libglpk_la-wclique.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/wclique.c' object='libglpk_la-wclique.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-wclique.lo `test -f 'misc/wclique.c' || echo '$(srcdir)/'`misc/wclique.c - -libglpk_la-wclique1.lo: misc/wclique1.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-wclique1.lo -MD -MP -MF $(DEPDIR)/libglpk_la-wclique1.Tpo -c -o libglpk_la-wclique1.lo `test -f 'misc/wclique1.c' || echo '$(srcdir)/'`misc/wclique1.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-wclique1.Tpo $(DEPDIR)/libglpk_la-wclique1.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc/wclique1.c' object='libglpk_la-wclique1.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-wclique1.lo `test -f 'misc/wclique1.c' || echo '$(srcdir)/'`misc/wclique1.c - -libglpk_la-proxy.lo: proxy/proxy.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-proxy.lo -MD -MP -MF $(DEPDIR)/libglpk_la-proxy.Tpo -c -o libglpk_la-proxy.lo `test -f 'proxy/proxy.c' || echo '$(srcdir)/'`proxy/proxy.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-proxy.Tpo $(DEPDIR)/libglpk_la-proxy.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='proxy/proxy.c' object='libglpk_la-proxy.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-proxy.lo `test -f 'proxy/proxy.c' || echo '$(srcdir)/'`proxy/proxy.c - -libglpk_la-proxy1.lo: proxy/proxy1.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-proxy1.lo -MD -MP -MF $(DEPDIR)/libglpk_la-proxy1.Tpo -c -o libglpk_la-proxy1.lo `test -f 'proxy/proxy1.c' || echo '$(srcdir)/'`proxy/proxy1.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-proxy1.Tpo $(DEPDIR)/libglpk_la-proxy1.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='proxy/proxy1.c' object='libglpk_la-proxy1.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-proxy1.lo `test -f 'proxy/proxy1.c' || echo '$(srcdir)/'`proxy/proxy1.c - -libglpk_la-adler32.lo: zlib/adler32.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-adler32.lo -MD -MP -MF $(DEPDIR)/libglpk_la-adler32.Tpo -c -o libglpk_la-adler32.lo `test -f 'zlib/adler32.c' || echo '$(srcdir)/'`zlib/adler32.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-adler32.Tpo $(DEPDIR)/libglpk_la-adler32.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/adler32.c' object='libglpk_la-adler32.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-adler32.lo `test -f 'zlib/adler32.c' || echo '$(srcdir)/'`zlib/adler32.c - -libglpk_la-compress.lo: zlib/compress.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-compress.lo -MD -MP -MF $(DEPDIR)/libglpk_la-compress.Tpo -c -o libglpk_la-compress.lo `test -f 'zlib/compress.c' || echo '$(srcdir)/'`zlib/compress.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-compress.Tpo $(DEPDIR)/libglpk_la-compress.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/compress.c' object='libglpk_la-compress.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-compress.lo `test -f 'zlib/compress.c' || echo '$(srcdir)/'`zlib/compress.c - -libglpk_la-crc32.lo: zlib/crc32.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-crc32.lo -MD -MP -MF $(DEPDIR)/libglpk_la-crc32.Tpo -c -o libglpk_la-crc32.lo `test -f 'zlib/crc32.c' || echo '$(srcdir)/'`zlib/crc32.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-crc32.Tpo $(DEPDIR)/libglpk_la-crc32.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/crc32.c' object='libglpk_la-crc32.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-crc32.lo `test -f 'zlib/crc32.c' || echo '$(srcdir)/'`zlib/crc32.c - -libglpk_la-deflate.lo: zlib/deflate.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-deflate.lo -MD -MP -MF $(DEPDIR)/libglpk_la-deflate.Tpo -c -o libglpk_la-deflate.lo `test -f 'zlib/deflate.c' || echo '$(srcdir)/'`zlib/deflate.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-deflate.Tpo $(DEPDIR)/libglpk_la-deflate.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/deflate.c' object='libglpk_la-deflate.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-deflate.lo `test -f 'zlib/deflate.c' || echo '$(srcdir)/'`zlib/deflate.c - -libglpk_la-gzclose.lo: zlib/gzclose.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-gzclose.lo -MD -MP -MF $(DEPDIR)/libglpk_la-gzclose.Tpo -c -o libglpk_la-gzclose.lo `test -f 'zlib/gzclose.c' || echo '$(srcdir)/'`zlib/gzclose.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-gzclose.Tpo $(DEPDIR)/libglpk_la-gzclose.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/gzclose.c' object='libglpk_la-gzclose.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-gzclose.lo `test -f 'zlib/gzclose.c' || echo '$(srcdir)/'`zlib/gzclose.c - -libglpk_la-gzlib.lo: zlib/gzlib.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-gzlib.lo -MD -MP -MF $(DEPDIR)/libglpk_la-gzlib.Tpo -c -o libglpk_la-gzlib.lo `test -f 'zlib/gzlib.c' || echo '$(srcdir)/'`zlib/gzlib.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-gzlib.Tpo $(DEPDIR)/libglpk_la-gzlib.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/gzlib.c' object='libglpk_la-gzlib.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-gzlib.lo `test -f 'zlib/gzlib.c' || echo '$(srcdir)/'`zlib/gzlib.c - -libglpk_la-gzread.lo: zlib/gzread.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-gzread.lo -MD -MP -MF $(DEPDIR)/libglpk_la-gzread.Tpo -c -o libglpk_la-gzread.lo `test -f 'zlib/gzread.c' || echo '$(srcdir)/'`zlib/gzread.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-gzread.Tpo $(DEPDIR)/libglpk_la-gzread.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/gzread.c' object='libglpk_la-gzread.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-gzread.lo `test -f 'zlib/gzread.c' || echo '$(srcdir)/'`zlib/gzread.c - -libglpk_la-gzwrite.lo: zlib/gzwrite.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-gzwrite.lo -MD -MP -MF $(DEPDIR)/libglpk_la-gzwrite.Tpo -c -o libglpk_la-gzwrite.lo `test -f 'zlib/gzwrite.c' || echo '$(srcdir)/'`zlib/gzwrite.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-gzwrite.Tpo $(DEPDIR)/libglpk_la-gzwrite.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/gzwrite.c' object='libglpk_la-gzwrite.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-gzwrite.lo `test -f 'zlib/gzwrite.c' || echo '$(srcdir)/'`zlib/gzwrite.c - -libglpk_la-inffast.lo: zlib/inffast.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-inffast.lo -MD -MP -MF $(DEPDIR)/libglpk_la-inffast.Tpo -c -o libglpk_la-inffast.lo `test -f 'zlib/inffast.c' || echo '$(srcdir)/'`zlib/inffast.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-inffast.Tpo $(DEPDIR)/libglpk_la-inffast.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/inffast.c' object='libglpk_la-inffast.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-inffast.lo `test -f 'zlib/inffast.c' || echo '$(srcdir)/'`zlib/inffast.c - -libglpk_la-inflate.lo: zlib/inflate.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-inflate.lo -MD -MP -MF $(DEPDIR)/libglpk_la-inflate.Tpo -c -o libglpk_la-inflate.lo `test -f 'zlib/inflate.c' || echo '$(srcdir)/'`zlib/inflate.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-inflate.Tpo $(DEPDIR)/libglpk_la-inflate.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/inflate.c' object='libglpk_la-inflate.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-inflate.lo `test -f 'zlib/inflate.c' || echo '$(srcdir)/'`zlib/inflate.c - -libglpk_la-inftrees.lo: zlib/inftrees.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-inftrees.lo -MD -MP -MF $(DEPDIR)/libglpk_la-inftrees.Tpo -c -o libglpk_la-inftrees.lo `test -f 'zlib/inftrees.c' || echo '$(srcdir)/'`zlib/inftrees.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-inftrees.Tpo $(DEPDIR)/libglpk_la-inftrees.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/inftrees.c' object='libglpk_la-inftrees.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-inftrees.lo `test -f 'zlib/inftrees.c' || echo '$(srcdir)/'`zlib/inftrees.c - -libglpk_la-trees.lo: zlib/trees.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-trees.lo -MD -MP -MF $(DEPDIR)/libglpk_la-trees.Tpo -c -o libglpk_la-trees.lo `test -f 'zlib/trees.c' || echo '$(srcdir)/'`zlib/trees.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-trees.Tpo $(DEPDIR)/libglpk_la-trees.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/trees.c' object='libglpk_la-trees.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-trees.lo `test -f 'zlib/trees.c' || echo '$(srcdir)/'`zlib/trees.c - -libglpk_la-uncompr.lo: zlib/uncompr.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-uncompr.lo -MD -MP -MF $(DEPDIR)/libglpk_la-uncompr.Tpo -c -o libglpk_la-uncompr.lo `test -f 'zlib/uncompr.c' || echo '$(srcdir)/'`zlib/uncompr.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-uncompr.Tpo $(DEPDIR)/libglpk_la-uncompr.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/uncompr.c' object='libglpk_la-uncompr.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-uncompr.lo `test -f 'zlib/uncompr.c' || echo '$(srcdir)/'`zlib/uncompr.c - -libglpk_la-zio.lo: zlib/zio.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-zio.lo -MD -MP -MF $(DEPDIR)/libglpk_la-zio.Tpo -c -o libglpk_la-zio.lo `test -f 'zlib/zio.c' || echo '$(srcdir)/'`zlib/zio.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-zio.Tpo $(DEPDIR)/libglpk_la-zio.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/zio.c' object='libglpk_la-zio.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-zio.lo `test -f 'zlib/zio.c' || echo '$(srcdir)/'`zlib/zio.c - -libglpk_la-zutil.lo: zlib/zutil.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libglpk_la-zutil.lo -MD -MP -MF $(DEPDIR)/libglpk_la-zutil.Tpo -c -o libglpk_la-zutil.lo `test -f 'zlib/zutil.c' || echo '$(srcdir)/'`zlib/zutil.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libglpk_la-zutil.Tpo $(DEPDIR)/libglpk_la-zutil.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='zlib/zutil.c' object='libglpk_la-zutil.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libglpk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libglpk_la-zutil.lo `test -f 'zlib/zutil.c' || echo '$(srcdir)/'`zlib/zutil.c - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -install-includeHEADERS: $(include_HEADERS) - @$(NORMAL_INSTALL) - @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ - done - -uninstall-includeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -cscopelist: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-includeHEADERS - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-libLTLIBRARIES - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libLTLIBRARIES clean-libtool cscopelist ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-includeHEADERS install-info \ - install-info-am install-libLTLIBRARIES install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-includeHEADERS \ - uninstall-libLTLIBRARIES - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/resources/3rdparty/glpk-4.53/src/amd/COPYING b/resources/3rdparty/glpk-4.53/src/amd/COPYING deleted file mode 100644 index 84bba36d0..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/COPYING +++ /dev/null @@ -1,502 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/resources/3rdparty/glpk-4.53/src/amd/README b/resources/3rdparty/glpk-4.53/src/amd/README deleted file mode 100644 index de950eb48..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/README +++ /dev/null @@ -1,58 +0,0 @@ -NOTE: Files in this subdirectory are NOT part of the GLPK package, but - are used with GLPK. - - The original code was modified according to GLPK requirements by - Andrew Makhorin . -************************************************************************ -AMD Version 2.2, Copyright (C) 2007 by Timothy A. Davis, -Patrick R. Amestoy, and Iain S. Duff. All Rights Reserved. - -Description: - - AMD is a set of routines for pre-ordering sparse matrices prior to - Cholesky or LU factorization, using the approximate minimum degree - ordering algorithm. Written in ANSI/ISO C with a MATLAB interface, - and in Fortran 77. - -Authors: - - Timothy A. Davis (davis at cise.ufl.edu), University of Florida. - Patrick R. Amestoy, ENSEEIHT, Toulouse, France. - Iain S. Duff, Rutherford Appleton Laboratory, UK. - -AMD License: - - Your use or distribution of AMD or any modified version of AMD - implies that you agree to this License. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 - USA. - - Permission is hereby granted to use or copy this program under the - terms of the GNU LGPL, provided that the Copyright, this License, - and the Availability of the original version is retained on all - copies. User documentation of any code that uses this code or any - modified version of this code must cite the Copyright, this License, - the Availability note, and "Used by permission." Permission to - modify the code and to distribute modified code is granted, provided - the Copyright, this License, and the Availability note are retained, - and a notice that the code was modified is included. - - AMD is available under alternate licences; contact T. Davis for - details. - -Availability: - - http://www.cise.ufl.edu/research/sparse/amd diff --git a/resources/3rdparty/glpk-4.53/src/amd/amd.h b/resources/3rdparty/glpk-4.53/src/amd/amd.h deleted file mode 100644 index be662d954..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/amd.h +++ /dev/null @@ -1,67 +0,0 @@ -/* amd.h */ - -/* Written by Andrew Makhorin . */ - -#ifndef GLPAMD_H -#define GLPAMD_H - -#define AMD_DATE "May 31, 2007" -#define AMD_VERSION_CODE(main, sub) ((main) * 1000 + (sub)) -#define AMD_MAIN_VERSION 2 -#define AMD_SUB_VERSION 2 -#define AMD_SUBSUB_VERSION 0 -#define AMD_VERSION AMD_VERSION_CODE(AMD_MAIN_VERSION, AMD_SUB_VERSION) - -#define AMD_CONTROL 5 -#define AMD_INFO 20 - -#define AMD_DENSE 0 -#define AMD_AGGRESSIVE 1 - -#define AMD_DEFAULT_DENSE 10.0 -#define AMD_DEFAULT_AGGRESSIVE 1 - -#define AMD_STATUS 0 -#define AMD_N 1 -#define AMD_NZ 2 -#define AMD_SYMMETRY 3 -#define AMD_NZDIAG 4 -#define AMD_NZ_A_PLUS_AT 5 -#define AMD_NDENSE 6 -#define AMD_MEMORY 7 -#define AMD_NCMPA 8 -#define AMD_LNZ 9 -#define AMD_NDIV 10 -#define AMD_NMULTSUBS_LDL 11 -#define AMD_NMULTSUBS_LU 12 -#define AMD_DMAX 13 - -#define AMD_OK 0 -#define AMD_OUT_OF_MEMORY (-1) -#define AMD_INVALID (-2) -#define AMD_OK_BUT_JUMBLED 1 - -#define amd_order _glp_amd_order -int amd_order(int n, const int Ap[], const int Ai[], int P[], - double Control[], double Info[]); - -#define amd_2 _glp_amd_2 -void amd_2(int n, int Pe[], int Iw[], int Len[], int iwlen, int pfree, - int Nv[], int Next[], int Last[], int Head[], int Elen[], - int Degree[], int W[], double Control[], double Info[]); - -#define amd_valid _glp_amd_valid -int amd_valid(int n_row, int n_col, const int Ap[], const int Ai[]); - -#define amd_defaults _glp_amd_defaults -void amd_defaults(double Control[]); - -#define amd_control _glp_amd_control -void amd_control(double Control[]); - -#define amd_info _glp_amd_info -void amd_info(double Info[]); - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/amd/amd_1.c b/resources/3rdparty/glpk-4.53/src/amd/amd_1.c deleted file mode 100644 index 4f9b07d7c..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/amd_1.c +++ /dev/null @@ -1,181 +0,0 @@ -/* ========================================================================= */ -/* === AMD_1 =============================================================== */ -/* ========================================================================= */ - -/* ------------------------------------------------------------------------- */ -/* AMD, Copyright (c) Timothy A. Davis, */ -/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ -/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ -/* web: http://www.cise.ufl.edu/research/sparse/amd */ -/* ------------------------------------------------------------------------- */ - -/* AMD_1: Construct A+A' for a sparse matrix A and perform the AMD ordering. - * - * The n-by-n sparse matrix A can be unsymmetric. It is stored in MATLAB-style - * compressed-column form, with sorted row indices in each column, and no - * duplicate entries. Diagonal entries may be present, but they are ignored. - * Row indices of column j of A are stored in Ai [Ap [j] ... Ap [j+1]-1]. - * Ap [0] must be zero, and nz = Ap [n] is the number of entries in A. The - * size of the matrix, n, must be greater than or equal to zero. - * - * This routine must be preceded by a call to AMD_aat, which computes the - * number of entries in each row/column in A+A', excluding the diagonal. - * Len [j], on input, is the number of entries in row/column j of A+A'. This - * routine constructs the matrix A+A' and then calls AMD_2. No error checking - * is performed (this was done in AMD_valid). - */ - -#include "amd_internal.h" - -GLOBAL void AMD_1 -( - Int n, /* n > 0 */ - const Int Ap [ ], /* input of size n+1, not modified */ - const Int Ai [ ], /* input of size nz = Ap [n], not modified */ - Int P [ ], /* size n output permutation */ - Int Pinv [ ], /* size n output inverse permutation */ - Int Len [ ], /* size n input, undefined on output */ - Int slen, /* slen >= sum (Len [0..n-1]) + 7n, - * ideally slen = 1.2 * sum (Len) + 8n */ - Int S [ ], /* size slen workspace */ - double Control [ ], /* input array of size AMD_CONTROL */ - double Info [ ] /* output array of size AMD_INFO */ -) -{ - Int i, j, k, p, pfree, iwlen, pj, p1, p2, pj2, *Iw, *Pe, *Nv, *Head, - *Elen, *Degree, *s, *W, *Sp, *Tp ; - - /* --------------------------------------------------------------------- */ - /* construct the matrix for AMD_2 */ - /* --------------------------------------------------------------------- */ - - ASSERT (n > 0) ; - - iwlen = slen - 6*n ; - s = S ; - Pe = s ; s += n ; - Nv = s ; s += n ; - Head = s ; s += n ; - Elen = s ; s += n ; - Degree = s ; s += n ; - W = s ; s += n ; - Iw = s ; s += iwlen ; - - ASSERT (AMD_valid (n, n, Ap, Ai) == AMD_OK) ; - - /* construct the pointers for A+A' */ - Sp = Nv ; /* use Nv and W as workspace for Sp and Tp [ */ - Tp = W ; - pfree = 0 ; - for (j = 0 ; j < n ; j++) - { - Pe [j] = pfree ; - Sp [j] = pfree ; - pfree += Len [j] ; - } - - /* Note that this restriction on iwlen is slightly more restrictive than - * what is strictly required in AMD_2. AMD_2 can operate with no elbow - * room at all, but it will be very slow. For better performance, at - * least size-n elbow room is enforced. */ - ASSERT (iwlen >= pfree + n) ; - -#ifndef NDEBUG - for (p = 0 ; p < iwlen ; p++) Iw [p] = EMPTY ; -#endif - - for (k = 0 ; k < n ; k++) - { - AMD_DEBUG1 (("Construct row/column k= "ID" of A+A'\n", k)) ; - p1 = Ap [k] ; - p2 = Ap [k+1] ; - - /* construct A+A' */ - for (p = p1 ; p < p2 ; ) - { - /* scan the upper triangular part of A */ - j = Ai [p] ; - ASSERT (j >= 0 && j < n) ; - if (j < k) - { - /* entry A (j,k) in the strictly upper triangular part */ - ASSERT (Sp [j] < (j == n-1 ? pfree : Pe [j+1])) ; - ASSERT (Sp [k] < (k == n-1 ? pfree : Pe [k+1])) ; - Iw [Sp [j]++] = k ; - Iw [Sp [k]++] = j ; - p++ ; - } - else if (j == k) - { - /* skip the diagonal */ - p++ ; - break ; - } - else /* j > k */ - { - /* first entry below the diagonal */ - break ; - } - /* scan lower triangular part of A, in column j until reaching - * row k. Start where last scan left off. */ - ASSERT (Ap [j] <= Tp [j] && Tp [j] <= Ap [j+1]) ; - pj2 = Ap [j+1] ; - for (pj = Tp [j] ; pj < pj2 ; ) - { - i = Ai [pj] ; - ASSERT (i >= 0 && i < n) ; - if (i < k) - { - /* A (i,j) is only in the lower part, not in upper */ - ASSERT (Sp [i] < (i == n-1 ? pfree : Pe [i+1])) ; - ASSERT (Sp [j] < (j == n-1 ? pfree : Pe [j+1])) ; - Iw [Sp [i]++] = j ; - Iw [Sp [j]++] = i ; - pj++ ; - } - else if (i == k) - { - /* entry A (k,j) in lower part and A (j,k) in upper */ - pj++ ; - break ; - } - else /* i > k */ - { - /* consider this entry later, when k advances to i */ - break ; - } - } - Tp [j] = pj ; - } - Tp [k] = p ; - } - - /* clean up, for remaining mismatched entries */ - for (j = 0 ; j < n ; j++) - { - for (pj = Tp [j] ; pj < Ap [j+1] ; pj++) - { - i = Ai [pj] ; - ASSERT (i >= 0 && i < n) ; - /* A (i,j) is only in the lower part, not in upper */ - ASSERT (Sp [i] < (i == n-1 ? pfree : Pe [i+1])) ; - ASSERT (Sp [j] < (j == n-1 ? pfree : Pe [j+1])) ; - Iw [Sp [i]++] = j ; - Iw [Sp [j]++] = i ; - } - } - -#ifndef NDEBUG - for (j = 0 ; j < n-1 ; j++) ASSERT (Sp [j] == Pe [j+1]) ; - ASSERT (Sp [n-1] == pfree) ; -#endif - - /* Tp and Sp no longer needed ] */ - - /* --------------------------------------------------------------------- */ - /* order the matrix */ - /* --------------------------------------------------------------------- */ - - AMD_2 (n, Pe, Iw, Len, iwlen, pfree, - Nv, Pinv, P, Head, Elen, Degree, W, Control, Info) ; -} diff --git a/resources/3rdparty/glpk-4.53/src/amd/amd_2.c b/resources/3rdparty/glpk-4.53/src/amd/amd_2.c deleted file mode 100644 index b448fc93c..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/amd_2.c +++ /dev/null @@ -1,1842 +0,0 @@ -/* ========================================================================= */ -/* === AMD_2 =============================================================== */ -/* ========================================================================= */ - -/* ------------------------------------------------------------------------- */ -/* AMD, Copyright (c) Timothy A. Davis, */ -/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ -/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ -/* web: http://www.cise.ufl.edu/research/sparse/amd */ -/* ------------------------------------------------------------------------- */ - -/* AMD_2: performs the AMD ordering on a symmetric sparse matrix A, followed - * by a postordering (via depth-first search) of the assembly tree using the - * AMD_postorder routine. - */ - -#include "amd_internal.h" - -/* ========================================================================= */ -/* === clear_flag ========================================================== */ -/* ========================================================================= */ - -static Int clear_flag (Int wflg, Int wbig, Int W [ ], Int n) -{ - Int x ; - if (wflg < 2 || wflg >= wbig) - { - for (x = 0 ; x < n ; x++) - { - if (W [x] != 0) W [x] = 1 ; - } - wflg = 2 ; - } - /* at this point, W [0..n-1] < wflg holds */ - return (wflg) ; -} - - -/* ========================================================================= */ -/* === AMD_2 =============================================================== */ -/* ========================================================================= */ - -GLOBAL void AMD_2 -( - Int n, /* A is n-by-n, where n > 0 */ - Int Pe [ ], /* Pe [0..n-1]: index in Iw of row i on input */ - Int Iw [ ], /* workspace of size iwlen. Iw [0..pfree-1] - * holds the matrix on input */ - Int Len [ ], /* Len [0..n-1]: length for row/column i on input */ - Int iwlen, /* length of Iw. iwlen >= pfree + n */ - Int pfree, /* Iw [pfree ... iwlen-1] is empty on input */ - - /* 7 size-n workspaces, not defined on input: */ - Int Nv [ ], /* the size of each supernode on output */ - Int Next [ ], /* the output inverse permutation */ - Int Last [ ], /* the output permutation */ - Int Head [ ], - Int Elen [ ], /* the size columns of L for each supernode */ - Int Degree [ ], - Int W [ ], - - /* control parameters and output statistics */ - double Control [ ], /* array of size AMD_CONTROL */ - double Info [ ] /* array of size AMD_INFO */ -) -{ - -/* - * Given a representation of the nonzero pattern of a symmetric matrix, A, - * (excluding the diagonal) perform an approximate minimum (UMFPACK/MA38-style) - * degree ordering to compute a pivot order such that the introduction of - * nonzeros (fill-in) in the Cholesky factors A = LL' is kept low. At each - * step, the pivot selected is the one with the minimum UMFAPACK/MA38-style - * upper-bound on the external degree. This routine can optionally perform - * aggresive absorption (as done by MC47B in the Harwell Subroutine - * Library). - * - * The approximate degree algorithm implemented here is the symmetric analog of - * the degree update algorithm in MA38 and UMFPACK (the Unsymmetric-pattern - * MultiFrontal PACKage, both by Davis and Duff). The routine is based on the - * MA27 minimum degree ordering algorithm by Iain Duff and John Reid. - * - * This routine is a translation of the original AMDBAR and MC47B routines, - * in Fortran, with the following modifications: - * - * (1) dense rows/columns are removed prior to ordering the matrix, and placed - * last in the output order. The presence of a dense row/column can - * increase the ordering time by up to O(n^2), unless they are removed - * prior to ordering. - * - * (2) the minimum degree ordering is followed by a postordering (depth-first - * search) of the assembly tree. Note that mass elimination (discussed - * below) combined with the approximate degree update can lead to the mass - * elimination of nodes with lower exact degree than the current pivot - * element. No additional fill-in is caused in the representation of the - * Schur complement. The mass-eliminated nodes merge with the current - * pivot element. They are ordered prior to the current pivot element. - * Because they can have lower exact degree than the current element, the - * merger of two or more of these nodes in the current pivot element can - * lead to a single element that is not a "fundamental supernode". The - * diagonal block can have zeros in it. Thus, the assembly tree used here - * is not guaranteed to be the precise supernodal elemination tree (with - * "funadmental" supernodes), and the postordering performed by this - * routine is not guaranteed to be a precise postordering of the - * elimination tree. - * - * (3) input parameters are added, to control aggressive absorption and the - * detection of "dense" rows/columns of A. - * - * (4) additional statistical information is returned, such as the number of - * nonzeros in L, and the flop counts for subsequent LDL' and LU - * factorizations. These are slight upper bounds, because of the mass - * elimination issue discussed above. - * - * (5) additional routines are added to interface this routine to MATLAB - * to provide a simple C-callable user-interface, to check inputs for - * errors, compute the symmetry of the pattern of A and the number of - * nonzeros in each row/column of A+A', to compute the pattern of A+A', - * to perform the assembly tree postordering, and to provide debugging - * ouput. Many of these functions are also provided by the Fortran - * Harwell Subroutine Library routine MC47A. - * - * (6) both int and UF_long versions are provided. In the descriptions below - * and integer is and int or UF_long depending on which version is - * being used. - - ********************************************************************** - ***** CAUTION: ARGUMENTS ARE NOT CHECKED FOR ERRORS ON INPUT. ****** - ********************************************************************** - ** If you want error checking, a more versatile input format, and a ** - ** simpler user interface, use amd_order or amd_l_order instead. ** - ** This routine is not meant to be user-callable. ** - ********************************************************************** - - * ---------------------------------------------------------------------------- - * References: - * ---------------------------------------------------------------------------- - * - * [1] Timothy A. Davis and Iain Duff, "An unsymmetric-pattern multifrontal - * method for sparse LU factorization", SIAM J. Matrix Analysis and - * Applications, vol. 18, no. 1, pp. 140-158. Discusses UMFPACK / MA38, - * which first introduced the approximate minimum degree used by this - * routine. - * - * [2] Patrick Amestoy, Timothy A. Davis, and Iain S. Duff, "An approximate - * minimum degree ordering algorithm," SIAM J. Matrix Analysis and - * Applications, vol. 17, no. 4, pp. 886-905, 1996. Discusses AMDBAR and - * MC47B, which are the Fortran versions of this routine. - * - * [3] Alan George and Joseph Liu, "The evolution of the minimum degree - * ordering algorithm," SIAM Review, vol. 31, no. 1, pp. 1-19, 1989. - * We list below the features mentioned in that paper that this code - * includes: - * - * mass elimination: - * Yes. MA27 relied on supervariable detection for mass elimination. - * - * indistinguishable nodes: - * Yes (we call these "supervariables"). This was also in the MA27 - * code - although we modified the method of detecting them (the - * previous hash was the true degree, which we no longer keep track - * of). A supervariable is a set of rows with identical nonzero - * pattern. All variables in a supervariable are eliminated together. - * Each supervariable has as its numerical name that of one of its - * variables (its principal variable). - * - * quotient graph representation: - * Yes. We use the term "element" for the cliques formed during - * elimination. This was also in the MA27 code. The algorithm can - * operate in place, but it will work more efficiently if given some - * "elbow room." - * - * element absorption: - * Yes. This was also in the MA27 code. - * - * external degree: - * Yes. The MA27 code was based on the true degree. - * - * incomplete degree update and multiple elimination: - * No. This was not in MA27, either. Our method of degree update - * within MC47B is element-based, not variable-based. It is thus - * not well-suited for use with incomplete degree update or multiple - * elimination. - * - * Authors, and Copyright (C) 2004 by: - * Timothy A. Davis, Patrick Amestoy, Iain S. Duff, John K. Reid. - * - * Acknowledgements: This work (and the UMFPACK package) was supported by the - * National Science Foundation (ASC-9111263, DMS-9223088, and CCR-0203270). - * The UMFPACK/MA38 approximate degree update algorithm, the unsymmetric analog - * which forms the basis of AMD, was developed while Tim Davis was supported by - * CERFACS (Toulouse, France) in a post-doctoral position. This C version, and - * the etree postorder, were written while Tim Davis was on sabbatical at - * Stanford University and Lawrence Berkeley National Laboratory. - - * ---------------------------------------------------------------------------- - * INPUT ARGUMENTS (unaltered): - * ---------------------------------------------------------------------------- - - * n: The matrix order. Restriction: n >= 1. - * - * iwlen: The size of the Iw array. On input, the matrix is stored in - * Iw [0..pfree-1]. However, Iw [0..iwlen-1] should be slightly larger - * than what is required to hold the matrix, at least iwlen >= pfree + n. - * Otherwise, excessive compressions will take place. The recommended - * value of iwlen is 1.2 * pfree + n, which is the value used in the - * user-callable interface to this routine (amd_order.c). The algorithm - * will not run at all if iwlen < pfree. Restriction: iwlen >= pfree + n. - * Note that this is slightly more restrictive than the actual minimum - * (iwlen >= pfree), but AMD_2 will be very slow with no elbow room. - * Thus, this routine enforces a bare minimum elbow room of size n. - * - * pfree: On input the tail end of the array, Iw [pfree..iwlen-1], is empty, - * and the matrix is stored in Iw [0..pfree-1]. During execution, - * additional data is placed in Iw, and pfree is modified so that - * Iw [pfree..iwlen-1] is always the unused part of Iw. - * - * Control: A double array of size AMD_CONTROL containing input parameters - * that affect how the ordering is computed. If NULL, then default - * settings are used. - * - * Control [AMD_DENSE] is used to determine whether or not a given input - * row is "dense". A row is "dense" if the number of entries in the row - * exceeds Control [AMD_DENSE] times sqrt (n), except that rows with 16 or - * fewer entries are never considered "dense". To turn off the detection - * of dense rows, set Control [AMD_DENSE] to a negative number, or to a - * number larger than sqrt (n). The default value of Control [AMD_DENSE] - * is AMD_DEFAULT_DENSE, which is defined in amd.h as 10. - * - * Control [AMD_AGGRESSIVE] is used to determine whether or not aggressive - * absorption is to be performed. If nonzero, then aggressive absorption - * is performed (this is the default). - - * ---------------------------------------------------------------------------- - * INPUT/OUPUT ARGUMENTS: - * ---------------------------------------------------------------------------- - * - * Pe: An integer array of size n. On input, Pe [i] is the index in Iw of - * the start of row i. Pe [i] is ignored if row i has no off-diagonal - * entries. Thus Pe [i] must be in the range 0 to pfree-1 for non-empty - * rows. - * - * During execution, it is used for both supervariables and elements: - * - * Principal supervariable i: index into Iw of the description of - * supervariable i. A supervariable represents one or more rows of - * the matrix with identical nonzero pattern. In this case, - * Pe [i] >= 0. - * - * Non-principal supervariable i: if i has been absorbed into another - * supervariable j, then Pe [i] = FLIP (j), where FLIP (j) is defined - * as (-(j)-2). Row j has the same pattern as row i. Note that j - * might later be absorbed into another supervariable j2, in which - * case Pe [i] is still FLIP (j), and Pe [j] = FLIP (j2) which is - * < EMPTY, where EMPTY is defined as (-1) in amd_internal.h. - * - * Unabsorbed element e: the index into Iw of the description of element - * e, if e has not yet been absorbed by a subsequent element. Element - * e is created when the supervariable of the same name is selected as - * the pivot. In this case, Pe [i] >= 0. - * - * Absorbed element e: if element e is absorbed into element e2, then - * Pe [e] = FLIP (e2). This occurs when the pattern of e (which we - * refer to as Le) is found to be a subset of the pattern of e2 (that - * is, Le2). In this case, Pe [i] < EMPTY. If element e is "null" - * (it has no nonzeros outside its pivot block), then Pe [e] = EMPTY, - * and e is the root of an assembly subtree (or the whole tree if - * there is just one such root). - * - * Dense variable i: if i is "dense", then Pe [i] = EMPTY. - * - * On output, Pe holds the assembly tree/forest, which implicitly - * represents a pivot order with identical fill-in as the actual order - * (via a depth-first search of the tree), as follows. If Nv [i] > 0, - * then i represents a node in the assembly tree, and the parent of i is - * Pe [i], or EMPTY if i is a root. If Nv [i] = 0, then (i, Pe [i]) - * represents an edge in a subtree, the root of which is a node in the - * assembly tree. Note that i refers to a row/column in the original - * matrix, not the permuted matrix. - * - * Info: A double array of size AMD_INFO. If present, (that is, not NULL), - * then statistics about the ordering are returned in the Info array. - * See amd.h for a description. - - * ---------------------------------------------------------------------------- - * INPUT/MODIFIED (undefined on output): - * ---------------------------------------------------------------------------- - * - * Len: An integer array of size n. On input, Len [i] holds the number of - * entries in row i of the matrix, excluding the diagonal. The contents - * of Len are undefined on output. - * - * Iw: An integer array of size iwlen. On input, Iw [0..pfree-1] holds the - * description of each row i in the matrix. The matrix must be symmetric, - * and both upper and lower triangular parts must be present. The - * diagonal must not be present. Row i is held as follows: - * - * Len [i]: the length of the row i data structure in the Iw array. - * Iw [Pe [i] ... Pe [i] + Len [i] - 1]: - * the list of column indices for nonzeros in row i (simple - * supervariables), excluding the diagonal. All supervariables - * start with one row/column each (supervariable i is just row i). - * If Len [i] is zero on input, then Pe [i] is ignored on input. - * - * Note that the rows need not be in any particular order, and there - * may be empty space between the rows. - * - * During execution, the supervariable i experiences fill-in. This is - * represented by placing in i a list of the elements that cause fill-in - * in supervariable i: - * - * Len [i]: the length of supervariable i in the Iw array. - * Iw [Pe [i] ... Pe [i] + Elen [i] - 1]: - * the list of elements that contain i. This list is kept short - * by removing absorbed elements. - * Iw [Pe [i] + Elen [i] ... Pe [i] + Len [i] - 1]: - * the list of supervariables in i. This list is kept short by - * removing nonprincipal variables, and any entry j that is also - * contained in at least one of the elements (j in Le) in the list - * for i (e in row i). - * - * When supervariable i is selected as pivot, we create an element e of - * the same name (e=i): - * - * Len [e]: the length of element e in the Iw array. - * Iw [Pe [e] ... Pe [e] + Len [e] - 1]: - * the list of supervariables in element e. - * - * An element represents the fill-in that occurs when supervariable i is - * selected as pivot (which represents the selection of row i and all - * non-principal variables whose principal variable is i). We use the - * term Le to denote the set of all supervariables in element e. Absorbed - * supervariables and elements are pruned from these lists when - * computationally convenient. - * - * CAUTION: THE INPUT MATRIX IS OVERWRITTEN DURING COMPUTATION. - * The contents of Iw are undefined on output. - - * ---------------------------------------------------------------------------- - * OUTPUT (need not be set on input): - * ---------------------------------------------------------------------------- - * - * Nv: An integer array of size n. During execution, ABS (Nv [i]) is equal to - * the number of rows that are represented by the principal supervariable - * i. If i is a nonprincipal or dense variable, then Nv [i] = 0. - * Initially, Nv [i] = 1 for all i. Nv [i] < 0 signifies that i is a - * principal variable in the pattern Lme of the current pivot element me. - * After element me is constructed, Nv [i] is set back to a positive - * value. - * - * On output, Nv [i] holds the number of pivots represented by super - * row/column i of the original matrix, or Nv [i] = 0 for non-principal - * rows/columns. Note that i refers to a row/column in the original - * matrix, not the permuted matrix. - * - * Elen: An integer array of size n. See the description of Iw above. At the - * start of execution, Elen [i] is set to zero for all rows i. During - * execution, Elen [i] is the number of elements in the list for - * supervariable i. When e becomes an element, Elen [e] = FLIP (esize) is - * set, where esize is the size of the element (the number of pivots, plus - * the number of nonpivotal entries). Thus Elen [e] < EMPTY. - * Elen (i) = EMPTY set when variable i becomes nonprincipal. - * - * For variables, Elen (i) >= EMPTY holds until just before the - * postordering and permutation vectors are computed. For elements, - * Elen [e] < EMPTY holds. - * - * On output, Elen [i] is the degree of the row/column in the Cholesky - * factorization of the permuted matrix, corresponding to the original row - * i, if i is a super row/column. It is equal to EMPTY if i is - * non-principal. Note that i refers to a row/column in the original - * matrix, not the permuted matrix. - * - * Note that the contents of Elen on output differ from the Fortran - * version (Elen holds the inverse permutation in the Fortran version, - * which is instead returned in the Next array in this C version, - * described below). - * - * Last: In a degree list, Last [i] is the supervariable preceding i, or EMPTY - * if i is the head of the list. In a hash bucket, Last [i] is the hash - * key for i. - * - * Last [Head [hash]] is also used as the head of a hash bucket if - * Head [hash] contains a degree list (see the description of Head, - * below). - * - * On output, Last [0..n-1] holds the permutation. That is, if - * i = Last [k], then row i is the kth pivot row (where k ranges from 0 to - * n-1). Row Last [k] of A is the kth row in the permuted matrix, PAP'. - * - * Next: Next [i] is the supervariable following i in a link list, or EMPTY if - * i is the last in the list. Used for two kinds of lists: degree lists - * and hash buckets (a supervariable can be in only one kind of list at a - * time). - * - * On output Next [0..n-1] holds the inverse permutation. That is, if - * k = Next [i], then row i is the kth pivot row. Row i of A appears as - * the (Next[i])-th row in the permuted matrix, PAP'. - * - * Note that the contents of Next on output differ from the Fortran - * version (Next is undefined on output in the Fortran version). - - * ---------------------------------------------------------------------------- - * LOCAL WORKSPACE (not input or output - used only during execution): - * ---------------------------------------------------------------------------- - * - * Degree: An integer array of size n. If i is a supervariable, then - * Degree [i] holds the current approximation of the external degree of - * row i (an upper bound). The external degree is the number of nonzeros - * in row i, minus ABS (Nv [i]), the diagonal part. The bound is equal to - * the exact external degree if Elen [i] is less than or equal to two. - * - * We also use the term "external degree" for elements e to refer to - * |Le \ Lme|. If e is an element, then Degree [e] is |Le|, which is the - * degree of the off-diagonal part of the element e (not including the - * diagonal part). - * - * Head: An integer array of size n. Head is used for degree lists. - * Head [deg] is the first supervariable in a degree list. All - * supervariables i in a degree list Head [deg] have the same approximate - * degree, namely, deg = Degree [i]. If the list Head [deg] is empty then - * Head [deg] = EMPTY. - * - * During supervariable detection Head [hash] also serves as a pointer to - * a hash bucket. If Head [hash] >= 0, there is a degree list of degree - * hash. The hash bucket head pointer is Last [Head [hash]]. If - * Head [hash] = EMPTY, then the degree list and hash bucket are both - * empty. If Head [hash] < EMPTY, then the degree list is empty, and - * FLIP (Head [hash]) is the head of the hash bucket. After supervariable - * detection is complete, all hash buckets are empty, and the - * (Last [Head [hash]] = EMPTY) condition is restored for the non-empty - * degree lists. - * - * W: An integer array of size n. The flag array W determines the status of - * elements and variables, and the external degree of elements. - * - * for elements: - * if W [e] = 0, then the element e is absorbed. - * if W [e] >= wflg, then W [e] - wflg is the size of the set - * |Le \ Lme|, in terms of nonzeros (the sum of ABS (Nv [i]) for - * each principal variable i that is both in the pattern of - * element e and NOT in the pattern of the current pivot element, - * me). - * if wflg > W [e] > 0, then e is not absorbed and has not yet been - * seen in the scan of the element lists in the computation of - * |Le\Lme| in Scan 1 below. - * - * for variables: - * during supervariable detection, if W [j] != wflg then j is - * not in the pattern of variable i. - * - * The W array is initialized by setting W [i] = 1 for all i, and by - * setting wflg = 2. It is reinitialized if wflg becomes too large (to - * ensure that wflg+n does not cause integer overflow). - - * ---------------------------------------------------------------------------- - * LOCAL INTEGERS: - * ---------------------------------------------------------------------------- - */ - - Int deg, degme, dext, lemax, e, elenme, eln, i, ilast, inext, j, - jlast, jnext, k, knt1, knt2, knt3, lenj, ln, me, mindeg, nel, nleft, - nvi, nvj, nvpiv, slenme, wbig, we, wflg, wnvi, ok, ndense, ncmpa, - dense, aggressive ; - - unsigned Int hash ; /* unsigned, so that hash % n is well defined.*/ - -/* - * deg: the degree of a variable or element - * degme: size, |Lme|, of the current element, me (= Degree [me]) - * dext: external degree, |Le \ Lme|, of some element e - * lemax: largest |Le| seen so far (called dmax in Fortran version) - * e: an element - * elenme: the length, Elen [me], of element list of pivotal variable - * eln: the length, Elen [...], of an element list - * hash: the computed value of the hash function - * i: a supervariable - * ilast: the entry in a link list preceding i - * inext: the entry in a link list following i - * j: a supervariable - * jlast: the entry in a link list preceding j - * jnext: the entry in a link list, or path, following j - * k: the pivot order of an element or variable - * knt1: loop counter used during element construction - * knt2: loop counter used during element construction - * knt3: loop counter used during compression - * lenj: Len [j] - * ln: length of a supervariable list - * me: current supervariable being eliminated, and the current - * element created by eliminating that supervariable - * mindeg: current minimum degree - * nel: number of pivots selected so far - * nleft: n - nel, the number of nonpivotal rows/columns remaining - * nvi: the number of variables in a supervariable i (= Nv [i]) - * nvj: the number of variables in a supervariable j (= Nv [j]) - * nvpiv: number of pivots in current element - * slenme: number of variables in variable list of pivotal variable - * wbig: = INT_MAX - n for the int version, UF_long_max - n for the - * UF_long version. wflg is not allowed to be >= wbig. - * we: W [e] - * wflg: used for flagging the W array. See description of Iw. - * wnvi: wflg - Nv [i] - * x: either a supervariable or an element - * - * ok: true if supervariable j can be absorbed into i - * ndense: number of "dense" rows/columns - * dense: rows/columns with initial degree > dense are considered "dense" - * aggressive: true if aggressive absorption is being performed - * ncmpa: number of garbage collections - - * ---------------------------------------------------------------------------- - * LOCAL DOUBLES, used for statistical output only (except for alpha): - * ---------------------------------------------------------------------------- - */ - - double f, r, ndiv, s, nms_lu, nms_ldl, dmax, alpha, lnz, lnzme ; - -/* - * f: nvpiv - * r: degme + nvpiv - * ndiv: number of divisions for LU or LDL' factorizations - * s: number of multiply-subtract pairs for LU factorization, for the - * current element me - * nms_lu number of multiply-subtract pairs for LU factorization - * nms_ldl number of multiply-subtract pairs for LDL' factorization - * dmax: the largest number of entries in any column of L, including the - * diagonal - * alpha: "dense" degree ratio - * lnz: the number of nonzeros in L (excluding the diagonal) - * lnzme: the number of nonzeros in L (excl. the diagonal) for the - * current element me - - * ---------------------------------------------------------------------------- - * LOCAL "POINTERS" (indices into the Iw array) - * ---------------------------------------------------------------------------- -*/ - - Int p, p1, p2, p3, p4, pdst, pend, pj, pme, pme1, pme2, pn, psrc ; - -/* - * Any parameter (Pe [...] or pfree) or local variable starting with "p" (for - * Pointer) is an index into Iw, and all indices into Iw use variables starting - * with "p." The only exception to this rule is the iwlen input argument. - * - * p: pointer into lots of things - * p1: Pe [i] for some variable i (start of element list) - * p2: Pe [i] + Elen [i] - 1 for some variable i - * p3: index of first supervariable in clean list - * p4: - * pdst: destination pointer, for compression - * pend: end of memory to compress - * pj: pointer into an element or variable - * pme: pointer into the current element (pme1...pme2) - * pme1: the current element, me, is stored in Iw [pme1...pme2] - * pme2: the end of the current element - * pn: pointer into a "clean" variable, also used to compress - * psrc: source pointer, for compression -*/ - -/* ========================================================================= */ -/* INITIALIZATIONS */ -/* ========================================================================= */ - - /* Note that this restriction on iwlen is slightly more restrictive than - * what is actually required in AMD_2. AMD_2 can operate with no elbow - * room at all, but it will be slow. For better performance, at least - * size-n elbow room is enforced. */ - ASSERT (iwlen >= pfree + n) ; - ASSERT (n > 0) ; - - /* initialize output statistics */ - lnz = 0 ; - ndiv = 0 ; - nms_lu = 0 ; - nms_ldl = 0 ; - dmax = 1 ; - me = EMPTY ; - - mindeg = 0 ; - ncmpa = 0 ; - nel = 0 ; - lemax = 0 ; - - /* get control parameters */ - if (Control != (double *) NULL) - { - alpha = Control [AMD_DENSE] ; - aggressive = (Control [AMD_AGGRESSIVE] != 0) ; - } - else - { - alpha = AMD_DEFAULT_DENSE ; - aggressive = AMD_DEFAULT_AGGRESSIVE ; - } - /* Note: if alpha is NaN, this is undefined: */ - if (alpha < 0) - { - /* only remove completely dense rows/columns */ - dense = n-2 ; - } - else - { - dense = alpha * sqrt ((double) n) ; - } - dense = MAX (16, dense) ; - dense = MIN (n, dense) ; - AMD_DEBUG1 (("\n\nAMD (debug), alpha %g, aggr. "ID"\n", - alpha, aggressive)) ; - - for (i = 0 ; i < n ; i++) - { - Last [i] = EMPTY ; - Head [i] = EMPTY ; - Next [i] = EMPTY ; - /* if separate Hhead array is used for hash buckets: * - Hhead [i] = EMPTY ; - */ - Nv [i] = 1 ; - W [i] = 1 ; - Elen [i] = 0 ; - Degree [i] = Len [i] ; - } - -#ifndef NDEBUG - AMD_DEBUG1 (("\n======Nel "ID" initial\n", nel)) ; - AMD_dump (n, Pe, Iw, Len, iwlen, pfree, Nv, Next, Last, - Head, Elen, Degree, W, -1) ; -#endif - - /* initialize wflg */ - wbig = Int_MAX - n ; - wflg = clear_flag (0, wbig, W, n) ; - - /* --------------------------------------------------------------------- */ - /* initialize degree lists and eliminate dense and empty rows */ - /* --------------------------------------------------------------------- */ - - ndense = 0 ; - - for (i = 0 ; i < n ; i++) - { - deg = Degree [i] ; - ASSERT (deg >= 0 && deg < n) ; - if (deg == 0) - { - - /* ------------------------------------------------------------- - * we have a variable that can be eliminated at once because - * there is no off-diagonal non-zero in its row. Note that - * Nv [i] = 1 for an empty variable i. It is treated just - * the same as an eliminated element i. - * ------------------------------------------------------------- */ - - Elen [i] = FLIP (1) ; - nel++ ; - Pe [i] = EMPTY ; - W [i] = 0 ; - - } - else if (deg > dense) - { - - /* ------------------------------------------------------------- - * Dense variables are not treated as elements, but as unordered, - * non-principal variables that have no parent. They do not take - * part in the postorder, since Nv [i] = 0. Note that the Fortran - * version does not have this option. - * ------------------------------------------------------------- */ - - AMD_DEBUG1 (("Dense node "ID" degree "ID"\n", i, deg)) ; - ndense++ ; - Nv [i] = 0 ; /* do not postorder this node */ - Elen [i] = EMPTY ; - nel++ ; - Pe [i] = EMPTY ; - - } - else - { - - /* ------------------------------------------------------------- - * place i in the degree list corresponding to its degree - * ------------------------------------------------------------- */ - - inext = Head [deg] ; - ASSERT (inext >= EMPTY && inext < n) ; - if (inext != EMPTY) Last [inext] = i ; - Next [i] = inext ; - Head [deg] = i ; - - } - } - -/* ========================================================================= */ -/* WHILE (selecting pivots) DO */ -/* ========================================================================= */ - - while (nel < n) - { - -#ifndef NDEBUG - AMD_DEBUG1 (("\n======Nel "ID"\n", nel)) ; - if (AMD_debug >= 2) - { - AMD_dump (n, Pe, Iw, Len, iwlen, pfree, Nv, Next, - Last, Head, Elen, Degree, W, nel) ; - } -#endif - -/* ========================================================================= */ -/* GET PIVOT OF MINIMUM DEGREE */ -/* ========================================================================= */ - - /* ----------------------------------------------------------------- */ - /* find next supervariable for elimination */ - /* ----------------------------------------------------------------- */ - - ASSERT (mindeg >= 0 && mindeg < n) ; - for (deg = mindeg ; deg < n ; deg++) - { - me = Head [deg] ; - if (me != EMPTY) break ; - } - mindeg = deg ; - ASSERT (me >= 0 && me < n) ; - AMD_DEBUG1 (("=================me: "ID"\n", me)) ; - - /* ----------------------------------------------------------------- */ - /* remove chosen variable from link list */ - /* ----------------------------------------------------------------- */ - - inext = Next [me] ; - ASSERT (inext >= EMPTY && inext < n) ; - if (inext != EMPTY) Last [inext] = EMPTY ; - Head [deg] = inext ; - - /* ----------------------------------------------------------------- */ - /* me represents the elimination of pivots nel to nel+Nv[me]-1. */ - /* place me itself as the first in this set. */ - /* ----------------------------------------------------------------- */ - - elenme = Elen [me] ; - nvpiv = Nv [me] ; - ASSERT (nvpiv > 0) ; - nel += nvpiv ; - -/* ========================================================================= */ -/* CONSTRUCT NEW ELEMENT */ -/* ========================================================================= */ - - /* ----------------------------------------------------------------- - * At this point, me is the pivotal supervariable. It will be - * converted into the current element. Scan list of the pivotal - * supervariable, me, setting tree pointers and constructing new list - * of supervariables for the new element, me. p is a pointer to the - * current position in the old list. - * ----------------------------------------------------------------- */ - - /* flag the variable "me" as being in Lme by negating Nv [me] */ - Nv [me] = -nvpiv ; - degme = 0 ; - ASSERT (Pe [me] >= 0 && Pe [me] < iwlen) ; - - if (elenme == 0) - { - - /* ------------------------------------------------------------- */ - /* construct the new element in place */ - /* ------------------------------------------------------------- */ - - pme1 = Pe [me] ; - pme2 = pme1 - 1 ; - - for (p = pme1 ; p <= pme1 + Len [me] - 1 ; p++) - { - i = Iw [p] ; - ASSERT (i >= 0 && i < n && Nv [i] >= 0) ; - nvi = Nv [i] ; - if (nvi > 0) - { - - /* ----------------------------------------------------- */ - /* i is a principal variable not yet placed in Lme. */ - /* store i in new list */ - /* ----------------------------------------------------- */ - - /* flag i as being in Lme by negating Nv [i] */ - degme += nvi ; - Nv [i] = -nvi ; - Iw [++pme2] = i ; - - /* ----------------------------------------------------- */ - /* remove variable i from degree list. */ - /* ----------------------------------------------------- */ - - ilast = Last [i] ; - inext = Next [i] ; - ASSERT (ilast >= EMPTY && ilast < n) ; - ASSERT (inext >= EMPTY && inext < n) ; - if (inext != EMPTY) Last [inext] = ilast ; - if (ilast != EMPTY) - { - Next [ilast] = inext ; - } - else - { - /* i is at the head of the degree list */ - ASSERT (Degree [i] >= 0 && Degree [i] < n) ; - Head [Degree [i]] = inext ; - } - } - } - } - else - { - - /* ------------------------------------------------------------- */ - /* construct the new element in empty space, Iw [pfree ...] */ - /* ------------------------------------------------------------- */ - - p = Pe [me] ; - pme1 = pfree ; - slenme = Len [me] - elenme ; - - for (knt1 = 1 ; knt1 <= elenme + 1 ; knt1++) - { - - if (knt1 > elenme) - { - /* search the supervariables in me. */ - e = me ; - pj = p ; - ln = slenme ; - AMD_DEBUG2 (("Search sv: "ID" "ID" "ID"\n", me,pj,ln)) ; - } - else - { - /* search the elements in me. */ - e = Iw [p++] ; - ASSERT (e >= 0 && e < n) ; - pj = Pe [e] ; - ln = Len [e] ; - AMD_DEBUG2 (("Search element e "ID" in me "ID"\n", e,me)) ; - ASSERT (Elen [e] < EMPTY && W [e] > 0 && pj >= 0) ; - } - ASSERT (ln >= 0 && (ln == 0 || (pj >= 0 && pj < iwlen))) ; - - /* --------------------------------------------------------- - * search for different supervariables and add them to the - * new list, compressing when necessary. this loop is - * executed once for each element in the list and once for - * all the supervariables in the list. - * --------------------------------------------------------- */ - - for (knt2 = 1 ; knt2 <= ln ; knt2++) - { - i = Iw [pj++] ; - ASSERT (i >= 0 && i < n && (i == me || Elen [i] >= EMPTY)); - nvi = Nv [i] ; - AMD_DEBUG2 ((": "ID" "ID" "ID" "ID"\n", - i, Elen [i], Nv [i], wflg)) ; - - if (nvi > 0) - { - - /* ------------------------------------------------- */ - /* compress Iw, if necessary */ - /* ------------------------------------------------- */ - - if (pfree >= iwlen) - { - - AMD_DEBUG1 (("GARBAGE COLLECTION\n")) ; - - /* prepare for compressing Iw by adjusting pointers - * and lengths so that the lists being searched in - * the inner and outer loops contain only the - * remaining entries. */ - - Pe [me] = p ; - Len [me] -= knt1 ; - /* check if nothing left of supervariable me */ - if (Len [me] == 0) Pe [me] = EMPTY ; - Pe [e] = pj ; - Len [e] = ln - knt2 ; - /* nothing left of element e */ - if (Len [e] == 0) Pe [e] = EMPTY ; - - ncmpa++ ; /* one more garbage collection */ - - /* store first entry of each object in Pe */ - /* FLIP the first entry in each object */ - for (j = 0 ; j < n ; j++) - { - pn = Pe [j] ; - if (pn >= 0) - { - ASSERT (pn >= 0 && pn < iwlen) ; - Pe [j] = Iw [pn] ; - Iw [pn] = FLIP (j) ; - } - } - - /* psrc/pdst point to source/destination */ - psrc = 0 ; - pdst = 0 ; - pend = pme1 - 1 ; - - while (psrc <= pend) - { - /* search for next FLIP'd entry */ - j = FLIP (Iw [psrc++]) ; - if (j >= 0) - { - AMD_DEBUG2 (("Got object j: "ID"\n", j)) ; - Iw [pdst] = Pe [j] ; - Pe [j] = pdst++ ; - lenj = Len [j] ; - /* copy from source to destination */ - for (knt3 = 0 ; knt3 <= lenj - 2 ; knt3++) - { - Iw [pdst++] = Iw [psrc++] ; - } - } - } - - /* move the new partially-constructed element */ - p1 = pdst ; - for (psrc = pme1 ; psrc <= pfree-1 ; psrc++) - { - Iw [pdst++] = Iw [psrc] ; - } - pme1 = p1 ; - pfree = pdst ; - pj = Pe [e] ; - p = Pe [me] ; - - } - - /* ------------------------------------------------- */ - /* i is a principal variable not yet placed in Lme */ - /* store i in new list */ - /* ------------------------------------------------- */ - - /* flag i as being in Lme by negating Nv [i] */ - degme += nvi ; - Nv [i] = -nvi ; - Iw [pfree++] = i ; - AMD_DEBUG2 ((" s: "ID" nv "ID"\n", i, Nv [i])); - - /* ------------------------------------------------- */ - /* remove variable i from degree link list */ - /* ------------------------------------------------- */ - - ilast = Last [i] ; - inext = Next [i] ; - ASSERT (ilast >= EMPTY && ilast < n) ; - ASSERT (inext >= EMPTY && inext < n) ; - if (inext != EMPTY) Last [inext] = ilast ; - if (ilast != EMPTY) - { - Next [ilast] = inext ; - } - else - { - /* i is at the head of the degree list */ - ASSERT (Degree [i] >= 0 && Degree [i] < n) ; - Head [Degree [i]] = inext ; - } - } - } - - if (e != me) - { - /* set tree pointer and flag to indicate element e is - * absorbed into new element me (the parent of e is me) */ - AMD_DEBUG1 ((" Element "ID" => "ID"\n", e, me)) ; - Pe [e] = FLIP (me) ; - W [e] = 0 ; - } - } - - pme2 = pfree - 1 ; - } - - /* ----------------------------------------------------------------- */ - /* me has now been converted into an element in Iw [pme1..pme2] */ - /* ----------------------------------------------------------------- */ - - /* degme holds the external degree of new element */ - Degree [me] = degme ; - Pe [me] = pme1 ; - Len [me] = pme2 - pme1 + 1 ; - ASSERT (Pe [me] >= 0 && Pe [me] < iwlen) ; - - Elen [me] = FLIP (nvpiv + degme) ; - /* FLIP (Elen (me)) is now the degree of pivot (including - * diagonal part). */ - -#ifndef NDEBUG - AMD_DEBUG2 (("New element structure: length= "ID"\n", pme2-pme1+1)) ; - for (pme = pme1 ; pme <= pme2 ; pme++) AMD_DEBUG3 ((" "ID"", Iw[pme])); - AMD_DEBUG3 (("\n")) ; -#endif - - /* ----------------------------------------------------------------- */ - /* make sure that wflg is not too large. */ - /* ----------------------------------------------------------------- */ - - /* With the current value of wflg, wflg+n must not cause integer - * overflow */ - - wflg = clear_flag (wflg, wbig, W, n) ; - -/* ========================================================================= */ -/* COMPUTE (W [e] - wflg) = |Le\Lme| FOR ALL ELEMENTS */ -/* ========================================================================= */ - - /* ----------------------------------------------------------------- - * Scan 1: compute the external degrees of previous elements with - * respect to the current element. That is: - * (W [e] - wflg) = |Le \ Lme| - * for each element e that appears in any supervariable in Lme. The - * notation Le refers to the pattern (list of supervariables) of a - * previous element e, where e is not yet absorbed, stored in - * Iw [Pe [e] + 1 ... Pe [e] + Len [e]]. The notation Lme - * refers to the pattern of the current element (stored in - * Iw [pme1..pme2]). If aggressive absorption is enabled, and - * (W [e] - wflg) becomes zero, then the element e will be absorbed - * in Scan 2. - * ----------------------------------------------------------------- */ - - AMD_DEBUG2 (("me: ")) ; - for (pme = pme1 ; pme <= pme2 ; pme++) - { - i = Iw [pme] ; - ASSERT (i >= 0 && i < n) ; - eln = Elen [i] ; - AMD_DEBUG3 ((""ID" Elen "ID": \n", i, eln)) ; - if (eln > 0) - { - /* note that Nv [i] has been negated to denote i in Lme: */ - nvi = -Nv [i] ; - ASSERT (nvi > 0 && Pe [i] >= 0 && Pe [i] < iwlen) ; - wnvi = wflg - nvi ; - for (p = Pe [i] ; p <= Pe [i] + eln - 1 ; p++) - { - e = Iw [p] ; - ASSERT (e >= 0 && e < n) ; - we = W [e] ; - AMD_DEBUG4 ((" e "ID" we "ID" ", e, we)) ; - if (we >= wflg) - { - /* unabsorbed element e has been seen in this loop */ - AMD_DEBUG4 ((" unabsorbed, first time seen")) ; - we -= nvi ; - } - else if (we != 0) - { - /* e is an unabsorbed element */ - /* this is the first we have seen e in all of Scan 1 */ - AMD_DEBUG4 ((" unabsorbed")) ; - we = Degree [e] + wnvi ; - } - AMD_DEBUG4 (("\n")) ; - W [e] = we ; - } - } - } - AMD_DEBUG2 (("\n")) ; - -/* ========================================================================= */ -/* DEGREE UPDATE AND ELEMENT ABSORPTION */ -/* ========================================================================= */ - - /* ----------------------------------------------------------------- - * Scan 2: for each i in Lme, sum up the degree of Lme (which is - * degme), plus the sum of the external degrees of each Le for the - * elements e appearing within i, plus the supervariables in i. - * Place i in hash list. - * ----------------------------------------------------------------- */ - - for (pme = pme1 ; pme <= pme2 ; pme++) - { - i = Iw [pme] ; - ASSERT (i >= 0 && i < n && Nv [i] < 0 && Elen [i] >= 0) ; - AMD_DEBUG2 (("Updating: i "ID" "ID" "ID"\n", i, Elen[i], Len [i])); - p1 = Pe [i] ; - p2 = p1 + Elen [i] - 1 ; - pn = p1 ; - hash = 0 ; - deg = 0 ; - ASSERT (p1 >= 0 && p1 < iwlen && p2 >= -1 && p2 < iwlen) ; - - /* ------------------------------------------------------------- */ - /* scan the element list associated with supervariable i */ - /* ------------------------------------------------------------- */ - - /* UMFPACK/MA38-style approximate degree: */ - if (aggressive) - { - for (p = p1 ; p <= p2 ; p++) - { - e = Iw [p] ; - ASSERT (e >= 0 && e < n) ; - we = W [e] ; - if (we != 0) - { - /* e is an unabsorbed element */ - /* dext = | Le \ Lme | */ - dext = we - wflg ; - if (dext > 0) - { - deg += dext ; - Iw [pn++] = e ; - hash += e ; - AMD_DEBUG4 ((" e: "ID" hash = "ID"\n",e,hash)) ; - } - else - { - /* external degree of e is zero, absorb e into me*/ - AMD_DEBUG1 ((" Element "ID" =>"ID" (aggressive)\n", - e, me)) ; - ASSERT (dext == 0) ; - Pe [e] = FLIP (me) ; - W [e] = 0 ; - } - } - } - } - else - { - for (p = p1 ; p <= p2 ; p++) - { - e = Iw [p] ; - ASSERT (e >= 0 && e < n) ; - we = W [e] ; - if (we != 0) - { - /* e is an unabsorbed element */ - dext = we - wflg ; - ASSERT (dext >= 0) ; - deg += dext ; - Iw [pn++] = e ; - hash += e ; - AMD_DEBUG4 ((" e: "ID" hash = "ID"\n",e,hash)) ; - } - } - } - - /* count the number of elements in i (including me): */ - Elen [i] = pn - p1 + 1 ; - - /* ------------------------------------------------------------- */ - /* scan the supervariables in the list associated with i */ - /* ------------------------------------------------------------- */ - - /* The bulk of the AMD run time is typically spent in this loop, - * particularly if the matrix has many dense rows that are not - * removed prior to ordering. */ - p3 = pn ; - p4 = p1 + Len [i] ; - for (p = p2 + 1 ; p < p4 ; p++) - { - j = Iw [p] ; - ASSERT (j >= 0 && j < n) ; - nvj = Nv [j] ; - if (nvj > 0) - { - /* j is unabsorbed, and not in Lme. */ - /* add to degree and add to new list */ - deg += nvj ; - Iw [pn++] = j ; - hash += j ; - AMD_DEBUG4 ((" s: "ID" hash "ID" Nv[j]= "ID"\n", - j, hash, nvj)) ; - } - } - - /* ------------------------------------------------------------- */ - /* update the degree and check for mass elimination */ - /* ------------------------------------------------------------- */ - - /* with aggressive absorption, deg==0 is identical to the - * Elen [i] == 1 && p3 == pn test, below. */ - ASSERT (IMPLIES (aggressive, (deg==0) == (Elen[i]==1 && p3==pn))) ; - - if (Elen [i] == 1 && p3 == pn) - { - - /* --------------------------------------------------------- */ - /* mass elimination */ - /* --------------------------------------------------------- */ - - /* There is nothing left of this node except for an edge to - * the current pivot element. Elen [i] is 1, and there are - * no variables adjacent to node i. Absorb i into the - * current pivot element, me. Note that if there are two or - * more mass eliminations, fillin due to mass elimination is - * possible within the nvpiv-by-nvpiv pivot block. It is this - * step that causes AMD's analysis to be an upper bound. - * - * The reason is that the selected pivot has a lower - * approximate degree than the true degree of the two mass - * eliminated nodes. There is no edge between the two mass - * eliminated nodes. They are merged with the current pivot - * anyway. - * - * No fillin occurs in the Schur complement, in any case, - * and this effect does not decrease the quality of the - * ordering itself, just the quality of the nonzero and - * flop count analysis. It also means that the post-ordering - * is not an exact elimination tree post-ordering. */ - - AMD_DEBUG1 ((" MASS i "ID" => parent e "ID"\n", i, me)) ; - Pe [i] = FLIP (me) ; - nvi = -Nv [i] ; - degme -= nvi ; - nvpiv += nvi ; - nel += nvi ; - Nv [i] = 0 ; - Elen [i] = EMPTY ; - - } - else - { - - /* --------------------------------------------------------- */ - /* update the upper-bound degree of i */ - /* --------------------------------------------------------- */ - - /* the following degree does not yet include the size - * of the current element, which is added later: */ - - Degree [i] = MIN (Degree [i], deg) ; - - /* --------------------------------------------------------- */ - /* add me to the list for i */ - /* --------------------------------------------------------- */ - - /* move first supervariable to end of list */ - Iw [pn] = Iw [p3] ; - /* move first element to end of element part of list */ - Iw [p3] = Iw [p1] ; - /* add new element, me, to front of list. */ - Iw [p1] = me ; - /* store the new length of the list in Len [i] */ - Len [i] = pn - p1 + 1 ; - - /* --------------------------------------------------------- */ - /* place in hash bucket. Save hash key of i in Last [i]. */ - /* --------------------------------------------------------- */ - - /* NOTE: this can fail if hash is negative, because the ANSI C - * standard does not define a % b when a and/or b are negative. - * That's why hash is defined as an unsigned Int, to avoid this - * problem. */ - hash = hash % n ; - ASSERT (((Int) hash) >= 0 && ((Int) hash) < n) ; - - /* if the Hhead array is not used: */ - j = Head [hash] ; - if (j <= EMPTY) - { - /* degree list is empty, hash head is FLIP (j) */ - Next [i] = FLIP (j) ; - Head [hash] = FLIP (i) ; - } - else - { - /* degree list is not empty, use Last [Head [hash]] as - * hash head. */ - Next [i] = Last [j] ; - Last [j] = i ; - } - - /* if a separate Hhead array is used: * - Next [i] = Hhead [hash] ; - Hhead [hash] = i ; - */ - - Last [i] = hash ; - } - } - - Degree [me] = degme ; - - /* ----------------------------------------------------------------- */ - /* Clear the counter array, W [...], by incrementing wflg. */ - /* ----------------------------------------------------------------- */ - - /* make sure that wflg+n does not cause integer overflow */ - lemax = MAX (lemax, degme) ; - wflg += lemax ; - wflg = clear_flag (wflg, wbig, W, n) ; - /* at this point, W [0..n-1] < wflg holds */ - -/* ========================================================================= */ -/* SUPERVARIABLE DETECTION */ -/* ========================================================================= */ - - AMD_DEBUG1 (("Detecting supervariables:\n")) ; - for (pme = pme1 ; pme <= pme2 ; pme++) - { - i = Iw [pme] ; - ASSERT (i >= 0 && i < n) ; - AMD_DEBUG2 (("Consider i "ID" nv "ID"\n", i, Nv [i])) ; - if (Nv [i] < 0) - { - /* i is a principal variable in Lme */ - - /* --------------------------------------------------------- - * examine all hash buckets with 2 or more variables. We do - * this by examing all unique hash keys for supervariables in - * the pattern Lme of the current element, me - * --------------------------------------------------------- */ - - /* let i = head of hash bucket, and empty the hash bucket */ - ASSERT (Last [i] >= 0 && Last [i] < n) ; - hash = Last [i] ; - - /* if Hhead array is not used: */ - j = Head [hash] ; - if (j == EMPTY) - { - /* hash bucket and degree list are both empty */ - i = EMPTY ; - } - else if (j < EMPTY) - { - /* degree list is empty */ - i = FLIP (j) ; - Head [hash] = EMPTY ; - } - else - { - /* degree list is not empty, restore Last [j] of head j */ - i = Last [j] ; - Last [j] = EMPTY ; - } - - /* if separate Hhead array is used: * - i = Hhead [hash] ; - Hhead [hash] = EMPTY ; - */ - - ASSERT (i >= EMPTY && i < n) ; - AMD_DEBUG2 (("----i "ID" hash "ID"\n", i, hash)) ; - - while (i != EMPTY && Next [i] != EMPTY) - { - - /* ----------------------------------------------------- - * this bucket has one or more variables following i. - * scan all of them to see if i can absorb any entries - * that follow i in hash bucket. Scatter i into w. - * ----------------------------------------------------- */ - - ln = Len [i] ; - eln = Elen [i] ; - ASSERT (ln >= 0 && eln >= 0) ; - ASSERT (Pe [i] >= 0 && Pe [i] < iwlen) ; - /* do not flag the first element in the list (me) */ - for (p = Pe [i] + 1 ; p <= Pe [i] + ln - 1 ; p++) - { - ASSERT (Iw [p] >= 0 && Iw [p] < n) ; - W [Iw [p]] = wflg ; - } - - /* ----------------------------------------------------- */ - /* scan every other entry j following i in bucket */ - /* ----------------------------------------------------- */ - - jlast = i ; - j = Next [i] ; - ASSERT (j >= EMPTY && j < n) ; - - while (j != EMPTY) - { - /* ------------------------------------------------- */ - /* check if j and i have identical nonzero pattern */ - /* ------------------------------------------------- */ - - AMD_DEBUG3 (("compare i "ID" and j "ID"\n", i,j)) ; - - /* check if i and j have the same Len and Elen */ - ASSERT (Len [j] >= 0 && Elen [j] >= 0) ; - ASSERT (Pe [j] >= 0 && Pe [j] < iwlen) ; - ok = (Len [j] == ln) && (Elen [j] == eln) ; - /* skip the first element in the list (me) */ - for (p = Pe [j] + 1 ; ok && p <= Pe [j] + ln - 1 ; p++) - { - ASSERT (Iw [p] >= 0 && Iw [p] < n) ; - if (W [Iw [p]] != wflg) ok = 0 ; - } - if (ok) - { - /* --------------------------------------------- */ - /* found it! j can be absorbed into i */ - /* --------------------------------------------- */ - - AMD_DEBUG1 (("found it! j "ID" => i "ID"\n", j,i)); - Pe [j] = FLIP (i) ; - /* both Nv [i] and Nv [j] are negated since they */ - /* are in Lme, and the absolute values of each */ - /* are the number of variables in i and j: */ - Nv [i] += Nv [j] ; - Nv [j] = 0 ; - Elen [j] = EMPTY ; - /* delete j from hash bucket */ - ASSERT (j != Next [j]) ; - j = Next [j] ; - Next [jlast] = j ; - - } - else - { - /* j cannot be absorbed into i */ - jlast = j ; - ASSERT (j != Next [j]) ; - j = Next [j] ; - } - ASSERT (j >= EMPTY && j < n) ; - } - - /* ----------------------------------------------------- - * no more variables can be absorbed into i - * go to next i in bucket and clear flag array - * ----------------------------------------------------- */ - - wflg++ ; - i = Next [i] ; - ASSERT (i >= EMPTY && i < n) ; - - } - } - } - AMD_DEBUG2 (("detect done\n")) ; - -/* ========================================================================= */ -/* RESTORE DEGREE LISTS AND REMOVE NONPRINCIPAL SUPERVARIABLES FROM ELEMENT */ -/* ========================================================================= */ - - p = pme1 ; - nleft = n - nel ; - for (pme = pme1 ; pme <= pme2 ; pme++) - { - i = Iw [pme] ; - ASSERT (i >= 0 && i < n) ; - nvi = -Nv [i] ; - AMD_DEBUG3 (("Restore i "ID" "ID"\n", i, nvi)) ; - if (nvi > 0) - { - /* i is a principal variable in Lme */ - /* restore Nv [i] to signify that i is principal */ - Nv [i] = nvi ; - - /* --------------------------------------------------------- */ - /* compute the external degree (add size of current element) */ - /* --------------------------------------------------------- */ - - deg = Degree [i] + degme - nvi ; - deg = MIN (deg, nleft - nvi) ; - ASSERT (IMPLIES (aggressive, deg > 0) && deg >= 0 && deg < n) ; - - /* --------------------------------------------------------- */ - /* place the supervariable at the head of the degree list */ - /* --------------------------------------------------------- */ - - inext = Head [deg] ; - ASSERT (inext >= EMPTY && inext < n) ; - if (inext != EMPTY) Last [inext] = i ; - Next [i] = inext ; - Last [i] = EMPTY ; - Head [deg] = i ; - - /* --------------------------------------------------------- */ - /* save the new degree, and find the minimum degree */ - /* --------------------------------------------------------- */ - - mindeg = MIN (mindeg, deg) ; - Degree [i] = deg ; - - /* --------------------------------------------------------- */ - /* place the supervariable in the element pattern */ - /* --------------------------------------------------------- */ - - Iw [p++] = i ; - - } - } - AMD_DEBUG2 (("restore done\n")) ; - -/* ========================================================================= */ -/* FINALIZE THE NEW ELEMENT */ -/* ========================================================================= */ - - AMD_DEBUG2 (("ME = "ID" DONE\n", me)) ; - Nv [me] = nvpiv ; - /* save the length of the list for the new element me */ - Len [me] = p - pme1 ; - if (Len [me] == 0) - { - /* there is nothing left of the current pivot element */ - /* it is a root of the assembly tree */ - Pe [me] = EMPTY ; - W [me] = 0 ; - } - if (elenme != 0) - { - /* element was not constructed in place: deallocate part of */ - /* it since newly nonprincipal variables may have been removed */ - pfree = p ; - } - - /* The new element has nvpiv pivots and the size of the contribution - * block for a multifrontal method is degme-by-degme, not including - * the "dense" rows/columns. If the "dense" rows/columns are included, - * the frontal matrix is no larger than - * (degme+ndense)-by-(degme+ndense). - */ - - if (Info != (double *) NULL) - { - f = nvpiv ; - r = degme + ndense ; - dmax = MAX (dmax, f + r) ; - - /* number of nonzeros in L (excluding the diagonal) */ - lnzme = f*r + (f-1)*f/2 ; - lnz += lnzme ; - - /* number of divide operations for LDL' and for LU */ - ndiv += lnzme ; - - /* number of multiply-subtract pairs for LU */ - s = f*r*r + r*(f-1)*f + (f-1)*f*(2*f-1)/6 ; - nms_lu += s ; - - /* number of multiply-subtract pairs for LDL' */ - nms_ldl += (s + lnzme)/2 ; - } - -#ifndef NDEBUG - AMD_DEBUG2 (("finalize done nel "ID" n "ID"\n ::::\n", nel, n)) ; - for (pme = Pe [me] ; pme <= Pe [me] + Len [me] - 1 ; pme++) - { - AMD_DEBUG3 ((" "ID"", Iw [pme])) ; - } - AMD_DEBUG3 (("\n")) ; -#endif - - } - -/* ========================================================================= */ -/* DONE SELECTING PIVOTS */ -/* ========================================================================= */ - - if (Info != (double *) NULL) - { - - /* count the work to factorize the ndense-by-ndense submatrix */ - f = ndense ; - dmax = MAX (dmax, (double) ndense) ; - - /* number of nonzeros in L (excluding the diagonal) */ - lnzme = (f-1)*f/2 ; - lnz += lnzme ; - - /* number of divide operations for LDL' and for LU */ - ndiv += lnzme ; - - /* number of multiply-subtract pairs for LU */ - s = (f-1)*f*(2*f-1)/6 ; - nms_lu += s ; - - /* number of multiply-subtract pairs for LDL' */ - nms_ldl += (s + lnzme)/2 ; - - /* number of nz's in L (excl. diagonal) */ - Info [AMD_LNZ] = lnz ; - - /* number of divide ops for LU and LDL' */ - Info [AMD_NDIV] = ndiv ; - - /* number of multiply-subtract pairs for LDL' */ - Info [AMD_NMULTSUBS_LDL] = nms_ldl ; - - /* number of multiply-subtract pairs for LU */ - Info [AMD_NMULTSUBS_LU] = nms_lu ; - - /* number of "dense" rows/columns */ - Info [AMD_NDENSE] = ndense ; - - /* largest front is dmax-by-dmax */ - Info [AMD_DMAX] = dmax ; - - /* number of garbage collections in AMD */ - Info [AMD_NCMPA] = ncmpa ; - - /* successful ordering */ - Info [AMD_STATUS] = AMD_OK ; - } - -/* ========================================================================= */ -/* POST-ORDERING */ -/* ========================================================================= */ - -/* ------------------------------------------------------------------------- - * Variables at this point: - * - * Pe: holds the elimination tree. The parent of j is FLIP (Pe [j]), - * or EMPTY if j is a root. The tree holds both elements and - * non-principal (unordered) variables absorbed into them. - * Dense variables are non-principal and unordered. - * - * Elen: holds the size of each element, including the diagonal part. - * FLIP (Elen [e]) > 0 if e is an element. For unordered - * variables i, Elen [i] is EMPTY. - * - * Nv: Nv [e] > 0 is the number of pivots represented by the element e. - * For unordered variables i, Nv [i] is zero. - * - * Contents no longer needed: - * W, Iw, Len, Degree, Head, Next, Last. - * - * The matrix itself has been destroyed. - * - * n: the size of the matrix. - * No other scalars needed (pfree, iwlen, etc.) - * ------------------------------------------------------------------------- */ - - /* restore Pe */ - for (i = 0 ; i < n ; i++) - { - Pe [i] = FLIP (Pe [i]) ; - } - - /* restore Elen, for output information, and for postordering */ - for (i = 0 ; i < n ; i++) - { - Elen [i] = FLIP (Elen [i]) ; - } - -/* Now the parent of j is Pe [j], or EMPTY if j is a root. Elen [e] > 0 - * is the size of element e. Elen [i] is EMPTY for unordered variable i. */ - -#ifndef NDEBUG - AMD_DEBUG2 (("\nTree:\n")) ; - for (i = 0 ; i < n ; i++) - { - AMD_DEBUG2 ((" "ID" parent: "ID" ", i, Pe [i])) ; - ASSERT (Pe [i] >= EMPTY && Pe [i] < n) ; - if (Nv [i] > 0) - { - /* this is an element */ - e = i ; - AMD_DEBUG2 ((" element, size is "ID"\n", Elen [i])) ; - ASSERT (Elen [e] > 0) ; - } - AMD_DEBUG2 (("\n")) ; - } - AMD_DEBUG2 (("\nelements:\n")) ; - for (e = 0 ; e < n ; e++) - { - if (Nv [e] > 0) - { - AMD_DEBUG3 (("Element e= "ID" size "ID" nv "ID" \n", e, - Elen [e], Nv [e])) ; - } - } - AMD_DEBUG2 (("\nvariables:\n")) ; - for (i = 0 ; i < n ; i++) - { - Int cnt ; - if (Nv [i] == 0) - { - AMD_DEBUG3 (("i unordered: "ID"\n", i)) ; - j = Pe [i] ; - cnt = 0 ; - AMD_DEBUG3 ((" j: "ID"\n", j)) ; - if (j == EMPTY) - { - AMD_DEBUG3 ((" i is a dense variable\n")) ; - } - else - { - ASSERT (j >= 0 && j < n) ; - while (Nv [j] == 0) - { - AMD_DEBUG3 ((" j : "ID"\n", j)) ; - j = Pe [j] ; - AMD_DEBUG3 ((" j:: "ID"\n", j)) ; - cnt++ ; - if (cnt > n) break ; - } - e = j ; - AMD_DEBUG3 ((" got to e: "ID"\n", e)) ; - } - } - } -#endif - -/* ========================================================================= */ -/* compress the paths of the variables */ -/* ========================================================================= */ - - for (i = 0 ; i < n ; i++) - { - if (Nv [i] == 0) - { - - /* ------------------------------------------------------------- - * i is an un-ordered row. Traverse the tree from i until - * reaching an element, e. The element, e, was the principal - * supervariable of i and all nodes in the path from i to when e - * was selected as pivot. - * ------------------------------------------------------------- */ - - AMD_DEBUG1 (("Path compression, i unordered: "ID"\n", i)) ; - j = Pe [i] ; - ASSERT (j >= EMPTY && j < n) ; - AMD_DEBUG3 ((" j: "ID"\n", j)) ; - if (j == EMPTY) - { - /* Skip a dense variable. It has no parent. */ - AMD_DEBUG3 ((" i is a dense variable\n")) ; - continue ; - } - - /* while (j is a variable) */ - while (Nv [j] == 0) - { - AMD_DEBUG3 ((" j : "ID"\n", j)) ; - j = Pe [j] ; - AMD_DEBUG3 ((" j:: "ID"\n", j)) ; - ASSERT (j >= 0 && j < n) ; - } - /* got to an element e */ - e = j ; - AMD_DEBUG3 (("got to e: "ID"\n", e)) ; - - /* ------------------------------------------------------------- - * traverse the path again from i to e, and compress the path - * (all nodes point to e). Path compression allows this code to - * compute in O(n) time. - * ------------------------------------------------------------- */ - - j = i ; - /* while (j is a variable) */ - while (Nv [j] == 0) - { - jnext = Pe [j] ; - AMD_DEBUG3 (("j "ID" jnext "ID"\n", j, jnext)) ; - Pe [j] = e ; - j = jnext ; - ASSERT (j >= 0 && j < n) ; - } - } - } - -/* ========================================================================= */ -/* postorder the assembly tree */ -/* ========================================================================= */ - - AMD_postorder (n, Pe, Nv, Elen, - W, /* output order */ - Head, Next, Last) ; /* workspace */ - -/* ========================================================================= */ -/* compute output permutation and inverse permutation */ -/* ========================================================================= */ - - /* W [e] = k means that element e is the kth element in the new - * order. e is in the range 0 to n-1, and k is in the range 0 to - * the number of elements. Use Head for inverse order. */ - - for (k = 0 ; k < n ; k++) - { - Head [k] = EMPTY ; - Next [k] = EMPTY ; - } - for (e = 0 ; e < n ; e++) - { - k = W [e] ; - ASSERT ((k == EMPTY) == (Nv [e] == 0)) ; - if (k != EMPTY) - { - ASSERT (k >= 0 && k < n) ; - Head [k] = e ; - } - } - - /* construct output inverse permutation in Next, - * and permutation in Last */ - nel = 0 ; - for (k = 0 ; k < n ; k++) - { - e = Head [k] ; - if (e == EMPTY) break ; - ASSERT (e >= 0 && e < n && Nv [e] > 0) ; - Next [e] = nel ; - nel += Nv [e] ; - } - ASSERT (nel == n - ndense) ; - - /* order non-principal variables (dense, & those merged into supervar's) */ - for (i = 0 ; i < n ; i++) - { - if (Nv [i] == 0) - { - e = Pe [i] ; - ASSERT (e >= EMPTY && e < n) ; - if (e != EMPTY) - { - /* This is an unordered variable that was merged - * into element e via supernode detection or mass - * elimination of i when e became the pivot element. - * Place i in order just before e. */ - ASSERT (Next [i] == EMPTY && Nv [e] > 0) ; - Next [i] = Next [e] ; - Next [e]++ ; - } - else - { - /* This is a dense unordered variable, with no parent. - * Place it last in the output order. */ - Next [i] = nel++ ; - } - } - } - ASSERT (nel == n) ; - - AMD_DEBUG2 (("\n\nPerm:\n")) ; - for (i = 0 ; i < n ; i++) - { - k = Next [i] ; - ASSERT (k >= 0 && k < n) ; - Last [k] = i ; - AMD_DEBUG2 ((" perm ["ID"] = "ID"\n", k, i)) ; - } -} diff --git a/resources/3rdparty/glpk-4.53/src/amd/amd_aat.c b/resources/3rdparty/glpk-4.53/src/amd/amd_aat.c deleted file mode 100644 index 63bf55f52..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/amd_aat.c +++ /dev/null @@ -1,185 +0,0 @@ -/* ========================================================================= */ -/* === AMD_aat ============================================================= */ -/* ========================================================================= */ - -/* ------------------------------------------------------------------------- */ -/* AMD, Copyright (c) Timothy A. Davis, */ -/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ -/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ -/* web: http://www.cise.ufl.edu/research/sparse/amd */ -/* ------------------------------------------------------------------------- */ - -/* AMD_aat: compute the symmetry of the pattern of A, and count the number of - * nonzeros each column of A+A' (excluding the diagonal). Assumes the input - * matrix has no errors, with sorted columns and no duplicates - * (AMD_valid (n, n, Ap, Ai) must be AMD_OK, but this condition is not - * checked). - */ - -#include "amd_internal.h" - -GLOBAL size_t AMD_aat /* returns nz in A+A' */ -( - Int n, - const Int Ap [ ], - const Int Ai [ ], - Int Len [ ], /* Len [j]: length of column j of A+A', excl diagonal*/ - Int Tp [ ], /* workspace of size n */ - double Info [ ] -) -{ - Int p1, p2, p, i, j, pj, pj2, k, nzdiag, nzboth, nz ; - double sym ; - size_t nzaat ; - -#ifndef NDEBUG - AMD_debug_init ("AMD AAT") ; - for (k = 0 ; k < n ; k++) Tp [k] = EMPTY ; - ASSERT (AMD_valid (n, n, Ap, Ai) == AMD_OK) ; -#endif - - if (Info != (double *) NULL) - { - /* clear the Info array, if it exists */ - for (i = 0 ; i < AMD_INFO ; i++) - { - Info [i] = EMPTY ; - } - Info [AMD_STATUS] = AMD_OK ; - } - - for (k = 0 ; k < n ; k++) - { - Len [k] = 0 ; - } - - nzdiag = 0 ; - nzboth = 0 ; - nz = Ap [n] ; - - for (k = 0 ; k < n ; k++) - { - p1 = Ap [k] ; - p2 = Ap [k+1] ; - AMD_DEBUG2 (("\nAAT Column: "ID" p1: "ID" p2: "ID"\n", k, p1, p2)) ; - - /* construct A+A' */ - for (p = p1 ; p < p2 ; ) - { - /* scan the upper triangular part of A */ - j = Ai [p] ; - if (j < k) - { - /* entry A (j,k) is in the strictly upper triangular part, - * add both A (j,k) and A (k,j) to the matrix A+A' */ - Len [j]++ ; - Len [k]++ ; - AMD_DEBUG3 ((" upper ("ID","ID") ("ID","ID")\n", j,k, k,j)); - p++ ; - } - else if (j == k) - { - /* skip the diagonal */ - p++ ; - nzdiag++ ; - break ; - } - else /* j > k */ - { - /* first entry below the diagonal */ - break ; - } - /* scan lower triangular part of A, in column j until reaching - * row k. Start where last scan left off. */ - ASSERT (Tp [j] != EMPTY) ; - ASSERT (Ap [j] <= Tp [j] && Tp [j] <= Ap [j+1]) ; - pj2 = Ap [j+1] ; - for (pj = Tp [j] ; pj < pj2 ; ) - { - i = Ai [pj] ; - if (i < k) - { - /* A (i,j) is only in the lower part, not in upper. - * add both A (i,j) and A (j,i) to the matrix A+A' */ - Len [i]++ ; - Len [j]++ ; - AMD_DEBUG3 ((" lower ("ID","ID") ("ID","ID")\n", - i,j, j,i)) ; - pj++ ; - } - else if (i == k) - { - /* entry A (k,j) in lower part and A (j,k) in upper */ - pj++ ; - nzboth++ ; - break ; - } - else /* i > k */ - { - /* consider this entry later, when k advances to i */ - break ; - } - } - Tp [j] = pj ; - } - /* Tp [k] points to the entry just below the diagonal in column k */ - Tp [k] = p ; - } - - /* clean up, for remaining mismatched entries */ - for (j = 0 ; j < n ; j++) - { - for (pj = Tp [j] ; pj < Ap [j+1] ; pj++) - { - i = Ai [pj] ; - /* A (i,j) is only in the lower part, not in upper. - * add both A (i,j) and A (j,i) to the matrix A+A' */ - Len [i]++ ; - Len [j]++ ; - AMD_DEBUG3 ((" lower cleanup ("ID","ID") ("ID","ID")\n", - i,j, j,i)) ; - } - } - - /* --------------------------------------------------------------------- */ - /* compute the symmetry of the nonzero pattern of A */ - /* --------------------------------------------------------------------- */ - - /* Given a matrix A, the symmetry of A is: - * B = tril (spones (A), -1) + triu (spones (A), 1) ; - * sym = nnz (B & B') / nnz (B) ; - * or 1 if nnz (B) is zero. - */ - - if (nz == nzdiag) - { - sym = 1 ; - } - else - { - sym = (2 * (double) nzboth) / ((double) (nz - nzdiag)) ; - } - - nzaat = 0 ; - for (k = 0 ; k < n ; k++) - { - nzaat += Len [k] ; - } - - AMD_DEBUG1 (("AMD nz in A+A', excluding diagonal (nzaat) = %g\n", - (double) nzaat)) ; - AMD_DEBUG1 ((" nzboth: "ID" nz: "ID" nzdiag: "ID" symmetry: %g\n", - nzboth, nz, nzdiag, sym)) ; - - if (Info != (double *) NULL) - { - Info [AMD_STATUS] = AMD_OK ; - Info [AMD_N] = n ; - Info [AMD_NZ] = nz ; - Info [AMD_SYMMETRY] = sym ; /* symmetry of pattern of A */ - Info [AMD_NZDIAG] = nzdiag ; /* nonzeros on diagonal of A */ - Info [AMD_NZ_A_PLUS_AT] = nzaat ; /* nonzeros in A+A' */ - } - - return (nzaat) ; -} diff --git a/resources/3rdparty/glpk-4.53/src/amd/amd_control.c b/resources/3rdparty/glpk-4.53/src/amd/amd_control.c deleted file mode 100644 index f4d4f0dfa..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/amd_control.c +++ /dev/null @@ -1,64 +0,0 @@ -/* ========================================================================= */ -/* === AMD_control ========================================================= */ -/* ========================================================================= */ - -/* ------------------------------------------------------------------------- */ -/* AMD, Copyright (c) Timothy A. Davis, */ -/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ -/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ -/* web: http://www.cise.ufl.edu/research/sparse/amd */ -/* ------------------------------------------------------------------------- */ - -/* User-callable. Prints the control parameters for AMD. See amd.h - * for details. If the Control array is not present, the defaults are - * printed instead. - */ - -#include "amd_internal.h" - -GLOBAL void AMD_control -( - double Control [ ] -) -{ - double alpha ; - Int aggressive ; - - if (Control != (double *) NULL) - { - alpha = Control [AMD_DENSE] ; - aggressive = Control [AMD_AGGRESSIVE] != 0 ; - } - else - { - alpha = AMD_DEFAULT_DENSE ; - aggressive = AMD_DEFAULT_AGGRESSIVE ; - } - - PRINTF (("\nAMD version %d.%d.%d, %s: approximate minimum degree ordering\n" - " dense row parameter: %g\n", AMD_MAIN_VERSION, AMD_SUB_VERSION, - AMD_SUBSUB_VERSION, AMD_DATE, alpha)) ; - - if (alpha < 0) - { - PRINTF ((" no rows treated as dense\n")) ; - } - else - { - PRINTF (( - " (rows with more than max (%g * sqrt (n), 16) entries are\n" - " considered \"dense\", and placed last in output permutation)\n", - alpha)) ; - } - - if (aggressive) - { - PRINTF ((" aggressive absorption: yes\n")) ; - } - else - { - PRINTF ((" aggressive absorption: no\n")) ; - } - - PRINTF ((" size of AMD integer: %d\n\n", sizeof (Int))) ; -} diff --git a/resources/3rdparty/glpk-4.53/src/amd/amd_defaults.c b/resources/3rdparty/glpk-4.53/src/amd/amd_defaults.c deleted file mode 100644 index 820e89420..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/amd_defaults.c +++ /dev/null @@ -1,38 +0,0 @@ -/* ========================================================================= */ -/* === AMD_defaults ======================================================== */ -/* ========================================================================= */ - -/* ------------------------------------------------------------------------- */ -/* AMD, Copyright (c) Timothy A. Davis, */ -/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ -/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ -/* web: http://www.cise.ufl.edu/research/sparse/amd */ -/* ------------------------------------------------------------------------- */ - -/* User-callable. Sets default control parameters for AMD. See amd.h - * for details. - */ - -#include "amd_internal.h" - -/* ========================================================================= */ -/* === AMD defaults ======================================================== */ -/* ========================================================================= */ - -GLOBAL void AMD_defaults -( - double Control [ ] -) -{ - Int i ; - - if (Control != (double *) NULL) - { - for (i = 0 ; i < AMD_CONTROL ; i++) - { - Control [i] = 0 ; - } - Control [AMD_DENSE] = AMD_DEFAULT_DENSE ; - Control [AMD_AGGRESSIVE] = AMD_DEFAULT_AGGRESSIVE ; - } -} diff --git a/resources/3rdparty/glpk-4.53/src/amd/amd_dump.c b/resources/3rdparty/glpk-4.53/src/amd/amd_dump.c deleted file mode 100644 index 39bbe1d8e..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/amd_dump.c +++ /dev/null @@ -1,180 +0,0 @@ -/* ========================================================================= */ -/* === AMD_dump ============================================================ */ -/* ========================================================================= */ - -/* ------------------------------------------------------------------------- */ -/* AMD, Copyright (c) Timothy A. Davis, */ -/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ -/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ -/* web: http://www.cise.ufl.edu/research/sparse/amd */ -/* ------------------------------------------------------------------------- */ - -/* Debugging routines for AMD. Not used if NDEBUG is not defined at compile- - * time (the default). See comments in amd_internal.h on how to enable - * debugging. Not user-callable. - */ - -#include "amd_internal.h" - -#ifndef NDEBUG - -/* This global variable is present only when debugging */ -GLOBAL Int AMD_debug = -999 ; /* default is no debug printing */ - -/* ========================================================================= */ -/* === AMD_debug_init ====================================================== */ -/* ========================================================================= */ - -/* Sets the debug print level, by reading the file debug.amd (if it exists) */ - -GLOBAL void AMD_debug_init ( char *s ) -{ - FILE *f ; - f = fopen ("debug.amd", "r") ; - if (f == (FILE *) NULL) - { - AMD_debug = -999 ; - } - else - { - fscanf (f, ID, &AMD_debug) ; - fclose (f) ; - } - if (AMD_debug >= 0) - { - printf ("%s: AMD_debug_init, D= "ID"\n", s, AMD_debug) ; - } -} - -/* ========================================================================= */ -/* === AMD_dump ============================================================ */ -/* ========================================================================= */ - -/* Dump AMD's data structure, except for the hash buckets. This routine - * cannot be called when the hash buckets are non-empty. - */ - -GLOBAL void AMD_dump ( - Int n, /* A is n-by-n */ - Int Pe [ ], /* pe [0..n-1]: index in iw of start of row i */ - Int Iw [ ], /* workspace of size iwlen, iwlen [0..pfree-1] - * holds the matrix on input */ - Int Len [ ], /* len [0..n-1]: length for row i */ - Int iwlen, /* length of iw */ - Int pfree, /* iw [pfree ... iwlen-1] is empty on input */ - Int Nv [ ], /* nv [0..n-1] */ - Int Next [ ], /* next [0..n-1] */ - Int Last [ ], /* last [0..n-1] */ - Int Head [ ], /* head [0..n-1] */ - Int Elen [ ], /* size n */ - Int Degree [ ], /* size n */ - Int W [ ], /* size n */ - Int nel -) -{ - Int i, pe, elen, nv, len, e, p, k, j, deg, w, cnt, ilast ; - - if (AMD_debug < 0) return ; - ASSERT (pfree <= iwlen) ; - AMD_DEBUG3 (("\nAMD dump, pfree: "ID"\n", pfree)) ; - for (i = 0 ; i < n ; i++) - { - pe = Pe [i] ; - elen = Elen [i] ; - nv = Nv [i] ; - len = Len [i] ; - w = W [i] ; - - if (elen >= EMPTY) - { - if (nv == 0) - { - AMD_DEBUG3 (("\nI "ID": nonprincipal: ", i)) ; - ASSERT (elen == EMPTY) ; - if (pe == EMPTY) - { - AMD_DEBUG3 ((" dense node\n")) ; - ASSERT (w == 1) ; - } - else - { - ASSERT (pe < EMPTY) ; - AMD_DEBUG3 ((" i "ID" -> parent "ID"\n", i, FLIP (Pe[i]))); - } - } - else - { - AMD_DEBUG3 (("\nI "ID": active principal supervariable:\n",i)); - AMD_DEBUG3 ((" nv(i): "ID" Flag: %d\n", nv, (nv < 0))) ; - ASSERT (elen >= 0) ; - ASSERT (nv > 0 && pe >= 0) ; - p = pe ; - AMD_DEBUG3 ((" e/s: ")) ; - if (elen == 0) AMD_DEBUG3 ((" : ")) ; - ASSERT (pe + len <= pfree) ; - for (k = 0 ; k < len ; k++) - { - j = Iw [p] ; - AMD_DEBUG3 ((" "ID"", j)) ; - ASSERT (j >= 0 && j < n) ; - if (k == elen-1) AMD_DEBUG3 ((" : ")) ; - p++ ; - } - AMD_DEBUG3 (("\n")) ; - } - } - else - { - e = i ; - if (w == 0) - { - AMD_DEBUG3 (("\nE "ID": absorbed element: w "ID"\n", e, w)) ; - ASSERT (nv > 0 && pe < 0) ; - AMD_DEBUG3 ((" e "ID" -> parent "ID"\n", e, FLIP (Pe [e]))) ; - } - else - { - AMD_DEBUG3 (("\nE "ID": unabsorbed element: w "ID"\n", e, w)) ; - ASSERT (nv > 0 && pe >= 0) ; - p = pe ; - AMD_DEBUG3 ((" : ")) ; - ASSERT (pe + len <= pfree) ; - for (k = 0 ; k < len ; k++) - { - j = Iw [p] ; - AMD_DEBUG3 ((" "ID"", j)) ; - ASSERT (j >= 0 && j < n) ; - p++ ; - } - AMD_DEBUG3 (("\n")) ; - } - } - } - - /* this routine cannot be called when the hash buckets are non-empty */ - AMD_DEBUG3 (("\nDegree lists:\n")) ; - if (nel >= 0) - { - cnt = 0 ; - for (deg = 0 ; deg < n ; deg++) - { - if (Head [deg] == EMPTY) continue ; - ilast = EMPTY ; - AMD_DEBUG3 ((ID": \n", deg)) ; - for (i = Head [deg] ; i != EMPTY ; i = Next [i]) - { - AMD_DEBUG3 ((" "ID" : next "ID" last "ID" deg "ID"\n", - i, Next [i], Last [i], Degree [i])) ; - ASSERT (i >= 0 && i < n && ilast == Last [i] && - deg == Degree [i]) ; - cnt += Nv [i] ; - ilast = i ; - } - AMD_DEBUG3 (("\n")) ; - } - ASSERT (cnt == n - nel) ; - } - -} - -#endif diff --git a/resources/3rdparty/glpk-4.53/src/amd/amd_info.c b/resources/3rdparty/glpk-4.53/src/amd/amd_info.c deleted file mode 100644 index e7b806a97..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/amd_info.c +++ /dev/null @@ -1,120 +0,0 @@ -/* ========================================================================= */ -/* === AMD_info ============================================================ */ -/* ========================================================================= */ - -/* ------------------------------------------------------------------------- */ -/* AMD, Copyright (c) Timothy A. Davis, */ -/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ -/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ -/* web: http://www.cise.ufl.edu/research/sparse/amd */ -/* ------------------------------------------------------------------------- */ - -/* User-callable. Prints the output statistics for AMD. See amd.h - * for details. If the Info array is not present, nothing is printed. - */ - -#include "amd_internal.h" - -#define PRI(format,x) { if (x >= 0) { PRINTF ((format, x)) ; }} - -GLOBAL void AMD_info -( - double Info [ ] -) -{ - double n, ndiv, nmultsubs_ldl, nmultsubs_lu, lnz, lnzd ; - - PRINTF (("\nAMD version %d.%d.%d, %s, results:\n", - AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION, AMD_DATE)) ; - - if (!Info) - { - return ; - } - - n = Info [AMD_N] ; - ndiv = Info [AMD_NDIV] ; - nmultsubs_ldl = Info [AMD_NMULTSUBS_LDL] ; - nmultsubs_lu = Info [AMD_NMULTSUBS_LU] ; - lnz = Info [AMD_LNZ] ; - lnzd = (n >= 0 && lnz >= 0) ? (n + lnz) : (-1) ; - - /* AMD return status */ - PRINTF ((" status: ")) ; - if (Info [AMD_STATUS] == AMD_OK) - { - PRINTF (("OK\n")) ; - } - else if (Info [AMD_STATUS] == AMD_OUT_OF_MEMORY) - { - PRINTF (("out of memory\n")) ; - } - else if (Info [AMD_STATUS] == AMD_INVALID) - { - PRINTF (("invalid matrix\n")) ; - } - else if (Info [AMD_STATUS] == AMD_OK_BUT_JUMBLED) - { - PRINTF (("OK, but jumbled\n")) ; - } - else - { - PRINTF (("unknown\n")) ; - } - - /* statistics about the input matrix */ - PRI (" n, dimension of A: %.20g\n", n); - PRI (" nz, number of nonzeros in A: %.20g\n", - Info [AMD_NZ]) ; - PRI (" symmetry of A: %.4f\n", - Info [AMD_SYMMETRY]) ; - PRI (" number of nonzeros on diagonal: %.20g\n", - Info [AMD_NZDIAG]) ; - PRI (" nonzeros in pattern of A+A' (excl. diagonal): %.20g\n", - Info [AMD_NZ_A_PLUS_AT]) ; - PRI (" # dense rows/columns of A+A': %.20g\n", - Info [AMD_NDENSE]) ; - - /* statistics about AMD's behavior */ - PRI (" memory used, in bytes: %.20g\n", - Info [AMD_MEMORY]) ; - PRI (" # of memory compactions: %.20g\n", - Info [AMD_NCMPA]) ; - - /* statistics about the ordering quality */ - PRINTF (("\n" - " The following approximate statistics are for a subsequent\n" - " factorization of A(P,P) + A(P,P)'. They are slight upper\n" - " bounds if there are no dense rows/columns in A+A', and become\n" - " looser if dense rows/columns exist.\n\n")) ; - - PRI (" nonzeros in L (excluding diagonal): %.20g\n", - lnz) ; - PRI (" nonzeros in L (including diagonal): %.20g\n", - lnzd) ; - PRI (" # divide operations for LDL' or LU: %.20g\n", - ndiv) ; - PRI (" # multiply-subtract operations for LDL': %.20g\n", - nmultsubs_ldl) ; - PRI (" # multiply-subtract operations for LU: %.20g\n", - nmultsubs_lu) ; - PRI (" max nz. in any column of L (incl. diagonal): %.20g\n", - Info [AMD_DMAX]) ; - - /* total flop counts for various factorizations */ - - if (n >= 0 && ndiv >= 0 && nmultsubs_ldl >= 0 && nmultsubs_lu >= 0) - { - PRINTF (("\n" - " chol flop count for real A, sqrt counted as 1 flop: %.20g\n" - " LDL' flop count for real A: %.20g\n" - " LDL' flop count for complex A: %.20g\n" - " LU flop count for real A (with no pivoting): %.20g\n" - " LU flop count for complex A (with no pivoting): %.20g\n\n", - n + ndiv + 2*nmultsubs_ldl, - ndiv + 2*nmultsubs_ldl, - 9*ndiv + 8*nmultsubs_ldl, - ndiv + 2*nmultsubs_lu, - 9*ndiv + 8*nmultsubs_lu)) ; - } -} diff --git a/resources/3rdparty/glpk-4.53/src/amd/amd_internal.h b/resources/3rdparty/glpk-4.53/src/amd/amd_internal.h deleted file mode 100644 index b08f8436b..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/amd_internal.h +++ /dev/null @@ -1,117 +0,0 @@ -/* amd_internal.h */ - -/* Written by Andrew Makhorin . */ - -#ifndef AMD_INTERNAL_H -#define AMD_INTERNAL_H - -/* AMD will be exceedingly slow when running in debug mode. */ -#if 1 -#define NDEBUG -#endif - -#include "amd.h" -#define _GLPSTD_STDIO -#include "env.h" - -#define Int int -#define ID "%d" -#define Int_MAX INT_MAX - -#if 0 /* 15/II-2012 */ -/* now this macro is defined in glpenv.h; besides, the definiton below - depends on implementation, because size_t is an unsigned type */ -#define SIZE_T_MAX ((size_t)(-1)) -#endif - -#define EMPTY (-1) -#define FLIP(i) (-(i)-2) -#define UNFLIP(i) ((i < EMPTY) ? FLIP (i) : (i)) - -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) - -#define IMPLIES(p, q) (!(p) || (q)) - -#define GLOBAL - -#define AMD_order amd_order -#define AMD_defaults amd_defaults -#define AMD_control amd_control -#define AMD_info amd_info -#define AMD_1 amd_1 -#define AMD_2 amd_2 -#define AMD_valid amd_valid -#define AMD_aat amd_aat -#define AMD_postorder amd_postorder -#define AMD_post_tree amd_post_tree -#define AMD_dump amd_dump -#define AMD_debug amd_debug -#define AMD_debug_init amd_debug_init -#define AMD_preprocess amd_preprocess - -#define amd_malloc xmalloc -#if 0 /* 24/V-2009 */ -#define amd_free xfree -#else -#define amd_free(ptr) { if ((ptr) != NULL) xfree(ptr); } -#endif -#define amd_printf xprintf - -#define PRINTF(params) { amd_printf params; } - -#ifndef NDEBUG -#define ASSERT(expr) xassert(expr) -#define AMD_DEBUG0(params) { PRINTF(params); } -#define AMD_DEBUG1(params) { if (AMD_debug >= 1) PRINTF(params); } -#define AMD_DEBUG2(params) { if (AMD_debug >= 2) PRINTF(params); } -#define AMD_DEBUG3(params) { if (AMD_debug >= 3) PRINTF(params); } -#define AMD_DEBUG4(params) { if (AMD_debug >= 4) PRINTF(params); } -#else -#define ASSERT(expression) -#define AMD_DEBUG0(params) -#define AMD_DEBUG1(params) -#define AMD_DEBUG2(params) -#define AMD_DEBUG3(params) -#define AMD_DEBUG4(params) -#endif - -#define amd_aat _glp_amd_aat -size_t AMD_aat(Int n, const Int Ap[], const Int Ai[], Int Len[], - Int Tp[], double Info[]); - -#define amd_1 _glp_amd_1 -void AMD_1(Int n, const Int Ap[], const Int Ai[], Int P[], Int Pinv[], - Int Len[], Int slen, Int S[], double Control[], double Info[]); - -#define amd_postorder _glp_amd_postorder -void AMD_postorder(Int nn, Int Parent[], Int Npiv[], Int Fsize[], - Int Order[], Int Child[], Int Sibling[], Int Stack[]); - -#define amd_post_tree _glp_amd_post_tree -#ifndef NDEBUG -Int AMD_post_tree(Int root, Int k, Int Child[], const Int Sibling[], - Int Order[], Int Stack[], Int nn); -#else -Int AMD_post_tree(Int root, Int k, Int Child[], const Int Sibling[], - Int Order[], Int Stack[]); -#endif - -#define amd_preprocess _glp_amd_preprocess -void AMD_preprocess(Int n, const Int Ap[], const Int Ai[], Int Rp[], - Int Ri[], Int W[], Int Flag[]); - -#define amd_debug _glp_amd_debug -extern Int AMD_debug; - -#define amd_debug_init _glp_amd_debug_init -void AMD_debug_init(char *s); - -#define amd_dump _glp_amd_dump -void AMD_dump(Int n, Int Pe[], Int Iw[], Int Len[], Int iwlen, - Int pfree, Int Nv[], Int Next[], Int Last[], Int Head[], - Int Elen[], Int Degree[], Int W[], Int nel); - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/amd/amd_order.c b/resources/3rdparty/glpk-4.53/src/amd/amd_order.c deleted file mode 100644 index 332d56637..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/amd_order.c +++ /dev/null @@ -1,200 +0,0 @@ -/* ========================================================================= */ -/* === AMD_order =========================================================== */ -/* ========================================================================= */ - -/* ------------------------------------------------------------------------- */ -/* AMD, Copyright (c) Timothy A. Davis, */ -/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ -/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ -/* web: http://www.cise.ufl.edu/research/sparse/amd */ -/* ------------------------------------------------------------------------- */ - -/* User-callable AMD minimum degree ordering routine. See amd.h for - * documentation. - */ - -#include "amd_internal.h" - -/* ========================================================================= */ -/* === AMD_order =========================================================== */ -/* ========================================================================= */ - -GLOBAL Int AMD_order -( - Int n, - const Int Ap [ ], - const Int Ai [ ], - Int P [ ], - double Control [ ], - double Info [ ] -) -{ - Int *Len, *S, nz, i, *Pinv, info, status, *Rp, *Ri, *Cp, *Ci, ok ; - size_t nzaat, slen ; - double mem = 0 ; - -#ifndef NDEBUG - AMD_debug_init ("amd") ; -#endif - - /* clear the Info array, if it exists */ - info = Info != (double *) NULL ; - if (info) - { - for (i = 0 ; i < AMD_INFO ; i++) - { - Info [i] = EMPTY ; - } - Info [AMD_N] = n ; - Info [AMD_STATUS] = AMD_OK ; - } - - /* make sure inputs exist and n is >= 0 */ - if (Ai == (Int *) NULL || Ap == (Int *) NULL || P == (Int *) NULL || n < 0) - { - if (info) Info [AMD_STATUS] = AMD_INVALID ; - return (AMD_INVALID) ; /* arguments are invalid */ - } - - if (n == 0) - { - return (AMD_OK) ; /* n is 0 so there's nothing to do */ - } - - nz = Ap [n] ; - if (info) - { - Info [AMD_NZ] = nz ; - } - if (nz < 0) - { - if (info) Info [AMD_STATUS] = AMD_INVALID ; - return (AMD_INVALID) ; - } - - /* check if n or nz will cause size_t overflow */ - if (((size_t) n) >= SIZE_T_MAX / sizeof (Int) - || ((size_t) nz) >= SIZE_T_MAX / sizeof (Int)) - { - if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; - return (AMD_OUT_OF_MEMORY) ; /* problem too large */ - } - - /* check the input matrix: AMD_OK, AMD_INVALID, or AMD_OK_BUT_JUMBLED */ - status = AMD_valid (n, n, Ap, Ai) ; - - if (status == AMD_INVALID) - { - if (info) Info [AMD_STATUS] = AMD_INVALID ; - return (AMD_INVALID) ; /* matrix is invalid */ - } - - /* allocate two size-n integer workspaces */ - Len = amd_malloc (n * sizeof (Int)) ; - Pinv = amd_malloc (n * sizeof (Int)) ; - mem += n ; - mem += n ; - if (!Len || !Pinv) - { - /* :: out of memory :: */ - amd_free (Len) ; - amd_free (Pinv) ; - if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; - return (AMD_OUT_OF_MEMORY) ; - } - - if (status == AMD_OK_BUT_JUMBLED) - { - /* sort the input matrix and remove duplicate entries */ - AMD_DEBUG1 (("Matrix is jumbled\n")) ; - Rp = amd_malloc ((n+1) * sizeof (Int)) ; - Ri = amd_malloc (MAX (nz,1) * sizeof (Int)) ; - mem += (n+1) ; - mem += MAX (nz,1) ; - if (!Rp || !Ri) - { - /* :: out of memory :: */ - amd_free (Rp) ; - amd_free (Ri) ; - amd_free (Len) ; - amd_free (Pinv) ; - if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; - return (AMD_OUT_OF_MEMORY) ; - } - /* use Len and Pinv as workspace to create R = A' */ - AMD_preprocess (n, Ap, Ai, Rp, Ri, Len, Pinv) ; - Cp = Rp ; - Ci = Ri ; - } - else - { - /* order the input matrix as-is. No need to compute R = A' first */ - Rp = NULL ; - Ri = NULL ; - Cp = (Int *) Ap ; - Ci = (Int *) Ai ; - } - - /* --------------------------------------------------------------------- */ - /* determine the symmetry and count off-diagonal nonzeros in A+A' */ - /* --------------------------------------------------------------------- */ - - nzaat = AMD_aat (n, Cp, Ci, Len, P, Info) ; - AMD_DEBUG1 (("nzaat: %g\n", (double) nzaat)) ; - ASSERT ((MAX (nz-n, 0) <= nzaat) && (nzaat <= 2 * (size_t) nz)) ; - - /* --------------------------------------------------------------------- */ - /* allocate workspace for matrix, elbow room, and 6 size-n vectors */ - /* --------------------------------------------------------------------- */ - - S = NULL ; - slen = nzaat ; /* space for matrix */ - ok = ((slen + nzaat/5) >= slen) ; /* check for size_t overflow */ - slen += nzaat/5 ; /* add elbow room */ - for (i = 0 ; ok && i < 7 ; i++) - { - ok = ((slen + n) > slen) ; /* check for size_t overflow */ - slen += n ; /* size-n elbow room, 6 size-n work */ - } - mem += slen ; - ok = ok && (slen < SIZE_T_MAX / sizeof (Int)) ; /* check for overflow */ - ok = ok && (slen < Int_MAX) ; /* S[i] for Int i must be OK */ - if (ok) - { - S = amd_malloc (slen * sizeof (Int)) ; - } - AMD_DEBUG1 (("slen %g\n", (double) slen)) ; - if (!S) - { - /* :: out of memory :: (or problem too large) */ - amd_free (Rp) ; - amd_free (Ri) ; - amd_free (Len) ; - amd_free (Pinv) ; - if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; - return (AMD_OUT_OF_MEMORY) ; - } - if (info) - { - /* memory usage, in bytes. */ - Info [AMD_MEMORY] = mem * sizeof (Int) ; - } - - /* --------------------------------------------------------------------- */ - /* order the matrix */ - /* --------------------------------------------------------------------- */ - - AMD_1 (n, Cp, Ci, P, Pinv, Len, slen, S, Control, Info) ; - - /* --------------------------------------------------------------------- */ - /* free the workspace */ - /* --------------------------------------------------------------------- */ - - amd_free (Rp) ; - amd_free (Ri) ; - amd_free (Len) ; - amd_free (Pinv) ; - amd_free (S) ; - if (info) Info [AMD_STATUS] = status ; - return (status) ; /* successful ordering */ -} diff --git a/resources/3rdparty/glpk-4.53/src/amd/amd_post_tree.c b/resources/3rdparty/glpk-4.53/src/amd/amd_post_tree.c deleted file mode 100644 index bff0e263a..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/amd_post_tree.c +++ /dev/null @@ -1,121 +0,0 @@ -/* ========================================================================= */ -/* === AMD_post_tree ======================================================= */ -/* ========================================================================= */ - -/* ------------------------------------------------------------------------- */ -/* AMD, Copyright (c) Timothy A. Davis, */ -/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ -/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ -/* web: http://www.cise.ufl.edu/research/sparse/amd */ -/* ------------------------------------------------------------------------- */ - -/* Post-ordering of a supernodal elimination tree. */ - -#include "amd_internal.h" - -GLOBAL Int AMD_post_tree -( - Int root, /* root of the tree */ - Int k, /* start numbering at k */ - Int Child [ ], /* input argument of size nn, undefined on - * output. Child [i] is the head of a link - * list of all nodes that are children of node - * i in the tree. */ - const Int Sibling [ ], /* input argument of size nn, not modified. - * If f is a node in the link list of the - * children of node i, then Sibling [f] is the - * next child of node i. - */ - Int Order [ ], /* output order, of size nn. Order [i] = k - * if node i is the kth node of the reordered - * tree. */ - Int Stack [ ] /* workspace of size nn */ -#ifndef NDEBUG - , Int nn /* nodes are in the range 0..nn-1. */ -#endif -) -{ - Int f, head, h, i ; - -#if 0 - /* --------------------------------------------------------------------- */ - /* recursive version (Stack [ ] is not used): */ - /* --------------------------------------------------------------------- */ - - /* this is simple, but can caouse stack overflow if nn is large */ - i = root ; - for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) - { - k = AMD_post_tree (f, k, Child, Sibling, Order, Stack, nn) ; - } - Order [i] = k++ ; - return (k) ; -#endif - - /* --------------------------------------------------------------------- */ - /* non-recursive version, using an explicit stack */ - /* --------------------------------------------------------------------- */ - - /* push root on the stack */ - head = 0 ; - Stack [0] = root ; - - while (head >= 0) - { - /* get head of stack */ - ASSERT (head < nn) ; - i = Stack [head] ; - AMD_DEBUG1 (("head of stack "ID" \n", i)) ; - ASSERT (i >= 0 && i < nn) ; - - if (Child [i] != EMPTY) - { - /* the children of i are not yet ordered */ - /* push each child onto the stack in reverse order */ - /* so that small ones at the head of the list get popped first */ - /* and the biggest one at the end of the list gets popped last */ - for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) - { - head++ ; - ASSERT (head < nn) ; - ASSERT (f >= 0 && f < nn) ; - } - h = head ; - ASSERT (head < nn) ; - for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) - { - ASSERT (h > 0) ; - Stack [h--] = f ; - AMD_DEBUG1 (("push "ID" on stack\n", f)) ; - ASSERT (f >= 0 && f < nn) ; - } - ASSERT (Stack [h] == i) ; - - /* delete child list so that i gets ordered next time we see it */ - Child [i] = EMPTY ; - } - else - { - /* the children of i (if there were any) are already ordered */ - /* remove i from the stack and order it. Front i is kth front */ - head-- ; - AMD_DEBUG1 (("pop "ID" order "ID"\n", i, k)) ; - Order [i] = k++ ; - ASSERT (k <= nn) ; - } - -#ifndef NDEBUG - AMD_DEBUG1 (("\nStack:")) ; - for (h = head ; h >= 0 ; h--) - { - Int j = Stack [h] ; - AMD_DEBUG1 ((" "ID, j)) ; - ASSERT (j >= 0 && j < nn) ; - } - AMD_DEBUG1 (("\n\n")) ; - ASSERT (head < nn) ; -#endif - - } - return (k) ; -} diff --git a/resources/3rdparty/glpk-4.53/src/amd/amd_postorder.c b/resources/3rdparty/glpk-4.53/src/amd/amd_postorder.c deleted file mode 100644 index a3ece915c..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/amd_postorder.c +++ /dev/null @@ -1,207 +0,0 @@ -/* ========================================================================= */ -/* === AMD_postorder ======================================================= */ -/* ========================================================================= */ - -/* ------------------------------------------------------------------------- */ -/* AMD, Copyright (c) Timothy A. Davis, */ -/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ -/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ -/* web: http://www.cise.ufl.edu/research/sparse/amd */ -/* ------------------------------------------------------------------------- */ - -/* Perform a postordering (via depth-first search) of an assembly tree. */ - -#include "amd_internal.h" - -GLOBAL void AMD_postorder -( - /* inputs, not modified on output: */ - Int nn, /* nodes are in the range 0..nn-1 */ - Int Parent [ ], /* Parent [j] is the parent of j, or EMPTY if root */ - Int Nv [ ], /* Nv [j] > 0 number of pivots represented by node j, - * or zero if j is not a node. */ - Int Fsize [ ], /* Fsize [j]: size of node j */ - - /* output, not defined on input: */ - Int Order [ ], /* output post-order */ - - /* workspaces of size nn: */ - Int Child [ ], - Int Sibling [ ], - Int Stack [ ] -) -{ - Int i, j, k, parent, frsize, f, fprev, maxfrsize, bigfprev, bigf, fnext ; - - for (j = 0 ; j < nn ; j++) - { - Child [j] = EMPTY ; - Sibling [j] = EMPTY ; - } - - /* --------------------------------------------------------------------- */ - /* place the children in link lists - bigger elements tend to be last */ - /* --------------------------------------------------------------------- */ - - for (j = nn-1 ; j >= 0 ; j--) - { - if (Nv [j] > 0) - { - /* this is an element */ - parent = Parent [j] ; - if (parent != EMPTY) - { - /* place the element in link list of the children its parent */ - /* bigger elements will tend to be at the end of the list */ - Sibling [j] = Child [parent] ; - Child [parent] = j ; - } - } - } - -#ifndef NDEBUG - { - Int nels, ff, nchild ; - AMD_DEBUG1 (("\n\n================================ AMD_postorder:\n")); - nels = 0 ; - for (j = 0 ; j < nn ; j++) - { - if (Nv [j] > 0) - { - AMD_DEBUG1 (( ""ID" : nels "ID" npiv "ID" size "ID - " parent "ID" maxfr "ID"\n", j, nels, - Nv [j], Fsize [j], Parent [j], Fsize [j])) ; - /* this is an element */ - /* dump the link list of children */ - nchild = 0 ; - AMD_DEBUG1 ((" Children: ")) ; - for (ff = Child [j] ; ff != EMPTY ; ff = Sibling [ff]) - { - AMD_DEBUG1 ((ID" ", ff)) ; - ASSERT (Parent [ff] == j) ; - nchild++ ; - ASSERT (nchild < nn) ; - } - AMD_DEBUG1 (("\n")) ; - parent = Parent [j] ; - if (parent != EMPTY) - { - ASSERT (Nv [parent] > 0) ; - } - nels++ ; - } - } - } - AMD_DEBUG1 (("\n\nGo through the children of each node, and put\n" - "the biggest child last in each list:\n")) ; -#endif - - /* --------------------------------------------------------------------- */ - /* place the largest child last in the list of children for each node */ - /* --------------------------------------------------------------------- */ - - for (i = 0 ; i < nn ; i++) - { - if (Nv [i] > 0 && Child [i] != EMPTY) - { - -#ifndef NDEBUG - Int nchild ; - AMD_DEBUG1 (("Before partial sort, element "ID"\n", i)) ; - nchild = 0 ; - for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) - { - ASSERT (f >= 0 && f < nn) ; - AMD_DEBUG1 ((" f: "ID" size: "ID"\n", f, Fsize [f])) ; - nchild++ ; - ASSERT (nchild <= nn) ; - } -#endif - - /* find the biggest element in the child list */ - fprev = EMPTY ; - maxfrsize = EMPTY ; - bigfprev = EMPTY ; - bigf = EMPTY ; - for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) - { - ASSERT (f >= 0 && f < nn) ; - frsize = Fsize [f] ; - if (frsize >= maxfrsize) - { - /* this is the biggest seen so far */ - maxfrsize = frsize ; - bigfprev = fprev ; - bigf = f ; - } - fprev = f ; - } - ASSERT (bigf != EMPTY) ; - - fnext = Sibling [bigf] ; - - AMD_DEBUG1 (("bigf "ID" maxfrsize "ID" bigfprev "ID" fnext "ID - " fprev " ID"\n", bigf, maxfrsize, bigfprev, fnext, fprev)) ; - - if (fnext != EMPTY) - { - /* if fnext is EMPTY then bigf is already at the end of list */ - - if (bigfprev == EMPTY) - { - /* delete bigf from the element of the list */ - Child [i] = fnext ; - } - else - { - /* delete bigf from the middle of the list */ - Sibling [bigfprev] = fnext ; - } - - /* put bigf at the end of the list */ - Sibling [bigf] = EMPTY ; - ASSERT (Child [i] != EMPTY) ; - ASSERT (fprev != bigf) ; - ASSERT (fprev != EMPTY) ; - Sibling [fprev] = bigf ; - } - -#ifndef NDEBUG - AMD_DEBUG1 (("After partial sort, element "ID"\n", i)) ; - for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) - { - ASSERT (f >= 0 && f < nn) ; - AMD_DEBUG1 ((" "ID" "ID"\n", f, Fsize [f])) ; - ASSERT (Nv [f] > 0) ; - nchild-- ; - } - ASSERT (nchild == 0) ; -#endif - - } - } - - /* --------------------------------------------------------------------- */ - /* postorder the assembly tree */ - /* --------------------------------------------------------------------- */ - - for (i = 0 ; i < nn ; i++) - { - Order [i] = EMPTY ; - } - - k = 0 ; - - for (i = 0 ; i < nn ; i++) - { - if (Parent [i] == EMPTY && Nv [i] > 0) - { - AMD_DEBUG1 (("Root of assembly tree "ID"\n", i)) ; - k = AMD_post_tree (i, k, Child, Sibling, Order, Stack -#ifndef NDEBUG - , nn -#endif - ) ; - } - } -} diff --git a/resources/3rdparty/glpk-4.53/src/amd/amd_preprocess.c b/resources/3rdparty/glpk-4.53/src/amd/amd_preprocess.c deleted file mode 100644 index fc223fb51..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/amd_preprocess.c +++ /dev/null @@ -1,119 +0,0 @@ -/* ========================================================================= */ -/* === AMD_preprocess ====================================================== */ -/* ========================================================================= */ - -/* ------------------------------------------------------------------------- */ -/* AMD, Copyright (c) Timothy A. Davis, */ -/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ -/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ -/* web: http://www.cise.ufl.edu/research/sparse/amd */ -/* ------------------------------------------------------------------------- */ - -/* Sorts, removes duplicate entries, and transposes from the nonzero pattern of - * a column-form matrix A, to obtain the matrix R. The input matrix can have - * duplicate entries and/or unsorted columns (AMD_valid (n,Ap,Ai) must not be - * AMD_INVALID). - * - * This input condition is NOT checked. This routine is not user-callable. - */ - -#include "amd_internal.h" - -/* ========================================================================= */ -/* === AMD_preprocess ====================================================== */ -/* ========================================================================= */ - -/* AMD_preprocess does not check its input for errors or allocate workspace. - * On input, the condition (AMD_valid (n,n,Ap,Ai) != AMD_INVALID) must hold. - */ - -GLOBAL void AMD_preprocess -( - Int n, /* input matrix: A is n-by-n */ - const Int Ap [ ], /* size n+1 */ - const Int Ai [ ], /* size nz = Ap [n] */ - - /* output matrix R: */ - Int Rp [ ], /* size n+1 */ - Int Ri [ ], /* size nz (or less, if duplicates present) */ - - Int W [ ], /* workspace of size n */ - Int Flag [ ] /* workspace of size n */ -) -{ - - /* --------------------------------------------------------------------- */ - /* local variables */ - /* --------------------------------------------------------------------- */ - - Int i, j, p, p2 ; - - ASSERT (AMD_valid (n, n, Ap, Ai) != AMD_INVALID) ; - - /* --------------------------------------------------------------------- */ - /* count the entries in each row of A (excluding duplicates) */ - /* --------------------------------------------------------------------- */ - - for (i = 0 ; i < n ; i++) - { - W [i] = 0 ; /* # of nonzeros in row i (excl duplicates) */ - Flag [i] = EMPTY ; /* Flag [i] = j if i appears in column j */ - } - for (j = 0 ; j < n ; j++) - { - p2 = Ap [j+1] ; - for (p = Ap [j] ; p < p2 ; p++) - { - i = Ai [p] ; - if (Flag [i] != j) - { - /* row index i has not yet appeared in column j */ - W [i]++ ; /* one more entry in row i */ - Flag [i] = j ; /* flag row index i as appearing in col j*/ - } - } - } - - /* --------------------------------------------------------------------- */ - /* compute the row pointers for R */ - /* --------------------------------------------------------------------- */ - - Rp [0] = 0 ; - for (i = 0 ; i < n ; i++) - { - Rp [i+1] = Rp [i] + W [i] ; - } - for (i = 0 ; i < n ; i++) - { - W [i] = Rp [i] ; - Flag [i] = EMPTY ; - } - - /* --------------------------------------------------------------------- */ - /* construct the row form matrix R */ - /* --------------------------------------------------------------------- */ - - /* R = row form of pattern of A */ - for (j = 0 ; j < n ; j++) - { - p2 = Ap [j+1] ; - for (p = Ap [j] ; p < p2 ; p++) - { - i = Ai [p] ; - if (Flag [i] != j) - { - /* row index i has not yet appeared in column j */ - Ri [W [i]++] = j ; /* put col j in row i */ - Flag [i] = j ; /* flag row index i as appearing in col j*/ - } - } - } - -#ifndef NDEBUG - ASSERT (AMD_valid (n, n, Rp, Ri) == AMD_OK) ; - for (j = 0 ; j < n ; j++) - { - ASSERT (W [j] == Rp [j+1]) ; - } -#endif -} diff --git a/resources/3rdparty/glpk-4.53/src/amd/amd_valid.c b/resources/3rdparty/glpk-4.53/src/amd/amd_valid.c deleted file mode 100644 index e9e2e5ab6..000000000 --- a/resources/3rdparty/glpk-4.53/src/amd/amd_valid.c +++ /dev/null @@ -1,93 +0,0 @@ -/* ========================================================================= */ -/* === AMD_valid =========================================================== */ -/* ========================================================================= */ - -/* ------------------------------------------------------------------------- */ -/* AMD, Copyright (c) Timothy A. Davis, */ -/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ -/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ -/* web: http://www.cise.ufl.edu/research/sparse/amd */ -/* ------------------------------------------------------------------------- */ - -/* Check if a column-form matrix is valid or not. The matrix A is - * n_row-by-n_col. The row indices of entries in column j are in - * Ai [Ap [j] ... Ap [j+1]-1]. Required conditions are: - * - * n_row >= 0 - * n_col >= 0 - * nz = Ap [n_col] >= 0 number of entries in the matrix - * Ap [0] == 0 - * Ap [j] <= Ap [j+1] for all j in the range 0 to n_col. - * Ai [0 ... nz-1] must be in the range 0 to n_row-1. - * - * If any of the above conditions hold, AMD_INVALID is returned. If the - * following condition holds, AMD_OK_BUT_JUMBLED is returned (a warning, - * not an error): - * - * row indices in Ai [Ap [j] ... Ap [j+1]-1] are not sorted in ascending - * order, and/or duplicate entries exist. - * - * Otherwise, AMD_OK is returned. - * - * In v1.2 and earlier, this function returned TRUE if the matrix was valid - * (now returns AMD_OK), or FALSE otherwise (now returns AMD_INVALID or - * AMD_OK_BUT_JUMBLED). - */ - -#include "amd_internal.h" - -GLOBAL Int AMD_valid -( - /* inputs, not modified on output: */ - Int n_row, /* A is n_row-by-n_col */ - Int n_col, - const Int Ap [ ], /* column pointers of A, of size n_col+1 */ - const Int Ai [ ] /* row indices of A, of size nz = Ap [n_col] */ -) -{ - Int nz, j, p1, p2, ilast, i, p, result = AMD_OK ; - - if (n_row < 0 || n_col < 0 || Ap == NULL || Ai == NULL) - { - return (AMD_INVALID) ; - } - nz = Ap [n_col] ; - if (Ap [0] != 0 || nz < 0) - { - /* column pointers must start at Ap [0] = 0, and Ap [n] must be >= 0 */ - AMD_DEBUG0 (("column 0 pointer bad or nz < 0\n")) ; - return (AMD_INVALID) ; - } - for (j = 0 ; j < n_col ; j++) - { - p1 = Ap [j] ; - p2 = Ap [j+1] ; - AMD_DEBUG2 (("\nColumn: "ID" p1: "ID" p2: "ID"\n", j, p1, p2)) ; - if (p1 > p2) - { - /* column pointers must be ascending */ - AMD_DEBUG0 (("column "ID" pointer bad\n", j)) ; - return (AMD_INVALID) ; - } - ilast = EMPTY ; - for (p = p1 ; p < p2 ; p++) - { - i = Ai [p] ; - AMD_DEBUG3 (("row: "ID"\n", i)) ; - if (i < 0 || i >= n_row) - { - /* row index out of range */ - AMD_DEBUG0 (("index out of range, col "ID" row "ID"\n", j, i)); - return (AMD_INVALID) ; - } - if (i <= ilast) - { - /* row index unsorted, or duplicate entry present */ - AMD_DEBUG1 (("index unsorted/dupl col "ID" row "ID"\n", j, i)); - result = AMD_OK_BUT_JUMBLED ; - } - ilast = i ; - } - } - return (result) ; -} diff --git a/resources/3rdparty/glpk-4.53/src/avl.c b/resources/3rdparty/glpk-4.53/src/avl.c deleted file mode 100644 index c9b7f2203..000000000 --- a/resources/3rdparty/glpk-4.53/src/avl.c +++ /dev/null @@ -1,406 +0,0 @@ -/* avl.c (binary search tree) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "avl.h" -#include "dmp.h" -#include "env.h" - -struct AVL -{ /* AVL tree (Adelson-Velsky & Landis binary search tree) */ - DMP *pool; - /* memory pool for allocating nodes */ - AVLNODE *root; - /* pointer to the root node */ - int (*fcmp)(void *info, const void *key1, const void *key2); - /* application-defined key comparison routine */ - void *info; - /* transit pointer passed to the routine fcmp */ - int size; - /* the tree size (the total number of nodes) */ - int height; - /* the tree height */ -}; - -struct AVLNODE -{ /* node of AVL tree */ - const void *key; - /* pointer to the node key (data structure for representing keys - is supplied by the application) */ - int rank; - /* node rank = relative position of the node in its own subtree = - the number of nodes in the left subtree plus one */ - int type; - /* reserved for the application specific information */ - void *link; - /* reserved for the application specific information */ - AVLNODE *up; - /* pointer to the parent node */ - short int flag; - /* node flag: - 0 - this node is the left child of its parent (or this node is - the root of the tree and has no parent) - 1 - this node is the right child of its parent */ - short int bal; - /* node balance = the difference between heights of the right and - left subtrees: - -1 - the left subtree is higher than the right one; - 0 - the left and right subtrees have the same height; - +1 - the left subtree is lower than the right one */ - AVLNODE *left; - /* pointer to the root of the left subtree */ - AVLNODE *right; - /* pointer to the root of the right subtree */ -}; - -AVL *avl_create_tree(int (*fcmp)(void *info, const void *key1, - const void *key2), void *info) -{ /* create AVL tree */ - AVL *tree; - tree = xmalloc(sizeof(AVL)); - tree->pool = dmp_create_pool(); - tree->root = NULL; - tree->fcmp = fcmp; - tree->info = info; - tree->size = 0; - tree->height = 0; - return tree; -} - -int avl_strcmp(void *info, const void *key1, const void *key2) -{ /* compare character string keys */ - xassert(info == info); - return strcmp(key1, key2); -} - -static AVLNODE *rotate_subtree(AVL *tree, AVLNODE *node); - -AVLNODE *avl_insert_node(AVL *tree, const void *key) -{ /* insert new node into AVL tree */ - AVLNODE *p, *q, *r; - short int flag; - /* find an appropriate point for insertion */ - p = NULL; q = tree->root; - while (q != NULL) - { p = q; - if (tree->fcmp(tree->info, key, p->key) <= 0) - { flag = 0; - q = p->left; - p->rank++; - } - else - { flag = 1; - q = p->right; - } - } - /* create new node and insert it into the tree */ - r = dmp_get_atom(tree->pool, sizeof(AVLNODE)); - r->key = key; r->type = 0; r->link = NULL; - r->rank = 1; r->up = p; - r->flag = (short int)(p == NULL ? 0 : flag); - r->bal = 0; r->left = NULL; r->right = NULL; - tree->size++; - if (p == NULL) - tree->root = r; - else - if (flag == 0) p->left = r; else p->right = r; - /* go upstairs to the root and correct all subtrees affected by - insertion */ - while (p != NULL) - { if (flag == 0) - { /* the height of the left subtree of [p] is increased */ - if (p->bal > 0) - { p->bal = 0; - break; - } - if (p->bal < 0) - { rotate_subtree(tree, p); - break; - } - p->bal = -1; flag = p->flag; p = p->up; - } - else - { /* the height of the right subtree of [p] is increased */ - if (p->bal < 0) - { p->bal = 0; - break; - } - if (p->bal > 0) - { rotate_subtree(tree, p); - break; - } - p->bal = +1; flag = p->flag; p = p->up; - } - } - /* if the root has been reached, the height of the entire tree is - increased */ - if (p == NULL) tree->height++; - return r; -} - -void avl_set_node_type(AVLNODE *node, int type) -{ /* assign the type field of specified node */ - node->type = type; - return; -} - -void avl_set_node_link(AVLNODE *node, void *link) -{ /* assign the link field of specified node */ - node->link = link; - return; -} - -AVLNODE *avl_find_node(AVL *tree, const void *key) -{ /* find node in AVL tree */ - AVLNODE *p; - int c; - p = tree->root; - while (p != NULL) - { c = tree->fcmp(tree->info, key, p->key); - if (c == 0) break; - p = (c < 0 ? p->left : p->right); - } - return p; -} - -int avl_get_node_type(AVLNODE *node) -{ /* retrieve the type field of specified node */ - return node->type; -} - -void *avl_get_node_link(AVLNODE *node) -{ /* retrieve the link field of specified node */ - return node->link; -} - -static AVLNODE *find_next_node(AVL *tree, AVLNODE *node) -{ /* find next node in AVL tree */ - AVLNODE *p, *q; - if (tree->root == NULL) return NULL; - p = node; - q = (p == NULL ? tree->root : p->right); - if (q == NULL) - { /* go upstairs from the left subtree */ - for (;;) - { q = p->up; - if (q == NULL) break; - if (p->flag == 0) break; - p = q; - } - } - else - { /* go downstairs into the right subtree */ - for (;;) - { p = q->left; - if (p == NULL) break; - q = p; - } - } - return q; -} - -void avl_delete_node(AVL *tree, AVLNODE *node) -{ /* delete specified node from AVL tree */ - AVLNODE *f, *p, *q, *r, *s, *x, *y; - short int flag; - p = node; - /* if both subtrees of the specified node are non-empty, the node - should be interchanged with the next one, at least one subtree - of which is always empty */ - if (p->left == NULL || p->right == NULL) goto skip; - f = p->up; q = p->left; - r = find_next_node(tree, p); s = r->right; - if (p->right == r) - { if (f == NULL) - tree->root = r; - else - if (p->flag == 0) f->left = r; else f->right = r; - r->rank = p->rank; r->up = f; - r->flag = p->flag; r->bal = p->bal; - r->left = q; r->right = p; - q->up = r; - p->rank = 1; p->up = r; p->flag = 1; - p->bal = (short int)(s == NULL ? 0 : +1); - p->left = NULL; p->right = s; - if (s != NULL) s->up = p; - } - else - { x = p->right; y = r->up; - if (f == NULL) - tree->root = r; - else - if (p->flag == 0) f->left = r; else f->right = r; - r->rank = p->rank; r->up = f; - r->flag = p->flag; r->bal = p->bal; - r->left = q; r->right = x; - q->up = r; x->up = r; y->left = p; - p->rank = 1; p->up = y; p->flag = 0; - p->bal = (short int)(s == NULL ? 0 : +1); - p->left = NULL; p->right = s; - if (s != NULL) s->up = p; - } -skip: /* now the specified node [p] has at least one empty subtree; - go upstairs to the root and adjust the rank field of all nodes - affected by deletion */ - q = p; f = q->up; - while (f != NULL) - { if (q->flag == 0) f->rank--; - q = f; f = q->up; - } - /* delete the specified node from the tree */ - f = p->up; flag = p->flag; - q = p->left != NULL ? p->left : p->right; - if (f == NULL) - tree->root = q; - else - if (flag == 0) f->left = q; else f->right = q; - if (q != NULL) q->up = f, q->flag = flag; - tree->size--; - /* go upstairs to the root and correct all subtrees affected by - deletion */ - while (f != NULL) - { if (flag == 0) - { /* the height of the left subtree of [f] is decreased */ - if (f->bal == 0) - { f->bal = +1; - break; - } - if (f->bal < 0) - f->bal = 0; - else - { f = rotate_subtree(tree, f); - if (f->bal < 0) break; - } - flag = f->flag; f = f->up; - } - else - { /* the height of the right subtree of [f] is decreased */ - if (f->bal == 0) - { f->bal = -1; - break; - } - if (f->bal > 0) - f->bal = 0; - else - { f = rotate_subtree(tree, f); - if (f->bal > 0) break; - } - flag = f->flag; f = f->up; - } - } - /* if the root has been reached, the height of the entire tree is - decreased */ - if (f == NULL) tree->height--; - /* returns the deleted node to the memory pool */ - dmp_free_atom(tree->pool, p, sizeof(AVLNODE)); - return; -} - -static AVLNODE *rotate_subtree(AVL *tree, AVLNODE *node) -{ /* restore balance of AVL subtree */ - AVLNODE *f, *p, *q, *r, *x, *y; - xassert(node != NULL); - p = node; - if (p->bal < 0) - { /* perform negative (left) rotation */ - f = p->up; q = p->left; r = q->right; - if (q->bal <= 0) - { /* perform single negative rotation */ - if (f == NULL) - tree->root = q; - else - if (p->flag == 0) f->left = q; else f->right = q; - p->rank -= q->rank; - q->up = f; q->flag = p->flag; q->bal++; q->right = p; - p->up = q; p->flag = 1; - p->bal = (short int)(-q->bal); p->left = r; - if (r != NULL) r->up = p, r->flag = 0; - node = q; - } - else - { /* perform double negative rotation */ - x = r->left; y = r->right; - if (f == NULL) - tree->root = r; - else - if (p->flag == 0) f->left = r; else f->right = r; - p->rank -= (q->rank + r->rank); - r->rank += q->rank; - p->bal = (short int)(r->bal >= 0 ? 0 : +1); - q->bal = (short int)(r->bal <= 0 ? 0 : -1); - r->up = f; r->flag = p->flag; r->bal = 0; - r->left = q; r->right = p; - p->up = r; p->flag = 1; p->left = y; - q->up = r; q->flag = 0; q->right = x; - if (x != NULL) x->up = q, x->flag = 1; - if (y != NULL) y->up = p, y->flag = 0; - node = r; - } - } - else - { /* perform positive (right) rotation */ - f = p->up; q = p->right; r = q->left; - if (q->bal >= 0) - { /* perform single positive rotation */ - if (f == NULL) - tree->root = q; - else - if (p->flag == 0) f->left = q; else f->right = q; - q->rank += p->rank; - q->up = f; q->flag = p->flag; q->bal--; q->left = p; - p->up = q; p->flag = 0; - p->bal = (short int)(-q->bal); p->right = r; - if (r != NULL) r->up = p, r->flag = 1; - node = q; - } - else - { /* perform double positive rotation */ - x = r->left; y = r->right; - if (f == NULL) - tree->root = r; - else - if (p->flag == 0) f->left = r; else f->right = r; - q->rank -= r->rank; - r->rank += p->rank; - p->bal = (short int)(r->bal <= 0 ? 0 : -1); - q->bal = (short int)(r->bal >= 0 ? 0 : +1); - r->up = f; r->flag = p->flag; r->bal = 0; - r->left = p; r->right = q; - p->up = r; p->flag = 0; p->right = x; - q->up = r; q->flag = 1; q->left = y; - if (x != NULL) x->up = p, x->flag = 1; - if (y != NULL) y->up = q, y->flag = 0; - node = r; - } - } - return node; -} - -void avl_delete_tree(AVL *tree) -{ /* delete AVL tree */ - dmp_delete_pool(tree->pool); - xfree(tree); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/avl.h b/resources/3rdparty/glpk-4.53/src/avl.h deleted file mode 100644 index c4144c293..000000000 --- a/resources/3rdparty/glpk-4.53/src/avl.h +++ /dev/null @@ -1,74 +0,0 @@ -/* avl.h (binary search tree) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef AVL_H -#define AVL_H - -typedef struct AVL AVL; -typedef struct AVLNODE AVLNODE; - -#define avl_create_tree _glp_avl_create_tree -AVL *avl_create_tree(int (*fcmp)(void *info, const void *key1, - const void *key2), void *info); -/* create AVL tree */ - -#define avl_strcmp _glp_avl_strcmp -int avl_strcmp(void *info, const void *key1, const void *key2); -/* compare character string keys */ - -#define avl_insert_node _glp_avl_insert_node -AVLNODE *avl_insert_node(AVL *tree, const void *key); -/* insert new node into AVL tree */ - -#define avl_set_node_type _glp_avl_set_node_type -void avl_set_node_type(AVLNODE *node, int type); -/* assign the type field of specified node */ - -#define avl_set_node_link _glp_avl_set_node_link -void avl_set_node_link(AVLNODE *node, void *link); -/* assign the link field of specified node */ - -#define avl_find_node _glp_avl_find_node -AVLNODE *avl_find_node(AVL *tree, const void *key); -/* find node in AVL tree */ - -#define avl_get_node_type _glp_avl_get_node_type -int avl_get_node_type(AVLNODE *node); -/* retrieve the type field of specified node */ - -#define avl_get_node_link _glp_avl_get_node_link -void *avl_get_node_link(AVLNODE *node); -/* retrieve the link field of specified node */ - -#define avl_delete_node _glp_avl_delete_node -void avl_delete_node(AVL *tree, AVLNODE *node); -/* delete specified node from AVL tree */ - -#define avl_delete_tree _glp_avl_delete_tree -void avl_delete_tree(AVL *tree); -/* delete AVL tree */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bfd.c b/resources/3rdparty/glpk-4.53/src/bfd.c deleted file mode 100644 index 2ce5dcd37..000000000 --- a/resources/3rdparty/glpk-4.53/src/bfd.c +++ /dev/null @@ -1,576 +0,0 @@ -/* bfd.c (LP basis factorization driver) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#if 0 /* 27/IV-2013 */ -#include "glpfhv.h" -#else -#include "fhvint.h" -#endif -#include "glplpf.h" -#include "prob.h" - -/* CAUTION: DO NOT CHANGE THE LIMIT BELOW */ - -#define M_MAX 100000000 /* = 100*10^6 */ -/* maximal order of the basis matrix */ - -struct BFD -{ /* LP basis factorization */ - int valid; - /* factorization is valid only if this flag is set */ - int type; - /* factorization type: - GLP_BF_FT - LUF + Forrest-Tomlin - GLP_BF_BG - LUF + Schur compl. + Bartels-Golub - GLP_BF_GR - LUF + Schur compl. + Givens rotation */ -#if 0 /* 27/IV-2013 */ - FHV *fhv; - /* LP basis factorization (GLP_BF_FT) */ -#else - FHVINT *fi; - /* interface to FHV-factorization (GLP_BF_FT) */ -#endif - LPF *lpf; - /* LP basis factorization (GLP_BF_BG, GLP_BF_GR) */ - int lu_size; /* luf.sv_size */ - double piv_tol; /* luf.piv_tol */ - int piv_lim; /* luf.piv_lim */ - int suhl; /* luf.suhl */ - double eps_tol; /* luf.eps_tol */ - double max_gro; /* luf.max_gro */ - int nfs_max; /* fhv.hh_max */ - double upd_tol; /* fhv.upd_tol */ - int nrs_max; /* lpf.n_max */ - int rs_size; /* lpf.v_size */ - /* internal control parameters */ - int upd_lim; - /* the factorization update limit */ - int upd_cnt; - /* the factorization update count */ -}; - -/*********************************************************************** -* NAME -* -* bfd_create_it - create LP basis factorization -* -* SYNOPSIS -* -* #include "glpbfd.h" -* BFD *bfd_create_it(void); -* -* DESCRIPTION -* -* The routine bfd_create_it creates a program object, which represents -* a factorization of LP basis. -* -* RETURNS -* -* The routine bfd_create_it returns a pointer to the object created. */ - -BFD *bfd_create_it(void) -{ BFD *bfd; - bfd = xmalloc(sizeof(BFD)); - bfd->valid = 0; - bfd->type = GLP_BF_FT; -#if 0 /* 27/IV-2013 */ - bfd->fhv = NULL; -#else - bfd->fi = NULL; -#endif - bfd->lpf = NULL; - bfd->lu_size = 0; - bfd->piv_tol = 0.10; - bfd->piv_lim = 4; - bfd->suhl = 1; - bfd->eps_tol = 1e-15; - bfd->max_gro = 1e+10; - bfd->nfs_max = 100; - bfd->upd_tol = 1e-6; - bfd->nrs_max = 100; - bfd->rs_size = 1000; - bfd->upd_lim = -1; - bfd->upd_cnt = 0; - return bfd; -} - -/**********************************************************************/ - -void bfd_set_parm(BFD *bfd, const void *_parm) -{ /* change LP basis factorization control parameters */ - const glp_bfcp *parm = _parm; - xassert(bfd != NULL); - bfd->type = parm->type; - bfd->lu_size = parm->lu_size; - bfd->piv_tol = parm->piv_tol; - bfd->piv_lim = parm->piv_lim; - bfd->suhl = parm->suhl; - bfd->eps_tol = parm->eps_tol; - bfd->max_gro = parm->max_gro; - bfd->nfs_max = parm->nfs_max; - bfd->upd_tol = parm->upd_tol; - bfd->nrs_max = parm->nrs_max; - bfd->rs_size = parm->rs_size; - return; -} - -/*********************************************************************** -* NAME -* -* bfd_factorize - compute LP basis factorization -* -* SYNOPSIS -* -* #include "glpbfd.h" -* int bfd_factorize(BFD *bfd, int m, int bh[], int (*col)(void *info, -* int j, int ind[], double val[]), void *info); -* -* DESCRIPTION -* -* The routine bfd_factorize computes the factorization of the basis -* matrix B specified by the routine col. -* -* The parameter bfd specified the basis factorization data structure -* created with the routine bfd_create_it. -* -* The parameter m specifies the order of B, m > 0. -* -* The array bh specifies the basis header: bh[j], 1 <= j <= m, is the -* number of j-th column of B in some original matrix. The array bh is -* optional and can be specified as NULL. -* -* The formal routine col specifies the matrix B to be factorized. To -* obtain j-th column of A the routine bfd_factorize calls the routine -* col with the parameter j (1 <= j <= n). In response the routine col -* should store row indices and numerical values of non-zero elements -* of j-th column of B to locations ind[1,...,len] and val[1,...,len], -* respectively, where len is the number of non-zeros in j-th column -* returned on exit. Neither zero nor duplicate elements are allowed. -* -* The parameter info is a transit pointer passed to the routine col. -* -* RETURNS -* -* 0 The factorization has been successfully computed. -* -* BFD_ESING -* The specified matrix is singular within the working precision. -* -* BFD_ECOND -* The specified matrix is ill-conditioned. -* -* For more details see comments to the routine luf_factorize. */ - -int bfd_factorize(BFD *bfd, int m, const int bh[], int (*col) - (void *info, int j, int ind[], double val[]), void *info) -#if 0 /* 06/VI-2013 */ -{ LUF *luf; -#else -{ -#endif - int nov, ret; - xassert(bfd != NULL); - xassert(1 <= m && m <= M_MAX); - /* invalidate the factorization */ - bfd->valid = 0; - /* create the factorization, if necessary */ - nov = 0; - switch (bfd->type) - { case GLP_BF_FT: - if (bfd->lpf != NULL) - lpf_delete_it(bfd->lpf), bfd->lpf = NULL; -#if 0 /* 27/IV-2013 */ - if (bfd->fhv == NULL) - bfd->fhv = fhv_create_it(), nov = 1; -#else - if (bfd->fi == NULL) - bfd->fi = fhvint_create(), nov = 1; -#endif - break; - case GLP_BF_BG: - case GLP_BF_GR: -#if 0 /* 27/IV-2013 */ - if (bfd->fhv != NULL) - fhv_delete_it(bfd->fhv), bfd->fhv = NULL; -#else - if (bfd->fi != NULL) - fhvint_delete(bfd->fi), bfd->fi = NULL; -#endif - if (bfd->lpf == NULL) - bfd->lpf = lpf_create_it(), nov = 1; - break; - default: - xassert(bfd != bfd); - } -#if 0 /* 06/VI-2013 */ - /* set control parameters specific to LUF */ -#if 0 /* 27/IV-2013 */ - if (bfd->fhv != NULL) - luf = bfd->fhv->luf; -#else - if (bfd->fi != NULL) - goto skip; -#endif - else if (bfd->lpf != NULL) - luf = bfd->lpf->luf; - else - xassert(bfd != bfd); - if (nov) luf->new_sva = bfd->lu_size; - luf->piv_tol = bfd->piv_tol; - luf->piv_lim = bfd->piv_lim; - luf->suhl = bfd->suhl; - luf->eps_tol = bfd->eps_tol; - luf->max_gro = bfd->max_gro; -#endif -#if 0 /* 27/IV-2013 */ - /* set control parameters specific to FHV */ - if (bfd->fhv != NULL) - { if (nov) bfd->fhv->hh_max = bfd->nfs_max; - bfd->fhv->upd_tol = bfd->upd_tol; - } -#endif - /* set control parameters specific to LPF */ - if (bfd->lpf != NULL) - { if (nov) bfd->lpf->n_max = bfd->nrs_max; - if (nov) bfd->lpf->v_size = bfd->rs_size; - } -#if 0 /* 27/IV-2013 */ - /* try to factorize the basis matrix */ - if (bfd->fhv != NULL) - { switch (fhv_factorize(bfd->fhv, m, col, info)) - { case 0: - break; - case FHV_ESING: - ret = BFD_ESING; - goto done; - case FHV_ECOND: - ret = BFD_ECOND; - goto done; - default: - xassert(bfd != bfd); - } - } -#else -skip: /* try to factorize the basis matrix */ - if (bfd->fi != NULL) - { /* FIXME */ - if (fhvint_factorize(bfd->fi, m, col, info) != 0) - { ret = BFD_ESING; - goto done; - } - /* printf("*** FACTORIZED; m = %d ***\n", m); */ - } -#endif - else if (bfd->lpf != NULL) - { switch (lpf_factorize(bfd->lpf, m, bh, col, info)) - { case 0: - /* set the Schur complement update type */ - switch (bfd->type) - { case GLP_BF_BG: - /* Bartels-Golub update */ -#if 0 /* 11/VIII-2013 */ - bfd->lpf->scf->t_opt = SCF_TBG; -#else - bfd->lpf->t_opt = SCF_TBG; -#endif - break; - case GLP_BF_GR: - /* Givens rotations update */ -#if 0 /* 11/VIII-2013 */ - bfd->lpf->scf->t_opt = SCF_TGR; -#else - bfd->lpf->t_opt = SCF_TGR; -#endif - break; - default: - xassert(bfd != bfd); - } - break; - case LPF_ESING: - ret = BFD_ESING; - goto done; - case LPF_ECOND: - ret = BFD_ECOND; - goto done; - default: - xassert(bfd != bfd); - } - } - else - xassert(bfd != bfd); - /* the basis matrix has been successfully factorized */ - bfd->valid = 1; - bfd->upd_cnt = 0; - ret = 0; -done: /* return to the calling program */ - return ret; -} - -/*********************************************************************** -* NAME -* -* bfd_ftran - perform forward transformation (solve system B*x = b) -* -* SYNOPSIS -* -* #include "glpbfd.h" -* void bfd_ftran(BFD *bfd, double x[]); -* -* DESCRIPTION -* -* The routine bfd_ftran performs forward transformation, i.e. solves -* the system B*x = b, where B is the basis matrix, x is the vector of -* unknowns to be computed, b is the vector of right-hand sides. -* -* On entry elements of the vector b should be stored in dense format -* in locations x[1], ..., x[m], where m is the number of rows. On exit -* the routine stores elements of the vector x in the same locations. */ - -void bfd_ftran(BFD *bfd, double x[]) -{ xassert(bfd != NULL); - xassert(bfd->valid); -#if 0 /* 27/IV-2013 */ - if (bfd->fhv != NULL) - fhv_ftran(bfd->fhv, x); -#else - if (bfd->fi != NULL) - fhvint_ftran(bfd->fi, x); -#endif - else if (bfd->lpf != NULL) - lpf_ftran(bfd->lpf, x); - else - xassert(bfd != bfd); - return; -} - -/*********************************************************************** -* NAME -* -* bfd_btran - perform backward transformation (solve system B'*x = b) -* -* SYNOPSIS -* -* #include "glpbfd.h" -* void bfd_btran(BFD *bfd, double x[]); -* -* DESCRIPTION -* -* The routine bfd_btran performs backward transformation, i.e. solves -* the system B'*x = b, where B' is a matrix transposed to the basis -* matrix B, x is the vector of unknowns to be computed, b is the vector -* of right-hand sides. -* -* On entry elements of the vector b should be stored in dense format -* in locations x[1], ..., x[m], where m is the number of rows. On exit -* the routine stores elements of the vector x in the same locations. */ - -void bfd_btran(BFD *bfd, double x[]) -{ xassert(bfd != NULL); - xassert(bfd->valid); -#if 0 /* 27/IV-2013 */ - if (bfd->fhv != NULL) - fhv_btran(bfd->fhv, x); -#else - if (bfd->fi != NULL) - fhvint_btran(bfd->fi, x); -#endif - else if (bfd->lpf != NULL) - lpf_btran(bfd->lpf, x); - else - xassert(bfd != bfd); - return; -} - -/*********************************************************************** -* NAME -* -* bfd_update_it - update LP basis factorization -* -* SYNOPSIS -* -* #include "glpbfd.h" -* int bfd_update_it(BFD *bfd, int j, int bh, int len, const int ind[], -* const double val[]); -* -* DESCRIPTION -* -* The routine bfd_update_it updates the factorization of the basis -* matrix B after replacing its j-th column by a new vector. -* -* The parameter j specifies the number of column of B, which has been -* replaced, 1 <= j <= m, where m is the order of B. -* -* The parameter bh specifies the basis header entry for the new column -* of B, which is the number of the new column in some original matrix. -* This parameter is optional and can be specified as 0. -* -* Row indices and numerical values of non-zero elements of the new -* column of B should be placed in locations ind[1], ..., ind[len] and -* val[1], ..., val[len], resp., where len is the number of non-zeros -* in the column. Neither zero nor duplicate elements are allowed. -* -* RETURNS -* -* 0 The factorization has been successfully updated. -* -* BFD_ESING -* New basis matrix is singular within the working precision. -* -* BFD_ECHECK -* The factorization is inaccurate. -* -* BFD_ELIMIT -* Factorization update limit has been reached. -* -* BFD_EROOM -* Overflow of the sparse vector area. -* -* In case of non-zero return code the factorization becomes invalid. -* It should not be used until it has been recomputed with the routine -* bfd_factorize. */ - -int bfd_update_it(BFD *bfd, int j, int bh, int len, const int ind[], - const double val[]) -{ int ret; - xassert(bfd != NULL); - xassert(bfd->valid); - /* try to update the factorization */ -#if 0 /* 27/IV-2013 */ - if (bfd->fhv != NULL) - { switch (fhv_update_it(bfd->fhv, j, len, ind, val)) - { case 0: - break; - case FHV_ESING: - bfd->valid = 0; - ret = BFD_ESING; - goto done; - case FHV_ECHECK: - bfd->valid = 0; - ret = BFD_ECHECK; - goto done; - case FHV_ELIMIT: - bfd->valid = 0; - ret = BFD_ELIMIT; - goto done; - case FHV_EROOM: - bfd->valid = 0; - ret = BFD_EROOM; - goto done; - default: - xassert(bfd != bfd); - } - } -#else - if (bfd->fi != NULL) - { /* see fhv_ft_update for return codes */ - switch (fhvint_update(bfd->fi, j, len, ind, val)) - { case 0: - break; - case 1: - bfd->valid = 0; - ret = BFD_ESING; - goto done; - case 2: - case 3: - case 5: - bfd->valid = 0; - ret = BFD_ECHECK; - goto done; - case 4: - bfd->valid = 0; - ret = BFD_ELIMIT; - goto done; - default: - xassert(bfd != bfd); - } - } -#endif - else if (bfd->lpf != NULL) - { switch (lpf_update_it(bfd->lpf, j, bh, len, ind, val)) - { case 0: - break; - case LPF_ESING: - bfd->valid = 0; - ret = BFD_ESING; - goto done; - case LPF_ELIMIT: - bfd->valid = 0; - ret = BFD_ELIMIT; - goto done; - default: - xassert(bfd != bfd); - } - } - else - xassert(bfd != bfd); - /* the factorization has been successfully updated */ - /* increase the update count */ - bfd->upd_cnt++; - ret = 0; -done: /* return to the calling program */ - return ret; -} - -/**********************************************************************/ - -int bfd_get_count(BFD *bfd) -{ /* determine factorization update count */ - xassert(bfd != NULL); - xassert(bfd->valid); - return bfd->upd_cnt; -} - -/*********************************************************************** -* NAME -* -* bfd_delete_it - delete LP basis factorization -* -* SYNOPSIS -* -* #include "glpbfd.h" -* void bfd_delete_it(BFD *bfd); -* -* DESCRIPTION -* -* The routine bfd_delete_it deletes LP basis factorization specified -* by the parameter fhv and frees all memory allocated to this program -* object. */ - -void bfd_delete_it(BFD *bfd) -{ xassert(bfd != NULL); -#if 0 /* 27/IV-2013 */ - if (bfd->fhv != NULL) - fhv_delete_it(bfd->fhv); -#else - if (bfd->fi != NULL) - fhvint_delete(bfd->fi); -#endif - if (bfd->lpf != NULL) - lpf_delete_it(bfd->lpf); - xfree(bfd); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bfd.h b/resources/3rdparty/glpk-4.53/src/bfd.h deleted file mode 100644 index 98f7e44b4..000000000 --- a/resources/3rdparty/glpk-4.53/src/bfd.h +++ /dev/null @@ -1,73 +0,0 @@ -/* bfd.h (LP basis factorization driver) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef BFD_H -#define BFD_H - -typedef struct BFD BFD; - -/* return codes: */ -#define BFD_ESING 1 /* singular matrix */ -#define BFD_ECOND 2 /* ill-conditioned matrix */ -#define BFD_ECHECK 3 /* insufficient accuracy */ -#define BFD_ELIMIT 4 /* update limit reached */ -#define BFD_EROOM 5 /* SVA overflow */ - -#define bfd_create_it _glp_bfd_create_it -BFD *bfd_create_it(void); -/* create LP basis factorization */ - -#define bfd_set_parm _glp_bfd_set_parm -void bfd_set_parm(BFD *bfd, const void *parm); -/* change LP basis factorization control parameters */ - -#define bfd_factorize _glp_bfd_factorize -int bfd_factorize(BFD *bfd, int m, const int bh[], int (*col) - (void *info, int j, int ind[], double val[]), void *info); -/* compute LP basis factorization */ - -#define bfd_ftran _glp_bfd_ftran -void bfd_ftran(BFD *bfd, double x[]); -/* perform forward transformation (solve system B*x = b) */ - -#define bfd_btran _glp_bfd_btran -void bfd_btran(BFD *bfd, double x[]); -/* perform backward transformation (solve system B'*x = b) */ - -#define bfd_update_it _glp_bfd_update_it -int bfd_update_it(BFD *bfd, int j, int bh, int len, const int ind[], - const double val[]); -/* update LP basis factorization */ - -#define bfd_get_count _glp_bfd_get_count -int bfd_get_count(BFD *bfd); -/* determine factorization update count */ - -#define bfd_delete_it _glp_bfd_delete_it -void bfd_delete_it(BFD *bfd); -/* delete LP basis factorization */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bflib/fhv.c b/resources/3rdparty/glpk-4.53/src/bflib/fhv.c deleted file mode 100644 index 271460657..000000000 --- a/resources/3rdparty/glpk-4.53/src/bflib/fhv.c +++ /dev/null @@ -1,586 +0,0 @@ -/* fhv.c (sparse updatable FHV-factorization) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "fhv.h" - -/*********************************************************************** -* fhv_ft_update - update FHV-factorization (Forrest-Tomlin) -* -* This routine updates FHV-factorization of the original matrix A -* after replacing its j-th column by a new one. The routine is based -* on the method proposed by Forrest and Tomlin [1]. -* -* The parameter q specifies the number of column of A, which has been -* replaced, 1 <= q <= n, where n is the order of A. -* -* Row indices and numerical values of non-zero elements of the new -* j-th column of A should be placed in locations aq_ind[1], ..., -* aq_ind[aq_len] and aq_val[1], ..., aq_val[aq_len], respectively, -* where aq_len is the number of non-zeros. Neither zero nor duplicate -* elements are allowed. -* -* The working arrays ind, val, and work should have at least 1+n -* elements (0-th elements are not used). -* -* RETURNS -* -* 0 The factorization has been successfully updated. -* -* 1 New matrix U = P'* V * Q' is upper triangular with zero diagonal -* element u[s,s]. (Elimination was not performed.) -* -* 2 New matrix U = P'* V * Q' is upper triangular, and its diagonal -* element u[s,s] or u[t,t] is too small in magnitude. (Elimination -* was not performed.) -* -* 3 The same as 2, but after performing elimination. -* -* 4 The factorization has not been updated, because maximal number of -* updates has been reached. -* -* 5 Accuracy test failed for the updated factorization. -* -* BACKGROUND -* -* The routine is based on the updating method proposed by Forrest and -* Tomlin [1]. -* -* Let q-th column of the original matrix A have been replaced by new -* column A[q]. Then, to keep the equality A = F * H * V, q-th column -* of matrix V should be replaced by column V[q] = inv(F * H) * A[q]. -* From the standpoint of matrix U = P'* V * Q' such replacement is -* equivalent to replacement of s-th column of matrix U, where s is -* determined from q by permutation matrix Q. Thus, matrix U loses its -* upper triangular form and becomes the following: -* -* 1 s t n -* 1 x x * x x x x x x -* . x * x x x x x x -* s . . * x x x x x x -* . . * x x x x x x -* . . * . x x x x x -* . . * . . x x x x -* t . . * . . . x x x -* . . . . . . . x x -* n . . . . . . . . x -* -* where t is largest row index of a non-zero element in s-th column. -* -* The routine makes matrix U upper triangular as follows. First, it -* moves rows and columns s+1, ..., t by one position to the left and -* upwards, resp., and moves s-th row and s-th column to position t. -* Due to such symmetric permutations matrix U becomes the following -* (note that all diagonal elements remain on the diagonal, and element -* u[s,s] becomes u[t,t]): -* -* 1 s t n -* 1 x x x x x x * x x -* . x x x x x * x x -* s . . x x x x * x x -* . . . x x x * x x -* . . . . x x * x x -* . . . . . x * x x -* t . . x x x x * x x -* . . . . . . . x x -* n . . . . . . . . x -* -* Then the routine performs gaussian elimination to eliminate -* subdiagonal elements u[t,s], ..., u[t,t-1] using diagonal elements -* u[s,s], ..., u[t-1,t-1] as pivots. During the elimination process -* the routine permutes neither rows nor columns, so only t-th row is -* changed. Should note that actually all operations are performed on -* matrix V = P * U * Q, since matrix U is not stored. -* -* To keep the equality A = F * H * V, the routine appends new row-like -* factor H[k] to matrix H, and every time it applies elementary -* gaussian transformation to eliminate u[t,j'] = v[p,j] using pivot -* u[j',j'] = v[i,j], it also adds new element f[p,j] = v[p,j] / v[i,j] -* (gaussian multiplier) to factor H[k], which initially is a unity -* matrix. At the end of elimination process the row-like factor H[k] -* may look as follows: -* -* 1 n 1 s t n -* 1 1 . . . . . . . . 1 1 . . . . . . . . -* . 1 . . . . . . . . 1 . . . . . . . -* . . 1 . . . . . . s . . 1 . . . . . . -* p . x x 1 . x . x . . . . 1 . . . . . -* . . . . 1 . . . . . . . . 1 . . . . -* . . . . . 1 . . . . . . . . 1 . . . -* . . . . . . 1 . . t . . x x x x 1 . . -* . . . . . . . 1 . . . . . . . . 1 . -* n . . . . . . . . 1 n . . . . . . . . 1 -* -* H[k] inv(P) * H[k] * P -* -* If, however, s = t, no elimination is needed, in which case no new -* row-like factor is created. -* -* REFERENCES -* -* 1. J.J.H.Forrest and J.A.Tomlin, "Updated triangular factors of the -* basis to maintain sparsity in the product form simplex method," -* Math. Prog. 2 (1972), pp. 263-78. */ - -int fhv_ft_update(FHV *fhv, int q, int aq_len, const int aq_ind[], - const double aq_val[], int ind[/*1+n*/], double val[/*1+n*/], - double work[/*1+n*/]) -{ LUF *luf = fhv->luf; - int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int vr_ref = luf->vr_ref; - int *vr_ptr = &sva->ptr[vr_ref-1]; - int *vr_len = &sva->len[vr_ref-1]; - int *vr_cap = &sva->cap[vr_ref-1]; - double *vr_piv = luf->vr_piv; - int vc_ref = luf->vc_ref; - int *vc_ptr = &sva->ptr[vc_ref-1]; - int *vc_len = &sva->len[vc_ref-1]; - int *vc_cap = &sva->cap[vc_ref-1]; - int *pp_ind = luf->pp_ind; - int *pp_inv = luf->pp_inv; - int *qq_ind = luf->qq_ind; - int *qq_inv = luf->qq_inv; - int *hh_ind = fhv->hh_ind; - int hh_ref = fhv->hh_ref; - int *hh_ptr = &sva->ptr[hh_ref-1]; - int *hh_len = &sva->len[hh_ref-1]; -#if 1 /* FIXME */ - const double eps_tol = DBL_EPSILON; - const double vpq_tol = 1e-5; - const double err_tol = 1e-10; -#endif - int end, i, i_end, i_ptr, j, j_end, j_ptr, k, len, nnz, p, p_end, - p_ptr, ptr, q_end, q_ptr, s, t; - double f, vpq, temp; - /*--------------------------------------------------------------*/ - /* replace current q-th column of matrix V by new one */ - /*--------------------------------------------------------------*/ - xassert(1 <= q && q <= n); - /* convert new q-th column of matrix A to dense format */ - for (i = 1; i <= n; i++) - val[i] = 0.0; - xassert(0 <= aq_len && aq_len <= n); - for (k = 1; k <= aq_len; k++) - { i = aq_ind[k]; - xassert(1 <= i && i <= n); - xassert(val[i] == 0.0); - xassert(aq_val[k] != 0.0); - val[i] = aq_val[k]; - } - /* compute new q-th column of matrix V: - * new V[q] = inv(F * H) * (new A[q]) */ - luf->pp_ind = fhv->p0_ind; - luf->pp_inv = fhv->p0_inv; - luf_f_solve(luf, val); - luf->pp_ind = pp_ind; - luf->pp_inv = pp_inv; - fhv_h_solve(fhv, val); - /* q-th column of V = s-th column of U */ - s = qq_inv[q]; - /* determine row number of element v[p,q] that corresponds to - * diagonal element u[s,s] */ - p = pp_inv[s]; - /* convert new q-th column of V to sparse format; - * element v[p,q] = u[s,s] is not included in the element list - * and stored separately */ - vpq = 0.0; - len = 0; - for (i = 1; i <= n; i++) - { temp = val[i]; -#if 1 /* FIXME */ - if (-eps_tol < temp && temp < +eps_tol) -#endif - /* nop */; - else if (i == p) - vpq = temp; - else - { ind[++len] = i; - val[len] = temp; - } - } - /* clear q-th column of matrix V */ - for (q_end = (q_ptr = vc_ptr[q]) + vc_len[q]; - q_ptr < q_end; q_ptr++) - { /* get row index of v[i,q] */ - i = sv_ind[q_ptr]; - /* find and remove v[i,q] from i-th row */ - for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; - sv_ind[i_ptr] != q; i_ptr++) - /* nop */; - xassert(i_ptr < i_end); - sv_ind[i_ptr] = sv_ind[i_end-1]; - sv_val[i_ptr] = sv_val[i_end-1]; - vr_len[i]--; - } - /* now q-th column of matrix V is empty */ - vc_len[q] = 0; - /* put new q-th column of V (except element v[p,q] = u[s,s]) in - * column-wise format */ - if (len > 0) - { if (vc_cap[q] < len) - { if (sva->r_ptr - sva->m_ptr < len) - { sva_more_space(sva, len); - sv_ind = sva->ind; - sv_val = sva->val; - } - sva_enlarge_cap(sva, vc_ref-1+q, len, 0); - } - ptr = vc_ptr[q]; - memcpy(&sv_ind[ptr], &ind[1], len * sizeof(int)); - memcpy(&sv_val[ptr], &val[1], len * sizeof(double)); - vc_len[q] = len; - } - /* put new q-th column of V (except element v[p,q] = u[s,s]) in - * row-wise format, and determine largest row number t such that - * u[s,t] != 0 */ - t = (vpq == 0.0 ? 0 : s); - for (k = 1; k <= len; k++) - { /* get row index of v[i,q] */ - i = ind[k]; - /* put v[i,q] to i-th row */ - if (vr_cap[i] == vr_len[i]) - { /* reserve extra locations in i-th row to reduce further - * relocations of that row */ -#if 1 /* FIXME */ - int need = vr_len[i] + 5; -#endif - if (sva->r_ptr - sva->m_ptr < need) - { sva_more_space(sva, need); - sv_ind = sva->ind; - sv_val = sva->val; - } - sva_enlarge_cap(sva, vr_ref-1+i, need, 0); - } - sv_ind[ptr = vr_ptr[i] + (vr_len[i]++)] = q; - sv_val[ptr] = val[k]; - /* v[i,q] is non-zero; increase t */ - if (t < pp_ind[i]) - t = pp_ind[i]; - } - /*--------------------------------------------------------------*/ - /* check if matrix U is already upper triangular */ - /*--------------------------------------------------------------*/ - /* check if there is a spike in s-th column of matrix U, which - * is q-th column of matrix V */ - if (s >= t) - { /* no spike; matrix U is already upper triangular */ - /* store its diagonal element u[s,s] = v[p,q] */ - vr_piv[p] = vpq; - if (s > t) - { /* matrix U is structurally singular, because its diagonal - * element u[s,s] = v[p,q] is exact zero */ - xassert(vpq == 0.0); - return 1; - } -#if 1 /* FIXME */ - else if (-vpq_tol < vpq && vpq < +vpq_tol) -#endif - { /* matrix U is not well conditioned, because its diagonal - * element u[s,s] = v[p,q] is too small in magnitude */ - return 2; - } - else - { /* normal case */ - return 0; - } - } - /*--------------------------------------------------------------*/ - /* perform implicit symmetric permutations of rows and columns */ - /* of matrix U */ - /*--------------------------------------------------------------*/ - /* currently v[p,q] = u[s,s] */ - xassert(p == pp_inv[s] && q == qq_ind[s]); - for (k = s; k < t; k++) - { pp_ind[pp_inv[k] = pp_inv[k+1]] = k; - qq_inv[qq_ind[k] = qq_ind[k+1]] = k; - } - /* now v[p,q] = u[t,t] */ - pp_ind[pp_inv[t] = p] = qq_inv[qq_ind[t] = q] = t; - /*--------------------------------------------------------------*/ - /* check if matrix U is already upper triangular */ - /*--------------------------------------------------------------*/ - /* check if there is a spike in t-th row of matrix U, which is - * p-th row of matrix V */ - for (p_end = (p_ptr = vr_ptr[p]) + vr_len[p]; - p_ptr < p_end; p_ptr++) - { if (qq_inv[sv_ind[p_ptr]] < t) - break; /* spike detected */ - } - if (p_ptr == p_end) - { /* no spike; matrix U is already upper triangular */ - /* store its diagonal element u[t,t] = v[p,q] */ - vr_piv[p] = vpq; -#if 1 /* FIXME */ - if (-vpq_tol < vpq && vpq < +vpq_tol) -#endif - { /* matrix U is not well conditioned, because its diagonal - * element u[t,t] = v[p,q] is too small in magnitude */ - return 2; - } - else - { /* normal case */ - return 0; - } - } - /*--------------------------------------------------------------*/ - /* copy p-th row of matrix V, which is t-th row of matrix U, to */ - /* working array */ - /*--------------------------------------------------------------*/ - /* copy p-th row of matrix V, including element v[p,q] = u[t,t], - * to the working array in dense format and remove these elements - * from matrix V; since no pivoting is used, only this row will - * change during elimination */ - for (j = 1; j <= n; j++) - work[j] = 0.0; - work[q] = vpq; - for (p_end = (p_ptr = vr_ptr[p]) + vr_len[p]; - p_ptr < p_end; p_ptr++) - { /* get column index of v[p,j] and store this element to the - * working array */ - work[j = sv_ind[p_ptr]] = sv_val[p_ptr]; - /* find and remove v[p,j] from j-th column */ - for (j_end = (j_ptr = vc_ptr[j]) + vc_len[j]; - sv_ind[j_ptr] != p; j_ptr++) - /* nop */; - xassert(j_ptr < j_end); - sv_ind[j_ptr] = sv_ind[j_end-1]; - sv_val[j_ptr] = sv_val[j_end-1]; - vc_len[j]--; - } - /* now p-th row of matrix V is temporarily empty */ - vr_len[p] = 0; - /*--------------------------------------------------------------*/ - /* perform gaussian elimination */ - /*--------------------------------------------------------------*/ - /* transform p-th row of matrix V stored in working array, which - * is t-th row of matrix U, to eliminate subdiagonal elements - * u[t,s], ..., u[t,t-1]; corresponding gaussian multipliers will - * form non-trivial row of new row-like factor */ - nnz = 0; /* number of non-zero gaussian multipliers */ - for (k = s; k < t; k++) - { /* diagonal element u[k,k] = v[i,j] is used as pivot */ - i = pp_inv[k], j = qq_ind[k]; - /* take subdiagonal element u[t,k] = v[p,j] */ - temp = work[j]; -#if 1 /* FIXME */ - if (-eps_tol < temp && temp < +eps_tol) - continue; -#endif - /* compute and save gaussian multiplier: - * f := u[t,k] / u[k,k] = v[p,j] / v[i,j] */ - ind[++nnz] = i; - val[nnz] = f = work[j] / vr_piv[i]; - /* gaussian transformation to eliminate u[t,k] = v[p,j]: - * (p-th row of V) := (p-th row of V) - f * (i-th row of V) */ - for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; - i_ptr < i_end; i_ptr++) - work[sv_ind[i_ptr]] -= f * sv_val[i_ptr]; - } - /* now matrix U is again upper triangular */ -#if 1 /* FIXME */ - if (-vpq_tol < work[q] && work[q] < +vpq_tol) -#endif - { /* however, its new diagonal element u[t,t] = v[p,q] is too - * small in magnitude */ - return 3; - } - /*--------------------------------------------------------------*/ - /* create new row-like factor H[k] and add to eta file H */ - /*--------------------------------------------------------------*/ - /* (nnz = 0 means that all subdiagonal elements were too small - * in magnitude) */ - if (nnz > 0) - { if (fhv->nfs == fhv->nfs_max) - { /* maximal number of row-like factors has been reached */ - return 4; - } - k = ++(fhv->nfs); - hh_ind[k] = p; - /* store non-trivial row of H[k] in right (dynamic) part of - * SVA (diagonal unity element is not stored) */ - if (sva->r_ptr - sva->m_ptr < nnz) - { sva_more_space(sva, nnz); - sv_ind = sva->ind; - sv_val = sva->val; - } - sva_reserve_cap(sva, fhv->hh_ref-1+k, nnz); - ptr = hh_ptr[k]; - memcpy(&sv_ind[ptr], &ind[1], nnz * sizeof(int)); - memcpy(&sv_val[ptr], &val[1], nnz * sizeof(double)); - hh_len[k] = nnz; - } - /*--------------------------------------------------------------*/ - /* copy transformed p-th row of matrix V, which is t-th row of */ - /* matrix U, from working array back to matrix V */ - /*--------------------------------------------------------------*/ - /* copy elements of transformed p-th row of matrix V, which are - * non-diagonal elements u[t,t+1], ..., u[t,n] of matrix U, from - * working array to corresponding columns of matrix V (note that - * diagonal element u[t,t] = v[p,q] not copied); also transform - * p-th row of matrix V to sparse format */ - len = 0; - for (k = t+1; k <= n; k++) - { /* j-th column of V = k-th column of U */ - j = qq_ind[k]; - /* take non-diagonal element v[p,j] = u[t,k] */ - temp = work[j]; -#if 1 /* FIXME */ - if (-eps_tol < temp && temp < +eps_tol) - continue; -#endif - /* add v[p,j] to j-th column of matrix V */ - if (vc_cap[j] == vc_len[j]) - { /* reserve extra locations in j-th column to reduce further - * relocations of that column */ -#if 1 /* FIXME */ - int need = vc_len[j] + 5; -#endif - if (sva->r_ptr - sva->m_ptr < need) - { sva_more_space(sva, need); - sv_ind = sva->ind; - sv_val = sva->val; - } - sva_enlarge_cap(sva, vc_ref-1+j, need, 0); - } - sv_ind[ptr = vc_ptr[j] + (vc_len[j]++)] = p; - sv_val[ptr] = temp; - /* store element v[p,j] = u[t,k] to working sparse vector */ - ind[++len] = j; - val[len] = temp; - } - /* copy elements from working sparse vector to p-th row of matrix - * V (this row is currently empty) */ - if (vr_cap[p] < len) - { if (sva->r_ptr - sva->m_ptr < len) - { sva_more_space(sva, len); - sv_ind = sva->ind; - sv_val = sva->val; - } - sva_enlarge_cap(sva, vr_ref-1+p, len, 0); - } - ptr = vr_ptr[p]; - memcpy(&sv_ind[ptr], &ind[1], len * sizeof(int)); - memcpy(&sv_val[ptr], &val[1], len * sizeof(double)); - vr_len[p] = len; - /* store new diagonal element u[t,t] = v[p,q] */ - vr_piv[p] = work[q]; - /*--------------------------------------------------------------*/ - /* perform accuracy test (only if new H[k] was added) */ - /*--------------------------------------------------------------*/ - if (nnz > 0) - { /* copy p-th (non-trivial) row of row-like factor H[k] (except - * unity diagonal element) to working array in dense format */ - for (j = 1; j <= n; j++) - work[j] = 0.0; - k = fhv->nfs; - for (end = (ptr = hh_ptr[k]) + hh_len[k]; ptr < end; ptr++) - work[sv_ind[ptr]] = sv_val[ptr]; - /* compute inner product of p-th (non-trivial) row of matrix - * H[k] and q-th column of matrix V */ - temp = vr_piv[p]; /* 1 * v[p,q] */ - ptr = vc_ptr[q]; - end = ptr + vc_len[q]; - for (; ptr < end; ptr++) - temp += work[sv_ind[ptr]] * sv_val[ptr]; - /* inner product should be equal to element v[p,q] *before* - * matrix V was transformed */ - /* compute relative error */ - temp = fabs(vpq - temp) / (1.0 + fabs(vpq)); -#if 1 /* FIXME */ - if (temp > err_tol) -#endif - { /* relative error is too large */ - return 5; - } - } - /* factorization has been successfully updated */ - return 0; -} - -/*********************************************************************** -* fhv_h_solve - solve system H * x = b -* -* This routine solves the system H * x = b, where the matrix H is the -* middle factor of the sparse updatable FHV-factorization. -* -* On entry the array x should contain elements of the right-hand side -* vector b in locations x[1], ..., x[n], where n is the order of the -* matrix H. On exit this array will contain elements of the solution -* vector x in the same locations. */ - -void fhv_h_solve(FHV *fhv, double x[/*1+n*/]) -{ SVA *sva = fhv->luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int nfs = fhv->nfs; - int *hh_ind = fhv->hh_ind; - int hh_ref = fhv->hh_ref; - int *hh_ptr = &sva->ptr[hh_ref-1]; - int *hh_len = &sva->len[hh_ref-1]; - int i, k, end, ptr; - double x_i; - for (k = 1; k <= nfs; k++) - { x_i = x[i = hh_ind[k]]; - for (end = (ptr = hh_ptr[k]) + hh_len[k]; ptr < end; ptr++) - x_i -= sv_val[ptr] * x[sv_ind[ptr]]; - x[i] = x_i; - } - return; -} - -/*********************************************************************** -* fhv_ht_solve - solve system H' * x = b -* -* This routine solves the system H' * x = b, where H' is a matrix -* transposed to the matrix H, which is the middle factor of the sparse -* updatable FHV-factorization. -* -* On entry the array x should contain elements of the right-hand side -* vector b in locations x[1], ..., x[n], where n is the order of the -* matrix H. On exit this array will contain elements of the solution -* vector x in the same locations. */ - -void fhv_ht_solve(FHV *fhv, double x[/*1+n*/]) -{ SVA *sva = fhv->luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int nfs = fhv->nfs; - int *hh_ind = fhv->hh_ind; - int hh_ref = fhv->hh_ref; - int *hh_ptr = &sva->ptr[hh_ref-1]; - int *hh_len = &sva->len[hh_ref-1]; - int k, end, ptr; - double x_j; - for (k = nfs; k >= 1; k--) - { if ((x_j = x[hh_ind[k]]) == 0.0) - continue; - for (end = (ptr = hh_ptr[k]) + hh_len[k]; ptr < end; ptr++) - x[sv_ind[ptr]] -= sv_val[ptr] * x_j; - } - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bflib/fhv.h b/resources/3rdparty/glpk-4.53/src/bflib/fhv.h deleted file mode 100644 index 992ca311d..000000000 --- a/resources/3rdparty/glpk-4.53/src/bflib/fhv.h +++ /dev/null @@ -1,114 +0,0 @@ -/* fhv.h (sparse updatable FHV-factorization) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef FHV_H -#define FHV_H - -#include "luf.h" - -/*********************************************************************** -* The structure FHV describes sparse updatable FHV-factorization. -* -* The FHV-factorization has the following format: -* -* A = F * H * V, (1) -* -* F = P0 * L * P0', (2) -* -* H = H[1] * H[2] * ... * H[nfs], (3) -* -* V = P * U * Q, (4) -* -* where: A is a given (unsymmetric) square matrix; F, H, V are matrix -* factors actually computed; L is a lower triangular matrix with unity -* diagonal; U is an upper tringular matrix; H[k], k = 1, 2, ..., nfs, -* is a row-like factor, which differs from unity matrix only in one -* row called a non-trivial row; P0, P, Q are permutation matrices; and -* P0' is a matrix transposed to P0. -* -* Matrices F, V, P, Q are stored in the underlying LUF object. -* -* Non-trivial rows of factors H[k] are stored as sparse vectors in the -* right (static) part of the sparse vector area (SVA). Note that unity -* diagonal elements of non-trivial rows are not stored. -* -* Matrix P0 is stored in the same way as matrix P. -* -* Matrices L and U are completely defined by matrices F, V, P, and Q, -* and therefore not stored explicitly. */ - -typedef struct FHV FHV; - -struct FHV -{ /* FHV-factorization */ - LUF *luf; - /* LU-factorization (contains matrices F, V, P, Q) */ - /*--------------------------------------------------------------*/ - /* matrix H in the form of eta file */ - int nfs_max; - /* maximal number of row-like factors (this limits the number of - * updates of the factorization) */ - int nfs; - /* current number of row-like factors, 0 <= nfs <= nfs_max */ - int *hh_ind; /* int hh_ind[1+nfs_max]; */ - /* hh_ind[0] is not used; - * hh_ind[k], 1 <= k <= nfs, is number of non-trivial row of - * factor H[k] */ - int hh_ref; - /* reference number of sparse vector in SVA, which is non-trivial - * row of factor H[1] */ -#if 0 + 0 - int *hh_ptr = &sva->ptr[hh_ref-1]; - /* hh_ptr[0] is not used; - * hh_ptr[k], 1 <= k <= nfs, is pointer to non-trivial row of - * factor H[k] */ - int *hh_len = &sva->len[hh_ref-1]; - /* hh_len[0] is not used; - * hh_len[k], 1 <= k <= nfs, is number of non-zero elements in - * non-trivial row of factor H[k] */ -#endif - /*--------------------------------------------------------------*/ - /* matrix P0 */ - int *p0_ind; /* int p0_ind[1+n]; */ - /* p0_ind[i] = j means that P0[i,j] = 1 */ - int *p0_inv; /* int p0_inv[1+n]; */ - /* p0_inv[j] = i means that P0[i,j] = 1 */ -}; - -#define fhv_ft_update _glp_fhv_ft_update -int fhv_ft_update(FHV *fhv, int q, int aq_len, const int aq_ind[], - const double aq_val[], int ind[/*1+n*/], double val[/*1+n*/], - double work[/*1+n*/]); -/* update FHV-factorization (Forrest-Tomlin) */ - -#define fhv_h_solve _glp_fhv_h_solve -void fhv_h_solve(FHV *fhv, double x[/*1+n*/]); -/* solve system H * x = b */ - -#define fhv_ht_solve _glp_fhv_ht_solve -void fhv_ht_solve(FHV *fhv, double x[/*1+n*/]); -/* solve system H' * x = b */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bflib/fhvint.c b/resources/3rdparty/glpk-4.53/src/bflib/fhvint.c deleted file mode 100644 index 9d2b25938..000000000 --- a/resources/3rdparty/glpk-4.53/src/bflib/fhvint.c +++ /dev/null @@ -1,181 +0,0 @@ -/* fhvint.c (interface to FHV-factorization) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "fhvint.h" - -FHVINT *fhvint_create(void) -{ /* create interface to FHV-factorization */ - FHVINT *fi; - fi = talloc(1, FHVINT); - fi->valid = 0; - fi->fhv = NULL; - fi->lufint = NULL; - fi->nfs_max = 0; - return fi; -} - -int fhvint_factorize(FHVINT *fi, int n, int (*col)(void *info, int j, - int ind[], double val[]), void *info) -{ /* compute FHV-factorization of specified matrix A */ - FHV *fhv; - LUFINT *lufint; - int nfs_max, old_n_max, n_max, k, ret; - xassert(n > 0); - fi->valid = 0; - /* get required value of nfs_max */ - nfs_max = fi->nfs_max; - if (nfs_max == 0) - nfs_max = 100; - xassert(nfs_max > 0); - /* create interface to LU-factorization, if necessary */ - lufint = fi->lufint; - if (lufint == NULL) - { lufint = fi->lufint = lufint_create(); - lufint->sva_n_max = 4 * n + nfs_max; - lufint->sva_size = 10 * n; - lufint->delta_n0 = 0; - lufint->delta_n = 100; - lufint->sgf_updat = 1; - } - /* compute LU-factorization of specified matrix A */ - old_n_max = lufint->n_max; - ret = lufint_factorize(lufint, n, col, info); - n_max = lufint->n_max; - /* create FHV-factorization, if necessary */ - fhv = fi->fhv; - if (fhv == NULL) - { fhv = fi->fhv = talloc(1, FHV); - fhv->luf = lufint->luf; - fhv->nfs_max = 0; - fhv->hh_ind = NULL; - fhv->p0_ind = NULL; - fhv->p0_inv = NULL; - } - /* allocate/reallocate FHV-factorization, if necessary */ - if (fhv->nfs_max != nfs_max) - { fhv->nfs_max = nfs_max; - if (fhv->hh_ind != NULL) - tfree(fhv->hh_ind); - fhv->hh_ind = talloc(1+nfs_max, int); - } - if (old_n_max < n_max) - { if (fhv->p0_ind != NULL) - tfree(fhv->p0_ind); - if (fhv->p0_inv != NULL) - tfree(fhv->p0_inv); - fhv->p0_ind = talloc(1+n_max, int); - fhv->p0_inv = talloc(1+n_max, int); - } - /* H := I */ - fhv->nfs = 0; - fhv->hh_ref = sva_alloc_vecs(fi->lufint->sva, nfs_max); - /* P0 := P */ - for (k = 1; k <= n; k++) - { fhv->p0_ind[k] = fi->lufint->luf->pp_ind[k]; - fhv->p0_inv[k] = fi->lufint->luf->pp_inv[k]; - } - /* set validation flag */ - if (ret == 0) - fi->valid = 1; - return ret; -} - -int fhvint_update(FHVINT *fi, int j, int len, const int ind[], - const double val[]) -{ /* update FHV-factorization after replacing j-th column of A */ - SGF *sgf = fi->lufint->sgf; - int *ind1 = sgf->rs_next; - double *val1 = sgf->vr_max; - double *work = sgf->work; - int ret; - xassert(fi->valid); - ret = fhv_ft_update(fi->fhv, j, len, ind, val, ind1, val1, work); - if (ret != 0) - fi->valid = 0; - return ret; -} - -void fhvint_ftran(FHVINT *fi, double x[]) -{ /* solve system A * x = b */ - FHV *fhv = fi->fhv; - LUF *luf = fhv->luf; - int n = luf->n; - int *pp_ind = luf->pp_ind; - int *pp_inv = luf->pp_inv; - SGF *sgf = fi->lufint->sgf; - double *work = sgf->work; - xassert(fi->valid); - /* A = F * H * V */ - /* x = inv(A) * b = inv(V) * inv(H) * inv(F) * b */ - luf->pp_ind = fhv->p0_ind; - luf->pp_inv = fhv->p0_inv; - luf_f_solve(luf, x); - luf->pp_ind = pp_ind; - luf->pp_inv = pp_inv; - fhv_h_solve(fhv, x); - luf_v_solve(luf, x, work); - memcpy(&x[1], &work[1], n * sizeof(double)); - return; -} - -void fhvint_btran(FHVINT *fi, double x[]) -{ /* solve system A'* x = b */ - FHV *fhv = fi->fhv; - LUF *luf = fhv->luf; - int n = luf->n; - int *pp_ind = luf->pp_ind; - int *pp_inv = luf->pp_inv; - SGF *sgf = fi->lufint->sgf; - double *work = sgf->work; - xassert(fi->valid); - /* A' = (F * H * V)' = V'* H'* F' */ - /* x = inv(A') * b = inv(F') * inv(H') * inv(V') * b */ - luf_vt_solve(luf, x, work); - fhv_ht_solve(fhv, work); - luf->pp_ind = fhv->p0_ind; - luf->pp_inv = fhv->p0_inv; - luf_ft_solve(luf, work); - luf->pp_ind = pp_ind; - luf->pp_inv = pp_inv; - memcpy(&x[1], &work[1], n * sizeof(double)); - return; -} - -void fhvint_delete(FHVINT *fi) -{ /* delete interface to FHV-factorization */ - FHV *fhv = fi->fhv; - LUFINT *lufint = fi->lufint; - if (fhv != NULL) - { tfree(fhv->hh_ind); - tfree(fhv->p0_ind); - tfree(fhv->p0_inv); - tfree(fhv); - } - if (lufint != NULL) - lufint_delete(fi->lufint); - tfree(fi); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bflib/fhvint.h b/resources/3rdparty/glpk-4.53/src/bflib/fhvint.h deleted file mode 100644 index 1363a9230..000000000 --- a/resources/3rdparty/glpk-4.53/src/bflib/fhvint.h +++ /dev/null @@ -1,74 +0,0 @@ -/* fhvint.h (interface to FHV-factorization) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef FHVINT_H -#define FHVINT_H - -#include "fhv.h" -#include "lufint.h" - -typedef struct FHVINT FHVINT; - -struct FHVINT -{ /* interface to FHV-factorization */ - int valid; - /* factorization is valid only if this flag is set */ - FHV *fhv; - /* FHV-factorization */ - LUFINT *lufint; - /* interface to underlying LU-factorization */ - /*--------------------------------------------------------------*/ - /* control parameters */ - int nfs_max; - /* required maximal number of row-like factors */ -}; - -#define fhvint_create _glp_fhvint_create -FHVINT *fhvint_create(void); -/* create interface to FHV-factorization */ - -#define fhvint_factorize _glp_fhvint_factorize -int fhvint_factorize(FHVINT *fi, int n, int (*col)(void *info, int j, - int ind[], double val[]), void *info); -/* compute FHV-factorization of specified matrix A */ - -#define fhvint_update _glp_fhvint_update -int fhvint_update(FHVINT *fi, int j, int len, const int ind[], - const double val[]); -/* update FHV-factorization after replacing j-th column of A */ - -#define fhvint_ftran _glp_fhvint_ftran -void fhvint_ftran(FHVINT *fi, double x[]); -/* solve system A * x = b */ - -#define fhvint_btran _glp_fhvint_btran -void fhvint_btran(FHVINT *fi, double x[]); -/* solve system A'* x = b */ - -#define fhvint_delete _glp_fhvint_delete -void fhvint_delete(FHVINT *fi); -/* delete interface to FHV-factorization */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bflib/ifu.c b/resources/3rdparty/glpk-4.53/src/bflib/ifu.c deleted file mode 100644 index 9e4adc7f8..000000000 --- a/resources/3rdparty/glpk-4.53/src/bflib/ifu.c +++ /dev/null @@ -1,392 +0,0 @@ -/* ifu.c (dense updatable IFU-factorization) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "ifu.h" - -/*********************************************************************** -* ifu_expand - expand IFU-factorization -* -* This routine expands the IFU-factorization of the matrix A according -* to the following expansion of A: -* -* ( A c ) -* new A = ( ) -* ( r' d ) -* -* where c[1,...,n] is a new column, r[1,...,n] is a new row, and d is -* a new diagonal element. -* -* From the main equality F * A = U it follows that: -* -* ( F 0 ) ( A c ) ( FA Fc ) ( U Fc ) -* ( ) ( ) = ( ) = ( ), -* ( 0 1 ) ( r' d ) ( r' d ) ( r' d ) -* -* thus, -* -* ( F 0 ) ( U Fc ) -* new F = ( ), new U = ( ). -* ( 0 1 ) ( r' d ) -* -* Note that the resulting matrix U loses its upper triangular form due -* to row spike r', which should be eliminated. */ - -void ifu_expand(IFU *ifu, double c[/*1+n*/], double r[/*1+n*/], - double d) -{ /* non-optimized version */ - int n_max = ifu->n_max; - int n = ifu->n; - double *f_ = ifu->f; - double *u_ = ifu->u; - int i, j; - double t; -# define f(i,j) f_[(i)*n_max+(j)] -# define u(i,j) u_[(i)*n_max+(j)] - xassert(0 <= n && n < n_max); - /* adjust indexing */ - c++, r++; - /* set new zero column of matrix F */ - for (i = 0; i < n; i++) - f(i,n) = 0.0; - /* set new zero row of matrix F */ - for (j = 0; j < n; j++) - f(n,j) = 0.0; - /* set new unity diagonal element of matrix F */ - f(n,n) = 1.0; - /* set new column of matrix U to vector (old F) * c */ - for (i = 0; i < n; i++) - { /* u[i,n] := (i-th row of old F) * c */ - t = 0.0; - for (j = 0; j < n; j++) - t += f(i,j) * c[j]; - u(i,n) = t; - } - /* set new row of matrix U to vector r */ - for (j = 0; j < n; j++) - u(n,j) = r[j]; - /* set new diagonal element of matrix U to scalar d */ - u(n,n) = d; - /* increase factorization order */ - ifu->n++; -# undef f -# undef u - return; -} - -/*********************************************************************** -* ifu_bg_update - update IFU-factorization (Bartels-Golub) -* -* This routine updates IFU-factorization of the matrix A according to -* its expansion (see comments to the routine ifu_expand). The routine -* is based on the method proposed by Bartels and Golub [1]. -* -* RETURNS -* -* 0 The factorization has been successfully updated. -* -* 1 On some elimination step diagional element u[k,k] to be used as -* pivot is too small in magnitude. -* -* 2 Diagonal element u[n,n] is too small in magnitude (at the end of -* update). -* -* REFERENCES -* -* 1. R.H.Bartels, G.H.Golub, "The Simplex Method of Linear Programming -* Using LU-decomposition", Comm. ACM, 12, pp. 266-68, 1969. */ - -int ifu_bg_update(IFU *ifu, double c[/*1+n*/], double r[/*1+n*/], - double d) -{ /* non-optimized version */ - int n_max = ifu->n_max; - int n = ifu->n; - double *f_ = ifu->f; - double *u_ = ifu->u; -#if 1 /* FIXME */ - double tol = 1e-5; -#endif - int j, k; - double t; -# define f(i,j) f_[(i)*n_max+(j)] -# define u(i,j) u_[(i)*n_max+(j)] - /* expand factorization */ - ifu_expand(ifu, c, r, d); - /* NOTE: n keeps its old value */ - /* eliminate spike (non-zero subdiagonal elements) in last row of - * matrix U */ - for (k = 0; k < n; k++) - { /* if |u[k,k]| < |u[n,k]|, interchange k-th and n-th rows to - * provide |u[k,k]| >= |u[n,k]| for numeric stability */ - if (fabs(u(k,k)) < fabs(u(n,k))) - { /* interchange k-th and n-th rows of matrix U */ - for (j = k; j <= n; j++) - t = u(k,j), u(k,j) = u(n,j), u(n,j) = t; - /* interchange k-th and n-th rows of matrix F to keep the - * main equality F * A = U */ - for (j = 0; j <= n; j++) - t = f(k,j), f(k,j) = f(n,j), f(n,j) = t; - } - /* now |u[k,k]| >= |u[n,k]| */ - /* check if diagonal element u[k,k] can be used as pivot */ - if (fabs(u(k,k)) < tol) - { /* u[k,k] is too small in magnitude */ - return 1; - } - /* if u[n,k] = 0, elimination is not needed */ - if (u(n,k) == 0.0) - continue; - /* compute gaussian multiplier t = u[n,k] / u[k,k] */ - t = u(n,k) / u(k,k); - /* apply gaussian transformation to eliminate u[n,k] */ - /* (n-th row of U) := (n-th row of U) - t * (k-th row of U) */ - for (j = k+1; j <= n; j++) - u(n,j) -= t * u(k,j); - /* apply the same transformation to matrix F to keep the main - * equality F * A = U */ - for (j = 0; j <= n; j++) - f(n,j) -= t * f(k,j); - } - /* now matrix U is upper triangular */ - if (fabs(u(n,n)) < tol) - { /* u[n,n] is too small in magnitude */ - return 2; - } -# undef f -# undef u - return 0; -} - -/*********************************************************************** -* The routine givens computes the parameters of Givens plane rotation -* c = cos(teta) and s = sin(teta) such that: -* -* ( c -s ) ( a ) ( r ) -* ( ) ( ) = ( ) , -* ( s c ) ( b ) ( 0 ) -* -* where a and b are given scalars. -* -* REFERENCES -* -* G.H.Golub, C.F.Van Loan, "Matrix Computations", 2nd ed. */ - -static void givens(double a, double b, double *c, double *s) -{ /* non-optimized version */ - double t; - if (b == 0.0) - (*c) = 1.0, (*s) = 0.0; - else if (fabs(a) <= fabs(b)) - t = - a / b, (*s) = 1.0 / sqrt(1.0 + t * t), (*c) = (*s) * t; - else - t = - b / a, (*c) = 1.0 / sqrt(1.0 + t * t), (*s) = (*c) * t; - return; -} - -/*********************************************************************** -* ifu_gr_update - update IFU-factorization (Givens rotations) -* -* This routine updates IFU-factorization of the matrix A according to -* its expansion (see comments to the routine ifu_expand). The routine -* is based on Givens plane rotations [1]. -* -* RETURNS -* -* 0 The factorization has been successfully updated. -* -* 1 On some elimination step both elements u[k,k] and u[n,k] are too -* small in magnitude. -* -* 2 Diagonal element u[n,n] is too small in magnitude (at the end of -* update). -* -* REFERENCES -* -* 1. G.H.Golub, C.F.Van Loan, "Matrix Computations", 2nd ed. */ - -int ifu_gr_update(IFU *ifu, double c[/*1+n*/], double r[/*1+n*/], - double d) -{ /* non-optimized version */ - int n_max = ifu->n_max; - int n = ifu->n; - double *f_ = ifu->f; - double *u_ = ifu->u; -#if 1 /* FIXME */ - double tol = 1e-5; -#endif - int j, k; - double cs, sn; -# define f(i,j) f_[(i)*n_max+(j)] -# define u(i,j) u_[(i)*n_max+(j)] - /* expand factorization */ - ifu_expand(ifu, c, r, d); - /* NOTE: n keeps its old value */ - /* eliminate spike (non-zero subdiagonal elements) in last row of - * matrix U */ - for (k = 0; k < n; k++) - { /* check if elements u[k,k] and u[n,k] are eligible */ - if (fabs(u(k,k)) < tol && fabs(u(n,k)) < tol) - { /* both u[k,k] and u[n,k] are too small in magnitude */ - return 1; - } - /* if u[n,k] = 0, elimination is not needed */ - if (u(n,k) == 0.0) - continue; - /* compute parameters of Givens plane rotation */ - givens(u(k,k), u(n,k), &cs, &sn); - /* apply Givens rotation to k-th and n-th rows of matrix U to - * eliminate u[n,k] */ - for (j = k; j <= n; j++) - { double ukj = u(k,j), unj = u(n,j); - u(k,j) = cs * ukj - sn * unj; - u(n,j) = sn * ukj + cs * unj; - } - /* apply the same transformation to matrix F to keep the main - * equality F * A = U */ - for (j = 0; j <= n; j++) - { double fkj = f(k,j), fnj = f(n,j); - f(k,j) = cs * fkj - sn * fnj; - f(n,j) = sn * fkj + cs * fnj; - } - } - /* now matrix U is upper triangular */ - if (fabs(u(n,n)) < tol) - { /* u[n,n] is too small in magnitude */ - return 2; - } -# undef f -# undef u - return 0; -} - -/*********************************************************************** -* ifu_a_solve - solve system A * x = b -* -* This routine solves the system A * x = b, where the matrix A is -* specified by its IFU-factorization. -* -* Using the main equality F * A = U we have: -* -* A * x = b => F * A * x = F * b => U * x = F * b => -* -* x = inv(U) * F * b. -* -* On entry the array x should contain elements of the right-hand side -* vector b in locations x[1], ..., x[n], where n is the order of the -* matrix A. On exit this array will contain elements of the solution -* vector x in the same locations. -* -* The working array w should have at least 1+n elements (0-th element -* is not used). */ - -void ifu_a_solve(IFU *ifu, double x[/*1+n*/], double w[/*1+n*/]) -{ /* non-optimized version */ - int n_max = ifu->n_max; - int n = ifu->n; - double *f_ = ifu->f; - double *u_ = ifu->u; - int i, j; - double t; -# define f(i,j) f_[(i)*n_max+(j)] -# define u(i,j) u_[(i)*n_max+(j)] - xassert(0 <= n && n <= n_max); - /* adjust indexing */ - x++, w++; - /* y := F * b */ - memcpy(w, x, n * sizeof(double)); - for (i = 0; i < n; i++) - { /* y[i] := (i-th row of F) * b */ - t = 0.0; - for (j = 0; j < n; j++) - t += f(i,j) * w[j]; - x[i] = t; - } - /* x := inv(U) * y */ - for (i = n-1; i >= 0; i--) - { t = x[i]; - for (j = i+1; j < n; j++) - t -= u(i,j) * x[j]; - x[i] = t / u(i,i); - } -# undef f -# undef u - return; -} - -/*********************************************************************** -* ifu_at_solve - solve system A'* x = b -* -* This routine solves the system A'* x = b, where A' is a matrix -* transposed to the matrix A, specified by its IFU-factorization. -* -* Using the main equality F * A = U, from which it follows that -* A'* F' = U', we have: -* -* A'* x = b => A'* F'* inv(F') * x = b => -* -* U'* inv(F') * x = b => inv(F') * x = inv(U') * b => -* -* x = F' * inv(U') * b. -* -* On entry the array x should contain elements of the right-hand side -* vector b in locations x[1], ..., x[n], where n is the order of the -* matrix A. On exit this array will contain elements of the solution -* vector x in the same locations. -* -* The working array w should have at least 1+n elements (0-th element -* is not used). */ - -void ifu_at_solve(IFU *ifu, double x[/*1+n*/], double w[/*1+n*/]) -{ /* non-optimized version */ - int n_max = ifu->n_max; - int n = ifu->n; - double *f_ = ifu->f; - double *u_ = ifu->u; - int i, j; - double t; -# define f(i,j) f_[(i)*n_max+(j)] -# define u(i,j) u_[(i)*n_max+(j)] - xassert(0 <= n && n <= n_max); - /* adjust indexing */ - x++, w++; - /* y := inv(U') * b */ - for (i = 0; i < n; i++) - { t = (x[i] /= u(i,i)); - for (j = i+1; j < n; j++) - x[j] -= u(i,j) * t; - } - /* x := F'* y */ - for (j = 0; j < n; j++) - { /* x[j] := (j-th column of F) * y */ - t = 0.0; - for (i = 0; i < n; i++) - t += f(i,j) * x[i]; - w[j] = t; - } - memcpy(x, w, n * sizeof(double)); -# undef f -# undef u - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bflib/ifu.h b/resources/3rdparty/glpk-4.53/src/bflib/ifu.h deleted file mode 100644 index 0d53f78f6..000000000 --- a/resources/3rdparty/glpk-4.53/src/bflib/ifu.h +++ /dev/null @@ -1,99 +0,0 @@ -/* ifu.h (dense updatable IFU-factorization) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef IFU_H -#define IFU_H - -/*********************************************************************** -* The structure IFU describes dense updatable IFU-factorization. -* -* The IFU-factorization has the following format: -* -* A = inv(F) * U, (1) -* -* where A is a given (unsymmetric) nxn square matrix, F is a square -* matrix, U is an upper triangular matrix. Obviously, the equality (1) -* is equivalent to the following equality: -* -* F * A = U. (2) -* -* It is assumed that matrix A is small and dense, so matrices F and U -* are stored by rows in dense format as follows: -* -* 1 n n_max 1 n n_max -* 1 * * * * * * x x x x 1 * * * * * * x x x x -* * * * * * * x x x x ? * * * * * x x x x -* * * * * * * x x x x ? ? * * * * x x x x -* * * * * * * x x x x ? ? ? * * * x x x x -* * * * * * * x x x x ? ? ? ? * * x x x x -* n * * * * * * x x x x n ? ? ? ? ? * x x x x -* x x x x x x x x x x x x x x x x x x x x -* x x x x x x x x x x x x x x x x x x x x -* x x x x x x x x x x x x x x x x x x x x -* n_max x x x x x x x x x x n_max x x x x x x x x x x -* -* matrix F matrix U -* -* where '*' are matrix elements, '?' are unused locations, 'x' are -* reserved locations. */ - -typedef struct IFU IFU; - -struct IFU -{ /* IFU-factorization */ - int n_max; - /* maximal order of matrices A, F, U; n_max >= 1 */ - int n; - /* current order of matrices A, F, U; 0 <= n <= n_max */ - double *f; /* double f[n_max*n_max]; */ - /* matrix F stored by rows */ - double *u; /* double u[n_max*n_max]; */ - /* matrix U stored by rows */ -}; - -#define ifu_expand _glp_ifu_expand -void ifu_expand(IFU *ifu, double c[/*1+n*/], double r[/*1+n*/], - double d); -/* expand IFU-factorization */ - -#define ifu_bg_update _glp_ifu_bg_update -int ifu_bg_update(IFU *ifu, double c[/*1+n*/], double r[/*1+n*/], - double d); -/* update IFU-factorization (Bartels-Golub) */ - -#define ifu_gr_update _glp_ifu_gr_update -int ifu_gr_update(IFU *ifu, double c[/*1+n*/], double r[/*1+n*/], - double d); -/* update IFU-factorization (Givens rotations) */ - -#define ifu_a_solve _glp_ifu_a_solve -void ifu_a_solve(IFU *ifu, double x[/*1+n*/], double w[/*1+n*/]); -/* solve system A * x = b */ - -#define ifu_at_solve _glp_ifu_at_solve -void ifu_at_solve(IFU *ifu, double x[/*1+n*/], double w[/*1+n*/]); -/* solve system A'* x = b */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bflib/luf.c b/resources/3rdparty/glpk-4.53/src/bflib/luf.c deleted file mode 100644 index adbf10451..000000000 --- a/resources/3rdparty/glpk-4.53/src/bflib/luf.c +++ /dev/null @@ -1,575 +0,0 @@ -/* luf.c (sparse LU-factorization) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "luf.h" - -/*********************************************************************** -* luf_check_all - check LU-factorization before k-th elimination step -* -* This routine checks that before performing k-th elimination step, -* 1 <= k <= n+1, all components of the LU-factorization are correct. -* -* In case of k = n+1, i.e. after last elimination step, it is assumed -* that rows of F and columns of V are *not* built yet. -* -* NOTE: For testing/debugging only. */ - -void luf_check_all(LUF *luf, int k) -{ int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int fr_ref = luf->fr_ref; - int *fr_len = &sva->len[fr_ref-1]; - int fc_ref = luf->fc_ref; - int *fc_ptr = &sva->ptr[fc_ref-1]; - int *fc_len = &sva->len[fc_ref-1]; - int vr_ref = luf->vr_ref; - int *vr_ptr = &sva->ptr[vr_ref-1]; - int *vr_len = &sva->len[vr_ref-1]; - int vc_ref = luf->vc_ref; - int *vc_ptr = &sva->ptr[vc_ref-1]; - int *vc_len = &sva->len[vc_ref-1]; - int *pp_ind = luf->pp_ind; - int *pp_inv = luf->pp_inv; - int *qq_ind = luf->qq_ind; - int *qq_inv = luf->qq_inv; - int i, ii, i_ptr, i_end, j, jj, j_ptr, j_end; - xassert(n > 0); - xassert(1 <= k && k <= n+1); - /* check permutation matrix P */ - for (i = 1; i <= n; i++) - { ii = pp_ind[i]; - xassert(1 <= ii && ii <= n); - xassert(pp_inv[ii] == i); - } - /* check permutation matrix Q */ - for (j = 1; j <= n; j++) - { jj = qq_inv[j]; - xassert(1 <= jj && jj <= n); - xassert(qq_ind[jj] == j); - } - /* check row-wise representation of matrix F */ - for (i = 1; i <= n; i++) - xassert(fr_len[i] == 0); - /* check column-wise representation of matrix F */ - for (j = 1; j <= n; j++) - { /* j-th column of F = jj-th column of L */ - jj = pp_ind[j]; - if (jj < k) - { j_ptr = fc_ptr[j]; - j_end = j_ptr + fc_len[j]; - for (; j_ptr < j_end; j_ptr++) - { i = sv_ind[j_ptr]; - xassert(1 <= i && i <= n); - ii = pp_ind[i]; /* f[i,j] = l[ii,jj] */ - xassert(ii > jj); - xassert(sv_val[j_ptr] != 0.0); - } - } - else /* jj >= k */ - xassert(fc_len[j] == 0); - } - /* check row-wise representation of matrix V */ - for (i = 1; i <= n; i++) - { /* i-th row of V = ii-th row of U */ - ii = pp_ind[i]; - i_ptr = vr_ptr[i]; - i_end = i_ptr + vr_len[i]; - for (; i_ptr < i_end; i_ptr++) - { j = sv_ind[i_ptr]; - xassert(1 <= j && j <= n); - jj = qq_inv[j]; /* v[i,j] = u[ii,jj] */ - if (ii < k) - xassert(jj > ii); - else /* ii >= k */ - { xassert(jj >= k); - /* find v[i,j] in j-th column */ - j_ptr = vc_ptr[j]; - j_end = j_ptr + vc_len[j]; - for (; sv_ind[j_ptr] != i; j_ptr++) - /* nop */; - xassert(j_ptr < j_end); - } - xassert(sv_val[i_ptr] != 0.0); - } - } - /* check column-wise representation of matrix V */ - for (j = 1; j <= n; j++) - { /* j-th column of V = jj-th column of U */ - jj = qq_inv[j]; - if (jj < k) - xassert(vc_len[j] == 0); - else /* jj >= k */ - { j_ptr = vc_ptr[j]; - j_end = j_ptr + vc_len[j]; - for (; j_ptr < j_end; j_ptr++) - { i = sv_ind[j_ptr]; - ii = pp_ind[i]; /* v[i,j] = u[ii,jj] */ - xassert(ii >= k); - /* find v[i,j] in i-th row */ - i_ptr = vr_ptr[i]; - i_end = i_ptr + vr_len[i]; - for (; sv_ind[i_ptr] != j; i_ptr++) - /* nop */; - xassert(i_ptr < i_end); - } - } - } - return; -} - -/*********************************************************************** -* luf_build_v_rows - build matrix V in row-wise format -* -* This routine builds the row-wise representation of matrix V in the -* left part of SVA using its column-wise representation. -* -* NOTE: On entry to the routine all rows of matrix V should have zero -* capacity. -* -* The working array len should have at least 1+n elements (len[0] is -* not used). */ - -void luf_build_v_rows(LUF *luf, int len[/*1+n*/]) -{ int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int vr_ref = luf->vr_ref; - int *vr_ptr = &sva->ptr[vr_ref-1]; - int *vr_len = &sva->len[vr_ref-1]; - int vc_ref = luf->vc_ref; - int *vc_ptr = &sva->ptr[vc_ref-1]; - int *vc_len = &sva->len[vc_ref-1]; - int i, j, end, nnz, ptr, ptr1; - /* calculate the number of non-zeros in each row of matrix V and - * the total number of non-zeros */ - nnz = 0; - for (i = 1; i <= n; i++) - len[i] = 0; - for (j = 1; j <= n; j++) - { nnz += vc_len[j]; - for (end = (ptr = vc_ptr[j]) + vc_len[j]; ptr < end; ptr++) - len[sv_ind[ptr]]++; - } - /* we need at least nnz free locations in SVA */ - if (sva->r_ptr - sva->m_ptr < nnz) - { sva_more_space(sva, nnz); - sv_ind = sva->ind; - sv_val = sva->val; - } - /* reserve locations for rows of matrix V */ - for (i = 1; i <= n; i++) - { if (len[i] > 0) - sva_enlarge_cap(sva, vr_ref-1+i, len[i], 0); - vr_len[i] = len[i]; - } - /* walk thru column of matrix V and build its rows */ - for (j = 1; j <= n; j++) - { for (end = (ptr = vc_ptr[j]) + vc_len[j]; ptr < end; ptr++) - { i = sv_ind[ptr]; - sv_ind[ptr1 = vr_ptr[i] + (--len[i])] = j; - sv_val[ptr1] = sv_val[ptr]; - } - } - return; -} - -/*********************************************************************** -* luf_build_f_rows - build matrix F in row-wise format -* -* This routine builds the row-wise representation of matrix F in the -* right part of SVA using its column-wise representation. -* -* NOTE: On entry to the routine all rows of matrix F should have zero -* capacity. -* -* The working array len should have at least 1+n elements (len[0] is -* not used). */ - -void luf_build_f_rows(LUF *luf, int len[/*1+n*/]) -{ int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int fr_ref = luf->fr_ref; - int *fr_ptr = &sva->ptr[fr_ref-1]; - int *fr_len = &sva->len[fr_ref-1]; - int fc_ref = luf->fc_ref; - int *fc_ptr = &sva->ptr[fc_ref-1]; - int *fc_len = &sva->len[fc_ref-1]; - int i, j, end, nnz, ptr, ptr1; - /* calculate the number of non-zeros in each row of matrix F and - * the total number of non-zeros (except diagonal elements) */ - nnz = 0; - for (i = 1; i <= n; i++) - len[i] = 0; - for (j = 1; j <= n; j++) - { nnz += fc_len[j]; - for (end = (ptr = fc_ptr[j]) + fc_len[j]; ptr < end; ptr++) - len[sv_ind[ptr]]++; - } - /* we need at least nnz free locations in SVA */ - if (sva->r_ptr - sva->m_ptr < nnz) - { sva_more_space(sva, nnz); - sv_ind = sva->ind; - sv_val = sva->val; - } - /* reserve locations for rows of matrix F */ - for (i = 1; i <= n; i++) - { if (len[i] > 0) - sva_reserve_cap(sva, fr_ref-1+i, len[i]); - fr_len[i] = len[i]; - } - /* walk through columns of matrix F and build its rows */ - for (j = 1; j <= n; j++) - { for (end = (ptr = fc_ptr[j]) + fc_len[j]; ptr < end; ptr++) - { i = sv_ind[ptr]; - sv_ind[ptr1 = fr_ptr[i] + (--len[i])] = j; - sv_val[ptr1] = sv_val[ptr]; - } - } - return; -} - -/*********************************************************************** -* luf_build_v_cols - build matrix V in column-wise format -* -* This routine builds the column-wise representation of matrix V in -* the left (if the flag updat is set) or right (if the flag updat is -* clear) part of SVA using its row-wise representation. -* -* NOTE: On entry to the routine all columns of matrix V should have -* zero capacity. -* -* The working array len should have at least 1+n elements (len[0] is -* not used). */ - -void luf_build_v_cols(LUF *luf, int updat, int len[/*1+n*/]) -{ int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int vr_ref = luf->vr_ref; - int *vr_ptr = &sva->ptr[vr_ref-1]; - int *vr_len = &sva->len[vr_ref-1]; - int vc_ref = luf->vc_ref; - int *vc_ptr = &sva->ptr[vc_ref-1]; - int *vc_len = &sva->len[vc_ref-1]; - int i, j, end, nnz, ptr, ptr1; - /* calculate the number of non-zeros in each column of matrix V - * and the total number of non-zeros (except pivot elements) */ - nnz = 0; - for (j = 1; j <= n; j++) - len[j] = 0; - for (i = 1; i <= n; i++) - { nnz += vr_len[i]; - for (end = (ptr = vr_ptr[i]) + vr_len[i]; ptr < end; ptr++) - len[sv_ind[ptr]]++; - } - /* we need at least nnz free locations in SVA */ - if (sva->r_ptr - sva->m_ptr < nnz) - { sva_more_space(sva, nnz); - sv_ind = sva->ind; - sv_val = sva->val; - } - /* reserve locations for columns of matrix V */ - for (j = 1; j <= n; j++) - { if (len[j] > 0) - { if (updat) - sva_enlarge_cap(sva, vc_ref-1+j, len[j], 0); - else - sva_reserve_cap(sva, vc_ref-1+j, len[j]); - } - vc_len[j] = len[j]; - } - /* walk through rows of matrix V and build its columns */ - for (i = 1; i <= n; i++) - { for (end = (ptr = vr_ptr[i]) + vr_len[i]; ptr < end; ptr++) - { j = sv_ind[ptr]; - sv_ind[ptr1 = vc_ptr[j] + (--len[j])] = i; - sv_val[ptr1] = sv_val[ptr]; - } - } - return; -} - -/*********************************************************************** -* luf_check_f_rc - check rows and columns of matrix F -* -* This routine checks that the row- and column-wise representations -* of matrix F are identical. -* -* NOTE: For testing/debugging only. */ - -void luf_check_f_rc(LUF *luf) -{ int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int fr_ref = luf->fr_ref; - int *fr_ptr = &sva->ptr[fr_ref-1]; - int *fr_len = &sva->len[fr_ref-1]; - int fc_ref = luf->fc_ref; - int *fc_ptr = &sva->ptr[fc_ref-1]; - int *fc_len = &sva->len[fc_ref-1]; - int i, i_end, i_ptr, j, j_end, j_ptr; - /* walk thru rows of matrix F */ - for (i = 1; i <= n; i++) - { for (i_end = (i_ptr = fr_ptr[i]) + fr_len[i]; - i_ptr < i_end; i_ptr++) - { j = sv_ind[i_ptr]; - /* find element f[i,j] in j-th column of matrix F */ - for (j_end = (j_ptr = fc_ptr[j]) + fc_len[j]; - sv_ind[j_ptr] != i; j_ptr++) - /* nop */; - xassert(j_ptr < j_end); - xassert(sv_val[i_ptr] == sv_val[j_ptr]); - /* mark element f[i,j] */ - sv_ind[j_ptr] = -i; - } - } - /* walk thru column of matix F and check that all elements has - been marked */ - for (j = 1; j <= n; j++) - { for (j_end = (j_ptr = fc_ptr[j]) + fc_len[j]; - j_ptr < j_end; j_ptr++) - { xassert((i = sv_ind[j_ptr]) < 0); - /* unmark element f[i,j] */ - sv_ind[j_ptr] = -i; - } - } - return; -} - -/*********************************************************************** -* luf_check_v_rc - check rows and columns of matrix V -* -* This routine checks that the row- and column-wise representations -* of matrix V are identical. -* -* NOTE: For testing/debugging only. */ - -void luf_check_v_rc(LUF *luf) -{ int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int vr_ref = luf->vr_ref; - int *vr_ptr = &sva->ptr[vr_ref-1]; - int *vr_len = &sva->len[vr_ref-1]; - int vc_ref = luf->vc_ref; - int *vc_ptr = &sva->ptr[vc_ref-1]; - int *vc_len = &sva->len[vc_ref-1]; - int i, i_end, i_ptr, j, j_end, j_ptr; - /* walk thru rows of matrix V */ - for (i = 1; i <= n; i++) - { for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; - i_ptr < i_end; i_ptr++) - { j = sv_ind[i_ptr]; - /* find element v[i,j] in j-th column of matrix V */ - for (j_end = (j_ptr = vc_ptr[j]) + vc_len[j]; - sv_ind[j_ptr] != i; j_ptr++) - /* nop */; - xassert(j_ptr < j_end); - xassert(sv_val[i_ptr] == sv_val[j_ptr]); - /* mark element v[i,j] */ - sv_ind[j_ptr] = -i; - } - } - /* walk thru column of matix V and check that all elements has - been marked */ - for (j = 1; j <= n; j++) - { for (j_end = (j_ptr = vc_ptr[j]) + vc_len[j]; - j_ptr < j_end; j_ptr++) - { xassert((i = sv_ind[j_ptr]) < 0); - /* unmark element v[i,j] */ - sv_ind[j_ptr] = -i; - } - } - return; -} - -/*********************************************************************** -* luf_f_solve - solve system F * x = b -* -* This routine solves the system F * x = b, where the matrix F is the -* left factor of the sparse LU-factorization. -* -* On entry the array x should contain elements of the right-hand side -* vector b in locations x[1], ..., x[n], where n is the order of the -* matrix F. On exit this array will contain elements of the solution -* vector x in the same locations. */ - -void luf_f_solve(LUF *luf, double x[/*1+n*/]) -{ int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int fc_ref = luf->fc_ref; - int *fc_ptr = &sva->ptr[fc_ref-1]; - int *fc_len = &sva->len[fc_ref-1]; - int *pp_inv = luf->pp_inv; - int j, k, ptr, end; - double x_j; - for (k = 1; k <= n; k++) - { /* k-th column of L = j-th column of F */ - j = pp_inv[k]; - /* x[j] is already computed */ - /* walk thru j-th column of matrix F and substitute x[j] into - * other equations */ - if ((x_j = x[j]) != 0.0) - { for (end = (ptr = fc_ptr[j]) + fc_len[j]; - ptr < end; ptr++) - x[sv_ind[ptr]] -= sv_val[ptr] * x_j; - } - } - return; -} - -/*********************************************************************** -* luf_ft_solve - solve system F' * x = b -* -* This routine solves the system F' * x = b, where F' is a matrix -* transposed to the matrix F, which is the left factor of the sparse -* LU-factorization. -* -* On entry the array x should contain elements of the right-hand side -* vector b in locations x[1], ..., x[n], where n is the order of the -* matrix F. On exit this array will contain elements of the solution -* vector x in the same locations. */ - -void luf_ft_solve(LUF *luf, double x[/*1+n*/]) -{ int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int fr_ref = luf->fr_ref; - int *fr_ptr = &sva->ptr[fr_ref-1]; - int *fr_len = &sva->len[fr_ref-1]; - int *pp_inv = luf->pp_inv; - int i, k, ptr, end; - double x_i; - for (k = n; k >= 1; k--) - { /* k-th column of L' = i-th row of F */ - i = pp_inv[k]; - /* x[i] is already computed */ - /* walk thru i-th row of matrix F and substitute x[i] into - * other equations */ - if ((x_i = x[i]) != 0.0) - { for (end = (ptr = fr_ptr[i]) + fr_len[i]; - ptr < end; ptr++) - x[sv_ind[ptr]] -= sv_val[ptr] * x_i; - } - } - return; -} - -/*********************************************************************** -* luf_v_solve - solve system V * x = b -* -* This routine solves the system V * x = b, where the matrix V is the -* right factor of the sparse LU-factorization. -* -* On entry the array b should contain elements of the right-hand side -* vector b in locations b[1], ..., b[n], where n is the order of the -* matrix V. On exit the array x will contain elements of the solution -* vector x in locations x[1], ..., x[n]. Note that the array b will be -* clobbered on exit. */ - -void luf_v_solve(LUF *luf, double b[/*1+n*/], double x[/*1+n*/]) -{ int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - double *vr_piv = luf->vr_piv; - int vc_ref = luf->vc_ref; - int *vc_ptr = &sva->ptr[vc_ref-1]; - int *vc_len = &sva->len[vc_ref-1]; - int *pp_inv = luf->pp_inv; - int *qq_ind = luf->qq_ind; - int i, j, k, ptr, end; - double x_j; - for (k = n; k >= 1; k--) - { /* k-th row of U = i-th row of V */ - /* k-th column of U = j-th column of V */ - i = pp_inv[k]; - j = qq_ind[k]; - /* compute x[j] = b[i] / u[k,k], where u[k,k] = v[i,j]; - * walk through j-th column of matrix V and substitute x[j] - * into other equations */ - if ((x_j = x[j] = b[i] / vr_piv[i]) != 0.0) - { for (end = (ptr = vc_ptr[j]) + vc_len[j]; - ptr < end; ptr++) - b[sv_ind[ptr]] -= sv_val[ptr] * x_j; - } - } - return; -} - -/*********************************************************************** -* luf_vt_solve - solve system V' * x = b -* -* This routine solves the system V' * x = b, where V' is a matrix -* transposed to the matrix V, which is the right factor of the sparse -* LU-factorization. -* -* On entry the array b should contain elements of the right-hand side -* vector b in locations b[1], ..., b[n], where n is the order of the -* matrix V. On exit the array x will contain elements of the solution -* vector x in locations x[1], ..., x[n]. Note that the array b will be -* clobbered on exit. */ - -void luf_vt_solve(LUF *luf, double b[/*1+n*/], double x[/*1+n*/]) -{ int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - double *vr_piv = luf->vr_piv; - int vr_ref = luf->vr_ref; - int *vr_ptr = &sva->ptr[vr_ref-1]; - int *vr_len = &sva->len[vr_ref-1]; - int *pp_inv = luf->pp_inv; - int *qq_ind = luf->qq_ind; - int i, j, k, ptr, end; - double x_i; - for (k = 1; k <= n; k++) - { /* k-th row of U' = j-th column of V */ - /* k-th column of U' = i-th row of V */ - i = pp_inv[k]; - j = qq_ind[k]; - /* compute x[i] = b[j] / u'[k,k], where u'[k,k] = v[i,j]; - * walk through i-th row of matrix V and substitute x[i] into - * other equations */ - if ((x_i = x[i] = b[j] / vr_piv[i]) != 0.0) - { for (end = (ptr = vr_ptr[i]) + vr_len[i]; - ptr < end; ptr++) - b[sv_ind[ptr]] -= sv_val[ptr] * x_i; - } - } - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bflib/luf.h b/resources/3rdparty/glpk-4.53/src/bflib/luf.h deleted file mode 100644 index d5b0bd3c8..000000000 --- a/resources/3rdparty/glpk-4.53/src/bflib/luf.h +++ /dev/null @@ -1,213 +0,0 @@ -/* luf.h (sparse LU-factorization) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef LUF_H -#define LUF_H - -#include "sva.h" - -/*********************************************************************** -* The structure LUF describes sparse LU-factorization. -* -* The LU-factorization has the following format: -* -* A = F * V = P * L * U * Q, (1) -* -* F = P * L * P', (2) -* -* V = P * U * Q, (3) -* -* where A is a given (unsymmetric) square matrix, F and V are matrix -* factors actually computed, L is a lower triangular matrix with unity -* diagonal, U is an upper triangular matrix, P and Q are permutation -* matrices, P' is a matrix transposed to P. All the matrices have the -* same order n. -* -* Matrices F and V are stored in both row- and column-wise sparse -* formats in the associated sparse vector area (SVA). Unity diagonal -* elements of matrix F are not stored. Pivot elements of matrix V -* (which correspond to diagonal elements of matrix U) are stored in -* a separate ordinary array. -* -* Permutation matrices P and Q are stored in ordinary arrays in both -* row- and column-like formats. -* -* Matrices L and U are completely defined by matrices F, V, P, and Q, -* and therefore not stored explicitly. */ - -typedef struct LUF LUF; - -struct LUF -{ /* sparse LU-factorization */ - int n; - /* order of matrices A, F, V, P, Q */ - SVA *sva; - /* associated sparse vector area (SVA) used to store rows and - * columns of matrices F and V; note that different objects may - * share the same SVA */ - /*--------------------------------------------------------------*/ - /* matrix F in row-wise format */ - /* during the factorization process this object is not used */ - int fr_ref; - /* reference number of sparse vector in SVA, which is the first - * row of matrix F */ -#if 0 + 0 - int *fr_ptr = &sva->ptr[fr_ref-1]; - /* fr_ptr[0] is not used; - * fr_ptr[i], 1 <= i <= n, is pointer to i-th row in SVA */ - int *fr_len = &sva->len[fr_ref-1]; - /* fr_len[0] is not used; - * fr_len[i], 1 <= i <= n, is length of i-th row */ -#endif - /*--------------------------------------------------------------*/ - /* matrix F in column-wise format */ - /* during the factorization process this object is constructed - by columns */ - int fc_ref; - /* reference number of sparse vector in SVA, which is the first - * column of matrix F */ -#if 0 + 0 - int *fc_ptr = &sva->ptr[fc_ref-1]; - /* fc_ptr[0] is not used; - * fc_ptr[j], 1 <= j <= n, is pointer to j-th column in SVA */ - int *fc_len = &sva->len[fc_ref-1]; - /* fc_len[0] is not used; - * fc_len[j], 1 <= j <= n, is length of j-th column */ -#endif - /*--------------------------------------------------------------*/ - /* matrix V in row-wise format */ - int vr_ref; - /* reference number of sparse vector in SVA, which is the first - * row of matrix V */ -#if 0 + 0 - int *vr_ptr = &sva->ptr[vr_ref-1]; - /* vr_ptr[0] is not used; - * vr_ptr[i], 1 <= i <= n, is pointer to i-th row in SVA */ - int *vr_len = &sva->len[vr_ref-1]; - /* vr_len[0] is not used; - * vr_len[i], 1 <= i <= n, is length of i-th row */ - int *vr_cap = &sva->cap[vr_ref-1]; - /* vr_cap[0] is not used; - * vr_cap[i], 1 <= i <= n, is capacity of i-th row */ -#endif - double *vr_piv; /* double vr_piv[1+n]; */ - /* vr_piv[0] is not used; - * vr_piv[i], 1 <= i <= n, is pivot element of i-th row */ - /*--------------------------------------------------------------*/ - /* matrix V in column-wise format */ - /* during the factorization process this object contains only the - * patterns (row indices) of columns of the active submatrix */ - int vc_ref; - /* reference number of sparse vector in SVA, which is the first - * column of matrix V */ -#if 0 + 0 - int *vc_ptr = &sva->ptr[vc_ref-1]; - /* vc_ptr[0] is not used; - * vc_ptr[j], 1 <= j <= n, is pointer to j-th column in SVA */ - int *vc_len = &sva->len[vc_ref-1]; - /* vc_len[0] is not used; - * vc_len[j], 1 <= j <= n, is length of j-th column */ - int *vc_cap = &sva->cap[vc_ref-1]; - /* vc_cap[0] is not used; - * vc_cap[j], 1 <= j <= n, is capacity of j-th column */ -#endif - /*--------------------------------------------------------------*/ - /* matrix P */ - int *pp_ind; /* int pp_ind[1+n]; */ - /* pp_ind[i] = j means that P[i,j] = 1 */ - int *pp_inv; /* int pp_inv[1+n]; */ - /* pp_inv[j] = i means that P[i,j] = 1 */ - /* if i-th row or column of matrix F is i'-th row or column of - * matrix L, or if i-th row of matrix V is i'-th row of matrix U, - * then pp_ind[i] = i' and pp_inv[i'] = i */ - /*--------------------------------------------------------------*/ - /* matrix Q */ - int *qq_ind; /* int qq_ind[1+n]; */ - /* qq_ind[i] = j means that Q[i,j] = 1 */ - int *qq_inv; /* int qq_inv[1+n]; */ - /* qq_inv[j] = i means that Q[i,j] = 1 */ - /* if j-th column of matrix V is j'-th column of matrix U, then - * qq_ind[j'] = j and qq_inv[j] = j' */ -}; - -#define luf_swap_u_rows(i1, i2) \ - do \ - { int j1, j2; \ - j1 = pp_inv[i1], j2 = pp_inv[i2]; \ - pp_ind[j1] = i2, pp_inv[i2] = j1; \ - pp_ind[j2] = i1, pp_inv[i1] = j2; \ - } while (0) -/* swap rows i1 and i2 of matrix U = P'* V * Q' */ - -#define luf_swap_u_cols(j1, j2) \ - do \ - { int i1, i2; \ - i1 = qq_ind[j1], i2 = qq_ind[j2]; \ - qq_ind[j1] = i2, qq_inv[i2] = j1; \ - qq_ind[j2] = i1, qq_inv[i1] = j2; \ - } while (0) -/* swap columns j1 and j2 of matrix U = P'* V * Q' */ - -#define luf_check_all _glp_luf_check_all -void luf_check_all(LUF *luf, int k); -/* check LU-factorization before k-th elimination step */ - -#define luf_build_v_rows _glp_luf_build_v_rows -void luf_build_v_rows(LUF *luf, int len[/*1+n*/]); -/* build matrix V in row-wise format */ - -#define luf_build_f_rows _glp_luf_build_f_rows -void luf_build_f_rows(LUF *luf, int len[/*1+n*/]); -/* build matrix F in row-wise format */ - -#define luf_build_v_cols _glp_luf_build_v_cols -void luf_build_v_cols(LUF *luf, int updat, int len[/*1+n*/]); -/* build matrix V in column-wise format */ - -#define luf_check_f_rc _glp_luf_check_f_rc -void luf_check_f_rc(LUF *luf); -/* check rows and columns of matrix F */ - -#define luf_check_v_rc _glp_luf_check_v_rc -void luf_check_v_rc(LUF *luf); -/* check rows and columns of matrix V */ - -#define luf_f_solve _glp_luf_f_solve1 -void luf_f_solve(LUF *luf, double x[/*1+n*/]); -/* solve system F * x = b */ - -#define luf_ft_solve _glp_luf_ft_solve1 -void luf_ft_solve(LUF *luf, double x[/*1+n*/]); -/* solve system F' * x = b */ - -#define luf_v_solve _glp_luf_v_solve1 -void luf_v_solve(LUF *luf, double b[/*1+n*/], double x[/*1+n*/]); -/* solve system V * x = b */ - -#define luf_vt_solve _glp_luf_vt_solve1 -void luf_vt_solve(LUF *luf, double b[/*1+n*/], double x[/*1+n*/]); -/* solve system V' * x = b */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bflib/lufint.c b/resources/3rdparty/glpk-4.53/src/bflib/lufint.c deleted file mode 100644 index 56f83e32f..000000000 --- a/resources/3rdparty/glpk-4.53/src/bflib/lufint.c +++ /dev/null @@ -1,218 +0,0 @@ -/* lufint.c (interface to LU-factorization) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "lufint.h" - -LUFINT *lufint_create(void) -{ /* create interface to LU-factorization */ - LUFINT *fi; - fi = talloc(1, LUFINT); - fi->n_max = 0; - fi->valid = 0; - fi->sva = NULL; - fi->luf = NULL; - fi->sgf = NULL; - fi->sva_n_max = fi->sva_size = 0; - fi->delta_n0 = fi->delta_n = 0; - fi->sgf_updat = 0; - fi->sgf_piv_tol = 0.10; - fi->sgf_piv_lim = 4; - fi->sgf_suhl = 1; - fi->sgf_eps_tol = DBL_EPSILON; - return fi; -} - -static int setup_v_cols(LUF *luf, int (*col)(void *info, int j, - int ind[], double val[]), void *info, int ind[], double val[]) -{ /* setup matrix V = A in column-wise format */ - int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int vc_ref = luf->vc_ref; - int *vc_ptr = &sva->ptr[vc_ref-1]; - int *vc_len = &sva->len[vc_ref-1]; - int *vc_cap = &sva->cap[vc_ref-1]; - int j, len, ptr, nnz; - nnz = 0; - for (j = 1; j <= n; j++) - { /* get j-th column */ - len = col(info, j, ind, val); - xassert(0 <= len && len <= n); - /* enlarge j-th column capacity */ - if (vc_cap[j] < len) - { if (sva->r_ptr - sva->m_ptr < len) - { sva_more_space(sva, len); - sv_ind = sva->ind; - sv_val = sva->val; - } - sva_enlarge_cap(sva, vc_ref-1+j, len, 0); - } - /* store j-th column */ - ptr = vc_ptr[j]; - memcpy(&sv_ind[ptr], &ind[1], len * sizeof(int)); - memcpy(&sv_val[ptr], &val[1], len * sizeof(double)); - vc_len[j] = len; - nnz += len; - } - return nnz; -} - -int lufint_factorize(LUFINT *fi, int n, int (*col)(void *info, int j, - int ind[], double val[]), void *info) -{ /* compute LU-factorization of specified matrix A */ - SVA *sva; - LUF *luf; - SGF *sgf; - int k; - xassert(n > 0); - fi->valid = 0; - /* create sparse vector area (SVA), if necessary */ - sva = fi->sva; - if (sva == NULL) - { int sva_n_max = fi->sva_n_max; - int sva_size = fi->sva_size; - if (sva_n_max == 0) - sva_n_max = 4 * n; - if (sva_size == 0) - sva_size = 10 * n; - sva = fi->sva = sva_create_area(sva_n_max, sva_size); - } - /* allocate/reallocate underlying objects, if necessary */ - if (fi->n_max < n) - { int n_max = fi->n_max; - if (n_max == 0) - n_max = fi->n_max = n + fi->delta_n0; - else - n_max = fi->n_max = n + fi->delta_n; - xassert(n_max >= n); - /* allocate/reallocate LU-factorization (LUF) */ - luf = fi->luf; - if (luf == NULL) - { luf = fi->luf = talloc(1, LUF); - memset(luf, 0, sizeof(LUF)); - luf->sva = sva; - } - else - { tfree(luf->vr_piv); - tfree(luf->pp_ind); - tfree(luf->pp_inv); - tfree(luf->qq_ind); - tfree(luf->qq_inv); - } - luf->vr_piv = talloc(1+n_max, double); - luf->pp_ind = talloc(1+n_max, int); - luf->pp_inv = talloc(1+n_max, int); - luf->qq_ind = talloc(1+n_max, int); - luf->qq_inv = talloc(1+n_max, int); - /* allocate/reallocate factorizer workspace (SGF) */ - sgf = fi->sgf; - if (sgf == NULL) - { sgf = fi->sgf = talloc(1, SGF); - memset(sgf, 0, sizeof(SGF)); - sgf->luf = luf; - } - else - { tfree(sgf->rs_head); - tfree(sgf->rs_prev); - tfree(sgf->rs_next); - tfree(sgf->cs_head); - tfree(sgf->cs_prev); - tfree(sgf->cs_next); - tfree(sgf->vr_max); - tfree(sgf->flag); - tfree(sgf->work); - } - sgf->rs_head = talloc(1+n_max, int); - sgf->rs_prev = talloc(1+n_max, int); - sgf->rs_next = talloc(1+n_max, int); - sgf->cs_head = talloc(1+n_max, int); - sgf->cs_prev = talloc(1+n_max, int); - sgf->cs_next = talloc(1+n_max, int); - sgf->vr_max = talloc(1+n_max, double); - sgf->flag = talloc(1+n_max, char); - sgf->work = talloc(1+n_max, double); - } - luf = fi->luf; - sgf = fi->sgf; -#if 1 /* FIXME */ - /* initialize SVA */ - sva->n = 0; - sva->m_ptr = 1; - sva->r_ptr = sva->size + 1; - sva->head = sva->tail = 0; -#endif - /* allocate sparse vectors in SVA */ - luf->n = n; - luf->fr_ref = sva_alloc_vecs(sva, n); - luf->fc_ref = sva_alloc_vecs(sva, n); - luf->vr_ref = sva_alloc_vecs(sva, n); - luf->vc_ref = sva_alloc_vecs(sva, n); - /* setup matrix V = A in column-wise format */ - setup_v_cols(luf, col, info, sgf->rs_prev, sgf->work); - /* setup factorizer control parameters */ - sgf->updat = fi->sgf_updat; - sgf->piv_tol = fi->sgf_piv_tol; - sgf->piv_lim = fi->sgf_piv_lim; - sgf->suhl = fi->sgf_suhl; - sgf->eps_tol = fi->sgf_eps_tol; - /* compute LU-factorization of specified matrix A */ - k = sgf_factorize(sgf, 1); - if (k == 0) - fi->valid = 1; - return k; -} - -void lufint_delete(LUFINT *fi) -{ /* delete interface to LU-factorization */ - SVA *sva = fi->sva; - LUF *luf = fi->luf; - SGF *sgf = fi->sgf; - if (sva != NULL) - sva_delete_area(sva); - if (luf != NULL) - { tfree(luf->vr_piv); - tfree(luf->pp_ind); - tfree(luf->pp_inv); - tfree(luf->qq_ind); - tfree(luf->qq_inv); - tfree(luf); - } - if (sgf != NULL) - { tfree(sgf->rs_head); - tfree(sgf->rs_prev); - tfree(sgf->rs_next); - tfree(sgf->cs_head); - tfree(sgf->cs_prev); - tfree(sgf->cs_next); - tfree(sgf->vr_max); - tfree(sgf->flag); - tfree(sgf->work); - tfree(sgf); - } - tfree(fi); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bflib/lufint.h b/resources/3rdparty/glpk-4.53/src/bflib/lufint.h deleted file mode 100644 index 6ec6cf073..000000000 --- a/resources/3rdparty/glpk-4.53/src/bflib/lufint.h +++ /dev/null @@ -1,73 +0,0 @@ -/* lufint.h (interface to LU-factorization) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef LUFINT_H -#define LUFINT_H - -#include "sgf.h" - -typedef struct LUFINT LUFINT; - -struct LUFINT -{ /* interface to LU-factorization */ - int n_max; - /* maximal value of n (increased automatically) */ - int valid; - /* factorization is valid only if this flag is set */ - SVA *sva; - /* sparse vector area (SVA) */ - LUF *luf; - /* sparse LU-factorization */ - SGF *sgf; - /* sparse Gaussian factorizer workspace */ - /*--------------------------------------------------------------*/ - /* control parameters */ - int sva_n_max, sva_size; - /* parameters passed to sva_create_area */ - int delta_n0, delta_n; - /* if n_max = 0, set n_max = n + delta_n0 - * if n_max < n, set n_max = n + delta_n */ - int sgf_updat; - double sgf_piv_tol; - int sgf_piv_lim; - int sgf_suhl; - double sgf_eps_tol; - /* factorizer control parameters */ -}; - -#define lufint_create _glp_lufint_create -LUFINT *lufint_create(void); -/* create interface to LU-factorization */ - -#define lufint_factorize _glp_lufint_factorize -int lufint_factorize(LUFINT *fi, int n, int (*col)(void *info, int j, - int ind[], double val[]), void *info); -/* compute LU-factorization of specified matrix A */ - -#define lufint_delete _glp_lufint_delete -void lufint_delete(LUFINT *fi); -/* delete interface to LU-factorization */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bflib/sgf.c b/resources/3rdparty/glpk-4.53/src/bflib/sgf.c deleted file mode 100644 index 462ac10ac..000000000 --- a/resources/3rdparty/glpk-4.53/src/bflib/sgf.c +++ /dev/null @@ -1,1407 +0,0 @@ -/* sgf.c (sparse Gaussian factorizer) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "sgf.h" - -/*********************************************************************** -* sgf_reduce_nuc - initial reordering to minimize nucleus size -* -* On entry to this routine it is assumed that V = A and F = P = Q = I, -* where A is the original matrix to be factorized. It is also assumed -* that matrix V = A is stored in both row- and column-wise formats. -* -* This routine performs (implicit) non-symmetric permutations of rows -* and columns of matrix U = P'* V * Q' to reduce it to the form: -* -* 1 k1 k2 n -* 1 x x x x x x x x x x -* . x x x x x x x x x -* . . x x x x x x x x -* k1 . . . * * * * x x x -* . . . * * * * x x x -* . . . * * * * x x x -* k2 . . . * * * * x x x -* . . . . . . . x x x -* . . . . . . . . x x -* n . . . . . . . . . x -* -* where non-zeros in rows and columns k1, k1+1, ..., k2 constitute so -* called nucleus ('*'), whose size is minimized by the routine. -* -* The numbers k1 and k2 are returned by the routine on exit. Usually, -* if the nucleus exists, 1 <= k1 < k2 <= n. However, if the resultant -* matrix U is upper triangular (has no nucleus), k1 = n+1 and k2 = n. -* -* Note that the routines sgf_choose_pivot and sgf_eliminate perform -* exactly the same transformations (by processing row and columns -* singletons), so preliminary minimization of the nucleus may not be -* used. However, processing row and column singletons by the routines -* sgf_minimize_nuc and sgf_singl_phase is more efficient. */ - -void sgf_reduce_nuc(LUF *luf, int *k1_, int *k2_, int cnt[/*1+n*/], - int list[/*1+n*/]) -{ int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - int vr_ref = luf->vr_ref; - int *vr_ptr = &sva->ptr[vr_ref-1]; - int *vr_len = &sva->len[vr_ref-1]; - int vc_ref = luf->vc_ref; - int *vc_ptr = &sva->ptr[vc_ref-1]; - int *vc_len = &sva->len[vc_ref-1]; - int *pp_ind = luf->pp_ind; - int *pp_inv = luf->pp_inv; - int *qq_ind = luf->qq_ind; - int *qq_inv = luf->qq_inv; - int i, ii, j, jj, k1, k2, ns, ptr, end; - /* initial nucleus is U = V = A */ - k1 = 1, k2 = n; - /*--------------------------------------------------------------*/ - /* process column singletons */ - /*--------------------------------------------------------------*/ - /* determine initial counts of columns of V and initialize list - * of active column singletons */ - ns = 0; /* number of active column singletons */ - for (j = 1; j <= n; j++) - { if ((cnt[j] = vc_len[j]) == 1) - list[++ns] = j; - } - /* process active column singletons */ - while (ns > 0) - { /* column singleton is in j-th column of V */ - j = list[ns--]; - /* find i-th row of V containing column singleton */ - ptr = vc_ptr[j]; - end = ptr + vc_len[j]; - for (; pp_ind[i = sv_ind[ptr]] < k1; ptr++) - /* nop */; - xassert(ptr < end); - /* permute rows and columns of U to move column singleton to - * position u[k1,k1] */ - ii = pp_ind[i]; - luf_swap_u_rows(k1, ii); - jj = qq_inv[j]; - luf_swap_u_cols(k1, jj); - /* nucleus size decreased */ - k1++; - /* walk thru i-th row of V and decrease column counts; this - * may cause new column singletons to appear */ - ptr = vr_ptr[i]; - end = ptr + vr_len[i]; - for (; ptr < end; ptr++) - { if (--(cnt[j = sv_ind[ptr]]) == 1) - list[++ns] = j; - } - } - /* nucleus begins at k1-th row/column of U */ - if (k1 > n) - { /* U is upper triangular; no nucleus exist */ - goto done; - } - /*--------------------------------------------------------------*/ - /* process row singletons */ - /*--------------------------------------------------------------*/ - /* determine initial counts of rows of V and initialize list of - * active row singletons */ - ns = 0; /* number of active row singletons */ - for (i = 1; i <= n; i++) - { if (pp_ind[i] < k1) - { /* corresponding row of U is above its k1-th row; set its - * count to zero to prevent including it in active list */ - cnt[i] = 0; - } - else if ((cnt[i] = vr_len[i]) == 1) - list[++ns] = i; - } - /* process active row singletons */ - while (ns > 0) - { /* row singleton is in i-th row of V */ - i = list[ns--]; - /* find j-th column of V containing row singleton */ - ptr = vr_ptr[i]; - end = ptr + vr_len[i]; - for (; qq_inv[j = sv_ind[ptr]] > k2; ptr++) - /* nop */; - xassert(ptr < end); - /* permute rows and columns of U to move row singleton to - * position u[k2,k2] */ - ii = pp_ind[i]; - luf_swap_u_rows(k2, ii); - jj = qq_inv[j]; - luf_swap_u_cols(k2, jj); - /* nucleus size decreased */ - k2--; - /* walk thru j-th column of V and decrease row counts; this - * may cause new row singletons to appear */ - ptr = vc_ptr[j]; - end = ptr + vc_len[j]; - for (; ptr < end; ptr++) - { if (--(cnt[i = sv_ind[ptr]]) == 1) - list[++ns] = i; - } - } - /* nucleus ends at k2-th row/column of U */ - xassert(k1 < k2); -done: *k1_ = k1, *k2_ = k2; - return; -} - -/*********************************************************************** -* sgf_singl_phase - compute LU-factorization (singleton phase) -* -* It is assumed that on entry to the routine L = P'* F * P = F = I -* and matrix U = P'* V * Q' has the following structure (provided by -* the routine sgf_reduce_nuc): -* -* 1 k1 k2 n -* 1 a a a b b b b c c c -* . a a b b b b c c c -* . . a b b b b c c c -* k1 . . . * * * * d d d -* . . . * * * * d d d -* . . . * * * * d d d -* k2 . . . * * * * d d d -* . . . . . . . e e e -* . . . . . . . . e e -* n . . . . . . . . . e -* -* First, the routine performs (implicit) symmetric permutations of -* rows and columns of matrix U to place them in the following order: -* -* 1, 2, ..., k1-1; n, n-1, ..., k2+1; k1, k1+1, ..., k2 -* -* This changes the structure of matrix U as follows: -* -* 1 k1 k2' n -* 1 a a a c c c b b b b -* . a a c c c b b b b -* . . a c c c b b b b -* k1 . . . e . . . . . . -* . . . e e . . . . . -* . . . e e e . . . . -* k2'. . . d d d * * * * -* . . . d d d * * * * -* . . . d d d * * * * -* n . . . d d d * * * * -* -* where k2' = n - k2 + k1. -* -* Then the routine performs elementary gaussian transformations to -* eliminate subdiagonal elements in columns k1, ..., k2'-1 of U. The -* effect is the same as if the routine sgf_eliminate would be called -* for k = 1, ..., k2'-1 using diagonal elements u[k,k] as pivots. -* -* After elimination matrices L and U becomes the following: -* -* 1 k1 k2' n 1 k1 k2' n -* 1 1 . . . . . . . . . 1 a a a c c c b b b b -* . 1 . . . . . . . . . a a c c c b b b b -* . . 1 . . . . . . . . . a c c c b b b b -* k1 . . . 1 . . . . . . k1 . . . e . . . . . . -* . . . e'1 . . . . . . . . . e . . . . . -* . . . e'e'1 . . . . . . . . . e . . . . -* k2'. . . d'd'd'1 . . . k2'. . . . . . * * * * -* . . . d'd'd'. 1 . . . . . . . . * * * * -* . . . d'd'd'. . 1 . . . . . . . * * * * -* n . . . d'd'd'. . . 1 n . . . . . . * * * * -* -* matrix L matrix U -* -* where columns k1, ..., k2'-1 of L consist of subdiagonal elements -* of initial matrix U divided by pivots u[k,k]. -* -* On exit the routine returns k2', the elimination step number, from -* which computing of the factorization should be continued. Note that -* k2' = n+1 means that matrix U is already upper triangular. */ - -int sgf_singl_phase(LUF *luf, int k1, int k2, int updat, - int ind[/*1+n*/], double val[/*1+n*/]) -{ int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int fc_ref = luf->fc_ref; - int *fc_ptr = &sva->ptr[fc_ref-1]; - int *fc_len = &sva->len[fc_ref-1]; - int vr_ref = luf->vr_ref; - int *vr_ptr = &sva->ptr[vr_ref-1]; - int *vr_len = &sva->len[vr_ref-1]; - double *vr_piv = luf->vr_piv; - int vc_ref = luf->vc_ref; - int *vc_ptr = &sva->ptr[vc_ref-1]; - int *vc_len = &sva->len[vc_ref-1]; - int *pp_ind = luf->pp_ind; - int *pp_inv = luf->pp_inv; - int *qq_ind = luf->qq_ind; - int *qq_inv = luf->qq_inv; - int i, j, k, ptr, ptr1, end, len; - double piv; - /* (see routine sgf_reduce_nuc) */ - xassert((1 <= k1 && k1 < k2 && k2 <= n) - || (k1 == n+1 && k2 == n)); - /* perform symmetric permutations of rows/columns of U */ - for (k = k1; k <= k2; k++) - pp_ind[pp_inv[k]] = qq_inv[qq_ind[k]] = k - k2 + n; - for (k = k2+1; k <= n; k++) - pp_ind[pp_inv[k]] = qq_inv[qq_ind[k]] = n - k + k1; - for (k = 1; k <= n; k++) - pp_inv[pp_ind[k]] = qq_ind[qq_inv[k]] = k; - /* determine k2' */ - k2 = n - k2 + k1; - /* process rows and columns of V corresponding to rows and - * columns 1, ..., k1-1 of U */ - for (k = 1; k < k1; k++) - { /* k-th row of U = i-th row of V */ - i = pp_inv[k]; - /* find pivot u[k,k] = v[i,j] in i-th row of V */ - ptr = vr_ptr[i]; - end = ptr + vr_len[i]; - for (; qq_inv[sv_ind[ptr]] != k; ptr++) - /* nop */; - xassert(ptr < end); - /* store pivot */ - vr_piv[i] = sv_val[ptr]; - /* and remove it from i-th row of V */ - sv_ind[ptr] = sv_ind[end-1]; - sv_val[ptr] = sv_val[end-1]; - vr_len[i]--; - /* clear column of V corresponding to k-th column of U */ - vc_len[qq_ind[k]] = 0; - } - /* clear rows of V corresponding to rows k1, ..., k2'-1 of U */ - for (k = k1; k < k2; k++) - vr_len[pp_inv[k]] = 0; - /* process rows and columns of V corresponding to rows and - * columns k2', ..., n of U */ - for (k = k2; k <= n; k++) - { /* k-th row of U = i-th row of V */ - i = pp_inv[k]; - /* remove elements from i-th row of V that correspond to - * elements u[k,k1], ..., u[k,k2'-1] */ - ptr = ptr1 = vr_ptr[i]; - end = ptr + vr_len[i]; - for (; ptr < end; ptr++) - { if (qq_inv[sv_ind[ptr]] >= k2) - { sv_ind[ptr1] = sv_ind[ptr]; - sv_val[ptr1] = sv_val[ptr]; - ptr1++; - } - } - vr_len[i] = ptr1 - vr_ptr[i]; - /* k-th column of U = j-th column of V */ - j = qq_ind[k]; - /* remove elements from j-th column of V that correspond to - * elements u[1,k], ..., u[k1-1,k] */ - ptr = ptr1 = vc_ptr[j]; - end = ptr + vc_len[j]; - for (; ptr < end; ptr++) - { if (pp_ind[sv_ind[ptr]] >= k2) - /* element value is not needed in this case */ - sv_ind[ptr1++] = sv_ind[ptr]; - } - vc_len[j] = ptr1 - vc_ptr[j]; - } - /* process columns of V corresponding to columns k1, ..., k2'-1 - * of U, build columns of F */ - for (k = k1; k < k2; k++) - { /* k-th column of U = j-th column of V */ - j = qq_ind[k]; - /* remove elements from j-th column of V that correspond to - * pivot (diagonal) element u[k,k] and subdiagonal elements - * u[k+1,k], ..., u[n,k]; subdiagonal elements are stored for - * further addition to matrix F */ - len = 0; - piv = 0.0; - ptr = vc_ptr[j]; - end = ptr + vc_len[j]; - for (; ptr < end; ptr++) - { i = sv_ind[ptr]; /* v[i,j] */ - if (pp_ind[i] == k) - { /* store pivot v[i,j] = u[k,k] */ - piv = vr_piv[i] = sv_val[ptr]; - } - else if (pp_ind[i] > k) - { /* store subdiagonal element v[i,j] = u[i',k] */ - len++; - ind[len] = i; - val[len] = sv_val[ptr]; - } - } - /* clear j-th column of V = k-th column of U */ - vc_len[j] = 0; - /* build k-th column of L = j-th column of F */ - j = pp_inv[k]; - xassert(piv != 0.0); - if (len > 0) - { if (sva->r_ptr - sva->m_ptr < len) - { sva_more_space(sva, len); - sv_ind = sva->ind; - sv_val = sva->val; - } - sva_reserve_cap(sva, fc_ref-1+j, len); - for (ptr = fc_ptr[j], ptr1 = 1; ptr1 <= len; ptr++, ptr1++) - { sv_ind[ptr] = ind[ptr1]; - sv_val[ptr] = val[ptr1] / piv; - } - fc_len[j] = len; - } - } - /* if it is not planned to update matrix V, relocate all its - * non-active rows corresponding to rows 1, ..., k2'-1 of U to - * the right (static) part of SVA */ - if (!updat) - { for (k = 1; k < k2; k++) - { i = pp_inv[k]; - len = vr_len[i]; - if (sva->r_ptr - sva->m_ptr < len) - { sva_more_space(sva, len); - sv_ind = sva->ind; - sv_val = sva->val; - } - sva_make_static(sva, vr_ref-1+i); - } - } - /* elimination steps 1, ..., k2'-1 have been performed */ - return k2; -} - -/*********************************************************************** -* sgf_choose_pivot - choose pivot element v[p,q] -* -* This routine chooses pivot element v[p,q], k <= p, q <= n, in the -* active submatrix of matrix V = P * U * Q, where k is the number of -* current elimination step, 1 <= k <= n. -* -* It is assumed that on entry to the routine matrix U = P'* V * Q' has -* the following partially triangularized form: -* -* 1 k n -* 1 x x x x x x x x x x -* . x x x x x x x x x -* . . x x x x x x x x -* . . . x x x x x x x -* k . . . . * * * * * * -* . . . . * * * * * * -* . . . . * * * * * * -* . . . . * * * * * * -* . . . . * * * * * * -* n . . . . * * * * * * -* -* where rows and columns k, k+1, ..., n belong to the active submatrix -* (its elements are marked by '*'). -* -* Since the matrix U is not stored, the routine works with the matrix -* V = P * U * Q. It is assumed that the row-wise representation -* corresponds to the matrix V, but the column-wise representation -* corresponds to the active submatrix of the matrix V, i.e. elements, -* which are not in the active submatrix, are not included in column -* vectors. It is also assumed that each active row of the matrix V is -* in the set R[len], where len is the number of non-zeros in the row, -* and each active column of the matrix V is in the set C[len], where -* len is the number of non-zeros in the column (in the latter case -* only elements of the active submatrix are counted; such elements are -* marked by '*' on the figure above). -* -* For the reason of numerical stability the routine applies so called -* threshold pivoting proposed by J.Reid. It is assumed that an element -* v[i,j] can be selected as a pivot candidate if it is not very small -* (in magnitude) among other elements in the same row, i.e. if it -* satisfies to the stability condition |v[i,j]| >= tol * max|v[i,*]|, -* where 0 < tol < 1 is a given tolerance. -* -* In order to keep sparsity of the matrix V the routine uses Markowitz -* strategy, trying to choose such element v[p,q], which satisfies to -* the stability condition (see above) and has smallest Markowitz cost -* (nr[p]-1) * (nc[q]-1), where nr[p] and nc[q] are, resp., numbers of -* non-zeros in p-th row and q-th column of the active submatrix. -* -* In order to reduce the search, i.e. not to walk through all elements -* of the active submatrix, the routine uses a technique proposed by -* I.Duff. This technique is based on using the sets R[len] and C[len] -* of active rows and columns. -* -* If the pivot element v[p,q] has been chosen, the routine stores its -* indices to locations *p and *q and returns zero. Otherwise, non-zero -* is returned. */ - -int sgf_choose_pivot(SGF *sgf, int *p_, int *q_) -{ LUF *luf = sgf->luf; - int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int vr_ref = luf->vr_ref; - int *vr_ptr = &sva->ptr[vr_ref-1]; - int *vr_len = &sva->len[vr_ref-1]; - int vc_ref = luf->vc_ref; - int *vc_ptr = &sva->ptr[vc_ref-1]; - int *vc_len = &sva->len[vc_ref-1]; - int *rs_head = sgf->rs_head; - int *rs_next = sgf->rs_next; - int *cs_head = sgf->cs_head; - int *cs_prev = sgf->cs_prev; - int *cs_next = sgf->cs_next; - double *vr_max = sgf->vr_max; - double piv_tol = sgf->piv_tol; - int piv_lim = sgf->piv_lim; - int suhl = sgf->suhl; - int i, i_ptr, i_end, j, j_ptr, j_end, len, min_i, min_j, min_len, - ncand, next_j, p, q; - double best, big, cost, temp; - /* no pivot candidate has been chosen so far */ - p = q = 0, best = DBL_MAX, ncand = 0; - /* if the active submatrix contains a column having the only - * non-zero element (column singleton), choose it as the pivot */ - j = cs_head[1]; - if (j != 0) - { xassert(vc_len[j] == 1); - p = sv_ind[vc_ptr[j]], q = j; - goto done; - } - /* if the active submatrix contains a row having the only - * non-zero element (row singleton), choose it as the pivot */ - i = rs_head[1]; - if (i != 0) - { xassert(vr_len[i] == 1); - p = i, q = sv_ind[vr_ptr[i]]; - goto done; - } - /* the active submatrix contains no singletons; walk thru its - * other non-empty rows and columns */ - for (len = 2; len <= n; len++) - { /* consider active columns containing len non-zeros */ - for (j = cs_head[len]; j != 0; j = next_j) - { /* save the number of next column of the same length */ - next_j = cs_next[j]; - /* find an element in j-th column, which is placed in the - * row with minimal number of non-zeros and satisfies to - * the stability condition (such element may not exist) */ - min_i = min_j = 0, min_len = INT_MAX; - for (j_end = (j_ptr = vc_ptr[j]) + vc_len[j]; - j_ptr < j_end; j_ptr++) - { /* get row index of v[i,j] */ - i = sv_ind[j_ptr]; - /* if i-th row is not shorter, skip v[i,j] */ - if (vr_len[i] >= min_len) - continue; - /* big := max|v[i,*]| */ - if ((big = vr_max[i]) < 0.0) - { /* largest magnitude is unknown; compute it */ - for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; - i_ptr < i_end; i_ptr++) - { if ((temp = sv_val[i_ptr]) < 0.0) - temp = -temp; - if (big < temp) - big = temp; - } - xassert(big > 0.0); - vr_max[i] = big; - } - /* find v[i,j] in i-th row */ - for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; - sv_ind[i_ptr] != j; i_ptr++) - /* nop */; - xassert(i_ptr < i_end); - /* if |v[i,j]| < piv_tol * max|v[i,*]|, skip v[i,j] */ - if ((temp = sv_val[i_ptr]) < 0.0) - temp = -temp; - if (temp < piv_tol * big) - continue; - /* v[i,j] is a better candidate */ - min_i = i, min_j = j, min_len = vr_len[i]; - /* if Markowitz cost of v[i,j] is not greater than - * (len-1)**2, v[i,j] can be chosen as the pivot right - * now; this heuristic reduces the search and works well - * in many cases */ - if (min_len <= len) - { p = min_i, q = min_j; - goto done; - } - } - /* j-th column has been scanned */ - if (min_i != 0) - { /* element v[min_i,min_j] is a next pivot candidate */ - ncand++; - /* compute its Markowitz cost */ - cost = (double)(min_len - 1) * (double)(len - 1); - /* if this element is better, choose it as the pivot */ - if (cost < best) - p = min_i, q = min_j, best = cost; - /* if piv_lim candidates were considered, terminate - * the search, because it is doubtful that a much better - * candidate will be found */ - if (ncand == piv_lim) - goto done; - } - else if (suhl) - { /* j-th column has no eligible elements that satisfy to - * the stability criterion; Uwe Suhl suggests to exclude - * such column from further considerations until it - * becomes a column singleton; in hard cases this may - * significantly reduce the time needed to choose the - * pivot element */ - sgf_deactivate_col(j); - cs_prev[j] = cs_next[j] = j; - } - } - /* consider active rows containing len non-zeros */ - for (i = rs_head[len]; i != 0; i = rs_next[i]) - { /* big := max|v[i,*]| */ - if ((big = vr_max[i]) < 0.0) - { /* largest magnitude is unknown; compute it */ - for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; - i_ptr < i_end; i_ptr++) - { if ((temp = sv_val[i_ptr]) < 0.0) - temp = -temp; - if (big < temp) - big = temp; - } - xassert(big > 0.0); - vr_max[i] = big; - } - /* find an element in i-th row, which is placed in the - * column with minimal number of non-zeros and satisfies to - * the stability condition (such element always exists) */ - min_i = min_j = 0, min_len = INT_MAX; - for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; - i_ptr < i_end; i_ptr++) - { /* get column index of v[i,j] */ - j = sv_ind[i_ptr]; - /* if j-th column is not shorter, skip v[i,j] */ - if (vc_len[j] >= min_len) - continue; - /* if |v[i,j]| < piv_tol * max|v[i,*]|, skip v[i,j] */ - if ((temp = sv_val[i_ptr]) < 0.0) - temp = -temp; - if (temp < piv_tol * big) - continue; - /* v[i,j] is a better candidate */ - min_i = i, min_j = j, min_len = vc_len[j]; - /* if Markowitz cost of v[i,j] is not greater than - * (len-1)**2, v[i,j] can be chosen as the pivot right - * now; this heuristic reduces the search and works well - * in many cases */ - if (min_len <= len) - { p = min_i, q = min_j; - goto done; - } - } - /* i-th row has been scanned */ - if (min_i != 0) - { /* element v[min_i,min_j] is a next pivot candidate */ - ncand++; - /* compute its Markowitz cost */ - cost = (double)(len - 1) * (double)(min_len - 1); - /* if this element is better, choose it as the pivot */ - if (cost < best) - p = min_i, q = min_j, best = cost; - /* if piv_lim candidates were considered, terminate - * the search, because it is doubtful that a much better - * candidate will be found */ - if (ncand == piv_lim) - goto done; - } - else - { /* this can never be */ - xassert(min_i != min_i); - } - } - } -done: /* report the pivot to the factorization routine */ - *p_ = p, *q_ = q; - return (p == 0); -} - -/*********************************************************************** -* sgf_eliminate - perform gaussian elimination -* -* This routine performs elementary gaussian transformations in order -* to eliminate subdiagonal elements in k-th column of matrix -* U = P'* V * Q' using pivot element u[k,k], where k is the number of -* current elimination step, 1 <= k <= n. -* -* The parameters p and q specify, resp., row and column indices of the -* pivot element v[p,q] = u[k,k]. -* -* On entry the routine assumes that partially triangularized matrices -* L = P'* F * P and U = P'* V * Q' have the following structure: -* -* 1 k n 1 k n -* 1 1 . . . . . . . . . 1 x x x x x x x x x x -* x 1 . . . . . . . . . x x x x x x x x x -* x x 1 . . . . . . . . . x x x x x x x x -* x x x 1 . . . . . . . . . x x x x x x x -* k x x x x 1 . . . . . k . . . . * * * * * * -* x x x x _ 1 . . . . . . . . # * * * * * -* x x x x _ . 1 . . . . . . . # * * * * * -* x x x x _ . . 1 . . . . . . # * * * * * -* x x x x _ . . . 1 . . . . . # * * * * * -* n x x x x _ . . . . 1 n . . . . # * * * * * -* -* matrix L matrix U -* -* where rows and columns k, k+1, ..., n of matrix U constitute the -* active submatrix. Elements to be eliminated are marked by '#', and -* other elements of the active submatrix are marked by '*'. May note -* that each eliminated non-zero element u[i,k] of matrix U gives -* corresponding non-zero element l[i,k] of matrix L (marked by '_'). -* -* Actually all operations are performed on matrix V. It is assumed -* that the row-wise representation corresponds to matrix V, but the -* column-wise representation corresponds to the active submatrix of -* matrix V (or, more precisely, to its pattern, because only row -* indices for columns of the active submatrix are used on this stage). -* -* Let u[k,k] = v[p,q] be the pivot. In order to eliminate subdiagonal -* elements u[i',k] = v[i,q], i'= k+1, k+2, ..., n, the routine applies -* the following elementary gaussian transformations: -* -* (i-th row of V) := (i-th row of V) - f[i,p] * (p-th row of V), -* -* where f[i,p] = v[i,q] / v[p,q] is a gaussian multiplier stored to -* p-th column of matrix F to keep the main equality A = F * V -* (corresponding elements l[i',k] of matrix L are marked by '_' on the -* figure above). -* -* NOTE: On entry to the routine the working arrays flag and work -* should contain zeros. This status is retained by the routine -* on exit. */ - -int sgf_eliminate(SGF *sgf, int p, int q) -{ LUF *luf = sgf->luf; - int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int fc_ref = luf->fc_ref; - int *fc_ptr = &sva->ptr[fc_ref-1]; - int *fc_len = &sva->len[fc_ref-1]; - int vr_ref = luf->vr_ref; - int *vr_ptr = &sva->ptr[vr_ref-1]; - int *vr_len = &sva->len[vr_ref-1]; - int *vr_cap = &sva->cap[vr_ref-1]; - double *vr_piv = luf->vr_piv; - int vc_ref = luf->vc_ref; - int *vc_ptr = &sva->ptr[vc_ref-1]; - int *vc_len = &sva->len[vc_ref-1]; - int *vc_cap = &sva->cap[vc_ref-1]; - int *rs_head = sgf->rs_head; - int *rs_prev = sgf->rs_prev; - int *rs_next = sgf->rs_next; - int *cs_head = sgf->cs_head; - int *cs_prev = sgf->cs_prev; - int *cs_next = sgf->cs_next; - double *vr_max = sgf->vr_max; - char *flag = sgf->flag; - double *work = sgf->work; - double eps_tol = sgf->eps_tol; - int nnz_diff = 0; - int fill, i, i_ptr, i_end, j, j_ptr, j_end, ptr, len, loc, loc1; - double vpq, fip, vij; - xassert(1 <= p && p <= n); - xassert(1 <= q && q <= n); - /* remove p-th row from the active set; this row will never - * return there */ - sgf_deactivate_row(p); - /* process p-th (pivot) row */ - ptr = 0; - for (i_end = (i_ptr = vr_ptr[p]) + vr_len[p]; - i_ptr < i_end; i_ptr++) - { /* get column index of v[p,j] */ - j = sv_ind[i_ptr]; - if (j == q) - { /* save pointer to pivot v[p,q] */ - ptr = i_ptr; - } - else - { /* store v[p,j], j != q, to working array */ - flag[j] = 1; - work[j] = sv_val[i_ptr]; - } - /* remove j-th column from the active set; q-th column will - * never return there while other columns will return to the - * active set with new length */ - if (cs_next[j] == j) - { /* j-th column was marked by the pivoting routine according - * to Uwe Suhl's suggestion and is already inactive */ - xassert(cs_prev[j] == j); - } - else - sgf_deactivate_col(j); - nnz_diff -= vc_len[j]; - /* find and remove v[p,j] from j-th column */ - for (j_end = (j_ptr = vc_ptr[j]) + vc_len[j]; - sv_ind[j_ptr] != p; j_ptr++) - /* nop */; - xassert(j_ptr < j_end); - sv_ind[j_ptr] = sv_ind[j_end-1]; - vc_len[j]--; - } - /* save pivot v[p,q] and remove it from p-th row */ - xassert(ptr > 0); - vpq = vr_piv[p] = sv_val[ptr]; - sv_ind[ptr] = sv_ind[i_end-1]; - sv_val[ptr] = sv_val[i_end-1]; - vr_len[p]--; - /* if it is not planned to update matrix V, relocate p-th row to - * the right (static) part of SVA */ - if (!sgf->updat) - { len = vr_len[p]; - if (sva->r_ptr - sva->m_ptr < len) - { sva_more_space(sva, len); - sv_ind = sva->ind; - sv_val = sva->val; - } - sva_make_static(sva, vr_ref-1+p); - } - /* copy the pattern (row indices) of q-th column of the active - * submatrix (from which v[p,q] has been just removed) to p-th - * column of matrix F (without unity diagonal element) */ - len = vc_len[q]; - if (len > 0) - { if (sva->r_ptr - sva->m_ptr < len) - { sva_more_space(sva, len); - sv_ind = sva->ind; - sv_val = sva->val; - } - sva_reserve_cap(sva, fc_ref-1+p, len); - memcpy(&sv_ind[fc_ptr[p]], &sv_ind[vc_ptr[q]], - len * sizeof(int)); - fc_len[p] = len; - } - /* make q-th column of the active submatrix empty */ - vc_len[q] = 0; - /* transform non-pivot rows of the active submatrix */ - for (loc = fc_len[p]-1; loc >= 0; loc--) - { /* get row index of v[i,q] = row index of f[i,p] */ - i = sv_ind[fc_ptr[p] + loc]; - xassert(i != p); /* v[p,q] was removed */ - /* remove i-th row from the active set; this row will return - * there with new length */ - sgf_deactivate_row(i); - /* find v[i,q] in i-th row */ - for (i_end = (i_ptr = vr_ptr[i]) + vr_len[i]; - sv_ind[i_ptr] != q; i_ptr++) - /* nop */; - xassert(i_ptr < i_end); - /* compute gaussian multiplier f[i,p] = v[i,q] / v[p,q] */ - fip = sv_val[fc_ptr[p] + loc] = sv_val[i_ptr] / vpq; - /* remove v[i,q] from i-th row */ - sv_ind[i_ptr] = sv_ind[i_end-1]; - sv_val[i_ptr] = sv_val[i_end-1]; - vr_len[i]--; - /* perform elementary gaussian transformation: - * (i-th row) := (i-th row) - f[i,p] * (p-th row) - * note that p-th row of V, which is in the working array, - * doesn't contain pivot v[p,q], and i-th row of V doesn't - * contain v[i,q] to be eliminated */ - /* walk thru i-th row and transform existing elements */ - fill = vr_len[p]; - for (i_end = (i_ptr = ptr = vr_ptr[i]) + vr_len[i]; - i_ptr < i_end; i_ptr++) - { /* get column index and value of v[i,j] */ - j = sv_ind[i_ptr]; - vij = sv_val[i_ptr]; - if (flag[j]) - { /* v[p,j] != 0 */ - flag[j] = 0, fill--; - /* v[i,j] := v[i,j] - f[i,p] * v[p,j] */ - vij -= fip * work[j]; - if (-eps_tol < vij && vij < +eps_tol) - { /* new v[i,j] is close to zero; remove it from the - * active submatrix, i.e. replace it by exact zero */ - /* find and remove v[i,j] from j-th column */ - for (j_end = (j_ptr = vc_ptr[j]) + vc_len[j]; - sv_ind[j_ptr] != i; j_ptr++) - /* nop */; - xassert(j_ptr < j_end); - sv_ind[j_ptr] = sv_ind[j_end-1]; - vc_len[j]--; - continue; - } - } - /* keep new v[i,j] in i-th row */ - sv_ind[ptr] = j; - sv_val[ptr] = vij; - ptr++; - } - /* (new length of i-th row may decrease because of numerical - * cancellation) */ - vr_len[i] = len = ptr - vr_ptr[i]; - /* now flag[*] is the pattern of the set v[p,*] \ v[i,*], and - * fill is the number of non-zeros in this set */ - if (fill == 0) - { /* no fill-in occurs */ - /* walk thru p-th row and restore the column flags */ - for (i_end = (i_ptr = vr_ptr[p]) + vr_len[p]; - i_ptr < i_end; i_ptr++) - flag[sv_ind[i_ptr]] = 1; /* v[p,j] != 0 */ - goto skip; - } - /* up to fill new non-zero elements may appear in i-th row due - * to fill-in; reserve locations for these elements (note that - * actual length of i-th row is currently stored in len) */ - if (vr_cap[i] < len + fill) - { if (sva->r_ptr - sva->m_ptr < len + fill) - { sva_more_space(sva, len + fill); - sv_ind = sva->ind; - sv_val = sva->val; - } - sva_enlarge_cap(sva, vr_ref-1+i, len + fill, 0); - } - vr_len[i] += fill; - /* walk thru p-th row and add new elements to i-th row */ - for (loc1 = vr_len[p]-1; loc1 >= 0; loc1--) - { /* get column index of v[p,j] */ - j = sv_ind[vr_ptr[p] + loc1]; - if (!flag[j]) - { /* restore j-th column flag */ - flag[j] = 1; - /* v[i,j] was computed earlier on transforming existing - * elements of i-th row */ - continue; - } - /* v[i,j] := 0 - f[i,p] * v[p,j] */ - vij = - fip * work[j]; - if (-eps_tol < vij && vij < +eps_tol) - { /* new v[i,j] is close to zero; do not add it to the - * active submatrix, i.e. replace it by exact zero */ - continue; - } - /* add new v[i,j] to i-th row */ - sv_ind[ptr = vr_ptr[i] + (len++)] = j; - sv_val[ptr] = vij; - /* add new v[i,j] to j-th column */ - if (vc_cap[j] == vc_len[j]) - { /* we reserve extra locations in j-th column to reduce - * further relocations of that column */ -#if 1 /* FIXME */ - /* use control parameter to specify the number of extra - * locations reserved */ - int need = vc_len[j] + 10; -#endif - if (sva->r_ptr - sva->m_ptr < need) - { sva_more_space(sva, need); - sv_ind = sva->ind; - sv_val = sva->val; - } - sva_enlarge_cap(sva, vc_ref-1+j, need, 1); - } - sv_ind[vc_ptr[j] + (vc_len[j]++)] = i; - } - /* set final length of i-th row just transformed */ - xassert(len <= vr_len[i]); - vr_len[i] = len; -skip: /* return i-th row to the active set with new length */ - sgf_activate_row(i); - /* since i-th row has been changed, largest magnitude of its - * elements becomes unknown */ - vr_max[i] = -1.0; - } - /* walk thru p-th (pivot) row */ - for (i_end = (i_ptr = vr_ptr[p]) + vr_len[p]; - i_ptr < i_end; i_ptr++) - { /* get column index of v[p,j] */ - j = sv_ind[i_ptr]; - xassert(j != q); /* v[p,q] was removed */ - /* return j-th column to the active set with new length */ - if (cs_next[j] == j && vc_len[j] != 1) - { /* j-th column was marked by the pivoting routine and it is - * still not a column singleton, so leave it incative */ - xassert(cs_prev[j] == j); - } - else - sgf_activate_col(j); - nnz_diff += vc_len[j]; - /* restore zero content of the working arrays */ - flag[j] = 0; - work[j] = 0.0; - } - /* return the difference between the numbers of non-zeros in the - * active submatrix on entry and on exit, resp. */ - return nnz_diff; -} - -/*********************************************************************** -* sgf_dense_lu - compute dense LU-factorization with full pivoting -* -* This routine performs Gaussian elimination with full pivoting to -* compute dense LU-factorization of the specified matrix A of order n -* in the form: -* -* A = P * L * U * Q, (1) -* -* where L is lower triangular matrix with unit diagonal, U is upper -* triangular matrix, P and Q are permutation matrices. -* -* On entry to the routine elements of matrix A = (a[i,j]) should be -* placed in the array elements a[0], ..., a[n^2-1] in dense row-wise -* format. On exit from the routine matrix A is replaced by factors L -* and U as follows: -* -* u[1,1] u[1,2] ... u[1,n-1] u[1,n] -* l[2,1] u[2,2] ... u[2,n-1] u[2,n] -* . . . . . . . . . . . . . . -* l[n-1,1] l[n-1,2] u[n-1,n-1] u[n-1,n] -* l[n,1] l[n,2] ... l[n,n-1] u[n,n] -* -* The unit diagonal elements of L are not stored. -* -* Information on permutations of rows and columns of active submatrix -* during factorization is accumulated by the routine as follows. Every -* time the routine permutes rows i and i' or columns j and j', it also -* permutes elements r[i-1] and r[i'-1] or c[j-1] and c[j'-1], resp. -* Thus, on entry to the routine elements r[0], r[1], ..., r[n-1] and -* c[0], c[1], ..., c[n-1] should be initialized by some integers that -* identify rows and columns of the original matrix A. -* -* If the factorization has been successfully computed, the routine -* returns zero. Otherwise, if on k-th elimination step, 1 <= k <= n, -* all elements of the active submatrix are close to zero, the routine -* returns k, in which case a partial factorization is stored in the -* array a. */ - -int sgf_dense_lu(int n, double a_[], int r[], int c[], double eps) -{ /* non-optimized version */ - int i, j, k, p, q, ref; - double akk, big, temp; -# define a(i,j) a_[(i)*n+(j)] - /* initially U = A, L = P = Q = I */ - /* main elimination loop */ - for (k = 0; k < n; k++) - { /* choose pivot u[p,q], k <= p, q <= n */ - p = q = -1, big = eps; - for (i = k; i < n; i++) - { for (j = k; j < n; j++) - { /* temp = |u[i,j]| */ - if ((temp = a(i,j)) < 0.0) - temp = -temp; - if (big < temp) - p = i, q = j, big = temp; - } - } - if (p < 0) - { /* k-th elimination step failed */ - return k+1; - } - /* permute rows k and p */ - if (k != p) - { for (j = 0; j < n; j++) - temp = a(k,j), a(k,j) = a(p,j), a(p,j) = temp; - ref = r[k], r[k] = r[p], r[p] = ref; - } - /* permute columns k and q */ - if (k != q) - { for (i = 0; i < n; i++) - temp = a(i,k), a(i,k) = a(i,q), a(i,q) = temp; - ref = c[k], c[k] = c[q], c[q] = ref; - } - /* now pivot is in position u[k,k] */ - akk = a(k,k); - /* eliminate subdiagonal elements u[k+1,k], ..., u[n,k] */ - for (i = k+1; i < n; i++) - { if (a(i,k) != 0.0) - { /* gaussian multiplier l[i,k] := u[i,k] / u[k,k] */ - temp = (a(i,k) /= akk); - /* (i-th row) := (i-th row) - l[i,k] * (k-th row) */ - for (j = k+1; j < n; j++) - a(i,j) -= temp * a(k,j); - } - } - } -# undef a - return 0; -} - -/*********************************************************************** -* sgf_dense_phase - compute LU-factorization (dense phase) -* -* This routine performs dense phase of computing LU-factorization. -* -* The aim is two-fold. First, the main factorization routine switches -* to dense phase when the active submatrix is relatively dense, so -* using dense format allows significantly reduces overheads needed to -* maintain sparse data structures. And second, that is more important, -* on dense phase full pivoting is used (rather than partial pivoting) -* that allows improving numerical stability, since round-off errors -* tend to increase on last steps of the elimination process. -* -* On entry the routine assumes that elimination steps 1, 2, ..., k-1 -* have been performed, so partially transformed matrices L = P'* F * P -* and U = P'* V * Q' have the following structure: -* -* 1 k n 1 k n -* 1 1 . . . . . . . . . 1 x x x x x x x x x x -* x 1 . . . . . . . . . x x x x x x x x x -* x x 1 . . . . . . . . . x x x x x x x x -* x x x 1 . . . . . . . . . x x x x x x x -* k x x x x 1 . . . . . k . . . . * * * * * * -* x x x x . 1 . . . . . . . . * * * * * * -* x x x x . . 1 . . . . . . . * * * * * * -* x x x x . . . 1 . . . . . . * * * * * * -* x x x x . . . . 1 . . . . . * * * * * * -* n x x x x . . . . . 1 n . . . . * * * * * * -* -* matrix L matrix U -* -* where rows and columns k, k+1, ..., n of matrix U constitute the -* active submatrix A~, whose elements are marked by '*'. -* -* The routine copies the active submatrix A~ to a working array in -* dense format, compute dense factorization A~ = P~* L~* U~* Q~ using -* full pivoting, and then copies non-zero elements of factors L~ and -* U~ back to factors L and U (more precisely, to factors F and V). -* -* If the factorization has been successfully computed, the routine -* returns zero. Otherwise, if on k-th elimination step, 1 <= k <= n, -* all elements of the active submatrix are close to zero, the routine -* returns k (information on linearly dependent rows/columns in this -* case is provided by matrices P and Q). */ - -int sgf_dense_phase(LUF *luf, int k, int updat) -{ int n = luf->n; - SVA *sva = luf->sva; - int *sv_ind = sva->ind; - double *sv_val = sva->val; - int fc_ref = luf->fc_ref; - int *fc_ptr = &sva->ptr[fc_ref-1]; - int *fc_len = &sva->len[fc_ref-1]; - int *fc_cap = &sva->cap[fc_ref-1]; - int vr_ref = luf->vr_ref; - int *vr_ptr = &sva->ptr[vr_ref-1]; - int *vr_len = &sva->len[vr_ref-1]; - int *vr_cap = &sva->cap[vr_ref-1]; - double *vr_piv = luf->vr_piv; - int vc_ref = luf->vc_ref; - int *vc_len = &sva->len[vc_ref-1]; - int *pp_inv = luf->pp_inv; - int *pp_ind = luf->pp_ind; - int *qq_ind = luf->qq_ind; - int *qq_inv = luf->qq_inv; - int a_end, a_ptr, end, i, ia, ii, j, ja, jj, ka, len, na, ne, - need, ptr; - double *a_; - xassert(1 <= k && k <= n); - /* active columns of V are not longer needed; make them empty */ - for (jj = k; jj <= n; jj++) - { /* jj is number of active column of U = P'* V * Q' */ - vc_len[qq_ind[jj]] = 0; - } - /* determine order of active submatrix A~ of matrix U */ - na = n - k + 1; - xassert(1 <= na && na <= n); - /* determine number of elements in dense triangular factor (L~ or - * U~), except diagonal elements */ - ne = na * (na - 1) / 2; - /* we allocate active submatrix A~ in free (middle) part of SVA; - * to avoid defragmentation that could destroy A~ we also should - * reserve ne locations to build rows of V from rows of U~ and ne - * locations to build columns of F from columns of L~ */ - need = na * na + ne + ne; - if (sva->r_ptr - sva->m_ptr < need) - { sva_more_space(sva, need); - sv_ind = sva->ind; - sv_val = sva->val; - } - /* free (middle) part of SVA is structured as follows: - * end of left (dynamic) part - * ne free locations for new rows of V - * na free locations for active submatrix A~ - * unused locations, if any - * ne free locations for new columns of F - * beginning of right (static) part */ - a_ptr = sva->m_ptr + ne; - a_end = a_ptr + na * na; - /* copy active submatrix A~ from matrix V to working array in - * dense row-wise format */ - a_ = &sva->val[a_ptr]; -# define a(ia, ja) a_[((ia) - 1) * na + ((ja) - 1)] - for (ia = 1; ia <= na; ia++) - { /* clear ia-th row of A~ */ - for (ja = 1; ja <= na; ja++) - a(ia, ja) = 0.0; - /* ia-th row of A~ = (k-1+ia)-th row of U = i-th row of V */ - i = pp_inv[k-1+ia]; - ptr = vr_ptr[i]; - end = ptr + vr_len[i]; - for (; ptr < end; ptr++) - a(ia, qq_inv[sv_ind[ptr]]-k+1) = sv_val[ptr]; - /* i-th row of V is no longer needed; make it empty */ - vr_len[i] = 0; - } - /* compute dense factorization A~ = P~* L~* U~* Q~ */ -#if 1 /* FIXME: epsilon tolerance */ - ka = sgf_dense_lu(na, &a(1, 1), &pp_inv[k], &qq_ind[k], 1e-20); -#endif - /* rows of U with numbers pp_inv[k, k+1, ..., n] were permuted - * due to row permutations of A~; update matrix P using P~ */ - for (ii = k; ii <= n; ii++) - pp_ind[pp_inv[ii]] = ii; - /* columns of U with numbers qq_ind[k, k+1, ..., n] were permuted - * due to column permutations of A~; update matrix Q using Q~ */ - for (jj = k; jj <= n; jj++) - qq_inv[qq_ind[jj]] = jj; - /* check if dense factorization is complete */ - if (ka != 0) - { /* A~ is singular to working precision */ - /* information on linearly dependent rows/columns is provided - * by matrices P and Q */ - xassert(1 <= ka && ka <= na); - return k - 1 + ka; - } - /* build new rows of V from rows of U~ */ - for (ia = 1; ia <= na; ia++) - { /* ia-th row of U~ = (k-1+ia)-th row of U = i-th row of V */ - i = pp_inv[k-1+ia]; - xassert(vr_len[i] == 0); - /* store diagonal element u~[ia,ia] */ - vr_piv[i] = a(ia, ia); - /* determine number of non-zero non-diagonal elements in ia-th - * row of U~ */ - len = 0; - for (ja = ia+1; ja <= na; ja++) - { if (a(ia, ja) != 0.0) - len++; - } - /* reserve len locations for i-th row of matrix V in left - * (dynamic) part of SVA */ - if (vr_cap[i] < len) - { /* there should be enough room in free part of SVA */ - xassert(sva->r_ptr - sva->m_ptr >= len); - sva_enlarge_cap(sva, vr_ref-1+i, len, 0); - /* left part of SVA should not overlap matrix A~ */ - xassert(sva->m_ptr <= a_ptr); - } - /* copy non-zero non-diaginal elements of ia-th row of U~ to - * i-th row of V */ - ptr = vr_ptr[i]; - for (ja = ia+1; ja <= na; ja++) - { if (a(ia, ja) != 0.0) - { sv_ind[ptr] = qq_ind[k-1+ja]; - sv_val[ptr] = a(ia, ja); - ptr++; - } - } - xassert(ptr - vr_ptr[i] == len); - vr_len[i] = len; - } - /* build new columns of F from columns of L~ */ - for (ja = 1; ja <= na; ja++) - { /* ja-th column of L~ = (k-1+ja)-th column of L = j-th column - * of F */ - j = pp_inv[k-1+ja]; - xassert(fc_len[j] == 0); - xassert(fc_cap[j] == 0); - /* determine number of non-zero non-diagonal elements in ja-th - * column of L~ */ - len = 0; - for (ia = ja+1; ia <= na; ia++) - { if (a(ia, ja) != 0.0) - len++; - } - /* reserve len locations for j-th column of matrix F in right - * (static) part of SVA */ - /* there should be enough room in free part of SVA */ - xassert(sva->r_ptr - sva->m_ptr >= len); - if (len > 0) - sva_reserve_cap(sva, fc_ref-1+j, len); - /* right part of SVA should not overlap matrix A~ */ - xassert(a_end <= sva->r_ptr); - /* copy non-zero non-diagonal elements of ja-th column of L~ - * to j-th column of F */ - ptr = fc_ptr[j]; - for (ia = ja+1; ia <= na; ia++) - { if (a(ia, ja) != 0.0) - { sv_ind[ptr] = pp_inv[k-1+ia]; - sv_val[ptr] = a(ia, ja); - ptr++; - } - } - xassert(ptr - fc_ptr[j] == len); - fc_len[j] = len; - } - /* factors L~ and U~ are no longer needed */ -# undef a - /* if it is not planned to update matrix V, relocate all its new - * rows to the right (static) part of SVA */ - if (!updat) - { for (ia = 1; ia <= na; ia++) - { i = pp_inv[k-1+ia]; - len = vr_len[i]; - if (sva->r_ptr - sva->m_ptr < len) - { sva_more_space(sva, len); - sv_ind = sva->ind; - sv_val = sva->val; - } - sva_make_static(sva, vr_ref-1+i); - } - } - return 0; -} - -/*********************************************************************** -* sgf_factorize - compute LU-factorization (main routine) -* -* This routine computes sparse LU-factorization of specified matrix A -* using Gaussian elimination. -* -* On entry to the routine matrix V = A should be stored in column-wise -* format. -* -* If the factorization has been successfully computed, the routine -* returns zero. Otherwise, if on k-th elimination step, 1 <= k <= n, -* all elements of the active submatrix are close to zero, the routine -* returns k (information on linearly dependent rows/columns in this -* case is provided by matrices P and Q). */ - -int sgf_factorize(SGF *sgf, int singl) -{ LUF *luf = sgf->luf; - int n = luf->n; - SVA *sva = luf->sva; - int vr_ref = luf->vr_ref; - int *vr_len = &sva->len[vr_ref-1]; - double *vr_piv = luf->vr_piv; - int vc_ref = luf->vc_ref; - int *vc_len = &sva->len[vc_ref-1]; - int *pp_ind = luf->pp_ind; - int *pp_inv = luf->pp_inv; - int *qq_ind = luf->qq_ind; - int *qq_inv = luf->qq_inv; - int *rs_head = sgf->rs_head; - int *rs_prev = sgf->rs_prev; - int *rs_next = sgf->rs_next; - int *cs_head = sgf->cs_head; - int *cs_prev = sgf->cs_prev; - int *cs_next = sgf->cs_next; - double *vr_max = sgf->vr_max; - char *flag = sgf->flag; - double *work = sgf->work; - int i, j, k, k1, k2, p, q, nnz; - /* build matrix V = A in row-wise format */ - luf_build_v_rows(luf, rs_prev); - /* P := Q := I, so V = U = A, F = L = I */ - for (k = 1; k <= n; k++) - { vr_piv[k] = 0.0; - pp_ind[k] = pp_inv[k] = qq_ind[k] = qq_inv[k] = k; - } -#ifdef GLP_DEBUG - sva_check_area(sva); - luf_check_all(luf, 1); -#endif - /* perform singleton phase, if required */ - if (!singl) - { /* assume that nucleus is entire matrix U */ - k2 = 1; - } - else - { /* minimize nucleus size */ - sgf_reduce_nuc(luf, &k1, &k2, rs_prev, rs_next); -#ifdef GLP_DEBUG - xprintf("n = %d; k1 = %d; k2 = %d\n", n, k1, k2); -#endif - /* perform singleton phase */ - k2 = sgf_singl_phase(luf, k1, k2, sgf->updat, rs_prev, work); - } -#ifdef GLP_DEBUG - sva_check_area(sva); - luf_check_all(luf, k2); -#endif - /* initialize working arrays */ - rs_head[0] = cs_head[0] = 0; - for (k = 1; k <= n; k++) - { rs_head[k] = cs_head[k] = 0; - vr_max[k] = -1.0; - flag[k] = 0; - work[k] = 0.0; - } - /* build lists of active rows and columns of matrix V; determine - * number of non-zeros in initial active submatrix */ - nnz = 0; - for (k = k2; k <= n; k++) - { i = pp_inv[k]; - sgf_activate_row(i); - nnz += vr_len[i]; - j = qq_ind[k]; - sgf_activate_col(j); - } - /* main factorization loop */ - for (k = k2; k <= n; k++) - { int na; - double den; - /* calculate density of active submatrix */ - na = n - k + 1; /* order of active submatrix */ - den = (double)nnz / (double)(na * na); - /* if active submatrix is relatively dense, switch to dense - * phase */ -#if 1 /* FIXME */ - if (na >= 5 && den >= 0.71) - { -#ifdef GLP_DEBUG - xprintf("na = %d; nnz = %d; den = %g\n", na, nnz, den); -#endif - break; - } -#endif - /* choose pivot v[p,q] */ - if (sgf_choose_pivot(sgf, &p, &q) != 0) - return k; /* failure */ - /* u[i,j] = v[p,q], k <= i, j <= n */ - i = pp_ind[p]; - xassert(k <= i && i <= n); - j = qq_inv[q]; - xassert(k <= j && j <= n); - /* move u[i,j] to position u[k,k] by implicit permutations of - * rows and columns of matrix U */ - luf_swap_u_rows(k, i); - luf_swap_u_cols(k, j); - /* perform gaussian elimination */ - nnz += sgf_eliminate(sgf, p, q); - } -#if 1 /* FIXME */ - if (k <= n) - { /* continue computing factorization in dense mode */ -#ifdef GLP_DEBUG - sva_check_area(sva); - luf_check_all(luf, k); -#endif - k = sgf_dense_phase(luf, k, sgf->updat); - if (k != 0) - return k; /* failure */ - } -#endif -#ifdef GLP_DEBUG - sva_check_area(sva); - luf_check_all(luf, n+1); -#endif - /* defragment SVA; currently all columns of V are empty, so they - * will have zero capacity as required by luf_build_v_cols */ - sva_defrag_area(sva); - /* build matrix F in row-wise format */ - luf_build_f_rows(luf, rs_head); - /* build matrix V in column-wise format */ - luf_build_v_cols(luf, sgf->updat, rs_head); - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bflib/sgf.h b/resources/3rdparty/glpk-4.53/src/bflib/sgf.h deleted file mode 100644 index dc64f957c..000000000 --- a/resources/3rdparty/glpk-4.53/src/bflib/sgf.h +++ /dev/null @@ -1,203 +0,0 @@ -/* sgf.h (sparse Gaussian factorizer) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef SGF_H -#define SGF_H - -#include "luf.h" - -typedef struct SGF SGF; - -struct SGF -{ /* sparse Gaussian factorizer workspace */ - LUF *luf; - /* LU-factorization being computed */ - /*--------------------------------------------------------------*/ - /* to efficiently choose pivot elements according to Markowitz - * strategy, the search technique proposed by Iain Duff is used; - * it is based on using two families of sets {R[0], ..., R[n]} - * and {C[0], ..., C[n]}, where R[k] and C[k], 0 <= k <= n, are, - * respectively, sets of rows and columns of the active submatrix - * of matrix V having k non-zeros (i.e. whose length is k); each - * set R[k] and C[k] is implemented as a doubly linked list */ - int *rs_head; /* int rs_head[1+n]; */ - /* rs_head[k], 0 <= k <= n, is the number of first row, which - * has k non-zeros in the active submatrix */ - int *rs_prev; /* int rs_prev[1+n]; */ - /* rs_prev[0] is not used; - * rs_prev[i], 1 <= i <= n, is the number of previous row, which - * has the same number of non-zeros as i-th row; - * rs_prev[i] < 0 means that i-th row is inactive */ - int *rs_next; /* int rs_next[1+n]; */ - /* rs_next[0] is not used; - * rs_next[i], 1 <= i <= n, is the number of next row, which has - * the same number of non-zeros as i-th row; - * rs_next[i] < 0 means that i-th row is inactive */ - int *cs_head; /* int cs_head[1+n]; */ - /* cs_head[k], 0 <= k <= n, is the number of first column, which - * has k non-zeros in the active submatrix */ - int *cs_prev; /* int cs_prev[1+n]; */ - /* cs_prev[0] is not used; - * cs_prev[j], 1 <= j <= n, is the number of previous column, - * which has the same number of non-zeros as j-th column; - * cs_prev[j] < 0 means that j-th column is inactive */ - int *cs_next; /* int cs_next[1+n]; */ - /* cs_next[0] is not used; - * cs_next[j], 1 <= j <= n, is the number of next column, which - * has the same number of non-zeros as j-th column; - * cs_next[j] < 0 means that j-th column is inactive */ - /* NOTE: cs_prev[j] = cs_next[j] = j means that j-th column was - * temporarily removed from corresponding set C[k] by the - * pivoting routine according to Uwe Suhl's heuristic */ - /*--------------------------------------------------------------*/ - /* working arrays */ - double *vr_max; /* int vr_max[1+n]; */ - /* vr_max[0] is not used; - * vr_max[i], 1 <= i <= n, is used only if i-th row of matrix V - * is active (i.e. belongs to the active submatrix), and is the - * largest magnitude of elements in that row; if vr_max[i] < 0, - * the largest magnitude is unknown yet */ - char *flag; /* char flag[1+n]; */ - /* boolean working array */ - double *work; /* double work[1+n]; */ - /* floating-point working array */ - /*--------------------------------------------------------------*/ - /* control parameters */ - int updat; - /* if this flag is set, the matrix V is assumed to be updatable; - * in this case factorized (non-active) part of V is stored in - * the left part of SVA rather than in its right part */ - double piv_tol; - /* threshold pivoting tolerance, 0 < piv_tol < 1; element v[i,j] - * of the active submatrix fits to be pivot if it satisfies to - * the stability criterion |v[i,j]| >= piv_tol * max |v[i,*]|, - * i.e. if it is not very small in the magnitude among other - * elements in the same row; decreasing this parameter gives - * better sparsity at the expense of numerical accuracy and vice - * versa */ - int piv_lim; - /* maximal allowable number of pivot candidates to be considered; - * if piv_lim pivot candidates have been considered, the pivoting - * routine terminates the search with the best candidate found */ - int suhl; - /* if this flag is set, the pivoting routine applies a heuristic - * proposed by Uwe Suhl: if a column of the active submatrix has - * no eligible pivot candidates (i.e. all its elements do not - * satisfy to the stability criterion), the routine excludes it - * from futher consideration until it becomes column singleton; - * in many cases this allows reducing the time needed to choose - * the pivot */ - double eps_tol; - /* epsilon tolerance; each element of the active submatrix, whose - * magnitude is less than eps_tol, is replaced by exact zero */ -#if 0 /* FIXME */ - double den_lim; - /* density limit; if the density of the active submatrix reaches - * this limit, the factorization routine switches from sparse to - * dense mode */ -#endif -}; - -#define sgf_activate_row(i) \ - do \ - { int len = vr_len[i]; \ - rs_prev[i] = 0; \ - rs_next[i] = rs_head[len]; \ - if (rs_next[i] != 0) \ - rs_prev[rs_next[i]] = i; \ - rs_head[len] = i; \ - } while (0) -/* include i-th row of matrix V in active set R[len] */ - -#define sgf_deactivate_row(i) \ - do \ - { if (rs_prev[i] == 0) \ - rs_head[vr_len[i]] = rs_next[i]; \ - else \ - rs_next[rs_prev[i]] = rs_next[i]; \ - if (rs_next[i] == 0) \ - ; \ - else \ - rs_prev[rs_next[i]] = rs_prev[i]; \ - rs_prev[i] = rs_next[i] = -1; \ - } while (0) -/* remove i-th row of matrix V from active set R[len] */ - -#define sgf_activate_col(j) \ - do \ - { int len = vc_len[j]; \ - cs_prev[j] = 0; \ - cs_next[j] = cs_head[len]; \ - if (cs_next[j] != 0) \ - cs_prev[cs_next[j]] = j; \ - cs_head[len] = j; \ - } while (0) -/* include j-th column of matrix V in active set C[len] */ - -#define sgf_deactivate_col(j) \ - do \ - { if (cs_prev[j] == 0) \ - cs_head[vc_len[j]] = cs_next[j]; \ - else \ - cs_next[cs_prev[j]] = cs_next[j]; \ - if (cs_next[j] == 0) \ - ; \ - else \ - cs_prev[cs_next[j]] = cs_prev[j]; \ - cs_prev[j] = cs_next[j] = -1; \ - } while (0) -/* remove j-th column of matrix V from active set C[len] */ - -#define sgf_reduce_nuc _glp_sgf_reduce_nuc -void sgf_reduce_nuc(LUF *luf, int *k1, int *k2, int cnt[/*1+n*/], - int list[/*1+n*/]); -/* initial reordering to minimize nucleus size */ - -#define sgf_singl_phase _glp_sgf_singl_phase -int sgf_singl_phase(LUF *luf, int k1, int k2, int updat, - int ind[/*1+n*/], double val[/*1+n*/]); -/* compute LU-factorization (singleton phase) */ - -#define sgf_choose_pivot _glp_sgf_choose_pivot -int sgf_choose_pivot(SGF *sgf, int *p, int *q); -/* choose pivot element v[p,q] */ - -#define sgf_eliminate _glp_sgf_eliminate -int sgf_eliminate(SGF *sgf, int p, int q); -/* perform gaussian elimination */ - -#define sgf_dense_lu _glp_sgf_dense_lu -int sgf_dense_lu(int n, double a[], int r[], int c[], double eps); -/* compute dense LU-factorization with full pivoting */ - -#define sgf_dense_phase _glp_sgf_dense_phase -int sgf_dense_phase(LUF *luf, int k, int updat); -/* compute LU-factorization (dense phase) */ - -#define sgf_factorize _glp_sgf_factorize -int sgf_factorize(SGF *sgf, int singl); -/* compute LU-factorization (main routine) */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bflib/sva.c b/resources/3rdparty/glpk-4.53/src/bflib/sva.c deleted file mode 100644 index 264f9e15f..000000000 --- a/resources/3rdparty/glpk-4.53/src/bflib/sva.c +++ /dev/null @@ -1,568 +0,0 @@ -/* sva.c (sparse vector area) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "sva.h" - -/*********************************************************************** -* sva_create_area - create sparse vector area (SVA) -* -* This routine creates the sparse vector area (SVA), which initially -* is empty. -* -* The parameter n_max specifies the initial number of vectors that can -* be allocated in the SVA, n_max > 0. -* -* The parameter size specifies the initial number of free locations in -* the SVA, size > 0. -* -* On exit the routine returns a pointer to the SVA created. */ - -SVA *sva_create_area(int n_max, int size) -{ SVA *sva; - xassert(0 < n_max && n_max < INT_MAX); - xassert(0 < size && size < INT_MAX); - sva = talloc(1, SVA); - sva->n_max = n_max; - sva->n = 0; - sva->ptr = talloc(1+n_max, int); - sva->len = talloc(1+n_max, int); - sva->cap = talloc(1+n_max, int); - sva->size = size; - sva->m_ptr = 1; - sva->r_ptr = size+1; - sva->head = sva->tail = 0; - sva->prev = talloc(1+n_max, int); - sva->next = talloc(1+n_max, int); - sva->ind = talloc(1+size, int); - sva->val = talloc(1+size, double); - sva->talky = 0; - return sva; -} - -/*********************************************************************** -* sva_alloc_vecs - allocate new vectors in SVA -* -* This routine allocates nnn new empty vectors, nnn > 0, in the sparse -* vector area (SVA). -* -* The new vectors are assigned reference numbers k, k+1, ..., k+nnn-1, -* where k is a reference number assigned to the very first new vector, -* which is returned by the routine on exit. */ - -int sva_alloc_vecs(SVA *sva, int nnn) -{ int n = sva->n; - int n_max = sva->n_max; - int *ptr = sva->ptr; - int *len = sva->len; - int *cap = sva->cap; - int *prev = sva->prev; - int *next = sva->next; - int k, new_n; -#if 1 - if (sva->talky) - xprintf("sva_alloc_vecs: nnn = %d\n", nnn); -#endif - xassert(nnn > 0); - /* determine new number of vectors in SVA */ - new_n = n + nnn; - xassert(new_n > n); - if (n_max < new_n) - { /* enlarge the SVA arrays */ - while (n_max < new_n) - { n_max += n_max; - xassert(n_max > 0); - } - sva->n_max = n_max; - sva->ptr = ptr = trealloc(ptr, 1+n_max, int); - sva->len = len = trealloc(len, 1+n_max, int); - sva->cap = cap = trealloc(cap, 1+n_max, int); - sva->prev = prev = trealloc(prev, 1+n_max, int); - sva->next = next = trealloc(next, 1+n_max, int); - } - /* initialize new vectors */ - sva->n = new_n; - for (k = n+1; k <= new_n; k++) - { ptr[k] = len[k] = cap[k] = 0; - prev[k] = next[k] = -1; - } -#if 1 - if (sva->talky) - xprintf("now sva->n_max = %d, sva->n = %d\n", - sva->n_max, sva->n); -#endif - /* return reference number of very first new vector */ - return n+1; -} - -/*********************************************************************** -* sva_resize_area - change size of SVA storage -* -* This routine increases or decrases the size of the SVA storage by -* reallocating it. -* -* The parameter delta specifies the number of location by which the -* current size of the SVA storage should be increased (if delta > 0) -* or decreased (if delta < 0). Note that if delta is negative, it -* should not be less than the current size of the middle part. -* -* As a result of this operation the size of the middle part of SVA is -* increased/decreased by delta locations. -* -* NOTE: This operation changes ptr[k] for all vectors stored in the -* right part of SVA. */ - -void sva_resize_area(SVA *sva, int delta) -{ int n = sva->n; - int *ptr = sva->ptr; - int size = sva->size; - int m_ptr = sva->m_ptr; - int r_ptr = sva->r_ptr; - int k, r_size; -#if 1 - if (sva->talky) - xprintf("sva_resize_area: delta = %d\n", delta); -#endif - xassert(delta != 0); - /* determine size of the right part, in locations */ - r_size = size - r_ptr + 1; - /* relocate the right part in case of negative delta */ - if (delta < 0) - { xassert(delta >= m_ptr - r_ptr); - sva->r_ptr += delta; - memmove(&sva->ind[sva->r_ptr], &sva->ind[r_ptr], - r_size * sizeof(int)); - memmove(&sva->val[sva->r_ptr], &sva->val[r_ptr], - r_size * sizeof(double)); - } - /* reallocate the storage arrays */ - xassert(delta < INT_MAX - sva->size); - sva->size += delta; - sva->ind = trealloc(sva->ind, 1+sva->size, int); - sva->val = trealloc(sva->val, 1+sva->size, double); - /* relocate the right part in case of positive delta */ - if (delta > 0) - { sva->r_ptr += delta; - memmove(&sva->ind[sva->r_ptr], &sva->ind[r_ptr], - r_size * sizeof(int)); - memmove(&sva->val[sva->r_ptr], &sva->val[r_ptr], - r_size * sizeof(double)); - } - /* update pointers to vectors stored in the right part */ - for (k = 1; k <= n; k++) - { if (ptr[k] >= r_ptr) - ptr[k] += delta; - } -#if 1 - if (sva->talky) - xprintf("now sva->size = %d\n", sva->size); -#endif - return; -} - -/*********************************************************************** -* sva_defrag_area - defragment left part of SVA -* -* This routine performs "garbage" collection to defragment the left -* part of SVA. -* -* NOTE: This operation may change ptr[k] and cap[k] for all vectors -* stored in the left part of SVA. */ - -void sva_defrag_area(SVA *sva) -{ int *ptr = sva->ptr; - int *len = sva->len; - int *cap = sva->cap; - int *prev = sva->prev; - int *next = sva->next; - int *ind = sva->ind; - double *val = sva->val; - int k, next_k, ptr_k, len_k, m_ptr, head, tail; -#if 1 - if (sva->talky) - { xprintf("sva_defrag_area:\n"); - xprintf("before defragmenting = %d %d %d\n", sva->m_ptr - 1, - sva->r_ptr - sva->m_ptr, sva->size + 1 - sva->r_ptr); - } -#endif - m_ptr = 1; - head = tail = 0; - /* walk through the linked list of vectors stored in the left - * part of SVA */ - for (k = sva->head; k != 0; k = next_k) - { /* save number of next vector in the list */ - next_k = next[k]; - /* determine length of k-th vector */ - len_k = len[k]; - if (len_k == 0) - { /* k-th vector is empty; remove it from the left part */ - ptr[k] = cap[k] = 0; - prev[k] = next[k] = -1; - } - else - { /* determine pointer to first location of k-th vector */ - ptr_k = ptr[k]; - xassert(m_ptr <= ptr_k); - /* relocate k-th vector to the beginning of the left part, - * if necessary */ - if (m_ptr < ptr_k) - { memmove(&ind[m_ptr], &ind[ptr_k], - len_k * sizeof(int)); - memmove(&val[m_ptr], &val[ptr_k], - len_k * sizeof(double)); - ptr[k] = m_ptr; - } - /* remove unused locations from k-th vector */ - cap[k] = len_k; - /* the left part of SVA has been enlarged */ - m_ptr += len_k; - /* add k-th vector to the end of the new linked list */ - prev[k] = tail; - next[k] = 0; - if (head == 0) - head = k; - else - next[tail] = k; - tail = k; - } - } - /* set new pointer to the middle part of SVA */ - xassert(m_ptr <= sva->r_ptr); - sva->m_ptr = m_ptr; - /* set new head and tail of the linked list */ - sva->head = head; - sva->tail = tail; -#if 1 - if (sva->talky) - xprintf("after defragmenting = %d %d %d\n", sva->m_ptr - 1, - sva->r_ptr - sva->m_ptr, sva->size + 1 - sva->r_ptr); -#endif - return; -} - -/*********************************************************************** -* sva_more_space - increase size of middle (free) part of SVA -* -* This routine increases the size of the middle (free) part of the -* sparse vector area (SVA). -* -* The parameter m_size specifies the minimal size, in locations, of -* the middle part to be provided. This new size should be greater than -* the current size of the middle part. -* -* First, the routine defragments the left part of SVA. Then, if the -* size of the left part has not sufficiently increased, the routine -* increases the total size of the SVA storage by reallocating it. */ - -void sva_more_space(SVA *sva, int m_size) -{ int size, delta; -#if 1 - if (sva->talky) - xprintf("sva_more_space: m_size = %d\n", m_size); -#endif - xassert(m_size > sva->r_ptr - sva->m_ptr); - /* defragment the left part */ - sva_defrag_area(sva); - /* set, heuristically, the minimal size of the middle part to be - * not less than the size of the defragmented left part */ - if (m_size < sva->m_ptr - 1) - m_size = sva->m_ptr - 1; - /* if there is still not enough room, increase the total size of - * the SVA storage */ - if (sva->r_ptr - sva->m_ptr < m_size) - { size = sva->size; /* new sva size */ - for (;;) - { delta = size - sva->size; - if (sva->r_ptr - sva->m_ptr + delta >= m_size) - break; - size += size; - xassert(size > 0); - } - sva_resize_area(sva, delta); - xassert(sva->r_ptr - sva->m_ptr >= m_size); - } - return; -} - -/*********************************************************************** -* sva_enlarge_cap - enlarge capacity of specified vector -* -* This routine enlarges the current capacity of the specified vector -* by relocating its content. -* -* The parameter k specifies the reference number of the vector whose -* capacity should be enlarged, 1 <= k <= n. This vector should either -* have zero capacity or be stored in the left (dynamic) part of SVA. -* -* The parameter new_cap specifies the new capacity of the vector, -* in locations. This new capacity should be greater than the current -* capacity of the vector. -* -* The parameter skip is a flag. If this flag is set, the routine does -* *not* copy numerical values of elements of the vector on relocating -* its content, i.e. only element indices are copied. -* -* NOTE: On entry to the routine the middle part of SVA should have at -* least new_cap free locations. */ - -void sva_enlarge_cap(SVA *sva, int k, int new_cap, int skip) -{ int *ptr = sva->ptr; - int *len = sva->len; - int *cap = sva->cap; - int *prev = sva->prev; - int *next = sva->next; - int *ind = sva->ind; - double *val = sva->val; - xassert(1 <= k && k <= sva->n); - xassert(new_cap > cap[k]); - /* there should be at least new_cap free locations */ - xassert(sva->r_ptr - sva->m_ptr >= new_cap); - /* relocate the vector */ - if (cap[k] == 0) - { /* the vector is empty */ - xassert(ptr[k] == 0); - xassert(len[k] == 0); - } - else - { /* the vector has non-zero capacity */ - xassert(ptr[k] + len[k] <= sva->m_ptr); - /* copy the current vector content to the beginning of the - * middle part */ - if (len[k] > 0) - { memcpy(&ind[sva->m_ptr], &ind[ptr[k]], - len[k] * sizeof(int)); - if (!skip) - memcpy(&val[sva->m_ptr], &val[ptr[k]], - len[k] * sizeof(double)); - } - /* remove the vector from the linked list */ - if (prev[k] == 0) - sva->head = next[k]; - else - { /* preceding vector exists; increase its capacity */ - cap[prev[k]] += cap[k]; - next[prev[k]] = next[k]; - } - if (next[k] == 0) - sva->tail = prev[k]; - else - prev[next[k]] = prev[k]; - } - /* set new pointer and capacity of the vector */ - ptr[k] = sva->m_ptr; - cap[k] = new_cap; - /* add the vector to the end of the linked list */ - prev[k] = sva->tail; - next[k] = 0; - if (sva->head == 0) - sva->head = k; - else - next[sva->tail] = k; - sva->tail = k; - /* new_cap free locations have been consumed */ - sva->m_ptr += new_cap; - xassert(sva->m_ptr <= sva->r_ptr); - return; -} - -/*********************************************************************** -* sva_reserve_cap - reserve locations for specified vector -* -* This routine reserves locations for the specified vector in the -* right (static) part of SVA. -* -* The parameter k specifies the reference number of the vector (this -* vector should have zero capacity), 1 <= k <= n. -* -* The parameter new_cap specifies a non-zero capacity of the vector, -* in locations. -* -* NOTE: On entry to the routine the middle part of SVA should have at -* least new_cap free locations. */ - -void sva_reserve_cap(SVA *sva, int k, int new_cap) -{ int *ptr = sva->ptr; - int *len = sva->len; - int *cap = sva->cap; - xassert(1 <= k && k <= sva->n); - xassert(new_cap > 0); - xassert(ptr[k] == 0 && len[k] == 0 && cap[k] == 0); - /* there should be at least new_cap free locations */ - xassert(sva->r_ptr - sva->m_ptr >= new_cap); - /* set the pointer and capacity of the vector */ - ptr[k] = sva->r_ptr - new_cap; - cap[k] = new_cap; - /* new_cap free locations have been consumed */ - sva->r_ptr -= new_cap; - return; -} - -/*********************************************************************** -* sva_make_static - relocate specified vector to right part of SVA -* -* Assuming that the specified vector is stored in the left (dynamic) -* part of SVA, this routine makes the vector static by relocating its -* content to the right (static) part of SVA. However, if the specified -* vector has zero capacity, the routine does nothing. -* -* The parameter k specifies the reference number of the vector to be -* relocated, 1 <= k <= n. -* -* NOTE: On entry to the routine the middle part of SVA should have at -* least len[k] free locations, where len[k] is the length of the -* vector to be relocated. */ - -void sva_make_static(SVA *sva, int k) -{ int *ptr = sva->ptr; - int *len = sva->len; - int *cap = sva->cap; - int *prev = sva->prev; - int *next = sva->next; - int *ind = sva->ind; - double *val = sva->val; - int ptr_k, len_k; - xassert(1 <= k && k <= sva->n); - /* if the vector has zero capacity, do nothing */ - if (cap[k] == 0) - { xassert(ptr[k] == 0); - xassert(len[k] == 0); - goto done; - } - /* there should be at least len[k] free locations */ - len_k = len[k]; - xassert(sva->r_ptr - sva->m_ptr >= len_k); - /* remove the vector from the linked list */ - if (prev[k] == 0) - sva->head = next[k]; - else - { /* preceding vector exists; increase its capacity */ - cap[prev[k]] += cap[k]; - next[prev[k]] = next[k]; - } - if (next[k] == 0) - sva->tail = prev[k]; - else - prev[next[k]] = prev[k]; - /* if the vector has zero length, make it empty */ - if (len_k == 0) - { ptr[k] = cap[k] = 0; - goto done; - } - /* copy the vector content to the beginning of the right part */ - ptr_k = sva->r_ptr - len_k; - memcpy(&ind[ptr_k], &ind[ptr[k]], len_k * sizeof(int)); - memcpy(&val[ptr_k], &val[ptr[k]], len_k * sizeof(double)); - /* set new pointer and capacity of the vector */ - ptr[k] = ptr_k; - cap[k] = len_k; - /* len[k] free locations have been consumed */ - sva->r_ptr -= len_k; -done: return; -} - -/*********************************************************************** -* sva_check_area - check sparse vector area (SVA) -* -* This routine checks the SVA data structures for correctness. -* -* NOTE: For testing/debugging only. */ - -void sva_check_area(SVA *sva) -{ int n_max = sva->n_max; - int n = sva->n; - int *ptr = sva->ptr; - int *len = sva->len; - int *cap = sva->cap; - int size = sva->size; - int m_ptr = sva->m_ptr; - int r_ptr = sva->r_ptr; - int head = sva->head; - int tail = sva->tail; - int *prev = sva->prev; - int *next = sva->next; - int k; - xassert(1 <= n && n <= n_max); - xassert(1 <= m_ptr && m_ptr <= r_ptr && r_ptr <= size+1); - /* all vectors included the linked list should have non-zero - * capacity and be stored in the left part */ - for (k = head; k != 0; k = next[k]) - { xassert(1 <= k && k <= n); - xassert(cap[k] > 0); - xassert(0 <= len[k] && len[k] <= cap[k]); - if (prev[k] == 0) - xassert(k == head); - else - { xassert(1 <= prev[k] && prev[k] <= n); - xassert(next[prev[k]] == k); - } - if (next[k] == 0) - { xassert(k == tail); - xassert(ptr[k] + cap[k] <= m_ptr); - } - else - { xassert(1 <= next[k] && next[k] <= n); - xassert(prev[next[k]] == k); - xassert(ptr[k] + cap[k] <= ptr[next[k]]); - } - cap[k] = -cap[k]; - } - /* all other vectors should either have zero capacity or be - * stored in the right part */ - for (k = 1; k <= n; k++) - { if (cap[k] < 0) - { /* k-th vector is stored in the left part */ - cap[k] = -cap[k]; - } - else if (cap[k] == 0) - { /* k-th vector has zero capacity */ - xassert(ptr[k] == 0); - xassert(len[k] == 0); - } - else /* cap[k] > 0 */ - { /* k-th vector is stored in the right part */ - xassert(0 <= len[k] && len[k] <= cap[k]); - xassert(r_ptr <= ptr[k] && ptr[k] + cap[k] <= size+1); - } - } - return; -} - -/*********************************************************************** -* sva_delete_area - delete sparse vector area (SVA) -* -* This routine deletes the sparse vector area (SVA) freeing all the -* memory allocated to it. */ - -void sva_delete_area(SVA *sva) -{ tfree(sva->ptr); - tfree(sva->len); - tfree(sva->cap); - tfree(sva->prev); - tfree(sva->next); - tfree(sva->ind); - tfree(sva->val); - tfree(sva); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bflib/sva.h b/resources/3rdparty/glpk-4.53/src/bflib/sva.h deleted file mode 100644 index ad3959ba5..000000000 --- a/resources/3rdparty/glpk-4.53/src/bflib/sva.h +++ /dev/null @@ -1,161 +0,0 @@ -/* sva.h (sparse vector area) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef SVA_H -#define SVA_H - -/*********************************************************************** -* Sparse Vector Area (SVA) is a container for sparse vectors. This -* program object is used mainly on computing factorization, where the -* sparse vectors are rows and columns of sparse matrices. -* -* The SVA storage is a set of locations numbered 1, 2, ..., size, -* where size is the size of SVA, which is the total number of -* locations currently allocated. Each location is identified by its -* pointer p, 1 <= p <= size, and is the pair (ind[p], val[p]), where -* ind[p] and val[p] are, respectively, the index and value fields used -* to store the index and numeric value of a particular vector element. -* -* Each sparse vector is identified by its reference number k, -* 1 <= k <= n, where n is the total number of vectors currently stored -* in SVA, and defined by the triplet (ptr[k], len[k], cap[k]), where: -* ptr[k] is a pointer to the first location of the vector; len[k] is -* the vector length, which is the number of its non-zero elements, -* len[k] >= 0; and cap[k] is the capacity of the vector, which is the -* total number of adjacent locations allocated to that vector, -* cap[k] >= len[k]. Thus, non-zero elements of k-th vector are stored -* in locations ptr[k], ptr[k]+1, ..., ptr[k]+len[k]-1, and locations -* ptr[k]+len[k], ptr[k]+len[k]+1, ..., ptr[k]+cap[k]-1 are reserved. -* -* The SVA storage is divided into three parts as follows: -* -* Locations 1, 2, ..., m_ptr-1 constitute the left (dynamic) part of -* SVA. This part is used to store vectors, whose capacity may change. -* Note that all vectors stored in the left part are also included in -* a doubly linked list, where they are ordered by increasing their -* pointers ptr[k] (this list is needed for efficient implementation -* of the garbage collector used to defragment the left part of SVA); -* -* Locations m_ptr, m_ptr+1, ..., r_ptr-1 are free and constitute the -* middle (free) part of SVA. -* -* Locations r_ptr, r_ptr+1, ..., size constitute the right (static) -* part of SVA. This part is used to store vectors, whose capacity is -* not changed. */ - -typedef struct SVA SVA; - -struct SVA -{ /* sparse vector area */ - int n_max; - /* maximal value of n (enlarged automatically) */ - int n; - /* number of currently allocated vectors, 0 <= n <= n_max */ - int *ptr; /* int ptr[1+n_max]; */ - /* ptr[0] is not used; - * ptr[k], 1 <= i <= n, is pointer to first location of k-th - * vector in the arrays ind and val */ - int *len; /* int len[1+n_max]; */ - /* len[0] is not used; - * len[k], 1 <= k <= n, is length of k-th vector, len[k] >= 0 */ - int *cap; /* int cap[1+n_max]; */ - /* cap[0] is not used; - * cap[k], 1 <= k <= n, is capacity of k-th vector (the number - * of adjacent locations allocated to it), cap[k] >= len[k] */ - /* NOTE: if cap[k] = 0, then ptr[k] = 0 and len[k] = 0 */ - int size; - /* total number of locations in SVA */ - int m_ptr, r_ptr; - /* partitioning pointers that define the left, middle, and right - * parts of SVA (see above); 1 <= m_ptr <= r_ptr <= size+1 */ - int head; - /* number of first (leftmost) vector in the linked list */ - int tail; - /* number of last (rightmost) vector in the linked list */ - int *prev; /* int prev[1+n_max]; */ - /* prev[0] is not used; - * prev[k] is number of vector which precedes k-th vector in the - * linked list; - * prev[k] < 0 means that k-th vector is not in the list */ - int *next; /* int next[1+n_max]; */ - /* next[0] is not used; - * next[k] is number of vector which succedes k-th vector in the - * linked list; - * next[k] < 0 means that k-th vector is not in the list */ - /* NOTE: only vectors having non-zero capacity and stored in the - * left part of SVA are included in this linked list */ - int *ind; /* int ind[1+size]; */ - /* ind[0] is not used; - * ind[p], 1 <= p <= size, is index field of location p */ - double *val; /* double val[1+size]; */ - /* val[0] is not used; - * val[p], 1 <= p <= size, is value field of location p */ -#if 1 - int talky; - /* option to enable talky mode */ -#endif -}; - -#define sva_create_area _glp_sva_create_area -SVA *sva_create_area(int n_max, int size); -/* create sparse vector area (SVA) */ - -#define sva_alloc_vecs _glp_sva_alloc_vecs -int sva_alloc_vecs(SVA *sva, int nnn); -/* allocate new vectors in SVA */ - -#define sva_resize_area _glp_sva_resize_area -void sva_resize_area(SVA *sva, int delta); -/* change size of SVA storage */ - -#define sva_defrag_area _glp_sva_defrag_area -void sva_defrag_area(SVA *sva); -/* defragment left part of SVA */ - -#define sva_more_space _glp_sva_more_space -void sva_more_space(SVA *sva, int m_size); -/* increase size of middle (free) part of SVA */ - -#define sva_enlarge_cap _glp_sva_enlarge_cap -void sva_enlarge_cap(SVA *sva, int k, int new_cap, int skip); -/* enlarge capacity of specified vector */ - -#define sva_reserve_cap _glp_sva_reserve_cap -void sva_reserve_cap(SVA *sva, int k, int new_cap); -/* reserve locations for specified vector */ - -#define sva_make_static _glp_sva_make_static -void sva_make_static(SVA *sva, int k); -/* relocate specified vector to right part of SVA */ - -#define sva_check_area _glp_sva_check_area -void sva_check_area(SVA *sva); -/* check sparse vector area (SVA) */ - -#define sva_delete_area _glp_sva_delete_area -void sva_delete_area(SVA *sva); -/* delete sparse vector area (SVA) */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bfx.c b/resources/3rdparty/glpk-4.53/src/bfx.c deleted file mode 100644 index 565480b6f..000000000 --- a/resources/3rdparty/glpk-4.53/src/bfx.c +++ /dev/null @@ -1,89 +0,0 @@ -/* bfx.c (LP basis factorization driver, rational arithmetic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "bfx.h" -#include "env.h" -#include "lux.h" - -struct BFX -{ int valid; - LUX *lux; -}; - -BFX *bfx_create_binv(void) -{ /* create factorization of the basis matrix */ - BFX *bfx; - bfx = xmalloc(sizeof(BFX)); - bfx->valid = 0; - bfx->lux = NULL; - return bfx; -} - -int bfx_factorize(BFX *binv, int m, int (*col)(void *info, int j, - int ind[], mpq_t val[]), void *info) -{ /* compute factorization of the basis matrix */ - int ret; - xassert(m > 0); - if (binv->lux != NULL && binv->lux->n != m) - { lux_delete(binv->lux); - binv->lux = NULL; - } - if (binv->lux == NULL) - binv->lux = lux_create(m); - ret = lux_decomp(binv->lux, col, info); - binv->valid = (ret == 0); - return ret; -} - -void bfx_ftran(BFX *binv, mpq_t x[], int save) -{ /* perform forward transformation (FTRAN) */ - xassert(binv->valid); - lux_solve(binv->lux, 0, x); - xassert(save == save); - return; -} - -void bfx_btran(BFX *binv, mpq_t x[]) -{ /* perform backward transformation (BTRAN) */ - xassert(binv->valid); - lux_solve(binv->lux, 1, x); - return; -} - -int bfx_update(BFX *binv, int j) -{ /* update factorization of the basis matrix */ - xassert(binv->valid); - xassert(1 <= j && j <= binv->lux->n); - return 1; -} - -void bfx_delete_binv(BFX *binv) -{ /* delete factorization of the basis matrix */ - if (binv->lux != NULL) - lux_delete(binv->lux); - xfree(binv); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/bfx.h b/resources/3rdparty/glpk-4.53/src/bfx.h deleted file mode 100644 index 7d0aedaad..000000000 --- a/resources/3rdparty/glpk-4.53/src/bfx.h +++ /dev/null @@ -1,67 +0,0 @@ -/* bfx.h (LP basis factorization driver, rational arithmetic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef BFX_H -#define BFX_H - -#include "glpgmp.h" - -typedef struct BFX BFX; - -#define bfx_create_binv _glp_bfx_create_binv -BFX *bfx_create_binv(void); -/* create factorization of the basis matrix */ - -#define bfx_is_valid _glp_bfx_is_valid -int bfx_is_valid(BFX *binv); -/* check if factorization is valid */ - -#define bfx_invalidate _glp_bfx_invalidate -void bfx_invalidate(BFX *binv); -/* invalidate factorization of the basis matrix */ - -#define bfx_factorize _glp_bfx_factorize -int bfx_factorize(BFX *binv, int m, int (*col)(void *info, int j, - int ind[], mpq_t val[]), void *info); -/* compute factorization of the basis matrix */ - -#define bfx_ftran _glp_bfx_ftran -void bfx_ftran(BFX *binv, mpq_t x[], int save); -/* perform forward transformation (FTRAN) */ - -#define bfx_btran _glp_bfx_btran -void bfx_btran(BFX *binv, mpq_t x[]); -/* perform backward transformation (BTRAN) */ - -#define bfx_update _glp_bfx_update -int bfx_update(BFX *binv, int j); -/* update factorization of the basis matrix */ - -#define bfx_delete_binv _glp_bfx_delete_binv -void bfx_delete_binv(BFX *binv); -/* delete factorization of the basis matrix */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/cglib/cfg.c b/resources/3rdparty/glpk-4.53/src/cglib/cfg.c deleted file mode 100644 index 92738b415..000000000 --- a/resources/3rdparty/glpk-4.53/src/cglib/cfg.c +++ /dev/null @@ -1,409 +0,0 @@ -/* cfg.c (conflict graph) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "cfg.h" -#include "env.h" - -/*********************************************************************** -* cfg_create_graph - create conflict graph -* -* This routine creates the conflict graph, which initially is empty, -* and returns a pointer to the graph descriptor. -* -* The parameter n specifies the number of *all* variables in MIP, for -* which the conflict graph will be built. -* -* The parameter nv_max specifies maximal number of vertices in the -* conflict graph. It should be the double number of binary variables -* in corresponding MIP. */ - -CFG *cfg_create_graph(int n, int nv_max) -{ CFG *G; - xassert(n >= 0); - xassert(0 <= nv_max && nv_max <= n + n); - G = talloc(1, CFG); - G->n = n; - G->pos = talloc(1+n, int); - memset(&G->pos[1], 0, n * sizeof(int)); - G->neg = talloc(1+n, int); - memset(&G->neg[1], 0, n * sizeof(int)); - G->pool = dmp_create_pool(); - G->nv_max = nv_max; - G->nv = 0; - G->ref = talloc(1+nv_max, int); - G->vptr = talloc(1+nv_max, CFGVLE *); - G->cptr = talloc(1+nv_max, CFGCLE *); - return G; -} - -/*********************************************************************** -* cfg_add_clique - add clique to conflict graph -* -* This routine adds a clique to the conflict graph. -* -* The parameter size specifies the clique size, size >= 2. Note that -* any edge can be considered as a clique of size 2. -* -* The array ind specifies vertices constituting the clique in elements -* ind[k], 1 <= k <= size: -* -* ind[k] = +j means a vertex of the conflict graph that corresponds to -* original binary variable x[j], 1 <= j <= n. -* -* ind[k] = -j means a vertex of the conflict graph that corresponds to -* complement of original binary variable x[j], 1 <= j <= n. -* -* Note that if both vertices for x[j] and (1 - x[j]) have appeared in -* the conflict graph, the routine automatically adds an edge incident -* to these vertices. */ - -static void add_edge(CFG *G, int v, int w) -{ /* add clique of size 2 */ - DMP *pool = G->pool; - int nv = G->nv; - CFGVLE **vptr = G->vptr; - CFGVLE *vle; - xassert(1 <= v && v <= nv); - xassert(1 <= w && w <= nv); - xassert(v != w); - vle = dmp_talloc(pool, CFGVLE); - vle->v = w; - vle->next = vptr[v]; - vptr[v] = vle; - vle = dmp_talloc(pool, CFGVLE); - vle->v = v; - vle->next = vptr[w]; - vptr[w] = vle; - return; -} - -void cfg_add_clique(CFG *G, int size, const int ind[]) -{ int n = G->n; - int *pos = G->pos; - int *neg = G->neg; - DMP *pool = G->pool; - int nv_max = G->nv_max; - int *ref = G->ref; - CFGVLE **vptr = G->vptr; - CFGCLE **cptr = G->cptr; - int j, k, v; - xassert(2 <= size && size <= nv_max); - /* add new vertices to the conflict graph */ - for (k = 1; k <= size; k++) - { j = ind[k]; - if (j > 0) - { /* vertex corresponds to x[j] */ - xassert(1 <= j && j <= n); - if (pos[j] == 0) - { /* no such vertex exists; add it */ - v = pos[j] = ++(G->nv); - xassert(v <= nv_max); - ref[v] = j; - vptr[v] = NULL; - cptr[v] = NULL; - if (neg[j] != 0) - { /* now both vertices for x[j] and (1 - x[j]) exist */ - add_edge(G, v, neg[j]); - } - } - } - else - { /* vertex corresponds to (1 - x[j]) */ - j = -j; - xassert(1 <= j && j <= n); - if (neg[j] == 0) - { /* no such vertex exists; add it */ - v = neg[j] = ++(G->nv); - xassert(v <= nv_max); - ref[v] = j; - vptr[v] = NULL; - cptr[v] = NULL; - if (pos[j] != 0) - { /* now both vertices for x[j] and (1 - x[j]) exist */ - add_edge(G, v, pos[j]); - } - } - } - } - /* add specified clique to the conflict graph */ - if (size == 2) - add_edge(G, - ind[1] > 0 ? pos[+ind[1]] : neg[-ind[1]], - ind[2] > 0 ? pos[+ind[2]] : neg[-ind[2]]); - else - { CFGVLE *vp, *vle; - CFGCLE *cle; - /* build list of clique vertices */ - vp = NULL; - for (k = 1; k <= size; k++) - { vle = dmp_talloc(pool, CFGVLE); - vle->v = ind[k] > 0 ? pos[+ind[k]] : neg[-ind[k]]; - vle->next = vp; - vp = vle; - } - /* attach the clique to all its vertices */ - for (k = 1; k <= size; k++) - { cle = dmp_talloc(pool, CFGCLE); - cle->vptr = vp; - v = ind[k] > 0 ? pos[+ind[k]] : neg[-ind[k]]; - cle->next = cptr[v]; - cptr[v] = cle; - } - } - return; -} - -/*********************************************************************** -* cfg_get_adjacent - get vertices adjacent to specified vertex -* -* This routine stores numbers of all vertices adjacent to specified -* vertex v of the conflict graph in locations ind[1], ..., ind[len], -* and returns len, 1 <= len <= nv-1, where nv is the total number of -* vertices in the conflict graph. -* -* Note that the conflict graph defined by this routine has neither -* self-loops nor multiple edges. */ - -int cfg_get_adjacent(CFG *G, int v, int ind[]) -{ int nv = G->nv; - int *ref = G->ref; - CFGVLE **vptr = G->vptr; - CFGCLE **cptr = G->cptr; - CFGVLE *vle; - CFGCLE *cle; - int k, w, len; - xassert(1 <= v && v <= nv); - len = 0; - /* walk thru the list of adjacent vertices */ - for (vle = vptr[v]; vle != NULL; vle = vle->next) - { w = vle->v; - xassert(1 <= w && w <= nv); - xassert(w != v); - if (ref[w] > 0) - { ind[++len] = w; - ref[w] = -ref[w]; - } - } - /* walk thru the list of incident cliques */ - for (cle = cptr[v]; cle != NULL; cle = cle->next) - { /* walk thru the list of clique vertices */ - for (vle = cle->vptr; vle != NULL; vle = vle->next) - { w = vle->v; - xassert(1 <= w && w <= nv); - if (w != v && ref[w] > 0) - { ind[++len] = w; - ref[w] = -ref[w]; - } - } - } - xassert(1 <= len && len < nv); - /* unmark vertices included in the resultant adjacency list */ - for (k = 1; k <= len; k++) - { w = ind[k]; - ref[w] = -ref[w]; - } - return len; -} - -/*********************************************************************** -* cfg_expand_clique - expand specified clique to maximal clique -* -* Given some clique in the conflict graph this routine expands it to -* a maximal clique by including in it new vertices. -* -* On entry vertex indices constituting the initial clique should be -* stored in locations c_ind[1], ..., c_ind[c_len], where c_len is the -* initial clique size. On exit the routine stores new vertex indices -* to locations c_ind[c_len+1], ..., c_ind[c_len'], where c_len' is the -* size of the maximal clique found, and returns c_len'. -* -* ALGORITHM -* -* Let G = (V, E) be a graph, C within V be a current clique to be -* expanded, and D within V \ C be a subset of vertices adjacent to all -* vertices from C. On every iteration the routine chooses some vertex -* v in D, includes it into C, and removes from D the vertex v as well -* as all vertices not adjacent to v. Initially C is empty and D = V. -* Iterations repeat until D becomes an empty set. Obviously, the final -* set C is a maximal clique in G. -* -* Now let C0 be an initial clique, and we want C0 to be a subset of -* the final maximal clique C. To provide this condition the routine -* starts constructing C by choosing only such vertices v in D, which -* are in C0, until all vertices from C0 have been included in C. May -* note that if on some iteration C0 \ C is non-empty (i.e. if not all -* vertices from C0 have been included in C), C0 \ C is a subset of D, -* because C0 is a clique. */ - -static int intersection(int d_len, int d_ind[], int d_pos[], int len, - const int ind[]) -{ /* compute intersection D := D inter W, where W is some specified - * set of vertices */ - int k, t, v, new_len; - /* walk thru vertices in W and mark vertices in D */ - for (t = 1; t <= len; t++) - { /* v in W */ - v = ind[t]; - /* determine position of v in D */ - k = d_pos[v]; - if (k != 0) - { /* v in D */ - xassert(d_ind[k] == v); - /* mark v to keep it in D */ - d_ind[k] = -v; - } - } - /* remove all unmarked vertices from D */ - new_len = 0; - for (k = 1; k <= d_len; k++) - { /* v in D */ - v = d_ind[k]; - if (v < 0) - { /* v is marked; keep it */ - v = -v; - new_len++; - d_ind[new_len] = v; - d_pos[v] = new_len; - } - else - { /* v is not marked; remove it */ - d_pos[v] = 0; - } - } - return new_len; -} - -int cfg_expand_clique(CFG *G, int c_len, int c_ind[]) -{ int nv = G->nv; - int d_len, *d_ind, *d_pos, len, *ind; - int k, v; - xassert(0 <= c_len && c_len <= nv); - /* allocate working arrays */ - d_ind = talloc(1+nv, int); - d_pos = talloc(1+nv, int); - ind = talloc(1+nv, int); - /* initialize C := 0, D := V */ - d_len = nv; - for (k = 1; k <= nv; k++) - d_ind[k] = d_pos[k] = k; - /* expand C by vertices of specified initial clique C0 */ - for (k = 1; k <= c_len; k++) - { /* v in C0 */ - v = c_ind[k]; - xassert(1 <= v && v <= nv); - /* since C0 is clique, v should be in D */ - xassert(d_pos[v] != 0); - /* W := set of vertices adjacent to v */ - len = cfg_get_adjacent(G, v, ind); - /* D := D inter W */ - d_len = intersection(d_len, d_ind, d_pos, len, ind); - /* since v not in W, now v should be not in D */ - xassert(d_pos[v] == 0); - } - /* expand C by some other vertices until D is empty */ - while (d_len > 0) - { /* v in D */ - v = d_ind[1]; - xassert(1 <= v && v <= nv); - /* note that v is adjacent to all vertices in C (by design), - * so add v to C */ - c_ind[++c_len] = v; - /* W := set of vertices adjacent to v */ - len = cfg_get_adjacent(G, v, ind); - /* D := D inter W */ - d_len = intersection(d_len, d_ind, d_pos, len, ind); - /* since v not in W, now v should be not in D */ - xassert(d_pos[v] == 0); - } - /* free working arrays */ - tfree(d_ind); - tfree(d_pos); - tfree(ind); - /* bring maximal clique to calling routine */ - return c_len; -} - -/*********************************************************************** -* cfg_check_clique - check clique in conflict graph -* -* This routine checks that vertices of the conflict graph specified -* in locations c_ind[1], ..., c_ind[c_len] constitute a clique. -* -* NOTE: for testing/debugging only. */ - -void cfg_check_clique(CFG *G, int c_len, const int c_ind[]) -{ int nv = G->nv; - int k, kk, v, w, len, *ind; - char *flag; - ind = talloc(1+nv, int); - flag = talloc(1+nv, char); - memset(&flag[1], 0, nv); - /* walk thru clique vertices */ - xassert(c_len >= 0); - for (k = 1; k <= c_len; k++) - { /* get clique vertex v */ - v = c_ind[k]; - xassert(1 <= v && v <= nv); - /* get vertices adjacent to vertex v */ - len = cfg_get_adjacent(G, v, ind); - for (kk = 1; kk <= len; kk++) - { w = ind[kk]; - xassert(1 <= w && w <= nv); - xassert(w != v); - flag[w] = 1; - } - /* check that all clique vertices other than v are adjacent - to v */ - for (kk = 1; kk <= c_len; kk++) - { w = c_ind[kk]; - xassert(1 <= w && w <= nv); - if (w != v) - xassert(flag[w]); - } - /* reset vertex flags */ - for (kk = 1; kk <= len; kk++) - flag[ind[kk]] = 0; - } - tfree(ind); - tfree(flag); - return; -} - -/*********************************************************************** -* cfg_delete_graph - delete conflict graph -* -* This routine deletes the conflict graph by freeing all the memory -* allocated to this program object. */ - -void cfg_delete_graph(CFG *G) -{ tfree(G->pos); - tfree(G->neg); - dmp_delete_pool(G->pool); - tfree(G->ref); - tfree(G->vptr); - tfree(G->cptr); - tfree(G); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/cglib/cfg.h b/resources/3rdparty/glpk-4.53/src/cglib/cfg.h deleted file mode 100644 index 87b61c738..000000000 --- a/resources/3rdparty/glpk-4.53/src/cglib/cfg.h +++ /dev/null @@ -1,130 +0,0 @@ -/* cfg.h (conflict graph) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef CFG_H -#define CFG_H - -#include "dmp.h" - -/*********************************************************************** -* The structure CFG describes the conflict graph. -* -* Conflict graph is an undirected graph G = (V, E), where V is a set -* of vertices, E <= V x V is a set of edges. Each vertex v in V of the -* conflict graph corresponds to a binary variable z[v], which is -* either an original binary variable x[j] or its complement 1 - x[j]. -* Edge (v,w) in E means that z[v] and z[w] cannot take the value 1 at -* the same time, i.e. it defines an inequality z[v] + z[w] <= 1, which -* is assumed to be valid for original MIP. -* -* Since the conflict graph may be dense, it is stored as an union of -* its cliques rather than explicitly. */ - -typedef struct CFG CFG; -typedef struct CFGVLE CFGVLE; -typedef struct CFGCLE CFGCLE; - -struct CFG -{ /* conflict graph descriptor */ - int n; - /* number of *all* variables (columns) in corresponding MIP */ - int *pos; /* int pos[1+n]; */ - /* pos[0] is not used; - * pos[j] = v, 1 <= j <= n, means that vertex v corresponds to - * original binary variable x[j], and pos[j] = 0 means that the - * conflict graph has no such vertex */ - int *neg; /* int neg[1+n]; */ - /* neg[0] is not used; - * neg[j] = v, 1 <= j <= n, means that vertex v corresponds to - * complement of original binary variable x[j], and neg[j] = 0 - * means that the conflict graph has no such vertex */ - DMP *pool; - /* memory pool to allocate elements of the conflict graph */ - int nv_max; - /* maximal number of vertices in the conflict graph */ - int nv; - /* current number of vertices in the conflict graph */ - int *ref; /* int ref[1+nv_max]; */ - /* ref[v] = j, 1 <= v <= nv, means that vertex v corresponds - * either to original binary variable x[j] or to its complement, - * i.e. either pos[j] = v or neg[j] = v */ - CFGVLE **vptr; /* CFGVLE *vptr[1+nv_max]; */ - /* vptr[v], 1 <= v <= nv, is an initial pointer to the list of - * vertices adjacent to vertex v */ - CFGCLE **cptr; /* CFGCLE *cptr[1+nv_max]; */ - /* cptr[v], 1 <= v <= nv, is an initial pointer to the list of - * cliques that contain vertex v */ -}; - -struct CFGVLE -{ /* vertex list element */ - int v; - /* vertex number, 1 <= v <= nv */ - CFGVLE *next; - /* pointer to next vertex list element */ -}; - -struct CFGCLE -{ /* clique list element */ - CFGVLE *vptr; - /* initial pointer to the list of clique vertices */ - CFGCLE *next; - /* pointer to next clique list element */ -}; - -#define cfg_create_graph _glp_cfg_create_graph -CFG *cfg_create_graph(int n, int nv_max); -/* create conflict graph */ - -#define cfg_add_clique _glp_cfg_add_clique -void cfg_add_clique(CFG *G, int size, const int ind[]); -/* add clique to conflict graph */ - -#define cfg_get_adjacent _glp_cfg_get_adjacent -int cfg_get_adjacent(CFG *G, int v, int ind[]); -/* get vertices adjacent to specified vertex */ - -#define cfg_expand_clique _glp_cfg_expand_clique -int cfg_expand_clique(CFG *G, int c_len, int c_ind[]); -/* expand specified clique to maximal clique */ - -#define cfg_check_clique _glp_cfg_check_clique -void cfg_check_clique(CFG *G, int c_len, const int c_ind[]); -/* check clique in conflict graph */ - -#define cfg_delete_graph _glp_cfg_delete_graph -void cfg_delete_graph(CFG *G); -/* delete conflict graph */ - -#define cfg_build_graph _glp_cfg_build_graph -CFG *cfg_build_graph(void /* glp_prob */ *P); -/* build conflict graph */ - -#define cfg_find_clique _glp_cfg_find_clique -int cfg_find_clique(void /* glp_prob */ *P, CFG *G, int ind[], - double *sum); -/* find maximum weight clique in conflict graph */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/cglib/cfg1.c b/resources/3rdparty/glpk-4.53/src/cglib/cfg1.c deleted file mode 100644 index 02317bffb..000000000 --- a/resources/3rdparty/glpk-4.53/src/cglib/cfg1.c +++ /dev/null @@ -1,703 +0,0 @@ -/* cfg1.c (conflict graph) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "cfg.h" -#include "env.h" -#include "prob.h" -#include "wclique.h" -#include "wclique1.h" - -/*********************************************************************** -* cfg_build_graph - build conflict graph -* -* This routine builds the conflict graph. It analyzes the specified -* problem object to discover original and implied packing inequalities -* and adds corresponding cliques to the conflict graph. -* -* Packing inequality has the form: -* -* sum z[j] <= 1, (1) -* j in J -* -* where z[j] = x[j] or z[j] = 1 - x[j], x[j] is an original binary -* variable. Every packing inequality (1) is equivalent to a set of -* edge inequalities: -* -* z[i] + z[j] <= 1 for all i, j in J, i != j, (2) -* -* and since every edge inequality (2) defines an edge in the conflict -* graph, corresponding packing inequality (1) defines a clique. -* -* To discover packing inequalities the routine analyzes constraints -* of the specified MIP. To simplify the analysis each constraint is -* analyzed separately. The analysis is performed as follows. -* -* Let some original constraint be the following: -* -* L <= sum a[j] x[j] <= U. (3) -* -* To analyze it the routine analyzes two constraints of "not greater -* than" type: -* -* sum (-a[j]) x[j] <= -L, (4) -* -* sum (+a[j]) x[j] <= +U, (5) -* -* which are relaxations of the original constraint (3). (If, however, -* L = -oo, or U = +oo, corresponding constraint being redundant is not -* analyzed.) -* -* Let a constraint of "not greater than" type be the following: -* -* sum a[j] x[j] + sum a[j] x[j] <= b, (6) -* j in J j in J' -* -* where J is a subset of binary variables, J' is a subset of other -* (continues and non-binary integer) variables. The constraint (6) is -* is relaxed as follows, to eliminate non-binary variables: -* -* sum a[j] x[j] <= b - sum a[j] x[j] <= b', (7) -* j in J j in J' -* -* b' = sup(b - sum a[j] x[j]) = -* j in J' -* -* = b - inf(sum a[j] x[j]) = -* -* = b - sum inf(a[j] x[j]) = (8) -* -* = b - sum a[j] inf(x[j]) - sum a[j] sup(x[j]) = -* a[j]>0 a[j]<0 -* -* = b - sum a[j] l[j] - sum a[j] u[j], -* a[j]>0 a[j]<0 -* -* where l[j] and u[j] are, resp., lower and upper bounds of x[j]. -* -* Then the routine transforms the relaxed constraint containing only -* binary variables: -* -* sum a[j] x[j] <= b (9) -* -* to an equivalent 0-1 knapsack constraint as follows: -* -* sum a[j] x[j] + sum a[j] x[j] <= b ==> -* a[j]>0 a[j]<0 -* -* sum a[j] x[j] + sum a[j] (1 - x[j]) <= b ==> -* a[j]>0 a[j]<0 (10) -* -* sum (+a[j]) x[j] + sum (-a[j]) x[j] <= b + sum (-a[j]) ==> -* a[j]>0 a[j]<0 a[j]<0 -* -* sum a'[j] z[j] <= b', -* -* where a'[j] = |a[j]| > 0, and -* -* ( x[j] if a[j] > 0 -* z[j] = < -* ( 1 - x[j] if a[j] < 0 -* -* is a binary variable, which is either original binary variable x[j] -* or its complement. -* -* Finally, the routine analyzes the resultant 0-1 knapsack inequality: -* -* sum a[j] z[j] <= b, (11) -* j in J -* -* where all a[j] are positive, to discover clique inequalities (1), -* which are valid for (11) and therefore valid for (3). (It is assumed -* that the original MIP has been preprocessed, so it is not checked, -* for example, that b > 0 or that a[j] <= b.) -* -* In principle, to discover any edge inequalities valid for (11) it -* is sufficient to check whether a[i] + a[j] > b for all i, j in J, -* i < j. However, this way requires O(|J|^2) checks, so the routine -* analyses (11) in the following way, which is much more efficient in -* many practical cases. -* -* 1. Let a[p] and a[q] be two minimal coefficients: -* -* a[p] = min a[j], (12) -* -* a[q] = min a[j], j != p, (13) -* -* such that -* -* a[p] + a[q] > b. (14) -* -* This means that a[i] + a[j] > b for any i, j in J, i != j, so -* -* z[i] + z[j] <= 1 (15) -* -* are valid for (11) for any i, j in J, i != j. This case means that -* J define a clique in the conflict graph. -* -* 2. Otherwise, let a[p] and [q] be two maximal coefficients: -* -* a[p] = max a[j], (16) -* -* a[q] = max a[j], j != p, (17) -* -* such that -* -* a[p] + a[q] <= b. (18) -* -* This means that a[i] + a[j] <= b for any i, j in J, i != j, so in -* this case no valid edge inequalities for (11) exist. -* -* 3. Otherwise, let all a[j] be ordered by descending their values: -* -* a[1] >= a[2] >= ... >= a[p-1] >= a[p] >= a[p+1] >= ... (19) -* -* where p is such that -* -* a[p-1] + a[p] > b, (20) -* -* a[p] + a[p+1] <= b. (21) -* -* (May note that due to the former two cases in this case we always -* have 2 <= p <= |J|-1.) -* -* Since a[p] and a[p-1] are two minimal coefficients in the set -* J' = {1, ..., p}, J' define a clique in the conflict graph for the -* same reason as in the first case. Similarly, since a[p] and a[p+1] -* are two maximal coefficients in the set J" = {p, ..., |J|}, no edge -* inequalities exist for all i, j in J" for the same reason as in the -* second case. Thus, to discover other edge inequalities (15) valid -* for (11), the routine checks if a[i] + a[j] > b for all i in J', -* j in J", i != j. */ - -#define is_binary(j) \ - (P->col[j]->kind == GLP_IV && P->col[j]->type == GLP_DB && \ - P->col[j]->lb == 0.0 && P->col[j]->ub == 1.0) -/* check if x[j] is binary variable */ - -struct term { int ind; double val; }; -/* term a[j] * z[j] used to sort a[j]'s */ - -static int fcmp(const void *e1, const void *e2) -{ /* auxiliary routine called from qsort */ - const struct term *t1 = e1, *t2 = e2; - if (t1->val > t2->val) - return -1; - else if (t1->val < t2->val) - return +1; - else - return 0; -} - -static void analyze_ineq(glp_prob *P, CFG *G, int len, int ind[], - double val[], double rhs, struct term t[]) -{ /* analyze inequality constraint (6) */ - /* P is the original MIP - * G is the conflict graph to be built - * len is the number of terms in the constraint - * ind[1], ..., ind[len] are indices of variables x[j] - * val[1], ..., val[len] are constraint coefficients a[j] - * rhs is the right-hand side b - * t[1+len] is a working array */ - int j, k, kk, p, q, type, new_len; - /* eliminate non-binary variables; see (7) and (8) */ - new_len = 0; - for (k = 1; k <= len; k++) - { /* get index of variable x[j] */ - j = ind[k]; - if (is_binary(j)) - { /* x[j] remains in relaxed constraint */ - new_len++; - ind[new_len] = j; - val[new_len] = val[k]; - } - else if (val[k] > 0.0) - { /* eliminate non-binary x[j] in case a[j] > 0 */ - /* b := b - a[j] * l[j]; see (8) */ - type = P->col[j]->type; - if (type == GLP_FR || type == GLP_UP) - { /* x[j] has no lower bound */ - goto done; - } - rhs -= val[k] * P->col[j]->lb; - } - else /* val[j] < 0.0 */ - { /* eliminate non-binary x[j] in case a[j] < 0 */ - /* b := b - a[j] * u[j]; see (8) */ - type = P->col[j]->type; - if (type == GLP_FR || type == GLP_LO) - { /* x[j] has no upper bound */ - goto done; - } - rhs -= val[k] * P->col[j]->ub; - } - } - len = new_len; - /* now we have the constraint (9) */ - if (len <= 1) - { /* at least two terms are needed */ - goto done; - } - /* make all constraint coefficients positive; see (10) */ - for (k = 1; k <= len; k++) - { if (val[k] < 0.0) - { /* a[j] < 0; substitute x[j] = 1 - x'[j], where x'[j] is - * a complement binary variable */ - ind[k] = -ind[k]; - val[k] = -val[k]; - rhs += val[k]; - } - } - /* now we have 0-1 knapsack inequality (11) */ - /* increase the right-hand side a bit to avoid false checks due - * to rounding errors */ - rhs += 0.001 * (1.0 + fabs(rhs)); - /*** first case ***/ - /* find two minimal coefficients a[p] and a[q] */ - p = 0; - for (k = 1; k <= len; k++) - { if (p == 0 || val[p] > val[k]) - p = k; - } - q = 0; - for (k = 1; k <= len; k++) - { if (k != p && (q == 0 || val[q] > val[k])) - q = k; - } - xassert(p != 0 && q != 0 && p != q); - /* check condition (14) */ - if (val[p] + val[q] > rhs) - { /* all z[j] define a clique in the conflict graph */ - cfg_add_clique(G, len, ind); - goto done; - } - /*** second case ***/ - /* find two maximal coefficients a[p] and a[q] */ - p = 0; - for (k = 1; k <= len; k++) - { if (p == 0 || val[p] < val[k]) - p = k; - } - q = 0; - for (k = 1; k <= len; k++) - { if (k != p && (q == 0 || val[q] < val[k])) - q = k; - } - xassert(p != 0 && q != 0 && p != q); - /* check condition (18) */ - if (val[p] + val[q] <= rhs) - { /* no valid edge inequalities exist */ - goto done; - } - /*** third case ***/ - xassert(len >= 3); - /* sort terms in descending order of coefficient values */ - for (k = 1; k <= len; k++) - { t[k].ind = ind[k]; - t[k].val = val[k]; - } - qsort(&t[1], len, sizeof(struct term), fcmp); - for (k = 1; k <= len; k++) - { ind[k] = t[k].ind; - val[k] = t[k].val; - } - /* now a[1] >= a[2] >= ... >= a[len-1] >= a[len] */ - /* note that a[1] + a[2] > b and a[len-1] + a[len] <= b due two - * the former two cases */ - xassert(val[1] + val[2] > rhs); - xassert(val[len-1] + val[len] <= rhs); - /* find p according to conditions (20) and (21) */ - for (p = 2; p < len; p++) - { if (val[p] + val[p+1] <= rhs) - break; - } - xassert(p < len); - /* z[1], ..., z[p] define a clique in the conflict graph */ - cfg_add_clique(G, p, ind); - /* discover other edge inequalities */ - for (k = 1; k <= p; k++) - { for (kk = p; kk <= len; kk++) - { if (k != kk && val[k] + val[kk] > rhs) - { int iii[1+2]; - iii[1] = ind[k]; - iii[2] = ind[kk]; - cfg_add_clique(G, 2, iii); - } - } - } -done: return; -} - -CFG *cfg_build_graph(void *P_) -{ glp_prob *P = P_; - int m = P->m; - int n = P->n; - CFG *G; - int i, k, type, len, *ind; - double *val; - struct term *t; - /* create the conflict graph (number of its vertices cannot be - * greater than double number of binary variables) */ - G = cfg_create_graph(n, 2 * glp_get_num_bin(P)); - /* allocate working arrays */ - ind = talloc(1+n, int); - val = talloc(1+n, double); - t = talloc(1+n, struct term); - /* analyze constraints to discover edge inequalities */ - for (i = 1; i <= m; i++) - { type = P->row[i]->type; - if (type == GLP_LO || type == GLP_DB || type == GLP_FX) - { /* i-th row has lower bound */ - /* analyze inequality sum (-a[j]) * x[j] <= -lb */ - len = glp_get_mat_row(P, i, ind, val); - for (k = 1; k <= len; k++) - val[k] = -val[k]; - analyze_ineq(P, G, len, ind, val, -P->row[i]->lb, t); - } - if (type == GLP_UP || type == GLP_DB || type == GLP_FX) - { /* i-th row has upper bound */ - /* analyze inequality sum (+a[j]) * x[j] <= +ub */ - len = glp_get_mat_row(P, i, ind, val); - analyze_ineq(P, G, len, ind, val, +P->row[i]->ub, t); - } - } - /* free working arrays */ - tfree(ind); - tfree(val); - tfree(t); - return G; -} - -/*********************************************************************** -* cfg_find_clique - find maximum weight clique in conflict graph -* -* This routine finds a maximum weight clique in the conflict graph -* G = (V, E), where the weight of vertex v in V is the value of -* corresponding binary variable z (which is either an original binary -* variable or its complement) in the optimal solution to LP relaxation -* provided in the problem object. The goal is to find a clique in G, -* whose weight is greater than 1, in which case corresponding packing -* inequality is violated at the optimal point. -* -* On exit the routine stores vertex indices of the conflict graph -* included in the clique found to locations ind[1], ..., ind[len], and -* returns len, which is the clique size. The clique weight is stored -* in location pointed to by the parameter sum. If no clique has been -* found, the routine returns 0. -* -* Since the conflict graph may have a big number of vertices and be -* quite dense, the routine uses an induced subgraph G' = (V', E'), -* which is constructed as follows: -* -* 1. If the weight of some vertex v in V is zero (close to zero), it -* is not included in V'. Obviously, including in a clique -* zero-weight vertices does not change its weight, so if in G there -* exist a clique of a non-zero weight, in G' exists a clique of the -* same weight. This point is extremely important, because dropping -* out zero-weight vertices can be done without retrieving lists of -* adjacent vertices whose size may be very large. -* -* 2. Cumulative weight of vertex v in V is the sum of the weight of v -* and weights of all vertices in V adjacent to v. Obviously, if -* a clique includes a vertex v, the clique weight cannot be greater -* than the cumulative weight of v. Since we are interested only in -* cliques whose weight is greater than 1, vertices of V, whose -* cumulative weight is not greater than 1, are not included in V'. -* -* May note that in many practical cases the size of the induced -* subgraph G' is much less than the size of the original conflict -* graph G due to many binary variables, whose optimal values are zero -* or close to zero. For example, it may happen that |V| = 100,000 and -* |E| = 1e9 while |V'| = 50 and |E'| = 1000. */ - -struct csa -{ /* common storage area */ - glp_prob *P; - /* original MIP */ - CFG *G; - /* original conflict graph G = (V, E), |V| = nv */ - int *ind; /* int ind[1+nv]; */ - /* working array */ - /*--------------------------------------------------------------*/ - /* induced subgraph G' = (V', E') of original conflict graph */ - int nn; - /* number of vertices in V' */ - int *vtoi; /* int vtoi[1+nv]; */ - /* vtoi[v] = i, 1 <= v <= nv, means that vertex v in V is vertex - * i in V'; vtoi[v] = 0 means that vertex v is not included in - * the subgraph */ - int *itov; /* int itov[1+nv]; */ - /* itov[i] = v, 1 <= i <= nn, means that vertex i in V' is vertex - * v in V */ - double *wgt; /* double wgt[1+nv]; */ - /* wgt[i], 1 <= i <= nn, is a weight of vertex i in V', which is - * the value of corresponding binary variable in optimal solution - * to LP relaxation */ -}; - -static void build_subgraph(struct csa *csa) -{ /* build induced subgraph */ - glp_prob *P = csa->P; - int n = P->n; - CFG *G = csa->G; - int *ind = csa->ind; - int *pos = G->pos; - int *neg = G->neg; - int nv = G->nv; - int *ref = G->ref; - int *vtoi = csa->vtoi; - int *itov = csa->itov; - double *wgt = csa->wgt; - int j, k, v, w, nn, len; - double z, sum; - /* initially induced subgraph is empty */ - nn = 0; - /* walk thru vertices of original conflict graph */ - for (v = 1; v <= nv; v++) - { /* determine value of binary variable z[j] that corresponds to - * vertex v */ - j = ref[v]; - xassert(1 <= j && j <= n); - if (pos[j] == v) - { /* z[j] = x[j], where x[j] is original variable */ - z = P->col[j]->prim; - } - else if (neg[j] == v) - { /* z[j] = 1 - x[j], where x[j] is original variable */ - z = 1.0 - P->col[j]->prim; - } - else - xassert(v != v); - /* if z[j] is close to zero, do not include v in the induced - * subgraph */ - if (z < 0.001) - { vtoi[v] = 0; - continue; - } - /* calculate cumulative weight of vertex v */ - sum = z; - /* walk thru all vertices adjacent to v */ - len = cfg_get_adjacent(G, v, ind); - for (k = 1; k <= len; k++) - { /* there is an edge (v,w) in the conflict graph */ - w = ind[k]; - xassert(w != v); - /* add value of z[j] that corresponds to vertex w */ - j = ref[w]; - xassert(1 <= j && j <= n); - if (pos[j] == w) - sum += P->col[j]->prim; - else if (neg[j] == w) - sum += 1.0 - P->col[j]->prim; - else - xassert(w != w); - } - /* cumulative weight of vertex v is an upper bound of weight - * of any clique containing v; so if it not greater than 1, do - * not include v in the induced subgraph */ - if (sum < 1.010) - { vtoi[v] = 0; - continue; - } - /* include vertex v in the induced subgraph */ - nn++; - vtoi[v] = nn; - itov[nn] = v; - wgt[nn] = z; - } - /* induced subgraph has been built */ - csa->nn = nn; - return; -} - -static int sub_adjacent(struct csa *csa, int i, int adj[]) -{ /* retrieve vertices of induced subgraph adjacent to specified - * vertex */ - CFG *G = csa->G; - int nv = G->nv; - int *ind = csa->ind; - int nn = csa->nn; - int *vtoi = csa->vtoi; - int *itov = csa->itov; - int j, k, v, w, len, len1; - /* determine original vertex v corresponding to vertex i */ - xassert(1 <= i && i <= nn); - v = itov[i]; - /* retrieve vertices adjacent to vertex v in original graph */ - len1 = cfg_get_adjacent(G, v, ind); - /* keep only adjacent vertices which are in induced subgraph and - * change their numbers appropriately */ - len = 0; - for (k = 1; k <= len1; k++) - { /* there exists edge (v, w) in original graph */ - w = ind[k]; - xassert(1 <= w && w <= nv && w != v); - j = vtoi[w]; - if (j != 0) - { /* vertex w is vertex j in induced subgraph */ - xassert(1 <= j && j <= nn && j != i); - adj[++len] = j; - } - } - return len; -} - -static int find_clique(struct csa *csa, int c_ind[]) -{ /* find maximum weight clique in induced subgraph with exact - * Ostergard's algorithm */ - int nn = csa->nn; - double *wgt = csa->wgt; - int i, j, k, p, q, t, ne, nb, len, *iwt, *ind; - unsigned char *a; - xassert(nn >= 2); - /* allocate working array */ - ind = talloc(1+nn, int); - /* calculate the number of elements in lower triangle (without - * diagonal) of adjacency matrix of induced subgraph */ - ne = (nn * (nn - 1)) / 2; - /* calculate the number of bytes needed to store lower triangle - * of adjacency matrix */ - nb = (ne + (CHAR_BIT - 1)) / CHAR_BIT; - /* allocate lower triangle of adjacency matrix */ - a = talloc(nb, unsigned char); - /* fill lower triangle of adjacency matrix */ - memset(a, 0, nb); - for (p = 1; p <= nn; p++) - { /* retrieve vertices adjacent to vertex p */ - len = sub_adjacent(csa, p, ind); - for (k = 1; k <= len; k++) - { /* there exists edge (p, q) in induced subgraph */ - q = ind[k]; - xassert(1 <= q && q <= nn && q != p); - /* determine row and column indices of this edge in lower - * triangle of adjacency matrix */ - if (p > q) - i = p, j = q; - else /* p < q */ - i = q, j = p; - /* set bit a[i,j] to 1, i > j */ - t = ((i - 1) * (i - 2)) / 2 + (j - 1); - a[t / CHAR_BIT] |= - (unsigned char)(1 << ((CHAR_BIT - 1) - t % CHAR_BIT)); - } - } - /* scale vertex weights by 1000 and convert them to integers as - * required by Ostergard's algorithm */ - iwt = ind; - for (i = 1; i <= nn; i++) - { /* it is assumed that 0 <= wgt[i] <= 1 */ - t = (int)(1000.0 * wgt[i] + 0.5); - if (t < 0) - t = 0; - else if (t > 1000) - t = 1000; - iwt[i] = t; - } - /* find maximum weight clique */ - len = wclique(nn, iwt, a, c_ind); - /* free working arrays */ - tfree(ind); - tfree(a); - /* return clique size to calling routine */ - return len; -} - -static int func(void *info, int i, int ind[]) -{ /* auxiliary routine used by routine find_clique1 */ - struct csa *csa = info; - xassert(1 <= i && i <= csa->nn); - return sub_adjacent(csa, i, ind); -} - -static int find_clique1(struct csa *csa, int c_ind[]) -{ /* find maximum weight clique in induced subgraph with greedy - * heuristic */ - int nn = csa->nn; - double *wgt = csa->wgt; - int len; - xassert(nn >= 2); - len = wclique1(nn, wgt, func, csa, c_ind); - /* return clique size to calling routine */ - return len; -} - -int cfg_find_clique(void *P, CFG *G, int ind[], double *sum_) -{ int nv = G->nv; - struct csa csa; - int i, k, len; - double sum; - /* initialize common storage area */ - csa.P = P; - csa.G = G; - csa.ind = talloc(1+nv, int); - csa.nn = -1; - csa.vtoi = talloc(1+nv, int); - csa.itov = talloc(1+nv, int); - csa.wgt = talloc(1+nv, double); - /* build induced subgraph */ - build_subgraph(&csa); -#ifdef GLP_DEBUG - xprintf("nn = %d\n", csa.nn); -#endif - /* if subgraph has less than two vertices, do nothing */ - if (csa.nn < 2) - { len = 0; - sum = 0.0; - goto skip; - } - /* find maximum weight clique in induced subgraph */ -#if 1 /* FIXME */ - if (csa.nn <= 50) -#endif - { /* induced subgraph is small; use exact algorithm */ - len = find_clique(&csa, ind); - } - else - { /* induced subgraph is large; use greedy heuristic */ - len = find_clique1(&csa, ind); - } - /* do not report clique, if it has less than two vertices */ - if (len < 2) - { len = 0; - sum = 0.0; - goto skip; - } - /* convert indices of clique vertices from induced subgraph to - * original conflict graph and compute clique weight */ - sum = 0.0; - for (k = 1; k <= len; k++) - { i = ind[k]; - xassert(1 <= i && i <= csa.nn); - sum += csa.wgt[i]; - ind[k] = csa.itov[i]; - } -skip: /* free working arrays */ - tfree(csa.ind); - tfree(csa.vtoi); - tfree(csa.itov); - tfree(csa.wgt); - /* return to calling routine */ - *sum_ = sum; - return len; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/colamd/COPYING b/resources/3rdparty/glpk-4.53/src/colamd/COPYING deleted file mode 100644 index 84bba36d0..000000000 --- a/resources/3rdparty/glpk-4.53/src/colamd/COPYING +++ /dev/null @@ -1,502 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/resources/3rdparty/glpk-4.53/src/colamd/README b/resources/3rdparty/glpk-4.53/src/colamd/README deleted file mode 100644 index a365059fe..000000000 --- a/resources/3rdparty/glpk-4.53/src/colamd/README +++ /dev/null @@ -1,98 +0,0 @@ -NOTE: Files in this subdirectory are NOT part of the GLPK package, but - are used with GLPK. - - The original code was modified according to GLPK requirements by - Andrew Makhorin . -************************************************************************ -COLAMD/SYMAMD Version 2.7, Copyright (C) 1998-2007, Timothy A. Davis, -All Rights Reserved. - -Description: - - colamd: an approximate minimum degree column ordering algorithm, - for LU factorization of symmetric or unsymmetric matrices, - QR factorization, least squares, interior point methods for - linear programming problems, and other related problems. - - symamd: an approximate minimum degree ordering algorithm for - Cholesky factorization of symmetric matrices. - -Purpose: - - Colamd computes a permutation Q such that the Cholesky factorization - of (AQ)'(AQ) has less fill-in and requires fewer floating point - operations than A'A. This also provides a good ordering for sparse - partial pivoting methods, P(AQ) = LU, where Q is computed prior to - numerical factorization, and P is computed during numerical - factorization via conventional partial pivoting with row - interchanges. Colamd is the column ordering method used in SuperLU, - part of the ScaLAPACK library. It is also available as built-in - function in MATLAB Version 6, available from MathWorks, Inc. - (http://www.mathworks.com). This routine can be used in place of - colmmd in MATLAB. - - Symamd computes a permutation P of a symmetric matrix A such that - the Cholesky factorization of PAP' has less fill-in and requires - fewer floating point operations than A. Symamd constructs a matrix - M such that M'M has the same nonzero pattern of A, and then orders - the columns of M using colmmd. The column ordering of M is then - returned as the row and column ordering P of A. - -Authors: - - The authors of the code itself are Stefan I. Larimore and Timothy A. - Davis (davis at cise.ufl.edu), University of Florida. The algorithm - was developed in collaboration with John Gilbert, Xerox PARC, and - Esmond Ng, Oak Ridge National Laboratory. - -Acknowledgements: - - This work was supported by the National Science Foundation, under - grants DMS-9504974 and DMS-9803599. - -License: - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License - as published by the Free Software Foundation; either version 2.1 of - the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 - USA. - - Permission is hereby granted to use or copy this program under the - terms of the GNU LGPL, provided that the Copyright, this License, - and the Availability of the original version is retained on all - copies. User documentation of any code that uses this code or any - modified version of this code must cite the Copyright, this License, - the Availability note, and "Used by permission." Permission to - modify the code and to distribute modified code is granted, provided - the Copyright, this License, and the Availability note are retained, - and a notice that the code was modified is included. - - COLAMD is also available under alternate licenses, contact T. Davis - for details. - -Availability: - - The colamd/symamd library is available at: - - http://www.cise.ufl.edu/research/sparse/colamd/ - -References: - - T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, An approximate - column minimum degree ordering algorithm, ACM Transactions on - Mathematical Software, vol. 30, no. 3., pp. 353-376, 2004. - - T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, Algorithm 836: - COLAMD, an approximate column minimum degree ordering algorithm, ACM - Transactions on Mathematical Software, vol. 30, no. 3., pp. 377-380, - 2004. diff --git a/resources/3rdparty/glpk-4.53/src/colamd/colamd.c b/resources/3rdparty/glpk-4.53/src/colamd/colamd.c deleted file mode 100644 index 86ddd6b74..000000000 --- a/resources/3rdparty/glpk-4.53/src/colamd/colamd.c +++ /dev/null @@ -1,3622 +0,0 @@ -/* ========================================================================== */ -/* === colamd/symamd - a sparse matrix column ordering algorithm ============ */ -/* ========================================================================== */ - -/* COLAMD / SYMAMD - - colamd: an approximate minimum degree column ordering algorithm, - for LU factorization of symmetric or unsymmetric matrices, - QR factorization, least squares, interior point methods for - linear programming problems, and other related problems. - - symamd: an approximate minimum degree ordering algorithm for Cholesky - factorization of symmetric matrices. - - Purpose: - - Colamd computes a permutation Q such that the Cholesky factorization of - (AQ)'(AQ) has less fill-in and requires fewer floating point operations - than A'A. This also provides a good ordering for sparse partial - pivoting methods, P(AQ) = LU, where Q is computed prior to numerical - factorization, and P is computed during numerical factorization via - conventional partial pivoting with row interchanges. Colamd is the - column ordering method used in SuperLU, part of the ScaLAPACK library. - It is also available as built-in function in MATLAB Version 6, - available from MathWorks, Inc. (http://www.mathworks.com). This - routine can be used in place of colmmd in MATLAB. - - Symamd computes a permutation P of a symmetric matrix A such that the - Cholesky factorization of PAP' has less fill-in and requires fewer - floating point operations than A. Symamd constructs a matrix M such - that M'M has the same nonzero pattern of A, and then orders the columns - of M using colmmd. The column ordering of M is then returned as the - row and column ordering P of A. - - Authors: - - The authors of the code itself are Stefan I. Larimore and Timothy A. - Davis (davis at cise.ufl.edu), University of Florida. The algorithm was - developed in collaboration with John Gilbert, Xerox PARC, and Esmond - Ng, Oak Ridge National Laboratory. - - Acknowledgements: - - This work was supported by the National Science Foundation, under - grants DMS-9504974 and DMS-9803599. - - Copyright and License: - - Copyright (c) 1998-2007, Timothy A. Davis, All Rights Reserved. - COLAMD is also available under alternate licenses, contact T. Davis - for details. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 - USA - - Permission is hereby granted to use or copy this program under the - terms of the GNU LGPL, provided that the Copyright, this License, - and the Availability of the original version is retained on all copies. - User documentation of any code that uses this code or any modified - version of this code must cite the Copyright, this License, the - Availability note, and "Used by permission." Permission to modify - the code and to distribute modified code is granted, provided the - Copyright, this License, and the Availability note are retained, - and a notice that the code was modified is included. - - Availability: - - The colamd/symamd library is available at - - http://www.cise.ufl.edu/research/sparse/colamd/ - - This is the http://www.cise.ufl.edu/research/sparse/colamd/colamd.c - file. It requires the colamd.h file. It is required by the colamdmex.c - and symamdmex.c files, for the MATLAB interface to colamd and symamd. - Appears as ACM Algorithm 836. - - See the ChangeLog file for changes since Version 1.0. - - References: - - T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, An approximate column - minimum degree ordering algorithm, ACM Transactions on Mathematical - Software, vol. 30, no. 3., pp. 353-376, 2004. - - T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, Algorithm 836: COLAMD, - an approximate column minimum degree ordering algorithm, ACM - Transactions on Mathematical Software, vol. 30, no. 3., pp. 377-380, - 2004. - -*/ - -/* ========================================================================== */ -/* === Description of user-callable routines ================================ */ -/* ========================================================================== */ - -/* COLAMD includes both int and UF_long versions of all its routines. The - * description below is for the int version. For UF_long, all int arguments - * become UF_long. UF_long is normally defined as long, except for WIN64. - - ---------------------------------------------------------------------------- - colamd_recommended: - ---------------------------------------------------------------------------- - - C syntax: - - #include "colamd.h" - size_t colamd_recommended (int nnz, int n_row, int n_col) ; - size_t colamd_l_recommended (UF_long nnz, UF_long n_row, - UF_long n_col) ; - - Purpose: - - Returns recommended value of Alen for use by colamd. Returns 0 - if any input argument is negative. The use of this routine - is optional. Not needed for symamd, which dynamically allocates - its own memory. - - Note that in v2.4 and earlier, these routines returned int or long. - They now return a value of type size_t. - - Arguments (all input arguments): - - int nnz ; Number of nonzeros in the matrix A. This must - be the same value as p [n_col] in the call to - colamd - otherwise you will get a wrong value - of the recommended memory to use. - - int n_row ; Number of rows in the matrix A. - - int n_col ; Number of columns in the matrix A. - - ---------------------------------------------------------------------------- - colamd_set_defaults: - ---------------------------------------------------------------------------- - - C syntax: - - #include "colamd.h" - colamd_set_defaults (double knobs [COLAMD_KNOBS]) ; - colamd_l_set_defaults (double knobs [COLAMD_KNOBS]) ; - - Purpose: - - Sets the default parameters. The use of this routine is optional. - - Arguments: - - double knobs [COLAMD_KNOBS] ; Output only. - - NOTE: the meaning of the dense row/col knobs has changed in v2.4 - - knobs [0] and knobs [1] control dense row and col detection: - - Colamd: rows with more than - max (16, knobs [COLAMD_DENSE_ROW] * sqrt (n_col)) - entries are removed prior to ordering. Columns with more than - max (16, knobs [COLAMD_DENSE_COL] * sqrt (MIN (n_row,n_col))) - entries are removed prior to - ordering, and placed last in the output column ordering. - - Symamd: uses only knobs [COLAMD_DENSE_ROW], which is knobs [0]. - Rows and columns with more than - max (16, knobs [COLAMD_DENSE_ROW] * sqrt (n)) - entries are removed prior to ordering, and placed last in the - output ordering. - - COLAMD_DENSE_ROW and COLAMD_DENSE_COL are defined as 0 and 1, - respectively, in colamd.h. Default values of these two knobs - are both 10. Currently, only knobs [0] and knobs [1] are - used, but future versions may use more knobs. If so, they will - be properly set to their defaults by the future version of - colamd_set_defaults, so that the code that calls colamd will - not need to change, assuming that you either use - colamd_set_defaults, or pass a (double *) NULL pointer as the - knobs array to colamd or symamd. - - knobs [2]: aggressive absorption - - knobs [COLAMD_AGGRESSIVE] controls whether or not to do - aggressive absorption during the ordering. Default is TRUE. - - - ---------------------------------------------------------------------------- - colamd: - ---------------------------------------------------------------------------- - - C syntax: - - #include "colamd.h" - int colamd (int n_row, int n_col, int Alen, int *A, int *p, - double knobs [COLAMD_KNOBS], int stats [COLAMD_STATS]) ; - UF_long colamd_l (UF_long n_row, UF_long n_col, UF_long Alen, - UF_long *A, UF_long *p, double knobs [COLAMD_KNOBS], - UF_long stats [COLAMD_STATS]) ; - - Purpose: - - Computes a column ordering (Q) of A such that P(AQ)=LU or - (AQ)'AQ=LL' have less fill-in and require fewer floating point - operations than factorizing the unpermuted matrix A or A'A, - respectively. - - Returns: - - TRUE (1) if successful, FALSE (0) otherwise. - - Arguments: - - int n_row ; Input argument. - - Number of rows in the matrix A. - Restriction: n_row >= 0. - Colamd returns FALSE if n_row is negative. - - int n_col ; Input argument. - - Number of columns in the matrix A. - Restriction: n_col >= 0. - Colamd returns FALSE if n_col is negative. - - int Alen ; Input argument. - - Restriction (see note): - Alen >= 2*nnz + 6*(n_col+1) + 4*(n_row+1) + n_col - Colamd returns FALSE if these conditions are not met. - - Note: this restriction makes an modest assumption regarding - the size of the two typedef's structures in colamd.h. - We do, however, guarantee that - - Alen >= colamd_recommended (nnz, n_row, n_col) - - will be sufficient. Note: the macro version does not check - for integer overflow, and thus is not recommended. Use - the colamd_recommended routine instead. - - int A [Alen] ; Input argument, undefined on output. - - A is an integer array of size Alen. Alen must be at least as - large as the bare minimum value given above, but this is very - low, and can result in excessive run time. For best - performance, we recommend that Alen be greater than or equal to - colamd_recommended (nnz, n_row, n_col), which adds - nnz/5 to the bare minimum value given above. - - On input, the row indices of the entries in column c of the - matrix are held in A [(p [c]) ... (p [c+1]-1)]. The row indices - in a given column c need not be in ascending order, and - duplicate row indices may be be present. However, colamd will - work a little faster if both of these conditions are met - (Colamd puts the matrix into this format, if it finds that the - the conditions are not met). - - The matrix is 0-based. That is, rows are in the range 0 to - n_row-1, and columns are in the range 0 to n_col-1. Colamd - returns FALSE if any row index is out of range. - - The contents of A are modified during ordering, and are - undefined on output. - - int p [n_col+1] ; Both input and output argument. - - p is an integer array of size n_col+1. On input, it holds the - "pointers" for the column form of the matrix A. Column c of - the matrix A is held in A [(p [c]) ... (p [c+1]-1)]. The first - entry, p [0], must be zero, and p [c] <= p [c+1] must hold - for all c in the range 0 to n_col-1. The value p [n_col] is - thus the total number of entries in the pattern of the matrix A. - Colamd returns FALSE if these conditions are not met. - - On output, if colamd returns TRUE, the array p holds the column - permutation (Q, for P(AQ)=LU or (AQ)'(AQ)=LL'), where p [0] is - the first column index in the new ordering, and p [n_col-1] is - the last. That is, p [k] = j means that column j of A is the - kth pivot column, in AQ, where k is in the range 0 to n_col-1 - (p [0] = j means that column j of A is the first column in AQ). - - If colamd returns FALSE, then no permutation is returned, and - p is undefined on output. - - double knobs [COLAMD_KNOBS] ; Input argument. - - See colamd_set_defaults for a description. - - int stats [COLAMD_STATS] ; Output argument. - - Statistics on the ordering, and error status. - See colamd.h for related definitions. - Colamd returns FALSE if stats is not present. - - stats [0]: number of dense or empty rows ignored. - - stats [1]: number of dense or empty columns ignored (and - ordered last in the output permutation p) - Note that a row can become "empty" if it - contains only "dense" and/or "empty" columns, - and similarly a column can become "empty" if it - only contains "dense" and/or "empty" rows. - - stats [2]: number of garbage collections performed. - This can be excessively high if Alen is close - to the minimum required value. - - stats [3]: status code. < 0 is an error code. - > 1 is a warning or notice. - - 0 OK. Each column of the input matrix contained - row indices in increasing order, with no - duplicates. - - 1 OK, but columns of input matrix were jumbled - (unsorted columns or duplicate entries). Colamd - had to do some extra work to sort the matrix - first and remove duplicate entries, but it - still was able to return a valid permutation - (return value of colamd was TRUE). - - stats [4]: highest numbered column that - is unsorted or has duplicate - entries. - stats [5]: last seen duplicate or - unsorted row index. - stats [6]: number of duplicate or - unsorted row indices. - - -1 A is a null pointer - - -2 p is a null pointer - - -3 n_row is negative - - stats [4]: n_row - - -4 n_col is negative - - stats [4]: n_col - - -5 number of nonzeros in matrix is negative - - stats [4]: number of nonzeros, p [n_col] - - -6 p [0] is nonzero - - stats [4]: p [0] - - -7 A is too small - - stats [4]: required size - stats [5]: actual size (Alen) - - -8 a column has a negative number of entries - - stats [4]: column with < 0 entries - stats [5]: number of entries in col - - -9 a row index is out of bounds - - stats [4]: column with bad row index - stats [5]: bad row index - stats [6]: n_row, # of rows of matrx - - -10 (unused; see symamd.c) - - -999 (unused; see symamd.c) - - Future versions may return more statistics in the stats array. - - Example: - - See http://www.cise.ufl.edu/research/sparse/colamd/example.c - for a complete example. - - To order the columns of a 5-by-4 matrix with 11 nonzero entries in - the following nonzero pattern - - x 0 x 0 - x 0 x x - 0 x x 0 - 0 0 x x - x x 0 0 - - with default knobs and no output statistics, do the following: - - #include "colamd.h" - #define ALEN 100 - int A [ALEN] = {0, 1, 4, 2, 4, 0, 1, 2, 3, 1, 3} ; - int p [ ] = {0, 3, 5, 9, 11} ; - int stats [COLAMD_STATS] ; - colamd (5, 4, ALEN, A, p, (double *) NULL, stats) ; - - The permutation is returned in the array p, and A is destroyed. - - ---------------------------------------------------------------------------- - symamd: - ---------------------------------------------------------------------------- - - C syntax: - - #include "colamd.h" - int symamd (int n, int *A, int *p, int *perm, - double knobs [COLAMD_KNOBS], int stats [COLAMD_STATS], - void (*allocate) (size_t, size_t), void (*release) (void *)) ; - UF_long symamd_l (UF_long n, UF_long *A, UF_long *p, UF_long *perm, - double knobs [COLAMD_KNOBS], UF_long stats [COLAMD_STATS], - void (*allocate) (size_t, size_t), void (*release) (void *)) ; - - Purpose: - - The symamd routine computes an ordering P of a symmetric sparse - matrix A such that the Cholesky factorization PAP' = LL' remains - sparse. It is based on a column ordering of a matrix M constructed - so that the nonzero pattern of M'M is the same as A. The matrix A - is assumed to be symmetric; only the strictly lower triangular part - is accessed. You must pass your selected memory allocator (usually - calloc/free or mxCalloc/mxFree) to symamd, for it to allocate - memory for the temporary matrix M. - - Returns: - - TRUE (1) if successful, FALSE (0) otherwise. - - Arguments: - - int n ; Input argument. - - Number of rows and columns in the symmetrix matrix A. - Restriction: n >= 0. - Symamd returns FALSE if n is negative. - - int A [nnz] ; Input argument. - - A is an integer array of size nnz, where nnz = p [n]. - - The row indices of the entries in column c of the matrix are - held in A [(p [c]) ... (p [c+1]-1)]. The row indices in a - given column c need not be in ascending order, and duplicate - row indices may be present. However, symamd will run faster - if the columns are in sorted order with no duplicate entries. - - The matrix is 0-based. That is, rows are in the range 0 to - n-1, and columns are in the range 0 to n-1. Symamd - returns FALSE if any row index is out of range. - - The contents of A are not modified. - - int p [n+1] ; Input argument. - - p is an integer array of size n+1. On input, it holds the - "pointers" for the column form of the matrix A. Column c of - the matrix A is held in A [(p [c]) ... (p [c+1]-1)]. The first - entry, p [0], must be zero, and p [c] <= p [c+1] must hold - for all c in the range 0 to n-1. The value p [n] is - thus the total number of entries in the pattern of the matrix A. - Symamd returns FALSE if these conditions are not met. - - The contents of p are not modified. - - int perm [n+1] ; Output argument. - - On output, if symamd returns TRUE, the array perm holds the - permutation P, where perm [0] is the first index in the new - ordering, and perm [n-1] is the last. That is, perm [k] = j - means that row and column j of A is the kth column in PAP', - where k is in the range 0 to n-1 (perm [0] = j means - that row and column j of A are the first row and column in - PAP'). The array is used as a workspace during the ordering, - which is why it must be of length n+1, not just n. - - double knobs [COLAMD_KNOBS] ; Input argument. - - See colamd_set_defaults for a description. - - int stats [COLAMD_STATS] ; Output argument. - - Statistics on the ordering, and error status. - See colamd.h for related definitions. - Symamd returns FALSE if stats is not present. - - stats [0]: number of dense or empty row and columns ignored - (and ordered last in the output permutation - perm). Note that a row/column can become - "empty" if it contains only "dense" and/or - "empty" columns/rows. - - stats [1]: (same as stats [0]) - - stats [2]: number of garbage collections performed. - - stats [3]: status code. < 0 is an error code. - > 1 is a warning or notice. - - 0 OK. Each column of the input matrix contained - row indices in increasing order, with no - duplicates. - - 1 OK, but columns of input matrix were jumbled - (unsorted columns or duplicate entries). Symamd - had to do some extra work to sort the matrix - first and remove duplicate entries, but it - still was able to return a valid permutation - (return value of symamd was TRUE). - - stats [4]: highest numbered column that - is unsorted or has duplicate - entries. - stats [5]: last seen duplicate or - unsorted row index. - stats [6]: number of duplicate or - unsorted row indices. - - -1 A is a null pointer - - -2 p is a null pointer - - -3 (unused, see colamd.c) - - -4 n is negative - - stats [4]: n - - -5 number of nonzeros in matrix is negative - - stats [4]: # of nonzeros (p [n]). - - -6 p [0] is nonzero - - stats [4]: p [0] - - -7 (unused) - - -8 a column has a negative number of entries - - stats [4]: column with < 0 entries - stats [5]: number of entries in col - - -9 a row index is out of bounds - - stats [4]: column with bad row index - stats [5]: bad row index - stats [6]: n_row, # of rows of matrx - - -10 out of memory (unable to allocate temporary - workspace for M or count arrays using the - "allocate" routine passed into symamd). - - Future versions may return more statistics in the stats array. - - void * (*allocate) (size_t, size_t) - - A pointer to a function providing memory allocation. The - allocated memory must be returned initialized to zero. For a - C application, this argument should normally be a pointer to - calloc. For a MATLAB mexFunction, the routine mxCalloc is - passed instead. - - void (*release) (size_t, size_t) - - A pointer to a function that frees memory allocated by the - memory allocation routine above. For a C application, this - argument should normally be a pointer to free. For a MATLAB - mexFunction, the routine mxFree is passed instead. - - - ---------------------------------------------------------------------------- - colamd_report: - ---------------------------------------------------------------------------- - - C syntax: - - #include "colamd.h" - colamd_report (int stats [COLAMD_STATS]) ; - colamd_l_report (UF_long stats [COLAMD_STATS]) ; - - Purpose: - - Prints the error status and statistics recorded in the stats - array on the standard error output (for a standard C routine) - or on the MATLAB output (for a mexFunction). - - Arguments: - - int stats [COLAMD_STATS] ; Input only. Statistics from colamd. - - - ---------------------------------------------------------------------------- - symamd_report: - ---------------------------------------------------------------------------- - - C syntax: - - #include "colamd.h" - symamd_report (int stats [COLAMD_STATS]) ; - symamd_l_report (UF_long stats [COLAMD_STATS]) ; - - Purpose: - - Prints the error status and statistics recorded in the stats - array on the standard error output (for a standard C routine) - or on the MATLAB output (for a mexFunction). - - Arguments: - - int stats [COLAMD_STATS] ; Input only. Statistics from symamd. - - -*/ - -/* ========================================================================== */ -/* === Scaffolding code definitions ======================================== */ -/* ========================================================================== */ - -/* Ensure that debugging is turned off: */ -#ifndef NDEBUG -#define NDEBUG -#endif - -/* turn on debugging by uncommenting the following line - #undef NDEBUG -*/ - -/* - Our "scaffolding code" philosophy: In our opinion, well-written library - code should keep its "debugging" code, and just normally have it turned off - by the compiler so as not to interfere with performance. This serves - several purposes: - - (1) assertions act as comments to the reader, telling you what the code - expects at that point. All assertions will always be true (unless - there really is a bug, of course). - - (2) leaving in the scaffolding code assists anyone who would like to modify - the code, or understand the algorithm (by reading the debugging output, - one can get a glimpse into what the code is doing). - - (3) (gasp!) for actually finding bugs. This code has been heavily tested - and "should" be fully functional and bug-free ... but you never know... - - The code will become outrageously slow when debugging is - enabled. To control the level of debugging output, set an environment - variable D to 0 (little), 1 (some), 2, 3, or 4 (lots). When debugging, - you should see the following message on the standard output: - - colamd: debug version, D = 1 (THIS WILL BE SLOW!) - - or a similar message for symamd. If you don't, then debugging has not - been enabled. - -*/ - -/* ========================================================================== */ -/* === Include files ======================================================== */ -/* ========================================================================== */ - -#include "colamd.h" - -#if 0 /* by mao */ -#include -#include - -#ifdef MATLAB_MEX_FILE -#include "mex.h" -#include "matrix.h" -#endif /* MATLAB_MEX_FILE */ - -#if !defined (NPRINT) || !defined (NDEBUG) -#include -#endif - -#ifndef NULL -#define NULL ((void *) 0) -#endif -#endif - -/* ========================================================================== */ -/* === int or UF_long ======================================================= */ -/* ========================================================================== */ - -#if 0 /* by mao */ -/* define UF_long */ -#include "UFconfig.h" -#endif - -#ifdef DLONG - -#define Int UF_long -#define ID UF_long_id -#define Int_MAX UF_long_max - -#define COLAMD_recommended colamd_l_recommended -#define COLAMD_set_defaults colamd_l_set_defaults -#define COLAMD_MAIN colamd_l -#define SYMAMD_MAIN symamd_l -#define COLAMD_report colamd_l_report -#define SYMAMD_report symamd_l_report - -#else - -#define Int int -#define ID "%d" -#define Int_MAX INT_MAX - -#define COLAMD_recommended colamd_recommended -#define COLAMD_set_defaults colamd_set_defaults -#define COLAMD_MAIN colamd -#define SYMAMD_MAIN symamd -#define COLAMD_report colamd_report -#define SYMAMD_report symamd_report - -#endif - -/* ========================================================================== */ -/* === Row and Column structures ============================================ */ -/* ========================================================================== */ - -/* User code that makes use of the colamd/symamd routines need not directly */ -/* reference these structures. They are used only for colamd_recommended. */ - -typedef struct Colamd_Col_struct -{ - Int start ; /* index for A of first row in this column, or DEAD */ - /* if column is dead */ - Int length ; /* number of rows in this column */ - union - { - Int thickness ; /* number of original columns represented by this */ - /* col, if the column is alive */ - Int parent ; /* parent in parent tree super-column structure, if */ - /* the column is dead */ - } shared1 ; - union - { - Int score ; /* the score used to maintain heap, if col is alive */ - Int order ; /* pivot ordering of this column, if col is dead */ - } shared2 ; - union - { - Int headhash ; /* head of a hash bucket, if col is at the head of */ - /* a degree list */ - Int hash ; /* hash value, if col is not in a degree list */ - Int prev ; /* previous column in degree list, if col is in a */ - /* degree list (but not at the head of a degree list) */ - } shared3 ; - union - { - Int degree_next ; /* next column, if col is in a degree list */ - Int hash_next ; /* next column, if col is in a hash list */ - } shared4 ; - -} Colamd_Col ; - -typedef struct Colamd_Row_struct -{ - Int start ; /* index for A of first col in this row */ - Int length ; /* number of principal columns in this row */ - union - { - Int degree ; /* number of principal & non-principal columns in row */ - Int p ; /* used as a row pointer in init_rows_cols () */ - } shared1 ; - union - { - Int mark ; /* for computing set differences and marking dead rows*/ - Int first_column ;/* first column in row (used in garbage collection) */ - } shared2 ; - -} Colamd_Row ; - -/* ========================================================================== */ -/* === Definitions ========================================================== */ -/* ========================================================================== */ - -/* Routines are either PUBLIC (user-callable) or PRIVATE (not user-callable) */ -#define PUBLIC -#define PRIVATE static - -#define DENSE_DEGREE(alpha,n) \ - ((Int) MAX (16.0, (alpha) * sqrt ((double) (n)))) - -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) - -#define ONES_COMPLEMENT(r) (-(r)-1) - -/* -------------------------------------------------------------------------- */ -/* Change for version 2.1: define TRUE and FALSE only if not yet defined */ -/* -------------------------------------------------------------------------- */ - -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -/* -------------------------------------------------------------------------- */ - -#define EMPTY (-1) - -/* Row and column status */ -#define ALIVE (0) -#define DEAD (-1) - -/* Column status */ -#define DEAD_PRINCIPAL (-1) -#define DEAD_NON_PRINCIPAL (-2) - -/* Macros for row and column status update and checking. */ -#define ROW_IS_DEAD(r) ROW_IS_MARKED_DEAD (Row[r].shared2.mark) -#define ROW_IS_MARKED_DEAD(row_mark) (row_mark < ALIVE) -#define ROW_IS_ALIVE(r) (Row [r].shared2.mark >= ALIVE) -#define COL_IS_DEAD(c) (Col [c].start < ALIVE) -#define COL_IS_ALIVE(c) (Col [c].start >= ALIVE) -#define COL_IS_DEAD_PRINCIPAL(c) (Col [c].start == DEAD_PRINCIPAL) -#define KILL_ROW(r) { Row [r].shared2.mark = DEAD ; } -#define KILL_PRINCIPAL_COL(c) { Col [c].start = DEAD_PRINCIPAL ; } -#define KILL_NON_PRINCIPAL_COL(c) { Col [c].start = DEAD_NON_PRINCIPAL ; } - -/* ========================================================================== */ -/* === Colamd reporting mechanism =========================================== */ -/* ========================================================================== */ - -#if defined (MATLAB_MEX_FILE) || defined (MATHWORKS) -/* In MATLAB, matrices are 1-based to the user, but 0-based internally */ -#define INDEX(i) ((i)+1) -#else -/* In C, matrices are 0-based and indices are reported as such in *_report */ -#define INDEX(i) (i) -#endif - -/* All output goes through the PRINTF macro. */ -#define PRINTF(params) { if (colamd_printf != NULL) (void) colamd_printf params ; } - -/* ========================================================================== */ -/* === Prototypes of PRIVATE routines ======================================= */ -/* ========================================================================== */ - -PRIVATE Int init_rows_cols -( - Int n_row, - Int n_col, - Colamd_Row Row [], - Colamd_Col Col [], - Int A [], - Int p [], - Int stats [COLAMD_STATS] -) ; - -PRIVATE void init_scoring -( - Int n_row, - Int n_col, - Colamd_Row Row [], - Colamd_Col Col [], - Int A [], - Int head [], - double knobs [COLAMD_KNOBS], - Int *p_n_row2, - Int *p_n_col2, - Int *p_max_deg -) ; - -PRIVATE Int find_ordering -( - Int n_row, - Int n_col, - Int Alen, - Colamd_Row Row [], - Colamd_Col Col [], - Int A [], - Int head [], - Int n_col2, - Int max_deg, - Int pfree, - Int aggressive -) ; - -PRIVATE void order_children -( - Int n_col, - Colamd_Col Col [], - Int p [] -) ; - -PRIVATE void detect_super_cols -( - -#ifndef NDEBUG - Int n_col, - Colamd_Row Row [], -#endif /* NDEBUG */ - - Colamd_Col Col [], - Int A [], - Int head [], - Int row_start, - Int row_length -) ; - -PRIVATE Int garbage_collection -( - Int n_row, - Int n_col, - Colamd_Row Row [], - Colamd_Col Col [], - Int A [], - Int *pfree -) ; - -PRIVATE Int clear_mark -( - Int tag_mark, - Int max_mark, - Int n_row, - Colamd_Row Row [] -) ; - -PRIVATE void print_report -( - char *method, - Int stats [COLAMD_STATS] -) ; - -/* ========================================================================== */ -/* === Debugging prototypes and definitions ================================= */ -/* ========================================================================== */ - -#ifndef NDEBUG - -#if 0 /* by mao */ -#include -#endif - -/* colamd_debug is the *ONLY* global variable, and is only */ -/* present when debugging */ - -PRIVATE Int colamd_debug = 0 ; /* debug print level */ - -#define DEBUG0(params) { PRINTF (params) ; } -#define DEBUG1(params) { if (colamd_debug >= 1) PRINTF (params) ; } -#define DEBUG2(params) { if (colamd_debug >= 2) PRINTF (params) ; } -#define DEBUG3(params) { if (colamd_debug >= 3) PRINTF (params) ; } -#define DEBUG4(params) { if (colamd_debug >= 4) PRINTF (params) ; } - -#if 0 /* by mao */ -#ifdef MATLAB_MEX_FILE -#define ASSERT(expression) (mxAssert ((expression), "")) -#else -#define ASSERT(expression) (assert (expression)) -#endif /* MATLAB_MEX_FILE */ -#else -#define ASSERT xassert -#endif - -PRIVATE void colamd_get_debug /* gets the debug print level from getenv */ -( - char *method -) ; - -PRIVATE void debug_deg_lists -( - Int n_row, - Int n_col, - Colamd_Row Row [], - Colamd_Col Col [], - Int head [], - Int min_score, - Int should, - Int max_deg -) ; - -PRIVATE void debug_mark -( - Int n_row, - Colamd_Row Row [], - Int tag_mark, - Int max_mark -) ; - -PRIVATE void debug_matrix -( - Int n_row, - Int n_col, - Colamd_Row Row [], - Colamd_Col Col [], - Int A [] -) ; - -PRIVATE void debug_structures -( - Int n_row, - Int n_col, - Colamd_Row Row [], - Colamd_Col Col [], - Int A [], - Int n_col2 -) ; - -#else /* NDEBUG */ - -/* === No debugging ========================================================= */ - -#define DEBUG0(params) ; -#define DEBUG1(params) ; -#define DEBUG2(params) ; -#define DEBUG3(params) ; -#define DEBUG4(params) ; - -#define ASSERT(expression) - -#endif /* NDEBUG */ - -/* ========================================================================== */ -/* === USER-CALLABLE ROUTINES: ============================================== */ -/* ========================================================================== */ - -/* ========================================================================== */ -/* === colamd_recommended =================================================== */ -/* ========================================================================== */ - -/* - The colamd_recommended routine returns the suggested size for Alen. This - value has been determined to provide good balance between the number of - garbage collections and the memory requirements for colamd. If any - argument is negative, or if integer overflow occurs, a 0 is returned as an - error condition. 2*nnz space is required for the row and column - indices of the matrix. COLAMD_C (n_col) + COLAMD_R (n_row) space is - required for the Col and Row arrays, respectively, which are internal to - colamd (roughly 6*n_col + 4*n_row). An additional n_col space is the - minimal amount of "elbow room", and nnz/5 more space is recommended for - run time efficiency. - - Alen is approximately 2.2*nnz + 7*n_col + 4*n_row + 10. - - This function is not needed when using symamd. -*/ - -/* add two values of type size_t, and check for integer overflow */ -static size_t t_add (size_t a, size_t b, int *ok) -{ - (*ok) = (*ok) && ((a + b) >= MAX (a,b)) ; - return ((*ok) ? (a + b) : 0) ; -} - -/* compute a*k where k is a small integer, and check for integer overflow */ -static size_t t_mult (size_t a, size_t k, int *ok) -{ - size_t i, s = 0 ; - for (i = 0 ; i < k ; i++) - { - s = t_add (s, a, ok) ; - } - return (s) ; -} - -/* size of the Col and Row structures */ -#define COLAMD_C(n_col,ok) \ - ((t_mult (t_add (n_col, 1, ok), sizeof (Colamd_Col), ok) / sizeof (Int))) - -#define COLAMD_R(n_row,ok) \ - ((t_mult (t_add (n_row, 1, ok), sizeof (Colamd_Row), ok) / sizeof (Int))) - - -PUBLIC size_t COLAMD_recommended /* returns recommended value of Alen. */ -( - /* === Parameters ======================================================= */ - - Int nnz, /* number of nonzeros in A */ - Int n_row, /* number of rows in A */ - Int n_col /* number of columns in A */ -) -{ - size_t s, c, r ; - int ok = TRUE ; - if (nnz < 0 || n_row < 0 || n_col < 0) - { - return (0) ; - } - s = t_mult (nnz, 2, &ok) ; /* 2*nnz */ - c = COLAMD_C (n_col, &ok) ; /* size of column structures */ - r = COLAMD_R (n_row, &ok) ; /* size of row structures */ - s = t_add (s, c, &ok) ; - s = t_add (s, r, &ok) ; - s = t_add (s, n_col, &ok) ; /* elbow room */ - s = t_add (s, nnz/5, &ok) ; /* elbow room */ - ok = ok && (s < Int_MAX) ; - return (ok ? s : 0) ; -} - - -/* ========================================================================== */ -/* === colamd_set_defaults ================================================== */ -/* ========================================================================== */ - -/* - The colamd_set_defaults routine sets the default values of the user- - controllable parameters for colamd and symamd: - - Colamd: rows with more than max (16, knobs [0] * sqrt (n_col)) - entries are removed prior to ordering. Columns with more than - max (16, knobs [1] * sqrt (MIN (n_row,n_col))) entries are removed - prior to ordering, and placed last in the output column ordering. - - Symamd: Rows and columns with more than max (16, knobs [0] * sqrt (n)) - entries are removed prior to ordering, and placed last in the - output ordering. - - knobs [0] dense row control - - knobs [1] dense column control - - knobs [2] if nonzero, do aggresive absorption - - knobs [3..19] unused, but future versions might use this - -*/ - -PUBLIC void COLAMD_set_defaults -( - /* === Parameters ======================================================= */ - - double knobs [COLAMD_KNOBS] /* knob array */ -) -{ - /* === Local variables ================================================== */ - - Int i ; - - if (!knobs) - { - return ; /* no knobs to initialize */ - } - for (i = 0 ; i < COLAMD_KNOBS ; i++) - { - knobs [i] = 0 ; - } - knobs [COLAMD_DENSE_ROW] = 10 ; - knobs [COLAMD_DENSE_COL] = 10 ; - knobs [COLAMD_AGGRESSIVE] = TRUE ; /* default: do aggressive absorption*/ -} - - -/* ========================================================================== */ -/* === symamd =============================================================== */ -/* ========================================================================== */ - -PUBLIC Int SYMAMD_MAIN /* return TRUE if OK, FALSE otherwise */ -( - /* === Parameters ======================================================= */ - - Int n, /* number of rows and columns of A */ - Int A [], /* row indices of A */ - Int p [], /* column pointers of A */ - Int perm [], /* output permutation, size n+1 */ - double knobs [COLAMD_KNOBS], /* parameters (uses defaults if NULL) */ - Int stats [COLAMD_STATS], /* output statistics and error codes */ - void * (*allocate) (size_t, size_t), - /* pointer to calloc (ANSI C) or */ - /* mxCalloc (for MATLAB mexFunction) */ - void (*release) (void *) - /* pointer to free (ANSI C) or */ - /* mxFree (for MATLAB mexFunction) */ -) -{ - /* === Local variables ================================================== */ - - Int *count ; /* length of each column of M, and col pointer*/ - Int *mark ; /* mark array for finding duplicate entries */ - Int *M ; /* row indices of matrix M */ - size_t Mlen ; /* length of M */ - Int n_row ; /* number of rows in M */ - Int nnz ; /* number of entries in A */ - Int i ; /* row index of A */ - Int j ; /* column index of A */ - Int k ; /* row index of M */ - Int mnz ; /* number of nonzeros in M */ - Int pp ; /* index into a column of A */ - Int last_row ; /* last row seen in the current column */ - Int length ; /* number of nonzeros in a column */ - - double cknobs [COLAMD_KNOBS] ; /* knobs for colamd */ - double default_knobs [COLAMD_KNOBS] ; /* default knobs for colamd */ - -#ifndef NDEBUG - colamd_get_debug ("symamd") ; -#endif /* NDEBUG */ - - /* === Check the input arguments ======================================== */ - - if (!stats) - { - DEBUG0 (("symamd: stats not present\n")) ; - return (FALSE) ; - } - for (i = 0 ; i < COLAMD_STATS ; i++) - { - stats [i] = 0 ; - } - stats [COLAMD_STATUS] = COLAMD_OK ; - stats [COLAMD_INFO1] = -1 ; - stats [COLAMD_INFO2] = -1 ; - - if (!A) - { - stats [COLAMD_STATUS] = COLAMD_ERROR_A_not_present ; - DEBUG0 (("symamd: A not present\n")) ; - return (FALSE) ; - } - - if (!p) /* p is not present */ - { - stats [COLAMD_STATUS] = COLAMD_ERROR_p_not_present ; - DEBUG0 (("symamd: p not present\n")) ; - return (FALSE) ; - } - - if (n < 0) /* n must be >= 0 */ - { - stats [COLAMD_STATUS] = COLAMD_ERROR_ncol_negative ; - stats [COLAMD_INFO1] = n ; - DEBUG0 (("symamd: n negative %d\n", n)) ; - return (FALSE) ; - } - - nnz = p [n] ; - if (nnz < 0) /* nnz must be >= 0 */ - { - stats [COLAMD_STATUS] = COLAMD_ERROR_nnz_negative ; - stats [COLAMD_INFO1] = nnz ; - DEBUG0 (("symamd: number of entries negative %d\n", nnz)) ; - return (FALSE) ; - } - - if (p [0] != 0) - { - stats [COLAMD_STATUS] = COLAMD_ERROR_p0_nonzero ; - stats [COLAMD_INFO1] = p [0] ; - DEBUG0 (("symamd: p[0] not zero %d\n", p [0])) ; - return (FALSE) ; - } - - /* === If no knobs, set default knobs =================================== */ - - if (!knobs) - { - COLAMD_set_defaults (default_knobs) ; - knobs = default_knobs ; - } - - /* === Allocate count and mark ========================================== */ - - count = (Int *) ((*allocate) (n+1, sizeof (Int))) ; - if (!count) - { - stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; - DEBUG0 (("symamd: allocate count (size %d) failed\n", n+1)) ; - return (FALSE) ; - } - - mark = (Int *) ((*allocate) (n+1, sizeof (Int))) ; - if (!mark) - { - stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; - (*release) ((void *) count) ; - DEBUG0 (("symamd: allocate mark (size %d) failed\n", n+1)) ; - return (FALSE) ; - } - - /* === Compute column counts of M, check if A is valid ================== */ - - stats [COLAMD_INFO3] = 0 ; /* number of duplicate or unsorted row indices*/ - - for (i = 0 ; i < n ; i++) - { - mark [i] = -1 ; - } - - for (j = 0 ; j < n ; j++) - { - last_row = -1 ; - - length = p [j+1] - p [j] ; - if (length < 0) - { - /* column pointers must be non-decreasing */ - stats [COLAMD_STATUS] = COLAMD_ERROR_col_length_negative ; - stats [COLAMD_INFO1] = j ; - stats [COLAMD_INFO2] = length ; - (*release) ((void *) count) ; - (*release) ((void *) mark) ; - DEBUG0 (("symamd: col %d negative length %d\n", j, length)) ; - return (FALSE) ; - } - - for (pp = p [j] ; pp < p [j+1] ; pp++) - { - i = A [pp] ; - if (i < 0 || i >= n) - { - /* row index i, in column j, is out of bounds */ - stats [COLAMD_STATUS] = COLAMD_ERROR_row_index_out_of_bounds ; - stats [COLAMD_INFO1] = j ; - stats [COLAMD_INFO2] = i ; - stats [COLAMD_INFO3] = n ; - (*release) ((void *) count) ; - (*release) ((void *) mark) ; - DEBUG0 (("symamd: row %d col %d out of bounds\n", i, j)) ; - return (FALSE) ; - } - - if (i <= last_row || mark [i] == j) - { - /* row index is unsorted or repeated (or both), thus col */ - /* is jumbled. This is a notice, not an error condition. */ - stats [COLAMD_STATUS] = COLAMD_OK_BUT_JUMBLED ; - stats [COLAMD_INFO1] = j ; - stats [COLAMD_INFO2] = i ; - (stats [COLAMD_INFO3]) ++ ; - DEBUG1 (("symamd: row %d col %d unsorted/duplicate\n", i, j)) ; - } - - if (i > j && mark [i] != j) - { - /* row k of M will contain column indices i and j */ - count [i]++ ; - count [j]++ ; - } - - /* mark the row as having been seen in this column */ - mark [i] = j ; - - last_row = i ; - } - } - - /* v2.4: removed free(mark) */ - - /* === Compute column pointers of M ===================================== */ - - /* use output permutation, perm, for column pointers of M */ - perm [0] = 0 ; - for (j = 1 ; j <= n ; j++) - { - perm [j] = perm [j-1] + count [j-1] ; - } - for (j = 0 ; j < n ; j++) - { - count [j] = perm [j] ; - } - - /* === Construct M ====================================================== */ - - mnz = perm [n] ; - n_row = mnz / 2 ; - Mlen = COLAMD_recommended (mnz, n_row, n) ; - M = (Int *) ((*allocate) (Mlen, sizeof (Int))) ; - DEBUG0 (("symamd: M is %d-by-%d with %d entries, Mlen = %g\n", - n_row, n, mnz, (double) Mlen)) ; - - if (!M) - { - stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; - (*release) ((void *) count) ; - (*release) ((void *) mark) ; - DEBUG0 (("symamd: allocate M (size %g) failed\n", (double) Mlen)) ; - return (FALSE) ; - } - - k = 0 ; - - if (stats [COLAMD_STATUS] == COLAMD_OK) - { - /* Matrix is OK */ - for (j = 0 ; j < n ; j++) - { - ASSERT (p [j+1] - p [j] >= 0) ; - for (pp = p [j] ; pp < p [j+1] ; pp++) - { - i = A [pp] ; - ASSERT (i >= 0 && i < n) ; - if (i > j) - { - /* row k of M contains column indices i and j */ - M [count [i]++] = k ; - M [count [j]++] = k ; - k++ ; - } - } - } - } - else - { - /* Matrix is jumbled. Do not add duplicates to M. Unsorted cols OK. */ - DEBUG0 (("symamd: Duplicates in A.\n")) ; - for (i = 0 ; i < n ; i++) - { - mark [i] = -1 ; - } - for (j = 0 ; j < n ; j++) - { - ASSERT (p [j+1] - p [j] >= 0) ; - for (pp = p [j] ; pp < p [j+1] ; pp++) - { - i = A [pp] ; - ASSERT (i >= 0 && i < n) ; - if (i > j && mark [i] != j) - { - /* row k of M contains column indices i and j */ - M [count [i]++] = k ; - M [count [j]++] = k ; - k++ ; - mark [i] = j ; - } - } - } - /* v2.4: free(mark) moved below */ - } - - /* count and mark no longer needed */ - (*release) ((void *) count) ; - (*release) ((void *) mark) ; /* v2.4: free (mark) moved here */ - ASSERT (k == n_row) ; - - /* === Adjust the knobs for M =========================================== */ - - for (i = 0 ; i < COLAMD_KNOBS ; i++) - { - cknobs [i] = knobs [i] ; - } - - /* there are no dense rows in M */ - cknobs [COLAMD_DENSE_ROW] = -1 ; - cknobs [COLAMD_DENSE_COL] = knobs [COLAMD_DENSE_ROW] ; - - /* === Order the columns of M =========================================== */ - - /* v2.4: colamd cannot fail here, so the error check is removed */ - (void) COLAMD_MAIN (n_row, n, (Int) Mlen, M, perm, cknobs, stats) ; - - /* Note that the output permutation is now in perm */ - - /* === get the statistics for symamd from colamd ======================== */ - - /* a dense column in colamd means a dense row and col in symamd */ - stats [COLAMD_DENSE_ROW] = stats [COLAMD_DENSE_COL] ; - - /* === Free M =========================================================== */ - - (*release) ((void *) M) ; - DEBUG0 (("symamd: done.\n")) ; - return (TRUE) ; - -} - -/* ========================================================================== */ -/* === colamd =============================================================== */ -/* ========================================================================== */ - -/* - The colamd routine computes a column ordering Q of a sparse matrix - A such that the LU factorization P(AQ) = LU remains sparse, where P is - selected via partial pivoting. The routine can also be viewed as - providing a permutation Q such that the Cholesky factorization - (AQ)'(AQ) = LL' remains sparse. -*/ - -PUBLIC Int COLAMD_MAIN /* returns TRUE if successful, FALSE otherwise*/ -( - /* === Parameters ======================================================= */ - - Int n_row, /* number of rows in A */ - Int n_col, /* number of columns in A */ - Int Alen, /* length of A */ - Int A [], /* row indices of A */ - Int p [], /* pointers to columns in A */ - double knobs [COLAMD_KNOBS],/* parameters (uses defaults if NULL) */ - Int stats [COLAMD_STATS] /* output statistics and error codes */ -) -{ - /* === Local variables ================================================== */ - - Int i ; /* loop index */ - Int nnz ; /* nonzeros in A */ - size_t Row_size ; /* size of Row [], in integers */ - size_t Col_size ; /* size of Col [], in integers */ - size_t need ; /* minimum required length of A */ - Colamd_Row *Row ; /* pointer into A of Row [0..n_row] array */ - Colamd_Col *Col ; /* pointer into A of Col [0..n_col] array */ - Int n_col2 ; /* number of non-dense, non-empty columns */ - Int n_row2 ; /* number of non-dense, non-empty rows */ - Int ngarbage ; /* number of garbage collections performed */ - Int max_deg ; /* maximum row degree */ - double default_knobs [COLAMD_KNOBS] ; /* default knobs array */ - Int aggressive ; /* do aggressive absorption */ - int ok ; - -#ifndef NDEBUG - colamd_get_debug ("colamd") ; -#endif /* NDEBUG */ - - /* === Check the input arguments ======================================== */ - - if (!stats) - { - DEBUG0 (("colamd: stats not present\n")) ; - return (FALSE) ; - } - for (i = 0 ; i < COLAMD_STATS ; i++) - { - stats [i] = 0 ; - } - stats [COLAMD_STATUS] = COLAMD_OK ; - stats [COLAMD_INFO1] = -1 ; - stats [COLAMD_INFO2] = -1 ; - - if (!A) /* A is not present */ - { - stats [COLAMD_STATUS] = COLAMD_ERROR_A_not_present ; - DEBUG0 (("colamd: A not present\n")) ; - return (FALSE) ; - } - - if (!p) /* p is not present */ - { - stats [COLAMD_STATUS] = COLAMD_ERROR_p_not_present ; - DEBUG0 (("colamd: p not present\n")) ; - return (FALSE) ; - } - - if (n_row < 0) /* n_row must be >= 0 */ - { - stats [COLAMD_STATUS] = COLAMD_ERROR_nrow_negative ; - stats [COLAMD_INFO1] = n_row ; - DEBUG0 (("colamd: nrow negative %d\n", n_row)) ; - return (FALSE) ; - } - - if (n_col < 0) /* n_col must be >= 0 */ - { - stats [COLAMD_STATUS] = COLAMD_ERROR_ncol_negative ; - stats [COLAMD_INFO1] = n_col ; - DEBUG0 (("colamd: ncol negative %d\n", n_col)) ; - return (FALSE) ; - } - - nnz = p [n_col] ; - if (nnz < 0) /* nnz must be >= 0 */ - { - stats [COLAMD_STATUS] = COLAMD_ERROR_nnz_negative ; - stats [COLAMD_INFO1] = nnz ; - DEBUG0 (("colamd: number of entries negative %d\n", nnz)) ; - return (FALSE) ; - } - - if (p [0] != 0) - { - stats [COLAMD_STATUS] = COLAMD_ERROR_p0_nonzero ; - stats [COLAMD_INFO1] = p [0] ; - DEBUG0 (("colamd: p[0] not zero %d\n", p [0])) ; - return (FALSE) ; - } - - /* === If no knobs, set default knobs =================================== */ - - if (!knobs) - { - COLAMD_set_defaults (default_knobs) ; - knobs = default_knobs ; - } - - aggressive = (knobs [COLAMD_AGGRESSIVE] != FALSE) ; - - /* === Allocate the Row and Col arrays from array A ===================== */ - - ok = TRUE ; - Col_size = COLAMD_C (n_col, &ok) ; /* size of Col array of structs */ - Row_size = COLAMD_R (n_row, &ok) ; /* size of Row array of structs */ - - /* need = 2*nnz + n_col + Col_size + Row_size ; */ - need = t_mult (nnz, 2, &ok) ; - need = t_add (need, n_col, &ok) ; - need = t_add (need, Col_size, &ok) ; - need = t_add (need, Row_size, &ok) ; - - if (!ok || need > (size_t) Alen || need > Int_MAX) - { - /* not enough space in array A to perform the ordering */ - stats [COLAMD_STATUS] = COLAMD_ERROR_A_too_small ; - stats [COLAMD_INFO1] = need ; - stats [COLAMD_INFO2] = Alen ; - DEBUG0 (("colamd: Need Alen >= %d, given only Alen = %d\n", need,Alen)); - return (FALSE) ; - } - - Alen -= Col_size + Row_size ; - Col = (Colamd_Col *) &A [Alen] ; - Row = (Colamd_Row *) &A [Alen + Col_size] ; - - /* === Construct the row and column data structures ===================== */ - - if (!init_rows_cols (n_row, n_col, Row, Col, A, p, stats)) - { - /* input matrix is invalid */ - DEBUG0 (("colamd: Matrix invalid\n")) ; - return (FALSE) ; - } - - /* === Initialize scores, kill dense rows/columns ======================= */ - - init_scoring (n_row, n_col, Row, Col, A, p, knobs, - &n_row2, &n_col2, &max_deg) ; - - /* === Order the supercolumns =========================================== */ - - ngarbage = find_ordering (n_row, n_col, Alen, Row, Col, A, p, - n_col2, max_deg, 2*nnz, aggressive) ; - - /* === Order the non-principal columns ================================== */ - - order_children (n_col, Col, p) ; - - /* === Return statistics in stats ======================================= */ - - stats [COLAMD_DENSE_ROW] = n_row - n_row2 ; - stats [COLAMD_DENSE_COL] = n_col - n_col2 ; - stats [COLAMD_DEFRAG_COUNT] = ngarbage ; - DEBUG0 (("colamd: done.\n")) ; - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === colamd_report ======================================================== */ -/* ========================================================================== */ - -PUBLIC void COLAMD_report -( - Int stats [COLAMD_STATS] -) -{ - print_report ("colamd", stats) ; -} - - -/* ========================================================================== */ -/* === symamd_report ======================================================== */ -/* ========================================================================== */ - -PUBLIC void SYMAMD_report -( - Int stats [COLAMD_STATS] -) -{ - print_report ("symamd", stats) ; -} - - - -/* ========================================================================== */ -/* === NON-USER-CALLABLE ROUTINES: ========================================== */ -/* ========================================================================== */ - -/* There are no user-callable routines beyond this point in the file */ - - -/* ========================================================================== */ -/* === init_rows_cols ======================================================= */ -/* ========================================================================== */ - -/* - Takes the column form of the matrix in A and creates the row form of the - matrix. Also, row and column attributes are stored in the Col and Row - structs. If the columns are un-sorted or contain duplicate row indices, - this routine will also sort and remove duplicate row indices from the - column form of the matrix. Returns FALSE if the matrix is invalid, - TRUE otherwise. Not user-callable. -*/ - -PRIVATE Int init_rows_cols /* returns TRUE if OK, or FALSE otherwise */ -( - /* === Parameters ======================================================= */ - - Int n_row, /* number of rows of A */ - Int n_col, /* number of columns of A */ - Colamd_Row Row [], /* of size n_row+1 */ - Colamd_Col Col [], /* of size n_col+1 */ - Int A [], /* row indices of A, of size Alen */ - Int p [], /* pointers to columns in A, of size n_col+1 */ - Int stats [COLAMD_STATS] /* colamd statistics */ -) -{ - /* === Local variables ================================================== */ - - Int col ; /* a column index */ - Int row ; /* a row index */ - Int *cp ; /* a column pointer */ - Int *cp_end ; /* a pointer to the end of a column */ - Int *rp ; /* a row pointer */ - Int *rp_end ; /* a pointer to the end of a row */ - Int last_row ; /* previous row */ - - /* === Initialize columns, and check column pointers ==================== */ - - for (col = 0 ; col < n_col ; col++) - { - Col [col].start = p [col] ; - Col [col].length = p [col+1] - p [col] ; - - if (Col [col].length < 0) - { - /* column pointers must be non-decreasing */ - stats [COLAMD_STATUS] = COLAMD_ERROR_col_length_negative ; - stats [COLAMD_INFO1] = col ; - stats [COLAMD_INFO2] = Col [col].length ; - DEBUG0 (("colamd: col %d length %d < 0\n", col, Col [col].length)) ; - return (FALSE) ; - } - - Col [col].shared1.thickness = 1 ; - Col [col].shared2.score = 0 ; - Col [col].shared3.prev = EMPTY ; - Col [col].shared4.degree_next = EMPTY ; - } - - /* p [0..n_col] no longer needed, used as "head" in subsequent routines */ - - /* === Scan columns, compute row degrees, and check row indices ========= */ - - stats [COLAMD_INFO3] = 0 ; /* number of duplicate or unsorted row indices*/ - - for (row = 0 ; row < n_row ; row++) - { - Row [row].length = 0 ; - Row [row].shared2.mark = -1 ; - } - - for (col = 0 ; col < n_col ; col++) - { - last_row = -1 ; - - cp = &A [p [col]] ; - cp_end = &A [p [col+1]] ; - - while (cp < cp_end) - { - row = *cp++ ; - - /* make sure row indices within range */ - if (row < 0 || row >= n_row) - { - stats [COLAMD_STATUS] = COLAMD_ERROR_row_index_out_of_bounds ; - stats [COLAMD_INFO1] = col ; - stats [COLAMD_INFO2] = row ; - stats [COLAMD_INFO3] = n_row ; - DEBUG0 (("colamd: row %d col %d out of bounds\n", row, col)) ; - return (FALSE) ; - } - - if (row <= last_row || Row [row].shared2.mark == col) - { - /* row index are unsorted or repeated (or both), thus col */ - /* is jumbled. This is a notice, not an error condition. */ - stats [COLAMD_STATUS] = COLAMD_OK_BUT_JUMBLED ; - stats [COLAMD_INFO1] = col ; - stats [COLAMD_INFO2] = row ; - (stats [COLAMD_INFO3]) ++ ; - DEBUG1 (("colamd: row %d col %d unsorted/duplicate\n",row,col)); - } - - if (Row [row].shared2.mark != col) - { - Row [row].length++ ; - } - else - { - /* this is a repeated entry in the column, */ - /* it will be removed */ - Col [col].length-- ; - } - - /* mark the row as having been seen in this column */ - Row [row].shared2.mark = col ; - - last_row = row ; - } - } - - /* === Compute row pointers ============================================= */ - - /* row form of the matrix starts directly after the column */ - /* form of matrix in A */ - Row [0].start = p [n_col] ; - Row [0].shared1.p = Row [0].start ; - Row [0].shared2.mark = -1 ; - for (row = 1 ; row < n_row ; row++) - { - Row [row].start = Row [row-1].start + Row [row-1].length ; - Row [row].shared1.p = Row [row].start ; - Row [row].shared2.mark = -1 ; - } - - /* === Create row form ================================================== */ - - if (stats [COLAMD_STATUS] == COLAMD_OK_BUT_JUMBLED) - { - /* if cols jumbled, watch for repeated row indices */ - for (col = 0 ; col < n_col ; col++) - { - cp = &A [p [col]] ; - cp_end = &A [p [col+1]] ; - while (cp < cp_end) - { - row = *cp++ ; - if (Row [row].shared2.mark != col) - { - A [(Row [row].shared1.p)++] = col ; - Row [row].shared2.mark = col ; - } - } - } - } - else - { - /* if cols not jumbled, we don't need the mark (this is faster) */ - for (col = 0 ; col < n_col ; col++) - { - cp = &A [p [col]] ; - cp_end = &A [p [col+1]] ; - while (cp < cp_end) - { - A [(Row [*cp++].shared1.p)++] = col ; - } - } - } - - /* === Clear the row marks and set row degrees ========================== */ - - for (row = 0 ; row < n_row ; row++) - { - Row [row].shared2.mark = 0 ; - Row [row].shared1.degree = Row [row].length ; - } - - /* === See if we need to re-create columns ============================== */ - - if (stats [COLAMD_STATUS] == COLAMD_OK_BUT_JUMBLED) - { - DEBUG0 (("colamd: reconstructing column form, matrix jumbled\n")) ; - -#ifndef NDEBUG - /* make sure column lengths are correct */ - for (col = 0 ; col < n_col ; col++) - { - p [col] = Col [col].length ; - } - for (row = 0 ; row < n_row ; row++) - { - rp = &A [Row [row].start] ; - rp_end = rp + Row [row].length ; - while (rp < rp_end) - { - p [*rp++]-- ; - } - } - for (col = 0 ; col < n_col ; col++) - { - ASSERT (p [col] == 0) ; - } - /* now p is all zero (different than when debugging is turned off) */ -#endif /* NDEBUG */ - - /* === Compute col pointers ========================================= */ - - /* col form of the matrix starts at A [0]. */ - /* Note, we may have a gap between the col form and the row */ - /* form if there were duplicate entries, if so, it will be */ - /* removed upon the first garbage collection */ - Col [0].start = 0 ; - p [0] = Col [0].start ; - for (col = 1 ; col < n_col ; col++) - { - /* note that the lengths here are for pruned columns, i.e. */ - /* no duplicate row indices will exist for these columns */ - Col [col].start = Col [col-1].start + Col [col-1].length ; - p [col] = Col [col].start ; - } - - /* === Re-create col form =========================================== */ - - for (row = 0 ; row < n_row ; row++) - { - rp = &A [Row [row].start] ; - rp_end = rp + Row [row].length ; - while (rp < rp_end) - { - A [(p [*rp++])++] = row ; - } - } - } - - /* === Done. Matrix is not (or no longer) jumbled ====================== */ - - return (TRUE) ; -} - - -/* ========================================================================== */ -/* === init_scoring ========================================================= */ -/* ========================================================================== */ - -/* - Kills dense or empty columns and rows, calculates an initial score for - each column, and places all columns in the degree lists. Not user-callable. -*/ - -PRIVATE void init_scoring -( - /* === Parameters ======================================================= */ - - Int n_row, /* number of rows of A */ - Int n_col, /* number of columns of A */ - Colamd_Row Row [], /* of size n_row+1 */ - Colamd_Col Col [], /* of size n_col+1 */ - Int A [], /* column form and row form of A */ - Int head [], /* of size n_col+1 */ - double knobs [COLAMD_KNOBS],/* parameters */ - Int *p_n_row2, /* number of non-dense, non-empty rows */ - Int *p_n_col2, /* number of non-dense, non-empty columns */ - Int *p_max_deg /* maximum row degree */ -) -{ - /* === Local variables ================================================== */ - - Int c ; /* a column index */ - Int r, row ; /* a row index */ - Int *cp ; /* a column pointer */ - Int deg ; /* degree of a row or column */ - Int *cp_end ; /* a pointer to the end of a column */ - Int *new_cp ; /* new column pointer */ - Int col_length ; /* length of pruned column */ - Int score ; /* current column score */ - Int n_col2 ; /* number of non-dense, non-empty columns */ - Int n_row2 ; /* number of non-dense, non-empty rows */ - Int dense_row_count ; /* remove rows with more entries than this */ - Int dense_col_count ; /* remove cols with more entries than this */ - Int min_score ; /* smallest column score */ - Int max_deg ; /* maximum row degree */ - Int next_col ; /* Used to add to degree list.*/ - -#ifndef NDEBUG - Int debug_count ; /* debug only. */ -#endif /* NDEBUG */ - - /* === Extract knobs ==================================================== */ - - /* Note: if knobs contains a NaN, this is undefined: */ - if (knobs [COLAMD_DENSE_ROW] < 0) - { - /* only remove completely dense rows */ - dense_row_count = n_col-1 ; - } - else - { - dense_row_count = DENSE_DEGREE (knobs [COLAMD_DENSE_ROW], n_col) ; - } - if (knobs [COLAMD_DENSE_COL] < 0) - { - /* only remove completely dense columns */ - dense_col_count = n_row-1 ; - } - else - { - dense_col_count = - DENSE_DEGREE (knobs [COLAMD_DENSE_COL], MIN (n_row, n_col)) ; - } - - DEBUG1 (("colamd: densecount: %d %d\n", dense_row_count, dense_col_count)) ; - max_deg = 0 ; - n_col2 = n_col ; - n_row2 = n_row ; - - /* === Kill empty columns =============================================== */ - - /* Put the empty columns at the end in their natural order, so that LU */ - /* factorization can proceed as far as possible. */ - for (c = n_col-1 ; c >= 0 ; c--) - { - deg = Col [c].length ; - if (deg == 0) - { - /* this is a empty column, kill and order it last */ - Col [c].shared2.order = --n_col2 ; - KILL_PRINCIPAL_COL (c) ; - } - } - DEBUG1 (("colamd: null columns killed: %d\n", n_col - n_col2)) ; - - /* === Kill dense columns =============================================== */ - - /* Put the dense columns at the end, in their natural order */ - for (c = n_col-1 ; c >= 0 ; c--) - { - /* skip any dead columns */ - if (COL_IS_DEAD (c)) - { - continue ; - } - deg = Col [c].length ; - if (deg > dense_col_count) - { - /* this is a dense column, kill and order it last */ - Col [c].shared2.order = --n_col2 ; - /* decrement the row degrees */ - cp = &A [Col [c].start] ; - cp_end = cp + Col [c].length ; - while (cp < cp_end) - { - Row [*cp++].shared1.degree-- ; - } - KILL_PRINCIPAL_COL (c) ; - } - } - DEBUG1 (("colamd: Dense and null columns killed: %d\n", n_col - n_col2)) ; - - /* === Kill dense and empty rows ======================================== */ - - for (r = 0 ; r < n_row ; r++) - { - deg = Row [r].shared1.degree ; - ASSERT (deg >= 0 && deg <= n_col) ; - if (deg > dense_row_count || deg == 0) - { - /* kill a dense or empty row */ - KILL_ROW (r) ; - --n_row2 ; - } - else - { - /* keep track of max degree of remaining rows */ - max_deg = MAX (max_deg, deg) ; - } - } - DEBUG1 (("colamd: Dense and null rows killed: %d\n", n_row - n_row2)) ; - - /* === Compute initial column scores ==================================== */ - - /* At this point the row degrees are accurate. They reflect the number */ - /* of "live" (non-dense) columns in each row. No empty rows exist. */ - /* Some "live" columns may contain only dead rows, however. These are */ - /* pruned in the code below. */ - - /* now find the initial matlab score for each column */ - for (c = n_col-1 ; c >= 0 ; c--) - { - /* skip dead column */ - if (COL_IS_DEAD (c)) - { - continue ; - } - score = 0 ; - cp = &A [Col [c].start] ; - new_cp = cp ; - cp_end = cp + Col [c].length ; - while (cp < cp_end) - { - /* get a row */ - row = *cp++ ; - /* skip if dead */ - if (ROW_IS_DEAD (row)) - { - continue ; - } - /* compact the column */ - *new_cp++ = row ; - /* add row's external degree */ - score += Row [row].shared1.degree - 1 ; - /* guard against integer overflow */ - score = MIN (score, n_col) ; - } - /* determine pruned column length */ - col_length = (Int) (new_cp - &A [Col [c].start]) ; - if (col_length == 0) - { - /* a newly-made null column (all rows in this col are "dense" */ - /* and have already been killed) */ - DEBUG2 (("Newly null killed: %d\n", c)) ; - Col [c].shared2.order = --n_col2 ; - KILL_PRINCIPAL_COL (c) ; - } - else - { - /* set column length and set score */ - ASSERT (score >= 0) ; - ASSERT (score <= n_col) ; - Col [c].length = col_length ; - Col [c].shared2.score = score ; - } - } - DEBUG1 (("colamd: Dense, null, and newly-null columns killed: %d\n", - n_col-n_col2)) ; - - /* At this point, all empty rows and columns are dead. All live columns */ - /* are "clean" (containing no dead rows) and simplicial (no supercolumns */ - /* yet). Rows may contain dead columns, but all live rows contain at */ - /* least one live column. */ - -#ifndef NDEBUG - debug_structures (n_row, n_col, Row, Col, A, n_col2) ; -#endif /* NDEBUG */ - - /* === Initialize degree lists ========================================== */ - -#ifndef NDEBUG - debug_count = 0 ; -#endif /* NDEBUG */ - - /* clear the hash buckets */ - for (c = 0 ; c <= n_col ; c++) - { - head [c] = EMPTY ; - } - min_score = n_col ; - /* place in reverse order, so low column indices are at the front */ - /* of the lists. This is to encourage natural tie-breaking */ - for (c = n_col-1 ; c >= 0 ; c--) - { - /* only add principal columns to degree lists */ - if (COL_IS_ALIVE (c)) - { - DEBUG4 (("place %d score %d minscore %d ncol %d\n", - c, Col [c].shared2.score, min_score, n_col)) ; - - /* === Add columns score to DList =============================== */ - - score = Col [c].shared2.score ; - - ASSERT (min_score >= 0) ; - ASSERT (min_score <= n_col) ; - ASSERT (score >= 0) ; - ASSERT (score <= n_col) ; - ASSERT (head [score] >= EMPTY) ; - - /* now add this column to dList at proper score location */ - next_col = head [score] ; - Col [c].shared3.prev = EMPTY ; - Col [c].shared4.degree_next = next_col ; - - /* if there already was a column with the same score, set its */ - /* previous pointer to this new column */ - if (next_col != EMPTY) - { - Col [next_col].shared3.prev = c ; - } - head [score] = c ; - - /* see if this score is less than current min */ - min_score = MIN (min_score, score) ; - -#ifndef NDEBUG - debug_count++ ; -#endif /* NDEBUG */ - - } - } - -#ifndef NDEBUG - DEBUG1 (("colamd: Live cols %d out of %d, non-princ: %d\n", - debug_count, n_col, n_col-debug_count)) ; - ASSERT (debug_count == n_col2) ; - debug_deg_lists (n_row, n_col, Row, Col, head, min_score, n_col2, max_deg) ; -#endif /* NDEBUG */ - - /* === Return number of remaining columns, and max row degree =========== */ - - *p_n_col2 = n_col2 ; - *p_n_row2 = n_row2 ; - *p_max_deg = max_deg ; -} - - -/* ========================================================================== */ -/* === find_ordering ======================================================== */ -/* ========================================================================== */ - -/* - Order the principal columns of the supercolumn form of the matrix - (no supercolumns on input). Uses a minimum approximate column minimum - degree ordering method. Not user-callable. -*/ - -PRIVATE Int find_ordering /* return the number of garbage collections */ -( - /* === Parameters ======================================================= */ - - Int n_row, /* number of rows of A */ - Int n_col, /* number of columns of A */ - Int Alen, /* size of A, 2*nnz + n_col or larger */ - Colamd_Row Row [], /* of size n_row+1 */ - Colamd_Col Col [], /* of size n_col+1 */ - Int A [], /* column form and row form of A */ - Int head [], /* of size n_col+1 */ - Int n_col2, /* Remaining columns to order */ - Int max_deg, /* Maximum row degree */ - Int pfree, /* index of first free slot (2*nnz on entry) */ - Int aggressive -) -{ - /* === Local variables ================================================== */ - - Int k ; /* current pivot ordering step */ - Int pivot_col ; /* current pivot column */ - Int *cp ; /* a column pointer */ - Int *rp ; /* a row pointer */ - Int pivot_row ; /* current pivot row */ - Int *new_cp ; /* modified column pointer */ - Int *new_rp ; /* modified row pointer */ - Int pivot_row_start ; /* pointer to start of pivot row */ - Int pivot_row_degree ; /* number of columns in pivot row */ - Int pivot_row_length ; /* number of supercolumns in pivot row */ - Int pivot_col_score ; /* score of pivot column */ - Int needed_memory ; /* free space needed for pivot row */ - Int *cp_end ; /* pointer to the end of a column */ - Int *rp_end ; /* pointer to the end of a row */ - Int row ; /* a row index */ - Int col ; /* a column index */ - Int max_score ; /* maximum possible score */ - Int cur_score ; /* score of current column */ - unsigned Int hash ; /* hash value for supernode detection */ - Int head_column ; /* head of hash bucket */ - Int first_col ; /* first column in hash bucket */ - Int tag_mark ; /* marker value for mark array */ - Int row_mark ; /* Row [row].shared2.mark */ - Int set_difference ; /* set difference size of row with pivot row */ - Int min_score ; /* smallest column score */ - Int col_thickness ; /* "thickness" (no. of columns in a supercol) */ - Int max_mark ; /* maximum value of tag_mark */ - Int pivot_col_thickness ; /* number of columns represented by pivot col */ - Int prev_col ; /* Used by Dlist operations. */ - Int next_col ; /* Used by Dlist operations. */ - Int ngarbage ; /* number of garbage collections performed */ - -#ifndef NDEBUG - Int debug_d ; /* debug loop counter */ - Int debug_step = 0 ; /* debug loop counter */ -#endif /* NDEBUG */ - - /* === Initialization and clear mark ==================================== */ - - max_mark = INT_MAX - n_col ; /* INT_MAX defined in */ - tag_mark = clear_mark (0, max_mark, n_row, Row) ; - min_score = 0 ; - ngarbage = 0 ; - DEBUG1 (("colamd: Ordering, n_col2=%d\n", n_col2)) ; - - /* === Order the columns ================================================ */ - - for (k = 0 ; k < n_col2 ; /* 'k' is incremented below */) - { - -#ifndef NDEBUG - if (debug_step % 100 == 0) - { - DEBUG2 (("\n... Step k: %d out of n_col2: %d\n", k, n_col2)) ; - } - else - { - DEBUG3 (("\n----------Step k: %d out of n_col2: %d\n", k, n_col2)) ; - } - debug_step++ ; - debug_deg_lists (n_row, n_col, Row, Col, head, - min_score, n_col2-k, max_deg) ; - debug_matrix (n_row, n_col, Row, Col, A) ; -#endif /* NDEBUG */ - - /* === Select pivot column, and order it ============================ */ - - /* make sure degree list isn't empty */ - ASSERT (min_score >= 0) ; - ASSERT (min_score <= n_col) ; - ASSERT (head [min_score] >= EMPTY) ; - -#ifndef NDEBUG - for (debug_d = 0 ; debug_d < min_score ; debug_d++) - { - ASSERT (head [debug_d] == EMPTY) ; - } -#endif /* NDEBUG */ - - /* get pivot column from head of minimum degree list */ - while (head [min_score] == EMPTY && min_score < n_col) - { - min_score++ ; - } - pivot_col = head [min_score] ; - ASSERT (pivot_col >= 0 && pivot_col <= n_col) ; - next_col = Col [pivot_col].shared4.degree_next ; - head [min_score] = next_col ; - if (next_col != EMPTY) - { - Col [next_col].shared3.prev = EMPTY ; - } - - ASSERT (COL_IS_ALIVE (pivot_col)) ; - - /* remember score for defrag check */ - pivot_col_score = Col [pivot_col].shared2.score ; - - /* the pivot column is the kth column in the pivot order */ - Col [pivot_col].shared2.order = k ; - - /* increment order count by column thickness */ - pivot_col_thickness = Col [pivot_col].shared1.thickness ; - k += pivot_col_thickness ; - ASSERT (pivot_col_thickness > 0) ; - DEBUG3 (("Pivot col: %d thick %d\n", pivot_col, pivot_col_thickness)) ; - - /* === Garbage_collection, if necessary ============================= */ - - needed_memory = MIN (pivot_col_score, n_col - k) ; - if (pfree + needed_memory >= Alen) - { - pfree = garbage_collection (n_row, n_col, Row, Col, A, &A [pfree]) ; - ngarbage++ ; - /* after garbage collection we will have enough */ - ASSERT (pfree + needed_memory < Alen) ; - /* garbage collection has wiped out the Row[].shared2.mark array */ - tag_mark = clear_mark (0, max_mark, n_row, Row) ; - -#ifndef NDEBUG - debug_matrix (n_row, n_col, Row, Col, A) ; -#endif /* NDEBUG */ - } - - /* === Compute pivot row pattern ==================================== */ - - /* get starting location for this new merged row */ - pivot_row_start = pfree ; - - /* initialize new row counts to zero */ - pivot_row_degree = 0 ; - - /* tag pivot column as having been visited so it isn't included */ - /* in merged pivot row */ - Col [pivot_col].shared1.thickness = -pivot_col_thickness ; - - /* pivot row is the union of all rows in the pivot column pattern */ - cp = &A [Col [pivot_col].start] ; - cp_end = cp + Col [pivot_col].length ; - while (cp < cp_end) - { - /* get a row */ - row = *cp++ ; - DEBUG4 (("Pivot col pattern %d %d\n", ROW_IS_ALIVE (row), row)) ; - /* skip if row is dead */ - if (ROW_IS_ALIVE (row)) - { - rp = &A [Row [row].start] ; - rp_end = rp + Row [row].length ; - while (rp < rp_end) - { - /* get a column */ - col = *rp++ ; - /* add the column, if alive and untagged */ - col_thickness = Col [col].shared1.thickness ; - if (col_thickness > 0 && COL_IS_ALIVE (col)) - { - /* tag column in pivot row */ - Col [col].shared1.thickness = -col_thickness ; - ASSERT (pfree < Alen) ; - /* place column in pivot row */ - A [pfree++] = col ; - pivot_row_degree += col_thickness ; - } - } - } - } - - /* clear tag on pivot column */ - Col [pivot_col].shared1.thickness = pivot_col_thickness ; - max_deg = MAX (max_deg, pivot_row_degree) ; - -#ifndef NDEBUG - DEBUG3 (("check2\n")) ; - debug_mark (n_row, Row, tag_mark, max_mark) ; -#endif /* NDEBUG */ - - /* === Kill all rows used to construct pivot row ==================== */ - - /* also kill pivot row, temporarily */ - cp = &A [Col [pivot_col].start] ; - cp_end = cp + Col [pivot_col].length ; - while (cp < cp_end) - { - /* may be killing an already dead row */ - row = *cp++ ; - DEBUG3 (("Kill row in pivot col: %d\n", row)) ; - KILL_ROW (row) ; - } - - /* === Select a row index to use as the new pivot row =============== */ - - pivot_row_length = pfree - pivot_row_start ; - if (pivot_row_length > 0) - { - /* pick the "pivot" row arbitrarily (first row in col) */ - pivot_row = A [Col [pivot_col].start] ; - DEBUG3 (("Pivotal row is %d\n", pivot_row)) ; - } - else - { - /* there is no pivot row, since it is of zero length */ - pivot_row = EMPTY ; - ASSERT (pivot_row_length == 0) ; - } - ASSERT (Col [pivot_col].length > 0 || pivot_row_length == 0) ; - - /* === Approximate degree computation =============================== */ - - /* Here begins the computation of the approximate degree. The column */ - /* score is the sum of the pivot row "length", plus the size of the */ - /* set differences of each row in the column minus the pattern of the */ - /* pivot row itself. The column ("thickness") itself is also */ - /* excluded from the column score (we thus use an approximate */ - /* external degree). */ - - /* The time taken by the following code (compute set differences, and */ - /* add them up) is proportional to the size of the data structure */ - /* being scanned - that is, the sum of the sizes of each column in */ - /* the pivot row. Thus, the amortized time to compute a column score */ - /* is proportional to the size of that column (where size, in this */ - /* context, is the column "length", or the number of row indices */ - /* in that column). The number of row indices in a column is */ - /* monotonically non-decreasing, from the length of the original */ - /* column on input to colamd. */ - - /* === Compute set differences ====================================== */ - - DEBUG3 (("** Computing set differences phase. **\n")) ; - - /* pivot row is currently dead - it will be revived later. */ - - DEBUG3 (("Pivot row: ")) ; - /* for each column in pivot row */ - rp = &A [pivot_row_start] ; - rp_end = rp + pivot_row_length ; - while (rp < rp_end) - { - col = *rp++ ; - ASSERT (COL_IS_ALIVE (col) && col != pivot_col) ; - DEBUG3 (("Col: %d\n", col)) ; - - /* clear tags used to construct pivot row pattern */ - col_thickness = -Col [col].shared1.thickness ; - ASSERT (col_thickness > 0) ; - Col [col].shared1.thickness = col_thickness ; - - /* === Remove column from degree list =========================== */ - - cur_score = Col [col].shared2.score ; - prev_col = Col [col].shared3.prev ; - next_col = Col [col].shared4.degree_next ; - ASSERT (cur_score >= 0) ; - ASSERT (cur_score <= n_col) ; - ASSERT (cur_score >= EMPTY) ; - if (prev_col == EMPTY) - { - head [cur_score] = next_col ; - } - else - { - Col [prev_col].shared4.degree_next = next_col ; - } - if (next_col != EMPTY) - { - Col [next_col].shared3.prev = prev_col ; - } - - /* === Scan the column ========================================== */ - - cp = &A [Col [col].start] ; - cp_end = cp + Col [col].length ; - while (cp < cp_end) - { - /* get a row */ - row = *cp++ ; - row_mark = Row [row].shared2.mark ; - /* skip if dead */ - if (ROW_IS_MARKED_DEAD (row_mark)) - { - continue ; - } - ASSERT (row != pivot_row) ; - set_difference = row_mark - tag_mark ; - /* check if the row has been seen yet */ - if (set_difference < 0) - { - ASSERT (Row [row].shared1.degree <= max_deg) ; - set_difference = Row [row].shared1.degree ; - } - /* subtract column thickness from this row's set difference */ - set_difference -= col_thickness ; - ASSERT (set_difference >= 0) ; - /* absorb this row if the set difference becomes zero */ - if (set_difference == 0 && aggressive) - { - DEBUG3 (("aggressive absorption. Row: %d\n", row)) ; - KILL_ROW (row) ; - } - else - { - /* save the new mark */ - Row [row].shared2.mark = set_difference + tag_mark ; - } - } - } - -#ifndef NDEBUG - debug_deg_lists (n_row, n_col, Row, Col, head, - min_score, n_col2-k-pivot_row_degree, max_deg) ; -#endif /* NDEBUG */ - - /* === Add up set differences for each column ======================= */ - - DEBUG3 (("** Adding set differences phase. **\n")) ; - - /* for each column in pivot row */ - rp = &A [pivot_row_start] ; - rp_end = rp + pivot_row_length ; - while (rp < rp_end) - { - /* get a column */ - col = *rp++ ; - ASSERT (COL_IS_ALIVE (col) && col != pivot_col) ; - hash = 0 ; - cur_score = 0 ; - cp = &A [Col [col].start] ; - /* compact the column */ - new_cp = cp ; - cp_end = cp + Col [col].length ; - - DEBUG4 (("Adding set diffs for Col: %d.\n", col)) ; - - while (cp < cp_end) - { - /* get a row */ - row = *cp++ ; - ASSERT(row >= 0 && row < n_row) ; - row_mark = Row [row].shared2.mark ; - /* skip if dead */ - if (ROW_IS_MARKED_DEAD (row_mark)) - { - DEBUG4 ((" Row %d, dead\n", row)) ; - continue ; - } - DEBUG4 ((" Row %d, set diff %d\n", row, row_mark-tag_mark)); - ASSERT (row_mark >= tag_mark) ; - /* compact the column */ - *new_cp++ = row ; - /* compute hash function */ - hash += row ; - /* add set difference */ - cur_score += row_mark - tag_mark ; - /* integer overflow... */ - cur_score = MIN (cur_score, n_col) ; - } - - /* recompute the column's length */ - Col [col].length = (Int) (new_cp - &A [Col [col].start]) ; - - /* === Further mass elimination ================================= */ - - if (Col [col].length == 0) - { - DEBUG4 (("further mass elimination. Col: %d\n", col)) ; - /* nothing left but the pivot row in this column */ - KILL_PRINCIPAL_COL (col) ; - pivot_row_degree -= Col [col].shared1.thickness ; - ASSERT (pivot_row_degree >= 0) ; - /* order it */ - Col [col].shared2.order = k ; - /* increment order count by column thickness */ - k += Col [col].shared1.thickness ; - } - else - { - /* === Prepare for supercolumn detection ==================== */ - - DEBUG4 (("Preparing supercol detection for Col: %d.\n", col)) ; - - /* save score so far */ - Col [col].shared2.score = cur_score ; - - /* add column to hash table, for supercolumn detection */ - hash %= n_col + 1 ; - - DEBUG4 ((" Hash = %d, n_col = %d.\n", hash, n_col)) ; - ASSERT (((Int) hash) <= n_col) ; - - head_column = head [hash] ; - if (head_column > EMPTY) - { - /* degree list "hash" is non-empty, use prev (shared3) of */ - /* first column in degree list as head of hash bucket */ - first_col = Col [head_column].shared3.headhash ; - Col [head_column].shared3.headhash = col ; - } - else - { - /* degree list "hash" is empty, use head as hash bucket */ - first_col = - (head_column + 2) ; - head [hash] = - (col + 2) ; - } - Col [col].shared4.hash_next = first_col ; - - /* save hash function in Col [col].shared3.hash */ - Col [col].shared3.hash = (Int) hash ; - ASSERT (COL_IS_ALIVE (col)) ; - } - } - - /* The approximate external column degree is now computed. */ - - /* === Supercolumn detection ======================================== */ - - DEBUG3 (("** Supercolumn detection phase. **\n")) ; - - detect_super_cols ( - -#ifndef NDEBUG - n_col, Row, -#endif /* NDEBUG */ - - Col, A, head, pivot_row_start, pivot_row_length) ; - - /* === Kill the pivotal column ====================================== */ - - KILL_PRINCIPAL_COL (pivot_col) ; - - /* === Clear mark =================================================== */ - - tag_mark = clear_mark (tag_mark+max_deg+1, max_mark, n_row, Row) ; - -#ifndef NDEBUG - DEBUG3 (("check3\n")) ; - debug_mark (n_row, Row, tag_mark, max_mark) ; -#endif /* NDEBUG */ - - /* === Finalize the new pivot row, and column scores ================ */ - - DEBUG3 (("** Finalize scores phase. **\n")) ; - - /* for each column in pivot row */ - rp = &A [pivot_row_start] ; - /* compact the pivot row */ - new_rp = rp ; - rp_end = rp + pivot_row_length ; - while (rp < rp_end) - { - col = *rp++ ; - /* skip dead columns */ - if (COL_IS_DEAD (col)) - { - continue ; - } - *new_rp++ = col ; - /* add new pivot row to column */ - A [Col [col].start + (Col [col].length++)] = pivot_row ; - - /* retrieve score so far and add on pivot row's degree. */ - /* (we wait until here for this in case the pivot */ - /* row's degree was reduced due to mass elimination). */ - cur_score = Col [col].shared2.score + pivot_row_degree ; - - /* calculate the max possible score as the number of */ - /* external columns minus the 'k' value minus the */ - /* columns thickness */ - max_score = n_col - k - Col [col].shared1.thickness ; - - /* make the score the external degree of the union-of-rows */ - cur_score -= Col [col].shared1.thickness ; - - /* make sure score is less or equal than the max score */ - cur_score = MIN (cur_score, max_score) ; - ASSERT (cur_score >= 0) ; - - /* store updated score */ - Col [col].shared2.score = cur_score ; - - /* === Place column back in degree list ========================= */ - - ASSERT (min_score >= 0) ; - ASSERT (min_score <= n_col) ; - ASSERT (cur_score >= 0) ; - ASSERT (cur_score <= n_col) ; - ASSERT (head [cur_score] >= EMPTY) ; - next_col = head [cur_score] ; - Col [col].shared4.degree_next = next_col ; - Col [col].shared3.prev = EMPTY ; - if (next_col != EMPTY) - { - Col [next_col].shared3.prev = col ; - } - head [cur_score] = col ; - - /* see if this score is less than current min */ - min_score = MIN (min_score, cur_score) ; - - } - -#ifndef NDEBUG - debug_deg_lists (n_row, n_col, Row, Col, head, - min_score, n_col2-k, max_deg) ; -#endif /* NDEBUG */ - - /* === Resurrect the new pivot row ================================== */ - - if (pivot_row_degree > 0) - { - /* update pivot row length to reflect any cols that were killed */ - /* during super-col detection and mass elimination */ - Row [pivot_row].start = pivot_row_start ; - Row [pivot_row].length = (Int) (new_rp - &A[pivot_row_start]) ; - ASSERT (Row [pivot_row].length > 0) ; - Row [pivot_row].shared1.degree = pivot_row_degree ; - Row [pivot_row].shared2.mark = 0 ; - /* pivot row is no longer dead */ - - DEBUG1 (("Resurrect Pivot_row %d deg: %d\n", - pivot_row, pivot_row_degree)) ; - } - } - - /* === All principal columns have now been ordered ====================== */ - - return (ngarbage) ; -} - - -/* ========================================================================== */ -/* === order_children ======================================================= */ -/* ========================================================================== */ - -/* - The find_ordering routine has ordered all of the principal columns (the - representatives of the supercolumns). The non-principal columns have not - yet been ordered. This routine orders those columns by walking up the - parent tree (a column is a child of the column which absorbed it). The - final permutation vector is then placed in p [0 ... n_col-1], with p [0] - being the first column, and p [n_col-1] being the last. It doesn't look - like it at first glance, but be assured that this routine takes time linear - in the number of columns. Although not immediately obvious, the time - taken by this routine is O (n_col), that is, linear in the number of - columns. Not user-callable. -*/ - -PRIVATE void order_children -( - /* === Parameters ======================================================= */ - - Int n_col, /* number of columns of A */ - Colamd_Col Col [], /* of size n_col+1 */ - Int p [] /* p [0 ... n_col-1] is the column permutation*/ -) -{ - /* === Local variables ================================================== */ - - Int i ; /* loop counter for all columns */ - Int c ; /* column index */ - Int parent ; /* index of column's parent */ - Int order ; /* column's order */ - - /* === Order each non-principal column ================================== */ - - for (i = 0 ; i < n_col ; i++) - { - /* find an un-ordered non-principal column */ - ASSERT (COL_IS_DEAD (i)) ; - if (!COL_IS_DEAD_PRINCIPAL (i) && Col [i].shared2.order == EMPTY) - { - parent = i ; - /* once found, find its principal parent */ - do - { - parent = Col [parent].shared1.parent ; - } while (!COL_IS_DEAD_PRINCIPAL (parent)) ; - - /* now, order all un-ordered non-principal columns along path */ - /* to this parent. collapse tree at the same time */ - c = i ; - /* get order of parent */ - order = Col [parent].shared2.order ; - - do - { - ASSERT (Col [c].shared2.order == EMPTY) ; - - /* order this column */ - Col [c].shared2.order = order++ ; - /* collaps tree */ - Col [c].shared1.parent = parent ; - - /* get immediate parent of this column */ - c = Col [c].shared1.parent ; - - /* continue until we hit an ordered column. There are */ - /* guarranteed not to be anymore unordered columns */ - /* above an ordered column */ - } while (Col [c].shared2.order == EMPTY) ; - - /* re-order the super_col parent to largest order for this group */ - Col [parent].shared2.order = order ; - } - } - - /* === Generate the permutation ========================================= */ - - for (c = 0 ; c < n_col ; c++) - { - p [Col [c].shared2.order] = c ; - } -} - - -/* ========================================================================== */ -/* === detect_super_cols ==================================================== */ -/* ========================================================================== */ - -/* - Detects supercolumns by finding matches between columns in the hash buckets. - Check amongst columns in the set A [row_start ... row_start + row_length-1]. - The columns under consideration are currently *not* in the degree lists, - and have already been placed in the hash buckets. - - The hash bucket for columns whose hash function is equal to h is stored - as follows: - - if head [h] is >= 0, then head [h] contains a degree list, so: - - head [h] is the first column in degree bucket h. - Col [head [h]].headhash gives the first column in hash bucket h. - - otherwise, the degree list is empty, and: - - -(head [h] + 2) is the first column in hash bucket h. - - For a column c in a hash bucket, Col [c].shared3.prev is NOT a "previous - column" pointer. Col [c].shared3.hash is used instead as the hash number - for that column. The value of Col [c].shared4.hash_next is the next column - in the same hash bucket. - - Assuming no, or "few" hash collisions, the time taken by this routine is - linear in the sum of the sizes (lengths) of each column whose score has - just been computed in the approximate degree computation. - Not user-callable. -*/ - -PRIVATE void detect_super_cols -( - /* === Parameters ======================================================= */ - -#ifndef NDEBUG - /* these two parameters are only needed when debugging is enabled: */ - Int n_col, /* number of columns of A */ - Colamd_Row Row [], /* of size n_row+1 */ -#endif /* NDEBUG */ - - Colamd_Col Col [], /* of size n_col+1 */ - Int A [], /* row indices of A */ - Int head [], /* head of degree lists and hash buckets */ - Int row_start, /* pointer to set of columns to check */ - Int row_length /* number of columns to check */ -) -{ - /* === Local variables ================================================== */ - - Int hash ; /* hash value for a column */ - Int *rp ; /* pointer to a row */ - Int c ; /* a column index */ - Int super_c ; /* column index of the column to absorb into */ - Int *cp1 ; /* column pointer for column super_c */ - Int *cp2 ; /* column pointer for column c */ - Int length ; /* length of column super_c */ - Int prev_c ; /* column preceding c in hash bucket */ - Int i ; /* loop counter */ - Int *rp_end ; /* pointer to the end of the row */ - Int col ; /* a column index in the row to check */ - Int head_column ; /* first column in hash bucket or degree list */ - Int first_col ; /* first column in hash bucket */ - - /* === Consider each column in the row ================================== */ - - rp = &A [row_start] ; - rp_end = rp + row_length ; - while (rp < rp_end) - { - col = *rp++ ; - if (COL_IS_DEAD (col)) - { - continue ; - } - - /* get hash number for this column */ - hash = Col [col].shared3.hash ; - ASSERT (hash <= n_col) ; - - /* === Get the first column in this hash bucket ===================== */ - - head_column = head [hash] ; - if (head_column > EMPTY) - { - first_col = Col [head_column].shared3.headhash ; - } - else - { - first_col = - (head_column + 2) ; - } - - /* === Consider each column in the hash bucket ====================== */ - - for (super_c = first_col ; super_c != EMPTY ; - super_c = Col [super_c].shared4.hash_next) - { - ASSERT (COL_IS_ALIVE (super_c)) ; - ASSERT (Col [super_c].shared3.hash == hash) ; - length = Col [super_c].length ; - - /* prev_c is the column preceding column c in the hash bucket */ - prev_c = super_c ; - - /* === Compare super_c with all columns after it ================ */ - - for (c = Col [super_c].shared4.hash_next ; - c != EMPTY ; c = Col [c].shared4.hash_next) - { - ASSERT (c != super_c) ; - ASSERT (COL_IS_ALIVE (c)) ; - ASSERT (Col [c].shared3.hash == hash) ; - - /* not identical if lengths or scores are different */ - if (Col [c].length != length || - Col [c].shared2.score != Col [super_c].shared2.score) - { - prev_c = c ; - continue ; - } - - /* compare the two columns */ - cp1 = &A [Col [super_c].start] ; - cp2 = &A [Col [c].start] ; - - for (i = 0 ; i < length ; i++) - { - /* the columns are "clean" (no dead rows) */ - ASSERT (ROW_IS_ALIVE (*cp1)) ; - ASSERT (ROW_IS_ALIVE (*cp2)) ; - /* row indices will same order for both supercols, */ - /* no gather scatter nessasary */ - if (*cp1++ != *cp2++) - { - break ; - } - } - - /* the two columns are different if the for-loop "broke" */ - if (i != length) - { - prev_c = c ; - continue ; - } - - /* === Got it! two columns are identical =================== */ - - ASSERT (Col [c].shared2.score == Col [super_c].shared2.score) ; - - Col [super_c].shared1.thickness += Col [c].shared1.thickness ; - Col [c].shared1.parent = super_c ; - KILL_NON_PRINCIPAL_COL (c) ; - /* order c later, in order_children() */ - Col [c].shared2.order = EMPTY ; - /* remove c from hash bucket */ - Col [prev_c].shared4.hash_next = Col [c].shared4.hash_next ; - } - } - - /* === Empty this hash bucket ======================================= */ - - if (head_column > EMPTY) - { - /* corresponding degree list "hash" is not empty */ - Col [head_column].shared3.headhash = EMPTY ; - } - else - { - /* corresponding degree list "hash" is empty */ - head [hash] = EMPTY ; - } - } -} - - -/* ========================================================================== */ -/* === garbage_collection =================================================== */ -/* ========================================================================== */ - -/* - Defragments and compacts columns and rows in the workspace A. Used when - all avaliable memory has been used while performing row merging. Returns - the index of the first free position in A, after garbage collection. The - time taken by this routine is linear is the size of the array A, which is - itself linear in the number of nonzeros in the input matrix. - Not user-callable. -*/ - -PRIVATE Int garbage_collection /* returns the new value of pfree */ -( - /* === Parameters ======================================================= */ - - Int n_row, /* number of rows */ - Int n_col, /* number of columns */ - Colamd_Row Row [], /* row info */ - Colamd_Col Col [], /* column info */ - Int A [], /* A [0 ... Alen-1] holds the matrix */ - Int *pfree /* &A [0] ... pfree is in use */ -) -{ - /* === Local variables ================================================== */ - - Int *psrc ; /* source pointer */ - Int *pdest ; /* destination pointer */ - Int j ; /* counter */ - Int r ; /* a row index */ - Int c ; /* a column index */ - Int length ; /* length of a row or column */ - -#ifndef NDEBUG - Int debug_rows ; - DEBUG2 (("Defrag..\n")) ; - for (psrc = &A[0] ; psrc < pfree ; psrc++) ASSERT (*psrc >= 0) ; - debug_rows = 0 ; -#endif /* NDEBUG */ - - /* === Defragment the columns =========================================== */ - - pdest = &A[0] ; - for (c = 0 ; c < n_col ; c++) - { - if (COL_IS_ALIVE (c)) - { - psrc = &A [Col [c].start] ; - - /* move and compact the column */ - ASSERT (pdest <= psrc) ; - Col [c].start = (Int) (pdest - &A [0]) ; - length = Col [c].length ; - for (j = 0 ; j < length ; j++) - { - r = *psrc++ ; - if (ROW_IS_ALIVE (r)) - { - *pdest++ = r ; - } - } - Col [c].length = (Int) (pdest - &A [Col [c].start]) ; - } - } - - /* === Prepare to defragment the rows =================================== */ - - for (r = 0 ; r < n_row ; r++) - { - if (ROW_IS_DEAD (r) || (Row [r].length == 0)) - { - /* This row is already dead, or is of zero length. Cannot compact - * a row of zero length, so kill it. NOTE: in the current version, - * there are no zero-length live rows. Kill the row (for the first - * time, or again) just to be safe. */ - KILL_ROW (r) ; - } - else - { - /* save first column index in Row [r].shared2.first_column */ - psrc = &A [Row [r].start] ; - Row [r].shared2.first_column = *psrc ; - ASSERT (ROW_IS_ALIVE (r)) ; - /* flag the start of the row with the one's complement of row */ - *psrc = ONES_COMPLEMENT (r) ; -#ifndef NDEBUG - debug_rows++ ; -#endif /* NDEBUG */ - } - } - - /* === Defragment the rows ============================================== */ - - psrc = pdest ; - while (psrc < pfree) - { - /* find a negative number ... the start of a row */ - if (*psrc++ < 0) - { - psrc-- ; - /* get the row index */ - r = ONES_COMPLEMENT (*psrc) ; - ASSERT (r >= 0 && r < n_row) ; - /* restore first column index */ - *psrc = Row [r].shared2.first_column ; - ASSERT (ROW_IS_ALIVE (r)) ; - ASSERT (Row [r].length > 0) ; - /* move and compact the row */ - ASSERT (pdest <= psrc) ; - Row [r].start = (Int) (pdest - &A [0]) ; - length = Row [r].length ; - for (j = 0 ; j < length ; j++) - { - c = *psrc++ ; - if (COL_IS_ALIVE (c)) - { - *pdest++ = c ; - } - } - Row [r].length = (Int) (pdest - &A [Row [r].start]) ; - ASSERT (Row [r].length > 0) ; -#ifndef NDEBUG - debug_rows-- ; -#endif /* NDEBUG */ - } - } - /* ensure we found all the rows */ - ASSERT (debug_rows == 0) ; - - /* === Return the new value of pfree ==================================== */ - - return ((Int) (pdest - &A [0])) ; -} - - -/* ========================================================================== */ -/* === clear_mark =========================================================== */ -/* ========================================================================== */ - -/* - Clears the Row [].shared2.mark array, and returns the new tag_mark. - Return value is the new tag_mark. Not user-callable. -*/ - -PRIVATE Int clear_mark /* return the new value for tag_mark */ -( - /* === Parameters ======================================================= */ - - Int tag_mark, /* new value of tag_mark */ - Int max_mark, /* max allowed value of tag_mark */ - - Int n_row, /* number of rows in A */ - Colamd_Row Row [] /* Row [0 ... n_row-1].shared2.mark is set to zero */ -) -{ - /* === Local variables ================================================== */ - - Int r ; - - if (tag_mark <= 0 || tag_mark >= max_mark) - { - for (r = 0 ; r < n_row ; r++) - { - if (ROW_IS_ALIVE (r)) - { - Row [r].shared2.mark = 0 ; - } - } - tag_mark = 1 ; - } - - return (tag_mark) ; -} - - -/* ========================================================================== */ -/* === print_report ========================================================= */ -/* ========================================================================== */ - -PRIVATE void print_report -( - char *method, - Int stats [COLAMD_STATS] -) -{ - - Int i1, i2, i3 ; - - PRINTF (("\n%s version %d.%d, %s: ", method, - COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE)) ; - - if (!stats) - { - PRINTF (("No statistics available.\n")) ; - return ; - } - - i1 = stats [COLAMD_INFO1] ; - i2 = stats [COLAMD_INFO2] ; - i3 = stats [COLAMD_INFO3] ; - - if (stats [COLAMD_STATUS] >= 0) - { - PRINTF (("OK. ")) ; - } - else - { - PRINTF (("ERROR. ")) ; - } - - switch (stats [COLAMD_STATUS]) - { - - case COLAMD_OK_BUT_JUMBLED: - - PRINTF(("Matrix has unsorted or duplicate row indices.\n")) ; - - PRINTF(("%s: number of duplicate or out-of-order row indices: %d\n", - method, i3)) ; - - PRINTF(("%s: last seen duplicate or out-of-order row index: %d\n", - method, INDEX (i2))) ; - - PRINTF(("%s: last seen in column: %d", - method, INDEX (i1))) ; - - /* no break - fall through to next case instead */ - - case COLAMD_OK: - - PRINTF(("\n")) ; - - PRINTF(("%s: number of dense or empty rows ignored: %d\n", - method, stats [COLAMD_DENSE_ROW])) ; - - PRINTF(("%s: number of dense or empty columns ignored: %d\n", - method, stats [COLAMD_DENSE_COL])) ; - - PRINTF(("%s: number of garbage collections performed: %d\n", - method, stats [COLAMD_DEFRAG_COUNT])) ; - break ; - - case COLAMD_ERROR_A_not_present: - - PRINTF(("Array A (row indices of matrix) not present.\n")) ; - break ; - - case COLAMD_ERROR_p_not_present: - - PRINTF(("Array p (column pointers for matrix) not present.\n")) ; - break ; - - case COLAMD_ERROR_nrow_negative: - - PRINTF(("Invalid number of rows (%d).\n", i1)) ; - break ; - - case COLAMD_ERROR_ncol_negative: - - PRINTF(("Invalid number of columns (%d).\n", i1)) ; - break ; - - case COLAMD_ERROR_nnz_negative: - - PRINTF(("Invalid number of nonzero entries (%d).\n", i1)) ; - break ; - - case COLAMD_ERROR_p0_nonzero: - - PRINTF(("Invalid column pointer, p [0] = %d, must be zero.\n", i1)); - break ; - - case COLAMD_ERROR_A_too_small: - - PRINTF(("Array A too small.\n")) ; - PRINTF((" Need Alen >= %d, but given only Alen = %d.\n", - i1, i2)) ; - break ; - - case COLAMD_ERROR_col_length_negative: - - PRINTF - (("Column %d has a negative number of nonzero entries (%d).\n", - INDEX (i1), i2)) ; - break ; - - case COLAMD_ERROR_row_index_out_of_bounds: - - PRINTF - (("Row index (row %d) out of bounds (%d to %d) in column %d.\n", - INDEX (i2), INDEX (0), INDEX (i3-1), INDEX (i1))) ; - break ; - - case COLAMD_ERROR_out_of_memory: - - PRINTF(("Out of memory.\n")) ; - break ; - - /* v2.4: internal-error case deleted */ - } -} - - - - -/* ========================================================================== */ -/* === colamd debugging routines ============================================ */ -/* ========================================================================== */ - -/* When debugging is disabled, the remainder of this file is ignored. */ - -#ifndef NDEBUG - - -/* ========================================================================== */ -/* === debug_structures ===================================================== */ -/* ========================================================================== */ - -/* - At this point, all empty rows and columns are dead. All live columns - are "clean" (containing no dead rows) and simplicial (no supercolumns - yet). Rows may contain dead columns, but all live rows contain at - least one live column. -*/ - -PRIVATE void debug_structures -( - /* === Parameters ======================================================= */ - - Int n_row, - Int n_col, - Colamd_Row Row [], - Colamd_Col Col [], - Int A [], - Int n_col2 -) -{ - /* === Local variables ================================================== */ - - Int i ; - Int c ; - Int *cp ; - Int *cp_end ; - Int len ; - Int score ; - Int r ; - Int *rp ; - Int *rp_end ; - Int deg ; - - /* === Check A, Row, and Col ============================================ */ - - for (c = 0 ; c < n_col ; c++) - { - if (COL_IS_ALIVE (c)) - { - len = Col [c].length ; - score = Col [c].shared2.score ; - DEBUG4 (("initial live col %5d %5d %5d\n", c, len, score)) ; - ASSERT (len > 0) ; - ASSERT (score >= 0) ; - ASSERT (Col [c].shared1.thickness == 1) ; - cp = &A [Col [c].start] ; - cp_end = cp + len ; - while (cp < cp_end) - { - r = *cp++ ; - ASSERT (ROW_IS_ALIVE (r)) ; - } - } - else - { - i = Col [c].shared2.order ; - ASSERT (i >= n_col2 && i < n_col) ; - } - } - - for (r = 0 ; r < n_row ; r++) - { - if (ROW_IS_ALIVE (r)) - { - i = 0 ; - len = Row [r].length ; - deg = Row [r].shared1.degree ; - ASSERT (len > 0) ; - ASSERT (deg > 0) ; - rp = &A [Row [r].start] ; - rp_end = rp + len ; - while (rp < rp_end) - { - c = *rp++ ; - if (COL_IS_ALIVE (c)) - { - i++ ; - } - } - ASSERT (i > 0) ; - } - } -} - - -/* ========================================================================== */ -/* === debug_deg_lists ====================================================== */ -/* ========================================================================== */ - -/* - Prints the contents of the degree lists. Counts the number of columns - in the degree list and compares it to the total it should have. Also - checks the row degrees. -*/ - -PRIVATE void debug_deg_lists -( - /* === Parameters ======================================================= */ - - Int n_row, - Int n_col, - Colamd_Row Row [], - Colamd_Col Col [], - Int head [], - Int min_score, - Int should, - Int max_deg -) -{ - /* === Local variables ================================================== */ - - Int deg ; - Int col ; - Int have ; - Int row ; - - /* === Check the degree lists =========================================== */ - - if (n_col > 10000 && colamd_debug <= 0) - { - return ; - } - have = 0 ; - DEBUG4 (("Degree lists: %d\n", min_score)) ; - for (deg = 0 ; deg <= n_col ; deg++) - { - col = head [deg] ; - if (col == EMPTY) - { - continue ; - } - DEBUG4 (("%d:", deg)) ; - while (col != EMPTY) - { - DEBUG4 ((" %d", col)) ; - have += Col [col].shared1.thickness ; - ASSERT (COL_IS_ALIVE (col)) ; - col = Col [col].shared4.degree_next ; - } - DEBUG4 (("\n")) ; - } - DEBUG4 (("should %d have %d\n", should, have)) ; - ASSERT (should == have) ; - - /* === Check the row degrees ============================================ */ - - if (n_row > 10000 && colamd_debug <= 0) - { - return ; - } - for (row = 0 ; row < n_row ; row++) - { - if (ROW_IS_ALIVE (row)) - { - ASSERT (Row [row].shared1.degree <= max_deg) ; - } - } -} - - -/* ========================================================================== */ -/* === debug_mark =========================================================== */ -/* ========================================================================== */ - -/* - Ensures that the tag_mark is less that the maximum and also ensures that - each entry in the mark array is less than the tag mark. -*/ - -PRIVATE void debug_mark -( - /* === Parameters ======================================================= */ - - Int n_row, - Colamd_Row Row [], - Int tag_mark, - Int max_mark -) -{ - /* === Local variables ================================================== */ - - Int r ; - - /* === Check the Row marks ============================================== */ - - ASSERT (tag_mark > 0 && tag_mark <= max_mark) ; - if (n_row > 10000 && colamd_debug <= 0) - { - return ; - } - for (r = 0 ; r < n_row ; r++) - { - ASSERT (Row [r].shared2.mark < tag_mark) ; - } -} - - -/* ========================================================================== */ -/* === debug_matrix ========================================================= */ -/* ========================================================================== */ - -/* - Prints out the contents of the columns and the rows. -*/ - -PRIVATE void debug_matrix -( - /* === Parameters ======================================================= */ - - Int n_row, - Int n_col, - Colamd_Row Row [], - Colamd_Col Col [], - Int A [] -) -{ - /* === Local variables ================================================== */ - - Int r ; - Int c ; - Int *rp ; - Int *rp_end ; - Int *cp ; - Int *cp_end ; - - /* === Dump the rows and columns of the matrix ========================== */ - - if (colamd_debug < 3) - { - return ; - } - DEBUG3 (("DUMP MATRIX:\n")) ; - for (r = 0 ; r < n_row ; r++) - { - DEBUG3 (("Row %d alive? %d\n", r, ROW_IS_ALIVE (r))) ; - if (ROW_IS_DEAD (r)) - { - continue ; - } - DEBUG3 (("start %d length %d degree %d\n", - Row [r].start, Row [r].length, Row [r].shared1.degree)) ; - rp = &A [Row [r].start] ; - rp_end = rp + Row [r].length ; - while (rp < rp_end) - { - c = *rp++ ; - DEBUG4 ((" %d col %d\n", COL_IS_ALIVE (c), c)) ; - } - } - - for (c = 0 ; c < n_col ; c++) - { - DEBUG3 (("Col %d alive? %d\n", c, COL_IS_ALIVE (c))) ; - if (COL_IS_DEAD (c)) - { - continue ; - } - DEBUG3 (("start %d length %d shared1 %d shared2 %d\n", - Col [c].start, Col [c].length, - Col [c].shared1.thickness, Col [c].shared2.score)) ; - cp = &A [Col [c].start] ; - cp_end = cp + Col [c].length ; - while (cp < cp_end) - { - r = *cp++ ; - DEBUG4 ((" %d row %d\n", ROW_IS_ALIVE (r), r)) ; - } - } -} - -PRIVATE void colamd_get_debug -( - char *method -) -{ - FILE *f ; - colamd_debug = 0 ; /* no debug printing */ - f = fopen ("debug", "r") ; - if (f == (FILE *) NULL) - { - colamd_debug = 0 ; - } - else - { - fscanf (f, "%d", &colamd_debug) ; - fclose (f) ; - } - DEBUG0 (("%s: debug version, D = %d (THIS WILL BE SLOW!)\n", - method, colamd_debug)) ; -} - -#endif /* NDEBUG */ diff --git a/resources/3rdparty/glpk-4.53/src/colamd/colamd.h b/resources/3rdparty/glpk-4.53/src/colamd/colamd.h deleted file mode 100644 index 511735e5c..000000000 --- a/resources/3rdparty/glpk-4.53/src/colamd/colamd.h +++ /dev/null @@ -1,69 +0,0 @@ -/* colamd.h */ - -/* Written by Andrew Makhorin . */ - -#ifndef COLAMD_H -#define COLAMD_H - -#define _GLPSTD_STDIO -#include "env.h" - -#define COLAMD_DATE "Nov 1, 2007" -#define COLAMD_VERSION_CODE(main, sub) ((main) * 1000 + (sub)) -#define COLAMD_MAIN_VERSION 2 -#define COLAMD_SUB_VERSION 7 -#define COLAMD_SUBSUB_VERSION 1 -#define COLAMD_VERSION \ - COLAMD_VERSION_CODE(COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION) - -#define COLAMD_KNOBS 20 -#define COLAMD_STATS 20 -#define COLAMD_DENSE_ROW 0 -#define COLAMD_DENSE_COL 1 -#define COLAMD_AGGRESSIVE 2 -#define COLAMD_DEFRAG_COUNT 2 -#define COLAMD_STATUS 3 -#define COLAMD_INFO1 4 -#define COLAMD_INFO2 5 -#define COLAMD_INFO3 6 - -#define COLAMD_OK (0) -#define COLAMD_OK_BUT_JUMBLED (1) -#define COLAMD_ERROR_A_not_present (-1) -#define COLAMD_ERROR_p_not_present (-2) -#define COLAMD_ERROR_nrow_negative (-3) -#define COLAMD_ERROR_ncol_negative (-4) -#define COLAMD_ERROR_nnz_negative (-5) -#define COLAMD_ERROR_p0_nonzero (-6) -#define COLAMD_ERROR_A_too_small (-7) -#define COLAMD_ERROR_col_length_negative (-8) -#define COLAMD_ERROR_row_index_out_of_bounds (-9) -#define COLAMD_ERROR_out_of_memory (-10) -#define COLAMD_ERROR_internal_error (-999) - -#define colamd_recommended _glp_colamd_recommended -size_t colamd_recommended(int nnz, int n_row, int n_col); - -#define colamd_set_defaults _glp_colamd_set_defaults -void colamd_set_defaults(double knobs [COLAMD_KNOBS]); - -#define colamd _glp_colamd -int colamd(int n_row, int n_col, int Alen, int A[], int p[], - double knobs[COLAMD_KNOBS], int stats[COLAMD_STATS]); - -#define symamd _glp_symamd -int symamd(int n, int A[], int p[], int perm[], - double knobs[COLAMD_KNOBS], int stats[COLAMD_STATS], - void *(*allocate)(size_t, size_t), void(*release)(void *)); - -#define colamd_report _glp_colamd_report -void colamd_report(int stats[COLAMD_STATS]); - -#define symamd_report _glp_symamd_report -void symamd_report(int stats[COLAMD_STATS]); - -#define colamd_printf xprintf - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/draft.h b/resources/3rdparty/glpk-4.53/src/draft.h deleted file mode 100644 index b453acd48..000000000 --- a/resources/3rdparty/glpk-4.53/src/draft.h +++ /dev/null @@ -1,32 +0,0 @@ -/* draft.h */ - -/* (reserved for copyright notice) */ - -#ifndef DRAFT_H -#define DRAFT_H - -#include "glpk.h" - -#if 1 /* 28/XI-2009 */ -int _glp_analyze_row(glp_prob *P, int len, const int ind[], - const double val[], int type, double rhs, double eps, int *_piv, - double *_x, double *_dx, double *_y, double *_dy, double *_dz); -/* simulate one iteration of dual simplex method */ -#endif - -#if 1 /* 08/XII-2009 */ -void _glp_mpl_init_rand(glp_tran *tran, int seed); -#endif - -#define glp_skpgen _glp_skpgen -void glp_skpgen(int n, int r, int type, int v, int s, int a[], - int *b, int c[]); -/* Pisinger's 0-1 single knapsack problem generator */ - -#if 1 /* 28/V-2010 */ -int _glp_intopt1(glp_prob *P, const glp_iocp *parm); -#endif - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/env/alloc.c b/resources/3rdparty/glpk-4.53/src/env/alloc.c deleted file mode 100644 index 5a9d5b766..000000000 --- a/resources/3rdparty/glpk-4.53/src/env/alloc.c +++ /dev/null @@ -1,252 +0,0 @@ -/* alloc.c (dynamic memory allocation) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" - -#define ALIGN 16 -/* some processors need data to be properly aligned, so this macro - * defines the alignment boundary, in bytes, provided by glpk memory - * allocation routines; looks like 16-byte alignment boundary is - * sufficient for all 32- and 64-bit platforms (8-byte boundary is not - * sufficient for some 64-bit platforms because of jmp_buf) */ - -#define MBD_SIZE (((sizeof(MBD) + (ALIGN - 1)) / ALIGN) * ALIGN) -/* size of memory block descriptor, in bytes, rounded up to multiple - * of the alignment boundary */ - -/*********************************************************************** -* dma - dynamic memory allocation (basic routine) -* -* This routine performs dynamic memory allocation. It is similar to -* the standard realloc function, however, it provides every allocated -* memory block with a descriptor, which is used for sanity checks on -* reallocating/freeing previously allocated memory blocks as well as -* for book-keeping the memory usage statistics. */ - -static void *dma(const char *func, void *ptr, size_t size) -{ ENV *env = get_env_ptr(); - MBD *mbd; - if (ptr == NULL) - { /* new memory block will be allocated */ - mbd = NULL; - } - else - { /* allocated memory block will be reallocated or freed */ - /* get pointer to the block descriptor */ - mbd = (MBD *)((char *)ptr - MBD_SIZE); - /* make sure that the block descriptor is valid */ - if (mbd->self != mbd) - xerror("%s: ptr = %p; invalid pointer\n", func, ptr); - /* remove the block from the linked list */ - mbd->self = NULL; - if (mbd->prev == NULL) - env->mem_ptr = mbd->next; - else - mbd->prev->next = mbd->next; - if (mbd->next == NULL) - ; - else - mbd->next->prev = mbd->prev; - /* decrease usage counts */ - if (!(env->mem_count >= 1 && env->mem_total >= mbd->size)) - xerror("%s: memory allocation error\n", func); - env->mem_count--; - env->mem_total -= mbd->size; - if (size == 0) - { /* free the memory block */ - free(mbd); - return NULL; - } - } - /* allocate/reallocate memory block */ - if (size > SIZE_T_MAX - MBD_SIZE) - xerror("%s: block too large\n", func); - size += MBD_SIZE; - if (size > env->mem_limit - env->mem_total) - xerror("%s: memory allocation limit exceeded\n", func); - if (env->mem_count == INT_MAX) - xerror("%s: too many memory blocks allocated\n", func); - mbd = (mbd == NULL ? malloc(size) : realloc(mbd, size)); - if (mbd == NULL) - xerror("%s: no memory available\n", func); - /* setup the block descriptor */ - mbd->size = size; - mbd->self = mbd; - mbd->prev = NULL; - mbd->next = env->mem_ptr; - /* add the block to the beginning of the linked list */ - if (mbd->next != NULL) - mbd->next->prev = mbd; - env->mem_ptr = mbd; - /* increase usage counts */ - env->mem_count++; - if (env->mem_cpeak < env->mem_count) - env->mem_cpeak = env->mem_count; - env->mem_total += size; - if (env->mem_tpeak < env->mem_total) - env->mem_tpeak = env->mem_total; - return (char *)mbd + MBD_SIZE; -} - -/*********************************************************************** -* NAME -* -* glp_alloc - allocate memory block -* -* SYNOPSIS -* -* void *glp_alloc(int n, int size); -* -* DESCRIPTION -* -* The routine glp_alloc allocates a memory block of n * size bytes -* long. -* -* Note that being allocated the memory block contains arbitrary data -* (not binary zeros!). -* -* RETURNS -* -* The routine glp_alloc returns a pointer to the block allocated. -* To free this block the routine glp_free (not free!) must be used. */ - -void *glp_alloc(int n, int size) -{ if (n < 1) - xerror("glp_alloc: n = %d; invalid parameter\n", n); - if (size < 1) - xerror("glp_alloc: size = %d; invalid parameter\n", size); - if ((size_t)n > SIZE_T_MAX / (size_t)size) - xerror("glp_alloc: n = %d, size = %d; block too large\n", - n, size); - return dma("glp_alloc", NULL, (size_t)n * (size_t)size); -} - -/**********************************************************************/ - -void *glp_realloc(void *ptr, int n, int size) -{ /* reallocate memory block */ - if (ptr == NULL) - xerror("glp_realloc: ptr = %p; invalid pointer\n", ptr); - if (n < 1) - xerror("glp_realloc: n = %d; invalid parameter\n", n); - if (size < 1) - xerror("glp_realloc: size = %d; invalid parameter\n", size); - if ((size_t)n > SIZE_T_MAX / (size_t)size) - xerror("glp_realloc: n = %d, size = %d; block too large\n", - n, size); - return dma("glp_realloc", ptr, (size_t)n * (size_t)size); -} - -/*********************************************************************** -* NAME -* -* glp_free - free (deallocate) memory block -* -* SYNOPSIS -* -* void glp_free(void *ptr); -* -* DESCRIPTION -* -* The routine glp_free frees (deallocates) a memory block pointed to -* by ptr, which was previuosly allocated by the routine glp_alloc or -* reallocated by the routine glp_realloc. */ - -void glp_free(void *ptr) -{ if (ptr == NULL) - xerror("glp_free: ptr = %p; invalid pointer\n", ptr); - dma("glp_free", ptr, 0); - return; -} - -/*********************************************************************** -* NAME -* -* glp_mem_limit - set memory usage limit -* -* SYNOPSIS -* -* void glp_mem_limit(int limit); -* -* DESCRIPTION -* -* The routine glp_mem_limit limits the amount of memory available for -* dynamic allocation (in GLPK routines) to limit megabytes. */ - -void glp_mem_limit(int limit) -{ ENV *env = get_env_ptr(); - if (limit < 1) - xerror("glp_mem_limit: limit = %d; invalid parameter\n", - limit); - if ((size_t)limit <= (SIZE_T_MAX >> 20)) - env->mem_limit = (size_t)limit << 20; - else - env->mem_limit = SIZE_T_MAX; - return; -} - -/*********************************************************************** -* NAME -* -* glp_mem_usage - get memory usage information -* -* SYNOPSIS -* -* void glp_mem_usage(int *count, int *cpeak, size_t *total, -* size_t *tpeak); -* -* DESCRIPTION -* -* The routine glp_mem_usage reports some information about utilization -* of the memory by GLPK routines. Information is stored to locations -* specified by corresponding parameters (see below). Any parameter can -* be specified as NULL, in which case its value is not stored. -* -* *count is the number of the memory blocks currently allocated by the -* routines glp_malloc and glp_calloc (one call to glp_malloc or -* glp_calloc results in allocating one memory block). -* -* *cpeak is the peak value of *count reached since the initialization -* of the GLPK library environment. -* -* *total is the total amount, in bytes, of the memory blocks currently -* allocated by the routines glp_malloc and glp_calloc. -* -* *tpeak is the peak value of *total reached since the initialization -* of the GLPK library envirionment. */ - -void glp_mem_usage(int *count, int *cpeak, size_t *total, - size_t *tpeak) -{ ENV *env = get_env_ptr(); - if (count != NULL) - *count = env->mem_count; - if (cpeak != NULL) - *cpeak = env->mem_cpeak; - if (total != NULL) - *total = env->mem_total; - if (tpeak != NULL) - *tpeak = env->mem_tpeak; - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/env/dlsup.c b/resources/3rdparty/glpk-4.53/src/env/dlsup.c deleted file mode 100644 index 0987bd5cf..000000000 --- a/resources/3rdparty/glpk-4.53/src/env/dlsup.c +++ /dev/null @@ -1,167 +0,0 @@ -/* dlsup.c (dynamic linking support) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2008, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "env.h" - -/* GNU version ********************************************************/ - -#if defined(HAVE_LTDL) - -#include - -void *xdlopen(const char *module) -{ /* open dynamically linked library */ - void *h = NULL; - if (lt_dlinit() != 0) - { put_err_msg(lt_dlerror()); - goto done; - } - h = lt_dlopen(module); - if (h == NULL) - { put_err_msg(lt_dlerror()); - if (lt_dlexit() != 0) - xerror("xdlopen: %s\n", lt_dlerror()); - } -done: return h; -} - -void *xdlsym(void *h, const char *symbol) -{ /* obtain address of symbol from dynamically linked library */ - void *ptr; - xassert(h != NULL); - ptr = lt_dlsym(h, symbol); - if (ptr == NULL) - xerror("xdlsym: %s: %s\n", symbol, lt_dlerror()); - return ptr; -} - -void xdlclose(void *h) -{ /* close dynamically linked library */ - xassert(h != NULL); - if (lt_dlclose(h) != 0) - xerror("xdlclose: %s\n", lt_dlerror()); - if (lt_dlexit() != 0) - xerror("xdlclose: %s\n", lt_dlerror()); - return; -} - -/* POSIX version ******************************************************/ - -#elif defined(HAVE_DLFCN) - -#include - -void *xdlopen(const char *module) -{ /* open dynamically linked library */ - void *h; - h = dlopen(module, RTLD_NOW); - if (h == NULL) - put_err_msg(dlerror()); - return h; -} - -void *xdlsym(void *h, const char *symbol) -{ /* obtain address of symbol from dynamically linked library */ - void *ptr; - xassert(h != NULL); - ptr = dlsym(h, symbol); - if (ptr == NULL) - xerror("xdlsym: %s: %s\n", symbol, dlerror()); - return ptr; -} - -void xdlclose(void *h) -{ /* close dynamically linked library */ - xassert(h != NULL); - if (dlclose(h) != 0) - xerror("xdlclose: %s\n", dlerror()); - return; -} - -/* MS Windows version *************************************************/ - -#elif defined(__WOE__) - -#include - -void *xdlopen(const char *module) -{ /* open dynamically linked library */ - void *h; - h = LoadLibrary(module); - if (h == NULL) - { char msg[20]; - sprintf(msg, "Error %d", GetLastError()); - put_err_msg(msg); - } - return h; -} - -void *xdlsym(void *h, const char *symbol) -{ /* obtain address of symbol from dynamically linked library */ - void *ptr; - xassert(h != NULL); - ptr = GetProcAddress(h, symbol); - if (ptr == NULL) - xerror("xdlsym: %s: Error %d\n", symbol, GetLastError()); - return ptr; -} - -void xdlclose(void *h) -{ /* close dynamically linked library */ - xassert(h != NULL); - if (!FreeLibrary(h)) - xerror("xdlclose: Error %d\n", GetLastError()); - return; -} - -/* NULL version *******************************************************/ - -#else - -void *xdlopen(const char *module) -{ /* open dynamically linked library */ - xassert(module == module); - put_err_msg("Shared libraries not supported"); - return NULL; -} - -void *xdlsym(void *h, const char *symbol) -{ /* obtain address of symbol from dynamically linked library */ - xassert(h != h); - xassert(symbol != symbol); - return NULL; -} - -void xdlclose(void *h) -{ /* close dynamically linked library */ - xassert(h != h); - return; -} - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/env/env.c b/resources/3rdparty/glpk-4.53/src/env/env.c deleted file mode 100644 index 56bd7540b..000000000 --- a/resources/3rdparty/glpk-4.53/src/env/env.c +++ /dev/null @@ -1,237 +0,0 @@ -/* env.c (GLPK environment initialization/termination) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "glpk.h" -#include "env.h" - -/*********************************************************************** -* NAME -* -* glp_init_env - initialize GLPK environment -* -* SYNOPSIS -* -* int glp_init_env(void); -* -* DESCRIPTION -* -* The routine glp_init_env initializes the GLPK environment. Normally -* the application program does not need to call this routine, because -* it is called automatically on the first call to any API routine. -* -* RETURNS -* -* The routine glp_init_env returns one of the following codes: -* -* 0 - initialization successful; -* 1 - environment has been already initialized; -* 2 - initialization failed (insufficient memory); -* 3 - initialization failed (unsupported programming model). */ - -int glp_init_env(void) -{ ENV *env; - int ok; - /* check if the programming model is supported */ - ok = (CHAR_BIT == 8 && sizeof(char) == 1 && - sizeof(short) == 2 && sizeof(int) == 4 && - (sizeof(void *) == 4 || sizeof(void *) == 8)); - if (!ok) - return 3; - /* check if the environment is already initialized */ - if (tls_get_ptr() != NULL) - return 1; - /* allocate and initialize the environment block */ - env = malloc(sizeof(ENV)); - if (env == NULL) - return 2; - memset(env, 0, sizeof(ENV)); - sprintf(env->version, "%d.%d", - GLP_MAJOR_VERSION, GLP_MINOR_VERSION); - env->self = env; - env->term_buf = malloc(TBUF_SIZE); - if (env->term_buf == NULL) - { free(env); - return 2; - } - env->term_out = GLP_ON; - env->term_hook = NULL; - env->term_info = NULL; - env->tee_file = NULL; - env->err_file = NULL; - env->err_line = 0; - env->err_hook = NULL; - env->err_info = NULL; - env->err_buf = malloc(EBUF_SIZE); - if (env->err_buf == NULL) - { free(env->term_buf); - free(env); - return 2; - } - env->err_buf[0] = '\0'; - env->mem_limit = SIZE_T_MAX; - env->mem_ptr = NULL; - env->mem_count = env->mem_cpeak = 0; - env->mem_total = env->mem_tpeak = 0; - env->h_odbc = env->h_mysql = NULL; - /* save pointer to the environment block */ - tls_set_ptr(env); - /* initialization successful */ - return 0; -} - -/*********************************************************************** -* NAME -* -* get_env_ptr - retrieve pointer to environment block -* -* SYNOPSIS -* -* #include "env.h" -* ENV *get_env_ptr(void); -* -* DESCRIPTION -* -* The routine get_env_ptr retrieves and returns a pointer to the GLPK -* environment block. -* -* If the GLPK environment has not been initialized yet, the routine -* performs initialization. If initialization fails, the routine prints -* an error message to stderr and terminates the program. -* -* RETURNS -* -* The routine returns a pointer to the environment block. */ - -ENV *get_env_ptr(void) -{ ENV *env = tls_get_ptr(); - /* check if the environment has been initialized */ - if (env == NULL) - { /* not initialized yet; perform initialization */ - if (glp_init_env() != 0) - { /* initialization failed; display an error message */ - fprintf(stderr, "GLPK initialization failed\n"); - fflush(stderr); - /* and abnormally terminate the program */ - abort(); - } - /* initialization successful; retrieve the pointer */ - env = tls_get_ptr(); - } - /* check if the environment block is valid */ - if (env->self != env) - { fprintf(stderr, "Invalid GLPK environment\n"); - fflush(stderr); - abort(); - } - return env; -} - -/*********************************************************************** -* NAME -* -* glp_version - determine library version -* -* SYNOPSIS -* -* const char *glp_version(void); -* -* RETURNS -* -* The routine glp_version returns a pointer to a null-terminated -* character string, which specifies the version of the GLPK library in -* the form "X.Y", where X is the major version number, and Y is the -* minor version number, for example, "4.16". */ - -const char *glp_version(void) -{ ENV *env = get_env_ptr(); - return env->version; -} - -/*********************************************************************** -* NAME -* -* glp_free_env - free GLPK environment -* -* SYNOPSIS -* -* int glp_free_env(void); -* -* DESCRIPTION -* -* The routine glp_free_env frees all resources used by GLPK routines -* (memory blocks, etc.) which are currently still in use. -* -* Normally the application program does not need to call this routine, -* because GLPK routines always free all unused resources. However, if -* the application program even has deleted all problem objects, there -* will be several memory blocks still allocated for the library needs. -* For some reasons the application program may want GLPK to free this -* memory, in which case it should call glp_free_env. -* -* Note that a call to glp_free_env invalidates all problem objects as -* if no GLPK routine were called. -* -* RETURNS -* -* 0 - termination successful; -* 1 - environment is inactive (was not initialized). */ - -int glp_free_env(void) -{ ENV *env = tls_get_ptr(); - MBD *desc; - /* check if the environment is active */ - if (env == NULL) - return 1; - /* check if the environment block is valid */ - if (env->self != env) - { fprintf(stderr, "Invalid GLPK environment\n"); - fflush(stderr); - abort(); - } - /* close handles to shared libraries */ - if (env->h_odbc != NULL) - xdlclose(env->h_odbc); - if (env->h_mysql != NULL) - xdlclose(env->h_mysql); - /* free memory blocks which are still allocated */ - while (env->mem_ptr != NULL) - { desc = env->mem_ptr; - env->mem_ptr = desc->next; - free(desc); - } - /* close text file used for copying terminal output */ - if (env->tee_file != NULL) - fclose(env->tee_file); - /* invalidate the environment block */ - env->self = NULL; - /* free memory allocated to the environment block */ - free(env->term_buf); - free(env->err_buf); - free(env); - /* reset a pointer to the environment block */ - tls_set_ptr(NULL); - /* termination successful */ - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/env/env.h b/resources/3rdparty/glpk-4.53/src/env/env.h deleted file mode 100644 index 2c013dce7..000000000 --- a/resources/3rdparty/glpk-4.53/src/env/env.h +++ /dev/null @@ -1,258 +0,0 @@ -/* env.h (GLPK environment) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef ENV_H -#define ENV_H - -#include "stdc.h" - -typedef struct ENV ENV; -typedef struct MBD MBD; - -#define SIZE_T_MAX (~(size_t)0) -/* largest value of size_t type */ - -#define TBUF_SIZE 4096 -/* terminal output buffer size, in bytes */ - -#define EBUF_SIZE 1024 -/* error message buffer size, in bytes */ - -/* enable/disable flag: */ -#define GLP_ON 1 -#define GLP_OFF 0 - -struct ENV -{ /* GLPK environment block */ - char version[7+1]; - /* version string returned by the routine glp_version */ - ENV *self; - /* pointer to this block to check its validity */ - /*--------------------------------------------------------------*/ - /* terminal output */ - char *term_buf; /* char term_buf[TBUF_SIZE]; */ - /* terminal output buffer */ - int term_out; - /* flag to enable/disable terminal output */ - int (*term_hook)(void *info, const char *s); - /* user-defined routine to intercept terminal output */ - void *term_info; - /* transit pointer (cookie) passed to the routine term_hook */ - FILE *tee_file; - /* output stream used to copy terminal output */ - /*--------------------------------------------------------------*/ - /* error handling */ - const char *err_file; - /* value of the __FILE__ macro passed to glp_error */ - int err_line; - /* value of the __LINE__ macro passed to glp_error */ - void (*err_hook)(void *info); - /* user-defined routine to intercept abnormal termination */ - void *err_info; - /* transit pointer (cookie) passed to the routine err_hook */ - char *err_buf; /* char err_buf[EBUF_SIZE]; */ - /* buffer to store error messages (used by I/O routines) */ - /*--------------------------------------------------------------*/ - /* dynamic memory allocation */ - size_t mem_limit; - /* maximal amount of memory, in bytes, available for dynamic - * allocation */ - MBD *mem_ptr; - /* pointer to the linked list of allocated memory blocks */ - int mem_count; - /* total number of currently allocated memory blocks */ - int mem_cpeak; - /* peak value of mem_count */ - size_t mem_total; - /* total amount of currently allocated memory, in bytes; it is - * the sum of the size field over all memory block descriptors */ - size_t mem_tpeak; - /* peak value of mem_total */ - /*--------------------------------------------------------------*/ - /* dynamic linking support (optional) */ - void *h_odbc; - /* handle to ODBC shared library */ - void *h_mysql; - /* handle to MySQL shared library */ -}; - -struct MBD -{ /* memory block descriptor */ - size_t size; - /* size of block, in bytes, including descriptor */ - MBD *self; - /* pointer to this descriptor to check its validity */ - MBD *prev; - /* pointer to previous memory block descriptor */ - MBD *next; - /* pointer to next memory block descriptor */ -}; - -#define get_env_ptr _glp_get_env_ptr -ENV *get_env_ptr(void); -/* retrieve pointer to environment block */ - -#define tls_set_ptr _glp_tls_set_ptr -void tls_set_ptr(void *ptr); -/* store global pointer in TLS */ - -#define tls_get_ptr _glp_tls_get_ptr -void *tls_get_ptr(void); -/* retrieve global pointer from TLS */ - -#define xputs glp_puts -void glp_puts(const char *s); -/* write string on terminal */ - -#define xprintf glp_printf -void glp_printf(const char *fmt, ...); -/* write formatted output on terminal */ - -#define xvprintf glp_vprintf -void glp_vprintf(const char *fmt, va_list arg); -/* write formatted output on terminal */ - -int glp_term_out(int flag); -/* enable/disable terminal output */ - -void glp_term_hook(int (*func)(void *info, const char *s), void *info); -/* install hook to intercept terminal output */ - -int glp_open_tee(const char *fname); -/* start copying terminal output to text file */ - -int glp_close_tee(void); -/* stop copying terminal output to text file */ - -#ifndef GLP_ERRFUNC_DEFINED -#define GLP_ERRFUNC_DEFINED -typedef void (*glp_errfunc)(const char *fmt, ...); -#endif - -#define xerror glp_error_(__FILE__, __LINE__) -glp_errfunc glp_error_(const char *file, int line); -/* display fatal error message and terminate execution */ - -#define xassert(expr) \ - ((void)((expr) || (glp_assert_(#expr, __FILE__, __LINE__), 1))) -void glp_assert_(const char *expr, const char *file, int line); -/* check for logical condition */ - -void glp_error_hook(void (*func)(void *info), void *info); -/* install hook to intercept abnormal termination */ - -#define put_err_msg _glp_put_err_msg -void put_err_msg(const char *msg); -/* provide error message string */ - -#define get_err_msg _glp_get_err_msg -const char *get_err_msg(void); -/* obtain error message string */ - -#define xmalloc(size) glp_alloc(1, size) -/* allocate memory block (obsolete) */ - -#define xcalloc(n, size) glp_alloc(n, size) -/* allocate memory block (obsolete) */ - -#define xalloc(n, size) glp_alloc(n, size) -#define talloc(n, type) ((type *)glp_alloc(n, sizeof(type))) -void *glp_alloc(int n, int size); -/* allocate memory block */ - -#define xrealloc(ptr, n, size) glp_realloc(ptr, n, size) -#define trealloc(ptr, n, type) ((type *)glp_realloc(ptr, n, \ - sizeof(type))) -void *glp_realloc(void *ptr, int n, int size); -/* reallocate memory block */ - -#define xfree(ptr) glp_free(ptr) -#define tfree(ptr) glp_free(ptr) -void glp_free(void *ptr); -/* free memory block */ - -void glp_mem_limit(int limit); -/* set memory usage limit */ - -void glp_mem_usage(int *count, int *cpeak, size_t *total, - size_t *tpeak); -/* get memory usage information */ - -typedef struct glp_file glp_file; -/* sequential stream descriptor */ - -#define glp_open _glp_open -glp_file *glp_open(const char *name, const char *mode); -/* open stream */ - -#define glp_eof _glp_eof -int glp_eof(glp_file *f); -/* test end-of-file indicator */ - -#define glp_ioerr _glp_ioerr -int glp_ioerr(glp_file *f); -/* test I/O error indicator */ - -#define glp_read _glp_read -int glp_read(glp_file *f, void *buf, int nnn); -/* read data from stream */ - -#define glp_getc _glp_getc -int glp_getc(glp_file *f); -/* read character from stream */ - -#define glp_write _glp_write -int glp_write(glp_file *f, const void *buf, int nnn); -/* write data to stream */ - -#define glp_format _glp_format -int glp_format(glp_file *f, const char *fmt, ...); -/* write formatted data to stream */ - -#define glp_close _glp_close -int glp_close(glp_file *f); -/* close stream */ - -#define xtime glp_time -double glp_time(void); -/* determine current universal time */ - -#define xdifftime glp_difftime -double glp_difftime(double t1, double t0); -/* compute difference between two time values */ - -#define xdlopen _glp_dlopen -void *xdlopen(const char *module); -/* open dynamically linked library */ - -#define xdlsym _glp_dlsym -void *xdlsym(void *h, const char *symbol); -/* obtain address of symbol from dynamically linked library */ - -#define xdlclose _glp_dlclose -void xdlclose(void *h); -/* close dynamically linked library */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/env/error.c b/resources/3rdparty/glpk-4.53/src/env/error.c deleted file mode 100644 index 3dec72125..000000000 --- a/resources/3rdparty/glpk-4.53/src/env/error.c +++ /dev/null @@ -1,170 +0,0 @@ -/* error.c (error handling) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" - -/*********************************************************************** -* NAME -* -* glp_error - display fatal error message and terminate execution -* -* SYNOPSIS -* -* void glp_error(const char *fmt, ...); -* -* DESCRIPTION -* -* The routine glp_error (implemented as a macro) formats its -* parameters using the format control string fmt, writes the formatted -* message on the terminal, and abnormally terminates the program. */ - -static void errfunc(const char *fmt, ...) -{ ENV *env = get_env_ptr(); - va_list arg; - env->term_out = GLP_ON; - va_start(arg, fmt); - xvprintf(fmt, arg); - va_end(arg); - xprintf("Error detected in file %s at line %d\n", - env->err_file, env->err_line); - if (env->err_hook != NULL) - env->err_hook(env->err_info); - abort(); - exit(EXIT_FAILURE); - /* no return */ -} - -glp_errfunc glp_error_(const char *file, int line) -{ ENV *env = get_env_ptr(); - env->err_file = file; - env->err_line = line; - return errfunc; -} - -/*********************************************************************** -* NAME -* -* glp_assert - check for logical condition -* -* SYNOPSIS -* -* void glp_assert(int expr); -* -* DESCRIPTION -* -* The routine glp_assert (implemented as a macro) checks for a logical -* condition specified by the parameter expr. If the condition is false -* (i.e. the value of expr is zero), the routine writes a message on -* the terminal and abnormally terminates the program. */ - -void glp_assert_(const char *expr, const char *file, int line) -{ glp_error_(file, line)("Assertion failed: %s\n", expr); - /* no return */ -} - -/*********************************************************************** -* NAME -* -* glp_error_hook - install hook to intercept abnormal termination -* -* SYNOPSIS -* -* void glp_error_hook(void (*func)(void *info), void *info); -* -* DESCRIPTION -* -* The routine glp_error_hook installs a user-defined hook routine to -* intercept abnormal termination. -* -* The parameter func specifies the user-defined hook routine. It is -* called from the routine glp_error before the latter calls the abort -* function to abnormally terminate the application program because of -* fatal error. The parameter info is a transit pointer, specified in -* the corresponding call to the routine glp_error_hook; it may be used -* to pass some information to the hook routine. -* -* To uninstall the hook routine the parameters func and info should be -* both specified as NULL. */ - -void glp_error_hook(void (*func)(void *info), void *info) -{ ENV *env = get_env_ptr(); - if (func == NULL) - { env->err_hook = NULL; - env->err_info = NULL; - } - else - { env->err_hook = func; - env->err_info = info; - } - return; -} - -/*********************************************************************** -* NAME -* -* put_err_msg - provide error message string -* -* SYNOPSIS -* -* #include "env.h" -* void put_err_msg(const char *msg); -* -* DESCRIPTION -* -* The routine put_err_msg stores an error message string pointed to by -* msg to the environment block. */ - -void put_err_msg(const char *msg) -{ ENV *env = get_env_ptr(); - int len; - len = strlen(msg); - if (len >= EBUF_SIZE) - len = EBUF_SIZE - 1; - memcpy(env->err_buf, msg, len); - if (len > 0 && env->err_buf[len-1] == '\n') - len--; - env->err_buf[len] = '\0'; - return; -} - -/*********************************************************************** -* NAME -* -* get_err_msg - obtain error message string -* -* SYNOPSIS -* -* #include "env.h" -* const char *get_err_msg(void); -* -* RETURNS -* -* The routine get_err_msg returns a pointer to an error message string -* previously stored by the routine put_err_msg. */ - -const char *get_err_msg(void) -{ ENV *env = get_env_ptr(); - return env->err_buf; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/env/stdc.h b/resources/3rdparty/glpk-4.53/src/env/stdc.h deleted file mode 100644 index 2d0416370..000000000 --- a/resources/3rdparty/glpk-4.53/src/env/stdc.h +++ /dev/null @@ -1,42 +0,0 @@ -/* stdc.h (standard ANSI C headers) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef STDC_H -#define STDC_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/env/stdout.c b/resources/3rdparty/glpk-4.53/src/env/stdout.c deleted file mode 100644 index fc44e1218..000000000 --- a/resources/3rdparty/glpk-4.53/src/env/stdout.c +++ /dev/null @@ -1,262 +0,0 @@ -/* stdout.c (terminal output) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#undef NDEBUG -#include -#include "env.h" - -/*********************************************************************** -* NAME -* -* glp_puts - write string on terminal -* -* SYNOPSIS -* -* void glp_puts(const char *s); -* -* The routine glp_puts writes the string s on the terminal. */ - -void glp_puts(const char *s) -{ ENV *env = get_env_ptr(); - /* if terminal output is disabled, do nothing */ - if (!env->term_out) - goto skip; - /* pass the string to the hook routine, if defined */ - if (env->term_hook != NULL) - { if (env->term_hook(env->term_info, s) != 0) - goto skip; - } - /* write the string on the terminal */ - fputs(s, stdout); - fflush(stdout); - /* write the string on the tee file, if required */ - if (env->tee_file != NULL) - { fputs(s, env->tee_file); - fflush(env->tee_file); - } -skip: return; -} - -/*********************************************************************** -* NAME -* -* glp_printf - write formatted output on terminal -* -* SYNOPSIS -* -* void glp_printf(const char *fmt, ...); -* -* DESCRIPTION -* -* The routine glp_printf uses the format control string fmt to format -* its parameters and writes the formatted output on the terminal. */ - -void glp_printf(const char *fmt, ...) -{ ENV *env = get_env_ptr(); - va_list arg; - /* if terminal output is disabled, do nothing */ - if (!env->term_out) - goto skip; - /* format the output */ - va_start(arg, fmt); - vsprintf(env->term_buf, fmt, arg); - /* (do not use xassert) */ - assert(strlen(env->term_buf) < TBUF_SIZE); - va_end(arg); - /* write the formatted output on the terminal */ - glp_puts(env->term_buf); -skip: return; -} - -/*********************************************************************** -* NAME -* -* glp_vprintf - write formatted output on terminal -* -* SYNOPSIS -* -* void glp_vprintf(const char *fmt, va_list arg); -* -* DESCRIPTION -* -* The routine glp_vprintf uses the format control string fmt to format -* its parameters specified by the list arg and writes the formatted -* output on the terminal. */ - -void glp_vprintf(const char *fmt, va_list arg) -{ ENV *env = get_env_ptr(); - /* if terminal output is disabled, do nothing */ - if (!env->term_out) - goto skip; - /* format the output */ - vsprintf(env->term_buf, fmt, arg); - /* (do not use xassert) */ - assert(strlen(env->term_buf) < TBUF_SIZE); - /* write the formatted output on the terminal */ - glp_puts(env->term_buf); -skip: return; -} - -/*********************************************************************** -* NAME -* -* glp_term_out - enable/disable terminal output -* -* SYNOPSIS -* -* int glp_term_out(int flag); -* -* DESCRIPTION -* -* Depending on the parameter flag the routine glp_term_out enables or -* disables terminal output performed by glpk routines: -* -* GLP_ON - enable terminal output; -* GLP_OFF - disable terminal output. -* -* RETURNS -* -* The routine glp_term_out returns the previous value of the terminal -* output flag. */ - -int glp_term_out(int flag) -{ ENV *env = get_env_ptr(); - int old = env->term_out; - if (!(flag == GLP_ON || flag == GLP_OFF)) - xerror("glp_term_out: flag = %d; invalid parameter\n", flag); - env->term_out = flag; - return old; -} - -/*********************************************************************** -* NAME -* -* glp_term_hook - install hook to intercept terminal output -* -* SYNOPSIS -* -* void glp_term_hook(int (*func)(void *info, const char *s), -* void *info); -* -* DESCRIPTION -* -* The routine glp_term_hook installs a user-defined hook routine to -* intercept all terminal output performed by glpk routines. -* -* This feature can be used to redirect the terminal output to other -* destination, for example to a file or a text window. -* -* The parameter func specifies the user-defined hook routine. It is -* called from an internal printing routine, which passes to it two -* parameters: info and s. The parameter info is a transit pointer, -* specified in the corresponding call to the routine glp_term_hook; -* it may be used to pass some information to the hook routine. The -* parameter s is a pointer to the null terminated character string, -* which is intended to be written to the terminal. If the hook routine -* returns zero, the printing routine writes the string s to the -* terminal in a usual way; otherwise, if the hook routine returns -* non-zero, no terminal output is performed. -* -* To uninstall the hook routine the parameters func and info should be -* specified as NULL. */ - -void glp_term_hook(int (*func)(void *info, const char *s), void *info) -{ ENV *env = get_env_ptr(); - if (func == NULL) - { env->term_hook = NULL; - env->term_info = NULL; - } - else - { env->term_hook = func; - env->term_info = info; - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_open_tee - start copying terminal output to text file -* -* SYNOPSIS -* -* int glp_open_tee(const char *name); -* -* DESCRIPTION -* -* The routine glp_open_tee starts copying all the terminal output to -* an output text file, whose name is specified by the character string -* name. -* -* RETURNS -* -* 0 - operation successful -* 1 - copying terminal output is already active -* 2 - unable to create output file */ - -int glp_open_tee(const char *name) -{ ENV *env = get_env_ptr(); - if (env->tee_file != NULL) - { /* copying terminal output is already active */ - return 1; - } - env->tee_file = fopen(name, "w"); - if (env->tee_file == NULL) - { /* unable to create output file */ - return 2; - } - return 0; -} - -/*********************************************************************** -* NAME -* -* glp_close_tee - stop copying terminal output to text file -* -* SYNOPSIS -* -* int glp_close_tee(void); -* -* DESCRIPTION -* -* The routine glp_close_tee stops copying the terminal output to the -* output text file previously open by the routine glp_open_tee closing -* that file. -* -* RETURNS -* -* 0 - operation successful -* 1 - copying terminal output was not started */ - -int glp_close_tee(void) -{ ENV *env = get_env_ptr(); - if (env->tee_file == NULL) - { /* copying terminal output was not started */ - return 1; - } - fclose(env->tee_file); - env->tee_file = NULL; - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/env/stream.c b/resources/3rdparty/glpk-4.53/src/env/stream.c deleted file mode 100644 index d290c116e..000000000 --- a/resources/3rdparty/glpk-4.53/src/env/stream.c +++ /dev/null @@ -1,475 +0,0 @@ -/* stream.c (stream input/output) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2008, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "zlib.h" - -struct glp_file -{ /* sequential stream descriptor */ - char *base; - /* pointer to buffer */ - int size; - /* size of buffer, in bytes */ - char *ptr; - /* pointer to next byte in buffer */ - int cnt; - /* count of bytes in buffer */ - int flag; - /* stream flags: */ -#define IONULL 0x01 /* null file */ -#define IOSTD 0x02 /* standard stream */ -#define IOGZIP 0x04 /* gzipped file */ -#define IOWRT 0x08 /* output stream */ -#define IOEOF 0x10 /* end of file */ -#define IOERR 0x20 /* input/output error */ - void *file; - /* pointer to underlying control object */ -}; - -/*********************************************************************** -* NAME -* -* glp_open - open stream -* -* SYNOPSIS -* -* glp_file *glp_open(const char *name, const char *mode); -* -* DESCRIPTION -* -* The routine glp_open opens a file whose name is a string pointed to -* by name and associates a stream with it. -* -* The following special filenames are recognized by the routine (this -* feature is platform independent): -* -* "/dev/null" empty (null) file; -* "/dev/stdin" standard input stream; -* "/dev/stdout" standard output stream; -* "/dev/stderr" standard error stream. -* -* If the specified filename is ended with ".gz", it is assumed that -* the file is in gzipped format. In this case the file is compressed -* or decompressed by the I/O routines "on the fly". -* -* The parameter mode points to a string, which indicates the open mode -* and should be one of the following: -* -* "r" open text file for reading; -* "w" truncate to zero length or create text file for writing; -* "rb" open binary file for reading; -* "wb" truncate to zero length or create binary file for writing. -* -* RETURNS -* -* The routine glp_open returns a pointer to the object controlling the -* stream. If the operation fails, the routine returns NULL. */ - -glp_file *glp_open(const char *name, const char *mode) -{ glp_file *f; - int flag; - void *file; - if (strcmp(mode, "r") == 0 || strcmp(mode, "rb") == 0) - flag = 0; - else if (strcmp(mode, "w") == 0 || strcmp(mode, "wb") == 0) - flag = IOWRT; - else - xerror("glp_open: invalid mode string\n"); - if (strcmp(name, "/dev/null") == 0) - { flag |= IONULL; - file = NULL; - } - else if (strcmp(name, "/dev/stdin") == 0) - { flag |= IOSTD; - file = stdin; - } - else if (strcmp(name, "/dev/stdout") == 0) - { flag |= IOSTD; - file = stdout; - } - else if (strcmp(name, "/dev/stderr") == 0) - { flag |= IOSTD; - file = stderr; - } - else - { char *ext = strrchr(name, '.'); - if (ext == NULL || strcmp(ext, ".gz") != 0) - { file = fopen(name, mode); - if (file == NULL) - { put_err_msg(strerror(errno)); - return NULL; - } - } - else - { flag |= IOGZIP; - if (strcmp(mode, "r") == 0) - mode = "rb"; - else if (strcmp(mode, "w") == 0) - mode = "wb"; - file = gzopen(name, mode); - if (file == NULL) - { put_err_msg(strerror(errno)); - return NULL; - } - } - } - f = talloc(1, glp_file); - f->base = talloc(BUFSIZ, char); - f->size = BUFSIZ; - f->ptr = f->base; - f->cnt = 0; - f->flag = flag; - f->file = file; - return f; -} - -/*********************************************************************** -* NAME -* -* glp_eof - test end-of-file indicator -* -* SYNOPSIS -* -* int glp_eof(glp_file *f); -* -* DESCRIPTION -* -* The routine glp_eof tests the end-of-file indicator for the stream -* pointed to by f. -* -* RETURNS -* -* The routine glp_eof returns non-zero if and only if the end-of-file -* indicator is set for the specified stream. */ - -int glp_eof(glp_file *f) -{ return - f->flag & IOEOF; -} - -/*********************************************************************** -* NAME -* -* glp_ioerr - test I/O error indicator -* -* SYNOPSIS -* -* int glp_ioerr(glp_file *f); -* -* DESCRIPTION -* -* The routine glp_ioerr tests the I/O error indicator for the stream -* pointed to by f. -* -* RETURNS -* -* The routine glp_ioerr returns non-zero if and only if the I/O error -* indicator is set for the specified stream. */ - -int glp_ioerr(glp_file *f) -{ return - f->flag & IOERR; -} - -/*********************************************************************** -* NAME -* -* glp_read - read data from stream -* -* SYNOPSIS -* -* int glp_read(glp_file *f, void *buf, int nnn); -* -* DESCRIPTION -* -* The routine glp_read reads, into the buffer pointed to by buf, up to -* nnn bytes, from the stream pointed to by f. -* -* RETURNS -* -* The routine glp_read returns the number of bytes successfully read -* (which may be less than nnn). If an end-of-file is encountered, the -* end-of-file indicator for the stream is set and glp_read returns -* zero. If a read error occurs, the error indicator for the stream is -* set and glp_read returns a negative value. */ - -int glp_read(glp_file *f, void *buf, int nnn) -{ int nrd, cnt; - if (f->flag & IOWRT) - xerror("glp_read: attempt to read from output stream\n"); - if (nnn < 1) - xerror("glp_read: nnn = %d; invalid parameter\n", nnn); - for (nrd = 0; nrd < nnn; nrd += cnt) - { if (f->cnt == 0) - { /* buffer is empty; fill it */ - if (f->flag & IONULL) - cnt = 0; - else if (!(f->flag & IOGZIP)) - { cnt = fread(f->base, 1, f->size, (FILE *)(f->file)); - if (ferror((FILE *)(f->file))) - { f->flag |= IOERR; - put_err_msg(strerror(errno)); - return EOF; - } - } - else - { int errnum; - const char *msg; - cnt = gzread((gzFile)(f->file), f->base, f->size); - if (cnt < 0) - { f->flag |= IOERR; - msg = gzerror((gzFile)(f->file), &errnum); - if (errnum == Z_ERRNO) - put_err_msg(strerror(errno)); - else - put_err_msg(msg); - return EOF; - } - } - if (cnt == 0) - { if (nrd == 0) - f->flag |= IOEOF; - break; - } - f->ptr = f->base; - f->cnt = cnt; - } - cnt = nnn - nrd; - if (cnt > f->cnt) - cnt = f->cnt; - memcpy((char *)buf + nrd, f->ptr, cnt); - f->ptr += cnt; - f->cnt -= cnt; - } - return nrd; -} - -/*********************************************************************** -* NAME -* -* glp_getc - read character from stream -* -* SYNOPSIS -* -* int glp_getc(glp_file *f); -* -* DESCRIPTION -* -* The routine glp_getc obtains a next character as an unsigned char -* converted to an int from the input stream pointed to by f. -* -* RETURNS -* -* The routine glp_getc returns the next character obtained. However, -* if an end-of-file is encountered or a read error occurs, the routine -* returns EOF. (An end-of-file and a read error can be distinguished -* by use of the routines glp_eof and glp_ioerr.) */ - -int glp_getc(glp_file *f) -{ unsigned char buf[1]; - if (f->flag & IOWRT) - xerror("glp_getc: attempt to read from output stream\n"); - if (glp_read(f, buf, 1) != 1) - return EOF; - return buf[0]; -} - -/*********************************************************************** -* do_flush - flush output stream -* -* This routine causes buffered data for the specified output stream to -* be written to the associated file. -* -* If the operation was successful, the routine returns zero, otherwise -* non-zero. */ - -static int do_flush(glp_file *f) -{ xassert(f->flag & IOWRT); - if (f->cnt > 0) - { if (f->flag & IONULL) - ; - else if (!(f->flag & IOGZIP)) - { if ((int)fwrite(f->base, 1, f->cnt, (FILE *)(f->file)) - != f->cnt) - { f->flag |= IOERR; - put_err_msg(strerror(errno)); - return EOF; - } - } - else - { int errnum; - const char *msg; - if (gzwrite((gzFile)(f->file), f->base, f->cnt) != f->cnt) - { f->flag |= IOERR; - msg = gzerror((gzFile)(f->file), &errnum); - if (errnum == Z_ERRNO) - put_err_msg(strerror(errno)); - else - put_err_msg(msg); - return EOF; - } - } - } - f->ptr = f->base; - f->cnt = 0; - return 0; -} - -/*********************************************************************** -* NAME -* -* glp_write - write data to stream -* -* SYNOPSIS -* -* int glp_write(glp_file *f, const void *buf, int nnn); -* -* DESCRIPTION -* -* The routine glp_write writes, from the buffer pointed to by buf, up -* to nnn bytes, to the stream pointed to by f. -* -* RETURNS -* -* The routine glp_write returns the number of bytes successfully -* written (which is equal to nnn). If a write error occurs, the error -* indicator for the stream is set and glp_write returns a negative -* value. */ - -int glp_write(glp_file *f, const void *buf, int nnn) -{ int nwr, cnt; - if (!(f->flag & IOWRT)) - xerror("glp_write: attempt to write to input stream\n"); - if (nnn < 1) - xerror("glp_write: nnn = %d; invalid parameter\n", nnn); - for (nwr = 0; nwr < nnn; nwr += cnt) - { cnt = nnn - nwr; - if (cnt > f->size - f->cnt) - cnt = f->size - f->cnt; - memcpy(f->ptr, (const char *)buf + nwr, cnt); - f->ptr += cnt; - f->cnt += cnt; - if (f->cnt == f->size) - { /* buffer is full; flush it */ - if (do_flush(f) != 0) - return EOF; - } - } - return nwr; -} - -/*********************************************************************** -* NAME -* -* glp_format - write formatted data to stream -* -* SYNOPSIS -* -* int glp_format(glp_file *f, const char *fmt, ...); -* -* DESCRIPTION -* -* The routine glp_format writes formatted data to the stream pointed -* to by f. The format control string pointed to by fmt specifies how -* subsequent arguments are converted for output. -* -* RETURNS -* -* The routine glp_format returns the number of characters written, or -* a negative value if an output error occurs. */ - -int glp_format(glp_file *f, const char *fmt, ...) -{ ENV *env = get_env_ptr(); - va_list arg; - int nnn; - if (!(f->flag & IOWRT)) - xerror("glp_format: attempt to write to input stream\n"); - va_start(arg, fmt); - nnn = vsprintf(env->term_buf, fmt, arg); - xassert(0 <= nnn && nnn < TBUF_SIZE); - va_end(arg); - return nnn == 0 ? 0 : glp_write(f, env->term_buf, nnn); -} - -/*********************************************************************** -* NAME -* -* glp_close - close stream -* -* SYNOPSIS -* -* int glp_close(glp_file *f); -* -* DESCRIPTION -* -* The routine glp_close closes the stream pointed to by f. -* -* RETURNS -* -* If the operation was successful, the routine returns zero, otherwise -* non-zero. */ - -int glp_close(glp_file *f) -{ int ret = 0; - if (f->flag & IOWRT) - { if (do_flush(f) != 0) - ret = EOF; - } - if (f->flag & (IONULL | IOSTD)) - ; - else if (!(f->flag & IOGZIP)) - { if (fclose((FILE *)(f->file)) != 0) - { if (ret == 0) - { put_err_msg(strerror(errno)); - ret = EOF; - } - } - } - else - { int errnum; - errnum = gzclose((gzFile)(f->file)); - if (errnum == Z_OK) - ; - else if (errnum == Z_ERRNO) - { if (ret == 0) - { put_err_msg(strerror(errno)); - ret = EOF; - } - } -#if 1 /* FIXME */ - else - { if (ret == 0) - { ENV *env = get_env_ptr(); - sprintf(env->term_buf, "gzclose returned %d", errnum); - put_err_msg(env->term_buf); - ret = EOF; - } - } -#endif - } - tfree(f->base); - tfree(f); - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/env/time.c b/resources/3rdparty/glpk-4.53/src/env/time.c deleted file mode 100644 index 01956ce7f..000000000 --- a/resources/3rdparty/glpk-4.53/src/env/time.c +++ /dev/null @@ -1,159 +0,0 @@ -/* time.c (standard time) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "env.h" -#include "jd.h" - -/*********************************************************************** -* NAME -* -* glp_time - determine current universal time -* -* SYNOPSIS -* -* double glp_time(void); -* -* RETURNS -* -* The routine glp_time returns the current universal time (UTC), in -* milliseconds, elapsed since 00:00:00 GMT January 1, 1970. */ - -#define EPOCH 2440588 /* jday(1, 1, 1970) */ - -/* POSIX version ******************************************************/ - -#if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY) - -#include -#include - -double glp_time(void) -{ struct timeval tv; - struct tm *tm; - int j; - double t; - gettimeofday(&tv, NULL); - tm = gmtime(&tv.tv_sec); - j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year); - xassert(j >= 0); - t = ((((double)(j - EPOCH) * 24.0 + (double)tm->tm_hour) * 60.0 + - (double)tm->tm_min) * 60.0 + (double)tm->tm_sec) * 1000.0 + - (double)(tv.tv_usec / 1000); - return t; -} - -/* MS Windows version *************************************************/ - -#elif defined(__WOE__) - -#include - -double glp_time(void) -{ SYSTEMTIME st; - int j; - double t; - GetSystemTime(&st); - j = jday(st.wDay, st.wMonth, st.wYear); - xassert(j >= 0); - t = ((((double)(j - EPOCH) * 24.0 + (double)st.wHour) * 60.0 + - (double)st.wMinute) * 60.0 + (double)st.wSecond) * 1000.0 + - (double)st.wMilliseconds; - return t; -} - -/* portable ANSI C version ********************************************/ - -#else - -#include - -double glp_time(void) -{ time_t timer; - struct tm *tm; - int j; - double t; - timer = time(NULL); - tm = gmtime(&timer); - j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year); - xassert(j >= 0); - t = ((((double)(j - EPOCH) * 24.0 + (double)tm->tm_hour) * 60.0 + - (double)tm->tm_min) * 60.0 + (double)tm->tm_sec) * 1000.0; - return t; -} - -#endif - -/*********************************************************************** -* NAME -* -* glp_difftime - compute difference between two time values -* -* SYNOPSIS -* -* double glp_difftime(double t1, double t0); -* -* RETURNS -* -* The routine glp_difftime returns the difference between two time -* values t1 and t0, expressed in seconds. */ - -double glp_difftime(double t1, double t0) -{ return - (t1 - t0) / 1000.0; -} - -/**********************************************************************/ - -#ifdef GLP_TEST -#include - -int main(void) -{ int ttt, ss, mm, hh, day, month, year; - double t; - t = glp_time(); - xprintf("t = %.f\n", t); - assert(floor(t) == t); - ttt = (int)fmod(t, 1000.0); - t = (t - (double)ttt) / 1000.0; - assert(floor(t) == t); - ss = (int)fmod(t, 60.0); - t = (t - (double)ss) / 60.0; - assert(floor(t) == t); - mm = (int)fmod(t, 60.0); - t = (t - (double)mm) / 60.0; - assert(floor(t) == t); - hh = (int)fmod(t, 24.0); - t = (t - (double)hh) / 24.0; - assert(floor(t) == t); - assert(jdate((int)t + EPOCH, &day, &month, &year) == 0); - printf("%04d-%02d-%02d %02d:%02d:%02d.%03d\n", - year, month, day, hh, mm, ss, ttt); - return 0; -} -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/env/tls.c b/resources/3rdparty/glpk-4.53/src/env/tls.c deleted file mode 100644 index b414e3b32..000000000 --- a/resources/3rdparty/glpk-4.53/src/env/tls.c +++ /dev/null @@ -1,72 +0,0 @@ -/* tls.c (thread local storage) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2001, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" - -static void *tls = NULL; -/* NOTE: in a re-entrant version of the package this variable should be - * placed in the Thread Local Storage (TLS) */ - -/*********************************************************************** -* NAME -* -* tls_set_ptr - store global pointer in TLS -* -* SYNOPSIS -* -* #include "env.h" -* void tls_set_ptr(void *ptr); -* -* DESCRIPTION -* -* The routine tls_set_ptr stores a pointer specified by the parameter -* ptr in the Thread Local Storage (TLS). */ - -void tls_set_ptr(void *ptr) -{ tls = ptr; - return; -} - -/*********************************************************************** -* NAME -* -* tls_get_ptr - retrieve global pointer from TLS -* -* SYNOPSIS -* -* #include "env.h" -* void *tls_get_ptr(void); -* -* RETURNS -* -* The routine tls_get_ptr returns a pointer previously stored by the -* routine tls_set_ptr. If the latter has not been called yet, NULL is -* returned. */ - -void *tls_get_ptr(void) -{ void *ptr; - ptr = tls; - return ptr; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi01.c b/resources/3rdparty/glpk-4.53/src/glpapi01.c deleted file mode 100644 index a7010b4e3..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi01.c +++ /dev/null @@ -1,1571 +0,0 @@ -/* glpapi01.c (problem creating and modifying routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpios.h" - -/* CAUTION: DO NOT CHANGE THE LIMITS BELOW */ - -#define M_MAX 100000000 /* = 100*10^6 */ -/* maximal number of rows in the problem object */ - -#define N_MAX 100000000 /* = 100*10^6 */ -/* maximal number of columns in the problem object */ - -#define NNZ_MAX 500000000 /* = 500*10^6 */ -/* maximal number of constraint coefficients in the problem object */ - -/*********************************************************************** -* NAME -* -* glp_create_prob - create problem object -* -* SYNOPSIS -* -* glp_prob *glp_create_prob(void); -* -* DESCRIPTION -* -* The routine glp_create_prob creates a new problem object, which is -* initially "empty", i.e. has no rows and columns. -* -* RETURNS -* -* The routine returns a pointer to the object created, which should be -* used in any subsequent operations on this object. */ - -static void create_prob(glp_prob *lp) -{ lp->magic = GLP_PROB_MAGIC; - lp->pool = dmp_create_pool(); -#if 0 /* 17/XI-2009 */ - lp->cps = xmalloc(sizeof(struct LPXCPS)); - lpx_reset_parms(lp); -#else - lp->parms = NULL; -#endif - lp->tree = NULL; -#if 0 - lp->lwa = 0; - lp->cwa = NULL; -#endif - /* LP/MIP data */ - lp->name = NULL; - lp->obj = NULL; - lp->dir = GLP_MIN; - lp->c0 = 0.0; - lp->m_max = 100; - lp->n_max = 200; - lp->m = lp->n = 0; - lp->nnz = 0; - lp->row = xcalloc(1+lp->m_max, sizeof(GLPROW *)); - lp->col = xcalloc(1+lp->n_max, sizeof(GLPCOL *)); - lp->r_tree = lp->c_tree = NULL; - /* basis factorization */ - lp->valid = 0; - lp->head = xcalloc(1+lp->m_max, sizeof(int)); - lp->bfcp = NULL; - lp->bfd = NULL; - /* basic solution (LP) */ - lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; - lp->obj_val = 0.0; - lp->it_cnt = 0; - lp->some = 0; - /* interior-point solution (LP) */ - lp->ipt_stat = GLP_UNDEF; - lp->ipt_obj = 0.0; - /* integer solution (MIP) */ - lp->mip_stat = GLP_UNDEF; - lp->mip_obj = 0.0; - return; -} - -glp_prob *glp_create_prob(void) -{ glp_prob *lp; - lp = xmalloc(sizeof(glp_prob)); - create_prob(lp); - return lp; -} - -/*********************************************************************** -* NAME -* -* glp_set_prob_name - assign (change) problem name -* -* SYNOPSIS -* -* void glp_set_prob_name(glp_prob *lp, const char *name); -* -* DESCRIPTION -* -* The routine glp_set_prob_name assigns a given symbolic name (1 up to -* 255 characters) to the specified problem object. -* -* If the parameter name is NULL or empty string, the routine erases an -* existing symbolic name of the problem object. */ - -void glp_set_prob_name(glp_prob *lp, const char *name) -{ glp_tree *tree = lp->tree; - if (tree != NULL && tree->reason != 0) - xerror("glp_set_prob_name: operation not allowed\n"); - if (lp->name != NULL) - { dmp_free_atom(lp->pool, lp->name, strlen(lp->name)+1); - lp->name = NULL; - } - if (!(name == NULL || name[0] == '\0')) - { int k; - for (k = 0; name[k] != '\0'; k++) - { if (k == 256) - xerror("glp_set_prob_name: problem name too long\n"); - if (iscntrl((unsigned char)name[k])) - xerror("glp_set_prob_name: problem name contains invalid" - " character(s)\n"); - } - lp->name = dmp_get_atom(lp->pool, strlen(name)+1); - strcpy(lp->name, name); - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_set_obj_name - assign (change) objective function name -* -* SYNOPSIS -* -* void glp_set_obj_name(glp_prob *lp, const char *name); -* -* DESCRIPTION -* -* The routine glp_set_obj_name assigns a given symbolic name (1 up to -* 255 characters) to the objective function of the specified problem -* object. -* -* If the parameter name is NULL or empty string, the routine erases an -* existing name of the objective function. */ - -void glp_set_obj_name(glp_prob *lp, const char *name) -{ glp_tree *tree = lp->tree; - if (tree != NULL && tree->reason != 0) - xerror("glp_set_obj_name: operation not allowed\n"); - if (lp->obj != NULL) - { dmp_free_atom(lp->pool, lp->obj, strlen(lp->obj)+1); - lp->obj = NULL; - } - if (!(name == NULL || name[0] == '\0')) - { int k; - for (k = 0; name[k] != '\0'; k++) - { if (k == 256) - xerror("glp_set_obj_name: objective name too long\n"); - if (iscntrl((unsigned char)name[k])) - xerror("glp_set_obj_name: objective name contains invali" - "d character(s)\n"); - } - lp->obj = dmp_get_atom(lp->pool, strlen(name)+1); - strcpy(lp->obj, name); - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_set_obj_dir - set (change) optimization direction flag -* -* SYNOPSIS -* -* void glp_set_obj_dir(glp_prob *lp, int dir); -* -* DESCRIPTION -* -* The routine glp_set_obj_dir sets (changes) optimization direction -* flag (i.e. "sense" of the objective function) as specified by the -* parameter dir: -* -* GLP_MIN - minimization; -* GLP_MAX - maximization. */ - -void glp_set_obj_dir(glp_prob *lp, int dir) -{ glp_tree *tree = lp->tree; - if (tree != NULL && tree->reason != 0) - xerror("glp_set_obj_dir: operation not allowed\n"); - if (!(dir == GLP_MIN || dir == GLP_MAX)) - xerror("glp_set_obj_dir: dir = %d; invalid direction flag\n", - dir); - lp->dir = dir; - return; -} - -/*********************************************************************** -* NAME -* -* glp_add_rows - add new rows to problem object -* -* SYNOPSIS -* -* int glp_add_rows(glp_prob *lp, int nrs); -* -* DESCRIPTION -* -* The routine glp_add_rows adds nrs rows (constraints) to the specified -* problem object. New rows are always added to the end of the row list, -* so the ordinal numbers of existing rows remain unchanged. -* -* Being added each new row is initially free (unbounded) and has empty -* list of the constraint coefficients. -* -* RETURNS -* -* The routine glp_add_rows returns the ordinal number of the first new -* row added to the problem object. */ - -int glp_add_rows(glp_prob *lp, int nrs) -{ glp_tree *tree = lp->tree; - GLPROW *row; - int m_new, i; - /* determine new number of rows */ - if (nrs < 1) - xerror("glp_add_rows: nrs = %d; invalid number of rows\n", - nrs); - if (nrs > M_MAX - lp->m) - xerror("glp_add_rows: nrs = %d; too many rows\n", nrs); - m_new = lp->m + nrs; - /* increase the room, if necessary */ - if (lp->m_max < m_new) - { GLPROW **save = lp->row; - while (lp->m_max < m_new) - { lp->m_max += lp->m_max; - xassert(lp->m_max > 0); - } - lp->row = xcalloc(1+lp->m_max, sizeof(GLPROW *)); - memcpy(&lp->row[1], &save[1], lp->m * sizeof(GLPROW *)); - xfree(save); - /* do not forget about the basis header */ - xfree(lp->head); - lp->head = xcalloc(1+lp->m_max, sizeof(int)); - } - /* add new rows to the end of the row list */ - for (i = lp->m+1; i <= m_new; i++) - { /* create row descriptor */ - lp->row[i] = row = dmp_get_atom(lp->pool, sizeof(GLPROW)); - row->i = i; - row->name = NULL; - row->node = NULL; -#if 1 /* 20/IX-2008 */ - row->level = 0; - row->origin = 0; - row->klass = 0; - if (tree != NULL) - { switch (tree->reason) - { case 0: - break; - case GLP_IROWGEN: - xassert(tree->curr != NULL); - row->level = tree->curr->level; - row->origin = GLP_RF_LAZY; - break; - case GLP_ICUTGEN: - xassert(tree->curr != NULL); - row->level = tree->curr->level; - row->origin = GLP_RF_CUT; - break; - default: - xassert(tree != tree); - } - } -#endif - row->type = GLP_FR; - row->lb = row->ub = 0.0; - row->ptr = NULL; - row->rii = 1.0; - row->stat = GLP_BS; -#if 0 - row->bind = -1; -#else - row->bind = 0; -#endif - row->prim = row->dual = 0.0; - row->pval = row->dval = 0.0; - row->mipx = 0.0; - } - /* set new number of rows */ - lp->m = m_new; - /* invalidate the basis factorization */ - lp->valid = 0; -#if 1 - if (tree != NULL && tree->reason != 0) tree->reopt = 1; -#endif - /* return the ordinal number of the first row added */ - return m_new - nrs + 1; -} - -/*********************************************************************** -* NAME -* -* glp_add_cols - add new columns to problem object -* -* SYNOPSIS -* -* int glp_add_cols(glp_prob *lp, int ncs); -* -* DESCRIPTION -* -* The routine glp_add_cols adds ncs columns (structural variables) to -* the specified problem object. New columns are always added to the end -* of the column list, so the ordinal numbers of existing columns remain -* unchanged. -* -* Being added each new column is initially fixed at zero and has empty -* list of the constraint coefficients. -* -* RETURNS -* -* The routine glp_add_cols returns the ordinal number of the first new -* column added to the problem object. */ - -int glp_add_cols(glp_prob *lp, int ncs) -{ glp_tree *tree = lp->tree; - GLPCOL *col; - int n_new, j; - if (tree != NULL && tree->reason != 0) - xerror("glp_add_cols: operation not allowed\n"); - /* determine new number of columns */ - if (ncs < 1) - xerror("glp_add_cols: ncs = %d; invalid number of columns\n", - ncs); - if (ncs > N_MAX - lp->n) - xerror("glp_add_cols: ncs = %d; too many columns\n", ncs); - n_new = lp->n + ncs; - /* increase the room, if necessary */ - if (lp->n_max < n_new) - { GLPCOL **save = lp->col; - while (lp->n_max < n_new) - { lp->n_max += lp->n_max; - xassert(lp->n_max > 0); - } - lp->col = xcalloc(1+lp->n_max, sizeof(GLPCOL *)); - memcpy(&lp->col[1], &save[1], lp->n * sizeof(GLPCOL *)); - xfree(save); - } - /* add new columns to the end of the column list */ - for (j = lp->n+1; j <= n_new; j++) - { /* create column descriptor */ - lp->col[j] = col = dmp_get_atom(lp->pool, sizeof(GLPCOL)); - col->j = j; - col->name = NULL; - col->node = NULL; - col->kind = GLP_CV; - col->type = GLP_FX; - col->lb = col->ub = 0.0; - col->coef = 0.0; - col->ptr = NULL; - col->sjj = 1.0; - col->stat = GLP_NS; -#if 0 - col->bind = -1; -#else - col->bind = 0; /* the basis may remain valid */ -#endif - col->prim = col->dual = 0.0; - col->pval = col->dval = 0.0; - col->mipx = 0.0; - } - /* set new number of columns */ - lp->n = n_new; - /* return the ordinal number of the first column added */ - return n_new - ncs + 1; -} - -/*********************************************************************** -* NAME -* -* glp_set_row_name - assign (change) row name -* -* SYNOPSIS -* -* void glp_set_row_name(glp_prob *lp, int i, const char *name); -* -* DESCRIPTION -* -* The routine glp_set_row_name assigns a given symbolic name (1 up to -* 255 characters) to i-th row (auxiliary variable) of the specified -* problem object. -* -* If the parameter name is NULL or empty string, the routine erases an -* existing name of i-th row. */ - -void glp_set_row_name(glp_prob *lp, int i, const char *name) -{ glp_tree *tree = lp->tree; - GLPROW *row; - if (!(1 <= i && i <= lp->m)) - xerror("glp_set_row_name: i = %d; row number out of range\n", - i); - row = lp->row[i]; - if (tree != NULL && tree->reason != 0) - { xassert(tree->curr != NULL); - xassert(row->level == tree->curr->level); - } - if (row->name != NULL) - { if (row->node != NULL) - { xassert(lp->r_tree != NULL); - avl_delete_node(lp->r_tree, row->node); - row->node = NULL; - } - dmp_free_atom(lp->pool, row->name, strlen(row->name)+1); - row->name = NULL; - } - if (!(name == NULL || name[0] == '\0')) - { int k; - for (k = 0; name[k] != '\0'; k++) - { if (k == 256) - xerror("glp_set_row_name: i = %d; row name too long\n", - i); - if (iscntrl((unsigned char)name[k])) - xerror("glp_set_row_name: i = %d: row name contains inva" - "lid character(s)\n", i); - } - row->name = dmp_get_atom(lp->pool, strlen(name)+1); - strcpy(row->name, name); - if (lp->r_tree != NULL) - { xassert(row->node == NULL); - row->node = avl_insert_node(lp->r_tree, row->name); - avl_set_node_link(row->node, row); - } - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_set_col_name - assign (change) column name -* -* SYNOPSIS -* -* void glp_set_col_name(glp_prob *lp, int j, const char *name); -* -* DESCRIPTION -* -* The routine glp_set_col_name assigns a given symbolic name (1 up to -* 255 characters) to j-th column (structural variable) of the specified -* problem object. -* -* If the parameter name is NULL or empty string, the routine erases an -* existing name of j-th column. */ - -void glp_set_col_name(glp_prob *lp, int j, const char *name) -{ glp_tree *tree = lp->tree; - GLPCOL *col; - if (tree != NULL && tree->reason != 0) - xerror("glp_set_col_name: operation not allowed\n"); - if (!(1 <= j && j <= lp->n)) - xerror("glp_set_col_name: j = %d; column number out of range\n" - , j); - col = lp->col[j]; - if (col->name != NULL) - { if (col->node != NULL) - { xassert(lp->c_tree != NULL); - avl_delete_node(lp->c_tree, col->node); - col->node = NULL; - } - dmp_free_atom(lp->pool, col->name, strlen(col->name)+1); - col->name = NULL; - } - if (!(name == NULL || name[0] == '\0')) - { int k; - for (k = 0; name[k] != '\0'; k++) - { if (k == 256) - xerror("glp_set_col_name: j = %d; column name too long\n" - , j); - if (iscntrl((unsigned char)name[k])) - xerror("glp_set_col_name: j = %d: column name contains i" - "nvalid character(s)\n", j); - } - col->name = dmp_get_atom(lp->pool, strlen(name)+1); - strcpy(col->name, name); - if (lp->c_tree != NULL && col->name != NULL) - { xassert(col->node == NULL); - col->node = avl_insert_node(lp->c_tree, col->name); - avl_set_node_link(col->node, col); - } - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_set_row_bnds - set (change) row bounds -* -* SYNOPSIS -* -* void glp_set_row_bnds(glp_prob *lp, int i, int type, double lb, -* double ub); -* -* DESCRIPTION -* -* The routine glp_set_row_bnds sets (changes) the type and bounds of -* i-th row (auxiliary variable) of the specified problem object. -* -* Parameters type, lb, and ub specify the type, lower bound, and upper -* bound, respectively, as follows: -* -* Type Bounds Comments -* ------------------------------------------------------ -* GLP_FR -inf < x < +inf Free variable -* GLP_LO lb <= x < +inf Variable with lower bound -* GLP_UP -inf < x <= ub Variable with upper bound -* GLP_DB lb <= x <= ub Double-bounded variable -* GLP_FX x = lb Fixed variable -* -* where x is the auxiliary variable associated with i-th row. -* -* If the row has no lower bound, the parameter lb is ignored. If the -* row has no upper bound, the parameter ub is ignored. If the row is -* an equality constraint (i.e. the corresponding auxiliary variable is -* of fixed type), only the parameter lb is used while the parameter ub -* is ignored. */ - -void glp_set_row_bnds(glp_prob *lp, int i, int type, double lb, - double ub) -{ GLPROW *row; - if (!(1 <= i && i <= lp->m)) - xerror("glp_set_row_bnds: i = %d; row number out of range\n", - i); - row = lp->row[i]; - row->type = type; - switch (type) - { case GLP_FR: - row->lb = row->ub = 0.0; - if (row->stat != GLP_BS) row->stat = GLP_NF; - break; - case GLP_LO: - row->lb = lb, row->ub = 0.0; - if (row->stat != GLP_BS) row->stat = GLP_NL; - break; - case GLP_UP: - row->lb = 0.0, row->ub = ub; - if (row->stat != GLP_BS) row->stat = GLP_NU; - break; - case GLP_DB: - row->lb = lb, row->ub = ub; - if (!(row->stat == GLP_BS || - row->stat == GLP_NL || row->stat == GLP_NU)) - row->stat = (fabs(lb) <= fabs(ub) ? GLP_NL : GLP_NU); - break; - case GLP_FX: - row->lb = row->ub = lb; - if (row->stat != GLP_BS) row->stat = GLP_NS; - break; - default: - xerror("glp_set_row_bnds: i = %d; type = %d; invalid row ty" - "pe\n", i, type); - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_set_col_bnds - set (change) column bounds -* -* SYNOPSIS -* -* void glp_set_col_bnds(glp_prob *lp, int j, int type, double lb, -* double ub); -* -* DESCRIPTION -* -* The routine glp_set_col_bnds sets (changes) the type and bounds of -* j-th column (structural variable) of the specified problem object. -* -* Parameters type, lb, and ub specify the type, lower bound, and upper -* bound, respectively, as follows: -* -* Type Bounds Comments -* ------------------------------------------------------ -* GLP_FR -inf < x < +inf Free variable -* GLP_LO lb <= x < +inf Variable with lower bound -* GLP_UP -inf < x <= ub Variable with upper bound -* GLP_DB lb <= x <= ub Double-bounded variable -* GLP_FX x = lb Fixed variable -* -* where x is the structural variable associated with j-th column. -* -* If the column has no lower bound, the parameter lb is ignored. If the -* column has no upper bound, the parameter ub is ignored. If the column -* is of fixed type, only the parameter lb is used while the parameter -* ub is ignored. */ - -void glp_set_col_bnds(glp_prob *lp, int j, int type, double lb, - double ub) -{ GLPCOL *col; - if (!(1 <= j && j <= lp->n)) - xerror("glp_set_col_bnds: j = %d; column number out of range\n" - , j); - col = lp->col[j]; - col->type = type; - switch (type) - { case GLP_FR: - col->lb = col->ub = 0.0; - if (col->stat != GLP_BS) col->stat = GLP_NF; - break; - case GLP_LO: - col->lb = lb, col->ub = 0.0; - if (col->stat != GLP_BS) col->stat = GLP_NL; - break; - case GLP_UP: - col->lb = 0.0, col->ub = ub; - if (col->stat != GLP_BS) col->stat = GLP_NU; - break; - case GLP_DB: - col->lb = lb, col->ub = ub; - if (!(col->stat == GLP_BS || - col->stat == GLP_NL || col->stat == GLP_NU)) - col->stat = (fabs(lb) <= fabs(ub) ? GLP_NL : GLP_NU); - break; - case GLP_FX: - col->lb = col->ub = lb; - if (col->stat != GLP_BS) col->stat = GLP_NS; - break; - default: - xerror("glp_set_col_bnds: j = %d; type = %d; invalid column" - " type\n", j, type); - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_set_obj_coef - set (change) obj. coefficient or constant term -* -* SYNOPSIS -* -* void glp_set_obj_coef(glp_prob *lp, int j, double coef); -* -* DESCRIPTION -* -* The routine glp_set_obj_coef sets (changes) objective coefficient at -* j-th column (structural variable) of the specified problem object. -* -* If the parameter j is 0, the routine sets (changes) the constant term -* ("shift") of the objective function. */ - -void glp_set_obj_coef(glp_prob *lp, int j, double coef) -{ glp_tree *tree = lp->tree; - if (tree != NULL && tree->reason != 0) - xerror("glp_set_obj_coef: operation not allowed\n"); - if (!(0 <= j && j <= lp->n)) - xerror("glp_set_obj_coef: j = %d; column number out of range\n" - , j); - if (j == 0) - lp->c0 = coef; - else - lp->col[j]->coef = coef; - return; -} - -/*********************************************************************** -* NAME -* -* glp_set_mat_row - set (replace) row of the constraint matrix -* -* SYNOPSIS -* -* void glp_set_mat_row(glp_prob *lp, int i, int len, const int ind[], -* const double val[]); -* -* DESCRIPTION -* -* The routine glp_set_mat_row stores (replaces) the contents of i-th -* row of the constraint matrix of the specified problem object. -* -* Column indices and numeric values of new row elements must be placed -* in locations ind[1], ..., ind[len] and val[1], ..., val[len], where -* 0 <= len <= n is the new length of i-th row, n is the current number -* of columns in the problem object. Elements with identical column -* indices are not allowed. Zero elements are allowed, but they are not -* stored in the constraint matrix. -* -* If the parameter len is zero, the parameters ind and/or val can be -* specified as NULL. */ - -void glp_set_mat_row(glp_prob *lp, int i, int len, const int ind[], - const double val[]) -{ glp_tree *tree = lp->tree; - GLPROW *row; - GLPCOL *col; - GLPAIJ *aij, *next; - int j, k; - /* obtain pointer to i-th row */ - if (!(1 <= i && i <= lp->m)) - xerror("glp_set_mat_row: i = %d; row number out of range\n", - i); - row = lp->row[i]; - if (tree != NULL && tree->reason != 0) - { xassert(tree->curr != NULL); - xassert(row->level == tree->curr->level); - } - /* remove all existing elements from i-th row */ - while (row->ptr != NULL) - { /* take next element in the row */ - aij = row->ptr; - /* remove the element from the row list */ - row->ptr = aij->r_next; - /* obtain pointer to corresponding column */ - col = aij->col; - /* remove the element from the column list */ - if (aij->c_prev == NULL) - col->ptr = aij->c_next; - else - aij->c_prev->c_next = aij->c_next; - if (aij->c_next == NULL) - ; - else - aij->c_next->c_prev = aij->c_prev; - /* return the element to the memory pool */ - dmp_free_atom(lp->pool, aij, sizeof(GLPAIJ)), lp->nnz--; - /* if the corresponding column is basic, invalidate the basis - factorization */ - if (col->stat == GLP_BS) lp->valid = 0; - } - /* store new contents of i-th row */ - if (!(0 <= len && len <= lp->n)) - xerror("glp_set_mat_row: i = %d; len = %d; invalid row length " - "\n", i, len); - if (len > NNZ_MAX - lp->nnz) - xerror("glp_set_mat_row: i = %d; len = %d; too many constraint" - " coefficients\n", i, len); - for (k = 1; k <= len; k++) - { /* take number j of corresponding column */ - j = ind[k]; - /* obtain pointer to j-th column */ - if (!(1 <= j && j <= lp->n)) - xerror("glp_set_mat_row: i = %d; ind[%d] = %d; column index" - " out of range\n", i, k, j); - col = lp->col[j]; - /* if there is element with the same column index, it can only - be found in the beginning of j-th column list */ - if (col->ptr != NULL && col->ptr->row->i == i) - xerror("glp_set_mat_row: i = %d; ind[%d] = %d; duplicate co" - "lumn indices not allowed\n", i, k, j); - /* create new element */ - aij = dmp_get_atom(lp->pool, sizeof(GLPAIJ)), lp->nnz++; - aij->row = row; - aij->col = col; - aij->val = val[k]; - /* add the new element to the beginning of i-th row and j-th - column lists */ - aij->r_prev = NULL; - aij->r_next = row->ptr; - aij->c_prev = NULL; - aij->c_next = col->ptr; - if (aij->r_next != NULL) aij->r_next->r_prev = aij; - if (aij->c_next != NULL) aij->c_next->c_prev = aij; - row->ptr = col->ptr = aij; - /* if the corresponding column is basic, invalidate the basis - factorization */ - if (col->stat == GLP_BS && aij->val != 0.0) lp->valid = 0; - } - /* remove zero elements from i-th row */ - for (aij = row->ptr; aij != NULL; aij = next) - { next = aij->r_next; - if (aij->val == 0.0) - { /* remove the element from the row list */ - if (aij->r_prev == NULL) - row->ptr = next; - else - aij->r_prev->r_next = next; - if (next == NULL) - ; - else - next->r_prev = aij->r_prev; - /* remove the element from the column list */ - xassert(aij->c_prev == NULL); - aij->col->ptr = aij->c_next; - if (aij->c_next != NULL) aij->c_next->c_prev = NULL; - /* return the element to the memory pool */ - dmp_free_atom(lp->pool, aij, sizeof(GLPAIJ)), lp->nnz--; - } - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_set_mat_col - set (replace) column of the constraint matrix -* -* SYNOPSIS -* -* void glp_set_mat_col(glp_prob *lp, int j, int len, const int ind[], -* const double val[]); -* -* DESCRIPTION -* -* The routine glp_set_mat_col stores (replaces) the contents of j-th -* column of the constraint matrix of the specified problem object. -* -* Row indices and numeric values of new column elements must be placed -* in locations ind[1], ..., ind[len] and val[1], ..., val[len], where -* 0 <= len <= m is the new length of j-th column, m is the current -* number of rows in the problem object. Elements with identical column -* indices are not allowed. Zero elements are allowed, but they are not -* stored in the constraint matrix. -* -* If the parameter len is zero, the parameters ind and/or val can be -* specified as NULL. */ - -void glp_set_mat_col(glp_prob *lp, int j, int len, const int ind[], - const double val[]) -{ glp_tree *tree = lp->tree; - GLPROW *row; - GLPCOL *col; - GLPAIJ *aij, *next; - int i, k; - if (tree != NULL && tree->reason != 0) - xerror("glp_set_mat_col: operation not allowed\n"); - /* obtain pointer to j-th column */ - if (!(1 <= j && j <= lp->n)) - xerror("glp_set_mat_col: j = %d; column number out of range\n", - j); - col = lp->col[j]; - /* remove all existing elements from j-th column */ - while (col->ptr != NULL) - { /* take next element in the column */ - aij = col->ptr; - /* remove the element from the column list */ - col->ptr = aij->c_next; - /* obtain pointer to corresponding row */ - row = aij->row; - /* remove the element from the row list */ - if (aij->r_prev == NULL) - row->ptr = aij->r_next; - else - aij->r_prev->r_next = aij->r_next; - if (aij->r_next == NULL) - ; - else - aij->r_next->r_prev = aij->r_prev; - /* return the element to the memory pool */ - dmp_free_atom(lp->pool, aij, sizeof(GLPAIJ)), lp->nnz--; - } - /* store new contents of j-th column */ - if (!(0 <= len && len <= lp->m)) - xerror("glp_set_mat_col: j = %d; len = %d; invalid column leng" - "th\n", j, len); - if (len > NNZ_MAX - lp->nnz) - xerror("glp_set_mat_col: j = %d; len = %d; too many constraint" - " coefficients\n", j, len); - for (k = 1; k <= len; k++) - { /* take number i of corresponding row */ - i = ind[k]; - /* obtain pointer to i-th row */ - if (!(1 <= i && i <= lp->m)) - xerror("glp_set_mat_col: j = %d; ind[%d] = %d; row index ou" - "t of range\n", j, k, i); - row = lp->row[i]; - /* if there is element with the same row index, it can only be - found in the beginning of i-th row list */ - if (row->ptr != NULL && row->ptr->col->j == j) - xerror("glp_set_mat_col: j = %d; ind[%d] = %d; duplicate ro" - "w indices not allowed\n", j, k, i); - /* create new element */ - aij = dmp_get_atom(lp->pool, sizeof(GLPAIJ)), lp->nnz++; - aij->row = row; - aij->col = col; - aij->val = val[k]; - /* add the new element to the beginning of i-th row and j-th - column lists */ - aij->r_prev = NULL; - aij->r_next = row->ptr; - aij->c_prev = NULL; - aij->c_next = col->ptr; - if (aij->r_next != NULL) aij->r_next->r_prev = aij; - if (aij->c_next != NULL) aij->c_next->c_prev = aij; - row->ptr = col->ptr = aij; - } - /* remove zero elements from j-th column */ - for (aij = col->ptr; aij != NULL; aij = next) - { next = aij->c_next; - if (aij->val == 0.0) - { /* remove the element from the row list */ - xassert(aij->r_prev == NULL); - aij->row->ptr = aij->r_next; - if (aij->r_next != NULL) aij->r_next->r_prev = NULL; - /* remove the element from the column list */ - if (aij->c_prev == NULL) - col->ptr = next; - else - aij->c_prev->c_next = next; - if (next == NULL) - ; - else - next->c_prev = aij->c_prev; - /* return the element to the memory pool */ - dmp_free_atom(lp->pool, aij, sizeof(GLPAIJ)), lp->nnz--; - } - } - /* if j-th column is basic, invalidate the basis factorization */ - if (col->stat == GLP_BS) lp->valid = 0; - return; -} - -/*********************************************************************** -* NAME -* -* glp_load_matrix - load (replace) the whole constraint matrix -* -* SYNOPSIS -* -* void glp_load_matrix(glp_prob *lp, int ne, const int ia[], -* const int ja[], const double ar[]); -* -* DESCRIPTION -* -* The routine glp_load_matrix loads the constraint matrix passed in -* the arrays ia, ja, and ar into the specified problem object. Before -* loading the current contents of the constraint matrix is destroyed. -* -* Constraint coefficients (elements of the constraint matrix) must be -* specified as triplets (ia[k], ja[k], ar[k]) for k = 1, ..., ne, -* where ia[k] is the row index, ja[k] is the column index, ar[k] is a -* numeric value of corresponding constraint coefficient. The parameter -* ne specifies the total number of (non-zero) elements in the matrix -* to be loaded. Coefficients with identical indices are not allowed. -* Zero coefficients are allowed, however, they are not stored in the -* constraint matrix. -* -* If the parameter ne is zero, the parameters ia, ja, and ar can be -* specified as NULL. */ - -void glp_load_matrix(glp_prob *lp, int ne, const int ia[], - const int ja[], const double ar[]) -{ glp_tree *tree = lp->tree; - GLPROW *row; - GLPCOL *col; - GLPAIJ *aij, *next; - int i, j, k; - if (tree != NULL && tree->reason != 0) - xerror("glp_load_matrix: operation not allowed\n"); - /* clear the constraint matrix */ - for (i = 1; i <= lp->m; i++) - { row = lp->row[i]; - while (row->ptr != NULL) - { aij = row->ptr; - row->ptr = aij->r_next; - dmp_free_atom(lp->pool, aij, sizeof(GLPAIJ)), lp->nnz--; - } - } - xassert(lp->nnz == 0); - for (j = 1; j <= lp->n; j++) lp->col[j]->ptr = NULL; - /* load the new contents of the constraint matrix and build its - row lists */ - if (ne < 0) - xerror("glp_load_matrix: ne = %d; invalid number of constraint" - " coefficients\n", ne); - if (ne > NNZ_MAX) - xerror("glp_load_matrix: ne = %d; too many constraint coeffici" - "ents\n", ne); - for (k = 1; k <= ne; k++) - { /* take indices of new element */ - i = ia[k], j = ja[k]; - /* obtain pointer to i-th row */ - if (!(1 <= i && i <= lp->m)) - xerror("glp_load_matrix: ia[%d] = %d; row index out of rang" - "e\n", k, i); - row = lp->row[i]; - /* obtain pointer to j-th column */ - if (!(1 <= j && j <= lp->n)) - xerror("glp_load_matrix: ja[%d] = %d; column index out of r" - "ange\n", k, j); - col = lp->col[j]; - /* create new element */ - aij = dmp_get_atom(lp->pool, sizeof(GLPAIJ)), lp->nnz++; - aij->row = row; - aij->col = col; - aij->val = ar[k]; - /* add the new element to the beginning of i-th row list */ - aij->r_prev = NULL; - aij->r_next = row->ptr; - if (aij->r_next != NULL) aij->r_next->r_prev = aij; - row->ptr = aij; - } - xassert(lp->nnz == ne); - /* build column lists of the constraint matrix and check elements - with identical indices */ - for (i = 1; i <= lp->m; i++) - { for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) - { /* obtain pointer to corresponding column */ - col = aij->col; - /* if there is element with identical indices, it can only - be found in the beginning of j-th column list */ - if (col->ptr != NULL && col->ptr->row->i == i) - { for (k = 1; k <= ne; k++) - if (ia[k] == i && ja[k] == col->j) break; - xerror("glp_load_mat: ia[%d] = %d; ja[%d] = %d; duplicat" - "e indices not allowed\n", k, i, k, col->j); - } - /* add the element to the beginning of j-th column list */ - aij->c_prev = NULL; - aij->c_next = col->ptr; - if (aij->c_next != NULL) aij->c_next->c_prev = aij; - col->ptr = aij; - } - } - /* remove zero elements from the constraint matrix */ - for (i = 1; i <= lp->m; i++) - { row = lp->row[i]; - for (aij = row->ptr; aij != NULL; aij = next) - { next = aij->r_next; - if (aij->val == 0.0) - { /* remove the element from the row list */ - if (aij->r_prev == NULL) - row->ptr = next; - else - aij->r_prev->r_next = next; - if (next == NULL) - ; - else - next->r_prev = aij->r_prev; - /* remove the element from the column list */ - if (aij->c_prev == NULL) - aij->col->ptr = aij->c_next; - else - aij->c_prev->c_next = aij->c_next; - if (aij->c_next == NULL) - ; - else - aij->c_next->c_prev = aij->c_prev; - /* return the element to the memory pool */ - dmp_free_atom(lp->pool, aij, sizeof(GLPAIJ)), lp->nnz--; - } - } - } - /* invalidate the basis factorization */ - lp->valid = 0; - return; -} - -/*********************************************************************** -* NAME -* -* glp_check_dup - check for duplicate elements in sparse matrix -* -* SYNOPSIS -* -* int glp_check_dup(int m, int n, int ne, const int ia[], -* const int ja[]); -* -* DESCRIPTION -* -* The routine glp_check_dup checks for duplicate elements (that is, -* elements with identical indices) in a sparse matrix specified in the -* coordinate format. -* -* The parameters m and n specifies, respectively, the number of rows -* and columns in the matrix, m >= 0, n >= 0. -* -* The parameter ne specifies the number of (structurally) non-zero -* elements in the matrix, ne >= 0. -* -* Elements of the matrix are specified as doublets (ia[k],ja[k]) for -* k = 1,...,ne, where ia[k] is a row index, ja[k] is a column index. -* -* The routine glp_check_dup can be used prior to a call to the routine -* glp_load_matrix to check that the constraint matrix to be loaded has -* no duplicate elements. -* -* RETURNS -* -* The routine glp_check_dup returns one of the following values: -* -* 0 - the matrix has no duplicate elements; -* -* -k - indices ia[k] or/and ja[k] are out of range; -* -* +k - element (ia[k],ja[k]) is duplicate. */ - -int glp_check_dup(int m, int n, int ne, const int ia[], const int ja[]) -{ int i, j, k, *ptr, *next, ret; - char *flag; - if (m < 0) - xerror("glp_check_dup: m = %d; invalid parameter\n"); - if (n < 0) - xerror("glp_check_dup: n = %d; invalid parameter\n"); - if (ne < 0) - xerror("glp_check_dup: ne = %d; invalid parameter\n"); - if (ne > 0 && ia == NULL) - xerror("glp_check_dup: ia = %p; invalid parameter\n", ia); - if (ne > 0 && ja == NULL) - xerror("glp_check_dup: ja = %p; invalid parameter\n", ja); - for (k = 1; k <= ne; k++) - { i = ia[k], j = ja[k]; - if (!(1 <= i && i <= m && 1 <= j && j <= n)) - { ret = -k; - goto done; - } - } - if (m == 0 || n == 0) - { ret = 0; - goto done; - } - /* allocate working arrays */ - ptr = xcalloc(1+m, sizeof(int)); - next = xcalloc(1+ne, sizeof(int)); - flag = xcalloc(1+n, sizeof(char)); - /* build row lists */ - for (i = 1; i <= m; i++) - ptr[i] = 0; - for (k = 1; k <= ne; k++) - { i = ia[k]; - next[k] = ptr[i]; - ptr[i] = k; - } - /* clear column flags */ - for (j = 1; j <= n; j++) - flag[j] = 0; - /* check for duplicate elements */ - for (i = 1; i <= m; i++) - { for (k = ptr[i]; k != 0; k = next[k]) - { j = ja[k]; - if (flag[j]) - { /* find first element (i,j) */ - for (k = 1; k <= ne; k++) - if (ia[k] == i && ja[k] == j) break; - xassert(k <= ne); - /* find next (duplicate) element (i,j) */ - for (k++; k <= ne; k++) - if (ia[k] == i && ja[k] == j) break; - xassert(k <= ne); - ret = +k; - goto skip; - } - flag[j] = 1; - } - /* clear column flags */ - for (k = ptr[i]; k != 0; k = next[k]) - flag[ja[k]] = 0; - } - /* no duplicate element found */ - ret = 0; -skip: /* free working arrays */ - xfree(ptr); - xfree(next); - xfree(flag); -done: return ret; -} - -/*********************************************************************** -* NAME -* -* glp_sort_matrix - sort elements of the constraint matrix -* -* SYNOPSIS -* -* void glp_sort_matrix(glp_prob *P); -* -* DESCRIPTION -* -* The routine glp_sort_matrix sorts elements of the constraint matrix -* rebuilding its row and column linked lists. On exit from the routine -* the constraint matrix is not changed, however, elements in the row -* linked lists become ordered by ascending column indices, and the -* elements in the column linked lists become ordered by ascending row -* indices. */ - -void glp_sort_matrix(glp_prob *P) -{ GLPAIJ *aij; - int i, j; - if (P == NULL || P->magic != GLP_PROB_MAGIC) - xerror("glp_sort_matrix: P = %p; invalid problem object\n", - P); - /* rebuild row linked lists */ - for (i = P->m; i >= 1; i--) - P->row[i]->ptr = NULL; - for (j = P->n; j >= 1; j--) - { for (aij = P->col[j]->ptr; aij != NULL; aij = aij->c_next) - { i = aij->row->i; - aij->r_prev = NULL; - aij->r_next = P->row[i]->ptr; - if (aij->r_next != NULL) aij->r_next->r_prev = aij; - P->row[i]->ptr = aij; - } - } - /* rebuild column linked lists */ - for (j = P->n; j >= 1; j--) - P->col[j]->ptr = NULL; - for (i = P->m; i >= 1; i--) - { for (aij = P->row[i]->ptr; aij != NULL; aij = aij->r_next) - { j = aij->col->j; - aij->c_prev = NULL; - aij->c_next = P->col[j]->ptr; - if (aij->c_next != NULL) aij->c_next->c_prev = aij; - P->col[j]->ptr = aij; - } - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_del_rows - delete rows from problem object -* -* SYNOPSIS -* -* void glp_del_rows(glp_prob *lp, int nrs, const int num[]); -* -* DESCRIPTION -* -* The routine glp_del_rows deletes rows from the specified problem -* object. Ordinal numbers of rows to be deleted should be placed in -* locations num[1], ..., num[nrs], where nrs > 0. -* -* Note that deleting rows involves changing ordinal numbers of other -* rows remaining in the problem object. New ordinal numbers of the -* remaining rows are assigned under the assumption that the original -* order of rows is not changed. */ - -void glp_del_rows(glp_prob *lp, int nrs, const int num[]) -{ glp_tree *tree = lp->tree; - GLPROW *row; - int i, k, m_new; - /* mark rows to be deleted */ - if (!(1 <= nrs && nrs <= lp->m)) - xerror("glp_del_rows: nrs = %d; invalid number of rows\n", - nrs); - for (k = 1; k <= nrs; k++) - { /* take the number of row to be deleted */ - i = num[k]; - /* obtain pointer to i-th row */ - if (!(1 <= i && i <= lp->m)) - xerror("glp_del_rows: num[%d] = %d; row number out of range" - "\n", k, i); - row = lp->row[i]; - if (tree != NULL && tree->reason != 0) - { if (!(tree->reason == GLP_IROWGEN || - tree->reason == GLP_ICUTGEN)) - xerror("glp_del_rows: operation not allowed\n"); - xassert(tree->curr != NULL); - if (row->level != tree->curr->level) - xerror("glp_del_rows: num[%d] = %d; invalid attempt to d" - "elete row created not in current subproblem\n", k,i); - if (row->stat != GLP_BS) - xerror("glp_del_rows: num[%d] = %d; invalid attempt to d" - "elete active row (constraint)\n", k, i); - tree->reinv = 1; - } - /* check that the row is not marked yet */ - if (row->i == 0) - xerror("glp_del_rows: num[%d] = %d; duplicate row numbers n" - "ot allowed\n", k, i); - /* erase symbolic name assigned to the row */ - glp_set_row_name(lp, i, NULL); - xassert(row->node == NULL); - /* erase corresponding row of the constraint matrix */ - glp_set_mat_row(lp, i, 0, NULL, NULL); - xassert(row->ptr == NULL); - /* mark the row to be deleted */ - row->i = 0; - } - /* delete all marked rows from the row list */ - m_new = 0; - for (i = 1; i <= lp->m; i++) - { /* obtain pointer to i-th row */ - row = lp->row[i]; - /* check if the row is marked */ - if (row->i == 0) - { /* it is marked, delete it */ - dmp_free_atom(lp->pool, row, sizeof(GLPROW)); - } - else - { /* it is not marked; keep it */ - row->i = ++m_new; - lp->row[row->i] = row; - } - } - /* set new number of rows */ - lp->m = m_new; - /* invalidate the basis factorization */ - lp->valid = 0; - return; -} - -/*********************************************************************** -* NAME -* -* glp_del_cols - delete columns from problem object -* -* SYNOPSIS -* -* void glp_del_cols(glp_prob *lp, int ncs, const int num[]); -* -* DESCRIPTION -* -* The routine glp_del_cols deletes columns from the specified problem -* object. Ordinal numbers of columns to be deleted should be placed in -* locations num[1], ..., num[ncs], where ncs > 0. -* -* Note that deleting columns involves changing ordinal numbers of -* other columns remaining in the problem object. New ordinal numbers -* of the remaining columns are assigned under the assumption that the -* original order of columns is not changed. */ - -void glp_del_cols(glp_prob *lp, int ncs, const int num[]) -{ glp_tree *tree = lp->tree; - GLPCOL *col; - int j, k, n_new; - if (tree != NULL && tree->reason != 0) - xerror("glp_del_cols: operation not allowed\n"); - /* mark columns to be deleted */ - if (!(1 <= ncs && ncs <= lp->n)) - xerror("glp_del_cols: ncs = %d; invalid number of columns\n", - ncs); - for (k = 1; k <= ncs; k++) - { /* take the number of column to be deleted */ - j = num[k]; - /* obtain pointer to j-th column */ - if (!(1 <= j && j <= lp->n)) - xerror("glp_del_cols: num[%d] = %d; column number out of ra" - "nge", k, j); - col = lp->col[j]; - /* check that the column is not marked yet */ - if (col->j == 0) - xerror("glp_del_cols: num[%d] = %d; duplicate column number" - "s not allowed\n", k, j); - /* erase symbolic name assigned to the column */ - glp_set_col_name(lp, j, NULL); - xassert(col->node == NULL); - /* erase corresponding column of the constraint matrix */ - glp_set_mat_col(lp, j, 0, NULL, NULL); - xassert(col->ptr == NULL); - /* mark the column to be deleted */ - col->j = 0; - /* if it is basic, invalidate the basis factorization */ - if (col->stat == GLP_BS) lp->valid = 0; - } - /* delete all marked columns from the column list */ - n_new = 0; - for (j = 1; j <= lp->n; j++) - { /* obtain pointer to j-th column */ - col = lp->col[j]; - /* check if the column is marked */ - if (col->j == 0) - { /* it is marked; delete it */ - dmp_free_atom(lp->pool, col, sizeof(GLPCOL)); - } - else - { /* it is not marked; keep it */ - col->j = ++n_new; - lp->col[col->j] = col; - } - } - /* set new number of columns */ - lp->n = n_new; - /* if the basis header is still valid, adjust it */ - if (lp->valid) - { int m = lp->m; - int *head = lp->head; - for (j = 1; j <= n_new; j++) - { k = lp->col[j]->bind; - if (k != 0) - { xassert(1 <= k && k <= m); - head[k] = m + j; - } - } - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_copy_prob - copy problem object content -* -* SYNOPSIS -* -* void glp_copy_prob(glp_prob *dest, glp_prob *prob, int names); -* -* DESCRIPTION -* -* The routine glp_copy_prob copies the content of the problem object -* prob to the problem object dest. -* -* The parameter names is a flag. If it is non-zero, the routine also -* copies all symbolic names; otherwise, if it is zero, symbolic names -* are not copied. */ - -void glp_copy_prob(glp_prob *dest, glp_prob *prob, int names) -{ glp_tree *tree = dest->tree; - glp_bfcp bfcp; - int i, j, len, *ind; - double *val; - if (tree != NULL && tree->reason != 0) - xerror("glp_copy_prob: operation not allowed\n"); - if (dest == prob) - xerror("glp_copy_prob: copying problem object to itself not al" - "lowed\n"); - if (!(names == GLP_ON || names == GLP_OFF)) - xerror("glp_copy_prob: names = %d; invalid parameter\n", - names); - glp_erase_prob(dest); - if (names && prob->name != NULL) - glp_set_prob_name(dest, prob->name); - if (names && prob->obj != NULL) - glp_set_obj_name(dest, prob->obj); - dest->dir = prob->dir; - dest->c0 = prob->c0; - if (prob->m > 0) - glp_add_rows(dest, prob->m); - if (prob->n > 0) - glp_add_cols(dest, prob->n); - glp_get_bfcp(prob, &bfcp); - glp_set_bfcp(dest, &bfcp); - dest->pbs_stat = prob->pbs_stat; - dest->dbs_stat = prob->dbs_stat; - dest->obj_val = prob->obj_val; - dest->some = prob->some; - dest->ipt_stat = prob->ipt_stat; - dest->ipt_obj = prob->ipt_obj; - dest->mip_stat = prob->mip_stat; - dest->mip_obj = prob->mip_obj; - for (i = 1; i <= prob->m; i++) - { GLPROW *to = dest->row[i]; - GLPROW *from = prob->row[i]; - if (names && from->name != NULL) - glp_set_row_name(dest, i, from->name); - to->type = from->type; - to->lb = from->lb; - to->ub = from->ub; - to->rii = from->rii; - to->stat = from->stat; - to->prim = from->prim; - to->dual = from->dual; - to->pval = from->pval; - to->dval = from->dval; - to->mipx = from->mipx; - } - ind = xcalloc(1+prob->m, sizeof(int)); - val = xcalloc(1+prob->m, sizeof(double)); - for (j = 1; j <= prob->n; j++) - { GLPCOL *to = dest->col[j]; - GLPCOL *from = prob->col[j]; - if (names && from->name != NULL) - glp_set_col_name(dest, j, from->name); - to->kind = from->kind; - to->type = from->type; - to->lb = from->lb; - to->ub = from->ub; - to->coef = from->coef; - len = glp_get_mat_col(prob, j, ind, val); - glp_set_mat_col(dest, j, len, ind, val); - to->sjj = from->sjj; - to->stat = from->stat; - to->prim = from->prim; - to->dual = from->dual; - to->pval = from->pval; - to->dval = from->dval; - to->mipx = from->mipx; - } - xfree(ind); - xfree(val); - return; -} - -/*********************************************************************** -* NAME -* -* glp_erase_prob - erase problem object content -* -* SYNOPSIS -* -* void glp_erase_prob(glp_prob *lp); -* -* DESCRIPTION -* -* The routine glp_erase_prob erases the content of the specified -* problem object. The effect of this operation is the same as if the -* problem object would be deleted with the routine glp_delete_prob and -* then created anew with the routine glp_create_prob, with exception -* that the handle (pointer) to the problem object remains valid. */ - -static void delete_prob(glp_prob *lp); - -void glp_erase_prob(glp_prob *lp) -{ glp_tree *tree = lp->tree; - if (tree != NULL && tree->reason != 0) - xerror("glp_erase_prob: operation not allowed\n"); - delete_prob(lp); - create_prob(lp); - return; -} - -/*********************************************************************** -* NAME -* -* glp_delete_prob - delete problem object -* -* SYNOPSIS -* -* void glp_delete_prob(glp_prob *lp); -* -* DESCRIPTION -* -* The routine glp_delete_prob deletes the specified problem object and -* frees all the memory allocated to it. */ - -static void delete_prob(glp_prob *lp) -{ lp->magic = 0x3F3F3F3F; - dmp_delete_pool(lp->pool); -#if 0 /* 17/XI-2009 */ - xfree(lp->cps); -#else - if (lp->parms != NULL) xfree(lp->parms); -#endif - xassert(lp->tree == NULL); -#if 0 - if (lp->cwa != NULL) xfree(lp->cwa); -#endif - xfree(lp->row); - xfree(lp->col); - if (lp->r_tree != NULL) avl_delete_tree(lp->r_tree); - if (lp->c_tree != NULL) avl_delete_tree(lp->c_tree); - xfree(lp->head); - if (lp->bfcp != NULL) xfree(lp->bfcp); - if (lp->bfd != NULL) bfd_delete_it(lp->bfd); - return; -} - -void glp_delete_prob(glp_prob *lp) -{ glp_tree *tree = lp->tree; - if (tree != NULL && tree->reason != 0) - xerror("glp_delete_prob: operation not allowed\n"); - delete_prob(lp); - xfree(lp); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi02.c b/resources/3rdparty/glpk-4.53/src/glpapi02.c deleted file mode 100644 index 5b74aab95..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi02.c +++ /dev/null @@ -1,492 +0,0 @@ -/* glpapi02.c (problem retrieving routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "prob.h" - -/*********************************************************************** -* NAME -* -* glp_get_prob_name - retrieve problem name -* -* SYNOPSIS -* -* const char *glp_get_prob_name(glp_prob *lp); -* -* RETURNS -* -* The routine glp_get_prob_name returns a pointer to an internal -* buffer, which contains symbolic name of the problem. However, if the -* problem has no assigned name, the routine returns NULL. */ - -const char *glp_get_prob_name(glp_prob *lp) -{ char *name; - name = lp->name; - return name; -} - -/*********************************************************************** -* NAME -* -* glp_get_obj_name - retrieve objective function name -* -* SYNOPSIS -* -* const char *glp_get_obj_name(glp_prob *lp); -* -* RETURNS -* -* The routine glp_get_obj_name returns a pointer to an internal -* buffer, which contains a symbolic name of the objective function. -* However, if the objective function has no assigned name, the routine -* returns NULL. */ - -const char *glp_get_obj_name(glp_prob *lp) -{ char *name; - name = lp->obj; - return name; -} - -/*********************************************************************** -* NAME -* -* glp_get_obj_dir - retrieve optimization direction flag -* -* SYNOPSIS -* -* int glp_get_obj_dir(glp_prob *lp); -* -* RETURNS -* -* The routine glp_get_obj_dir returns the optimization direction flag -* (i.e. "sense" of the objective function): -* -* GLP_MIN - minimization; -* GLP_MAX - maximization. */ - -int glp_get_obj_dir(glp_prob *lp) -{ int dir = lp->dir; - return dir; -} - -/*********************************************************************** -* NAME -* -* glp_get_num_rows - retrieve number of rows -* -* SYNOPSIS -* -* int glp_get_num_rows(glp_prob *lp); -* -* RETURNS -* -* The routine glp_get_num_rows returns the current number of rows in -* the specified problem object. */ - -int glp_get_num_rows(glp_prob *lp) -{ int m = lp->m; - return m; -} - -/*********************************************************************** -* NAME -* -* glp_get_num_cols - retrieve number of columns -* -* SYNOPSIS -* -* int glp_get_num_cols(glp_prob *lp); -* -* RETURNS -* -* The routine glp_get_num_cols returns the current number of columns -* in the specified problem object. */ - -int glp_get_num_cols(glp_prob *lp) -{ int n = lp->n; - return n; -} - -/*********************************************************************** -* NAME -* -* glp_get_row_name - retrieve row name -* -* SYNOPSIS -* -* const char *glp_get_row_name(glp_prob *lp, int i); -* -* RETURNS -* -* The routine glp_get_row_name returns a pointer to an internal -* buffer, which contains symbolic name of i-th row. However, if i-th -* row has no assigned name, the routine returns NULL. */ - -const char *glp_get_row_name(glp_prob *lp, int i) -{ char *name; - if (!(1 <= i && i <= lp->m)) - xerror("glp_get_row_name: i = %d; row number out of range\n", - i); - name = lp->row[i]->name; - return name; -} - -/*********************************************************************** -* NAME -* -* glp_get_col_name - retrieve column name -* -* SYNOPSIS -* -* const char *glp_get_col_name(glp_prob *lp, int j); -* -* RETURNS -* -* The routine glp_get_col_name returns a pointer to an internal -* buffer, which contains symbolic name of j-th column. However, if j-th -* column has no assigned name, the routine returns NULL. */ - -const char *glp_get_col_name(glp_prob *lp, int j) -{ char *name; - if (!(1 <= j && j <= lp->n)) - xerror("glp_get_col_name: j = %d; column number out of range\n" - , j); - name = lp->col[j]->name; - return name; -} - -/*********************************************************************** -* NAME -* -* glp_get_row_type - retrieve row type -* -* SYNOPSIS -* -* int glp_get_row_type(glp_prob *lp, int i); -* -* RETURNS -* -* The routine glp_get_row_type returns the type of i-th row, i.e. the -* type of corresponding auxiliary variable, as follows: -* -* GLP_FR - free (unbounded) variable; -* GLP_LO - variable with lower bound; -* GLP_UP - variable with upper bound; -* GLP_DB - double-bounded variable; -* GLP_FX - fixed variable. */ - -int glp_get_row_type(glp_prob *lp, int i) -{ if (!(1 <= i && i <= lp->m)) - xerror("glp_get_row_type: i = %d; row number out of range\n", - i); - return lp->row[i]->type; -} - -/*********************************************************************** -* NAME -* -* glp_get_row_lb - retrieve row lower bound -* -* SYNOPSIS -* -* double glp_get_row_lb(glp_prob *lp, int i); -* -* RETURNS -* -* The routine glp_get_row_lb returns the lower bound of i-th row, i.e. -* the lower bound of corresponding auxiliary variable. However, if the -* row has no lower bound, the routine returns -DBL_MAX. */ - -double glp_get_row_lb(glp_prob *lp, int i) -{ double lb; - if (!(1 <= i && i <= lp->m)) - xerror("glp_get_row_lb: i = %d; row number out of range\n", i); - switch (lp->row[i]->type) - { case GLP_FR: - case GLP_UP: - lb = -DBL_MAX; break; - case GLP_LO: - case GLP_DB: - case GLP_FX: - lb = lp->row[i]->lb; break; - default: - xassert(lp != lp); - } - return lb; -} - -/*********************************************************************** -* NAME -* -* glp_get_row_ub - retrieve row upper bound -* -* SYNOPSIS -* -* double glp_get_row_ub(glp_prob *lp, int i); -* -* RETURNS -* -* The routine glp_get_row_ub returns the upper bound of i-th row, i.e. -* the upper bound of corresponding auxiliary variable. However, if the -* row has no upper bound, the routine returns +DBL_MAX. */ - -double glp_get_row_ub(glp_prob *lp, int i) -{ double ub; - if (!(1 <= i && i <= lp->m)) - xerror("glp_get_row_ub: i = %d; row number out of range\n", i); - switch (lp->row[i]->type) - { case GLP_FR: - case GLP_LO: - ub = +DBL_MAX; break; - case GLP_UP: - case GLP_DB: - case GLP_FX: - ub = lp->row[i]->ub; break; - default: - xassert(lp != lp); - } - return ub; -} - -/*********************************************************************** -* NAME -* -* glp_get_col_type - retrieve column type -* -* SYNOPSIS -* -* int glp_get_col_type(glp_prob *lp, int j); -* -* RETURNS -* -* The routine glp_get_col_type returns the type of j-th column, i.e. -* the type of corresponding structural variable, as follows: -* -* GLP_FR - free (unbounded) variable; -* GLP_LO - variable with lower bound; -* GLP_UP - variable with upper bound; -* GLP_DB - double-bounded variable; -* GLP_FX - fixed variable. */ - -int glp_get_col_type(glp_prob *lp, int j) -{ if (!(1 <= j && j <= lp->n)) - xerror("glp_get_col_type: j = %d; column number out of range\n" - , j); - return lp->col[j]->type; -} - -/*********************************************************************** -* NAME -* -* glp_get_col_lb - retrieve column lower bound -* -* SYNOPSIS -* -* double glp_get_col_lb(glp_prob *lp, int j); -* -* RETURNS -* -* The routine glp_get_col_lb returns the lower bound of j-th column, -* i.e. the lower bound of corresponding structural variable. However, -* if the column has no lower bound, the routine returns -DBL_MAX. */ - -double glp_get_col_lb(glp_prob *lp, int j) -{ double lb; - if (!(1 <= j && j <= lp->n)) - xerror("glp_get_col_lb: j = %d; column number out of range\n", - j); - switch (lp->col[j]->type) - { case GLP_FR: - case GLP_UP: - lb = -DBL_MAX; break; - case GLP_LO: - case GLP_DB: - case GLP_FX: - lb = lp->col[j]->lb; break; - default: - xassert(lp != lp); - } - return lb; -} - -/*********************************************************************** -* NAME -* -* glp_get_col_ub - retrieve column upper bound -* -* SYNOPSIS -* -* double glp_get_col_ub(glp_prob *lp, int j); -* -* RETURNS -* -* The routine glp_get_col_ub returns the upper bound of j-th column, -* i.e. the upper bound of corresponding structural variable. However, -* if the column has no upper bound, the routine returns +DBL_MAX. */ - -double glp_get_col_ub(glp_prob *lp, int j) -{ double ub; - if (!(1 <= j && j <= lp->n)) - xerror("glp_get_col_ub: j = %d; column number out of range\n", - j); - switch (lp->col[j]->type) - { case GLP_FR: - case GLP_LO: - ub = +DBL_MAX; break; - case GLP_UP: - case GLP_DB: - case GLP_FX: - ub = lp->col[j]->ub; break; - default: - xassert(lp != lp); - } - return ub; -} - -/*********************************************************************** -* NAME -* -* glp_get_obj_coef - retrieve obj. coefficient or constant term -* -* SYNOPSIS -* -* double glp_get_obj_coef(glp_prob *lp, int j); -* -* RETURNS -* -* The routine glp_get_obj_coef returns the objective coefficient at -* j-th structural variable (column) of the specified problem object. -* -* If the parameter j is zero, the routine returns the constant term -* ("shift") of the objective function. */ - -double glp_get_obj_coef(glp_prob *lp, int j) -{ if (!(0 <= j && j <= lp->n)) - xerror("glp_get_obj_coef: j = %d; column number out of range\n" - , j); - return j == 0 ? lp->c0 : lp->col[j]->coef; -} - -/*********************************************************************** -* NAME -* -* glp_get_num_nz - retrieve number of constraint coefficients -* -* SYNOPSIS -* -* int glp_get_num_nz(glp_prob *lp); -* -* RETURNS -* -* The routine glp_get_num_nz returns the number of (non-zero) elements -* in the constraint matrix of the specified problem object. */ - -int glp_get_num_nz(glp_prob *lp) -{ int nnz = lp->nnz; - return nnz; -} - -/*********************************************************************** -* NAME -* -* glp_get_mat_row - retrieve row of the constraint matrix -* -* SYNOPSIS -* -* int glp_get_mat_row(glp_prob *lp, int i, int ind[], double val[]); -* -* DESCRIPTION -* -* The routine glp_get_mat_row scans (non-zero) elements of i-th row -* of the constraint matrix of the specified problem object and stores -* their column indices and numeric values to locations ind[1], ..., -* ind[len] and val[1], ..., val[len], respectively, where 0 <= len <= n -* is the number of elements in i-th row, n is the number of columns. -* -* The parameter ind and/or val can be specified as NULL, in which case -* corresponding information is not stored. -* -* RETURNS -* -* The routine glp_get_mat_row returns the length len, i.e. the number -* of (non-zero) elements in i-th row. */ - -int glp_get_mat_row(glp_prob *lp, int i, int ind[], double val[]) -{ GLPAIJ *aij; - int len; - if (!(1 <= i && i <= lp->m)) - xerror("glp_get_mat_row: i = %d; row number out of range\n", - i); - len = 0; - for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) - { len++; - if (ind != NULL) ind[len] = aij->col->j; - if (val != NULL) val[len] = aij->val; - } - xassert(len <= lp->n); - return len; -} - -/*********************************************************************** -* NAME -* -* glp_get_mat_col - retrieve column of the constraint matrix -* -* SYNOPSIS -* -* int glp_get_mat_col(glp_prob *lp, int j, int ind[], double val[]); -* -* DESCRIPTION -* -* The routine glp_get_mat_col scans (non-zero) elements of j-th column -* of the constraint matrix of the specified problem object and stores -* their row indices and numeric values to locations ind[1], ..., -* ind[len] and val[1], ..., val[len], respectively, where 0 <= len <= m -* is the number of elements in j-th column, m is the number of rows. -* -* The parameter ind or/and val can be specified as NULL, in which case -* corresponding information is not stored. -* -* RETURNS -* -* The routine glp_get_mat_col returns the length len, i.e. the number -* of (non-zero) elements in j-th column. */ - -int glp_get_mat_col(glp_prob *lp, int j, int ind[], double val[]) -{ GLPAIJ *aij; - int len; - if (!(1 <= j && j <= lp->n)) - xerror("glp_get_mat_col: j = %d; column number out of range\n", - j); - len = 0; - for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next) - { len++; - if (ind != NULL) ind[len] = aij->row->i; - if (val != NULL) val[len] = aij->val; - } - xassert(len <= lp->m); - return len; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi03.c b/resources/3rdparty/glpk-4.53/src/glpapi03.c deleted file mode 100644 index daf9174af..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi03.c +++ /dev/null @@ -1,167 +0,0 @@ -/* glpapi03.c (row and column searching routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "prob.h" - -/*********************************************************************** -* NAME -* -* glp_create_index - create the name index -* -* SYNOPSIS -* -* void glp_create_index(glp_prob *lp); -* -* DESCRIPTION -* -* The routine glp_create_index creates the name index for the -* specified problem object. The name index is an auxiliary data -* structure, which is intended to quickly (i.e. for logarithmic time) -* find rows and columns by their names. -* -* This routine can be called at any time. If the name index already -* exists, the routine does nothing. */ - -void glp_create_index(glp_prob *lp) -{ GLPROW *row; - GLPCOL *col; - int i, j; - /* create row name index */ - if (lp->r_tree == NULL) - { lp->r_tree = avl_create_tree(avl_strcmp, NULL); - for (i = 1; i <= lp->m; i++) - { row = lp->row[i]; - xassert(row->node == NULL); - if (row->name != NULL) - { row->node = avl_insert_node(lp->r_tree, row->name); - avl_set_node_link(row->node, row); - } - } - } - /* create column name index */ - if (lp->c_tree == NULL) - { lp->c_tree = avl_create_tree(avl_strcmp, NULL); - for (j = 1; j <= lp->n; j++) - { col = lp->col[j]; - xassert(col->node == NULL); - if (col->name != NULL) - { col->node = avl_insert_node(lp->c_tree, col->name); - avl_set_node_link(col->node, col); - } - } - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_find_row - find row by its name -* -* SYNOPSIS -* -* int glp_find_row(glp_prob *lp, const char *name); -* -* RETURNS -* -* The routine glp_find_row returns the ordinal number of a row, -* which is assigned (by the routine glp_set_row_name) the specified -* symbolic name. If no such row exists, the routine returns 0. */ - -int glp_find_row(glp_prob *lp, const char *name) -{ AVLNODE *node; - int i = 0; - if (lp->r_tree == NULL) - xerror("glp_find_row: row name index does not exist\n"); - if (!(name == NULL || name[0] == '\0' || strlen(name) > 255)) - { node = avl_find_node(lp->r_tree, name); - if (node != NULL) - i = ((GLPROW *)avl_get_node_link(node))->i; - } - return i; -} - -/*********************************************************************** -* NAME -* -* glp_find_col - find column by its name -* -* SYNOPSIS -* -* int glp_find_col(glp_prob *lp, const char *name); -* -* RETURNS -* -* The routine glp_find_col returns the ordinal number of a column, -* which is assigned (by the routine glp_set_col_name) the specified -* symbolic name. If no such column exists, the routine returns 0. */ - -int glp_find_col(glp_prob *lp, const char *name) -{ AVLNODE *node; - int j = 0; - if (lp->c_tree == NULL) - xerror("glp_find_col: column name index does not exist\n"); - if (!(name == NULL || name[0] == '\0' || strlen(name) > 255)) - { node = avl_find_node(lp->c_tree, name); - if (node != NULL) - j = ((GLPCOL *)avl_get_node_link(node))->j; - } - return j; -} - -/*********************************************************************** -* NAME -* -* glp_delete_index - delete the name index -* -* SYNOPSIS -* -* void glp_delete_index(glp_prob *lp); -* -* DESCRIPTION -* -* The routine glp_delete_index deletes the name index previously -* created by the routine glp_create_index and frees the memory -* allocated to this auxiliary data structure. -* -* This routine can be called at any time. If the name index does not -* exist, the routine does nothing. */ - -void glp_delete_index(glp_prob *lp) -{ int i, j; - /* delete row name index */ - if (lp->r_tree != NULL) - { for (i = 1; i <= lp->m; i++) lp->row[i]->node = NULL; - avl_delete_tree(lp->r_tree), lp->r_tree = NULL; - } - /* delete column name index */ - if (lp->c_tree != NULL) - { for (j = 1; j <= lp->n; j++) lp->col[j]->node = NULL; - avl_delete_tree(lp->c_tree), lp->c_tree = NULL; - } - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi04.c b/resources/3rdparty/glpk-4.53/src/glpapi04.c deleted file mode 100644 index adabb02c1..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi04.c +++ /dev/null @@ -1,157 +0,0 @@ -/* glpapi04.c (problem scaling routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "prob.h" - -/*********************************************************************** -* NAME -* -* glp_set_rii - set (change) row scale factor -* -* SYNOPSIS -* -* void glp_set_rii(glp_prob *lp, int i, double rii); -* -* DESCRIPTION -* -* The routine glp_set_rii sets (changes) the scale factor r[i,i] for -* i-th row of the specified problem object. */ - -void glp_set_rii(glp_prob *lp, int i, double rii) -{ if (!(1 <= i && i <= lp->m)) - xerror("glp_set_rii: i = %d; row number out of range\n", i); - if (rii <= 0.0) - xerror("glp_set_rii: i = %d; rii = %g; invalid scale factor\n", - i, rii); - if (lp->valid && lp->row[i]->rii != rii) - { GLPAIJ *aij; - for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) - { if (aij->col->stat == GLP_BS) - { /* invalidate the basis factorization */ - lp->valid = 0; - break; - } - } - } - lp->row[i]->rii = rii; - return; -} - -/*********************************************************************** -* NAME -* -* glp_set sjj - set (change) column scale factor -* -* SYNOPSIS -* -* void glp_set_sjj(glp_prob *lp, int j, double sjj); -* -* DESCRIPTION -* -* The routine glp_set_sjj sets (changes) the scale factor s[j,j] for -* j-th column of the specified problem object. */ - -void glp_set_sjj(glp_prob *lp, int j, double sjj) -{ if (!(1 <= j && j <= lp->n)) - xerror("glp_set_sjj: j = %d; column number out of range\n", j); - if (sjj <= 0.0) - xerror("glp_set_sjj: j = %d; sjj = %g; invalid scale factor\n", - j, sjj); - if (lp->valid && lp->col[j]->sjj != sjj && lp->col[j]->stat == - GLP_BS) - { /* invalidate the basis factorization */ - lp->valid = 0; - } - lp->col[j]->sjj = sjj; - return; -} - -/*********************************************************************** -* NAME -* -* glp_get_rii - retrieve row scale factor -* -* SYNOPSIS -* -* double glp_get_rii(glp_prob *lp, int i); -* -* RETURNS -* -* The routine glp_get_rii returns current scale factor r[i,i] for i-th -* row of the specified problem object. */ - -double glp_get_rii(glp_prob *lp, int i) -{ if (!(1 <= i && i <= lp->m)) - xerror("glp_get_rii: i = %d; row number out of range\n", i); - return lp->row[i]->rii; -} - -/*********************************************************************** -* NAME -* -* glp_get_sjj - retrieve column scale factor -* -* SYNOPSIS -* -* double glp_get_sjj(glp_prob *lp, int j); -* -* RETURNS -* -* The routine glp_get_sjj returns current scale factor s[j,j] for j-th -* column of the specified problem object. */ - -double glp_get_sjj(glp_prob *lp, int j) -{ if (!(1 <= j && j <= lp->n)) - xerror("glp_get_sjj: j = %d; column number out of range\n", j); - return lp->col[j]->sjj; -} - -/*********************************************************************** -* NAME -* -* glp_unscale_prob - unscale problem data -* -* SYNOPSIS -* -* void glp_unscale_prob(glp_prob *lp); -* -* DESCRIPTION -* -* The routine glp_unscale_prob performs unscaling of problem data for -* the specified problem object. -* -* "Unscaling" means replacing the current scaling matrices R and S by -* unity matrices that cancels the scaling effect. */ - -void glp_unscale_prob(glp_prob *lp) -{ int m = glp_get_num_rows(lp); - int n = glp_get_num_cols(lp); - int i, j; - for (i = 1; i <= m; i++) glp_set_rii(lp, i, 1.0); - for (j = 1; j <= n; j++) glp_set_sjj(lp, j, 1.0); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi05.c b/resources/3rdparty/glpk-4.53/src/glpapi05.c deleted file mode 100644 index b18845522..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi05.c +++ /dev/null @@ -1,169 +0,0 @@ -/* glpapi05.c (LP basis constructing routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "prob.h" - -/*********************************************************************** -* NAME -* -* glp_set_row_stat - set (change) row status -* -* SYNOPSIS -* -* void glp_set_row_stat(glp_prob *lp, int i, int stat); -* -* DESCRIPTION -* -* The routine glp_set_row_stat sets (changes) status of the auxiliary -* variable associated with i-th row. -* -* The new status of the auxiliary variable should be specified by the -* parameter stat as follows: -* -* GLP_BS - basic variable; -* GLP_NL - non-basic variable; -* GLP_NU - non-basic variable on its upper bound; if the variable is -* not double-bounded, this means the same as GLP_NL (only in -* case of this routine); -* GLP_NF - the same as GLP_NL (only in case of this routine); -* GLP_NS - the same as GLP_NL (only in case of this routine). */ - -void glp_set_row_stat(glp_prob *lp, int i, int stat) -{ GLPROW *row; - if (!(1 <= i && i <= lp->m)) - xerror("glp_set_row_stat: i = %d; row number out of range\n", - i); - if (!(stat == GLP_BS || stat == GLP_NL || stat == GLP_NU || - stat == GLP_NF || stat == GLP_NS)) - xerror("glp_set_row_stat: i = %d; stat = %d; invalid status\n", - i, stat); - row = lp->row[i]; - if (stat != GLP_BS) - { switch (row->type) - { case GLP_FR: stat = GLP_NF; break; - case GLP_LO: stat = GLP_NL; break; - case GLP_UP: stat = GLP_NU; break; - case GLP_DB: if (stat != GLP_NU) stat = GLP_NL; break; - case GLP_FX: stat = GLP_NS; break; - default: xassert(row != row); - } - } - if (row->stat == GLP_BS && stat != GLP_BS || - row->stat != GLP_BS && stat == GLP_BS) - { /* invalidate the basis factorization */ - lp->valid = 0; - } - row->stat = stat; - return; -} - -/*********************************************************************** -* NAME -* -* glp_set_col_stat - set (change) column status -* -* SYNOPSIS -* -* void glp_set_col_stat(glp_prob *lp, int j, int stat); -* -* DESCRIPTION -* -* The routine glp_set_col_stat sets (changes) status of the structural -* variable associated with j-th column. -* -* The new status of the structural variable should be specified by the -* parameter stat as follows: -* -* GLP_BS - basic variable; -* GLP_NL - non-basic variable; -* GLP_NU - non-basic variable on its upper bound; if the variable is -* not double-bounded, this means the same as GLP_NL (only in -* case of this routine); -* GLP_NF - the same as GLP_NL (only in case of this routine); -* GLP_NS - the same as GLP_NL (only in case of this routine). */ - -void glp_set_col_stat(glp_prob *lp, int j, int stat) -{ GLPCOL *col; - if (!(1 <= j && j <= lp->n)) - xerror("glp_set_col_stat: j = %d; column number out of range\n" - , j); - if (!(stat == GLP_BS || stat == GLP_NL || stat == GLP_NU || - stat == GLP_NF || stat == GLP_NS)) - xerror("glp_set_col_stat: j = %d; stat = %d; invalid status\n", - j, stat); - col = lp->col[j]; - if (stat != GLP_BS) - { switch (col->type) - { case GLP_FR: stat = GLP_NF; break; - case GLP_LO: stat = GLP_NL; break; - case GLP_UP: stat = GLP_NU; break; - case GLP_DB: if (stat != GLP_NU) stat = GLP_NL; break; - case GLP_FX: stat = GLP_NS; break; - default: xassert(col != col); - } - } - if (col->stat == GLP_BS && stat != GLP_BS || - col->stat != GLP_BS && stat == GLP_BS) - { /* invalidate the basis factorization */ - lp->valid = 0; - } - col->stat = stat; - return; -} - -/*********************************************************************** -* NAME -* -* glp_std_basis - construct standard initial LP basis -* -* SYNOPSIS -* -* void glp_std_basis(glp_prob *lp); -* -* DESCRIPTION -* -* The routine glp_std_basis builds the "standard" (trivial) initial -* basis for the specified problem object. -* -* In the "standard" basis all auxiliary variables are basic, and all -* structural variables are non-basic. */ - -void glp_std_basis(glp_prob *lp) -{ int i, j; - /* make all auxiliary variables basic */ - for (i = 1; i <= lp->m; i++) - glp_set_row_stat(lp, i, GLP_BS); - /* make all structural variables non-basic */ - for (j = 1; j <= lp->n; j++) - { GLPCOL *col = lp->col[j]; - if (col->type == GLP_DB && fabs(col->lb) > fabs(col->ub)) - glp_set_col_stat(lp, j, GLP_NU); - else - glp_set_col_stat(lp, j, GLP_NL); - } - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi06.c b/resources/3rdparty/glpk-4.53/src/glpapi06.c deleted file mode 100644 index 53a2f9340..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi06.c +++ /dev/null @@ -1,822 +0,0 @@ -/* glpapi06.c (simplex method routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpios.h" -#include "glpnpp.h" -#include "glpspx.h" - -/*********************************************************************** -* NAME -* -* glp_simplex - solve LP problem with the simplex method -* -* SYNOPSIS -* -* int glp_simplex(glp_prob *P, const glp_smcp *parm); -* -* DESCRIPTION -* -* The routine glp_simplex is a driver to the LP solver based on the -* simplex method. This routine retrieves problem data from the -* specified problem object, calls the solver to solve the problem -* instance, and stores results of computations back into the problem -* object. -* -* The simplex solver has a set of control parameters. Values of the -* control parameters can be passed in a structure glp_smcp, which the -* parameter parm points to. -* -* The parameter parm can be specified as NULL, in which case the LP -* solver uses default settings. -* -* RETURNS -* -* 0 The LP problem instance has been successfully solved. This code -* does not necessarily mean that the solver has found optimal -* solution. It only means that the solution process was successful. -* -* GLP_EBADB -* Unable to start the search, because the initial basis specified -* in the problem object is invalid--the number of basic (auxiliary -* and structural) variables is not the same as the number of rows in -* the problem object. -* -* GLP_ESING -* Unable to start the search, because the basis matrix correspodning -* to the initial basis is singular within the working precision. -* -* GLP_ECOND -* Unable to start the search, because the basis matrix correspodning -* to the initial basis is ill-conditioned, i.e. its condition number -* is too large. -* -* GLP_EBOUND -* Unable to start the search, because some double-bounded variables -* have incorrect bounds. -* -* GLP_EFAIL -* The search was prematurely terminated due to the solver failure. -* -* GLP_EOBJLL -* The search was prematurely terminated, because the objective -* function being maximized has reached its lower limit and continues -* decreasing (dual simplex only). -* -* GLP_EOBJUL -* The search was prematurely terminated, because the objective -* function being minimized has reached its upper limit and continues -* increasing (dual simplex only). -* -* GLP_EITLIM -* The search was prematurely terminated, because the simplex -* iteration limit has been exceeded. -* -* GLP_ETMLIM -* The search was prematurely terminated, because the time limit has -* been exceeded. -* -* GLP_ENOPFS -* The LP problem instance has no primal feasible solution (only if -* the LP presolver is used). -* -* GLP_ENODFS -* The LP problem instance has no dual feasible solution (only if the -* LP presolver is used). */ - -static void trivial_lp(glp_prob *P, const glp_smcp *parm) -{ /* solve trivial LP which has empty constraint matrix */ - GLPROW *row; - GLPCOL *col; - int i, j; - double p_infeas, d_infeas, zeta; - P->valid = 0; - P->pbs_stat = P->dbs_stat = GLP_FEAS; - P->obj_val = P->c0; - P->some = 0; - p_infeas = d_infeas = 0.0; - /* make all auxiliary variables basic */ - for (i = 1; i <= P->m; i++) - { row = P->row[i]; - row->stat = GLP_BS; - row->prim = row->dual = 0.0; - /* check primal feasibility */ - if (row->type == GLP_LO || row->type == GLP_DB || - row->type == GLP_FX) - { /* row has lower bound */ - if (row->lb > + parm->tol_bnd) - { P->pbs_stat = GLP_NOFEAS; - if (P->some == 0 && parm->meth != GLP_PRIMAL) - P->some = i; - } - if (p_infeas < + row->lb) - p_infeas = + row->lb; - } - if (row->type == GLP_UP || row->type == GLP_DB || - row->type == GLP_FX) - { /* row has upper bound */ - if (row->ub < - parm->tol_bnd) - { P->pbs_stat = GLP_NOFEAS; - if (P->some == 0 && parm->meth != GLP_PRIMAL) - P->some = i; - } - if (p_infeas < - row->ub) - p_infeas = - row->ub; - } - } - /* determine scale factor for the objective row */ - zeta = 1.0; - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - if (zeta < fabs(col->coef)) zeta = fabs(col->coef); - } - zeta = (P->dir == GLP_MIN ? +1.0 : -1.0) / zeta; - /* make all structural variables non-basic */ - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - if (col->type == GLP_FR) - col->stat = GLP_NF, col->prim = 0.0; - else if (col->type == GLP_LO) -lo: col->stat = GLP_NL, col->prim = col->lb; - else if (col->type == GLP_UP) -up: col->stat = GLP_NU, col->prim = col->ub; - else if (col->type == GLP_DB) - { if (zeta * col->coef > 0.0) - goto lo; - else if (zeta * col->coef < 0.0) - goto up; - else if (fabs(col->lb) <= fabs(col->ub)) - goto lo; - else - goto up; - } - else if (col->type == GLP_FX) - col->stat = GLP_NS, col->prim = col->lb; - col->dual = col->coef; - P->obj_val += col->coef * col->prim; - /* check dual feasibility */ - if (col->type == GLP_FR || col->type == GLP_LO) - { /* column has no upper bound */ - if (zeta * col->dual < - parm->tol_dj) - { P->dbs_stat = GLP_NOFEAS; - if (P->some == 0 && parm->meth == GLP_PRIMAL) - P->some = P->m + j; - } - if (d_infeas < - zeta * col->dual) - d_infeas = - zeta * col->dual; - } - if (col->type == GLP_FR || col->type == GLP_UP) - { /* column has no lower bound */ - if (zeta * col->dual > + parm->tol_dj) - { P->dbs_stat = GLP_NOFEAS; - if (P->some == 0 && parm->meth == GLP_PRIMAL) - P->some = P->m + j; - } - if (d_infeas < + zeta * col->dual) - d_infeas = + zeta * col->dual; - } - } - /* simulate the simplex solver output */ - if (parm->msg_lev >= GLP_MSG_ON && parm->out_dly == 0) - { xprintf("~%6d: obj = %17.9e infeas = %10.3e\n", P->it_cnt, - P->obj_val, parm->meth == GLP_PRIMAL ? p_infeas : d_infeas); - } - if (parm->msg_lev >= GLP_MSG_ALL && parm->out_dly == 0) - { if (P->pbs_stat == GLP_FEAS && P->dbs_stat == GLP_FEAS) - xprintf("OPTIMAL SOLUTION FOUND\n"); - else if (P->pbs_stat == GLP_NOFEAS) - xprintf("PROBLEM HAS NO FEASIBLE SOLUTION\n"); - else if (parm->meth == GLP_PRIMAL) - xprintf("PROBLEM HAS UNBOUNDED SOLUTION\n"); - else - xprintf("PROBLEM HAS NO DUAL FEASIBLE SOLUTION\n"); - } - return; -} - -static int solve_lp(glp_prob *P, const glp_smcp *parm) -{ /* solve LP directly without using the preprocessor */ - int ret; - if (!glp_bf_exists(P)) - { ret = glp_factorize(P); - if (ret == 0) - ; - else if (ret == GLP_EBADB) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_simplex: initial basis is invalid\n"); - } - else if (ret == GLP_ESING) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_simplex: initial basis is singular\n"); - } - else if (ret == GLP_ECOND) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf( - "glp_simplex: initial basis is ill-conditioned\n"); - } - else - xassert(ret != ret); - if (ret != 0) goto done; - } - if (parm->meth == GLP_PRIMAL) - ret = spx_primal(P, parm); - else if (parm->meth == GLP_DUALP) - { ret = spx_dual(P, parm); - if (ret == GLP_EFAIL && P->valid) - ret = spx_primal(P, parm); - } - else if (parm->meth == GLP_DUAL) - ret = spx_dual(P, parm); - else - xassert(parm != parm); -done: return ret; -} - -static int preprocess_and_solve_lp(glp_prob *P, const glp_smcp *parm) -{ /* solve LP using the preprocessor */ - NPP *npp; - glp_prob *lp = NULL; - glp_bfcp bfcp; - int ret; - if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("Preprocessing...\n"); - /* create preprocessor workspace */ - npp = npp_create_wksp(); - /* load original problem into the preprocessor workspace */ - npp_load_prob(npp, P, GLP_OFF, GLP_SOL, GLP_OFF); - /* process LP prior to applying primal/dual simplex method */ - ret = npp_simplex(npp, parm); - if (ret == 0) - ; - else if (ret == GLP_ENOPFS) - { if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n"); - } - else if (ret == GLP_ENODFS) - { if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("PROBLEM HAS NO DUAL FEASIBLE SOLUTION\n"); - } - else - xassert(ret != ret); - if (ret != 0) goto done; - /* build transformed LP */ - lp = glp_create_prob(); - npp_build_prob(npp, lp); - /* if the transformed LP is empty, it has empty solution, which - is optimal */ - if (lp->m == 0 && lp->n == 0) - { lp->pbs_stat = lp->dbs_stat = GLP_FEAS; - lp->obj_val = lp->c0; - if (parm->msg_lev >= GLP_MSG_ON && parm->out_dly == 0) - { xprintf("~%6d: obj = %17.9e infeas = %10.3e\n", P->it_cnt, - lp->obj_val, 0.0); - } - if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("OPTIMAL SOLUTION FOUND BY LP PREPROCESSOR\n"); - goto post; - } - if (parm->msg_lev >= GLP_MSG_ALL) - { xprintf("%d row%s, %d column%s, %d non-zero%s\n", - lp->m, lp->m == 1 ? "" : "s", lp->n, lp->n == 1 ? "" : "s", - lp->nnz, lp->nnz == 1 ? "" : "s"); - } - /* inherit basis factorization control parameters */ - glp_get_bfcp(P, &bfcp); - glp_set_bfcp(lp, &bfcp); - /* scale the transformed problem */ - { ENV *env = get_env_ptr(); - int term_out = env->term_out; - if (!term_out || parm->msg_lev < GLP_MSG_ALL) - env->term_out = GLP_OFF; - else - env->term_out = GLP_ON; - glp_scale_prob(lp, GLP_SF_AUTO); - env->term_out = term_out; - } - /* build advanced initial basis */ - { ENV *env = get_env_ptr(); - int term_out = env->term_out; - if (!term_out || parm->msg_lev < GLP_MSG_ALL) - env->term_out = GLP_OFF; - else - env->term_out = GLP_ON; - glp_adv_basis(lp, 0); - env->term_out = term_out; - } - /* solve the transformed LP */ - lp->it_cnt = P->it_cnt; - ret = solve_lp(lp, parm); - P->it_cnt = lp->it_cnt; - /* only optimal solution can be postprocessed */ - if (!(ret == 0 && lp->pbs_stat == GLP_FEAS && lp->dbs_stat == - GLP_FEAS)) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_simplex: unable to recover undefined or non-op" - "timal solution\n"); - if (ret == 0) - { if (lp->pbs_stat == GLP_NOFEAS) - ret = GLP_ENOPFS; - else if (lp->dbs_stat == GLP_NOFEAS) - ret = GLP_ENODFS; - else - xassert(lp != lp); - } - goto done; - } -post: /* postprocess solution from the transformed LP */ - npp_postprocess(npp, lp); - /* the transformed LP is no longer needed */ - glp_delete_prob(lp), lp = NULL; - /* store solution to the original problem */ - npp_unload_sol(npp, P); - /* the original LP has been successfully solved */ - ret = 0; -done: /* delete the transformed LP, if it exists */ - if (lp != NULL) glp_delete_prob(lp); - /* delete preprocessor workspace */ - npp_delete_wksp(npp); - return ret; -} - -int glp_simplex(glp_prob *P, const glp_smcp *parm) -{ /* solve LP problem with the simplex method */ - glp_smcp _parm; - int i, j, ret; - /* check problem object */ - if (P == NULL || P->magic != GLP_PROB_MAGIC) - xerror("glp_simplex: P = %p; invalid problem object\n", P); - if (P->tree != NULL && P->tree->reason != 0) - xerror("glp_simplex: operation not allowed\n"); - /* check control parameters */ - if (parm == NULL) - parm = &_parm, glp_init_smcp((glp_smcp *)parm); - if (!(parm->msg_lev == GLP_MSG_OFF || - parm->msg_lev == GLP_MSG_ERR || - parm->msg_lev == GLP_MSG_ON || - parm->msg_lev == GLP_MSG_ALL || - parm->msg_lev == GLP_MSG_DBG)) - xerror("glp_simplex: msg_lev = %d; invalid parameter\n", - parm->msg_lev); - if (!(parm->meth == GLP_PRIMAL || - parm->meth == GLP_DUALP || - parm->meth == GLP_DUAL)) - xerror("glp_simplex: meth = %d; invalid parameter\n", - parm->meth); - if (!(parm->pricing == GLP_PT_STD || - parm->pricing == GLP_PT_PSE)) - xerror("glp_simplex: pricing = %d; invalid parameter\n", - parm->pricing); - if (!(parm->r_test == GLP_RT_STD || - parm->r_test == GLP_RT_HAR)) - xerror("glp_simplex: r_test = %d; invalid parameter\n", - parm->r_test); - if (!(0.0 < parm->tol_bnd && parm->tol_bnd < 1.0)) - xerror("glp_simplex: tol_bnd = %g; invalid parameter\n", - parm->tol_bnd); - if (!(0.0 < parm->tol_dj && parm->tol_dj < 1.0)) - xerror("glp_simplex: tol_dj = %g; invalid parameter\n", - parm->tol_dj); - if (!(0.0 < parm->tol_piv && parm->tol_piv < 1.0)) - xerror("glp_simplex: tol_piv = %g; invalid parameter\n", - parm->tol_piv); - if (parm->it_lim < 0) - xerror("glp_simplex: it_lim = %d; invalid parameter\n", - parm->it_lim); - if (parm->tm_lim < 0) - xerror("glp_simplex: tm_lim = %d; invalid parameter\n", - parm->tm_lim); - if (parm->out_frq < 1) - xerror("glp_simplex: out_frq = %d; invalid parameter\n", - parm->out_frq); - if (parm->out_dly < 0) - xerror("glp_simplex: out_dly = %d; invalid parameter\n", - parm->out_dly); - if (!(parm->presolve == GLP_ON || parm->presolve == GLP_OFF)) - xerror("glp_simplex: presolve = %d; invalid parameter\n", - parm->presolve); - /* basic solution is currently undefined */ - P->pbs_stat = P->dbs_stat = GLP_UNDEF; - P->obj_val = 0.0; - P->some = 0; - /* check bounds of double-bounded variables */ - for (i = 1; i <= P->m; i++) - { GLPROW *row = P->row[i]; - if (row->type == GLP_DB && row->lb >= row->ub) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_simplex: row %d: lb = %g, ub = %g; incorrec" - "t bounds\n", i, row->lb, row->ub); - ret = GLP_EBOUND; - goto done; - } - } - for (j = 1; j <= P->n; j++) - { GLPCOL *col = P->col[j]; - if (col->type == GLP_DB && col->lb >= col->ub) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_simplex: column %d: lb = %g, ub = %g; incor" - "rect bounds\n", j, col->lb, col->ub); - ret = GLP_EBOUND; - goto done; - } - } - /* solve LP problem */ - if (parm->msg_lev >= GLP_MSG_ALL) - { xprintf("GLPK Simplex Optimizer, v%s\n", glp_version()); - xprintf("%d row%s, %d column%s, %d non-zero%s\n", - P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s", - P->nnz, P->nnz == 1 ? "" : "s"); - } - if (P->nnz == 0) - trivial_lp(P, parm), ret = 0; - else if (!parm->presolve) - ret = solve_lp(P, parm); - else - ret = preprocess_and_solve_lp(P, parm); -done: /* return to the application program */ - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_init_smcp - initialize simplex method control parameters -* -* SYNOPSIS -* -* void glp_init_smcp(glp_smcp *parm); -* -* DESCRIPTION -* -* The routine glp_init_smcp initializes control parameters, which are -* used by the simplex solver, with default values. -* -* Default values of the control parameters are stored in a glp_smcp -* structure, which the parameter parm points to. */ - -void glp_init_smcp(glp_smcp *parm) -{ parm->msg_lev = GLP_MSG_ALL; - parm->meth = GLP_PRIMAL; - parm->pricing = GLP_PT_PSE; - parm->r_test = GLP_RT_HAR; - parm->tol_bnd = 1e-7; - parm->tol_dj = 1e-7; - parm->tol_piv = 1e-10; - parm->obj_ll = -DBL_MAX; - parm->obj_ul = +DBL_MAX; - parm->it_lim = INT_MAX; - parm->tm_lim = INT_MAX; - parm->out_frq = 500; - parm->out_dly = 0; - parm->presolve = GLP_OFF; - return; -} - -/*********************************************************************** -* NAME -* -* glp_get_status - retrieve generic status of basic solution -* -* SYNOPSIS -* -* int glp_get_status(glp_prob *lp); -* -* RETURNS -* -* The routine glp_get_status reports the generic status of the basic -* solution for the specified problem object as follows: -* -* GLP_OPT - solution is optimal; -* GLP_FEAS - solution is feasible; -* GLP_INFEAS - solution is infeasible; -* GLP_NOFEAS - problem has no feasible solution; -* GLP_UNBND - problem has unbounded solution; -* GLP_UNDEF - solution is undefined. */ - -int glp_get_status(glp_prob *lp) -{ int status; - status = glp_get_prim_stat(lp); - switch (status) - { case GLP_FEAS: - switch (glp_get_dual_stat(lp)) - { case GLP_FEAS: - status = GLP_OPT; - break; - case GLP_NOFEAS: - status = GLP_UNBND; - break; - case GLP_UNDEF: - case GLP_INFEAS: - status = status; - break; - default: - xassert(lp != lp); - } - break; - case GLP_UNDEF: - case GLP_INFEAS: - case GLP_NOFEAS: - status = status; - break; - default: - xassert(lp != lp); - } - return status; -} - -/*********************************************************************** -* NAME -* -* glp_get_prim_stat - retrieve status of primal basic solution -* -* SYNOPSIS -* -* int glp_get_prim_stat(glp_prob *lp); -* -* RETURNS -* -* The routine glp_get_prim_stat reports the status of the primal basic -* solution for the specified problem object as follows: -* -* GLP_UNDEF - primal solution is undefined; -* GLP_FEAS - primal solution is feasible; -* GLP_INFEAS - primal solution is infeasible; -* GLP_NOFEAS - no primal feasible solution exists. */ - -int glp_get_prim_stat(glp_prob *lp) -{ int pbs_stat = lp->pbs_stat; - return pbs_stat; -} - -/*********************************************************************** -* NAME -* -* glp_get_dual_stat - retrieve status of dual basic solution -* -* SYNOPSIS -* -* int glp_get_dual_stat(glp_prob *lp); -* -* RETURNS -* -* The routine glp_get_dual_stat reports the status of the dual basic -* solution for the specified problem object as follows: -* -* GLP_UNDEF - dual solution is undefined; -* GLP_FEAS - dual solution is feasible; -* GLP_INFEAS - dual solution is infeasible; -* GLP_NOFEAS - no dual feasible solution exists. */ - -int glp_get_dual_stat(glp_prob *lp) -{ int dbs_stat = lp->dbs_stat; - return dbs_stat; -} - -/*********************************************************************** -* NAME -* -* glp_get_obj_val - retrieve objective value (basic solution) -* -* SYNOPSIS -* -* double glp_get_obj_val(glp_prob *lp); -* -* RETURNS -* -* The routine glp_get_obj_val returns value of the objective function -* for basic solution. */ - -double glp_get_obj_val(glp_prob *lp) -{ /*struct LPXCPS *cps = lp->cps;*/ - double z; - z = lp->obj_val; - /*if (cps->round && fabs(z) < 1e-9) z = 0.0;*/ - return z; -} - -/*********************************************************************** -* NAME -* -* glp_get_row_stat - retrieve row status -* -* SYNOPSIS -* -* int glp_get_row_stat(glp_prob *lp, int i); -* -* RETURNS -* -* The routine glp_get_row_stat returns current status assigned to the -* auxiliary variable associated with i-th row as follows: -* -* GLP_BS - basic variable; -* GLP_NL - non-basic variable on its lower bound; -* GLP_NU - non-basic variable on its upper bound; -* GLP_NF - non-basic free (unbounded) variable; -* GLP_NS - non-basic fixed variable. */ - -int glp_get_row_stat(glp_prob *lp, int i) -{ if (!(1 <= i && i <= lp->m)) - xerror("glp_get_row_stat: i = %d; row number out of range\n", - i); - return lp->row[i]->stat; -} - -/*********************************************************************** -* NAME -* -* glp_get_row_prim - retrieve row primal value (basic solution) -* -* SYNOPSIS -* -* double glp_get_row_prim(glp_prob *lp, int i); -* -* RETURNS -* -* The routine glp_get_row_prim returns primal value of the auxiliary -* variable associated with i-th row. */ - -double glp_get_row_prim(glp_prob *lp, int i) -{ /*struct LPXCPS *cps = lp->cps;*/ - double prim; - if (!(1 <= i && i <= lp->m)) - xerror("glp_get_row_prim: i = %d; row number out of range\n", - i); - prim = lp->row[i]->prim; - /*if (cps->round && fabs(prim) < 1e-9) prim = 0.0;*/ - return prim; -} - -/*********************************************************************** -* NAME -* -* glp_get_row_dual - retrieve row dual value (basic solution) -* -* SYNOPSIS -* -* double glp_get_row_dual(glp_prob *lp, int i); -* -* RETURNS -* -* The routine glp_get_row_dual returns dual value (i.e. reduced cost) -* of the auxiliary variable associated with i-th row. */ - -double glp_get_row_dual(glp_prob *lp, int i) -{ /*struct LPXCPS *cps = lp->cps;*/ - double dual; - if (!(1 <= i && i <= lp->m)) - xerror("glp_get_row_dual: i = %d; row number out of range\n", - i); - dual = lp->row[i]->dual; - /*if (cps->round && fabs(dual) < 1e-9) dual = 0.0;*/ - return dual; -} - -/*********************************************************************** -* NAME -* -* glp_get_col_stat - retrieve column status -* -* SYNOPSIS -* -* int glp_get_col_stat(glp_prob *lp, int j); -* -* RETURNS -* -* The routine glp_get_col_stat returns current status assigned to the -* structural variable associated with j-th column as follows: -* -* GLP_BS - basic variable; -* GLP_NL - non-basic variable on its lower bound; -* GLP_NU - non-basic variable on its upper bound; -* GLP_NF - non-basic free (unbounded) variable; -* GLP_NS - non-basic fixed variable. */ - -int glp_get_col_stat(glp_prob *lp, int j) -{ if (!(1 <= j && j <= lp->n)) - xerror("glp_get_col_stat: j = %d; column number out of range\n" - , j); - return lp->col[j]->stat; -} - -/*********************************************************************** -* NAME -* -* glp_get_col_prim - retrieve column primal value (basic solution) -* -* SYNOPSIS -* -* double glp_get_col_prim(glp_prob *lp, int j); -* -* RETURNS -* -* The routine glp_get_col_prim returns primal value of the structural -* variable associated with j-th column. */ - -double glp_get_col_prim(glp_prob *lp, int j) -{ /*struct LPXCPS *cps = lp->cps;*/ - double prim; - if (!(1 <= j && j <= lp->n)) - xerror("glp_get_col_prim: j = %d; column number out of range\n" - , j); - prim = lp->col[j]->prim; - /*if (cps->round && fabs(prim) < 1e-9) prim = 0.0;*/ - return prim; -} - -/*********************************************************************** -* NAME -* -* glp_get_col_dual - retrieve column dual value (basic solution) -* -* SYNOPSIS -* -* double glp_get_col_dual(glp_prob *lp, int j); -* -* RETURNS -* -* The routine glp_get_col_dual returns dual value (i.e. reduced cost) -* of the structural variable associated with j-th column. */ - -double glp_get_col_dual(glp_prob *lp, int j) -{ /*struct LPXCPS *cps = lp->cps;*/ - double dual; - if (!(1 <= j && j <= lp->n)) - xerror("glp_get_col_dual: j = %d; column number out of range\n" - , j); - dual = lp->col[j]->dual; - /*if (cps->round && fabs(dual) < 1e-9) dual = 0.0;*/ - return dual; -} - -/*********************************************************************** -* NAME -* -* glp_get_unbnd_ray - determine variable causing unboundedness -* -* SYNOPSIS -* -* int glp_get_unbnd_ray(glp_prob *lp); -* -* RETURNS -* -* The routine glp_get_unbnd_ray returns the number k of a variable, -* which causes primal or dual unboundedness. If 1 <= k <= m, it is -* k-th auxiliary variable, and if m+1 <= k <= m+n, it is (k-m)-th -* structural variable, where m is the number of rows, n is the number -* of columns in the problem object. If such variable is not defined, -* the routine returns 0. -* -* COMMENTS -* -* If it is not exactly known which version of the simplex solver -* detected unboundedness, i.e. whether the unboundedness is primal or -* dual, it is sufficient to check the status of the variable reported -* with the routine glp_get_row_stat or glp_get_col_stat. If the -* variable is non-basic, the unboundedness is primal, otherwise, if -* the variable is basic, the unboundedness is dual (the latter case -* means that the problem has no primal feasible dolution). */ - -int glp_get_unbnd_ray(glp_prob *lp) -{ int k; - k = lp->some; - xassert(k >= 0); - if (k > lp->m + lp->n) k = 0; - return k; -} - -#if 1 /* 08/VIII-2013 */ -int glp_get_it_cnt(glp_prob *P) -{ /* get simplex solver iteration count */ - return P->it_cnt; -} -#endif - -#if 1 /* 08/VIII-2013 */ -int glp_set_it_cnt(glp_prob *P, int it_cnt) -{ /* set simplex solver iteration count */ - P->it_cnt = it_cnt; - return; -} -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi07.c b/resources/3rdparty/glpk-4.53/src/glpapi07.c deleted file mode 100644 index 5258a4dec..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi07.c +++ /dev/null @@ -1,456 +0,0 @@ -/* glpapi07.c (exact simplex solver) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "draft.h" -#include "glpssx.h" -#include "misc.h" -#include "prob.h" - -/*********************************************************************** -* NAME -* -* glp_exact - solve LP problem in exact arithmetic -* -* SYNOPSIS -* -* int glp_exact(glp_prob *lp, const glp_smcp *parm); -* -* DESCRIPTION -* -* The routine glp_exact is a tentative implementation of the primal -* two-phase simplex method based on exact (rational) arithmetic. It is -* similar to the routine glp_simplex, however, for all internal -* computations it uses arithmetic of rational numbers, which is exact -* in mathematical sense, i.e. free of round-off errors unlike floating -* point arithmetic. -* -* Note that the routine glp_exact uses inly two control parameters -* passed in the structure glp_smcp, namely, it_lim and tm_lim. -* -* RETURNS -* -* 0 The LP problem instance has been successfully solved. This code -* does not necessarily mean that the solver has found optimal -* solution. It only means that the solution process was successful. -* -* GLP_EBADB -* Unable to start the search, because the initial basis specified -* in the problem object is invalid--the number of basic (auxiliary -* and structural) variables is not the same as the number of rows in -* the problem object. -* -* GLP_ESING -* Unable to start the search, because the basis matrix correspodning -* to the initial basis is exactly singular. -* -* GLP_EBOUND -* Unable to start the search, because some double-bounded variables -* have incorrect bounds. -* -* GLP_EFAIL -* The problem has no rows/columns. -* -* GLP_EITLIM -* The search was prematurely terminated, because the simplex -* iteration limit has been exceeded. -* -* GLP_ETMLIM -* The search was prematurely terminated, because the time limit has -* been exceeded. */ - -static void set_d_eps(mpq_t x, double val) -{ /* convert double val to rational x obtaining a more adequate - fraction than provided by mpq_set_d due to allowing a small - approximation error specified by a given relative tolerance; - for example, mpq_set_d would give the following - 1/3 ~= 0.333333333333333314829616256247391... -> - -> 6004799503160661/18014398509481984 - while this routine gives exactly 1/3 */ - int s, n, j; - double f, p, q, eps = 1e-9; - mpq_t temp; - xassert(-DBL_MAX <= val && val <= +DBL_MAX); -#if 1 /* 30/VII-2008 */ - if (val == floor(val)) - { /* if val is integral, do not approximate */ - mpq_set_d(x, val); - goto done; - } -#endif - if (val > 0.0) - s = +1; - else if (val < 0.0) - s = -1; - else - { mpq_set_si(x, 0, 1); - goto done; - } - f = frexp(fabs(val), &n); - /* |val| = f * 2^n, where 0.5 <= f < 1.0 */ - fp2rat(f, 0.1 * eps, &p, &q); - /* f ~= p / q, where p and q are integers */ - mpq_init(temp); - mpq_set_d(x, p); - mpq_set_d(temp, q); - mpq_div(x, x, temp); - mpq_set_si(temp, 1, 1); - for (j = 1; j <= abs(n); j++) - mpq_add(temp, temp, temp); - if (n > 0) - mpq_mul(x, x, temp); - else if (n < 0) - mpq_div(x, x, temp); - mpq_clear(temp); - if (s < 0) mpq_neg(x, x); - /* check that the desired tolerance has been attained */ - xassert(fabs(val - mpq_get_d(x)) <= eps * (1.0 + fabs(val))); -done: return; -} - -static void load_data(SSX *ssx, glp_prob *lp) -{ /* load LP problem data into simplex solver workspace */ - int m = ssx->m; - int n = ssx->n; - int nnz = ssx->A_ptr[n+1]-1; - int j, k, type, loc, len, *ind; - double lb, ub, coef, *val; - xassert(lp->m == m); - xassert(lp->n == n); - xassert(lp->nnz == nnz); - /* types and bounds of rows and columns */ - for (k = 1; k <= m+n; k++) - { if (k <= m) - { type = lp->row[k]->type; - lb = lp->row[k]->lb; - ub = lp->row[k]->ub; - } - else - { type = lp->col[k-m]->type; - lb = lp->col[k-m]->lb; - ub = lp->col[k-m]->ub; - } - switch (type) - { case GLP_FR: type = SSX_FR; break; - case GLP_LO: type = SSX_LO; break; - case GLP_UP: type = SSX_UP; break; - case GLP_DB: type = SSX_DB; break; - case GLP_FX: type = SSX_FX; break; - default: xassert(type != type); - } - ssx->type[k] = type; - set_d_eps(ssx->lb[k], lb); - set_d_eps(ssx->ub[k], ub); - } - /* optimization direction */ - switch (lp->dir) - { case GLP_MIN: ssx->dir = SSX_MIN; break; - case GLP_MAX: ssx->dir = SSX_MAX; break; - default: xassert(lp != lp); - } - /* objective coefficients */ - for (k = 0; k <= m+n; k++) - { if (k == 0) - coef = lp->c0; - else if (k <= m) - coef = 0.0; - else - coef = lp->col[k-m]->coef; - set_d_eps(ssx->coef[k], coef); - } - /* constraint coefficients */ - ind = xcalloc(1+m, sizeof(int)); - val = xcalloc(1+m, sizeof(double)); - loc = 0; - for (j = 1; j <= n; j++) - { ssx->A_ptr[j] = loc+1; - len = glp_get_mat_col(lp, j, ind, val); - for (k = 1; k <= len; k++) - { loc++; - ssx->A_ind[loc] = ind[k]; - set_d_eps(ssx->A_val[loc], val[k]); - } - } - xassert(loc == nnz); - xfree(ind); - xfree(val); - return; -} - -static int load_basis(SSX *ssx, glp_prob *lp) -{ /* load current LP basis into simplex solver workspace */ - int m = ssx->m; - int n = ssx->n; - int *type = ssx->type; - int *stat = ssx->stat; - int *Q_row = ssx->Q_row; - int *Q_col = ssx->Q_col; - int i, j, k; - xassert(lp->m == m); - xassert(lp->n == n); - /* statuses of rows and columns */ - for (k = 1; k <= m+n; k++) - { if (k <= m) - stat[k] = lp->row[k]->stat; - else - stat[k] = lp->col[k-m]->stat; - switch (stat[k]) - { case GLP_BS: - stat[k] = SSX_BS; - break; - case GLP_NL: - stat[k] = SSX_NL; - xassert(type[k] == SSX_LO || type[k] == SSX_DB); - break; - case GLP_NU: - stat[k] = SSX_NU; - xassert(type[k] == SSX_UP || type[k] == SSX_DB); - break; - case GLP_NF: - stat[k] = SSX_NF; - xassert(type[k] == SSX_FR); - break; - case GLP_NS: - stat[k] = SSX_NS; - xassert(type[k] == SSX_FX); - break; - default: - xassert(stat != stat); - } - } - /* build permutation matix Q */ - i = j = 0; - for (k = 1; k <= m+n; k++) - { if (stat[k] == SSX_BS) - { i++; - if (i > m) return 1; - Q_row[k] = i, Q_col[i] = k; - } - else - { j++; - if (j > n) return 1; - Q_row[k] = m+j, Q_col[m+j] = k; - } - } - xassert(i == m && j == n); - return 0; -} - -int glp_exact(glp_prob *lp, const glp_smcp *parm) -{ glp_smcp _parm; - SSX *ssx; - int m = lp->m; - int n = lp->n; - int nnz = lp->nnz; - int i, j, k, type, pst, dst, ret, stat; - double lb, ub, prim, dual, sum; - if (parm == NULL) - parm = &_parm, glp_init_smcp((glp_smcp *)parm); - /* check control parameters */ - if (parm->it_lim < 0) - xerror("glp_exact: it_lim = %d; invalid parameter\n", - parm->it_lim); - if (parm->tm_lim < 0) - xerror("glp_exact: tm_lim = %d; invalid parameter\n", - parm->tm_lim); - /* the problem must have at least one row and one column */ - if (!(m > 0 && n > 0)) - { xprintf("glp_exact: problem has no rows/columns\n"); - return GLP_EFAIL; - } -#if 1 - /* basic solution is currently undefined */ - lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; - lp->obj_val = 0.0; - lp->some = 0; -#endif - /* check that all double-bounded variables have correct bounds */ - for (k = 1; k <= m+n; k++) - { if (k <= m) - { type = lp->row[k]->type; - lb = lp->row[k]->lb; - ub = lp->row[k]->ub; - } - else - { type = lp->col[k-m]->type; - lb = lp->col[k-m]->lb; - ub = lp->col[k-m]->ub; - } - if (type == GLP_DB && lb >= ub) - { xprintf("glp_exact: %s %d has invalid bounds\n", - k <= m ? "row" : "column", k <= m ? k : k-m); - return GLP_EBOUND; - } - } - /* create the simplex solver workspace */ - xprintf("glp_exact: %d rows, %d columns, %d non-zeros\n", - m, n, nnz); -#ifdef HAVE_GMP - xprintf("GNU MP bignum library is being used\n"); -#else - xprintf("GLPK bignum module is being used\n"); - xprintf("(Consider installing GNU MP to attain a much better perf" - "ormance.)\n"); -#endif - ssx = ssx_create(m, n, nnz); - /* load LP problem data into the workspace */ - load_data(ssx, lp); - /* load current LP basis into the workspace */ - if (load_basis(ssx, lp)) - { xprintf("glp_exact: initial LP basis is invalid\n"); - ret = GLP_EBADB; - goto done; - } - /* inherit some control parameters from the LP object */ -#if 0 - ssx->it_lim = lpx_get_int_parm(lp, LPX_K_ITLIM); - ssx->it_cnt = lpx_get_int_parm(lp, LPX_K_ITCNT); - ssx->tm_lim = lpx_get_real_parm(lp, LPX_K_TMLIM); -#else - ssx->it_lim = parm->it_lim; - ssx->it_cnt = lp->it_cnt; - ssx->tm_lim = (double)parm->tm_lim / 1000.0; -#endif - ssx->out_frq = 5.0; - ssx->tm_beg = xtime(); -#if 0 /* 10/VI-2013 */ - ssx->tm_lag = xlset(0); -#else - ssx->tm_lag = 0.0; -#endif - /* solve LP */ - ret = ssx_driver(ssx); - /* copy back some statistics to the LP object */ -#if 0 - lpx_set_int_parm(lp, LPX_K_ITLIM, ssx->it_lim); - lpx_set_int_parm(lp, LPX_K_ITCNT, ssx->it_cnt); - lpx_set_real_parm(lp, LPX_K_TMLIM, ssx->tm_lim); -#else - lp->it_cnt = ssx->it_cnt; -#endif - /* analyze the return code */ - switch (ret) - { case 0: - /* optimal solution found */ - ret = 0; - pst = dst = GLP_FEAS; - break; - case 1: - /* problem has no feasible solution */ - ret = 0; - pst = GLP_NOFEAS, dst = GLP_INFEAS; - break; - case 2: - /* problem has unbounded solution */ - ret = 0; - pst = GLP_FEAS, dst = GLP_NOFEAS; -#if 1 - xassert(1 <= ssx->q && ssx->q <= n); - lp->some = ssx->Q_col[m + ssx->q]; - xassert(1 <= lp->some && lp->some <= m+n); -#endif - break; - case 3: - /* iteration limit exceeded (phase I) */ - ret = GLP_EITLIM; - pst = dst = GLP_INFEAS; - break; - case 4: - /* iteration limit exceeded (phase II) */ - ret = GLP_EITLIM; - pst = GLP_FEAS, dst = GLP_INFEAS; - break; - case 5: - /* time limit exceeded (phase I) */ - ret = GLP_ETMLIM; - pst = dst = GLP_INFEAS; - break; - case 6: - /* time limit exceeded (phase II) */ - ret = GLP_ETMLIM; - pst = GLP_FEAS, dst = GLP_INFEAS; - break; - case 7: - /* initial basis matrix is singular */ - ret = GLP_ESING; - goto done; - default: - xassert(ret != ret); - } - /* store final basic solution components into LP object */ - lp->pbs_stat = pst; - lp->dbs_stat = dst; - sum = lp->c0; - for (k = 1; k <= m+n; k++) - { if (ssx->stat[k] == SSX_BS) - { i = ssx->Q_row[k]; /* x[k] = xB[i] */ - xassert(1 <= i && i <= m); - stat = GLP_BS; - prim = mpq_get_d(ssx->bbar[i]); - dual = 0.0; - } - else - { j = ssx->Q_row[k] - m; /* x[k] = xN[j] */ - xassert(1 <= j && j <= n); - switch (ssx->stat[k]) - { case SSX_NF: - stat = GLP_NF; - prim = 0.0; - break; - case SSX_NL: - stat = GLP_NL; - prim = mpq_get_d(ssx->lb[k]); - break; - case SSX_NU: - stat = GLP_NU; - prim = mpq_get_d(ssx->ub[k]); - break; - case SSX_NS: - stat = GLP_NS; - prim = mpq_get_d(ssx->lb[k]); - break; - default: - xassert(ssx != ssx); - } - dual = mpq_get_d(ssx->cbar[j]); - } - if (k <= m) - { glp_set_row_stat(lp, k, stat); - lp->row[k]->prim = prim; - lp->row[k]->dual = dual; - } - else - { glp_set_col_stat(lp, k-m, stat); - lp->col[k-m]->prim = prim; - lp->col[k-m]->dual = dual; - sum += lp->col[k-m]->coef * prim; - } - } - lp->obj_val = sum; -done: /* delete the simplex solver workspace */ - ssx_delete(ssx); - /* return to the application program */ - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi08.c b/resources/3rdparty/glpk-4.53/src/glpapi08.c deleted file mode 100644 index e7fc62e8f..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi08.c +++ /dev/null @@ -1,388 +0,0 @@ -/* glpapi08.c (interior-point method routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpipm.h" -#include "glpnpp.h" - -/*********************************************************************** -* NAME -* -* glp_interior - solve LP problem with the interior-point method -* -* SYNOPSIS -* -* int glp_interior(glp_prob *P, const glp_iptcp *parm); -* -* The routine glp_interior is a driver to the LP solver based on the -* interior-point method. -* -* The interior-point solver has a set of control parameters. Values of -* the control parameters can be passed in a structure glp_iptcp, which -* the parameter parm points to. -* -* Currently this routine implements an easy variant of the primal-dual -* interior-point method based on Mehrotra's technique. -* -* This routine transforms the original LP problem to an equivalent LP -* problem in the standard formulation (all constraints are equalities, -* all variables are non-negative), calls the routine ipm_main to solve -* the transformed problem, and then transforms an obtained solution to -* the solution of the original problem. -* -* RETURNS -* -* 0 The LP problem instance has been successfully solved. This code -* does not necessarily mean that the solver has found optimal -* solution. It only means that the solution process was successful. -* -* GLP_EFAIL -* The problem has no rows/columns. -* -* GLP_ENOCVG -* Very slow convergence or divergence. -* -* GLP_EITLIM -* Iteration limit exceeded. -* -* GLP_EINSTAB -* Numerical instability on solving Newtonian system. */ - -static void transform(NPP *npp) -{ /* transform LP to the standard formulation */ - NPPROW *row, *prev_row; - NPPCOL *col, *prev_col; - for (row = npp->r_tail; row != NULL; row = prev_row) - { prev_row = row->prev; - if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) - npp_free_row(npp, row); - else if (row->lb == -DBL_MAX) - npp_leq_row(npp, row); - else if (row->ub == +DBL_MAX) - npp_geq_row(npp, row); - else if (row->lb != row->ub) - { if (fabs(row->lb) < fabs(row->ub)) - npp_geq_row(npp, row); - else - npp_leq_row(npp, row); - } - } - for (col = npp->c_tail; col != NULL; col = prev_col) - { prev_col = col->prev; - if (col->lb == -DBL_MAX && col->ub == +DBL_MAX) - npp_free_col(npp, col); - else if (col->lb == -DBL_MAX) - npp_ubnd_col(npp, col); - else if (col->ub == +DBL_MAX) - { if (col->lb != 0.0) - npp_lbnd_col(npp, col); - } - else if (col->lb != col->ub) - { if (fabs(col->lb) < fabs(col->ub)) - { if (col->lb != 0.0) - npp_lbnd_col(npp, col); - } - else - npp_ubnd_col(npp, col); - npp_dbnd_col(npp, col); - } - else - npp_fixed_col(npp, col); - } - for (row = npp->r_head; row != NULL; row = row->next) - xassert(row->lb == row->ub); - for (col = npp->c_head; col != NULL; col = col->next) - xassert(col->lb == 0.0 && col->ub == +DBL_MAX); - return; -} - -int glp_interior(glp_prob *P, const glp_iptcp *parm) -{ glp_iptcp _parm; - GLPROW *row; - GLPCOL *col; - NPP *npp = NULL; - glp_prob *prob = NULL; - int i, j, ret; - /* check control parameters */ - if (parm == NULL) - glp_init_iptcp(&_parm), parm = &_parm; - if (!(parm->msg_lev == GLP_MSG_OFF || - parm->msg_lev == GLP_MSG_ERR || - parm->msg_lev == GLP_MSG_ON || - parm->msg_lev == GLP_MSG_ALL)) - xerror("glp_interior: msg_lev = %d; invalid parameter\n", - parm->msg_lev); - if (!(parm->ord_alg == GLP_ORD_NONE || - parm->ord_alg == GLP_ORD_QMD || - parm->ord_alg == GLP_ORD_AMD || - parm->ord_alg == GLP_ORD_SYMAMD)) - xerror("glp_interior: ord_alg = %d; invalid parameter\n", - parm->ord_alg); - /* interior-point solution is currently undefined */ - P->ipt_stat = GLP_UNDEF; - P->ipt_obj = 0.0; - /* check bounds of double-bounded variables */ - for (i = 1; i <= P->m; i++) - { row = P->row[i]; - if (row->type == GLP_DB && row->lb >= row->ub) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_interior: row %d: lb = %g, ub = %g; incorre" - "ct bounds\n", i, row->lb, row->ub); - ret = GLP_EBOUND; - goto done; - } - } - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - if (col->type == GLP_DB && col->lb >= col->ub) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_interior: column %d: lb = %g, ub = %g; inco" - "rrect bounds\n", j, col->lb, col->ub); - ret = GLP_EBOUND; - goto done; - } - } - /* transform LP to the standard formulation */ - if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("Original LP has %d row(s), %d column(s), and %d non-z" - "ero(s)\n", P->m, P->n, P->nnz); - npp = npp_create_wksp(); - npp_load_prob(npp, P, GLP_OFF, GLP_IPT, GLP_ON); - transform(npp); - prob = glp_create_prob(); - npp_build_prob(npp, prob); - if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("Working LP has %d row(s), %d column(s), and %d non-ze" - "ro(s)\n", prob->m, prob->n, prob->nnz); -#if 1 - /* currently empty problem cannot be solved */ - if (!(prob->m > 0 && prob->n > 0)) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_interior: unable to solve empty problem\n"); - ret = GLP_EFAIL; - goto done; - } -#endif - /* scale the resultant LP */ - { ENV *env = get_env_ptr(); - int term_out = env->term_out; - env->term_out = GLP_OFF; - glp_scale_prob(prob, GLP_SF_EQ); - env->term_out = term_out; - } - /* warn about dense columns */ - if (parm->msg_lev >= GLP_MSG_ON && prob->m >= 200) - { int len, cnt = 0; - for (j = 1; j <= prob->n; j++) - { len = glp_get_mat_col(prob, j, NULL, NULL); - if ((double)len >= 0.20 * (double)prob->m) cnt++; - } - if (cnt == 1) - xprintf("WARNING: PROBLEM HAS ONE DENSE COLUMN\n"); - else if (cnt > 0) - xprintf("WARNING: PROBLEM HAS %d DENSE COLUMNS\n", cnt); - } - /* solve the transformed LP */ - ret = ipm_solve(prob, parm); - /* postprocess solution from the transformed LP */ - npp_postprocess(npp, prob); - /* and store solution to the original LP */ - npp_unload_sol(npp, P); -done: /* free working program objects */ - if (npp != NULL) npp_delete_wksp(npp); - if (prob != NULL) glp_delete_prob(prob); - /* return to the application program */ - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_init_iptcp - initialize interior-point solver control parameters -* -* SYNOPSIS -* -* void glp_init_iptcp(glp_iptcp *parm); -* -* DESCRIPTION -* -* The routine glp_init_iptcp initializes control parameters, which are -* used by the interior-point solver, with default values. -* -* Default values of the control parameters are stored in the glp_iptcp -* structure, which the parameter parm points to. */ - -void glp_init_iptcp(glp_iptcp *parm) -{ parm->msg_lev = GLP_MSG_ALL; - parm->ord_alg = GLP_ORD_AMD; - return; -} - -/*********************************************************************** -* NAME -* -* glp_ipt_status - retrieve status of interior-point solution -* -* SYNOPSIS -* -* int glp_ipt_status(glp_prob *lp); -* -* RETURNS -* -* The routine glp_ipt_status reports the status of solution found by -* the interior-point solver as follows: -* -* GLP_UNDEF - interior-point solution is undefined; -* GLP_OPT - interior-point solution is optimal; -* GLP_INFEAS - interior-point solution is infeasible; -* GLP_NOFEAS - no feasible solution exists. */ - -int glp_ipt_status(glp_prob *lp) -{ int ipt_stat = lp->ipt_stat; - return ipt_stat; -} - -/*********************************************************************** -* NAME -* -* glp_ipt_obj_val - retrieve objective value (interior point) -* -* SYNOPSIS -* -* double glp_ipt_obj_val(glp_prob *lp); -* -* RETURNS -* -* The routine glp_ipt_obj_val returns value of the objective function -* for interior-point solution. */ - -double glp_ipt_obj_val(glp_prob *lp) -{ /*struct LPXCPS *cps = lp->cps;*/ - double z; - z = lp->ipt_obj; - /*if (cps->round && fabs(z) < 1e-9) z = 0.0;*/ - return z; -} - -/*********************************************************************** -* NAME -* -* glp_ipt_row_prim - retrieve row primal value (interior point) -* -* SYNOPSIS -* -* double glp_ipt_row_prim(glp_prob *lp, int i); -* -* RETURNS -* -* The routine glp_ipt_row_prim returns primal value of the auxiliary -* variable associated with i-th row. */ - -double glp_ipt_row_prim(glp_prob *lp, int i) -{ /*struct LPXCPS *cps = lp->cps;*/ - double pval; - if (!(1 <= i && i <= lp->m)) - xerror("glp_ipt_row_prim: i = %d; row number out of range\n", - i); - pval = lp->row[i]->pval; - /*if (cps->round && fabs(pval) < 1e-9) pval = 0.0;*/ - return pval; -} - -/*********************************************************************** -* NAME -* -* glp_ipt_row_dual - retrieve row dual value (interior point) -* -* SYNOPSIS -* -* double glp_ipt_row_dual(glp_prob *lp, int i); -* -* RETURNS -* -* The routine glp_ipt_row_dual returns dual value (i.e. reduced cost) -* of the auxiliary variable associated with i-th row. */ - -double glp_ipt_row_dual(glp_prob *lp, int i) -{ /*struct LPXCPS *cps = lp->cps;*/ - double dval; - if (!(1 <= i && i <= lp->m)) - xerror("glp_ipt_row_dual: i = %d; row number out of range\n", - i); - dval = lp->row[i]->dval; - /*if (cps->round && fabs(dval) < 1e-9) dval = 0.0;*/ - return dval; -} - -/*********************************************************************** -* NAME -* -* glp_ipt_col_prim - retrieve column primal value (interior point) -* -* SYNOPSIS -* -* double glp_ipt_col_prim(glp_prob *lp, int j); -* -* RETURNS -* -* The routine glp_ipt_col_prim returns primal value of the structural -* variable associated with j-th column. */ - -double glp_ipt_col_prim(glp_prob *lp, int j) -{ /*struct LPXCPS *cps = lp->cps;*/ - double pval; - if (!(1 <= j && j <= lp->n)) - xerror("glp_ipt_col_prim: j = %d; column number out of range\n" - , j); - pval = lp->col[j]->pval; - /*if (cps->round && fabs(pval) < 1e-9) pval = 0.0;*/ - return pval; -} - -/*********************************************************************** -* NAME -* -* glp_ipt_col_dual - retrieve column dual value (interior point) -* -* SYNOPSIS -* -* double glp_ipt_col_dual(glp_prob *lp, int j); -* -* RETURNS -* -* The routine glp_ipt_col_dual returns dual value (i.e. reduced cost) -* of the structural variable associated with j-th column. */ - -double glp_ipt_col_dual(glp_prob *lp, int j) -{ /*struct LPXCPS *cps = lp->cps;*/ - double dval; - if (!(1 <= j && j <= lp->n)) - xerror("glp_ipt_col_dual: j = %d; column number out of range\n" - , j); - dval = lp->col[j]->dval; - /*if (cps->round && fabs(dval) < 1e-9) dval = 0.0;*/ - return dval; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi09.c b/resources/3rdparty/glpk-4.53/src/glpapi09.c deleted file mode 100644 index a24f3fdb6..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi09.c +++ /dev/null @@ -1,786 +0,0 @@ -/* glpapi09.c (mixed integer programming routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "draft.h" -#include "env.h" -#include "glpios.h" -#include "glpnpp.h" - -/*********************************************************************** -* NAME -* -* glp_set_col_kind - set (change) column kind -* -* SYNOPSIS -* -* void glp_set_col_kind(glp_prob *mip, int j, int kind); -* -* DESCRIPTION -* -* The routine glp_set_col_kind sets (changes) the kind of j-th column -* (structural variable) as specified by the parameter kind: -* -* GLP_CV - continuous variable; -* GLP_IV - integer variable; -* GLP_BV - binary variable. */ - -void glp_set_col_kind(glp_prob *mip, int j, int kind) -{ GLPCOL *col; - if (!(1 <= j && j <= mip->n)) - xerror("glp_set_col_kind: j = %d; column number out of range\n" - , j); - col = mip->col[j]; - switch (kind) - { case GLP_CV: - col->kind = GLP_CV; - break; - case GLP_IV: - col->kind = GLP_IV; - break; - case GLP_BV: - col->kind = GLP_IV; - if (!(col->type == GLP_DB && col->lb == 0.0 && col->ub == - 1.0)) glp_set_col_bnds(mip, j, GLP_DB, 0.0, 1.0); - break; - default: - xerror("glp_set_col_kind: j = %d; kind = %d; invalid column" - " kind\n", j, kind); - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_get_col_kind - retrieve column kind -* -* SYNOPSIS -* -* int glp_get_col_kind(glp_prob *mip, int j); -* -* RETURNS -* -* The routine glp_get_col_kind returns the kind of j-th column, i.e. -* the kind of corresponding structural variable, as follows: -* -* GLP_CV - continuous variable; -* GLP_IV - integer variable; -* GLP_BV - binary variable */ - -int glp_get_col_kind(glp_prob *mip, int j) -{ GLPCOL *col; - int kind; - if (!(1 <= j && j <= mip->n)) - xerror("glp_get_col_kind: j = %d; column number out of range\n" - , j); - col = mip->col[j]; - kind = col->kind; - switch (kind) - { case GLP_CV: - break; - case GLP_IV: - if (col->type == GLP_DB && col->lb == 0.0 && col->ub == 1.0) - kind = GLP_BV; - break; - default: - xassert(kind != kind); - } - return kind; -} - -/*********************************************************************** -* NAME -* -* glp_get_num_int - retrieve number of integer columns -* -* SYNOPSIS -* -* int glp_get_num_int(glp_prob *mip); -* -* RETURNS -* -* The routine glp_get_num_int returns the current number of columns, -* which are marked as integer. */ - -int glp_get_num_int(glp_prob *mip) -{ GLPCOL *col; - int j, count = 0; - for (j = 1; j <= mip->n; j++) - { col = mip->col[j]; - if (col->kind == GLP_IV) count++; - } - return count; -} - -/*********************************************************************** -* NAME -* -* glp_get_num_bin - retrieve number of binary columns -* -* SYNOPSIS -* -* int glp_get_num_bin(glp_prob *mip); -* -* RETURNS -* -* The routine glp_get_num_bin returns the current number of columns, -* which are marked as binary. */ - -int glp_get_num_bin(glp_prob *mip) -{ GLPCOL *col; - int j, count = 0; - for (j = 1; j <= mip->n; j++) - { col = mip->col[j]; - if (col->kind == GLP_IV && col->type == GLP_DB && col->lb == - 0.0 && col->ub == 1.0) count++; - } - return count; -} - -/*********************************************************************** -* NAME -* -* glp_intopt - solve MIP problem with the branch-and-bound method -* -* SYNOPSIS -* -* int glp_intopt(glp_prob *P, const glp_iocp *parm); -* -* DESCRIPTION -* -* The routine glp_intopt is a driver to the MIP solver based on the -* branch-and-bound method. -* -* On entry the problem object should contain optimal solution to LP -* relaxation (which can be obtained with the routine glp_simplex). -* -* The MIP solver has a set of control parameters. Values of the control -* parameters can be passed in a structure glp_iocp, which the parameter -* parm points to. -* -* The parameter parm can be specified as NULL, in which case the MIP -* solver uses default settings. -* -* RETURNS -* -* 0 The MIP problem instance has been successfully solved. This code -* does not necessarily mean that the solver has found optimal -* solution. It only means that the solution process was successful. -* -* GLP_EBOUND -* Unable to start the search, because some double-bounded variables -* have incorrect bounds or some integer variables have non-integer -* (fractional) bounds. -* -* GLP_EROOT -* Unable to start the search, because optimal basis for initial LP -* relaxation is not provided. -* -* GLP_EFAIL -* The search was prematurely terminated due to the solver failure. -* -* GLP_EMIPGAP -* The search was prematurely terminated, because the relative mip -* gap tolerance has been reached. -* -* GLP_ETMLIM -* The search was prematurely terminated, because the time limit has -* been exceeded. -* -* GLP_ENOPFS -* The MIP problem instance has no primal feasible solution (only if -* the MIP presolver is used). -* -* GLP_ENODFS -* LP relaxation of the MIP problem instance has no dual feasible -* solution (only if the MIP presolver is used). -* -* GLP_ESTOP -* The search was prematurely terminated by application. */ - -#if 0 /* 11/VII-2013 */ -static int solve_mip(glp_prob *P, const glp_iocp *parm) -#else -static int solve_mip(glp_prob *P, const glp_iocp *parm, - glp_prob *P0 /* problem passed to glp_intopt */, - NPP *npp /* preprocessor workspace or NULL */) -#endif -{ /* solve MIP directly without using the preprocessor */ - glp_tree *T; - int ret; - /* optimal basis to LP relaxation must be provided */ - if (glp_get_status(P) != GLP_OPT) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_intopt: optimal basis to initial LP relaxation" - " not provided\n"); - ret = GLP_EROOT; - goto done; - } - /* it seems all is ok */ - if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("Integer optimization begins...\n"); - /* create the branch-and-bound tree */ - T = ios_create_tree(P, parm); -#if 1 /* 11/VII-2013 */ - T->P = P0; - T->npp = npp; -#endif - /* solve the problem instance */ - ret = ios_driver(T); - /* delete the branch-and-bound tree */ - ios_delete_tree(T); - /* analyze exit code reported by the mip driver */ - if (ret == 0) - { if (P->mip_stat == GLP_FEAS) - { if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("INTEGER OPTIMAL SOLUTION FOUND\n"); - P->mip_stat = GLP_OPT; - } - else - { if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("PROBLEM HAS NO INTEGER FEASIBLE SOLUTION\n"); - P->mip_stat = GLP_NOFEAS; - } - } - else if (ret == GLP_EMIPGAP) - { if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("RELATIVE MIP GAP TOLERANCE REACHED; SEARCH TERMINA" - "TED\n"); - } - else if (ret == GLP_ETMLIM) - { if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); - } - else if (ret == GLP_EFAIL) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_intopt: cannot solve current LP relaxation\n"); - } - else if (ret == GLP_ESTOP) - { if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("SEARCH TERMINATED BY APPLICATION\n"); - } - else - xassert(ret != ret); -done: return ret; -} - -static int preprocess_and_solve_mip(glp_prob *P, const glp_iocp *parm) -{ /* solve MIP using the preprocessor */ - ENV *env = get_env_ptr(); - int term_out = env->term_out; - NPP *npp; - glp_prob *mip = NULL; - glp_bfcp bfcp; - glp_smcp smcp; - int ret; - if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("Preprocessing...\n"); - /* create preprocessor workspace */ - npp = npp_create_wksp(); - /* load original problem into the preprocessor workspace */ - npp_load_prob(npp, P, GLP_OFF, GLP_MIP, GLP_OFF); - /* process MIP prior to applying the branch-and-bound method */ - if (!term_out || parm->msg_lev < GLP_MSG_ALL) - env->term_out = GLP_OFF; - else - env->term_out = GLP_ON; - ret = npp_integer(npp, parm); - env->term_out = term_out; - if (ret == 0) - ; - else if (ret == GLP_ENOPFS) - { if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n"); - } - else if (ret == GLP_ENODFS) - { if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("LP RELAXATION HAS NO DUAL FEASIBLE SOLUTION\n"); - } - else - xassert(ret != ret); - if (ret != 0) goto done; - /* build transformed MIP */ - mip = glp_create_prob(); - npp_build_prob(npp, mip); - /* if the transformed MIP is empty, it has empty solution, which - is optimal */ - if (mip->m == 0 && mip->n == 0) - { mip->mip_stat = GLP_OPT; - mip->mip_obj = mip->c0; - if (parm->msg_lev >= GLP_MSG_ALL) - { xprintf("Objective value = %17.9e\n", mip->mip_obj); - xprintf("INTEGER OPTIMAL SOLUTION FOUND BY MIP PREPROCESSOR" - "\n"); - } - goto post; - } - /* display some statistics */ - if (parm->msg_lev >= GLP_MSG_ALL) - { int ni = glp_get_num_int(mip); - int nb = glp_get_num_bin(mip); - char s[50]; - xprintf("%d row%s, %d column%s, %d non-zero%s\n", - mip->m, mip->m == 1 ? "" : "s", mip->n, mip->n == 1 ? "" : - "s", mip->nnz, mip->nnz == 1 ? "" : "s"); - if (nb == 0) - strcpy(s, "none of"); - else if (ni == 1 && nb == 1) - strcpy(s, ""); - else if (nb == 1) - strcpy(s, "one of"); - else if (nb == ni) - strcpy(s, "all of"); - else - sprintf(s, "%d of", nb); - xprintf("%d integer variable%s, %s which %s binary\n", - ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are"); - } - /* inherit basis factorization control parameters */ - glp_get_bfcp(P, &bfcp); - glp_set_bfcp(mip, &bfcp); - /* scale the transformed problem */ - if (!term_out || parm->msg_lev < GLP_MSG_ALL) - env->term_out = GLP_OFF; - else - env->term_out = GLP_ON; - glp_scale_prob(mip, - GLP_SF_GM | GLP_SF_EQ | GLP_SF_2N | GLP_SF_SKIP); - env->term_out = term_out; - /* build advanced initial basis */ - if (!term_out || parm->msg_lev < GLP_MSG_ALL) - env->term_out = GLP_OFF; - else - env->term_out = GLP_ON; - glp_adv_basis(mip, 0); - env->term_out = term_out; - /* solve initial LP relaxation */ - if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("Solving LP relaxation...\n"); - glp_init_smcp(&smcp); - smcp.msg_lev = parm->msg_lev; - mip->it_cnt = P->it_cnt; - ret = glp_simplex(mip, &smcp); - P->it_cnt = mip->it_cnt; - if (ret != 0) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_intopt: cannot solve LP relaxation\n"); - ret = GLP_EFAIL; - goto done; - } - /* check status of the basic solution */ - ret = glp_get_status(mip); - if (ret == GLP_OPT) - ret = 0; - else if (ret == GLP_NOFEAS) - ret = GLP_ENOPFS; - else if (ret == GLP_UNBND) - ret = GLP_ENODFS; - else - xassert(ret != ret); - if (ret != 0) goto done; - /* solve the transformed MIP */ - mip->it_cnt = P->it_cnt; -#if 0 /* 11/VII-2013 */ - ret = solve_mip(mip, parm); -#else - if (parm->use_sol) - { mip->mip_stat = P->mip_stat; - mip->mip_obj = P->mip_obj; - } - ret = solve_mip(mip, parm, P, npp); -#endif - P->it_cnt = mip->it_cnt; - /* only integer feasible solution can be postprocessed */ - if (!(mip->mip_stat == GLP_OPT || mip->mip_stat == GLP_FEAS)) - { P->mip_stat = mip->mip_stat; - goto done; - } - /* postprocess solution from the transformed MIP */ -post: npp_postprocess(npp, mip); - /* the transformed MIP is no longer needed */ - glp_delete_prob(mip), mip = NULL; - /* store solution to the original problem */ - npp_unload_sol(npp, P); -done: /* delete the transformed MIP, if it exists */ - if (mip != NULL) glp_delete_prob(mip); - /* delete preprocessor workspace */ - npp_delete_wksp(npp); - return ret; -} - -#ifndef HAVE_ALIEN_SOLVER /* 28/V-2010 */ -int _glp_intopt1(glp_prob *P, const glp_iocp *parm) -{ xassert(P == P); - xassert(parm == parm); - xprintf("glp_intopt: no alien solver is available\n"); - return GLP_EFAIL; -} -#endif - -int glp_intopt(glp_prob *P, const glp_iocp *parm) -{ /* solve MIP problem with the branch-and-bound method */ - glp_iocp _parm; - int i, j, ret; - /* check problem object */ - if (P == NULL || P->magic != GLP_PROB_MAGIC) - xerror("glp_intopt: P = %p; invalid problem object\n", P); - if (P->tree != NULL) - xerror("glp_intopt: operation not allowed\n"); - /* check control parameters */ - if (parm == NULL) - parm = &_parm, glp_init_iocp((glp_iocp *)parm); - if (!(parm->msg_lev == GLP_MSG_OFF || - parm->msg_lev == GLP_MSG_ERR || - parm->msg_lev == GLP_MSG_ON || - parm->msg_lev == GLP_MSG_ALL || - parm->msg_lev == GLP_MSG_DBG)) - xerror("glp_intopt: msg_lev = %d; invalid parameter\n", - parm->msg_lev); - if (!(parm->br_tech == GLP_BR_FFV || - parm->br_tech == GLP_BR_LFV || - parm->br_tech == GLP_BR_MFV || - parm->br_tech == GLP_BR_DTH || - parm->br_tech == GLP_BR_PCH)) - xerror("glp_intopt: br_tech = %d; invalid parameter\n", - parm->br_tech); - if (!(parm->bt_tech == GLP_BT_DFS || - parm->bt_tech == GLP_BT_BFS || - parm->bt_tech == GLP_BT_BLB || - parm->bt_tech == GLP_BT_BPH)) - xerror("glp_intopt: bt_tech = %d; invalid parameter\n", - parm->bt_tech); - if (!(0.0 < parm->tol_int && parm->tol_int < 1.0)) - xerror("glp_intopt: tol_int = %g; invalid parameter\n", - parm->tol_int); - if (!(0.0 < parm->tol_obj && parm->tol_obj < 1.0)) - xerror("glp_intopt: tol_obj = %g; invalid parameter\n", - parm->tol_obj); - if (parm->tm_lim < 0) - xerror("glp_intopt: tm_lim = %d; invalid parameter\n", - parm->tm_lim); - if (parm->out_frq < 0) - xerror("glp_intopt: out_frq = %d; invalid parameter\n", - parm->out_frq); - if (parm->out_dly < 0) - xerror("glp_intopt: out_dly = %d; invalid parameter\n", - parm->out_dly); - if (!(0 <= parm->cb_size && parm->cb_size <= 256)) - xerror("glp_intopt: cb_size = %d; invalid parameter\n", - parm->cb_size); - if (!(parm->pp_tech == GLP_PP_NONE || - parm->pp_tech == GLP_PP_ROOT || - parm->pp_tech == GLP_PP_ALL)) - xerror("glp_intopt: pp_tech = %d; invalid parameter\n", - parm->pp_tech); - if (parm->mip_gap < 0.0) - xerror("glp_intopt: mip_gap = %g; invalid parameter\n", - parm->mip_gap); - if (!(parm->mir_cuts == GLP_ON || parm->mir_cuts == GLP_OFF)) - xerror("glp_intopt: mir_cuts = %d; invalid parameter\n", - parm->mir_cuts); - if (!(parm->gmi_cuts == GLP_ON || parm->gmi_cuts == GLP_OFF)) - xerror("glp_intopt: gmi_cuts = %d; invalid parameter\n", - parm->gmi_cuts); - if (!(parm->cov_cuts == GLP_ON || parm->cov_cuts == GLP_OFF)) - xerror("glp_intopt: cov_cuts = %d; invalid parameter\n", - parm->cov_cuts); - if (!(parm->clq_cuts == GLP_ON || parm->clq_cuts == GLP_OFF)) - xerror("glp_intopt: clq_cuts = %d; invalid parameter\n", - parm->clq_cuts); - if (!(parm->presolve == GLP_ON || parm->presolve == GLP_OFF)) - xerror("glp_intopt: presolve = %d; invalid parameter\n", - parm->presolve); - if (!(parm->binarize == GLP_ON || parm->binarize == GLP_OFF)) - xerror("glp_intopt: binarize = %d; invalid parameter\n", - parm->binarize); - if (!(parm->fp_heur == GLP_ON || parm->fp_heur == GLP_OFF)) - xerror("glp_intopt: fp_heur = %d; invalid parameter\n", - parm->fp_heur); -#if 1 /* 28/V-2010 */ - if (!(parm->alien == GLP_ON || parm->alien == GLP_OFF)) - xerror("glp_intopt: alien = %d; invalid parameter\n", - parm->alien); -#endif -#if 0 /* 11/VII-2013 */ - /* integer solution is currently undefined */ - P->mip_stat = GLP_UNDEF; - P->mip_obj = 0.0; -#else - if (!parm->use_sol) - P->mip_stat = GLP_UNDEF; - if (P->mip_stat == GLP_NOFEAS) - P->mip_stat = GLP_UNDEF; - if (P->mip_stat == GLP_UNDEF) - P->mip_obj = 0.0; - else if (P->mip_stat == GLP_OPT) - P->mip_stat = GLP_FEAS; -#endif - /* check bounds of double-bounded variables */ - for (i = 1; i <= P->m; i++) - { GLPROW *row = P->row[i]; - if (row->type == GLP_DB && row->lb >= row->ub) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_intopt: row %d: lb = %g, ub = %g; incorrect" - " bounds\n", i, row->lb, row->ub); - ret = GLP_EBOUND; - goto done; - } - } - for (j = 1; j <= P->n; j++) - { GLPCOL *col = P->col[j]; - if (col->type == GLP_DB && col->lb >= col->ub) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_intopt: column %d: lb = %g, ub = %g; incorr" - "ect bounds\n", j, col->lb, col->ub); - ret = GLP_EBOUND; - goto done; - } - } - /* bounds of all integer variables must be integral */ - for (j = 1; j <= P->n; j++) - { GLPCOL *col = P->col[j]; - if (col->kind != GLP_IV) continue; - if (col->type == GLP_LO || col->type == GLP_DB) - { if (col->lb != floor(col->lb)) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_intopt: integer column %d has non-intege" - "r lower bound %g\n", j, col->lb); - ret = GLP_EBOUND; - goto done; - } - } - if (col->type == GLP_UP || col->type == GLP_DB) - { if (col->ub != floor(col->ub)) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_intopt: integer column %d has non-intege" - "r upper bound %g\n", j, col->ub); - ret = GLP_EBOUND; - goto done; - } - } - if (col->type == GLP_FX) - { if (col->lb != floor(col->lb)) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("glp_intopt: integer column %d has non-intege" - "r fixed value %g\n", j, col->lb); - ret = GLP_EBOUND; - goto done; - } - } - } - /* solve MIP problem */ - if (parm->msg_lev >= GLP_MSG_ALL) - { int ni = glp_get_num_int(P); - int nb = glp_get_num_bin(P); - char s[50]; - xprintf("GLPK Integer Optimizer, v%s\n", glp_version()); - xprintf("%d row%s, %d column%s, %d non-zero%s\n", - P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s", - P->nnz, P->nnz == 1 ? "" : "s"); - if (nb == 0) - strcpy(s, "none of"); - else if (ni == 1 && nb == 1) - strcpy(s, ""); - else if (nb == 1) - strcpy(s, "one of"); - else if (nb == ni) - strcpy(s, "all of"); - else - sprintf(s, "%d of", nb); - xprintf("%d integer variable%s, %s which %s binary\n", - ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are"); - } -#if 1 /* 28/V-2010 */ - if (parm->alien) - { /* use alien integer optimizer */ - ret = _glp_intopt1(P, parm); - goto done; - } -#endif - if (!parm->presolve) -#if 0 /* 11/VII-2013 */ - ret = solve_mip(P, parm); -#else - ret = solve_mip(P, parm, P, NULL); -#endif - else - ret = preprocess_and_solve_mip(P, parm); -done: /* return to the application program */ - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_init_iocp - initialize integer optimizer control parameters -* -* SYNOPSIS -* -* void glp_init_iocp(glp_iocp *parm); -* -* DESCRIPTION -* -* The routine glp_init_iocp initializes control parameters, which are -* used by the integer optimizer, with default values. -* -* Default values of the control parameters are stored in a glp_iocp -* structure, which the parameter parm points to. */ - -void glp_init_iocp(glp_iocp *parm) -{ parm->msg_lev = GLP_MSG_ALL; - parm->br_tech = GLP_BR_DTH; - parm->bt_tech = GLP_BT_BLB; - parm->tol_int = 1e-5; - parm->tol_obj = 1e-7; - parm->tm_lim = INT_MAX; - parm->out_frq = 5000; - parm->out_dly = 10000; - parm->cb_func = NULL; - parm->cb_info = NULL; - parm->cb_size = 0; - parm->pp_tech = GLP_PP_ALL; - parm->mip_gap = 0.0; - parm->mir_cuts = GLP_OFF; - parm->gmi_cuts = GLP_OFF; - parm->cov_cuts = GLP_OFF; - parm->clq_cuts = GLP_OFF; - parm->presolve = GLP_OFF; - parm->binarize = GLP_OFF; - parm->fp_heur = GLP_OFF; -#if 1 /* 25/V-2013 */ - parm->ps_heur = GLP_OFF; -#endif -#if 1 /* 29/VI-2013 */ - parm->ps_tm_lim = 60000; /* 1 minute */ -#endif -#if 1 /* 11/VII-2013 */ - parm->use_sol = GLP_OFF; - parm->save_sol = NULL; -#endif -#if 1 /* 28/V-2010 */ - parm->alien = GLP_OFF; -#endif - return; -} - -/*********************************************************************** -* NAME -* -* glp_mip_status - retrieve status of MIP solution -* -* SYNOPSIS -* -* int glp_mip_status(glp_prob *mip); -* -* RETURNS -* -* The routine lpx_mip_status reports the status of MIP solution found -* by the branch-and-bound solver as follows: -* -* GLP_UNDEF - MIP solution is undefined; -* GLP_OPT - MIP solution is integer optimal; -* GLP_FEAS - MIP solution is integer feasible but its optimality -* (or non-optimality) has not been proven, perhaps due to -* premature termination of the search; -* GLP_NOFEAS - problem has no integer feasible solution (proven by the -* solver). */ - -int glp_mip_status(glp_prob *mip) -{ int mip_stat = mip->mip_stat; - return mip_stat; -} - -/*********************************************************************** -* NAME -* -* glp_mip_obj_val - retrieve objective value (MIP solution) -* -* SYNOPSIS -* -* double glp_mip_obj_val(glp_prob *mip); -* -* RETURNS -* -* The routine glp_mip_obj_val returns value of the objective function -* for MIP solution. */ - -double glp_mip_obj_val(glp_prob *mip) -{ /*struct LPXCPS *cps = mip->cps;*/ - double z; - z = mip->mip_obj; - /*if (cps->round && fabs(z) < 1e-9) z = 0.0;*/ - return z; -} - -/*********************************************************************** -* NAME -* -* glp_mip_row_val - retrieve row value (MIP solution) -* -* SYNOPSIS -* -* double glp_mip_row_val(glp_prob *mip, int i); -* -* RETURNS -* -* The routine glp_mip_row_val returns value of the auxiliary variable -* associated with i-th row. */ - -double glp_mip_row_val(glp_prob *mip, int i) -{ /*struct LPXCPS *cps = mip->cps;*/ - double mipx; - if (!(1 <= i && i <= mip->m)) - xerror("glp_mip_row_val: i = %d; row number out of range\n", i) - ; - mipx = mip->row[i]->mipx; - /*if (cps->round && fabs(mipx) < 1e-9) mipx = 0.0;*/ - return mipx; -} - -/*********************************************************************** -* NAME -* -* glp_mip_col_val - retrieve column value (MIP solution) -* -* SYNOPSIS -* -* double glp_mip_col_val(glp_prob *mip, int j); -* -* RETURNS -* -* The routine glp_mip_col_val returns value of the structural variable -* associated with j-th column. */ - -double glp_mip_col_val(glp_prob *mip, int j) -{ /*struct LPXCPS *cps = mip->cps;*/ - double mipx; - if (!(1 <= j && j <= mip->n)) - xerror("glp_mip_col_val: j = %d; column number out of range\n", - j); - mipx = mip->col[j]->mipx; - /*if (cps->round && fabs(mipx) < 1e-9) mipx = 0.0;*/ - return mipx; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi10.c b/resources/3rdparty/glpk-4.53/src/glpapi10.c deleted file mode 100644 index 5550aa39f..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi10.c +++ /dev/null @@ -1,305 +0,0 @@ -/* glpapi10.c (solution checking routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "prob.h" - -void glp_check_kkt(glp_prob *P, int sol, int cond, double *_ae_max, - int *_ae_ind, double *_re_max, int *_re_ind) -{ /* check feasibility and optimality conditions */ - int m = P->m; - int n = P->n; - GLPROW *row; - GLPCOL *col; - GLPAIJ *aij; - int i, j, ae_ind, re_ind; - double e, sp, sn, t, ae_max, re_max; - if (!(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP)) - xerror("glp_check_kkt: sol = %d; invalid solution indicator\n", - sol); - if (!(cond == GLP_KKT_PE || cond == GLP_KKT_PB || - cond == GLP_KKT_DE || cond == GLP_KKT_DB || - cond == GLP_KKT_CS)) - xerror("glp_check_kkt: cond = %d; invalid condition indicator " - "\n", cond); - ae_max = re_max = 0.0; - ae_ind = re_ind = 0; - if (cond == GLP_KKT_PE) - { /* xR - A * xS = 0 */ - for (i = 1; i <= m; i++) - { row = P->row[i]; - sp = sn = 0.0; - /* t := xR[i] */ - if (sol == GLP_SOL) - t = row->prim; - else if (sol == GLP_IPT) - t = row->pval; - else if (sol == GLP_MIP) - t = row->mipx; - else - xassert(sol != sol); - if (t >= 0.0) sp += t; else sn -= t; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { col = aij->col; - /* t := - a[i,j] * xS[j] */ - if (sol == GLP_SOL) - t = - aij->val * col->prim; - else if (sol == GLP_IPT) - t = - aij->val * col->pval; - else if (sol == GLP_MIP) - t = - aij->val * col->mipx; - else - xassert(sol != sol); - if (t >= 0.0) sp += t; else sn -= t; - } - /* absolute error */ - e = fabs(sp - sn); - if (ae_max < e) - ae_max = e, ae_ind = i; - /* relative error */ - e /= (1.0 + sp + sn); - if (re_max < e) - re_max = e, re_ind = i; - } - } - else if (cond == GLP_KKT_PB) - { /* lR <= xR <= uR */ - for (i = 1; i <= m; i++) - { row = P->row[i]; - /* t := xR[i] */ - if (sol == GLP_SOL) - t = row->prim; - else if (sol == GLP_IPT) - t = row->pval; - else if (sol == GLP_MIP) - t = row->mipx; - else - xassert(sol != sol); - /* check lower bound */ - if (row->type == GLP_LO || row->type == GLP_DB || - row->type == GLP_FX) - { if (t < row->lb) - { /* absolute error */ - e = row->lb - t; - if (ae_max < e) - ae_max = e, ae_ind = i; - /* relative error */ - e /= (1.0 + fabs(row->lb)); - if (re_max < e) - re_max = e, re_ind = i; - } - } - /* check upper bound */ - if (row->type == GLP_UP || row->type == GLP_DB || - row->type == GLP_FX) - { if (t > row->ub) - { /* absolute error */ - e = t - row->ub; - if (ae_max < e) - ae_max = e, ae_ind = i; - /* relative error */ - e /= (1.0 + fabs(row->ub)); - if (re_max < e) - re_max = e, re_ind = i; - } - } - } - /* lS <= xS <= uS */ - for (j = 1; j <= n; j++) - { col = P->col[j]; - /* t := xS[j] */ - if (sol == GLP_SOL) - t = col->prim; - else if (sol == GLP_IPT) - t = col->pval; - else if (sol == GLP_MIP) - t = col->mipx; - else - xassert(sol != sol); - /* check lower bound */ - if (col->type == GLP_LO || col->type == GLP_DB || - col->type == GLP_FX) - { if (t < col->lb) - { /* absolute error */ - e = col->lb - t; - if (ae_max < e) - ae_max = e, ae_ind = m+j; - /* relative error */ - e /= (1.0 + fabs(col->lb)); - if (re_max < e) - re_max = e, re_ind = m+j; - } - } - /* check upper bound */ - if (col->type == GLP_UP || col->type == GLP_DB || - col->type == GLP_FX) - { if (t > col->ub) - { /* absolute error */ - e = t - col->ub; - if (ae_max < e) - ae_max = e, ae_ind = m+j; - /* relative error */ - e /= (1.0 + fabs(col->ub)); - if (re_max < e) - re_max = e, re_ind = m+j; - } - } - } - } - else if (cond == GLP_KKT_DE) - { /* A' * (lambdaR - cR) + (lambdaS - cS) = 0 */ - for (j = 1; j <= n; j++) - { col = P->col[j]; - sp = sn = 0.0; - /* t := lambdaS[j] - cS[j] */ - if (sol == GLP_SOL) - t = col->dual - col->coef; - else if (sol == GLP_IPT) - t = col->dval - col->coef; - else - xassert(sol != sol); - if (t >= 0.0) sp += t; else sn -= t; - for (aij = col->ptr; aij != NULL; aij = aij->c_next) - { row = aij->row; - /* t := a[i,j] * (lambdaR[i] - cR[i]) */ - if (sol == GLP_SOL) - t = aij->val * row->dual; - else if (sol == GLP_IPT) - t = aij->val * row->dval; - else - xassert(sol != sol); - if (t >= 0.0) sp += t; else sn -= t; - } - /* absolute error */ - e = fabs(sp - sn); - if (ae_max < e) - ae_max = e, ae_ind = m+j; - /* relative error */ - e /= (1.0 + sp + sn); - if (re_max < e) - re_max = e, re_ind = m+j; - } - } - else if (cond == GLP_KKT_DB) - { /* check lambdaR */ - for (i = 1; i <= m; i++) - { row = P->row[i]; - /* t := lambdaR[i] */ - if (sol == GLP_SOL) - t = row->dual; - else if (sol == GLP_IPT) - t = row->dval; - else - xassert(sol != sol); - /* correct sign */ - if (P->dir == GLP_MIN) - t = + t; - else if (P->dir == GLP_MAX) - t = - t; - else - xassert(P != P); - /* check for positivity */ -#if 1 /* 08/III-2013 */ - /* the former check was correct */ - /* the bug reported by David Price is related to violation - of complementarity slackness, not to this condition */ - if (row->type == GLP_FR || row->type == GLP_LO) -#else - if (row->stat == GLP_NF || row->stat == GLP_NL) -#endif - { if (t < 0.0) - { e = - t; - if (ae_max < e) - ae_max = re_max = e, ae_ind = re_ind = i; - } - } - /* check for negativity */ -#if 1 /* 08/III-2013 */ - /* see comment above */ - if (row->type == GLP_FR || row->type == GLP_UP) -#else - if (row->stat == GLP_NF || row->stat == GLP_NU) -#endif - { if (t > 0.0) - { e = + t; - if (ae_max < e) - ae_max = re_max = e, ae_ind = re_ind = i; - } - } - } - /* check lambdaS */ - for (j = 1; j <= n; j++) - { col = P->col[j]; - /* t := lambdaS[j] */ - if (sol == GLP_SOL) - t = col->dual; - else if (sol == GLP_IPT) - t = col->dval; - else - xassert(sol != sol); - /* correct sign */ - if (P->dir == GLP_MIN) - t = + t; - else if (P->dir == GLP_MAX) - t = - t; - else - xassert(P != P); - /* check for positivity */ -#if 1 /* 08/III-2013 */ - /* see comment above */ - if (col->type == GLP_FR || col->type == GLP_LO) -#else - if (col->stat == GLP_NF || col->stat == GLP_NL) -#endif - { if (t < 0.0) - { e = - t; - if (ae_max < e) - ae_max = re_max = e, ae_ind = re_ind = m+j; - } - } - /* check for negativity */ -#if 1 /* 08/III-2013 */ - /* see comment above */ - if (col->type == GLP_FR || col->type == GLP_UP) -#else - if (col->stat == GLP_NF || col->stat == GLP_NU) -#endif - { if (t > 0.0) - { e = + t; - if (ae_max < e) - ae_max = re_max = e, ae_ind = re_ind = m+j; - } - } - } - } - else - xassert(cond != cond); - if (_ae_max != NULL) *_ae_max = ae_max; - if (_ae_ind != NULL) *_ae_ind = ae_ind; - if (_re_max != NULL) *_re_max = re_max; - if (_re_ind != NULL) *_re_ind = re_ind; - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi11.c b/resources/3rdparty/glpk-4.53/src/glpapi11.c deleted file mode 100644 index 29876da23..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi11.c +++ /dev/null @@ -1,1235 +0,0 @@ -/* glpapi11.c (utility routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpsdf.h" -#include "prob.h" - -#define xfprintf glp_format - -int glp_print_sol(glp_prob *P, const char *fname) -{ /* write basic solution in printable format */ - glp_file *fp; - GLPROW *row; - GLPCOL *col; - int i, j, t, ae_ind, re_ind, ret; - double ae_max, re_max; - xprintf("Writing basic solution to `%s'...\n", fname); - fp = glp_open(fname, "w"); - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xfprintf(fp, "%-12s%s\n", "Problem:", - P->name == NULL ? "" : P->name); - xfprintf(fp, "%-12s%d\n", "Rows:", P->m); - xfprintf(fp, "%-12s%d\n", "Columns:", P->n); - xfprintf(fp, "%-12s%d\n", "Non-zeros:", P->nnz); - t = glp_get_status(P); - xfprintf(fp, "%-12s%s\n", "Status:", - t == GLP_OPT ? "OPTIMAL" : - t == GLP_FEAS ? "FEASIBLE" : - t == GLP_INFEAS ? "INFEASIBLE (INTERMEDIATE)" : - t == GLP_NOFEAS ? "INFEASIBLE (FINAL)" : - t == GLP_UNBND ? "UNBOUNDED" : - t == GLP_UNDEF ? "UNDEFINED" : "???"); - xfprintf(fp, "%-12s%s%s%.10g (%s)\n", "Objective:", - P->obj == NULL ? "" : P->obj, - P->obj == NULL ? "" : " = ", P->obj_val, - P->dir == GLP_MIN ? "MINimum" : - P->dir == GLP_MAX ? "MAXimum" : "???"); - xfprintf(fp, "\n"); - xfprintf(fp, " No. Row name St Activity Lower bound " - " Upper bound Marginal\n"); - xfprintf(fp, "------ ------------ -- ------------- ------------- " - "------------- -------------\n"); - for (i = 1; i <= P->m; i++) - { row = P->row[i]; - xfprintf(fp, "%6d ", i); - if (row->name == NULL || strlen(row->name) <= 12) - xfprintf(fp, "%-12s ", row->name == NULL ? "" : row->name); - else - xfprintf(fp, "%s\n%20s", row->name, ""); - xfprintf(fp, "%s ", - row->stat == GLP_BS ? "B " : - row->stat == GLP_NL ? "NL" : - row->stat == GLP_NU ? "NU" : - row->stat == GLP_NF ? "NF" : - row->stat == GLP_NS ? "NS" : "??"); - xfprintf(fp, "%13.6g ", - fabs(row->prim) <= 1e-9 ? 0.0 : row->prim); - if (row->type == GLP_LO || row->type == GLP_DB || - row->type == GLP_FX) - xfprintf(fp, "%13.6g ", row->lb); - else - xfprintf(fp, "%13s ", ""); - if (row->type == GLP_UP || row->type == GLP_DB) - xfprintf(fp, "%13.6g ", row->ub); - else - xfprintf(fp, "%13s ", row->type == GLP_FX ? "=" : ""); - if (row->stat != GLP_BS) - { if (fabs(row->dual) <= 1e-9) - xfprintf(fp, "%13s", "< eps"); - else - xfprintf(fp, "%13.6g ", row->dual); - } - xfprintf(fp, "\n"); - } - xfprintf(fp, "\n"); - xfprintf(fp, " No. Column name St Activity Lower bound " - " Upper bound Marginal\n"); - xfprintf(fp, "------ ------------ -- ------------- ------------- " - "------------- -------------\n"); - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - xfprintf(fp, "%6d ", j); - if (col->name == NULL || strlen(col->name) <= 12) - xfprintf(fp, "%-12s ", col->name == NULL ? "" : col->name); - else - xfprintf(fp, "%s\n%20s", col->name, ""); - xfprintf(fp, "%s ", - col->stat == GLP_BS ? "B " : - col->stat == GLP_NL ? "NL" : - col->stat == GLP_NU ? "NU" : - col->stat == GLP_NF ? "NF" : - col->stat == GLP_NS ? "NS" : "??"); - xfprintf(fp, "%13.6g ", - fabs(col->prim) <= 1e-9 ? 0.0 : col->prim); - if (col->type == GLP_LO || col->type == GLP_DB || - col->type == GLP_FX) - xfprintf(fp, "%13.6g ", col->lb); - else - xfprintf(fp, "%13s ", ""); - if (col->type == GLP_UP || col->type == GLP_DB) - xfprintf(fp, "%13.6g ", col->ub); - else - xfprintf(fp, "%13s ", col->type == GLP_FX ? "=" : ""); - if (col->stat != GLP_BS) - { if (fabs(col->dual) <= 1e-9) - xfprintf(fp, "%13s", "< eps"); - else - xfprintf(fp, "%13.6g ", col->dual); - } - xfprintf(fp, "\n"); - } - xfprintf(fp, "\n"); - xfprintf(fp, "Karush-Kuhn-Tucker optimality conditions:\n"); - xfprintf(fp, "\n"); - glp_check_kkt(P, GLP_SOL, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, - &re_ind); - xfprintf(fp, "KKT.PE: max.abs.err = %.2e on row %d\n", - ae_max, ae_ind); - xfprintf(fp, " max.rel.err = %.2e on row %d\n", - re_max, re_ind); - xfprintf(fp, "%8s%s\n", "", - re_max <= 1e-9 ? "High quality" : - re_max <= 1e-6 ? "Medium quality" : - re_max <= 1e-3 ? "Low quality" : "PRIMAL SOLUTION IS WRONG"); - xfprintf(fp, "\n"); - glp_check_kkt(P, GLP_SOL, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, - &re_ind); - xfprintf(fp, "KKT.PB: max.abs.err = %.2e on %s %d\n", - ae_max, ae_ind <= P->m ? "row" : "column", - ae_ind <= P->m ? ae_ind : ae_ind - P->m); - xfprintf(fp, " max.rel.err = %.2e on %s %d\n", - re_max, re_ind <= P->m ? "row" : "column", - re_ind <= P->m ? re_ind : re_ind - P->m); - xfprintf(fp, "%8s%s\n", "", - re_max <= 1e-9 ? "High quality" : - re_max <= 1e-6 ? "Medium quality" : - re_max <= 1e-3 ? "Low quality" : "PRIMAL SOLUTION IS INFEASIBL" - "E"); - xfprintf(fp, "\n"); - glp_check_kkt(P, GLP_SOL, GLP_KKT_DE, &ae_max, &ae_ind, &re_max, - &re_ind); - xfprintf(fp, "KKT.DE: max.abs.err = %.2e on column %d\n", - ae_max, ae_ind == 0 ? 0 : ae_ind - P->m); - xfprintf(fp, " max.rel.err = %.2e on column %d\n", - re_max, re_ind == 0 ? 0 : re_ind - P->m); - xfprintf(fp, "%8s%s\n", "", - re_max <= 1e-9 ? "High quality" : - re_max <= 1e-6 ? "Medium quality" : - re_max <= 1e-3 ? "Low quality" : "DUAL SOLUTION IS WRONG"); - xfprintf(fp, "\n"); - glp_check_kkt(P, GLP_SOL, GLP_KKT_DB, &ae_max, &ae_ind, &re_max, - &re_ind); - xfprintf(fp, "KKT.DB: max.abs.err = %.2e on %s %d\n", - ae_max, ae_ind <= P->m ? "row" : "column", - ae_ind <= P->m ? ae_ind : ae_ind - P->m); - xfprintf(fp, " max.rel.err = %.2e on %s %d\n", - re_max, re_ind <= P->m ? "row" : "column", - re_ind <= P->m ? re_ind : re_ind - P->m); - xfprintf(fp, "%8s%s\n", "", - re_max <= 1e-9 ? "High quality" : - re_max <= 1e-6 ? "Medium quality" : - re_max <= 1e-3 ? "Low quality" : "DUAL SOLUTION IS INFEASIBLE") - ; - xfprintf(fp, "\n"); - xfprintf(fp, "End of output\n"); -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - ret = 0; -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_read_sol - read basic solution from text file -* -* SYNOPSIS -* -* int glp_read_sol(glp_prob *lp, const char *fname); -* -* DESCRIPTION -* -* The routine glp_read_sol reads basic solution from a text file whose -* name is specified by the parameter fname into the problem object. -* -* For the file format see description of the routine glp_write_sol. -* -* RETURNS -* -* On success the routine returns zero, otherwise non-zero. */ - -int glp_read_sol(glp_prob *lp, const char *fname) -{ glp_data *data; - jmp_buf jump; - int i, j, k, ret = 0; - xprintf("Reading basic solution from `%s'...\n", fname); - data = glp_sdf_open_file(fname); - if (data == NULL) - { ret = 1; - goto done; - } - if (setjmp(jump)) - { ret = 1; - goto done; - } - glp_sdf_set_jump(data, jump); - /* number of rows, number of columns */ - k = glp_sdf_read_int(data); - if (k != lp->m) - glp_sdf_error(data, "wrong number of rows\n"); - k = glp_sdf_read_int(data); - if (k != lp->n) - glp_sdf_error(data, "wrong number of columns\n"); - /* primal status, dual status, objective value */ - k = glp_sdf_read_int(data); - if (!(k == GLP_UNDEF || k == GLP_FEAS || k == GLP_INFEAS || - k == GLP_NOFEAS)) - glp_sdf_error(data, "invalid primal status\n"); - lp->pbs_stat = k; - k = glp_sdf_read_int(data); - if (!(k == GLP_UNDEF || k == GLP_FEAS || k == GLP_INFEAS || - k == GLP_NOFEAS)) - glp_sdf_error(data, "invalid dual status\n"); - lp->dbs_stat = k; - lp->obj_val = glp_sdf_read_num(data); - /* rows (auxiliary variables) */ - for (i = 1; i <= lp->m; i++) - { GLPROW *row = lp->row[i]; - /* status, primal value, dual value */ - k = glp_sdf_read_int(data); - if (!(k == GLP_BS || k == GLP_NL || k == GLP_NU || - k == GLP_NF || k == GLP_NS)) - glp_sdf_error(data, "invalid row status\n"); - glp_set_row_stat(lp, i, k); - row->prim = glp_sdf_read_num(data); - row->dual = glp_sdf_read_num(data); - } - /* columns (structural variables) */ - for (j = 1; j <= lp->n; j++) - { GLPCOL *col = lp->col[j]; - /* status, primal value, dual value */ - k = glp_sdf_read_int(data); - if (!(k == GLP_BS || k == GLP_NL || k == GLP_NU || - k == GLP_NF || k == GLP_NS)) - glp_sdf_error(data, "invalid column status\n"); - glp_set_col_stat(lp, j, k); - col->prim = glp_sdf_read_num(data); - col->dual = glp_sdf_read_num(data); - } - xprintf("%d lines were read\n", glp_sdf_line(data)); -done: if (ret) lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; - if (data != NULL) glp_sdf_close_file(data); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_write_sol - write basic solution to text file -* -* SYNOPSIS -* -* int glp_write_sol(glp_prob *lp, const char *fname); -* -* DESCRIPTION -* -* The routine glp_write_sol writes the current basic solution to a -* text file whose name is specified by the parameter fname. This file -* can be read back with the routine glp_read_sol. -* -* RETURNS -* -* On success the routine returns zero, otherwise non-zero. -* -* FILE FORMAT -* -* The file created by the routine glp_write_sol is a plain text file, -* which contains the following information: -* -* m n -* p_stat d_stat obj_val -* r_stat[1] r_prim[1] r_dual[1] -* . . . -* r_stat[m] r_prim[m] r_dual[m] -* c_stat[1] c_prim[1] c_dual[1] -* . . . -* c_stat[n] c_prim[n] c_dual[n] -* -* where: -* m is the number of rows (auxiliary variables); -* n is the number of columns (structural variables); -* p_stat is the primal status of the basic solution (GLP_UNDEF = 1, -* GLP_FEAS = 2, GLP_INFEAS = 3, or GLP_NOFEAS = 4); -* d_stat is the dual status of the basic solution (GLP_UNDEF = 1, -* GLP_FEAS = 2, GLP_INFEAS = 3, or GLP_NOFEAS = 4); -* obj_val is the objective value; -* r_stat[i], i = 1,...,m, is the status of i-th row (GLP_BS = 1, -* GLP_NL = 2, GLP_NU = 3, GLP_NF = 4, or GLP_NS = 5); -* r_prim[i], i = 1,...,m, is the primal value of i-th row; -* r_dual[i], i = 1,...,m, is the dual value of i-th row; -* c_stat[j], j = 1,...,n, is the status of j-th column (GLP_BS = 1, -* GLP_NL = 2, GLP_NU = 3, GLP_NF = 4, or GLP_NS = 5); -* c_prim[j], j = 1,...,n, is the primal value of j-th column; -* c_dual[j], j = 1,...,n, is the dual value of j-th column. */ - -int glp_write_sol(glp_prob *lp, const char *fname) -{ glp_file *fp; - int i, j, ret = 0; - xprintf("Writing basic solution to `%s'...\n", fname); - fp = glp_open(fname, "w"); - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - /* number of rows, number of columns */ - xfprintf(fp, "%d %d\n", lp->m, lp->n); - /* primal status, dual status, objective value */ - xfprintf(fp, "%d %d %.*g\n", lp->pbs_stat, lp->dbs_stat, DBL_DIG, - lp->obj_val); - /* rows (auxiliary variables) */ - for (i = 1; i <= lp->m; i++) - { GLPROW *row = lp->row[i]; - /* status, primal value, dual value */ - xfprintf(fp, "%d %.*g %.*g\n", row->stat, DBL_DIG, row->prim, - DBL_DIG, row->dual); - } - /* columns (structural variables) */ - for (j = 1; j <= lp->n; j++) - { GLPCOL *col = lp->col[j]; - /* status, primal value, dual value */ - xfprintf(fp, "%d %.*g %.*g\n", col->stat, DBL_DIG, col->prim, - DBL_DIG, col->dual); - } -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xprintf("%d lines were written\n", 2 + lp->m + lp->n); -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/**********************************************************************/ - -static char *format(char buf[13+1], double x) -{ /* format floating-point number in MPS/360-like style */ - if (x == -DBL_MAX) - strcpy(buf, " -Inf"); - else if (x == +DBL_MAX) - strcpy(buf, " +Inf"); - else if (fabs(x) <= 999999.99998) - { sprintf(buf, "%13.5f", x); -#if 1 - if (strcmp(buf, " 0.00000") == 0 || - strcmp(buf, " -0.00000") == 0) - strcpy(buf, " . "); - else if (memcmp(buf, " 0.", 8) == 0) - memcpy(buf, " .", 8); - else if (memcmp(buf, " -0.", 8) == 0) - memcpy(buf, " -.", 8); -#endif - } - else - sprintf(buf, "%13.6g", x); - return buf; -} - -int glp_print_ranges(glp_prob *P, int len, const int list[], - int flags, const char *fname) -{ /* print sensitivity analysis report */ - glp_file *fp = NULL; - GLPROW *row; - GLPCOL *col; - int m, n, pass, k, t, numb, type, stat, var1, var2, count, page, - ret; - double lb, ub, slack, coef, prim, dual, value1, value2, coef1, - coef2, obj1, obj2; - const char *name, *limit; - char buf[13+1]; - /* sanity checks */ - if (P == NULL || P->magic != GLP_PROB_MAGIC) - xerror("glp_print_ranges: P = %p; invalid problem object\n", - P); - m = P->m, n = P->n; - if (len < 0) - xerror("glp_print_ranges: len = %d; invalid list length\n", - len); - if (len > 0) - { if (list == NULL) - xerror("glp_print_ranges: list = %p: invalid parameter\n", - list); - for (t = 1; t <= len; t++) - { k = list[t]; - if (!(1 <= k && k <= m+n)) - xerror("glp_print_ranges: list[%d] = %d; row/column numb" - "er out of range\n", t, k); - } - } - if (flags != 0) - xerror("glp_print_ranges: flags = %d; invalid parameter\n", - flags); - if (fname == NULL) - xerror("glp_print_ranges: fname = %p; invalid parameter\n", - fname); - if (glp_get_status(P) != GLP_OPT) - { xprintf("glp_print_ranges: optimal basic solution required\n"); - ret = 1; - goto done; - } - if (!glp_bf_exists(P)) - { xprintf("glp_print_ranges: basis factorization required\n"); - ret = 2; - goto done; - } - /* start reporting */ - xprintf("Write sensitivity analysis report to `%s'...\n", fname); - fp = glp_open(fname, "w"); - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 3; - goto done; - } - page = count = 0; - for (pass = 1; pass <= 2; pass++) - for (t = 1; t <= (len == 0 ? m+n : len); t++) - { if (t == 1) count = 0; - k = (len == 0 ? t : list[t]); - if (pass == 1 && k > m || pass == 2 && k <= m) - continue; - if (count == 0) - { xfprintf(fp, "GLPK %-4s - SENSITIVITY ANALYSIS REPORT%73sPa" - "ge%4d\n", glp_version(), "", ++page); - xfprintf(fp, "\n"); - xfprintf(fp, "%-12s%s\n", "Problem:", - P->name == NULL ? "" : P->name); - xfprintf(fp, "%-12s%s%s%.10g (%s)\n", "Objective:", - P->obj == NULL ? "" : P->obj, - P->obj == NULL ? "" : " = ", P->obj_val, - P->dir == GLP_MIN ? "MINimum" : - P->dir == GLP_MAX ? "MAXimum" : "???"); - xfprintf(fp, "\n"); - xfprintf(fp, "%6s %-12s %2s %13s %13s %13s %13s %13s %13s " - "%s\n", "No.", pass == 1 ? "Row name" : "Column name", - "St", "Activity", pass == 1 ? "Slack" : "Obj coef", - "Lower bound", "Activity", "Obj coef", "Obj value at", - "Limiting"); - xfprintf(fp, "%6s %-12s %2s %13s %13s %13s %13s %13s %13s " - "%s\n", "", "", "", "", "Marginal", "Upper bound", - "range", "range", "break point", "variable"); - xfprintf(fp, "------ ------------ -- ------------- --------" - "----- ------------- ------------- ------------- ------" - "------- ------------\n"); - } - if (pass == 1) - { numb = k; - xassert(1 <= numb && numb <= m); - row = P->row[numb]; - name = row->name; - type = row->type; - lb = glp_get_row_lb(P, numb); - ub = glp_get_row_ub(P, numb); - coef = 0.0; - stat = row->stat; - prim = row->prim; - if (type == GLP_FR) - slack = - prim; - else if (type == GLP_LO) - slack = lb - prim; - else if (type == GLP_UP || type == GLP_DB || type == GLP_FX) - slack = ub - prim; - dual = row->dual; - } - else - { numb = k - m; - xassert(1 <= numb && numb <= n); - col = P->col[numb]; - name = col->name; - lb = glp_get_col_lb(P, numb); - ub = glp_get_col_ub(P, numb); - coef = col->coef; - stat = col->stat; - prim = col->prim; - slack = 0.0; - dual = col->dual; - } - if (stat != GLP_BS) - { glp_analyze_bound(P, k, &value1, &var1, &value2, &var2); - if (stat == GLP_NF) - coef1 = coef2 = coef; - else if (stat == GLP_NS) - coef1 = -DBL_MAX, coef2 = +DBL_MAX; - else if (stat == GLP_NL && P->dir == GLP_MIN || - stat == GLP_NU && P->dir == GLP_MAX) - coef1 = coef - dual, coef2 = +DBL_MAX; - else - coef1 = -DBL_MAX, coef2 = coef - dual; - if (value1 == -DBL_MAX) - { if (dual < -1e-9) - obj1 = +DBL_MAX; - else if (dual > +1e-9) - obj1 = -DBL_MAX; - else - obj1 = P->obj_val; - } - else - obj1 = P->obj_val + dual * (value1 - prim); - if (value2 == +DBL_MAX) - { if (dual < -1e-9) - obj2 = -DBL_MAX; - else if (dual > +1e-9) - obj2 = +DBL_MAX; - else - obj2 = P->obj_val; - } - else - obj2 = P->obj_val + dual * (value2 - prim); - } - else - { glp_analyze_coef(P, k, &coef1, &var1, &value1, &coef2, - &var2, &value2); - if (coef1 == -DBL_MAX) - { if (prim < -1e-9) - obj1 = +DBL_MAX; - else if (prim > +1e-9) - obj1 = -DBL_MAX; - else - obj1 = P->obj_val; - } - else - obj1 = P->obj_val + (coef1 - coef) * prim; - if (coef2 == +DBL_MAX) - { if (prim < -1e-9) - obj2 = -DBL_MAX; - else if (prim > +1e-9) - obj2 = +DBL_MAX; - else - obj2 = P->obj_val; - } - else - obj2 = P->obj_val + (coef2 - coef) * prim; - } - /*** first line ***/ - /* row/column number */ - xfprintf(fp, "%6d", numb); - /* row/column name */ - xfprintf(fp, " %-12.12s", name == NULL ? "" : name); - if (name != NULL && strlen(name) > 12) - xfprintf(fp, "%s\n%6s %12s", name+12, "", ""); - /* row/column status */ - xfprintf(fp, " %2s", - stat == GLP_BS ? "BS" : stat == GLP_NL ? "NL" : - stat == GLP_NU ? "NU" : stat == GLP_NF ? "NF" : - stat == GLP_NS ? "NS" : "??"); - /* row/column activity */ - xfprintf(fp, " %s", format(buf, prim)); - /* row slack, column objective coefficient */ - xfprintf(fp, " %s", format(buf, k <= m ? slack : coef)); - /* row/column lower bound */ - xfprintf(fp, " %s", format(buf, lb)); - /* row/column activity range */ - xfprintf(fp, " %s", format(buf, value1)); - /* row/column objective coefficient range */ - xfprintf(fp, " %s", format(buf, coef1)); - /* objective value at break point */ - xfprintf(fp, " %s", format(buf, obj1)); - /* limiting variable name */ - if (var1 != 0) - { if (var1 <= m) - limit = glp_get_row_name(P, var1); - else - limit = glp_get_col_name(P, var1 - m); - if (limit != NULL) - xfprintf(fp, " %s", limit); - } - xfprintf(fp, "\n"); - /*** second line ***/ - xfprintf(fp, "%6s %-12s %2s %13s", "", "", "", ""); - /* row/column reduced cost */ - xfprintf(fp, " %s", format(buf, dual)); - /* row/column upper bound */ - xfprintf(fp, " %s", format(buf, ub)); - /* row/column activity range */ - xfprintf(fp, " %s", format(buf, value2)); - /* row/column objective coefficient range */ - xfprintf(fp, " %s", format(buf, coef2)); - /* objective value at break point */ - xfprintf(fp, " %s", format(buf, obj2)); - /* limiting variable name */ - if (var2 != 0) - { if (var2 <= m) - limit = glp_get_row_name(P, var2); - else - limit = glp_get_col_name(P, var2 - m); - if (limit != NULL) - xfprintf(fp, " %s", limit); - } - xfprintf(fp, "\n"); - xfprintf(fp, "\n"); - /* print 10 items per page */ - count = (count + 1) % 10; - } - xfprintf(fp, "End of report\n"); -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 4; - goto done; - } - ret = 0; -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/**********************************************************************/ - -int glp_print_ipt(glp_prob *P, const char *fname) -{ /* write interior-point solution in printable format */ - glp_file *fp; - GLPROW *row; - GLPCOL *col; - int i, j, t, ae_ind, re_ind, ret; - double ae_max, re_max; - xprintf("Writing interior-point solution to `%s'...\n", fname); - fp = glp_open(fname, "w"); - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xfprintf(fp, "%-12s%s\n", "Problem:", - P->name == NULL ? "" : P->name); - xfprintf(fp, "%-12s%d\n", "Rows:", P->m); - xfprintf(fp, "%-12s%d\n", "Columns:", P->n); - xfprintf(fp, "%-12s%d\n", "Non-zeros:", P->nnz); - t = glp_ipt_status(P); - xfprintf(fp, "%-12s%s\n", "Status:", - t == GLP_OPT ? "OPTIMAL" : - t == GLP_UNDEF ? "UNDEFINED" : - t == GLP_INFEAS ? "INFEASIBLE (INTERMEDIATE)" : - t == GLP_NOFEAS ? "INFEASIBLE (FINAL)" : "???"); - xfprintf(fp, "%-12s%s%s%.10g (%s)\n", "Objective:", - P->obj == NULL ? "" : P->obj, - P->obj == NULL ? "" : " = ", P->ipt_obj, - P->dir == GLP_MIN ? "MINimum" : - P->dir == GLP_MAX ? "MAXimum" : "???"); - xfprintf(fp, "\n"); - xfprintf(fp, " No. Row name Activity Lower bound " - " Upper bound Marginal\n"); - xfprintf(fp, "------ ------------ ------------- ------------- " - "------------- -------------\n"); - for (i = 1; i <= P->m; i++) - { row = P->row[i]; - xfprintf(fp, "%6d ", i); - if (row->name == NULL || strlen(row->name) <= 12) - xfprintf(fp, "%-12s ", row->name == NULL ? "" : row->name); - else - xfprintf(fp, "%s\n%20s", row->name, ""); - xfprintf(fp, "%3s", ""); - xfprintf(fp, "%13.6g ", - fabs(row->pval) <= 1e-9 ? 0.0 : row->pval); - if (row->type == GLP_LO || row->type == GLP_DB || - row->type == GLP_FX) - xfprintf(fp, "%13.6g ", row->lb); - else - xfprintf(fp, "%13s ", ""); - if (row->type == GLP_UP || row->type == GLP_DB) - xfprintf(fp, "%13.6g ", row->ub); - else - xfprintf(fp, "%13s ", row->type == GLP_FX ? "=" : ""); - if (fabs(row->dval) <= 1e-9) - xfprintf(fp, "%13s", "< eps"); - else - xfprintf(fp, "%13.6g ", row->dval); - xfprintf(fp, "\n"); - } - xfprintf(fp, "\n"); - xfprintf(fp, " No. Column name Activity Lower bound " - " Upper bound Marginal\n"); - xfprintf(fp, "------ ------------ ------------- ------------- " - "------------- -------------\n"); - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - xfprintf(fp, "%6d ", j); - if (col->name == NULL || strlen(col->name) <= 12) - xfprintf(fp, "%-12s ", col->name == NULL ? "" : col->name); - else - xfprintf(fp, "%s\n%20s", col->name, ""); - xfprintf(fp, "%3s", ""); - xfprintf(fp, "%13.6g ", - fabs(col->pval) <= 1e-9 ? 0.0 : col->pval); - if (col->type == GLP_LO || col->type == GLP_DB || - col->type == GLP_FX) - xfprintf(fp, "%13.6g ", col->lb); - else - xfprintf(fp, "%13s ", ""); - if (col->type == GLP_UP || col->type == GLP_DB) - xfprintf(fp, "%13.6g ", col->ub); - else - xfprintf(fp, "%13s ", col->type == GLP_FX ? "=" : ""); - if (fabs(col->dval) <= 1e-9) - xfprintf(fp, "%13s", "< eps"); - else - xfprintf(fp, "%13.6g ", col->dval); - xfprintf(fp, "\n"); - } - xfprintf(fp, "\n"); - xfprintf(fp, "Karush-Kuhn-Tucker optimality conditions:\n"); - xfprintf(fp, "\n"); - glp_check_kkt(P, GLP_IPT, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, - &re_ind); - xfprintf(fp, "KKT.PE: max.abs.err = %.2e on row %d\n", - ae_max, ae_ind); - xfprintf(fp, " max.rel.err = %.2e on row %d\n", - re_max, re_ind); - xfprintf(fp, "%8s%s\n", "", - re_max <= 1e-9 ? "High quality" : - re_max <= 1e-6 ? "Medium quality" : - re_max <= 1e-3 ? "Low quality" : "PRIMAL SOLUTION IS WRONG"); - xfprintf(fp, "\n"); - glp_check_kkt(P, GLP_IPT, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, - &re_ind); - xfprintf(fp, "KKT.PB: max.abs.err = %.2e on %s %d\n", - ae_max, ae_ind <= P->m ? "row" : "column", - ae_ind <= P->m ? ae_ind : ae_ind - P->m); - xfprintf(fp, " max.rel.err = %.2e on %s %d\n", - re_max, re_ind <= P->m ? "row" : "column", - re_ind <= P->m ? re_ind : re_ind - P->m); - xfprintf(fp, "%8s%s\n", "", - re_max <= 1e-9 ? "High quality" : - re_max <= 1e-6 ? "Medium quality" : - re_max <= 1e-3 ? "Low quality" : "PRIMAL SOLUTION IS INFEASIBL" - "E"); - xfprintf(fp, "\n"); - glp_check_kkt(P, GLP_IPT, GLP_KKT_DE, &ae_max, &ae_ind, &re_max, - &re_ind); - xfprintf(fp, "KKT.DE: max.abs.err = %.2e on column %d\n", - ae_max, ae_ind == 0 ? 0 : ae_ind - P->m); - xfprintf(fp, " max.rel.err = %.2e on column %d\n", - re_max, re_ind == 0 ? 0 : re_ind - P->m); - xfprintf(fp, "%8s%s\n", "", - re_max <= 1e-9 ? "High quality" : - re_max <= 1e-6 ? "Medium quality" : - re_max <= 1e-3 ? "Low quality" : "DUAL SOLUTION IS WRONG"); - xfprintf(fp, "\n"); - glp_check_kkt(P, GLP_IPT, GLP_KKT_DB, &ae_max, &ae_ind, &re_max, - &re_ind); - xfprintf(fp, "KKT.DB: max.abs.err = %.2e on %s %d\n", - ae_max, ae_ind <= P->m ? "row" : "column", - ae_ind <= P->m ? ae_ind : ae_ind - P->m); - xfprintf(fp, " max.rel.err = %.2e on %s %d\n", - re_max, re_ind <= P->m ? "row" : "column", - re_ind <= P->m ? re_ind : re_ind - P->m); - xfprintf(fp, "%8s%s\n", "", - re_max <= 1e-9 ? "High quality" : - re_max <= 1e-6 ? "Medium quality" : - re_max <= 1e-3 ? "Low quality" : "DUAL SOLUTION IS INFEASIBLE") - ; - xfprintf(fp, "\n"); - xfprintf(fp, "End of output\n"); -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - ret = 0; -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_read_ipt - read interior-point solution from text file -* -* SYNOPSIS -* -* int glp_read_ipt(glp_prob *lp, const char *fname); -* -* DESCRIPTION -* -* The routine glp_read_ipt reads interior-point solution from a text -* file whose name is specified by the parameter fname into the problem -* object. -* -* For the file format see description of the routine glp_write_ipt. -* -* RETURNS -* -* On success the routine returns zero, otherwise non-zero. */ - -int glp_read_ipt(glp_prob *lp, const char *fname) -{ glp_data *data; - jmp_buf jump; - int i, j, k, ret = 0; - xprintf("Reading interior-point solution from `%s'...\n", fname); - data = glp_sdf_open_file(fname); - if (data == NULL) - { ret = 1; - goto done; - } - if (setjmp(jump)) - { ret = 1; - goto done; - } - glp_sdf_set_jump(data, jump); - /* number of rows, number of columns */ - k = glp_sdf_read_int(data); - if (k != lp->m) - glp_sdf_error(data, "wrong number of rows\n"); - k = glp_sdf_read_int(data); - if (k != lp->n) - glp_sdf_error(data, "wrong number of columns\n"); - /* solution status, objective value */ - k = glp_sdf_read_int(data); - if (!(k == GLP_UNDEF || k == GLP_OPT)) - glp_sdf_error(data, "invalid solution status\n"); - lp->ipt_stat = k; - lp->ipt_obj = glp_sdf_read_num(data); - /* rows (auxiliary variables) */ - for (i = 1; i <= lp->m; i++) - { GLPROW *row = lp->row[i]; - /* primal value, dual value */ - row->pval = glp_sdf_read_num(data); - row->dval = glp_sdf_read_num(data); - } - /* columns (structural variables) */ - for (j = 1; j <= lp->n; j++) - { GLPCOL *col = lp->col[j]; - /* primal value, dual value */ - col->pval = glp_sdf_read_num(data); - col->dval = glp_sdf_read_num(data); - } - xprintf("%d lines were read\n", glp_sdf_line(data)); -done: if (ret) lp->ipt_stat = GLP_UNDEF; - if (data != NULL) glp_sdf_close_file(data); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_write_ipt - write interior-point solution to text file -* -* SYNOPSIS -* -* int glp_write_ipt(glp_prob *lp, const char *fname); -* -* DESCRIPTION -* -* The routine glp_write_ipt writes the current interior-point solution -* to a text file whose name is specified by the parameter fname. This -* file can be read back with the routine glp_read_ipt. -* -* RETURNS -* -* On success the routine returns zero, otherwise non-zero. -* -* FILE FORMAT -* -* The file created by the routine glp_write_ipt is a plain text file, -* which contains the following information: -* -* m n -* stat obj_val -* r_prim[1] r_dual[1] -* . . . -* r_prim[m] r_dual[m] -* c_prim[1] c_dual[1] -* . . . -* c_prim[n] c_dual[n] -* -* where: -* m is the number of rows (auxiliary variables); -* n is the number of columns (structural variables); -* stat is the solution status (GLP_UNDEF = 1 or GLP_OPT = 5); -* obj_val is the objective value; -* r_prim[i], i = 1,...,m, is the primal value of i-th row; -* r_dual[i], i = 1,...,m, is the dual value of i-th row; -* c_prim[j], j = 1,...,n, is the primal value of j-th column; -* c_dual[j], j = 1,...,n, is the dual value of j-th column. */ - -int glp_write_ipt(glp_prob *lp, const char *fname) -{ glp_file *fp; - int i, j, ret = 0; - xprintf("Writing interior-point solution to `%s'...\n", fname); - fp = glp_open(fname, "w"); - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - /* number of rows, number of columns */ - xfprintf(fp, "%d %d\n", lp->m, lp->n); - /* solution status, objective value */ - xfprintf(fp, "%d %.*g\n", lp->ipt_stat, DBL_DIG, lp->ipt_obj); - /* rows (auxiliary variables) */ - for (i = 1; i <= lp->m; i++) - { GLPROW *row = lp->row[i]; - /* primal value, dual value */ - xfprintf(fp, "%.*g %.*g\n", DBL_DIG, row->pval, DBL_DIG, - row->dval); - } - /* columns (structural variables) */ - for (j = 1; j <= lp->n; j++) - { GLPCOL *col = lp->col[j]; - /* primal value, dual value */ - xfprintf(fp, "%.*g %.*g\n", DBL_DIG, col->pval, DBL_DIG, - col->dval); - } -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xprintf("%d lines were written\n", 2 + lp->m + lp->n); -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/**********************************************************************/ - -int glp_print_mip(glp_prob *P, const char *fname) -{ /* write MIP solution in printable format */ - glp_file *fp; - GLPROW *row; - GLPCOL *col; - int i, j, t, ae_ind, re_ind, ret; - double ae_max, re_max; - xprintf("Writing MIP solution to `%s'...\n", fname); - fp = glp_open(fname, "w"); - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xfprintf(fp, "%-12s%s\n", "Problem:", - P->name == NULL ? "" : P->name); - xfprintf(fp, "%-12s%d\n", "Rows:", P->m); - xfprintf(fp, "%-12s%d (%d integer, %d binary)\n", "Columns:", - P->n, glp_get_num_int(P), glp_get_num_bin(P)); - xfprintf(fp, "%-12s%d\n", "Non-zeros:", P->nnz); - t = glp_mip_status(P); - xfprintf(fp, "%-12s%s\n", "Status:", - t == GLP_OPT ? "INTEGER OPTIMAL" : - t == GLP_FEAS ? "INTEGER NON-OPTIMAL" : - t == GLP_NOFEAS ? "INTEGER EMPTY" : - t == GLP_UNDEF ? "INTEGER UNDEFINED" : "???"); - xfprintf(fp, "%-12s%s%s%.10g (%s)\n", "Objective:", - P->obj == NULL ? "" : P->obj, - P->obj == NULL ? "" : " = ", P->mip_obj, - P->dir == GLP_MIN ? "MINimum" : - P->dir == GLP_MAX ? "MAXimum" : "???"); - xfprintf(fp, "\n"); - xfprintf(fp, " No. Row name Activity Lower bound " - " Upper bound\n"); - xfprintf(fp, "------ ------------ ------------- ------------- " - "-------------\n"); - for (i = 1; i <= P->m; i++) - { row = P->row[i]; - xfprintf(fp, "%6d ", i); - if (row->name == NULL || strlen(row->name) <= 12) - xfprintf(fp, "%-12s ", row->name == NULL ? "" : row->name); - else - xfprintf(fp, "%s\n%20s", row->name, ""); - xfprintf(fp, "%3s", ""); - xfprintf(fp, "%13.6g ", - fabs(row->mipx) <= 1e-9 ? 0.0 : row->mipx); - if (row->type == GLP_LO || row->type == GLP_DB || - row->type == GLP_FX) - xfprintf(fp, "%13.6g ", row->lb); - else - xfprintf(fp, "%13s ", ""); - if (row->type == GLP_UP || row->type == GLP_DB) - xfprintf(fp, "%13.6g ", row->ub); - else - xfprintf(fp, "%13s ", row->type == GLP_FX ? "=" : ""); - xfprintf(fp, "\n"); - } - xfprintf(fp, "\n"); - xfprintf(fp, " No. Column name Activity Lower bound " - " Upper bound\n"); - xfprintf(fp, "------ ------------ ------------- ------------- " - "-------------\n"); - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - xfprintf(fp, "%6d ", j); - if (col->name == NULL || strlen(col->name) <= 12) - xfprintf(fp, "%-12s ", col->name == NULL ? "" : col->name); - else - xfprintf(fp, "%s\n%20s", col->name, ""); - xfprintf(fp, "%s ", - col->kind == GLP_CV ? " " : - col->kind == GLP_IV ? "*" : "?"); - xfprintf(fp, "%13.6g ", - fabs(col->mipx) <= 1e-9 ? 0.0 : col->mipx); - if (col->type == GLP_LO || col->type == GLP_DB || - col->type == GLP_FX) - xfprintf(fp, "%13.6g ", col->lb); - else - xfprintf(fp, "%13s ", ""); - if (col->type == GLP_UP || col->type == GLP_DB) - xfprintf(fp, "%13.6g ", col->ub); - else - xfprintf(fp, "%13s ", col->type == GLP_FX ? "=" : ""); - xfprintf(fp, "\n"); - } - xfprintf(fp, "\n"); - xfprintf(fp, "Integer feasibility conditions:\n"); - xfprintf(fp, "\n"); - glp_check_kkt(P, GLP_MIP, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, - &re_ind); - xfprintf(fp, "KKT.PE: max.abs.err = %.2e on row %d\n", - ae_max, ae_ind); - xfprintf(fp, " max.rel.err = %.2e on row %d\n", - re_max, re_ind); - xfprintf(fp, "%8s%s\n", "", - re_max <= 1e-9 ? "High quality" : - re_max <= 1e-6 ? "Medium quality" : - re_max <= 1e-3 ? "Low quality" : "SOLUTION IS WRONG"); - xfprintf(fp, "\n"); - glp_check_kkt(P, GLP_MIP, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, - &re_ind); - xfprintf(fp, "KKT.PB: max.abs.err = %.2e on %s %d\n", - ae_max, ae_ind <= P->m ? "row" : "column", - ae_ind <= P->m ? ae_ind : ae_ind - P->m); - xfprintf(fp, " max.rel.err = %.2e on %s %d\n", - re_max, re_ind <= P->m ? "row" : "column", - re_ind <= P->m ? re_ind : re_ind - P->m); - xfprintf(fp, "%8s%s\n", "", - re_max <= 1e-9 ? "High quality" : - re_max <= 1e-6 ? "Medium quality" : - re_max <= 1e-3 ? "Low quality" : "SOLUTION IS INFEASIBLE"); - xfprintf(fp, "\n"); - xfprintf(fp, "End of output\n"); -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - ret = 0; -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_read_mip - read MIP solution from text file -* -* SYNOPSIS -* -* int glp_read_mip(glp_prob *mip, const char *fname); -* -* DESCRIPTION -* -* The routine glp_read_mip reads MIP solution from a text file whose -* name is specified by the parameter fname into the problem object. -* -* For the file format see description of the routine glp_write_mip. -* -* RETURNS -* -* On success the routine returns zero, otherwise non-zero. */ - -int glp_read_mip(glp_prob *mip, const char *fname) -{ glp_data *data; - jmp_buf jump; - int i, j, k, ret = 0; - xprintf("Reading MIP solution from `%s'...\n", fname); - data = glp_sdf_open_file(fname); - if (data == NULL) - { ret = 1; - goto done; - } - if (setjmp(jump)) - { ret = 1; - goto done; - } - glp_sdf_set_jump(data, jump); - /* number of rows, number of columns */ - k = glp_sdf_read_int(data); - if (k != mip->m) - glp_sdf_error(data, "wrong number of rows\n"); - k = glp_sdf_read_int(data); - if (k != mip->n) - glp_sdf_error(data, "wrong number of columns\n"); - /* solution status, objective value */ - k = glp_sdf_read_int(data); - if (!(k == GLP_UNDEF || k == GLP_OPT || k == GLP_FEAS || - k == GLP_NOFEAS)) - glp_sdf_error(data, "invalid solution status\n"); - mip->mip_stat = k; - mip->mip_obj = glp_sdf_read_num(data); - /* rows (auxiliary variables) */ - for (i = 1; i <= mip->m; i++) - { GLPROW *row = mip->row[i]; - row->mipx = glp_sdf_read_num(data); - } - /* columns (structural variables) */ - for (j = 1; j <= mip->n; j++) - { GLPCOL *col = mip->col[j]; - col->mipx = glp_sdf_read_num(data); - if (col->kind == GLP_IV && col->mipx != floor(col->mipx)) - glp_sdf_error(data, "non-integer column value"); - } - xprintf("%d lines were read\n", glp_sdf_line(data)); -done: if (ret) mip->mip_stat = GLP_UNDEF; - if (data != NULL) glp_sdf_close_file(data); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_write_mip - write MIP solution to text file -* -* SYNOPSIS -* -* int glp_write_mip(glp_prob *mip, const char *fname); -* -* DESCRIPTION -* -* The routine glp_write_mip writes the current MIP solution to a text -* file whose name is specified by the parameter fname. This file can -* be read back with the routine glp_read_mip. -* -* RETURNS -* -* On success the routine returns zero, otherwise non-zero. -* -* FILE FORMAT -* -* The file created by the routine glp_write_sol is a plain text file, -* which contains the following information: -* -* m n -* stat obj_val -* r_val[1] -* . . . -* r_val[m] -* c_val[1] -* . . . -* c_val[n] -* -* where: -* m is the number of rows (auxiliary variables); -* n is the number of columns (structural variables); -* stat is the solution status (GLP_UNDEF = 1, GLP_FEAS = 2, -* GLP_NOFEAS = 4, or GLP_OPT = 5); -* obj_val is the objective value; -* r_val[i], i = 1,...,m, is the value of i-th row; -* c_val[j], j = 1,...,n, is the value of j-th column. */ - -int glp_write_mip(glp_prob *mip, const char *fname) -{ glp_file *fp; - int i, j, ret = 0; - xprintf("Writing MIP solution to `%s'...\n", fname); - fp = glp_open(fname, "w"); - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - /* number of rows, number of columns */ - xfprintf(fp, "%d %d\n", mip->m, mip->n); - /* solution status, objective value */ - xfprintf(fp, "%d %.*g\n", mip->mip_stat, DBL_DIG, mip->mip_obj); - /* rows (auxiliary variables) */ - for (i = 1; i <= mip->m; i++) - xfprintf(fp, "%.*g\n", DBL_DIG, mip->row[i]->mipx); - /* columns (structural variables) */ - for (j = 1; j <= mip->n; j++) - xfprintf(fp, "%.*g\n", DBL_DIG, mip->col[j]->mipx); -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xprintf("%d lines were written\n", 2 + mip->m + mip->n); -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi12.c b/resources/3rdparty/glpk-4.53/src/glpapi12.c deleted file mode 100644 index 8c2ff9073..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi12.c +++ /dev/null @@ -1,2237 +0,0 @@ -/* glpapi12.c (basis factorization and simplex tableau routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "draft.h" -#include "env.h" -#include "prob.h" - -/*********************************************************************** -* NAME -* -* glp_bf_exists - check if the basis factorization exists -* -* SYNOPSIS -* -* int glp_bf_exists(glp_prob *lp); -* -* RETURNS -* -* If the basis factorization for the current basis associated with -* the specified problem object exists and therefore is available for -* computations, the routine glp_bf_exists returns non-zero. Otherwise -* the routine returns zero. */ - -int glp_bf_exists(glp_prob *lp) -{ int ret; - ret = (lp->m == 0 || lp->valid); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_factorize - compute the basis factorization -* -* SYNOPSIS -* -* int glp_factorize(glp_prob *lp); -* -* DESCRIPTION -* -* The routine glp_factorize computes the basis factorization for the -* current basis associated with the specified problem object. -* -* RETURNS -* -* 0 The basis factorization has been successfully computed. -* -* GLP_EBADB -* The basis matrix is invalid, i.e. the number of basic (auxiliary -* and structural) variables differs from the number of rows in the -* problem object. -* -* GLP_ESING -* The basis matrix is singular within the working precision. -* -* GLP_ECOND -* The basis matrix is ill-conditioned. */ - -static int b_col(void *info, int j, int ind[], double val[]) -{ glp_prob *lp = info; - int m = lp->m; - GLPAIJ *aij; - int k, len; - xassert(1 <= j && j <= m); - /* determine the ordinal number of basic auxiliary or structural - variable x[k] corresponding to basic variable xB[j] */ - k = lp->head[j]; - /* build j-th column of the basic matrix, which is k-th column of - the scaled augmented matrix (I | -R*A*S) */ - if (k <= m) - { /* x[k] is auxiliary variable */ - len = 1; - ind[1] = k; - val[1] = 1.0; - } - else - { /* x[k] is structural variable */ - len = 0; - for (aij = lp->col[k-m]->ptr; aij != NULL; aij = aij->c_next) - { len++; - ind[len] = aij->row->i; - val[len] = - aij->row->rii * aij->val * aij->col->sjj; - } - } - return len; -} - -static void copy_bfcp(glp_prob *lp); - -int glp_factorize(glp_prob *lp) -{ int m = lp->m; - int n = lp->n; - GLPROW **row = lp->row; - GLPCOL **col = lp->col; - int *head = lp->head; - int j, k, stat, ret; - /* invalidate the basis factorization */ - lp->valid = 0; - /* build the basis header */ - j = 0; - for (k = 1; k <= m+n; k++) - { if (k <= m) - { stat = row[k]->stat; - row[k]->bind = 0; - } - else - { stat = col[k-m]->stat; - col[k-m]->bind = 0; - } - if (stat == GLP_BS) - { j++; - if (j > m) - { /* too many basic variables */ - ret = GLP_EBADB; - goto fini; - } - head[j] = k; - if (k <= m) - row[k]->bind = j; - else - col[k-m]->bind = j; - } - } - if (j < m) - { /* too few basic variables */ - ret = GLP_EBADB; - goto fini; - } - /* try to factorize the basis matrix */ - if (m > 0) - { if (lp->bfd == NULL) - { lp->bfd = bfd_create_it(); - copy_bfcp(lp); - } - switch (bfd_factorize(lp->bfd, m, lp->head, b_col, lp)) - { case 0: - /* ok */ - break; - case BFD_ESING: - /* singular matrix */ - ret = GLP_ESING; - goto fini; - case BFD_ECOND: - /* ill-conditioned matrix */ - ret = GLP_ECOND; - goto fini; - default: - xassert(lp != lp); - } - lp->valid = 1; - } - /* factorization successful */ - ret = 0; -fini: /* bring the return code to the calling program */ - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_bf_updated - check if the basis factorization has been updated -* -* SYNOPSIS -* -* int glp_bf_updated(glp_prob *lp); -* -* RETURNS -* -* If the basis factorization has been just computed from scratch, the -* routine glp_bf_updated returns zero. Otherwise, if the factorization -* has been updated one or more times, the routine returns non-zero. */ - -int glp_bf_updated(glp_prob *lp) -{ int cnt; - if (!(lp->m == 0 || lp->valid)) - xerror("glp_bf_update: basis factorization does not exist\n"); -#if 0 /* 15/XI-2009 */ - cnt = (lp->m == 0 ? 0 : lp->bfd->upd_cnt); -#else - cnt = (lp->m == 0 ? 0 : bfd_get_count(lp->bfd)); -#endif - return cnt; -} - -/*********************************************************************** -* NAME -* -* glp_get_bfcp - retrieve basis factorization control parameters -* -* SYNOPSIS -* -* void glp_get_bfcp(glp_prob *lp, glp_bfcp *parm); -* -* DESCRIPTION -* -* The routine glp_get_bfcp retrieves control parameters, which are -* used on computing and updating the basis factorization associated -* with the specified problem object. -* -* Current values of control parameters are stored by the routine in -* a glp_bfcp structure, which the parameter parm points to. */ - -void glp_get_bfcp(glp_prob *lp, glp_bfcp *parm) -{ glp_bfcp *bfcp = lp->bfcp; - if (bfcp == NULL) - { parm->type = GLP_BF_FT; - parm->lu_size = 0; - parm->piv_tol = 0.10; - parm->piv_lim = 4; - parm->suhl = GLP_ON; - parm->eps_tol = 1e-15; - parm->max_gro = 1e+10; - parm->nfs_max = 100; - parm->upd_tol = 1e-6; - parm->nrs_max = 100; - parm->rs_size = 0; - } - else - memcpy(parm, bfcp, sizeof(glp_bfcp)); - return; -} - -/*********************************************************************** -* NAME -* -* glp_set_bfcp - change basis factorization control parameters -* -* SYNOPSIS -* -* void glp_set_bfcp(glp_prob *lp, const glp_bfcp *parm); -* -* DESCRIPTION -* -* The routine glp_set_bfcp changes control parameters, which are used -* by internal GLPK routines in computing and updating the basis -* factorization associated with the specified problem object. -* -* New values of the control parameters should be passed in a structure -* glp_bfcp, which the parameter parm points to. -* -* The parameter parm can be specified as NULL, in which case all -* control parameters are reset to their default values. */ - -#if 0 /* 15/XI-2009 */ -static void copy_bfcp(glp_prob *lp) -{ glp_bfcp _parm, *parm = &_parm; - BFD *bfd = lp->bfd; - glp_get_bfcp(lp, parm); - xassert(bfd != NULL); - bfd->type = parm->type; - bfd->lu_size = parm->lu_size; - bfd->piv_tol = parm->piv_tol; - bfd->piv_lim = parm->piv_lim; - bfd->suhl = parm->suhl; - bfd->eps_tol = parm->eps_tol; - bfd->max_gro = parm->max_gro; - bfd->nfs_max = parm->nfs_max; - bfd->upd_tol = parm->upd_tol; - bfd->nrs_max = parm->nrs_max; - bfd->rs_size = parm->rs_size; - return; -} -#else -static void copy_bfcp(glp_prob *lp) -{ glp_bfcp _parm, *parm = &_parm; - glp_get_bfcp(lp, parm); - bfd_set_parm(lp->bfd, parm); - return; -} -#endif - -void glp_set_bfcp(glp_prob *lp, const glp_bfcp *parm) -{ glp_bfcp *bfcp = lp->bfcp; - if (parm == NULL) - { /* reset to default values */ - if (bfcp != NULL) - xfree(bfcp), lp->bfcp = NULL; - } - else - { /* set to specified values */ - if (bfcp == NULL) - bfcp = lp->bfcp = xmalloc(sizeof(glp_bfcp)); - memcpy(bfcp, parm, sizeof(glp_bfcp)); - if (!(bfcp->type == GLP_BF_FT || bfcp->type == GLP_BF_BG || - bfcp->type == GLP_BF_GR)) - xerror("glp_set_bfcp: type = %d; invalid parameter\n", - bfcp->type); - if (bfcp->lu_size < 0) - xerror("glp_set_bfcp: lu_size = %d; invalid parameter\n", - bfcp->lu_size); - if (!(0.0 < bfcp->piv_tol && bfcp->piv_tol < 1.0)) - xerror("glp_set_bfcp: piv_tol = %g; invalid parameter\n", - bfcp->piv_tol); - if (bfcp->piv_lim < 1) - xerror("glp_set_bfcp: piv_lim = %d; invalid parameter\n", - bfcp->piv_lim); - if (!(bfcp->suhl == GLP_ON || bfcp->suhl == GLP_OFF)) - xerror("glp_set_bfcp: suhl = %d; invalid parameter\n", - bfcp->suhl); - if (!(0.0 <= bfcp->eps_tol && bfcp->eps_tol <= 1e-6)) - xerror("glp_set_bfcp: eps_tol = %g; invalid parameter\n", - bfcp->eps_tol); - if (bfcp->max_gro < 1.0) - xerror("glp_set_bfcp: max_gro = %g; invalid parameter\n", - bfcp->max_gro); - if (!(1 <= bfcp->nfs_max && bfcp->nfs_max <= 32767)) - xerror("glp_set_bfcp: nfs_max = %d; invalid parameter\n", - bfcp->nfs_max); - if (!(0.0 < bfcp->upd_tol && bfcp->upd_tol < 1.0)) - xerror("glp_set_bfcp: upd_tol = %g; invalid parameter\n", - bfcp->upd_tol); - if (!(1 <= bfcp->nrs_max && bfcp->nrs_max <= 32767)) - xerror("glp_set_bfcp: nrs_max = %d; invalid parameter\n", - bfcp->nrs_max); - if (bfcp->rs_size < 0) - xerror("glp_set_bfcp: rs_size = %d; invalid parameter\n", - bfcp->nrs_max); - if (bfcp->rs_size == 0) - bfcp->rs_size = 20 * bfcp->nrs_max; - } - if (lp->bfd != NULL) copy_bfcp(lp); - return; -} - -/*********************************************************************** -* NAME -* -* glp_get_bhead - retrieve the basis header information -* -* SYNOPSIS -* -* int glp_get_bhead(glp_prob *lp, int k); -* -* DESCRIPTION -* -* The routine glp_get_bhead returns the basis header information for -* the current basis associated with the specified problem object. -* -* RETURNS -* -* If xB[k], 1 <= k <= m, is i-th auxiliary variable (1 <= i <= m), the -* routine returns i. Otherwise, if xB[k] is j-th structural variable -* (1 <= j <= n), the routine returns m+j. Here m is the number of rows -* and n is the number of columns in the problem object. */ - -int glp_get_bhead(glp_prob *lp, int k) -{ if (!(lp->m == 0 || lp->valid)) - xerror("glp_get_bhead: basis factorization does not exist\n"); - if (!(1 <= k && k <= lp->m)) - xerror("glp_get_bhead: k = %d; index out of range\n", k); - return lp->head[k]; -} - -/*********************************************************************** -* NAME -* -* glp_get_row_bind - retrieve row index in the basis header -* -* SYNOPSIS -* -* int glp_get_row_bind(glp_prob *lp, int i); -* -* RETURNS -* -* The routine glp_get_row_bind returns the index k of basic variable -* xB[k], 1 <= k <= m, which is i-th auxiliary variable, 1 <= i <= m, -* in the current basis associated with the specified problem object, -* where m is the number of rows. However, if i-th auxiliary variable -* is non-basic, the routine returns zero. */ - -int glp_get_row_bind(glp_prob *lp, int i) -{ if (!(lp->m == 0 || lp->valid)) - xerror("glp_get_row_bind: basis factorization does not exist\n" - ); - if (!(1 <= i && i <= lp->m)) - xerror("glp_get_row_bind: i = %d; row number out of range\n", - i); - return lp->row[i]->bind; -} - -/*********************************************************************** -* NAME -* -* glp_get_col_bind - retrieve column index in the basis header -* -* SYNOPSIS -* -* int glp_get_col_bind(glp_prob *lp, int j); -* -* RETURNS -* -* The routine glp_get_col_bind returns the index k of basic variable -* xB[k], 1 <= k <= m, which is j-th structural variable, 1 <= j <= n, -* in the current basis associated with the specified problem object, -* where m is the number of rows, n is the number of columns. However, -* if j-th structural variable is non-basic, the routine returns zero.*/ - -int glp_get_col_bind(glp_prob *lp, int j) -{ if (!(lp->m == 0 || lp->valid)) - xerror("glp_get_col_bind: basis factorization does not exist\n" - ); - if (!(1 <= j && j <= lp->n)) - xerror("glp_get_col_bind: j = %d; column number out of range\n" - , j); - return lp->col[j]->bind; -} - -/*********************************************************************** -* NAME -* -* glp_ftran - perform forward transformation (solve system B*x = b) -* -* SYNOPSIS -* -* void glp_ftran(glp_prob *lp, double x[]); -* -* DESCRIPTION -* -* The routine glp_ftran performs forward transformation, i.e. solves -* the system B*x = b, where B is the basis matrix corresponding to the -* current basis for the specified problem object, x is the vector of -* unknowns to be computed, b is the vector of right-hand sides. -* -* On entry elements of the vector b should be stored in dense format -* in locations x[1], ..., x[m], where m is the number of rows. On exit -* the routine stores elements of the vector x in the same locations. -* -* SCALING/UNSCALING -* -* Let A~ = (I | -A) is the augmented constraint matrix of the original -* (unscaled) problem. In the scaled LP problem instead the matrix A the -* scaled matrix A" = R*A*S is actually used, so -* -* A~" = (I | A") = (I | R*A*S) = (R*I*inv(R) | R*A*S) = -* (1) -* = R*(I | A)*S~ = R*A~*S~, -* -* is the scaled augmented constraint matrix, where R and S are diagonal -* scaling matrices used to scale rows and columns of the matrix A, and -* -* S~ = diag(inv(R) | S) (2) -* -* is an augmented diagonal scaling matrix. -* -* By definition: -* -* A~ = (B | N), (3) -* -* where B is the basic matrix, which consists of basic columns of the -* augmented constraint matrix A~, and N is a matrix, which consists of -* non-basic columns of A~. From (1) it follows that: -* -* A~" = (B" | N") = (R*B*SB | R*N*SN), (4) -* -* where SB and SN are parts of the augmented scaling matrix S~, which -* correspond to basic and non-basic variables, respectively. Therefore -* -* B" = R*B*SB, (5) -* -* which is the scaled basis matrix. */ - -void glp_ftran(glp_prob *lp, double x[]) -{ int m = lp->m; - GLPROW **row = lp->row; - GLPCOL **col = lp->col; - int i, k; - /* B*x = b ===> (R*B*SB)*(inv(SB)*x) = R*b ===> - B"*x" = b", where b" = R*b, x = SB*x" */ - if (!(m == 0 || lp->valid)) - xerror("glp_ftran: basis factorization does not exist\n"); - /* b" := R*b */ - for (i = 1; i <= m; i++) - x[i] *= row[i]->rii; - /* x" := inv(B")*b" */ - if (m > 0) bfd_ftran(lp->bfd, x); - /* x := SB*x" */ - for (i = 1; i <= m; i++) - { k = lp->head[i]; - if (k <= m) - x[i] /= row[k]->rii; - else - x[i] *= col[k-m]->sjj; - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_btran - perform backward transformation (solve system B'*x = b) -* -* SYNOPSIS -* -* void glp_btran(glp_prob *lp, double x[]); -* -* DESCRIPTION -* -* The routine glp_btran performs backward transformation, i.e. solves -* the system B'*x = b, where B' is a matrix transposed to the basis -* matrix corresponding to the current basis for the specified problem -* problem object, x is the vector of unknowns to be computed, b is the -* vector of right-hand sides. -* -* On entry elements of the vector b should be stored in dense format -* in locations x[1], ..., x[m], where m is the number of rows. On exit -* the routine stores elements of the vector x in the same locations. -* -* SCALING/UNSCALING -* -* See comments to the routine glp_ftran. */ - -void glp_btran(glp_prob *lp, double x[]) -{ int m = lp->m; - GLPROW **row = lp->row; - GLPCOL **col = lp->col; - int i, k; - /* B'*x = b ===> (SB*B'*R)*(inv(R)*x) = SB*b ===> - (B")'*x" = b", where b" = SB*b, x = R*x" */ - if (!(m == 0 || lp->valid)) - xerror("glp_btran: basis factorization does not exist\n"); - /* b" := SB*b */ - for (i = 1; i <= m; i++) - { k = lp->head[i]; - if (k <= m) - x[i] /= row[k]->rii; - else - x[i] *= col[k-m]->sjj; - } - /* x" := inv[(B")']*b" */ - if (m > 0) bfd_btran(lp->bfd, x); - /* x := R*x" */ - for (i = 1; i <= m; i++) - x[i] *= row[i]->rii; - return; -} - -/*********************************************************************** -* NAME -* -* glp_warm_up - "warm up" LP basis -* -* SYNOPSIS -* -* int glp_warm_up(glp_prob *P); -* -* DESCRIPTION -* -* The routine glp_warm_up "warms up" the LP basis for the specified -* problem object using current statuses assigned to rows and columns -* (that is, to auxiliary and structural variables). -* -* This operation includes computing factorization of the basis matrix -* (if it does not exist), computing primal and dual components of basic -* solution, and determining the solution status. -* -* RETURNS -* -* 0 The operation has been successfully performed. -* -* GLP_EBADB -* The basis matrix is invalid, i.e. the number of basic (auxiliary -* and structural) variables differs from the number of rows in the -* problem object. -* -* GLP_ESING -* The basis matrix is singular within the working precision. -* -* GLP_ECOND -* The basis matrix is ill-conditioned. */ - -int glp_warm_up(glp_prob *P) -{ GLPROW *row; - GLPCOL *col; - GLPAIJ *aij; - int i, j, type, stat, ret; - double eps, temp, *work; - /* invalidate basic solution */ - P->pbs_stat = P->dbs_stat = GLP_UNDEF; - P->obj_val = 0.0; - P->some = 0; - for (i = 1; i <= P->m; i++) - { row = P->row[i]; - row->prim = row->dual = 0.0; - } - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - col->prim = col->dual = 0.0; - } - /* compute the basis factorization, if necessary */ - if (!glp_bf_exists(P)) - { ret = glp_factorize(P); - if (ret != 0) goto done; - } - /* allocate working array */ - work = xcalloc(1+P->m, sizeof(double)); - /* determine and store values of non-basic variables, compute - vector (- N * xN) */ - for (i = 1; i <= P->m; i++) - work[i] = 0.0; - for (i = 1; i <= P->m; i++) - { row = P->row[i]; - if (row->stat == GLP_BS) - continue; - else if (row->stat == GLP_NL) - row->prim = row->lb; - else if (row->stat == GLP_NU) - row->prim = row->ub; - else if (row->stat == GLP_NF) - row->prim = 0.0; - else if (row->stat == GLP_NS) - row->prim = row->lb; - else - xassert(row != row); - /* N[j] is i-th column of matrix (I|-A) */ - work[i] -= row->prim; - } - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - if (col->stat == GLP_BS) - continue; - else if (col->stat == GLP_NL) - col->prim = col->lb; - else if (col->stat == GLP_NU) - col->prim = col->ub; - else if (col->stat == GLP_NF) - col->prim = 0.0; - else if (col->stat == GLP_NS) - col->prim = col->lb; - else - xassert(col != col); - /* N[j] is (m+j)-th column of matrix (I|-A) */ - if (col->prim != 0.0) - { for (aij = col->ptr; aij != NULL; aij = aij->c_next) - work[aij->row->i] += aij->val * col->prim; - } - } - /* compute vector of basic variables xB = - inv(B) * N * xN */ - glp_ftran(P, work); - /* store values of basic variables, check primal feasibility */ - P->pbs_stat = GLP_FEAS; - for (i = 1; i <= P->m; i++) - { row = P->row[i]; - if (row->stat != GLP_BS) - continue; - row->prim = work[row->bind]; - type = row->type; - if (type == GLP_LO || type == GLP_DB || type == GLP_FX) - { eps = 1e-6 + 1e-9 * fabs(row->lb); - if (row->prim < row->lb - eps) - P->pbs_stat = GLP_INFEAS; - } - if (type == GLP_UP || type == GLP_DB || type == GLP_FX) - { eps = 1e-6 + 1e-9 * fabs(row->ub); - if (row->prim > row->ub + eps) - P->pbs_stat = GLP_INFEAS; - } - } - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - if (col->stat != GLP_BS) - continue; - col->prim = work[col->bind]; - type = col->type; - if (type == GLP_LO || type == GLP_DB || type == GLP_FX) - { eps = 1e-6 + 1e-9 * fabs(col->lb); - if (col->prim < col->lb - eps) - P->pbs_stat = GLP_INFEAS; - } - if (type == GLP_UP || type == GLP_DB || type == GLP_FX) - { eps = 1e-6 + 1e-9 * fabs(col->ub); - if (col->prim > col->ub + eps) - P->pbs_stat = GLP_INFEAS; - } - } - /* compute value of the objective function */ - P->obj_val = P->c0; - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - P->obj_val += col->coef * col->prim; - } - /* build vector cB of objective coefficients at basic variables */ - for (i = 1; i <= P->m; i++) - work[i] = 0.0; - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - if (col->stat == GLP_BS) - work[col->bind] = col->coef; - } - /* compute vector of simplex multipliers pi = inv(B') * cB */ - glp_btran(P, work); - /* compute and store reduced costs of non-basic variables d[j] = - c[j] - N'[j] * pi, check dual feasibility */ - P->dbs_stat = GLP_FEAS; - for (i = 1; i <= P->m; i++) - { row = P->row[i]; - if (row->stat == GLP_BS) - { row->dual = 0.0; - continue; - } - /* N[j] is i-th column of matrix (I|-A) */ - row->dual = - work[i]; -#if 0 /* 07/III-2013 */ - type = row->type; - temp = (P->dir == GLP_MIN ? + row->dual : - row->dual); - if ((type == GLP_FR || type == GLP_LO) && temp < -1e-5 || - (type == GLP_FR || type == GLP_UP) && temp > +1e-5) - P->dbs_stat = GLP_INFEAS; -#else - stat = row->stat; - temp = (P->dir == GLP_MIN ? + row->dual : - row->dual); - if ((stat == GLP_NF || stat == GLP_NL) && temp < -1e-5 || - (stat == GLP_NF || stat == GLP_NU) && temp > +1e-5) - P->dbs_stat = GLP_INFEAS; -#endif - } - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - if (col->stat == GLP_BS) - { col->dual = 0.0; - continue; - } - /* N[j] is (m+j)-th column of matrix (I|-A) */ - col->dual = col->coef; - for (aij = col->ptr; aij != NULL; aij = aij->c_next) - col->dual += aij->val * work[aij->row->i]; -#if 0 /* 07/III-2013 */ - type = col->type; - temp = (P->dir == GLP_MIN ? + col->dual : - col->dual); - if ((type == GLP_FR || type == GLP_LO) && temp < -1e-5 || - (type == GLP_FR || type == GLP_UP) && temp > +1e-5) - P->dbs_stat = GLP_INFEAS; -#else - stat = col->stat; - temp = (P->dir == GLP_MIN ? + col->dual : - col->dual); - if ((stat == GLP_NF || stat == GLP_NL) && temp < -1e-5 || - (stat == GLP_NF || stat == GLP_NU) && temp > +1e-5) - P->dbs_stat = GLP_INFEAS; -#endif - } - /* free working array */ - xfree(work); - ret = 0; -done: return ret; -} - -/*********************************************************************** -* NAME -* -* glp_eval_tab_row - compute row of the simplex tableau -* -* SYNOPSIS -* -* int glp_eval_tab_row(glp_prob *lp, int k, int ind[], double val[]); -* -* DESCRIPTION -* -* The routine glp_eval_tab_row computes a row of the current simplex -* tableau for the basic variable, which is specified by the number k: -* if 1 <= k <= m, x[k] is k-th auxiliary variable; if m+1 <= k <= m+n, -* x[k] is (k-m)-th structural variable, where m is number of rows, and -* n is number of columns. The current basis must be available. -* -* The routine stores column indices and numerical values of non-zero -* elements of the computed row using sparse format to the locations -* ind[1], ..., ind[len] and val[1], ..., val[len], respectively, where -* 0 <= len <= n is number of non-zeros returned on exit. -* -* Element indices stored in the array ind have the same sense as the -* index k, i.e. indices 1 to m denote auxiliary variables and indices -* m+1 to m+n denote structural ones (all these variables are obviously -* non-basic by definition). -* -* The computed row shows how the specified basic variable x[k] = xB[i] -* depends on non-basic variables: -* -* xB[i] = alfa[i,1]*xN[1] + alfa[i,2]*xN[2] + ... + alfa[i,n]*xN[n], -* -* where alfa[i,j] are elements of the simplex table row, xN[j] are -* non-basic (auxiliary and structural) variables. -* -* RETURNS -* -* The routine returns number of non-zero elements in the simplex table -* row stored in the arrays ind and val. -* -* BACKGROUND -* -* The system of equality constraints of the LP problem is: -* -* xR = A * xS, (1) -* -* where xR is the vector of auxliary variables, xS is the vector of -* structural variables, A is the matrix of constraint coefficients. -* -* The system (1) can be written in homogenous form as follows: -* -* A~ * x = 0, (2) -* -* where A~ = (I | -A) is the augmented constraint matrix (has m rows -* and m+n columns), x = (xR | xS) is the vector of all (auxiliary and -* structural) variables. -* -* By definition for the current basis we have: -* -* A~ = (B | N), (3) -* -* where B is the basis matrix. Thus, the system (2) can be written as: -* -* B * xB + N * xN = 0. (4) -* -* From (4) it follows that: -* -* xB = A^ * xN, (5) -* -* where the matrix -* -* A^ = - inv(B) * N (6) -* -* is called the simplex table. -* -* It is understood that i-th row of the simplex table is: -* -* e * A^ = - e * inv(B) * N, (7) -* -* where e is a unity vector with e[i] = 1. -* -* To compute i-th row of the simplex table the routine first computes -* i-th row of the inverse: -* -* rho = inv(B') * e, (8) -* -* where B' is a matrix transposed to B, and then computes elements of -* i-th row of the simplex table as scalar products: -* -* alfa[i,j] = - rho * N[j] for all j, (9) -* -* where N[j] is a column of the augmented constraint matrix A~, which -* corresponds to some non-basic auxiliary or structural variable. */ - -int glp_eval_tab_row(glp_prob *lp, int k, int ind[], double val[]) -{ int m = lp->m; - int n = lp->n; - int i, t, len, lll, *iii; - double alfa, *rho, *vvv; - if (!(m == 0 || lp->valid)) - xerror("glp_eval_tab_row: basis factorization does not exist\n" - ); - if (!(1 <= k && k <= m+n)) - xerror("glp_eval_tab_row: k = %d; variable number out of range" - , k); - /* determine xB[i] which corresponds to x[k] */ - if (k <= m) - i = glp_get_row_bind(lp, k); - else - i = glp_get_col_bind(lp, k-m); - if (i == 0) - xerror("glp_eval_tab_row: k = %d; variable must be basic", k); - xassert(1 <= i && i <= m); - /* allocate working arrays */ - rho = xcalloc(1+m, sizeof(double)); - iii = xcalloc(1+m, sizeof(int)); - vvv = xcalloc(1+m, sizeof(double)); - /* compute i-th row of the inverse; see (8) */ - for (t = 1; t <= m; t++) rho[t] = 0.0; - rho[i] = 1.0; - glp_btran(lp, rho); - /* compute i-th row of the simplex table */ - len = 0; - for (k = 1; k <= m+n; k++) - { if (k <= m) - { /* x[k] is auxiliary variable, so N[k] is a unity column */ - if (glp_get_row_stat(lp, k) == GLP_BS) continue; - /* compute alfa[i,j]; see (9) */ - alfa = - rho[k]; - } - else - { /* x[k] is structural variable, so N[k] is a column of the - original constraint matrix A with negative sign */ - if (glp_get_col_stat(lp, k-m) == GLP_BS) continue; - /* compute alfa[i,j]; see (9) */ - lll = glp_get_mat_col(lp, k-m, iii, vvv); - alfa = 0.0; - for (t = 1; t <= lll; t++) alfa += rho[iii[t]] * vvv[t]; - } - /* store alfa[i,j] */ - if (alfa != 0.0) len++, ind[len] = k, val[len] = alfa; - } - xassert(len <= n); - /* free working arrays */ - xfree(rho); - xfree(iii); - xfree(vvv); - /* return to the calling program */ - return len; -} - -/*********************************************************************** -* NAME -* -* glp_eval_tab_col - compute column of the simplex tableau -* -* SYNOPSIS -* -* int glp_eval_tab_col(glp_prob *lp, int k, int ind[], double val[]); -* -* DESCRIPTION -* -* The routine glp_eval_tab_col computes a column of the current simplex -* table for the non-basic variable, which is specified by the number k: -* if 1 <= k <= m, x[k] is k-th auxiliary variable; if m+1 <= k <= m+n, -* x[k] is (k-m)-th structural variable, where m is number of rows, and -* n is number of columns. The current basis must be available. -* -* The routine stores row indices and numerical values of non-zero -* elements of the computed column using sparse format to the locations -* ind[1], ..., ind[len] and val[1], ..., val[len] respectively, where -* 0 <= len <= m is number of non-zeros returned on exit. -* -* Element indices stored in the array ind have the same sense as the -* index k, i.e. indices 1 to m denote auxiliary variables and indices -* m+1 to m+n denote structural ones (all these variables are obviously -* basic by the definition). -* -* The computed column shows how basic variables depend on the specified -* non-basic variable x[k] = xN[j]: -* -* xB[1] = ... + alfa[1,j]*xN[j] + ... -* xB[2] = ... + alfa[2,j]*xN[j] + ... -* . . . . . . -* xB[m] = ... + alfa[m,j]*xN[j] + ... -* -* where alfa[i,j] are elements of the simplex table column, xB[i] are -* basic (auxiliary and structural) variables. -* -* RETURNS -* -* The routine returns number of non-zero elements in the simplex table -* column stored in the arrays ind and val. -* -* BACKGROUND -* -* As it was explained in comments to the routine glp_eval_tab_row (see -* above) the simplex table is the following matrix: -* -* A^ = - inv(B) * N. (1) -* -* Therefore j-th column of the simplex table is: -* -* A^ * e = - inv(B) * N * e = - inv(B) * N[j], (2) -* -* where e is a unity vector with e[j] = 1, B is the basis matrix, N[j] -* is a column of the augmented constraint matrix A~, which corresponds -* to the given non-basic auxiliary or structural variable. */ - -int glp_eval_tab_col(glp_prob *lp, int k, int ind[], double val[]) -{ int m = lp->m; - int n = lp->n; - int t, len, stat; - double *col; - if (!(m == 0 || lp->valid)) - xerror("glp_eval_tab_col: basis factorization does not exist\n" - ); - if (!(1 <= k && k <= m+n)) - xerror("glp_eval_tab_col: k = %d; variable number out of range" - , k); - if (k <= m) - stat = glp_get_row_stat(lp, k); - else - stat = glp_get_col_stat(lp, k-m); - if (stat == GLP_BS) - xerror("glp_eval_tab_col: k = %d; variable must be non-basic", - k); - /* obtain column N[k] with negative sign */ - col = xcalloc(1+m, sizeof(double)); - for (t = 1; t <= m; t++) col[t] = 0.0; - if (k <= m) - { /* x[k] is auxiliary variable, so N[k] is a unity column */ - col[k] = -1.0; - } - else - { /* x[k] is structural variable, so N[k] is a column of the - original constraint matrix A with negative sign */ - len = glp_get_mat_col(lp, k-m, ind, val); - for (t = 1; t <= len; t++) col[ind[t]] = val[t]; - } - /* compute column of the simplex table, which corresponds to the - specified non-basic variable x[k] */ - glp_ftran(lp, col); - len = 0; - for (t = 1; t <= m; t++) - { if (col[t] != 0.0) - { len++; - ind[len] = glp_get_bhead(lp, t); - val[len] = col[t]; - } - } - xfree(col); - /* return to the calling program */ - return len; -} - -/*********************************************************************** -* NAME -* -* glp_transform_row - transform explicitly specified row -* -* SYNOPSIS -* -* int glp_transform_row(glp_prob *P, int len, int ind[], double val[]); -* -* DESCRIPTION -* -* The routine glp_transform_row performs the same operation as the -* routine glp_eval_tab_row with exception that the row to be -* transformed is specified explicitly as a sparse vector. -* -* The explicitly specified row may be thought as a linear form: -* -* x = a[1]*x[m+1] + a[2]*x[m+2] + ... + a[n]*x[m+n], (1) -* -* where x is an auxiliary variable for this row, a[j] are coefficients -* of the linear form, x[m+j] are structural variables. -* -* On entry column indices and numerical values of non-zero elements of -* the row should be stored in locations ind[1], ..., ind[len] and -* val[1], ..., val[len], where len is the number of non-zero elements. -* -* This routine uses the system of equality constraints and the current -* basis in order to express the auxiliary variable x in (1) through the -* current non-basic variables (as if the transformed row were added to -* the problem object and its auxiliary variable were basic), i.e. the -* resultant row has the form: -* -* x = alfa[1]*xN[1] + alfa[2]*xN[2] + ... + alfa[n]*xN[n], (2) -* -* where xN[j] are non-basic (auxiliary or structural) variables, n is -* the number of columns in the LP problem object. -* -* On exit the routine stores indices and numerical values of non-zero -* elements of the resultant row (2) in locations ind[1], ..., ind[len'] -* and val[1], ..., val[len'], where 0 <= len' <= n is the number of -* non-zero elements in the resultant row returned by the routine. Note -* that indices (numbers) of non-basic variables stored in the array ind -* correspond to original ordinal numbers of variables: indices 1 to m -* mean auxiliary variables and indices m+1 to m+n mean structural ones. -* -* RETURNS -* -* The routine returns len', which is the number of non-zero elements in -* the resultant row stored in the arrays ind and val. -* -* BACKGROUND -* -* The explicitly specified row (1) is transformed in the same way as it -* were the objective function row. -* -* From (1) it follows that: -* -* x = aB * xB + aN * xN, (3) -* -* where xB is the vector of basic variables, xN is the vector of -* non-basic variables. -* -* The simplex table, which corresponds to the current basis, is: -* -* xB = [-inv(B) * N] * xN. (4) -* -* Therefore substituting xB from (4) to (3) we have: -* -* x = aB * [-inv(B) * N] * xN + aN * xN = -* (5) -* = rho * (-N) * xN + aN * xN = alfa * xN, -* -* where: -* -* rho = inv(B') * aB, (6) -* -* and -* -* alfa = aN + rho * (-N) (7) -* -* is the resultant row computed by the routine. */ - -int glp_transform_row(glp_prob *P, int len, int ind[], double val[]) -{ int i, j, k, m, n, t, lll, *iii; - double alfa, *a, *aB, *rho, *vvv; - if (!glp_bf_exists(P)) - xerror("glp_transform_row: basis factorization does not exist " - "\n"); - m = glp_get_num_rows(P); - n = glp_get_num_cols(P); - /* unpack the row to be transformed to the array a */ - a = xcalloc(1+n, sizeof(double)); - for (j = 1; j <= n; j++) a[j] = 0.0; - if (!(0 <= len && len <= n)) - xerror("glp_transform_row: len = %d; invalid row length\n", - len); - for (t = 1; t <= len; t++) - { j = ind[t]; - if (!(1 <= j && j <= n)) - xerror("glp_transform_row: ind[%d] = %d; column index out o" - "f range\n", t, j); - if (val[t] == 0.0) - xerror("glp_transform_row: val[%d] = 0; zero coefficient no" - "t allowed\n", t); - if (a[j] != 0.0) - xerror("glp_transform_row: ind[%d] = %d; duplicate column i" - "ndices not allowed\n", t, j); - a[j] = val[t]; - } - /* construct the vector aB */ - aB = xcalloc(1+m, sizeof(double)); - for (i = 1; i <= m; i++) - { k = glp_get_bhead(P, i); - /* xB[i] is k-th original variable */ - xassert(1 <= k && k <= m+n); - aB[i] = (k <= m ? 0.0 : a[k-m]); - } - /* solve the system B'*rho = aB to compute the vector rho */ - rho = aB, glp_btran(P, rho); - /* compute coefficients at non-basic auxiliary variables */ - len = 0; - for (i = 1; i <= m; i++) - { if (glp_get_row_stat(P, i) != GLP_BS) - { alfa = - rho[i]; - if (alfa != 0.0) - { len++; - ind[len] = i; - val[len] = alfa; - } - } - } - /* compute coefficients at non-basic structural variables */ - iii = xcalloc(1+m, sizeof(int)); - vvv = xcalloc(1+m, sizeof(double)); - for (j = 1; j <= n; j++) - { if (glp_get_col_stat(P, j) != GLP_BS) - { alfa = a[j]; - lll = glp_get_mat_col(P, j, iii, vvv); - for (t = 1; t <= lll; t++) alfa += vvv[t] * rho[iii[t]]; - if (alfa != 0.0) - { len++; - ind[len] = m+j; - val[len] = alfa; - } - } - } - xassert(len <= n); - xfree(iii); - xfree(vvv); - xfree(aB); - xfree(a); - return len; -} - -/*********************************************************************** -* NAME -* -* glp_transform_col - transform explicitly specified column -* -* SYNOPSIS -* -* int glp_transform_col(glp_prob *P, int len, int ind[], double val[]); -* -* DESCRIPTION -* -* The routine glp_transform_col performs the same operation as the -* routine glp_eval_tab_col with exception that the column to be -* transformed is specified explicitly as a sparse vector. -* -* The explicitly specified column may be thought as if it were added -* to the original system of equality constraints: -* -* x[1] = a[1,1]*x[m+1] + ... + a[1,n]*x[m+n] + a[1]*x -* x[2] = a[2,1]*x[m+1] + ... + a[2,n]*x[m+n] + a[2]*x (1) -* . . . . . . . . . . . . . . . -* x[m] = a[m,1]*x[m+1] + ... + a[m,n]*x[m+n] + a[m]*x -* -* where x[i] are auxiliary variables, x[m+j] are structural variables, -* x is a structural variable for the explicitly specified column, a[i] -* are constraint coefficients for x. -* -* On entry row indices and numerical values of non-zero elements of -* the column should be stored in locations ind[1], ..., ind[len] and -* val[1], ..., val[len], where len is the number of non-zero elements. -* -* This routine uses the system of equality constraints and the current -* basis in order to express the current basic variables through the -* structural variable x in (1) (as if the transformed column were added -* to the problem object and the variable x were non-basic), i.e. the -* resultant column has the form: -* -* xB[1] = ... + alfa[1]*x -* xB[2] = ... + alfa[2]*x (2) -* . . . . . . -* xB[m] = ... + alfa[m]*x -* -* where xB are basic (auxiliary and structural) variables, m is the -* number of rows in the problem object. -* -* On exit the routine stores indices and numerical values of non-zero -* elements of the resultant column (2) in locations ind[1], ..., -* ind[len'] and val[1], ..., val[len'], where 0 <= len' <= m is the -* number of non-zero element in the resultant column returned by the -* routine. Note that indices (numbers) of basic variables stored in -* the array ind correspond to original ordinal numbers of variables: -* indices 1 to m mean auxiliary variables and indices m+1 to m+n mean -* structural ones. -* -* RETURNS -* -* The routine returns len', which is the number of non-zero elements -* in the resultant column stored in the arrays ind and val. -* -* BACKGROUND -* -* The explicitly specified column (1) is transformed in the same way -* as any other column of the constraint matrix using the formula: -* -* alfa = inv(B) * a, (3) -* -* where alfa is the resultant column computed by the routine. */ - -int glp_transform_col(glp_prob *P, int len, int ind[], double val[]) -{ int i, m, t; - double *a, *alfa; - if (!glp_bf_exists(P)) - xerror("glp_transform_col: basis factorization does not exist " - "\n"); - m = glp_get_num_rows(P); - /* unpack the column to be transformed to the array a */ - a = xcalloc(1+m, sizeof(double)); - for (i = 1; i <= m; i++) a[i] = 0.0; - if (!(0 <= len && len <= m)) - xerror("glp_transform_col: len = %d; invalid column length\n", - len); - for (t = 1; t <= len; t++) - { i = ind[t]; - if (!(1 <= i && i <= m)) - xerror("glp_transform_col: ind[%d] = %d; row index out of r" - "ange\n", t, i); - if (val[t] == 0.0) - xerror("glp_transform_col: val[%d] = 0; zero coefficient no" - "t allowed\n", t); - if (a[i] != 0.0) - xerror("glp_transform_col: ind[%d] = %d; duplicate row indi" - "ces not allowed\n", t, i); - a[i] = val[t]; - } - /* solve the system B*a = alfa to compute the vector alfa */ - alfa = a, glp_ftran(P, alfa); - /* store resultant coefficients */ - len = 0; - for (i = 1; i <= m; i++) - { if (alfa[i] != 0.0) - { len++; - ind[len] = glp_get_bhead(P, i); - val[len] = alfa[i]; - } - } - xfree(a); - return len; -} - -/*********************************************************************** -* NAME -* -* glp_prim_rtest - perform primal ratio test -* -* SYNOPSIS -* -* int glp_prim_rtest(glp_prob *P, int len, const int ind[], -* const double val[], int dir, double eps); -* -* DESCRIPTION -* -* The routine glp_prim_rtest performs the primal ratio test using an -* explicitly specified column of the simplex table. -* -* The current basic solution associated with the LP problem object -* must be primal feasible. -* -* The explicitly specified column of the simplex table shows how the -* basic variables xB depend on some non-basic variable x (which is not -* necessarily presented in the problem object): -* -* xB[1] = ... + alfa[1] * x + ... -* xB[2] = ... + alfa[2] * x + ... (*) -* . . . . . . . . -* xB[m] = ... + alfa[m] * x + ... -* -* The column (*) is specifed on entry to the routine using the sparse -* format. Ordinal numbers of basic variables xB[i] should be placed in -* locations ind[1], ..., ind[len], where ordinal number 1 to m denote -* auxiliary variables, and ordinal numbers m+1 to m+n denote structural -* variables. The corresponding non-zero coefficients alfa[i] should be -* placed in locations val[1], ..., val[len]. The arrays ind and val are -* not changed on exit. -* -* The parameter dir specifies direction in which the variable x changes -* on entering the basis: +1 means increasing, -1 means decreasing. -* -* The parameter eps is an absolute tolerance (small positive number) -* used by the routine to skip small alfa[j] of the row (*). -* -* The routine determines which basic variable (among specified in -* ind[1], ..., ind[len]) should leave the basis in order to keep primal -* feasibility. -* -* RETURNS -* -* The routine glp_prim_rtest returns the index piv in the arrays ind -* and val corresponding to the pivot element chosen, 1 <= piv <= len. -* If the adjacent basic solution is primal unbounded and therefore the -* choice cannot be made, the routine returns zero. -* -* COMMENTS -* -* If the non-basic variable x is presented in the LP problem object, -* the column (*) can be computed with the routine glp_eval_tab_col; -* otherwise it can be computed with the routine glp_transform_col. */ - -int glp_prim_rtest(glp_prob *P, int len, const int ind[], - const double val[], int dir, double eps) -{ int k, m, n, piv, t, type, stat; - double alfa, big, beta, lb, ub, temp, teta; - if (glp_get_prim_stat(P) != GLP_FEAS) - xerror("glp_prim_rtest: basic solution is not primal feasible " - "\n"); - if (!(dir == +1 || dir == -1)) - xerror("glp_prim_rtest: dir = %d; invalid parameter\n", dir); - if (!(0.0 < eps && eps < 1.0)) - xerror("glp_prim_rtest: eps = %g; invalid parameter\n", eps); - m = glp_get_num_rows(P); - n = glp_get_num_cols(P); - /* initial settings */ - piv = 0, teta = DBL_MAX, big = 0.0; - /* walk through the entries of the specified column */ - for (t = 1; t <= len; t++) - { /* get the ordinal number of basic variable */ - k = ind[t]; - if (!(1 <= k && k <= m+n)) - xerror("glp_prim_rtest: ind[%d] = %d; variable number out o" - "f range\n", t, k); - /* determine type, bounds, status and primal value of basic - variable xB[i] = x[k] in the current basic solution */ - if (k <= m) - { type = glp_get_row_type(P, k); - lb = glp_get_row_lb(P, k); - ub = glp_get_row_ub(P, k); - stat = glp_get_row_stat(P, k); - beta = glp_get_row_prim(P, k); - } - else - { type = glp_get_col_type(P, k-m); - lb = glp_get_col_lb(P, k-m); - ub = glp_get_col_ub(P, k-m); - stat = glp_get_col_stat(P, k-m); - beta = glp_get_col_prim(P, k-m); - } - if (stat != GLP_BS) - xerror("glp_prim_rtest: ind[%d] = %d; non-basic variable no" - "t allowed\n", t, k); - /* determine influence coefficient at basic variable xB[i] - in the explicitly specified column and turn to the case of - increasing the variable x in order to simplify the program - logic */ - alfa = (dir > 0 ? + val[t] : - val[t]); - /* analyze main cases */ - if (type == GLP_FR) - { /* xB[i] is free variable */ - continue; - } - else if (type == GLP_LO) -lo: { /* xB[i] has an lower bound */ - if (alfa > - eps) continue; - temp = (lb - beta) / alfa; - } - else if (type == GLP_UP) -up: { /* xB[i] has an upper bound */ - if (alfa < + eps) continue; - temp = (ub - beta) / alfa; - } - else if (type == GLP_DB) - { /* xB[i] has both lower and upper bounds */ - if (alfa < 0.0) goto lo; else goto up; - } - else if (type == GLP_FX) - { /* xB[i] is fixed variable */ - if (- eps < alfa && alfa < + eps) continue; - temp = 0.0; - } - else - xassert(type != type); - /* if the value of the variable xB[i] violates its lower or - upper bound (slightly, because the current basis is assumed - to be primal feasible), temp is negative; we can think this - happens due to round-off errors and the value is exactly on - the bound; this allows replacing temp by zero */ - if (temp < 0.0) temp = 0.0; - /* apply the minimal ratio test */ - if (teta > temp || teta == temp && big < fabs(alfa)) - piv = t, teta = temp, big = fabs(alfa); - } - /* return index of the pivot element chosen */ - return piv; -} - -/*********************************************************************** -* NAME -* -* glp_dual_rtest - perform dual ratio test -* -* SYNOPSIS -* -* int glp_dual_rtest(glp_prob *P, int len, const int ind[], -* const double val[], int dir, double eps); -* -* DESCRIPTION -* -* The routine glp_dual_rtest performs the dual ratio test using an -* explicitly specified row of the simplex table. -* -* The current basic solution associated with the LP problem object -* must be dual feasible. -* -* The explicitly specified row of the simplex table is a linear form -* that shows how some basic variable x (which is not necessarily -* presented in the problem object) depends on non-basic variables xN: -* -* x = alfa[1] * xN[1] + alfa[2] * xN[2] + ... + alfa[n] * xN[n]. (*) -* -* The row (*) is specified on entry to the routine using the sparse -* format. Ordinal numbers of non-basic variables xN[j] should be placed -* in locations ind[1], ..., ind[len], where ordinal numbers 1 to m -* denote auxiliary variables, and ordinal numbers m+1 to m+n denote -* structural variables. The corresponding non-zero coefficients alfa[j] -* should be placed in locations val[1], ..., val[len]. The arrays ind -* and val are not changed on exit. -* -* The parameter dir specifies direction in which the variable x changes -* on leaving the basis: +1 means that x goes to its lower bound, and -1 -* means that x goes to its upper bound. -* -* The parameter eps is an absolute tolerance (small positive number) -* used by the routine to skip small alfa[j] of the row (*). -* -* The routine determines which non-basic variable (among specified in -* ind[1], ..., ind[len]) should enter the basis in order to keep dual -* feasibility. -* -* RETURNS -* -* The routine glp_dual_rtest returns the index piv in the arrays ind -* and val corresponding to the pivot element chosen, 1 <= piv <= len. -* If the adjacent basic solution is dual unbounded and therefore the -* choice cannot be made, the routine returns zero. -* -* COMMENTS -* -* If the basic variable x is presented in the LP problem object, the -* row (*) can be computed with the routine glp_eval_tab_row; otherwise -* it can be computed with the routine glp_transform_row. */ - -int glp_dual_rtest(glp_prob *P, int len, const int ind[], - const double val[], int dir, double eps) -{ int k, m, n, piv, t, stat; - double alfa, big, cost, obj, temp, teta; - if (glp_get_dual_stat(P) != GLP_FEAS) - xerror("glp_dual_rtest: basic solution is not dual feasible\n") - ; - if (!(dir == +1 || dir == -1)) - xerror("glp_dual_rtest: dir = %d; invalid parameter\n", dir); - if (!(0.0 < eps && eps < 1.0)) - xerror("glp_dual_rtest: eps = %g; invalid parameter\n", eps); - m = glp_get_num_rows(P); - n = glp_get_num_cols(P); - /* take into account optimization direction */ - obj = (glp_get_obj_dir(P) == GLP_MIN ? +1.0 : -1.0); - /* initial settings */ - piv = 0, teta = DBL_MAX, big = 0.0; - /* walk through the entries of the specified row */ - for (t = 1; t <= len; t++) - { /* get ordinal number of non-basic variable */ - k = ind[t]; - if (!(1 <= k && k <= m+n)) - xerror("glp_dual_rtest: ind[%d] = %d; variable number out o" - "f range\n", t, k); - /* determine status and reduced cost of non-basic variable - x[k] = xN[j] in the current basic solution */ - if (k <= m) - { stat = glp_get_row_stat(P, k); - cost = glp_get_row_dual(P, k); - } - else - { stat = glp_get_col_stat(P, k-m); - cost = glp_get_col_dual(P, k-m); - } - if (stat == GLP_BS) - xerror("glp_dual_rtest: ind[%d] = %d; basic variable not al" - "lowed\n", t, k); - /* determine influence coefficient at non-basic variable xN[j] - in the explicitly specified row and turn to the case of - increasing the variable x in order to simplify the program - logic */ - alfa = (dir > 0 ? + val[t] : - val[t]); - /* analyze main cases */ - if (stat == GLP_NL) - { /* xN[j] is on its lower bound */ - if (alfa < + eps) continue; - temp = (obj * cost) / alfa; - } - else if (stat == GLP_NU) - { /* xN[j] is on its upper bound */ - if (alfa > - eps) continue; - temp = (obj * cost) / alfa; - } - else if (stat == GLP_NF) - { /* xN[j] is non-basic free variable */ - if (- eps < alfa && alfa < + eps) continue; - temp = 0.0; - } - else if (stat == GLP_NS) - { /* xN[j] is non-basic fixed variable */ - continue; - } - else - xassert(stat != stat); - /* if the reduced cost of the variable xN[j] violates its zero - bound (slightly, because the current basis is assumed to be - dual feasible), temp is negative; we can think this happens - due to round-off errors and the reduced cost is exact zero; - this allows replacing temp by zero */ - if (temp < 0.0) temp = 0.0; - /* apply the minimal ratio test */ - if (teta > temp || teta == temp && big < fabs(alfa)) - piv = t, teta = temp, big = fabs(alfa); - } - /* return index of the pivot element chosen */ - return piv; -} - -/*********************************************************************** -* NAME -* -* glp_analyze_row - simulate one iteration of dual simplex method -* -* SYNOPSIS -* -* int glp_analyze_row(glp_prob *P, int len, const int ind[], -* const double val[], int type, double rhs, double eps, int *piv, -* double *x, double *dx, double *y, double *dy, double *dz); -* -* DESCRIPTION -* -* Let the current basis be optimal or dual feasible, and there be -* specified a row (constraint), which is violated by the current basic -* solution. The routine glp_analyze_row simulates one iteration of the -* dual simplex method to determine some information on the adjacent -* basis (see below), where the specified row becomes active constraint -* (i.e. its auxiliary variable becomes non-basic). -* -* The current basic solution associated with the problem object passed -* to the routine must be dual feasible, and its primal components must -* be defined. -* -* The row to be analyzed must be previously transformed either with -* the routine glp_eval_tab_row (if the row is in the problem object) -* or with the routine glp_transform_row (if the row is external, i.e. -* not in the problem object). This is needed to express the row only -* through (auxiliary and structural) variables, which are non-basic in -* the current basis: -* -* y = alfa[1] * xN[1] + alfa[2] * xN[2] + ... + alfa[n] * xN[n], -* -* where y is an auxiliary variable of the row, alfa[j] is an influence -* coefficient, xN[j] is a non-basic variable. -* -* The row is passed to the routine in sparse format. Ordinal numbers -* of non-basic variables are stored in locations ind[1], ..., ind[len], -* where numbers 1 to m denote auxiliary variables while numbers m+1 to -* m+n denote structural variables. Corresponding non-zero coefficients -* alfa[j] are stored in locations val[1], ..., val[len]. The arrays -* ind and val are ot changed on exit. -* -* The parameters type and rhs specify the row type and its right-hand -* side as follows: -* -* type = GLP_LO: y = sum alfa[j] * xN[j] >= rhs -* -* type = GLP_UP: y = sum alfa[j] * xN[j] <= rhs -* -* The parameter eps is an absolute tolerance (small positive number) -* used by the routine to skip small coefficients alfa[j] on performing -* the dual ratio test. -* -* If the operation was successful, the routine stores the following -* information to corresponding location (if some parameter is NULL, -* its value is not stored): -* -* piv index in the array ind and val, 1 <= piv <= len, determining -* the non-basic variable, which would enter the adjacent basis; -* -* x value of the non-basic variable in the current basis; -* -* dx difference between values of the non-basic variable in the -* adjacent and current bases, dx = x.new - x.old; -* -* y value of the row (i.e. of its auxiliary variable) in the -* current basis; -* -* dy difference between values of the row in the adjacent and -* current bases, dy = y.new - y.old; -* -* dz difference between values of the objective function in the -* adjacent and current bases, dz = z.new - z.old. Note that in -* case of minimization dz >= 0, and in case of maximization -* dz <= 0, i.e. in the adjacent basis the objective function -* always gets worse (degrades). */ - -int _glp_analyze_row(glp_prob *P, int len, const int ind[], - const double val[], int type, double rhs, double eps, int *_piv, - double *_x, double *_dx, double *_y, double *_dy, double *_dz) -{ int t, k, dir, piv, ret = 0; - double x, dx, y, dy, dz; - if (P->pbs_stat == GLP_UNDEF) - xerror("glp_analyze_row: primal basic solution components are " - "undefined\n"); - if (P->dbs_stat != GLP_FEAS) - xerror("glp_analyze_row: basic solution is not dual feasible\n" - ); - /* compute the row value y = sum alfa[j] * xN[j] in the current - basis */ - if (!(0 <= len && len <= P->n)) - xerror("glp_analyze_row: len = %d; invalid row length\n", len); - y = 0.0; - for (t = 1; t <= len; t++) - { /* determine value of x[k] = xN[j] in the current basis */ - k = ind[t]; - if (!(1 <= k && k <= P->m+P->n)) - xerror("glp_analyze_row: ind[%d] = %d; row/column index out" - " of range\n", t, k); - if (k <= P->m) - { /* x[k] is auxiliary variable */ - if (P->row[k]->stat == GLP_BS) - xerror("glp_analyze_row: ind[%d] = %d; basic auxiliary v" - "ariable is not allowed\n", t, k); - x = P->row[k]->prim; - } - else - { /* x[k] is structural variable */ - if (P->col[k-P->m]->stat == GLP_BS) - xerror("glp_analyze_row: ind[%d] = %d; basic structural " - "variable is not allowed\n", t, k); - x = P->col[k-P->m]->prim; - } - y += val[t] * x; - } - /* check if the row is primal infeasible in the current basis, - i.e. the constraint is violated at the current point */ - if (type == GLP_LO) - { if (y >= rhs) - { /* the constraint is not violated */ - ret = 1; - goto done; - } - /* in the adjacent basis y goes to its lower bound */ - dir = +1; - } - else if (type == GLP_UP) - { if (y <= rhs) - { /* the constraint is not violated */ - ret = 1; - goto done; - } - /* in the adjacent basis y goes to its upper bound */ - dir = -1; - } - else - xerror("glp_analyze_row: type = %d; invalid parameter\n", - type); - /* compute dy = y.new - y.old */ - dy = rhs - y; - /* perform dual ratio test to determine which non-basic variable - should enter the adjacent basis to keep it dual feasible */ - piv = glp_dual_rtest(P, len, ind, val, dir, eps); - if (piv == 0) - { /* no dual feasible adjacent basis exists */ - ret = 2; - goto done; - } - /* non-basic variable x[k] = xN[j] should enter the basis */ - k = ind[piv]; - xassert(1 <= k && k <= P->m+P->n); - /* determine its value in the current basis */ - if (k <= P->m) - x = P->row[k]->prim; - else - x = P->col[k-P->m]->prim; - /* compute dx = x.new - x.old = dy / alfa[j] */ - xassert(val[piv] != 0.0); - dx = dy / val[piv]; - /* compute dz = z.new - z.old = d[j] * dx, where d[j] is reduced - cost of xN[j] in the current basis */ - if (k <= P->m) - dz = P->row[k]->dual * dx; - else - dz = P->col[k-P->m]->dual * dx; - /* store the analysis results */ - if (_piv != NULL) *_piv = piv; - if (_x != NULL) *_x = x; - if (_dx != NULL) *_dx = dx; - if (_y != NULL) *_y = y; - if (_dy != NULL) *_dy = dy; - if (_dz != NULL) *_dz = dz; -done: return ret; -} - -#if 0 -int main(void) -{ /* example program for the routine glp_analyze_row */ - glp_prob *P; - glp_smcp parm; - int i, k, len, piv, ret, ind[1+100]; - double rhs, x, dx, y, dy, dz, val[1+100]; - P = glp_create_prob(); - /* read plan.mps (see glpk/examples) */ - ret = glp_read_mps(P, GLP_MPS_DECK, NULL, "plan.mps"); - glp_assert(ret == 0); - /* and solve it to optimality */ - ret = glp_simplex(P, NULL); - glp_assert(ret == 0); - glp_assert(glp_get_status(P) == GLP_OPT); - /* the optimal objective value is 296.217 */ - /* we would like to know what happens if we would add a new row - (constraint) to plan.mps: - .01 * bin1 + .01 * bin2 + .02 * bin4 + .02 * bin5 <= 12 */ - /* first, we specify this new row */ - glp_create_index(P); - len = 0; - ind[++len] = glp_find_col(P, "BIN1"), val[len] = .01; - ind[++len] = glp_find_col(P, "BIN2"), val[len] = .01; - ind[++len] = glp_find_col(P, "BIN4"), val[len] = .02; - ind[++len] = glp_find_col(P, "BIN5"), val[len] = .02; - rhs = 12; - /* then we can compute value of the row (i.e. of its auxiliary - variable) in the current basis to see if the constraint is - violated */ - y = 0.0; - for (k = 1; k <= len; k++) - y += val[k] * glp_get_col_prim(P, ind[k]); - glp_printf("y = %g\n", y); - /* this prints y = 15.1372, so the constraint is violated, since - we require that y <= rhs = 12 */ - /* now we transform the row to express it only through non-basic - (auxiliary and artificial) variables */ - len = glp_transform_row(P, len, ind, val); - /* finally, we simulate one step of the dual simplex method to - obtain necessary information for the adjacent basis */ - ret = _glp_analyze_row(P, len, ind, val, GLP_UP, rhs, 1e-9, &piv, - &x, &dx, &y, &dy, &dz); - glp_assert(ret == 0); - glp_printf("k = %d, x = %g; dx = %g; y = %g; dy = %g; dz = %g\n", - ind[piv], x, dx, y, dy, dz); - /* this prints dz = 5.64418 and means that in the adjacent basis - the objective function would be 296.217 + 5.64418 = 301.861 */ - /* now we actually include the row into the problem object; note - that the arrays ind and val are clobbered, so we need to build - them once again */ - len = 0; - ind[++len] = glp_find_col(P, "BIN1"), val[len] = .01; - ind[++len] = glp_find_col(P, "BIN2"), val[len] = .01; - ind[++len] = glp_find_col(P, "BIN4"), val[len] = .02; - ind[++len] = glp_find_col(P, "BIN5"), val[len] = .02; - rhs = 12; - i = glp_add_rows(P, 1); - glp_set_row_bnds(P, i, GLP_UP, 0, rhs); - glp_set_mat_row(P, i, len, ind, val); - /* and perform one dual simplex iteration */ - glp_init_smcp(&parm); - parm.meth = GLP_DUAL; - parm.it_lim = 1; - glp_simplex(P, &parm); - /* the current objective value is 301.861 */ - return 0; -} -#endif - -/*********************************************************************** -* NAME -* -* glp_analyze_bound - analyze active bound of non-basic variable -* -* SYNOPSIS -* -* void glp_analyze_bound(glp_prob *P, int k, double *limit1, int *var1, -* double *limit2, int *var2); -* -* DESCRIPTION -* -* The routine glp_analyze_bound analyzes the effect of varying the -* active bound of specified non-basic variable. -* -* The non-basic variable is specified by the parameter k, where -* 1 <= k <= m means auxiliary variable of corresponding row while -* m+1 <= k <= m+n means structural variable (column). -* -* Note that the current basic solution must be optimal, and the basis -* factorization must exist. -* -* Results of the analysis have the following meaning. -* -* value1 is the minimal value of the active bound, at which the basis -* still remains primal feasible and thus optimal. -DBL_MAX means that -* the active bound has no lower limit. -* -* var1 is the ordinal number of an auxiliary (1 to m) or structural -* (m+1 to n) basic variable, which reaches its bound first and thereby -* limits further decreasing the active bound being analyzed. -* if value1 = -DBL_MAX, var1 is set to 0. -* -* value2 is the maximal value of the active bound, at which the basis -* still remains primal feasible and thus optimal. +DBL_MAX means that -* the active bound has no upper limit. -* -* var2 is the ordinal number of an auxiliary (1 to m) or structural -* (m+1 to n) basic variable, which reaches its bound first and thereby -* limits further increasing the active bound being analyzed. -* if value2 = +DBL_MAX, var2 is set to 0. */ - -void glp_analyze_bound(glp_prob *P, int k, double *value1, int *var1, - double *value2, int *var2) -{ GLPROW *row; - GLPCOL *col; - int m, n, stat, kase, p, len, piv, *ind; - double x, new_x, ll, uu, xx, delta, *val; - /* sanity checks */ - if (P == NULL || P->magic != GLP_PROB_MAGIC) - xerror("glp_analyze_bound: P = %p; invalid problem object\n", - P); - m = P->m, n = P->n; - if (!(P->pbs_stat == GLP_FEAS && P->dbs_stat == GLP_FEAS)) - xerror("glp_analyze_bound: optimal basic solution required\n"); - if (!(m == 0 || P->valid)) - xerror("glp_analyze_bound: basis factorization required\n"); - if (!(1 <= k && k <= m+n)) - xerror("glp_analyze_bound: k = %d; variable number out of rang" - "e\n", k); - /* retrieve information about the specified non-basic variable - x[k] whose active bound is to be analyzed */ - if (k <= m) - { row = P->row[k]; - stat = row->stat; - x = row->prim; - } - else - { col = P->col[k-m]; - stat = col->stat; - x = col->prim; - } - if (stat == GLP_BS) - xerror("glp_analyze_bound: k = %d; basic variable not allowed " - "\n", k); - /* allocate working arrays */ - ind = xcalloc(1+m, sizeof(int)); - val = xcalloc(1+m, sizeof(double)); - /* compute column of the simplex table corresponding to the - non-basic variable x[k] */ - len = glp_eval_tab_col(P, k, ind, val); - xassert(0 <= len && len <= m); - /* perform analysis */ - for (kase = -1; kase <= +1; kase += 2) - { /* kase < 0 means active bound of x[k] is decreasing; - kase > 0 means active bound of x[k] is increasing */ - /* use the primal ratio test to determine some basic variable - x[p] which reaches its bound first */ - piv = glp_prim_rtest(P, len, ind, val, kase, 1e-9); - if (piv == 0) - { /* nothing limits changing the active bound of x[k] */ - p = 0; - new_x = (kase < 0 ? -DBL_MAX : +DBL_MAX); - goto store; - } - /* basic variable x[p] limits changing the active bound of - x[k]; determine its value in the current basis */ - xassert(1 <= piv && piv <= len); - p = ind[piv]; - if (p <= m) - { row = P->row[p]; - ll = glp_get_row_lb(P, row->i); - uu = glp_get_row_ub(P, row->i); - stat = row->stat; - xx = row->prim; - } - else - { col = P->col[p-m]; - ll = glp_get_col_lb(P, col->j); - uu = glp_get_col_ub(P, col->j); - stat = col->stat; - xx = col->prim; - } - xassert(stat == GLP_BS); - /* determine delta x[p] = bound of x[p] - value of x[p] */ - if (kase < 0 && val[piv] > 0.0 || - kase > 0 && val[piv] < 0.0) - { /* delta x[p] < 0, so x[p] goes toward its lower bound */ - xassert(ll != -DBL_MAX); - delta = ll - xx; - } - else - { /* delta x[p] > 0, so x[p] goes toward its upper bound */ - xassert(uu != +DBL_MAX); - delta = uu - xx; - } - /* delta x[p] = alfa[p,k] * delta x[k], so new x[k] = x[k] + - delta x[k] = x[k] + delta x[p] / alfa[p,k] is the value of - x[k] in the adjacent basis */ - xassert(val[piv] != 0.0); - new_x = x + delta / val[piv]; -store: /* store analysis results */ - if (kase < 0) - { if (value1 != NULL) *value1 = new_x; - if (var1 != NULL) *var1 = p; - } - else - { if (value2 != NULL) *value2 = new_x; - if (var2 != NULL) *var2 = p; - } - } - /* free working arrays */ - xfree(ind); - xfree(val); - return; -} - -/*********************************************************************** -* NAME -* -* glp_analyze_coef - analyze objective coefficient at basic variable -* -* SYNOPSIS -* -* void glp_analyze_coef(glp_prob *P, int k, double *coef1, int *var1, -* double *value1, double *coef2, int *var2, double *value2); -* -* DESCRIPTION -* -* The routine glp_analyze_coef analyzes the effect of varying the -* objective coefficient at specified basic variable. -* -* The basic variable is specified by the parameter k, where -* 1 <= k <= m means auxiliary variable of corresponding row while -* m+1 <= k <= m+n means structural variable (column). -* -* Note that the current basic solution must be optimal, and the basis -* factorization must exist. -* -* Results of the analysis have the following meaning. -* -* coef1 is the minimal value of the objective coefficient, at which -* the basis still remains dual feasible and thus optimal. -DBL_MAX -* means that the objective coefficient has no lower limit. -* -* var1 is the ordinal number of an auxiliary (1 to m) or structural -* (m+1 to n) non-basic variable, whose reduced cost reaches its zero -* bound first and thereby limits further decreasing the objective -* coefficient being analyzed. If coef1 = -DBL_MAX, var1 is set to 0. -* -* value1 is value of the basic variable being analyzed in an adjacent -* basis, which is defined as follows. Let the objective coefficient -* reaches its minimal value (coef1) and continues decreasing. Then the -* reduced cost of the limiting non-basic variable (var1) becomes dual -* infeasible and the current basis becomes non-optimal that forces the -* limiting non-basic variable to enter the basis replacing there some -* basic variable that leaves the basis to keep primal feasibility. -* Should note that on determining the adjacent basis current bounds -* of the basic variable being analyzed are ignored as if it were free -* (unbounded) variable, so it cannot leave the basis. It may happen -* that no dual feasible adjacent basis exists, in which case value1 is -* set to -DBL_MAX or +DBL_MAX. -* -* coef2 is the maximal value of the objective coefficient, at which -* the basis still remains dual feasible and thus optimal. +DBL_MAX -* means that the objective coefficient has no upper limit. -* -* var2 is the ordinal number of an auxiliary (1 to m) or structural -* (m+1 to n) non-basic variable, whose reduced cost reaches its zero -* bound first and thereby limits further increasing the objective -* coefficient being analyzed. If coef2 = +DBL_MAX, var2 is set to 0. -* -* value2 is value of the basic variable being analyzed in an adjacent -* basis, which is defined exactly in the same way as value1 above with -* exception that now the objective coefficient is increasing. */ - -void glp_analyze_coef(glp_prob *P, int k, double *coef1, int *var1, - double *value1, double *coef2, int *var2, double *value2) -{ GLPROW *row; GLPCOL *col; - int m, n, type, stat, kase, p, q, dir, clen, cpiv, rlen, rpiv, - *cind, *rind; - double lb, ub, coef, x, lim_coef, new_x, d, delta, ll, uu, xx, - *rval, *cval; - /* sanity checks */ - if (P == NULL || P->magic != GLP_PROB_MAGIC) - xerror("glp_analyze_coef: P = %p; invalid problem object\n", - P); - m = P->m, n = P->n; - if (!(P->pbs_stat == GLP_FEAS && P->dbs_stat == GLP_FEAS)) - xerror("glp_analyze_coef: optimal basic solution required\n"); - if (!(m == 0 || P->valid)) - xerror("glp_analyze_coef: basis factorization required\n"); - if (!(1 <= k && k <= m+n)) - xerror("glp_analyze_coef: k = %d; variable number out of range" - "\n", k); - /* retrieve information about the specified basic variable x[k] - whose objective coefficient c[k] is to be analyzed */ - if (k <= m) - { row = P->row[k]; - type = row->type; - lb = row->lb; - ub = row->ub; - coef = 0.0; - stat = row->stat; - x = row->prim; - } - else - { col = P->col[k-m]; - type = col->type; - lb = col->lb; - ub = col->ub; - coef = col->coef; - stat = col->stat; - x = col->prim; - } - if (stat != GLP_BS) - xerror("glp_analyze_coef: k = %d; non-basic variable not allow" - "ed\n", k); - /* allocate working arrays */ - cind = xcalloc(1+m, sizeof(int)); - cval = xcalloc(1+m, sizeof(double)); - rind = xcalloc(1+n, sizeof(int)); - rval = xcalloc(1+n, sizeof(double)); - /* compute row of the simplex table corresponding to the basic - variable x[k] */ - rlen = glp_eval_tab_row(P, k, rind, rval); - xassert(0 <= rlen && rlen <= n); - /* perform analysis */ - for (kase = -1; kase <= +1; kase += 2) - { /* kase < 0 means objective coefficient c[k] is decreasing; - kase > 0 means objective coefficient c[k] is increasing */ - /* note that decreasing c[k] is equivalent to increasing dual - variable lambda[k] and vice versa; we need to correctly set - the dir flag as required by the routine glp_dual_rtest */ - if (P->dir == GLP_MIN) - dir = - kase; - else if (P->dir == GLP_MAX) - dir = + kase; - else - xassert(P != P); - /* use the dual ratio test to determine non-basic variable - x[q] whose reduced cost d[q] reaches zero bound first */ - rpiv = glp_dual_rtest(P, rlen, rind, rval, dir, 1e-9); - if (rpiv == 0) - { /* nothing limits changing c[k] */ - lim_coef = (kase < 0 ? -DBL_MAX : +DBL_MAX); - q = 0; - /* x[k] keeps its current value */ - new_x = x; - goto store; - } - /* non-basic variable x[q] limits changing coefficient c[k]; - determine its status and reduced cost d[k] in the current - basis */ - xassert(1 <= rpiv && rpiv <= rlen); - q = rind[rpiv]; - xassert(1 <= q && q <= m+n); - if (q <= m) - { row = P->row[q]; - stat = row->stat; - d = row->dual; - } - else - { col = P->col[q-m]; - stat = col->stat; - d = col->dual; - } - /* note that delta d[q] = new d[q] - d[q] = - d[q], because - new d[q] = 0; delta d[q] = alfa[k,q] * delta c[k], so - delta c[k] = delta d[q] / alfa[k,q] = - d[q] / alfa[k,q] */ - xassert(rval[rpiv] != 0.0); - delta = - d / rval[rpiv]; - /* compute new c[k] = c[k] + delta c[k], which is the limiting - value of the objective coefficient c[k] */ - lim_coef = coef + delta; - /* let c[k] continue decreasing/increasing that makes d[q] - dual infeasible and forces x[q] to enter the basis; - to perform the primal ratio test we need to know in which - direction x[q] changes on entering the basis; we determine - that analyzing the sign of delta d[q] (see above), since - d[q] may be close to zero having wrong sign */ - /* let, for simplicity, the problem is minimization */ - if (kase < 0 && rval[rpiv] > 0.0 || - kase > 0 && rval[rpiv] < 0.0) - { /* delta d[q] < 0, so d[q] being non-negative will become - negative, so x[q] will increase */ - dir = +1; - } - else - { /* delta d[q] > 0, so d[q] being non-positive will become - positive, so x[q] will decrease */ - dir = -1; - } - /* if the problem is maximization, correct the direction */ - if (P->dir == GLP_MAX) dir = - dir; - /* check that we didn't make a silly mistake */ - if (dir > 0) - xassert(stat == GLP_NL || stat == GLP_NF); - else - xassert(stat == GLP_NU || stat == GLP_NF); - /* compute column of the simplex table corresponding to the - non-basic variable x[q] */ - clen = glp_eval_tab_col(P, q, cind, cval); - /* make x[k] temporarily free (unbounded) */ - if (k <= m) - { row = P->row[k]; - row->type = GLP_FR; - row->lb = row->ub = 0.0; - } - else - { col = P->col[k-m]; - col->type = GLP_FR; - col->lb = col->ub = 0.0; - } - /* use the primal ratio test to determine some basic variable - which leaves the basis */ - cpiv = glp_prim_rtest(P, clen, cind, cval, dir, 1e-9); - /* restore original bounds of the basic variable x[k] */ - if (k <= m) - { row = P->row[k]; - row->type = type; - row->lb = lb, row->ub = ub; - } - else - { col = P->col[k-m]; - col->type = type; - col->lb = lb, col->ub = ub; - } - if (cpiv == 0) - { /* non-basic variable x[q] can change unlimitedly */ - if (dir < 0 && rval[rpiv] > 0.0 || - dir > 0 && rval[rpiv] < 0.0) - { /* delta x[k] = alfa[k,q] * delta x[q] < 0 */ - new_x = -DBL_MAX; - } - else - { /* delta x[k] = alfa[k,q] * delta x[q] > 0 */ - new_x = +DBL_MAX; - } - goto store; - } - /* some basic variable x[p] limits changing non-basic variable - x[q] in the adjacent basis */ - xassert(1 <= cpiv && cpiv <= clen); - p = cind[cpiv]; - xassert(1 <= p && p <= m+n); - xassert(p != k); - if (p <= m) - { row = P->row[p]; - xassert(row->stat == GLP_BS); - ll = glp_get_row_lb(P, row->i); - uu = glp_get_row_ub(P, row->i); - xx = row->prim; - } - else - { col = P->col[p-m]; - xassert(col->stat == GLP_BS); - ll = glp_get_col_lb(P, col->j); - uu = glp_get_col_ub(P, col->j); - xx = col->prim; - } - /* determine delta x[p] = new x[p] - x[p] */ - if (dir < 0 && cval[cpiv] > 0.0 || - dir > 0 && cval[cpiv] < 0.0) - { /* delta x[p] < 0, so x[p] goes toward its lower bound */ - xassert(ll != -DBL_MAX); - delta = ll - xx; - } - else - { /* delta x[p] > 0, so x[p] goes toward its upper bound */ - xassert(uu != +DBL_MAX); - delta = uu - xx; - } - /* compute new x[k] = x[k] + alfa[k,q] * delta x[q], where - delta x[q] = delta x[p] / alfa[p,q] */ - xassert(cval[cpiv] != 0.0); - new_x = x + (rval[rpiv] / cval[cpiv]) * delta; -store: /* store analysis results */ - if (kase < 0) - { if (coef1 != NULL) *coef1 = lim_coef; - if (var1 != NULL) *var1 = q; - if (value1 != NULL) *value1 = new_x; - } - else - { if (coef2 != NULL) *coef2 = lim_coef; - if (var2 != NULL) *var2 = q; - if (value2 != NULL) *value2 = new_x; - } - } - /* free working arrays */ - xfree(cind); - xfree(cval); - xfree(rind); - xfree(rval); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi13.c b/resources/3rdparty/glpk-4.53/src/glpapi13.c deleted file mode 100644 index a4ad10b66..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi13.c +++ /dev/null @@ -1,706 +0,0 @@ -/* glpapi13.c (branch-and-bound interface routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpios.h" - -/*********************************************************************** -* NAME -* -* glp_ios_reason - determine reason for calling the callback routine -* -* SYNOPSIS -* -* glp_ios_reason(glp_tree *tree); -* -* RETURNS -* -* The routine glp_ios_reason returns a code, which indicates why the -* user-defined callback routine is being called. */ - -int glp_ios_reason(glp_tree *tree) -{ return - tree->reason; -} - -/*********************************************************************** -* NAME -* -* glp_ios_get_prob - access the problem object -* -* SYNOPSIS -* -* glp_prob *glp_ios_get_prob(glp_tree *tree); -* -* DESCRIPTION -* -* The routine glp_ios_get_prob can be called from the user-defined -* callback routine to access the problem object, which is used by the -* MIP solver. It is the original problem object passed to the routine -* glp_intopt if the MIP presolver is not used; otherwise it is an -* internal problem object built by the presolver. If the current -* subproblem exists, LP segment of the problem object corresponds to -* its LP relaxation. -* -* RETURNS -* -* The routine glp_ios_get_prob returns a pointer to the problem object -* used by the MIP solver. */ - -glp_prob *glp_ios_get_prob(glp_tree *tree) -{ return - tree->mip; -} - -/*********************************************************************** -* NAME -* -* glp_ios_tree_size - determine size of the branch-and-bound tree -* -* SYNOPSIS -* -* void glp_ios_tree_size(glp_tree *tree, int *a_cnt, int *n_cnt, -* int *t_cnt); -* -* DESCRIPTION -* -* The routine glp_ios_tree_size stores the following three counts which -* characterize the current size of the branch-and-bound tree: -* -* a_cnt is the current number of active nodes, i.e. the current size of -* the active list; -* -* n_cnt is the current number of all (active and inactive) nodes; -* -* t_cnt is the total number of nodes including those which have been -* already removed from the tree. This count is increased whenever -* a new node appears in the tree and never decreased. -* -* If some of the parameters a_cnt, n_cnt, t_cnt is a null pointer, the -* corresponding count is not stored. */ - -void glp_ios_tree_size(glp_tree *tree, int *a_cnt, int *n_cnt, - int *t_cnt) -{ if (a_cnt != NULL) *a_cnt = tree->a_cnt; - if (n_cnt != NULL) *n_cnt = tree->n_cnt; - if (t_cnt != NULL) *t_cnt = tree->t_cnt; - return; -} - -/*********************************************************************** -* NAME -* -* glp_ios_curr_node - determine current active subproblem -* -* SYNOPSIS -* -* int glp_ios_curr_node(glp_tree *tree); -* -* RETURNS -* -* The routine glp_ios_curr_node returns the reference number of the -* current active subproblem. However, if the current subproblem does -* not exist, the routine returns zero. */ - -int glp_ios_curr_node(glp_tree *tree) -{ IOSNPD *node; - /* obtain pointer to the current subproblem */ - node = tree->curr; - /* return its reference number */ - return node == NULL ? 0 : node->p; -} - -/*********************************************************************** -* NAME -* -* glp_ios_next_node - determine next active subproblem -* -* SYNOPSIS -* -* int glp_ios_next_node(glp_tree *tree, int p); -* -* RETURNS -* -* If the parameter p is zero, the routine glp_ios_next_node returns -* the reference number of the first active subproblem. However, if the -* tree is empty, zero is returned. -* -* If the parameter p is not zero, it must specify the reference number -* of some active subproblem, in which case the routine returns the -* reference number of the next active subproblem. However, if there is -* no next active subproblem in the list, zero is returned. -* -* All subproblems in the active list are ordered chronologically, i.e. -* subproblem A precedes subproblem B if A was created before B. */ - -int glp_ios_next_node(glp_tree *tree, int p) -{ IOSNPD *node; - if (p == 0) - { /* obtain pointer to the first active subproblem */ - node = tree->head; - } - else - { /* obtain pointer to the specified subproblem */ - if (!(1 <= p && p <= tree->nslots)) -err: xerror("glp_ios_next_node: p = %d; invalid subproblem refer" - "ence number\n", p); - node = tree->slot[p].node; - if (node == NULL) goto err; - /* the specified subproblem must be active */ - if (node->count != 0) - xerror("glp_ios_next_node: p = %d; subproblem not in the ac" - "tive list\n", p); - /* obtain pointer to the next active subproblem */ - node = node->next; - } - /* return the reference number */ - return node == NULL ? 0 : node->p; -} - -/*********************************************************************** -* NAME -* -* glp_ios_prev_node - determine previous active subproblem -* -* SYNOPSIS -* -* int glp_ios_prev_node(glp_tree *tree, int p); -* -* RETURNS -* -* If the parameter p is zero, the routine glp_ios_prev_node returns -* the reference number of the last active subproblem. However, if the -* tree is empty, zero is returned. -* -* If the parameter p is not zero, it must specify the reference number -* of some active subproblem, in which case the routine returns the -* reference number of the previous active subproblem. However, if there -* is no previous active subproblem in the list, zero is returned. -* -* All subproblems in the active list are ordered chronologically, i.e. -* subproblem A precedes subproblem B if A was created before B. */ - -int glp_ios_prev_node(glp_tree *tree, int p) -{ IOSNPD *node; - if (p == 0) - { /* obtain pointer to the last active subproblem */ - node = tree->tail; - } - else - { /* obtain pointer to the specified subproblem */ - if (!(1 <= p && p <= tree->nslots)) -err: xerror("glp_ios_prev_node: p = %d; invalid subproblem refer" - "ence number\n", p); - node = tree->slot[p].node; - if (node == NULL) goto err; - /* the specified subproblem must be active */ - if (node->count != 0) - xerror("glp_ios_prev_node: p = %d; subproblem not in the ac" - "tive list\n", p); - /* obtain pointer to the previous active subproblem */ - node = node->prev; - } - /* return the reference number */ - return node == NULL ? 0 : node->p; -} - -/*********************************************************************** -* NAME -* -* glp_ios_up_node - determine parent subproblem -* -* SYNOPSIS -* -* int glp_ios_up_node(glp_tree *tree, int p); -* -* RETURNS -* -* The parameter p must specify the reference number of some (active or -* inactive) subproblem, in which case the routine iet_get_up_node -* returns the reference number of its parent subproblem. However, if -* the specified subproblem is the root of the tree and, therefore, has -* no parent, the routine returns zero. */ - -int glp_ios_up_node(glp_tree *tree, int p) -{ IOSNPD *node; - /* obtain pointer to the specified subproblem */ - if (!(1 <= p && p <= tree->nslots)) -err: xerror("glp_ios_up_node: p = %d; invalid subproblem reference " - "number\n", p); - node = tree->slot[p].node; - if (node == NULL) goto err; - /* obtain pointer to the parent subproblem */ - node = node->up; - /* return the reference number */ - return node == NULL ? 0 : node->p; -} - -/*********************************************************************** -* NAME -* -* glp_ios_node_level - determine subproblem level -* -* SYNOPSIS -* -* int glp_ios_node_level(glp_tree *tree, int p); -* -* RETURNS -* -* The routine glp_ios_node_level returns the level of the subproblem, -* whose reference number is p, in the branch-and-bound tree. (The root -* subproblem has level 0, and the level of any other subproblem is the -* level of its parent plus one.) */ - -int glp_ios_node_level(glp_tree *tree, int p) -{ IOSNPD *node; - /* obtain pointer to the specified subproblem */ - if (!(1 <= p && p <= tree->nslots)) -err: xerror("glp_ios_node_level: p = %d; invalid subproblem referen" - "ce number\n", p); - node = tree->slot[p].node; - if (node == NULL) goto err; - /* return the node level */ - return node->level; -} - -/*********************************************************************** -* NAME -* -* glp_ios_node_bound - determine subproblem local bound -* -* SYNOPSIS -* -* double glp_ios_node_bound(glp_tree *tree, int p); -* -* RETURNS -* -* The routine glp_ios_node_bound returns the local bound for (active or -* inactive) subproblem, whose reference number is p. -* -* COMMENTS -* -* The local bound for subproblem p is an lower (minimization) or upper -* (maximization) bound for integer optimal solution to this subproblem -* (not to the original problem). This bound is local in the sense that -* only subproblems in the subtree rooted at node p cannot have better -* integer feasible solutions. -* -* On creating a subproblem (due to the branching step) its local bound -* is inherited from its parent and then may get only stronger (never -* weaker). For the root subproblem its local bound is initially set to -* -DBL_MAX (minimization) or +DBL_MAX (maximization) and then improved -* as the root LP relaxation has been solved. -* -* Note that the local bound is not necessarily the optimal objective -* value to corresponding LP relaxation; it may be stronger. */ - -double glp_ios_node_bound(glp_tree *tree, int p) -{ IOSNPD *node; - /* obtain pointer to the specified subproblem */ - if (!(1 <= p && p <= tree->nslots)) -err: xerror("glp_ios_node_bound: p = %d; invalid subproblem referen" - "ce number\n", p); - node = tree->slot[p].node; - if (node == NULL) goto err; - /* return the node local bound */ - return node->bound; -} - -/*********************************************************************** -* NAME -* -* glp_ios_best_node - find active subproblem with best local bound -* -* SYNOPSIS -* -* int glp_ios_best_node(glp_tree *tree); -* -* RETURNS -* -* The routine glp_ios_best_node returns the reference number of the -* active subproblem, whose local bound is best (i.e. smallest in case -* of minimization or largest in case of maximization). However, if the -* tree is empty, the routine returns zero. -* -* COMMENTS -* -* The best local bound is an lower (minimization) or upper -* (maximization) bound for integer optimal solution to the original -* MIP problem. */ - -int glp_ios_best_node(glp_tree *tree) -{ return - ios_best_node(tree); -} - -/*********************************************************************** -* NAME -* -* glp_ios_mip_gap - compute relative MIP gap -* -* SYNOPSIS -* -* double glp_ios_mip_gap(glp_tree *tree); -* -* DESCRIPTION -* -* The routine glp_ios_mip_gap computes the relative MIP gap with the -* following formula: -* -* gap = |best_mip - best_bnd| / (|best_mip| + DBL_EPSILON), -* -* where best_mip is the best integer feasible solution found so far, -* best_bnd is the best (global) bound. If no integer feasible solution -* has been found yet, gap is set to DBL_MAX. -* -* RETURNS -* -* The routine glp_ios_mip_gap returns the relative MIP gap. */ - -double glp_ios_mip_gap(glp_tree *tree) -{ return - ios_relative_gap(tree); -} - -/*********************************************************************** -* NAME -* -* glp_ios_node_data - access subproblem application-specific data -* -* SYNOPSIS -* -* void *glp_ios_node_data(glp_tree *tree, int p); -* -* DESCRIPTION -* -* The routine glp_ios_node_data allows the application accessing a -* memory block allocated for the subproblem (which may be active or -* inactive), whose reference number is p. -* -* The size of the block is defined by the control parameter cb_size -* passed to the routine glp_intopt. The block is initialized by binary -* zeros on creating corresponding subproblem, and its contents is kept -* until the subproblem will be removed from the tree. -* -* The application may use these memory blocks to store specific data -* for each subproblem. -* -* RETURNS -* -* The routine glp_ios_node_data returns a pointer to the memory block -* for the specified subproblem. Note that if cb_size = 0, the routine -* returns a null pointer. */ - -void *glp_ios_node_data(glp_tree *tree, int p) -{ IOSNPD *node; - /* obtain pointer to the specified subproblem */ - if (!(1 <= p && p <= tree->nslots)) -err: xerror("glp_ios_node_level: p = %d; invalid subproblem referen" - "ce number\n", p); - node = tree->slot[p].node; - if (node == NULL) goto err; - /* return pointer to the application-specific data */ - return node->data; -} - -/*********************************************************************** -* NAME -* -* glp_ios_row_attr - retrieve additional row attributes -* -* SYNOPSIS -* -* void glp_ios_row_attr(glp_tree *tree, int i, glp_attr *attr); -* -* DESCRIPTION -* -* The routine glp_ios_row_attr retrieves additional attributes of row -* i and stores them in the structure glp_attr. */ - -void glp_ios_row_attr(glp_tree *tree, int i, glp_attr *attr) -{ GLPROW *row; - if (!(1 <= i && i <= tree->mip->m)) - xerror("glp_ios_row_attr: i = %d; row number out of range\n", - i); - row = tree->mip->row[i]; - attr->level = row->level; - attr->origin = row->origin; - attr->klass = row->klass; - return; -} - -/**********************************************************************/ - -int glp_ios_pool_size(glp_tree *tree) -{ /* determine current size of the cut pool */ - if (tree->reason != GLP_ICUTGEN) - xerror("glp_ios_pool_size: operation not allowed\n"); - xassert(tree->local != NULL); - return tree->local->size; -} - -/**********************************************************************/ - -int glp_ios_add_row(glp_tree *tree, - const char *name, int klass, int flags, int len, const int ind[], - const double val[], int type, double rhs) -{ /* add row (constraint) to the cut pool */ - int num; - if (tree->reason != GLP_ICUTGEN) - xerror("glp_ios_add_row: operation not allowed\n"); - xassert(tree->local != NULL); - num = ios_add_row(tree, tree->local, name, klass, flags, len, - ind, val, type, rhs); - return num; -} - -/**********************************************************************/ - -void glp_ios_del_row(glp_tree *tree, int i) -{ /* remove row (constraint) from the cut pool */ - if (tree->reason != GLP_ICUTGEN) - xerror("glp_ios_del_row: operation not allowed\n"); - ios_del_row(tree, tree->local, i); - return; -} - -/**********************************************************************/ - -void glp_ios_clear_pool(glp_tree *tree) -{ /* remove all rows (constraints) from the cut pool */ - if (tree->reason != GLP_ICUTGEN) - xerror("glp_ios_clear_pool: operation not allowed\n"); - ios_clear_pool(tree, tree->local); - return; -} - -/*********************************************************************** -* NAME -* -* glp_ios_can_branch - check if can branch upon specified variable -* -* SYNOPSIS -* -* int glp_ios_can_branch(glp_tree *tree, int j); -* -* RETURNS -* -* If j-th variable (column) can be used to branch upon, the routine -* glp_ios_can_branch returns non-zero, otherwise zero. */ - -int glp_ios_can_branch(glp_tree *tree, int j) -{ if (!(1 <= j && j <= tree->mip->n)) - xerror("glp_ios_can_branch: j = %d; column number out of range" - "\n", j); - return tree->non_int[j]; -} - -/*********************************************************************** -* NAME -* -* glp_ios_branch_upon - choose variable to branch upon -* -* SYNOPSIS -* -* void glp_ios_branch_upon(glp_tree *tree, int j, int sel); -* -* DESCRIPTION -* -* The routine glp_ios_branch_upon can be called from the user-defined -* callback routine in response to the reason GLP_IBRANCH to choose a -* branching variable, whose ordinal number is j. Should note that only -* variables, for which the routine glp_ios_can_branch returns non-zero, -* can be used to branch upon. -* -* The parameter sel is a flag that indicates which branch (subproblem) -* should be selected next to continue the search: -* -* GLP_DN_BRNCH - select down-branch; -* GLP_UP_BRNCH - select up-branch; -* GLP_NO_BRNCH - use general selection technique. */ - -void glp_ios_branch_upon(glp_tree *tree, int j, int sel) -{ if (!(1 <= j && j <= tree->mip->n)) - xerror("glp_ios_branch_upon: j = %d; column number out of rang" - "e\n", j); - if (!(sel == GLP_DN_BRNCH || sel == GLP_UP_BRNCH || - sel == GLP_NO_BRNCH)) - xerror("glp_ios_branch_upon: sel = %d: invalid branch selectio" - "n flag\n", sel); - if (!(tree->non_int[j])) - xerror("glp_ios_branch_upon: j = %d; variable cannot be used t" - "o branch upon\n", j); - if (tree->br_var != 0) - xerror("glp_ios_branch_upon: branching variable already chosen" - "\n"); - tree->br_var = j; - tree->br_sel = sel; - return; -} - -/*********************************************************************** -* NAME -* -* glp_ios_select_node - select subproblem to continue the search -* -* SYNOPSIS -* -* void glp_ios_select_node(glp_tree *tree, int p); -* -* DESCRIPTION -* -* The routine glp_ios_select_node can be called from the user-defined -* callback routine in response to the reason GLP_ISELECT to select an -* active subproblem, whose reference number is p. The search will be -* continued from the subproblem selected. */ - -void glp_ios_select_node(glp_tree *tree, int p) -{ IOSNPD *node; - /* obtain pointer to the specified subproblem */ - if (!(1 <= p && p <= tree->nslots)) -err: xerror("glp_ios_select_node: p = %d; invalid subproblem refere" - "nce number\n", p); - node = tree->slot[p].node; - if (node == NULL) goto err; - /* the specified subproblem must be active */ - if (node->count != 0) - xerror("glp_ios_select_node: p = %d; subproblem not in the act" - "ive list\n", p); - /* no subproblem must be selected yet */ - if (tree->next_p != 0) - xerror("glp_ios_select_node: subproblem already selected\n"); - /* select the specified subproblem to continue the search */ - tree->next_p = p; - return; -} - -/*********************************************************************** -* NAME -* -* glp_ios_heur_sol - provide solution found by heuristic -* -* SYNOPSIS -* -* int glp_ios_heur_sol(glp_tree *tree, const double x[]); -* -* DESCRIPTION -* -* The routine glp_ios_heur_sol can be called from the user-defined -* callback routine in response to the reason GLP_IHEUR to provide an -* integer feasible solution found by a primal heuristic. -* -* Primal values of *all* variables (columns) found by the heuristic -* should be placed in locations x[1], ..., x[n], where n is the number -* of columns in the original problem object. Note that the routine -* glp_ios_heur_sol *does not* check primal feasibility of the solution -* provided. -* -* Using the solution passed in the array x the routine computes value -* of the objective function. If the objective value is better than the -* best known integer feasible solution, the routine computes values of -* auxiliary variables (rows) and stores all solution components in the -* problem object. -* -* RETURNS -* -* If the provided solution is accepted, the routine glp_ios_heur_sol -* returns zero. Otherwise, if the provided solution is rejected, the -* routine returns non-zero. */ - -int glp_ios_heur_sol(glp_tree *tree, const double x[]) -{ glp_prob *mip = tree->mip; - int m = tree->orig_m; - int n = tree->n; - int i, j; - double obj; - xassert(mip->m >= m); - xassert(mip->n == n); - /* check values of integer variables and compute value of the - objective function */ - obj = mip->c0; - for (j = 1; j <= n; j++) - { GLPCOL *col = mip->col[j]; - if (col->kind == GLP_IV) - { /* provided value must be integral */ - if (x[j] != floor(x[j])) return 1; - } - obj += col->coef * x[j]; - } - /* check if the provided solution is better than the best known - integer feasible solution */ - if (mip->mip_stat == GLP_FEAS) - { switch (mip->dir) - { case GLP_MIN: - if (obj >= tree->mip->mip_obj) return 1; - break; - case GLP_MAX: - if (obj <= tree->mip->mip_obj) return 1; - break; - default: - xassert(mip != mip); - } - } - /* it is better; store it in the problem object */ - if (tree->parm->msg_lev >= GLP_MSG_ON) - xprintf("Solution found by heuristic: %.12g\n", obj); - mip->mip_stat = GLP_FEAS; - mip->mip_obj = obj; - for (j = 1; j <= n; j++) - mip->col[j]->mipx = x[j]; - for (i = 1; i <= m; i++) - { GLPROW *row = mip->row[i]; - GLPAIJ *aij; - row->mipx = 0.0; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - row->mipx += aij->val * aij->col->mipx; - } -#if 1 /* 11/VII-2013 */ - ios_process_sol(tree); -#endif - return 0; -} - -/*********************************************************************** -* NAME -* -* glp_ios_terminate - terminate the solution process. -* -* SYNOPSIS -* -* void glp_ios_terminate(glp_tree *tree); -* -* DESCRIPTION -* -* The routine glp_ios_terminate sets a flag indicating that the MIP -* solver should prematurely terminate the search. */ - -void glp_ios_terminate(glp_tree *tree) -{ if (tree->parm->msg_lev >= GLP_MSG_DBG) - xprintf("The search is prematurely terminated due to applicati" - "on request\n"); - tree->stop = 1; - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi14.c b/resources/3rdparty/glpk-4.53/src/glpapi14.c deleted file mode 100644 index fc3b73757..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi14.c +++ /dev/null @@ -1,272 +0,0 @@ -/* glpapi14.c (processing models in GNU MathProg language) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "draft.h" -#include "glpmpl.h" -#include "prob.h" - -glp_tran *glp_mpl_alloc_wksp(void) -{ /* allocate the MathProg translator workspace */ - glp_tran *tran; - tran = mpl_initialize(); - return tran; -} - -#if 1 /* 08/XII-2009 */ -void _glp_mpl_init_rand(glp_tran *tran, int seed) -{ if (tran->phase != 0) - xerror("glp_mpl_init_rand: invalid call sequence\n"); - rng_init_rand(tran->rand, seed); - return; -} -#endif - -int glp_mpl_read_model(glp_tran *tran, const char *fname, int skip) -{ /* read and translate model section */ - int ret; - if (tran->phase != 0) - xerror("glp_mpl_read_model: invalid call sequence\n"); - ret = mpl_read_model(tran, (char *)fname, skip); - if (ret == 1 || ret == 2) - ret = 0; - else if (ret == 4) - ret = 1; - else - xassert(ret != ret); - return ret; -} - -int glp_mpl_read_data(glp_tran *tran, const char *fname) -{ /* read and translate data section */ - int ret; - if (!(tran->phase == 1 || tran->phase == 2)) - xerror("glp_mpl_read_data: invalid call sequence\n"); - ret = mpl_read_data(tran, (char *)fname); - if (ret == 2) - ret = 0; - else if (ret == 4) - ret = 1; - else - xassert(ret != ret); - return ret; -} - -int glp_mpl_generate(glp_tran *tran, const char *fname) -{ /* generate the model */ - int ret; - if (!(tran->phase == 1 || tran->phase == 2)) - xerror("glp_mpl_generate: invalid call sequence\n"); - ret = mpl_generate(tran, (char *)fname); - if (ret == 3) - ret = 0; - else if (ret == 4) - ret = 1; - return ret; -} - -void glp_mpl_build_prob(glp_tran *tran, glp_prob *prob) -{ /* build LP/MIP problem instance from the model */ - int m, n, i, j, t, kind, type, len, *ind; - double lb, ub, *val; - if (tran->phase != 3) - xerror("glp_mpl_build_prob: invalid call sequence\n"); - /* erase the problem object */ - glp_erase_prob(prob); - /* set problem name */ - glp_set_prob_name(prob, mpl_get_prob_name(tran)); - /* build rows (constraints) */ - m = mpl_get_num_rows(tran); - if (m > 0) - glp_add_rows(prob, m); - for (i = 1; i <= m; i++) - { /* set row name */ - glp_set_row_name(prob, i, mpl_get_row_name(tran, i)); - /* set row bounds */ - type = mpl_get_row_bnds(tran, i, &lb, &ub); - switch (type) - { case MPL_FR: type = GLP_FR; break; - case MPL_LO: type = GLP_LO; break; - case MPL_UP: type = GLP_UP; break; - case MPL_DB: type = GLP_DB; break; - case MPL_FX: type = GLP_FX; break; - default: xassert(type != type); - } - if (type == GLP_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb))) - { type = GLP_FX; - if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub; - } - glp_set_row_bnds(prob, i, type, lb, ub); - /* warn about non-zero constant term */ - if (mpl_get_row_c0(tran, i) != 0.0) - xprintf("glp_mpl_build_prob: row %s; constant term %.12g ig" - "nored\n", - mpl_get_row_name(tran, i), mpl_get_row_c0(tran, i)); - } - /* build columns (variables) */ - n = mpl_get_num_cols(tran); - if (n > 0) - glp_add_cols(prob, n); - for (j = 1; j <= n; j++) - { /* set column name */ - glp_set_col_name(prob, j, mpl_get_col_name(tran, j)); - /* set column kind */ - kind = mpl_get_col_kind(tran, j); - switch (kind) - { case MPL_NUM: - break; - case MPL_INT: - case MPL_BIN: - glp_set_col_kind(prob, j, GLP_IV); - break; - default: - xassert(kind != kind); - } - /* set column bounds */ - type = mpl_get_col_bnds(tran, j, &lb, &ub); - switch (type) - { case MPL_FR: type = GLP_FR; break; - case MPL_LO: type = GLP_LO; break; - case MPL_UP: type = GLP_UP; break; - case MPL_DB: type = GLP_DB; break; - case MPL_FX: type = GLP_FX; break; - default: xassert(type != type); - } - if (kind == MPL_BIN) - { if (type == GLP_FR || type == GLP_UP || lb < 0.0) lb = 0.0; - if (type == GLP_FR || type == GLP_LO || ub > 1.0) ub = 1.0; - type = GLP_DB; - } - if (type == GLP_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb))) - { type = GLP_FX; - if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub; - } - glp_set_col_bnds(prob, j, type, lb, ub); - } - /* load the constraint matrix */ - ind = xcalloc(1+n, sizeof(int)); - val = xcalloc(1+n, sizeof(double)); - for (i = 1; i <= m; i++) - { len = mpl_get_mat_row(tran, i, ind, val); - glp_set_mat_row(prob, i, len, ind, val); - } - /* build objective function (the first objective is used) */ - for (i = 1; i <= m; i++) - { kind = mpl_get_row_kind(tran, i); - if (kind == MPL_MIN || kind == MPL_MAX) - { /* set objective name */ - glp_set_obj_name(prob, mpl_get_row_name(tran, i)); - /* set optimization direction */ - glp_set_obj_dir(prob, kind == MPL_MIN ? GLP_MIN : GLP_MAX); - /* set constant term */ - glp_set_obj_coef(prob, 0, mpl_get_row_c0(tran, i)); - /* set objective coefficients */ - len = mpl_get_mat_row(tran, i, ind, val); - for (t = 1; t <= len; t++) - glp_set_obj_coef(prob, ind[t], val[t]); - break; - } - } - /* free working arrays */ - xfree(ind); - xfree(val); - return; -} - -int glp_mpl_postsolve(glp_tran *tran, glp_prob *prob, int sol) -{ /* postsolve the model */ - int i, j, m, n, stat, ret; - double prim, dual; - if (!(tran->phase == 3 && !tran->flag_p)) - xerror("glp_mpl_postsolve: invalid call sequence\n"); - if (!(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP)) - xerror("glp_mpl_postsolve: sol = %d; invalid parameter\n", - sol); - m = mpl_get_num_rows(tran); - n = mpl_get_num_cols(tran); - if (!(m == glp_get_num_rows(prob) && - n == glp_get_num_cols(prob))) - xerror("glp_mpl_postsolve: wrong problem object\n"); - if (!mpl_has_solve_stmt(tran)) - { ret = 0; - goto done; - } - for (i = 1; i <= m; i++) - { if (sol == GLP_SOL) - { stat = glp_get_row_stat(prob, i); - prim = glp_get_row_prim(prob, i); - dual = glp_get_row_dual(prob, i); - } - else if (sol == GLP_IPT) - { stat = 0; - prim = glp_ipt_row_prim(prob, i); - dual = glp_ipt_row_dual(prob, i); - } - else if (sol == GLP_MIP) - { stat = 0; - prim = glp_mip_row_val(prob, i); - dual = 0.0; - } - else - xassert(sol != sol); - if (fabs(prim) < 1e-9) prim = 0.0; - if (fabs(dual) < 1e-9) dual = 0.0; - mpl_put_row_soln(tran, i, stat, prim, dual); - } - for (j = 1; j <= n; j++) - { if (sol == GLP_SOL) - { stat = glp_get_col_stat(prob, j); - prim = glp_get_col_prim(prob, j); - dual = glp_get_col_dual(prob, j); - } - else if (sol == GLP_IPT) - { stat = 0; - prim = glp_ipt_col_prim(prob, j); - dual = glp_ipt_col_dual(prob, j); - } - else if (sol == GLP_MIP) - { stat = 0; - prim = glp_mip_col_val(prob, j); - dual = 0.0; - } - else - xassert(sol != sol); - if (fabs(prim) < 1e-9) prim = 0.0; - if (fabs(dual) < 1e-9) dual = 0.0; - mpl_put_col_soln(tran, j, stat, prim, dual); - } - ret = mpl_postsolve(tran); - if (ret == 3) - ret = 0; - else if (ret == 4) - ret = 1; -done: return ret; -} - -void glp_mpl_free_wksp(glp_tran *tran) -{ /* free the MathProg translator workspace */ - mpl_terminate(tran); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi15.c b/resources/3rdparty/glpk-4.53/src/glpapi15.c deleted file mode 100644 index ecc6c32d3..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi15.c +++ /dev/null @@ -1,615 +0,0 @@ -/* glpapi15.c (basic graph and network routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpsdf.h" -#include "prob.h" - -#define xfprintf glp_format - -/* CAUTION: DO NOT CHANGE THE LIMITS BELOW */ - -#define NV_MAX 100000000 /* = 100*10^6 */ -/* maximal number of vertices in the graph */ - -#define NA_MAX 500000000 /* = 500*10^6 */ -/* maximal number of arcs in the graph */ - -/*********************************************************************** -* NAME -* -* glp_create_graph - create graph -* -* SYNOPSIS -* -* glp_graph *glp_create_graph(int v_size, int a_size); -* -* DESCRIPTION -* -* The routine creates a new graph, which initially is empty, i.e. has -* no vertices and arcs. -* -* The parameter v_size specifies the size of data associated with each -* vertex of the graph (0 to 256 bytes). -* -* The parameter a_size specifies the size of data associated with each -* arc of the graph (0 to 256 bytes). -* -* RETURNS -* -* The routine returns a pointer to the graph created. */ - -static void create_graph(glp_graph *G, int v_size, int a_size) -{ G->pool = dmp_create_pool(); - G->name = NULL; - G->nv_max = 50; - G->nv = G->na = 0; - G->v = xcalloc(1+G->nv_max, sizeof(glp_vertex *)); - G->index = NULL; - G->v_size = v_size; - G->a_size = a_size; - return; -} - -glp_graph *glp_create_graph(int v_size, int a_size) -{ glp_graph *G; - if (!(0 <= v_size && v_size <= 256)) - xerror("glp_create_graph: v_size = %d; invalid size of vertex " - "data\n", v_size); - if (!(0 <= a_size && a_size <= 256)) - xerror("glp_create_graph: a_size = %d; invalid size of arc dat" - "a\n", a_size); - G = xmalloc(sizeof(glp_graph)); - create_graph(G, v_size, a_size); - return G; -} - -/*********************************************************************** -* NAME -* -* glp_set_graph_name - assign (change) graph name -* -* SYNOPSIS -* -* void glp_set_graph_name(glp_graph *G, const char *name); -* -* DESCRIPTION -* -* The routine glp_set_graph_name assigns a symbolic name specified by -* the character string name (1 to 255 chars) to the graph. -* -* If the parameter name is NULL or an empty string, the routine erases -* the existing symbolic name of the graph. */ - -void glp_set_graph_name(glp_graph *G, const char *name) -{ if (G->name != NULL) - { dmp_free_atom(G->pool, G->name, strlen(G->name)+1); - G->name = NULL; - } - if (!(name == NULL || name[0] == '\0')) - { int j; - for (j = 0; name[j] != '\0'; j++) - { if (j == 256) - xerror("glp_set_graph_name: graph name too long\n"); - if (iscntrl((unsigned char)name[j])) - xerror("glp_set_graph_name: graph name contains invalid " - "character(s)\n"); - } - G->name = dmp_get_atom(G->pool, strlen(name)+1); - strcpy(G->name, name); - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_add_vertices - add new vertices to graph -* -* SYNOPSIS -* -* int glp_add_vertices(glp_graph *G, int nadd); -* -* DESCRIPTION -* -* The routine glp_add_vertices adds nadd vertices to the specified -* graph. New vertices are always added to the end of the vertex list, -* so ordinal numbers of existing vertices remain unchanged. -* -* Being added each new vertex is isolated (has no incident arcs). -* -* RETURNS -* -* The routine glp_add_vertices returns an ordinal number of the first -* new vertex added to the graph. */ - -int glp_add_vertices(glp_graph *G, int nadd) -{ int i, nv_new; - if (nadd < 1) - xerror("glp_add_vertices: nadd = %d; invalid number of vertice" - "s\n", nadd); - if (nadd > NV_MAX - G->nv) - xerror("glp_add_vertices: nadd = %d; too many vertices\n", - nadd); - /* determine new number of vertices */ - nv_new = G->nv + nadd; - /* increase the room, if necessary */ - if (G->nv_max < nv_new) - { glp_vertex **save = G->v; - while (G->nv_max < nv_new) - { G->nv_max += G->nv_max; - xassert(G->nv_max > 0); - } - G->v = xcalloc(1+G->nv_max, sizeof(glp_vertex *)); - memcpy(&G->v[1], &save[1], G->nv * sizeof(glp_vertex *)); - xfree(save); - } - /* add new vertices to the end of the vertex list */ - for (i = G->nv+1; i <= nv_new; i++) - { glp_vertex *v; - G->v[i] = v = dmp_get_atom(G->pool, sizeof(glp_vertex)); - v->i = i; - v->name = NULL; - v->entry = NULL; - if (G->v_size == 0) - v->data = NULL; - else - { v->data = dmp_get_atom(G->pool, G->v_size); - memset(v->data, 0, G->v_size); - } - v->temp = NULL; - v->in = v->out = NULL; - } - /* set new number of vertices */ - G->nv = nv_new; - /* return the ordinal number of the first vertex added */ - return nv_new - nadd + 1; -} - -/**********************************************************************/ - -void glp_set_vertex_name(glp_graph *G, int i, const char *name) -{ /* assign (change) vertex name */ - glp_vertex *v; - if (!(1 <= i && i <= G->nv)) - xerror("glp_set_vertex_name: i = %d; vertex number out of rang" - "e\n", i); - v = G->v[i]; - if (v->name != NULL) - { if (v->entry != NULL) - { xassert(G->index != NULL); - avl_delete_node(G->index, v->entry); - v->entry = NULL; - } - dmp_free_atom(G->pool, v->name, strlen(v->name)+1); - v->name = NULL; - } - if (!(name == NULL || name[0] == '\0')) - { int k; - for (k = 0; name[k] != '\0'; k++) - { if (k == 256) - xerror("glp_set_vertex_name: i = %d; vertex name too lon" - "g\n", i); - if (iscntrl((unsigned char)name[k])) - xerror("glp_set_vertex_name: i = %d; vertex name contain" - "s invalid character(s)\n", i); - } - v->name = dmp_get_atom(G->pool, strlen(name)+1); - strcpy(v->name, name); - if (G->index != NULL) - { xassert(v->entry == NULL); - v->entry = avl_insert_node(G->index, v->name); - avl_set_node_link(v->entry, v); - } - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_add_arc - add new arc to graph -* -* SYNOPSIS -* -* glp_arc *glp_add_arc(glp_graph *G, int i, int j); -* -* DESCRIPTION -* -* The routine glp_add_arc adds a new arc to the specified graph. -* -* The parameters i and j specify the ordinal numbers of, resp., tail -* and head vertices of the arc. Note that self-loops and multiple arcs -* are allowed. -* -* RETURNS -* -* The routine glp_add_arc returns a pointer to the arc added. */ - -glp_arc *glp_add_arc(glp_graph *G, int i, int j) -{ glp_arc *a; - if (!(1 <= i && i <= G->nv)) - xerror("glp_add_arc: i = %d; tail vertex number out of range\n" - , i); - if (!(1 <= j && j <= G->nv)) - xerror("glp_add_arc: j = %d; head vertex number out of range\n" - , j); - if (G->na == NA_MAX) - xerror("glp_add_arc: too many arcs\n"); - a = dmp_get_atom(G->pool, sizeof(glp_arc)); - a->tail = G->v[i]; - a->head = G->v[j]; - if (G->a_size == 0) - a->data = NULL; - else - { a->data = dmp_get_atom(G->pool, G->a_size); - memset(a->data, 0, G->a_size); - } - a->temp = NULL; - a->t_prev = NULL; - a->t_next = G->v[i]->out; - if (a->t_next != NULL) a->t_next->t_prev = a; - a->h_prev = NULL; - a->h_next = G->v[j]->in; - if (a->h_next != NULL) a->h_next->h_prev = a; - G->v[i]->out = G->v[j]->in = a; - G->na++; - return a; -} - -/*********************************************************************** -* NAME -* -* glp_del_vertices - delete vertices from graph -* -* SYNOPSIS -* -* void glp_del_vertices(glp_graph *G, int ndel, const int num[]); -* -* DESCRIPTION -* -* The routine glp_del_vertices deletes vertices along with all -* incident arcs from the specified graph. Ordinal numbers of vertices -* to be deleted should be placed in locations num[1], ..., num[ndel], -* ndel > 0. -* -* Note that deleting vertices involves changing ordinal numbers of -* other vertices remaining in the graph. New ordinal numbers of the -* remaining vertices are assigned under the assumption that the -* original order of vertices is not changed. */ - -void glp_del_vertices(glp_graph *G, int ndel, const int num[]) -{ glp_vertex *v; - int i, k, nv_new; - /* scan the list of vertices to be deleted */ - if (!(1 <= ndel && ndel <= G->nv)) - xerror("glp_del_vertices: ndel = %d; invalid number of vertice" - "s\n", ndel); - for (k = 1; k <= ndel; k++) - { /* take the number of vertex to be deleted */ - i = num[k]; - /* obtain pointer to i-th vertex */ - if (!(1 <= i && i <= G->nv)) - xerror("glp_del_vertices: num[%d] = %d; vertex number out o" - "f range\n", k, i); - v = G->v[i]; - /* check that the vertex is not marked yet */ - if (v->i == 0) - xerror("glp_del_vertices: num[%d] = %d; duplicate vertex nu" - "mbers not allowed\n", k, i); - /* erase symbolic name assigned to the vertex */ - glp_set_vertex_name(G, i, NULL); - xassert(v->name == NULL); - xassert(v->entry == NULL); - /* free vertex data, if allocated */ - if (v->data != NULL) - dmp_free_atom(G->pool, v->data, G->v_size); - /* delete all incoming arcs */ - while (v->in != NULL) - glp_del_arc(G, v->in); - /* delete all outgoing arcs */ - while (v->out != NULL) - glp_del_arc(G, v->out); - /* mark the vertex to be deleted */ - v->i = 0; - } - /* delete all marked vertices from the vertex list */ - nv_new = 0; - for (i = 1; i <= G->nv; i++) - { /* obtain pointer to i-th vertex */ - v = G->v[i]; - /* check if the vertex is marked */ - if (v->i == 0) - { /* it is marked, delete it */ - dmp_free_atom(G->pool, v, sizeof(glp_vertex)); - } - else - { /* it is not marked, keep it */ - v->i = ++nv_new; - G->v[v->i] = v; - } - } - /* set new number of vertices in the graph */ - G->nv = nv_new; - return; -} - -/*********************************************************************** -* NAME -* -* glp_del_arc - delete arc from graph -* -* SYNOPSIS -* -* void glp_del_arc(glp_graph *G, glp_arc *a); -* -* DESCRIPTION -* -* The routine glp_del_arc deletes an arc from the specified graph. -* The arc to be deleted must exist. */ - -void glp_del_arc(glp_graph *G, glp_arc *a) -{ /* some sanity checks */ - xassert(G->na > 0); - xassert(1 <= a->tail->i && a->tail->i <= G->nv); - xassert(a->tail == G->v[a->tail->i]); - xassert(1 <= a->head->i && a->head->i <= G->nv); - xassert(a->head == G->v[a->head->i]); - /* remove the arc from the list of incoming arcs */ - if (a->h_prev == NULL) - a->head->in = a->h_next; - else - a->h_prev->h_next = a->h_next; - if (a->h_next == NULL) - ; - else - a->h_next->h_prev = a->h_prev; - /* remove the arc from the list of outgoing arcs */ - if (a->t_prev == NULL) - a->tail->out = a->t_next; - else - a->t_prev->t_next = a->t_next; - if (a->t_next == NULL) - ; - else - a->t_next->t_prev = a->t_prev; - /* free arc data, if allocated */ - if (a->data != NULL) - dmp_free_atom(G->pool, a->data, G->a_size); - /* delete the arc from the graph */ - dmp_free_atom(G->pool, a, sizeof(glp_arc)); - G->na--; - return; -} - -/*********************************************************************** -* NAME -* -* glp_erase_graph - erase graph content -* -* SYNOPSIS -* -* void glp_erase_graph(glp_graph *G, int v_size, int a_size); -* -* DESCRIPTION -* -* The routine glp_erase_graph erases the content of the specified -* graph. The effect of this operation is the same as if the graph -* would be deleted with the routine glp_delete_graph and then created -* anew with the routine glp_create_graph, with exception that the -* handle (pointer) to the graph remains valid. */ - -static void delete_graph(glp_graph *G) -{ dmp_delete_pool(G->pool); - xfree(G->v); - if (G->index != NULL) avl_delete_tree(G->index); - return; -} - -void glp_erase_graph(glp_graph *G, int v_size, int a_size) -{ if (!(0 <= v_size && v_size <= 256)) - xerror("glp_erase_graph: v_size = %d; invalid size of vertex d" - "ata\n", v_size); - if (!(0 <= a_size && a_size <= 256)) - xerror("glp_erase_graph: a_size = %d; invalid size of arc data" - "\n", a_size); - delete_graph(G); - create_graph(G, v_size, a_size); - return; -} - -/*********************************************************************** -* NAME -* -* glp_delete_graph - delete graph -* -* SYNOPSIS -* -* void glp_delete_graph(glp_graph *G); -* -* DESCRIPTION -* -* The routine glp_delete_graph deletes the specified graph and frees -* all the memory allocated to this program object. */ - -void glp_delete_graph(glp_graph *G) -{ delete_graph(G); - xfree(G); - return; -} - -/**********************************************************************/ - -void glp_create_v_index(glp_graph *G) -{ /* create vertex name index */ - glp_vertex *v; - int i; - if (G->index == NULL) - { G->index = avl_create_tree(avl_strcmp, NULL); - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - xassert(v->entry == NULL); - if (v->name != NULL) - { v->entry = avl_insert_node(G->index, v->name); - avl_set_node_link(v->entry, v); - } - } - } - return; -} - -int glp_find_vertex(glp_graph *G, const char *name) -{ /* find vertex by its name */ - AVLNODE *node; - int i = 0; - if (G->index == NULL) - xerror("glp_find_vertex: vertex name index does not exist\n"); - if (!(name == NULL || name[0] == '\0' || strlen(name) > 255)) - { node = avl_find_node(G->index, name); - if (node != NULL) - i = ((glp_vertex *)avl_get_node_link(node))->i; - } - return i; -} - -void glp_delete_v_index(glp_graph *G) -{ /* delete vertex name index */ - int i; - if (G->index != NULL) - { avl_delete_tree(G->index), G->index = NULL; - for (i = 1; i <= G->nv; i++) G->v[i]->entry = NULL; - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_read_graph - read graph from plain text file -* -* SYNOPSIS -* -* int glp_read_graph(glp_graph *G, const char *fname); -* -* DESCRIPTION -* -* The routine glp_read_graph reads a graph from a plain text file. -* -* RETURNS -* -* If the operation was successful, the routine returns zero. Otherwise -* it prints an error message and returns non-zero. */ - -int glp_read_graph(glp_graph *G, const char *fname) -{ glp_data *data; - jmp_buf jump; - int nv, na, i, j, k, ret; - glp_erase_graph(G, G->v_size, G->a_size); - xprintf("Reading graph from `%s'...\n", fname); - data = glp_sdf_open_file(fname); - if (data == NULL) - { ret = 1; - goto done; - } - if (setjmp(jump)) - { ret = 1; - goto done; - } - glp_sdf_set_jump(data, jump); - nv = glp_sdf_read_int(data); - if (nv < 0) - glp_sdf_error(data, "invalid number of vertices\n"); - na = glp_sdf_read_int(data); - if (na < 0) - glp_sdf_error(data, "invalid number of arcs\n"); - xprintf("Graph has %d vert%s and %d arc%s\n", - nv, nv == 1 ? "ex" : "ices", na, na == 1 ? "" : "s"); - if (nv > 0) glp_add_vertices(G, nv); - for (k = 1; k <= na; k++) - { i = glp_sdf_read_int(data); - if (!(1 <= i && i <= nv)) - glp_sdf_error(data, "tail vertex number out of range\n"); - j = glp_sdf_read_int(data); - if (!(1 <= j && j <= nv)) - glp_sdf_error(data, "head vertex number out of range\n"); - glp_add_arc(G, i, j); - } - xprintf("%d lines were read\n", glp_sdf_line(data)); - ret = 0; -done: if (data != NULL) glp_sdf_close_file(data); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_write_graph - write graph to plain text file -* -* SYNOPSIS -* -* int glp_write_graph(glp_graph *G, const char *fname). -* -* DESCRIPTION -* -* The routine glp_write_graph writes the specified graph to a plain -* text file. -* -* RETURNS -* -* If the operation was successful, the routine returns zero. Otherwise -* it prints an error message and returns non-zero. */ - -int glp_write_graph(glp_graph *G, const char *fname) -{ glp_file *fp; - glp_vertex *v; - glp_arc *a; - int i, count, ret; - xprintf("Writing graph to `%s'...\n", fname); - fp = glp_open(fname, "w"), count = 0; - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xfprintf(fp, "%d %d\n", G->nv, G->na), count++; - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - xfprintf(fp, "%d %d\n", a->tail->i, a->head->i), count++; - } -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xprintf("%d lines were written\n", count); - ret = 0; -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi16.c b/resources/3rdparty/glpk-4.53/src/glpapi16.c deleted file mode 100644 index 9af86e2bd..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi16.c +++ /dev/null @@ -1,330 +0,0 @@ -/* glpapi16.c (graph and network analysis routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "mc13d.h" -#include "prob.h" - -/*********************************************************************** -* NAME -* -* glp_weak_comp - find all weakly connected components of graph -* -* SYNOPSIS -* -* int glp_weak_comp(glp_graph *G, int v_num); -* -* DESCRIPTION -* -* The routine glp_weak_comp finds all weakly connected components of -* the specified graph. -* -* The parameter v_num specifies an offset of the field of type int -* in the vertex data block, to which the routine stores the number of -* a (weakly) connected component containing that vertex. If v_num < 0, -* no component numbers are stored. -* -* The components are numbered in arbitrary order from 1 to nc, where -* nc is the total number of components found, 0 <= nc <= |V|. -* -* RETURNS -* -* The routine returns nc, the total number of components found. */ - -int glp_weak_comp(glp_graph *G, int v_num) -{ glp_vertex *v; - glp_arc *a; - int f, i, j, nc, nv, pos1, pos2, *prev, *next, *list; - if (v_num >= 0 && v_num > G->v_size - (int)sizeof(int)) - xerror("glp_weak_comp: v_num = %d; invalid offset\n", v_num); - nv = G->nv; - if (nv == 0) - { nc = 0; - goto done; - } - /* allocate working arrays */ - prev = xcalloc(1+nv, sizeof(int)); - next = xcalloc(1+nv, sizeof(int)); - list = xcalloc(1+nv, sizeof(int)); - /* if vertex i is unlabelled, prev[i] is the index of previous - unlabelled vertex, and next[i] is the index of next unlabelled - vertex; if vertex i is labelled, then prev[i] < 0, and next[i] - is the connected component number */ - /* initially all vertices are unlabelled */ - f = 1; - for (i = 1; i <= nv; i++) - prev[i] = i - 1, next[i] = i + 1; - next[nv] = 0; - /* main loop (until all vertices have been labelled) */ - nc = 0; - while (f != 0) - { /* take an unlabelled vertex */ - i = f; - /* and remove it from the list of unlabelled vertices */ - f = next[i]; - if (f != 0) prev[f] = 0; - /* label the vertex; it begins a new component */ - prev[i] = -1, next[i] = ++nc; - /* breadth first search */ - list[1] = i, pos1 = pos2 = 1; - while (pos1 <= pos2) - { /* dequeue vertex i */ - i = list[pos1++]; - /* consider all arcs incoming to vertex i */ - for (a = G->v[i]->in; a != NULL; a = a->h_next) - { /* vertex j is adjacent to vertex i */ - j = a->tail->i; - if (prev[j] >= 0) - { /* vertex j is unlabelled */ - /* remove it from the list of unlabelled vertices */ - if (prev[j] == 0) - f = next[j]; - else - next[prev[j]] = next[j]; - if (next[j] == 0) - ; - else - prev[next[j]] = prev[j]; - /* label the vertex */ - prev[j] = -1, next[j] = nc; - /* and enqueue it for further consideration */ - list[++pos2] = j; - } - } - /* consider all arcs outgoing from vertex i */ - for (a = G->v[i]->out; a != NULL; a = a->t_next) - { /* vertex j is adjacent to vertex i */ - j = a->head->i; - if (prev[j] >= 0) - { /* vertex j is unlabelled */ - /* remove it from the list of unlabelled vertices */ - if (prev[j] == 0) - f = next[j]; - else - next[prev[j]] = next[j]; - if (next[j] == 0) - ; - else - prev[next[j]] = prev[j]; - /* label the vertex */ - prev[j] = -1, next[j] = nc; - /* and enqueue it for further consideration */ - list[++pos2] = j; - } - } - } - } - /* store component numbers */ - if (v_num >= 0) - { for (i = 1; i <= nv; i++) - { v = G->v[i]; - memcpy((char *)v->data + v_num, &next[i], sizeof(int)); - } - } - /* free working arrays */ - xfree(prev); - xfree(next); - xfree(list); -done: return nc; -} - -/*********************************************************************** -* NAME -* -* glp_strong_comp - find all strongly connected components of graph -* -* SYNOPSIS -* -* int glp_strong_comp(glp_graph *G, int v_num); -* -* DESCRIPTION -* -* The routine glp_strong_comp finds all strongly connected components -* of the specified graph. -* -* The parameter v_num specifies an offset of the field of type int -* in the vertex data block, to which the routine stores the number of -* a strongly connected component containing that vertex. If v_num < 0, -* no component numbers are stored. -* -* The components are numbered in arbitrary order from 1 to nc, where -* nc is the total number of components found, 0 <= nc <= |V|. However, -* the component numbering has the property that for every arc (i->j) -* in the graph the condition num(i) >= num(j) holds. -* -* RETURNS -* -* The routine returns nc, the total number of components found. */ - -int glp_strong_comp(glp_graph *G, int v_num) -{ glp_vertex *v; - glp_arc *a; - int i, k, last, n, na, nc, *icn, *ip, *lenr, *ior, *ib, *lowl, - *numb, *prev; - if (v_num >= 0 && v_num > G->v_size - (int)sizeof(int)) - xerror("glp_strong_comp: v_num = %d; invalid offset\n", - v_num); - n = G->nv; - if (n == 0) - { nc = 0; - goto done; - } - na = G->na; - icn = xcalloc(1+na, sizeof(int)); - ip = xcalloc(1+n, sizeof(int)); - lenr = xcalloc(1+n, sizeof(int)); - ior = xcalloc(1+n, sizeof(int)); - ib = xcalloc(1+n, sizeof(int)); - lowl = xcalloc(1+n, sizeof(int)); - numb = xcalloc(1+n, sizeof(int)); - prev = xcalloc(1+n, sizeof(int)); - k = 1; - for (i = 1; i <= n; i++) - { v = G->v[i]; - ip[i] = k; - for (a = v->out; a != NULL; a = a->t_next) - icn[k++] = a->head->i; - lenr[i] = k - ip[i]; - } - xassert(na == k-1); - nc = mc13d(n, icn, ip, lenr, ior, ib, lowl, numb, prev); - if (v_num >= 0) - { xassert(ib[1] == 1); - for (k = 1; k <= nc; k++) - { last = (k < nc ? ib[k+1] : n+1); - xassert(ib[k] < last); - for (i = ib[k]; i < last; i++) - { v = G->v[ior[i]]; - memcpy((char *)v->data + v_num, &k, sizeof(int)); - } - } - } - xfree(icn); - xfree(ip); - xfree(lenr); - xfree(ior); - xfree(ib); - xfree(lowl); - xfree(numb); - xfree(prev); -done: return nc; -} - -/*********************************************************************** -* NAME -* -* glp_top_sort - topological sorting of acyclic digraph -* -* SYNOPSIS -* -* int glp_top_sort(glp_graph *G, int v_num); -* -* DESCRIPTION -* -* The routine glp_top_sort performs topological sorting of vertices of -* the specified acyclic digraph. -* -* The parameter v_num specifies an offset of the field of type int in -* the vertex data block, to which the routine stores the vertex number -* assigned. If v_num < 0, vertex numbers are not stored. -* -* The vertices are numbered from 1 to n, where n is the total number -* of vertices in the graph. The vertex numbering has the property that -* for every arc (i->j) in the graph the condition num(i) < num(j) -* holds. Special case num(i) = 0 means that vertex i is not assigned a -* number, because the graph is *not* acyclic. -* -* RETURNS -* -* If the graph is acyclic and therefore all the vertices have been -* assigned numbers, the routine glp_top_sort returns zero. Otherwise, -* if the graph is not acyclic, the routine returns the number of -* vertices which have not been numbered, i.e. for which num(i) = 0. */ - -static int top_sort(glp_graph *G, int num[]) -{ glp_arc *a; - int i, j, cnt, top, *stack, *indeg; - /* allocate working arrays */ - indeg = xcalloc(1+G->nv, sizeof(int)); - stack = xcalloc(1+G->nv, sizeof(int)); - /* determine initial indegree of each vertex; push into the stack - the vertices having zero indegree */ - top = 0; - for (i = 1; i <= G->nv; i++) - { num[i] = indeg[i] = 0; - for (a = G->v[i]->in; a != NULL; a = a->h_next) - indeg[i]++; - if (indeg[i] == 0) - stack[++top] = i; - } - /* assign numbers to vertices in the sorted order */ - cnt = 0; - while (top > 0) - { /* pull vertex i from the stack */ - i = stack[top--]; - /* it has zero indegree in the current graph */ - xassert(indeg[i] == 0); - /* so assign it a next number */ - xassert(num[i] == 0); - num[i] = ++cnt; - /* remove vertex i from the current graph, update indegree of - its adjacent vertices, and push into the stack new vertices - whose indegree becomes zero */ - for (a = G->v[i]->out; a != NULL; a = a->t_next) - { j = a->head->i; - /* there exists arc (i->j) in the graph */ - xassert(indeg[j] > 0); - indeg[j]--; - if (indeg[j] == 0) - stack[++top] = j; - } - } - /* free working arrays */ - xfree(indeg); - xfree(stack); - return G->nv - cnt; -} - -int glp_top_sort(glp_graph *G, int v_num) -{ glp_vertex *v; - int i, cnt, *num; - if (v_num >= 0 && v_num > G->v_size - (int)sizeof(int)) - xerror("glp_top_sort: v_num = %d; invalid offset\n", v_num); - if (G->nv == 0) - { cnt = 0; - goto done; - } - num = xcalloc(1+G->nv, sizeof(int)); - cnt = top_sort(G, num); - if (v_num >= 0) - { for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - memcpy((char *)v->data + v_num, &num[i], sizeof(int)); - } - } - xfree(num); -done: return cnt; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi17.c b/resources/3rdparty/glpk-4.53/src/glpapi17.c deleted file mode 100644 index 425c6a5a8..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi17.c +++ /dev/null @@ -1,1269 +0,0 @@ -/* glpapi17.c (flow network problems) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "ffalg.h" -#include "mc21a.h" -#include "okalg.h" -#include "prob.h" -#include "relax4.h" - -/*********************************************************************** -* NAME -* -* glp_mincost_lp - convert minimum cost flow problem to LP -* -* SYNOPSIS -* -* void glp_mincost_lp(glp_prob *lp, glp_graph *G, int names, -* int v_rhs, int a_low, int a_cap, int a_cost); -* -* DESCRIPTION -* -* The routine glp_mincost_lp builds an LP problem, which corresponds -* to the minimum cost flow problem on the specified network G. */ - -void glp_mincost_lp(glp_prob *lp, glp_graph *G, int names, int v_rhs, - int a_low, int a_cap, int a_cost) -{ glp_vertex *v; - glp_arc *a; - int i, j, type, ind[1+2]; - double rhs, low, cap, cost, val[1+2]; - if (!(names == GLP_ON || names == GLP_OFF)) - xerror("glp_mincost_lp: names = %d; invalid parameter\n", - names); - if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) - xerror("glp_mincost_lp: v_rhs = %d; invalid offset\n", v_rhs); - if (a_low >= 0 && a_low > G->a_size - (int)sizeof(double)) - xerror("glp_mincost_lp: a_low = %d; invalid offset\n", a_low); - if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) - xerror("glp_mincost_lp: a_cap = %d; invalid offset\n", a_cap); - if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) - xerror("glp_mincost_lp: a_cost = %d; invalid offset\n", a_cost) - ; - glp_erase_prob(lp); - if (names) glp_set_prob_name(lp, G->name); - if (G->nv > 0) glp_add_rows(lp, G->nv); - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - if (names) glp_set_row_name(lp, i, v->name); - if (v_rhs >= 0) - memcpy(&rhs, (char *)v->data + v_rhs, sizeof(double)); - else - rhs = 0.0; - glp_set_row_bnds(lp, i, GLP_FX, rhs, rhs); - } - if (G->na > 0) glp_add_cols(lp, G->na); - for (i = 1, j = 0; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { j++; - if (names) - { char name[50+1]; - sprintf(name, "x[%d,%d]", a->tail->i, a->head->i); - xassert(strlen(name) < sizeof(name)); - glp_set_col_name(lp, j, name); - } - if (a->tail->i != a->head->i) - { ind[1] = a->tail->i, val[1] = +1.0; - ind[2] = a->head->i, val[2] = -1.0; - glp_set_mat_col(lp, j, 2, ind, val); - } - if (a_low >= 0) - memcpy(&low, (char *)a->data + a_low, sizeof(double)); - else - low = 0.0; - if (a_cap >= 0) - memcpy(&cap, (char *)a->data + a_cap, sizeof(double)); - else - cap = 1.0; - if (cap == DBL_MAX) - type = GLP_LO; - else if (low != cap) - type = GLP_DB; - else - type = GLP_FX; - glp_set_col_bnds(lp, j, type, low, cap); - if (a_cost >= 0) - memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); - else - cost = 0.0; - glp_set_obj_coef(lp, j, cost); - } - } - xassert(j == G->na); - return; -} - -/**********************************************************************/ - -int glp_mincost_okalg(glp_graph *G, int v_rhs, int a_low, int a_cap, - int a_cost, double *sol, int a_x, int v_pi) -{ /* find minimum-cost flow with out-of-kilter algorithm */ - glp_vertex *v; - glp_arc *a; - int nv, na, i, k, s, t, *tail, *head, *low, *cap, *cost, *x, *pi, - ret; - double sum, temp; - if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) - xerror("glp_mincost_okalg: v_rhs = %d; invalid offset\n", - v_rhs); - if (a_low >= 0 && a_low > G->a_size - (int)sizeof(double)) - xerror("glp_mincost_okalg: a_low = %d; invalid offset\n", - a_low); - if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) - xerror("glp_mincost_okalg: a_cap = %d; invalid offset\n", - a_cap); - if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) - xerror("glp_mincost_okalg: a_cost = %d; invalid offset\n", - a_cost); - if (a_x >= 0 && a_x > G->a_size - (int)sizeof(double)) - xerror("glp_mincost_okalg: a_x = %d; invalid offset\n", a_x); - if (v_pi >= 0 && v_pi > G->v_size - (int)sizeof(double)) - xerror("glp_mincost_okalg: v_pi = %d; invalid offset\n", v_pi); - /* s is artificial source node */ - s = G->nv + 1; - /* t is artificial sink node */ - t = s + 1; - /* nv is the total number of nodes in the resulting network */ - nv = t; - /* na is the total number of arcs in the resulting network */ - na = G->na + 1; - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - if (v_rhs >= 0) - memcpy(&temp, (char *)v->data + v_rhs, sizeof(double)); - else - temp = 0.0; - if (temp != 0.0) na++; - } - /* allocate working arrays */ - tail = xcalloc(1+na, sizeof(int)); - head = xcalloc(1+na, sizeof(int)); - low = xcalloc(1+na, sizeof(int)); - cap = xcalloc(1+na, sizeof(int)); - cost = xcalloc(1+na, sizeof(int)); - x = xcalloc(1+na, sizeof(int)); - pi = xcalloc(1+nv, sizeof(int)); - /* construct the resulting network */ - k = 0; - /* (original arcs) */ - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { k++; - tail[k] = a->tail->i; - head[k] = a->head->i; - if (tail[k] == head[k]) - { ret = GLP_EDATA; - goto done; - } - if (a_low >= 0) - memcpy(&temp, (char *)a->data + a_low, sizeof(double)); - else - temp = 0.0; - if (!(0.0 <= temp && temp <= (double)INT_MAX && - temp == floor(temp))) - { ret = GLP_EDATA; - goto done; - } - low[k] = (int)temp; - if (a_cap >= 0) - memcpy(&temp, (char *)a->data + a_cap, sizeof(double)); - else - temp = 1.0; - if (!((double)low[k] <= temp && temp <= (double)INT_MAX && - temp == floor(temp))) - { ret = GLP_EDATA; - goto done; - } - cap[k] = (int)temp; - if (a_cost >= 0) - memcpy(&temp, (char *)a->data + a_cost, sizeof(double)); - else - temp = 0.0; - if (!(fabs(temp) <= (double)INT_MAX && temp == floor(temp))) - { ret = GLP_EDATA; - goto done; - } - cost[k] = (int)temp; - } - } - /* (artificial arcs) */ - sum = 0.0; - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - if (v_rhs >= 0) - memcpy(&temp, (char *)v->data + v_rhs, sizeof(double)); - else - temp = 0.0; - if (!(fabs(temp) <= (double)INT_MAX && temp == floor(temp))) - { ret = GLP_EDATA; - goto done; - } - if (temp > 0.0) - { /* artificial arc from s to original source i */ - k++; - tail[k] = s; - head[k] = i; - low[k] = cap[k] = (int)(+temp); /* supply */ - cost[k] = 0; - sum += (double)temp; - } - else if (temp < 0.0) - { /* artificial arc from original sink i to t */ - k++; - tail[k] = i; - head[k] = t; - low[k] = cap[k] = (int)(-temp); /* demand */ - cost[k] = 0; - } - } - /* (feedback arc from t to s) */ - k++; - xassert(k == na); - tail[k] = t; - head[k] = s; - if (sum > (double)INT_MAX) - { ret = GLP_EDATA; - goto done; - } - low[k] = cap[k] = (int)sum; /* total supply/demand */ - cost[k] = 0; - /* find minimal-cost circulation in the resulting network */ - ret = okalg(nv, na, tail, head, low, cap, cost, x, pi); - switch (ret) - { case 0: - /* optimal circulation found */ - ret = 0; - break; - case 1: - /* no feasible circulation exists */ - ret = GLP_ENOPFS; - break; - case 2: - /* integer overflow occured */ - ret = GLP_ERANGE; - goto done; - case 3: - /* optimality test failed (logic error) */ - ret = GLP_EFAIL; - goto done; - default: - xassert(ret != ret); - } - /* store solution components */ - /* (objective function = the total cost) */ - if (sol != NULL) - { temp = 0.0; - for (k = 1; k <= na; k++) - temp += (double)cost[k] * (double)x[k]; - *sol = temp; - } - /* (arc flows) */ - if (a_x >= 0) - { k = 0; - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { temp = (double)x[++k]; - memcpy((char *)a->data + a_x, &temp, sizeof(double)); - } - } - } - /* (node potentials = Lagrange multipliers) */ - if (v_pi >= 0) - { for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - temp = - (double)pi[i]; - memcpy((char *)v->data + v_pi, &temp, sizeof(double)); - } - } -done: /* free working arrays */ - xfree(tail); - xfree(head); - xfree(low); - xfree(cap); - xfree(cost); - xfree(x); - xfree(pi); - return ret; -} - -/**********************************************************************/ - -static int overflow(int u, int v) -{ /* check for integer overflow on computing u + v */ - if (u > 0 && v > 0 && u + v < 0) return 1; - if (u < 0 && v < 0 && u + v > 0) return 1; - return 0; -} - -int glp_mincost_relax4(glp_graph *G, int v_rhs, int a_low, int a_cap, - int a_cost, int crash, double *sol, int a_x, int a_rc) -{ /* find minimum-cost flow with Bertsekas-Tseng relaxation method - (RELAX-IV) */ - glp_vertex *v; - glp_arc *a; - struct relax4_csa csa; - int i, k, large, n, na, ret; - double cap, cost, low, rc, rhs, sum, x; - if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) - xerror("glp_mincost_relax4: v_rhs = %d; invalid offset\n", - v_rhs); - if (a_low >= 0 && a_low > G->a_size - (int)sizeof(double)) - xerror("glp_mincost_relax4: a_low = %d; invalid offset\n", - a_low); - if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) - xerror("glp_mincost_relax4: a_cap = %d; invalid offset\n", - a_cap); - if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) - xerror("glp_mincost_relax4: a_cost = %d; invalid offset\n", - a_cost); - if (a_x >= 0 && a_x > G->a_size - (int)sizeof(double)) - xerror("glp_mincost_relax4: a_x = %d; invalid offset\n", - a_x); - if (a_rc >= 0 && a_rc > G->a_size - (int)sizeof(double)) - xerror("glp_mincost_relax4: a_rc = %d; invalid offset\n", - a_rc); - csa.n = n = G->nv; /* number of nodes */ - csa.na = na = G->na; /* number of arcs */ - csa.large = large = INT_MAX / 4; - csa.repeat = 0; - csa.crash = crash; - /* allocate working arrays */ - csa.startn = xcalloc(1+na, sizeof(int)); - csa.endn = xcalloc(1+na, sizeof(int)); - csa.fou = xcalloc(1+n, sizeof(int)); - csa.nxtou = xcalloc(1+na, sizeof(int)); - csa.fin = xcalloc(1+n, sizeof(int)); - csa.nxtin = xcalloc(1+na, sizeof(int)); - csa.rc = xcalloc(1+na, sizeof(int)); - csa.u = xcalloc(1+na, sizeof(int)); - csa.dfct = xcalloc(1+n, sizeof(int)); - csa.x = xcalloc(1+na, sizeof(int)); - csa.label = xcalloc(1+n, sizeof(int)); - csa.prdcsr = xcalloc(1+n, sizeof(int)); - csa.save = xcalloc(1+na, sizeof(int)); - csa.tfstou = xcalloc(1+n, sizeof(int)); - csa.tnxtou = xcalloc(1+na, sizeof(int)); - csa.tfstin = xcalloc(1+n, sizeof(int)); - csa.tnxtin = xcalloc(1+na, sizeof(int)); - csa.nxtqueue = xcalloc(1+n, sizeof(int)); - csa.scan = xcalloc(1+n, sizeof(char)); - csa.mark = xcalloc(1+n, sizeof(char)); - if (crash) - { csa.extend_arc = xcalloc(1+n, sizeof(int)); - csa.sb_level = xcalloc(1+n, sizeof(int)); - csa.sb_arc = xcalloc(1+n, sizeof(int)); - } - else - { csa.extend_arc = NULL; - csa.sb_level = NULL; - csa.sb_arc = NULL; - } - /* scan nodes */ - for (i = 1; i <= n; i++) - { v = G->v[i]; - /* get supply at i-th node */ - if (v_rhs >= 0) - memcpy(&rhs, (char *)v->data + v_rhs, sizeof(double)); - else - rhs = 0.0; - if (!(fabs(rhs) <= (double)large && rhs == floor(rhs))) - { ret = GLP_EDATA; - goto done; - } - /* set demand at i-th node */ - csa.dfct[i] = -(int)rhs; - } - /* scan arcs */ - k = 0; - for (i = 1; i <= n; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { k++; - /* set endpoints of k-th arc */ - if (a->tail->i == a->head->i) - { /* self-loops not allowed */ - ret = GLP_EDATA; - goto done; - } - csa.startn[k] = a->tail->i; - csa.endn[k] = a->head->i; - /* set per-unit cost for k-th arc flow */ - if (a_cost >= 0) - memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); - else - cost = 0.0; - if (!(fabs(cost) <= (double)large && cost == floor(cost))) - { ret = GLP_EDATA; - goto done; - } - csa.rc[k] = (int)cost; - /* get lower bound for k-th arc flow */ - if (a_low >= 0) - memcpy(&low, (char *)a->data + a_low, sizeof(double)); - else - low = 0.0; - if (!(0.0 <= low && low <= (double)large && - low == floor(low))) - { ret = GLP_EDATA; - goto done; - } - /* get upper bound for k-th arc flow */ - if (a_cap >= 0) - memcpy(&cap, (char *)a->data + a_cap, sizeof(double)); - else - cap = 1.0; - if (!(low <= cap && cap <= (double)large && - cap == floor(cap))) - { ret = GLP_EDATA; - goto done; - } - /* substitute x = x' + low, where 0 <= x' <= cap - low */ - csa.u[k] = (int)(cap - low); - /* correct demands at endpoints of k-th arc */ - if (overflow(csa.dfct[a->tail->i], +low)) - { ret = GLP_ERANGE; - goto done; - } - csa.dfct[a->tail->i] += low; - if (overflow(csa.dfct[a->head->i], -low)) - { ret = GLP_ERANGE; - goto done; - } - csa.dfct[a->head->i] -= low; - } - } - /* construct linked list for network topology */ - relax4_inidat(&csa); - /* find minimum-cost flow */ - ret = relax4(&csa); - if (ret != 0) - { /* problem is found to be infeasible */ - xassert(1 <= ret && ret <= 8); - ret = GLP_ENOPFS; - goto done; - } - /* store solution */ - sum = 0.0; - k = 0; - for (i = 1; i <= n; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { k++; - /* get lower bound for k-th arc flow */ - if (a_low >= 0) - memcpy(&low, (char *)a->data + a_low, sizeof(double)); - else - low = 0.0; - /* store original flow x = x' + low thru k-th arc */ - x = (double)csa.x[k] + low; - if (a_x >= 0) - memcpy((char *)a->data + a_x, &x, sizeof(double)); - /* store reduced cost for k-th arc flow */ - rc = (double)csa.rc[k]; - if (a_rc >= 0) - memcpy((char *)a->data + a_rc, &rc, sizeof(double)); - /* get per-unit cost for k-th arc flow */ - if (a_cost >= 0) - memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); - else - cost = 0.0; - /* compute the total cost */ - sum += cost * x; - } - } - /* store the total cost */ - if (sol != NULL) - *sol = sum; -done: /* free working arrays */ - xfree(csa.startn); - xfree(csa.endn); - xfree(csa.fou); - xfree(csa.nxtou); - xfree(csa.fin); - xfree(csa.nxtin); - xfree(csa.rc); - xfree(csa.u); - xfree(csa.dfct); - xfree(csa.x); - xfree(csa.label); - xfree(csa.prdcsr); - xfree(csa.save); - xfree(csa.tfstou); - xfree(csa.tnxtou); - xfree(csa.tfstin); - xfree(csa.tnxtin); - xfree(csa.nxtqueue); - xfree(csa.scan); - xfree(csa.mark); - if (crash) - { xfree(csa.extend_arc); - xfree(csa.sb_level); - xfree(csa.sb_arc); - } - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_maxflow_lp - convert maximum flow problem to LP -* -* SYNOPSIS -* -* void glp_maxflow_lp(glp_prob *lp, glp_graph *G, int names, int s, -* int t, int a_cap); -* -* DESCRIPTION -* -* The routine glp_maxflow_lp builds an LP problem, which corresponds -* to the maximum flow problem on the specified network G. */ - -void glp_maxflow_lp(glp_prob *lp, glp_graph *G, int names, int s, - int t, int a_cap) -{ glp_vertex *v; - glp_arc *a; - int i, j, type, ind[1+2]; - double cap, val[1+2]; - if (!(names == GLP_ON || names == GLP_OFF)) - xerror("glp_maxflow_lp: names = %d; invalid parameter\n", - names); - if (!(1 <= s && s <= G->nv)) - xerror("glp_maxflow_lp: s = %d; source node number out of rang" - "e\n", s); - if (!(1 <= t && t <= G->nv)) - xerror("glp_maxflow_lp: t = %d: sink node number out of range " - "\n", t); - if (s == t) - xerror("glp_maxflow_lp: s = t = %d; source and sink nodes must" - " be distinct\n", s); - if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) - xerror("glp_maxflow_lp: a_cap = %d; invalid offset\n", a_cap); - glp_erase_prob(lp); - if (names) glp_set_prob_name(lp, G->name); - glp_set_obj_dir(lp, GLP_MAX); - glp_add_rows(lp, G->nv); - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - if (names) glp_set_row_name(lp, i, v->name); - if (i == s) - type = GLP_LO; - else if (i == t) - type = GLP_UP; - else - type = GLP_FX; - glp_set_row_bnds(lp, i, type, 0.0, 0.0); - } - if (G->na > 0) glp_add_cols(lp, G->na); - for (i = 1, j = 0; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { j++; - if (names) - { char name[50+1]; - sprintf(name, "x[%d,%d]", a->tail->i, a->head->i); - xassert(strlen(name) < sizeof(name)); - glp_set_col_name(lp, j, name); - } - if (a->tail->i != a->head->i) - { ind[1] = a->tail->i, val[1] = +1.0; - ind[2] = a->head->i, val[2] = -1.0; - glp_set_mat_col(lp, j, 2, ind, val); - } - if (a_cap >= 0) - memcpy(&cap, (char *)a->data + a_cap, sizeof(double)); - else - cap = 1.0; - if (cap == DBL_MAX) - type = GLP_LO; - else if (cap != 0.0) - type = GLP_DB; - else - type = GLP_FX; - glp_set_col_bnds(lp, j, type, 0.0, cap); - if (a->tail->i == s) - glp_set_obj_coef(lp, j, +1.0); - else if (a->head->i == s) - glp_set_obj_coef(lp, j, -1.0); - } - } - xassert(j == G->na); - return; -} - -int glp_maxflow_ffalg(glp_graph *G, int s, int t, int a_cap, - double *sol, int a_x, int v_cut) -{ /* find maximal flow with Ford-Fulkerson algorithm */ - glp_vertex *v; - glp_arc *a; - int nv, na, i, k, flag, *tail, *head, *cap, *x, ret; - char *cut; - double temp; - if (!(1 <= s && s <= G->nv)) - xerror("glp_maxflow_ffalg: s = %d; source node number out of r" - "ange\n", s); - if (!(1 <= t && t <= G->nv)) - xerror("glp_maxflow_ffalg: t = %d: sink node number out of ran" - "ge\n", t); - if (s == t) - xerror("glp_maxflow_ffalg: s = t = %d; source and sink nodes m" - "ust be distinct\n", s); - if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) - xerror("glp_maxflow_ffalg: a_cap = %d; invalid offset\n", - a_cap); - if (v_cut >= 0 && v_cut > G->v_size - (int)sizeof(int)) - xerror("glp_maxflow_ffalg: v_cut = %d; invalid offset\n", - v_cut); - /* allocate working arrays */ - nv = G->nv; - na = G->na; - tail = xcalloc(1+na, sizeof(int)); - head = xcalloc(1+na, sizeof(int)); - cap = xcalloc(1+na, sizeof(int)); - x = xcalloc(1+na, sizeof(int)); - if (v_cut < 0) - cut = NULL; - else - cut = xcalloc(1+nv, sizeof(char)); - /* copy the flow network */ - k = 0; - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { k++; - tail[k] = a->tail->i; - head[k] = a->head->i; - if (tail[k] == head[k]) - { ret = GLP_EDATA; - goto done; - } - if (a_cap >= 0) - memcpy(&temp, (char *)a->data + a_cap, sizeof(double)); - else - temp = 1.0; - if (!(0.0 <= temp && temp <= (double)INT_MAX && - temp == floor(temp))) - { ret = GLP_EDATA; - goto done; - } - cap[k] = (int)temp; - } - } - xassert(k == na); - /* find maximal flow in the flow network */ - ffalg(nv, na, tail, head, s, t, cap, x, cut); - ret = 0; - /* store solution components */ - /* (objective function = total flow through the network) */ - if (sol != NULL) - { temp = 0.0; - for (k = 1; k <= na; k++) - { if (tail[k] == s) - temp += (double)x[k]; - else if (head[k] == s) - temp -= (double)x[k]; - } - *sol = temp; - } - /* (arc flows) */ - if (a_x >= 0) - { k = 0; - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { temp = (double)x[++k]; - memcpy((char *)a->data + a_x, &temp, sizeof(double)); - } - } - } - /* (node flags) */ - if (v_cut >= 0) - { for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - flag = cut[i]; - memcpy((char *)v->data + v_cut, &flag, sizeof(int)); - } - } -done: /* free working arrays */ - xfree(tail); - xfree(head); - xfree(cap); - xfree(x); - if (cut != NULL) xfree(cut); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_check_asnprob - check correctness of assignment problem data -* -* SYNOPSIS -* -* int glp_check_asnprob(glp_graph *G, int v_set); -* -* RETURNS -* -* If the specified assignment problem data are correct, the routine -* glp_check_asnprob returns zero, otherwise, non-zero. */ - -int glp_check_asnprob(glp_graph *G, int v_set) -{ glp_vertex *v; - int i, k, ret = 0; - if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) - xerror("glp_check_asnprob: v_set = %d; invalid offset\n", - v_set); - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - if (v_set >= 0) - { memcpy(&k, (char *)v->data + v_set, sizeof(int)); - if (k == 0) - { if (v->in != NULL) - { ret = 1; - break; - } - } - else if (k == 1) - { if (v->out != NULL) - { ret = 2; - break; - } - } - else - { ret = 3; - break; - } - } - else - { if (v->in != NULL && v->out != NULL) - { ret = 4; - break; - } - } - } - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_asnprob_lp - convert assignment problem to LP -* -* SYNOPSIS -* -* int glp_asnprob_lp(glp_prob *P, int form, glp_graph *G, int names, -* int v_set, int a_cost); -* -* DESCRIPTION -* -* The routine glp_asnprob_lp builds an LP problem, which corresponds -* to the assignment problem on the specified graph G. -* -* RETURNS -* -* If the LP problem has been successfully built, the routine returns -* zero, otherwise, non-zero. */ - -int glp_asnprob_lp(glp_prob *P, int form, glp_graph *G, int names, - int v_set, int a_cost) -{ glp_vertex *v; - glp_arc *a; - int i, j, ret, ind[1+2]; - double cost, val[1+2]; - if (!(form == GLP_ASN_MIN || form == GLP_ASN_MAX || - form == GLP_ASN_MMP)) - xerror("glp_asnprob_lp: form = %d; invalid parameter\n", - form); - if (!(names == GLP_ON || names == GLP_OFF)) - xerror("glp_asnprob_lp: names = %d; invalid parameter\n", - names); - if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) - xerror("glp_asnprob_lp: v_set = %d; invalid offset\n", - v_set); - if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) - xerror("glp_asnprob_lp: a_cost = %d; invalid offset\n", - a_cost); - ret = glp_check_asnprob(G, v_set); - if (ret != 0) goto done; - glp_erase_prob(P); - if (names) glp_set_prob_name(P, G->name); - glp_set_obj_dir(P, form == GLP_ASN_MIN ? GLP_MIN : GLP_MAX); - if (G->nv > 0) glp_add_rows(P, G->nv); - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - if (names) glp_set_row_name(P, i, v->name); - glp_set_row_bnds(P, i, form == GLP_ASN_MMP ? GLP_UP : GLP_FX, - 1.0, 1.0); - } - if (G->na > 0) glp_add_cols(P, G->na); - for (i = 1, j = 0; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { j++; - if (names) - { char name[50+1]; - sprintf(name, "x[%d,%d]", a->tail->i, a->head->i); - xassert(strlen(name) < sizeof(name)); - glp_set_col_name(P, j, name); - } - ind[1] = a->tail->i, val[1] = +1.0; - ind[2] = a->head->i, val[2] = +1.0; - glp_set_mat_col(P, j, 2, ind, val); - glp_set_col_bnds(P, j, GLP_DB, 0.0, 1.0); - if (a_cost >= 0) - memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); - else - cost = 1.0; - glp_set_obj_coef(P, j, cost); - } - } - xassert(j == G->na); -done: return ret; -} - -/**********************************************************************/ - -int glp_asnprob_okalg(int form, glp_graph *G, int v_set, int a_cost, - double *sol, int a_x) -{ /* solve assignment problem with out-of-kilter algorithm */ - glp_vertex *v; - glp_arc *a; - int nv, na, i, k, *tail, *head, *low, *cap, *cost, *x, *pi, ret; - double temp; - if (!(form == GLP_ASN_MIN || form == GLP_ASN_MAX || - form == GLP_ASN_MMP)) - xerror("glp_asnprob_okalg: form = %d; invalid parameter\n", - form); - if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) - xerror("glp_asnprob_okalg: v_set = %d; invalid offset\n", - v_set); - if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) - xerror("glp_asnprob_okalg: a_cost = %d; invalid offset\n", - a_cost); - if (a_x >= 0 && a_x > G->a_size - (int)sizeof(int)) - xerror("glp_asnprob_okalg: a_x = %d; invalid offset\n", a_x); - if (glp_check_asnprob(G, v_set)) - return GLP_EDATA; - /* nv is the total number of nodes in the resulting network */ - nv = G->nv + 1; - /* na is the total number of arcs in the resulting network */ - na = G->na + G->nv; - /* allocate working arrays */ - tail = xcalloc(1+na, sizeof(int)); - head = xcalloc(1+na, sizeof(int)); - low = xcalloc(1+na, sizeof(int)); - cap = xcalloc(1+na, sizeof(int)); - cost = xcalloc(1+na, sizeof(int)); - x = xcalloc(1+na, sizeof(int)); - pi = xcalloc(1+nv, sizeof(int)); - /* construct the resulting network */ - k = 0; - /* (original arcs) */ - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { k++; - tail[k] = a->tail->i; - head[k] = a->head->i; - low[k] = 0; - cap[k] = 1; - if (a_cost >= 0) - memcpy(&temp, (char *)a->data + a_cost, sizeof(double)); - else - temp = 1.0; - if (!(fabs(temp) <= (double)INT_MAX && temp == floor(temp))) - { ret = GLP_EDATA; - goto done; - } - cost[k] = (int)temp; - if (form != GLP_ASN_MIN) cost[k] = - cost[k]; - } - } - /* (artificial arcs) */ - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - k++; - if (v->out == NULL) - tail[k] = i, head[k] = nv; - else if (v->in == NULL) - tail[k] = nv, head[k] = i; - else - xassert(v != v); - low[k] = (form == GLP_ASN_MMP ? 0 : 1); - cap[k] = 1; - cost[k] = 0; - } - xassert(k == na); - /* find minimal-cost circulation in the resulting network */ - ret = okalg(nv, na, tail, head, low, cap, cost, x, pi); - switch (ret) - { case 0: - /* optimal circulation found */ - ret = 0; - break; - case 1: - /* no feasible circulation exists */ - ret = GLP_ENOPFS; - break; - case 2: - /* integer overflow occured */ - ret = GLP_ERANGE; - goto done; - case 3: - /* optimality test failed (logic error) */ - ret = GLP_EFAIL; - goto done; - default: - xassert(ret != ret); - } - /* store solution components */ - /* (objective function = the total cost) */ - if (sol != NULL) - { temp = 0.0; - for (k = 1; k <= na; k++) - temp += (double)cost[k] * (double)x[k]; - if (form != GLP_ASN_MIN) temp = - temp; - *sol = temp; - } - /* (arc flows) */ - if (a_x >= 0) - { k = 0; - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { k++; - if (ret == 0) - xassert(x[k] == 0 || x[k] == 1); - memcpy((char *)a->data + a_x, &x[k], sizeof(int)); - } - } - } -done: /* free working arrays */ - xfree(tail); - xfree(head); - xfree(low); - xfree(cap); - xfree(cost); - xfree(x); - xfree(pi); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_asnprob_hall - find bipartite matching of maximum cardinality -* -* SYNOPSIS -* -* int glp_asnprob_hall(glp_graph *G, int v_set, int a_x); -* -* DESCRIPTION -* -* The routine glp_asnprob_hall finds a matching of maximal cardinality -* in the specified bipartite graph G. It uses a version of the Fortran -* routine MC21A developed by I.S.Duff [1], which implements Hall's -* algorithm [2]. -* -* RETURNS -* -* The routine glp_asnprob_hall returns the cardinality of the matching -* found. However, if the specified graph is incorrect (as detected by -* the routine glp_check_asnprob), the routine returns negative value. -* -* REFERENCES -* -* 1. I.S.Duff, Algorithm 575: Permutations for zero-free diagonal, ACM -* Trans. on Math. Softw. 7 (1981), 387-390. -* -* 2. M.Hall, "An Algorithm for distinct representatives," Amer. Math. -* Monthly 63 (1956), 716-717. */ - -int glp_asnprob_hall(glp_graph *G, int v_set, int a_x) -{ glp_vertex *v; - glp_arc *a; - int card, i, k, loc, n, n1, n2, xij; - int *num, *icn, *ip, *lenr, *iperm, *pr, *arp, *cv, *out; - if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) - xerror("glp_asnprob_hall: v_set = %d; invalid offset\n", - v_set); - if (a_x >= 0 && a_x > G->a_size - (int)sizeof(int)) - xerror("glp_asnprob_hall: a_x = %d; invalid offset\n", a_x); - if (glp_check_asnprob(G, v_set)) - return -1; - /* determine the number of vertices in sets R and S and renumber - vertices in S which correspond to columns of the matrix; skip - all isolated vertices */ - num = xcalloc(1+G->nv, sizeof(int)); - n1 = n2 = 0; - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - if (v->in == NULL && v->out != NULL) - n1++, num[i] = 0; /* vertex in R */ - else if (v->in != NULL && v->out == NULL) - n2++, num[i] = n2; /* vertex in S */ - else - { xassert(v->in == NULL && v->out == NULL); - num[i] = -1; /* isolated vertex */ - } - } - /* the matrix must be square, thus, if it has more columns than - rows, extra rows will be just empty, and vice versa */ - n = (n1 >= n2 ? n1 : n2); - /* allocate working arrays */ - icn = xcalloc(1+G->na, sizeof(int)); - ip = xcalloc(1+n, sizeof(int)); - lenr = xcalloc(1+n, sizeof(int)); - iperm = xcalloc(1+n, sizeof(int)); - pr = xcalloc(1+n, sizeof(int)); - arp = xcalloc(1+n, sizeof(int)); - cv = xcalloc(1+n, sizeof(int)); - out = xcalloc(1+n, sizeof(int)); - /* build the adjacency matrix of the bipartite graph in row-wise - format (rows are vertices in R, columns are vertices in S) */ - k = 0, loc = 1; - for (i = 1; i <= G->nv; i++) - { if (num[i] != 0) continue; - /* vertex i in R */ - ip[++k] = loc; - v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { xassert(num[a->head->i] != 0); - icn[loc++] = num[a->head->i]; - } - lenr[k] = loc - ip[k]; - } - xassert(loc-1 == G->na); - /* make all extra rows empty (all extra columns are empty due to - the row-wise format used) */ - for (k++; k <= n; k++) - ip[k] = loc, lenr[k] = 0; - /* find a row permutation that maximizes the number of non-zeros - on the main diagonal */ - card = mc21a(n, icn, ip, lenr, iperm, pr, arp, cv, out); -#if 1 /* 18/II-2010 */ - /* FIXED: if card = n, arp remains clobbered on exit */ - for (i = 1; i <= n; i++) - arp[i] = 0; - for (i = 1; i <= card; i++) - { k = iperm[i]; - xassert(1 <= k && k <= n); - xassert(arp[k] == 0); - arp[k] = i; - } -#endif - /* store solution, if necessary */ - if (a_x < 0) goto skip; - k = 0; - for (i = 1; i <= G->nv; i++) - { if (num[i] != 0) continue; - /* vertex i in R */ - k++; - v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { /* arp[k] is the number of matched column or zero */ - if (arp[k] == num[a->head->i]) - { xassert(arp[k] != 0); - xij = 1; - } - else - xij = 0; - memcpy((char *)a->data + a_x, &xij, sizeof(int)); - } - } -skip: /* free working arrays */ - xfree(num); - xfree(icn); - xfree(ip); - xfree(lenr); - xfree(iperm); - xfree(pr); - xfree(arp); - xfree(cv); - xfree(out); - return card; -} - -/*********************************************************************** -* NAME -* -* glp_cpp - solve critical path problem -* -* SYNOPSIS -* -* double glp_cpp(glp_graph *G, int v_t, int v_es, int v_ls); -* -* DESCRIPTION -* -* The routine glp_cpp solves the critical path problem represented in -* the form of the project network. -* -* The parameter G is a pointer to the graph object, which specifies -* the project network. This graph must be acyclic. Multiple arcs are -* allowed being considered as single arcs. -* -* The parameter v_t specifies an offset of the field of type double -* in the vertex data block, which contains time t[i] >= 0 needed to -* perform corresponding job j. If v_t < 0, it is assumed that t[i] = 1 -* for all jobs. -* -* The parameter v_es specifies an offset of the field of type double -* in the vertex data block, to which the routine stores earliest start -* time for corresponding job. If v_es < 0, this time is not stored. -* -* The parameter v_ls specifies an offset of the field of type double -* in the vertex data block, to which the routine stores latest start -* time for corresponding job. If v_ls < 0, this time is not stored. -* -* RETURNS -* -* The routine glp_cpp returns the minimal project duration, that is, -* minimal time needed to perform all jobs in the project. */ - -static void sorting(glp_graph *G, int list[]); - -double glp_cpp(glp_graph *G, int v_t, int v_es, int v_ls) -{ glp_vertex *v; - glp_arc *a; - int i, j, k, nv, *list; - double temp, total, *t, *es, *ls; - if (v_t >= 0 && v_t > G->v_size - (int)sizeof(double)) - xerror("glp_cpp: v_t = %d; invalid offset\n", v_t); - if (v_es >= 0 && v_es > G->v_size - (int)sizeof(double)) - xerror("glp_cpp: v_es = %d; invalid offset\n", v_es); - if (v_ls >= 0 && v_ls > G->v_size - (int)sizeof(double)) - xerror("glp_cpp: v_ls = %d; invalid offset\n", v_ls); - nv = G->nv; - if (nv == 0) - { total = 0.0; - goto done; - } - /* allocate working arrays */ - t = xcalloc(1+nv, sizeof(double)); - es = xcalloc(1+nv, sizeof(double)); - ls = xcalloc(1+nv, sizeof(double)); - list = xcalloc(1+nv, sizeof(int)); - /* retrieve job times */ - for (i = 1; i <= nv; i++) - { v = G->v[i]; - if (v_t >= 0) - { memcpy(&t[i], (char *)v->data + v_t, sizeof(double)); - if (t[i] < 0.0) - xerror("glp_cpp: t[%d] = %g; invalid time\n", i, t[i]); - } - else - t[i] = 1.0; - } - /* perform topological sorting to determine the list of nodes - (jobs) such that if list[k] = i and list[kk] = j and there - exists arc (i->j), then k < kk */ - sorting(G, list); - /* FORWARD PASS */ - /* determine earliest start times */ - for (k = 1; k <= nv; k++) - { j = list[k]; - es[j] = 0.0; - for (a = G->v[j]->in; a != NULL; a = a->h_next) - { i = a->tail->i; - /* there exists arc (i->j) in the project network */ - temp = es[i] + t[i]; - if (es[j] < temp) es[j] = temp; - } - } - /* determine the minimal project duration */ - total = 0.0; - for (i = 1; i <= nv; i++) - { temp = es[i] + t[i]; - if (total < temp) total = temp; - } - /* BACKWARD PASS */ - /* determine latest start times */ - for (k = nv; k >= 1; k--) - { i = list[k]; - ls[i] = total - t[i]; - for (a = G->v[i]->out; a != NULL; a = a->t_next) - { j = a->head->i; - /* there exists arc (i->j) in the project network */ - temp = ls[j] - t[i]; - if (ls[i] > temp) ls[i] = temp; - } - /* avoid possible round-off errors */ - if (ls[i] < es[i]) ls[i] = es[i]; - } - /* store results, if necessary */ - if (v_es >= 0) - { for (i = 1; i <= nv; i++) - { v = G->v[i]; - memcpy((char *)v->data + v_es, &es[i], sizeof(double)); - } - } - if (v_ls >= 0) - { for (i = 1; i <= nv; i++) - { v = G->v[i]; - memcpy((char *)v->data + v_ls, &ls[i], sizeof(double)); - } - } - /* free working arrays */ - xfree(t); - xfree(es); - xfree(ls); - xfree(list); -done: return total; -} - -static void sorting(glp_graph *G, int list[]) -{ /* perform topological sorting to determine the list of nodes - (jobs) such that if list[k] = i and list[kk] = j and there - exists arc (i->j), then k < kk */ - int i, k, nv, v_size, *num; - void **save; - nv = G->nv; - v_size = G->v_size; - save = xcalloc(1+nv, sizeof(void *)); - num = xcalloc(1+nv, sizeof(int)); - G->v_size = sizeof(int); - for (i = 1; i <= nv; i++) - { save[i] = G->v[i]->data; - G->v[i]->data = &num[i]; - list[i] = 0; - } - if (glp_top_sort(G, 0) != 0) - xerror("glp_cpp: project network is not acyclic\n"); - G->v_size = v_size; - for (i = 1; i <= nv; i++) - { G->v[i]->data = save[i]; - k = num[i]; - xassert(1 <= k && k <= nv); - xassert(list[k] == 0); - list[k] = i; - } - xfree(save); - xfree(num); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi18.c b/resources/3rdparty/glpk-4.53/src/glpapi18.c deleted file mode 100644 index 07ab490d5..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi18.c +++ /dev/null @@ -1,123 +0,0 @@ -/* glpapi18.c (maximum clique problem) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "prob.h" -#include "wclique.h" - -static void set_edge(int nv, unsigned char a[], int i, int j) -{ int k; - xassert(1 <= j && j < i && i <= nv); - k = ((i - 1) * (i - 2)) / 2 + (j - 1); - a[k / CHAR_BIT] |= - (unsigned char)(1 << ((CHAR_BIT - 1) - k % CHAR_BIT)); - return; -} - -int glp_wclique_exact(glp_graph *G, int v_wgt, double *sol, int v_set) -{ /* find maximum weight clique with exact algorithm */ - glp_arc *e; - int i, j, k, len, x, *w, *ind, ret = 0; - unsigned char *a; - double s, t; - if (v_wgt >= 0 && v_wgt > G->v_size - (int)sizeof(double)) - xerror("glp_wclique_exact: v_wgt = %d; invalid parameter\n", - v_wgt); - if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) - xerror("glp_wclique_exact: v_set = %d; invalid parameter\n", - v_set); - if (G->nv == 0) - { /* empty graph has only empty clique */ - if (sol != NULL) *sol = 0.0; - return 0; - } - /* allocate working arrays */ - w = xcalloc(1+G->nv, sizeof(int)); - ind = xcalloc(1+G->nv, sizeof(int)); - len = G->nv; /* # vertices */ - len = len * (len - 1) / 2; /* # entries in lower triangle */ - len = (len + (CHAR_BIT - 1)) / CHAR_BIT; /* # bytes needed */ - a = xcalloc(len, sizeof(char)); - memset(a, 0, len * sizeof(char)); - /* determine vertex weights */ - s = 0.0; - for (i = 1; i <= G->nv; i++) - { if (v_wgt >= 0) - { memcpy(&t, (char *)G->v[i]->data + v_wgt, sizeof(double)); - if (!(0.0 <= t && t <= (double)INT_MAX && t == floor(t))) - { ret = GLP_EDATA; - goto done; - } - w[i] = (int)t; - } - else - w[i] = 1; - s += (double)w[i]; - } - if (s > (double)INT_MAX) - { ret = GLP_EDATA; - goto done; - } - /* build the adjacency matrix */ - for (i = 1; i <= G->nv; i++) - { for (e = G->v[i]->in; e != NULL; e = e->h_next) - { j = e->tail->i; - /* there exists edge (j,i) in the graph */ - if (i > j) set_edge(G->nv, a, i, j); - } - for (e = G->v[i]->out; e != NULL; e = e->t_next) - { j = e->head->i; - /* there exists edge (i,j) in the graph */ - if (i > j) set_edge(G->nv, a, i, j); - } - } - /* find maximum weight clique in the graph */ - len = wclique(G->nv, w, a, ind); - /* compute the clique weight */ - s = 0.0; - for (k = 1; k <= len; k++) - { i = ind[k]; - xassert(1 <= i && i <= G->nv); - s += (double)w[i]; - } - if (sol != NULL) *sol = s; - /* mark vertices included in the clique */ - if (v_set >= 0) - { x = 0; - for (i = 1; i <= G->nv; i++) - memcpy((char *)G->v[i]->data + v_set, &x, sizeof(int)); - x = 1; - for (k = 1; k <= len; k++) - { i = ind[k]; - memcpy((char *)G->v[i]->data + v_set, &x, sizeof(int)); - } - } -done: /* free working arrays */ - xfree(w); - xfree(ind); - xfree(a); - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi19.c b/resources/3rdparty/glpk-4.53/src/glpapi19.c deleted file mode 100644 index 49fee3898..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi19.c +++ /dev/null @@ -1,133 +0,0 @@ -/* glpapi19.c (driver to MiniSat solver) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "minisat.h" -#include "prob.h" - -int glp_minisat1(glp_prob *P) -{ /* solve CNF-SAT problem with MiniSat solver */ - solver *s; - GLPAIJ *aij; - int i, j, len, ret, *ind; - double sum; - /* check problem object */ - if (P == NULL || P->magic != GLP_PROB_MAGIC) - xerror("glp_minisat1: P = %p; invalid problem object\n", - P); - if (P->tree != NULL) - xerror("glp_minisat1: operation not allowed\n"); - /* integer solution is currently undefined */ - P->mip_stat = GLP_UNDEF; - P->mip_obj = 0.0; - /* check that problem object encodes CNF-SAT instance */ - if (glp_check_cnfsat(P) != 0) - { xprintf("glp_minisat1: problem object does not encode CNF-SAT " - "instance\n"); - ret = GLP_EDATA; - goto done; - } - /* solve CNF-SAT problem */ - xprintf("Solving CNF-SAT problem...\n"); - xprintf("Instance has %d variable%s, %d clause%s, and %d literal%" - "s\n", P->n, P->n == 1 ? "" : "s", P->m, P->m == 1 ? "" : "s", - P->nnz, P->nnz == 1 ? "" : "s"); - /* if CNF-SAT has no clauses, it is satisfiable */ - if (P->m == 0) - { P->mip_stat = GLP_OPT; - for (j = 1; j <= P->n; j++) - P->col[j]->mipx = 0.0; - goto fini; - } - /* if CNF-SAT has an empty clause, it is unsatisfiable */ - for (i = 1; i <= P->m; i++) - { if (P->row[i]->ptr == NULL) - { P->mip_stat = GLP_NOFEAS; - goto fini; - } - } - /* prepare input data for the solver */ - s = solver_new(); - solver_setnvars(s, P->n); - ind = xcalloc(1+P->n, sizeof(int)); - for (i = 1; i <= P->m; i++) - { len = 0; - for (aij = P->row[i]->ptr; aij != NULL; aij = aij->r_next) - { ind[++len] = toLit(aij->col->j-1); - if (aij->val < 0.0) - ind[len] = lit_neg(ind[len]); - } - xassert(len > 0); - xassert(solver_addclause(s, &ind[1], &ind[1+len])); - } - xfree(ind); - /* call the solver */ - s->verbosity = 1; - if (solver_solve(s, 0, 0)) - { /* instance is reported as satisfiable */ - P->mip_stat = GLP_OPT; - /* copy solution to the problem object */ - xassert(s->model.size == P->n); - for (j = 1; j <= P->n; j++) - { P->col[j]->mipx = - s->model.ptr[j-1] == l_True ? 1.0 : 0.0; - } - /* compute row values */ - for (i = 1; i <= P->m; i++) - { sum = 0; - for (aij = P->row[i]->ptr; aij != NULL; aij = aij->r_next) - sum += aij->val * aij->col->mipx; - P->row[i]->mipx = sum; - } - /* check integer feasibility */ - for (i = 1; i <= P->m; i++) - { if (P->row[i]->mipx < P->row[i]->lb) - { /* solution is wrong */ - P->mip_stat = GLP_UNDEF; - break; - } - } - } - else - { /* instance is reported as unsatisfiable */ - P->mip_stat = GLP_NOFEAS; - } - solver_delete(s); -fini: /* report the instance status */ - if (P->mip_stat == GLP_OPT) - { xprintf("SATISFIABLE\n"); - ret = 0; - } - else if (P->mip_stat == GLP_NOFEAS) - { xprintf("UNSATISFIABLE\n"); - ret = 0; - } - else - { xprintf("glp_minisat1: solver failed\n"); - ret = GLP_EFAIL; - } -done: return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi20.c b/resources/3rdparty/glpk-4.53/src/glpapi20.c deleted file mode 100644 index 2a2f6f988..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi20.c +++ /dev/null @@ -1,257 +0,0 @@ -/* glpapi20.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpnpp.h" - -int glp_intfeas1(glp_prob *P, int use_bound, int obj_bound) -{ /* solve integer feasibility problem */ - NPP *npp = NULL; - glp_prob *mip = NULL; - int *obj_ind = NULL; - double *obj_val = NULL; - int obj_row = 0; - int i, j, k, obj_len, temp, ret; - /* check the problem object */ - if (P == NULL || P->magic != GLP_PROB_MAGIC) - xerror("glp_intfeas1: P = %p; invalid problem object\n", - P); - if (P->tree != NULL) - xerror("glp_intfeas1: operation not allowed\n"); - /* integer solution is currently undefined */ - P->mip_stat = GLP_UNDEF; - P->mip_obj = 0.0; - /* check columns (variables) */ - for (j = 1; j <= P->n; j++) - { GLPCOL *col = P->col[j]; -#if 0 /* currently binarization is not yet implemented */ - if (!(col->kind == GLP_IV || col->type == GLP_FX)) - { xprintf("glp_intfeas1: column %d: non-integer non-fixed var" - "iable not allowed\n", j); -#else - if (!((col->kind == GLP_IV && col->lb == 0.0 && col->ub == 1.0) - || col->type == GLP_FX)) - { xprintf("glp_intfeas1: column %d: non-binary non-fixed vari" - "able not allowed\n", j); -#endif - ret = GLP_EDATA; - goto done; - } - temp = (int)col->lb; - if ((double)temp != col->lb) - { if (col->type == GLP_FX) - xprintf("glp_intfeas1: column %d: fixed value %g is non-" - "integer or out of range\n", j, col->lb); - else - xprintf("glp_intfeas1: column %d: lower bound %g is non-" - "integer or out of range\n", j, col->lb); - ret = GLP_EDATA; - goto done; - } - temp = (int)col->ub; - if ((double)temp != col->ub) - { xprintf("glp_intfeas1: column %d: upper bound %g is non-int" - "eger or out of range\n", j, col->ub); - ret = GLP_EDATA; - goto done; - } - if (col->type == GLP_DB && col->lb > col->ub) - { xprintf("glp_intfeas1: column %d: lower bound %g is greater" - " than upper bound %g\n", j, col->lb, col->ub); - ret = GLP_EBOUND; - goto done; - } - } - /* check rows (constraints) */ - for (i = 1; i <= P->m; i++) - { GLPROW *row = P->row[i]; - GLPAIJ *aij; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { temp = (int)aij->val; - if ((double)temp != aij->val) - { xprintf("glp_intfeas1: row = %d, column %d: constraint c" - "oefficient %g is non-integer or out of range\n", - i, aij->col->j, aij->val); - ret = GLP_EDATA; - goto done; - } - } - temp = (int)row->lb; - if ((double)temp != row->lb) - { if (row->type == GLP_FX) - xprintf("glp_intfeas1: row = %d: fixed value %g is non-i" - "nteger or out of range\n", i, row->lb); - else - xprintf("glp_intfeas1: row = %d: lower bound %g is non-i" - "nteger or out of range\n", i, row->lb); - ret = GLP_EDATA; - goto done; - } - temp = (int)row->ub; - if ((double)temp != row->ub) - { xprintf("glp_intfeas1: row = %d: upper bound %g is non-inte" - "ger or out of range\n", i, row->ub); - ret = GLP_EDATA; - goto done; - } - if (row->type == GLP_DB && row->lb > row->ub) - { xprintf("glp_intfeas1: row %d: lower bound %g is greater th" - "an upper bound %g\n", i, row->lb, row->ub); - ret = GLP_EBOUND; - goto done; - } - } - /* check the objective function */ - temp = (int)P->c0; - if ((double)temp != P->c0) - { xprintf("glp_intfeas1: objective constant term %g is non-integ" - "er or out of range\n", P->c0); - ret = GLP_EDATA; - goto done; - } - for (j = 1; j <= P->n; j++) - { temp = (int)P->col[j]->coef; - if ((double)temp != P->col[j]->coef) - { xprintf("glp_intfeas1: column %d: objective coefficient is " - "non-integer or out of range\n", j, P->col[j]->coef); - ret = GLP_EDATA; - goto done; - } - } - /* save the objective function and set it to zero */ - obj_ind = xcalloc(1+P->n, sizeof(int)); - obj_val = xcalloc(1+P->n, sizeof(double)); - obj_len = 0; - obj_ind[0] = 0; - obj_val[0] = P->c0; - P->c0 = 0.0; - for (j = 1; j <= P->n; j++) - { if (P->col[j]->coef != 0.0) - { obj_len++; - obj_ind[obj_len] = j; - obj_val[obj_len] = P->col[j]->coef; - P->col[j]->coef = 0.0; - } - } - /* add inequality to bound the objective function, if required */ - if (!use_bound) - xprintf("Will search for ANY feasible solution\n"); - else - { xprintf("Will search only for solution not worse than %d\n", - obj_bound); - obj_row = glp_add_rows(P, 1); - glp_set_mat_row(P, obj_row, obj_len, obj_ind, obj_val); - if (P->dir == GLP_MIN) - glp_set_row_bnds(P, obj_row, - GLP_UP, 0.0, (double)obj_bound - obj_val[0]); - else if (P->dir == GLP_MAX) - glp_set_row_bnds(P, obj_row, - GLP_LO, (double)obj_bound - obj_val[0], 0.0); - else - xassert(P != P); - } - /* create preprocessor workspace */ - xprintf("Translating to CNF-SAT...\n"); - xprintf("Original problem has %d row%s, %d column%s, and %d non-z" - "ero%s\n", P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : - "s", P->nnz, P->nnz == 1 ? "" : "s"); - npp = npp_create_wksp(); - /* load the original problem into the preprocessor workspace */ - npp_load_prob(npp, P, GLP_OFF, GLP_MIP, GLP_OFF); - /* perform translation to SAT-CNF problem instance */ - ret = npp_sat_encode_prob(npp); - if (ret == 0) - ; - else if (ret == GLP_ENOPFS) - xprintf("PROBLEM HAS NO INTEGER FEASIBLE SOLUTION\n"); - else if (ret == GLP_ERANGE) - xprintf("glp_intfeas1: translation to SAT-CNF failed because o" - "f integer overflow\n"); - else - xassert(ret != ret); - if (ret != 0) - goto done; - /* build SAT-CNF problem instance and try to solve it */ - mip = glp_create_prob(); - npp_build_prob(npp, mip); - ret = glp_minisat1(mip); - /* only integer feasible solution can be postprocessed */ - if (!(mip->mip_stat == GLP_OPT || mip->mip_stat == GLP_FEAS)) - { P->mip_stat = mip->mip_stat; - goto done; - } - /* postprocess the solution found */ - npp_postprocess(npp, mip); - /* the transformed problem is no longer needed */ - glp_delete_prob(mip), mip = NULL; - /* store solution to the original problem object */ - npp_unload_sol(npp, P); - /* change the solution status to 'integer feasible' */ - P->mip_stat = GLP_FEAS; - /* check integer feasibility */ - for (i = 1; i <= P->m; i++) - { GLPROW *row; - GLPAIJ *aij; - double sum; - row = P->row[i]; - sum = 0.0; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - sum += aij->val * aij->col->mipx; - xassert(sum == row->mipx); - if (row->type == GLP_LO || row->type == GLP_DB || - row->type == GLP_FX) - xassert(sum >= row->lb); - if (row->type == GLP_UP || row->type == GLP_DB || - row->type == GLP_FX) - xassert(sum <= row->ub); - } - /* compute value of the original objective function */ - P->mip_obj = obj_val[0]; - for (k = 1; k <= obj_len; k++) - P->mip_obj += obj_val[k] * P->col[obj_ind[k]]->mipx; - xprintf("Objective value = %17.9e\n", P->mip_obj); -done: /* delete the transformed problem, if it exists */ - if (mip != NULL) - glp_delete_prob(mip); - /* delete the preprocessor workspace, if it exists */ - if (npp != NULL) - npp_delete_wksp(npp); - /* remove inequality used to bound the objective function */ - if (obj_row > 0) - { int ind[1+1]; - ind[1] = obj_row; - glp_del_rows(P, 1, ind); - } - /* restore the original objective function */ - if (obj_ind != NULL) - { P->c0 = obj_val[0]; - for (k = 1; k <= obj_len; k++) - P->col[obj_ind[k]]->coef = obj_val[k]; - xfree(obj_ind); - xfree(obj_val); - } - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpapi21.c b/resources/3rdparty/glpk-4.53/src/glpapi21.c deleted file mode 100644 index 3b54a0dfb..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpapi21.c +++ /dev/null @@ -1,1428 +0,0 @@ -/* glpapi21.c (stand-alone LP/MIP solver) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "draft.h" -#include "env.h" -#include "glpgmp.h" -#include "misc.h" -#include "prob.h" - -struct csa -{ /* common storage area */ - glp_prob *prob; - /* LP/MIP problem object */ - glp_bfcp bfcp; - /* basis factorization control parameters */ - glp_smcp smcp; - /* simplex method control parameters */ - glp_iptcp iptcp; - /* interior-point method control parameters */ - glp_iocp iocp; - /* integer optimizer control parameters */ - glp_tran *tran; - /* model translator workspace */ - glp_graph *graph; - /* network problem object */ - int format; - /* problem file format: */ -#define FMT_MPS_DECK 1 /* fixed MPS */ -#define FMT_MPS_FILE 2 /* free MPS */ -#define FMT_LP 3 /* CPLEX LP */ -#define FMT_GLP 4 /* GLPK LP/MIP */ -#define FMT_MATHPROG 5 /* MathProg */ -#define FMT_MIN_COST 6 /* DIMACS min-cost flow */ -#define FMT_MAX_FLOW 7 /* DIMACS maximum flow */ -#if 1 /* 06/VIII-2011 */ -#define FMT_CNF 8 /* DIMACS CNF-SAT */ -#endif - const char *in_file; - /* name of input problem file */ -#define DATA_MAX 10 - /* maximal number of input data files */ - int ndf; - /* number of input data files specified */ - const char *in_data[1+DATA_MAX]; - /* name(s) of input data file(s) */ - const char *out_dpy; - /* name of output file to send display output; NULL means the - display output is sent to the terminal */ - int seed; - /* seed value to be passed to the MathProg translator; initially - set to 1; 0x80000000 means the value is omitted */ - int solution; - /* solution type flag: */ -#define SOL_BASIC 1 /* basic */ -#define SOL_INTERIOR 2 /* interior-point */ -#define SOL_INTEGER 3 /* mixed integer */ - const char *in_res; - /* name of input solution file in raw format */ - int dir; - /* optimization direction flag: - 0 - not specified - GLP_MIN - minimization - GLP_MAX - maximization */ - int scale; - /* automatic problem scaling flag */ - const char *out_sol; - /* name of output solution file in printable format */ - const char *out_res; - /* name of output solution file in raw format */ - const char *out_ranges; - /* name of output file to write sensitivity analysis report */ - int check; - /* input data checking flag; no solution is performed */ - const char *new_name; - /* new name to be assigned to the problem */ - const char *out_mps; - /* name of output problem file in fixed MPS format */ - const char *out_freemps; - /* name of output problem file in free MPS format */ - const char *out_cpxlp; - /* name of output problem file in CPLEX LP format */ - const char *out_glp; - /* name of output problem file in GLPK format */ -#if 0 - const char *out_pb; - /* name of output problem file in OPB format */ - const char *out_npb; - /* name of output problem file in normalized OPB format */ -#endif -#if 1 /* 06/VIII-2011 */ - const char *out_cnf; - /* name of output problem file in DIMACS CNF-SAT format */ -#endif - const char *log_file; - /* name of output file to hardcopy terminal output */ - int crash; - /* initial basis option: */ -#define USE_STD_BASIS 1 /* use standard basis */ -#define USE_ADV_BASIS 2 /* use advanced basis */ -#define USE_CPX_BASIS 3 /* use Bixby's basis */ -#define USE_INI_BASIS 4 /* use initial basis from ini_file */ - const char *ini_file; - /* name of input file containing initial basis */ - int exact; - /* flag to use glp_exact rather than glp_simplex */ - int xcheck; - /* flag to check final basis with glp_exact */ - int nomip; - /* flag to consider MIP as pure LP */ -#if 1 /* 15/VIII-2011 */ - int minisat; - /* option to solve feasibility problem with MiniSat solver */ - int use_bnd; - /* option to bound objective function */ - int obj_bnd; - /* upper (minization) or lower (maximization) objective bound */ -#endif -#if 1 /* 11/VII-2013 */ - const char *use_sol; - /* name of input mip solution file in GLPK format */ -#endif -}; - -static void print_help(const char *my_name) -{ /* print help information */ - xprintf("Usage: %s [options...] filename\n", my_name); - xprintf("\n"); - xprintf("General options:\n"); - xprintf(" --mps read LP/MIP problem in fixed MPS fo" - "rmat\n"); - xprintf(" --freemps read LP/MIP problem in free MPS for" - "mat (default)\n"); - xprintf(" --lp read LP/MIP problem in CPLEX LP for" - "mat\n"); - xprintf(" --glp read LP/MIP problem in GLPK format " - "\n"); - xprintf(" --math read LP/MIP model written in GNU Ma" - "thProg modeling\n"); - xprintf(" language\n"); - xprintf(" -m filename, --model filename\n"); - xprintf(" read model section and optional dat" - "a section from\n"); - xprintf(" filename (same as --math)\n"); - xprintf(" -d filename, --data filename\n"); - xprintf(" read data section from filename (fo" - "r --math only);\n"); - xprintf(" if model file also has data section" - ", it is ignored\n"); - xprintf(" -y filename, --display filename\n"); - xprintf(" send display output to filename (fo" - "r --math only);\n"); - xprintf(" by default the output is sent to te" - "rminal\n"); - xprintf(" --seed value initialize pseudo-random number gen" - "erator used in\n"); - xprintf(" MathProg model with specified seed " - "(any integer);\n"); - xprintf(" if seed value is ?, some random see" - "d will be used\n"); - xprintf(" --mincost read min-cost flow problem in DIMAC" - "S format\n"); - xprintf(" --maxflow read maximum flow problem in DIMACS" - " format\n"); -#if 1 /* 06/VIII-2011 */ - xprintf(" --cnf read CNF-SAT problem in DIMACS form" - "at\n"); -#endif - xprintf(" --simplex use simplex method (default)\n"); - xprintf(" --interior use interior point method (LP only)" - "\n"); - xprintf(" -r filename, --read filename\n"); - xprintf(" read solution from filename rather " - "to find it with\n"); - xprintf(" the solver\n"); - xprintf(" --min minimization\n"); - xprintf(" --max maximization\n"); - xprintf(" --scale scale problem (default)\n"); - xprintf(" --noscale do not scale problem\n"); - xprintf(" -o filename, --output filename\n"); - xprintf(" write solution to filename in print" - "able format\n"); - xprintf(" -w filename, --write filename\n"); - xprintf(" write solution to filename in plain" - " text format\n"); - xprintf(" --ranges filename\n"); - xprintf(" write sensitivity analysis report t" - "o filename in\n"); - xprintf(" printable format (simplex only)\n"); - xprintf(" --tmlim nnn limit solution time to nnn seconds " - "\n"); - xprintf(" --memlim nnn limit available memory to nnn megab" - "ytes\n"); - xprintf(" --check do not solve problem, check input d" - "ata only\n"); - xprintf(" --name probname change problem name to probname\n"); - xprintf(" --wmps filename write problem to filename in fixed " - "MPS format\n"); - xprintf(" --wfreemps filename\n"); - xprintf(" write problem to filename in free M" - "PS format\n"); - xprintf(" --wlp filename write problem to filename in CPLEX " - "LP format\n"); - xprintf(" --wglp filename write problem to filename in GLPK f" - "ormat\n"); -#if 0 - xprintf(" --wpb filename write problem to filename in OPB fo" - "rmat\n"); - xprintf(" --wnpb filename write problem to filename in normal" - "ized OPB format\n"); -#endif -#if 1 /* 06/VIII-2011 */ - xprintf(" --wcnf filename write problem to filename in DIMACS" - " CNF-SAT format\n"); -#endif - xprintf(" --log filename write copy of terminal output to fi" - "lename\n"); - xprintf(" -h, --help display this help information and e" - "xit\n"); - xprintf(" -v, --version display program version and exit\n") - ; - xprintf("\n"); - xprintf("LP basis factorization options:\n"); - xprintf(" --luf LU + Forrest-Tomlin update\n"); - xprintf(" (faster, less stable; default)\n"); - xprintf(" --cbg LU + Schur complement + Bartels-Gol" - "ub update\n"); - xprintf(" (slower, more stable)\n"); - xprintf(" --cgr LU + Schur complement + Givens rota" - "tion update\n"); - xprintf(" (slower, more stable)\n"); - xprintf("\n"); - xprintf("Options specific to simplex solver:\n"); - xprintf(" --primal use primal simplex (default)\n"); - xprintf(" --dual use dual simplex\n"); - xprintf(" --std use standard initial basis of all s" - "lacks\n"); - xprintf(" --adv use advanced initial basis (default" - ")\n"); - xprintf(" --bib use Bixby's initial basis\n"); - xprintf(" --ini filename use as initial basis previously sav" - "ed with -w\n"); - xprintf(" (disables LP presolver)\n"); - xprintf(" --steep use steepest edge technique (defaul" - "t)\n"); - xprintf(" --nosteep use standard \"textbook\" pricing\n" - ); - xprintf(" --relax use Harris' two-pass ratio test (de" - "fault)\n"); - xprintf(" --norelax use standard \"textbook\" ratio tes" - "t\n"); - xprintf(" --presol use presolver (default; assumes --s" - "cale and --adv)\n"); - xprintf(" --nopresol do not use presolver\n"); - xprintf(" --exact use simplex method based on exact a" - "rithmetic\n"); - xprintf(" --xcheck check final basis using exact arith" - "metic\n"); - xprintf("\n"); - xprintf("Options specific to interior-point solver:\n"); - xprintf(" --nord use natural (original) ordering\n"); - xprintf(" --qmd use quotient minimum degree orderin" - "g\n"); - xprintf(" --amd use approximate minimum degree orde" - "ring (default)\n"); - xprintf(" --symamd use approximate minimum degree orde" - "ring\n"); - xprintf("\n"); - xprintf("Options specific to MIP solver:\n"); - xprintf(" --nomip consider all integer variables as c" - "ontinuous\n"); - xprintf(" (allows solving MIP as pure LP)\n"); - xprintf(" --first branch on first integer variable\n") - ; - xprintf(" --last branch on last integer variable\n"); - xprintf(" --mostf branch on most fractional variable " - "\n"); - xprintf(" --drtom branch using heuristic by Driebeck " - "and Tomlin\n"); - xprintf(" (default)\n"); - xprintf(" --pcost branch using hybrid pseudocost heur" - "istic (may be\n"); - xprintf(" useful for hard instances)\n"); - xprintf(" --dfs backtrack using depth first search " - "\n"); - xprintf(" --bfs backtrack using breadth first searc" - "h\n"); - xprintf(" --bestp backtrack using the best projection" - " heuristic\n"); - xprintf(" --bestb backtrack using node with best loca" - "l bound\n"); - xprintf(" (default)\n"); - xprintf(" --intopt use MIP presolver (default)\n"); - xprintf(" --nointopt do not use MIP presolver\n"); - xprintf(" --binarize replace general integer variables b" - "y binary ones\n"); - xprintf(" (assumes --intopt)\n"); - xprintf(" --fpump apply feasibility pump heuristic\n") - ; -#if 1 /* 29/VI-2013 */ - xprintf(" --proxy [nnn] apply proximity search heuristic (n" - "nn is time limit\n"); - xprintf(" in seconds; default is 60)\n"); -#endif - xprintf(" --gomory generate Gomory's mixed integer cut" - "s\n"); - xprintf(" --mir generate MIR (mixed integer roundin" - "g) cuts\n"); - xprintf(" --cover generate mixed cover cuts\n"); - xprintf(" --clique generate clique cuts\n"); - xprintf(" --cuts generate all cuts above\n"); - xprintf(" --mipgap tol set relative mip gap tolerance to t" - "ol\n"); -#if 1 /* 15/VIII-2011 */ - xprintf(" --minisat translate integer feasibility probl" - "em to CNF-SAT\n"); - xprintf(" and solve it with MiniSat solver\n") - ; - xprintf(" --objbnd bound add inequality obj <= bound (minimi" - "zation) or\n"); - xprintf(" obj >= bound (maximization) to inte" - "ger feasibility\n"); - xprintf(" problem (assumes --minisat)\n"); -#endif - xprintf("\n"); - xprintf("For description of the MPS and CPLEX LP formats see Refe" - "rence Manual.\n"); - xprintf("For description of the modeling language see \"GLPK: Mod" - "eling Language\n"); - xprintf("GNU MathProg\". Both documents are included in the GLPK " - "distribution.\n"); - xprintf("\n"); - xprintf("See GLPK web page at .\n"); - xprintf("\n"); - xprintf("Please report bugs to .\n"); - return; -} - -static void print_version(int briefly) -{ /* print version information */ - xprintf("GLPSOL: GLPK LP/MIP Solver, v%s\n", glp_version()); - if (briefly) goto done; - xprintf("\n"); - xprintf("Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, " - "2007, 2008,\n"); - xprintf("2009, 2010, 2011, 2013, 2014 Andrew Makhorin, Department" - " for Applied\n"); - xprintf("Informatics, Moscow Aviation Institute, Moscow, Russia. " - "All rights\n"); - xprintf("reserved. E-mail: .\n"); - xprintf("\n"); - xprintf("This program has ABSOLUTELY NO WARRANTY.\n"); - xprintf("\n"); - xprintf("This program is free software; you may re-distribute it " - "under the terms\n"); - xprintf("of the GNU General Public License version 3 or later.\n") - ; -done: return; -} - -static int parse_cmdline(struct csa *csa, int argc, const char *argv[]) -{ /* parse command-line parameters */ - int k; -#define p(str) (strcmp(argv[k], str) == 0) - for (k = 1; k < argc; k++) - { if (p("--mps")) - csa->format = FMT_MPS_DECK; - else if (p("--freemps")) - csa->format = FMT_MPS_FILE; - else if (p("--lp") || p("--cpxlp")) - csa->format = FMT_LP; - else if (p("--glp")) - csa->format = FMT_GLP; - else if (p("--math") || p("-m") || p("--model")) - csa->format = FMT_MATHPROG; - else if (p("-d") || p("--data")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No input data file specified\n"); - return 1; - } - if (csa->ndf == DATA_MAX) - { xprintf("Too many input data files\n"); - return 1; - } - csa->in_data[++(csa->ndf)] = argv[k]; - } - else if (p("-y") || p("--display")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No display output file specified\n"); - return 1; - } - if (csa->out_dpy != NULL) - { xprintf("Only one display output file allowed\n"); - return 1; - } - csa->out_dpy = argv[k]; - } - else if (p("--seed")) - { k++; - if (k == argc || argv[k][0] == '\0' || - argv[k][0] == '-' && !isdigit((unsigned char)argv[k][1])) - { xprintf("No seed value specified\n"); - return 1; - } - if (strcmp(argv[k], "?") == 0) - csa->seed = 0x80000000; - else if (str2int(argv[k], &csa->seed)) - { xprintf("Invalid seed value '%s'\n", argv[k]); - return 1; - } - } - else if (p("--mincost")) - csa->format = FMT_MIN_COST; - else if (p("--maxflow")) - csa->format = FMT_MAX_FLOW; -#if 1 /* 06/VIII-2011 */ - else if (p("--cnf")) - csa->format = FMT_CNF; -#endif - else if (p("--simplex")) - csa->solution = SOL_BASIC; - else if (p("--interior")) - csa->solution = SOL_INTERIOR; -#if 1 /* 28/V-2010 */ - else if (p("--alien")) - csa->iocp.alien = GLP_ON; -#endif - else if (p("-r") || p("--read")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No input solution file specified\n"); - return 1; - } - if (csa->in_res != NULL) - { xprintf("Only one input solution file allowed\n"); - return 1; - } - csa->in_res = argv[k]; - } - else if (p("--min")) - csa->dir = GLP_MIN; - else if (p("--max")) - csa->dir = GLP_MAX; - else if (p("--scale")) - csa->scale = 1; - else if (p("--noscale")) - csa->scale = 0; - else if (p("-o") || p("--output")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No output solution file specified\n"); - return 1; - } - if (csa->out_sol != NULL) - { xprintf("Only one output solution file allowed\n"); - return 1; - } - csa->out_sol = argv[k]; - } - else if (p("-w") || p("--write")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No output solution file specified\n"); - return 1; - } - if (csa->out_res != NULL) - { xprintf("Only one output solution file allowed\n"); - return 1; - } - csa->out_res = argv[k]; - } - else if (p("--ranges") || p("--bounds")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No output file specified to write sensitivity a" - "nalysis report\n"); - return 1; - } - if (csa->out_ranges != NULL) - { xprintf("Only one output file allowed to write sensitivi" - "ty analysis report\n"); - return 1; - } - csa->out_ranges = argv[k]; - } - else if (p("--tmlim")) - { int tm_lim; - k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No time limit specified\n"); - return 1; - } - if (str2int(argv[k], &tm_lim) || tm_lim < 0) - { xprintf("Invalid time limit '%s'\n", argv[k]); - return 1; - } - if (tm_lim <= INT_MAX / 1000) - csa->smcp.tm_lim = csa->iocp.tm_lim = 1000 * tm_lim; - else - csa->smcp.tm_lim = csa->iocp.tm_lim = INT_MAX; - } - else if (p("--memlim")) - { int mem_lim; - k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No memory limit specified\n"); - return 1; - } - if (str2int(argv[k], &mem_lim) || mem_lim < 1) - { xprintf("Invalid memory limit '%s'\n", argv[k]); - return 1; - } - glp_mem_limit(mem_lim); - } - else if (p("--check")) - csa->check = 1; - else if (p("--name")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No problem name specified\n"); - return 1; - } - if (csa->new_name != NULL) - { xprintf("Only one problem name allowed\n"); - return 1; - } - csa->new_name = argv[k]; - } - else if (p("--wmps")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No fixed MPS output file specified\n"); - return 1; - } - if (csa->out_mps != NULL) - { xprintf("Only one fixed MPS output file allowed\n"); - return 1; - } - csa->out_mps = argv[k]; - } - else if (p("--wfreemps")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No free MPS output file specified\n"); - return 1; - } - if (csa->out_freemps != NULL) - { xprintf("Only one free MPS output file allowed\n"); - return 1; - } - csa->out_freemps = argv[k]; - } - else if (p("--wlp") || p("--wcpxlp") || p("--wlpt")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No CPLEX LP output file specified\n"); - return 1; - } - if (csa->out_cpxlp != NULL) - { xprintf("Only one CPLEX LP output file allowed\n"); - return 1; - } - csa->out_cpxlp = argv[k]; - } - else if (p("--wglp")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No GLPK LP/MIP output file specified\n"); - return 1; - } - if (csa->out_glp != NULL) - { xprintf("Only one GLPK LP/MIP output file allowed\n"); - return 1; - } - csa->out_glp = argv[k]; - } -#if 0 - else if (p("--wpb")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No problem output file specified\n"); - return 1; - } - if (csa->out_pb != NULL) - { xprintf("Only one OPB output file allowed\n"); - return 1; - } - csa->out_pb = argv[k]; - } - else if (p("--wnpb")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No problem output file specified\n"); - return 1; - } - if (csa->out_npb != NULL) - { xprintf("Only one normalized OPB output file allowed\n"); - return 1; - } - csa->out_npb = argv[k]; - } -#endif -#if 1 /* 06/VIII-2011 */ - else if (p("--wcnf")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No problem output file specified\n"); - return 1; - } - if (csa->out_cnf != NULL) - { xprintf("Only one output DIMACS CNF-SAT file allowed\n"); - return 1; - } - csa->out_cnf = argv[k]; - } -#endif - else if (p("--log")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No log file specified\n"); - return 1; - } - if (csa->log_file != NULL) - { xprintf("Only one log file allowed\n"); - return 1; - } - csa->log_file = argv[k]; - } - else if (p("-h") || p("--help")) - { print_help(argv[0]); - return -1; - } - else if (p("-v") || p("--version")) - { print_version(0); - return -1; - } - else if (p("--luf")) - csa->bfcp.type = GLP_BF_FT; - else if (p("--cbg")) - csa->bfcp.type = GLP_BF_BG; - else if (p("--cgr")) - csa->bfcp.type = GLP_BF_GR; - else if (p("--primal")) - csa->smcp.meth = GLP_PRIMAL; - else if (p("--dual")) - csa->smcp.meth = GLP_DUAL; - else if (p("--std")) - csa->crash = USE_STD_BASIS; - else if (p("--adv")) - csa->crash = USE_ADV_BASIS; - else if (p("--bib")) - csa->crash = USE_CPX_BASIS; - else if (p("--ini")) - { csa->crash = USE_INI_BASIS; - csa->smcp.presolve = GLP_OFF; - k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No initial basis file specified\n"); - return 1; - } - if (csa->ini_file != NULL) - { xprintf("Only one initial basis file allowed\n"); - return 1; - } - csa->ini_file = argv[k]; - } - else if (p("--steep")) - csa->smcp.pricing = GLP_PT_PSE; - else if (p("--nosteep")) - csa->smcp.pricing = GLP_PT_STD; - else if (p("--relax")) - csa->smcp.r_test = GLP_RT_HAR; - else if (p("--norelax")) - csa->smcp.r_test = GLP_RT_STD; - else if (p("--presol")) - csa->smcp.presolve = GLP_ON; - else if (p("--nopresol")) - csa->smcp.presolve = GLP_OFF; - else if (p("--exact")) - csa->exact = 1; - else if (p("--xcheck")) - csa->xcheck = 1; - else if (p("--nord")) - csa->iptcp.ord_alg = GLP_ORD_NONE; - else if (p("--qmd")) - csa->iptcp.ord_alg = GLP_ORD_QMD; - else if (p("--amd")) - csa->iptcp.ord_alg = GLP_ORD_AMD; - else if (p("--symamd")) - csa->iptcp.ord_alg = GLP_ORD_SYMAMD; - else if (p("--nomip")) - csa->nomip = 1; - else if (p("--first")) - csa->iocp.br_tech = GLP_BR_FFV; - else if (p("--last")) - csa->iocp.br_tech = GLP_BR_LFV; - else if (p("--drtom")) - csa->iocp.br_tech = GLP_BR_DTH; - else if (p("--mostf")) - csa->iocp.br_tech = GLP_BR_MFV; - else if (p("--pcost")) - csa->iocp.br_tech = GLP_BR_PCH; - else if (p("--dfs")) - csa->iocp.bt_tech = GLP_BT_DFS; - else if (p("--bfs")) - csa->iocp.bt_tech = GLP_BT_BFS; - else if (p("--bestp")) - csa->iocp.bt_tech = GLP_BT_BPH; - else if (p("--bestb")) - csa->iocp.bt_tech = GLP_BT_BLB; - else if (p("--intopt")) - csa->iocp.presolve = GLP_ON; - else if (p("--nointopt")) - csa->iocp.presolve = GLP_OFF; - else if (p("--binarize")) - csa->iocp.presolve = csa->iocp.binarize = GLP_ON; - else if (p("--fpump")) - csa->iocp.fp_heur = GLP_ON; -#if 1 /* 29/VI-2013 */ - else if (p("--proxy")) - { csa->iocp.ps_heur = GLP_ON; - if (argv[k+1] && isdigit((unsigned char)argv[k+1][0])) - { int nnn; - k++; - if (str2int(argv[k], &nnn) || nnn < 1) - { xprintf("Invalid proxy time limit '%s'\n", argv[k]); - return 1; - } - csa->iocp.ps_tm_lim = 1000 * nnn; - } - } -#endif - else if (p("--gomory")) - csa->iocp.gmi_cuts = GLP_ON; - else if (p("--mir")) - csa->iocp.mir_cuts = GLP_ON; - else if (p("--cover")) - csa->iocp.cov_cuts = GLP_ON; - else if (p("--clique")) - csa->iocp.clq_cuts = GLP_ON; - else if (p("--cuts")) - csa->iocp.gmi_cuts = csa->iocp.mir_cuts = - csa->iocp.cov_cuts = csa->iocp.clq_cuts = GLP_ON; - else if (p("--mipgap")) - { double mip_gap; - k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No relative gap tolerance specified\n"); - return 1; - } - if (str2num(argv[k], &mip_gap) || mip_gap < 0.0) - { xprintf("Invalid relative mip gap tolerance '%s'\n", - argv[k]); - return 1; - } - csa->iocp.mip_gap = mip_gap; - } -#if 1 /* 15/VIII-2011 */ - else if (p("--minisat")) - csa->minisat = 1; - else if (p("--objbnd")) - { k++; - if (k == argc || argv[k][0] == '\0' || - argv[k][0] == '-' && !isdigit((unsigned char)argv[k][1])) - { xprintf("No objective bound specified\n"); - return 1; - } - csa->minisat = 1; - csa->use_bnd = 1; - if (str2int(argv[k], &csa->obj_bnd)) - { xprintf("Invalid objective bound '%s' (should be integer" - " value)\n", argv[k]); - return 1; - } - } -#endif -#if 1 /* 11/VII-2013 */ - else if (p("--use")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No input MIP solution file specified\n"); - return 1; - } - if (csa->use_sol != NULL) - { xprintf("Only one input MIP solution file allowed\n"); - return 1; - } - csa->use_sol = argv[k]; - } - else if (p("--save")) - { k++; - if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-') - { xprintf("No output MIP solution file specified\n"); - return 1; - } - if (csa->iocp.save_sol != NULL) - { xprintf("Only one output MIP solution file allowed\n"); - return 1; - } - csa->iocp.save_sol = argv[k]; - } -#endif - else if (argv[k][0] == '-' || - (argv[k][0] == '-' && argv[k][1] == '-')) - { xprintf("Invalid option '%s'; try %s --help\n", - argv[k], argv[0]); - return 1; - } - else - { if (csa->in_file != NULL) - { xprintf("Only one input problem file allowed\n"); - return 1; - } - csa->in_file = argv[k]; - } - } -#undef p - return 0; -} - -typedef struct { double rhs, pi; } v_data; -typedef struct { double low, cap, cost, x; } a_data; - -int glp_main(int argc, const char *argv[]) -{ /* stand-alone LP/MIP solver */ - struct csa _csa, *csa = &_csa; - int ret; -#if 0 /* 10/VI-2013 */ - glp_long start; -#else - double start; -#endif - /* perform initialization */ - csa->prob = glp_create_prob(); - glp_get_bfcp(csa->prob, &csa->bfcp); - glp_init_smcp(&csa->smcp); - csa->smcp.presolve = GLP_ON; - glp_init_iptcp(&csa->iptcp); - glp_init_iocp(&csa->iocp); - csa->iocp.presolve = GLP_ON; - csa->tran = NULL; - csa->graph = NULL; - csa->format = FMT_MPS_FILE; - csa->in_file = NULL; - csa->ndf = 0; - csa->out_dpy = NULL; - csa->seed = 1; - csa->solution = SOL_BASIC; - csa->in_res = NULL; - csa->dir = 0; - csa->scale = 1; - csa->out_sol = NULL; - csa->out_res = NULL; - csa->out_ranges = NULL; - csa->check = 0; - csa->new_name = NULL; - csa->out_mps = NULL; - csa->out_freemps = NULL; - csa->out_cpxlp = NULL; - csa->out_glp = NULL; -#if 0 - csa->out_pb = NULL; - csa->out_npb = NULL; -#endif -#if 1 /* 06/VIII-2011 */ - csa->out_cnf = NULL; -#endif - csa->log_file = NULL; - csa->crash = USE_ADV_BASIS; - csa->ini_file = NULL; - csa->exact = 0; - csa->xcheck = 0; - csa->nomip = 0; -#if 1 /* 15/VIII-2011 */ - csa->minisat = 0; - csa->use_bnd = 0; - csa->obj_bnd = 0; -#endif -#if 1 /* 11/VII-2013 */ - csa->use_sol = NULL; -#endif - /* parse command-line parameters */ - ret = parse_cmdline(csa, argc, argv); - if (ret < 0) - { ret = EXIT_SUCCESS; - goto done; - } - if (ret > 0) - { ret = EXIT_FAILURE; - goto done; - } - /*--------------------------------------------------------------*/ - /* remove all output files specified in the command line */ - if (csa->out_dpy != NULL) remove(csa->out_dpy); - if (csa->out_sol != NULL) remove(csa->out_sol); - if (csa->out_res != NULL) remove(csa->out_res); - if (csa->out_ranges != NULL) remove(csa->out_ranges); - if (csa->out_mps != NULL) remove(csa->out_mps); - if (csa->out_freemps != NULL) remove(csa->out_freemps); - if (csa->out_cpxlp != NULL) remove(csa->out_cpxlp); - if (csa->out_glp != NULL) remove(csa->out_glp); -#if 0 - if (csa->out_pb != NULL) remove(csa->out_pb); - if (csa->out_npb != NULL) remove(csa->out_npb); -#endif -#if 1 /* 06/VIII-2011 */ - if (csa->out_cnf != NULL) remove(csa->out_cnf); -#endif - if (csa->log_file != NULL) remove(csa->log_file); - /*--------------------------------------------------------------*/ - /* open log file, if required */ - if (csa->log_file != NULL) - { if (glp_open_tee(csa->log_file)) - { xprintf("Unable to create log file\n"); - ret = EXIT_FAILURE; - goto done; - } - } - /*--------------------------------------------------------------*/ - /* print version information */ - print_version(1); - /*--------------------------------------------------------------*/ - /* print parameters specified in the command line */ - if (argc > 1) - { int k, len = INT_MAX; - xprintf("Parameter(s) specified in the command line:"); - for (k = 1; k < argc; k++) - { if (len > 72) - xprintf("\n"), len = 0; - xprintf(" %s", argv[k]); - len += 1 + strlen(argv[k]); - } - xprintf("\n"); - } - /*--------------------------------------------------------------*/ - /* read problem data from the input file */ - if (csa->in_file == NULL) - { xprintf("No input problem file specified; try %s --help\n", - argv[0]); - ret = EXIT_FAILURE; - goto done; - } - if (csa->format == FMT_MPS_DECK) - { ret = glp_read_mps(csa->prob, GLP_MPS_DECK, NULL, - csa->in_file); - if (ret != 0) -err1: { xprintf("MPS file processing error\n"); - ret = EXIT_FAILURE; - goto done; - } - } - else if (csa->format == FMT_MPS_FILE) - { ret = glp_read_mps(csa->prob, GLP_MPS_FILE, NULL, - csa->in_file); - if (ret != 0) goto err1; - } - else if (csa->format == FMT_LP) - { ret = glp_read_lp(csa->prob, NULL, csa->in_file); - if (ret != 0) - { xprintf("CPLEX LP file processing error\n"); - ret = EXIT_FAILURE; - goto done; - } - } - else if (csa->format == FMT_GLP) - { ret = glp_read_prob(csa->prob, 0, csa->in_file); - if (ret != 0) - { xprintf("GLPK LP/MIP file processing error\n"); - ret = EXIT_FAILURE; - goto done; - } - } - else if (csa->format == FMT_MATHPROG) - { int k; - /* allocate the translator workspace */ - csa->tran = glp_mpl_alloc_wksp(); - /* set seed value */ - if (csa->seed == 0x80000000) -#if 0 /* 10/VI-2013 */ - { csa->seed = glp_time().lo; -#else - { csa->seed = (int)fmod(glp_time(), 1000000000.0); -#endif - xprintf("Seed value %d will be used\n", csa->seed); - } - _glp_mpl_init_rand(csa->tran, csa->seed); - /* read model section and optional data section */ - if (glp_mpl_read_model(csa->tran, csa->in_file, csa->ndf > 0)) -err2: { xprintf("MathProg model processing error\n"); - ret = EXIT_FAILURE; - goto done; - } - /* read optional data section(s), if necessary */ - for (k = 1; k <= csa->ndf; k++) - { if (glp_mpl_read_data(csa->tran, csa->in_data[k])) - goto err2; - } - /* generate the model */ - if (glp_mpl_generate(csa->tran, csa->out_dpy)) goto err2; - /* build the problem instance from the model */ - glp_mpl_build_prob(csa->tran, csa->prob); - } - else if (csa->format == FMT_MIN_COST) - { csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data)); - ret = glp_read_mincost(csa->graph, offsetof(v_data, rhs), - offsetof(a_data, low), offsetof(a_data, cap), - offsetof(a_data, cost), csa->in_file); - if (ret != 0) - { xprintf("DIMACS file processing error\n"); - ret = EXIT_FAILURE; - goto done; - } - glp_mincost_lp(csa->prob, csa->graph, GLP_ON, - offsetof(v_data, rhs), offsetof(a_data, low), - offsetof(a_data, cap), offsetof(a_data, cost)); - glp_set_prob_name(csa->prob, csa->in_file); - } - else if (csa->format == FMT_MAX_FLOW) - { int s, t; - csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data)); - ret = glp_read_maxflow(csa->graph, &s, &t, - offsetof(a_data, cap), csa->in_file); - if (ret != 0) - { xprintf("DIMACS file processing error\n"); - ret = EXIT_FAILURE; - goto done; - } - glp_maxflow_lp(csa->prob, csa->graph, GLP_ON, s, t, - offsetof(a_data, cap)); - glp_set_prob_name(csa->prob, csa->in_file); - } -#if 1 /* 06/VIII-2011 */ - else if (csa->format == FMT_CNF) - { ret = glp_read_cnfsat(csa->prob, csa->in_file); - if (ret != 0) - { xprintf("DIMACS file processing error\n"); - ret = EXIT_FAILURE; - goto done; - } - glp_set_prob_name(csa->prob, csa->in_file); - } -#endif - else - xassert(csa != csa); - /*--------------------------------------------------------------*/ - /* change problem name, if required */ - if (csa->new_name != NULL) - glp_set_prob_name(csa->prob, csa->new_name); - /* change optimization direction, if required */ - if (csa->dir != 0) - glp_set_obj_dir(csa->prob, csa->dir); - /* sort elements of the constraint matrix */ - glp_sort_matrix(csa->prob); - /*--------------------------------------------------------------*/ - /* write problem data in fixed MPS format, if required */ - if (csa->out_mps != NULL) - { ret = glp_write_mps(csa->prob, GLP_MPS_DECK, NULL, - csa->out_mps); - if (ret != 0) - { xprintf("Unable to write problem in fixed MPS format\n"); - ret = EXIT_FAILURE; - goto done; - } - } - /* write problem data in free MPS format, if required */ - if (csa->out_freemps != NULL) - { ret = glp_write_mps(csa->prob, GLP_MPS_FILE, NULL, - csa->out_freemps); - if (ret != 0) - { xprintf("Unable to write problem in free MPS format\n"); - ret = EXIT_FAILURE; - goto done; - } - } - /* write problem data in CPLEX LP format, if required */ - if (csa->out_cpxlp != NULL) - { ret = glp_write_lp(csa->prob, NULL, csa->out_cpxlp); - if (ret != 0) - { xprintf("Unable to write problem in CPLEX LP format\n"); - ret = EXIT_FAILURE; - goto done; - } - } - /* write problem data in GLPK format, if required */ - if (csa->out_glp != NULL) - { ret = glp_write_prob(csa->prob, 0, csa->out_glp); - if (ret != 0) - { xprintf("Unable to write problem in GLPK format\n"); - ret = EXIT_FAILURE; - goto done; - } - } -#if 0 - /* write problem data in OPB format, if required */ - if (csa->out_pb != NULL) - { ret = lpx_write_pb(csa->prob, csa->out_pb, 0, 0); - if (ret != 0) - { xprintf("Unable to write problem in OPB format\n"); - ret = EXIT_FAILURE; - goto done; - } - } - /* write problem data in normalized OPB format, if required */ - if (csa->out_npb != NULL) - { ret = lpx_write_pb(csa->prob, csa->out_npb, 1, 1); - if (ret != 0) - { xprintf( - "Unable to write problem in normalized OPB format\n"); - ret = EXIT_FAILURE; - goto done; - } - } -#endif -#if 1 /* 06/VIII-2011 */ - /* write problem data in DIMACS CNF-SAT format, if required */ - if (csa->out_cnf != NULL) - { ret = glp_write_cnfsat(csa->prob, csa->out_cnf); - if (ret != 0) - { xprintf( - "Unable to write problem in DIMACS CNF-SAT format\n"); - ret = EXIT_FAILURE; - goto done; - } - } -#endif - /*--------------------------------------------------------------*/ - /* if only problem data check is required, skip computations */ - if (csa->check) - { ret = EXIT_SUCCESS; - goto done; - } - /*--------------------------------------------------------------*/ - /* determine the solution type */ - if (!csa->nomip && - glp_get_num_int(csa->prob) + glp_get_num_bin(csa->prob) > 0) - { if (csa->solution == SOL_INTERIOR) - { xprintf("Interior-point method is not able to solve MIP pro" - "blem; use --simplex\n"); - ret = EXIT_FAILURE; - goto done; - } - csa->solution = SOL_INTEGER; - } - /*--------------------------------------------------------------*/ - /* if solution is provided, read it and skip computations */ - if (csa->in_res != NULL) - { if (csa->solution == SOL_BASIC) - ret = glp_read_sol(csa->prob, csa->in_res); - else if (csa->solution == SOL_INTERIOR) - ret = glp_read_ipt(csa->prob, csa->in_res); - else if (csa->solution == SOL_INTEGER) - ret = glp_read_mip(csa->prob, csa->in_res); - else - xassert(csa != csa); - if (ret != 0) - { xprintf("Unable to read problem solution\n"); - ret = EXIT_FAILURE; - goto done; - } - goto skip; - } -#if 1 /* 11/VII-2013 */ - /*--------------------------------------------------------------*/ - /* if initial MIP solution is provided, read it */ - if (csa->solution == SOL_INTEGER && csa->use_sol != NULL) - { ret = glp_read_mip(csa->prob, csa->use_sol); - if (ret != 0) - { xprintf("Unable to read initial MIP solution\n"); - ret = EXIT_FAILURE; - goto done; - } - csa->iocp.use_sol = GLP_ON; - } -#endif - /*--------------------------------------------------------------*/ - /* scale the problem data, if required */ - if (csa->scale) - { if (csa->solution == SOL_BASIC && !csa->smcp.presolve || - csa->solution == SOL_INTERIOR || - csa->solution == SOL_INTEGER && !csa->iocp.presolve) - glp_scale_prob(csa->prob, GLP_SF_AUTO); - } - /*--------------------------------------------------------------*/ - /* construct starting LP basis */ - if (csa->solution == SOL_BASIC && !csa->smcp.presolve || - csa->solution == SOL_INTEGER && !csa->iocp.presolve) - { if (csa->crash == USE_STD_BASIS) - glp_std_basis(csa->prob); - else if (csa->crash == USE_ADV_BASIS) - glp_adv_basis(csa->prob, 0); - else if (csa->crash == USE_CPX_BASIS) - glp_cpx_basis(csa->prob); - else if (csa->crash == USE_INI_BASIS) - { ret = glp_read_sol(csa->prob, csa->ini_file); - if (ret != 0) - { xprintf("Unable to read initial basis\n"); - ret = EXIT_FAILURE; - goto done; - } - } - else - xassert(csa != csa); - } - /*--------------------------------------------------------------*/ - /* solve the problem */ - start = xtime(); - if (csa->solution == SOL_BASIC) - { if (!csa->exact) - { glp_set_bfcp(csa->prob, &csa->bfcp); - glp_simplex(csa->prob, &csa->smcp); - if (csa->xcheck) - { if (csa->smcp.presolve && - glp_get_status(csa->prob) != GLP_OPT) - xprintf("If you need to check final basis for non-opt" - "imal solution, use --nopresol\n"); - else - glp_exact(csa->prob, &csa->smcp); - } - if (csa->out_sol != NULL || csa->out_res != NULL) - { if (csa->smcp.presolve && - glp_get_status(csa->prob) != GLP_OPT) - xprintf("If you need actual output for non-optimal solut" - "ion, use --nopresol\n"); - } - } - else - glp_exact(csa->prob, &csa->smcp); - } - else if (csa->solution == SOL_INTERIOR) - glp_interior(csa->prob, &csa->iptcp); -#if 1 /* 15/VIII-2011 */ - else if (csa->solution == SOL_INTEGER && csa->minisat) - { if (glp_check_cnfsat(csa->prob) == 0) - glp_minisat1(csa->prob); - else - glp_intfeas1(csa->prob, csa->use_bnd, csa->obj_bnd); - } -#endif - else if (csa->solution == SOL_INTEGER) - { glp_set_bfcp(csa->prob, &csa->bfcp); - if (!csa->iocp.presolve) - glp_simplex(csa->prob, &csa->smcp); -#if 0 - csa->iocp.msg_lev = GLP_MSG_DBG; - csa->iocp.pp_tech = GLP_PP_NONE; -#endif - glp_intopt(csa->prob, &csa->iocp); - } - else - xassert(csa != csa); - /*--------------------------------------------------------------*/ - /* display statistics */ - xprintf("Time used: %.1f secs\n", xdifftime(xtime(), start)); -#if 0 /* 16/II-2012 */ - { glp_long tpeak; - char buf[50]; - glp_mem_usage(NULL, NULL, NULL, &tpeak); - xprintf("Memory used: %.1f Mb (%s bytes)\n", - xltod(tpeak) / 1048576.0, xltoa(tpeak, buf)); - } -#else - { size_t tpeak; - glp_mem_usage(NULL, NULL, NULL, &tpeak); - xprintf("Memory used: %.1f Mb (%.0f bytes)\n", - (double)tpeak / 1048576.0, (double)tpeak); - } -#endif - /*--------------------------------------------------------------*/ -skip: /* postsolve the model, if necessary */ - if (csa->tran != NULL) - { if (csa->solution == SOL_BASIC) - { if (!(glp_get_status(csa->prob) == GLP_OPT || - glp_get_status(csa->prob) == GLP_FEAS)) - ret = -1; - else - ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_SOL); - } - else if (csa->solution == SOL_INTERIOR) - { if (!(glp_ipt_status(csa->prob) == GLP_OPT || - glp_ipt_status(csa->prob) == GLP_FEAS)) - ret = -1; - else - ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_IPT); - } - else if (csa->solution == SOL_INTEGER) - { if (!(glp_mip_status(csa->prob) == GLP_OPT || - glp_mip_status(csa->prob) == GLP_FEAS)) - ret = -1; - else - ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_MIP); - } - else - xassert(csa != csa); - if (ret > 0) - { xprintf("Model postsolving error\n"); - ret = EXIT_FAILURE; - goto done; - } - } - /*--------------------------------------------------------------*/ - /* write problem solution in printable format, if required */ - if (csa->out_sol != NULL) - { if (csa->solution == SOL_BASIC) - ret = glp_print_sol(csa->prob, csa->out_sol); - else if (csa->solution == SOL_INTERIOR) - ret = glp_print_ipt(csa->prob, csa->out_sol); - else if (csa->solution == SOL_INTEGER) - ret = glp_print_mip(csa->prob, csa->out_sol); - else - xassert(csa != csa); - if (ret != 0) - { xprintf("Unable to write problem solution\n"); - ret = EXIT_FAILURE; - goto done; - } - } - /* write problem solution in printable format, if required */ - if (csa->out_res != NULL) - { if (csa->solution == SOL_BASIC) - ret = glp_write_sol(csa->prob, csa->out_res); - else if (csa->solution == SOL_INTERIOR) - ret = glp_write_ipt(csa->prob, csa->out_res); - else if (csa->solution == SOL_INTEGER) - ret = glp_write_mip(csa->prob, csa->out_res); - else - xassert(csa != csa); - if (ret != 0) - { xprintf("Unable to write problem solution\n"); - ret = EXIT_FAILURE; - goto done; - } - } - /* write sensitivity analysis report, if required */ - if (csa->out_ranges != NULL) - { if (csa->solution == SOL_BASIC) - { if (glp_get_status(csa->prob) == GLP_OPT) - { if (glp_bf_exists(csa->prob)) -ranges: { ret = glp_print_ranges(csa->prob, 0, NULL, 0, - csa->out_ranges); - if (ret != 0) - { xprintf("Unable to write sensitivity analysis repo" - "rt\n"); - ret = EXIT_FAILURE; - goto done; - } - } - else - { ret = glp_factorize(csa->prob); - if (ret == 0) goto ranges; - xprintf("Cannot produce sensitivity analysis report d" - "ue to error in basis factorization (glp_factorize" - " returned %d); try --nopresol\n", ret); - } - } - else - xprintf("Cannot produce sensitivity analysis report for " - "non-optimal basic solution\n"); - } - else - xprintf("Cannot produce sensitivity analysis report for int" - "erior-point or MIP solution\n"); - } - /*--------------------------------------------------------------*/ - /* all seems to be ok */ - ret = EXIT_SUCCESS; - /*--------------------------------------------------------------*/ -done: /* delete the LP/MIP problem object */ - if (csa->prob != NULL) - glp_delete_prob(csa->prob); - /* free the translator workspace, if necessary */ - if (csa->tran != NULL) - glp_mpl_free_wksp(csa->tran); - /* delete the network problem object, if necessary */ - if (csa->graph != NULL) - glp_delete_graph(csa->graph); - xassert(gmp_pool_count() == 0); - gmp_free_mem(); - /* close log file, if necessary */ - if (csa->log_file != NULL) glp_close_tee(); - /* check that no memory blocks are still allocated */ -#if 0 /* 16/II-2012 */ - { int count; - glp_long total; - glp_mem_usage(&count, NULL, &total, NULL); - if (count != 0) - xerror("Error: %d memory block(s) were lost\n", count); - xassert(count == 0); - xassert(total.lo == 0 && total.hi == 0); - } -#else - { int count; - size_t total; - glp_mem_usage(&count, NULL, &total, NULL); - if (count != 0) - xerror("Error: %d memory block(s) were lost\n", count); - xassert(total == 0); - } -#endif - /* free the GLPK environment */ - glp_free_env(); - /* return to the control program */ - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpcpx.c b/resources/3rdparty/glpk-4.53/src/glpcpx.c deleted file mode 100644 index 1aa3f346b..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpcpx.c +++ /dev/null @@ -1,1262 +0,0 @@ -/* glpcpx.c (CPLEX LP format routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "misc.h" -#include "prob.h" - -#define xfprintf glp_format - -/*********************************************************************** -* NAME -* -* glp_init_cpxcp - initialize CPLEX LP format control parameters -* -* SYNOPSIS -* -* void glp_init_cpxcp(glp_cpxcp *parm): -* -* The routine glp_init_cpxcp initializes control parameters used by -* the CPLEX LP input/output routines glp_read_lp and glp_write_lp with -* default values. -* -* Default values of the control parameters are stored in the glp_cpxcp -* structure, which the parameter parm points to. */ - -void glp_init_cpxcp(glp_cpxcp *parm) -{ xassert(parm != NULL); - return; -} - -static void check_parm(const char *func, const glp_cpxcp *parm) -{ /* check control parameters */ - xassert(func != NULL); - xassert(parm != NULL); - return; -} - -/*********************************************************************** -* NAME -* -* glp_read_lp - read problem data in CPLEX LP format -* -* SYNOPSIS -* -* int glp_read_lp(glp_prob *P, const glp_cpxcp *parm, const char -* *fname); -* -* DESCRIPTION -* -* The routine glp_read_lp reads problem data in CPLEX LP format from -* a text file. -* -* The parameter parm is a pointer to the structure glp_cpxcp, which -* specifies control parameters used by the routine. If parm is NULL, -* the routine uses default settings. -* -* The character string fname specifies a name of the text file to be -* read. -* -* Note that before reading data the current content of the problem -* object is completely erased with the routine glp_erase_prob. -* -* RETURNS -* -* If the operation was successful, the routine glp_read_lp returns -* zero. Otherwise, it prints an error message and returns non-zero. */ - -struct csa -{ /* common storage area */ - glp_prob *P; - /* LP/MIP problem object */ - const glp_cpxcp *parm; - /* pointer to control parameters */ - const char *fname; - /* name of input CPLEX LP file */ - glp_file *fp; - /* stream assigned to input CPLEX LP file */ - jmp_buf jump; - /* label for go to in case of error */ - int count; - /* line count */ - int c; - /* current character or EOF */ - int token; - /* current token: */ -#define T_EOF 0x00 /* end of file */ -#define T_MINIMIZE 0x01 /* keyword 'minimize' */ -#define T_MAXIMIZE 0x02 /* keyword 'maximize' */ -#define T_SUBJECT_TO 0x03 /* keyword 'subject to' */ -#define T_BOUNDS 0x04 /* keyword 'bounds' */ -#define T_GENERAL 0x05 /* keyword 'general' */ -#define T_INTEGER 0x06 /* keyword 'integer' */ -#define T_BINARY 0x07 /* keyword 'binary' */ -#define T_END 0x08 /* keyword 'end' */ -#define T_NAME 0x09 /* symbolic name */ -#define T_NUMBER 0x0A /* numeric constant */ -#define T_PLUS 0x0B /* delimiter '+' */ -#define T_MINUS 0x0C /* delimiter '-' */ -#define T_COLON 0x0D /* delimiter ':' */ -#define T_LE 0x0E /* delimiter '<=' */ -#define T_GE 0x0F /* delimiter '>=' */ -#define T_EQ 0x10 /* delimiter '=' */ - char image[255+1]; - /* image of current token */ - int imlen; - /* length of token image */ - double value; - /* value of numeric constant */ - int n_max; - /* length of the following five arrays (enlarged automatically, - if necessary) */ - int *ind; /* int ind[1+n_max]; */ - double *val; /* double val[1+n_max]; */ - char *flag; /* char flag[1+n_max]; */ - /* working arrays used to construct linear forms */ - double *lb; /* double lb[1+n_max]; */ - double *ub; /* double ub[1+n_max]; */ - /* lower and upper bounds of variables (columns) */ -#if 1 /* 27/VII-2013 */ - int lb_warn, ub_warn; - /* warning 'lower/upper bound redefined' already issued */ -#endif -}; - -#define CHAR_SET "!\"#$%&()/,.;?@_`'{}|~" -/* characters, which may appear in symbolic names */ - -static void error(struct csa *csa, const char *fmt, ...) -{ /* print error message and terminate processing */ - va_list arg; - xprintf("%s:%d: ", csa->fname, csa->count); - va_start(arg, fmt); - xvprintf(fmt, arg); - va_end(arg); - longjmp(csa->jump, 1); - /* no return */ -} - -static void warning(struct csa *csa, const char *fmt, ...) -{ /* print warning message and continue processing */ - va_list arg; - xprintf("%s:%d: warning: ", csa->fname, csa->count); - va_start(arg, fmt); - xvprintf(fmt, arg); - va_end(arg); - return; -} - -static void read_char(struct csa *csa) -{ /* read next character from input file */ - int c; - xassert(csa->c != EOF); - if (csa->c == '\n') csa->count++; - c = glp_getc(csa->fp); - if (c < 0) - { if (glp_ioerr(csa->fp)) - error(csa, "read error - %s\n", get_err_msg()); - else if (csa->c == '\n') - { csa->count--; - c = EOF; - } - else - { warning(csa, "missing final end of line\n"); - c = '\n'; - } - } - else if (c == '\n') - ; - else if (isspace(c)) - c = ' '; - else if (iscntrl(c)) - error(csa, "invalid control character 0x%02X\n", c); - csa->c = c; - return; -} - -static void add_char(struct csa *csa) -{ /* append current character to current token */ - if (csa->imlen == sizeof(csa->image)-1) - error(csa, "token '%.15s...' too long\n", csa->image); - csa->image[csa->imlen++] = (char)csa->c; - csa->image[csa->imlen] = '\0'; - read_char(csa); - return; -} - -static int the_same(char *s1, char *s2) -{ /* compare two character strings ignoring case sensitivity */ - for (; *s1 != '\0'; s1++, s2++) - { if (tolower((unsigned char)*s1) != tolower((unsigned char)*s2)) - return 0; - } - return 1; -} - -static void scan_token(struct csa *csa) -{ /* scan next token */ - int flag; - csa->token = -1; - csa->image[0] = '\0'; - csa->imlen = 0; - csa->value = 0.0; -loop: flag = 0; - /* skip non-significant characters */ - while (csa->c == ' ') read_char(csa); - /* recognize and scan current token */ - if (csa->c == EOF) - csa->token = T_EOF; - else if (csa->c == '\n') - { read_char(csa); - /* if the next character is letter, it may begin a keyword */ - if (isalpha(csa->c)) - { flag = 1; - goto name; - } - goto loop; - } - else if (csa->c == '\\') - { /* comment; ignore everything until end-of-line */ - while (csa->c != '\n') read_char(csa); - goto loop; - } - else if (isalpha(csa->c) || csa->c != '.' && strchr(CHAR_SET, - csa->c) != NULL) -name: { /* symbolic name */ - csa->token = T_NAME; - while (isalnum(csa->c) || strchr(CHAR_SET, csa->c) != NULL) - add_char(csa); - if (flag) - { /* check for keyword */ - if (the_same(csa->image, "minimize")) - csa->token = T_MINIMIZE; - else if (the_same(csa->image, "minimum")) - csa->token = T_MINIMIZE; - else if (the_same(csa->image, "min")) - csa->token = T_MINIMIZE; - else if (the_same(csa->image, "maximize")) - csa->token = T_MAXIMIZE; - else if (the_same(csa->image, "maximum")) - csa->token = T_MAXIMIZE; - else if (the_same(csa->image, "max")) - csa->token = T_MAXIMIZE; - else if (the_same(csa->image, "subject")) - { if (csa->c == ' ') - { read_char(csa); - if (tolower(csa->c) == 't') - { csa->token = T_SUBJECT_TO; - csa->image[csa->imlen++] = ' '; - csa->image[csa->imlen] = '\0'; - add_char(csa); - if (tolower(csa->c) != 'o') - error(csa, "keyword 'subject to' incomplete\n"); - add_char(csa); - if (isalpha(csa->c)) - error(csa, "keyword '%s%c...' not recognized\n", - csa->image, csa->c); - } - } - } - else if (the_same(csa->image, "such")) - { if (csa->c == ' ') - { read_char(csa); - if (tolower(csa->c) == 't') - { csa->token = T_SUBJECT_TO; - csa->image[csa->imlen++] = ' '; - csa->image[csa->imlen] = '\0'; - add_char(csa); - if (tolower(csa->c) != 'h') -err: error(csa, "keyword 'such that' incomplete\n"); - add_char(csa); - if (tolower(csa->c) != 'a') goto err; - add_char(csa); - if (tolower(csa->c) != 't') goto err; - add_char(csa); - if (isalpha(csa->c)) - error(csa, "keyword '%s%c...' not recognized\n", - csa->image, csa->c); - } - } - } - else if (the_same(csa->image, "st")) - csa->token = T_SUBJECT_TO; - else if (the_same(csa->image, "s.t.")) - csa->token = T_SUBJECT_TO; - else if (the_same(csa->image, "st.")) - csa->token = T_SUBJECT_TO; - else if (the_same(csa->image, "bounds")) - csa->token = T_BOUNDS; - else if (the_same(csa->image, "bound")) - csa->token = T_BOUNDS; - else if (the_same(csa->image, "general")) - csa->token = T_GENERAL; - else if (the_same(csa->image, "generals")) - csa->token = T_GENERAL; - else if (the_same(csa->image, "gen")) - csa->token = T_GENERAL; - else if (the_same(csa->image, "integer")) - csa->token = T_INTEGER; - else if (the_same(csa->image, "integers")) - csa->token = T_INTEGER; - else if (the_same(csa->image, "int")) - csa->token = T_INTEGER; - else if (the_same(csa->image, "binary")) - csa->token = T_BINARY; - else if (the_same(csa->image, "binaries")) - csa->token = T_BINARY; - else if (the_same(csa->image, "bin")) - csa->token = T_BINARY; - else if (the_same(csa->image, "end")) - csa->token = T_END; - } - } - else if (isdigit(csa->c) || csa->c == '.') - { /* numeric constant */ - csa->token = T_NUMBER; - /* scan integer part */ - while (isdigit(csa->c)) add_char(csa); - /* scan optional fractional part (it is mandatory, if there is - no integer part) */ - if (csa->c == '.') - { add_char(csa); - if (csa->imlen == 1 && !isdigit(csa->c)) - error(csa, "invalid use of decimal point\n"); - while (isdigit(csa->c)) add_char(csa); - } - /* scan optional decimal exponent */ - if (csa->c == 'e' || csa->c == 'E') - { add_char(csa); - if (csa->c == '+' || csa->c == '-') add_char(csa); - if (!isdigit(csa->c)) - error(csa, "numeric constant '%s' incomplete\n", - csa->image); - while (isdigit(csa->c)) add_char(csa); - } - /* convert the numeric constant to floating-point */ - if (str2num(csa->image, &csa->value)) - error(csa, "numeric constant '%s' out of range\n", - csa->image); - } - else if (csa->c == '+') - csa->token = T_PLUS, add_char(csa); - else if (csa->c == '-') - csa->token = T_MINUS, add_char(csa); - else if (csa->c == ':') - csa->token = T_COLON, add_char(csa); - else if (csa->c == '<') - { csa->token = T_LE, add_char(csa); - if (csa->c == '=') add_char(csa); - } - else if (csa->c == '>') - { csa->token = T_GE, add_char(csa); - if (csa->c == '=') add_char(csa); - } - else if (csa->c == '=') - { csa->token = T_EQ, add_char(csa); - if (csa->c == '<') - csa->token = T_LE, add_char(csa); - else if (csa->c == '>') - csa->token = T_GE, add_char(csa); - } - else - error(csa, "character '%c' not recognized\n", csa->c); - /* skip non-significant characters */ - while (csa->c == ' ') read_char(csa); - return; -} - -static int find_col(struct csa *csa, char *name) -{ /* find column by its symbolic name */ - int j; - j = glp_find_col(csa->P, name); - if (j == 0) - { /* not found; create new column */ - j = glp_add_cols(csa->P, 1); - glp_set_col_name(csa->P, j, name); - /* enlarge working arrays, if necessary */ - if (csa->n_max < j) - { int n_max = csa->n_max; - int *ind = csa->ind; - double *val = csa->val; - char *flag = csa->flag; - double *lb = csa->lb; - double *ub = csa->ub; - csa->n_max += csa->n_max; - csa->ind = xcalloc(1+csa->n_max, sizeof(int)); - memcpy(&csa->ind[1], &ind[1], n_max * sizeof(int)); - xfree(ind); - csa->val = xcalloc(1+csa->n_max, sizeof(double)); - memcpy(&csa->val[1], &val[1], n_max * sizeof(double)); - xfree(val); - csa->flag = xcalloc(1+csa->n_max, sizeof(char)); - memset(&csa->flag[1], 0, csa->n_max * sizeof(char)); - memcpy(&csa->flag[1], &flag[1], n_max * sizeof(char)); - xfree(flag); - csa->lb = xcalloc(1+csa->n_max, sizeof(double)); - memcpy(&csa->lb[1], &lb[1], n_max * sizeof(double)); - xfree(lb); - csa->ub = xcalloc(1+csa->n_max, sizeof(double)); - memcpy(&csa->ub[1], &ub[1], n_max * sizeof(double)); - xfree(ub); - } - csa->lb[j] = +DBL_MAX, csa->ub[j] = -DBL_MAX; - } - return j; -} - -/*********************************************************************** -* parse_linear_form - parse linear form -* -* This routine parses the linear form using the following syntax: -* -* ::= -* ::= -* ::= | -* ::= | + | - | -* + | - -* -* The routine returns the number of terms in the linear form. */ - -static int parse_linear_form(struct csa *csa) -{ int j, k, len = 0, newlen; - double s, coef; -loop: /* parse an optional sign */ - if (csa->token == T_PLUS) - s = +1.0, scan_token(csa); - else if (csa->token == T_MINUS) - s = -1.0, scan_token(csa); - else - s = +1.0; - /* parse an optional coefficient */ - if (csa->token == T_NUMBER) - coef = csa->value, scan_token(csa); - else - coef = 1.0; - /* parse a variable name */ - if (csa->token != T_NAME) - error(csa, "missing variable name\n"); - /* find the corresponding column */ - j = find_col(csa, csa->image); - /* check if the variable is already used in the linear form */ - if (csa->flag[j]) - error(csa, "multiple use of variable '%s' not allowed\n", - csa->image); - /* add new term to the linear form */ - len++, csa->ind[len] = j, csa->val[len] = s * coef; - /* and mark that the variable is used in the linear form */ - csa->flag[j] = 1; - scan_token(csa); - /* if the next token is a sign, there is another term */ - if (csa->token == T_PLUS || csa->token == T_MINUS) goto loop; - /* clear marks of the variables used in the linear form */ - for (k = 1; k <= len; k++) csa->flag[csa->ind[k]] = 0; - /* remove zero coefficients */ - newlen = 0; - for (k = 1; k <= len; k++) - { if (csa->val[k] != 0.0) - { newlen++; - csa->ind[newlen] = csa->ind[k]; - csa->val[newlen] = csa->val[k]; - } - } - return newlen; -} - -/*********************************************************************** -* parse_objective - parse objective function -* -* This routine parses definition of the objective function using the -* following syntax: -* -* ::= minimize | minimum | min | maximize | maximum | max -* ::= | : -* ::= */ - -static void parse_objective(struct csa *csa) -{ /* parse objective sense */ - int k, len; - /* parse the keyword 'minimize' or 'maximize' */ - if (csa->token == T_MINIMIZE) - glp_set_obj_dir(csa->P, GLP_MIN); - else if (csa->token == T_MAXIMIZE) - glp_set_obj_dir(csa->P, GLP_MAX); - else - xassert(csa != csa); - scan_token(csa); - /* parse objective name */ - if (csa->token == T_NAME && csa->c == ':') - { /* objective name is followed by a colon */ - glp_set_obj_name(csa->P, csa->image); - scan_token(csa); - xassert(csa->token == T_COLON); - scan_token(csa); - } - else - { /* objective name is not specified; use default */ - glp_set_obj_name(csa->P, "obj"); - } - /* parse linear form */ - len = parse_linear_form(csa); - for (k = 1; k <= len; k++) - glp_set_obj_coef(csa->P, csa->ind[k], csa->val[k]); - return; -} - -/*********************************************************************** -* parse_constraints - parse constraints section -* -* This routine parses the constraints section using the following -* syntax: -* -* ::= | : -* ::= < | <= | =< | > | >= | => | = -* ::= | + | -* - -* ::= -* -* ::= subject to | such that | st | s.t. | st. -* ::= | -* */ - -static void parse_constraints(struct csa *csa) -{ int i, len, type; - double s; - /* parse the keyword 'subject to' */ - xassert(csa->token == T_SUBJECT_TO); - scan_token(csa); -loop: /* create new row (constraint) */ - i = glp_add_rows(csa->P, 1); - /* parse row name */ - if (csa->token == T_NAME && csa->c == ':') - { /* row name is followed by a colon */ - if (glp_find_row(csa->P, csa->image) != 0) - error(csa, "constraint '%s' multiply defined\n", - csa->image); - glp_set_row_name(csa->P, i, csa->image); - scan_token(csa); - xassert(csa->token == T_COLON); - scan_token(csa); - } - else - { /* row name is not specified; use default */ - char name[50]; - sprintf(name, "r.%d", csa->count); - glp_set_row_name(csa->P, i, name); - } - /* parse linear form */ - len = parse_linear_form(csa); - glp_set_mat_row(csa->P, i, len, csa->ind, csa->val); - /* parse constraint sense */ - if (csa->token == T_LE) - type = GLP_UP, scan_token(csa); - else if (csa->token == T_GE) - type = GLP_LO, scan_token(csa); - else if (csa->token == T_EQ) - type = GLP_FX, scan_token(csa); - else - error(csa, "missing constraint sense\n"); - /* parse right-hand side */ - if (csa->token == T_PLUS) - s = +1.0, scan_token(csa); - else if (csa->token == T_MINUS) - s = -1.0, scan_token(csa); - else - s = +1.0; - if (csa->token != T_NUMBER) - error(csa, "missing right-hand side\n"); - glp_set_row_bnds(csa->P, i, type, s * csa->value, s * csa->value); - /* the rest of the current line must be empty */ - if (!(csa->c == '\n' || csa->c == EOF)) - error(csa, "invalid symbol(s) beyond right-hand side\n"); - scan_token(csa); - /* if the next token is a sign, numeric constant, or a symbolic - name, here is another constraint */ - if (csa->token == T_PLUS || csa->token == T_MINUS || - csa->token == T_NUMBER || csa->token == T_NAME) goto loop; - return; -} - -static void set_lower_bound(struct csa *csa, int j, double lb) -{ /* set lower bound of j-th variable */ - if (csa->lb[j] != +DBL_MAX && !csa->lb_warn) - { warning(csa, "lower bound of variable '%s' redefined\n", - glp_get_col_name(csa->P, j)); - csa->lb_warn = 1; - } - csa->lb[j] = lb; - return; -} - -static void set_upper_bound(struct csa *csa, int j, double ub) -{ /* set upper bound of j-th variable */ - if (csa->ub[j] != -DBL_MAX && !csa->ub_warn) - { warning(csa, "upper bound of variable '%s' redefined\n", - glp_get_col_name(csa->P, j)); - csa->ub_warn = 1; - } - csa->ub[j] = ub; - return; -} - -/*********************************************************************** -* parse_bounds - parse bounds section -* -* This routine parses the bounds section using the following syntax: -* -* ::= -* ::= infinity | inf -* ::= | + | -* - | + | - -* ::= < | <= | =< -* ::= > | >= | => -* ::= | -* | | -* | = | free -* ::= bounds | bound -* ::= | -* */ - -static void parse_bounds(struct csa *csa) -{ int j, lb_flag; - double lb, s; - /* parse the keyword 'bounds' */ - xassert(csa->token == T_BOUNDS); - scan_token(csa); -loop: /* bound definition can start with a sign, numeric constant, or - a symbolic name */ - if (!(csa->token == T_PLUS || csa->token == T_MINUS || - csa->token == T_NUMBER || csa->token == T_NAME)) goto done; - /* parse bound definition */ - if (csa->token == T_PLUS || csa->token == T_MINUS) - { /* parse signed lower bound */ - lb_flag = 1; - s = (csa->token == T_PLUS ? +1.0 : -1.0); - scan_token(csa); - if (csa->token == T_NUMBER) - lb = s * csa->value, scan_token(csa); - else if (the_same(csa->image, "infinity") || - the_same(csa->image, "inf")) - { if (s > 0.0) - error(csa, "invalid use of '+inf' as lower bound\n"); - lb = -DBL_MAX, scan_token(csa); - } - else - error(csa, "missing lower bound\n"); - } - else if (csa->token == T_NUMBER) - { /* parse unsigned lower bound */ - lb_flag = 1; - lb = csa->value, scan_token(csa); - } - else - { /* lower bound is not specified */ - lb_flag = 0; - } - /* parse the token that should follow the lower bound */ - if (lb_flag) - { if (csa->token != T_LE) - error(csa, "missing '<', '<=', or '=<' after lower bound\n") - ; - scan_token(csa); - } - /* parse variable name */ - if (csa->token != T_NAME) - error(csa, "missing variable name\n"); - j = find_col(csa, csa->image); - /* set lower bound */ - if (lb_flag) set_lower_bound(csa, j, lb); - scan_token(csa); - /* parse the context that follows the variable name */ - if (csa->token == T_LE) - { /* parse upper bound */ - scan_token(csa); - if (csa->token == T_PLUS || csa->token == T_MINUS) - { /* parse signed upper bound */ - s = (csa->token == T_PLUS ? +1.0 : -1.0); - scan_token(csa); - if (csa->token == T_NUMBER) - { set_upper_bound(csa, j, s * csa->value); - scan_token(csa); - } - else if (the_same(csa->image, "infinity") || - the_same(csa->image, "inf")) - { if (s < 0.0) - error(csa, "invalid use of '-inf' as upper bound\n"); - set_upper_bound(csa, j, +DBL_MAX); - scan_token(csa); - } - else - error(csa, "missing upper bound\n"); - } - else if (csa->token == T_NUMBER) - { /* parse unsigned upper bound */ - set_upper_bound(csa, j, csa->value); - scan_token(csa); - } - else - error(csa, "missing upper bound\n"); - } - else if (csa->token == T_GE) - { /* parse lower bound */ - if (lb_flag) - { /* the context '... <= x >= ...' is invalid */ - error(csa, "invalid bound definition\n"); - } - scan_token(csa); - if (csa->token == T_PLUS || csa->token == T_MINUS) - { /* parse signed lower bound */ - s = (csa->token == T_PLUS ? +1.0 : -1.0); - scan_token(csa); - if (csa->token == T_NUMBER) - { set_lower_bound(csa, j, s * csa->value); - scan_token(csa); - } - else if (the_same(csa->image, "infinity") || - the_same(csa->image, "inf") == 0) - { if (s > 0.0) - error(csa, "invalid use of '+inf' as lower bound\n"); - set_lower_bound(csa, j, -DBL_MAX); - scan_token(csa); - } - else - error(csa, "missing lower bound\n"); - } - else if (csa->token == T_NUMBER) - { /* parse unsigned lower bound */ - set_lower_bound(csa, j, csa->value); - scan_token(csa); - } - else - error(csa, "missing lower bound\n"); - } - else if (csa->token == T_EQ) - { /* parse fixed value */ - if (lb_flag) - { /* the context '... <= x = ...' is invalid */ - error(csa, "invalid bound definition\n"); - } - scan_token(csa); - if (csa->token == T_PLUS || csa->token == T_MINUS) - { /* parse signed fixed value */ - s = (csa->token == T_PLUS ? +1.0 : -1.0); - scan_token(csa); - if (csa->token == T_NUMBER) - { set_lower_bound(csa, j, s * csa->value); - set_upper_bound(csa, j, s * csa->value); - scan_token(csa); - } - else - error(csa, "missing fixed value\n"); - } - else if (csa->token == T_NUMBER) - { /* parse unsigned fixed value */ - set_lower_bound(csa, j, csa->value); - set_upper_bound(csa, j, csa->value); - scan_token(csa); - } - else - error(csa, "missing fixed value\n"); - } - else if (the_same(csa->image, "free")) - { /* parse the keyword 'free' */ - if (lb_flag) - { /* the context '... <= x free ...' is invalid */ - error(csa, "invalid bound definition\n"); - } - set_lower_bound(csa, j, -DBL_MAX); - set_upper_bound(csa, j, +DBL_MAX); - scan_token(csa); - } - else if (!lb_flag) - { /* neither lower nor upper bounds are specified */ - error(csa, "invalid bound definition\n"); - } - goto loop; -done: return; -} - -/*********************************************************************** -* parse_integer - parse general, integer, or binary section -* -* ::= -* ::= general | generals | gen -* ::= integer | integers | int -* ::= binary | binaries | bin -*

    ::= -* ::=
    | -* */ - -static void parse_integer(struct csa *csa) -{ int j, binary; - /* parse the keyword 'general', 'integer', or 'binary' */ - if (csa->token == T_GENERAL) - binary = 0, scan_token(csa); - else if (csa->token == T_INTEGER) - binary = 0, scan_token(csa); - else if (csa->token == T_BINARY) - binary = 1, scan_token(csa); - else - xassert(csa != csa); - /* parse list of variables (may be empty) */ - while (csa->token == T_NAME) - { /* find the corresponding column */ - j = find_col(csa, csa->image); - /* change kind of the variable */ - glp_set_col_kind(csa->P, j, GLP_IV); - /* set bounds for the binary variable */ - if (binary) -#if 0 /* 07/VIII-2013 */ - { set_lower_bound(csa, j, 0.0); - set_upper_bound(csa, j, 1.0); - } -#else - { set_lower_bound(csa, j, - csa->lb[j] == +DBL_MAX ? 0.0 : csa->lb[j]); - set_upper_bound(csa, j, - csa->ub[j] == -DBL_MAX ? 1.0 : csa->ub[j]); - } -#endif - scan_token(csa); - } - return; -} - -int glp_read_lp(glp_prob *P, const glp_cpxcp *parm, const char *fname) -{ /* read problem data in CPLEX LP format */ - glp_cpxcp _parm; - struct csa _csa, *csa = &_csa; - int ret; - xprintf("Reading problem data from '%s'...\n", fname); - if (parm == NULL) - glp_init_cpxcp(&_parm), parm = &_parm; - /* check control parameters */ - check_parm("glp_read_lp", parm); - /* initialize common storage area */ - csa->P = P; - csa->parm = parm; - csa->fname = fname; - csa->fp = NULL; - if (setjmp(csa->jump)) - { ret = 1; - goto done; - } - csa->count = 0; - csa->c = '\n'; - csa->token = T_EOF; - csa->image[0] = '\0'; - csa->imlen = 0; - csa->value = 0.0; - csa->n_max = 100; - csa->ind = xcalloc(1+csa->n_max, sizeof(int)); - csa->val = xcalloc(1+csa->n_max, sizeof(double)); - csa->flag = xcalloc(1+csa->n_max, sizeof(char)); - memset(&csa->flag[1], 0, csa->n_max * sizeof(char)); - csa->lb = xcalloc(1+csa->n_max, sizeof(double)); - csa->ub = xcalloc(1+csa->n_max, sizeof(double)); -#if 1 /* 27/VII-2013 */ - csa->lb_warn = csa->ub_warn = 0; -#endif - /* erase problem object */ - glp_erase_prob(P); - glp_create_index(P); - /* open input CPLEX LP file */ - csa->fp = glp_open(fname, "r"); - if (csa->fp == NULL) - { xprintf("Unable to open '%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - /* scan very first token */ - scan_token(csa); - /* parse definition of the objective function */ - if (!(csa->token == T_MINIMIZE || csa->token == T_MAXIMIZE)) - error(csa, "'minimize' or 'maximize' keyword missing\n"); - parse_objective(csa); - /* parse constraints section */ - if (csa->token != T_SUBJECT_TO) - error(csa, "constraints section missing\n"); - parse_constraints(csa); - /* parse optional bounds section */ - if (csa->token == T_BOUNDS) parse_bounds(csa); - /* parse optional general, integer, and binary sections */ - while (csa->token == T_GENERAL || - csa->token == T_INTEGER || - csa->token == T_BINARY) parse_integer(csa); - /* check for the keyword 'end' */ - if (csa->token == T_END) - scan_token(csa); - else if (csa->token == T_EOF) - warning(csa, "keyword 'end' missing\n"); - else - error(csa, "symbol '%s' in wrong position\n", csa->image); - /* nothing must follow the keyword 'end' (except comments) */ - if (csa->token != T_EOF) - error(csa, "extra symbol(s) detected beyond 'end'\n"); - /* set bounds of variables */ - { int j, type; - double lb, ub; - for (j = 1; j <= P->n; j++) - { lb = csa->lb[j]; - ub = csa->ub[j]; - if (lb == +DBL_MAX) lb = 0.0; /* default lb */ - if (ub == -DBL_MAX) ub = +DBL_MAX; /* default ub */ - if (lb == -DBL_MAX && ub == +DBL_MAX) - type = GLP_FR; - else if (ub == +DBL_MAX) - type = GLP_LO; - else if (lb == -DBL_MAX) - type = GLP_UP; - else if (lb != ub) - type = GLP_DB; - else - type = GLP_FX; - glp_set_col_bnds(csa->P, j, type, lb, ub); - } - } - /* print some statistics */ - xprintf("%d row%s, %d column%s, %d non-zero%s\n", - P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s", - P->nnz, P->nnz == 1 ? "" : "s"); - if (glp_get_num_int(P) > 0) - { int ni = glp_get_num_int(P); - int nb = glp_get_num_bin(P); - if (ni == 1) - { if (nb == 0) - xprintf("One variable is integer\n"); - else - xprintf("One variable is binary\n"); - } - else - { xprintf("%d integer variables, ", ni); - if (nb == 0) - xprintf("none"); - else if (nb == 1) - xprintf("one"); - else if (nb == ni) - xprintf("all"); - else - xprintf("%d", nb); - xprintf(" of which %s binary\n", nb == 1 ? "is" : "are"); - } - } - xprintf("%d lines were read\n", csa->count); - /* problem data has been successfully read */ - glp_delete_index(P); - glp_sort_matrix(P); - ret = 0; -done: if (csa->fp != NULL) glp_close(csa->fp); - xfree(csa->ind); - xfree(csa->val); - xfree(csa->flag); - xfree(csa->lb); - xfree(csa->ub); - if (ret != 0) glp_erase_prob(P); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_write_lp - write problem data in CPLEX LP format -* -* SYNOPSIS -* -* int glp_write_lp(glp_prob *P, const glp_cpxcp *parm, const char -* *fname); -* -* DESCRIPTION -* -* The routine glp_write_lp writes problem data in CPLEX LP format to -* a text file. -* -* The parameter parm is a pointer to the structure glp_cpxcp, which -* specifies control parameters used by the routine. If parm is NULL, -* the routine uses default settings. -* -* The character string fname specifies a name of the text file to be -* written. -* -* RETURNS -* -* If the operation was successful, the routine glp_write_lp returns -* zero. Otherwise, it prints an error message and returns non-zero. */ - -#define csa csa1 - -struct csa -{ /* common storage area */ - glp_prob *P; - /* pointer to problem object */ - const glp_cpxcp *parm; - /* pointer to control parameters */ -}; - -static int check_name(char *name) -{ /* check if specified name is valid for CPLEX LP format */ - if (*name == '.') return 1; - if (isdigit((unsigned char)*name)) return 1; - for (; *name; name++) - { if (!isalnum((unsigned char)*name) && - strchr(CHAR_SET, (unsigned char)*name) == NULL) return 1; - } - return 0; /* name is ok */ -} - -static void adjust_name(char *name) -{ /* attempt to adjust specified name to make it valid for CPLEX LP - format */ - for (; *name; name++) - { if (*name == ' ') - *name = '_'; - else if (*name == '-') - *name = '~'; - else if (*name == '[') - *name = '('; - else if (*name == ']') - *name = ')'; - } - return; -} - -static char *row_name(struct csa *csa, int i, char rname[255+1]) -{ /* construct symbolic name of i-th row (constraint) */ - const char *name; - if (i == 0) - name = glp_get_obj_name(csa->P); - else - name = glp_get_row_name(csa->P, i); - if (name == NULL) goto fake; - strcpy(rname, name); - adjust_name(rname); - if (check_name(rname)) goto fake; - return rname; -fake: if (i == 0) - strcpy(rname, "obj"); - else - sprintf(rname, "r_%d", i); - return rname; -} - -static char *col_name(struct csa *csa, int j, char cname[255+1]) -{ /* construct symbolic name of j-th column (variable) */ - const char *name; - name = glp_get_col_name(csa->P, j); - if (name == NULL) goto fake; - strcpy(cname, name); - adjust_name(cname); - if (check_name(cname)) goto fake; - return cname; -fake: sprintf(cname, "x_%d", j); - return cname; -} - -int glp_write_lp(glp_prob *P, const glp_cpxcp *parm, const char *fname) -{ /* write problem data in CPLEX LP format */ - glp_cpxcp _parm; - struct csa _csa, *csa = &_csa; - glp_file *fp; - GLPROW *row; - GLPCOL *col; - GLPAIJ *aij; - int i, j, len, flag, count, ret; - char line[1000+1], term[500+1], name[255+1]; - xprintf("Writing problem data to '%s'...\n", fname); - if (parm == NULL) - glp_init_cpxcp(&_parm), parm = &_parm; - /* check control parameters */ - check_parm("glp_write_lp", parm); - /* initialize common storage area */ - csa->P = P; - csa->parm = parm; - /* create output CPLEX LP file */ - fp = glp_open(fname, "w"), count = 0; - if (fp == NULL) - { xprintf("Unable to create '%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - /* write problem name */ - xfprintf(fp, "\\* Problem: %s *\\\n", - P->name == NULL ? "Unknown" : P->name), count++; - xfprintf(fp, "\n"), count++; - /* the problem should contain at least one row and one column */ - if (!(P->m > 0 && P->n > 0)) - { xprintf("Warning: problem has no rows/columns\n"); - xfprintf(fp, "\\* WARNING: PROBLEM HAS NO ROWS/COLUMNS *\\\n"), - count++; - xfprintf(fp, "\n"), count++; - goto skip; - } - /* write the objective function definition */ - if (P->dir == GLP_MIN) - xfprintf(fp, "Minimize\n"), count++; - else if (P->dir == GLP_MAX) - xfprintf(fp, "Maximize\n"), count++; - else - xassert(P != P); - row_name(csa, 0, name); - sprintf(line, " %s:", name); - len = 0; - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - if (col->coef != 0.0 || col->ptr == NULL) - { len++; - col_name(csa, j, name); - if (col->coef == 0.0) - sprintf(term, " + 0 %s", name); /* empty column */ - else if (col->coef == +1.0) - sprintf(term, " + %s", name); - else if (col->coef == -1.0) - sprintf(term, " - %s", name); - else if (col->coef > 0.0) - sprintf(term, " + %.*g %s", DBL_DIG, +col->coef, name); - else - sprintf(term, " - %.*g %s", DBL_DIG, -col->coef, name); - if (strlen(line) + strlen(term) > 72) - xfprintf(fp, "%s\n", line), line[0] = '\0', count++; - strcat(line, term); - } - } - if (len == 0) - { /* empty objective */ - sprintf(term, " 0 %s", col_name(csa, 1, name)); - strcat(line, term); - } - xfprintf(fp, "%s\n", line), count++; - if (P->c0 != 0.0) - xfprintf(fp, "\\* constant term = %.*g *\\\n", DBL_DIG, P->c0), - count++; - xfprintf(fp, "\n"), count++; - /* write the constraints section */ - xfprintf(fp, "Subject To\n"), count++; - for (i = 1; i <= P->m; i++) - { row = P->row[i]; - if (row->type == GLP_FR) continue; /* skip free row */ - row_name(csa, i, name); - sprintf(line, " %s:", name); - /* linear form */ - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { col_name(csa, aij->col->j, name); - if (aij->val == +1.0) - sprintf(term, " + %s", name); - else if (aij->val == -1.0) - sprintf(term, " - %s", name); - else if (aij->val > 0.0) - sprintf(term, " + %.*g %s", DBL_DIG, +aij->val, name); - else - sprintf(term, " - %.*g %s", DBL_DIG, -aij->val, name); - if (strlen(line) + strlen(term) > 72) - xfprintf(fp, "%s\n", line), line[0] = '\0', count++; - strcat(line, term); - } - if (row->type == GLP_DB) - { /* double-bounded (ranged) constraint */ - sprintf(term, " - ~r_%d", i); - if (strlen(line) + strlen(term) > 72) - xfprintf(fp, "%s\n", line), line[0] = '\0', count++; - strcat(line, term); - } - else if (row->ptr == NULL) - { /* empty constraint */ - sprintf(term, " 0 %s", col_name(csa, 1, name)); - strcat(line, term); - } - /* right hand-side */ - if (row->type == GLP_LO) - sprintf(term, " >= %.*g", DBL_DIG, row->lb); - else if (row->type == GLP_UP) - sprintf(term, " <= %.*g", DBL_DIG, row->ub); - else if (row->type == GLP_DB || row->type == GLP_FX) - sprintf(term, " = %.*g", DBL_DIG, row->lb); - else - xassert(row != row); - if (strlen(line) + strlen(term) > 72) - xfprintf(fp, "%s\n", line), line[0] = '\0', count++; - strcat(line, term); - xfprintf(fp, "%s\n", line), count++; - } - xfprintf(fp, "\n"), count++; - /* write the bounds section */ - flag = 0; - for (i = 1; i <= P->m; i++) - { row = P->row[i]; - if (row->type != GLP_DB) continue; - if (!flag) - xfprintf(fp, "Bounds\n"), flag = 1, count++; - xfprintf(fp, " 0 <= ~r_%d <= %.*g\n", - i, DBL_DIG, row->ub - row->lb), count++; - } - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - if (col->type == GLP_LO && col->lb == 0.0) continue; - if (!flag) - xfprintf(fp, "Bounds\n"), flag = 1, count++; - col_name(csa, j, name); - if (col->type == GLP_FR) - xfprintf(fp, " %s free\n", name), count++; - else if (col->type == GLP_LO) - xfprintf(fp, " %s >= %.*g\n", - name, DBL_DIG, col->lb), count++; - else if (col->type == GLP_UP) - xfprintf(fp, " -Inf <= %s <= %.*g\n", - name, DBL_DIG, col->ub), count++; - else if (col->type == GLP_DB) - xfprintf(fp, " %.*g <= %s <= %.*g\n", - DBL_DIG, col->lb, name, DBL_DIG, col->ub), count++; - else if (col->type == GLP_FX) - xfprintf(fp, " %s = %.*g\n", - name, DBL_DIG, col->lb), count++; - else - xassert(col != col); - } - if (flag) xfprintf(fp, "\n"), count++; - /* write the integer section */ - flag = 0; - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - if (col->kind == GLP_CV) continue; - xassert(col->kind == GLP_IV); - if (!flag) - xfprintf(fp, "Generals\n"), flag = 1, count++; - xfprintf(fp, " %s\n", col_name(csa, j, name)), count++; - } - if (flag) xfprintf(fp, "\n"), count++; -skip: /* write the end keyword */ - xfprintf(fp, "End\n"), count++; -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on '%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - /* problem data has been successfully written */ - xprintf("%d lines were written\n", count); - ret = 0; -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpdmx.c b/resources/3rdparty/glpk-4.53/src/glpdmx.c deleted file mode 100644 index 329baaf69..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpdmx.c +++ /dev/null @@ -1,1693 +0,0 @@ -/* glpdmx.c (reading/writing data in DIMACS format) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "misc.h" -#include "prob.h" - -#define xfprintf glp_format - -struct csa -{ /* common storage area */ - jmp_buf jump; - /* label for go to in case of error */ - const char *fname; - /* name of input text file */ - glp_file *fp; - /* stream assigned to input text file */ - int count; - /* line count */ - int c; - /* current character */ - char field[255+1]; - /* data field */ - int empty; - /* warning 'empty line ignored' was printed */ - int nonint; - /* warning 'non-integer data detected' was printed */ -}; - -static void error(struct csa *csa, const char *fmt, ...) -{ /* print error message and terminate processing */ - va_list arg; - xprintf("%s:%d: error: ", csa->fname, csa->count); - va_start(arg, fmt); - xvprintf(fmt, arg); - va_end(arg); - xprintf("\n"); - longjmp(csa->jump, 1); - /* no return */ -} - -static void warning(struct csa *csa, const char *fmt, ...) -{ /* print warning message and continue processing */ - va_list arg; - xprintf("%s:%d: warning: ", csa->fname, csa->count); - va_start(arg, fmt); - xvprintf(fmt, arg); - va_end(arg); - xprintf("\n"); - return; -} - -static void read_char(struct csa *csa) -{ /* read character from input text file */ - int c; - if (csa->c == '\n') csa->count++; - c = glp_getc(csa->fp); - if (c < 0) - { if (glp_ioerr(csa->fp)) - error(csa, "read error - %s", get_err_msg()); - else if (csa->c == '\n') - error(csa, "unexpected end of file"); - else - { warning(csa, "missing final end of line"); - c = '\n'; - } - } - else if (c == '\n') - ; - else if (isspace(c)) - c = ' '; - else if (iscntrl(c)) - error(csa, "invalid control character 0x%02X", c); - csa->c = c; - return; -} - -static void read_designator(struct csa *csa) -{ /* read one-character line designator */ - xassert(csa->c == '\n'); - read_char(csa); - for (;;) - { /* skip preceding white-space characters */ - while (csa->c == ' ') - read_char(csa); - if (csa->c == '\n') - { /* ignore empty line */ - if (!csa->empty) - { warning(csa, "empty line ignored"); - csa->empty = 1; - } - read_char(csa); - } - else if (csa->c == 'c') - { /* skip comment line */ - while (csa->c != '\n') - read_char(csa); - read_char(csa); - } - else - { /* hmm... looks like a line designator */ - csa->field[0] = (char)csa->c, csa->field[1] = '\0'; - /* check that it is followed by a white-space character */ - read_char(csa); - if (!(csa->c == ' ' || csa->c == '\n')) - error(csa, "line designator missing or invalid"); - break; - } - } - return; -} - -static void read_field(struct csa *csa) -{ /* read data field */ - int len = 0; - /* skip preceding white-space characters */ - while (csa->c == ' ') - read_char(csa); - /* scan data field */ - if (csa->c == '\n') - error(csa, "unexpected end of line"); - while (!(csa->c == ' ' || csa->c == '\n')) - { if (len == sizeof(csa->field)-1) - error(csa, "data field `%.15s...' too long", csa->field); - csa->field[len++] = (char)csa->c; - read_char(csa); - } - csa->field[len] = '\0'; - return; -} - -static void end_of_line(struct csa *csa) -{ /* skip white-space characters until end of line */ - while (csa->c == ' ') - read_char(csa); - if (csa->c != '\n') - error(csa, "too many data fields specified"); - return; -} - -static void check_int(struct csa *csa, double num) -{ /* print a warning if non-integer data are detected */ - if (!csa->nonint && num != floor(num)) - { warning(csa, "non-integer data detected"); - csa->nonint = 1; - } - return; -} - -/*********************************************************************** -* NAME -* -* glp_read_mincost - read min-cost flow problem data in DIMACS format -* -* SYNOPSIS -* -* int glp_read_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, -* int a_cost, const char *fname); -* -* DESCRIPTION -* -* The routine glp_read_mincost reads minimum cost flow problem data in -* DIMACS format from a text file. -* -* RETURNS -* -* If the operation was successful, the routine returns zero. Otherwise -* it prints an error message and returns non-zero. */ - -int glp_read_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, - int a_cost, const char *fname) -{ struct csa _csa, *csa = &_csa; - glp_vertex *v; - glp_arc *a; - int i, j, k, nv, na, ret = 0; - double rhs, low, cap, cost; - char *flag = NULL; - if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) - xerror("glp_read_mincost: v_rhs = %d; invalid offset\n", - v_rhs); - if (a_low >= 0 && a_low > G->a_size - (int)sizeof(double)) - xerror("glp_read_mincost: a_low = %d; invalid offset\n", - a_low); - if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) - xerror("glp_read_mincost: a_cap = %d; invalid offset\n", - a_cap); - if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) - xerror("glp_read_mincost: a_cost = %d; invalid offset\n", - a_cost); - glp_erase_graph(G, G->v_size, G->a_size); - if (setjmp(csa->jump)) - { ret = 1; - goto done; - } - csa->fname = fname; - csa->fp = NULL; - csa->count = 0; - csa->c = '\n'; - csa->field[0] = '\0'; - csa->empty = csa->nonint = 0; - xprintf("Reading min-cost flow problem data from `%s'...\n", - fname); - csa->fp = glp_open(fname, "r"); - if (csa->fp == NULL) - { xprintf("Unable to open `%s' - %s\n", fname, get_err_msg()); - longjmp(csa->jump, 1); - } - /* read problem line */ - read_designator(csa); - if (strcmp(csa->field, "p") != 0) - error(csa, "problem line missing or invalid"); - read_field(csa); - if (strcmp(csa->field, "min") != 0) - error(csa, "wrong problem designator; `min' expected"); - read_field(csa); - if (!(str2int(csa->field, &nv) == 0 && nv >= 0)) - error(csa, "number of nodes missing or invalid"); - read_field(csa); - if (!(str2int(csa->field, &na) == 0 && na >= 0)) - error(csa, "number of arcs missing or invalid"); - xprintf("Flow network has %d node%s and %d arc%s\n", - nv, nv == 1 ? "" : "s", na, na == 1 ? "" : "s"); - if (nv > 0) glp_add_vertices(G, nv); - end_of_line(csa); - /* read node descriptor lines */ - flag = xcalloc(1+nv, sizeof(char)); - memset(&flag[1], 0, nv * sizeof(char)); - if (v_rhs >= 0) - { rhs = 0.0; - for (i = 1; i <= nv; i++) - { v = G->v[i]; - memcpy((char *)v->data + v_rhs, &rhs, sizeof(double)); - } - } - for (;;) - { read_designator(csa); - if (strcmp(csa->field, "n") != 0) break; - read_field(csa); - if (str2int(csa->field, &i) != 0) - error(csa, "node number missing or invalid"); - if (!(1 <= i && i <= nv)) - error(csa, "node number %d out of range", i); - if (flag[i]) - error(csa, "duplicate descriptor of node %d", i); - read_field(csa); - if (str2num(csa->field, &rhs) != 0) - error(csa, "node supply/demand missing or invalid"); - check_int(csa, rhs); - if (v_rhs >= 0) - { v = G->v[i]; - memcpy((char *)v->data + v_rhs, &rhs, sizeof(double)); - } - flag[i] = 1; - end_of_line(csa); - } - xfree(flag), flag = NULL; - /* read arc descriptor lines */ - for (k = 1; k <= na; k++) - { if (k > 1) read_designator(csa); - if (strcmp(csa->field, "a") != 0) - error(csa, "wrong line designator; `a' expected"); - read_field(csa); - if (str2int(csa->field, &i) != 0) - error(csa, "starting node number missing or invalid"); - if (!(1 <= i && i <= nv)) - error(csa, "starting node number %d out of range", i); - read_field(csa); - if (str2int(csa->field, &j) != 0) - error(csa, "ending node number missing or invalid"); - if (!(1 <= j && j <= nv)) - error(csa, "ending node number %d out of range", j); - read_field(csa); - if (!(str2num(csa->field, &low) == 0 && low >= 0.0)) - error(csa, "lower bound of arc flow missing or invalid"); - check_int(csa, low); - read_field(csa); - if (!(str2num(csa->field, &cap) == 0 && cap >= low)) - error(csa, "upper bound of arc flow missing or invalid"); - check_int(csa, cap); - read_field(csa); - if (str2num(csa->field, &cost) != 0) - error(csa, "per-unit cost of arc flow missing or invalid"); - check_int(csa, cost); - a = glp_add_arc(G, i, j); - if (a_low >= 0) - memcpy((char *)a->data + a_low, &low, sizeof(double)); - if (a_cap >= 0) - memcpy((char *)a->data + a_cap, &cap, sizeof(double)); - if (a_cost >= 0) - memcpy((char *)a->data + a_cost, &cost, sizeof(double)); - end_of_line(csa); - } - xprintf("%d lines were read\n", csa->count); -done: if (ret) glp_erase_graph(G, G->v_size, G->a_size); - if (csa->fp != NULL) glp_close(csa->fp); - if (flag != NULL) xfree(flag); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_write_mincost - write min-cost flow problem data in DIMACS format -* -* SYNOPSIS -* -* int glp_write_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, -* int a_cost, const char *fname); -* -* DESCRIPTION -* -* The routine glp_write_mincost writes minimum cost flow problem data -* in DIMACS format to a text file. -* -* RETURNS -* -* If the operation was successful, the routine returns zero. Otherwise -* it prints an error message and returns non-zero. */ - -int glp_write_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, - int a_cost, const char *fname) -{ glp_file *fp; - glp_vertex *v; - glp_arc *a; - int i, count = 0, ret; - double rhs, low, cap, cost; - if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) - xerror("glp_write_mincost: v_rhs = %d; invalid offset\n", - v_rhs); - if (a_low >= 0 && a_low > G->a_size - (int)sizeof(double)) - xerror("glp_write_mincost: a_low = %d; invalid offset\n", - a_low); - if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) - xerror("glp_write_mincost: a_cap = %d; invalid offset\n", - a_cap); - if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) - xerror("glp_write_mincost: a_cost = %d; invalid offset\n", - a_cost); - xprintf("Writing min-cost flow problem data to `%s'...\n", - fname); - fp = glp_open(fname, "w"); - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xfprintf(fp, "c %s\n", - G->name == NULL ? "unknown" : G->name), count++; - xfprintf(fp, "p min %d %d\n", G->nv, G->na), count++; - if (v_rhs >= 0) - { for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - memcpy(&rhs, (char *)v->data + v_rhs, sizeof(double)); - if (rhs != 0.0) - xfprintf(fp, "n %d %.*g\n", i, DBL_DIG, rhs), count++; - } - } - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { if (a_low >= 0) - memcpy(&low, (char *)a->data + a_low, sizeof(double)); - else - low = 0.0; - if (a_cap >= 0) - memcpy(&cap, (char *)a->data + a_cap, sizeof(double)); - else - cap = 1.0; - if (a_cost >= 0) - memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); - else - cost = 0.0; - xfprintf(fp, "a %d %d %.*g %.*g %.*g\n", - a->tail->i, a->head->i, DBL_DIG, low, DBL_DIG, cap, - DBL_DIG, cost), count++; - } - } - xfprintf(fp, "c eof\n"), count++; -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xprintf("%d lines were written\n", count); - ret = 0; -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_read_maxflow - read maximum flow problem data in DIMACS format -* -* SYNOPSIS -* -* int glp_read_maxflow(glp_graph *G, int *s, int *t, int a_cap, -* const char *fname); -* -* DESCRIPTION -* -* The routine glp_read_maxflow reads maximum flow problem data in -* DIMACS format from a text file. -* -* RETURNS -* -* If the operation was successful, the routine returns zero. Otherwise -* it prints an error message and returns non-zero. */ - -int glp_read_maxflow(glp_graph *G, int *_s, int *_t, int a_cap, - const char *fname) -{ struct csa _csa, *csa = &_csa; - glp_arc *a; - int i, j, k, s, t, nv, na, ret = 0; - double cap; - if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) - xerror("glp_read_maxflow: a_cap = %d; invalid offset\n", - a_cap); - glp_erase_graph(G, G->v_size, G->a_size); - if (setjmp(csa->jump)) - { ret = 1; - goto done; - } - csa->fname = fname; - csa->fp = NULL; - csa->count = 0; - csa->c = '\n'; - csa->field[0] = '\0'; - csa->empty = csa->nonint = 0; - xprintf("Reading maximum flow problem data from `%s'...\n", - fname); - csa->fp = glp_open(fname, "r"); - if (csa->fp == NULL) - { xprintf("Unable to open `%s' - %s\n", fname, get_err_msg()); - longjmp(csa->jump, 1); - } - /* read problem line */ - read_designator(csa); - if (strcmp(csa->field, "p") != 0) - error(csa, "problem line missing or invalid"); - read_field(csa); - if (strcmp(csa->field, "max") != 0) - error(csa, "wrong problem designator; `max' expected"); - read_field(csa); - if (!(str2int(csa->field, &nv) == 0 && nv >= 2)) - error(csa, "number of nodes missing or invalid"); - read_field(csa); - if (!(str2int(csa->field, &na) == 0 && na >= 0)) - error(csa, "number of arcs missing or invalid"); - xprintf("Flow network has %d node%s and %d arc%s\n", - nv, nv == 1 ? "" : "s", na, na == 1 ? "" : "s"); - if (nv > 0) glp_add_vertices(G, nv); - end_of_line(csa); - /* read node descriptor lines */ - s = t = 0; - for (;;) - { read_designator(csa); - if (strcmp(csa->field, "n") != 0) break; - read_field(csa); - if (str2int(csa->field, &i) != 0) - error(csa, "node number missing or invalid"); - if (!(1 <= i && i <= nv)) - error(csa, "node number %d out of range", i); - read_field(csa); - if (strcmp(csa->field, "s") == 0) - { if (s > 0) - error(csa, "only one source node allowed"); - s = i; - } - else if (strcmp(csa->field, "t") == 0) - { if (t > 0) - error(csa, "only one sink node allowed"); - t = i; - } - else - error(csa, "wrong node designator; `s' or `t' expected"); - if (s > 0 && s == t) - error(csa, "source and sink nodes must be distinct"); - end_of_line(csa); - } - if (s == 0) - error(csa, "source node descriptor missing\n"); - if (t == 0) - error(csa, "sink node descriptor missing\n"); - if (_s != NULL) *_s = s; - if (_t != NULL) *_t = t; - /* read arc descriptor lines */ - for (k = 1; k <= na; k++) - { if (k > 1) read_designator(csa); - if (strcmp(csa->field, "a") != 0) - error(csa, "wrong line designator; `a' expected"); - read_field(csa); - if (str2int(csa->field, &i) != 0) - error(csa, "starting node number missing or invalid"); - if (!(1 <= i && i <= nv)) - error(csa, "starting node number %d out of range", i); - read_field(csa); - if (str2int(csa->field, &j) != 0) - error(csa, "ending node number missing or invalid"); - if (!(1 <= j && j <= nv)) - error(csa, "ending node number %d out of range", j); - read_field(csa); - if (!(str2num(csa->field, &cap) == 0 && cap >= 0.0)) - error(csa, "arc capacity missing or invalid"); - check_int(csa, cap); - a = glp_add_arc(G, i, j); - if (a_cap >= 0) - memcpy((char *)a->data + a_cap, &cap, sizeof(double)); - end_of_line(csa); - } - xprintf("%d lines were read\n", csa->count); -done: if (ret) glp_erase_graph(G, G->v_size, G->a_size); - if (csa->fp != NULL) glp_close(csa->fp); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_write_maxflow - write maximum flow problem data in DIMACS format -* -* SYNOPSIS -* -* int glp_write_maxflow(glp_graph *G, int s, int t, int a_cap, -* const char *fname); -* -* DESCRIPTION -* -* The routine glp_write_maxflow writes maximum flow problem data in -* DIMACS format to a text file. -* -* RETURNS -* -* If the operation was successful, the routine returns zero. Otherwise -* it prints an error message and returns non-zero. */ - -int glp_write_maxflow(glp_graph *G, int s, int t, int a_cap, - const char *fname) -{ glp_file *fp; - glp_vertex *v; - glp_arc *a; - int i, count = 0, ret; - double cap; - if (!(1 <= s && s <= G->nv)) - xerror("glp_write_maxflow: s = %d; source node number out of r" - "ange\n", s); - if (!(1 <= t && t <= G->nv)) - xerror("glp_write_maxflow: t = %d: sink node number out of ran" - "ge\n", t); - if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) - xerror("glp_write_mincost: a_cap = %d; invalid offset\n", - a_cap); - xprintf("Writing maximum flow problem data to `%s'...\n", - fname); - fp = glp_open(fname, "w"); - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xfprintf(fp, "c %s\n", - G->name == NULL ? "unknown" : G->name), count++; - xfprintf(fp, "p max %d %d\n", G->nv, G->na), count++; - xfprintf(fp, "n %d s\n", s), count++; - xfprintf(fp, "n %d t\n", t), count++; - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { if (a_cap >= 0) - memcpy(&cap, (char *)a->data + a_cap, sizeof(double)); - else - cap = 1.0; - xfprintf(fp, "a %d %d %.*g\n", - a->tail->i, a->head->i, DBL_DIG, cap), count++; - } - } - xfprintf(fp, "c eof\n"), count++; -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xprintf("%d lines were written\n", count); - ret = 0; -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_read_asnprob - read assignment problem data in DIMACS format -* -* SYNOPSIS -* -* int glp_read_asnprob(glp_graph *G, int v_set, int a_cost, -* const char *fname); -* -* DESCRIPTION -* -* The routine glp_read_asnprob reads assignment problem data in DIMACS -* format from a text file. -* -* RETURNS -* -* If the operation was successful, the routine returns zero. Otherwise -* it prints an error message and returns non-zero. */ - -int glp_read_asnprob(glp_graph *G, int v_set, int a_cost, const char - *fname) -{ struct csa _csa, *csa = &_csa; - glp_vertex *v; - glp_arc *a; - int nv, na, n1, i, j, k, ret = 0; - double cost; - char *flag = NULL; - if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) - xerror("glp_read_asnprob: v_set = %d; invalid offset\n", - v_set); - if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) - xerror("glp_read_asnprob: a_cost = %d; invalid offset\n", - a_cost); - glp_erase_graph(G, G->v_size, G->a_size); - if (setjmp(csa->jump)) - { ret = 1; - goto done; - } - csa->fname = fname; - csa->fp = NULL; - csa->count = 0; - csa->c = '\n'; - csa->field[0] = '\0'; - csa->empty = csa->nonint = 0; - xprintf("Reading assignment problem data from `%s'...\n", fname); - csa->fp = glp_open(fname, "r"); - if (csa->fp == NULL) - { xprintf("Unable to open `%s' - %s\n", fname, get_err_msg()); - longjmp(csa->jump, 1); - } - /* read problem line */ - read_designator(csa); - if (strcmp(csa->field, "p") != 0) - error(csa, "problem line missing or invalid"); - read_field(csa); - if (strcmp(csa->field, "asn") != 0) - error(csa, "wrong problem designator; `asn' expected"); - read_field(csa); - if (!(str2int(csa->field, &nv) == 0 && nv >= 0)) - error(csa, "number of nodes missing or invalid"); - read_field(csa); - if (!(str2int(csa->field, &na) == 0 && na >= 0)) - error(csa, "number of arcs missing or invalid"); - if (nv > 0) glp_add_vertices(G, nv); - end_of_line(csa); - /* read node descriptor lines */ - flag = xcalloc(1+nv, sizeof(char)); - memset(&flag[1], 0, nv * sizeof(char)); - n1 = 0; - for (;;) - { read_designator(csa); - if (strcmp(csa->field, "n") != 0) break; - read_field(csa); - if (str2int(csa->field, &i) != 0) - error(csa, "node number missing or invalid"); - if (!(1 <= i && i <= nv)) - error(csa, "node number %d out of range", i); - if (flag[i]) - error(csa, "duplicate descriptor of node %d", i); - flag[i] = 1, n1++; - end_of_line(csa); - } - xprintf( - "Assignment problem has %d + %d = %d node%s and %d arc%s\n", - n1, nv - n1, nv, nv == 1 ? "" : "s", na, na == 1 ? "" : "s"); - if (v_set >= 0) - { for (i = 1; i <= nv; i++) - { v = G->v[i]; - k = (flag[i] ? 0 : 1); - memcpy((char *)v->data + v_set, &k, sizeof(int)); - } - } - /* read arc descriptor lines */ - for (k = 1; k <= na; k++) - { if (k > 1) read_designator(csa); - if (strcmp(csa->field, "a") != 0) - error(csa, "wrong line designator; `a' expected"); - read_field(csa); - if (str2int(csa->field, &i) != 0) - error(csa, "starting node number missing or invalid"); - if (!(1 <= i && i <= nv)) - error(csa, "starting node number %d out of range", i); - if (!flag[i]) - error(csa, "node %d cannot be a starting node", i); - read_field(csa); - if (str2int(csa->field, &j) != 0) - error(csa, "ending node number missing or invalid"); - if (!(1 <= j && j <= nv)) - error(csa, "ending node number %d out of range", j); - if (flag[j]) - error(csa, "node %d cannot be an ending node", j); - read_field(csa); - if (str2num(csa->field, &cost) != 0) - error(csa, "arc cost missing or invalid"); - check_int(csa, cost); - a = glp_add_arc(G, i, j); - if (a_cost >= 0) - memcpy((char *)a->data + a_cost, &cost, sizeof(double)); - end_of_line(csa); - } - xprintf("%d lines were read\n", csa->count); -done: if (ret) glp_erase_graph(G, G->v_size, G->a_size); - if (csa->fp != NULL) glp_close(csa->fp); - if (flag != NULL) xfree(flag); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_write_asnprob - write assignment problem data in DIMACS format -* -* SYNOPSIS -* -* int glp_write_asnprob(glp_graph *G, int v_set, int a_cost, -* const char *fname); -* -* DESCRIPTION -* -* The routine glp_write_asnprob writes assignment problem data in -* DIMACS format to a text file. -* -* RETURNS -* -* If the operation was successful, the routine returns zero. Otherwise -* it prints an error message and returns non-zero. */ - -int glp_write_asnprob(glp_graph *G, int v_set, int a_cost, const char - *fname) -{ glp_file *fp; - glp_vertex *v; - glp_arc *a; - int i, k, count = 0, ret; - double cost; - if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) - xerror("glp_write_asnprob: v_set = %d; invalid offset\n", - v_set); - if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) - xerror("glp_write_asnprob: a_cost = %d; invalid offset\n", - a_cost); - xprintf("Writing assignment problem data to `%s'...\n", fname); - fp = glp_open(fname, "w"); - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xfprintf(fp, "c %s\n", - G->name == NULL ? "unknown" : G->name), count++; - xfprintf(fp, "p asn %d %d\n", G->nv, G->na), count++; - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - if (v_set >= 0) - memcpy(&k, (char *)v->data + v_set, sizeof(int)); - else - k = (v->out != NULL ? 0 : 1); - if (k == 0) - xfprintf(fp, "n %d\n", i), count++; - } - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (a = v->out; a != NULL; a = a->t_next) - { if (a_cost >= 0) - memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); - else - cost = 1.0; - xfprintf(fp, "a %d %d %.*g\n", - a->tail->i, a->head->i, DBL_DIG, cost), count++; - } - } - xfprintf(fp, "c eof\n"), count++; -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xprintf("%d lines were written\n", count); - ret = 0; -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_read_ccdata - read graph in DIMACS clique/coloring format -* -* SYNOPSIS -* -* int glp_read_ccdata(glp_graph *G, int v_wgt, const char *fname); -* -* DESCRIPTION -* -* The routine glp_read_ccdata reads an (undirected) graph in DIMACS -* clique/coloring format from a text file. -* -* RETURNS -* -* If the operation was successful, the routine returns zero. Otherwise -* it prints an error message and returns non-zero. */ - -int glp_read_ccdata(glp_graph *G, int v_wgt, const char *fname) -{ struct csa _csa, *csa = &_csa; - glp_vertex *v; - int i, j, k, nv, ne, ret = 0; - double w; - char *flag = NULL; - if (v_wgt >= 0 && v_wgt > G->v_size - (int)sizeof(double)) - xerror("glp_read_ccdata: v_wgt = %d; invalid offset\n", - v_wgt); - glp_erase_graph(G, G->v_size, G->a_size); - if (setjmp(csa->jump)) - { ret = 1; - goto done; - } - csa->fname = fname; - csa->fp = NULL; - csa->count = 0; - csa->c = '\n'; - csa->field[0] = '\0'; - csa->empty = csa->nonint = 0; - xprintf("Reading graph from `%s'...\n", fname); - csa->fp = glp_open(fname, "r"); - if (csa->fp == NULL) - { xprintf("Unable to open `%s' - %s\n", fname, get_err_msg()); - longjmp(csa->jump, 1); - } - /* read problem line */ - read_designator(csa); - if (strcmp(csa->field, "p") != 0) - error(csa, "problem line missing or invalid"); - read_field(csa); - if (strcmp(csa->field, "edge") != 0) - error(csa, "wrong problem designator; `edge' expected"); - read_field(csa); - if (!(str2int(csa->field, &nv) == 0 && nv >= 0)) - error(csa, "number of vertices missing or invalid"); - read_field(csa); - if (!(str2int(csa->field, &ne) == 0 && ne >= 0)) - error(csa, "number of edges missing or invalid"); - xprintf("Graph has %d vert%s and %d edge%s\n", - nv, nv == 1 ? "ex" : "ices", ne, ne == 1 ? "" : "s"); - if (nv > 0) glp_add_vertices(G, nv); - end_of_line(csa); - /* read node descriptor lines */ - flag = xcalloc(1+nv, sizeof(char)); - memset(&flag[1], 0, nv * sizeof(char)); - if (v_wgt >= 0) - { w = 1.0; - for (i = 1; i <= nv; i++) - { v = G->v[i]; - memcpy((char *)v->data + v_wgt, &w, sizeof(double)); - } - } - for (;;) - { read_designator(csa); - if (strcmp(csa->field, "n") != 0) break; - read_field(csa); - if (str2int(csa->field, &i) != 0) - error(csa, "vertex number missing or invalid"); - if (!(1 <= i && i <= nv)) - error(csa, "vertex number %d out of range", i); - if (flag[i]) - error(csa, "duplicate descriptor of vertex %d", i); - read_field(csa); - if (str2num(csa->field, &w) != 0) - error(csa, "vertex weight missing or invalid"); - check_int(csa, w); - if (v_wgt >= 0) - { v = G->v[i]; - memcpy((char *)v->data + v_wgt, &w, sizeof(double)); - } - flag[i] = 1; - end_of_line(csa); - } - xfree(flag), flag = NULL; - /* read edge descriptor lines */ - for (k = 1; k <= ne; k++) - { if (k > 1) read_designator(csa); - if (strcmp(csa->field, "e") != 0) - error(csa, "wrong line designator; `e' expected"); - read_field(csa); - if (str2int(csa->field, &i) != 0) - error(csa, "first vertex number missing or invalid"); - if (!(1 <= i && i <= nv)) - error(csa, "first vertex number %d out of range", i); - read_field(csa); - if (str2int(csa->field, &j) != 0) - error(csa, "second vertex number missing or invalid"); - if (!(1 <= j && j <= nv)) - error(csa, "second vertex number %d out of range", j); - glp_add_arc(G, i, j); - end_of_line(csa); - } - xprintf("%d lines were read\n", csa->count); -done: if (ret) glp_erase_graph(G, G->v_size, G->a_size); - if (csa->fp != NULL) glp_close(csa->fp); - if (flag != NULL) xfree(flag); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_write_ccdata - write graph in DIMACS clique/coloring format -* -* SYNOPSIS -* -* int glp_write_ccdata(glp_graph *G, int v_wgt, const char *fname); -* -* DESCRIPTION -* -* The routine glp_write_ccdata writes the specified graph in DIMACS -* clique/coloring format to a text file. -* -* RETURNS -* -* If the operation was successful, the routine returns zero. Otherwise -* it prints an error message and returns non-zero. */ - -int glp_write_ccdata(glp_graph *G, int v_wgt, const char *fname) -{ glp_file *fp; - glp_vertex *v; - glp_arc *e; - int i, count = 0, ret; - double w; - if (v_wgt >= 0 && v_wgt > G->v_size - (int)sizeof(double)) - xerror("glp_write_ccdata: v_wgt = %d; invalid offset\n", - v_wgt); - xprintf("Writing graph to `%s'\n", fname); - fp = glp_open(fname, "w"); - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xfprintf(fp, "c %s\n", - G->name == NULL ? "unknown" : G->name), count++; - xfprintf(fp, "p edge %d %d\n", G->nv, G->na), count++; - if (v_wgt >= 0) - { for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - memcpy(&w, (char *)v->data + v_wgt, sizeof(double)); - if (w != 1.0) - xfprintf(fp, "n %d %.*g\n", i, DBL_DIG, w), count++; - } - } - for (i = 1; i <= G->nv; i++) - { v = G->v[i]; - for (e = v->out; e != NULL; e = e->t_next) - xfprintf(fp, "e %d %d\n", e->tail->i, e->head->i), count++; - } - xfprintf(fp, "c eof\n"), count++; -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xprintf("%d lines were written\n", count); - ret = 0; -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_read_prob - read problem data in GLPK format -* -* SYNOPSIS -* -* int glp_read_prob(glp_prob *P, int flags, const char *fname); -* -* The routine glp_read_prob reads problem data in GLPK LP/MIP format -* from a text file. -* -* RETURNS -* -* If the operation was successful, the routine returns zero. Otherwise -* it prints an error message and returns non-zero. */ - -int glp_read_prob(glp_prob *P, int flags, const char *fname) -{ struct csa _csa, *csa = &_csa; - int mip, m, n, nnz, ne, i, j, k, type, kind, ret, *ln = NULL, - *ia = NULL, *ja = NULL; - double lb, ub, temp, *ar = NULL; - char *rf = NULL, *cf = NULL; - if (P == NULL || P->magic != GLP_PROB_MAGIC) - xerror("glp_read_prob: P = %p; invalid problem object\n", - P); - if (flags != 0) - xerror("glp_read_prob: flags = %d; invalid parameter\n", - flags); - if (fname == NULL) - xerror("glp_read_prob: fname = %d; invalid parameter\n", - fname); - glp_erase_prob(P); - if (setjmp(csa->jump)) - { ret = 1; - goto done; - } - csa->fname = fname; - csa->fp = NULL; - csa->count = 0; - csa->c = '\n'; - csa->field[0] = '\0'; - csa->empty = csa->nonint = 0; - xprintf("Reading problem data from `%s'...\n", fname); - csa->fp = glp_open(fname, "r"); - if (csa->fp == NULL) - { xprintf("Unable to open `%s' - %s\n", fname, get_err_msg()); - longjmp(csa->jump, 1); - } - /* read problem line */ - read_designator(csa); - if (strcmp(csa->field, "p") != 0) - error(csa, "problem line missing or invalid"); - read_field(csa); - if (strcmp(csa->field, "lp") == 0) - mip = 0; - else if (strcmp(csa->field, "mip") == 0) - mip = 1; - else - error(csa, "wrong problem designator; `lp' or `mip' expected\n" - ); - read_field(csa); - if (strcmp(csa->field, "min") == 0) - glp_set_obj_dir(P, GLP_MIN); - else if (strcmp(csa->field, "max") == 0) - glp_set_obj_dir(P, GLP_MAX); - else - error(csa, "objective sense missing or invalid"); - read_field(csa); - if (!(str2int(csa->field, &m) == 0 && m >= 0)) - error(csa, "number of rows missing or invalid"); - read_field(csa); - if (!(str2int(csa->field, &n) == 0 && n >= 0)) - error(csa, "number of columns missing or invalid"); - read_field(csa); - if (!(str2int(csa->field, &nnz) == 0 && nnz >= 0)) - error(csa, "number of constraint coefficients missing or inval" - "id"); - if (m > 0) - { glp_add_rows(P, m); - for (i = 1; i <= m; i++) - glp_set_row_bnds(P, i, GLP_FX, 0.0, 0.0); - } - if (n > 0) - { glp_add_cols(P, n); - for (j = 1; j <= n; j++) - { if (!mip) - glp_set_col_bnds(P, j, GLP_LO, 0.0, 0.0); - else - glp_set_col_kind(P, j, GLP_BV); - } - } - end_of_line(csa); - /* allocate working arrays */ - rf = xcalloc(1+m, sizeof(char)); - memset(rf, 0, 1+m); - cf = xcalloc(1+n, sizeof(char)); - memset(cf, 0, 1+n); - ln = xcalloc(1+nnz, sizeof(int)); - ia = xcalloc(1+nnz, sizeof(int)); - ja = xcalloc(1+nnz, sizeof(int)); - ar = xcalloc(1+nnz, sizeof(double)); - /* read descriptor lines */ - ne = 0; - for (;;) - { read_designator(csa); - if (strcmp(csa->field, "i") == 0) - { /* row descriptor */ - read_field(csa); - if (str2int(csa->field, &i) != 0) - error(csa, "row number missing or invalid"); - if (!(1 <= i && i <= m)) - error(csa, "row number out of range"); - read_field(csa); - if (strcmp(csa->field, "f") == 0) - type = GLP_FR; - else if (strcmp(csa->field, "l") == 0) - type = GLP_LO; - else if (strcmp(csa->field, "u") == 0) - type = GLP_UP; - else if (strcmp(csa->field, "d") == 0) - type = GLP_DB; - else if (strcmp(csa->field, "s") == 0) - type = GLP_FX; - else - error(csa, "row type missing or invalid"); - if (type == GLP_LO || type == GLP_DB || type == GLP_FX) - { read_field(csa); - if (str2num(csa->field, &lb) != 0) - error(csa, "row lower bound/fixed value missing or in" - "valid"); - } - else - lb = 0.0; - if (type == GLP_UP || type == GLP_DB) - { read_field(csa); - if (str2num(csa->field, &ub) != 0) - error(csa, "row upper bound missing or invalid"); - } - else - ub = 0.0; - if (rf[i] & 0x01) - error(csa, "duplicate row descriptor"); - glp_set_row_bnds(P, i, type, lb, ub), rf[i] |= 0x01; - } - else if (strcmp(csa->field, "j") == 0) - { /* column descriptor */ - read_field(csa); - if (str2int(csa->field, &j) != 0) - error(csa, "column number missing or invalid"); - if (!(1 <= j && j <= n)) - error(csa, "column number out of range"); - if (!mip) - kind = GLP_CV; - else - { read_field(csa); - if (strcmp(csa->field, "c") == 0) - kind = GLP_CV; - else if (strcmp(csa->field, "i") == 0) - kind = GLP_IV; - else if (strcmp(csa->field, "b") == 0) - { kind = GLP_IV; - type = GLP_DB, lb = 0.0, ub = 1.0; - goto skip; - } - else - error(csa, "column kind missing or invalid"); - } - read_field(csa); - if (strcmp(csa->field, "f") == 0) - type = GLP_FR; - else if (strcmp(csa->field, "l") == 0) - type = GLP_LO; - else if (strcmp(csa->field, "u") == 0) - type = GLP_UP; - else if (strcmp(csa->field, "d") == 0) - type = GLP_DB; - else if (strcmp(csa->field, "s") == 0) - type = GLP_FX; - else - error(csa, "column type missing or invalid"); - if (type == GLP_LO || type == GLP_DB || type == GLP_FX) - { read_field(csa); - if (str2num(csa->field, &lb) != 0) - error(csa, "column lower bound/fixed value missing or" - " invalid"); - } - else - lb = 0.0; - if (type == GLP_UP || type == GLP_DB) - { read_field(csa); - if (str2num(csa->field, &ub) != 0) - error(csa, "column upper bound missing or invalid"); - } - else - ub = 0.0; -skip: if (cf[j] & 0x01) - error(csa, "duplicate column descriptor"); - glp_set_col_kind(P, j, kind); - glp_set_col_bnds(P, j, type, lb, ub), cf[j] |= 0x01; - } - else if (strcmp(csa->field, "a") == 0) - { /* coefficient descriptor */ - read_field(csa); - if (str2int(csa->field, &i) != 0) - error(csa, "row number missing or invalid"); - if (!(0 <= i && i <= m)) - error(csa, "row number out of range"); - read_field(csa); - if (str2int(csa->field, &j) != 0) - error(csa, "column number missing or invalid"); - if (!((i == 0 ? 0 : 1) <= j && j <= n)) - error(csa, "column number out of range"); - read_field(csa); - if (i == 0) - { if (str2num(csa->field, &temp) != 0) - error(csa, "objective %s missing or invalid", - j == 0 ? "constant term" : "coefficient"); - if (cf[j] & 0x10) - error(csa, "duplicate objective %s", - j == 0 ? "constant term" : "coefficient"); - glp_set_obj_coef(P, j, temp), cf[j] |= 0x10; - } - else - { if (str2num(csa->field, &temp) != 0) - error(csa, "constraint coefficient missing or invalid" - ); - if (ne == nnz) - error(csa, "too many constraint coefficient descripto" - "rs"); - ln[++ne] = csa->count; - ia[ne] = i, ja[ne] = j, ar[ne] = temp; - } - } - else if (strcmp(csa->field, "n") == 0) - { /* symbolic name descriptor */ - read_field(csa); - if (strcmp(csa->field, "p") == 0) - { /* problem name */ - read_field(csa); - if (P->name != NULL) - error(csa, "duplicate problem name"); - glp_set_prob_name(P, csa->field); - } - else if (strcmp(csa->field, "z") == 0) - { /* objective name */ - read_field(csa); - if (P->obj != NULL) - error(csa, "duplicate objective name"); - glp_set_obj_name(P, csa->field); - } - else if (strcmp(csa->field, "i") == 0) - { /* row name */ - read_field(csa); - if (str2int(csa->field, &i) != 0) - error(csa, "row number missing or invalid"); - if (!(1 <= i && i <= m)) - error(csa, "row number out of range"); - read_field(csa); - if (P->row[i]->name != NULL) - error(csa, "duplicate row name"); - glp_set_row_name(P, i, csa->field); - } - else if (strcmp(csa->field, "j") == 0) - { /* column name */ - read_field(csa); - if (str2int(csa->field, &j) != 0) - error(csa, "column number missing or invalid"); - if (!(1 <= j && j <= n)) - error(csa, "column number out of range"); - read_field(csa); - if (P->col[j]->name != NULL) - error(csa, "duplicate column name"); - glp_set_col_name(P, j, csa->field); - } - else - error(csa, "object designator missing or invalid"); - } - else if (strcmp(csa->field, "e") == 0) - break; - else - error(csa, "line designator missing or invalid"); - end_of_line(csa); - } - if (ne < nnz) - error(csa, "too few constraint coefficient descriptors"); - xassert(ne == nnz); - k = glp_check_dup(m, n, ne, ia, ja); - xassert(0 <= k && k <= nnz); - if (k > 0) - { csa->count = ln[k]; - error(csa, "duplicate constraint coefficient"); - } - glp_load_matrix(P, ne, ia, ja, ar); - /* print some statistics */ - if (P->name != NULL) - xprintf("Problem: %s\n", P->name); - if (P->obj != NULL) - xprintf("Objective: %s\n", P->obj); - xprintf("%d row%s, %d column%s, %d non-zero%s\n", - m, m == 1 ? "" : "s", n, n == 1 ? "" : "s", nnz, nnz == 1 ? - "" : "s"); - if (glp_get_num_int(P) > 0) - { int ni = glp_get_num_int(P); - int nb = glp_get_num_bin(P); - if (ni == 1) - { if (nb == 0) - xprintf("One variable is integer\n"); - else - xprintf("One variable is binary\n"); - } - else - { xprintf("%d integer variables, ", ni); - if (nb == 0) - xprintf("none"); - else if (nb == 1) - xprintf("one"); - else if (nb == ni) - xprintf("all"); - else - xprintf("%d", nb); - xprintf(" of which %s binary\n", nb == 1 ? "is" : "are"); - } - } - xprintf("%d lines were read\n", csa->count); - /* problem data has been successfully read */ - glp_sort_matrix(P); - ret = 0; -done: if (csa->fp != NULL) glp_close(csa->fp); - if (rf != NULL) xfree(rf); - if (cf != NULL) xfree(cf); - if (ln != NULL) xfree(ln); - if (ia != NULL) xfree(ia); - if (ja != NULL) xfree(ja); - if (ar != NULL) xfree(ar); - if (ret) glp_erase_prob(P); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_write_prob - write problem data in GLPK format -* -* SYNOPSIS -* -* int glp_write_prob(glp_prob *P, int flags, const char *fname); -* -* The routine glp_write_prob writes problem data in GLPK LP/MIP format -* to a text file. -* -* RETURNS -* -* If the operation was successful, the routine returns zero. Otherwise -* it prints an error message and returns non-zero. */ - -int glp_write_prob(glp_prob *P, int flags, const char *fname) -{ glp_file *fp; - GLPROW *row; - GLPCOL *col; - GLPAIJ *aij; - int mip, i, j, count, ret; - if (P == NULL || P->magic != GLP_PROB_MAGIC) - xerror("glp_write_prob: P = %p; invalid problem object\n", - P); - if (flags != 0) - xerror("glp_write_prob: flags = %d; invalid parameter\n", - flags); - if (fname == NULL) - xerror("glp_write_prob: fname = %d; invalid parameter\n", - fname); - xprintf("Writing problem data to `%s'...\n", fname); - fp = glp_open(fname, "w"), count = 0; - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - /* write problem line */ - mip = (glp_get_num_int(P) > 0); - xfprintf(fp, "p %s %s %d %d %d\n", !mip ? "lp" : "mip", - P->dir == GLP_MIN ? "min" : P->dir == GLP_MAX ? "max" : "???", - P->m, P->n, P->nnz), count++; - if (P->name != NULL) - xfprintf(fp, "n p %s\n", P->name), count++; - if (P->obj != NULL) - xfprintf(fp, "n z %s\n", P->obj), count++; - /* write row descriptors */ - for (i = 1; i <= P->m; i++) - { row = P->row[i]; - if (row->type == GLP_FX && row->lb == 0.0) - goto skip1; - xfprintf(fp, "i %d ", i), count++; - if (row->type == GLP_FR) - xfprintf(fp, "f\n"); - else if (row->type == GLP_LO) - xfprintf(fp, "l %.*g\n", DBL_DIG, row->lb); - else if (row->type == GLP_UP) - xfprintf(fp, "u %.*g\n", DBL_DIG, row->ub); - else if (row->type == GLP_DB) - xfprintf(fp, "d %.*g %.*g\n", DBL_DIG, row->lb, DBL_DIG, - row->ub); - else if (row->type == GLP_FX) - xfprintf(fp, "s %.*g\n", DBL_DIG, row->lb); - else - xassert(row != row); -skip1: if (row->name != NULL) - xfprintf(fp, "n i %d %s\n", i, row->name), count++; - } - /* write column descriptors */ - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - if (!mip && col->type == GLP_LO && col->lb == 0.0) - goto skip2; - if (mip && col->kind == GLP_IV && col->type == GLP_DB && - col->lb == 0.0 && col->ub == 1.0) - goto skip2; - xfprintf(fp, "j %d ", j), count++; - if (mip) - { if (col->kind == GLP_CV) - xfprintf(fp, "c "); - else if (col->kind == GLP_IV) - xfprintf(fp, "i "); - else - xassert(col != col); - } - if (col->type == GLP_FR) - xfprintf(fp, "f\n"); - else if (col->type == GLP_LO) - xfprintf(fp, "l %.*g\n", DBL_DIG, col->lb); - else if (col->type == GLP_UP) - xfprintf(fp, "u %.*g\n", DBL_DIG, col->ub); - else if (col->type == GLP_DB) - xfprintf(fp, "d %.*g %.*g\n", DBL_DIG, col->lb, DBL_DIG, - col->ub); - else if (col->type == GLP_FX) - xfprintf(fp, "s %.*g\n", DBL_DIG, col->lb); - else - xassert(col != col); -skip2: if (col->name != NULL) - xfprintf(fp, "n j %d %s\n", j, col->name), count++; - } - /* write objective coefficient descriptors */ - if (P->c0 != 0.0) - xfprintf(fp, "a 0 0 %.*g\n", DBL_DIG, P->c0), count++; - for (j = 1; j <= P->n; j++) - { col = P->col[j]; - if (col->coef != 0.0) - xfprintf(fp, "a 0 %d %.*g\n", j, DBL_DIG, col->coef), - count++; - } - /* write constraint coefficient descriptors */ - for (i = 1; i <= P->m; i++) - { row = P->row[i]; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - xfprintf(fp, "a %d %d %.*g\n", i, aij->col->j, DBL_DIG, - aij->val), count++; - } - /* write end line */ - xfprintf(fp, "e o f\n"), count++; -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xprintf("%d lines were written\n", count); - ret = 0; -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/**********************************************************************/ - -int glp_read_cnfsat(glp_prob *P, const char *fname) -{ /* read CNF-SAT problem data in DIMACS format */ - struct csa _csa, *csa = &_csa; - int m, n, i, j, len, neg, rhs, ret = 0, *ind = NULL; - double *val = NULL; - char *map = NULL; - if (P == NULL || P->magic != GLP_PROB_MAGIC) - xerror("glp_read_cnfsat: P = %p; invalid problem object\n", - P); - if (fname == NULL) - xerror("glp_read_cnfsat: fname = %p; invalid parameter\n", - fname); - glp_erase_prob(P); - if (setjmp(csa->jump)) - { ret = 1; - goto done; - } - csa->fname = fname; - csa->fp = NULL; - csa->count = 0; - csa->c = '\n'; - csa->field[0] = '\0'; - csa->empty = csa->nonint = 0; - xprintf("Reading CNF-SAT problem data from `%s'...\n", fname); - csa->fp = glp_open(fname, "r"); - if (csa->fp == NULL) - { xprintf("Unable to open `%s' - %s\n", fname, get_err_msg()); - longjmp(csa->jump, 1); - } - /* read problem line */ - read_designator(csa); - if (strcmp(csa->field, "p") != 0) - error(csa, "problem line missing or invalid"); - read_field(csa); - if (strcmp(csa->field, "cnf") != 0) - error(csa, "wrong problem designator; `cnf' expected\n"); - read_field(csa); - if (!(str2int(csa->field, &n) == 0 && n >= 0)) - error(csa, "number of variables missing or invalid\n"); - read_field(csa); - if (!(str2int(csa->field, &m) == 0 && m >= 0)) - error(csa, "number of clauses missing or invalid\n"); - xprintf("Instance has %d variable%s and %d clause%s\n", - n, n == 1 ? "" : "s", m, m == 1 ? "" : "s"); - end_of_line(csa); - if (m > 0) - glp_add_rows(P, m); - if (n > 0) - { glp_add_cols(P, n); - for (j = 1; j <= n; j++) - glp_set_col_kind(P, j, GLP_BV); - } - /* allocate working arrays */ - ind = xcalloc(1+n, sizeof(int)); - val = xcalloc(1+n, sizeof(double)); - map = xcalloc(1+n, sizeof(char)); - for (j = 1; j <= n; j++) map[j] = 0; - /* read clauses */ - for (i = 1; i <= m; i++) - { /* read i-th clause */ - len = 0, rhs = 1; - for (;;) - { /* skip white-space characters */ - while (csa->c == ' ' || csa->c == '\n') - read_char(csa); - /* read term */ - read_field(csa); - if (str2int(csa->field, &j) != 0) - error(csa, "variable number missing or invalid\n"); - if (j > 0) - neg = 0; - else if (j < 0) - neg = 1, j = -j, rhs--; - else - break; - if (!(1 <= j && j <= n)) - error(csa, "variable number out of range\n"); - if (map[j]) - error(csa, "duplicate variable number\n"); - len++, ind[len] = j, val[len] = (neg ? -1.0 : +1.0); - map[j] = 1; - } - glp_set_row_bnds(P, i, GLP_LO, (double)rhs, 0.0); - glp_set_mat_row(P, i, len, ind, val); - while (len > 0) map[ind[len--]] = 0; - } - xprintf("%d lines were read\n", csa->count); - /* problem data has been successfully read */ - glp_sort_matrix(P); -done: if (csa->fp != NULL) glp_close(csa->fp); - if (ind != NULL) xfree(ind); - if (val != NULL) xfree(val); - if (map != NULL) xfree(map); - if (ret) glp_erase_prob(P); - return ret; -} - -/**********************************************************************/ - -int glp_check_cnfsat(glp_prob *P) -{ /* check for CNF-SAT problem instance */ - int m = P->m; - int n = P->n; - GLPROW *row; - GLPCOL *col; - GLPAIJ *aij; - int i, j, neg; - if (P == NULL || P->magic != GLP_PROB_MAGIC) - xerror("glp_check_cnfsat: P = %p; invalid problem object\n", - P); - /* check columns */ - for (j = 1; j <= n; j++) - { col = P->col[j]; - /* the variable should be binary */ - if (!(col->kind == GLP_IV && col->type == GLP_DB && - col->lb == 0.0 && col->ub == 1.0)) - return 1; - } - /* objective function should be zero */ - if (P->c0 != 0.0) - return 2; - for (j = 1; j <= n; j++) - { col = P->col[j]; - if (col->coef != 0.0) - return 3; - } - /* check rows */ - for (i = 1; i <= m; i++) - { row = P->row[i]; - /* the row should be of ">=" type */ - if (row->type != GLP_LO) - return 4; - /* check constraint coefficients */ - neg = 0; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { /* the constraint coefficient should be +1 or -1 */ - if (aij->val == +1.0) - ; - else if (aij->val == -1.0) - neg++; - else - return 5; - } - /* the right-hand side should be (1 - neg), where neg is the - number of negative constraint coefficients in the row */ - if (row->lb != (double)(1 - neg)) - return 6; - } - /* congratulations; this is CNF-SAT */ - return 0; -} - -/**********************************************************************/ - -int glp_write_cnfsat(glp_prob *P, const char *fname) -{ /* write CNF-SAT problem data in DIMACS format */ - glp_file *fp = NULL; - GLPAIJ *aij; - int i, j, len, count = 0, ret; - char s[50]; - if (P == NULL || P->magic != GLP_PROB_MAGIC) - xerror("glp_write_cnfsat: P = %p; invalid problem object\n", - P); - if (glp_check_cnfsat(P) != 0) - { xprintf("glp_write_cnfsat: problem object does not encode CNF-" - "SAT instance\n"); - ret = 1; - goto done; - } - xprintf("Writing CNF-SAT problem data to `%s'...\n", fname); - fp = glp_open(fname, "w"); - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xfprintf(fp, "c %s\n", - P->name == NULL ? "unknown" : P->name), count++; - xfprintf(fp, "p cnf %d %d\n", P->n, P->m), count++; - for (i = 1; i <= P->m; i++) - { len = 0; - for (aij = P->row[i]->ptr; aij != NULL; aij = aij->r_next) - { j = aij->col->j; - if (aij->val < 0.0) j = -j; - sprintf(s, "%d", j); - if (len > 0 && len + 1 + strlen(s) > 72) - xfprintf(fp, "\n"), count++, len = 0; - xfprintf(fp, "%s%s", len == 0 ? "" : " ", s); - if (len > 0) len++; - len += strlen(s); - } - if (len > 0 && len + 1 + 1 > 72) - xfprintf(fp, "\n"), count++, len = 0; - xfprintf(fp, "%s0\n", len == 0 ? "" : " "), count++; - } - xfprintf(fp, "c eof\n"), count++; -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - xprintf("%d lines were written\n", count); - ret = 0; -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpgmp.c b/resources/3rdparty/glpk-4.53/src/glpgmp.c deleted file mode 100644 index 95c5159bd..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpgmp.c +++ /dev/null @@ -1,1116 +0,0 @@ -/* glpgmp.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#define _GLPSTD_STDIO -#if 1 /* 11/VI-2013 */ -#include "bignum.h" -#endif -#include "dmp.h" -#include "glpgmp.h" -#include "env.h" -#define xfault xerror - -#ifdef HAVE_GMP /* use GNU MP bignum library */ - -int gmp_pool_count(void) { return 0; } - -void gmp_free_mem(void) { return; } - -#else /* use GLPK bignum module */ - -static DMP *gmp_pool = NULL; -static int gmp_size = 0; -static unsigned short *gmp_work = NULL; - -void *gmp_get_atom(int size) -{ if (gmp_pool == NULL) - gmp_pool = dmp_create_pool(); - return dmp_get_atom(gmp_pool, size); -} - -void gmp_free_atom(void *ptr, int size) -{ xassert(gmp_pool != NULL); - dmp_free_atom(gmp_pool, ptr, size); - return; -} - -int gmp_pool_count(void) -{ if (gmp_pool == NULL) - return 0; - else -#if 0 /* 10/VI-2013 */ - return dmp_in_use(gmp_pool).lo; -#else - return dmp_in_use(gmp_pool); -#endif -} - -unsigned short *gmp_get_work(int size) -{ xassert(size > 0); - if (gmp_size < size) - { if (gmp_size == 0) - { xassert(gmp_work == NULL); - gmp_size = 100; - } - else - { xassert(gmp_work != NULL); - xfree(gmp_work); - } - while (gmp_size < size) gmp_size += gmp_size; - gmp_work = xcalloc(gmp_size, sizeof(unsigned short)); - } - return gmp_work; -} - -void gmp_free_mem(void) -{ if (gmp_pool != NULL) dmp_delete_pool(gmp_pool); - if (gmp_work != NULL) xfree(gmp_work); - gmp_pool = NULL; - gmp_size = 0; - gmp_work = NULL; - return; -} - -/*====================================================================*/ - -mpz_t _mpz_init(void) -{ /* initialize x, and set its value to 0 */ - mpz_t x; - x = gmp_get_atom(sizeof(struct mpz)); - x->val = 0; - x->ptr = NULL; - return x; -} - -void mpz_clear(mpz_t x) -{ /* free the space occupied by x */ - mpz_set_si(x, 0); - xassert(x->ptr == NULL); - /* free the number descriptor */ - gmp_free_atom(x, sizeof(struct mpz)); - return; -} - -void mpz_set(mpz_t z, mpz_t x) -{ /* set the value of z from x */ - struct mpz_seg *e, *ee, *es; - if (z != x) - { mpz_set_si(z, 0); - z->val = x->val; - xassert(z->ptr == NULL); - for (e = x->ptr, es = NULL; e != NULL; e = e->next) - { ee = gmp_get_atom(sizeof(struct mpz_seg)); - memcpy(ee->d, e->d, 12); - ee->next = NULL; - if (z->ptr == NULL) - z->ptr = ee; - else - es->next = ee; - es = ee; - } - } - return; -} - -void mpz_set_si(mpz_t x, int val) -{ /* set the value of x to val */ - struct mpz_seg *e; - /* free existing segments, if any */ - while (x->ptr != NULL) - { e = x->ptr; - x->ptr = e->next; - gmp_free_atom(e, sizeof(struct mpz_seg)); - } - /* assign new value */ - if (val == 0x80000000) - { /* long format is needed */ - x->val = -1; - x->ptr = e = gmp_get_atom(sizeof(struct mpz_seg)); - memset(e->d, 0, 12); - e->d[1] = 0x8000; - e->next = NULL; - } - else - { /* short format is enough */ - x->val = val; - } - return; -} - -double mpz_get_d(mpz_t x) -{ /* convert x to a double, truncating if necessary */ - struct mpz_seg *e; - int j; - double val, deg; - if (x->ptr == NULL) - val = (double)x->val; - else - { xassert(x->val != 0); - val = 0.0; - deg = 1.0; - for (e = x->ptr; e != NULL; e = e->next) - { for (j = 0; j <= 5; j++) - { val += deg * (double)((int)e->d[j]); - deg *= 65536.0; - } - } - if (x->val < 0) val = - val; - } - return val; -} - -double mpz_get_d_2exp(int *exp, mpz_t x) -{ /* convert x to a double, truncating if necessary (i.e. rounding - towards zero), and returning the exponent separately; - the return value is in the range 0.5 <= |d| < 1 and the - exponent is stored to *exp; d*2^exp is the (truncated) x value; - if x is zero, the return is 0.0 and 0 is stored to *exp; - this is similar to the standard C frexp function */ - struct mpz_seg *e; - int j, n, n1; - double val; - if (x->ptr == NULL) - val = (double)x->val, n = 0; - else - { xassert(x->val != 0); - val = 0.0, n = 0; - for (e = x->ptr; e != NULL; e = e->next) - { for (j = 0; j <= 5; j++) - { val += (double)((int)e->d[j]); - val /= 65536.0, n += 16; - } - } - if (x->val < 0) val = - val; - } - val = frexp(val, &n1); - *exp = n + n1; - return val; -} - -void mpz_swap(mpz_t x, mpz_t y) -{ /* swap the values x and y efficiently */ - int val; - void *ptr; - val = x->val, ptr = x->ptr; - x->val = y->val, x->ptr = y->ptr; - y->val = val, y->ptr = ptr; - return; -} - -static void normalize(mpz_t x) -{ /* normalize integer x that includes removing non-significant - (leading) zeros and converting to short format, if possible */ - struct mpz_seg *es, *e; - /* if the integer is in short format, it remains unchanged */ - if (x->ptr == NULL) - { xassert(x->val != 0x80000000); - goto done; - } - xassert(x->val == +1 || x->val == -1); - /* find the last (most significant) non-zero segment */ - es = NULL; - for (e = x->ptr; e != NULL; e = e->next) - { if (e->d[0] || e->d[1] || e->d[2] || - e->d[3] || e->d[4] || e->d[5]) es = e; - } - /* if all segments contain zeros, the integer is zero */ - if (es == NULL) - { mpz_set_si(x, 0); - goto done; - } - /* remove non-significant (leading) zero segments */ - while (es->next != NULL) - { e = es->next; - es->next = e->next; - gmp_free_atom(e, sizeof(struct mpz_seg)); - } - /* convert the integer to short format, if possible */ - e = x->ptr; - if (e->next == NULL && e->d[1] <= 0x7FFF && - !e->d[2] && !e->d[3] && !e->d[4] && !e->d[5]) - { int val; - val = (int)e->d[0] + ((int)e->d[1] << 16); - if (x->val < 0) val = - val; - mpz_set_si(x, val); - } -done: return; -} - -void mpz_add(mpz_t z, mpz_t x, mpz_t y) -{ /* set z to x + y */ - static struct mpz_seg zero = { { 0, 0, 0, 0, 0, 0 }, NULL }; - struct mpz_seg dumx, dumy, *ex, *ey, *ez, *es, *ee; - int k, sx, sy, sz; - unsigned int t; - /* if [x] = 0 then [z] = [y] */ - if (x->val == 0) - { xassert(x->ptr == NULL); - mpz_set(z, y); - goto done; - } - /* if [y] = 0 then [z] = [x] */ - if (y->val == 0) - { xassert(y->ptr == NULL); - mpz_set(z, x); - goto done; - } - /* special case when both [x] and [y] are in short format */ - if (x->ptr == NULL && y->ptr == NULL) - { int xval = x->val, yval = y->val, zval = x->val + y->val; - xassert(xval != 0x80000000 && yval != 0x80000000); - if (!(xval > 0 && yval > 0 && zval <= 0 || - xval < 0 && yval < 0 && zval >= 0)) - { mpz_set_si(z, zval); - goto done; - } - } - /* convert [x] to long format, if necessary */ - if (x->ptr == NULL) - { xassert(x->val != 0x80000000); - if (x->val >= 0) - { sx = +1; - t = (unsigned int)(+ x->val); - } - else - { sx = -1; - t = (unsigned int)(- x->val); - } - ex = &dumx; - ex->d[0] = (unsigned short)t; - ex->d[1] = (unsigned short)(t >> 16); - ex->d[2] = ex->d[3] = ex->d[4] = ex->d[5] = 0; - ex->next = NULL; - } - else - { sx = x->val; - xassert(sx == +1 || sx == -1); - ex = x->ptr; - } - /* convert [y] to long format, if necessary */ - if (y->ptr == NULL) - { xassert(y->val != 0x80000000); - if (y->val >= 0) - { sy = +1; - t = (unsigned int)(+ y->val); - } - else - { sy = -1; - t = (unsigned int)(- y->val); - } - ey = &dumy; - ey->d[0] = (unsigned short)t; - ey->d[1] = (unsigned short)(t >> 16); - ey->d[2] = ey->d[3] = ey->d[4] = ey->d[5] = 0; - ey->next = NULL; - } - else - { sy = y->val; - xassert(sy == +1 || sy == -1); - ey = y->ptr; - } - /* main fragment */ - sz = sx; - ez = es = NULL; - if (sx > 0 && sy > 0 || sx < 0 && sy < 0) - { /* [x] and [y] have identical signs -- addition */ - t = 0; - for (; ex || ey; ex = ex->next, ey = ey->next) - { if (ex == NULL) ex = &zero; - if (ey == NULL) ey = &zero; - ee = gmp_get_atom(sizeof(struct mpz_seg)); - for (k = 0; k <= 5; k++) - { t += (unsigned int)ex->d[k]; - t += (unsigned int)ey->d[k]; - ee->d[k] = (unsigned short)t; - t >>= 16; - } - ee->next = NULL; - if (ez == NULL) - ez = ee; - else - es->next = ee; - es = ee; - } - if (t) - { /* overflow -- one extra digit is needed */ - ee = gmp_get_atom(sizeof(struct mpz_seg)); - ee->d[0] = 1; - ee->d[1] = ee->d[2] = ee->d[3] = ee->d[4] = ee->d[5] = 0; - ee->next = NULL; - xassert(es != NULL); - es->next = ee; - } - } - else - { /* [x] and [y] have different signs -- subtraction */ - t = 1; - for (; ex || ey; ex = ex->next, ey = ey->next) - { if (ex == NULL) ex = &zero; - if (ey == NULL) ey = &zero; - ee = gmp_get_atom(sizeof(struct mpz_seg)); - for (k = 0; k <= 5; k++) - { t += (unsigned int)ex->d[k]; - t += (0xFFFF - (unsigned int)ey->d[k]); - ee->d[k] = (unsigned short)t; - t >>= 16; - } - ee->next = NULL; - if (ez == NULL) - ez = ee; - else - es->next = ee; - es = ee; - } - if (!t) - { /* |[x]| < |[y]| -- result in complement coding */ - sz = - sz; - t = 1; - for (ee = ez; ee != NULL; ee = ee->next) - for (k = 0; k <= 5; k++) - { t += (0xFFFF - (unsigned int)ee->d[k]); - ee->d[k] = (unsigned short)t; - t >>= 16; - } - } - } - /* contruct and normalize result */ - mpz_set_si(z, 0); - z->val = sz; - z->ptr = ez; - normalize(z); -done: return; -} - -void mpz_sub(mpz_t z, mpz_t x, mpz_t y) -{ /* set z to x - y */ - if (x == y) - mpz_set_si(z, 0); - else - { y->val = - y->val; - mpz_add(z, x, y); - if (y != z) y->val = - y->val; - } - return; -} - -void mpz_mul(mpz_t z, mpz_t x, mpz_t y) -{ /* set z to x * y */ - struct mpz_seg dumx, dumy, *ex, *ey, *es, *e; - int sx, sy, k, nx, ny, n; - unsigned int t; - unsigned short *work, *wx, *wy; - /* if [x] = 0 then [z] = 0 */ - if (x->val == 0) - { xassert(x->ptr == NULL); - mpz_set_si(z, 0); - goto done; - } - /* if [y] = 0 then [z] = 0 */ - if (y->val == 0) - { xassert(y->ptr == NULL); - mpz_set_si(z, 0); - goto done; - } - /* special case when both [x] and [y] are in short format */ - if (x->ptr == NULL && y->ptr == NULL) - { int xval = x->val, yval = y->val, sz = +1; - xassert(xval != 0x80000000 && yval != 0x80000000); - if (xval < 0) xval = - xval, sz = - sz; - if (yval < 0) yval = - yval, sz = - sz; - if (xval <= 0x7FFFFFFF / yval) - { mpz_set_si(z, sz * (xval * yval)); - goto done; - } - } - /* convert [x] to long format, if necessary */ - if (x->ptr == NULL) - { xassert(x->val != 0x80000000); - if (x->val >= 0) - { sx = +1; - t = (unsigned int)(+ x->val); - } - else - { sx = -1; - t = (unsigned int)(- x->val); - } - ex = &dumx; - ex->d[0] = (unsigned short)t; - ex->d[1] = (unsigned short)(t >> 16); - ex->d[2] = ex->d[3] = ex->d[4] = ex->d[5] = 0; - ex->next = NULL; - } - else - { sx = x->val; - xassert(sx == +1 || sx == -1); - ex = x->ptr; - } - /* convert [y] to long format, if necessary */ - if (y->ptr == NULL) - { xassert(y->val != 0x80000000); - if (y->val >= 0) - { sy = +1; - t = (unsigned int)(+ y->val); - } - else - { sy = -1; - t = (unsigned int)(- y->val); - } - ey = &dumy; - ey->d[0] = (unsigned short)t; - ey->d[1] = (unsigned short)(t >> 16); - ey->d[2] = ey->d[3] = ey->d[4] = ey->d[5] = 0; - ey->next = NULL; - } - else - { sy = y->val; - xassert(sy == +1 || sy == -1); - ey = y->ptr; - } - /* determine the number of digits of [x] */ - nx = n = 0; - for (e = ex; e != NULL; e = e->next) - for (k = 0; k <= 5; k++) - { n++; - if (e->d[k]) nx = n; - } - xassert(nx > 0); - /* determine the number of digits of [y] */ - ny = n = 0; - for (e = ey; e != NULL; e = e->next) - for (k = 0; k <= 5; k++) - { n++; - if (e->d[k]) ny = n; - } - xassert(ny > 0); - /* we need working array containing at least nx+ny+ny places */ - work = gmp_get_work(nx+ny+ny); - /* load digits of [x] */ - wx = &work[0]; - for (n = 0; n < nx; n++) wx[ny+n] = 0; - for (n = 0, e = ex; e != NULL; e = e->next) - for (k = 0; k <= 5; k++, n++) - if (e->d[k]) wx[ny+n] = e->d[k]; - /* load digits of [y] */ - wy = &work[nx+ny]; - for (n = 0; n < ny; n++) wy[n] = 0; - for (n = 0, e = ey; e != NULL; e = e->next) - for (k = 0; k <= 5; k++, n++) - if (e->d[k]) wy[n] = e->d[k]; - /* compute [x] * [y] */ - bigmul(nx, ny, wx, wy); - /* construct and normalize result */ - mpz_set_si(z, 0); - z->val = sx * sy; - es = NULL; - k = 6; - for (n = 0; n < nx+ny; n++) - { if (k > 5) - { e = gmp_get_atom(sizeof(struct mpz_seg)); - e->d[0] = e->d[1] = e->d[2] = 0; - e->d[3] = e->d[4] = e->d[5] = 0; - e->next = NULL; - if (z->ptr == NULL) - z->ptr = e; - else - es->next = e; - es = e; - k = 0; - } - es->d[k++] = wx[n]; - } - normalize(z); -done: return; -} - -void mpz_neg(mpz_t z, mpz_t x) -{ /* set z to 0 - x */ - mpz_set(z, x); - z->val = - z->val; - return; -} - -void mpz_abs(mpz_t z, mpz_t x) -{ /* set z to the absolute value of x */ - mpz_set(z, x); - if (z->val < 0) z->val = - z->val; - return; -} - -void mpz_div(mpz_t q, mpz_t r, mpz_t x, mpz_t y) -{ /* divide x by y, forming quotient q and/or remainder r - if q = NULL then quotient is not stored; if r = NULL then - remainder is not stored - the sign of quotient is determined as in algebra while the - sign of remainder is the same as the sign of dividend: - +26 : +7 = +3, remainder is +5 - -26 : +7 = -3, remainder is -5 - +26 : -7 = -3, remainder is +5 - -26 : -7 = +3, remainder is -5 */ - struct mpz_seg dumx, dumy, *ex, *ey, *es, *e; - int sx, sy, k, nx, ny, n; - unsigned int t; - unsigned short *work, *wx, *wy; - /* divide by zero is not allowed */ - if (y->val == 0) - { xassert(y->ptr == NULL); - xfault("mpz_div: divide by zero not allowed\n"); - } - /* if [x] = 0 then [q] = [r] = 0 */ - if (x->val == 0) - { xassert(x->ptr == NULL); - if (q != NULL) mpz_set_si(q, 0); - if (r != NULL) mpz_set_si(r, 0); - goto done; - } - /* special case when both [x] and [y] are in short format */ - if (x->ptr == NULL && y->ptr == NULL) - { int xval = x->val, yval = y->val; - xassert(xval != 0x80000000 && yval != 0x80000000); - if (q != NULL) mpz_set_si(q, xval / yval); - if (r != NULL) mpz_set_si(r, xval % yval); - goto done; - } - /* convert [x] to long format, if necessary */ - if (x->ptr == NULL) - { xassert(x->val != 0x80000000); - if (x->val >= 0) - { sx = +1; - t = (unsigned int)(+ x->val); - } - else - { sx = -1; - t = (unsigned int)(- x->val); - } - ex = &dumx; - ex->d[0] = (unsigned short)t; - ex->d[1] = (unsigned short)(t >> 16); - ex->d[2] = ex->d[3] = ex->d[4] = ex->d[5] = 0; - ex->next = NULL; - } - else - { sx = x->val; - xassert(sx == +1 || sx == -1); - ex = x->ptr; - } - /* convert [y] to long format, if necessary */ - if (y->ptr == NULL) - { xassert(y->val != 0x80000000); - if (y->val >= 0) - { sy = +1; - t = (unsigned int)(+ y->val); - } - else - { sy = -1; - t = (unsigned int)(- y->val); - } - ey = &dumy; - ey->d[0] = (unsigned short)t; - ey->d[1] = (unsigned short)(t >> 16); - ey->d[2] = ey->d[3] = ey->d[4] = ey->d[5] = 0; - ey->next = NULL; - } - else - { sy = y->val; - xassert(sy == +1 || sy == -1); - ey = y->ptr; - } - /* determine the number of digits of [x] */ - nx = n = 0; - for (e = ex; e != NULL; e = e->next) - for (k = 0; k <= 5; k++) - { n++; - if (e->d[k]) nx = n; - } - xassert(nx > 0); - /* determine the number of digits of [y] */ - ny = n = 0; - for (e = ey; e != NULL; e = e->next) - for (k = 0; k <= 5; k++) - { n++; - if (e->d[k]) ny = n; - } - xassert(ny > 0); - /* if nx < ny then [q] = 0 and [r] = [x] */ - if (nx < ny) - { if (r != NULL) mpz_set(r, x); - if (q != NULL) mpz_set_si(q, 0); - goto done; - } - /* we need working array containing at least nx+ny+1 places */ - work = gmp_get_work(nx+ny+1); - /* load digits of [x] */ - wx = &work[0]; - for (n = 0; n < nx; n++) wx[n] = 0; - for (n = 0, e = ex; e != NULL; e = e->next) - for (k = 0; k <= 5; k++, n++) - if (e->d[k]) wx[n] = e->d[k]; - /* load digits of [y] */ - wy = &work[nx+1]; - for (n = 0; n < ny; n++) wy[n] = 0; - for (n = 0, e = ey; e != NULL; e = e->next) - for (k = 0; k <= 5; k++, n++) - if (e->d[k]) wy[n] = e->d[k]; - /* compute quotient and remainder */ - xassert(wy[ny-1] != 0); - bigdiv(nx-ny, ny, wx, wy); - /* construct and normalize quotient */ - if (q != NULL) - { mpz_set_si(q, 0); - q->val = sx * sy; - es = NULL; - k = 6; - for (n = ny; n <= nx; n++) - { if (k > 5) - { e = gmp_get_atom(sizeof(struct mpz_seg)); - e->d[0] = e->d[1] = e->d[2] = 0; - e->d[3] = e->d[4] = e->d[5] = 0; - e->next = NULL; - if (q->ptr == NULL) - q->ptr = e; - else - es->next = e; - es = e; - k = 0; - } - es->d[k++] = wx[n]; - } - normalize(q); - } - /* construct and normalize remainder */ - if (r != NULL) - { mpz_set_si(r, 0); - r->val = sx; - es = NULL; - k = 6; - for (n = 0; n < ny; n++) - { if (k > 5) - { e = gmp_get_atom(sizeof(struct mpz_seg)); - e->d[0] = e->d[1] = e->d[2] = 0; - e->d[3] = e->d[4] = e->d[5] = 0; - e->next = NULL; - if (r->ptr == NULL) - r->ptr = e; - else - es->next = e; - es = e; - k = 0; - } - es->d[k++] = wx[n]; - } - normalize(r); - } -done: return; -} - -void mpz_gcd(mpz_t z, mpz_t x, mpz_t y) -{ /* set z to the greatest common divisor of x and y */ - /* in case of arbitrary integers GCD(x, y) = GCD(|x|, |y|), and, - in particular, GCD(0, 0) = 0 */ - mpz_t u, v, r; - mpz_init(u); - mpz_init(v); - mpz_init(r); - mpz_abs(u, x); - mpz_abs(v, y); - while (mpz_sgn(v)) - { mpz_div(NULL, r, u, v); - mpz_set(u, v); - mpz_set(v, r); - } - mpz_set(z, u); - mpz_clear(u); - mpz_clear(v); - mpz_clear(r); - return; -} - -int mpz_cmp(mpz_t x, mpz_t y) -{ /* compare x and y; return a positive value if x > y, zero if - x = y, or a nefative value if x < y */ - static struct mpz_seg zero = { { 0, 0, 0, 0, 0, 0 }, NULL }; - struct mpz_seg dumx, dumy, *ex, *ey; - int cc, sx, sy, k; - unsigned int t; - if (x == y) - { cc = 0; - goto done; - } - /* special case when both [x] and [y] are in short format */ - if (x->ptr == NULL && y->ptr == NULL) - { int xval = x->val, yval = y->val; - xassert(xval != 0x80000000 && yval != 0x80000000); - cc = (xval > yval ? +1 : xval < yval ? -1 : 0); - goto done; - } - /* special case when [x] and [y] have different signs */ - if (x->val > 0 && y->val <= 0 || x->val == 0 && y->val < 0) - { cc = +1; - goto done; - } - if (x->val < 0 && y->val >= 0 || x->val == 0 && y->val > 0) - { cc = -1; - goto done; - } - /* convert [x] to long format, if necessary */ - if (x->ptr == NULL) - { xassert(x->val != 0x80000000); - if (x->val >= 0) - { sx = +1; - t = (unsigned int)(+ x->val); - } - else - { sx = -1; - t = (unsigned int)(- x->val); - } - ex = &dumx; - ex->d[0] = (unsigned short)t; - ex->d[1] = (unsigned short)(t >> 16); - ex->d[2] = ex->d[3] = ex->d[4] = ex->d[5] = 0; - ex->next = NULL; - } - else - { sx = x->val; - xassert(sx == +1 || sx == -1); - ex = x->ptr; - } - /* convert [y] to long format, if necessary */ - if (y->ptr == NULL) - { xassert(y->val != 0x80000000); - if (y->val >= 0) - { sy = +1; - t = (unsigned int)(+ y->val); - } - else - { sy = -1; - t = (unsigned int)(- y->val); - } - ey = &dumy; - ey->d[0] = (unsigned short)t; - ey->d[1] = (unsigned short)(t >> 16); - ey->d[2] = ey->d[3] = ey->d[4] = ey->d[5] = 0; - ey->next = NULL; - } - else - { sy = y->val; - xassert(sy == +1 || sy == -1); - ey = y->ptr; - } - /* main fragment */ - xassert(sx > 0 && sy > 0 || sx < 0 && sy < 0); - cc = 0; - for (; ex || ey; ex = ex->next, ey = ey->next) - { if (ex == NULL) ex = &zero; - if (ey == NULL) ey = &zero; - for (k = 0; k <= 5; k++) - { if (ex->d[k] > ey->d[k]) cc = +1; - if (ex->d[k] < ey->d[k]) cc = -1; - } - } - if (sx < 0) cc = - cc; -done: return cc; -} - -int mpz_sgn(mpz_t x) -{ /* return +1 if x > 0, 0 if x = 0, and -1 if x < 0 */ - int s; - s = (x->val > 0 ? +1 : x->val < 0 ? -1 : 0); - return s; -} - -int mpz_out_str(void *_fp, int base, mpz_t x) -{ /* output x on stream fp, as a string in given base; the base - may vary from 2 to 36; - return the number of bytes written, or if an error occurred, - return 0 */ - FILE *fp = _fp; - mpz_t b, y, r; - int n, j, nwr = 0; - unsigned char *d; - static char *set = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - if (!(2 <= base && base <= 36)) - xfault("mpz_out_str: base = %d; invalid base\n", base); - mpz_init(b); - mpz_set_si(b, base); - mpz_init(y); - mpz_init(r); - /* determine the number of digits */ - mpz_abs(y, x); - for (n = 0; mpz_sgn(y) != 0; n++) - mpz_div(y, NULL, y, b); - if (n == 0) n = 1; - /* compute the digits */ - d = xmalloc(n); - mpz_abs(y, x); - for (j = 0; j < n; j++) - { mpz_div(y, r, y, b); - xassert(0 <= r->val && r->val < base && r->ptr == NULL); - d[j] = (unsigned char)r->val; - } - /* output the integer to the stream */ - if (fp == NULL) fp = stdout; - if (mpz_sgn(x) < 0) - fputc('-', fp), nwr++; - for (j = n-1; j >= 0; j--) - fputc(set[d[j]], fp), nwr++; - if (ferror(fp)) nwr = 0; - mpz_clear(b); - mpz_clear(y); - mpz_clear(r); - xfree(d); - return nwr; -} - -/*====================================================================*/ - -mpq_t _mpq_init(void) -{ /* initialize x, and set its value to 0/1 */ - mpq_t x; - x = gmp_get_atom(sizeof(struct mpq)); - x->p.val = 0; - x->p.ptr = NULL; - x->q.val = 1; - x->q.ptr = NULL; - return x; -} - -void mpq_clear(mpq_t x) -{ /* free the space occupied by x */ - mpz_set_si(&x->p, 0); - xassert(x->p.ptr == NULL); - mpz_set_si(&x->q, 0); - xassert(x->q.ptr == NULL); - /* free the number descriptor */ - gmp_free_atom(x, sizeof(struct mpq)); - return; -} - -void mpq_canonicalize(mpq_t x) -{ /* remove any factors that are common to the numerator and - denominator of x, and make the denominator positive */ - mpz_t f; - xassert(x->q.val != 0); - if (x->q.val < 0) - { mpz_neg(&x->p, &x->p); - mpz_neg(&x->q, &x->q); - } - mpz_init(f); - mpz_gcd(f, &x->p, &x->q); - if (!(f->val == 1 && f->ptr == NULL)) - { mpz_div(&x->p, NULL, &x->p, f); - mpz_div(&x->q, NULL, &x->q, f); - } - mpz_clear(f); - return; -} - -void mpq_set(mpq_t z, mpq_t x) -{ /* set the value of z from x */ - if (z != x) - { mpz_set(&z->p, &x->p); - mpz_set(&z->q, &x->q); - } - return; -} - -void mpq_set_si(mpq_t x, int p, unsigned int q) -{ /* set the value of x to p/q */ - if (q == 0) - xfault("mpq_set_si: zero denominator not allowed\n"); - mpz_set_si(&x->p, p); - xassert(q <= 0x7FFFFFFF); - mpz_set_si(&x->q, q); - return; -} - -double mpq_get_d(mpq_t x) -{ /* convert x to a double, truncating if necessary */ - int np, nq; - double p, q; - p = mpz_get_d_2exp(&np, &x->p); - q = mpz_get_d_2exp(&nq, &x->q); - return ldexp(p / q, np - nq); -} - -void mpq_set_d(mpq_t x, double val) -{ /* set x to val; there is no rounding, the conversion is exact */ - int s, n, d, j; - double f; - mpz_t temp; - xassert(-DBL_MAX <= val && val <= +DBL_MAX); - mpq_set_si(x, 0, 1); - if (val > 0.0) - s = +1; - else if (val < 0.0) - s = -1; - else - goto done; - f = frexp(fabs(val), &n); - /* |val| = f * 2^n, where 0.5 <= f < 1.0 */ - mpz_init(temp); - while (f != 0.0) - { f *= 16.0, n -= 4; - d = (int)f; - xassert(0 <= d && d <= 15); - f -= (double)d; - /* x := 16 * x + d */ - mpz_set_si(temp, 16); - mpz_mul(&x->p, &x->p, temp); - mpz_set_si(temp, d); - mpz_add(&x->p, &x->p, temp); - } - mpz_clear(temp); - /* x := x * 2^n */ - if (n > 0) - { for (j = 1; j <= n; j++) - mpz_add(&x->p, &x->p, &x->p); - } - else if (n < 0) - { for (j = 1; j <= -n; j++) - mpz_add(&x->q, &x->q, &x->q); - mpq_canonicalize(x); - } - if (s < 0) mpq_neg(x, x); -done: return; -} - -void mpq_add(mpq_t z, mpq_t x, mpq_t y) -{ /* set z to x + y */ - mpz_t p, q; - mpz_init(p); - mpz_init(q); - mpz_mul(p, &x->p, &y->q); - mpz_mul(q, &x->q, &y->p); - mpz_add(p, p, q); - mpz_mul(q, &x->q, &y->q); - mpz_set(&z->p, p); - mpz_set(&z->q, q); - mpz_clear(p); - mpz_clear(q); - mpq_canonicalize(z); - return; -} - -void mpq_sub(mpq_t z, mpq_t x, mpq_t y) -{ /* set z to x - y */ - mpz_t p, q; - mpz_init(p); - mpz_init(q); - mpz_mul(p, &x->p, &y->q); - mpz_mul(q, &x->q, &y->p); - mpz_sub(p, p, q); - mpz_mul(q, &x->q, &y->q); - mpz_set(&z->p, p); - mpz_set(&z->q, q); - mpz_clear(p); - mpz_clear(q); - mpq_canonicalize(z); - return; -} - -void mpq_mul(mpq_t z, mpq_t x, mpq_t y) -{ /* set z to x * y */ - mpz_mul(&z->p, &x->p, &y->p); - mpz_mul(&z->q, &x->q, &y->q); - mpq_canonicalize(z); - return; -} - -void mpq_div(mpq_t z, mpq_t x, mpq_t y) -{ /* set z to x / y */ - mpz_t p, q; - if (mpq_sgn(y) == 0) - xfault("mpq_div: zero divisor not allowed\n"); - mpz_init(p); - mpz_init(q); - mpz_mul(p, &x->p, &y->q); - mpz_mul(q, &x->q, &y->p); - mpz_set(&z->p, p); - mpz_set(&z->q, q); - mpz_clear(p); - mpz_clear(q); - mpq_canonicalize(z); - return; -} - -void mpq_neg(mpq_t z, mpq_t x) -{ /* set z to 0 - x */ - mpq_set(z, x); - mpz_neg(&z->p, &z->p); - return; -} - -void mpq_abs(mpq_t z, mpq_t x) -{ /* set z to the absolute value of x */ - mpq_set(z, x); - mpz_abs(&z->p, &z->p); - xassert(mpz_sgn(&x->q) > 0); - return; -} - -int mpq_cmp(mpq_t x, mpq_t y) -{ /* compare x and y; return a positive value if x > y, zero if - x = y, or a nefative value if x < y */ - mpq_t temp; - int s; - mpq_init(temp); - mpq_sub(temp, x, y); - s = mpq_sgn(temp); - mpq_clear(temp); - return s; -} - -int mpq_sgn(mpq_t x) -{ /* return +1 if x > 0, 0 if x = 0, and -1 if x < 0 */ - int s; - s = mpz_sgn(&x->p); - xassert(mpz_sgn(&x->q) > 0); - return s; -} - -int mpq_out_str(void *_fp, int base, mpq_t x) -{ /* output x on stream fp, as a string in given base; the base - may vary from 2 to 36; output is in the form 'num/den' or if - the denominator is 1 then just 'num'; - if the parameter fp is a null pointer, stdout is assumed; - return the number of bytes written, or if an error occurred, - return 0 */ - FILE *fp = _fp; - int nwr; - if (!(2 <= base && base <= 36)) - xfault("mpq_out_str: base = %d; invalid base\n", base); - if (fp == NULL) fp = stdout; - nwr = mpz_out_str(fp, base, &x->p); - if (x->q.val == 1 && x->q.ptr == NULL) - ; - else - { fputc('/', fp), nwr++; - nwr += mpz_out_str(fp, base, &x->q); - } - if (ferror(fp)) nwr = 0; - return nwr; -} - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpgmp.h b/resources/3rdparty/glpk-4.53/src/glpgmp.h deleted file mode 100644 index e1615ae27..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpgmp.h +++ /dev/null @@ -1,190 +0,0 @@ -/* glpgmp.h (bignum arithmetic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPGMP_H -#define GLPGMP_H - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef HAVE_GMP /* use GNU MP bignum library */ - -#include - -#define gmp_pool_count _glp_gmp_pool_count -#define gmp_free_mem _glp_gmp_free_mem - -int gmp_pool_count(void); -void gmp_free_mem(void); - -#else /* use GLPK bignum module */ - -/*---------------------------------------------------------------------- -// INTEGER NUMBERS -// -// Depending on its magnitude an integer number of arbitrary precision -// is represented either in short format or in long format. -// -// Short format corresponds to the int type and allows representing -// integer numbers in the range [-(2^31-1), +(2^31-1)]. Note that for -// the most negative number of int type the short format is not used. -// -// In long format integer numbers are represented using the positional -// system with the base (radix) 2^16 = 65536: -// -// x = (-1)^s sum{j in 0..n-1} d[j] * 65536^j, -// -// where x is the integer to be represented, s is its sign (+1 or -1), -// d[j] are its digits (0 <= d[j] <= 65535). -// -// RATIONAL NUMBERS -// -// A rational number is represented as an irreducible fraction: -// -// p / q, -// -// where p (numerator) and q (denominator) are integer numbers (q > 0) -// having no common divisors. */ - -struct mpz -{ /* integer number */ - int val; - /* if ptr is a null pointer, the number is in short format, and - val is its value; otherwise, the number is in long format, and - val is its sign (+1 or -1) */ - struct mpz_seg *ptr; - /* pointer to the linked list of the number segments ordered in - ascending of powers of the base */ -}; - -struct mpz_seg -{ /* integer number segment */ - unsigned short d[6]; - /* six digits of the number ordered in ascending of powers of the - base */ - struct mpz_seg *next; - /* pointer to the next number segment */ -}; - -struct mpq -{ /* rational number (p / q) */ - struct mpz p; - /* numerator */ - struct mpz q; - /* denominator */ -}; - -typedef struct mpz *mpz_t; -typedef struct mpq *mpq_t; - -#define gmp_get_atom _glp_gmp_get_atom -#define gmp_free_atom _glp_gmp_free_atom -#define gmp_pool_count _glp_gmp_pool_count -#define gmp_get_work _glp_gmp_get_work -#define gmp_free_mem _glp_gmp_free_mem - -#define _mpz_init _glp_mpz_init -#define mpz_clear _glp_mpz_clear -#define mpz_set _glp_mpz_set -#define mpz_set_si _glp_mpz_set_si -#define mpz_get_d _glp_mpz_get_d -#define mpz_get_d_2exp _glp_mpz_get_d_2exp -#define mpz_swap _glp_mpz_swap -#define mpz_add _glp_mpz_add -#define mpz_sub _glp_mpz_sub -#define mpz_mul _glp_mpz_mul -#define mpz_neg _glp_mpz_neg -#define mpz_abs _glp_mpz_abs -#define mpz_div _glp_mpz_div -#define mpz_gcd _glp_mpz_gcd -#define mpz_cmp _glp_mpz_cmp -#define mpz_sgn _glp_mpz_sgn -#define mpz_out_str _glp_mpz_out_str - -#define _mpq_init _glp_mpq_init -#define mpq_clear _glp_mpq_clear -#define mpq_canonicalize _glp_mpq_canonicalize -#define mpq_set _glp_mpq_set -#define mpq_set_si _glp_mpq_set_si -#define mpq_get_d _glp_mpq_get_d -#define mpq_set_d _glp_mpq_set_d -#define mpq_add _glp_mpq_add -#define mpq_sub _glp_mpq_sub -#define mpq_mul _glp_mpq_mul -#define mpq_div _glp_mpq_div -#define mpq_neg _glp_mpq_neg -#define mpq_abs _glp_mpq_abs -#define mpq_cmp _glp_mpq_cmp -#define mpq_sgn _glp_mpq_sgn -#define mpq_out_str _glp_mpq_out_str - -void *gmp_get_atom(int size); -void gmp_free_atom(void *ptr, int size); -int gmp_pool_count(void); -unsigned short *gmp_get_work(int size); -void gmp_free_mem(void); - -mpz_t _mpz_init(void); -#define mpz_init(x) (void)((x) = _mpz_init()) -void mpz_clear(mpz_t x); -void mpz_set(mpz_t z, mpz_t x); -void mpz_set_si(mpz_t x, int val); -double mpz_get_d(mpz_t x); -double mpz_get_d_2exp(int *exp, mpz_t x); -void mpz_swap(mpz_t x, mpz_t y); -void mpz_add(mpz_t, mpz_t, mpz_t); -void mpz_sub(mpz_t, mpz_t, mpz_t); -void mpz_mul(mpz_t, mpz_t, mpz_t); -void mpz_neg(mpz_t z, mpz_t x); -void mpz_abs(mpz_t z, mpz_t x); -void mpz_div(mpz_t q, mpz_t r, mpz_t x, mpz_t y); -void mpz_gcd(mpz_t z, mpz_t x, mpz_t y); -int mpz_cmp(mpz_t x, mpz_t y); -int mpz_sgn(mpz_t x); -int mpz_out_str(void *fp, int base, mpz_t x); - -mpq_t _mpq_init(void); -#define mpq_init(x) (void)((x) = _mpq_init()) -void mpq_clear(mpq_t x); -void mpq_canonicalize(mpq_t x); -void mpq_set(mpq_t z, mpq_t x); -void mpq_set_si(mpq_t x, int p, unsigned int q); -double mpq_get_d(mpq_t x); -void mpq_set_d(mpq_t x, double val); -void mpq_add(mpq_t z, mpq_t x, mpq_t y); -void mpq_sub(mpq_t z, mpq_t x, mpq_t y); -void mpq_mul(mpq_t z, mpq_t x, mpq_t y); -void mpq_div(mpq_t z, mpq_t x, mpq_t y); -void mpq_neg(mpq_t z, mpq_t x); -void mpq_abs(mpq_t z, mpq_t x); -int mpq_cmp(mpq_t x, mpq_t y); -int mpq_sgn(mpq_t x); -int mpq_out_str(void *fp, int base, mpq_t x); - -#endif - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glphbm.c b/resources/3rdparty/glpk-4.53/src/glphbm.c deleted file mode 100644 index 07f4107d9..000000000 --- a/resources/3rdparty/glpk-4.53/src/glphbm.c +++ /dev/null @@ -1,529 +0,0 @@ -/* glphbm.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glphbm.h" -#include "misc.h" - -/*********************************************************************** -* NAME -* -* hbm_read_mat - read sparse matrix in Harwell-Boeing format -* -* SYNOPSIS -* -* #include "glphbm.h" -* HBM *hbm_read_mat(const char *fname); -* -* DESCRIPTION -* -* The routine hbm_read_mat reads a sparse matrix in the Harwell-Boeing -* format from a text file whose name is the character string fname. -* -* Detailed description of the Harwell-Boeing format recognised by this -* routine is given in the following report: -* -* I.S.Duff, R.G.Grimes, J.G.Lewis. User's Guide for the Harwell-Boeing -* Sparse Matrix Collection (Release I), TR/PA/92/86, October 1992. -* -* RETURNS -* -* If no error occured, the routine hbm_read_mat returns a pointer to -* a data structure containing the matrix. In case of error the routine -* prints an appropriate error message and returns NULL. */ - -struct dsa -{ /* working area used by routine hbm_read_mat */ - const char *fname; - /* name of input text file */ - FILE *fp; - /* stream assigned to input text file */ - int seqn; - /* card sequential number */ - char card[80+1]; - /* card image buffer */ - int fmt_p; - /* scale factor */ - int fmt_k; - /* iterator */ - int fmt_f; - /* format code */ - int fmt_w; - /* field width */ - int fmt_d; - /* number of decimal places after point */ -}; - -/*********************************************************************** -* read_card - read next data card -* -* This routine reads the next 80-column card from the input text file -* and stores its image into the character string card. If the card was -* read successfully, the routine returns zero, otherwise non-zero. */ - -#if 1 /* 11/III-2012 */ -static int read_card(struct dsa *dsa) -{ int c, len = 0; - char buf[255+1]; - dsa->seqn++; - for (;;) - { c = fgetc(dsa->fp); - if (c == EOF) - { if (ferror(dsa->fp)) - xprintf("%s:%d: read error\n", - dsa->fname, dsa->seqn); - else - xprintf("%s:%d: unexpected end-of-file\n", - dsa->fname, dsa->seqn); - return 1; - } - else if (c == '\r') - /* nop */; - else if (c == '\n') - break; - else if (iscntrl(c)) - { xprintf("%s:%d: invalid control character\n", - dsa->fname, dsa->seqn, c); - return 1; - } - else - { if (len == sizeof(buf)-1) - goto err; - buf[len++] = (char)c; - } - } - /* remove trailing spaces */ - while (len > 80 && buf[len-1] == ' ') - len--; - buf[len] = '\0'; - /* line should not be longer than 80 chars */ - if (len > 80) -err: { xerror("%s:%d: card image too long\n", - dsa->fname, dsa->seqn); - return 1; - } - /* padd by spaces to 80-column card image */ - strcpy(dsa->card, buf); - memset(&dsa->card[len], ' ', 80 - len); - dsa->card[80] = '\0'; - return 0; -} -#endif - -/*********************************************************************** -* scan_int - scan integer value from the current card -* -* This routine scans an integer value from the current card, where fld -* is the name of the field, pos is the position of the field, width is -* the width of the field, val points to a location to which the scanned -* value should be stored. If the value was scanned successfully, the -* routine returns zero, otherwise non-zero. */ - -static int scan_int(struct dsa *dsa, char *fld, int pos, int width, - int *val) -{ char str[80+1]; - xassert(1 <= width && width <= 80); - memcpy(str, dsa->card + pos, width), str[width] = '\0'; - if (str2int(strspx(str), val)) - { xprintf("%s:%d: field `%s' contains invalid value `%s'\n", - dsa->fname, dsa->seqn, fld, str); - return 1; - } - return 0; -} - -/*********************************************************************** -* parse_fmt - parse Fortran format specification -* -* This routine parses the Fortran format specification represented as -* character string which fmt points to and stores format elements into -* appropriate static locations. Should note that not all valid Fortran -* format specifications may be recognised. If the format specification -* was recognised, the routine returns zero, otherwise non-zero. */ - -static int parse_fmt(struct dsa *dsa, char *fmt) -{ int k, s, val; - char str[80+1]; - /* first character should be left parenthesis */ - if (fmt[0] != '(') -fail: { xprintf("hbm_read_mat: format `%s' not recognised\n", fmt); - return 1; - } - k = 1; - /* optional scale factor */ - dsa->fmt_p = 0; - if (isdigit((unsigned char)fmt[k])) - { s = 0; - while (isdigit((unsigned char)fmt[k])) - { if (s == 80) goto fail; - str[s++] = fmt[k++]; - } - str[s] = '\0'; - if (str2int(str, &val)) goto fail; - if (toupper((unsigned char)fmt[k]) != 'P') goto iter; - dsa->fmt_p = val, k++; - if (!(0 <= dsa->fmt_p && dsa->fmt_p <= 255)) goto fail; - /* optional comma may follow scale factor */ - if (fmt[k] == ',') k++; - } - /* optional iterator */ - dsa->fmt_k = 1; - if (isdigit((unsigned char)fmt[k])) - { s = 0; - while (isdigit((unsigned char)fmt[k])) - { if (s == 80) goto fail; - str[s++] = fmt[k++]; - } - str[s] = '\0'; - if (str2int(str, &val)) goto fail; -iter: dsa->fmt_k = val; - if (!(1 <= dsa->fmt_k && dsa->fmt_k <= 255)) goto fail; - } - /* format code */ - dsa->fmt_f = toupper((unsigned char)fmt[k++]); - if (!(dsa->fmt_f == 'D' || dsa->fmt_f == 'E' || - dsa->fmt_f == 'F' || dsa->fmt_f == 'G' || - dsa->fmt_f == 'I')) goto fail; - /* field width */ - if (!isdigit((unsigned char)fmt[k])) goto fail; - s = 0; - while (isdigit((unsigned char)fmt[k])) - { if (s == 80) goto fail; - str[s++] = fmt[k++]; - } - str[s] = '\0'; - if (str2int(str, &dsa->fmt_w)) goto fail; - if (!(1 <= dsa->fmt_w && dsa->fmt_w <= 255)) goto fail; - /* optional number of decimal places after point */ - dsa->fmt_d = 0; - if (fmt[k] == '.') - { k++; - if (!isdigit((unsigned char)fmt[k])) goto fail; - s = 0; - while (isdigit((unsigned char)fmt[k])) - { if (s == 80) goto fail; - str[s++] = fmt[k++]; - } - str[s] = '\0'; - if (str2int(str, &dsa->fmt_d)) goto fail; - if (!(0 <= dsa->fmt_d && dsa->fmt_d <= 255)) goto fail; - } - /* last character should be right parenthesis */ - if (!(fmt[k] == ')' && fmt[k+1] == '\0')) goto fail; - return 0; -} - -/*********************************************************************** -* read_int_array - read array of integer type -* -* This routine reads an integer array from the input text file, where -* name is array name, fmt is Fortran format specification that controls -* reading, n is number of array elements, val is array of integer type. -* If the array was read successful, the routine returns zero, otherwise -* non-zero. */ - -static int read_int_array(struct dsa *dsa, char *name, char *fmt, - int n, int val[]) -{ int k, pos; - char str[80+1]; - if (parse_fmt(dsa, fmt)) return 1; - if (!(dsa->fmt_f == 'I' && dsa->fmt_w <= 80 && - dsa->fmt_k * dsa->fmt_w <= 80)) - { xprintf( - "%s:%d: can't read array `%s' - invalid format `%s'\n", - dsa->fname, dsa->seqn, name, fmt); - return 1; - } - for (k = 1, pos = INT_MAX; k <= n; k++, pos++) - { if (pos >= dsa->fmt_k) - { if (read_card(dsa)) return 1; - pos = 0; - } - memcpy(str, dsa->card + dsa->fmt_w * pos, dsa->fmt_w); - str[dsa->fmt_w] = '\0'; - strspx(str); - if (str2int(str, &val[k])) - { xprintf( - "%s:%d: can't read array `%s' - invalid value `%s'\n", - dsa->fname, dsa->seqn, name, str); - return 1; - } - } - return 0; -} - -/*********************************************************************** -* read_real_array - read array of real type -* -* This routine reads a real array from the input text file, where name -* is array name, fmt is Fortran format specification that controls -* reading, n is number of array elements, val is array of real type. -* If the array was read successful, the routine returns zero, otherwise -* non-zero. */ - -static int read_real_array(struct dsa *dsa, char *name, char *fmt, - int n, double val[]) -{ int k, pos; - char str[80+1], *ptr; - if (parse_fmt(dsa, fmt)) return 1; - if (!(dsa->fmt_f != 'I' && dsa->fmt_w <= 80 && - dsa->fmt_k * dsa->fmt_w <= 80)) - { xprintf( - "%s:%d: can't read array `%s' - invalid format `%s'\n", - dsa->fname, dsa->seqn, name, fmt); - return 1; - } - for (k = 1, pos = INT_MAX; k <= n; k++, pos++) - { if (pos >= dsa->fmt_k) - { if (read_card(dsa)) return 1; - pos = 0; - } - memcpy(str, dsa->card + dsa->fmt_w * pos, dsa->fmt_w); - str[dsa->fmt_w] = '\0'; - strspx(str); - if (strchr(str, '.') == NULL && strcmp(str, "0")) - { xprintf("%s(%d): can't read array `%s' - value `%s' has no " - "decimal point\n", dsa->fname, dsa->seqn, name, str); - return 1; - } - /* sometimes lower case letters appear */ - for (ptr = str; *ptr; ptr++) - *ptr = (char)toupper((unsigned char)*ptr); - ptr = strchr(str, 'D'); - if (ptr != NULL) *ptr = 'E'; - /* value may appear with decimal exponent but without letters - E or D (for example, -123.456-012), so missing letter should - be inserted */ - ptr = strchr(str+1, '+'); - if (ptr == NULL) ptr = strchr(str+1, '-'); - if (ptr != NULL && *(ptr-1) != 'E') - { xassert(strlen(str) < 80); - memmove(ptr+1, ptr, strlen(ptr)+1); - *ptr = 'E'; - } - if (str2num(str, &val[k])) - { xprintf( - "%s:%d: can't read array `%s' - invalid value `%s'\n", - dsa->fname, dsa->seqn, name, str); - return 1; - } - } - return 0; -} - -HBM *hbm_read_mat(const char *fname) -{ struct dsa _dsa, *dsa = &_dsa; - HBM *hbm = NULL; - dsa->fname = fname; - xprintf("hbm_read_mat: reading matrix from `%s'...\n", - dsa->fname); - dsa->fp = fopen(dsa->fname, "r"); - if (dsa->fp == NULL) - { xprintf("hbm_read_mat: unable to open `%s' - %s\n", - dsa->fname, strerror(errno)); - goto fail; - } - dsa->seqn = 0; - hbm = xmalloc(sizeof(HBM)); - memset(hbm, 0, sizeof(HBM)); - /* read the first heading card */ - if (read_card(dsa)) goto fail; - memcpy(hbm->title, dsa->card, 72), hbm->title[72] = '\0'; - strtrim(hbm->title); - xprintf("%s\n", hbm->title); - memcpy(hbm->key, dsa->card+72, 8), hbm->key[8] = '\0'; - strspx(hbm->key); - xprintf("key = %s\n", hbm->key); - /* read the second heading card */ - if (read_card(dsa)) goto fail; - if (scan_int(dsa, "totcrd", 0, 14, &hbm->totcrd)) goto fail; - if (scan_int(dsa, "ptrcrd", 14, 14, &hbm->ptrcrd)) goto fail; - if (scan_int(dsa, "indcrd", 28, 14, &hbm->indcrd)) goto fail; - if (scan_int(dsa, "valcrd", 42, 14, &hbm->valcrd)) goto fail; - if (scan_int(dsa, "rhscrd", 56, 14, &hbm->rhscrd)) goto fail; - xprintf("totcrd = %d; ptrcrd = %d; indcrd = %d; valcrd = %d; rhsc" - "rd = %d\n", hbm->totcrd, hbm->ptrcrd, hbm->indcrd, - hbm->valcrd, hbm->rhscrd); - /* read the third heading card */ - if (read_card(dsa)) goto fail; - memcpy(hbm->mxtype, dsa->card, 3), hbm->mxtype[3] = '\0'; - if (strchr("RCP", hbm->mxtype[0]) == NULL || - strchr("SUHZR", hbm->mxtype[1]) == NULL || - strchr("AE", hbm->mxtype[2]) == NULL) - { xprintf("%s:%d: matrix type `%s' not recognised\n", - dsa->fname, dsa->seqn, hbm->mxtype); - goto fail; - } - if (scan_int(dsa, "nrow", 14, 14, &hbm->nrow)) goto fail; - if (scan_int(dsa, "ncol", 28, 14, &hbm->ncol)) goto fail; - if (scan_int(dsa, "nnzero", 42, 14, &hbm->nnzero)) goto fail; - if (scan_int(dsa, "neltvl", 56, 14, &hbm->neltvl)) goto fail; - xprintf("mxtype = %s; nrow = %d; ncol = %d; nnzero = %d; neltvl =" - " %d\n", hbm->mxtype, hbm->nrow, hbm->ncol, hbm->nnzero, - hbm->neltvl); - /* read the fourth heading card */ - if (read_card(dsa)) goto fail; - memcpy(hbm->ptrfmt, dsa->card, 16), hbm->ptrfmt[16] = '\0'; - strspx(hbm->ptrfmt); - memcpy(hbm->indfmt, dsa->card+16, 16), hbm->indfmt[16] = '\0'; - strspx(hbm->indfmt); - memcpy(hbm->valfmt, dsa->card+32, 20), hbm->valfmt[20] = '\0'; - strspx(hbm->valfmt); - memcpy(hbm->rhsfmt, dsa->card+52, 20), hbm->rhsfmt[20] = '\0'; - strspx(hbm->rhsfmt); - xprintf("ptrfmt = %s; indfmt = %s; valfmt = %s; rhsfmt = %s\n", - hbm->ptrfmt, hbm->indfmt, hbm->valfmt, hbm->rhsfmt); - /* read the fifth heading card (optional) */ - if (hbm->rhscrd <= 0) - { strcpy(hbm->rhstyp, "???"); - hbm->nrhs = 0; - hbm->nrhsix = 0; - } - else - { if (read_card(dsa)) goto fail; - memcpy(hbm->rhstyp, dsa->card, 3), hbm->rhstyp[3] = '\0'; - if (scan_int(dsa, "nrhs", 14, 14, &hbm->nrhs)) goto fail; - if (scan_int(dsa, "nrhsix", 28, 14, &hbm->nrhsix)) goto fail; - xprintf("rhstyp = `%s'; nrhs = %d; nrhsix = %d\n", - hbm->rhstyp, hbm->nrhs, hbm->nrhsix); - } - /* read matrix structure */ - hbm->colptr = xcalloc(1+hbm->ncol+1, sizeof(int)); - if (read_int_array(dsa, "colptr", hbm->ptrfmt, hbm->ncol+1, - hbm->colptr)) goto fail; - hbm->rowind = xcalloc(1+hbm->nnzero, sizeof(int)); - if (read_int_array(dsa, "rowind", hbm->indfmt, hbm->nnzero, - hbm->rowind)) goto fail; - /* read matrix values */ - if (hbm->valcrd <= 0) goto done; - if (hbm->mxtype[2] == 'A') - { /* assembled matrix */ - hbm->values = xcalloc(1+hbm->nnzero, sizeof(double)); - if (read_real_array(dsa, "values", hbm->valfmt, hbm->nnzero, - hbm->values)) goto fail; - } - else - { /* elemental (unassembled) matrix */ - hbm->values = xcalloc(1+hbm->neltvl, sizeof(double)); - if (read_real_array(dsa, "values", hbm->valfmt, hbm->neltvl, - hbm->values)) goto fail; - } - /* read right-hand sides */ - if (hbm->nrhs <= 0) goto done; - if (hbm->rhstyp[0] == 'F') - { /* dense format */ - hbm->nrhsvl = hbm->nrow * hbm->nrhs; - hbm->rhsval = xcalloc(1+hbm->nrhsvl, sizeof(double)); - if (read_real_array(dsa, "rhsval", hbm->rhsfmt, hbm->nrhsvl, - hbm->rhsval)) goto fail; - } - else if (hbm->rhstyp[0] == 'M' && hbm->mxtype[2] == 'A') - { /* sparse format */ - /* read pointers */ - hbm->rhsptr = xcalloc(1+hbm->nrhs+1, sizeof(int)); - if (read_int_array(dsa, "rhsptr", hbm->ptrfmt, hbm->nrhs+1, - hbm->rhsptr)) goto fail; - /* read sparsity pattern */ - hbm->rhsind = xcalloc(1+hbm->nrhsix, sizeof(int)); - if (read_int_array(dsa, "rhsind", hbm->indfmt, hbm->nrhsix, - hbm->rhsind)) goto fail; - /* read values */ - hbm->rhsval = xcalloc(1+hbm->nrhsix, sizeof(double)); - if (read_real_array(dsa, "rhsval", hbm->rhsfmt, hbm->nrhsix, - hbm->rhsval)) goto fail; - } - else if (hbm->rhstyp[0] == 'M' && hbm->mxtype[2] == 'E') - { /* elemental format */ - hbm->rhsval = xcalloc(1+hbm->nrhsvl, sizeof(double)); - if (read_real_array(dsa, "rhsval", hbm->rhsfmt, hbm->nrhsvl, - hbm->rhsval)) goto fail; - } - else - { xprintf("%s:%d: right-hand side type `%c' not recognised\n", - dsa->fname, dsa->seqn, hbm->rhstyp[0]); - goto fail; - } - /* read starting guesses */ - if (hbm->rhstyp[1] == 'G') - { hbm->nguess = hbm->nrow * hbm->nrhs; - hbm->sguess = xcalloc(1+hbm->nguess, sizeof(double)); - if (read_real_array(dsa, "sguess", hbm->rhsfmt, hbm->nguess, - hbm->sguess)) goto fail; - } - /* read solution vectors */ - if (hbm->rhstyp[2] == 'X') - { hbm->nexact = hbm->nrow * hbm->nrhs; - hbm->xexact = xcalloc(1+hbm->nexact, sizeof(double)); - if (read_real_array(dsa, "xexact", hbm->rhsfmt, hbm->nexact, - hbm->xexact)) goto fail; - } -done: /* reading has been completed */ - xprintf("hbm_read_mat: %d cards were read\n", dsa->seqn); - fclose(dsa->fp); - return hbm; -fail: /* something wrong in Danish kingdom */ - if (hbm != NULL) - { if (hbm->colptr != NULL) xfree(hbm->colptr); - if (hbm->rowind != NULL) xfree(hbm->rowind); - if (hbm->rhsptr != NULL) xfree(hbm->rhsptr); - if (hbm->rhsind != NULL) xfree(hbm->rhsind); - if (hbm->values != NULL) xfree(hbm->values); - if (hbm->rhsval != NULL) xfree(hbm->rhsval); - if (hbm->sguess != NULL) xfree(hbm->sguess); - if (hbm->xexact != NULL) xfree(hbm->xexact); - xfree(hbm); - } - if (dsa->fp != NULL) fclose(dsa->fp); - return NULL; -} - -/*********************************************************************** -* NAME -* -* hbm_free_mat - free sparse matrix in Harwell-Boeing format -* -* SYNOPSIS -* -* #include "glphbm.h" -* void hbm_free_mat(HBM *hbm); -* -* DESCRIPTION -* -* The hbm_free_mat routine frees all the memory allocated to the data -* structure containing a sparse matrix in the Harwell-Boeing format. */ - -void hbm_free_mat(HBM *hbm) -{ if (hbm->colptr != NULL) xfree(hbm->colptr); - if (hbm->rowind != NULL) xfree(hbm->rowind); - if (hbm->rhsptr != NULL) xfree(hbm->rhsptr); - if (hbm->rhsind != NULL) xfree(hbm->rhsind); - if (hbm->values != NULL) xfree(hbm->values); - if (hbm->rhsval != NULL) xfree(hbm->rhsval); - if (hbm->sguess != NULL) xfree(hbm->sguess); - if (hbm->xexact != NULL) xfree(hbm->xexact); - xfree(hbm); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glphbm.h b/resources/3rdparty/glpk-4.53/src/glphbm.h deleted file mode 100644 index 688a78ec1..000000000 --- a/resources/3rdparty/glpk-4.53/src/glphbm.h +++ /dev/null @@ -1,127 +0,0 @@ -/* glphbm.h (Harwell-Boeing sparse matrix format) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPHBM_H -#define GLPHBM_H - -typedef struct HBM HBM; - -struct HBM -{ /* sparse matrix in Harwell-Boeing format; for details see the - report: I.S.Duff, R.G.Grimes, J.G.Lewis. User's Guide for the - Harwell-Boeing Sparse Matrix Collection (Release I), 1992 */ - char title[72+1]; - /* matrix title (informative) */ - char key[8+1]; - /* matrix key (informative) */ - char mxtype[3+1]; - /* matrix type: - R.. real matrix - C.. complex matrix - P.. pattern only (no numerical values supplied) - .S. symmetric (lower triangle + main diagonal) - .U. unsymmetric - .H. hermitian (lower triangle + main diagonal) - .Z. skew symmetric (lower triangle only) - .R. rectangular - ..A assembled - ..E elemental (unassembled) */ - char rhstyp[3+1]; - /* optional types: - F.. right-hand sides in dense format - M.. right-hand sides in same format as matrix - .G. starting vector(s) (guess) is supplied - ..X exact solution vector(s) is supplied */ - char ptrfmt[16+1]; - /* format for pointers */ - char indfmt[16+1]; - /* format for row (or variable) indices */ - char valfmt[20+1]; - /* format for numerical values of coefficient matrix */ - char rhsfmt[20+1]; - /* format for numerical values of right-hand sides */ - int totcrd; - /* total number of cards excluding header */ - int ptrcrd; - /* number of cards for ponters */ - int indcrd; - /* number of cards for row (or variable) indices */ - int valcrd; - /* number of cards for numerical values */ - int rhscrd; - /* number of lines for right-hand sides; - including starting guesses and solution vectors if present; - zero indicates no right-hand side data is present */ - int nrow; - /* number of rows (or variables) */ - int ncol; - /* number of columns (or elements) */ - int nnzero; - /* number of row (or variable) indices; - equal to number of entries for assembled matrix */ - int neltvl; - /* number of elemental matrix entries; - zero in case of assembled matrix */ - int nrhs; - /* number of right-hand sides */ - int nrhsix; - /* number of row indices; - ignored in case of unassembled matrix */ - int nrhsvl; - /* total number of entries in all right-hand sides */ - int nguess; - /* total number of entries in all starting guesses */ - int nexact; - /* total number of entries in all solution vectors */ - int *colptr; /* alias: eltptr */ - /* column pointers (in case of assembled matrix); - elemental matrix pointers (in case of unassembled matrix) */ - int *rowind; /* alias: varind */ - /* row indices (in case of assembled matrix); - variable indices (in case of unassembled matrix) */ - int *rhsptr; - /* right-hand side pointers */ - int *rhsind; - /* right-hand side indices */ - double *values; - /* matrix values */ - double *rhsval; - /* right-hand side values */ - double *sguess; - /* starting guess values */ - double *xexact; - /* solution vector values */ -}; - -#define hbm_read_mat _glp_hbm_read_mat -HBM *hbm_read_mat(const char *fname); -/* read sparse matrix in Harwell-Boeing format */ - -#define hbm_free_mat _glp_hbm_free_mat -void hbm_free_mat(HBM *hbm); -/* free sparse matrix in Harwell-Boeing format */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpini01.c b/resources/3rdparty/glpk-4.53/src/glpini01.c deleted file mode 100644 index 76c021477..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpini01.c +++ /dev/null @@ -1,155 +0,0 @@ -/* glpini01.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "prob.h" -#include "triang.h" - -/*********************************************************************** -* NAME -* -* glp_adv_basis - construct advanced initial LP basis -* -* SYNOPSIS -* -* void glp_adv_basis(glp_prob *P, int flags); -* -* DESCRIPTION -* -* The routine glp_adv_basis constructs an advanced initial LP basis -* for the specified problem object. -* -* The parameter flag is reserved for use in the future and should be -* specified as zero. -* -* NOTE -* -* The routine glp_adv_basis should be called after the constraint -* matrix has been scaled (if scaling is used). */ - -static int mat(void *info, int k, int ind[], double val[]) -{ glp_prob *P = info; - int m = P->m; - int n = P->n; - GLPROW **row = P->row; - GLPCOL **col = P->col; - GLPAIJ *aij; - int i, j, len; - if (k > 0) - { /* retrieve scaled row of constraint matrix */ - i = +k; - xassert(1 <= i && i <= m); - len = 0; - if (row[i]->type == GLP_FX) - { for (aij = row[i]->ptr; aij != NULL; aij = aij->r_next) - { j = aij->col->j; - if (col[j]->type != GLP_FX) - { len++; - ind[len] = j; - val[len] = aij->row->rii * aij->val * aij->col->sjj; - } - } - } - } - else - { /* retrieve scaled column of constraint matrix */ - j = -k; - xassert(1 <= j && j <= n); - len = 0; - if (col[j]->type != GLP_FX) - { for (aij = col[j]->ptr; aij != NULL; aij = aij->c_next) - { i = aij->row->i; - if (row[i]->type == GLP_FX) - { len++; - ind[len] = i; - val[len] = aij->row->rii * aij->val * aij->col->sjj; - } - } - } - } - return len; -} - -void glp_adv_basis(glp_prob *P, int flags) -{ int i, j, k, m, n, min_mn, size, *rn, *cn; - char *flag; - if (flags != 0) - xerror("glp_adv_basis: flags = %d; invalid flags\n", flags); - m = P->m; /* number of rows */ - n = P->n; /* number of columns */ - if (m == 0 || n == 0) - { /* trivial case */ - glp_std_basis(P); - goto done; - } - xprintf("Constructing initial basis...\n"); - /* allocate working arrays */ - min_mn = (m < n ? m : n); - rn = talloc(1+min_mn, int); - cn = talloc(1+min_mn, int); - flag = talloc(1+m, char); - /* make the basis empty */ - for (i = 1; i <= m; i++) - { flag[i] = 0; - glp_set_row_stat(P, i, GLP_NS); - } - for (j = 1; j <= n; j++) - glp_set_col_stat(P, j, GLP_NS); - /* find maximal triangular part of the constraint matrix; - to prevent including non-fixed rows and fixed columns in the - triangular part, such rows and columns are temporarily made - empty by the routine mat */ -#if 1 /* FIXME: tolerance */ - size = triang(m, n, mat, P, 0.001, rn, cn); -#endif - xassert(0 <= size && size <= min_mn); - /* include in the basis non-fixed structural variables, whose - columns constitute the triangular part */ - for (k = 1; k <= size; k++) - { i = rn[k]; - xassert(1 <= i && i <= m); - flag[i] = 1; - j = cn[k]; - xassert(1 <= j && j <= n); - glp_set_col_stat(P, j, GLP_BS); - } - /* include in the basis appropriate auxiliary variables, whose - unity columns preserve triangular form of the basis matrix */ - for (i = 1; i <= m; i++) - { if (flag[i] == 0) - { glp_set_row_stat(P, i, GLP_BS); - if (P->row[i]->type != GLP_FX) - size++; - } - } - /* size of triangular part = (number of rows) - (number of basic - fixed auxiliary variables) */ - xprintf("Size of triangular part is %d\n", size); - /* deallocate working arrays */ - tfree(rn); - tfree(cn); - tfree(flag); -done: return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpini02.c b/resources/3rdparty/glpk-4.53/src/glpini02.c deleted file mode 100644 index 6aad59feb..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpini02.c +++ /dev/null @@ -1,270 +0,0 @@ -/* glpini02.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "prob.h" - -struct var -{ /* structural variable */ - int j; - /* ordinal number */ - double q; - /* penalty value */ -}; - -static int fcmp(const void *ptr1, const void *ptr2) -{ /* this routine is passed to the qsort() function */ - struct var *col1 = (void *)ptr1, *col2 = (void *)ptr2; - if (col1->q < col2->q) return -1; - if (col1->q > col2->q) return +1; - return 0; -} - -static int get_column(glp_prob *lp, int j, int ind[], double val[]) -{ /* Bixby's algorithm assumes that the constraint matrix is scaled - such that the maximum absolute value in every non-zero row and - column is 1 */ - int k, len; - double big; - len = glp_get_mat_col(lp, j, ind, val); - big = 0.0; - for (k = 1; k <= len; k++) - if (big < fabs(val[k])) big = fabs(val[k]); - if (big == 0.0) big = 1.0; - for (k = 1; k <= len; k++) val[k] /= big; - return len; -} - -static void cpx_basis(glp_prob *lp) -{ /* main routine */ - struct var *C, *C2, *C3, *C4; - int m, n, i, j, jk, k, l, ll, t, n2, n3, n4, type, len, *I, *r, - *ind; - double alpha, gamma, cmax, temp, *v, *val; - xprintf("Constructing initial basis...\n"); - /* determine the number of rows and columns */ - m = glp_get_num_rows(lp); - n = glp_get_num_cols(lp); - /* allocate working arrays */ - C = xcalloc(1+n, sizeof(struct var)); - I = xcalloc(1+m, sizeof(int)); - r = xcalloc(1+m, sizeof(int)); - v = xcalloc(1+m, sizeof(double)); - ind = xcalloc(1+m, sizeof(int)); - val = xcalloc(1+m, sizeof(double)); - /* make all auxiliary variables non-basic */ - for (i = 1; i <= m; i++) - { if (glp_get_row_type(lp, i) != GLP_DB) - glp_set_row_stat(lp, i, GLP_NS); - else if (fabs(glp_get_row_lb(lp, i)) <= - fabs(glp_get_row_ub(lp, i))) - glp_set_row_stat(lp, i, GLP_NL); - else - glp_set_row_stat(lp, i, GLP_NU); - } - /* make all structural variables non-basic */ - for (j = 1; j <= n; j++) - { if (glp_get_col_type(lp, j) != GLP_DB) - glp_set_col_stat(lp, j, GLP_NS); - else if (fabs(glp_get_col_lb(lp, j)) <= - fabs(glp_get_col_ub(lp, j))) - glp_set_col_stat(lp, j, GLP_NL); - else - glp_set_col_stat(lp, j, GLP_NU); - } - /* C2 is a set of free structural variables */ - n2 = 0, C2 = C + 0; - for (j = 1; j <= n; j++) - { type = glp_get_col_type(lp, j); - if (type == GLP_FR) - { n2++; - C2[n2].j = j; - C2[n2].q = 0.0; - } - } - /* C3 is a set of structural variables having excatly one (lower - or upper) bound */ - n3 = 0, C3 = C2 + n2; - for (j = 1; j <= n; j++) - { type = glp_get_col_type(lp, j); - if (type == GLP_LO) - { n3++; - C3[n3].j = j; - C3[n3].q = + glp_get_col_lb(lp, j); - } - else if (type == GLP_UP) - { n3++; - C3[n3].j = j; - C3[n3].q = - glp_get_col_ub(lp, j); - } - } - /* C4 is a set of structural variables having both (lower and - upper) bounds */ - n4 = 0, C4 = C3 + n3; - for (j = 1; j <= n; j++) - { type = glp_get_col_type(lp, j); - if (type == GLP_DB) - { n4++; - C4[n4].j = j; - C4[n4].q = glp_get_col_lb(lp, j) - glp_get_col_ub(lp, j); - } - } - /* compute gamma = max{|c[j]|: 1 <= j <= n} */ - gamma = 0.0; - for (j = 1; j <= n; j++) - { temp = fabs(glp_get_obj_coef(lp, j)); - if (gamma < temp) gamma = temp; - } - /* compute cmax */ - cmax = (gamma == 0.0 ? 1.0 : 1000.0 * gamma); - /* compute final penalty for all structural variables within sets - C2, C3, and C4 */ - switch (glp_get_obj_dir(lp)) - { case GLP_MIN: temp = +1.0; break; - case GLP_MAX: temp = -1.0; break; - default: xassert(lp != lp); - } - for (k = 1; k <= n2+n3+n4; k++) - { j = C[k].j; - C[k].q += (temp * glp_get_obj_coef(lp, j)) / cmax; - } - /* sort structural variables within C2, C3, and C4 in ascending - order of penalty value */ - qsort(C2+1, n2, sizeof(struct var), fcmp); - for (k = 1; k < n2; k++) xassert(C2[k].q <= C2[k+1].q); - qsort(C3+1, n3, sizeof(struct var), fcmp); - for (k = 1; k < n3; k++) xassert(C3[k].q <= C3[k+1].q); - qsort(C4+1, n4, sizeof(struct var), fcmp); - for (k = 1; k < n4; k++) xassert(C4[k].q <= C4[k+1].q); - /*** STEP 1 ***/ - for (i = 1; i <= m; i++) - { type = glp_get_row_type(lp, i); - if (type != GLP_FX) - { /* row i is either free or inequality constraint */ - glp_set_row_stat(lp, i, GLP_BS); - I[i] = 1; - r[i] = 1; - } - else - { /* row i is equality constraint */ - I[i] = 0; - r[i] = 0; - } - v[i] = +DBL_MAX; - } - /*** STEP 2 ***/ - for (k = 1; k <= n2+n3+n4; k++) - { jk = C[k].j; - len = get_column(lp, jk, ind, val); - /* let alpha = max{|A[l,jk]|: r[l] = 0} and let l' be such - that alpha = |A[l',jk]| */ - alpha = 0.0, ll = 0; - for (t = 1; t <= len; t++) - { l = ind[t]; - if (r[l] == 0 && alpha < fabs(val[t])) - alpha = fabs(val[t]), ll = l; - } - if (alpha >= 0.99) - { /* B := B union {jk} */ - glp_set_col_stat(lp, jk, GLP_BS); - I[ll] = 1; - v[ll] = alpha; - /* r[l] := r[l] + 1 for all l such that |A[l,jk]| != 0 */ - for (t = 1; t <= len; t++) - { l = ind[t]; - if (val[t] != 0.0) r[l]++; - } - /* continue to the next k */ - continue; - } - /* if |A[l,jk]| > 0.01 * v[l] for some l, continue to the - next k */ - for (t = 1; t <= len; t++) - { l = ind[t]; - if (fabs(val[t]) > 0.01 * v[l]) break; - } - if (t <= len) continue; - /* otherwise, let alpha = max{|A[l,jk]|: I[l] = 0} and let l' - be such that alpha = |A[l',jk]| */ - alpha = 0.0, ll = 0; - for (t = 1; t <= len; t++) - { l = ind[t]; - if (I[l] == 0 && alpha < fabs(val[t])) - alpha = fabs(val[t]), ll = l; - } - /* if alpha = 0, continue to the next k */ - if (alpha == 0.0) continue; - /* B := B union {jk} */ - glp_set_col_stat(lp, jk, GLP_BS); - I[ll] = 1; - v[ll] = alpha; - /* r[l] := r[l] + 1 for all l such that |A[l,jk]| != 0 */ - for (t = 1; t <= len; t++) - { l = ind[t]; - if (val[t] != 0.0) r[l]++; - } - } - /*** STEP 3 ***/ - /* add an artificial variable (auxiliary variable for equality - constraint) to cover each remaining uncovered row */ - for (i = 1; i <= m; i++) - if (I[i] == 0) glp_set_row_stat(lp, i, GLP_BS); - /* free working arrays */ - xfree(C); - xfree(I); - xfree(r); - xfree(v); - xfree(ind); - xfree(val); - return; -} - -/*********************************************************************** -* NAME -* -* glp_cpx_basis - construct Bixby's initial LP basis -* -* SYNOPSIS -* -* void glp_cpx_basis(glp_prob *lp); -* -* DESCRIPTION -* -* The routine glp_cpx_basis constructs an advanced initial basis for -* the specified problem object. -* -* The routine is based on Bixby's algorithm described in the paper: -* -* Robert E. Bixby. Implementing the Simplex Method: The Initial Basis. -* ORSA Journal on Computing, Vol. 4, No. 3, 1992, pp. 267-84. */ - -void glp_cpx_basis(glp_prob *lp) -{ if (lp->m == 0 || lp->n == 0) - glp_std_basis(lp); - else - cpx_basis(lp); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpios.h b/resources/3rdparty/glpk-4.53/src/glpios.h deleted file mode 100644 index 07ee9810e..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpios.h +++ /dev/null @@ -1,620 +0,0 @@ -/* glpios.h (integer optimization suite) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPIOS_H -#define GLPIOS_H - -#include "prob.h" - -typedef struct IOSLOT IOSLOT; -typedef struct IOSNPD IOSNPD; -typedef struct IOSBND IOSBND; -typedef struct IOSTAT IOSTAT; -typedef struct IOSROW IOSROW; -typedef struct IOSAIJ IOSAIJ; -typedef struct IOSPOOL IOSPOOL; -typedef struct IOSCUT IOSCUT; - -struct glp_tree -{ /* branch-and-bound tree */ - int magic; - /* magic value used for debugging */ - DMP *pool; - /* memory pool to store all IOS components */ - int n; - /* number of columns (variables) */ - /*--------------------------------------------------------------*/ - /* problem components corresponding to the original MIP and its - LP relaxation (used to restore the original problem object on - exit from the solver) */ - int orig_m; - /* number of rows */ - unsigned char *orig_type; /* uchar orig_type[1+orig_m+n]; */ - /* types of all variables */ - double *orig_lb; /* double orig_lb[1+orig_m+n]; */ - /* lower bounds of all variables */ - double *orig_ub; /* double orig_ub[1+orig_m+n]; */ - /* upper bounds of all variables */ - unsigned char *orig_stat; /* uchar orig_stat[1+orig_m+n]; */ - /* statuses of all variables */ - double *orig_prim; /* double orig_prim[1+orig_m+n]; */ - /* primal values of all variables */ - double *orig_dual; /* double orig_dual[1+orig_m+n]; */ - /* dual values of all variables */ - double orig_obj; - /* optimal objective value for LP relaxation */ - /*--------------------------------------------------------------*/ - /* branch-and-bound tree */ - int nslots; - /* length of the array of slots (enlarged automatically) */ - int avail; - /* index of the first free slot; 0 means all slots are in use */ - IOSLOT *slot; /* IOSLOT slot[1+nslots]; */ - /* array of slots: - slot[0] is not used; - slot[p], 1 <= p <= nslots, either contains a pointer to some - node of the branch-and-bound tree, in which case p is used on - API level as the reference number of corresponding subproblem, - or is free; all free slots are linked into single linked list; - slot[1] always contains a pointer to the root node (it is free - only if the tree is empty) */ - IOSNPD *head; - /* pointer to the head of the active list */ - IOSNPD *tail; - /* pointer to the tail of the active list */ - /* the active list is a doubly linked list of active subproblems - which correspond to leaves of the tree; all subproblems in the - active list are ordered chronologically (each a new subproblem - is always added to the tail of the list) */ - int a_cnt; - /* current number of active nodes (including the current one) */ - int n_cnt; - /* current number of all (active and inactive) nodes */ - int t_cnt; - /* total number of nodes including those which have been already - removed from the tree; this count is increased by one whenever - a new node is created and never decreased */ - /*--------------------------------------------------------------*/ - /* problem components corresponding to the root subproblem */ - int root_m; - /* number of rows */ - unsigned char *root_type; /* uchar root_type[1+root_m+n]; */ - /* types of all variables */ - double *root_lb; /* double root_lb[1+root_m+n]; */ - /* lower bounds of all variables */ - double *root_ub; /* double root_ub[1+root_m+n]; */ - /* upper bounds of all variables */ - unsigned char *root_stat; /* uchar root_stat[1+root_m+n]; */ - /* statuses of all variables */ - /*--------------------------------------------------------------*/ - /* current subproblem and its LP relaxation */ - IOSNPD *curr; - /* pointer to the current subproblem (which can be only active); - NULL means the current subproblem does not exist */ - glp_prob *mip; - /* original problem object passed to the solver; if the current - subproblem exists, its LP segment corresponds to LP relaxation - of the current subproblem; if the current subproblem does not - exist, its LP segment corresponds to LP relaxation of the root - subproblem (note that the root subproblem may differ from the - original MIP, because it may be preprocessed and/or may have - additional rows) */ - unsigned char *non_int; /* uchar non_int[1+n]; */ - /* these column flags are set each time when LP relaxation of the - current subproblem has been solved; - non_int[0] is not used; - non_int[j], 1 <= j <= n, is j-th column flag; if this flag is - set, corresponding variable is required to be integer, but its - value in basic solution is fractional */ - /*--------------------------------------------------------------*/ - /* problem components corresponding to the parent (predecessor) - subproblem for the current subproblem; used to inspect changes - on freezing the current subproblem */ - int pred_m; - /* number of rows */ - int pred_max; - /* length of the following four arrays (enlarged automatically), - pred_max >= pred_m + n */ - unsigned char *pred_type; /* uchar pred_type[1+pred_m+n]; */ - /* types of all variables */ - double *pred_lb; /* double pred_lb[1+pred_m+n]; */ - /* lower bounds of all variables */ - double *pred_ub; /* double pred_ub[1+pred_m+n]; */ - /* upper bounds of all variables */ - unsigned char *pred_stat; /* uchar pred_stat[1+pred_m+n]; */ - /* statuses of all variables */ - /****************************************************************/ - /* built-in cut generators segment */ - IOSPOOL *local; - /* local cut pool */ - void *mir_gen; - /* pointer to working area used by the MIR cut generator */ - void *clq_gen; - /* pointer to working area used by the clique cut generator */ - /*--------------------------------------------------------------*/ - void *pcost; - /* pointer to working area used on pseudocost branching */ - int *iwrk; /* int iwrk[1+n]; */ - /* working array */ - double *dwrk; /* double dwrk[1+n]; */ - /* working array */ - /*--------------------------------------------------------------*/ - /* control parameters and statistics */ - const glp_iocp *parm; - /* copy of control parameters passed to the solver */ -#if 0 /* 10/VI-2013 */ - glp_long tm_beg; -#else - double tm_beg; -#endif - /* starting time of the search, in seconds; the total time of the - search is the difference between xtime() and tm_beg */ -#if 0 /* 10/VI-2013 */ - glp_long tm_lag; -#else - double tm_lag; -#endif - /* the most recent time, in seconds, at which the progress of the - the search was displayed */ - int sol_cnt; - /* number of integer feasible solutions found */ -#if 1 /* 11/VII-2013 */ - void *P; /* glp_prob *P; */ - /* problem passed to glp_intopt */ - void *npp; /* NPP *npp; */ - /* preprocessor workspace or NULL */ - const char *save_sol; - /* filename (template) to save every new solution */ - int save_cnt; - /* count to generate filename */ -#endif - /*--------------------------------------------------------------*/ - /* advanced solver interface */ - int reason; - /* flag indicating the reason why the callback routine is being - called (see glpk.h) */ - int stop; - /* flag indicating that the callback routine requires premature - termination of the search */ - int next_p; - /* reference number of active subproblem selected to continue - the search; 0 means no subproblem has been selected */ - int reopt; - /* flag indicating that the current LP relaxation needs to be - re-optimized */ - int reinv; - /* flag indicating that some (non-active) rows were removed from - the current LP relaxation, so if there no new rows appear, the - basis must be re-factorized */ - int br_var; - /* the number of variable chosen to branch on */ - int br_sel; - /* flag indicating which branch (subproblem) is suggested to be - selected to continue the search: - GLP_DN_BRNCH - select down-branch - GLP_UP_BRNCH - select up-branch - GLP_NO_BRNCH - use general selection technique */ - int child; - /* subproblem reference number corresponding to br_sel */ -}; - -struct IOSLOT -{ /* node subproblem slot */ - IOSNPD *node; - /* pointer to subproblem descriptor; NULL means free slot */ - int next; - /* index of another free slot (only if this slot is free) */ -}; - -struct IOSNPD -{ /* node subproblem descriptor */ - int p; - /* subproblem reference number (it is the index to corresponding - slot, i.e. slot[p] points to this descriptor) */ - IOSNPD *up; - /* pointer to the parent subproblem; NULL means this node is the - root of the tree, in which case p = 1 */ - int level; - /* node level (the root node has level 0) */ - int count; - /* if count = 0, this subproblem is active; if count > 0, this - subproblem is inactive, in which case count is the number of - its child subproblems */ - /* the following three linked lists are destroyed on reviving and - built anew on freezing the subproblem: */ - IOSBND *b_ptr; - /* linked list of rows and columns of the parent subproblem whose - types and bounds were changed */ - IOSTAT *s_ptr; - /* linked list of rows and columns of the parent subproblem whose - statuses were changed */ - IOSROW *r_ptr; - /* linked list of rows (cuts) added to the parent subproblem */ - int solved; - /* how many times LP relaxation of this subproblem was solved; - for inactive subproblem this count is always non-zero; - for active subproblem, which is not current, this count may be - non-zero, if the subproblem was temporarily suspended */ - double lp_obj; - /* optimal objective value to LP relaxation of this subproblem; - on creating a subproblem this value is inherited from its - parent; for the root subproblem, which has no parent, this - value is initially set to -DBL_MAX (minimization) or +DBL_MAX - (maximization); each time the subproblem is re-optimized, this - value is appropriately changed */ - double bound; - /* local lower (minimization) or upper (maximization) bound for - integer optimal solution to *this* subproblem; this bound is - local in the sense that only subproblems in the subtree rooted - at this node cannot have better integer feasible solutions; - on creating a subproblem its local bound is inherited from its - parent and then can be made stronger (never weaker); for the - root subproblem its local bound is initially set to -DBL_MAX - (minimization) or +DBL_MAX (maximization) and then improved as - the root LP relaxation has been solved */ - /* the following two quantities are defined only if LP relaxation - of this subproblem was solved at least once (solved > 0): */ - int ii_cnt; - /* number of integer variables whose value in optimal solution to - LP relaxation of this subproblem is fractional */ - double ii_sum; - /* sum of integer infeasibilities */ -#if 1 /* 30/XI-2009 */ - int changed; - /* how many times this subproblem was re-formulated (by adding - cutting plane constraints) */ -#endif - int br_var; - /* ordinal number of branching variable, 1 <= br_var <= n, used - to split this subproblem; 0 means that either this subproblem - is active or branching was made on a constraint */ - double br_val; - /* (fractional) value of branching variable in optimal solution - to final LP relaxation of this subproblem */ - void *data; /* char data[tree->cb_size]; */ - /* pointer to the application-specific data */ - IOSNPD *temp; - /* working pointer used by some routines */ - IOSNPD *prev; - /* pointer to previous subproblem in the active list */ - IOSNPD *next; - /* pointer to next subproblem in the active list */ -}; - -struct IOSBND -{ /* bounds change entry */ - int k; - /* ordinal number of corresponding row (1 <= k <= m) or column - (m+1 <= k <= m+n), where m and n are the number of rows and - columns, resp., in the parent subproblem */ - unsigned char type; - /* new type */ - double lb; - /* new lower bound */ - double ub; - /* new upper bound */ - IOSBND *next; - /* pointer to next entry for the same subproblem */ -}; - -struct IOSTAT -{ /* status change entry */ - int k; - /* ordinal number of corresponding row (1 <= k <= m) or column - (m+1 <= k <= m+n), where m and n are the number of rows and - columns, resp., in the parent subproblem */ - unsigned char stat; - /* new status */ - IOSTAT *next; - /* pointer to next entry for the same subproblem */ -}; - -struct IOSROW -{ /* row (constraint) addition entry */ - char *name; - /* row name or NULL */ - unsigned char origin; - /* row origin flag (see glp_attr.origin) */ - unsigned char klass; - /* row class descriptor (see glp_attr.klass) */ - unsigned char type; - /* row type (GLP_LO, GLP_UP, etc.) */ - double lb; - /* row lower bound */ - double ub; - /* row upper bound */ - IOSAIJ *ptr; - /* pointer to the row coefficient list */ - double rii; - /* row scale factor */ - unsigned char stat; - /* row status (GLP_BS, GLP_NL, etc.) */ - IOSROW *next; - /* pointer to next entry for the same subproblem */ -}; - -struct IOSAIJ -{ /* constraint coefficient */ - int j; - /* variable (column) number, 1 <= j <= n */ - double val; - /* non-zero coefficient value */ - IOSAIJ *next; - /* pointer to next coefficient for the same row */ -}; - -struct IOSPOOL -{ /* cut pool */ - int size; - /* pool size = number of cuts in the pool */ - IOSCUT *head; - /* pointer to the first cut */ - IOSCUT *tail; - /* pointer to the last cut */ - int ord; - /* ordinal number of the current cut, 1 <= ord <= size */ - IOSCUT *curr; - /* pointer to the current cut */ -}; - -struct IOSCUT -{ /* cut (cutting plane constraint) */ - char *name; - /* cut name or NULL */ - unsigned char klass; - /* cut class descriptor (see glp_attr.klass) */ - IOSAIJ *ptr; - /* pointer to the cut coefficient list */ - unsigned char type; - /* cut type: - GLP_LO: sum a[j] * x[j] >= b - GLP_UP: sum a[j] * x[j] <= b - GLP_FX: sum a[j] * x[j] = b */ - double rhs; - /* cut right-hand side */ - IOSCUT *prev; - /* pointer to previous cut */ - IOSCUT *next; - /* pointer to next cut */ -}; - -#define ios_create_tree _glp_ios_create_tree -glp_tree *ios_create_tree(glp_prob *mip, const glp_iocp *parm); -/* create branch-and-bound tree */ - -#define ios_revive_node _glp_ios_revive_node -void ios_revive_node(glp_tree *tree, int p); -/* revive specified subproblem */ - -#define ios_freeze_node _glp_ios_freeze_node -void ios_freeze_node(glp_tree *tree); -/* freeze current subproblem */ - -#define ios_clone_node _glp_ios_clone_node -void ios_clone_node(glp_tree *tree, int p, int nnn, int ref[]); -/* clone specified subproblem */ - -#define ios_delete_node _glp_ios_delete_node -void ios_delete_node(glp_tree *tree, int p); -/* delete specified subproblem */ - -#define ios_delete_tree _glp_ios_delete_tree -void ios_delete_tree(glp_tree *tree); -/* delete branch-and-bound tree */ - -#define ios_eval_degrad _glp_ios_eval_degrad -void ios_eval_degrad(glp_tree *tree, int j, double *dn, double *up); -/* estimate obj. degrad. for down- and up-branches */ - -#define ios_round_bound _glp_ios_round_bound -double ios_round_bound(glp_tree *tree, double bound); -/* improve local bound by rounding */ - -#define ios_is_hopeful _glp_ios_is_hopeful -int ios_is_hopeful(glp_tree *tree, double bound); -/* check if subproblem is hopeful */ - -#define ios_best_node _glp_ios_best_node -int ios_best_node(glp_tree *tree); -/* find active node with best local bound */ - -#define ios_relative_gap _glp_ios_relative_gap -double ios_relative_gap(glp_tree *tree); -/* compute relative mip gap */ - -#define ios_solve_node _glp_ios_solve_node -int ios_solve_node(glp_tree *tree); -/* solve LP relaxation of current subproblem */ - -#define ios_create_pool _glp_ios_create_pool -IOSPOOL *ios_create_pool(glp_tree *tree); -/* create cut pool */ - -#define ios_add_row _glp_ios_add_row -int ios_add_row(glp_tree *tree, IOSPOOL *pool, - const char *name, int klass, int flags, int len, const int ind[], - const double val[], int type, double rhs); -/* add row (constraint) to the cut pool */ - -#define ios_find_row _glp_ios_find_row -IOSCUT *ios_find_row(IOSPOOL *pool, int i); -/* find row (constraint) in the cut pool */ - -#define ios_del_row _glp_ios_del_row -void ios_del_row(glp_tree *tree, IOSPOOL *pool, int i); -/* remove row (constraint) from the cut pool */ - -#define ios_clear_pool _glp_ios_clear_pool -void ios_clear_pool(glp_tree *tree, IOSPOOL *pool); -/* remove all rows (constraints) from the cut pool */ - -#define ios_delete_pool _glp_ios_delete_pool -void ios_delete_pool(glp_tree *tree, IOSPOOL *pool); -/* delete cut pool */ - -#if 1 /* 11/VII-2013 */ -#define ios_process_sol _glp_ios_process_sol -void ios_process_sol(glp_tree *T); -/* process integer feasible solution just found */ -#endif - -#define ios_preprocess_node _glp_ios_preprocess_node -int ios_preprocess_node(glp_tree *tree, int max_pass); -/* preprocess current subproblem */ - -#define ios_driver _glp_ios_driver -int ios_driver(glp_tree *tree); -/* branch-and-bound driver */ - -/**********************************************************************/ - -typedef struct IOSVEC IOSVEC; - -struct IOSVEC -{ /* sparse vector v = (v[j]) */ - int n; - /* dimension, n >= 0 */ - int nnz; - /* number of non-zero components, 0 <= nnz <= n */ - int *pos; /* int pos[1+n]; */ - /* pos[j] = k, 1 <= j <= n, is position of (non-zero) v[j] in the - arrays ind and val, where 1 <= k <= nnz; pos[j] = 0 means that - v[j] is structural zero */ - int *ind; /* int ind[1+n]; */ - /* ind[k] = j, 1 <= k <= nnz, is index of v[j] */ - double *val; /* double val[1+n]; */ - /* val[k], 1 <= k <= nnz, is a numeric value of v[j] */ -}; - -#define ios_create_vec _glp_ios_create_vec -IOSVEC *ios_create_vec(int n); -/* create sparse vector */ - -#define ios_check_vec _glp_ios_check_vec -void ios_check_vec(IOSVEC *v); -/* check that sparse vector has correct representation */ - -#define ios_get_vj _glp_ios_get_vj -double ios_get_vj(IOSVEC *v, int j); -/* retrieve component of sparse vector */ - -#define ios_set_vj _glp_ios_set_vj -void ios_set_vj(IOSVEC *v, int j, double val); -/* set/change component of sparse vector */ - -#define ios_clear_vec _glp_ios_clear_vec -void ios_clear_vec(IOSVEC *v); -/* set all components of sparse vector to zero */ - -#define ios_clean_vec _glp_ios_clean_vec -void ios_clean_vec(IOSVEC *v, double eps); -/* remove zero or small components from sparse vector */ - -#define ios_copy_vec _glp_ios_copy_vec -void ios_copy_vec(IOSVEC *x, IOSVEC *y); -/* copy sparse vector (x := y) */ - -#define ios_linear_comb _glp_ios_linear_comb -void ios_linear_comb(IOSVEC *x, double a, IOSVEC *y); -/* compute linear combination (x := x + a * y) */ - -#define ios_delete_vec _glp_ios_delete_vec -void ios_delete_vec(IOSVEC *v); -/* delete sparse vector */ - -/**********************************************************************/ - -#define ios_gmi_gen _glp_ios_gmi_gen -void ios_gmi_gen(glp_tree *tree); -/* generate Gomory's mixed integer cuts */ - -#define ios_mir_init _glp_ios_mir_init -void *ios_mir_init(glp_tree *tree); -/* initialize MIR cut generator */ - -#define ios_mir_gen _glp_ios_mir_gen -void ios_mir_gen(glp_tree *tree, void *gen); -/* generate MIR cuts */ - -#define ios_mir_term _glp_ios_mir_term -void ios_mir_term(void *gen); -/* terminate MIR cut generator */ - -#define ios_cov_gen _glp_ios_cov_gen -void ios_cov_gen(glp_tree *tree); -/* generate mixed cover cuts */ - -#define ios_clq_init _glp_ios_clq_init -void *ios_clq_init(glp_tree *tree); -/* initialize clique cut generator */ - -#define ios_clq_gen _glp_ios_clq_gen -void ios_clq_gen(glp_tree *tree, void *gen); -/* generate clique cuts */ - -#define ios_clq_term _glp_ios_clq_term -void ios_clq_term(void *gen); -/* terminate clique cut generator */ - -#define ios_pcost_init _glp_ios_pcost_init -void *ios_pcost_init(glp_tree *tree); -/* initialize working data used on pseudocost branching */ - -#define ios_pcost_branch _glp_ios_pcost_branch -int ios_pcost_branch(glp_tree *T, int *next); -/* choose branching variable with pseudocost branching */ - -#define ios_pcost_update _glp_ios_pcost_update -void ios_pcost_update(glp_tree *tree); -/* update history information for pseudocost branching */ - -#define ios_pcost_free _glp_ios_pcost_free -void ios_pcost_free(glp_tree *tree); -/* free working area used on pseudocost branching */ - -#define ios_feas_pump _glp_ios_feas_pump -void ios_feas_pump(glp_tree *T); -/* feasibility pump heuristic */ - -#if 1 /* 25/V-2013 */ -#define ios_proxy_heur _glp_ios_proxy_heur -void ios_proxy_heur(glp_tree *T); -/* proximity search heuristic */ -#endif - -#define ios_process_cuts _glp_ios_process_cuts -void ios_process_cuts(glp_tree *T); -/* process cuts stored in the local cut pool */ - -#define ios_choose_node _glp_ios_choose_node -int ios_choose_node(glp_tree *T); -/* select subproblem to continue the search */ - -#define ios_choose_var _glp_ios_choose_var -int ios_choose_var(glp_tree *T, int *next); -/* select variable to branch on */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpios01.c b/resources/3rdparty/glpk-4.53/src/glpios01.c deleted file mode 100644 index da1b9479f..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpios01.c +++ /dev/null @@ -1,1602 +0,0 @@ -/* glpios01.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpios.h" -#include "misc.h" - -static int lpx_eval_tab_row(glp_prob *lp, int k, int ind[], - double val[]) -{ /* compute row of the simplex tableau */ - return glp_eval_tab_row(lp, k, ind, val); -} - -static int lpx_dual_ratio_test(glp_prob *lp, int len, const int ind[], - const double val[], int how, double tol) -{ /* perform dual ratio test */ - int piv; - piv = glp_dual_rtest(lp, len, ind, val, how, tol); - xassert(0 <= piv && piv <= len); - return piv == 0 ? 0 : ind[piv]; -} - -/*********************************************************************** -* NAME -* -* ios_create_tree - create branch-and-bound tree -* -* SYNOPSIS -* -* #include "glpios.h" -* glp_tree *ios_create_tree(glp_prob *mip, const glp_iocp *parm); -* -* DESCRIPTION -* -* The routine ios_create_tree creates the branch-and-bound tree. -* -* Being created the tree consists of the only root subproblem whose -* reference number is 1. Note that initially the root subproblem is in -* frozen state and therefore needs to be revived. -* -* RETURNS -* -* The routine returns a pointer to the tree created. */ - -static IOSNPD *new_node(glp_tree *tree, IOSNPD *parent); - -glp_tree *ios_create_tree(glp_prob *mip, const glp_iocp *parm) -{ int m = mip->m; - int n = mip->n; - glp_tree *tree; - int i, j; - xassert(mip->tree == NULL); - mip->tree = tree = xmalloc(sizeof(glp_tree)); - tree->pool = dmp_create_pool(); - tree->n = n; - /* save original problem components */ - tree->orig_m = m; - tree->orig_type = xcalloc(1+m+n, sizeof(char)); - tree->orig_lb = xcalloc(1+m+n, sizeof(double)); - tree->orig_ub = xcalloc(1+m+n, sizeof(double)); - tree->orig_stat = xcalloc(1+m+n, sizeof(char)); - tree->orig_prim = xcalloc(1+m+n, sizeof(double)); - tree->orig_dual = xcalloc(1+m+n, sizeof(double)); - for (i = 1; i <= m; i++) - { GLPROW *row = mip->row[i]; - tree->orig_type[i] = (char)row->type; - tree->orig_lb[i] = row->lb; - tree->orig_ub[i] = row->ub; - tree->orig_stat[i] = (char)row->stat; - tree->orig_prim[i] = row->prim; - tree->orig_dual[i] = row->dual; - } - for (j = 1; j <= n; j++) - { GLPCOL *col = mip->col[j]; - tree->orig_type[m+j] = (char)col->type; - tree->orig_lb[m+j] = col->lb; - tree->orig_ub[m+j] = col->ub; - tree->orig_stat[m+j] = (char)col->stat; - tree->orig_prim[m+j] = col->prim; - tree->orig_dual[m+j] = col->dual; - } - tree->orig_obj = mip->obj_val; - /* initialize the branch-and-bound tree */ - tree->nslots = 0; - tree->avail = 0; - tree->slot = NULL; - tree->head = tree->tail = NULL; - tree->a_cnt = tree->n_cnt = tree->t_cnt = 0; - /* the root subproblem is not solved yet, so its final components - are unknown so far */ - tree->root_m = 0; - tree->root_type = NULL; - tree->root_lb = tree->root_ub = NULL; - tree->root_stat = NULL; - /* the current subproblem does not exist yet */ - tree->curr = NULL; - tree->mip = mip; - /*tree->solved = 0;*/ - tree->non_int = xcalloc(1+n, sizeof(char)); - memset(&tree->non_int[1], 0, n); - /* arrays to save parent subproblem components will be allocated - later */ - tree->pred_m = tree->pred_max = 0; - tree->pred_type = NULL; - tree->pred_lb = tree->pred_ub = NULL; - tree->pred_stat = NULL; - /* cut generator */ - tree->local = ios_create_pool(tree); - /*tree->first_attempt = 1;*/ - /*tree->max_added_cuts = 0;*/ - /*tree->min_eff = 0.0;*/ - /*tree->miss = 0;*/ - /*tree->just_selected = 0;*/ - tree->mir_gen = NULL; - tree->clq_gen = NULL; - /*tree->round = 0;*/ -#if 0 - /* create the conflict graph */ - tree->n_ref = xcalloc(1+n, sizeof(int)); - memset(&tree->n_ref[1], 0, n * sizeof(int)); - tree->c_ref = xcalloc(1+n, sizeof(int)); - memset(&tree->c_ref[1], 0, n * sizeof(int)); - tree->g = scg_create_graph(0); - tree->j_ref = xcalloc(1+tree->g->n_max, sizeof(int)); -#endif - /* pseudocost branching */ - tree->pcost = NULL; - tree->iwrk = xcalloc(1+n, sizeof(int)); - tree->dwrk = xcalloc(1+n, sizeof(double)); - /* initialize control parameters */ - tree->parm = parm; - tree->tm_beg = xtime(); -#if 0 /* 10/VI-2013 */ - tree->tm_lag = xlset(0); -#else - tree->tm_lag = 0.0; -#endif - tree->sol_cnt = 0; -#if 1 /* 11/VII-2013 */ - tree->P = NULL; - tree->npp = NULL; - tree->save_sol = parm->save_sol; - tree->save_cnt = 0; -#endif - /* initialize advanced solver interface */ - tree->reason = 0; - tree->reopt = 0; - tree->reinv = 0; - tree->br_var = 0; - tree->br_sel = 0; - tree->child = 0; - tree->next_p = 0; - /*tree->btrack = NULL;*/ - tree->stop = 0; - /* create the root subproblem, which initially is identical to - the original MIP */ - new_node(tree, NULL); - return tree; -} - -/*********************************************************************** -* NAME -* -* ios_revive_node - revive specified subproblem -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_revive_node(glp_tree *tree, int p); -* -* DESCRIPTION -* -* The routine ios_revive_node revives the specified subproblem, whose -* reference number is p, and thereby makes it the current subproblem. -* Note that the specified subproblem must be active. Besides, if the -* current subproblem already exists, it must be frozen before reviving -* another subproblem. */ - -void ios_revive_node(glp_tree *tree, int p) -{ glp_prob *mip = tree->mip; - IOSNPD *node, *root; - /* obtain pointer to the specified subproblem */ - xassert(1 <= p && p <= tree->nslots); - node = tree->slot[p].node; - xassert(node != NULL); - /* the specified subproblem must be active */ - xassert(node->count == 0); - /* the current subproblem must not exist */ - xassert(tree->curr == NULL); - /* the specified subproblem becomes current */ - tree->curr = node; - /*tree->solved = 0;*/ - /* obtain pointer to the root subproblem */ - root = tree->slot[1].node; - xassert(root != NULL); - /* at this point problem object components correspond to the root - subproblem, so if the root subproblem should be revived, there - is nothing more to do */ - if (node == root) goto done; - xassert(mip->m == tree->root_m); - /* build path from the root to the current node */ - node->temp = NULL; - for (node = node; node != NULL; node = node->up) - { if (node->up == NULL) - xassert(node == root); - else - node->up->temp = node; - } - /* go down from the root to the current node and make necessary - changes to restore components of the current subproblem */ - for (node = root; node != NULL; node = node->temp) - { int m = mip->m; - int n = mip->n; - /* if the current node is reached, the problem object at this - point corresponds to its parent, so save attributes of rows - and columns for the parent subproblem */ - if (node->temp == NULL) - { int i, j; - tree->pred_m = m; - /* allocate/reallocate arrays, if necessary */ - if (tree->pred_max < m + n) - { int new_size = m + n + 100; - if (tree->pred_type != NULL) xfree(tree->pred_type); - if (tree->pred_lb != NULL) xfree(tree->pred_lb); - if (tree->pred_ub != NULL) xfree(tree->pred_ub); - if (tree->pred_stat != NULL) xfree(tree->pred_stat); - tree->pred_max = new_size; - tree->pred_type = xcalloc(1+new_size, sizeof(char)); - tree->pred_lb = xcalloc(1+new_size, sizeof(double)); - tree->pred_ub = xcalloc(1+new_size, sizeof(double)); - tree->pred_stat = xcalloc(1+new_size, sizeof(char)); - } - /* save row attributes */ - for (i = 1; i <= m; i++) - { GLPROW *row = mip->row[i]; - tree->pred_type[i] = (char)row->type; - tree->pred_lb[i] = row->lb; - tree->pred_ub[i] = row->ub; - tree->pred_stat[i] = (char)row->stat; - } - /* save column attributes */ - for (j = 1; j <= n; j++) - { GLPCOL *col = mip->col[j]; - tree->pred_type[mip->m+j] = (char)col->type; - tree->pred_lb[mip->m+j] = col->lb; - tree->pred_ub[mip->m+j] = col->ub; - tree->pred_stat[mip->m+j] = (char)col->stat; - } - } - /* change bounds of rows and columns */ - { IOSBND *b; - for (b = node->b_ptr; b != NULL; b = b->next) - { if (b->k <= m) - glp_set_row_bnds(mip, b->k, b->type, b->lb, b->ub); - else - glp_set_col_bnds(mip, b->k-m, b->type, b->lb, b->ub); - } - } - /* change statuses of rows and columns */ - { IOSTAT *s; - for (s = node->s_ptr; s != NULL; s = s->next) - { if (s->k <= m) - glp_set_row_stat(mip, s->k, s->stat); - else - glp_set_col_stat(mip, s->k-m, s->stat); - } - } - /* add new rows */ - if (node->r_ptr != NULL) - { IOSROW *r; - IOSAIJ *a; - int i, len, *ind; - double *val; - ind = xcalloc(1+n, sizeof(int)); - val = xcalloc(1+n, sizeof(double)); - for (r = node->r_ptr; r != NULL; r = r->next) - { i = glp_add_rows(mip, 1); - glp_set_row_name(mip, i, r->name); -#if 1 /* 20/IX-2008 */ - xassert(mip->row[i]->level == 0); - mip->row[i]->level = node->level; - mip->row[i]->origin = r->origin; - mip->row[i]->klass = r->klass; -#endif - glp_set_row_bnds(mip, i, r->type, r->lb, r->ub); - len = 0; - for (a = r->ptr; a != NULL; a = a->next) - len++, ind[len] = a->j, val[len] = a->val; - glp_set_mat_row(mip, i, len, ind, val); - glp_set_rii(mip, i, r->rii); - glp_set_row_stat(mip, i, r->stat); - } - xfree(ind); - xfree(val); - } -#if 0 - /* add new edges to the conflict graph */ - /* add new cliques to the conflict graph */ - /* (not implemented yet) */ - xassert(node->own_nn == 0); - xassert(node->own_nc == 0); - xassert(node->e_ptr == NULL); -#endif - } - /* the specified subproblem has been revived */ - node = tree->curr; - /* delete its bound change list */ - while (node->b_ptr != NULL) - { IOSBND *b; - b = node->b_ptr; - node->b_ptr = b->next; - dmp_free_atom(tree->pool, b, sizeof(IOSBND)); - } - /* delete its status change list */ - while (node->s_ptr != NULL) - { IOSTAT *s; - s = node->s_ptr; - node->s_ptr = s->next; - dmp_free_atom(tree->pool, s, sizeof(IOSTAT)); - } -#if 1 /* 20/XI-2009 */ - /* delete its row addition list (additional rows may appear, for - example, due to branching on GUB constraints */ - while (node->r_ptr != NULL) - { IOSROW *r; - r = node->r_ptr; - node->r_ptr = r->next; - xassert(r->name == NULL); - while (r->ptr != NULL) - { IOSAIJ *a; - a = r->ptr; - r->ptr = a->next; - dmp_free_atom(tree->pool, a, sizeof(IOSAIJ)); - } - dmp_free_atom(tree->pool, r, sizeof(IOSROW)); - } -#endif -done: return; -} - -/*********************************************************************** -* NAME -* -* ios_freeze_node - freeze current subproblem -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_freeze_node(glp_tree *tree); -* -* DESCRIPTION -* -* The routine ios_freeze_node freezes the current subproblem. */ - -void ios_freeze_node(glp_tree *tree) -{ glp_prob *mip = tree->mip; - int m = mip->m; - int n = mip->n; - IOSNPD *node; - /* obtain pointer to the current subproblem */ - node = tree->curr; - xassert(node != NULL); - if (node->up == NULL) - { /* freeze the root subproblem */ - int k; - xassert(node->p == 1); - xassert(tree->root_m == 0); - xassert(tree->root_type == NULL); - xassert(tree->root_lb == NULL); - xassert(tree->root_ub == NULL); - xassert(tree->root_stat == NULL); - tree->root_m = m; - tree->root_type = xcalloc(1+m+n, sizeof(char)); - tree->root_lb = xcalloc(1+m+n, sizeof(double)); - tree->root_ub = xcalloc(1+m+n, sizeof(double)); - tree->root_stat = xcalloc(1+m+n, sizeof(char)); - for (k = 1; k <= m+n; k++) - { if (k <= m) - { GLPROW *row = mip->row[k]; - tree->root_type[k] = (char)row->type; - tree->root_lb[k] = row->lb; - tree->root_ub[k] = row->ub; - tree->root_stat[k] = (char)row->stat; - } - else - { GLPCOL *col = mip->col[k-m]; - tree->root_type[k] = (char)col->type; - tree->root_lb[k] = col->lb; - tree->root_ub[k] = col->ub; - tree->root_stat[k] = (char)col->stat; - } - } - } - else - { /* freeze non-root subproblem */ - int root_m = tree->root_m; - int pred_m = tree->pred_m; - int i, j, k; - xassert(pred_m <= m); - /* build change lists for rows and columns which exist in the - parent subproblem */ - xassert(node->b_ptr == NULL); - xassert(node->s_ptr == NULL); - for (k = 1; k <= pred_m + n; k++) - { int pred_type, pred_stat, type, stat; - double pred_lb, pred_ub, lb, ub; - /* determine attributes in the parent subproblem */ - pred_type = tree->pred_type[k]; - pred_lb = tree->pred_lb[k]; - pred_ub = tree->pred_ub[k]; - pred_stat = tree->pred_stat[k]; - /* determine attributes in the current subproblem */ - if (k <= pred_m) - { GLPROW *row = mip->row[k]; - type = row->type; - lb = row->lb; - ub = row->ub; - stat = row->stat; - } - else - { GLPCOL *col = mip->col[k - pred_m]; - type = col->type; - lb = col->lb; - ub = col->ub; - stat = col->stat; - } - /* save type and bounds of a row/column, if changed */ - if (!(pred_type == type && pred_lb == lb && pred_ub == ub)) - { IOSBND *b; - b = dmp_get_atom(tree->pool, sizeof(IOSBND)); - b->k = k; - b->type = (unsigned char)type; - b->lb = lb; - b->ub = ub; - b->next = node->b_ptr; - node->b_ptr = b; - } - /* save status of a row/column, if changed */ - if (pred_stat != stat) - { IOSTAT *s; - s = dmp_get_atom(tree->pool, sizeof(IOSTAT)); - s->k = k; - s->stat = (unsigned char)stat; - s->next = node->s_ptr; - node->s_ptr = s; - } - } - /* save new rows added to the current subproblem */ - xassert(node->r_ptr == NULL); - if (pred_m < m) - { int i, len, *ind; - double *val; - ind = xcalloc(1+n, sizeof(int)); - val = xcalloc(1+n, sizeof(double)); - for (i = m; i > pred_m; i--) - { GLPROW *row = mip->row[i]; - IOSROW *r; - const char *name; - r = dmp_get_atom(tree->pool, sizeof(IOSROW)); - name = glp_get_row_name(mip, i); - if (name == NULL) - r->name = NULL; - else - { r->name = dmp_get_atom(tree->pool, strlen(name)+1); - strcpy(r->name, name); - } -#if 1 /* 20/IX-2008 */ - r->origin = row->origin; - r->klass = row->klass; -#endif - r->type = (unsigned char)row->type; - r->lb = row->lb; - r->ub = row->ub; - r->ptr = NULL; - len = glp_get_mat_row(mip, i, ind, val); - for (k = 1; k <= len; k++) - { IOSAIJ *a; - a = dmp_get_atom(tree->pool, sizeof(IOSAIJ)); - a->j = ind[k]; - a->val = val[k]; - a->next = r->ptr; - r->ptr = a; - } - r->rii = row->rii; - r->stat = (unsigned char)row->stat; - r->next = node->r_ptr; - node->r_ptr = r; - } - xfree(ind); - xfree(val); - } - /* remove all rows missing in the root subproblem */ - if (m != root_m) - { int nrs, *num; - nrs = m - root_m; - xassert(nrs > 0); - num = xcalloc(1+nrs, sizeof(int)); - for (i = 1; i <= nrs; i++) num[i] = root_m + i; - glp_del_rows(mip, nrs, num); - xfree(num); - } - m = mip->m; - /* and restore attributes of all rows and columns for the root - subproblem */ - xassert(m == root_m); - for (i = 1; i <= m; i++) - { glp_set_row_bnds(mip, i, tree->root_type[i], - tree->root_lb[i], tree->root_ub[i]); - glp_set_row_stat(mip, i, tree->root_stat[i]); - } - for (j = 1; j <= n; j++) - { glp_set_col_bnds(mip, j, tree->root_type[m+j], - tree->root_lb[m+j], tree->root_ub[m+j]); - glp_set_col_stat(mip, j, tree->root_stat[m+j]); - } -#if 1 - /* remove all edges and cliques missing in the conflict graph - for the root subproblem */ - /* (not implemented yet) */ -#endif - } - /* the current subproblem has been frozen */ - tree->curr = NULL; - return; -} - -/*********************************************************************** -* NAME -* -* ios_clone_node - clone specified subproblem -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_clone_node(glp_tree *tree, int p, int nnn, int ref[]); -* -* DESCRIPTION -* -* The routine ios_clone_node clones the specified subproblem, whose -* reference number is p, creating its nnn exact copies. Note that the -* specified subproblem must be active and must be in the frozen state -* (i.e. it must not be the current subproblem). -* -* Each clone, an exact copy of the specified subproblem, becomes a new -* active subproblem added to the end of the active list. After cloning -* the specified subproblem becomes inactive. -* -* The reference numbers of clone subproblems are stored to locations -* ref[1], ..., ref[nnn]. */ - -static int get_slot(glp_tree *tree) -{ int p; - /* if no free slots are available, increase the room */ - if (tree->avail == 0) - { int nslots = tree->nslots; - IOSLOT *save = tree->slot; - if (nslots == 0) - tree->nslots = 20; - else - { tree->nslots = nslots + nslots; - xassert(tree->nslots > nslots); - } - tree->slot = xcalloc(1+tree->nslots, sizeof(IOSLOT)); - if (save != NULL) - { memcpy(&tree->slot[1], &save[1], nslots * sizeof(IOSLOT)); - xfree(save); - } - /* push more free slots into the stack */ - for (p = tree->nslots; p > nslots; p--) - { tree->slot[p].node = NULL; - tree->slot[p].next = tree->avail; - tree->avail = p; - } - } - /* pull a free slot from the stack */ - p = tree->avail; - tree->avail = tree->slot[p].next; - xassert(tree->slot[p].node == NULL); - tree->slot[p].next = 0; - return p; -} - -static IOSNPD *new_node(glp_tree *tree, IOSNPD *parent) -{ IOSNPD *node; - int p; - /* pull a free slot for the new node */ - p = get_slot(tree); - /* create descriptor of the new subproblem */ - node = dmp_get_atom(tree->pool, sizeof(IOSNPD)); - tree->slot[p].node = node; - node->p = p; - node->up = parent; - node->level = (parent == NULL ? 0 : parent->level + 1); - node->count = 0; - node->b_ptr = NULL; - node->s_ptr = NULL; - node->r_ptr = NULL; - node->solved = 0; -#if 0 - node->own_nn = node->own_nc = 0; - node->e_ptr = NULL; -#endif -#if 1 /* 04/X-2008 */ - node->lp_obj = (parent == NULL ? (tree->mip->dir == GLP_MIN ? - -DBL_MAX : +DBL_MAX) : parent->lp_obj); -#endif - node->bound = (parent == NULL ? (tree->mip->dir == GLP_MIN ? - -DBL_MAX : +DBL_MAX) : parent->bound); - node->br_var = 0; - node->br_val = 0.0; - node->ii_cnt = 0; - node->ii_sum = 0.0; -#if 1 /* 30/XI-2009 */ - node->changed = 0; -#endif - if (tree->parm->cb_size == 0) - node->data = NULL; - else - { node->data = dmp_get_atom(tree->pool, tree->parm->cb_size); - memset(node->data, 0, tree->parm->cb_size); - } - node->temp = NULL; - node->prev = tree->tail; - node->next = NULL; - /* add the new subproblem to the end of the active list */ - if (tree->head == NULL) - tree->head = node; - else - tree->tail->next = node; - tree->tail = node; - tree->a_cnt++; - tree->n_cnt++; - tree->t_cnt++; - /* increase the number of child subproblems */ - if (parent == NULL) - xassert(p == 1); - else - parent->count++; - return node; -} - -void ios_clone_node(glp_tree *tree, int p, int nnn, int ref[]) -{ IOSNPD *node; - int k; - /* obtain pointer to the subproblem to be cloned */ - xassert(1 <= p && p <= tree->nslots); - node = tree->slot[p].node; - xassert(node != NULL); - /* the specified subproblem must be active */ - xassert(node->count == 0); - /* and must be in the frozen state */ - xassert(tree->curr != node); - /* remove the specified subproblem from the active list, because - it becomes inactive */ - if (node->prev == NULL) - tree->head = node->next; - else - node->prev->next = node->next; - if (node->next == NULL) - tree->tail = node->prev; - else - node->next->prev = node->prev; - node->prev = node->next = NULL; - tree->a_cnt--; - /* create clone subproblems */ - xassert(nnn > 0); - for (k = 1; k <= nnn; k++) - ref[k] = new_node(tree, node)->p; - return; -} - -/*********************************************************************** -* NAME -* -* ios_delete_node - delete specified subproblem -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_delete_node(glp_tree *tree, int p); -* -* DESCRIPTION -* -* The routine ios_delete_node deletes the specified subproblem, whose -* reference number is p. The subproblem must be active and must be in -* the frozen state (i.e. it must not be the current subproblem). -* -* Note that deletion is performed recursively, i.e. if a subproblem to -* be deleted is the only child of its parent, the parent subproblem is -* also deleted, etc. */ - -void ios_delete_node(glp_tree *tree, int p) -{ IOSNPD *node, *temp; - /* obtain pointer to the subproblem to be deleted */ - xassert(1 <= p && p <= tree->nslots); - node = tree->slot[p].node; - xassert(node != NULL); - /* the specified subproblem must be active */ - xassert(node->count == 0); - /* and must be in the frozen state */ - xassert(tree->curr != node); - /* remove the specified subproblem from the active list, because - it is gone from the tree */ - if (node->prev == NULL) - tree->head = node->next; - else - node->prev->next = node->next; - if (node->next == NULL) - tree->tail = node->prev; - else - node->next->prev = node->prev; - node->prev = node->next = NULL; - tree->a_cnt--; -loop: /* recursive deletion starts here */ - /* delete the bound change list */ - { IOSBND *b; - while (node->b_ptr != NULL) - { b = node->b_ptr; - node->b_ptr = b->next; - dmp_free_atom(tree->pool, b, sizeof(IOSBND)); - } - } - /* delete the status change list */ - { IOSTAT *s; - while (node->s_ptr != NULL) - { s = node->s_ptr; - node->s_ptr = s->next; - dmp_free_atom(tree->pool, s, sizeof(IOSTAT)); - } - } - /* delete the row addition list */ - while (node->r_ptr != NULL) - { IOSROW *r; - r = node->r_ptr; - if (r->name != NULL) - dmp_free_atom(tree->pool, r->name, strlen(r->name)+1); - while (r->ptr != NULL) - { IOSAIJ *a; - a = r->ptr; - r->ptr = a->next; - dmp_free_atom(tree->pool, a, sizeof(IOSAIJ)); - } - node->r_ptr = r->next; - dmp_free_atom(tree->pool, r, sizeof(IOSROW)); - } -#if 0 - /* delete the edge addition list */ - /* delete the clique addition list */ - /* (not implemented yet) */ - xassert(node->own_nn == 0); - xassert(node->own_nc == 0); - xassert(node->e_ptr == NULL); -#endif - /* free application-specific data */ - if (tree->parm->cb_size == 0) - xassert(node->data == NULL); - else - dmp_free_atom(tree->pool, node->data, tree->parm->cb_size); - /* free the corresponding node slot */ - p = node->p; - xassert(tree->slot[p].node == node); - tree->slot[p].node = NULL; - tree->slot[p].next = tree->avail; - tree->avail = p; - /* save pointer to the parent subproblem */ - temp = node->up; - /* delete the subproblem descriptor */ - dmp_free_atom(tree->pool, node, sizeof(IOSNPD)); - tree->n_cnt--; - /* take pointer to the parent subproblem */ - node = temp; - if (node != NULL) - { /* the parent subproblem exists; decrease the number of its - child subproblems */ - xassert(node->count > 0); - node->count--; - /* if now the parent subproblem has no childs, it also must be - deleted */ - if (node->count == 0) goto loop; - } - return; -} - -/*********************************************************************** -* NAME -* -* ios_delete_tree - delete branch-and-bound tree -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_delete_tree(glp_tree *tree); -* -* DESCRIPTION -* -* The routine ios_delete_tree deletes the branch-and-bound tree, which -* the parameter tree points to, and frees all the memory allocated to -* this program object. -* -* On exit components of the problem object are restored to correspond -* to the original MIP passed to the routine ios_create_tree. */ - -void ios_delete_tree(glp_tree *tree) -{ glp_prob *mip = tree->mip; - int i, j; - int m = mip->m; - int n = mip->n; - xassert(mip->tree == tree); - /* remove all additional rows */ - if (m != tree->orig_m) - { int nrs, *num; - nrs = m - tree->orig_m; - xassert(nrs > 0); - num = xcalloc(1+nrs, sizeof(int)); - for (i = 1; i <= nrs; i++) num[i] = tree->orig_m + i; - glp_del_rows(mip, nrs, num); - xfree(num); - } - m = tree->orig_m; - /* restore original attributes of rows and columns */ - xassert(m == tree->orig_m); - xassert(n == tree->n); - for (i = 1; i <= m; i++) - { glp_set_row_bnds(mip, i, tree->orig_type[i], - tree->orig_lb[i], tree->orig_ub[i]); - glp_set_row_stat(mip, i, tree->orig_stat[i]); - mip->row[i]->prim = tree->orig_prim[i]; - mip->row[i]->dual = tree->orig_dual[i]; - } - for (j = 1; j <= n; j++) - { glp_set_col_bnds(mip, j, tree->orig_type[m+j], - tree->orig_lb[m+j], tree->orig_ub[m+j]); - glp_set_col_stat(mip, j, tree->orig_stat[m+j]); - mip->col[j]->prim = tree->orig_prim[m+j]; - mip->col[j]->dual = tree->orig_dual[m+j]; - } - mip->pbs_stat = mip->dbs_stat = GLP_FEAS; - mip->obj_val = tree->orig_obj; - /* delete the branch-and-bound tree */ - xassert(tree->local != NULL); - ios_delete_pool(tree, tree->local); - dmp_delete_pool(tree->pool); - xfree(tree->orig_type); - xfree(tree->orig_lb); - xfree(tree->orig_ub); - xfree(tree->orig_stat); - xfree(tree->orig_prim); - xfree(tree->orig_dual); - xfree(tree->slot); - if (tree->root_type != NULL) xfree(tree->root_type); - if (tree->root_lb != NULL) xfree(tree->root_lb); - if (tree->root_ub != NULL) xfree(tree->root_ub); - if (tree->root_stat != NULL) xfree(tree->root_stat); - xfree(tree->non_int); -#if 0 - xfree(tree->n_ref); - xfree(tree->c_ref); - xfree(tree->j_ref); -#endif - if (tree->pcost != NULL) ios_pcost_free(tree); - xfree(tree->iwrk); - xfree(tree->dwrk); -#if 0 - scg_delete_graph(tree->g); -#endif - if (tree->pred_type != NULL) xfree(tree->pred_type); - if (tree->pred_lb != NULL) xfree(tree->pred_lb); - if (tree->pred_ub != NULL) xfree(tree->pred_ub); - if (tree->pred_stat != NULL) xfree(tree->pred_stat); -#if 0 - xassert(tree->cut_gen == NULL); -#endif - xassert(tree->mir_gen == NULL); - xassert(tree->clq_gen == NULL); - xfree(tree); - mip->tree = NULL; - return; -} - -/*********************************************************************** -* NAME -* -* ios_eval_degrad - estimate obj. degrad. for down- and up-branches -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_eval_degrad(glp_tree *tree, int j, double *dn, double *up); -* -* DESCRIPTION -* -* Given optimal basis to LP relaxation of the current subproblem the -* routine ios_eval_degrad performs the dual ratio test to compute the -* objective values in the adjacent basis for down- and up-branches, -* which are stored in locations *dn and *up, assuming that x[j] is a -* variable chosen to branch upon. */ - -void ios_eval_degrad(glp_tree *tree, int j, double *dn, double *up) -{ glp_prob *mip = tree->mip; - int m = mip->m, n = mip->n; - int len, kase, k, t, stat; - double alfa, beta, gamma, delta, dz; - int *ind = tree->iwrk; - double *val = tree->dwrk; - /* current basis must be optimal */ - xassert(glp_get_status(mip) == GLP_OPT); - /* basis factorization must exist */ - xassert(glp_bf_exists(mip)); - /* obtain (fractional) value of x[j] in optimal basic solution - to LP relaxation of the current subproblem */ - xassert(1 <= j && j <= n); - beta = mip->col[j]->prim; - /* since the value of x[j] is fractional, it is basic; compute - corresponding row of the simplex table */ - len = lpx_eval_tab_row(mip, m+j, ind, val); - /* kase < 0 means down-branch; kase > 0 means up-branch */ - for (kase = -1; kase <= +1; kase += 2) - { /* for down-branch we introduce new upper bound floor(beta) - for x[j]; similarly, for up-branch we introduce new lower - bound ceil(beta) for x[j]; in the current basis this new - upper/lower bound is violated, so in the adjacent basis - x[j] will leave the basis and go to its new upper/lower - bound; we need to know which non-basic variable x[k] should - enter the basis to keep dual feasibility */ -#if 0 /* 23/XI-2009 */ - k = lpx_dual_ratio_test(mip, len, ind, val, kase, 1e-7); -#else - k = lpx_dual_ratio_test(mip, len, ind, val, kase, 1e-9); -#endif - /* if no variable has been chosen, current basis being primal - infeasible due to the new upper/lower bound of x[j] is dual - unbounded, therefore, LP relaxation to corresponding branch - has no primal feasible solution */ - if (k == 0) - { if (mip->dir == GLP_MIN) - { if (kase < 0) - *dn = +DBL_MAX; - else - *up = +DBL_MAX; - } - else if (mip->dir == GLP_MAX) - { if (kase < 0) - *dn = -DBL_MAX; - else - *up = -DBL_MAX; - } - else - xassert(mip != mip); - continue; - } - xassert(1 <= k && k <= m+n); - /* row of the simplex table corresponding to specified basic - variable x[j] is the following: - x[j] = ... + alfa * x[k] + ... ; - we need to know influence coefficient, alfa, at non-basic - variable x[k] chosen with the dual ratio test */ - for (t = 1; t <= len; t++) - if (ind[t] == k) break; - xassert(1 <= t && t <= len); - alfa = val[t]; - /* determine status and reduced cost of variable x[k] */ - if (k <= m) - { stat = mip->row[k]->stat; - gamma = mip->row[k]->dual; - } - else - { stat = mip->col[k-m]->stat; - gamma = mip->col[k-m]->dual; - } - /* x[k] cannot be basic or fixed non-basic */ - xassert(stat == GLP_NL || stat == GLP_NU || stat == GLP_NF); - /* if the current basis is dual degenerative, some reduced - costs, which are close to zero, may have wrong sign due to - round-off errors, so correct the sign of gamma */ - if (mip->dir == GLP_MIN) - { if (stat == GLP_NL && gamma < 0.0 || - stat == GLP_NU && gamma > 0.0 || - stat == GLP_NF) gamma = 0.0; - } - else if (mip->dir == GLP_MAX) - { if (stat == GLP_NL && gamma > 0.0 || - stat == GLP_NU && gamma < 0.0 || - stat == GLP_NF) gamma = 0.0; - } - else - xassert(mip != mip); - /* determine the change of x[j] in the adjacent basis: - delta x[j] = new x[j] - old x[j] */ - delta = (kase < 0 ? floor(beta) : ceil(beta)) - beta; - /* compute the change of x[k] in the adjacent basis: - delta x[k] = new x[k] - old x[k] = delta x[j] / alfa */ - delta /= alfa; - /* compute the change of the objective in the adjacent basis: - delta z = new z - old z = gamma * delta x[k] */ - dz = gamma * delta; - if (mip->dir == GLP_MIN) - xassert(dz >= 0.0); - else if (mip->dir == GLP_MAX) - xassert(dz <= 0.0); - else - xassert(mip != mip); - /* compute the new objective value in the adjacent basis: - new z = old z + delta z */ - if (kase < 0) - *dn = mip->obj_val + dz; - else - *up = mip->obj_val + dz; - } - /*xprintf("obj = %g; dn = %g; up = %g\n", - mip->obj_val, *dn, *up);*/ - return; -} - -/*********************************************************************** -* NAME -* -* ios_round_bound - improve local bound by rounding -* -* SYNOPSIS -* -* #include "glpios.h" -* double ios_round_bound(glp_tree *tree, double bound); -* -* RETURNS -* -* For the given local bound for any integer feasible solution to the -* current subproblem the routine ios_round_bound returns an improved -* local bound for the same integer feasible solution. -* -* BACKGROUND -* -* Let the current subproblem has the following objective function: -* -* z = sum c[j] * x[j] + s >= b, (1) -* j in J -* -* where J = {j: c[j] is non-zero and integer, x[j] is integer}, s is -* the sum of terms corresponding to fixed variables, b is an initial -* local bound (minimization). -* -* From (1) it follows that: -* -* d * sum (c[j] / d) * x[j] + s >= b, (2) -* j in J -* -* or, equivalently, -* -* sum (c[j] / d) * x[j] >= (b - s) / d = h, (3) -* j in J -* -* where d = gcd(c[j]). Since the left-hand side of (3) is integer, -* h = (b - s) / d can be rounded up to the nearest integer: -* -* h' = ceil(h) = (b' - s) / d, (4) -* -* that gives an rounded, improved local bound: -* -* b' = d * h' + s. (5) -* -* In case of maximization '>=' in (1) should be replaced by '<=' that -* leads to the following formula: -* -* h' = floor(h) = (b' - s) / d, (6) -* -* which should used in the same way as (4). -* -* NOTE: If b is a valid local bound for a child of the current -* subproblem, b' is also valid for that child subproblem. */ - -double ios_round_bound(glp_tree *tree, double bound) -{ glp_prob *mip = tree->mip; - int n = mip->n; - int d, j, nn, *c = tree->iwrk; - double s, h; - /* determine c[j] and compute s */ - nn = 0, s = mip->c0, d = 0; - for (j = 1; j <= n; j++) - { GLPCOL *col = mip->col[j]; - if (col->coef == 0.0) continue; - if (col->type == GLP_FX) - { /* fixed variable */ - s += col->coef * col->prim; - } - else - { /* non-fixed variable */ - if (col->kind != GLP_IV) goto skip; - if (col->coef != floor(col->coef)) goto skip; - if (fabs(col->coef) <= (double)INT_MAX) - c[++nn] = (int)fabs(col->coef); - else - d = 1; - } - } - /* compute d = gcd(c[1],...c[nn]) */ - if (d == 0) - { if (nn == 0) goto skip; - d = gcdn(nn, c); - } - xassert(d > 0); - /* compute new local bound */ - if (mip->dir == GLP_MIN) - { if (bound != +DBL_MAX) - { h = (bound - s) / (double)d; - if (h >= floor(h) + 0.001) - { /* round up */ - h = ceil(h); - /*xprintf("d = %d; old = %g; ", d, bound);*/ - bound = (double)d * h + s; - /*xprintf("new = %g\n", bound);*/ - } - } - } - else if (mip->dir == GLP_MAX) - { if (bound != -DBL_MAX) - { h = (bound - s) / (double)d; - if (h <= ceil(h) - 0.001) - { /* round down */ - h = floor(h); - bound = (double)d * h + s; - } - } - } - else - xassert(mip != mip); -skip: return bound; -} - -/*********************************************************************** -* NAME -* -* ios_is_hopeful - check if subproblem is hopeful -* -* SYNOPSIS -* -* #include "glpios.h" -* int ios_is_hopeful(glp_tree *tree, double bound); -* -* DESCRIPTION -* -* Given the local bound of a subproblem the routine ios_is_hopeful -* checks if the subproblem can have an integer optimal solution which -* is better than the best one currently known. -* -* RETURNS -* -* If the subproblem can have a better integer optimal solution, the -* routine returns non-zero; otherwise, if the corresponding branch can -* be pruned, the routine returns zero. */ - -int ios_is_hopeful(glp_tree *tree, double bound) -{ glp_prob *mip = tree->mip; - int ret = 1; - double eps; - if (mip->mip_stat == GLP_FEAS) - { eps = tree->parm->tol_obj * (1.0 + fabs(mip->mip_obj)); - switch (mip->dir) - { case GLP_MIN: - if (bound >= mip->mip_obj - eps) ret = 0; - break; - case GLP_MAX: - if (bound <= mip->mip_obj + eps) ret = 0; - break; - default: - xassert(mip != mip); - } - } - else - { switch (mip->dir) - { case GLP_MIN: - if (bound == +DBL_MAX) ret = 0; - break; - case GLP_MAX: - if (bound == -DBL_MAX) ret = 0; - break; - default: - xassert(mip != mip); - } - } - return ret; -} - -/*********************************************************************** -* NAME -* -* ios_best_node - find active node with best local bound -* -* SYNOPSIS -* -* #include "glpios.h" -* int ios_best_node(glp_tree *tree); -* -* DESCRIPTION -* -* The routine ios_best_node finds an active node whose local bound is -* best among other active nodes. -* -* It is understood that the integer optimal solution of the original -* mip problem cannot be better than the best bound, so the best bound -* is an lower (minimization) or upper (maximization) global bound for -* the original problem. -* -* RETURNS -* -* The routine ios_best_node returns the subproblem reference number -* for the best node. However, if the tree is empty, it returns zero. */ - -int ios_best_node(glp_tree *tree) -{ IOSNPD *node, *best = NULL; - switch (tree->mip->dir) - { case GLP_MIN: - /* minimization */ - for (node = tree->head; node != NULL; node = node->next) - if (best == NULL || best->bound > node->bound) - best = node; - break; - case GLP_MAX: - /* maximization */ - for (node = tree->head; node != NULL; node = node->next) - if (best == NULL || best->bound < node->bound) - best = node; - break; - default: - xassert(tree != tree); - } - return best == NULL ? 0 : best->p; -} - -/*********************************************************************** -* NAME -* -* ios_relative_gap - compute relative mip gap -* -* SYNOPSIS -* -* #include "glpios.h" -* double ios_relative_gap(glp_tree *tree); -* -* DESCRIPTION -* -* The routine ios_relative_gap computes the relative mip gap using the -* formula: -* -* gap = |best_mip - best_bnd| / (|best_mip| + DBL_EPSILON), -* -* where best_mip is the best integer feasible solution found so far, -* best_bnd is the best (global) bound. If no integer feasible solution -* has been found yet, rel_gap is set to DBL_MAX. -* -* RETURNS -* -* The routine ios_relative_gap returns the relative mip gap. */ - -double ios_relative_gap(glp_tree *tree) -{ glp_prob *mip = tree->mip; - int p; - double best_mip, best_bnd, gap; - if (mip->mip_stat == GLP_FEAS) - { best_mip = mip->mip_obj; - p = ios_best_node(tree); - if (p == 0) - { /* the tree is empty */ - gap = 0.0; - } - else - { best_bnd = tree->slot[p].node->bound; - gap = fabs(best_mip - best_bnd) / (fabs(best_mip) + - DBL_EPSILON); - } - } - else - { /* no integer feasible solution has been found yet */ - gap = DBL_MAX; - } - return gap; -} - -/*********************************************************************** -* NAME -* -* ios_solve_node - solve LP relaxation of current subproblem -* -* SYNOPSIS -* -* #include "glpios.h" -* int ios_solve_node(glp_tree *tree); -* -* DESCRIPTION -* -* The routine ios_solve_node re-optimizes LP relaxation of the current -* subproblem using the dual simplex method. -* -* RETURNS -* -* The routine returns the code which is reported by glp_simplex. */ - -int ios_solve_node(glp_tree *tree) -{ glp_prob *mip = tree->mip; - glp_smcp parm; - int ret; - /* the current subproblem must exist */ - xassert(tree->curr != NULL); - /* set some control parameters */ - glp_init_smcp(&parm); - switch (tree->parm->msg_lev) - { case GLP_MSG_OFF: - parm.msg_lev = GLP_MSG_OFF; break; - case GLP_MSG_ERR: - parm.msg_lev = GLP_MSG_ERR; break; - case GLP_MSG_ON: - case GLP_MSG_ALL: - parm.msg_lev = GLP_MSG_ON; break; - case GLP_MSG_DBG: - parm.msg_lev = GLP_MSG_ALL; break; - default: - xassert(tree != tree); - } - parm.meth = GLP_DUALP; - if (tree->parm->msg_lev < GLP_MSG_DBG) - parm.out_dly = tree->parm->out_dly; - else - parm.out_dly = 0; - /* if the incumbent objective value is already known, use it to - prematurely terminate the dual simplex search */ - if (mip->mip_stat == GLP_FEAS) - { switch (tree->mip->dir) - { case GLP_MIN: - parm.obj_ul = mip->mip_obj; - break; - case GLP_MAX: - parm.obj_ll = mip->mip_obj; - break; - default: - xassert(mip != mip); - } - } - /* try to solve/re-optimize the LP relaxation */ - ret = glp_simplex(mip, &parm); - tree->curr->solved++; -#if 0 - xprintf("ret = %d; status = %d; pbs = %d; dbs = %d; some = %d\n", - ret, glp_get_status(mip), mip->pbs_stat, mip->dbs_stat, - mip->some); - lpx_print_sol(mip, "sol"); -#endif - return ret; -} - -/**********************************************************************/ - -IOSPOOL *ios_create_pool(glp_tree *tree) -{ /* create cut pool */ - IOSPOOL *pool; -#if 0 - pool = dmp_get_atom(tree->pool, sizeof(IOSPOOL)); -#else - xassert(tree == tree); - pool = xmalloc(sizeof(IOSPOOL)); -#endif - pool->size = 0; - pool->head = pool->tail = NULL; - pool->ord = 0, pool->curr = NULL; - return pool; -} - -int ios_add_row(glp_tree *tree, IOSPOOL *pool, - const char *name, int klass, int flags, int len, const int ind[], - const double val[], int type, double rhs) -{ /* add row (constraint) to the cut pool */ - IOSCUT *cut; - IOSAIJ *aij; - int k; - xassert(pool != NULL); - cut = dmp_get_atom(tree->pool, sizeof(IOSCUT)); - if (name == NULL || name[0] == '\0') - cut->name = NULL; - else - { for (k = 0; name[k] != '\0'; k++) - { if (k == 256) - xerror("glp_ios_add_row: cut name too long\n"); - if (iscntrl((unsigned char)name[k])) - xerror("glp_ios_add_row: cut name contains invalid chara" - "cter(s)\n"); - } - cut->name = dmp_get_atom(tree->pool, strlen(name)+1); - strcpy(cut->name, name); - } - if (!(0 <= klass && klass <= 255)) - xerror("glp_ios_add_row: klass = %d; invalid cut class\n", - klass); - cut->klass = (unsigned char)klass; - if (flags != 0) - xerror("glp_ios_add_row: flags = %d; invalid cut flags\n", - flags); - cut->ptr = NULL; - if (!(0 <= len && len <= tree->n)) - xerror("glp_ios_add_row: len = %d; invalid cut length\n", - len); - for (k = 1; k <= len; k++) - { aij = dmp_get_atom(tree->pool, sizeof(IOSAIJ)); - if (!(1 <= ind[k] && ind[k] <= tree->n)) - xerror("glp_ios_add_row: ind[%d] = %d; column index out of " - "range\n", k, ind[k]); - aij->j = ind[k]; - aij->val = val[k]; - aij->next = cut->ptr; - cut->ptr = aij; - } - if (!(type == GLP_LO || type == GLP_UP || type == GLP_FX)) - xerror("glp_ios_add_row: type = %d; invalid cut type\n", - type); - cut->type = (unsigned char)type; - cut->rhs = rhs; - cut->prev = pool->tail; - cut->next = NULL; - if (cut->prev == NULL) - pool->head = cut; - else - cut->prev->next = cut; - pool->tail = cut; - pool->size++; - return pool->size; -} - -IOSCUT *ios_find_row(IOSPOOL *pool, int i) -{ /* find row (constraint) in the cut pool */ - /* (smart linear search) */ - xassert(pool != NULL); - xassert(1 <= i && i <= pool->size); - if (pool->ord == 0) - { xassert(pool->curr == NULL); - pool->ord = 1; - pool->curr = pool->head; - } - xassert(pool->curr != NULL); - if (i < pool->ord) - { if (i < pool->ord - i) - { pool->ord = 1; - pool->curr = pool->head; - while (pool->ord != i) - { pool->ord++; - xassert(pool->curr != NULL); - pool->curr = pool->curr->next; - } - } - else - { while (pool->ord != i) - { pool->ord--; - xassert(pool->curr != NULL); - pool->curr = pool->curr->prev; - } - } - } - else if (i > pool->ord) - { if (i - pool->ord < pool->size - i) - { while (pool->ord != i) - { pool->ord++; - xassert(pool->curr != NULL); - pool->curr = pool->curr->next; - } - } - else - { pool->ord = pool->size; - pool->curr = pool->tail; - while (pool->ord != i) - { pool->ord--; - xassert(pool->curr != NULL); - pool->curr = pool->curr->prev; - } - } - } - xassert(pool->ord == i); - xassert(pool->curr != NULL); - return pool->curr; -} - -void ios_del_row(glp_tree *tree, IOSPOOL *pool, int i) -{ /* remove row (constraint) from the cut pool */ - IOSCUT *cut; - IOSAIJ *aij; - xassert(pool != NULL); - if (!(1 <= i && i <= pool->size)) - xerror("glp_ios_del_row: i = %d; cut number out of range\n", - i); - cut = ios_find_row(pool, i); - xassert(pool->curr == cut); - if (cut->next != NULL) - pool->curr = cut->next; - else if (cut->prev != NULL) - pool->ord--, pool->curr = cut->prev; - else - pool->ord = 0, pool->curr = NULL; - if (cut->name != NULL) - dmp_free_atom(tree->pool, cut->name, strlen(cut->name)+1); - if (cut->prev == NULL) - { xassert(pool->head == cut); - pool->head = cut->next; - } - else - { xassert(cut->prev->next == cut); - cut->prev->next = cut->next; - } - if (cut->next == NULL) - { xassert(pool->tail == cut); - pool->tail = cut->prev; - } - else - { xassert(cut->next->prev == cut); - cut->next->prev = cut->prev; - } - while (cut->ptr != NULL) - { aij = cut->ptr; - cut->ptr = aij->next; - dmp_free_atom(tree->pool, aij, sizeof(IOSAIJ)); - } - dmp_free_atom(tree->pool, cut, sizeof(IOSCUT)); - pool->size--; - return; -} - -void ios_clear_pool(glp_tree *tree, IOSPOOL *pool) -{ /* remove all rows (constraints) from the cut pool */ - xassert(pool != NULL); - while (pool->head != NULL) - { IOSCUT *cut = pool->head; - pool->head = cut->next; - if (cut->name != NULL) - dmp_free_atom(tree->pool, cut->name, strlen(cut->name)+1); - while (cut->ptr != NULL) - { IOSAIJ *aij = cut->ptr; - cut->ptr = aij->next; - dmp_free_atom(tree->pool, aij, sizeof(IOSAIJ)); - } - dmp_free_atom(tree->pool, cut, sizeof(IOSCUT)); - } - pool->size = 0; - pool->head = pool->tail = NULL; - pool->ord = 0, pool->curr = NULL; - return; -} - -void ios_delete_pool(glp_tree *tree, IOSPOOL *pool) -{ /* delete cut pool */ - xassert(pool != NULL); - ios_clear_pool(tree, pool); - xfree(pool); - return; -} - -#if 1 /* 11/VII-2013 */ -#include "glpnpp.h" - -void ios_process_sol(glp_tree *T) -{ /* process integer feasible solution just found */ - if (T->npp != NULL) - { /* postprocess solution from transformed mip */ - npp_postprocess(T->npp, T->mip); - /* store solution to problem passed to glp_intopt */ - npp_unload_sol(T->npp, T->P); - } - xassert(T->P != NULL); - /* save solution to text file, if requested */ - if (T->save_sol != NULL) - { char *fn, *mark; - fn = talloc(strlen(T->save_sol) + 50, char); - mark = strrchr(T->save_sol, '*'); - if (mark == NULL) - strcpy(fn, T->save_sol); - else - { memcpy(fn, T->save_sol, mark - T->save_sol); - fn[mark - T->save_sol] = '\0'; - sprintf(fn + strlen(fn), "%03d", ++(T->save_cnt)); - strcat(fn, &mark[1]); - } - glp_write_mip(T->P, fn); - tfree(fn); - } - return; -} -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpios02.c b/resources/3rdparty/glpk-4.53/src/glpios02.c deleted file mode 100644 index 43cff57e1..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpios02.c +++ /dev/null @@ -1,826 +0,0 @@ -/* glpios02.c (preprocess current subproblem) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpios.h" - -/*********************************************************************** -* prepare_row_info - prepare row info to determine implied bounds -* -* Given a row (linear form) -* -* n -* sum a[j] * x[j] (1) -* j=1 -* -* and bounds of columns (variables) -* -* l[j] <= x[j] <= u[j] (2) -* -* this routine computes f_min, j_min, f_max, j_max needed to determine -* implied bounds. -* -* ALGORITHM -* -* Let J+ = {j : a[j] > 0} and J- = {j : a[j] < 0}. -* -* Parameters f_min and j_min are computed as follows: -* -* 1) if there is no x[k] such that k in J+ and l[k] = -inf or k in J- -* and u[k] = +inf, then -* -* f_min := sum a[j] * l[j] + sum a[j] * u[j] -* j in J+ j in J- -* (3) -* j_min := 0 -* -* 2) if there is exactly one x[k] such that k in J+ and l[k] = -inf -* or k in J- and u[k] = +inf, then -* -* f_min := sum a[j] * l[j] + sum a[j] * u[j] -* j in J+\{k} j in J-\{k} -* (4) -* j_min := k -* -* 3) if there are two or more x[k] such that k in J+ and l[k] = -inf -* or k in J- and u[k] = +inf, then -* -* f_min := -inf -* (5) -* j_min := 0 -* -* Parameters f_max and j_max are computed in a similar way as follows: -* -* 1) if there is no x[k] such that k in J+ and u[k] = +inf or k in J- -* and l[k] = -inf, then -* -* f_max := sum a[j] * u[j] + sum a[j] * l[j] -* j in J+ j in J- -* (6) -* j_max := 0 -* -* 2) if there is exactly one x[k] such that k in J+ and u[k] = +inf -* or k in J- and l[k] = -inf, then -* -* f_max := sum a[j] * u[j] + sum a[j] * l[j] -* j in J+\{k} j in J-\{k} -* (7) -* j_max := k -* -* 3) if there are two or more x[k] such that k in J+ and u[k] = +inf -* or k in J- and l[k] = -inf, then -* -* f_max := +inf -* (8) -* j_max := 0 */ - -struct f_info -{ int j_min, j_max; - double f_min, f_max; -}; - -static void prepare_row_info(int n, const double a[], const double l[], - const double u[], struct f_info *f) -{ int j, j_min, j_max; - double f_min, f_max; - xassert(n >= 0); - /* determine f_min and j_min */ - f_min = 0.0, j_min = 0; - for (j = 1; j <= n; j++) - { if (a[j] > 0.0) - { if (l[j] == -DBL_MAX) - { if (j_min == 0) - j_min = j; - else - { f_min = -DBL_MAX, j_min = 0; - break; - } - } - else - f_min += a[j] * l[j]; - } - else if (a[j] < 0.0) - { if (u[j] == +DBL_MAX) - { if (j_min == 0) - j_min = j; - else - { f_min = -DBL_MAX, j_min = 0; - break; - } - } - else - f_min += a[j] * u[j]; - } - else - xassert(a != a); - } - f->f_min = f_min, f->j_min = j_min; - /* determine f_max and j_max */ - f_max = 0.0, j_max = 0; - for (j = 1; j <= n; j++) - { if (a[j] > 0.0) - { if (u[j] == +DBL_MAX) - { if (j_max == 0) - j_max = j; - else - { f_max = +DBL_MAX, j_max = 0; - break; - } - } - else - f_max += a[j] * u[j]; - } - else if (a[j] < 0.0) - { if (l[j] == -DBL_MAX) - { if (j_max == 0) - j_max = j; - else - { f_max = +DBL_MAX, j_max = 0; - break; - } - } - else - f_max += a[j] * l[j]; - } - else - xassert(a != a); - } - f->f_max = f_max, f->j_max = j_max; - return; -} - -/*********************************************************************** -* row_implied_bounds - determine row implied bounds -* -* Given a row (linear form) -* -* n -* sum a[j] * x[j] -* j=1 -* -* and bounds of columns (variables) -* -* l[j] <= x[j] <= u[j] -* -* this routine determines implied bounds of the row. -* -* ALGORITHM -* -* Let J+ = {j : a[j] > 0} and J- = {j : a[j] < 0}. -* -* The implied lower bound of the row is computed as follows: -* -* L' := sum a[j] * l[j] + sum a[j] * u[j] (9) -* j in J+ j in J- -* -* and as it follows from (3), (4), and (5): -* -* L' := if j_min = 0 then f_min else -inf (10) -* -* The implied upper bound of the row is computed as follows: -* -* U' := sum a[j] * u[j] + sum a[j] * l[j] (11) -* j in J+ j in J- -* -* and as it follows from (6), (7), and (8): -* -* U' := if j_max = 0 then f_max else +inf (12) -* -* The implied bounds are stored in locations LL and UU. */ - -static void row_implied_bounds(const struct f_info *f, double *LL, - double *UU) -{ *LL = (f->j_min == 0 ? f->f_min : -DBL_MAX); - *UU = (f->j_max == 0 ? f->f_max : +DBL_MAX); - return; -} - -/*********************************************************************** -* col_implied_bounds - determine column implied bounds -* -* Given a row (constraint) -* -* n -* L <= sum a[j] * x[j] <= U (13) -* j=1 -* -* and bounds of columns (variables) -* -* l[j] <= x[j] <= u[j] -* -* this routine determines implied bounds of variable x[k]. -* -* It is assumed that if L != -inf, the lower bound of the row can be -* active, and if U != +inf, the upper bound of the row can be active. -* -* ALGORITHM -* -* From (13) it follows that -* -* L <= sum a[j] * x[j] + a[k] * x[k] <= U -* j!=k -* or -* -* L - sum a[j] * x[j] <= a[k] * x[k] <= U - sum a[j] * x[j] -* j!=k j!=k -* -* Thus, if the row lower bound L can be active, implied lower bound of -* term a[k] * x[k] can be determined as follows: -* -* ilb(a[k] * x[k]) = min(L - sum a[j] * x[j]) = -* j!=k -* (14) -* = L - max sum a[j] * x[j] -* j!=k -* -* where, as it follows from (6), (7), and (8) -* -* / f_max - a[k] * u[k], j_max = 0, a[k] > 0 -* | -* | f_max - a[k] * l[k], j_max = 0, a[k] < 0 -* max sum a[j] * x[j] = { -* j!=k | f_max, j_max = k -* | -* \ +inf, j_max != 0 -* -* and if the upper bound U can be active, implied upper bound of term -* a[k] * x[k] can be determined as follows: -* -* iub(a[k] * x[k]) = max(U - sum a[j] * x[j]) = -* j!=k -* (15) -* = U - min sum a[j] * x[j] -* j!=k -* -* where, as it follows from (3), (4), and (5) -* -* / f_min - a[k] * l[k], j_min = 0, a[k] > 0 -* | -* | f_min - a[k] * u[k], j_min = 0, a[k] < 0 -* min sum a[j] * x[j] = { -* j!=k | f_min, j_min = k -* | -* \ -inf, j_min != 0 -* -* Since -* -* ilb(a[k] * x[k]) <= a[k] * x[k] <= iub(a[k] * x[k]) -* -* implied lower and upper bounds of x[k] are determined as follows: -* -* l'[k] := if a[k] > 0 then ilb / a[k] else ulb / a[k] (16) -* -* u'[k] := if a[k] > 0 then ulb / a[k] else ilb / a[k] (17) -* -* The implied bounds are stored in locations ll and uu. */ - -static void col_implied_bounds(const struct f_info *f, int n, - const double a[], double L, double U, const double l[], - const double u[], int k, double *ll, double *uu) -{ double ilb, iub; - xassert(n >= 0); - xassert(1 <= k && k <= n); - /* determine implied lower bound of term a[k] * x[k] (14) */ - if (L == -DBL_MAX || f->f_max == +DBL_MAX) - ilb = -DBL_MAX; - else if (f->j_max == 0) - { if (a[k] > 0.0) - { xassert(u[k] != +DBL_MAX); - ilb = L - (f->f_max - a[k] * u[k]); - } - else if (a[k] < 0.0) - { xassert(l[k] != -DBL_MAX); - ilb = L - (f->f_max - a[k] * l[k]); - } - else - xassert(a != a); - } - else if (f->j_max == k) - ilb = L - f->f_max; - else - ilb = -DBL_MAX; - /* determine implied upper bound of term a[k] * x[k] (15) */ - if (U == +DBL_MAX || f->f_min == -DBL_MAX) - iub = +DBL_MAX; - else if (f->j_min == 0) - { if (a[k] > 0.0) - { xassert(l[k] != -DBL_MAX); - iub = U - (f->f_min - a[k] * l[k]); - } - else if (a[k] < 0.0) - { xassert(u[k] != +DBL_MAX); - iub = U - (f->f_min - a[k] * u[k]); - } - else - xassert(a != a); - } - else if (f->j_min == k) - iub = U - f->f_min; - else - iub = +DBL_MAX; - /* determine implied bounds of x[k] (16) and (17) */ -#if 1 - /* do not use a[k] if it has small magnitude to prevent wrong - implied bounds; for example, 1e-15 * x1 >= x2 + x3, where - x1 >= -10, x2, x3 >= 0, would lead to wrong conclusion that - x1 >= 0 */ - if (fabs(a[k]) < 1e-6) - *ll = -DBL_MAX, *uu = +DBL_MAX; else -#endif - if (a[k] > 0.0) - { *ll = (ilb == -DBL_MAX ? -DBL_MAX : ilb / a[k]); - *uu = (iub == +DBL_MAX ? +DBL_MAX : iub / a[k]); - } - else if (a[k] < 0.0) - { *ll = (iub == +DBL_MAX ? -DBL_MAX : iub / a[k]); - *uu = (ilb == -DBL_MAX ? +DBL_MAX : ilb / a[k]); - } - else - xassert(a != a); - return; -} - -/*********************************************************************** -* check_row_bounds - check and relax original row bounds -* -* Given a row (constraint) -* -* n -* L <= sum a[j] * x[j] <= U -* j=1 -* -* and bounds of columns (variables) -* -* l[j] <= x[j] <= u[j] -* -* this routine checks the original row bounds L and U for feasibility -* and redundancy. If the original lower bound L or/and upper bound U -* cannot be active due to bounds of variables, the routine remove them -* replacing by -inf or/and +inf, respectively. -* -* If no primal infeasibility is detected, the routine returns zero, -* otherwise non-zero. */ - -static int check_row_bounds(const struct f_info *f, double *L_, - double *U_) -{ int ret = 0; - double L = *L_, U = *U_, LL, UU; - /* determine implied bounds of the row */ - row_implied_bounds(f, &LL, &UU); - /* check if the original lower bound is infeasible */ - if (L != -DBL_MAX) - { double eps = 1e-3 * (1.0 + fabs(L)); - if (UU < L - eps) - { ret = 1; - goto done; - } - } - /* check if the original upper bound is infeasible */ - if (U != +DBL_MAX) - { double eps = 1e-3 * (1.0 + fabs(U)); - if (LL > U + eps) - { ret = 1; - goto done; - } - } - /* check if the original lower bound is redundant */ - if (L != -DBL_MAX) - { double eps = 1e-12 * (1.0 + fabs(L)); - if (LL > L - eps) - { /* it cannot be active, so remove it */ - *L_ = -DBL_MAX; - } - } - /* check if the original upper bound is redundant */ - if (U != +DBL_MAX) - { double eps = 1e-12 * (1.0 + fabs(U)); - if (UU < U + eps) - { /* it cannot be active, so remove it */ - *U_ = +DBL_MAX; - } - } -done: return ret; -} - -/*********************************************************************** -* check_col_bounds - check and tighten original column bounds -* -* Given a row (constraint) -* -* n -* L <= sum a[j] * x[j] <= U -* j=1 -* -* and bounds of columns (variables) -* -* l[j] <= x[j] <= u[j] -* -* for column (variable) x[j] this routine checks the original column -* bounds l[j] and u[j] for feasibility and redundancy. If the original -* lower bound l[j] or/and upper bound u[j] cannot be active due to -* bounds of the constraint and other variables, the routine tighten -* them replacing by corresponding implied bounds, if possible. -* -* NOTE: It is assumed that if L != -inf, the row lower bound can be -* active, and if U != +inf, the row upper bound can be active. -* -* The flag means that variable x[j] is required to be integer. -* -* New actual bounds for x[j] are stored in locations lj and uj. -* -* If no primal infeasibility is detected, the routine returns zero, -* otherwise non-zero. */ - -static int check_col_bounds(const struct f_info *f, int n, - const double a[], double L, double U, const double l[], - const double u[], int flag, int j, double *_lj, double *_uj) -{ int ret = 0; - double lj, uj, ll, uu; - xassert(n >= 0); - xassert(1 <= j && j <= n); - lj = l[j], uj = u[j]; - /* determine implied bounds of the column */ - col_implied_bounds(f, n, a, L, U, l, u, j, &ll, &uu); - /* if x[j] is integral, round its implied bounds */ - if (flag) - { if (ll != -DBL_MAX) - ll = (ll - floor(ll) < 1e-3 ? floor(ll) : ceil(ll)); - if (uu != +DBL_MAX) - uu = (ceil(uu) - uu < 1e-3 ? ceil(uu) : floor(uu)); - } - /* check if the original lower bound is infeasible */ - if (lj != -DBL_MAX) - { double eps = 1e-3 * (1.0 + fabs(lj)); - if (uu < lj - eps) - { ret = 1; - goto done; - } - } - /* check if the original upper bound is infeasible */ - if (uj != +DBL_MAX) - { double eps = 1e-3 * (1.0 + fabs(uj)); - if (ll > uj + eps) - { ret = 1; - goto done; - } - } - /* check if the original lower bound is redundant */ - if (ll != -DBL_MAX) - { double eps = 1e-3 * (1.0 + fabs(ll)); - if (lj < ll - eps) - { /* it cannot be active, so tighten it */ - lj = ll; - } - } - /* check if the original upper bound is redundant */ - if (uu != +DBL_MAX) - { double eps = 1e-3 * (1.0 + fabs(uu)); - if (uj > uu + eps) - { /* it cannot be active, so tighten it */ - uj = uu; - } - } - /* due to round-off errors it may happen that lj > uj (although - lj < uj + eps, since no primal infeasibility is detected), so - adjuct the new actual bounds to provide lj <= uj */ - if (!(lj == -DBL_MAX || uj == +DBL_MAX)) - { double t1 = fabs(lj), t2 = fabs(uj); - double eps = 1e-10 * (1.0 + (t1 <= t2 ? t1 : t2)); - if (lj > uj - eps) - { if (lj == l[j]) - uj = lj; - else if (uj == u[j]) - lj = uj; - else if (t1 <= t2) - uj = lj; - else - lj = uj; - } - } - *_lj = lj, *_uj = uj; -done: return ret; -} - -/*********************************************************************** -* check_efficiency - check if change in column bounds is efficient -* -* Given the original bounds of a column l and u and its new actual -* bounds l' and u' (possibly tighten by the routine check_col_bounds) -* this routine checks if the change in the column bounds is efficient -* enough. If so, the routine returns non-zero, otherwise zero. -* -* The flag means that the variable is required to be integer. */ - -static int check_efficiency(int flag, double l, double u, double ll, - double uu) -{ int eff = 0; - /* check efficiency for lower bound */ - if (l < ll) - { if (flag || l == -DBL_MAX) - eff++; - else - { double r; - if (u == +DBL_MAX) - r = 1.0 + fabs(l); - else - r = 1.0 + (u - l); - if (ll - l >= 0.25 * r) - eff++; - } - } - /* check efficiency for upper bound */ - if (u > uu) - { if (flag || u == +DBL_MAX) - eff++; - else - { double r; - if (l == -DBL_MAX) - r = 1.0 + fabs(u); - else - r = 1.0 + (u - l); - if (u - uu >= 0.25 * r) - eff++; - } - } - return eff; -} - -/*********************************************************************** -* basic_preprocessing - perform basic preprocessing -* -* This routine performs basic preprocessing of the specified MIP that -* includes relaxing some row bounds and tightening some column bounds. -* -* On entry the arrays L and U contains original row bounds, and the -* arrays l and u contains original column bounds: -* -* L[0] is the lower bound of the objective row; -* L[i], i = 1,...,m, is the lower bound of i-th row; -* U[0] is the upper bound of the objective row; -* U[i], i = 1,...,m, is the upper bound of i-th row; -* l[0] is not used; -* l[j], j = 1,...,n, is the lower bound of j-th column; -* u[0] is not used; -* u[j], j = 1,...,n, is the upper bound of j-th column. -* -* On exit the arrays L, U, l, and u contain new actual bounds of rows -* and column in the same locations. -* -* The parameters nrs and num specify an initial list of rows to be -* processed: -* -* nrs is the number of rows in the initial list, 0 <= nrs <= m+1; -* num[0] is not used; -* num[1,...,nrs] are row numbers (0 means the objective row). -* -* The parameter max_pass specifies the maximal number of times that -* each row can be processed, max_pass > 0. -* -* If no primal infeasibility is detected, the routine returns zero, -* otherwise non-zero. */ - -static int basic_preprocessing(glp_prob *mip, double L[], double U[], - double l[], double u[], int nrs, const int num[], int max_pass) -{ int m = mip->m; - int n = mip->n; - struct f_info f; - int i, j, k, len, size, ret = 0; - int *ind, *list, *mark, *pass; - double *val, *lb, *ub; - xassert(0 <= nrs && nrs <= m+1); - xassert(max_pass > 0); - /* allocate working arrays */ - ind = xcalloc(1+n, sizeof(int)); - list = xcalloc(1+m+1, sizeof(int)); - mark = xcalloc(1+m+1, sizeof(int)); - memset(&mark[0], 0, (m+1) * sizeof(int)); - pass = xcalloc(1+m+1, sizeof(int)); - memset(&pass[0], 0, (m+1) * sizeof(int)); - val = xcalloc(1+n, sizeof(double)); - lb = xcalloc(1+n, sizeof(double)); - ub = xcalloc(1+n, sizeof(double)); - /* initialize the list of rows to be processed */ - size = 0; - for (k = 1; k <= nrs; k++) - { i = num[k]; - xassert(0 <= i && i <= m); - /* duplicate row numbers are not allowed */ - xassert(!mark[i]); - list[++size] = i, mark[i] = 1; - } - xassert(size == nrs); - /* process rows in the list until it becomes empty */ - while (size > 0) - { /* get a next row from the list */ - i = list[size--], mark[i] = 0; - /* increase the row processing count */ - pass[i]++; - /* if the row is free, skip it */ - if (L[i] == -DBL_MAX && U[i] == +DBL_MAX) continue; - /* obtain coefficients of the row */ - len = 0; - if (i == 0) - { for (j = 1; j <= n; j++) - { GLPCOL *col = mip->col[j]; - if (col->coef != 0.0) - len++, ind[len] = j, val[len] = col->coef; - } - } - else - { GLPROW *row = mip->row[i]; - GLPAIJ *aij; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - len++, ind[len] = aij->col->j, val[len] = aij->val; - } - /* determine lower and upper bounds of columns corresponding - to non-zero row coefficients */ - for (k = 1; k <= len; k++) - j = ind[k], lb[k] = l[j], ub[k] = u[j]; - /* prepare the row info to determine implied bounds */ - prepare_row_info(len, val, lb, ub, &f); - /* check and relax bounds of the row */ - if (check_row_bounds(&f, &L[i], &U[i])) - { /* the feasible region is empty */ - ret = 1; - goto done; - } - /* if the row became free, drop it */ - if (L[i] == -DBL_MAX && U[i] == +DBL_MAX) continue; - /* process columns having non-zero coefficients in the row */ - for (k = 1; k <= len; k++) - { GLPCOL *col; - int flag, eff; - double ll, uu; - /* take a next column in the row */ - j = ind[k], col = mip->col[j]; - flag = col->kind != GLP_CV; - /* check and tighten bounds of the column */ - if (check_col_bounds(&f, len, val, L[i], U[i], lb, ub, - flag, k, &ll, &uu)) - { /* the feasible region is empty */ - ret = 1; - goto done; - } - /* check if change in the column bounds is efficient */ - eff = check_efficiency(flag, l[j], u[j], ll, uu); - /* set new actual bounds of the column */ - l[j] = ll, u[j] = uu; - /* if the change is efficient, add all rows affected by the - corresponding column, to the list */ - if (eff > 0) - { GLPAIJ *aij; - for (aij = col->ptr; aij != NULL; aij = aij->c_next) - { int ii = aij->row->i; - /* if the row was processed maximal number of times, - skip it */ - if (pass[ii] >= max_pass) continue; - /* if the row is free, skip it */ - if (L[ii] == -DBL_MAX && U[ii] == +DBL_MAX) continue; - /* put the row into the list */ - if (mark[ii] == 0) - { xassert(size <= m); - list[++size] = ii, mark[ii] = 1; - } - } - } - } - } -done: /* free working arrays */ - xfree(ind); - xfree(list); - xfree(mark); - xfree(pass); - xfree(val); - xfree(lb); - xfree(ub); - return ret; -} - -/*********************************************************************** -* NAME -* -* ios_preprocess_node - preprocess current subproblem -* -* SYNOPSIS -* -* #include "glpios.h" -* int ios_preprocess_node(glp_tree *tree, int max_pass); -* -* DESCRIPTION -* -* The routine ios_preprocess_node performs basic preprocessing of the -* current subproblem. -* -* RETURNS -* -* If no primal infeasibility is detected, the routine returns zero, -* otherwise non-zero. */ - -int ios_preprocess_node(glp_tree *tree, int max_pass) -{ glp_prob *mip = tree->mip; - int m = mip->m; - int n = mip->n; - int i, j, nrs, *num, ret = 0; - double *L, *U, *l, *u; - /* the current subproblem must exist */ - xassert(tree->curr != NULL); - /* determine original row bounds */ - L = xcalloc(1+m, sizeof(double)); - U = xcalloc(1+m, sizeof(double)); - switch (mip->mip_stat) - { case GLP_UNDEF: - L[0] = -DBL_MAX, U[0] = +DBL_MAX; - break; - case GLP_FEAS: - switch (mip->dir) - { case GLP_MIN: - L[0] = -DBL_MAX, U[0] = mip->mip_obj - mip->c0; - break; - case GLP_MAX: - L[0] = mip->mip_obj - mip->c0, U[0] = +DBL_MAX; - break; - default: - xassert(mip != mip); - } - break; - default: - xassert(mip != mip); - } - for (i = 1; i <= m; i++) - { L[i] = glp_get_row_lb(mip, i); - U[i] = glp_get_row_ub(mip, i); - } - /* determine original column bounds */ - l = xcalloc(1+n, sizeof(double)); - u = xcalloc(1+n, sizeof(double)); - for (j = 1; j <= n; j++) - { l[j] = glp_get_col_lb(mip, j); - u[j] = glp_get_col_ub(mip, j); - } - /* build the initial list of rows to be analyzed */ - nrs = m + 1; - num = xcalloc(1+nrs, sizeof(int)); - for (i = 1; i <= nrs; i++) num[i] = i - 1; - /* perform basic preprocessing */ - if (basic_preprocessing(mip , L, U, l, u, nrs, num, max_pass)) - { ret = 1; - goto done; - } - /* set new actual (relaxed) row bounds */ - for (i = 1; i <= m; i++) - { /* consider only non-active rows to keep dual feasibility */ - if (glp_get_row_stat(mip, i) == GLP_BS) - { if (L[i] == -DBL_MAX && U[i] == +DBL_MAX) - glp_set_row_bnds(mip, i, GLP_FR, 0.0, 0.0); - else if (U[i] == +DBL_MAX) - glp_set_row_bnds(mip, i, GLP_LO, L[i], 0.0); - else if (L[i] == -DBL_MAX) - glp_set_row_bnds(mip, i, GLP_UP, 0.0, U[i]); - } - } - /* set new actual (tightened) column bounds */ - for (j = 1; j <= n; j++) - { int type; - if (l[j] == -DBL_MAX && u[j] == +DBL_MAX) - type = GLP_FR; - else if (u[j] == +DBL_MAX) - type = GLP_LO; - else if (l[j] == -DBL_MAX) - type = GLP_UP; - else if (l[j] != u[j]) - type = GLP_DB; - else - type = GLP_FX; - glp_set_col_bnds(mip, j, type, l[j], u[j]); - } -done: /* free working arrays and return */ - xfree(L); - xfree(U); - xfree(l); - xfree(u); - xfree(num); - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpios03.c b/resources/3rdparty/glpk-4.53/src/glpios03.c deleted file mode 100644 index 3ee79ee04..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpios03.c +++ /dev/null @@ -1,1438 +0,0 @@ -/* glpios03.c (branch-and-cut driver) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpios.h" - -/*********************************************************************** -* show_progress - display current progress of the search -* -* This routine displays some information about current progress of the -* search. -* -* The information includes: -* -* the current number of iterations performed by the simplex solver; -* -* the objective value for the best known integer feasible solution, -* which is upper (minimization) or lower (maximization) global bound -* for optimal solution of the original mip problem; -* -* the best local bound for active nodes, which is lower (minimization) -* or upper (maximization) global bound for optimal solution of the -* original mip problem; -* -* the relative mip gap, in percents; -* -* the number of open (active) subproblems; -* -* the number of completely explored subproblems, i.e. whose nodes have -* been removed from the tree. */ - -static void show_progress(glp_tree *T, int bingo) -{ int p; - double temp; - char best_mip[50], best_bound[50], *rho, rel_gap[50]; - /* format the best known integer feasible solution */ - if (T->mip->mip_stat == GLP_FEAS) - sprintf(best_mip, "%17.9e", T->mip->mip_obj); - else - sprintf(best_mip, "%17s", "not found yet"); - /* determine reference number of an active subproblem whose local - bound is best */ - p = ios_best_node(T); - /* format the best bound */ - if (p == 0) - sprintf(best_bound, "%17s", "tree is empty"); - else - { temp = T->slot[p].node->bound; - if (temp == -DBL_MAX) - sprintf(best_bound, "%17s", "-inf"); - else if (temp == +DBL_MAX) - sprintf(best_bound, "%17s", "+inf"); - else - sprintf(best_bound, "%17.9e", temp); - } - /* choose the relation sign between global bounds */ - if (T->mip->dir == GLP_MIN) - rho = ">="; - else if (T->mip->dir == GLP_MAX) - rho = "<="; - else - xassert(T != T); - /* format the relative mip gap */ - temp = ios_relative_gap(T); - if (temp == 0.0) - sprintf(rel_gap, " 0.0%%"); - else if (temp < 0.001) - sprintf(rel_gap, "< 0.1%%"); - else if (temp <= 9.999) - sprintf(rel_gap, "%5.1f%%", 100.0 * temp); - else - sprintf(rel_gap, "%6s", ""); - /* display progress of the search */ - xprintf("+%6d: %s %s %s %s %s (%d; %d)\n", - T->mip->it_cnt, bingo ? ">>>>>" : "mip =", best_mip, rho, - best_bound, rel_gap, T->a_cnt, T->t_cnt - T->n_cnt); - T->tm_lag = xtime(); - return; -} - -/*********************************************************************** -* is_branch_hopeful - check if specified branch is hopeful -* -* This routine checks if the specified subproblem can have an integer -* optimal solution which is better than the best known one. -* -* The check is based on comparison of the local objective bound stored -* in the subproblem descriptor and the incumbent objective value which -* is the global objective bound. -* -* If there is a chance that the specified subproblem can have a better -* integer optimal solution, the routine returns non-zero. Otherwise, if -* the corresponding branch can pruned, zero is returned. */ - -static int is_branch_hopeful(glp_tree *T, int p) -{ xassert(1 <= p && p <= T->nslots); - xassert(T->slot[p].node != NULL); - return ios_is_hopeful(T, T->slot[p].node->bound); -} - -/*********************************************************************** -* check_integrality - check integrality of basic solution -* -* This routine checks if the basic solution of LP relaxation of the -* current subproblem satisfies to integrality conditions, i.e. that all -* variables of integer kind have integral primal values. (The solution -* is assumed to be optimal.) -* -* For each variable of integer kind the routine computes the following -* quantity: -* -* ii(x[j]) = min(x[j] - floor(x[j]), ceil(x[j]) - x[j]), (1) -* -* which is a measure of the integer infeasibility (non-integrality) of -* x[j] (for example, ii(2.1) = 0.1, ii(3.7) = 0.3, ii(5.0) = 0). It is -* understood that 0 <= ii(x[j]) <= 0.5, and variable x[j] is integer -* feasible if ii(x[j]) = 0. However, due to floating-point arithmetic -* the routine checks less restrictive condition: -* -* ii(x[j]) <= tol_int, (2) -* -* where tol_int is a given tolerance (small positive number) and marks -* each variable which does not satisfy to (2) as integer infeasible by -* setting its fractionality flag. -* -* In order to characterize integer infeasibility of the basic solution -* in the whole the routine computes two parameters: ii_cnt, which is -* the number of variables with the fractionality flag set, and ii_sum, -* which is the sum of integer infeasibilities (1). */ - -static void check_integrality(glp_tree *T) -{ glp_prob *mip = T->mip; - int j, type, ii_cnt = 0; - double lb, ub, x, temp1, temp2, ii_sum = 0.0; - /* walk through the set of columns (structural variables) */ - for (j = 1; j <= mip->n; j++) - { GLPCOL *col = mip->col[j]; - T->non_int[j] = 0; - /* if the column is not integer, skip it */ - if (col->kind != GLP_IV) continue; - /* if the column is non-basic, it is integer feasible */ - if (col->stat != GLP_BS) continue; - /* obtain the type and bounds of the column */ - type = col->type, lb = col->lb, ub = col->ub; - /* obtain value of the column in optimal basic solution */ - x = col->prim; - /* if the column's primal value is close to the lower bound, - the column is integer feasible within given tolerance */ - if (type == GLP_LO || type == GLP_DB || type == GLP_FX) - { temp1 = lb - T->parm->tol_int; - temp2 = lb + T->parm->tol_int; - if (temp1 <= x && x <= temp2) continue; -#if 0 - /* the lower bound must not be violated */ - xassert(x >= lb); -#else - if (x < lb) continue; -#endif - } - /* if the column's primal value is close to the upper bound, - the column is integer feasible within given tolerance */ - if (type == GLP_UP || type == GLP_DB || type == GLP_FX) - { temp1 = ub - T->parm->tol_int; - temp2 = ub + T->parm->tol_int; - if (temp1 <= x && x <= temp2) continue; -#if 0 - /* the upper bound must not be violated */ - xassert(x <= ub); -#else - if (x > ub) continue; -#endif - } - /* if the column's primal value is close to nearest integer, - the column is integer feasible within given tolerance */ - temp1 = floor(x + 0.5) - T->parm->tol_int; - temp2 = floor(x + 0.5) + T->parm->tol_int; - if (temp1 <= x && x <= temp2) continue; - /* otherwise the column is integer infeasible */ - T->non_int[j] = 1; - /* increase the number of fractional-valued columns */ - ii_cnt++; - /* compute the sum of integer infeasibilities */ - temp1 = x - floor(x); - temp2 = ceil(x) - x; - xassert(temp1 > 0.0 && temp2 > 0.0); - ii_sum += (temp1 <= temp2 ? temp1 : temp2); - } - /* store ii_cnt and ii_sum to the current problem descriptor */ - xassert(T->curr != NULL); - T->curr->ii_cnt = ii_cnt; - T->curr->ii_sum = ii_sum; - /* and also display these parameters */ - if (T->parm->msg_lev >= GLP_MSG_DBG) - { if (ii_cnt == 0) - xprintf("There are no fractional columns\n"); - else if (ii_cnt == 1) - xprintf("There is one fractional column, integer infeasibil" - "ity is %.3e\n", ii_sum); - else - xprintf("There are %d fractional columns, integer infeasibi" - "lity is %.3e\n", ii_cnt, ii_sum); - } - return; -} - -/*********************************************************************** -* record_solution - record better integer feasible solution -* -* This routine records optimal basic solution of LP relaxation of the -* current subproblem, which being integer feasible is better than the -* best known integer feasible solution. */ - -static void record_solution(glp_tree *T) -{ glp_prob *mip = T->mip; - int i, j; - mip->mip_stat = GLP_FEAS; - mip->mip_obj = mip->obj_val; - for (i = 1; i <= mip->m; i++) - { GLPROW *row = mip->row[i]; - row->mipx = row->prim; - } - for (j = 1; j <= mip->n; j++) - { GLPCOL *col = mip->col[j]; - if (col->kind == GLP_CV) - col->mipx = col->prim; - else if (col->kind == GLP_IV) - { /* value of the integer column must be integral */ - col->mipx = floor(col->prim + 0.5); - } - else - xassert(col != col); - } - T->sol_cnt++; - return; -} - -/*********************************************************************** -* fix_by_red_cost - fix non-basic integer columns by reduced costs -* -* This routine fixes some non-basic integer columns if their reduced -* costs indicate that increasing (decreasing) the column at least by -* one involves the objective value becoming worse than the incumbent -* objective value. */ - -static void fix_by_red_cost(glp_tree *T) -{ glp_prob *mip = T->mip; - int j, stat, fixed = 0; - double obj, lb, ub, dj; - /* the global bound must exist */ - xassert(T->mip->mip_stat == GLP_FEAS); - /* basic solution of LP relaxation must be optimal */ - xassert(mip->pbs_stat == GLP_FEAS && mip->dbs_stat == GLP_FEAS); - /* determine the objective function value */ - obj = mip->obj_val; - /* walk through the column list */ - for (j = 1; j <= mip->n; j++) - { GLPCOL *col = mip->col[j]; - /* if the column is not integer, skip it */ - if (col->kind != GLP_IV) continue; - /* obtain bounds of j-th column */ - lb = col->lb, ub = col->ub; - /* and determine its status and reduced cost */ - stat = col->stat, dj = col->dual; - /* analyze the reduced cost */ - switch (mip->dir) - { case GLP_MIN: - /* minimization */ - if (stat == GLP_NL) - { /* j-th column is non-basic on its lower bound */ - if (dj < 0.0) dj = 0.0; - if (obj + dj >= mip->mip_obj) - glp_set_col_bnds(mip, j, GLP_FX, lb, lb), fixed++; - } - else if (stat == GLP_NU) - { /* j-th column is non-basic on its upper bound */ - if (dj > 0.0) dj = 0.0; - if (obj - dj >= mip->mip_obj) - glp_set_col_bnds(mip, j, GLP_FX, ub, ub), fixed++; - } - break; - case GLP_MAX: - /* maximization */ - if (stat == GLP_NL) - { /* j-th column is non-basic on its lower bound */ - if (dj > 0.0) dj = 0.0; - if (obj + dj <= mip->mip_obj) - glp_set_col_bnds(mip, j, GLP_FX, lb, lb), fixed++; - } - else if (stat == GLP_NU) - { /* j-th column is non-basic on its upper bound */ - if (dj < 0.0) dj = 0.0; - if (obj - dj <= mip->mip_obj) - glp_set_col_bnds(mip, j, GLP_FX, ub, ub), fixed++; - } - break; - default: - xassert(T != T); - } - } - if (T->parm->msg_lev >= GLP_MSG_DBG) - { if (fixed == 0) - /* nothing to say */; - else if (fixed == 1) - xprintf("One column has been fixed by reduced cost\n"); - else - xprintf("%d columns have been fixed by reduced costs\n", - fixed); - } - /* fixing non-basic columns on their current bounds does not - change the basic solution */ - xassert(mip->pbs_stat == GLP_FEAS && mip->dbs_stat == GLP_FEAS); - return; -} - -/*********************************************************************** -* branch_on - perform branching on specified variable -* -* This routine performs branching on j-th column (structural variable) -* of the current subproblem. The specified column must be of integer -* kind and must have a fractional value in optimal basic solution of -* LP relaxation of the current subproblem (i.e. only columns for which -* the flag non_int[j] is set are valid candidates to branch on). -* -* Let x be j-th structural variable, and beta be its primal fractional -* value in the current basic solution. Branching on j-th variable is -* dividing the current subproblem into two new subproblems, which are -* identical to the current subproblem with the following exception: in -* the first subproblem that begins the down-branch x has a new upper -* bound x <= floor(beta), and in the second subproblem that begins the -* up-branch x has a new lower bound x >= ceil(beta). -* -* Depending on estimation of local bounds for down- and up-branches -* this routine returns the following: -* -* 0 - both branches have been created; -* 1 - one branch is hopeless and has been pruned, so now the current -* subproblem is other branch; -* 2 - both branches are hopeless and have been pruned; new subproblem -* selection is needed to continue the search. */ - -static int branch_on(glp_tree *T, int j, int next) -{ glp_prob *mip = T->mip; - IOSNPD *node; - int m = mip->m; - int n = mip->n; - int type, dn_type, up_type, dn_bad, up_bad, p, ret, clone[1+2]; - double lb, ub, beta, new_ub, new_lb, dn_lp, up_lp, dn_bnd, up_bnd; - /* determine bounds and value of x[j] in optimal solution to LP - relaxation of the current subproblem */ - xassert(1 <= j && j <= n); - type = mip->col[j]->type; - lb = mip->col[j]->lb; - ub = mip->col[j]->ub; - beta = mip->col[j]->prim; - /* determine new bounds of x[j] for down- and up-branches */ - new_ub = floor(beta); - new_lb = ceil(beta); - switch (type) - { case GLP_FR: - dn_type = GLP_UP; - up_type = GLP_LO; - break; - case GLP_LO: - xassert(lb <= new_ub); - dn_type = (lb == new_ub ? GLP_FX : GLP_DB); - xassert(lb + 1.0 <= new_lb); - up_type = GLP_LO; - break; - case GLP_UP: - xassert(new_ub <= ub - 1.0); - dn_type = GLP_UP; - xassert(new_lb <= ub); - up_type = (new_lb == ub ? GLP_FX : GLP_DB); - break; - case GLP_DB: - xassert(lb <= new_ub && new_ub <= ub - 1.0); - dn_type = (lb == new_ub ? GLP_FX : GLP_DB); - xassert(lb + 1.0 <= new_lb && new_lb <= ub); - up_type = (new_lb == ub ? GLP_FX : GLP_DB); - break; - default: - xassert(type != type); - } - /* compute local bounds to LP relaxation for both branches */ - ios_eval_degrad(T, j, &dn_lp, &up_lp); - /* and improve them by rounding */ - dn_bnd = ios_round_bound(T, dn_lp); - up_bnd = ios_round_bound(T, up_lp); - /* check local bounds for down- and up-branches */ - dn_bad = !ios_is_hopeful(T, dn_bnd); - up_bad = !ios_is_hopeful(T, up_bnd); - if (dn_bad && up_bad) - { if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Both down- and up-branches are hopeless\n"); - ret = 2; - goto done; - } - else if (up_bad) - { if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Up-branch is hopeless\n"); - glp_set_col_bnds(mip, j, dn_type, lb, new_ub); - T->curr->lp_obj = dn_lp; - if (mip->dir == GLP_MIN) - { if (T->curr->bound < dn_bnd) - T->curr->bound = dn_bnd; - } - else if (mip->dir == GLP_MAX) - { if (T->curr->bound > dn_bnd) - T->curr->bound = dn_bnd; - } - else - xassert(mip != mip); - ret = 1; - goto done; - } - else if (dn_bad) - { if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Down-branch is hopeless\n"); - glp_set_col_bnds(mip, j, up_type, new_lb, ub); - T->curr->lp_obj = up_lp; - if (mip->dir == GLP_MIN) - { if (T->curr->bound < up_bnd) - T->curr->bound = up_bnd; - } - else if (mip->dir == GLP_MAX) - { if (T->curr->bound > up_bnd) - T->curr->bound = up_bnd; - } - else - xassert(mip != mip); - ret = 1; - goto done; - } - /* both down- and up-branches seem to be hopeful */ - if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Branching on column %d, primal value is %.9e\n", - j, beta); - /* determine the reference number of the current subproblem */ - xassert(T->curr != NULL); - p = T->curr->p; - T->curr->br_var = j; - T->curr->br_val = beta; - /* freeze the current subproblem */ - ios_freeze_node(T); - /* create two clones of the current subproblem; the first clone - begins the down-branch, the second one begins the up-branch */ - ios_clone_node(T, p, 2, clone); - if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Node %d begins down branch, node %d begins up branch " - "\n", clone[1], clone[2]); - /* set new upper bound of j-th column in the down-branch */ - node = T->slot[clone[1]].node; - xassert(node != NULL); - xassert(node->up != NULL); - xassert(node->b_ptr == NULL); - node->b_ptr = dmp_get_atom(T->pool, sizeof(IOSBND)); - node->b_ptr->k = m + j; - node->b_ptr->type = (unsigned char)dn_type; - node->b_ptr->lb = lb; - node->b_ptr->ub = new_ub; - node->b_ptr->next = NULL; - node->lp_obj = dn_lp; - if (mip->dir == GLP_MIN) - { if (node->bound < dn_bnd) - node->bound = dn_bnd; - } - else if (mip->dir == GLP_MAX) - { if (node->bound > dn_bnd) - node->bound = dn_bnd; - } - else - xassert(mip != mip); - /* set new lower bound of j-th column in the up-branch */ - node = T->slot[clone[2]].node; - xassert(node != NULL); - xassert(node->up != NULL); - xassert(node->b_ptr == NULL); - node->b_ptr = dmp_get_atom(T->pool, sizeof(IOSBND)); - node->b_ptr->k = m + j; - node->b_ptr->type = (unsigned char)up_type; - node->b_ptr->lb = new_lb; - node->b_ptr->ub = ub; - node->b_ptr->next = NULL; - node->lp_obj = up_lp; - if (mip->dir == GLP_MIN) - { if (node->bound < up_bnd) - node->bound = up_bnd; - } - else if (mip->dir == GLP_MAX) - { if (node->bound > up_bnd) - node->bound = up_bnd; - } - else - xassert(mip != mip); - /* suggest the subproblem to be solved next */ - xassert(T->child == 0); - if (next == GLP_NO_BRNCH) - T->child = 0; - else if (next == GLP_DN_BRNCH) - T->child = clone[1]; - else if (next == GLP_UP_BRNCH) - T->child = clone[2]; - else - xassert(next != next); - ret = 0; -done: return ret; -} - -/*********************************************************************** -* cleanup_the_tree - prune hopeless branches from the tree -* -* This routine walks through the active list and checks the local -* bound for every active subproblem. If the local bound indicates that -* the subproblem cannot have integer optimal solution better than the -* incumbent objective value, the routine deletes such subproblem that, -* in turn, involves pruning the corresponding branch of the tree. */ - -static void cleanup_the_tree(glp_tree *T) -{ IOSNPD *node, *next_node; - int count = 0; - /* the global bound must exist */ - xassert(T->mip->mip_stat == GLP_FEAS); - /* walk through the list of active subproblems */ - for (node = T->head; node != NULL; node = next_node) - { /* deleting some active problem node may involve deleting its - parents recursively; however, all its parents being created - *before* it are always *precede* it in the node list, so - the next problem node is never affected by such deletion */ - next_node = node->next; - /* if the branch is hopeless, prune it */ - if (!is_branch_hopeful(T, node->p)) - ios_delete_node(T, node->p), count++; - } - if (T->parm->msg_lev >= GLP_MSG_DBG) - { if (count == 1) - xprintf("One hopeless branch has been pruned\n"); - else if (count > 1) - xprintf("%d hopeless branches have been pruned\n", count); - } - return; -} - -#if 0 /* 09/VII-2013 */ -/*********************************************************************** -* round_heur - simple rounding heuristic -* -* This routine attempts to guess an integer feasible solution by -* simple rounding values of all integer variables in basic solution to -* nearest integers. */ - -static int round_heur(glp_tree *T) -{ glp_prob *P = T->mip; - int m = P->m; - int n = P->n; - int i, j, ret; - double *x; - /* compute rounded values of variables */ - x = talloc(1+n, double); - for (j = 1; j <= n; j++) - { GLPCOL *col = P->col[j]; - if (col->kind == GLP_IV) - { /* integer variable */ - x[j] = floor(col->prim + 0.5); - } - else if (col->type == GLP_FX) - { /* fixed variable */ - x[j] = col->prim; - } - else - { /* non-integer non-fixed variable */ - ret = 3; - goto done; - } - } - /* check that no constraints are violated */ - for (i = 1; i <= m; i++) - { GLPROW *row = P->row[i]; - int type = row->type; - GLPAIJ *aij; - double sum; - if (type == GLP_FR) - continue; - /* compute value of linear form */ - sum = 0.0; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - sum += aij->val * x[aij->col->j]; - /* check lower bound */ - if (type == GLP_LO || type == GLP_DB || type == GLP_FX) - { if (sum < row->lb - 1e-9) - { /* lower bound is violated */ - ret = 2; - goto done; - } - } - /* check upper bound */ - if (type == GLP_UP || type == GLP_DB || type == GLP_FX) - { if (sum > row->ub + 1e-9) - { /* upper bound is violated */ - ret = 2; - goto done; - } - } - } - /* rounded solution is integer feasible */ - if (glp_ios_heur_sol(T, x) == 0) - { /* solution is accepted */ - ret = 0; - } - else - { /* solution is rejected */ - ret = 1; - } -done: tfree(x); - return ret; -} -#else -/*********************************************************************** -* round_heur - simple rounding heuristic -* -* This routine attempts to guess an integer feasible solution by -* simple rounding values of all integer variables in basic solution to -* nearest integers. */ - -static int round_heur(glp_tree *T) -{ glp_prob *P = T->mip; - /*int m = P->m;*/ - int n = P->n; - int i, j, ret; - double *x; - /* compute rounded values of variables */ - x = talloc(1+n, double); - for (j = 1; j <= n; j++) - { GLPCOL *col = P->col[j]; - if (col->kind == GLP_IV) - { /* integer variable */ - x[j] = floor(col->prim + 0.5); - } - else if (col->type == GLP_FX) - { /* fixed variable */ - x[j] = col->prim; - } - else - { /* non-integer non-fixed variable */ - ret = 3; - goto done; - } - } - /* check that no constraints are violated */ - for (i = 1; i <= T->orig_m; i++) - { int type = T->orig_type[i]; - GLPAIJ *aij; - double sum; - if (type == GLP_FR) - continue; - /* compute value of linear form */ - sum = 0.0; - for (aij = P->row[i]->ptr; aij != NULL; aij = aij->r_next) - sum += aij->val * x[aij->col->j]; - /* check lower bound */ - if (type == GLP_LO || type == GLP_DB || type == GLP_FX) - { if (sum < T->orig_lb[i] - 1e-9) - { /* lower bound is violated */ - ret = 2; - goto done; - } - } - /* check upper bound */ - if (type == GLP_UP || type == GLP_DB || type == GLP_FX) - { if (sum > T->orig_ub[i] + 1e-9) - { /* upper bound is violated */ - ret = 2; - goto done; - } - } - } - /* rounded solution is integer feasible */ - if (glp_ios_heur_sol(T, x) == 0) - { /* solution is accepted */ - ret = 0; - } - else - { /* solution is rejected */ - ret = 1; - } -done: tfree(x); - return ret; -} -#endif - -#if 0 -#define round_heur round_heur2 -static int round_heur(glp_tree *T) -{ glp_prob *lp; - int *ind, ret, i, j, len; - double *val; - lp = glp_create_prob(); - ind = talloc(1+T->mip->n, int); - val = talloc(1+T->mip->n, double); - glp_add_rows(lp, T->orig_m); - glp_add_cols(lp, T->n); - for (i = 1; i <= T->orig_m; i++) - { glp_set_row_bnds(lp, i, - T->orig_type[i], T->orig_lb[i], T->orig_ub[i]); - len = glp_get_mat_row(T->mip, i, ind, val); - glp_set_mat_row(lp, i, len, ind, val); - } - for (j = 1; j <= T->n; j++) - { GLPCOL *col = T->mip->col[j]; - glp_set_obj_coef(lp, j, col->coef); - if (col->kind == GLP_IV) - { /* integer variable */ - glp_set_col_bnds(lp, j, GLP_FX, floor(col->prim + .5), 0); - } - else - { glp_set_col_bnds(lp, j, T->orig_type[T->orig_m+j], - T->orig_lb[T->orig_m+j], T->orig_ub[T->orig_m+j]); - } - } -glp_term_out(GLP_OFF); - glp_adv_basis(lp, 0); - ret = glp_simplex(lp, NULL); -glp_term_out(GLP_ON); - if (ret != 0) - { ret = 1; - goto done; - } - if (glp_get_status(lp) != GLP_OPT) - { ret = 2; - goto done; - } - for (j = 1; j <= lp->n; j++) - val[j] = lp->col[j]->prim; - if (glp_ios_heur_sol(T, val) == 0) - ret = 0; - else - ret = 3; -done: glp_delete_prob(lp); - tfree(ind); - tfree(val); - return ret; -} -#endif - -/**********************************************************************/ - -static void generate_cuts(glp_tree *T) -{ /* generate generic cuts with built-in generators */ - if (!(T->parm->mir_cuts == GLP_ON || - T->parm->gmi_cuts == GLP_ON || - T->parm->cov_cuts == GLP_ON || - T->parm->clq_cuts == GLP_ON)) goto done; -#if 1 /* 20/IX-2008 */ - { int i, max_cuts, added_cuts; - max_cuts = T->n; - if (max_cuts < 1000) max_cuts = 1000; - added_cuts = 0; - for (i = T->orig_m+1; i <= T->mip->m; i++) - { if (T->mip->row[i]->origin == GLP_RF_CUT) - added_cuts++; - } - /* xprintf("added_cuts = %d\n", added_cuts); */ - if (added_cuts >= max_cuts) goto done; - } -#endif - /* generate and add to POOL all cuts violated by x* */ - if (T->parm->gmi_cuts == GLP_ON) - { if (T->curr->changed < 7) - ios_gmi_gen(T); - } - if (T->parm->mir_cuts == GLP_ON) - { xassert(T->mir_gen != NULL); - ios_mir_gen(T, T->mir_gen); - } - if (T->parm->cov_cuts == GLP_ON) - { /* cover cuts works well along with mir cuts */ - /*if (T->round <= 5)*/ - ios_cov_gen(T); - } - if (T->parm->clq_cuts == GLP_ON) - { if (T->clq_gen != NULL) -#if 0 /* 29/VI-2013 */ - { if (T->curr->level == 0 && T->curr->changed < 50 || - T->curr->level > 0 && T->curr->changed < 5) -#else /* FIXME */ - { if (T->curr->level == 0 && T->curr->changed < 500 || - T->curr->level > 0 && T->curr->changed < 50) -#endif - ios_clq_gen(T, T->clq_gen); - } - } -done: return; -} - -/**********************************************************************/ - -static void remove_cuts(glp_tree *T) -{ /* remove inactive cuts (some valueable globally valid cut might - be saved in the global cut pool) */ - int i, cnt = 0, *num = NULL; - xassert(T->curr != NULL); - for (i = T->orig_m+1; i <= T->mip->m; i++) - { if (T->mip->row[i]->origin == GLP_RF_CUT && - T->mip->row[i]->level == T->curr->level && - T->mip->row[i]->stat == GLP_BS) - { if (num == NULL) - num = xcalloc(1+T->mip->m, sizeof(int)); - num[++cnt] = i; - } - } - if (cnt > 0) - { glp_del_rows(T->mip, cnt, num); -#if 0 - xprintf("%d inactive cut(s) removed\n", cnt); -#endif - xfree(num); - xassert(glp_factorize(T->mip) == 0); - } - return; -} - -/**********************************************************************/ - -static void display_cut_info(glp_tree *T) -{ glp_prob *mip = T->mip; - int i, gmi = 0, mir = 0, cov = 0, clq = 0, app = 0; - for (i = mip->m; i > 0; i--) - { GLPROW *row; - row = mip->row[i]; - /* if (row->level < T->curr->level) break; */ - if (row->origin == GLP_RF_CUT) - { if (row->klass == GLP_RF_GMI) - gmi++; - else if (row->klass == GLP_RF_MIR) - mir++; - else if (row->klass == GLP_RF_COV) - cov++; - else if (row->klass == GLP_RF_CLQ) - clq++; - else - app++; - } - } - xassert(T->curr != NULL); - if (gmi + mir + cov + clq + app > 0) - { xprintf("Cuts on level %d:", T->curr->level); - if (gmi > 0) xprintf(" gmi = %d;", gmi); - if (mir > 0) xprintf(" mir = %d;", mir); - if (cov > 0) xprintf(" cov = %d;", cov); - if (clq > 0) xprintf(" clq = %d;", clq); - if (app > 0) xprintf(" app = %d;", app); - xprintf("\n"); - } - return; -} - -/*********************************************************************** -* NAME -* -* ios_driver - branch-and-cut driver -* -* SYNOPSIS -* -* #include "glpios.h" -* int ios_driver(glp_tree *T); -* -* DESCRIPTION -* -* The routine ios_driver is a branch-and-cut driver. It controls the -* MIP solution process. -* -* RETURNS -* -* 0 The MIP problem instance has been successfully solved. This code -* does not necessarily mean that the solver has found optimal -* solution. It only means that the solution process was successful. -* -* GLP_EFAIL -* The search was prematurely terminated due to the solver failure. -* -* GLP_EMIPGAP -* The search was prematurely terminated, because the relative mip -* gap tolerance has been reached. -* -* GLP_ETMLIM -* The search was prematurely terminated, because the time limit has -* been exceeded. -* -* GLP_ESTOP -* The search was prematurely terminated by application. */ - -int ios_driver(glp_tree *T) -{ int p, curr_p, p_stat, d_stat, ret; -#if 1 /* carry out to glp_tree */ - int pred_p = 0; - /* if the current subproblem has been just created due to - branching, pred_p is the reference number of its parent - subproblem, otherwise pred_p is zero */ -#endif -#if 1 /* 18/VII-2013 */ - int bad_cut; - double old_obj; -#endif -#if 0 /* 10/VI-2013 */ - glp_long ttt = T->tm_beg; -#else - double ttt = T->tm_beg; -#endif -#if 0 - ((glp_iocp *)T->parm)->msg_lev = GLP_MSG_DBG; -#endif - /* on entry to the B&B driver it is assumed that the active list - contains the only active (i.e. root) subproblem, which is the - original MIP problem to be solved */ -loop: /* main loop starts here */ - /* at this point the current subproblem does not exist */ - xassert(T->curr == NULL); - /* if the active list is empty, the search is finished */ - if (T->head == NULL) - { if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Active list is empty!\n"); -#if 0 /* 10/VI-2013 */ - xassert(dmp_in_use(T->pool).lo == 0); -#else - xassert(dmp_in_use(T->pool) == 0); -#endif - ret = 0; - goto done; - } - /* select some active subproblem to continue the search */ - xassert(T->next_p == 0); - /* let the application program select subproblem */ - if (T->parm->cb_func != NULL) - { xassert(T->reason == 0); - T->reason = GLP_ISELECT; - T->parm->cb_func(T, T->parm->cb_info); - T->reason = 0; - if (T->stop) - { ret = GLP_ESTOP; - goto done; - } - } - if (T->next_p != 0) - { /* the application program has selected something */ - ; - } - else if (T->a_cnt == 1) - { /* the only active subproblem exists, so select it */ - xassert(T->head->next == NULL); - T->next_p = T->head->p; - } - else if (T->child != 0) - { /* select one of branching childs suggested by the branching - heuristic */ - T->next_p = T->child; - } - else - { /* select active subproblem as specified by the backtracking - technique option */ - T->next_p = ios_choose_node(T); - } - /* the active subproblem just selected becomes current */ - ios_revive_node(T, T->next_p); - T->next_p = T->child = 0; - /* invalidate pred_p, if it is not the reference number of the - parent of the current subproblem */ - if (T->curr->up != NULL && T->curr->up->p != pred_p) pred_p = 0; - /* determine the reference number of the current subproblem */ - p = T->curr->p; - if (T->parm->msg_lev >= GLP_MSG_DBG) - { xprintf("-----------------------------------------------------" - "-------------------\n"); - xprintf("Processing node %d at level %d\n", p, T->curr->level); - } -#if 0 - if (p == 1) - glp_write_lp(T->mip, NULL, "root.lp"); -#endif - /* if it is the root subproblem, initialize cut generators */ - if (p == 1) - { if (T->parm->gmi_cuts == GLP_ON) - { if (T->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Gomory's cuts enabled\n"); - } - if (T->parm->mir_cuts == GLP_ON) - { if (T->parm->msg_lev >= GLP_MSG_ALL) - xprintf("MIR cuts enabled\n"); - xassert(T->mir_gen == NULL); - T->mir_gen = ios_mir_init(T); - } - if (T->parm->cov_cuts == GLP_ON) - { if (T->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Cover cuts enabled\n"); - } - if (T->parm->clq_cuts == GLP_ON) - { xassert(T->clq_gen == NULL); - if (T->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Clique cuts enabled\n"); - T->clq_gen = ios_clq_init(T); - } - } -#if 1 /* 18/VII-2013 */ - bad_cut = 0; -#endif -more: /* minor loop starts here */ - /* at this point the current subproblem needs either to be solved - for the first time or re-optimized due to reformulation */ - /* display current progress of the search */ - if (T->parm->msg_lev >= GLP_MSG_DBG || - T->parm->msg_lev >= GLP_MSG_ON && - (double)(T->parm->out_frq - 1) <= - 1000.0 * xdifftime(xtime(), T->tm_lag)) - show_progress(T, 0); - if (T->parm->msg_lev >= GLP_MSG_ALL && - xdifftime(xtime(), ttt) >= 60.0) -#if 0 /* 16/II-2012 */ - { glp_long total; - glp_mem_usage(NULL, NULL, &total, NULL); - xprintf("Time used: %.1f secs. Memory used: %.1f Mb.\n", - xdifftime(xtime(), T->tm_beg), xltod(total) / 1048576.0); - ttt = xtime(); - } -#else - { size_t total; - glp_mem_usage(NULL, NULL, &total, NULL); - xprintf("Time used: %.1f secs. Memory used: %.1f Mb.\n", - xdifftime(xtime(), T->tm_beg), (double)total / 1048576.0); - ttt = xtime(); - } -#endif - /* check the mip gap */ - if (T->parm->mip_gap > 0.0 && - ios_relative_gap(T) <= T->parm->mip_gap) - { if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Relative gap tolerance reached; search terminated " - "\n"); - ret = GLP_EMIPGAP; - goto done; - } - /* check if the time limit has been exhausted */ - if (T->parm->tm_lim < INT_MAX && - (double)(T->parm->tm_lim - 1) <= - 1000.0 * xdifftime(xtime(), T->tm_beg)) - { if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Time limit exhausted; search terminated\n"); - ret = GLP_ETMLIM; - goto done; - } - /* let the application program preprocess the subproblem */ - if (T->parm->cb_func != NULL) - { xassert(T->reason == 0); - T->reason = GLP_IPREPRO; - T->parm->cb_func(T, T->parm->cb_info); - T->reason = 0; - if (T->stop) - { ret = GLP_ESTOP; - goto done; - } - } - /* perform basic preprocessing */ - if (T->parm->pp_tech == GLP_PP_NONE) - ; - else if (T->parm->pp_tech == GLP_PP_ROOT) - { if (T->curr->level == 0) - { if (ios_preprocess_node(T, 100)) - goto fath; - } - } - else if (T->parm->pp_tech == GLP_PP_ALL) - { if (ios_preprocess_node(T, T->curr->level == 0 ? 100 : 10)) - goto fath; - } - else - xassert(T != T); - /* preprocessing may improve the global bound */ - if (!is_branch_hopeful(T, p)) - { xprintf("*** not tested yet ***\n"); - goto fath; - } - /* solve LP relaxation of the current subproblem */ - if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Solving LP relaxation...\n"); - ret = ios_solve_node(T); - if (!(ret == 0 || ret == GLP_EOBJLL || ret == GLP_EOBJUL)) - { if (T->parm->msg_lev >= GLP_MSG_ERR) - xprintf("ios_driver: unable to solve current LP relaxation;" - " glp_simplex returned %d\n", ret); - ret = GLP_EFAIL; - goto done; - } - /* analyze status of the basic solution to LP relaxation found */ - p_stat = T->mip->pbs_stat; - d_stat = T->mip->dbs_stat; - if (p_stat == GLP_FEAS && d_stat == GLP_FEAS) - { /* LP relaxation has optimal solution */ - if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Found optimal solution to LP relaxation\n"); - } - else if (d_stat == GLP_NOFEAS) - { /* LP relaxation has no dual feasible solution */ - /* since the current subproblem cannot have a larger feasible - region than its parent, there is something wrong */ - if (T->parm->msg_lev >= GLP_MSG_ERR) - xprintf("ios_driver: current LP relaxation has no dual feas" - "ible solution\n"); - ret = GLP_EFAIL; - goto done; - } - else if (p_stat == GLP_INFEAS && d_stat == GLP_FEAS) - { /* LP relaxation has no primal solution which is better than - the incumbent objective value */ - xassert(T->mip->mip_stat == GLP_FEAS); - if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("LP relaxation has no solution better than incumben" - "t objective value\n"); - /* prune the branch */ - goto fath; - } - else if (p_stat == GLP_NOFEAS) - { /* LP relaxation has no primal feasible solution */ - if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("LP relaxation has no feasible solution\n"); - /* prune the branch */ - goto fath; - } - else - { /* other cases cannot appear */ - xassert(T->mip != T->mip); - } - /* at this point basic solution to LP relaxation of the current - subproblem is optimal */ - xassert(p_stat == GLP_FEAS && d_stat == GLP_FEAS); - xassert(T->curr != NULL); - T->curr->lp_obj = T->mip->obj_val; - /* thus, it defines a local bound to integer optimal solution of - the current subproblem */ - { double bound = T->mip->obj_val; - /* some local bound to the current subproblem could be already - set before, so we should only improve it */ - bound = ios_round_bound(T, bound); - if (T->mip->dir == GLP_MIN) - { if (T->curr->bound < bound) - T->curr->bound = bound; - } - else if (T->mip->dir == GLP_MAX) - { if (T->curr->bound > bound) - T->curr->bound = bound; - } - else - xassert(T->mip != T->mip); - if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Local bound is %.9e\n", bound); - } - /* if the local bound indicates that integer optimal solution of - the current subproblem cannot be better than the global bound, - prune the branch */ - if (!is_branch_hopeful(T, p)) - { if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Current branch is hopeless and can be pruned\n"); - goto fath; - } - /* let the application program generate additional rows ("lazy" - constraints) */ - xassert(T->reopt == 0); - xassert(T->reinv == 0); - if (T->parm->cb_func != NULL) - { xassert(T->reason == 0); - T->reason = GLP_IROWGEN; - T->parm->cb_func(T, T->parm->cb_info); - T->reason = 0; - if (T->stop) - { ret = GLP_ESTOP; - goto done; - } - if (T->reopt) - { /* some rows were added; re-optimization is needed */ - T->reopt = T->reinv = 0; - goto more; - } - if (T->reinv) - { /* no rows were added, however, some inactive rows were - removed */ - T->reinv = 0; - xassert(glp_factorize(T->mip) == 0); - } - } - /* check if the basic solution is integer feasible */ - check_integrality(T); - /* if the basic solution satisfies to all integrality conditions, - it is a new, better integer feasible solution */ - if (T->curr->ii_cnt == 0) - { if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("New integer feasible solution found\n"); - if (T->parm->msg_lev >= GLP_MSG_ALL) - display_cut_info(T); - record_solution(T); - if (T->parm->msg_lev >= GLP_MSG_ON) - show_progress(T, 1); -#if 1 /* 11/VII-2013 */ - ios_process_sol(T); -#endif - /* make the application program happy */ - if (T->parm->cb_func != NULL) - { xassert(T->reason == 0); - T->reason = GLP_IBINGO; - T->parm->cb_func(T, T->parm->cb_info); - T->reason = 0; - if (T->stop) - { ret = GLP_ESTOP; - goto done; - } - } - /* since the current subproblem has been fathomed, prune its - branch */ - goto fath; - } - /* at this point basic solution to LP relaxation of the current - subproblem is optimal, but integer infeasible */ - /* try to fix some non-basic structural variables of integer kind - on their current bounds due to reduced costs */ - if (T->mip->mip_stat == GLP_FEAS) - fix_by_red_cost(T); - /* let the application program try to find some solution to the - original MIP with a primal heuristic */ - if (T->parm->cb_func != NULL) - { xassert(T->reason == 0); - T->reason = GLP_IHEUR; - T->parm->cb_func(T, T->parm->cb_info); - T->reason = 0; - if (T->stop) - { ret = GLP_ESTOP; - goto done; - } - /* check if the current branch became hopeless */ - if (!is_branch_hopeful(T, p)) - { if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Current branch became hopeless and can be prune" - "d\n"); - goto fath; - } - } - /* try to find solution with the feasibility pump heuristic */ - if (T->parm->fp_heur) - { xassert(T->reason == 0); - T->reason = GLP_IHEUR; - ios_feas_pump(T); - T->reason = 0; - /* check if the current branch became hopeless */ - if (!is_branch_hopeful(T, p)) - { if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Current branch became hopeless and can be prune" - "d\n"); - goto fath; - } - } -#if 1 /* 25/V-2013 */ - /* try to find solution with the proximity search heuristic */ - if (T->parm->ps_heur) - { xassert(T->reason == 0); - T->reason = GLP_IHEUR; - ios_proxy_heur(T); - T->reason = 0; - /* check if the current branch became hopeless */ - if (!is_branch_hopeful(T, p)) - { if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Current branch became hopeless and can be prune" - "d\n"); - goto fath; - } - } -#endif -#if 1 /* 09/VII-2013 */ - /* try to find solution with a simple rounding heuristic */ - { xassert(T->reason == 0); - T->reason = GLP_IHEUR; - round_heur(T); - T->reason = 0; - /* check if the current branch became hopeless */ - if (!is_branch_hopeful(T, p)) - { if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Current branch became hopeless and can be prune" - "d\n"); - goto fath; - } - } -#endif - /* it's time to generate cutting planes */ - xassert(T->local != NULL); - xassert(T->local->size == 0); - /* let the application program generate some cuts; note that it - can add cuts either to the local cut pool or directly to the - current subproblem */ - if (T->parm->cb_func != NULL) - { xassert(T->reason == 0); - T->reason = GLP_ICUTGEN; - T->parm->cb_func(T, T->parm->cb_info); - T->reason = 0; - if (T->stop) - { ret = GLP_ESTOP; - goto done; - } - } -#if 1 /* 18/VII-2013 */ - if (T->curr->changed > 0) - { double degrad = fabs(T->curr->lp_obj - old_obj); - if (degrad < 1e-4 * (1.0 + fabs(old_obj))) - bad_cut++; - else - bad_cut = 0; - } - old_obj = T->curr->lp_obj; - if (bad_cut == 0 || (T->curr->level == 0 && bad_cut <= 3)) -#endif - /* try to generate generic cuts with built-in generators - (as suggested by Prof. Fischetti et al. the built-in cuts are - not generated at each branching node; an intense attempt of - generating new cuts is only made at the root node, and then - a moderate effort is spent after each backtracking step) */ - if (T->curr->level == 0 || pred_p == 0) - { xassert(T->reason == 0); - T->reason = GLP_ICUTGEN; - generate_cuts(T); - T->reason = 0; - } - /* if the local cut pool is not empty, select useful cuts and add - them to the current subproblem */ - if (T->local->size > 0) - { xassert(T->reason == 0); - T->reason = GLP_ICUTGEN; - ios_process_cuts(T); - T->reason = 0; - } - /* clear the local cut pool */ - ios_clear_pool(T, T->local); - /* perform re-optimization, if necessary */ - if (T->reopt) - { T->reopt = 0; - T->curr->changed++; - goto more; - } - /* no cuts were generated; remove inactive cuts */ - remove_cuts(T); - if (T->parm->msg_lev >= GLP_MSG_ALL && T->curr->level == 0) - display_cut_info(T); - /* update history information used on pseudocost branching */ - if (T->pcost != NULL) ios_pcost_update(T); - /* it's time to perform branching */ - xassert(T->br_var == 0); - xassert(T->br_sel == 0); - /* let the application program choose variable to branch on */ - if (T->parm->cb_func != NULL) - { xassert(T->reason == 0); - xassert(T->br_var == 0); - xassert(T->br_sel == 0); - T->reason = GLP_IBRANCH; - T->parm->cb_func(T, T->parm->cb_info); - T->reason = 0; - if (T->stop) - { ret = GLP_ESTOP; - goto done; - } - } - /* if nothing has been chosen, choose some variable as specified - by the branching technique option */ - if (T->br_var == 0) - T->br_var = ios_choose_var(T, &T->br_sel); - /* perform actual branching */ - curr_p = T->curr->p; - ret = branch_on(T, T->br_var, T->br_sel); - T->br_var = T->br_sel = 0; - if (ret == 0) - { /* both branches have been created */ - pred_p = curr_p; - goto loop; - } - else if (ret == 1) - { /* one branch is hopeless and has been pruned, so now the - current subproblem is other branch */ - /* the current subproblem should be considered as a new one, - since one bound of the branching variable was changed */ - T->curr->solved = T->curr->changed = 0; -#if 1 /* 18/VII-2013 */ - /* bad_cut = 0; */ -#endif - goto more; - } - else if (ret == 2) - { /* both branches are hopeless and have been pruned; new - subproblem selection is needed to continue the search */ - goto fath; - } - else - xassert(ret != ret); -fath: /* the current subproblem has been fathomed */ - if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("Node %d fathomed\n", p); - /* freeze the current subproblem */ - ios_freeze_node(T); - /* and prune the corresponding branch of the tree */ - ios_delete_node(T, p); - /* if a new integer feasible solution has just been found, other - branches may become hopeless and therefore must be pruned */ - if (T->mip->mip_stat == GLP_FEAS) cleanup_the_tree(T); - /* new subproblem selection is needed due to backtracking */ - pred_p = 0; - goto loop; -done: /* display progress of the search on exit from the solver */ - if (T->parm->msg_lev >= GLP_MSG_ON) - show_progress(T, 0); - if (T->mir_gen != NULL) - ios_mir_term(T->mir_gen), T->mir_gen = NULL; - if (T->clq_gen != NULL) - ios_clq_term(T->clq_gen), T->clq_gen = NULL; - /* return to the calling program */ - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpios04.c b/resources/3rdparty/glpk-4.53/src/glpios04.c deleted file mode 100644 index 8074f7e71..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpios04.c +++ /dev/null @@ -1,304 +0,0 @@ -/* glpios04.c (operations on sparse vectors) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpios.h" - -/*********************************************************************** -* NAME -* -* ios_create_vec - create sparse vector -* -* SYNOPSIS -* -* #include "glpios.h" -* IOSVEC *ios_create_vec(int n); -* -* DESCRIPTION -* -* The routine ios_create_vec creates a sparse vector of dimension n, -* which initially is a null vector. -* -* RETURNS -* -* The routine returns a pointer to the vector created. */ - -IOSVEC *ios_create_vec(int n) -{ IOSVEC *v; - xassert(n >= 0); - v = xmalloc(sizeof(IOSVEC)); - v->n = n; - v->nnz = 0; - v->pos = xcalloc(1+n, sizeof(int)); - memset(&v->pos[1], 0, n * sizeof(int)); - v->ind = xcalloc(1+n, sizeof(int)); - v->val = xcalloc(1+n, sizeof(double)); - return v; -} - -/*********************************************************************** -* NAME -* -* ios_check_vec - check that sparse vector has correct representation -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_check_vec(IOSVEC *v); -* -* DESCRIPTION -* -* The routine ios_check_vec checks that a sparse vector specified by -* the parameter v has correct representation. -* -* NOTE -* -* Complexity of this operation is O(n). */ - -void ios_check_vec(IOSVEC *v) -{ int j, k, nnz; - xassert(v->n >= 0); - nnz = 0; - for (j = v->n; j >= 1; j--) - { k = v->pos[j]; - xassert(0 <= k && k <= v->nnz); - if (k != 0) - { xassert(v->ind[k] == j); - nnz++; - } - } - xassert(v->nnz == nnz); - return; -} - -/*********************************************************************** -* NAME -* -* ios_get_vj - retrieve component of sparse vector -* -* SYNOPSIS -* -* #include "glpios.h" -* double ios_get_vj(IOSVEC *v, int j); -* -* RETURNS -* -* The routine ios_get_vj returns j-th component of a sparse vector -* specified by the parameter v. */ - -double ios_get_vj(IOSVEC *v, int j) -{ int k; - xassert(1 <= j && j <= v->n); - k = v->pos[j]; - xassert(0 <= k && k <= v->nnz); - return (k == 0 ? 0.0 : v->val[k]); -} - -/*********************************************************************** -* NAME -* -* ios_set_vj - set/change component of sparse vector -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_set_vj(IOSVEC *v, int j, double val); -* -* DESCRIPTION -* -* The routine ios_set_vj assigns val to j-th component of a sparse -* vector specified by the parameter v. */ - -void ios_set_vj(IOSVEC *v, int j, double val) -{ int k; - xassert(1 <= j && j <= v->n); - k = v->pos[j]; - if (val == 0.0) - { if (k != 0) - { /* remove j-th component */ - v->pos[j] = 0; - if (k < v->nnz) - { v->pos[v->ind[v->nnz]] = k; - v->ind[k] = v->ind[v->nnz]; - v->val[k] = v->val[v->nnz]; - } - v->nnz--; - } - } - else - { if (k == 0) - { /* create j-th component */ - k = ++(v->nnz); - v->pos[j] = k; - v->ind[k] = j; - } - v->val[k] = val; - } - return; -} - -/*********************************************************************** -* NAME -* -* ios_clear_vec - set all components of sparse vector to zero -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_clear_vec(IOSVEC *v); -* -* DESCRIPTION -* -* The routine ios_clear_vec sets all components of a sparse vector -* specified by the parameter v to zero. */ - -void ios_clear_vec(IOSVEC *v) -{ int k; - for (k = 1; k <= v->nnz; k++) - v->pos[v->ind[k]] = 0; - v->nnz = 0; - return; -} - -/*********************************************************************** -* NAME -* -* ios_clean_vec - remove zero or small components from sparse vector -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_clean_vec(IOSVEC *v, double eps); -* -* DESCRIPTION -* -* The routine ios_clean_vec removes zero components and components -* whose magnitude is less than eps from a sparse vector specified by -* the parameter v. If eps is 0.0, only zero components are removed. */ - -void ios_clean_vec(IOSVEC *v, double eps) -{ int k, nnz; - nnz = 0; - for (k = 1; k <= v->nnz; k++) - { if (fabs(v->val[k]) == 0.0 || fabs(v->val[k]) < eps) - { /* remove component */ - v->pos[v->ind[k]] = 0; - } - else - { /* keep component */ - nnz++; - v->pos[v->ind[k]] = nnz; - v->ind[nnz] = v->ind[k]; - v->val[nnz] = v->val[k]; - } - } - v->nnz = nnz; - return; -} - -/*********************************************************************** -* NAME -* -* ios_copy_vec - copy sparse vector (x := y) -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_copy_vec(IOSVEC *x, IOSVEC *y); -* -* DESCRIPTION -* -* The routine ios_copy_vec copies a sparse vector specified by the -* parameter y to a sparse vector specified by the parameter x. */ - -void ios_copy_vec(IOSVEC *x, IOSVEC *y) -{ int j; - xassert(x != y); - xassert(x->n == y->n); - ios_clear_vec(x); - x->nnz = y->nnz; - memcpy(&x->ind[1], &y->ind[1], x->nnz * sizeof(int)); - memcpy(&x->val[1], &y->val[1], x->nnz * sizeof(double)); - for (j = 1; j <= x->nnz; j++) - x->pos[x->ind[j]] = j; - return; -} - -/*********************************************************************** -* NAME -* -* ios_linear_comb - compute linear combination (x := x + a * y) -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_linear_comb(IOSVEC *x, double a, IOSVEC *y); -* -* DESCRIPTION -* -* The routine ios_linear_comb computes the linear combination -* -* x := x + a * y, -* -* where x and y are sparse vectors, a is a scalar. */ - -void ios_linear_comb(IOSVEC *x, double a, IOSVEC *y) -{ int j, k; - double xj, yj; - xassert(x != y); - xassert(x->n == y->n); - for (k = 1; k <= y->nnz; k++) - { j = y->ind[k]; - xj = ios_get_vj(x, j); - yj = y->val[k]; - ios_set_vj(x, j, xj + a * yj); - } - return; -} - -/*********************************************************************** -* NAME -* -* ios_delete_vec - delete sparse vector -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_delete_vec(IOSVEC *v); -* -* DESCRIPTION -* -* The routine ios_delete_vec deletes a sparse vector specified by the -* parameter v freeing all the memory allocated to this object. */ - -void ios_delete_vec(IOSVEC *v) -{ /* delete sparse vector */ - xfree(v->pos); - xfree(v->ind); - xfree(v->val); - xfree(v); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpios05.c b/resources/3rdparty/glpk-4.53/src/glpios05.c deleted file mode 100644 index 18ae0cbbb..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpios05.c +++ /dev/null @@ -1,282 +0,0 @@ -/* glpios05.c (Gomory's mixed integer cut generator) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpios.h" - -/*********************************************************************** -* NAME -* -* ios_gmi_gen - generate Gomory's mixed integer cuts. -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_gmi_gen(glp_tree *tree, IOSPOOL *pool); -* -* DESCRIPTION -* -* The routine ios_gmi_gen generates Gomory's mixed integer cuts for -* the current point and adds them to the cut pool. */ - -#define MAXCUTS 50 -/* maximal number of cuts to be generated for one round */ - -struct worka -{ /* Gomory's cut generator working area */ - int *ind; /* int ind[1+n]; */ - double *val; /* double val[1+n]; */ - double *phi; /* double phi[1+m+n]; */ -}; - -#define f(x) ((x) - floor(x)) -/* compute fractional part of x */ - -static void gen_cut(glp_tree *tree, struct worka *worka, int j) -{ /* this routine tries to generate Gomory's mixed integer cut for - specified structural variable x[m+j] of integer kind, which is - basic and has fractional value in optimal solution to current - LP relaxation */ - glp_prob *mip = tree->mip; - int m = mip->m; - int n = mip->n; - int *ind = worka->ind; - double *val = worka->val; - double *phi = worka->phi; - int i, k, len, kind, stat; - double lb, ub, alfa, beta, ksi, phi1, rhs; - /* compute row of the simplex tableau, which (row) corresponds - to specified basic variable xB[i] = x[m+j]; see (23) */ - len = glp_eval_tab_row(mip, m+j, ind, val); - /* determine beta[i], which a value of xB[i] in optimal solution - to current LP relaxation; note that this value is the same as - if it would be computed with formula (27); it is assumed that - beta[i] is fractional enough */ - beta = mip->col[j]->prim; - /* compute cut coefficients phi and right-hand side rho, which - correspond to formula (30); dense format is used, because rows - of the simplex tableau is usually dense */ - for (k = 1; k <= m+n; k++) phi[k] = 0.0; - rhs = f(beta); /* initial value of rho; see (28), (32) */ - for (j = 1; j <= len; j++) - { /* determine original number of non-basic variable xN[j] */ - k = ind[j]; - xassert(1 <= k && k <= m+n); - /* determine the kind, bounds and current status of xN[j] in - optimal solution to LP relaxation */ - if (k <= m) - { /* auxiliary variable */ - GLPROW *row = mip->row[k]; - kind = GLP_CV; - lb = row->lb; - ub = row->ub; - stat = row->stat; - } - else - { /* structural variable */ - GLPCOL *col = mip->col[k-m]; - kind = col->kind; - lb = col->lb; - ub = col->ub; - stat = col->stat; - } - /* xN[j] cannot be basic */ - xassert(stat != GLP_BS); - /* determine row coefficient ksi[i,j] at xN[j]; see (23) */ - ksi = val[j]; - /* if ksi[i,j] is too large in the magnitude, do not generate - the cut */ - if (fabs(ksi) > 1e+05) goto fini; - /* if ksi[i,j] is too small in the magnitude, skip it */ - if (fabs(ksi) < 1e-10) goto skip; - /* compute row coefficient alfa[i,j] at y[j]; see (26) */ - switch (stat) - { case GLP_NF: - /* xN[j] is free (unbounded) having non-zero ksi[i,j]; - do not generate the cut */ - goto fini; - case GLP_NL: - /* xN[j] has active lower bound */ - alfa = - ksi; - break; - case GLP_NU: - /* xN[j] has active upper bound */ - alfa = + ksi; - break; - case GLP_NS: - /* xN[j] is fixed; skip it */ - goto skip; - default: - xassert(stat != stat); - } - /* compute cut coefficient phi'[j] at y[j]; see (21), (28) */ - switch (kind) - { case GLP_IV: - /* y[j] is integer */ - if (fabs(alfa - floor(alfa + 0.5)) < 1e-10) - { /* alfa[i,j] is close to nearest integer; skip it */ - goto skip; - } - else if (f(alfa) <= f(beta)) - phi1 = f(alfa); - else - phi1 = (f(beta) / (1.0 - f(beta))) * (1.0 - f(alfa)); - break; - case GLP_CV: - /* y[j] is continuous */ - if (alfa >= 0.0) - phi1 = + alfa; - else - phi1 = (f(beta) / (1.0 - f(beta))) * (- alfa); - break; - default: - xassert(kind != kind); - } - /* compute cut coefficient phi[j] at xN[j] and update right- - hand side rho; see (31), (32) */ - switch (stat) - { case GLP_NL: - /* xN[j] has active lower bound */ - phi[k] = + phi1; - rhs += phi1 * lb; - break; - case GLP_NU: - /* xN[j] has active upper bound */ - phi[k] = - phi1; - rhs -= phi1 * ub; - break; - default: - xassert(stat != stat); - } -skip: ; - } - /* now the cut has the form sum_k phi[k] * x[k] >= rho, where cut - coefficients are stored in the array phi in dense format; - x[1,...,m] are auxiliary variables, x[m+1,...,m+n] are struc- - tural variables; see (30) */ - /* eliminate auxiliary variables in order to express the cut only - through structural variables; see (33) */ - for (i = 1; i <= m; i++) - { GLPROW *row; - GLPAIJ *aij; - if (fabs(phi[i]) < 1e-10) continue; - /* auxiliary variable x[i] has non-zero cut coefficient */ - row = mip->row[i]; - /* x[i] cannot be fixed */ - xassert(row->type != GLP_FX); - /* substitute x[i] = sum_j a[i,j] * x[m+j] */ - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - phi[m+aij->col->j] += phi[i] * aij->val; - } - /* convert the final cut to sparse format and substitute fixed - (structural) variables */ - len = 0; - for (j = 1; j <= n; j++) - { GLPCOL *col; - if (fabs(phi[m+j]) < 1e-10) continue; - /* structural variable x[m+j] has non-zero cut coefficient */ - col = mip->col[j]; - if (col->type == GLP_FX) - { /* eliminate x[m+j] */ - rhs -= phi[m+j] * col->lb; - } - else - { len++; - ind[len] = j; - val[len] = phi[m+j]; - } - } - if (fabs(rhs) < 1e-12) rhs = 0.0; - /* if the cut inequality seems to be badly scaled, reject it to - avoid numeric difficulties */ - for (k = 1; k <= len; k++) - { if (fabs(val[k]) < 1e-03) goto fini; - if (fabs(val[k]) > 1e+03) goto fini; - } - /* add the cut to the cut pool for further consideration */ -#if 0 - ios_add_cut_row(tree, pool, GLP_RF_GMI, len, ind, val, GLP_LO, - rhs); -#else - glp_ios_add_row(tree, NULL, GLP_RF_GMI, 0, len, ind, val, GLP_LO, - rhs); -#endif -fini: return; -} - -struct var { int j; double f; }; - -static int fcmp(const void *p1, const void *p2) -{ const struct var *v1 = p1, *v2 = p2; - if (v1->f > v2->f) return -1; - if (v1->f < v2->f) return +1; - return 0; -} - -void ios_gmi_gen(glp_tree *tree) -{ /* main routine to generate Gomory's cuts */ - glp_prob *mip = tree->mip; - int m = mip->m; - int n = mip->n; - struct var *var; - int k, nv, j, size; - struct worka _worka, *worka = &_worka; - /* allocate working arrays */ - var = xcalloc(1+n, sizeof(struct var)); - worka->ind = xcalloc(1+n, sizeof(int)); - worka->val = xcalloc(1+n, sizeof(double)); - worka->phi = xcalloc(1+m+n, sizeof(double)); - /* build the list of integer structural variables, which are - basic and have fractional value in optimal solution to current - LP relaxation */ - nv = 0; - for (j = 1; j <= n; j++) - { GLPCOL *col = mip->col[j]; - double frac; - if (col->kind != GLP_IV) continue; - if (col->type == GLP_FX) continue; - if (col->stat != GLP_BS) continue; - frac = f(col->prim); - if (!(0.05 <= frac && frac <= 0.95)) continue; - /* add variable to the list */ - nv++, var[nv].j = j, var[nv].f = frac; - } - /* order the list by descending fractionality */ - qsort(&var[1], nv, sizeof(struct var), fcmp); - /* try to generate cuts by one for each variable in the list, but - not more than MAXCUTS cuts */ - size = glp_ios_pool_size(tree); - for (k = 1; k <= nv; k++) - { if (glp_ios_pool_size(tree) - size >= MAXCUTS) break; - gen_cut(tree, worka, var[k].j); - } - /* free working arrays */ - xfree(var); - xfree(worka->ind); - xfree(worka->val); - xfree(worka->phi); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpios06.c b/resources/3rdparty/glpk-4.53/src/glpios06.c deleted file mode 100644 index 53f8dcfc7..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpios06.c +++ /dev/null @@ -1,1448 +0,0 @@ -/* glpios06.c (MIR cut generator) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpios.h" - -#define _MIR_DEBUG 0 - -#define MAXAGGR 5 -/* maximal number of rows which can be aggregated */ - -struct MIR -{ /* MIR cut generator working area */ - /*--------------------------------------------------------------*/ - /* global information valid for the root subproblem */ - int m; - /* number of rows (in the root subproblem) */ - int n; - /* number of columns */ - char *skip; /* char skip[1+m]; */ - /* skip[i], 1 <= i <= m, is a flag that means that row i should - not be used because (1) it is not suitable, or (2) because it - has been used in the aggregated constraint */ - char *isint; /* char isint[1+m+n]; */ - /* isint[k], 1 <= k <= m+n, is a flag that means that variable - x[k] is integer (otherwise, continuous) */ - double *lb; /* double lb[1+m+n]; */ - /* lb[k], 1 <= k <= m+n, is lower bound of x[k]; -DBL_MAX means - that x[k] has no lower bound */ - int *vlb; /* int vlb[1+m+n]; */ - /* vlb[k] = k', 1 <= k <= m+n, is the number of integer variable, - which defines variable lower bound x[k] >= lb[k] * x[k']; zero - means that x[k] has simple lower bound */ - double *ub; /* double ub[1+m+n]; */ - /* ub[k], 1 <= k <= m+n, is upper bound of x[k]; +DBL_MAX means - that x[k] has no upper bound */ - int *vub; /* int vub[1+m+n]; */ - /* vub[k] = k', 1 <= k <= m+n, is the number of integer variable, - which defines variable upper bound x[k] <= ub[k] * x[k']; zero - means that x[k] has simple upper bound */ - /*--------------------------------------------------------------*/ - /* current (fractional) point to be separated */ - double *x; /* double x[1+m+n]; */ - /* x[k] is current value of auxiliary (1 <= k <= m) or structural - (m+1 <= k <= m+n) variable */ - /*--------------------------------------------------------------*/ - /* aggregated constraint sum a[k] * x[k] = b, which is a linear - combination of original constraints transformed to equalities - by introducing auxiliary variables */ - int agg_cnt; - /* number of rows (original constraints) used to build aggregated - constraint, 1 <= agg_cnt <= MAXAGGR */ - int *agg_row; /* int agg_row[1+MAXAGGR]; */ - /* agg_row[k], 1 <= k <= agg_cnt, is the row number used to build - aggregated constraint */ - IOSVEC *agg_vec; /* IOSVEC agg_vec[1:m+n]; */ - /* sparse vector of aggregated constraint coefficients, a[k] */ - double agg_rhs; - /* right-hand side of the aggregated constraint, b */ - /*--------------------------------------------------------------*/ - /* bound substitution flags for modified constraint */ - char *subst; /* char subst[1+m+n]; */ - /* subst[k], 1 <= k <= m+n, is a bound substitution flag used for - variable x[k]: - '?' - x[k] is missing in modified constraint - 'L' - x[k] = (lower bound) + x'[k] - 'U' - x[k] = (upper bound) - x'[k] */ - /*--------------------------------------------------------------*/ - /* modified constraint sum a'[k] * x'[k] = b', where x'[k] >= 0, - derived from aggregated constraint by substituting bounds; - note that due to substitution of variable bounds there may be - additional terms in the modified constraint */ - IOSVEC *mod_vec; /* IOSVEC mod_vec[1:m+n]; */ - /* sparse vector of modified constraint coefficients, a'[k] */ - double mod_rhs; - /* right-hand side of the modified constraint, b' */ - /*--------------------------------------------------------------*/ - /* cutting plane sum alpha[k] * x[k] <= beta */ - IOSVEC *cut_vec; /* IOSVEC cut_vec[1:m+n]; */ - /* sparse vector of cutting plane coefficients, alpha[k] */ - double cut_rhs; - /* right-hand size of the cutting plane, beta */ -}; - -/*********************************************************************** -* NAME -* -* ios_mir_init - initialize MIR cut generator -* -* SYNOPSIS -* -* #include "glpios.h" -* void *ios_mir_init(glp_tree *tree); -* -* DESCRIPTION -* -* The routine ios_mir_init initializes the MIR cut generator assuming -* that the current subproblem is the root subproblem. -* -* RETURNS -* -* The routine ios_mir_init returns a pointer to the MIR cut generator -* working area. */ - -static void set_row_attrib(glp_tree *tree, struct MIR *mir) -{ /* set global row attributes */ - glp_prob *mip = tree->mip; - int m = mir->m; - int k; - for (k = 1; k <= m; k++) - { GLPROW *row = mip->row[k]; - mir->skip[k] = 0; - mir->isint[k] = 0; - switch (row->type) - { case GLP_FR: - mir->lb[k] = -DBL_MAX, mir->ub[k] = +DBL_MAX; break; - case GLP_LO: - mir->lb[k] = row->lb, mir->ub[k] = +DBL_MAX; break; - case GLP_UP: - mir->lb[k] = -DBL_MAX, mir->ub[k] = row->ub; break; - case GLP_DB: - mir->lb[k] = row->lb, mir->ub[k] = row->ub; break; - case GLP_FX: - mir->lb[k] = mir->ub[k] = row->lb; break; - default: - xassert(row != row); - } - mir->vlb[k] = mir->vub[k] = 0; - } - return; -} - -static void set_col_attrib(glp_tree *tree, struct MIR *mir) -{ /* set global column attributes */ - glp_prob *mip = tree->mip; - int m = mir->m; - int n = mir->n; - int k; - for (k = m+1; k <= m+n; k++) - { GLPCOL *col = mip->col[k-m]; - switch (col->kind) - { case GLP_CV: - mir->isint[k] = 0; break; - case GLP_IV: - mir->isint[k] = 1; break; - default: - xassert(col != col); - } - switch (col->type) - { case GLP_FR: - mir->lb[k] = -DBL_MAX, mir->ub[k] = +DBL_MAX; break; - case GLP_LO: - mir->lb[k] = col->lb, mir->ub[k] = +DBL_MAX; break; - case GLP_UP: - mir->lb[k] = -DBL_MAX, mir->ub[k] = col->ub; break; - case GLP_DB: - mir->lb[k] = col->lb, mir->ub[k] = col->ub; break; - case GLP_FX: - mir->lb[k] = mir->ub[k] = col->lb; break; - default: - xassert(col != col); - } - mir->vlb[k] = mir->vub[k] = 0; - } - return; -} - -static void set_var_bounds(glp_tree *tree, struct MIR *mir) -{ /* set variable bounds */ - glp_prob *mip = tree->mip; - int m = mir->m; - GLPAIJ *aij; - int i, k1, k2; - double a1, a2; - for (i = 1; i <= m; i++) - { /* we need the row to be '>= 0' or '<= 0' */ - if (!(mir->lb[i] == 0.0 && mir->ub[i] == +DBL_MAX || - mir->lb[i] == -DBL_MAX && mir->ub[i] == 0.0)) continue; - /* take first term */ - aij = mip->row[i]->ptr; - if (aij == NULL) continue; - k1 = m + aij->col->j, a1 = aij->val; - /* take second term */ - aij = aij->r_next; - if (aij == NULL) continue; - k2 = m + aij->col->j, a2 = aij->val; - /* there must be only two terms */ - if (aij->r_next != NULL) continue; - /* interchange terms, if needed */ - if (!mir->isint[k1] && mir->isint[k2]) - ; - else if (mir->isint[k1] && !mir->isint[k2]) - { k2 = k1, a2 = a1; - k1 = m + aij->col->j, a1 = aij->val; - } - else - { /* both terms are either continuous or integer */ - continue; - } - /* x[k2] should be double-bounded */ - if (mir->lb[k2] == -DBL_MAX || mir->ub[k2] == +DBL_MAX || - mir->lb[k2] == mir->ub[k2]) continue; - /* change signs, if necessary */ - if (mir->ub[i] == 0.0) a1 = - a1, a2 = - a2; - /* now the row has the form a1 * x1 + a2 * x2 >= 0, where x1 - is continuous, x2 is integer */ - if (a1 > 0.0) - { /* x1 >= - (a2 / a1) * x2 */ - if (mir->vlb[k1] == 0) - { /* set variable lower bound for x1 */ - mir->lb[k1] = - a2 / a1; - mir->vlb[k1] = k2; - /* the row should not be used */ - mir->skip[i] = 1; - } - } - else /* a1 < 0.0 */ - { /* x1 <= - (a2 / a1) * x2 */ - if (mir->vub[k1] == 0) - { /* set variable upper bound for x1 */ - mir->ub[k1] = - a2 / a1; - mir->vub[k1] = k2; - /* the row should not be used */ - mir->skip[i] = 1; - } - } - } - return; -} - -static void mark_useless_rows(glp_tree *tree, struct MIR *mir) -{ /* mark rows which should not be used */ - glp_prob *mip = tree->mip; - int m = mir->m; - GLPAIJ *aij; - int i, k, nv; - for (i = 1; i <= m; i++) - { /* free rows should not be used */ - if (mir->lb[i] == -DBL_MAX && mir->ub[i] == +DBL_MAX) - { mir->skip[i] = 1; - continue; - } - nv = 0; - for (aij = mip->row[i]->ptr; aij != NULL; aij = aij->r_next) - { k = m + aij->col->j; - /* rows with free variables should not be used */ - if (mir->lb[k] == -DBL_MAX && mir->ub[k] == +DBL_MAX) - { mir->skip[i] = 1; - break; - } - /* rows with integer variables having infinite (lower or - upper) bound should not be used */ - if (mir->isint[k] && mir->lb[k] == -DBL_MAX || - mir->isint[k] && mir->ub[k] == +DBL_MAX) - { mir->skip[i] = 1; - break; - } - /* count non-fixed variables */ - if (!(mir->vlb[k] == 0 && mir->vub[k] == 0 && - mir->lb[k] == mir->ub[k])) nv++; - } - /* rows with all variables fixed should not be used */ - if (nv == 0) - { mir->skip[i] = 1; - continue; - } - } - return; -} - -void *ios_mir_init(glp_tree *tree) -{ /* initialize MIR cut generator */ - glp_prob *mip = tree->mip; - int m = mip->m; - int n = mip->n; - struct MIR *mir; -#if _MIR_DEBUG - xprintf("ios_mir_init: warning: debug mode enabled\n"); -#endif - /* allocate working area */ - mir = xmalloc(sizeof(struct MIR)); - mir->m = m; - mir->n = n; - mir->skip = xcalloc(1+m, sizeof(char)); - mir->isint = xcalloc(1+m+n, sizeof(char)); - mir->lb = xcalloc(1+m+n, sizeof(double)); - mir->vlb = xcalloc(1+m+n, sizeof(int)); - mir->ub = xcalloc(1+m+n, sizeof(double)); - mir->vub = xcalloc(1+m+n, sizeof(int)); - mir->x = xcalloc(1+m+n, sizeof(double)); - mir->agg_row = xcalloc(1+MAXAGGR, sizeof(int)); - mir->agg_vec = ios_create_vec(m+n); - mir->subst = xcalloc(1+m+n, sizeof(char)); - mir->mod_vec = ios_create_vec(m+n); - mir->cut_vec = ios_create_vec(m+n); - /* set global row attributes */ - set_row_attrib(tree, mir); - /* set global column attributes */ - set_col_attrib(tree, mir); - /* set variable bounds */ - set_var_bounds(tree, mir); - /* mark rows which should not be used */ - mark_useless_rows(tree, mir); - return mir; -} - -/*********************************************************************** -* NAME -* -* ios_mir_gen - generate MIR cuts -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_mir_gen(glp_tree *tree, void *gen, IOSPOOL *pool); -* -* DESCRIPTION -* -* The routine ios_mir_gen generates MIR cuts for the current point and -* adds them to the cut pool. */ - -static void get_current_point(glp_tree *tree, struct MIR *mir) -{ /* obtain current point */ - glp_prob *mip = tree->mip; - int m = mir->m; - int n = mir->n; - int k; - for (k = 1; k <= m; k++) - mir->x[k] = mip->row[k]->prim; - for (k = m+1; k <= m+n; k++) - mir->x[k] = mip->col[k-m]->prim; - return; -} - -#if _MIR_DEBUG -static void check_current_point(struct MIR *mir) -{ /* check current point */ - int m = mir->m; - int n = mir->n; - int k, kk; - double lb, ub, eps; - for (k = 1; k <= m+n; k++) - { /* determine lower bound */ - lb = mir->lb[k]; - kk = mir->vlb[k]; - if (kk != 0) - { xassert(lb != -DBL_MAX); - xassert(!mir->isint[k]); - xassert(mir->isint[kk]); - lb *= mir->x[kk]; - } - /* check lower bound */ - if (lb != -DBL_MAX) - { eps = 1e-6 * (1.0 + fabs(lb)); - xassert(mir->x[k] >= lb - eps); - } - /* determine upper bound */ - ub = mir->ub[k]; - kk = mir->vub[k]; - if (kk != 0) - { xassert(ub != +DBL_MAX); - xassert(!mir->isint[k]); - xassert(mir->isint[kk]); - ub *= mir->x[kk]; - } - /* check upper bound */ - if (ub != +DBL_MAX) - { eps = 1e-6 * (1.0 + fabs(ub)); - xassert(mir->x[k] <= ub + eps); - } - } - return; -} -#endif - -static void initial_agg_row(glp_tree *tree, struct MIR *mir, int i) -{ /* use original i-th row as initial aggregated constraint */ - glp_prob *mip = tree->mip; - int m = mir->m; - GLPAIJ *aij; - xassert(1 <= i && i <= m); - xassert(!mir->skip[i]); - /* mark i-th row in order not to use it in the same aggregated - constraint */ - mir->skip[i] = 2; - mir->agg_cnt = 1; - mir->agg_row[1] = i; - /* use x[i] - sum a[i,j] * x[m+j] = 0, where x[i] is auxiliary - variable of row i, x[m+j] are structural variables */ - ios_clear_vec(mir->agg_vec); - ios_set_vj(mir->agg_vec, i, 1.0); - for (aij = mip->row[i]->ptr; aij != NULL; aij = aij->r_next) - ios_set_vj(mir->agg_vec, m + aij->col->j, - aij->val); - mir->agg_rhs = 0.0; -#if _MIR_DEBUG - ios_check_vec(mir->agg_vec); -#endif - return; -} - -#if _MIR_DEBUG -static void check_agg_row(struct MIR *mir) -{ /* check aggregated constraint */ - int m = mir->m; - int n = mir->n; - int j, k; - double r, big; - /* compute the residual r = sum a[k] * x[k] - b and determine - big = max(1, |a[k]|, |b|) */ - r = 0.0, big = 1.0; - for (j = 1; j <= mir->agg_vec->nnz; j++) - { k = mir->agg_vec->ind[j]; - xassert(1 <= k && k <= m+n); - r += mir->agg_vec->val[j] * mir->x[k]; - if (big < fabs(mir->agg_vec->val[j])) - big = fabs(mir->agg_vec->val[j]); - } - r -= mir->agg_rhs; - if (big < fabs(mir->agg_rhs)) - big = fabs(mir->agg_rhs); - /* the residual must be close to zero */ - xassert(fabs(r) <= 1e-6 * big); - return; -} -#endif - -static void subst_fixed_vars(struct MIR *mir) -{ /* substitute fixed variables into aggregated constraint */ - int m = mir->m; - int n = mir->n; - int j, k; - for (j = 1; j <= mir->agg_vec->nnz; j++) - { k = mir->agg_vec->ind[j]; - xassert(1 <= k && k <= m+n); - if (mir->vlb[k] == 0 && mir->vub[k] == 0 && - mir->lb[k] == mir->ub[k]) - { /* x[k] is fixed */ - mir->agg_rhs -= mir->agg_vec->val[j] * mir->lb[k]; - mir->agg_vec->val[j] = 0.0; - } - } - /* remove terms corresponding to fixed variables */ - ios_clean_vec(mir->agg_vec, DBL_EPSILON); -#if _MIR_DEBUG - ios_check_vec(mir->agg_vec); -#endif - return; -} - -static void bound_subst_heur(struct MIR *mir) -{ /* bound substitution heuristic */ - int m = mir->m; - int n = mir->n; - int j, k, kk; - double d1, d2; - for (j = 1; j <= mir->agg_vec->nnz; j++) - { k = mir->agg_vec->ind[j]; - xassert(1 <= k && k <= m+n); - if (mir->isint[k]) continue; /* skip integer variable */ - /* compute distance from x[k] to its lower bound */ - kk = mir->vlb[k]; - if (kk == 0) - { if (mir->lb[k] == -DBL_MAX) - d1 = DBL_MAX; - else - d1 = mir->x[k] - mir->lb[k]; - } - else - { xassert(1 <= kk && kk <= m+n); - xassert(mir->isint[kk]); - xassert(mir->lb[k] != -DBL_MAX); - d1 = mir->x[k] - mir->lb[k] * mir->x[kk]; - } - /* compute distance from x[k] to its upper bound */ - kk = mir->vub[k]; - if (kk == 0) - { if (mir->vub[k] == +DBL_MAX) - d2 = DBL_MAX; - else - d2 = mir->ub[k] - mir->x[k]; - } - else - { xassert(1 <= kk && kk <= m+n); - xassert(mir->isint[kk]); - xassert(mir->ub[k] != +DBL_MAX); - d2 = mir->ub[k] * mir->x[kk] - mir->x[k]; - } - /* x[k] cannot be free */ - xassert(d1 != DBL_MAX || d2 != DBL_MAX); - /* choose the bound which is closer to x[k] */ - xassert(mir->subst[k] == '?'); - if (d1 <= d2) - mir->subst[k] = 'L'; - else - mir->subst[k] = 'U'; - } - return; -} - -static void build_mod_row(struct MIR *mir) -{ /* substitute bounds and build modified constraint */ - int m = mir->m; - int n = mir->n; - int j, jj, k, kk; - /* initially modified constraint is aggregated constraint */ - ios_copy_vec(mir->mod_vec, mir->agg_vec); - mir->mod_rhs = mir->agg_rhs; -#if _MIR_DEBUG - ios_check_vec(mir->mod_vec); -#endif - /* substitute bounds for continuous variables; note that due to - substitution of variable bounds additional terms may appear in - modified constraint */ - for (j = mir->mod_vec->nnz; j >= 1; j--) - { k = mir->mod_vec->ind[j]; - xassert(1 <= k && k <= m+n); - if (mir->isint[k]) continue; /* skip integer variable */ - if (mir->subst[k] == 'L') - { /* x[k] = (lower bound) + x'[k] */ - xassert(mir->lb[k] != -DBL_MAX); - kk = mir->vlb[k]; - if (kk == 0) - { /* x[k] = lb[k] + x'[k] */ - mir->mod_rhs -= mir->mod_vec->val[j] * mir->lb[k]; - } - else - { /* x[k] = lb[k] * x[kk] + x'[k] */ - xassert(mir->isint[kk]); - jj = mir->mod_vec->pos[kk]; - if (jj == 0) - { ios_set_vj(mir->mod_vec, kk, 1.0); - jj = mir->mod_vec->pos[kk]; - mir->mod_vec->val[jj] = 0.0; - } - mir->mod_vec->val[jj] += - mir->mod_vec->val[j] * mir->lb[k]; - } - } - else if (mir->subst[k] == 'U') - { /* x[k] = (upper bound) - x'[k] */ - xassert(mir->ub[k] != +DBL_MAX); - kk = mir->vub[k]; - if (kk == 0) - { /* x[k] = ub[k] - x'[k] */ - mir->mod_rhs -= mir->mod_vec->val[j] * mir->ub[k]; - } - else - { /* x[k] = ub[k] * x[kk] - x'[k] */ - xassert(mir->isint[kk]); - jj = mir->mod_vec->pos[kk]; - if (jj == 0) - { ios_set_vj(mir->mod_vec, kk, 1.0); - jj = mir->mod_vec->pos[kk]; - mir->mod_vec->val[jj] = 0.0; - } - mir->mod_vec->val[jj] += - mir->mod_vec->val[j] * mir->ub[k]; - } - mir->mod_vec->val[j] = - mir->mod_vec->val[j]; - } - else - xassert(k != k); - } -#if _MIR_DEBUG - ios_check_vec(mir->mod_vec); -#endif - /* substitute bounds for integer variables */ - for (j = 1; j <= mir->mod_vec->nnz; j++) - { k = mir->mod_vec->ind[j]; - xassert(1 <= k && k <= m+n); - if (!mir->isint[k]) continue; /* skip continuous variable */ - xassert(mir->subst[k] == '?'); - xassert(mir->vlb[k] == 0 && mir->vub[k] == 0); - xassert(mir->lb[k] != -DBL_MAX && mir->ub[k] != +DBL_MAX); - if (fabs(mir->lb[k]) <= fabs(mir->ub[k])) - { /* x[k] = lb[k] + x'[k] */ - mir->subst[k] = 'L'; - mir->mod_rhs -= mir->mod_vec->val[j] * mir->lb[k]; - } - else - { /* x[k] = ub[k] - x'[k] */ - mir->subst[k] = 'U'; - mir->mod_rhs -= mir->mod_vec->val[j] * mir->ub[k]; - mir->mod_vec->val[j] = - mir->mod_vec->val[j]; - } - } -#if _MIR_DEBUG - ios_check_vec(mir->mod_vec); -#endif - return; -} - -#if _MIR_DEBUG -static void check_mod_row(struct MIR *mir) -{ /* check modified constraint */ - int m = mir->m; - int n = mir->n; - int j, k, kk; - double r, big, x; - /* compute the residual r = sum a'[k] * x'[k] - b' and determine - big = max(1, |a[k]|, |b|) */ - r = 0.0, big = 1.0; - for (j = 1; j <= mir->mod_vec->nnz; j++) - { k = mir->mod_vec->ind[j]; - xassert(1 <= k && k <= m+n); - if (mir->subst[k] == 'L') - { /* x'[k] = x[k] - (lower bound) */ - xassert(mir->lb[k] != -DBL_MAX); - kk = mir->vlb[k]; - if (kk == 0) - x = mir->x[k] - mir->lb[k]; - else - x = mir->x[k] - mir->lb[k] * mir->x[kk]; - } - else if (mir->subst[k] == 'U') - { /* x'[k] = (upper bound) - x[k] */ - xassert(mir->ub[k] != +DBL_MAX); - kk = mir->vub[k]; - if (kk == 0) - x = mir->ub[k] - mir->x[k]; - else - x = mir->ub[k] * mir->x[kk] - mir->x[k]; - } - else - xassert(k != k); - r += mir->mod_vec->val[j] * x; - if (big < fabs(mir->mod_vec->val[j])) - big = fabs(mir->mod_vec->val[j]); - } - r -= mir->mod_rhs; - if (big < fabs(mir->mod_rhs)) - big = fabs(mir->mod_rhs); - /* the residual must be close to zero */ - xassert(fabs(r) <= 1e-6 * big); - return; -} -#endif - -/*********************************************************************** -* mir_ineq - construct MIR inequality -* -* Given the single constraint mixed integer set -* -* |N| -* X = {(x,s) in Z x R : sum a[j] * x[j] <= b + s}, -* + + j in N -* -* this routine constructs the mixed integer rounding (MIR) inequality -* -* sum alpha[j] * x[j] <= beta + gamma * s, -* j in N -* -* which is valid for X. -* -* If the MIR inequality has been successfully constructed, the routine -* returns zero. Otherwise, if b is close to nearest integer, there may -* be numeric difficulties due to big coefficients; so in this case the -* routine returns non-zero. */ - -static int mir_ineq(const int n, const double a[], const double b, - double alpha[], double *beta, double *gamma) -{ int j; - double f, t; - if (fabs(b - floor(b + .5)) < 0.01) - return 1; - f = b - floor(b); - for (j = 1; j <= n; j++) - { t = (a[j] - floor(a[j])) - f; - if (t <= 0.0) - alpha[j] = floor(a[j]); - else - alpha[j] = floor(a[j]) + t / (1.0 - f); - } - *beta = floor(b); - *gamma = 1.0 / (1.0 - f); - return 0; -} - -/*********************************************************************** -* cmir_ineq - construct c-MIR inequality -* -* Given the mixed knapsack set -* -* MK |N| -* X = {(x,s) in Z x R : sum a[j] * x[j] <= b + s, -* + + j in N -* -* x[j] <= u[j]}, -* -* a subset C of variables to be complemented, and a divisor delta > 0, -* this routine constructs the complemented MIR (c-MIR) inequality -* -* sum alpha[j] * x[j] <= beta + gamma * s, -* j in N -* MK -* which is valid for X . -* -* If the c-MIR inequality has been successfully constructed, the -* routine returns zero. Otherwise, if there is a risk of numerical -* difficulties due to big coefficients (see comments to the routine -* mir_ineq), the routine cmir_ineq returns non-zero. */ - -static int cmir_ineq(const int n, const double a[], const double b, - const double u[], const char cset[], const double delta, - double alpha[], double *beta, double *gamma) -{ int j; - double *aa, bb; - aa = alpha, bb = b; - for (j = 1; j <= n; j++) - { aa[j] = a[j] / delta; - if (cset[j]) - aa[j] = - aa[j], bb -= a[j] * u[j]; - } - bb /= delta; - if (mir_ineq(n, aa, bb, alpha, beta, gamma)) return 1; - for (j = 1; j <= n; j++) - { if (cset[j]) - alpha[j] = - alpha[j], *beta += alpha[j] * u[j]; - } - *gamma /= delta; - return 0; -} - -/*********************************************************************** -* cmir_sep - c-MIR separation heuristic -* -* Given the mixed knapsack set -* -* MK |N| -* X = {(x,s) in Z x R : sum a[j] * x[j] <= b + s, -* + + j in N -* -* x[j] <= u[j]} -* -* * * -* and a fractional point (x , s ), this routine tries to construct -* c-MIR inequality -* -* sum alpha[j] * x[j] <= beta + gamma * s, -* j in N -* MK -* which is valid for X and has (desirably maximal) violation at the -* fractional point given. This is attained by choosing an appropriate -* set C of variables to be complemented and a divisor delta > 0, which -* together define corresponding c-MIR inequality. -* -* If a violated c-MIR inequality has been successfully constructed, -* the routine returns its violation: -* -* * * -* sum alpha[j] * x [j] - beta - gamma * s , -* j in N -* -* which is positive. In case of failure the routine returns zero. */ - -struct vset { int j; double v; }; - -static int cmir_cmp(const void *p1, const void *p2) -{ const struct vset *v1 = p1, *v2 = p2; - if (v1->v < v2->v) return -1; - if (v1->v > v2->v) return +1; - return 0; -} - -static double cmir_sep(const int n, const double a[], const double b, - const double u[], const double x[], const double s, - double alpha[], double *beta, double *gamma) -{ int fail, j, k, nv, v; - double delta, eps, d_try[1+3], r, r_best; - char *cset; - struct vset *vset; - /* allocate working arrays */ - cset = xcalloc(1+n, sizeof(char)); - vset = xcalloc(1+n, sizeof(struct vset)); - /* choose initial C */ - for (j = 1; j <= n; j++) - cset[j] = (char)(x[j] >= 0.5 * u[j]); - /* choose initial delta */ - r_best = delta = 0.0; - for (j = 1; j <= n; j++) - { xassert(a[j] != 0.0); - /* if x[j] is close to its bounds, skip it */ - eps = 1e-9 * (1.0 + fabs(u[j])); - if (x[j] < eps || x[j] > u[j] - eps) continue; - /* try delta = |a[j]| to construct c-MIR inequality */ - fail = cmir_ineq(n, a, b, u, cset, fabs(a[j]), alpha, beta, - gamma); - if (fail) continue; - /* compute violation */ - r = - (*beta) - (*gamma) * s; - for (k = 1; k <= n; k++) r += alpha[k] * x[k]; - if (r_best < r) r_best = r, delta = fabs(a[j]); - } - if (r_best < 0.001) r_best = 0.0; - if (r_best == 0.0) goto done; - xassert(delta > 0.0); - /* try to increase violation by dividing delta by 2, 4, and 8, - respectively */ - d_try[1] = delta / 2.0; - d_try[2] = delta / 4.0; - d_try[3] = delta / 8.0; - for (j = 1; j <= 3; j++) - { /* construct c-MIR inequality */ - fail = cmir_ineq(n, a, b, u, cset, d_try[j], alpha, beta, - gamma); - if (fail) continue; - /* compute violation */ - r = - (*beta) - (*gamma) * s; - for (k = 1; k <= n; k++) r += alpha[k] * x[k]; - if (r_best < r) r_best = r, delta = d_try[j]; - } - /* build subset of variables lying strictly between their bounds - and order it by nondecreasing values of |x[j] - u[j]/2| */ - nv = 0; - for (j = 1; j <= n; j++) - { /* if x[j] is close to its bounds, skip it */ - eps = 1e-9 * (1.0 + fabs(u[j])); - if (x[j] < eps || x[j] > u[j] - eps) continue; - /* add x[j] to the subset */ - nv++; - vset[nv].j = j; - vset[nv].v = fabs(x[j] - 0.5 * u[j]); - } - qsort(&vset[1], nv, sizeof(struct vset), cmir_cmp); - /* try to increase violation by successively complementing each - variable in the subset */ - for (v = 1; v <= nv; v++) - { j = vset[v].j; - /* replace x[j] by its complement or vice versa */ - cset[j] = (char)!cset[j]; - /* construct c-MIR inequality */ - fail = cmir_ineq(n, a, b, u, cset, delta, alpha, beta, gamma); - /* restore the variable */ - cset[j] = (char)!cset[j]; - /* do not replace the variable in case of failure */ - if (fail) continue; - /* compute violation */ - r = - (*beta) - (*gamma) * s; - for (k = 1; k <= n; k++) r += alpha[k] * x[k]; - if (r_best < r) r_best = r, cset[j] = (char)!cset[j]; - } - /* construct the best c-MIR inequality chosen */ - fail = cmir_ineq(n, a, b, u, cset, delta, alpha, beta, gamma); - xassert(!fail); -done: /* free working arrays */ - xfree(cset); - xfree(vset); - /* return to the calling routine */ - return r_best; -} - -static double generate(struct MIR *mir) -{ /* try to generate violated c-MIR cut for modified constraint */ - int m = mir->m; - int n = mir->n; - int j, k, kk, nint; - double s, *u, *x, *alpha, r_best = 0.0, b, beta, gamma; - ios_copy_vec(mir->cut_vec, mir->mod_vec); - mir->cut_rhs = mir->mod_rhs; - /* remove small terms, which can appear due to substitution of - variable bounds */ - ios_clean_vec(mir->cut_vec, DBL_EPSILON); -#if _MIR_DEBUG - ios_check_vec(mir->cut_vec); -#endif - /* remove positive continuous terms to obtain MK relaxation */ - for (j = 1; j <= mir->cut_vec->nnz; j++) - { k = mir->cut_vec->ind[j]; - xassert(1 <= k && k <= m+n); - if (!mir->isint[k] && mir->cut_vec->val[j] > 0.0) - mir->cut_vec->val[j] = 0.0; - } - ios_clean_vec(mir->cut_vec, 0.0); -#if _MIR_DEBUG - ios_check_vec(mir->cut_vec); -#endif - /* move integer terms to the beginning of the sparse vector and - determine the number of integer variables */ - nint = 0; - for (j = 1; j <= mir->cut_vec->nnz; j++) - { k = mir->cut_vec->ind[j]; - xassert(1 <= k && k <= m+n); - if (mir->isint[k]) - { double temp; - nint++; - /* interchange elements [nint] and [j] */ - kk = mir->cut_vec->ind[nint]; - mir->cut_vec->pos[k] = nint; - mir->cut_vec->pos[kk] = j; - mir->cut_vec->ind[nint] = k; - mir->cut_vec->ind[j] = kk; - temp = mir->cut_vec->val[nint]; - mir->cut_vec->val[nint] = mir->cut_vec->val[j]; - mir->cut_vec->val[j] = temp; - } - } -#if _MIR_DEBUG - ios_check_vec(mir->cut_vec); -#endif - /* if there is no integer variable, nothing to generate */ - if (nint == 0) goto done; - /* allocate working arrays */ - u = xcalloc(1+nint, sizeof(double)); - x = xcalloc(1+nint, sizeof(double)); - alpha = xcalloc(1+nint, sizeof(double)); - /* determine u and x */ - for (j = 1; j <= nint; j++) - { k = mir->cut_vec->ind[j]; - xassert(m+1 <= k && k <= m+n); - xassert(mir->isint[k]); - u[j] = mir->ub[k] - mir->lb[k]; - xassert(u[j] >= 1.0); - if (mir->subst[k] == 'L') - x[j] = mir->x[k] - mir->lb[k]; - else if (mir->subst[k] == 'U') - x[j] = mir->ub[k] - mir->x[k]; - else - xassert(k != k); - xassert(x[j] >= -0.001); - if (x[j] < 0.0) x[j] = 0.0; - } - /* compute s = - sum of continuous terms */ - s = 0.0; - for (j = nint+1; j <= mir->cut_vec->nnz; j++) - { double x; - k = mir->cut_vec->ind[j]; - xassert(1 <= k && k <= m+n); - /* must be continuous */ - xassert(!mir->isint[k]); - if (mir->subst[k] == 'L') - { xassert(mir->lb[k] != -DBL_MAX); - kk = mir->vlb[k]; - if (kk == 0) - x = mir->x[k] - mir->lb[k]; - else - x = mir->x[k] - mir->lb[k] * mir->x[kk]; - } - else if (mir->subst[k] == 'U') - { xassert(mir->ub[k] != +DBL_MAX); - kk = mir->vub[k]; - if (kk == 0) - x = mir->ub[k] - mir->x[k]; - else - x = mir->ub[k] * mir->x[kk] - mir->x[k]; - } - else - xassert(k != k); - xassert(x >= -0.001); - if (x < 0.0) x = 0.0; - s -= mir->cut_vec->val[j] * x; - } - xassert(s >= 0.0); - /* apply heuristic to obtain most violated c-MIR inequality */ - b = mir->cut_rhs; - r_best = cmir_sep(nint, mir->cut_vec->val, b, u, x, s, alpha, - &beta, &gamma); - if (r_best == 0.0) goto skip; - xassert(r_best > 0.0); - /* convert to raw cut */ - /* sum alpha[j] * x[j] <= beta + gamma * s */ - for (j = 1; j <= nint; j++) - mir->cut_vec->val[j] = alpha[j]; - for (j = nint+1; j <= mir->cut_vec->nnz; j++) - { k = mir->cut_vec->ind[j]; - if (k <= m+n) mir->cut_vec->val[j] *= gamma; - } - mir->cut_rhs = beta; -#if _MIR_DEBUG - ios_check_vec(mir->cut_vec); -#endif -skip: /* free working arrays */ - xfree(u); - xfree(x); - xfree(alpha); -done: return r_best; -} - -#if _MIR_DEBUG -static void check_raw_cut(struct MIR *mir, double r_best) -{ /* check raw cut before back bound substitution */ - int m = mir->m; - int n = mir->n; - int j, k, kk; - double r, big, x; - /* compute the residual r = sum a[k] * x[k] - b and determine - big = max(1, |a[k]|, |b|) */ - r = 0.0, big = 1.0; - for (j = 1; j <= mir->cut_vec->nnz; j++) - { k = mir->cut_vec->ind[j]; - xassert(1 <= k && k <= m+n); - if (mir->subst[k] == 'L') - { xassert(mir->lb[k] != -DBL_MAX); - kk = mir->vlb[k]; - if (kk == 0) - x = mir->x[k] - mir->lb[k]; - else - x = mir->x[k] - mir->lb[k] * mir->x[kk]; - } - else if (mir->subst[k] == 'U') - { xassert(mir->ub[k] != +DBL_MAX); - kk = mir->vub[k]; - if (kk == 0) - x = mir->ub[k] - mir->x[k]; - else - x = mir->ub[k] * mir->x[kk] - mir->x[k]; - } - else - xassert(k != k); - r += mir->cut_vec->val[j] * x; - if (big < fabs(mir->cut_vec->val[j])) - big = fabs(mir->cut_vec->val[j]); - } - r -= mir->cut_rhs; - if (big < fabs(mir->cut_rhs)) - big = fabs(mir->cut_rhs); - /* the residual must be close to r_best */ - xassert(fabs(r - r_best) <= 1e-6 * big); - return; -} -#endif - -static void back_subst(struct MIR *mir) -{ /* back substitution of original bounds */ - int m = mir->m; - int n = mir->n; - int j, jj, k, kk; - /* at first, restore bounds of integer variables (because on - restoring variable bounds of continuous variables we need - original, not shifted, bounds of integer variables) */ - for (j = 1; j <= mir->cut_vec->nnz; j++) - { k = mir->cut_vec->ind[j]; - xassert(1 <= k && k <= m+n); - if (!mir->isint[k]) continue; /* skip continuous */ - if (mir->subst[k] == 'L') - { /* x'[k] = x[k] - lb[k] */ - xassert(mir->lb[k] != -DBL_MAX); - xassert(mir->vlb[k] == 0); - mir->cut_rhs += mir->cut_vec->val[j] * mir->lb[k]; - } - else if (mir->subst[k] == 'U') - { /* x'[k] = ub[k] - x[k] */ - xassert(mir->ub[k] != +DBL_MAX); - xassert(mir->vub[k] == 0); - mir->cut_rhs -= mir->cut_vec->val[j] * mir->ub[k]; - mir->cut_vec->val[j] = - mir->cut_vec->val[j]; - } - else - xassert(k != k); - } - /* now restore bounds of continuous variables */ - for (j = 1; j <= mir->cut_vec->nnz; j++) - { k = mir->cut_vec->ind[j]; - xassert(1 <= k && k <= m+n); - if (mir->isint[k]) continue; /* skip integer */ - if (mir->subst[k] == 'L') - { /* x'[k] = x[k] - (lower bound) */ - xassert(mir->lb[k] != -DBL_MAX); - kk = mir->vlb[k]; - if (kk == 0) - { /* x'[k] = x[k] - lb[k] */ - mir->cut_rhs += mir->cut_vec->val[j] * mir->lb[k]; - } - else - { /* x'[k] = x[k] - lb[k] * x[kk] */ - jj = mir->cut_vec->pos[kk]; -#if 0 - xassert(jj != 0); -#else - if (jj == 0) - { ios_set_vj(mir->cut_vec, kk, 1.0); - jj = mir->cut_vec->pos[kk]; - xassert(jj != 0); - mir->cut_vec->val[jj] = 0.0; - } -#endif - mir->cut_vec->val[jj] -= mir->cut_vec->val[j] * - mir->lb[k]; - } - } - else if (mir->subst[k] == 'U') - { /* x'[k] = (upper bound) - x[k] */ - xassert(mir->ub[k] != +DBL_MAX); - kk = mir->vub[k]; - if (kk == 0) - { /* x'[k] = ub[k] - x[k] */ - mir->cut_rhs -= mir->cut_vec->val[j] * mir->ub[k]; - } - else - { /* x'[k] = ub[k] * x[kk] - x[k] */ - jj = mir->cut_vec->pos[kk]; - if (jj == 0) - { ios_set_vj(mir->cut_vec, kk, 1.0); - jj = mir->cut_vec->pos[kk]; - xassert(jj != 0); - mir->cut_vec->val[jj] = 0.0; - } - mir->cut_vec->val[jj] += mir->cut_vec->val[j] * - mir->ub[k]; - } - mir->cut_vec->val[j] = - mir->cut_vec->val[j]; - } - else - xassert(k != k); - } -#if _MIR_DEBUG - ios_check_vec(mir->cut_vec); -#endif - return; -} - -#if _MIR_DEBUG -static void check_cut_row(struct MIR *mir, double r_best) -{ /* check the cut after back bound substitution or elimination of - auxiliary variables */ - int m = mir->m; - int n = mir->n; - int j, k; - double r, big; - /* compute the residual r = sum a[k] * x[k] - b and determine - big = max(1, |a[k]|, |b|) */ - r = 0.0, big = 1.0; - for (j = 1; j <= mir->cut_vec->nnz; j++) - { k = mir->cut_vec->ind[j]; - xassert(1 <= k && k <= m+n); - r += mir->cut_vec->val[j] * mir->x[k]; - if (big < fabs(mir->cut_vec->val[j])) - big = fabs(mir->cut_vec->val[j]); - } - r -= mir->cut_rhs; - if (big < fabs(mir->cut_rhs)) - big = fabs(mir->cut_rhs); - /* the residual must be close to r_best */ - xassert(fabs(r - r_best) <= 1e-6 * big); - return; -} -#endif - -static void subst_aux_vars(glp_tree *tree, struct MIR *mir) -{ /* final substitution to eliminate auxiliary variables */ - glp_prob *mip = tree->mip; - int m = mir->m; - int n = mir->n; - GLPAIJ *aij; - int j, k, kk, jj; - for (j = mir->cut_vec->nnz; j >= 1; j--) - { k = mir->cut_vec->ind[j]; - xassert(1 <= k && k <= m+n); - if (k > m) continue; /* skip structurals */ - for (aij = mip->row[k]->ptr; aij != NULL; aij = aij->r_next) - { kk = m + aij->col->j; /* structural */ - jj = mir->cut_vec->pos[kk]; - if (jj == 0) - { ios_set_vj(mir->cut_vec, kk, 1.0); - jj = mir->cut_vec->pos[kk]; - mir->cut_vec->val[jj] = 0.0; - } - mir->cut_vec->val[jj] += mir->cut_vec->val[j] * aij->val; - } - mir->cut_vec->val[j] = 0.0; - } - ios_clean_vec(mir->cut_vec, 0.0); - return; -} - -static void add_cut(glp_tree *tree, struct MIR *mir) -{ /* add constructed cut inequality to the cut pool */ - int m = mir->m; - int n = mir->n; - int j, k, len; - int *ind = xcalloc(1+n, sizeof(int)); - double *val = xcalloc(1+n, sizeof(double)); - len = 0; - for (j = mir->cut_vec->nnz; j >= 1; j--) - { k = mir->cut_vec->ind[j]; - xassert(m+1 <= k && k <= m+n); - len++, ind[len] = k - m, val[len] = mir->cut_vec->val[j]; - } -#if 0 - ios_add_cut_row(tree, pool, GLP_RF_MIR, len, ind, val, GLP_UP, - mir->cut_rhs); -#else - glp_ios_add_row(tree, NULL, GLP_RF_MIR, 0, len, ind, val, GLP_UP, - mir->cut_rhs); -#endif - xfree(ind); - xfree(val); - return; -} - -static int aggregate_row(glp_tree *tree, struct MIR *mir) -{ /* try to aggregate another row */ - glp_prob *mip = tree->mip; - int m = mir->m; - int n = mir->n; - GLPAIJ *aij; - IOSVEC *v; - int ii, j, jj, k, kk, kappa = 0, ret = 0; - double d1, d2, d, d_max = 0.0; - /* choose appropriate structural variable in the aggregated row - to be substituted */ - for (j = 1; j <= mir->agg_vec->nnz; j++) - { k = mir->agg_vec->ind[j]; - xassert(1 <= k && k <= m+n); - if (k <= m) continue; /* skip auxiliary var */ - if (mir->isint[k]) continue; /* skip integer var */ - if (fabs(mir->agg_vec->val[j]) < 0.001) continue; - /* compute distance from x[k] to its lower bound */ - kk = mir->vlb[k]; - if (kk == 0) - { if (mir->lb[k] == -DBL_MAX) - d1 = DBL_MAX; - else - d1 = mir->x[k] - mir->lb[k]; - } - else - { xassert(1 <= kk && kk <= m+n); - xassert(mir->isint[kk]); - xassert(mir->lb[k] != -DBL_MAX); - d1 = mir->x[k] - mir->lb[k] * mir->x[kk]; - } - /* compute distance from x[k] to its upper bound */ - kk = mir->vub[k]; - if (kk == 0) - { if (mir->vub[k] == +DBL_MAX) - d2 = DBL_MAX; - else - d2 = mir->ub[k] - mir->x[k]; - } - else - { xassert(1 <= kk && kk <= m+n); - xassert(mir->isint[kk]); - xassert(mir->ub[k] != +DBL_MAX); - d2 = mir->ub[k] * mir->x[kk] - mir->x[k]; - } - /* x[k] cannot be free */ - xassert(d1 != DBL_MAX || d2 != DBL_MAX); - /* d = min(d1, d2) */ - d = (d1 <= d2 ? d1 : d2); - xassert(d != DBL_MAX); - /* should not be close to corresponding bound */ - if (d < 0.001) continue; - if (d_max < d) d_max = d, kappa = k; - } - if (kappa == 0) - { /* nothing chosen */ - ret = 1; - goto done; - } - /* x[kappa] has been chosen */ - xassert(m+1 <= kappa && kappa <= m+n); - xassert(!mir->isint[kappa]); - /* find another row, which have not been used yet, to eliminate - x[kappa] from the aggregated row */ - for (ii = 1; ii <= m; ii++) - { if (mir->skip[ii]) continue; - for (aij = mip->row[ii]->ptr; aij != NULL; aij = aij->r_next) - if (aij->col->j == kappa - m) break; - if (aij != NULL && fabs(aij->val) >= 0.001) break; - } - if (ii > m) - { /* nothing found */ - ret = 2; - goto done; - } - /* row ii has been found; include it in the aggregated list */ - mir->agg_cnt++; - xassert(mir->agg_cnt <= MAXAGGR); - mir->agg_row[mir->agg_cnt] = ii; - mir->skip[ii] = 2; - /* v := new row */ - v = ios_create_vec(m+n); - ios_set_vj(v, ii, 1.0); - for (aij = mip->row[ii]->ptr; aij != NULL; aij = aij->r_next) - ios_set_vj(v, m + aij->col->j, - aij->val); -#if _MIR_DEBUG - ios_check_vec(v); -#endif - /* perform gaussian elimination to remove x[kappa] */ - j = mir->agg_vec->pos[kappa]; - xassert(j != 0); - jj = v->pos[kappa]; - xassert(jj != 0); - ios_linear_comb(mir->agg_vec, - - mir->agg_vec->val[j] / v->val[jj], v); - ios_delete_vec(v); - ios_set_vj(mir->agg_vec, kappa, 0.0); -#if _MIR_DEBUG - ios_check_vec(mir->agg_vec); -#endif -done: return ret; -} - -void ios_mir_gen(glp_tree *tree, void *gen) -{ /* main routine to generate MIR cuts */ - glp_prob *mip = tree->mip; - struct MIR *mir = gen; - int m = mir->m; - int n = mir->n; - int i; - double r_best; - xassert(mip->m >= m); - xassert(mip->n == n); - /* obtain current point */ - get_current_point(tree, mir); -#if _MIR_DEBUG - /* check current point */ - check_current_point(mir); -#endif - /* reset bound substitution flags */ - memset(&mir->subst[1], '?', m+n); - /* try to generate a set of violated MIR cuts */ - for (i = 1; i <= m; i++) - { if (mir->skip[i]) continue; - /* use original i-th row as initial aggregated constraint */ - initial_agg_row(tree, mir, i); -loop: ; -#if _MIR_DEBUG - /* check aggregated row */ - check_agg_row(mir); -#endif - /* substitute fixed variables into aggregated constraint */ - subst_fixed_vars(mir); -#if _MIR_DEBUG - /* check aggregated row */ - check_agg_row(mir); -#endif -#if _MIR_DEBUG - /* check bound substitution flags */ - { int k; - for (k = 1; k <= m+n; k++) - xassert(mir->subst[k] == '?'); - } -#endif - /* apply bound substitution heuristic */ - bound_subst_heur(mir); - /* substitute bounds and build modified constraint */ - build_mod_row(mir); -#if _MIR_DEBUG - /* check modified row */ - check_mod_row(mir); -#endif - /* try to generate violated c-MIR cut for modified row */ - r_best = generate(mir); - if (r_best > 0.0) - { /* success */ -#if _MIR_DEBUG - /* check raw cut before back bound substitution */ - check_raw_cut(mir, r_best); -#endif - /* back substitution of original bounds */ - back_subst(mir); -#if _MIR_DEBUG - /* check the cut after back bound substitution */ - check_cut_row(mir, r_best); -#endif - /* final substitution to eliminate auxiliary variables */ - subst_aux_vars(tree, mir); -#if _MIR_DEBUG - /* check the cut after elimination of auxiliaries */ - check_cut_row(mir, r_best); -#endif - /* add constructed cut inequality to the cut pool */ - add_cut(tree, mir); - } - /* reset bound substitution flags */ - { int j, k; - for (j = 1; j <= mir->mod_vec->nnz; j++) - { k = mir->mod_vec->ind[j]; - xassert(1 <= k && k <= m+n); - xassert(mir->subst[k] != '?'); - mir->subst[k] = '?'; - } - } - if (r_best == 0.0) - { /* failure */ - if (mir->agg_cnt < MAXAGGR) - { /* try to aggregate another row */ - if (aggregate_row(tree, mir) == 0) goto loop; - } - } - /* unmark rows used in the aggregated constraint */ - { int k, ii; - for (k = 1; k <= mir->agg_cnt; k++) - { ii = mir->agg_row[k]; - xassert(1 <= ii && ii <= m); - xassert(mir->skip[ii] == 2); - mir->skip[ii] = 0; - } - } - } - return; -} - -/*********************************************************************** -* NAME -* -* ios_mir_term - terminate MIR cut generator -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_mir_term(void *gen); -* -* DESCRIPTION -* -* The routine ios_mir_term deletes the MIR cut generator working area -* freeing all the memory allocated to it. */ - -void ios_mir_term(void *gen) -{ struct MIR *mir = gen; - xfree(mir->skip); - xfree(mir->isint); - xfree(mir->lb); - xfree(mir->vlb); - xfree(mir->ub); - xfree(mir->vub); - xfree(mir->x); - xfree(mir->agg_row); - ios_delete_vec(mir->agg_vec); - xfree(mir->subst); - ios_delete_vec(mir->mod_vec); - ios_delete_vec(mir->cut_vec); - xfree(mir); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpios07.c b/resources/3rdparty/glpk-4.53/src/glpios07.c deleted file mode 100644 index 3ea515b67..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpios07.c +++ /dev/null @@ -1,551 +0,0 @@ -/* glpios07.c (mixed cover cut generator) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpios.h" - -/*---------------------------------------------------------------------- --- COVER INEQUALITIES --- --- Consider the set of feasible solutions to 0-1 knapsack problem: --- --- sum a[j]*x[j] <= b, (1) --- j in J --- --- x[j] is binary, (2) --- --- where, wlog, we assume that a[j] > 0 (since 0-1 variables can be --- complemented) and a[j] <= b (since a[j] > b implies x[j] = 0). --- --- A set C within J is called a cover if --- --- sum a[j] > b. (3) --- j in C --- --- For any cover C the inequality --- --- sum x[j] <= |C| - 1 (4) --- j in C --- --- is called a cover inequality and is valid for (1)-(2). --- --- MIXED COVER INEQUALITIES --- --- Consider the set of feasible solutions to mixed knapsack problem: --- --- sum a[j]*x[j] + y <= b, (5) --- j in J --- --- x[j] is binary, (6) --- --- 0 <= y <= u is continuous, (7) --- --- where again we assume that a[j] > 0. --- --- Let C within J be some set. From (1)-(4) it follows that --- --- sum a[j] > b - y (8) --- j in C --- --- implies --- --- sum x[j] <= |C| - 1. (9) --- j in C --- --- Thus, we need to modify the inequality (9) in such a way that it be --- a constraint only if the condition (8) is satisfied. --- --- Consider the following inequality: --- --- sum x[j] <= |C| - t. (10) --- j in C --- --- If 0 < t <= 1, then (10) is equivalent to (9), because all x[j] are --- binary variables. On the other hand, if t <= 0, (10) being satisfied --- for any values of x[j] is not a constraint. --- --- Let --- --- t' = sum a[j] + y - b. (11) --- j in C --- --- It is understood that the condition t' > 0 is equivalent to (8). --- Besides, from (6)-(7) it follows that t' has an implied upper bound: --- --- t'max = sum a[j] + u - b. (12) --- j in C --- --- This allows to express the parameter t having desired properties: --- --- t = t' / t'max. (13) --- --- In fact, t <= 1 by definition, and t > 0 being equivalent to t' > 0 --- is equivalent to (8). --- --- Thus, the inequality (10), where t is given by formula (13) is valid --- for (5)-(7). --- --- Note that if u = 0, then y = 0, so t = 1, and the conditions (8) and --- (10) is transformed to the conditions (3) and (4). --- --- GENERATING MIXED COVER CUTS --- --- To generate a mixed cover cut in the form (10) we need to find such --- set C which satisfies to the inequality (8) and for which, in turn, --- the inequality (10) is violated in the current point. --- --- Substituting t from (13) to (10) gives: --- --- 1 --- sum x[j] <= |C| - ----- (sum a[j] + y - b), (14) --- j in C t'max j in C --- --- and finally we have the cut inequality in the standard form: --- --- sum x[j] + alfa * y <= beta, (15) --- j in C --- --- where: --- --- alfa = 1 / t'max, (16) --- --- beta = |C| - alfa * (sum a[j] - b). (17) --- j in C */ - -#if 1 -#define MAXTRY 1000 -#else -#define MAXTRY 10000 -#endif - -static int cover2(int n, double a[], double b, double u, double x[], - double y, int cov[], double *_alfa, double *_beta) -{ /* try to generate mixed cover cut using two-element cover */ - int i, j, try = 0, ret = 0; - double eps, alfa, beta, temp, rmax = 0.001; - eps = 0.001 * (1.0 + fabs(b)); - for (i = 0+1; i <= n; i++) - for (j = i+1; j <= n; j++) - { /* C = {i, j} */ - try++; - if (try > MAXTRY) goto done; - /* check if condition (8) is satisfied */ - if (a[i] + a[j] + y > b + eps) - { /* compute parameters for inequality (15) */ - temp = a[i] + a[j] - b; - alfa = 1.0 / (temp + u); - beta = 2.0 - alfa * temp; - /* compute violation of inequality (15) */ - temp = x[i] + x[j] + alfa * y - beta; - /* choose C providing maximum violation */ - if (rmax < temp) - { rmax = temp; - cov[1] = i; - cov[2] = j; - *_alfa = alfa; - *_beta = beta; - ret = 1; - } - } - } -done: return ret; -} - -static int cover3(int n, double a[], double b, double u, double x[], - double y, int cov[], double *_alfa, double *_beta) -{ /* try to generate mixed cover cut using three-element cover */ - int i, j, k, try = 0, ret = 0; - double eps, alfa, beta, temp, rmax = 0.001; - eps = 0.001 * (1.0 + fabs(b)); - for (i = 0+1; i <= n; i++) - for (j = i+1; j <= n; j++) - for (k = j+1; k <= n; k++) - { /* C = {i, j, k} */ - try++; - if (try > MAXTRY) goto done; - /* check if condition (8) is satisfied */ - if (a[i] + a[j] + a[k] + y > b + eps) - { /* compute parameters for inequality (15) */ - temp = a[i] + a[j] + a[k] - b; - alfa = 1.0 / (temp + u); - beta = 3.0 - alfa * temp; - /* compute violation of inequality (15) */ - temp = x[i] + x[j] + x[k] + alfa * y - beta; - /* choose C providing maximum violation */ - if (rmax < temp) - { rmax = temp; - cov[1] = i; - cov[2] = j; - cov[3] = k; - *_alfa = alfa; - *_beta = beta; - ret = 1; - } - } - } -done: return ret; -} - -static int cover4(int n, double a[], double b, double u, double x[], - double y, int cov[], double *_alfa, double *_beta) -{ /* try to generate mixed cover cut using four-element cover */ - int i, j, k, l, try = 0, ret = 0; - double eps, alfa, beta, temp, rmax = 0.001; - eps = 0.001 * (1.0 + fabs(b)); - for (i = 0+1; i <= n; i++) - for (j = i+1; j <= n; j++) - for (k = j+1; k <= n; k++) - for (l = k+1; l <= n; l++) - { /* C = {i, j, k, l} */ - try++; - if (try > MAXTRY) goto done; - /* check if condition (8) is satisfied */ - if (a[i] + a[j] + a[k] + a[l] + y > b + eps) - { /* compute parameters for inequality (15) */ - temp = a[i] + a[j] + a[k] + a[l] - b; - alfa = 1.0 / (temp + u); - beta = 4.0 - alfa * temp; - /* compute violation of inequality (15) */ - temp = x[i] + x[j] + x[k] + x[l] + alfa * y - beta; - /* choose C providing maximum violation */ - if (rmax < temp) - { rmax = temp; - cov[1] = i; - cov[2] = j; - cov[3] = k; - cov[4] = l; - *_alfa = alfa; - *_beta = beta; - ret = 1; - } - } - } -done: return ret; -} - -static int cover(int n, double a[], double b, double u, double x[], - double y, int cov[], double *alfa, double *beta) -{ /* try to generate mixed cover cut; - input (see (5)): - n is the number of binary variables; - a[1:n] are coefficients at binary variables; - b is the right-hand side; - u is upper bound of continuous variable; - x[1:n] are values of binary variables at current point; - y is value of continuous variable at current point; - output (see (15), (16), (17)): - cov[1:r] are indices of binary variables included in cover C, - where r is the set cardinality returned on exit; - alfa coefficient at continuous variable; - beta is the right-hand side; */ - int j; - /* perform some sanity checks */ - xassert(n >= 2); - for (j = 1; j <= n; j++) xassert(a[j] > 0.0); -#if 1 /* ??? */ - xassert(b > -1e-5); -#else - xassert(b > 0.0); -#endif - xassert(u >= 0.0); - for (j = 1; j <= n; j++) xassert(0.0 <= x[j] && x[j] <= 1.0); - xassert(0.0 <= y && y <= u); - /* try to generate mixed cover cut */ - if (cover2(n, a, b, u, x, y, cov, alfa, beta)) return 2; - if (cover3(n, a, b, u, x, y, cov, alfa, beta)) return 3; - if (cover4(n, a, b, u, x, y, cov, alfa, beta)) return 4; - return 0; -} - -/*---------------------------------------------------------------------- --- lpx_cover_cut - generate mixed cover cut. --- --- SYNOPSIS --- --- int lpx_cover_cut(LPX *lp, int len, int ind[], double val[], --- double work[]); --- --- DESCRIPTION --- --- The routine lpx_cover_cut generates a mixed cover cut for a given --- row of the MIP problem. --- --- The given row of the MIP problem should be explicitly specified in --- the form: --- --- sum{j in J} a[j]*x[j] <= b. (1) --- --- On entry indices (ordinal numbers) of structural variables, which --- have non-zero constraint coefficients, should be placed in locations --- ind[1], ..., ind[len], and corresponding constraint coefficients --- should be placed in locations val[1], ..., val[len]. The right-hand --- side b should be stored in location val[0]. --- --- The working array work should have at least nb locations, where nb --- is the number of binary variables in (1). --- --- The routine generates a mixed cover cut in the same form as (1) and --- stores the cut coefficients and right-hand side in the same way as --- just described above. --- --- RETURNS --- --- If the cutting plane has been successfully generated, the routine --- returns 1 <= len' <= n, which is the number of non-zero coefficients --- in the inequality constraint. Otherwise, the routine returns zero. */ - -static int lpx_cover_cut(glp_prob *lp, int len, int ind[], - double val[], double work[]) -{ int cov[1+4], j, k, nb, newlen, r; - double f_min, f_max, alfa, beta, u, *x = work, y; - /* substitute and remove fixed variables */ - newlen = 0; - for (k = 1; k <= len; k++) - { j = ind[k]; - if (glp_get_col_type(lp, j) == GLP_FX) - val[0] -= val[k] * glp_get_col_lb(lp, j); - else - { newlen++; - ind[newlen] = ind[k]; - val[newlen] = val[k]; - } - } - len = newlen; - /* move binary variables to the beginning of the list so that - elements 1, 2, ..., nb correspond to binary variables, and - elements nb+1, nb+2, ..., len correspond to rest variables */ - nb = 0; - for (k = 1; k <= len; k++) - { j = ind[k]; - if (glp_get_col_kind(lp, j) == GLP_BV) - { /* binary variable */ - int ind_k; - double val_k; - nb++; - ind_k = ind[nb], val_k = val[nb]; - ind[nb] = ind[k], val[nb] = val[k]; - ind[k] = ind_k, val[k] = val_k; - } - } - /* now the specified row has the form: - sum a[j]*x[j] + sum a[j]*y[j] <= b, - where x[j] are binary variables, y[j] are rest variables */ - /* at least two binary variables are needed */ - if (nb < 2) return 0; - /* compute implied lower and upper bounds for sum a[j]*y[j] */ - f_min = f_max = 0.0; - for (k = nb+1; k <= len; k++) - { j = ind[k]; - /* both bounds must be finite */ - if (glp_get_col_type(lp, j) != GLP_DB) return 0; - if (val[k] > 0.0) - { f_min += val[k] * glp_get_col_lb(lp, j); - f_max += val[k] * glp_get_col_ub(lp, j); - } - else - { f_min += val[k] * glp_get_col_ub(lp, j); - f_max += val[k] * glp_get_col_lb(lp, j); - } - } - /* sum a[j]*x[j] + sum a[j]*y[j] <= b ===> - sum a[j]*x[j] + (sum a[j]*y[j] - f_min) <= b - f_min ===> - sum a[j]*x[j] + y <= b - f_min, - where y = sum a[j]*y[j] - f_min; - note that 0 <= y <= u, u = f_max - f_min */ - /* determine upper bound of y */ - u = f_max - f_min; - /* determine value of y at the current point */ - y = 0.0; - for (k = nb+1; k <= len; k++) - { j = ind[k]; - y += val[k] * glp_get_col_prim(lp, j); - } - y -= f_min; - if (y < 0.0) y = 0.0; - if (y > u) y = u; - /* modify the right-hand side b */ - val[0] -= f_min; - /* now the transformed row has the form: - sum a[j]*x[j] + y <= b, where 0 <= y <= u */ - /* determine values of x[j] at the current point */ - for (k = 1; k <= nb; k++) - { j = ind[k]; - x[k] = glp_get_col_prim(lp, j); - if (x[k] < 0.0) x[k] = 0.0; - if (x[k] > 1.0) x[k] = 1.0; - } - /* if a[j] < 0, replace x[j] by its complement 1 - x'[j] */ - for (k = 1; k <= nb; k++) - { if (val[k] < 0.0) - { ind[k] = - ind[k]; - val[k] = - val[k]; - val[0] += val[k]; - x[k] = 1.0 - x[k]; - } - } - /* try to generate a mixed cover cut for the transformed row */ - r = cover(nb, val, val[0], u, x, y, cov, &alfa, &beta); - if (r == 0) return 0; - xassert(2 <= r && r <= 4); - /* now the cut is in the form: - sum{j in C} x[j] + alfa * y <= beta */ - /* store the right-hand side beta */ - ind[0] = 0, val[0] = beta; - /* restore the original ordinal numbers of x[j] */ - for (j = 1; j <= r; j++) cov[j] = ind[cov[j]]; - /* store cut coefficients at binary variables complementing back - the variables having negative row coefficients */ - xassert(r <= nb); - for (k = 1; k <= r; k++) - { if (cov[k] > 0) - { ind[k] = +cov[k]; - val[k] = +1.0; - } - else - { ind[k] = -cov[k]; - val[k] = -1.0; - val[0] -= 1.0; - } - } - /* substitute y = sum a[j]*y[j] - f_min */ - for (k = nb+1; k <= len; k++) - { r++; - ind[r] = ind[k]; - val[r] = alfa * val[k]; - } - val[0] += alfa * f_min; - xassert(r <= len); - len = r; - return len; -} - -/*---------------------------------------------------------------------- --- lpx_eval_row - compute explictily specified row. --- --- SYNOPSIS --- --- double lpx_eval_row(LPX *lp, int len, int ind[], double val[]); --- --- DESCRIPTION --- --- The routine lpx_eval_row computes the primal value of an explicitly --- specified row using current values of structural variables. --- --- The explicitly specified row may be thought as a linear form: --- --- y = a[1]*x[m+1] + a[2]*x[m+2] + ... + a[n]*x[m+n], --- --- where y is an auxiliary variable for this row, a[j] are coefficients --- of the linear form, x[m+j] are structural variables. --- --- On entry column indices and numerical values of non-zero elements of --- the row should be stored in locations ind[1], ..., ind[len] and --- val[1], ..., val[len], where len is the number of non-zero elements. --- The array ind and val are not changed on exit. --- --- RETURNS --- --- The routine returns a computed value of y, the auxiliary variable of --- the specified row. */ - -static double lpx_eval_row(glp_prob *lp, int len, int ind[], - double val[]) -{ int n = glp_get_num_cols(lp); - int j, k; - double sum = 0.0; - if (len < 0) - xerror("lpx_eval_row: len = %d; invalid row length\n", len); - for (k = 1; k <= len; k++) - { j = ind[k]; - if (!(1 <= j && j <= n)) - xerror("lpx_eval_row: j = %d; column number out of range\n", - j); - sum += val[k] * glp_get_col_prim(lp, j); - } - return sum; -} - -/*********************************************************************** -* NAME -* -* ios_cov_gen - generate mixed cover cuts -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_cov_gen(glp_tree *tree); -* -* DESCRIPTION -* -* The routine ios_cov_gen generates mixed cover cuts for the current -* point and adds them to the cut pool. */ - -void ios_cov_gen(glp_tree *tree) -{ glp_prob *prob = tree->mip; - int m = glp_get_num_rows(prob); - int n = glp_get_num_cols(prob); - int i, k, type, kase, len, *ind; - double r, *val, *work; - xassert(glp_get_status(prob) == GLP_OPT); - /* allocate working arrays */ - ind = xcalloc(1+n, sizeof(int)); - val = xcalloc(1+n, sizeof(double)); - work = xcalloc(1+n, sizeof(double)); - /* look through all rows */ - for (i = 1; i <= m; i++) - for (kase = 1; kase <= 2; kase++) - { type = glp_get_row_type(prob, i); - if (kase == 1) - { /* consider rows of '<=' type */ - if (!(type == GLP_UP || type == GLP_DB)) continue; - len = glp_get_mat_row(prob, i, ind, val); - val[0] = glp_get_row_ub(prob, i); - } - else - { /* consider rows of '>=' type */ - if (!(type == GLP_LO || type == GLP_DB)) continue; - len = glp_get_mat_row(prob, i, ind, val); - for (k = 1; k <= len; k++) val[k] = - val[k]; - val[0] = - glp_get_row_lb(prob, i); - } - /* generate mixed cover cut: - sum{j in J} a[j] * x[j] <= b */ - len = lpx_cover_cut(prob, len, ind, val, work); - if (len == 0) continue; - /* at the current point the cut inequality is violated, i.e. - sum{j in J} a[j] * x[j] - b > 0 */ - r = lpx_eval_row(prob, len, ind, val) - val[0]; - if (r < 1e-3) continue; - /* add the cut to the cut pool */ - glp_ios_add_row(tree, NULL, GLP_RF_COV, 0, len, ind, val, - GLP_UP, val[0]); - } - /* free working arrays */ - xfree(ind); - xfree(val); - xfree(work); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpios08.c b/resources/3rdparty/glpk-4.53/src/glpios08.c deleted file mode 100644 index d165492f7..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpios08.c +++ /dev/null @@ -1,147 +0,0 @@ -/* glpios08.c (clique cut generator) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2008, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "cfg.h" -#include "env.h" -#include "glpios.h" - -void *ios_clq_init(glp_tree *T) -{ /* initialize clique cut generator */ - glp_prob *P = T->mip; - CFG *G; - int j, n1, n2; - xprintf("Constructing conflict graph...\n"); - G = cfg_build_graph(P); - n1 = n2 = 0; - for (j = 1; j <= P->n; j++) - { if (G->pos[j]) - n1 ++; - if (G->neg[j]) - n2++; - } - if (n1 == 0 && n2 == 0) - { xprintf("No conflicts found\n"); - cfg_delete_graph(G); - G = NULL; - } - else - xprintf("Conflict graph has %d + %d = %d vertices\n", - n1, n2, G->nv); - return G; -} - -void ios_clq_gen(glp_tree *T, void *G_) -{ /* attempt to generate clique cut */ - glp_prob *P = T->mip; - int n = P->n; - CFG *G = G_; - int *pos = G->pos; - int *neg = G->neg; - int nv = G->nv; - int *ref = G->ref; - int j, k, v, len, *ind; - double rhs, sum, *val; - xassert(G->n == n); - /* allocate working arrays */ - ind = talloc(1+n, int); - val = talloc(1+n, double); - /* find maximum weight clique in conflict graph */ - len = cfg_find_clique(P, G, ind, &sum); -#ifdef GLP_DEBUG - xprintf("len = %d; sum = %g\n", len, sum); - cfg_check_clique(G, len, ind); -#endif - /* check if clique inequality is violated */ - if (sum < 1.07) - goto skip; - /* expand clique to maximal one */ - len = cfg_expand_clique(G, len, ind); -#ifdef GLP_DEBUG - xprintf("maximal clique size = %d\n", len); - cfg_check_clique(G, len, ind); -#endif - /* construct clique cut (fixed binary variables are removed, so - this cut is only locally valid) */ - rhs = 1.0; - for (j = 1; j <= n; j++) - val[j] = 0.0; - for (k = 1; k <= len; k++) - { /* v is clique vertex */ - v = ind[k]; - xassert(1 <= v && v <= nv); - /* j is number of corresponding binary variable */ - j = ref[v]; - xassert(1 <= j && j <= n); - if (pos[j] == v) - { /* v corresponds to x[j] */ - if (P->col[j]->type == GLP_FX) - { /* x[j] is fixed */ - rhs -= P->col[j]->prim; - } - else - { /* x[j] is not fixed */ - val[j] += 1.0; - } - } - else if (neg[j] == v) - { /* v corresponds to (1 - x[j]) */ - if (P->col[j]->type == GLP_FX) - { /* x[j] is fixed */ - rhs -= (1.0 - P->col[j]->prim); - } - else - { /* x[j] is not fixed */ - val[j] -= 1.0; - rhs -= 1.0; - } - } - else - xassert(v != v); - } - /* convert cut inequality to sparse format */ - len = 0; - for (j = 1; j <= n; j++) - { if (val[j] != 0.0) - { len++; - ind[len] = j; - val[len] = val[j]; - } - } - /* add cut inequality to local cut pool */ - glp_ios_add_row(T, NULL, GLP_RF_CLQ, 0, len, ind, val, GLP_UP, - rhs); -skip: /* free working arrays */ - tfree(ind); - tfree(val); - return; -} - -void ios_clq_term(void *G_) -{ /* terminate clique cut generator */ - CFG *G = G_; - xassert(G != NULL); - cfg_delete_graph(G); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpios09.c b/resources/3rdparty/glpk-4.53/src/glpios09.c deleted file mode 100644 index d87578cbc..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpios09.c +++ /dev/null @@ -1,664 +0,0 @@ -/* glpios09.c (branching heuristics) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpios.h" - -/*********************************************************************** -* NAME -* -* ios_choose_var - select variable to branch on -* -* SYNOPSIS -* -* #include "glpios.h" -* int ios_choose_var(glp_tree *T, int *next); -* -* The routine ios_choose_var chooses a variable from the candidate -* list to branch on. Additionally the routine provides a flag stored -* in the location next to suggests which of the child subproblems -* should be solved next. -* -* RETURNS -* -* The routine ios_choose_var returns the ordinal number of the column -* choosen. */ - -static int branch_first(glp_tree *T, int *next); -static int branch_last(glp_tree *T, int *next); -static int branch_mostf(glp_tree *T, int *next); -static int branch_drtom(glp_tree *T, int *next); - -int ios_choose_var(glp_tree *T, int *next) -{ int j; - if (T->parm->br_tech == GLP_BR_FFV) - { /* branch on first fractional variable */ - j = branch_first(T, next); - } - else if (T->parm->br_tech == GLP_BR_LFV) - { /* branch on last fractional variable */ - j = branch_last(T, next); - } - else if (T->parm->br_tech == GLP_BR_MFV) - { /* branch on most fractional variable */ - j = branch_mostf(T, next); - } - else if (T->parm->br_tech == GLP_BR_DTH) - { /* branch using the heuristic by Dreebeck and Tomlin */ - j = branch_drtom(T, next); - } - else if (T->parm->br_tech == GLP_BR_PCH) - { /* hybrid pseudocost heuristic */ - j = ios_pcost_branch(T, next); - } - else - xassert(T != T); - return j; -} - -/*********************************************************************** -* branch_first - choose first branching variable -* -* This routine looks up the list of structural variables and chooses -* the first one, which is of integer kind and has fractional value in -* optimal solution to the current LP relaxation. -* -* This routine also selects the branch to be solved next where integer -* infeasibility of the chosen variable is less than in other one. */ - -static int branch_first(glp_tree *T, int *_next) -{ int j, next; - double beta; - /* choose the column to branch on */ - for (j = 1; j <= T->n; j++) - if (T->non_int[j]) break; - xassert(1 <= j && j <= T->n); - /* select the branch to be solved next */ - beta = glp_get_col_prim(T->mip, j); - if (beta - floor(beta) < ceil(beta) - beta) - next = GLP_DN_BRNCH; - else - next = GLP_UP_BRNCH; - *_next = next; - return j; -} - -/*********************************************************************** -* branch_last - choose last branching variable -* -* This routine looks up the list of structural variables and chooses -* the last one, which is of integer kind and has fractional value in -* optimal solution to the current LP relaxation. -* -* This routine also selects the branch to be solved next where integer -* infeasibility of the chosen variable is less than in other one. */ - -static int branch_last(glp_tree *T, int *_next) -{ int j, next; - double beta; - /* choose the column to branch on */ - for (j = T->n; j >= 1; j--) - if (T->non_int[j]) break; - xassert(1 <= j && j <= T->n); - /* select the branch to be solved next */ - beta = glp_get_col_prim(T->mip, j); - if (beta - floor(beta) < ceil(beta) - beta) - next = GLP_DN_BRNCH; - else - next = GLP_UP_BRNCH; - *_next = next; - return j; -} - -/*********************************************************************** -* branch_mostf - choose most fractional branching variable -* -* This routine looks up the list of structural variables and chooses -* that one, which is of integer kind and has most fractional value in -* optimal solution to the current LP relaxation. -* -* This routine also selects the branch to be solved next where integer -* infeasibility of the chosen variable is less than in other one. -* -* (Alexander Martin notices that "...most infeasible is as good as -* random...".) */ - -static int branch_mostf(glp_tree *T, int *_next) -{ int j, jj, next; - double beta, most, temp; - /* choose the column to branch on */ - jj = 0, most = DBL_MAX; - for (j = 1; j <= T->n; j++) - { if (T->non_int[j]) - { beta = glp_get_col_prim(T->mip, j); - temp = floor(beta) + 0.5; - if (most > fabs(beta - temp)) - { jj = j, most = fabs(beta - temp); - if (beta < temp) - next = GLP_DN_BRNCH; - else - next = GLP_UP_BRNCH; - } - } - } - *_next = next; - return jj; -} - -/*********************************************************************** -* branch_drtom - choose branching var using Driebeck-Tomlin heuristic -* -* This routine chooses a structural variable, which is required to be -* integral and has fractional value in optimal solution of the current -* LP relaxation, using a heuristic proposed by Driebeck and Tomlin. -* -* The routine also selects the branch to be solved next, again due to -* Driebeck and Tomlin. -* -* This routine is based on the heuristic proposed in: -* -* Driebeck N.J. An algorithm for the solution of mixed-integer -* programming problems, Management Science, 12: 576-87 (1966); -* -* and improved in: -* -* Tomlin J.A. Branch and bound methods for integer and non-convex -* programming, in J.Abadie (ed.), Integer and Nonlinear Programming, -* North-Holland, Amsterdam, pp. 437-50 (1970). -* -* Must note that this heuristic is time-expensive, because computing -* one-step degradation (see the routine below) requires one BTRAN for -* each fractional-valued structural variable. */ - -static int branch_drtom(glp_tree *T, int *_next) -{ glp_prob *mip = T->mip; - int m = mip->m; - int n = mip->n; - unsigned char *non_int = T->non_int; - int j, jj, k, t, next, kase, len, stat, *ind; - double x, dk, alfa, delta_j, delta_k, delta_z, dz_dn, dz_up, - dd_dn, dd_up, degrad, *val; - /* basic solution of LP relaxation must be optimal */ - xassert(glp_get_status(mip) == GLP_OPT); - /* allocate working arrays */ - ind = xcalloc(1+n, sizeof(int)); - val = xcalloc(1+n, sizeof(double)); - /* nothing has been chosen so far */ - jj = 0, degrad = -1.0; - /* walk through the list of columns (structural variables) */ - for (j = 1; j <= n; j++) - { /* if j-th column is not marked as fractional, skip it */ - if (!non_int[j]) continue; - /* obtain (fractional) value of j-th column in basic solution - of LP relaxation */ - x = glp_get_col_prim(mip, j); - /* since the value of j-th column is fractional, the column is - basic; compute corresponding row of the simplex table */ - len = glp_eval_tab_row(mip, m+j, ind, val); - /* the following fragment computes a change in the objective - function: delta Z = new Z - old Z, where old Z is the - objective value in the current optimal basis, and new Z is - the objective value in the adjacent basis, for two cases: - 1) if new upper bound ub' = floor(x[j]) is introduced for - j-th column (down branch); - 2) if new lower bound lb' = ceil(x[j]) is introduced for - j-th column (up branch); - since in both cases the solution remaining dual feasible - becomes primal infeasible, one implicit simplex iteration - is performed to determine the change delta Z; - it is obvious that new Z, which is never better than old Z, - is a lower (minimization) or upper (maximization) bound of - the objective function for down- and up-branches. */ - for (kase = -1; kase <= +1; kase += 2) - { /* if kase < 0, the new upper bound of x[j] is introduced; - in this case x[j] should decrease in order to leave the - basis and go to its new upper bound */ - /* if kase > 0, the new lower bound of x[j] is introduced; - in this case x[j] should increase in order to leave the - basis and go to its new lower bound */ - /* apply the dual ratio test in order to determine which - auxiliary or structural variable should enter the basis - to keep dual feasibility */ - k = glp_dual_rtest(mip, len, ind, val, kase, 1e-9); - if (k != 0) k = ind[k]; - /* if no non-basic variable has been chosen, LP relaxation - of corresponding branch being primal infeasible and dual - unbounded has no primal feasible solution; in this case - the change delta Z is formally set to infinity */ - if (k == 0) - { delta_z = - (T->mip->dir == GLP_MIN ? +DBL_MAX : -DBL_MAX); - goto skip; - } - /* row of the simplex table that corresponds to non-basic - variable x[k] choosen by the dual ratio test is: - x[j] = ... + alfa * x[k] + ... - where alfa is the influence coefficient (an element of - the simplex table row) */ - /* determine the coefficient alfa */ - for (t = 1; t <= len; t++) if (ind[t] == k) break; - xassert(1 <= t && t <= len); - alfa = val[t]; - /* since in the adjacent basis the variable x[j] becomes - non-basic, knowing its value in the current basis we can - determine its change delta x[j] = new x[j] - old x[j] */ - delta_j = (kase < 0 ? floor(x) : ceil(x)) - x; - /* and knowing the coefficient alfa we can determine the - corresponding change delta x[k] = new x[k] - old x[k], - where old x[k] is a value of x[k] in the current basis, - and new x[k] is a value of x[k] in the adjacent basis */ - delta_k = delta_j / alfa; - /* Tomlin noticed that if the variable x[k] is of integer - kind, its change cannot be less (eventually) than one in - the magnitude */ - if (k > m && glp_get_col_kind(mip, k-m) != GLP_CV) - { /* x[k] is structural integer variable */ - if (fabs(delta_k - floor(delta_k + 0.5)) > 1e-3) - { if (delta_k > 0.0) - delta_k = ceil(delta_k); /* +3.14 -> +4 */ - else - delta_k = floor(delta_k); /* -3.14 -> -4 */ - } - } - /* now determine the status and reduced cost of x[k] in the - current basis */ - if (k <= m) - { stat = glp_get_row_stat(mip, k); - dk = glp_get_row_dual(mip, k); - } - else - { stat = glp_get_col_stat(mip, k-m); - dk = glp_get_col_dual(mip, k-m); - } - /* if the current basis is dual degenerate, some reduced - costs which are close to zero may have wrong sign due to - round-off errors, so correct the sign of d[k] */ - switch (T->mip->dir) - { case GLP_MIN: - if (stat == GLP_NL && dk < 0.0 || - stat == GLP_NU && dk > 0.0 || - stat == GLP_NF) dk = 0.0; - break; - case GLP_MAX: - if (stat == GLP_NL && dk > 0.0 || - stat == GLP_NU && dk < 0.0 || - stat == GLP_NF) dk = 0.0; - break; - default: - xassert(T != T); - } - /* now knowing the change of x[k] and its reduced cost d[k] - we can compute the corresponding change in the objective - function delta Z = new Z - old Z = d[k] * delta x[k]; - note that due to Tomlin's modification new Z can be even - worse than in the adjacent basis */ - delta_z = dk * delta_k; -skip: /* new Z is never better than old Z, therefore the change - delta Z is always non-negative (in case of minimization) - or non-positive (in case of maximization) */ - switch (T->mip->dir) - { case GLP_MIN: xassert(delta_z >= 0.0); break; - case GLP_MAX: xassert(delta_z <= 0.0); break; - default: xassert(T != T); - } - /* save the change in the objective fnction for down- and - up-branches, respectively */ - if (kase < 0) dz_dn = delta_z; else dz_up = delta_z; - } - /* thus, in down-branch no integer feasible solution can be - better than Z + dz_dn, and in up-branch no integer feasible - solution can be better than Z + dz_up, where Z is value of - the objective function in the current basis */ - /* following the heuristic by Driebeck and Tomlin we choose a - column (i.e. structural variable) which provides largest - degradation of the objective function in some of branches; - besides, we select the branch with smaller degradation to - be solved next and keep other branch with larger degradation - in the active list hoping to minimize the number of further - backtrackings */ - if (degrad < fabs(dz_dn) || degrad < fabs(dz_up)) - { jj = j; - if (fabs(dz_dn) < fabs(dz_up)) - { /* select down branch to be solved next */ - next = GLP_DN_BRNCH; - degrad = fabs(dz_up); - } - else - { /* select up branch to be solved next */ - next = GLP_UP_BRNCH; - degrad = fabs(dz_dn); - } - /* save the objective changes for printing */ - dd_dn = dz_dn, dd_up = dz_up; - /* if down- or up-branch has no feasible solution, we does - not need to consider other candidates (in principle, the - corresponding branch could be pruned right now) */ - if (degrad == DBL_MAX) break; - } - } - /* free working arrays */ - xfree(ind); - xfree(val); - /* something must be chosen */ - xassert(1 <= jj && jj <= n); -#if 1 /* 02/XI-2009 */ - if (degrad < 1e-6 * (1.0 + 0.001 * fabs(mip->obj_val))) - { jj = branch_mostf(T, &next); - goto done; - } -#endif - if (T->parm->msg_lev >= GLP_MSG_DBG) - { xprintf("branch_drtom: column %d chosen to branch on\n", jj); - if (fabs(dd_dn) == DBL_MAX) - xprintf("branch_drtom: down-branch is infeasible\n"); - else - xprintf("branch_drtom: down-branch bound is %.9e\n", - glp_get_obj_val(mip) + dd_dn); - if (fabs(dd_up) == DBL_MAX) - xprintf("branch_drtom: up-branch is infeasible\n"); - else - xprintf("branch_drtom: up-branch bound is %.9e\n", - glp_get_obj_val(mip) + dd_up); - } -done: *_next = next; - return jj; -} - -/**********************************************************************/ - -struct csa -{ /* common storage area */ - int *dn_cnt; /* int dn_cnt[1+n]; */ - /* dn_cnt[j] is the number of subproblems, whose LP relaxations - have been solved and which are down-branches for variable x[j]; - dn_cnt[j] = 0 means the down pseudocost is uninitialized */ - double *dn_sum; /* double dn_sum[1+n]; */ - /* dn_sum[j] is the sum of per unit degradations of the objective - over all dn_cnt[j] subproblems */ - int *up_cnt; /* int up_cnt[1+n]; */ - /* up_cnt[j] is the number of subproblems, whose LP relaxations - have been solved and which are up-branches for variable x[j]; - up_cnt[j] = 0 means the up pseudocost is uninitialized */ - double *up_sum; /* double up_sum[1+n]; */ - /* up_sum[j] is the sum of per unit degradations of the objective - over all up_cnt[j] subproblems */ -}; - -void *ios_pcost_init(glp_tree *tree) -{ /* initialize working data used on pseudocost branching */ - struct csa *csa; - int n = tree->n, j; - csa = xmalloc(sizeof(struct csa)); - csa->dn_cnt = xcalloc(1+n, sizeof(int)); - csa->dn_sum = xcalloc(1+n, sizeof(double)); - csa->up_cnt = xcalloc(1+n, sizeof(int)); - csa->up_sum = xcalloc(1+n, sizeof(double)); - for (j = 1; j <= n; j++) - { csa->dn_cnt[j] = csa->up_cnt[j] = 0; - csa->dn_sum[j] = csa->up_sum[j] = 0.0; - } - return csa; -} - -static double eval_degrad(glp_prob *P, int j, double bnd) -{ /* compute degradation of the objective on fixing x[j] at given - value with a limited number of dual simplex iterations */ - /* this routine fixes column x[j] at specified value bnd, - solves resulting LP, and returns a lower bound to degradation - of the objective, degrad >= 0 */ - glp_prob *lp; - glp_smcp parm; - int ret; - double degrad; - /* the current basis must be optimal */ - xassert(glp_get_status(P) == GLP_OPT); - /* create a copy of P */ - lp = glp_create_prob(); - glp_copy_prob(lp, P, 0); - /* fix column x[j] at specified value */ - glp_set_col_bnds(lp, j, GLP_FX, bnd, bnd); - /* try to solve resulting LP */ - glp_init_smcp(&parm); - parm.msg_lev = GLP_MSG_OFF; - parm.meth = GLP_DUAL; - parm.it_lim = 30; - parm.out_dly = 1000; - parm.meth = GLP_DUAL; - ret = glp_simplex(lp, &parm); - if (ret == 0 || ret == GLP_EITLIM) - { if (glp_get_prim_stat(lp) == GLP_NOFEAS) - { /* resulting LP has no primal feasible solution */ - degrad = DBL_MAX; - } - else if (glp_get_dual_stat(lp) == GLP_FEAS) - { /* resulting basis is optimal or at least dual feasible, - so we have the correct lower bound to degradation */ - if (P->dir == GLP_MIN) - degrad = lp->obj_val - P->obj_val; - else if (P->dir == GLP_MAX) - degrad = P->obj_val - lp->obj_val; - else - xassert(P != P); - /* degradation cannot be negative by definition */ - /* note that the lower bound to degradation may be close - to zero even if its exact value is zero due to round-off - errors on computing the objective value */ - if (degrad < 1e-6 * (1.0 + 0.001 * fabs(P->obj_val))) - degrad = 0.0; - } - else - { /* the final basis reported by the simplex solver is dual - infeasible, so we cannot determine a non-trivial lower - bound to degradation */ - degrad = 0.0; - } - } - else - { /* the simplex solver failed */ - degrad = 0.0; - } - /* delete the copy of P */ - glp_delete_prob(lp); - return degrad; -} - -void ios_pcost_update(glp_tree *tree) -{ /* update history information for pseudocost branching */ - /* this routine is called every time when LP relaxation of the - current subproblem has been solved to optimality with all lazy - and cutting plane constraints included */ - int j; - double dx, dz, psi; - struct csa *csa = tree->pcost; - xassert(csa != NULL); - xassert(tree->curr != NULL); - /* if the current subproblem is the root, skip updating */ - if (tree->curr->up == NULL) goto skip; - /* determine branching variable x[j], which was used in the - parent subproblem to create the current subproblem */ - j = tree->curr->up->br_var; - xassert(1 <= j && j <= tree->n); - /* determine the change dx[j] = new x[j] - old x[j], - where new x[j] is a value of x[j] in optimal solution to LP - relaxation of the current subproblem, old x[j] is a value of - x[j] in optimal solution to LP relaxation of the parent - subproblem */ - dx = tree->mip->col[j]->prim - tree->curr->up->br_val; - xassert(dx != 0.0); - /* determine corresponding change dz = new dz - old dz in the - objective function value */ - dz = tree->mip->obj_val - tree->curr->up->lp_obj; - /* determine per unit degradation of the objective function */ - psi = fabs(dz / dx); - /* update history information */ - if (dx < 0.0) - { /* the current subproblem is down-branch */ - csa->dn_cnt[j]++; - csa->dn_sum[j] += psi; - } - else /* dx > 0.0 */ - { /* the current subproblem is up-branch */ - csa->up_cnt[j]++; - csa->up_sum[j] += psi; - } -skip: return; -} - -void ios_pcost_free(glp_tree *tree) -{ /* free working area used on pseudocost branching */ - struct csa *csa = tree->pcost; - xassert(csa != NULL); - xfree(csa->dn_cnt); - xfree(csa->dn_sum); - xfree(csa->up_cnt); - xfree(csa->up_sum); - xfree(csa); - tree->pcost = NULL; - return; -} - -static double eval_psi(glp_tree *T, int j, int brnch) -{ /* compute estimation of pseudocost of variable x[j] for down- - or up-branch */ - struct csa *csa = T->pcost; - double beta, degrad, psi; - xassert(csa != NULL); - xassert(1 <= j && j <= T->n); - if (brnch == GLP_DN_BRNCH) - { /* down-branch */ - if (csa->dn_cnt[j] == 0) - { /* initialize down pseudocost */ - beta = T->mip->col[j]->prim; - degrad = eval_degrad(T->mip, j, floor(beta)); - if (degrad == DBL_MAX) - { psi = DBL_MAX; - goto done; - } - csa->dn_cnt[j] = 1; - csa->dn_sum[j] = degrad / (beta - floor(beta)); - } - psi = csa->dn_sum[j] / (double)csa->dn_cnt[j]; - } - else if (brnch == GLP_UP_BRNCH) - { /* up-branch */ - if (csa->up_cnt[j] == 0) - { /* initialize up pseudocost */ - beta = T->mip->col[j]->prim; - degrad = eval_degrad(T->mip, j, ceil(beta)); - if (degrad == DBL_MAX) - { psi = DBL_MAX; - goto done; - } - csa->up_cnt[j] = 1; - csa->up_sum[j] = degrad / (ceil(beta) - beta); - } - psi = csa->up_sum[j] / (double)csa->up_cnt[j]; - } - else - xassert(brnch != brnch); -done: return psi; -} - -static void progress(glp_tree *T) -{ /* display progress of pseudocost initialization */ - struct csa *csa = T->pcost; - int j, nv = 0, ni = 0; - for (j = 1; j <= T->n; j++) - { if (glp_ios_can_branch(T, j)) - { nv++; - if (csa->dn_cnt[j] > 0 && csa->up_cnt[j] > 0) ni++; - } - } - xprintf("Pseudocosts initialized for %d of %d variables\n", - ni, nv); - return; -} - -int ios_pcost_branch(glp_tree *T, int *_next) -{ /* choose branching variable with pseudocost branching */ -#if 0 /* 10/VI-2013 */ - glp_long t = xtime(); -#else - double t = xtime(); -#endif - int j, jjj, sel; - double beta, psi, d1, d2, d, dmax; - /* initialize the working arrays */ - if (T->pcost == NULL) - T->pcost = ios_pcost_init(T); - /* nothing has been chosen so far */ - jjj = 0, dmax = -1.0; - /* go through the list of branching candidates */ - for (j = 1; j <= T->n; j++) - { if (!glp_ios_can_branch(T, j)) continue; - /* determine primal value of x[j] in optimal solution to LP - relaxation of the current subproblem */ - beta = T->mip->col[j]->prim; - /* estimate pseudocost of x[j] for down-branch */ - psi = eval_psi(T, j, GLP_DN_BRNCH); - if (psi == DBL_MAX) - { /* down-branch has no primal feasible solution */ - jjj = j, sel = GLP_DN_BRNCH; - goto done; - } - /* estimate degradation of the objective for down-branch */ - d1 = psi * (beta - floor(beta)); - /* estimate pseudocost of x[j] for up-branch */ - psi = eval_psi(T, j, GLP_UP_BRNCH); - if (psi == DBL_MAX) - { /* up-branch has no primal feasible solution */ - jjj = j, sel = GLP_UP_BRNCH; - goto done; - } - /* estimate degradation of the objective for up-branch */ - d2 = psi * (ceil(beta) - beta); - /* determine d = max(d1, d2) */ - d = (d1 > d2 ? d1 : d2); - /* choose x[j] which provides maximal estimated degradation of - the objective either in down- or up-branch */ - if (dmax < d) - { dmax = d; - jjj = j; - /* continue the search from a subproblem, where degradation - is less than in other one */ - sel = (d1 <= d2 ? GLP_DN_BRNCH : GLP_UP_BRNCH); - } - /* display progress of pseudocost initialization */ - if (T->parm->msg_lev >= GLP_ON) - { if (xdifftime(xtime(), t) >= 10.0) - { progress(T); - t = xtime(); - } - } - } - if (dmax == 0.0) - { /* no degradation is indicated; choose a variable having most - fractional value */ - jjj = branch_mostf(T, &sel); - } -done: *_next = sel; - return jjj; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpios10.c b/resources/3rdparty/glpk-4.53/src/glpios10.c deleted file mode 100644 index e67625795..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpios10.c +++ /dev/null @@ -1,355 +0,0 @@ -/* glpios10.c (feasibility pump heuristic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpios.h" -#include "rng.h" - -/*********************************************************************** -* NAME -* -* ios_feas_pump - feasibility pump heuristic -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_feas_pump(glp_tree *T); -* -* DESCRIPTION -* -* The routine ios_feas_pump is a simple implementation of the Feasi- -* bility Pump heuristic. -* -* REFERENCES -* -* M.Fischetti, F.Glover, and A.Lodi. "The feasibility pump." Math. -* Program., Ser. A 104, pp. 91-104 (2005). */ - -struct VAR -{ /* binary variable */ - int j; - /* ordinal number */ - int x; - /* value in the rounded solution (0 or 1) */ - double d; - /* sorting key */ -}; - -static int fcmp(const void *x, const void *y) -{ /* comparison routine */ - const struct VAR *vx = x, *vy = y; - if (vx->d > vy->d) - return -1; - else if (vx->d < vy->d) - return +1; - else - return 0; -} - -void ios_feas_pump(glp_tree *T) -{ glp_prob *P = T->mip; - int n = P->n; - glp_prob *lp = NULL; - struct VAR *var = NULL; - RNG *rand = NULL; - GLPCOL *col; - glp_smcp parm; - int j, k, new_x, nfail, npass, nv, ret, stalling; - double dist, tol; - xassert(glp_get_status(P) == GLP_OPT); - /* this heuristic is applied only once on the root level */ - if (!(T->curr->level == 0 && T->curr->solved == 1)) goto done; - /* determine number of binary variables */ - nv = 0; - for (j = 1; j <= n; j++) - { col = P->col[j]; - /* if x[j] is continuous, skip it */ - if (col->kind == GLP_CV) continue; - /* if x[j] is fixed, skip it */ - if (col->type == GLP_FX) continue; - /* x[j] is non-fixed integer */ - xassert(col->kind == GLP_IV); - if (col->type == GLP_DB && col->lb == 0.0 && col->ub == 1.0) - { /* x[j] is binary */ - nv++; - } - else - { /* x[j] is general integer */ - if (T->parm->msg_lev >= GLP_MSG_ALL) - xprintf("FPUMP heuristic cannot be applied due to genera" - "l integer variables\n"); - goto done; - } - } - /* there must be at least one binary variable */ - if (nv == 0) goto done; - if (T->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Applying FPUMP heuristic...\n"); - /* build the list of binary variables */ - var = xcalloc(1+nv, sizeof(struct VAR)); - k = 0; - for (j = 1; j <= n; j++) - { col = P->col[j]; - if (col->kind == GLP_IV && col->type == GLP_DB) - var[++k].j = j; - } - xassert(k == nv); - /* create working problem object */ - lp = glp_create_prob(); -more: /* copy the original problem object to keep it intact */ - glp_copy_prob(lp, P, GLP_OFF); - /* we are interested to find an integer feasible solution, which - is better than the best known one */ - if (P->mip_stat == GLP_FEAS) - { int *ind; - double *val, bnd; - /* add a row and make it identical to the objective row */ - glp_add_rows(lp, 1); - ind = xcalloc(1+n, sizeof(int)); - val = xcalloc(1+n, sizeof(double)); - for (j = 1; j <= n; j++) - { ind[j] = j; - val[j] = P->col[j]->coef; - } - glp_set_mat_row(lp, lp->m, n, ind, val); - xfree(ind); - xfree(val); - /* introduce upper (minimization) or lower (maximization) - bound to the original objective function; note that this - additional constraint is not violated at the optimal point - to LP relaxation */ -#if 0 /* modified by xypron */ - if (P->dir == GLP_MIN) - { bnd = P->mip_obj - 0.10 * (1.0 + fabs(P->mip_obj)); - if (bnd < P->obj_val) bnd = P->obj_val; - glp_set_row_bnds(lp, lp->m, GLP_UP, 0.0, bnd - P->c0); - } - else if (P->dir == GLP_MAX) - { bnd = P->mip_obj + 0.10 * (1.0 + fabs(P->mip_obj)); - if (bnd > P->obj_val) bnd = P->obj_val; - glp_set_row_bnds(lp, lp->m, GLP_LO, bnd - P->c0, 0.0); - } - else - xassert(P != P); -#else - bnd = 0.1 * P->obj_val + 0.9 * P->mip_obj; - /* xprintf("bnd = %f\n", bnd); */ - if (P->dir == GLP_MIN) - glp_set_row_bnds(lp, lp->m, GLP_UP, 0.0, bnd - P->c0); - else if (P->dir == GLP_MAX) - glp_set_row_bnds(lp, lp->m, GLP_LO, bnd - P->c0, 0.0); - else - xassert(P != P); -#endif - } - /* reset pass count */ - npass = 0; - /* invalidate the rounded point */ - for (k = 1; k <= nv; k++) - var[k].x = -1; -pass: /* next pass starts here */ - npass++; - if (T->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Pass %d\n", npass); - /* initialize minimal distance between the basic point and the - rounded one obtained during this pass */ - dist = DBL_MAX; - /* reset failure count (the number of succeeded iterations failed - to improve the distance) */ - nfail = 0; - /* if it is not the first pass, perturb the last rounded point - rather than construct it from the basic solution */ - if (npass > 1) - { double rho, temp; - if (rand == NULL) - rand = rng_create_rand(); - for (k = 1; k <= nv; k++) - { j = var[k].j; - col = lp->col[j]; - rho = rng_uniform(rand, -0.3, 0.7); - if (rho < 0.0) rho = 0.0; - temp = fabs((double)var[k].x - col->prim); - if (temp + rho > 0.5) var[k].x = 1 - var[k].x; - } - goto skip; - } -loop: /* innermost loop begins here */ - /* round basic solution (which is assumed primal feasible) */ - stalling = 1; - for (k = 1; k <= nv; k++) - { col = lp->col[var[k].j]; - if (col->prim < 0.5) - { /* rounded value is 0 */ - new_x = 0; - } - else - { /* rounded value is 1 */ - new_x = 1; - } - if (var[k].x != new_x) - { stalling = 0; - var[k].x = new_x; - } - } - /* if the rounded point has not changed (stalling), choose and - flip some its entries heuristically */ - if (stalling) - { /* compute d[j] = |x[j] - round(x[j])| */ - for (k = 1; k <= nv; k++) - { col = lp->col[var[k].j]; - var[k].d = fabs(col->prim - (double)var[k].x); - } - /* sort the list of binary variables by descending d[j] */ - qsort(&var[1], nv, sizeof(struct VAR), fcmp); - /* choose and flip some rounded components */ - for (k = 1; k <= nv; k++) - { if (k >= 5 && var[k].d < 0.35 || k >= 10) break; - var[k].x = 1 - var[k].x; - } - } -skip: /* check if the time limit has been exhausted */ - if (T->parm->tm_lim < INT_MAX && - (double)(T->parm->tm_lim - 1) <= - 1000.0 * xdifftime(xtime(), T->tm_beg)) goto done; - /* build the objective, which is the distance between the current - (basic) point and the rounded one */ - lp->dir = GLP_MIN; - lp->c0 = 0.0; - for (j = 1; j <= n; j++) - lp->col[j]->coef = 0.0; - for (k = 1; k <= nv; k++) - { j = var[k].j; - if (var[k].x == 0) - lp->col[j]->coef = +1.0; - else - { lp->col[j]->coef = -1.0; - lp->c0 += 1.0; - } - } - /* minimize the distance with the simplex method */ - glp_init_smcp(&parm); - if (T->parm->msg_lev <= GLP_MSG_ERR) - parm.msg_lev = T->parm->msg_lev; - else if (T->parm->msg_lev <= GLP_MSG_ALL) - { parm.msg_lev = GLP_MSG_ON; - parm.out_dly = 10000; - } - ret = glp_simplex(lp, &parm); - if (ret != 0) - { if (T->parm->msg_lev >= GLP_MSG_ERR) - xprintf("Warning: glp_simplex returned %d\n", ret); - goto done; - } - ret = glp_get_status(lp); - if (ret != GLP_OPT) - { if (T->parm->msg_lev >= GLP_MSG_ERR) - xprintf("Warning: glp_get_status returned %d\n", ret); - goto done; - } - if (T->parm->msg_lev >= GLP_MSG_DBG) - xprintf("delta = %g\n", lp->obj_val); - /* check if the basic solution is integer feasible; note that it - may be so even if the minimial distance is positive */ - tol = 0.3 * T->parm->tol_int; - for (k = 1; k <= nv; k++) - { col = lp->col[var[k].j]; - if (tol < col->prim && col->prim < 1.0 - tol) break; - } - if (k > nv) - { /* okay; the basic solution seems to be integer feasible */ - double *x = xcalloc(1+n, sizeof(double)); - for (j = 1; j <= n; j++) - { x[j] = lp->col[j]->prim; - if (P->col[j]->kind == GLP_IV) x[j] = floor(x[j] + 0.5); - } -#if 1 /* modified by xypron */ - /* reset direction and right-hand side of objective */ - lp->c0 = P->c0; - lp->dir = P->dir; - /* fix integer variables */ - for (k = 1; k <= nv; k++) -#if 0 /* 18/VI-2013; fixed by mao - * this bug causes numerical instability, because column statuses - * are not changed appropriately */ - { lp->col[var[k].j]->lb = x[var[k].j]; - lp->col[var[k].j]->ub = x[var[k].j]; - lp->col[var[k].j]->type = GLP_FX; - } -#else - glp_set_col_bnds(lp, var[k].j, GLP_FX, x[var[k].j], 0.); -#endif - /* copy original objective function */ - for (j = 1; j <= n; j++) - lp->col[j]->coef = P->col[j]->coef; - /* solve original LP and copy result */ - ret = glp_simplex(lp, &parm); - if (ret != 0) - { if (T->parm->msg_lev >= GLP_MSG_ERR) - xprintf("Warning: glp_simplex returned %d\n", ret); - goto done; - } - ret = glp_get_status(lp); - if (ret != GLP_OPT) - { if (T->parm->msg_lev >= GLP_MSG_ERR) - xprintf("Warning: glp_get_status returned %d\n", ret); - goto done; - } - for (j = 1; j <= n; j++) - if (P->col[j]->kind != GLP_IV) x[j] = lp->col[j]->prim; -#endif - ret = glp_ios_heur_sol(T, x); - xfree(x); - if (ret == 0) - { /* the integer solution is accepted */ - if (ios_is_hopeful(T, T->curr->bound)) - { /* it is reasonable to apply the heuristic once again */ - goto more; - } - else - { /* the best known integer feasible solution just found - is close to optimal solution to LP relaxation */ - goto done; - } - } - } - /* the basic solution is fractional */ - if (dist == DBL_MAX || - lp->obj_val <= dist - 1e-6 * (1.0 + dist)) - { /* the distance is reducing */ - nfail = 0, dist = lp->obj_val; - } - else - { /* improving the distance failed */ - nfail++; - } - if (nfail < 3) goto loop; - if (npass < 5) goto pass; -done: /* delete working objects */ - if (lp != NULL) glp_delete_prob(lp); - if (var != NULL) xfree(var); - if (rand != NULL) rng_delete_rand(rand); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpios11.c b/resources/3rdparty/glpk-4.53/src/glpios11.c deleted file mode 100644 index a9f4854d8..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpios11.c +++ /dev/null @@ -1,282 +0,0 @@ -/* glpios11.c (process cuts stored in the local cut pool) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "draft.h" -#include "env.h" -#include "glpios.h" - -/*********************************************************************** -* NAME -* -* ios_process_cuts - process cuts stored in the local cut pool -* -* SYNOPSIS -* -* #include "glpios.h" -* void ios_process_cuts(glp_tree *T); -* -* DESCRIPTION -* -* The routine ios_process_cuts analyzes each cut currently stored in -* the local cut pool, which must be non-empty, and either adds the cut -* to the current subproblem or just discards it. All cuts are assumed -* to be locally valid. On exit the local cut pool remains unchanged. -* -* REFERENCES -* -* 1. E.Balas, S.Ceria, G.Cornuejols, "Mixed 0-1 Programming by -* Lift-and-Project in a Branch-and-Cut Framework", Management Sc., -* 42 (1996) 1229-1246. -* -* 2. G.Andreello, A.Caprara, and M.Fischetti, "Embedding Cuts in -* a Branch&Cut Framework: a Computational Study with {0,1/2}-Cuts", -* Preliminary Draft, October 28, 2003, pp.6-8. */ - -struct info -{ /* estimated cut efficiency */ - IOSCUT *cut; - /* pointer to cut in the cut pool */ - char flag; - /* if this flag is set, the cut is included into the current - subproblem */ - double eff; - /* cut efficacy (normalized residual) */ - double deg; - /* lower bound to objective degradation */ -}; - -static int fcmp(const void *arg1, const void *arg2) -{ const struct info *info1 = arg1, *info2 = arg2; - if (info1->deg == 0.0 && info2->deg == 0.0) - { if (info1->eff > info2->eff) return -1; - if (info1->eff < info2->eff) return +1; - } - else - { if (info1->deg > info2->deg) return -1; - if (info1->deg < info2->deg) return +1; - } - return 0; -} - -static double parallel(IOSCUT *a, IOSCUT *b, double work[]); - -void ios_process_cuts(glp_tree *T) -{ IOSPOOL *pool; - IOSCUT *cut; - IOSAIJ *aij; - struct info *info; - int k, kk, max_cuts, len, ret, *ind; - double *val, *work; - /* the current subproblem must exist */ - xassert(T->curr != NULL); - /* the pool must exist and be non-empty */ - pool = T->local; - xassert(pool != NULL); - xassert(pool->size > 0); - /* allocate working arrays */ - info = xcalloc(1+pool->size, sizeof(struct info)); - ind = xcalloc(1+T->n, sizeof(int)); - val = xcalloc(1+T->n, sizeof(double)); - work = xcalloc(1+T->n, sizeof(double)); - for (k = 1; k <= T->n; k++) work[k] = 0.0; - /* build the list of cuts stored in the cut pool */ - for (k = 0, cut = pool->head; cut != NULL; cut = cut->next) - k++, info[k].cut = cut, info[k].flag = 0; - xassert(k == pool->size); - /* estimate efficiency of all cuts in the cut pool */ - for (k = 1; k <= pool->size; k++) - { double temp, dy, dz; - cut = info[k].cut; - /* build the vector of cut coefficients and compute its - Euclidean norm */ - len = 0; temp = 0.0; - for (aij = cut->ptr; aij != NULL; aij = aij->next) - { xassert(1 <= aij->j && aij->j <= T->n); - len++, ind[len] = aij->j, val[len] = aij->val; - temp += aij->val * aij->val; - } - if (temp < DBL_EPSILON * DBL_EPSILON) temp = DBL_EPSILON; - /* transform the cut to express it only through non-basic - (auxiliary and structural) variables */ - len = glp_transform_row(T->mip, len, ind, val); - /* determine change in the cut value and in the objective - value for the adjacent basis by simulating one step of the - dual simplex */ - ret = _glp_analyze_row(T->mip, len, ind, val, cut->type, - cut->rhs, 1e-9, NULL, NULL, NULL, NULL, &dy, &dz); - /* determine normalized residual and lower bound to objective - degradation */ - if (ret == 0) - { info[k].eff = fabs(dy) / sqrt(temp); - /* if some reduced costs violates (slightly) their zero - bounds (i.e. have wrong signs) due to round-off errors, - dz also may have wrong sign being close to zero */ - if (T->mip->dir == GLP_MIN) - { if (dz < 0.0) dz = 0.0; - info[k].deg = + dz; - } - else /* GLP_MAX */ - { if (dz > 0.0) dz = 0.0; - info[k].deg = - dz; - } - } - else if (ret == 1) - { /* the constraint is not violated at the current point */ - info[k].eff = info[k].deg = 0.0; - } - else if (ret == 2) - { /* no dual feasible adjacent basis exists */ - info[k].eff = 1.0; - info[k].deg = DBL_MAX; - } - else - xassert(ret != ret); - /* if the degradation is too small, just ignore it */ - if (info[k].deg < 0.01) info[k].deg = 0.0; - } - /* sort the list of cuts by decreasing objective degradation and - then by decreasing efficacy */ - qsort(&info[1], pool->size, sizeof(struct info), fcmp); - /* only first (most efficient) max_cuts in the list are qualified - as candidates to be added to the current subproblem */ - max_cuts = (T->curr->level == 0 ? 90 : 10); - if (max_cuts > pool->size) max_cuts = pool->size; - /* add cuts to the current subproblem */ -#if 0 - xprintf("*** adding cuts ***\n"); -#endif - for (k = 1; k <= max_cuts; k++) - { int i, len; - /* if this cut seems to be inefficient, skip it */ - if (info[k].deg < 0.01 && info[k].eff < 0.01) continue; - /* if the angle between this cut and every other cut included - in the current subproblem is small, skip this cut */ - for (kk = 1; kk < k; kk++) - { if (info[kk].flag) - { if (parallel(info[k].cut, info[kk].cut, work) > 0.90) - break; - } - } - if (kk < k) continue; - /* add this cut to the current subproblem */ -#if 0 - xprintf("eff = %g; deg = %g\n", info[k].eff, info[k].deg); -#endif - cut = info[k].cut, info[k].flag = 1; - i = glp_add_rows(T->mip, 1); - if (cut->name != NULL) - glp_set_row_name(T->mip, i, cut->name); - xassert(T->mip->row[i]->origin == GLP_RF_CUT); - T->mip->row[i]->klass = cut->klass; - len = 0; - for (aij = cut->ptr; aij != NULL; aij = aij->next) - len++, ind[len] = aij->j, val[len] = aij->val; - glp_set_mat_row(T->mip, i, len, ind, val); - xassert(cut->type == GLP_LO || cut->type == GLP_UP); - glp_set_row_bnds(T->mip, i, cut->type, cut->rhs, cut->rhs); - } - /* free working arrays */ - xfree(info); - xfree(ind); - xfree(val); - xfree(work); - return; -} - -#if 0 -/*********************************************************************** -* Given a cut a * x >= b (<= b) the routine efficacy computes the cut -* efficacy as follows: -* -* eff = d * (a * x~ - b) / ||a||, -* -* where d is -1 (in case of '>= b') or +1 (in case of '<= b'), x~ is -* the vector of values of structural variables in optimal solution to -* LP relaxation of the current subproblem, ||a|| is the Euclidean norm -* of the vector of cut coefficients. -* -* If the cut is violated at point x~, the efficacy eff is positive, -* and its value is the Euclidean distance between x~ and the cut plane -* a * x = b in the space of structural variables. -* -* Following geometrical intuition, it is quite natural to consider -* this distance as a first-order measure of the expected efficacy of -* the cut: the larger the distance the better the cut [1]. */ - -static double efficacy(glp_tree *T, IOSCUT *cut) -{ glp_prob *mip = T->mip; - IOSAIJ *aij; - double s = 0.0, t = 0.0, temp; - for (aij = cut->ptr; aij != NULL; aij = aij->next) - { xassert(1 <= aij->j && aij->j <= mip->n); - s += aij->val * mip->col[aij->j]->prim; - t += aij->val * aij->val; - } - temp = sqrt(t); - if (temp < DBL_EPSILON) temp = DBL_EPSILON; - if (cut->type == GLP_LO) - temp = (s >= cut->rhs ? 0.0 : (cut->rhs - s) / temp); - else if (cut->type == GLP_UP) - temp = (s <= cut->rhs ? 0.0 : (s - cut->rhs) / temp); - else - xassert(cut != cut); - return temp; -} -#endif - -/*********************************************************************** -* Given two cuts a1 * x >= b1 (<= b1) and a2 * x >= b2 (<= b2) the -* routine parallel computes the cosine of angle between the cut planes -* a1 * x = b1 and a2 * x = b2 (which is the acute angle between two -* normals to these planes) in the space of structural variables as -* follows: -* -* cos phi = (a1' * a2) / (||a1|| * ||a2||), -* -* where (a1' * a2) is a dot product of vectors of cut coefficients, -* ||a1|| and ||a2|| are Euclidean norms of vectors a1 and a2. -* -* Note that requirement cos phi = 0 forces the cuts to be orthogonal, -* i.e. with disjoint support, while requirement cos phi <= 0.999 means -* only avoiding duplicate (parallel) cuts [1]. */ - -static double parallel(IOSCUT *a, IOSCUT *b, double work[]) -{ IOSAIJ *aij; - double s = 0.0, sa = 0.0, sb = 0.0, temp; - for (aij = a->ptr; aij != NULL; aij = aij->next) - { work[aij->j] = aij->val; - sa += aij->val * aij->val; - } - for (aij = b->ptr; aij != NULL; aij = aij->next) - { s += work[aij->j] * aij->val; - sb += aij->val * aij->val; - } - for (aij = a->ptr; aij != NULL; aij = aij->next) - work[aij->j] = 0.0; - temp = sqrt(sa) * sqrt(sb); - if (temp < DBL_EPSILON * DBL_EPSILON) temp = DBL_EPSILON; - return s / temp; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpios12.c b/resources/3rdparty/glpk-4.53/src/glpios12.c deleted file mode 100644 index d5cf302a8..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpios12.c +++ /dev/null @@ -1,177 +0,0 @@ -/* glpios12.c (node selection heuristics) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpios.h" - -/*********************************************************************** -* NAME -* -* ios_choose_node - select subproblem to continue the search -* -* SYNOPSIS -* -* #include "glpios.h" -* int ios_choose_node(glp_tree *T); -* -* DESCRIPTION -* -* The routine ios_choose_node selects a subproblem from the active -* list to continue the search. The choice depends on the backtracking -* technique option. -* -* RETURNS -* -* The routine ios_choose_node return the reference number of the -* subproblem selected. */ - -static int most_feas(glp_tree *T); -static int best_proj(glp_tree *T); -static int best_node(glp_tree *T); - -int ios_choose_node(glp_tree *T) -{ int p; - if (T->parm->bt_tech == GLP_BT_DFS) - { /* depth first search */ - xassert(T->tail != NULL); - p = T->tail->p; - } - else if (T->parm->bt_tech == GLP_BT_BFS) - { /* breadth first search */ - xassert(T->head != NULL); - p = T->head->p; - } - else if (T->parm->bt_tech == GLP_BT_BLB) - { /* select node with best local bound */ - p = best_node(T); - } - else if (T->parm->bt_tech == GLP_BT_BPH) - { if (T->mip->mip_stat == GLP_UNDEF) - { /* "most integer feasible" subproblem */ - p = most_feas(T); - } - else - { /* best projection heuristic */ - p = best_proj(T); - } - } - else - xassert(T != T); - return p; -} - -static int most_feas(glp_tree *T) -{ /* select subproblem whose parent has minimal sum of integer - infeasibilities */ - IOSNPD *node; - int p; - double best; - p = 0, best = DBL_MAX; - for (node = T->head; node != NULL; node = node->next) - { xassert(node->up != NULL); - if (best > node->up->ii_sum) - p = node->p, best = node->up->ii_sum; - } - return p; -} - -static int best_proj(glp_tree *T) -{ /* select subproblem using the best projection heuristic */ - IOSNPD *root, *node; - int p; - double best, deg, obj; - /* the global bound must exist */ - xassert(T->mip->mip_stat == GLP_FEAS); - /* obtain pointer to the root node, which must exist */ - root = T->slot[1].node; - xassert(root != NULL); - /* deg estimates degradation of the objective function per unit - of the sum of integer infeasibilities */ - xassert(root->ii_sum > 0.0); - deg = (T->mip->mip_obj - root->bound) / root->ii_sum; - /* nothing has been selected so far */ - p = 0, best = DBL_MAX; - /* walk through the list of active subproblems */ - for (node = T->head; node != NULL; node = node->next) - { xassert(node->up != NULL); - /* obj estimates optimal objective value if the sum of integer - infeasibilities were zero */ - obj = node->up->bound + deg * node->up->ii_sum; - if (T->mip->dir == GLP_MAX) obj = - obj; - /* select the subproblem which has the best estimated optimal - objective value */ - if (best > obj) p = node->p, best = obj; - } - return p; -} - -static int best_node(glp_tree *T) -{ /* select subproblem with best local bound */ - IOSNPD *node, *best = NULL; - double bound, eps; - switch (T->mip->dir) - { case GLP_MIN: - bound = +DBL_MAX; - for (node = T->head; node != NULL; node = node->next) - if (bound > node->bound) bound = node->bound; - xassert(bound != +DBL_MAX); - eps = 1e-10 * (1.0 + fabs(bound)); - for (node = T->head; node != NULL; node = node->next) - { if (node->bound <= bound + eps) - { xassert(node->up != NULL); - if (best == NULL || -#if 1 - best->up->ii_sum > node->up->ii_sum) best = node; -#else - best->lp_obj > node->lp_obj) best = node; -#endif - } - } - break; - case GLP_MAX: - bound = -DBL_MAX; - for (node = T->head; node != NULL; node = node->next) - if (bound < node->bound) bound = node->bound; - xassert(bound != -DBL_MAX); - eps = 1e-10 * (1.0 + fabs(bound)); - for (node = T->head; node != NULL; node = node->next) - { if (node->bound >= bound - eps) - { xassert(node->up != NULL); - if (best == NULL || -#if 1 - best->up->ii_sum > node->up->ii_sum) best = node; -#else - best->lp_obj < node->lp_obj) best = node; -#endif - } - } - break; - default: - xassert(T != T); - } - xassert(best != NULL); - return best->p; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpipm.c b/resources/3rdparty/glpk-4.53/src/glpipm.c deleted file mode 100644 index 2b3a81762..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpipm.c +++ /dev/null @@ -1,1144 +0,0 @@ -/* glpipm.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpipm.h" -#include "glpmat.h" - -#define ITER_MAX 100 -/* maximal number of iterations */ - -struct csa -{ /* common storage area */ - /*--------------------------------------------------------------*/ - /* LP data */ - int m; - /* number of rows (equality constraints) */ - int n; - /* number of columns (structural variables) */ - int *A_ptr; /* int A_ptr[1+m+1]; */ - int *A_ind; /* int A_ind[A_ptr[m+1]]; */ - double *A_val; /* double A_val[A_ptr[m+1]]; */ - /* mxn-matrix A in storage-by-rows format */ - double *b; /* double b[1+m]; */ - /* m-vector b of right-hand sides */ - double *c; /* double c[1+n]; */ - /* n-vector c of objective coefficients; c[0] is constant term of - the objective function */ - /*--------------------------------------------------------------*/ - /* LP solution */ - double *x; /* double x[1+n]; */ - double *y; /* double y[1+m]; */ - double *z; /* double z[1+n]; */ - /* current point in primal-dual space; the best point on exit */ - /*--------------------------------------------------------------*/ - /* control parameters */ - const glp_iptcp *parm; - /*--------------------------------------------------------------*/ - /* working arrays and variables */ - double *D; /* double D[1+n]; */ - /* diagonal nxn-matrix D = X*inv(Z), where X = diag(x[j]) and - Z = diag(z[j]) */ - int *P; /* int P[1+m+m]; */ - /* permutation mxm-matrix P used to minimize fill-in in Cholesky - factorization */ - int *S_ptr; /* int S_ptr[1+m+1]; */ - int *S_ind; /* int S_ind[S_ptr[m+1]]; */ - double *S_val; /* double S_val[S_ptr[m+1]]; */ - double *S_diag; /* double S_diag[1+m]; */ - /* symmetric mxm-matrix S = P*A*D*A'*P' whose upper triangular - part without diagonal elements is stored in S_ptr, S_ind, and - S_val in storage-by-rows format, diagonal elements are stored - in S_diag */ - int *U_ptr; /* int U_ptr[1+m+1]; */ - int *U_ind; /* int U_ind[U_ptr[m+1]]; */ - double *U_val; /* double U_val[U_ptr[m+1]]; */ - double *U_diag; /* double U_diag[1+m]; */ - /* upper triangular mxm-matrix U defining Cholesky factorization - S = U'*U; its non-diagonal elements are stored in U_ptr, U_ind, - U_val in storage-by-rows format, diagonal elements are stored - in U_diag */ - int iter; - /* iteration number (0, 1, 2, ...); iter = 0 corresponds to the - initial point */ - double obj; - /* current value of the objective function */ - double rpi; - /* relative primal infeasibility rpi = ||A*x-b||/(1+||b||) */ - double rdi; - /* relative dual infeasibility rdi = ||A'*y+z-c||/(1+||c||) */ - double gap; - /* primal-dual gap = |c'*x-b'*y|/(1+|c'*x|) which is a relative - difference between primal and dual objective functions */ - double phi; - /* merit function phi = ||A*x-b||/max(1,||b||) + - + ||A'*y+z-c||/max(1,||c||) + - + |c'*x-b'*y|/max(1,||b||,||c||) */ - double mu; - /* duality measure mu = x'*z/n (used as barrier parameter) */ - double rmu; - /* rmu = max(||A*x-b||,||A'*y+z-c||)/mu */ - double rmu0; - /* the initial value of rmu on iteration 0 */ - double *phi_min; /* double phi_min[1+ITER_MAX]; */ - /* phi_min[k] = min(phi[k]), where phi[k] is the value of phi on - k-th iteration, 0 <= k <= iter */ - int best_iter; - /* iteration number, on which the value of phi reached its best - (minimal) value */ - double *best_x; /* double best_x[1+n]; */ - double *best_y; /* double best_y[1+m]; */ - double *best_z; /* double best_z[1+n]; */ - /* best point (in the sense of the merit function phi) which has - been reached on iteration iter_best */ - double best_obj; - /* objective value at the best point */ - double *dx_aff; /* double dx_aff[1+n]; */ - double *dy_aff; /* double dy_aff[1+m]; */ - double *dz_aff; /* double dz_aff[1+n]; */ - /* affine scaling direction */ - double alfa_aff_p, alfa_aff_d; - /* maximal primal and dual stepsizes in affine scaling direction, - on which x and z are still non-negative */ - double mu_aff; - /* duality measure mu_aff = x_aff'*z_aff/n in the boundary point - x_aff' = x+alfa_aff_p*dx_aff, z_aff' = z+alfa_aff_d*dz_aff */ - double sigma; - /* Mehrotra's heuristic parameter (0 <= sigma <= 1) */ - double *dx_cc; /* double dx_cc[1+n]; */ - double *dy_cc; /* double dy_cc[1+m]; */ - double *dz_cc; /* double dz_cc[1+n]; */ - /* centering corrector direction */ - double *dx; /* double dx[1+n]; */ - double *dy; /* double dy[1+m]; */ - double *dz; /* double dz[1+n]; */ - /* final combined direction dx = dx_aff+dx_cc, dy = dy_aff+dy_cc, - dz = dz_aff+dz_cc */ - double alfa_max_p; - double alfa_max_d; - /* maximal primal and dual stepsizes in combined direction, on - which x and z are still non-negative */ -}; - -/*********************************************************************** -* initialize - allocate and initialize common storage area -* -* This routine allocates and initializes the common storage area (CSA) -* used by interior-point method routines. */ - -static void initialize(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - int i; - if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Matrix A has %d non-zeros\n", csa->A_ptr[m+1]-1); - csa->D = xcalloc(1+n, sizeof(double)); - /* P := I */ - csa->P = xcalloc(1+m+m, sizeof(int)); - for (i = 1; i <= m; i++) csa->P[i] = csa->P[m+i] = i; - /* S := A*A', symbolically */ - csa->S_ptr = xcalloc(1+m+1, sizeof(int)); - csa->S_ind = adat_symbolic(m, n, csa->P, csa->A_ptr, csa->A_ind, - csa->S_ptr); - if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Matrix S = A*A' has %d non-zeros (upper triangle)\n", - csa->S_ptr[m+1]-1 + m); - /* determine P using specified ordering algorithm */ - if (csa->parm->ord_alg == GLP_ORD_NONE) - { if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Original ordering is being used\n"); - for (i = 1; i <= m; i++) - csa->P[i] = csa->P[m+i] = i; - } - else if (csa->parm->ord_alg == GLP_ORD_QMD) - { if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Minimum degree ordering (QMD)...\n"); - min_degree(m, csa->S_ptr, csa->S_ind, csa->P); - } - else if (csa->parm->ord_alg == GLP_ORD_AMD) - { if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Approximate minimum degree ordering (AMD)...\n"); - amd_order1(m, csa->S_ptr, csa->S_ind, csa->P); - } - else if (csa->parm->ord_alg == GLP_ORD_SYMAMD) - { if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Approximate minimum degree ordering (SYMAMD)...\n") - ; - symamd_ord(m, csa->S_ptr, csa->S_ind, csa->P); - } - else - xassert(csa != csa); - /* S := P*A*A'*P', symbolically */ - xfree(csa->S_ind); - csa->S_ind = adat_symbolic(m, n, csa->P, csa->A_ptr, csa->A_ind, - csa->S_ptr); - csa->S_val = xcalloc(csa->S_ptr[m+1], sizeof(double)); - csa->S_diag = xcalloc(1+m, sizeof(double)); - /* compute Cholesky factorization S = U'*U, symbolically */ - if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Computing Cholesky factorization S = L*L'...\n"); - csa->U_ptr = xcalloc(1+m+1, sizeof(int)); - csa->U_ind = chol_symbolic(m, csa->S_ptr, csa->S_ind, csa->U_ptr); - if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Matrix L has %d non-zeros\n", csa->U_ptr[m+1]-1 + m); - csa->U_val = xcalloc(csa->U_ptr[m+1], sizeof(double)); - csa->U_diag = xcalloc(1+m, sizeof(double)); - csa->iter = 0; - csa->obj = 0.0; - csa->rpi = 0.0; - csa->rdi = 0.0; - csa->gap = 0.0; - csa->phi = 0.0; - csa->mu = 0.0; - csa->rmu = 0.0; - csa->rmu0 = 0.0; - csa->phi_min = xcalloc(1+ITER_MAX, sizeof(double)); - csa->best_iter = 0; - csa->best_x = xcalloc(1+n, sizeof(double)); - csa->best_y = xcalloc(1+m, sizeof(double)); - csa->best_z = xcalloc(1+n, sizeof(double)); - csa->best_obj = 0.0; - csa->dx_aff = xcalloc(1+n, sizeof(double)); - csa->dy_aff = xcalloc(1+m, sizeof(double)); - csa->dz_aff = xcalloc(1+n, sizeof(double)); - csa->alfa_aff_p = 0.0; - csa->alfa_aff_d = 0.0; - csa->mu_aff = 0.0; - csa->sigma = 0.0; - csa->dx_cc = xcalloc(1+n, sizeof(double)); - csa->dy_cc = xcalloc(1+m, sizeof(double)); - csa->dz_cc = xcalloc(1+n, sizeof(double)); - csa->dx = csa->dx_aff; - csa->dy = csa->dy_aff; - csa->dz = csa->dz_aff; - csa->alfa_max_p = 0.0; - csa->alfa_max_d = 0.0; - return; -} - -/*********************************************************************** -* A_by_vec - compute y = A*x -* -* This routine computes matrix-vector product y = A*x, where A is the -* constraint matrix. */ - -static void A_by_vec(struct csa *csa, double x[], double y[]) -{ /* compute y = A*x */ - int m = csa->m; - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int i, t, beg, end; - double temp; - for (i = 1; i <= m; i++) - { temp = 0.0; - beg = A_ptr[i], end = A_ptr[i+1]; - for (t = beg; t < end; t++) temp += A_val[t] * x[A_ind[t]]; - y[i] = temp; - } - return; -} - -/*********************************************************************** -* AT_by_vec - compute y = A'*x -* -* This routine computes matrix-vector product y = A'*x, where A' is a -* matrix transposed to the constraint matrix A. */ - -static void AT_by_vec(struct csa *csa, double x[], double y[]) -{ /* compute y = A'*x, where A' is transposed to A */ - int m = csa->m; - int n = csa->n; - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int i, j, t, beg, end; - double temp; - for (j = 1; j <= n; j++) y[j] = 0.0; - for (i = 1; i <= m; i++) - { temp = x[i]; - if (temp == 0.0) continue; - beg = A_ptr[i], end = A_ptr[i+1]; - for (t = beg; t < end; t++) y[A_ind[t]] += A_val[t] * temp; - } - return; -} - -/*********************************************************************** -* decomp_NE - numeric factorization of matrix S = P*A*D*A'*P' -* -* This routine implements numeric phase of Cholesky factorization of -* the matrix S = P*A*D*A'*P', which is a permuted matrix of the normal -* equation system. Matrix D is assumed to be already computed. */ - -static void decomp_NE(struct csa *csa) -{ adat_numeric(csa->m, csa->n, csa->P, csa->A_ptr, csa->A_ind, - csa->A_val, csa->D, csa->S_ptr, csa->S_ind, csa->S_val, - csa->S_diag); - chol_numeric(csa->m, csa->S_ptr, csa->S_ind, csa->S_val, - csa->S_diag, csa->U_ptr, csa->U_ind, csa->U_val, csa->U_diag); - return; -} - -/*********************************************************************** -* solve_NE - solve normal equation system -* -* This routine solves the normal equation system: -* -* A*D*A'*y = h. -* -* It is assumed that the matrix A*D*A' has been previously factorized -* by the routine decomp_NE. -* -* On entry the array y contains the vector of right-hand sides h. On -* exit this array contains the computed vector of unknowns y. -* -* Once the vector y has been computed the routine checks for numeric -* stability. If the residual vector: -* -* r = A*D*A'*y - h -* -* is relatively small, the routine returns zero, otherwise non-zero is -* returned. */ - -static int solve_NE(struct csa *csa, double y[]) -{ int m = csa->m; - int n = csa->n; - int *P = csa->P; - int i, j, ret = 0; - double *h, *r, *w; - /* save vector of right-hand sides h */ - h = xcalloc(1+m, sizeof(double)); - for (i = 1; i <= m; i++) h[i] = y[i]; - /* solve normal equation system (A*D*A')*y = h */ - /* since S = P*A*D*A'*P' = U'*U, then A*D*A' = P'*U'*U*P, so we - have inv(A*D*A') = P'*inv(U)*inv(U')*P */ - /* w := P*h */ - w = xcalloc(1+m, sizeof(double)); - for (i = 1; i <= m; i++) w[i] = y[P[i]]; - /* w := inv(U')*w */ - ut_solve(m, csa->U_ptr, csa->U_ind, csa->U_val, csa->U_diag, w); - /* w := inv(U)*w */ - u_solve(m, csa->U_ptr, csa->U_ind, csa->U_val, csa->U_diag, w); - /* y := P'*w */ - for (i = 1; i <= m; i++) y[i] = w[P[m+i]]; - xfree(w); - /* compute residual vector r = A*D*A'*y - h */ - r = xcalloc(1+m, sizeof(double)); - /* w := A'*y */ - w = xcalloc(1+n, sizeof(double)); - AT_by_vec(csa, y, w); - /* w := D*w */ - for (j = 1; j <= n; j++) w[j] *= csa->D[j]; - /* r := A*w */ - A_by_vec(csa, w, r); - xfree(w); - /* r := r - h */ - for (i = 1; i <= m; i++) r[i] -= h[i]; - /* check for numeric stability */ - for (i = 1; i <= m; i++) - { if (fabs(r[i]) / (1.0 + fabs(h[i])) > 1e-4) - { ret = 1; - break; - } - } - xfree(h); - xfree(r); - return ret; -} - -/*********************************************************************** -* solve_NS - solve Newtonian system -* -* This routine solves the Newtonian system: -* -* A*dx = p -* -* A'*dy + dz = q -* -* Z*dx + X*dz = r -* -* where X = diag(x[j]), Z = diag(z[j]), by reducing it to the normal -* equation system: -* -* (A*inv(Z)*X*A')*dy = A*inv(Z)*(X*q-r)+p -* -* (it is assumed that the matrix A*inv(Z)*X*A' has been factorized by -* the routine decomp_NE). -* -* Once vector dy has been computed the routine computes vectors dx and -* dz as follows: -* -* dx = inv(Z)*(X*(A'*dy-q)+r) -* -* dz = inv(X)*(r-Z*dx) -* -* The routine solve_NS returns the same code which was reported by the -* routine solve_NE (see above). */ - -static int solve_NS(struct csa *csa, double p[], double q[], double r[], - double dx[], double dy[], double dz[]) -{ int m = csa->m; - int n = csa->n; - double *x = csa->x; - double *z = csa->z; - int i, j, ret; - double *w = dx; - /* compute the vector of right-hand sides A*inv(Z)*(X*q-r)+p for - the normal equation system */ - for (j = 1; j <= n; j++) - w[j] = (x[j] * q[j] - r[j]) / z[j]; - A_by_vec(csa, w, dy); - for (i = 1; i <= m; i++) dy[i] += p[i]; - /* solve the normal equation system to compute vector dy */ - ret = solve_NE(csa, dy); - /* compute vectors dx and dz */ - AT_by_vec(csa, dy, dx); - for (j = 1; j <= n; j++) - { dx[j] = (x[j] * (dx[j] - q[j]) + r[j]) / z[j]; - dz[j] = (r[j] - z[j] * dx[j]) / x[j]; - } - return ret; -} - -/*********************************************************************** -* initial_point - choose initial point using Mehrotra's heuristic -* -* This routine chooses a starting point using a heuristic proposed in -* the paper: -* -* S. Mehrotra. On the implementation of a primal-dual interior point -* method. SIAM J. on Optim., 2(4), pp. 575-601, 1992. -* -* The starting point x in the primal space is chosen as a solution of -* the following least squares problem: -* -* minimize ||x|| -* -* subject to A*x = b -* -* which can be computed explicitly as follows: -* -* x = A'*inv(A*A')*b -* -* Similarly, the starting point (y, z) in the dual space is chosen as -* a solution of the following least squares problem: -* -* minimize ||z|| -* -* subject to A'*y + z = c -* -* which can be computed explicitly as follows: -* -* y = inv(A*A')*A*c -* -* z = c - A'*y -* -* However, some components of the vectors x and z may be non-positive -* or close to zero, so the routine uses a Mehrotra's heuristic to find -* a more appropriate starting point. */ - -static void initial_point(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - double *b = csa->b; - double *c = csa->c; - double *x = csa->x; - double *y = csa->y; - double *z = csa->z; - double *D = csa->D; - int i, j; - double dp, dd, ex, ez, xz; - /* factorize A*A' */ - for (j = 1; j <= n; j++) D[j] = 1.0; - decomp_NE(csa); - /* x~ = A'*inv(A*A')*b */ - for (i = 1; i <= m; i++) y[i] = b[i]; - solve_NE(csa, y); - AT_by_vec(csa, y, x); - /* y~ = inv(A*A')*A*c */ - A_by_vec(csa, c, y); - solve_NE(csa, y); - /* z~ = c - A'*y~ */ - AT_by_vec(csa, y,z); - for (j = 1; j <= n; j++) z[j] = c[j] - z[j]; - /* use Mehrotra's heuristic in order to choose more appropriate - starting point with positive components of vectors x and z */ - dp = dd = 0.0; - for (j = 1; j <= n; j++) - { if (dp < -1.5 * x[j]) dp = -1.5 * x[j]; - if (dd < -1.5 * z[j]) dd = -1.5 * z[j]; - } - /* note that b = 0 involves x = 0, and c = 0 involves y = 0 and - z = 0, so we need to be careful */ - if (dp == 0.0) dp = 1.5; - if (dd == 0.0) dd = 1.5; - ex = ez = xz = 0.0; - for (j = 1; j <= n; j++) - { ex += (x[j] + dp); - ez += (z[j] + dd); - xz += (x[j] + dp) * (z[j] + dd); - } - dp += 0.5 * (xz / ez); - dd += 0.5 * (xz / ex); - for (j = 1; j <= n; j++) - { x[j] += dp; - z[j] += dd; - xassert(x[j] > 0.0 && z[j] > 0.0); - } - return; -} - -/*********************************************************************** -* basic_info - perform basic computations at the current point -* -* This routine computes the following quantities at the current point: -* -* 1) value of the objective function: -* -* F = c'*x + c[0] -* -* 2) relative primal infeasibility: -* -* rpi = ||A*x-b|| / (1+||b||) -* -* 3) relative dual infeasibility: -* -* rdi = ||A'*y+z-c|| / (1+||c||) -* -* 4) primal-dual gap (relative difference between the primal and the -* dual objective function values): -* -* gap = |c'*x-b'*y| / (1+|c'*x|) -* -* 5) merit function: -* -* phi = ||A*x-b|| / max(1,||b||) + ||A'*y+z-c|| / max(1,||c||) + -* -* + |c'*x-b'*y| / max(1,||b||,||c||) -* -* 6) duality measure: -* -* mu = x'*z / n -* -* 7) the ratio of infeasibility to mu: -* -* rmu = max(||A*x-b||,||A'*y+z-c||) / mu -* -* where ||*|| denotes euclidian norm, *' denotes transposition. */ - -static void basic_info(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - double *b = csa->b; - double *c = csa->c; - double *x = csa->x; - double *y = csa->y; - double *z = csa->z; - int i, j; - double norm1, bnorm, norm2, cnorm, cx, by, *work, temp; - /* compute value of the objective function */ - temp = c[0]; - for (j = 1; j <= n; j++) temp += c[j] * x[j]; - csa->obj = temp; - /* norm1 = ||A*x-b|| */ - work = xcalloc(1+m, sizeof(double)); - A_by_vec(csa, x, work); - norm1 = 0.0; - for (i = 1; i <= m; i++) - norm1 += (work[i] - b[i]) * (work[i] - b[i]); - norm1 = sqrt(norm1); - xfree(work); - /* bnorm = ||b|| */ - bnorm = 0.0; - for (i = 1; i <= m; i++) bnorm += b[i] * b[i]; - bnorm = sqrt(bnorm); - /* compute relative primal infeasibility */ - csa->rpi = norm1 / (1.0 + bnorm); - /* norm2 = ||A'*y+z-c|| */ - work = xcalloc(1+n, sizeof(double)); - AT_by_vec(csa, y, work); - norm2 = 0.0; - for (j = 1; j <= n; j++) - norm2 += (work[j] + z[j] - c[j]) * (work[j] + z[j] - c[j]); - norm2 = sqrt(norm2); - xfree(work); - /* cnorm = ||c|| */ - cnorm = 0.0; - for (j = 1; j <= n; j++) cnorm += c[j] * c[j]; - cnorm = sqrt(cnorm); - /* compute relative dual infeasibility */ - csa->rdi = norm2 / (1.0 + cnorm); - /* by = b'*y */ - by = 0.0; - for (i = 1; i <= m; i++) by += b[i] * y[i]; - /* cx = c'*x */ - cx = 0.0; - for (j = 1; j <= n; j++) cx += c[j] * x[j]; - /* compute primal-dual gap */ - csa->gap = fabs(cx - by) / (1.0 + fabs(cx)); - /* compute merit function */ - csa->phi = 0.0; - csa->phi += norm1 / (bnorm > 1.0 ? bnorm : 1.0); - csa->phi += norm2 / (cnorm > 1.0 ? cnorm : 1.0); - temp = 1.0; - if (temp < bnorm) temp = bnorm; - if (temp < cnorm) temp = cnorm; - csa->phi += fabs(cx - by) / temp; - /* compute duality measure */ - temp = 0.0; - for (j = 1; j <= n; j++) temp += x[j] * z[j]; - csa->mu = temp / (double)n; - /* compute the ratio of infeasibility to mu */ - csa->rmu = (norm1 > norm2 ? norm1 : norm2) / csa->mu; - return; -} - -/*********************************************************************** -* make_step - compute next point using Mehrotra's technique -* -* This routine computes the next point using the predictor-corrector -* technique proposed in the paper: -* -* S. Mehrotra. On the implementation of a primal-dual interior point -* method. SIAM J. on Optim., 2(4), pp. 575-601, 1992. -* -* At first, the routine computes so called affine scaling (predictor) -* direction (dx_aff,dy_aff,dz_aff) which is a solution of the system: -* -* A*dx_aff = b - A*x -* -* A'*dy_aff + dz_aff = c - A'*y - z -* -* Z*dx_aff + X*dz_aff = - X*Z*e -* -* where (x,y,z) is the current point, X = diag(x[j]), Z = diag(z[j]), -* e = (1,...,1)'. -* -* Then, the routine computes the centering parameter sigma, using the -* following Mehrotra's heuristic: -* -* alfa_aff_p = inf{0 <= alfa <= 1 | x+alfa*dx_aff >= 0} -* -* alfa_aff_d = inf{0 <= alfa <= 1 | z+alfa*dz_aff >= 0} -* -* mu_aff = (x+alfa_aff_p*dx_aff)'*(z+alfa_aff_d*dz_aff)/n -* -* sigma = (mu_aff/mu)^3 -* -* where alfa_aff_p is the maximal stepsize along the affine scaling -* direction in the primal space, alfa_aff_d is the maximal stepsize -* along the same direction in the dual space. -* -* After determining sigma the routine computes so called centering -* (corrector) direction (dx_cc,dy_cc,dz_cc) which is the solution of -* the system: -* -* A*dx_cc = 0 -* -* A'*dy_cc + dz_cc = 0 -* -* Z*dx_cc + X*dz_cc = sigma*mu*e - X*Z*e -* -* Finally, the routine computes the combined direction -* -* (dx,dy,dz) = (dx_aff,dy_aff,dz_aff) + (dx_cc,dy_cc,dz_cc) -* -* and determines maximal primal and dual stepsizes along the combined -* direction: -* -* alfa_max_p = inf{0 <= alfa <= 1 | x+alfa*dx >= 0} -* -* alfa_max_d = inf{0 <= alfa <= 1 | z+alfa*dz >= 0} -* -* In order to prevent the next point to be too close to the boundary -* of the positive ortant, the routine decreases maximal stepsizes: -* -* alfa_p = gamma_p * alfa_max_p -* -* alfa_d = gamma_d * alfa_max_d -* -* where gamma_p and gamma_d are scaling factors, and computes the next -* point: -* -* x_new = x + alfa_p * dx -* -* y_new = y + alfa_d * dy -* -* z_new = z + alfa_d * dz -* -* which becomes the current point on the next iteration. */ - -static int make_step(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - double *b = csa->b; - double *c = csa->c; - double *x = csa->x; - double *y = csa->y; - double *z = csa->z; - double *dx_aff = csa->dx_aff; - double *dy_aff = csa->dy_aff; - double *dz_aff = csa->dz_aff; - double *dx_cc = csa->dx_cc; - double *dy_cc = csa->dy_cc; - double *dz_cc = csa->dz_cc; - double *dx = csa->dx; - double *dy = csa->dy; - double *dz = csa->dz; - int i, j, ret = 0; - double temp, gamma_p, gamma_d, *p, *q, *r; - /* allocate working arrays */ - p = xcalloc(1+m, sizeof(double)); - q = xcalloc(1+n, sizeof(double)); - r = xcalloc(1+n, sizeof(double)); - /* p = b - A*x */ - A_by_vec(csa, x, p); - for (i = 1; i <= m; i++) p[i] = b[i] - p[i]; - /* q = c - A'*y - z */ - AT_by_vec(csa, y,q); - for (j = 1; j <= n; j++) q[j] = c[j] - q[j] - z[j]; - /* r = - X * Z * e */ - for (j = 1; j <= n; j++) r[j] = - x[j] * z[j]; - /* solve the first Newtonian system */ - if (solve_NS(csa, p, q, r, dx_aff, dy_aff, dz_aff)) - { ret = 1; - goto done; - } - /* alfa_aff_p = inf{0 <= alfa <= 1 | x + alfa*dx_aff >= 0} */ - /* alfa_aff_d = inf{0 <= alfa <= 1 | z + alfa*dz_aff >= 0} */ - csa->alfa_aff_p = csa->alfa_aff_d = 1.0; - for (j = 1; j <= n; j++) - { if (dx_aff[j] < 0.0) - { temp = - x[j] / dx_aff[j]; - if (csa->alfa_aff_p > temp) csa->alfa_aff_p = temp; - } - if (dz_aff[j] < 0.0) - { temp = - z[j] / dz_aff[j]; - if (csa->alfa_aff_d > temp) csa->alfa_aff_d = temp; - } - } - /* mu_aff = (x+alfa_aff_p*dx_aff)' * (z+alfa_aff_d*dz_aff) / n */ - temp = 0.0; - for (j = 1; j <= n; j++) - temp += (x[j] + csa->alfa_aff_p * dx_aff[j]) * - (z[j] + csa->alfa_aff_d * dz_aff[j]); - csa->mu_aff = temp / (double)n; - /* sigma = (mu_aff/mu)^3 */ - temp = csa->mu_aff / csa->mu; - csa->sigma = temp * temp * temp; - /* p = 0 */ - for (i = 1; i <= m; i++) p[i] = 0.0; - /* q = 0 */ - for (j = 1; j <= n; j++) q[j] = 0.0; - /* r = sigma * mu * e - X * Z * e */ - for (j = 1; j <= n; j++) - r[j] = csa->sigma * csa->mu - dx_aff[j] * dz_aff[j]; - /* solve the second Newtonian system with the same coefficients - but with altered right-hand sides */ - if (solve_NS(csa, p, q, r, dx_cc, dy_cc, dz_cc)) - { ret = 1; - goto done; - } - /* (dx,dy,dz) = (dx_aff,dy_aff,dz_aff) + (dx_cc,dy_cc,dz_cc) */ - for (j = 1; j <= n; j++) dx[j] = dx_aff[j] + dx_cc[j]; - for (i = 1; i <= m; i++) dy[i] = dy_aff[i] + dy_cc[i]; - for (j = 1; j <= n; j++) dz[j] = dz_aff[j] + dz_cc[j]; - /* alfa_max_p = inf{0 <= alfa <= 1 | x + alfa*dx >= 0} */ - /* alfa_max_d = inf{0 <= alfa <= 1 | z + alfa*dz >= 0} */ - csa->alfa_max_p = csa->alfa_max_d = 1.0; - for (j = 1; j <= n; j++) - { if (dx[j] < 0.0) - { temp = - x[j] / dx[j]; - if (csa->alfa_max_p > temp) csa->alfa_max_p = temp; - } - if (dz[j] < 0.0) - { temp = - z[j] / dz[j]; - if (csa->alfa_max_d > temp) csa->alfa_max_d = temp; - } - } - /* determine scale factors (not implemented yet) */ - gamma_p = 0.90; - gamma_d = 0.90; - /* compute the next point */ - for (j = 1; j <= n; j++) - { x[j] += gamma_p * csa->alfa_max_p * dx[j]; - xassert(x[j] > 0.0); - } - for (i = 1; i <= m; i++) - y[i] += gamma_d * csa->alfa_max_d * dy[i]; - for (j = 1; j <= n; j++) - { z[j] += gamma_d * csa->alfa_max_d * dz[j]; - xassert(z[j] > 0.0); - } -done: /* free working arrays */ - xfree(p); - xfree(q); - xfree(r); - return ret; -} - -/*********************************************************************** -* terminate - deallocate common storage area -* -* This routine frees all memory allocated to the common storage area -* used by interior-point method routines. */ - -static void terminate(struct csa *csa) -{ xfree(csa->D); - xfree(csa->P); - xfree(csa->S_ptr); - xfree(csa->S_ind); - xfree(csa->S_val); - xfree(csa->S_diag); - xfree(csa->U_ptr); - xfree(csa->U_ind); - xfree(csa->U_val); - xfree(csa->U_diag); - xfree(csa->phi_min); - xfree(csa->best_x); - xfree(csa->best_y); - xfree(csa->best_z); - xfree(csa->dx_aff); - xfree(csa->dy_aff); - xfree(csa->dz_aff); - xfree(csa->dx_cc); - xfree(csa->dy_cc); - xfree(csa->dz_cc); - return; -} - -/*********************************************************************** -* ipm_main - main interior-point method routine -* -* This is a main routine of the primal-dual interior-point method. -* -* The routine ipm_main returns one of the following codes: -* -* 0 - optimal solution found; -* 1 - problem has no feasible (primal or dual) solution; -* 2 - no convergence; -* 3 - iteration limit exceeded; -* 4 - numeric instability on solving Newtonian system. -* -* In case of non-zero return code the routine returns the best point, -* which has been reached during optimization. */ - -static int ipm_main(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - int i, j, status; - double temp; - /* choose initial point using Mehrotra's heuristic */ - if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Guessing initial point...\n"); - initial_point(csa); - /* main loop starts here */ - if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Optimization begins...\n"); - for (;;) - { /* perform basic computations at the current point */ - basic_info(csa); - /* save initial value of rmu */ - if (csa->iter == 0) csa->rmu0 = csa->rmu; - /* accumulate values of min(phi[k]) and save the best point */ - xassert(csa->iter <= ITER_MAX); - if (csa->iter == 0 || csa->phi_min[csa->iter-1] > csa->phi) - { csa->phi_min[csa->iter] = csa->phi; - csa->best_iter = csa->iter; - for (j = 1; j <= n; j++) csa->best_x[j] = csa->x[j]; - for (i = 1; i <= m; i++) csa->best_y[i] = csa->y[i]; - for (j = 1; j <= n; j++) csa->best_z[j] = csa->z[j]; - csa->best_obj = csa->obj; - } - else - csa->phi_min[csa->iter] = csa->phi_min[csa->iter-1]; - /* display information at the current point */ - if (csa->parm->msg_lev >= GLP_MSG_ON) - xprintf("%3d: obj = %17.9e; rpi = %8.1e; rdi = %8.1e; gap =" - " %8.1e\n", csa->iter, csa->obj, csa->rpi, csa->rdi, - csa->gap); - /* check if the current point is optimal */ - if (csa->rpi < 1e-8 && csa->rdi < 1e-8 && csa->gap < 1e-8) - { if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("OPTIMAL SOLUTION FOUND\n"); - status = 0; - break; - } - /* check if the problem has no feasible solution */ - temp = 1e5 * csa->phi_min[csa->iter]; - if (temp < 1e-8) temp = 1e-8; - if (csa->phi >= temp) - { if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("PROBLEM HAS NO FEASIBLE PRIMAL/DUAL SOLUTION\n") - ; - status = 1; - break; - } - /* check for very slow convergence or divergence */ - if (((csa->rpi >= 1e-8 || csa->rdi >= 1e-8) && csa->rmu / - csa->rmu0 >= 1e6) || - (csa->iter >= 30 && csa->phi_min[csa->iter] >= 0.5 * - csa->phi_min[csa->iter - 30])) - { if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("NO CONVERGENCE; SEARCH TERMINATED\n"); - status = 2; - break; - } - /* check for maximal number of iterations */ - if (csa->iter == ITER_MAX) - { if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("ITERATION LIMIT EXCEEDED; SEARCH TERMINATED\n"); - status = 3; - break; - } - /* start the next iteration */ - csa->iter++; - /* factorize normal equation system */ - for (j = 1; j <= n; j++) csa->D[j] = csa->x[j] / csa->z[j]; - decomp_NE(csa); - /* compute the next point using Mehrotra's predictor-corrector - technique */ - if (make_step(csa)) - { if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("NUMERIC INSTABILITY; SEARCH TERMINATED\n"); - status = 4; - break; - } - } - /* restore the best point */ - if (status != 0) - { for (j = 1; j <= n; j++) csa->x[j] = csa->best_x[j]; - for (i = 1; i <= m; i++) csa->y[i] = csa->best_y[i]; - for (j = 1; j <= n; j++) csa->z[j] = csa->best_z[j]; - if (csa->parm->msg_lev >= GLP_MSG_ALL) - xprintf("Best point %17.9e was reached on iteration %d\n", - csa->best_obj, csa->best_iter); - } - /* return to the calling program */ - return status; -} - -/*********************************************************************** -* NAME -* -* ipm_solve - core LP solver based on the interior-point method -* -* SYNOPSIS -* -* #include "glpipm.h" -* int ipm_solve(glp_prob *P, const glp_iptcp *parm); -* -* DESCRIPTION -* -* The routine ipm_solve is a core LP solver based on the primal-dual -* interior-point method. -* -* The routine assumes the following standard formulation of LP problem -* to be solved: -* -* minimize -* -* F = c[0] + c[1]*x[1] + c[2]*x[2] + ... + c[n]*x[n] -* -* subject to linear constraints -* -* a[1,1]*x[1] + a[1,2]*x[2] + ... + a[1,n]*x[n] = b[1] -* -* a[2,1]*x[1] + a[2,2]*x[2] + ... + a[2,n]*x[n] = b[2] -* -* . . . . . . -* -* a[m,1]*x[1] + a[m,2]*x[2] + ... + a[m,n]*x[n] = b[m] -* -* and non-negative variables -* -* x[1] >= 0, x[2] >= 0, ..., x[n] >= 0 -* -* where: -* F is the objective function; -* x[1], ..., x[n] are (structural) variables; -* c[0] is a constant term of the objective function; -* c[1], ..., c[n] are objective coefficients; -* a[1,1], ..., a[m,n] are constraint coefficients; -* b[1], ..., b[n] are right-hand sides. -* -* The solution is three vectors x, y, and z, which are stored by the -* routine in the arrays x, y, and z, respectively. These vectors -* correspond to the best primal-dual point found during optimization. -* They are approximate solution of the following system (which is the -* Karush-Kuhn-Tucker optimality conditions): -* -* A*x = b (primal feasibility condition) -* -* A'*y + z = c (dual feasibility condition) -* -* x'*z = 0 (primal-dual complementarity condition) -* -* x >= 0, z >= 0 (non-negativity condition) -* -* where: -* x[1], ..., x[n] are primal (structural) variables; -* y[1], ..., y[m] are dual variables (Lagrange multipliers) for -* equality constraints; -* z[1], ..., z[n] are dual variables (Lagrange multipliers) for -* non-negativity constraints. -* -* RETURNS -* -* 0 LP has been successfully solved. -* -* GLP_ENOCVG -* No convergence. -* -* GLP_EITLIM -* Iteration limit exceeded. -* -* GLP_EINSTAB -* Numeric instability on solving Newtonian system. -* -* In case of non-zero return code the routine returns the best point, -* which has been reached during optimization. */ - -int ipm_solve(glp_prob *P, const glp_iptcp *parm) -{ struct csa _dsa, *csa = &_dsa; - int m = P->m; - int n = P->n; - int nnz = P->nnz; - GLPROW *row; - GLPCOL *col; - GLPAIJ *aij; - int i, j, loc, ret, *A_ind, *A_ptr; - double dir, *A_val, *b, *c, *x, *y, *z; - xassert(m > 0); - xassert(n > 0); - /* allocate working arrays */ - A_ptr = xcalloc(1+m+1, sizeof(int)); - A_ind = xcalloc(1+nnz, sizeof(int)); - A_val = xcalloc(1+nnz, sizeof(double)); - b = xcalloc(1+m, sizeof(double)); - c = xcalloc(1+n, sizeof(double)); - x = xcalloc(1+n, sizeof(double)); - y = xcalloc(1+m, sizeof(double)); - z = xcalloc(1+n, sizeof(double)); - /* prepare rows and constraint coefficients */ - loc = 1; - for (i = 1; i <= m; i++) - { row = P->row[i]; - xassert(row->type == GLP_FX); - b[i] = row->lb * row->rii; - A_ptr[i] = loc; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { A_ind[loc] = aij->col->j; - A_val[loc] = row->rii * aij->val * aij->col->sjj; - loc++; - } - } - A_ptr[m+1] = loc; - xassert(loc-1 == nnz); - /* prepare columns and objective coefficients */ - if (P->dir == GLP_MIN) - dir = +1.0; - else if (P->dir == GLP_MAX) - dir = -1.0; - else - xassert(P != P); - c[0] = dir * P->c0; - for (j = 1; j <= n; j++) - { col = P->col[j]; - xassert(col->type == GLP_LO && col->lb == 0.0); - c[j] = dir * col->coef * col->sjj; - } - /* allocate and initialize the common storage area */ - csa->m = m; - csa->n = n; - csa->A_ptr = A_ptr; - csa->A_ind = A_ind; - csa->A_val = A_val; - csa->b = b; - csa->c = c; - csa->x = x; - csa->y = y; - csa->z = z; - csa->parm = parm; - initialize(csa); - /* solve LP with the interior-point method */ - ret = ipm_main(csa); - /* deallocate the common storage area */ - terminate(csa); - /* determine solution status */ - if (ret == 0) - { /* optimal solution found */ - P->ipt_stat = GLP_OPT; - ret = 0; - } - else if (ret == 1) - { /* problem has no feasible (primal or dual) solution */ - P->ipt_stat = GLP_NOFEAS; - ret = 0; - } - else if (ret == 2) - { /* no convergence */ - P->ipt_stat = GLP_INFEAS; - ret = GLP_ENOCVG; - } - else if (ret == 3) - { /* iteration limit exceeded */ - P->ipt_stat = GLP_INFEAS; - ret = GLP_EITLIM; - } - else if (ret == 4) - { /* numeric instability on solving Newtonian system */ - P->ipt_stat = GLP_INFEAS; - ret = GLP_EINSTAB; - } - else - xassert(ret != ret); - /* store row solution components */ - for (i = 1; i <= m; i++) - { row = P->row[i]; - row->pval = row->lb; - row->dval = dir * y[i] * row->rii; - } - /* store column solution components */ - P->ipt_obj = P->c0; - for (j = 1; j <= n; j++) - { col = P->col[j]; - col->pval = x[j] * col->sjj; - col->dval = dir * z[j] / col->sjj; - P->ipt_obj += col->coef * col->pval; - } - /* free working arrays */ - xfree(A_ptr); - xfree(A_ind); - xfree(A_val); - xfree(b); - xfree(c); - xfree(x); - xfree(y); - xfree(z); - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpipm.h b/resources/3rdparty/glpk-4.53/src/glpipm.h deleted file mode 100644 index a5f94fec1..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpipm.h +++ /dev/null @@ -1,36 +0,0 @@ -/* glpipm.h (primal-dual interior-point method) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPIPM_H -#define GLPIPM_H - -#include "prob.h" - -#define ipm_solve _glp_ipm_solve -int ipm_solve(glp_prob *P, const glp_iptcp *parm); -/* core LP solver based on the interior-point method */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpk.h b/resources/3rdparty/glpk-4.53/src/glpk.h deleted file mode 100644 index 86b8b913b..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpk.h +++ /dev/null @@ -1,1076 +0,0 @@ -/* glpk.h (GLPK API) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013, 2014 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPK_H -#define GLPK_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* library version numbers: */ -#define GLP_MAJOR_VERSION 4 -#define GLP_MINOR_VERSION 53 - -typedef struct glp_prob glp_prob; -/* LP/MIP problem object */ - -/* optimization direction flag: */ -#define GLP_MIN 1 /* minimization */ -#define GLP_MAX 2 /* maximization */ - -/* kind of structural variable: */ -#define GLP_CV 1 /* continuous variable */ -#define GLP_IV 2 /* integer variable */ -#define GLP_BV 3 /* binary variable */ - -/* type of auxiliary/structural variable: */ -#define GLP_FR 1 /* free (unbounded) variable */ -#define GLP_LO 2 /* variable with lower bound */ -#define GLP_UP 3 /* variable with upper bound */ -#define GLP_DB 4 /* double-bounded variable */ -#define GLP_FX 5 /* fixed variable */ - -/* status of auxiliary/structural variable: */ -#define GLP_BS 1 /* basic variable */ -#define GLP_NL 2 /* non-basic variable on lower bound */ -#define GLP_NU 3 /* non-basic variable on upper bound */ -#define GLP_NF 4 /* non-basic free (unbounded) variable */ -#define GLP_NS 5 /* non-basic fixed variable */ - -/* scaling options: */ -#define GLP_SF_GM 0x01 /* perform geometric mean scaling */ -#define GLP_SF_EQ 0x10 /* perform equilibration scaling */ -#define GLP_SF_2N 0x20 /* round scale factors to power of two */ -#define GLP_SF_SKIP 0x40 /* skip if problem is well scaled */ -#define GLP_SF_AUTO 0x80 /* choose scaling options automatically */ - -/* solution indicator: */ -#define GLP_SOL 1 /* basic solution */ -#define GLP_IPT 2 /* interior-point solution */ -#define GLP_MIP 3 /* mixed integer solution */ - -/* solution status: */ -#define GLP_UNDEF 1 /* solution is undefined */ -#define GLP_FEAS 2 /* solution is feasible */ -#define GLP_INFEAS 3 /* solution is infeasible */ -#define GLP_NOFEAS 4 /* no feasible solution exists */ -#define GLP_OPT 5 /* solution is optimal */ -#define GLP_UNBND 6 /* solution is unbounded */ - -typedef struct -{ /* basis factorization control parameters */ - int msg_lev; /* (reserved) */ - int type; /* factorization type: */ -#define GLP_BF_FT 1 /* LUF + Forrest-Tomlin */ -#define GLP_BF_BG 2 /* LUF + Schur compl. + Bartels-Golub */ -#define GLP_BF_GR 3 /* LUF + Schur compl. + Givens rotation */ - int lu_size; /* luf.sv_size */ - double piv_tol; /* luf.piv_tol */ - int piv_lim; /* luf.piv_lim */ - int suhl; /* luf.suhl */ - double eps_tol; /* luf.eps_tol */ - double max_gro; /* luf.max_gro */ - int nfs_max; /* fhv.hh_max */ - double upd_tol; /* fhv.upd_tol */ - int nrs_max; /* lpf.n_max */ - int rs_size; /* lpf.v_size */ - double foo_bar[38]; /* (reserved) */ -} glp_bfcp; - -typedef struct -{ /* simplex method control parameters */ - int msg_lev; /* message level: */ -#define GLP_MSG_OFF 0 /* no output */ -#define GLP_MSG_ERR 1 /* warning and error messages only */ -#define GLP_MSG_ON 2 /* normal output */ -#define GLP_MSG_ALL 3 /* full output */ -#define GLP_MSG_DBG 4 /* debug output */ - int meth; /* simplex method option: */ -#define GLP_PRIMAL 1 /* use primal simplex */ -#define GLP_DUALP 2 /* use dual; if it fails, use primal */ -#define GLP_DUAL 3 /* use dual simplex */ - int pricing; /* pricing technique: */ -#define GLP_PT_STD 0x11 /* standard (Dantzig rule) */ -#define GLP_PT_PSE 0x22 /* projected steepest edge */ - int r_test; /* ratio test technique: */ -#define GLP_RT_STD 0x11 /* standard (textbook) */ -#define GLP_RT_HAR 0x22 /* two-pass Harris' ratio test */ - double tol_bnd; /* spx.tol_bnd */ - double tol_dj; /* spx.tol_dj */ - double tol_piv; /* spx.tol_piv */ - double obj_ll; /* spx.obj_ll */ - double obj_ul; /* spx.obj_ul */ - int it_lim; /* spx.it_lim */ - int tm_lim; /* spx.tm_lim (milliseconds) */ - int out_frq; /* spx.out_frq */ - int out_dly; /* spx.out_dly (milliseconds) */ - int presolve; /* enable/disable using LP presolver */ - double foo_bar[36]; /* (reserved) */ -} glp_smcp; - -typedef struct -{ /* interior-point solver control parameters */ - int msg_lev; /* message level (see glp_smcp) */ - int ord_alg; /* ordering algorithm: */ -#define GLP_ORD_NONE 0 /* natural (original) ordering */ -#define GLP_ORD_QMD 1 /* quotient minimum degree (QMD) */ -#define GLP_ORD_AMD 2 /* approx. minimum degree (AMD) */ -#define GLP_ORD_SYMAMD 3 /* approx. minimum degree (SYMAMD) */ - double foo_bar[48]; /* (reserved) */ -} glp_iptcp; - -typedef struct glp_tree glp_tree; -/* branch-and-bound tree */ - -typedef struct -{ /* integer optimizer control parameters */ - int msg_lev; /* message level (see glp_smcp) */ - int br_tech; /* branching technique: */ -#define GLP_BR_FFV 1 /* first fractional variable */ -#define GLP_BR_LFV 2 /* last fractional variable */ -#define GLP_BR_MFV 3 /* most fractional variable */ -#define GLP_BR_DTH 4 /* heuristic by Driebeck and Tomlin */ -#define GLP_BR_PCH 5 /* hybrid pseudocost heuristic */ - int bt_tech; /* backtracking technique: */ -#define GLP_BT_DFS 1 /* depth first search */ -#define GLP_BT_BFS 2 /* breadth first search */ -#define GLP_BT_BLB 3 /* best local bound */ -#define GLP_BT_BPH 4 /* best projection heuristic */ - double tol_int; /* mip.tol_int */ - double tol_obj; /* mip.tol_obj */ - int tm_lim; /* mip.tm_lim (milliseconds) */ - int out_frq; /* mip.out_frq (milliseconds) */ - int out_dly; /* mip.out_dly (milliseconds) */ - void (*cb_func)(glp_tree *T, void *info); - /* mip.cb_func */ - void *cb_info; /* mip.cb_info */ - int cb_size; /* mip.cb_size */ - int pp_tech; /* preprocessing technique: */ -#define GLP_PP_NONE 0 /* disable preprocessing */ -#define GLP_PP_ROOT 1 /* preprocessing only on root level */ -#define GLP_PP_ALL 2 /* preprocessing on all levels */ - double mip_gap; /* relative MIP gap tolerance */ - int mir_cuts; /* MIR cuts (GLP_ON/GLP_OFF) */ - int gmi_cuts; /* Gomory's cuts (GLP_ON/GLP_OFF) */ - int cov_cuts; /* cover cuts (GLP_ON/GLP_OFF) */ - int clq_cuts; /* clique cuts (GLP_ON/GLP_OFF) */ - int presolve; /* enable/disable using MIP presolver */ - int binarize; /* try to binarize integer variables */ - int fp_heur; /* feasibility pump heuristic */ -#if 1 /* 25/V-2013 */ - int ps_heur; /* proximity search heuristic */ -#endif -#if 1 /* 29/VI-2013 */ - int ps_tm_lim; /* proxy time limit, milliseconds */ -#endif -#if 1 /* 11/VII-2013 */ - int use_sol; /* use existing solution */ - const char *save_sol; /* filename to save every new solution */ -#endif -#if 1 /* 28/V-2010 */ - int alien; /* use alien solver */ -#endif - double foo_bar[25]; /* (reserved) */ -} glp_iocp; - -typedef struct -{ /* additional row attributes */ - int level; - /* subproblem level at which the row was added */ - int origin; - /* row origin flag: */ -#define GLP_RF_REG 0 /* regular constraint */ -#define GLP_RF_LAZY 1 /* "lazy" constraint */ -#define GLP_RF_CUT 2 /* cutting plane constraint */ - int klass; - /* row class descriptor: */ -#define GLP_RF_GMI 1 /* Gomory's mixed integer cut */ -#define GLP_RF_MIR 2 /* mixed integer rounding cut */ -#define GLP_RF_COV 3 /* mixed cover cut */ -#define GLP_RF_CLQ 4 /* clique cut */ - double foo_bar[7]; - /* (reserved) */ -} glp_attr; - -/* enable/disable flag: */ -#define GLP_ON 1 /* enable something */ -#define GLP_OFF 0 /* disable something */ - -/* reason codes: */ -#define GLP_IROWGEN 0x01 /* request for row generation */ -#define GLP_IBINGO 0x02 /* better integer solution found */ -#define GLP_IHEUR 0x03 /* request for heuristic solution */ -#define GLP_ICUTGEN 0x04 /* request for cut generation */ -#define GLP_IBRANCH 0x05 /* request for branching */ -#define GLP_ISELECT 0x06 /* request for subproblem selection */ -#define GLP_IPREPRO 0x07 /* request for preprocessing */ - -/* branch selection indicator: */ -#define GLP_NO_BRNCH 0 /* select no branch */ -#define GLP_DN_BRNCH 1 /* select down-branch */ -#define GLP_UP_BRNCH 2 /* select up-branch */ - -/* return codes: */ -#define GLP_EBADB 0x01 /* invalid basis */ -#define GLP_ESING 0x02 /* singular matrix */ -#define GLP_ECOND 0x03 /* ill-conditioned matrix */ -#define GLP_EBOUND 0x04 /* invalid bounds */ -#define GLP_EFAIL 0x05 /* solver failed */ -#define GLP_EOBJLL 0x06 /* objective lower limit reached */ -#define GLP_EOBJUL 0x07 /* objective upper limit reached */ -#define GLP_EITLIM 0x08 /* iteration limit exceeded */ -#define GLP_ETMLIM 0x09 /* time limit exceeded */ -#define GLP_ENOPFS 0x0A /* no primal feasible solution */ -#define GLP_ENODFS 0x0B /* no dual feasible solution */ -#define GLP_EROOT 0x0C /* root LP optimum not provided */ -#define GLP_ESTOP 0x0D /* search terminated by application */ -#define GLP_EMIPGAP 0x0E /* relative mip gap tolerance reached */ -#define GLP_ENOFEAS 0x0F /* no primal/dual feasible solution */ -#define GLP_ENOCVG 0x10 /* no convergence */ -#define GLP_EINSTAB 0x11 /* numerical instability */ -#define GLP_EDATA 0x12 /* invalid data */ -#define GLP_ERANGE 0x13 /* result out of range */ - -/* condition indicator: */ -#define GLP_KKT_PE 1 /* primal equalities */ -#define GLP_KKT_PB 2 /* primal bounds */ -#define GLP_KKT_DE 3 /* dual equalities */ -#define GLP_KKT_DB 4 /* dual bounds */ -#define GLP_KKT_CS 5 /* complementary slackness */ - -/* MPS file format: */ -#define GLP_MPS_DECK 1 /* fixed (ancient) */ -#define GLP_MPS_FILE 2 /* free (modern) */ - -typedef struct -{ /* MPS format control parameters */ - int blank; - /* character code to replace blanks in symbolic names */ - char *obj_name; - /* objective row name */ - double tol_mps; - /* zero tolerance for MPS data */ - double foo_bar[17]; - /* (reserved for use in the future) */ -} glp_mpscp; - -typedef struct -{ /* CPLEX LP format control parameters */ - double foo_bar[20]; - /* (reserved for use in the future) */ -} glp_cpxcp; - -typedef struct glp_tran glp_tran; -/* MathProg translator workspace */ - -glp_prob *glp_create_prob(void); -/* create problem object */ - -void glp_set_prob_name(glp_prob *P, const char *name); -/* assign (change) problem name */ - -void glp_set_obj_name(glp_prob *P, const char *name); -/* assign (change) objective function name */ - -void glp_set_obj_dir(glp_prob *P, int dir); -/* set (change) optimization direction flag */ - -int glp_add_rows(glp_prob *P, int nrs); -/* add new rows to problem object */ - -int glp_add_cols(glp_prob *P, int ncs); -/* add new columns to problem object */ - -void glp_set_row_name(glp_prob *P, int i, const char *name); -/* assign (change) row name */ - -void glp_set_col_name(glp_prob *P, int j, const char *name); -/* assign (change) column name */ - -void glp_set_row_bnds(glp_prob *P, int i, int type, double lb, - double ub); -/* set (change) row bounds */ - -void glp_set_col_bnds(glp_prob *P, int j, int type, double lb, - double ub); -/* set (change) column bounds */ - -void glp_set_obj_coef(glp_prob *P, int j, double coef); -/* set (change) obj. coefficient or constant term */ - -void glp_set_mat_row(glp_prob *P, int i, int len, const int ind[], - const double val[]); -/* set (replace) row of the constraint matrix */ - -void glp_set_mat_col(glp_prob *P, int j, int len, const int ind[], - const double val[]); -/* set (replace) column of the constraint matrix */ - -void glp_load_matrix(glp_prob *P, int ne, const int ia[], - const int ja[], const double ar[]); -/* load (replace) the whole constraint matrix */ - -int glp_check_dup(int m, int n, int ne, const int ia[], const int ja[]); -/* check for duplicate elements in sparse matrix */ - -void glp_sort_matrix(glp_prob *P); -/* sort elements of the constraint matrix */ - -void glp_del_rows(glp_prob *P, int nrs, const int num[]); -/* delete specified rows from problem object */ - -void glp_del_cols(glp_prob *P, int ncs, const int num[]); -/* delete specified columns from problem object */ - -void glp_copy_prob(glp_prob *dest, glp_prob *prob, int names); -/* copy problem object content */ - -void glp_erase_prob(glp_prob *P); -/* erase problem object content */ - -void glp_delete_prob(glp_prob *P); -/* delete problem object */ - -const char *glp_get_prob_name(glp_prob *P); -/* retrieve problem name */ - -const char *glp_get_obj_name(glp_prob *P); -/* retrieve objective function name */ - -int glp_get_obj_dir(glp_prob *P); -/* retrieve optimization direction flag */ - -int glp_get_num_rows(glp_prob *P); -/* retrieve number of rows */ - -int glp_get_num_cols(glp_prob *P); -/* retrieve number of columns */ - -const char *glp_get_row_name(glp_prob *P, int i); -/* retrieve row name */ - -const char *glp_get_col_name(glp_prob *P, int j); -/* retrieve column name */ - -int glp_get_row_type(glp_prob *P, int i); -/* retrieve row type */ - -double glp_get_row_lb(glp_prob *P, int i); -/* retrieve row lower bound */ - -double glp_get_row_ub(glp_prob *P, int i); -/* retrieve row upper bound */ - -int glp_get_col_type(glp_prob *P, int j); -/* retrieve column type */ - -double glp_get_col_lb(glp_prob *P, int j); -/* retrieve column lower bound */ - -double glp_get_col_ub(glp_prob *P, int j); -/* retrieve column upper bound */ - -double glp_get_obj_coef(glp_prob *P, int j); -/* retrieve obj. coefficient or constant term */ - -int glp_get_num_nz(glp_prob *P); -/* retrieve number of constraint coefficients */ - -int glp_get_mat_row(glp_prob *P, int i, int ind[], double val[]); -/* retrieve row of the constraint matrix */ - -int glp_get_mat_col(glp_prob *P, int j, int ind[], double val[]); -/* retrieve column of the constraint matrix */ - -void glp_create_index(glp_prob *P); -/* create the name index */ - -int glp_find_row(glp_prob *P, const char *name); -/* find row by its name */ - -int glp_find_col(glp_prob *P, const char *name); -/* find column by its name */ - -void glp_delete_index(glp_prob *P); -/* delete the name index */ - -void glp_set_rii(glp_prob *P, int i, double rii); -/* set (change) row scale factor */ - -void glp_set_sjj(glp_prob *P, int j, double sjj); -/* set (change) column scale factor */ - -double glp_get_rii(glp_prob *P, int i); -/* retrieve row scale factor */ - -double glp_get_sjj(glp_prob *P, int j); -/* retrieve column scale factor */ - -void glp_scale_prob(glp_prob *P, int flags); -/* scale problem data */ - -void glp_unscale_prob(glp_prob *P); -/* unscale problem data */ - -void glp_set_row_stat(glp_prob *P, int i, int stat); -/* set (change) row status */ - -void glp_set_col_stat(glp_prob *P, int j, int stat); -/* set (change) column status */ - -void glp_std_basis(glp_prob *P); -/* construct standard initial LP basis */ - -void glp_adv_basis(glp_prob *P, int flags); -/* construct advanced initial LP basis */ - -void glp_cpx_basis(glp_prob *P); -/* construct Bixby's initial LP basis */ - -int glp_simplex(glp_prob *P, const glp_smcp *parm); -/* solve LP problem with the simplex method */ - -int glp_exact(glp_prob *P, const glp_smcp *parm); -/* solve LP problem in exact arithmetic */ - -void glp_init_smcp(glp_smcp *parm); -/* initialize simplex method control parameters */ - -int glp_get_status(glp_prob *P); -/* retrieve generic status of basic solution */ - -int glp_get_prim_stat(glp_prob *P); -/* retrieve status of primal basic solution */ - -int glp_get_dual_stat(glp_prob *P); -/* retrieve status of dual basic solution */ - -double glp_get_obj_val(glp_prob *P); -/* retrieve objective value (basic solution) */ - -int glp_get_row_stat(glp_prob *P, int i); -/* retrieve row status */ - -double glp_get_row_prim(glp_prob *P, int i); -/* retrieve row primal value (basic solution) */ - -double glp_get_row_dual(glp_prob *P, int i); -/* retrieve row dual value (basic solution) */ - -int glp_get_col_stat(glp_prob *P, int j); -/* retrieve column status */ - -double glp_get_col_prim(glp_prob *P, int j); -/* retrieve column primal value (basic solution) */ - -double glp_get_col_dual(glp_prob *P, int j); -/* retrieve column dual value (basic solution) */ - -int glp_get_unbnd_ray(glp_prob *P); -/* determine variable causing unboundedness */ - -#if 1 /* 08/VIII-2013; not documented yet */ -int glp_get_it_cnt(glp_prob *P); -/* get simplex solver iteration count */ -#endif - -#if 1 /* 08/VIII-2013; not documented yet */ -int glp_set_it_cnt(glp_prob *P, int it_cnt); -/* set simplex solver iteration count */ -#endif - -int glp_interior(glp_prob *P, const glp_iptcp *parm); -/* solve LP problem with the interior-point method */ - -void glp_init_iptcp(glp_iptcp *parm); -/* initialize interior-point solver control parameters */ - -int glp_ipt_status(glp_prob *P); -/* retrieve status of interior-point solution */ - -double glp_ipt_obj_val(glp_prob *P); -/* retrieve objective value (interior point) */ - -double glp_ipt_row_prim(glp_prob *P, int i); -/* retrieve row primal value (interior point) */ - -double glp_ipt_row_dual(glp_prob *P, int i); -/* retrieve row dual value (interior point) */ - -double glp_ipt_col_prim(glp_prob *P, int j); -/* retrieve column primal value (interior point) */ - -double glp_ipt_col_dual(glp_prob *P, int j); -/* retrieve column dual value (interior point) */ - -void glp_set_col_kind(glp_prob *P, int j, int kind); -/* set (change) column kind */ - -int glp_get_col_kind(glp_prob *P, int j); -/* retrieve column kind */ - -int glp_get_num_int(glp_prob *P); -/* retrieve number of integer columns */ - -int glp_get_num_bin(glp_prob *P); -/* retrieve number of binary columns */ - -int glp_intopt(glp_prob *P, const glp_iocp *parm); -/* solve MIP problem with the branch-and-bound method */ - -void glp_init_iocp(glp_iocp *parm); -/* initialize integer optimizer control parameters */ - -int glp_mip_status(glp_prob *P); -/* retrieve status of MIP solution */ - -double glp_mip_obj_val(glp_prob *P); -/* retrieve objective value (MIP solution) */ - -double glp_mip_row_val(glp_prob *P, int i); -/* retrieve row value (MIP solution) */ - -double glp_mip_col_val(glp_prob *P, int j); -/* retrieve column value (MIP solution) */ - -void glp_check_kkt(glp_prob *P, int sol, int cond, double *ae_max, - int *ae_ind, double *re_max, int *re_ind); -/* check feasibility/optimality conditions */ - -int glp_print_sol(glp_prob *P, const char *fname); -/* write basic solution in printable format */ - -int glp_read_sol(glp_prob *P, const char *fname); -/* read basic solution from text file */ - -int glp_write_sol(glp_prob *P, const char *fname); -/* write basic solution to text file */ - -int glp_print_ranges(glp_prob *P, int len, const int list[], - int flags, const char *fname); -/* print sensitivity analysis report */ - -int glp_print_ipt(glp_prob *P, const char *fname); -/* write interior-point solution in printable format */ - -int glp_read_ipt(glp_prob *P, const char *fname); -/* read interior-point solution from text file */ - -int glp_write_ipt(glp_prob *P, const char *fname); -/* write interior-point solution to text file */ - -int glp_print_mip(glp_prob *P, const char *fname); -/* write MIP solution in printable format */ - -int glp_read_mip(glp_prob *P, const char *fname); -/* read MIP solution from text file */ - -int glp_write_mip(glp_prob *P, const char *fname); -/* write MIP solution to text file */ - -int glp_bf_exists(glp_prob *P); -/* check if the basis factorization exists */ - -int glp_factorize(glp_prob *P); -/* compute the basis factorization */ - -int glp_bf_updated(glp_prob *P); -/* check if the basis factorization has been updated */ - -void glp_get_bfcp(glp_prob *P, glp_bfcp *parm); -/* retrieve basis factorization control parameters */ - -void glp_set_bfcp(glp_prob *P, const glp_bfcp *parm); -/* change basis factorization control parameters */ - -int glp_get_bhead(glp_prob *P, int k); -/* retrieve the basis header information */ - -int glp_get_row_bind(glp_prob *P, int i); -/* retrieve row index in the basis header */ - -int glp_get_col_bind(glp_prob *P, int j); -/* retrieve column index in the basis header */ - -void glp_ftran(glp_prob *P, double x[]); -/* perform forward transformation (solve system B*x = b) */ - -void glp_btran(glp_prob *P, double x[]); -/* perform backward transformation (solve system B'*x = b) */ - -int glp_warm_up(glp_prob *P); -/* "warm up" LP basis */ - -int glp_eval_tab_row(glp_prob *P, int k, int ind[], double val[]); -/* compute row of the simplex tableau */ - -int glp_eval_tab_col(glp_prob *P, int k, int ind[], double val[]); -/* compute column of the simplex tableau */ - -int glp_transform_row(glp_prob *P, int len, int ind[], double val[]); -/* transform explicitly specified row */ - -int glp_transform_col(glp_prob *P, int len, int ind[], double val[]); -/* transform explicitly specified column */ - -int glp_prim_rtest(glp_prob *P, int len, const int ind[], - const double val[], int dir, double eps); -/* perform primal ratio test */ - -int glp_dual_rtest(glp_prob *P, int len, const int ind[], - const double val[], int dir, double eps); -/* perform dual ratio test */ - -void glp_analyze_bound(glp_prob *P, int k, double *value1, int *var1, - double *value2, int *var2); -/* analyze active bound of non-basic variable */ - -void glp_analyze_coef(glp_prob *P, int k, double *coef1, int *var1, - double *value1, double *coef2, int *var2, double *value2); -/* analyze objective coefficient at basic variable */ - -int glp_ios_reason(glp_tree *T); -/* determine reason for calling the callback routine */ - -glp_prob *glp_ios_get_prob(glp_tree *T); -/* access the problem object */ - -void glp_ios_tree_size(glp_tree *T, int *a_cnt, int *n_cnt, - int *t_cnt); -/* determine size of the branch-and-bound tree */ - -int glp_ios_curr_node(glp_tree *T); -/* determine current active subproblem */ - -int glp_ios_next_node(glp_tree *T, int p); -/* determine next active subproblem */ - -int glp_ios_prev_node(glp_tree *T, int p); -/* determine previous active subproblem */ - -int glp_ios_up_node(glp_tree *T, int p); -/* determine parent subproblem */ - -int glp_ios_node_level(glp_tree *T, int p); -/* determine subproblem level */ - -double glp_ios_node_bound(glp_tree *T, int p); -/* determine subproblem local bound */ - -int glp_ios_best_node(glp_tree *T); -/* find active subproblem with best local bound */ - -double glp_ios_mip_gap(glp_tree *T); -/* compute relative MIP gap */ - -void *glp_ios_node_data(glp_tree *T, int p); -/* access subproblem application-specific data */ - -void glp_ios_row_attr(glp_tree *T, int i, glp_attr *attr); -/* retrieve additional row attributes */ - -int glp_ios_pool_size(glp_tree *T); -/* determine current size of the cut pool */ - -int glp_ios_add_row(glp_tree *T, - const char *name, int klass, int flags, int len, const int ind[], - const double val[], int type, double rhs); -/* add row (constraint) to the cut pool */ - -void glp_ios_del_row(glp_tree *T, int i); -/* remove row (constraint) from the cut pool */ - -void glp_ios_clear_pool(glp_tree *T); -/* remove all rows (constraints) from the cut pool */ - -int glp_ios_can_branch(glp_tree *T, int j); -/* check if can branch upon specified variable */ - -void glp_ios_branch_upon(glp_tree *T, int j, int sel); -/* choose variable to branch upon */ - -void glp_ios_select_node(glp_tree *T, int p); -/* select subproblem to continue the search */ - -int glp_ios_heur_sol(glp_tree *T, const double x[]); -/* provide solution found by heuristic */ - -void glp_ios_terminate(glp_tree *T); -/* terminate the solution process */ - -void glp_init_mpscp(glp_mpscp *parm); -/* initialize MPS format control parameters */ - -int glp_read_mps(glp_prob *P, int fmt, const glp_mpscp *parm, - const char *fname); -/* read problem data in MPS format */ - -int glp_write_mps(glp_prob *P, int fmt, const glp_mpscp *parm, - const char *fname); -/* write problem data in MPS format */ - -void glp_init_cpxcp(glp_cpxcp *parm); -/* initialize CPLEX LP format control parameters */ - -int glp_read_lp(glp_prob *P, const glp_cpxcp *parm, const char *fname); -/* read problem data in CPLEX LP format */ - -int glp_write_lp(glp_prob *P, const glp_cpxcp *parm, const char *fname); -/* write problem data in CPLEX LP format */ - -int glp_read_prob(glp_prob *P, int flags, const char *fname); -/* read problem data in GLPK format */ - -int glp_write_prob(glp_prob *P, int flags, const char *fname); -/* write problem data in GLPK format */ - -glp_tran *glp_mpl_alloc_wksp(void); -/* allocate the MathProg translator workspace */ - -int glp_mpl_read_model(glp_tran *tran, const char *fname, int skip); -/* read and translate model section */ - -int glp_mpl_read_data(glp_tran *tran, const char *fname); -/* read and translate data section */ - -int glp_mpl_generate(glp_tran *tran, const char *fname); -/* generate the model */ - -void glp_mpl_build_prob(glp_tran *tran, glp_prob *prob); -/* build LP/MIP problem instance from the model */ - -int glp_mpl_postsolve(glp_tran *tran, glp_prob *prob, int sol); -/* postsolve the model */ - -void glp_mpl_free_wksp(glp_tran *tran); -/* free the MathProg translator workspace */ - -int glp_main(int argc, const char *argv[]); -/* stand-alone LP/MIP solver */ - -int glp_read_cnfsat(glp_prob *P, const char *fname); -/* read CNF-SAT problem data in DIMACS format */ - -int glp_check_cnfsat(glp_prob *P); -/* check for CNF-SAT problem instance */ - -int glp_write_cnfsat(glp_prob *P, const char *fname); -/* write CNF-SAT problem data in DIMACS format */ - -int glp_minisat1(glp_prob *P); -/* solve CNF-SAT problem with MiniSat solver */ - -int glp_intfeas1(glp_prob *P, int use_bound, int obj_bound); -/* solve integer feasibility problem */ - -int glp_init_env(void); -/* initialize GLPK environment */ - -const char *glp_version(void); -/* determine library version */ - -int glp_free_env(void); -/* free GLPK environment */ - -void glp_puts(const char *s); -/* write string on terminal */ - -void glp_printf(const char *fmt, ...); -/* write formatted output on terminal */ - -void glp_vprintf(const char *fmt, va_list arg); -/* write formatted output on terminal */ - -int glp_term_out(int flag); -/* enable/disable terminal output */ - -void glp_term_hook(int (*func)(void *info, const char *s), void *info); -/* install hook to intercept terminal output */ - -int glp_open_tee(const char *name); -/* start copying terminal output to text file */ - -int glp_close_tee(void); -/* stop copying terminal output to text file */ - -#ifndef GLP_ERRFUNC_DEFINED -#define GLP_ERRFUNC_DEFINED -typedef void (*glp_errfunc)(const char *fmt, ...); -#endif - -#define glp_error glp_error_(__FILE__, __LINE__) -glp_errfunc glp_error_(const char *file, int line); -/* display fatal error message and terminate execution */ - -#define glp_assert(expr) \ - ((void)((expr) || (glp_assert_(#expr, __FILE__, __LINE__), 1))) -void glp_assert_(const char *expr, const char *file, int line); -/* check for logical condition */ - -void glp_error_hook(void (*func)(void *info), void *info); -/* install hook to intercept abnormal termination */ - -#define glp_malloc(size) glp_alloc(1, size) -/* allocate memory block (obsolete) */ - -#define glp_calloc(n, size) glp_alloc(n, size) -/* allocate memory block (obsolete) */ - -void *glp_alloc(int n, int size); -/* allocate memory block */ - -void *glp_realloc(void *ptr, int n, int size); -/* reallocate memory block */ - -void glp_free(void *ptr); -/* free (deallocate) memory block */ - -void glp_mem_limit(int limit); -/* set memory usage limit */ - -void glp_mem_usage(int *count, int *cpeak, size_t *total, - size_t *tpeak); -/* get memory usage information */ - -typedef struct glp_graph glp_graph; -typedef struct glp_vertex glp_vertex; -typedef struct glp_arc glp_arc; - -struct glp_graph -{ /* graph descriptor */ - void *pool; /* DMP *pool; */ - /* memory pool to store graph components */ - char *name; - /* graph name (1 to 255 chars); NULL means no name is assigned - to the graph */ - int nv_max; - /* length of the vertex list (enlarged automatically) */ - int nv; - /* number of vertices in the graph, 0 <= nv <= nv_max */ - int na; - /* number of arcs in the graph, na >= 0 */ - glp_vertex **v; /* glp_vertex *v[1+nv_max]; */ - /* v[i], 1 <= i <= nv, is a pointer to i-th vertex */ - void *index; /* AVL *index; */ - /* vertex index to find vertices by their names; NULL means the - index does not exist */ - int v_size; - /* size of data associated with each vertex (0 to 256 bytes) */ - int a_size; - /* size of data associated with each arc (0 to 256 bytes) */ -}; - -struct glp_vertex -{ /* vertex descriptor */ - int i; - /* vertex ordinal number, 1 <= i <= nv */ - char *name; - /* vertex name (1 to 255 chars); NULL means no name is assigned - to the vertex */ - void *entry; /* AVLNODE *entry; */ - /* pointer to corresponding entry in the vertex index; NULL means - that either the index does not exist or the vertex has no name - assigned */ - void *data; - /* pointer to data associated with the vertex */ - void *temp; - /* working pointer */ - glp_arc *in; - /* pointer to the (unordered) list of incoming arcs */ - glp_arc *out; - /* pointer to the (unordered) list of outgoing arcs */ -}; - -struct glp_arc -{ /* arc descriptor */ - glp_vertex *tail; - /* pointer to the tail endpoint */ - glp_vertex *head; - /* pointer to the head endpoint */ - void *data; - /* pointer to data associated with the arc */ - void *temp; - /* working pointer */ - glp_arc *t_prev; - /* pointer to previous arc having the same tail endpoint */ - glp_arc *t_next; - /* pointer to next arc having the same tail endpoint */ - glp_arc *h_prev; - /* pointer to previous arc having the same head endpoint */ - glp_arc *h_next; - /* pointer to next arc having the same head endpoint */ -}; - -glp_graph *glp_create_graph(int v_size, int a_size); -/* create graph */ - -void glp_set_graph_name(glp_graph *G, const char *name); -/* assign (change) graph name */ - -int glp_add_vertices(glp_graph *G, int nadd); -/* add new vertices to graph */ - -void glp_set_vertex_name(glp_graph *G, int i, const char *name); -/* assign (change) vertex name */ - -glp_arc *glp_add_arc(glp_graph *G, int i, int j); -/* add new arc to graph */ - -void glp_del_vertices(glp_graph *G, int ndel, const int num[]); -/* delete vertices from graph */ - -void glp_del_arc(glp_graph *G, glp_arc *a); -/* delete arc from graph */ - -void glp_erase_graph(glp_graph *G, int v_size, int a_size); -/* erase graph content */ - -void glp_delete_graph(glp_graph *G); -/* delete graph */ - -void glp_create_v_index(glp_graph *G); -/* create vertex name index */ - -int glp_find_vertex(glp_graph *G, const char *name); -/* find vertex by its name */ - -void glp_delete_v_index(glp_graph *G); -/* delete vertex name index */ - -int glp_read_graph(glp_graph *G, const char *fname); -/* read graph from plain text file */ - -int glp_write_graph(glp_graph *G, const char *fname); -/* write graph to plain text file */ - -void glp_mincost_lp(glp_prob *P, glp_graph *G, int names, int v_rhs, - int a_low, int a_cap, int a_cost); -/* convert minimum cost flow problem to LP */ - -int glp_mincost_okalg(glp_graph *G, int v_rhs, int a_low, int a_cap, - int a_cost, double *sol, int a_x, int v_pi); -/* find minimum-cost flow with out-of-kilter algorithm */ - -int glp_mincost_relax4(glp_graph *G, int v_rhs, int a_low, int a_cap, - int a_cost, int crash, double *sol, int a_x, int a_rc); -/* find minimum-cost flow with Bertsekas-Tseng relaxation method */ - -void glp_maxflow_lp(glp_prob *P, glp_graph *G, int names, int s, - int t, int a_cap); -/* convert maximum flow problem to LP */ - -int glp_maxflow_ffalg(glp_graph *G, int s, int t, int a_cap, - double *sol, int a_x, int v_cut); -/* find maximal flow with Ford-Fulkerson algorithm */ - -int glp_check_asnprob(glp_graph *G, int v_set); -/* check correctness of assignment problem data */ - -/* assignment problem formulation: */ -#define GLP_ASN_MIN 1 /* perfect matching (minimization) */ -#define GLP_ASN_MAX 2 /* perfect matching (maximization) */ -#define GLP_ASN_MMP 3 /* maximum matching */ - -int glp_asnprob_lp(glp_prob *P, int form, glp_graph *G, int names, - int v_set, int a_cost); -/* convert assignment problem to LP */ - -int glp_asnprob_okalg(int form, glp_graph *G, int v_set, int a_cost, - double *sol, int a_x); -/* solve assignment problem with out-of-kilter algorithm */ - -int glp_asnprob_hall(glp_graph *G, int v_set, int a_x); -/* find bipartite matching of maximum cardinality */ - -double glp_cpp(glp_graph *G, int v_t, int v_es, int v_ls); -/* solve critical path problem */ - -int glp_read_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, - int a_cost, const char *fname); -/* read min-cost flow problem data in DIMACS format */ - -int glp_write_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, - int a_cost, const char *fname); -/* write min-cost flow problem data in DIMACS format */ - -int glp_read_maxflow(glp_graph *G, int *s, int *t, int a_cap, - const char *fname); -/* read maximum flow problem data in DIMACS format */ - -int glp_write_maxflow(glp_graph *G, int s, int t, int a_cap, - const char *fname); -/* write maximum flow problem data in DIMACS format */ - -int glp_read_asnprob(glp_graph *G, int v_set, int a_cost, const char - *fname); -/* read assignment problem data in DIMACS format */ - -int glp_write_asnprob(glp_graph *G, int v_set, int a_cost, const char - *fname); -/* write assignment problem data in DIMACS format */ - -int glp_read_ccdata(glp_graph *G, int v_wgt, const char *fname); -/* read graph in DIMACS clique/coloring format */ - -int glp_write_ccdata(glp_graph *G, int v_wgt, const char *fname); -/* write graph in DIMACS clique/coloring format */ - -int glp_netgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, - const int parm[1+15]); -/* Klingman's network problem generator */ - -void glp_netgen_prob(int nprob, int parm[1+15]); -/* Klingman's standard network problem instance */ - -int glp_gridgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, - const int parm[1+14]); -/* grid-like network problem generator */ - -int glp_rmfgen(glp_graph *G, int *s, int *t, int a_cap, - const int parm[1+5]); -/* Goldfarb's maximum flow problem generator */ - -int glp_weak_comp(glp_graph *G, int v_num); -/* find all weakly connected components of graph */ - -int glp_strong_comp(glp_graph *G, int v_num); -/* find all strongly connected components of graph */ - -int glp_top_sort(glp_graph *G, int v_num); -/* topological sorting of acyclic digraph */ - -int glp_wclique_exact(glp_graph *G, int v_wgt, double *sol, int v_set); -/* find maximum weight clique with exact algorithm */ - -#ifdef __cplusplus -} -#endif - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glplpf.c b/resources/3rdparty/glpk-4.53/src/glplpf.c deleted file mode 100644 index 8f858531d..000000000 --- a/resources/3rdparty/glpk-4.53/src/glplpf.c +++ /dev/null @@ -1,1097 +0,0 @@ -/* glplpf.c (LP basis factorization, Schur complement version) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glplpf.h" - -#define xfault xerror - -#define GLPLPF_DEBUG 0 - -/* CAUTION: DO NOT CHANGE THE LIMIT BELOW */ - -#define M_MAX 100000000 /* = 100*10^6 */ -/* maximal order of the basis matrix */ - -/*********************************************************************** -* NAME -* -* lpf_create_it - create LP basis factorization -* -* SYNOPSIS -* -* #include "glplpf.h" -* LPF *lpf_create_it(void); -* -* DESCRIPTION -* -* The routine lpf_create_it creates a program object, which represents -* a factorization of LP basis. -* -* RETURNS -* -* The routine lpf_create_it returns a pointer to the object created. */ - -LPF *lpf_create_it(void) -{ LPF *lpf; -#if GLPLPF_DEBUG - xprintf("lpf_create_it: warning: debug mode enabled\n"); -#endif - lpf = xmalloc(sizeof(LPF)); - lpf->valid = 0; - lpf->m0_max = lpf->m0 = 0; -#if 0 /* 06/VI-2013 */ - lpf->luf = luf_create_it(); -#else - lpf->lufint = lufint_create(); -#endif - lpf->m = 0; - lpf->B = NULL; - lpf->n_max = 50; - lpf->n = 0; - lpf->R_ptr = lpf->R_len = NULL; - lpf->S_ptr = lpf->S_len = NULL; -#if 0 /* 11/VIII-2013 */ - lpf->scf = NULL; -#else - lpf->ifu.n_max = 0; - lpf->ifu.n = 0; - lpf->ifu.f = NULL; - lpf->ifu.u = NULL; - lpf->t_opt = 0; -#endif - lpf->P_row = lpf->P_col = NULL; - lpf->Q_row = lpf->Q_col = NULL; - lpf->v_size = 1000; - lpf->v_ptr = 0; - lpf->v_ind = NULL; - lpf->v_val = NULL; - lpf->work1 = lpf->work2 = NULL; - return lpf; -} - -/*********************************************************************** -* NAME -* -* lpf_factorize - compute LP basis factorization -* -* SYNOPSIS -* -* #include "glplpf.h" -* int lpf_factorize(LPF *lpf, int m, const int bh[], int (*col) -* (void *info, int j, int ind[], double val[]), void *info); -* -* DESCRIPTION -* -* The routine lpf_factorize computes the factorization of the basis -* matrix B specified by the routine col. -* -* The parameter lpf specified the basis factorization data structure -* created with the routine lpf_create_it. -* -* The parameter m specifies the order of B, m > 0. -* -* The array bh specifies the basis header: bh[j], 1 <= j <= m, is the -* number of j-th column of B in some original matrix. The array bh is -* optional and can be specified as NULL. -* -* The formal routine col specifies the matrix B to be factorized. To -* obtain j-th column of A the routine lpf_factorize calls the routine -* col with the parameter j (1 <= j <= n). In response the routine col -* should store row indices and numerical values of non-zero elements -* of j-th column of B to locations ind[1,...,len] and val[1,...,len], -* respectively, where len is the number of non-zeros in j-th column -* returned on exit. Neither zero nor duplicate elements are allowed. -* -* The parameter info is a transit pointer passed to the routine col. -* -* RETURNS -* -* 0 The factorization has been successfully computed. -* -* LPF_ESING -* The specified matrix is singular within the working precision. -* -* LPF_ECOND -* The specified matrix is ill-conditioned. -* -* For more details see comments to the routine luf_factorize. */ - -int lpf_factorize(LPF *lpf, int m, const int bh[], int (*col) - (void *info, int j, int ind[], double val[]), void *info) -{ int k, ret; -#if GLPLPF_DEBUG - int i, j, len, *ind; - double *B, *val; -#endif - xassert(bh == bh); - if (m < 1) - xfault("lpf_factorize: m = %d; invalid parameter\n", m); - if (m > M_MAX) - xfault("lpf_factorize: m = %d; matrix too big\n", m); - lpf->m0 = lpf->m = m; - /* invalidate the factorization */ - lpf->valid = 0; - /* allocate/reallocate arrays, if necessary */ - if (lpf->R_ptr == NULL) - lpf->R_ptr = xcalloc(1+lpf->n_max, sizeof(int)); - if (lpf->R_len == NULL) - lpf->R_len = xcalloc(1+lpf->n_max, sizeof(int)); - if (lpf->S_ptr == NULL) - lpf->S_ptr = xcalloc(1+lpf->n_max, sizeof(int)); - if (lpf->S_len == NULL) - lpf->S_len = xcalloc(1+lpf->n_max, sizeof(int)); -#if 0 /* 11/VIII-2013 */ - if (lpf->scf == NULL) - lpf->scf = scf_create_it(lpf->n_max); -#else - if (lpf->ifu.n_max == 0) - { int n_max = lpf->n_max; - lpf->ifu.n_max = n_max; - lpf->ifu.n = 0; - xassert(n_max > 0); - xassert(lpf->ifu.f == NULL); - lpf->ifu.f = talloc(n_max * n_max, double); - xassert(lpf->ifu.u == NULL); - lpf->ifu.u = talloc(n_max * n_max, double); - lpf->t_opt = 0; - } -#endif - if (lpf->v_ind == NULL) - lpf->v_ind = xcalloc(1+lpf->v_size, sizeof(int)); - if (lpf->v_val == NULL) - lpf->v_val = xcalloc(1+lpf->v_size, sizeof(double)); - if (lpf->m0_max < m) - { if (lpf->P_row != NULL) xfree(lpf->P_row); - if (lpf->P_col != NULL) xfree(lpf->P_col); - if (lpf->Q_row != NULL) xfree(lpf->Q_row); - if (lpf->Q_col != NULL) xfree(lpf->Q_col); - if (lpf->work1 != NULL) xfree(lpf->work1); - if (lpf->work2 != NULL) xfree(lpf->work2); - lpf->m0_max = m + 100; - lpf->P_row = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int)); - lpf->P_col = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int)); - lpf->Q_row = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int)); - lpf->Q_col = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int)); - lpf->work1 = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(double)); - lpf->work2 = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(double)); - } - /* try to factorize the basis matrix */ -#if 0 /* 06/VI-2013 */ - switch (luf_factorize(lpf->luf, m, col, info)) - { case 0: - break; - case LUF_ESING: - ret = LPF_ESING; - goto done; - case LUF_ECOND: - ret = LPF_ECOND; - goto done; - default: - xassert(lpf != lpf); - } -#else - if (lufint_factorize(lpf->lufint, m, col, info) != 0) - { ret = LPF_ESING; - goto done; - } -#endif - /* the basis matrix has been successfully factorized */ - lpf->valid = 1; -#if GLPLPF_DEBUG - /* store the basis matrix for debugging */ - if (lpf->B != NULL) xfree(lpf->B); - xassert(m <= 32767); - lpf->B = B = xcalloc(1+m*m, sizeof(double)); - ind = xcalloc(1+m, sizeof(int)); - val = xcalloc(1+m, sizeof(double)); - for (k = 1; k <= m * m; k++) - B[k] = 0.0; - for (j = 1; j <= m; j++) - { len = col(info, j, ind, val); - xassert(0 <= len && len <= m); - for (k = 1; k <= len; k++) - { i = ind[k]; - xassert(1 <= i && i <= m); - xassert(B[(i - 1) * m + j] == 0.0); - xassert(val[k] != 0.0); - B[(i - 1) * m + j] = val[k]; - } - } - xfree(ind); - xfree(val); -#endif - /* B = B0, so there are no additional rows/columns */ - lpf->n = 0; - /* reset the Schur complement factorization */ -#if 0 /* 11/VIII-2013 */ - scf_reset_it(lpf->scf); -#else - lpf->ifu.n = 0; -#endif - /* P := Q := I */ - for (k = 1; k <= m; k++) - { lpf->P_row[k] = lpf->P_col[k] = k; - lpf->Q_row[k] = lpf->Q_col[k] = k; - } - /* make all SVA locations free */ - lpf->v_ptr = 1; - ret = 0; -done: /* return to the calling program */ - return ret; -} - -/*********************************************************************** -* The routine r_prod computes the product y := y + alpha * R * x, -* where x is a n-vector, alpha is a scalar, y is a m0-vector. -* -* Since matrix R is available by columns, the product is computed as -* a linear combination: -* -* y := y + alpha * (R[1] * x[1] + ... + R[n] * x[n]), -* -* where R[j] is j-th column of R. */ - -static void r_prod(LPF *lpf, double y[], double a, const double x[]) -{ int n = lpf->n; - int *R_ptr = lpf->R_ptr; - int *R_len = lpf->R_len; - int *v_ind = lpf->v_ind; - double *v_val = lpf->v_val; - int j, beg, end, ptr; - double t; - for (j = 1; j <= n; j++) - { if (x[j] == 0.0) continue; - /* y := y + alpha * R[j] * x[j] */ - t = a * x[j]; - beg = R_ptr[j]; - end = beg + R_len[j]; - for (ptr = beg; ptr < end; ptr++) - y[v_ind[ptr]] += t * v_val[ptr]; - } - return; -} - -/*********************************************************************** -* The routine rt_prod computes the product y := y + alpha * R' * x, -* where R' is a matrix transposed to R, x is a m0-vector, alpha is a -* scalar, y is a n-vector. -* -* Since matrix R is available by columns, the product components are -* computed as inner products: -* -* y[j] := y[j] + alpha * (j-th column of R) * x -* -* for j = 1, 2, ..., n. */ - -static void rt_prod(LPF *lpf, double y[], double a, const double x[]) -{ int n = lpf->n; - int *R_ptr = lpf->R_ptr; - int *R_len = lpf->R_len; - int *v_ind = lpf->v_ind; - double *v_val = lpf->v_val; - int j, beg, end, ptr; - double t; - for (j = 1; j <= n; j++) - { /* t := (j-th column of R) * x */ - t = 0.0; - beg = R_ptr[j]; - end = beg + R_len[j]; - for (ptr = beg; ptr < end; ptr++) - t += v_val[ptr] * x[v_ind[ptr]]; - /* y[j] := y[j] + alpha * t */ - y[j] += a * t; - } - return; -} - -/*********************************************************************** -* The routine s_prod computes the product y := y + alpha * S * x, -* where x is a m0-vector, alpha is a scalar, y is a n-vector. -* -* Since matrix S is available by rows, the product components are -* computed as inner products: -* -* y[i] = y[i] + alpha * (i-th row of S) * x -* -* for i = 1, 2, ..., n. */ - -static void s_prod(LPF *lpf, double y[], double a, const double x[]) -{ int n = lpf->n; - int *S_ptr = lpf->S_ptr; - int *S_len = lpf->S_len; - int *v_ind = lpf->v_ind; - double *v_val = lpf->v_val; - int i, beg, end, ptr; - double t; - for (i = 1; i <= n; i++) - { /* t := (i-th row of S) * x */ - t = 0.0; - beg = S_ptr[i]; - end = beg + S_len[i]; - for (ptr = beg; ptr < end; ptr++) - t += v_val[ptr] * x[v_ind[ptr]]; - /* y[i] := y[i] + alpha * t */ - y[i] += a * t; - } - return; -} - -/*********************************************************************** -* The routine st_prod computes the product y := y + alpha * S' * x, -* where S' is a matrix transposed to S, x is a n-vector, alpha is a -* scalar, y is m0-vector. -* -* Since matrix R is available by rows, the product is computed as a -* linear combination: -* -* y := y + alpha * (S'[1] * x[1] + ... + S'[n] * x[n]), -* -* where S'[i] is i-th row of S. */ - -static void st_prod(LPF *lpf, double y[], double a, const double x[]) -{ int n = lpf->n; - int *S_ptr = lpf->S_ptr; - int *S_len = lpf->S_len; - int *v_ind = lpf->v_ind; - double *v_val = lpf->v_val; - int i, beg, end, ptr; - double t; - for (i = 1; i <= n; i++) - { if (x[i] == 0.0) continue; - /* y := y + alpha * S'[i] * x[i] */ - t = a * x[i]; - beg = S_ptr[i]; - end = beg + S_len[i]; - for (ptr = beg; ptr < end; ptr++) - y[v_ind[ptr]] += t * v_val[ptr]; - } - return; -} - -#if GLPLPF_DEBUG -/*********************************************************************** -* The routine check_error computes the maximal relative error between -* left- and right-hand sides for the system B * x = b (if tr is zero) -* or B' * x = b (if tr is non-zero), where B' is a matrix transposed -* to B. (This routine is intended for debugging only.) */ - -static void check_error(LPF *lpf, int tr, const double x[], - const double b[]) -{ int m = lpf->m; - double *B = lpf->B; - int i, j; - double d, dmax = 0.0, s, t, tmax; - for (i = 1; i <= m; i++) - { s = 0.0; - tmax = 1.0; - for (j = 1; j <= m; j++) - { if (!tr) - t = B[m * (i - 1) + j] * x[j]; - else - t = B[m * (j - 1) + i] * x[j]; - if (tmax < fabs(t)) tmax = fabs(t); - s += t; - } - d = fabs(s - b[i]) / tmax; - if (dmax < d) dmax = d; - } - if (dmax > 1e-8) - xprintf("%s: dmax = %g; relative error too large\n", - !tr ? "lpf_ftran" : "lpf_btran", dmax); - return; -} -#endif - -/*********************************************************************** -* NAME -* -* lpf_ftran - perform forward transformation (solve system B*x = b) -* -* SYNOPSIS -* -* #include "glplpf.h" -* void lpf_ftran(LPF *lpf, double x[]); -* -* DESCRIPTION -* -* The routine lpf_ftran performs forward transformation, i.e. solves -* the system B*x = b, where B is the basis matrix, x is the vector of -* unknowns to be computed, b is the vector of right-hand sides. -* -* On entry elements of the vector b should be stored in dense format -* in locations x[1], ..., x[m], where m is the number of rows. On exit -* the routine stores elements of the vector x in the same locations. -* -* BACKGROUND -* -* Solution of the system B * x = b can be obtained by solving the -* following augmented system: -* -* ( B F^) ( x ) ( b ) -* ( ) ( ) = ( ) -* ( G^ H^) ( y ) ( 0 ) -* -* which, using the main equality, can be written as follows: -* -* ( L0 0 ) ( U0 R ) ( x ) ( b ) -* P ( ) ( ) Q ( ) = ( ) -* ( S I ) ( 0 C ) ( y ) ( 0 ) -* -* therefore, -* -* ( x ) ( U0 R )-1 ( L0 0 )-1 ( b ) -* ( ) = Q' ( ) ( ) P' ( ) -* ( y ) ( 0 C ) ( S I ) ( 0 ) -* -* Thus, computing the solution includes the following steps: -* -* 1. Compute -* -* ( f ) ( b ) -* ( ) = P' ( ) -* ( g ) ( 0 ) -* -* 2. Solve the system -* -* ( f1 ) ( L0 0 )-1 ( f ) ( L0 0 ) ( f1 ) ( f ) -* ( ) = ( ) ( ) => ( ) ( ) = ( ) -* ( g1 ) ( S I ) ( g ) ( S I ) ( g1 ) ( g ) -* -* from which it follows that: -* -* { L0 * f1 = f f1 = inv(L0) * f -* { => -* { S * f1 + g1 = g g1 = g - S * f1 -* -* 3. Solve the system -* -* ( f2 ) ( U0 R )-1 ( f1 ) ( U0 R ) ( f2 ) ( f1 ) -* ( ) = ( ) ( ) => ( ) ( ) = ( ) -* ( g2 ) ( 0 C ) ( g1 ) ( 0 C ) ( g2 ) ( g1 ) -* -* from which it follows that: -* -* { U0 * f2 + R * g2 = f1 f2 = inv(U0) * (f1 - R * g2) -* { => -* { C * g2 = g1 g2 = inv(C) * g1 -* -* 4. Compute -* -* ( x ) ( f2 ) -* ( ) = Q' ( ) -* ( y ) ( g2 ) */ - -void lpf_ftran(LPF *lpf, double x[]) -{ int m0 = lpf->m0; - int m = lpf->m; - int n = lpf->n; - int *P_col = lpf->P_col; - int *Q_col = lpf->Q_col; - double *fg = lpf->work1; - double *f = fg; - double *g = fg + m0; - int i, ii; -#if GLPLPF_DEBUG - double *b; -#endif - if (!lpf->valid) - xfault("lpf_ftran: the factorization is not valid\n"); - xassert(0 <= m && m <= m0 + n); -#if GLPLPF_DEBUG - /* save the right-hand side vector */ - b = xcalloc(1+m, sizeof(double)); - for (i = 1; i <= m; i++) b[i] = x[i]; -#endif - /* (f g) := inv(P) * (b 0) */ - for (i = 1; i <= m0 + n; i++) - fg[i] = ((ii = P_col[i]) <= m ? x[ii] : 0.0); - /* f1 := inv(L0) * f */ -#if 0 /* 06/VI-2013 */ - luf_f_solve(lpf->luf, 0, f); -#else - luf_f_solve(lpf->lufint->luf, f); -#endif - /* g1 := g - S * f1 */ - s_prod(lpf, g, -1.0, f); - /* g2 := inv(C) * g1 */ -#if 0 /* 11/VIII-2013 */ - scf_solve_it(lpf->scf, 0, g); -#else - ifu_a_solve(&lpf->ifu, g, lpf->work2); -#endif - /* f2 := inv(U0) * (f1 - R * g2) */ - r_prod(lpf, f, -1.0, g); -#if 0 /* 06/VI-2013 */ - luf_v_solve(lpf->luf, 0, f); -#else - { double *work = lpf->lufint->sgf->work; - luf_v_solve(lpf->lufint->luf, f, work); - memcpy(&f[1], &work[1], m0 * sizeof(double)); - } -#endif - /* (x y) := inv(Q) * (f2 g2) */ - for (i = 1; i <= m; i++) - x[i] = fg[Q_col[i]]; -#if GLPLPF_DEBUG - /* check relative error in solution */ - check_error(lpf, 0, x, b); - xfree(b); -#endif - return; -} - -/*********************************************************************** -* NAME -* -* lpf_btran - perform backward transformation (solve system B'*x = b) -* -* SYNOPSIS -* -* #include "glplpf.h" -* void lpf_btran(LPF *lpf, double x[]); -* -* DESCRIPTION -* -* The routine lpf_btran performs backward transformation, i.e. solves -* the system B'*x = b, where B' is a matrix transposed to the basis -* matrix B, x is the vector of unknowns to be computed, b is the vector -* of right-hand sides. -* -* On entry elements of the vector b should be stored in dense format -* in locations x[1], ..., x[m], where m is the number of rows. On exit -* the routine stores elements of the vector x in the same locations. -* -* BACKGROUND -* -* Solution of the system B' * x = b, where B' is a matrix transposed -* to B, can be obtained by solving the following augmented system: -* -* ( B F^)T ( x ) ( b ) -* ( ) ( ) = ( ) -* ( G^ H^) ( y ) ( 0 ) -* -* which, using the main equality, can be written as follows: -* -* T ( U0 R )T ( L0 0 )T T ( x ) ( b ) -* Q ( ) ( ) P ( ) = ( ) -* ( 0 C ) ( S I ) ( y ) ( 0 ) -* -* or, equivalently, as follows: -* -* ( U'0 0 ) ( L'0 S') ( x ) ( b ) -* Q' ( ) ( ) P' ( ) = ( ) -* ( R' C') ( 0 I ) ( y ) ( 0 ) -* -* therefore, -* -* ( x ) ( L'0 S')-1 ( U'0 0 )-1 ( b ) -* ( ) = P ( ) ( ) Q ( ) -* ( y ) ( 0 I ) ( R' C') ( 0 ) -* -* Thus, computing the solution includes the following steps: -* -* 1. Compute -* -* ( f ) ( b ) -* ( ) = Q ( ) -* ( g ) ( 0 ) -* -* 2. Solve the system -* -* ( f1 ) ( U'0 0 )-1 ( f ) ( U'0 0 ) ( f1 ) ( f ) -* ( ) = ( ) ( ) => ( ) ( ) = ( ) -* ( g1 ) ( R' C') ( g ) ( R' C') ( g1 ) ( g ) -* -* from which it follows that: -* -* { U'0 * f1 = f f1 = inv(U'0) * f -* { => -* { R' * f1 + C' * g1 = g g1 = inv(C') * (g - R' * f1) -* -* 3. Solve the system -* -* ( f2 ) ( L'0 S')-1 ( f1 ) ( L'0 S') ( f2 ) ( f1 ) -* ( ) = ( ) ( ) => ( ) ( ) = ( ) -* ( g2 ) ( 0 I ) ( g1 ) ( 0 I ) ( g2 ) ( g1 ) -* -* from which it follows that: -* -* { L'0 * f2 + S' * g2 = f1 -* { => f2 = inv(L'0) * ( f1 - S' * g2) -* { g2 = g1 -* -* 4. Compute -* -* ( x ) ( f2 ) -* ( ) = P ( ) -* ( y ) ( g2 ) */ - -void lpf_btran(LPF *lpf, double x[]) -{ int m0 = lpf->m0; - int m = lpf->m; - int n = lpf->n; - int *P_row = lpf->P_row; - int *Q_row = lpf->Q_row; - double *fg = lpf->work1; - double *f = fg; - double *g = fg + m0; - int i, ii; -#if GLPLPF_DEBUG - double *b; -#endif - if (!lpf->valid) - xfault("lpf_btran: the factorization is not valid\n"); - xassert(0 <= m && m <= m0 + n); -#if GLPLPF_DEBUG - /* save the right-hand side vector */ - b = xcalloc(1+m, sizeof(double)); - for (i = 1; i <= m; i++) b[i] = x[i]; -#endif - /* (f g) := Q * (b 0) */ - for (i = 1; i <= m0 + n; i++) - fg[i] = ((ii = Q_row[i]) <= m ? x[ii] : 0.0); - /* f1 := inv(U'0) * f */ -#if 0 /* 06/VI-2013 */ - luf_v_solve(lpf->luf, 1, f); -#else - { double *work = lpf->lufint->sgf->work; - luf_vt_solve(lpf->lufint->luf, f, work); - memcpy(&f[1], &work[1], m0 * sizeof(double)); - } -#endif - /* g1 := inv(C') * (g - R' * f1) */ - rt_prod(lpf, g, -1.0, f); -#if 0 /* 11/VIII-2013 */ - scf_solve_it(lpf->scf, 1, g); -#else - ifu_at_solve(&lpf->ifu, g, lpf->work2); -#endif - /* g2 := g1 */ - g = g; - /* f2 := inv(L'0) * (f1 - S' * g2) */ - st_prod(lpf, f, -1.0, g); -#if 0 /* 06/VI-2013 */ - luf_f_solve(lpf->luf, 1, f); -#else - luf_ft_solve(lpf->lufint->luf, f); -#endif - /* (x y) := P * (f2 g2) */ - for (i = 1; i <= m; i++) - x[i] = fg[P_row[i]]; -#if GLPLPF_DEBUG - /* check relative error in solution */ - check_error(lpf, 1, x, b); - xfree(b); -#endif - return; -} - -/*********************************************************************** -* The routine enlarge_sva enlarges the Sparse Vector Area to new_size -* locations by reallocating the arrays v_ind and v_val. */ - -static void enlarge_sva(LPF *lpf, int new_size) -{ int v_size = lpf->v_size; - int used = lpf->v_ptr - 1; - int *v_ind = lpf->v_ind; - double *v_val = lpf->v_val; - xassert(v_size < new_size); - while (v_size < new_size) v_size += v_size; - lpf->v_size = v_size; - lpf->v_ind = xcalloc(1+v_size, sizeof(int)); - lpf->v_val = xcalloc(1+v_size, sizeof(double)); - xassert(used >= 0); - memcpy(&lpf->v_ind[1], &v_ind[1], used * sizeof(int)); - memcpy(&lpf->v_val[1], &v_val[1], used * sizeof(double)); - xfree(v_ind); - xfree(v_val); - return; -} - -/*********************************************************************** -* NAME -* -* lpf_update_it - update LP basis factorization -* -* SYNOPSIS -* -* #include "glplpf.h" -* int lpf_update_it(LPF *lpf, int j, int bh, int len, const int ind[], -* const double val[]); -* -* DESCRIPTION -* -* The routine lpf_update_it updates the factorization of the basis -* matrix B after replacing its j-th column by a new vector. -* -* The parameter j specifies the number of column of B, which has been -* replaced, 1 <= j <= m, where m is the order of B. -* -* The parameter bh specifies the basis header entry for the new column -* of B, which is the number of the new column in some original matrix. -* This parameter is optional and can be specified as 0. -* -* Row indices and numerical values of non-zero elements of the new -* column of B should be placed in locations ind[1], ..., ind[len] and -* val[1], ..., val[len], resp., where len is the number of non-zeros -* in the column. Neither zero nor duplicate elements are allowed. -* -* RETURNS -* -* 0 The factorization has been successfully updated. -* -* LPF_ESING -* New basis B is singular within the working precision. -* -* LPF_ELIMIT -* Maximal number of additional rows and columns has been reached. -* -* BACKGROUND -* -* Let j-th column of the current basis matrix B have to be replaced by -* a new column a. This replacement is equivalent to removing the old -* j-th column by fixing it at zero and introducing the new column as -* follows: -* -* ( B F^| a ) -* ( B F^) ( | ) -* ( ) ---> ( G^ H^| 0 ) -* ( G^ H^) (-------+---) -* ( e'j 0 | 0 ) -* -* where ej is a unit vector with 1 in j-th position which used to fix -* the old j-th column of B (at zero). Then using the main equality we -* have: -* -* ( B F^| a ) ( B0 F | f ) -* ( | ) ( P 0 ) ( | ) ( Q 0 ) -* ( G^ H^| 0 ) = ( ) ( G H | g ) ( ) = -* (-------+---) ( 0 1 ) (-------+---) ( 0 1 ) -* ( e'j 0 | 0 ) ( v' w'| 0 ) -* -* [ ( B0 F )| ( f ) ] [ ( B0 F ) | ( f ) ] -* [ P ( )| P ( ) ] ( Q 0 ) [ P ( ) Q| P ( ) ] -* = [ ( G H )| ( g ) ] ( ) = [ ( G H ) | ( g ) ] -* [------------+-------- ] ( 0 1 ) [-------------+---------] -* [ ( v' w')| 0 ] [ ( v' w') Q| 0 ] -* -* where: -* -* ( a ) ( f ) ( f ) ( a ) -* ( ) = P ( ) => ( ) = P' * ( ) -* ( 0 ) ( g ) ( g ) ( 0 ) -* -* ( ej ) ( v ) ( v ) ( ej ) -* ( e'j 0 ) = ( v' w' ) Q => ( ) = Q' ( ) => ( ) = Q ( ) -* ( 0 ) ( w ) ( w ) ( 0 ) -* -* On the other hand: -* -* ( B0| F f ) -* ( P 0 ) (---+------) ( Q 0 ) ( B0 new F ) -* ( ) ( G | H g ) ( ) = new P ( ) new Q -* ( 0 1 ) ( | ) ( 0 1 ) ( new G new H ) -* ( v'| w' 0 ) -* -* where: -* ( G ) ( H g ) -* new F = ( F f ), new G = ( ), new H = ( ), -* ( v') ( w' 0 ) -* -* ( P 0 ) ( Q 0 ) -* new P = ( ) , new Q = ( ) . -* ( 0 1 ) ( 0 1 ) -* -* The factorization structure for the new augmented matrix remains the -* same, therefore: -* -* ( B0 new F ) ( L0 0 ) ( U0 new R ) -* new P ( ) new Q = ( ) ( ) -* ( new G new H ) ( new S I ) ( 0 new C ) -* -* where: -* -* new F = L0 * new R => -* -* new R = inv(L0) * new F = inv(L0) * (F f) = ( R inv(L0)*f ) -* -* new G = new S * U0 => -* -* ( G ) ( S ) -* new S = new G * inv(U0) = ( ) * inv(U0) = ( ) -* ( v') ( v'*inv(U0) ) -* -* new H = new S * new R + new C => -* -* new C = new H - new S * new R = -* -* ( H g ) ( S ) -* = ( ) - ( ) * ( R inv(L0)*f ) = -* ( w' 0 ) ( v'*inv(U0) ) -* -* ( H - S*R g - S*inv(L0)*f ) ( C x ) -* = ( ) = ( ) -* ( w'- v'*inv(U0)*R -v'*inv(U0)*inv(L0)*f) ( y' z ) -* -* Note that new C is resulted by expanding old C with new column x, -* row y', and diagonal element z, where: -* -* x = g - S * inv(L0) * f = g - S * (new column of R) -* -* y = w - R'* inv(U'0)* v = w - R'* (new row of S) -* -* z = - (new row of S) * (new column of R) -* -* Finally, to replace old B by new B we have to permute j-th and last -* (just added) columns of the matrix -* -* ( B F^| a ) -* ( | ) -* ( G^ H^| 0 ) -* (-------+---) -* ( e'j 0 | 0 ) -* -* and to keep the main equality do the same for matrix Q. */ - -int lpf_update_it(LPF *lpf, int j, int bh, int len, const int ind[], - const double val[]) -{ int m0 = lpf->m0; - int m = lpf->m; -#if GLPLPF_DEBUG - double *B = lpf->B; -#endif - int n = lpf->n; - int *R_ptr = lpf->R_ptr; - int *R_len = lpf->R_len; - int *S_ptr = lpf->S_ptr; - int *S_len = lpf->S_len; - int *P_row = lpf->P_row; - int *P_col = lpf->P_col; - int *Q_row = lpf->Q_row; - int *Q_col = lpf->Q_col; - int v_ptr = lpf->v_ptr; - int *v_ind = lpf->v_ind; - double *v_val = lpf->v_val; - double *a = lpf->work2; /* new column */ - double *fg = lpf->work1, *f = fg, *g = fg + m0; - double *vw = lpf->work2, *v = vw, *w = vw + m0; - double *x = g, *y = w, z; - int i, ii, k, ret; - xassert(bh == bh); - if (!lpf->valid) - xfault("lpf_update_it: the factorization is not valid\n"); - if (!(1 <= j && j <= m)) - xfault("lpf_update_it: j = %d; column number out of range\n", - j); - xassert(0 <= m && m <= m0 + n); - /* check if the basis factorization can be expanded */ - if (n == lpf->n_max) - { lpf->valid = 0; - ret = LPF_ELIMIT; - goto done; - } - /* convert new j-th column of B to dense format */ - for (i = 1; i <= m; i++) - a[i] = 0.0; - for (k = 1; k <= len; k++) - { i = ind[k]; - if (!(1 <= i && i <= m)) - xfault("lpf_update_it: ind[%d] = %d; row number out of rang" - "e\n", k, i); - if (a[i] != 0.0) - xfault("lpf_update_it: ind[%d] = %d; duplicate row index no" - "t allowed\n", k, i); - if (val[k] == 0.0) - xfault("lpf_update_it: val[%d] = %g; zero element not allow" - "ed\n", k, val[k]); - a[i] = val[k]; - } -#if GLPLPF_DEBUG - /* change column in the basis matrix for debugging */ - for (i = 1; i <= m; i++) - B[(i - 1) * m + j] = a[i]; -#endif - /* (f g) := inv(P) * (a 0) */ - for (i = 1; i <= m0+n; i++) - fg[i] = ((ii = P_col[i]) <= m ? a[ii] : 0.0); - /* (v w) := Q * (ej 0) */ - for (i = 1; i <= m0+n; i++) vw[i] = 0.0; - vw[Q_col[j]] = 1.0; - /* f1 := inv(L0) * f (new column of R) */ -#if 0 /* 06/VI-2013 */ - luf_f_solve(lpf->luf, 0, f); -#else - luf_f_solve(lpf->lufint->luf, f); -#endif - /* v1 := inv(U'0) * v (new row of S) */ -#if 0 /* 06/VI-2013 */ - luf_v_solve(lpf->luf, 1, v); -#else - { double *work = lpf->lufint->sgf->work; - luf_vt_solve(lpf->lufint->luf, v, work); - memcpy(&v[1], &work[1], m0 * sizeof(double)); - } -#endif - /* we need at most 2 * m0 available locations in the SVA to store - new column of matrix R and new row of matrix S */ - if (lpf->v_size < v_ptr + m0 + m0) - { enlarge_sva(lpf, v_ptr + m0 + m0); - v_ind = lpf->v_ind; - v_val = lpf->v_val; - } - /* store new column of R */ - R_ptr[n+1] = v_ptr; - for (i = 1; i <= m0; i++) - { if (f[i] != 0.0) - v_ind[v_ptr] = i, v_val[v_ptr] = f[i], v_ptr++; - } - R_len[n+1] = v_ptr - lpf->v_ptr; - lpf->v_ptr = v_ptr; - /* store new row of S */ - S_ptr[n+1] = v_ptr; - for (i = 1; i <= m0; i++) - { if (v[i] != 0.0) - v_ind[v_ptr] = i, v_val[v_ptr] = v[i], v_ptr++; - } - S_len[n+1] = v_ptr - lpf->v_ptr; - lpf->v_ptr = v_ptr; - /* x := g - S * f1 (new column of C) */ - s_prod(lpf, x, -1.0, f); - /* y := w - R' * v1 (new row of C) */ - rt_prod(lpf, y, -1.0, v); - /* z := - v1 * f1 (new diagonal element of C) */ - z = 0.0; - for (i = 1; i <= m0; i++) z -= v[i] * f[i]; - /* update factorization of new matrix C */ -#if 0 /* 11/VIII-2013 */ - switch (scf_update_exp(lpf->scf, x, y, z)) - { case 0: - break; - case SCF_ESING: - lpf->valid = 0; - ret = LPF_ESING; - goto done; - case SCF_ELIMIT: - xassert(lpf != lpf); - default: - xassert(lpf != lpf); - } -#else - if (lpf->t_opt == SCF_TBG) - { if (ifu_bg_update(&lpf->ifu, x, y, z) != 0) -#if 0 - { xprintf("Warning: insufficient accuracy (Bartels-Golub upda" - "te)\n"); -#else - { -#endif - lpf->valid = 0; - ret = LPF_ESING; - goto done; - } - } - else if (lpf->t_opt == SCF_TGR) - { if (ifu_gr_update(&lpf->ifu, x, y, z) != 0) -#if 0 - { xprintf("Warning: insufficient accuracy (Givens rotations u" - "pdate)\n"); -#else - { -#endif - lpf->valid = 0; - ret = LPF_ESING; - goto done; - } - } - else - xassert(lpf != lpf); -#endif - /* expand matrix P */ - P_row[m0+n+1] = P_col[m0+n+1] = m0+n+1; - /* expand matrix Q */ - Q_row[m0+n+1] = Q_col[m0+n+1] = m0+n+1; - /* permute j-th and last (just added) column of matrix Q */ - i = Q_col[j], ii = Q_col[m0+n+1]; - Q_row[i] = m0+n+1, Q_col[m0+n+1] = i; - Q_row[ii] = j, Q_col[j] = ii; - /* increase the number of additional rows and columns */ - lpf->n++; - xassert(lpf->n <= lpf->n_max); - /* the factorization has been successfully updated */ - ret = 0; -done: /* return to the calling program */ - return ret; -} - -/*********************************************************************** -* NAME -* -* lpf_delete_it - delete LP basis factorization -* -* SYNOPSIS -* -* #include "glplpf.h" -* void lpf_delete_it(LPF *lpf) -* -* DESCRIPTION -* -* The routine lpf_delete_it deletes LP basis factorization specified -* by the parameter lpf and frees all memory allocated to this program -* object. */ - -void lpf_delete_it(LPF *lpf) -#if 0 /* 06/VI-2013 */ -{ luf_delete_it(lpf->luf); -#else -{ lufint_delete(lpf->lufint); -#endif -#if GLPLPF_DEBUG - if (lpf->B != NULL) xfree(lpf->B); -#else - xassert(lpf->B == NULL); -#endif - if (lpf->R_ptr != NULL) xfree(lpf->R_ptr); - if (lpf->R_len != NULL) xfree(lpf->R_len); - if (lpf->S_ptr != NULL) xfree(lpf->S_ptr); - if (lpf->S_len != NULL) xfree(lpf->S_len); -#if 0 /* 11/VIII-2013 */ - if (lpf->scf != NULL) scf_delete_it(lpf->scf); -#else - if (lpf->ifu.f != NULL) tfree(lpf->ifu.f); - if (lpf->ifu.u != NULL) tfree(lpf->ifu.u); -#endif - if (lpf->P_row != NULL) xfree(lpf->P_row); - if (lpf->P_col != NULL) xfree(lpf->P_col); - if (lpf->Q_row != NULL) xfree(lpf->Q_row); - if (lpf->Q_col != NULL) xfree(lpf->Q_col); - if (lpf->v_ind != NULL) xfree(lpf->v_ind); - if (lpf->v_val != NULL) xfree(lpf->v_val); - if (lpf->work1 != NULL) xfree(lpf->work1); - if (lpf->work2 != NULL) xfree(lpf->work2); - xfree(lpf); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glplpf.h b/resources/3rdparty/glpk-4.53/src/glplpf.h deleted file mode 100644 index e06e6c595..000000000 --- a/resources/3rdparty/glpk-4.53/src/glplpf.h +++ /dev/null @@ -1,216 +0,0 @@ -/* glplpf.h (LP basis factorization, Schur complement version) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPLPF_H -#define GLPLPF_H - -#if 0 /* 11/VIII-2013 */ -#include "glpscf.h" -#else -#include "ifu.h" -#endif -#if 0 /* 06/VI-2013 */ -#include "glpluf.h" -#else -#include "lufint.h" -#endif - -/*********************************************************************** -* The structure LPF defines the factorization of the basis mxm matrix -* B, where m is the number of rows in corresponding problem instance. -* -* This factorization is the following septet: -* -* [B] = (L0, U0, R, S, C, P, Q), (1) -* -* and is based on the following main equality: -* -* ( B F^) ( B0 F ) ( L0 0 ) ( U0 R ) -* ( ) = P ( ) Q = P ( ) ( ) Q, (2) -* ( G^ H^) ( G H ) ( S I ) ( 0 C ) -* -* where: -* -* B is the current basis matrix (not stored); -* -* F^, G^, H^ are some additional matrices (not stored); -* -* B0 is some initial basis matrix (not stored); -* -* F, G, H are some additional matrices (not stored); -* -* P, Q are permutation matrices (stored in both row- and column-like -* formats); -* -* L0, U0 are some matrices that defines a factorization of the initial -* basis matrix B0 = L0 * U0 (stored in an invertable form); -* -* R is a matrix defined from L0 * R = F, so R = inv(L0) * F (stored in -* a column-wise sparse format); -* -* S is a matrix defined from S * U0 = G, so S = G * inv(U0) (stored in -* a row-wise sparse format); -* -* C is the Schur complement for matrix (B0 F G H). It is defined from -* S * R + C = H, so C = H - S * R = H - G * inv(U0) * inv(L0) * F = -* = H - G * inv(B0) * F. Matrix C is stored in an invertable form. -* -* REFERENCES -* -* 1. M.A.Saunders, "LUSOL: A basis package for constrained optimiza- -* tion," SCCM, Stanford University, 2006. -* -* 2. M.A.Saunders, "Notes 5: Basis Updates," CME 318, Stanford Univer- -* sity, Spring 2006. -* -* 3. M.A.Saunders, "Notes 6: LUSOL---a Basis Factorization Package," -* ibid. */ - -typedef struct LPF LPF; - -struct LPF -{ /* LP basis factorization */ - int valid; - /* the factorization is valid only if this flag is set */ - /*--------------------------------------------------------------*/ - /* initial basis matrix B0 */ - int m0_max; - /* maximal value of m0 (increased automatically, if necessary) */ - int m0; - /* the order of B0 */ -#if 0 /* 06/VI-2013 */ - LUF *luf; -#else - LUFINT *lufint; -#endif - /* LU-factorization of B0 */ - /*--------------------------------------------------------------*/ - /* current basis matrix B */ - int m; - /* the order of B */ - double *B; /* double B[1+m*m]; */ - /* B in dense format stored by rows and used only for debugging; - normally this array is not allocated */ - /*--------------------------------------------------------------*/ - /* augmented matrix (B0 F G H) of the order m0+n */ - int n_max; - /* maximal number of additional rows and columns */ - int n; - /* current number of additional rows and columns */ - /*--------------------------------------------------------------*/ - /* m0xn matrix R in column-wise format */ - int *R_ptr; /* int R_ptr[1+n_max]; */ - /* R_ptr[j], 1 <= j <= n, is a pointer to j-th column */ - int *R_len; /* int R_len[1+n_max]; */ - /* R_len[j], 1 <= j <= n, is the length of j-th column */ - /*--------------------------------------------------------------*/ - /* nxm0 matrix S in row-wise format */ - int *S_ptr; /* int S_ptr[1+n_max]; */ - /* S_ptr[i], 1 <= i <= n, is a pointer to i-th row */ - int *S_len; /* int S_len[1+n_max]; */ - /* S_len[i], 1 <= i <= n, is the length of i-th row */ - /*--------------------------------------------------------------*/ - /* Schur complement C of the order n */ -#if 0 /* 11/VIII-2013 */ - SCF *scf; /* SCF scf[1:n_max]; */ - /* factorization of the Schur complement */ -#else - IFU ifu; - /* IFU-factorization of the Schur complement */ - int t_opt; - /* type of transformation used to restore triangular structure of - matrix U: */ -#define SCF_TBG 1 /* Bartels-Golub elimination */ -#define SCF_TGR 2 /* Givens plane rotations */ -#endif - /*--------------------------------------------------------------*/ - /* matrix P of the order m0+n */ - int *P_row; /* int P_row[1+m0_max+n_max]; */ - /* P_row[i] = j means that P[i,j] = 1 */ - int *P_col; /* int P_col[1+m0_max+n_max]; */ - /* P_col[j] = i means that P[i,j] = 1 */ - /*--------------------------------------------------------------*/ - /* matrix Q of the order m0+n */ - int *Q_row; /* int Q_row[1+m0_max+n_max]; */ - /* Q_row[i] = j means that Q[i,j] = 1 */ - int *Q_col; /* int Q_col[1+m0_max+n_max]; */ - /* Q_col[j] = i means that Q[i,j] = 1 */ - /*--------------------------------------------------------------*/ - /* Sparse Vector Area (SVA) is a set of locations intended to - store sparse vectors which represent columns of matrix R and - rows of matrix S; each location is a doublet (ind, val), where - ind is an index, val is a numerical value of a sparse vector - element; in the whole each sparse vector is a set of adjacent - locations defined by a pointer to its first element and its - length, i.e. the number of its elements */ - int v_size; - /* the SVA size, in locations; locations are numbered by integers - 1, 2, ..., v_size, and location 0 is not used */ - int v_ptr; - /* pointer to the first available location */ - int *v_ind; /* int v_ind[1+v_size]; */ - /* v_ind[k], 1 <= k <= v_size, is the index field of location k */ - double *v_val; /* double v_val[1+v_size]; */ - /* v_val[k], 1 <= k <= v_size, is the value field of location k */ - /*--------------------------------------------------------------*/ - double *work1; /* double work1[1+m0+n_max]; */ - /* working array */ - double *work2; /* double work2[1+m0+n_max]; */ - /* working array */ -}; - -/* return codes: */ -#define LPF_ESING 1 /* singular matrix */ -#define LPF_ECOND 2 /* ill-conditioned matrix */ -#define LPF_ELIMIT 3 /* update limit reached */ - -#define lpf_create_it _glp_lpf_create_it -LPF *lpf_create_it(void); -/* create LP basis factorization */ - -#define lpf_factorize _glp_lpf_factorize -int lpf_factorize(LPF *lpf, int m, const int bh[], int (*col) - (void *info, int j, int ind[], double val[]), void *info); -/* compute LP basis factorization */ - -#define lpf_ftran _glp_lpf_ftran -void lpf_ftran(LPF *lpf, double x[]); -/* perform forward transformation (solve system B*x = b) */ - -#define lpf_btran _glp_lpf_btran -void lpf_btran(LPF *lpf, double x[]); -/* perform backward transformation (solve system B'*x = b) */ - -#define lpf_update_it _glp_lpf_update_it -int lpf_update_it(LPF *lpf, int j, int bh, int len, const int ind[], - const double val[]); -/* update LP basis factorization */ - -#define lpf_delete_it _glp_lpf_delete_it -void lpf_delete_it(LPF *lpf); -/* delete LP basis factorization */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpmat.c b/resources/3rdparty/glpk-4.53/src/glpmat.c deleted file mode 100644 index 97d1c6515..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpmat.c +++ /dev/null @@ -1,924 +0,0 @@ -/* glpmat.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpmat.h" -#include "qmd.h" -#include "amd.h" -#include "colamd.h" - -/*---------------------------------------------------------------------- --- check_fvs - check sparse vector in full-vector storage format. --- --- SYNOPSIS --- --- #include "glpmat.h" --- int check_fvs(int n, int nnz, int ind[], double vec[]); --- --- DESCRIPTION --- --- The routine check_fvs checks if a given vector of dimension n in --- full-vector storage format has correct representation. --- --- RETURNS --- --- The routine returns one of the following codes: --- --- 0 - the vector is correct; --- 1 - the number of elements (n) is negative; --- 2 - the number of non-zero elements (nnz) is negative; --- 3 - some element index is out of range; --- 4 - some element index is duplicate; --- 5 - some non-zero element is out of pattern. */ - -int check_fvs(int n, int nnz, int ind[], double vec[]) -{ int i, t, ret, *flag = NULL; - /* check the number of elements */ - if (n < 0) - { ret = 1; - goto done; - } - /* check the number of non-zero elements */ - if (nnz < 0) - { ret = 2; - goto done; - } - /* check vector indices */ - flag = xcalloc(1+n, sizeof(int)); - for (i = 1; i <= n; i++) flag[i] = 0; - for (t = 1; t <= nnz; t++) - { i = ind[t]; - if (!(1 <= i && i <= n)) - { ret = 3; - goto done; - } - if (flag[i]) - { ret = 4; - goto done; - } - flag[i] = 1; - } - /* check vector elements */ - for (i = 1; i <= n; i++) - { if (!flag[i] && vec[i] != 0.0) - { ret = 5; - goto done; - } - } - /* the vector is ok */ - ret = 0; -done: if (flag != NULL) xfree(flag); - return ret; -} - -/*---------------------------------------------------------------------- --- check_pattern - check pattern of sparse matrix. --- --- SYNOPSIS --- --- #include "glpmat.h" --- int check_pattern(int m, int n, int A_ptr[], int A_ind[]); --- --- DESCRIPTION --- --- The routine check_pattern checks the pattern of a given mxn matrix --- in storage-by-rows format. --- --- RETURNS --- --- The routine returns one of the following codes: --- --- 0 - the pattern is correct; --- 1 - the number of rows (m) is negative; --- 2 - the number of columns (n) is negative; --- 3 - A_ptr[1] is not 1; --- 4 - some column index is out of range; --- 5 - some column indices are duplicate. */ - -int check_pattern(int m, int n, int A_ptr[], int A_ind[]) -{ int i, j, ptr, ret, *flag = NULL; - /* check the number of rows */ - if (m < 0) - { ret = 1; - goto done; - } - /* check the number of columns */ - if (n < 0) - { ret = 2; - goto done; - } - /* check location A_ptr[1] */ - if (A_ptr[1] != 1) - { ret = 3; - goto done; - } - /* check row patterns */ - flag = xcalloc(1+n, sizeof(int)); - for (j = 1; j <= n; j++) flag[j] = 0; - for (i = 1; i <= m; i++) - { /* check pattern of row i */ - for (ptr = A_ptr[i]; ptr < A_ptr[i+1]; ptr++) - { j = A_ind[ptr]; - /* check column index */ - if (!(1 <= j && j <= n)) - { ret = 4; - goto done; - } - /* check for duplication */ - if (flag[j]) - { ret = 5; - goto done; - } - flag[j] = 1; - } - /* clear flags */ - for (ptr = A_ptr[i]; ptr < A_ptr[i+1]; ptr++) - { j = A_ind[ptr]; - flag[j] = 0; - } - } - /* the pattern is ok */ - ret = 0; -done: if (flag != NULL) xfree(flag); - return ret; -} - -/*---------------------------------------------------------------------- --- transpose - transpose sparse matrix. --- --- *Synopsis* --- --- #include "glpmat.h" --- void transpose(int m, int n, int A_ptr[], int A_ind[], --- double A_val[], int AT_ptr[], int AT_ind[], double AT_val[]); --- --- *Description* --- --- For a given mxn sparse matrix A the routine transpose builds a nxm --- sparse matrix A' which is a matrix transposed to A. --- --- The arrays A_ptr, A_ind, and A_val specify a given mxn matrix A to --- be transposed in storage-by-rows format. The parameter A_val can be --- NULL, in which case numeric values are not copied. The arrays A_ptr, --- A_ind, and A_val are not changed on exit. --- --- On entry the arrays AT_ptr, AT_ind, and AT_val must be allocated, --- but their content is ignored. On exit the routine stores a resultant --- nxm matrix A' in these arrays in storage-by-rows format. Note that --- if the parameter A_val is NULL, the array AT_val is not used. --- --- The routine transpose has a side effect that elements in rows of the --- resultant matrix A' follow in ascending their column indices. */ - -void transpose(int m, int n, int A_ptr[], int A_ind[], double A_val[], - int AT_ptr[], int AT_ind[], double AT_val[]) -{ int i, j, t, beg, end, pos, len; - /* determine row lengths of resultant matrix */ - for (j = 1; j <= n; j++) AT_ptr[j] = 0; - for (i = 1; i <= m; i++) - { beg = A_ptr[i], end = A_ptr[i+1]; - for (t = beg; t < end; t++) AT_ptr[A_ind[t]]++; - } - /* set up row pointers of resultant matrix */ - pos = 1; - for (j = 1; j <= n; j++) - len = AT_ptr[j], pos += len, AT_ptr[j] = pos; - AT_ptr[n+1] = pos; - /* build resultant matrix */ - for (i = m; i >= 1; i--) - { beg = A_ptr[i], end = A_ptr[i+1]; - for (t = beg; t < end; t++) - { pos = --AT_ptr[A_ind[t]]; - AT_ind[pos] = i; - if (A_val != NULL) AT_val[pos] = A_val[t]; - } - } - return; -} - -/*---------------------------------------------------------------------- --- adat_symbolic - compute S = P*A*D*A'*P' (symbolic phase). --- --- *Synopsis* --- --- #include "glpmat.h" --- int *adat_symbolic(int m, int n, int P_per[], int A_ptr[], --- int A_ind[], int S_ptr[]); --- --- *Description* --- --- The routine adat_symbolic implements the symbolic phase to compute --- symmetric matrix S = P*A*D*A'*P', where P is a permutation matrix, --- A is a given sparse matrix, D is a diagonal matrix, A' is a matrix --- transposed to A, P' is an inverse of P. --- --- The parameter m is the number of rows in A and the order of P. --- --- The parameter n is the number of columns in A and the order of D. --- --- The array P_per specifies permutation matrix P. It is not changed on --- exit. --- --- The arrays A_ptr and A_ind specify the pattern of matrix A. They are --- not changed on exit. --- --- On exit the routine stores the pattern of upper triangular part of --- matrix S without diagonal elements in the arrays S_ptr and S_ind in --- storage-by-rows format. The array S_ptr should be allocated on entry, --- however, its content is ignored. The array S_ind is allocated by the --- routine itself which returns a pointer to it. --- --- *Returns* --- --- The routine returns a pointer to the array S_ind. */ - -int *adat_symbolic(int m, int n, int P_per[], int A_ptr[], int A_ind[], - int S_ptr[]) -{ int i, j, t, ii, jj, tt, k, size, len; - int *S_ind, *AT_ptr, *AT_ind, *ind, *map, *temp; - /* build the pattern of A', which is a matrix transposed to A, to - efficiently access A in column-wise manner */ - AT_ptr = xcalloc(1+n+1, sizeof(int)); - AT_ind = xcalloc(A_ptr[m+1], sizeof(int)); - transpose(m, n, A_ptr, A_ind, NULL, AT_ptr, AT_ind, NULL); - /* allocate the array S_ind */ - size = A_ptr[m+1] - 1; - if (size < m) size = m; - S_ind = xcalloc(1+size, sizeof(int)); - /* allocate and initialize working arrays */ - ind = xcalloc(1+m, sizeof(int)); - map = xcalloc(1+m, sizeof(int)); - for (jj = 1; jj <= m; jj++) map[jj] = 0; - /* compute pattern of S; note that symbolically S = B*B', where - B = P*A, B' is matrix transposed to B */ - S_ptr[1] = 1; - for (ii = 1; ii <= m; ii++) - { /* compute pattern of ii-th row of S */ - len = 0; - i = P_per[ii]; /* i-th row of A = ii-th row of B */ - for (t = A_ptr[i]; t < A_ptr[i+1]; t++) - { k = A_ind[t]; - /* walk through k-th column of A */ - for (tt = AT_ptr[k]; tt < AT_ptr[k+1]; tt++) - { j = AT_ind[tt]; - jj = P_per[m+j]; /* j-th row of A = jj-th row of B */ - /* a[i,k] != 0 and a[j,k] != 0 ergo s[ii,jj] != 0 */ - if (ii < jj && !map[jj]) ind[++len] = jj, map[jj] = 1; - } - } - /* now (ind) is pattern of ii-th row of S */ - S_ptr[ii+1] = S_ptr[ii] + len; - /* at least (S_ptr[ii+1] - 1) locations should be available in - the array S_ind */ - if (S_ptr[ii+1] - 1 > size) - { temp = S_ind; - size += size; - S_ind = xcalloc(1+size, sizeof(int)); - memcpy(&S_ind[1], &temp[1], (S_ptr[ii] - 1) * sizeof(int)); - xfree(temp); - } - xassert(S_ptr[ii+1] - 1 <= size); - /* (ii-th row of S) := (ind) */ - memcpy(&S_ind[S_ptr[ii]], &ind[1], len * sizeof(int)); - /* clear the row pattern map */ - for (t = 1; t <= len; t++) map[ind[t]] = 0; - } - /* free working arrays */ - xfree(AT_ptr); - xfree(AT_ind); - xfree(ind); - xfree(map); - /* reallocate the array S_ind to free unused locations */ - temp = S_ind; - size = S_ptr[m+1] - 1; - S_ind = xcalloc(1+size, sizeof(int)); - memcpy(&S_ind[1], &temp[1], size * sizeof(int)); - xfree(temp); - return S_ind; -} - -/*---------------------------------------------------------------------- --- adat_numeric - compute S = P*A*D*A'*P' (numeric phase). --- --- *Synopsis* --- --- #include "glpmat.h" --- void adat_numeric(int m, int n, int P_per[], --- int A_ptr[], int A_ind[], double A_val[], double D_diag[], --- int S_ptr[], int S_ind[], double S_val[], double S_diag[]); --- --- *Description* --- --- The routine adat_numeric implements the numeric phase to compute --- symmetric matrix S = P*A*D*A'*P', where P is a permutation matrix, --- A is a given sparse matrix, D is a diagonal matrix, A' is a matrix --- transposed to A, P' is an inverse of P. --- --- The parameter m is the number of rows in A and the order of P. --- --- The parameter n is the number of columns in A and the order of D. --- --- The matrix P is specified in the array P_per, which is not changed --- on exit. --- --- The matrix A is specified in the arrays A_ptr, A_ind, and A_val in --- storage-by-rows format. These arrays are not changed on exit. --- --- Diagonal elements of the matrix D are specified in the array D_diag, --- where D_diag[0] is not used, D_diag[i] = d[i,i] for i = 1, ..., n. --- The array D_diag is not changed on exit. --- --- The pattern of the upper triangular part of the matrix S without --- diagonal elements (previously computed by the routine adat_symbolic) --- is specified in the arrays S_ptr and S_ind, which are not changed on --- exit. Numeric values of non-diagonal elements of S are stored in --- corresponding locations of the array S_val, and values of diagonal --- elements of S are stored in locations S_diag[1], ..., S_diag[n]. */ - -void adat_numeric(int m, int n, int P_per[], - int A_ptr[], int A_ind[], double A_val[], double D_diag[], - int S_ptr[], int S_ind[], double S_val[], double S_diag[]) -{ int i, j, t, ii, jj, tt, beg, end, beg1, end1, k; - double sum, *work; - work = xcalloc(1+n, sizeof(double)); - for (j = 1; j <= n; j++) work[j] = 0.0; - /* compute S = B*D*B', where B = P*A, B' is a matrix transposed - to B */ - for (ii = 1; ii <= m; ii++) - { i = P_per[ii]; /* i-th row of A = ii-th row of B */ - /* (work) := (i-th row of A) */ - beg = A_ptr[i], end = A_ptr[i+1]; - for (t = beg; t < end; t++) - work[A_ind[t]] = A_val[t]; - /* compute ii-th row of S */ - beg = S_ptr[ii], end = S_ptr[ii+1]; - for (t = beg; t < end; t++) - { jj = S_ind[t]; - j = P_per[jj]; /* j-th row of A = jj-th row of B */ - /* s[ii,jj] := sum a[i,k] * d[k,k] * a[j,k] */ - sum = 0.0; - beg1 = A_ptr[j], end1 = A_ptr[j+1]; - for (tt = beg1; tt < end1; tt++) - { k = A_ind[tt]; - sum += work[k] * D_diag[k] * A_val[tt]; - } - S_val[t] = sum; - } - /* s[ii,ii] := sum a[i,k] * d[k,k] * a[i,k] */ - sum = 0.0; - beg = A_ptr[i], end = A_ptr[i+1]; - for (t = beg; t < end; t++) - { k = A_ind[t]; - sum += A_val[t] * D_diag[k] * A_val[t]; - work[k] = 0.0; - } - S_diag[ii] = sum; - } - xfree(work); - return; -} - -/*---------------------------------------------------------------------- --- min_degree - minimum degree ordering. --- --- *Synopsis* --- --- #include "glpmat.h" --- void min_degree(int n, int A_ptr[], int A_ind[], int P_per[]); --- --- *Description* --- --- The routine min_degree uses the minimum degree ordering algorithm --- to find a permutation matrix P for a given sparse symmetric positive --- matrix A which minimizes the number of non-zeros in upper triangular --- factor U for Cholesky factorization P*A*P' = U'*U. --- --- The parameter n is the order of matrices A and P. --- --- The pattern of the given matrix A is specified on entry in the arrays --- A_ptr and A_ind in storage-by-rows format. Only the upper triangular --- part without diagonal elements (which all are assumed to be non-zero) --- should be specified as if A were upper triangular. The arrays A_ptr --- and A_ind are not changed on exit. --- --- The permutation matrix P is stored by the routine in the array P_per --- on exit. --- --- *Algorithm* --- --- The routine min_degree is based on some subroutines from the package --- SPARSPAK (see comments in the module glpqmd). */ - -void min_degree(int n, int A_ptr[], int A_ind[], int P_per[]) -{ int i, j, ne, t, pos, len; - int *xadj, *adjncy, *deg, *marker, *rchset, *nbrhd, *qsize, - *qlink, nofsub; - /* determine number of non-zeros in complete pattern */ - ne = A_ptr[n+1] - 1; - ne += ne; - /* allocate working arrays */ - xadj = xcalloc(1+n+1, sizeof(int)); - adjncy = xcalloc(1+ne, sizeof(int)); - deg = xcalloc(1+n, sizeof(int)); - marker = xcalloc(1+n, sizeof(int)); - rchset = xcalloc(1+n, sizeof(int)); - nbrhd = xcalloc(1+n, sizeof(int)); - qsize = xcalloc(1+n, sizeof(int)); - qlink = xcalloc(1+n, sizeof(int)); - /* determine row lengths in complete pattern */ - for (i = 1; i <= n; i++) xadj[i] = 0; - for (i = 1; i <= n; i++) - { for (t = A_ptr[i]; t < A_ptr[i+1]; t++) - { j = A_ind[t]; - xassert(i < j && j <= n); - xadj[i]++, xadj[j]++; - } - } - /* set up row pointers for complete pattern */ - pos = 1; - for (i = 1; i <= n; i++) - len = xadj[i], pos += len, xadj[i] = pos; - xadj[n+1] = pos; - xassert(pos - 1 == ne); - /* construct complete pattern */ - for (i = 1; i <= n; i++) - { for (t = A_ptr[i]; t < A_ptr[i+1]; t++) - { j = A_ind[t]; - adjncy[--xadj[i]] = j, adjncy[--xadj[j]] = i; - } - } - /* call the main minimimum degree ordering routine */ - genqmd(&n, xadj, adjncy, P_per, P_per + n, deg, marker, rchset, - nbrhd, qsize, qlink, &nofsub); - /* make sure that permutation matrix P is correct */ - for (i = 1; i <= n; i++) - { j = P_per[i]; - xassert(1 <= j && j <= n); - xassert(P_per[n+j] == i); - } - /* free working arrays */ - xfree(xadj); - xfree(adjncy); - xfree(deg); - xfree(marker); - xfree(rchset); - xfree(nbrhd); - xfree(qsize); - xfree(qlink); - return; -} - -/**********************************************************************/ - -void amd_order1(int n, int A_ptr[], int A_ind[], int P_per[]) -{ /* approximate minimum degree ordering (AMD) */ - int k, ret; - double Control[AMD_CONTROL], Info[AMD_INFO]; - /* get the default parameters */ - amd_defaults(Control); -#if 0 - /* and print them */ - amd_control(Control); -#endif - /* make all indices 0-based */ - for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]--; - for (k = 1; k <= n+1; k++) A_ptr[k]--; - /* call the ordering routine */ - ret = amd_order(n, &A_ptr[1], &A_ind[1], &P_per[1], Control, Info) - ; -#if 0 - amd_info(Info); -#endif - xassert(ret == AMD_OK || ret == AMD_OK_BUT_JUMBLED); - /* retsore 1-based indices */ - for (k = 1; k <= n+1; k++) A_ptr[k]++; - for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]++; - /* patch up permutation matrix */ - memset(&P_per[n+1], 0, n * sizeof(int)); - for (k = 1; k <= n; k++) - { P_per[k]++; - xassert(1 <= P_per[k] && P_per[k] <= n); - xassert(P_per[n+P_per[k]] == 0); - P_per[n+P_per[k]] = k; - } - return; -} - -/**********************************************************************/ - -static void *allocate(size_t n, size_t size) -{ void *ptr; - ptr = xcalloc(n, size); - memset(ptr, 0, n * size); - return ptr; -} - -static void release(void *ptr) -{ xfree(ptr); - return; -} - -void symamd_ord(int n, int A_ptr[], int A_ind[], int P_per[]) -{ /* approximate minimum degree ordering (SYMAMD) */ - int k, ok; - int stats[COLAMD_STATS]; - /* make all indices 0-based */ - for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]--; - for (k = 1; k <= n+1; k++) A_ptr[k]--; - /* call the ordering routine */ - ok = symamd(n, &A_ind[1], &A_ptr[1], &P_per[1], NULL, stats, - allocate, release); -#if 0 - symamd_report(stats); -#endif - xassert(ok); - /* restore 1-based indices */ - for (k = 1; k <= n+1; k++) A_ptr[k]++; - for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]++; - /* patch up permutation matrix */ - memset(&P_per[n+1], 0, n * sizeof(int)); - for (k = 1; k <= n; k++) - { P_per[k]++; - xassert(1 <= P_per[k] && P_per[k] <= n); - xassert(P_per[n+P_per[k]] == 0); - P_per[n+P_per[k]] = k; - } - return; -} - -/*---------------------------------------------------------------------- --- chol_symbolic - compute Cholesky factorization (symbolic phase). --- --- *Synopsis* --- --- #include "glpmat.h" --- int *chol_symbolic(int n, int A_ptr[], int A_ind[], int U_ptr[]); --- --- *Description* --- --- The routine chol_symbolic implements the symbolic phase of Cholesky --- factorization A = U'*U, where A is a given sparse symmetric positive --- definite matrix, U is a resultant upper triangular factor, U' is a --- matrix transposed to U. --- --- The parameter n is the order of matrices A and U. --- --- The pattern of the given matrix A is specified on entry in the arrays --- A_ptr and A_ind in storage-by-rows format. Only the upper triangular --- part without diagonal elements (which all are assumed to be non-zero) --- should be specified as if A were upper triangular. The arrays A_ptr --- and A_ind are not changed on exit. --- --- The pattern of the matrix U without diagonal elements (which all are --- assumed to be non-zero) is stored on exit from the routine in the --- arrays U_ptr and U_ind in storage-by-rows format. The array U_ptr --- should be allocated on entry, however, its content is ignored. The --- array U_ind is allocated by the routine which returns a pointer to it --- on exit. --- --- *Returns* --- --- The routine returns a pointer to the array U_ind. --- --- *Method* --- --- The routine chol_symbolic computes the pattern of the matrix U in a --- row-wise manner. No pivoting is used. --- --- It is known that to compute the pattern of row k of the matrix U we --- need to merge the pattern of row k of the matrix A and the patterns --- of each row i of U, where u[i,k] is non-zero (these rows are already --- computed and placed above row k). --- --- However, to reduce the number of rows to be merged the routine uses --- an advanced algorithm proposed in: --- --- D.J.Rose, R.E.Tarjan, and G.S.Lueker. Algorithmic aspects of vertex --- elimination on graphs. SIAM J. Comput. 5, 1976, 266-83. --- --- The authors of the cited paper show that we have the same result if --- we merge row k of the matrix A and such rows of the matrix U (among --- rows 1, ..., k-1) whose leftmost non-diagonal non-zero element is --- placed in k-th column. This feature signficantly reduces the number --- of rows to be merged, especially on the final steps, where rows of --- the matrix U become quite dense. --- --- To determine rows, which should be merged on k-th step, for a fixed --- time the routine uses linked lists of row numbers of the matrix U. --- Location head[k] contains the number of a first row, whose leftmost --- non-diagonal non-zero element is placed in column k, and location --- next[i] contains the number of a next row with the same property as --- row i. */ - -int *chol_symbolic(int n, int A_ptr[], int A_ind[], int U_ptr[]) -{ int i, j, k, t, len, size, beg, end, min_j, *U_ind, *head, *next, - *ind, *map, *temp; - /* initially we assume that on computing the pattern of U fill-in - will double the number of non-zeros in A */ - size = A_ptr[n+1] - 1; - if (size < n) size = n; - size += size; - U_ind = xcalloc(1+size, sizeof(int)); - /* allocate and initialize working arrays */ - head = xcalloc(1+n, sizeof(int)); - for (i = 1; i <= n; i++) head[i] = 0; - next = xcalloc(1+n, sizeof(int)); - ind = xcalloc(1+n, sizeof(int)); - map = xcalloc(1+n, sizeof(int)); - for (j = 1; j <= n; j++) map[j] = 0; - /* compute the pattern of matrix U */ - U_ptr[1] = 1; - for (k = 1; k <= n; k++) - { /* compute the pattern of k-th row of U, which is the union of - k-th row of A and those rows of U (among 1, ..., k-1) whose - leftmost non-diagonal non-zero is placed in k-th column */ - /* (ind) := (k-th row of A) */ - len = A_ptr[k+1] - A_ptr[k]; - memcpy(&ind[1], &A_ind[A_ptr[k]], len * sizeof(int)); - for (t = 1; t <= len; t++) - { j = ind[t]; - xassert(k < j && j <= n); - map[j] = 1; - } - /* walk through rows of U whose leftmost non-diagonal non-zero - is placed in k-th column */ - for (i = head[k]; i != 0; i = next[i]) - { /* (ind) := (ind) union (i-th row of U) */ - beg = U_ptr[i], end = U_ptr[i+1]; - for (t = beg; t < end; t++) - { j = U_ind[t]; - if (j > k && !map[j]) ind[++len] = j, map[j] = 1; - } - } - /* now (ind) is the pattern of k-th row of U */ - U_ptr[k+1] = U_ptr[k] + len; - /* at least (U_ptr[k+1] - 1) locations should be available in - the array U_ind */ - if (U_ptr[k+1] - 1 > size) - { temp = U_ind; - size += size; - U_ind = xcalloc(1+size, sizeof(int)); - memcpy(&U_ind[1], &temp[1], (U_ptr[k] - 1) * sizeof(int)); - xfree(temp); - } - xassert(U_ptr[k+1] - 1 <= size); - /* (k-th row of U) := (ind) */ - memcpy(&U_ind[U_ptr[k]], &ind[1], len * sizeof(int)); - /* determine column index of leftmost non-diagonal non-zero in - k-th row of U and clear the row pattern map */ - min_j = n + 1; - for (t = 1; t <= len; t++) - { j = ind[t], map[j] = 0; - if (min_j > j) min_j = j; - } - /* include k-th row into corresponding linked list */ - if (min_j <= n) next[k] = head[min_j], head[min_j] = k; - } - /* free working arrays */ - xfree(head); - xfree(next); - xfree(ind); - xfree(map); - /* reallocate the array U_ind to free unused locations */ - temp = U_ind; - size = U_ptr[n+1] - 1; - U_ind = xcalloc(1+size, sizeof(int)); - memcpy(&U_ind[1], &temp[1], size * sizeof(int)); - xfree(temp); - return U_ind; -} - -/*---------------------------------------------------------------------- --- chol_numeric - compute Cholesky factorization (numeric phase). --- --- *Synopsis* --- --- #include "glpmat.h" --- int chol_numeric(int n, --- int A_ptr[], int A_ind[], double A_val[], double A_diag[], --- int U_ptr[], int U_ind[], double U_val[], double U_diag[]); --- --- *Description* --- --- The routine chol_symbolic implements the numeric phase of Cholesky --- factorization A = U'*U, where A is a given sparse symmetric positive --- definite matrix, U is a resultant upper triangular factor, U' is a --- matrix transposed to U. --- --- The parameter n is the order of matrices A and U. --- --- Upper triangular part of the matrix A without diagonal elements is --- specified in the arrays A_ptr, A_ind, and A_val in storage-by-rows --- format. Diagonal elements of A are specified in the array A_diag, --- where A_diag[0] is not used, A_diag[i] = a[i,i] for i = 1, ..., n. --- The arrays A_ptr, A_ind, A_val, and A_diag are not changed on exit. --- --- The pattern of the matrix U without diagonal elements (previously --- computed with the routine chol_symbolic) is specified in the arrays --- U_ptr and U_ind, which are not changed on exit. Numeric values of --- non-diagonal elements of U are stored in corresponding locations of --- the array U_val, and values of diagonal elements of U are stored in --- locations U_diag[1], ..., U_diag[n]. --- --- *Returns* --- --- The routine returns the number of non-positive diagonal elements of --- the matrix U which have been replaced by a huge positive number (see --- the method description below). Zero return code means the matrix A --- has been successfully factorized. --- --- *Method* --- --- The routine chol_numeric computes the matrix U in a row-wise manner --- using standard gaussian elimination technique. No pivoting is used. --- --- Initially the routine sets U = A, and before k-th elimination step --- the matrix U is the following: --- --- 1 k n --- 1 x x x x x x x x x x --- . x x x x x x x x x --- . . x x x x x x x x --- . . . x x x x x x x --- k . . . . * * * * * * --- . . . . * * * * * * --- . . . . * * * * * * --- . . . . * * * * * * --- . . . . * * * * * * --- n . . . . * * * * * * --- --- where 'x' are elements of already computed rows, '*' are elements of --- the active submatrix. (Note that the lower triangular part of the --- active submatrix being symmetric is not stored and diagonal elements --- are stored separately in the array U_diag.) --- --- The matrix A is assumed to be positive definite. However, if it is --- close to semi-definite, on some elimination step a pivot u[k,k] may --- happen to be non-positive due to round-off errors. In this case the --- routine uses a technique proposed in: --- --- S.J.Wright. The Cholesky factorization in interior-point and barrier --- methods. Preprint MCS-P600-0596, Mathematics and Computer Science --- Division, Argonne National Laboratory, Argonne, Ill., May 1996. --- --- The routine just replaces non-positive u[k,k] by a huge positive --- number. This involves non-diagonal elements in k-th row of U to be --- close to zero that, in turn, involves k-th component of a solution --- vector to be close to zero. Note, however, that this technique works --- only if the system A*x = b is consistent. */ - -int chol_numeric(int n, - int A_ptr[], int A_ind[], double A_val[], double A_diag[], - int U_ptr[], int U_ind[], double U_val[], double U_diag[]) -{ int i, j, k, t, t1, beg, end, beg1, end1, count = 0; - double ukk, uki, *work; - work = xcalloc(1+n, sizeof(double)); - for (j = 1; j <= n; j++) work[j] = 0.0; - /* U := (upper triangle of A) */ - /* note that the upper traingle of A is a subset of U */ - for (i = 1; i <= n; i++) - { beg = A_ptr[i], end = A_ptr[i+1]; - for (t = beg; t < end; t++) - j = A_ind[t], work[j] = A_val[t]; - beg = U_ptr[i], end = U_ptr[i+1]; - for (t = beg; t < end; t++) - j = U_ind[t], U_val[t] = work[j], work[j] = 0.0; - U_diag[i] = A_diag[i]; - } - /* main elimination loop */ - for (k = 1; k <= n; k++) - { /* transform k-th row of U */ - ukk = U_diag[k]; - if (ukk > 0.0) - U_diag[k] = ukk = sqrt(ukk); - else - U_diag[k] = ukk = DBL_MAX, count++; - /* (work) := (transformed k-th row) */ - beg = U_ptr[k], end = U_ptr[k+1]; - for (t = beg; t < end; t++) - work[U_ind[t]] = (U_val[t] /= ukk); - /* transform other rows of U */ - for (t = beg; t < end; t++) - { i = U_ind[t]; - xassert(i > k); - /* (i-th row) := (i-th row) - u[k,i] * (k-th row) */ - uki = work[i]; - beg1 = U_ptr[i], end1 = U_ptr[i+1]; - for (t1 = beg1; t1 < end1; t1++) - U_val[t1] -= uki * work[U_ind[t1]]; - U_diag[i] -= uki * uki; - } - /* (work) := 0 */ - for (t = beg; t < end; t++) - work[U_ind[t]] = 0.0; - } - xfree(work); - return count; -} - -/*---------------------------------------------------------------------- --- u_solve - solve upper triangular system U*x = b. --- --- *Synopsis* --- --- #include "glpmat.h" --- void u_solve(int n, int U_ptr[], int U_ind[], double U_val[], --- double U_diag[], double x[]); --- --- *Description* --- --- The routine u_solve solves an linear system U*x = b, where U is an --- upper triangular matrix. --- --- The parameter n is the order of matrix U. --- --- The matrix U without diagonal elements is specified in the arrays --- U_ptr, U_ind, and U_val in storage-by-rows format. Diagonal elements --- of U are specified in the array U_diag, where U_diag[0] is not used, --- U_diag[i] = u[i,i] for i = 1, ..., n. All these four arrays are not --- changed on exit. --- --- The right-hand side vector b is specified on entry in the array x, --- where x[0] is not used, and x[i] = b[i] for i = 1, ..., n. On exit --- the routine stores computed components of the vector of unknowns x --- in the array x in the same manner. */ - -void u_solve(int n, int U_ptr[], int U_ind[], double U_val[], - double U_diag[], double x[]) -{ int i, t, beg, end; - double temp; - for (i = n; i >= 1; i--) - { temp = x[i]; - beg = U_ptr[i], end = U_ptr[i+1]; - for (t = beg; t < end; t++) - temp -= U_val[t] * x[U_ind[t]]; - xassert(U_diag[i] != 0.0); - x[i] = temp / U_diag[i]; - } - return; -} - -/*---------------------------------------------------------------------- --- ut_solve - solve lower triangular system U'*x = b. --- --- *Synopsis* --- --- #include "glpmat.h" --- void ut_solve(int n, int U_ptr[], int U_ind[], double U_val[], --- double U_diag[], double x[]); --- --- *Description* --- --- The routine ut_solve solves an linear system U'*x = b, where U is a --- matrix transposed to an upper triangular matrix. --- --- The parameter n is the order of matrix U. --- --- The matrix U without diagonal elements is specified in the arrays --- U_ptr, U_ind, and U_val in storage-by-rows format. Diagonal elements --- of U are specified in the array U_diag, where U_diag[0] is not used, --- U_diag[i] = u[i,i] for i = 1, ..., n. All these four arrays are not --- changed on exit. --- --- The right-hand side vector b is specified on entry in the array x, --- where x[0] is not used, and x[i] = b[i] for i = 1, ..., n. On exit --- the routine stores computed components of the vector of unknowns x --- in the array x in the same manner. */ - -void ut_solve(int n, int U_ptr[], int U_ind[], double U_val[], - double U_diag[], double x[]) -{ int i, t, beg, end; - double temp; - for (i = 1; i <= n; i++) - { xassert(U_diag[i] != 0.0); - temp = (x[i] /= U_diag[i]); - if (temp == 0.0) continue; - beg = U_ptr[i], end = U_ptr[i+1]; - for (t = beg; t < end; t++) - x[U_ind[t]] -= U_val[t] * temp; - } - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpmat.h b/resources/3rdparty/glpk-4.53/src/glpmat.h deleted file mode 100644 index 5b0584371..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpmat.h +++ /dev/null @@ -1,198 +0,0 @@ -/* glpmat.h (linear algebra routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPMAT_H -#define GLPMAT_H - -/*********************************************************************** -* FULL-VECTOR STORAGE -* -* For a sparse vector x having n elements, ne of which are non-zero, -* the full-vector storage format uses two arrays x_ind and x_vec, which -* are set up as follows: -* -* x_ind is an integer array of length [1+ne]. Location x_ind[0] is -* not used, and locations x_ind[1], ..., x_ind[ne] contain indices of -* non-zero elements in vector x. -* -* x_vec is a floating-point array of length [1+n]. Location x_vec[0] -* is not used, and locations x_vec[1], ..., x_vec[n] contain numeric -* values of ALL elements in vector x, including its zero elements. -* -* Let, for example, the following sparse vector x be given: -* -* (0, 1, 0, 0, 2, 3, 0, 4) -* -* Then the arrays are: -* -* x_ind = { X; 2, 5, 6, 8 } -* -* x_vec = { X; 0, 1, 0, 0, 2, 3, 0, 4 } -* -* COMPRESSED-VECTOR STORAGE -* -* For a sparse vector x having n elements, ne of which are non-zero, -* the compressed-vector storage format uses two arrays x_ind and x_vec, -* which are set up as follows: -* -* x_ind is an integer array of length [1+ne]. Location x_ind[0] is -* not used, and locations x_ind[1], ..., x_ind[ne] contain indices of -* non-zero elements in vector x. -* -* x_vec is a floating-point array of length [1+ne]. Location x_vec[0] -* is not used, and locations x_vec[1], ..., x_vec[ne] contain numeric -* values of corresponding non-zero elements in vector x. -* -* Let, for example, the following sparse vector x be given: -* -* (0, 1, 0, 0, 2, 3, 0, 4) -* -* Then the arrays are: -* -* x_ind = { X; 2, 5, 6, 8 } -* -* x_vec = { X; 1, 2, 3, 4 } -* -* STORAGE-BY-ROWS -* -* For a sparse matrix A, which has m rows, n columns, and ne non-zero -* elements the storage-by-rows format uses three arrays A_ptr, A_ind, -* and A_val, which are set up as follows: -* -* A_ptr is an integer array of length [1+m+1] also called "row pointer -* array". It contains the relative starting positions of each row of A -* in the arrays A_ind and A_val, i.e. element A_ptr[i], 1 <= i <= m, -* indicates where row i begins in the arrays A_ind and A_val. If all -* elements in row i are zero, then A_ptr[i] = A_ptr[i+1]. Location -* A_ptr[0] is not used, location A_ptr[1] must contain 1, and location -* A_ptr[m+1] must contain ne+1 that indicates the position after the -* last element in the arrays A_ind and A_val. -* -* A_ind is an integer array of length [1+ne]. Location A_ind[0] is not -* used, and locations A_ind[1], ..., A_ind[ne] contain column indices -* of (non-zero) elements in matrix A. -* -* A_val is a floating-point array of length [1+ne]. Location A_val[0] -* is not used, and locations A_val[1], ..., A_val[ne] contain numeric -* values of non-zero elements in matrix A. -* -* Non-zero elements of matrix A are stored contiguously, and the rows -* of matrix A are stored consecutively from 1 to m in the arrays A_ind -* and A_val. The elements in each row of A may be stored in any order -* in A_ind and A_val. Note that elements with duplicate column indices -* are not allowed. -* -* Let, for example, the following sparse matrix A be given: -* -* | 11 . 13 . . . | -* | 21 22 . 24 . . | -* | . 32 33 . . . | -* | . . 43 44 . 46 | -* | . . . . . . | -* | 61 62 . . . 66 | -* -* Then the arrays are: -* -* A_ptr = { X; 1, 3, 6, 8, 11, 11; 14 } -* -* A_ind = { X; 1, 3; 4, 2, 1; 2, 3; 4, 3, 6; 1, 2, 6 } -* -* A_val = { X; 11, 13; 24, 22, 21; 32, 33; 44, 43, 46; 61, 62, 66 } -* -* PERMUTATION MATRICES -* -* Let P be a permutation matrix of the order n. It is represented as -* an integer array P_per of length [1+n+n] as follows: if p[i,j] = 1, -* then P_per[i] = j and P_per[n+j] = i. Location P_per[0] is not used. -* -* Let A' = P*A. If i-th row of A corresponds to i'-th row of A', then -* P_per[i'] = i and P_per[n+i] = i'. -* -* References: -* -* 1. Gustavson F.G. Some basic techniques for solving sparse systems of -* linear equations. In Rose and Willoughby (1972), pp. 41-52. -* -* 2. Basic Linear Algebra Subprograms Technical (BLAST) Forum Standard. -* University of Tennessee (2001). */ - -#define check_fvs _glp_mat_check_fvs -int check_fvs(int n, int nnz, int ind[], double vec[]); -/* check sparse vector in full-vector storage format */ - -#define check_pattern _glp_mat_check_pattern -int check_pattern(int m, int n, int A_ptr[], int A_ind[]); -/* check pattern of sparse matrix */ - -#define transpose _glp_mat_transpose -void transpose(int m, int n, int A_ptr[], int A_ind[], double A_val[], - int AT_ptr[], int AT_ind[], double AT_val[]); -/* transpose sparse matrix */ - -#define adat_symbolic _glp_mat_adat_symbolic -int *adat_symbolic(int m, int n, int P_per[], int A_ptr[], int A_ind[], - int S_ptr[]); -/* compute S = P*A*D*A'*P' (symbolic phase) */ - -#define adat_numeric _glp_mat_adat_numeric -void adat_numeric(int m, int n, int P_per[], - int A_ptr[], int A_ind[], double A_val[], double D_diag[], - int S_ptr[], int S_ind[], double S_val[], double S_diag[]); -/* compute S = P*A*D*A'*P' (numeric phase) */ - -#define min_degree _glp_mat_min_degree -void min_degree(int n, int A_ptr[], int A_ind[], int P_per[]); -/* minimum degree ordering */ - -#define amd_order1 _glp_mat_amd_order1 -void amd_order1(int n, int A_ptr[], int A_ind[], int P_per[]); -/* approximate minimum degree ordering (AMD) */ - -#define symamd_ord _glp_mat_symamd_ord -void symamd_ord(int n, int A_ptr[], int A_ind[], int P_per[]); -/* approximate minimum degree ordering (SYMAMD) */ - -#define chol_symbolic _glp_mat_chol_symbolic -int *chol_symbolic(int n, int A_ptr[], int A_ind[], int U_ptr[]); -/* compute Cholesky factorization (symbolic phase) */ - -#define chol_numeric _glp_mat_chol_numeric -int chol_numeric(int n, - int A_ptr[], int A_ind[], double A_val[], double A_diag[], - int U_ptr[], int U_ind[], double U_val[], double U_diag[]); -/* compute Cholesky factorization (numeric phase) */ - -#define u_solve _glp_mat_u_solve -void u_solve(int n, int U_ptr[], int U_ind[], double U_val[], - double U_diag[], double x[]); -/* solve upper triangular system U*x = b */ - -#define ut_solve _glp_mat_ut_solve -void ut_solve(int n, int U_ptr[], int U_ind[], double U_val[], - double U_diag[], double x[]); -/* solve lower triangular system U'*x = b */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpmpl.h b/resources/3rdparty/glpk-4.53/src/glpmpl.h deleted file mode 100644 index 34445d30a..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpmpl.h +++ /dev/null @@ -1,2594 +0,0 @@ -/* glpmpl.h (GNU MathProg translator) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPMPL_H -#define GLPMPL_H - -#include "avl.h" -#include "dmp.h" -#include "env.h" -#include "misc.h" -#include "rng.h" - -#if 0 /* 22/I-2013 */ -typedef struct MPL MPL; -#else -typedef struct glp_tran MPL; -#endif -typedef char STRING; -typedef struct SYMBOL SYMBOL; -typedef struct TUPLE TUPLE; -typedef struct ARRAY ELEMSET; -typedef struct ELEMVAR ELEMVAR; -typedef struct FORMULA FORMULA; -typedef struct ELEMCON ELEMCON; -typedef union VALUE VALUE; -typedef struct ARRAY ARRAY; -typedef struct MEMBER MEMBER; -#if 1 -/* many C compilers have DOMAIN declared in :( */ -#undef DOMAIN -#define DOMAIN DOMAIN1 -#endif -typedef struct DOMAIN DOMAIN; -typedef struct DOMAIN_BLOCK DOMAIN_BLOCK; -typedef struct DOMAIN_SLOT DOMAIN_SLOT; -typedef struct SET SET; -typedef struct WITHIN WITHIN; -typedef struct GADGET GADGET; -typedef struct PARAMETER PARAMETER; -typedef struct CONDITION CONDITION; -typedef struct VARIABLE VARIABLE; -typedef struct CONSTRAINT CONSTRAINT; -typedef struct TABLE TABLE; -typedef struct TABARG TABARG; -typedef struct TABFLD TABFLD; -typedef struct TABIN TABIN; -typedef struct TABOUT TABOUT; -typedef struct TABDCA TABDCA; -typedef union OPERANDS OPERANDS; -typedef struct ARG_LIST ARG_LIST; -typedef struct CODE CODE; -typedef struct CHECK CHECK; -typedef struct DISPLAY DISPLAY; -typedef struct DISPLAY1 DISPLAY1; -typedef struct PRINTF PRINTF; -typedef struct PRINTF1 PRINTF1; -typedef struct FOR FOR; -typedef struct STATEMENT STATEMENT; -typedef struct TUPLE SLICE; - -/**********************************************************************/ -/* * * TRANSLATOR DATABASE * * */ -/**********************************************************************/ - -#define A_BINARY 101 /* something binary */ -#define A_CHECK 102 /* check statement */ -#define A_CONSTRAINT 103 /* model constraint */ -#define A_DISPLAY 104 /* display statement */ -#define A_ELEMCON 105 /* elemental constraint/objective */ -#define A_ELEMSET 106 /* elemental set */ -#define A_ELEMVAR 107 /* elemental variable */ -#define A_EXPRESSION 108 /* expression */ -#define A_FOR 109 /* for statement */ -#define A_FORMULA 110 /* formula */ -#define A_INDEX 111 /* dummy index */ -#define A_INPUT 112 /* input table */ -#define A_INTEGER 113 /* something integer */ -#define A_LOGICAL 114 /* something logical */ -#define A_MAXIMIZE 115 /* objective has to be maximized */ -#define A_MINIMIZE 116 /* objective has to be minimized */ -#define A_NONE 117 /* nothing */ -#define A_NUMERIC 118 /* something numeric */ -#define A_OUTPUT 119 /* output table */ -#define A_PARAMETER 120 /* model parameter */ -#define A_PRINTF 121 /* printf statement */ -#define A_SET 122 /* model set */ -#define A_SOLVE 123 /* solve statement */ -#define A_SYMBOLIC 124 /* something symbolic */ -#define A_TABLE 125 /* data table */ -#define A_TUPLE 126 /* n-tuple */ -#define A_VARIABLE 127 /* model variable */ - -#define MAX_LENGTH 100 -/* maximal length of any symbolic value (this includes symbolic names, - numeric and string literals, and all symbolic values that may appear - during the evaluation phase) */ - -#define CONTEXT_SIZE 60 -/* size of the context queue, in characters */ - -#define OUTBUF_SIZE 1024 -/* size of the output buffer, in characters */ - -#if 0 /* 22/I-2013 */ -struct MPL -#else -struct glp_tran -#endif -{ /* translator database */ - /*--------------------------------------------------------------*/ - /* scanning segment */ - int line; - /* number of the current text line */ - int c; - /* the current character or EOF */ - int token; - /* the current token: */ -#define T_EOF 201 /* end of file */ -#define T_NAME 202 /* symbolic name (model section only) */ -#define T_SYMBOL 203 /* symbol (data section only) */ -#define T_NUMBER 204 /* numeric literal */ -#define T_STRING 205 /* string literal */ -#define T_AND 206 /* and && */ -#define T_BY 207 /* by */ -#define T_CROSS 208 /* cross */ -#define T_DIFF 209 /* diff */ -#define T_DIV 210 /* div */ -#define T_ELSE 211 /* else */ -#define T_IF 212 /* if */ -#define T_IN 213 /* in */ -#define T_INFINITY 214 /* Infinity */ -#define T_INTER 215 /* inter */ -#define T_LESS 216 /* less */ -#define T_MOD 217 /* mod */ -#define T_NOT 218 /* not ! */ -#define T_OR 219 /* or || */ -#define T_SPTP 220 /* s.t. */ -#define T_SYMDIFF 221 /* symdiff */ -#define T_THEN 222 /* then */ -#define T_UNION 223 /* union */ -#define T_WITHIN 224 /* within */ -#define T_PLUS 225 /* + */ -#define T_MINUS 226 /* - */ -#define T_ASTERISK 227 /* * */ -#define T_SLASH 228 /* / */ -#define T_POWER 229 /* ^ ** */ -#define T_LT 230 /* < */ -#define T_LE 231 /* <= */ -#define T_EQ 232 /* = == */ -#define T_GE 233 /* >= */ -#define T_GT 234 /* > */ -#define T_NE 235 /* <> != */ -#define T_CONCAT 236 /* & */ -#define T_BAR 237 /* | */ -#define T_POINT 238 /* . */ -#define T_COMMA 239 /* , */ -#define T_COLON 240 /* : */ -#define T_SEMICOLON 241 /* ; */ -#define T_ASSIGN 242 /* := */ -#define T_DOTS 243 /* .. */ -#define T_LEFT 244 /* ( */ -#define T_RIGHT 245 /* ) */ -#define T_LBRACKET 246 /* [ */ -#define T_RBRACKET 247 /* ] */ -#define T_LBRACE 248 /* { */ -#define T_RBRACE 249 /* } */ -#define T_APPEND 250 /* >> */ -#define T_TILDE 251 /* ~ */ -#define T_INPUT 252 /* <- */ - int imlen; - /* length of the current token */ - char *image; /* char image[MAX_LENGTH+1]; */ - /* image of the current token */ - double value; - /* value of the current token (for T_NUMBER only) */ - int b_token; - /* the previous token */ - int b_imlen; - /* length of the previous token */ - char *b_image; /* char b_image[MAX_LENGTH+1]; */ - /* image of the previous token */ - double b_value; - /* value of the previous token (if token is T_NUMBER) */ - int f_dots; - /* if this flag is set, the next token should be recognized as - T_DOTS, not as T_POINT */ - int f_scan; - /* if this flag is set, the next token is already scanned */ - int f_token; - /* the next token */ - int f_imlen; - /* length of the next token */ - char *f_image; /* char f_image[MAX_LENGTH+1]; */ - /* image of the next token */ - double f_value; - /* value of the next token (if token is T_NUMBER) */ - char *context; /* char context[CONTEXT_SIZE]; */ - /* context circular queue (not null-terminated!) */ - int c_ptr; - /* pointer to the current position in the context queue */ - int flag_d; - /* if this flag is set, the data section is being processed */ - /*--------------------------------------------------------------*/ - /* translating segment */ - DMP *pool; - /* memory pool used to allocate all data instances created during - the translation phase */ - AVL *tree; - /* symbolic name table: - node.type = A_INDEX => node.link -> DOMAIN_SLOT - node.type = A_SET => node.link -> SET - node.type = A_PARAMETER => node.link -> PARAMETER - node.type = A_VARIABLE => node.link -> VARIABLE - node.type = A_CONSTRANT => node.link -> CONSTRAINT */ - STATEMENT *model; - /* linked list of model statements in the original order */ - int flag_x; - /* if this flag is set, the current token being left parenthesis - begins a slice that allows recognizing any undeclared symbolic - names as dummy indices; this flag is automatically reset once - the next token has been scanned */ - int as_within; - /* the warning "in understood as within" has been issued */ - int as_in; - /* the warning "within understood as in" has been issued */ - int as_binary; - /* the warning "logical understood as binary" has been issued */ - int flag_s; - /* if this flag is set, the solve statement has been parsed */ - /*--------------------------------------------------------------*/ - /* common segment */ - DMP *strings; - /* memory pool to allocate STRING data structures */ - DMP *symbols; - /* memory pool to allocate SYMBOL data structures */ - DMP *tuples; - /* memory pool to allocate TUPLE data structures */ - DMP *arrays; - /* memory pool to allocate ARRAY data structures */ - DMP *members; - /* memory pool to allocate MEMBER data structures */ - DMP *elemvars; - /* memory pool to allocate ELEMVAR data structures */ - DMP *formulae; - /* memory pool to allocate FORMULA data structures */ - DMP *elemcons; - /* memory pool to allocate ELEMCON data structures */ - ARRAY *a_list; - /* linked list of all arrays in the database */ - char *sym_buf; /* char sym_buf[255+1]; */ - /* working buffer used by the routine format_symbol */ - char *tup_buf; /* char tup_buf[255+1]; */ - /* working buffer used by the routine format_tuple */ - /*--------------------------------------------------------------*/ - /* generating/postsolving segment */ - RNG *rand; - /* pseudo-random number generator */ - int flag_p; - /* if this flag is set, the postsolving phase is in effect */ - STATEMENT *stmt; - /* model statement being currently executed */ - TABDCA *dca; - /* pointer to table driver communication area for table statement - currently executed */ - int m; - /* number of rows in the problem, m >= 0 */ - int n; - /* number of columns in the problem, n >= 0 */ - ELEMCON **row; /* ELEMCON *row[1+m]; */ - /* row[0] is not used; - row[i] is elemental constraint or objective, which corresponds - to i-th row of the problem, 1 <= i <= m */ - ELEMVAR **col; /* ELEMVAR *col[1+n]; */ - /* col[0] is not used; - col[j] is elemental variable, which corresponds to j-th column - of the problem, 1 <= j <= n */ - /*--------------------------------------------------------------*/ - /* input/output segment */ - glp_file *in_fp; - /* stream assigned to the input text file */ - char *in_file; - /* name of the input text file */ - glp_file *out_fp; - /* stream assigned to the output text file used to write all data - produced by display and printf statements; NULL means the data - should be sent to stdout via the routine xprintf */ - char *out_file; - /* name of the output text file */ -#if 0 /* 08/XI-2009 */ - char *out_buf; /* char out_buf[OUTBUF_SIZE] */ - /* buffer to accumulate output data */ - int out_cnt; - /* count of data bytes stored in the output buffer */ -#endif - glp_file *prt_fp; - /* stream assigned to the print text file; may be NULL */ - char *prt_file; - /* name of the output print file */ - /*--------------------------------------------------------------*/ - /* solver interface segment */ - jmp_buf jump; - /* jump address for non-local go to in case of error */ - int phase; - /* phase of processing: - 0 - database is being or has been initialized - 1 - model section is being or has been read - 2 - data section is being or has been read - 3 - model is being or has been generated/postsolved - 4 - model processing error has occurred */ - char *mod_file; - /* name of the input text file, which contains model section */ - char *mpl_buf; /* char mpl_buf[255+1]; */ - /* working buffer used by some interface routines */ -}; - -/**********************************************************************/ -/* * * PROCESSING MODEL SECTION * * */ -/**********************************************************************/ - -#define alloc(type) ((type *)dmp_get_atomv(mpl->pool, sizeof(type))) -/* allocate atom of given type */ - -#define enter_context _glp_mpl_enter_context -void enter_context(MPL *mpl); -/* enter current token into context queue */ - -#define print_context _glp_mpl_print_context -void print_context(MPL *mpl); -/* print current content of context queue */ - -#define get_char _glp_mpl_get_char -void get_char(MPL *mpl); -/* scan next character from input text file */ - -#define append_char _glp_mpl_append_char -void append_char(MPL *mpl); -/* append character to current token */ - -#define get_token _glp_mpl_get_token -void get_token(MPL *mpl); -/* scan next token from input text file */ - -#define unget_token _glp_mpl_unget_token -void unget_token(MPL *mpl); -/* return current token back to input stream */ - -#define is_keyword _glp_mpl_is_keyword -int is_keyword(MPL *mpl, char *keyword); -/* check if current token is given non-reserved keyword */ - -#define is_reserved _glp_mpl_is_reserved -int is_reserved(MPL *mpl); -/* check if current token is reserved keyword */ - -#define make_code _glp_mpl_make_code -CODE *make_code(MPL *mpl, int op, OPERANDS *arg, int type, int dim); -/* generate pseudo-code (basic routine) */ - -#define make_unary _glp_mpl_make_unary -CODE *make_unary(MPL *mpl, int op, CODE *x, int type, int dim); -/* generate pseudo-code for unary operation */ - -#define make_binary _glp_mpl_make_binary -CODE *make_binary(MPL *mpl, int op, CODE *x, CODE *y, int type, - int dim); -/* generate pseudo-code for binary operation */ - -#define make_ternary _glp_mpl_make_ternary -CODE *make_ternary(MPL *mpl, int op, CODE *x, CODE *y, CODE *z, - int type, int dim); -/* generate pseudo-code for ternary operation */ - -#define numeric_literal _glp_mpl_numeric_literal -CODE *numeric_literal(MPL *mpl); -/* parse reference to numeric literal */ - -#define string_literal _glp_mpl_string_literal -CODE *string_literal(MPL *mpl); -/* parse reference to string literal */ - -#define create_arg_list _glp_mpl_create_arg_list -ARG_LIST *create_arg_list(MPL *mpl); -/* create empty operands list */ - -#define expand_arg_list _glp_mpl_expand_arg_list -ARG_LIST *expand_arg_list(MPL *mpl, ARG_LIST *list, CODE *x); -/* append operand to operands list */ - -#define arg_list_len _glp_mpl_arg_list_len -int arg_list_len(MPL *mpl, ARG_LIST *list); -/* determine length of operands list */ - -#define subscript_list _glp_mpl_subscript_list -ARG_LIST *subscript_list(MPL *mpl); -/* parse subscript list */ - -#define object_reference _glp_mpl_object_reference -CODE *object_reference(MPL *mpl); -/* parse reference to named object */ - -#define numeric_argument _glp_mpl_numeric_argument -CODE *numeric_argument(MPL *mpl, char *func); -/* parse argument passed to built-in function */ - -#define symbolic_argument _glp_mpl_symbolic_argument -CODE *symbolic_argument(MPL *mpl, char *func); - -#define elemset_argument _glp_mpl_elemset_argument -CODE *elemset_argument(MPL *mpl, char *func); - -#define function_reference _glp_mpl_function_reference -CODE *function_reference(MPL *mpl); -/* parse reference to built-in function */ - -#define create_domain _glp_mpl_create_domain -DOMAIN *create_domain(MPL *mpl); -/* create empty domain */ - -#define create_block _glp_mpl_create_block -DOMAIN_BLOCK *create_block(MPL *mpl); -/* create empty domain block */ - -#define append_block _glp_mpl_append_block -void append_block(MPL *mpl, DOMAIN *domain, DOMAIN_BLOCK *block); -/* append domain block to specified domain */ - -#define append_slot _glp_mpl_append_slot -DOMAIN_SLOT *append_slot(MPL *mpl, DOMAIN_BLOCK *block, char *name, - CODE *code); -/* create and append new slot to domain block */ - -#define expression_list _glp_mpl_expression_list -CODE *expression_list(MPL *mpl); -/* parse expression list */ - -#define literal_set _glp_mpl_literal_set -CODE *literal_set(MPL *mpl, CODE *code); -/* parse literal set */ - -#define indexing_expression _glp_mpl_indexing_expression -DOMAIN *indexing_expression(MPL *mpl); -/* parse indexing expression */ - -#define close_scope _glp_mpl_close_scope -void close_scope(MPL *mpl, DOMAIN *domain); -/* close scope of indexing expression */ - -#define iterated_expression _glp_mpl_iterated_expression -CODE *iterated_expression(MPL *mpl); -/* parse iterated expression */ - -#define domain_arity _glp_mpl_domain_arity -int domain_arity(MPL *mpl, DOMAIN *domain); -/* determine arity of domain */ - -#define set_expression _glp_mpl_set_expression -CODE *set_expression(MPL *mpl); -/* parse set expression */ - -#define branched_expression _glp_mpl_branched_expression -CODE *branched_expression(MPL *mpl); -/* parse conditional expression */ - -#define primary_expression _glp_mpl_primary_expression -CODE *primary_expression(MPL *mpl); -/* parse primary expression */ - -#define error_preceding _glp_mpl_error_preceding -void error_preceding(MPL *mpl, char *opstr); -/* raise error if preceding operand has wrong type */ - -#define error_following _glp_mpl_error_following -void error_following(MPL *mpl, char *opstr); -/* raise error if following operand has wrong type */ - -#define error_dimension _glp_mpl_error_dimension -void error_dimension(MPL *mpl, char *opstr, int dim1, int dim2); -/* raise error if operands have different dimension */ - -#define expression_0 _glp_mpl_expression_0 -CODE *expression_0(MPL *mpl); -/* parse expression of level 0 */ - -#define expression_1 _glp_mpl_expression_1 -CODE *expression_1(MPL *mpl); -/* parse expression of level 1 */ - -#define expression_2 _glp_mpl_expression_2 -CODE *expression_2(MPL *mpl); -/* parse expression of level 2 */ - -#define expression_3 _glp_mpl_expression_3 -CODE *expression_3(MPL *mpl); -/* parse expression of level 3 */ - -#define expression_4 _glp_mpl_expression_4 -CODE *expression_4(MPL *mpl); -/* parse expression of level 4 */ - -#define expression_5 _glp_mpl_expression_5 -CODE *expression_5(MPL *mpl); -/* parse expression of level 5 */ - -#define expression_6 _glp_mpl_expression_6 -CODE *expression_6(MPL *mpl); -/* parse expression of level 6 */ - -#define expression_7 _glp_mpl_expression_7 -CODE *expression_7(MPL *mpl); -/* parse expression of level 7 */ - -#define expression_8 _glp_mpl_expression_8 -CODE *expression_8(MPL *mpl); -/* parse expression of level 8 */ - -#define expression_9 _glp_mpl_expression_9 -CODE *expression_9(MPL *mpl); -/* parse expression of level 9 */ - -#define expression_10 _glp_mpl_expression_10 -CODE *expression_10(MPL *mpl); -/* parse expression of level 10 */ - -#define expression_11 _glp_mpl_expression_11 -CODE *expression_11(MPL *mpl); -/* parse expression of level 11 */ - -#define expression_12 _glp_mpl_expression_12 -CODE *expression_12(MPL *mpl); -/* parse expression of level 12 */ - -#define expression_13 _glp_mpl_expression_13 -CODE *expression_13(MPL *mpl); -/* parse expression of level 13 */ - -#define set_statement _glp_mpl_set_statement -SET *set_statement(MPL *mpl); -/* parse set statement */ - -#define parameter_statement _glp_mpl_parameter_statement -PARAMETER *parameter_statement(MPL *mpl); -/* parse parameter statement */ - -#define variable_statement _glp_mpl_variable_statement -VARIABLE *variable_statement(MPL *mpl); -/* parse variable statement */ - -#define constraint_statement _glp_mpl_constraint_statement -CONSTRAINT *constraint_statement(MPL *mpl); -/* parse constraint statement */ - -#define objective_statement _glp_mpl_objective_statement -CONSTRAINT *objective_statement(MPL *mpl); -/* parse objective statement */ - -#define table_statement _glp_mpl_table_statement -TABLE *table_statement(MPL *mpl); -/* parse table statement */ - -#define solve_statement _glp_mpl_solve_statement -void *solve_statement(MPL *mpl); -/* parse solve statement */ - -#define check_statement _glp_mpl_check_statement -CHECK *check_statement(MPL *mpl); -/* parse check statement */ - -#define display_statement _glp_mpl_display_statement -DISPLAY *display_statement(MPL *mpl); -/* parse display statement */ - -#define printf_statement _glp_mpl_printf_statement -PRINTF *printf_statement(MPL *mpl); -/* parse printf statement */ - -#define for_statement _glp_mpl_for_statement -FOR *for_statement(MPL *mpl); -/* parse for statement */ - -#define end_statement _glp_mpl_end_statement -void end_statement(MPL *mpl); -/* parse end statement */ - -#define simple_statement _glp_mpl_simple_statement -STATEMENT *simple_statement(MPL *mpl, int spec); -/* parse simple statement */ - -#define model_section _glp_mpl_model_section -void model_section(MPL *mpl); -/* parse model section */ - -/**********************************************************************/ -/* * * PROCESSING DATA SECTION * * */ -/**********************************************************************/ - -#if 2 + 2 == 5 -struct SLICE /* see TUPLE */ -{ /* component of slice; the slice itself is associated with its - first component; slices are similar to n-tuples with exception - that some slice components (which are indicated by asterisks) - don't refer to any symbols */ - SYMBOL *sym; - /* symbol, which this component refers to; can be NULL */ - SLICE *next; - /* the next component of slice */ -}; -#endif - -#define create_slice _glp_mpl_create_slice -SLICE *create_slice(MPL *mpl); -/* create slice */ - -#define expand_slice _glp_mpl_expand_slice -SLICE *expand_slice -( MPL *mpl, - SLICE *slice, /* destroyed */ - SYMBOL *sym /* destroyed */ -); -/* append new component to slice */ - -#define slice_dimen _glp_mpl_slice_dimen -int slice_dimen -( MPL *mpl, - SLICE *slice /* not changed */ -); -/* determine dimension of slice */ - -#define slice_arity _glp_mpl_slice_arity -int slice_arity -( MPL *mpl, - SLICE *slice /* not changed */ -); -/* determine arity of slice */ - -#define fake_slice _glp_mpl_fake_slice -SLICE *fake_slice(MPL *mpl, int dim); -/* create fake slice of all asterisks */ - -#define delete_slice _glp_mpl_delete_slice -void delete_slice -( MPL *mpl, - SLICE *slice /* destroyed */ -); -/* delete slice */ - -#define is_number _glp_mpl_is_number -int is_number(MPL *mpl); -/* check if current token is number */ - -#define is_symbol _glp_mpl_is_symbol -int is_symbol(MPL *mpl); -/* check if current token is symbol */ - -#define is_literal _glp_mpl_is_literal -int is_literal(MPL *mpl, char *literal); -/* check if current token is given symbolic literal */ - -#define read_number _glp_mpl_read_number -double read_number(MPL *mpl); -/* read number */ - -#define read_symbol _glp_mpl_read_symbol -SYMBOL *read_symbol(MPL *mpl); -/* read symbol */ - -#define read_slice _glp_mpl_read_slice -SLICE *read_slice -( MPL *mpl, - char *name, /* not changed */ - int dim -); -/* read slice */ - -#define select_set _glp_mpl_select_set -SET *select_set -( MPL *mpl, - char *name /* not changed */ -); -/* select set to saturate it with elemental sets */ - -#define simple_format _glp_mpl_simple_format -void simple_format -( MPL *mpl, - SET *set, /* not changed */ - MEMBER *memb, /* modified */ - SLICE *slice /* not changed */ -); -/* read set data block in simple format */ - -#define matrix_format _glp_mpl_matrix_format -void matrix_format -( MPL *mpl, - SET *set, /* not changed */ - MEMBER *memb, /* modified */ - SLICE *slice, /* not changed */ - int tr -); -/* read set data block in matrix format */ - -#define set_data _glp_mpl_set_data -void set_data(MPL *mpl); -/* read set data */ - -#define select_parameter _glp_mpl_select_parameter -PARAMETER *select_parameter -( MPL *mpl, - char *name /* not changed */ -); -/* select parameter to saturate it with data */ - -#define set_default _glp_mpl_set_default -void set_default -( MPL *mpl, - PARAMETER *par, /* not changed */ - SYMBOL *altval /* destroyed */ -); -/* set default parameter value */ - -#define read_value _glp_mpl_read_value -MEMBER *read_value -( MPL *mpl, - PARAMETER *par, /* not changed */ - TUPLE *tuple /* destroyed */ -); -/* read value and assign it to parameter member */ - -#define plain_format _glp_mpl_plain_format -void plain_format -( MPL *mpl, - PARAMETER *par, /* not changed */ - SLICE *slice /* not changed */ -); -/* read parameter data block in plain format */ - -#define tabular_format _glp_mpl_tabular_format -void tabular_format -( MPL *mpl, - PARAMETER *par, /* not changed */ - SLICE *slice, /* not changed */ - int tr -); -/* read parameter data block in tabular format */ - -#define tabbing_format _glp_mpl_tabbing_format -void tabbing_format -( MPL *mpl, - SYMBOL *altval /* not changed */ -); -/* read parameter data block in tabbing format */ - -#define parameter_data _glp_mpl_parameter_data -void parameter_data(MPL *mpl); -/* read parameter data */ - -#define data_section _glp_mpl_data_section -void data_section(MPL *mpl); -/* read data section */ - -/**********************************************************************/ -/* * * FLOATING-POINT NUMBERS * * */ -/**********************************************************************/ - -#define fp_add _glp_mpl_fp_add -double fp_add(MPL *mpl, double x, double y); -/* floating-point addition */ - -#define fp_sub _glp_mpl_fp_sub -double fp_sub(MPL *mpl, double x, double y); -/* floating-point subtraction */ - -#define fp_less _glp_mpl_fp_less -double fp_less(MPL *mpl, double x, double y); -/* floating-point non-negative subtraction */ - -#define fp_mul _glp_mpl_fp_mul -double fp_mul(MPL *mpl, double x, double y); -/* floating-point multiplication */ - -#define fp_div _glp_mpl_fp_div -double fp_div(MPL *mpl, double x, double y); -/* floating-point division */ - -#define fp_idiv _glp_mpl_fp_idiv -double fp_idiv(MPL *mpl, double x, double y); -/* floating-point quotient of exact division */ - -#define fp_mod _glp_mpl_fp_mod -double fp_mod(MPL *mpl, double x, double y); -/* floating-point remainder of exact division */ - -#define fp_power _glp_mpl_fp_power -double fp_power(MPL *mpl, double x, double y); -/* floating-point exponentiation (raise to power) */ - -#define fp_exp _glp_mpl_fp_exp -double fp_exp(MPL *mpl, double x); -/* floating-point base-e exponential */ - -#define fp_log _glp_mpl_fp_log -double fp_log(MPL *mpl, double x); -/* floating-point natural logarithm */ - -#define fp_log10 _glp_mpl_fp_log10 -double fp_log10(MPL *mpl, double x); -/* floating-point common (decimal) logarithm */ - -#define fp_sqrt _glp_mpl_fp_sqrt -double fp_sqrt(MPL *mpl, double x); -/* floating-point square root */ - -#define fp_sin _glp_mpl_fp_sin -double fp_sin(MPL *mpl, double x); -/* floating-point trigonometric sine */ - -#define fp_cos _glp_mpl_fp_cos -double fp_cos(MPL *mpl, double x); -/* floating-point trigonometric cosine */ - -#define fp_atan _glp_mpl_fp_atan -double fp_atan(MPL *mpl, double x); -/* floating-point trigonometric arctangent */ - -#define fp_atan2 _glp_mpl_fp_atan2 -double fp_atan2(MPL *mpl, double y, double x); -/* floating-point trigonometric arctangent */ - -#define fp_round _glp_mpl_fp_round -double fp_round(MPL *mpl, double x, double n); -/* round floating-point value to n fractional digits */ - -#define fp_trunc _glp_mpl_fp_trunc -double fp_trunc(MPL *mpl, double x, double n); -/* truncate floating-point value to n fractional digits */ - -/**********************************************************************/ -/* * * PSEUDO-RANDOM NUMBER GENERATORS * * */ -/**********************************************************************/ - -#define fp_irand224 _glp_mpl_fp_irand224 -double fp_irand224(MPL *mpl); -/* pseudo-random integer in the range [0, 2^24) */ - -#define fp_uniform01 _glp_mpl_fp_uniform01 -double fp_uniform01(MPL *mpl); -/* pseudo-random number in the range [0, 1) */ - -#define fp_uniform _glp_mpl_uniform -double fp_uniform(MPL *mpl, double a, double b); -/* pseudo-random number in the range [a, b) */ - -#define fp_normal01 _glp_mpl_fp_normal01 -double fp_normal01(MPL *mpl); -/* Gaussian random variate with mu = 0 and sigma = 1 */ - -#define fp_normal _glp_mpl_fp_normal -double fp_normal(MPL *mpl, double mu, double sigma); -/* Gaussian random variate with specified mu and sigma */ - -/**********************************************************************/ -/* * * DATE/TIME * * */ -/**********************************************************************/ - -#define fn_gmtime _glp_mpl_fn_gmtime -double fn_gmtime(MPL *mpl); -/* obtain the current calendar time (UTC) */ - -#define fn_str2time _glp_mpl_fn_str2time -double fn_str2time(MPL *mpl, const char *str, const char *fmt); -/* convert character string to the calendar time */ - -#define fn_time2str _glp_mpl_fn_time2str -void fn_time2str(MPL *mpl, char *str, double t, const char *fmt); -/* convert the calendar time to character string */ - -/**********************************************************************/ -/* * * CHARACTER STRINGS * * */ -/**********************************************************************/ - -#define create_string _glp_mpl_create_string -STRING *create_string -( MPL *mpl, - char buf[MAX_LENGTH+1] /* not changed */ -); -/* create character string */ - -#define copy_string _glp_mpl_copy_string -STRING *copy_string -( MPL *mpl, - STRING *str /* not changed */ -); -/* make copy of character string */ - -#define compare_strings _glp_mpl_compare_strings -int compare_strings -( MPL *mpl, - STRING *str1, /* not changed */ - STRING *str2 /* not changed */ -); -/* compare one character string with another */ - -#define fetch_string _glp_mpl_fetch_string -char *fetch_string -( MPL *mpl, - STRING *str, /* not changed */ - char buf[MAX_LENGTH+1] /* modified */ -); -/* extract content of character string */ - -#define delete_string _glp_mpl_delete_string -void delete_string -( MPL *mpl, - STRING *str /* destroyed */ -); -/* delete character string */ - -/**********************************************************************/ -/* * * SYMBOLS * * */ -/**********************************************************************/ - -struct SYMBOL -{ /* symbol (numeric or abstract quantity) */ - double num; - /* numeric value of symbol (used only if str == NULL) */ - STRING *str; - /* abstract value of symbol (used only if str != NULL) */ -}; - -#define create_symbol_num _glp_mpl_create_symbol_num -SYMBOL *create_symbol_num(MPL *mpl, double num); -/* create symbol of numeric type */ - -#define create_symbol_str _glp_mpl_create_symbol_str -SYMBOL *create_symbol_str -( MPL *mpl, - STRING *str /* destroyed */ -); -/* create symbol of abstract type */ - -#define copy_symbol _glp_mpl_copy_symbol -SYMBOL *copy_symbol -( MPL *mpl, - SYMBOL *sym /* not changed */ -); -/* make copy of symbol */ - -#define compare_symbols _glp_mpl_compare_symbols -int compare_symbols -( MPL *mpl, - SYMBOL *sym1, /* not changed */ - SYMBOL *sym2 /* not changed */ -); -/* compare one symbol with another */ - -#define delete_symbol _glp_mpl_delete_symbol -void delete_symbol -( MPL *mpl, - SYMBOL *sym /* destroyed */ -); -/* delete symbol */ - -#define format_symbol _glp_mpl_format_symbol -char *format_symbol -( MPL *mpl, - SYMBOL *sym /* not changed */ -); -/* format symbol for displaying or printing */ - -#define concat_symbols _glp_mpl_concat_symbols -SYMBOL *concat_symbols -( MPL *mpl, - SYMBOL *sym1, /* destroyed */ - SYMBOL *sym2 /* destroyed */ -); -/* concatenate one symbol with another */ - -/**********************************************************************/ -/* * * N-TUPLES * * */ -/**********************************************************************/ - -struct TUPLE -{ /* component of n-tuple; the n-tuple itself is associated with - its first component; (note that 0-tuple has no components) */ - SYMBOL *sym; - /* symbol, which the component refers to; cannot be NULL */ - TUPLE *next; - /* the next component of n-tuple */ -}; - -#define create_tuple _glp_mpl_create_tuple -TUPLE *create_tuple(MPL *mpl); -/* create n-tuple */ - -#define expand_tuple _glp_mpl_expand_tuple -TUPLE *expand_tuple -( MPL *mpl, - TUPLE *tuple, /* destroyed */ - SYMBOL *sym /* destroyed */ -); -/* append symbol to n-tuple */ - -#define tuple_dimen _glp_mpl_tuple_dimen -int tuple_dimen -( MPL *mpl, - TUPLE *tuple /* not changed */ -); -/* determine dimension of n-tuple */ - -#define copy_tuple _glp_mpl_copy_tuple -TUPLE *copy_tuple -( MPL *mpl, - TUPLE *tuple /* not changed */ -); -/* make copy of n-tuple */ - -#define compare_tuples _glp_mpl_compare_tuples -int compare_tuples -( MPL *mpl, - TUPLE *tuple1, /* not changed */ - TUPLE *tuple2 /* not changed */ -); -/* compare one n-tuple with another */ - -#define build_subtuple _glp_mpl_build_subtuple -TUPLE *build_subtuple -( MPL *mpl, - TUPLE *tuple, /* not changed */ - int dim -); -/* build subtuple of given n-tuple */ - -#define delete_tuple _glp_mpl_delete_tuple -void delete_tuple -( MPL *mpl, - TUPLE *tuple /* destroyed */ -); -/* delete n-tuple */ - -#define format_tuple _glp_mpl_format_tuple -char *format_tuple -( MPL *mpl, - int c, - TUPLE *tuple /* not changed */ -); -/* format n-tuple for displaying or printing */ - -/**********************************************************************/ -/* * * ELEMENTAL SETS * * */ -/**********************************************************************/ - -#if 2 + 2 == 5 -struct ELEMSET /* see ARRAY */ -{ /* elemental set of n-tuples; formally it is a "value" assigned - to members of model sets (like numbers and symbols, which are - values assigned to members of model parameters); note that a - simple model set is not an elemental set, it is 0-dimensional - array, the only member of which (if it exists) is assigned an - elemental set */ -#endif - -#define create_elemset _glp_mpl_create_elemset -ELEMSET *create_elemset(MPL *mpl, int dim); -/* create elemental set */ - -#define find_tuple _glp_mpl_find_tuple -MEMBER *find_tuple -( MPL *mpl, - ELEMSET *set, /* not changed */ - TUPLE *tuple /* not changed */ -); -/* check if elemental set contains given n-tuple */ - -#define add_tuple _glp_mpl_add_tuple -MEMBER *add_tuple -( MPL *mpl, - ELEMSET *set, /* modified */ - TUPLE *tuple /* destroyed */ -); -/* add new n-tuple to elemental set */ - -#define check_then_add _glp_mpl_check_then_add -MEMBER *check_then_add -( MPL *mpl, - ELEMSET *set, /* modified */ - TUPLE *tuple /* destroyed */ -); -/* check and add new n-tuple to elemental set */ - -#define copy_elemset _glp_mpl_copy_elemset -ELEMSET *copy_elemset -( MPL *mpl, - ELEMSET *set /* not changed */ -); -/* make copy of elemental set */ - -#define delete_elemset _glp_mpl_delete_elemset -void delete_elemset -( MPL *mpl, - ELEMSET *set /* destroyed */ -); -/* delete elemental set */ - -#define arelset_size _glp_mpl_arelset_size -int arelset_size(MPL *mpl, double t0, double tf, double dt); -/* compute size of "arithmetic" elemental set */ - -#define arelset_member _glp_mpl_arelset_member -double arelset_member(MPL *mpl, double t0, double tf, double dt, int j); -/* compute member of "arithmetic" elemental set */ - -#define create_arelset _glp_mpl_create_arelset -ELEMSET *create_arelset(MPL *mpl, double t0, double tf, double dt); -/* create "arithmetic" elemental set */ - -#define set_union _glp_mpl_set_union -ELEMSET *set_union -( MPL *mpl, - ELEMSET *X, /* destroyed */ - ELEMSET *Y /* destroyed */ -); -/* union of two elemental sets */ - -#define set_diff _glp_mpl_set_diff -ELEMSET *set_diff -( MPL *mpl, - ELEMSET *X, /* destroyed */ - ELEMSET *Y /* destroyed */ -); -/* difference between two elemental sets */ - -#define set_symdiff _glp_mpl_set_symdiff -ELEMSET *set_symdiff -( MPL *mpl, - ELEMSET *X, /* destroyed */ - ELEMSET *Y /* destroyed */ -); -/* symmetric difference between two elemental sets */ - -#define set_inter _glp_mpl_set_inter -ELEMSET *set_inter -( MPL *mpl, - ELEMSET *X, /* destroyed */ - ELEMSET *Y /* destroyed */ -); -/* intersection of two elemental sets */ - -#define set_cross _glp_mpl_set_cross -ELEMSET *set_cross -( MPL *mpl, - ELEMSET *X, /* destroyed */ - ELEMSET *Y /* destroyed */ -); -/* cross (Cartesian) product of two elemental sets */ - -/**********************************************************************/ -/* * * ELEMENTAL VARIABLES * * */ -/**********************************************************************/ - -struct ELEMVAR -{ /* elemental variable; formally it is a "value" assigned to - members of model variables (like numbers and symbols, which - are values assigned to members of model parameters) */ - int j; - /* LP column number assigned to this elemental variable */ - VARIABLE *var; - /* model variable, which contains this elemental variable */ - MEMBER *memb; - /* array member, which is assigned this elemental variable */ - double lbnd; - /* lower bound */ - double ubnd; - /* upper bound */ - double temp; - /* working quantity used in operations on linear forms; normally - it contains floating-point zero */ -#if 1 /* 15/V-2010 */ - int stat; - double prim, dual; - /* solution components provided by the solver */ -#endif -}; - -/**********************************************************************/ -/* * * LINEAR FORMS * * */ -/**********************************************************************/ - -struct FORMULA -{ /* term of linear form c * x, where c is a coefficient, x is an - elemental variable; the linear form itself is the sum of terms - and is associated with its first term; (note that the linear - form may be empty that means the sum is equal to zero) */ - double coef; - /* coefficient at elemental variable or constant term */ - ELEMVAR *var; - /* reference to elemental variable; NULL means constant term */ - FORMULA *next; - /* the next term of linear form */ -}; - -#define constant_term _glp_mpl_constant_term -FORMULA *constant_term(MPL *mpl, double coef); -/* create constant term */ - -#define single_variable _glp_mpl_single_variable -FORMULA *single_variable -( MPL *mpl, - ELEMVAR *var /* referenced */ -); -/* create single variable */ - -#define copy_formula _glp_mpl_copy_formula -FORMULA *copy_formula -( MPL *mpl, - FORMULA *form /* not changed */ -); -/* make copy of linear form */ - -#define delete_formula _glp_mpl_delete_formula -void delete_formula -( MPL *mpl, - FORMULA *form /* destroyed */ -); -/* delete linear form */ - -#define linear_comb _glp_mpl_linear_comb -FORMULA *linear_comb -( MPL *mpl, - double a, FORMULA *fx, /* destroyed */ - double b, FORMULA *fy /* destroyed */ -); -/* linear combination of two linear forms */ - -#define remove_constant _glp_mpl_remove_constant -FORMULA *remove_constant -( MPL *mpl, - FORMULA *form, /* destroyed */ - double *coef /* modified */ -); -/* remove constant term from linear form */ - -#define reduce_terms _glp_mpl_reduce_terms -FORMULA *reduce_terms -( MPL *mpl, - FORMULA *form /* destroyed */ -); -/* reduce identical terms in linear form */ - -/**********************************************************************/ -/* * * ELEMENTAL CONSTRAINTS * * */ -/**********************************************************************/ - -struct ELEMCON -{ /* elemental constraint; formally it is a "value" assigned to - members of model constraints (like numbers or symbols, which - are values assigned to members of model parameters) */ - int i; - /* LP row number assigned to this elemental constraint */ - CONSTRAINT *con; - /* model constraint, which contains this elemental constraint */ - MEMBER *memb; - /* array member, which is assigned this elemental constraint */ - FORMULA *form; - /* linear form */ - double lbnd; - /* lower bound */ - double ubnd; - /* upper bound */ -#if 1 /* 15/V-2010 */ - int stat; - double prim, dual; - /* solution components provided by the solver */ -#endif -}; - -/**********************************************************************/ -/* * * GENERIC VALUES * * */ -/**********************************************************************/ - -union VALUE -{ /* generic value, which can be assigned to object member or be a - result of evaluation of expression */ - /* indicator that specifies the particular type of generic value - is stored in the corresponding array or pseudo-code descriptor - and can be one of the following: - A_NONE - no value - A_NUMERIC - floating-point number - A_SYMBOLIC - symbol - A_LOGICAL - logical value - A_TUPLE - n-tuple - A_ELEMSET - elemental set - A_ELEMVAR - elemental variable - A_FORMULA - linear form - A_ELEMCON - elemental constraint */ - void *none; /* null */ - double num; /* value */ - SYMBOL *sym; /* value */ - int bit; /* value */ - TUPLE *tuple; /* value */ - ELEMSET *set; /* value */ - ELEMVAR *var; /* reference */ - FORMULA *form; /* value */ - ELEMCON *con; /* reference */ -}; - -#define delete_value _glp_mpl_delete_value -void delete_value -( MPL *mpl, - int type, - VALUE *value /* content destroyed */ -); -/* delete generic value */ - -/**********************************************************************/ -/* * * SYMBOLICALLY INDEXED ARRAYS * * */ -/**********************************************************************/ - -struct ARRAY -{ /* multi-dimensional array, a set of members indexed over simple - or compound sets of symbols; arrays are used to represent the - contents of model objects (i.e. sets, parameters, variables, - constraints, and objectives); arrays also are used as "values" - that are assigned to members of set objects, in which case the - array itself represents an elemental set */ - int type; - /* type of generic values assigned to the array members: - A_NONE - none (members have no assigned values) - A_NUMERIC - floating-point numbers - A_SYMBOLIC - symbols - A_ELEMSET - elemental sets - A_ELEMVAR - elemental variables - A_ELEMCON - elemental constraints */ - int dim; - /* dimension of the array that determines number of components in - n-tuples for all members of the array, dim >= 0; dim = 0 means - the array is 0-dimensional */ - int size; - /* size of the array, i.e. number of its members */ - MEMBER *head; - /* the first array member; NULL means the array is empty */ - MEMBER *tail; - /* the last array member; NULL means the array is empty */ - AVL *tree; - /* the search tree intended to find array members for logarithmic - time; NULL means the search tree doesn't exist */ - ARRAY *prev; - /* the previous array in the translator database */ - ARRAY *next; - /* the next array in the translator database */ -}; - -struct MEMBER -{ /* array member */ - TUPLE *tuple; - /* n-tuple, which identifies the member; number of its components - is the same for all members within the array and determined by - the array dimension; duplicate members are not allowed */ - MEMBER *next; - /* the next array member */ - VALUE value; - /* generic value assigned to the member */ -}; - -#define create_array _glp_mpl_create_array -ARRAY *create_array(MPL *mpl, int type, int dim); -/* create array */ - -#define find_member _glp_mpl_find_member -MEMBER *find_member -( MPL *mpl, - ARRAY *array, /* not changed */ - TUPLE *tuple /* not changed */ -); -/* find array member with given n-tuple */ - -#define add_member _glp_mpl_add_member -MEMBER *add_member -( MPL *mpl, - ARRAY *array, /* modified */ - TUPLE *tuple /* destroyed */ -); -/* add new member to array */ - -#define delete_array _glp_mpl_delete_array -void delete_array -( MPL *mpl, - ARRAY *array /* destroyed */ -); -/* delete array */ - -/**********************************************************************/ -/* * * DOMAINS AND DUMMY INDICES * * */ -/**********************************************************************/ - -struct DOMAIN -{ /* domain (a simple or compound set); syntactically domain looks - like '{ i in I, (j,k) in S, t in T : }'; domains - are used to define sets, over which model objects are indexed, - and also as constituents of iterated operators */ - DOMAIN_BLOCK *list; - /* linked list of domain blocks (in the example above such blocks - are 'i in I', '(j,k) in S', and 't in T'); this list cannot be - empty */ - CODE *code; - /* pseudo-code for computing the logical predicate, which follows - the colon; NULL means no predicate is specified */ -}; - -struct DOMAIN_BLOCK -{ /* domain block; syntactically domain blocks look like 'i in I', - '(j,k) in S', and 't in T' in the example above (in the sequel - sets like I, S, and T are called basic sets) */ - DOMAIN_SLOT *list; - /* linked list of domain slots (i.e. indexing positions); number - of slots in this list is the same as dimension of n-tuples in - the basic set; this list cannot be empty */ - CODE *code; - /* pseudo-code for computing basic set; cannot be NULL */ - TUPLE *backup; - /* if this n-tuple is not empty, current values of dummy indices - in the domain block are the same as components of this n-tuple - (note that this n-tuple may have larger dimension than number - of dummy indices in this block, in which case extra components - are ignored); this n-tuple is used to restore former values of - dummy indices, if they were changed due to recursive calls to - the domain block */ - DOMAIN_BLOCK *next; - /* the next block in the same domain */ -}; - -struct DOMAIN_SLOT -{ /* domain slot; it specifies an individual indexing position and - defines the corresponding dummy index */ - char *name; - /* symbolic name of the dummy index; null pointer means the dummy - index is not explicitly specified */ - CODE *code; - /* pseudo-code for computing symbolic value, at which the dummy - index is bound; NULL means the dummy index is free within the - domain scope */ - SYMBOL *value; - /* current value assigned to the dummy index; NULL means no value - is assigned at the moment */ - CODE *list; - /* linked list of pseudo-codes with operation O_INDEX referring - to this slot; this linked list is used to invalidate resultant - values of the operation, which depend on this dummy index */ - DOMAIN_SLOT *next; - /* the next slot in the same domain block */ -}; - -#define assign_dummy_index _glp_mpl_assign_dummy_index -void assign_dummy_index -( MPL *mpl, - DOMAIN_SLOT *slot, /* modified */ - SYMBOL *value /* not changed */ -); -/* assign new value to dummy index */ - -#define update_dummy_indices _glp_mpl_update_dummy_indices -void update_dummy_indices -( MPL *mpl, - DOMAIN_BLOCK *block /* not changed */ -); -/* update current values of dummy indices */ - -#define enter_domain_block _glp_mpl_enter_domain_block -int enter_domain_block -( MPL *mpl, - DOMAIN_BLOCK *block, /* not changed */ - TUPLE *tuple, /* not changed */ - void *info, void (*func)(MPL *mpl, void *info) -); -/* enter domain block */ - -#define eval_within_domain _glp_mpl_eval_within_domain -int eval_within_domain -( MPL *mpl, - DOMAIN *domain, /* not changed */ - TUPLE *tuple, /* not changed */ - void *info, void (*func)(MPL *mpl, void *info) -); -/* perform evaluation within domain scope */ - -#define loop_within_domain _glp_mpl_loop_within_domain -void loop_within_domain -( MPL *mpl, - DOMAIN *domain, /* not changed */ - void *info, int (*func)(MPL *mpl, void *info) -); -/* perform iterations within domain scope */ - -#define out_of_domain _glp_mpl_out_of_domain -void out_of_domain -( MPL *mpl, - char *name, /* not changed */ - TUPLE *tuple /* not changed */ -); -/* raise domain exception */ - -#define get_domain_tuple _glp_mpl_get_domain_tuple -TUPLE *get_domain_tuple -( MPL *mpl, - DOMAIN *domain /* not changed */ -); -/* obtain current n-tuple from domain */ - -#define clean_domain _glp_mpl_clean_domain -void clean_domain(MPL *mpl, DOMAIN *domain); -/* clean domain */ - -/**********************************************************************/ -/* * * MODEL SETS * * */ -/**********************************************************************/ - -struct SET -{ /* model set */ - char *name; - /* symbolic name; cannot be NULL */ - char *alias; - /* alias; NULL means alias is not specified */ - int dim; /* aka arity */ - /* dimension (number of subscripts); dim = 0 means 0-dimensional - (unsubscripted) set, dim > 0 means set of sets */ - DOMAIN *domain; - /* subscript domain; NULL for 0-dimensional set */ - int dimen; - /* dimension of n-tuples, which members of this set consist of - (note that the model set itself is an array of elemental sets, - which are its members; so, don't confuse this dimension with - dimension of the model set); always non-zero */ - WITHIN *within; - /* list of supersets, which restrict each member of the set to be - in every superset from this list; this list can be empty */ - CODE *assign; - /* pseudo-code for computing assigned value; can be NULL */ - CODE *option; - /* pseudo-code for computing default value; can be NULL */ - GADGET *gadget; - /* plain set used to initialize the array of sets; can be NULL */ - int data; - /* data status flag: - 0 - no data are provided in the data section - 1 - data are provided, but not checked yet - 2 - data are provided and have been checked */ - ARRAY *array; - /* array of members, which are assigned elemental sets */ -}; - -struct WITHIN -{ /* restricting superset list entry */ - CODE *code; - /* pseudo-code for computing the superset; cannot be NULL */ - WITHIN *next; - /* the next entry for the same set or parameter */ -}; - -struct GADGET -{ /* plain set used to initialize the array of sets with data */ - SET *set; - /* pointer to plain set; cannot be NULL */ - int ind[20]; /* ind[dim+dimen]; */ - /* permutation of integers 1, 2, ..., dim+dimen */ -}; - -#define check_elem_set _glp_mpl_check_elem_set -void check_elem_set -( MPL *mpl, - SET *set, /* not changed */ - TUPLE *tuple, /* not changed */ - ELEMSET *refer /* not changed */ -); -/* check elemental set assigned to set member */ - -#define take_member_set _glp_mpl_take_member_set -ELEMSET *take_member_set /* returns reference, not value */ -( MPL *mpl, - SET *set, /* not changed */ - TUPLE *tuple /* not changed */ -); -/* obtain elemental set assigned to set member */ - -#define eval_member_set _glp_mpl_eval_member_set -ELEMSET *eval_member_set /* returns reference, not value */ -( MPL *mpl, - SET *set, /* not changed */ - TUPLE *tuple /* not changed */ -); -/* evaluate elemental set assigned to set member */ - -#define eval_whole_set _glp_mpl_eval_whole_set -void eval_whole_set(MPL *mpl, SET *set); -/* evaluate model set over entire domain */ - -#define clean_set _glp_mpl_clean_set -void clean_set(MPL *mpl, SET *set); -/* clean model set */ - -/**********************************************************************/ -/* * * MODEL PARAMETERS * * */ -/**********************************************************************/ - -struct PARAMETER -{ /* model parameter */ - char *name; - /* symbolic name; cannot be NULL */ - char *alias; - /* alias; NULL means alias is not specified */ - int dim; /* aka arity */ - /* dimension (number of subscripts); dim = 0 means 0-dimensional - (unsubscripted) parameter */ - DOMAIN *domain; - /* subscript domain; NULL for 0-dimensional parameter */ - int type; - /* parameter type: - A_NUMERIC - numeric - A_INTEGER - integer - A_BINARY - binary - A_SYMBOLIC - symbolic */ - CONDITION *cond; - /* list of conditions, which restrict each parameter member to - satisfy to every condition from this list; this list is used - only for numeric parameters and can be empty */ - WITHIN *in; - /* list of supersets, which restrict each parameter member to be - in every superset from this list; this list is used only for - symbolic parameters and can be empty */ - CODE *assign; - /* pseudo-code for computing assigned value; can be NULL */ - CODE *option; - /* pseudo-code for computing default value; can be NULL */ - int data; - /* data status flag: - 0 - no data are provided in the data section - 1 - data are provided, but not checked yet - 2 - data are provided and have been checked */ - SYMBOL *defval; - /* default value provided in the data section; can be NULL */ - ARRAY *array; - /* array of members, which are assigned numbers or symbols */ -}; - -struct CONDITION -{ /* restricting condition list entry */ - int rho; - /* flag that specifies the form of the condition: - O_LT - less than - O_LE - less than or equal to - O_EQ - equal to - O_GE - greater than or equal to - O_GT - greater than - O_NE - not equal to */ - CODE *code; - /* pseudo-code for computing the reference value */ - CONDITION *next; - /* the next entry for the same parameter */ -}; - -#define check_value_num _glp_mpl_check_value_num -void check_value_num -( MPL *mpl, - PARAMETER *par, /* not changed */ - TUPLE *tuple, /* not changed */ - double value -); -/* check numeric value assigned to parameter member */ - -#define take_member_num _glp_mpl_take_member_num -double take_member_num -( MPL *mpl, - PARAMETER *par, /* not changed */ - TUPLE *tuple /* not changed */ -); -/* obtain numeric value assigned to parameter member */ - -#define eval_member_num _glp_mpl_eval_member_num -double eval_member_num -( MPL *mpl, - PARAMETER *par, /* not changed */ - TUPLE *tuple /* not changed */ -); -/* evaluate numeric value assigned to parameter member */ - -#define check_value_sym _glp_mpl_check_value_sym -void check_value_sym -( MPL *mpl, - PARAMETER *par, /* not changed */ - TUPLE *tuple, /* not changed */ - SYMBOL *value /* not changed */ -); -/* check symbolic value assigned to parameter member */ - -#define take_member_sym _glp_mpl_take_member_sym -SYMBOL *take_member_sym /* returns value, not reference */ -( MPL *mpl, - PARAMETER *par, /* not changed */ - TUPLE *tuple /* not changed */ -); -/* obtain symbolic value assigned to parameter member */ - -#define eval_member_sym _glp_mpl_eval_member_sym -SYMBOL *eval_member_sym /* returns value, not reference */ -( MPL *mpl, - PARAMETER *par, /* not changed */ - TUPLE *tuple /* not changed */ -); -/* evaluate symbolic value assigned to parameter member */ - -#define eval_whole_par _glp_mpl_eval_whole_par -void eval_whole_par(MPL *mpl, PARAMETER *par); -/* evaluate model parameter over entire domain */ - -#define clean_parameter _glp_mpl_clean_parameter -void clean_parameter(MPL *mpl, PARAMETER *par); -/* clean model parameter */ - -/**********************************************************************/ -/* * * MODEL VARIABLES * * */ -/**********************************************************************/ - -struct VARIABLE -{ /* model variable */ - char *name; - /* symbolic name; cannot be NULL */ - char *alias; - /* alias; NULL means alias is not specified */ - int dim; /* aka arity */ - /* dimension (number of subscripts); dim = 0 means 0-dimensional - (unsubscripted) variable */ - DOMAIN *domain; - /* subscript domain; NULL for 0-dimensional variable */ - int type; - /* variable type: - A_NUMERIC - continuous - A_INTEGER - integer - A_BINARY - binary */ - CODE *lbnd; - /* pseudo-code for computing lower bound; NULL means lower bound - is not specified */ - CODE *ubnd; - /* pseudo-code for computing upper bound; NULL means upper bound - is not specified */ - /* if both the pointers lbnd and ubnd refer to the same code, the - variable is fixed at the corresponding value */ - ARRAY *array; - /* array of members, which are assigned elemental variables */ -}; - -#define take_member_var _glp_mpl_take_member_var -ELEMVAR *take_member_var /* returns reference */ -( MPL *mpl, - VARIABLE *var, /* not changed */ - TUPLE *tuple /* not changed */ -); -/* obtain reference to elemental variable */ - -#define eval_member_var _glp_mpl_eval_member_var -ELEMVAR *eval_member_var /* returns reference */ -( MPL *mpl, - VARIABLE *var, /* not changed */ - TUPLE *tuple /* not changed */ -); -/* evaluate reference to elemental variable */ - -#define eval_whole_var _glp_mpl_eval_whole_var -void eval_whole_var(MPL *mpl, VARIABLE *var); -/* evaluate model variable over entire domain */ - -#define clean_variable _glp_mpl_clean_variable -void clean_variable(MPL *mpl, VARIABLE *var); -/* clean model variable */ - -/**********************************************************************/ -/* * * MODEL CONSTRAINTS AND OBJECTIVES * * */ -/**********************************************************************/ - -struct CONSTRAINT -{ /* model constraint or objective */ - char *name; - /* symbolic name; cannot be NULL */ - char *alias; - /* alias; NULL means alias is not specified */ - int dim; /* aka arity */ - /* dimension (number of subscripts); dim = 0 means 0-dimensional - (unsubscripted) constraint */ - DOMAIN *domain; - /* subscript domain; NULL for 0-dimensional constraint */ - int type; - /* constraint type: - A_CONSTRAINT - constraint - A_MINIMIZE - objective (minimization) - A_MAXIMIZE - objective (maximization) */ - CODE *code; - /* pseudo-code for computing main linear form; cannot be NULL */ - CODE *lbnd; - /* pseudo-code for computing lower bound; NULL means lower bound - is not specified */ - CODE *ubnd; - /* pseudo-code for computing upper bound; NULL means upper bound - is not specified */ - /* if both the pointers lbnd and ubnd refer to the same code, the - constraint has the form of equation */ - ARRAY *array; - /* array of members, which are assigned elemental constraints */ -}; - -#define take_member_con _glp_mpl_take_member_con -ELEMCON *take_member_con /* returns reference */ -( MPL *mpl, - CONSTRAINT *con, /* not changed */ - TUPLE *tuple /* not changed */ -); -/* obtain reference to elemental constraint */ - -#define eval_member_con _glp_mpl_eval_member_con -ELEMCON *eval_member_con /* returns reference */ -( MPL *mpl, - CONSTRAINT *con, /* not changed */ - TUPLE *tuple /* not changed */ -); -/* evaluate reference to elemental constraint */ - -#define eval_whole_con _glp_mpl_eval_whole_con -void eval_whole_con(MPL *mpl, CONSTRAINT *con); -/* evaluate model constraint over entire domain */ - -#define clean_constraint _glp_mpl_clean_constraint -void clean_constraint(MPL *mpl, CONSTRAINT *con); -/* clean model constraint */ - -/**********************************************************************/ -/* * * DATA TABLES * * */ -/**********************************************************************/ - -struct TABLE -{ /* data table */ - char *name; - /* symbolic name; cannot be NULL */ - char *alias; - /* alias; NULL means alias is not specified */ - int type; - /* table type: - A_INPUT - input table - A_OUTPUT - output table */ - TABARG *arg; - /* argument list; cannot be empty */ - union - { struct - { SET *set; - /* input set; NULL means the set is not specified */ - TABFLD *fld; - /* field list; cannot be empty */ - TABIN *list; - /* input list; can be empty */ - } in; - struct - { DOMAIN *domain; - /* subscript domain; cannot be NULL */ - TABOUT *list; - /* output list; cannot be empty */ - } out; - } u; -}; - -struct TABARG -{ /* table argument list entry */ - CODE *code; - /* pseudo-code for computing the argument */ - TABARG *next; - /* next entry for the same table */ -}; - -struct TABFLD -{ /* table field list entry */ - char *name; - /* field name; cannot be NULL */ - TABFLD *next; - /* next entry for the same table */ -}; - -struct TABIN -{ /* table input list entry */ - PARAMETER *par; - /* parameter to be read; cannot be NULL */ - char *name; - /* column name; cannot be NULL */ - TABIN *next; - /* next entry for the same table */ -}; - -struct TABOUT -{ /* table output list entry */ - CODE *code; - /* pseudo-code for computing the value to be written */ - char *name; - /* column name; cannot be NULL */ - TABOUT *next; - /* next entry for the same table */ -}; - -struct TABDCA -{ /* table driver communication area */ - int id; - /* driver identifier (set by mpl_tab_drv_open) */ - void *link; - /* driver link pointer (set by mpl_tab_drv_open) */ - int na; - /* number of arguments */ - char **arg; /* char *arg[1+ns]; */ - /* arg[k], 1 <= k <= ns, is pointer to k-th argument */ - int nf; - /* number of fields */ - char **name; /* char *name[1+nc]; */ - /* name[k], 1 <= k <= nc, is name of k-th field */ - int *type; /* int type[1+nc]; */ - /* type[k], 1 <= k <= nc, is type of k-th field: - '?' - value not assigned - 'N' - number - 'S' - character string */ - double *num; /* double num[1+nc]; */ - /* num[k], 1 <= k <= nc, is numeric value of k-th field */ - char **str; - /* str[k], 1 <= k <= nc, is string value of k-th field */ -}; - -#define mpl_tab_num_args _glp_mpl_tab_num_args -int mpl_tab_num_args(TABDCA *dca); - -#define mpl_tab_get_arg _glp_mpl_tab_get_arg -const char *mpl_tab_get_arg(TABDCA *dca, int k); - -#define mpl_tab_num_flds _glp_mpl_tab_num_flds -int mpl_tab_num_flds(TABDCA *dca); - -#define mpl_tab_get_name _glp_mpl_tab_get_name -const char *mpl_tab_get_name(TABDCA *dca, int k); - -#define mpl_tab_get_type _glp_mpl_tab_get_type -int mpl_tab_get_type(TABDCA *dca, int k); - -#define mpl_tab_get_num _glp_mpl_tab_get_num -double mpl_tab_get_num(TABDCA *dca, int k); - -#define mpl_tab_get_str _glp_mpl_tab_get_str -const char *mpl_tab_get_str(TABDCA *dca, int k); - -#define mpl_tab_set_num _glp_mpl_tab_set_num -void mpl_tab_set_num(TABDCA *dca, int k, double num); - -#define mpl_tab_set_str _glp_mpl_tab_set_str -void mpl_tab_set_str(TABDCA *dca, int k, const char *str); - -#define mpl_tab_drv_open _glp_mpl_tab_drv_open -void mpl_tab_drv_open(MPL *mpl, int mode); - -#define mpl_tab_drv_read _glp_mpl_tab_drv_read -int mpl_tab_drv_read(MPL *mpl); - -#define mpl_tab_drv_write _glp_mpl_tab_drv_write -void mpl_tab_drv_write(MPL *mpl); - -#define mpl_tab_drv_close _glp_mpl_tab_drv_close -void mpl_tab_drv_close(MPL *mpl); - -/**********************************************************************/ -/* * * PSEUDO-CODE * * */ -/**********************************************************************/ - -union OPERANDS -{ /* operands that participate in pseudo-code operation (choice of - particular operands depends on the operation code) */ - /*--------------------------------------------------------------*/ - double num; /* O_NUMBER */ - /* floaing-point number to be taken */ - /*--------------------------------------------------------------*/ - char *str; /* O_STRING */ - /* character string to be taken */ - /*--------------------------------------------------------------*/ - struct /* O_INDEX */ - { DOMAIN_SLOT *slot; - /* domain slot, which contains dummy index to be taken */ - CODE *next; - /* the next pseudo-code with op = O_INDEX, which refers to the - same slot as this one; pointer to the beginning of this list - is stored in the corresponding domain slot */ - } index; - /*--------------------------------------------------------------*/ - struct /* O_MEMNUM, O_MEMSYM */ - { PARAMETER *par; - /* model parameter, which contains member to be taken */ - ARG_LIST *list; - /* list of subscripts; NULL for 0-dimensional parameter */ - } par; - /*--------------------------------------------------------------*/ - struct /* O_MEMSET */ - { SET *set; - /* model set, which contains member to be taken */ - ARG_LIST *list; - /* list of subscripts; NULL for 0-dimensional set */ - } set; - /*--------------------------------------------------------------*/ - struct /* O_MEMVAR */ - { VARIABLE *var; - /* model variable, which contains member to be taken */ - ARG_LIST *list; - /* list of subscripts; NULL for 0-dimensional variable */ -#if 1 /* 15/V-2010 */ - int suff; - /* suffix specified: */ -#define DOT_NONE 0x00 /* none (means variable itself) */ -#define DOT_LB 0x01 /* .lb (lower bound) */ -#define DOT_UB 0x02 /* .ub (upper bound) */ -#define DOT_STATUS 0x03 /* .status (status) */ -#define DOT_VAL 0x04 /* .val (primal value) */ -#define DOT_DUAL 0x05 /* .dual (dual value) */ -#endif - } var; -#if 1 /* 15/V-2010 */ - /*--------------------------------------------------------------*/ - struct /* O_MEMCON */ - { CONSTRAINT *con; - /* model constraint, which contains member to be taken */ - ARG_LIST *list; - /* list of subscripys; NULL for 0-dimensional constraint */ - int suff; - /* suffix specified (see O_MEMVAR above) */ - } con; -#endif - /*--------------------------------------------------------------*/ - ARG_LIST *list; /* O_TUPLE, O_MAKE, n-ary operations */ - /* list of operands */ - /*--------------------------------------------------------------*/ - DOMAIN_BLOCK *slice; /* O_SLICE */ - /* domain block, which specifies slice (i.e. n-tuple that contains - free dummy indices); this operation is never evaluated */ - /*--------------------------------------------------------------*/ - struct /* unary, binary, ternary operations */ - { CODE *x; - /* pseudo-code for computing first operand */ - CODE *y; - /* pseudo-code for computing second operand */ - CODE *z; - /* pseudo-code for computing third operand */ - } arg; - /*--------------------------------------------------------------*/ - struct /* iterated operations */ - { DOMAIN *domain; - /* domain, over which the operation is performed */ - CODE *x; - /* pseudo-code for computing "integrand" */ - } loop; - /*--------------------------------------------------------------*/ -}; - -struct ARG_LIST -{ /* operands list entry */ - CODE *x; - /* pseudo-code for computing operand */ - ARG_LIST *next; - /* the next operand of the same operation */ -}; - -struct CODE -{ /* pseudo-code (internal form of expressions) */ - int op; - /* operation code: */ -#define O_NUMBER 301 /* take floating-point number */ -#define O_STRING 302 /* take character string */ -#define O_INDEX 303 /* take dummy index */ -#define O_MEMNUM 304 /* take member of numeric parameter */ -#define O_MEMSYM 305 /* take member of symbolic parameter */ -#define O_MEMSET 306 /* take member of set */ -#define O_MEMVAR 307 /* take member of variable */ -#define O_MEMCON 308 /* take member of constraint */ -#define O_TUPLE 309 /* make n-tuple */ -#define O_MAKE 310 /* make elemental set of n-tuples */ -#define O_SLICE 311 /* define domain block (dummy op) */ - /* 0-ary operations --------------------*/ -#define O_IRAND224 312 /* pseudo-random in [0, 2^24-1] */ -#define O_UNIFORM01 313 /* pseudo-random in [0, 1) */ -#define O_NORMAL01 314 /* gaussian random, mu = 0, sigma = 1 */ -#define O_GMTIME 315 /* current calendar time (UTC) */ - /* unary operations --------------------*/ -#define O_CVTNUM 316 /* conversion to numeric */ -#define O_CVTSYM 317 /* conversion to symbolic */ -#define O_CVTLOG 318 /* conversion to logical */ -#define O_CVTTUP 319 /* conversion to 1-tuple */ -#define O_CVTLFM 320 /* conversion to linear form */ -#define O_PLUS 321 /* unary plus */ -#define O_MINUS 322 /* unary minus */ -#define O_NOT 323 /* negation (logical "not") */ -#define O_ABS 324 /* absolute value */ -#define O_CEIL 325 /* round upward ("ceiling of x") */ -#define O_FLOOR 326 /* round downward ("floor of x") */ -#define O_EXP 327 /* base-e exponential */ -#define O_LOG 328 /* natural logarithm */ -#define O_LOG10 329 /* common (decimal) logarithm */ -#define O_SQRT 330 /* square root */ -#define O_SIN 331 /* trigonometric sine */ -#define O_COS 332 /* trigonometric cosine */ -#define O_ATAN 333 /* trigonometric arctangent */ -#define O_ROUND 334 /* round to nearest integer */ -#define O_TRUNC 335 /* truncate to nearest integer */ -#define O_CARD 336 /* cardinality of set */ -#define O_LENGTH 337 /* length of symbolic value */ - /* binary operations -------------------*/ -#define O_ADD 338 /* addition */ -#define O_SUB 339 /* subtraction */ -#define O_LESS 340 /* non-negative subtraction */ -#define O_MUL 341 /* multiplication */ -#define O_DIV 342 /* division */ -#define O_IDIV 343 /* quotient of exact division */ -#define O_MOD 344 /* remainder of exact division */ -#define O_POWER 345 /* exponentiation (raise to power) */ -#define O_ATAN2 346 /* trigonometric arctangent */ -#define O_ROUND2 347 /* round to n fractional digits */ -#define O_TRUNC2 348 /* truncate to n fractional digits */ -#define O_UNIFORM 349 /* pseudo-random in [a, b) */ -#define O_NORMAL 350 /* gaussian random, given mu and sigma */ -#define O_CONCAT 351 /* concatenation */ -#define O_LT 352 /* comparison on 'less than' */ -#define O_LE 353 /* comparison on 'not greater than' */ -#define O_EQ 354 /* comparison on 'equal to' */ -#define O_GE 355 /* comparison on 'not less than' */ -#define O_GT 356 /* comparison on 'greater than' */ -#define O_NE 357 /* comparison on 'not equal to' */ -#define O_AND 358 /* conjunction (logical "and") */ -#define O_OR 359 /* disjunction (logical "or") */ -#define O_UNION 360 /* union */ -#define O_DIFF 361 /* difference */ -#define O_SYMDIFF 362 /* symmetric difference */ -#define O_INTER 363 /* intersection */ -#define O_CROSS 364 /* cross (Cartesian) product */ -#define O_IN 365 /* test on 'x in Y' */ -#define O_NOTIN 366 /* test on 'x not in Y' */ -#define O_WITHIN 367 /* test on 'X within Y' */ -#define O_NOTWITHIN 368 /* test on 'X not within Y' */ -#define O_SUBSTR 369 /* substring */ -#define O_STR2TIME 370 /* convert string to time */ -#define O_TIME2STR 371 /* convert time to string */ - /* ternary operations ------------------*/ -#define O_DOTS 372 /* build "arithmetic" set */ -#define O_FORK 373 /* if-then-else */ -#define O_SUBSTR3 374 /* substring */ - /* n-ary operations --------------------*/ -#define O_MIN 375 /* minimal value (n-ary) */ -#define O_MAX 376 /* maximal value (n-ary) */ - /* iterated operations -----------------*/ -#define O_SUM 377 /* summation */ -#define O_PROD 378 /* multiplication */ -#define O_MINIMUM 379 /* minimum */ -#define O_MAXIMUM 380 /* maximum */ -#define O_FORALL 381 /* conjunction (A-quantification) */ -#define O_EXISTS 382 /* disjunction (E-quantification) */ -#define O_SETOF 383 /* compute elemental set */ -#define O_BUILD 384 /* build elemental set */ - OPERANDS arg; - /* operands that participate in the operation */ - int type; - /* type of the resultant value: - A_NUMERIC - numeric - A_SYMBOLIC - symbolic - A_LOGICAL - logical - A_TUPLE - n-tuple - A_ELEMSET - elemental set - A_FORMULA - linear form */ - int dim; - /* dimension of the resultant value; for A_TUPLE and A_ELEMSET it - is the dimension of the corresponding n-tuple(s) and cannot be - zero; for other resultant types it is always zero */ - CODE *up; - /* parent pseudo-code, which refers to this pseudo-code as to its - operand; NULL means this pseudo-code has no parent and defines - an expression, which is not contained in another expression */ - int vflag; - /* volatile flag; being set this flag means that this operation - has a side effect; for primary expressions this flag is set - directly by corresponding parsing routines (for example, if - primary expression is a reference to a function that generates - pseudo-random numbers); in other cases this flag is inherited - from operands */ - int valid; - /* if this flag is set, the resultant value, which is a temporary - result of evaluating this operation on particular values of - operands, is valid; if this flag is clear, the resultant value - doesn't exist and therefore not valid; having been evaluated - the resultant value is stored here and not destroyed until the - dummy indices, which this value depends on, have been changed - (and if it doesn't depend on dummy indices at all, it is never - destroyed); thus, if the resultant value is valid, evaluating - routine can immediately take its copy not computing the result - from scratch; this mechanism is similar to moving invariants - out of loops and allows improving efficiency at the expense of - some extra memory needed to keep temporary results */ - /* however, if the volatile flag (see above) is set, even if the - resultant value is valid, evaluating routine computes it as if - it were not valid, i.e. caching is not used in this case */ - VALUE value; - /* resultant value in generic format */ -}; - -#define eval_numeric _glp_mpl_eval_numeric -double eval_numeric(MPL *mpl, CODE *code); -/* evaluate pseudo-code to determine numeric value */ - -#define eval_symbolic _glp_mpl_eval_symbolic -SYMBOL *eval_symbolic(MPL *mpl, CODE *code); -/* evaluate pseudo-code to determine symbolic value */ - -#define eval_logical _glp_mpl_eval_logical -int eval_logical(MPL *mpl, CODE *code); -/* evaluate pseudo-code to determine logical value */ - -#define eval_tuple _glp_mpl_eval_tuple -TUPLE *eval_tuple(MPL *mpl, CODE *code); -/* evaluate pseudo-code to construct n-tuple */ - -#define eval_elemset _glp_mpl_eval_elemset -ELEMSET *eval_elemset(MPL *mpl, CODE *code); -/* evaluate pseudo-code to construct elemental set */ - -#define is_member _glp_mpl_is_member -int is_member(MPL *mpl, CODE *code, TUPLE *tuple); -/* check if n-tuple is in set specified by pseudo-code */ - -#define eval_formula _glp_mpl_eval_formula -FORMULA *eval_formula(MPL *mpl, CODE *code); -/* evaluate pseudo-code to construct linear form */ - -#define clean_code _glp_mpl_clean_code -void clean_code(MPL *mpl, CODE *code); -/* clean pseudo-code */ - -/**********************************************************************/ -/* * * MODEL STATEMENTS * * */ -/**********************************************************************/ - -struct CHECK -{ /* check statement */ - DOMAIN *domain; - /* subscript domain; NULL means domain is not used */ - CODE *code; - /* code for computing the predicate to be checked */ -}; - -struct DISPLAY -{ /* display statement */ - DOMAIN *domain; - /* subscript domain; NULL means domain is not used */ - DISPLAY1 *list; - /* display list; cannot be empty */ -}; - -struct DISPLAY1 -{ /* display list entry */ - int type; - /* item type: - A_INDEX - dummy index - A_SET - model set - A_PARAMETER - model parameter - A_VARIABLE - model variable - A_CONSTRAINT - model constraint/objective - A_EXPRESSION - expression */ - union - { DOMAIN_SLOT *slot; - SET *set; - PARAMETER *par; - VARIABLE *var; - CONSTRAINT *con; - CODE *code; - } u; - /* item to be displayed */ -#if 0 /* 15/V-2010 */ - ARG_LIST *list; - /* optional subscript list (for constraint/objective only) */ -#endif - DISPLAY1 *next; - /* the next entry for the same statement */ -}; - -struct PRINTF -{ /* printf statement */ - DOMAIN *domain; - /* subscript domain; NULL means domain is not used */ - CODE *fmt; - /* pseudo-code for computing format string */ - PRINTF1 *list; - /* printf list; can be empty */ - CODE *fname; - /* pseudo-code for computing filename to redirect the output; - NULL means the output goes to stdout */ - int app; - /* if this flag is set, the output is appended */ -}; - -struct PRINTF1 -{ /* printf list entry */ - CODE *code; - /* pseudo-code for computing value to be printed */ - PRINTF1 *next; - /* the next entry for the same statement */ -}; - -struct FOR -{ /* for statement */ - DOMAIN *domain; - /* subscript domain; cannot be NULL */ - STATEMENT *list; - /* linked list of model statements within this for statement in - the original order */ -}; - -struct STATEMENT -{ /* model statement */ - int line; - /* number of source text line, where statement begins */ - int type; - /* statement type: - A_SET - set statement - A_PARAMETER - parameter statement - A_VARIABLE - variable statement - A_CONSTRAINT - constraint/objective statement - A_TABLE - table statement - A_SOLVE - solve statement - A_CHECK - check statement - A_DISPLAY - display statement - A_PRINTF - printf statement - A_FOR - for statement */ - union - { SET *set; - PARAMETER *par; - VARIABLE *var; - CONSTRAINT *con; - TABLE *tab; - void *slv; /* currently not used (set to NULL) */ - CHECK *chk; - DISPLAY *dpy; - PRINTF *prt; - FOR *fur; - } u; - /* specific part of statement */ - STATEMENT *next; - /* the next statement; in this list statements follow in the same - order as they appear in the model section */ -}; - -#define execute_table _glp_mpl_execute_table -void execute_table(MPL *mpl, TABLE *tab); -/* execute table statement */ - -#define free_dca _glp_mpl_free_dca -void free_dca(MPL *mpl); -/* free table driver communucation area */ - -#define clean_table _glp_mpl_clean_table -void clean_table(MPL *mpl, TABLE *tab); -/* clean table statement */ - -#define execute_check _glp_mpl_execute_check -void execute_check(MPL *mpl, CHECK *chk); -/* execute check statement */ - -#define clean_check _glp_mpl_clean_check -void clean_check(MPL *mpl, CHECK *chk); -/* clean check statement */ - -#define execute_display _glp_mpl_execute_display -void execute_display(MPL *mpl, DISPLAY *dpy); -/* execute display statement */ - -#define clean_display _glp_mpl_clean_display -void clean_display(MPL *mpl, DISPLAY *dpy); -/* clean display statement */ - -#define execute_printf _glp_mpl_execute_printf -void execute_printf(MPL *mpl, PRINTF *prt); -/* execute printf statement */ - -#define clean_printf _glp_mpl_clean_printf -void clean_printf(MPL *mpl, PRINTF *prt); -/* clean printf statement */ - -#define execute_for _glp_mpl_execute_for -void execute_for(MPL *mpl, FOR *fur); -/* execute for statement */ - -#define clean_for _glp_mpl_clean_for -void clean_for(MPL *mpl, FOR *fur); -/* clean for statement */ - -#define execute_statement _glp_mpl_execute_statement -void execute_statement(MPL *mpl, STATEMENT *stmt); -/* execute specified model statement */ - -#define clean_statement _glp_mpl_clean_statement -void clean_statement(MPL *mpl, STATEMENT *stmt); -/* clean specified model statement */ - -/**********************************************************************/ -/* * * GENERATING AND POSTSOLVING MODEL * * */ -/**********************************************************************/ - -#define alloc_content _glp_mpl_alloc_content -void alloc_content(MPL *mpl); -/* allocate content arrays for all model objects */ - -#define generate_model _glp_mpl_generate_model -void generate_model(MPL *mpl); -/* generate model */ - -#define build_problem _glp_mpl_build_problem -void build_problem(MPL *mpl); -/* build problem instance */ - -#define postsolve_model _glp_mpl_postsolve_model -void postsolve_model(MPL *mpl); -/* postsolve model */ - -#define clean_model _glp_mpl_clean_model -void clean_model(MPL *mpl); -/* clean model content */ - -/**********************************************************************/ -/* * * INPUT/OUTPUT * * */ -/**********************************************************************/ - -#define open_input _glp_mpl_open_input -void open_input(MPL *mpl, char *file); -/* open input text file */ - -#define read_char _glp_mpl_read_char -int read_char(MPL *mpl); -/* read next character from input text file */ - -#define close_input _glp_mpl_close_input -void close_input(MPL *mpl); -/* close input text file */ - -#define open_output _glp_mpl_open_output -void open_output(MPL *mpl, char *file); -/* open output text file */ - -#define write_char _glp_mpl_write_char -void write_char(MPL *mpl, int c); -/* write next character to output text file */ - -#define write_text _glp_mpl_write_text -void write_text(MPL *mpl, char *fmt, ...); -/* format and write text to output text file */ - -#define flush_output _glp_mpl_flush_output -void flush_output(MPL *mpl); -/* finalize writing data to output text file */ - -/**********************************************************************/ -/* * * SOLVER INTERFACE * * */ -/**********************************************************************/ - -#define MPL_FR 401 /* free (unbounded) */ -#define MPL_LO 402 /* lower bound */ -#define MPL_UP 403 /* upper bound */ -#define MPL_DB 404 /* both lower and upper bounds */ -#define MPL_FX 405 /* fixed */ - -#define MPL_ST 411 /* constraint */ -#define MPL_MIN 412 /* objective (minimization) */ -#define MPL_MAX 413 /* objective (maximization) */ - -#define MPL_NUM 421 /* continuous */ -#define MPL_INT 422 /* integer */ -#define MPL_BIN 423 /* binary */ - -#define error _glp_mpl_error -void error(MPL *mpl, char *fmt, ...); -/* print error message and terminate model processing */ - -#define warning _glp_mpl_warning -void warning(MPL *mpl, char *fmt, ...); -/* print warning message and continue model processing */ - -#define mpl_initialize _glp_mpl_initialize -MPL *mpl_initialize(void); -/* create and initialize translator database */ - -#define mpl_read_model _glp_mpl_read_model -int mpl_read_model(MPL *mpl, char *file, int skip_data); -/* read model section and optional data section */ - -#define mpl_read_data _glp_mpl_read_data -int mpl_read_data(MPL *mpl, char *file); -/* read data section */ - -#define mpl_generate _glp_mpl_generate -int mpl_generate(MPL *mpl, char *file); -/* generate model */ - -#define mpl_get_prob_name _glp_mpl_get_prob_name -char *mpl_get_prob_name(MPL *mpl); -/* obtain problem (model) name */ - -#define mpl_get_num_rows _glp_mpl_get_num_rows -int mpl_get_num_rows(MPL *mpl); -/* determine number of rows */ - -#define mpl_get_num_cols _glp_mpl_get_num_cols -int mpl_get_num_cols(MPL *mpl); -/* determine number of columns */ - -#define mpl_get_row_name _glp_mpl_get_row_name -char *mpl_get_row_name(MPL *mpl, int i); -/* obtain row name */ - -#define mpl_get_row_kind _glp_mpl_get_row_kind -int mpl_get_row_kind(MPL *mpl, int i); -/* determine row kind */ - -#define mpl_get_row_bnds _glp_mpl_get_row_bnds -int mpl_get_row_bnds(MPL *mpl, int i, double *lb, double *ub); -/* obtain row bounds */ - -#define mpl_get_mat_row _glp_mpl_get_mat_row -int mpl_get_mat_row(MPL *mpl, int i, int ndx[], double val[]); -/* obtain row of the constraint matrix */ - -#define mpl_get_row_c0 _glp_mpl_get_row_c0 -double mpl_get_row_c0(MPL *mpl, int i); -/* obtain constant term of free row */ - -#define mpl_get_col_name _glp_mpl_get_col_name -char *mpl_get_col_name(MPL *mpl, int j); -/* obtain column name */ - -#define mpl_get_col_kind _glp_mpl_get_col_kind -int mpl_get_col_kind(MPL *mpl, int j); -/* determine column kind */ - -#define mpl_get_col_bnds _glp_mpl_get_col_bnds -int mpl_get_col_bnds(MPL *mpl, int j, double *lb, double *ub); -/* obtain column bounds */ - -#define mpl_has_solve_stmt _glp_mpl_has_solve_stmt -int mpl_has_solve_stmt(MPL *mpl); -/* check if model has solve statement */ - -#if 1 /* 15/V-2010 */ -#define mpl_put_row_soln _glp_mpl_put_row_soln -void mpl_put_row_soln(MPL *mpl, int i, int stat, double prim, - double dual); -/* store row (constraint/objective) solution components */ -#endif - -#if 1 /* 15/V-2010 */ -#define mpl_put_col_soln _glp_mpl_put_col_soln -void mpl_put_col_soln(MPL *mpl, int j, int stat, double prim, - double dual); -/* store column (variable) solution components */ -#endif - -#if 0 /* 15/V-2010 */ -#define mpl_put_col_value _glp_mpl_put_col_value -void mpl_put_col_value(MPL *mpl, int j, double val); -/* store column value */ -#endif - -#define mpl_postsolve _glp_mpl_postsolve -int mpl_postsolve(MPL *mpl); -/* postsolve model */ - -#define mpl_terminate _glp_mpl_terminate -void mpl_terminate(MPL *mpl); -/* free all resources used by translator */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpmpl01.c b/resources/3rdparty/glpk-4.53/src/glpmpl01.c deleted file mode 100644 index db7af246b..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpmpl01.c +++ /dev/null @@ -1,4715 +0,0 @@ -/* glpmpl01.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "glpmpl.h" - -#define dmp_get_atomv dmp_get_atom - -/**********************************************************************/ -/* * * PROCESSING MODEL SECTION * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- enter_context - enter current token into context queue. --- --- This routine enters the current token into the context queue. */ - -void enter_context(MPL *mpl) -{ char *image, *s; - if (mpl->token == T_EOF) - image = "_|_"; - else if (mpl->token == T_STRING) - image = "'...'"; - else - image = mpl->image; - xassert(0 <= mpl->c_ptr && mpl->c_ptr < CONTEXT_SIZE); - mpl->context[mpl->c_ptr++] = ' '; - if (mpl->c_ptr == CONTEXT_SIZE) mpl->c_ptr = 0; - for (s = image; *s != '\0'; s++) - { mpl->context[mpl->c_ptr++] = *s; - if (mpl->c_ptr == CONTEXT_SIZE) mpl->c_ptr = 0; - } - return; -} - -/*---------------------------------------------------------------------- --- print_context - print current content of context queue. --- --- This routine prints current content of the context queue. */ - -void print_context(MPL *mpl) -{ int c; - while (mpl->c_ptr > 0) - { mpl->c_ptr--; - c = mpl->context[0]; - memmove(mpl->context, mpl->context+1, CONTEXT_SIZE-1); - mpl->context[CONTEXT_SIZE-1] = (char)c; - } - xprintf("Context: %s%.*s\n", mpl->context[0] == ' ' ? "" : "...", - CONTEXT_SIZE, mpl->context); - return; -} - -/*---------------------------------------------------------------------- --- get_char - scan next character from input text file. --- --- This routine scans a next ASCII character from the input text file. --- In case of end-of-file, the character is assigned EOF. */ - -void get_char(MPL *mpl) -{ int c; - if (mpl->c == EOF) goto done; - if (mpl->c == '\n') mpl->line++; - c = read_char(mpl); - if (c == EOF) - { if (mpl->c == '\n') - mpl->line--; - else - warning(mpl, "final NL missing before end of file"); - } - else if (c == '\n') - ; - else if (isspace(c)) - c = ' '; - else if (iscntrl(c)) - { enter_context(mpl); - error(mpl, "control character 0x%02X not allowed", c); - } - mpl->c = c; -done: return; -} - -/*---------------------------------------------------------------------- --- append_char - append character to current token. --- --- This routine appends the current character to the current token and --- then scans a next character. */ - -void append_char(MPL *mpl) -{ xassert(0 <= mpl->imlen && mpl->imlen <= MAX_LENGTH); - if (mpl->imlen == MAX_LENGTH) - { switch (mpl->token) - { case T_NAME: - enter_context(mpl); - error(mpl, "symbolic name %s... too long", mpl->image); - case T_SYMBOL: - enter_context(mpl); - error(mpl, "symbol %s... too long", mpl->image); - case T_NUMBER: - enter_context(mpl); - error(mpl, "numeric literal %s... too long", mpl->image); - case T_STRING: - enter_context(mpl); - error(mpl, "string literal too long"); - default: - xassert(mpl != mpl); - } - } - mpl->image[mpl->imlen++] = (char)mpl->c; - mpl->image[mpl->imlen] = '\0'; - get_char(mpl); - return; -} - -/*---------------------------------------------------------------------- --- get_token - scan next token from input text file. --- --- This routine scans a next token from the input text file using the --- standard finite automation technique. */ - -void get_token(MPL *mpl) -{ /* save the current token */ - mpl->b_token = mpl->token; - mpl->b_imlen = mpl->imlen; - strcpy(mpl->b_image, mpl->image); - mpl->b_value = mpl->value; - /* if the next token is already scanned, make it current */ - if (mpl->f_scan) - { mpl->f_scan = 0; - mpl->token = mpl->f_token; - mpl->imlen = mpl->f_imlen; - strcpy(mpl->image, mpl->f_image); - mpl->value = mpl->f_value; - goto done; - } -loop: /* nothing has been scanned so far */ - mpl->token = 0; - mpl->imlen = 0; - mpl->image[0] = '\0'; - mpl->value = 0.0; - /* skip any uninteresting characters */ - while (mpl->c == ' ' || mpl->c == '\n') get_char(mpl); - /* recognize and construct the token */ - if (mpl->c == EOF) - { /* end-of-file reached */ - mpl->token = T_EOF; - } - else if (mpl->c == '#') - { /* comment; skip anything until end-of-line */ - while (mpl->c != '\n' && mpl->c != EOF) get_char(mpl); - goto loop; - } - else if (!mpl->flag_d && (isalpha(mpl->c) || mpl->c == '_')) - { /* symbolic name or reserved keyword */ - mpl->token = T_NAME; - while (isalnum(mpl->c) || mpl->c == '_') append_char(mpl); - if (strcmp(mpl->image, "and") == 0) - mpl->token = T_AND; - else if (strcmp(mpl->image, "by") == 0) - mpl->token = T_BY; - else if (strcmp(mpl->image, "cross") == 0) - mpl->token = T_CROSS; - else if (strcmp(mpl->image, "diff") == 0) - mpl->token = T_DIFF; - else if (strcmp(mpl->image, "div") == 0) - mpl->token = T_DIV; - else if (strcmp(mpl->image, "else") == 0) - mpl->token = T_ELSE; - else if (strcmp(mpl->image, "if") == 0) - mpl->token = T_IF; - else if (strcmp(mpl->image, "in") == 0) - mpl->token = T_IN; -#if 1 /* 21/VII-2006 */ - else if (strcmp(mpl->image, "Infinity") == 0) - mpl->token = T_INFINITY; -#endif - else if (strcmp(mpl->image, "inter") == 0) - mpl->token = T_INTER; - else if (strcmp(mpl->image, "less") == 0) - mpl->token = T_LESS; - else if (strcmp(mpl->image, "mod") == 0) - mpl->token = T_MOD; - else if (strcmp(mpl->image, "not") == 0) - mpl->token = T_NOT; - else if (strcmp(mpl->image, "or") == 0) - mpl->token = T_OR; - else if (strcmp(mpl->image, "s") == 0 && mpl->c == '.') - { mpl->token = T_SPTP; - append_char(mpl); - if (mpl->c != 't') -sptp: { enter_context(mpl); - error(mpl, "keyword s.t. incomplete"); - } - append_char(mpl); - if (mpl->c != '.') goto sptp; - append_char(mpl); - } - else if (strcmp(mpl->image, "symdiff") == 0) - mpl->token = T_SYMDIFF; - else if (strcmp(mpl->image, "then") == 0) - mpl->token = T_THEN; - else if (strcmp(mpl->image, "union") == 0) - mpl->token = T_UNION; - else if (strcmp(mpl->image, "within") == 0) - mpl->token = T_WITHIN; - } - else if (!mpl->flag_d && isdigit(mpl->c)) - { /* numeric literal */ - mpl->token = T_NUMBER; - /* scan integer part */ - while (isdigit(mpl->c)) append_char(mpl); - /* scan optional fractional part */ - if (mpl->c == '.') - { append_char(mpl); - if (mpl->c == '.') - { /* hmm, it is not the fractional part, it is dots that - follow the integer part */ - mpl->imlen--; - mpl->image[mpl->imlen] = '\0'; - mpl->f_dots = 1; - goto conv; - } -frac: while (isdigit(mpl->c)) append_char(mpl); - } - /* scan optional decimal exponent */ - if (mpl->c == 'e' || mpl->c == 'E') - { append_char(mpl); - if (mpl->c == '+' || mpl->c == '-') append_char(mpl); - if (!isdigit(mpl->c)) - { enter_context(mpl); - error(mpl, "numeric literal %s incomplete", mpl->image); - } - while (isdigit(mpl->c)) append_char(mpl); - } - /* there must be no letter following the numeric literal */ - if (isalpha(mpl->c) || mpl->c == '_') - { enter_context(mpl); - error(mpl, "symbol %s%c... should be enclosed in quotes", - mpl->image, mpl->c); - } -conv: /* convert numeric literal to floating-point */ - if (str2num(mpl->image, &mpl->value)) -err: { enter_context(mpl); - error(mpl, "cannot convert numeric literal %s to floating-p" - "oint number", mpl->image); - } - } - else if (mpl->c == '\'' || mpl->c == '"') - { /* character string */ - int quote = mpl->c; - mpl->token = T_STRING; - get_char(mpl); - for (;;) - { if (mpl->c == '\n' || mpl->c == EOF) - { enter_context(mpl); - error(mpl, "unexpected end of line; string literal incom" - "plete"); - } - if (mpl->c == quote) - { get_char(mpl); - if (mpl->c != quote) break; - } - append_char(mpl); - } - } - else if (!mpl->flag_d && mpl->c == '+') - mpl->token = T_PLUS, append_char(mpl); - else if (!mpl->flag_d && mpl->c == '-') - mpl->token = T_MINUS, append_char(mpl); - else if (mpl->c == '*') - { mpl->token = T_ASTERISK, append_char(mpl); - if (mpl->c == '*') - mpl->token = T_POWER, append_char(mpl); - } - else if (mpl->c == '/') - { mpl->token = T_SLASH, append_char(mpl); - if (mpl->c == '*') - { /* comment sequence */ - get_char(mpl); - for (;;) - { if (mpl->c == EOF) - { /* do not call enter_context at this point */ - error(mpl, "unexpected end of file; comment sequence " - "incomplete"); - } - else if (mpl->c == '*') - { get_char(mpl); - if (mpl->c == '/') break; - } - else - get_char(mpl); - } - get_char(mpl); - goto loop; - } - } - else if (mpl->c == '^') - mpl->token = T_POWER, append_char(mpl); - else if (mpl->c == '<') - { mpl->token = T_LT, append_char(mpl); - if (mpl->c == '=') - mpl->token = T_LE, append_char(mpl); - else if (mpl->c == '>') - mpl->token = T_NE, append_char(mpl); -#if 1 /* 11/II-2008 */ - else if (mpl->c == '-') - mpl->token = T_INPUT, append_char(mpl); -#endif - } - else if (mpl->c == '=') - { mpl->token = T_EQ, append_char(mpl); - if (mpl->c == '=') append_char(mpl); - } - else if (mpl->c == '>') - { mpl->token = T_GT, append_char(mpl); - if (mpl->c == '=') - mpl->token = T_GE, append_char(mpl); -#if 1 /* 14/VII-2006 */ - else if (mpl->c == '>') - mpl->token = T_APPEND, append_char(mpl); -#endif - } - else if (mpl->c == '!') - { mpl->token = T_NOT, append_char(mpl); - if (mpl->c == '=') - mpl->token = T_NE, append_char(mpl); - } - else if (mpl->c == '&') - { mpl->token = T_CONCAT, append_char(mpl); - if (mpl->c == '&') - mpl->token = T_AND, append_char(mpl); - } - else if (mpl->c == '|') - { mpl->token = T_BAR, append_char(mpl); - if (mpl->c == '|') - mpl->token = T_OR, append_char(mpl); - } - else if (!mpl->flag_d && mpl->c == '.') - { mpl->token = T_POINT, append_char(mpl); - if (mpl->f_dots) - { /* dots; the first dot was read on the previous call to the - scanner, so the current character is the second dot */ - mpl->token = T_DOTS; - mpl->imlen = 2; - strcpy(mpl->image, ".."); - mpl->f_dots = 0; - } - else if (mpl->c == '.') - mpl->token = T_DOTS, append_char(mpl); - else if (isdigit(mpl->c)) - { /* numeric literal that begins with the decimal point */ - mpl->token = T_NUMBER, append_char(mpl); - goto frac; - } - } - else if (mpl->c == ',') - mpl->token = T_COMMA, append_char(mpl); - else if (mpl->c == ':') - { mpl->token = T_COLON, append_char(mpl); - if (mpl->c == '=') - mpl->token = T_ASSIGN, append_char(mpl); - } - else if (mpl->c == ';') - mpl->token = T_SEMICOLON, append_char(mpl); - else if (mpl->c == '(') - mpl->token = T_LEFT, append_char(mpl); - else if (mpl->c == ')') - mpl->token = T_RIGHT, append_char(mpl); - else if (mpl->c == '[') - mpl->token = T_LBRACKET, append_char(mpl); - else if (mpl->c == ']') - mpl->token = T_RBRACKET, append_char(mpl); - else if (mpl->c == '{') - mpl->token = T_LBRACE, append_char(mpl); - else if (mpl->c == '}') - mpl->token = T_RBRACE, append_char(mpl); -#if 1 /* 11/II-2008 */ - else if (mpl->c == '~') - mpl->token = T_TILDE, append_char(mpl); -#endif - else if (isalnum(mpl->c) || strchr("+-._", mpl->c) != NULL) - { /* symbol */ - xassert(mpl->flag_d); - mpl->token = T_SYMBOL; - while (isalnum(mpl->c) || strchr("+-._", mpl->c) != NULL) - append_char(mpl); - switch (str2num(mpl->image, &mpl->value)) - { case 0: - mpl->token = T_NUMBER; - break; - case 1: - goto err; - case 2: - break; - default: - xassert(mpl != mpl); - } - } - else - { enter_context(mpl); - error(mpl, "character %c not allowed", mpl->c); - } - /* enter the current token into the context queue */ - enter_context(mpl); - /* reset the flag, which may be set by indexing_expression() and - is used by expression_list() */ - mpl->flag_x = 0; -done: return; -} - -/*---------------------------------------------------------------------- --- unget_token - return current token back to input stream. --- --- This routine returns the current token back to the input stream, so --- the previously scanned token becomes the current one. */ - -void unget_token(MPL *mpl) -{ /* save the current token, which becomes the next one */ - xassert(!mpl->f_scan); - mpl->f_scan = 1; - mpl->f_token = mpl->token; - mpl->f_imlen = mpl->imlen; - strcpy(mpl->f_image, mpl->image); - mpl->f_value = mpl->value; - /* restore the previous token, which becomes the current one */ - mpl->token = mpl->b_token; - mpl->imlen = mpl->b_imlen; - strcpy(mpl->image, mpl->b_image); - mpl->value = mpl->b_value; - return; -} - -/*---------------------------------------------------------------------- --- is_keyword - check if current token is given non-reserved keyword. --- --- If the current token is given (non-reserved) keyword, this routine --- returns non-zero. Otherwise zero is returned. */ - -int is_keyword(MPL *mpl, char *keyword) -{ return - mpl->token == T_NAME && strcmp(mpl->image, keyword) == 0; -} - -/*---------------------------------------------------------------------- --- is_reserved - check if current token is reserved keyword. --- --- If the current token is a reserved keyword, this routine returns --- non-zero. Otherwise zero is returned. */ - -int is_reserved(MPL *mpl) -{ return - mpl->token == T_AND && mpl->image[0] == 'a' || - mpl->token == T_BY || - mpl->token == T_CROSS || - mpl->token == T_DIFF || - mpl->token == T_DIV || - mpl->token == T_ELSE || - mpl->token == T_IF || - mpl->token == T_IN || - mpl->token == T_INTER || - mpl->token == T_LESS || - mpl->token == T_MOD || - mpl->token == T_NOT && mpl->image[0] == 'n' || - mpl->token == T_OR && mpl->image[0] == 'o' || - mpl->token == T_SYMDIFF || - mpl->token == T_THEN || - mpl->token == T_UNION || - mpl->token == T_WITHIN; -} - -/*---------------------------------------------------------------------- --- make_code - generate pseudo-code (basic routine). --- --- This routine generates specified pseudo-code. It is assumed that all --- other translator routines use this basic routine. */ - -CODE *make_code(MPL *mpl, int op, OPERANDS *arg, int type, int dim) -{ CODE *code; - DOMAIN *domain; - DOMAIN_BLOCK *block; - ARG_LIST *e; - /* generate pseudo-code */ - code = alloc(CODE); - code->op = op; - code->vflag = 0; /* is inherited from operand(s) */ - /* copy operands and also make them referring to the pseudo-code - being generated, because the latter becomes the parent for all - its operands */ - memset(&code->arg, '?', sizeof(OPERANDS)); - switch (op) - { case O_NUMBER: - code->arg.num = arg->num; - break; - case O_STRING: - code->arg.str = arg->str; - break; - case O_INDEX: - code->arg.index.slot = arg->index.slot; - code->arg.index.next = arg->index.next; - break; - case O_MEMNUM: - case O_MEMSYM: - for (e = arg->par.list; e != NULL; e = e->next) - { xassert(e->x != NULL); - xassert(e->x->up == NULL); - e->x->up = code; - code->vflag |= e->x->vflag; - } - code->arg.par.par = arg->par.par; - code->arg.par.list = arg->par.list; - break; - case O_MEMSET: - for (e = arg->set.list; e != NULL; e = e->next) - { xassert(e->x != NULL); - xassert(e->x->up == NULL); - e->x->up = code; - code->vflag |= e->x->vflag; - } - code->arg.set.set = arg->set.set; - code->arg.set.list = arg->set.list; - break; - case O_MEMVAR: - for (e = arg->var.list; e != NULL; e = e->next) - { xassert(e->x != NULL); - xassert(e->x->up == NULL); - e->x->up = code; - code->vflag |= e->x->vflag; - } - code->arg.var.var = arg->var.var; - code->arg.var.list = arg->var.list; -#if 1 /* 15/V-2010 */ - code->arg.var.suff = arg->var.suff; -#endif - break; -#if 1 /* 15/V-2010 */ - case O_MEMCON: - for (e = arg->con.list; e != NULL; e = e->next) - { xassert(e->x != NULL); - xassert(e->x->up == NULL); - e->x->up = code; - code->vflag |= e->x->vflag; - } - code->arg.con.con = arg->con.con; - code->arg.con.list = arg->con.list; - code->arg.con.suff = arg->con.suff; - break; -#endif - case O_TUPLE: - case O_MAKE: - for (e = arg->list; e != NULL; e = e->next) - { xassert(e->x != NULL); - xassert(e->x->up == NULL); - e->x->up = code; - code->vflag |= e->x->vflag; - } - code->arg.list = arg->list; - break; - case O_SLICE: - xassert(arg->slice != NULL); - code->arg.slice = arg->slice; - break; - case O_IRAND224: - case O_UNIFORM01: - case O_NORMAL01: - case O_GMTIME: - code->vflag = 1; - break; - case O_CVTNUM: - case O_CVTSYM: - case O_CVTLOG: - case O_CVTTUP: - case O_CVTLFM: - case O_PLUS: - case O_MINUS: - case O_NOT: - case O_ABS: - case O_CEIL: - case O_FLOOR: - case O_EXP: - case O_LOG: - case O_LOG10: - case O_SQRT: - case O_SIN: - case O_COS: - case O_ATAN: - case O_ROUND: - case O_TRUNC: - case O_CARD: - case O_LENGTH: - /* unary operation */ - xassert(arg->arg.x != NULL); - xassert(arg->arg.x->up == NULL); - arg->arg.x->up = code; - code->vflag |= arg->arg.x->vflag; - code->arg.arg.x = arg->arg.x; - break; - case O_ADD: - case O_SUB: - case O_LESS: - case O_MUL: - case O_DIV: - case O_IDIV: - case O_MOD: - case O_POWER: - case O_ATAN2: - case O_ROUND2: - case O_TRUNC2: - case O_UNIFORM: - if (op == O_UNIFORM) code->vflag = 1; - case O_NORMAL: - if (op == O_NORMAL) code->vflag = 1; - case O_CONCAT: - case O_LT: - case O_LE: - case O_EQ: - case O_GE: - case O_GT: - case O_NE: - case O_AND: - case O_OR: - case O_UNION: - case O_DIFF: - case O_SYMDIFF: - case O_INTER: - case O_CROSS: - case O_IN: - case O_NOTIN: - case O_WITHIN: - case O_NOTWITHIN: - case O_SUBSTR: - case O_STR2TIME: - case O_TIME2STR: - /* binary operation */ - xassert(arg->arg.x != NULL); - xassert(arg->arg.x->up == NULL); - arg->arg.x->up = code; - code->vflag |= arg->arg.x->vflag; - xassert(arg->arg.y != NULL); - xassert(arg->arg.y->up == NULL); - arg->arg.y->up = code; - code->vflag |= arg->arg.y->vflag; - code->arg.arg.x = arg->arg.x; - code->arg.arg.y = arg->arg.y; - break; - case O_DOTS: - case O_FORK: - case O_SUBSTR3: - /* ternary operation */ - xassert(arg->arg.x != NULL); - xassert(arg->arg.x->up == NULL); - arg->arg.x->up = code; - code->vflag |= arg->arg.x->vflag; - xassert(arg->arg.y != NULL); - xassert(arg->arg.y->up == NULL); - arg->arg.y->up = code; - code->vflag |= arg->arg.y->vflag; - if (arg->arg.z != NULL) - { xassert(arg->arg.z->up == NULL); - arg->arg.z->up = code; - code->vflag |= arg->arg.z->vflag; - } - code->arg.arg.x = arg->arg.x; - code->arg.arg.y = arg->arg.y; - code->arg.arg.z = arg->arg.z; - break; - case O_MIN: - case O_MAX: - /* n-ary operation */ - for (e = arg->list; e != NULL; e = e->next) - { xassert(e->x != NULL); - xassert(e->x->up == NULL); - e->x->up = code; - code->vflag |= e->x->vflag; - } - code->arg.list = arg->list; - break; - case O_SUM: - case O_PROD: - case O_MINIMUM: - case O_MAXIMUM: - case O_FORALL: - case O_EXISTS: - case O_SETOF: - case O_BUILD: - /* iterated operation */ - domain = arg->loop.domain; - xassert(domain != NULL); - if (domain->code != NULL) - { xassert(domain->code->up == NULL); - domain->code->up = code; - code->vflag |= domain->code->vflag; - } - for (block = domain->list; block != NULL; block = - block->next) - { xassert(block->code != NULL); - xassert(block->code->up == NULL); - block->code->up = code; - code->vflag |= block->code->vflag; - } - if (arg->loop.x != NULL) - { xassert(arg->loop.x->up == NULL); - arg->loop.x->up = code; - code->vflag |= arg->loop.x->vflag; - } - code->arg.loop.domain = arg->loop.domain; - code->arg.loop.x = arg->loop.x; - break; - default: - xassert(op != op); - } - /* set other attributes of the pseudo-code */ - code->type = type; - code->dim = dim; - code->up = NULL; - code->valid = 0; - memset(&code->value, '?', sizeof(VALUE)); - return code; -} - -/*---------------------------------------------------------------------- --- make_unary - generate pseudo-code for unary operation. --- --- This routine generates pseudo-code for unary operation. */ - -CODE *make_unary(MPL *mpl, int op, CODE *x, int type, int dim) -{ CODE *code; - OPERANDS arg; - xassert(x != NULL); - arg.arg.x = x; - code = make_code(mpl, op, &arg, type, dim); - return code; -} - -/*---------------------------------------------------------------------- --- make_binary - generate pseudo-code for binary operation. --- --- This routine generates pseudo-code for binary operation. */ - -CODE *make_binary(MPL *mpl, int op, CODE *x, CODE *y, int type, - int dim) -{ CODE *code; - OPERANDS arg; - xassert(x != NULL); - xassert(y != NULL); - arg.arg.x = x; - arg.arg.y = y; - code = make_code(mpl, op, &arg, type, dim); - return code; -} - -/*---------------------------------------------------------------------- --- make_ternary - generate pseudo-code for ternary operation. --- --- This routine generates pseudo-code for ternary operation. */ - -CODE *make_ternary(MPL *mpl, int op, CODE *x, CODE *y, CODE *z, - int type, int dim) -{ CODE *code; - OPERANDS arg; - xassert(x != NULL); - xassert(y != NULL); - /* third operand can be NULL */ - arg.arg.x = x; - arg.arg.y = y; - arg.arg.z = z; - code = make_code(mpl, op, &arg, type, dim); - return code; -} - -/*---------------------------------------------------------------------- --- numeric_literal - parse reference to numeric literal. --- --- This routine parses primary expression using the syntax: --- --- ::= */ - -CODE *numeric_literal(MPL *mpl) -{ CODE *code; - OPERANDS arg; - xassert(mpl->token == T_NUMBER); - arg.num = mpl->value; - code = make_code(mpl, O_NUMBER, &arg, A_NUMERIC, 0); - get_token(mpl /* */); - return code; -} - -/*---------------------------------------------------------------------- --- string_literal - parse reference to string literal. --- --- This routine parses primary expression using the syntax: --- --- ::= */ - -CODE *string_literal(MPL *mpl) -{ CODE *code; - OPERANDS arg; - xassert(mpl->token == T_STRING); - arg.str = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(arg.str, mpl->image); - code = make_code(mpl, O_STRING, &arg, A_SYMBOLIC, 0); - get_token(mpl /* */); - return code; -} - -/*---------------------------------------------------------------------- --- create_arg_list - create empty operands list. --- --- This routine creates operands list, which is initially empty. */ - -ARG_LIST *create_arg_list(MPL *mpl) -{ ARG_LIST *list; - xassert(mpl == mpl); - list = NULL; - return list; -} - -/*---------------------------------------------------------------------- --- expand_arg_list - append operand to operands list. --- --- This routine appends new operand to specified operands list. */ - -ARG_LIST *expand_arg_list(MPL *mpl, ARG_LIST *list, CODE *x) -{ ARG_LIST *tail, *temp; - xassert(x != NULL); - /* create new operands list entry */ - tail = alloc(ARG_LIST); - tail->x = x; - tail->next = NULL; - /* and append it to the operands list */ - if (list == NULL) - list = tail; - else - { for (temp = list; temp->next != NULL; temp = temp->next); - temp->next = tail; - } - return list; -} - -/*---------------------------------------------------------------------- --- arg_list_len - determine length of operands list. --- --- This routine returns the number of operands in operands list. */ - -int arg_list_len(MPL *mpl, ARG_LIST *list) -{ ARG_LIST *temp; - int len; - xassert(mpl == mpl); - len = 0; - for (temp = list; temp != NULL; temp = temp->next) len++; - return len; -} - -/*---------------------------------------------------------------------- --- subscript_list - parse subscript list. --- --- This routine parses subscript list using the syntax: --- --- ::= --- ::= , --- ::= */ - -ARG_LIST *subscript_list(MPL *mpl) -{ ARG_LIST *list; - CODE *x; - list = create_arg_list(mpl); - for (;;) - { /* parse subscript expression */ - x = expression_5(mpl); - /* convert it to symbolic type, if necessary */ - if (x->type == A_NUMERIC) - x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); - /* check that now the expression is of symbolic type */ - if (x->type != A_SYMBOLIC) - error(mpl, "subscript expression has invalid type"); - xassert(x->dim == 0); - /* and append it to the subscript list */ - list = expand_arg_list(mpl, list, x); - /* check a token that follows the subscript expression */ - if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else if (mpl->token == T_RBRACKET) - break; - else - error(mpl, "syntax error in subscript list"); - } - return list; -} - -#if 1 /* 15/V-2010 */ -/*---------------------------------------------------------------------- --- object_reference - parse reference to named object. --- --- This routine parses primary expression using the syntax: --- --- ::= --- ::= --- ::= [ ] --- ::= --- ::= [ ] --- ::= --- ::= [ ] --- --- ::= --- ::= [ ] --- --- ::= --- ::= --- ::= --- ::= --- ::= --- ::= | .lb | .ub | .status | .val | .dual */ - -CODE *object_reference(MPL *mpl) -{ AVLNODE *node; - DOMAIN_SLOT *slot; - SET *set; - PARAMETER *par; - VARIABLE *var; - CONSTRAINT *con; - ARG_LIST *list; - OPERANDS arg; - CODE *code; - char *name; - int dim, suff; - /* find the object in the symbolic name table */ - xassert(mpl->token == T_NAME); - node = avl_find_node(mpl->tree, mpl->image); - if (node == NULL) - error(mpl, "%s not defined", mpl->image); - /* check the object type and obtain its dimension */ - switch (avl_get_node_type(node)) - { case A_INDEX: - /* dummy index */ - slot = (DOMAIN_SLOT *)avl_get_node_link(node); - name = slot->name; - dim = 0; - break; - case A_SET: - /* model set */ - set = (SET *)avl_get_node_link(node); - name = set->name; - dim = set->dim; - /* if a set object is referenced in its own declaration and - the dimen attribute is not specified yet, use dimen 1 by - default */ - if (set->dimen == 0) set->dimen = 1; - break; - case A_PARAMETER: - /* model parameter */ - par = (PARAMETER *)avl_get_node_link(node); - name = par->name; - dim = par->dim; - break; - case A_VARIABLE: - /* model variable */ - var = (VARIABLE *)avl_get_node_link(node); - name = var->name; - dim = var->dim; - break; - case A_CONSTRAINT: - /* model constraint or objective */ - con = (CONSTRAINT *)avl_get_node_link(node); - name = con->name; - dim = con->dim; - break; - default: - xassert(node != node); - } - get_token(mpl /* */); - /* parse optional subscript list */ - if (mpl->token == T_LBRACKET) - { /* subscript list is specified */ - if (dim == 0) - error(mpl, "%s cannot be subscripted", name); - get_token(mpl /* [ */); - list = subscript_list(mpl); - if (dim != arg_list_len(mpl, list)) - error(mpl, "%s must have %d subscript%s rather than %d", - name, dim, dim == 1 ? "" : "s", arg_list_len(mpl, list)); - xassert(mpl->token == T_RBRACKET); - get_token(mpl /* ] */); - } - else - { /* subscript list is not specified */ - if (dim != 0) - error(mpl, "%s must be subscripted", name); - list = create_arg_list(mpl); - } - /* parse optional suffix */ - if (!mpl->flag_s && avl_get_node_type(node) == A_VARIABLE) - suff = DOT_NONE; - else - suff = DOT_VAL; - if (mpl->token == T_POINT) - { get_token(mpl /* . */); - if (mpl->token != T_NAME) - error(mpl, "invalid use of period"); - if (!(avl_get_node_type(node) == A_VARIABLE || - avl_get_node_type(node) == A_CONSTRAINT)) - error(mpl, "%s cannot have a suffix", name); - if (strcmp(mpl->image, "lb") == 0) - suff = DOT_LB; - else if (strcmp(mpl->image, "ub") == 0) - suff = DOT_UB; - else if (strcmp(mpl->image, "status") == 0) - suff = DOT_STATUS; - else if (strcmp(mpl->image, "val") == 0) - suff = DOT_VAL; - else if (strcmp(mpl->image, "dual") == 0) - suff = DOT_DUAL; - else - error(mpl, "suffix .%s invalid", mpl->image); - get_token(mpl /* suffix */); - } - /* generate pseudo-code to take value of the object */ - switch (avl_get_node_type(node)) - { case A_INDEX: - arg.index.slot = slot; - arg.index.next = slot->list; - code = make_code(mpl, O_INDEX, &arg, A_SYMBOLIC, 0); - slot->list = code; - break; - case A_SET: - arg.set.set = set; - arg.set.list = list; - code = make_code(mpl, O_MEMSET, &arg, A_ELEMSET, - set->dimen); - break; - case A_PARAMETER: - arg.par.par = par; - arg.par.list = list; - if (par->type == A_SYMBOLIC) - code = make_code(mpl, O_MEMSYM, &arg, A_SYMBOLIC, 0); - else - code = make_code(mpl, O_MEMNUM, &arg, A_NUMERIC, 0); - break; - case A_VARIABLE: - if (!mpl->flag_s && (suff == DOT_STATUS || suff == DOT_VAL - || suff == DOT_DUAL)) - error(mpl, "invalid reference to status, primal value, o" - "r dual value of variable %s above solve statement", - var->name); - arg.var.var = var; - arg.var.list = list; - arg.var.suff = suff; - code = make_code(mpl, O_MEMVAR, &arg, suff == DOT_NONE ? - A_FORMULA : A_NUMERIC, 0); - break; - case A_CONSTRAINT: - if (!mpl->flag_s && (suff == DOT_STATUS || suff == DOT_VAL - || suff == DOT_DUAL)) - error(mpl, "invalid reference to status, primal value, o" - "r dual value of %s %s above solve statement", - con->type == A_CONSTRAINT ? "constraint" : "objective" - , con->name); - arg.con.con = con; - arg.con.list = list; - arg.con.suff = suff; - code = make_code(mpl, O_MEMCON, &arg, A_NUMERIC, 0); - break; - default: - xassert(node != node); - } - return code; -} -#endif - -/*---------------------------------------------------------------------- --- numeric_argument - parse argument passed to built-in function. --- --- This routine parses an argument passed to numeric built-in function --- using the syntax: --- --- ::= */ - -CODE *numeric_argument(MPL *mpl, char *func) -{ CODE *x; - x = expression_5(mpl); - /* convert the argument to numeric type, if necessary */ - if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - /* check that now the argument is of numeric type */ - if (x->type != A_NUMERIC) - error(mpl, "argument for %s has invalid type", func); - xassert(x->dim == 0); - return x; -} - -#if 1 /* 15/VII-2006 */ -CODE *symbolic_argument(MPL *mpl, char *func) -{ CODE *x; - x = expression_5(mpl); - /* convert the argument to symbolic type, if necessary */ - if (x->type == A_NUMERIC) - x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); - /* check that now the argument is of symbolic type */ - if (x->type != A_SYMBOLIC) - error(mpl, "argument for %s has invalid type", func); - xassert(x->dim == 0); - return x; -} -#endif - -#if 1 /* 15/VII-2006 */ -CODE *elemset_argument(MPL *mpl, char *func) -{ CODE *x; - x = expression_9(mpl); - if (x->type != A_ELEMSET) - error(mpl, "argument for %s has invalid type", func); - xassert(x->dim > 0); - return x; -} -#endif - -/*---------------------------------------------------------------------- --- function_reference - parse reference to built-in function. --- --- This routine parses primary expression using the syntax: --- --- ::= abs ( ) --- ::= ceil ( ) --- ::= floor ( ) --- ::= exp ( ) --- ::= log ( ) --- ::= log10 ( ) --- ::= max ( ) --- ::= min ( ) --- ::= sqrt ( ) --- ::= sin ( ) --- ::= cos ( ) --- ::= atan ( ) --- ::= atan2 ( , ) --- ::= round ( ) --- ::= round ( , ) --- ::= trunc ( ) --- ::= trunc ( , ) --- ::= Irand224 ( ) --- ::= Uniform01 ( ) --- ::= Uniform ( , ) --- ::= Normal01 ( ) --- ::= Normal ( , ) --- ::= card ( ) --- ::= length ( ) --- ::= substr ( , ) --- ::= substr ( , , ) --- ::= str2time ( , ) --- ::= time2str ( , ) --- ::= gmtime ( ) --- ::= --- ::= , */ - -CODE *function_reference(MPL *mpl) -{ CODE *code; - OPERANDS arg; - int op; - char func[15+1]; - /* determine operation code */ - xassert(mpl->token == T_NAME); - if (strcmp(mpl->image, "abs") == 0) - op = O_ABS; - else if (strcmp(mpl->image, "ceil") == 0) - op = O_CEIL; - else if (strcmp(mpl->image, "floor") == 0) - op = O_FLOOR; - else if (strcmp(mpl->image, "exp") == 0) - op = O_EXP; - else if (strcmp(mpl->image, "log") == 0) - op = O_LOG; - else if (strcmp(mpl->image, "log10") == 0) - op = O_LOG10; - else if (strcmp(mpl->image, "sqrt") == 0) - op = O_SQRT; - else if (strcmp(mpl->image, "sin") == 0) - op = O_SIN; - else if (strcmp(mpl->image, "cos") == 0) - op = O_COS; - else if (strcmp(mpl->image, "atan") == 0) - op = O_ATAN; - else if (strcmp(mpl->image, "min") == 0) - op = O_MIN; - else if (strcmp(mpl->image, "max") == 0) - op = O_MAX; - else if (strcmp(mpl->image, "round") == 0) - op = O_ROUND; - else if (strcmp(mpl->image, "trunc") == 0) - op = O_TRUNC; - else if (strcmp(mpl->image, "Irand224") == 0) - op = O_IRAND224; - else if (strcmp(mpl->image, "Uniform01") == 0) - op = O_UNIFORM01; - else if (strcmp(mpl->image, "Uniform") == 0) - op = O_UNIFORM; - else if (strcmp(mpl->image, "Normal01") == 0) - op = O_NORMAL01; - else if (strcmp(mpl->image, "Normal") == 0) - op = O_NORMAL; - else if (strcmp(mpl->image, "card") == 0) - op = O_CARD; - else if (strcmp(mpl->image, "length") == 0) - op = O_LENGTH; - else if (strcmp(mpl->image, "substr") == 0) - op = O_SUBSTR; - else if (strcmp(mpl->image, "str2time") == 0) - op = O_STR2TIME; - else if (strcmp(mpl->image, "time2str") == 0) - op = O_TIME2STR; - else if (strcmp(mpl->image, "gmtime") == 0) - op = O_GMTIME; - else - error(mpl, "function %s unknown", mpl->image); - /* save symbolic name of the function */ - strcpy(func, mpl->image); - xassert(strlen(func) < sizeof(func)); - get_token(mpl /* */); - /* check the left parenthesis that follows the function name */ - xassert(mpl->token == T_LEFT); - get_token(mpl /* ( */); - /* parse argument list */ - if (op == O_MIN || op == O_MAX) - { /* min and max allow arbitrary number of arguments */ - arg.list = create_arg_list(mpl); - /* parse argument list */ - for (;;) - { /* parse argument and append it to the operands list */ - arg.list = expand_arg_list(mpl, arg.list, - numeric_argument(mpl, func)); - /* check a token that follows the argument */ - if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else if (mpl->token == T_RIGHT) - break; - else - error(mpl, "syntax error in argument list for %s", func); - } - } - else if (op == O_IRAND224 || op == O_UNIFORM01 || op == - O_NORMAL01 || op == O_GMTIME) - { /* Irand224, Uniform01, Normal01, gmtime need no arguments */ - if (mpl->token != T_RIGHT) - error(mpl, "%s needs no arguments", func); - } - else if (op == O_UNIFORM || op == O_NORMAL) - { /* Uniform and Normal need two arguments */ - /* parse the first argument */ - arg.arg.x = numeric_argument(mpl, func); - /* check a token that follows the first argument */ - if (mpl->token == T_COMMA) - ; - else if (mpl->token == T_RIGHT) - error(mpl, "%s needs two arguments", func); - else - error(mpl, "syntax error in argument for %s", func); - get_token(mpl /* , */); - /* parse the second argument */ - arg.arg.y = numeric_argument(mpl, func); - /* check a token that follows the second argument */ - if (mpl->token == T_COMMA) - error(mpl, "%s needs two argument", func); - else if (mpl->token == T_RIGHT) - ; - else - error(mpl, "syntax error in argument for %s", func); - } - else if (op == O_ATAN || op == O_ROUND || op == O_TRUNC) - { /* atan, round, and trunc need one or two arguments */ - /* parse the first argument */ - arg.arg.x = numeric_argument(mpl, func); - /* parse the second argument, if specified */ - if (mpl->token == T_COMMA) - { switch (op) - { case O_ATAN: op = O_ATAN2; break; - case O_ROUND: op = O_ROUND2; break; - case O_TRUNC: op = O_TRUNC2; break; - default: xassert(op != op); - } - get_token(mpl /* , */); - arg.arg.y = numeric_argument(mpl, func); - } - /* check a token that follows the last argument */ - if (mpl->token == T_COMMA) - error(mpl, "%s needs one or two arguments", func); - else if (mpl->token == T_RIGHT) - ; - else - error(mpl, "syntax error in argument for %s", func); - } - else if (op == O_SUBSTR) - { /* substr needs two or three arguments */ - /* parse the first argument */ - arg.arg.x = symbolic_argument(mpl, func); - /* check a token that follows the first argument */ - if (mpl->token == T_COMMA) - ; - else if (mpl->token == T_RIGHT) - error(mpl, "%s needs two or three arguments", func); - else - error(mpl, "syntax error in argument for %s", func); - get_token(mpl /* , */); - /* parse the second argument */ - arg.arg.y = numeric_argument(mpl, func); - /* parse the third argument, if specified */ - if (mpl->token == T_COMMA) - { op = O_SUBSTR3; - get_token(mpl /* , */); - arg.arg.z = numeric_argument(mpl, func); - } - /* check a token that follows the last argument */ - if (mpl->token == T_COMMA) - error(mpl, "%s needs two or three arguments", func); - else if (mpl->token == T_RIGHT) - ; - else - error(mpl, "syntax error in argument for %s", func); - } - else if (op == O_STR2TIME) - { /* str2time needs two arguments, both symbolic */ - /* parse the first argument */ - arg.arg.x = symbolic_argument(mpl, func); - /* check a token that follows the first argument */ - if (mpl->token == T_COMMA) - ; - else if (mpl->token == T_RIGHT) - error(mpl, "%s needs two arguments", func); - else - error(mpl, "syntax error in argument for %s", func); - get_token(mpl /* , */); - /* parse the second argument */ - arg.arg.y = symbolic_argument(mpl, func); - /* check a token that follows the second argument */ - if (mpl->token == T_COMMA) - error(mpl, "%s needs two argument", func); - else if (mpl->token == T_RIGHT) - ; - else - error(mpl, "syntax error in argument for %s", func); - } - else if (op == O_TIME2STR) - { /* time2str needs two arguments, numeric and symbolic */ - /* parse the first argument */ - arg.arg.x = numeric_argument(mpl, func); - /* check a token that follows the first argument */ - if (mpl->token == T_COMMA) - ; - else if (mpl->token == T_RIGHT) - error(mpl, "%s needs two arguments", func); - else - error(mpl, "syntax error in argument for %s", func); - get_token(mpl /* , */); - /* parse the second argument */ - arg.arg.y = symbolic_argument(mpl, func); - /* check a token that follows the second argument */ - if (mpl->token == T_COMMA) - error(mpl, "%s needs two argument", func); - else if (mpl->token == T_RIGHT) - ; - else - error(mpl, "syntax error in argument for %s", func); - } - else - { /* other functions need one argument */ - if (op == O_CARD) - arg.arg.x = elemset_argument(mpl, func); - else if (op == O_LENGTH) - arg.arg.x = symbolic_argument(mpl, func); - else - arg.arg.x = numeric_argument(mpl, func); - /* check a token that follows the argument */ - if (mpl->token == T_COMMA) - error(mpl, "%s needs one argument", func); - else if (mpl->token == T_RIGHT) - ; - else - error(mpl, "syntax error in argument for %s", func); - } - /* make pseudo-code to call the built-in function */ - if (op == O_SUBSTR || op == O_SUBSTR3 || op == O_TIME2STR) - code = make_code(mpl, op, &arg, A_SYMBOLIC, 0); - else - code = make_code(mpl, op, &arg, A_NUMERIC, 0); - /* the reference ends with the right parenthesis */ - xassert(mpl->token == T_RIGHT); - get_token(mpl /* ) */); - return code; -} - -/*---------------------------------------------------------------------- --- create_domain - create empty domain. --- --- This routine creates empty domain, which is initially empty, i.e. --- has no domain blocks. */ - -DOMAIN *create_domain(MPL *mpl) -{ DOMAIN *domain; - domain = alloc(DOMAIN); - domain->list = NULL; - domain->code = NULL; - return domain; -} - -/*---------------------------------------------------------------------- --- create_block - create empty domain block. --- --- This routine creates empty domain block, which is initially empty, --- i.e. has no domain slots. */ - -DOMAIN_BLOCK *create_block(MPL *mpl) -{ DOMAIN_BLOCK *block; - block = alloc(DOMAIN_BLOCK); - block->list = NULL; - block->code = NULL; - block->backup = NULL; - block->next = NULL; - return block; -} - -/*---------------------------------------------------------------------- --- append_block - append domain block to specified domain. --- --- This routine adds given domain block to the end of the block list of --- specified domain. */ - -void append_block(MPL *mpl, DOMAIN *domain, DOMAIN_BLOCK *block) -{ DOMAIN_BLOCK *temp; - xassert(mpl == mpl); - xassert(domain != NULL); - xassert(block != NULL); - xassert(block->next == NULL); - if (domain->list == NULL) - domain->list = block; - else - { for (temp = domain->list; temp->next != NULL; temp = - temp->next); - temp->next = block; - } - return; -} - -/*---------------------------------------------------------------------- --- append_slot - create and append new slot to domain block. --- --- This routine creates new domain slot and adds it to the end of slot --- list of specified domain block. --- --- The parameter name is symbolic name of the dummy index associated --- with the slot (the character string must be allocated). NULL means --- the dummy index is not explicitly specified. --- --- The parameter code is pseudo-code for computing symbolic value, at --- which the dummy index is bounded. NULL means the dummy index is free --- in the domain scope. */ - -DOMAIN_SLOT *append_slot(MPL *mpl, DOMAIN_BLOCK *block, char *name, - CODE *code) -{ DOMAIN_SLOT *slot, *temp; - xassert(block != NULL); - slot = alloc(DOMAIN_SLOT); - slot->name = name; - slot->code = code; - slot->value = NULL; - slot->list = NULL; - slot->next = NULL; - if (block->list == NULL) - block->list = slot; - else - { for (temp = block->list; temp->next != NULL; temp = - temp->next); - temp->next = slot; - } - return slot; -} - -/*---------------------------------------------------------------------- --- expression_list - parse expression list. --- --- This routine parses a list of one or more expressions enclosed into --- the parentheses using the syntax: --- --- ::= ( ) --- ::= --- ::= , --- --- Note that this construction may have three different meanings: --- --- 1. If consists of only one expression, is a parenthesized expression, which may be of any --- valid type (not necessarily 1-tuple). --- --- 2. If consists of several expressions separated by --- commae, where no expression is undeclared symbolic name, is a n-tuple. --- --- 3. If consists of several expressions separated by --- commae, where at least one expression is undeclared symbolic name --- (that denotes a dummy index), is a slice and --- can be only used as constituent of indexing expression. */ - -#define max_dim 20 -/* maximal number of components allowed within parentheses */ - -CODE *expression_list(MPL *mpl) -{ CODE *code; - OPERANDS arg; - struct { char *name; CODE *code; } list[1+max_dim]; - int flag_x, next_token, dim, j, slice = 0; - xassert(mpl->token == T_LEFT); - /* the flag, which allows recognizing undeclared symbolic names - as dummy indices, will be automatically reset by get_token(), - so save it before scanning the next token */ - flag_x = mpl->flag_x; - get_token(mpl /* ( */); - /* parse */ - for (dim = 1; ; dim++) - { if (dim > max_dim) - error(mpl, "too many components within parentheses"); - /* current component of can be either dummy - index or expression */ - if (mpl->token == T_NAME) - { /* symbolic name is recognized as dummy index only if: - the flag, which allows that, is set, and - the name is followed by comma or right parenthesis, and - the name is undeclared */ - get_token(mpl /* */); - next_token = mpl->token; - unget_token(mpl); - if (!(flag_x && - (next_token == T_COMMA || next_token == T_RIGHT) && - avl_find_node(mpl->tree, mpl->image) == NULL)) - { /* this is not dummy index */ - goto expr; - } - /* all dummy indices within the same slice must have unique - symbolic names */ - for (j = 1; j < dim; j++) - { if (list[j].name != NULL && strcmp(list[j].name, - mpl->image) == 0) - error(mpl, "duplicate dummy index %s not allowed", - mpl->image); - } - /* current component of is dummy index */ - list[dim].name - = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(list[dim].name, mpl->image); - list[dim].code = NULL; - get_token(mpl /* */); - /* is a slice, because at least one dummy - index has appeared */ - slice = 1; - /* note that the context ( ) is not allowed, - i.e. in this case is considered as - a parenthesized expression */ - if (dim == 1 && mpl->token == T_RIGHT) - error(mpl, "%s not defined", list[dim].name); - } - else -expr: { /* current component of is expression */ - code = expression_13(mpl); - /* if the current expression is followed by comma or it is - not the very first expression, entire - is n-tuple or slice, in which case the current expression - should be converted to symbolic type, if necessary */ - if (mpl->token == T_COMMA || dim > 1) - { if (code->type == A_NUMERIC) - code = make_unary(mpl, O_CVTSYM, code, A_SYMBOLIC, 0); - /* now the expression must be of symbolic type */ - if (code->type != A_SYMBOLIC) - error(mpl, "component expression has invalid type"); - xassert(code->dim == 0); - } - list[dim].name = NULL; - list[dim].code = code; - } - /* check a token that follows the current component */ - if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else if (mpl->token == T_RIGHT) - break; - else - error(mpl, "right parenthesis missing where expected"); - } - /* generate pseudo-code for */ - if (dim == 1 && !slice) - { /* is a parenthesized expression */ - code = list[1].code; - } - else if (!slice) - { /* is a n-tuple */ - arg.list = create_arg_list(mpl); - for (j = 1; j <= dim; j++) - arg.list = expand_arg_list(mpl, arg.list, list[j].code); - code = make_code(mpl, O_TUPLE, &arg, A_TUPLE, dim); - } - else - { /* is a slice */ - arg.slice = create_block(mpl); - for (j = 1; j <= dim; j++) - append_slot(mpl, arg.slice, list[j].name, list[j].code); - /* note that actually pseudo-codes with op = O_SLICE are never - evaluated */ - code = make_code(mpl, O_SLICE, &arg, A_TUPLE, dim); - } - get_token(mpl /* ) */); - /* if is a slice, there must be the keyword - 'in', which follows the right parenthesis */ - if (slice && mpl->token != T_IN) - error(mpl, "keyword in missing where expected"); - /* if the slice flag is set and there is the keyword 'in', which - follows , the latter must be a slice */ - if (flag_x && mpl->token == T_IN && !slice) - { if (dim == 1) - error(mpl, "syntax error in indexing expression"); - else - error(mpl, "0-ary slice not allowed"); - } - return code; -} - -/*---------------------------------------------------------------------- --- literal set - parse literal set. --- --- This routine parses literal set using the syntax: --- --- ::= { } --- ::= --- ::= , --- ::= --- --- It is assumed that the left curly brace and the very first member --- expression that follows it are already parsed. The right curly brace --- remains unscanned on exit. */ - -CODE *literal_set(MPL *mpl, CODE *code) -{ OPERANDS arg; - int j; - xassert(code != NULL); - arg.list = create_arg_list(mpl); - /* parse */ - for (j = 1; ; j++) - { /* all member expressions must be n-tuples; so, if the current - expression is not n-tuple, convert it to 1-tuple */ - if (code->type == A_NUMERIC) - code = make_unary(mpl, O_CVTSYM, code, A_SYMBOLIC, 0); - if (code->type == A_SYMBOLIC) - code = make_unary(mpl, O_CVTTUP, code, A_TUPLE, 1); - /* now the expression must be n-tuple */ - if (code->type != A_TUPLE) - error(mpl, "member expression has invalid type"); - /* all member expressions must have identical dimension */ - if (arg.list != NULL && arg.list->x->dim != code->dim) - error(mpl, "member %d has %d component%s while member %d ha" - "s %d component%s", - j-1, arg.list->x->dim, arg.list->x->dim == 1 ? "" : "s", - j, code->dim, code->dim == 1 ? "" : "s"); - /* append the current expression to the member list */ - arg.list = expand_arg_list(mpl, arg.list, code); - /* check a token that follows the current expression */ - if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else if (mpl->token == T_RBRACE) - break; - else - error(mpl, "syntax error in literal set"); - /* parse the next expression that follows the comma */ - code = expression_5(mpl); - } - /* generate pseudo-code for */ - code = make_code(mpl, O_MAKE, &arg, A_ELEMSET, arg.list->x->dim); - return code; -} - -/*---------------------------------------------------------------------- --- indexing_expression - parse indexing expression. --- --- This routine parses indexing expression using the syntax: --- --- ::= --- ::= { } --- ::= { : } --- ::= --- ::= , --- ::= --- ::= in --- ::= in --- ::= --- ::= ( ) --- ::= --- ::= --- --- This routine creates domain for , where each --- domain block corresponds to , and each domain slot --- corresponds to individual indexing position. */ - -DOMAIN *indexing_expression(MPL *mpl) -{ DOMAIN *domain; - DOMAIN_BLOCK *block; - DOMAIN_SLOT *slot; - CODE *code; - xassert(mpl->token == T_LBRACE); - get_token(mpl /* { */); - if (mpl->token == T_RBRACE) - error(mpl, "empty indexing expression not allowed"); - /* create domain to be constructed */ - domain = create_domain(mpl); - /* parse either or that follows the - left brace */ - for (;;) - { /* domain block for is not created yet */ - block = NULL; - /* pseudo-code for is not generated yet */ - code = NULL; - /* check a token, which begins with */ - if (mpl->token == T_NAME) - { /* it is a symbolic name */ - int next_token; - char *name; - /* symbolic name is recognized as dummy index only if it is - followed by the keyword 'in' and not declared */ - get_token(mpl /* */); - next_token = mpl->token; - unget_token(mpl); - if (!(next_token == T_IN && - avl_find_node(mpl->tree, mpl->image) == NULL)) - { /* this is not dummy index; the symbolic name begins an - expression, which is either or the - very first in */ - goto expr; - } - /* create domain block with one slot, which is assigned the - dummy index */ - block = create_block(mpl); - name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(name, mpl->image); - append_slot(mpl, block, name, NULL); - get_token(mpl /* */); - /* the keyword 'in' is already checked above */ - xassert(mpl->token == T_IN); - get_token(mpl /* in */); - /* that follows the keyword 'in' will be - parsed below */ - } - else if (mpl->token == T_LEFT) - { /* it is the left parenthesis; parse expression that begins - with this parenthesis (the flag is set in order to allow - recognizing slices; see the routine expression_list) */ - mpl->flag_x = 1; - code = expression_9(mpl); - if (code->op != O_SLICE) - { /* this is either or the very first - in */ - goto expr; - } - /* this is a slice; besides the corresponding domain block - is already created by expression_list() */ - block = code->arg.slice; - code = NULL; /* is not parsed yet */ - /* the keyword 'in' following the slice is already checked - by expression_list() */ - xassert(mpl->token == T_IN); - get_token(mpl /* in */); - /* that follows the keyword 'in' will be - parsed below */ - } -expr: /* parse expression that follows either the keyword 'in' (in - which case it can be as well as the - very first in ); note that - this expression can be already parsed above */ - if (code == NULL) code = expression_9(mpl); - /* check the type of the expression just parsed */ - if (code->type != A_ELEMSET) - { /* it is not and therefore it can only - be the very first in ; - however, then there must be no dummy index neither slice - between the left brace and this expression */ - if (block != NULL) - error(mpl, "domain expression has invalid type"); - /* parse the rest part of and make this set - be , i.e. the construction {a, b, c} - is parsed as it were written as {A}, where A = {a, b, c} - is a temporary elemental set */ - code = literal_set(mpl, code); - } - /* now pseudo-code for has been built */ - xassert(code != NULL); - xassert(code->type == A_ELEMSET); - xassert(code->dim > 0); - /* if domain block for the current is still - not created, create it for fake slice of the same dimension - as */ - if (block == NULL) - { int j; - block = create_block(mpl); - for (j = 1; j <= code->dim; j++) - append_slot(mpl, block, NULL, NULL); - } - /* number of indexing positions in must be - the same as dimension of n-tuples in basic set */ - { int dim = 0; - for (slot = block->list; slot != NULL; slot = slot->next) - dim++; - if (dim != code->dim) - error(mpl,"%d %s specified for set of dimension %d", - dim, dim == 1 ? "index" : "indices", code->dim); - } - /* store pseudo-code for in the domain block */ - xassert(block->code == NULL); - block->code = code; - /* and append the domain block to the domain */ - append_block(mpl, domain, block); - /* the current has been completely parsed; - include all its dummy indices into the symbolic name table - to make them available for referencing from expressions; - implicit declarations of dummy indices remain valid while - the corresponding domain scope is valid */ - for (slot = block->list; slot != NULL; slot = slot->next) - if (slot->name != NULL) - { AVLNODE *node; - xassert(avl_find_node(mpl->tree, slot->name) == NULL); - node = avl_insert_node(mpl->tree, slot->name); - avl_set_node_type(node, A_INDEX); - avl_set_node_link(node, (void *)slot); - } - /* check a token that follows */ - if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else if (mpl->token == T_COLON || mpl->token == T_RBRACE) - break; - else - error(mpl, "syntax error in indexing expression"); - } - /* parse that follows the colon */ - if (mpl->token == T_COLON) - { get_token(mpl /* : */); - code = expression_13(mpl); - /* convert the expression to logical type, if necessary */ - if (code->type == A_SYMBOLIC) - code = make_unary(mpl, O_CVTNUM, code, A_NUMERIC, 0); - if (code->type == A_NUMERIC) - code = make_unary(mpl, O_CVTLOG, code, A_LOGICAL, 0); - /* now the expression must be of logical type */ - if (code->type != A_LOGICAL) - error(mpl, "expression following colon has invalid type"); - xassert(code->dim == 0); - domain->code = code; - /* the right brace must follow the logical expression */ - if (mpl->token != T_RBRACE) - error(mpl, "syntax error in indexing expression"); - } - get_token(mpl /* } */); - return domain; -} - -/*---------------------------------------------------------------------- --- close_scope - close scope of indexing expression. --- --- The routine closes the scope of indexing expression specified by its --- domain and thereby makes all dummy indices introduced in the indexing --- expression no longer available for referencing. */ - -void close_scope(MPL *mpl, DOMAIN *domain) -{ DOMAIN_BLOCK *block; - DOMAIN_SLOT *slot; - AVLNODE *node; - xassert(domain != NULL); - /* remove all dummy indices from the symbolic names table */ - for (block = domain->list; block != NULL; block = block->next) - { for (slot = block->list; slot != NULL; slot = slot->next) - { if (slot->name != NULL) - { node = avl_find_node(mpl->tree, slot->name); - xassert(node != NULL); - xassert(avl_get_node_type(node) == A_INDEX); - avl_delete_node(mpl->tree, node); - } - } - } - return; -} - -/*---------------------------------------------------------------------- --- iterated_expression - parse iterated expression. --- --- This routine parses primary expression using the syntax: --- --- ::= --- ::= sum --- ::= prod --- ::= min --- ::= max --- ::= exists --- --- ::= forall --- --- ::= setof --- --- Note that parsing "integrand" depends on the iterated operator. */ - -#if 1 /* 07/IX-2008 */ -static void link_up(CODE *code) -{ /* if we have something like sum{(i+1,j,k-1) in E} x[i,j,k], - where i and k are dummy indices defined out of the iterated - expression, we should link up pseudo-code for computing i+1 - and k-1 to pseudo-code for computing the iterated expression; - this is needed to invalidate current value of the iterated - expression once i or k have been changed */ - DOMAIN_BLOCK *block; - DOMAIN_SLOT *slot; - for (block = code->arg.loop.domain->list; block != NULL; - block = block->next) - { for (slot = block->list; slot != NULL; slot = slot->next) - { if (slot->code != NULL) - { xassert(slot->code->up == NULL); - slot->code->up = code; - } - } - } - return; -} -#endif - -CODE *iterated_expression(MPL *mpl) -{ CODE *code; - OPERANDS arg; - int op; - char opstr[8]; - /* determine operation code */ - xassert(mpl->token == T_NAME); - if (strcmp(mpl->image, "sum") == 0) - op = O_SUM; - else if (strcmp(mpl->image, "prod") == 0) - op = O_PROD; - else if (strcmp(mpl->image, "min") == 0) - op = O_MINIMUM; - else if (strcmp(mpl->image, "max") == 0) - op = O_MAXIMUM; - else if (strcmp(mpl->image, "forall") == 0) - op = O_FORALL; - else if (strcmp(mpl->image, "exists") == 0) - op = O_EXISTS; - else if (strcmp(mpl->image, "setof") == 0) - op = O_SETOF; - else - error(mpl, "operator %s unknown", mpl->image); - strcpy(opstr, mpl->image); - xassert(strlen(opstr) < sizeof(opstr)); - get_token(mpl /* */); - /* check the left brace that follows the operator name */ - xassert(mpl->token == T_LBRACE); - /* parse indexing expression that controls iterating */ - arg.loop.domain = indexing_expression(mpl); - /* parse "integrand" expression and generate pseudo-code */ - switch (op) - { case O_SUM: - case O_PROD: - case O_MINIMUM: - case O_MAXIMUM: - arg.loop.x = expression_3(mpl); - /* convert the integrand to numeric type, if necessary */ - if (arg.loop.x->type == A_SYMBOLIC) - arg.loop.x = make_unary(mpl, O_CVTNUM, arg.loop.x, - A_NUMERIC, 0); - /* now the integrand must be of numeric type or linear form - (the latter is only allowed for the sum operator) */ - if (!(arg.loop.x->type == A_NUMERIC || - op == O_SUM && arg.loop.x->type == A_FORMULA)) -err: error(mpl, "integrand following %s{...} has invalid type" - , opstr); - xassert(arg.loop.x->dim == 0); - /* generate pseudo-code */ - code = make_code(mpl, op, &arg, arg.loop.x->type, 0); - break; - case O_FORALL: - case O_EXISTS: - arg.loop.x = expression_12(mpl); - /* convert the integrand to logical type, if necessary */ - if (arg.loop.x->type == A_SYMBOLIC) - arg.loop.x = make_unary(mpl, O_CVTNUM, arg.loop.x, - A_NUMERIC, 0); - if (arg.loop.x->type == A_NUMERIC) - arg.loop.x = make_unary(mpl, O_CVTLOG, arg.loop.x, - A_LOGICAL, 0); - /* now the integrand must be of logical type */ - if (arg.loop.x->type != A_LOGICAL) goto err; - xassert(arg.loop.x->dim == 0); - /* generate pseudo-code */ - code = make_code(mpl, op, &arg, A_LOGICAL, 0); - break; - case O_SETOF: - arg.loop.x = expression_5(mpl); - /* convert the integrand to 1-tuple, if necessary */ - if (arg.loop.x->type == A_NUMERIC) - arg.loop.x = make_unary(mpl, O_CVTSYM, arg.loop.x, - A_SYMBOLIC, 0); - if (arg.loop.x->type == A_SYMBOLIC) - arg.loop.x = make_unary(mpl, O_CVTTUP, arg.loop.x, - A_TUPLE, 1); - /* now the integrand must be n-tuple */ - if (arg.loop.x->type != A_TUPLE) goto err; - xassert(arg.loop.x->dim > 0); - /* generate pseudo-code */ - code = make_code(mpl, op, &arg, A_ELEMSET, arg.loop.x->dim); - break; - default: - xassert(op != op); - } - /* close the scope of the indexing expression */ - close_scope(mpl, arg.loop.domain); -#if 1 /* 07/IX-2008 */ - link_up(code); -#endif - return code; -} - -/*---------------------------------------------------------------------- --- domain_arity - determine arity of domain. --- --- This routine returns arity of specified domain, which is number of --- its free dummy indices. */ - -int domain_arity(MPL *mpl, DOMAIN *domain) -{ DOMAIN_BLOCK *block; - DOMAIN_SLOT *slot; - int arity; - xassert(mpl == mpl); - arity = 0; - for (block = domain->list; block != NULL; block = block->next) - for (slot = block->list; slot != NULL; slot = slot->next) - if (slot->code == NULL) arity++; - return arity; -} - -/*---------------------------------------------------------------------- --- set_expression - parse set expression. --- --- This routine parses primary expression using the syntax: --- --- ::= { } --- ::= */ - -CODE *set_expression(MPL *mpl) -{ CODE *code; - OPERANDS arg; - xassert(mpl->token == T_LBRACE); - get_token(mpl /* { */); - /* check a token that follows the left brace */ - if (mpl->token == T_RBRACE) - { /* it is the right brace, so the resultant is an empty set of - dimension 1 */ - arg.list = NULL; - /* generate pseudo-code to build the resultant set */ - code = make_code(mpl, O_MAKE, &arg, A_ELEMSET, 1); - get_token(mpl /* } */); - } - else - { /* the next token begins an indexing expression */ - unget_token(mpl); - arg.loop.domain = indexing_expression(mpl); - arg.loop.x = NULL; /* integrand is not used */ - /* close the scope of the indexing expression */ - close_scope(mpl, arg.loop.domain); - /* generate pseudo-code to build the resultant set */ - code = make_code(mpl, O_BUILD, &arg, A_ELEMSET, - domain_arity(mpl, arg.loop.domain)); -#if 1 /* 07/IX-2008 */ - link_up(code); -#endif - } - return code; -} - -/*---------------------------------------------------------------------- --- branched_expression - parse conditional expression. --- --- This routine parses primary expression using the syntax: --- --- ::= --- ::= if then --- ::= if then --- else --- ::= */ - -CODE *branched_expression(MPL *mpl) -{ CODE *code, *x, *y, *z; - xassert(mpl->token == T_IF); - get_token(mpl /* if */); - /* parse that follows 'if' */ - x = expression_13(mpl); - /* convert the expression to logical type, if necessary */ - if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (x->type == A_NUMERIC) - x = make_unary(mpl, O_CVTLOG, x, A_LOGICAL, 0); - /* now the expression must be of logical type */ - if (x->type != A_LOGICAL) - error(mpl, "expression following if has invalid type"); - xassert(x->dim == 0); - /* the keyword 'then' must follow the logical expression */ - if (mpl->token != T_THEN) - error(mpl, "keyword then missing where expected"); - get_token(mpl /* then */); - /* parse that follows 'then' and check its type */ - y = expression_9(mpl); - if (!(y->type == A_NUMERIC || y->type == A_SYMBOLIC || - y->type == A_ELEMSET || y->type == A_FORMULA)) - error(mpl, "expression following then has invalid type"); - /* if the expression that follows the keyword 'then' is elemental - set, the keyword 'else' cannot be omitted; otherwise else-part - is optional */ - if (mpl->token != T_ELSE) - { if (y->type == A_ELEMSET) - error(mpl, "keyword else missing where expected"); - z = NULL; - goto skip; - } - get_token(mpl /* else */); - /* parse that follow 'else' and check its type */ - z = expression_9(mpl); - if (!(z->type == A_NUMERIC || z->type == A_SYMBOLIC || - z->type == A_ELEMSET || z->type == A_FORMULA)) - error(mpl, "expression following else has invalid type"); - /* convert to identical types, if necessary */ - if (y->type == A_FORMULA || z->type == A_FORMULA) - { if (y->type == A_SYMBOLIC) - y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); - if (y->type == A_NUMERIC) - y = make_unary(mpl, O_CVTLFM, y, A_FORMULA, 0); - if (z->type == A_SYMBOLIC) - z = make_unary(mpl, O_CVTNUM, z, A_NUMERIC, 0); - if (z->type == A_NUMERIC) - z = make_unary(mpl, O_CVTLFM, z, A_FORMULA, 0); - } - if (y->type == A_SYMBOLIC || z->type == A_SYMBOLIC) - { if (y->type == A_NUMERIC) - y = make_unary(mpl, O_CVTSYM, y, A_SYMBOLIC, 0); - if (z->type == A_NUMERIC) - z = make_unary(mpl, O_CVTSYM, z, A_SYMBOLIC, 0); - } - /* now both expressions must have identical types */ - if (y->type != z->type) - error(mpl, "expressions following then and else have incompati" - "ble types"); - /* and identical dimensions */ - if (y->dim != z->dim) - error(mpl, "expressions following then and else have different" - " dimensions %d and %d, respectively", y->dim, z->dim); -skip: /* generate pseudo-code to perform branching */ - code = make_ternary(mpl, O_FORK, x, y, z, y->type, y->dim); - return code; -} - -/*---------------------------------------------------------------------- --- primary_expression - parse primary expression. --- --- This routine parses primary expression using the syntax: --- --- ::= --- ::= Infinity --- ::= --- ::= --- ::= --- ::= [ ] --- ::= --- ::= [ ] --- ::= --- ::= [ ] --- ::= ( ) --- ::= ( ) --- ::= --- ::= { } --- ::= --- ::= --- --- For complete list of syntactic rules for see --- comments to the corresponding parsing routines. */ - -CODE *primary_expression(MPL *mpl) -{ CODE *code; - if (mpl->token == T_NUMBER) - { /* parse numeric literal */ - code = numeric_literal(mpl); - } -#if 1 /* 21/VII-2006 */ - else if (mpl->token == T_INFINITY) - { /* parse "infinity" */ - OPERANDS arg; - arg.num = DBL_MAX; - code = make_code(mpl, O_NUMBER, &arg, A_NUMERIC, 0); - get_token(mpl /* Infinity */); - } -#endif - else if (mpl->token == T_STRING) - { /* parse string literal */ - code = string_literal(mpl); - } - else if (mpl->token == T_NAME) - { int next_token; - get_token(mpl /* */); - next_token = mpl->token; - unget_token(mpl); - /* check a token that follows */ - switch (next_token) - { case T_LBRACKET: - /* parse reference to subscripted object */ - code = object_reference(mpl); - break; - case T_LEFT: - /* parse reference to built-in function */ - code = function_reference(mpl); - break; - case T_LBRACE: - /* parse iterated expression */ - code = iterated_expression(mpl); - break; - default: - /* parse reference to unsubscripted object */ - code = object_reference(mpl); - break; - } - } - else if (mpl->token == T_LEFT) - { /* parse parenthesized expression */ - code = expression_list(mpl); - } - else if (mpl->token == T_LBRACE) - { /* parse set expression */ - code = set_expression(mpl); - } - else if (mpl->token == T_IF) - { /* parse conditional expression */ - code = branched_expression(mpl); - } - else if (is_reserved(mpl)) - { /* other reserved keywords cannot be used here */ - error(mpl, "invalid use of reserved keyword %s", mpl->image); - } - else - error(mpl, "syntax error in expression"); - return code; -} - -/*---------------------------------------------------------------------- --- error_preceding - raise error if preceding operand has wrong type. --- --- This routine is called to raise error if operand that precedes some --- infix operator has invalid type. */ - -void error_preceding(MPL *mpl, char *opstr) -{ error(mpl, "operand preceding %s has invalid type", opstr); - /* no return */ -} - -/*---------------------------------------------------------------------- --- error_following - raise error if following operand has wrong type. --- --- This routine is called to raise error if operand that follows some --- infix operator has invalid type. */ - -void error_following(MPL *mpl, char *opstr) -{ error(mpl, "operand following %s has invalid type", opstr); - /* no return */ -} - -/*---------------------------------------------------------------------- --- error_dimension - raise error if operands have different dimension. --- --- This routine is called to raise error if two operands of some infix --- operator have different dimension. */ - -void error_dimension(MPL *mpl, char *opstr, int dim1, int dim2) -{ error(mpl, "operands preceding and following %s have different di" - "mensions %d and %d, respectively", opstr, dim1, dim2); - /* no return */ -} - -/*---------------------------------------------------------------------- --- expression_0 - parse expression of level 0. --- --- This routine parses expression of level 0 using the syntax: --- --- ::= */ - -CODE *expression_0(MPL *mpl) -{ CODE *code; - code = primary_expression(mpl); - return code; -} - -/*---------------------------------------------------------------------- --- expression_1 - parse expression of level 1. --- --- This routine parses expression of level 1 using the syntax: --- --- ::= --- ::= --- ::= --- ::= ^ | ** */ - -CODE *expression_1(MPL *mpl) -{ CODE *x, *y; - char opstr[8]; - x = expression_0(mpl); - if (mpl->token == T_POWER) - { strcpy(opstr, mpl->image); - xassert(strlen(opstr) < sizeof(opstr)); - if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (x->type != A_NUMERIC) - error_preceding(mpl, opstr); - get_token(mpl /* ^ | ** */); - if (mpl->token == T_PLUS || mpl->token == T_MINUS) - y = expression_2(mpl); - else - y = expression_1(mpl); - if (y->type == A_SYMBOLIC) - y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); - if (y->type != A_NUMERIC) - error_following(mpl, opstr); - x = make_binary(mpl, O_POWER, x, y, A_NUMERIC, 0); - } - return x; -} - -/*---------------------------------------------------------------------- --- expression_2 - parse expression of level 2. --- --- This routine parses expression of level 2 using the syntax: --- --- ::= --- ::= + --- ::= - */ - -CODE *expression_2(MPL *mpl) -{ CODE *x; - if (mpl->token == T_PLUS) - { get_token(mpl /* + */); - x = expression_1(mpl); - if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) - error_following(mpl, "+"); - x = make_unary(mpl, O_PLUS, x, x->type, 0); - } - else if (mpl->token == T_MINUS) - { get_token(mpl /* - */); - x = expression_1(mpl); - if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) - error_following(mpl, "-"); - x = make_unary(mpl, O_MINUS, x, x->type, 0); - } - else - x = expression_1(mpl); - return x; -} - -/*---------------------------------------------------------------------- --- expression_3 - parse expression of level 3. --- --- This routine parses expression of level 3 using the syntax: --- --- ::= --- ::= * --- ::= / --- ::= div --- ::= mod */ - -CODE *expression_3(MPL *mpl) -{ CODE *x, *y; - x = expression_2(mpl); - for (;;) - { if (mpl->token == T_ASTERISK) - { if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) - error_preceding(mpl, "*"); - get_token(mpl /* * */); - y = expression_2(mpl); - if (y->type == A_SYMBOLIC) - y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); - if (!(y->type == A_NUMERIC || y->type == A_FORMULA)) - error_following(mpl, "*"); - if (x->type == A_FORMULA && y->type == A_FORMULA) - error(mpl, "multiplication of linear forms not allowed"); - if (x->type == A_NUMERIC && y->type == A_NUMERIC) - x = make_binary(mpl, O_MUL, x, y, A_NUMERIC, 0); - else - x = make_binary(mpl, O_MUL, x, y, A_FORMULA, 0); - } - else if (mpl->token == T_SLASH) - { if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) - error_preceding(mpl, "/"); - get_token(mpl /* / */); - y = expression_2(mpl); - if (y->type == A_SYMBOLIC) - y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); - if (y->type != A_NUMERIC) - error_following(mpl, "/"); - if (x->type == A_NUMERIC) - x = make_binary(mpl, O_DIV, x, y, A_NUMERIC, 0); - else - x = make_binary(mpl, O_DIV, x, y, A_FORMULA, 0); - } - else if (mpl->token == T_DIV) - { if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (x->type != A_NUMERIC) - error_preceding(mpl, "div"); - get_token(mpl /* div */); - y = expression_2(mpl); - if (y->type == A_SYMBOLIC) - y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); - if (y->type != A_NUMERIC) - error_following(mpl, "div"); - x = make_binary(mpl, O_IDIV, x, y, A_NUMERIC, 0); - } - else if (mpl->token == T_MOD) - { if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (x->type != A_NUMERIC) - error_preceding(mpl, "mod"); - get_token(mpl /* mod */); - y = expression_2(mpl); - if (y->type == A_SYMBOLIC) - y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); - if (y->type != A_NUMERIC) - error_following(mpl, "mod"); - x = make_binary(mpl, O_MOD, x, y, A_NUMERIC, 0); - } - else - break; - } - return x; -} - -/*---------------------------------------------------------------------- --- expression_4 - parse expression of level 4. --- --- This routine parses expression of level 4 using the syntax: --- --- ::= --- ::= + --- ::= - --- ::= less */ - -CODE *expression_4(MPL *mpl) -{ CODE *x, *y; - x = expression_3(mpl); - for (;;) - { if (mpl->token == T_PLUS) - { if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) - error_preceding(mpl, "+"); - get_token(mpl /* + */); - y = expression_3(mpl); - if (y->type == A_SYMBOLIC) - y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); - if (!(y->type == A_NUMERIC || y->type == A_FORMULA)) - error_following(mpl, "+"); - if (x->type == A_NUMERIC && y->type == A_FORMULA) - x = make_unary(mpl, O_CVTLFM, x, A_FORMULA, 0); - if (x->type == A_FORMULA && y->type == A_NUMERIC) - y = make_unary(mpl, O_CVTLFM, y, A_FORMULA, 0); - x = make_binary(mpl, O_ADD, x, y, x->type, 0); - } - else if (mpl->token == T_MINUS) - { if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) - error_preceding(mpl, "-"); - get_token(mpl /* - */); - y = expression_3(mpl); - if (y->type == A_SYMBOLIC) - y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); - if (!(y->type == A_NUMERIC || y->type == A_FORMULA)) - error_following(mpl, "-"); - if (x->type == A_NUMERIC && y->type == A_FORMULA) - x = make_unary(mpl, O_CVTLFM, x, A_FORMULA, 0); - if (x->type == A_FORMULA && y->type == A_NUMERIC) - y = make_unary(mpl, O_CVTLFM, y, A_FORMULA, 0); - x = make_binary(mpl, O_SUB, x, y, x->type, 0); - } - else if (mpl->token == T_LESS) - { if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (x->type != A_NUMERIC) - error_preceding(mpl, "less"); - get_token(mpl /* less */); - y = expression_3(mpl); - if (y->type == A_SYMBOLIC) - y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); - if (y->type != A_NUMERIC) - error_following(mpl, "less"); - x = make_binary(mpl, O_LESS, x, y, A_NUMERIC, 0); - } - else - break; - } - return x; -} - -/*---------------------------------------------------------------------- --- expression_5 - parse expression of level 5. --- --- This routine parses expression of level 5 using the syntax: --- --- ::= --- ::= & */ - -CODE *expression_5(MPL *mpl) -{ CODE *x, *y; - x = expression_4(mpl); - for (;;) - { if (mpl->token == T_CONCAT) - { if (x->type == A_NUMERIC) - x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); - if (x->type != A_SYMBOLIC) - error_preceding(mpl, "&"); - get_token(mpl /* & */); - y = expression_4(mpl); - if (y->type == A_NUMERIC) - y = make_unary(mpl, O_CVTSYM, y, A_SYMBOLIC, 0); - if (y->type != A_SYMBOLIC) - error_following(mpl, "&"); - x = make_binary(mpl, O_CONCAT, x, y, A_SYMBOLIC, 0); - } - else - break; - } - return x; -} - -/*---------------------------------------------------------------------- --- expression_6 - parse expression of level 6. --- --- This routine parses expression of level 6 using the syntax: --- --- ::= --- ::= .. --- ::= .. by --- */ - -CODE *expression_6(MPL *mpl) -{ CODE *x, *y, *z; - x = expression_5(mpl); - if (mpl->token == T_DOTS) - { if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (x->type != A_NUMERIC) - error_preceding(mpl, ".."); - get_token(mpl /* .. */); - y = expression_5(mpl); - if (y->type == A_SYMBOLIC) - y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); - if (y->type != A_NUMERIC) - error_following(mpl, ".."); - if (mpl->token == T_BY) - { get_token(mpl /* by */); - z = expression_5(mpl); - if (z->type == A_SYMBOLIC) - z = make_unary(mpl, O_CVTNUM, z, A_NUMERIC, 0); - if (z->type != A_NUMERIC) - error_following(mpl, "by"); - } - else - z = NULL; - x = make_ternary(mpl, O_DOTS, x, y, z, A_ELEMSET, 1); - } - return x; -} - -/*---------------------------------------------------------------------- --- expression_7 - parse expression of level 7. --- --- This routine parses expression of level 7 using the syntax: --- --- ::= --- ::= cross */ - -CODE *expression_7(MPL *mpl) -{ CODE *x, *y; - x = expression_6(mpl); - for (;;) - { if (mpl->token == T_CROSS) - { if (x->type != A_ELEMSET) - error_preceding(mpl, "cross"); - get_token(mpl /* cross */); - y = expression_6(mpl); - if (y->type != A_ELEMSET) - error_following(mpl, "cross"); - x = make_binary(mpl, O_CROSS, x, y, A_ELEMSET, - x->dim + y->dim); - } - else - break; - } - return x; -} - -/*---------------------------------------------------------------------- --- expression_8 - parse expression of level 8. --- --- This routine parses expression of level 8 using the syntax: --- --- ::= --- ::= inter */ - -CODE *expression_8(MPL *mpl) -{ CODE *x, *y; - x = expression_7(mpl); - for (;;) - { if (mpl->token == T_INTER) - { if (x->type != A_ELEMSET) - error_preceding(mpl, "inter"); - get_token(mpl /* inter */); - y = expression_7(mpl); - if (y->type != A_ELEMSET) - error_following(mpl, "inter"); - if (x->dim != y->dim) - error_dimension(mpl, "inter", x->dim, y->dim); - x = make_binary(mpl, O_INTER, x, y, A_ELEMSET, x->dim); - } - else - break; - } - return x; -} - -/*---------------------------------------------------------------------- --- expression_9 - parse expression of level 9. --- --- This routine parses expression of level 9 using the syntax: --- --- ::= --- ::= union --- ::= diff --- ::= symdiff */ - -CODE *expression_9(MPL *mpl) -{ CODE *x, *y; - x = expression_8(mpl); - for (;;) - { if (mpl->token == T_UNION) - { if (x->type != A_ELEMSET) - error_preceding(mpl, "union"); - get_token(mpl /* union */); - y = expression_8(mpl); - if (y->type != A_ELEMSET) - error_following(mpl, "union"); - if (x->dim != y->dim) - error_dimension(mpl, "union", x->dim, y->dim); - x = make_binary(mpl, O_UNION, x, y, A_ELEMSET, x->dim); - } - else if (mpl->token == T_DIFF) - { if (x->type != A_ELEMSET) - error_preceding(mpl, "diff"); - get_token(mpl /* diff */); - y = expression_8(mpl); - if (y->type != A_ELEMSET) - error_following(mpl, "diff"); - if (x->dim != y->dim) - error_dimension(mpl, "diff", x->dim, y->dim); - x = make_binary(mpl, O_DIFF, x, y, A_ELEMSET, x->dim); - } - else if (mpl->token == T_SYMDIFF) - { if (x->type != A_ELEMSET) - error_preceding(mpl, "symdiff"); - get_token(mpl /* symdiff */); - y = expression_8(mpl); - if (y->type != A_ELEMSET) - error_following(mpl, "symdiff"); - if (x->dim != y->dim) - error_dimension(mpl, "symdiff", x->dim, y->dim); - x = make_binary(mpl, O_SYMDIFF, x, y, A_ELEMSET, x->dim); - } - else - break; - } - return x; -} - -/*---------------------------------------------------------------------- --- expression_10 - parse expression of level 10. --- --- This routine parses expression of level 10 using the syntax: --- --- ::= --- ::= --- ::= < | <= | = | == | >= | > | <> | != | in | not in | ! in | --- within | not within | ! within */ - -CODE *expression_10(MPL *mpl) -{ CODE *x, *y; - int op = -1; - char opstr[16]; - x = expression_9(mpl); - strcpy(opstr, ""); - switch (mpl->token) - { case T_LT: - op = O_LT; break; - case T_LE: - op = O_LE; break; - case T_EQ: - op = O_EQ; break; - case T_GE: - op = O_GE; break; - case T_GT: - op = O_GT; break; - case T_NE: - op = O_NE; break; - case T_IN: - op = O_IN; break; - case T_WITHIN: - op = O_WITHIN; break; - case T_NOT: - strcpy(opstr, mpl->image); - get_token(mpl /* not | ! */); - if (mpl->token == T_IN) - op = O_NOTIN; - else if (mpl->token == T_WITHIN) - op = O_NOTWITHIN; - else - error(mpl, "invalid use of %s", opstr); - strcat(opstr, " "); - break; - default: - goto done; - } - strcat(opstr, mpl->image); - xassert(strlen(opstr) < sizeof(opstr)); - switch (op) - { case O_EQ: - case O_NE: -#if 1 /* 02/VIII-2008 */ - case O_LT: - case O_LE: - case O_GT: - case O_GE: -#endif - if (!(x->type == A_NUMERIC || x->type == A_SYMBOLIC)) - error_preceding(mpl, opstr); - get_token(mpl /* */); - y = expression_9(mpl); - if (!(y->type == A_NUMERIC || y->type == A_SYMBOLIC)) - error_following(mpl, opstr); - if (x->type == A_NUMERIC && y->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); - if (x->type == A_SYMBOLIC && y->type == A_NUMERIC) - y = make_unary(mpl, O_CVTSYM, y, A_SYMBOLIC, 0); - x = make_binary(mpl, op, x, y, A_LOGICAL, 0); - break; -#if 0 /* 02/VIII-2008 */ - case O_LT: - case O_LE: - case O_GT: - case O_GE: - if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (x->type != A_NUMERIC) - error_preceding(mpl, opstr); - get_token(mpl /* */); - y = expression_9(mpl); - if (y->type == A_SYMBOLIC) - y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); - if (y->type != A_NUMERIC) - error_following(mpl, opstr); - x = make_binary(mpl, op, x, y, A_LOGICAL, 0); - break; -#endif - case O_IN: - case O_NOTIN: - if (x->type == A_NUMERIC) - x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); - if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTTUP, x, A_TUPLE, 1); - if (x->type != A_TUPLE) - error_preceding(mpl, opstr); - get_token(mpl /* */); - y = expression_9(mpl); - if (y->type != A_ELEMSET) - error_following(mpl, opstr); - if (x->dim != y->dim) - error_dimension(mpl, opstr, x->dim, y->dim); - x = make_binary(mpl, op, x, y, A_LOGICAL, 0); - break; - case O_WITHIN: - case O_NOTWITHIN: - if (x->type != A_ELEMSET) - error_preceding(mpl, opstr); - get_token(mpl /* */); - y = expression_9(mpl); - if (y->type != A_ELEMSET) - error_following(mpl, opstr); - if (x->dim != y->dim) - error_dimension(mpl, opstr, x->dim, y->dim); - x = make_binary(mpl, op, x, y, A_LOGICAL, 0); - break; - default: - xassert(op != op); - } -done: return x; -} - -/*---------------------------------------------------------------------- --- expression_11 - parse expression of level 11. --- --- This routine parses expression of level 11 using the syntax: --- --- ::= --- ::= not --- ::= ! */ - -CODE *expression_11(MPL *mpl) -{ CODE *x; - char opstr[8]; - if (mpl->token == T_NOT) - { strcpy(opstr, mpl->image); - xassert(strlen(opstr) < sizeof(opstr)); - get_token(mpl /* not | ! */); - x = expression_10(mpl); - if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (x->type == A_NUMERIC) - x = make_unary(mpl, O_CVTLOG, x, A_LOGICAL, 0); - if (x->type != A_LOGICAL) - error_following(mpl, opstr); - x = make_unary(mpl, O_NOT, x, A_LOGICAL, 0); - } - else - x = expression_10(mpl); - return x; -} - -/*---------------------------------------------------------------------- --- expression_12 - parse expression of level 12. --- --- This routine parses expression of level 12 using the syntax: --- --- ::= --- ::= and --- ::= && */ - -CODE *expression_12(MPL *mpl) -{ CODE *x, *y; - char opstr[8]; - x = expression_11(mpl); - for (;;) - { if (mpl->token == T_AND) - { strcpy(opstr, mpl->image); - xassert(strlen(opstr) < sizeof(opstr)); - if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (x->type == A_NUMERIC) - x = make_unary(mpl, O_CVTLOG, x, A_LOGICAL, 0); - if (x->type != A_LOGICAL) - error_preceding(mpl, opstr); - get_token(mpl /* and | && */); - y = expression_11(mpl); - if (y->type == A_SYMBOLIC) - y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); - if (y->type == A_NUMERIC) - y = make_unary(mpl, O_CVTLOG, y, A_LOGICAL, 0); - if (y->type != A_LOGICAL) - error_following(mpl, opstr); - x = make_binary(mpl, O_AND, x, y, A_LOGICAL, 0); - } - else - break; - } - return x; -} - -/*---------------------------------------------------------------------- --- expression_13 - parse expression of level 13. --- --- This routine parses expression of level 13 using the syntax: --- --- ::= --- ::= or --- ::= || */ - -CODE *expression_13(MPL *mpl) -{ CODE *x, *y; - char opstr[8]; - x = expression_12(mpl); - for (;;) - { if (mpl->token == T_OR) - { strcpy(opstr, mpl->image); - xassert(strlen(opstr) < sizeof(opstr)); - if (x->type == A_SYMBOLIC) - x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); - if (x->type == A_NUMERIC) - x = make_unary(mpl, O_CVTLOG, x, A_LOGICAL, 0); - if (x->type != A_LOGICAL) - error_preceding(mpl, opstr); - get_token(mpl /* or | || */); - y = expression_12(mpl); - if (y->type == A_SYMBOLIC) - y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); - if (y->type == A_NUMERIC) - y = make_unary(mpl, O_CVTLOG, y, A_LOGICAL, 0); - if (y->type != A_LOGICAL) - error_following(mpl, opstr); - x = make_binary(mpl, O_OR, x, y, A_LOGICAL, 0); - } - else - break; - } - return x; -} - -/*---------------------------------------------------------------------- --- set_statement - parse set statement. --- --- This routine parses set statement using the syntax: --- --- ::= set --- ; --- ::= --- ::= --- ::= --- ::= --- ::= --- ::= , dimen --- ::= , within --- ::= , := --- ::= , default --- --- Commae in are optional and may be omitted anywhere. */ - -SET *set_statement(MPL *mpl) -{ SET *set; - int dimen_used = 0; - xassert(is_keyword(mpl, "set")); - get_token(mpl /* set */); - /* symbolic name must follow the keyword 'set' */ - if (mpl->token == T_NAME) - ; - else if (is_reserved(mpl)) - error(mpl, "invalid use of reserved keyword %s", mpl->image); - else - error(mpl, "symbolic name missing where expected"); - /* there must be no other object with the same name */ - if (avl_find_node(mpl->tree, mpl->image) != NULL) - error(mpl, "%s multiply declared", mpl->image); - /* create model set */ - set = alloc(SET); - set->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(set->name, mpl->image); - set->alias = NULL; - set->dim = 0; - set->domain = NULL; - set->dimen = 0; - set->within = NULL; - set->assign = NULL; - set->option = NULL; - set->gadget = NULL; - set->data = 0; - set->array = NULL; - get_token(mpl /* */); - /* parse optional alias */ - if (mpl->token == T_STRING) - { set->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(set->alias, mpl->image); - get_token(mpl /* */); - } - /* parse optional indexing expression */ - if (mpl->token == T_LBRACE) - { set->domain = indexing_expression(mpl); - set->dim = domain_arity(mpl, set->domain); - } - /* include the set name in the symbolic names table */ - { AVLNODE *node; - node = avl_insert_node(mpl->tree, set->name); - avl_set_node_type(node, A_SET); - avl_set_node_link(node, (void *)set); - } - /* parse the list of optional attributes */ - for (;;) - { if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else if (mpl->token == T_SEMICOLON) - break; - if (is_keyword(mpl, "dimen")) - { /* dimension of set members */ - int dimen; - get_token(mpl /* dimen */); - if (!(mpl->token == T_NUMBER && - 1.0 <= mpl->value && mpl->value <= 20.0 && - floor(mpl->value) == mpl->value)) - error(mpl, "dimension must be integer between 1 and 20"); - dimen = (int)(mpl->value + 0.5); - if (dimen_used) - error(mpl, "at most one dimension attribute allowed"); - if (set->dimen > 0) - error(mpl, "dimension %d conflicts with dimension %d alr" - "eady determined", dimen, set->dimen); - set->dimen = dimen; - dimen_used = 1; - get_token(mpl /* */); - } - else if (mpl->token == T_WITHIN || mpl->token == T_IN) - { /* restricting superset */ - WITHIN *within, *temp; - if (mpl->token == T_IN && !mpl->as_within) - { warning(mpl, "keyword in understood as within"); - mpl->as_within = 1; - } - get_token(mpl /* within */); - /* create new restricting superset list entry and append it - to the within-list */ - within = alloc(WITHIN); - within->code = NULL; - within->next = NULL; - if (set->within == NULL) - set->within = within; - else - { for (temp = set->within; temp->next != NULL; temp = - temp->next); - temp->next = within; - } - /* parse an expression that follows 'within' */ - within->code = expression_9(mpl); - if (within->code->type != A_ELEMSET) - error(mpl, "expression following within has invalid type" - ); - xassert(within->code->dim > 0); - /* check/set dimension of set members */ - if (set->dimen == 0) set->dimen = within->code->dim; - if (set->dimen != within->code->dim) - error(mpl, "set expression following within must have di" - "mension %d rather than %d", - set->dimen, within->code->dim); - } - else if (mpl->token == T_ASSIGN) - { /* assignment expression */ - if (!(set->assign == NULL && set->option == NULL && - set->gadget == NULL)) -err: error(mpl, "at most one := or default/data allowed"); - get_token(mpl /* := */); - /* parse an expression that follows ':=' */ - set->assign = expression_9(mpl); - if (set->assign->type != A_ELEMSET) - error(mpl, "expression following := has invalid type"); - xassert(set->assign->dim > 0); - /* check/set dimension of set members */ - if (set->dimen == 0) set->dimen = set->assign->dim; - if (set->dimen != set->assign->dim) - error(mpl, "set expression following := must have dimens" - "ion %d rather than %d", - set->dimen, set->assign->dim); - } - else if (is_keyword(mpl, "default")) - { /* expression for default value */ - if (!(set->assign == NULL && set->option == NULL)) goto err; - get_token(mpl /* := */); - /* parse an expression that follows 'default' */ - set->option = expression_9(mpl); - if (set->option->type != A_ELEMSET) - error(mpl, "expression following default has invalid typ" - "e"); - xassert(set->option->dim > 0); - /* check/set dimension of set members */ - if (set->dimen == 0) set->dimen = set->option->dim; - if (set->dimen != set->option->dim) - error(mpl, "set expression following default must have d" - "imension %d rather than %d", - set->dimen, set->option->dim); - } -#if 1 /* 12/XII-2008 */ - else if (is_keyword(mpl, "data")) - { /* gadget to initialize the set by data from plain set */ - GADGET *gadget; - AVLNODE *node; - int i, k, fff[20]; - if (!(set->assign == NULL && set->gadget == NULL)) goto err; - get_token(mpl /* data */); - set->gadget = gadget = alloc(GADGET); - /* set name must follow the keyword 'data' */ - if (mpl->token == T_NAME) - ; - else if (is_reserved(mpl)) - error(mpl, "invalid use of reserved keyword %s", - mpl->image); - else - error(mpl, "set name missing where expected"); - /* find the set in the symbolic name table */ - node = avl_find_node(mpl->tree, mpl->image); - if (node == NULL) - error(mpl, "%s not defined", mpl->image); - if (avl_get_node_type(node) != A_SET) -err1: error(mpl, "%s not a plain set", mpl->image); - gadget->set = avl_get_node_link(node); - if (gadget->set->dim != 0) goto err1; - if (gadget->set == set) - error(mpl, "set cannot be initialized by itself"); - /* check and set dimensions */ - if (set->dim >= gadget->set->dimen) -err2: error(mpl, "dimension of %s too small", mpl->image); - if (set->dimen == 0) - set->dimen = gadget->set->dimen - set->dim; - if (set->dim + set->dimen > gadget->set->dimen) - goto err2; - else if (set->dim + set->dimen < gadget->set->dimen) - error(mpl, "dimension of %s too big", mpl->image); - get_token(mpl /* set name */); - /* left parenthesis must follow the set name */ - if (mpl->token == T_LEFT) - get_token(mpl /* ( */); - else - error(mpl, "left parenthesis missing where expected"); - /* parse permutation of component numbers */ - for (k = 0; k < gadget->set->dimen; k++) fff[k] = 0; - k = 0; - for (;;) - { if (mpl->token != T_NUMBER) - error(mpl, "component number missing where expected"); - if (str2int(mpl->image, &i) != 0) -err3: error(mpl, "component number must be integer between " - "1 and %d", gadget->set->dimen); - if (!(1 <= i && i <= gadget->set->dimen)) goto err3; - if (fff[i-1] != 0) - error(mpl, "component %d multiply specified", i); - gadget->ind[k++] = i, fff[i-1] = 1; - xassert(k <= gadget->set->dimen); - get_token(mpl /* number */); - if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else if (mpl->token == T_RIGHT) - break; - else - error(mpl, "syntax error in data attribute"); - } - if (k < gadget->set->dimen) - error(mpl, "there are must be %d components rather than " - "%d", gadget->set->dimen, k); - get_token(mpl /* ) */); - } -#endif - else - error(mpl, "syntax error in set statement"); - } - /* close the domain scope */ - if (set->domain != NULL) close_scope(mpl, set->domain); - /* if dimension of set members is still unknown, set it to 1 */ - if (set->dimen == 0) set->dimen = 1; - /* the set statement has been completely parsed */ - xassert(mpl->token == T_SEMICOLON); - get_token(mpl /* ; */); - return set; -} - -/*---------------------------------------------------------------------- --- parameter_statement - parse parameter statement. --- --- This routine parses parameter statement using the syntax: --- --- ::= param --- ; --- ::= --- ::= --- ::= --- ::= --- ::= --- ::= , integer --- ::= , binary --- ::= , symbolic --- ::= , --- ::= , in --- ::= , := --- ::= , default --- ::= < | <= | = | == | >= | > | <> | != --- --- Commae in are optional and may be omitted anywhere. */ - -PARAMETER *parameter_statement(MPL *mpl) -{ PARAMETER *par; - int integer_used = 0, binary_used = 0, symbolic_used = 0; - xassert(is_keyword(mpl, "param")); - get_token(mpl /* param */); - /* symbolic name must follow the keyword 'param' */ - if (mpl->token == T_NAME) - ; - else if (is_reserved(mpl)) - error(mpl, "invalid use of reserved keyword %s", mpl->image); - else - error(mpl, "symbolic name missing where expected"); - /* there must be no other object with the same name */ - if (avl_find_node(mpl->tree, mpl->image) != NULL) - error(mpl, "%s multiply declared", mpl->image); - /* create model parameter */ - par = alloc(PARAMETER); - par->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(par->name, mpl->image); - par->alias = NULL; - par->dim = 0; - par->domain = NULL; - par->type = A_NUMERIC; - par->cond = NULL; - par->in = NULL; - par->assign = NULL; - par->option = NULL; - par->data = 0; - par->defval = NULL; - par->array = NULL; - get_token(mpl /* */); - /* parse optional alias */ - if (mpl->token == T_STRING) - { par->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(par->alias, mpl->image); - get_token(mpl /* */); - } - /* parse optional indexing expression */ - if (mpl->token == T_LBRACE) - { par->domain = indexing_expression(mpl); - par->dim = domain_arity(mpl, par->domain); - } - /* include the parameter name in the symbolic names table */ - { AVLNODE *node; - node = avl_insert_node(mpl->tree, par->name); - avl_set_node_type(node, A_PARAMETER); - avl_set_node_link(node, (void *)par); - } - /* parse the list of optional attributes */ - for (;;) - { if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else if (mpl->token == T_SEMICOLON) - break; - if (is_keyword(mpl, "integer")) - { if (integer_used) - error(mpl, "at most one integer allowed"); - if (par->type == A_SYMBOLIC) - error(mpl, "symbolic parameter cannot be integer"); - if (par->type != A_BINARY) par->type = A_INTEGER; - integer_used = 1; - get_token(mpl /* integer */); - } - else if (is_keyword(mpl, "binary")) -bin: { if (binary_used) - error(mpl, "at most one binary allowed"); - if (par->type == A_SYMBOLIC) - error(mpl, "symbolic parameter cannot be binary"); - par->type = A_BINARY; - binary_used = 1; - get_token(mpl /* binary */); - } - else if (is_keyword(mpl, "logical")) - { if (!mpl->as_binary) - { warning(mpl, "keyword logical understood as binary"); - mpl->as_binary = 1; - } - goto bin; - } - else if (is_keyword(mpl, "symbolic")) - { if (symbolic_used) - error(mpl, "at most one symbolic allowed"); - if (par->type != A_NUMERIC) - error(mpl, "integer or binary parameter cannot be symbol" - "ic"); - /* the parameter may be referenced from expressions given - in the same parameter declaration, so its type must be - completed before parsing that expressions */ - if (!(par->cond == NULL && par->in == NULL && - par->assign == NULL && par->option == NULL)) - error(mpl, "keyword symbolic must precede any other para" - "meter attributes"); - par->type = A_SYMBOLIC; - symbolic_used = 1; - get_token(mpl /* symbolic */); - } - else if (mpl->token == T_LT || mpl->token == T_LE || - mpl->token == T_EQ || mpl->token == T_GE || - mpl->token == T_GT || mpl->token == T_NE) - { /* restricting condition */ - CONDITION *cond, *temp; - char opstr[8]; - /* create new restricting condition list entry and append - it to the conditions list */ - cond = alloc(CONDITION); - switch (mpl->token) - { case T_LT: - cond->rho = O_LT, strcpy(opstr, mpl->image); break; - case T_LE: - cond->rho = O_LE, strcpy(opstr, mpl->image); break; - case T_EQ: - cond->rho = O_EQ, strcpy(opstr, mpl->image); break; - case T_GE: - cond->rho = O_GE, strcpy(opstr, mpl->image); break; - case T_GT: - cond->rho = O_GT, strcpy(opstr, mpl->image); break; - case T_NE: - cond->rho = O_NE, strcpy(opstr, mpl->image); break; - default: - xassert(mpl->token != mpl->token); - } - xassert(strlen(opstr) < sizeof(opstr)); - cond->code = NULL; - cond->next = NULL; - if (par->cond == NULL) - par->cond = cond; - else - { for (temp = par->cond; temp->next != NULL; temp = - temp->next); - temp->next = cond; - } -#if 0 /* 13/VIII-2008 */ - if (par->type == A_SYMBOLIC && - !(cond->rho == O_EQ || cond->rho == O_NE)) - error(mpl, "inequality restriction not allowed"); -#endif - get_token(mpl /* rho */); - /* parse an expression that follows relational operator */ - cond->code = expression_5(mpl); - if (!(cond->code->type == A_NUMERIC || - cond->code->type == A_SYMBOLIC)) - error(mpl, "expression following %s has invalid type", - opstr); - xassert(cond->code->dim == 0); - /* convert to the parameter type, if necessary */ - if (par->type != A_SYMBOLIC && cond->code->type == - A_SYMBOLIC) - cond->code = make_unary(mpl, O_CVTNUM, cond->code, - A_NUMERIC, 0); - if (par->type == A_SYMBOLIC && cond->code->type != - A_SYMBOLIC) - cond->code = make_unary(mpl, O_CVTSYM, cond->code, - A_SYMBOLIC, 0); - } - else if (mpl->token == T_IN || mpl->token == T_WITHIN) - { /* restricting superset */ - WITHIN *in, *temp; - if (mpl->token == T_WITHIN && !mpl->as_in) - { warning(mpl, "keyword within understood as in"); - mpl->as_in = 1; - } - get_token(mpl /* in */); - /* create new restricting superset list entry and append it - to the in-list */ - in = alloc(WITHIN); - in->code = NULL; - in->next = NULL; - if (par->in == NULL) - par->in = in; - else - { for (temp = par->in; temp->next != NULL; temp = - temp->next); - temp->next = in; - } - /* parse an expression that follows 'in' */ - in->code = expression_9(mpl); - if (in->code->type != A_ELEMSET) - error(mpl, "expression following in has invalid type"); - xassert(in->code->dim > 0); - if (in->code->dim != 1) - error(mpl, "set expression following in must have dimens" - "ion 1 rather than %d", in->code->dim); - } - else if (mpl->token == T_ASSIGN) - { /* assignment expression */ - if (!(par->assign == NULL && par->option == NULL)) -err: error(mpl, "at most one := or default allowed"); - get_token(mpl /* := */); - /* parse an expression that follows ':=' */ - par->assign = expression_5(mpl); - /* the expression must be of numeric/symbolic type */ - if (!(par->assign->type == A_NUMERIC || - par->assign->type == A_SYMBOLIC)) - error(mpl, "expression following := has invalid type"); - xassert(par->assign->dim == 0); - /* convert to the parameter type, if necessary */ - if (par->type != A_SYMBOLIC && par->assign->type == - A_SYMBOLIC) - par->assign = make_unary(mpl, O_CVTNUM, par->assign, - A_NUMERIC, 0); - if (par->type == A_SYMBOLIC && par->assign->type != - A_SYMBOLIC) - par->assign = make_unary(mpl, O_CVTSYM, par->assign, - A_SYMBOLIC, 0); - } - else if (is_keyword(mpl, "default")) - { /* expression for default value */ - if (!(par->assign == NULL && par->option == NULL)) goto err; - get_token(mpl /* default */); - /* parse an expression that follows 'default' */ - par->option = expression_5(mpl); - if (!(par->option->type == A_NUMERIC || - par->option->type == A_SYMBOLIC)) - error(mpl, "expression following default has invalid typ" - "e"); - xassert(par->option->dim == 0); - /* convert to the parameter type, if necessary */ - if (par->type != A_SYMBOLIC && par->option->type == - A_SYMBOLIC) - par->option = make_unary(mpl, O_CVTNUM, par->option, - A_NUMERIC, 0); - if (par->type == A_SYMBOLIC && par->option->type != - A_SYMBOLIC) - par->option = make_unary(mpl, O_CVTSYM, par->option, - A_SYMBOLIC, 0); - } - else - error(mpl, "syntax error in parameter statement"); - } - /* close the domain scope */ - if (par->domain != NULL) close_scope(mpl, par->domain); - /* the parameter statement has been completely parsed */ - xassert(mpl->token == T_SEMICOLON); - get_token(mpl /* ; */); - return par; -} - -/*---------------------------------------------------------------------- --- variable_statement - parse variable statement. --- --- This routine parses variable statement using the syntax: --- --- ::= var --- ; --- ::= --- ::= --- ::= --- ::= --- ::= --- ::= , integer --- ::= , binary --- ::= , --- ::= >= | <= | = | == --- --- Commae in are optional and may be omitted anywhere. */ - -VARIABLE *variable_statement(MPL *mpl) -{ VARIABLE *var; - int integer_used = 0, binary_used = 0; - xassert(is_keyword(mpl, "var")); - if (mpl->flag_s) - error(mpl, "variable statement must precede solve statement"); - get_token(mpl /* var */); - /* symbolic name must follow the keyword 'var' */ - if (mpl->token == T_NAME) - ; - else if (is_reserved(mpl)) - error(mpl, "invalid use of reserved keyword %s", mpl->image); - else - error(mpl, "symbolic name missing where expected"); - /* there must be no other object with the same name */ - if (avl_find_node(mpl->tree, mpl->image) != NULL) - error(mpl, "%s multiply declared", mpl->image); - /* create model variable */ - var = alloc(VARIABLE); - var->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(var->name, mpl->image); - var->alias = NULL; - var->dim = 0; - var->domain = NULL; - var->type = A_NUMERIC; - var->lbnd = NULL; - var->ubnd = NULL; - var->array = NULL; - get_token(mpl /* */); - /* parse optional alias */ - if (mpl->token == T_STRING) - { var->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(var->alias, mpl->image); - get_token(mpl /* */); - } - /* parse optional indexing expression */ - if (mpl->token == T_LBRACE) - { var->domain = indexing_expression(mpl); - var->dim = domain_arity(mpl, var->domain); - } - /* include the variable name in the symbolic names table */ - { AVLNODE *node; - node = avl_insert_node(mpl->tree, var->name); - avl_set_node_type(node, A_VARIABLE); - avl_set_node_link(node, (void *)var); - } - /* parse the list of optional attributes */ - for (;;) - { if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else if (mpl->token == T_SEMICOLON) - break; - if (is_keyword(mpl, "integer")) - { if (integer_used) - error(mpl, "at most one integer allowed"); - if (var->type != A_BINARY) var->type = A_INTEGER; - integer_used = 1; - get_token(mpl /* integer */); - } - else if (is_keyword(mpl, "binary")) -bin: { if (binary_used) - error(mpl, "at most one binary allowed"); - var->type = A_BINARY; - binary_used = 1; - get_token(mpl /* binary */); - } - else if (is_keyword(mpl, "logical")) - { if (!mpl->as_binary) - { warning(mpl, "keyword logical understood as binary"); - mpl->as_binary = 1; - } - goto bin; - } - else if (is_keyword(mpl, "symbolic")) - error(mpl, "variable cannot be symbolic"); - else if (mpl->token == T_GE) - { /* lower bound */ - if (var->lbnd != NULL) - { if (var->lbnd == var->ubnd) - error(mpl, "both fixed value and lower bound not allo" - "wed"); - else - error(mpl, "at most one lower bound allowed"); - } - get_token(mpl /* >= */); - /* parse an expression that specifies the lower bound */ - var->lbnd = expression_5(mpl); - if (var->lbnd->type == A_SYMBOLIC) - var->lbnd = make_unary(mpl, O_CVTNUM, var->lbnd, - A_NUMERIC, 0); - if (var->lbnd->type != A_NUMERIC) - error(mpl, "expression following >= has invalid type"); - xassert(var->lbnd->dim == 0); - } - else if (mpl->token == T_LE) - { /* upper bound */ - if (var->ubnd != NULL) - { if (var->ubnd == var->lbnd) - error(mpl, "both fixed value and upper bound not allo" - "wed"); - else - error(mpl, "at most one upper bound allowed"); - } - get_token(mpl /* <= */); - /* parse an expression that specifies the upper bound */ - var->ubnd = expression_5(mpl); - if (var->ubnd->type == A_SYMBOLIC) - var->ubnd = make_unary(mpl, O_CVTNUM, var->ubnd, - A_NUMERIC, 0); - if (var->ubnd->type != A_NUMERIC) - error(mpl, "expression following <= has invalid type"); - xassert(var->ubnd->dim == 0); - } - else if (mpl->token == T_EQ) - { /* fixed value */ - char opstr[8]; - if (!(var->lbnd == NULL && var->ubnd == NULL)) - { if (var->lbnd == var->ubnd) - error(mpl, "at most one fixed value allowed"); - else if (var->lbnd != NULL) - error(mpl, "both lower bound and fixed value not allo" - "wed"); - else - error(mpl, "both upper bound and fixed value not allo" - "wed"); - } - strcpy(opstr, mpl->image); - xassert(strlen(opstr) < sizeof(opstr)); - get_token(mpl /* = | == */); - /* parse an expression that specifies the fixed value */ - var->lbnd = expression_5(mpl); - if (var->lbnd->type == A_SYMBOLIC) - var->lbnd = make_unary(mpl, O_CVTNUM, var->lbnd, - A_NUMERIC, 0); - if (var->lbnd->type != A_NUMERIC) - error(mpl, "expression following %s has invalid type", - opstr); - xassert(var->lbnd->dim == 0); - /* indicate that the variable is fixed, not bounded */ - var->ubnd = var->lbnd; - } - else if (mpl->token == T_LT || mpl->token == T_GT || - mpl->token == T_NE) - error(mpl, "strict bound not allowed"); - else - error(mpl, "syntax error in variable statement"); - } - /* close the domain scope */ - if (var->domain != NULL) close_scope(mpl, var->domain); - /* the variable statement has been completely parsed */ - xassert(mpl->token == T_SEMICOLON); - get_token(mpl /* ; */); - return var; -} - -/*---------------------------------------------------------------------- --- constraint_statement - parse constraint statement. --- --- This routine parses constraint statement using the syntax: --- --- ::= --- : ; --- ::= --- ::= subject to --- ::= subj to --- ::= s.t. --- ::= --- ::= --- ::= --- ::= --- ::= , >= --- ::= , <= --- ::= , = --- ::= , <= , <= --- ::= , >= , >= --- ::= --- --- Commae in are optional and may be omitted anywhere. */ - -CONSTRAINT *constraint_statement(MPL *mpl) -{ CONSTRAINT *con; - CODE *first, *second, *third; - int rho; - char opstr[8]; - if (mpl->flag_s) - error(mpl, "constraint statement must precede solve statement") - ; - if (is_keyword(mpl, "subject")) - { get_token(mpl /* subject */); - if (!is_keyword(mpl, "to")) - error(mpl, "keyword subject to incomplete"); - get_token(mpl /* to */); - } - else if (is_keyword(mpl, "subj")) - { get_token(mpl /* subj */); - if (!is_keyword(mpl, "to")) - error(mpl, "keyword subj to incomplete"); - get_token(mpl /* to */); - } - else if (mpl->token == T_SPTP) - get_token(mpl /* s.t. */); - /* the current token must be symbolic name of constraint */ - if (mpl->token == T_NAME) - ; - else if (is_reserved(mpl)) - error(mpl, "invalid use of reserved keyword %s", mpl->image); - else - error(mpl, "symbolic name missing where expected"); - /* there must be no other object with the same name */ - if (avl_find_node(mpl->tree, mpl->image) != NULL) - error(mpl, "%s multiply declared", mpl->image); - /* create model constraint */ - con = alloc(CONSTRAINT); - con->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(con->name, mpl->image); - con->alias = NULL; - con->dim = 0; - con->domain = NULL; - con->type = A_CONSTRAINT; - con->code = NULL; - con->lbnd = NULL; - con->ubnd = NULL; - con->array = NULL; - get_token(mpl /* */); - /* parse optional alias */ - if (mpl->token == T_STRING) - { con->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(con->alias, mpl->image); - get_token(mpl /* */); - } - /* parse optional indexing expression */ - if (mpl->token == T_LBRACE) - { con->domain = indexing_expression(mpl); - con->dim = domain_arity(mpl, con->domain); - } - /* include the constraint name in the symbolic names table */ - { AVLNODE *node; - node = avl_insert_node(mpl->tree, con->name); - avl_set_node_type(node, A_CONSTRAINT); - avl_set_node_link(node, (void *)con); - } - /* the colon must precede the first expression */ - if (mpl->token != T_COLON) - error(mpl, "colon missing where expected"); - get_token(mpl /* : */); - /* parse the first expression */ - first = expression_5(mpl); - if (first->type == A_SYMBOLIC) - first = make_unary(mpl, O_CVTNUM, first, A_NUMERIC, 0); - if (!(first->type == A_NUMERIC || first->type == A_FORMULA)) - error(mpl, "expression following colon has invalid type"); - xassert(first->dim == 0); - /* relational operator must follow the first expression */ - if (mpl->token == T_COMMA) get_token(mpl /* , */); - switch (mpl->token) - { case T_LE: - case T_GE: - case T_EQ: - break; - case T_LT: - case T_GT: - case T_NE: - error(mpl, "strict inequality not allowed"); - case T_SEMICOLON: - error(mpl, "constraint must be equality or inequality"); - default: - goto err; - } - rho = mpl->token; - strcpy(opstr, mpl->image); - xassert(strlen(opstr) < sizeof(opstr)); - get_token(mpl /* rho */); - /* parse the second expression */ - second = expression_5(mpl); - if (second->type == A_SYMBOLIC) - second = make_unary(mpl, O_CVTNUM, second, A_NUMERIC, 0); - if (!(second->type == A_NUMERIC || second->type == A_FORMULA)) - error(mpl, "expression following %s has invalid type", opstr); - xassert(second->dim == 0); - /* check a token that follow the second expression */ - if (mpl->token == T_COMMA) - { get_token(mpl /* , */); - if (mpl->token == T_SEMICOLON) goto err; - } - if (mpl->token == T_LT || mpl->token == T_LE || - mpl->token == T_EQ || mpl->token == T_GE || - mpl->token == T_GT || mpl->token == T_NE) - { /* it is another relational operator, therefore the constraint - is double inequality */ - if (rho == T_EQ || mpl->token != rho) - error(mpl, "double inequality must be ... <= ... <= ... or " - "... >= ... >= ..."); - /* the first expression cannot be linear form */ - if (first->type == A_FORMULA) - error(mpl, "leftmost expression in double inequality cannot" - " be linear form"); - get_token(mpl /* rho */); - /* parse the third expression */ - third = expression_5(mpl); - if (third->type == A_SYMBOLIC) - third = make_unary(mpl, O_CVTNUM, second, A_NUMERIC, 0); - if (!(third->type == A_NUMERIC || third->type == A_FORMULA)) - error(mpl, "rightmost expression in double inequality const" - "raint has invalid type"); - xassert(third->dim == 0); - /* the third expression also cannot be linear form */ - if (third->type == A_FORMULA) - error(mpl, "rightmost expression in double inequality canno" - "t be linear form"); - } - else - { /* the constraint is equality or single inequality */ - third = NULL; - } - /* close the domain scope */ - if (con->domain != NULL) close_scope(mpl, con->domain); - /* convert all expressions to linear form, if necessary */ - if (first->type != A_FORMULA) - first = make_unary(mpl, O_CVTLFM, first, A_FORMULA, 0); - if (second->type != A_FORMULA) - second = make_unary(mpl, O_CVTLFM, second, A_FORMULA, 0); - if (third != NULL) - third = make_unary(mpl, O_CVTLFM, third, A_FORMULA, 0); - /* arrange expressions in the constraint */ - if (third == NULL) - { /* the constraint is equality or single inequality */ - switch (rho) - { case T_LE: - /* first <= second */ - con->code = first; - con->lbnd = NULL; - con->ubnd = second; - break; - case T_GE: - /* first >= second */ - con->code = first; - con->lbnd = second; - con->ubnd = NULL; - break; - case T_EQ: - /* first = second */ - con->code = first; - con->lbnd = second; - con->ubnd = second; - break; - default: - xassert(rho != rho); - } - } - else - { /* the constraint is double inequality */ - switch (rho) - { case T_LE: - /* first <= second <= third */ - con->code = second; - con->lbnd = first; - con->ubnd = third; - break; - case T_GE: - /* first >= second >= third */ - con->code = second; - con->lbnd = third; - con->ubnd = first; - break; - default: - xassert(rho != rho); - } - } - /* the constraint statement has been completely parsed */ - if (mpl->token != T_SEMICOLON) -err: error(mpl, "syntax error in constraint statement"); - get_token(mpl /* ; */); - return con; -} - -/*---------------------------------------------------------------------- --- objective_statement - parse objective statement. --- --- This routine parses objective statement using the syntax: --- --- ::= : --- ; --- ::= minimize --- ::= maximize --- ::= --- ::= --- ::= --- ::= --- ::= */ - -CONSTRAINT *objective_statement(MPL *mpl) -{ CONSTRAINT *obj; - int type; - if (is_keyword(mpl, "minimize")) - type = A_MINIMIZE; - else if (is_keyword(mpl, "maximize")) - type = A_MAXIMIZE; - else - xassert(mpl != mpl); - if (mpl->flag_s) - error(mpl, "objective statement must precede solve statement"); - get_token(mpl /* minimize | maximize */); - /* symbolic name must follow the verb 'minimize' or 'maximize' */ - if (mpl->token == T_NAME) - ; - else if (is_reserved(mpl)) - error(mpl, "invalid use of reserved keyword %s", mpl->image); - else - error(mpl, "symbolic name missing where expected"); - /* there must be no other object with the same name */ - if (avl_find_node(mpl->tree, mpl->image) != NULL) - error(mpl, "%s multiply declared", mpl->image); - /* create model objective */ - obj = alloc(CONSTRAINT); - obj->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(obj->name, mpl->image); - obj->alias = NULL; - obj->dim = 0; - obj->domain = NULL; - obj->type = type; - obj->code = NULL; - obj->lbnd = NULL; - obj->ubnd = NULL; - obj->array = NULL; - get_token(mpl /* */); - /* parse optional alias */ - if (mpl->token == T_STRING) - { obj->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(obj->alias, mpl->image); - get_token(mpl /* */); - } - /* parse optional indexing expression */ - if (mpl->token == T_LBRACE) - { obj->domain = indexing_expression(mpl); - obj->dim = domain_arity(mpl, obj->domain); - } - /* include the constraint name in the symbolic names table */ - { AVLNODE *node; - node = avl_insert_node(mpl->tree, obj->name); - avl_set_node_type(node, A_CONSTRAINT); - avl_set_node_link(node, (void *)obj); - } - /* the colon must precede the objective expression */ - if (mpl->token != T_COLON) - error(mpl, "colon missing where expected"); - get_token(mpl /* : */); - /* parse the objective expression */ - obj->code = expression_5(mpl); - if (obj->code->type == A_SYMBOLIC) - obj->code = make_unary(mpl, O_CVTNUM, obj->code, A_NUMERIC, 0); - if (obj->code->type == A_NUMERIC) - obj->code = make_unary(mpl, O_CVTLFM, obj->code, A_FORMULA, 0); - if (obj->code->type != A_FORMULA) - error(mpl, "expression following colon has invalid type"); - xassert(obj->code->dim == 0); - /* close the domain scope */ - if (obj->domain != NULL) close_scope(mpl, obj->domain); - /* the objective statement has been completely parsed */ - if (mpl->token != T_SEMICOLON) - error(mpl, "syntax error in objective statement"); - get_token(mpl /* ; */); - return obj; -} - -#if 1 /* 11/II-2008 */ -/*********************************************************************** -* table_statement - parse table statement -* -* This routine parses table statement using the syntax: -* -*
  • ::= -*
    ::= -* -* ::= -* table
    IN : -* [ ] , ; -* ::= -* ::= -* ::= -* ::= -* ::= , -* ::= -* ::= <- -* ::= -* ::= , -* ::= -* ::= , -* ::= -* ::= ~ -* -* ::= -* table
    OUT : -* ; -* ::= -* ::= -* ::= , -* ::= -* ::= ~ */ - -TABLE *table_statement(MPL *mpl) -{ TABLE *tab; - TABARG *last_arg, *arg; - TABFLD *last_fld, *fld; - TABIN *last_in, *in; - TABOUT *last_out, *out; - AVLNODE *node; - int nflds; - char name[MAX_LENGTH+1]; - xassert(is_keyword(mpl, "table")); - get_token(mpl /* solve */); - /* symbolic name must follow the keyword table */ - if (mpl->token == T_NAME) - ; - else if (is_reserved(mpl)) - error(mpl, "invalid use of reserved keyword %s", mpl->image); - else - error(mpl, "symbolic name missing where expected"); - /* there must be no other object with the same name */ - if (avl_find_node(mpl->tree, mpl->image) != NULL) - error(mpl, "%s multiply declared", mpl->image); - /* create data table */ - tab = alloc(TABLE); - tab->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(tab->name, mpl->image); - get_token(mpl /* */); - /* parse optional alias */ - if (mpl->token == T_STRING) - { tab->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(tab->alias, mpl->image); - get_token(mpl /* */); - } - else - tab->alias = NULL; - /* parse optional indexing expression */ - if (mpl->token == T_LBRACE) - { /* this is output table */ - tab->type = A_OUTPUT; - tab->u.out.domain = indexing_expression(mpl); - if (!is_keyword(mpl, "OUT")) - error(mpl, "keyword OUT missing where expected"); - get_token(mpl /* OUT */); - } - else - { /* this is input table */ - tab->type = A_INPUT; - if (!is_keyword(mpl, "IN")) - error(mpl, "keyword IN missing where expected"); - get_token(mpl /* IN */); - } - /* parse argument list */ - tab->arg = last_arg = NULL; - for (;;) - { /* create argument list entry */ - arg = alloc(TABARG); - /* parse argument expression */ - if (mpl->token == T_COMMA || mpl->token == T_COLON || - mpl->token == T_SEMICOLON) - error(mpl, "argument expression missing where expected"); - arg->code = expression_5(mpl); - /* convert the result to symbolic type, if necessary */ - if (arg->code->type == A_NUMERIC) - arg->code = - make_unary(mpl, O_CVTSYM, arg->code, A_SYMBOLIC, 0); - /* check that now the result is of symbolic type */ - if (arg->code->type != A_SYMBOLIC) - error(mpl, "argument expression has invalid type"); - /* add the entry to the end of the list */ - arg->next = NULL; - if (last_arg == NULL) - tab->arg = arg; - else - last_arg->next = arg; - last_arg = arg; - /* argument expression has been parsed */ - if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else if (mpl->token == T_COLON || mpl->token == T_SEMICOLON) - break; - } - xassert(tab->arg != NULL); - /* argument list must end with colon */ - if (mpl->token == T_COLON) - get_token(mpl /* : */); - else - error(mpl, "colon missing where expected"); - /* parse specific part of the table statement */ - switch (tab->type) - { case A_INPUT: goto input_table; - case A_OUTPUT: goto output_table; - default: xassert(tab != tab); - } -input_table: - /* parse optional set name */ - if (mpl->token == T_NAME) - { node = avl_find_node(mpl->tree, mpl->image); - if (node == NULL) - error(mpl, "%s not defined", mpl->image); - if (avl_get_node_type(node) != A_SET) - error(mpl, "%s not a set", mpl->image); - tab->u.in.set = (SET *)avl_get_node_link(node); - if (tab->u.in.set->assign != NULL) - error(mpl, "%s needs no data", mpl->image); - if (tab->u.in.set->dim != 0) - error(mpl, "%s must be a simple set", mpl->image); - get_token(mpl /* */); - if (mpl->token == T_INPUT) - get_token(mpl /* <- */); - else - error(mpl, "delimiter <- missing where expected"); - } - else if (is_reserved(mpl)) - error(mpl, "invalid use of reserved keyword %s", mpl->image); - else - tab->u.in.set = NULL; - /* parse field list */ - tab->u.in.fld = last_fld = NULL; - nflds = 0; - if (mpl->token == T_LBRACKET) - get_token(mpl /* [ */); - else - error(mpl, "field list missing where expected"); - for (;;) - { /* create field list entry */ - fld = alloc(TABFLD); - /* parse field name */ - if (mpl->token == T_NAME) - ; - else if (is_reserved(mpl)) - error(mpl, - "invalid use of reserved keyword %s", mpl->image); - else - error(mpl, "field name missing where expected"); - fld->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); - strcpy(fld->name, mpl->image); - get_token(mpl /* */); - /* add the entry to the end of the list */ - fld->next = NULL; - if (last_fld == NULL) - tab->u.in.fld = fld; - else - last_fld->next = fld; - last_fld = fld; - nflds++; - /* field name has been parsed */ - if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else if (mpl->token == T_RBRACKET) - break; - else - error(mpl, "syntax error in field list"); - } - /* check that the set dimen is equal to the number of fields */ - if (tab->u.in.set != NULL && tab->u.in.set->dimen != nflds) - error(mpl, "there must be %d field%s rather than %d", - tab->u.in.set->dimen, tab->u.in.set->dimen == 1 ? "" : "s", - nflds); - get_token(mpl /* ] */); - /* parse optional input list */ - tab->u.in.list = last_in = NULL; - while (mpl->token == T_COMMA) - { get_token(mpl /* , */); - /* create input list entry */ - in = alloc(TABIN); - /* parse parameter name */ - if (mpl->token == T_NAME) - ; - else if (is_reserved(mpl)) - error(mpl, - "invalid use of reserved keyword %s", mpl->image); - else - error(mpl, "parameter name missing where expected"); - node = avl_find_node(mpl->tree, mpl->image); - if (node == NULL) - error(mpl, "%s not defined", mpl->image); - if (avl_get_node_type(node) != A_PARAMETER) - error(mpl, "%s not a parameter", mpl->image); - in->par = (PARAMETER *)avl_get_node_link(node); - if (in->par->dim != nflds) - error(mpl, "%s must have %d subscript%s rather than %d", - mpl->image, nflds, nflds == 1 ? "" : "s", in->par->dim); - if (in->par->assign != NULL) - error(mpl, "%s needs no data", mpl->image); - get_token(mpl /* */); - /* parse optional field name */ - if (mpl->token == T_TILDE) - { get_token(mpl /* ~ */); - /* parse field name */ - if (mpl->token == T_NAME) - ; - else if (is_reserved(mpl)) - error(mpl, - "invalid use of reserved keyword %s", mpl->image); - else - error(mpl, "field name missing where expected"); - xassert(strlen(mpl->image) < sizeof(name)); - strcpy(name, mpl->image); - get_token(mpl /* */); - } - else - { /* field name is the same as the parameter name */ - xassert(strlen(in->par->name) < sizeof(name)); - strcpy(name, in->par->name); - } - /* assign field name */ - in->name = dmp_get_atomv(mpl->pool, strlen(name)+1); - strcpy(in->name, name); - /* add the entry to the end of the list */ - in->next = NULL; - if (last_in == NULL) - tab->u.in.list = in; - else - last_in->next = in; - last_in = in; - } - goto end_of_table; -output_table: - /* parse output list */ - tab->u.out.list = last_out = NULL; - for (;;) - { /* create output list entry */ - out = alloc(TABOUT); - /* parse expression */ - if (mpl->token == T_COMMA || mpl->token == T_SEMICOLON) - error(mpl, "expression missing where expected"); - if (mpl->token == T_NAME) - { xassert(strlen(mpl->image) < sizeof(name)); - strcpy(name, mpl->image); - } - else - name[0] = '\0'; - out->code = expression_5(mpl); - /* parse optional field name */ - if (mpl->token == T_TILDE) - { get_token(mpl /* ~ */); - /* parse field name */ - if (mpl->token == T_NAME) - ; - else if (is_reserved(mpl)) - error(mpl, - "invalid use of reserved keyword %s", mpl->image); - else - error(mpl, "field name missing where expected"); - xassert(strlen(mpl->image) < sizeof(name)); - strcpy(name, mpl->image); - get_token(mpl /* */); - } - /* assign field name */ - if (name[0] == '\0') - error(mpl, "field name required"); - out->name = dmp_get_atomv(mpl->pool, strlen(name)+1); - strcpy(out->name, name); - /* add the entry to the end of the list */ - out->next = NULL; - if (last_out == NULL) - tab->u.out.list = out; - else - last_out->next = out; - last_out = out; - /* output item has been parsed */ - if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else if (mpl->token == T_SEMICOLON) - break; - else - error(mpl, "syntax error in output list"); - } - /* close the domain scope */ - close_scope(mpl,tab->u.out.domain); -end_of_table: - /* the table statement must end with semicolon */ - if (mpl->token != T_SEMICOLON) - error(mpl, "syntax error in table statement"); - get_token(mpl /* ; */); - return tab; -} -#endif - -/*---------------------------------------------------------------------- --- solve_statement - parse solve statement. --- --- This routine parses solve statement using the syntax: --- --- ::= solve ; --- --- The solve statement can be used at most once. */ - -void *solve_statement(MPL *mpl) -{ xassert(is_keyword(mpl, "solve")); - if (mpl->flag_s) - error(mpl, "at most one solve statement allowed"); - mpl->flag_s = 1; - get_token(mpl /* solve */); - /* semicolon must follow solve statement */ - if (mpl->token != T_SEMICOLON) - error(mpl, "syntax error in solve statement"); - get_token(mpl /* ; */); - return NULL; -} - -/*---------------------------------------------------------------------- --- check_statement - parse check statement. --- --- This routine parses check statement using the syntax: --- --- ::= check : ; --- ::= --- ::= --- --- If is omitted, colon following it may also be omitted. */ - -CHECK *check_statement(MPL *mpl) -{ CHECK *chk; - xassert(is_keyword(mpl, "check")); - /* create check descriptor */ - chk = alloc(CHECK); - chk->domain = NULL; - chk->code = NULL; - get_token(mpl /* check */); - /* parse optional indexing expression */ - if (mpl->token == T_LBRACE) - { chk->domain = indexing_expression(mpl); -#if 0 - if (mpl->token != T_COLON) - error(mpl, "colon missing where expected"); -#endif - } - /* skip optional colon */ - if (mpl->token == T_COLON) get_token(mpl /* : */); - /* parse logical expression */ - chk->code = expression_13(mpl); - if (chk->code->type != A_LOGICAL) - error(mpl, "expression has invalid type"); - xassert(chk->code->dim == 0); - /* close the domain scope */ - if (chk->domain != NULL) close_scope(mpl, chk->domain); - /* the check statement has been completely parsed */ - if (mpl->token != T_SEMICOLON) - error(mpl, "syntax error in check statement"); - get_token(mpl /* ; */); - return chk; -} - -#if 1 /* 15/V-2010 */ -/*---------------------------------------------------------------------- --- display_statement - parse display statement. --- --- This routine parses display statement using the syntax: --- --- ::= display : ; --- ::= display ; --- ::= --- ::= --- ::= --- ::= , --- ::= --- ::= --- ::= [ ] --- ::= --- ::= [ ] --- ::= --- ::= [ ] --- ::= --- ::= [ ] --- ::= */ - -DISPLAY *display_statement(MPL *mpl) -{ DISPLAY *dpy; - DISPLAY1 *entry, *last_entry; - xassert(is_keyword(mpl, "display")); - /* create display descriptor */ - dpy = alloc(DISPLAY); - dpy->domain = NULL; - dpy->list = last_entry = NULL; - get_token(mpl /* display */); - /* parse optional indexing expression */ - if (mpl->token == T_LBRACE) - dpy->domain = indexing_expression(mpl); - /* skip optional colon */ - if (mpl->token == T_COLON) get_token(mpl /* : */); - /* parse display list */ - for (;;) - { /* create new display entry */ - entry = alloc(DISPLAY1); - entry->type = 0; - entry->next = NULL; - /* and append it to the display list */ - if (dpy->list == NULL) - dpy->list = entry; - else - last_entry->next = entry; - last_entry = entry; - /* parse display entry */ - if (mpl->token == T_NAME) - { AVLNODE *node; - int next_token; - get_token(mpl /* */); - next_token = mpl->token; - unget_token(mpl); - if (!(next_token == T_COMMA || next_token == T_SEMICOLON)) - { /* symbolic name begins expression */ - goto expr; - } - /* display entry is dummy index or model object */ - node = avl_find_node(mpl->tree, mpl->image); - if (node == NULL) - error(mpl, "%s not defined", mpl->image); - entry->type = avl_get_node_type(node); - switch (avl_get_node_type(node)) - { case A_INDEX: - entry->u.slot = - (DOMAIN_SLOT *)avl_get_node_link(node); - break; - case A_SET: - entry->u.set = (SET *)avl_get_node_link(node); - break; - case A_PARAMETER: - entry->u.par = (PARAMETER *)avl_get_node_link(node); - break; - case A_VARIABLE: - entry->u.var = (VARIABLE *)avl_get_node_link(node); - if (!mpl->flag_s) - error(mpl, "invalid reference to variable %s above" - " solve statement", entry->u.var->name); - break; - case A_CONSTRAINT: - entry->u.con = (CONSTRAINT *)avl_get_node_link(node); - if (!mpl->flag_s) - error(mpl, "invalid reference to %s %s above solve" - " statement", - entry->u.con->type == A_CONSTRAINT ? - "constraint" : "objective", entry->u.con->name); - break; - default: - xassert(node != node); - } - get_token(mpl /* */); - } - else -expr: { /* display entry is expression */ - entry->type = A_EXPRESSION; - entry->u.code = expression_13(mpl); - } - /* check a token that follows the entry parsed */ - if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else - break; - } - /* close the domain scope */ - if (dpy->domain != NULL) close_scope(mpl, dpy->domain); - /* the display statement has been completely parsed */ - if (mpl->token != T_SEMICOLON) - error(mpl, "syntax error in display statement"); - get_token(mpl /* ; */); - return dpy; -} -#endif - -/*---------------------------------------------------------------------- --- printf_statement - parse printf statement. --- --- This routine parses print statement using the syntax: --- --- ::= ; --- ::= > ; --- ::= >> ; --- ::= printf : --- ::= printf --- ::= --- ::= --- ::= --- ::= --- ::= , --- ::= --- ::= */ - -PRINTF *printf_statement(MPL *mpl) -{ PRINTF *prt; - PRINTF1 *entry, *last_entry; - xassert(is_keyword(mpl, "printf")); - /* create printf descriptor */ - prt = alloc(PRINTF); - prt->domain = NULL; - prt->fmt = NULL; - prt->list = last_entry = NULL; - get_token(mpl /* printf */); - /* parse optional indexing expression */ - if (mpl->token == T_LBRACE) - { prt->domain = indexing_expression(mpl); -#if 0 - if (mpl->token != T_COLON) - error(mpl, "colon missing where expected"); -#endif - } - /* skip optional colon */ - if (mpl->token == T_COLON) get_token(mpl /* : */); - /* parse expression for format string */ - prt->fmt = expression_5(mpl); - /* convert it to symbolic type, if necessary */ - if (prt->fmt->type == A_NUMERIC) - prt->fmt = make_unary(mpl, O_CVTSYM, prt->fmt, A_SYMBOLIC, 0); - /* check that now the expression is of symbolic type */ - if (prt->fmt->type != A_SYMBOLIC) - error(mpl, "format expression has invalid type"); - /* parse printf list */ - while (mpl->token == T_COMMA) - { get_token(mpl /* , */); - /* create new printf entry */ - entry = alloc(PRINTF1); - entry->code = NULL; - entry->next = NULL; - /* and append it to the printf list */ - if (prt->list == NULL) - prt->list = entry; - else - last_entry->next = entry; - last_entry = entry; - /* parse printf entry */ - entry->code = expression_9(mpl); - if (!(entry->code->type == A_NUMERIC || - entry->code->type == A_SYMBOLIC || - entry->code->type == A_LOGICAL)) - error(mpl, "only numeric, symbolic, or logical expression a" - "llowed"); - } - /* close the domain scope */ - if (prt->domain != NULL) close_scope(mpl, prt->domain); -#if 1 /* 14/VII-2006 */ - /* parse optional redirection */ - prt->fname = NULL, prt->app = 0; - if (mpl->token == T_GT || mpl->token == T_APPEND) - { prt->app = (mpl->token == T_APPEND); - get_token(mpl /* > or >> */); - /* parse expression for file name string */ - prt->fname = expression_5(mpl); - /* convert it to symbolic type, if necessary */ - if (prt->fname->type == A_NUMERIC) - prt->fname = make_unary(mpl, O_CVTSYM, prt->fname, - A_SYMBOLIC, 0); - /* check that now the expression is of symbolic type */ - if (prt->fname->type != A_SYMBOLIC) - error(mpl, "file name expression has invalid type"); - } -#endif - /* the printf statement has been completely parsed */ - if (mpl->token != T_SEMICOLON) - error(mpl, "syntax error in printf statement"); - get_token(mpl /* ; */); - return prt; -} - -/*---------------------------------------------------------------------- --- for_statement - parse for statement. --- --- This routine parses for statement using the syntax: --- --- ::= for --- ::= for { } --- ::= --- ::= --- ::= --- ::= --- ::= --- ::= --- ::= */ - -FOR *for_statement(MPL *mpl) -{ FOR *fur; - STATEMENT *stmt, *last_stmt; - xassert(is_keyword(mpl, "for")); - /* create for descriptor */ - fur = alloc(FOR); - fur->domain = NULL; - fur->list = last_stmt = NULL; - get_token(mpl /* for */); - /* parse indexing expression */ - if (mpl->token != T_LBRACE) - error(mpl, "indexing expression missing where expected"); - fur->domain = indexing_expression(mpl); - /* skip optional colon */ - if (mpl->token == T_COLON) get_token(mpl /* : */); - /* parse for statement body */ - if (mpl->token != T_LBRACE) - { /* parse simple statement */ - fur->list = simple_statement(mpl, 1); - } - else - { /* parse compound statement */ - get_token(mpl /* { */); - while (mpl->token != T_RBRACE) - { /* parse statement */ - stmt = simple_statement(mpl, 1); - /* and append it to the end of the statement list */ - if (last_stmt == NULL) - fur->list = stmt; - else - last_stmt->next = stmt; - last_stmt = stmt; - } - get_token(mpl /* } */); - } - /* close the domain scope */ - xassert(fur->domain != NULL); - close_scope(mpl, fur->domain); - /* the for statement has been completely parsed */ - return fur; -} - -/*---------------------------------------------------------------------- --- end_statement - parse end statement. --- --- This routine parses end statement using the syntax: --- --- ::= end ; */ - -void end_statement(MPL *mpl) -{ if (!mpl->flag_d && is_keyword(mpl, "end") || - mpl->flag_d && is_literal(mpl, "end")) - { get_token(mpl /* end */); - if (mpl->token == T_SEMICOLON) - get_token(mpl /* ; */); - else - warning(mpl, "no semicolon following end statement; missing" - " semicolon inserted"); - } - else - warning(mpl, "unexpected end of file; missing end statement in" - "serted"); - if (mpl->token != T_EOF) - warning(mpl, "some text detected beyond end statement; text ig" - "nored"); - return; -} - -/*---------------------------------------------------------------------- --- simple_statement - parse simple statement. --- --- This routine parses simple statement using the syntax: --- --- ::= --- ::= --- ::= --- ::= --- ::= --- ::= --- ::= --- ::= --- ::= --- ::= --- --- If the flag spec is set, some statements cannot be used. */ - -STATEMENT *simple_statement(MPL *mpl, int spec) -{ STATEMENT *stmt; - stmt = alloc(STATEMENT); - stmt->line = mpl->line; - stmt->next = NULL; - if (is_keyword(mpl, "set")) - { if (spec) - error(mpl, "set statement not allowed here"); - stmt->type = A_SET; - stmt->u.set = set_statement(mpl); - } - else if (is_keyword(mpl, "param")) - { if (spec) - error(mpl, "parameter statement not allowed here"); - stmt->type = A_PARAMETER; - stmt->u.par = parameter_statement(mpl); - } - else if (is_keyword(mpl, "var")) - { if (spec) - error(mpl, "variable statement not allowed here"); - stmt->type = A_VARIABLE; - stmt->u.var = variable_statement(mpl); - } - else if (is_keyword(mpl, "subject") || - is_keyword(mpl, "subj") || - mpl->token == T_SPTP) - { if (spec) - error(mpl, "constraint statement not allowed here"); - stmt->type = A_CONSTRAINT; - stmt->u.con = constraint_statement(mpl); - } - else if (is_keyword(mpl, "minimize") || - is_keyword(mpl, "maximize")) - { if (spec) - error(mpl, "objective statement not allowed here"); - stmt->type = A_CONSTRAINT; - stmt->u.con = objective_statement(mpl); - } -#if 1 /* 11/II-2008 */ - else if (is_keyword(mpl, "table")) - { if (spec) - error(mpl, "table statement not allowed here"); - stmt->type = A_TABLE; - stmt->u.tab = table_statement(mpl); - } -#endif - else if (is_keyword(mpl, "solve")) - { if (spec) - error(mpl, "solve statement not allowed here"); - stmt->type = A_SOLVE; - stmt->u.slv = solve_statement(mpl); - } - else if (is_keyword(mpl, "check")) - { stmt->type = A_CHECK; - stmt->u.chk = check_statement(mpl); - } - else if (is_keyword(mpl, "display")) - { stmt->type = A_DISPLAY; - stmt->u.dpy = display_statement(mpl); - } - else if (is_keyword(mpl, "printf")) - { stmt->type = A_PRINTF; - stmt->u.prt = printf_statement(mpl); - } - else if (is_keyword(mpl, "for")) - { stmt->type = A_FOR; - stmt->u.fur = for_statement(mpl); - } - else if (mpl->token == T_NAME) - { if (spec) - error(mpl, "constraint statement not allowed here"); - stmt->type = A_CONSTRAINT; - stmt->u.con = constraint_statement(mpl); - } - else if (is_reserved(mpl)) - error(mpl, "invalid use of reserved keyword %s", mpl->image); - else - error(mpl, "syntax error in model section"); - return stmt; -} - -/*---------------------------------------------------------------------- --- model_section - parse model section. --- --- This routine parses model section using the syntax: --- --- ::= --- ::= --- --- Parsing model section is terminated by either the keyword 'data', or --- the keyword 'end', or the end of file. */ - -void model_section(MPL *mpl) -{ STATEMENT *stmt, *last_stmt; - xassert(mpl->model == NULL); - last_stmt = NULL; - while (!(mpl->token == T_EOF || is_keyword(mpl, "data") || - is_keyword(mpl, "end"))) - { /* parse statement */ - stmt = simple_statement(mpl, 0); - /* and append it to the end of the statement list */ - if (last_stmt == NULL) - mpl->model = stmt; - else - last_stmt->next = stmt; - last_stmt = stmt; - } - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpmpl02.c b/resources/3rdparty/glpk-4.53/src/glpmpl02.c deleted file mode 100644 index 277593981..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpmpl02.c +++ /dev/null @@ -1,1203 +0,0 @@ -/* glpmpl02.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "glpmpl.h" - -/**********************************************************************/ -/* * * PROCESSING DATA SECTION * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- create_slice - create slice. --- --- This routine creates a slice, which initially has no components. */ - -SLICE *create_slice(MPL *mpl) -{ SLICE *slice; - xassert(mpl == mpl); - slice = NULL; - return slice; -} - -/*---------------------------------------------------------------------- --- expand_slice - append new component to slice. --- --- This routine expands slice appending to it either a given symbol or --- null component, which becomes the last component of the slice. */ - -SLICE *expand_slice -( MPL *mpl, - SLICE *slice, /* destroyed */ - SYMBOL *sym /* destroyed */ -) -{ SLICE *tail, *temp; - /* create a new component */ - tail = dmp_get_atom(mpl->tuples, sizeof(SLICE)); - tail->sym = sym; - tail->next = NULL; - /* and append it to the component list */ - if (slice == NULL) - slice = tail; - else - { for (temp = slice; temp->next != NULL; temp = temp->next); - temp->next = tail; - } - return slice; -} - -/*---------------------------------------------------------------------- --- slice_dimen - determine dimension of slice. --- --- This routine returns dimension of slice, which is number of all its --- components including null ones. */ - -int slice_dimen -( MPL *mpl, - SLICE *slice /* not changed */ -) -{ SLICE *temp; - int dim; - xassert(mpl == mpl); - dim = 0; - for (temp = slice; temp != NULL; temp = temp->next) dim++; - return dim; -} - -/*---------------------------------------------------------------------- --- slice_arity - determine arity of slice. --- --- This routine returns arity of slice, i.e. number of null components --- (indicated by asterisks) in the slice. */ - -int slice_arity -( MPL *mpl, - SLICE *slice /* not changed */ -) -{ SLICE *temp; - int arity; - xassert(mpl == mpl); - arity = 0; - for (temp = slice; temp != NULL; temp = temp->next) - if (temp->sym == NULL) arity++; - return arity; -} - -/*---------------------------------------------------------------------- --- fake_slice - create fake slice of all asterisks. --- --- This routine creates a fake slice of given dimension, which contains --- asterisks in all components. Zero dimension is allowed. */ - -SLICE *fake_slice(MPL *mpl, int dim) -{ SLICE *slice; - slice = create_slice(mpl); - while (dim-- > 0) slice = expand_slice(mpl, slice, NULL); - return slice; -} - -/*---------------------------------------------------------------------- --- delete_slice - delete slice. --- --- This routine deletes specified slice. */ - -void delete_slice -( MPL *mpl, - SLICE *slice /* destroyed */ -) -{ SLICE *temp; - while (slice != NULL) - { temp = slice; - slice = temp->next; - if (temp->sym != NULL) delete_symbol(mpl, temp->sym); -xassert(sizeof(SLICE) == sizeof(TUPLE)); - dmp_free_atom(mpl->tuples, temp, sizeof(TUPLE)); - } - return; -} - -/*---------------------------------------------------------------------- --- is_number - check if current token is number. --- --- If the current token is a number, this routine returns non-zero. --- Otherwise zero is returned. */ - -int is_number(MPL *mpl) -{ return - mpl->token == T_NUMBER; -} - -/*---------------------------------------------------------------------- --- is_symbol - check if current token is symbol. --- --- If the current token is suitable to be a symbol, the routine returns --- non-zero. Otherwise zero is returned. */ - -int is_symbol(MPL *mpl) -{ return - mpl->token == T_NUMBER || - mpl->token == T_SYMBOL || - mpl->token == T_STRING; -} - -/*---------------------------------------------------------------------- --- is_literal - check if current token is given symbolic literal. --- --- If the current token is given symbolic literal, this routine returns --- non-zero. Otherwise zero is returned. --- --- This routine is used on processing the data section in the same way --- as the routine is_keyword on processing the model section. */ - -int is_literal(MPL *mpl, char *literal) -{ return - is_symbol(mpl) && strcmp(mpl->image, literal) == 0; -} - -/*---------------------------------------------------------------------- --- read_number - read number. --- --- This routine reads the current token, which must be a number, and --- returns its numeric value. */ - -double read_number(MPL *mpl) -{ double num; - xassert(is_number(mpl)); - num = mpl->value; - get_token(mpl /* */); - return num; -} - -/*---------------------------------------------------------------------- --- read_symbol - read symbol. --- --- This routine reads the current token, which must be a symbol, and --- returns its symbolic value. */ - -SYMBOL *read_symbol(MPL *mpl) -{ SYMBOL *sym; - xassert(is_symbol(mpl)); - if (is_number(mpl)) - sym = create_symbol_num(mpl, mpl->value); - else - sym = create_symbol_str(mpl, create_string(mpl, mpl->image)); - get_token(mpl /* */); - return sym; -} - -/*---------------------------------------------------------------------- --- read_slice - read slice. --- --- This routine reads slice using the syntax: --- --- ::= [ ] --- ::= ( ) --- ::= --- ::= , --- ::= --- ::= * --- --- The bracketed form of slice is used for members of multi-dimensional --- objects while the parenthesized form is used for elemental sets. */ - -SLICE *read_slice -( MPL *mpl, - char *name, /* not changed */ - int dim -) -{ SLICE *slice; - int close; - xassert(name != NULL); - switch (mpl->token) - { case T_LBRACKET: - close = T_RBRACKET; - break; - case T_LEFT: - xassert(dim > 0); - close = T_RIGHT; - break; - default: - xassert(mpl != mpl); - } - if (dim == 0) - error(mpl, "%s cannot be subscripted", name); - get_token(mpl /* ( | [ */); - /* read slice components */ - slice = create_slice(mpl); - for (;;) - { /* the current token must be a symbol or asterisk */ - if (is_symbol(mpl)) - slice = expand_slice(mpl, slice, read_symbol(mpl)); - else if (mpl->token == T_ASTERISK) - { slice = expand_slice(mpl, slice, NULL); - get_token(mpl /* * */); - } - else - error(mpl, "number, symbol, or asterisk missing where expec" - "ted"); - /* check a token that follows the symbol */ - if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else if (mpl->token == close) - break; - else - error(mpl, "syntax error in slice"); - } - /* number of slice components must be the same as the appropriate - dimension */ - if (slice_dimen(mpl, slice) != dim) - { switch (close) - { case T_RBRACKET: - error(mpl, "%s must have %d subscript%s, not %d", name, - dim, dim == 1 ? "" : "s", slice_dimen(mpl, slice)); - break; - case T_RIGHT: - error(mpl, "%s has dimension %d, not %d", name, dim, - slice_dimen(mpl, slice)); - break; - default: - xassert(close != close); - } - } - get_token(mpl /* ) | ] */); - return slice; -} - -/*---------------------------------------------------------------------- --- select_set - select set to saturate it with elemental sets. --- --- This routine selects set to saturate it with elemental sets provided --- in the data section. */ - -SET *select_set -( MPL *mpl, - char *name /* not changed */ -) -{ SET *set; - AVLNODE *node; - xassert(name != NULL); - node = avl_find_node(mpl->tree, name); - if (node == NULL || avl_get_node_type(node) != A_SET) - error(mpl, "%s not a set", name); - set = (SET *)avl_get_node_link(node); - if (set->assign != NULL || set->gadget != NULL) - error(mpl, "%s needs no data", name); - set->data = 1; - return set; -} - -/*---------------------------------------------------------------------- --- simple_format - read set data block in simple format. --- --- This routine reads set data block using the syntax: --- --- ::= , , ... , --- --- where are used to construct a complete n-tuple, which is --- included in elemental set assigned to the set member. Commae between --- symbols are optional and may be omitted anywhere. --- --- Number of components in the slice must be the same as dimension of --- n-tuples in elemental sets assigned to the set members. To construct --- complete n-tuple the routine replaces null positions in the slice by --- corresponding . --- --- If the slice contains at least one null position, the current token --- must be symbol. Otherwise, the routine reads no symbols to construct --- the n-tuple, so the current token is not checked. */ - -void simple_format -( MPL *mpl, - SET *set, /* not changed */ - MEMBER *memb, /* modified */ - SLICE *slice /* not changed */ -) -{ TUPLE *tuple; - SLICE *temp; - SYMBOL *sym, *with = NULL; - xassert(set != NULL); - xassert(memb != NULL); - xassert(slice != NULL); - xassert(set->dimen == slice_dimen(mpl, slice)); - xassert(memb->value.set->dim == set->dimen); - if (slice_arity(mpl, slice) > 0) xassert(is_symbol(mpl)); - /* read symbols and construct complete n-tuple */ - tuple = create_tuple(mpl); - for (temp = slice; temp != NULL; temp = temp->next) - { if (temp->sym == NULL) - { /* substitution is needed; read symbol */ - if (!is_symbol(mpl)) - { int lack = slice_arity(mpl, temp); - /* with cannot be null due to assertion above */ - xassert(with != NULL); - if (lack == 1) - error(mpl, "one item missing in data group beginning " - "with %s", format_symbol(mpl, with)); - else - error(mpl, "%d items missing in data group beginning " - "with %s", lack, format_symbol(mpl, with)); - } - sym = read_symbol(mpl); - if (with == NULL) with = sym; - } - else - { /* copy symbol from the slice */ - sym = copy_symbol(mpl, temp->sym); - } - /* append the symbol to the n-tuple */ - tuple = expand_tuple(mpl, tuple, sym); - /* skip optional comma *between* */ - if (temp->next != NULL && mpl->token == T_COMMA) - get_token(mpl /* , */); - } - /* add constructed n-tuple to elemental set */ - check_then_add(mpl, memb->value.set, tuple); - return; -} - -/*---------------------------------------------------------------------- --- matrix_format - read set data block in matrix format. --- --- This routine reads set data block using the syntax: --- --- ::= ... := --- +/- +/- ... +/- --- +/- +/- ... +/- --- . . . . . . . . . . . --- +/- +/- ... +/- --- --- where are symbols that denote rows of the matrix, --- are symbols that denote columns of the matrix, "+" and "-" indicate --- whether corresponding n-tuple needs to be included in the elemental --- set or not, respectively. --- --- Number of the slice components must be the same as dimension of the --- elemental set. The slice must have two null positions. To construct --- complete n-tuple for particular element of the matrix the routine --- replaces first null position of the slice by the corresponding --- (or , if the flag tr is on) and second null position by the --- corresponding (or by , if the flag tr is on). */ - -void matrix_format -( MPL *mpl, - SET *set, /* not changed */ - MEMBER *memb, /* modified */ - SLICE *slice, /* not changed */ - int tr -) -{ SLICE *list, *col, *temp; - TUPLE *tuple; - SYMBOL *row; - xassert(set != NULL); - xassert(memb != NULL); - xassert(slice != NULL); - xassert(set->dimen == slice_dimen(mpl, slice)); - xassert(memb->value.set->dim == set->dimen); - xassert(slice_arity(mpl, slice) == 2); - /* read the matrix heading that contains column symbols (there - may be no columns at all) */ - list = create_slice(mpl); - while (mpl->token != T_ASSIGN) - { /* read column symbol and append it to the column list */ - if (!is_symbol(mpl)) - error(mpl, "number, symbol, or := missing where expected"); - list = expand_slice(mpl, list, read_symbol(mpl)); - } - get_token(mpl /* := */); - /* read zero or more rows that contain matrix data */ - while (is_symbol(mpl)) - { /* read row symbol (if the matrix has no columns, row symbols - are just ignored) */ - row = read_symbol(mpl); - /* read the matrix row accordingly to the column list */ - for (col = list; col != NULL; col = col->next) - { int which = 0; - /* check indicator */ - if (is_literal(mpl, "+")) - ; - else if (is_literal(mpl, "-")) - { get_token(mpl /* - */); - continue; - } - else - { int lack = slice_dimen(mpl, col); - if (lack == 1) - error(mpl, "one item missing in data group beginning " - "with %s", format_symbol(mpl, row)); - else - error(mpl, "%d items missing in data group beginning " - "with %s", lack, format_symbol(mpl, row)); - } - /* construct complete n-tuple */ - tuple = create_tuple(mpl); - for (temp = slice; temp != NULL; temp = temp->next) - { if (temp->sym == NULL) - { /* substitution is needed */ - switch (++which) - { case 1: - /* substitute in the first null position */ - tuple = expand_tuple(mpl, tuple, - copy_symbol(mpl, tr ? col->sym : row)); - break; - case 2: - /* substitute in the second null position */ - tuple = expand_tuple(mpl, tuple, - copy_symbol(mpl, tr ? row : col->sym)); - break; - default: - xassert(which != which); - } - } - else - { /* copy symbol from the slice */ - tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, - temp->sym)); - } - } - xassert(which == 2); - /* add constructed n-tuple to elemental set */ - check_then_add(mpl, memb->value.set, tuple); - get_token(mpl /* + */); - } - /* delete the row symbol */ - delete_symbol(mpl, row); - } - /* delete the column list */ - delete_slice(mpl, list); - return; -} - -/*---------------------------------------------------------------------- --- set_data - read set data. --- --- This routine reads set data using the syntax: --- --- ::= set ; --- ::= set [ ] ; --- ::= --- ::= --- ::= , := --- ::= , ( ) --- ::= , --- ::= , : --- ::= , (tr) --- ::= , (tr) : --- --- Commae in are optional and may be omitted anywhere. */ - -void set_data(MPL *mpl) -{ SET *set; - TUPLE *tuple; - MEMBER *memb; - SLICE *slice; - int tr = 0; - xassert(is_literal(mpl, "set")); - get_token(mpl /* set */); - /* symbolic name of set must follows the keyword 'set' */ - if (!is_symbol(mpl)) - error(mpl, "set name missing where expected"); - /* select the set to saturate it with data */ - set = select_set(mpl, mpl->image); - get_token(mpl /* */); - /* read optional subscript list, which identifies member of the - set to be read */ - tuple = create_tuple(mpl); - if (mpl->token == T_LBRACKET) - { /* subscript list is specified */ - if (set->dim == 0) - error(mpl, "%s cannot be subscripted", set->name); - get_token(mpl /* [ */); - /* read symbols and construct subscript list */ - for (;;) - { if (!is_symbol(mpl)) - error(mpl, "number or symbol missing where expected"); - tuple = expand_tuple(mpl, tuple, read_symbol(mpl)); - if (mpl->token == T_COMMA) - get_token(mpl /* , */); - else if (mpl->token == T_RBRACKET) - break; - else - error(mpl, "syntax error in subscript list"); - } - if (set->dim != tuple_dimen(mpl, tuple)) - error(mpl, "%s must have %d subscript%s rather than %d", - set->name, set->dim, set->dim == 1 ? "" : "s", - tuple_dimen(mpl, tuple)); - get_token(mpl /* ] */); - } - else - { /* subscript list is not specified */ - if (set->dim != 0) - error(mpl, "%s must be subscripted", set->name); - } - /* there must be no member with the same subscript list */ - if (find_member(mpl, set->array, tuple) != NULL) - error(mpl, "%s%s already defined", - set->name, format_tuple(mpl, '[', tuple)); - /* add new member to the set and assign it empty elemental set */ - memb = add_member(mpl, set->array, tuple); - memb->value.set = create_elemset(mpl, set->dimen); - /* create an initial fake slice of all asterisks */ - slice = fake_slice(mpl, set->dimen); - /* read zero or more data assignments */ - for (;;) - { /* skip optional comma */ - if (mpl->token == T_COMMA) get_token(mpl /* , */); - /* process assignment element */ - if (mpl->token == T_ASSIGN) - { /* assignment ligature is non-significant element */ - get_token(mpl /* := */); - } - else if (mpl->token == T_LEFT) - { /* left parenthesis begins either new slice or "transpose" - indicator */ - int is_tr; - get_token(mpl /* ( */); - is_tr = is_literal(mpl, "tr"); - unget_token(mpl /* ( */); - if (is_tr) goto left; - /* delete the current slice and read new one */ - delete_slice(mpl, slice); - slice = read_slice(mpl, set->name, set->dimen); - /* each new slice resets the "transpose" indicator */ - tr = 0; - /* if the new slice is 0-ary, formally there is one 0-tuple - (in the simple format) that follows it */ - if (slice_arity(mpl, slice) == 0) - simple_format(mpl, set, memb, slice); - } - else if (is_symbol(mpl)) - { /* number or symbol begins data in the simple format */ - simple_format(mpl, set, memb, slice); - } - else if (mpl->token == T_COLON) - { /* colon begins data in the matrix format */ - if (slice_arity(mpl, slice) != 2) -err1: error(mpl, "slice currently used must specify 2 asterisk" - "s, not %d", slice_arity(mpl, slice)); - get_token(mpl /* : */); - /* read elemental set data in the matrix format */ - matrix_format(mpl, set, memb, slice, tr); - } - else if (mpl->token == T_LEFT) -left: { /* left parenthesis begins the "transpose" indicator, which - is followed by data in the matrix format */ - get_token(mpl /* ( */); - if (!is_literal(mpl, "tr")) -err2: error(mpl, "transpose indicator (tr) incomplete"); - if (slice_arity(mpl, slice) != 2) goto err1; - get_token(mpl /* tr */); - if (mpl->token != T_RIGHT) goto err2; - get_token(mpl /* ) */); - /* in this case the colon is optional */ - if (mpl->token == T_COLON) get_token(mpl /* : */); - /* set the "transpose" indicator */ - tr = 1; - /* read elemental set data in the matrix format */ - matrix_format(mpl, set, memb, slice, tr); - } - else if (mpl->token == T_SEMICOLON) - { /* semicolon terminates the data block */ - get_token(mpl /* ; */); - break; - } - else - error(mpl, "syntax error in set data block"); - } - /* delete the current slice */ - delete_slice(mpl, slice); - return; -} - -/*---------------------------------------------------------------------- --- select_parameter - select parameter to saturate it with data. --- --- This routine selects parameter to saturate it with data provided in --- the data section. */ - -PARAMETER *select_parameter -( MPL *mpl, - char *name /* not changed */ -) -{ PARAMETER *par; - AVLNODE *node; - xassert(name != NULL); - node = avl_find_node(mpl->tree, name); - if (node == NULL || avl_get_node_type(node) != A_PARAMETER) - error(mpl, "%s not a parameter", name); - par = (PARAMETER *)avl_get_node_link(node); - if (par->assign != NULL) - error(mpl, "%s needs no data", name); - if (par->data) - error(mpl, "%s already provided with data", name); - par->data = 1; - return par; -} - -/*---------------------------------------------------------------------- --- set_default - set default parameter value. --- --- This routine sets default value for specified parameter. */ - -void set_default -( MPL *mpl, - PARAMETER *par, /* not changed */ - SYMBOL *altval /* destroyed */ -) -{ xassert(par != NULL); - xassert(altval != NULL); - if (par->option != NULL) - error(mpl, "default value for %s already specified in model se" - "ction", par->name); - xassert(par->defval == NULL); - par->defval = altval; - return; -} - -/*---------------------------------------------------------------------- --- read_value - read value and assign it to parameter member. --- --- This routine reads numeric or symbolic value from the input stream --- and assigns to new parameter member specified by its n-tuple, which --- (the member) is created and added to the parameter array. */ - -MEMBER *read_value -( MPL *mpl, - PARAMETER *par, /* not changed */ - TUPLE *tuple /* destroyed */ -) -{ MEMBER *memb; - xassert(par != NULL); - xassert(is_symbol(mpl)); - /* there must be no member with the same n-tuple */ - if (find_member(mpl, par->array, tuple) != NULL) - error(mpl, "%s%s already defined", - par->name, format_tuple(mpl, '[', tuple)); - /* create new parameter member with given n-tuple */ - memb = add_member(mpl, par->array, tuple); - /* read value and assigns it to the new parameter member */ - switch (par->type) - { case A_NUMERIC: - case A_INTEGER: - case A_BINARY: - if (!is_number(mpl)) - error(mpl, "%s requires numeric data", par->name); - memb->value.num = read_number(mpl); - break; - case A_SYMBOLIC: - memb->value.sym = read_symbol(mpl); - break; - default: - xassert(par != par); - } - return memb; -} - -/*---------------------------------------------------------------------- --- plain_format - read parameter data block in plain format. --- --- This routine reads parameter data block using the syntax: --- --- ::= , , ... , , --- --- where are used to determine a complete subscript list for --- parameter member, is a numeric or symbolic value assigned to --- the parameter member. Commae between data items are optional and may --- be omitted anywhere. --- --- Number of components in the slice must be the same as dimension of --- the parameter. To construct the complete subscript list the routine --- replaces null positions in the slice by corresponding . */ - -void plain_format -( MPL *mpl, - PARAMETER *par, /* not changed */ - SLICE *slice /* not changed */ -) -{ TUPLE *tuple; - SLICE *temp; - SYMBOL *sym, *with = NULL; - xassert(par != NULL); - xassert(par->dim == slice_dimen(mpl, slice)); - xassert(is_symbol(mpl)); - /* read symbols and construct complete subscript list */ - tuple = create_tuple(mpl); - for (temp = slice; temp != NULL; temp = temp->next) - { if (temp->sym == NULL) - { /* substitution is needed; read symbol */ - if (!is_symbol(mpl)) - { int lack = slice_arity(mpl, temp) + 1; - xassert(with != NULL); - xassert(lack > 1); - error(mpl, "%d items missing in data group beginning wit" - "h %s", lack, format_symbol(mpl, with)); - } - sym = read_symbol(mpl); - if (with == NULL) with = sym; - } - else - { /* copy symbol from the slice */ - sym = copy_symbol(mpl, temp->sym); - } - /* append the symbol to the subscript list */ - tuple = expand_tuple(mpl, tuple, sym); - /* skip optional comma */ - if (mpl->token == T_COMMA) get_token(mpl /* , */); - } - /* read value and assign it to new parameter member */ - if (!is_symbol(mpl)) - { xassert(with != NULL); - error(mpl, "one item missing in data group beginning with %s", - format_symbol(mpl, with)); - } - read_value(mpl, par, tuple); - return; -} - -/*---------------------------------------------------------------------- --- tabular_format - read parameter data block in tabular format. --- --- This routine reads parameter data block using the syntax: --- --- ::= ... := --- ... --- ... --- . . . . . . . . . . . --- ... --- --- where are symbols that denote rows of the table, --- are symbols that denote columns of the table, are numeric --- or symbolic values assigned to the corresponding parameter members. --- If is specified as single point, no value is provided. --- --- Number of components in the slice must be the same as dimension of --- the parameter. The slice must have two null positions. To construct --- complete subscript list for particular the routine replaces --- the first null position of the slice by the corresponding (or --- , if the flag tr is on) and the second null position by the --- corresponding (or by , if the flag tr is on). */ - -void tabular_format -( MPL *mpl, - PARAMETER *par, /* not changed */ - SLICE *slice, /* not changed */ - int tr -) -{ SLICE *list, *col, *temp; - TUPLE *tuple; - SYMBOL *row; - xassert(par != NULL); - xassert(par->dim == slice_dimen(mpl, slice)); - xassert(slice_arity(mpl, slice) == 2); - /* read the table heading that contains column symbols (the table - may have no columns) */ - list = create_slice(mpl); - while (mpl->token != T_ASSIGN) - { /* read column symbol and append it to the column list */ - if (!is_symbol(mpl)) - error(mpl, "number, symbol, or := missing where expected"); - list = expand_slice(mpl, list, read_symbol(mpl)); - } - get_token(mpl /* := */); - /* read zero or more rows that contain tabular data */ - while (is_symbol(mpl)) - { /* read row symbol (if the table has no columns, these symbols - are just ignored) */ - row = read_symbol(mpl); - /* read values accordingly to the column list */ - for (col = list; col != NULL; col = col->next) - { int which = 0; - /* if the token is single point, no value is provided */ - if (is_literal(mpl, ".")) - { get_token(mpl /* . */); - continue; - } - /* construct complete subscript list */ - tuple = create_tuple(mpl); - for (temp = slice; temp != NULL; temp = temp->next) - { if (temp->sym == NULL) - { /* substitution is needed */ - switch (++which) - { case 1: - /* substitute in the first null position */ - tuple = expand_tuple(mpl, tuple, - copy_symbol(mpl, tr ? col->sym : row)); - break; - case 2: - /* substitute in the second null position */ - tuple = expand_tuple(mpl, tuple, - copy_symbol(mpl, tr ? row : col->sym)); - break; - default: - xassert(which != which); - } - } - else - { /* copy symbol from the slice */ - tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, - temp->sym)); - } - } - xassert(which == 2); - /* read value and assign it to new parameter member */ - if (!is_symbol(mpl)) - { int lack = slice_dimen(mpl, col); - if (lack == 1) - error(mpl, "one item missing in data group beginning " - "with %s", format_symbol(mpl, row)); - else - error(mpl, "%d items missing in data group beginning " - "with %s", lack, format_symbol(mpl, row)); - } - read_value(mpl, par, tuple); - } - /* delete the row symbol */ - delete_symbol(mpl, row); - } - /* delete the column list */ - delete_slice(mpl, list); - return; -} - -/*---------------------------------------------------------------------- --- tabbing_format - read parameter data block in tabbing format. --- --- This routine reads parameter data block using the syntax: --- --- ::= , ... , , := , --- , ... , , , ... , , --- , ... , , , ... , , --- . . . . . . . . . . . . . . . . . --- , ... , , , ... , --- ::= --- ::= : --- --- where are names of parameters (all the parameters must be --- subscripted and have identical dimensions), are symbols --- used to define subscripts of parameter members, are numeric --- or symbolic values assigned to the corresponding parameter members. --- Optional may specify a simple set, in which case n-tuples --- built of for each row of the data table (i.e. subscripts --- of parameter members) are added to the specified set. Commae between --- data items are optional and may be omitted anywhere. --- --- If the parameter altval is not NULL, it specifies a default value --- provided for all the parameters specified in the data block. */ - -void tabbing_format -( MPL *mpl, - SYMBOL *altval /* not changed */ -) -{ SET *set = NULL; - PARAMETER *par; - SLICE *list, *col; - TUPLE *tuple; - int next_token, j, dim = 0; - char *last_name = NULL; - /* read the optional */ - if (is_symbol(mpl)) - { get_token(mpl /* */); - next_token = mpl->token; - unget_token(mpl /* */); - if (next_token == T_COLON) - { /* select the set to saturate it with data */ - set = select_set(mpl, mpl->image); - /* the set must be simple (i.e. not set of sets) */ - if (set->dim != 0) - error(mpl, "%s must be a simple set", set->name); - /* and must not be defined yet */ - if (set->array->head != NULL) - error(mpl, "%s already defined", set->name); - /* add new (the only) member to the set and assign it empty - elemental set */ - add_member(mpl, set->array, NULL)->value.set = - create_elemset(mpl, set->dimen); - last_name = set->name, dim = set->dimen; - get_token(mpl /* */); - xassert(mpl->token == T_COLON); - get_token(mpl /* : */); - } - } - /* read the table heading that contains parameter names */ - list = create_slice(mpl); - while (mpl->token != T_ASSIGN) - { /* there must be symbolic name of parameter */ - if (!is_symbol(mpl)) - error(mpl, "parameter name or := missing where expected"); - /* select the parameter to saturate it with data */ - par = select_parameter(mpl, mpl->image); - /* the parameter must be subscripted */ - if (par->dim == 0) - error(mpl, "%s not a subscripted parameter", mpl->image); - /* the set (if specified) and all the parameters in the data - block must have identical dimension */ - if (dim != 0 && par->dim != dim) - { xassert(last_name != NULL); - error(mpl, "%s has dimension %d while %s has dimension %d", - last_name, dim, par->name, par->dim); - } - /* set default value for the parameter (if specified) */ - if (altval != NULL) - set_default(mpl, par, copy_symbol(mpl, altval)); - /* append the parameter to the column list */ - list = expand_slice(mpl, list, (SYMBOL *)par); - last_name = par->name, dim = par->dim; - get_token(mpl /* */); - /* skip optional comma */ - if (mpl->token == T_COMMA) get_token(mpl /* , */); - } - if (slice_dimen(mpl, list) == 0) - error(mpl, "at least one parameter name required"); - get_token(mpl /* := */); - /* skip optional comma */ - if (mpl->token == T_COMMA) get_token(mpl /* , */); - /* read rows that contain tabbing data */ - while (is_symbol(mpl)) - { /* read subscript list */ - tuple = create_tuple(mpl); - for (j = 1; j <= dim; j++) - { /* read j-th subscript */ - if (!is_symbol(mpl)) - { int lack = slice_dimen(mpl, list) + dim - j + 1; - xassert(tuple != NULL); - xassert(lack > 1); - error(mpl, "%d items missing in data group beginning wit" - "h %s", lack, format_symbol(mpl, tuple->sym)); - } - /* read and append j-th subscript to the n-tuple */ - tuple = expand_tuple(mpl, tuple, read_symbol(mpl)); - /* skip optional comma *between* */ - if (j < dim && mpl->token == T_COMMA) - get_token(mpl /* , */); - } - /* if the set is specified, add to it new n-tuple, which is a - copy of the subscript list just read */ - if (set != NULL) - check_then_add(mpl, set->array->head->value.set, - copy_tuple(mpl, tuple)); - /* skip optional comma between and */ - if (mpl->token == T_COMMA) get_token(mpl /* , */); - /* read values accordingly to the column list */ - for (col = list; col != NULL; col = col->next) - { /* if the token is single point, no value is provided */ - if (is_literal(mpl, ".")) - { get_token(mpl /* . */); - continue; - } - /* read value and assign it to new parameter member */ - if (!is_symbol(mpl)) - { int lack = slice_dimen(mpl, col); - xassert(tuple != NULL); - if (lack == 1) - error(mpl, "one item missing in data group beginning " - "with %s", format_symbol(mpl, tuple->sym)); - else - error(mpl, "%d items missing in data group beginning " - "with %s", lack, format_symbol(mpl, tuple->sym)); - } - read_value(mpl, (PARAMETER *)col->sym, copy_tuple(mpl, - tuple)); - /* skip optional comma preceding the next value */ - if (col->next != NULL && mpl->token == T_COMMA) - get_token(mpl /* , */); - } - /* delete the original subscript list */ - delete_tuple(mpl, tuple); - /* skip optional comma (only if there is next data group) */ - if (mpl->token == T_COMMA) - { get_token(mpl /* , */); - if (!is_symbol(mpl)) unget_token(mpl /* , */); - } - } - /* delete the column list (it contains parameters, not symbols, - so nullify it before) */ - for (col = list; col != NULL; col = col->next) col->sym = NULL; - delete_slice(mpl, list); - return; -} - -/*---------------------------------------------------------------------- --- parameter_data - read parameter data. --- --- This routine reads parameter data using the syntax: --- --- ::= param : ; --- ::= param --- ; --- ::= --- ::= --- ::= default --- ::= --- ::= , := --- ::= , [ ] --- ::= , --- ::= , : --- ::= , (tr) --- ::= , (tr) : --- --- Commae in are optional and may be omitted anywhere. */ - -void parameter_data(MPL *mpl) -{ PARAMETER *par; - SYMBOL *altval = NULL; - SLICE *slice; - int tr = 0; - xassert(is_literal(mpl, "param")); - get_token(mpl /* param */); - /* read optional default value */ - if (is_literal(mpl, "default")) - { get_token(mpl /* default */); - if (!is_symbol(mpl)) - error(mpl, "default value missing where expected"); - altval = read_symbol(mpl); - /* if the default value follows the keyword 'param', the next - token must be only the colon */ - if (mpl->token != T_COLON) - error(mpl, "colon missing where expected"); - } - /* being used after the keyword 'param' or the optional default - value the colon begins data in the tabbing format */ - if (mpl->token == T_COLON) - { get_token(mpl /* : */); - /* skip optional comma */ - if (mpl->token == T_COMMA) get_token(mpl /* , */); - /* read parameter data in the tabbing format */ - tabbing_format(mpl, altval); - /* on reading data in the tabbing format the default value is - always copied, so delete the original symbol */ - if (altval != NULL) delete_symbol(mpl, altval); - /* the next token must be only semicolon */ - if (mpl->token != T_SEMICOLON) - error(mpl, "symbol, number, or semicolon missing where expe" - "cted"); - get_token(mpl /* ; */); - goto done; - } - /* in other cases there must be symbolic name of parameter, which - follows the keyword 'param' */ - if (!is_symbol(mpl)) - error(mpl, "parameter name missing where expected"); - /* select the parameter to saturate it with data */ - par = select_parameter(mpl, mpl->image); - get_token(mpl /* */); - /* read optional default value */ - if (is_literal(mpl, "default")) - { get_token(mpl /* default */); - if (!is_symbol(mpl)) - error(mpl, "default value missing where expected"); - altval = read_symbol(mpl); - /* set default value for the parameter */ - set_default(mpl, par, altval); - } - /* create initial fake slice of all asterisks */ - slice = fake_slice(mpl, par->dim); - /* read zero or more data assignments */ - for (;;) - { /* skip optional comma */ - if (mpl->token == T_COMMA) get_token(mpl /* , */); - /* process current assignment */ - if (mpl->token == T_ASSIGN) - { /* assignment ligature is non-significant element */ - get_token(mpl /* := */); - } - else if (mpl->token == T_LBRACKET) - { /* left bracket begins new slice; delete the current slice - and read new one */ - delete_slice(mpl, slice); - slice = read_slice(mpl, par->name, par->dim); - /* each new slice resets the "transpose" indicator */ - tr = 0; - } - else if (is_symbol(mpl)) - { /* number or symbol begins data in the plain format */ - plain_format(mpl, par, slice); - } - else if (mpl->token == T_COLON) - { /* colon begins data in the tabular format */ - if (par->dim == 0) -err1: error(mpl, "%s not a subscripted parameter", - par->name); - if (slice_arity(mpl, slice) != 2) -err2: error(mpl, "slice currently used must specify 2 asterisk" - "s, not %d", slice_arity(mpl, slice)); - get_token(mpl /* : */); - /* read parameter data in the tabular format */ - tabular_format(mpl, par, slice, tr); - } - else if (mpl->token == T_LEFT) - { /* left parenthesis begins the "transpose" indicator, which - is followed by data in the tabular format */ - get_token(mpl /* ( */); - if (!is_literal(mpl, "tr")) -err3: error(mpl, "transpose indicator (tr) incomplete"); - if (par->dim == 0) goto err1; - if (slice_arity(mpl, slice) != 2) goto err2; - get_token(mpl /* tr */); - if (mpl->token != T_RIGHT) goto err3; - get_token(mpl /* ) */); - /* in this case the colon is optional */ - if (mpl->token == T_COLON) get_token(mpl /* : */); - /* set the "transpose" indicator */ - tr = 1; - /* read parameter data in the tabular format */ - tabular_format(mpl, par, slice, tr); - } - else if (mpl->token == T_SEMICOLON) - { /* semicolon terminates the data block */ - get_token(mpl /* ; */); - break; - } - else - error(mpl, "syntax error in parameter data block"); - } - /* delete the current slice */ - delete_slice(mpl, slice); -done: return; -} - -/*---------------------------------------------------------------------- --- data_section - read data section. --- --- This routine reads data section using the syntax: --- --- ::= --- ::= ; --- ::= --- ::= --- --- Reading data section is terminated by either the keyword 'end' or --- the end of file. */ - -void data_section(MPL *mpl) -{ while (!(mpl->token == T_EOF || is_literal(mpl, "end"))) - { if (is_literal(mpl, "set")) - set_data(mpl); - else if (is_literal(mpl, "param")) - parameter_data(mpl); - else - error(mpl, "syntax error in data section"); - } - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpmpl03.c b/resources/3rdparty/glpk-4.53/src/glpmpl03.c deleted file mode 100644 index b84dd7ccf..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpmpl03.c +++ /dev/null @@ -1,6085 +0,0 @@ -/* glpmpl03.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "glpmpl.h" - -/**********************************************************************/ -/* * * FLOATING-POINT NUMBERS * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- fp_add - floating-point addition. --- --- This routine computes the sum x + y. */ - -double fp_add(MPL *mpl, double x, double y) -{ if (x > 0.0 && y > 0.0 && x > + 0.999 * DBL_MAX - y || - x < 0.0 && y < 0.0 && x < - 0.999 * DBL_MAX - y) - error(mpl, "%.*g + %.*g; floating-point overflow", - DBL_DIG, x, DBL_DIG, y); - return x + y; -} - -/*---------------------------------------------------------------------- --- fp_sub - floating-point subtraction. --- --- This routine computes the difference x - y. */ - -double fp_sub(MPL *mpl, double x, double y) -{ if (x > 0.0 && y < 0.0 && x > + 0.999 * DBL_MAX + y || - x < 0.0 && y > 0.0 && x < - 0.999 * DBL_MAX + y) - error(mpl, "%.*g - %.*g; floating-point overflow", - DBL_DIG, x, DBL_DIG, y); - return x - y; -} - -/*---------------------------------------------------------------------- --- fp_less - floating-point non-negative subtraction. --- --- This routine computes the non-negative difference max(0, x - y). */ - -double fp_less(MPL *mpl, double x, double y) -{ if (x < y) return 0.0; - if (x > 0.0 && y < 0.0 && x > + 0.999 * DBL_MAX + y) - error(mpl, "%.*g less %.*g; floating-point overflow", - DBL_DIG, x, DBL_DIG, y); - return x - y; -} - -/*---------------------------------------------------------------------- --- fp_mul - floating-point multiplication. --- --- This routine computes the product x * y. */ - -double fp_mul(MPL *mpl, double x, double y) -{ if (fabs(y) > 1.0 && fabs(x) > (0.999 * DBL_MAX) / fabs(y)) - error(mpl, "%.*g * %.*g; floating-point overflow", - DBL_DIG, x, DBL_DIG, y); - return x * y; -} - -/*---------------------------------------------------------------------- --- fp_div - floating-point division. --- --- This routine computes the quotient x / y. */ - -double fp_div(MPL *mpl, double x, double y) -{ if (fabs(y) < DBL_MIN) - error(mpl, "%.*g / %.*g; floating-point zero divide", - DBL_DIG, x, DBL_DIG, y); - if (fabs(y) < 1.0 && fabs(x) > (0.999 * DBL_MAX) * fabs(y)) - error(mpl, "%.*g / %.*g; floating-point overflow", - DBL_DIG, x, DBL_DIG, y); - return x / y; -} - -/*---------------------------------------------------------------------- --- fp_idiv - floating-point quotient of exact division. --- --- This routine computes the quotient of exact division x div y. */ - -double fp_idiv(MPL *mpl, double x, double y) -{ if (fabs(y) < DBL_MIN) - error(mpl, "%.*g div %.*g; floating-point zero divide", - DBL_DIG, x, DBL_DIG, y); - if (fabs(y) < 1.0 && fabs(x) > (0.999 * DBL_MAX) * fabs(y)) - error(mpl, "%.*g div %.*g; floating-point overflow", - DBL_DIG, x, DBL_DIG, y); - x /= y; - return x > 0.0 ? floor(x) : x < 0.0 ? ceil(x) : 0.0; -} - -/*---------------------------------------------------------------------- --- fp_mod - floating-point remainder of exact division. --- --- This routine computes the remainder of exact division x mod y. --- --- NOTE: By definition x mod y = x - y * floor(x / y). */ - -double fp_mod(MPL *mpl, double x, double y) -{ double r; - xassert(mpl == mpl); - if (x == 0.0) - r = 0.0; - else if (y == 0.0) - r = x; - else - { r = fmod(fabs(x), fabs(y)); - if (r != 0.0) - { if (x < 0.0) r = - r; - if (x > 0.0 && y < 0.0 || x < 0.0 && y > 0.0) r += y; - } - } - return r; -} - -/*---------------------------------------------------------------------- --- fp_power - floating-point exponentiation (raise to power). --- --- This routine computes the exponentiation x ** y. */ - -double fp_power(MPL *mpl, double x, double y) -{ double r; - if (x == 0.0 && y <= 0.0 || x < 0.0 && y != floor(y)) - error(mpl, "%.*g ** %.*g; result undefined", - DBL_DIG, x, DBL_DIG, y); - if (x == 0.0) goto eval; - if (fabs(x) > 1.0 && y > +1.0 && - +log(fabs(x)) > (0.999 * log(DBL_MAX)) / y || - fabs(x) < 1.0 && y < -1.0 && - +log(fabs(x)) < (0.999 * log(DBL_MAX)) / y) - error(mpl, "%.*g ** %.*g; floating-point overflow", - DBL_DIG, x, DBL_DIG, y); - if (fabs(x) > 1.0 && y < -1.0 && - -log(fabs(x)) < (0.999 * log(DBL_MAX)) / y || - fabs(x) < 1.0 && y > +1.0 && - -log(fabs(x)) > (0.999 * log(DBL_MAX)) / y) - r = 0.0; - else -eval: r = pow(x, y); - return r; -} - -/*---------------------------------------------------------------------- --- fp_exp - floating-point base-e exponential. --- --- This routine computes the base-e exponential e ** x. */ - -double fp_exp(MPL *mpl, double x) -{ if (x > 0.999 * log(DBL_MAX)) - error(mpl, "exp(%.*g); floating-point overflow", DBL_DIG, x); - return exp(x); -} - -/*---------------------------------------------------------------------- --- fp_log - floating-point natural logarithm. --- --- This routine computes the natural logarithm log x. */ - -double fp_log(MPL *mpl, double x) -{ if (x <= 0.0) - error(mpl, "log(%.*g); non-positive argument", DBL_DIG, x); - return log(x); -} - -/*---------------------------------------------------------------------- --- fp_log10 - floating-point common (decimal) logarithm. --- --- This routine computes the common (decimal) logarithm lg x. */ - -double fp_log10(MPL *mpl, double x) -{ if (x <= 0.0) - error(mpl, "log10(%.*g); non-positive argument", DBL_DIG, x); - return log10(x); -} - -/*---------------------------------------------------------------------- --- fp_sqrt - floating-point square root. --- --- This routine computes the square root x ** 0.5. */ - -double fp_sqrt(MPL *mpl, double x) -{ if (x < 0.0) - error(mpl, "sqrt(%.*g); negative argument", DBL_DIG, x); - return sqrt(x); -} - -/*---------------------------------------------------------------------- --- fp_sin - floating-point trigonometric sine. --- --- This routine computes the trigonometric sine sin(x). */ - -double fp_sin(MPL *mpl, double x) -{ if (!(-1e6 <= x && x <= +1e6)) - error(mpl, "sin(%.*g); argument too large", DBL_DIG, x); - return sin(x); -} - -/*---------------------------------------------------------------------- --- fp_cos - floating-point trigonometric cosine. --- --- This routine computes the trigonometric cosine cos(x). */ - -double fp_cos(MPL *mpl, double x) -{ if (!(-1e6 <= x && x <= +1e6)) - error(mpl, "cos(%.*g); argument too large", DBL_DIG, x); - return cos(x); -} - -/*---------------------------------------------------------------------- --- fp_atan - floating-point trigonometric arctangent. --- --- This routine computes the trigonometric arctangent atan(x). */ - -double fp_atan(MPL *mpl, double x) -{ xassert(mpl == mpl); - return atan(x); -} - -/*---------------------------------------------------------------------- --- fp_atan2 - floating-point trigonometric arctangent. --- --- This routine computes the trigonometric arctangent atan(y / x). */ - -double fp_atan2(MPL *mpl, double y, double x) -{ xassert(mpl == mpl); - return atan2(y, x); -} - -/*---------------------------------------------------------------------- --- fp_round - round floating-point value to n fractional digits. --- --- This routine rounds given floating-point value x to n fractional --- digits with the formula: --- --- round(x, n) = floor(x * 10^n + 0.5) / 10^n. --- --- The parameter n is assumed to be integer. */ - -double fp_round(MPL *mpl, double x, double n) -{ double ten_to_n; - if (n != floor(n)) - error(mpl, "round(%.*g, %.*g); non-integer second argument", - DBL_DIG, x, DBL_DIG, n); - if (n <= DBL_DIG + 2) - { ten_to_n = pow(10.0, n); - if (fabs(x) < (0.999 * DBL_MAX) / ten_to_n) - { x = floor(x * ten_to_n + 0.5); - if (x != 0.0) x /= ten_to_n; - } - } - return x; -} - -/*---------------------------------------------------------------------- --- fp_trunc - truncate floating-point value to n fractional digits. --- --- This routine truncates given floating-point value x to n fractional --- digits with the formula: --- --- ( floor(x * 10^n) / 10^n, if x >= 0 --- trunc(x, n) = < --- ( ceil(x * 10^n) / 10^n, if x < 0 --- --- The parameter n is assumed to be integer. */ - -double fp_trunc(MPL *mpl, double x, double n) -{ double ten_to_n; - if (n != floor(n)) - error(mpl, "trunc(%.*g, %.*g); non-integer second argument", - DBL_DIG, x, DBL_DIG, n); - if (n <= DBL_DIG + 2) - { ten_to_n = pow(10.0, n); - if (fabs(x) < (0.999 * DBL_MAX) / ten_to_n) - { x = (x >= 0.0 ? floor(x * ten_to_n) : ceil(x * ten_to_n)); - if (x != 0.0) x /= ten_to_n; - } - } - return x; -} - -/**********************************************************************/ -/* * * PSEUDO-RANDOM NUMBER GENERATORS * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- fp_irand224 - pseudo-random integer in the range [0, 2^24). --- --- This routine returns a next pseudo-random integer (converted to --- floating-point) which is uniformly distributed between 0 and 2^24-1, --- inclusive. */ - -#define two_to_the_24 0x1000000 - -double fp_irand224(MPL *mpl) -{ return - (double)rng_unif_rand(mpl->rand, two_to_the_24); -} - -/*---------------------------------------------------------------------- --- fp_uniform01 - pseudo-random number in the range [0, 1). --- --- This routine returns a next pseudo-random number which is uniformly --- distributed in the range [0, 1). */ - -#define two_to_the_31 ((unsigned int)0x80000000) - -double fp_uniform01(MPL *mpl) -{ return - (double)rng_next_rand(mpl->rand) / (double)two_to_the_31; -} - -/*---------------------------------------------------------------------- --- fp_uniform - pseudo-random number in the range [a, b). --- --- This routine returns a next pseudo-random number which is uniformly --- distributed in the range [a, b). */ - -double fp_uniform(MPL *mpl, double a, double b) -{ double x; - if (a >= b) - error(mpl, "Uniform(%.*g, %.*g); invalid range", - DBL_DIG, a, DBL_DIG, b); - x = fp_uniform01(mpl); -#if 0 - x = a * (1.0 - x) + b * x; -#else - x = fp_add(mpl, a * (1.0 - x), b * x); -#endif - return x; -} - -/*---------------------------------------------------------------------- --- fp_normal01 - Gaussian random variate with mu = 0 and sigma = 1. --- --- This routine returns a Gaussian random variate with zero mean and --- unit standard deviation. The polar (Box-Mueller) method is used. --- --- This code is a modified version of the routine gsl_ran_gaussian from --- the GNU Scientific Library Version 1.0. */ - -double fp_normal01(MPL *mpl) -{ double x, y, r2; - do - { /* choose x, y in uniform square (-1,-1) to (+1,+1) */ - x = -1.0 + 2.0 * fp_uniform01(mpl); - y = -1.0 + 2.0 * fp_uniform01(mpl); - /* see if it is in the unit circle */ - r2 = x * x + y * y; - } while (r2 > 1.0 || r2 == 0.0); - /* Box-Muller transform */ - return y * sqrt(-2.0 * log (r2) / r2); -} - -/*---------------------------------------------------------------------- --- fp_normal - Gaussian random variate with specified mu and sigma. --- --- This routine returns a Gaussian random variate with mean mu and --- standard deviation sigma. */ - -double fp_normal(MPL *mpl, double mu, double sigma) -{ double x; -#if 0 - x = mu + sigma * fp_normal01(mpl); -#else - x = fp_add(mpl, mu, fp_mul(mpl, sigma, fp_normal01(mpl))); -#endif - return x; -} - -/**********************************************************************/ -/* * * SEGMENTED CHARACTER STRINGS * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- create_string - create character string. --- --- This routine creates a segmented character string, which is exactly --- equivalent to specified character string. */ - -STRING *create_string -( MPL *mpl, - char buf[MAX_LENGTH+1] /* not changed */ -) -#if 0 -{ STRING *head, *tail; - int i, j; - xassert(buf != NULL); - xassert(strlen(buf) <= MAX_LENGTH); - head = tail = dmp_get_atom(mpl->strings, sizeof(STRING)); - for (i = j = 0; ; i++) - { if ((tail->seg[j++] = buf[i]) == '\0') break; - if (j == STRSEG_SIZE) -tail = (tail->next = dmp_get_atom(mpl->strings, sizeof(STRING))), j = 0; - } - tail->next = NULL; - return head; -} -#else -{ STRING *str; - xassert(strlen(buf) <= MAX_LENGTH); - str = dmp_get_atom(mpl->strings, strlen(buf)+1); - strcpy(str, buf); - return str; -} -#endif - -/*---------------------------------------------------------------------- --- copy_string - make copy of character string. --- --- This routine returns an exact copy of segmented character string. */ - -STRING *copy_string -( MPL *mpl, - STRING *str /* not changed */ -) -#if 0 -{ STRING *head, *tail; - xassert(str != NULL); - head = tail = dmp_get_atom(mpl->strings, sizeof(STRING)); - for (; str != NULL; str = str->next) - { memcpy(tail->seg, str->seg, STRSEG_SIZE); - if (str->next != NULL) -tail = (tail->next = dmp_get_atom(mpl->strings, sizeof(STRING))); - } - tail->next = NULL; - return head; -} -#else -{ xassert(mpl == mpl); - return create_string(mpl, str); -} -#endif - -/*---------------------------------------------------------------------- --- compare_strings - compare one character string with another. --- --- This routine compares one segmented character strings with another --- and returns the result of comparison as follows: --- --- = 0 - both strings are identical; --- < 0 - the first string precedes the second one; --- > 0 - the first string follows the second one. */ - -int compare_strings -( MPL *mpl, - STRING *str1, /* not changed */ - STRING *str2 /* not changed */ -) -#if 0 -{ int j, c1, c2; - xassert(mpl == mpl); - for (;; str1 = str1->next, str2 = str2->next) - { xassert(str1 != NULL); - xassert(str2 != NULL); - for (j = 0; j < STRSEG_SIZE; j++) - { c1 = (unsigned char)str1->seg[j]; - c2 = (unsigned char)str2->seg[j]; - if (c1 < c2) return -1; - if (c1 > c2) return +1; - if (c1 == '\0') goto done; - } - } -done: return 0; -} -#else -{ xassert(mpl == mpl); - return strcmp(str1, str2); -} -#endif - -/*---------------------------------------------------------------------- --- fetch_string - extract content of character string. --- --- This routine returns a character string, which is exactly equivalent --- to specified segmented character string. */ - -char *fetch_string -( MPL *mpl, - STRING *str, /* not changed */ - char buf[MAX_LENGTH+1] /* modified */ -) -#if 0 -{ int i, j; - xassert(mpl == mpl); - xassert(buf != NULL); - for (i = 0; ; str = str->next) - { xassert(str != NULL); - for (j = 0; j < STRSEG_SIZE; j++) - if ((buf[i++] = str->seg[j]) == '\0') goto done; - } -done: xassert(strlen(buf) <= MAX_LENGTH); - return buf; -} -#else -{ xassert(mpl == mpl); - return strcpy(buf, str); -} -#endif - -/*---------------------------------------------------------------------- --- delete_string - delete character string. --- --- This routine deletes specified segmented character string. */ - -void delete_string -( MPL *mpl, - STRING *str /* destroyed */ -) -#if 0 -{ STRING *temp; - xassert(str != NULL); - while (str != NULL) - { temp = str; - str = str->next; - dmp_free_atom(mpl->strings, temp, sizeof(STRING)); - } - return; -} -#else -{ dmp_free_atom(mpl->strings, str, strlen(str)+1); - return; -} -#endif - -/**********************************************************************/ -/* * * SYMBOLS * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- create_symbol_num - create symbol of numeric type. --- --- This routine creates a symbol, which has a numeric value specified --- as floating-point number. */ - -SYMBOL *create_symbol_num(MPL *mpl, double num) -{ SYMBOL *sym; - sym = dmp_get_atom(mpl->symbols, sizeof(SYMBOL)); - sym->num = num; - sym->str = NULL; - return sym; -} - -/*---------------------------------------------------------------------- --- create_symbol_str - create symbol of abstract type. --- --- This routine creates a symbol, which has an abstract value specified --- as segmented character string. */ - -SYMBOL *create_symbol_str -( MPL *mpl, - STRING *str /* destroyed */ -) -{ SYMBOL *sym; - xassert(str != NULL); - sym = dmp_get_atom(mpl->symbols, sizeof(SYMBOL)); - sym->num = 0.0; - sym->str = str; - return sym; -} - -/*---------------------------------------------------------------------- --- copy_symbol - make copy of symbol. --- --- This routine returns an exact copy of symbol. */ - -SYMBOL *copy_symbol -( MPL *mpl, - SYMBOL *sym /* not changed */ -) -{ SYMBOL *copy; - xassert(sym != NULL); - copy = dmp_get_atom(mpl->symbols, sizeof(SYMBOL)); - if (sym->str == NULL) - { copy->num = sym->num; - copy->str = NULL; - } - else - { copy->num = 0.0; - copy->str = copy_string(mpl, sym->str); - } - return copy; -} - -/*---------------------------------------------------------------------- --- compare_symbols - compare one symbol with another. --- --- This routine compares one symbol with another and returns the result --- of comparison as follows: --- --- = 0 - both symbols are identical; --- < 0 - the first symbol precedes the second one; --- > 0 - the first symbol follows the second one. --- --- Note that the linear order, in which symbols follow each other, is --- implementation-dependent. It may be not an alphabetical order. */ - -int compare_symbols -( MPL *mpl, - SYMBOL *sym1, /* not changed */ - SYMBOL *sym2 /* not changed */ -) -{ xassert(sym1 != NULL); - xassert(sym2 != NULL); - /* let all numeric quantities precede all symbolic quantities */ - if (sym1->str == NULL && sym2->str == NULL) - { if (sym1->num < sym2->num) return -1; - if (sym1->num > sym2->num) return +1; - return 0; - } - if (sym1->str == NULL) return -1; - if (sym2->str == NULL) return +1; - return compare_strings(mpl, sym1->str, sym2->str); -} - -/*---------------------------------------------------------------------- --- delete_symbol - delete symbol. --- --- This routine deletes specified symbol. */ - -void delete_symbol -( MPL *mpl, - SYMBOL *sym /* destroyed */ -) -{ xassert(sym != NULL); - if (sym->str != NULL) delete_string(mpl, sym->str); - dmp_free_atom(mpl->symbols, sym, sizeof(SYMBOL)); - return; -} - -/*---------------------------------------------------------------------- --- format_symbol - format symbol for displaying or printing. --- --- This routine converts specified symbol to a charater string, which --- is suitable for displaying or printing. --- --- The resultant string is never longer than 255 characters. If it gets --- longer, it is truncated from the right and appended by dots. */ - -char *format_symbol -( MPL *mpl, - SYMBOL *sym /* not changed */ -) -{ char *buf = mpl->sym_buf; - xassert(sym != NULL); - if (sym->str == NULL) - sprintf(buf, "%.*g", DBL_DIG, sym->num); - else - { char str[MAX_LENGTH+1]; - int quoted, j, len; - fetch_string(mpl, sym->str, str); - if (!(isalpha((unsigned char)str[0]) || str[0] == '_')) - quoted = 1; - else - { quoted = 0; - for (j = 1; str[j] != '\0'; j++) - { if (!(isalnum((unsigned char)str[j]) || - strchr("+-._", (unsigned char)str[j]) != NULL)) - { quoted = 1; - break; - } - } - } -# define safe_append(c) \ - (void)(len < 255 ? (buf[len++] = (char)(c)) : 0) - buf[0] = '\0', len = 0; - if (quoted) safe_append('\''); - for (j = 0; str[j] != '\0'; j++) - { if (quoted && str[j] == '\'') safe_append('\''); - safe_append(str[j]); - } - if (quoted) safe_append('\''); -# undef safe_append - buf[len] = '\0'; - if (len == 255) strcpy(buf+252, "..."); - } - xassert(strlen(buf) <= 255); - return buf; -} - -/*---------------------------------------------------------------------- --- concat_symbols - concatenate one symbol with another. --- --- This routine concatenates values of two given symbols and assigns --- the resultant character string to a new symbol, which is returned on --- exit. Both original symbols are destroyed. */ - -SYMBOL *concat_symbols -( MPL *mpl, - SYMBOL *sym1, /* destroyed */ - SYMBOL *sym2 /* destroyed */ -) -{ char str1[MAX_LENGTH+1], str2[MAX_LENGTH+1]; - xassert(MAX_LENGTH >= DBL_DIG + DBL_DIG); - if (sym1->str == NULL) - sprintf(str1, "%.*g", DBL_DIG, sym1->num); - else - fetch_string(mpl, sym1->str, str1); - if (sym2->str == NULL) - sprintf(str2, "%.*g", DBL_DIG, sym2->num); - else - fetch_string(mpl, sym2->str, str2); - if (strlen(str1) + strlen(str2) > MAX_LENGTH) - { char buf[255+1]; - strcpy(buf, format_symbol(mpl, sym1)); - xassert(strlen(buf) < sizeof(buf)); - error(mpl, "%s & %s; resultant symbol exceeds %d characters", - buf, format_symbol(mpl, sym2), MAX_LENGTH); - } - delete_symbol(mpl, sym1); - delete_symbol(mpl, sym2); - return create_symbol_str(mpl, create_string(mpl, strcat(str1, - str2))); -} - -/**********************************************************************/ -/* * * N-TUPLES * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- create_tuple - create n-tuple. --- --- This routine creates a n-tuple, which initially has no components, --- i.e. which is 0-tuple. */ - -TUPLE *create_tuple(MPL *mpl) -{ TUPLE *tuple; - xassert(mpl == mpl); - tuple = NULL; - return tuple; -} - -/*---------------------------------------------------------------------- --- expand_tuple - append symbol to n-tuple. --- --- This routine expands n-tuple appending to it a given symbol, which --- becomes its new last component. */ - -TUPLE *expand_tuple -( MPL *mpl, - TUPLE *tuple, /* destroyed */ - SYMBOL *sym /* destroyed */ -) -{ TUPLE *tail, *temp; - xassert(sym != NULL); - /* create a new component */ - tail = dmp_get_atom(mpl->tuples, sizeof(TUPLE)); - tail->sym = sym; - tail->next = NULL; - /* and append it to the component list */ - if (tuple == NULL) - tuple = tail; - else - { for (temp = tuple; temp->next != NULL; temp = temp->next); - temp->next = tail; - } - return tuple; -} - -/*---------------------------------------------------------------------- --- tuple_dimen - determine dimension of n-tuple. --- --- This routine returns dimension of n-tuple, i.e. number of components --- in the n-tuple. */ - -int tuple_dimen -( MPL *mpl, - TUPLE *tuple /* not changed */ -) -{ TUPLE *temp; - int dim = 0; - xassert(mpl == mpl); - for (temp = tuple; temp != NULL; temp = temp->next) dim++; - return dim; -} - -/*---------------------------------------------------------------------- --- copy_tuple - make copy of n-tuple. --- --- This routine returns an exact copy of n-tuple. */ - -TUPLE *copy_tuple -( MPL *mpl, - TUPLE *tuple /* not changed */ -) -{ TUPLE *head, *tail; - if (tuple == NULL) - head = NULL; - else - { head = tail = dmp_get_atom(mpl->tuples, sizeof(TUPLE)); - for (; tuple != NULL; tuple = tuple->next) - { xassert(tuple->sym != NULL); - tail->sym = copy_symbol(mpl, tuple->sym); - if (tuple->next != NULL) -tail = (tail->next = dmp_get_atom(mpl->tuples, sizeof(TUPLE))); - } - tail->next = NULL; - } - return head; -} - -/*---------------------------------------------------------------------- --- compare_tuples - compare one n-tuple with another. --- --- This routine compares two given n-tuples, which must have the same --- dimension (not checked for the sake of efficiency), and returns one --- of the following codes: --- --- = 0 - both n-tuples are identical; --- < 0 - the first n-tuple precedes the second one; --- > 0 - the first n-tuple follows the second one. --- --- Note that the linear order, in which n-tuples follow each other, is --- implementation-dependent. It may be not an alphabetical order. */ - -int compare_tuples -( MPL *mpl, - TUPLE *tuple1, /* not changed */ - TUPLE *tuple2 /* not changed */ -) -{ TUPLE *item1, *item2; - int ret; - xassert(mpl == mpl); - for (item1 = tuple1, item2 = tuple2; item1 != NULL; - item1 = item1->next, item2 = item2->next) - { xassert(item2 != NULL); - xassert(item1->sym != NULL); - xassert(item2->sym != NULL); - ret = compare_symbols(mpl, item1->sym, item2->sym); - if (ret != 0) return ret; - } - xassert(item2 == NULL); - return 0; -} - -/*---------------------------------------------------------------------- --- build_subtuple - build subtuple of given n-tuple. --- --- This routine builds subtuple, which consists of first dim components --- of given n-tuple. */ - -TUPLE *build_subtuple -( MPL *mpl, - TUPLE *tuple, /* not changed */ - int dim -) -{ TUPLE *head, *temp; - int j; - head = create_tuple(mpl); - for (j = 1, temp = tuple; j <= dim; j++, temp = temp->next) - { xassert(temp != NULL); - head = expand_tuple(mpl, head, copy_symbol(mpl, temp->sym)); - } - return head; -} - -/*---------------------------------------------------------------------- --- delete_tuple - delete n-tuple. --- --- This routine deletes specified n-tuple. */ - -void delete_tuple -( MPL *mpl, - TUPLE *tuple /* destroyed */ -) -{ TUPLE *temp; - while (tuple != NULL) - { temp = tuple; - tuple = temp->next; - xassert(temp->sym != NULL); - delete_symbol(mpl, temp->sym); - dmp_free_atom(mpl->tuples, temp, sizeof(TUPLE)); - } - return; -} - -/*---------------------------------------------------------------------- --- format_tuple - format n-tuple for displaying or printing. --- --- This routine converts specified n-tuple to a character string, which --- is suitable for displaying or printing. --- --- The resultant string is never longer than 255 characters. If it gets --- longer, it is truncated from the right and appended by dots. */ - -char *format_tuple -( MPL *mpl, - int c, - TUPLE *tuple /* not changed */ -) -{ TUPLE *temp; - int dim, j, len; - char *buf = mpl->tup_buf, str[255+1], *save; -# define safe_append(c) \ - (void)(len < 255 ? (buf[len++] = (char)(c)) : 0) - buf[0] = '\0', len = 0; - dim = tuple_dimen(mpl, tuple); - if (c == '[' && dim > 0) safe_append('['); - if (c == '(' && dim > 1) safe_append('('); - for (temp = tuple; temp != NULL; temp = temp->next) - { if (temp != tuple) safe_append(','); - xassert(temp->sym != NULL); - save = mpl->sym_buf; - mpl->sym_buf = str; - format_symbol(mpl, temp->sym); - mpl->sym_buf = save; - xassert(strlen(str) < sizeof(str)); - for (j = 0; str[j] != '\0'; j++) safe_append(str[j]); - } - if (c == '[' && dim > 0) safe_append(']'); - if (c == '(' && dim > 1) safe_append(')'); -# undef safe_append - buf[len] = '\0'; - if (len == 255) strcpy(buf+252, "..."); - xassert(strlen(buf) <= 255); - return buf; -} - -/**********************************************************************/ -/* * * ELEMENTAL SETS * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- create_elemset - create elemental set. --- --- This routine creates an elemental set, whose members are n-tuples of --- specified dimension. Being created the set is initially empty. */ - -ELEMSET *create_elemset(MPL *mpl, int dim) -{ ELEMSET *set; - xassert(dim > 0); - set = create_array(mpl, A_NONE, dim); - return set; -} - -/*---------------------------------------------------------------------- --- find_tuple - check if elemental set contains given n-tuple. --- --- This routine finds given n-tuple in specified elemental set in order --- to check if the set contains that n-tuple. If the n-tuple is found, --- the routine returns pointer to corresponding array member. Otherwise --- null pointer is returned. */ - -MEMBER *find_tuple -( MPL *mpl, - ELEMSET *set, /* not changed */ - TUPLE *tuple /* not changed */ -) -{ xassert(set != NULL); - xassert(set->type == A_NONE); - xassert(set->dim == tuple_dimen(mpl, tuple)); - return find_member(mpl, set, tuple); -} - -/*---------------------------------------------------------------------- --- add_tuple - add new n-tuple to elemental set. --- --- This routine adds given n-tuple to specified elemental set. --- --- For the sake of efficiency this routine doesn't check whether the --- set already contains the same n-tuple or not. Therefore the calling --- program should use the routine find_tuple (if necessary) in order to --- make sure that the given n-tuple is not contained in the set, since --- duplicate n-tuples within the same set are not allowed. */ - -MEMBER *add_tuple -( MPL *mpl, - ELEMSET *set, /* modified */ - TUPLE *tuple /* destroyed */ -) -{ MEMBER *memb; - xassert(set != NULL); - xassert(set->type == A_NONE); - xassert(set->dim == tuple_dimen(mpl, tuple)); - memb = add_member(mpl, set, tuple); - memb->value.none = NULL; - return memb; -} - -/*---------------------------------------------------------------------- --- check_then_add - check and add new n-tuple to elemental set. --- --- This routine is equivalent to the routine add_tuple except that it --- does check for duplicate n-tuples. */ - -MEMBER *check_then_add -( MPL *mpl, - ELEMSET *set, /* modified */ - TUPLE *tuple /* destroyed */ -) -{ if (find_tuple(mpl, set, tuple) != NULL) - error(mpl, "duplicate tuple %s detected", format_tuple(mpl, - '(', tuple)); - return add_tuple(mpl, set, tuple); -} - -/*---------------------------------------------------------------------- --- copy_elemset - make copy of elemental set. --- --- This routine makes an exact copy of elemental set. */ - -ELEMSET *copy_elemset -( MPL *mpl, - ELEMSET *set /* not changed */ -) -{ ELEMSET *copy; - MEMBER *memb; - xassert(set != NULL); - xassert(set->type == A_NONE); - xassert(set->dim > 0); - copy = create_elemset(mpl, set->dim); - for (memb = set->head; memb != NULL; memb = memb->next) - add_tuple(mpl, copy, copy_tuple(mpl, memb->tuple)); - return copy; -} - -/*---------------------------------------------------------------------- --- delete_elemset - delete elemental set. --- --- This routine deletes specified elemental set. */ - -void delete_elemset -( MPL *mpl, - ELEMSET *set /* destroyed */ -) -{ xassert(set != NULL); - xassert(set->type == A_NONE); - delete_array(mpl, set); - return; -} - -/*---------------------------------------------------------------------- --- arelset_size - compute size of "arithmetic" elemental set. --- --- This routine computes the size of "arithmetic" elemental set, which --- is specified in the form of arithmetic progression: --- --- { t0 .. tf by dt }. --- --- The size is computed using the formula: --- --- n = max(0, floor((tf - t0) / dt) + 1). */ - -int arelset_size(MPL *mpl, double t0, double tf, double dt) -{ double temp; - if (dt == 0.0) - error(mpl, "%.*g .. %.*g by %.*g; zero stride not allowed", - DBL_DIG, t0, DBL_DIG, tf, DBL_DIG, dt); - if (tf > 0.0 && t0 < 0.0 && tf > + 0.999 * DBL_MAX + t0) - temp = +DBL_MAX; - else if (tf < 0.0 && t0 > 0.0 && tf < - 0.999 * DBL_MAX + t0) - temp = -DBL_MAX; - else - temp = tf - t0; - if (fabs(dt) < 1.0 && fabs(temp) > (0.999 * DBL_MAX) * fabs(dt)) - { if (temp > 0.0 && dt > 0.0 || temp < 0.0 && dt < 0.0) - temp = +DBL_MAX; - else - temp = 0.0; - } - else - { temp = floor(temp / dt) + 1.0; - if (temp < 0.0) temp = 0.0; - } - xassert(temp >= 0.0); - if (temp > (double)(INT_MAX - 1)) - error(mpl, "%.*g .. %.*g by %.*g; set too large", - DBL_DIG, t0, DBL_DIG, tf, DBL_DIG, dt); - return (int)(temp + 0.5); -} - -/*---------------------------------------------------------------------- --- arelset_member - compute member of "arithmetic" elemental set. --- --- This routine returns a numeric value of symbol, which is equivalent --- to j-th member of given "arithmetic" elemental set specified in the --- form of arithmetic progression: --- --- { t0 .. tf by dt }. --- --- The symbol value is computed with the formula: --- --- j-th member = t0 + (j - 1) * dt, --- --- The number j must satisfy to the restriction 1 <= j <= n, where n is --- the set size computed by the routine arelset_size. */ - -double arelset_member(MPL *mpl, double t0, double tf, double dt, int j) -{ xassert(1 <= j && j <= arelset_size(mpl, t0, tf, dt)); - return t0 + (double)(j - 1) * dt; -} - -/*---------------------------------------------------------------------- --- create_arelset - create "arithmetic" elemental set. --- --- This routine creates "arithmetic" elemental set, which is specified --- in the form of arithmetic progression: --- --- { t0 .. tf by dt }. --- --- Components of this set are 1-tuples. */ - -ELEMSET *create_arelset(MPL *mpl, double t0, double tf, double dt) -{ ELEMSET *set; - int j, n; - set = create_elemset(mpl, 1); - n = arelset_size(mpl, t0, tf, dt); - for (j = 1; j <= n; j++) - { add_tuple - ( mpl, - set, - expand_tuple - ( mpl, - create_tuple(mpl), - create_symbol_num - ( mpl, - arelset_member(mpl, t0, tf, dt, j) - ) - ) - ); - } - return set; -} - -/*---------------------------------------------------------------------- --- set_union - union of two elemental sets. --- --- This routine computes the union: --- --- X U Y = { j | (j in X) or (j in Y) }, --- --- where X and Y are given elemental sets (destroyed on exit). */ - -ELEMSET *set_union -( MPL *mpl, - ELEMSET *X, /* destroyed */ - ELEMSET *Y /* destroyed */ -) -{ MEMBER *memb; - xassert(X != NULL); - xassert(X->type == A_NONE); - xassert(X->dim > 0); - xassert(Y != NULL); - xassert(Y->type == A_NONE); - xassert(Y->dim > 0); - xassert(X->dim == Y->dim); - for (memb = Y->head; memb != NULL; memb = memb->next) - { if (find_tuple(mpl, X, memb->tuple) == NULL) - add_tuple(mpl, X, copy_tuple(mpl, memb->tuple)); - } - delete_elemset(mpl, Y); - return X; -} - -/*---------------------------------------------------------------------- --- set_diff - difference between two elemental sets. --- --- This routine computes the difference: --- --- X \ Y = { j | (j in X) and (j not in Y) }, --- --- where X and Y are given elemental sets (destroyed on exit). */ - -ELEMSET *set_diff -( MPL *mpl, - ELEMSET *X, /* destroyed */ - ELEMSET *Y /* destroyed */ -) -{ ELEMSET *Z; - MEMBER *memb; - xassert(X != NULL); - xassert(X->type == A_NONE); - xassert(X->dim > 0); - xassert(Y != NULL); - xassert(Y->type == A_NONE); - xassert(Y->dim > 0); - xassert(X->dim == Y->dim); - Z = create_elemset(mpl, X->dim); - for (memb = X->head; memb != NULL; memb = memb->next) - { if (find_tuple(mpl, Y, memb->tuple) == NULL) - add_tuple(mpl, Z, copy_tuple(mpl, memb->tuple)); - } - delete_elemset(mpl, X); - delete_elemset(mpl, Y); - return Z; -} - -/*---------------------------------------------------------------------- --- set_symdiff - symmetric difference between two elemental sets. --- --- This routine computes the symmetric difference: --- --- X (+) Y = (X \ Y) U (Y \ X), --- --- where X and Y are given elemental sets (destroyed on exit). */ - -ELEMSET *set_symdiff -( MPL *mpl, - ELEMSET *X, /* destroyed */ - ELEMSET *Y /* destroyed */ -) -{ ELEMSET *Z; - MEMBER *memb; - xassert(X != NULL); - xassert(X->type == A_NONE); - xassert(X->dim > 0); - xassert(Y != NULL); - xassert(Y->type == A_NONE); - xassert(Y->dim > 0); - xassert(X->dim == Y->dim); - /* Z := X \ Y */ - Z = create_elemset(mpl, X->dim); - for (memb = X->head; memb != NULL; memb = memb->next) - { if (find_tuple(mpl, Y, memb->tuple) == NULL) - add_tuple(mpl, Z, copy_tuple(mpl, memb->tuple)); - } - /* Z := Z U (Y \ X) */ - for (memb = Y->head; memb != NULL; memb = memb->next) - { if (find_tuple(mpl, X, memb->tuple) == NULL) - add_tuple(mpl, Z, copy_tuple(mpl, memb->tuple)); - } - delete_elemset(mpl, X); - delete_elemset(mpl, Y); - return Z; -} - -/*---------------------------------------------------------------------- --- set_inter - intersection of two elemental sets. --- --- This routine computes the intersection: --- --- X ^ Y = { j | (j in X) and (j in Y) }, --- --- where X and Y are given elemental sets (destroyed on exit). */ - -ELEMSET *set_inter -( MPL *mpl, - ELEMSET *X, /* destroyed */ - ELEMSET *Y /* destroyed */ -) -{ ELEMSET *Z; - MEMBER *memb; - xassert(X != NULL); - xassert(X->type == A_NONE); - xassert(X->dim > 0); - xassert(Y != NULL); - xassert(Y->type == A_NONE); - xassert(Y->dim > 0); - xassert(X->dim == Y->dim); - Z = create_elemset(mpl, X->dim); - for (memb = X->head; memb != NULL; memb = memb->next) - { if (find_tuple(mpl, Y, memb->tuple) != NULL) - add_tuple(mpl, Z, copy_tuple(mpl, memb->tuple)); - } - delete_elemset(mpl, X); - delete_elemset(mpl, Y); - return Z; -} - -/*---------------------------------------------------------------------- --- set_cross - cross (Cartesian) product of two elemental sets. --- --- This routine computes the cross (Cartesian) product: --- --- X x Y = { (i,j) | (i in X) and (j in Y) }, --- --- where X and Y are given elemental sets (destroyed on exit). */ - -ELEMSET *set_cross -( MPL *mpl, - ELEMSET *X, /* destroyed */ - ELEMSET *Y /* destroyed */ -) -{ ELEMSET *Z; - MEMBER *memx, *memy; - TUPLE *tuple, *temp; - xassert(X != NULL); - xassert(X->type == A_NONE); - xassert(X->dim > 0); - xassert(Y != NULL); - xassert(Y->type == A_NONE); - xassert(Y->dim > 0); - Z = create_elemset(mpl, X->dim + Y->dim); - for (memx = X->head; memx != NULL; memx = memx->next) - { for (memy = Y->head; memy != NULL; memy = memy->next) - { tuple = copy_tuple(mpl, memx->tuple); - for (temp = memy->tuple; temp != NULL; temp = temp->next) - tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, - temp->sym)); - add_tuple(mpl, Z, tuple); - } - } - delete_elemset(mpl, X); - delete_elemset(mpl, Y); - return Z; -} - -/**********************************************************************/ -/* * * ELEMENTAL VARIABLES * * */ -/**********************************************************************/ - -/* (there are no specific routines for elemental variables) */ - -/**********************************************************************/ -/* * * LINEAR FORMS * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- constant_term - create constant term. --- --- This routine creates the linear form, which is a constant term. */ - -FORMULA *constant_term(MPL *mpl, double coef) -{ FORMULA *form; - if (coef == 0.0) - form = NULL; - else - { form = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); - form->coef = coef; - form->var = NULL; - form->next = NULL; - } - return form; -} - -/*---------------------------------------------------------------------- --- single_variable - create single variable. --- --- This routine creates the linear form, which is a single elemental --- variable. */ - -FORMULA *single_variable -( MPL *mpl, - ELEMVAR *var /* referenced */ -) -{ FORMULA *form; - xassert(var != NULL); - form = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); - form->coef = 1.0; - form->var = var; - form->next = NULL; - return form; -} - -/*---------------------------------------------------------------------- --- copy_formula - make copy of linear form. --- --- This routine returns an exact copy of linear form. */ - -FORMULA *copy_formula -( MPL *mpl, - FORMULA *form /* not changed */ -) -{ FORMULA *head, *tail; - if (form == NULL) - head = NULL; - else - { head = tail = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); - for (; form != NULL; form = form->next) - { tail->coef = form->coef; - tail->var = form->var; - if (form->next != NULL) -tail = (tail->next = dmp_get_atom(mpl->formulae, sizeof(FORMULA))); - } - tail->next = NULL; - } - return head; -} - -/*---------------------------------------------------------------------- --- delete_formula - delete linear form. --- --- This routine deletes specified linear form. */ - -void delete_formula -( MPL *mpl, - FORMULA *form /* destroyed */ -) -{ FORMULA *temp; - while (form != NULL) - { temp = form; - form = form->next; - dmp_free_atom(mpl->formulae, temp, sizeof(FORMULA)); - } - return; -} - -/*---------------------------------------------------------------------- --- linear_comb - linear combination of two linear forms. --- --- This routine computes the linear combination: --- --- a * fx + b * fy, --- --- where a and b are numeric coefficients, fx and fy are linear forms --- (destroyed on exit). */ - -FORMULA *linear_comb -( MPL *mpl, - double a, FORMULA *fx, /* destroyed */ - double b, FORMULA *fy /* destroyed */ -) -{ FORMULA *form = NULL, *term, *temp; - double c0 = 0.0; - for (term = fx; term != NULL; term = term->next) - { if (term->var == NULL) - c0 = fp_add(mpl, c0, fp_mul(mpl, a, term->coef)); - else - term->var->temp = - fp_add(mpl, term->var->temp, fp_mul(mpl, a, term->coef)); - } - for (term = fy; term != NULL; term = term->next) - { if (term->var == NULL) - c0 = fp_add(mpl, c0, fp_mul(mpl, b, term->coef)); - else - term->var->temp = - fp_add(mpl, term->var->temp, fp_mul(mpl, b, term->coef)); - } - for (term = fx; term != NULL; term = term->next) - { if (term->var != NULL && term->var->temp != 0.0) - { temp = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); - temp->coef = term->var->temp, temp->var = term->var; - temp->next = form, form = temp; - term->var->temp = 0.0; - } - } - for (term = fy; term != NULL; term = term->next) - { if (term->var != NULL && term->var->temp != 0.0) - { temp = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); - temp->coef = term->var->temp, temp->var = term->var; - temp->next = form, form = temp; - term->var->temp = 0.0; - } - } - if (c0 != 0.0) - { temp = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); - temp->coef = c0, temp->var = NULL; - temp->next = form, form = temp; - } - delete_formula(mpl, fx); - delete_formula(mpl, fy); - return form; -} - -/*---------------------------------------------------------------------- --- remove_constant - remove constant term from linear form. --- --- This routine removes constant term from linear form and stores its --- value to given location. */ - -FORMULA *remove_constant -( MPL *mpl, - FORMULA *form, /* destroyed */ - double *coef /* modified */ -) -{ FORMULA *head = NULL, *temp; - *coef = 0.0; - while (form != NULL) - { temp = form; - form = form->next; - if (temp->var == NULL) - { /* constant term */ - *coef = fp_add(mpl, *coef, temp->coef); - dmp_free_atom(mpl->formulae, temp, sizeof(FORMULA)); - } - else - { /* linear term */ - temp->next = head; - head = temp; - } - } - return head; -} - -/*---------------------------------------------------------------------- --- reduce_terms - reduce identical terms in linear form. --- --- This routine reduces identical terms in specified linear form. */ - -FORMULA *reduce_terms -( MPL *mpl, - FORMULA *form /* destroyed */ -) -{ FORMULA *term, *next_term; - double c0 = 0.0; - for (term = form; term != NULL; term = term->next) - { if (term->var == NULL) - c0 = fp_add(mpl, c0, term->coef); - else - term->var->temp = fp_add(mpl, term->var->temp, term->coef); - } - next_term = form, form = NULL; - for (term = next_term; term != NULL; term = next_term) - { next_term = term->next; - if (term->var == NULL && c0 != 0.0) - { term->coef = c0, c0 = 0.0; - term->next = form, form = term; - } - else if (term->var != NULL && term->var->temp != 0.0) - { term->coef = term->var->temp, term->var->temp = 0.0; - term->next = form, form = term; - } - else - dmp_free_atom(mpl->formulae, term, sizeof(FORMULA)); - } - return form; -} - -/**********************************************************************/ -/* * * ELEMENTAL CONSTRAINTS * * */ -/**********************************************************************/ - -/* (there are no specific routines for elemental constraints) */ - -/**********************************************************************/ -/* * * GENERIC VALUES * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- delete_value - delete generic value. --- --- This routine deletes specified generic value. --- --- NOTE: The generic value to be deleted must be valid. */ - -void delete_value -( MPL *mpl, - int type, - VALUE *value /* content destroyed */ -) -{ xassert(value != NULL); - switch (type) - { case A_NONE: - value->none = NULL; - break; - case A_NUMERIC: - value->num = 0.0; - break; - case A_SYMBOLIC: - delete_symbol(mpl, value->sym), value->sym = NULL; - break; - case A_LOGICAL: - value->bit = 0; - break; - case A_TUPLE: - delete_tuple(mpl, value->tuple), value->tuple = NULL; - break; - case A_ELEMSET: - delete_elemset(mpl, value->set), value->set = NULL; - break; - case A_ELEMVAR: - value->var = NULL; - break; - case A_FORMULA: - delete_formula(mpl, value->form), value->form = NULL; - break; - case A_ELEMCON: - value->con = NULL; - break; - default: - xassert(type != type); - } - return; -} - -/**********************************************************************/ -/* * * SYMBOLICALLY INDEXED ARRAYS * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- create_array - create array. --- --- This routine creates an array of specified type and dimension. Being --- created the array is initially empty. --- --- The type indicator determines generic values, which can be assigned --- to the array members: --- --- A_NONE - none (members have no assigned values) --- A_NUMERIC - floating-point numbers --- A_SYMBOLIC - symbols --- A_ELEMSET - elemental sets --- A_ELEMVAR - elemental variables --- A_ELEMCON - elemental constraints --- --- The dimension may be 0, in which case the array consists of the only --- member (such arrays represent 0-dimensional objects). */ - -ARRAY *create_array(MPL *mpl, int type, int dim) -{ ARRAY *array; - xassert(type == A_NONE || type == A_NUMERIC || - type == A_SYMBOLIC || type == A_ELEMSET || - type == A_ELEMVAR || type == A_ELEMCON); - xassert(dim >= 0); - array = dmp_get_atom(mpl->arrays, sizeof(ARRAY)); - array->type = type; - array->dim = dim; - array->size = 0; - array->head = NULL; - array->tail = NULL; - array->tree = NULL; - array->prev = NULL; - array->next = mpl->a_list; - /* include the array in the global array list */ - if (array->next != NULL) array->next->prev = array; - mpl->a_list = array; - return array; -} - -/*---------------------------------------------------------------------- --- find_member - find array member with given n-tuple. --- --- This routine finds an array member, which has given n-tuple. If the --- array is short, the linear search is used. Otherwise the routine --- autimatically creates the search tree (i.e. the array index) to find --- members for logarithmic time. */ - -static int compare_member_tuples(void *info, const void *key1, - const void *key2) -{ /* this is an auxiliary routine used to compare keys, which are - n-tuples assigned to array members */ - return compare_tuples((MPL *)info, (TUPLE *)key1, (TUPLE *)key2); -} - -MEMBER *find_member -( MPL *mpl, - ARRAY *array, /* not changed */ - TUPLE *tuple /* not changed */ -) -{ MEMBER *memb; - xassert(array != NULL); - /* the n-tuple must have the same dimension as the array */ - xassert(tuple_dimen(mpl, tuple) == array->dim); - /* if the array is large enough, create the search tree and index - all existing members of the array */ - if (array->size > 30 && array->tree == NULL) - { array->tree = avl_create_tree(compare_member_tuples, mpl); - for (memb = array->head; memb != NULL; memb = memb->next) -avl_set_node_link(avl_insert_node(array->tree, memb->tuple), - (void *)memb); - } - /* find a member, which has the given tuple */ - if (array->tree == NULL) - { /* the search tree doesn't exist; use the linear search */ - for (memb = array->head; memb != NULL; memb = memb->next) - if (compare_tuples(mpl, memb->tuple, tuple) == 0) break; - } - else - { /* the search tree exists; use the binary search */ - AVLNODE *node; - node = avl_find_node(array->tree, tuple); -memb = (MEMBER *)(node == NULL ? NULL : avl_get_node_link(node)); - } - return memb; -} - -/*---------------------------------------------------------------------- --- add_member - add new member to array. --- --- This routine creates a new member with given n-tuple and adds it to --- specified array. --- --- For the sake of efficiency this routine doesn't check whether the --- array already contains a member with the given n-tuple or not. Thus, --- if necessary, the calling program should use the routine find_member --- in order to be sure that the array contains no member with the same --- n-tuple, because members with duplicate n-tuples are not allowed. --- --- This routine assigns no generic value to the new member, because the --- calling program must do that. */ - -MEMBER *add_member -( MPL *mpl, - ARRAY *array, /* modified */ - TUPLE *tuple /* destroyed */ -) -{ MEMBER *memb; - xassert(array != NULL); - /* the n-tuple must have the same dimension as the array */ - xassert(tuple_dimen(mpl, tuple) == array->dim); - /* create new member */ - memb = dmp_get_atom(mpl->members, sizeof(MEMBER)); - memb->tuple = tuple; - memb->next = NULL; - memset(&memb->value, '?', sizeof(VALUE)); - /* and append it to the member list */ - array->size++; - if (array->head == NULL) - array->head = memb; - else - array->tail->next = memb; - array->tail = memb; - /* if the search tree exists, index the new member */ - if (array->tree != NULL) -avl_set_node_link(avl_insert_node(array->tree, memb->tuple), - (void *)memb); - return memb; -} - -/*---------------------------------------------------------------------- --- delete_array - delete array. --- --- This routine deletes specified array. --- --- Generic values assigned to the array members are not deleted by this --- routine. The calling program itself must delete all assigned generic --- values before deleting the array. */ - -void delete_array -( MPL *mpl, - ARRAY *array /* destroyed */ -) -{ MEMBER *memb; - xassert(array != NULL); - /* delete all existing array members */ - while (array->head != NULL) - { memb = array->head; - array->head = memb->next; - delete_tuple(mpl, memb->tuple); - dmp_free_atom(mpl->members, memb, sizeof(MEMBER)); - } - /* if the search tree exists, also delete it */ - if (array->tree != NULL) avl_delete_tree(array->tree); - /* remove the array from the global array list */ - if (array->prev == NULL) - mpl->a_list = array->next; - else - array->prev->next = array->next; - if (array->next == NULL) - ; - else - array->next->prev = array->prev; - /* delete the array descriptor */ - dmp_free_atom(mpl->arrays, array, sizeof(ARRAY)); - return; -} - -/**********************************************************************/ -/* * * DOMAINS AND DUMMY INDICES * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- assign_dummy_index - assign new value to dummy index. --- --- This routine assigns new value to specified dummy index and, that is --- important, invalidates all temporary resultant values, which depends --- on that dummy index. */ - -void assign_dummy_index -( MPL *mpl, - DOMAIN_SLOT *slot, /* modified */ - SYMBOL *value /* not changed */ -) -{ CODE *leaf, *code; - xassert(slot != NULL); - xassert(value != NULL); - /* delete the current value assigned to the dummy index */ - if (slot->value != NULL) - { /* if the current value and the new one are identical, actual - assignment is not needed */ - if (compare_symbols(mpl, slot->value, value) == 0) goto done; - /* delete a symbol, which is the current value */ - delete_symbol(mpl, slot->value), slot->value = NULL; - } - /* now walk through all the pseudo-codes with op = O_INDEX, which - refer to the dummy index to be changed (these pseudo-codes are - leaves in the forest of *all* expressions in the database) */ - for (leaf = slot->list; leaf != NULL; leaf = leaf->arg.index. - next) - { xassert(leaf->op == O_INDEX); - /* invalidate all resultant values, which depend on the dummy - index, walking from the current leaf toward the root of the - corresponding expression tree */ - for (code = leaf; code != NULL; code = code->up) - { if (code->valid) - { /* invalidate and delete resultant value */ - code->valid = 0; - delete_value(mpl, code->type, &code->value); - } - } - } - /* assign new value to the dummy index */ - slot->value = copy_symbol(mpl, value); -done: return; -} - -/*---------------------------------------------------------------------- --- update_dummy_indices - update current values of dummy indices. --- --- This routine assigns components of "backup" n-tuple to dummy indices --- of specified domain block. If no "backup" n-tuple is defined for the --- domain block, values of the dummy indices remain untouched. */ - -void update_dummy_indices -( MPL *mpl, - DOMAIN_BLOCK *block /* not changed */ -) -{ DOMAIN_SLOT *slot; - TUPLE *temp; - if (block->backup != NULL) - { for (slot = block->list, temp = block->backup; slot != NULL; - slot = slot->next, temp = temp->next) - { xassert(temp != NULL); - xassert(temp->sym != NULL); - assign_dummy_index(mpl, slot, temp->sym); - } - } - return; -} - -/*---------------------------------------------------------------------- --- enter_domain_block - enter domain block. --- --- Let specified domain block have the form: --- --- { ..., (j1, j2, ..., jn) in J, ... } --- --- where j1, j2, ..., jn are dummy indices, J is a basic set. --- --- This routine does the following: --- --- 1. Checks if the given n-tuple is a member of the basic set J. Note --- that J being *out of the scope* of the domain block cannot depend --- on the dummy indices in the same and inner domain blocks, so it --- can be computed before the dummy indices are assigned new values. --- If this check fails, the routine returns with non-zero code. --- --- 2. Saves current values of the dummy indices j1, j2, ..., jn. --- --- 3. Assigns new values, which are components of the given n-tuple, to --- the dummy indices j1, j2, ..., jn. If dimension of the n-tuple is --- larger than n, its extra components n+1, n+2, ... are not used. --- --- 4. Calls the formal routine func which either enters the next domain --- block or evaluates some code within the domain scope. --- --- 5. Restores former values of the dummy indices j1, j2, ..., jn. --- --- Since current values assigned to the dummy indices on entry to this --- routine are restored on exit, the formal routine func is allowed to --- call this routine recursively. */ - -int enter_domain_block -( MPL *mpl, - DOMAIN_BLOCK *block, /* not changed */ - TUPLE *tuple, /* not changed */ - void *info, void (*func)(MPL *mpl, void *info) -) -{ TUPLE *backup; - int ret = 0; - /* check if the given n-tuple is a member of the basic set */ - xassert(block->code != NULL); - if (!is_member(mpl, block->code, tuple)) - { ret = 1; - goto done; - } - /* save reference to "backup" n-tuple, which was used to assign - current values of the dummy indices (it is sufficient to save - reference, not value, because that n-tuple is defined in some - outer level of recursion and therefore cannot be changed on - this and deeper recursive calls) */ - backup = block->backup; - /* set up new "backup" n-tuple, which defines new values of the - dummy indices */ - block->backup = tuple; - /* assign new values to the dummy indices */ - update_dummy_indices(mpl, block); - /* call the formal routine that does the rest part of the job */ - func(mpl, info); - /* restore reference to the former "backup" n-tuple */ - block->backup = backup; - /* restore former values of the dummy indices; note that if the - domain block just escaped has no other active instances which - may exist due to recursion (it is indicated by a null pointer - to the former n-tuple), former values of the dummy indices are - undefined; therefore in this case the routine keeps currently - assigned values of the dummy indices that involves keeping all - dependent temporary results and thereby, if this domain block - is not used recursively, allows improving efficiency */ - update_dummy_indices(mpl, block); -done: return ret; -} - -/*---------------------------------------------------------------------- --- eval_within_domain - perform evaluation within domain scope. --- --- This routine assigns new values (symbols) to all dummy indices of --- specified domain and calls the formal routine func, which is used to --- evaluate some code in the domain scope. Each free dummy index in the --- domain is assigned a value specified in the corresponding component --- of given n-tuple. Non-free dummy indices are assigned values, which --- are computed by this routine. --- --- Number of components in the given n-tuple must be the same as number --- of free indices in the domain. --- --- If the given n-tuple is not a member of the domain set, the routine --- func is not called, and non-zero code is returned. --- --- For the sake of convenience it is allowed to specify domain as NULL --- (then n-tuple also must be 0-tuple, i.e. empty), in which case this --- routine just calls the routine func and returns zero. --- --- This routine allows recursive calls from the routine func providing --- correct values of dummy indices for each instance. --- --- NOTE: The n-tuple passed to this routine must not be changed by any --- other routines called from the formal routine func until this --- routine has returned. */ - -struct eval_domain_info -{ /* working info used by the routine eval_within_domain */ - DOMAIN *domain; - /* domain, which has to be entered */ - DOMAIN_BLOCK *block; - /* domain block, which is currently processed */ - TUPLE *tuple; - /* tail of original n-tuple, whose components have to be assigned - to free dummy indices in the current domain block */ - void *info; - /* transit pointer passed to the formal routine func */ - void (*func)(MPL *mpl, void *info); - /* routine, which has to be executed in the domain scope */ - int failure; - /* this flag indicates that given n-tuple is not a member of the - domain set */ -}; - -static void eval_domain_func(MPL *mpl, void *_my_info) -{ /* this routine recursively enters into the domain scope and then - calls the routine func */ - struct eval_domain_info *my_info = _my_info; - if (my_info->block != NULL) - { /* the current domain block to be entered exists */ - DOMAIN_BLOCK *block; - DOMAIN_SLOT *slot; - TUPLE *tuple = NULL, *temp = NULL; - /* save pointer to the current domain block */ - block = my_info->block; - /* and get ready to enter the next block (if it exists) */ - my_info->block = block->next; - /* construct temporary n-tuple, whose components correspond to - dummy indices (slots) of the current domain; components of - the temporary n-tuple that correspond to free dummy indices - are assigned references (not values!) to symbols specified - in the corresponding components of the given n-tuple, while - other components that correspond to non-free dummy indices - are assigned symbolic values computed here */ - for (slot = block->list; slot != NULL; slot = slot->next) - { /* create component that corresponds to the current slot */ - if (tuple == NULL) - tuple = temp = dmp_get_atom(mpl->tuples, sizeof(TUPLE)); - else -temp = (temp->next = dmp_get_atom(mpl->tuples, sizeof(TUPLE))); - if (slot->code == NULL) - { /* dummy index is free; take reference to symbol, which - is specified in the corresponding component of given - n-tuple */ - xassert(my_info->tuple != NULL); - temp->sym = my_info->tuple->sym; - xassert(temp->sym != NULL); - my_info->tuple = my_info->tuple->next; - } - else - { /* dummy index is non-free; compute symbolic value to be - temporarily assigned to the dummy index */ - temp->sym = eval_symbolic(mpl, slot->code); - } - } - temp->next = NULL; - /* enter the current domain block */ - if (enter_domain_block(mpl, block, tuple, my_info, - eval_domain_func)) my_info->failure = 1; - /* delete temporary n-tuple as well as symbols that correspond - to non-free dummy indices (they were computed here) */ - for (slot = block->list; slot != NULL; slot = slot->next) - { xassert(tuple != NULL); - temp = tuple; - tuple = tuple->next; - if (slot->code != NULL) - { /* dummy index is non-free; delete symbolic value */ - delete_symbol(mpl, temp->sym); - } - /* delete component that corresponds to the current slot */ - dmp_free_atom(mpl->tuples, temp, sizeof(TUPLE)); - } - } - else - { /* there are no more domain blocks, i.e. we have reached the - domain scope */ - xassert(my_info->tuple == NULL); - /* check optional predicate specified for the domain */ - if (my_info->domain->code != NULL && !eval_logical(mpl, - my_info->domain->code)) - { /* the predicate is false */ - my_info->failure = 2; - } - else - { /* the predicate is true; do the job */ - my_info->func(mpl, my_info->info); - } - } - return; -} - -int eval_within_domain -( MPL *mpl, - DOMAIN *domain, /* not changed */ - TUPLE *tuple, /* not changed */ - void *info, void (*func)(MPL *mpl, void *info) -) -{ /* this routine performs evaluation within domain scope */ - struct eval_domain_info _my_info, *my_info = &_my_info; - if (domain == NULL) - { xassert(tuple == NULL); - func(mpl, info); - my_info->failure = 0; - } - else - { xassert(tuple != NULL); - my_info->domain = domain; - my_info->block = domain->list; - my_info->tuple = tuple; - my_info->info = info; - my_info->func = func; - my_info->failure = 0; - /* enter the very first domain block */ - eval_domain_func(mpl, my_info); - } - return my_info->failure; -} - -/*---------------------------------------------------------------------- --- loop_within_domain - perform iterations within domain scope. --- --- This routine iteratively assigns new values (symbols) to the dummy --- indices of specified domain by enumerating all n-tuples, which are --- members of the domain set, and for every n-tuple it calls the formal --- routine func to evaluate some code within the domain scope. --- --- If the routine func returns non-zero, enumeration within the domain --- is prematurely terminated. --- --- For the sake of convenience it is allowed to specify domain as NULL, --- in which case this routine just calls the routine func only once and --- returns zero. --- --- This routine allows recursive calls from the routine func providing --- correct values of dummy indices for each instance. */ - -struct loop_domain_info -{ /* working info used by the routine loop_within_domain */ - DOMAIN *domain; - /* domain, which has to be entered */ - DOMAIN_BLOCK *block; - /* domain block, which is currently processed */ - int looping; - /* clearing this flag leads to terminating enumeration */ - void *info; - /* transit pointer passed to the formal routine func */ - int (*func)(MPL *mpl, void *info); - /* routine, which needs to be executed in the domain scope */ -}; - -static void loop_domain_func(MPL *mpl, void *_my_info) -{ /* this routine enumerates all n-tuples in the basic set of the - current domain block, enters recursively into the domain scope - for every n-tuple, and then calls the routine func */ - struct loop_domain_info *my_info = _my_info; - if (my_info->block != NULL) - { /* the current domain block to be entered exists */ - DOMAIN_BLOCK *block; - DOMAIN_SLOT *slot; - TUPLE *bound; - /* save pointer to the current domain block */ - block = my_info->block; - /* and get ready to enter the next block (if it exists) */ - my_info->block = block->next; - /* compute symbolic values, at which non-free dummy indices of - the current domain block are bound; since that values don't - depend on free dummy indices of the current block, they can - be computed once out of the enumeration loop */ - bound = create_tuple(mpl); - for (slot = block->list; slot != NULL; slot = slot->next) - { if (slot->code != NULL) - bound = expand_tuple(mpl, bound, eval_symbolic(mpl, - slot->code)); - } - /* start enumeration */ - xassert(block->code != NULL); - if (block->code->op == O_DOTS) - { /* the basic set is "arithmetic", in which case it doesn't - need to be computed explicitly */ - TUPLE *tuple; - int n, j; - double t0, tf, dt; - /* compute "parameters" of the basic set */ - t0 = eval_numeric(mpl, block->code->arg.arg.x); - tf = eval_numeric(mpl, block->code->arg.arg.y); - if (block->code->arg.arg.z == NULL) - dt = 1.0; - else - dt = eval_numeric(mpl, block->code->arg.arg.z); - /* determine cardinality of the basic set */ - n = arelset_size(mpl, t0, tf, dt); - /* create dummy 1-tuple for members of the basic set */ - tuple = expand_tuple(mpl, create_tuple(mpl), - create_symbol_num(mpl, 0.0)); - /* in case of "arithmetic" set there is exactly one dummy - index, which cannot be non-free */ - xassert(bound == NULL); - /* walk through 1-tuples of the basic set */ - for (j = 1; j <= n && my_info->looping; j++) - { /* construct dummy 1-tuple for the current member */ - tuple->sym->num = arelset_member(mpl, t0, tf, dt, j); - /* enter the current domain block */ - enter_domain_block(mpl, block, tuple, my_info, - loop_domain_func); - } - /* delete dummy 1-tuple */ - delete_tuple(mpl, tuple); - } - else - { /* the basic set is of general kind, in which case it needs - to be explicitly computed */ - ELEMSET *set; - MEMBER *memb; - TUPLE *temp1, *temp2; - /* compute the basic set */ - set = eval_elemset(mpl, block->code); - /* walk through all n-tuples of the basic set */ - for (memb = set->head; memb != NULL && my_info->looping; - memb = memb->next) - { /* all components of the current n-tuple that correspond - to non-free dummy indices must be feasible; otherwise - the n-tuple is not in the basic set */ - temp1 = memb->tuple; - temp2 = bound; - for (slot = block->list; slot != NULL; slot = slot->next) - { xassert(temp1 != NULL); - if (slot->code != NULL) - { /* non-free dummy index */ - xassert(temp2 != NULL); - if (compare_symbols(mpl, temp1->sym, temp2->sym) - != 0) - { /* the n-tuple is not in the basic set */ - goto skip; - } - temp2 = temp2->next; - } - temp1 = temp1->next; - } - xassert(temp1 == NULL); - xassert(temp2 == NULL); - /* enter the current domain block */ - enter_domain_block(mpl, block, memb->tuple, my_info, - loop_domain_func); -skip: ; - } - /* delete the basic set */ - delete_elemset(mpl, set); - } - /* delete symbolic values binding non-free dummy indices */ - delete_tuple(mpl, bound); - /* restore pointer to the current domain block */ - my_info->block = block; - } - else - { /* there are no more domain blocks, i.e. we have reached the - domain scope */ - /* check optional predicate specified for the domain */ - if (my_info->domain->code != NULL && !eval_logical(mpl, - my_info->domain->code)) - { /* the predicate is false */ - /* nop */; - } - else - { /* the predicate is true; do the job */ - my_info->looping = !my_info->func(mpl, my_info->info); - } - } - return; -} - -void loop_within_domain -( MPL *mpl, - DOMAIN *domain, /* not changed */ - void *info, int (*func)(MPL *mpl, void *info) -) -{ /* this routine performs iterations within domain scope */ - struct loop_domain_info _my_info, *my_info = &_my_info; - if (domain == NULL) - func(mpl, info); - else - { my_info->domain = domain; - my_info->block = domain->list; - my_info->looping = 1; - my_info->info = info; - my_info->func = func; - /* enter the very first domain block */ - loop_domain_func(mpl, my_info); - } - return; -} - -/*---------------------------------------------------------------------- --- out_of_domain - raise domain exception. --- --- This routine is called when a reference is made to a member of some --- model object, but its n-tuple is out of the object domain. */ - -void out_of_domain -( MPL *mpl, - char *name, /* not changed */ - TUPLE *tuple /* not changed */ -) -{ xassert(name != NULL); - xassert(tuple != NULL); - error(mpl, "%s%s out of domain", name, format_tuple(mpl, '[', - tuple)); - /* no return */ -} - -/*---------------------------------------------------------------------- --- get_domain_tuple - obtain current n-tuple from domain. --- --- This routine constructs n-tuple, whose components are current values --- assigned to *free* dummy indices of specified domain. --- --- For the sake of convenience it is allowed to specify domain as NULL, --- in which case this routine returns 0-tuple. --- --- NOTE: This routine must not be called out of domain scope. */ - -TUPLE *get_domain_tuple -( MPL *mpl, - DOMAIN *domain /* not changed */ -) -{ DOMAIN_BLOCK *block; - DOMAIN_SLOT *slot; - TUPLE *tuple; - tuple = create_tuple(mpl); - if (domain != NULL) - { for (block = domain->list; block != NULL; block = block->next) - { for (slot = block->list; slot != NULL; slot = slot->next) - { if (slot->code == NULL) - { xassert(slot->value != NULL); - tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, - slot->value)); - } - } - } - } - return tuple; -} - -/*---------------------------------------------------------------------- --- clean_domain - clean domain. --- --- This routine cleans specified domain that assumes deleting all stuff --- dynamically allocated during the generation phase. */ - -void clean_domain(MPL *mpl, DOMAIN *domain) -{ DOMAIN_BLOCK *block; - DOMAIN_SLOT *slot; - /* if no domain is specified, do nothing */ - if (domain == NULL) goto done; - /* clean all domain blocks */ - for (block = domain->list; block != NULL; block = block->next) - { /* clean all domain slots */ - for (slot = block->list; slot != NULL; slot = slot->next) - { /* clean pseudo-code for computing bound value */ - clean_code(mpl, slot->code); - /* delete symbolic value assigned to dummy index */ - if (slot->value != NULL) - delete_symbol(mpl, slot->value), slot->value = NULL; - } - /* clean pseudo-code for computing basic set */ - clean_code(mpl, block->code); - } - /* clean pseudo-code for computing domain predicate */ - clean_code(mpl, domain->code); -done: return; -} - -/**********************************************************************/ -/* * * MODEL SETS * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- check_elem_set - check elemental set assigned to set member. --- --- This routine checks if given elemental set being assigned to member --- of specified model set satisfies to all restrictions. --- --- NOTE: This routine must not be called out of domain scope. */ - -void check_elem_set -( MPL *mpl, - SET *set, /* not changed */ - TUPLE *tuple, /* not changed */ - ELEMSET *refer /* not changed */ -) -{ WITHIN *within; - MEMBER *memb; - int eqno; - /* elemental set must be within all specified supersets */ - for (within = set->within, eqno = 1; within != NULL; within = - within->next, eqno++) - { xassert(within->code != NULL); - for (memb = refer->head; memb != NULL; memb = memb->next) - { if (!is_member(mpl, within->code, memb->tuple)) - { char buf[255+1]; - strcpy(buf, format_tuple(mpl, '(', memb->tuple)); - xassert(strlen(buf) < sizeof(buf)); - error(mpl, "%s%s contains %s which not within specified " - "set; see (%d)", set->name, format_tuple(mpl, '[', - tuple), buf, eqno); - } - } - } - return; -} - -/*---------------------------------------------------------------------- --- take_member_set - obtain elemental set assigned to set member. --- --- This routine obtains a reference to elemental set assigned to given --- member of specified model set and returns it on exit. --- --- NOTE: This routine must not be called out of domain scope. */ - -ELEMSET *take_member_set /* returns reference, not value */ -( MPL *mpl, - SET *set, /* not changed */ - TUPLE *tuple /* not changed */ -) -{ MEMBER *memb; - ELEMSET *refer; - /* find member in the set array */ - memb = find_member(mpl, set->array, tuple); - if (memb != NULL) - { /* member exists, so just take the reference */ - refer = memb->value.set; - } - else if (set->assign != NULL) - { /* compute value using assignment expression */ - refer = eval_elemset(mpl, set->assign); -add: /* check that the elemental set satisfies to all restrictions, - assign it to new member, and add the member to the array */ - check_elem_set(mpl, set, tuple, refer); - memb = add_member(mpl, set->array, copy_tuple(mpl, tuple)); - memb->value.set = refer; - } - else if (set->option != NULL) - { /* compute default elemental set */ - refer = eval_elemset(mpl, set->option); - goto add; - } - else - { /* no value (elemental set) is provided */ - error(mpl, "no value for %s%s", set->name, format_tuple(mpl, - '[', tuple)); - } - return refer; -} - -/*---------------------------------------------------------------------- --- eval_member_set - evaluate elemental set assigned to set member. --- --- This routine evaluates a reference to elemental set assigned to given --- member of specified model set and returns it on exit. */ - -struct eval_set_info -{ /* working info used by the routine eval_member_set */ - SET *set; - /* model set */ - TUPLE *tuple; - /* n-tuple, which defines set member */ - MEMBER *memb; - /* normally this pointer is NULL; the routine uses this pointer - to check data provided in the data section, in which case it - points to a member currently checked; this check is performed - automatically only once when a reference to any member occurs - for the first time */ - ELEMSET *refer; - /* evaluated reference to elemental set */ -}; - -static void eval_set_func(MPL *mpl, void *_info) -{ /* this is auxiliary routine to work within domain scope */ - struct eval_set_info *info = _info; - if (info->memb != NULL) - { /* checking call; check elemental set being assigned */ - check_elem_set(mpl, info->set, info->memb->tuple, - info->memb->value.set); - } - else - { /* normal call; evaluate member, which has given n-tuple */ - info->refer = take_member_set(mpl, info->set, info->tuple); - } - return; -} - -#if 1 /* 12/XII-2008 */ -static void saturate_set(MPL *mpl, SET *set) -{ GADGET *gadget = set->gadget; - ELEMSET *data; - MEMBER *elem, *memb; - TUPLE *tuple, *work[20]; - int i; - xprintf("Generating %s...\n", set->name); - eval_whole_set(mpl, gadget->set); - /* gadget set must have exactly one member */ - xassert(gadget->set->array != NULL); - xassert(gadget->set->array->head != NULL); - xassert(gadget->set->array->head == gadget->set->array->tail); - data = gadget->set->array->head->value.set; - xassert(data->type == A_NONE); - xassert(data->dim == gadget->set->dimen); - /* walk thru all elements of the plain set */ - for (elem = data->head; elem != NULL; elem = elem->next) - { /* create a copy of n-tuple */ - tuple = copy_tuple(mpl, elem->tuple); - /* rearrange component of the n-tuple */ - for (i = 0; i < gadget->set->dimen; i++) - work[i] = NULL; - for (i = 0; tuple != NULL; tuple = tuple->next) - work[gadget->ind[i++]-1] = tuple; - xassert(i == gadget->set->dimen); - for (i = 0; i < gadget->set->dimen; i++) - { xassert(work[i] != NULL); - work[i]->next = work[i+1]; - } - /* construct subscript list from first set->dim components */ - if (set->dim == 0) - tuple = NULL; - else - tuple = work[0], work[set->dim-1]->next = NULL; - /* find corresponding member of the set to be initialized */ - memb = find_member(mpl, set->array, tuple); - if (memb == NULL) - { /* not found; add new member to the set and assign it empty - elemental set */ - memb = add_member(mpl, set->array, tuple); - memb->value.set = create_elemset(mpl, set->dimen); - } - else - { /* found; free subscript list */ - delete_tuple(mpl, tuple); - } - /* construct new n-tuple from rest set->dimen components */ - tuple = work[set->dim]; - xassert(set->dim + set->dimen == gadget->set->dimen); - work[gadget->set->dimen-1]->next = NULL; - /* and add it to the elemental set assigned to the member - (no check for duplicates is needed) */ - add_tuple(mpl, memb->value.set, tuple); - } - /* the set has been saturated with data */ - set->data = 1; - return; -} -#endif - -ELEMSET *eval_member_set /* returns reference, not value */ -( MPL *mpl, - SET *set, /* not changed */ - TUPLE *tuple /* not changed */ -) -{ /* this routine evaluates set member */ - struct eval_set_info _info, *info = &_info; - xassert(set->dim == tuple_dimen(mpl, tuple)); - info->set = set; - info->tuple = tuple; -#if 1 /* 12/XII-2008 */ - if (set->gadget != NULL && set->data == 0) - { /* initialize the set with data from a plain set */ - saturate_set(mpl, set); - } -#endif - if (set->data == 1) - { /* check data, which are provided in the data section, but not - checked yet */ - /* save pointer to the last array member; note that during the - check new members may be added beyond the last member due to - references to the same parameter from default expression as - well as from expressions that define restricting supersets; - however, values assigned to the new members will be checked - by other routine, so we don't need to check them here */ - MEMBER *tail = set->array->tail; - /* change the data status to prevent infinite recursive loop - due to references to the same set during the check */ - set->data = 2; - /* check elemental sets assigned to array members in the data - section until the marked member has been reached */ - for (info->memb = set->array->head; info->memb != NULL; - info->memb = info->memb->next) - { if (eval_within_domain(mpl, set->domain, info->memb->tuple, - info, eval_set_func)) - out_of_domain(mpl, set->name, info->memb->tuple); - if (info->memb == tail) break; - } - /* the check has been finished */ - } - /* evaluate member, which has given n-tuple */ - info->memb = NULL; - if (eval_within_domain(mpl, info->set->domain, info->tuple, info, - eval_set_func)) - out_of_domain(mpl, set->name, info->tuple); - /* bring evaluated reference to the calling program */ - return info->refer; -} - -/*---------------------------------------------------------------------- --- eval_whole_set - evaluate model set over entire domain. --- --- This routine evaluates all members of specified model set over entire --- domain. */ - -static int whole_set_func(MPL *mpl, void *info) -{ /* this is auxiliary routine to work within domain scope */ - SET *set = (SET *)info; - TUPLE *tuple = get_domain_tuple(mpl, set->domain); - eval_member_set(mpl, set, tuple); - delete_tuple(mpl, tuple); - return 0; -} - -void eval_whole_set(MPL *mpl, SET *set) -{ loop_within_domain(mpl, set->domain, set, whole_set_func); - return; -} - -/*---------------------------------------------------------------------- --- clean set - clean model set. --- --- This routine cleans specified model set that assumes deleting all --- stuff dynamically allocated during the generation phase. */ - -void clean_set(MPL *mpl, SET *set) -{ WITHIN *within; - MEMBER *memb; - /* clean subscript domain */ - clean_domain(mpl, set->domain); - /* clean pseudo-code for computing supersets */ - for (within = set->within; within != NULL; within = within->next) - clean_code(mpl, within->code); - /* clean pseudo-code for computing assigned value */ - clean_code(mpl, set->assign); - /* clean pseudo-code for computing default value */ - clean_code(mpl, set->option); - /* reset data status flag */ - set->data = 0; - /* delete content array */ - for (memb = set->array->head; memb != NULL; memb = memb->next) - delete_value(mpl, set->array->type, &memb->value); - delete_array(mpl, set->array), set->array = NULL; - return; -} - -/**********************************************************************/ -/* * * MODEL PARAMETERS * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- check_value_num - check numeric value assigned to parameter member. --- --- This routine checks if numeric value being assigned to some member --- of specified numeric model parameter satisfies to all restrictions. --- --- NOTE: This routine must not be called out of domain scope. */ - -void check_value_num -( MPL *mpl, - PARAMETER *par, /* not changed */ - TUPLE *tuple, /* not changed */ - double value -) -{ CONDITION *cond; - WITHIN *in; - int eqno; - /* the value must satisfy to the parameter type */ - switch (par->type) - { case A_NUMERIC: - break; - case A_INTEGER: - if (value != floor(value)) - error(mpl, "%s%s = %.*g not integer", par->name, - format_tuple(mpl, '[', tuple), DBL_DIG, value); - break; - case A_BINARY: - if (!(value == 0.0 || value == 1.0)) - error(mpl, "%s%s = %.*g not binary", par->name, - format_tuple(mpl, '[', tuple), DBL_DIG, value); - break; - default: - xassert(par != par); - } - /* the value must satisfy to all specified conditions */ - for (cond = par->cond, eqno = 1; cond != NULL; cond = cond->next, - eqno++) - { double bound; - char *rho; - xassert(cond->code != NULL); - bound = eval_numeric(mpl, cond->code); - switch (cond->rho) - { case O_LT: - if (!(value < bound)) - { rho = "<"; -err: error(mpl, "%s%s = %.*g not %s %.*g; see (%d)", - par->name, format_tuple(mpl, '[', tuple), DBL_DIG, - value, rho, DBL_DIG, bound, eqno); - } - break; - case O_LE: - if (!(value <= bound)) { rho = "<="; goto err; } - break; - case O_EQ: - if (!(value == bound)) { rho = "="; goto err; } - break; - case O_GE: - if (!(value >= bound)) { rho = ">="; goto err; } - break; - case O_GT: - if (!(value > bound)) { rho = ">"; goto err; } - break; - case O_NE: - if (!(value != bound)) { rho = "<>"; goto err; } - break; - default: - xassert(cond != cond); - } - } - /* the value must be in all specified supersets */ - for (in = par->in, eqno = 1; in != NULL; in = in->next, eqno++) - { TUPLE *dummy; - xassert(in->code != NULL); - xassert(in->code->dim == 1); - dummy = expand_tuple(mpl, create_tuple(mpl), - create_symbol_num(mpl, value)); - if (!is_member(mpl, in->code, dummy)) - error(mpl, "%s%s = %.*g not in specified set; see (%d)", - par->name, format_tuple(mpl, '[', tuple), DBL_DIG, - value, eqno); - delete_tuple(mpl, dummy); - } - return; -} - -/*---------------------------------------------------------------------- --- take_member_num - obtain num. value assigned to parameter member. --- --- This routine obtains a numeric value assigned to member of specified --- numeric model parameter and returns it on exit. --- --- NOTE: This routine must not be called out of domain scope. */ - -double take_member_num -( MPL *mpl, - PARAMETER *par, /* not changed */ - TUPLE *tuple /* not changed */ -) -{ MEMBER *memb; - double value; - /* find member in the parameter array */ - memb = find_member(mpl, par->array, tuple); - if (memb != NULL) - { /* member exists, so just take its value */ - value = memb->value.num; - } - else if (par->assign != NULL) - { /* compute value using assignment expression */ - value = eval_numeric(mpl, par->assign); -add: /* check that the value satisfies to all restrictions, assign - it to new member, and add the member to the array */ - check_value_num(mpl, par, tuple, value); - memb = add_member(mpl, par->array, copy_tuple(mpl, tuple)); - memb->value.num = value; - } - else if (par->option != NULL) - { /* compute default value */ - value = eval_numeric(mpl, par->option); - goto add; - } - else if (par->defval != NULL) - { /* take default value provided in the data section */ - if (par->defval->str != NULL) - error(mpl, "cannot convert %s to floating-point number", - format_symbol(mpl, par->defval)); - value = par->defval->num; - goto add; - } - else - { /* no value is provided */ - error(mpl, "no value for %s%s", par->name, format_tuple(mpl, - '[', tuple)); - } - return value; -} - -/*---------------------------------------------------------------------- --- eval_member_num - evaluate num. value assigned to parameter member. --- --- This routine evaluates a numeric value assigned to given member of --- specified numeric model parameter and returns it on exit. */ - -struct eval_num_info -{ /* working info used by the routine eval_member_num */ - PARAMETER *par; - /* model parameter */ - TUPLE *tuple; - /* n-tuple, which defines parameter member */ - MEMBER *memb; - /* normally this pointer is NULL; the routine uses this pointer - to check data provided in the data section, in which case it - points to a member currently checked; this check is performed - automatically only once when a reference to any member occurs - for the first time */ - double value; - /* evaluated numeric value */ -}; - -static void eval_num_func(MPL *mpl, void *_info) -{ /* this is auxiliary routine to work within domain scope */ - struct eval_num_info *info = _info; - if (info->memb != NULL) - { /* checking call; check numeric value being assigned */ - check_value_num(mpl, info->par, info->memb->tuple, - info->memb->value.num); - } - else - { /* normal call; evaluate member, which has given n-tuple */ - info->value = take_member_num(mpl, info->par, info->tuple); - } - return; -} - -double eval_member_num -( MPL *mpl, - PARAMETER *par, /* not changed */ - TUPLE *tuple /* not changed */ -) -{ /* this routine evaluates numeric parameter member */ - struct eval_num_info _info, *info = &_info; - xassert(par->type == A_NUMERIC || par->type == A_INTEGER || - par->type == A_BINARY); - xassert(par->dim == tuple_dimen(mpl, tuple)); - info->par = par; - info->tuple = tuple; - if (par->data == 1) - { /* check data, which are provided in the data section, but not - checked yet */ - /* save pointer to the last array member; note that during the - check new members may be added beyond the last member due to - references to the same parameter from default expression as - well as from expressions that define restricting conditions; - however, values assigned to the new members will be checked - by other routine, so we don't need to check them here */ - MEMBER *tail = par->array->tail; - /* change the data status to prevent infinite recursive loop - due to references to the same parameter during the check */ - par->data = 2; - /* check values assigned to array members in the data section - until the marked member has been reached */ - for (info->memb = par->array->head; info->memb != NULL; - info->memb = info->memb->next) - { if (eval_within_domain(mpl, par->domain, info->memb->tuple, - info, eval_num_func)) - out_of_domain(mpl, par->name, info->memb->tuple); - if (info->memb == tail) break; - } - /* the check has been finished */ - } - /* evaluate member, which has given n-tuple */ - info->memb = NULL; - if (eval_within_domain(mpl, info->par->domain, info->tuple, info, - eval_num_func)) - out_of_domain(mpl, par->name, info->tuple); - /* bring evaluated value to the calling program */ - return info->value; -} - -/*---------------------------------------------------------------------- --- check_value_sym - check symbolic value assigned to parameter member. --- --- This routine checks if symbolic value being assigned to some member --- of specified symbolic model parameter satisfies to all restrictions. --- --- NOTE: This routine must not be called out of domain scope. */ - -void check_value_sym -( MPL *mpl, - PARAMETER *par, /* not changed */ - TUPLE *tuple, /* not changed */ - SYMBOL *value /* not changed */ -) -{ CONDITION *cond; - WITHIN *in; - int eqno; - /* the value must satisfy to all specified conditions */ - for (cond = par->cond, eqno = 1; cond != NULL; cond = cond->next, - eqno++) - { SYMBOL *bound; - char buf[255+1]; - xassert(cond->code != NULL); - bound = eval_symbolic(mpl, cond->code); - switch (cond->rho) - { -#if 1 /* 13/VIII-2008 */ - case O_LT: - if (!(compare_symbols(mpl, value, bound) < 0)) - { strcpy(buf, format_symbol(mpl, bound)); - xassert(strlen(buf) < sizeof(buf)); - error(mpl, "%s%s = %s not < %s", - par->name, format_tuple(mpl, '[', tuple), - format_symbol(mpl, value), buf, eqno); - } - break; - case O_LE: - if (!(compare_symbols(mpl, value, bound) <= 0)) - { strcpy(buf, format_symbol(mpl, bound)); - xassert(strlen(buf) < sizeof(buf)); - error(mpl, "%s%s = %s not <= %s", - par->name, format_tuple(mpl, '[', tuple), - format_symbol(mpl, value), buf, eqno); - } - break; -#endif - case O_EQ: - if (!(compare_symbols(mpl, value, bound) == 0)) - { strcpy(buf, format_symbol(mpl, bound)); - xassert(strlen(buf) < sizeof(buf)); - error(mpl, "%s%s = %s not = %s", - par->name, format_tuple(mpl, '[', tuple), - format_symbol(mpl, value), buf, eqno); - } - break; -#if 1 /* 13/VIII-2008 */ - case O_GE: - if (!(compare_symbols(mpl, value, bound) >= 0)) - { strcpy(buf, format_symbol(mpl, bound)); - xassert(strlen(buf) < sizeof(buf)); - error(mpl, "%s%s = %s not >= %s", - par->name, format_tuple(mpl, '[', tuple), - format_symbol(mpl, value), buf, eqno); - } - break; - case O_GT: - if (!(compare_symbols(mpl, value, bound) > 0)) - { strcpy(buf, format_symbol(mpl, bound)); - xassert(strlen(buf) < sizeof(buf)); - error(mpl, "%s%s = %s not > %s", - par->name, format_tuple(mpl, '[', tuple), - format_symbol(mpl, value), buf, eqno); - } - break; -#endif - case O_NE: - if (!(compare_symbols(mpl, value, bound) != 0)) - { strcpy(buf, format_symbol(mpl, bound)); - xassert(strlen(buf) < sizeof(buf)); - error(mpl, "%s%s = %s not <> %s", - par->name, format_tuple(mpl, '[', tuple), - format_symbol(mpl, value), buf, eqno); - } - break; - default: - xassert(cond != cond); - } - delete_symbol(mpl, bound); - } - /* the value must be in all specified supersets */ - for (in = par->in, eqno = 1; in != NULL; in = in->next, eqno++) - { TUPLE *dummy; - xassert(in->code != NULL); - xassert(in->code->dim == 1); - dummy = expand_tuple(mpl, create_tuple(mpl), copy_symbol(mpl, - value)); - if (!is_member(mpl, in->code, dummy)) - error(mpl, "%s%s = %s not in specified set; see (%d)", - par->name, format_tuple(mpl, '[', tuple), - format_symbol(mpl, value), eqno); - delete_tuple(mpl, dummy); - } - return; -} - -/*---------------------------------------------------------------------- --- take_member_sym - obtain symb. value assigned to parameter member. --- --- This routine obtains a symbolic value assigned to member of specified --- symbolic model parameter and returns it on exit. --- --- NOTE: This routine must not be called out of domain scope. */ - -SYMBOL *take_member_sym /* returns value, not reference */ -( MPL *mpl, - PARAMETER *par, /* not changed */ - TUPLE *tuple /* not changed */ -) -{ MEMBER *memb; - SYMBOL *value; - /* find member in the parameter array */ - memb = find_member(mpl, par->array, tuple); - if (memb != NULL) - { /* member exists, so just take its value */ - value = copy_symbol(mpl, memb->value.sym); - } - else if (par->assign != NULL) - { /* compute value using assignment expression */ - value = eval_symbolic(mpl, par->assign); -add: /* check that the value satisfies to all restrictions, assign - it to new member, and add the member to the array */ - check_value_sym(mpl, par, tuple, value); - memb = add_member(mpl, par->array, copy_tuple(mpl, tuple)); - memb->value.sym = copy_symbol(mpl, value); - } - else if (par->option != NULL) - { /* compute default value */ - value = eval_symbolic(mpl, par->option); - goto add; - } - else if (par->defval != NULL) - { /* take default value provided in the data section */ - value = copy_symbol(mpl, par->defval); - goto add; - } - else - { /* no value is provided */ - error(mpl, "no value for %s%s", par->name, format_tuple(mpl, - '[', tuple)); - } - return value; -} - -/*---------------------------------------------------------------------- --- eval_member_sym - evaluate symb. value assigned to parameter member. --- --- This routine evaluates a symbolic value assigned to given member of --- specified symbolic model parameter and returns it on exit. */ - -struct eval_sym_info -{ /* working info used by the routine eval_member_sym */ - PARAMETER *par; - /* model parameter */ - TUPLE *tuple; - /* n-tuple, which defines parameter member */ - MEMBER *memb; - /* normally this pointer is NULL; the routine uses this pointer - to check data provided in the data section, in which case it - points to a member currently checked; this check is performed - automatically only once when a reference to any member occurs - for the first time */ - SYMBOL *value; - /* evaluated symbolic value */ -}; - -static void eval_sym_func(MPL *mpl, void *_info) -{ /* this is auxiliary routine to work within domain scope */ - struct eval_sym_info *info = _info; - if (info->memb != NULL) - { /* checking call; check symbolic value being assigned */ - check_value_sym(mpl, info->par, info->memb->tuple, - info->memb->value.sym); - } - else - { /* normal call; evaluate member, which has given n-tuple */ - info->value = take_member_sym(mpl, info->par, info->tuple); - } - return; -} - -SYMBOL *eval_member_sym /* returns value, not reference */ -( MPL *mpl, - PARAMETER *par, /* not changed */ - TUPLE *tuple /* not changed */ -) -{ /* this routine evaluates symbolic parameter member */ - struct eval_sym_info _info, *info = &_info; - xassert(par->type == A_SYMBOLIC); - xassert(par->dim == tuple_dimen(mpl, tuple)); - info->par = par; - info->tuple = tuple; - if (par->data == 1) - { /* check data, which are provided in the data section, but not - checked yet */ - /* save pointer to the last array member; note that during the - check new members may be added beyond the last member due to - references to the same parameter from default expression as - well as from expressions that define restricting conditions; - however, values assigned to the new members will be checked - by other routine, so we don't need to check them here */ - MEMBER *tail = par->array->tail; - /* change the data status to prevent infinite recursive loop - due to references to the same parameter during the check */ - par->data = 2; - /* check values assigned to array members in the data section - until the marked member has been reached */ - for (info->memb = par->array->head; info->memb != NULL; - info->memb = info->memb->next) - { if (eval_within_domain(mpl, par->domain, info->memb->tuple, - info, eval_sym_func)) - out_of_domain(mpl, par->name, info->memb->tuple); - if (info->memb == tail) break; - } - /* the check has been finished */ - } - /* evaluate member, which has given n-tuple */ - info->memb = NULL; - if (eval_within_domain(mpl, info->par->domain, info->tuple, info, - eval_sym_func)) - out_of_domain(mpl, par->name, info->tuple); - /* bring evaluated value to the calling program */ - return info->value; -} - -/*---------------------------------------------------------------------- --- eval_whole_par - evaluate model parameter over entire domain. --- --- This routine evaluates all members of specified model parameter over --- entire domain. */ - -static int whole_par_func(MPL *mpl, void *info) -{ /* this is auxiliary routine to work within domain scope */ - PARAMETER *par = (PARAMETER *)info; - TUPLE *tuple = get_domain_tuple(mpl, par->domain); - switch (par->type) - { case A_NUMERIC: - case A_INTEGER: - case A_BINARY: - eval_member_num(mpl, par, tuple); - break; - case A_SYMBOLIC: - delete_symbol(mpl, eval_member_sym(mpl, par, tuple)); - break; - default: - xassert(par != par); - } - delete_tuple(mpl, tuple); - return 0; -} - -void eval_whole_par(MPL *mpl, PARAMETER *par) -{ loop_within_domain(mpl, par->domain, par, whole_par_func); - return; -} - -/*---------------------------------------------------------------------- --- clean_parameter - clean model parameter. --- --- This routine cleans specified model parameter that assumes deleting --- all stuff dynamically allocated during the generation phase. */ - -void clean_parameter(MPL *mpl, PARAMETER *par) -{ CONDITION *cond; - WITHIN *in; - MEMBER *memb; - /* clean subscript domain */ - clean_domain(mpl, par->domain); - /* clean pseudo-code for computing restricting conditions */ - for (cond = par->cond; cond != NULL; cond = cond->next) - clean_code(mpl, cond->code); - /* clean pseudo-code for computing restricting supersets */ - for (in = par->in; in != NULL; in = in->next) - clean_code(mpl, in->code); - /* clean pseudo-code for computing assigned value */ - clean_code(mpl, par->assign); - /* clean pseudo-code for computing default value */ - clean_code(mpl, par->option); - /* reset data status flag */ - par->data = 0; - /* delete default symbolic value */ - if (par->defval != NULL) - delete_symbol(mpl, par->defval), par->defval = NULL; - /* delete content array */ - for (memb = par->array->head; memb != NULL; memb = memb->next) - delete_value(mpl, par->array->type, &memb->value); - delete_array(mpl, par->array), par->array = NULL; - return; -} - -/**********************************************************************/ -/* * * MODEL VARIABLES * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- take_member_var - obtain reference to elemental variable. --- --- This routine obtains a reference to elemental variable assigned to --- given member of specified model variable and returns it on exit. If --- necessary, new elemental variable is created. --- --- NOTE: This routine must not be called out of domain scope. */ - -ELEMVAR *take_member_var /* returns reference */ -( MPL *mpl, - VARIABLE *var, /* not changed */ - TUPLE *tuple /* not changed */ -) -{ MEMBER *memb; - ELEMVAR *refer; - /* find member in the variable array */ - memb = find_member(mpl, var->array, tuple); - if (memb != NULL) - { /* member exists, so just take the reference */ - refer = memb->value.var; - } - else - { /* member is referenced for the first time and therefore does - not exist; create new elemental variable, assign it to new - member, and add the member to the variable array */ - memb = add_member(mpl, var->array, copy_tuple(mpl, tuple)); - refer = (memb->value.var = - dmp_get_atom(mpl->elemvars, sizeof(ELEMVAR))); - refer->j = 0; - refer->var = var; - refer->memb = memb; - /* compute lower bound */ - if (var->lbnd == NULL) - refer->lbnd = 0.0; - else - refer->lbnd = eval_numeric(mpl, var->lbnd); - /* compute upper bound */ - if (var->ubnd == NULL) - refer->ubnd = 0.0; - else if (var->ubnd == var->lbnd) - refer->ubnd = refer->lbnd; - else - refer->ubnd = eval_numeric(mpl, var->ubnd); - /* nullify working quantity */ - refer->temp = 0.0; -#if 1 /* 15/V-2010 */ - /* solution has not been obtained by the solver yet */ - refer->stat = 0; - refer->prim = refer->dual = 0.0; -#endif - } - return refer; -} - -/*---------------------------------------------------------------------- --- eval_member_var - evaluate reference to elemental variable. --- --- This routine evaluates a reference to elemental variable assigned to --- member of specified model variable and returns it on exit. */ - -struct eval_var_info -{ /* working info used by the routine eval_member_var */ - VARIABLE *var; - /* model variable */ - TUPLE *tuple; - /* n-tuple, which defines variable member */ - ELEMVAR *refer; - /* evaluated reference to elemental variable */ -}; - -static void eval_var_func(MPL *mpl, void *_info) -{ /* this is auxiliary routine to work within domain scope */ - struct eval_var_info *info = _info; - info->refer = take_member_var(mpl, info->var, info->tuple); - return; -} - -ELEMVAR *eval_member_var /* returns reference */ -( MPL *mpl, - VARIABLE *var, /* not changed */ - TUPLE *tuple /* not changed */ -) -{ /* this routine evaluates variable member */ - struct eval_var_info _info, *info = &_info; - xassert(var->dim == tuple_dimen(mpl, tuple)); - info->var = var; - info->tuple = tuple; - /* evaluate member, which has given n-tuple */ - if (eval_within_domain(mpl, info->var->domain, info->tuple, info, - eval_var_func)) - out_of_domain(mpl, var->name, info->tuple); - /* bring evaluated reference to the calling program */ - return info->refer; -} - -/*---------------------------------------------------------------------- --- eval_whole_var - evaluate model variable over entire domain. --- --- This routine evaluates all members of specified model variable over --- entire domain. */ - -static int whole_var_func(MPL *mpl, void *info) -{ /* this is auxiliary routine to work within domain scope */ - VARIABLE *var = (VARIABLE *)info; - TUPLE *tuple = get_domain_tuple(mpl, var->domain); - eval_member_var(mpl, var, tuple); - delete_tuple(mpl, tuple); - return 0; -} - -void eval_whole_var(MPL *mpl, VARIABLE *var) -{ loop_within_domain(mpl, var->domain, var, whole_var_func); - return; -} - -/*---------------------------------------------------------------------- --- clean_variable - clean model variable. --- --- This routine cleans specified model variable that assumes deleting --- all stuff dynamically allocated during the generation phase. */ - -void clean_variable(MPL *mpl, VARIABLE *var) -{ MEMBER *memb; - /* clean subscript domain */ - clean_domain(mpl, var->domain); - /* clean code for computing lower bound */ - clean_code(mpl, var->lbnd); - /* clean code for computing upper bound */ - if (var->ubnd != var->lbnd) clean_code(mpl, var->ubnd); - /* delete content array */ - for (memb = var->array->head; memb != NULL; memb = memb->next) - dmp_free_atom(mpl->elemvars, memb->value.var, sizeof(ELEMVAR)); - delete_array(mpl, var->array), var->array = NULL; - return; -} - -/**********************************************************************/ -/* * * MODEL CONSTRAINTS AND OBJECTIVES * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- take_member_con - obtain reference to elemental constraint. --- --- This routine obtains a reference to elemental constraint assigned --- to given member of specified model constraint and returns it on exit. --- If necessary, new elemental constraint is created. --- --- NOTE: This routine must not be called out of domain scope. */ - -ELEMCON *take_member_con /* returns reference */ -( MPL *mpl, - CONSTRAINT *con, /* not changed */ - TUPLE *tuple /* not changed */ -) -{ MEMBER *memb; - ELEMCON *refer; - /* find member in the constraint array */ - memb = find_member(mpl, con->array, tuple); - if (memb != NULL) - { /* member exists, so just take the reference */ - refer = memb->value.con; - } - else - { /* member is referenced for the first time and therefore does - not exist; create new elemental constraint, assign it to new - member, and add the member to the constraint array */ - memb = add_member(mpl, con->array, copy_tuple(mpl, tuple)); - refer = (memb->value.con = - dmp_get_atom(mpl->elemcons, sizeof(ELEMCON))); - refer->i = 0; - refer->con = con; - refer->memb = memb; - /* compute linear form */ - xassert(con->code != NULL); - refer->form = eval_formula(mpl, con->code); - /* compute lower and upper bounds */ - if (con->lbnd == NULL && con->ubnd == NULL) - { /* objective has no bounds */ - double temp; - xassert(con->type == A_MINIMIZE || con->type == A_MAXIMIZE); - /* carry the constant term to the right-hand side */ - refer->form = remove_constant(mpl, refer->form, &temp); - refer->lbnd = refer->ubnd = - temp; - } - else if (con->lbnd != NULL && con->ubnd == NULL) - { /* constraint a * x + b >= c * y + d is transformed to the - standard form a * x - c * y >= d - b */ - double temp; - xassert(con->type == A_CONSTRAINT); - refer->form = linear_comb(mpl, - +1.0, refer->form, - -1.0, eval_formula(mpl, con->lbnd)); - refer->form = remove_constant(mpl, refer->form, &temp); - refer->lbnd = - temp; - refer->ubnd = 0.0; - } - else if (con->lbnd == NULL && con->ubnd != NULL) - { /* constraint a * x + b <= c * y + d is transformed to the - standard form a * x - c * y <= d - b */ - double temp; - xassert(con->type == A_CONSTRAINT); - refer->form = linear_comb(mpl, - +1.0, refer->form, - -1.0, eval_formula(mpl, con->ubnd)); - refer->form = remove_constant(mpl, refer->form, &temp); - refer->lbnd = 0.0; - refer->ubnd = - temp; - } - else if (con->lbnd == con->ubnd) - { /* constraint a * x + b = c * y + d is transformed to the - standard form a * x - c * y = d - b */ - double temp; - xassert(con->type == A_CONSTRAINT); - refer->form = linear_comb(mpl, - +1.0, refer->form, - -1.0, eval_formula(mpl, con->lbnd)); - refer->form = remove_constant(mpl, refer->form, &temp); - refer->lbnd = refer->ubnd = - temp; - } - else - { /* ranged constraint c <= a * x + b <= d is transformed to - the standard form c - b <= a * x <= d - b */ - double temp, temp1, temp2; - xassert(con->type == A_CONSTRAINT); - refer->form = remove_constant(mpl, refer->form, &temp); - xassert(remove_constant(mpl, eval_formula(mpl, con->lbnd), - &temp1) == NULL); - xassert(remove_constant(mpl, eval_formula(mpl, con->ubnd), - &temp2) == NULL); - refer->lbnd = fp_sub(mpl, temp1, temp); - refer->ubnd = fp_sub(mpl, temp2, temp); - } -#if 1 /* 15/V-2010 */ - /* solution has not been obtained by the solver yet */ - refer->stat = 0; - refer->prim = refer->dual = 0.0; -#endif - } - return refer; -} - -/*---------------------------------------------------------------------- --- eval_member_con - evaluate reference to elemental constraint. --- --- This routine evaluates a reference to elemental constraint assigned --- to member of specified model constraint and returns it on exit. */ - -struct eval_con_info -{ /* working info used by the routine eval_member_con */ - CONSTRAINT *con; - /* model constraint */ - TUPLE *tuple; - /* n-tuple, which defines constraint member */ - ELEMCON *refer; - /* evaluated reference to elemental constraint */ -}; - -static void eval_con_func(MPL *mpl, void *_info) -{ /* this is auxiliary routine to work within domain scope */ - struct eval_con_info *info = _info; - info->refer = take_member_con(mpl, info->con, info->tuple); - return; -} - -ELEMCON *eval_member_con /* returns reference */ -( MPL *mpl, - CONSTRAINT *con, /* not changed */ - TUPLE *tuple /* not changed */ -) -{ /* this routine evaluates constraint member */ - struct eval_con_info _info, *info = &_info; - xassert(con->dim == tuple_dimen(mpl, tuple)); - info->con = con; - info->tuple = tuple; - /* evaluate member, which has given n-tuple */ - if (eval_within_domain(mpl, info->con->domain, info->tuple, info, - eval_con_func)) - out_of_domain(mpl, con->name, info->tuple); - /* bring evaluated reference to the calling program */ - return info->refer; -} - -/*---------------------------------------------------------------------- --- eval_whole_con - evaluate model constraint over entire domain. --- --- This routine evaluates all members of specified model constraint over --- entire domain. */ - -static int whole_con_func(MPL *mpl, void *info) -{ /* this is auxiliary routine to work within domain scope */ - CONSTRAINT *con = (CONSTRAINT *)info; - TUPLE *tuple = get_domain_tuple(mpl, con->domain); - eval_member_con(mpl, con, tuple); - delete_tuple(mpl, tuple); - return 0; -} - -void eval_whole_con(MPL *mpl, CONSTRAINT *con) -{ loop_within_domain(mpl, con->domain, con, whole_con_func); - return; -} - -/*---------------------------------------------------------------------- --- clean_constraint - clean model constraint. --- --- This routine cleans specified model constraint that assumes deleting --- all stuff dynamically allocated during the generation phase. */ - -void clean_constraint(MPL *mpl, CONSTRAINT *con) -{ MEMBER *memb; - /* clean subscript domain */ - clean_domain(mpl, con->domain); - /* clean code for computing main linear form */ - clean_code(mpl, con->code); - /* clean code for computing lower bound */ - clean_code(mpl, con->lbnd); - /* clean code for computing upper bound */ - if (con->ubnd != con->lbnd) clean_code(mpl, con->ubnd); - /* delete content array */ - for (memb = con->array->head; memb != NULL; memb = memb->next) - { delete_formula(mpl, memb->value.con->form); - dmp_free_atom(mpl->elemcons, memb->value.con, sizeof(ELEMCON)); - } - delete_array(mpl, con->array), con->array = NULL; - return; -} - -/**********************************************************************/ -/* * * PSEUDO-CODE * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- eval_numeric - evaluate pseudo-code to determine numeric value. --- --- This routine evaluates specified pseudo-code to determine resultant --- numeric value, which is returned on exit. */ - -struct iter_num_info -{ /* working info used by the routine iter_num_func */ - CODE *code; - /* pseudo-code for iterated operation to be performed */ - double value; - /* resultant value */ -}; - -static int iter_num_func(MPL *mpl, void *_info) -{ /* this is auxiliary routine used to perform iterated operation - on numeric "integrand" within domain scope */ - struct iter_num_info *info = _info; - double temp; - temp = eval_numeric(mpl, info->code->arg.loop.x); - switch (info->code->op) - { case O_SUM: - /* summation over domain */ - info->value = fp_add(mpl, info->value, temp); - break; - case O_PROD: - /* multiplication over domain */ - info->value = fp_mul(mpl, info->value, temp); - break; - case O_MINIMUM: - /* minimum over domain */ - if (info->value > temp) info->value = temp; - break; - case O_MAXIMUM: - /* maximum over domain */ - if (info->value < temp) info->value = temp; - break; - default: - xassert(info != info); - } - return 0; -} - -double eval_numeric(MPL *mpl, CODE *code) -{ double value; - xassert(code != NULL); - xassert(code->type == A_NUMERIC); - xassert(code->dim == 0); - /* if the operation has a side effect, invalidate and delete the - resultant value */ - if (code->vflag && code->valid) - { code->valid = 0; - delete_value(mpl, code->type, &code->value); - } - /* if resultant value is valid, no evaluation is needed */ - if (code->valid) - { value = code->value.num; - goto done; - } - /* evaluate pseudo-code recursively */ - switch (code->op) - { case O_NUMBER: - /* take floating-point number */ - value = code->arg.num; - break; - case O_MEMNUM: - /* take member of numeric parameter */ - { TUPLE *tuple; - ARG_LIST *e; - tuple = create_tuple(mpl); - for (e = code->arg.par.list; e != NULL; e = e->next) - tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, - e->x)); - value = eval_member_num(mpl, code->arg.par.par, tuple); - delete_tuple(mpl, tuple); - } - break; - case O_MEMVAR: - /* take computed value of elemental variable */ - { TUPLE *tuple; - ARG_LIST *e; -#if 1 /* 15/V-2010 */ - ELEMVAR *var; -#endif - tuple = create_tuple(mpl); - for (e = code->arg.var.list; e != NULL; e = e->next) - tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, - e->x)); -#if 0 /* 15/V-2010 */ - value = eval_member_var(mpl, code->arg.var.var, tuple) - ->value; -#else - var = eval_member_var(mpl, code->arg.var.var, tuple); - switch (code->arg.var.suff) - { case DOT_LB: - if (var->var->lbnd == NULL) - value = -DBL_MAX; - else - value = var->lbnd; - break; - case DOT_UB: - if (var->var->ubnd == NULL) - value = +DBL_MAX; - else - value = var->ubnd; - break; - case DOT_STATUS: - value = var->stat; - break; - case DOT_VAL: - value = var->prim; - break; - case DOT_DUAL: - value = var->dual; - break; - default: - xassert(code != code); - } -#endif - delete_tuple(mpl, tuple); - } - break; -#if 1 /* 15/V-2010 */ - case O_MEMCON: - /* take computed value of elemental constraint */ - { TUPLE *tuple; - ARG_LIST *e; - ELEMCON *con; - tuple = create_tuple(mpl); - for (e = code->arg.con.list; e != NULL; e = e->next) - tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, - e->x)); - con = eval_member_con(mpl, code->arg.con.con, tuple); - switch (code->arg.con.suff) - { case DOT_LB: - if (con->con->lbnd == NULL) - value = -DBL_MAX; - else - value = con->lbnd; - break; - case DOT_UB: - if (con->con->ubnd == NULL) - value = +DBL_MAX; - else - value = con->ubnd; - break; - case DOT_STATUS: - value = con->stat; - break; - case DOT_VAL: - value = con->prim; - break; - case DOT_DUAL: - value = con->dual; - break; - default: - xassert(code != code); - } - delete_tuple(mpl, tuple); - } - break; -#endif - case O_IRAND224: - /* pseudo-random in [0, 2^24-1] */ - value = fp_irand224(mpl); - break; - case O_UNIFORM01: - /* pseudo-random in [0, 1) */ - value = fp_uniform01(mpl); - break; - case O_NORMAL01: - /* gaussian random, mu = 0, sigma = 1 */ - value = fp_normal01(mpl); - break; - case O_GMTIME: - /* current calendar time */ - value = fn_gmtime(mpl); - break; - case O_CVTNUM: - /* conversion to numeric */ - { SYMBOL *sym; - sym = eval_symbolic(mpl, code->arg.arg.x); -#if 0 /* 23/XI-2008 */ - if (sym->str != NULL) - error(mpl, "cannot convert %s to floating-point numbe" - "r", format_symbol(mpl, sym)); - value = sym->num; -#else - if (sym->str == NULL) - value = sym->num; - else - { if (str2num(sym->str, &value)) - error(mpl, "cannot convert %s to floating-point nu" - "mber", format_symbol(mpl, sym)); - } -#endif - delete_symbol(mpl, sym); - } - break; - case O_PLUS: - /* unary plus */ - value = + eval_numeric(mpl, code->arg.arg.x); - break; - case O_MINUS: - /* unary minus */ - value = - eval_numeric(mpl, code->arg.arg.x); - break; - case O_ABS: - /* absolute value */ - value = fabs(eval_numeric(mpl, code->arg.arg.x)); - break; - case O_CEIL: - /* round upward ("ceiling of x") */ - value = ceil(eval_numeric(mpl, code->arg.arg.x)); - break; - case O_FLOOR: - /* round downward ("floor of x") */ - value = floor(eval_numeric(mpl, code->arg.arg.x)); - break; - case O_EXP: - /* base-e exponential */ - value = fp_exp(mpl, eval_numeric(mpl, code->arg.arg.x)); - break; - case O_LOG: - /* natural logarithm */ - value = fp_log(mpl, eval_numeric(mpl, code->arg.arg.x)); - break; - case O_LOG10: - /* common (decimal) logarithm */ - value = fp_log10(mpl, eval_numeric(mpl, code->arg.arg.x)); - break; - case O_SQRT: - /* square root */ - value = fp_sqrt(mpl, eval_numeric(mpl, code->arg.arg.x)); - break; - case O_SIN: - /* trigonometric sine */ - value = fp_sin(mpl, eval_numeric(mpl, code->arg.arg.x)); - break; - case O_COS: - /* trigonometric cosine */ - value = fp_cos(mpl, eval_numeric(mpl, code->arg.arg.x)); - break; - case O_ATAN: - /* trigonometric arctangent (one argument) */ - value = fp_atan(mpl, eval_numeric(mpl, code->arg.arg.x)); - break; - case O_ATAN2: - /* trigonometric arctangent (two arguments) */ - value = fp_atan2(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_numeric(mpl, code->arg.arg.y)); - break; - case O_ROUND: - /* round to nearest integer */ - value = fp_round(mpl, - eval_numeric(mpl, code->arg.arg.x), 0.0); - break; - case O_ROUND2: - /* round to n fractional digits */ - value = fp_round(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_numeric(mpl, code->arg.arg.y)); - break; - case O_TRUNC: - /* truncate to nearest integer */ - value = fp_trunc(mpl, - eval_numeric(mpl, code->arg.arg.x), 0.0); - break; - case O_TRUNC2: - /* truncate to n fractional digits */ - value = fp_trunc(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_numeric(mpl, code->arg.arg.y)); - break; - case O_ADD: - /* addition */ - value = fp_add(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_numeric(mpl, code->arg.arg.y)); - break; - case O_SUB: - /* subtraction */ - value = fp_sub(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_numeric(mpl, code->arg.arg.y)); - break; - case O_LESS: - /* non-negative subtraction */ - value = fp_less(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_numeric(mpl, code->arg.arg.y)); - break; - case O_MUL: - /* multiplication */ - value = fp_mul(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_numeric(mpl, code->arg.arg.y)); - break; - case O_DIV: - /* division */ - value = fp_div(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_numeric(mpl, code->arg.arg.y)); - break; - case O_IDIV: - /* quotient of exact division */ - value = fp_idiv(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_numeric(mpl, code->arg.arg.y)); - break; - case O_MOD: - /* remainder of exact division */ - value = fp_mod(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_numeric(mpl, code->arg.arg.y)); - break; - case O_POWER: - /* exponentiation (raise to power) */ - value = fp_power(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_numeric(mpl, code->arg.arg.y)); - break; - case O_UNIFORM: - /* pseudo-random in [a, b) */ - value = fp_uniform(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_numeric(mpl, code->arg.arg.y)); - break; - case O_NORMAL: - /* gaussian random, given mu and sigma */ - value = fp_normal(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_numeric(mpl, code->arg.arg.y)); - break; - case O_CARD: - { ELEMSET *set; - set = eval_elemset(mpl, code->arg.arg.x); - value = set->size; - delete_array(mpl, set); - } - break; - case O_LENGTH: - { SYMBOL *sym; - char str[MAX_LENGTH+1]; - sym = eval_symbolic(mpl, code->arg.arg.x); - if (sym->str == NULL) - sprintf(str, "%.*g", DBL_DIG, sym->num); - else - fetch_string(mpl, sym->str, str); - delete_symbol(mpl, sym); - value = strlen(str); - } - break; - case O_STR2TIME: - { SYMBOL *sym; - char str[MAX_LENGTH+1], fmt[MAX_LENGTH+1]; - sym = eval_symbolic(mpl, code->arg.arg.x); - if (sym->str == NULL) - sprintf(str, "%.*g", DBL_DIG, sym->num); - else - fetch_string(mpl, sym->str, str); - delete_symbol(mpl, sym); - sym = eval_symbolic(mpl, code->arg.arg.y); - if (sym->str == NULL) - sprintf(fmt, "%.*g", DBL_DIG, sym->num); - else - fetch_string(mpl, sym->str, fmt); - delete_symbol(mpl, sym); - value = fn_str2time(mpl, str, fmt); - } - break; - case O_FORK: - /* if-then-else */ - if (eval_logical(mpl, code->arg.arg.x)) - value = eval_numeric(mpl, code->arg.arg.y); - else if (code->arg.arg.z == NULL) - value = 0.0; - else - value = eval_numeric(mpl, code->arg.arg.z); - break; - case O_MIN: - /* minimal value (n-ary) */ - { ARG_LIST *e; - double temp; - value = +DBL_MAX; - for (e = code->arg.list; e != NULL; e = e->next) - { temp = eval_numeric(mpl, e->x); - if (value > temp) value = temp; - } - } - break; - case O_MAX: - /* maximal value (n-ary) */ - { ARG_LIST *e; - double temp; - value = -DBL_MAX; - for (e = code->arg.list; e != NULL; e = e->next) - { temp = eval_numeric(mpl, e->x); - if (value < temp) value = temp; - } - } - break; - case O_SUM: - /* summation over domain */ - { struct iter_num_info _info, *info = &_info; - info->code = code; - info->value = 0.0; - loop_within_domain(mpl, code->arg.loop.domain, info, - iter_num_func); - value = info->value; - } - break; - case O_PROD: - /* multiplication over domain */ - { struct iter_num_info _info, *info = &_info; - info->code = code; - info->value = 1.0; - loop_within_domain(mpl, code->arg.loop.domain, info, - iter_num_func); - value = info->value; - } - break; - case O_MINIMUM: - /* minimum over domain */ - { struct iter_num_info _info, *info = &_info; - info->code = code; - info->value = +DBL_MAX; - loop_within_domain(mpl, code->arg.loop.domain, info, - iter_num_func); - if (info->value == +DBL_MAX) - error(mpl, "min{} over empty set; result undefined"); - value = info->value; - } - break; - case O_MAXIMUM: - /* maximum over domain */ - { struct iter_num_info _info, *info = &_info; - info->code = code; - info->value = -DBL_MAX; - loop_within_domain(mpl, code->arg.loop.domain, info, - iter_num_func); - if (info->value == -DBL_MAX) - error(mpl, "max{} over empty set; result undefined"); - value = info->value; - } - break; - default: - xassert(code != code); - } - /* save resultant value */ - xassert(!code->valid); - code->valid = 1; - code->value.num = value; -done: return value; -} - -/*---------------------------------------------------------------------- --- eval_symbolic - evaluate pseudo-code to determine symbolic value. --- --- This routine evaluates specified pseudo-code to determine resultant --- symbolic value, which is returned on exit. */ - -SYMBOL *eval_symbolic(MPL *mpl, CODE *code) -{ SYMBOL *value; - xassert(code != NULL); - xassert(code->type == A_SYMBOLIC); - xassert(code->dim == 0); - /* if the operation has a side effect, invalidate and delete the - resultant value */ - if (code->vflag && code->valid) - { code->valid = 0; - delete_value(mpl, code->type, &code->value); - } - /* if resultant value is valid, no evaluation is needed */ - if (code->valid) - { value = copy_symbol(mpl, code->value.sym); - goto done; - } - /* evaluate pseudo-code recursively */ - switch (code->op) - { case O_STRING: - /* take character string */ - value = create_symbol_str(mpl, create_string(mpl, - code->arg.str)); - break; - case O_INDEX: - /* take dummy index */ - xassert(code->arg.index.slot->value != NULL); - value = copy_symbol(mpl, code->arg.index.slot->value); - break; - case O_MEMSYM: - /* take member of symbolic parameter */ - { TUPLE *tuple; - ARG_LIST *e; - tuple = create_tuple(mpl); - for (e = code->arg.par.list; e != NULL; e = e->next) - tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, - e->x)); - value = eval_member_sym(mpl, code->arg.par.par, tuple); - delete_tuple(mpl, tuple); - } - break; - case O_CVTSYM: - /* conversion to symbolic */ - value = create_symbol_num(mpl, eval_numeric(mpl, - code->arg.arg.x)); - break; - case O_CONCAT: - /* concatenation */ - value = concat_symbols(mpl, - eval_symbolic(mpl, code->arg.arg.x), - eval_symbolic(mpl, code->arg.arg.y)); - break; - case O_FORK: - /* if-then-else */ - if (eval_logical(mpl, code->arg.arg.x)) - value = eval_symbolic(mpl, code->arg.arg.y); - else if (code->arg.arg.z == NULL) - value = create_symbol_num(mpl, 0.0); - else - value = eval_symbolic(mpl, code->arg.arg.z); - break; - case O_SUBSTR: - case O_SUBSTR3: - { double pos, len; - char str[MAX_LENGTH+1]; - value = eval_symbolic(mpl, code->arg.arg.x); - if (value->str == NULL) - sprintf(str, "%.*g", DBL_DIG, value->num); - else - fetch_string(mpl, value->str, str); - delete_symbol(mpl, value); - if (code->op == O_SUBSTR) - { pos = eval_numeric(mpl, code->arg.arg.y); - if (pos != floor(pos)) - error(mpl, "substr('...', %.*g); non-integer secon" - "d argument", DBL_DIG, pos); - if (pos < 1 || pos > strlen(str) + 1) - error(mpl, "substr('...', %.*g); substring out of " - "range", DBL_DIG, pos); - } - else - { pos = eval_numeric(mpl, code->arg.arg.y); - len = eval_numeric(mpl, code->arg.arg.z); - if (pos != floor(pos) || len != floor(len)) - error(mpl, "substr('...', %.*g, %.*g); non-integer" - " second and/or third argument", DBL_DIG, pos, - DBL_DIG, len); - if (pos < 1 || len < 0 || pos + len > strlen(str) + 1) - error(mpl, "substr('...', %.*g, %.*g); substring o" - "ut of range", DBL_DIG, pos, DBL_DIG, len); - str[(int)pos + (int)len - 1] = '\0'; - } - value = create_symbol_str(mpl, create_string(mpl, str + - (int)pos - 1)); - } - break; - case O_TIME2STR: - { double num; - SYMBOL *sym; - char str[MAX_LENGTH+1], fmt[MAX_LENGTH+1]; - num = eval_numeric(mpl, code->arg.arg.x); - sym = eval_symbolic(mpl, code->arg.arg.y); - if (sym->str == NULL) - sprintf(fmt, "%.*g", DBL_DIG, sym->num); - else - fetch_string(mpl, sym->str, fmt); - delete_symbol(mpl, sym); - fn_time2str(mpl, str, num, fmt); - value = create_symbol_str(mpl, create_string(mpl, str)); - } - break; - default: - xassert(code != code); - } - /* save resultant value */ - xassert(!code->valid); - code->valid = 1; - code->value.sym = copy_symbol(mpl, value); -done: return value; -} - -/*---------------------------------------------------------------------- --- eval_logical - evaluate pseudo-code to determine logical value. --- --- This routine evaluates specified pseudo-code to determine resultant --- logical value, which is returned on exit. */ - -struct iter_log_info -{ /* working info used by the routine iter_log_func */ - CODE *code; - /* pseudo-code for iterated operation to be performed */ - int value; - /* resultant value */ -}; - -static int iter_log_func(MPL *mpl, void *_info) -{ /* this is auxiliary routine used to perform iterated operation - on logical "integrand" within domain scope */ - struct iter_log_info *info = _info; - int ret = 0; - switch (info->code->op) - { case O_FORALL: - /* conjunction over domain */ - info->value &= eval_logical(mpl, info->code->arg.loop.x); - if (!info->value) ret = 1; - break; - case O_EXISTS: - /* disjunction over domain */ - info->value |= eval_logical(mpl, info->code->arg.loop.x); - if (info->value) ret = 1; - break; - default: - xassert(info != info); - } - return ret; -} - -int eval_logical(MPL *mpl, CODE *code) -{ int value; - xassert(code->type == A_LOGICAL); - xassert(code->dim == 0); - /* if the operation has a side effect, invalidate and delete the - resultant value */ - if (code->vflag && code->valid) - { code->valid = 0; - delete_value(mpl, code->type, &code->value); - } - /* if resultant value is valid, no evaluation is needed */ - if (code->valid) - { value = code->value.bit; - goto done; - } - /* evaluate pseudo-code recursively */ - switch (code->op) - { case O_CVTLOG: - /* conversion to logical */ - value = (eval_numeric(mpl, code->arg.arg.x) != 0.0); - break; - case O_NOT: - /* negation (logical "not") */ - value = !eval_logical(mpl, code->arg.arg.x); - break; - case O_LT: - /* comparison on 'less than' */ -#if 0 /* 02/VIII-2008 */ - value = (eval_numeric(mpl, code->arg.arg.x) < - eval_numeric(mpl, code->arg.arg.y)); -#else - xassert(code->arg.arg.x != NULL); - if (code->arg.arg.x->type == A_NUMERIC) - value = (eval_numeric(mpl, code->arg.arg.x) < - eval_numeric(mpl, code->arg.arg.y)); - else - { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); - SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); - value = (compare_symbols(mpl, sym1, sym2) < 0); - delete_symbol(mpl, sym1); - delete_symbol(mpl, sym2); - } -#endif - break; - case O_LE: - /* comparison on 'not greater than' */ -#if 0 /* 02/VIII-2008 */ - value = (eval_numeric(mpl, code->arg.arg.x) <= - eval_numeric(mpl, code->arg.arg.y)); -#else - xassert(code->arg.arg.x != NULL); - if (code->arg.arg.x->type == A_NUMERIC) - value = (eval_numeric(mpl, code->arg.arg.x) <= - eval_numeric(mpl, code->arg.arg.y)); - else - { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); - SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); - value = (compare_symbols(mpl, sym1, sym2) <= 0); - delete_symbol(mpl, sym1); - delete_symbol(mpl, sym2); - } -#endif - break; - case O_EQ: - /* comparison on 'equal to' */ - xassert(code->arg.arg.x != NULL); - if (code->arg.arg.x->type == A_NUMERIC) - value = (eval_numeric(mpl, code->arg.arg.x) == - eval_numeric(mpl, code->arg.arg.y)); - else - { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); - SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); - value = (compare_symbols(mpl, sym1, sym2) == 0); - delete_symbol(mpl, sym1); - delete_symbol(mpl, sym2); - } - break; - case O_GE: - /* comparison on 'not less than' */ -#if 0 /* 02/VIII-2008 */ - value = (eval_numeric(mpl, code->arg.arg.x) >= - eval_numeric(mpl, code->arg.arg.y)); -#else - xassert(code->arg.arg.x != NULL); - if (code->arg.arg.x->type == A_NUMERIC) - value = (eval_numeric(mpl, code->arg.arg.x) >= - eval_numeric(mpl, code->arg.arg.y)); - else - { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); - SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); - value = (compare_symbols(mpl, sym1, sym2) >= 0); - delete_symbol(mpl, sym1); - delete_symbol(mpl, sym2); - } -#endif - break; - case O_GT: - /* comparison on 'greater than' */ -#if 0 /* 02/VIII-2008 */ - value = (eval_numeric(mpl, code->arg.arg.x) > - eval_numeric(mpl, code->arg.arg.y)); -#else - xassert(code->arg.arg.x != NULL); - if (code->arg.arg.x->type == A_NUMERIC) - value = (eval_numeric(mpl, code->arg.arg.x) > - eval_numeric(mpl, code->arg.arg.y)); - else - { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); - SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); - value = (compare_symbols(mpl, sym1, sym2) > 0); - delete_symbol(mpl, sym1); - delete_symbol(mpl, sym2); - } -#endif - break; - case O_NE: - /* comparison on 'not equal to' */ - xassert(code->arg.arg.x != NULL); - if (code->arg.arg.x->type == A_NUMERIC) - value = (eval_numeric(mpl, code->arg.arg.x) != - eval_numeric(mpl, code->arg.arg.y)); - else - { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); - SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); - value = (compare_symbols(mpl, sym1, sym2) != 0); - delete_symbol(mpl, sym1); - delete_symbol(mpl, sym2); - } - break; - case O_AND: - /* conjunction (logical "and") */ - value = eval_logical(mpl, code->arg.arg.x) && - eval_logical(mpl, code->arg.arg.y); - break; - case O_OR: - /* disjunction (logical "or") */ - value = eval_logical(mpl, code->arg.arg.x) || - eval_logical(mpl, code->arg.arg.y); - break; - case O_IN: - /* test on 'x in Y' */ - { TUPLE *tuple; - tuple = eval_tuple(mpl, code->arg.arg.x); - value = is_member(mpl, code->arg.arg.y, tuple); - delete_tuple(mpl, tuple); - } - break; - case O_NOTIN: - /* test on 'x not in Y' */ - { TUPLE *tuple; - tuple = eval_tuple(mpl, code->arg.arg.x); - value = !is_member(mpl, code->arg.arg.y, tuple); - delete_tuple(mpl, tuple); - } - break; - case O_WITHIN: - /* test on 'X within Y' */ - { ELEMSET *set; - MEMBER *memb; - set = eval_elemset(mpl, code->arg.arg.x); - value = 1; - for (memb = set->head; memb != NULL; memb = memb->next) - { if (!is_member(mpl, code->arg.arg.y, memb->tuple)) - { value = 0; - break; - } - } - delete_elemset(mpl, set); - } - break; - case O_NOTWITHIN: - /* test on 'X not within Y' */ - { ELEMSET *set; - MEMBER *memb; - set = eval_elemset(mpl, code->arg.arg.x); - value = 1; - for (memb = set->head; memb != NULL; memb = memb->next) - { if (is_member(mpl, code->arg.arg.y, memb->tuple)) - { value = 0; - break; - } - } - delete_elemset(mpl, set); - } - break; - case O_FORALL: - /* conjunction (A-quantification) */ - { struct iter_log_info _info, *info = &_info; - info->code = code; - info->value = 1; - loop_within_domain(mpl, code->arg.loop.domain, info, - iter_log_func); - value = info->value; - } - break; - case O_EXISTS: - /* disjunction (E-quantification) */ - { struct iter_log_info _info, *info = &_info; - info->code = code; - info->value = 0; - loop_within_domain(mpl, code->arg.loop.domain, info, - iter_log_func); - value = info->value; - } - break; - default: - xassert(code != code); - } - /* save resultant value */ - xassert(!code->valid); - code->valid = 1; - code->value.bit = value; -done: return value; -} - -/*---------------------------------------------------------------------- --- eval_tuple - evaluate pseudo-code to construct n-tuple. --- --- This routine evaluates specified pseudo-code to construct resultant --- n-tuple, which is returned on exit. */ - -TUPLE *eval_tuple(MPL *mpl, CODE *code) -{ TUPLE *value; - xassert(code != NULL); - xassert(code->type == A_TUPLE); - xassert(code->dim > 0); - /* if the operation has a side effect, invalidate and delete the - resultant value */ - if (code->vflag && code->valid) - { code->valid = 0; - delete_value(mpl, code->type, &code->value); - } - /* if resultant value is valid, no evaluation is needed */ - if (code->valid) - { value = copy_tuple(mpl, code->value.tuple); - goto done; - } - /* evaluate pseudo-code recursively */ - switch (code->op) - { case O_TUPLE: - /* make n-tuple */ - { ARG_LIST *e; - value = create_tuple(mpl); - for (e = code->arg.list; e != NULL; e = e->next) - value = expand_tuple(mpl, value, eval_symbolic(mpl, - e->x)); - } - break; - case O_CVTTUP: - /* convert to 1-tuple */ - value = expand_tuple(mpl, create_tuple(mpl), - eval_symbolic(mpl, code->arg.arg.x)); - break; - default: - xassert(code != code); - } - /* save resultant value */ - xassert(!code->valid); - code->valid = 1; - code->value.tuple = copy_tuple(mpl, value); -done: return value; -} - -/*---------------------------------------------------------------------- --- eval_elemset - evaluate pseudo-code to construct elemental set. --- --- This routine evaluates specified pseudo-code to construct resultant --- elemental set, which is returned on exit. */ - -struct iter_set_info -{ /* working info used by the routine iter_set_func */ - CODE *code; - /* pseudo-code for iterated operation to be performed */ - ELEMSET *value; - /* resultant value */ -}; - -static int iter_set_func(MPL *mpl, void *_info) -{ /* this is auxiliary routine used to perform iterated operation - on n-tuple "integrand" within domain scope */ - struct iter_set_info *info = _info; - TUPLE *tuple; - switch (info->code->op) - { case O_SETOF: - /* compute next n-tuple and add it to the set; in this case - duplicate n-tuples are silently ignored */ - tuple = eval_tuple(mpl, info->code->arg.loop.x); - if (find_tuple(mpl, info->value, tuple) == NULL) - add_tuple(mpl, info->value, tuple); - else - delete_tuple(mpl, tuple); - break; - case O_BUILD: - /* construct next n-tuple using current values assigned to - *free* dummy indices as its components and add it to the - set; in this case duplicate n-tuples cannot appear */ - add_tuple(mpl, info->value, get_domain_tuple(mpl, - info->code->arg.loop.domain)); - break; - default: - xassert(info != info); - } - return 0; -} - -ELEMSET *eval_elemset(MPL *mpl, CODE *code) -{ ELEMSET *value; - xassert(code != NULL); - xassert(code->type == A_ELEMSET); - xassert(code->dim > 0); - /* if the operation has a side effect, invalidate and delete the - resultant value */ - if (code->vflag && code->valid) - { code->valid = 0; - delete_value(mpl, code->type, &code->value); - } - /* if resultant value is valid, no evaluation is needed */ - if (code->valid) - { value = copy_elemset(mpl, code->value.set); - goto done; - } - /* evaluate pseudo-code recursively */ - switch (code->op) - { case O_MEMSET: - /* take member of set */ - { TUPLE *tuple; - ARG_LIST *e; - tuple = create_tuple(mpl); - for (e = code->arg.set.list; e != NULL; e = e->next) - tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, - e->x)); - value = copy_elemset(mpl, - eval_member_set(mpl, code->arg.set.set, tuple)); - delete_tuple(mpl, tuple); - } - break; - case O_MAKE: - /* make elemental set of n-tuples */ - { ARG_LIST *e; - value = create_elemset(mpl, code->dim); - for (e = code->arg.list; e != NULL; e = e->next) - check_then_add(mpl, value, eval_tuple(mpl, e->x)); - } - break; - case O_UNION: - /* union of two elemental sets */ - value = set_union(mpl, - eval_elemset(mpl, code->arg.arg.x), - eval_elemset(mpl, code->arg.arg.y)); - break; - case O_DIFF: - /* difference between two elemental sets */ - value = set_diff(mpl, - eval_elemset(mpl, code->arg.arg.x), - eval_elemset(mpl, code->arg.arg.y)); - break; - case O_SYMDIFF: - /* symmetric difference between two elemental sets */ - value = set_symdiff(mpl, - eval_elemset(mpl, code->arg.arg.x), - eval_elemset(mpl, code->arg.arg.y)); - break; - case O_INTER: - /* intersection of two elemental sets */ - value = set_inter(mpl, - eval_elemset(mpl, code->arg.arg.x), - eval_elemset(mpl, code->arg.arg.y)); - break; - case O_CROSS: - /* cross (Cartesian) product of two elemental sets */ - value = set_cross(mpl, - eval_elemset(mpl, code->arg.arg.x), - eval_elemset(mpl, code->arg.arg.y)); - break; - case O_DOTS: - /* build "arithmetic" elemental set */ - value = create_arelset(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_numeric(mpl, code->arg.arg.y), - code->arg.arg.z == NULL ? 1.0 : eval_numeric(mpl, - code->arg.arg.z)); - break; - case O_FORK: - /* if-then-else */ - if (eval_logical(mpl, code->arg.arg.x)) - value = eval_elemset(mpl, code->arg.arg.y); - else - value = eval_elemset(mpl, code->arg.arg.z); - break; - case O_SETOF: - /* compute elemental set */ - { struct iter_set_info _info, *info = &_info; - info->code = code; - info->value = create_elemset(mpl, code->dim); - loop_within_domain(mpl, code->arg.loop.domain, info, - iter_set_func); - value = info->value; - } - break; - case O_BUILD: - /* build elemental set identical to domain set */ - { struct iter_set_info _info, *info = &_info; - info->code = code; - info->value = create_elemset(mpl, code->dim); - loop_within_domain(mpl, code->arg.loop.domain, info, - iter_set_func); - value = info->value; - } - break; - default: - xassert(code != code); - } - /* save resultant value */ - xassert(!code->valid); - code->valid = 1; - code->value.set = copy_elemset(mpl, value); -done: return value; -} - -/*---------------------------------------------------------------------- --- is_member - check if n-tuple is in set specified by pseudo-code. --- --- This routine checks if given n-tuple is a member of elemental set --- specified in the form of pseudo-code (i.e. by expression). --- --- The n-tuple may have more components that dimension of the elemental --- set, in which case the extra components are ignored. */ - -static void null_func(MPL *mpl, void *info) -{ /* this is dummy routine used to enter the domain scope */ - xassert(mpl == mpl); - xassert(info == NULL); - return; -} - -int is_member(MPL *mpl, CODE *code, TUPLE *tuple) -{ int value; - xassert(code != NULL); - xassert(code->type == A_ELEMSET); - xassert(code->dim > 0); - xassert(tuple != NULL); - switch (code->op) - { case O_MEMSET: - /* check if given n-tuple is member of elemental set, which - is assigned to member of model set */ - { ARG_LIST *e; - TUPLE *temp; - ELEMSET *set; - /* evaluate reference to elemental set */ - temp = create_tuple(mpl); - for (e = code->arg.set.list; e != NULL; e = e->next) - temp = expand_tuple(mpl, temp, eval_symbolic(mpl, - e->x)); - set = eval_member_set(mpl, code->arg.set.set, temp); - delete_tuple(mpl, temp); - /* check if the n-tuple is contained in the set array */ - temp = build_subtuple(mpl, tuple, set->dim); - value = (find_tuple(mpl, set, temp) != NULL); - delete_tuple(mpl, temp); - } - break; - case O_MAKE: - /* check if given n-tuple is member of literal set */ - { ARG_LIST *e; - TUPLE *temp, *that; - value = 0; - temp = build_subtuple(mpl, tuple, code->dim); - for (e = code->arg.list; e != NULL; e = e->next) - { that = eval_tuple(mpl, e->x); - value = (compare_tuples(mpl, temp, that) == 0); - delete_tuple(mpl, that); - if (value) break; - } - delete_tuple(mpl, temp); - } - break; - case O_UNION: - value = is_member(mpl, code->arg.arg.x, tuple) || - is_member(mpl, code->arg.arg.y, tuple); - break; - case O_DIFF: - value = is_member(mpl, code->arg.arg.x, tuple) && - !is_member(mpl, code->arg.arg.y, tuple); - break; - case O_SYMDIFF: - { int in1 = is_member(mpl, code->arg.arg.x, tuple); - int in2 = is_member(mpl, code->arg.arg.y, tuple); - value = (in1 && !in2) || (!in1 && in2); - } - break; - case O_INTER: - value = is_member(mpl, code->arg.arg.x, tuple) && - is_member(mpl, code->arg.arg.y, tuple); - break; - case O_CROSS: - { int j; - value = is_member(mpl, code->arg.arg.x, tuple); - if (value) - { for (j = 1; j <= code->arg.arg.x->dim; j++) - { xassert(tuple != NULL); - tuple = tuple->next; - } - value = is_member(mpl, code->arg.arg.y, tuple); - } - } - break; - case O_DOTS: - /* check if given 1-tuple is member of "arithmetic" set */ - { int j; - double x, t0, tf, dt; - xassert(code->dim == 1); - /* compute "parameters" of the "arithmetic" set */ - t0 = eval_numeric(mpl, code->arg.arg.x); - tf = eval_numeric(mpl, code->arg.arg.y); - if (code->arg.arg.z == NULL) - dt = 1.0; - else - dt = eval_numeric(mpl, code->arg.arg.z); - /* make sure the parameters are correct */ - arelset_size(mpl, t0, tf, dt); - /* if component of 1-tuple is symbolic, not numeric, the - 1-tuple cannot be member of "arithmetic" set */ - xassert(tuple->sym != NULL); - if (tuple->sym->str != NULL) - { value = 0; - break; - } - /* determine numeric value of the component */ - x = tuple->sym->num; - /* if the component value is out of the set range, the - 1-tuple is not in the set */ - if (dt > 0.0 && !(t0 <= x && x <= tf) || - dt < 0.0 && !(tf <= x && x <= t0)) - { value = 0; - break; - } - /* estimate ordinal number of the 1-tuple in the set */ - j = (int)(((x - t0) / dt) + 0.5) + 1; - /* perform the main check */ - value = (arelset_member(mpl, t0, tf, dt, j) == x); - } - break; - case O_FORK: - /* check if given n-tuple is member of conditional set */ - if (eval_logical(mpl, code->arg.arg.x)) - value = is_member(mpl, code->arg.arg.y, tuple); - else - value = is_member(mpl, code->arg.arg.z, tuple); - break; - case O_SETOF: - /* check if given n-tuple is member of computed set */ - /* it is not clear how to efficiently perform the check not - computing the entire elemental set :+( */ - error(mpl, "implementation restriction; in/within setof{} n" - "ot allowed"); - break; - case O_BUILD: - /* check if given n-tuple is member of domain set */ - { TUPLE *temp; - temp = build_subtuple(mpl, tuple, code->dim); - /* try to enter the domain scope; if it is successful, - the n-tuple is in the domain set */ - value = (eval_within_domain(mpl, code->arg.loop.domain, - temp, NULL, null_func) == 0); - delete_tuple(mpl, temp); - } - break; - default: - xassert(code != code); - } - return value; -} - -/*---------------------------------------------------------------------- --- eval_formula - evaluate pseudo-code to construct linear form. --- --- This routine evaluates specified pseudo-code to construct resultant --- linear form, which is returned on exit. */ - -struct iter_form_info -{ /* working info used by the routine iter_form_func */ - CODE *code; - /* pseudo-code for iterated operation to be performed */ - FORMULA *value; - /* resultant value */ - FORMULA *tail; - /* pointer to the last term */ -}; - -static int iter_form_func(MPL *mpl, void *_info) -{ /* this is auxiliary routine used to perform iterated operation - on linear form "integrand" within domain scope */ - struct iter_form_info *info = _info; - switch (info->code->op) - { case O_SUM: - /* summation over domain */ -#if 0 - info->value = - linear_comb(mpl, - +1.0, info->value, - +1.0, eval_formula(mpl, info->code->arg.loop.x)); -#else - /* the routine linear_comb needs to look through all terms - of both linear forms to reduce identical terms, so using - it here is not a good idea (for example, evaluation of - sum{i in 1..n} x[i] required quadratic time); the better - idea is to gather all terms of the integrand in one list - and reduce identical terms only once after all terms of - the resultant linear form have been evaluated */ - { FORMULA *form, *term; - form = eval_formula(mpl, info->code->arg.loop.x); - if (info->value == NULL) - { xassert(info->tail == NULL); - info->value = form; - } - else - { xassert(info->tail != NULL); - info->tail->next = form; - } - for (term = form; term != NULL; term = term->next) - info->tail = term; - } -#endif - break; - default: - xassert(info != info); - } - return 0; -} - -FORMULA *eval_formula(MPL *mpl, CODE *code) -{ FORMULA *value; - xassert(code != NULL); - xassert(code->type == A_FORMULA); - xassert(code->dim == 0); - /* if the operation has a side effect, invalidate and delete the - resultant value */ - if (code->vflag && code->valid) - { code->valid = 0; - delete_value(mpl, code->type, &code->value); - } - /* if resultant value is valid, no evaluation is needed */ - if (code->valid) - { value = copy_formula(mpl, code->value.form); - goto done; - } - /* evaluate pseudo-code recursively */ - switch (code->op) - { case O_MEMVAR: - /* take member of variable */ - { TUPLE *tuple; - ARG_LIST *e; - tuple = create_tuple(mpl); - for (e = code->arg.var.list; e != NULL; e = e->next) - tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, - e->x)); -#if 1 /* 15/V-2010 */ - xassert(code->arg.var.suff == DOT_NONE); -#endif - value = single_variable(mpl, - eval_member_var(mpl, code->arg.var.var, tuple)); - delete_tuple(mpl, tuple); - } - break; - case O_CVTLFM: - /* convert to linear form */ - value = constant_term(mpl, eval_numeric(mpl, - code->arg.arg.x)); - break; - case O_PLUS: - /* unary plus */ - value = linear_comb(mpl, - 0.0, constant_term(mpl, 0.0), - +1.0, eval_formula(mpl, code->arg.arg.x)); - break; - case O_MINUS: - /* unary minus */ - value = linear_comb(mpl, - 0.0, constant_term(mpl, 0.0), - -1.0, eval_formula(mpl, code->arg.arg.x)); - break; - case O_ADD: - /* addition */ - value = linear_comb(mpl, - +1.0, eval_formula(mpl, code->arg.arg.x), - +1.0, eval_formula(mpl, code->arg.arg.y)); - break; - case O_SUB: - /* subtraction */ - value = linear_comb(mpl, - +1.0, eval_formula(mpl, code->arg.arg.x), - -1.0, eval_formula(mpl, code->arg.arg.y)); - break; - case O_MUL: - /* multiplication */ - xassert(code->arg.arg.x != NULL); - xassert(code->arg.arg.y != NULL); - if (code->arg.arg.x->type == A_NUMERIC) - { xassert(code->arg.arg.y->type == A_FORMULA); - value = linear_comb(mpl, - eval_numeric(mpl, code->arg.arg.x), - eval_formula(mpl, code->arg.arg.y), - 0.0, constant_term(mpl, 0.0)); - } - else - { xassert(code->arg.arg.x->type == A_FORMULA); - xassert(code->arg.arg.y->type == A_NUMERIC); - value = linear_comb(mpl, - eval_numeric(mpl, code->arg.arg.y), - eval_formula(mpl, code->arg.arg.x), - 0.0, constant_term(mpl, 0.0)); - } - break; - case O_DIV: - /* division */ - value = linear_comb(mpl, - fp_div(mpl, 1.0, eval_numeric(mpl, code->arg.arg.y)), - eval_formula(mpl, code->arg.arg.x), - 0.0, constant_term(mpl, 0.0)); - break; - case O_FORK: - /* if-then-else */ - if (eval_logical(mpl, code->arg.arg.x)) - value = eval_formula(mpl, code->arg.arg.y); - else if (code->arg.arg.z == NULL) - value = constant_term(mpl, 0.0); - else - value = eval_formula(mpl, code->arg.arg.z); - break; - case O_SUM: - /* summation over domain */ - { struct iter_form_info _info, *info = &_info; - info->code = code; - info->value = constant_term(mpl, 0.0); - info->tail = NULL; - loop_within_domain(mpl, code->arg.loop.domain, info, - iter_form_func); - value = reduce_terms(mpl, info->value); - } - break; - default: - xassert(code != code); - } - /* save resultant value */ - xassert(!code->valid); - code->valid = 1; - code->value.form = copy_formula(mpl, value); -done: return value; -} - -/*---------------------------------------------------------------------- --- clean_code - clean pseudo-code. --- --- This routine recursively cleans specified pseudo-code that assumes --- deleting all temporary resultant values. */ - -void clean_code(MPL *mpl, CODE *code) -{ ARG_LIST *e; - /* if no pseudo-code is specified, do nothing */ - if (code == NULL) goto done; - /* if resultant value is valid (exists), delete it */ - if (code->valid) - { code->valid = 0; - delete_value(mpl, code->type, &code->value); - } - /* recursively clean pseudo-code for operands */ - switch (code->op) - { case O_NUMBER: - case O_STRING: - case O_INDEX: - break; - case O_MEMNUM: - case O_MEMSYM: - for (e = code->arg.par.list; e != NULL; e = e->next) - clean_code(mpl, e->x); - break; - case O_MEMSET: - for (e = code->arg.set.list; e != NULL; e = e->next) - clean_code(mpl, e->x); - break; - case O_MEMVAR: - for (e = code->arg.var.list; e != NULL; e = e->next) - clean_code(mpl, e->x); - break; -#if 1 /* 15/V-2010 */ - case O_MEMCON: - for (e = code->arg.con.list; e != NULL; e = e->next) - clean_code(mpl, e->x); - break; -#endif - case O_TUPLE: - case O_MAKE: - for (e = code->arg.list; e != NULL; e = e->next) - clean_code(mpl, e->x); - break; - case O_SLICE: - xassert(code != code); - case O_IRAND224: - case O_UNIFORM01: - case O_NORMAL01: - case O_GMTIME: - break; - case O_CVTNUM: - case O_CVTSYM: - case O_CVTLOG: - case O_CVTTUP: - case O_CVTLFM: - case O_PLUS: - case O_MINUS: - case O_NOT: - case O_ABS: - case O_CEIL: - case O_FLOOR: - case O_EXP: - case O_LOG: - case O_LOG10: - case O_SQRT: - case O_SIN: - case O_COS: - case O_ATAN: - case O_ROUND: - case O_TRUNC: - case O_CARD: - case O_LENGTH: - /* unary operation */ - clean_code(mpl, code->arg.arg.x); - break; - case O_ADD: - case O_SUB: - case O_LESS: - case O_MUL: - case O_DIV: - case O_IDIV: - case O_MOD: - case O_POWER: - case O_ATAN2: - case O_ROUND2: - case O_TRUNC2: - case O_UNIFORM: - case O_NORMAL: - case O_CONCAT: - case O_LT: - case O_LE: - case O_EQ: - case O_GE: - case O_GT: - case O_NE: - case O_AND: - case O_OR: - case O_UNION: - case O_DIFF: - case O_SYMDIFF: - case O_INTER: - case O_CROSS: - case O_IN: - case O_NOTIN: - case O_WITHIN: - case O_NOTWITHIN: - case O_SUBSTR: - case O_STR2TIME: - case O_TIME2STR: - /* binary operation */ - clean_code(mpl, code->arg.arg.x); - clean_code(mpl, code->arg.arg.y); - break; - case O_DOTS: - case O_FORK: - case O_SUBSTR3: - /* ternary operation */ - clean_code(mpl, code->arg.arg.x); - clean_code(mpl, code->arg.arg.y); - clean_code(mpl, code->arg.arg.z); - break; - case O_MIN: - case O_MAX: - /* n-ary operation */ - for (e = code->arg.list; e != NULL; e = e->next) - clean_code(mpl, e->x); - break; - case O_SUM: - case O_PROD: - case O_MINIMUM: - case O_MAXIMUM: - case O_FORALL: - case O_EXISTS: - case O_SETOF: - case O_BUILD: - /* iterated operation */ - clean_domain(mpl, code->arg.loop.domain); - clean_code(mpl, code->arg.loop.x); - break; - default: - xassert(code->op != code->op); - } -done: return; -} - -#if 1 /* 11/II-2008 */ -/**********************************************************************/ -/* * * DATA TABLES * * */ -/**********************************************************************/ - -int mpl_tab_num_args(TABDCA *dca) -{ /* returns the number of arguments */ - return dca->na; -} - -const char *mpl_tab_get_arg(TABDCA *dca, int k) -{ /* returns pointer to k-th argument */ - xassert(1 <= k && k <= dca->na); - return dca->arg[k]; -} - -int mpl_tab_num_flds(TABDCA *dca) -{ /* returns the number of fields */ - return dca->nf; -} - -const char *mpl_tab_get_name(TABDCA *dca, int k) -{ /* returns pointer to name of k-th field */ - xassert(1 <= k && k <= dca->nf); - return dca->name[k]; -} - -int mpl_tab_get_type(TABDCA *dca, int k) -{ /* returns type of k-th field */ - xassert(1 <= k && k <= dca->nf); - return dca->type[k]; -} - -double mpl_tab_get_num(TABDCA *dca, int k) -{ /* returns numeric value of k-th field */ - xassert(1 <= k && k <= dca->nf); - xassert(dca->type[k] == 'N'); - return dca->num[k]; -} - -const char *mpl_tab_get_str(TABDCA *dca, int k) -{ /* returns pointer to string value of k-th field */ - xassert(1 <= k && k <= dca->nf); - xassert(dca->type[k] == 'S'); - xassert(dca->str[k] != NULL); - return dca->str[k]; -} - -void mpl_tab_set_num(TABDCA *dca, int k, double num) -{ /* assign numeric value to k-th field */ - xassert(1 <= k && k <= dca->nf); - xassert(dca->type[k] == '?'); - dca->type[k] = 'N'; - dca->num[k] = num; - return; -} - -void mpl_tab_set_str(TABDCA *dca, int k, const char *str) -{ /* assign string value to k-th field */ - xassert(1 <= k && k <= dca->nf); - xassert(dca->type[k] == '?'); - xassert(strlen(str) <= MAX_LENGTH); - xassert(dca->str[k] != NULL); - dca->type[k] = 'S'; - strcpy(dca->str[k], str); - return; -} - -static int write_func(MPL *mpl, void *info) -{ /* this is auxiliary routine to work within domain scope */ - TABLE *tab = info; - TABDCA *dca = mpl->dca; - TABOUT *out; - SYMBOL *sym; - int k; - char buf[MAX_LENGTH+1]; - /* evaluate field values */ - k = 0; - for (out = tab->u.out.list; out != NULL; out = out->next) - { k++; - switch (out->code->type) - { case A_NUMERIC: - dca->type[k] = 'N'; - dca->num[k] = eval_numeric(mpl, out->code); - dca->str[k][0] = '\0'; - break; - case A_SYMBOLIC: - sym = eval_symbolic(mpl, out->code); - if (sym->str == NULL) - { dca->type[k] = 'N'; - dca->num[k] = sym->num; - dca->str[k][0] = '\0'; - } - else - { dca->type[k] = 'S'; - dca->num[k] = 0.0; - fetch_string(mpl, sym->str, buf); - strcpy(dca->str[k], buf); - } - delete_symbol(mpl, sym); - break; - default: - xassert(out != out); - } - } - /* write record to output table */ - mpl_tab_drv_write(mpl); - return 0; -} - -void execute_table(MPL *mpl, TABLE *tab) -{ /* execute table statement */ - TABARG *arg; - TABFLD *fld; - TABIN *in; - TABOUT *out; - TABDCA *dca; - SET *set; - int k; - char buf[MAX_LENGTH+1]; - /* allocate table driver communication area */ - xassert(mpl->dca == NULL); - mpl->dca = dca = xmalloc(sizeof(TABDCA)); - dca->id = 0; - dca->link = NULL; - dca->na = 0; - dca->arg = NULL; - dca->nf = 0; - dca->name = NULL; - dca->type = NULL; - dca->num = NULL; - dca->str = NULL; - /* allocate arguments */ - xassert(dca->na == 0); - for (arg = tab->arg; arg != NULL; arg = arg->next) - dca->na++; - dca->arg = xcalloc(1+dca->na, sizeof(char *)); -#if 1 /* 28/IX-2008 */ - for (k = 1; k <= dca->na; k++) dca->arg[k] = NULL; -#endif - /* evaluate argument values */ - k = 0; - for (arg = tab->arg; arg != NULL; arg = arg->next) - { SYMBOL *sym; - k++; - xassert(arg->code->type == A_SYMBOLIC); - sym = eval_symbolic(mpl, arg->code); - if (sym->str == NULL) - sprintf(buf, "%.*g", DBL_DIG, sym->num); - else - fetch_string(mpl, sym->str, buf); - delete_symbol(mpl, sym); - dca->arg[k] = xmalloc(strlen(buf)+1); - strcpy(dca->arg[k], buf); - } - /* perform table input/output */ - switch (tab->type) - { case A_INPUT: goto read_table; - case A_OUTPUT: goto write_table; - default: xassert(tab != tab); - } -read_table: - /* read data from input table */ - /* add the only member to the control set and assign it empty - elemental set */ - set = tab->u.in.set; - if (set != NULL) - { if (set->data) - error(mpl, "%s already provided with data", set->name); - xassert(set->array->head == NULL); - add_member(mpl, set->array, NULL)->value.set = - create_elemset(mpl, set->dimen); - set->data = 1; - } - /* check parameters specified in the input list */ - for (in = tab->u.in.list; in != NULL; in = in->next) - { if (in->par->data) - error(mpl, "%s already provided with data", in->par->name); - in->par->data = 1; - } - /* allocate and initialize fields */ - xassert(dca->nf == 0); - for (fld = tab->u.in.fld; fld != NULL; fld = fld->next) - dca->nf++; - for (in = tab->u.in.list; in != NULL; in = in->next) - dca->nf++; - dca->name = xcalloc(1+dca->nf, sizeof(char *)); - dca->type = xcalloc(1+dca->nf, sizeof(int)); - dca->num = xcalloc(1+dca->nf, sizeof(double)); - dca->str = xcalloc(1+dca->nf, sizeof(char *)); - k = 0; - for (fld = tab->u.in.fld; fld != NULL; fld = fld->next) - { k++; - dca->name[k] = fld->name; - dca->type[k] = '?'; - dca->num[k] = 0.0; - dca->str[k] = xmalloc(MAX_LENGTH+1); - dca->str[k][0] = '\0'; - } - for (in = tab->u.in.list; in != NULL; in = in->next) - { k++; - dca->name[k] = in->name; - dca->type[k] = '?'; - dca->num[k] = 0.0; - dca->str[k] = xmalloc(MAX_LENGTH+1); - dca->str[k][0] = '\0'; - } - /* open input table */ - mpl_tab_drv_open(mpl, 'R'); - /* read and process records */ - for (;;) - { TUPLE *tup; - /* reset field types */ - for (k = 1; k <= dca->nf; k++) - dca->type[k] = '?'; - /* read next record */ - if (mpl_tab_drv_read(mpl)) break; - /* all fields must be set by the driver */ - for (k = 1; k <= dca->nf; k++) - { if (dca->type[k] == '?') - error(mpl, "field %s missing in input table", - dca->name[k]); - } - /* construct n-tuple */ - tup = create_tuple(mpl); - k = 0; - for (fld = tab->u.in.fld; fld != NULL; fld = fld->next) - { k++; - xassert(k <= dca->nf); - switch (dca->type[k]) - { case 'N': - tup = expand_tuple(mpl, tup, create_symbol_num(mpl, - dca->num[k])); - break; - case 'S': - xassert(strlen(dca->str[k]) <= MAX_LENGTH); - tup = expand_tuple(mpl, tup, create_symbol_str(mpl, - create_string(mpl, dca->str[k]))); - break; - default: - xassert(dca != dca); - } - } - /* add n-tuple just read to the control set */ - if (tab->u.in.set != NULL) - check_then_add(mpl, tab->u.in.set->array->head->value.set, - copy_tuple(mpl, tup)); - /* assign values to the parameters in the input list */ - for (in = tab->u.in.list; in != NULL; in = in->next) - { MEMBER *memb; - k++; - xassert(k <= dca->nf); - /* there must be no member with the same n-tuple */ - if (find_member(mpl, in->par->array, tup) != NULL) - error(mpl, "%s%s already defined", in->par->name, - format_tuple(mpl, '[', tup)); - /* create new parameter member with given n-tuple */ - memb = add_member(mpl, in->par->array, copy_tuple(mpl, tup)) - ; - /* assign value to the parameter member */ - switch (in->par->type) - { case A_NUMERIC: - case A_INTEGER: - case A_BINARY: - if (dca->type[k] != 'N') - error(mpl, "%s requires numeric data", - in->par->name); - memb->value.num = dca->num[k]; - break; - case A_SYMBOLIC: - switch (dca->type[k]) - { case 'N': - memb->value.sym = create_symbol_num(mpl, - dca->num[k]); - break; - case 'S': - xassert(strlen(dca->str[k]) <= MAX_LENGTH); - memb->value.sym = create_symbol_str(mpl, - create_string(mpl,dca->str[k])); - break; - default: - xassert(dca != dca); - } - break; - default: - xassert(in != in); - } - } - /* n-tuple is no more needed */ - delete_tuple(mpl, tup); - } - /* close input table */ - mpl_tab_drv_close(mpl); - goto done; -write_table: - /* write data to output table */ - /* allocate and initialize fields */ - xassert(dca->nf == 0); - for (out = tab->u.out.list; out != NULL; out = out->next) - dca->nf++; - dca->name = xcalloc(1+dca->nf, sizeof(char *)); - dca->type = xcalloc(1+dca->nf, sizeof(int)); - dca->num = xcalloc(1+dca->nf, sizeof(double)); - dca->str = xcalloc(1+dca->nf, sizeof(char *)); - k = 0; - for (out = tab->u.out.list; out != NULL; out = out->next) - { k++; - dca->name[k] = out->name; - dca->type[k] = '?'; - dca->num[k] = 0.0; - dca->str[k] = xmalloc(MAX_LENGTH+1); - dca->str[k][0] = '\0'; - } - /* open output table */ - mpl_tab_drv_open(mpl, 'W'); - /* evaluate fields and write records */ - loop_within_domain(mpl, tab->u.out.domain, tab, write_func); - /* close output table */ - mpl_tab_drv_close(mpl); -done: /* free table driver communication area */ - free_dca(mpl); - return; -} - -void free_dca(MPL *mpl) -{ /* free table driver communucation area */ - TABDCA *dca = mpl->dca; - int k; - if (dca != NULL) - { if (dca->link != NULL) - mpl_tab_drv_close(mpl); - if (dca->arg != NULL) - { for (k = 1; k <= dca->na; k++) -#if 1 /* 28/IX-2008 */ - if (dca->arg[k] != NULL) -#endif - xfree(dca->arg[k]); - xfree(dca->arg); - } - if (dca->name != NULL) xfree(dca->name); - if (dca->type != NULL) xfree(dca->type); - if (dca->num != NULL) xfree(dca->num); - if (dca->str != NULL) - { for (k = 1; k <= dca->nf; k++) - xfree(dca->str[k]); - xfree(dca->str); - } - xfree(dca), mpl->dca = NULL; - } - return; -} - -void clean_table(MPL *mpl, TABLE *tab) -{ /* clean table statement */ - TABARG *arg; - TABOUT *out; - /* clean string list */ - for (arg = tab->arg; arg != NULL; arg = arg->next) - clean_code(mpl, arg->code); - switch (tab->type) - { case A_INPUT: - break; - case A_OUTPUT: - /* clean subscript domain */ - clean_domain(mpl, tab->u.out.domain); - /* clean output list */ - for (out = tab->u.out.list; out != NULL; out = out->next) - clean_code(mpl, out->code); - break; - default: - xassert(tab != tab); - } - return; -} -#endif - -/**********************************************************************/ -/* * * MODEL STATEMENTS * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- execute_check - execute check statement. --- --- This routine executes specified check statement. */ - -static int check_func(MPL *mpl, void *info) -{ /* this is auxiliary routine to work within domain scope */ - CHECK *chk = (CHECK *)info; - if (!eval_logical(mpl, chk->code)) - error(mpl, "check%s failed", format_tuple(mpl, '[', - get_domain_tuple(mpl, chk->domain))); - return 0; -} - -void execute_check(MPL *mpl, CHECK *chk) -{ loop_within_domain(mpl, chk->domain, chk, check_func); - return; -} - -/*---------------------------------------------------------------------- --- clean_check - clean check statement. --- --- This routine cleans specified check statement that assumes deleting --- all stuff dynamically allocated on generating/postsolving phase. */ - -void clean_check(MPL *mpl, CHECK *chk) -{ /* clean subscript domain */ - clean_domain(mpl, chk->domain); - /* clean pseudo-code for computing predicate */ - clean_code(mpl, chk->code); - return; -} - -/*---------------------------------------------------------------------- --- execute_display - execute display statement. --- --- This routine executes specified display statement. */ - -static void display_set(MPL *mpl, SET *set, MEMBER *memb) -{ /* display member of model set */ - ELEMSET *s = memb->value.set; - MEMBER *m; - write_text(mpl, "%s%s%s\n", set->name, - format_tuple(mpl, '[', memb->tuple), - s->head == NULL ? " is empty" : ":"); - for (m = s->head; m != NULL; m = m->next) - write_text(mpl, " %s\n", format_tuple(mpl, '(', m->tuple)); - return; -} - -static void display_par(MPL *mpl, PARAMETER *par, MEMBER *memb) -{ /* display member of model parameter */ - switch (par->type) - { case A_NUMERIC: - case A_INTEGER: - case A_BINARY: - write_text(mpl, "%s%s = %.*g\n", par->name, - format_tuple(mpl, '[', memb->tuple), - DBL_DIG, memb->value.num); - break; - case A_SYMBOLIC: - write_text(mpl, "%s%s = %s\n", par->name, - format_tuple(mpl, '[', memb->tuple), - format_symbol(mpl, memb->value.sym)); - break; - default: - xassert(par != par); - } - return; -} - -#if 1 /* 15/V-2010 */ -static void display_var(MPL *mpl, VARIABLE *var, MEMBER *memb, - int suff) -{ /* display member of model variable */ - if (suff == DOT_NONE || suff == DOT_VAL) - write_text(mpl, "%s%s.val = %.*g\n", var->name, - format_tuple(mpl, '[', memb->tuple), DBL_DIG, - memb->value.var->prim); - else if (suff == DOT_LB) - write_text(mpl, "%s%s.lb = %.*g\n", var->name, - format_tuple(mpl, '[', memb->tuple), DBL_DIG, - memb->value.var->var->lbnd == NULL ? -DBL_MAX : - memb->value.var->lbnd); - else if (suff == DOT_UB) - write_text(mpl, "%s%s.ub = %.*g\n", var->name, - format_tuple(mpl, '[', memb->tuple), DBL_DIG, - memb->value.var->var->ubnd == NULL ? +DBL_MAX : - memb->value.var->ubnd); - else if (suff == DOT_STATUS) - write_text(mpl, "%s%s.status = %d\n", var->name, format_tuple - (mpl, '[', memb->tuple), memb->value.var->stat); - else if (suff == DOT_DUAL) - write_text(mpl, "%s%s.dual = %.*g\n", var->name, - format_tuple(mpl, '[', memb->tuple), DBL_DIG, - memb->value.var->dual); - else - xassert(suff != suff); - return; -} -#endif - -#if 1 /* 15/V-2010 */ -static void display_con(MPL *mpl, CONSTRAINT *con, MEMBER *memb, - int suff) -{ /* display member of model constraint */ - if (suff == DOT_NONE || suff == DOT_VAL) - write_text(mpl, "%s%s.val = %.*g\n", con->name, - format_tuple(mpl, '[', memb->tuple), DBL_DIG, - memb->value.con->prim); - else if (suff == DOT_LB) - write_text(mpl, "%s%s.lb = %.*g\n", con->name, - format_tuple(mpl, '[', memb->tuple), DBL_DIG, - memb->value.con->con->lbnd == NULL ? -DBL_MAX : - memb->value.con->lbnd); - else if (suff == DOT_UB) - write_text(mpl, "%s%s.ub = %.*g\n", con->name, - format_tuple(mpl, '[', memb->tuple), DBL_DIG, - memb->value.con->con->ubnd == NULL ? +DBL_MAX : - memb->value.con->ubnd); - else if (suff == DOT_STATUS) - write_text(mpl, "%s%s.status = %d\n", con->name, format_tuple - (mpl, '[', memb->tuple), memb->value.con->stat); - else if (suff == DOT_DUAL) - write_text(mpl, "%s%s.dual = %.*g\n", con->name, - format_tuple(mpl, '[', memb->tuple), DBL_DIG, - memb->value.con->dual); - else - xassert(suff != suff); - return; -} -#endif - -static void display_memb(MPL *mpl, CODE *code) -{ /* display member specified by pseudo-code */ - MEMBER memb; - ARG_LIST *e; - xassert(code->op == O_MEMNUM || code->op == O_MEMSYM - || code->op == O_MEMSET || code->op == O_MEMVAR - || code->op == O_MEMCON); - memb.tuple = create_tuple(mpl); - for (e = code->arg.par.list; e != NULL; e = e->next) - memb.tuple = expand_tuple(mpl, memb.tuple, eval_symbolic(mpl, - e->x)); - switch (code->op) - { case O_MEMNUM: - memb.value.num = eval_member_num(mpl, code->arg.par.par, - memb.tuple); - display_par(mpl, code->arg.par.par, &memb); - break; - case O_MEMSYM: - memb.value.sym = eval_member_sym(mpl, code->arg.par.par, - memb.tuple); - display_par(mpl, code->arg.par.par, &memb); - delete_symbol(mpl, memb.value.sym); - break; - case O_MEMSET: - memb.value.set = eval_member_set(mpl, code->arg.set.set, - memb.tuple); - display_set(mpl, code->arg.set.set, &memb); - break; - case O_MEMVAR: - memb.value.var = eval_member_var(mpl, code->arg.var.var, - memb.tuple); - display_var - (mpl, code->arg.var.var, &memb, code->arg.var.suff); - break; - case O_MEMCON: - memb.value.con = eval_member_con(mpl, code->arg.con.con, - memb.tuple); - display_con - (mpl, code->arg.con.con, &memb, code->arg.con.suff); - break; - default: - xassert(code != code); - } - delete_tuple(mpl, memb.tuple); - return; -} - -static void display_code(MPL *mpl, CODE *code) -{ /* display value of expression */ - switch (code->type) - { case A_NUMERIC: - /* numeric value */ - { double num; - num = eval_numeric(mpl, code); - write_text(mpl, "%.*g\n", DBL_DIG, num); - } - break; - case A_SYMBOLIC: - /* symbolic value */ - { SYMBOL *sym; - sym = eval_symbolic(mpl, code); - write_text(mpl, "%s\n", format_symbol(mpl, sym)); - delete_symbol(mpl, sym); - } - break; - case A_LOGICAL: - /* logical value */ - { int bit; - bit = eval_logical(mpl, code); - write_text(mpl, "%s\n", bit ? "true" : "false"); - } - break; - case A_TUPLE: - /* n-tuple */ - { TUPLE *tuple; - tuple = eval_tuple(mpl, code); - write_text(mpl, "%s\n", format_tuple(mpl, '(', tuple)); - delete_tuple(mpl, tuple); - } - break; - case A_ELEMSET: - /* elemental set */ - { ELEMSET *set; - MEMBER *memb; - set = eval_elemset(mpl, code); - if (set->head == 0) - write_text(mpl, "set is empty\n"); - for (memb = set->head; memb != NULL; memb = memb->next) - write_text(mpl, " %s\n", format_tuple(mpl, '(', - memb->tuple)); - delete_elemset(mpl, set); - } - break; - case A_FORMULA: - /* linear form */ - { FORMULA *form, *term; - form = eval_formula(mpl, code); - if (form == NULL) - write_text(mpl, "linear form is empty\n"); - for (term = form; term != NULL; term = term->next) - { if (term->var == NULL) - write_text(mpl, " %.*g\n", term->coef); - else - write_text(mpl, " %.*g %s%s\n", DBL_DIG, - term->coef, term->var->var->name, - format_tuple(mpl, '[', term->var->memb->tuple)); - } - delete_formula(mpl, form); - } - break; - default: - xassert(code != code); - } - return; -} - -static int display_func(MPL *mpl, void *info) -{ /* this is auxiliary routine to work within domain scope */ - DISPLAY *dpy = (DISPLAY *)info; - DISPLAY1 *entry; - for (entry = dpy->list; entry != NULL; entry = entry->next) - { if (entry->type == A_INDEX) - { /* dummy index */ - DOMAIN_SLOT *slot = entry->u.slot; - write_text(mpl, "%s = %s\n", slot->name, - format_symbol(mpl, slot->value)); - } - else if (entry->type == A_SET) - { /* model set */ - SET *set = entry->u.set; - MEMBER *memb; - if (set->assign != NULL) - { /* the set has assignment expression; evaluate all its - members over entire domain */ - eval_whole_set(mpl, set); - } - else - { /* the set has no assignment expression; refer to its - any existing member ignoring resultant value to check - the data provided the data section */ -#if 1 /* 12/XII-2008 */ - if (set->gadget != NULL && set->data == 0) - { /* initialize the set with data from a plain set */ - saturate_set(mpl, set); - } -#endif - if (set->array->head != NULL) - eval_member_set(mpl, set, set->array->head->tuple); - } - /* display all members of the set array */ - if (set->array->head == NULL) - write_text(mpl, "%s has empty content\n", set->name); - for (memb = set->array->head; memb != NULL; memb = - memb->next) display_set(mpl, set, memb); - } - else if (entry->type == A_PARAMETER) - { /* model parameter */ - PARAMETER *par = entry->u.par; - MEMBER *memb; - if (par->assign != NULL) - { /* the parameter has an assignment expression; evaluate - all its member over entire domain */ - eval_whole_par(mpl, par); - } - else - { /* the parameter has no assignment expression; refer to - its any existing member ignoring resultant value to - check the data provided in the data section */ - if (par->array->head != NULL) - { if (par->type != A_SYMBOLIC) - eval_member_num(mpl, par, par->array->head->tuple); - else - delete_symbol(mpl, eval_member_sym(mpl, par, - par->array->head->tuple)); - } - } - /* display all members of the parameter array */ - if (par->array->head == NULL) - write_text(mpl, "%s has empty content\n", par->name); - for (memb = par->array->head; memb != NULL; memb = - memb->next) display_par(mpl, par, memb); - } - else if (entry->type == A_VARIABLE) - { /* model variable */ - VARIABLE *var = entry->u.var; - MEMBER *memb; - xassert(mpl->flag_p); - /* display all members of the variable array */ - if (var->array->head == NULL) - write_text(mpl, "%s has empty content\n", var->name); - for (memb = var->array->head; memb != NULL; memb = - memb->next) display_var(mpl, var, memb, DOT_NONE); - } - else if (entry->type == A_CONSTRAINT) - { /* model constraint */ - CONSTRAINT *con = entry->u.con; - MEMBER *memb; - xassert(mpl->flag_p); - /* display all members of the constraint array */ - if (con->array->head == NULL) - write_text(mpl, "%s has empty content\n", con->name); - for (memb = con->array->head; memb != NULL; memb = - memb->next) display_con(mpl, con, memb, DOT_NONE); - } - else if (entry->type == A_EXPRESSION) - { /* expression */ - CODE *code = entry->u.code; - if (code->op == O_MEMNUM || code->op == O_MEMSYM || - code->op == O_MEMSET || code->op == O_MEMVAR || - code->op == O_MEMCON) - display_memb(mpl, code); - else - display_code(mpl, code); - } - else - xassert(entry != entry); - } - return 0; -} - -void execute_display(MPL *mpl, DISPLAY *dpy) -{ loop_within_domain(mpl, dpy->domain, dpy, display_func); - return; -} - -/*---------------------------------------------------------------------- --- clean_display - clean display statement. --- --- This routine cleans specified display statement that assumes deleting --- all stuff dynamically allocated on generating/postsolving phase. */ - -void clean_display(MPL *mpl, DISPLAY *dpy) -{ DISPLAY1 *d; -#if 0 /* 15/V-2010 */ - ARG_LIST *e; -#endif - /* clean subscript domain */ - clean_domain(mpl, dpy->domain); - /* clean display list */ - for (d = dpy->list; d != NULL; d = d->next) - { /* clean pseudo-code for computing expression */ - if (d->type == A_EXPRESSION) - clean_code(mpl, d->u.code); -#if 0 /* 15/V-2010 */ - /* clean pseudo-code for computing subscripts */ - for (e = d->list; e != NULL; e = e->next) - clean_code(mpl, e->x); -#endif - } - return; -} - -/*---------------------------------------------------------------------- --- execute_printf - execute printf statement. --- --- This routine executes specified printf statement. */ - -#if 1 /* 14/VII-2006 */ -static void print_char(MPL *mpl, int c) -{ if (mpl->prt_fp == NULL) - write_char(mpl, c); - else -#if 0 /* 04/VIII-2013 */ - xfputc(c, mpl->prt_fp); -#else - { unsigned char buf[1]; - buf[0] = (unsigned char)c; - glp_write(mpl->prt_fp, buf, 1); - } -#endif - return; -} - -static void print_text(MPL *mpl, char *fmt, ...) -{ va_list arg; - char buf[OUTBUF_SIZE], *c; - va_start(arg, fmt); - vsprintf(buf, fmt, arg); - xassert(strlen(buf) < sizeof(buf)); - va_end(arg); - for (c = buf; *c != '\0'; c++) print_char(mpl, *c); - return; -} -#endif - -static int printf_func(MPL *mpl, void *info) -{ /* this is auxiliary routine to work within domain scope */ - PRINTF *prt = (PRINTF *)info; - PRINTF1 *entry; - SYMBOL *sym; - char fmt[MAX_LENGTH+1], *c, *from, save; - /* evaluate format control string */ - sym = eval_symbolic(mpl, prt->fmt); - if (sym->str == NULL) - sprintf(fmt, "%.*g", DBL_DIG, sym->num); - else - fetch_string(mpl, sym->str, fmt); - delete_symbol(mpl, sym); - /* scan format control string and perform formatting output */ - entry = prt->list; - for (c = fmt; *c != '\0'; c++) - { if (*c == '%') - { /* scan format specifier */ - from = c++; - if (*c == '%') - { print_char(mpl, '%'); - continue; - } - if (entry == NULL) break; - /* scan optional flags */ - while (*c == '-' || *c == '+' || *c == ' ' || *c == '#' || - *c == '0') c++; - /* scan optional minimum field width */ - while (isdigit((unsigned char)*c)) c++; - /* scan optional precision */ - if (*c == '.') - { c++; - while (isdigit((unsigned char)*c)) c++; - } - /* scan conversion specifier and perform formatting */ - save = *(c+1), *(c+1) = '\0'; - if (*c == 'd' || *c == 'i' || *c == 'e' || *c == 'E' || - *c == 'f' || *c == 'F' || *c == 'g' || *c == 'G') - { /* the specifier requires numeric value */ - double value; - xassert(entry != NULL); - switch (entry->code->type) - { case A_NUMERIC: - value = eval_numeric(mpl, entry->code); - break; - case A_SYMBOLIC: - sym = eval_symbolic(mpl, entry->code); - if (sym->str != NULL) - error(mpl, "cannot convert %s to floating-point" - " number", format_symbol(mpl, sym)); - value = sym->num; - delete_symbol(mpl, sym); - break; - case A_LOGICAL: - if (eval_logical(mpl, entry->code)) - value = 1.0; - else - value = 0.0; - break; - default: - xassert(entry != entry); - } - if (*c == 'd' || *c == 'i') - { double int_max = (double)INT_MAX; - if (!(-int_max <= value && value <= +int_max)) - error(mpl, "cannot convert %.*g to integer", - DBL_DIG, value); - print_text(mpl, from, (int)floor(value + 0.5)); - } - else - print_text(mpl, from, value); - } - else if (*c == 's') - { /* the specifier requires symbolic value */ - char value[MAX_LENGTH+1]; - switch (entry->code->type) - { case A_NUMERIC: - sprintf(value, "%.*g", DBL_DIG, eval_numeric(mpl, - entry->code)); - break; - case A_LOGICAL: - if (eval_logical(mpl, entry->code)) - strcpy(value, "T"); - else - strcpy(value, "F"); - break; - case A_SYMBOLIC: - sym = eval_symbolic(mpl, entry->code); - if (sym->str == NULL) - sprintf(value, "%.*g", DBL_DIG, sym->num); - else - fetch_string(mpl, sym->str, value); - delete_symbol(mpl, sym); - break; - default: - xassert(entry != entry); - } - print_text(mpl, from, value); - } - else - error(mpl, "format specifier missing or invalid"); - *(c+1) = save; - entry = entry->next; - } - else if (*c == '\\') - { /* write some control character */ - c++; - if (*c == 't') - print_char(mpl, '\t'); - else if (*c == 'n') - print_char(mpl, '\n'); -#if 1 /* 28/X-2010 */ - else if (*c == '\0') - { /* format string ends with backslash */ - error(mpl, "invalid use of escape character \\ in format" - " control string"); - } -#endif - else - print_char(mpl, *c); - } - else - { /* write character without formatting */ - print_char(mpl, *c); - } - } - return 0; -} - -#if 0 /* 14/VII-2006 */ -void execute_printf(MPL *mpl, PRINTF *prt) -{ loop_within_domain(mpl, prt->domain, prt, printf_func); - return; -} -#else -void execute_printf(MPL *mpl, PRINTF *prt) -{ if (prt->fname == NULL) - { /* switch to the standard output */ - if (mpl->prt_fp != NULL) - { glp_close(mpl->prt_fp), mpl->prt_fp = NULL; - xfree(mpl->prt_file), mpl->prt_file = NULL; - } - } - else - { /* evaluate file name string */ - SYMBOL *sym; - char fname[MAX_LENGTH+1]; - sym = eval_symbolic(mpl, prt->fname); - if (sym->str == NULL) - sprintf(fname, "%.*g", DBL_DIG, sym->num); - else - fetch_string(mpl, sym->str, fname); - delete_symbol(mpl, sym); - /* close the current print file, if necessary */ - if (mpl->prt_fp != NULL && - (!prt->app || strcmp(mpl->prt_file, fname) != 0)) - { glp_close(mpl->prt_fp), mpl->prt_fp = NULL; - xfree(mpl->prt_file), mpl->prt_file = NULL; - } - /* open the specified print file, if necessary */ - if (mpl->prt_fp == NULL) - { mpl->prt_fp = glp_open(fname, prt->app ? "a" : "w"); - if (mpl->prt_fp == NULL) - error(mpl, "unable to open `%s' for writing - %s", - fname, get_err_msg()); - mpl->prt_file = xmalloc(strlen(fname)+1); - strcpy(mpl->prt_file, fname); - } - } - loop_within_domain(mpl, prt->domain, prt, printf_func); - if (mpl->prt_fp != NULL) - { -#if 0 /* FIXME */ - xfflush(mpl->prt_fp); -#endif - if (glp_ioerr(mpl->prt_fp)) - error(mpl, "writing error to `%s' - %s", mpl->prt_file, - get_err_msg()); - } - return; -} -#endif - -/*---------------------------------------------------------------------- --- clean_printf - clean printf statement. --- --- This routine cleans specified printf statement that assumes deleting --- all stuff dynamically allocated on generating/postsolving phase. */ - -void clean_printf(MPL *mpl, PRINTF *prt) -{ PRINTF1 *p; - /* clean subscript domain */ - clean_domain(mpl, prt->domain); - /* clean pseudo-code for computing format string */ - clean_code(mpl, prt->fmt); - /* clean printf list */ - for (p = prt->list; p != NULL; p = p->next) - { /* clean pseudo-code for computing value to be printed */ - clean_code(mpl, p->code); - } -#if 1 /* 14/VII-2006 */ - /* clean pseudo-code for computing file name string */ - clean_code(mpl, prt->fname); -#endif - return; -} - -/*---------------------------------------------------------------------- --- execute_for - execute for statement. --- --- This routine executes specified for statement. */ - -static int for_func(MPL *mpl, void *info) -{ /* this is auxiliary routine to work within domain scope */ - FOR *fur = (FOR *)info; - STATEMENT *stmt, *save; - save = mpl->stmt; - for (stmt = fur->list; stmt != NULL; stmt = stmt->next) - execute_statement(mpl, stmt); - mpl->stmt = save; - return 0; -} - -void execute_for(MPL *mpl, FOR *fur) -{ loop_within_domain(mpl, fur->domain, fur, for_func); - return; -} - -/*---------------------------------------------------------------------- --- clean_for - clean for statement. --- --- This routine cleans specified for statement that assumes deleting all --- stuff dynamically allocated on generating/postsolving phase. */ - -void clean_for(MPL *mpl, FOR *fur) -{ STATEMENT *stmt; - /* clean subscript domain */ - clean_domain(mpl, fur->domain); - /* clean all sub-statements */ - for (stmt = fur->list; stmt != NULL; stmt = stmt->next) - clean_statement(mpl, stmt); - return; -} - -/*---------------------------------------------------------------------- --- execute_statement - execute specified model statement. --- --- This routine executes specified model statement. */ - -void execute_statement(MPL *mpl, STATEMENT *stmt) -{ mpl->stmt = stmt; - switch (stmt->type) - { case A_SET: - case A_PARAMETER: - case A_VARIABLE: - break; - case A_CONSTRAINT: - xprintf("Generating %s...\n", stmt->u.con->name); - eval_whole_con(mpl, stmt->u.con); - break; - case A_TABLE: - switch (stmt->u.tab->type) - { case A_INPUT: - xprintf("Reading %s...\n", stmt->u.tab->name); - break; - case A_OUTPUT: - xprintf("Writing %s...\n", stmt->u.tab->name); - break; - default: - xassert(stmt != stmt); - } - execute_table(mpl, stmt->u.tab); - break; - case A_SOLVE: - break; - case A_CHECK: - xprintf("Checking (line %d)...\n", stmt->line); - execute_check(mpl, stmt->u.chk); - break; - case A_DISPLAY: - write_text(mpl, "Display statement at line %d\n", - stmt->line); - execute_display(mpl, stmt->u.dpy); - break; - case A_PRINTF: - execute_printf(mpl, stmt->u.prt); - break; - case A_FOR: - execute_for(mpl, stmt->u.fur); - break; - default: - xassert(stmt != stmt); - } - return; -} - -/*---------------------------------------------------------------------- --- clean_statement - clean specified model statement. --- --- This routine cleans specified model statement that assumes deleting --- all stuff dynamically allocated on generating/postsolving phase. */ - -void clean_statement(MPL *mpl, STATEMENT *stmt) -{ switch(stmt->type) - { case A_SET: - clean_set(mpl, stmt->u.set); break; - case A_PARAMETER: - clean_parameter(mpl, stmt->u.par); break; - case A_VARIABLE: - clean_variable(mpl, stmt->u.var); break; - case A_CONSTRAINT: - clean_constraint(mpl, stmt->u.con); break; -#if 1 /* 11/II-2008 */ - case A_TABLE: - clean_table(mpl, stmt->u.tab); break; -#endif - case A_SOLVE: - break; - case A_CHECK: - clean_check(mpl, stmt->u.chk); break; - case A_DISPLAY: - clean_display(mpl, stmt->u.dpy); break; - case A_PRINTF: - clean_printf(mpl, stmt->u.prt); break; - case A_FOR: - clean_for(mpl, stmt->u.fur); break; - default: - xassert(stmt != stmt); - } - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpmpl04.c b/resources/3rdparty/glpk-4.53/src/glpmpl04.c deleted file mode 100644 index 4ec2c19c2..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpmpl04.c +++ /dev/null @@ -1,1427 +0,0 @@ -/* glpmpl04.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "glpmpl.h" - -#define xfault xerror -#define xfprintf glp_format -#define dmp_create_poolx(size) dmp_create_pool() - -/**********************************************************************/ -/* * * GENERATING AND POSTSOLVING MODEL * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- alloc_content - allocate content arrays for all model objects. --- --- This routine allocates content arrays for all existing model objects --- and thereby finalizes creating model. --- --- This routine must be called immediately after reading model section, --- i.e. before reading data section or generating model. */ - -void alloc_content(MPL *mpl) -{ STATEMENT *stmt; - /* walk through all model statements */ - for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) - { switch (stmt->type) - { case A_SET: - /* model set */ - xassert(stmt->u.set->array == NULL); - stmt->u.set->array = create_array(mpl, A_ELEMSET, - stmt->u.set->dim); - break; - case A_PARAMETER: - /* model parameter */ - xassert(stmt->u.par->array == NULL); - switch (stmt->u.par->type) - { case A_NUMERIC: - case A_INTEGER: - case A_BINARY: - stmt->u.par->array = create_array(mpl, A_NUMERIC, - stmt->u.par->dim); - break; - case A_SYMBOLIC: - stmt->u.par->array = create_array(mpl, A_SYMBOLIC, - stmt->u.par->dim); - break; - default: - xassert(stmt != stmt); - } - break; - case A_VARIABLE: - /* model variable */ - xassert(stmt->u.var->array == NULL); - stmt->u.var->array = create_array(mpl, A_ELEMVAR, - stmt->u.var->dim); - break; - case A_CONSTRAINT: - /* model constraint/objective */ - xassert(stmt->u.con->array == NULL); - stmt->u.con->array = create_array(mpl, A_ELEMCON, - stmt->u.con->dim); - break; -#if 1 /* 11/II-2008 */ - case A_TABLE: -#endif - case A_SOLVE: - case A_CHECK: - case A_DISPLAY: - case A_PRINTF: - case A_FOR: - /* functional statements have no content array */ - break; - default: - xassert(stmt != stmt); - } - } - return; -} - -/*---------------------------------------------------------------------- --- generate_model - generate model. --- --- This routine executes the model statements which precede the solve --- statement. */ - -void generate_model(MPL *mpl) -{ STATEMENT *stmt; - xassert(!mpl->flag_p); - for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) - { execute_statement(mpl, stmt); - if (mpl->stmt->type == A_SOLVE) break; - } - mpl->stmt = stmt; - return; -} - -/*---------------------------------------------------------------------- --- build_problem - build problem instance. --- --- This routine builds lists of rows and columns for problem instance, --- which corresponds to the generated model. */ - -void build_problem(MPL *mpl) -{ STATEMENT *stmt; - MEMBER *memb; - VARIABLE *v; - CONSTRAINT *c; - FORMULA *t; - int i, j; - xassert(mpl->m == 0); - xassert(mpl->n == 0); - xassert(mpl->row == NULL); - xassert(mpl->col == NULL); - /* check that all elemental variables has zero column numbers */ - for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) - { if (stmt->type == A_VARIABLE) - { v = stmt->u.var; - for (memb = v->array->head; memb != NULL; memb = memb->next) - xassert(memb->value.var->j == 0); - } - } - /* assign row numbers to elemental constraints and objectives */ - for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) - { if (stmt->type == A_CONSTRAINT) - { c = stmt->u.con; - for (memb = c->array->head; memb != NULL; memb = memb->next) - { xassert(memb->value.con->i == 0); - memb->value.con->i = ++mpl->m; - /* walk through linear form and mark elemental variables, - which are referenced at least once */ - for (t = memb->value.con->form; t != NULL; t = t->next) - { xassert(t->var != NULL); - t->var->memb->value.var->j = -1; - } - } - } - } - /* assign column numbers to marked elemental variables */ - for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) - { if (stmt->type == A_VARIABLE) - { v = stmt->u.var; - for (memb = v->array->head; memb != NULL; memb = memb->next) - if (memb->value.var->j != 0) memb->value.var->j = - ++mpl->n; - } - } - /* build list of rows */ - mpl->row = xcalloc(1+mpl->m, sizeof(ELEMCON *)); - for (i = 1; i <= mpl->m; i++) mpl->row[i] = NULL; - for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) - { if (stmt->type == A_CONSTRAINT) - { c = stmt->u.con; - for (memb = c->array->head; memb != NULL; memb = memb->next) - { i = memb->value.con->i; - xassert(1 <= i && i <= mpl->m); - xassert(mpl->row[i] == NULL); - mpl->row[i] = memb->value.con; - } - } - } - for (i = 1; i <= mpl->m; i++) xassert(mpl->row[i] != NULL); - /* build list of columns */ - mpl->col = xcalloc(1+mpl->n, sizeof(ELEMVAR *)); - for (j = 1; j <= mpl->n; j++) mpl->col[j] = NULL; - for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) - { if (stmt->type == A_VARIABLE) - { v = stmt->u.var; - for (memb = v->array->head; memb != NULL; memb = memb->next) - { j = memb->value.var->j; - if (j == 0) continue; - xassert(1 <= j && j <= mpl->n); - xassert(mpl->col[j] == NULL); - mpl->col[j] = memb->value.var; - } - } - } - for (j = 1; j <= mpl->n; j++) xassert(mpl->col[j] != NULL); - return; -} - -/*---------------------------------------------------------------------- --- postsolve_model - postsolve model. --- --- This routine executes the model statements which follow the solve --- statement. */ - -void postsolve_model(MPL *mpl) -{ STATEMENT *stmt; - xassert(!mpl->flag_p); - mpl->flag_p = 1; - for (stmt = mpl->stmt; stmt != NULL; stmt = stmt->next) - execute_statement(mpl, stmt); - mpl->stmt = NULL; - return; -} - -/*---------------------------------------------------------------------- --- clean_model - clean model content. --- --- This routine cleans the model content that assumes deleting all stuff --- dynamically allocated on generating/postsolving phase. --- --- Actually cleaning model content is not needed. This function is used --- mainly to be sure that there were no logical errors on using dynamic --- memory pools during the generation phase. --- --- NOTE: This routine must not be called if any errors were detected on --- the generation phase. */ - -void clean_model(MPL *mpl) -{ STATEMENT *stmt; - for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) - clean_statement(mpl, stmt); - /* check that all atoms have been returned to their pools */ - if (dmp_in_use(mpl->strings) != 0) - error(mpl, "internal logic error: %d string segment(s) were lo" - "st", dmp_in_use(mpl->strings)); - if (dmp_in_use(mpl->symbols) != 0) - error(mpl, "internal logic error: %d symbol(s) were lost", - dmp_in_use(mpl->symbols)); - if (dmp_in_use(mpl->tuples) != 0) - error(mpl, "internal logic error: %d n-tuple component(s) were" - " lost", dmp_in_use(mpl->tuples)); - if (dmp_in_use(mpl->arrays) != 0) - error(mpl, "internal logic error: %d array(s) were lost", - dmp_in_use(mpl->arrays)); - if (dmp_in_use(mpl->members) != 0) - error(mpl, "internal logic error: %d array member(s) were lost" - , dmp_in_use(mpl->members)); - if (dmp_in_use(mpl->elemvars) != 0) - error(mpl, "internal logic error: %d elemental variable(s) wer" - "e lost", dmp_in_use(mpl->elemvars)); - if (dmp_in_use(mpl->formulae) != 0) - error(mpl, "internal logic error: %d linear term(s) were lost", - dmp_in_use(mpl->formulae)); - if (dmp_in_use(mpl->elemcons) != 0) - error(mpl, "internal logic error: %d elemental constraint(s) w" - "ere lost", dmp_in_use(mpl->elemcons)); - return; -} - -/**********************************************************************/ -/* * * INPUT/OUTPUT * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- open_input - open input text file. --- --- This routine opens the input text file for scanning. */ - -void open_input(MPL *mpl, char *file) -{ mpl->line = 0; - mpl->c = '\n'; - mpl->token = 0; - mpl->imlen = 0; - mpl->image[0] = '\0'; - mpl->value = 0.0; - mpl->b_token = T_EOF; - mpl->b_imlen = 0; - mpl->b_image[0] = '\0'; - mpl->b_value = 0.0; - mpl->f_dots = 0; - mpl->f_scan = 0; - mpl->f_token = 0; - mpl->f_imlen = 0; - mpl->f_image[0] = '\0'; - mpl->f_value = 0.0; - memset(mpl->context, ' ', CONTEXT_SIZE); - mpl->c_ptr = 0; - xassert(mpl->in_fp == NULL); - mpl->in_fp = glp_open(file, "r"); - if (mpl->in_fp == NULL) - error(mpl, "unable to open %s - %s", file, get_err_msg()); - mpl->in_file = file; - /* scan the very first character */ - get_char(mpl); - /* scan the very first token */ - get_token(mpl); - return; -} - -/*---------------------------------------------------------------------- --- read_char - read next character from input text file. --- --- This routine returns a next ASCII character read from the input text --- file. If the end of file has been reached, EOF is returned. */ - -int read_char(MPL *mpl) -{ int c; - xassert(mpl->in_fp != NULL); - c = glp_getc(mpl->in_fp); - if (c < 0) - { if (glp_ioerr(mpl->in_fp)) - error(mpl, "read error on %s - %s", mpl->in_file, - get_err_msg()); - c = EOF; - } - return c; -} - -/*---------------------------------------------------------------------- --- close_input - close input text file. --- --- This routine closes the input text file. */ - -void close_input(MPL *mpl) -{ xassert(mpl->in_fp != NULL); - glp_close(mpl->in_fp); - mpl->in_fp = NULL; - mpl->in_file = NULL; - return; -} - -/*---------------------------------------------------------------------- --- open_output - open output text file. --- --- This routine opens the output text file for writing data produced by --- display and printf statements. */ - -void open_output(MPL *mpl, char *file) -{ xassert(mpl->out_fp == NULL); - if (file == NULL) - { file = ""; - mpl->out_fp = (void *)stdout; - } - else - { mpl->out_fp = glp_open(file, "w"); - if (mpl->out_fp == NULL) - error(mpl, "unable to create %s - %s", file, get_err_msg()); - } - mpl->out_file = xmalloc(strlen(file)+1); - strcpy(mpl->out_file, file); - return; -} - -/*---------------------------------------------------------------------- --- write_char - write next character to output text file. --- --- This routine writes an ASCII character to the output text file. */ - -void write_char(MPL *mpl, int c) -{ xassert(mpl->out_fp != NULL); - if (mpl->out_fp == (void *)stdout) - xprintf("%c", c); - else - xfprintf(mpl->out_fp, "%c", c); - return; -} - -/*---------------------------------------------------------------------- --- write_text - format and write text to output text file. --- --- This routine formats a text using the format control string and then --- writes this text to the output text file. */ - -void write_text(MPL *mpl, char *fmt, ...) -{ va_list arg; - char buf[OUTBUF_SIZE], *c; - va_start(arg, fmt); - vsprintf(buf, fmt, arg); - xassert(strlen(buf) < sizeof(buf)); - va_end(arg); - for (c = buf; *c != '\0'; c++) write_char(mpl, *c); - return; -} - -/*---------------------------------------------------------------------- --- flush_output - finalize writing data to output text file. --- --- This routine finalizes writing data to the output text file. */ - -void flush_output(MPL *mpl) -{ xassert(mpl->out_fp != NULL); - if (mpl->out_fp != (void *)stdout) - { -#if 0 /* FIXME */ - xfflush(mpl->out_fp); -#endif - if (glp_ioerr(mpl->out_fp)) - error(mpl, "write error on %s - %s", mpl->out_file, - get_err_msg()); - } - return; -} - -/**********************************************************************/ -/* * * SOLVER INTERFACE * * */ -/**********************************************************************/ - -/*---------------------------------------------------------------------- --- error - print error message and terminate model processing. --- --- This routine formats and prints an error message and then terminates --- model processing. */ - -void error(MPL *mpl, char *fmt, ...) -{ va_list arg; - char msg[4095+1]; - va_start(arg, fmt); - vsprintf(msg, fmt, arg); - xassert(strlen(msg) < sizeof(msg)); - va_end(arg); - switch (mpl->phase) - { case 1: - case 2: - /* translation phase */ - xprintf("%s:%d: %s\n", - mpl->in_file == NULL ? "(unknown)" : mpl->in_file, - mpl->line, msg); - print_context(mpl); - break; - case 3: - /* generation/postsolve phase */ - xprintf("%s:%d: %s\n", - mpl->mod_file == NULL ? "(unknown)" : mpl->mod_file, - mpl->stmt == NULL ? 0 : mpl->stmt->line, msg); - break; - default: - xassert(mpl != mpl); - } - mpl->phase = 4; - longjmp(mpl->jump, 1); - /* no return */ -} - -/*---------------------------------------------------------------------- --- warning - print warning message and continue model processing. --- --- This routine formats and prints a warning message and returns to the --- calling program. */ - -void warning(MPL *mpl, char *fmt, ...) -{ va_list arg; - char msg[4095+1]; - va_start(arg, fmt); - vsprintf(msg, fmt, arg); - xassert(strlen(msg) < sizeof(msg)); - va_end(arg); - switch (mpl->phase) - { case 1: - case 2: - /* translation phase */ - xprintf("%s:%d: warning: %s\n", - mpl->in_file == NULL ? "(unknown)" : mpl->in_file, - mpl->line, msg); - break; - case 3: - /* generation/postsolve phase */ - xprintf("%s:%d: warning: %s\n", - mpl->mod_file == NULL ? "(unknown)" : mpl->mod_file, - mpl->stmt == NULL ? 0 : mpl->stmt->line, msg); - break; - default: - xassert(mpl != mpl); - } - return; -} - -/*---------------------------------------------------------------------- --- mpl_initialize - create and initialize translator database. --- --- *Synopsis* --- --- #include "glpmpl.h" --- MPL *mpl_initialize(void); --- --- *Description* --- --- The routine mpl_initialize creates and initializes the database used --- by the GNU MathProg translator. --- --- *Returns* --- --- The routine returns a pointer to the database created. */ - -MPL *mpl_initialize(void) -{ MPL *mpl; - mpl = xmalloc(sizeof(MPL)); - /* scanning segment */ - mpl->line = 0; - mpl->c = 0; - mpl->token = 0; - mpl->imlen = 0; - mpl->image = xcalloc(MAX_LENGTH+1, sizeof(char)); - mpl->image[0] = '\0'; - mpl->value = 0.0; - mpl->b_token = 0; - mpl->b_imlen = 0; - mpl->b_image = xcalloc(MAX_LENGTH+1, sizeof(char)); - mpl->b_image[0] = '\0'; - mpl->b_value = 0.0; - mpl->f_dots = 0; - mpl->f_scan = 0; - mpl->f_token = 0; - mpl->f_imlen = 0; - mpl->f_image = xcalloc(MAX_LENGTH+1, sizeof(char)); - mpl->f_image[0] = '\0'; - mpl->f_value = 0.0; - mpl->context = xcalloc(CONTEXT_SIZE, sizeof(char)); - memset(mpl->context, ' ', CONTEXT_SIZE); - mpl->c_ptr = 0; - mpl->flag_d = 0; - /* translating segment */ - mpl->pool = dmp_create_poolx(0); - mpl->tree = avl_create_tree(avl_strcmp, NULL); - mpl->model = NULL; - mpl->flag_x = 0; - mpl->as_within = 0; - mpl->as_in = 0; - mpl->as_binary = 0; - mpl->flag_s = 0; - /* common segment */ - mpl->strings = dmp_create_poolx(sizeof(STRING)); - mpl->symbols = dmp_create_poolx(sizeof(SYMBOL)); - mpl->tuples = dmp_create_poolx(sizeof(TUPLE)); - mpl->arrays = dmp_create_poolx(sizeof(ARRAY)); - mpl->members = dmp_create_poolx(sizeof(MEMBER)); - mpl->elemvars = dmp_create_poolx(sizeof(ELEMVAR)); - mpl->formulae = dmp_create_poolx(sizeof(FORMULA)); - mpl->elemcons = dmp_create_poolx(sizeof(ELEMCON)); - mpl->a_list = NULL; - mpl->sym_buf = xcalloc(255+1, sizeof(char)); - mpl->sym_buf[0] = '\0'; - mpl->tup_buf = xcalloc(255+1, sizeof(char)); - mpl->tup_buf[0] = '\0'; - /* generating/postsolving segment */ - mpl->rand = rng_create_rand(); - mpl->flag_p = 0; - mpl->stmt = NULL; -#if 1 /* 11/II-2008 */ - mpl->dca = NULL; -#endif - mpl->m = 0; - mpl->n = 0; - mpl->row = NULL; - mpl->col = NULL; - /* input/output segment */ - mpl->in_fp = NULL; - mpl->in_file = NULL; - mpl->out_fp = NULL; - mpl->out_file = NULL; - mpl->prt_fp = NULL; - mpl->prt_file = NULL; - /* solver interface segment */ - if (setjmp(mpl->jump)) xassert(mpl != mpl); - mpl->phase = 0; - mpl->mod_file = NULL; - mpl->mpl_buf = xcalloc(255+1, sizeof(char)); - mpl->mpl_buf[0] = '\0'; - return mpl; -} - -/*---------------------------------------------------------------------- --- mpl_read_model - read model section and optional data section. --- --- *Synopsis* --- --- #include "glpmpl.h" --- int mpl_read_model(MPL *mpl, char *file, int skip_data); --- --- *Description* --- --- The routine mpl_read_model reads model section and optionally data --- section, which may follow the model section, from the text file, --- whose name is the character string file, performs translating model --- statements and data blocks, and stores all the information in the --- translator database. --- --- The parameter skip_data is a flag. If the input file contains the --- data section and this flag is set, the data section is not read as --- if there were no data section and a warning message is issued. This --- allows reading the data section from another input file. --- --- This routine should be called once after the routine mpl_initialize --- and before other API routines. --- --- *Returns* --- --- The routine mpl_read_model returns one the following codes: --- --- 1 - translation successful. The input text file contains only model --- section. In this case the calling program may call the routine --- mpl_read_data to read data section from another file. --- 2 - translation successful. The input text file contains both model --- and data section. --- 4 - processing failed due to some errors. In this case the calling --- program should call the routine mpl_terminate to terminate model --- processing. */ - -int mpl_read_model(MPL *mpl, char *file, int skip_data) -{ if (mpl->phase != 0) - xfault("mpl_read_model: invalid call sequence\n"); - if (file == NULL) - xfault("mpl_read_model: no input filename specified\n"); - /* set up error handler */ - if (setjmp(mpl->jump)) goto done; - /* translate model section */ - mpl->phase = 1; - xprintf("Reading model section from %s...\n", file); - open_input(mpl, file); - model_section(mpl); - if (mpl->model == NULL) - error(mpl, "empty model section not allowed"); - /* save name of the input text file containing model section for - error diagnostics during the generation phase */ - mpl->mod_file = xcalloc(strlen(file)+1, sizeof(char)); - strcpy(mpl->mod_file, mpl->in_file); - /* allocate content arrays for all model objects */ - alloc_content(mpl); - /* optional data section may begin with the keyword 'data' */ - if (is_keyword(mpl, "data")) - { if (skip_data) - { warning(mpl, "data section ignored"); - goto skip; - } - mpl->flag_d = 1; - get_token(mpl /* data */); - if (mpl->token != T_SEMICOLON) - error(mpl, "semicolon missing where expected"); - get_token(mpl /* ; */); - /* translate data section */ - mpl->phase = 2; - xprintf("Reading data section from %s...\n", file); - data_section(mpl); - } - /* process end statement */ - end_statement(mpl); -skip: xprintf("%d line%s were read\n", - mpl->line, mpl->line == 1 ? "" : "s"); - close_input(mpl); -done: /* return to the calling program */ - return mpl->phase; -} - -/*---------------------------------------------------------------------- --- mpl_read_data - read data section. --- --- *Synopsis* --- --- #include "glpmpl.h" --- int mpl_read_data(MPL *mpl, char *file); --- --- *Description* --- --- The routine mpl_read_data reads data section from the text file, --- whose name is the character string file, performs translating data --- blocks, and stores the data read in the translator database. --- --- If this routine is used, it should be called once after the routine --- mpl_read_model and if the latter returned the code 1. --- --- *Returns* --- --- The routine mpl_read_data returns one of the following codes: --- --- 2 - data section has been successfully processed. --- 4 - processing failed due to some errors. In this case the calling --- program should call the routine mpl_terminate to terminate model --- processing. */ - -int mpl_read_data(MPL *mpl, char *file) -#if 0 /* 02/X-2008 */ -{ if (mpl->phase != 1) -#else -{ if (!(mpl->phase == 1 || mpl->phase == 2)) -#endif - xfault("mpl_read_data: invalid call sequence\n"); - if (file == NULL) - xfault("mpl_read_data: no input filename specified\n"); - /* set up error handler */ - if (setjmp(mpl->jump)) goto done; - /* process data section */ - mpl->phase = 2; - xprintf("Reading data section from %s...\n", file); - mpl->flag_d = 1; - open_input(mpl, file); - /* in this case the keyword 'data' is optional */ - if (is_literal(mpl, "data")) - { get_token(mpl /* data */); - if (mpl->token != T_SEMICOLON) - error(mpl, "semicolon missing where expected"); - get_token(mpl /* ; */); - } - data_section(mpl); - /* process end statement */ - end_statement(mpl); - xprintf("%d line%s were read\n", - mpl->line, mpl->line == 1 ? "" : "s"); - close_input(mpl); -done: /* return to the calling program */ - return mpl->phase; -} - -/*---------------------------------------------------------------------- --- mpl_generate - generate model. --- --- *Synopsis* --- --- #include "glpmpl.h" --- int mpl_generate(MPL *mpl, char *file); --- --- *Description* --- --- The routine mpl_generate generates the model using its description --- stored in the translator database. This phase means generating all --- variables, constraints, and objectives, executing check and display --- statements, which precede the solve statement (if it is presented), --- and building the problem instance. --- --- The character string file specifies the name of output text file, to --- which output produced by display statements should be written. It is --- allowed to specify NULL, in which case the output goes to stdout via --- the routine print. --- --- This routine should be called once after the routine mpl_read_model --- or mpl_read_data and if one of the latters returned the code 2. --- --- *Returns* --- --- The routine mpl_generate returns one of the following codes: --- --- 3 - model has been successfully generated. In this case the calling --- program may call other api routines to obtain components of the --- problem instance from the translator database. --- 4 - processing failed due to some errors. In this case the calling --- program should call the routine mpl_terminate to terminate model --- processing. */ - -int mpl_generate(MPL *mpl, char *file) -{ if (!(mpl->phase == 1 || mpl->phase == 2)) - xfault("mpl_generate: invalid call sequence\n"); - /* set up error handler */ - if (setjmp(mpl->jump)) goto done; - /* generate model */ - mpl->phase = 3; - open_output(mpl, file); - generate_model(mpl); - flush_output(mpl); - /* build problem instance */ - build_problem(mpl); - /* generation phase has been finished */ - xprintf("Model has been successfully generated\n"); -done: /* return to the calling program */ - return mpl->phase; -} - -/*---------------------------------------------------------------------- --- mpl_get_prob_name - obtain problem (model) name. --- --- *Synopsis* --- --- #include "glpmpl.h" --- char *mpl_get_prob_name(MPL *mpl); --- --- *Returns* --- --- The routine mpl_get_prob_name returns a pointer to internal buffer, --- which contains symbolic name of the problem (model). --- --- *Note* --- --- Currently MathProg has no feature to assign a symbolic name to the --- model. Therefore the routine mpl_get_prob_name tries to construct --- such name using the name of input text file containing model section, --- although this is not a good idea (due to portability problems). */ - -char *mpl_get_prob_name(MPL *mpl) -{ char *name = mpl->mpl_buf; - char *file = mpl->mod_file; - int k; - if (mpl->phase != 3) - xfault("mpl_get_prob_name: invalid call sequence\n"); - for (;;) - { if (strchr(file, '/') != NULL) - file = strchr(file, '/') + 1; - else if (strchr(file, '\\') != NULL) - file = strchr(file, '\\') + 1; - else if (strchr(file, ':') != NULL) - file = strchr(file, ':') + 1; - else - break; - } - for (k = 0; ; k++) - { if (k == 255) break; - if (!(isalnum((unsigned char)*file) || *file == '_')) break; - name[k] = *file++; - } - if (k == 0) - strcpy(name, "Unknown"); - else - name[k] = '\0'; - xassert(strlen(name) <= 255); - return name; -} - -/*---------------------------------------------------------------------- --- mpl_get_num_rows - determine number of rows. --- --- *Synopsis* --- --- #include "glpmpl.h" --- int mpl_get_num_rows(MPL *mpl); --- --- *Returns* --- --- The routine mpl_get_num_rows returns total number of rows in the --- problem, where each row is an individual constraint or objective. */ - -int mpl_get_num_rows(MPL *mpl) -{ if (mpl->phase != 3) - xfault("mpl_get_num_rows: invalid call sequence\n"); - return mpl->m; -} - -/*---------------------------------------------------------------------- --- mpl_get_num_cols - determine number of columns. --- --- *Synopsis* --- --- #include "glpmpl.h" --- int mpl_get_num_cols(MPL *mpl); --- --- *Returns* --- --- The routine mpl_get_num_cols returns total number of columns in the --- problem, where each column is an individual variable. */ - -int mpl_get_num_cols(MPL *mpl) -{ if (mpl->phase != 3) - xfault("mpl_get_num_cols: invalid call sequence\n"); - return mpl->n; -} - -/*---------------------------------------------------------------------- --- mpl_get_row_name - obtain row name. --- --- *Synopsis* --- --- #include "glpmpl.h" --- char *mpl_get_row_name(MPL *mpl, int i); --- --- *Returns* --- --- The routine mpl_get_row_name returns a pointer to internal buffer, --- which contains symbolic name of i-th row of the problem. */ - -char *mpl_get_row_name(MPL *mpl, int i) -{ char *name = mpl->mpl_buf, *t; - int len; - if (mpl->phase != 3) - xfault("mpl_get_row_name: invalid call sequence\n"); - if (!(1 <= i && i <= mpl->m)) - xfault("mpl_get_row_name: i = %d; row number out of range\n", - i); - strcpy(name, mpl->row[i]->con->name); - len = strlen(name); - xassert(len <= 255); - t = format_tuple(mpl, '[', mpl->row[i]->memb->tuple); - while (*t) - { if (len == 255) break; - name[len++] = *t++; - } - name[len] = '\0'; - if (len == 255) strcpy(name+252, "..."); - xassert(strlen(name) <= 255); - return name; -} - -/*---------------------------------------------------------------------- --- mpl_get_row_kind - determine row kind. --- --- *Synopsis* --- --- #include "glpmpl.h" --- int mpl_get_row_kind(MPL *mpl, int i); --- --- *Returns* --- --- The routine mpl_get_row_kind returns the kind of i-th row, which can --- be one of the following: --- --- MPL_ST - non-free (constraint) row; --- MPL_MIN - free (objective) row to be minimized; --- MPL_MAX - free (objective) row to be maximized. */ - -int mpl_get_row_kind(MPL *mpl, int i) -{ int kind; - if (mpl->phase != 3) - xfault("mpl_get_row_kind: invalid call sequence\n"); - if (!(1 <= i && i <= mpl->m)) - xfault("mpl_get_row_kind: i = %d; row number out of range\n", - i); - switch (mpl->row[i]->con->type) - { case A_CONSTRAINT: - kind = MPL_ST; break; - case A_MINIMIZE: - kind = MPL_MIN; break; - case A_MAXIMIZE: - kind = MPL_MAX; break; - default: - xassert(mpl != mpl); - } - return kind; -} - -/*---------------------------------------------------------------------- --- mpl_get_row_bnds - obtain row bounds. --- --- *Synopsis* --- --- #include "glpmpl.h" --- int mpl_get_row_bnds(MPL *mpl, int i, double *lb, double *ub); --- --- *Description* --- --- The routine mpl_get_row_bnds stores lower and upper bounds of i-th --- row of the problem to the locations, which the parameters lb and ub --- point to, respectively. Besides the routine returns the type of the --- i-th row. --- --- If some of the parameters lb and ub is NULL, the corresponding bound --- value is not stored. --- --- Types and bounds have the following meaning: --- --- Type Bounds Note --- ----------------------------------------------------------- --- MPL_FR -inf < f(x) < +inf Free linear form --- MPL_LO lb <= f(x) < +inf Inequality f(x) >= lb --- MPL_UP -inf < f(x) <= ub Inequality f(x) <= ub --- MPL_DB lb <= f(x) <= ub Inequality lb <= f(x) <= ub --- MPL_FX f(x) = lb Equality f(x) = lb --- --- where f(x) is the corresponding linear form of the i-th row. --- --- If the row has no lower bound, *lb is set to zero; if the row has --- no upper bound, *ub is set to zero; and if the row is of fixed type, --- both *lb and *ub are set to the same value. --- --- *Returns* --- --- The routine returns the type of the i-th row as it is stated in the --- table above. */ - -int mpl_get_row_bnds(MPL *mpl, int i, double *_lb, double *_ub) -{ ELEMCON *con; - int type; - double lb, ub; - if (mpl->phase != 3) - xfault("mpl_get_row_bnds: invalid call sequence\n"); - if (!(1 <= i && i <= mpl->m)) - xfault("mpl_get_row_bnds: i = %d; row number out of range\n", - i); - con = mpl->row[i]; -#if 0 /* 21/VII-2006 */ - if (con->con->lbnd == NULL && con->con->ubnd == NULL) - type = MPL_FR, lb = ub = 0.0; - else if (con->con->ubnd == NULL) - type = MPL_LO, lb = con->lbnd, ub = 0.0; - else if (con->con->lbnd == NULL) - type = MPL_UP, lb = 0.0, ub = con->ubnd; - else if (con->con->lbnd != con->con->ubnd) - type = MPL_DB, lb = con->lbnd, ub = con->ubnd; - else - type = MPL_FX, lb = ub = con->lbnd; -#else - lb = (con->con->lbnd == NULL ? -DBL_MAX : con->lbnd); - ub = (con->con->ubnd == NULL ? +DBL_MAX : con->ubnd); - if (lb == -DBL_MAX && ub == +DBL_MAX) - type = MPL_FR, lb = ub = 0.0; - else if (ub == +DBL_MAX) - type = MPL_LO, ub = 0.0; - else if (lb == -DBL_MAX) - type = MPL_UP, lb = 0.0; - else if (con->con->lbnd != con->con->ubnd) - type = MPL_DB; - else - type = MPL_FX; -#endif - if (_lb != NULL) *_lb = lb; - if (_ub != NULL) *_ub = ub; - return type; -} - -/*---------------------------------------------------------------------- --- mpl_get_mat_row - obtain row of the constraint matrix. --- --- *Synopsis* --- --- #include "glpmpl.h" --- int mpl_get_mat_row(MPL *mpl, int i, int ndx[], double val[]); --- --- *Description* --- --- The routine mpl_get_mat_row stores column indices and numeric values --- of constraint coefficients for the i-th row to locations ndx[1], ..., --- ndx[len] and val[1], ..., val[len], respectively, where 0 <= len <= n --- is number of (structural) non-zero constraint coefficients, and n is --- number of columns in the problem. --- --- If the parameter ndx is NULL, column indices are not stored. If the --- parameter val is NULL, numeric values are not stored. --- --- Note that free rows may have constant terms, which are not part of --- the constraint matrix and therefore not reported by this routine. The --- constant term of a particular row can be obtained, if necessary, via --- the routine mpl_get_row_c0. --- --- *Returns* --- --- The routine mpl_get_mat_row returns len, which is length of i-th row --- of the constraint matrix (i.e. number of non-zero coefficients). */ - -int mpl_get_mat_row(MPL *mpl, int i, int ndx[], double val[]) -{ FORMULA *term; - int len = 0; - if (mpl->phase != 3) - xfault("mpl_get_mat_row: invalid call sequence\n"); - if (!(1 <= i && i <= mpl->m)) - xfault("mpl_get_mat_row: i = %d; row number out of range\n", - i); - for (term = mpl->row[i]->form; term != NULL; term = term->next) - { xassert(term->var != NULL); - len++; - xassert(len <= mpl->n); - if (ndx != NULL) ndx[len] = term->var->j; - if (val != NULL) val[len] = term->coef; - } - return len; -} - -/*---------------------------------------------------------------------- --- mpl_get_row_c0 - obtain constant term of free row. --- --- *Synopsis* --- --- #include "glpmpl.h" --- double mpl_get_row_c0(MPL *mpl, int i); --- --- *Returns* --- --- The routine mpl_get_row_c0 returns numeric value of constant term of --- i-th row. --- --- Note that only free rows may have non-zero constant terms. Therefore --- if i-th row is not free, the routine returns zero. */ - -double mpl_get_row_c0(MPL *mpl, int i) -{ ELEMCON *con; - double c0; - if (mpl->phase != 3) - xfault("mpl_get_row_c0: invalid call sequence\n"); - if (!(1 <= i && i <= mpl->m)) - xfault("mpl_get_row_c0: i = %d; row number out of range\n", - i); - con = mpl->row[i]; - if (con->con->lbnd == NULL && con->con->ubnd == NULL) - c0 = - con->lbnd; - else - c0 = 0.0; - return c0; -} - -/*---------------------------------------------------------------------- --- mpl_get_col_name - obtain column name. --- --- *Synopsis* --- --- #include "glpmpl.h" --- char *mpl_get_col_name(MPL *mpl, int j); --- --- *Returns* --- --- The routine mpl_get_col_name returns a pointer to internal buffer, --- which contains symbolic name of j-th column of the problem. */ - -char *mpl_get_col_name(MPL *mpl, int j) -{ char *name = mpl->mpl_buf, *t; - int len; - if (mpl->phase != 3) - xfault("mpl_get_col_name: invalid call sequence\n"); - if (!(1 <= j && j <= mpl->n)) - xfault("mpl_get_col_name: j = %d; column number out of range\n" - , j); - strcpy(name, mpl->col[j]->var->name); - len = strlen(name); - xassert(len <= 255); - t = format_tuple(mpl, '[', mpl->col[j]->memb->tuple); - while (*t) - { if (len == 255) break; - name[len++] = *t++; - } - name[len] = '\0'; - if (len == 255) strcpy(name+252, "..."); - xassert(strlen(name) <= 255); - return name; -} - -/*---------------------------------------------------------------------- --- mpl_get_col_kind - determine column kind. --- --- *Synopsis* --- --- #include "glpmpl.h" --- int mpl_get_col_kind(MPL *mpl, int j); --- --- *Returns* --- --- The routine mpl_get_col_kind returns the kind of j-th column, which --- can be one of the following: --- --- MPL_NUM - continuous variable; --- MPL_INT - integer variable; --- MPL_BIN - binary variable. --- --- Note that column kinds are defined independently on type and bounds --- (reported by the routine mpl_get_col_bnds) of corresponding columns. --- This means, in particular, that bounds of an integer column may be --- fractional, or a binary column may have lower and upper bounds that --- are not 0 and 1 (or it may have no lower/upper bound at all). */ - -int mpl_get_col_kind(MPL *mpl, int j) -{ int kind; - if (mpl->phase != 3) - xfault("mpl_get_col_kind: invalid call sequence\n"); - if (!(1 <= j && j <= mpl->n)) - xfault("mpl_get_col_kind: j = %d; column number out of range\n" - , j); - switch (mpl->col[j]->var->type) - { case A_NUMERIC: - kind = MPL_NUM; break; - case A_INTEGER: - kind = MPL_INT; break; - case A_BINARY: - kind = MPL_BIN; break; - default: - xassert(mpl != mpl); - } - return kind; -} - -/*---------------------------------------------------------------------- --- mpl_get_col_bnds - obtain column bounds. --- --- *Synopsis* --- --- #include "glpmpl.h" --- int mpl_get_col_bnds(MPL *mpl, int j, double *lb, double *ub); --- --- *Description* --- --- The routine mpl_get_col_bnds stores lower and upper bound of j-th --- column of the problem to the locations, which the parameters lb and --- ub point to, respectively. Besides the routine returns the type of --- the j-th column. --- --- If some of the parameters lb and ub is NULL, the corresponding bound --- value is not stored. --- --- Types and bounds have the following meaning: --- --- Type Bounds Note --- ------------------------------------------------------ --- MPL_FR -inf < x < +inf Free (unbounded) variable --- MPL_LO lb <= x < +inf Variable with lower bound --- MPL_UP -inf < x <= ub Variable with upper bound --- MPL_DB lb <= x <= ub Double-bounded variable --- MPL_FX x = lb Fixed variable --- --- where x is individual variable corresponding to the j-th column. --- --- If the column has no lower bound, *lb is set to zero; if the column --- has no upper bound, *ub is set to zero; and if the column is of fixed --- type, both *lb and *ub are set to the same value. --- --- *Returns* --- --- The routine returns the type of the j-th column as it is stated in --- the table above. */ - -int mpl_get_col_bnds(MPL *mpl, int j, double *_lb, double *_ub) -{ ELEMVAR *var; - int type; - double lb, ub; - if (mpl->phase != 3) - xfault("mpl_get_col_bnds: invalid call sequence\n"); - if (!(1 <= j && j <= mpl->n)) - xfault("mpl_get_col_bnds: j = %d; column number out of range\n" - , j); - var = mpl->col[j]; -#if 0 /* 21/VII-2006 */ - if (var->var->lbnd == NULL && var->var->ubnd == NULL) - type = MPL_FR, lb = ub = 0.0; - else if (var->var->ubnd == NULL) - type = MPL_LO, lb = var->lbnd, ub = 0.0; - else if (var->var->lbnd == NULL) - type = MPL_UP, lb = 0.0, ub = var->ubnd; - else if (var->var->lbnd != var->var->ubnd) - type = MPL_DB, lb = var->lbnd, ub = var->ubnd; - else - type = MPL_FX, lb = ub = var->lbnd; -#else - lb = (var->var->lbnd == NULL ? -DBL_MAX : var->lbnd); - ub = (var->var->ubnd == NULL ? +DBL_MAX : var->ubnd); - if (lb == -DBL_MAX && ub == +DBL_MAX) - type = MPL_FR, lb = ub = 0.0; - else if (ub == +DBL_MAX) - type = MPL_LO, ub = 0.0; - else if (lb == -DBL_MAX) - type = MPL_UP, lb = 0.0; - else if (var->var->lbnd != var->var->ubnd) - type = MPL_DB; - else - type = MPL_FX; -#endif - if (_lb != NULL) *_lb = lb; - if (_ub != NULL) *_ub = ub; - return type; -} - -/*---------------------------------------------------------------------- --- mpl_has_solve_stmt - check if model has solve statement. --- --- *Synopsis* --- --- #include "glpmpl.h" --- int mpl_has_solve_stmt(MPL *mpl); --- --- *Returns* --- --- If the model has the solve statement, the routine returns non-zero, --- otherwise zero is returned. */ - -int mpl_has_solve_stmt(MPL *mpl) -{ if (mpl->phase != 3) - xfault("mpl_has_solve_stmt: invalid call sequence\n"); - return mpl->flag_s; -} - -#if 1 /* 15/V-2010 */ -void mpl_put_row_soln(MPL *mpl, int i, int stat, double prim, - double dual) -{ /* store row (constraint/objective) solution components */ - xassert(mpl->phase == 3); - xassert(1 <= i && i <= mpl->m); - mpl->row[i]->stat = stat; - mpl->row[i]->prim = prim; - mpl->row[i]->dual = dual; - return; -} -#endif - -#if 1 /* 15/V-2010 */ -void mpl_put_col_soln(MPL *mpl, int j, int stat, double prim, - double dual) -{ /* store column (variable) solution components */ - xassert(mpl->phase == 3); - xassert(1 <= j && j <= mpl->n); - mpl->col[j]->stat = stat; - mpl->col[j]->prim = prim; - mpl->col[j]->dual = dual; - return; -} -#endif - -#if 0 /* 15/V-2010 */ -/*---------------------------------------------------------------------- --- mpl_put_col_value - store column value. --- --- *Synopsis* --- --- #include "glpmpl.h" --- void mpl_put_col_value(MPL *mpl, int j, double val); --- --- *Description* --- --- The routine mpl_put_col_value stores numeric value of j-th column --- into the translator database. It is assumed that the column value is --- provided by the solver. */ - -void mpl_put_col_value(MPL *mpl, int j, double val) -{ if (mpl->phase != 3) - xfault("mpl_put_col_value: invalid call sequence\n"); - if (!(1 <= j && j <= mpl->n)) - xfault( - "mpl_put_col_value: j = %d; column number out of range\n", j); - mpl->col[j]->prim = val; - return; -} -#endif - -/*---------------------------------------------------------------------- --- mpl_postsolve - postsolve model. --- --- *Synopsis* --- --- #include "glpmpl.h" --- int mpl_postsolve(MPL *mpl); --- --- *Description* --- --- The routine mpl_postsolve performs postsolving of the model using --- its description stored in the translator database. This phase means --- executing statements, which follow the solve statement. --- --- If this routine is used, it should be called once after the routine --- mpl_generate and if the latter returned the code 3. --- --- *Returns* --- --- The routine mpl_postsolve returns one of the following codes: --- --- 3 - model has been successfully postsolved. --- 4 - processing failed due to some errors. In this case the calling --- program should call the routine mpl_terminate to terminate model --- processing. */ - -int mpl_postsolve(MPL *mpl) -{ if (!(mpl->phase == 3 && !mpl->flag_p)) - xfault("mpl_postsolve: invalid call sequence\n"); - /* set up error handler */ - if (setjmp(mpl->jump)) goto done; - /* perform postsolving */ - postsolve_model(mpl); - flush_output(mpl); - /* postsolving phase has been finished */ - xprintf("Model has been successfully processed\n"); -done: /* return to the calling program */ - return mpl->phase; -} - -/*---------------------------------------------------------------------- --- mpl_terminate - free all resources used by translator. --- --- *Synopsis* --- --- #include "glpmpl.h" --- void mpl_terminate(MPL *mpl); --- --- *Description* --- --- The routine mpl_terminate frees all the resources used by the GNU --- MathProg translator. */ - -void mpl_terminate(MPL *mpl) -{ if (setjmp(mpl->jump)) xassert(mpl != mpl); - switch (mpl->phase) - { case 0: - case 1: - case 2: - case 3: - /* there were no errors; clean the model content */ - clean_model(mpl); - xassert(mpl->a_list == NULL); -#if 1 /* 11/II-2008 */ - xassert(mpl->dca == NULL); -#endif - break; - case 4: - /* model processing has been finished due to error; delete - search trees, which may be created for some arrays */ - { ARRAY *a; - for (a = mpl->a_list; a != NULL; a = a->next) - if (a->tree != NULL) avl_delete_tree(a->tree); - } -#if 1 /* 11/II-2008 */ - free_dca(mpl); -#endif - break; - default: - xassert(mpl != mpl); - } - /* delete the translator database */ - xfree(mpl->image); - xfree(mpl->b_image); - xfree(mpl->f_image); - xfree(mpl->context); - dmp_delete_pool(mpl->pool); - avl_delete_tree(mpl->tree); - dmp_delete_pool(mpl->strings); - dmp_delete_pool(mpl->symbols); - dmp_delete_pool(mpl->tuples); - dmp_delete_pool(mpl->arrays); - dmp_delete_pool(mpl->members); - dmp_delete_pool(mpl->elemvars); - dmp_delete_pool(mpl->formulae); - dmp_delete_pool(mpl->elemcons); - xfree(mpl->sym_buf); - xfree(mpl->tup_buf); - rng_delete_rand(mpl->rand); - if (mpl->row != NULL) xfree(mpl->row); - if (mpl->col != NULL) xfree(mpl->col); - if (mpl->in_fp != NULL) glp_close(mpl->in_fp); - if (mpl->out_fp != NULL && mpl->out_fp != (void *)stdout) - glp_close(mpl->out_fp); - if (mpl->out_file != NULL) xfree(mpl->out_file); - if (mpl->prt_fp != NULL) glp_close(mpl->prt_fp); - if (mpl->prt_file != NULL) xfree(mpl->prt_file); - if (mpl->mod_file != NULL) xfree(mpl->mod_file); - xfree(mpl->mpl_buf); - xfree(mpl); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpmpl05.c b/resources/3rdparty/glpk-4.53/src/glpmpl05.c deleted file mode 100644 index 2207572a7..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpmpl05.c +++ /dev/null @@ -1,563 +0,0 @@ -/* glpmpl05.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Authors: Andrew Makhorin -* Heinrich Schuchardt -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "glpmpl.h" -#if 1 /* 11/VI-2013 */ -#include "jd.h" -#endif - -double fn_gmtime(MPL *mpl) -{ /* obtain the current calendar time (UTC) */ - time_t timer; - struct tm *tm; - int j; - time(&timer); - if (timer == (time_t)(-1)) -err: error(mpl, "gmtime(); unable to obtain current calendar time"); - tm = gmtime(&timer); - if (tm == NULL) goto err; - j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year); - if (j < 0) goto err; - return (((double)(j - jday(1, 1, 1970)) * 24.0 + - (double)tm->tm_hour) * 60.0 + (double)tm->tm_min) * 60.0 + - (double)tm->tm_sec; -} - -static char *week[] = { "Monday", "Tuesday", "Wednesday", "Thursday", - "Friday", "Saturday", "Sunday" }; - -static char *moon[] = { "January", "February", "March", "April", "May", - "June", "July", "August", "September", "October", "November", - "December" }; - -static void error1(MPL *mpl, const char *str, const char *s, - const char *fmt, const char *f, const char *msg) -{ xprintf("Input string passed to str2time:\n"); - xprintf("%s\n", str); - xprintf("%*s\n", (s - str) + 1, "^"); - xprintf("Format string passed to str2time:\n"); - xprintf("%s\n", fmt); - xprintf("%*s\n", (f - fmt) + 1, "^"); - error(mpl, "%s", msg); - /* no return */ -} - -double fn_str2time(MPL *mpl, const char *str, const char *fmt) -{ /* convert character string to the calendar time */ - int j, year, month, day, hh, mm, ss, zone; - const char *s, *f; - year = month = day = hh = mm = ss = -1, zone = INT_MAX; - s = str; - for (f = fmt; *f != '\0'; f++) - { if (*f == '%') - { f++; - if (*f == 'b' || *f == 'h') - { /* the abbreviated month name */ - int k; - char *name; - if (month >= 0) - error1(mpl, str, s, fmt, f, "month multiply specified" - ); - while (*s == ' ') s++; - for (month = 1; month <= 12; month++) - { name = moon[month-1]; - for (k = 0; k <= 2; k++) - { if (toupper((unsigned char)s[k]) != - toupper((unsigned char)name[k])) goto next; - } - s += 3; - for (k = 3; name[k] != '\0'; k++) - { if (toupper((unsigned char)*s) != - toupper((unsigned char)name[k])) break; - s++; - } - break; -next: ; - } - if (month > 12) - error1(mpl, str, s, fmt, f, "abbreviated month name m" - "issing or invalid"); - } - else if (*f == 'd') - { /* the day of the month as a decimal number (01..31) */ - if (day >= 0) - error1(mpl, str, s, fmt, f, "day multiply specified"); - while (*s == ' ') s++; - if (!('0' <= *s && *s <= '9')) - error1(mpl, str, s, fmt, f, "day missing or invalid"); - day = (*s++) - '0'; - if ('0' <= *s && *s <= '9') - day = 10 * day + ((*s++) - '0'); - if (!(1 <= day && day <= 31)) - error1(mpl, str, s, fmt, f, "day out of range"); - } - else if (*f == 'H') - { /* the hour as a decimal number, using a 24-hour clock - (00..23) */ - if (hh >= 0) - error1(mpl, str, s, fmt, f, "hour multiply specified") - ; - while (*s == ' ') s++; - if (!('0' <= *s && *s <= '9')) - error1(mpl, str, s, fmt, f, "hour missing or invalid") - ; - hh = (*s++) - '0'; - if ('0' <= *s && *s <= '9') - hh = 10 * hh + ((*s++) - '0'); - if (!(0 <= hh && hh <= 23)) - error1(mpl, str, s, fmt, f, "hour out of range"); - } - else if (*f == 'm') - { /* the month as a decimal number (01..12) */ - if (month >= 0) - error1(mpl, str, s, fmt, f, "month multiply specified" - ); - while (*s == ' ') s++; - if (!('0' <= *s && *s <= '9')) - error1(mpl, str, s, fmt, f, "month missing or invalid" - ); - month = (*s++) - '0'; - if ('0' <= *s && *s <= '9') - month = 10 * month + ((*s++) - '0'); - if (!(1 <= month && month <= 12)) - error1(mpl, str, s, fmt, f, "month out of range"); - } - else if (*f == 'M') - { /* the minute as a decimal number (00..59) */ - if (mm >= 0) - error1(mpl, str, s, fmt, f, "minute multiply specifie" - "d"); - while (*s == ' ') s++; - if (!('0' <= *s && *s <= '9')) - error1(mpl, str, s, fmt, f, "minute missing or invali" - "d"); - mm = (*s++) - '0'; - if ('0' <= *s && *s <= '9') - mm = 10 * mm + ((*s++) - '0'); - if (!(0 <= mm && mm <= 59)) - error1(mpl, str, s, fmt, f, "minute out of range"); - } - else if (*f == 'S') - { /* the second as a decimal number (00..60) */ - if (ss >= 0) - error1(mpl, str, s, fmt, f, "second multiply specifie" - "d"); - while (*s == ' ') s++; - if (!('0' <= *s && *s <= '9')) - error1(mpl, str, s, fmt, f, "second missing or invali" - "d"); - ss = (*s++) - '0'; - if ('0' <= *s && *s <= '9') - ss = 10 * ss + ((*s++) - '0'); - if (!(0 <= ss && ss <= 60)) - error1(mpl, str, s, fmt, f, "second out of range"); - } - else if (*f == 'y') - { /* the year without a century as a decimal number - (00..99); the values 00 to 68 mean the years 2000 to - 2068 while the values 69 to 99 mean the years 1969 to - 1999 */ - if (year >= 0) - error1(mpl, str, s, fmt, f, "year multiply specified") - ; - while (*s == ' ') s++; - if (!('0' <= *s && *s <= '9')) - error1(mpl, str, s, fmt, f, "year missing or invalid") - ; - year = (*s++) - '0'; - if ('0' <= *s && *s <= '9') - year = 10 * year + ((*s++) - '0'); - year += (year >= 69 ? 1900 : 2000); - } - else if (*f == 'Y') - { /* the year as a decimal number, using the Gregorian - calendar */ - if (year >= 0) - error1(mpl, str, s, fmt, f, "year multiply specified") - ; - while (*s == ' ') s++; - if (!('0' <= *s && *s <= '9')) - error1(mpl, str, s, fmt, f, "year missing or invalid") - ; - year = 0; - for (j = 1; j <= 4; j++) - { if (!('0' <= *s && *s <= '9')) break; - year = 10 * year + ((*s++) - '0'); - } - if (!(1 <= year && year <= 4000)) - error1(mpl, str, s, fmt, f, "year out of range"); - } - else if (*f == 'z') - { /* time zone offset in the form zhhmm */ - int z, hh, mm; - if (zone != INT_MAX) - error1(mpl, str, s, fmt, f, "time zone offset multipl" - "y specified"); - while (*s == ' ') s++; - if (*s == 'Z') - { z = hh = mm = 0, s++; - goto skip; - } - if (*s == '+') - z = +1, s++; - else if (*s == '-') - z = -1, s++; - else - error1(mpl, str, s, fmt, f, "time zone offset sign mi" - "ssing"); - hh = 0; - for (j = 1; j <= 2; j++) - { if (!('0' <= *s && *s <= '9')) -err1: error1(mpl, str, s, fmt, f, "time zone offset valu" - "e incomplete or invalid"); - hh = 10 * hh + ((*s++) - '0'); - } - if (hh > 23) -err2: error1(mpl, str, s, fmt, f, "time zone offset value o" - "ut of range"); - if (*s == ':') - { s++; - if (!('0' <= *s && *s <= '9')) goto err1; - } - mm = 0; - if (!('0' <= *s && *s <= '9')) goto skip; - for (j = 1; j <= 2; j++) - { if (!('0' <= *s && *s <= '9')) goto err1; - mm = 10 * mm + ((*s++) - '0'); - } - if (mm > 59) goto err2; -skip: zone = z * (60 * hh + mm); - } - else if (*f == '%') - { /* literal % character */ - goto test; - } - else - error1(mpl, str, s, fmt, f, "invalid conversion specifie" - "r"); - } - else if (*f == ' ') - ; - else -test: { /* check a matching character in the input string */ - if (*s != *f) - error1(mpl, str, s, fmt, f, "character mismatch"); - s++; - } - } - if (year < 0) year = 1970; - if (month < 0) month = 1; - if (day < 0) day = 1; - if (hh < 0) hh = 0; - if (mm < 0) mm = 0; - if (ss < 0) ss = 0; - if (zone == INT_MAX) zone = 0; - j = jday(day, month, year); - xassert(j >= 0); - return (((double)(j - jday(1, 1, 1970)) * 24.0 + (double)hh) * - 60.0 + (double)mm) * 60.0 + (double)ss - 60.0 * (double)zone; -} - -static void error2(MPL *mpl, const char *fmt, const char *f, - const char *msg) -{ xprintf("Format string passed to time2str:\n"); - xprintf("%s\n", fmt); - xprintf("%*s\n", (f - fmt) + 1, "^"); - error(mpl, "%s", msg); - /* no return */ -} - -static int weekday(int j) -{ /* determine weekday number (1 = Mon, ..., 7 = Sun) */ - return (j + jday(1, 1, 1970)) % 7 + 1; -} - -static int firstday(int year) -{ /* determine the first day of the first week for a specified year - according to ISO 8601 */ - int j; - /* if 1 January is Monday, Tuesday, Wednesday or Thursday, it is - in week 01; if 1 January is Friday, Saturday or Sunday, it is - in week 52 or 53 of the previous year */ - j = jday(1, 1, year) - jday(1, 1, 1970); - switch (weekday(j)) - { case 1: /* 1 Jan is Mon */ j += 0; break; - case 2: /* 1 Jan is Tue */ j -= 1; break; - case 3: /* 1 Jan is Wed */ j -= 2; break; - case 4: /* 1 Jan is Thu */ j -= 3; break; - case 5: /* 1 Jan is Fri */ j += 3; break; - case 6: /* 1 Jan is Sat */ j += 2; break; - case 7: /* 1 Jan is Sun */ j += 1; break; - default: xassert(j != j); - } - /* the first day of the week must be Monday */ - xassert(weekday(j) == 1); - return j; -} - -void fn_time2str(MPL *mpl, char *str, double t, const char *fmt) -{ /* convert the calendar time to character string */ - int j, year, month, day, hh, mm, ss, len; - double temp; - const char *f; - char buf[MAX_LENGTH+1]; - if (!(-62135596800.0 <= t && t <= 64092211199.0)) - error(mpl, "time2str(%.*g,...); argument out of range", - DBL_DIG, t); - t = floor(t + 0.5); - temp = fabs(t) / 86400.0; - j = (int)floor(temp); - if (t < 0.0) - { if (temp == floor(temp)) - j = - j; - else - j = - (j + 1); - } - xassert(jdate(j + jday(1, 1, 1970), &day, &month, &year) == 0); - ss = (int)(t - 86400.0 * (double)j); - xassert(0 <= ss && ss < 86400); - mm = ss / 60, ss %= 60; - hh = mm / 60, mm %= 60; - len = 0; - for (f = fmt; *f != '\0'; f++) - { if (*f == '%') - { f++; - if (*f == 'a') - { /* the abbreviated weekday name */ - memcpy(buf, week[weekday(j)-1], 3), buf[3] = '\0'; - } - else if (*f == 'A') - { /* the full weekday name */ - strcpy(buf, week[weekday(j)-1]); - } - else if (*f == 'b' || *f == 'h') - { /* the abbreviated month name */ - memcpy(buf, moon[month-1], 3), buf[3] = '\0'; - } - else if (*f == 'B') - { /* the full month name */ - strcpy(buf, moon[month-1]); - } - else if (*f == 'C') - { /* the century of the year */ - sprintf(buf, "%02d", year / 100); - } - else if (*f == 'd') - { /* the day of the month as a decimal number (01..31) */ - sprintf(buf, "%02d", day); - } - else if (*f == 'D') - { /* the date using the format %m/%d/%y */ - sprintf(buf, "%02d/%02d/%02d", month, day, year % 100); - } - else if (*f == 'e') - { /* the day of the month like with %d, but padded with - blank (1..31) */ - sprintf(buf, "%2d", day); - } - else if (*f == 'F') - { /* the date using the format %Y-%m-%d */ - sprintf(buf, "%04d-%02d-%02d", year, month, day); - } - else if (*f == 'g') - { /* the year corresponding to the ISO week number, but - without the century (range 00 through 99); this has - the same format and value as %y, except that if the - ISO week number (see %V) belongs to the previous or - next year, that year is used instead */ - int iso; - if (j < firstday(year)) - iso = year - 1; - else if (j < firstday(year + 1)) - iso = year; - else - iso = year + 1; - sprintf(buf, "%02d", iso % 100); - } - else if (*f == 'G') - { /* the year corresponding to the ISO week number; this - has the same format and value as %Y, excepth that if - the ISO week number (see %V) belongs to the previous - or next year, that year is used instead */ - int iso; - if (j < firstday(year)) - iso = year - 1; - else if (j < firstday(year + 1)) - iso = year; - else - iso = year + 1; - sprintf(buf, "%04d", iso); - } - else if (*f == 'H') - { /* the hour as a decimal number, using a 24-hour clock - (00..23) */ - sprintf(buf, "%02d", hh); - } - else if (*f == 'I') - { /* the hour as a decimal number, using a 12-hour clock - (01..12) */ - sprintf(buf, "%02d", - hh == 0 ? 12 : hh <= 12 ? hh : hh - 12); - } - else if (*f == 'j') - { /* the day of the year as a decimal number (001..366) */ - sprintf(buf, "%03d", - jday(day, month, year) - jday(1, 1, year) + 1); - } - else if (*f == 'k') - { /* the hour as a decimal number, using a 24-hour clock - like %H, but padded with blank (0..23) */ - sprintf(buf, "%2d", hh); - } - else if (*f == 'l') - { /* the hour as a decimal number, using a 12-hour clock - like %I, but padded with blank (1..12) */ - sprintf(buf, "%2d", - hh == 0 ? 12 : hh <= 12 ? hh : hh - 12); - } - else if (*f == 'm') - { /* the month as a decimal number (01..12) */ - sprintf(buf, "%02d", month); - } - else if (*f == 'M') - { /* the minute as a decimal number (00..59) */ - sprintf(buf, "%02d", mm); - } - else if (*f == 'p') - { /* either AM or PM, according to the given time value; - noon is treated as PM and midnight as AM */ - strcpy(buf, hh <= 11 ? "AM" : "PM"); - } - else if (*f == 'P') - { /* either am or pm, according to the given time value; - noon is treated as pm and midnight as am */ - strcpy(buf, hh <= 11 ? "am" : "pm"); - } - else if (*f == 'r') - { /* the calendar time using the format %I:%M:%S %p */ - sprintf(buf, "%02d:%02d:%02d %s", - hh == 0 ? 12 : hh <= 12 ? hh : hh - 12, - mm, ss, hh <= 11 ? "AM" : "PM"); - } - else if (*f == 'R') - { /* the hour and minute using the format %H:%M */ - sprintf(buf, "%02d:%02d", hh, mm); - } - else if (*f == 'S') - { /* the second as a decimal number (00..59) */ - sprintf(buf, "%02d", ss); - } - else if (*f == 'T') - { /* the time of day using the format %H:%M:%S */ - sprintf(buf, "%02d:%02d:%02d", hh, mm, ss); - } - else if (*f == 'u') - { /* the day of the week as a decimal number (1..7), - Monday being 1 */ - sprintf(buf, "%d", weekday(j)); - } - else if (*f == 'U') - { /* the week number of the current year as a decimal - number (range 00 through 53), starting with the first - Sunday as the first day of the first week; days - preceding the first Sunday in the year are considered - to be in week 00 */ -#if 1 /* 09/I-2009 */ -#undef sun -/* causes compilation error in SunOS */ -#endif - int sun; - /* sun = the first Sunday of the year */ - sun = jday(1, 1, year) - jday(1, 1, 1970); - sun += (7 - weekday(sun)); - sprintf(buf, "%02d", (j + 7 - sun) / 7); - } - else if (*f == 'V') - { /* the ISO week number as a decimal number (range 01 - through 53); ISO weeks start with Monday and end with - Sunday; week 01 of a year is the first week which has - the majority of its days in that year; week 01 of - a year can contain days from the previous year; the - week before week 01 of a year is the last week (52 or - 53) of the previous year even if it contains days - from the new year */ - int iso; - if (j < firstday(year)) - iso = j - firstday(year - 1); - else if (j < firstday(year + 1)) - iso = j - firstday(year); - else - iso = j - firstday(year + 1); - sprintf(buf, "%02d", iso / 7 + 1); - } - else if (*f == 'w') - { /* the day of the week as a decimal number (0..6), - Sunday being 0 */ - sprintf(buf, "%d", weekday(j) % 7); - } - else if (*f == 'W') - { /* the week number of the current year as a decimal - number (range 00 through 53), starting with the first - Monday as the first day of the first week; days - preceding the first Monday in the year are considered - to be in week 00 */ - int mon; - /* mon = the first Monday of the year */ - mon = jday(1, 1, year) - jday(1, 1, 1970); - mon += (8 - weekday(mon)) % 7; - sprintf(buf, "%02d", (j + 7 - mon) / 7); - } - else if (*f == 'y') - { /* the year without a century as a decimal number - (00..99) */ - sprintf(buf, "%02d", year % 100); - } - else if (*f == 'Y') - { /* the year as a decimal number, using the Gregorian - calendar */ - sprintf(buf, "%04d", year); - } - else if (*f == '%') - { /* a literal % character */ - buf[0] = '%', buf[1] = '\0'; - } - else - error2(mpl, fmt, f, "invalid conversion specifier"); - } - else - buf[0] = *f, buf[1] = '\0'; - if (len + strlen(buf) > MAX_LENGTH) - error(mpl, "time2str; output string length exceeds %d chara" - "cters", MAX_LENGTH); - memcpy(str+len, buf, strlen(buf)); - len += strlen(buf); - } - str[len] = '\0'; - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpmpl06.c b/resources/3rdparty/glpk-4.53/src/glpmpl06.c deleted file mode 100644 index 8ab122a75..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpmpl06.c +++ /dev/null @@ -1,1000 +0,0 @@ -/* glpmpl06.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "glpmpl.h" -#include "glpsql.h" - -/**********************************************************************/ - -#define CSV_FIELD_MAX 50 -/* maximal number of fields in record */ - -#define CSV_FDLEN_MAX 100 -/* maximal field length */ - -struct csv -{ /* comma-separated values file */ - int mode; - /* 'R' = reading; 'W' = writing */ - char *fname; - /* name of csv file */ - FILE *fp; - /* stream assigned to csv file */ - jmp_buf jump; - /* address for non-local go to in case of error */ - int count; - /* record count */ - /*--------------------------------------------------------------*/ - /* used only for input csv file */ - int c; - /* current character or EOF */ - int what; - /* current marker: */ -#define CSV_EOF 0 /* end-of-file */ -#define CSV_EOR 1 /* end-of-record */ -#define CSV_NUM 2 /* floating-point number */ -#define CSV_STR 3 /* character string */ - char field[CSV_FDLEN_MAX+1]; - /* current field just read */ - int nf; - /* number of fields in the csv file */ - int ref[1+CSV_FIELD_MAX]; - /* ref[k] = k', if k-th field of the csv file corresponds to - k'-th field in the table statement; if ref[k] = 0, k-th field - of the csv file is ignored */ -#if 1 /* 01/VI-2010 */ - int nskip; - /* number of comment records preceding the header record */ -#endif -}; - -#undef read_char - -static void read_char(struct csv *csv) -{ /* read character from csv data file */ - int c; - xassert(csv->c != EOF); - if (csv->c == '\n') csv->count++; -loop: c = fgetc(csv->fp); - if (ferror(csv->fp)) - { xprintf("%s:%d: read error - %s\n", csv->fname, csv->count, - strerror(errno)); - longjmp(csv->jump, 0); - } - if (feof(csv->fp)) - { if (csv->c == '\n') - { csv->count--; - c = EOF; - } - else - { xprintf("%s:%d: warning: missing final end-of-line\n", - csv->fname, csv->count); - c = '\n'; - } - } - else if (c == '\r') - goto loop; - else if (c == '\n') - ; - else if (iscntrl(c)) - { xprintf("%s:%d: invalid control character 0x%02X\n", - csv->fname, csv->count, c); - longjmp(csv->jump, 0); - } - csv->c = c; - return; -} - -static void read_field(struct csv *csv) -{ /* read field from csv data file */ - /* check for end of file */ - if (csv->c == EOF) - { csv->what = CSV_EOF; - strcpy(csv->field, "EOF"); - goto done; - } - /* check for end of record */ - if (csv->c == '\n') - { csv->what = CSV_EOR; - strcpy(csv->field, "EOR"); - read_char(csv); - if (csv->c == ',') -err1: { xprintf("%s:%d: empty field not allowed\n", csv->fname, - csv->count); - longjmp(csv->jump, 0); - } - if (csv->c == '\n') - { xprintf("%s:%d: empty record not allowed\n", csv->fname, - csv->count); - longjmp(csv->jump, 0); - } -#if 1 /* 01/VI-2010 */ - /* skip comment records; may appear only before the very first - record containing field names */ - if (csv->c == '#' && csv->count == 1) - { while (csv->c == '#') - { while (csv->c != '\n') - read_char(csv); - read_char(csv); - csv->nskip++; - } - } -#endif - goto done; - } - /* skip comma before next field */ - if (csv->c == ',') - read_char(csv); - /* read field */ - if (csv->c == '\'' || csv->c == '"') - { /* read a field enclosed in quotes */ - int quote = csv->c, len = 0; - csv->what = CSV_STR; - /* skip opening quote */ - read_char(csv); - /* read field characters within quotes */ - for (;;) - { /* check for closing quote and read it */ - if (csv->c == quote) - { read_char(csv); - if (csv->c == quote) - ; - else if (csv->c == ',' || csv->c == '\n') - break; - else - { xprintf("%s:%d: invalid field\n", csv->fname, - csv->count); - longjmp(csv->jump, 0); - } - } - /* check the current field length */ - if (len == CSV_FDLEN_MAX) -err2: { xprintf("%s:%d: field too long\n", csv->fname, - csv->count); - longjmp(csv->jump, 0); - } - /* add the current character to the field */ - csv->field[len++] = (char)csv->c; - /* read the next character */ - read_char(csv); - } - /* the field has been read */ - if (len == 0) goto err1; - csv->field[len] = '\0'; - } - else - { /* read a field not enclosed in quotes */ - int len = 0; - double temp; - csv->what = CSV_NUM; - while (!(csv->c == ',' || csv->c == '\n')) - { /* quotes within the field are not allowed */ - if (csv->c == '\'' || csv->c == '"') - { xprintf("%s:%d: invalid use of single or double quote wi" - "thin field\n", csv->fname, csv->count); - longjmp(csv->jump, 0); - } - /* check the current field length */ - if (len == CSV_FDLEN_MAX) goto err2; - /* add the current character to the field */ - csv->field[len++] = (char)csv->c; - /* read the next character */ - read_char(csv); - } - /* the field has been read */ - if (len == 0) goto err1; - csv->field[len] = '\0'; - /* check the field type */ - if (str2num(csv->field, &temp)) csv->what = CSV_STR; - } -done: return; -} - -static struct csv *csv_open_file(TABDCA *dca, int mode) -{ /* open csv data file */ - struct csv *csv; - /* create control structure */ - csv = xmalloc(sizeof(struct csv)); - csv->mode = mode; - csv->fname = NULL; - csv->fp = NULL; - if (setjmp(csv->jump)) goto fail; - csv->count = 0; - csv->c = '\n'; - csv->what = 0; - csv->field[0] = '\0'; - csv->nf = 0; - /* try to open the csv data file */ - if (mpl_tab_num_args(dca) < 2) - { xprintf("csv_driver: file name not specified\n"); - longjmp(csv->jump, 0); - } - csv->fname = xmalloc(strlen(mpl_tab_get_arg(dca, 2))+1); - strcpy(csv->fname, mpl_tab_get_arg(dca, 2)); - if (mode == 'R') - { /* open the file for reading */ - int k; - csv->fp = fopen(csv->fname, "r"); - if (csv->fp == NULL) - { xprintf("csv_driver: unable to open %s - %s\n", - csv->fname, strerror(errno)); - longjmp(csv->jump, 0); - } -#if 1 /* 01/VI-2010 */ - csv->nskip = 0; -#endif - /* skip fake new-line */ - read_field(csv); - xassert(csv->what == CSV_EOR); - /* read field names */ - xassert(csv->nf == 0); - for (;;) - { read_field(csv); - if (csv->what == CSV_EOR) - break; - if (csv->what != CSV_STR) - { xprintf("%s:%d: invalid field name\n", csv->fname, - csv->count); - longjmp(csv->jump, 0); - } - if (csv->nf == CSV_FIELD_MAX) - { xprintf("%s:%d: too many fields\n", csv->fname, - csv->count); - longjmp(csv->jump, 0); - } - csv->nf++; - /* find corresponding field in the table statement */ - for (k = mpl_tab_num_flds(dca); k >= 1; k--) - { if (strcmp(mpl_tab_get_name(dca, k), csv->field) == 0) - break; - } - csv->ref[csv->nf] = k; - } - /* find dummy RECNO field in the table statement */ - for (k = mpl_tab_num_flds(dca); k >= 1; k--) - if (strcmp(mpl_tab_get_name(dca, k), "RECNO") == 0) break; - csv->ref[0] = k; - } - else if (mode == 'W') - { /* open the file for writing */ - int k, nf; - csv->fp = fopen(csv->fname, "w"); - if (csv->fp == NULL) - { xprintf("csv_driver: unable to create %s - %s\n", - csv->fname, strerror(errno)); - longjmp(csv->jump, 0); - } - /* write field names */ - nf = mpl_tab_num_flds(dca); - for (k = 1; k <= nf; k++) - fprintf(csv->fp, "%s%c", mpl_tab_get_name(dca, k), - k < nf ? ',' : '\n'); - csv->count++; - } - else - xassert(mode != mode); - /* the file has been open */ - return csv; -fail: /* the file cannot be open */ - if (csv->fname != NULL) xfree(csv->fname); - if (csv->fp != NULL) fclose(csv->fp); - xfree(csv); - return NULL; -} - -static int csv_read_record(TABDCA *dca, struct csv *csv) -{ /* read next record from csv data file */ - int k, ret = 0; - xassert(csv->mode == 'R'); - if (setjmp(csv->jump)) - { ret = 1; - goto done; - } - /* read dummy RECNO field */ - if (csv->ref[0] > 0) -#if 0 /* 01/VI-2010 */ - mpl_tab_set_num(dca, csv->ref[0], csv->count-1); -#else - mpl_tab_set_num(dca, csv->ref[0], csv->count-csv->nskip-1); -#endif - /* read fields */ - for (k = 1; k <= csv->nf; k++) - { read_field(csv); - if (csv->what == CSV_EOF) - { /* end-of-file reached */ - xassert(k == 1); - ret = -1; - goto done; - } - else if (csv->what == CSV_EOR) - { /* end-of-record reached */ - int lack = csv->nf - k + 1; - if (lack == 1) - xprintf("%s:%d: one field missing\n", csv->fname, - csv->count); - else - xprintf("%s:%d: %d fields missing\n", csv->fname, - csv->count, lack); - longjmp(csv->jump, 0); - } - else if (csv->what == CSV_NUM) - { /* floating-point number */ - if (csv->ref[k] > 0) - { double num; - xassert(str2num(csv->field, &num) == 0); - mpl_tab_set_num(dca, csv->ref[k], num); - } - } - else if (csv->what == CSV_STR) - { /* character string */ - if (csv->ref[k] > 0) - mpl_tab_set_str(dca, csv->ref[k], csv->field); - } - else - xassert(csv != csv); - } - /* now there must be NL */ - read_field(csv); - xassert(csv->what != CSV_EOF); - if (csv->what != CSV_EOR) - { xprintf("%s:%d: too many fields\n", csv->fname, csv->count); - longjmp(csv->jump, 0); - } -done: return ret; -} - -static int csv_write_record(TABDCA *dca, struct csv *csv) -{ /* write next record to csv data file */ - int k, nf, ret = 0; - const char *c; - xassert(csv->mode == 'W'); - nf = mpl_tab_num_flds(dca); - for (k = 1; k <= nf; k++) - { switch (mpl_tab_get_type(dca, k)) - { case 'N': - fprintf(csv->fp, "%.*g", DBL_DIG, - mpl_tab_get_num(dca, k)); - break; - case 'S': - fputc('"', csv->fp); - for (c = mpl_tab_get_str(dca, k); *c != '\0'; c++) - { if (*c == '"') - fputc('"', csv->fp), fputc('"', csv->fp); - else - fputc(*c, csv->fp); - } - fputc('"', csv->fp); - break; - default: - xassert(dca != dca); - } - fputc(k < nf ? ',' : '\n', csv->fp); - } - csv->count++; - if (ferror(csv->fp)) - { xprintf("%s:%d: write error - %s\n", csv->fname, csv->count, - strerror(errno)); - ret = 1; - } - return ret; -} - -static int csv_close_file(TABDCA *dca, struct csv *csv) -{ /* close csv data file */ - int ret = 0; - xassert(dca == dca); - if (csv->mode == 'W') - { fflush(csv->fp); - if (ferror(csv->fp)) - { xprintf("%s:%d: write error - %s\n", csv->fname, - csv->count, strerror(errno)); - ret = 1; - } - } - xfree(csv->fname); - fclose(csv->fp); - xfree(csv); - return ret; -} - -/**********************************************************************/ - -#define DBF_FIELD_MAX 50 -/* maximal number of fields in record */ - -#define DBF_FDLEN_MAX 100 -/* maximal field length */ - -struct dbf -{ /* xBASE data file */ - int mode; - /* 'R' = reading; 'W' = writing */ - char *fname; - /* name of xBASE file */ - FILE *fp; - /* stream assigned to xBASE file */ - jmp_buf jump; - /* address for non-local go to in case of error */ - int offset; - /* offset of a byte to be read next */ - int count; - /* record count */ - int nf; - /* number of fields */ - int ref[1+DBF_FIELD_MAX]; - /* ref[k] = k', if k-th field of the csv file corresponds to - k'-th field in the table statement; if ref[k] = 0, k-th field - of the csv file is ignored */ - int type[1+DBF_FIELD_MAX]; - /* type[k] is type of k-th field */ - int len[1+DBF_FIELD_MAX]; - /* len[k] is length of k-th field */ - int prec[1+DBF_FIELD_MAX]; - /* prec[k] is precision of k-th field */ -}; - -static int read_byte(struct dbf *dbf) -{ /* read byte from xBASE data file */ - int b; - b = fgetc(dbf->fp); - if (ferror(dbf->fp)) - { xprintf("%s:0x%X: read error - %s\n", dbf->fname, - dbf->offset, strerror(errno)); - longjmp(dbf->jump, 0); - } - if (feof(dbf->fp)) - { xprintf("%s:0x%X: unexpected end of file\n", dbf->fname, - dbf->offset); - longjmp(dbf->jump, 0); - } - xassert(0x00 <= b && b <= 0xFF); - dbf->offset++; - return b; -} - -static void read_header(TABDCA *dca, struct dbf *dbf) -{ /* read xBASE data file header */ - int b, j, k, recl; - char name[10+1]; - /* (ignored) */ - for (j = 1; j <= 10; j++) - read_byte(dbf); - /* length of each record, in bytes */ - recl = read_byte(dbf); - recl += read_byte(dbf) << 8; - /* (ignored) */ - for (j = 1; j <= 20; j++) - read_byte(dbf); - /* field descriptor array */ - xassert(dbf->nf == 0); - for (;;) - { /* check for end of array */ - b = read_byte(dbf); - if (b == 0x0D) break; - if (dbf->nf == DBF_FIELD_MAX) - { xprintf("%s:0x%X: too many fields\n", dbf->fname, - dbf->offset); - longjmp(dbf->jump, 0); - } - dbf->nf++; - /* field name */ - name[0] = (char)b; - for (j = 1; j < 10; j++) - { b = read_byte(dbf); - name[j] = (char)b; - } - name[10] = '\0'; - b = read_byte(dbf); - if (b != 0x00) - { xprintf("%s:0x%X: invalid field name\n", dbf->fname, - dbf->offset); - longjmp(dbf->jump, 0); - } - /* find corresponding field in the table statement */ - for (k = mpl_tab_num_flds(dca); k >= 1; k--) - if (strcmp(mpl_tab_get_name(dca, k), name) == 0) break; - dbf->ref[dbf->nf] = k; - /* field type */ - b = read_byte(dbf); - if (!(b == 'C' || b == 'N')) - { xprintf("%s:0x%X: invalid field type\n", dbf->fname, - dbf->offset); - longjmp(dbf->jump, 0); - } - dbf->type[dbf->nf] = b; - /* (ignored) */ - for (j = 1; j <= 4; j++) - read_byte(dbf); - /* field length */ - b = read_byte(dbf); - if (b == 0) - { xprintf("%s:0x%X: invalid field length\n", dbf->fname, - dbf->offset); - longjmp(dbf->jump, 0); - } - if (b > DBF_FDLEN_MAX) - { xprintf("%s:0x%X: field too long\n", dbf->fname, - dbf->offset); - longjmp(dbf->jump, 0); - } - dbf->len[dbf->nf] = b; - recl -= b; - /* (ignored) */ - for (j = 1; j <= 15; j++) - read_byte(dbf); - } - if (recl != 1) - { xprintf("%s:0x%X: invalid file header\n", dbf->fname, - dbf->offset); - longjmp(dbf->jump, 0); - } - /* find dummy RECNO field in the table statement */ - for (k = mpl_tab_num_flds(dca); k >= 1; k--) - if (strcmp(mpl_tab_get_name(dca, k), "RECNO") == 0) break; - dbf->ref[0] = k; - return; -} - -static void parse_third_arg(TABDCA *dca, struct dbf *dbf) -{ /* parse xBASE file format (third argument) */ - int j, k, temp; - const char *arg; - dbf->nf = mpl_tab_num_flds(dca); - arg = mpl_tab_get_arg(dca, 3), j = 0; - for (k = 1; k <= dbf->nf; k++) - { /* parse specification of k-th field */ - if (arg[j] == '\0') - { xprintf("xBASE driver: field %s: specification missing\n", - mpl_tab_get_name(dca, k)); - longjmp(dbf->jump, 0); - } - /* parse field type */ - if (arg[j] == 'C' || arg[j] == 'N') - dbf->type[k] = arg[j], j++; - else - { xprintf("xBASE driver: field %s: invalid field type\n", - mpl_tab_get_name(dca, k)); - longjmp(dbf->jump, 0); - } - /* check for left parenthesis */ - if (arg[j] == '(') - j++; - else -err: { xprintf("xBASE driver: field %s: invalid field format\n", - mpl_tab_get_name(dca, k)); - longjmp(dbf->jump, 0); - } - /* parse field length */ - temp = 0; - while (isdigit(arg[j])) - { if (temp > DBF_FDLEN_MAX) break; - temp = 10 * temp + (arg[j] - '0'), j++; - } - if (!(1 <= temp && temp <= DBF_FDLEN_MAX)) - { xprintf("xBASE driver: field %s: invalid field length\n", - mpl_tab_get_name(dca, k)); - longjmp(dbf->jump, 0); - } - dbf->len[k] = temp; - /* parse optional field precision */ - if (dbf->type[k] == 'N' && arg[j] == ',') - { j++; - temp = 0; - while (isdigit(arg[j])) - { if (temp > dbf->len[k]) break; - temp = 10 * temp + (arg[j] - '0'), j++; - } - if (temp > dbf->len[k]) - { xprintf("xBASE driver: field %s: invalid field precision" - "\n", mpl_tab_get_name(dca, k)); - longjmp(dbf->jump, 0); - } - dbf->prec[k] = temp; - } - else - dbf->prec[k] = 0; - /* check for right parenthesis */ - if (arg[j] == ')') - j++; - else - goto err; - } - /* ignore other specifications */ - return; -} - -static void write_byte(struct dbf *dbf, int b) -{ /* write byte to xBASE data file */ - fputc(b, dbf->fp); - dbf->offset++; - return; -} - -static void write_header(TABDCA *dca, struct dbf *dbf) -{ /* write xBASE data file header */ - int j, k, temp; - const char *name; - /* version number */ - write_byte(dbf, 0x03 /* file without DBT */); - /* date of last update (YYMMDD) */ - write_byte(dbf, 70 /* 1970 */); - write_byte(dbf, 1 /* January */); - write_byte(dbf, 1 /* 1st */); - /* number of records (unknown so far) */ - for (j = 1; j <= 4; j++) - write_byte(dbf, 0xFF); - /* length of the header, in bytes */ - temp = 32 + dbf->nf * 32 + 1; - write_byte(dbf, temp); - write_byte(dbf, temp >> 8); - /* length of each record, in bytes */ - temp = 1; - for (k = 1; k <= dbf->nf; k++) - temp += dbf->len[k]; - write_byte(dbf, temp); - write_byte(dbf, temp >> 8); - /* (reserved) */ - for (j = 1; j <= 20; j++) - write_byte(dbf, 0x00); - /* field descriptor array */ - for (k = 1; k <= dbf->nf; k++) - { /* field name (terminated by 0x00) */ - name = mpl_tab_get_name(dca, k); - for (j = 0; j < 10 && name[j] != '\0'; j++) - write_byte(dbf, name[j]); - for (j = j; j < 11; j++) - write_byte(dbf, 0x00); - /* field type */ - write_byte(dbf, dbf->type[k]); - /* (reserved) */ - for (j = 1; j <= 4; j++) - write_byte(dbf, 0x00); - /* field length */ - write_byte(dbf, dbf->len[k]); - /* field precision */ - write_byte(dbf, dbf->prec[k]); - /* (reserved) */ - for (j = 1; j <= 14; j++) - write_byte(dbf, 0x00); - } - /* end of header */ - write_byte(dbf, 0x0D); - return; -} - -static struct dbf *dbf_open_file(TABDCA *dca, int mode) -{ /* open xBASE data file */ - struct dbf *dbf; - /* create control structure */ - dbf = xmalloc(sizeof(struct dbf)); - dbf->mode = mode; - dbf->fname = NULL; - dbf->fp = NULL; - if (setjmp(dbf->jump)) goto fail; - dbf->offset = 0; - dbf->count = 0; - dbf->nf = 0; - /* try to open the xBASE data file */ - if (mpl_tab_num_args(dca) < 2) - { xprintf("xBASE driver: file name not specified\n"); - longjmp(dbf->jump, 0); - } - dbf->fname = xmalloc(strlen(mpl_tab_get_arg(dca, 2))+1); - strcpy(dbf->fname, mpl_tab_get_arg(dca, 2)); - if (mode == 'R') - { /* open the file for reading */ - dbf->fp = fopen(dbf->fname, "rb"); - if (dbf->fp == NULL) - { xprintf("xBASE driver: unable to open %s - %s\n", - dbf->fname, strerror(errno)); - longjmp(dbf->jump, 0); - } - read_header(dca, dbf); - } - else if (mode == 'W') - { /* open the file for writing */ - if (mpl_tab_num_args(dca) < 3) - { xprintf("xBASE driver: file format not specified\n"); - longjmp(dbf->jump, 0); - } - parse_third_arg(dca, dbf); - dbf->fp = fopen(dbf->fname, "wb"); - if (dbf->fp == NULL) - { xprintf("xBASE driver: unable to create %s - %s\n", - dbf->fname, strerror(errno)); - longjmp(dbf->jump, 0); - } - write_header(dca, dbf); - } - else - xassert(mode != mode); - /* the file has been open */ - return dbf; -fail: /* the file cannot be open */ - if (dbf->fname != NULL) xfree(dbf->fname); - if (dbf->fp != NULL) fclose(dbf->fp); - xfree(dbf); - return NULL; -} - -static int dbf_read_record(TABDCA *dca, struct dbf *dbf) -{ /* read next record from xBASE data file */ - int b, j, k, ret = 0; - char buf[DBF_FDLEN_MAX+1]; - xassert(dbf->mode == 'R'); - if (setjmp(dbf->jump)) - { ret = 1; - goto done; - } - /* check record flag */ - b = read_byte(dbf); - if (b == 0x1A) - { /* end of data */ - ret = -1; - goto done; - } - if (b != 0x20) - { xprintf("%s:0x%X: invalid record flag\n", dbf->fname, - dbf->offset); - longjmp(dbf->jump, 0); - } - /* read dummy RECNO field */ - if (dbf->ref[0] > 0) - mpl_tab_set_num(dca, dbf->ref[0], dbf->count+1); - /* read fields */ - for (k = 1; k <= dbf->nf; k++) - { /* read k-th field */ - for (j = 0; j < dbf->len[k]; j++) - buf[j] = (char)read_byte(dbf); - buf[dbf->len[k]] = '\0'; - /* set field value */ - if (dbf->type[k] == 'C') - { /* character field */ - if (dbf->ref[k] > 0) - mpl_tab_set_str(dca, dbf->ref[k], strtrim(buf)); - } - else if (dbf->type[k] == 'N') - { /* numeric field */ - if (dbf->ref[k] > 0) - { double num; - strspx(buf); - xassert(str2num(buf, &num) == 0); - mpl_tab_set_num(dca, dbf->ref[k], num); - } - } - else - xassert(dbf != dbf); - } - /* increase record count */ - dbf->count++; -done: return ret; -} - -static int dbf_write_record(TABDCA *dca, struct dbf *dbf) -{ /* write next record to xBASE data file */ - int j, k, ret = 0; - char buf[255+1]; - xassert(dbf->mode == 'W'); - if (setjmp(dbf->jump)) - { ret = 1; - goto done; - } - /* record flag */ - write_byte(dbf, 0x20); - xassert(dbf->nf == mpl_tab_num_flds(dca)); - for (k = 1; k <= dbf->nf; k++) - { if (dbf->type[k] == 'C') - { /* character field */ - const char *str; - if (mpl_tab_get_type(dca, k) == 'N') - { sprintf(buf, "%.*g", DBL_DIG, mpl_tab_get_num(dca, k)); - str = buf; - } - else if (mpl_tab_get_type(dca, k) == 'S') - str = mpl_tab_get_str(dca, k); - else - xassert(dca != dca); - if ((int)strlen(str) > dbf->len[k]) - { xprintf("xBASE driver: field %s: cannot convert %.15s..." - " to field format\n", mpl_tab_get_name(dca, k), str); - longjmp(dbf->jump, 0); - } - for (j = 0; j < dbf->len[k] && str[j] != '\0'; j++) - write_byte(dbf, str[j]); - for (j = j; j < dbf->len[k]; j++) - write_byte(dbf, ' '); - } - else if (dbf->type[k] == 'N') - { /* numeric field */ - double num = mpl_tab_get_num(dca, k); - if (fabs(num) > 1e20) -err: { xprintf("xBASE driver: field %s: cannot convert %g to fi" - "eld format\n", mpl_tab_get_name(dca, k), num); - longjmp(dbf->jump, 0); - } - sprintf(buf, "%*.*f", dbf->len[k], dbf->prec[k], num); - xassert(strlen(buf) < sizeof(buf)); - if ((int)strlen(buf) != dbf->len[k]) goto err; - for (j = 0; j < dbf->len[k]; j++) - write_byte(dbf, buf[j]); - } - else - xassert(dbf != dbf); - } - /* increase record count */ - dbf->count++; -done: return ret; -} - -static int dbf_close_file(TABDCA *dca, struct dbf *dbf) -{ /* close xBASE data file */ - int ret = 0; - xassert(dca == dca); - if (dbf->mode == 'W') - { if (setjmp(dbf->jump)) - { ret = 1; - goto skip; - } - /* end-of-file flag */ - write_byte(dbf, 0x1A); - /* number of records */ - dbf->offset = 4; - if (fseek(dbf->fp, dbf->offset, SEEK_SET)) - { xprintf("%s:0x%X: seek error - %s\n", dbf->fname, - dbf->offset, strerror(errno)); - longjmp(dbf->jump, 0); - } - write_byte(dbf, dbf->count); - write_byte(dbf, dbf->count >> 8); - write_byte(dbf, dbf->count >> 16); - write_byte(dbf, dbf->count >> 24); - fflush(dbf->fp); - if (ferror(dbf->fp)) - { xprintf("%s:0x%X: write error - %s\n", dbf->fname, - dbf->offset, strerror(errno)); - longjmp(dbf->jump, 0); - } -skip: ; - } - xfree(dbf->fname); - fclose(dbf->fp); - xfree(dbf); - return ret; -} - -/**********************************************************************/ - -#define TAB_CSV 1 -#define TAB_XBASE 2 -#define TAB_ODBC 3 -#define TAB_MYSQL 4 - -void mpl_tab_drv_open(MPL *mpl, int mode) -{ TABDCA *dca = mpl->dca; - xassert(dca->id == 0); - xassert(dca->link == NULL); - xassert(dca->na >= 1); - if (strcmp(dca->arg[1], "CSV") == 0) - { dca->id = TAB_CSV; - dca->link = csv_open_file(dca, mode); - } - else if (strcmp(dca->arg[1], "xBASE") == 0) - { dca->id = TAB_XBASE; - dca->link = dbf_open_file(dca, mode); - } - else if (strcmp(dca->arg[1], "ODBC") == 0 || - strcmp(dca->arg[1], "iODBC") == 0) - { dca->id = TAB_ODBC; - dca->link = db_iodbc_open(dca, mode); - } - else if (strcmp(dca->arg[1], "MySQL") == 0) - { dca->id = TAB_MYSQL; - dca->link = db_mysql_open(dca, mode); - } - else - xprintf("Invalid table driver `%s'\n", dca->arg[1]); - if (dca->link == NULL) - error(mpl, "error on opening table %s", - mpl->stmt->u.tab->name); - return; -} - -int mpl_tab_drv_read(MPL *mpl) -{ TABDCA *dca = mpl->dca; - int ret; - switch (dca->id) - { case TAB_CSV: - ret = csv_read_record(dca, dca->link); - break; - case TAB_XBASE: - ret = dbf_read_record(dca, dca->link); - break; - case TAB_ODBC: - ret = db_iodbc_read(dca, dca->link); - break; - case TAB_MYSQL: - ret = db_mysql_read(dca, dca->link); - break; - default: - xassert(dca != dca); - } - if (ret > 0) - error(mpl, "error on reading data from table %s", - mpl->stmt->u.tab->name); - return ret; -} - -void mpl_tab_drv_write(MPL *mpl) -{ TABDCA *dca = mpl->dca; - int ret; - switch (dca->id) - { case TAB_CSV: - ret = csv_write_record(dca, dca->link); - break; - case TAB_XBASE: - ret = dbf_write_record(dca, dca->link); - break; - case TAB_ODBC: - ret = db_iodbc_write(dca, dca->link); - break; - case TAB_MYSQL: - ret = db_mysql_write(dca, dca->link); - break; - default: - xassert(dca != dca); - } - if (ret) - error(mpl, "error on writing data to table %s", - mpl->stmt->u.tab->name); - return; -} - -void mpl_tab_drv_close(MPL *mpl) -{ TABDCA *dca = mpl->dca; - int ret; - switch (dca->id) - { case TAB_CSV: - ret = csv_close_file(dca, dca->link); - break; - case TAB_XBASE: - ret = dbf_close_file(dca, dca->link); - break; - case TAB_ODBC: - ret = db_iodbc_close(dca, dca->link); - break; - case TAB_MYSQL: - ret = db_mysql_close(dca, dca->link); - break; - default: - xassert(dca != dca); - } - dca->id = 0; - dca->link = NULL; - if (ret) - error(mpl, "error on closing table %s", - mpl->stmt->u.tab->name); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpmps.c b/resources/3rdparty/glpk-4.53/src/glpmps.c deleted file mode 100644 index 7b45ff77f..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpmps.c +++ /dev/null @@ -1,1433 +0,0 @@ -/* glpmps.c (MPS format routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "misc.h" -#include "prob.h" - -#define xfprintf glp_format - -/*********************************************************************** -* NAME -* -* glp_init_mpscp - initialize MPS format control parameters -* -* SYNOPSIS -* -* void glp_init_mpscp(glp_mpscp *parm); -* -* DESCRIPTION -* -* The routine glp_init_mpscp initializes control parameters, which are -* used by the MPS input/output routines glp_read_mps and glp_write_mps, -* with default values. -* -* Default values of the control parameters are stored in the glp_mpscp -* structure, which the parameter parm points to. */ - -void glp_init_mpscp(glp_mpscp *parm) -{ parm->blank = '\0'; - parm->obj_name = NULL; - parm->tol_mps = 1e-12; - return; -} - -static void check_parm(const char *func, const glp_mpscp *parm) -{ /* check control parameters */ - if (!(0x00 <= parm->blank && parm->blank <= 0xFF) || - !(parm->blank == '\0' || isprint(parm->blank))) - xerror("%s: blank = 0x%02X; invalid parameter\n", - func, parm->blank); - if (!(parm->obj_name == NULL || strlen(parm->obj_name) <= 255)) - xerror("%s: obj_name = \"%.12s...\"; parameter too long\n", - func, parm->obj_name); - if (!(0.0 <= parm->tol_mps && parm->tol_mps < 1.0)) - xerror("%s: tol_mps = %g; invalid parameter\n", - func, parm->tol_mps); - return; -} - -/*********************************************************************** -* NAME -* -* glp_read_mps - read problem data in MPS format -* -* SYNOPSIS -* -* int glp_read_mps(glp_prob *P, int fmt, const glp_mpscp *parm, -* const char *fname); -* -* DESCRIPTION -* -* The routine glp_read_mps reads problem data in MPS format from a -* text file. -* -* The parameter fmt specifies the version of MPS format: -* -* GLP_MPS_DECK - fixed (ancient) MPS format; -* GLP_MPS_FILE - free (modern) MPS format. -* -* The parameter parm is a pointer to the structure glp_mpscp, which -* specifies control parameters used by the routine. If parm is NULL, -* the routine uses default settings. -* -* The character string fname specifies a name of the text file to be -* read. -* -* Note that before reading data the current content of the problem -* object is completely erased with the routine glp_erase_prob. -* -* RETURNS -* -* If the operation was successful, the routine glp_read_mps returns -* zero. Otherwise, it prints an error message and returns non-zero. */ - -struct csa -{ /* common storage area */ - glp_prob *P; - /* pointer to problem object */ - int deck; - /* MPS format (0 - free, 1 - fixed) */ - const glp_mpscp *parm; - /* pointer to control parameters */ - const char *fname; - /* name of input MPS file */ - glp_file *fp; - /* stream assigned to input MPS file */ - jmp_buf jump; - /* label for go to in case of error */ - int recno; - /* current record (card) number */ - int recpos; - /* current record (card) position */ - int c; - /* current character */ - int fldno; - /* current field number */ - char field[255+1]; - /* current field content */ - int w80; - /* warning 'record must not be longer than 80 chars' issued */ - int wef; - /* warning 'extra fields detected beyond field 6' issued */ - int obj_row; - /* objective row number */ - void *work1, *work2, *work3; - /* working arrays */ -}; - -static void error(struct csa *csa, const char *fmt, ...) -{ /* print error message and terminate processing */ - va_list arg; - xprintf("%s:%d: ", csa->fname, csa->recno); - va_start(arg, fmt); - xvprintf(fmt, arg); - va_end(arg); - longjmp(csa->jump, 1); - /* no return */ -} - -static void warning(struct csa *csa, const char *fmt, ...) -{ /* print warning message and continue processing */ - va_list arg; - xprintf("%s:%d: warning: ", csa->fname, csa->recno); - va_start(arg, fmt); - xvprintf(fmt, arg); - va_end(arg); - return; -} - -static void read_char(struct csa *csa) -{ /* read next character */ - int c; - if (csa->c == '\n') - csa->recno++, csa->recpos = 0; - csa->recpos++; -read: c = glp_getc(csa->fp); - if (c < 0) - { if (glp_ioerr(csa->fp)) - error(csa, "read error - %s\n", get_err_msg()); - else if (csa->c == '\n') - error(csa, "unexpected end of file\n"); - else - { warning(csa, "missing final end of line\n"); - c = '\n'; - } - } - else if (c == '\n') - ; - else if (csa->c == '\r') - { c = '\r'; - goto badc; - } - else if (csa->deck && c == '\r') - { csa->c = '\r'; - goto read; - } - else if (c == ' ') - ; - else if (isspace(c)) - { if (csa->deck) -badc: error(csa, "in fixed MPS format white-space character 0x%02" - "X is not allowed\n", c); - c = ' '; - } - else if (iscntrl(c)) - error(csa, "invalid control character 0x%02X\n", c); - if (csa->deck && csa->recpos == 81 && c != '\n' && csa->w80 < 1) - { warning(csa, "in fixed MPS format record must not be longer th" - "an 80 characters\n"); - csa->w80++; - } - csa->c = c; - return; -} - -static int indicator(struct csa *csa, int name) -{ /* skip comment records and read possible indicator record */ - int ret; - /* reset current field number */ - csa->fldno = 0; -loop: /* read the very first character of the next record */ - xassert(csa->c == '\n'); - read_char(csa); - if (csa->c == ' ' || csa->c == '\n') - { /* data record */ - ret = 0; - } - else if (csa->c == '*') - { /* comment record */ - while (csa->c != '\n') - read_char(csa); - goto loop; - } - else - { /* indicator record */ - int len = 0; - while (csa->c != ' ' && csa->c != '\n' && len < 12) - { csa->field[len++] = (char)csa->c; - read_char(csa); - } - csa->field[len] = '\0'; - if (!(strcmp(csa->field, "NAME") == 0 || - strcmp(csa->field, "ROWS") == 0 || - strcmp(csa->field, "COLUMNS") == 0 || - strcmp(csa->field, "RHS") == 0 || - strcmp(csa->field, "RANGES") == 0 || - strcmp(csa->field, "BOUNDS") == 0 || - strcmp(csa->field, "ENDATA") == 0)) - error(csa, "invalid indicator record\n"); - if (!name) - { while (csa->c != '\n') - read_char(csa); - } - ret = 1; - } - return ret; -} - -static void read_field(struct csa *csa) -{ /* read next field of the current data record */ - csa->fldno++; - if (csa->deck) - { /* fixed MPS format */ - int beg, end, pos; - /* determine predefined field positions */ - if (csa->fldno == 1) - beg = 2, end = 3; - else if (csa->fldno == 2) - beg = 5, end = 12; - else if (csa->fldno == 3) - beg = 15, end = 22; - else if (csa->fldno == 4) - beg = 25, end = 36; - else if (csa->fldno == 5) - beg = 40, end = 47; - else if (csa->fldno == 6) - beg = 50, end = 61; - else - xassert(csa != csa); - /* skip blanks preceding the current field */ - if (csa->c != '\n') - { pos = csa->recpos; - while (csa->recpos < beg) - { if (csa->c == ' ') - ; - else if (csa->c == '\n') - break; - else - error(csa, "in fixed MPS format positions %d-%d must " - "be blank\n", pos, beg-1); - read_char(csa); - } - } - /* skip possible comment beginning in the field 3 or 5 */ - if ((csa->fldno == 3 || csa->fldno == 5) && csa->c == '$') - { while (csa->c != '\n') - read_char(csa); - } - /* read the current field */ - for (pos = beg; pos <= end; pos++) - { if (csa->c == '\n') break; - csa->field[pos-beg] = (char)csa->c; - read_char(csa); - } - csa->field[pos-beg] = '\0'; - strtrim(csa->field); - /* skip blanks following the last field */ - if (csa->fldno == 6 && csa->c != '\n') - { while (csa->recpos <= 72) - { if (csa->c == ' ') - ; - else if (csa->c == '\n') - break; - else - error(csa, "in fixed MPS format positions 62-72 must " - "be blank\n"); - read_char(csa); - } - while (csa->c != '\n') - read_char(csa); - } - } - else - { /* free MPS format */ - int len; - /* skip blanks preceding the current field */ - while (csa->c == ' ') - read_char(csa); - /* skip possible comment */ - if (csa->c == '$') - { while (csa->c != '\n') - read_char(csa); - } - /* read the current field */ - len = 0; - while (!(csa->c == ' ' || csa->c == '\n')) - { if (len == 255) - error(csa, "length of field %d exceeds 255 characters\n", - csa->fldno++); - csa->field[len++] = (char)csa->c; - read_char(csa); - } - csa->field[len] = '\0'; - /* skip anything following the last field (any extra fields - are considered to be comments) */ - if (csa->fldno == 6) - { while (csa->c == ' ') - read_char(csa); - if (csa->c != '$' && csa->c != '\n' && csa->wef < 1) - { warning(csa, "some extra field(s) detected beyond field " - "6; field(s) ignored\n"); - csa->wef++; - } - while (csa->c != '\n') - read_char(csa); - } - } - return; -} - -static void patch_name(struct csa *csa, char *name) -{ /* process embedded blanks in symbolic name */ - int blank = csa->parm->blank; - if (blank == '\0') - { /* remove emedded blanks */ - strspx(name); - } - else - { /* replace embedded blanks by specified character */ - for (; *name != '\0'; name++) - if (*name == ' ') *name = (char)blank; - } - return; -} - -static double read_number(struct csa *csa) -{ /* read next field and convert it to floating-point number */ - double x; - char *s; - /* read next field */ - read_field(csa); - xassert(csa->fldno == 4 || csa->fldno == 6); - if (csa->field[0] == '\0') - error(csa, "missing numeric value in field %d\n", csa->fldno); - /* skip initial spaces of the field */ - for (s = csa->field; *s == ' '; s++); - /* perform conversion */ - if (str2num(s, &x) != 0) - error(csa, "cannot convert `%s' to floating-point number\n", - s); - return x; -} - -static void skip_field(struct csa *csa) -{ /* read and skip next field (assumed to be blank) */ - read_field(csa); - if (csa->field[0] != '\0') - error(csa, "field %d must be blank\n", csa->fldno); - return; -} - -static void read_name(struct csa *csa) -{ /* read NAME indicator record */ - if (!(indicator(csa, 1) && strcmp(csa->field, "NAME") == 0)) - error(csa, "missing NAME indicator record\n"); - /* this indicator record looks like a data record; simulate that - fields 1 and 2 were read */ - csa->fldno = 2; - /* field 3: model name */ - read_field(csa), patch_name(csa, csa->field); - if (csa->field[0] == '\0') - warning(csa, "missing model name in field 3\n"); - else - glp_set_prob_name(csa->P, csa->field); - /* skip anything following field 3 */ - while (csa->c != '\n') - read_char(csa); - return; -} - -static void read_rows(struct csa *csa) -{ /* read ROWS section */ - int i, type; -loop: if (indicator(csa, 0)) goto done; - /* field 1: row type */ - read_field(csa), strspx(csa->field); - if (strcmp(csa->field, "N") == 0) - type = GLP_FR; - else if (strcmp(csa->field, "G") == 0) - type = GLP_LO; - else if (strcmp(csa->field, "L") == 0) - type = GLP_UP; - else if (strcmp(csa->field, "E") == 0) - type = GLP_FX; - else if (csa->field[0] == '\0') - error(csa, "missing row type in field 1\n"); - else - error(csa, "invalid row type in field 1\n"); - /* field 2: row name */ - read_field(csa), patch_name(csa, csa->field); - if (csa->field[0] == '\0') - error(csa, "missing row name in field 2\n"); - if (glp_find_row(csa->P, csa->field) != 0) - error(csa, "row `%s' multiply specified\n", csa->field); - i = glp_add_rows(csa->P, 1); - glp_set_row_name(csa->P, i, csa->field); - glp_set_row_bnds(csa->P, i, type, 0.0, 0.0); - /* fields 3, 4, 5, and 6 must be blank */ - skip_field(csa); - skip_field(csa); - skip_field(csa); - skip_field(csa); - goto loop; -done: return; -} - -static void read_columns(struct csa *csa) -{ /* read COLUMNS section */ - int i, j, f, len, kind = GLP_CV, *ind; - double aij, *val; - char name[255+1], *flag; - /* allocate working arrays */ - csa->work1 = ind = xcalloc(1+csa->P->m, sizeof(int)); - csa->work2 = val = xcalloc(1+csa->P->m, sizeof(double)); - csa->work3 = flag = xcalloc(1+csa->P->m, sizeof(char)); - memset(&flag[1], 0, csa->P->m); - /* no current column exists */ - j = 0, len = 0; -loop: if (indicator(csa, 0)) goto done; - /* field 1 must be blank */ - if (csa->deck) - { read_field(csa); - if (csa->field[0] != '\0') - error(csa, "field 1 must be blank\n"); - } - else - csa->fldno++; - /* field 2: column or kind name */ - read_field(csa), patch_name(csa, csa->field); - strcpy(name, csa->field); - /* field 3: row name or keyword 'MARKER' */ - read_field(csa), patch_name(csa, csa->field); - if (strcmp(csa->field, "'MARKER'") == 0) - { /* process kind data record */ - /* field 4 must be blank */ - if (csa->deck) - { read_field(csa); - if (csa->field[0] != '\0') - error(csa, "field 4 must be blank\n"); - } - else - csa->fldno++; - /* field 5: keyword 'INTORG' or 'INTEND' */ - read_field(csa), patch_name(csa, csa->field); - if (strcmp(csa->field, "'INTORG'") == 0) - kind = GLP_IV; - else if (strcmp(csa->field, "'INTEND'") == 0) - kind = GLP_CV; - else if (csa->field[0] == '\0') - error(csa, "missing keyword in field 5\n"); - else - error(csa, "invalid keyword in field 5\n"); - /* field 6 must be blank */ - skip_field(csa); - goto loop; - } - /* process column name specified in field 2 */ - if (name[0] == '\0') - { /* the same column as in previous data record */ - if (j == 0) - error(csa, "missing column name in field 2\n"); - } - else if (j != 0 && strcmp(name, csa->P->col[j]->name) == 0) - { /* the same column as in previous data record */ - xassert(j != 0); - } - else - { /* store the current column */ - if (j != 0) - { glp_set_mat_col(csa->P, j, len, ind, val); - while (len > 0) flag[ind[len--]] = 0; - } - /* create new column */ - if (glp_find_col(csa->P, name) != 0) - error(csa, "column `%s' multiply specified\n", name); - j = glp_add_cols(csa->P, 1); - glp_set_col_name(csa->P, j, name); - glp_set_col_kind(csa->P, j, kind); - if (kind == GLP_CV) - glp_set_col_bnds(csa->P, j, GLP_LO, 0.0, 0.0); - else if (kind == GLP_IV) - glp_set_col_bnds(csa->P, j, GLP_DB, 0.0, 1.0); - else - xassert(kind != kind); - } - /* process fields 3-4 and 5-6 */ - for (f = 3; f <= 5; f += 2) - { /* field 3 or 5: row name */ - if (f == 3) - { if (csa->field[0] == '\0') - error(csa, "missing row name in field 3\n"); - } - else - { read_field(csa), patch_name(csa, csa->field); - if (csa->field[0] == '\0') - { /* if field 5 is blank, field 6 also must be blank */ - skip_field(csa); - continue; - } - } - i = glp_find_row(csa->P, csa->field); - if (i == 0) - error(csa, "row `%s' not found\n", csa->field); - if (flag[i]) - error(csa, "duplicate coefficient in row `%s'\n", - csa->field); - /* field 4 or 6: coefficient value */ - aij = read_number(csa); - if (fabs(aij) < csa->parm->tol_mps) aij = 0.0; - len++, ind[len] = i, val[len] = aij, flag[i] = 1; - } - goto loop; -done: /* store the last column */ - if (j != 0) - glp_set_mat_col(csa->P, j, len, ind, val); - /* free working arrays */ - xfree(ind); - xfree(val); - xfree(flag); - csa->work1 = csa->work2 = csa->work3 = NULL; - return; -} - -static void read_rhs(struct csa *csa) -{ /* read RHS section */ - int i, f, v, type; - double rhs; - char name[255+1], *flag; - /* allocate working array */ - csa->work3 = flag = xcalloc(1+csa->P->m, sizeof(char)); - memset(&flag[1], 0, csa->P->m); - /* no current RHS vector exists */ - v = 0; -loop: if (indicator(csa, 0)) goto done; - /* field 1 must be blank */ - if (csa->deck) - { read_field(csa); - if (csa->field[0] != '\0') - error(csa, "field 1 must be blank\n"); - } - else - csa->fldno++; - /* field 2: RHS vector name */ - read_field(csa), patch_name(csa, csa->field); - if (csa->field[0] == '\0') - { /* the same RHS vector as in previous data record */ - if (v == 0) - { warning(csa, "missing RHS vector name in field 2\n"); - goto blnk; - } - } - else if (v != 0 && strcmp(csa->field, name) == 0) - { /* the same RHS vector as in previous data record */ - xassert(v != 0); - } - else -blnk: { /* new RHS vector */ - if (v != 0) - error(csa, "multiple RHS vectors not supported\n"); - v++; - strcpy(name, csa->field); - } - /* process fields 3-4 and 5-6 */ - for (f = 3; f <= 5; f += 2) - { /* field 3 or 5: row name */ - read_field(csa), patch_name(csa, csa->field); - if (csa->field[0] == '\0') - { if (f == 3) - error(csa, "missing row name in field 3\n"); - else - { /* if field 5 is blank, field 6 also must be blank */ - skip_field(csa); - continue; - } - } - i = glp_find_row(csa->P, csa->field); - if (i == 0) - error(csa, "row `%s' not found\n", csa->field); - if (flag[i]) - error(csa, "duplicate right-hand side for row `%s'\n", - csa->field); - /* field 4 or 6: right-hand side value */ - rhs = read_number(csa); - if (fabs(rhs) < csa->parm->tol_mps) rhs = 0.0; - type = csa->P->row[i]->type; - if (type == GLP_FR) - { if (i == csa->obj_row) - glp_set_obj_coef(csa->P, 0, rhs); - else if (rhs != 0.0) - warning(csa, "non-zero right-hand side for free row `%s'" - " ignored\n", csa->P->row[i]->name); - } - else - glp_set_row_bnds(csa->P, i, type, rhs, rhs); - flag[i] = 1; - } - goto loop; -done: /* free working array */ - xfree(flag); - csa->work3 = NULL; - return; -} - -static void read_ranges(struct csa *csa) -{ /* read RANGES section */ - int i, f, v, type; - double rhs, rng; - char name[255+1], *flag; - /* allocate working array */ - csa->work3 = flag = xcalloc(1+csa->P->m, sizeof(char)); - memset(&flag[1], 0, csa->P->m); - /* no current RANGES vector exists */ - v = 0; -loop: if (indicator(csa, 0)) goto done; - /* field 1 must be blank */ - if (csa->deck) - { read_field(csa); - if (csa->field[0] != '\0') - error(csa, "field 1 must be blank\n"); - } - else - csa->fldno++; - /* field 2: RANGES vector name */ - read_field(csa), patch_name(csa, csa->field); - if (csa->field[0] == '\0') - { /* the same RANGES vector as in previous data record */ - if (v == 0) - { warning(csa, "missing RANGES vector name in field 2\n"); - goto blnk; - } - } - else if (v != 0 && strcmp(csa->field, name) == 0) - { /* the same RANGES vector as in previous data record */ - xassert(v != 0); - } - else -blnk: { /* new RANGES vector */ - if (v != 0) - error(csa, "multiple RANGES vectors not supported\n"); - v++; - strcpy(name, csa->field); - } - /* process fields 3-4 and 5-6 */ - for (f = 3; f <= 5; f += 2) - { /* field 3 or 5: row name */ - read_field(csa), patch_name(csa, csa->field); - if (csa->field[0] == '\0') - { if (f == 3) - error(csa, "missing row name in field 3\n"); - else - { /* if field 5 is blank, field 6 also must be blank */ - skip_field(csa); - continue; - } - } - i = glp_find_row(csa->P, csa->field); - if (i == 0) - error(csa, "row `%s' not found\n", csa->field); - if (flag[i]) - error(csa, "duplicate range for row `%s'\n", csa->field); - /* field 4 or 6: range value */ - rng = read_number(csa); - if (fabs(rng) < csa->parm->tol_mps) rng = 0.0; - type = csa->P->row[i]->type; - if (type == GLP_FR) - warning(csa, "range for free row `%s' ignored\n", - csa->P->row[i]->name); - else if (type == GLP_LO) - { rhs = csa->P->row[i]->lb; - glp_set_row_bnds(csa->P, i, rhs == 0.0 ? GLP_FX : GLP_DB, - rhs, rhs + fabs(rng)); - } - else if (type == GLP_UP) - { rhs = csa->P->row[i]->ub; - glp_set_row_bnds(csa->P, i, rhs == 0.0 ? GLP_FX : GLP_DB, - rhs - fabs(rng), rhs); - } - else if (type == GLP_FX) - { rhs = csa->P->row[i]->lb; - if (rng > 0.0) - glp_set_row_bnds(csa->P, i, GLP_DB, rhs, rhs + rng); - else if (rng < 0.0) - glp_set_row_bnds(csa->P, i, GLP_DB, rhs + rng, rhs); - } - else - xassert(type != type); - flag[i] = 1; - } - goto loop; -done: /* free working array */ - xfree(flag); - csa->work3 = NULL; - return; -} - -static void read_bounds(struct csa *csa) -{ /* read BOUNDS section */ - GLPCOL *col; - int j, v, mask, data; - double bnd, lb, ub; - char type[2+1], name[255+1], *flag; - /* allocate working array */ - csa->work3 = flag = xcalloc(1+csa->P->n, sizeof(char)); - memset(&flag[1], 0, csa->P->n); - /* no current BOUNDS vector exists */ - v = 0; -loop: if (indicator(csa, 0)) goto done; - /* field 1: bound type */ - read_field(csa); - if (strcmp(csa->field, "LO") == 0) - mask = 0x01, data = 1; - else if (strcmp(csa->field, "UP") == 0) - mask = 0x10, data = 1; - else if (strcmp(csa->field, "FX") == 0) - mask = 0x11, data = 1; - else if (strcmp(csa->field, "FR") == 0) - mask = 0x11, data = 0; - else if (strcmp(csa->field, "MI") == 0) - mask = 0x01, data = 0; - else if (strcmp(csa->field, "PL") == 0) - mask = 0x10, data = 0; - else if (strcmp(csa->field, "LI") == 0) - mask = 0x01, data = 1; - else if (strcmp(csa->field, "UI") == 0) - mask = 0x10, data = 1; - else if (strcmp(csa->field, "BV") == 0) - mask = 0x11, data = 0; - else if (csa->field[0] == '\0') - error(csa, "missing bound type in field 1\n"); - else - error(csa, "invalid bound type in field 1\n"); - strcpy(type, csa->field); - /* field 2: BOUNDS vector name */ - read_field(csa), patch_name(csa, csa->field); - if (csa->field[0] == '\0') - { /* the same BOUNDS vector as in previous data record */ - if (v == 0) - { warning(csa, "missing BOUNDS vector name in field 2\n"); - goto blnk; - } - } - else if (v != 0 && strcmp(csa->field, name) == 0) - { /* the same BOUNDS vector as in previous data record */ - xassert(v != 0); - } - else -blnk: { /* new BOUNDS vector */ - if (v != 0) - error(csa, "multiple BOUNDS vectors not supported\n"); - v++; - strcpy(name, csa->field); - } - /* field 3: column name */ - read_field(csa), patch_name(csa, csa->field); - if (csa->field[0] == '\0') - error(csa, "missing column name in field 3\n"); - j = glp_find_col(csa->P, csa->field); - if (j == 0) - error(csa, "column `%s' not found\n", csa->field); - if ((flag[j] & mask) == 0x01) - error(csa, "duplicate lower bound for column `%s'\n", - csa->field); - if ((flag[j] & mask) == 0x10) - error(csa, "duplicate upper bound for column `%s'\n", - csa->field); - xassert((flag[j] & mask) == 0x00); - /* field 4: bound value */ - if (data) - { bnd = read_number(csa); - if (fabs(bnd) < csa->parm->tol_mps) bnd = 0.0; - } - else - read_field(csa), bnd = 0.0; - /* get current column bounds */ - col = csa->P->col[j]; - if (col->type == GLP_FR) - lb = -DBL_MAX, ub = +DBL_MAX; - else if (col->type == GLP_LO) - lb = col->lb, ub = +DBL_MAX; - else if (col->type == GLP_UP) - lb = -DBL_MAX, ub = col->ub; - else if (col->type == GLP_DB) - lb = col->lb, ub = col->ub; - else if (col->type == GLP_FX) - lb = ub = col->lb; - else - xassert(col != col); - /* change column bounds */ - if (strcmp(type, "LO") == 0) - lb = bnd; - else if (strcmp(type, "UP") == 0) - ub = bnd; - else if (strcmp(type, "FX") == 0) - lb = ub = bnd; - else if (strcmp(type, "FR") == 0) - lb = -DBL_MAX, ub = +DBL_MAX; - else if (strcmp(type, "MI") == 0) - lb = -DBL_MAX; - else if (strcmp(type, "PL") == 0) - ub = +DBL_MAX; - else if (strcmp(type, "LI") == 0) - { glp_set_col_kind(csa->P, j, GLP_IV); - lb = ceil(bnd); -#if 1 /* 16/VII-2013 */ - /* if column upper bound has not been explicitly specified, - take it as +inf */ - if (!(flag[j] & 0x10)) - ub = +DBL_MAX; -#endif - } - else if (strcmp(type, "UI") == 0) - { glp_set_col_kind(csa->P, j, GLP_IV); - ub = floor(bnd); - } - else if (strcmp(type, "BV") == 0) - { glp_set_col_kind(csa->P, j, GLP_IV); - lb = 0.0, ub = 1.0; - } - else - xassert(type != type); - /* set new column bounds */ - if (lb == -DBL_MAX && ub == +DBL_MAX) - glp_set_col_bnds(csa->P, j, GLP_FR, lb, ub); - else if (ub == +DBL_MAX) - glp_set_col_bnds(csa->P, j, GLP_LO, lb, ub); - else if (lb == -DBL_MAX) - glp_set_col_bnds(csa->P, j, GLP_UP, lb, ub); - else if (lb != ub) - glp_set_col_bnds(csa->P, j, GLP_DB, lb, ub); - else - glp_set_col_bnds(csa->P, j, GLP_FX, lb, ub); - flag[j] |= (char)mask; - /* fields 5 and 6 must be blank */ - skip_field(csa); - skip_field(csa); - goto loop; -done: /* free working array */ - xfree(flag); - csa->work3 = NULL; - return; -} - -int glp_read_mps(glp_prob *P, int fmt, const glp_mpscp *parm, - const char *fname) -{ /* read problem data in MPS format */ - glp_mpscp _parm; - struct csa _csa, *csa = &_csa; - int ret; - xprintf("Reading problem data from `%s'...\n", fname); - if (!(fmt == GLP_MPS_DECK || fmt == GLP_MPS_FILE)) - xerror("glp_read_mps: fmt = %d; invalid parameter\n", fmt); - if (parm == NULL) - glp_init_mpscp(&_parm), parm = &_parm; - /* check control parameters */ - check_parm("glp_read_mps", parm); - /* initialize common storage area */ - csa->P = P; - csa->deck = (fmt == GLP_MPS_DECK); - csa->parm = parm; - csa->fname = fname; - csa->fp = NULL; - if (setjmp(csa->jump)) - { ret = 1; - goto done; - } - csa->recno = csa->recpos = 0; - csa->c = '\n'; - csa->fldno = 0; - csa->field[0] = '\0'; - csa->w80 = csa->wef = 0; - csa->obj_row = 0; - csa->work1 = csa->work2 = csa->work3 = NULL; - /* erase problem object */ - glp_erase_prob(P); - glp_create_index(P); - /* open input MPS file */ - csa->fp = glp_open(fname, "r"); - if (csa->fp == NULL) - { xprintf("Unable to open `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - /* read NAME indicator record */ - read_name(csa); - if (P->name != NULL) - xprintf("Problem: %s\n", P->name); - /* read ROWS section */ - if (!(indicator(csa, 0) && strcmp(csa->field, "ROWS") == 0)) - error(csa, "missing ROWS indicator record\n"); - read_rows(csa); - /* determine objective row */ - if (parm->obj_name == NULL || parm->obj_name[0] == '\0') - { /* use the first row of N type */ - int i; - for (i = 1; i <= P->m; i++) - { if (P->row[i]->type == GLP_FR) - { csa->obj_row = i; - break; - } - } - if (csa->obj_row == 0) - warning(csa, "unable to determine objective row\n"); - } - else - { /* use a row with specified name */ - int i; - for (i = 1; i <= P->m; i++) - { xassert(P->row[i]->name != NULL); - if (strcmp(parm->obj_name, P->row[i]->name) == 0) - { csa->obj_row = i; - break; - } - } - if (csa->obj_row == 0) - error(csa, "objective row `%s' not found\n", - parm->obj_name); - } - if (csa->obj_row != 0) - { glp_set_obj_name(P, P->row[csa->obj_row]->name); - xprintf("Objective: %s\n", P->obj); - } - /* read COLUMNS section */ - if (strcmp(csa->field, "COLUMNS") != 0) - error(csa, "missing COLUMNS indicator record\n"); - read_columns(csa); - /* set objective coefficients */ - if (csa->obj_row != 0) - { GLPAIJ *aij; - for (aij = P->row[csa->obj_row]->ptr; aij != NULL; aij = - aij->r_next) glp_set_obj_coef(P, aij->col->j, aij->val); - } - /* read optional RHS section */ - if (strcmp(csa->field, "RHS") == 0) - read_rhs(csa); - /* read optional RANGES section */ - if (strcmp(csa->field, "RANGES") == 0) - read_ranges(csa); - /* read optional BOUNDS section */ - if (strcmp(csa->field, "BOUNDS") == 0) - read_bounds(csa); - /* read ENDATA indicator record */ - if (strcmp(csa->field, "ENDATA") != 0) - error(csa, "invalid use of %s indicator record\n", - csa->field); -#if 1 /* 08/VIII-2013 */ - /* remove free rows */ - { int i, nrs, *num; - num = talloc(1+P->m, int); - nrs = 0; - for (i = 1; i <= P->m; i++) - { if (P->row[i]->type == GLP_FR) - num[++nrs] = i; - } - if (nrs > 0) - { glp_del_rows(P, nrs, num); - if (nrs == 1) - xprintf("One free row was removed\n"); - else - xprintf("%d free rows were removed\n", nrs); - } - tfree(num); - } -#endif - /* print some statistics */ - xprintf("%d row%s, %d column%s, %d non-zero%s\n", - P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s", - P->nnz, P->nnz == 1 ? "" : "s"); - if (glp_get_num_int(P) > 0) - { int ni = glp_get_num_int(P); - int nb = glp_get_num_bin(P); - if (ni == 1) - { if (nb == 0) - xprintf("One variable is integer\n"); - else - xprintf("One variable is binary\n"); - } - else - { xprintf("%d integer variables, ", ni); - if (nb == 0) - xprintf("none"); - else if (nb == 1) - xprintf("one"); - else if (nb == ni) - xprintf("all"); - else - xprintf("%d", nb); - xprintf(" of which %s binary\n", nb == 1 ? "is" : "are"); - } - } - xprintf("%d records were read\n", csa->recno); - /* problem data has been successfully read */ - glp_delete_index(P); - glp_sort_matrix(P); - ret = 0; -done: if (csa->fp != NULL) glp_close(csa->fp); - if (csa->work1 != NULL) xfree(csa->work1); - if (csa->work2 != NULL) xfree(csa->work2); - if (csa->work3 != NULL) xfree(csa->work3); - if (ret != 0) glp_erase_prob(P); - return ret; -} - -/*********************************************************************** -* NAME -* -* glp_write_mps - write problem data in MPS format -* -* SYNOPSIS -* -* int glp_write_mps(glp_prob *P, int fmt, const glp_mpscp *parm, -* const char *fname); -* -* DESCRIPTION -* -* The routine glp_write_mps writes problem data in MPS format to a -* text file. -* -* The parameter fmt specifies the version of MPS format: -* -* GLP_MPS_DECK - fixed (ancient) MPS format; -* GLP_MPS_FILE - free (modern) MPS format. -* -* The parameter parm is a pointer to the structure glp_mpscp, which -* specifies control parameters used by the routine. If parm is NULL, -* the routine uses default settings. -* -* The character string fname specifies a name of the text file to be -* written. -* -* RETURNS -* -* If the operation was successful, the routine glp_read_mps returns -* zero. Otherwise, it prints an error message and returns non-zero. */ - -#define csa csa1 - -struct csa -{ /* common storage area */ - glp_prob *P; - /* pointer to problem object */ - int deck; - /* MPS format (0 - free, 1 - fixed) */ - const glp_mpscp *parm; - /* pointer to control parameters */ - char field[255+1]; - /* field buffer */ -}; - -static char *mps_name(struct csa *csa) -{ /* make problem name */ - char *f; - if (csa->P->name == NULL) - csa->field[0] = '\0'; - else if (csa->deck) - { strncpy(csa->field, csa->P->name, 8); - csa->field[8] = '\0'; - } - else - strcpy(csa->field, csa->P->name); - for (f = csa->field; *f != '\0'; f++) - if (*f == ' ') *f = '_'; - return csa->field; -} - -static char *row_name(struct csa *csa, int i) -{ /* make i-th row name */ - char *f; - xassert(0 <= i && i <= csa->P->m); - if (i == 0 || csa->P->row[i]->name == NULL || - csa->deck && strlen(csa->P->row[i]->name) > 8) - sprintf(csa->field, "R%07d", i); - else - { strcpy(csa->field, csa->P->row[i]->name); - for (f = csa->field; *f != '\0'; f++) - if (*f == ' ') *f = '_'; - } - return csa->field; -} - -static char *col_name(struct csa *csa, int j) -{ /* make j-th column name */ - char *f; - xassert(1 <= j && j <= csa->P->n); - if (csa->P->col[j]->name == NULL || - csa->deck && strlen(csa->P->col[j]->name) > 8) - sprintf(csa->field, "C%07d", j); - else - { strcpy(csa->field, csa->P->col[j]->name); - for (f = csa->field; *f != '\0'; f++) - if (*f == ' ') *f = '_'; - } - return csa->field; -} - -static char *mps_numb(struct csa *csa, double val) -{ /* format floating-point number */ - int dig; - char *exp; - for (dig = 12; dig >= 6; dig--) - { if (val != 0.0 && fabs(val) < 0.002) - sprintf(csa->field, "%.*E", dig-1, val); - else - sprintf(csa->field, "%.*G", dig, val); - exp = strchr(csa->field, 'E'); - if (exp != NULL) - sprintf(exp+1, "%d", atoi(exp+1)); - if (strlen(csa->field) <= 12) break; - } - xassert(strlen(csa->field) <= 12); - return csa->field; -} - -int glp_write_mps(glp_prob *P, int fmt, const glp_mpscp *parm, - const char *fname) -{ /* write problem data in MPS format */ - glp_mpscp _parm; - struct csa _csa, *csa = &_csa; - glp_file *fp; - int out_obj, one_col = 0, empty = 0; - int i, j, recno, marker, count, gap, ret; - xprintf("Writing problem data to `%s'...\n", fname); - if (!(fmt == GLP_MPS_DECK || fmt == GLP_MPS_FILE)) - xerror("glp_write_mps: fmt = %d; invalid parameter\n", fmt); - if (parm == NULL) - glp_init_mpscp(&_parm), parm = &_parm; - /* check control parameters */ - check_parm("glp_write_mps", parm); - /* initialize common storage area */ - csa->P = P; - csa->deck = (fmt == GLP_MPS_DECK); - csa->parm = parm; - /* create output MPS file */ - fp = glp_open(fname, "w"), recno = 0; - if (fp == NULL) - { xprintf("Unable to create `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - /* write comment records */ - xfprintf(fp, "* %-*s%s\n", P->name == NULL ? 1 : 12, "Problem:", - P->name == NULL ? "" : P->name), recno++; - xfprintf(fp, "* %-12s%s\n", "Class:", glp_get_num_int(P) == 0 ? - "LP" : "MIP"), recno++; - xfprintf(fp, "* %-12s%d\n", "Rows:", P->m), recno++; - if (glp_get_num_int(P) == 0) - xfprintf(fp, "* %-12s%d\n", "Columns:", P->n), recno++; - else - xfprintf(fp, "* %-12s%d (%d integer, %d binary)\n", - "Columns:", P->n, glp_get_num_int(P), glp_get_num_bin(P)), - recno++; - xfprintf(fp, "* %-12s%d\n", "Non-zeros:", P->nnz), recno++; - xfprintf(fp, "* %-12s%s\n", "Format:", csa->deck ? "Fixed MPS" : - "Free MPS"), recno++; - xfprintf(fp, "*\n", recno++); - /* write NAME indicator record */ - xfprintf(fp, "NAME%*s%s\n", - P->name == NULL ? 0 : csa->deck ? 10 : 1, "", mps_name(csa)), - recno++; -#if 1 - /* determine whether to write the objective row */ - out_obj = 1; - for (i = 1; i <= P->m; i++) - { if (P->row[i]->type == GLP_FR) - { out_obj = 0; - break; - } - } -#endif - /* write ROWS section */ - xfprintf(fp, "ROWS\n"), recno++; - for (i = (out_obj ? 0 : 1); i <= P->m; i++) - { int type; - type = (i == 0 ? GLP_FR : P->row[i]->type); - if (type == GLP_FR) - type = 'N'; - else if (type == GLP_LO) - type = 'G'; - else if (type == GLP_UP) - type = 'L'; - else if (type == GLP_DB || type == GLP_FX) - type = 'E'; - else - xassert(type != type); - xfprintf(fp, " %c%*s%s\n", type, csa->deck ? 2 : 1, "", - row_name(csa, i)), recno++; - } - /* write COLUMNS section */ - xfprintf(fp, "COLUMNS\n"), recno++; - marker = 0; - for (j = 1; j <= P->n; j++) - { GLPAIJ cj, *aij; - int kind; - kind = P->col[j]->kind; - if (kind == GLP_CV) - { if (marker % 2 == 1) - { /* close current integer block */ - marker++; - xfprintf(fp, "%*sM%07d%*s'MARKER'%*s'INTEND'\n", - csa->deck ? 4 : 1, "", marker, csa->deck ? 2 : 1, "", - csa->deck ? 17 : 1, ""), recno++; - } - } - else if (kind == GLP_IV) - { if (marker % 2 == 0) - { /* open new integer block */ - marker++; - xfprintf(fp, "%*sM%07d%*s'MARKER'%*s'INTORG'\n", - csa->deck ? 4 : 1, "", marker, csa->deck ? 2 : 1, "", - csa->deck ? 17 : 1, ""), recno++; - } - } - else - xassert(kind != kind); - if (out_obj && P->col[j]->coef != 0.0) - { /* make fake objective coefficient */ - aij = &cj; - aij->row = NULL; - aij->val = P->col[j]->coef; - aij->c_next = P->col[j]->ptr; - } - else - aij = P->col[j]->ptr; -#if 1 /* FIXME */ - if (aij == NULL) - { /* empty column */ - empty++; - xfprintf(fp, "%*s%-*s", csa->deck ? 4 : 1, "", - csa->deck ? 8 : 1, col_name(csa, j)); - /* we need a row */ - xassert(P->m > 0); - xfprintf(fp, "%*s%-*s", - csa->deck ? 2 : 1, "", csa->deck ? 8 : 1, - row_name(csa, 1)); - xfprintf(fp, "%*s0%*s$ empty column\n", - csa->deck ? 13 : 1, "", csa->deck ? 3 : 1, ""), recno++; - } -#endif - count = 0; - for (aij = aij; aij != NULL; aij = aij->c_next) - { if (one_col || count % 2 == 0) - xfprintf(fp, "%*s%-*s", csa->deck ? 4 : 1, "", - csa->deck ? 8 : 1, col_name(csa, j)); - gap = (one_col || count % 2 == 0 ? 2 : 3); - xfprintf(fp, "%*s%-*s", - csa->deck ? gap : 1, "", csa->deck ? 8 : 1, - row_name(csa, aij->row == NULL ? 0 : aij->row->i)); - xfprintf(fp, "%*s%*s", - csa->deck ? 2 : 1, "", csa->deck ? 12 : 1, - mps_numb(csa, aij->val)), count++; - if (one_col || count % 2 == 0) - xfprintf(fp, "\n"), recno++; - } - if (!(one_col || count % 2 == 0)) - xfprintf(fp, "\n"), recno++; - } - if (marker % 2 == 1) - { /* close last integer block */ - marker++; - xfprintf(fp, "%*sM%07d%*s'MARKER'%*s'INTEND'\n", - csa->deck ? 4 : 1, "", marker, csa->deck ? 2 : 1, "", - csa->deck ? 17 : 1, ""), recno++; - } -#if 1 - if (empty > 0) - xprintf("Warning: problem has %d empty column(s)\n", empty); -#endif - /* write RHS section */ - xfprintf(fp, "RHS\n"), recno++; - count = 0; - for (i = (out_obj ? 0 : 1); i <= P->m; i++) - { int type; - double rhs; - if (i == 0) - rhs = P->c0; - else - { type = P->row[i]->type; - if (type == GLP_FR) - rhs = 0.0; - else if (type == GLP_LO) - rhs = P->row[i]->lb; - else if (type == GLP_UP) - rhs = P->row[i]->ub; - else if (type == GLP_DB || type == GLP_FX) - rhs = P->row[i]->lb; - else - xassert(type != type); - } - if (rhs != 0.0) - { if (one_col || count % 2 == 0) - xfprintf(fp, "%*s%-*s", csa->deck ? 4 : 1, "", - csa->deck ? 8 : 1, "RHS1"); - gap = (one_col || count % 2 == 0 ? 2 : 3); - xfprintf(fp, "%*s%-*s", - csa->deck ? gap : 1, "", csa->deck ? 8 : 1, - row_name(csa, i)); - xfprintf(fp, "%*s%*s", - csa->deck ? 2 : 1, "", csa->deck ? 12 : 1, - mps_numb(csa, rhs)), count++; - if (one_col || count % 2 == 0) - xfprintf(fp, "\n"), recno++; - } - } - if (!(one_col || count % 2 == 0)) - xfprintf(fp, "\n"), recno++; - /* write RANGES section */ - for (i = P->m; i >= 1; i--) - if (P->row[i]->type == GLP_DB) break; - if (i == 0) goto bnds; - xfprintf(fp, "RANGES\n"), recno++; - count = 0; - for (i = 1; i <= P->m; i++) - { if (P->row[i]->type == GLP_DB) - { if (one_col || count % 2 == 0) - xfprintf(fp, "%*s%-*s", csa->deck ? 4 : 1, "", - csa->deck ? 8 : 1, "RNG1"); - gap = (one_col || count % 2 == 0 ? 2 : 3); - xfprintf(fp, "%*s%-*s", - csa->deck ? gap : 1, "", csa->deck ? 8 : 1, - row_name(csa, i)); - xfprintf(fp, "%*s%*s", - csa->deck ? 2 : 1, "", csa->deck ? 12 : 1, - mps_numb(csa, P->row[i]->ub - P->row[i]->lb)), count++; - if (one_col || count % 2 == 0) - xfprintf(fp, "\n"), recno++; - } - } - if (!(one_col || count % 2 == 0)) - xfprintf(fp, "\n"), recno++; -bnds: /* write BOUNDS section */ - for (j = P->n; j >= 1; j--) - if (!(P->col[j]->kind == GLP_CV && - P->col[j]->type == GLP_LO && P->col[j]->lb == 0.0)) - break; - if (j == 0) goto endt; - xfprintf(fp, "BOUNDS\n"), recno++; - for (j = 1; j <= P->n; j++) - { int type, data[2]; - double bnd[2]; - char *spec[2]; - spec[0] = spec[1] = NULL; - type = P->col[j]->type; - if (type == GLP_FR) - spec[0] = "FR", data[0] = 0; - else if (type == GLP_LO) - { if (P->col[j]->lb != 0.0) - spec[0] = "LO", data[0] = 1, bnd[0] = P->col[j]->lb; - if (P->col[j]->kind == GLP_IV) - spec[1] = "PL", data[1] = 0; - } - else if (type == GLP_UP) - { spec[0] = "MI", data[0] = 0; - spec[1] = "UP", data[1] = 1, bnd[1] = P->col[j]->ub; - } - else if (type == GLP_DB) - { if (P->col[j]->lb != 0.0) - spec[0] = "LO", data[0] = 1, bnd[0] = P->col[j]->lb; - spec[1] = "UP", data[1] = 1, bnd[1] = P->col[j]->ub; - } - else if (type == GLP_FX) - spec[0] = "FX", data[0] = 1, bnd[0] = P->col[j]->lb; - else - xassert(type != type); - for (i = 0; i <= 1; i++) - { if (spec[i] != NULL) - { xfprintf(fp, " %s %-*s%*s%-*s", spec[i], - csa->deck ? 8 : 1, "BND1", csa->deck ? 2 : 1, "", - csa->deck ? 8 : 1, col_name(csa, j)); - if (data[i]) - xfprintf(fp, "%*s%*s", csa->deck ? 2 : 1, "", - csa->deck ? 12 : 1, mps_numb(csa, bnd[i])); - xfprintf(fp, "\n"), recno++; - } - } - } -endt: /* write ENDATA indicator record */ - xfprintf(fp, "ENDATA\n"), recno++; -#if 0 /* FIXME */ - xfflush(fp); -#endif - if (glp_ioerr(fp)) - { xprintf("Write error on `%s' - %s\n", fname, get_err_msg()); - ret = 1; - goto done; - } - /* problem data has been successfully written */ - xprintf("%d records were written\n", recno); - ret = 0; -done: if (fp != NULL) glp_close(fp); - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpnet03.c b/resources/3rdparty/glpk-4.53/src/glpnet03.c deleted file mode 100644 index 9ddf1cb75..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpnet03.c +++ /dev/null @@ -1,1020 +0,0 @@ -/* glpnet03.c (Klingman's network problem generator) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* This code is the result of translation of the Fortran program NETGEN -* developed by Dr. Darwin Klingman, which is publically available from -* NETLIB at . -* -* The translation was made by Andrew Makhorin . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpk.h" - -/*********************************************************************** -* NAME -* -* glp_netgen - Klingman's network problem generator -* -* SYNOPSIS -* -* int glp_netgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, -* const int parm[1+15]); -* -* DESCRIPTION -* -* The routine glp_netgen is a network problem generator developed by -* Dr. Darwin Klingman. It can create capacitated and uncapacitated -* minimum cost flow (or transshipment), transportation, and assignment -* problems. -* -* The parameter G specifies the graph object, to which the generated -* problem data have to be stored. Note that on entry the graph object -* is erased with the routine glp_erase_graph. -* -* The parameter v_rhs specifies an offset of the field of type double -* in the vertex data block, to which the routine stores the supply or -* demand value. If v_rhs < 0, the value is not stored. -* -* The parameter a_cap specifies an offset of the field of type double -* in the arc data block, to which the routine stores the arc capacity. -* If a_cap < 0, the capacity is not stored. -* -* The parameter a_cost specifies an offset of the field of type double -* in the arc data block, to which the routine stores the per-unit cost -* if the arc flow. If a_cost < 0, the cost is not stored. -* -* The array parm contains description of the network to be generated: -* -* parm[0] not used -* parm[1] (iseed) 8-digit positive random number seed -* parm[2] (nprob) 8-digit problem id number -* parm[3] (nodes) total number of nodes -* parm[4] (nsorc) total number of source nodes (including -* transshipment nodes) -* parm[5] (nsink) total number of sink nodes (including -* transshipment nodes) -* parm[6] (iarcs) number of arcs -* parm[7] (mincst) minimum cost for arcs -* parm[8] (maxcst) maximum cost for arcs -* parm[9] (itsup) total supply -* parm[10] (ntsorc) number of transshipment source nodes -* parm[11] (ntsink) number of transshipment sink nodes -* parm[12] (iphic) percentage of skeleton arcs to be given -* the maximum cost -* parm[13] (ipcap) percentage of arcs to be capacitated -* parm[14] (mincap) minimum upper bound for capacitated arcs -* parm[15] (maxcap) maximum upper bound for capacitated arcs -* -* The routine generates a transportation problem if: -* -* nsorc + nsink = nodes, ntsorc = 0, and ntsink = 0. -* -* The routine generates an assignment problem if the requirements for -* a transportation problem are met and: -* -* nsorc = nsink and itsup = nsorc. -* -* RETURNS -* -* If the instance was successfully generated, the routine glp_netgen -* returns zero; otherwise, if specified parameters are inconsistent, -* the routine returns a non-zero error code. -* -* REFERENCES -* -* D.Klingman, A.Napier, and J.Stutz. NETGEN: A program for generating -* large scale capacitated assignment, transportation, and minimum cost -* flow networks. Management Science 20 (1974), 814-20. */ - -struct csa -{ /* common storage area */ - glp_graph *G; - int v_rhs, a_cap, a_cost; - int nodes, iarcs, mincst, maxcst, itsup, nsorc, nsink, nonsor, - nfsink, narcs, nsort, nftsor, ipcap, mincap, maxcap, ktl, - nodlft, *ipred, *ihead, *itail, *iflag, *isup, *lsinks, mult, - modul, i15, i16, jran; -}; - -#define G (csa->G) -#define v_rhs (csa->v_rhs) -#define a_cap (csa->a_cap) -#define a_cost (csa->a_cost) -#define nodes (csa->nodes) -#define iarcs (csa->iarcs) -#define mincst (csa->mincst) -#define maxcst (csa->maxcst) -#define itsup (csa->itsup) -#define nsorc (csa->nsorc) -#define nsink (csa->nsink) -#define nonsor (csa->nonsor) -#define nfsink (csa->nfsink) -#define narcs (csa->narcs) -#define nsort (csa->nsort) -#define nftsor (csa->nftsor) -#define ipcap (csa->ipcap) -#define mincap (csa->mincap) -#define maxcap (csa->maxcap) -#define ktl (csa->ktl) -#define nodlft (csa->nodlft) -#if 0 -/* spent a day to find out this bug */ -#define ist (csa->ist) -#else -#define ist (ipred[0]) -#endif -#define ipred (csa->ipred) -#define ihead (csa->ihead) -#define itail (csa->itail) -#define iflag (csa->iflag) -#define isup (csa->isup) -#define lsinks (csa->lsinks) -#define mult (csa->mult) -#define modul (csa->modul) -#define i15 (csa->i15) -#define i16 (csa->i16) -#define jran (csa->jran) - -static void cresup(struct csa *csa); -static void chain(struct csa *csa, int lpick, int lsorc); -static void chnarc(struct csa *csa, int lsorc); -static void sort(struct csa *csa); -static void pickj(struct csa *csa, int it); -static void assign(struct csa *csa); -static void setran(struct csa *csa, int iseed); -static int iran(struct csa *csa, int ilow, int ihigh); - -int glp_netgen(glp_graph *G_, int _v_rhs, int _a_cap, int _a_cost, - const int parm[1+15]) -{ struct csa _csa, *csa = &_csa; - int iseed, nprob, ntsorc, ntsink, iphic, i, nskel, nltr, ltsink, - ntrans, npsink, nftr, npsorc, ntravl, ntrrem, lsorc, lpick, - nsksr, nsrchn, j, item, l, ks, k, ksp, li, n, ii, it, ih, icap, - jcap, icost, jcost, ret; - G = G_; - v_rhs = _v_rhs; - a_cap = _a_cap; - a_cost = _a_cost; - if (G != NULL) - { if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) - xerror("glp_netgen: v_rhs = %d; invalid offset\n", v_rhs); - if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) - xerror("glp_netgen: a_cap = %d; invalid offset\n", a_cap); - if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) - xerror("glp_netgen: a_cost = %d; invalid offset\n", a_cost); - } - /* Input the user's random number seed and fix it if - non-positive. */ - iseed = parm[1]; - nprob = parm[2]; - if (iseed <= 0) iseed = 13502460; - setran(csa, iseed); - /* Input the user's problem characteristics. */ - nodes = parm[3]; - nsorc = parm[4]; - nsink = parm[5]; - iarcs = parm[6]; - mincst = parm[7]; - maxcst = parm[8]; - itsup = parm[9]; - ntsorc = parm[10]; - ntsink = parm[11]; - iphic = parm[12]; - ipcap = parm[13]; - mincap = parm[14]; - maxcap = parm[15]; - /* Check the size of the problem. */ - if (!(10 <= nodes && nodes <= 100000)) - { ret = 1; - goto done; - } - /* Check user supplied parameters for consistency. */ - if (!(nsorc >= 0 && nsink >= 0 && nsorc + nsink <= nodes)) - { ret = 2; - goto done; - } - if (iarcs < 0) - { ret = 3; - goto done; - } - if (mincst > maxcst) - { ret = 4; - goto done; - } - if (itsup < 0) - { ret = 5; - goto done; - } - if (!(0 <= ntsorc && ntsorc <= nsorc)) - { ret = 6; - goto done; - } - if (!(0 <= ntsink && ntsink <= nsink)) - { ret = 7; - goto done; - } - if (!(0 <= iphic && iphic <= 100)) - { ret = 8; - goto done; - } - if (!(0 <= ipcap && ipcap <= 100)) - { ret = 9; - goto done; - } - if (mincap > maxcap) - { ret = 10; - goto done; - } - /* Initailize the graph object. */ - if (G != NULL) - { glp_erase_graph(G, G->v_size, G->a_size); - glp_add_vertices(G, nodes); - if (v_rhs >= 0) - { double zero = 0.0; - for (i = 1; i <= nodes; i++) - { glp_vertex *v = G->v[i]; - memcpy((char *)v->data + v_rhs, &zero, sizeof(double)); - } - } - } - /* Allocate working arrays. */ - ipred = xcalloc(1+nodes, sizeof(int)); - ihead = xcalloc(1+nodes, sizeof(int)); - itail = xcalloc(1+nodes, sizeof(int)); - iflag = xcalloc(1+nodes, sizeof(int)); - isup = xcalloc(1+nodes, sizeof(int)); - lsinks = xcalloc(1+nodes, sizeof(int)); - /* Print the problem documentation records. */ - if (G == NULL) - { xprintf("BEGIN\n"); - xprintf("NETGEN PROBLEM%8d%10s%10d NODES AND%10d ARCS\n", - nprob, "", nodes, iarcs); - xprintf("USER:%11d%11d%11d%11d%11d%11d\nDATA:%11d%11d%11d%11d%" - "11d%11d\n", iseed, nsorc, nsink, mincst, - maxcst, itsup, ntsorc, ntsink, iphic, ipcap, - mincap, maxcap); - } - else - glp_set_graph_name(G, "NETGEN"); - /* Set various constants used in the program. */ - narcs = 0; - nskel = 0; - nltr = nodes - nsink; - ltsink = nltr + ntsink; - ntrans = nltr - nsorc; - nfsink = nltr + 1; - nonsor = nodes - nsorc + ntsorc; - npsink = nsink - ntsink; - nodlft = nodes - nsink + ntsink; - nftr = nsorc + 1; - nftsor = nsorc - ntsorc + 1; - npsorc = nsorc - ntsorc; - /* Randomly distribute the supply among the source nodes. */ - if (npsorc + npsink == nodes && npsorc == npsink && - itsup == nsorc) - { assign(csa); - nskel = nsorc; - goto L390; - } - cresup(csa); - /* Print the supply records. */ - if (G == NULL) - { xprintf("SUPPLY\n"); - for (i = 1; i <= nsorc; i++) - xprintf("%6s%6d%18s%10d\n", "", i, "", isup[i]); - xprintf("ARCS\n"); - } - else - { if (v_rhs >= 0) - { for (i = 1; i <= nsorc; i++) - { double temp = (double)isup[i]; - glp_vertex *v = G->v[i]; - memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); - } - } - } - /* Make the sources point to themselves in ipred array. */ - for (i = 1; i <= nsorc; i++) - ipred[i] = i; - if (ntrans == 0) goto L170; - /* Chain the transshipment nodes together in the ipred array. */ - ist = nftr; - ipred[nltr] = 0; - for (i = nftr; i < nltr; i++) - ipred[i] = i+1; - /* Form even length chains for 60 percent of the transshipments.*/ - ntravl = 6 * ntrans / 10; - ntrrem = ntrans - ntravl; -L140: lsorc = 1; - while (ntravl != 0) - { lpick = iran(csa, 1, ntravl + ntrrem); - ntravl--; - chain(csa, lpick, lsorc); - if (lsorc == nsorc) goto L140; - lsorc++; - } - /* Add the remaining transshipments to the chains. */ - while (ntrrem != 0) - { - lpick = iran(csa, 1, ntrrem); - ntrrem--; - lsorc = iran(csa, 1, nsorc); - chain(csa, lpick, lsorc); - } -L170: /* Set all demands equal to zero. */ - for (i = nfsink; i <= nodes; i++) - ipred[i] = 0; - /* The following loop takes one chain at a time (through the use - of logic contained in the loop and calls to other routines) and - creates the remaining network arcs. */ - for (lsorc = 1; lsorc <= nsorc; lsorc++) - { chnarc(csa, lsorc); - for (i = nfsink; i <= nodes; i++) - iflag[i] = 0; - /* Choose the number of sinks to be hooked up to the current - chain. */ - if (ntrans != 0) - nsksr = (nsort * 2 * nsink) / ntrans; - else - nsksr = nsink / nsorc + 1; - if (nsksr < 2) nsksr = 2; - if (nsksr > nsink) nsksr = nsink; - nsrchn = nsort; - /* Randomly pick nsksr sinks and put their names in lsinks. */ - ktl = nsink; - for (j = 1; j <= nsksr; j++) - { item = iran(csa, 1, ktl); - ktl--; - for (l = nfsink; l <= nodes; l++) - { if (iflag[l] != 1) - { item--; - if (item == 0) goto L230; - } - } - break; -L230: lsinks[j] = l; - iflag[l] = 1; - } - /* If last source chain, add all sinks with zero demand to - lsinks list. */ - if (lsorc == nsorc) - { for (j = nfsink; j <= nodes; j++) - { if (ipred[j] == 0 && iflag[j] != 1) - { nsksr++; - lsinks[nsksr] = j; - iflag[j] = 1; - } - } - } - /* Create demands for group of sinks in lsinks. */ - ks = isup[lsorc] / nsksr; - k = ipred[lsorc]; - for (i = 1; i <= nsksr; i++) - { nsort++; - ksp = iran(csa, 1, ks); - j = iran(csa, 1, nsksr); - itail[nsort] = k; - li = lsinks[i]; - ihead[nsort] = li; - ipred[li] += ksp; - li = lsinks[j]; - ipred[li] += ks - ksp; - n = iran(csa, 1, nsrchn); - k = lsorc; - for (ii = 1; ii <= n; ii++) - k = ipred[k]; - } - li = lsinks[1]; - ipred[li] += isup[lsorc] - ks * nsksr; - nskel += nsort; - /* Sort the arcs in the chain from source lsorc using itail as - sort key. */ - sort(csa); - /* Print this part of skeleton and create the arcs for these - nodes. */ - i = 1; - itail[nsort+1] = 0; -L300: for (j = nftsor; j <= nodes; j++) - iflag[j] = 0; - ktl = nonsor - 1; - it = itail[i]; - iflag[it] = 1; -L320: ih = ihead[i]; - iflag[ih] = 1; - narcs++; - ktl--; - /* Determine if this skeleton arc should be capacitated. */ - icap = itsup; - jcap = iran(csa, 1, 100); - if (jcap <= ipcap) - { icap = isup[lsorc]; - if (mincap > icap) icap = mincap; - } - /* Determine if this skeleton arc should have the maximum - cost. */ - icost = maxcst; - jcost = iran(csa, 1, 100); - if (jcost > iphic) - icost = iran(csa, mincst, maxcst); - if (G == NULL) - xprintf("%6s%6d%6d%2s%10d%10d\n", "", it, ih, "", icost, - icap); - else - { glp_arc *a = glp_add_arc(G, it, ih); - if (a_cap >= 0) - { double temp = (double)icap; - memcpy((char *)a->data + a_cap, &temp, sizeof(double)); - } - if (a_cost >= 0) - { double temp = (double)icost; - memcpy((char *)a->data + a_cost, &temp, sizeof(double)); - } - } - i++; - if (itail[i] == it) goto L320; - pickj(csa, it); - if (i <= nsort) goto L300; - } - /* Create arcs from the transshipment sinks. */ - if (ntsink != 0) - { for (i = nfsink; i <= ltsink; i++) - { for (j = nftsor; j <= nodes; j++) - iflag[j] = 0; - ktl = nonsor - 1; - iflag[i] = 1; - pickj(csa, i); - } - } -L390: /* Print the demand records and end record. */ - if (G == NULL) - { xprintf("DEMAND\n"); - for (i = nfsink; i <= nodes; i++) - xprintf("%6s%6d%18s%10d\n", "", i, "", ipred[i]); - xprintf("END\n"); - } - else - { if (v_rhs >= 0) - { for (i = nfsink; i <= nodes; i++) - { double temp = - (double)ipred[i]; - glp_vertex *v = G->v[i]; - memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); - } - } - } - /* Free working arrays. */ - xfree(ipred); - xfree(ihead); - xfree(itail); - xfree(iflag); - xfree(isup); - xfree(lsinks); - /* The instance has been successfully generated. */ - ret = 0; -done: return ret; -} - -/*********************************************************************** -* The routine cresup randomly distributes the total supply among the -* source nodes. */ - -static void cresup(struct csa *csa) -{ int i, j, ks, ksp; - xassert(itsup > nsorc); - ks = itsup / nsorc; - for (i = 1; i <= nsorc; i++) - isup[i] = 0; - for (i = 1; i <= nsorc; i++) - { ksp = iran(csa, 1, ks); - j = iran(csa, 1, nsorc); - isup[i] += ksp; - isup[j] += ks - ksp; - } - j = iran(csa, 1, nsorc); - isup[j] += itsup - ks * nsorc; - return; -} - -/*********************************************************************** -* The routine chain adds node lpick to the end of the chain with source -* node lsorc. */ - -static void chain(struct csa *csa, int lpick, int lsorc) -{ int i, j, k, l, m; - k = 0; - m = ist; - for (i = 1; i <= lpick; i++) - { l = k; - k = m; - m = ipred[k]; - } - ipred[l] = m; - j = ipred[lsorc]; - ipred[k] = j; - ipred[lsorc] = k; - return; -} - -/*********************************************************************** -* The routine chnarc puts the arcs in the chain from source lsorc into -* the ihead and itail arrays for sorting. */ - -static void chnarc(struct csa *csa, int lsorc) -{ int ito, ifrom; - nsort = 0; - ito = ipred[lsorc]; -L10: if (ito == lsorc) return; - nsort++; - ifrom = ipred[ito]; - ihead[nsort] = ito; - itail[nsort] = ifrom; - ito = ifrom; - goto L10; -} - -/*********************************************************************** -* The routine sort sorts the nsort arcs in the ihead and itail arrays. -* ihead is used as the sort key (i.e. forward star sort order). */ - -static void sort(struct csa *csa) -{ int i, j, k, l, m, n, it; - n = nsort; - m = n; -L10: m /= 2; - if (m == 0) return; - k = n - m; - j = 1; -L20: i = j; -L30: l = i + m; - if (itail[i] <= itail[l]) goto L40; - it = itail[i]; - itail[i] = itail[l]; - itail[l] = it; - it = ihead[i]; - ihead[i] = ihead[l]; - ihead[l] = it; - i -= m; - if (i >= 1) goto L30; -L40: j++; - if (j <= k) goto L20; - goto L10; -} - -/*********************************************************************** -* The routine pickj creates a random number of arcs out of node 'it'. -* Various parameters are dynamically adjusted in an attempt to ensure -* that the generated network has the correct number of arcs. */ - -static void pickj(struct csa *csa, int it) -{ int j, k, l, nn, nupbnd, icap, jcap, icost; - if ((nodlft - 1) * 2 > iarcs - narcs - 1) - { nodlft--; - return; - } - if ((iarcs - narcs + nonsor - ktl - 1) / nodlft - nonsor + 1 >= 0) - k = nonsor; - else - { nupbnd = (iarcs - narcs - nodlft) / nodlft * 2; -L40: k = iran(csa, 1, nupbnd); - if (nodlft == 1) k = iarcs - narcs; - if ((nodlft - 1) * (nonsor - 1) < iarcs - narcs - k) goto L40; - } - nodlft--; - for (j = 1; j <= k; j++) - { nn = iran(csa, 1, ktl); - ktl--; - for (l = nftsor; l <= nodes; l++) - { if (iflag[l] != 1) - { nn--; - if (nn == 0) goto L70; - } - } - return; -L70: iflag[l] = 1; - icap = itsup; - jcap = iran(csa, 1, 100); - if (jcap <= ipcap) - icap = iran(csa, mincap, maxcap); - icost = iran(csa, mincst, maxcst); - if (G == NULL) - xprintf("%6s%6d%6d%2s%10d%10d\n", "", it, l, "", icost, - icap); - else - { glp_arc *a = glp_add_arc(G, it, l); - if (a_cap >= 0) - { double temp = (double)icap; - memcpy((char *)a->data + a_cap, &temp, sizeof(double)); - } - if (a_cost >= 0) - { double temp = (double)icost; - memcpy((char *)a->data + a_cost, &temp, sizeof(double)); - } - } - narcs++; - } - return; -} - -/*********************************************************************** -* The routine assign generate assignment problems. It defines the unit -* supplies, builds a skeleton, then calls pickj to create the arcs. */ - -static void assign(struct csa *csa) -{ int i, it, nn, l, ll, icost; - if (G == NULL) - xprintf("SUPPLY\n"); - for (i = 1; i <= nsorc; i++) - { isup[i] = 1; - iflag[i] = 0; - if (G == NULL) - xprintf("%6s%6d%18s%10d\n", "", i, "", isup[i]); - else - { if (v_rhs >= 0) - { double temp = (double)isup[i]; - glp_vertex *v = G->v[i]; - memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); - } - } - } - if (G == NULL) - xprintf("ARCS\n"); - for (i = nfsink; i <= nodes; i++) - ipred[i] = 1; - for (it = 1; it <= nsorc; it++) - { for (i = nfsink; i <= nodes; i++) - iflag[i] = 0; - ktl = nsink - 1; - nn = iran(csa, 1, nsink - it + 1); - for (l = 1; l <= nsorc; l++) - { if (iflag[l] != 1) - { nn--; - if (nn == 0) break; - } - } - narcs++; - ll = nsorc + l; - icost = iran(csa, mincst, maxcst); - if (G == NULL) - xprintf("%6s%6d%6d%2s%10d%10d\n", "", it, ll, "", icost, - isup[1]); - else - { glp_arc *a = glp_add_arc(G, it, ll); - if (a_cap >= 0) - { double temp = (double)isup[1]; - memcpy((char *)a->data + a_cap, &temp, sizeof(double)); - } - if (a_cost >= 0) - { double temp = (double)icost; - memcpy((char *)a->data + a_cost, &temp, sizeof(double)); - } - } - iflag[l] = 1; - iflag[ll] = 1; - pickj(csa, it); - } - return; -} - -/*********************************************************************** -* Portable congruential (uniform) random number generator: -* -* next_value = ((7**5) * previous_value) modulo ((2**31)-1) -* -* This generator consists of three routines: -* -* (1) setran - initializes constants and seed -* (2) iran - generates an integer random number -* (3) rran - generates a real random number -* -* The generator requires a machine with at least 32 bits of precision. -* The seed (iseed) must be in the range [1,(2**31)-1]. */ - -static void setran(struct csa *csa, int iseed) -{ xassert(iseed >= 1); - mult = 16807; - modul = 2147483647; - i15 = 1 << 15; - i16 = 1 << 16; - jran = iseed; - return; -} - -/*********************************************************************** -* The routine iran generates an integer random number between ilow and -* ihigh. If ilow > ihigh then iran returns ihigh. */ - -static int iran(struct csa *csa, int ilow, int ihigh) -{ int ixhi, ixlo, ixalo, leftlo, ixahi, ifulhi, irtlo, iover, - irthi, j; - ixhi = jran / i16; - ixlo = jran - ixhi * i16; - ixalo = ixlo * mult; - leftlo = ixalo / i16; - ixahi = ixhi * mult; - ifulhi = ixahi + leftlo; - irtlo = ixalo - leftlo * i16; - iover = ifulhi / i15; - irthi = ifulhi - iover * i15; - jran = ((irtlo - modul) + irthi * i16) + iover; - if (jran < 0) jran += modul; - j = ihigh - ilow + 1; - if (j > 0) - return jran % j + ilow; - else - return ihigh; -} - -/*********************************************************************** -* NAME -* -* glp_netgen_prob - Klingman's standard network problem instance -* -* SYNOPSIS -* -* void glp_netgen_prob(int nprob, int parm[1+15]); -* -* DESCRIPTION -* -* The routine glp_netgen_prob provides the set of parameters for -* Klingman's network problem generator (see the routine glp_netgen), -* which describe a standard network problem instance. -* -* The parameter nprob (101 <= nprob <= 150) specifies the problem -* instance number. -* -* The array parm contains description of the network, provided by the -* routine. (For detailed description of these parameters see comments -* to the routine glp_netgen.) -* -* PROBLEM CHARACTERISTICS -* -* The table below shows characteristics of Klingman's standard network -* problem instances. -* -* Problem Nodes Arcs Optimum -* ------- ----- ----- ---------- -* 101 5000 25336 6191726 -* 102 5000 25387 72337144 -* 103 5000 25355 218947553 -* 104 5000 25344 -19100371 -* 105 5000 25332 31192578 -* 106 5000 12870 4314276 -* 107 5000 37832 7393769 -* 108 5000 50309 8405738 -* 109 5000 75299 9190300 -* 110 5000 12825 8975048 -* 111 5000 37828 4747532 -* 112 5000 50325 4012671 -* 113 5000 75318 2979725 -* 114 5000 26514 5821181 -* 115 5000 25962 6353310 -* 116 5000 25304 5915426 -* 117 5000 12816 4420560 -* 118 5000 37797 7045842 -* 119 5000 50301 7724179 -* 120 5000 75330 8455200 -* 121 5000 25000 66366360 -* 122 5000 25000 30997529 -* 123 5000 25000 23388777 -* 124 5000 25000 17803443 -* 125 5000 25000 14119622 -* 126 5000 12500 18802218 -* 127 5000 37500 27674647 -* 128 5000 50000 30906194 -* 129 5000 75000 40905209 -* 130 5000 12500 38939608 -* 131 5000 37500 16752978 -* 132 5000 50000 13302951 -* 133 5000 75000 9830268 -* 134 1000 25000 3804874 -* 135 2500 25000 11729616 -* 136 7500 25000 33318101 -* 137 10000 25000 46426030 -* 138 5000 25000 60710879 -* 139 5000 25000 32729682 -* 140 5000 25000 27183831 -* 141 5000 25000 19963286 -* 142 5000 25000 20243457 -* 143 5000 25000 18586777 -* 144 5000 25000 2504591 -* 145 5000 25000 215956138 -* 146 5000 25000 2253113811 -* 147 5000 25000 -427908373 -* 148 5000 25000 -92965318 -* 149 5000 25000 86051224 -* 150 5000 25000 619314919 */ - -static const int data[50][1+15] = -{ { 0, 13502460, 101, 5000, 2500, 2500, 25000, - 1, 100, 250000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 4281922, 102, 5000, 2500, 2500, 25000, - 1, 100, 2500000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 44820113, 103, 5000, 2500, 2500, 25000, - 1, 100, 6250000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 13450451, 104, 5000, 2500, 2500, 25000, - -100, -1, 250000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 14719436, 105, 5000, 2500, 2500, 25000, - 101, 200, 250000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 17365786, 106, 5000, 2500, 2500, 12500, - 1, 100, 125000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 19540113, 107, 5000, 2500, 2500, 37500, - 1, 100, 375000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 19560313, 108, 5000, 2500, 2500, 50000, - 1, 100, 500000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 2403509, 109, 5000, 2500, 2500, 75000, - 1, 100, 750000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 92480414, 110, 5000, 2500, 2500, 12500, - 1, 100, 250000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 4230140, 111, 5000, 2500, 2500, 37500, - 1, 100, 250000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 10032490, 112, 5000, 2500, 2500, 50000, - 1, 100, 250000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 17307474, 113, 5000, 2500, 2500, 75000, - 1, 100, 250000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 4925114, 114, 5000, 500, 4500, 25000, - 1, 100, 250000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 19842704, 115, 5000, 1500, 3500, 25000, - 1, 100, 250000, 0, 0, 0, 100, 1, 1000 - }, - { 0, 88392060, 116, 5000, 2500, 2500, 25000, - 1, 100, 250000, 0, 0, 0, 0, 1, 1000 - }, - { 0, 12904407, 117, 5000, 2500, 2500, 12500, - 1, 100, 125000, 0, 0, 0, 0, 1, 1000 - }, - { 0, 11811811, 118, 5000, 2500, 2500, 37500, - 1, 100, 375000, 0, 0, 0, 0, 1, 1000 - }, - { 0, 90023593, 119, 5000, 2500, 2500, 50000, - 1, 100, 500000, 0, 0, 0, 0, 1, 1000 - }, - { 0, 93028922, 120, 5000, 2500, 2500, 75000, - 1, 100, 750000, 0, 0, 0, 0, 1, 1000 - }, - { 0, 72707401, 121, 5000, 50, 50, 25000, - 1, 100, 250000, 50, 50, 0, 100, 1, 1000 - }, - { 0, 93040771, 122, 5000, 250, 250, 25000, - 1, 100, 250000, 250, 250, 0, 100, 1, 1000 - }, - { 0, 70220611, 123, 5000, 500, 500, 25000, - 1, 100, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 52774811, 124, 5000, 1000, 1000, 25000, - 1, 100, 250000, 1000, 1000, 0, 100, 1, 1000 - }, - { 0, 22492311, 125, 5000, 1500, 1500, 25000, - 1, 100, 250000, 1500, 1500, 0, 100, 1, 1000 - }, - { 0, 35269337, 126, 5000, 500, 500, 12500, - 1, 100, 125000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 30140502, 127, 5000, 500, 500, 37500, - 1, 100, 375000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 49205455, 128, 5000, 500, 500, 50000, - 1, 100, 500000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 42958341, 129, 5000, 500, 500, 75000, - 1, 100, 750000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 25440925, 130, 5000, 500, 500, 12500, - 1, 100, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 75294924, 131, 5000, 500, 500, 37500, - 1, 100, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 4463965, 132, 5000, 500, 500, 50000, - 1, 100, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 13390427, 133, 5000, 500, 500, 75000, - 1, 100, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 95250971, 134, 1000, 500, 500, 25000, - 1, 100, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 54830522, 135, 2500, 500, 500, 25000, - 1, 100, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 520593, 136, 7500, 500, 500, 25000, - 1, 100, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 52900925, 137, 10000, 500, 500, 25000, - 1, 100, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 22603395, 138, 5000, 500, 500, 25000, - 1, 100, 250000, 500, 500, 0, 100, 1, 50 - }, - { 0, 55253099, 139, 5000, 500, 500, 25000, - 1, 100, 250000, 500, 500, 0, 100, 1, 250 - }, - { 0, 75357001, 140, 5000, 500, 500, 25000, - 1, 100, 250000, 500, 500, 0, 100, 1, 500 - }, - { 0, 10072459, 141, 5000, 500, 500, 25000, - 1, 100, 250000, 500, 500, 0, 100, 1, 2500 - }, - { 0, 55728492, 142, 5000, 500, 500, 25000, - 1, 100, 250000, 500, 500, 0, 100, 1, 5000 - }, - { 0, 593043, 143, 5000, 500, 500, 25000, - 1, 100, 250000, 500, 500, 0, 0, 1, 1000 - }, - { 0, 94236572, 144, 5000, 500, 500, 25000, - 1, 10, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 94882955, 145, 5000, 500, 500, 25000, - 1, 1000, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 48489922, 146, 5000, 500, 500, 25000, - 1, 10000, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 75578374, 147, 5000, 500, 500, 25000, - -100, -1, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 44821152, 148, 5000, 500, 500, 25000, - -50, 49, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 45224103, 149, 5000, 500, 500, 25000, - 101, 200, 250000, 500, 500, 0, 100, 1, 1000 - }, - { 0, 63491741, 150, 5000, 500, 500, 25000, - 1001, 1100, 250000, 500, 500, 0, 100, 1, 1000 - }, -}; - -void glp_netgen_prob(int nprob, int parm[1+15]) -{ int k; - if (!(101 <= nprob && nprob <= 150)) - xerror("glp_netgen_prob: nprob = %d; invalid problem instance " - "number\n", nprob); - for (k = 1; k <= 15; k++) - parm[k] = data[nprob-101][k]; - return; -} - -/**********************************************************************/ - -#if 0 -static int scan(char card[80+1], int pos, int len) -{ char buf[10+1]; - memcpy(buf, &card[pos-1], len); - buf[len] = '\0'; - return atoi(buf); -} - -int main(void) -{ int parm[1+15]; - char card[80+1]; - xassert(fgets(card, sizeof(card), stdin) == card); - parm[1] = scan(card, 1, 8); - parm[2] = scan(card, 9, 8); - xassert(fgets(card, sizeof(card), stdin) == card); - parm[3] = scan(card, 1, 5); - parm[4] = scan(card, 6, 5); - parm[5] = scan(card, 11, 5); - parm[6] = scan(card, 16, 5); - parm[7] = scan(card, 21, 5); - parm[8] = scan(card, 26, 5); - parm[9] = scan(card, 31, 10); - parm[10] = scan(card, 41, 5); - parm[11] = scan(card, 46, 5); - parm[12] = scan(card, 51, 5); - parm[13] = scan(card, 56, 5); - parm[14] = scan(card, 61, 10); - parm[15] = scan(card, 71, 10); - glp_netgen(NULL, 0, 0, 0, parm); - return 0; -} -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpnet04.c b/resources/3rdparty/glpk-4.53/src/glpnet04.c deleted file mode 100644 index 391392878..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpnet04.c +++ /dev/null @@ -1,769 +0,0 @@ -/* glpnet04.c (grid-like network problem generator) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* This code is a modified version of the program GRIDGEN, a grid-like -* network problem generator developed by Yusin Lee and Jim Orlin. -* The original code is publically available on the DIMACS ftp site at: -* . -* -* All changes concern only the program interface, so this modified -* version produces exactly the same instances as the original version. -* -* Changes were made by Andrew Makhorin . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpk.h" - -/*********************************************************************** -* NAME -* -* glp_gridgen - grid-like network problem generator -* -* SYNOPSIS -* -* int glp_gridgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, -* const int parm[1+14]); -* -* DESCRIPTION -* -* The routine glp_gridgen is a grid-like network problem generator -* developed by Yusin Lee and Jim Orlin. -* -* The parameter G specifies the graph object, to which the generated -* problem data have to be stored. Note that on entry the graph object -* is erased with the routine glp_erase_graph. -* -* The parameter v_rhs specifies an offset of the field of type double -* in the vertex data block, to which the routine stores the supply or -* demand value. If v_rhs < 0, the value is not stored. -* -* The parameter a_cap specifies an offset of the field of type double -* in the arc data block, to which the routine stores the arc capacity. -* If a_cap < 0, the capacity is not stored. -* -* The parameter a_cost specifies an offset of the field of type double -* in the arc data block, to which the routine stores the per-unit cost -* if the arc flow. If a_cost < 0, the cost is not stored. -* -* The array parm contains description of the network to be generated: -* -* parm[0] not used -* parm[1] two-ways arcs indicator: -* 1 - if links in both direction should be generated -* 0 - otherwise -* parm[2] random number seed (a positive integer) -* parm[3] number of nodes (the number of nodes generated might be -* slightly different to make the network a grid) -* parm[4] grid width -* parm[5] number of sources -* parm[6] number of sinks -* parm[7] average degree -* parm[8] total flow -* parm[9] distribution of arc costs: -* 1 - uniform -* 2 - exponential -* parm[10] lower bound for arc cost (uniform) -* 100 * lambda (exponential) -* parm[11] upper bound for arc cost (uniform) -* not used (exponential) -* parm[12] distribution of arc capacities: -* 1 - uniform -* 2 - exponential -* parm[13] lower bound for arc capacity (uniform) -* 100 * lambda (exponential) -* parm[14] upper bound for arc capacity (uniform) -* not used (exponential) -* -* RETURNS -* -* If the instance was successfully generated, the routine glp_gridgen -* returns zero; otherwise, if specified parameters are inconsistent, -* the routine returns a non-zero error code. -* -* COMMENTS -* -* This network generator generates a grid-like network plus a super -* node. In additional to the arcs connecting the nodes in the grid, -* there is an arc from each supply node to the super node and from the -* super node to each demand node to guarantee feasiblity. These arcs -* have very high costs and very big capacities. -* -* The idea of this network generator is as follows: First, a grid of -* n1 * n2 is generated. For example, 5 * 3. The nodes are numbered as -* 1 to 15, and the supernode is numbered as n1*n2+1. Then arcs between -* adjacent nodes are generated. For these arcs, the user is allowed to -* specify either to generate two-way arcs or one-way arcs. If two-way -* arcs are to be generated, two arcs, one in each direction, will be -* generated between each adjacent node pairs. Otherwise, only one arc -* will be generated. If this is the case, the arcs will be generated -* in alterntive directions as shown below. -* -* 1 ---> 2 ---> 3 ---> 4 ---> 5 -* | ^ | ^ | -* | | | | | -* V | V | V -* 6 <--- 7 <--- 8 <--- 9 <--- 10 -* | ^ | ^ | -* | | | | | -* V | V | V -* 11 --->12 --->13 --->14 ---> 15 -* -* Then the arcs between the super node and the source/sink nodes are -* added as mentioned before. If the number of arcs still doesn't reach -* the requirement, additional arcs will be added by uniformly picking -* random node pairs. There is no checking to prevent multiple arcs -* between any pair of nodes. However, there will be no self-arcs (arcs -* that poins back to its tail node) in the network. -* -* The source and sink nodes are selected uniformly in the network, and -* the imbalances of each source/sink node are also assigned by uniform -* distribution. */ - -struct stat_para -{ /* structure for statistical distributions */ - int distribution; - /* the distribution: */ -#define UNIFORM 1 /* uniform distribution */ -#define EXPONENTIAL 2 /* exponential distribution */ - double parameter[5]; - /* the parameters of the distribution */ -}; - -struct arcs -{ int from; - /* the FROM node of that arc */ - int to; - /* the TO node of that arc */ - int cost; - /* original cost of that arc */ - int u; - /* capacity of the arc */ -}; - -struct imbalance -{ int node; - /* Node ID */ - int supply; - /* Supply of that node */ -}; - -struct csa -{ /* common storage area */ - glp_graph *G; - int v_rhs, a_cap, a_cost; - int seed; - /* random number seed */ - int seed_original; - /* the original seed from input */ - int two_way; - /* 0: generate arcs in both direction for the basic grid, except - for the arcs to/from the super node. 1: o/w */ - int n_node; - /* total number of nodes in the network, numbered 1 to n_node, - including the super node, which is the last one */ - int n_arc; - /* total number of arcs in the network, counting EVERY arc. */ - int n_grid_arc; - /* number of arcs in the basic grid, including the arcs to/from - the super node */ - int n_source, n_sink; - /* number of source and sink nodes */ - int avg_degree; - /* average degree, arcs to and from the super node are counted */ - int t_supply; - /* total supply in the network */ - int n1, n2; - /* the two edges of the network grid. n1 >= n2 */ - struct imbalance *source_list, *sink_list; - /* head of the array of source/sink nodes */ - struct stat_para arc_costs; - /* the distribution of arc costs */ - struct stat_para capacities; - /* distribution of the capacities of the arcs */ - struct arcs *arc_list; - /* head of the arc list array. Arcs in this array are in the - order of grid_arcs, arcs to/from super node, and other arcs */ -}; - -#define G (csa->G) -#define v_rhs (csa->v_rhs) -#define a_cap (csa->a_cap) -#define a_cost (csa->a_cost) -#define seed (csa->seed) -#define seed_original (csa->seed_original) -#define two_way (csa->two_way) -#define n_node (csa->n_node) -#define n_arc (csa->n_arc) -#define n_grid_arc (csa->n_grid_arc) -#define n_source (csa->n_source) -#define n_sink (csa->n_sink) -#define avg_degree (csa->avg_degree) -#define t_supply (csa->t_supply) -#define n1 (csa->n1) -#define n2 (csa->n2) -#define source_list (csa->source_list) -#define sink_list (csa->sink_list) -#define arc_costs (csa->arc_costs) -#define capacities (csa->capacities) -#define arc_list (csa->arc_list) - -static void assign_capacities(struct csa *csa); -static void assign_costs(struct csa *csa); -static void assign_imbalance(struct csa *csa); -static int exponential(struct csa *csa, double lambda[1]); -static struct arcs *gen_additional_arcs(struct csa *csa, struct arcs - *arc_ptr); -static struct arcs *gen_basic_grid(struct csa *csa, struct arcs - *arc_ptr); -static void gen_more_arcs(struct csa *csa, struct arcs *arc_ptr); -static void generate(struct csa *csa); -static void output(struct csa *csa); -static double randy(struct csa *csa); -static void select_source_sinks(struct csa *csa); -static int uniform(struct csa *csa, double a[2]); - -int glp_gridgen(glp_graph *G_, int _v_rhs, int _a_cap, int _a_cost, - const int parm[1+14]) -{ struct csa _csa, *csa = &_csa; - int n, ret; - G = G_; - v_rhs = _v_rhs; - a_cap = _a_cap; - a_cost = _a_cost; - if (G != NULL) - { if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) - xerror("glp_gridgen: v_rhs = %d; invalid offset\n", v_rhs); - if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) - xerror("glp_gridgen: a_cap = %d; invalid offset\n", a_cap); - if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) - xerror("glp_gridgen: a_cost = %d; invalid offset\n", a_cost) - ; - } - /* Check the parameters for consistency. */ - if (!(parm[1] == 0 || parm[1] == 1)) - { ret = 1; - goto done; - } - if (parm[2] < 1) - { ret = 2; - goto done; - } - if (!(10 <= parm[3] && parm[3] <= 40000)) - { ret = 3; - goto done; - } - if (!(1 <= parm[4] && parm[4] <= 40000)) - { ret = 4; - goto done; - } - if (!(parm[5] >= 0 && parm[6] >= 0 && parm[5] + parm[6] <= - parm[3])) - { ret = 5; - goto done; - } - if (!(1 <= parm[7] && parm[7] <= parm[3])) - { ret = 6; - goto done; - } - if (parm[8] < 0) - { ret = 7; - goto done; - } - if (!(parm[9] == 1 || parm[9] == 2)) - { ret = 8; - goto done; - } - if (parm[9] == 1 && parm[10] > parm[11] || - parm[9] == 2 && parm[10] < 1) - { ret = 9; - goto done; - } - if (!(parm[12] == 1 || parm[12] == 2)) - { ret = 10; - goto done; - } - if (parm[12] == 1 && !(0 <= parm[13] && parm[13] <= parm[14]) || - parm[12] == 2 && parm[13] < 1) - { ret = 11; - goto done; - } - /* Initialize the graph object. */ - if (G != NULL) - { glp_erase_graph(G, G->v_size, G->a_size); - glp_set_graph_name(G, "GRIDGEN"); - } - /* Copy the generator parameters. */ - two_way = parm[1]; - seed_original = seed = parm[2]; - n_node = parm[3]; - n = parm[4]; - n_source = parm[5]; - n_sink = parm[6]; - avg_degree = parm[7]; - t_supply = parm[8]; - arc_costs.distribution = parm[9]; - if (parm[9] == 1) - { arc_costs.parameter[0] = parm[10]; - arc_costs.parameter[1] = parm[11]; - } - else - { arc_costs.parameter[0] = (double)parm[10] / 100.0; - arc_costs.parameter[1] = 0.0; - } - capacities.distribution = parm[12]; - if (parm[12] == 1) - { capacities.parameter[0] = parm[13]; - capacities.parameter[1] = parm[14]; - } - else - { capacities.parameter[0] = (double)parm[13] / 100.0; - capacities.parameter[1] = 0.0; - } - /* Calculate the edge lengths of the grid according to the - input. */ - if (n * n >= n_node) - { n1 = n; - n2 = (int)((double)n_node / (double)n + 0.5); - } - else - { n2 = n; - n1 = (int)((double)n_node / (double)n + 0.5); - } - /* Recalculate the total number of nodes and plus 1 for the super - node. */ - n_node = n1 * n2 + 1; - n_arc = n_node * avg_degree; - n_grid_arc = (two_way + 1) * ((n1 - 1) * n2 + (n2 - 1) * n1) + - n_source + n_sink; - if (n_grid_arc > n_arc) n_arc = n_grid_arc; - arc_list = xcalloc(n_arc, sizeof(struct arcs)); - source_list = xcalloc(n_source, sizeof(struct imbalance)); - sink_list = xcalloc(n_sink, sizeof(struct imbalance)); - /* Generate a random network. */ - generate(csa); - /* Output the network. */ - output(csa); - /* Free all allocated memory. */ - xfree(arc_list); - xfree(source_list); - xfree(sink_list); - /* The instance has been successfully generated. */ - ret = 0; -done: return ret; -} - -#undef random - -static void assign_capacities(struct csa *csa) -{ /* Assign a capacity to each arc. */ - struct arcs *arc_ptr = arc_list; - int (*random)(struct csa *csa, double *); - int i; - /* Determine the random number generator to use. */ - switch (arc_costs.distribution) - { case UNIFORM: - random = uniform; - break; - case EXPONENTIAL: - random = exponential; - break; - default: - xassert(csa != csa); - } - /* Assign capacities to grid arcs. */ - for (i = n_source + n_sink; i < n_grid_arc; i++, arc_ptr++) - arc_ptr->u = random(csa, capacities.parameter); - i = i - n_source - n_sink; - /* Assign capacities to arcs to/from supernode. */ - for (; i < n_grid_arc; i++, arc_ptr++) - arc_ptr->u = t_supply; - /* Assign capacities to all other arcs. */ - for (; i < n_arc; i++, arc_ptr++) - arc_ptr->u = random(csa, capacities.parameter); - return; -} - -static void assign_costs(struct csa *csa) -{ /* Assign a cost to each arc. */ - struct arcs *arc_ptr = arc_list; - int (*random)(struct csa *csa, double *); - int i; - /* A high cost assigned to arcs to/from the supernode. */ - int high_cost; - /* The maximum cost assigned to arcs in the base grid. */ - int max_cost = 0; - /* Determine the random number generator to use. */ - switch (arc_costs.distribution) - { case UNIFORM: - random = uniform; - break; - case EXPONENTIAL: - random = exponential; - break; - default: - xassert(csa != csa); - } - /* Assign costs to arcs in the base grid. */ - for (i = n_source + n_sink; i < n_grid_arc; i++, arc_ptr++) - { arc_ptr->cost = random(csa, arc_costs.parameter); - if (max_cost < arc_ptr->cost) max_cost = arc_ptr->cost; - } - i = i - n_source - n_sink; - /* Assign costs to arcs to/from the super node. */ - high_cost = max_cost * 2; - for (; i < n_grid_arc; i++, arc_ptr++) - arc_ptr->cost = high_cost; - /* Assign costs to all other arcs. */ - for (; i < n_arc; i++, arc_ptr++) - arc_ptr->cost = random(csa, arc_costs.parameter); - return; -} - -static void assign_imbalance(struct csa *csa) -{ /* Assign an imbalance to each node. */ - int total, i; - double avg; - struct imbalance *ptr; - /* assign the supply nodes */ - avg = 2.0 * t_supply / n_source; - do - { for (i = 1, total = t_supply, ptr = source_list + 1; - i < n_source; i++, ptr++) - { ptr->supply = (int)(randy(csa) * avg + 0.5); - total -= ptr->supply; - } - source_list->supply = total; - } - /* redo all if the assignment "overshooted" */ - while (total <= 0); - /* assign the demand nodes */ - avg = -2.0 * t_supply / n_sink; - do - { for (i = 1, total = t_supply, ptr = sink_list + 1; - i < n_sink; i++, ptr++) - { ptr->supply = (int)(randy(csa) * avg - 0.5); - total += ptr->supply; - } - sink_list->supply = - total; - } - while (total <= 0); - return; -} - -static int exponential(struct csa *csa, double lambda[1]) -{ /* Returns an "exponentially distributed" integer with parameter - lambda. */ - return ((int)(- lambda[0] * log((double)randy(csa)) + 0.5)); -} - -static struct arcs *gen_additional_arcs(struct csa *csa, struct arcs - *arc_ptr) -{ /* Generate an arc from each source to the supernode and from - supernode to each sink. */ - int i; - for (i = 0; i < n_source; i++, arc_ptr++) - { arc_ptr->from = source_list[i].node; - arc_ptr->to = n_node; - } - for (i = 0; i < n_sink; i++, arc_ptr++) - { arc_ptr->to = sink_list[i].node; - arc_ptr->from = n_node; - } - return arc_ptr; -} - -static struct arcs *gen_basic_grid(struct csa *csa, struct arcs - *arc_ptr) -{ /* Generate the basic grid. */ - int direction = 1, i, j, k; - if (two_way) - { /* Generate an arc in each direction. */ - for (i = 1; i < n_node; i += n1) - { for (j = i, k = j + n1 - 1; j < k; j++) - { arc_ptr->from = j; - arc_ptr->to = j + 1; - arc_ptr++; - arc_ptr->from = j + 1; - arc_ptr->to = j; - arc_ptr++; - } - } - for (i = 1; i <= n1; i++) - { for (j = i + n1; j < n_node; j += n1) - { arc_ptr->from = j; - arc_ptr->to = j - n1; - arc_ptr++; - arc_ptr->from = j - n1; - arc_ptr->to = j; - arc_ptr++; - } - } - } - else - { /* Generate one arc in each direction. */ - for (i = 1; i < n_node; i += n1) - { if (direction == 1) - j = i; - else - j = i + 1; - for (k = j + n1 - 1; j < k; j++) - { arc_ptr->from = j; - arc_ptr->to = j + direction; - arc_ptr++; - } - direction = - direction; - } - for (i = 1; i <= n1; i++) - { j = i + n1; - if (direction == 1) - { for (; j < n_node; j += n1) - { arc_ptr->from = j - n1; - arc_ptr->to = j; - arc_ptr++; - } - } - else - { for (; j < n_node; j += n1) - { arc_ptr->from = j - n1; - arc_ptr->to = j; - arc_ptr++; - } - } - direction = - direction; - } - } - return arc_ptr; -} - -static void gen_more_arcs(struct csa *csa, struct arcs *arc_ptr) -{ /* Generate random arcs to meet the specified density. */ - int i; - double ab[2]; - ab[0] = 0.9; - ab[1] = n_node - 0.99; /* upper limit is n_node-1 because the - supernode cannot be selected */ - for (i = n_grid_arc; i < n_arc; i++, arc_ptr++) - { arc_ptr->from = uniform(csa, ab); - arc_ptr->to = uniform(csa, ab); - if (arc_ptr->from == arc_ptr->to) - { arc_ptr--; - i--; - } - } - return; -} - -static void generate(struct csa *csa) -{ /* Generate a random network. */ - struct arcs *arc_ptr = arc_list; - arc_ptr = gen_basic_grid(csa, arc_ptr); - select_source_sinks(csa); - arc_ptr = gen_additional_arcs(csa, arc_ptr); - gen_more_arcs(csa, arc_ptr); - assign_costs(csa); - assign_capacities(csa); - assign_imbalance(csa); - return; -} - -static void output(struct csa *csa) -{ /* Output the network in DIMACS format. */ - struct arcs *arc_ptr; - struct imbalance *imb_ptr; - int i; - if (G != NULL) goto skip; - /* Output "c", "p" records. */ - xprintf("c generated by GRIDGEN\n"); - xprintf("c seed %d\n", seed_original); - xprintf("c nodes %d\n", n_node); - xprintf("c grid size %d X %d\n", n1, n2); - xprintf("c sources %d sinks %d\n", n_source, n_sink); - xprintf("c avg. degree %d\n", avg_degree); - xprintf("c supply %d\n", t_supply); - switch (arc_costs.distribution) - { case UNIFORM: - xprintf("c arc costs: UNIFORM distr. min %d max %d\n", - (int)arc_costs.parameter[0], - (int)arc_costs.parameter[1]); - break; - case EXPONENTIAL: - xprintf("c arc costs: EXPONENTIAL distr. lambda %d\n", - (int)arc_costs.parameter[0]); - break; - default: - xassert(csa != csa); - } - switch (capacities.distribution) - { case UNIFORM: - xprintf("c arc caps : UNIFORM distr. min %d max %d\n", - (int)capacities.parameter[0], - (int)capacities.parameter[1]); - break; - case EXPONENTIAL: - xprintf("c arc caps : EXPONENTIAL distr. %d lambda %d\n", - (int)capacities.parameter[0]); - break; - default: - xassert(csa != csa); - } -skip: if (G == NULL) - xprintf("p min %d %d\n", n_node, n_arc); - else - { glp_add_vertices(G, n_node); - if (v_rhs >= 0) - { double zero = 0.0; - for (i = 1; i <= n_node; i++) - { glp_vertex *v = G->v[i]; - memcpy((char *)v->data + v_rhs, &zero, sizeof(double)); - } - } - } - /* Output "n node supply". */ - for (i = 0, imb_ptr = source_list; i < n_source; i++, imb_ptr++) - { if (G == NULL) - xprintf("n %d %d\n", imb_ptr->node, imb_ptr->supply); - else - { if (v_rhs >= 0) - { double temp = (double)imb_ptr->supply; - glp_vertex *v = G->v[imb_ptr->node]; - memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); - } - } - } - for (i = 0, imb_ptr = sink_list; i < n_sink; i++, imb_ptr++) - { if (G == NULL) - xprintf("n %d %d\n", imb_ptr->node, imb_ptr->supply); - else - { if (v_rhs >= 0) - { double temp = (double)imb_ptr->supply; - glp_vertex *v = G->v[imb_ptr->node]; - memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); - } - } - } - /* Output "a from to lowcap=0 hicap cost". */ - for (i = 0, arc_ptr = arc_list; i < n_arc; i++, arc_ptr++) - { if (G == NULL) - xprintf("a %d %d 0 %d %d\n", arc_ptr->from, arc_ptr->to, - arc_ptr->u, arc_ptr->cost); - else - { glp_arc *a = glp_add_arc(G, arc_ptr->from, arc_ptr->to); - if (a_cap >= 0) - { double temp = (double)arc_ptr->u; - memcpy((char *)a->data + a_cap, &temp, sizeof(double)); - } - if (a_cost >= 0) - { double temp = (double)arc_ptr->cost; - memcpy((char *)a->data + a_cost, &temp, sizeof(double)); - } - } - } - return; -} - -static double randy(struct csa *csa) -{ /* Returns a random number between 0.0 and 1.0. - See Ward Cheney & David Kincaid, "Numerical Mathematics and - Computing," 2Ed, pp. 335. */ - seed = 16807 * seed % 2147483647; - if (seed < 0) seed = - seed; - return seed * 4.6566128752459e-10; -} - -static void select_source_sinks(struct csa *csa) -{ /* Randomly select the source nodes and sink nodes. */ - int i, *int_ptr; - int *temp_list; /* a temporary list of nodes */ - struct imbalance *ptr; - double ab[2]; /* parameter for random number generator */ - ab[0] = 0.9; - ab[1] = n_node - 0.99; /* upper limit is n_node-1 because the - supernode cannot be selected */ - temp_list = xcalloc(n_node, sizeof(int)); - for (i = 0, int_ptr = temp_list; i < n_node; i++, int_ptr++) - *int_ptr = 0; - /* Select the source nodes. */ - for (i = 0, ptr = source_list; i < n_source; i++, ptr++) - { ptr->node = uniform(csa, ab); - if (temp_list[ptr->node] == 1) /* check for duplicates */ - { ptr--; - i--; - } - else - temp_list[ptr->node] = 1; - } - /* Select the sink nodes. */ - for (i = 0, ptr = sink_list; i < n_sink; i++, ptr++) - { ptr->node = uniform(csa, ab); - if (temp_list[ptr->node] == 1) - { ptr--; - i--; - } - else - temp_list[ptr->node] = 1; - } - xfree(temp_list); - return; -} - -int uniform(struct csa *csa, double a[2]) -{ /* Generates an integer uniformly selected from [a[0],a[1]]. */ - return (int)((a[1] - a[0]) * randy(csa) + a[0] + 0.5); -} - -/**********************************************************************/ - -#if 0 -int main(void) -{ int parm[1+14]; - double temp; - scanf("%d", &parm[1]); - scanf("%d", &parm[2]); - scanf("%d", &parm[3]); - scanf("%d", &parm[4]); - scanf("%d", &parm[5]); - scanf("%d", &parm[6]); - scanf("%d", &parm[7]); - scanf("%d", &parm[8]); - scanf("%d", &parm[9]); - if (parm[9] == 1) - { scanf("%d", &parm[10]); - scanf("%d", &parm[11]); - } - else - { scanf("%le", &temp); - parm[10] = (int)(100.0 * temp + .5); - parm[11] = 0; - } - scanf("%d", &parm[12]); - if (parm[12] == 1) - { scanf("%d", &parm[13]); - scanf("%d", &parm[14]); - } - else - { scanf("%le", &temp); - parm[13] = (int)(100.0 * temp + .5); - parm[14] = 0; - } - glp_gridgen(NULL, 0, 0, 0, parm); - return 0; -} -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpnet05.c b/resources/3rdparty/glpk-4.53/src/glpnet05.c deleted file mode 100644 index ea7ca6300..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpnet05.c +++ /dev/null @@ -1,368 +0,0 @@ -/* glpnet05.c (Goldfarb's maximum flow problem generator) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* This code is a modified version of the program RMFGEN, a maxflow -* problem generator developed by D.Goldfarb and M.Grigoriadis, and -* originally implemented by Tamas Badics . -* The original code is publically available on the DIMACS ftp site at: -* . -* -* All changes concern only the program interface, so this modified -* version produces exactly the same instances as the original version. -* -* Changes were made by Andrew Makhorin . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpk.h" -#include "rng.h" - -/*********************************************************************** -* NAME -* -* glp_rmfgen - Goldfarb's maximum flow problem generator -* -* SYNOPSIS -* -* int glp_rmfgen(glp_graph *G, int *s, int *t, int a_cap, -* const int parm[1+5]); -* -* DESCRIPTION -* -* The routine glp_rmfgen is a maximum flow problem generator developed -* by D.Goldfarb and M.Grigoriadis. -* -* The parameter G specifies the graph object, to which the generated -* problem data have to be stored. Note that on entry the graph object -* is erased with the routine glp_erase_graph. -* -* The pointer s specifies a location, to which the routine stores the -* source node number. If s is NULL, the node number is not stored. -* -* The pointer t specifies a location, to which the routine stores the -* sink node number. If t is NULL, the node number is not stored. -* -* The parameter a_cap specifies an offset of the field of type double -* in the arc data block, to which the routine stores the arc capacity. -* If a_cap < 0, the capacity is not stored. -* -* The array parm contains description of the network to be generated: -* -* parm[0] not used -* parm[1] (seed) random number seed (a positive integer) -* parm[2] (a) frame size -* parm[3] (b) depth -* parm[4] (c1) minimal arc capacity -* parm[5] (c2) maximal arc capacity -* -* RETURNS -* -* If the instance was successfully generated, the routine glp_netgen -* returns zero; otherwise, if specified parameters are inconsistent, -* the routine returns a non-zero error code. -* -* COMMENTS -* -* The generated network is as follows. It has b pieces of frames of -* size a * a. (So alltogether the number of vertices is a * a * b) -* -* In each frame all the vertices are connected with their neighbours -* (forth and back). In addition the vertices of a frame are connected -* one to one with the vertices of next frame using a random permutation -* of those vertices. -* -* The source is the lower left vertex of the first frame, the sink is -* the upper right vertex of the b'th frame. -* -* t -* +-------+ -* | .| -* | . | -* / | / | -* +-------+/ -+ b -* | | |/. -* a | -v- |/ -* | | |/ -* +-------+ 1 -* s a -* -* The capacities are randomly chosen integers from the range of [c1,c2] -* in the case of interconnecting edges, and c2 * a * a for the in-frame -* edges. -* -* REFERENCES -* -* D.Goldfarb and M.D.Grigoriadis, "A computational comparison of the -* Dinic and network simplex methods for maximum flow." Annals of Op. -* Res. 13 (1988), pp. 83-123. -* -* U.Derigs and W.Meier, "Implementing Goldberg's max-flow algorithm: -* A computational investigation." Zeitschrift fuer Operations Research -* 33 (1989), pp. 383-403. */ - -typedef struct VERTEX -{ struct EDGE **edgelist; - /* Pointer to the list of pointers to the adjacent edges. - (No matter that to or from edges) */ - struct EDGE **current; - /* Pointer to the current edge */ - int degree; - /* Number of adjacent edges (both direction) */ - int index; -} vertex; - -typedef struct EDGE -{ int from; - int to; - int cap; - /* Capacity */ -} edge; - -typedef struct NETWORK -{ struct NETWORK *next, *prev; - int vertnum; - int edgenum; - vertex *verts; - /* Vertex array[1..vertnum] */ - edge *edges; - /* Edge array[1..edgenum] */ - int source; - /* Pointer to the source */ - int sink; - /* Pointer to the sink */ -} network; - -struct csa -{ /* common storage area */ - glp_graph *G; - int *s, *t, a_cap; - RNG *rand; - network *N; - int *Parr; - int A, AA, C2AA, Ec; -}; - -#define G (csa->G) -#define s (csa->s) -#define t (csa->t) -#define a_cap (csa->a_cap) -#define N (csa->N) -#define Parr (csa->Parr) -#define A (csa->A) -#define AA (csa->AA) -#define C2AA (csa->C2AA) -#define Ec (csa->Ec) - -#undef random -#define random(A) (int)(rng_unif_01(csa->rand) * (double)(A)) -#define RANDOM(A, B) (int)(random((B) - (A) + 1) + (A)) -#define sgn(A) (((A) > 0) ? 1 : ((A) == 0) ? 0 : -1) - -static void make_edge(struct csa *csa, int from, int to, int c1, int c2) -{ Ec++; - N->edges[Ec].from = from; - N->edges[Ec].to = to; - N->edges[Ec].cap = RANDOM(c1, c2); - return; -} - -static void permute(struct csa *csa) -{ int i, j, tmp; - for (i = 1; i < AA; i++) - { j = RANDOM(i, AA); - tmp = Parr[i]; - Parr[i] = Parr[j]; - Parr[j] = tmp; - } - return; -} - -static void connect(struct csa *csa, int offset, int cv, int x1, int y1) -{ int cv1; - cv1 = offset + (x1 - 1) * A + y1; - Ec++; - N->edges[Ec].from = cv; - N->edges[Ec].to = cv1; - N->edges[Ec].cap = C2AA; - return; -} - -static network *gen_rmf(struct csa *csa, int a, int b, int c1, int c2) -{ /* generates a network with a*a*b nodes and 6a*a*b-4ab-2a*a edges - random_frame network: - Derigs & Meier, Methods & Models of OR (1989), 33:383-403 */ - int x, y, z, offset, cv; - A = a; - AA = a * a; - C2AA = c2 * AA; - Ec = 0; - N = (network *)xmalloc(sizeof(network)); - N->vertnum = AA * b; - N->edgenum = 5 * AA * b - 4 * A * b - AA; - N->edges = (edge *)xcalloc(N->edgenum + 1, sizeof(edge)); - N->source = 1; - N->sink = N->vertnum; - Parr = (int *)xcalloc(AA + 1, sizeof(int)); - for (x = 1; x <= AA; x++) - Parr[x] = x; - for (z = 1; z <= b; z++) - { offset = AA * (z - 1); - if (z != b) - permute(csa); - for (x = 1; x <= A; x++) - { for (y = 1; y <= A; y++) - { cv = offset + (x - 1) * A + y; - if (z != b) - make_edge(csa, cv, offset + AA + Parr[cv - offset], - c1, c2); /* the intermediate edges */ - if (y < A) - connect(csa, offset, cv, x, y + 1); - if (y > 1) - connect(csa, offset, cv, x, y - 1); - if (x < A) - connect(csa, offset, cv, x + 1, y); - if (x > 1) - connect(csa, offset, cv, x - 1, y); - } - } - } - xfree(Parr); - return N; -} - -static void print_max_format(struct csa *csa, network *n, char *comm[], - int dim) -{ /* prints a network heading with dim lines of comments (no \n - needs at the ends) */ - int i, vnum, e_num; - edge *e; - vnum = n->vertnum; - e_num = n->edgenum; - if (G == NULL) - { for (i = 0; i < dim; i++) - xprintf("c %s\n", comm[i]); - xprintf("p max %7d %10d\n", vnum, e_num); - xprintf("n %7d s\n", n->source); - xprintf("n %7d t\n", n->sink); - } - else - { glp_add_vertices(G, vnum); - if (s != NULL) *s = n->source; - if (t != NULL) *t = n->sink; - } - for (i = 1; i <= e_num; i++) - { e = &n->edges[i]; - if (G == NULL) - xprintf("a %7d %7d %10d\n", e->from, e->to, (int)e->cap); - else - { glp_arc *a = glp_add_arc(G, e->from, e->to); - if (a_cap >= 0) - { double temp = (double)e->cap; - memcpy((char *)a->data + a_cap, &temp, sizeof(double)); - } - } - } - return; -} - -static void gen_free_net(network *n) -{ xfree(n->edges); - xfree(n); - return; -} - -int glp_rmfgen(glp_graph *G_, int *_s, int *_t, int _a_cap, - const int parm[1+5]) -{ struct csa _csa, *csa = &_csa; - network *n; - char comm[10][80], *com1[10]; - int seed, a, b, c1, c2, ret; - G = G_; - s = _s; - t = _t; - a_cap = _a_cap; - if (G != NULL) - { if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) - xerror("glp_rmfgen: a_cap = %d; invalid offset\n", a_cap); - } - seed = parm[1]; - a = parm[2]; - b = parm[3]; - c1 = parm[4]; - c2 = parm[5]; - if (!(seed > 0 && 1 <= a && a <= 1000 && 1 <= b && b <= 1000 && - 0 <= c1 && c1 <= c2 && c2 <= 1000)) - { ret = 1; - goto done; - } - if (G != NULL) - { glp_erase_graph(G, G->v_size, G->a_size); - glp_set_graph_name(G, "RMFGEN"); - } - csa->rand = rng_create_rand(); - rng_init_rand(csa->rand, seed); - n = gen_rmf(csa, a, b, c1, c2); - sprintf(comm[0], "This file was generated by genrmf."); - sprintf(comm[1], "The parameters are: a: %d b: %d c1: %d c2: %d", - a, b, c1, c2); - com1[0] = comm[0]; - com1[1] = comm[1]; - print_max_format(csa, n, com1, 2); - gen_free_net(n); - rng_delete_rand(csa->rand); - ret = 0; -done: return ret; -} - -/**********************************************************************/ - -#if 0 -int main(int argc, char *argv[]) -{ int seed, a, b, c1, c2, i, parm[1+5]; - seed = 123; - a = b = c1 = c2 = -1; - for (i = 1; i < argc; i++) - { if (strcmp(argv[i], "-seed") == 0) - seed = atoi(argv[++i]); - else if (strcmp(argv[i], "-a") == 0) - a = atoi(argv[++i]); - else if (strcmp(argv[i], "-b") == 0) - b = atoi(argv[++i]); - else if (strcmp(argv[i], "-c1") == 0) - c1 = atoi(argv[++i]); - else if (strcmp(argv[i], "-c2") == 0) - c2 = atoi(argv[++i]); - } - if (a < 0 || b < 0 || c1 < 0 || c2 < 0) - { xprintf("Usage:\n"); - xprintf("genrmf [-seed seed] -a frame_size -b depth\n"); - xprintf(" -c1 cap_range1 -c2 cap_range2\n"); - } - else - { parm[1] = seed; - parm[2] = a; - parm[3] = b; - parm[4] = c1; - parm[5] = c2; - glp_rmfgen(NULL, NULL, NULL, 0, parm); - } - return 0; -} -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpnpp.h b/resources/3rdparty/glpk-4.53/src/glpnpp.h deleted file mode 100644 index 6aaebe8d4..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpnpp.h +++ /dev/null @@ -1,638 +0,0 @@ -/* glpnpp.h (LP/MIP preprocessor) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPNPP_H -#define GLPNPP_H - -#include "prob.h" - -typedef struct NPP NPP; -typedef struct NPPROW NPPROW; -typedef struct NPPCOL NPPCOL; -typedef struct NPPAIJ NPPAIJ; -typedef struct NPPTSE NPPTSE; -typedef struct NPPLFE NPPLFE; - -struct NPP -{ /* LP/MIP preprocessor workspace */ - /*--------------------------------------------------------------*/ - /* original problem segment */ - int orig_dir; - /* optimization direction flag: - GLP_MIN - minimization - GLP_MAX - maximization */ - int orig_m; - /* number of rows */ - int orig_n; - /* number of columns */ - int orig_nnz; - /* number of non-zero constraint coefficients */ - /*--------------------------------------------------------------*/ - /* transformed problem segment (always minimization) */ - DMP *pool; - /* memory pool to store problem components */ - char *name; - /* problem name (1 to 255 chars); NULL means no name is assigned - to the problem */ - char *obj; - /* objective function name (1 to 255 chars); NULL means no name - is assigned to the objective function */ - double c0; - /* constant term of the objective function */ - int nrows; - /* number of rows introduced into the problem; this count - increases by one every time a new row is added and never - decreases; thus, actual number of rows may be less than nrows - due to row deletions */ - int ncols; - /* number of columns introduced into the problem; this count - increases by one every time a new column is added and never - decreases; thus, actual number of column may be less than - ncols due to column deletions */ - NPPROW *r_head; - /* pointer to the beginning of the row list */ - NPPROW *r_tail; - /* pointer to the end of the row list */ - NPPCOL *c_head; - /* pointer to the beginning of the column list */ - NPPCOL *c_tail; - /* pointer to the end of the column list */ - /*--------------------------------------------------------------*/ - /* transformation history */ - DMP *stack; - /* memory pool to store transformation entries */ - NPPTSE *top; - /* pointer to most recent transformation entry */ -#if 0 /* 16/XII-2009 */ - int count[1+25]; - /* transformation statistics */ -#endif - /*--------------------------------------------------------------*/ - /* resultant (preprocessed) problem segment */ - int m; - /* number of rows */ - int n; - /* number of columns */ - int nnz; - /* number of non-zero constraint coefficients */ - int *row_ref; /* int row_ref[1+m]; */ - /* row_ref[i], 1 <= i <= m, is the reference number assigned to - a row, which is i-th row of the resultant problem */ - int *col_ref; /* int col_ref[1+n]; */ - /* col_ref[j], 1 <= j <= n, is the reference number assigned to - a column, which is j-th column of the resultant problem */ - /*--------------------------------------------------------------*/ - /* recovered solution segment */ - int sol; - /* solution indicator: - GLP_SOL - basic solution - GLP_IPT - interior-point solution - GLP_MIP - mixed integer solution */ - int scaling; - /* scaling option: - GLP_OFF - scaling is disabled - GLP_ON - scaling is enabled */ - int p_stat; - /* status of primal basic solution: - GLP_UNDEF - primal solution is undefined - GLP_FEAS - primal solution is feasible - GLP_INFEAS - primal solution is infeasible - GLP_NOFEAS - no primal feasible solution exists */ - int d_stat; - /* status of dual basic solution: - GLP_UNDEF - dual solution is undefined - GLP_FEAS - dual solution is feasible - GLP_INFEAS - dual solution is infeasible - GLP_NOFEAS - no dual feasible solution exists */ - int t_stat; - /* status of interior-point solution: - GLP_UNDEF - interior solution is undefined - GLP_OPT - interior solution is optimal */ - int i_stat; - /* status of mixed integer solution: - GLP_UNDEF - integer solution is undefined - GLP_OPT - integer solution is optimal - GLP_FEAS - integer solution is feasible - GLP_NOFEAS - no integer solution exists */ - char *r_stat; /* char r_stat[1+nrows]; */ - /* r_stat[i], 1 <= i <= nrows, is status of i-th row: - GLP_BS - inactive constraint - GLP_NL - active constraint on lower bound - GLP_NU - active constraint on upper bound - GLP_NF - active free row - GLP_NS - active equality constraint */ - char *c_stat; /* char c_stat[1+nrows]; */ - /* c_stat[j], 1 <= j <= nrows, is status of j-th column: - GLP_BS - basic variable - GLP_NL - non-basic variable on lower bound - GLP_NU - non-basic variable on upper bound - GLP_NF - non-basic free variable - GLP_NS - non-basic fixed variable */ - double *r_pi; /* double r_pi[1+nrows]; */ - /* r_pi[i], 1 <= i <= nrows, is Lagrange multiplier (dual value) - for i-th row (constraint) */ - double *c_value; /* double c_value[1+ncols]; */ - /* c_value[j], 1 <= j <= ncols, is primal value of j-th column - (structural variable) */ -}; - -struct NPPROW -{ /* row (constraint) */ - int i; - /* reference number assigned to the row, 1 <= i <= nrows */ - char *name; - /* row name (1 to 255 chars); NULL means no name is assigned to - the row */ - double lb; - /* lower bound; -DBL_MAX means the row has no lower bound */ - double ub; - /* upper bound; +DBL_MAX means the row has no upper bound */ - NPPAIJ *ptr; - /* pointer to the linked list of constraint coefficients */ - int temp; - /* working field used by preprocessor routines */ - NPPROW *prev; - /* pointer to previous row in the row list */ - NPPROW *next; - /* pointer to next row in the row list */ -}; - -struct NPPCOL -{ /* column (variable) */ - int j; - /* reference number assigned to the column, 1 <= j <= ncols */ - char *name; - /* column name (1 to 255 chars); NULL means no name is assigned - to the column */ - char is_int; - /* 0 means continuous variable; 1 means integer variable */ - double lb; - /* lower bound; -DBL_MAX means the column has no lower bound */ - double ub; - /* upper bound; +DBL_MAX means the column has no upper bound */ - double coef; - /* objective coefficient */ - NPPAIJ *ptr; - /* pointer to the linked list of constraint coefficients */ - int temp; - /* working field used by preprocessor routines */ -#if 1 /* 28/XII-2009 */ - union - { double ll; - /* implied column lower bound */ - int pos; - /* vertex ordinal number corresponding to this binary column - in the conflict graph (0, if the vertex does not exist) */ - } ll; - union - { double uu; - /* implied column upper bound */ - int neg; - /* vertex ordinal number corresponding to complement of this - binary column in the conflict graph (0, if the vertex does - not exist) */ - } uu; -#endif - NPPCOL *prev; - /* pointer to previous column in the column list */ - NPPCOL *next; - /* pointer to next column in the column list */ -}; - -struct NPPAIJ -{ /* constraint coefficient */ - NPPROW *row; - /* pointer to corresponding row */ - NPPCOL *col; - /* pointer to corresponding column */ - double val; - /* (non-zero) coefficient value */ - NPPAIJ *r_prev; - /* pointer to previous coefficient in the same row */ - NPPAIJ *r_next; - /* pointer to next coefficient in the same row */ - NPPAIJ *c_prev; - /* pointer to previous coefficient in the same column */ - NPPAIJ *c_next; - /* pointer to next coefficient in the same column */ -}; - -struct NPPTSE -{ /* transformation stack entry */ - int (*func)(NPP *npp, void *info); - /* pointer to routine performing back transformation */ - void *info; - /* pointer to specific info (depends on the transformation) */ - NPPTSE *link; - /* pointer to another entry created *before* this entry */ -}; - -struct NPPLFE -{ /* linear form element */ - int ref; - /* row/column reference number */ - double val; - /* (non-zero) coefficient value */ - NPPLFE *next; - /* pointer to another element */ -}; - -#define npp_create_wksp _glp_npp_create_wksp -NPP *npp_create_wksp(void); -/* create LP/MIP preprocessor workspace */ - -#define npp_insert_row _glp_npp_insert_row -void npp_insert_row(NPP *npp, NPPROW *row, int where); -/* insert row to the row list */ - -#define npp_remove_row _glp_npp_remove_row -void npp_remove_row(NPP *npp, NPPROW *row); -/* remove row from the row list */ - -#define npp_activate_row _glp_npp_activate_row -void npp_activate_row(NPP *npp, NPPROW *row); -/* make row active */ - -#define npp_deactivate_row _glp_npp_deactivate_row -void npp_deactivate_row(NPP *npp, NPPROW *row); -/* make row inactive */ - -#define npp_insert_col _glp_npp_insert_col -void npp_insert_col(NPP *npp, NPPCOL *col, int where); -/* insert column to the column list */ - -#define npp_remove_col _glp_npp_remove_col -void npp_remove_col(NPP *npp, NPPCOL *col); -/* remove column from the column list */ - -#define npp_activate_col _glp_npp_activate_col -void npp_activate_col(NPP *npp, NPPCOL *col); -/* make column active */ - -#define npp_deactivate_col _glp_npp_deactivate_col -void npp_deactivate_col(NPP *npp, NPPCOL *col); -/* make column inactive */ - -#define npp_add_row _glp_npp_add_row -NPPROW *npp_add_row(NPP *npp); -/* add new row to the current problem */ - -#define npp_add_col _glp_npp_add_col -NPPCOL *npp_add_col(NPP *npp); -/* add new column to the current problem */ - -#define npp_add_aij _glp_npp_add_aij -NPPAIJ *npp_add_aij(NPP *npp, NPPROW *row, NPPCOL *col, double val); -/* add new element to the constraint matrix */ - -#define npp_row_nnz _glp_npp_row_nnz -int npp_row_nnz(NPP *npp, NPPROW *row); -/* count number of non-zero coefficients in row */ - -#define npp_col_nnz _glp_npp_col_nnz -int npp_col_nnz(NPP *npp, NPPCOL *col); -/* count number of non-zero coefficients in column */ - -#define npp_push_tse _glp_npp_push_tse -void *npp_push_tse(NPP *npp, int (*func)(NPP *npp, void *info), - int size); -/* push new entry to the transformation stack */ - -#define npp_erase_row _glp_npp_erase_row -void npp_erase_row(NPP *npp, NPPROW *row); -/* erase row content to make it empty */ - -#define npp_del_row _glp_npp_del_row -void npp_del_row(NPP *npp, NPPROW *row); -/* remove row from the current problem */ - -#define npp_del_col _glp_npp_del_col -void npp_del_col(NPP *npp, NPPCOL *col); -/* remove column from the current problem */ - -#define npp_del_aij _glp_npp_del_aij -void npp_del_aij(NPP *npp, NPPAIJ *aij); -/* remove element from the constraint matrix */ - -#define npp_load_prob _glp_npp_load_prob -void npp_load_prob(NPP *npp, glp_prob *orig, int names, int sol, - int scaling); -/* load original problem into the preprocessor workspace */ - -#define npp_build_prob _glp_npp_build_prob -void npp_build_prob(NPP *npp, glp_prob *prob); -/* build resultant (preprocessed) problem */ - -#define npp_postprocess _glp_npp_postprocess -void npp_postprocess(NPP *npp, glp_prob *prob); -/* postprocess solution from the resultant problem */ - -#define npp_unload_sol _glp_npp_unload_sol -void npp_unload_sol(NPP *npp, glp_prob *orig); -/* store solution to the original problem */ - -#define npp_delete_wksp _glp_npp_delete_wksp -void npp_delete_wksp(NPP *npp); -/* delete LP/MIP preprocessor workspace */ - -#define npp_error() - -#define npp_free_row _glp_npp_free_row -void npp_free_row(NPP *npp, NPPROW *p); -/* process free (unbounded) row */ - -#define npp_geq_row _glp_npp_geq_row -void npp_geq_row(NPP *npp, NPPROW *p); -/* process row of 'not less than' type */ - -#define npp_leq_row _glp_npp_leq_row -void npp_leq_row(NPP *npp, NPPROW *p); -/* process row of 'not greater than' type */ - -#define npp_free_col _glp_npp_free_col -void npp_free_col(NPP *npp, NPPCOL *q); -/* process free (unbounded) column */ - -#define npp_lbnd_col _glp_npp_lbnd_col -void npp_lbnd_col(NPP *npp, NPPCOL *q); -/* process column with (non-zero) lower bound */ - -#define npp_ubnd_col _glp_npp_ubnd_col -void npp_ubnd_col(NPP *npp, NPPCOL *q); -/* process column with upper bound */ - -#define npp_dbnd_col _glp_npp_dbnd_col -void npp_dbnd_col(NPP *npp, NPPCOL *q); -/* process non-negative column with upper bound */ - -#define npp_fixed_col _glp_npp_fixed_col -void npp_fixed_col(NPP *npp, NPPCOL *q); -/* process fixed column */ - -#define npp_make_equality _glp_npp_make_equality -int npp_make_equality(NPP *npp, NPPROW *p); -/* process row with almost identical bounds */ - -#define npp_make_fixed _glp_npp_make_fixed -int npp_make_fixed(NPP *npp, NPPCOL *q); -/* process column with almost identical bounds */ - -#define npp_empty_row _glp_npp_empty_row -int npp_empty_row(NPP *npp, NPPROW *p); -/* process empty row */ - -#define npp_empty_col _glp_npp_empty_col -int npp_empty_col(NPP *npp, NPPCOL *q); -/* process empty column */ - -#define npp_implied_value _glp_npp_implied_value -int npp_implied_value(NPP *npp, NPPCOL *q, double s); -/* process implied column value */ - -#define npp_eq_singlet _glp_npp_eq_singlet -int npp_eq_singlet(NPP *npp, NPPROW *p); -/* process row singleton (equality constraint) */ - -#define npp_implied_lower _glp_npp_implied_lower -int npp_implied_lower(NPP *npp, NPPCOL *q, double l); -/* process implied column lower bound */ - -#define npp_implied_upper _glp_npp_implied_upper -int npp_implied_upper(NPP *npp, NPPCOL *q, double u); -/* process implied upper bound of column */ - -#define npp_ineq_singlet _glp_npp_ineq_singlet -int npp_ineq_singlet(NPP *npp, NPPROW *p); -/* process row singleton (inequality constraint) */ - -#define npp_implied_slack _glp_npp_implied_slack -void npp_implied_slack(NPP *npp, NPPCOL *q); -/* process column singleton (implied slack variable) */ - -#define npp_implied_free _glp_npp_implied_free -int npp_implied_free(NPP *npp, NPPCOL *q); -/* process column singleton (implied free variable) */ - -#define npp_eq_doublet _glp_npp_eq_doublet -NPPCOL *npp_eq_doublet(NPP *npp, NPPROW *p); -/* process row doubleton (equality constraint) */ - -#define npp_forcing_row _glp_npp_forcing_row -int npp_forcing_row(NPP *npp, NPPROW *p, int at); -/* process forcing row */ - -#define npp_analyze_row _glp_npp_analyze_row -int npp_analyze_row(NPP *npp, NPPROW *p); -/* perform general row analysis */ - -#define npp_inactive_bound _glp_npp_inactive_bound -void npp_inactive_bound(NPP *npp, NPPROW *p, int which); -/* remove row lower/upper inactive bound */ - -#define npp_implied_bounds _glp_npp_implied_bounds -void npp_implied_bounds(NPP *npp, NPPROW *p); -/* determine implied column bounds */ - -#define npp_binarize_prob _glp_npp_binarize_prob -int npp_binarize_prob(NPP *npp); -/* binarize MIP problem */ - -#define npp_is_packing _glp_npp_is_packing -int npp_is_packing(NPP *npp, NPPROW *row); -/* test if constraint is packing inequality */ - -#define npp_hidden_packing _glp_npp_hidden_packing -int npp_hidden_packing(NPP *npp, NPPROW *row); -/* identify hidden packing inequality */ - -#define npp_implied_packing _glp_npp_implied_packing -int npp_implied_packing(NPP *npp, NPPROW *row, int which, - NPPCOL *var[], char set[]); -/* identify implied packing inequality */ - -#define npp_is_covering _glp_npp_is_covering -int npp_is_covering(NPP *npp, NPPROW *row); -/* test if constraint is covering inequality */ - -#define npp_hidden_covering _glp_npp_hidden_covering -int npp_hidden_covering(NPP *npp, NPPROW *row); -/* identify hidden covering inequality */ - -#define npp_is_partitioning _glp_npp_is_partitioning -int npp_is_partitioning(NPP *npp, NPPROW *row); -/* test if constraint is partitioning equality */ - -#define npp_reduce_ineq_coef _glp_npp_reduce_ineq_coef -int npp_reduce_ineq_coef(NPP *npp, NPPROW *row); -/* reduce inequality constraint coefficients */ - -#define npp_clean_prob _glp_npp_clean_prob -void npp_clean_prob(NPP *npp); -/* perform initial LP/MIP processing */ - -#define npp_process_row _glp_npp_process_row -int npp_process_row(NPP *npp, NPPROW *row, int hard); -/* perform basic row processing */ - -#define npp_improve_bounds _glp_npp_improve_bounds -int npp_improve_bounds(NPP *npp, NPPROW *row, int flag); -/* improve current column bounds */ - -#define npp_process_col _glp_npp_process_col -int npp_process_col(NPP *npp, NPPCOL *col); -/* perform basic column processing */ - -#define npp_process_prob _glp_npp_process_prob -int npp_process_prob(NPP *npp, int hard); -/* perform basic LP/MIP processing */ - -#define npp_simplex _glp_npp_simplex -int npp_simplex(NPP *npp, const glp_smcp *parm); -/* process LP prior to applying primal/dual simplex method */ - -#define npp_integer _glp_npp_integer -int npp_integer(NPP *npp, const glp_iocp *parm); -/* process MIP prior to applying branch-and-bound method */ - -/**********************************************************************/ - -#define npp_sat_free_row _glp_npp_sat_free_row -void npp_sat_free_row(NPP *npp, NPPROW *p); -/* process free (unbounded) row */ - -#define npp_sat_fixed_col _glp_npp_sat_fixed_col -int npp_sat_fixed_col(NPP *npp, NPPCOL *q); -/* process fixed column */ - -#define npp_sat_is_bin_comb _glp_npp_sat_is_bin_comb -int npp_sat_is_bin_comb(NPP *npp, NPPROW *row); -/* test if row is binary combination */ - -#define npp_sat_num_pos_coef _glp_npp_sat_num_pos_coef -int npp_sat_num_pos_coef(NPP *npp, NPPROW *row); -/* determine number of positive coefficients */ - -#define npp_sat_num_neg_coef _glp_npp_sat_num_neg_coef -int npp_sat_num_neg_coef(NPP *npp, NPPROW *row); -/* determine number of negative coefficients */ - -#define npp_sat_is_cover_ineq _glp_npp_sat_is_cover_ineq -int npp_sat_is_cover_ineq(NPP *npp, NPPROW *row); -/* test if row is covering inequality */ - -#define npp_sat_is_pack_ineq _glp_npp_sat_is_pack_ineq -int npp_sat_is_pack_ineq(NPP *npp, NPPROW *row); -/* test if row is packing inequality */ - -#define npp_sat_is_partn_eq _glp_npp_sat_is_partn_eq -int npp_sat_is_partn_eq(NPP *npp, NPPROW *row); -/* test if row is partitioning equality */ - -#define npp_sat_reverse_row _glp_npp_sat_reverse_row -int npp_sat_reverse_row(NPP *npp, NPPROW *row); -/* multiply both sides of row by -1 */ - -#define npp_sat_split_pack _glp_npp_sat_split_pack -NPPROW *npp_sat_split_pack(NPP *npp, NPPROW *row, int nnn); -/* split packing inequality */ - -#define npp_sat_encode_pack _glp_npp_sat_encode_pack -void npp_sat_encode_pack(NPP *npp, NPPROW *row); -/* encode packing inequality */ - -typedef struct NPPLIT NPPLIT; -typedef struct NPPLSE NPPLSE; -typedef struct NPPSED NPPSED; - -struct NPPLIT -{ /* literal (binary variable or its negation) */ - NPPCOL *col; - /* pointer to binary variable; NULL means constant false */ - int neg; - /* negation flag: - 0 - literal is variable (or constant false) - 1 - literal is negation of variable (or constant true) */ -}; - -struct NPPLSE -{ /* literal set element */ - NPPLIT lit; - /* literal */ - NPPLSE *next; - /* pointer to another element */ -}; - -struct NPPSED -{ /* summation encoding descriptor */ - /* this struct describes the equality - x + y + z = s + 2 * c, - which was encoded as CNF and included into the transformed - problem; here x and y are literals, z is either a literal or - constant zero, s and c are binary variables modeling, resp., - the low and high (carry) sum bits */ - NPPLIT x, y, z; - /* literals; if z.col = NULL, z is constant zero */ - NPPCOL *s, *c; - /* binary variables modeling the sum bits */ -}; - -#define npp_sat_encode_sum2 _glp_npp_sat_encode_sum2 -void npp_sat_encode_sum2(NPP *npp, NPPLSE *set, NPPSED *sed); -/* encode 2-bit summation */ - -#define npp_sat_encode_sum3 _glp_npp_sat_encode_sum3 -void npp_sat_encode_sum3(NPP *npp, NPPLSE *set, NPPSED *sed); -/* encode 3-bit summation */ - -#define npp_sat_encode_sum_ax _glp_npp_sat_encode_sum_ax -int npp_sat_encode_sum_ax(NPP *npp, NPPROW *row, NPPLIT y[]); -/* encode linear combination of 0-1 variables */ - -#define npp_sat_normalize_clause _glp_npp_sat_normalize_clause -int npp_sat_normalize_clause(NPP *npp, int size, NPPLIT lit[]); -/* normalize clause */ - -#define npp_sat_encode_clause _glp_npp_sat_encode_clause -NPPROW *npp_sat_encode_clause(NPP *npp, int size, NPPLIT lit[]); -/* translate clause to cover inequality */ - -#define npp_sat_encode_geq _glp_npp_sat_encode_geq -int npp_sat_encode_geq(NPP *npp, int n, NPPLIT y[], int rhs); -/* encode "not less than" constraint */ - -#define npp_sat_encode_leq _glp_npp_sat_encode_leq -int npp_sat_encode_leq(NPP *npp, int n, NPPLIT y[], int rhs); -/* encode "not greater than" constraint */ - -#define npp_sat_encode_row _glp_npp_sat_encode_row -int npp_sat_encode_row(NPP *npp, NPPROW *row); -/* encode constraint (row) of general type */ - -#define npp_sat_encode_prob _glp_npp_sat_encode_prob -int npp_sat_encode_prob(NPP *npp); -/* encode 0-1 feasibility problem */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpnpp01.c b/resources/3rdparty/glpk-4.53/src/glpnpp01.c deleted file mode 100644 index 9eb59f28e..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpnpp01.c +++ /dev/null @@ -1,938 +0,0 @@ -/* glpnpp01.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpnpp.h" - -NPP *npp_create_wksp(void) -{ /* create LP/MIP preprocessor workspace */ - NPP *npp; - npp = xmalloc(sizeof(NPP)); - npp->orig_dir = 0; - npp->orig_m = npp->orig_n = npp->orig_nnz = 0; - npp->pool = dmp_create_pool(); - npp->name = npp->obj = NULL; - npp->c0 = 0.0; - npp->nrows = npp->ncols = 0; - npp->r_head = npp->r_tail = NULL; - npp->c_head = npp->c_tail = NULL; - npp->stack = dmp_create_pool(); - npp->top = NULL; -#if 0 /* 16/XII-2009 */ - memset(&npp->count, 0, sizeof(npp->count)); -#endif - npp->m = npp->n = npp->nnz = 0; - npp->row_ref = npp->col_ref = NULL; - npp->sol = npp->scaling = 0; - npp->p_stat = npp->d_stat = npp->t_stat = npp->i_stat = 0; - npp->r_stat = NULL; - /*npp->r_prim =*/ npp->r_pi = NULL; - npp->c_stat = NULL; - npp->c_value = /*npp->c_dual =*/ NULL; - return npp; -} - -void npp_insert_row(NPP *npp, NPPROW *row, int where) -{ /* insert row to the row list */ - if (where == 0) - { /* insert row to the beginning of the row list */ - row->prev = NULL; - row->next = npp->r_head; - if (row->next == NULL) - npp->r_tail = row; - else - row->next->prev = row; - npp->r_head = row; - } - else - { /* insert row to the end of the row list */ - row->prev = npp->r_tail; - row->next = NULL; - if (row->prev == NULL) - npp->r_head = row; - else - row->prev->next = row; - npp->r_tail = row; - } - return; -} - -void npp_remove_row(NPP *npp, NPPROW *row) -{ /* remove row from the row list */ - if (row->prev == NULL) - npp->r_head = row->next; - else - row->prev->next = row->next; - if (row->next == NULL) - npp->r_tail = row->prev; - else - row->next->prev = row->prev; - return; -} - -void npp_activate_row(NPP *npp, NPPROW *row) -{ /* make row active */ - if (!row->temp) - { row->temp = 1; - /* move the row to the beginning of the row list */ - npp_remove_row(npp, row); - npp_insert_row(npp, row, 0); - } - return; -} - -void npp_deactivate_row(NPP *npp, NPPROW *row) -{ /* make row inactive */ - if (row->temp) - { row->temp = 0; - /* move the row to the end of the row list */ - npp_remove_row(npp, row); - npp_insert_row(npp, row, 1); - } - return; -} - -void npp_insert_col(NPP *npp, NPPCOL *col, int where) -{ /* insert column to the column list */ - if (where == 0) - { /* insert column to the beginning of the column list */ - col->prev = NULL; - col->next = npp->c_head; - if (col->next == NULL) - npp->c_tail = col; - else - col->next->prev = col; - npp->c_head = col; - } - else - { /* insert column to the end of the column list */ - col->prev = npp->c_tail; - col->next = NULL; - if (col->prev == NULL) - npp->c_head = col; - else - col->prev->next = col; - npp->c_tail = col; - } - return; -} - -void npp_remove_col(NPP *npp, NPPCOL *col) -{ /* remove column from the column list */ - if (col->prev == NULL) - npp->c_head = col->next; - else - col->prev->next = col->next; - if (col->next == NULL) - npp->c_tail = col->prev; - else - col->next->prev = col->prev; - return; -} - -void npp_activate_col(NPP *npp, NPPCOL *col) -{ /* make column active */ - if (!col->temp) - { col->temp = 1; - /* move the column to the beginning of the column list */ - npp_remove_col(npp, col); - npp_insert_col(npp, col, 0); - } - return; -} - -void npp_deactivate_col(NPP *npp, NPPCOL *col) -{ /* make column inactive */ - if (col->temp) - { col->temp = 0; - /* move the column to the end of the column list */ - npp_remove_col(npp, col); - npp_insert_col(npp, col, 1); - } - return; -} - -NPPROW *npp_add_row(NPP *npp) -{ /* add new row to the current problem */ - NPPROW *row; - row = dmp_get_atom(npp->pool, sizeof(NPPROW)); - row->i = ++(npp->nrows); - row->name = NULL; - row->lb = -DBL_MAX, row->ub = +DBL_MAX; - row->ptr = NULL; - row->temp = 0; - npp_insert_row(npp, row, 1); - return row; -} - -NPPCOL *npp_add_col(NPP *npp) -{ /* add new column to the current problem */ - NPPCOL *col; - col = dmp_get_atom(npp->pool, sizeof(NPPCOL)); - col->j = ++(npp->ncols); - col->name = NULL; -#if 0 - col->kind = GLP_CV; -#else - col->is_int = 0; -#endif - col->lb = col->ub = col->coef = 0.0; - col->ptr = NULL; - col->temp = 0; - npp_insert_col(npp, col, 1); - return col; -} - -NPPAIJ *npp_add_aij(NPP *npp, NPPROW *row, NPPCOL *col, double val) -{ /* add new element to the constraint matrix */ - NPPAIJ *aij; - aij = dmp_get_atom(npp->pool, sizeof(NPPAIJ)); - aij->row = row; - aij->col = col; - aij->val = val; - aij->r_prev = NULL; - aij->r_next = row->ptr; - aij->c_prev = NULL; - aij->c_next = col->ptr; - if (aij->r_next != NULL) - aij->r_next->r_prev = aij; - if (aij->c_next != NULL) - aij->c_next->c_prev = aij; - row->ptr = col->ptr = aij; - return aij; -} - -int npp_row_nnz(NPP *npp, NPPROW *row) -{ /* count number of non-zero coefficients in row */ - NPPAIJ *aij; - int nnz; - xassert(npp == npp); - nnz = 0; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - nnz++; - return nnz; -} - -int npp_col_nnz(NPP *npp, NPPCOL *col) -{ /* count number of non-zero coefficients in column */ - NPPAIJ *aij; - int nnz; - xassert(npp == npp); - nnz = 0; - for (aij = col->ptr; aij != NULL; aij = aij->c_next) - nnz++; - return nnz; -} - -void *npp_push_tse(NPP *npp, int (*func)(NPP *npp, void *info), - int size) -{ /* push new entry to the transformation stack */ - NPPTSE *tse; - tse = dmp_get_atom(npp->stack, sizeof(NPPTSE)); - tse->func = func; - tse->info = dmp_get_atom(npp->stack, size); - tse->link = npp->top; - npp->top = tse; - return tse->info; -} - -#if 1 /* 23/XII-2009 */ -void npp_erase_row(NPP *npp, NPPROW *row) -{ /* erase row content to make it empty */ - NPPAIJ *aij; - while (row->ptr != NULL) - { aij = row->ptr; - row->ptr = aij->r_next; - if (aij->c_prev == NULL) - aij->col->ptr = aij->c_next; - else - aij->c_prev->c_next = aij->c_next; - if (aij->c_next == NULL) - ; - else - aij->c_next->c_prev = aij->c_prev; - dmp_free_atom(npp->pool, aij, sizeof(NPPAIJ)); - } - return; -} -#endif - -void npp_del_row(NPP *npp, NPPROW *row) -{ /* remove row from the current problem */ -#if 0 /* 23/XII-2009 */ - NPPAIJ *aij; -#endif - if (row->name != NULL) - dmp_free_atom(npp->pool, row->name, strlen(row->name)+1); -#if 0 /* 23/XII-2009 */ - while (row->ptr != NULL) - { aij = row->ptr; - row->ptr = aij->r_next; - if (aij->c_prev == NULL) - aij->col->ptr = aij->c_next; - else - aij->c_prev->c_next = aij->c_next; - if (aij->c_next == NULL) - ; - else - aij->c_next->c_prev = aij->c_prev; - dmp_free_atom(npp->pool, aij, sizeof(NPPAIJ)); - } -#else - npp_erase_row(npp, row); -#endif - npp_remove_row(npp, row); - dmp_free_atom(npp->pool, row, sizeof(NPPROW)); - return; -} - -void npp_del_col(NPP *npp, NPPCOL *col) -{ /* remove column from the current problem */ - NPPAIJ *aij; - if (col->name != NULL) - dmp_free_atom(npp->pool, col->name, strlen(col->name)+1); - while (col->ptr != NULL) - { aij = col->ptr; - col->ptr = aij->c_next; - if (aij->r_prev == NULL) - aij->row->ptr = aij->r_next; - else - aij->r_prev->r_next = aij->r_next; - if (aij->r_next == NULL) - ; - else - aij->r_next->r_prev = aij->r_prev; - dmp_free_atom(npp->pool, aij, sizeof(NPPAIJ)); - } - npp_remove_col(npp, col); - dmp_free_atom(npp->pool, col, sizeof(NPPCOL)); - return; -} - -void npp_del_aij(NPP *npp, NPPAIJ *aij) -{ /* remove element from the constraint matrix */ - if (aij->r_prev == NULL) - aij->row->ptr = aij->r_next; - else - aij->r_prev->r_next = aij->r_next; - if (aij->r_next == NULL) - ; - else - aij->r_next->r_prev = aij->r_prev; - if (aij->c_prev == NULL) - aij->col->ptr = aij->c_next; - else - aij->c_prev->c_next = aij->c_next; - if (aij->c_next == NULL) - ; - else - aij->c_next->c_prev = aij->c_prev; - dmp_free_atom(npp->pool, aij, sizeof(NPPAIJ)); - return; -} - -void npp_load_prob(NPP *npp, glp_prob *orig, int names, int sol, - int scaling) -{ /* load original problem into the preprocessor workspace */ - int m = orig->m; - int n = orig->n; - NPPROW **link; - int i, j; - double dir; - xassert(names == GLP_OFF || names == GLP_ON); - xassert(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP); - xassert(scaling == GLP_OFF || scaling == GLP_ON); - if (sol == GLP_MIP) xassert(!scaling); - npp->orig_dir = orig->dir; - if (npp->orig_dir == GLP_MIN) - dir = +1.0; - else if (npp->orig_dir == GLP_MAX) - dir = -1.0; - else - xassert(npp != npp); - npp->orig_m = m; - npp->orig_n = n; - npp->orig_nnz = orig->nnz; - if (names && orig->name != NULL) - { npp->name = dmp_get_atom(npp->pool, strlen(orig->name)+1); - strcpy(npp->name, orig->name); - } - if (names && orig->obj != NULL) - { npp->obj = dmp_get_atom(npp->pool, strlen(orig->obj)+1); - strcpy(npp->obj, orig->obj); - } - npp->c0 = dir * orig->c0; - /* load rows */ - link = xcalloc(1+m, sizeof(NPPROW *)); - for (i = 1; i <= m; i++) - { GLPROW *rrr = orig->row[i]; - NPPROW *row; - link[i] = row = npp_add_row(npp); - xassert(row->i == i); - if (names && rrr->name != NULL) - { row->name = dmp_get_atom(npp->pool, strlen(rrr->name)+1); - strcpy(row->name, rrr->name); - } - if (!scaling) - { if (rrr->type == GLP_FR) - row->lb = -DBL_MAX, row->ub = +DBL_MAX; - else if (rrr->type == GLP_LO) - row->lb = rrr->lb, row->ub = +DBL_MAX; - else if (rrr->type == GLP_UP) - row->lb = -DBL_MAX, row->ub = rrr->ub; - else if (rrr->type == GLP_DB) - row->lb = rrr->lb, row->ub = rrr->ub; - else if (rrr->type == GLP_FX) - row->lb = row->ub = rrr->lb; - else - xassert(rrr != rrr); - } - else - { double rii = rrr->rii; - if (rrr->type == GLP_FR) - row->lb = -DBL_MAX, row->ub = +DBL_MAX; - else if (rrr->type == GLP_LO) - row->lb = rrr->lb * rii, row->ub = +DBL_MAX; - else if (rrr->type == GLP_UP) - row->lb = -DBL_MAX, row->ub = rrr->ub * rii; - else if (rrr->type == GLP_DB) - row->lb = rrr->lb * rii, row->ub = rrr->ub * rii; - else if (rrr->type == GLP_FX) - row->lb = row->ub = rrr->lb * rii; - else - xassert(rrr != rrr); - } - } - /* load columns and constraint coefficients */ - for (j = 1; j <= n; j++) - { GLPCOL *ccc = orig->col[j]; - GLPAIJ *aaa; - NPPCOL *col; - col = npp_add_col(npp); - xassert(col->j == j); - if (names && ccc->name != NULL) - { col->name = dmp_get_atom(npp->pool, strlen(ccc->name)+1); - strcpy(col->name, ccc->name); - } - if (sol == GLP_MIP) -#if 0 - col->kind = ccc->kind; -#else - col->is_int = (char)(ccc->kind == GLP_IV); -#endif - if (!scaling) - { if (ccc->type == GLP_FR) - col->lb = -DBL_MAX, col->ub = +DBL_MAX; - else if (ccc->type == GLP_LO) - col->lb = ccc->lb, col->ub = +DBL_MAX; - else if (ccc->type == GLP_UP) - col->lb = -DBL_MAX, col->ub = ccc->ub; - else if (ccc->type == GLP_DB) - col->lb = ccc->lb, col->ub = ccc->ub; - else if (ccc->type == GLP_FX) - col->lb = col->ub = ccc->lb; - else - xassert(ccc != ccc); - col->coef = dir * ccc->coef; - for (aaa = ccc->ptr; aaa != NULL; aaa = aaa->c_next) - npp_add_aij(npp, link[aaa->row->i], col, aaa->val); - } - else - { double sjj = ccc->sjj; - if (ccc->type == GLP_FR) - col->lb = -DBL_MAX, col->ub = +DBL_MAX; - else if (ccc->type == GLP_LO) - col->lb = ccc->lb / sjj, col->ub = +DBL_MAX; - else if (ccc->type == GLP_UP) - col->lb = -DBL_MAX, col->ub = ccc->ub / sjj; - else if (ccc->type == GLP_DB) - col->lb = ccc->lb / sjj, col->ub = ccc->ub / sjj; - else if (ccc->type == GLP_FX) - col->lb = col->ub = ccc->lb / sjj; - else - xassert(ccc != ccc); - col->coef = dir * ccc->coef * sjj; - for (aaa = ccc->ptr; aaa != NULL; aaa = aaa->c_next) - npp_add_aij(npp, link[aaa->row->i], col, - aaa->row->rii * aaa->val * sjj); - } - } - xfree(link); - /* keep solution indicator and scaling option */ - npp->sol = sol; - npp->scaling = scaling; - return; -} - -void npp_build_prob(NPP *npp, glp_prob *prob) -{ /* build resultant (preprocessed) problem */ - NPPROW *row; - NPPCOL *col; - NPPAIJ *aij; - int i, j, type, len, *ind; - double dir, *val; - glp_erase_prob(prob); - glp_set_prob_name(prob, npp->name); - glp_set_obj_name(prob, npp->obj); - glp_set_obj_dir(prob, npp->orig_dir); - if (npp->orig_dir == GLP_MIN) - dir = +1.0; - else if (npp->orig_dir == GLP_MAX) - dir = -1.0; - else - xassert(npp != npp); - glp_set_obj_coef(prob, 0, dir * npp->c0); - /* build rows */ - for (row = npp->r_head; row != NULL; row = row->next) - { row->temp = i = glp_add_rows(prob, 1); - glp_set_row_name(prob, i, row->name); - if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) - type = GLP_FR; - else if (row->ub == +DBL_MAX) - type = GLP_LO; - else if (row->lb == -DBL_MAX) - type = GLP_UP; - else if (row->lb != row->ub) - type = GLP_DB; - else - type = GLP_FX; - glp_set_row_bnds(prob, i, type, row->lb, row->ub); - } - /* build columns and the constraint matrix */ - ind = xcalloc(1+prob->m, sizeof(int)); - val = xcalloc(1+prob->m, sizeof(double)); - for (col = npp->c_head; col != NULL; col = col->next) - { j = glp_add_cols(prob, 1); - glp_set_col_name(prob, j, col->name); -#if 0 - glp_set_col_kind(prob, j, col->kind); -#else - glp_set_col_kind(prob, j, col->is_int ? GLP_IV : GLP_CV); -#endif - if (col->lb == -DBL_MAX && col->ub == +DBL_MAX) - type = GLP_FR; - else if (col->ub == +DBL_MAX) - type = GLP_LO; - else if (col->lb == -DBL_MAX) - type = GLP_UP; - else if (col->lb != col->ub) - type = GLP_DB; - else - type = GLP_FX; - glp_set_col_bnds(prob, j, type, col->lb, col->ub); - glp_set_obj_coef(prob, j, dir * col->coef); - len = 0; - for (aij = col->ptr; aij != NULL; aij = aij->c_next) - { len++; - ind[len] = aij->row->temp; - val[len] = aij->val; - } - glp_set_mat_col(prob, j, len, ind, val); - } - xfree(ind); - xfree(val); - /* resultant problem has been built */ - npp->m = prob->m; - npp->n = prob->n; - npp->nnz = prob->nnz; - npp->row_ref = xcalloc(1+npp->m, sizeof(int)); - npp->col_ref = xcalloc(1+npp->n, sizeof(int)); - for (row = npp->r_head, i = 0; row != NULL; row = row->next) - npp->row_ref[++i] = row->i; - for (col = npp->c_head, j = 0; col != NULL; col = col->next) - npp->col_ref[++j] = col->j; - /* transformed problem segment is no longer needed */ - dmp_delete_pool(npp->pool), npp->pool = NULL; - npp->name = npp->obj = NULL; - npp->c0 = 0.0; - npp->r_head = npp->r_tail = NULL; - npp->c_head = npp->c_tail = NULL; - return; -} - -void npp_postprocess(NPP *npp, glp_prob *prob) -{ /* postprocess solution from the resultant problem */ - GLPROW *row; - GLPCOL *col; - NPPTSE *tse; - int i, j, k; - double dir; - xassert(npp->orig_dir == prob->dir); - if (npp->orig_dir == GLP_MIN) - dir = +1.0; - else if (npp->orig_dir == GLP_MAX) - dir = -1.0; - else - xassert(npp != npp); -#if 0 /* 11/VII-2013; due to call from ios_main */ - xassert(npp->m == prob->m); -#else - if (npp->sol != GLP_MIP) - xassert(npp->m == prob->m); -#endif - xassert(npp->n == prob->n); -#if 0 /* 11/VII-2013; due to call from ios_main */ - xassert(npp->nnz == prob->nnz); -#else - if (npp->sol != GLP_MIP) - xassert(npp->nnz == prob->nnz); -#endif - /* copy solution status */ - if (npp->sol == GLP_SOL) - { npp->p_stat = prob->pbs_stat; - npp->d_stat = prob->dbs_stat; - } - else if (npp->sol == GLP_IPT) - npp->t_stat = prob->ipt_stat; - else if (npp->sol == GLP_MIP) - npp->i_stat = prob->mip_stat; - else - xassert(npp != npp); - /* allocate solution arrays */ - if (npp->sol == GLP_SOL) - { if (npp->r_stat == NULL) - npp->r_stat = xcalloc(1+npp->nrows, sizeof(char)); - for (i = 1; i <= npp->nrows; i++) - npp->r_stat[i] = 0; - if (npp->c_stat == NULL) - npp->c_stat = xcalloc(1+npp->ncols, sizeof(char)); - for (j = 1; j <= npp->ncols; j++) - npp->c_stat[j] = 0; - } -#if 0 - if (npp->r_prim == NULL) - npp->r_prim = xcalloc(1+npp->nrows, sizeof(double)); - for (i = 1; i <= npp->nrows; i++) - npp->r_prim[i] = DBL_MAX; -#endif - if (npp->c_value == NULL) - npp->c_value = xcalloc(1+npp->ncols, sizeof(double)); - for (j = 1; j <= npp->ncols; j++) - npp->c_value[j] = DBL_MAX; - if (npp->sol != GLP_MIP) - { if (npp->r_pi == NULL) - npp->r_pi = xcalloc(1+npp->nrows, sizeof(double)); - for (i = 1; i <= npp->nrows; i++) - npp->r_pi[i] = DBL_MAX; -#if 0 - if (npp->c_dual == NULL) - npp->c_dual = xcalloc(1+npp->ncols, sizeof(double)); - for (j = 1; j <= npp->ncols; j++) - npp->c_dual[j] = DBL_MAX; -#endif - } - /* copy solution components from the resultant problem */ - if (npp->sol == GLP_SOL) - { for (i = 1; i <= npp->m; i++) - { row = prob->row[i]; - k = npp->row_ref[i]; - npp->r_stat[k] = (char)row->stat; - /*npp->r_prim[k] = row->prim;*/ - npp->r_pi[k] = dir * row->dual; - } - for (j = 1; j <= npp->n; j++) - { col = prob->col[j]; - k = npp->col_ref[j]; - npp->c_stat[k] = (char)col->stat; - npp->c_value[k] = col->prim; - /*npp->c_dual[k] = dir * col->dual;*/ - } - } - else if (npp->sol == GLP_IPT) - { for (i = 1; i <= npp->m; i++) - { row = prob->row[i]; - k = npp->row_ref[i]; - /*npp->r_prim[k] = row->pval;*/ - npp->r_pi[k] = dir * row->dval; - } - for (j = 1; j <= npp->n; j++) - { col = prob->col[j]; - k = npp->col_ref[j]; - npp->c_value[k] = col->pval; - /*npp->c_dual[k] = dir * col->dval;*/ - } - } - else if (npp->sol == GLP_MIP) - { -#if 0 - for (i = 1; i <= npp->m; i++) - { row = prob->row[i]; - k = npp->row_ref[i]; - /*npp->r_prim[k] = row->mipx;*/ - } -#endif - for (j = 1; j <= npp->n; j++) - { col = prob->col[j]; - k = npp->col_ref[j]; - npp->c_value[k] = col->mipx; - } - } - else - xassert(npp != npp); - /* perform postprocessing to construct solution to the original - problem */ - for (tse = npp->top; tse != NULL; tse = tse->link) - { xassert(tse->func != NULL); - xassert(tse->func(npp, tse->info) == 0); - } - return; -} - -void npp_unload_sol(NPP *npp, glp_prob *orig) -{ /* store solution to the original problem */ - GLPROW *row; - GLPCOL *col; - int i, j; - double dir; - xassert(npp->orig_dir == orig->dir); - if (npp->orig_dir == GLP_MIN) - dir = +1.0; - else if (npp->orig_dir == GLP_MAX) - dir = -1.0; - else - xassert(npp != npp); - xassert(npp->orig_m == orig->m); - xassert(npp->orig_n == orig->n); - xassert(npp->orig_nnz == orig->nnz); - if (npp->sol == GLP_SOL) - { /* store basic solution */ - orig->valid = 0; - orig->pbs_stat = npp->p_stat; - orig->dbs_stat = npp->d_stat; - orig->obj_val = orig->c0; - orig->some = 0; - for (i = 1; i <= orig->m; i++) - { row = orig->row[i]; - row->stat = npp->r_stat[i]; - if (!npp->scaling) - { /*row->prim = npp->r_prim[i];*/ - row->dual = dir * npp->r_pi[i]; - } - else - { /*row->prim = npp->r_prim[i] / row->rii;*/ - row->dual = dir * npp->r_pi[i] * row->rii; - } - if (row->stat == GLP_BS) - row->dual = 0.0; - else if (row->stat == GLP_NL) - { xassert(row->type == GLP_LO || row->type == GLP_DB); - row->prim = row->lb; - } - else if (row->stat == GLP_NU) - { xassert(row->type == GLP_UP || row->type == GLP_DB); - row->prim = row->ub; - } - else if (row->stat == GLP_NF) - { xassert(row->type == GLP_FR); - row->prim = 0.0; - } - else if (row->stat == GLP_NS) - { xassert(row->type == GLP_FX); - row->prim = row->lb; - } - else - xassert(row != row); - } - for (j = 1; j <= orig->n; j++) - { col = orig->col[j]; - col->stat = npp->c_stat[j]; - if (!npp->scaling) - { col->prim = npp->c_value[j]; - /*col->dual = dir * npp->c_dual[j];*/ - } - else - { col->prim = npp->c_value[j] * col->sjj; - /*col->dual = dir * npp->c_dual[j] / col->sjj;*/ - } - if (col->stat == GLP_BS) - col->dual = 0.0; -#if 1 - else if (col->stat == GLP_NL) - { xassert(col->type == GLP_LO || col->type == GLP_DB); - col->prim = col->lb; - } - else if (col->stat == GLP_NU) - { xassert(col->type == GLP_UP || col->type == GLP_DB); - col->prim = col->ub; - } - else if (col->stat == GLP_NF) - { xassert(col->type == GLP_FR); - col->prim = 0.0; - } - else if (col->stat == GLP_NS) - { xassert(col->type == GLP_FX); - col->prim = col->lb; - } - else - xassert(col != col); -#endif - orig->obj_val += col->coef * col->prim; - } -#if 1 - /* compute primal values of inactive rows */ - for (i = 1; i <= orig->m; i++) - { row = orig->row[i]; - if (row->stat == GLP_BS) - { GLPAIJ *aij; - double temp; - temp = 0.0; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - temp += aij->val * aij->col->prim; - row->prim = temp; - } - } - /* compute reduced costs of active columns */ - for (j = 1; j <= orig->n; j++) - { col = orig->col[j]; - if (col->stat != GLP_BS) - { GLPAIJ *aij; - double temp; - temp = col->coef; - for (aij = col->ptr; aij != NULL; aij = aij->c_next) - temp -= aij->val * aij->row->dual; - col->dual = temp; - } - } -#endif - } - else if (npp->sol == GLP_IPT) - { /* store interior-point solution */ - orig->ipt_stat = npp->t_stat; - orig->ipt_obj = orig->c0; - for (i = 1; i <= orig->m; i++) - { row = orig->row[i]; - if (!npp->scaling) - { /*row->pval = npp->r_prim[i];*/ - row->dval = dir * npp->r_pi[i]; - } - else - { /*row->pval = npp->r_prim[i] / row->rii;*/ - row->dval = dir * npp->r_pi[i] * row->rii; - } - } - for (j = 1; j <= orig->n; j++) - { col = orig->col[j]; - if (!npp->scaling) - { col->pval = npp->c_value[j]; - /*col->dval = dir * npp->c_dual[j];*/ - } - else - { col->pval = npp->c_value[j] * col->sjj; - /*col->dval = dir * npp->c_dual[j] / col->sjj;*/ - } - orig->ipt_obj += col->coef * col->pval; - } -#if 1 - /* compute row primal values */ - for (i = 1; i <= orig->m; i++) - { row = orig->row[i]; - { GLPAIJ *aij; - double temp; - temp = 0.0; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - temp += aij->val * aij->col->pval; - row->pval = temp; - } - } - /* compute column dual values */ - for (j = 1; j <= orig->n; j++) - { col = orig->col[j]; - { GLPAIJ *aij; - double temp; - temp = col->coef; - for (aij = col->ptr; aij != NULL; aij = aij->c_next) - temp -= aij->val * aij->row->dval; - col->dval = temp; - } - } -#endif - } - else if (npp->sol == GLP_MIP) - { /* store MIP solution */ - xassert(!npp->scaling); - orig->mip_stat = npp->i_stat; - orig->mip_obj = orig->c0; -#if 0 - for (i = 1; i <= orig->m; i++) - { row = orig->row[i]; - /*row->mipx = npp->r_prim[i];*/ - } -#endif - for (j = 1; j <= orig->n; j++) - { col = orig->col[j]; - col->mipx = npp->c_value[j]; - if (col->kind == GLP_IV) - xassert(col->mipx == floor(col->mipx)); - orig->mip_obj += col->coef * col->mipx; - } -#if 1 - /* compute row primal values */ - for (i = 1; i <= orig->m; i++) - { row = orig->row[i]; - { GLPAIJ *aij; - double temp; - temp = 0.0; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - temp += aij->val * aij->col->mipx; - row->mipx = temp; - } - } -#endif - } - else - xassert(npp != npp); - return; -} - -void npp_delete_wksp(NPP *npp) -{ /* delete LP/MIP preprocessor workspace */ - if (npp->pool != NULL) - dmp_delete_pool(npp->pool); - if (npp->stack != NULL) - dmp_delete_pool(npp->stack); - if (npp->row_ref != NULL) - xfree(npp->row_ref); - if (npp->col_ref != NULL) - xfree(npp->col_ref); - if (npp->r_stat != NULL) - xfree(npp->r_stat); -#if 0 - if (npp->r_prim != NULL) - xfree(npp->r_prim); -#endif - if (npp->r_pi != NULL) - xfree(npp->r_pi); - if (npp->c_stat != NULL) - xfree(npp->c_stat); - if (npp->c_value != NULL) - xfree(npp->c_value); -#if 0 - if (npp->c_dual != NULL) - xfree(npp->c_dual); -#endif - xfree(npp); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpnpp02.c b/resources/3rdparty/glpk-4.53/src/glpnpp02.c deleted file mode 100644 index ec4a455b4..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpnpp02.c +++ /dev/null @@ -1,1434 +0,0 @@ -/* glpnpp02.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpnpp.h" - -/*********************************************************************** -* NAME -* -* npp_free_row - process free (unbounded) row -* -* SYNOPSIS -* -* #include "glpnpp.h" -* void npp_free_row(NPP *npp, NPPROW *p); -* -* DESCRIPTION -* -* The routine npp_free_row processes row p, which is free (i.e. has -* no finite bounds): -* -* -inf < sum a[p,j] x[j] < +inf. (1) -* j -* -* PROBLEM TRANSFORMATION -* -* Constraint (1) cannot be active, so it is redundant and can be -* removed from the original problem. -* -* Removing row p leads to removing a column of multiplier pi[p] for -* this row in the dual system. Since row p has no bounds, pi[p] = 0, -* so removing the column does not affect the dual solution. -* -* RECOVERING BASIC SOLUTION -* -* In solution to the original problem row p is inactive constraint, -* so it is assigned status GLP_BS, and multiplier pi[p] is assigned -* zero value. -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* In solution to the original problem row p is inactive constraint, -* so its multiplier pi[p] is assigned zero value. -* -* RECOVERING MIP SOLUTION -* -* None needed. */ - -struct free_row -{ /* free (unbounded) row */ - int p; - /* row reference number */ -}; - -static int rcv_free_row(NPP *npp, void *info); - -void npp_free_row(NPP *npp, NPPROW *p) -{ /* process free (unbounded) row */ - struct free_row *info; - /* the row must be free */ - xassert(p->lb == -DBL_MAX && p->ub == +DBL_MAX); - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_free_row, sizeof(struct free_row)); - info->p = p->i; - /* remove the row from the problem */ - npp_del_row(npp, p); - return; -} - -static int rcv_free_row(NPP *npp, void *_info) -{ /* recover free (unbounded) row */ - struct free_row *info = _info; - if (npp->sol == GLP_SOL) - npp->r_stat[info->p] = GLP_BS; - if (npp->sol != GLP_MIP) - npp->r_pi[info->p] = 0.0; - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_geq_row - process row of 'not less than' type -* -* SYNOPSIS -* -* #include "glpnpp.h" -* void npp_geq_row(NPP *npp, NPPROW *p); -* -* DESCRIPTION -* -* The routine npp_geq_row processes row p, which is 'not less than' -* inequality constraint: -* -* L[p] <= sum a[p,j] x[j] (<= U[p]), (1) -* j -* -* where L[p] < U[p], and upper bound may not exist (U[p] = +oo). -* -* PROBLEM TRANSFORMATION -* -* Constraint (1) can be replaced by equality constraint: -* -* sum a[p,j] x[j] - s = L[p], (2) -* j -* -* where -* -* 0 <= s (<= U[p] - L[p]) (3) -* -* is a non-negative surplus variable. -* -* Since in the primal system there appears column s having the only -* non-zero coefficient in row p, in the dual system there appears a -* new row: -* -* (-1) pi[p] + lambda = 0, (4) -* -* where (-1) is coefficient of column s in row p, pi[p] is multiplier -* of row p, lambda is multiplier of column q, 0 is coefficient of -* column s in the objective row. -* -* RECOVERING BASIC SOLUTION -* -* Status of row p in solution to the original problem is determined -* by its status and status of column q in solution to the transformed -* problem as follows: -* -* +--------------------------------------+------------------+ -* | Transformed problem | Original problem | -* +-----------------+--------------------+------------------+ -* | Status of row p | Status of column s | Status of row p | -* +-----------------+--------------------+------------------+ -* | GLP_BS | GLP_BS | N/A | -* | GLP_BS | GLP_NL | GLP_BS | -* | GLP_BS | GLP_NU | GLP_BS | -* | GLP_NS | GLP_BS | GLP_BS | -* | GLP_NS | GLP_NL | GLP_NL | -* | GLP_NS | GLP_NU | GLP_NU | -* +-----------------+--------------------+------------------+ -* -* Value of row multiplier pi[p] in solution to the original problem -* is the same as in solution to the transformed problem. -* -* 1. In solution to the transformed problem row p and column q cannot -* be basic at the same time; otherwise the basis matrix would have -* two linear dependent columns: unity column of auxiliary variable -* of row p and unity column of variable s. -* -* 2. Though in the transformed problem row p is equality constraint, -* it may be basic due to primal degenerate solution. -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* Value of row multiplier pi[p] in solution to the original problem -* is the same as in solution to the transformed problem. -* -* RECOVERING MIP SOLUTION -* -* None needed. */ - -struct ineq_row -{ /* inequality constraint row */ - int p; - /* row reference number */ - int s; - /* column reference number for slack/surplus variable */ -}; - -static int rcv_geq_row(NPP *npp, void *info); - -void npp_geq_row(NPP *npp, NPPROW *p) -{ /* process row of 'not less than' type */ - struct ineq_row *info; - NPPCOL *s; - /* the row must have lower bound */ - xassert(p->lb != -DBL_MAX); - xassert(p->lb < p->ub); - /* create column for surplus variable */ - s = npp_add_col(npp); - s->lb = 0.0; - s->ub = (p->ub == +DBL_MAX ? +DBL_MAX : p->ub - p->lb); - /* and add it to the transformed problem */ - npp_add_aij(npp, p, s, -1.0); - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_geq_row, sizeof(struct ineq_row)); - info->p = p->i; - info->s = s->j; - /* replace the row by equality constraint */ - p->ub = p->lb; - return; -} - -static int rcv_geq_row(NPP *npp, void *_info) -{ /* recover row of 'not less than' type */ - struct ineq_row *info = _info; - if (npp->sol == GLP_SOL) - { if (npp->r_stat[info->p] == GLP_BS) - { if (npp->c_stat[info->s] == GLP_BS) - { npp_error(); - return 1; - } - else if (npp->c_stat[info->s] == GLP_NL || - npp->c_stat[info->s] == GLP_NU) - npp->r_stat[info->p] = GLP_BS; - else - { npp_error(); - return 1; - } - } - else if (npp->r_stat[info->p] == GLP_NS) - { if (npp->c_stat[info->s] == GLP_BS) - npp->r_stat[info->p] = GLP_BS; - else if (npp->c_stat[info->s] == GLP_NL) - npp->r_stat[info->p] = GLP_NL; - else if (npp->c_stat[info->s] == GLP_NU) - npp->r_stat[info->p] = GLP_NU; - else - { npp_error(); - return 1; - } - } - else - { npp_error(); - return 1; - } - } - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_leq_row - process row of 'not greater than' type -* -* SYNOPSIS -* -* #include "glpnpp.h" -* void npp_leq_row(NPP *npp, NPPROW *p); -* -* DESCRIPTION -* -* The routine npp_leq_row processes row p, which is 'not greater than' -* inequality constraint: -* -* (L[p] <=) sum a[p,j] x[j] <= U[p], (1) -* j -* -* where L[p] < U[p], and lower bound may not exist (L[p] = +oo). -* -* PROBLEM TRANSFORMATION -* -* Constraint (1) can be replaced by equality constraint: -* -* sum a[p,j] x[j] + s = L[p], (2) -* j -* -* where -* -* 0 <= s (<= U[p] - L[p]) (3) -* -* is a non-negative slack variable. -* -* Since in the primal system there appears column s having the only -* non-zero coefficient in row p, in the dual system there appears a -* new row: -* -* (+1) pi[p] + lambda = 0, (4) -* -* where (+1) is coefficient of column s in row p, pi[p] is multiplier -* of row p, lambda is multiplier of column q, 0 is coefficient of -* column s in the objective row. -* -* RECOVERING BASIC SOLUTION -* -* Status of row p in solution to the original problem is determined -* by its status and status of column q in solution to the transformed -* problem as follows: -* -* +--------------------------------------+------------------+ -* | Transformed problem | Original problem | -* +-----------------+--------------------+------------------+ -* | Status of row p | Status of column s | Status of row p | -* +-----------------+--------------------+------------------+ -* | GLP_BS | GLP_BS | N/A | -* | GLP_BS | GLP_NL | GLP_BS | -* | GLP_BS | GLP_NU | GLP_BS | -* | GLP_NS | GLP_BS | GLP_BS | -* | GLP_NS | GLP_NL | GLP_NU | -* | GLP_NS | GLP_NU | GLP_NL | -* +-----------------+--------------------+------------------+ -* -* Value of row multiplier pi[p] in solution to the original problem -* is the same as in solution to the transformed problem. -* -* 1. In solution to the transformed problem row p and column q cannot -* be basic at the same time; otherwise the basis matrix would have -* two linear dependent columns: unity column of auxiliary variable -* of row p and unity column of variable s. -* -* 2. Though in the transformed problem row p is equality constraint, -* it may be basic due to primal degeneracy. -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* Value of row multiplier pi[p] in solution to the original problem -* is the same as in solution to the transformed problem. -* -* RECOVERING MIP SOLUTION -* -* None needed. */ - -static int rcv_leq_row(NPP *npp, void *info); - -void npp_leq_row(NPP *npp, NPPROW *p) -{ /* process row of 'not greater than' type */ - struct ineq_row *info; - NPPCOL *s; - /* the row must have upper bound */ - xassert(p->ub != +DBL_MAX); - xassert(p->lb < p->ub); - /* create column for slack variable */ - s = npp_add_col(npp); - s->lb = 0.0; - s->ub = (p->lb == -DBL_MAX ? +DBL_MAX : p->ub - p->lb); - /* and add it to the transformed problem */ - npp_add_aij(npp, p, s, +1.0); - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_leq_row, sizeof(struct ineq_row)); - info->p = p->i; - info->s = s->j; - /* replace the row by equality constraint */ - p->lb = p->ub; - return; -} - -static int rcv_leq_row(NPP *npp, void *_info) -{ /* recover row of 'not greater than' type */ - struct ineq_row *info = _info; - if (npp->sol == GLP_SOL) - { if (npp->r_stat[info->p] == GLP_BS) - { if (npp->c_stat[info->s] == GLP_BS) - { npp_error(); - return 1; - } - else if (npp->c_stat[info->s] == GLP_NL || - npp->c_stat[info->s] == GLP_NU) - npp->r_stat[info->p] = GLP_BS; - else - { npp_error(); - return 1; - } - } - else if (npp->r_stat[info->p] == GLP_NS) - { if (npp->c_stat[info->s] == GLP_BS) - npp->r_stat[info->p] = GLP_BS; - else if (npp->c_stat[info->s] == GLP_NL) - npp->r_stat[info->p] = GLP_NU; - else if (npp->c_stat[info->s] == GLP_NU) - npp->r_stat[info->p] = GLP_NL; - else - { npp_error(); - return 1; - } - } - else - { npp_error(); - return 1; - } - } - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_free_col - process free (unbounded) column -* -* SYNOPSIS -* -* #include "glpnpp.h" -* void npp_free_col(NPP *npp, NPPCOL *q); -* -* DESCRIPTION -* -* The routine npp_free_col processes column q, which is free (i.e. has -* no finite bounds): -* -* -oo < x[q] < +oo. (1) -* -* PROBLEM TRANSFORMATION -* -* Free (unbounded) variable can be replaced by the difference of two -* non-negative variables: -* -* x[q] = s' - s'', s', s'' >= 0. (2) -* -* Assuming that in the transformed problem x[q] becomes s', -* transformation (2) causes new column s'' to appear, which differs -* from column s' only in the sign of coefficients in constraint and -* objective rows. Thus, if in the dual system the following row -* corresponds to column s': -* -* sum a[i,q] pi[i] + lambda' = c[q], (3) -* i -* -* the row which corresponds to column s'' is the following: -* -* sum (-a[i,q]) pi[i] + lambda'' = -c[q]. (4) -* i -* -* Then from (3) and (4) it follows that: -* -* lambda' + lambda'' = 0 => lambda' = lmabda'' = 0, (5) -* -* where lambda' and lambda'' are multipliers for columns s' and s'', -* resp. -* -* RECOVERING BASIC SOLUTION -* -* With respect to (5) status of column q in solution to the original -* problem is determined by statuses of columns s' and s'' in solution -* to the transformed problem as follows: -* -* +--------------------------------------+------------------+ -* | Transformed problem | Original problem | -* +------------------+-------------------+------------------+ -* | Status of col s' | Status of col s'' | Status of col q | -* +------------------+-------------------+------------------+ -* | GLP_BS | GLP_BS | N/A | -* | GLP_BS | GLP_NL | GLP_BS | -* | GLP_NL | GLP_BS | GLP_BS | -* | GLP_NL | GLP_NL | GLP_NF | -* +------------------+-------------------+------------------+ -* -* Value of column q is computed with formula (2). -* -* 1. In solution to the transformed problem columns s' and s'' cannot -* be basic at the same time, because they differ only in the sign, -* hence, are linear dependent. -* -* 2. Though column q is free, it can be non-basic due to dual -* degeneracy. -* -* 3. If column q is integral, columns s' and s'' are also integral. -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* Value of column q is computed with formula (2). -* -* RECOVERING MIP SOLUTION -* -* Value of column q is computed with formula (2). */ - -struct free_col -{ /* free (unbounded) column */ - int q; - /* column reference number for variables x[q] and s' */ - int s; - /* column reference number for variable s'' */ -}; - -static int rcv_free_col(NPP *npp, void *info); - -void npp_free_col(NPP *npp, NPPCOL *q) -{ /* process free (unbounded) column */ - struct free_col *info; - NPPCOL *s; - NPPAIJ *aij; - /* the column must be free */ - xassert(q->lb == -DBL_MAX && q->ub == +DBL_MAX); - /* variable x[q] becomes s' */ - q->lb = 0.0, q->ub = +DBL_MAX; - /* create variable s'' */ - s = npp_add_col(npp); - s->is_int = q->is_int; - s->lb = 0.0, s->ub = +DBL_MAX; - /* duplicate objective coefficient */ - s->coef = -q->coef; - /* duplicate column of the constraint matrix */ - for (aij = q->ptr; aij != NULL; aij = aij->c_next) - npp_add_aij(npp, aij->row, s, -aij->val); - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_free_col, sizeof(struct free_col)); - info->q = q->j; - info->s = s->j; - return; -} - -static int rcv_free_col(NPP *npp, void *_info) -{ /* recover free (unbounded) column */ - struct free_col *info = _info; - if (npp->sol == GLP_SOL) - { if (npp->c_stat[info->q] == GLP_BS) - { if (npp->c_stat[info->s] == GLP_BS) - { npp_error(); - return 1; - } - else if (npp->c_stat[info->s] == GLP_NL) - npp->c_stat[info->q] = GLP_BS; - else - { npp_error(); - return -1; - } - } - else if (npp->c_stat[info->q] == GLP_NL) - { if (npp->c_stat[info->s] == GLP_BS) - npp->c_stat[info->q] = GLP_BS; - else if (npp->c_stat[info->s] == GLP_NL) - npp->c_stat[info->q] = GLP_NF; - else - { npp_error(); - return -1; - } - } - else - { npp_error(); - return -1; - } - } - /* compute value of x[q] with formula (2) */ - npp->c_value[info->q] -= npp->c_value[info->s]; - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_lbnd_col - process column with (non-zero) lower bound -* -* SYNOPSIS -* -* #include "glpnpp.h" -* void npp_lbnd_col(NPP *npp, NPPCOL *q); -* -* DESCRIPTION -* -* The routine npp_lbnd_col processes column q, which has (non-zero) -* lower bound: -* -* l[q] <= x[q] (<= u[q]), (1) -* -* where l[q] < u[q], and upper bound may not exist (u[q] = +oo). -* -* PROBLEM TRANSFORMATION -* -* Column q can be replaced as follows: -* -* x[q] = l[q] + s, (2) -* -* where -* -* 0 <= s (<= u[q] - l[q]) (3) -* -* is a non-negative variable. -* -* Substituting x[q] from (2) into the objective row, we have: -* -* z = sum c[j] x[j] + c0 = -* j -* -* = sum c[j] x[j] + c[q] x[q] + c0 = -* j!=q -* -* = sum c[j] x[j] + c[q] (l[q] + s) + c0 = -* j!=q -* -* = sum c[j] x[j] + c[q] s + c~0, -* -* where -* -* c~0 = c0 + c[q] l[q] (4) -* -* is the constant term of the objective in the transformed problem. -* Similarly, substituting x[q] into constraint row i, we have: -* -* L[i] <= sum a[i,j] x[j] <= U[i] ==> -* j -* -* L[i] <= sum a[i,j] x[j] + a[i,q] x[q] <= U[i] ==> -* j!=q -* -* L[i] <= sum a[i,j] x[j] + a[i,q] (l[q] + s) <= U[i] ==> -* j!=q -* -* L~[i] <= sum a[i,j] x[j] + a[i,q] s <= U~[i], -* j!=q -* -* where -* -* L~[i] = L[i] - a[i,q] l[q], U~[i] = U[i] - a[i,q] l[q] (5) -* -* are lower and upper bounds of row i in the transformed problem, -* resp. -* -* Transformation (2) does not affect the dual system. -* -* RECOVERING BASIC SOLUTION -* -* Status of column q in solution to the original problem is the same -* as in solution to the transformed problem (GLP_BS, GLP_NL or GLP_NU). -* Value of column q is computed with formula (2). -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* Value of column q is computed with formula (2). -* -* RECOVERING MIP SOLUTION -* -* Value of column q is computed with formula (2). */ - -struct bnd_col -{ /* bounded column */ - int q; - /* column reference number for variables x[q] and s */ - double bnd; - /* lower/upper bound l[q] or u[q] */ -}; - -static int rcv_lbnd_col(NPP *npp, void *info); - -void npp_lbnd_col(NPP *npp, NPPCOL *q) -{ /* process column with (non-zero) lower bound */ - struct bnd_col *info; - NPPROW *i; - NPPAIJ *aij; - /* the column must have non-zero lower bound */ - xassert(q->lb != 0.0); - xassert(q->lb != -DBL_MAX); - xassert(q->lb < q->ub); - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_lbnd_col, sizeof(struct bnd_col)); - info->q = q->j; - info->bnd = q->lb; - /* substitute x[q] into objective row */ - npp->c0 += q->coef * q->lb; - /* substitute x[q] into constraint rows */ - for (aij = q->ptr; aij != NULL; aij = aij->c_next) - { i = aij->row; - if (i->lb == i->ub) - i->ub = (i->lb -= aij->val * q->lb); - else - { if (i->lb != -DBL_MAX) - i->lb -= aij->val * q->lb; - if (i->ub != +DBL_MAX) - i->ub -= aij->val * q->lb; - } - } - /* column x[q] becomes column s */ - if (q->ub != +DBL_MAX) - q->ub -= q->lb; - q->lb = 0.0; - return; -} - -static int rcv_lbnd_col(NPP *npp, void *_info) -{ /* recover column with (non-zero) lower bound */ - struct bnd_col *info = _info; - if (npp->sol == GLP_SOL) - { if (npp->c_stat[info->q] == GLP_BS || - npp->c_stat[info->q] == GLP_NL || - npp->c_stat[info->q] == GLP_NU) - npp->c_stat[info->q] = npp->c_stat[info->q]; - else - { npp_error(); - return 1; - } - } - /* compute value of x[q] with formula (2) */ - npp->c_value[info->q] = info->bnd + npp->c_value[info->q]; - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_ubnd_col - process column with upper bound -* -* SYNOPSIS -* -* #include "glpnpp.h" -* void npp_ubnd_col(NPP *npp, NPPCOL *q); -* -* DESCRIPTION -* -* The routine npp_ubnd_col processes column q, which has upper bound: -* -* (l[q] <=) x[q] <= u[q], (1) -* -* where l[q] < u[q], and lower bound may not exist (l[q] = -oo). -* -* PROBLEM TRANSFORMATION -* -* Column q can be replaced as follows: -* -* x[q] = u[q] - s, (2) -* -* where -* -* 0 <= s (<= u[q] - l[q]) (3) -* -* is a non-negative variable. -* -* Substituting x[q] from (2) into the objective row, we have: -* -* z = sum c[j] x[j] + c0 = -* j -* -* = sum c[j] x[j] + c[q] x[q] + c0 = -* j!=q -* -* = sum c[j] x[j] + c[q] (u[q] - s) + c0 = -* j!=q -* -* = sum c[j] x[j] - c[q] s + c~0, -* -* where -* -* c~0 = c0 + c[q] u[q] (4) -* -* is the constant term of the objective in the transformed problem. -* Similarly, substituting x[q] into constraint row i, we have: -* -* L[i] <= sum a[i,j] x[j] <= U[i] ==> -* j -* -* L[i] <= sum a[i,j] x[j] + a[i,q] x[q] <= U[i] ==> -* j!=q -* -* L[i] <= sum a[i,j] x[j] + a[i,q] (u[q] - s) <= U[i] ==> -* j!=q -* -* L~[i] <= sum a[i,j] x[j] - a[i,q] s <= U~[i], -* j!=q -* -* where -* -* L~[i] = L[i] - a[i,q] u[q], U~[i] = U[i] - a[i,q] u[q] (5) -* -* are lower and upper bounds of row i in the transformed problem, -* resp. -* -* Note that in the transformed problem coefficients c[q] and a[i,q] -* change their sign. Thus, the row of the dual system corresponding to -* column q: -* -* sum a[i,q] pi[i] + lambda[q] = c[q] (6) -* i -* -* in the transformed problem becomes the following: -* -* sum (-a[i,q]) pi[i] + lambda[s] = -c[q]. (7) -* i -* -* Therefore: -* -* lambda[q] = - lambda[s], (8) -* -* where lambda[q] is multiplier for column q, lambda[s] is multiplier -* for column s. -* -* RECOVERING BASIC SOLUTION -* -* With respect to (8) status of column q in solution to the original -* problem is determined by status of column s in solution to the -* transformed problem as follows: -* -* +-----------------------+--------------------+ -* | Status of column s | Status of column q | -* | (transformed problem) | (original problem) | -* +-----------------------+--------------------+ -* | GLP_BS | GLP_BS | -* | GLP_NL | GLP_NU | -* | GLP_NU | GLP_NL | -* +-----------------------+--------------------+ -* -* Value of column q is computed with formula (2). -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* Value of column q is computed with formula (2). -* -* RECOVERING MIP SOLUTION -* -* Value of column q is computed with formula (2). */ - -static int rcv_ubnd_col(NPP *npp, void *info); - -void npp_ubnd_col(NPP *npp, NPPCOL *q) -{ /* process column with upper bound */ - struct bnd_col *info; - NPPROW *i; - NPPAIJ *aij; - /* the column must have upper bound */ - xassert(q->ub != +DBL_MAX); - xassert(q->lb < q->ub); - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_ubnd_col, sizeof(struct bnd_col)); - info->q = q->j; - info->bnd = q->ub; - /* substitute x[q] into objective row */ - npp->c0 += q->coef * q->ub; - q->coef = -q->coef; - /* substitute x[q] into constraint rows */ - for (aij = q->ptr; aij != NULL; aij = aij->c_next) - { i = aij->row; - if (i->lb == i->ub) - i->ub = (i->lb -= aij->val * q->ub); - else - { if (i->lb != -DBL_MAX) - i->lb -= aij->val * q->ub; - if (i->ub != +DBL_MAX) - i->ub -= aij->val * q->ub; - } - aij->val = -aij->val; - } - /* column x[q] becomes column s */ - if (q->lb != -DBL_MAX) - q->ub -= q->lb; - else - q->ub = +DBL_MAX; - q->lb = 0.0; - return; -} - -static int rcv_ubnd_col(NPP *npp, void *_info) -{ /* recover column with upper bound */ - struct bnd_col *info = _info; - if (npp->sol == GLP_BS) - { if (npp->c_stat[info->q] == GLP_BS) - npp->c_stat[info->q] = GLP_BS; - else if (npp->c_stat[info->q] == GLP_NL) - npp->c_stat[info->q] = GLP_NU; - else if (npp->c_stat[info->q] == GLP_NU) - npp->c_stat[info->q] = GLP_NL; - else - { npp_error(); - return 1; - } - } - /* compute value of x[q] with formula (2) */ - npp->c_value[info->q] = info->bnd - npp->c_value[info->q]; - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_dbnd_col - process non-negative column with upper bound -* -* SYNOPSIS -* -* #include "glpnpp.h" -* void npp_dbnd_col(NPP *npp, NPPCOL *q); -* -* DESCRIPTION -* -* The routine npp_dbnd_col processes column q, which is non-negative -* and has upper bound: -* -* 0 <= x[q] <= u[q], (1) -* -* where u[q] > 0. -* -* PROBLEM TRANSFORMATION -* -* Upper bound of column q can be replaced by the following equality -* constraint: -* -* x[q] + s = u[q], (2) -* -* where s >= 0 is a non-negative complement variable. -* -* Since in the primal system along with new row (2) there appears a -* new column s having the only non-zero coefficient in this row, in -* the dual system there appears a new row: -* -* (+1)pi + lambda[s] = 0, (3) -* -* where (+1) is coefficient at column s in row (2), pi is multiplier -* for row (2), lambda[s] is multiplier for column s, 0 is coefficient -* at column s in the objective row. -* -* RECOVERING BASIC SOLUTION -* -* Status of column q in solution to the original problem is determined -* by its status and status of column s in solution to the transformed -* problem as follows: -* -* +-----------------------------------+------------------+ -* | Transformed problem | Original problem | -* +-----------------+-----------------+------------------+ -* | Status of col q | Status of col s | Status of col q | -* +-----------------+-----------------+------------------+ -* | GLP_BS | GLP_BS | GLP_BS | -* | GLP_BS | GLP_NL | GLP_NU | -* | GLP_NL | GLP_BS | GLP_NL | -* | GLP_NL | GLP_NL | GLP_NL (*) | -* +-----------------+-----------------+------------------+ -* -* Value of column q in solution to the original problem is the same as -* in solution to the transformed problem. -* -* 1. Formally, in solution to the transformed problem columns q and s -* cannot be non-basic at the same time, since the constraint (2) -* would be violated. However, if u[q] is close to zero, violation -* may be less than a working precision even if both columns q and s -* are non-basic. In this degenerate case row (2) can be only basic, -* i.e. non-active constraint (otherwise corresponding row of the -* basis matrix would be zero). This allows to pivot out auxiliary -* variable and pivot in column s, in which case the row becomes -* active while column s becomes basic. -* -* 2. If column q is integral, column s is also integral. -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* Value of column q in solution to the original problem is the same as -* in solution to the transformed problem. -* -* RECOVERING MIP SOLUTION -* -* Value of column q in solution to the original problem is the same as -* in solution to the transformed problem. */ - -struct dbnd_col -{ /* double-bounded column */ - int q; - /* column reference number for variable x[q] */ - int s; - /* column reference number for complement variable s */ -}; - -static int rcv_dbnd_col(NPP *npp, void *info); - -void npp_dbnd_col(NPP *npp, NPPCOL *q) -{ /* process non-negative column with upper bound */ - struct dbnd_col *info; - NPPROW *p; - NPPCOL *s; - /* the column must be non-negative with upper bound */ - xassert(q->lb == 0.0); - xassert(q->ub > 0.0); - xassert(q->ub != +DBL_MAX); - /* create variable s */ - s = npp_add_col(npp); - s->is_int = q->is_int; - s->lb = 0.0, s->ub = +DBL_MAX; - /* create equality constraint (2) */ - p = npp_add_row(npp); - p->lb = p->ub = q->ub; - npp_add_aij(npp, p, q, +1.0); - npp_add_aij(npp, p, s, +1.0); - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_dbnd_col, sizeof(struct dbnd_col)); - info->q = q->j; - info->s = s->j; - /* remove upper bound of x[q] */ - q->ub = +DBL_MAX; - return; -} - -static int rcv_dbnd_col(NPP *npp, void *_info) -{ /* recover non-negative column with upper bound */ - struct dbnd_col *info = _info; - if (npp->sol == GLP_BS) - { if (npp->c_stat[info->q] == GLP_BS) - { if (npp->c_stat[info->s] == GLP_BS) - npp->c_stat[info->q] = GLP_BS; - else if (npp->c_stat[info->s] == GLP_NL) - npp->c_stat[info->q] = GLP_NU; - else - { npp_error(); - return 1; - } - } - else if (npp->c_stat[info->q] == GLP_NL) - { if (npp->c_stat[info->s] == GLP_BS || - npp->c_stat[info->s] == GLP_NL) - npp->c_stat[info->q] = GLP_NL; - else - { npp_error(); - return 1; - } - } - else - { npp_error(); - return 1; - } - } - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_fixed_col - process fixed column -* -* SYNOPSIS -* -* #include "glpnpp.h" -* void npp_fixed_col(NPP *npp, NPPCOL *q); -* -* DESCRIPTION -* -* The routine npp_fixed_col processes column q, which is fixed: -* -* x[q] = s[q], (1) -* -* where s[q] is a fixed column value. -* -* PROBLEM TRANSFORMATION -* -* The value of a fixed column can be substituted into the objective -* and constraint rows that allows removing the column from the problem. -* -* Substituting x[q] = s[q] into the objective row, we have: -* -* z = sum c[j] x[j] + c0 = -* j -* -* = sum c[j] x[j] + c[q] x[q] + c0 = -* j!=q -* -* = sum c[j] x[j] + c[q] s[q] + c0 = -* j!=q -* -* = sum c[j] x[j] + c~0, -* j!=q -* -* where -* -* c~0 = c0 + c[q] s[q] (2) -* -* is the constant term of the objective in the transformed problem. -* Similarly, substituting x[q] = s[q] into constraint row i, we have: -* -* L[i] <= sum a[i,j] x[j] <= U[i] ==> -* j -* -* L[i] <= sum a[i,j] x[j] + a[i,q] x[q] <= U[i] ==> -* j!=q -* -* L[i] <= sum a[i,j] x[j] + a[i,q] s[q] <= U[i] ==> -* j!=q -* -* L~[i] <= sum a[i,j] x[j] + a[i,q] s <= U~[i], -* j!=q -* -* where -* -* L~[i] = L[i] - a[i,q] s[q], U~[i] = U[i] - a[i,q] s[q] (3) -* -* are lower and upper bounds of row i in the transformed problem, -* resp. -* -* RECOVERING BASIC SOLUTION -* -* Column q is assigned status GLP_NS and its value is assigned s[q]. -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* Value of column q is assigned s[q]. -* -* RECOVERING MIP SOLUTION -* -* Value of column q is assigned s[q]. */ - -struct fixed_col -{ /* fixed column */ - int q; - /* column reference number for variable x[q] */ - double s; - /* value, at which x[q] is fixed */ -}; - -static int rcv_fixed_col(NPP *npp, void *info); - -void npp_fixed_col(NPP *npp, NPPCOL *q) -{ /* process fixed column */ - struct fixed_col *info; - NPPROW *i; - NPPAIJ *aij; - /* the column must be fixed */ - xassert(q->lb == q->ub); - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_fixed_col, sizeof(struct fixed_col)); - info->q = q->j; - info->s = q->lb; - /* substitute x[q] = s[q] into objective row */ - npp->c0 += q->coef * q->lb; - /* substitute x[q] = s[q] into constraint rows */ - for (aij = q->ptr; aij != NULL; aij = aij->c_next) - { i = aij->row; - if (i->lb == i->ub) - i->ub = (i->lb -= aij->val * q->lb); - else - { if (i->lb != -DBL_MAX) - i->lb -= aij->val * q->lb; - if (i->ub != +DBL_MAX) - i->ub -= aij->val * q->lb; - } - } - /* remove the column from the problem */ - npp_del_col(npp, q); - return; -} - -static int rcv_fixed_col(NPP *npp, void *_info) -{ /* recover fixed column */ - struct fixed_col *info = _info; - if (npp->sol == GLP_SOL) - npp->c_stat[info->q] = GLP_NS; - npp->c_value[info->q] = info->s; - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_make_equality - process row with almost identical bounds -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_make_equality(NPP *npp, NPPROW *p); -* -* DESCRIPTION -* -* The routine npp_make_equality processes row p: -* -* L[p] <= sum a[p,j] x[j] <= U[p], (1) -* j -* -* where -oo < L[p] < U[p] < +oo, i.e. which is double-sided inequality -* constraint. -* -* RETURNS -* -* 0 - row bounds have not been changed; -* -* 1 - row has been replaced by equality constraint. -* -* PROBLEM TRANSFORMATION -* -* If bounds of row (1) are very close to each other: -* -* U[p] - L[p] <= eps, (2) -* -* where eps is an absolute tolerance for row value, the row can be -* replaced by the following almost equivalent equiality constraint: -* -* sum a[p,j] x[j] = b, (3) -* j -* -* where b = (L[p] + U[p]) / 2. If the right-hand side in (3) happens -* to be very close to its nearest integer: -* -* |b - floor(b + 0.5)| <= eps, (4) -* -* it is reasonable to use this nearest integer as the right-hand side. -* -* RECOVERING BASIC SOLUTION -* -* Status of row p in solution to the original problem is determined -* by its status and the sign of its multiplier pi[p] in solution to -* the transformed problem as follows: -* -* +-----------------------+---------+--------------------+ -* | Status of row p | Sign of | Status of row p | -* | (transformed problem) | pi[p] | (original problem) | -* +-----------------------+---------+--------------------+ -* | GLP_BS | + / - | GLP_BS | -* | GLP_NS | + | GLP_NL | -* | GLP_NS | - | GLP_NU | -* +-----------------------+---------+--------------------+ -* -* Value of row multiplier pi[p] in solution to the original problem is -* the same as in solution to the transformed problem. -* -* RECOVERING INTERIOR POINT SOLUTION -* -* Value of row multiplier pi[p] in solution to the original problem is -* the same as in solution to the transformed problem. -* -* RECOVERING MIP SOLUTION -* -* None needed. */ - -struct make_equality -{ /* row with almost identical bounds */ - int p; - /* row reference number */ -}; - -static int rcv_make_equality(NPP *npp, void *info); - -int npp_make_equality(NPP *npp, NPPROW *p) -{ /* process row with almost identical bounds */ - struct make_equality *info; - double b, eps, nint; - /* the row must be double-sided inequality */ - xassert(p->lb != -DBL_MAX); - xassert(p->ub != +DBL_MAX); - xassert(p->lb < p->ub); - /* check row bounds */ - eps = 1e-9 + 1e-12 * fabs(p->lb); - if (p->ub - p->lb > eps) return 0; - /* row bounds are very close to each other */ - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_make_equality, sizeof(struct make_equality)); - info->p = p->i; - /* compute right-hand side */ - b = 0.5 * (p->ub + p->lb); - nint = floor(b + 0.5); - if (fabs(b - nint) <= eps) b = nint; - /* replace row p by almost equivalent equality constraint */ - p->lb = p->ub = b; - return 1; -} - -int rcv_make_equality(NPP *npp, void *_info) -{ /* recover row with almost identical bounds */ - struct make_equality *info = _info; - if (npp->sol == GLP_SOL) - { if (npp->r_stat[info->p] == GLP_BS) - npp->r_stat[info->p] = GLP_BS; - else if (npp->r_stat[info->p] == GLP_NS) - { if (npp->r_pi[info->p] >= 0.0) - npp->r_stat[info->p] = GLP_NL; - else - npp->r_stat[info->p] = GLP_NU; - } - else - { npp_error(); - return 1; - } - } - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_make_fixed - process column with almost identical bounds -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_make_fixed(NPP *npp, NPPCOL *q); -* -* DESCRIPTION -* -* The routine npp_make_fixed processes column q: -* -* l[q] <= x[q] <= u[q], (1) -* -* where -oo < l[q] < u[q] < +oo, i.e. which has both lower and upper -* bounds. -* -* RETURNS -* -* 0 - column bounds have not been changed; -* -* 1 - column has been fixed. -* -* PROBLEM TRANSFORMATION -* -* If bounds of column (1) are very close to each other: -* -* u[q] - l[q] <= eps, (2) -* -* where eps is an absolute tolerance for column value, the column can -* be fixed: -* -* x[q] = s[q], (3) -* -* where s[q] = (l[q] + u[q]) / 2. And if the fixed column value s[q] -* happens to be very close to its nearest integer: -* -* |s[q] - floor(s[q] + 0.5)| <= eps, (4) -* -* it is reasonable to use this nearest integer as the fixed value. -* -* RECOVERING BASIC SOLUTION -* -* In the dual system of the original (as well as transformed) problem -* column q corresponds to the following row: -* -* sum a[i,q] pi[i] + lambda[q] = c[q]. (5) -* i -* -* Since multipliers pi[i] are known for all rows from solution to the -* transformed problem, formula (5) allows computing value of multiplier -* (reduced cost) for column q: -* -* lambda[q] = c[q] - sum a[i,q] pi[i]. (6) -* i -* -* Status of column q in solution to the original problem is determined -* by its status and the sign of its multiplier lambda[q] in solution to -* the transformed problem as follows: -* -* +-----------------------+-----------+--------------------+ -* | Status of column q | Sign of | Status of column q | -* | (transformed problem) | lambda[q] | (original problem) | -* +-----------------------+-----------+--------------------+ -* | GLP_BS | + / - | GLP_BS | -* | GLP_NS | + | GLP_NL | -* | GLP_NS | - | GLP_NU | -* +-----------------------+-----------+--------------------+ -* -* Value of column q in solution to the original problem is the same as -* in solution to the transformed problem. -* -* RECOVERING INTERIOR POINT SOLUTION -* -* Value of column q in solution to the original problem is the same as -* in solution to the transformed problem. -* -* RECOVERING MIP SOLUTION -* -* None needed. */ - -struct make_fixed -{ /* column with almost identical bounds */ - int q; - /* column reference number */ - double c; - /* objective coefficient at x[q] */ - NPPLFE *ptr; - /* list of non-zero coefficients a[i,q] */ -}; - -static int rcv_make_fixed(NPP *npp, void *info); - -int npp_make_fixed(NPP *npp, NPPCOL *q) -{ /* process column with almost identical bounds */ - struct make_fixed *info; - NPPAIJ *aij; - NPPLFE *lfe; - double s, eps, nint; - /* the column must be double-bounded */ - xassert(q->lb != -DBL_MAX); - xassert(q->ub != +DBL_MAX); - xassert(q->lb < q->ub); - /* check column bounds */ - eps = 1e-9 + 1e-12 * fabs(q->lb); - if (q->ub - q->lb > eps) return 0; - /* column bounds are very close to each other */ - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_make_fixed, sizeof(struct make_fixed)); - info->q = q->j; - info->c = q->coef; - info->ptr = NULL; - /* save column coefficients a[i,q] (needed for basic solution - only) */ - if (npp->sol == GLP_SOL) - { for (aij = q->ptr; aij != NULL; aij = aij->c_next) - { lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); - lfe->ref = aij->row->i; - lfe->val = aij->val; - lfe->next = info->ptr; - info->ptr = lfe; - } - } - /* compute column fixed value */ - s = 0.5 * (q->ub + q->lb); - nint = floor(s + 0.5); - if (fabs(s - nint) <= eps) s = nint; - /* make column q fixed */ - q->lb = q->ub = s; - return 1; -} - -static int rcv_make_fixed(NPP *npp, void *_info) -{ /* recover column with almost identical bounds */ - struct make_fixed *info = _info; - NPPLFE *lfe; - double lambda; - if (npp->sol == GLP_SOL) - { if (npp->c_stat[info->q] == GLP_BS) - npp->c_stat[info->q] = GLP_BS; - else if (npp->c_stat[info->q] == GLP_NS) - { /* compute multiplier for column q with formula (6) */ - lambda = info->c; - for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) - lambda -= lfe->val * npp->r_pi[lfe->ref]; - /* assign status to non-basic column */ - if (lambda >= 0.0) - npp->c_stat[info->q] = GLP_NL; - else - npp->c_stat[info->q] = GLP_NU; - } - else - { npp_error(); - return 1; - } - } - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpnpp03.c b/resources/3rdparty/glpk-4.53/src/glpnpp03.c deleted file mode 100644 index 0c869ee39..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpnpp03.c +++ /dev/null @@ -1,2862 +0,0 @@ -/* glpnpp03.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpnpp.h" - -/*********************************************************************** -* NAME -* -* npp_empty_row - process empty row -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_empty_row(NPP *npp, NPPROW *p); -* -* DESCRIPTION -* -* The routine npp_empty_row processes row p, which is empty, i.e. -* coefficients at all columns in this row are zero: -* -* L[p] <= sum 0 x[j] <= U[p], (1) -* -* where L[p] <= U[p]. -* -* RETURNS -* -* 0 - success; -* -* 1 - problem has no primal feasible solution. -* -* PROBLEM TRANSFORMATION -* -* If the following conditions hold: -* -* L[p] <= +eps, U[p] >= -eps, (2) -* -* where eps is an absolute tolerance for row value, the row p is -* redundant. In this case it can be replaced by equivalent redundant -* row, which is free (unbounded), and then removed from the problem. -* Otherwise, the row p is infeasible and, thus, the problem has no -* primal feasible solution. -* -* RECOVERING BASIC SOLUTION -* -* See the routine npp_free_row. -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* See the routine npp_free_row. -* -* RECOVERING MIP SOLUTION -* -* None needed. */ - -int npp_empty_row(NPP *npp, NPPROW *p) -{ /* process empty row */ - double eps = 1e-3; - /* the row must be empty */ - xassert(p->ptr == NULL); - /* check primal feasibility */ - if (p->lb > +eps || p->ub < -eps) - return 1; - /* replace the row by equivalent free (unbounded) row */ - p->lb = -DBL_MAX, p->ub = +DBL_MAX; - /* and process it */ - npp_free_row(npp, p); - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_empty_col - process empty column -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_empty_col(NPP *npp, NPPCOL *q); -* -* DESCRIPTION -* -* The routine npp_empty_col processes column q: -* -* l[q] <= x[q] <= u[q], (1) -* -* where l[q] <= u[q], which is empty, i.e. has zero coefficients in -* all constraint rows. -* -* RETURNS -* -* 0 - success; -* -* 1 - problem has no dual feasible solution. -* -* PROBLEM TRANSFORMATION -* -* The row of the dual system corresponding to the empty column is the -* following: -* -* sum 0 pi[i] + lambda[q] = c[q], (2) -* i -* -* from which it follows that: -* -* lambda[q] = c[q]. (3) -* -* If the following condition holds: -* -* c[q] < - eps, (4) -* -* where eps is an absolute tolerance for column multiplier, the lower -* column bound l[q] must be active to provide dual feasibility (note -* that being preprocessed the problem is always minimization). In this -* case the column can be fixed on its lower bound and removed from the -* problem (if the column is integral, its bounds are also assumed to -* be integral). And if the column has no lower bound (l[q] = -oo), the -* problem has no dual feasible solution. -* -* If the following condition holds: -* -* c[q] > + eps, (5) -* -* the upper column bound u[q] must be active to provide dual -* feasibility. In this case the column can be fixed on its upper bound -* and removed from the problem. And if the column has no upper bound -* (u[q] = +oo), the problem has no dual feasible solution. -* -* Finally, if the following condition holds: -* -* - eps <= c[q] <= +eps, (6) -* -* dual feasibility does not depend on a particular value of column q. -* In this case the column can be fixed either on its lower bound (if -* l[q] > -oo) or on its upper bound (if u[q] < +oo) or at zero (if the -* column is unbounded) and then removed from the problem. -* -* RECOVERING BASIC SOLUTION -* -* See the routine npp_fixed_col. Having been recovered the column -* is assigned status GLP_NS. However, if actually it is not fixed -* (l[q] < u[q]), its status should be changed to GLP_NL, GLP_NU, or -* GLP_NF depending on which bound it was fixed on transformation stage. -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* See the routine npp_fixed_col. -* -* RECOVERING MIP SOLUTION -* -* See the routine npp_fixed_col. */ - -struct empty_col -{ /* empty column */ - int q; - /* column reference number */ - char stat; - /* status in basic solution */ -}; - -static int rcv_empty_col(NPP *npp, void *info); - -int npp_empty_col(NPP *npp, NPPCOL *q) -{ /* process empty column */ - struct empty_col *info; - double eps = 1e-3; - /* the column must be empty */ - xassert(q->ptr == NULL); - /* check dual feasibility */ - if (q->coef > +eps && q->lb == -DBL_MAX) - return 1; - if (q->coef < -eps && q->ub == +DBL_MAX) - return 1; - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_empty_col, sizeof(struct empty_col)); - info->q = q->j; - /* fix the column */ - if (q->lb == -DBL_MAX && q->ub == +DBL_MAX) - { /* free column */ - info->stat = GLP_NF; - q->lb = q->ub = 0.0; - } - else if (q->ub == +DBL_MAX) -lo: { /* column with lower bound */ - info->stat = GLP_NL; - q->ub = q->lb; - } - else if (q->lb == -DBL_MAX) -up: { /* column with upper bound */ - info->stat = GLP_NU; - q->lb = q->ub; - } - else if (q->lb != q->ub) - { /* double-bounded column */ - if (q->coef >= +DBL_EPSILON) goto lo; - if (q->coef <= -DBL_EPSILON) goto up; - if (fabs(q->lb) <= fabs(q->ub)) goto lo; else goto up; - } - else - { /* fixed column */ - info->stat = GLP_NS; - } - /* process fixed column */ - npp_fixed_col(npp, q); - return 0; -} - -static int rcv_empty_col(NPP *npp, void *_info) -{ /* recover empty column */ - struct empty_col *info = _info; - if (npp->sol == GLP_SOL) - npp->c_stat[info->q] = info->stat; - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_implied_value - process implied column value -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_implied_value(NPP *npp, NPPCOL *q, double s); -* -* DESCRIPTION -* -* For column q: -* -* l[q] <= x[q] <= u[q], (1) -* -* where l[q] < u[q], the routine npp_implied_value processes its -* implied value s[q]. If this implied value satisfies to the current -* column bounds and integrality condition, the routine fixes column q -* at the given point. Note that the column is kept in the problem in -* any case. -* -* RETURNS -* -* 0 - column has been fixed; -* -* 1 - implied value violates to current column bounds; -* -* 2 - implied value violates integrality condition. -* -* ALGORITHM -* -* Implied column value s[q] satisfies to the current column bounds if -* the following condition holds: -* -* l[q] - eps <= s[q] <= u[q] + eps, (2) -* -* where eps is an absolute tolerance for column value. If the column -* is integral, the following condition also must hold: -* -* |s[q] - floor(s[q]+0.5)| <= eps, (3) -* -* where floor(s[q]+0.5) is the nearest integer to s[q]. -* -* If both condition (2) and (3) are satisfied, the column can be fixed -* at the value s[q], or, if it is integral, at floor(s[q]+0.5). -* Otherwise, if s[q] violates (2) or (3), the problem has no feasible -* solution. -* -* Note: If s[q] is close to l[q] or u[q], it seems to be reasonable to -* fix the column at its lower or upper bound, resp. rather than at the -* implied value. */ - -int npp_implied_value(NPP *npp, NPPCOL *q, double s) -{ /* process implied column value */ - double eps, nint; - xassert(npp == npp); - /* column must not be fixed */ - xassert(q->lb < q->ub); - /* check integrality */ - if (q->is_int) - { nint = floor(s + 0.5); - if (fabs(s - nint) <= 1e-5) - s = nint; - else - return 2; - } - /* check current column lower bound */ - if (q->lb != -DBL_MAX) - { eps = (q->is_int ? 1e-5 : 1e-5 + 1e-8 * fabs(q->lb)); - if (s < q->lb - eps) return 1; - /* if s[q] is close to l[q], fix column at its lower bound - rather than at the implied value */ - if (s < q->lb + 1e-3 * eps) - { q->ub = q->lb; - return 0; - } - } - /* check current column upper bound */ - if (q->ub != +DBL_MAX) - { eps = (q->is_int ? 1e-5 : 1e-5 + 1e-8 * fabs(q->ub)); - if (s > q->ub + eps) return 1; - /* if s[q] is close to u[q], fix column at its upper bound - rather than at the implied value */ - if (s > q->ub - 1e-3 * eps) - { q->lb = q->ub; - return 0; - } - } - /* fix column at the implied value */ - q->lb = q->ub = s; - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_eq_singlet - process row singleton (equality constraint) -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_eq_singlet(NPP *npp, NPPROW *p); -* -* DESCRIPTION -* -* The routine npp_eq_singlet processes row p, which is equiality -* constraint having the only non-zero coefficient: -* -* a[p,q] x[q] = b. (1) -* -* RETURNS -* -* 0 - success; -* -* 1 - problem has no primal feasible solution; -* -* 2 - problem has no integer feasible solution. -* -* PROBLEM TRANSFORMATION -* -* The equality constraint defines implied value of column q: -* -* x[q] = s[q] = b / a[p,q]. (2) -* -* If the implied value s[q] satisfies to the column bounds (see the -* routine npp_implied_value), the column can be fixed at s[q] and -* removed from the problem. In this case row p becomes redundant, so -* it can be replaced by equivalent free row and also removed from the -* problem. -* -* Note that the routine removes from the problem only row p. Column q -* becomes fixed, however, it is kept in the problem. -* -* RECOVERING BASIC SOLUTION -* -* In solution to the original problem row p is assigned status GLP_NS -* (active equality constraint), and column q is assigned status GLP_BS -* (basic column). -* -* Multiplier for row p can be computed as follows. In the dual system -* of the original problem column q corresponds to the following row: -* -* sum a[i,q] pi[i] + lambda[q] = c[q] ==> -* i -* -* sum a[i,q] pi[i] + a[p,q] pi[p] + lambda[q] = c[q]. -* i!=p -* -* Therefore: -* -* 1 -* pi[p] = ------ (c[q] - lambda[q] - sum a[i,q] pi[i]), (3) -* a[p,q] i!=q -* -* where lambda[q] = 0 (since column[q] is basic), and pi[i] for all -* i != p are known in solution to the transformed problem. -* -* Value of column q in solution to the original problem is assigned -* its implied value s[q]. -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* Multiplier for row p is computed with formula (3). Value of column -* q is assigned its implied value s[q]. -* -* RECOVERING MIP SOLUTION -* -* Value of column q is assigned its implied value s[q]. */ - -struct eq_singlet -{ /* row singleton (equality constraint) */ - int p; - /* row reference number */ - int q; - /* column reference number */ - double apq; - /* constraint coefficient a[p,q] */ - double c; - /* objective coefficient at x[q] */ - NPPLFE *ptr; - /* list of non-zero coefficients a[i,q], i != p */ -}; - -static int rcv_eq_singlet(NPP *npp, void *info); - -int npp_eq_singlet(NPP *npp, NPPROW *p) -{ /* process row singleton (equality constraint) */ - struct eq_singlet *info; - NPPCOL *q; - NPPAIJ *aij; - NPPLFE *lfe; - int ret; - double s; - /* the row must be singleton equality constraint */ - xassert(p->lb == p->ub); - xassert(p->ptr != NULL && p->ptr->r_next == NULL); - /* compute and process implied column value */ - aij = p->ptr; - q = aij->col; - s = p->lb / aij->val; - ret = npp_implied_value(npp, q, s); - xassert(0 <= ret && ret <= 2); - if (ret != 0) return ret; - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_eq_singlet, sizeof(struct eq_singlet)); - info->p = p->i; - info->q = q->j; - info->apq = aij->val; - info->c = q->coef; - info->ptr = NULL; - /* save column coefficients a[i,q], i != p (not needed for MIP - solution) */ - if (npp->sol != GLP_MIP) - { for (aij = q->ptr; aij != NULL; aij = aij->c_next) - { if (aij->row == p) continue; /* skip a[p,q] */ - lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); - lfe->ref = aij->row->i; - lfe->val = aij->val; - lfe->next = info->ptr; - info->ptr = lfe; - } - } - /* remove the row from the problem */ - npp_del_row(npp, p); - return 0; -} - -static int rcv_eq_singlet(NPP *npp, void *_info) -{ /* recover row singleton (equality constraint) */ - struct eq_singlet *info = _info; - NPPLFE *lfe; - double temp; - if (npp->sol == GLP_SOL) - { /* column q must be already recovered as GLP_NS */ - if (npp->c_stat[info->q] != GLP_NS) - { npp_error(); - return 1; - } - npp->r_stat[info->p] = GLP_NS; - npp->c_stat[info->q] = GLP_BS; - } - if (npp->sol != GLP_MIP) - { /* compute multiplier for row p with formula (3) */ - temp = info->c; - for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) - temp -= lfe->val * npp->r_pi[lfe->ref]; - npp->r_pi[info->p] = temp / info->apq; - } - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_implied_lower - process implied column lower bound -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_implied_lower(NPP *npp, NPPCOL *q, double l); -* -* DESCRIPTION -* -* For column q: -* -* l[q] <= x[q] <= u[q], (1) -* -* where l[q] < u[q], the routine npp_implied_lower processes its -* implied lower bound l'[q]. As the result the current column lower -* bound may increase. Note that the column is kept in the problem in -* any case. -* -* RETURNS -* -* 0 - current column lower bound has not changed; -* -* 1 - current column lower bound has changed, but not significantly; -* -* 2 - current column lower bound has significantly changed; -* -* 3 - column has been fixed on its upper bound; -* -* 4 - implied lower bound violates current column upper bound. -* -* ALGORITHM -* -* If column q is integral, before processing its implied lower bound -* should be rounded up: -* -* ( floor(l'[q]+0.5), if |l'[q] - floor(l'[q]+0.5)| <= eps -* l'[q] := < (2) -* ( ceil(l'[q]), otherwise -* -* where floor(l'[q]+0.5) is the nearest integer to l'[q], ceil(l'[q]) -* is smallest integer not less than l'[q], and eps is an absolute -* tolerance for column value. -* -* Processing implied column lower bound l'[q] includes the following -* cases: -* -* 1) if l'[q] < l[q] + eps, implied lower bound is redundant; -* -* 2) if l[q] + eps <= l[q] <= u[q] + eps, current column lower bound -* l[q] can be strengthened by replacing it with l'[q]. If in this -* case new column lower bound becomes close to current column upper -* bound u[q], the column can be fixed on its upper bound; -* -* 3) if l'[q] > u[q] + eps, implied lower bound violates current -* column upper bound u[q], in which case the problem has no primal -* feasible solution. */ - -int npp_implied_lower(NPP *npp, NPPCOL *q, double l) -{ /* process implied column lower bound */ - int ret; - double eps, nint; - xassert(npp == npp); - /* column must not be fixed */ - xassert(q->lb < q->ub); - /* implied lower bound must be finite */ - xassert(l != -DBL_MAX); - /* if column is integral, round up l'[q] */ - if (q->is_int) - { nint = floor(l + 0.5); - if (fabs(l - nint) <= 1e-5) - l = nint; - else - l = ceil(l); - } - /* check current column lower bound */ - if (q->lb != -DBL_MAX) - { eps = (q->is_int ? 1e-3 : 1e-3 + 1e-6 * fabs(q->lb)); - if (l < q->lb + eps) - { ret = 0; /* redundant */ - goto done; - } - } - /* check current column upper bound */ - if (q->ub != +DBL_MAX) - { eps = (q->is_int ? 1e-5 : 1e-5 + 1e-8 * fabs(q->ub)); - if (l > q->ub + eps) - { ret = 4; /* infeasible */ - goto done; - } - /* if l'[q] is close to u[q], fix column at its upper bound */ - if (l > q->ub - 1e-3 * eps) - { q->lb = q->ub; - ret = 3; /* fixed */ - goto done; - } - } - /* check if column lower bound changes significantly */ - if (q->lb == -DBL_MAX) - ret = 2; /* significantly */ - else if (q->is_int && l > q->lb + 0.5) - ret = 2; /* significantly */ - else if (l > q->lb + 0.30 * (1.0 + fabs(q->lb))) - ret = 2; /* significantly */ - else - ret = 1; /* not significantly */ - /* set new column lower bound */ - q->lb = l; -done: return ret; -} - -/*********************************************************************** -* NAME -* -* npp_implied_upper - process implied column upper bound -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_implied_upper(NPP *npp, NPPCOL *q, double u); -* -* DESCRIPTION -* -* For column q: -* -* l[q] <= x[q] <= u[q], (1) -* -* where l[q] < u[q], the routine npp_implied_upper processes its -* implied upper bound u'[q]. As the result the current column upper -* bound may decrease. Note that the column is kept in the problem in -* any case. -* -* RETURNS -* -* 0 - current column upper bound has not changed; -* -* 1 - current column upper bound has changed, but not significantly; -* -* 2 - current column upper bound has significantly changed; -* -* 3 - column has been fixed on its lower bound; -* -* 4 - implied upper bound violates current column lower bound. -* -* ALGORITHM -* -* If column q is integral, before processing its implied upper bound -* should be rounded down: -* -* ( floor(u'[q]+0.5), if |u'[q] - floor(l'[q]+0.5)| <= eps -* u'[q] := < (2) -* ( floor(l'[q]), otherwise -* -* where floor(u'[q]+0.5) is the nearest integer to u'[q], -* floor(u'[q]) is largest integer not greater than u'[q], and eps is -* an absolute tolerance for column value. -* -* Processing implied column upper bound u'[q] includes the following -* cases: -* -* 1) if u'[q] > u[q] - eps, implied upper bound is redundant; -* -* 2) if l[q] - eps <= u[q] <= u[q] - eps, current column upper bound -* u[q] can be strengthened by replacing it with u'[q]. If in this -* case new column upper bound becomes close to current column lower -* bound, the column can be fixed on its lower bound; -* -* 3) if u'[q] < l[q] - eps, implied upper bound violates current -* column lower bound l[q], in which case the problem has no primal -* feasible solution. */ - -int npp_implied_upper(NPP *npp, NPPCOL *q, double u) -{ int ret; - double eps, nint; - xassert(npp == npp); - /* column must not be fixed */ - xassert(q->lb < q->ub); - /* implied upper bound must be finite */ - xassert(u != +DBL_MAX); - /* if column is integral, round down u'[q] */ - if (q->is_int) - { nint = floor(u + 0.5); - if (fabs(u - nint) <= 1e-5) - u = nint; - else - u = floor(u); - } - /* check current column upper bound */ - if (q->ub != +DBL_MAX) - { eps = (q->is_int ? 1e-3 : 1e-3 + 1e-6 * fabs(q->ub)); - if (u > q->ub - eps) - { ret = 0; /* redundant */ - goto done; - } - } - /* check current column lower bound */ - if (q->lb != -DBL_MAX) - { eps = (q->is_int ? 1e-5 : 1e-5 + 1e-8 * fabs(q->lb)); - if (u < q->lb - eps) - { ret = 4; /* infeasible */ - goto done; - } - /* if u'[q] is close to l[q], fix column at its lower bound */ - if (u < q->lb + 1e-3 * eps) - { q->ub = q->lb; - ret = 3; /* fixed */ - goto done; - } - } - /* check if column upper bound changes significantly */ - if (q->ub == +DBL_MAX) - ret = 2; /* significantly */ - else if (q->is_int && u < q->ub - 0.5) - ret = 2; /* significantly */ - else if (u < q->ub - 0.30 * (1.0 + fabs(q->ub))) - ret = 2; /* significantly */ - else - ret = 1; /* not significantly */ - /* set new column upper bound */ - q->ub = u; -done: return ret; -} - -/*********************************************************************** -* NAME -* -* npp_ineq_singlet - process row singleton (inequality constraint) -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_ineq_singlet(NPP *npp, NPPROW *p); -* -* DESCRIPTION -* -* The routine npp_ineq_singlet processes row p, which is inequality -* constraint having the only non-zero coefficient: -* -* L[p] <= a[p,q] * x[q] <= U[p], (1) -* -* where L[p] < U[p], L[p] > -oo and/or U[p] < +oo. -* -* RETURNS -* -* 0 - current column bounds have not changed; -* -* 1 - current column bounds have changed, but not significantly; -* -* 2 - current column bounds have significantly changed; -* -* 3 - column has been fixed on its lower or upper bound; -* -* 4 - problem has no primal feasible solution. -* -* PROBLEM TRANSFORMATION -* -* Inequality constraint (1) defines implied bounds of column q: -* -* ( L[p] / a[p,q], if a[p,q] > 0 -* l'[q] = < (2) -* ( U[p] / a[p,q], if a[p,q] < 0 -* -* ( U[p] / a[p,q], if a[p,q] > 0 -* u'[q] = < (3) -* ( L[p] / a[p,q], if a[p,q] < 0 -* -* If these implied bounds do not violate current bounds of column q: -* -* l[q] <= x[q] <= u[q], (4) -* -* they can be used to strengthen the current column bounds: -* -* l[q] := max(l[q], l'[q]), (5) -* -* u[q] := min(u[q], u'[q]). (6) -* -* (See the routines npp_implied_lower and npp_implied_upper.) -* -* Once bounds of row p (1) have been carried over column q, the row -* becomes redundant, so it can be replaced by equivalent free row and -* removed from the problem. -* -* Note that the routine removes from the problem only row p. Column q, -* even it has been fixed, is kept in the problem. -* -* RECOVERING BASIC SOLUTION -* -* Note that the row in the dual system corresponding to column q is -* the following: -* -* sum a[i,q] pi[i] + lambda[q] = c[q] ==> -* i -* (7) -* sum a[i,q] pi[i] + a[p,q] pi[p] + lambda[q] = c[q], -* i!=p -* -* where pi[i] for all i != p are known in solution to the transformed -* problem. Row p does not exist in the transformed problem, so it has -* zero multiplier there. This allows computing multiplier for column q -* in solution to the transformed problem: -* -* lambda~[q] = c[q] - sum a[i,q] pi[i]. (8) -* i!=p -* -* Let in solution to the transformed problem column q be non-basic -* with lower bound active (GLP_NL, lambda~[q] >= 0), and this lower -* bound be implied one l'[q]. From the original problem's standpoint -* this then means that actually the original column lower bound l[q] -* is inactive, and active is that row bound L[p] or U[p] that defines -* the implied bound l'[q] (2). In this case in solution to the -* original problem column q is assigned status GLP_BS while row p is -* assigned status GLP_NL (if a[p,q] > 0) or GLP_NU (if a[p,q] < 0). -* Since now column q is basic, its multiplier lambda[q] is zero. This -* allows using (7) and (8) to find multiplier for row p in solution to -* the original problem: -* -* 1 -* pi[p] = ------ (c[q] - sum a[i,q] pi[i]) = lambda~[q] / a[p,q] (9) -* a[p,q] i!=p -* -* Now let in solution to the transformed problem column q be non-basic -* with upper bound active (GLP_NU, lambda~[q] <= 0), and this upper -* bound be implied one u'[q]. As in the previous case this then means -* that from the original problem's standpoint actually the original -* column upper bound u[q] is inactive, and active is that row bound -* L[p] or U[p] that defines the implied bound u'[q] (3). In this case -* in solution to the original problem column q is assigned status -* GLP_BS, row p is assigned status GLP_NU (if a[p,q] > 0) or GLP_NL -* (if a[p,q] < 0), and its multiplier is computed with formula (9). -* -* Strengthening bounds of column q according to (5) and (6) may make -* it fixed. Thus, if in solution to the transformed problem column q is -* non-basic and fixed (GLP_NS), we can suppose that if lambda~[q] > 0, -* column q has active lower bound (GLP_NL), and if lambda~[q] < 0, -* column q has active upper bound (GLP_NU), reducing this case to two -* previous ones. If, however, lambda~[q] is close to zero or -* corresponding bound of row p does not exist (this may happen if -* lambda~[q] has wrong sign due to round-off errors, in which case it -* is expected to be close to zero, since solution is assumed to be dual -* feasible), column q can be assigned status GLP_BS (basic), and row p -* can be made active on its existing bound. In the latter case row -* multiplier pi[p] computed with formula (9) will be also close to -* zero, and dual feasibility will be kept. -* -* In all other cases, namely, if in solution to the transformed -* problem column q is basic (GLP_BS), or non-basic with original lower -* bound l[q] active (GLP_NL), or non-basic with original upper bound -* u[q] active (GLP_NU), constraint (1) is inactive. So in solution to -* the original problem status of column q remains unchanged, row p is -* assigned status GLP_BS, and its multiplier pi[p] is assigned zero -* value. -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* First, value of multiplier for column q in solution to the original -* problem is computed with formula (8). If lambda~[q] > 0 and column q -* has implied lower bound, or if lambda~[q] < 0 and column q has -* implied upper bound, this means that from the original problem's -* standpoint actually row p has corresponding active bound, in which -* case its multiplier pi[p] is computed with formula (9). In other -* cases, when the sign of lambda~[q] corresponds to original bound of -* column q, or when lambda~[q] =~ 0, value of row multiplier pi[p] is -* assigned zero value. -* -* RECOVERING MIP SOLUTION -* -* None needed. */ - -struct ineq_singlet -{ /* row singleton (inequality constraint) */ - int p; - /* row reference number */ - int q; - /* column reference number */ - double apq; - /* constraint coefficient a[p,q] */ - double c; - /* objective coefficient at x[q] */ - double lb; - /* row lower bound */ - double ub; - /* row upper bound */ - char lb_changed; - /* this flag is set if column lower bound was changed */ - char ub_changed; - /* this flag is set if column upper bound was changed */ - NPPLFE *ptr; - /* list of non-zero coefficients a[i,q], i != p */ -}; - -static int rcv_ineq_singlet(NPP *npp, void *info); - -int npp_ineq_singlet(NPP *npp, NPPROW *p) -{ /* process row singleton (inequality constraint) */ - struct ineq_singlet *info; - NPPCOL *q; - NPPAIJ *apq, *aij; - NPPLFE *lfe; - int lb_changed, ub_changed; - double ll, uu; - /* the row must be singleton inequality constraint */ - xassert(p->lb != -DBL_MAX || p->ub != +DBL_MAX); - xassert(p->lb < p->ub); - xassert(p->ptr != NULL && p->ptr->r_next == NULL); - /* compute implied column bounds */ - apq = p->ptr; - q = apq->col; - xassert(q->lb < q->ub); - if (apq->val > 0.0) - { ll = (p->lb == -DBL_MAX ? -DBL_MAX : p->lb / apq->val); - uu = (p->ub == +DBL_MAX ? +DBL_MAX : p->ub / apq->val); - } - else - { ll = (p->ub == +DBL_MAX ? -DBL_MAX : p->ub / apq->val); - uu = (p->lb == -DBL_MAX ? +DBL_MAX : p->lb / apq->val); - } - /* process implied column lower bound */ - if (ll == -DBL_MAX) - lb_changed = 0; - else - { lb_changed = npp_implied_lower(npp, q, ll); - xassert(0 <= lb_changed && lb_changed <= 4); - if (lb_changed == 4) return 4; /* infeasible */ - } - /* process implied column upper bound */ - if (uu == +DBL_MAX) - ub_changed = 0; - else if (lb_changed == 3) - { /* column was fixed on its upper bound due to l'[q] = u[q] */ - /* note that L[p] < U[p], so l'[q] = u[q] < u'[q] */ - ub_changed = 0; - } - else - { ub_changed = npp_implied_upper(npp, q, uu); - xassert(0 <= ub_changed && ub_changed <= 4); - if (ub_changed == 4) return 4; /* infeasible */ - } - /* if neither lower nor upper column bound was changed, the row - is originally redundant and can be replaced by free row */ - if (!lb_changed && !ub_changed) - { p->lb = -DBL_MAX, p->ub = +DBL_MAX; - npp_free_row(npp, p); - return 0; - } - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_ineq_singlet, sizeof(struct ineq_singlet)); - info->p = p->i; - info->q = q->j; - info->apq = apq->val; - info->c = q->coef; - info->lb = p->lb; - info->ub = p->ub; - info->lb_changed = (char)lb_changed; - info->ub_changed = (char)ub_changed; - info->ptr = NULL; - /* save column coefficients a[i,q], i != p (not needed for MIP - solution) */ - if (npp->sol != GLP_MIP) - { for (aij = q->ptr; aij != NULL; aij = aij->c_next) - { if (aij == apq) continue; /* skip a[p,q] */ - lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); - lfe->ref = aij->row->i; - lfe->val = aij->val; - lfe->next = info->ptr; - info->ptr = lfe; - } - } - /* remove the row from the problem */ - npp_del_row(npp, p); - return lb_changed >= ub_changed ? lb_changed : ub_changed; -} - -static int rcv_ineq_singlet(NPP *npp, void *_info) -{ /* recover row singleton (inequality constraint) */ - struct ineq_singlet *info = _info; - NPPLFE *lfe; - double lambda; - if (npp->sol == GLP_MIP) goto done; - /* compute lambda~[q] in solution to the transformed problem - with formula (8) */ - lambda = info->c; - for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) - lambda -= lfe->val * npp->r_pi[lfe->ref]; - if (npp->sol == GLP_SOL) - { /* recover basic solution */ - if (npp->c_stat[info->q] == GLP_BS) - { /* column q is basic, so row p is inactive */ - npp->r_stat[info->p] = GLP_BS; - npp->r_pi[info->p] = 0.0; - } - else if (npp->c_stat[info->q] == GLP_NL) -nl: { /* column q is non-basic with lower bound active */ - if (info->lb_changed) - { /* it is implied bound, so actually row p is active - while column q is basic */ - npp->r_stat[info->p] = - (char)(info->apq > 0.0 ? GLP_NL : GLP_NU); - npp->c_stat[info->q] = GLP_BS; - npp->r_pi[info->p] = lambda / info->apq; - } - else - { /* it is original bound, so row p is inactive */ - npp->r_stat[info->p] = GLP_BS; - npp->r_pi[info->p] = 0.0; - } - } - else if (npp->c_stat[info->q] == GLP_NU) -nu: { /* column q is non-basic with upper bound active */ - if (info->ub_changed) - { /* it is implied bound, so actually row p is active - while column q is basic */ - npp->r_stat[info->p] = - (char)(info->apq > 0.0 ? GLP_NU : GLP_NL); - npp->c_stat[info->q] = GLP_BS; - npp->r_pi[info->p] = lambda / info->apq; - } - else - { /* it is original bound, so row p is inactive */ - npp->r_stat[info->p] = GLP_BS; - npp->r_pi[info->p] = 0.0; - } - } - else if (npp->c_stat[info->q] == GLP_NS) - { /* column q is non-basic and fixed; note, however, that in - in the original problem it is non-fixed */ - if (lambda > +1e-7) - { if (info->apq > 0.0 && info->lb != -DBL_MAX || - info->apq < 0.0 && info->ub != +DBL_MAX || - !info->lb_changed) - { /* either corresponding bound of row p exists or - column q remains non-basic with its original lower - bound active */ - npp->c_stat[info->q] = GLP_NL; - goto nl; - } - } - if (lambda < -1e-7) - { if (info->apq > 0.0 && info->ub != +DBL_MAX || - info->apq < 0.0 && info->lb != -DBL_MAX || - !info->ub_changed) - { /* either corresponding bound of row p exists or - column q remains non-basic with its original upper - bound active */ - npp->c_stat[info->q] = GLP_NU; - goto nu; - } - } - /* either lambda~[q] is close to zero, or corresponding - bound of row p does not exist, because lambda~[q] has - wrong sign due to round-off errors; in the latter case - lambda~[q] is also assumed to be close to zero; so, we - can make row p active on its existing bound and column q - basic; pi[p] will have wrong sign, but it also will be - close to zero (rarus casus of dual degeneracy) */ - if (info->lb != -DBL_MAX && info->ub == +DBL_MAX) - { /* row lower bound exists, but upper bound doesn't */ - npp->r_stat[info->p] = GLP_NL; - } - else if (info->lb == -DBL_MAX && info->ub != +DBL_MAX) - { /* row upper bound exists, but lower bound doesn't */ - npp->r_stat[info->p] = GLP_NU; - } - else if (info->lb != -DBL_MAX && info->ub != +DBL_MAX) - { /* both row lower and upper bounds exist */ - /* to choose proper active row bound we should not use - lambda~[q], because its value being close to zero is - unreliable; so we choose that bound which provides - primal feasibility for original constraint (1) */ - if (info->apq * npp->c_value[info->q] <= - 0.5 * (info->lb + info->ub)) - npp->r_stat[info->p] = GLP_NL; - else - npp->r_stat[info->p] = GLP_NU; - } - else - { npp_error(); - return 1; - } - npp->c_stat[info->q] = GLP_BS; - npp->r_pi[info->p] = lambda / info->apq; - } - else - { npp_error(); - return 1; - } - } - if (npp->sol == GLP_IPT) - { /* recover interior-point solution */ - if (lambda > +DBL_EPSILON && info->lb_changed || - lambda < -DBL_EPSILON && info->ub_changed) - { /* actually row p has corresponding active bound */ - npp->r_pi[info->p] = lambda / info->apq; - } - else - { /* either bounds of column q are both inactive or its - original bound is active */ - npp->r_pi[info->p] = 0.0; - } - } -done: return 0; -} - -/*********************************************************************** -* NAME -* -* npp_implied_slack - process column singleton (implied slack variable) -* -* SYNOPSIS -* -* #include "glpnpp.h" -* void npp_implied_slack(NPP *npp, NPPCOL *q); -* -* DESCRIPTION -* -* The routine npp_implied_slack processes column q: -* -* l[q] <= x[q] <= u[q], (1) -* -* where l[q] < u[q], having the only non-zero coefficient in row p, -* which is equality constraint: -* -* sum a[p,j] x[j] + a[p,q] x[q] = b. (2) -* j!=q -* -* PROBLEM TRANSFORMATION -* -* (If x[q] is integral, this transformation must not be used.) -* -* The term a[p,q] x[q] in constraint (2) can be considered as a slack -* variable that allows to carry bounds of column q over row p and then -* remove column q from the problem. -* -* Constraint (2) can be written as follows: -* -* sum a[p,j] x[j] = b - a[p,q] x[q]. (3) -* j!=q -* -* According to (1) constraint (3) is equivalent to the following -* inequality constraint: -* -* L[p] <= sum a[p,j] x[j] <= U[p], (4) -* j!=q -* -* where -* -* ( b - a[p,q] u[q], if a[p,q] > 0 -* L[p] = < (5) -* ( b - a[p,q] l[q], if a[p,q] < 0 -* -* ( b - a[p,q] l[q], if a[p,q] > 0 -* U[p] = < (6) -* ( b - a[p,q] u[q], if a[p,q] < 0 -* -* From (2) it follows that: -* -* 1 -* x[q] = ------ (b - sum a[p,j] x[j]). (7) -* a[p,q] j!=q -* -* In order to eliminate x[q] from the objective row we substitute it -* from (6) to that row: -* -* z = sum c[j] x[j] + c[q] x[q] + c[0] = -* j!=q -* 1 -* = sum c[j] x[j] + c[q] [------ (b - sum a[p,j] x[j])] + c0 = -* j!=q a[p,q] j!=q -* -* = sum c~[j] x[j] + c~[0], -* j!=q -* a[p,j] b -* c~[j] = c[j] - c[q] ------, c~0 = c0 - c[q] ------ (8) -* a[p,q] a[p,q] -* -* are values of objective coefficients and constant term, resp., in -* the transformed problem. -* -* Note that column q is column singleton, so in the dual system of the -* original problem it corresponds to the following row singleton: -* -* a[p,q] pi[p] + lambda[q] = c[q]. (9) -* -* In the transformed problem row (9) would be the following: -* -* a[p,q] pi~[p] + lambda[q] = c~[q] = 0. (10) -* -* Subtracting (10) from (9) we have: -* -* a[p,q] (pi[p] - pi~[p]) = c[q] -* -* that gives the following formula to compute multiplier for row p in -* solution to the original problem using its value in solution to the -* transformed problem: -* -* pi[p] = pi~[p] + c[q] / a[p,q]. (11) -* -* RECOVERING BASIC SOLUTION -* -* Status of column q in solution to the original problem is defined -* by status of row p in solution to the transformed problem and the -* sign of coefficient a[p,q] in the original inequality constraint (2) -* as follows: -* -* +-----------------------+---------+--------------------+ -* | Status of row p | Sign of | Status of column q | -* | (transformed problem) | a[p,q] | (original problem) | -* +-----------------------+---------+--------------------+ -* | GLP_BS | + / - | GLP_BS | -* | GLP_NL | + | GLP_NU | -* | GLP_NL | - | GLP_NL | -* | GLP_NU | + | GLP_NL | -* | GLP_NU | - | GLP_NU | -* | GLP_NF | + / - | GLP_NF | -* +-----------------------+---------+--------------------+ -* -* Value of column q is computed with formula (7). Since originally row -* p is equality constraint, its status is assigned GLP_NS, and value of -* its multiplier pi[p] is computed with formula (11). -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* Value of column q is computed with formula (7). Row multiplier value -* pi[p] is computed with formula (11). -* -* RECOVERING MIP SOLUTION -* -* Value of column q is computed with formula (7). */ - -struct implied_slack -{ /* column singleton (implied slack variable) */ - int p; - /* row reference number */ - int q; - /* column reference number */ - double apq; - /* constraint coefficient a[p,q] */ - double b; - /* right-hand side of original equality constraint */ - double c; - /* original objective coefficient at x[q] */ - NPPLFE *ptr; - /* list of non-zero coefficients a[p,j], j != q */ -}; - -static int rcv_implied_slack(NPP *npp, void *info); - -void npp_implied_slack(NPP *npp, NPPCOL *q) -{ /* process column singleton (implied slack variable) */ - struct implied_slack *info; - NPPROW *p; - NPPAIJ *aij; - NPPLFE *lfe; - /* the column must be non-integral non-fixed singleton */ - xassert(!q->is_int); - xassert(q->lb < q->ub); - xassert(q->ptr != NULL && q->ptr->c_next == NULL); - /* corresponding row must be equality constraint */ - aij = q->ptr; - p = aij->row; - xassert(p->lb == p->ub); - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_implied_slack, sizeof(struct implied_slack)); - info->p = p->i; - info->q = q->j; - info->apq = aij->val; - info->b = p->lb; - info->c = q->coef; - info->ptr = NULL; - /* save row coefficients a[p,j], j != q, and substitute x[q] - into the objective row */ - for (aij = p->ptr; aij != NULL; aij = aij->r_next) - { if (aij->col == q) continue; /* skip a[p,q] */ - lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); - lfe->ref = aij->col->j; - lfe->val = aij->val; - lfe->next = info->ptr; - info->ptr = lfe; - aij->col->coef -= info->c * (aij->val / info->apq); - } - npp->c0 += info->c * (info->b / info->apq); - /* compute new row bounds */ - if (info->apq > 0.0) - { p->lb = (q->ub == +DBL_MAX ? - -DBL_MAX : info->b - info->apq * q->ub); - p->ub = (q->lb == -DBL_MAX ? - +DBL_MAX : info->b - info->apq * q->lb); - } - else - { p->lb = (q->lb == -DBL_MAX ? - -DBL_MAX : info->b - info->apq * q->lb); - p->ub = (q->ub == +DBL_MAX ? - +DBL_MAX : info->b - info->apq * q->ub); - } - /* remove the column from the problem */ - npp_del_col(npp, q); - return; -} - -static int rcv_implied_slack(NPP *npp, void *_info) -{ /* recover column singleton (implied slack variable) */ - struct implied_slack *info = _info; - NPPLFE *lfe; - double temp; - if (npp->sol == GLP_SOL) - { /* assign statuses to row p and column q */ - if (npp->r_stat[info->p] == GLP_BS || - npp->r_stat[info->p] == GLP_NF) - npp->c_stat[info->q] = npp->r_stat[info->p]; - else if (npp->r_stat[info->p] == GLP_NL) - npp->c_stat[info->q] = - (char)(info->apq > 0.0 ? GLP_NU : GLP_NL); - else if (npp->r_stat[info->p] == GLP_NU) - npp->c_stat[info->q] = - (char)(info->apq > 0.0 ? GLP_NL : GLP_NU); - else - { npp_error(); - return 1; - } - npp->r_stat[info->p] = GLP_NS; - } - if (npp->sol != GLP_MIP) - { /* compute multiplier for row p */ - npp->r_pi[info->p] += info->c / info->apq; - } - /* compute value of column q */ - temp = info->b; - for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) - temp -= lfe->val * npp->c_value[lfe->ref]; - npp->c_value[info->q] = temp / info->apq; - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_implied_free - process column singleton (implied free variable) -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_implied_free(NPP *npp, NPPCOL *q); -* -* DESCRIPTION -* -* The routine npp_implied_free processes column q: -* -* l[q] <= x[q] <= u[q], (1) -* -* having non-zero coefficient in the only row p, which is inequality -* constraint: -* -* L[p] <= sum a[p,j] x[j] + a[p,q] x[q] <= U[p], (2) -* j!=q -* -* where l[q] < u[q], L[p] < U[p], L[p] > -oo and/or U[p] < +oo. -* -* RETURNS -* -* 0 - success; -* -* 1 - column lower and/or upper bound(s) can be active; -* -* 2 - problem has no dual feasible solution. -* -* PROBLEM TRANSFORMATION -* -* Constraint (2) can be written as follows: -* -* L[p] - sum a[p,j] x[j] <= a[p,q] x[q] <= U[p] - sum a[p,j] x[j], -* j!=q j!=q -* -* from which it follows that: -* -* alfa <= a[p,q] x[q] <= beta, (3) -* -* where -* -* alfa = inf(L[p] - sum a[p,j] x[j]) = -* j!=q -* -* = L[p] - sup sum a[p,j] x[j] = (4) -* j!=q -* -* = L[p] - sum a[p,j] u[j] - sum a[p,j] l[j], -* j in Jp j in Jn -* -* beta = sup(L[p] - sum a[p,j] x[j]) = -* j!=q -* -* = L[p] - inf sum a[p,j] x[j] = (5) -* j!=q -* -* = L[p] - sum a[p,j] l[j] - sum a[p,j] u[j], -* j in Jp j in Jn -* -* Jp = {j != q: a[p,j] > 0}, Jn = {j != q: a[p,j] < 0}. (6) -* -* Inequality (3) defines implied bounds of variable x[q]: -* -* l'[q] <= x[q] <= u'[q], (7) -* -* where -* -* ( alfa / a[p,q], if a[p,q] > 0 -* l'[q] = < (8a) -* ( beta / a[p,q], if a[p,q] < 0 -* -* ( beta / a[p,q], if a[p,q] > 0 -* u'[q] = < (8b) -* ( alfa / a[p,q], if a[p,q] < 0 -* -* Thus, if l'[q] > l[q] - eps and u'[q] < u[q] + eps, where eps is -* an absolute tolerance for column value, column bounds (1) cannot be -* active, in which case column q can be replaced by equivalent free -* (unbounded) column. -* -* Note that column q is column singleton, so in the dual system of the -* original problem it corresponds to the following row singleton: -* -* a[p,q] pi[p] + lambda[q] = c[q], (9) -* -* from which it follows that: -* -* pi[p] = (c[q] - lambda[q]) / a[p,q]. (10) -* -* Let x[q] be implied free (unbounded) variable. Then column q can be -* only basic, so its multiplier lambda[q] is equal to zero, and from -* (10) we have: -* -* pi[p] = c[q] / a[p,q]. (11) -* -* There are possible three cases: -* -* 1) pi[p] < -eps, where eps is an absolute tolerance for row -* multiplier. In this case, to provide dual feasibility of the -* original problem, row p must be active on its lower bound, and -* if its lower bound does not exist (L[p] = -oo), the problem has -* no dual feasible solution; -* -* 2) pi[p] > +eps. In this case row p must be active on its upper -* bound, and if its upper bound does not exist (U[p] = +oo), the -* problem has no dual feasible solution; -* -* 3) -eps <= pi[p] <= +eps. In this case any (either lower or upper) -* bound of row p can be active, because this does not affect dual -* feasibility. -* -* Thus, in all three cases original inequality constraint (2) can be -* replaced by equality constraint, where the right-hand side is either -* lower or upper bound of row p, and bounds of column q can be removed -* that makes it free (unbounded). (May note that this transformation -* can be followed by transformation "Column singleton (implied slack -* variable)" performed by the routine npp_implied_slack.) -* -* RECOVERING BASIC SOLUTION -* -* Status of row p in solution to the original problem is determined -* by its status in solution to the transformed problem and its bound, -* which was choosen to be active: -* -* +-----------------------+--------+--------------------+ -* | Status of row p | Active | Status of row p | -* | (transformed problem) | bound | (original problem) | -* +-----------------------+--------+--------------------+ -* | GLP_BS | L[p] | GLP_BS | -* | GLP_BS | U[p] | GLP_BS | -* | GLP_NS | L[p] | GLP_NL | -* | GLP_NS | U[p] | GLP_NU | -* +-----------------------+--------+--------------------+ -* -* Value of row multiplier pi[p] (as well as value of column q) in -* solution to the original problem is the same as in solution to the -* transformed problem. -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* Value of row multiplier pi[p] in solution to the original problem is -* the same as in solution to the transformed problem. -* -* RECOVERING MIP SOLUTION -* -* None needed. */ - -struct implied_free -{ /* column singleton (implied free variable) */ - int p; - /* row reference number */ - char stat; - /* row status: - GLP_NL - active constraint on lower bound - GLP_NU - active constraint on upper bound */ -}; - -static int rcv_implied_free(NPP *npp, void *info); - -int npp_implied_free(NPP *npp, NPPCOL *q) -{ /* process column singleton (implied free variable) */ - struct implied_free *info; - NPPROW *p; - NPPAIJ *apq, *aij; - double alfa, beta, l, u, pi, eps; - /* the column must be non-fixed singleton */ - xassert(q->lb < q->ub); - xassert(q->ptr != NULL && q->ptr->c_next == NULL); - /* corresponding row must be inequality constraint */ - apq = q->ptr; - p = apq->row; - xassert(p->lb != -DBL_MAX || p->ub != +DBL_MAX); - xassert(p->lb < p->ub); - /* compute alfa */ - alfa = p->lb; - if (alfa != -DBL_MAX) - { for (aij = p->ptr; aij != NULL; aij = aij->r_next) - { if (aij == apq) continue; /* skip a[p,q] */ - if (aij->val > 0.0) - { if (aij->col->ub == +DBL_MAX) - { alfa = -DBL_MAX; - break; - } - alfa -= aij->val * aij->col->ub; - } - else /* < 0.0 */ - { if (aij->col->lb == -DBL_MAX) - { alfa = -DBL_MAX; - break; - } - alfa -= aij->val * aij->col->lb; - } - } - } - /* compute beta */ - beta = p->ub; - if (beta != +DBL_MAX) - { for (aij = p->ptr; aij != NULL; aij = aij->r_next) - { if (aij == apq) continue; /* skip a[p,q] */ - if (aij->val > 0.0) - { if (aij->col->lb == -DBL_MAX) - { beta = +DBL_MAX; - break; - } - beta -= aij->val * aij->col->lb; - } - else /* < 0.0 */ - { if (aij->col->ub == +DBL_MAX) - { beta = +DBL_MAX; - break; - } - beta -= aij->val * aij->col->ub; - } - } - } - /* compute implied column lower bound l'[q] */ - if (apq->val > 0.0) - l = (alfa == -DBL_MAX ? -DBL_MAX : alfa / apq->val); - else /* < 0.0 */ - l = (beta == +DBL_MAX ? -DBL_MAX : beta / apq->val); - /* compute implied column upper bound u'[q] */ - if (apq->val > 0.0) - u = (beta == +DBL_MAX ? +DBL_MAX : beta / apq->val); - else - u = (alfa == -DBL_MAX ? +DBL_MAX : alfa / apq->val); - /* check if column lower bound l[q] can be active */ - if (q->lb != -DBL_MAX) - { eps = 1e-9 + 1e-12 * fabs(q->lb); - if (l < q->lb - eps) return 1; /* yes, it can */ - } - /* check if column upper bound u[q] can be active */ - if (q->ub != +DBL_MAX) - { eps = 1e-9 + 1e-12 * fabs(q->ub); - if (u > q->ub + eps) return 1; /* yes, it can */ - } - /* okay; make column q free (unbounded) */ - q->lb = -DBL_MAX, q->ub = +DBL_MAX; - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_implied_free, sizeof(struct implied_free)); - info->p = p->i; - info->stat = -1; - /* compute row multiplier pi[p] */ - pi = q->coef / apq->val; - /* check dual feasibility for row p */ - if (pi > +DBL_EPSILON) - { /* lower bound L[p] must be active */ - if (p->lb != -DBL_MAX) -nl: { info->stat = GLP_NL; - p->ub = p->lb; - } - else - { if (pi > +1e-5) return 2; /* dual infeasibility */ - /* take a chance on U[p] */ - xassert(p->ub != +DBL_MAX); - goto nu; - } - } - else if (pi < -DBL_EPSILON) - { /* upper bound U[p] must be active */ - if (p->ub != +DBL_MAX) -nu: { info->stat = GLP_NU; - p->lb = p->ub; - } - else - { if (pi < -1e-5) return 2; /* dual infeasibility */ - /* take a chance on L[p] */ - xassert(p->lb != -DBL_MAX); - goto nl; - } - } - else - { /* any bound (either L[p] or U[p]) can be made active */ - if (p->ub == +DBL_MAX) - { xassert(p->lb != -DBL_MAX); - goto nl; - } - if (p->lb == -DBL_MAX) - { xassert(p->ub != +DBL_MAX); - goto nu; - } - if (fabs(p->lb) <= fabs(p->ub)) goto nl; else goto nu; - } - return 0; -} - -static int rcv_implied_free(NPP *npp, void *_info) -{ /* recover column singleton (implied free variable) */ - struct implied_free *info = _info; - if (npp->sol == GLP_SOL) - { if (npp->r_stat[info->p] == GLP_BS) - npp->r_stat[info->p] = GLP_BS; - else if (npp->r_stat[info->p] == GLP_NS) - { xassert(info->stat == GLP_NL || info->stat == GLP_NU); - npp->r_stat[info->p] = info->stat; - } - else - { npp_error(); - return 1; - } - } - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_eq_doublet - process row doubleton (equality constraint) -* -* SYNOPSIS -* -* #include "glpnpp.h" -* NPPCOL *npp_eq_doublet(NPP *npp, NPPROW *p); -* -* DESCRIPTION -* -* The routine npp_eq_doublet processes row p, which is equality -* constraint having exactly two non-zero coefficients: -* -* a[p,q] x[q] + a[p,r] x[r] = b. (1) -* -* As the result of processing one of columns q or r is eliminated from -* all other rows and, thus, becomes column singleton of type "implied -* slack variable". Row p is not changed and along with column q and r -* remains in the problem. -* -* RETURNS -* -* The routine npp_eq_doublet returns pointer to the descriptor of that -* column q or r which has been eliminated. If, due to some reason, the -* elimination was not performed, the routine returns NULL. -* -* PROBLEM TRANSFORMATION -* -* First, we decide which column q or r will be eliminated. Let it be -* column q. Consider i-th constraint row, where column q has non-zero -* coefficient a[i,q] != 0: -* -* L[i] <= sum a[i,j] x[j] <= U[i]. (2) -* j -* -* In order to eliminate column q from row (2) we subtract from it row -* (1) multiplied by gamma[i] = a[i,q] / a[p,q], i.e. we replace in the -* transformed problem row (2) by its linear combination with row (1). -* This transformation changes only coefficients in columns q and r, -* and bounds of row i as follows: -* -* a~[i,q] = a[i,q] - gamma[i] a[p,q] = 0, (3) -* -* a~[i,r] = a[i,r] - gamma[i] a[p,r], (4) -* -* L~[i] = L[i] - gamma[i] b, (5) -* -* U~[i] = U[i] - gamma[i] b. (6) -* -* RECOVERING BASIC SOLUTION -* -* The transformation of the primal system of the original problem: -* -* L <= A x <= U (7) -* -* is equivalent to multiplying from the left a transformation matrix F -* by components of this primal system, which in the transformed problem -* becomes the following: -* -* F L <= F A x <= F U ==> L~ <= A~x <= U~. (8) -* -* The matrix F has the following structure: -* -* ( 1 -gamma[1] ) -* ( ) -* ( 1 -gamma[2] ) -* ( ) -* ( ... ... ) -* ( ) -* F = ( 1 -gamma[p-1] ) (9) -* ( ) -* ( 1 ) -* ( ) -* ( -gamma[p+1] 1 ) -* ( ) -* ( ... ... ) -* -* where its column containing elements -gamma[i] corresponds to row p -* of the primal system. -* -* From (8) it follows that the dual system of the original problem: -* -* A'pi + lambda = c, (10) -* -* in the transformed problem becomes the following: -* -* A'F'inv(F')pi + lambda = c ==> (A~)'pi~ + lambda = c, (11) -* -* where: -* -* pi~ = inv(F')pi (12) -* -* is the vector of row multipliers in the transformed problem. Thus: -* -* pi = F'pi~. (13) -* -* Therefore, as it follows from (13), value of multiplier for row p in -* solution to the original problem can be computed as follows: -* -* pi[p] = pi~[p] - sum gamma[i] pi~[i], (14) -* i -* -* where pi~[i] = pi[i] is multiplier for row i (i != p). -* -* Note that the statuses of all rows and columns are not changed. -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* Multiplier for row p in solution to the original problem is computed -* with formula (14). -* -* RECOVERING MIP SOLUTION -* -* None needed. */ - -struct eq_doublet -{ /* row doubleton (equality constraint) */ - int p; - /* row reference number */ - double apq; - /* constraint coefficient a[p,q] */ - NPPLFE *ptr; - /* list of non-zero coefficients a[i,q], i != p */ -}; - -static int rcv_eq_doublet(NPP *npp, void *info); - -NPPCOL *npp_eq_doublet(NPP *npp, NPPROW *p) -{ /* process row doubleton (equality constraint) */ - struct eq_doublet *info; - NPPROW *i; - NPPCOL *q, *r; - NPPAIJ *apq, *apr, *aiq, *air, *next; - NPPLFE *lfe; - double gamma; - /* the row must be doubleton equality constraint */ - xassert(p->lb == p->ub); - xassert(p->ptr != NULL && p->ptr->r_next != NULL && - p->ptr->r_next->r_next == NULL); - /* choose column to be eliminated */ - { NPPAIJ *a1, *a2; - a1 = p->ptr, a2 = a1->r_next; - if (fabs(a2->val) < 0.001 * fabs(a1->val)) - { /* only first column can be eliminated, because second one - has too small constraint coefficient */ - apq = a1, apr = a2; - } - else if (fabs(a1->val) < 0.001 * fabs(a2->val)) - { /* only second column can be eliminated, because first one - has too small constraint coefficient */ - apq = a2, apr = a1; - } - else - { /* both columns are appropriate; choose that one which is - shorter to minimize fill-in */ - if (npp_col_nnz(npp, a1->col) <= npp_col_nnz(npp, a2->col)) - { /* first column is shorter */ - apq = a1, apr = a2; - } - else - { /* second column is shorter */ - apq = a2, apr = a1; - } - } - } - /* now columns q and r have been chosen */ - q = apq->col, r = apr->col; - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_eq_doublet, sizeof(struct eq_doublet)); - info->p = p->i; - info->apq = apq->val; - info->ptr = NULL; - /* transform each row i (i != p), where a[i,q] != 0, to eliminate - column q */ - for (aiq = q->ptr; aiq != NULL; aiq = next) - { next = aiq->c_next; - if (aiq == apq) continue; /* skip row p */ - i = aiq->row; /* row i to be transformed */ - /* save constraint coefficient a[i,q] */ - if (npp->sol != GLP_MIP) - { lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); - lfe->ref = i->i; - lfe->val = aiq->val; - lfe->next = info->ptr; - info->ptr = lfe; - } - /* find coefficient a[i,r] in row i */ - for (air = i->ptr; air != NULL; air = air->r_next) - if (air->col == r) break; - /* if a[i,r] does not exist, create a[i,r] = 0 */ - if (air == NULL) - air = npp_add_aij(npp, i, r, 0.0); - /* compute gamma[i] = a[i,q] / a[p,q] */ - gamma = aiq->val / apq->val; - /* (row i) := (row i) - gamma[i] * (row p); see (3)-(6) */ - /* new a[i,q] is exact zero due to elimnation; remove it from - row i */ - npp_del_aij(npp, aiq); - /* compute new a[i,r] */ - air->val -= gamma * apr->val; - /* if new a[i,r] is close to zero due to numeric cancelation, - remove it from row i */ - if (fabs(air->val) <= 1e-10) - npp_del_aij(npp, air); - /* compute new lower and upper bounds of row i */ - if (i->lb == i->ub) - i->lb = i->ub = (i->lb - gamma * p->lb); - else - { if (i->lb != -DBL_MAX) - i->lb -= gamma * p->lb; - if (i->ub != +DBL_MAX) - i->ub -= gamma * p->lb; - } - } - return q; -} - -static int rcv_eq_doublet(NPP *npp, void *_info) -{ /* recover row doubleton (equality constraint) */ - struct eq_doublet *info = _info; - NPPLFE *lfe; - double gamma, temp; - /* we assume that processing row p is followed by processing - column q as singleton of type "implied slack variable", in - which case row p must always be active equality constraint */ - if (npp->sol == GLP_SOL) - { if (npp->r_stat[info->p] != GLP_NS) - { npp_error(); - return 1; - } - } - if (npp->sol != GLP_MIP) - { /* compute value of multiplier for row p; see (14) */ - temp = npp->r_pi[info->p]; - for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) - { gamma = lfe->val / info->apq; /* a[i,q] / a[p,q] */ - temp -= gamma * npp->r_pi[lfe->ref]; - } - npp->r_pi[info->p] = temp; - } - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_forcing_row - process forcing row -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_forcing_row(NPP *npp, NPPROW *p, int at); -* -* DESCRIPTION -* -* The routine npp_forcing row processes row p of general format: -* -* L[p] <= sum a[p,j] x[j] <= U[p], (1) -* j -* -* l[j] <= x[j] <= u[j], (2) -* -* where L[p] <= U[p] and l[j] < u[j] for all a[p,j] != 0. It is also -* assumed that: -* -* 1) if at = 0 then |L[p] - U'[p]| <= eps, where U'[p] is implied -* row upper bound (see below), eps is an absolute tolerance for row -* value; -* -* 2) if at = 1 then |U[p] - L'[p]| <= eps, where L'[p] is implied -* row lower bound (see below). -* -* RETURNS -* -* 0 - success; -* -* 1 - cannot fix columns due to too small constraint coefficients. -* -* PROBLEM TRANSFORMATION -* -* Implied lower and upper bounds of row (1) are determined by bounds -* of corresponding columns (variables) as follows: -* -* L'[p] = inf sum a[p,j] x[j] = -* j -* (3) -* = sum a[p,j] l[j] + sum a[p,j] u[j], -* j in Jp j in Jn -* -* U'[p] = sup sum a[p,j] x[j] = -* (4) -* = sum a[p,j] u[j] + sum a[p,j] l[j], -* j in Jp j in Jn -* -* Jp = {j: a[p,j] > 0}, Jn = {j: a[p,j] < 0}. (5) -* -* If L[p] =~ U'[p] (at = 0), solution can be primal feasible only when -* all variables take their boundary values as defined by (4): -* -* ( u[j], if j in Jp -* x[j] = < (6) -* ( l[j], if j in Jn -* -* Similarly, if U[p] =~ L'[p] (at = 1), solution can be primal feasible -* only when all variables take their boundary values as defined by (3): -* -* ( l[j], if j in Jp -* x[j] = < (7) -* ( u[j], if j in Jn -* -* Condition (6) or (7) allows fixing all columns (variables x[j]) -* in row (1) on their bounds and then removing them from the problem -* (see the routine npp_fixed_col). Due to this row p becomes redundant, -* so it can be replaced by equivalent free (unbounded) row and also -* removed from the problem (see the routine npp_free_row). -* -* 1. To apply this transformation row (1) should not have coefficients -* whose magnitude is too small, i.e. all a[p,j] should satisfy to -* the following condition: -* -* |a[p,j]| >= eps * max(1, |a[p,k]|), (8) -* k -* where eps is a relative tolerance for constraint coefficients. -* Otherwise, fixing columns may be numerically unreliable and may -* lead to wrong solution. -* -* 2. The routine fixes columns and remove bounds of row p, however, -* it does not remove the row and columns from the problem. -* -* RECOVERING BASIC SOLUTION -* -* In the transformed problem row p being inactive constraint is -* assigned status GLP_BS (as the result of transformation of free -* row), and all columns in this row are assigned status GLP_NS (as the -* result of transformation of fixed columns). -* -* Note that in the dual system of the transformed (as well as original) -* problem every column j in row p corresponds to the following row: -* -* sum a[i,j] pi[i] + a[p,j] pi[p] + lambda[j] = c[j], (9) -* i!=p -* -* from which it follows that: -* -* lambda[j] = c[j] - sum a[i,j] pi[i] - a[p,j] pi[p]. (10) -* i!=p -* -* In the transformed problem values of all multipliers pi[i] are known -* (including pi[i], whose value is zero, since row p is inactive). -* Thus, using formula (10) it is possible to compute values of -* multipliers lambda[j] for all columns in row p. -* -* Note also that in the original problem all columns in row p are -* bounded, not fixed. So status GLP_NS assigned to every such column -* must be changed to GLP_NL or GLP_NU depending on which bound the -* corresponding column has been fixed. This status change may lead to -* dual feasibility violation for solution of the original problem, -* because now column multipliers must satisfy to the following -* condition: -* -* ( >= 0, if status of column j is GLP_NL, -* lambda[j] < (11) -* ( <= 0, if status of column j is GLP_NU. -* -* If this condition holds, solution to the original problem is the -* same as to the transformed problem. Otherwise, we have to perform -* one degenerate pivoting step of the primal simplex method to obtain -* dual feasible (hence, optimal) solution to the original problem as -* follows. If, on problem transformation, row p was made active on its -* lower bound (case at = 0), we change its status to GLP_NL (or GLP_NS) -* and start increasing its multiplier pi[p]. Otherwise, if row p was -* made active on its upper bound (case at = 1), we change its status -* to GLP_NU (or GLP_NS) and start decreasing pi[p]. From (10) it -* follows that: -* -* delta lambda[j] = - a[p,j] * delta pi[p] = - a[p,j] pi[p]. (12) -* -* Simple analysis of formulae (3)-(5) shows that changing pi[p] in the -* specified direction causes increasing lambda[j] for every column j -* assigned status GLP_NL (delta lambda[j] > 0) and decreasing lambda[j] -* for every column j assigned status GLP_NU (delta lambda[j] < 0). It -* is understood that once the last lambda[q], which violates condition -* (11), has reached zero, multipliers lambda[j] for all columns get -* valid signs. Such column q can be determined as follows. Let d[j] be -* initial value of lambda[j] (i.e. reduced cost of column j) in the -* transformed problem computed with formula (10) when pi[p] = 0. Then -* lambda[j] = d[j] + delta lambda[j], and from (12) it follows that -* lambda[j] becomes zero if: -* -* delta lambda[j] = - a[p,j] pi[p] = - d[j] ==> -* (13) -* pi[p] = d[j] / a[p,j]. -* -* Therefore, the last column q, for which lambda[q] becomes zero, can -* be determined from the following condition: -* -* |d[q] / a[p,q]| = max |pi[p]| = max |d[j] / a[p,j]|, (14) -* j in D j in D -* -* where D is a set of columns j whose, reduced costs d[j] have invalid -* signs, i.e. violate condition (11). (Thus, if D is empty, solution -* to the original problem is the same as solution to the transformed -* problem, and no correction is needed as was noticed above.) In -* solution to the original problem column q is assigned status GLP_BS, -* since it replaces column of auxiliary variable of row p (becoming -* active) in the basis, and multiplier for row p is assigned its new -* value, which is pi[p] = d[q] / a[p,q]. Note that due to primal -* degeneracy values of all columns having non-zero coefficients in row -* p remain unchanged. -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* Value of multiplier pi[p] in solution to the original problem is -* corrected in the same way as for basic solution. Values of all -* columns having non-zero coefficients in row p remain unchanged. -* -* RECOVERING MIP SOLUTION -* -* None needed. */ - -struct forcing_col -{ /* column fixed on its bound by forcing row */ - int j; - /* column reference number */ - char stat; - /* original column status: - GLP_NL - fixed on lower bound - GLP_NU - fixed on upper bound */ - double a; - /* constraint coefficient a[p,j] */ - double c; - /* objective coefficient c[j] */ - NPPLFE *ptr; - /* list of non-zero coefficients a[i,j], i != p */ - struct forcing_col *next; - /* pointer to another column fixed by forcing row */ -}; - -struct forcing_row -{ /* forcing row */ - int p; - /* row reference number */ - char stat; - /* status assigned to the row if it becomes active: - GLP_NS - active equality constraint - GLP_NL - inequality constraint with lower bound active - GLP_NU - inequality constraint with upper bound active */ - struct forcing_col *ptr; - /* list of all columns having non-zero constraint coefficient - a[p,j] in the forcing row */ -}; - -static int rcv_forcing_row(NPP *npp, void *info); - -int npp_forcing_row(NPP *npp, NPPROW *p, int at) -{ /* process forcing row */ - struct forcing_row *info; - struct forcing_col *col = NULL; - NPPCOL *j; - NPPAIJ *apj, *aij; - NPPLFE *lfe; - double big; - xassert(at == 0 || at == 1); - /* determine maximal magnitude of the row coefficients */ - big = 1.0; - for (apj = p->ptr; apj != NULL; apj = apj->r_next) - if (big < fabs(apj->val)) big = fabs(apj->val); - /* if there are too small coefficients in the row, transformation - should not be applied */ - for (apj = p->ptr; apj != NULL; apj = apj->r_next) - if (fabs(apj->val) < 1e-7 * big) return 1; - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_forcing_row, sizeof(struct forcing_row)); - info->p = p->i; - if (p->lb == p->ub) - { /* equality constraint */ - info->stat = GLP_NS; - } - else if (at == 0) - { /* inequality constraint; case L[p] = U'[p] */ - info->stat = GLP_NL; - xassert(p->lb != -DBL_MAX); - } - else /* at == 1 */ - { /* inequality constraint; case U[p] = L'[p] */ - info->stat = GLP_NU; - xassert(p->ub != +DBL_MAX); - } - info->ptr = NULL; - /* scan the forcing row, fix columns at corresponding bounds, and - save column information (the latter is not needed for MIP) */ - for (apj = p->ptr; apj != NULL; apj = apj->r_next) - { /* column j has non-zero coefficient in the forcing row */ - j = apj->col; - /* it must be non-fixed */ - xassert(j->lb < j->ub); - /* allocate stack entry to save column information */ - if (npp->sol != GLP_MIP) - { col = dmp_get_atom(npp->stack, sizeof(struct forcing_col)); - col->j = j->j; - col->stat = -1; /* will be set below */ - col->a = apj->val; - col->c = j->coef; - col->ptr = NULL; - col->next = info->ptr; - info->ptr = col; - } - /* fix column j */ - if (at == 0 && apj->val < 0.0 || at != 0 && apj->val > 0.0) - { /* at its lower bound */ - if (npp->sol != GLP_MIP) - col->stat = GLP_NL; - xassert(j->lb != -DBL_MAX); - j->ub = j->lb; - } - else - { /* at its upper bound */ - if (npp->sol != GLP_MIP) - col->stat = GLP_NU; - xassert(j->ub != +DBL_MAX); - j->lb = j->ub; - } - /* save column coefficients a[i,j], i != p */ - if (npp->sol != GLP_MIP) - { for (aij = j->ptr; aij != NULL; aij = aij->c_next) - { if (aij == apj) continue; /* skip a[p,j] */ - lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); - lfe->ref = aij->row->i; - lfe->val = aij->val; - lfe->next = col->ptr; - col->ptr = lfe; - } - } - } - /* make the row free (unbounded) */ - p->lb = -DBL_MAX, p->ub = +DBL_MAX; - return 0; -} - -static int rcv_forcing_row(NPP *npp, void *_info) -{ /* recover forcing row */ - struct forcing_row *info = _info; - struct forcing_col *col, *piv; - NPPLFE *lfe; - double d, big, temp; - if (npp->sol == GLP_MIP) goto done; - /* initially solution to the original problem is the same as - to the transformed problem, where row p is inactive constraint - with pi[p] = 0, and all columns are non-basic */ - if (npp->sol == GLP_SOL) - { if (npp->r_stat[info->p] != GLP_BS) - { npp_error(); - return 1; - } - for (col = info->ptr; col != NULL; col = col->next) - { if (npp->c_stat[col->j] != GLP_NS) - { npp_error(); - return 1; - } - npp->c_stat[col->j] = col->stat; /* original status */ - } - } - /* compute reduced costs d[j] for all columns with formula (10) - and store them in col.c instead objective coefficients */ - for (col = info->ptr; col != NULL; col = col->next) - { d = col->c; - for (lfe = col->ptr; lfe != NULL; lfe = lfe->next) - d -= lfe->val * npp->r_pi[lfe->ref]; - col->c = d; - } - /* consider columns j, whose multipliers lambda[j] has wrong - sign in solution to the transformed problem (where lambda[j] = - d[j]), and choose column q, whose multipler lambda[q] reaches - zero last on changing row multiplier pi[p]; see (14) */ - piv = NULL, big = 0.0; - for (col = info->ptr; col != NULL; col = col->next) - { d = col->c; /* d[j] */ - temp = fabs(d / col->a); - if (col->stat == GLP_NL) - { /* column j has active lower bound */ - if (d < 0.0 && big < temp) - piv = col, big = temp; - } - else if (col->stat == GLP_NU) - { /* column j has active upper bound */ - if (d > 0.0 && big < temp) - piv = col, big = temp; - } - else - { npp_error(); - return 1; - } - } - /* if column q does not exist, no correction is needed */ - if (piv != NULL) - { /* correct solution; row p becomes active constraint while - column q becomes basic */ - if (npp->sol == GLP_SOL) - { npp->r_stat[info->p] = info->stat; - npp->c_stat[piv->j] = GLP_BS; - } - /* assign new value to row multiplier pi[p] = d[p] / a[p,q] */ - npp->r_pi[info->p] = piv->c / piv->a; - } -done: return 0; -} - -/*********************************************************************** -* NAME -* -* npp_analyze_row - perform general row analysis -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_analyze_row(NPP *npp, NPPROW *p); -* -* DESCRIPTION -* -* The routine npp_analyze_row performs analysis of row p of general -* format: -* -* L[p] <= sum a[p,j] x[j] <= U[p], (1) -* j -* -* l[j] <= x[j] <= u[j], (2) -* -* where L[p] <= U[p] and l[j] <= u[j] for all a[p,j] != 0. -* -* RETURNS -* -* 0x?0 - row lower bound does not exist or is redundant; -* -* 0x?1 - row lower bound can be active; -* -* 0x?2 - row lower bound is a forcing bound; -* -* 0x0? - row upper bound does not exist or is redundant; -* -* 0x1? - row upper bound can be active; -* -* 0x2? - row upper bound is a forcing bound; -* -* 0x33 - row bounds are inconsistent with column bounds. -* -* ALGORITHM -* -* Analysis of row (1) is based on analysis of its implied lower and -* upper bounds, which are determined by bounds of corresponding columns -* (variables) as follows: -* -* L'[p] = inf sum a[p,j] x[j] = -* j -* (3) -* = sum a[p,j] l[j] + sum a[p,j] u[j], -* j in Jp j in Jn -* -* U'[p] = sup sum a[p,j] x[j] = -* (4) -* = sum a[p,j] u[j] + sum a[p,j] l[j], -* j in Jp j in Jn -* -* Jp = {j: a[p,j] > 0}, Jn = {j: a[p,j] < 0}. (5) -* -* (Note that bounds of all columns in row p are assumed to be correct, -* so L'[p] <= U'[p].) -* -* Analysis of row lower bound L[p] includes the following cases: -* -* 1) if L[p] > U'[p] + eps, where eps is an absolute tolerance for row -* value, row lower bound L[p] and implied row upper bound U'[p] are -* inconsistent, ergo, the problem has no primal feasible solution; -* -* 2) if U'[p] - eps <= L[p] <= U'[p] + eps, i.e. if L[p] =~ U'[p], -* the row is a forcing row on its lower bound (see description of -* the routine npp_forcing_row); -* -* 3) if L[p] > L'[p] + eps, row lower bound L[p] can be active (this -* conclusion does not account other rows in the problem); -* -* 4) if L[p] <= L'[p] + eps, row lower bound L[p] cannot be active, so -* it is redundant and can be removed (replaced by -oo). -* -* Analysis of row upper bound U[p] is performed in a similar way and -* includes the following cases: -* -* 1) if U[p] < L'[p] - eps, row upper bound U[p] and implied row lower -* bound L'[p] are inconsistent, ergo the problem has no primal -* feasible solution; -* -* 2) if L'[p] - eps <= U[p] <= L'[p] + eps, i.e. if U[p] =~ L'[p], -* the row is a forcing row on its upper bound (see description of -* the routine npp_forcing_row); -* -* 3) if U[p] < U'[p] - eps, row upper bound U[p] can be active (this -* conclusion does not account other rows in the problem); -* -* 4) if U[p] >= U'[p] - eps, row upper bound U[p] cannot be active, so -* it is redundant and can be removed (replaced by +oo). */ - -int npp_analyze_row(NPP *npp, NPPROW *p) -{ /* perform general row analysis */ - NPPAIJ *aij; - int ret = 0x00; - double l, u, eps; - xassert(npp == npp); - /* compute implied lower bound L'[p]; see (3) */ - l = 0.0; - for (aij = p->ptr; aij != NULL; aij = aij->r_next) - { if (aij->val > 0.0) - { if (aij->col->lb == -DBL_MAX) - { l = -DBL_MAX; - break; - } - l += aij->val * aij->col->lb; - } - else /* aij->val < 0.0 */ - { if (aij->col->ub == +DBL_MAX) - { l = -DBL_MAX; - break; - } - l += aij->val * aij->col->ub; - } - } - /* compute implied upper bound U'[p]; see (4) */ - u = 0.0; - for (aij = p->ptr; aij != NULL; aij = aij->r_next) - { if (aij->val > 0.0) - { if (aij->col->ub == +DBL_MAX) - { u = +DBL_MAX; - break; - } - u += aij->val * aij->col->ub; - } - else /* aij->val < 0.0 */ - { if (aij->col->lb == -DBL_MAX) - { u = +DBL_MAX; - break; - } - u += aij->val * aij->col->lb; - } - } - /* column bounds are assumed correct, so L'[p] <= U'[p] */ - /* check if row lower bound is consistent */ - if (p->lb != -DBL_MAX) - { eps = 1e-3 + 1e-6 * fabs(p->lb); - if (p->lb - eps > u) - { ret = 0x33; - goto done; - } - } - /* check if row upper bound is consistent */ - if (p->ub != +DBL_MAX) - { eps = 1e-3 + 1e-6 * fabs(p->ub); - if (p->ub + eps < l) - { ret = 0x33; - goto done; - } - } - /* check if row lower bound can be active/forcing */ - if (p->lb != -DBL_MAX) - { eps = 1e-9 + 1e-12 * fabs(p->lb); - if (p->lb - eps > l) - { if (p->lb + eps <= u) - ret |= 0x01; - else - ret |= 0x02; - } - } - /* check if row upper bound can be active/forcing */ - if (p->ub != +DBL_MAX) - { eps = 1e-9 + 1e-12 * fabs(p->ub); - if (p->ub + eps < u) - { /* check if the upper bound is forcing */ - if (p->ub - eps >= l) - ret |= 0x10; - else - ret |= 0x20; - } - } -done: return ret; -} - -/*********************************************************************** -* NAME -* -* npp_inactive_bound - remove row lower/upper inactive bound -* -* SYNOPSIS -* -* #include "glpnpp.h" -* void npp_inactive_bound(NPP *npp, NPPROW *p, int which); -* -* DESCRIPTION -* -* The routine npp_inactive_bound removes lower (if which = 0) or upper -* (if which = 1) bound of row p: -* -* L[p] <= sum a[p,j] x[j] <= U[p], -* -* which (bound) is assumed to be redundant. -* -* PROBLEM TRANSFORMATION -* -* If which = 0, current lower bound L[p] of row p is assigned -oo. -* If which = 1, current upper bound U[p] of row p is assigned +oo. -* -* RECOVERING BASIC SOLUTION -* -* If in solution to the transformed problem row p is inactive -* constraint (GLP_BS), its status is not changed in solution to the -* original problem. Otherwise, status of row p in solution to the -* original problem is defined by its type before transformation and -* its status in solution to the transformed problem as follows: -* -* +---------------------+-------+---------------+---------------+ -* | Row | Flag | Row status in | Row status in | -* | type | which | transfmd soln | original soln | -* +---------------------+-------+---------------+---------------+ -* | sum >= L[p] | 0 | GLP_NF | GLP_NL | -* | sum <= U[p] | 1 | GLP_NF | GLP_NU | -* | L[p] <= sum <= U[p] | 0 | GLP_NU | GLP_NU | -* | L[p] <= sum <= U[p] | 1 | GLP_NL | GLP_NL | -* | sum = L[p] = U[p] | 0 | GLP_NU | GLP_NS | -* | sum = L[p] = U[p] | 1 | GLP_NL | GLP_NS | -* +---------------------+-------+---------------+---------------+ -* -* RECOVERING INTERIOR-POINT SOLUTION -* -* None needed. -* -* RECOVERING MIP SOLUTION -* -* None needed. */ - -struct inactive_bound -{ /* row inactive bound */ - int p; - /* row reference number */ - char stat; - /* row status (if active constraint) */ -}; - -static int rcv_inactive_bound(NPP *npp, void *info); - -void npp_inactive_bound(NPP *npp, NPPROW *p, int which) -{ /* remove row lower/upper inactive bound */ - struct inactive_bound *info; - if (npp->sol == GLP_SOL) - { /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_inactive_bound, sizeof(struct inactive_bound)); - info->p = p->i; - if (p->ub == +DBL_MAX) - info->stat = GLP_NL; - else if (p->lb == -DBL_MAX) - info->stat = GLP_NU; - else if (p->lb != p->ub) - info->stat = (char)(which == 0 ? GLP_NU : GLP_NL); - else - info->stat = GLP_NS; - } - /* remove row inactive bound */ - if (which == 0) - { xassert(p->lb != -DBL_MAX); - p->lb = -DBL_MAX; - } - else if (which == 1) - { xassert(p->ub != +DBL_MAX); - p->ub = +DBL_MAX; - } - else - xassert(which != which); - return; -} - -static int rcv_inactive_bound(NPP *npp, void *_info) -{ /* recover row status */ - struct inactive_bound *info = _info; - if (npp->sol != GLP_SOL) - { npp_error(); - return 1; - } - if (npp->r_stat[info->p] == GLP_BS) - npp->r_stat[info->p] = GLP_BS; - else - npp->r_stat[info->p] = info->stat; - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_implied_bounds - determine implied column bounds -* -* SYNOPSIS -* -* #include "glpnpp.h" -* void npp_implied_bounds(NPP *npp, NPPROW *p); -* -* DESCRIPTION -* -* The routine npp_implied_bounds inspects general row (constraint) p: -* -* L[p] <= sum a[p,j] x[j] <= U[p], (1) -* -* l[j] <= x[j] <= u[j], (2) -* -* where L[p] <= U[p] and l[j] <= u[j] for all a[p,j] != 0, to compute -* implied bounds of columns (variables x[j]) in this row. -* -* The routine stores implied column bounds l'[j] and u'[j] in column -* descriptors (NPPCOL); it does not change current column bounds l[j] -* and u[j]. (Implied column bounds can be then used to strengthen the -* current column bounds; see the routines npp_implied_lower and -* npp_implied_upper). -* -* ALGORITHM -* -* Current column bounds (2) define implied lower and upper bounds of -* row (1) as follows: -* -* L'[p] = inf sum a[p,j] x[j] = -* j -* (3) -* = sum a[p,j] l[j] + sum a[p,j] u[j], -* j in Jp j in Jn -* -* U'[p] = sup sum a[p,j] x[j] = -* (4) -* = sum a[p,j] u[j] + sum a[p,j] l[j], -* j in Jp j in Jn -* -* Jp = {j: a[p,j] > 0}, Jn = {j: a[p,j] < 0}. (5) -* -* (Note that bounds of all columns in row p are assumed to be correct, -* so L'[p] <= U'[p].) -* -* If L[p] > L'[p] and/or U[p] < U'[p], the lower and/or upper bound of -* row (1) can be active, in which case such row defines implied bounds -* of its variables. -* -* Let x[k] be some variable having in row (1) coefficient a[p,k] != 0. -* Consider a case when row lower bound can be active (L[p] > L'[p]): -* -* sum a[p,j] x[j] >= L[p] ==> -* j -* -* sum a[p,j] x[j] + a[p,k] x[k] >= L[p] ==> -* j!=k -* (6) -* a[p,k] x[k] >= L[p] - sum a[p,j] x[j] ==> -* j!=k -* -* a[p,k] x[k] >= L[p,k], -* -* where -* -* L[p,k] = inf(L[p] - sum a[p,j] x[j]) = -* j!=k -* -* = L[p] - sup sum a[p,j] x[j] = (7) -* j!=k -* -* = L[p] - sum a[p,j] u[j] - sum a[p,j] l[j]. -* j in Jp\{k} j in Jn\{k} -* -* Thus: -* -* x[k] >= l'[k] = L[p,k] / a[p,k], if a[p,k] > 0, (8) -* -* x[k] <= u'[k] = L[p,k] / a[p,k], if a[p,k] < 0. (9) -* -* where l'[k] and u'[k] are implied lower and upper bounds of variable -* x[k], resp. -* -* Now consider a similar case when row upper bound can be active -* (U[p] < U'[p]): -* -* sum a[p,j] x[j] <= U[p] ==> -* j -* -* sum a[p,j] x[j] + a[p,k] x[k] <= U[p] ==> -* j!=k -* (10) -* a[p,k] x[k] <= U[p] - sum a[p,j] x[j] ==> -* j!=k -* -* a[p,k] x[k] <= U[p,k], -* -* where: -* -* U[p,k] = sup(U[p] - sum a[p,j] x[j]) = -* j!=k -* -* = U[p] - inf sum a[p,j] x[j] = (11) -* j!=k -* -* = U[p] - sum a[p,j] l[j] - sum a[p,j] u[j]. -* j in Jp\{k} j in Jn\{k} -* -* Thus: -* -* x[k] <= u'[k] = U[p,k] / a[p,k], if a[p,k] > 0, (12) -* -* x[k] >= l'[k] = U[p,k] / a[p,k], if a[p,k] < 0. (13) -* -* Note that in formulae (8), (9), (12), and (13) coefficient a[p,k] -* must not be too small in magnitude relatively to other non-zero -* coefficients in row (1), i.e. the following condition must hold: -* -* |a[p,k]| >= eps * max(1, |a[p,j]|), (14) -* j -* -* where eps is a relative tolerance for constraint coefficients. -* Otherwise the implied column bounds can be numerical inreliable. For -* example, using formula (8) for the following inequality constraint: -* -* 1e-12 x1 - x2 - x3 >= 0, -* -* where x1 >= -1, x2, x3, >= 0, may lead to numerically unreliable -* conclusion that x1 >= 0. -* -* Using formulae (8), (9), (12), and (13) to compute implied bounds -* for one variable requires |J| operations, where J = {j: a[p,j] != 0}, -* because this needs computing L[p,k] and U[p,k]. Thus, computing -* implied bounds for all variables in row (1) would require |J|^2 -* operations, that is not a good technique. However, the total number -* of operations can be reduced to |J| as follows. -* -* Let a[p,k] > 0. Then from (7) and (11) we have: -* -* L[p,k] = L[p] - (U'[p] - a[p,k] u[k]) = -* -* = L[p] - U'[p] + a[p,k] u[k], -* -* U[p,k] = U[p] - (L'[p] - a[p,k] l[k]) = -* -* = U[p] - L'[p] + a[p,k] l[k], -* -* where L'[p] and U'[p] are implied row lower and upper bounds defined -* by formulae (3) and (4). Substituting these expressions into (8) and -* (12) gives: -* -* l'[k] = L[p,k] / a[p,k] = u[k] + (L[p] - U'[p]) / a[p,k], (15) -* -* u'[k] = U[p,k] / a[p,k] = l[k] + (U[p] - L'[p]) / a[p,k]. (16) -* -* Similarly, if a[p,k] < 0, according to (7) and (11) we have: -* -* L[p,k] = L[p] - (U'[p] - a[p,k] l[k]) = -* -* = L[p] - U'[p] + a[p,k] l[k], -* -* U[p,k] = U[p] - (L'[p] - a[p,k] u[k]) = -* -* = U[p] - L'[p] + a[p,k] u[k], -* -* and substituting these expressions into (8) and (12) gives: -* -* l'[k] = U[p,k] / a[p,k] = u[k] + (U[p] - L'[p]) / a[p,k], (17) -* -* u'[k] = L[p,k] / a[p,k] = l[k] + (L[p] - U'[p]) / a[p,k]. (18) -* -* Note that formulae (15)-(18) can be used only if L'[p] and U'[p] -* exist. However, if for some variable x[j] it happens that l[j] = -oo -* and/or u[j] = +oo, values of L'[p] (if a[p,j] > 0) and/or U'[p] (if -* a[p,j] < 0) are undefined. Consider, therefore, the most general -* situation, when some column bounds (2) may not exist. -* -* Let: -* -* J' = {j : (a[p,j] > 0 and l[j] = -oo) or -* (19) -* (a[p,j] < 0 and u[j] = +oo)}. -* -* Then (assuming that row upper bound U[p] can be active) the following -* three cases are possible: -* -* 1) |J'| = 0. In this case L'[p] exists, thus, for all variables x[j] -* in row (1) we can use formulae (16) and (17); -* -* 2) J' = {k}. In this case L'[p] = -oo, however, U[p,k] (11) exists, -* so for variable x[k] we can use formulae (12) and (13). Note that -* for all other variables x[j] (j != k) l'[j] = -oo (if a[p,j] < 0) -* or u'[j] = +oo (if a[p,j] > 0); -* -* 3) |J'| > 1. In this case for all variables x[j] in row [1] we have -* l'[j] = -oo (if a[p,j] < 0) or u'[j] = +oo (if a[p,j] > 0). -* -* Similarly, let: -* -* J'' = {j : (a[p,j] > 0 and u[j] = +oo) or -* (20) -* (a[p,j] < 0 and l[j] = -oo)}. -* -* Then (assuming that row lower bound L[p] can be active) the following -* three cases are possible: -* -* 1) |J''| = 0. In this case U'[p] exists, thus, for all variables x[j] -* in row (1) we can use formulae (15) and (18); -* -* 2) J'' = {k}. In this case U'[p] = +oo, however, L[p,k] (7) exists, -* so for variable x[k] we can use formulae (8) and (9). Note that -* for all other variables x[j] (j != k) l'[j] = -oo (if a[p,j] > 0) -* or u'[j] = +oo (if a[p,j] < 0); -* -* 3) |J''| > 1. In this case for all variables x[j] in row (1) we have -* l'[j] = -oo (if a[p,j] > 0) or u'[j] = +oo (if a[p,j] < 0). */ - -void npp_implied_bounds(NPP *npp, NPPROW *p) -{ NPPAIJ *apj, *apk; - double big, eps, temp; - xassert(npp == npp); - /* initialize implied bounds for all variables and determine - maximal magnitude of row coefficients a[p,j] */ - big = 1.0; - for (apj = p->ptr; apj != NULL; apj = apj->r_next) - { apj->col->ll.ll = -DBL_MAX, apj->col->uu.uu = +DBL_MAX; - if (big < fabs(apj->val)) big = fabs(apj->val); - } - eps = 1e-6 * big; - /* process row lower bound (assuming that it can be active) */ - if (p->lb != -DBL_MAX) - { apk = NULL; - for (apj = p->ptr; apj != NULL; apj = apj->r_next) - { if (apj->val > 0.0 && apj->col->ub == +DBL_MAX || - apj->val < 0.0 && apj->col->lb == -DBL_MAX) - { if (apk == NULL) - apk = apj; - else - goto skip1; - } - } - /* if a[p,k] = NULL then |J'| = 0 else J' = { k } */ - temp = p->lb; - for (apj = p->ptr; apj != NULL; apj = apj->r_next) - { if (apj == apk) - /* skip a[p,k] */; - else if (apj->val > 0.0) - temp -= apj->val * apj->col->ub; - else /* apj->val < 0.0 */ - temp -= apj->val * apj->col->lb; - } - /* compute column implied bounds */ - if (apk == NULL) - { /* temp = L[p] - U'[p] */ - for (apj = p->ptr; apj != NULL; apj = apj->r_next) - { if (apj->val >= +eps) - { /* l'[j] := u[j] + (L[p] - U'[p]) / a[p,j] */ - apj->col->ll.ll = apj->col->ub + temp / apj->val; - } - else if (apj->val <= -eps) - { /* u'[j] := l[j] + (L[p] - U'[p]) / a[p,j] */ - apj->col->uu.uu = apj->col->lb + temp / apj->val; - } - } - } - else - { /* temp = L[p,k] */ - if (apk->val >= +eps) - { /* l'[k] := L[p,k] / a[p,k] */ - apk->col->ll.ll = temp / apk->val; - } - else if (apk->val <= -eps) - { /* u'[k] := L[p,k] / a[p,k] */ - apk->col->uu.uu = temp / apk->val; - } - } -skip1: ; - } - /* process row upper bound (assuming that it can be active) */ - if (p->ub != +DBL_MAX) - { apk = NULL; - for (apj = p->ptr; apj != NULL; apj = apj->r_next) - { if (apj->val > 0.0 && apj->col->lb == -DBL_MAX || - apj->val < 0.0 && apj->col->ub == +DBL_MAX) - { if (apk == NULL) - apk = apj; - else - goto skip2; - } - } - /* if a[p,k] = NULL then |J''| = 0 else J'' = { k } */ - temp = p->ub; - for (apj = p->ptr; apj != NULL; apj = apj->r_next) - { if (apj == apk) - /* skip a[p,k] */; - else if (apj->val > 0.0) - temp -= apj->val * apj->col->lb; - else /* apj->val < 0.0 */ - temp -= apj->val * apj->col->ub; - } - /* compute column implied bounds */ - if (apk == NULL) - { /* temp = U[p] - L'[p] */ - for (apj = p->ptr; apj != NULL; apj = apj->r_next) - { if (apj->val >= +eps) - { /* u'[j] := l[j] + (U[p] - L'[p]) / a[p,j] */ - apj->col->uu.uu = apj->col->lb + temp / apj->val; - } - else if (apj->val <= -eps) - { /* l'[j] := u[j] + (U[p] - L'[p]) / a[p,j] */ - apj->col->ll.ll = apj->col->ub + temp / apj->val; - } - } - } - else - { /* temp = U[p,k] */ - if (apk->val >= +eps) - { /* u'[k] := U[p,k] / a[p,k] */ - apk->col->uu.uu = temp / apk->val; - } - else if (apk->val <= -eps) - { /* l'[k] := U[p,k] / a[p,k] */ - apk->col->ll.ll = temp / apk->val; - } - } -skip2: ; - } - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpnpp04.c b/resources/3rdparty/glpk-4.53/src/glpnpp04.c deleted file mode 100644 index 925b1ba0f..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpnpp04.c +++ /dev/null @@ -1,1415 +0,0 @@ -/* glpnpp04.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpnpp.h" - -/*********************************************************************** -* NAME -* -* npp_binarize_prob - binarize MIP problem -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_binarize_prob(NPP *npp); -* -* DESCRIPTION -* -* The routine npp_binarize_prob replaces in the original MIP problem -* every integer variable: -* -* l[q] <= x[q] <= u[q], (1) -* -* where l[q] < u[q], by an equivalent sum of binary variables. -* -* RETURNS -* -* The routine returns the number of integer variables for which the -* transformation failed, because u[q] - l[q] > d_max. -* -* PROBLEM TRANSFORMATION -* -* If variable x[q] has non-zero lower bound, it is first processed -* with the routine npp_lbnd_col. Thus, we can assume that: -* -* 0 <= x[q] <= u[q]. (2) -* -* If u[q] = 1, variable x[q] is already binary, so further processing -* is not needed. Let, therefore, that 2 <= u[q] <= d_max, and n be a -* smallest integer such that u[q] <= 2^n - 1 (n >= 2, since u[q] >= 2). -* Then variable x[q] can be replaced by the following sum: -* -* n-1 -* x[q] = sum 2^k x[k], (3) -* k=0 -* -* where x[k] are binary columns (variables). If u[q] < 2^n - 1, the -* following additional inequality constraint must be also included in -* the transformed problem: -* -* n-1 -* sum 2^k x[k] <= u[q]. (4) -* k=0 -* -* Note: Assuming that in the transformed problem x[q] becomes binary -* variable x[0], this transformation causes new n-1 binary variables -* to appear. -* -* Substituting x[q] from (3) to the objective row gives: -* -* z = sum c[j] x[j] + c[0] = -* j -* -* = sum c[j] x[j] + c[q] x[q] + c[0] = -* j!=q -* n-1 -* = sum c[j] x[j] + c[q] sum 2^k x[k] + c[0] = -* j!=q k=0 -* n-1 -* = sum c[j] x[j] + sum c[k] x[k] + c[0], -* j!=q k=0 -* -* where: -* -* c[k] = 2^k c[q], k = 0, ..., n-1. (5) -* -* And substituting x[q] from (3) to i-th constraint row i gives: -* -* L[i] <= sum a[i,j] x[j] <= U[i] ==> -* j -* -* L[i] <= sum a[i,j] x[j] + a[i,q] x[q] <= U[i] ==> -* j!=q -* n-1 -* L[i] <= sum a[i,j] x[j] + a[i,q] sum 2^k x[k] <= U[i] ==> -* j!=q k=0 -* n-1 -* L[i] <= sum a[i,j] x[j] + sum a[i,k] x[k] <= U[i], -* j!=q k=0 -* -* where: -* -* a[i,k] = 2^k a[i,q], k = 0, ..., n-1. (6) -* -* RECOVERING SOLUTION -* -* Value of variable x[q] is computed with formula (3). */ - -struct binarize -{ int q; - /* column reference number for x[q] = x[0] */ - int j; - /* column reference number for x[1]; x[2] has reference number - j+1, x[3] - j+2, etc. */ - int n; - /* total number of binary variables, n >= 2 */ -}; - -static int rcv_binarize_prob(NPP *npp, void *info); - -int npp_binarize_prob(NPP *npp) -{ /* binarize MIP problem */ - struct binarize *info; - NPPROW *row; - NPPCOL *col, *bin; - NPPAIJ *aij; - int u, n, k, temp, nfails, nvars, nbins, nrows; - /* new variables will be added to the end of the column list, so - we go from the end to beginning of the column list */ - nfails = nvars = nbins = nrows = 0; - for (col = npp->c_tail; col != NULL; col = col->prev) - { /* skip continuous variable */ - if (!col->is_int) continue; - /* skip fixed variable */ - if (col->lb == col->ub) continue; - /* skip binary variable */ - if (col->lb == 0.0 && col->ub == 1.0) continue; - /* check if the transformation is applicable */ - if (col->lb < -1e6 || col->ub > +1e6 || - col->ub - col->lb > 4095.0) - { /* unfortunately, not */ - nfails++; - continue; - } - /* process integer non-binary variable x[q] */ - nvars++; - /* make x[q] non-negative, if its lower bound is non-zero */ - if (col->lb != 0.0) - npp_lbnd_col(npp, col); - /* now 0 <= x[q] <= u[q] */ - xassert(col->lb == 0.0); - u = (int)col->ub; - xassert(col->ub == (double)u); - /* if x[q] is binary, further processing is not needed */ - if (u == 1) continue; - /* determine smallest n such that u <= 2^n - 1 (thus, n is the - number of binary variables needed) */ - n = 2, temp = 4; - while (u >= temp) - n++, temp += temp; - nbins += n; - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_binarize_prob, sizeof(struct binarize)); - info->q = col->j; - info->j = 0; /* will be set below */ - info->n = n; - /* if u < 2^n - 1, we need one additional row for (4) */ - if (u < temp - 1) - { row = npp_add_row(npp), nrows++; - row->lb = -DBL_MAX, row->ub = u; - } - else - row = NULL; - /* in the transformed problem variable x[q] becomes binary - variable x[0], so its objective and constraint coefficients - are not changed */ - col->ub = 1.0; - /* include x[0] into constraint (4) */ - if (row != NULL) - npp_add_aij(npp, row, col, 1.0); - /* add other binary variables x[1], ..., x[n-1] */ - for (k = 1, temp = 2; k < n; k++, temp += temp) - { /* add new binary variable x[k] */ - bin = npp_add_col(npp); - bin->is_int = 1; - bin->lb = 0.0, bin->ub = 1.0; - bin->coef = (double)temp * col->coef; - /* store column reference number for x[1] */ - if (info->j == 0) - info->j = bin->j; - else - xassert(info->j + (k-1) == bin->j); - /* duplicate constraint coefficients for x[k]; this also - automatically includes x[k] into constraint (4) */ - for (aij = col->ptr; aij != NULL; aij = aij->c_next) - npp_add_aij(npp, aij->row, bin, (double)temp * aij->val); - } - } - if (nvars > 0) - xprintf("%d integer variable(s) were replaced by %d binary one" - "s\n", nvars, nbins); - if (nrows > 0) - xprintf("%d row(s) were added due to binarization\n", nrows); - if (nfails > 0) - xprintf("Binarization failed for %d integer variable(s)\n", - nfails); - return nfails; -} - -static int rcv_binarize_prob(NPP *npp, void *_info) -{ /* recovery binarized variable */ - struct binarize *info = _info; - int k, temp; - double sum; - /* compute value of x[q]; see formula (3) */ - sum = npp->c_value[info->q]; - for (k = 1, temp = 2; k < info->n; k++, temp += temp) - sum += (double)temp * npp->c_value[info->j + (k-1)]; - npp->c_value[info->q] = sum; - return 0; -} - -/**********************************************************************/ - -struct elem -{ /* linear form element a[j] x[j] */ - double aj; - /* non-zero coefficient value */ - NPPCOL *xj; - /* pointer to variable (column) */ - struct elem *next; - /* pointer to another term */ -}; - -static struct elem *copy_form(NPP *npp, NPPROW *row, double s) -{ /* copy linear form */ - NPPAIJ *aij; - struct elem *ptr, *e; - ptr = NULL; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { e = dmp_get_atom(npp->pool, sizeof(struct elem)); - e->aj = s * aij->val; - e->xj = aij->col; - e->next = ptr; - ptr = e; - } - return ptr; -} - -static void drop_form(NPP *npp, struct elem *ptr) -{ /* drop linear form */ - struct elem *e; - while (ptr != NULL) - { e = ptr; - ptr = e->next; - dmp_free_atom(npp->pool, e, sizeof(struct elem)); - } - return; -} - -/*********************************************************************** -* NAME -* -* npp_is_packing - test if constraint is packing inequality -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_is_packing(NPP *npp, NPPROW *row); -* -* RETURNS -* -* If the specified row (constraint) is packing inequality (see below), -* the routine npp_is_packing returns non-zero. Otherwise, it returns -* zero. -* -* PACKING INEQUALITIES -* -* In canonical format the packing inequality is the following: -* -* sum x[j] <= 1, (1) -* j in J -* -* where all variables x[j] are binary. This inequality expresses the -* condition that in any integer feasible solution at most one variable -* from set J can take non-zero (unity) value while other variables -* must be equal to zero. W.l.o.g. it is assumed that |J| >= 2, because -* if J is empty or |J| = 1, the inequality (1) is redundant. -* -* In general case the packing inequality may include original variables -* x[j] as well as their complements x~[j]: -* -* sum x[j] + sum x~[j] <= 1, (2) -* j in Jp j in Jn -* -* where Jp and Jn are not intersected. Therefore, using substitution -* x~[j] = 1 - x[j] gives the packing inequality in generalized format: -* -* sum x[j] - sum x[j] <= 1 - |Jn|. (3) -* j in Jp j in Jn */ - -int npp_is_packing(NPP *npp, NPPROW *row) -{ /* test if constraint is packing inequality */ - NPPCOL *col; - NPPAIJ *aij; - int b; - xassert(npp == npp); - if (!(row->lb == -DBL_MAX && row->ub != +DBL_MAX)) - return 0; - b = 1; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { col = aij->col; - if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) - return 0; - if (aij->val == +1.0) - ; - else if (aij->val == -1.0) - b--; - else - return 0; - } - if (row->ub != (double)b) return 0; - return 1; -} - -/*********************************************************************** -* NAME -* -* npp_hidden_packing - identify hidden packing inequality -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_hidden_packing(NPP *npp, NPPROW *row); -* -* DESCRIPTION -* -* The routine npp_hidden_packing processes specified inequality -* constraint, which includes only binary variables, and the number of -* the variables is not less than two. If the original inequality is -* equivalent to a packing inequality, the routine replaces it by this -* equivalent inequality. If the original constraint is double-sided -* inequality, it is replaced by a pair of single-sided inequalities, -* if necessary. -* -* RETURNS -* -* If the original inequality constraint was replaced by equivalent -* packing inequality, the routine npp_hidden_packing returns non-zero. -* Otherwise, it returns zero. -* -* PROBLEM TRANSFORMATION -* -* Consider an inequality constraint: -* -* sum a[j] x[j] <= b, (1) -* j in J -* -* where all variables x[j] are binary, and |J| >= 2. (In case of '>=' -* inequality it can be transformed to '<=' format by multiplying both -* its sides by -1.) -* -* Let Jp = {j: a[j] > 0}, Jn = {j: a[j] < 0}. Performing substitution -* x[j] = 1 - x~[j] for all j in Jn, we have: -* -* sum a[j] x[j] <= b ==> -* j in J -* -* sum a[j] x[j] + sum a[j] x[j] <= b ==> -* j in Jp j in Jn -* -* sum a[j] x[j] + sum a[j] (1 - x~[j]) <= b ==> -* j in Jp j in Jn -* -* sum a[j] x[j] - sum a[j] x~[j] <= b - sum a[j]. -* j in Jp j in Jn j in Jn -* -* Thus, meaning the transformation above, we can assume that in -* inequality (1) all coefficients a[j] are positive. Moreover, we can -* assume that a[j] <= b. In fact, let a[j] > b; then the following -* three cases are possible: -* -* 1) b < 0. In this case inequality (1) is infeasible, so the problem -* has no feasible solution (see the routine npp_analyze_row); -* -* 2) b = 0. In this case inequality (1) is a forcing inequality on its -* upper bound (see the routine npp_forcing row), from which it -* follows that all variables x[j] should be fixed at zero; -* -* 3) b > 0. In this case inequality (1) defines an implied zero upper -* bound for variable x[j] (see the routine npp_implied_bounds), from -* which it follows that x[j] should be fixed at zero. -* -* It is assumed that all three cases listed above have been recognized -* by the routine npp_process_prob, which performs basic MIP processing -* prior to a call the routine npp_hidden_packing. So, if one of these -* cases occurs, we should just skip processing such constraint. -* -* Thus, let 0 < a[j] <= b. Then it is obvious that constraint (1) is -* equivalent to packing inquality only if: -* -* a[j] + a[k] > b + eps (2) -* -* for all j, k in J, j != k, where eps is an absolute tolerance for -* row (linear form) value. Checking the condition (2) for all j and k, -* j != k, requires time O(|J|^2). However, this time can be reduced to -* O(|J|), if use minimal a[j] and a[k], in which case it is sufficient -* to check the condition (2) only once. -* -* Once the original inequality (1) is replaced by equivalent packing -* inequality, we need to perform back substitution x~[j] = 1 - x[j] for -* all j in Jn (see above). -* -* RECOVERING SOLUTION -* -* None needed. */ - -static int hidden_packing(NPP *npp, struct elem *ptr, double *_b) -{ /* process inequality constraint: sum a[j] x[j] <= b; - 0 - specified row is NOT hidden packing inequality; - 1 - specified row is packing inequality; - 2 - specified row is hidden packing inequality. */ - struct elem *e, *ej, *ek; - int neg; - double b = *_b, eps; - xassert(npp == npp); - /* a[j] must be non-zero, x[j] must be binary, for all j in J */ - for (e = ptr; e != NULL; e = e->next) - { xassert(e->aj != 0.0); - xassert(e->xj->is_int); - xassert(e->xj->lb == 0.0 && e->xj->ub == 1.0); - } - /* check if the specified inequality constraint already has the - form of packing inequality */ - neg = 0; /* neg is |Jn| */ - for (e = ptr; e != NULL; e = e->next) - { if (e->aj == +1.0) - ; - else if (e->aj == -1.0) - neg++; - else - break; - } - if (e == NULL) - { /* all coefficients a[j] are +1 or -1; check rhs b */ - if (b == (double)(1 - neg)) - { /* it is packing inequality; no processing is needed */ - return 1; - } - } - /* substitute x[j] = 1 - x~[j] for all j in Jn to make all a[j] - positive; the result is a~[j] = |a[j]| and new rhs b */ - for (e = ptr; e != NULL; e = e->next) - if (e->aj < 0) b -= e->aj; - /* now a[j] > 0 for all j in J (actually |a[j]| are used) */ - /* if a[j] > b, skip processing--this case must not appear */ - for (e = ptr; e != NULL; e = e->next) - if (fabs(e->aj) > b) return 0; - /* now 0 < a[j] <= b for all j in J */ - /* find two minimal coefficients a[j] and a[k], j != k */ - ej = NULL; - for (e = ptr; e != NULL; e = e->next) - if (ej == NULL || fabs(ej->aj) > fabs(e->aj)) ej = e; - xassert(ej != NULL); - ek = NULL; - for (e = ptr; e != NULL; e = e->next) - if (e != ej) - if (ek == NULL || fabs(ek->aj) > fabs(e->aj)) ek = e; - xassert(ek != NULL); - /* the specified constraint is equivalent to packing inequality - iff a[j] + a[k] > b + eps */ - eps = 1e-3 + 1e-6 * fabs(b); - if (fabs(ej->aj) + fabs(ek->aj) <= b + eps) return 0; - /* perform back substitution x~[j] = 1 - x[j] and construct the - final equivalent packing inequality in generalized format */ - b = 1.0; - for (e = ptr; e != NULL; e = e->next) - { if (e->aj > 0.0) - e->aj = +1.0; - else /* e->aj < 0.0 */ - e->aj = -1.0, b -= 1.0; - } - *_b = b; - return 2; -} - -int npp_hidden_packing(NPP *npp, NPPROW *row) -{ /* identify hidden packing inequality */ - NPPROW *copy; - NPPAIJ *aij; - struct elem *ptr, *e; - int kase, ret, count = 0; - double b; - /* the row must be inequality constraint */ - xassert(row->lb < row->ub); - for (kase = 0; kase <= 1; kase++) - { if (kase == 0) - { /* process row upper bound */ - if (row->ub == +DBL_MAX) continue; - ptr = copy_form(npp, row, +1.0); - b = + row->ub; - } - else - { /* process row lower bound */ - if (row->lb == -DBL_MAX) continue; - ptr = copy_form(npp, row, -1.0); - b = - row->lb; - } - /* now the inequality has the form "sum a[j] x[j] <= b" */ - ret = hidden_packing(npp, ptr, &b); - xassert(0 <= ret && ret <= 2); - if (kase == 1 && ret == 1 || ret == 2) - { /* the original inequality has been identified as hidden - packing inequality */ - count++; -#ifdef GLP_DEBUG - xprintf("Original constraint:\n"); - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - xprintf(" %+g x%d", aij->val, aij->col->j); - if (row->lb != -DBL_MAX) xprintf(", >= %g", row->lb); - if (row->ub != +DBL_MAX) xprintf(", <= %g", row->ub); - xprintf("\n"); - xprintf("Equivalent packing inequality:\n"); - for (e = ptr; e != NULL; e = e->next) - xprintf(" %sx%d", e->aj > 0.0 ? "+" : "-", e->xj->j); - xprintf(", <= %g\n", b); -#endif - if (row->lb == -DBL_MAX || row->ub == +DBL_MAX) - { /* the original row is single-sided inequality; no copy - is needed */ - copy = NULL; - } - else - { /* the original row is double-sided inequality; we need - to create its copy for other bound before replacing it - with the equivalent inequality */ - copy = npp_add_row(npp); - if (kase == 0) - { /* the copy is for lower bound */ - copy->lb = row->lb, copy->ub = +DBL_MAX; - } - else - { /* the copy is for upper bound */ - copy->lb = -DBL_MAX, copy->ub = row->ub; - } - /* copy original row coefficients */ - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - npp_add_aij(npp, copy, aij->col, aij->val); - } - /* replace the original inequality by equivalent one */ - npp_erase_row(npp, row); - row->lb = -DBL_MAX, row->ub = b; - for (e = ptr; e != NULL; e = e->next) - npp_add_aij(npp, row, e->xj, e->aj); - /* continue processing lower bound for the copy */ - if (copy != NULL) row = copy; - } - drop_form(npp, ptr); - } - return count; -} - -/*********************************************************************** -* NAME -* -* npp_implied_packing - identify implied packing inequality -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_implied_packing(NPP *npp, NPPROW *row, int which, -* NPPCOL *var[], char set[]); -* -* DESCRIPTION -* -* The routine npp_implied_packing processes specified row (constraint) -* of general format: -* -* L <= sum a[j] x[j] <= U. (1) -* j -* -* If which = 0, only lower bound L, which must exist, is considered, -* while upper bound U is ignored. Similarly, if which = 1, only upper -* bound U, which must exist, is considered, while lower bound L is -* ignored. Thus, if the specified row is a double-sided inequality or -* equality constraint, this routine should be called twice for both -* lower and upper bounds. -* -* The routine npp_implied_packing attempts to find a non-trivial (i.e. -* having not less than two binary variables) packing inequality: -* -* sum x[j] - sum x[j] <= 1 - |Jn|, (2) -* j in Jp j in Jn -* -* which is relaxation of the constraint (1) in the sense that any -* solution satisfying to that constraint also satisfies to the packing -* inequality (2). If such relaxation exists, the routine stores -* pointers to descriptors of corresponding binary variables and their -* flags, resp., to locations var[1], var[2], ..., var[len] and set[1], -* set[2], ..., set[len], where set[j] = 0 means that j in Jp and -* set[j] = 1 means that j in Jn. -* -* RETURNS -* -* The routine npp_implied_packing returns len, which is the total -* number of binary variables in the packing inequality found, len >= 2. -* However, if the relaxation does not exist, the routine returns zero. -* -* ALGORITHM -* -* If which = 0, the constraint coefficients (1) are multiplied by -1 -* and b is assigned -L; if which = 1, the constraint coefficients (1) -* are not changed and b is assigned +U. In both cases the specified -* constraint gets the following format: -* -* sum a[j] x[j] <= b. (3) -* j -* -* (Note that (3) is a relaxation of (1), because one of bounds L or U -* is ignored.) -* -* Let J be set of binary variables, Kp be set of non-binary (integer -* or continuous) variables with a[j] > 0, and Kn be set of non-binary -* variables with a[j] < 0. Then the inequality (3) can be written as -* follows: -* -* sum a[j] x[j] <= b - sum a[j] x[j] - sum a[j] x[j]. (4) -* j in J j in Kp j in Kn -* -* To get rid of non-binary variables we can replace the inequality (4) -* by the following relaxed inequality: -* -* sum a[j] x[j] <= b~, (5) -* j in J -* -* where: -* -* b~ = sup(b - sum a[j] x[j] - sum a[j] x[j]) = -* j in Kp j in Kn -* -* = b - inf sum a[j] x[j] - inf sum a[j] x[j] = (6) -* j in Kp j in Kn -* -* = b - sum a[j] l[j] - sum a[j] u[j]. -* j in Kp j in Kn -* -* Note that if lower bound l[j] (if j in Kp) or upper bound u[j] -* (if j in Kn) of some non-binary variable x[j] does not exist, then -* formally b = +oo, in which case further analysis is not performed. -* -* Let Bp = {j in J: a[j] > 0}, Bn = {j in J: a[j] < 0}. To make all -* the inequality coefficients in (5) positive, we replace all x[j] in -* Bn by their complementaries, substituting x[j] = 1 - x~[j] for all -* j in Bn, that gives: -* -* sum a[j] x[j] - sum a[j] x~[j] <= b~ - sum a[j]. (7) -* j in Bp j in Bn j in Bn -* -* This inequality is a relaxation of the original constraint (1), and -* it is a binary knapsack inequality. Writing it in the standard format -* we have: -* -* sum alfa[j] z[j] <= beta, (8) -* j in J -* -* where: -* ( + a[j], if j in Bp, -* alfa[j] = < (9) -* ( - a[j], if j in Bn, -* -* ( x[j], if j in Bp, -* z[j] = < (10) -* ( 1 - x[j], if j in Bn, -* -* beta = b~ - sum a[j]. (11) -* j in Bn -* -* In the inequality (8) all coefficients are positive, therefore, the -* packing relaxation to be found for this inequality is the following: -* -* sum z[j] <= 1. (12) -* j in P -* -* It is obvious that set P within J, which we would like to find, must -* satisfy to the following condition: -* -* alfa[j] + alfa[k] > beta + eps for all j, k in P, j != k, (13) -* -* where eps is an absolute tolerance for value of the linear form. -* Thus, it is natural to take P = {j: alpha[j] > (beta + eps) / 2}. -* Moreover, if in the equality (8) there exist coefficients alfa[k], -* for which alfa[k] <= (beta + eps) / 2, but which, nevertheless, -* satisfies to the condition (13) for all j in P, *one* corresponding -* variable z[k] (having, for example, maximal coefficient alfa[k]) can -* be included in set P, that allows increasing the number of binary -* variables in (12) by one. -* -* Once the set P has been built, for the inequality (12) we need to -* perform back substitution according to (10) in order to express it -* through the original binary variables. As the result of such back -* substitution the relaxed packing inequality get its final format (2), -* where Jp = J intersect Bp, and Jn = J intersect Bn. */ - -int npp_implied_packing(NPP *npp, NPPROW *row, int which, - NPPCOL *var[], char set[]) -{ struct elem *ptr, *e, *i, *k; - int len = 0; - double b, eps; - /* build inequality (3) */ - if (which == 0) - { ptr = copy_form(npp, row, -1.0); - xassert(row->lb != -DBL_MAX); - b = - row->lb; - } - else if (which == 1) - { ptr = copy_form(npp, row, +1.0); - xassert(row->ub != +DBL_MAX); - b = + row->ub; - } - /* remove non-binary variables to build relaxed inequality (5); - compute its right-hand side b~ with formula (6) */ - for (e = ptr; e != NULL; e = e->next) - { if (!(e->xj->is_int && e->xj->lb == 0.0 && e->xj->ub == 1.0)) - { /* x[j] is non-binary variable */ - if (e->aj > 0.0) - { if (e->xj->lb == -DBL_MAX) goto done; - b -= e->aj * e->xj->lb; - } - else /* e->aj < 0.0 */ - { if (e->xj->ub == +DBL_MAX) goto done; - b -= e->aj * e->xj->ub; - } - /* a[j] = 0 means that variable x[j] is removed */ - e->aj = 0.0; - } - } - /* substitute x[j] = 1 - x~[j] to build knapsack inequality (8); - compute its right-hand side beta with formula (11) */ - for (e = ptr; e != NULL; e = e->next) - if (e->aj < 0.0) b -= e->aj; - /* if beta is close to zero, the knapsack inequality is either - infeasible or forcing inequality; this must never happen, so - we skip further analysis */ - if (b < 1e-3) goto done; - /* build set P as well as sets Jp and Jn, and determine x[k] as - explained above in comments to the routine */ - eps = 1e-3 + 1e-6 * b; - i = k = NULL; - for (e = ptr; e != NULL; e = e->next) - { /* note that alfa[j] = |a[j]| */ - if (fabs(e->aj) > 0.5 * (b + eps)) - { /* alfa[j] > (b + eps) / 2; include x[j] in set P, i.e. in - set Jp or Jn */ - var[++len] = e->xj; - set[len] = (char)(e->aj > 0.0 ? 0 : 1); - /* alfa[i] = min alfa[j] over all j included in set P */ - if (i == NULL || fabs(i->aj) > fabs(e->aj)) i = e; - } - else if (fabs(e->aj) >= 1e-3) - { /* alfa[k] = max alfa[j] over all j not included in set P; - we skip coefficient a[j] if it is close to zero to avoid - numerically unreliable results */ - if (k == NULL || fabs(k->aj) < fabs(e->aj)) k = e; - } - } - /* if alfa[k] satisfies to condition (13) for all j in P, include - x[k] in P */ - if (i != NULL && k != NULL && fabs(i->aj) + fabs(k->aj) > b + eps) - { var[++len] = k->xj; - set[len] = (char)(k->aj > 0.0 ? 0 : 1); - } - /* trivial packing inequality being redundant must never appear, - so we just ignore it */ - if (len < 2) len = 0; -done: drop_form(npp, ptr); - return len; -} - -/*********************************************************************** -* NAME -* -* npp_is_covering - test if constraint is covering inequality -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_is_covering(NPP *npp, NPPROW *row); -* -* RETURNS -* -* If the specified row (constraint) is covering inequality (see below), -* the routine npp_is_covering returns non-zero. Otherwise, it returns -* zero. -* -* COVERING INEQUALITIES -* -* In canonical format the covering inequality is the following: -* -* sum x[j] >= 1, (1) -* j in J -* -* where all variables x[j] are binary. This inequality expresses the -* condition that in any integer feasible solution variables in set J -* cannot be all equal to zero at the same time, i.e. at least one -* variable must take non-zero (unity) value. W.l.o.g. it is assumed -* that |J| >= 2, because if J is empty, the inequality (1) is -* infeasible, and if |J| = 1, the inequality (1) is a forcing row. -* -* In general case the covering inequality may include original -* variables x[j] as well as their complements x~[j]: -* -* sum x[j] + sum x~[j] >= 1, (2) -* j in Jp j in Jn -* -* where Jp and Jn are not intersected. Therefore, using substitution -* x~[j] = 1 - x[j] gives the packing inequality in generalized format: -* -* sum x[j] - sum x[j] >= 1 - |Jn|. (3) -* j in Jp j in Jn -* -* (May note that the inequality (3) cuts off infeasible solutions, -* where x[j] = 0 for all j in Jp and x[j] = 1 for all j in Jn.) -* -* NOTE: If |J| = 2, the inequality (3) is equivalent to packing -* inequality (see the routine npp_is_packing). */ - -int npp_is_covering(NPP *npp, NPPROW *row) -{ /* test if constraint is covering inequality */ - NPPCOL *col; - NPPAIJ *aij; - int b; - xassert(npp == npp); - if (!(row->lb != -DBL_MAX && row->ub == +DBL_MAX)) - return 0; - b = 1; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { col = aij->col; - if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) - return 0; - if (aij->val == +1.0) - ; - else if (aij->val == -1.0) - b--; - else - return 0; - } - if (row->lb != (double)b) return 0; - return 1; -} - -/*********************************************************************** -* NAME -* -* npp_hidden_covering - identify hidden covering inequality -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_hidden_covering(NPP *npp, NPPROW *row); -* -* DESCRIPTION -* -* The routine npp_hidden_covering processes specified inequality -* constraint, which includes only binary variables, and the number of -* the variables is not less than three. If the original inequality is -* equivalent to a covering inequality (see below), the routine -* replaces it by the equivalent inequality. If the original constraint -* is double-sided inequality, it is replaced by a pair of single-sided -* inequalities, if necessary. -* -* RETURNS -* -* If the original inequality constraint was replaced by equivalent -* covering inequality, the routine npp_hidden_covering returns -* non-zero. Otherwise, it returns zero. -* -* PROBLEM TRANSFORMATION -* -* Consider an inequality constraint: -* -* sum a[j] x[j] >= b, (1) -* j in J -* -* where all variables x[j] are binary, and |J| >= 3. (In case of '<=' -* inequality it can be transformed to '>=' format by multiplying both -* its sides by -1.) -* -* Let Jp = {j: a[j] > 0}, Jn = {j: a[j] < 0}. Performing substitution -* x[j] = 1 - x~[j] for all j in Jn, we have: -* -* sum a[j] x[j] >= b ==> -* j in J -* -* sum a[j] x[j] + sum a[j] x[j] >= b ==> -* j in Jp j in Jn -* -* sum a[j] x[j] + sum a[j] (1 - x~[j]) >= b ==> -* j in Jp j in Jn -* -* sum m a[j] x[j] - sum a[j] x~[j] >= b - sum a[j]. -* j in Jp j in Jn j in Jn -* -* Thus, meaning the transformation above, we can assume that in -* inequality (1) all coefficients a[j] are positive. Moreover, we can -* assume that b > 0, because otherwise the inequality (1) would be -* redundant (see the routine npp_analyze_row). It is then obvious that -* constraint (1) is equivalent to covering inequality only if: -* -* a[j] >= b, (2) -* -* for all j in J. -* -* Once the original inequality (1) is replaced by equivalent covering -* inequality, we need to perform back substitution x~[j] = 1 - x[j] for -* all j in Jn (see above). -* -* RECOVERING SOLUTION -* -* None needed. */ - -static int hidden_covering(NPP *npp, struct elem *ptr, double *_b) -{ /* process inequality constraint: sum a[j] x[j] >= b; - 0 - specified row is NOT hidden covering inequality; - 1 - specified row is covering inequality; - 2 - specified row is hidden covering inequality. */ - struct elem *e; - int neg; - double b = *_b, eps; - xassert(npp == npp); - /* a[j] must be non-zero, x[j] must be binary, for all j in J */ - for (e = ptr; e != NULL; e = e->next) - { xassert(e->aj != 0.0); - xassert(e->xj->is_int); - xassert(e->xj->lb == 0.0 && e->xj->ub == 1.0); - } - /* check if the specified inequality constraint already has the - form of covering inequality */ - neg = 0; /* neg is |Jn| */ - for (e = ptr; e != NULL; e = e->next) - { if (e->aj == +1.0) - ; - else if (e->aj == -1.0) - neg++; - else - break; - } - if (e == NULL) - { /* all coefficients a[j] are +1 or -1; check rhs b */ - if (b == (double)(1 - neg)) - { /* it is covering inequality; no processing is needed */ - return 1; - } - } - /* substitute x[j] = 1 - x~[j] for all j in Jn to make all a[j] - positive; the result is a~[j] = |a[j]| and new rhs b */ - for (e = ptr; e != NULL; e = e->next) - if (e->aj < 0) b -= e->aj; - /* now a[j] > 0 for all j in J (actually |a[j]| are used) */ - /* if b <= 0, skip processing--this case must not appear */ - if (b < 1e-3) return 0; - /* now a[j] > 0 for all j in J, and b > 0 */ - /* the specified constraint is equivalent to covering inequality - iff a[j] >= b for all j in J */ - eps = 1e-9 + 1e-12 * fabs(b); - for (e = ptr; e != NULL; e = e->next) - if (fabs(e->aj) < b - eps) return 0; - /* perform back substitution x~[j] = 1 - x[j] and construct the - final equivalent covering inequality in generalized format */ - b = 1.0; - for (e = ptr; e != NULL; e = e->next) - { if (e->aj > 0.0) - e->aj = +1.0; - else /* e->aj < 0.0 */ - e->aj = -1.0, b -= 1.0; - } - *_b = b; - return 2; -} - -int npp_hidden_covering(NPP *npp, NPPROW *row) -{ /* identify hidden covering inequality */ - NPPROW *copy; - NPPAIJ *aij; - struct elem *ptr, *e; - int kase, ret, count = 0; - double b; - /* the row must be inequality constraint */ - xassert(row->lb < row->ub); - for (kase = 0; kase <= 1; kase++) - { if (kase == 0) - { /* process row lower bound */ - if (row->lb == -DBL_MAX) continue; - ptr = copy_form(npp, row, +1.0); - b = + row->lb; - } - else - { /* process row upper bound */ - if (row->ub == +DBL_MAX) continue; - ptr = copy_form(npp, row, -1.0); - b = - row->ub; - } - /* now the inequality has the form "sum a[j] x[j] >= b" */ - ret = hidden_covering(npp, ptr, &b); - xassert(0 <= ret && ret <= 2); - if (kase == 1 && ret == 1 || ret == 2) - { /* the original inequality has been identified as hidden - covering inequality */ - count++; -#ifdef GLP_DEBUG - xprintf("Original constraint:\n"); - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - xprintf(" %+g x%d", aij->val, aij->col->j); - if (row->lb != -DBL_MAX) xprintf(", >= %g", row->lb); - if (row->ub != +DBL_MAX) xprintf(", <= %g", row->ub); - xprintf("\n"); - xprintf("Equivalent covering inequality:\n"); - for (e = ptr; e != NULL; e = e->next) - xprintf(" %sx%d", e->aj > 0.0 ? "+" : "-", e->xj->j); - xprintf(", >= %g\n", b); -#endif - if (row->lb == -DBL_MAX || row->ub == +DBL_MAX) - { /* the original row is single-sided inequality; no copy - is needed */ - copy = NULL; - } - else - { /* the original row is double-sided inequality; we need - to create its copy for other bound before replacing it - with the equivalent inequality */ - copy = npp_add_row(npp); - if (kase == 0) - { /* the copy is for upper bound */ - copy->lb = -DBL_MAX, copy->ub = row->ub; - } - else - { /* the copy is for lower bound */ - copy->lb = row->lb, copy->ub = +DBL_MAX; - } - /* copy original row coefficients */ - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - npp_add_aij(npp, copy, aij->col, aij->val); - } - /* replace the original inequality by equivalent one */ - npp_erase_row(npp, row); - row->lb = b, row->ub = +DBL_MAX; - for (e = ptr; e != NULL; e = e->next) - npp_add_aij(npp, row, e->xj, e->aj); - /* continue processing upper bound for the copy */ - if (copy != NULL) row = copy; - } - drop_form(npp, ptr); - } - return count; -} - -/*********************************************************************** -* NAME -* -* npp_is_partitioning - test if constraint is partitioning equality -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_is_partitioning(NPP *npp, NPPROW *row); -* -* RETURNS -* -* If the specified row (constraint) is partitioning equality (see -* below), the routine npp_is_partitioning returns non-zero. Otherwise, -* it returns zero. -* -* PARTITIONING EQUALITIES -* -* In canonical format the partitioning equality is the following: -* -* sum x[j] = 1, (1) -* j in J -* -* where all variables x[j] are binary. This equality expresses the -* condition that in any integer feasible solution exactly one variable -* in set J must take non-zero (unity) value while other variables must -* be equal to zero. W.l.o.g. it is assumed that |J| >= 2, because if -* J is empty, the inequality (1) is infeasible, and if |J| = 1, the -* inequality (1) is a fixing row. -* -* In general case the partitioning equality may include original -* variables x[j] as well as their complements x~[j]: -* -* sum x[j] + sum x~[j] = 1, (2) -* j in Jp j in Jn -* -* where Jp and Jn are not intersected. Therefore, using substitution -* x~[j] = 1 - x[j] leads to the partitioning equality in generalized -* format: -* -* sum x[j] - sum x[j] = 1 - |Jn|. (3) -* j in Jp j in Jn */ - -int npp_is_partitioning(NPP *npp, NPPROW *row) -{ /* test if constraint is partitioning equality */ - NPPCOL *col; - NPPAIJ *aij; - int b; - xassert(npp == npp); - if (row->lb != row->ub) return 0; - b = 1; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { col = aij->col; - if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) - return 0; - if (aij->val == +1.0) - ; - else if (aij->val == -1.0) - b--; - else - return 0; - } - if (row->lb != (double)b) return 0; - return 1; -} - -/*********************************************************************** -* NAME -* -* npp_reduce_ineq_coef - reduce inequality constraint coefficients -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_reduce_ineq_coef(NPP *npp, NPPROW *row); -* -* DESCRIPTION -* -* The routine npp_reduce_ineq_coef processes specified inequality -* constraint attempting to replace it by an equivalent constraint, -* where magnitude of coefficients at binary variables is smaller than -* in the original constraint. If the inequality is double-sided, it is -* replaced by a pair of single-sided inequalities, if necessary. -* -* RETURNS -* -* The routine npp_reduce_ineq_coef returns the number of coefficients -* reduced. -* -* BACKGROUND -* -* Consider an inequality constraint: -* -* sum a[j] x[j] >= b. (1) -* j in J -* -* (In case of '<=' inequality it can be transformed to '>=' format by -* multiplying both its sides by -1.) Let x[k] be a binary variable; -* other variables can be integer as well as continuous. We can write -* constraint (1) as follows: -* -* a[k] x[k] + t[k] >= b, (2) -* -* where: -* -* t[k] = sum a[j] x[j]. (3) -* j in J\{k} -* -* Since x[k] is binary, constraint (2) is equivalent to disjunction of -* the following two constraints: -* -* x[k] = 0, t[k] >= b (4) -* -* OR -* -* x[k] = 1, t[k] >= b - a[k]. (5) -* -* Let also that for the partial sum t[k] be known some its implied -* lower bound inf t[k]. -* -* Case a[k] > 0. Let inf t[k] < b, since otherwise both constraints -* (4) and (5) and therefore constraint (2) are redundant. -* If inf t[k] > b - a[k], only constraint (5) is redundant, in which -* case it can be replaced with the following redundant and therefore -* equivalent constraint: -* -* t[k] >= b - a'[k] = inf t[k], (6) -* -* where: -* -* a'[k] = b - inf t[k]. (7) -* -* Thus, the original constraint (2) is equivalent to the following -* constraint with coefficient at variable x[k] changed: -* -* a'[k] x[k] + t[k] >= b. (8) -* -* From inf t[k] < b it follows that a'[k] > 0, i.e. the coefficient -* at x[k] keeps its sign. And from inf t[k] > b - a[k] it follows that -* a'[k] < a[k], i.e. the coefficient reduces in magnitude. -* -* Case a[k] < 0. Let inf t[k] < b - a[k], since otherwise both -* constraints (4) and (5) and therefore constraint (2) are redundant. -* If inf t[k] > b, only constraint (4) is redundant, in which case it -* can be replaced with the following redundant and therefore equivalent -* constraint: -* -* t[k] >= b' = inf t[k]. (9) -* -* Rewriting constraint (5) as follows: -* -* t[k] >= b - a[k] = b' - a'[k], (10) -* -* where: -* -* a'[k] = a[k] + b' - b = a[k] + inf t[k] - b, (11) -* -* we can see that disjunction of constraint (9) and (10) is equivalent -* to disjunction of constraint (4) and (5), from which it follows that -* the original constraint (2) is equivalent to the following constraint -* with both coefficient at variable x[k] and right-hand side changed: -* -* a'[k] x[k] + t[k] >= b'. (12) -* -* From inf t[k] < b - a[k] it follows that a'[k] < 0, i.e. the -* coefficient at x[k] keeps its sign. And from inf t[k] > b it follows -* that a'[k] > a[k], i.e. the coefficient reduces in magnitude. -* -* PROBLEM TRANSFORMATION -* -* In the routine npp_reduce_ineq_coef the following implied lower -* bound of the partial sum (3) is used: -* -* inf t[k] = sum a[j] l[j] + sum a[j] u[j], (13) -* j in Jp\{k} k in Jn\{k} -* -* where Jp = {j : a[j] > 0}, Jn = {j : a[j] < 0}, l[j] and u[j] are -* lower and upper bounds, resp., of variable x[j]. -* -* In order to compute inf t[k] more efficiently, the following formula, -* which is equivalent to (13), is actually used: -* -* ( h - a[k] l[k] = h, if a[k] > 0, -* inf t[k] = < (14) -* ( h - a[k] u[k] = h - a[k], if a[k] < 0, -* -* where: -* -* h = sum a[j] l[j] + sum a[j] u[j] (15) -* j in Jp j in Jn -* -* is the implied lower bound of row (1). -* -* Reduction of positive coefficient (a[k] > 0) does not change value -* of h, since l[k] = 0. In case of reduction of negative coefficient -* (a[k] < 0) from (11) it follows that: -* -* delta a[k] = a'[k] - a[k] = inf t[k] - b (> 0), (16) -* -* so new value of h (accounting that u[k] = 1) can be computed as -* follows: -* -* h := h + delta a[k] = h + (inf t[k] - b). (17) -* -* RECOVERING SOLUTION -* -* None needed. */ - -static int reduce_ineq_coef(NPP *npp, struct elem *ptr, double *_b) -{ /* process inequality constraint: sum a[j] x[j] >= b */ - /* returns: the number of coefficients reduced */ - struct elem *e; - int count = 0; - double h, inf_t, new_a, b = *_b; - xassert(npp == npp); - /* compute h; see (15) */ - h = 0.0; - for (e = ptr; e != NULL; e = e->next) - { if (e->aj > 0.0) - { if (e->xj->lb == -DBL_MAX) goto done; - h += e->aj * e->xj->lb; - } - else /* e->aj < 0.0 */ - { if (e->xj->ub == +DBL_MAX) goto done; - h += e->aj * e->xj->ub; - } - } - /* perform reduction of coefficients at binary variables */ - for (e = ptr; e != NULL; e = e->next) - { /* skip non-binary variable */ - if (!(e->xj->is_int && e->xj->lb == 0.0 && e->xj->ub == 1.0)) - continue; - if (e->aj > 0.0) - { /* compute inf t[k]; see (14) */ - inf_t = h; - if (b - e->aj < inf_t && inf_t < b) - { /* compute reduced coefficient a'[k]; see (7) */ - new_a = b - inf_t; - if (new_a >= +1e-3 && - e->aj - new_a >= 0.01 * (1.0 + e->aj)) - { /* accept a'[k] */ -#ifdef GLP_DEBUG - xprintf("+"); -#endif - e->aj = new_a; - count++; - } - } - } - else /* e->aj < 0.0 */ - { /* compute inf t[k]; see (14) */ - inf_t = h - e->aj; - if (b < inf_t && inf_t < b - e->aj) - { /* compute reduced coefficient a'[k]; see (11) */ - new_a = e->aj + (inf_t - b); - if (new_a <= -1e-3 && - new_a - e->aj >= 0.01 * (1.0 - e->aj)) - { /* accept a'[k] */ -#ifdef GLP_DEBUG - xprintf("-"); -#endif - e->aj = new_a; - /* update h; see (17) */ - h += (inf_t - b); - /* compute b'; see (9) */ - b = inf_t; - count++; - } - } - } - } - *_b = b; -done: return count; -} - -int npp_reduce_ineq_coef(NPP *npp, NPPROW *row) -{ /* reduce inequality constraint coefficients */ - NPPROW *copy; - NPPAIJ *aij; - struct elem *ptr, *e; - int kase, count[2]; - double b; - /* the row must be inequality constraint */ - xassert(row->lb < row->ub); - count[0] = count[1] = 0; - for (kase = 0; kase <= 1; kase++) - { if (kase == 0) - { /* process row lower bound */ - if (row->lb == -DBL_MAX) continue; -#ifdef GLP_DEBUG - xprintf("L"); -#endif - ptr = copy_form(npp, row, +1.0); - b = + row->lb; - } - else - { /* process row upper bound */ - if (row->ub == +DBL_MAX) continue; -#ifdef GLP_DEBUG - xprintf("U"); -#endif - ptr = copy_form(npp, row, -1.0); - b = - row->ub; - } - /* now the inequality has the form "sum a[j] x[j] >= b" */ - count[kase] = reduce_ineq_coef(npp, ptr, &b); - if (count[kase] > 0) - { /* the original inequality has been replaced by equivalent - one with coefficients reduced */ - if (row->lb == -DBL_MAX || row->ub == +DBL_MAX) - { /* the original row is single-sided inequality; no copy - is needed */ - copy = NULL; - } - else - { /* the original row is double-sided inequality; we need - to create its copy for other bound before replacing it - with the equivalent inequality */ -#ifdef GLP_DEBUG - xprintf("*"); -#endif - copy = npp_add_row(npp); - if (kase == 0) - { /* the copy is for upper bound */ - copy->lb = -DBL_MAX, copy->ub = row->ub; - } - else - { /* the copy is for lower bound */ - copy->lb = row->lb, copy->ub = +DBL_MAX; - } - /* copy original row coefficients */ - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - npp_add_aij(npp, copy, aij->col, aij->val); - } - /* replace the original inequality by equivalent one */ - npp_erase_row(npp, row); - row->lb = b, row->ub = +DBL_MAX; - for (e = ptr; e != NULL; e = e->next) - npp_add_aij(npp, row, e->xj, e->aj); - /* continue processing upper bound for the copy */ - if (copy != NULL) row = copy; - } - drop_form(npp, ptr); - } - return count[0] + count[1]; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpnpp05.c b/resources/3rdparty/glpk-4.53/src/glpnpp05.c deleted file mode 100644 index 8c8818508..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpnpp05.c +++ /dev/null @@ -1,810 +0,0 @@ -/* glpnpp05.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpnpp.h" - -/*********************************************************************** -* NAME -* -* npp_clean_prob - perform initial LP/MIP processing -* -* SYNOPSIS -* -* #include "glpnpp.h" -* void npp_clean_prob(NPP *npp); -* -* DESCRIPTION -* -* The routine npp_clean_prob performs initial LP/MIP processing that -* currently includes: -* -* 1) removing free rows; -* -* 2) replacing double-sided constraint rows with almost identical -* bounds, by equality constraint rows; -* -* 3) removing fixed columns; -* -* 4) replacing double-bounded columns with almost identical bounds by -* fixed columns and removing those columns; -* -* 5) initial processing constraint coefficients (not implemented); -* -* 6) initial processing objective coefficients (not implemented). */ - -void npp_clean_prob(NPP *npp) -{ /* perform initial LP/MIP processing */ - NPPROW *row, *next_row; - NPPCOL *col, *next_col; - int ret; - xassert(npp == npp); - /* process rows which originally are free */ - for (row = npp->r_head; row != NULL; row = next_row) - { next_row = row->next; - if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) - { /* process free row */ -#ifdef GLP_DEBUG - xprintf("1"); -#endif - npp_free_row(npp, row); - /* row was deleted */ - } - } - /* process rows which originally are double-sided inequalities */ - for (row = npp->r_head; row != NULL; row = next_row) - { next_row = row->next; - if (row->lb != -DBL_MAX && row->ub != +DBL_MAX && - row->lb < row->ub) - { ret = npp_make_equality(npp, row); - if (ret == 0) - ; - else if (ret == 1) - { /* row was replaced by equality constraint */ -#ifdef GLP_DEBUG - xprintf("2"); -#endif - } - else - xassert(ret != ret); - } - } - /* process columns which are originally fixed */ - for (col = npp->c_head; col != NULL; col = next_col) - { next_col = col->next; - if (col->lb == col->ub) - { /* process fixed column */ -#ifdef GLP_DEBUG - xprintf("3"); -#endif - npp_fixed_col(npp, col); - /* column was deleted */ - } - } - /* process columns which are originally double-bounded */ - for (col = npp->c_head; col != NULL; col = next_col) - { next_col = col->next; - if (col->lb != -DBL_MAX && col->ub != +DBL_MAX && - col->lb < col->ub) - { ret = npp_make_fixed(npp, col); - if (ret == 0) - ; - else if (ret == 1) - { /* column was replaced by fixed column; process it */ -#ifdef GLP_DEBUG - xprintf("4"); -#endif - npp_fixed_col(npp, col); - /* column was deleted */ - } - } - } - return; -} - -/*********************************************************************** -* NAME -* -* npp_process_row - perform basic row processing -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_process_row(NPP *npp, NPPROW *row, int hard); -* -* DESCRIPTION -* -* The routine npp_process_row performs basic row processing that -* currently includes: -* -* 1) removing empty row; -* -* 2) removing equality constraint row singleton and corresponding -* column; -* -* 3) removing inequality constraint row singleton and corresponding -* column if it was fixed; -* -* 4) performing general row analysis; -* -* 5) removing redundant row bounds; -* -* 6) removing forcing row and corresponding columns; -* -* 7) removing row which becomes free due to redundant bounds; -* -* 8) computing implied bounds for all columns in the row and using -* them to strengthen current column bounds (MIP only, optional, -* performed if the flag hard is on). -* -* Additionally the routine may activate affected rows and/or columns -* for further processing. -* -* RETURNS -* -* 0 success; -* -* GLP_ENOPFS primal/integer infeasibility detected; -* -* GLP_ENODFS dual infeasibility detected. */ - -int npp_process_row(NPP *npp, NPPROW *row, int hard) -{ /* perform basic row processing */ - NPPCOL *col; - NPPAIJ *aij, *next_aij, *aaa; - int ret; - /* row must not be free */ - xassert(!(row->lb == -DBL_MAX && row->ub == +DBL_MAX)); - /* start processing row */ - if (row->ptr == NULL) - { /* empty row */ - ret = npp_empty_row(npp, row); - if (ret == 0) - { /* row was deleted */ -#ifdef GLP_DEBUG - xprintf("A"); -#endif - return 0; - } - else if (ret == 1) - { /* primal infeasibility */ - return GLP_ENOPFS; - } - else - xassert(ret != ret); - } - if (row->ptr->r_next == NULL) - { /* row singleton */ - col = row->ptr->col; - if (row->lb == row->ub) - { /* equality constraint */ - ret = npp_eq_singlet(npp, row); - if (ret == 0) - { /* column was fixed, row was deleted */ -#ifdef GLP_DEBUG - xprintf("B"); -#endif - /* activate rows affected by column */ - for (aij = col->ptr; aij != NULL; aij = aij->c_next) - npp_activate_row(npp, aij->row); - /* process fixed column */ - npp_fixed_col(npp, col); - /* column was deleted */ - return 0; - } - else if (ret == 1 || ret == 2) - { /* primal/integer infeasibility */ - return GLP_ENOPFS; - } - else - xassert(ret != ret); - } - else - { /* inequality constraint */ - ret = npp_ineq_singlet(npp, row); - if (0 <= ret && ret <= 3) - { /* row was deleted */ -#ifdef GLP_DEBUG - xprintf("C"); -#endif - /* activate column, since its length was changed due to - row deletion */ - npp_activate_col(npp, col); - if (ret >= 2) - { /* column bounds changed significantly or column was - fixed */ - /* activate rows affected by column */ - for (aij = col->ptr; aij != NULL; aij = aij->c_next) - npp_activate_row(npp, aij->row); - } - if (ret == 3) - { /* column was fixed; process it */ -#ifdef GLP_DEBUG - xprintf("D"); -#endif - npp_fixed_col(npp, col); - /* column was deleted */ - } - return 0; - } - else if (ret == 4) - { /* primal infeasibility */ - return GLP_ENOPFS; - } - else - xassert(ret != ret); - } - } -#if 0 - /* sometimes this causes too large round-off errors; probably - pivot coefficient should be chosen more carefully */ - if (row->ptr->r_next->r_next == NULL) - { /* row doubleton */ - if (row->lb == row->ub) - { /* equality constraint */ - if (!(row->ptr->col->is_int || - row->ptr->r_next->col->is_int)) - { /* both columns are continuous */ - NPPCOL *q; - q = npp_eq_doublet(npp, row); - if (q != NULL) - { /* column q was eliminated */ -#ifdef GLP_DEBUG - xprintf("E"); -#endif - /* now column q is singleton of type "implied slack - variable"; we process it here to make sure that on - recovering basic solution the row is always active - equality constraint (as required by the routine - rcv_eq_doublet) */ - xassert(npp_process_col(npp, q) == 0); - /* column q was deleted; note that row p also may be - deleted */ - return 0; - } - } - } - } -#endif - /* general row analysis */ - ret = npp_analyze_row(npp, row); - xassert(0x00 <= ret && ret <= 0xFF); - if (ret == 0x33) - { /* row bounds are inconsistent with column bounds */ - return GLP_ENOPFS; - } - if ((ret & 0x0F) == 0x00) - { /* row lower bound does not exist or redundant */ - if (row->lb != -DBL_MAX) - { /* remove redundant row lower bound */ -#ifdef GLP_DEBUG - xprintf("F"); -#endif - npp_inactive_bound(npp, row, 0); - } - } - else if ((ret & 0x0F) == 0x01) - { /* row lower bound can be active */ - /* see below */ - } - else if ((ret & 0x0F) == 0x02) - { /* row lower bound is a forcing bound */ -#ifdef GLP_DEBUG - xprintf("G"); -#endif - /* process forcing row */ - if (npp_forcing_row(npp, row, 0) == 0) -fixup: { /* columns were fixed, row was made free */ - for (aij = row->ptr; aij != NULL; aij = next_aij) - { /* process column fixed by forcing row */ -#ifdef GLP_DEBUG - xprintf("H"); -#endif - col = aij->col; - next_aij = aij->r_next; - /* activate rows affected by column */ - for (aaa = col->ptr; aaa != NULL; aaa = aaa->c_next) - npp_activate_row(npp, aaa->row); - /* process fixed column */ - npp_fixed_col(npp, col); - /* column was deleted */ - } - /* process free row (which now is empty due to deletion of - all its columns) */ - npp_free_row(npp, row); - /* row was deleted */ - return 0; - } - } - else - xassert(ret != ret); - if ((ret & 0xF0) == 0x00) - { /* row upper bound does not exist or redundant */ - if (row->ub != +DBL_MAX) - { /* remove redundant row upper bound */ -#ifdef GLP_DEBUG - xprintf("I"); -#endif - npp_inactive_bound(npp, row, 1); - } - } - else if ((ret & 0xF0) == 0x10) - { /* row upper bound can be active */ - /* see below */ - } - else if ((ret & 0xF0) == 0x20) - { /* row upper bound is a forcing bound */ -#ifdef GLP_DEBUG - xprintf("J"); -#endif - /* process forcing row */ - if (npp_forcing_row(npp, row, 1) == 0) goto fixup; - } - else - xassert(ret != ret); - if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) - { /* row became free due to redundant bounds removal */ -#ifdef GLP_DEBUG - xprintf("K"); -#endif - /* activate its columns, since their length will change due - to row deletion */ - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - npp_activate_col(npp, aij->col); - /* process free row */ - npp_free_row(npp, row); - /* row was deleted */ - return 0; - } -#if 1 /* 23/XII-2009 */ - /* row lower and/or upper bounds can be active */ - if (npp->sol == GLP_MIP && hard) - { /* improve current column bounds (optional) */ - if (npp_improve_bounds(npp, row, 1) < 0) - return GLP_ENOPFS; - } -#endif - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_improve_bounds - improve current column bounds -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_improve_bounds(NPP *npp, NPPROW *row, int flag); -* -* DESCRIPTION -* -* The routine npp_improve_bounds analyzes specified row (inequality -* or equality constraint) to determine implied column bounds and then -* uses these bounds to improve (strengthen) current column bounds. -* -* If the flag is on and current column bounds changed significantly -* or the column was fixed, the routine activate rows affected by the -* column for further processing. (This feature is intended to be used -* in the main loop of the routine npp_process_row.) -* -* NOTE: This operation can be used for MIP problem only. -* -* RETURNS -* -* The routine npp_improve_bounds returns the number of significantly -* changed bounds plus the number of column having been fixed due to -* bound improvements. However, if the routine detects primal/integer -* infeasibility, it returns a negative value. */ - -int npp_improve_bounds(NPP *npp, NPPROW *row, int flag) -{ /* improve current column bounds */ - NPPCOL *col; - NPPAIJ *aij, *next_aij, *aaa; - int kase, ret, count = 0; - double lb, ub; - xassert(npp->sol == GLP_MIP); - /* row must not be free */ - xassert(!(row->lb == -DBL_MAX && row->ub == +DBL_MAX)); - /* determine implied column bounds */ - npp_implied_bounds(npp, row); - /* and use these bounds to strengthen current column bounds */ - for (aij = row->ptr; aij != NULL; aij = next_aij) - { col = aij->col; - next_aij = aij->r_next; - for (kase = 0; kase <= 1; kase++) - { /* save current column bounds */ - lb = col->lb, ub = col->ub; - if (kase == 0) - { /* process implied column lower bound */ - if (col->ll.ll == -DBL_MAX) continue; - ret = npp_implied_lower(npp, col, col->ll.ll); - } - else - { /* process implied column upper bound */ - if (col->uu.uu == +DBL_MAX) continue; - ret = npp_implied_upper(npp, col, col->uu.uu); - } - if (ret == 0 || ret == 1) - { /* current column bounds did not change or changed, but - not significantly; restore current column bounds */ - col->lb = lb, col->ub = ub; - } - else if (ret == 2 || ret == 3) - { /* current column bounds changed significantly or column - was fixed */ -#ifdef GLP_DEBUG - xprintf("L"); -#endif - count++; - /* activate other rows affected by column, if required */ - if (flag) - { for (aaa = col->ptr; aaa != NULL; aaa = aaa->c_next) - { if (aaa->row != row) - npp_activate_row(npp, aaa->row); - } - } - if (ret == 3) - { /* process fixed column */ -#ifdef GLP_DEBUG - xprintf("M"); -#endif - npp_fixed_col(npp, col); - /* column was deleted */ - break; /* for kase */ - } - } - else if (ret == 4) - { /* primal/integer infeasibility */ - return -1; - } - else - xassert(ret != ret); - } - } - return count; -} - -/*********************************************************************** -* NAME -* -* npp_process_col - perform basic column processing -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_process_col(NPP *npp, NPPCOL *col); -* -* DESCRIPTION -* -* The routine npp_process_col performs basic column processing that -* currently includes: -* -* 1) fixing and removing empty column; -* -* 2) removing column singleton, which is implied slack variable, and -* corresponding row if it becomes free; -* -* 3) removing bounds of column, which is implied free variable, and -* replacing corresponding row by equality constraint. -* -* Additionally the routine may activate affected rows and/or columns -* for further processing. -* -* RETURNS -* -* 0 success; -* -* GLP_ENOPFS primal/integer infeasibility detected; -* -* GLP_ENODFS dual infeasibility detected. */ - -int npp_process_col(NPP *npp, NPPCOL *col) -{ /* perform basic column processing */ - NPPROW *row; - NPPAIJ *aij; - int ret; - /* column must not be fixed */ - xassert(col->lb < col->ub); - /* start processing column */ - if (col->ptr == NULL) - { /* empty column */ - ret = npp_empty_col(npp, col); - if (ret == 0) - { /* column was fixed and deleted */ -#ifdef GLP_DEBUG - xprintf("N"); -#endif - return 0; - } - else if (ret == 1) - { /* dual infeasibility */ - return GLP_ENODFS; - } - else - xassert(ret != ret); - } - if (col->ptr->c_next == NULL) - { /* column singleton */ - row = col->ptr->row; - if (row->lb == row->ub) - { /* equality constraint */ - if (!col->is_int) -slack: { /* implied slack variable */ -#ifdef GLP_DEBUG - xprintf("O"); -#endif - npp_implied_slack(npp, col); - /* column was deleted */ - if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) - { /* row became free due to implied slack variable */ -#ifdef GLP_DEBUG - xprintf("P"); -#endif - /* activate columns affected by row */ - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - npp_activate_col(npp, aij->col); - /* process free row */ - npp_free_row(npp, row); - /* row was deleted */ - } - else - { /* row became inequality constraint; activate it - since its length changed due to column deletion */ - npp_activate_row(npp, row); - } - return 0; - } - } - else - { /* inequality constraint */ - if (!col->is_int) - { ret = npp_implied_free(npp, col); - if (ret == 0) - { /* implied free variable */ -#ifdef GLP_DEBUG - xprintf("Q"); -#endif - /* column bounds were removed, row was replaced by - equality constraint */ - goto slack; - } - else if (ret == 1) - { /* column is not implied free variable, because its - lower and/or upper bounds can be active */ - } - else if (ret == 2) - { /* dual infeasibility */ - return GLP_ENODFS; - } - } - } - } - /* column still exists */ - return 0; -} - -/*********************************************************************** -* NAME -* -* npp_process_prob - perform basic LP/MIP processing -* -* SYNOPSIS -* -* #include "glpnpp.h" -* int npp_process_prob(NPP *npp, int hard); -* -* DESCRIPTION -* -* The routine npp_process_prob performs basic LP/MIP processing that -* currently includes: -* -* 1) initial LP/MIP processing (see the routine npp_clean_prob), -* -* 2) basic row processing (see the routine npp_process_row), and -* -* 3) basic column processing (see the routine npp_process_col). -* -* If the flag hard is on, the routine attempts to improve current -* column bounds multiple times within the main processing loop, in -* which case this feature may take a time. Otherwise, if the flag hard -* is off, improving column bounds is performed only once at the end of -* the main loop. (Note that this feature is used for MIP only.) -* -* The routine uses two sets: the set of active rows and the set of -* active columns. Rows/columns are marked by a flag (the field temp in -* NPPROW/NPPCOL). If the flag is non-zero, the row/column is active, -* in which case it is placed in the beginning of the row/column list; -* otherwise, if the flag is zero, the row/column is inactive, in which -* case it is placed in the end of the row/column list. If a row/column -* being currently processed may affect other rows/columns, the latters -* are activated for further processing. -* -* RETURNS -* -* 0 success; -* -* GLP_ENOPFS primal/integer infeasibility detected; -* -* GLP_ENODFS dual infeasibility detected. */ - -int npp_process_prob(NPP *npp, int hard) -{ /* perform basic LP/MIP processing */ - NPPROW *row; - NPPCOL *col; - int processing, ret; - /* perform initial LP/MIP processing */ - npp_clean_prob(npp); - /* activate all remaining rows and columns */ - for (row = npp->r_head; row != NULL; row = row->next) - row->temp = 1; - for (col = npp->c_head; col != NULL; col = col->next) - col->temp = 1; - /* main processing loop */ - processing = 1; - while (processing) - { processing = 0; - /* process all active rows */ - for (;;) - { row = npp->r_head; - if (row == NULL || !row->temp) break; - npp_deactivate_row(npp, row); - ret = npp_process_row(npp, row, hard); - if (ret != 0) goto done; - processing = 1; - } - /* process all active columns */ - for (;;) - { col = npp->c_head; - if (col == NULL || !col->temp) break; - npp_deactivate_col(npp, col); - ret = npp_process_col(npp, col); - if (ret != 0) goto done; - processing = 1; - } - } -#if 1 /* 23/XII-2009 */ - if (npp->sol == GLP_MIP && !hard) - { /* improve current column bounds (optional) */ - for (row = npp->r_head; row != NULL; row = row->next) - { if (npp_improve_bounds(npp, row, 0) < 0) - { ret = GLP_ENOPFS; - goto done; - } - } - } -#endif - /* all seems ok */ - ret = 0; -done: xassert(ret == 0 || ret == GLP_ENOPFS || ret == GLP_ENODFS); -#ifdef GLP_DEBUG - xprintf("\n"); -#endif - return ret; -} - -/**********************************************************************/ - -int npp_simplex(NPP *npp, const glp_smcp *parm) -{ /* process LP prior to applying primal/dual simplex method */ - int ret; - xassert(npp->sol == GLP_SOL); - xassert(parm == parm); - ret = npp_process_prob(npp, 0); - return ret; -} - -/**********************************************************************/ - -int npp_integer(NPP *npp, const glp_iocp *parm) -{ /* process MIP prior to applying branch-and-bound method */ - NPPROW *row, *prev_row; - NPPCOL *col; - NPPAIJ *aij; - int count, ret; - xassert(npp->sol == GLP_MIP); - xassert(parm == parm); - /*==============================================================*/ - /* perform basic MIP processing */ - ret = npp_process_prob(npp, 1); - if (ret != 0) goto done; - /*==============================================================*/ - /* binarize problem, if required */ - if (parm->binarize) - npp_binarize_prob(npp); - /*==============================================================*/ - /* identify hidden packing inequalities */ - count = 0; - /* new rows will be added to the end of the row list, so we go - from the end to beginning of the row list */ - for (row = npp->r_tail; row != NULL; row = prev_row) - { prev_row = row->prev; - /* skip free row */ - if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) continue; - /* skip equality constraint */ - if (row->lb == row->ub) continue; - /* skip row having less than two variables */ - if (row->ptr == NULL || row->ptr->r_next == NULL) continue; - /* skip row having non-binary variables */ - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { col = aij->col; - if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) - break; - } - if (aij != NULL) continue; - count += npp_hidden_packing(npp, row); - } - if (count > 0) - xprintf("%d hidden packing inequaliti(es) were detected\n", - count); - /*==============================================================*/ - /* identify hidden covering inequalities */ - count = 0; - /* new rows will be added to the end of the row list, so we go - from the end to beginning of the row list */ - for (row = npp->r_tail; row != NULL; row = prev_row) - { prev_row = row->prev; - /* skip free row */ - if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) continue; - /* skip equality constraint */ - if (row->lb == row->ub) continue; - /* skip row having less than three variables */ - if (row->ptr == NULL || row->ptr->r_next == NULL || - row->ptr->r_next->r_next == NULL) continue; - /* skip row having non-binary variables */ - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { col = aij->col; - if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) - break; - } - if (aij != NULL) continue; - count += npp_hidden_covering(npp, row); - } - if (count > 0) - xprintf("%d hidden covering inequaliti(es) were detected\n", - count); - /*==============================================================*/ - /* reduce inequality constraint coefficients */ - count = 0; - /* new rows will be added to the end of the row list, so we go - from the end to beginning of the row list */ - for (row = npp->r_tail; row != NULL; row = prev_row) - { prev_row = row->prev; - /* skip equality constraint */ - if (row->lb == row->ub) continue; - count += npp_reduce_ineq_coef(npp, row); - } - if (count > 0) - xprintf("%d constraint coefficient(s) were reduced\n", count); - /*==============================================================*/ -#ifdef GLP_DEBUG - routine(npp); -#endif - /*==============================================================*/ - /* all seems ok */ - ret = 0; -done: return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpnpp06.c b/resources/3rdparty/glpk-4.53/src/glpnpp06.c deleted file mode 100644 index 57d283ec9..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpnpp06.c +++ /dev/null @@ -1,1501 +0,0 @@ -/* glpnpp06.c (translate feasibility problem to CNF-SAT) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpnpp.h" - -/*********************************************************************** -* npp_sat_free_row - process free (unbounded) row -* -* This routine processes row p, which is free (i.e. has no finite -* bounds): -* -* -inf < sum a[p,j] x[j] < +inf. (1) -* -* The constraint (1) cannot be active and therefore it is redundant, -* so the routine simply removes it from the original problem. */ - -void npp_sat_free_row(NPP *npp, NPPROW *p) -{ /* the row should be free */ - xassert(p->lb == -DBL_MAX && p->ub == +DBL_MAX); - /* remove the row from the problem */ - npp_del_row(npp, p); - return; -} - -/*********************************************************************** -* npp_sat_fixed_col - process fixed column -* -* This routine processes column q, which is fixed: -* -* x[q] = s[q], (1) -* -* where s[q] is a fixed column value. -* -* The routine substitutes fixed value s[q] into constraint rows and -* then removes column x[q] from the original problem. -* -* Substitution of x[q] = s[q] into row i gives: -* -* L[i] <= sum a[i,j] x[j] <= U[i] ==> -* j -* -* L[i] <= sum a[i,j] x[j] + a[i,q] x[q] <= U[i] ==> -* j!=q -* -* L[i] <= sum a[i,j] x[j] + a[i,q] s[q] <= U[i] ==> -* j!=q -* -* L~[i] <= sum a[i,j] x[j] <= U~[i], -* j!=q -* -* where -* -* L~[i] = L[i] - a[i,q] s[q], (2) -* -* U~[i] = U[i] - a[i,q] s[q] (3) -* -* are, respectively, lower and upper bound of row i in the transformed -* problem. -* -* On recovering solution x[q] is assigned the value of s[q]. */ - -struct sat_fixed_col -{ /* fixed column */ - int q; - /* column reference number for variable x[q] */ - int s; - /* value, at which x[q] is fixed */ -}; - -static int rcv_sat_fixed_col(NPP *, void *); - -int npp_sat_fixed_col(NPP *npp, NPPCOL *q) -{ struct sat_fixed_col *info; - NPPROW *i; - NPPAIJ *aij; - int temp; - /* the column should be fixed */ - xassert(q->lb == q->ub); - /* create transformation stack entry */ - info = npp_push_tse(npp, - rcv_sat_fixed_col, sizeof(struct sat_fixed_col)); - info->q = q->j; - info->s = (int)q->lb; - xassert((double)info->s == q->lb); - /* substitute x[q] = s[q] into constraint rows */ - if (info->s == 0) - goto skip; - for (aij = q->ptr; aij != NULL; aij = aij->c_next) - { i = aij->row; - if (i->lb != -DBL_MAX) - { i->lb -= aij->val * (double)info->s; - temp = (int)i->lb; - if ((double)temp != i->lb) - return 1; /* integer arithmetic error */ - } - if (i->ub != +DBL_MAX) - { i->ub -= aij->val * (double)info->s; - temp = (int)i->ub; - if ((double)temp != i->ub) - return 2; /* integer arithmetic error */ - } - } -skip: /* remove the column from the problem */ - npp_del_col(npp, q); - return 0; -} - -static int rcv_sat_fixed_col(NPP *npp, void *info_) -{ struct sat_fixed_col *info = info_; - npp->c_value[info->q] = (double)info->s; - return 0; -} - -/*********************************************************************** -* npp_sat_is_bin_comb - test if row is binary combination -* -* This routine tests if the specified row is a binary combination, -* i.e. all its constraint coefficients are +1 and -1 and all variables -* are binary. If the test was passed, the routine returns non-zero, -* otherwise zero. */ - -int npp_sat_is_bin_comb(NPP *npp, NPPROW *row) -{ NPPCOL *col; - NPPAIJ *aij; - xassert(npp == npp); - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { if (!(aij->val == +1.0 || aij->val == -1.0)) - return 0; /* non-unity coefficient */ - col = aij->col; - if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) - return 0; /* non-binary column */ - } - return 1; /* test was passed */ -} - -/*********************************************************************** -* npp_sat_num_pos_coef - determine number of positive coefficients -* -* This routine returns the number of positive coefficients in the -* specified row. */ - -int npp_sat_num_pos_coef(NPP *npp, NPPROW *row) -{ NPPAIJ *aij; - int num = 0; - xassert(npp == npp); - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { if (aij->val > 0.0) - num++; - } - return num; -} - -/*********************************************************************** -* npp_sat_num_neg_coef - determine number of negative coefficients -* -* This routine returns the number of negative coefficients in the -* specified row. */ - -int npp_sat_num_neg_coef(NPP *npp, NPPROW *row) -{ NPPAIJ *aij; - int num = 0; - xassert(npp == npp); - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { if (aij->val < 0.0) - num++; - } - return num; -} - -/*********************************************************************** -* npp_sat_is_cover_ineq - test if row is covering inequality -* -* The canonical form of a covering inequality is the following: -* -* sum x[j] >= 1, (1) -* j in J -* -* where all x[j] are binary variables. -* -* In general case a covering inequality may have one of the following -* two forms: -* -* sum x[j] - sum x[j] >= 1 - |J-|, (2) -* j in J+ j in J- -* -* -* sum x[j] - sum x[j] <= |J+| - 1. (3) -* j in J+ j in J- -* -* Obviously, the inequality (2) can be transformed to the form (1) by -* substitution x[j] = 1 - x'[j] for all j in J-, where x'[j] is the -* negation of variable x[j]. And the inequality (3) can be transformed -* to (2) by multiplying both left- and right-hand sides by -1. -* -* This routine returns one of the following codes: -* -* 0, if the specified row is not a covering inequality; -* -* 1, if the specified row has the form (2); -* -* 2, if the specified row has the form (3). */ - -int npp_sat_is_cover_ineq(NPP *npp, NPPROW *row) -{ xassert(npp == npp); - if (row->lb != -DBL_MAX && row->ub == +DBL_MAX) - { /* row is inequality of '>=' type */ - if (npp_sat_is_bin_comb(npp, row)) - { /* row is a binary combination */ - if (row->lb == 1.0 - npp_sat_num_neg_coef(npp, row)) - { /* row has the form (2) */ - return 1; - } - } - } - else if (row->lb == -DBL_MAX && row->ub != +DBL_MAX) - { /* row is inequality of '<=' type */ - if (npp_sat_is_bin_comb(npp, row)) - { /* row is a binary combination */ - if (row->ub == npp_sat_num_pos_coef(npp, row) - 1.0) - { /* row has the form (3) */ - return 2; - } - } - } - /* row is not a covering inequality */ - return 0; -} - -/*********************************************************************** -* npp_sat_is_pack_ineq - test if row is packing inequality -* -* The canonical form of a packing inequality is the following: -* -* sum x[j] <= 1, (1) -* j in J -* -* where all x[j] are binary variables. -* -* In general case a packing inequality may have one of the following -* two forms: -* -* sum x[j] - sum x[j] <= 1 - |J-|, (2) -* j in J+ j in J- -* -* -* sum x[j] - sum x[j] >= |J+| - 1. (3) -* j in J+ j in J- -* -* Obviously, the inequality (2) can be transformed to the form (1) by -* substitution x[j] = 1 - x'[j] for all j in J-, where x'[j] is the -* negation of variable x[j]. And the inequality (3) can be transformed -* to (2) by multiplying both left- and right-hand sides by -1. -* -* This routine returns one of the following codes: -* -* 0, if the specified row is not a packing inequality; -* -* 1, if the specified row has the form (2); -* -* 2, if the specified row has the form (3). */ - -int npp_sat_is_pack_ineq(NPP *npp, NPPROW *row) -{ xassert(npp == npp); - if (row->lb == -DBL_MAX && row->ub != +DBL_MAX) - { /* row is inequality of '<=' type */ - if (npp_sat_is_bin_comb(npp, row)) - { /* row is a binary combination */ - if (row->ub == 1.0 - npp_sat_num_neg_coef(npp, row)) - { /* row has the form (2) */ - return 1; - } - } - } - else if (row->lb != -DBL_MAX && row->ub == +DBL_MAX) - { /* row is inequality of '>=' type */ - if (npp_sat_is_bin_comb(npp, row)) - { /* row is a binary combination */ - if (row->lb == npp_sat_num_pos_coef(npp, row) - 1.0) - { /* row has the form (3) */ - return 2; - } - } - } - /* row is not a packing inequality */ - return 0; -} - -/*********************************************************************** -* npp_sat_is_partn_eq - test if row is partitioning equality -* -* The canonical form of a partitioning equality is the following: -* -* sum x[j] = 1, (1) -* j in J -* -* where all x[j] are binary variables. -* -* In general case a partitioning equality may have one of the following -* two forms: -* -* sum x[j] - sum x[j] = 1 - |J-|, (2) -* j in J+ j in J- -* -* -* sum x[j] - sum x[j] = |J+| - 1. (3) -* j in J+ j in J- -* -* Obviously, the equality (2) can be transformed to the form (1) by -* substitution x[j] = 1 - x'[j] for all j in J-, where x'[j] is the -* negation of variable x[j]. And the equality (3) can be transformed -* to (2) by multiplying both left- and right-hand sides by -1. -* -* This routine returns one of the following codes: -* -* 0, if the specified row is not a partitioning equality; -* -* 1, if the specified row has the form (2); -* -* 2, if the specified row has the form (3). */ - -int npp_sat_is_partn_eq(NPP *npp, NPPROW *row) -{ xassert(npp == npp); - if (row->lb == row->ub) - { /* row is equality constraint */ - if (npp_sat_is_bin_comb(npp, row)) - { /* row is a binary combination */ - if (row->lb == 1.0 - npp_sat_num_neg_coef(npp, row)) - { /* row has the form (2) */ - return 1; - } - if (row->ub == npp_sat_num_pos_coef(npp, row) - 1.0) - { /* row has the form (3) */ - return 2; - } - } - } - /* row is not a partitioning equality */ - return 0; -} - -/*********************************************************************** -* npp_sat_reverse_row - multiply both sides of row by -1 -* -* This routines multiplies by -1 both left- and right-hand sides of -* the specified row: -* -* L <= sum x[j] <= U, -* -* that results in the following row: -* -* -U <= sum (-x[j]) <= -L. -* -* If no integer overflow occured, the routine returns zero, otherwise -* non-zero. */ - -int npp_sat_reverse_row(NPP *npp, NPPROW *row) -{ NPPAIJ *aij; - int temp, ret = 0; - double old_lb, old_ub; - xassert(npp == npp); - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { aij->val = -aij->val; - temp = (int)aij->val; - if ((double)temp != aij->val) - ret = 1; - } - old_lb = row->lb, old_ub = row->ub; - if (old_ub == +DBL_MAX) - row->lb = -DBL_MAX; - else - { row->lb = -old_ub; - temp = (int)row->lb; - if ((double)temp != row->lb) - ret = 2; - } - if (old_lb == -DBL_MAX) - row->ub = +DBL_MAX; - else - { row->ub = -old_lb; - temp = (int)row->ub; - if ((double)temp != row->ub) - ret = 3; - } - return ret; -} - -/*********************************************************************** -* npp_sat_split_pack - split packing inequality -* -* Let there be given a packing inequality in canonical form: -* -* sum t[j] <= 1, (1) -* j in J -* -* where t[j] = x[j] or t[j] = 1 - x[j], x[j] is a binary variable. -* And let J = J1 U J2 is a partition of the set of literals. Then the -* inequality (1) is obviously equivalent to the following two packing -* inequalities: -* -* sum t[j] <= y <--> sum t[j] + (1 - y) <= 1, (2) -* j in J1 j in J1 -* -* sum t[j] <= 1 - y <--> sum t[j] + y <= 1, (3) -* j in J2 j in J2 -* -* where y is a new binary variable added to the transformed problem. -* -* Assuming that the specified row is a packing inequality (1), this -* routine constructs the set J1 by including there first nlit literals -* (terms) from the specified row, and the set J2 = J \ J1. Then the -* routine creates a new row, which corresponds to inequality (2), and -* replaces the specified row with inequality (3). */ - -NPPROW *npp_sat_split_pack(NPP *npp, NPPROW *row, int nlit) -{ NPPROW *rrr; - NPPCOL *col; - NPPAIJ *aij; - int k; - /* original row should be packing inequality (1) */ - xassert(npp_sat_is_pack_ineq(npp, row) == 1); - /* and nlit should be less than the number of literals (terms) - in the original row */ - xassert(0 < nlit && nlit < npp_row_nnz(npp, row)); - /* create new row corresponding to inequality (2) */ - rrr = npp_add_row(npp); - rrr->lb = -DBL_MAX, rrr->ub = 1.0; - /* move first nlit literals (terms) from the original row to the - new row; the original row becomes inequality (3) */ - for (k = 1; k <= nlit; k++) - { aij = row->ptr; - xassert(aij != NULL); - /* add literal to the new row */ - npp_add_aij(npp, rrr, aij->col, aij->val); - /* correct rhs */ - if (aij->val < 0.0) - rrr->ub -= 1.0, row->ub += 1.0; - /* remove literal from the original row */ - npp_del_aij(npp, aij); - } - /* create new binary variable y */ - col = npp_add_col(npp); - col->is_int = 1, col->lb = 0.0, col->ub = 1.0; - /* include literal (1 - y) in the new row */ - npp_add_aij(npp, rrr, col, -1.0); - rrr->ub -= 1.0; - /* include literal y in the original row */ - npp_add_aij(npp, row, col, +1.0); - return rrr; -} - -/*********************************************************************** -* npp_sat_encode_pack - encode packing inequality -* -* Given a packing inequality in canonical form: -* -* sum t[j] <= 1, (1) -* j in J -* -* where t[j] = x[j] or t[j] = 1 - x[j], x[j] is a binary variable, -* this routine translates it to CNF by replacing it with the following -* equivalent set of edge packing inequalities: -* -* t[j] + t[k] <= 1 for all j, k in J, j != k. (2) -* -* Then the routine transforms each edge packing inequality (2) to -* corresponding covering inequality (that encodes two-literal clause) -* by multiplying both its part by -1: -* -* - t[j] - t[k] >= -1 <--> (1 - t[j]) + (1 - t[k]) >= 1. (3) -* -* On exit the routine removes the original row from the problem. */ - -void npp_sat_encode_pack(NPP *npp, NPPROW *row) -{ NPPROW *rrr; - NPPAIJ *aij, *aik; - /* original row should be packing inequality (1) */ - xassert(npp_sat_is_pack_ineq(npp, row) == 1); - /* create equivalent system of covering inequalities (3) */ - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { /* due to symmetry only one of inequalities t[j] + t[k] <= 1 - and t[k] <= t[j] <= 1 can be considered */ - for (aik = aij->r_next; aik != NULL; aik = aik->r_next) - { /* create edge packing inequality (2) */ - rrr = npp_add_row(npp); - rrr->lb = -DBL_MAX, rrr->ub = 1.0; - npp_add_aij(npp, rrr, aij->col, aij->val); - if (aij->val < 0.0) - rrr->ub -= 1.0; - npp_add_aij(npp, rrr, aik->col, aik->val); - if (aik->val < 0.0) - rrr->ub -= 1.0; - /* and transform it to covering inequality (3) */ - npp_sat_reverse_row(npp, rrr); - xassert(npp_sat_is_cover_ineq(npp, rrr) == 1); - } - } - /* remove the original row from the problem */ - npp_del_row(npp, row); - return; -} - -/*********************************************************************** -* npp_sat_encode_sum2 - encode 2-bit summation -* -* Given a set containing two literals x and y this routine encodes -* the equality -* -* x + y = s + 2 * c, (1) -* -* where -* -* s = (x + y) % 2 (2) -* -* is a binary variable modeling the low sum bit, and -* -* c = (x + y) / 2 (3) -* -* is a binary variable modeling the high (carry) sum bit. */ - -void npp_sat_encode_sum2(NPP *npp, NPPLSE *set, NPPSED *sed) -{ NPPROW *row; - int x, y, s, c; - /* the set should contain exactly two literals */ - xassert(set != NULL); - xassert(set->next != NULL); - xassert(set->next->next == NULL); - sed->x = set->lit; - xassert(sed->x.neg == 0 || sed->x.neg == 1); - sed->y = set->next->lit; - xassert(sed->y.neg == 0 || sed->y.neg == 1); - sed->z.col = NULL, sed->z.neg = 0; - /* perform encoding s = (x + y) % 2 */ - sed->s = npp_add_col(npp); - sed->s->is_int = 1, sed->s->lb = 0.0, sed->s->ub = 1.0; - for (x = 0; x <= 1; x++) - { for (y = 0; y <= 1; y++) - { for (s = 0; s <= 1; s++) - { if ((x + y) % 2 != s) - { /* generate CNF clause to disable infeasible - combination */ - row = npp_add_row(npp); - row->lb = 1.0, row->ub = +DBL_MAX; - if (x == sed->x.neg) - npp_add_aij(npp, row, sed->x.col, +1.0); - else - { npp_add_aij(npp, row, sed->x.col, -1.0); - row->lb -= 1.0; - } - if (y == sed->y.neg) - npp_add_aij(npp, row, sed->y.col, +1.0); - else - { npp_add_aij(npp, row, sed->y.col, -1.0); - row->lb -= 1.0; - } - if (s == 0) - npp_add_aij(npp, row, sed->s, +1.0); - else - { npp_add_aij(npp, row, sed->s, -1.0); - row->lb -= 1.0; - } - } - } - } - } - /* perform encoding c = (x + y) / 2 */ - sed->c = npp_add_col(npp); - sed->c->is_int = 1, sed->c->lb = 0.0, sed->c->ub = 1.0; - for (x = 0; x <= 1; x++) - { for (y = 0; y <= 1; y++) - { for (c = 0; c <= 1; c++) - { if ((x + y) / 2 != c) - { /* generate CNF clause to disable infeasible - combination */ - row = npp_add_row(npp); - row->lb = 1.0, row->ub = +DBL_MAX; - if (x == sed->x.neg) - npp_add_aij(npp, row, sed->x.col, +1.0); - else - { npp_add_aij(npp, row, sed->x.col, -1.0); - row->lb -= 1.0; - } - if (y == sed->y.neg) - npp_add_aij(npp, row, sed->y.col, +1.0); - else - { npp_add_aij(npp, row, sed->y.col, -1.0); - row->lb -= 1.0; - } - if (c == 0) - npp_add_aij(npp, row, sed->c, +1.0); - else - { npp_add_aij(npp, row, sed->c, -1.0); - row->lb -= 1.0; - } - } - } - } - } - return; -} - -/*********************************************************************** -* npp_sat_encode_sum3 - encode 3-bit summation -* -* Given a set containing at least three literals this routine chooses -* some literals x, y, z from that set and encodes the equality -* -* x + y + z = s + 2 * c, (1) -* -* where -* -* s = (x + y + z) % 2 (2) -* -* is a binary variable modeling the low sum bit, and -* -* c = (x + y + z) / 2 (3) -* -* is a binary variable modeling the high (carry) sum bit. */ - -void npp_sat_encode_sum3(NPP *npp, NPPLSE *set, NPPSED *sed) -{ NPPROW *row; - int x, y, z, s, c; - /* the set should contain at least three literals */ - xassert(set != NULL); - xassert(set->next != NULL); - xassert(set->next->next != NULL); - sed->x = set->lit; - xassert(sed->x.neg == 0 || sed->x.neg == 1); - sed->y = set->next->lit; - xassert(sed->y.neg == 0 || sed->y.neg == 1); - sed->z = set->next->next->lit; - xassert(sed->z.neg == 0 || sed->z.neg == 1); - /* perform encoding s = (x + y + z) % 2 */ - sed->s = npp_add_col(npp); - sed->s->is_int = 1, sed->s->lb = 0.0, sed->s->ub = 1.0; - for (x = 0; x <= 1; x++) - { for (y = 0; y <= 1; y++) - { for (z = 0; z <= 1; z++) - { for (s = 0; s <= 1; s++) - { if ((x + y + z) % 2 != s) - { /* generate CNF clause to disable infeasible - combination */ - row = npp_add_row(npp); - row->lb = 1.0, row->ub = +DBL_MAX; - if (x == sed->x.neg) - npp_add_aij(npp, row, sed->x.col, +1.0); - else - { npp_add_aij(npp, row, sed->x.col, -1.0); - row->lb -= 1.0; - } - if (y == sed->y.neg) - npp_add_aij(npp, row, sed->y.col, +1.0); - else - { npp_add_aij(npp, row, sed->y.col, -1.0); - row->lb -= 1.0; - } - if (z == sed->z.neg) - npp_add_aij(npp, row, sed->z.col, +1.0); - else - { npp_add_aij(npp, row, sed->z.col, -1.0); - row->lb -= 1.0; - } - if (s == 0) - npp_add_aij(npp, row, sed->s, +1.0); - else - { npp_add_aij(npp, row, sed->s, -1.0); - row->lb -= 1.0; - } - } - } - } - } - } - /* perform encoding c = (x + y + z) / 2 */ - sed->c = npp_add_col(npp); - sed->c->is_int = 1, sed->c->lb = 0.0, sed->c->ub = 1.0; - for (x = 0; x <= 1; x++) - { for (y = 0; y <= 1; y++) - { for (z = 0; z <= 1; z++) - { for (c = 0; c <= 1; c++) - { if ((x + y + z) / 2 != c) - { /* generate CNF clause to disable infeasible - combination */ - row = npp_add_row(npp); - row->lb = 1.0, row->ub = +DBL_MAX; - if (x == sed->x.neg) - npp_add_aij(npp, row, sed->x.col, +1.0); - else - { npp_add_aij(npp, row, sed->x.col, -1.0); - row->lb -= 1.0; - } - if (y == sed->y.neg) - npp_add_aij(npp, row, sed->y.col, +1.0); - else - { npp_add_aij(npp, row, sed->y.col, -1.0); - row->lb -= 1.0; - } - if (z == sed->z.neg) - npp_add_aij(npp, row, sed->z.col, +1.0); - else - { npp_add_aij(npp, row, sed->z.col, -1.0); - row->lb -= 1.0; - } - if (c == 0) - npp_add_aij(npp, row, sed->c, +1.0); - else - { npp_add_aij(npp, row, sed->c, -1.0); - row->lb -= 1.0; - } - } - } - } - } - } - return; -} - -/*********************************************************************** -* npp_sat_encode_sum_ax - encode linear combination of 0-1 variables -* -* PURPOSE -* -* Given a linear combination of binary variables: -* -* sum a[j] x[j], (1) -* j -* -* which is the linear form of the specified row, this routine encodes -* (i.e. translates to CNF) the following equality: -* -* n -* sum |a[j]| t[j] = sum 2**(k-1) * y[k], (2) -* j k=1 -* -* where t[j] = x[j] (if a[j] > 0) or t[j] = 1 - x[j] (if a[j] < 0), -* and y[k] is either t[j] or a new literal created by the routine or -* a constant zero. Note that the sum in the right-hand side of (2) can -* be thought as a n-bit representation of the sum in the left-hand -* side, which is a non-negative integer number. -* -* ALGORITHM -* -* First, the number of bits, n, sufficient to represent any value in -* the left-hand side of (2) is determined. Obviously, n is the number -* of bits sufficient to represent the sum (sum |a[j]|). -* -* Let -* -* n -* |a[j]| = sum 2**(k-1) b[j,k], (3) -* k=1 -* -* where b[j,k] is k-th bit in a n-bit representation of |a[j]|. Then -* -* m n -* sum |a[j]| * t[j] = sum 2**(k-1) sum b[j,k] * t[j]. (4) -* j k=1 j=1 -* -* Introducing the set -* -* J[k] = { j : b[j,k] = 1 } (5) -* -* allows rewriting (4) as follows: -* -* n -* sum |a[j]| * t[j] = sum 2**(k-1) sum t[j]. (6) -* j k=1 j in J[k] -* -* Thus, our goal is to provide |J[k]| <= 1 for all k, in which case -* we will have the representation (1). -* -* Let |J[k]| = 2, i.e. J[k] has exactly two literals u and v. In this -* case we can apply the following transformation: -* -* u + v = s + 2 * c, (7) -* -* where s and c are, respectively, low (sum) and high (carry) bits of -* the sum of two bits. This allows to replace two literals u and v in -* J[k] by one literal s, and carry out literal c to J[k+1]. -* -* If |J[k]| >= 3, i.e. J[k] has at least three literals u, v, and w, -* we can apply the following transformation: -* -* u + v + w = s + 2 * c. (8) -* -* Again, literal s replaces literals u, v, and w in J[k], and literal -* c goes into J[k+1]. -* -* On exit the routine stores each literal from J[k] in element y[k], -* 1 <= k <= n. If J[k] is empty, y[k] is set to constant false. -* -* RETURNS -* -* The routine returns n, the number of literals in the right-hand side -* of (2), 0 <= n <= NBIT_MAX. If the sum (sum |a[j]|) is too large, so -* more than NBIT_MAX (= 31) literals are needed to encode the original -* linear combination, the routine returns a negative value. */ - -#define NBIT_MAX 31 -/* maximal number of literals in the right hand-side of (2) */ - -static NPPLSE *remove_lse(NPP *npp, NPPLSE *set, NPPCOL *col) -{ /* remove specified literal from specified literal set */ - NPPLSE *lse, *prev = NULL; - for (lse = set; lse != NULL; prev = lse, lse = lse->next) - if (lse->lit.col == col) break; - xassert(lse != NULL); - if (prev == NULL) - set = lse->next; - else - prev->next = lse->next; - dmp_free_atom(npp->pool, lse, sizeof(NPPLSE)); - return set; -} - -int npp_sat_encode_sum_ax(NPP *npp, NPPROW *row, NPPLIT y[]) -{ NPPAIJ *aij; - NPPLSE *set[1+NBIT_MAX], *lse; - NPPSED sed; - int k, n, temp; - double sum; - /* compute the sum (sum |a[j]|) */ - sum = 0.0; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - sum += fabs(aij->val); - /* determine n, the number of bits in the sum */ - temp = (int)sum; - if ((double)temp != sum) - return -1; /* integer arithmetic error */ - for (n = 0; temp > 0; n++, temp >>= 1); - xassert(0 <= n && n <= NBIT_MAX); - /* build initial sets J[k], 1 <= k <= n; see (5) */ - /* set[k] is a pointer to the list of literals in J[k] */ - for (k = 1; k <= n; k++) - set[k] = NULL; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { temp = (int)fabs(aij->val); - xassert((int)temp == fabs(aij->val)); - for (k = 1; temp > 0; k++, temp >>= 1) - { if (temp & 1) - { xassert(k <= n); - lse = dmp_get_atom(npp->pool, sizeof(NPPLSE)); - lse->lit.col = aij->col; - lse->lit.neg = (aij->val > 0.0 ? 0 : 1); - lse->next = set[k]; - set[k] = lse; - } - } - } - /* main transformation loop */ - for (k = 1; k <= n; k++) - { /* reduce J[k] and set y[k] */ - for (;;) - { if (set[k] == NULL) - { /* J[k] is empty */ - /* set y[k] to constant false */ - y[k].col = NULL, y[k].neg = 0; - break; - } - if (set[k]->next == NULL) - { /* J[k] contains one literal */ - /* set y[k] to that literal */ - y[k] = set[k]->lit; - dmp_free_atom(npp->pool, set[k], sizeof(NPPLSE)); - break; - } - if (set[k]->next->next == NULL) - { /* J[k] contains two literals */ - /* apply transformation (7) */ - npp_sat_encode_sum2(npp, set[k], &sed); - } - else - { /* J[k] contains at least three literals */ - /* apply transformation (8) */ - npp_sat_encode_sum3(npp, set[k], &sed); - /* remove third literal from set[k] */ - set[k] = remove_lse(npp, set[k], sed.z.col); - } - /* remove second literal from set[k] */ - set[k] = remove_lse(npp, set[k], sed.y.col); - /* remove first literal from set[k] */ - set[k] = remove_lse(npp, set[k], sed.x.col); - /* include new literal s to set[k] */ - lse = dmp_get_atom(npp->pool, sizeof(NPPLSE)); - lse->lit.col = sed.s, lse->lit.neg = 0; - lse->next = set[k]; - set[k] = lse; - /* include new literal c to set[k+1] */ - xassert(k < n); /* FIXME: can "overflow" happen? */ - lse = dmp_get_atom(npp->pool, sizeof(NPPLSE)); - lse->lit.col = sed.c, lse->lit.neg = 0; - lse->next = set[k+1]; - set[k+1] = lse; - } - } - return n; -} - -/*********************************************************************** -* npp_sat_normalize_clause - normalize clause -* -* This routine normalizes the specified clause, which is a disjunction -* of literals, by replacing multiple literals, which refer to the same -* binary variable, with a single literal. -* -* On exit the routine returns the number of literals in the resulting -* clause. However, if the specified clause includes both a literal and -* its negation, the routine returns a negative value meaning that the -* clause is equivalent to the value true. */ - -int npp_sat_normalize_clause(NPP *npp, int size, NPPLIT lit[]) -{ int j, k, new_size; - xassert(npp == npp); - xassert(size >= 0); - new_size = 0; - for (k = 1; k <= size; k++) - { for (j = 1; j <= new_size; j++) - { if (lit[k].col == lit[j].col) - { /* lit[k] refers to the same variable as lit[j], which - is already included in the resulting clause */ - if (lit[k].neg == lit[j].neg) - { /* ignore lit[k] due to the idempotent law */ - goto skip; - } - else - { /* lit[k] is NOT lit[j]; the clause is equivalent to - the value true */ - return -1; - } - } - } - /* include lit[k] in the resulting clause */ - lit[++new_size] = lit[k]; -skip: ; - } - return new_size; -} - -/*********************************************************************** -* npp_sat_encode_clause - translate clause to cover inequality -* -* Given a clause -* -* OR t[j], (1) -* j in J -* -* where t[j] is a literal, i.e. t[j] = x[j] or t[j] = NOT x[j], this -* routine translates it to the following equivalent cover inequality, -* which is added to the transformed problem: -* -* sum t[j] >= 1, (2) -* j in J -* -* where t[j] = x[j] or t[j] = 1 - x[j]. -* -* If necessary, the clause should be normalized before a call to this -* routine. */ - -NPPROW *npp_sat_encode_clause(NPP *npp, int size, NPPLIT lit[]) -{ NPPROW *row; - int k; - xassert(size >= 1); - row = npp_add_row(npp); - row->lb = 1.0, row->ub = +DBL_MAX; - for (k = 1; k <= size; k++) - { xassert(lit[k].col != NULL); - if (lit[k].neg == 0) - npp_add_aij(npp, row, lit[k].col, +1.0); - else if (lit[k].neg == 1) - { npp_add_aij(npp, row, lit[k].col, -1.0); - row->lb -= 1.0; - } - else - xassert(lit != lit); - } - return row; -} - -/*********************************************************************** -* npp_sat_encode_geq - encode "not less than" constraint -* -* PURPOSE -* -* This routine translates to CNF the following constraint: -* -* n -* sum 2**(k-1) * y[k] >= b, (1) -* k=1 -* -* where y[k] is either a literal (i.e. y[k] = x[k] or y[k] = 1 - x[k]) -* or constant false (zero), b is a given lower bound. -* -* ALGORITHM -* -* If b < 0, the constraint is redundant, so assume that b >= 0. Let -* -* n -* b = sum 2**(k-1) b[k], (2) -* k=1 -* -* where b[k] is k-th binary digit of b. (Note that if b >= 2**n and -* therefore cannot be represented in the form (2), the constraint (1) -* is infeasible.) In this case the condition (1) is equivalent to the -* following condition: -* -* y[n] y[n-1] ... y[2] y[1] >= b[n] b[n-1] ... b[2] b[1], (3) -* -* where ">=" is understood lexicographically. -* -* Algorithmically the condition (3) can be tested as follows: -* -* for (k = n; k >= 1; k--) -* { if (y[k] < b[k]) -* y is less than b; -* if (y[k] > b[k]) -* y is greater than b; -* } -* y is equal to b; -* -* Thus, y is less than b iff there exists k, 1 <= k <= n, for which -* the following condition is satisfied: -* -* y[n] = b[n] AND ... AND y[k+1] = b[k+1] AND y[k] < b[k]. (4) -* -* Negating the condition (4) we have that y is not less than b iff for -* all k, 1 <= k <= n, the following condition is satisfied: -* -* y[n] != b[n] OR ... OR y[k+1] != b[k+1] OR y[k] >= b[k]. (5) -* -* Note that if b[k] = 0, the literal y[k] >= b[k] is always true, in -* which case the entire clause (5) is true and can be omitted. -* -* RETURNS -* -* Normally the routine returns zero. However, if the constraint (1) is -* infeasible, the routine returns non-zero. */ - -int npp_sat_encode_geq(NPP *npp, int n, NPPLIT y[], int rhs) -{ NPPLIT lit[1+NBIT_MAX]; - int j, k, size, temp, b[1+NBIT_MAX]; - xassert(0 <= n && n <= NBIT_MAX); - /* if the constraint (1) is redundant, do nothing */ - if (rhs < 0) - return 0; - /* determine binary digits of b according to (2) */ - for (k = 1, temp = rhs; k <= n; k++, temp >>= 1) - b[k] = temp & 1; - if (temp != 0) - { /* b >= 2**n; the constraint (1) is infeasible */ - return 1; - } - /* main transformation loop */ - for (k = 1; k <= n; k++) - { /* build the clause (5) for current k */ - size = 0; /* clause size = number of literals */ - /* add literal y[k] >= b[k] */ - if (b[k] == 0) - { /* b[k] = 0 -> the literal is true */ - goto skip; - } - else if (y[k].col == NULL) - { /* y[k] = 0, b[k] = 1 -> the literal is false */ - xassert(y[k].neg == 0); - } - else - { /* add literal y[k] = 1 */ - lit[++size] = y[k]; - } - for (j = k+1; j <= n; j++) - { /* add literal y[j] != b[j] */ - if (y[j].col == NULL) - { xassert(y[j].neg == 0); - if (b[j] == 0) - { /* y[j] = 0, b[j] = 0 -> the literal is false */ - continue; - } - else - { /* y[j] = 0, b[j] = 1 -> the literal is true */ - goto skip; - } - } - else - { lit[++size] = y[j]; - if (b[j] != 0) - lit[size].neg = 1 - lit[size].neg; - } - } - /* normalize the clause */ - size = npp_sat_normalize_clause(npp, size, lit); - if (size < 0) - { /* the clause is equivalent to the value true */ - goto skip; - } - if (size == 0) - { /* the clause is equivalent to the value false; this means - that the constraint (1) is infeasible */ - return 2; - } - /* translate the clause to corresponding cover inequality */ - npp_sat_encode_clause(npp, size, lit); -skip: ; - } - return 0; -} - -/*********************************************************************** -* npp_sat_encode_leq - encode "not greater than" constraint -* -* PURPOSE -* -* This routine translates to CNF the following constraint: -* -* n -* sum 2**(k-1) * y[k] <= b, (1) -* k=1 -* -* where y[k] is either a literal (i.e. y[k] = x[k] or y[k] = 1 - x[k]) -* or constant false (zero), b is a given upper bound. -* -* ALGORITHM -* -* If b < 0, the constraint is infeasible, so assume that b >= 0. Let -* -* n -* b = sum 2**(k-1) b[k], (2) -* k=1 -* -* where b[k] is k-th binary digit of b. (Note that if b >= 2**n and -* therefore cannot be represented in the form (2), the constraint (1) -* is redundant.) In this case the condition (1) is equivalent to the -* following condition: -* -* y[n] y[n-1] ... y[2] y[1] <= b[n] b[n-1] ... b[2] b[1], (3) -* -* where "<=" is understood lexicographically. -* -* Algorithmically the condition (3) can be tested as follows: -* -* for (k = n; k >= 1; k--) -* { if (y[k] < b[k]) -* y is less than b; -* if (y[k] > b[k]) -* y is greater than b; -* } -* y is equal to b; -* -* Thus, y is greater than b iff there exists k, 1 <= k <= n, for which -* the following condition is satisfied: -* -* y[n] = b[n] AND ... AND y[k+1] = b[k+1] AND y[k] > b[k]. (4) -* -* Negating the condition (4) we have that y is not greater than b iff -* for all k, 1 <= k <= n, the following condition is satisfied: -* -* y[n] != b[n] OR ... OR y[k+1] != b[k+1] OR y[k] <= b[k]. (5) -* -* Note that if b[k] = 1, the literal y[k] <= b[k] is always true, in -* which case the entire clause (5) is true and can be omitted. -* -* RETURNS -* -* Normally the routine returns zero. However, if the constraint (1) is -* infeasible, the routine returns non-zero. */ - -int npp_sat_encode_leq(NPP *npp, int n, NPPLIT y[], int rhs) -{ NPPLIT lit[1+NBIT_MAX]; - int j, k, size, temp, b[1+NBIT_MAX]; - xassert(0 <= n && n <= NBIT_MAX); - /* check if the constraint (1) is infeasible */ - if (rhs < 0) - return 1; - /* determine binary digits of b according to (2) */ - for (k = 1, temp = rhs; k <= n; k++, temp >>= 1) - b[k] = temp & 1; - if (temp != 0) - { /* b >= 2**n; the constraint (1) is redundant */ - return 0; - } - /* main transformation loop */ - for (k = 1; k <= n; k++) - { /* build the clause (5) for current k */ - size = 0; /* clause size = number of literals */ - /* add literal y[k] <= b[k] */ - if (b[k] == 1) - { /* b[k] = 1 -> the literal is true */ - goto skip; - } - else if (y[k].col == NULL) - { /* y[k] = 0, b[k] = 0 -> the literal is true */ - xassert(y[k].neg == 0); - goto skip; - } - else - { /* add literal y[k] = 0 */ - lit[++size] = y[k]; - lit[size].neg = 1 - lit[size].neg; - } - for (j = k+1; j <= n; j++) - { /* add literal y[j] != b[j] */ - if (y[j].col == NULL) - { xassert(y[j].neg == 0); - if (b[j] == 0) - { /* y[j] = 0, b[j] = 0 -> the literal is false */ - continue; - } - else - { /* y[j] = 0, b[j] = 1 -> the literal is true */ - goto skip; - } - } - else - { lit[++size] = y[j]; - if (b[j] != 0) - lit[size].neg = 1 - lit[size].neg; - } - } - /* normalize the clause */ - size = npp_sat_normalize_clause(npp, size, lit); - if (size < 0) - { /* the clause is equivalent to the value true */ - goto skip; - } - if (size == 0) - { /* the clause is equivalent to the value false; this means - that the constraint (1) is infeasible */ - return 2; - } - /* translate the clause to corresponding cover inequality */ - npp_sat_encode_clause(npp, size, lit); -skip: ; - } - return 0; -} - -/*********************************************************************** -* npp_sat_encode_row - encode constraint (row) of general type -* -* PURPOSE -* -* This routine translates to CNF the following constraint (row): -* -* L <= sum a[j] x[j] <= U, (1) -* j -* -* where all x[j] are binary variables. -* -* ALGORITHM -* -* First, the routine performs substitution x[j] = t[j] for j in J+ -* and x[j] = 1 - t[j] for j in J-, where J+ = { j : a[j] > 0 } and -* J- = { j : a[j] < 0 }. This gives: -* -* L <= sum a[j] t[j] + sum a[j] (1 - t[j]) <= U ==> -* j in J+ j in J- -* -* L' <= sum |a[j]| t[j] <= U', (2) -* j -* -* where -* -* L' = L - sum a[j], U' = U - sum a[j]. (3) -* j in J- j in J- -* -* (Actually only new bounds L' and U' are computed.) -* -* Then the routine translates to CNF the following equality: -* -* n -* sum |a[j]| t[j] = sum 2**(k-1) * y[k], (4) -* j k=1 -* -* where y[k] is either some t[j] or a new literal or a constant zero -* (see the routine npp_sat_encode_sum_ax). -* -* Finally, the routine translates to CNF the following conditions: -* -* n -* sum 2**(k-1) * y[k] >= L' (5) -* k=1 -* -* and -* -* n -* sum 2**(k-1) * y[k] <= U' (6) -* k=1 -* -* (see the routines npp_sat_encode_geq and npp_sat_encode_leq). -* -* All resulting clauses are encoded as cover inequalities and included -* into the transformed problem. -* -* Note that on exit the routine removes the specified constraint (row) -* from the original problem. -* -* RETURNS -* -* The routine returns one of the following codes: -* -* 0 - translation was successful; -* 1 - constraint (1) was found infeasible; -* 2 - integer arithmetic error occured. */ - -int npp_sat_encode_row(NPP *npp, NPPROW *row) -{ NPPAIJ *aij; - NPPLIT y[1+NBIT_MAX]; - int n, rhs; - double lb, ub; - /* the row should not be free */ - xassert(!(row->lb == -DBL_MAX && row->ub == +DBL_MAX)); - /* compute new bounds L' and U' (3) */ - lb = row->lb; - ub = row->ub; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - { if (aij->val < 0.0) - { if (lb != -DBL_MAX) - lb -= aij->val; - if (ub != -DBL_MAX) - ub -= aij->val; - } - } - /* encode the equality (4) */ - n = npp_sat_encode_sum_ax(npp, row, y); - if (n < 0) - return 2; /* integer arithmetic error */ - /* encode the condition (5) */ - if (lb != -DBL_MAX) - { rhs = (int)lb; - if ((double)rhs != lb) - return 2; /* integer arithmetic error */ - if (npp_sat_encode_geq(npp, n, y, rhs) != 0) - return 1; /* original constraint is infeasible */ - } - /* encode the condition (6) */ - if (ub != +DBL_MAX) - { rhs = (int)ub; - if ((double)rhs != ub) - return 2; /* integer arithmetic error */ - if (npp_sat_encode_leq(npp, n, y, rhs) != 0) - return 1; /* original constraint is infeasible */ - } - /* remove the specified row from the problem */ - npp_del_row(npp, row); - return 0; -} - -/*********************************************************************** -* npp_sat_encode_prob - encode 0-1 feasibility problem -* -* This routine translates the specified 0-1 feasibility problem to an -* equivalent SAT-CNF problem. -* -* N.B. Currently this is a very crude implementation. -* -* RETURNS -* -* 0 success; -* -* GLP_ENOPFS primal/integer infeasibility detected; -* -* GLP_ERANGE integer overflow occured. */ - -int npp_sat_encode_prob(NPP *npp) -{ NPPROW *row, *next_row, *prev_row; - NPPCOL *col, *next_col; - int cover = 0, pack = 0, partn = 0, ret; - /* process and remove free rows */ - for (row = npp->r_head; row != NULL; row = next_row) - { next_row = row->next; - if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) - npp_sat_free_row(npp, row); - } - /* process and remove fixed columns */ - for (col = npp->c_head; col != NULL; col = next_col) - { next_col = col->next; - if (col->lb == col->ub) - xassert(npp_sat_fixed_col(npp, col) == 0); - } - /* only binary variables should remain */ - for (col = npp->c_head; col != NULL; col = col->next) - xassert(col->is_int && col->lb == 0.0 && col->ub == 1.0); - /* new rows may be added to the end of the row list, so we walk - from the end to beginning of the list */ - for (row = npp->r_tail; row != NULL; row = prev_row) - { prev_row = row->prev; - /* process special cases */ - ret = npp_sat_is_cover_ineq(npp, row); - if (ret != 0) - { /* row is covering inequality */ - cover++; - /* since it already encodes a clause, just transform it to - canonical form */ - if (ret == 2) - { xassert(npp_sat_reverse_row(npp, row) == 0); - ret = npp_sat_is_cover_ineq(npp, row); - } - xassert(ret == 1); - continue; - } - ret = npp_sat_is_partn_eq(npp, row); - if (ret != 0) - { /* row is partitioning equality */ - NPPROW *cov; - NPPAIJ *aij; - partn++; - /* transform it to canonical form */ - if (ret == 2) - { xassert(npp_sat_reverse_row(npp, row) == 0); - ret = npp_sat_is_partn_eq(npp, row); - } - xassert(ret == 1); - /* and split it into covering and packing inequalities, - both in canonical forms */ - cov = npp_add_row(npp); - cov->lb = row->lb, cov->ub = +DBL_MAX; - for (aij = row->ptr; aij != NULL; aij = aij->r_next) - npp_add_aij(npp, cov, aij->col, aij->val); - xassert(npp_sat_is_cover_ineq(npp, cov) == 1); - /* the cover inequality already encodes a clause and do - not need any further processing */ - row->lb = -DBL_MAX; - xassert(npp_sat_is_pack_ineq(npp, row) == 1); - /* the packing inequality will be processed below */ - pack--; - } - ret = npp_sat_is_pack_ineq(npp, row); - if (ret != 0) - { /* row is packing inequality */ - NPPROW *rrr; - int nlit, desired_nlit = 4; - pack++; - /* transform it to canonical form */ - if (ret == 2) - { xassert(npp_sat_reverse_row(npp, row) == 0); - ret = npp_sat_is_pack_ineq(npp, row); - } - xassert(ret == 1); - /* process the packing inequality */ - for (;;) - { /* determine the number of literals in the remaining - inequality */ - nlit = npp_row_nnz(npp, row); - if (nlit <= desired_nlit) - break; - /* split the current inequality into one having not more - than desired_nlit literals and remaining one */ - rrr = npp_sat_split_pack(npp, row, desired_nlit-1); - /* translate the former inequality to CNF and remove it - from the original problem */ - npp_sat_encode_pack(npp, rrr); - } - /* translate the remaining inequality to CNF and remove it - from the original problem */ - npp_sat_encode_pack(npp, row); - continue; - } - /* translate row of general type to CNF and remove it from the - original problem */ - ret = npp_sat_encode_row(npp, row); - if (ret == 0) - ; - else if (ret == 1) - ret = GLP_ENOPFS; - else if (ret == 2) - ret = GLP_ERANGE; - else - xassert(ret != ret); - if (ret != 0) - goto done; - } - ret = 0; - if (cover != 0) - xprintf("%d covering inequalities\n", cover); - if (pack != 0) - xprintf("%d packing inequalities\n", pack); - if (partn != 0) - xprintf("%d partitioning equalities\n", partn); -done: return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glprgr.c b/resources/3rdparty/glpk-4.53/src/glprgr.c deleted file mode 100644 index 382a932ca..000000000 --- a/resources/3rdparty/glpk-4.53/src/glprgr.c +++ /dev/null @@ -1,165 +0,0 @@ -/* glprgr.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#define _GLPSTD_ERRNO -#define _GLPSTD_STDIO -#include "env.h" -#include "glprgr.h" -#define xfault xerror - -/*********************************************************************** -* NAME -* -* rgr_write_bmp16 - write 16-color raster image in BMP file format -* -* SYNOPSIS -* -* #include "glprgr.h" -* int rgr_write_bmp16(const char *fname, int m, int n, const char -* map[]); -* -* DESCRIPTION -* -* The routine rgr_write_bmp16 writes 16-color raster image in -* uncompressed BMP file format (Windows bitmap) to a binary file whose -* name is specified by the character string fname. -* -* The parameters m and n specify, respectively, the number of rows and -* the numbers of columns (i.e. height and width) of the raster image. -* -* The character array map has m*n elements. Elements map[0, ..., n-1] -* correspond to the first (top) scanline, elements map[n, ..., 2*n-1] -* correspond to the second scanline, etc. -* -* Each element of the array map specifies a color of the corresponding -* pixel as 8-bit binary number XXXXIRGB, where four high-order bits (X) -* are ignored, I is high intensity bit, R is red color bit, G is green -* color bit, and B is blue color bit. Thus, all 16 possible colors are -* coded as following hexadecimal numbers: -* -* 0x00 = black 0x08 = dark gray -* 0x01 = blue 0x09 = bright blue -* 0x02 = green 0x0A = bright green -* 0x03 = cyan 0x0B = bright cyan -* 0x04 = red 0x0C = bright red -* 0x05 = magenta 0x0D = bright magenta -* 0x06 = brown 0x0E = yellow -* 0x07 = light gray 0x0F = white -* -* RETURNS -* -* If no error occured, the routine returns zero; otherwise, it prints -* an appropriate error message and returns non-zero. */ - -static void put_byte(FILE *fp, int c) -{ fputc(c, fp); - return; -} - -static void put_word(FILE *fp, int w) -{ /* big endian */ - put_byte(fp, w); - put_byte(fp, w >> 8); - return; -} - -static void put_dword(FILE *fp, int d) -{ /* big endian */ - put_word(fp, d); - put_word(fp, d >> 16); - return; -} - -int rgr_write_bmp16(const char *fname, int m, int n, const char map[]) -{ FILE *fp; - int offset, bmsize, i, j, b, ret = 0; - if (!(1 <= m && m <= 32767)) - xfault("rgr_write_bmp16: m = %d; invalid height\n", m); - if (!(1 <= n && n <= 32767)) - xfault("rgr_write_bmp16: n = %d; invalid width\n", n); - fp = fopen(fname, "wb"); - if (fp == NULL) - { xprintf("rgr_write_bmp16: unable to create `%s' - %s\n", - fname, strerror(errno)); - ret = 1; - goto fini; - } - offset = 14 + 40 + 16 * 4; - bmsize = (4 * n + 31) / 32; - /* struct BMPFILEHEADER (14 bytes) */ - /* UINT bfType */ put_byte(fp, 'B'), put_byte(fp, 'M'); - /* DWORD bfSize */ put_dword(fp, offset + bmsize * 4); - /* UINT bfReserved1 */ put_word(fp, 0); - /* UNIT bfReserved2 */ put_word(fp, 0); - /* DWORD bfOffBits */ put_dword(fp, offset); - /* struct BMPINFOHEADER (40 bytes) */ - /* DWORD biSize */ put_dword(fp, 40); - /* LONG biWidth */ put_dword(fp, n); - /* LONG biHeight */ put_dword(fp, m); - /* WORD biPlanes */ put_word(fp, 1); - /* WORD biBitCount */ put_word(fp, 4); - /* DWORD biCompression */ put_dword(fp, 0 /* BI_RGB */); - /* DWORD biSizeImage */ put_dword(fp, 0); - /* LONG biXPelsPerMeter */ put_dword(fp, 2953 /* 75 dpi */); - /* LONG biYPelsPerMeter */ put_dword(fp, 2953 /* 75 dpi */); - /* DWORD biClrUsed */ put_dword(fp, 0); - /* DWORD biClrImportant */ put_dword(fp, 0); - /* struct RGBQUAD (16 * 4 = 64 bytes) */ - /* CGA-compatible colors: */ - /* 0x00 = black */ put_dword(fp, 0x000000); - /* 0x01 = blue */ put_dword(fp, 0x000080); - /* 0x02 = green */ put_dword(fp, 0x008000); - /* 0x03 = cyan */ put_dword(fp, 0x008080); - /* 0x04 = red */ put_dword(fp, 0x800000); - /* 0x05 = magenta */ put_dword(fp, 0x800080); - /* 0x06 = brown */ put_dword(fp, 0x808000); - /* 0x07 = light gray */ put_dword(fp, 0xC0C0C0); - /* 0x08 = dark gray */ put_dword(fp, 0x808080); - /* 0x09 = bright blue */ put_dword(fp, 0x0000FF); - /* 0x0A = bright green */ put_dword(fp, 0x00FF00); - /* 0x0B = bright cyan */ put_dword(fp, 0x00FFFF); - /* 0x0C = bright red */ put_dword(fp, 0xFF0000); - /* 0x0D = bright magenta */ put_dword(fp, 0xFF00FF); - /* 0x0E = yellow */ put_dword(fp, 0xFFFF00); - /* 0x0F = white */ put_dword(fp, 0xFFFFFF); - /* pixel data bits */ - b = 0; - for (i = m - 1; i >= 0; i--) - { for (j = 0; j < ((n + 7) / 8) * 8; j++) - { b <<= 4; - b |= (j < n ? map[i * n + j] & 15 : 0); - if (j & 1) put_byte(fp, b); - } - } - fflush(fp); - if (ferror(fp)) - { xprintf("rgr_write_bmp16: write error on `%s' - %s\n", - fname, strerror(errno)); - ret = 1; - } -fini: if (fp != NULL) fclose(fp); - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glprgr.h b/resources/3rdparty/glpk-4.53/src/glprgr.h deleted file mode 100644 index 71e089e91..000000000 --- a/resources/3rdparty/glpk-4.53/src/glprgr.h +++ /dev/null @@ -1,34 +0,0 @@ -/* glprgr.h (raster graphics) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPRGR_H -#define GLPRGR_H - -#define rgr_write_bmp16 _glp_rgr_write_bmp16 -int rgr_write_bmp16(const char *fname, int m, int n, const char map[]); -/* write 16-color raster image in BMP file format */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpscl.c b/resources/3rdparty/glpk-4.53/src/glpscl.c deleted file mode 100644 index de769a8b1..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpscl.c +++ /dev/null @@ -1,478 +0,0 @@ -/* glpscl.c (problem scaling routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "misc.h" -#include "prob.h" - -/*********************************************************************** -* min_row_aij - determine minimal |a[i,j]| in i-th row -* -* This routine returns minimal magnitude of (non-zero) constraint -* coefficients in i-th row of the constraint matrix. -* -* If the parameter scaled is zero, the original constraint matrix A is -* assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. -* -* If i-th row of the matrix is empty, the routine returns 1. */ - -static double min_row_aij(glp_prob *lp, int i, int scaled) -{ GLPAIJ *aij; - double min_aij, temp; - xassert(1 <= i && i <= lp->m); - min_aij = 1.0; - for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) - { temp = fabs(aij->val); - if (scaled) temp *= (aij->row->rii * aij->col->sjj); - if (aij->r_prev == NULL || min_aij > temp) - min_aij = temp; - } - return min_aij; -} - -/*********************************************************************** -* max_row_aij - determine maximal |a[i,j]| in i-th row -* -* This routine returns maximal magnitude of (non-zero) constraint -* coefficients in i-th row of the constraint matrix. -* -* If the parameter scaled is zero, the original constraint matrix A is -* assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. -* -* If i-th row of the matrix is empty, the routine returns 1. */ - -static double max_row_aij(glp_prob *lp, int i, int scaled) -{ GLPAIJ *aij; - double max_aij, temp; - xassert(1 <= i && i <= lp->m); - max_aij = 1.0; - for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) - { temp = fabs(aij->val); - if (scaled) temp *= (aij->row->rii * aij->col->sjj); - if (aij->r_prev == NULL || max_aij < temp) - max_aij = temp; - } - return max_aij; -} - -/*********************************************************************** -* min_col_aij - determine minimal |a[i,j]| in j-th column -* -* This routine returns minimal magnitude of (non-zero) constraint -* coefficients in j-th column of the constraint matrix. -* -* If the parameter scaled is zero, the original constraint matrix A is -* assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. -* -* If j-th column of the matrix is empty, the routine returns 1. */ - -static double min_col_aij(glp_prob *lp, int j, int scaled) -{ GLPAIJ *aij; - double min_aij, temp; - xassert(1 <= j && j <= lp->n); - min_aij = 1.0; - for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next) - { temp = fabs(aij->val); - if (scaled) temp *= (aij->row->rii * aij->col->sjj); - if (aij->c_prev == NULL || min_aij > temp) - min_aij = temp; - } - return min_aij; -} - -/*********************************************************************** -* max_col_aij - determine maximal |a[i,j]| in j-th column -* -* This routine returns maximal magnitude of (non-zero) constraint -* coefficients in j-th column of the constraint matrix. -* -* If the parameter scaled is zero, the original constraint matrix A is -* assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. -* -* If j-th column of the matrix is empty, the routine returns 1. */ - -static double max_col_aij(glp_prob *lp, int j, int scaled) -{ GLPAIJ *aij; - double max_aij, temp; - xassert(1 <= j && j <= lp->n); - max_aij = 1.0; - for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next) - { temp = fabs(aij->val); - if (scaled) temp *= (aij->row->rii * aij->col->sjj); - if (aij->c_prev == NULL || max_aij < temp) - max_aij = temp; - } - return max_aij; -} - -/*********************************************************************** -* min_mat_aij - determine minimal |a[i,j]| in constraint matrix -* -* This routine returns minimal magnitude of (non-zero) constraint -* coefficients in the constraint matrix. -* -* If the parameter scaled is zero, the original constraint matrix A is -* assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. -* -* If the matrix is empty, the routine returns 1. */ - -static double min_mat_aij(glp_prob *lp, int scaled) -{ int i; - double min_aij, temp; - min_aij = 1.0; - for (i = 1; i <= lp->m; i++) - { temp = min_row_aij(lp, i, scaled); - if (i == 1 || min_aij > temp) - min_aij = temp; - } - return min_aij; -} - -/*********************************************************************** -* max_mat_aij - determine maximal |a[i,j]| in constraint matrix -* -* This routine returns maximal magnitude of (non-zero) constraint -* coefficients in the constraint matrix. -* -* If the parameter scaled is zero, the original constraint matrix A is -* assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. -* -* If the matrix is empty, the routine returns 1. */ - -static double max_mat_aij(glp_prob *lp, int scaled) -{ int i; - double max_aij, temp; - max_aij = 1.0; - for (i = 1; i <= lp->m; i++) - { temp = max_row_aij(lp, i, scaled); - if (i == 1 || max_aij < temp) - max_aij = temp; - } - return max_aij; -} - -/*********************************************************************** -* eq_scaling - perform equilibration scaling -* -* This routine performs equilibration scaling of rows and columns of -* the constraint matrix. -* -* If the parameter flag is zero, the routine scales rows at first and -* then columns. Otherwise, the routine scales columns and then rows. -* -* Rows are scaled as follows: -* -* n -* a'[i,j] = a[i,j] / max |a[i,j]|, i = 1,...,m. -* j=1 -* -* This makes the infinity (maximum) norm of each row of the matrix -* equal to 1. -* -* Columns are scaled as follows: -* -* m -* a'[i,j] = a[i,j] / max |a[i,j]|, j = 1,...,n. -* i=1 -* -* This makes the infinity (maximum) norm of each column of the matrix -* equal to 1. */ - -static void eq_scaling(glp_prob *lp, int flag) -{ int i, j, pass; - double temp; - xassert(flag == 0 || flag == 1); - for (pass = 0; pass <= 1; pass++) - { if (pass == flag) - { /* scale rows */ - for (i = 1; i <= lp->m; i++) - { temp = max_row_aij(lp, i, 1); - glp_set_rii(lp, i, glp_get_rii(lp, i) / temp); - } - } - else - { /* scale columns */ - for (j = 1; j <= lp->n; j++) - { temp = max_col_aij(lp, j, 1); - glp_set_sjj(lp, j, glp_get_sjj(lp, j) / temp); - } - } - } - return; -} - -/*********************************************************************** -* gm_scaling - perform geometric mean scaling -* -* This routine performs geometric mean scaling of rows and columns of -* the constraint matrix. -* -* If the parameter flag is zero, the routine scales rows at first and -* then columns. Otherwise, the routine scales columns and then rows. -* -* Rows are scaled as follows: -* -* a'[i,j] = a[i,j] / sqrt(alfa[i] * beta[i]), i = 1,...,m, -* -* where: -* n n -* alfa[i] = min |a[i,j]|, beta[i] = max |a[i,j]|. -* j=1 j=1 -* -* This allows decreasing the ratio beta[i] / alfa[i] for each row of -* the matrix. -* -* Columns are scaled as follows: -* -* a'[i,j] = a[i,j] / sqrt(alfa[j] * beta[j]), j = 1,...,n, -* -* where: -* m m -* alfa[j] = min |a[i,j]|, beta[j] = max |a[i,j]|. -* i=1 i=1 -* -* This allows decreasing the ratio beta[j] / alfa[j] for each column -* of the matrix. */ - -static void gm_scaling(glp_prob *lp, int flag) -{ int i, j, pass; - double temp; - xassert(flag == 0 || flag == 1); - for (pass = 0; pass <= 1; pass++) - { if (pass == flag) - { /* scale rows */ - for (i = 1; i <= lp->m; i++) - { temp = min_row_aij(lp, i, 1) * max_row_aij(lp, i, 1); - glp_set_rii(lp, i, glp_get_rii(lp, i) / sqrt(temp)); - } - } - else - { /* scale columns */ - for (j = 1; j <= lp->n; j++) - { temp = min_col_aij(lp, j, 1) * max_col_aij(lp, j, 1); - glp_set_sjj(lp, j, glp_get_sjj(lp, j) / sqrt(temp)); - } - } - } - return; -} - -/*********************************************************************** -* max_row_ratio - determine worst scaling "quality" for rows -* -* This routine returns the worst scaling "quality" for rows of the -* currently scaled constraint matrix: -* -* m -* ratio = max ratio[i], -* i=1 -* where: -* n n -* ratio[i] = max |a[i,j]| / min |a[i,j]|, 1 <= i <= m, -* j=1 j=1 -* -* is the scaling "quality" of i-th row. */ - -static double max_row_ratio(glp_prob *lp) -{ int i; - double ratio, temp; - ratio = 1.0; - for (i = 1; i <= lp->m; i++) - { temp = max_row_aij(lp, i, 1) / min_row_aij(lp, i, 1); - if (i == 1 || ratio < temp) ratio = temp; - } - return ratio; -} - -/*********************************************************************** -* max_col_ratio - determine worst scaling "quality" for columns -* -* This routine returns the worst scaling "quality" for columns of the -* currently scaled constraint matrix: -* -* n -* ratio = max ratio[j], -* j=1 -* where: -* m m -* ratio[j] = max |a[i,j]| / min |a[i,j]|, 1 <= j <= n, -* i=1 i=1 -* -* is the scaling "quality" of j-th column. */ - -static double max_col_ratio(glp_prob *lp) -{ int j; - double ratio, temp; - ratio = 1.0; - for (j = 1; j <= lp->n; j++) - { temp = max_col_aij(lp, j, 1) / min_col_aij(lp, j, 1); - if (j == 1 || ratio < temp) ratio = temp; - } - return ratio; -} - -/*********************************************************************** -* gm_iterate - perform iterative geometric mean scaling -* -* This routine performs iterative geometric mean scaling of rows and -* columns of the constraint matrix. -* -* The parameter it_max specifies the maximal number of iterations. -* Recommended value of it_max is 15. -* -* The parameter tau specifies a minimal improvement of the scaling -* "quality" on each iteration, 0 < tau < 1. It means than the scaling -* process continues while the following condition is satisfied: -* -* ratio[k] <= tau * ratio[k-1], -* -* where ratio = max |a[i,j]| / min |a[i,j]| is the scaling "quality" -* to be minimized, k is the iteration number. Recommended value of tau -* is 0.90. */ - -static void gm_iterate(glp_prob *lp, int it_max, double tau) -{ int k, flag; - double ratio = 0.0, r_old; - /* if the scaling "quality" for rows is better than for columns, - the rows are scaled first; otherwise, the columns are scaled - first */ - flag = (max_row_ratio(lp) > max_col_ratio(lp)); - for (k = 1; k <= it_max; k++) - { /* save the scaling "quality" from previous iteration */ - r_old = ratio; - /* determine the current scaling "quality" */ - ratio = max_mat_aij(lp, 1) / min_mat_aij(lp, 1); -#if 0 - xprintf("k = %d; ratio = %g\n", k, ratio); -#endif - /* if improvement is not enough, terminate scaling */ - if (k > 1 && ratio > tau * r_old) break; - /* otherwise, perform another iteration */ - gm_scaling(lp, flag); - } - return; -} - -/*********************************************************************** -* NAME -* -* scale_prob - scale problem data -* -* SYNOPSIS -* -* #include "glpscl.h" -* void scale_prob(glp_prob *lp, int flags); -* -* DESCRIPTION -* -* The routine scale_prob performs automatic scaling of problem data -* for the specified problem object. */ - -static void scale_prob(glp_prob *lp, int flags) -{ static const char *fmt = - "%s: min|aij| = %10.3e max|aij| = %10.3e ratio = %10.3e\n"; - double min_aij, max_aij, ratio; - xprintf("Scaling...\n"); - /* cancel the current scaling effect */ - glp_unscale_prob(lp); - /* report original scaling "quality" */ - min_aij = min_mat_aij(lp, 1); - max_aij = max_mat_aij(lp, 1); - ratio = max_aij / min_aij; - xprintf(fmt, " A", min_aij, max_aij, ratio); - /* check if the problem is well scaled */ - if (min_aij >= 0.10 && max_aij <= 10.0) - { xprintf("Problem data seem to be well scaled\n"); - /* skip scaling, if required */ - if (flags & GLP_SF_SKIP) goto done; - } - /* perform iterative geometric mean scaling, if required */ - if (flags & GLP_SF_GM) - { gm_iterate(lp, 15, 0.90); - min_aij = min_mat_aij(lp, 1); - max_aij = max_mat_aij(lp, 1); - ratio = max_aij / min_aij; - xprintf(fmt, "GM", min_aij, max_aij, ratio); - } - /* perform equilibration scaling, if required */ - if (flags & GLP_SF_EQ) - { eq_scaling(lp, max_row_ratio(lp) > max_col_ratio(lp)); - min_aij = min_mat_aij(lp, 1); - max_aij = max_mat_aij(lp, 1); - ratio = max_aij / min_aij; - xprintf(fmt, "EQ", min_aij, max_aij, ratio); - } - /* round scale factors to nearest power of two, if required */ - if (flags & GLP_SF_2N) - { int i, j; - for (i = 1; i <= lp->m; i++) - glp_set_rii(lp, i, round2n(glp_get_rii(lp, i))); - for (j = 1; j <= lp->n; j++) - glp_set_sjj(lp, j, round2n(glp_get_sjj(lp, j))); - min_aij = min_mat_aij(lp, 1); - max_aij = max_mat_aij(lp, 1); - ratio = max_aij / min_aij; - xprintf(fmt, "2N", min_aij, max_aij, ratio); - } -done: return; -} - -/*********************************************************************** -* NAME -* -* glp_scale_prob - scale problem data -* -* SYNOPSIS -* -* void glp_scale_prob(glp_prob *lp, int flags); -* -* DESCRIPTION -* -* The routine glp_scale_prob performs automatic scaling of problem -* data for the specified problem object. -* -* The parameter flags specifies scaling options used by the routine. -* Options can be combined with the bitwise OR operator and may be the -* following: -* -* GLP_SF_GM perform geometric mean scaling; -* GLP_SF_EQ perform equilibration scaling; -* GLP_SF_2N round scale factors to nearest power of two; -* GLP_SF_SKIP skip scaling, if the problem is well scaled. -* -* The parameter flags may be specified as GLP_SF_AUTO, in which case -* the routine chooses scaling options automatically. */ - -void glp_scale_prob(glp_prob *lp, int flags) -{ if (flags & ~(GLP_SF_GM | GLP_SF_EQ | GLP_SF_2N | GLP_SF_SKIP | - GLP_SF_AUTO)) - xerror("glp_scale_prob: flags = 0x%02X; invalid scaling option" - "s\n", flags); - if (flags & GLP_SF_AUTO) - flags = (GLP_SF_GM | GLP_SF_EQ | GLP_SF_SKIP); - scale_prob(lp, flags); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpsdf.c b/resources/3rdparty/glpk-4.53/src/glpsdf.c deleted file mode 100644 index bd167f2dd..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpsdf.c +++ /dev/null @@ -1,259 +0,0 @@ -/* glpsdf.c (plain data file reading routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpsdf.h" -#include "misc.h" - -struct glp_data -{ /* plain data file */ - char *fname; - /* name of data file */ - glp_file *fp; - /* stream assigned to data file */ - void *jump; /* jmp_buf jump; */ - /* label for go to in case of error */ - int count; - /* line count */ - int c; - /* current character of EOF */ - char item[255+1]; - /* current data item */ -}; - -static void next_char(glp_data *data); - -glp_data *glp_sdf_open_file(const char *fname) -{ /* open plain data file */ - glp_data *data = NULL; - glp_file *fp; - jmp_buf jump; - fp = glp_open(fname, "r"); - if (fp == NULL) - { xprintf("Unable to open `%s' - %s\n", fname, get_err_msg()); - goto done; - } - data = xmalloc(sizeof(glp_data)); - data->fname = xmalloc(strlen(fname)+1); - strcpy(data->fname, fname); - data->fp = fp; - data->jump = NULL; - data->count = 0; - data->c = '\n'; - data->item[0] = '\0'; - /* read the very first character */ - if (setjmp(jump)) - { glp_sdf_close_file(data); - data = NULL; - goto done; - } - data->jump = jump; - next_char(data); - data->jump = NULL; -done: return data; -} - -void glp_sdf_set_jump(glp_data *data, void *jump) -{ /* set up error handling */ - data->jump = jump; - return; -} - -void glp_sdf_error(glp_data *data, const char *fmt, ...) -{ /* print error message */ - va_list arg; - xprintf("%s:%d: ", data->fname, data->count); - va_start(arg, fmt); - xvprintf(fmt, arg); - va_end(arg); - if (data->jump == NULL) - xerror(""); - else - longjmp(data->jump, 1); - /* no return */ -} - -void glp_sdf_warning(glp_data *data, const char *fmt, ...) -{ /* print warning message */ - va_list arg; - xprintf("%s:%d: warning: ", data->fname, data->count); - va_start(arg, fmt); - xvprintf(fmt, arg); - va_end(arg); - return; -} - -static void next_char(glp_data *data) -{ /* read next character */ - int c; - if (data->c == EOF) - glp_sdf_error(data, "unexpected end of file\n"); - else if (data->c == '\n') - data->count++; - c = glp_getc(data->fp); - if (c < 0) - { if (glp_ioerr(data->fp)) - glp_sdf_error(data, "read error - %s\n", get_err_msg()); - else if (data->c == '\n') - c = EOF; - else - { glp_sdf_warning(data, "missing final end of line\n"); - c = '\n'; - } - } - else if (c == '\n') - ; - else if (isspace(c)) - c = ' '; - else if (iscntrl(c)) - glp_sdf_error(data, "invalid control character 0x%02X\n", c); - data->c = c; - return; -} - -static void skip_pad(glp_data *data) -{ /* skip uninteresting characters and comments */ -loop: while (data->c == ' ' || data->c == '\n') - next_char(data); - if (data->c == '/') - { next_char(data); - if (data->c != '*') - glp_sdf_error(data, "invalid use of slash\n"); - next_char(data); - for (;;) - { if (data->c == '*') - { next_char(data); - if (data->c == '/') - { next_char(data); - break; - } - } - next_char(data); - } - goto loop; - } - return; -} - -static void next_item(glp_data *data) -{ /* read next item */ - int len; - skip_pad(data); - len = 0; - while (!(data->c == ' ' || data->c == '\n')) - { data->item[len++] = (char)data->c; - if (len == sizeof(data->item)) - glp_sdf_error(data, "data item `%.31s...' too long\n", - data->item); - next_char(data); - } - data->item[len] = '\0'; - return; -} - -int glp_sdf_read_int(glp_data *data) -{ /* read integer number */ - int x; - next_item(data); - switch (str2int(data->item, &x)) - { case 0: - break; - case 1: - glp_sdf_error(data, "integer `%s' out of range\n", - data->item); - case 2: - glp_sdf_error(data, "cannot convert `%s' to integer\n", - data->item); - default: - xassert(data != data); - } - return x; -} - -double glp_sdf_read_num(glp_data *data) -{ /* read floating-point number */ - double x; - next_item(data); - switch (str2num(data->item, &x)) - { case 0: - break; - case 1: - glp_sdf_error(data, "number `%s' out of range\n", - data->item); - case 2: - glp_sdf_error(data, "cannot convert `%s' to number\n", - data->item); - default: - xassert(data != data); - } - return x; -} - -const char *glp_sdf_read_item(glp_data *data) -{ /* read data item */ - next_item(data); - return data->item; -} - -const char *glp_sdf_read_text(glp_data *data) -{ /* read text until end of line */ - int c, len = 0; - for (;;) - { c = data->c; - next_char(data); - if (c == ' ') - { /* ignore initial spaces */ - if (len == 0) continue; - /* and multiple ones */ - if (data->item[len-1] == ' ') continue; - } - else if (c == '\n') - { /* remove trailing space */ - if (len > 0 && data->item[len-1] == ' ') len--; - /* and stop reading */ - break; - } - /* add current character to the buffer */ - data->item[len++] = (char)c; - if (len == sizeof(data->item)) - glp_sdf_error(data, "line too long\n", data->item); - } - data->item[len] = '\0'; - return data->item; -} - -int glp_sdf_line(glp_data *data) -{ /* determine current line number */ - return data->count; -} - -void glp_sdf_close_file(glp_data *data) -{ /* close plain data file */ - glp_close(data->fp); - xfree(data->fname); - xfree(data); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpsdf.h b/resources/3rdparty/glpk-4.53/src/glpsdf.h deleted file mode 100644 index d327a1033..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpsdf.h +++ /dev/null @@ -1,63 +0,0 @@ -/* glpsdf.h */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPSDF_H -#define GLPSDF_H - -typedef struct glp_data glp_data; -/* plain data file */ - -glp_data *glp_sdf_open_file(const char *fname); -/* open plain data file */ - -void glp_sdf_set_jump(glp_data *data, void *jump); -/* set up error handling */ - -void glp_sdf_error(glp_data *data, const char *fmt, ...); -/* print error message */ - -void glp_sdf_warning(glp_data *data, const char *fmt, ...); -/* print warning message */ - -int glp_sdf_read_int(glp_data *data); -/* read integer number */ - -double glp_sdf_read_num(glp_data *data); -/* read floating-point number */ - -const char *glp_sdf_read_item(glp_data *data); -/* read data item */ - -const char *glp_sdf_read_text(glp_data *data); -/* read text until end of line */ - -int glp_sdf_line(glp_data *data); -/* determine current line number */ - -void glp_sdf_close_file(glp_data *data); -/* close plain data file */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpspm.c b/resources/3rdparty/glpk-4.53/src/glpspm.c deleted file mode 100644 index c05b3ac18..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpspm.c +++ /dev/null @@ -1,847 +0,0 @@ -/* glpspm.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "glphbm.h" -#include "glprgr.h" -#include "glpspm.h" -#include "env.h" - -/*********************************************************************** -* NAME -* -* spm_create_mat - create general sparse matrix -* -* SYNOPSIS -* -* #include "glpspm.h" -* SPM *spm_create_mat(int m, int n); -* -* DESCRIPTION -* -* The routine spm_create_mat creates a general sparse matrix having -* m rows and n columns. Being created the matrix is zero (empty), i.e. -* has no elements. -* -* RETURNS -* -* The routine returns a pointer to the matrix created. */ - -SPM *spm_create_mat(int m, int n) -{ SPM *A; - xassert(0 <= m && m < INT_MAX); - xassert(0 <= n && n < INT_MAX); - A = xmalloc(sizeof(SPM)); - A->m = m; - A->n = n; - if (m == 0 || n == 0) - { A->pool = NULL; - A->row = NULL; - A->col = NULL; - } - else - { int i, j; - A->pool = dmp_create_pool(); - A->row = xcalloc(1+m, sizeof(SPME *)); - for (i = 1; i <= m; i++) A->row[i] = NULL; - A->col = xcalloc(1+n, sizeof(SPME *)); - for (j = 1; j <= n; j++) A->col[j] = NULL; - } - return A; -} - -/*********************************************************************** -* NAME -* -* spm_new_elem - add new element to sparse matrix -* -* SYNOPSIS -* -* #include "glpspm.h" -* SPME *spm_new_elem(SPM *A, int i, int j, double val); -* -* DESCRIPTION -* -* The routine spm_new_elem adds a new element to the specified sparse -* matrix. Parameters i, j, and val specify the row number, the column -* number, and a numerical value of the element, respectively. -* -* RETURNS -* -* The routine returns a pointer to the new element added. */ - -SPME *spm_new_elem(SPM *A, int i, int j, double val) -{ SPME *e; - xassert(1 <= i && i <= A->m); - xassert(1 <= j && j <= A->n); - e = dmp_get_atom(A->pool, sizeof(SPME)); - e->i = i; - e->j = j; - e->val = val; - e->r_prev = NULL; - e->r_next = A->row[i]; - if (e->r_next != NULL) e->r_next->r_prev = e; - e->c_prev = NULL; - e->c_next = A->col[j]; - if (e->c_next != NULL) e->c_next->c_prev = e; - A->row[i] = A->col[j] = e; - return e; -} - -/*********************************************************************** -* NAME -* -* spm_delete_mat - delete general sparse matrix -* -* SYNOPSIS -* -* #include "glpspm.h" -* void spm_delete_mat(SPM *A); -* -* DESCRIPTION -* -* The routine deletes the specified general sparse matrix freeing all -* the memory allocated to this object. */ - -void spm_delete_mat(SPM *A) -{ /* delete sparse matrix */ - if (A->pool != NULL) dmp_delete_pool(A->pool); - if (A->row != NULL) xfree(A->row); - if (A->col != NULL) xfree(A->col); - xfree(A); - return; -} - -/*********************************************************************** -* NAME -* -* spm_test_mat_e - create test sparse matrix of E(n,c) class -* -* SYNOPSIS -* -* #include "glpspm.h" -* SPM *spm_test_mat_e(int n, int c); -* -* DESCRIPTION -* -* The routine spm_test_mat_e creates a test sparse matrix of E(n,c) -* class as described in the book: Ole 0sterby, Zahari Zlatev. Direct -* Methods for Sparse Matrices. Springer-Verlag, 1983. -* -* Matrix of E(n,c) class is a symmetric positive definite matrix of -* the order n. It has the number 4 on its main diagonal and the number -* -1 on its four co-diagonals, two of which are neighbour to the main -* diagonal and two others are shifted from the main diagonal on the -* distance c. -* -* It is necessary that n >= 3 and 2 <= c <= n-1. -* -* RETURNS -* -* The routine returns a pointer to the matrix created. */ - -SPM *spm_test_mat_e(int n, int c) -{ SPM *A; - int i; - xassert(n >= 3 && 2 <= c && c <= n-1); - A = spm_create_mat(n, n); - for (i = 1; i <= n; i++) - spm_new_elem(A, i, i, 4.0); - for (i = 1; i <= n-1; i++) - { spm_new_elem(A, i, i+1, -1.0); - spm_new_elem(A, i+1, i, -1.0); - } - for (i = 1; i <= n-c; i++) - { spm_new_elem(A, i, i+c, -1.0); - spm_new_elem(A, i+c, i, -1.0); - } - return A; -} - -/*********************************************************************** -* NAME -* -* spm_test_mat_d - create test sparse matrix of D(n,c) class -* -* SYNOPSIS -* -* #include "glpspm.h" -* SPM *spm_test_mat_d(int n, int c); -* -* DESCRIPTION -* -* The routine spm_test_mat_d creates a test sparse matrix of D(n,c) -* class as described in the book: Ole 0sterby, Zahari Zlatev. Direct -* Methods for Sparse Matrices. Springer-Verlag, 1983. -* -* Matrix of D(n,c) class is a non-singular matrix of the order n. It -* has unity main diagonal, three co-diagonals above the main diagonal -* on the distance c, which are cyclically continued below the main -* diagonal, and a triangle block of the size 10x10 in the upper right -* corner. -* -* It is necessary that n >= 14 and 1 <= c <= n-13. -* -* RETURNS -* -* The routine returns a pointer to the matrix created. */ - -SPM *spm_test_mat_d(int n, int c) -{ SPM *A; - int i, j; - xassert(n >= 14 && 1 <= c && c <= n-13); - A = spm_create_mat(n, n); - for (i = 1; i <= n; i++) - spm_new_elem(A, i, i, 1.0); - for (i = 1; i <= n-c; i++) - spm_new_elem(A, i, i+c, (double)(i+1)); - for (i = n-c+1; i <= n; i++) - spm_new_elem(A, i, i-n+c, (double)(i+1)); - for (i = 1; i <= n-c-1; i++) - spm_new_elem(A, i, i+c+1, (double)(-i)); - for (i = n-c; i <= n; i++) - spm_new_elem(A, i, i-n+c+1, (double)(-i)); - for (i = 1; i <= n-c-2; i++) - spm_new_elem(A, i, i+c+2, 16.0); - for (i = n-c-1; i <= n; i++) - spm_new_elem(A, i, i-n+c+2, 16.0); - for (j = 1; j <= 10; j++) - for (i = 1; i <= 11-j; i++) - spm_new_elem(A, i, n-11+i+j, 100.0 * (double)j); - return A; -} - -/*********************************************************************** -* NAME -* -* spm_show_mat - write sparse matrix pattern in BMP file format -* -* SYNOPSIS -* -* #include "glpspm.h" -* int spm_show_mat(const SPM *A, const char *fname); -* -* DESCRIPTION -* -* The routine spm_show_mat writes pattern of the specified sparse -* matrix in uncompressed BMP file format (Windows bitmap) to a binary -* file whose name is specified by the character string fname. -* -* Each pixel corresponds to one matrix element. The pixel colors have -* the following meaning: -* -* Black structurally zero element -* White positive element -* Cyan negative element -* Green zero element -* Red duplicate element -* -* RETURNS -* -* If no error occured, the routine returns zero. Otherwise, it prints -* an appropriate error message and returns non-zero. */ - -int spm_show_mat(const SPM *A, const char *fname) -{ int m = A->m; - int n = A->n; - int i, j, k, ret; - char *map; - xprintf("spm_show_mat: writing matrix pattern to `%s'...\n", - fname); - xassert(1 <= m && m <= 32767); - xassert(1 <= n && n <= 32767); - map = xmalloc(m * n); - memset(map, 0x08, m * n); - for (i = 1; i <= m; i++) - { SPME *e; - for (e = A->row[i]; e != NULL; e = e->r_next) - { j = e->j; - xassert(1 <= j && j <= n); - k = n * (i - 1) + (j - 1); - if (map[k] != 0x08) - map[k] = 0x0C; - else if (e->val > 0.0) - map[k] = 0x0F; - else if (e->val < 0.0) - map[k] = 0x0B; - else - map[k] = 0x0A; - } - } - ret = rgr_write_bmp16(fname, m, n, map); - xfree(map); - return ret; -} - -/*********************************************************************** -* NAME -* -* spm_read_hbm - read sparse matrix in Harwell-Boeing format -* -* SYNOPSIS -* -* #include "glpspm.h" -* SPM *spm_read_hbm(const char *fname); -* -* DESCRIPTION -* -* The routine spm_read_hbm reads a sparse matrix in the Harwell-Boeing -* format from a text file whose name is the character string fname. -* -* Detailed description of the Harwell-Boeing format recognised by this -* routine can be found in the following report: -* -* I.S.Duff, R.G.Grimes, J.G.Lewis. User's Guide for the Harwell-Boeing -* Sparse Matrix Collection (Release I), TR/PA/92/86, October 1992. -* -* NOTE -* -* The routine spm_read_hbm reads the matrix "as is", due to which zero -* and/or duplicate elements can appear in the matrix. -* -* RETURNS -* -* If no error occured, the routine returns a pointer to the matrix -* created. Otherwise, the routine prints an appropriate error message -* and returns NULL. */ - -SPM *spm_read_hbm(const char *fname) -{ SPM *A = NULL; - HBM *hbm; - int nrow, ncol, nnzero, i, j, beg, end, ptr, *colptr, *rowind; - double val, *values; - char *mxtype; - hbm = hbm_read_mat(fname); - if (hbm == NULL) - { xprintf("spm_read_hbm: unable to read matrix\n"); - goto fini; - } - mxtype = hbm->mxtype; - nrow = hbm->nrow; - ncol = hbm->ncol; - nnzero = hbm->nnzero; - colptr = hbm->colptr; - rowind = hbm->rowind; - values = hbm->values; - if (!(strcmp(mxtype, "RSA") == 0 || strcmp(mxtype, "PSA") == 0 || - strcmp(mxtype, "RUA") == 0 || strcmp(mxtype, "PUA") == 0 || - strcmp(mxtype, "RRA") == 0 || strcmp(mxtype, "PRA") == 0)) - { xprintf("spm_read_hbm: matrix type `%s' not supported\n", - mxtype); - goto fini; - } - A = spm_create_mat(nrow, ncol); - if (mxtype[1] == 'S' || mxtype[1] == 'U') - xassert(nrow == ncol); - for (j = 1; j <= ncol; j++) - { beg = colptr[j]; - end = colptr[j+1]; - xassert(1 <= beg && beg <= end && end <= nnzero + 1); - for (ptr = beg; ptr < end; ptr++) - { i = rowind[ptr]; - xassert(1 <= i && i <= nrow); - if (mxtype[0] == 'R') - val = values[ptr]; - else - val = 1.0; - spm_new_elem(A, i, j, val); - if (mxtype[1] == 'S' && i != j) - spm_new_elem(A, j, i, val); - } - } -fini: if (hbm != NULL) hbm_free_mat(hbm); - return A; -} - -/*********************************************************************** -* NAME -* -* spm_count_nnz - determine number of non-zeros in sparse matrix -* -* SYNOPSIS -* -* #include "glpspm.h" -* int spm_count_nnz(const SPM *A); -* -* RETURNS -* -* The routine spm_count_nnz returns the number of structural non-zero -* elements in the specified sparse matrix. */ - -int spm_count_nnz(const SPM *A) -{ SPME *e; - int i, nnz = 0; - for (i = 1; i <= A->m; i++) - for (e = A->row[i]; e != NULL; e = e->r_next) nnz++; - return nnz; -} - -/*********************************************************************** -* NAME -* -* spm_drop_zeros - remove zero elements from sparse matrix -* -* SYNOPSIS -* -* #include "glpspm.h" -* int spm_drop_zeros(SPM *A, double eps); -* -* DESCRIPTION -* -* The routine spm_drop_zeros removes all elements from the specified -* sparse matrix, whose absolute value is less than eps. -* -* If the parameter eps is 0, only zero elements are removed from the -* matrix. -* -* RETURNS -* -* The routine returns the number of elements removed. */ - -int spm_drop_zeros(SPM *A, double eps) -{ SPME *e, *next; - int i, count = 0; - for (i = 1; i <= A->m; i++) - { for (e = A->row[i]; e != NULL; e = next) - { next = e->r_next; - if (e->val == 0.0 || fabs(e->val) < eps) - { /* remove element from the row list */ - if (e->r_prev == NULL) - A->row[e->i] = e->r_next; - else - e->r_prev->r_next = e->r_next; - if (e->r_next == NULL) - ; - else - e->r_next->r_prev = e->r_prev; - /* remove element from the column list */ - if (e->c_prev == NULL) - A->col[e->j] = e->c_next; - else - e->c_prev->c_next = e->c_next; - if (e->c_next == NULL) - ; - else - e->c_next->c_prev = e->c_prev; - /* return element to the memory pool */ - dmp_free_atom(A->pool, e, sizeof(SPME)); - count++; - } - } - } - return count; -} - -/*********************************************************************** -* NAME -* -* spm_read_mat - read sparse matrix from text file -* -* SYNOPSIS -* -* #include "glpspm.h" -* SPM *spm_read_mat(const char *fname); -* -* DESCRIPTION -* -* The routine reads a sparse matrix from a text file whose name is -* specified by the parameter fname. -* -* For the file format see description of the routine spm_write_mat. -* -* RETURNS -* -* On success the routine returns a pointer to the matrix created, -* otherwise NULL. */ - -#if 1 -SPM *spm_read_mat(const char *fname) -{ xassert(fname != fname); - return NULL; -} -#else -SPM *spm_read_mat(const char *fname) -{ SPM *A = NULL; - PDS *pds; - jmp_buf jump; - int i, j, k, m, n, nnz, fail = 0; - double val; - xprintf("spm_read_mat: reading matrix from `%s'...\n", fname); - pds = pds_open_file(fname); - if (pds == NULL) - { xprintf("spm_read_mat: unable to open `%s' - %s\n", fname, - strerror(errno)); - fail = 1; - goto done; - } - if (setjmp(jump)) - { fail = 1; - goto done; - } - pds_set_jump(pds, jump); - /* number of rows, number of columns, number of non-zeros */ - m = pds_scan_int(pds); - if (m < 0) - pds_error(pds, "invalid number of rows\n"); - n = pds_scan_int(pds); - if (n < 0) - pds_error(pds, "invalid number of columns\n"); - nnz = pds_scan_int(pds); - if (nnz < 0) - pds_error(pds, "invalid number of non-zeros\n"); - /* create matrix */ - xprintf("spm_read_mat: %d rows, %d columns, %d non-zeros\n", - m, n, nnz); - A = spm_create_mat(m, n); - /* read matrix elements */ - for (k = 1; k <= nnz; k++) - { /* row index, column index, element value */ - i = pds_scan_int(pds); - if (!(1 <= i && i <= m)) - pds_error(pds, "row index out of range\n"); - j = pds_scan_int(pds); - if (!(1 <= j && j <= n)) - pds_error(pds, "column index out of range\n"); - val = pds_scan_num(pds); - /* add new element to the matrix */ - spm_new_elem(A, i, j, val); - } - xprintf("spm_read_mat: %d lines were read\n", pds->count); -done: if (pds != NULL) pds_close_file(pds); - if (fail && A != NULL) spm_delete_mat(A), A = NULL; - return A; -} -#endif - -/*********************************************************************** -* NAME -* -* spm_write_mat - write sparse matrix to text file -* -* SYNOPSIS -* -* #include "glpspm.h" -* int spm_write_mat(const SPM *A, const char *fname); -* -* DESCRIPTION -* -* The routine spm_write_mat writes the specified sparse matrix to a -* text file whose name is specified by the parameter fname. This file -* can be read back with the routine spm_read_mat. -* -* RETURNS -* -* On success the routine returns zero, otherwise non-zero. -* -* FILE FORMAT -* -* The file created by the routine spm_write_mat is a plain text file, -* which contains the following information: -* -* m n nnz -* row[1] col[1] val[1] -* row[2] col[2] val[2] -* . . . -* row[nnz] col[nnz] val[nnz] -* -* where: -* m is the number of rows; -* n is the number of columns; -* nnz is the number of non-zeros; -* row[k], k = 1,...,nnz, are row indices; -* col[k], k = 1,...,nnz, are column indices; -* val[k], k = 1,...,nnz, are element values. */ - -#if 1 -int spm_write_mat(const SPM *A, const char *fname) -{ xassert(A != A); - xassert(fname != fname); - return 0; -} -#else -int spm_write_mat(const SPM *A, const char *fname) -{ FILE *fp; - int i, nnz, ret = 0; - xprintf("spm_write_mat: writing matrix to `%s'...\n", fname); - fp = fopen(fname, "w"); - if (fp == NULL) - { xprintf("spm_write_mat: unable to create `%s' - %s\n", fname, - strerror(errno)); - ret = 1; - goto done; - } - /* number of rows, number of columns, number of non-zeros */ - nnz = spm_count_nnz(A); - fprintf(fp, "%d %d %d\n", A->m, A->n, nnz); - /* walk through rows of the matrix */ - for (i = 1; i <= A->m; i++) - { SPME *e; - /* walk through elements of i-th row */ - for (e = A->row[i]; e != NULL; e = e->r_next) - { /* row index, column index, element value */ - fprintf(fp, "%d %d %.*g\n", e->i, e->j, DBL_DIG, e->val); - } - } - fflush(fp); - if (ferror(fp)) - { xprintf("spm_write_mat: writing error on `%s' - %s\n", fname, - strerror(errno)); - ret = 1; - goto done; - } - xprintf("spm_write_mat: %d lines were written\n", 1 + nnz); -done: if (fp != NULL) fclose(fp); - return ret; -} -#endif - -/*********************************************************************** -* NAME -* -* spm_transpose - transpose sparse matrix -* -* SYNOPSIS -* -* #include "glpspm.h" -* SPM *spm_transpose(const SPM *A); -* -* RETURNS -* -* The routine computes and returns sparse matrix B, which is a matrix -* transposed to sparse matrix A. */ - -SPM *spm_transpose(const SPM *A) -{ SPM *B; - int i; - B = spm_create_mat(A->n, A->m); - for (i = 1; i <= A->m; i++) - { SPME *e; - for (e = A->row[i]; e != NULL; e = e->r_next) - spm_new_elem(B, e->j, i, e->val); - } - return B; -} - -SPM *spm_add_sym(const SPM *A, const SPM *B) -{ /* add two sparse matrices (symbolic phase) */ - SPM *C; - int i, j, *flag; - xassert(A->m == B->m); - xassert(A->n == B->n); - /* create resultant matrix */ - C = spm_create_mat(A->m, A->n); - /* allocate and clear the flag array */ - flag = xcalloc(1+C->n, sizeof(int)); - for (j = 1; j <= C->n; j++) - flag[j] = 0; - /* compute pattern of C = A + B */ - for (i = 1; i <= C->m; i++) - { SPME *e; - /* at the beginning i-th row of C is empty */ - /* (i-th row of C) := (i-th row of C) union (i-th row of A) */ - for (e = A->row[i]; e != NULL; e = e->r_next) - { /* (note that i-th row of A may have duplicate elements) */ - j = e->j; - if (!flag[j]) - { spm_new_elem(C, i, j, 0.0); - flag[j] = 1; - } - } - /* (i-th row of C) := (i-th row of C) union (i-th row of B) */ - for (e = B->row[i]; e != NULL; e = e->r_next) - { /* (note that i-th row of B may have duplicate elements) */ - j = e->j; - if (!flag[j]) - { spm_new_elem(C, i, j, 0.0); - flag[j] = 1; - } - } - /* reset the flag array */ - for (e = C->row[i]; e != NULL; e = e->r_next) - flag[e->j] = 0; - } - /* check and deallocate the flag array */ - for (j = 1; j <= C->n; j++) - xassert(!flag[j]); - xfree(flag); - return C; -} - -void spm_add_num(SPM *C, double alfa, const SPM *A, double beta, - const SPM *B) -{ /* add two sparse matrices (numeric phase) */ - int i, j; - double *work; - /* allocate and clear the working array */ - work = xcalloc(1+C->n, sizeof(double)); - for (j = 1; j <= C->n; j++) - work[j] = 0.0; - /* compute matrix C = alfa * A + beta * B */ - for (i = 1; i <= C->n; i++) - { SPME *e; - /* work := alfa * (i-th row of A) + beta * (i-th row of B) */ - /* (note that A and/or B may have duplicate elements) */ - for (e = A->row[i]; e != NULL; e = e->r_next) - work[e->j] += alfa * e->val; - for (e = B->row[i]; e != NULL; e = e->r_next) - work[e->j] += beta * e->val; - /* (i-th row of C) := work, work := 0 */ - for (e = C->row[i]; e != NULL; e = e->r_next) - { j = e->j; - e->val = work[j]; - work[j] = 0.0; - } - } - /* check and deallocate the working array */ - for (j = 1; j <= C->n; j++) - xassert(work[j] == 0.0); - xfree(work); - return; -} - -SPM *spm_add_mat(double alfa, const SPM *A, double beta, const SPM *B) -{ /* add two sparse matrices (driver routine) */ - SPM *C; - C = spm_add_sym(A, B); - spm_add_num(C, alfa, A, beta, B); - return C; -} - -SPM *spm_mul_sym(const SPM *A, const SPM *B) -{ /* multiply two sparse matrices (symbolic phase) */ - int i, j, k, *flag; - SPM *C; - xassert(A->n == B->m); - /* create resultant matrix */ - C = spm_create_mat(A->m, B->n); - /* allocate and clear the flag array */ - flag = xcalloc(1+C->n, sizeof(int)); - for (j = 1; j <= C->n; j++) - flag[j] = 0; - /* compute pattern of C = A * B */ - for (i = 1; i <= C->m; i++) - { SPME *e, *ee; - /* compute pattern of i-th row of C */ - for (e = A->row[i]; e != NULL; e = e->r_next) - { k = e->j; - for (ee = B->row[k]; ee != NULL; ee = ee->r_next) - { j = ee->j; - /* if a[i,k] != 0 and b[k,j] != 0 then c[i,j] != 0 */ - if (!flag[j]) - { /* c[i,j] does not exist, so create it */ - spm_new_elem(C, i, j, 0.0); - flag[j] = 1; - } - } - } - /* reset the flag array */ - for (e = C->row[i]; e != NULL; e = e->r_next) - flag[e->j] = 0; - } - /* check and deallocate the flag array */ - for (j = 1; j <= C->n; j++) - xassert(!flag[j]); - xfree(flag); - return C; -} - -void spm_mul_num(SPM *C, const SPM *A, const SPM *B) -{ /* multiply two sparse matrices (numeric phase) */ - int i, j; - double *work; - /* allocate and clear the working array */ - work = xcalloc(1+A->n, sizeof(double)); - for (j = 1; j <= A->n; j++) - work[j] = 0.0; - /* compute matrix C = A * B */ - for (i = 1; i <= C->m; i++) - { SPME *e, *ee; - double temp; - /* work := (i-th row of A) */ - /* (note that A may have duplicate elements) */ - for (e = A->row[i]; e != NULL; e = e->r_next) - work[e->j] += e->val; - /* compute i-th row of C */ - for (e = C->row[i]; e != NULL; e = e->r_next) - { j = e->j; - /* c[i,j] := work * (j-th column of B) */ - temp = 0.0; - for (ee = B->col[j]; ee != NULL; ee = ee->c_next) - temp += work[ee->i] * ee->val; - e->val = temp; - } - /* reset the working array */ - for (e = A->row[i]; e != NULL; e = e->r_next) - work[e->j] = 0.0; - } - /* check and deallocate the working array */ - for (j = 1; j <= A->n; j++) - xassert(work[j] == 0.0); - xfree(work); - return; -} - -SPM *spm_mul_mat(const SPM *A, const SPM *B) -{ /* multiply two sparse matrices (driver routine) */ - SPM *C; - C = spm_mul_sym(A, B); - spm_mul_num(C, A, B); - return C; -} - -PER *spm_create_per(int n) -{ /* create permutation matrix */ - PER *P; - int k; - xassert(n >= 0); - P = xmalloc(sizeof(PER)); - P->n = n; - P->row = xcalloc(1+n, sizeof(int)); - P->col = xcalloc(1+n, sizeof(int)); - /* initially it is identity matrix */ - for (k = 1; k <= n; k++) - P->row[k] = P->col[k] = k; - return P; -} - -void spm_check_per(PER *P) -{ /* check permutation matrix for correctness */ - int i, j; - xassert(P->n >= 0); - for (i = 1; i <= P->n; i++) - { j = P->row[i]; - xassert(1 <= j && j <= P->n); - xassert(P->col[j] == i); - } - return; -} - -void spm_delete_per(PER *P) -{ /* delete permutation matrix */ - xfree(P->row); - xfree(P->col); - xfree(P); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpspm.h b/resources/3rdparty/glpk-4.53/src/glpspm.h deleted file mode 100644 index eda9f98f2..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpspm.h +++ /dev/null @@ -1,165 +0,0 @@ -/* glpspm.h (general sparse matrix) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPSPM_H -#define GLPSPM_H - -#include "dmp.h" - -typedef struct SPM SPM; -typedef struct SPME SPME; - -struct SPM -{ /* general sparse matrix */ - int m; - /* number of rows, m >= 0 */ - int n; - /* number of columns, n >= 0 */ - DMP *pool; - /* memory pool to store matrix elements */ - SPME **row; /* SPME *row[1+m]; */ - /* row[i], 1 <= i <= m, is a pointer to i-th row list */ - SPME **col; /* SPME *col[1+n]; */ - /* col[j], 1 <= j <= n, is a pointer to j-th column list */ -}; - -struct SPME -{ /* sparse matrix element */ - int i; - /* row number */ - int j; - /* column number */ - double val; - /* element value */ - SPME *r_prev; - /* pointer to previous element in the same row */ - SPME *r_next; - /* pointer to next element in the same row */ - SPME *c_prev; - /* pointer to previous element in the same column */ - SPME *c_next; - /* pointer to next element in the same column */ -}; - -typedef struct PER PER; - -struct PER -{ /* permutation matrix */ - int n; - /* matrix order, n >= 0 */ - int *row; /* int row[1+n]; */ - /* row[i] = j means p[i,j] = 1 */ - int *col; /* int col[1+n]; */ - /* col[j] = i means p[i,j] = 1 */ -}; - -#define spm_create_mat _glp_spm_create_mat -SPM *spm_create_mat(int m, int n); -/* create general sparse matrix */ - -#define spm_new_elem _glp_spm_new_elem -SPME *spm_new_elem(SPM *A, int i, int j, double val); -/* add new element to sparse matrix */ - -#define spm_delete_mat _glp_spm_delete_mat -void spm_delete_mat(SPM *A); -/* delete general sparse matrix */ - -#define spm_test_mat_e _glp_spm_test_mat_e -SPM *spm_test_mat_e(int n, int c); -/* create test sparse matrix of E(n,c) class */ - -#define spm_test_mat_d _glp_spm_test_mat_d -SPM *spm_test_mat_d(int n, int c); -/* create test sparse matrix of D(n,c) class */ - -#define spm_show_mat _glp_spm_show_mat -int spm_show_mat(const SPM *A, const char *fname); -/* write sparse matrix pattern in BMP file format */ - -#define spm_read_hbm _glp_spm_read_hbm -SPM *spm_read_hbm(const char *fname); -/* read sparse matrix in Harwell-Boeing format */ - -#define spm_count_nnz _glp_spm_count_nnz -int spm_count_nnz(const SPM *A); -/* determine number of non-zeros in sparse matrix */ - -#define spm_drop_zeros _glp_spm_drop_zeros -int spm_drop_zeros(SPM *A, double eps); -/* remove zero elements from sparse matrix */ - -#define spm_read_mat _glp_spm_read_mat -SPM *spm_read_mat(const char *fname); -/* read sparse matrix from text file */ - -#define spm_write_mat _glp_spm_write_mat -int spm_write_mat(const SPM *A, const char *fname); -/* write sparse matrix to text file */ - -#define spm_transpose _glp_spm_transpose -SPM *spm_transpose(const SPM *A); -/* transpose sparse matrix */ - -#define spm_add_sym _glp_spm_add_sym -SPM *spm_add_sym(const SPM *A, const SPM *B); -/* add two sparse matrices (symbolic phase) */ - -#define spm_add_num _glp_spm_add_num -void spm_add_num(SPM *C, double alfa, const SPM *A, double beta, - const SPM *B); -/* add two sparse matrices (numeric phase) */ - -#define spm_add_mat _glp_spm_add_mat -SPM *spm_add_mat(double alfa, const SPM *A, double beta, - const SPM *B); -/* add two sparse matrices (driver routine) */ - -#define spm_mul_sym _glp_spm_mul_sym -SPM *spm_mul_sym(const SPM *A, const SPM *B); -/* multiply two sparse matrices (symbolic phase) */ - -#define spm_mul_num _glp_spm_mul_num -void spm_mul_num(SPM *C, const SPM *A, const SPM *B); -/* multiply two sparse matrices (numeric phase) */ - -#define spm_mul_mat _glp_spm_mul_mat -SPM *spm_mul_mat(const SPM *A, const SPM *B); -/* multiply two sparse matrices (driver routine) */ - -#define spm_create_per _glp_spm_create_per -PER *spm_create_per(int n); -/* create permutation matrix */ - -#define spm_check_per _glp_spm_check_per -void spm_check_per(PER *P); -/* check permutation matrix for correctness */ - -#define spm_delete_per _glp_spm_delete_per -void spm_delete_per(PER *P); -/* delete permutation matrix */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpspx.h b/resources/3rdparty/glpk-4.53/src/glpspx.h deleted file mode 100644 index e62687a6c..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpspx.h +++ /dev/null @@ -1,40 +0,0 @@ -/* glpspx.h (core simplex solvers) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPSPX_H -#define GLPSPX_H - -#include "prob.h" - -#define spx_primal _glp_spx_primal -int spx_primal(glp_prob *lp, const glp_smcp *parm); -/* core LP solver based on the primal simplex method */ - -#define spx_dual _glp_spx_dual -int spx_dual(glp_prob *lp, const glp_smcp *parm); -/* core LP solver based on the dual simplex method */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpspx01.c b/resources/3rdparty/glpk-4.53/src/glpspx01.c deleted file mode 100644 index eb0e4b50c..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpspx01.c +++ /dev/null @@ -1,2971 +0,0 @@ -/* glpspx01.c (primal simplex method) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpspx.h" - -struct csa -{ /* common storage area */ - /*--------------------------------------------------------------*/ - /* LP data */ - int m; - /* number of rows (auxiliary variables), m > 0 */ - int n; - /* number of columns (structural variables), n > 0 */ - char *type; /* char type[1+m+n]; */ - /* type[0] is not used; - type[k], 1 <= k <= m+n, is the type of variable x[k]: - GLP_FR - free variable - GLP_LO - variable with lower bound - GLP_UP - variable with upper bound - GLP_DB - double-bounded variable - GLP_FX - fixed variable */ - double *lb; /* double lb[1+m+n]; */ - /* lb[0] is not used; - lb[k], 1 <= k <= m+n, is an lower bound of variable x[k]; - if x[k] has no lower bound, lb[k] is zero */ - double *ub; /* double ub[1+m+n]; */ - /* ub[0] is not used; - ub[k], 1 <= k <= m+n, is an upper bound of variable x[k]; - if x[k] has no upper bound, ub[k] is zero; - if x[k] is of fixed type, ub[k] is the same as lb[k] */ - double *coef; /* double coef[1+m+n]; */ - /* coef[0] is not used; - coef[k], 1 <= k <= m+n, is an objective coefficient at - variable x[k] (note that on phase I auxiliary variables also - may have non-zero objective coefficients) */ - /*--------------------------------------------------------------*/ - /* original objective function */ - double *obj; /* double obj[1+n]; */ - /* obj[0] is a constant term of the original objective function; - obj[j], 1 <= j <= n, is an original objective coefficient at - structural variable x[m+j] */ - double zeta; - /* factor used to scale original objective coefficients; its - sign defines original optimization direction: zeta > 0 means - minimization, zeta < 0 means maximization */ - /*--------------------------------------------------------------*/ - /* constraint matrix A; it has m rows and n columns and is stored - by columns */ - int *A_ptr; /* int A_ptr[1+n+1]; */ - /* A_ptr[0] is not used; - A_ptr[j], 1 <= j <= n, is starting position of j-th column in - arrays A_ind and A_val; note that A_ptr[1] is always 1; - A_ptr[n+1] indicates the position after the last element in - arrays A_ind and A_val */ - int *A_ind; /* int A_ind[A_ptr[n+1]]; */ - /* row indices */ - double *A_val; /* double A_val[A_ptr[n+1]]; */ - /* non-zero element values */ - /*--------------------------------------------------------------*/ - /* basis header */ - int *head; /* int head[1+m+n]; */ - /* head[0] is not used; - head[i], 1 <= i <= m, is the ordinal number of basic variable - xB[i]; head[i] = k means that xB[i] = x[k] and i-th column of - matrix B is k-th column of matrix (I|-A); - head[m+j], 1 <= j <= n, is the ordinal number of non-basic - variable xN[j]; head[m+j] = k means that xN[j] = x[k] and j-th - column of matrix N is k-th column of matrix (I|-A) */ - char *stat; /* char stat[1+n]; */ - /* stat[0] is not used; - stat[j], 1 <= j <= n, is the status of non-basic variable - xN[j], which defines its active bound: - GLP_NL - lower bound is active - GLP_NU - upper bound is active - GLP_NF - free variable - GLP_NS - fixed variable */ - /*--------------------------------------------------------------*/ - /* matrix B is the basis matrix; it is composed from columns of - the augmented constraint matrix (I|-A) corresponding to basic - variables and stored in a factorized (invertable) form */ - int valid; - /* factorization is valid only if this flag is set */ - BFD *bfd; /* BFD bfd[1:m,1:m]; */ - /* factorized (invertable) form of the basis matrix */ - /*--------------------------------------------------------------*/ - /* matrix N is a matrix composed from columns of the augmented - constraint matrix (I|-A) corresponding to non-basic variables - except fixed ones; it is stored by rows and changes every time - the basis changes */ - int *N_ptr; /* int N_ptr[1+m+1]; */ - /* N_ptr[0] is not used; - N_ptr[i], 1 <= i <= m, is starting position of i-th row in - arrays N_ind and N_val; note that N_ptr[1] is always 1; - N_ptr[m+1] indicates the position after the last element in - arrays N_ind and N_val */ - int *N_len; /* int N_len[1+m]; */ - /* N_len[0] is not used; - N_len[i], 1 <= i <= m, is length of i-th row (0 to n) */ - int *N_ind; /* int N_ind[N_ptr[m+1]]; */ - /* column indices */ - double *N_val; /* double N_val[N_ptr[m+1]]; */ - /* non-zero element values */ - /*--------------------------------------------------------------*/ - /* working parameters */ - int phase; - /* search phase: - 0 - not determined yet - 1 - search for primal feasible solution - 2 - search for optimal solution */ -#if 0 /* 10/VI-2013 */ - glp_long tm_beg; - /* time value at the beginning of the search */ -#else - double tm_beg; -#endif - int it_beg; - /* simplex iteration count at the beginning of the search */ - int it_cnt; - /* simplex iteration count; it increases by one every time the - basis changes (including the case when a non-basic variable - jumps to its opposite bound) */ - int it_dpy; - /* simplex iteration count at the most recent display output */ - /*--------------------------------------------------------------*/ - /* basic solution components */ - double *bbar; /* double bbar[1+m]; */ - /* bbar[0] is not used; - bbar[i], 1 <= i <= m, is primal value of basic variable xB[i] - (if xB[i] is free, its primal value is not updated) */ - double *cbar; /* double cbar[1+n]; */ - /* cbar[0] is not used; - cbar[j], 1 <= j <= n, is reduced cost of non-basic variable - xN[j] (if xN[j] is fixed, its reduced cost is not updated) */ - /*--------------------------------------------------------------*/ - /* the following pricing technique options may be used: - GLP_PT_STD - standard ("textbook") pricing; - GLP_PT_PSE - projected steepest edge; - GLP_PT_DVX - Devex pricing (not implemented yet); - in case of GLP_PT_STD the reference space is not used, and all - steepest edge coefficients are set to 1 */ - int refct; - /* this count is set to an initial value when the reference space - is defined and decreases by one every time the basis changes; - once this count reaches zero, the reference space is redefined - again */ - char *refsp; /* char refsp[1+m+n]; */ - /* refsp[0] is not used; - refsp[k], 1 <= k <= m+n, is the flag which means that variable - x[k] belongs to the current reference space */ - double *gamma; /* double gamma[1+n]; */ - /* gamma[0] is not used; - gamma[j], 1 <= j <= n, is the steepest edge coefficient for - non-basic variable xN[j]; if xN[j] is fixed, gamma[j] is not - used and just set to 1 */ - /*--------------------------------------------------------------*/ - /* non-basic variable xN[q] chosen to enter the basis */ - int q; - /* index of the non-basic variable xN[q] chosen, 1 <= q <= n; - if the set of eligible non-basic variables is empty and thus - no variable has been chosen, q is set to 0 */ - /*--------------------------------------------------------------*/ - /* pivot column of the simplex table corresponding to non-basic - variable xN[q] chosen is the following vector: - T * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q], - where B is the current basis matrix, N[q] is a column of the - matrix (I|-A) corresponding to xN[q] */ - int tcol_nnz; - /* number of non-zero components, 0 <= nnz <= m */ - int *tcol_ind; /* int tcol_ind[1+m]; */ - /* tcol_ind[0] is not used; - tcol_ind[t], 1 <= t <= nnz, is an index of non-zero component, - i.e. tcol_ind[t] = i means that tcol_vec[i] != 0 */ - double *tcol_vec; /* double tcol_vec[1+m]; */ - /* tcol_vec[0] is not used; - tcol_vec[i], 1 <= i <= m, is a numeric value of i-th component - of the column */ - double tcol_max; - /* infinity (maximum) norm of the column (max |tcol_vec[i]|) */ - int tcol_num; - /* number of significant non-zero components, which means that: - |tcol_vec[i]| >= eps for i in tcol_ind[1,...,num], - |tcol_vec[i]| < eps for i in tcol_ind[num+1,...,nnz], - where eps is a pivot tolerance */ - /*--------------------------------------------------------------*/ - /* basic variable xB[p] chosen to leave the basis */ - int p; - /* index of the basic variable xB[p] chosen, 1 <= p <= m; - p = 0 means that no basic variable reaches its bound; - p < 0 means that non-basic variable xN[q] reaches its opposite - bound before any basic variable */ - int p_stat; - /* new status (GLP_NL, GLP_NU, or GLP_NS) to be assigned to xB[p] - once it has left the basis */ - double teta; - /* change of non-basic variable xN[q] (see above), on which xB[p] - (or, if p < 0, xN[q] itself) reaches its bound */ - /*--------------------------------------------------------------*/ - /* pivot row of the simplex table corresponding to basic variable - xB[p] chosen is the following vector: - T' * e[p] = - N' * inv(B') * e[p] = - N' * rho, - where B' is a matrix transposed to the current basis matrix, - N' is a matrix, whose rows are columns of the matrix (I|-A) - corresponding to non-basic non-fixed variables */ - int trow_nnz; - /* number of non-zero components, 0 <= nnz <= n */ - int *trow_ind; /* int trow_ind[1+n]; */ - /* trow_ind[0] is not used; - trow_ind[t], 1 <= t <= nnz, is an index of non-zero component, - i.e. trow_ind[t] = j means that trow_vec[j] != 0 */ - double *trow_vec; /* int trow_vec[1+n]; */ - /* trow_vec[0] is not used; - trow_vec[j], 1 <= j <= n, is a numeric value of j-th component - of the row */ - /*--------------------------------------------------------------*/ - /* working arrays */ - double *work1; /* double work1[1+m]; */ - double *work2; /* double work2[1+m]; */ - double *work3; /* double work3[1+m]; */ - double *work4; /* double work4[1+m]; */ -}; - -static const double kappa = 0.10; - -/*********************************************************************** -* alloc_csa - allocate common storage area -* -* This routine allocates all arrays in the common storage area (CSA) -* and returns a pointer to the CSA. */ - -static struct csa *alloc_csa(glp_prob *lp) -{ struct csa *csa; - int m = lp->m; - int n = lp->n; - int nnz = lp->nnz; - csa = xmalloc(sizeof(struct csa)); - xassert(m > 0 && n > 0); - csa->m = m; - csa->n = n; - csa->type = xcalloc(1+m+n, sizeof(char)); - csa->lb = xcalloc(1+m+n, sizeof(double)); - csa->ub = xcalloc(1+m+n, sizeof(double)); - csa->coef = xcalloc(1+m+n, sizeof(double)); - csa->obj = xcalloc(1+n, sizeof(double)); - csa->A_ptr = xcalloc(1+n+1, sizeof(int)); - csa->A_ind = xcalloc(1+nnz, sizeof(int)); - csa->A_val = xcalloc(1+nnz, sizeof(double)); - csa->head = xcalloc(1+m+n, sizeof(int)); - csa->stat = xcalloc(1+n, sizeof(char)); - csa->N_ptr = xcalloc(1+m+1, sizeof(int)); - csa->N_len = xcalloc(1+m, sizeof(int)); - csa->N_ind = NULL; /* will be allocated later */ - csa->N_val = NULL; /* will be allocated later */ - csa->bbar = xcalloc(1+m, sizeof(double)); - csa->cbar = xcalloc(1+n, sizeof(double)); - csa->refsp = xcalloc(1+m+n, sizeof(char)); - csa->gamma = xcalloc(1+n, sizeof(double)); - csa->tcol_ind = xcalloc(1+m, sizeof(int)); - csa->tcol_vec = xcalloc(1+m, sizeof(double)); - csa->trow_ind = xcalloc(1+n, sizeof(int)); - csa->trow_vec = xcalloc(1+n, sizeof(double)); - csa->work1 = xcalloc(1+m, sizeof(double)); - csa->work2 = xcalloc(1+m, sizeof(double)); - csa->work3 = xcalloc(1+m, sizeof(double)); - csa->work4 = xcalloc(1+m, sizeof(double)); - return csa; -} - -/*********************************************************************** -* init_csa - initialize common storage area -* -* This routine initializes all data structures in the common storage -* area (CSA). */ - -static void alloc_N(struct csa *csa); -static void build_N(struct csa *csa); - -static void init_csa(struct csa *csa, glp_prob *lp) -{ int m = csa->m; - int n = csa->n; - char *type = csa->type; - double *lb = csa->lb; - double *ub = csa->ub; - double *coef = csa->coef; - double *obj = csa->obj; - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int *head = csa->head; - char *stat = csa->stat; - char *refsp = csa->refsp; - double *gamma = csa->gamma; - int i, j, k, loc; - double cmax; - /* auxiliary variables */ - for (i = 1; i <= m; i++) - { GLPROW *row = lp->row[i]; - type[i] = (char)row->type; - lb[i] = row->lb * row->rii; - ub[i] = row->ub * row->rii; - coef[i] = 0.0; - } - /* structural variables */ - for (j = 1; j <= n; j++) - { GLPCOL *col = lp->col[j]; - type[m+j] = (char)col->type; - lb[m+j] = col->lb / col->sjj; - ub[m+j] = col->ub / col->sjj; - coef[m+j] = col->coef * col->sjj; - } - /* original objective function */ - obj[0] = lp->c0; - memcpy(&obj[1], &coef[m+1], n * sizeof(double)); - /* factor used to scale original objective coefficients */ - cmax = 0.0; - for (j = 1; j <= n; j++) - if (cmax < fabs(obj[j])) cmax = fabs(obj[j]); - if (cmax == 0.0) cmax = 1.0; - switch (lp->dir) - { case GLP_MIN: - csa->zeta = + 1.0 / cmax; - break; - case GLP_MAX: - csa->zeta = - 1.0 / cmax; - break; - default: - xassert(lp != lp); - } -#if 1 - if (fabs(csa->zeta) < 1.0) csa->zeta *= 1000.0; -#endif - /* matrix A (by columns) */ - loc = 1; - for (j = 1; j <= n; j++) - { GLPAIJ *aij; - A_ptr[j] = loc; - for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next) - { A_ind[loc] = aij->row->i; - A_val[loc] = aij->row->rii * aij->val * aij->col->sjj; - loc++; - } - } - A_ptr[n+1] = loc; - xassert(loc == lp->nnz+1); - /* basis header */ - xassert(lp->valid); - memcpy(&head[1], &lp->head[1], m * sizeof(int)); - k = 0; - for (i = 1; i <= m; i++) - { GLPROW *row = lp->row[i]; - if (row->stat != GLP_BS) - { k++; - xassert(k <= n); - head[m+k] = i; - stat[k] = (char)row->stat; - } - } - for (j = 1; j <= n; j++) - { GLPCOL *col = lp->col[j]; - if (col->stat != GLP_BS) - { k++; - xassert(k <= n); - head[m+k] = m + j; - stat[k] = (char)col->stat; - } - } - xassert(k == n); - /* factorization of matrix B */ - csa->valid = 1, lp->valid = 0; - csa->bfd = lp->bfd, lp->bfd = NULL; - /* matrix N (by rows) */ - alloc_N(csa); - build_N(csa); - /* working parameters */ - csa->phase = 0; - csa->tm_beg = xtime(); - csa->it_beg = csa->it_cnt = lp->it_cnt; - csa->it_dpy = -1; - /* reference space and steepest edge coefficients */ - csa->refct = 0; - memset(&refsp[1], 0, (m+n) * sizeof(char)); - for (j = 1; j <= n; j++) gamma[j] = 1.0; - return; -} - -/*********************************************************************** -* invert_B - compute factorization of the basis matrix -* -* This routine computes factorization of the current basis matrix B. -* -* If the operation is successful, the routine returns zero, otherwise -* non-zero. */ - -static int inv_col(void *info, int i, int ind[], double val[]) -{ /* this auxiliary routine returns row indices and numeric values - of non-zero elements of i-th column of the basis matrix */ - struct csa *csa = info; - int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int *head = csa->head; - int k, len, ptr, t; -#ifdef GLP_DEBUG - xassert(1 <= i && i <= m); -#endif - k = head[i]; /* B[i] is k-th column of (I|-A) */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (k <= m) - { /* B[i] is k-th column of submatrix I */ - len = 1; - ind[1] = k; - val[1] = 1.0; - } - else - { /* B[i] is (k-m)-th column of submatrix (-A) */ - ptr = A_ptr[k-m]; - len = A_ptr[k-m+1] - ptr; - memcpy(&ind[1], &A_ind[ptr], len * sizeof(int)); - memcpy(&val[1], &A_val[ptr], len * sizeof(double)); - for (t = 1; t <= len; t++) val[t] = - val[t]; - } - return len; -} - -static int invert_B(struct csa *csa) -{ int ret; - ret = bfd_factorize(csa->bfd, csa->m, NULL, inv_col, csa); - csa->valid = (ret == 0); - return ret; -} - -/*********************************************************************** -* update_B - update factorization of the basis matrix -* -* This routine replaces i-th column of the basis matrix B by k-th -* column of the augmented constraint matrix (I|-A) and then updates -* the factorization of B. -* -* If the factorization has been successfully updated, the routine -* returns zero, otherwise non-zero. */ - -static int update_B(struct csa *csa, int i, int k) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int ret; -#ifdef GLP_DEBUG - xassert(1 <= i && i <= m); - xassert(1 <= k && k <= m+n); -#endif - if (k <= m) - { /* new i-th column of B is k-th column of I */ - int ind[1+1]; - double val[1+1]; - ind[1] = k; - val[1] = 1.0; - xassert(csa->valid); - ret = bfd_update_it(csa->bfd, i, 0, 1, ind, val); - } - else - { /* new i-th column of B is (k-m)-th column of (-A) */ - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - double *val = csa->work1; - int beg, end, ptr, len; - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - len = 0; - for (ptr = beg; ptr < end; ptr++) - val[++len] = - A_val[ptr]; - xassert(csa->valid); - ret = bfd_update_it(csa->bfd, i, 0, len, &A_ind[beg-1], val); - } - csa->valid = (ret == 0); - return ret; -} - -/*********************************************************************** -* error_ftran - compute residual vector r = h - B * x -* -* This routine computes the residual vector r = h - B * x, where B is -* the current basis matrix, h is the vector of right-hand sides, x is -* the solution vector. */ - -static void error_ftran(struct csa *csa, double h[], double x[], - double r[]) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int *head = csa->head; - int i, k, beg, end, ptr; - double temp; - /* compute the residual vector: - r = h - B * x = h - B[1] * x[1] - ... - B[m] * x[m], - where B[1], ..., B[m] are columns of matrix B */ - memcpy(&r[1], &h[1], m * sizeof(double)); - for (i = 1; i <= m; i++) - { temp = x[i]; - if (temp == 0.0) continue; - k = head[i]; /* B[i] is k-th column of (I|-A) */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (k <= m) - { /* B[i] is k-th column of submatrix I */ - r[k] -= temp; - } - else - { /* B[i] is (k-m)-th column of submatrix (-A) */ - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - r[A_ind[ptr]] += A_val[ptr] * temp; - } - } - return; -} - -/*********************************************************************** -* refine_ftran - refine solution of B * x = h -* -* This routine performs one iteration to refine the solution of -* the system B * x = h, where B is the current basis matrix, h is the -* vector of right-hand sides, x is the solution vector. */ - -static void refine_ftran(struct csa *csa, double h[], double x[]) -{ int m = csa->m; - double *r = csa->work1; - double *d = csa->work1; - int i; - /* compute the residual vector r = h - B * x */ - error_ftran(csa, h, x, r); - /* compute the correction vector d = inv(B) * r */ - xassert(csa->valid); - bfd_ftran(csa->bfd, d); - /* refine the solution vector (new x) = (old x) + d */ - for (i = 1; i <= m; i++) x[i] += d[i]; - return; -} - -/*********************************************************************** -* error_btran - compute residual vector r = h - B'* x -* -* This routine computes the residual vector r = h - B'* x, where B' -* is a matrix transposed to the current basis matrix, h is the vector -* of right-hand sides, x is the solution vector. */ - -static void error_btran(struct csa *csa, double h[], double x[], - double r[]) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int *head = csa->head; - int i, k, beg, end, ptr; - double temp; - /* compute the residual vector r = b - B'* x */ - for (i = 1; i <= m; i++) - { /* r[i] := b[i] - (i-th column of B)'* x */ - k = head[i]; /* B[i] is k-th column of (I|-A) */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - temp = h[i]; - if (k <= m) - { /* B[i] is k-th column of submatrix I */ - temp -= x[k]; - } - else - { /* B[i] is (k-m)-th column of submatrix (-A) */ - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - temp += A_val[ptr] * x[A_ind[ptr]]; - } - r[i] = temp; - } - return; -} - -/*********************************************************************** -* refine_btran - refine solution of B'* x = h -* -* This routine performs one iteration to refine the solution of the -* system B'* x = h, where B' is a matrix transposed to the current -* basis matrix, h is the vector of right-hand sides, x is the solution -* vector. */ - -static void refine_btran(struct csa *csa, double h[], double x[]) -{ int m = csa->m; - double *r = csa->work1; - double *d = csa->work1; - int i; - /* compute the residual vector r = h - B'* x */ - error_btran(csa, h, x, r); - /* compute the correction vector d = inv(B') * r */ - xassert(csa->valid); - bfd_btran(csa->bfd, d); - /* refine the solution vector (new x) = (old x) + d */ - for (i = 1; i <= m; i++) x[i] += d[i]; - return; -} - -/*********************************************************************** -* alloc_N - allocate matrix N -* -* This routine determines maximal row lengths of matrix N, sets its -* row pointers, and then allocates arrays N_ind and N_val. -* -* Note that some fixed structural variables may temporarily become -* double-bounded, so corresponding columns of matrix A should not be -* ignored on calculating maximal row lengths of matrix N. */ - -static void alloc_N(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - int *N_ptr = csa->N_ptr; - int *N_len = csa->N_len; - int i, j, beg, end, ptr; - /* determine number of non-zeros in each row of the augmented - constraint matrix (I|-A) */ - for (i = 1; i <= m; i++) - N_len[i] = 1; - for (j = 1; j <= n; j++) - { beg = A_ptr[j]; - end = A_ptr[j+1]; - for (ptr = beg; ptr < end; ptr++) - N_len[A_ind[ptr]]++; - } - /* determine maximal row lengths of matrix N and set its row - pointers */ - N_ptr[1] = 1; - for (i = 1; i <= m; i++) - { /* row of matrix N cannot have more than n non-zeros */ - if (N_len[i] > n) N_len[i] = n; - N_ptr[i+1] = N_ptr[i] + N_len[i]; - } - /* now maximal number of non-zeros in matrix N is known */ - csa->N_ind = xcalloc(N_ptr[m+1], sizeof(int)); - csa->N_val = xcalloc(N_ptr[m+1], sizeof(double)); - return; -} - -/*********************************************************************** -* add_N_col - add column of matrix (I|-A) to matrix N -* -* This routine adds j-th column to matrix N which is k-th column of -* the augmented constraint matrix (I|-A). (It is assumed that old j-th -* column was previously removed from matrix N.) */ - -static void add_N_col(struct csa *csa, int j, int k) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int *N_ptr = csa->N_ptr; - int *N_len = csa->N_len; - int *N_ind = csa->N_ind; - double *N_val = csa->N_val; - int pos; -#ifdef GLP_DEBUG - xassert(1 <= j && j <= n); - xassert(1 <= k && k <= m+n); -#endif - if (k <= m) - { /* N[j] is k-th column of submatrix I */ - pos = N_ptr[k] + (N_len[k]++); -#ifdef GLP_DEBUG - xassert(pos < N_ptr[k+1]); -#endif - N_ind[pos] = j; - N_val[pos] = 1.0; - } - else - { /* N[j] is (k-m)-th column of submatrix (-A) */ - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int i, beg, end, ptr; - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - { i = A_ind[ptr]; /* row number */ - pos = N_ptr[i] + (N_len[i]++); -#ifdef GLP_DEBUG - xassert(pos < N_ptr[i+1]); -#endif - N_ind[pos] = j; - N_val[pos] = - A_val[ptr]; - } - } - return; -} - -/*********************************************************************** -* del_N_col - remove column of matrix (I|-A) from matrix N -* -* This routine removes j-th column from matrix N which is k-th column -* of the augmented constraint matrix (I|-A). */ - -static void del_N_col(struct csa *csa, int j, int k) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int *N_ptr = csa->N_ptr; - int *N_len = csa->N_len; - int *N_ind = csa->N_ind; - double *N_val = csa->N_val; - int pos, head, tail; -#ifdef GLP_DEBUG - xassert(1 <= j && j <= n); - xassert(1 <= k && k <= m+n); -#endif - if (k <= m) - { /* N[j] is k-th column of submatrix I */ - /* find element in k-th row of N */ - head = N_ptr[k]; - for (pos = head; N_ind[pos] != j; pos++) /* nop */; - /* and remove it from the row list */ - tail = head + (--N_len[k]); -#ifdef GLP_DEBUG - xassert(pos <= tail); -#endif - N_ind[pos] = N_ind[tail]; - N_val[pos] = N_val[tail]; - } - else - { /* N[j] is (k-m)-th column of submatrix (-A) */ - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - int i, beg, end, ptr; - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - { i = A_ind[ptr]; /* row number */ - /* find element in i-th row of N */ - head = N_ptr[i]; - for (pos = head; N_ind[pos] != j; pos++) /* nop */; - /* and remove it from the row list */ - tail = head + (--N_len[i]); -#ifdef GLP_DEBUG - xassert(pos <= tail); -#endif - N_ind[pos] = N_ind[tail]; - N_val[pos] = N_val[tail]; - } - } - return; -} - -/*********************************************************************** -* build_N - build matrix N for current basis -* -* This routine builds matrix N for the current basis from columns -* of the augmented constraint matrix (I|-A) corresponding to non-basic -* non-fixed variables. */ - -static void build_N(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - int *head = csa->head; - char *stat = csa->stat; - int *N_len = csa->N_len; - int j, k; - /* N := empty matrix */ - memset(&N_len[1], 0, m * sizeof(int)); - /* go through non-basic columns of matrix (I|-A) */ - for (j = 1; j <= n; j++) - { if (stat[j] != GLP_NS) - { /* xN[j] is non-fixed; add j-th column to matrix N which is - k-th column of matrix (I|-A) */ - k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - add_N_col(csa, j, k); - } - } - return; -} - -/*********************************************************************** -* get_xN - determine current value of non-basic variable xN[j] -* -* This routine returns the current value of non-basic variable xN[j], -* which is a value of its active bound. */ - -static double get_xN(struct csa *csa, int j) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - double *lb = csa->lb; - double *ub = csa->ub; - int *head = csa->head; - char *stat = csa->stat; - int k; - double xN; -#ifdef GLP_DEBUG - xassert(1 <= j && j <= n); -#endif - k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - switch (stat[j]) - { case GLP_NL: - /* x[k] is on its lower bound */ - xN = lb[k]; break; - case GLP_NU: - /* x[k] is on its upper bound */ - xN = ub[k]; break; - case GLP_NF: - /* x[k] is free non-basic variable */ - xN = 0.0; break; - case GLP_NS: - /* x[k] is fixed non-basic variable */ - xN = lb[k]; break; - default: - xassert(stat != stat); - } - return xN; -} - -/*********************************************************************** -* eval_beta - compute primal values of basic variables -* -* This routine computes current primal values of all basic variables: -* -* beta = - inv(B) * N * xN, -* -* where B is the current basis matrix, N is a matrix built of columns -* of matrix (I|-A) corresponding to non-basic variables, and xN is the -* vector of current values of non-basic variables. */ - -static void eval_beta(struct csa *csa, double beta[]) -{ int m = csa->m; - int n = csa->n; - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int *head = csa->head; - double *h = csa->work2; - int i, j, k, beg, end, ptr; - double xN; - /* compute the right-hand side vector: - h := - N * xN = - N[1] * xN[1] - ... - N[n] * xN[n], - where N[1], ..., N[n] are columns of matrix N */ - for (i = 1; i <= m; i++) - h[i] = 0.0; - for (j = 1; j <= n; j++) - { k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - /* determine current value of xN[j] */ - xN = get_xN(csa, j); - if (xN == 0.0) continue; - if (k <= m) - { /* N[j] is k-th column of submatrix I */ - h[k] -= xN; - } - else - { /* N[j] is (k-m)-th column of submatrix (-A) */ - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - h[A_ind[ptr]] += xN * A_val[ptr]; - } - } - /* solve system B * beta = h */ - memcpy(&beta[1], &h[1], m * sizeof(double)); - xassert(csa->valid); - bfd_ftran(csa->bfd, beta); - /* and refine the solution */ - refine_ftran(csa, h, beta); - return; -} - -/*********************************************************************** -* eval_pi - compute vector of simplex multipliers -* -* This routine computes the vector of current simplex multipliers: -* -* pi = inv(B') * cB, -* -* where B' is a matrix transposed to the current basis matrix, cB is -* a subvector of objective coefficients at basic variables. */ - -static void eval_pi(struct csa *csa, double pi[]) -{ int m = csa->m; - double *c = csa->coef; - int *head = csa->head; - double *cB = csa->work2; - int i; - /* construct the right-hand side vector cB */ - for (i = 1; i <= m; i++) - cB[i] = c[head[i]]; - /* solve system B'* pi = cB */ - memcpy(&pi[1], &cB[1], m * sizeof(double)); - xassert(csa->valid); - bfd_btran(csa->bfd, pi); - /* and refine the solution */ - refine_btran(csa, cB, pi); - return; -} - -/*********************************************************************** -* eval_cost - compute reduced cost of non-basic variable xN[j] -* -* This routine computes the current reduced cost of non-basic variable -* xN[j]: -* -* d[j] = cN[j] - N'[j] * pi, -* -* where cN[j] is the objective coefficient at variable xN[j], N[j] is -* a column of the augmented constraint matrix (I|-A) corresponding to -* xN[j], pi is the vector of simplex multipliers. */ - -static double eval_cost(struct csa *csa, double pi[], int j) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - double *coef = csa->coef; - int *head = csa->head; - int k; - double dj; -#ifdef GLP_DEBUG - xassert(1 <= j && j <= n); -#endif - k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - dj = coef[k]; - if (k <= m) - { /* N[j] is k-th column of submatrix I */ - dj -= pi[k]; - } - else - { /* N[j] is (k-m)-th column of submatrix (-A) */ - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int beg, end, ptr; - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - dj += A_val[ptr] * pi[A_ind[ptr]]; - } - return dj; -} - -/*********************************************************************** -* eval_bbar - compute and store primal values of basic variables -* -* This routine computes primal values of all basic variables and then -* stores them in the solution array. */ - -static void eval_bbar(struct csa *csa) -{ eval_beta(csa, csa->bbar); - return; -} - -/*********************************************************************** -* eval_cbar - compute and store reduced costs of non-basic variables -* -* This routine computes reduced costs of all non-basic variables and -* then stores them in the solution array. */ - -static void eval_cbar(struct csa *csa) -{ -#ifdef GLP_DEBUG - int m = csa->m; -#endif - int n = csa->n; -#ifdef GLP_DEBUG - int *head = csa->head; -#endif - double *cbar = csa->cbar; - double *pi = csa->work3; - int j; -#ifdef GLP_DEBUG - int k; -#endif - /* compute simplex multipliers */ - eval_pi(csa, pi); - /* compute and store reduced costs */ - for (j = 1; j <= n; j++) - { -#ifdef GLP_DEBUG - k = head[m+j]; /* x[k] = xN[j] */ - xassert(1 <= k && k <= m+n); -#endif - cbar[j] = eval_cost(csa, pi, j); - } - return; -} - -/*********************************************************************** -* reset_refsp - reset the reference space -* -* This routine resets (redefines) the reference space used in the -* projected steepest edge pricing algorithm. */ - -static void reset_refsp(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - int *head = csa->head; - char *refsp = csa->refsp; - double *gamma = csa->gamma; - int j, k; - xassert(csa->refct == 0); - csa->refct = 1000; - memset(&refsp[1], 0, (m+n) * sizeof(char)); - for (j = 1; j <= n; j++) - { k = head[m+j]; /* x[k] = xN[j] */ - refsp[k] = 1; - gamma[j] = 1.0; - } - return; -} - -/*********************************************************************** -* eval_gamma - compute steepest edge coefficient -* -* This routine computes the steepest edge coefficient for non-basic -* variable xN[j] using its direct definition: -* -* gamma[j] = delta[j] + sum alfa[i,j]^2, -* i in R -* -* where delta[j] = 1, if xN[j] is in the current reference space, -* and 0 otherwise; R is a set of basic variables xB[i], which are in -* the current reference space; alfa[i,j] are elements of the current -* simplex table. -* -* NOTE: The routine is intended only for debugginig purposes. */ - -static double eval_gamma(struct csa *csa, int j) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int *head = csa->head; - char *refsp = csa->refsp; - double *alfa = csa->work3; - double *h = csa->work3; - int i, k; - double gamma; -#ifdef GLP_DEBUG - xassert(1 <= j && j <= n); -#endif - k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - /* construct the right-hand side vector h = - N[j] */ - for (i = 1; i <= m; i++) - h[i] = 0.0; - if (k <= m) - { /* N[j] is k-th column of submatrix I */ - h[k] = -1.0; - } - else - { /* N[j] is (k-m)-th column of submatrix (-A) */ - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int beg, end, ptr; - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - h[A_ind[ptr]] = A_val[ptr]; - } - /* solve system B * alfa = h */ - xassert(csa->valid); - bfd_ftran(csa->bfd, alfa); - /* compute gamma */ - gamma = (refsp[k] ? 1.0 : 0.0); - for (i = 1; i <= m; i++) - { k = head[i]; -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (refsp[k]) gamma += alfa[i] * alfa[i]; - } - return gamma; -} - -/*********************************************************************** -* chuzc - choose non-basic variable (column of the simplex table) -* -* This routine chooses non-basic variable xN[q], which has largest -* weighted reduced cost: -* -* |d[q]| / sqrt(gamma[q]) = max |d[j]| / sqrt(gamma[j]), -* j in J -* -* where J is a subset of eligible non-basic variables xN[j], d[j] is -* reduced cost of xN[j], gamma[j] is the steepest edge coefficient. -* -* The working objective function is always minimized, so the sign of -* d[q] determines direction, in which xN[q] has to change: -* -* if d[q] < 0, xN[q] has to increase; -* -* if d[q] > 0, xN[q] has to decrease. -* -* If |d[j]| <= tol_dj, where tol_dj is a specified tolerance, xN[j] -* is not included in J and therefore ignored. (It is assumed that the -* working objective row is appropriately scaled, i.e. max|c[k]| = 1.) -* -* If J is empty and no variable has been chosen, q is set to 0. */ - -static void chuzc(struct csa *csa, double tol_dj) -{ int n = csa->n; - char *stat = csa->stat; - double *cbar = csa->cbar; - double *gamma = csa->gamma; - int j, q; - double dj, best, temp; - /* nothing is chosen so far */ - q = 0, best = 0.0; - /* look through the list of non-basic variables */ - for (j = 1; j <= n; j++) - { dj = cbar[j]; - switch (stat[j]) - { case GLP_NL: - /* xN[j] can increase */ - if (dj >= - tol_dj) continue; - break; - case GLP_NU: - /* xN[j] can decrease */ - if (dj <= + tol_dj) continue; - break; - case GLP_NF: - /* xN[j] can change in any direction */ - if (- tol_dj <= dj && dj <= + tol_dj) continue; - break; - case GLP_NS: - /* xN[j] cannot change at all */ - continue; - default: - xassert(stat != stat); - } - /* xN[j] is eligible non-basic variable; choose one which has - largest weighted reduced cost */ -#ifdef GLP_DEBUG - xassert(gamma[j] > 0.0); -#endif - temp = (dj * dj) / gamma[j]; - if (best < temp) - q = j, best = temp; - } - /* store the index of non-basic variable xN[q] chosen */ - csa->q = q; - return; -} - -/*********************************************************************** -* eval_tcol - compute pivot column of the simplex table -* -* This routine computes the pivot column of the simplex table, which -* corresponds to non-basic variable xN[q] chosen. -* -* The pivot column is the following vector: -* -* tcol = T * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q], -* -* where B is the current basis matrix, N[q] is a column of the matrix -* (I|-A) corresponding to variable xN[q]. */ - -static void eval_tcol(struct csa *csa) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int *head = csa->head; - int q = csa->q; - int *tcol_ind = csa->tcol_ind; - double *tcol_vec = csa->tcol_vec; - double *h = csa->tcol_vec; - int i, k, nnz; -#ifdef GLP_DEBUG - xassert(1 <= q && q <= n); -#endif - k = head[m+q]; /* x[k] = xN[q] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - /* construct the right-hand side vector h = - N[q] */ - for (i = 1; i <= m; i++) - h[i] = 0.0; - if (k <= m) - { /* N[q] is k-th column of submatrix I */ - h[k] = -1.0; - } - else - { /* N[q] is (k-m)-th column of submatrix (-A) */ - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int beg, end, ptr; - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - h[A_ind[ptr]] = A_val[ptr]; - } - /* solve system B * tcol = h */ - xassert(csa->valid); - bfd_ftran(csa->bfd, tcol_vec); - /* construct sparse pattern of the pivot column */ - nnz = 0; - for (i = 1; i <= m; i++) - { if (tcol_vec[i] != 0.0) - tcol_ind[++nnz] = i; - } - csa->tcol_nnz = nnz; - return; -} - -/*********************************************************************** -* refine_tcol - refine pivot column of the simplex table -* -* This routine refines the pivot column of the simplex table assuming -* that it was previously computed by the routine eval_tcol. */ - -static void refine_tcol(struct csa *csa) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int *head = csa->head; - int q = csa->q; - int *tcol_ind = csa->tcol_ind; - double *tcol_vec = csa->tcol_vec; - double *h = csa->work3; - int i, k, nnz; -#ifdef GLP_DEBUG - xassert(1 <= q && q <= n); -#endif - k = head[m+q]; /* x[k] = xN[q] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - /* construct the right-hand side vector h = - N[q] */ - for (i = 1; i <= m; i++) - h[i] = 0.0; - if (k <= m) - { /* N[q] is k-th column of submatrix I */ - h[k] = -1.0; - } - else - { /* N[q] is (k-m)-th column of submatrix (-A) */ - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int beg, end, ptr; - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - h[A_ind[ptr]] = A_val[ptr]; - } - /* refine solution of B * tcol = h */ - refine_ftran(csa, h, tcol_vec); - /* construct sparse pattern of the pivot column */ - nnz = 0; - for (i = 1; i <= m; i++) - { if (tcol_vec[i] != 0.0) - tcol_ind[++nnz] = i; - } - csa->tcol_nnz = nnz; - return; -} - -/*********************************************************************** -* sort_tcol - sort pivot column of the simplex table -* -* This routine reorders the list of non-zero elements of the pivot -* column to put significant elements, whose magnitude is not less than -* a specified tolerance, in front of the list, and stores the number -* of significant elements in tcol_num. */ - -static void sort_tcol(struct csa *csa, double tol_piv) -{ -#ifdef GLP_DEBUG - int m = csa->m; -#endif - int nnz = csa->tcol_nnz; - int *tcol_ind = csa->tcol_ind; - double *tcol_vec = csa->tcol_vec; - int i, num, pos; - double big, eps, temp; - /* compute infinity (maximum) norm of the column */ - big = 0.0; - for (pos = 1; pos <= nnz; pos++) - { -#ifdef GLP_DEBUG - i = tcol_ind[pos]; - xassert(1 <= i && i <= m); -#endif - temp = fabs(tcol_vec[tcol_ind[pos]]); - if (big < temp) big = temp; - } - csa->tcol_max = big; - /* determine absolute pivot tolerance */ - eps = tol_piv * (1.0 + 0.01 * big); - /* move significant column components to front of the list */ - for (num = 0; num < nnz; ) - { i = tcol_ind[nnz]; - if (fabs(tcol_vec[i]) < eps) - nnz--; - else - { num++; - tcol_ind[nnz] = tcol_ind[num]; - tcol_ind[num] = i; - } - } - csa->tcol_num = num; - return; -} - -/*********************************************************************** -* chuzr - choose basic variable (row of the simplex table) -* -* This routine chooses basic variable xB[p], which reaches its bound -* first on changing non-basic variable xN[q] in valid direction. -* -* The parameter rtol is a relative tolerance used to relax bounds of -* basic variables. If rtol = 0, the routine implements the standard -* ratio test. Otherwise, if rtol > 0, the routine implements Harris' -* two-pass ratio test. In the latter case rtol should be about three -* times less than a tolerance used to check primal feasibility. */ - -static void chuzr(struct csa *csa, double rtol) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - char *type = csa->type; - double *lb = csa->lb; - double *ub = csa->ub; - double *coef = csa->coef; - int *head = csa->head; - int phase = csa->phase; - double *bbar = csa->bbar; - double *cbar = csa->cbar; - int q = csa->q; - int *tcol_ind = csa->tcol_ind; - double *tcol_vec = csa->tcol_vec; - int tcol_num = csa->tcol_num; - int i, i_stat, k, p, p_stat, pos; - double alfa, big, delta, s, t, teta, tmax; -#ifdef GLP_DEBUG - xassert(1 <= q && q <= n); -#endif - /* s := - sign(d[q]), where d[q] is reduced cost of xN[q] */ -#ifdef GLP_DEBUG - xassert(cbar[q] != 0.0); -#endif - s = (cbar[q] > 0.0 ? -1.0 : +1.0); - /*** FIRST PASS ***/ - k = head[m+q]; /* x[k] = xN[q] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (type[k] == GLP_DB) - { /* xN[q] has both lower and upper bounds */ - p = -1, p_stat = 0, teta = ub[k] - lb[k], big = 1.0; - } - else - { /* xN[q] has no opposite bound */ - p = 0, p_stat = 0, teta = DBL_MAX, big = 0.0; - } - /* walk through significant elements of the pivot column */ - for (pos = 1; pos <= tcol_num; pos++) - { i = tcol_ind[pos]; -#ifdef GLP_DEBUG - xassert(1 <= i && i <= m); -#endif - k = head[i]; /* x[k] = xB[i] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - alfa = s * tcol_vec[i]; -#ifdef GLP_DEBUG - xassert(alfa != 0.0); -#endif - /* xB[i] = ... + alfa * xN[q] + ..., and due to s we need to - consider the only case when xN[q] is increasing */ - if (alfa > 0.0) - { /* xB[i] is increasing */ - if (phase == 1 && coef[k] < 0.0) - { /* xB[i] violates its lower bound, which plays the role - of an upper bound on phase I */ - delta = rtol * (1.0 + kappa * fabs(lb[k])); - t = ((lb[k] + delta) - bbar[i]) / alfa; - i_stat = GLP_NL; - } - else if (phase == 1 && coef[k] > 0.0) - { /* xB[i] violates its upper bound, which plays the role - of an lower bound on phase I */ - continue; - } - else if (type[k] == GLP_UP || type[k] == GLP_DB || - type[k] == GLP_FX) - { /* xB[i] is within its bounds and has an upper bound */ - delta = rtol * (1.0 + kappa * fabs(ub[k])); - t = ((ub[k] + delta) - bbar[i]) / alfa; - i_stat = GLP_NU; - } - else - { /* xB[i] is within its bounds and has no upper bound */ - continue; - } - } - else - { /* xB[i] is decreasing */ - if (phase == 1 && coef[k] > 0.0) - { /* xB[i] violates its upper bound, which plays the role - of an lower bound on phase I */ - delta = rtol * (1.0 + kappa * fabs(ub[k])); - t = ((ub[k] - delta) - bbar[i]) / alfa; - i_stat = GLP_NU; - } - else if (phase == 1 && coef[k] < 0.0) - { /* xB[i] violates its lower bound, which plays the role - of an upper bound on phase I */ - continue; - } - else if (type[k] == GLP_LO || type[k] == GLP_DB || - type[k] == GLP_FX) - { /* xB[i] is within its bounds and has an lower bound */ - delta = rtol * (1.0 + kappa * fabs(lb[k])); - t = ((lb[k] - delta) - bbar[i]) / alfa; - i_stat = GLP_NL; - } - else - { /* xB[i] is within its bounds and has no lower bound */ - continue; - } - } - /* t is a change of xN[q], on which xB[i] reaches its bound - (possibly relaxed); since the basic solution is assumed to - be primal feasible (or pseudo feasible on phase I), t has - to be non-negative by definition; however, it may happen - that xB[i] slightly (i.e. within a tolerance) violates its - bound, that leads to negative t; in the latter case, if - xB[i] is chosen, negative t means that xN[q] changes in - wrong direction; if pivot alfa[i,q] is close to zero, even - small bound violation of xB[i] may lead to a large change - of xN[q] in wrong direction; let, for example, xB[i] >= 0 - and in the current basis its value be -5e-9; let also xN[q] - be on its zero bound and should increase; from the ratio - test rule it follows that the pivot alfa[i,q] < 0; however, - if alfa[i,q] is, say, -1e-9, the change of xN[q] in wrong - direction is 5e-9 / (-1e-9) = -5, and using it for updating - values of other basic variables will give absolutely wrong - results; therefore, if t is negative, we should replace it - by exact zero assuming that xB[i] is exactly on its bound, - and the violation appears due to round-off errors */ - if (t < 0.0) t = 0.0; - /* apply minimal ratio test */ - if (teta > t || teta == t && big < fabs(alfa)) - p = i, p_stat = i_stat, teta = t, big = fabs(alfa); - } - /* the second pass is skipped in the following cases: */ - /* if the standard ratio test is used */ - if (rtol == 0.0) goto done; - /* if xN[q] reaches its opposite bound or if no basic variable - has been chosen on the first pass */ - if (p <= 0) goto done; - /* if xB[p] is a blocking variable, i.e. if it prevents xN[q] - from any change */ - if (teta == 0.0) goto done; - /*** SECOND PASS ***/ - /* here tmax is a maximal change of xN[q], on which the solution - remains primal feasible (or pseudo feasible on phase I) within - a tolerance */ -#if 0 - tmax = (1.0 + 10.0 * DBL_EPSILON) * teta; -#else - tmax = teta; -#endif - /* nothing is chosen so far */ - p = 0, p_stat = 0, teta = DBL_MAX, big = 0.0; - /* walk through significant elements of the pivot column */ - for (pos = 1; pos <= tcol_num; pos++) - { i = tcol_ind[pos]; -#ifdef GLP_DEBUG - xassert(1 <= i && i <= m); -#endif - k = head[i]; /* x[k] = xB[i] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - alfa = s * tcol_vec[i]; -#ifdef GLP_DEBUG - xassert(alfa != 0.0); -#endif - /* xB[i] = ... + alfa * xN[q] + ..., and due to s we need to - consider the only case when xN[q] is increasing */ - if (alfa > 0.0) - { /* xB[i] is increasing */ - if (phase == 1 && coef[k] < 0.0) - { /* xB[i] violates its lower bound, which plays the role - of an upper bound on phase I */ - t = (lb[k] - bbar[i]) / alfa; - i_stat = GLP_NL; - } - else if (phase == 1 && coef[k] > 0.0) - { /* xB[i] violates its upper bound, which plays the role - of an lower bound on phase I */ - continue; - } - else if (type[k] == GLP_UP || type[k] == GLP_DB || - type[k] == GLP_FX) - { /* xB[i] is within its bounds and has an upper bound */ - t = (ub[k] - bbar[i]) / alfa; - i_stat = GLP_NU; - } - else - { /* xB[i] is within its bounds and has no upper bound */ - continue; - } - } - else - { /* xB[i] is decreasing */ - if (phase == 1 && coef[k] > 0.0) - { /* xB[i] violates its upper bound, which plays the role - of an lower bound on phase I */ - t = (ub[k] - bbar[i]) / alfa; - i_stat = GLP_NU; - } - else if (phase == 1 && coef[k] < 0.0) - { /* xB[i] violates its lower bound, which plays the role - of an upper bound on phase I */ - continue; - } - else if (type[k] == GLP_LO || type[k] == GLP_DB || - type[k] == GLP_FX) - { /* xB[i] is within its bounds and has an lower bound */ - t = (lb[k] - bbar[i]) / alfa; - i_stat = GLP_NL; - } - else - { /* xB[i] is within its bounds and has no lower bound */ - continue; - } - } - /* (see comments for the first pass) */ - if (t < 0.0) t = 0.0; - /* t is a change of xN[q], on which xB[i] reaches its bound; - if t <= tmax, all basic variables can violate their bounds - only within relaxation tolerance delta; we can use this - freedom and choose basic variable having largest influence - coefficient to avoid possible numeric instability */ - if (t <= tmax && big < fabs(alfa)) - p = i, p_stat = i_stat, teta = t, big = fabs(alfa); - } - /* something must be chosen on the second pass */ - xassert(p != 0); -done: /* store the index and status of basic variable xB[p] chosen */ - csa->p = p; - if (p > 0 && type[head[p]] == GLP_FX) - csa->p_stat = GLP_NS; - else - csa->p_stat = p_stat; - /* store corresponding change of non-basic variable xN[q] */ -#ifdef GLP_DEBUG - xassert(teta >= 0.0); -#endif - csa->teta = s * teta; - return; -} - -/*********************************************************************** -* eval_rho - compute pivot row of the inverse -* -* This routine computes the pivot (p-th) row of the inverse inv(B), -* which corresponds to basic variable xB[p] chosen: -* -* rho = inv(B') * e[p], -* -* where B' is a matrix transposed to the current basis matrix, e[p] -* is unity vector. */ - -static void eval_rho(struct csa *csa, double rho[]) -{ int m = csa->m; - int p = csa->p; - double *e = rho; - int i; -#ifdef GLP_DEBUG - xassert(1 <= p && p <= m); -#endif - /* construct the right-hand side vector e[p] */ - for (i = 1; i <= m; i++) - e[i] = 0.0; - e[p] = 1.0; - /* solve system B'* rho = e[p] */ - xassert(csa->valid); - bfd_btran(csa->bfd, rho); - return; -} - -/*********************************************************************** -* refine_rho - refine pivot row of the inverse -* -* This routine refines the pivot row of the inverse inv(B) assuming -* that it was previously computed by the routine eval_rho. */ - -static void refine_rho(struct csa *csa, double rho[]) -{ int m = csa->m; - int p = csa->p; - double *e = csa->work3; - int i; -#ifdef GLP_DEBUG - xassert(1 <= p && p <= m); -#endif - /* construct the right-hand side vector e[p] */ - for (i = 1; i <= m; i++) - e[i] = 0.0; - e[p] = 1.0; - /* refine solution of B'* rho = e[p] */ - refine_btran(csa, e, rho); - return; -} - -/*********************************************************************** -* eval_trow - compute pivot row of the simplex table -* -* This routine computes the pivot row of the simplex table, which -* corresponds to basic variable xB[p] chosen. -* -* The pivot row is the following vector: -* -* trow = T'* e[p] = - N'* inv(B') * e[p] = - N' * rho, -* -* where rho is the pivot row of the inverse inv(B) previously computed -* by the routine eval_rho. -* -* Note that elements of the pivot row corresponding to fixed non-basic -* variables are not computed. */ - -static void eval_trow(struct csa *csa, double rho[]) -{ int m = csa->m; - int n = csa->n; -#ifdef GLP_DEBUG - char *stat = csa->stat; -#endif - int *N_ptr = csa->N_ptr; - int *N_len = csa->N_len; - int *N_ind = csa->N_ind; - double *N_val = csa->N_val; - int *trow_ind = csa->trow_ind; - double *trow_vec = csa->trow_vec; - int i, j, beg, end, ptr, nnz; - double temp; - /* clear the pivot row */ - for (j = 1; j <= n; j++) - trow_vec[j] = 0.0; - /* compute the pivot row as a linear combination of rows of the - matrix N: trow = - rho[1] * N'[1] - ... - rho[m] * N'[m] */ - for (i = 1; i <= m; i++) - { temp = rho[i]; - if (temp == 0.0) continue; - /* trow := trow - rho[i] * N'[i] */ - beg = N_ptr[i]; - end = beg + N_len[i]; - for (ptr = beg; ptr < end; ptr++) - { -#ifdef GLP_DEBUG - j = N_ind[ptr]; - xassert(1 <= j && j <= n); - xassert(stat[j] != GLP_NS); -#endif - trow_vec[N_ind[ptr]] -= temp * N_val[ptr]; - } - } - /* construct sparse pattern of the pivot row */ - nnz = 0; - for (j = 1; j <= n; j++) - { if (trow_vec[j] != 0.0) - trow_ind[++nnz] = j; - } - csa->trow_nnz = nnz; - return; -} - -/*********************************************************************** -* update_bbar - update values of basic variables -* -* This routine updates values of all basic variables for the adjacent -* basis. */ - -static void update_bbar(struct csa *csa) -{ -#ifdef GLP_DEBUG - int m = csa->m; - int n = csa->n; -#endif - double *bbar = csa->bbar; - int q = csa->q; - int tcol_nnz = csa->tcol_nnz; - int *tcol_ind = csa->tcol_ind; - double *tcol_vec = csa->tcol_vec; - int p = csa->p; - double teta = csa->teta; - int i, pos; -#ifdef GLP_DEBUG - xassert(1 <= q && q <= n); - xassert(p < 0 || 1 <= p && p <= m); -#endif - /* if xN[q] leaves the basis, compute its value in the adjacent - basis, where it will replace xB[p] */ - if (p > 0) - bbar[p] = get_xN(csa, q) + teta; - /* update values of other basic variables (except xB[p], because - it will be replaced by xN[q]) */ - if (teta == 0.0) goto done; - for (pos = 1; pos <= tcol_nnz; pos++) - { i = tcol_ind[pos]; - /* skip xB[p] */ - if (i == p) continue; - /* (change of xB[i]) = alfa[i,q] * (change of xN[q]) */ - bbar[i] += tcol_vec[i] * teta; - } -done: return; -} - -/*********************************************************************** -* reeval_cost - recompute reduced cost of non-basic variable xN[q] -* -* This routine recomputes reduced cost of non-basic variable xN[q] for -* the current basis more accurately using its direct definition: -* -* d[q] = cN[q] - N'[q] * pi = -* -* = cN[q] - N'[q] * (inv(B') * cB) = -* -* = cN[q] - (cB' * inv(B) * N[q]) = -* -* = cN[q] + cB' * (pivot column). -* -* It is assumed that the pivot column of the simplex table is already -* computed. */ - -static double reeval_cost(struct csa *csa) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - double *coef = csa->coef; - int *head = csa->head; - int q = csa->q; - int tcol_nnz = csa->tcol_nnz; - int *tcol_ind = csa->tcol_ind; - double *tcol_vec = csa->tcol_vec; - int i, pos; - double dq; -#ifdef GLP_DEBUG - xassert(1 <= q && q <= n); -#endif - dq = coef[head[m+q]]; - for (pos = 1; pos <= tcol_nnz; pos++) - { i = tcol_ind[pos]; -#ifdef GLP_DEBUG - xassert(1 <= i && i <= m); -#endif - dq += coef[head[i]] * tcol_vec[i]; - } - return dq; -} - -/*********************************************************************** -* update_cbar - update reduced costs of non-basic variables -* -* This routine updates reduced costs of all (except fixed) non-basic -* variables for the adjacent basis. */ - -static void update_cbar(struct csa *csa) -{ -#ifdef GLP_DEBUG - int n = csa->n; -#endif - double *cbar = csa->cbar; - int q = csa->q; - int trow_nnz = csa->trow_nnz; - int *trow_ind = csa->trow_ind; - double *trow_vec = csa->trow_vec; - int j, pos; - double new_dq; -#ifdef GLP_DEBUG - xassert(1 <= q && q <= n); -#endif - /* compute reduced cost of xB[p] in the adjacent basis, where it - will replace xN[q] */ -#ifdef GLP_DEBUG - xassert(trow_vec[q] != 0.0); -#endif - new_dq = (cbar[q] /= trow_vec[q]); - /* update reduced costs of other non-basic variables (except - xN[q], because it will be replaced by xB[p]) */ - for (pos = 1; pos <= trow_nnz; pos++) - { j = trow_ind[pos]; - /* skip xN[q] */ - if (j == q) continue; - cbar[j] -= trow_vec[j] * new_dq; - } - return; -} - -/*********************************************************************** -* update_gamma - update steepest edge coefficients -* -* This routine updates steepest-edge coefficients for the adjacent -* basis. */ - -static void update_gamma(struct csa *csa) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - char *type = csa->type; - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int *head = csa->head; - char *refsp = csa->refsp; - double *gamma = csa->gamma; - int q = csa->q; - int tcol_nnz = csa->tcol_nnz; - int *tcol_ind = csa->tcol_ind; - double *tcol_vec = csa->tcol_vec; - int p = csa->p; - int trow_nnz = csa->trow_nnz; - int *trow_ind = csa->trow_ind; - double *trow_vec = csa->trow_vec; - double *u = csa->work3; - int i, j, k, pos, beg, end, ptr; - double gamma_q, delta_q, pivot, s, t, t1, t2; -#ifdef GLP_DEBUG - xassert(1 <= p && p <= m); - xassert(1 <= q && q <= n); -#endif - /* the basis changes, so decrease the count */ - xassert(csa->refct > 0); - csa->refct--; - /* recompute gamma[q] for the current basis more accurately and - compute auxiliary vector u */ - gamma_q = delta_q = (refsp[head[m+q]] ? 1.0 : 0.0); - for (i = 1; i <= m; i++) u[i] = 0.0; - for (pos = 1; pos <= tcol_nnz; pos++) - { i = tcol_ind[pos]; - if (refsp[head[i]]) - { u[i] = t = tcol_vec[i]; - gamma_q += t * t; - } - else - u[i] = 0.0; - } - xassert(csa->valid); - bfd_btran(csa->bfd, u); - /* update gamma[k] for other non-basic variables (except fixed - variables and xN[q], because it will be replaced by xB[p]) */ - pivot = trow_vec[q]; -#ifdef GLP_DEBUG - xassert(pivot != 0.0); -#endif - for (pos = 1; pos <= trow_nnz; pos++) - { j = trow_ind[pos]; - /* skip xN[q] */ - if (j == q) continue; - /* compute t */ - t = trow_vec[j] / pivot; - /* compute inner product s = N'[j] * u */ - k = head[m+j]; /* x[k] = xN[j] */ - if (k <= m) - s = u[k]; - else - { s = 0.0; - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - s -= A_val[ptr] * u[A_ind[ptr]]; - } - /* compute gamma[k] for the adjacent basis */ - t1 = gamma[j] + t * t * gamma_q + 2.0 * t * s; - t2 = (refsp[k] ? 1.0 : 0.0) + delta_q * t * t; - gamma[j] = (t1 >= t2 ? t1 : t2); - if (gamma[j] < DBL_EPSILON) gamma[j] = DBL_EPSILON; - } - /* compute gamma[q] for the adjacent basis */ - if (type[head[p]] == GLP_FX) - gamma[q] = 1.0; - else - { gamma[q] = gamma_q / (pivot * pivot); - if (gamma[q] < DBL_EPSILON) gamma[q] = DBL_EPSILON; - } - return; -} - -/*********************************************************************** -* err_in_bbar - compute maximal relative error in primal solution -* -* This routine returns maximal relative error: -* -* max |beta[i] - bbar[i]| / (1 + |beta[i]|), -* -* where beta and bbar are, respectively, directly computed and the -* current (updated) values of basic variables. -* -* NOTE: The routine is intended only for debugginig purposes. */ - -static double err_in_bbar(struct csa *csa) -{ int m = csa->m; - double *bbar = csa->bbar; - int i; - double e, emax, *beta; - beta = xcalloc(1+m, sizeof(double)); - eval_beta(csa, beta); - emax = 0.0; - for (i = 1; i <= m; i++) - { e = fabs(beta[i] - bbar[i]) / (1.0 + fabs(beta[i])); - if (emax < e) emax = e; - } - xfree(beta); - return emax; -} - -/*********************************************************************** -* err_in_cbar - compute maximal relative error in dual solution -* -* This routine returns maximal relative error: -* -* max |cost[j] - cbar[j]| / (1 + |cost[j]|), -* -* where cost and cbar are, respectively, directly computed and the -* current (updated) reduced costs of non-basic non-fixed variables. -* -* NOTE: The routine is intended only for debugginig purposes. */ - -static double err_in_cbar(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - char *stat = csa->stat; - double *cbar = csa->cbar; - int j; - double e, emax, cost, *pi; - pi = xcalloc(1+m, sizeof(double)); - eval_pi(csa, pi); - emax = 0.0; - for (j = 1; j <= n; j++) - { if (stat[j] == GLP_NS) continue; - cost = eval_cost(csa, pi, j); - e = fabs(cost - cbar[j]) / (1.0 + fabs(cost)); - if (emax < e) emax = e; - } - xfree(pi); - return emax; -} - -/*********************************************************************** -* err_in_gamma - compute maximal relative error in steepest edge cff. -* -* This routine returns maximal relative error: -* -* max |gamma'[j] - gamma[j]| / (1 + |gamma'[j]), -* -* where gamma'[j] and gamma[j] are, respectively, directly computed -* and the current (updated) steepest edge coefficients for non-basic -* non-fixed variable x[j]. -* -* NOTE: The routine is intended only for debugginig purposes. */ - -static double err_in_gamma(struct csa *csa) -{ int n = csa->n; - char *stat = csa->stat; - double *gamma = csa->gamma; - int j; - double e, emax, temp; - emax = 0.0; - for (j = 1; j <= n; j++) - { if (stat[j] == GLP_NS) - { xassert(gamma[j] == 1.0); - continue; - } - temp = eval_gamma(csa, j); - e = fabs(temp - gamma[j]) / (1.0 + fabs(temp)); - if (emax < e) emax = e; - } - return emax; -} - -/*********************************************************************** -* change_basis - change basis header -* -* This routine changes the basis header to make it corresponding to -* the adjacent basis. */ - -static void change_basis(struct csa *csa) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; - char *type = csa->type; -#endif - int *head = csa->head; - char *stat = csa->stat; - int q = csa->q; - int p = csa->p; - int p_stat = csa->p_stat; - int k; -#ifdef GLP_DEBUG - xassert(1 <= q && q <= n); -#endif - if (p < 0) - { /* xN[q] goes to its opposite bound */ -#ifdef GLP_DEBUG - k = head[m+q]; /* x[k] = xN[q] */ - xassert(1 <= k && k <= m+n); - xassert(type[k] == GLP_DB); -#endif - switch (stat[q]) - { case GLP_NL: - /* xN[q] increases */ - stat[q] = GLP_NU; - break; - case GLP_NU: - /* xN[q] decreases */ - stat[q] = GLP_NL; - break; - default: - xassert(stat != stat); - } - } - else - { /* xB[p] leaves the basis, xN[q] enters the basis */ -#ifdef GLP_DEBUG - xassert(1 <= p && p <= m); - k = head[p]; /* x[k] = xB[p] */ - switch (p_stat) - { case GLP_NL: - /* xB[p] goes to its lower bound */ - xassert(type[k] == GLP_LO || type[k] == GLP_DB); - break; - case GLP_NU: - /* xB[p] goes to its upper bound */ - xassert(type[k] == GLP_UP || type[k] == GLP_DB); - break; - case GLP_NS: - /* xB[p] goes to its fixed value */ - xassert(type[k] == GLP_NS); - break; - default: - xassert(p_stat != p_stat); - } -#endif - /* xB[p] <-> xN[q] */ - k = head[p], head[p] = head[m+q], head[m+q] = k; - stat[q] = (char)p_stat; - } - return; -} - -/*********************************************************************** -* set_aux_obj - construct auxiliary objective function -* -* The auxiliary objective function is a separable piecewise linear -* convex function, which is the sum of primal infeasibilities: -* -* z = t[1] + ... + t[m+n] -> minimize, -* -* where: -* -* / lb[k] - x[k], if x[k] < lb[k] -* | -* t[k] = < 0, if lb[k] <= x[k] <= ub[k] -* | -* \ x[k] - ub[k], if x[k] > ub[k] -* -* This routine computes objective coefficients for the current basis -* and returns the number of non-zero terms t[k]. */ - -static int set_aux_obj(struct csa *csa, double tol_bnd) -{ int m = csa->m; - int n = csa->n; - char *type = csa->type; - double *lb = csa->lb; - double *ub = csa->ub; - double *coef = csa->coef; - int *head = csa->head; - double *bbar = csa->bbar; - int i, k, cnt = 0; - double eps; - /* use a bit more restrictive tolerance */ - tol_bnd *= 0.90; - /* clear all objective coefficients */ - for (k = 1; k <= m+n; k++) - coef[k] = 0.0; - /* walk through the list of basic variables */ - for (i = 1; i <= m; i++) - { k = head[i]; /* x[k] = xB[i] */ - if (type[k] == GLP_LO || type[k] == GLP_DB || - type[k] == GLP_FX) - { /* x[k] has lower bound */ - eps = tol_bnd * (1.0 + kappa * fabs(lb[k])); - if (bbar[i] < lb[k] - eps) - { /* and violates it */ - coef[k] = -1.0; - cnt++; - } - } - if (type[k] == GLP_UP || type[k] == GLP_DB || - type[k] == GLP_FX) - { /* x[k] has upper bound */ - eps = tol_bnd * (1.0 + kappa * fabs(ub[k])); - if (bbar[i] > ub[k] + eps) - { /* and violates it */ - coef[k] = +1.0; - cnt++; - } - } - } - return cnt; -} - -/*********************************************************************** -* set_orig_obj - restore original objective function -* -* This routine assigns scaled original objective coefficients to the -* working objective function. */ - -static void set_orig_obj(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - double *coef = csa->coef; - double *obj = csa->obj; - double zeta = csa->zeta; - int i, j; - for (i = 1; i <= m; i++) - coef[i] = 0.0; - for (j = 1; j <= n; j++) - coef[m+j] = zeta * obj[j]; - return; -} - -/*********************************************************************** -* check_stab - check numerical stability of basic solution -* -* If the current basic solution is primal feasible (or pseudo feasible -* on phase I) within a tolerance, this routine returns zero, otherwise -* it returns non-zero. */ - -static int check_stab(struct csa *csa, double tol_bnd) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - char *type = csa->type; - double *lb = csa->lb; - double *ub = csa->ub; - double *coef = csa->coef; - int *head = csa->head; - int phase = csa->phase; - double *bbar = csa->bbar; - int i, k; - double eps; - /* walk through the list of basic variables */ - for (i = 1; i <= m; i++) - { k = head[i]; /* x[k] = xB[i] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (phase == 1 && coef[k] < 0.0) - { /* x[k] must not be greater than its lower bound */ -#ifdef GLP_DEBUG - xassert(type[k] == GLP_LO || type[k] == GLP_DB || - type[k] == GLP_FX); -#endif - eps = tol_bnd * (1.0 + kappa * fabs(lb[k])); - if (bbar[i] > lb[k] + eps) return 1; - } - else if (phase == 1 && coef[k] > 0.0) - { /* x[k] must not be less than its upper bound */ -#ifdef GLP_DEBUG - xassert(type[k] == GLP_UP || type[k] == GLP_DB || - type[k] == GLP_FX); -#endif - eps = tol_bnd * (1.0 + kappa * fabs(ub[k])); - if (bbar[i] < ub[k] - eps) return 1; - } - else - { /* either phase = 1 and coef[k] = 0, or phase = 2 */ - if (type[k] == GLP_LO || type[k] == GLP_DB || - type[k] == GLP_FX) - { /* x[k] must not be less than its lower bound */ - eps = tol_bnd * (1.0 + kappa * fabs(lb[k])); - if (bbar[i] < lb[k] - eps) return 1; - } - if (type[k] == GLP_UP || type[k] == GLP_DB || - type[k] == GLP_FX) - { /* x[k] must not be greater then its upper bound */ - eps = tol_bnd * (1.0 + kappa * fabs(ub[k])); - if (bbar[i] > ub[k] + eps) return 1; - } - } - } - /* basic solution is primal feasible within a tolerance */ - return 0; -} - -/*********************************************************************** -* check_feas - check primal feasibility of basic solution -* -* If the current basic solution is primal feasible within a tolerance, -* this routine returns zero, otherwise it returns non-zero. */ - -static int check_feas(struct csa *csa, double tol_bnd) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; - char *type = csa->type; -#endif - double *lb = csa->lb; - double *ub = csa->ub; - double *coef = csa->coef; - int *head = csa->head; - double *bbar = csa->bbar; - int i, k; - double eps; - xassert(csa->phase == 1); - /* walk through the list of basic variables */ - for (i = 1; i <= m; i++) - { k = head[i]; /* x[k] = xB[i] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (coef[k] < 0.0) - { /* check if x[k] still violates its lower bound */ -#ifdef GLP_DEBUG - xassert(type[k] == GLP_LO || type[k] == GLP_DB || - type[k] == GLP_FX); -#endif - eps = tol_bnd * (1.0 + kappa * fabs(lb[k])); - if (bbar[i] < lb[k] - eps) return 1; - } - else if (coef[k] > 0.0) - { /* check if x[k] still violates its upper bound */ -#ifdef GLP_DEBUG - xassert(type[k] == GLP_UP || type[k] == GLP_DB || - type[k] == GLP_FX); -#endif - eps = tol_bnd * (1.0 + kappa * fabs(ub[k])); - if (bbar[i] > ub[k] + eps) return 1; - } - } - /* basic solution is primal feasible within a tolerance */ - return 0; -} - -/*********************************************************************** -* eval_obj - compute original objective function -* -* This routine computes the current value of the original objective -* function. */ - -static double eval_obj(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - double *obj = csa->obj; - int *head = csa->head; - double *bbar = csa->bbar; - int i, j, k; - double sum; - sum = obj[0]; - /* walk through the list of basic variables */ - for (i = 1; i <= m; i++) - { k = head[i]; /* x[k] = xB[i] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (k > m) - sum += obj[k-m] * bbar[i]; - } - /* walk through the list of non-basic variables */ - for (j = 1; j <= n; j++) - { k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (k > m) - sum += obj[k-m] * get_xN(csa, j); - } - return sum; -} - -/*********************************************************************** -* display - display the search progress -* -* This routine displays some information about the search progress -* that includes: -* -* the search phase; -* -* the number of simplex iterations performed by the solver; -* -* the original objective value; -* -* the sum of (scaled) primal infeasibilities; -* -* the number of basic fixed variables. */ - -static void display(struct csa *csa, const glp_smcp *parm, int spec) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - char *type = csa->type; - double *lb = csa->lb; - double *ub = csa->ub; - int phase = csa->phase; - int *head = csa->head; - double *bbar = csa->bbar; - int i, k, cnt; - double sum; - if (parm->msg_lev < GLP_MSG_ON) goto skip; - if (parm->out_dly > 0 && - 1000.0 * xdifftime(xtime(), csa->tm_beg) < parm->out_dly) - goto skip; - if (csa->it_cnt == csa->it_dpy) goto skip; - if (!spec && csa->it_cnt % parm->out_frq != 0) goto skip; - /* compute the sum of primal infeasibilities and determine the - number of basic fixed variables */ - sum = 0.0, cnt = 0; - for (i = 1; i <= m; i++) - { k = head[i]; /* x[k] = xB[i] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (type[k] == GLP_LO || type[k] == GLP_DB || - type[k] == GLP_FX) - { /* x[k] has lower bound */ - if (bbar[i] < lb[k]) - sum += (lb[k] - bbar[i]); - } - if (type[k] == GLP_UP || type[k] == GLP_DB || - type[k] == GLP_FX) - { /* x[k] has upper bound */ - if (bbar[i] > ub[k]) - sum += (bbar[i] - ub[k]); - } - if (type[k] == GLP_FX) cnt++; - } - xprintf("%c%6d: obj = %17.9e infeas = %10.3e (%d)\n", - phase == 1 ? ' ' : '*', csa->it_cnt, eval_obj(csa), sum, cnt); - csa->it_dpy = csa->it_cnt; -skip: return; -} - -/*********************************************************************** -* store_sol - store basic solution back to the problem object -* -* This routine stores basic solution components back to the problem -* object. */ - -static void store_sol(struct csa *csa, glp_prob *lp, int p_stat, - int d_stat, int ray) -{ int m = csa->m; - int n = csa->n; - double zeta = csa->zeta; - int *head = csa->head; - char *stat = csa->stat; - double *bbar = csa->bbar; - double *cbar = csa->cbar; - int i, j, k; -#ifdef GLP_DEBUG - xassert(lp->m == m); - xassert(lp->n == n); -#endif - /* basis factorization */ -#ifdef GLP_DEBUG - xassert(!lp->valid && lp->bfd == NULL); - xassert(csa->valid && csa->bfd != NULL); -#endif - lp->valid = 1, csa->valid = 0; - lp->bfd = csa->bfd, csa->bfd = NULL; - memcpy(&lp->head[1], &head[1], m * sizeof(int)); - /* basic solution status */ - lp->pbs_stat = p_stat; - lp->dbs_stat = d_stat; - /* objective function value */ - lp->obj_val = eval_obj(csa); - /* simplex iteration count */ - lp->it_cnt = csa->it_cnt; - /* unbounded ray */ - lp->some = ray; - /* basic variables */ - for (i = 1; i <= m; i++) - { k = head[i]; /* x[k] = xB[i] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (k <= m) - { GLPROW *row = lp->row[k]; - row->stat = GLP_BS; - row->bind = i; - row->prim = bbar[i] / row->rii; - row->dual = 0.0; - } - else - { GLPCOL *col = lp->col[k-m]; - col->stat = GLP_BS; - col->bind = i; - col->prim = bbar[i] * col->sjj; - col->dual = 0.0; - } - } - /* non-basic variables */ - for (j = 1; j <= n; j++) - { k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (k <= m) - { GLPROW *row = lp->row[k]; - row->stat = stat[j]; - row->bind = 0; -#if 0 - row->prim = get_xN(csa, j) / row->rii; -#else - switch (stat[j]) - { case GLP_NL: - row->prim = row->lb; break; - case GLP_NU: - row->prim = row->ub; break; - case GLP_NF: - row->prim = 0.0; break; - case GLP_NS: - row->prim = row->lb; break; - default: - xassert(stat != stat); - } -#endif - row->dual = (cbar[j] * row->rii) / zeta; - } - else - { GLPCOL *col = lp->col[k-m]; - col->stat = stat[j]; - col->bind = 0; -#if 0 - col->prim = get_xN(csa, j) * col->sjj; -#else - switch (stat[j]) - { case GLP_NL: - col->prim = col->lb; break; - case GLP_NU: - col->prim = col->ub; break; - case GLP_NF: - col->prim = 0.0; break; - case GLP_NS: - col->prim = col->lb; break; - default: - xassert(stat != stat); - } -#endif - col->dual = (cbar[j] / col->sjj) / zeta; - } - } - return; -} - -/*********************************************************************** -* free_csa - deallocate common storage area -* -* This routine frees all the memory allocated to arrays in the common -* storage area (CSA). */ - -static void free_csa(struct csa *csa) -{ xfree(csa->type); - xfree(csa->lb); - xfree(csa->ub); - xfree(csa->coef); - xfree(csa->obj); - xfree(csa->A_ptr); - xfree(csa->A_ind); - xfree(csa->A_val); - xfree(csa->head); - xfree(csa->stat); - xfree(csa->N_ptr); - xfree(csa->N_len); - xfree(csa->N_ind); - xfree(csa->N_val); - xfree(csa->bbar); - xfree(csa->cbar); - xfree(csa->refsp); - xfree(csa->gamma); - xfree(csa->tcol_ind); - xfree(csa->tcol_vec); - xfree(csa->trow_ind); - xfree(csa->trow_vec); - xfree(csa->work1); - xfree(csa->work2); - xfree(csa->work3); - xfree(csa->work4); - xfree(csa); - return; -} - -/*********************************************************************** -* spx_primal - core LP solver based on the primal simplex method -* -* SYNOPSIS -* -* #include "glpspx.h" -* int spx_primal(glp_prob *lp, const glp_smcp *parm); -* -* DESCRIPTION -* -* The routine spx_primal is a core LP solver based on the two-phase -* primal simplex method. -* -* RETURNS -* -* 0 LP instance has been successfully solved. -* -* GLP_EITLIM -* Iteration limit has been exhausted. -* -* GLP_ETMLIM -* Time limit has been exhausted. -* -* GLP_EFAIL -* The solver failed to solve LP instance. */ - -int spx_primal(glp_prob *lp, const glp_smcp *parm) -{ struct csa *csa; - int binv_st = 2; - /* status of basis matrix factorization: - 0 - invalid; 1 - just computed; 2 - updated */ - int bbar_st = 0; - /* status of primal values of basic variables: - 0 - invalid; 1 - just computed; 2 - updated */ - int cbar_st = 0; - /* status of reduced costs of non-basic variables: - 0 - invalid; 1 - just computed; 2 - updated */ - int rigorous = 0; - /* rigorous mode flag; this flag is used to enable iterative - refinement on computing pivot rows and columns of the simplex - table */ - int check = 0; - int p_stat, d_stat, ret; - /* allocate and initialize the common storage area */ - csa = alloc_csa(lp); - init_csa(csa, lp); - if (parm->msg_lev >= GLP_MSG_DBG) - xprintf("Objective scale factor = %g\n", csa->zeta); -loop: /* main loop starts here */ - /* compute factorization of the basis matrix */ - if (binv_st == 0) - { ret = invert_B(csa); - if (ret != 0) - { if (parm->msg_lev >= GLP_MSG_ERR) - { xprintf("Error: unable to factorize the basis matrix (%d" - ")\n", ret); - xprintf("Sorry, basis recovery procedure not implemented" - " yet\n"); - } - xassert(!lp->valid && lp->bfd == NULL); - lp->bfd = csa->bfd, csa->bfd = NULL; - lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; - lp->obj_val = 0.0; - lp->it_cnt = csa->it_cnt; - lp->some = 0; - ret = GLP_EFAIL; - goto done; - } - csa->valid = 1; - binv_st = 1; /* just computed */ - /* invalidate basic solution components */ - bbar_st = cbar_st = 0; - } - /* compute primal values of basic variables */ - if (bbar_st == 0) - { eval_bbar(csa); - bbar_st = 1; /* just computed */ - /* determine the search phase, if not determined yet */ - if (csa->phase == 0) - { if (set_aux_obj(csa, parm->tol_bnd) > 0) - { /* current basic solution is primal infeasible */ - /* start to minimize the sum of infeasibilities */ - csa->phase = 1; - } - else - { /* current basic solution is primal feasible */ - /* start to minimize the original objective function */ - set_orig_obj(csa); - csa->phase = 2; - } - xassert(check_stab(csa, parm->tol_bnd) == 0); - /* working objective coefficients have been changed, so - invalidate reduced costs */ - cbar_st = 0; - display(csa, parm, 1); - } - /* make sure that the current basic solution remains primal - feasible (or pseudo feasible on phase I) */ - if (check_stab(csa, parm->tol_bnd)) - { /* there are excessive bound violations due to round-off - errors */ - if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("Warning: numerical instability (primal simplex," - " phase %s)\n", csa->phase == 1 ? "I" : "II"); - /* restart the search */ - csa->phase = 0; - binv_st = 0; - rigorous = 5; - goto loop; - } - } - xassert(csa->phase == 1 || csa->phase == 2); - /* on phase I we do not need to wait until the current basic - solution becomes dual feasible; it is sufficient to make sure - that no basic variable violates its bounds */ - if (csa->phase == 1 && !check_feas(csa, parm->tol_bnd)) - { /* the current basis is primal feasible; switch to phase II */ - csa->phase = 2; - set_orig_obj(csa); - cbar_st = 0; - display(csa, parm, 1); - } - /* compute reduced costs of non-basic variables */ - if (cbar_st == 0) - { eval_cbar(csa); - cbar_st = 1; /* just computed */ - } - /* redefine the reference space, if required */ - switch (parm->pricing) - { case GLP_PT_STD: - break; - case GLP_PT_PSE: - if (csa->refct == 0) reset_refsp(csa); - break; - default: - xassert(parm != parm); - } - /* at this point the basis factorization and all basic solution - components are valid */ - xassert(binv_st && bbar_st && cbar_st); - /* check accuracy of current basic solution components (only for - debugging) */ - if (check) - { double e_bbar = err_in_bbar(csa); - double e_cbar = err_in_cbar(csa); - double e_gamma = - (parm->pricing == GLP_PT_PSE ? err_in_gamma(csa) : 0.0); - xprintf("e_bbar = %10.3e; e_cbar = %10.3e; e_gamma = %10.3e\n", - e_bbar, e_cbar, e_gamma); - xassert(e_bbar <= 1e-5 && e_cbar <= 1e-5 && e_gamma <= 1e-3); - } - /* check if the iteration limit has been exhausted */ - if (parm->it_lim < INT_MAX && - csa->it_cnt - csa->it_beg >= parm->it_lim) - { if (bbar_st != 1 || csa->phase == 2 && cbar_st != 1) - { if (bbar_st != 1) bbar_st = 0; - if (csa->phase == 2 && cbar_st != 1) cbar_st = 0; - goto loop; - } - display(csa, parm, 1); - if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("ITERATION LIMIT EXCEEDED; SEARCH TERMINATED\n"); - switch (csa->phase) - { case 1: - p_stat = GLP_INFEAS; - set_orig_obj(csa); - eval_cbar(csa); - break; - case 2: - p_stat = GLP_FEAS; - break; - default: - xassert(csa != csa); - } - chuzc(csa, parm->tol_dj); - d_stat = (csa->q == 0 ? GLP_FEAS : GLP_INFEAS); - store_sol(csa, lp, p_stat, d_stat, 0); - ret = GLP_EITLIM; - goto done; - } - /* check if the time limit has been exhausted */ - if (parm->tm_lim < INT_MAX && - 1000.0 * xdifftime(xtime(), csa->tm_beg) >= parm->tm_lim) - { if (bbar_st != 1 || csa->phase == 2 && cbar_st != 1) - { if (bbar_st != 1) bbar_st = 0; - if (csa->phase == 2 && cbar_st != 1) cbar_st = 0; - goto loop; - } - display(csa, parm, 1); - if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); - switch (csa->phase) - { case 1: - p_stat = GLP_INFEAS; - set_orig_obj(csa); - eval_cbar(csa); - break; - case 2: - p_stat = GLP_FEAS; - break; - default: - xassert(csa != csa); - } - chuzc(csa, parm->tol_dj); - d_stat = (csa->q == 0 ? GLP_FEAS : GLP_INFEAS); - store_sol(csa, lp, p_stat, d_stat, 0); - ret = GLP_ETMLIM; - goto done; - } - /* display the search progress */ - display(csa, parm, 0); - /* choose non-basic variable xN[q] */ - chuzc(csa, parm->tol_dj); - if (csa->q == 0) - { if (bbar_st != 1 || cbar_st != 1) - { if (bbar_st != 1) bbar_st = 0; - if (cbar_st != 1) cbar_st = 0; - goto loop; - } - display(csa, parm, 1); - switch (csa->phase) - { case 1: - if (parm->msg_lev >= GLP_MSG_ALL) -#if 0 /* 13/VII-2013; suggested by Prof. Fischetti */ - xprintf("PROBLEM HAS NO FEASIBLE SOLUTION\n"); -#else - xprintf("LP HAS NO PRIMAL FEASIBLE SOLUTION\n"); -#endif - p_stat = GLP_NOFEAS; - set_orig_obj(csa); - eval_cbar(csa); - chuzc(csa, parm->tol_dj); - d_stat = (csa->q == 0 ? GLP_FEAS : GLP_INFEAS); - break; - case 2: - if (parm->msg_lev >= GLP_MSG_ALL) -#if 0 /* 13/VII-2013; suggested by Prof. Fischetti */ - xprintf("OPTIMAL SOLUTION FOUND\n"); -#else - xprintf("OPTIMAL LP SOLUTION FOUND\n"); -#endif - p_stat = d_stat = GLP_FEAS; - break; - default: - xassert(csa != csa); - } - store_sol(csa, lp, p_stat, d_stat, 0); - ret = 0; - goto done; - } - /* compute pivot column of the simplex table */ - eval_tcol(csa); - if (rigorous) refine_tcol(csa); - sort_tcol(csa, parm->tol_piv); - /* check accuracy of the reduced cost of xN[q] */ - { double d1 = csa->cbar[csa->q]; /* less accurate */ - double d2 = reeval_cost(csa); /* more accurate */ - xassert(d1 != 0.0); - if (fabs(d1 - d2) > 1e-5 * (1.0 + fabs(d2)) || - !(d1 < 0.0 && d2 < 0.0 || d1 > 0.0 && d2 > 0.0)) - { if (parm->msg_lev >= GLP_MSG_DBG) - xprintf("d1 = %.12g; d2 = %.12g\n", d1, d2); - if (cbar_st != 1 || !rigorous) - { if (cbar_st != 1) cbar_st = 0; - rigorous = 5; - goto loop; - } - } - /* replace cbar[q] by more accurate value keeping its sign */ - if (d1 > 0.0) - csa->cbar[csa->q] = (d2 > 0.0 ? d2 : +DBL_EPSILON); - else - csa->cbar[csa->q] = (d2 < 0.0 ? d2 : -DBL_EPSILON); - } - /* choose basic variable xB[p] */ - switch (parm->r_test) - { case GLP_RT_STD: - chuzr(csa, 0.0); - break; - case GLP_RT_HAR: - chuzr(csa, 0.30 * parm->tol_bnd); - break; - default: - xassert(parm != parm); - } - if (csa->p == 0) - { if (bbar_st != 1 || cbar_st != 1 || !rigorous) - { if (bbar_st != 1) bbar_st = 0; - if (cbar_st != 1) cbar_st = 0; - rigorous = 1; - goto loop; - } - display(csa, parm, 1); - switch (csa->phase) - { case 1: - if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("Error: unable to choose basic variable on ph" - "ase I\n"); - xassert(!lp->valid && lp->bfd == NULL); - lp->bfd = csa->bfd, csa->bfd = NULL; - lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; - lp->obj_val = 0.0; - lp->it_cnt = csa->it_cnt; - lp->some = 0; - ret = GLP_EFAIL; - break; - case 2: - if (parm->msg_lev >= GLP_MSG_ALL) -#if 0 /* 13/VII-2013; suggested by Prof. Fischetti */ - xprintf("PROBLEM HAS UNBOUNDED SOLUTION\n"); -#else - xprintf("LP HAS UNBOUNDED PRIMAL SOLUTION\n"); -#endif - store_sol(csa, lp, GLP_FEAS, GLP_NOFEAS, - csa->head[csa->m+csa->q]); - ret = 0; - break; - default: - xassert(csa != csa); - } - goto done; - } - /* check if the pivot element is acceptable */ - if (csa->p > 0) - { double piv = csa->tcol_vec[csa->p]; - double eps = 1e-5 * (1.0 + 0.01 * csa->tcol_max); - if (fabs(piv) < eps) - { if (parm->msg_lev >= GLP_MSG_DBG) - xprintf("piv = %.12g; eps = %g\n", piv, eps); - if (!rigorous) - { rigorous = 5; - goto loop; - } - } - } - /* now xN[q] and xB[p] have been chosen anyhow */ - /* compute pivot row of the simplex table */ - if (csa->p > 0) - { double *rho = csa->work4; - eval_rho(csa, rho); - if (rigorous) refine_rho(csa, rho); - eval_trow(csa, rho); - } - /* accuracy check based on the pivot element */ - if (csa->p > 0) - { double piv1 = csa->tcol_vec[csa->p]; /* more accurate */ - double piv2 = csa->trow_vec[csa->q]; /* less accurate */ - xassert(piv1 != 0.0); - if (fabs(piv1 - piv2) > 1e-8 * (1.0 + fabs(piv1)) || - !(piv1 > 0.0 && piv2 > 0.0 || piv1 < 0.0 && piv2 < 0.0)) - { if (parm->msg_lev >= GLP_MSG_DBG) - xprintf("piv1 = %.12g; piv2 = %.12g\n", piv1, piv2); - if (binv_st != 1 || !rigorous) - { if (binv_st != 1) binv_st = 0; - rigorous = 5; - goto loop; - } - /* use more accurate version in the pivot row */ - if (csa->trow_vec[csa->q] == 0.0) - { csa->trow_nnz++; - xassert(csa->trow_nnz <= csa->n); - csa->trow_ind[csa->trow_nnz] = csa->q; - } - csa->trow_vec[csa->q] = piv1; - } - } - /* update primal values of basic variables */ - update_bbar(csa); - bbar_st = 2; /* updated */ - /* update reduced costs of non-basic variables */ - if (csa->p > 0) - { update_cbar(csa); - cbar_st = 2; /* updated */ - /* on phase I objective coefficient of xB[p] in the adjacent - basis becomes zero */ - if (csa->phase == 1) - { int k = csa->head[csa->p]; /* x[k] = xB[p] -> xN[q] */ - csa->cbar[csa->q] -= csa->coef[k]; - csa->coef[k] = 0.0; - } - } - /* update steepest edge coefficients */ - if (csa->p > 0) - { switch (parm->pricing) - { case GLP_PT_STD: - break; - case GLP_PT_PSE: - if (csa->refct > 0) update_gamma(csa); - break; - default: - xassert(parm != parm); - } - } - /* update factorization of the basis matrix */ - if (csa->p > 0) - { ret = update_B(csa, csa->p, csa->head[csa->m+csa->q]); - if (ret == 0) - binv_st = 2; /* updated */ - else - { csa->valid = 0; - binv_st = 0; /* invalid */ - } - } - /* update matrix N */ - if (csa->p > 0) - { del_N_col(csa, csa->q, csa->head[csa->m+csa->q]); - if (csa->type[csa->head[csa->p]] != GLP_FX) - add_N_col(csa, csa->q, csa->head[csa->p]); - } - /* change the basis header */ - change_basis(csa); - /* iteration complete */ - csa->it_cnt++; - if (rigorous > 0) rigorous--; - goto loop; -done: /* deallocate the common storage area */ - free_csa(csa); - /* return to the calling program */ - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpspx02.c b/resources/3rdparty/glpk-4.53/src/glpspx02.c deleted file mode 100644 index 685c221a0..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpspx02.c +++ /dev/null @@ -1,3118 +0,0 @@ -/* glpspx02.c (dual simplex method) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpspx.h" - -#define GLP_DEBUG 1 - -#if 0 -#define GLP_LONG_STEP 1 -#endif - -struct csa -{ /* common storage area */ - /*--------------------------------------------------------------*/ - /* LP data */ - int m; - /* number of rows (auxiliary variables), m > 0 */ - int n; - /* number of columns (structural variables), n > 0 */ - char *type; /* char type[1+m+n]; */ - /* type[0] is not used; - type[k], 1 <= k <= m+n, is the type of variable x[k]: - GLP_FR - free variable - GLP_LO - variable with lower bound - GLP_UP - variable with upper bound - GLP_DB - double-bounded variable - GLP_FX - fixed variable */ - double *lb; /* double lb[1+m+n]; */ - /* lb[0] is not used; - lb[k], 1 <= k <= m+n, is an lower bound of variable x[k]; - if x[k] has no lower bound, lb[k] is zero */ - double *ub; /* double ub[1+m+n]; */ - /* ub[0] is not used; - ub[k], 1 <= k <= m+n, is an upper bound of variable x[k]; - if x[k] has no upper bound, ub[k] is zero; - if x[k] is of fixed type, ub[k] is the same as lb[k] */ - double *coef; /* double coef[1+m+n]; */ - /* coef[0] is not used; - coef[k], 1 <= k <= m+n, is an objective coefficient at - variable x[k] */ - /*--------------------------------------------------------------*/ - /* original bounds of variables */ - char *orig_type; /* char orig_type[1+m+n]; */ - double *orig_lb; /* double orig_lb[1+m+n]; */ - double *orig_ub; /* double orig_ub[1+m+n]; */ - /*--------------------------------------------------------------*/ - /* original objective function */ - double *obj; /* double obj[1+n]; */ - /* obj[0] is a constant term of the original objective function; - obj[j], 1 <= j <= n, is an original objective coefficient at - structural variable x[m+j] */ - double zeta; - /* factor used to scale original objective coefficients; its - sign defines original optimization direction: zeta > 0 means - minimization, zeta < 0 means maximization */ - /*--------------------------------------------------------------*/ - /* constraint matrix A; it has m rows and n columns and is stored - by columns */ - int *A_ptr; /* int A_ptr[1+n+1]; */ - /* A_ptr[0] is not used; - A_ptr[j], 1 <= j <= n, is starting position of j-th column in - arrays A_ind and A_val; note that A_ptr[1] is always 1; - A_ptr[n+1] indicates the position after the last element in - arrays A_ind and A_val */ - int *A_ind; /* int A_ind[A_ptr[n+1]]; */ - /* row indices */ - double *A_val; /* double A_val[A_ptr[n+1]]; */ - /* non-zero element values */ -#if 1 /* 06/IV-2009 */ - /* constraint matrix A stored by rows */ - int *AT_ptr; /* int AT_ptr[1+m+1]; */ - /* AT_ptr[0] is not used; - AT_ptr[i], 1 <= i <= m, is starting position of i-th row in - arrays AT_ind and AT_val; note that AT_ptr[1] is always 1; - AT_ptr[m+1] indicates the position after the last element in - arrays AT_ind and AT_val */ - int *AT_ind; /* int AT_ind[AT_ptr[m+1]]; */ - /* column indices */ - double *AT_val; /* double AT_val[AT_ptr[m+1]]; */ - /* non-zero element values */ -#endif - /*--------------------------------------------------------------*/ - /* basis header */ - int *head; /* int head[1+m+n]; */ - /* head[0] is not used; - head[i], 1 <= i <= m, is the ordinal number of basic variable - xB[i]; head[i] = k means that xB[i] = x[k] and i-th column of - matrix B is k-th column of matrix (I|-A); - head[m+j], 1 <= j <= n, is the ordinal number of non-basic - variable xN[j]; head[m+j] = k means that xN[j] = x[k] and j-th - column of matrix N is k-th column of matrix (I|-A) */ -#if 1 /* 06/IV-2009 */ - int *bind; /* int bind[1+m+n]; */ - /* bind[0] is not used; - bind[k], 1 <= k <= m+n, is the position of k-th column of the - matrix (I|-A) in the matrix (B|N); that is, bind[k] = k' means - that head[k'] = k */ -#endif - char *stat; /* char stat[1+n]; */ - /* stat[0] is not used; - stat[j], 1 <= j <= n, is the status of non-basic variable - xN[j], which defines its active bound: - GLP_NL - lower bound is active - GLP_NU - upper bound is active - GLP_NF - free variable - GLP_NS - fixed variable */ - /*--------------------------------------------------------------*/ - /* matrix B is the basis matrix; it is composed from columns of - the augmented constraint matrix (I|-A) corresponding to basic - variables and stored in a factorized (invertable) form */ - int valid; - /* factorization is valid only if this flag is set */ - BFD *bfd; /* BFD bfd[1:m,1:m]; */ - /* factorized (invertable) form of the basis matrix */ -#if 0 /* 06/IV-2009 */ - /*--------------------------------------------------------------*/ - /* matrix N is a matrix composed from columns of the augmented - constraint matrix (I|-A) corresponding to non-basic variables - except fixed ones; it is stored by rows and changes every time - the basis changes */ - int *N_ptr; /* int N_ptr[1+m+1]; */ - /* N_ptr[0] is not used; - N_ptr[i], 1 <= i <= m, is starting position of i-th row in - arrays N_ind and N_val; note that N_ptr[1] is always 1; - N_ptr[m+1] indicates the position after the last element in - arrays N_ind and N_val */ - int *N_len; /* int N_len[1+m]; */ - /* N_len[0] is not used; - N_len[i], 1 <= i <= m, is length of i-th row (0 to n) */ - int *N_ind; /* int N_ind[N_ptr[m+1]]; */ - /* column indices */ - double *N_val; /* double N_val[N_ptr[m+1]]; */ - /* non-zero element values */ -#endif - /*--------------------------------------------------------------*/ - /* working parameters */ - int phase; - /* search phase: - 0 - not determined yet - 1 - search for dual feasible solution - 2 - search for optimal solution */ -#if 0 /* 10/VI-2013 */ - glp_long tm_beg; -#else - double tm_beg; -#endif - /* time value at the beginning of the search */ - int it_beg; - /* simplex iteration count at the beginning of the search */ - int it_cnt; - /* simplex iteration count; it increases by one every time the - basis changes */ - int it_dpy; - /* simplex iteration count at the most recent display output */ - /*--------------------------------------------------------------*/ - /* basic solution components */ - double *bbar; /* double bbar[1+m]; */ - /* bbar[0] is not used on phase I; on phase II it is the current - value of the original objective function; - bbar[i], 1 <= i <= m, is primal value of basic variable xB[i] - (if xB[i] is free, its primal value is not updated) */ - double *cbar; /* double cbar[1+n]; */ - /* cbar[0] is not used; - cbar[j], 1 <= j <= n, is reduced cost of non-basic variable - xN[j] (if xN[j] is fixed, its reduced cost is not updated) */ - /*--------------------------------------------------------------*/ - /* the following pricing technique options may be used: - GLP_PT_STD - standard ("textbook") pricing; - GLP_PT_PSE - projected steepest edge; - GLP_PT_DVX - Devex pricing (not implemented yet); - in case of GLP_PT_STD the reference space is not used, and all - steepest edge coefficients are set to 1 */ - int refct; - /* this count is set to an initial value when the reference space - is defined and decreases by one every time the basis changes; - once this count reaches zero, the reference space is redefined - again */ - char *refsp; /* char refsp[1+m+n]; */ - /* refsp[0] is not used; - refsp[k], 1 <= k <= m+n, is the flag which means that variable - x[k] belongs to the current reference space */ - double *gamma; /* double gamma[1+m]; */ - /* gamma[0] is not used; - gamma[i], 1 <= i <= n, is the steepest edge coefficient for - basic variable xB[i]; if xB[i] is free, gamma[i] is not used - and just set to 1 */ - /*--------------------------------------------------------------*/ - /* basic variable xB[p] chosen to leave the basis */ - int p; - /* index of the basic variable xB[p] chosen, 1 <= p <= m; - if the set of eligible basic variables is empty (i.e. if the - current basic solution is primal feasible within a tolerance) - and thus no variable has been chosen, p is set to 0 */ - double delta; - /* change of xB[p] in the adjacent basis; - delta > 0 means that xB[p] violates its lower bound and will - increase to achieve it in the adjacent basis; - delta < 0 means that xB[p] violates its upper bound and will - decrease to achieve it in the adjacent basis */ - /*--------------------------------------------------------------*/ - /* pivot row of the simplex table corresponding to basic variable - xB[p] chosen is the following vector: - T' * e[p] = - N' * inv(B') * e[p] = - N' * rho, - where B' is a matrix transposed to the current basis matrix, - N' is a matrix, whose rows are columns of the matrix (I|-A) - corresponding to non-basic non-fixed variables */ - int trow_nnz; - /* number of non-zero components, 0 <= nnz <= n */ - int *trow_ind; /* int trow_ind[1+n]; */ - /* trow_ind[0] is not used; - trow_ind[t], 1 <= t <= nnz, is an index of non-zero component, - i.e. trow_ind[t] = j means that trow_vec[j] != 0 */ - double *trow_vec; /* int trow_vec[1+n]; */ - /* trow_vec[0] is not used; - trow_vec[j], 1 <= j <= n, is a numeric value of j-th component - of the row */ - double trow_max; - /* infinity (maximum) norm of the row (max |trow_vec[j]|) */ - int trow_num; - /* number of significant non-zero components, which means that: - |trow_vec[j]| >= eps for j in trow_ind[1,...,num], - |tcol_vec[j]| < eps for j in trow_ind[num+1,...,nnz], - where eps is a pivot tolerance */ - /*--------------------------------------------------------------*/ -#ifdef GLP_LONG_STEP /* 07/IV-2009 */ - int nbps; - /* number of breakpoints, 0 <= nbps <= n */ - struct bkpt - { int j; - /* index of non-basic variable xN[j], 1 <= j <= n */ - double t; - /* value of dual ray parameter at breakpoint, t >= 0 */ - double dz; - /* dz = zeta(t = t[k]) - zeta(t = 0) */ - } *bkpt; /* struct bkpt bkpt[1+n]; */ - /* bkpt[0] is not used; - bkpt[k], 1 <= k <= nbps, is k-th breakpoint of the dual - objective */ -#endif - /*--------------------------------------------------------------*/ - /* non-basic variable xN[q] chosen to enter the basis */ - int q; - /* index of the non-basic variable xN[q] chosen, 1 <= q <= n; - if no variable has been chosen, q is set to 0 */ - double new_dq; - /* reduced cost of xN[q] in the adjacent basis (it is the change - of lambdaB[p]) */ - /*--------------------------------------------------------------*/ - /* pivot column of the simplex table corresponding to non-basic - variable xN[q] chosen is the following vector: - T * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q], - where B is the current basis matrix, N[q] is a column of the - matrix (I|-A) corresponding to xN[q] */ - int tcol_nnz; - /* number of non-zero components, 0 <= nnz <= m */ - int *tcol_ind; /* int tcol_ind[1+m]; */ - /* tcol_ind[0] is not used; - tcol_ind[t], 1 <= t <= nnz, is an index of non-zero component, - i.e. tcol_ind[t] = i means that tcol_vec[i] != 0 */ - double *tcol_vec; /* double tcol_vec[1+m]; */ - /* tcol_vec[0] is not used; - tcol_vec[i], 1 <= i <= m, is a numeric value of i-th component - of the column */ - /*--------------------------------------------------------------*/ - /* working arrays */ - double *work1; /* double work1[1+m]; */ - double *work2; /* double work2[1+m]; */ - double *work3; /* double work3[1+m]; */ - double *work4; /* double work4[1+m]; */ -}; - -static const double kappa = 0.10; - -/*********************************************************************** -* alloc_csa - allocate common storage area -* -* This routine allocates all arrays in the common storage area (CSA) -* and returns a pointer to the CSA. */ - -static struct csa *alloc_csa(glp_prob *lp) -{ struct csa *csa; - int m = lp->m; - int n = lp->n; - int nnz = lp->nnz; - csa = xmalloc(sizeof(struct csa)); - xassert(m > 0 && n > 0); - csa->m = m; - csa->n = n; - csa->type = xcalloc(1+m+n, sizeof(char)); - csa->lb = xcalloc(1+m+n, sizeof(double)); - csa->ub = xcalloc(1+m+n, sizeof(double)); - csa->coef = xcalloc(1+m+n, sizeof(double)); - csa->orig_type = xcalloc(1+m+n, sizeof(char)); - csa->orig_lb = xcalloc(1+m+n, sizeof(double)); - csa->orig_ub = xcalloc(1+m+n, sizeof(double)); - csa->obj = xcalloc(1+n, sizeof(double)); - csa->A_ptr = xcalloc(1+n+1, sizeof(int)); - csa->A_ind = xcalloc(1+nnz, sizeof(int)); - csa->A_val = xcalloc(1+nnz, sizeof(double)); -#if 1 /* 06/IV-2009 */ - csa->AT_ptr = xcalloc(1+m+1, sizeof(int)); - csa->AT_ind = xcalloc(1+nnz, sizeof(int)); - csa->AT_val = xcalloc(1+nnz, sizeof(double)); -#endif - csa->head = xcalloc(1+m+n, sizeof(int)); -#if 1 /* 06/IV-2009 */ - csa->bind = xcalloc(1+m+n, sizeof(int)); -#endif - csa->stat = xcalloc(1+n, sizeof(char)); -#if 0 /* 06/IV-2009 */ - csa->N_ptr = xcalloc(1+m+1, sizeof(int)); - csa->N_len = xcalloc(1+m, sizeof(int)); - csa->N_ind = NULL; /* will be allocated later */ - csa->N_val = NULL; /* will be allocated later */ -#endif - csa->bbar = xcalloc(1+m, sizeof(double)); - csa->cbar = xcalloc(1+n, sizeof(double)); - csa->refsp = xcalloc(1+m+n, sizeof(char)); - csa->gamma = xcalloc(1+m, sizeof(double)); - csa->trow_ind = xcalloc(1+n, sizeof(int)); - csa->trow_vec = xcalloc(1+n, sizeof(double)); -#ifdef GLP_LONG_STEP /* 07/IV-2009 */ - csa->bkpt = xcalloc(1+n, sizeof(struct bkpt)); -#endif - csa->tcol_ind = xcalloc(1+m, sizeof(int)); - csa->tcol_vec = xcalloc(1+m, sizeof(double)); - csa->work1 = xcalloc(1+m, sizeof(double)); - csa->work2 = xcalloc(1+m, sizeof(double)); - csa->work3 = xcalloc(1+m, sizeof(double)); - csa->work4 = xcalloc(1+m, sizeof(double)); - return csa; -} - -/*********************************************************************** -* init_csa - initialize common storage area -* -* This routine initializes all data structures in the common storage -* area (CSA). */ - -static void init_csa(struct csa *csa, glp_prob *lp) -{ int m = csa->m; - int n = csa->n; - char *type = csa->type; - double *lb = csa->lb; - double *ub = csa->ub; - double *coef = csa->coef; - char *orig_type = csa->orig_type; - double *orig_lb = csa->orig_lb; - double *orig_ub = csa->orig_ub; - double *obj = csa->obj; - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; -#if 1 /* 06/IV-2009 */ - int *AT_ptr = csa->AT_ptr; - int *AT_ind = csa->AT_ind; - double *AT_val = csa->AT_val; -#endif - int *head = csa->head; -#if 1 /* 06/IV-2009 */ - int *bind = csa->bind; -#endif - char *stat = csa->stat; - char *refsp = csa->refsp; - double *gamma = csa->gamma; - int i, j, k, loc; - double cmax; - /* auxiliary variables */ - for (i = 1; i <= m; i++) - { GLPROW *row = lp->row[i]; - type[i] = (char)row->type; - lb[i] = row->lb * row->rii; - ub[i] = row->ub * row->rii; - coef[i] = 0.0; - } - /* structural variables */ - for (j = 1; j <= n; j++) - { GLPCOL *col = lp->col[j]; - type[m+j] = (char)col->type; - lb[m+j] = col->lb / col->sjj; - ub[m+j] = col->ub / col->sjj; - coef[m+j] = col->coef * col->sjj; - } - /* original bounds of variables */ - memcpy(&orig_type[1], &type[1], (m+n) * sizeof(char)); - memcpy(&orig_lb[1], &lb[1], (m+n) * sizeof(double)); - memcpy(&orig_ub[1], &ub[1], (m+n) * sizeof(double)); - /* original objective function */ - obj[0] = lp->c0; - memcpy(&obj[1], &coef[m+1], n * sizeof(double)); - /* factor used to scale original objective coefficients */ - cmax = 0.0; - for (j = 1; j <= n; j++) - if (cmax < fabs(obj[j])) cmax = fabs(obj[j]); - if (cmax == 0.0) cmax = 1.0; - switch (lp->dir) - { case GLP_MIN: - csa->zeta = + 1.0 / cmax; - break; - case GLP_MAX: - csa->zeta = - 1.0 / cmax; - break; - default: - xassert(lp != lp); - } -#if 1 - if (fabs(csa->zeta) < 1.0) csa->zeta *= 1000.0; -#endif - /* scale working objective coefficients */ - for (j = 1; j <= n; j++) coef[m+j] *= csa->zeta; - /* matrix A (by columns) */ - loc = 1; - for (j = 1; j <= n; j++) - { GLPAIJ *aij; - A_ptr[j] = loc; - for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next) - { A_ind[loc] = aij->row->i; - A_val[loc] = aij->row->rii * aij->val * aij->col->sjj; - loc++; - } - } - A_ptr[n+1] = loc; - xassert(loc-1 == lp->nnz); -#if 1 /* 06/IV-2009 */ - /* matrix A (by rows) */ - loc = 1; - for (i = 1; i <= m; i++) - { GLPAIJ *aij; - AT_ptr[i] = loc; - for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) - { AT_ind[loc] = aij->col->j; - AT_val[loc] = aij->row->rii * aij->val * aij->col->sjj; - loc++; - } - } - AT_ptr[m+1] = loc; - xassert(loc-1 == lp->nnz); -#endif - /* basis header */ - xassert(lp->valid); - memcpy(&head[1], &lp->head[1], m * sizeof(int)); - k = 0; - for (i = 1; i <= m; i++) - { GLPROW *row = lp->row[i]; - if (row->stat != GLP_BS) - { k++; - xassert(k <= n); - head[m+k] = i; - stat[k] = (char)row->stat; - } - } - for (j = 1; j <= n; j++) - { GLPCOL *col = lp->col[j]; - if (col->stat != GLP_BS) - { k++; - xassert(k <= n); - head[m+k] = m + j; - stat[k] = (char)col->stat; - } - } - xassert(k == n); -#if 1 /* 06/IV-2009 */ - for (k = 1; k <= m+n; k++) - bind[head[k]] = k; -#endif - /* factorization of matrix B */ - csa->valid = 1, lp->valid = 0; - csa->bfd = lp->bfd, lp->bfd = NULL; -#if 0 /* 06/IV-2009 */ - /* matrix N (by rows) */ - alloc_N(csa); - build_N(csa); -#endif - /* working parameters */ - csa->phase = 0; - csa->tm_beg = xtime(); - csa->it_beg = csa->it_cnt = lp->it_cnt; - csa->it_dpy = -1; - /* reference space and steepest edge coefficients */ - csa->refct = 0; - memset(&refsp[1], 0, (m+n) * sizeof(char)); - for (i = 1; i <= m; i++) gamma[i] = 1.0; - return; -} - -#if 1 /* copied from primal */ -/*********************************************************************** -* invert_B - compute factorization of the basis matrix -* -* This routine computes factorization of the current basis matrix B. -* -* If the operation is successful, the routine returns zero, otherwise -* non-zero. */ - -static int inv_col(void *info, int i, int ind[], double val[]) -{ /* this auxiliary routine returns row indices and numeric values - of non-zero elements of i-th column of the basis matrix */ - struct csa *csa = info; - int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int *head = csa->head; - int k, len, ptr, t; -#ifdef GLP_DEBUG - xassert(1 <= i && i <= m); -#endif - k = head[i]; /* B[i] is k-th column of (I|-A) */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (k <= m) - { /* B[i] is k-th column of submatrix I */ - len = 1; - ind[1] = k; - val[1] = 1.0; - } - else - { /* B[i] is (k-m)-th column of submatrix (-A) */ - ptr = A_ptr[k-m]; - len = A_ptr[k-m+1] - ptr; - memcpy(&ind[1], &A_ind[ptr], len * sizeof(int)); - memcpy(&val[1], &A_val[ptr], len * sizeof(double)); - for (t = 1; t <= len; t++) val[t] = - val[t]; - } - return len; -} - -static int invert_B(struct csa *csa) -{ int ret; - ret = bfd_factorize(csa->bfd, csa->m, NULL, inv_col, csa); - csa->valid = (ret == 0); - return ret; -} -#endif - -#if 1 /* copied from primal */ -/*********************************************************************** -* update_B - update factorization of the basis matrix -* -* This routine replaces i-th column of the basis matrix B by k-th -* column of the augmented constraint matrix (I|-A) and then updates -* the factorization of B. -* -* If the factorization has been successfully updated, the routine -* returns zero, otherwise non-zero. */ - -static int update_B(struct csa *csa, int i, int k) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int ret; -#ifdef GLP_DEBUG - xassert(1 <= i && i <= m); - xassert(1 <= k && k <= m+n); -#endif - if (k <= m) - { /* new i-th column of B is k-th column of I */ - int ind[1+1]; - double val[1+1]; - ind[1] = k; - val[1] = 1.0; - xassert(csa->valid); - ret = bfd_update_it(csa->bfd, i, 0, 1, ind, val); - } - else - { /* new i-th column of B is (k-m)-th column of (-A) */ - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - double *val = csa->work1; - int beg, end, ptr, len; - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - len = 0; - for (ptr = beg; ptr < end; ptr++) - val[++len] = - A_val[ptr]; - xassert(csa->valid); - ret = bfd_update_it(csa->bfd, i, 0, len, &A_ind[beg-1], val); - } - csa->valid = (ret == 0); - return ret; -} -#endif - -#if 1 /* copied from primal */ -/*********************************************************************** -* error_ftran - compute residual vector r = h - B * x -* -* This routine computes the residual vector r = h - B * x, where B is -* the current basis matrix, h is the vector of right-hand sides, x is -* the solution vector. */ - -static void error_ftran(struct csa *csa, double h[], double x[], - double r[]) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int *head = csa->head; - int i, k, beg, end, ptr; - double temp; - /* compute the residual vector: - r = h - B * x = h - B[1] * x[1] - ... - B[m] * x[m], - where B[1], ..., B[m] are columns of matrix B */ - memcpy(&r[1], &h[1], m * sizeof(double)); - for (i = 1; i <= m; i++) - { temp = x[i]; - if (temp == 0.0) continue; - k = head[i]; /* B[i] is k-th column of (I|-A) */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (k <= m) - { /* B[i] is k-th column of submatrix I */ - r[k] -= temp; - } - else - { /* B[i] is (k-m)-th column of submatrix (-A) */ - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - r[A_ind[ptr]] += A_val[ptr] * temp; - } - } - return; -} -#endif - -#if 1 /* copied from primal */ -/*********************************************************************** -* refine_ftran - refine solution of B * x = h -* -* This routine performs one iteration to refine the solution of -* the system B * x = h, where B is the current basis matrix, h is the -* vector of right-hand sides, x is the solution vector. */ - -static void refine_ftran(struct csa *csa, double h[], double x[]) -{ int m = csa->m; - double *r = csa->work1; - double *d = csa->work1; - int i; - /* compute the residual vector r = h - B * x */ - error_ftran(csa, h, x, r); - /* compute the correction vector d = inv(B) * r */ - xassert(csa->valid); - bfd_ftran(csa->bfd, d); - /* refine the solution vector (new x) = (old x) + d */ - for (i = 1; i <= m; i++) x[i] += d[i]; - return; -} -#endif - -#if 1 /* copied from primal */ -/*********************************************************************** -* error_btran - compute residual vector r = h - B'* x -* -* This routine computes the residual vector r = h - B'* x, where B' -* is a matrix transposed to the current basis matrix, h is the vector -* of right-hand sides, x is the solution vector. */ - -static void error_btran(struct csa *csa, double h[], double x[], - double r[]) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int *head = csa->head; - int i, k, beg, end, ptr; - double temp; - /* compute the residual vector r = b - B'* x */ - for (i = 1; i <= m; i++) - { /* r[i] := b[i] - (i-th column of B)'* x */ - k = head[i]; /* B[i] is k-th column of (I|-A) */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - temp = h[i]; - if (k <= m) - { /* B[i] is k-th column of submatrix I */ - temp -= x[k]; - } - else - { /* B[i] is (k-m)-th column of submatrix (-A) */ - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - temp += A_val[ptr] * x[A_ind[ptr]]; - } - r[i] = temp; - } - return; -} -#endif - -#if 1 /* copied from primal */ -/*********************************************************************** -* refine_btran - refine solution of B'* x = h -* -* This routine performs one iteration to refine the solution of the -* system B'* x = h, where B' is a matrix transposed to the current -* basis matrix, h is the vector of right-hand sides, x is the solution -* vector. */ - -static void refine_btran(struct csa *csa, double h[], double x[]) -{ int m = csa->m; - double *r = csa->work1; - double *d = csa->work1; - int i; - /* compute the residual vector r = h - B'* x */ - error_btran(csa, h, x, r); - /* compute the correction vector d = inv(B') * r */ - xassert(csa->valid); - bfd_btran(csa->bfd, d); - /* refine the solution vector (new x) = (old x) + d */ - for (i = 1; i <= m; i++) x[i] += d[i]; - return; -} -#endif - -#if 1 /* copied from primal */ -/*********************************************************************** -* get_xN - determine current value of non-basic variable xN[j] -* -* This routine returns the current value of non-basic variable xN[j], -* which is a value of its active bound. */ - -static double get_xN(struct csa *csa, int j) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - double *lb = csa->lb; - double *ub = csa->ub; - int *head = csa->head; - char *stat = csa->stat; - int k; - double xN; -#ifdef GLP_DEBUG - xassert(1 <= j && j <= n); -#endif - k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - switch (stat[j]) - { case GLP_NL: - /* x[k] is on its lower bound */ - xN = lb[k]; break; - case GLP_NU: - /* x[k] is on its upper bound */ - xN = ub[k]; break; - case GLP_NF: - /* x[k] is free non-basic variable */ - xN = 0.0; break; - case GLP_NS: - /* x[k] is fixed non-basic variable */ - xN = lb[k]; break; - default: - xassert(stat != stat); - } - return xN; -} -#endif - -#if 1 /* copied from primal */ -/*********************************************************************** -* eval_beta - compute primal values of basic variables -* -* This routine computes current primal values of all basic variables: -* -* beta = - inv(B) * N * xN, -* -* where B is the current basis matrix, N is a matrix built of columns -* of matrix (I|-A) corresponding to non-basic variables, and xN is the -* vector of current values of non-basic variables. */ - -static void eval_beta(struct csa *csa, double beta[]) -{ int m = csa->m; - int n = csa->n; - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int *head = csa->head; - double *h = csa->work2; - int i, j, k, beg, end, ptr; - double xN; - /* compute the right-hand side vector: - h := - N * xN = - N[1] * xN[1] - ... - N[n] * xN[n], - where N[1], ..., N[n] are columns of matrix N */ - for (i = 1; i <= m; i++) - h[i] = 0.0; - for (j = 1; j <= n; j++) - { k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - /* determine current value of xN[j] */ - xN = get_xN(csa, j); - if (xN == 0.0) continue; - if (k <= m) - { /* N[j] is k-th column of submatrix I */ - h[k] -= xN; - } - else - { /* N[j] is (k-m)-th column of submatrix (-A) */ - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - h[A_ind[ptr]] += xN * A_val[ptr]; - } - } - /* solve system B * beta = h */ - memcpy(&beta[1], &h[1], m * sizeof(double)); - xassert(csa->valid); - bfd_ftran(csa->bfd, beta); - /* and refine the solution */ - refine_ftran(csa, h, beta); - return; -} -#endif - -#if 1 /* copied from primal */ -/*********************************************************************** -* eval_pi - compute vector of simplex multipliers -* -* This routine computes the vector of current simplex multipliers: -* -* pi = inv(B') * cB, -* -* where B' is a matrix transposed to the current basis matrix, cB is -* a subvector of objective coefficients at basic variables. */ - -static void eval_pi(struct csa *csa, double pi[]) -{ int m = csa->m; - double *c = csa->coef; - int *head = csa->head; - double *cB = csa->work2; - int i; - /* construct the right-hand side vector cB */ - for (i = 1; i <= m; i++) - cB[i] = c[head[i]]; - /* solve system B'* pi = cB */ - memcpy(&pi[1], &cB[1], m * sizeof(double)); - xassert(csa->valid); - bfd_btran(csa->bfd, pi); - /* and refine the solution */ - refine_btran(csa, cB, pi); - return; -} -#endif - -#if 1 /* copied from primal */ -/*********************************************************************** -* eval_cost - compute reduced cost of non-basic variable xN[j] -* -* This routine computes the current reduced cost of non-basic variable -* xN[j]: -* -* d[j] = cN[j] - N'[j] * pi, -* -* where cN[j] is the objective coefficient at variable xN[j], N[j] is -* a column of the augmented constraint matrix (I|-A) corresponding to -* xN[j], pi is the vector of simplex multipliers. */ - -static double eval_cost(struct csa *csa, double pi[], int j) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - double *coef = csa->coef; - int *head = csa->head; - int k; - double dj; -#ifdef GLP_DEBUG - xassert(1 <= j && j <= n); -#endif - k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - dj = coef[k]; - if (k <= m) - { /* N[j] is k-th column of submatrix I */ - dj -= pi[k]; - } - else - { /* N[j] is (k-m)-th column of submatrix (-A) */ - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int beg, end, ptr; - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - dj += A_val[ptr] * pi[A_ind[ptr]]; - } - return dj; -} -#endif - -#if 1 /* copied from primal */ -/*********************************************************************** -* eval_bbar - compute and store primal values of basic variables -* -* This routine computes primal values of all basic variables and then -* stores them in the solution array. */ - -static void eval_bbar(struct csa *csa) -{ eval_beta(csa, csa->bbar); - return; -} -#endif - -#if 1 /* copied from primal */ -/*********************************************************************** -* eval_cbar - compute and store reduced costs of non-basic variables -* -* This routine computes reduced costs of all non-basic variables and -* then stores them in the solution array. */ - -static void eval_cbar(struct csa *csa) -{ -#ifdef GLP_DEBUG - int m = csa->m; -#endif - int n = csa->n; -#ifdef GLP_DEBUG - int *head = csa->head; -#endif - double *cbar = csa->cbar; - double *pi = csa->work3; - int j; -#ifdef GLP_DEBUG - int k; -#endif - /* compute simplex multipliers */ - eval_pi(csa, pi); - /* compute and store reduced costs */ - for (j = 1; j <= n; j++) - { -#ifdef GLP_DEBUG - k = head[m+j]; /* x[k] = xN[j] */ - xassert(1 <= k && k <= m+n); -#endif - cbar[j] = eval_cost(csa, pi, j); - } - return; -} -#endif - -/*********************************************************************** -* reset_refsp - reset the reference space -* -* This routine resets (redefines) the reference space used in the -* projected steepest edge pricing algorithm. */ - -static void reset_refsp(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - int *head = csa->head; - char *refsp = csa->refsp; - double *gamma = csa->gamma; - int i, k; - xassert(csa->refct == 0); - csa->refct = 1000; - memset(&refsp[1], 0, (m+n) * sizeof(char)); - for (i = 1; i <= m; i++) - { k = head[i]; /* x[k] = xB[i] */ - refsp[k] = 1; - gamma[i] = 1.0; - } - return; -} - -/*********************************************************************** -* eval_gamma - compute steepest edge coefficients -* -* This routine computes the vector of steepest edge coefficients for -* all basic variables (except free ones) using its direct definition: -* -* gamma[i] = eta[i] + sum alfa[i,j]^2, i = 1,...,m, -* j in C -* -* where eta[i] = 1 means that xB[i] is in the current reference space, -* and 0 otherwise; C is a set of non-basic non-fixed variables xN[j], -* which are in the current reference space; alfa[i,j] are elements of -* the current simplex table. -* -* NOTE: The routine is intended only for debugginig purposes. */ - -static void eval_gamma(struct csa *csa, double gamma[]) -{ int m = csa->m; - int n = csa->n; - char *type = csa->type; - int *head = csa->head; - char *refsp = csa->refsp; - double *alfa = csa->work3; - double *h = csa->work3; - int i, j, k; - /* gamma[i] := eta[i] (or 1, if xB[i] is free) */ - for (i = 1; i <= m; i++) - { k = head[i]; /* x[k] = xB[i] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (type[k] == GLP_FR) - gamma[i] = 1.0; - else - gamma[i] = (refsp[k] ? 1.0 : 0.0); - } - /* compute columns of the current simplex table */ - for (j = 1; j <= n; j++) - { k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - /* skip column, if xN[j] is not in C */ - if (!refsp[k]) continue; -#ifdef GLP_DEBUG - /* set C must not contain fixed variables */ - xassert(type[k] != GLP_FX); -#endif - /* construct the right-hand side vector h = - N[j] */ - for (i = 1; i <= m; i++) - h[i] = 0.0; - if (k <= m) - { /* N[j] is k-th column of submatrix I */ - h[k] = -1.0; - } - else - { /* N[j] is (k-m)-th column of submatrix (-A) */ - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int beg, end, ptr; - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - h[A_ind[ptr]] = A_val[ptr]; - } - /* solve system B * alfa = h */ - xassert(csa->valid); - bfd_ftran(csa->bfd, alfa); - /* gamma[i] := gamma[i] + alfa[i,j]^2 */ - for (i = 1; i <= m; i++) - { k = head[i]; /* x[k] = xB[i] */ - if (type[k] != GLP_FR) - gamma[i] += alfa[i] * alfa[i]; - } - } - return; -} - -/*********************************************************************** -* chuzr - choose basic variable (row of the simplex table) -* -* This routine chooses basic variable xB[p] having largest weighted -* bound violation: -* -* |r[p]| / sqrt(gamma[p]) = max |r[i]| / sqrt(gamma[i]), -* i in I -* -* / lB[i] - beta[i], if beta[i] < lB[i] -* | -* r[i] = < 0, if lB[i] <= beta[i] <= uB[i] -* | -* \ uB[i] - beta[i], if beta[i] > uB[i] -* -* where beta[i] is primal value of xB[i] in the current basis, lB[i] -* and uB[i] are lower and upper bounds of xB[i], I is a subset of -* eligible basic variables, which significantly violates their bounds, -* gamma[i] is the steepest edge coefficient. -* -* If |r[i]| is less than a specified tolerance, xB[i] is not included -* in I and therefore ignored. -* -* If I is empty and no variable has been chosen, p is set to 0. */ - -static void chuzr(struct csa *csa, double tol_bnd) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - char *type = csa->type; - double *lb = csa->lb; - double *ub = csa->ub; - int *head = csa->head; - double *bbar = csa->bbar; - double *gamma = csa->gamma; - int i, k, p; - double delta, best, eps, ri, temp; - /* nothing is chosen so far */ - p = 0, delta = 0.0, best = 0.0; - /* look through the list of basic variables */ - for (i = 1; i <= m; i++) - { k = head[i]; /* x[k] = xB[i] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - /* determine bound violation ri[i] */ - ri = 0.0; - if (type[k] == GLP_LO || type[k] == GLP_DB || - type[k] == GLP_FX) - { /* xB[i] has lower bound */ - eps = tol_bnd * (1.0 + kappa * fabs(lb[k])); - if (bbar[i] < lb[k] - eps) - { /* and significantly violates it */ - ri = lb[k] - bbar[i]; - } - } - if (type[k] == GLP_UP || type[k] == GLP_DB || - type[k] == GLP_FX) - { /* xB[i] has upper bound */ - eps = tol_bnd * (1.0 + kappa * fabs(ub[k])); - if (bbar[i] > ub[k] + eps) - { /* and significantly violates it */ - ri = ub[k] - bbar[i]; - } - } - /* if xB[i] is not eligible, skip it */ - if (ri == 0.0) continue; - /* xB[i] is eligible basic variable; choose one with largest - weighted bound violation */ -#ifdef GLP_DEBUG - xassert(gamma[i] >= 0.0); -#endif - temp = gamma[i]; - if (temp < DBL_EPSILON) temp = DBL_EPSILON; - temp = (ri * ri) / temp; - if (best < temp) - p = i, delta = ri, best = temp; - } - /* store the index of basic variable xB[p] chosen and its change - in the adjacent basis */ - csa->p = p; - csa->delta = delta; - return; -} - -#if 1 /* copied from primal */ -/*********************************************************************** -* eval_rho - compute pivot row of the inverse -* -* This routine computes the pivot (p-th) row of the inverse inv(B), -* which corresponds to basic variable xB[p] chosen: -* -* rho = inv(B') * e[p], -* -* where B' is a matrix transposed to the current basis matrix, e[p] -* is unity vector. */ - -static void eval_rho(struct csa *csa, double rho[]) -{ int m = csa->m; - int p = csa->p; - double *e = rho; - int i; -#ifdef GLP_DEBUG - xassert(1 <= p && p <= m); -#endif - /* construct the right-hand side vector e[p] */ - for (i = 1; i <= m; i++) - e[i] = 0.0; - e[p] = 1.0; - /* solve system B'* rho = e[p] */ - xassert(csa->valid); - bfd_btran(csa->bfd, rho); - return; -} -#endif - -#if 1 /* copied from primal */ -/*********************************************************************** -* refine_rho - refine pivot row of the inverse -* -* This routine refines the pivot row of the inverse inv(B) assuming -* that it was previously computed by the routine eval_rho. */ - -static void refine_rho(struct csa *csa, double rho[]) -{ int m = csa->m; - int p = csa->p; - double *e = csa->work3; - int i; -#ifdef GLP_DEBUG - xassert(1 <= p && p <= m); -#endif - /* construct the right-hand side vector e[p] */ - for (i = 1; i <= m; i++) - e[i] = 0.0; - e[p] = 1.0; - /* refine solution of B'* rho = e[p] */ - refine_btran(csa, e, rho); - return; -} -#endif - -#if 1 /* 06/IV-2009 */ -/*********************************************************************** -* eval_trow - compute pivot row of the simplex table -* -* This routine computes the pivot row of the simplex table, which -* corresponds to basic variable xB[p] chosen. -* -* The pivot row is the following vector: -* -* trow = T'* e[p] = - N'* inv(B') * e[p] = - N' * rho, -* -* where rho is the pivot row of the inverse inv(B) previously computed -* by the routine eval_rho. -* -* Note that elements of the pivot row corresponding to fixed non-basic -* variables are not computed. -* -* NOTES -* -* Computing pivot row of the simplex table is one of the most time -* consuming operations, and for some instances it may take more than -* 50% of the total solution time. -* -* In the current implementation there are two routines to compute the -* pivot row. The routine eval_trow1 computes elements of the pivot row -* as inner products of columns of the matrix N and the vector rho; it -* is used when the vector rho is relatively dense. The routine -* eval_trow2 computes the pivot row as a linear combination of rows of -* the matrix N; it is used when the vector rho is relatively sparse. */ - -static void eval_trow1(struct csa *csa, double rho[]) -{ int m = csa->m; - int n = csa->n; - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int *head = csa->head; - char *stat = csa->stat; - int *trow_ind = csa->trow_ind; - double *trow_vec = csa->trow_vec; - int j, k, beg, end, ptr, nnz; - double temp; - /* compute the pivot row as inner products of columns of the - matrix N and vector rho: trow[j] = - rho * N[j] */ - nnz = 0; - for (j = 1; j <= n; j++) - { if (stat[j] == GLP_NS) - { /* xN[j] is fixed */ - trow_vec[j] = 0.0; - continue; - } - k = head[m+j]; /* x[k] = xN[j] */ - if (k <= m) - { /* N[j] is k-th column of submatrix I */ - temp = - rho[k]; - } - else - { /* N[j] is (k-m)-th column of submatrix (-A) */ - beg = A_ptr[k-m], end = A_ptr[k-m+1]; - temp = 0.0; - for (ptr = beg; ptr < end; ptr++) - temp += rho[A_ind[ptr]] * A_val[ptr]; - } - if (temp != 0.0) - trow_ind[++nnz] = j; - trow_vec[j] = temp; - } - csa->trow_nnz = nnz; - return; -} - -static void eval_trow2(struct csa *csa, double rho[]) -{ int m = csa->m; - int n = csa->n; - int *AT_ptr = csa->AT_ptr; - int *AT_ind = csa->AT_ind; - double *AT_val = csa->AT_val; - int *bind = csa->bind; - char *stat = csa->stat; - int *trow_ind = csa->trow_ind; - double *trow_vec = csa->trow_vec; - int i, j, beg, end, ptr, nnz; - double temp; - /* clear the pivot row */ - for (j = 1; j <= n; j++) - trow_vec[j] = 0.0; - /* compute the pivot row as a linear combination of rows of the - matrix N: trow = - rho[1] * N'[1] - ... - rho[m] * N'[m] */ - for (i = 1; i <= m; i++) - { temp = rho[i]; - if (temp == 0.0) continue; - /* trow := trow - rho[i] * N'[i] */ - j = bind[i] - m; /* x[i] = xN[j] */ - if (j >= 1 && stat[j] != GLP_NS) - trow_vec[j] -= temp; - beg = AT_ptr[i], end = AT_ptr[i+1]; - for (ptr = beg; ptr < end; ptr++) - { j = bind[m + AT_ind[ptr]] - m; /* x[k] = xN[j] */ - if (j >= 1 && stat[j] != GLP_NS) - trow_vec[j] += temp * AT_val[ptr]; - } - } - /* construct sparse pattern of the pivot row */ - nnz = 0; - for (j = 1; j <= n; j++) - { if (trow_vec[j] != 0.0) - trow_ind[++nnz] = j; - } - csa->trow_nnz = nnz; - return; -} - -static void eval_trow(struct csa *csa, double rho[]) -{ int m = csa->m; - int i, nnz; - double dens; - /* determine the density of the vector rho */ - nnz = 0; - for (i = 1; i <= m; i++) - if (rho[i] != 0.0) nnz++; - dens = (double)nnz / (double)m; - if (dens >= 0.20) - { /* rho is relatively dense */ - eval_trow1(csa, rho); - } - else - { /* rho is relatively sparse */ - eval_trow2(csa, rho); - } - return; -} -#endif - -/*********************************************************************** -* sort_trow - sort pivot row of the simplex table -* -* This routine reorders the list of non-zero elements of the pivot -* row to put significant elements, whose magnitude is not less than -* a specified tolerance, in front of the list, and stores the number -* of significant elements in trow_num. */ - -static void sort_trow(struct csa *csa, double tol_piv) -{ -#ifdef GLP_DEBUG - int n = csa->n; - char *stat = csa->stat; -#endif - int nnz = csa->trow_nnz; - int *trow_ind = csa->trow_ind; - double *trow_vec = csa->trow_vec; - int j, num, pos; - double big, eps, temp; - /* compute infinity (maximum) norm of the row */ - big = 0.0; - for (pos = 1; pos <= nnz; pos++) - { -#ifdef GLP_DEBUG - j = trow_ind[pos]; - xassert(1 <= j && j <= n); - xassert(stat[j] != GLP_NS); -#endif - temp = fabs(trow_vec[trow_ind[pos]]); - if (big < temp) big = temp; - } - csa->trow_max = big; - /* determine absolute pivot tolerance */ - eps = tol_piv * (1.0 + 0.01 * big); - /* move significant row components to the front of the list */ - for (num = 0; num < nnz; ) - { j = trow_ind[nnz]; - if (fabs(trow_vec[j]) < eps) - nnz--; - else - { num++; - trow_ind[nnz] = trow_ind[num]; - trow_ind[num] = j; - } - } - csa->trow_num = num; - return; -} - -#ifdef GLP_LONG_STEP /* 07/IV-2009 */ -static int ls_func(const void *p1_, const void *p2_) -{ const struct bkpt *p1 = p1_, *p2 = p2_; - if (p1->t < p2->t) return -1; - if (p1->t > p2->t) return +1; - return 0; -} - -static int ls_func1(const void *p1_, const void *p2_) -{ const struct bkpt *p1 = p1_, *p2 = p2_; - if (p1->dz < p2->dz) return -1; - if (p1->dz > p2->dz) return +1; - return 0; -} - -static void long_step(struct csa *csa) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - char *type = csa->type; - double *lb = csa->lb; - double *ub = csa->ub; - int *head = csa->head; - char *stat = csa->stat; - double *cbar = csa->cbar; - double delta = csa->delta; - int *trow_ind = csa->trow_ind; - double *trow_vec = csa->trow_vec; - int trow_num = csa->trow_num; - struct bkpt *bkpt = csa->bkpt; - int j, k, kk, nbps, pos; - double alfa, s, slope, dzmax; - /* delta > 0 means that xB[p] violates its lower bound, so to - increase the dual objective lambdaB[p] must increase; - delta < 0 means that xB[p] violates its upper bound, so to - increase the dual objective lambdaB[p] must decrease */ - /* s := sign(delta) */ - s = (delta > 0.0 ? +1.0 : -1.0); - /* determine breakpoints of the dual objective */ - nbps = 0; - for (pos = 1; pos <= trow_num; pos++) - { j = trow_ind[pos]; -#ifdef GLP_DEBUG - xassert(1 <= j && j <= n); - xassert(stat[j] != GLP_NS); -#endif - /* if there is free non-basic variable, switch to the standard - ratio test */ - if (stat[j] == GLP_NF) - { nbps = 0; - goto done; - } - /* lambdaN[j] = ... - alfa * t - ..., where t = s * lambdaB[i] - is the dual ray parameter, t >= 0 */ - alfa = s * trow_vec[j]; -#ifdef GLP_DEBUG - xassert(alfa != 0.0); - xassert(stat[j] == GLP_NL || stat[j] == GLP_NU); -#endif - if (alfa > 0.0 && stat[j] == GLP_NL || - alfa < 0.0 && stat[j] == GLP_NU) - { /* either lambdaN[j] >= 0 (if stat = GLP_NL) and decreases - or lambdaN[j] <= 0 (if stat = GLP_NU) and increases; in - both cases we have a breakpoint */ - nbps++; -#ifdef GLP_DEBUG - xassert(nbps <= n); -#endif - bkpt[nbps].j = j; - bkpt[nbps].t = cbar[j] / alfa; -/* -if (stat[j] == GLP_NL && cbar[j] < 0.0 || - stat[j] == GLP_NU && cbar[j] > 0.0) -xprintf("%d %g\n", stat[j], cbar[j]); -*/ - /* if t is negative, replace it by exact zero (see comments - in the routine chuzc) */ - if (bkpt[nbps].t < 0.0) bkpt[nbps].t = 0.0; - } - } - /* if there are less than two breakpoints, switch to the standard - ratio test */ - if (nbps < 2) - { nbps = 0; - goto done; - } - /* sort breakpoints by ascending the dual ray parameter, t */ - qsort(&bkpt[1], nbps, sizeof(struct bkpt), ls_func); - /* determine last breakpoint, at which the dual objective still - greater than at t = 0 */ - dzmax = 0.0; - slope = fabs(delta); /* initial slope */ - for (kk = 1; kk <= nbps; kk++) - { if (kk == 1) - bkpt[kk].dz = - 0.0 + slope * (bkpt[kk].t - 0.0); - else - bkpt[kk].dz = - bkpt[kk-1].dz + slope * (bkpt[kk].t - bkpt[kk-1].t); - if (dzmax < bkpt[kk].dz) - dzmax = bkpt[kk].dz; - else if (bkpt[kk].dz < 0.05 * (1.0 + dzmax)) - { nbps = kk - 1; - break; - } - j = bkpt[kk].j; - k = head[m+j]; /* x[k] = xN[j] */ - if (type[k] == GLP_DB) - slope -= fabs(trow_vec[j]) * (ub[k] - lb[k]); - else - { nbps = kk; - break; - } - } - /* if there are less than two breakpoints, switch to the standard - ratio test */ - if (nbps < 2) - { nbps = 0; - goto done; - } - /* sort breakpoints by ascending the dual change, dz */ - qsort(&bkpt[1], nbps, sizeof(struct bkpt), ls_func1); -/* -for (kk = 1; kk <= nbps; kk++) -xprintf("%d; t = %g; dz = %g\n", kk, bkpt[kk].t, bkpt[kk].dz); -*/ -done: csa->nbps = nbps; - return; -} -#endif - -/*********************************************************************** -* chuzc - choose non-basic variable (column of the simplex table) -* -* This routine chooses non-basic variable xN[q], which being entered -* in the basis keeps dual feasibility of the basic solution. -* -* The parameter rtol is a relative tolerance used to relax zero bounds -* of reduced costs of non-basic variables. If rtol = 0, the routine -* implements the standard ratio test. Otherwise, if rtol > 0, the -* routine implements Harris' two-pass ratio test. In the latter case -* rtol should be about three times less than a tolerance used to check -* dual feasibility. */ - -static void chuzc(struct csa *csa, double rtol) -{ -#ifdef GLP_DEBUG - int m = csa->m; - int n = csa->n; -#endif - char *stat = csa->stat; - double *cbar = csa->cbar; -#ifdef GLP_DEBUG - int p = csa->p; -#endif - double delta = csa->delta; - int *trow_ind = csa->trow_ind; - double *trow_vec = csa->trow_vec; - int trow_num = csa->trow_num; - int j, pos, q; - double alfa, big, s, t, teta, tmax; -#ifdef GLP_DEBUG - xassert(1 <= p && p <= m); -#endif - /* delta > 0 means that xB[p] violates its lower bound and goes - to it in the adjacent basis, so lambdaB[p] is increasing from - its lower zero bound; - delta < 0 means that xB[p] violates its upper bound and goes - to it in the adjacent basis, so lambdaB[p] is decreasing from - its upper zero bound */ -#ifdef GLP_DEBUG - xassert(delta != 0.0); -#endif - /* s := sign(delta) */ - s = (delta > 0.0 ? +1.0 : -1.0); - /*** FIRST PASS ***/ - /* nothing is chosen so far */ - q = 0, teta = DBL_MAX, big = 0.0; - /* walk through significant elements of the pivot row */ - for (pos = 1; pos <= trow_num; pos++) - { j = trow_ind[pos]; -#ifdef GLP_DEBUG - xassert(1 <= j && j <= n); -#endif - alfa = s * trow_vec[j]; -#ifdef GLP_DEBUG - xassert(alfa != 0.0); -#endif - /* lambdaN[j] = ... - alfa * lambdaB[p] - ..., and due to s we - need to consider only increasing lambdaB[p] */ - if (alfa > 0.0) - { /* lambdaN[j] is decreasing */ - if (stat[j] == GLP_NL || stat[j] == GLP_NF) - { /* lambdaN[j] has zero lower bound */ - t = (cbar[j] + rtol) / alfa; - } - else - { /* lambdaN[j] has no lower bound */ - continue; - } - } - else - { /* lambdaN[j] is increasing */ - if (stat[j] == GLP_NU || stat[j] == GLP_NF) - { /* lambdaN[j] has zero upper bound */ - t = (cbar[j] - rtol) / alfa; - } - else - { /* lambdaN[j] has no upper bound */ - continue; - } - } - /* t is a change of lambdaB[p], on which lambdaN[j] reaches - its zero bound (possibly relaxed); since the basic solution - is assumed to be dual feasible, t has to be non-negative by - definition; however, it may happen that lambdaN[j] slightly - (i.e. within a tolerance) violates its zero bound, that - leads to negative t; in the latter case, if xN[j] is chosen, - negative t means that lambdaB[p] changes in wrong direction - that may cause wrong results on updating reduced costs; - thus, if t is negative, we should replace it by exact zero - assuming that lambdaN[j] is exactly on its zero bound, and - violation appears due to round-off errors */ - if (t < 0.0) t = 0.0; - /* apply minimal ratio test */ - if (teta > t || teta == t && big < fabs(alfa)) - q = j, teta = t, big = fabs(alfa); - } - /* the second pass is skipped in the following cases: */ - /* if the standard ratio test is used */ - if (rtol == 0.0) goto done; - /* if no non-basic variable has been chosen on the first pass */ - if (q == 0) goto done; - /* if lambdaN[q] prevents lambdaB[p] from any change */ - if (teta == 0.0) goto done; - /*** SECOND PASS ***/ - /* here tmax is a maximal change of lambdaB[p], on which the - solution remains dual feasible within a tolerance */ -#if 0 - tmax = (1.0 + 10.0 * DBL_EPSILON) * teta; -#else - tmax = teta; -#endif - /* nothing is chosen so far */ - q = 0, teta = DBL_MAX, big = 0.0; - /* walk through significant elements of the pivot row */ - for (pos = 1; pos <= trow_num; pos++) - { j = trow_ind[pos]; -#ifdef GLP_DEBUG - xassert(1 <= j && j <= n); -#endif - alfa = s * trow_vec[j]; -#ifdef GLP_DEBUG - xassert(alfa != 0.0); -#endif - /* lambdaN[j] = ... - alfa * lambdaB[p] - ..., and due to s we - need to consider only increasing lambdaB[p] */ - if (alfa > 0.0) - { /* lambdaN[j] is decreasing */ - if (stat[j] == GLP_NL || stat[j] == GLP_NF) - { /* lambdaN[j] has zero lower bound */ - t = cbar[j] / alfa; - } - else - { /* lambdaN[j] has no lower bound */ - continue; - } - } - else - { /* lambdaN[j] is increasing */ - if (stat[j] == GLP_NU || stat[j] == GLP_NF) - { /* lambdaN[j] has zero upper bound */ - t = cbar[j] / alfa; - } - else - { /* lambdaN[j] has no upper bound */ - continue; - } - } - /* (see comments for the first pass) */ - if (t < 0.0) t = 0.0; - /* t is a change of lambdaB[p], on which lambdaN[j] reaches - its zero (lower or upper) bound; if t <= tmax, all reduced - costs can violate their zero bounds only within relaxation - tolerance rtol, so we can choose non-basic variable having - largest influence coefficient to avoid possible numerical - instability */ - if (t <= tmax && big < fabs(alfa)) - q = j, teta = t, big = fabs(alfa); - } - /* something must be chosen on the second pass */ - xassert(q != 0); -done: /* store the index of non-basic variable xN[q] chosen */ - csa->q = q; - /* store reduced cost of xN[q] in the adjacent basis */ - csa->new_dq = s * teta; - return; -} - -#if 1 /* copied from primal */ -/*********************************************************************** -* eval_tcol - compute pivot column of the simplex table -* -* This routine computes the pivot column of the simplex table, which -* corresponds to non-basic variable xN[q] chosen. -* -* The pivot column is the following vector: -* -* tcol = T * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q], -* -* where B is the current basis matrix, N[q] is a column of the matrix -* (I|-A) corresponding to variable xN[q]. */ - -static void eval_tcol(struct csa *csa) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int *head = csa->head; - int q = csa->q; - int *tcol_ind = csa->tcol_ind; - double *tcol_vec = csa->tcol_vec; - double *h = csa->tcol_vec; - int i, k, nnz; -#ifdef GLP_DEBUG - xassert(1 <= q && q <= n); -#endif - k = head[m+q]; /* x[k] = xN[q] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - /* construct the right-hand side vector h = - N[q] */ - for (i = 1; i <= m; i++) - h[i] = 0.0; - if (k <= m) - { /* N[q] is k-th column of submatrix I */ - h[k] = -1.0; - } - else - { /* N[q] is (k-m)-th column of submatrix (-A) */ - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int beg, end, ptr; - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - h[A_ind[ptr]] = A_val[ptr]; - } - /* solve system B * tcol = h */ - xassert(csa->valid); - bfd_ftran(csa->bfd, tcol_vec); - /* construct sparse pattern of the pivot column */ - nnz = 0; - for (i = 1; i <= m; i++) - { if (tcol_vec[i] != 0.0) - tcol_ind[++nnz] = i; - } - csa->tcol_nnz = nnz; - return; -} -#endif - -#if 1 /* copied from primal */ -/*********************************************************************** -* refine_tcol - refine pivot column of the simplex table -* -* This routine refines the pivot column of the simplex table assuming -* that it was previously computed by the routine eval_tcol. */ - -static void refine_tcol(struct csa *csa) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - int *head = csa->head; - int q = csa->q; - int *tcol_ind = csa->tcol_ind; - double *tcol_vec = csa->tcol_vec; - double *h = csa->work3; - int i, k, nnz; -#ifdef GLP_DEBUG - xassert(1 <= q && q <= n); -#endif - k = head[m+q]; /* x[k] = xN[q] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - /* construct the right-hand side vector h = - N[q] */ - for (i = 1; i <= m; i++) - h[i] = 0.0; - if (k <= m) - { /* N[q] is k-th column of submatrix I */ - h[k] = -1.0; - } - else - { /* N[q] is (k-m)-th column of submatrix (-A) */ - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int beg, end, ptr; - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - h[A_ind[ptr]] = A_val[ptr]; - } - /* refine solution of B * tcol = h */ - refine_ftran(csa, h, tcol_vec); - /* construct sparse pattern of the pivot column */ - nnz = 0; - for (i = 1; i <= m; i++) - { if (tcol_vec[i] != 0.0) - tcol_ind[++nnz] = i; - } - csa->tcol_nnz = nnz; - return; -} -#endif - -/*********************************************************************** -* update_cbar - update reduced costs of non-basic variables -* -* This routine updates reduced costs of all (except fixed) non-basic -* variables for the adjacent basis. */ - -static void update_cbar(struct csa *csa) -{ -#ifdef GLP_DEBUG - int n = csa->n; -#endif - double *cbar = csa->cbar; - int trow_nnz = csa->trow_nnz; - int *trow_ind = csa->trow_ind; - double *trow_vec = csa->trow_vec; - int q = csa->q; - double new_dq = csa->new_dq; - int j, pos; -#ifdef GLP_DEBUG - xassert(1 <= q && q <= n); -#endif - /* set new reduced cost of xN[q] */ - cbar[q] = new_dq; - /* update reduced costs of other non-basic variables */ - if (new_dq == 0.0) goto done; - for (pos = 1; pos <= trow_nnz; pos++) - { j = trow_ind[pos]; -#ifdef GLP_DEBUG - xassert(1 <= j && j <= n); -#endif - if (j != q) - cbar[j] -= trow_vec[j] * new_dq; - } -done: return; -} - -/*********************************************************************** -* update_bbar - update values of basic variables -* -* This routine updates values of all basic variables for the adjacent -* basis. */ - -static void update_bbar(struct csa *csa) -{ -#ifdef GLP_DEBUG - int m = csa->m; - int n = csa->n; -#endif - double *bbar = csa->bbar; - int p = csa->p; - double delta = csa->delta; - int q = csa->q; - int tcol_nnz = csa->tcol_nnz; - int *tcol_ind = csa->tcol_ind; - double *tcol_vec = csa->tcol_vec; - int i, pos; - double teta; -#ifdef GLP_DEBUG - xassert(1 <= p && p <= m); - xassert(1 <= q && q <= n); -#endif - /* determine the change of xN[q] in the adjacent basis */ -#ifdef GLP_DEBUG - xassert(tcol_vec[p] != 0.0); -#endif - teta = delta / tcol_vec[p]; - /* set new primal value of xN[q] */ - bbar[p] = get_xN(csa, q) + teta; - /* update primal values of other basic variables */ - if (teta == 0.0) goto done; - for (pos = 1; pos <= tcol_nnz; pos++) - { i = tcol_ind[pos]; -#ifdef GLP_DEBUG - xassert(1 <= i && i <= m); -#endif - if (i != p) - bbar[i] += tcol_vec[i] * teta; - } -done: return; -} - -/*********************************************************************** -* update_gamma - update steepest edge coefficients -* -* This routine updates steepest-edge coefficients for the adjacent -* basis. */ - -static void update_gamma(struct csa *csa) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - char *type = csa->type; - int *head = csa->head; - char *refsp = csa->refsp; - double *gamma = csa->gamma; - int p = csa->p; - int trow_nnz = csa->trow_nnz; - int *trow_ind = csa->trow_ind; - double *trow_vec = csa->trow_vec; - int q = csa->q; - int tcol_nnz = csa->tcol_nnz; - int *tcol_ind = csa->tcol_ind; - double *tcol_vec = csa->tcol_vec; - double *u = csa->work3; - int i, j, k,pos; - double gamma_p, eta_p, pivot, t, t1, t2; -#ifdef GLP_DEBUG - xassert(1 <= p && p <= m); - xassert(1 <= q && q <= n); -#endif - /* the basis changes, so decrease the count */ - xassert(csa->refct > 0); - csa->refct--; - /* recompute gamma[p] for the current basis more accurately and - compute auxiliary vector u */ -#ifdef GLP_DEBUG - xassert(type[head[p]] != GLP_FR); -#endif - gamma_p = eta_p = (refsp[head[p]] ? 1.0 : 0.0); - for (i = 1; i <= m; i++) u[i] = 0.0; - for (pos = 1; pos <= trow_nnz; pos++) - { j = trow_ind[pos]; -#ifdef GLP_DEBUG - xassert(1 <= j && j <= n); -#endif - k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); - xassert(type[k] != GLP_FX); -#endif - if (!refsp[k]) continue; - t = trow_vec[j]; - gamma_p += t * t; - /* u := u + N[j] * delta[j] * trow[j] */ - if (k <= m) - { /* N[k] = k-j stolbec submatrix I */ - u[k] += t; - } - else - { /* N[k] = k-m-k stolbec (-A) */ - int *A_ptr = csa->A_ptr; - int *A_ind = csa->A_ind; - double *A_val = csa->A_val; - int beg, end, ptr; - beg = A_ptr[k-m]; - end = A_ptr[k-m+1]; - for (ptr = beg; ptr < end; ptr++) - u[A_ind[ptr]] -= t * A_val[ptr]; - } - } - xassert(csa->valid); - bfd_ftran(csa->bfd, u); - /* update gamma[i] for other basic variables (except xB[p] and - free variables) */ - pivot = tcol_vec[p]; -#ifdef GLP_DEBUG - xassert(pivot != 0.0); -#endif - for (pos = 1; pos <= tcol_nnz; pos++) - { i = tcol_ind[pos]; -#ifdef GLP_DEBUG - xassert(1 <= i && i <= m); -#endif - k = head[i]; -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - /* skip xB[p] */ - if (i == p) continue; - /* skip free basic variable */ - if (type[head[i]] == GLP_FR) - { -#ifdef GLP_DEBUG - xassert(gamma[i] == 1.0); -#endif - continue; - } - /* compute gamma[i] for the adjacent basis */ - t = tcol_vec[i] / pivot; - t1 = gamma[i] + t * t * gamma_p + 2.0 * t * u[i]; - t2 = (refsp[k] ? 1.0 : 0.0) + eta_p * t * t; - gamma[i] = (t1 >= t2 ? t1 : t2); - /* (though gamma[i] can be exact zero, because the reference - space does not include non-basic fixed variables) */ - if (gamma[i] < DBL_EPSILON) gamma[i] = DBL_EPSILON; - } - /* compute gamma[p] for the adjacent basis */ - if (type[head[m+q]] == GLP_FR) - gamma[p] = 1.0; - else - { gamma[p] = gamma_p / (pivot * pivot); - if (gamma[p] < DBL_EPSILON) gamma[p] = DBL_EPSILON; - } - /* if xB[p], which becomes xN[q] in the adjacent basis, is fixed - and belongs to the reference space, remove it from there, and - change all gamma's appropriately */ - k = head[p]; - if (type[k] == GLP_FX && refsp[k]) - { refsp[k] = 0; - for (pos = 1; pos <= tcol_nnz; pos++) - { i = tcol_ind[pos]; - if (i == p) - { if (type[head[m+q]] == GLP_FR) continue; - t = 1.0 / tcol_vec[p]; - } - else - { if (type[head[i]] == GLP_FR) continue; - t = tcol_vec[i] / tcol_vec[p]; - } - gamma[i] -= t * t; - if (gamma[i] < DBL_EPSILON) gamma[i] = DBL_EPSILON; - } - } - return; -} - -#if 1 /* copied from primal */ -/*********************************************************************** -* err_in_bbar - compute maximal relative error in primal solution -* -* This routine returns maximal relative error: -* -* max |beta[i] - bbar[i]| / (1 + |beta[i]|), -* -* where beta and bbar are, respectively, directly computed and the -* current (updated) values of basic variables. -* -* NOTE: The routine is intended only for debugginig purposes. */ - -static double err_in_bbar(struct csa *csa) -{ int m = csa->m; - double *bbar = csa->bbar; - int i; - double e, emax, *beta; - beta = xcalloc(1+m, sizeof(double)); - eval_beta(csa, beta); - emax = 0.0; - for (i = 1; i <= m; i++) - { e = fabs(beta[i] - bbar[i]) / (1.0 + fabs(beta[i])); - if (emax < e) emax = e; - } - xfree(beta); - return emax; -} -#endif - -#if 1 /* copied from primal */ -/*********************************************************************** -* err_in_cbar - compute maximal relative error in dual solution -* -* This routine returns maximal relative error: -* -* max |cost[j] - cbar[j]| / (1 + |cost[j]|), -* -* where cost and cbar are, respectively, directly computed and the -* current (updated) reduced costs of non-basic non-fixed variables. -* -* NOTE: The routine is intended only for debugginig purposes. */ - -static double err_in_cbar(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - char *stat = csa->stat; - double *cbar = csa->cbar; - int j; - double e, emax, cost, *pi; - pi = xcalloc(1+m, sizeof(double)); - eval_pi(csa, pi); - emax = 0.0; - for (j = 1; j <= n; j++) - { if (stat[j] == GLP_NS) continue; - cost = eval_cost(csa, pi, j); - e = fabs(cost - cbar[j]) / (1.0 + fabs(cost)); - if (emax < e) emax = e; - } - xfree(pi); - return emax; -} -#endif - -/*********************************************************************** -* err_in_gamma - compute maximal relative error in steepest edge cff. -* -* This routine returns maximal relative error: -* -* max |gamma'[j] - gamma[j]| / (1 + |gamma'[j]), -* -* where gamma'[j] and gamma[j] are, respectively, directly computed -* and the current (updated) steepest edge coefficients for non-basic -* non-fixed variable x[j]. -* -* NOTE: The routine is intended only for debugginig purposes. */ - -static double err_in_gamma(struct csa *csa) -{ int m = csa->m; - char *type = csa->type; - int *head = csa->head; - double *gamma = csa->gamma; - double *exact = csa->work4; - int i; - double e, emax, temp; - eval_gamma(csa, exact); - emax = 0.0; - for (i = 1; i <= m; i++) - { if (type[head[i]] == GLP_FR) - { xassert(gamma[i] == 1.0); - xassert(exact[i] == 1.0); - continue; - } - temp = exact[i]; - e = fabs(temp - gamma[i]) / (1.0 + fabs(temp)); - if (emax < e) emax = e; - } - return emax; -} - -/*********************************************************************** -* change_basis - change basis header -* -* This routine changes the basis header to make it corresponding to -* the adjacent basis. */ - -static void change_basis(struct csa *csa) -{ int m = csa->m; -#ifdef GLP_DEBUG - int n = csa->n; -#endif - char *type = csa->type; - int *head = csa->head; -#if 1 /* 06/IV-2009 */ - int *bind = csa->bind; -#endif - char *stat = csa->stat; - int p = csa->p; - double delta = csa->delta; - int q = csa->q; - int k; - /* xB[p] leaves the basis, xN[q] enters the basis */ -#ifdef GLP_DEBUG - xassert(1 <= p && p <= m); - xassert(1 <= q && q <= n); -#endif - /* xB[p] <-> xN[q] */ - k = head[p], head[p] = head[m+q], head[m+q] = k; -#if 1 /* 06/IV-2009 */ - bind[head[p]] = p, bind[head[m+q]] = m + q; -#endif - if (type[k] == GLP_FX) - stat[q] = GLP_NS; - else if (delta > 0.0) - { -#ifdef GLP_DEBUG - xassert(type[k] == GLP_LO || type[k] == GLP_DB); -#endif - stat[q] = GLP_NL; - } - else /* delta < 0.0 */ - { -#ifdef GLP_DEBUG - xassert(type[k] == GLP_UP || type[k] == GLP_DB); -#endif - stat[q] = GLP_NU; - } - return; -} - -/*********************************************************************** -* check_feas - check dual feasibility of basic solution -* -* If the current basic solution is dual feasible within a tolerance, -* this routine returns zero, otherwise it returns non-zero. */ - -static int check_feas(struct csa *csa, double tol_dj) -{ int m = csa->m; - int n = csa->n; - char *orig_type = csa->orig_type; - int *head = csa->head; - double *cbar = csa->cbar; - int j, k; - for (j = 1; j <= n; j++) - { k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (cbar[j] < - tol_dj) - if (orig_type[k] == GLP_LO || orig_type[k] == GLP_FR) - return 1; - if (cbar[j] > + tol_dj) - if (orig_type[k] == GLP_UP || orig_type[k] == GLP_FR) - return 1; - } - return 0; -} - -/*********************************************************************** -* set_aux_bnds - assign auxiliary bounds to variables -* -* This routine assigns auxiliary bounds to variables to construct an -* LP problem solved on phase I. */ - -static void set_aux_bnds(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - char *type = csa->type; - double *lb = csa->lb; - double *ub = csa->ub; - char *orig_type = csa->orig_type; - int *head = csa->head; - char *stat = csa->stat; - double *cbar = csa->cbar; - int j, k; - for (k = 1; k <= m+n; k++) - { switch (orig_type[k]) - { case GLP_FR: -#if 0 - type[k] = GLP_DB, lb[k] = -1.0, ub[k] = +1.0; -#else - /* to force free variables to enter the basis */ - type[k] = GLP_DB, lb[k] = -1e3, ub[k] = +1e3; -#endif - break; - case GLP_LO: - type[k] = GLP_DB, lb[k] = 0.0, ub[k] = +1.0; - break; - case GLP_UP: - type[k] = GLP_DB, lb[k] = -1.0, ub[k] = 0.0; - break; - case GLP_DB: - case GLP_FX: - type[k] = GLP_FX, lb[k] = ub[k] = 0.0; - break; - default: - xassert(orig_type != orig_type); - } - } - for (j = 1; j <= n; j++) - { k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (type[k] == GLP_FX) - stat[j] = GLP_NS; - else if (cbar[j] >= 0.0) - stat[j] = GLP_NL; - else - stat[j] = GLP_NU; - } - return; -} - -/*********************************************************************** -* set_orig_bnds - restore original bounds of variables -* -* This routine restores original types and bounds of variables and -* determines statuses of non-basic variables assuming that the current -* basis is dual feasible. */ - -static void set_orig_bnds(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - char *type = csa->type; - double *lb = csa->lb; - double *ub = csa->ub; - char *orig_type = csa->orig_type; - double *orig_lb = csa->orig_lb; - double *orig_ub = csa->orig_ub; - int *head = csa->head; - char *stat = csa->stat; - double *cbar = csa->cbar; - int j, k; - memcpy(&type[1], &orig_type[1], (m+n) * sizeof(char)); - memcpy(&lb[1], &orig_lb[1], (m+n) * sizeof(double)); - memcpy(&ub[1], &orig_ub[1], (m+n) * sizeof(double)); - for (j = 1; j <= n; j++) - { k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - switch (type[k]) - { case GLP_FR: - stat[j] = GLP_NF; - break; - case GLP_LO: - stat[j] = GLP_NL; - break; - case GLP_UP: - stat[j] = GLP_NU; - break; - case GLP_DB: - if (cbar[j] >= +DBL_EPSILON) - stat[j] = GLP_NL; - else if (cbar[j] <= -DBL_EPSILON) - stat[j] = GLP_NU; - else if (fabs(lb[k]) <= fabs(ub[k])) - stat[j] = GLP_NL; - else - stat[j] = GLP_NU; - break; - case GLP_FX: - stat[j] = GLP_NS; - break; - default: - xassert(type != type); - } - } - return; -} - -/*********************************************************************** -* check_stab - check numerical stability of basic solution -* -* If the current basic solution is dual feasible within a tolerance, -* this routine returns zero, otherwise it returns non-zero. */ - -static int check_stab(struct csa *csa, double tol_dj) -{ int n = csa->n; - char *stat = csa->stat; - double *cbar = csa->cbar; - int j; - for (j = 1; j <= n; j++) - { if (cbar[j] < - tol_dj) - if (stat[j] == GLP_NL || stat[j] == GLP_NF) return 1; - if (cbar[j] > + tol_dj) - if (stat[j] == GLP_NU || stat[j] == GLP_NF) return 1; - } - return 0; -} - -#if 1 /* copied from primal */ -/*********************************************************************** -* eval_obj - compute original objective function -* -* This routine computes the current value of the original objective -* function. */ - -static double eval_obj(struct csa *csa) -{ int m = csa->m; - int n = csa->n; - double *obj = csa->obj; - int *head = csa->head; - double *bbar = csa->bbar; - int i, j, k; - double sum; - sum = obj[0]; - /* walk through the list of basic variables */ - for (i = 1; i <= m; i++) - { k = head[i]; /* x[k] = xB[i] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (k > m) - sum += obj[k-m] * bbar[i]; - } - /* walk through the list of non-basic variables */ - for (j = 1; j <= n; j++) - { k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (k > m) - sum += obj[k-m] * get_xN(csa, j); - } - return sum; -} -#endif - -/*********************************************************************** -* display - display the search progress -* -* This routine displays some information about the search progress. */ - -static void display(struct csa *csa, const glp_smcp *parm, int spec) -{ int m = csa->m; - int n = csa->n; - double *coef = csa->coef; - char *orig_type = csa->orig_type; - int *head = csa->head; - char *stat = csa->stat; - int phase = csa->phase; - double *bbar = csa->bbar; - double *cbar = csa->cbar; - int i, j, cnt; - double sum; - if (parm->msg_lev < GLP_MSG_ON) goto skip; - if (parm->out_dly > 0 && - 1000.0 * xdifftime(xtime(), csa->tm_beg) < parm->out_dly) - goto skip; - if (csa->it_cnt == csa->it_dpy) goto skip; - if (!spec && csa->it_cnt % parm->out_frq != 0) goto skip; - /* compute the sum of dual infeasibilities */ - sum = 0.0; - if (phase == 1) - { for (i = 1; i <= m; i++) - sum -= coef[head[i]] * bbar[i]; - for (j = 1; j <= n; j++) - sum -= coef[head[m+j]] * get_xN(csa, j); - } - else - { for (j = 1; j <= n; j++) - { if (cbar[j] < 0.0) - if (stat[j] == GLP_NL || stat[j] == GLP_NF) - sum -= cbar[j]; - if (cbar[j] > 0.0) - if (stat[j] == GLP_NU || stat[j] == GLP_NF) - sum += cbar[j]; - } - } - /* determine the number of basic fixed variables */ - cnt = 0; - for (i = 1; i <= m; i++) - if (orig_type[head[i]] == GLP_FX) cnt++; - if (csa->phase == 1) - xprintf(" %6d: %24s infeas = %10.3e (%d)\n", - csa->it_cnt, "", sum, cnt); - else - xprintf("|%6d: obj = %17.9e infeas = %10.3e (%d)\n", - csa->it_cnt, eval_obj(csa), sum, cnt); - csa->it_dpy = csa->it_cnt; -skip: return; -} - -#if 1 /* copied from primal */ -/*********************************************************************** -* store_sol - store basic solution back to the problem object -* -* This routine stores basic solution components back to the problem -* object. */ - -static void store_sol(struct csa *csa, glp_prob *lp, int p_stat, - int d_stat, int ray) -{ int m = csa->m; - int n = csa->n; - double zeta = csa->zeta; - int *head = csa->head; - char *stat = csa->stat; - double *bbar = csa->bbar; - double *cbar = csa->cbar; - int i, j, k; -#ifdef GLP_DEBUG - xassert(lp->m == m); - xassert(lp->n == n); -#endif - /* basis factorization */ -#ifdef GLP_DEBUG - xassert(!lp->valid && lp->bfd == NULL); - xassert(csa->valid && csa->bfd != NULL); -#endif - lp->valid = 1, csa->valid = 0; - lp->bfd = csa->bfd, csa->bfd = NULL; - memcpy(&lp->head[1], &head[1], m * sizeof(int)); - /* basic solution status */ - lp->pbs_stat = p_stat; - lp->dbs_stat = d_stat; - /* objective function value */ - lp->obj_val = eval_obj(csa); - /* simplex iteration count */ - lp->it_cnt = csa->it_cnt; - /* unbounded ray */ - lp->some = ray; - /* basic variables */ - for (i = 1; i <= m; i++) - { k = head[i]; /* x[k] = xB[i] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (k <= m) - { GLPROW *row = lp->row[k]; - row->stat = GLP_BS; - row->bind = i; - row->prim = bbar[i] / row->rii; - row->dual = 0.0; - } - else - { GLPCOL *col = lp->col[k-m]; - col->stat = GLP_BS; - col->bind = i; - col->prim = bbar[i] * col->sjj; - col->dual = 0.0; - } - } - /* non-basic variables */ - for (j = 1; j <= n; j++) - { k = head[m+j]; /* x[k] = xN[j] */ -#ifdef GLP_DEBUG - xassert(1 <= k && k <= m+n); -#endif - if (k <= m) - { GLPROW *row = lp->row[k]; - row->stat = stat[j]; - row->bind = 0; -#if 0 - row->prim = get_xN(csa, j) / row->rii; -#else - switch (stat[j]) - { case GLP_NL: - row->prim = row->lb; break; - case GLP_NU: - row->prim = row->ub; break; - case GLP_NF: - row->prim = 0.0; break; - case GLP_NS: - row->prim = row->lb; break; - default: - xassert(stat != stat); - } -#endif - row->dual = (cbar[j] * row->rii) / zeta; - } - else - { GLPCOL *col = lp->col[k-m]; - col->stat = stat[j]; - col->bind = 0; -#if 0 - col->prim = get_xN(csa, j) * col->sjj; -#else - switch (stat[j]) - { case GLP_NL: - col->prim = col->lb; break; - case GLP_NU: - col->prim = col->ub; break; - case GLP_NF: - col->prim = 0.0; break; - case GLP_NS: - col->prim = col->lb; break; - default: - xassert(stat != stat); - } -#endif - col->dual = (cbar[j] / col->sjj) / zeta; - } - } - return; -} -#endif - -/*********************************************************************** -* free_csa - deallocate common storage area -* -* This routine frees all the memory allocated to arrays in the common -* storage area (CSA). */ - -static void free_csa(struct csa *csa) -{ xfree(csa->type); - xfree(csa->lb); - xfree(csa->ub); - xfree(csa->coef); - xfree(csa->orig_type); - xfree(csa->orig_lb); - xfree(csa->orig_ub); - xfree(csa->obj); - xfree(csa->A_ptr); - xfree(csa->A_ind); - xfree(csa->A_val); -#if 1 /* 06/IV-2009 */ - xfree(csa->AT_ptr); - xfree(csa->AT_ind); - xfree(csa->AT_val); -#endif - xfree(csa->head); -#if 1 /* 06/IV-2009 */ - xfree(csa->bind); -#endif - xfree(csa->stat); -#if 0 /* 06/IV-2009 */ - xfree(csa->N_ptr); - xfree(csa->N_len); - xfree(csa->N_ind); - xfree(csa->N_val); -#endif - xfree(csa->bbar); - xfree(csa->cbar); - xfree(csa->refsp); - xfree(csa->gamma); - xfree(csa->trow_ind); - xfree(csa->trow_vec); -#ifdef GLP_LONG_STEP /* 07/IV-2009 */ - xfree(csa->bkpt); -#endif - xfree(csa->tcol_ind); - xfree(csa->tcol_vec); - xfree(csa->work1); - xfree(csa->work2); - xfree(csa->work3); - xfree(csa->work4); - xfree(csa); - return; -} - -/*********************************************************************** -* spx_dual - core LP solver based on the dual simplex method -* -* SYNOPSIS -* -* #include "glpspx.h" -* int spx_dual(glp_prob *lp, const glp_smcp *parm); -* -* DESCRIPTION -* -* The routine spx_dual is a core LP solver based on the two-phase dual -* simplex method. -* -* RETURNS -* -* 0 LP instance has been successfully solved. -* -* GLP_EOBJLL -* Objective lower limit has been reached (maximization). -* -* GLP_EOBJUL -* Objective upper limit has been reached (minimization). -* -* GLP_EITLIM -* Iteration limit has been exhausted. -* -* GLP_ETMLIM -* Time limit has been exhausted. -* -* GLP_EFAIL -* The solver failed to solve LP instance. */ - -int spx_dual(glp_prob *lp, const glp_smcp *parm) -{ struct csa *csa; - int binv_st = 2; - /* status of basis matrix factorization: - 0 - invalid; 1 - just computed; 2 - updated */ - int bbar_st = 0; - /* status of primal values of basic variables: - 0 - invalid; 1 - just computed; 2 - updated */ - int cbar_st = 0; - /* status of reduced costs of non-basic variables: - 0 - invalid; 1 - just computed; 2 - updated */ - int rigorous = 0; - /* rigorous mode flag; this flag is used to enable iterative - refinement on computing pivot rows and columns of the simplex - table */ - int check = 0; - int p_stat, d_stat, ret; -#if 1 /* 16/VII-2013 */ - int degen = 0; - /* degenerated step count */ -#endif - /* allocate and initialize the common storage area */ - csa = alloc_csa(lp); - init_csa(csa, lp); - if (parm->msg_lev >= GLP_MSG_DBG) - xprintf("Objective scale factor = %g\n", csa->zeta); -loop: /* main loop starts here */ - /* compute factorization of the basis matrix */ - if (binv_st == 0) - { ret = invert_B(csa); - if (ret != 0) - { if (parm->msg_lev >= GLP_MSG_ERR) - { xprintf("Error: unable to factorize the basis matrix (%d" - ")\n", ret); - xprintf("Sorry, basis recovery procedure not implemented" - " yet\n"); - } - xassert(!lp->valid && lp->bfd == NULL); - lp->bfd = csa->bfd, csa->bfd = NULL; - lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; - lp->obj_val = 0.0; - lp->it_cnt = csa->it_cnt; - lp->some = 0; - ret = GLP_EFAIL; - goto done; - } - csa->valid = 1; - binv_st = 1; /* just computed */ - /* invalidate basic solution components */ - bbar_st = cbar_st = 0; - } -#if 1 /* 16/VII-2013 */ - if (degen >= 5000 && parm->meth == GLP_DUALP) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("Warning: dual degeneracy; switching to primal simp" - "lex\n"); - store_sol(csa, lp, GLP_UNDEF, GLP_UNDEF, 0); - ret = GLP_EFAIL; - goto done; - } -#endif - /* compute reduced costs of non-basic variables */ - if (cbar_st == 0) - { eval_cbar(csa); - cbar_st = 1; /* just computed */ - /* determine the search phase, if not determined yet */ - if (csa->phase == 0) - { if (check_feas(csa, 0.90 * parm->tol_dj) != 0) - { /* current basic solution is dual infeasible */ - /* start searching for dual feasible solution */ - csa->phase = 1; - set_aux_bnds(csa); - } - else - { /* current basic solution is dual feasible */ - /* start searching for optimal solution */ - csa->phase = 2; - set_orig_bnds(csa); - } - xassert(check_stab(csa, parm->tol_dj) == 0); - /* some non-basic double-bounded variables might become - fixed (on phase I) or vice versa (on phase II) */ -#if 0 /* 06/IV-2009 */ - build_N(csa); -#endif - csa->refct = 0; - /* bounds of non-basic variables have been changed, so - invalidate primal values */ - bbar_st = 0; - } - /* make sure that the current basic solution remains dual - feasible */ - if (check_stab(csa, parm->tol_dj) != 0) - { if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("Warning: numerical instability (dual simplex, p" - "hase %s)\n", csa->phase == 1 ? "I" : "II"); -#if 1 - if (parm->meth == GLP_DUALP) - { store_sol(csa, lp, GLP_UNDEF, GLP_UNDEF, 0); - ret = GLP_EFAIL; - goto done; - } -#endif - /* restart the search */ - csa->phase = 0; - binv_st = 0; - rigorous = 5; - goto loop; - } - } - xassert(csa->phase == 1 || csa->phase == 2); - /* on phase I we do not need to wait until the current basic - solution becomes primal feasible; it is sufficient to make - sure that all reduced costs have correct signs */ - if (csa->phase == 1 && check_feas(csa, parm->tol_dj) == 0) - { /* the current basis is dual feasible; switch to phase II */ - display(csa, parm, 1); - csa->phase = 2; - if (cbar_st != 1) - { eval_cbar(csa); - cbar_st = 1; - } - set_orig_bnds(csa); -#if 0 /* 06/IV-2009 */ - build_N(csa); -#endif - csa->refct = 0; - bbar_st = 0; - } - /* compute primal values of basic variables */ - if (bbar_st == 0) - { eval_bbar(csa); - if (csa->phase == 2) - csa->bbar[0] = eval_obj(csa); - bbar_st = 1; /* just computed */ - } - /* redefine the reference space, if required */ - switch (parm->pricing) - { case GLP_PT_STD: - break; - case GLP_PT_PSE: - if (csa->refct == 0) reset_refsp(csa); - break; - default: - xassert(parm != parm); - } - /* at this point the basis factorization and all basic solution - components are valid */ - xassert(binv_st && bbar_st && cbar_st); - /* check accuracy of current basic solution components (only for - debugging) */ - if (check) - { double e_bbar = err_in_bbar(csa); - double e_cbar = err_in_cbar(csa); - double e_gamma = - (parm->pricing == GLP_PT_PSE ? err_in_gamma(csa) : 0.0); - xprintf("e_bbar = %10.3e; e_cbar = %10.3e; e_gamma = %10.3e\n", - e_bbar, e_cbar, e_gamma); - xassert(e_bbar <= 1e-5 && e_cbar <= 1e-5 && e_gamma <= 1e-3); - } - /* if the objective has to be maximized, check if it has reached - its lower limit */ - if (csa->phase == 2 && csa->zeta < 0.0 && - parm->obj_ll > -DBL_MAX && csa->bbar[0] <= parm->obj_ll) - { if (bbar_st != 1 || cbar_st != 1) - { if (bbar_st != 1) bbar_st = 0; - if (cbar_st != 1) cbar_st = 0; - goto loop; - } - display(csa, parm, 1); - if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("OBJECTIVE LOWER LIMIT REACHED; SEARCH TERMINATED\n" - ); - store_sol(csa, lp, GLP_INFEAS, GLP_FEAS, 0); - ret = GLP_EOBJLL; - goto done; - } - /* if the objective has to be minimized, check if it has reached - its upper limit */ - if (csa->phase == 2 && csa->zeta > 0.0 && - parm->obj_ul < +DBL_MAX && csa->bbar[0] >= parm->obj_ul) - { if (bbar_st != 1 || cbar_st != 1) - { if (bbar_st != 1) bbar_st = 0; - if (cbar_st != 1) cbar_st = 0; - goto loop; - } - display(csa, parm, 1); - if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("OBJECTIVE UPPER LIMIT REACHED; SEARCH TERMINATED\n" - ); - store_sol(csa, lp, GLP_INFEAS, GLP_FEAS, 0); - ret = GLP_EOBJUL; - goto done; - } - /* check if the iteration limit has been exhausted */ - if (parm->it_lim < INT_MAX && - csa->it_cnt - csa->it_beg >= parm->it_lim) - { if (csa->phase == 2 && bbar_st != 1 || cbar_st != 1) - { if (csa->phase == 2 && bbar_st != 1) bbar_st = 0; - if (cbar_st != 1) cbar_st = 0; - goto loop; - } - display(csa, parm, 1); - if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("ITERATION LIMIT EXCEEDED; SEARCH TERMINATED\n"); - switch (csa->phase) - { case 1: - d_stat = GLP_INFEAS; - set_orig_bnds(csa); - eval_bbar(csa); - break; - case 2: - d_stat = GLP_FEAS; - break; - default: - xassert(csa != csa); - } - store_sol(csa, lp, GLP_INFEAS, d_stat, 0); - ret = GLP_EITLIM; - goto done; - } - /* check if the time limit has been exhausted */ - if (parm->tm_lim < INT_MAX && - 1000.0 * xdifftime(xtime(), csa->tm_beg) >= parm->tm_lim) - { if (csa->phase == 2 && bbar_st != 1 || cbar_st != 1) - { if (csa->phase == 2 && bbar_st != 1) bbar_st = 0; - if (cbar_st != 1) cbar_st = 0; - goto loop; - } - display(csa, parm, 1); - if (parm->msg_lev >= GLP_MSG_ALL) - xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); - switch (csa->phase) - { case 1: - d_stat = GLP_INFEAS; - set_orig_bnds(csa); - eval_bbar(csa); - break; - case 2: - d_stat = GLP_FEAS; - break; - default: - xassert(csa != csa); - } - store_sol(csa, lp, GLP_INFEAS, d_stat, 0); - ret = GLP_ETMLIM; - goto done; - } - /* display the search progress */ - display(csa, parm, 0); - /* choose basic variable xB[p] */ - chuzr(csa, parm->tol_bnd); - if (csa->p == 0) - { if (bbar_st != 1 || cbar_st != 1) - { if (bbar_st != 1) bbar_st = 0; - if (cbar_st != 1) cbar_st = 0; - goto loop; - } - display(csa, parm, 1); - switch (csa->phase) - { case 1: - if (parm->msg_lev >= GLP_MSG_ALL) -#if 0 /* 13/VII-2013; suggested by Prof. Fischetti */ - xprintf("PROBLEM HAS NO DUAL FEASIBLE SOLUTION\n"); -#else - xprintf("LP HAS NO DUAL FEASIBLE SOLUTION\n"); -#endif - set_orig_bnds(csa); - eval_bbar(csa); - p_stat = GLP_INFEAS, d_stat = GLP_NOFEAS; - break; - case 2: - if (parm->msg_lev >= GLP_MSG_ALL) -#if 0 /* 13/VII-2013; suggested by Prof. Fischetti */ - xprintf("OPTIMAL SOLUTION FOUND\n"); -#else - xprintf("OPTIMAL LP SOLUTION FOUND\n"); -#endif - p_stat = d_stat = GLP_FEAS; - break; - default: - xassert(csa != csa); - } - store_sol(csa, lp, p_stat, d_stat, 0); - ret = 0; - goto done; - } - /* compute pivot row of the simplex table */ - { double *rho = csa->work4; - eval_rho(csa, rho); - if (rigorous) refine_rho(csa, rho); - eval_trow(csa, rho); - sort_trow(csa, parm->tol_bnd); - } - /* unlike primal simplex there is no need to check accuracy of - the primal value of xB[p] (which might be computed using the - pivot row), since bbar is a result of FTRAN */ -#ifdef GLP_LONG_STEP /* 07/IV-2009 */ - long_step(csa); - if (csa->nbps > 0) - { csa->q = csa->bkpt[csa->nbps].j; - if (csa->delta > 0.0) - csa->new_dq = + csa->bkpt[csa->nbps].t; - else - csa->new_dq = - csa->bkpt[csa->nbps].t; - } - else -#endif - /* choose non-basic variable xN[q] */ - switch (parm->r_test) - { case GLP_RT_STD: - chuzc(csa, 0.0); - break; - case GLP_RT_HAR: - chuzc(csa, 0.30 * parm->tol_dj); - break; - default: - xassert(parm != parm); - } - if (csa->q == 0) - { if (bbar_st != 1 || cbar_st != 1 || !rigorous) - { if (bbar_st != 1) bbar_st = 0; - if (cbar_st != 1) cbar_st = 0; - rigorous = 1; - goto loop; - } - display(csa, parm, 1); - switch (csa->phase) - { case 1: - if (parm->msg_lev >= GLP_MSG_ERR) - xprintf("Error: unable to choose non-basic variable o" - "n phase I\n"); - xassert(!lp->valid && lp->bfd == NULL); - lp->bfd = csa->bfd, csa->bfd = NULL; - lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; - lp->obj_val = 0.0; - lp->it_cnt = csa->it_cnt; - lp->some = 0; - ret = GLP_EFAIL; - break; - case 2: - if (parm->msg_lev >= GLP_MSG_ALL) -#if 0 /* 13/VII-2013; suggested by Prof. Fischetti */ - xprintf("PROBLEM HAS NO FEASIBLE SOLUTION\n"); -#else - xprintf("LP HAS UNBOUNDED DUAL SOLUTION\n"); -#endif - store_sol(csa, lp, GLP_NOFEAS, GLP_FEAS, - csa->head[csa->p]); - ret = 0; - break; - default: - xassert(csa != csa); - } - goto done; - } - /* check if the pivot element is acceptable */ - { double piv = csa->trow_vec[csa->q]; - double eps = 1e-5 * (1.0 + 0.01 * csa->trow_max); - if (fabs(piv) < eps) - { if (parm->msg_lev >= GLP_MSG_DBG) - xprintf("piv = %.12g; eps = %g\n", piv, eps); - if (!rigorous) - { rigorous = 5; - goto loop; - } - } - } - /* now xN[q] and xB[p] have been chosen anyhow */ - /* compute pivot column of the simplex table */ - eval_tcol(csa); - if (rigorous) refine_tcol(csa); - /* accuracy check based on the pivot element */ - { double piv1 = csa->tcol_vec[csa->p]; /* more accurate */ - double piv2 = csa->trow_vec[csa->q]; /* less accurate */ - xassert(piv1 != 0.0); - if (fabs(piv1 - piv2) > 1e-8 * (1.0 + fabs(piv1)) || - !(piv1 > 0.0 && piv2 > 0.0 || piv1 < 0.0 && piv2 < 0.0)) - { if (parm->msg_lev >= GLP_MSG_DBG) - xprintf("piv1 = %.12g; piv2 = %.12g\n", piv1, piv2); - if (binv_st != 1 || !rigorous) - { if (binv_st != 1) binv_st = 0; - rigorous = 5; - goto loop; - } - /* (not a good idea; should be revised later) */ - if (csa->tcol_vec[csa->p] == 0.0) - { csa->tcol_nnz++; - xassert(csa->tcol_nnz <= csa->m); - csa->tcol_ind[csa->tcol_nnz] = csa->p; - } - csa->tcol_vec[csa->p] = piv2; - } - } - /* update primal values of basic variables */ -#ifdef GLP_LONG_STEP /* 07/IV-2009 */ - if (csa->nbps > 0) - { int kk, j, k; - for (kk = 1; kk < csa->nbps; kk++) - { if (csa->bkpt[kk].t >= csa->bkpt[csa->nbps].t) continue; - j = csa->bkpt[kk].j; - k = csa->head[csa->m + j]; - xassert(csa->type[k] == GLP_DB); - if (csa->stat[j] == GLP_NL) - csa->stat[j] = GLP_NU; - else - csa->stat[j] = GLP_NL; - } - } - bbar_st = 0; -#else - update_bbar(csa); - if (csa->phase == 2) - csa->bbar[0] += (csa->cbar[csa->q] / csa->zeta) * - (csa->delta / csa->tcol_vec[csa->p]); - bbar_st = 2; /* updated */ -#endif - /* update reduced costs of non-basic variables */ - update_cbar(csa); - cbar_st = 2; /* updated */ - /* update steepest edge coefficients */ - switch (parm->pricing) - { case GLP_PT_STD: - break; - case GLP_PT_PSE: - if (csa->refct > 0) update_gamma(csa); - break; - default: - xassert(parm != parm); - } - /* update factorization of the basis matrix */ - ret = update_B(csa, csa->p, csa->head[csa->m+csa->q]); - if (ret == 0) - binv_st = 2; /* updated */ - else - { csa->valid = 0; - binv_st = 0; /* invalid */ - } -#if 0 /* 06/IV-2009 */ - /* update matrix N */ - del_N_col(csa, csa->q, csa->head[csa->m+csa->q]); - if (csa->type[csa->head[csa->p]] != GLP_FX) - add_N_col(csa, csa->q, csa->head[csa->p]); -#endif - /* change the basis header */ - change_basis(csa); - /* iteration complete */ - csa->it_cnt++; -#if 1 /* 16/VII-2013 */ - if (-1e-9 <= csa->new_dq && csa->new_dq <= +1e-9) - { /* degenerated step */ - degen++; - } - else - { /* non-degenerated step */ - degen = 0; - } -#endif - if (rigorous > 0) rigorous--; - goto loop; -done: /* deallocate the common storage area */ - free_csa(csa); - /* return to the calling program */ - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpsql.c b/resources/3rdparty/glpk-4.53/src/glpsql.c deleted file mode 100644 index 8cd5cd08b..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpsql.c +++ /dev/null @@ -1,1644 +0,0 @@ -/* glpsql.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Author: Heinrich Schuchardt . -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "glpmpl.h" -#include "glpsql.h" - -#ifdef ODBC_DLNAME -#define HAVE_ODBC -#define libodbc ODBC_DLNAME -#define h_odbc (get_env_ptr()->h_odbc) -#endif - -#ifdef MYSQL_DLNAME -#define HAVE_MYSQL -#define libmysql MYSQL_DLNAME -#define h_mysql (get_env_ptr()->h_mysql) -#endif - -static void *db_iodbc_open_int(TABDCA *dca, int mode, const char - **sqllines); -static void *db_mysql_open_int(TABDCA *dca, int mode, const char - **sqllines); - -/**********************************************************************/ - -#if defined(HAVE_ODBC) || defined(HAVE_MYSQL) - -#define SQL_FIELD_MAX 100 -/* maximal field count */ - -#define SQL_FDLEN_MAX 255 -/* maximal field length */ - -/*********************************************************************** -* NAME -* -* args_concat - concatenate arguments -* -* SYNOPSIS -* -* static char **args_concat(TABDCA *dca); -* -* DESCRIPTION -* -* The arguments passed in dca are SQL statements. A SQL statement may -* be split over multiple arguments. The last argument of a SQL -* statement will be terminated with a semilocon. Each SQL statement is -* merged into a single zero terminated string. Boundaries between -* arguments are replaced by space. -* -* RETURNS -* -* Buffer with SQL statements */ - -static char **args_concat(TABDCA *dca) -{ - const char *arg; - int i; - int j; - int j0; - int j1; - int len; - int lentot; - int narg; - int nline = 0; - void *ret; - char **sqllines = NULL; - - narg = mpl_tab_num_args(dca); - /* The SQL statements start with argument 3. */ - if (narg < 3) - return NULL; - /* Count the SQL statements */ - for (j = 3; j <= narg; j++) - { - arg = mpl_tab_get_arg(dca, j); - len = strlen(arg); - if (arg[len-1] == ';' || j == narg) - nline ++; - } - /* Allocate string buffer. */ - sqllines = (char **) xmalloc((nline+1) * sizeof(char **)); - /* Join arguments */ - sqllines[0] = NULL; - j0 = 3; - i = 0; - lentot = 0; - for (j = 3; j <= narg; j++) - { - arg = mpl_tab_get_arg(dca, j); - len = strlen(arg); - /* add length of part */ - lentot += len; - /* add length of space separating parts or 0x00 at end of SQL - statement */ - lentot++; - if (arg[len-1] == ';' || j == narg) - { /* Join arguments for a single SQL statement */ - sqllines[i] = xmalloc(lentot); - sqllines[i+1] = NULL; - sqllines[i][0] = 0x00; - for (j1 = j0; j1 <= j; j1++) - { if(j1>j0) - strcat(sqllines[i], " "); - strcat(sqllines[i], mpl_tab_get_arg(dca, j1)); - } - len = strlen(sqllines[i]); - if (sqllines[i][len-1] == ';') - sqllines[i][len-1] = 0x00; - j0 = j+1; - i++; - lentot = 0; - } - } - return sqllines; -} - -/*********************************************************************** -* NAME -* -* free_buffer - free multiline string buffer -* -* SYNOPSIS -* -* static void free_buffer(char **buf); -* -* DESCRIPTION -* -* buf is a list of strings terminated by NULL. -* The memory for the strings and for the list is released. */ - -static void free_buffer(char **buf) -{ int i; - - for(i = 0; buf[i] != NULL; i++) - xfree(buf[i]); - xfree(buf); -} - -static int db_escaped_string_length(const char* from) -/* length of escaped string */ -{ - int count; - const char *pointer; - - for (pointer = from, count = 0; *pointer != (char) '\0'; pointer++, - count++) - { - switch (*pointer) - { - case '\'': - count++; - break; - } - } - - return count; -} - -static int db_escape_string (char *to, const char *from) -/* escape string*/ -{ - const char *source = from; - char *target = to; - unsigned int remaining; - - remaining = strlen(from); - - if (to == NULL) - to = (char *) (from + remaining); - - while (remaining > 0) - { - switch (*source) - { - case '\'': - *target = '\''; - target++; - *target = '\''; - break; - - default: - *target = *source; - } - source++; - target++; - remaining--; - } - - /* Write the terminating NUL character. */ - *target = '\0'; - - return target - to; -} - -static char *db_generate_select_stmt(TABDCA *dca) -/* generate select statement */ -{ - char *arg; - char const *field; - char *query; - int j; - int narg; - int nf; - int total; - - total = 50; - nf = mpl_tab_num_flds(dca); - narg = mpl_tab_num_args(dca); - for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) - { - field = mpl_tab_get_name(dca, j); - total += strlen(field); - total += 2; - } - arg = (char *) mpl_tab_get_arg(dca, narg); - total += strlen(arg); - query = xmalloc( total * sizeof(char)); - strcpy (query, "SELECT "); - for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) - { - field = mpl_tab_get_name(dca, j); - strcat(query, field); - if ( j < nf ) - strcat(query, ", "); - } - strcat(query, " FROM "); - strcat(query, arg); - return query; -} - -static char *db_generate_insert_stmt(TABDCA *dca) -/* generate insert statement */ -{ - char *arg; - char const *field; - char *query; - int j; - int narg; - int nf; - int total; - - total = 50; - nf = mpl_tab_num_flds(dca); - narg = mpl_tab_num_args(dca); - for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) - { - field = mpl_tab_get_name(dca, j); - total += strlen(field); - total += 5; - } - arg = (char *) mpl_tab_get_arg(dca, narg); - total += strlen(arg); - query = xmalloc( (total+1) * sizeof(char)); - strcpy (query, "INSERT INTO "); - strcat(query, arg); - strcat(query, " ( "); - for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) - { - field = mpl_tab_get_name(dca, j); - strcat(query, field); - if ( j < nf ) - strcat(query, ", "); - } - strcat(query, " ) VALUES ( "); - for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) - { - strcat(query, "?"); - if ( j < nf ) - strcat(query, ", "); - } - strcat(query, " )"); - return query; -} - -#endif - -/**********************************************************************/ - -#ifndef HAVE_ODBC - -void *db_iodbc_open(TABDCA *dca, int mode) -{ xassert(dca == dca); - xassert(mode == mode); - xprintf("iODBC table driver not supported\n"); - return NULL; -} - -int db_iodbc_read(TABDCA *dca, void *link) -{ xassert(dca != dca); - xassert(link != link); - return 0; -} - -int db_iodbc_write(TABDCA *dca, void *link) -{ xassert(dca != dca); - xassert(link != link); - return 0; -} - -int db_iodbc_close(TABDCA *dca, void *link) -{ xassert(dca != dca); - xassert(link != link); - return 0; -} - -#else - -#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WOE__) -#include -#endif - -#include -#include - -struct db_odbc -{ - int mode; /*'R' = Read, 'W' = Write*/ - SQLHDBC hdbc; /*connection handle*/ - SQLHENV henv; /*environment handle*/ - SQLHSTMT hstmt; /*statement handle*/ - SQLSMALLINT nresultcols; /* columns in result*/ - SQLULEN collen[SQL_FIELD_MAX+1]; - SQLLEN outlen[SQL_FIELD_MAX+1]; - SQLSMALLINT coltype[SQL_FIELD_MAX+1]; - SQLCHAR data[SQL_FIELD_MAX+1][SQL_FDLEN_MAX+1]; -#if 1 /* 12/I-2014 */ - SQLDOUBLE datanum[SQL_FIELD_MAX+1]; -#endif - SQLCHAR colname[SQL_FIELD_MAX+1][SQL_FDLEN_MAX+1]; - int isnumeric[SQL_FIELD_MAX+1]; - int nf; - /* number of fields in the csv file */ - int ref[1+SQL_FIELD_MAX]; - /* ref[k] = k', if k-th field of the csv file corresponds to - k'-th field in the table statement; if ref[k] = 0, k-th field - of the csv file is ignored */ - SQLCHAR *query; - /* query generated by db_iodbc_open */ -}; - -SQLRETURN SQL_API dl_SQLAllocHandle ( - SQLSMALLINT HandleType, - SQLHANDLE InputHandle, - SQLHANDLE *OutputHandle) -{ - typedef SQLRETURN SQL_API ep_SQLAllocHandle( - SQLSMALLINT HandleType, - SQLHANDLE InputHandle, - SQLHANDLE *OutputHandle); - - ep_SQLAllocHandle *fn; - fn = (ep_SQLAllocHandle *) xdlsym(h_odbc, "SQLAllocHandle"); - xassert(fn != NULL); - return (*fn)(HandleType, InputHandle, OutputHandle); -} - -SQLRETURN SQL_API dl_SQLBindCol ( - SQLHSTMT StatementHandle, - SQLUSMALLINT ColumnNumber, - SQLSMALLINT TargetType, - SQLPOINTER TargetValue, - SQLLEN BufferLength, - SQLLEN *StrLen_or_Ind) -{ - typedef SQLRETURN SQL_API ep_SQLBindCol( - SQLHSTMT StatementHandle, - SQLUSMALLINT ColumnNumber, - SQLSMALLINT TargetType, - SQLPOINTER TargetValue, - SQLLEN BufferLength, - SQLLEN *StrLen_or_Ind); - ep_SQLBindCol *fn; - fn = (ep_SQLBindCol *) xdlsym(h_odbc, "SQLBindCol"); - xassert(fn != NULL); - return (*fn)(StatementHandle, ColumnNumber, TargetType, - TargetValue, BufferLength, StrLen_or_Ind); -} - -SQLRETURN SQL_API dl_SQLCloseCursor ( - SQLHSTMT StatementHandle) -{ - typedef SQLRETURN SQL_API ep_SQLCloseCursor ( - SQLHSTMT StatementHandle); - - ep_SQLCloseCursor *fn; - fn = (ep_SQLCloseCursor *) xdlsym(h_odbc, "SQLCloseCursor"); - xassert(fn != NULL); - return (*fn)(StatementHandle); -} - - -SQLRETURN SQL_API dl_SQLDisconnect ( - SQLHDBC ConnectionHandle) -{ - typedef SQLRETURN SQL_API ep_SQLDisconnect( - SQLHDBC ConnectionHandle); - - ep_SQLDisconnect *fn; - fn = (ep_SQLDisconnect *) xdlsym(h_odbc, "SQLDisconnect"); - xassert(fn != NULL); - return (*fn)(ConnectionHandle); -} - -SQLRETURN SQL_API dl_SQLDriverConnect ( - SQLHDBC hdbc, - SQLHWND hwnd, - SQLCHAR *szConnStrIn, - SQLSMALLINT cbConnStrIn, - SQLCHAR *szConnStrOut, - SQLSMALLINT cbConnStrOutMax, - SQLSMALLINT *pcbConnStrOut, - SQLUSMALLINT fDriverCompletion) -{ - typedef SQLRETURN SQL_API ep_SQLDriverConnect( - SQLHDBC hdbc, - SQLHWND hwnd, - SQLCHAR * szConnStrIn, - SQLSMALLINT cbConnStrIn, - SQLCHAR * szConnStrOut, - SQLSMALLINT cbConnStrOutMax, - SQLSMALLINT * pcbConnStrOut, - SQLUSMALLINT fDriverCompletion); - - ep_SQLDriverConnect *fn; - fn = (ep_SQLDriverConnect *) xdlsym(h_odbc, "SQLDriverConnect"); - xassert(fn != NULL); - return (*fn)(hdbc, hwnd, szConnStrIn, cbConnStrIn, szConnStrOut, - cbConnStrOutMax, pcbConnStrOut, fDriverCompletion); -} - -SQLRETURN SQL_API dl_SQLEndTran ( - SQLSMALLINT HandleType, - SQLHANDLE Handle, - SQLSMALLINT CompletionType) -{ - typedef SQLRETURN SQL_API ep_SQLEndTran ( - SQLSMALLINT HandleType, - SQLHANDLE Handle, - SQLSMALLINT CompletionType); - - ep_SQLEndTran *fn; - fn = (ep_SQLEndTran *) xdlsym(h_odbc, "SQLEndTran"); - xassert(fn != NULL); - return (*fn)(HandleType, Handle, CompletionType); -} - -SQLRETURN SQL_API dl_SQLExecDirect ( - SQLHSTMT StatementHandle, - SQLCHAR * StatementText, - SQLINTEGER TextLength) -{ - typedef SQLRETURN SQL_API ep_SQLExecDirect ( - SQLHSTMT StatementHandle, - SQLCHAR * StatementText, - SQLINTEGER TextLength); - - ep_SQLExecDirect *fn; - fn = (ep_SQLExecDirect *) xdlsym(h_odbc, "SQLExecDirect"); - xassert(fn != NULL); - return (*fn)(StatementHandle, StatementText, TextLength); -} - -SQLRETURN SQL_API dl_SQLFetch ( - SQLHSTMT StatementHandle) -{ - typedef SQLRETURN SQL_API ep_SQLFetch ( - SQLHSTMT StatementHandle); - - ep_SQLFetch *fn; - fn = (ep_SQLFetch*) xdlsym(h_odbc, "SQLFetch"); - xassert(fn != NULL); - return (*fn)(StatementHandle); -} - -SQLRETURN SQL_API dl_SQLFreeHandle ( - SQLSMALLINT HandleType, - SQLHANDLE Handle) -{ - typedef SQLRETURN SQL_API ep_SQLFreeHandle ( - SQLSMALLINT HandleType, - SQLHANDLE Handle); - - ep_SQLFreeHandle *fn; - fn = (ep_SQLFreeHandle *) xdlsym(h_odbc, "SQLFreeHandle"); - xassert(fn != NULL); - return (*fn)(HandleType, Handle); -} - -SQLRETURN SQL_API dl_SQLDescribeCol ( - SQLHSTMT StatementHandle, - SQLUSMALLINT ColumnNumber, - SQLCHAR * ColumnName, - SQLSMALLINT BufferLength, - SQLSMALLINT * NameLength, - SQLSMALLINT * DataType, - SQLULEN * ColumnSize, - SQLSMALLINT * DecimalDigits, - SQLSMALLINT * Nullable) -{ - typedef SQLRETURN SQL_API ep_SQLDescribeCol ( - SQLHSTMT StatementHandle, - SQLUSMALLINT ColumnNumber, - SQLCHAR *ColumnName, - SQLSMALLINT BufferLength, - SQLSMALLINT *NameLength, - SQLSMALLINT *DataType, - SQLULEN *ColumnSize, - SQLSMALLINT *DecimalDigits, - SQLSMALLINT *Nullable); - - ep_SQLDescribeCol *fn; - fn = (ep_SQLDescribeCol *) xdlsym(h_odbc, "SQLDescribeCol"); - xassert(fn != NULL); - return (*fn)(StatementHandle, ColumnNumber, ColumnName, - BufferLength, NameLength, - DataType, ColumnSize, DecimalDigits, Nullable); -} - -SQLRETURN SQL_API dl_SQLGetDiagRec ( - SQLSMALLINT HandleType, - SQLHANDLE Handle, - SQLSMALLINT RecNumber, - SQLCHAR *Sqlstate, - SQLINTEGER *NativeError, - SQLCHAR *MessageText, - SQLSMALLINT BufferLength, - SQLSMALLINT *TextLength) -{ - typedef SQLRETURN SQL_API ep_SQLGetDiagRec ( - SQLSMALLINT HandleType, - SQLHANDLE Handle, - SQLSMALLINT RecNumber, - SQLCHAR *Sqlstate, - SQLINTEGER *NativeError, - SQLCHAR *MessageText, - SQLSMALLINT BufferLength, - SQLSMALLINT *TextLength); - - ep_SQLGetDiagRec *fn; - fn = (ep_SQLGetDiagRec *) xdlsym(h_odbc, "SQLGetDiagRec"); - xassert(fn != NULL); - return (*fn)(HandleType, Handle, RecNumber, Sqlstate, - NativeError, MessageText, BufferLength, TextLength); -} - -SQLRETURN SQL_API dl_SQLGetInfo ( - SQLHDBC ConnectionHandle, - SQLUSMALLINT InfoType, - SQLPOINTER InfoValue, - SQLSMALLINT BufferLength, - SQLSMALLINT *StringLength) -{ - typedef SQLRETURN SQL_API ep_SQLGetInfo ( - SQLHDBC ConnectionHandle, - SQLUSMALLINT InfoType, - SQLPOINTER InfoValue, - SQLSMALLINT BufferLength, - SQLSMALLINT *StringLength); - - ep_SQLGetInfo *fn; - fn = (ep_SQLGetInfo *) xdlsym(h_odbc, "SQLGetInfo"); - xassert(fn != NULL); - return (*fn)(ConnectionHandle, InfoType, InfoValue, BufferLength, - StringLength); -} - -SQLRETURN SQL_API dl_SQLNumResultCols ( - SQLHSTMT StatementHandle, - SQLSMALLINT *ColumnCount) -{ - typedef SQLRETURN SQL_API ep_SQLNumResultCols ( - SQLHSTMT StatementHandle, - SQLSMALLINT *ColumnCount); - - ep_SQLNumResultCols *fn; - fn = (ep_SQLNumResultCols *) xdlsym(h_odbc, "SQLNumResultCols"); - xassert(fn != NULL); - return (*fn)(StatementHandle, ColumnCount); -} - -SQLRETURN SQL_API dl_SQLSetConnectAttr ( - SQLHDBC ConnectionHandle, - SQLINTEGER Attribute, - SQLPOINTER Value, - SQLINTEGER StringLength) -{ - typedef SQLRETURN SQL_API ep_SQLSetConnectAttr ( - SQLHDBC ConnectionHandle, - SQLINTEGER Attribute, - SQLPOINTER Value, - SQLINTEGER StringLength); - - ep_SQLSetConnectAttr *fn; - fn = (ep_SQLSetConnectAttr *) xdlsym(h_odbc, "SQLSetConnectAttr"); - xassert(fn != NULL); - return (*fn)(ConnectionHandle, Attribute, Value, StringLength); -} - -SQLRETURN SQL_API dl_SQLSetEnvAttr ( - SQLHENV EnvironmentHandle, - SQLINTEGER Attribute, - SQLPOINTER Value, - SQLINTEGER StringLength) -{ - typedef SQLRETURN SQL_API ep_SQLSetEnvAttr ( - SQLHENV EnvironmentHandle, - SQLINTEGER Attribute, - SQLPOINTER Value, - SQLINTEGER StringLength); - - ep_SQLSetEnvAttr *fn; - fn = (ep_SQLSetEnvAttr *) xdlsym(h_odbc, "SQLSetEnvAttr"); - xassert(fn != NULL); - return (*fn)(EnvironmentHandle, Attribute, Value, StringLength); -} - -static void extract_error( - char *fn, - SQLHANDLE handle, - SQLSMALLINT type); - -static int is_numeric( - SQLSMALLINT coltype); - -/*********************************************************************** -* NAME -* -* db_iodbc_open - open connection to ODBC data base -* -* SYNOPSIS -* -* #include "glpsql.h" -* void *db_iodbc_open(TABDCA *dca, int mode); -* -* DESCRIPTION -* -* The routine db_iodbc_open opens a connection to an ODBC data base. -* It then executes the sql statements passed. -* -* In the case of table read the SELECT statement is executed. -* -* In the case of table write the INSERT statement is prepared. -* RETURNS -* -* The routine returns a pointer to data storage area created. */ -void *db_iodbc_open(TABDCA *dca, int mode) -{ void *ret; - char **sqllines; - - sqllines = args_concat(dca); - if (sqllines == NULL) - { xprintf("Missing arguments in table statement.\n" - "Please, supply table driver, dsn, and query.\n"); - return NULL; - } - ret = db_iodbc_open_int(dca, mode, (const char **) sqllines); - free_buffer(sqllines); - return ret; -} - -static void *db_iodbc_open_int(TABDCA *dca, int mode, const char - **sqllines) -{ - struct db_odbc *sql; - SQLRETURN ret; - SQLCHAR FAR *dsn; - SQLCHAR info[256]; - SQLSMALLINT colnamelen; - SQLSMALLINT nullable; - SQLSMALLINT scale; - const char *arg; - int narg; - int i, j; - int total; - - if (libodbc == NULL) - { - xprintf("No loader for shared ODBC library available\n"); - return NULL; - } - - if (h_odbc == NULL) - { - h_odbc = xdlopen(libodbc); - if (h_odbc == NULL) - { xprintf("unable to open library %s\n", libodbc); - xprintf("%s\n", get_err_msg()); - return NULL; - } - } - - sql = (struct db_odbc *) xmalloc(sizeof(struct db_odbc)); - if (sql == NULL) - return NULL; - - sql->mode = mode; - sql->hdbc = NULL; - sql->henv = NULL; - sql->hstmt = NULL; - sql->query = NULL; - narg = mpl_tab_num_args(dca); - - dsn = (SQLCHAR FAR *) mpl_tab_get_arg(dca, 2); - /* allocate an environment handle */ - ret = dl_SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, - &(sql->henv)); - /* set attribute to enable application to run as ODBC 3.0 - application */ - ret = dl_SQLSetEnvAttr(sql->henv, SQL_ATTR_ODBC_VERSION, - (void *) SQL_OV_ODBC3, 0); - /* allocate a connection handle */ - ret = dl_SQLAllocHandle(SQL_HANDLE_DBC, sql->henv, &(sql->hdbc)); - /* connect */ - ret = dl_SQLDriverConnect(sql->hdbc, NULL, dsn, SQL_NTS, NULL, 0, - NULL, SQL_DRIVER_COMPLETE); - if (SQL_SUCCEEDED(ret)) - { /* output information about data base connection */ - xprintf("Connected to "); - dl_SQLGetInfo(sql->hdbc, SQL_DBMS_NAME, (SQLPOINTER)info, - sizeof(info), NULL); - xprintf("%s ", info); - dl_SQLGetInfo(sql->hdbc, SQL_DBMS_VER, (SQLPOINTER)info, - sizeof(info), NULL); - xprintf("%s - ", info); - dl_SQLGetInfo(sql->hdbc, SQL_DATABASE_NAME, (SQLPOINTER)info, - sizeof(info), NULL); - xprintf("%s\n", info); - } - else - { /* describe error */ - xprintf("Failed to connect\n"); - extract_error("SQLDriverConnect", sql->hdbc, SQL_HANDLE_DBC); - dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); - dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); - xfree(sql); - return NULL; - } - /* set AUTOCOMMIT on*/ - ret = dl_SQLSetConnectAttr(sql->hdbc, SQL_ATTR_AUTOCOMMIT, - (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0); - /* allocate a statement handle */ - ret = dl_SQLAllocHandle(SQL_HANDLE_STMT, sql->hdbc, &(sql->hstmt)); - - /* initialization queries */ - for(j = 0; sqllines[j+1] != NULL; j++) - { - sql->query = (SQLCHAR *) sqllines[j]; - xprintf("%s\n", sql->query); - ret = dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS); - switch (ret) - { - case SQL_SUCCESS: - case SQL_SUCCESS_WITH_INFO: - case SQL_NO_DATA_FOUND: - break; - default: - xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n", - sql->query); - extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT); - dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); - dl_SQLDisconnect(sql->hdbc); - dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); - dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); - xfree(sql); - return NULL; - } - /* commit statement */ - dl_SQLEndTran(SQL_HANDLE_ENV, sql->henv, SQL_COMMIT); - } - - if ( sql->mode == 'R' ) - { sql->nf = mpl_tab_num_flds(dca); - for(j = 0; sqllines[j] != NULL; j++) - arg = sqllines[j]; - total = strlen(arg); - if (total > 7 && 0 == strncmp(arg, "SELECT ", 7)) - { - total = strlen(arg); - sql->query = xmalloc( (total+1) * sizeof(char)); - strcpy (sql->query, arg); - } - else - { - sql->query = db_generate_select_stmt(dca); - } - xprintf("%s\n", sql->query); - if (dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS) != - SQL_SUCCESS) - { - xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n", sql->query); - extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT); - dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); - dl_SQLDisconnect(sql->hdbc); - dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); - dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); - xfree(sql->query); - xfree(sql); - return NULL; - } - xfree(sql->query); - /* determine number of result columns */ - ret = dl_SQLNumResultCols(sql->hstmt, &sql->nresultcols); - total = sql->nresultcols; - if (total > SQL_FIELD_MAX) - { xprintf("db_iodbc_open: Too many fields (> %d) in query.\n" - "\"%s\"\n", SQL_FIELD_MAX, sql->query); - dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); - dl_SQLDisconnect(sql->hdbc); - dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); - dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); - xfree(sql->query); - return NULL; - } - for (i = 1; i <= total; i++) - { /* return a set of attributes for a column */ - ret = dl_SQLDescribeCol(sql->hstmt, (SQLSMALLINT) i, - sql->colname[i], SQL_FDLEN_MAX, - &colnamelen, &(sql->coltype[i]), &(sql->collen[i]), &scale, - &nullable); - sql->isnumeric[i] = is_numeric(sql->coltype[i]); - /* bind columns to program vars, converting all types to CHAR*/ - if (sql->isnumeric[i]) -#if 0 /* 12/I-2014 */ - { dl_SQLBindCol(sql->hstmt, i, SQL_DOUBLE, sql->data[i], -#else - { dl_SQLBindCol(sql->hstmt, i, SQL_DOUBLE, &sql->datanum[i], -#endif - SQL_FDLEN_MAX, &(sql->outlen[i])); - } else - { dl_SQLBindCol(sql->hstmt, i, SQL_CHAR, sql->data[i], - SQL_FDLEN_MAX, &(sql->outlen[i])); - } - for (j = sql->nf; j >= 1; j--) - { if (strcmp(mpl_tab_get_name(dca, j), sql->colname[i]) == 0) - break; - } - sql->ref[i] = j; - } - } - else if ( sql->mode == 'W' ) - { for(j = 0; sqllines[j] != NULL; j++) - arg = sqllines[j]; - if ( NULL != strchr(arg, '?') ) - { - total = strlen(arg); - sql->query = xmalloc( (total+1) * sizeof(char)); - strcpy (sql->query, arg); - } - else - { - sql->query = db_generate_insert_stmt(dca); - } - xprintf("%s\n", sql->query); - } - return sql; -} - -int db_iodbc_read(TABDCA *dca, void *link) -{ - struct db_odbc *sql; - SQLRETURN ret; - char buf[SQL_FDLEN_MAX+1]; - int i; - int len; - double num; - - sql = (struct db_odbc *) link; - - xassert(sql != NULL); - xassert(sql->mode == 'R'); - - ret=dl_SQLFetch(sql->hstmt); - if (ret== SQL_ERROR) - return -1; - if (ret== SQL_NO_DATA_FOUND) - return -1; /*EOF*/ - for (i=1; i <= sql->nresultcols; i++) - { - if (sql->ref[i] > 0) - { - len = sql->outlen[i]; - if (len != SQL_NULL_DATA) - { - if (sql->isnumeric[i]) - { mpl_tab_set_num(dca, sql->ref[i], -#if 0 /* 12/I-2014 */ - *((const double *) sql->data[i])); -#else - (const double) sql->datanum[i]); -#endif - } - else - { if (len > SQL_FDLEN_MAX) - len = SQL_FDLEN_MAX; - else if (len < 0) - len = 0; - strncpy(buf, (const char *) sql->data[i], len); - buf[len] = 0x00; - mpl_tab_set_str(dca, sql->ref[i], strtrim(buf)); - } - } - } - } - return 0; -} - -int db_iodbc_write(TABDCA *dca, void *link) -{ - struct db_odbc *sql; - char *part; - char *query; - char *template; - char num[50]; - int k; - int len; - int nf; - - sql = (struct db_odbc *) link; - xassert(sql != NULL); - xassert(sql->mode == 'W'); - - len = strlen(sql->query); - template = (char *) xmalloc( (len + 1) * sizeof(char) ); - strcpy(template, sql->query); - - nf = mpl_tab_num_flds(dca); - for (k = 1; k <= nf; k++) - { switch (mpl_tab_get_type(dca, k)) - { case 'N': - len += 20; - break; - case 'S': - len += db_escaped_string_length(mpl_tab_get_str(dca, k)); - len += 2; - break; - default: - xassert(dca != dca); - } - } - query = xmalloc( (len + 1 ) * sizeof(char) ); - query[0] = 0x00; - for (k = 1, part = strtok (template, "?"); (part != NULL); - part = strtok (NULL, "?"), k++) - { - if (k > nf) break; - strcat( query, part ); - switch (mpl_tab_get_type(dca, k)) - { case 'N': -#if 0 /* 02/XI-2010 by xypron */ - sprintf(num, "%-18g",mpl_tab_get_num(dca, k)); -#else - sprintf(num, "%.*g", DBL_DIG, mpl_tab_get_num(dca, k)); -#endif - strcat( query, num ); - break; - case 'S': - strcat( query, "'"); - db_escape_string( query + strlen(query), - mpl_tab_get_str(dca, k) ); - strcat( query, "'"); - break; - default: - xassert(dca != dca); - } - } - if (part != NULL) - strcat(query, part); - if (dl_SQLExecDirect(sql->hstmt, (SQLCHAR *) query, SQL_NTS) - != SQL_SUCCESS) - { - xprintf("db_iodbc_write: Query\n\"%s\"\nfailed.\n", query); - extract_error("SQLExecDirect", sql->hdbc, SQL_HANDLE_DBC); - xfree(query); - xfree(template); - return 1; - } - - xfree(query); - xfree(template); - return 0; -} - -int db_iodbc_close(TABDCA *dca, void *link) -{ - struct db_odbc *sql; - - sql = (struct db_odbc *) link; - xassert(sql != NULL); - /* Commit */ - if ( sql->mode == 'W' ) - dl_SQLEndTran(SQL_HANDLE_ENV, sql->henv, SQL_COMMIT); - if ( sql->mode == 'R' ) - dl_SQLCloseCursor(sql->hstmt); - - dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); - dl_SQLDisconnect(sql->hdbc); - dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); - dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); - if ( sql->mode == 'W' ) - xfree(sql->query); - xfree(sql); - dca->link = NULL; - return 0; -} - -static void extract_error( - char *fn, - SQLHANDLE handle, - SQLSMALLINT type) -{ - SQLINTEGER i = 0; - SQLINTEGER native; - SQLCHAR state[ 7 ]; - SQLCHAR text[256]; - SQLSMALLINT len; - SQLRETURN ret; - - xprintf("\nThe driver reported the following diagnostics whilst " - "running %s\n", fn); - - do - { - ret = dl_SQLGetDiagRec(type, handle, ++i, state, &native, text, - sizeof(text), &len ); - if (SQL_SUCCEEDED(ret)) - xprintf("%s:%ld:%ld:%s\n", state, i, native, text); - } - while( ret == SQL_SUCCESS ); -} - -static int is_numeric(SQLSMALLINT coltype) -{ - int ret = 0; - switch (coltype) - { - case SQL_DECIMAL: - case SQL_NUMERIC: - case SQL_SMALLINT: - case SQL_INTEGER: - case SQL_REAL: - case SQL_FLOAT: - case SQL_DOUBLE: - case SQL_TINYINT: - case SQL_BIGINT: - ret = 1; - break; - } - return ret; -} - -#endif - -/**********************************************************************/ - -#ifndef HAVE_MYSQL - -void *db_mysql_open(TABDCA *dca, int mode) -{ xassert(dca == dca); - xassert(mode == mode); - xprintf("MySQL table driver not supported\n"); - return NULL; -} - -int db_mysql_read(TABDCA *dca, void *link) -{ xassert(dca != dca); - xassert(link != link); - return 0; -} - -int db_mysql_write(TABDCA *dca, void *link) -{ xassert(dca != dca); - xassert(link != link); - return 0; -} - -int db_mysql_close(TABDCA *dca, void *link) -{ xassert(dca != dca); - xassert(link != link); - return 0; -} - -#else - -#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WOE__) -#include -#endif - -#ifdef __CYGWIN__ -#define byte_defined 1 -#endif - -#if 0 /* 12/II-2014; to fix namespace bug */ -#include -#include -#endif -#include - -struct db_mysql -{ - int mode; /*'R' = Read, 'W' = Write*/ - MYSQL *con; /*connection*/ - MYSQL_RES *res; /*result*/ - int nf; - /* number of fields in the csv file */ - int ref[1+SQL_FIELD_MAX]; - /* ref[k] = k', if k-th field of the csv file corresponds to - k'-th field in the table statement; if ref[k] = 0, k-th field - of the csv file is ignored */ - char *query; - /* query generated by db_mysql_open */ -}; - -void STDCALL dl_mysql_close(MYSQL *sock) -{ - typedef void STDCALL ep_mysql_close(MYSQL *sock); - - ep_mysql_close *fn; - fn = (ep_mysql_close *) xdlsym(h_mysql, "mysql_close"); - xassert(fn != NULL); - return (*fn)(sock); -} - -const char * STDCALL dl_mysql_error(MYSQL *mysql) -{ - typedef const char * STDCALL ep_mysql_error(MYSQL *mysql); - - ep_mysql_error *fn; - fn = (ep_mysql_error *) xdlsym(h_mysql, "mysql_error"); - xassert(fn != NULL); - return (*fn)(mysql); -} - -MYSQL_FIELD * STDCALL dl_mysql_fetch_fields(MYSQL_RES *res) -{ - typedef MYSQL_FIELD * STDCALL - ep_mysql_fetch_fields(MYSQL_RES *res); - - ep_mysql_fetch_fields *fn; - fn = (ep_mysql_fetch_fields *) xdlsym(h_mysql, "mysql_fetch_fields"); - xassert(fn != NULL); - return (*fn)(res); -} - -unsigned long * STDCALL dl_mysql_fetch_lengths(MYSQL_RES *result) -{ - typedef unsigned long * STDCALL - ep_mysql_fetch_lengths(MYSQL_RES *result); - - ep_mysql_fetch_lengths *fn; - fn = (ep_mysql_fetch_lengths *) xdlsym(h_mysql, - "mysql_fetch_lengths"); - xassert(fn != NULL); - return (*fn)(result); -} - -MYSQL_ROW STDCALL dl_mysql_fetch_row(MYSQL_RES *result) -{ - typedef MYSQL_ROW STDCALL ep_mysql_fetch_row(MYSQL_RES *result); - - ep_mysql_fetch_row *fn; - fn = (ep_mysql_fetch_row *) xdlsym(h_mysql, "mysql_fetch_row"); - xassert(fn != NULL); - return (*fn)(result); -} - -unsigned int STDCALL dl_mysql_field_count(MYSQL *mysql) -{ - typedef unsigned int STDCALL ep_mysql_field_count(MYSQL *mysql); - - ep_mysql_field_count *fn; - fn = (ep_mysql_field_count *) xdlsym(h_mysql, "mysql_field_count"); - xassert(fn != NULL); - return (*fn)(mysql); -} - -MYSQL * STDCALL dl_mysql_init(MYSQL *mysql) -{ - typedef MYSQL * STDCALL ep_mysql_init(MYSQL *mysql); - - ep_mysql_init *fn; - fn = (ep_mysql_init *) xdlsym(h_mysql, "mysql_init"); - xassert(fn != NULL); - return (*fn)(mysql); -} - -unsigned int STDCALL dl_mysql_num_fields(MYSQL_RES *res) -{ - typedef unsigned int STDCALL ep_mysql_num_fields(MYSQL_RES *res); - - ep_mysql_num_fields *fn; - fn = (ep_mysql_num_fields *) xdlsym(h_mysql, "mysql_num_fields"); - xassert(fn != NULL); - return (*fn)(res); -} - -int STDCALL dl_mysql_query(MYSQL *mysql, const char *q) -{ - typedef int STDCALL ep_mysql_query(MYSQL *mysql, const char *q); - - ep_mysql_query *fn; - fn = (ep_mysql_query *) xdlsym(h_mysql, "mysql_query"); - xassert(fn != NULL); - return (*fn)(mysql, q); -} - -MYSQL * STDCALL dl_mysql_real_connect(MYSQL *mysql, const char *host, - const char *user, - const char *passwd, - const char *db, - unsigned int port, - const char *unix_socket, - unsigned long clientflag) -{ - typedef MYSQL * STDCALL ep_mysql_real_connect(MYSQL *mysql, - const char *host, - const char *user, - const char *passwd, - const char *db, - unsigned int port, - const char *unix_socket, - unsigned long clientflag); - - ep_mysql_real_connect *fn; - fn = (ep_mysql_real_connect *) xdlsym(h_mysql, - "mysql_real_connect"); - xassert(fn != NULL); - return (*fn)(mysql, host, user, passwd, db, port, unix_socket, - clientflag); -} - -MYSQL_RES * STDCALL dl_mysql_use_result(MYSQL *mysql) -{ - typedef MYSQL_RES * STDCALL ep_mysql_use_result(MYSQL *mysql); - ep_mysql_use_result *fn; - fn = (ep_mysql_use_result *) xdlsym(h_mysql, "mysql_use_result"); - xassert(fn != NULL); - return (*fn)(mysql); -} - -/*********************************************************************** -* NAME -* -* db_mysql_open - open connection to ODBC data base -* -* SYNOPSIS -* -* #include "glpsql.h" -* void *db_mysql_open(TABDCA *dca, int mode); -* -* DESCRIPTION -* -* The routine db_mysql_open opens a connection to a MySQL data base. -* It then executes the sql statements passed. -* -* In the case of table read the SELECT statement is executed. -* -* In the case of table write the INSERT statement is prepared. -* RETURNS -* -* The routine returns a pointer to data storage area created. */ - -void *db_mysql_open(TABDCA *dca, int mode) -{ void *ret; - char **sqllines; - - sqllines = args_concat(dca); - if (sqllines == NULL) - { xprintf("Missing arguments in table statement.\n" - "Please, supply table driver, dsn, and query.\n"); - return NULL; - } - ret = db_mysql_open_int(dca, mode, (const char **) sqllines); - free_buffer(sqllines); - return ret; -} - -static void *db_mysql_open_int(TABDCA *dca, int mode, const char - **sqllines) -{ - struct db_mysql *sql = NULL; - char *arg = NULL; - const char *field; - MYSQL_FIELD *fields; - char *keyword; - char *value; - char *query; - char *dsn; -/* "Server=[server_name];Database=[database_name];UID=[username];*/ -/* PWD=[password];Port=[port]"*/ - char *server = NULL; /* Server */ - char *user = NULL; /* UID */ - char *password = NULL; /* PWD */ - char *database = NULL; /* Database */ - unsigned int port = 0; /* Port */ - int narg; - int i, j, total; - - if (libmysql == NULL) - { - xprintf("No loader for shared MySQL library available\n"); - return NULL; - } - - if (h_mysql == NULL) - { - h_mysql = xdlopen(libmysql); - if (h_mysql == NULL) - { xprintf("unable to open library %s\n", libmysql); - xprintf("%s\n", get_err_msg()); - return NULL; - } - } - - sql = (struct db_mysql *) xmalloc(sizeof(struct db_mysql)); - if (sql == NULL) - return NULL; - sql->mode = mode; - sql->res = NULL; - sql->query = NULL; - sql->nf = mpl_tab_num_flds(dca); - - narg = mpl_tab_num_args(dca); - if (narg < 3 ) - xprintf("MySQL driver: string list too short \n"); - - /* get connection string*/ - dsn = (char *) mpl_tab_get_arg(dca, 2); - /* copy connection string*/ - i = strlen(dsn); - i++; - arg = xmalloc(i * sizeof(char)); - strcpy(arg, dsn); - /*tokenize connection string*/ - for (i = 1, keyword = strtok (arg, "="); (keyword != NULL); - keyword = strtok (NULL, "="), i++) - { - value = strtok (NULL, ";"); - if (value==NULL) - { - xprintf("db_mysql_open: Missing value for keyword %s\n", - keyword); - xfree(arg); - xfree(sql); - return NULL; - } - if (0 == strcmp(keyword, "Server")) - server = value; - else if (0 == strcmp(keyword, "Database")) - database = value; - else if (0 == strcmp(keyword, "UID")) - user = value; - else if (0 == strcmp(keyword, "PWD")) - password = value; - else if (0 == strcmp(keyword, "Port")) - port = (unsigned int) atol(value); - } - /* Connect to database */ - sql->con = dl_mysql_init(NULL); - if (!dl_mysql_real_connect(sql->con, server, user, password, database, - port, NULL, 0)) - { - xprintf("db_mysql_open: Connect failed\n"); - xprintf("%s\n", dl_mysql_error(sql->con)); - xfree(arg); - xfree(sql); - return NULL; - } - xfree(arg); - - for(j = 0; sqllines[j+1] != NULL; j++) - { query = (char *) sqllines[j]; - xprintf("%s\n", query); - if (dl_mysql_query(sql->con, query)) - { - xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query); - xprintf("%s\n",dl_mysql_error(sql->con)); - dl_mysql_close(sql->con); - xfree(sql); - return NULL; - } - } - - if ( sql->mode == 'R' ) - { sql->nf = mpl_tab_num_flds(dca); - for(j = 0; sqllines[j] != NULL; j++) - arg = (char *) sqllines[j]; - total = strlen(arg); - if (total > 7 && 0 == strncmp(arg, "SELECT ", 7)) - { - total = strlen(arg); - query = xmalloc( (total+1) * sizeof(char)); - strcpy (query, arg); - } - else - { - query = db_generate_select_stmt(dca); - } - xprintf("%s\n", query); - if (dl_mysql_query(sql->con, query)) - { - xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query); - xprintf("%s\n",dl_mysql_error(sql->con)); - dl_mysql_close(sql->con); - xfree(query); - xfree(sql); - return NULL; - } - xfree(query); - sql->res = dl_mysql_use_result(sql->con); - if (sql->res) - { - /* create references between query results and table fields*/ - total = dl_mysql_num_fields(sql->res); - if (total > SQL_FIELD_MAX) - { xprintf("db_mysql_open: Too many fields (> %d) in query.\n" - "\"%s\"\n", SQL_FIELD_MAX, query); - xprintf("%s\n",dl_mysql_error(sql->con)); - dl_mysql_close(sql->con); - xfree(query); - xfree(sql); - return NULL; - } - fields = dl_mysql_fetch_fields(sql->res); - for (i = 1; i <= total; i++) - { - for (j = sql->nf; j >= 1; j--) - { - if (strcmp(mpl_tab_get_name(dca, j), fields[i-1].name) - == 0) - break; - } - sql->ref[i] = j; - } - } - else - { - if(dl_mysql_field_count(sql->con) == 0) - { - xprintf("db_mysql_open: Query was not a SELECT\n\"%s\"\n", - query); - xprintf("%s\n",dl_mysql_error(sql->con)); - xfree(query); - xfree(sql); - return NULL; - } - else - { - xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query); - xprintf("%s\n",dl_mysql_error(sql->con)); - xfree(query); - xfree(sql); - return NULL; - } - } - } - else if ( sql->mode == 'W' ) - { for(j = 0; sqllines[j] != NULL; j++) - arg = (char *) sqllines[j]; - if ( NULL != strchr(arg, '?') ) - { - total = strlen(arg); - query = xmalloc( (total+1) * sizeof(char)); - strcpy (query, arg); - } - else - query = db_generate_insert_stmt(dca); - sql->query = query; - xprintf("%s\n", query); - } - return sql; -} - -int db_mysql_read(TABDCA *dca, void *link) -{ struct db_mysql *sql; - char buf[255+1]; - char **row; - unsigned long *lengths; - MYSQL_FIELD *fields; - double num; - int len; - unsigned long num_fields; - int i; - - sql = (struct db_mysql *) link; - - xassert(sql != NULL); - xassert(sql->mode == 'R'); - if (NULL == sql->res) - { - xprintf("db_mysql_read: no result set available"); - return 1; - } - if (NULL==(row = (char **)dl_mysql_fetch_row(sql->res))) { - return -1; /*EOF*/ - } - lengths = dl_mysql_fetch_lengths(sql->res); - fields = dl_mysql_fetch_fields(sql->res); - num_fields = dl_mysql_num_fields(sql->res); - for (i=1; i <= num_fields; i++) - { - if (row[i-1] != NULL) - { len = (size_t) lengths[i-1]; - if (len > 255) - len = 255; - strncpy(buf, (const char *) row[i-1], len); - buf[len] = 0x00; - if (0 != (fields[i-1].flags & NUM_FLAG)) - { strspx(buf); /* remove spaces*/ - if (str2num(buf, &num) != 0) - { xprintf("'%s' cannot be converted to a number.\n", buf); - return 1; - } - if (sql->ref[i] > 0) - mpl_tab_set_num(dca, sql->ref[i], num); - } - else - { if (sql->ref[i] > 0) - mpl_tab_set_str(dca, sql->ref[i], strtrim(buf)); - } - } - } - return 0; -} - -int db_mysql_write(TABDCA *dca, void *link) -{ - struct db_mysql *sql; - char *part; - char *query; - char *template; - char num[50]; - int k; - int len; - int nf; - - sql = (struct db_mysql *) link; - xassert(sql != NULL); - xassert(sql->mode == 'W'); - - len = strlen(sql->query); - template = (char *) xmalloc( (len + 1) * sizeof(char) ); - strcpy(template, sql->query); - - nf = mpl_tab_num_flds(dca); - for (k = 1; k <= nf; k++) - { switch (mpl_tab_get_type(dca, k)) - { case 'N': - len += 20; - break; - case 'S': - len += db_escaped_string_length(mpl_tab_get_str(dca, k)); - len += 2; - break; - default: - xassert(dca != dca); - } - } - query = xmalloc( (len + 1 ) * sizeof(char) ); - query[0] = 0x00; - for (k = 1, part = strtok (template, "?"); (part != NULL); - part = strtok (NULL, "?"), k++) - { - if (k > nf) break; - strcat( query, part ); - switch (mpl_tab_get_type(dca, k)) - { case 'N': -#if 0 /* 02/XI-2010 by xypron */ - sprintf(num, "%-18g",mpl_tab_get_num(dca, k)); -#else - sprintf(num, "%.*g", DBL_DIG, mpl_tab_get_num(dca, k)); -#endif - strcat( query, num ); - break; - case 'S': - strcat( query, "'"); - db_escape_string( query + strlen(query), - mpl_tab_get_str(dca, k) ); - strcat( query, "'"); - break; - default: - xassert(dca != dca); - } - } - if (part != NULL) - strcat(query, part); - if (dl_mysql_query(sql->con, query)) - { - xprintf("db_mysql_write: Query\n\"%s\"\nfailed.\n", query); - xprintf("%s\n",dl_mysql_error(sql->con)); - xfree(query); - xfree(template); - return 1; - } - - xfree(query); - xfree(template); - return 0; - } - -int db_mysql_close(TABDCA *dca, void *link) -{ - struct db_mysql *sql; - - sql = (struct db_mysql *) link; - xassert(sql != NULL); - dl_mysql_close(sql->con); - if ( sql->mode == 'W' ) - xfree(sql->query); - xfree(sql); - dca->link = NULL; - return 0; -} - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpsql.h b/resources/3rdparty/glpk-4.53/src/glpsql.h deleted file mode 100644 index 2a1650561..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpsql.h +++ /dev/null @@ -1,64 +0,0 @@ -/* glpsql.h */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Author: Heinrich Schuchardt . -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPSQL_H -#define GLPSQL_H - -#define db_iodbc_open _glp_db_iodbc_open -void *db_iodbc_open(TABDCA *dca, int mode); -/* open iODBC database connection */ - -#define db_iodbc_read _glp_db_iodbc_read -int db_iodbc_read(TABDCA *dca, void *link); -/* read data from iODBC */ - -#define db_iodbc_write _glp_db_iodbc_write -int db_iodbc_write(TABDCA *dca, void *link); -/* write data to iODBC */ - -#define db_iodbc_close _glp_db_iodbc_close -int db_iodbc_close(TABDCA *dca, void *link); -/* close iODBC database connection */ - -#define db_mysql_open _glp_db_mysql_open -void *db_mysql_open(TABDCA *dca, int mode); -/* open MySQL database connection */ - -#define db_mysql_read _glp_db_mysql_read -int db_mysql_read(TABDCA *dca, void *link); -/* read data from MySQL */ - -#define db_mysql_write _glp_db_mysql_write -int db_mysql_write(TABDCA *dca, void *link); -/* write data to MySQL */ - -#define db_mysql_close _glp_db_mysql_close -int db_mysql_close(TABDCA *dca, void *link); -/* close MySQL database connection */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpssx.h b/resources/3rdparty/glpk-4.53/src/glpssx.h deleted file mode 100644 index 1b55d7a3d..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpssx.h +++ /dev/null @@ -1,426 +0,0 @@ -/* glpssx.h (simplex method, rational arithmetic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPSSX_H -#define GLPSSX_H - -#include "bfx.h" -#include "env.h" - -typedef struct SSX SSX; - -struct SSX -{ /* simplex solver workspace */ -/*---------------------------------------------------------------------- -// LP PROBLEM DATA -// -// It is assumed that LP problem has the following statement: -// -// minimize (or maximize) -// -// z = c[1]*x[1] + ... + c[m+n]*x[m+n] + c[0] (1) -// -// subject to equality constraints -// -// x[1] - a[1,1]*x[m+1] - ... - a[1,n]*x[m+n] = 0 -// -// . . . . . . . (2) -// -// x[m] - a[m,1]*x[m+1] + ... - a[m,n]*x[m+n] = 0 -// -// and bounds of variables -// -// l[1] <= x[1] <= u[1] -// -// . . . . . . . (3) -// -// l[m+n] <= x[m+n] <= u[m+n] -// -// where: -// x[1], ..., x[m] - auxiliary variables; -// x[m+1], ..., x[m+n] - structural variables; -// z - objective function; -// c[1], ..., c[m+n] - coefficients of the objective function; -// c[0] - constant term of the objective function; -// a[1,1], ..., a[m,n] - constraint coefficients; -// l[1], ..., l[m+n] - lower bounds of variables; -// u[1], ..., u[m+n] - upper bounds of variables. -// -// Bounds of variables can be finite as well as inifinite. Besides, -// lower and upper bounds can be equal to each other. So the following -// five types of variables are possible: -// -// Bounds of variable Type of variable -// ------------------------------------------------- -// -inf < x[k] < +inf Free (unbounded) variable -// l[k] <= x[k] < +inf Variable with lower bound -// -inf < x[k] <= u[k] Variable with upper bound -// l[k] <= x[k] <= u[k] Double-bounded variable -// l[k] = x[k] = u[k] Fixed variable -// -// Using vector-matrix notations the LP problem (1)-(3) can be written -// as follows: -// -// minimize (or maximize) -// -// z = c * x + c[0] (4) -// -// subject to equality constraints -// -// xR - A * xS = 0 (5) -// -// and bounds of variables -// -// l <= x <= u (6) -// -// where: -// xR - vector of auxiliary variables; -// xS - vector of structural variables; -// x = (xR, xS) - vector of all variables; -// z - objective function; -// c - vector of objective coefficients; -// c[0] - constant term of the objective function; -// A - matrix of constraint coefficients (has m rows -// and n columns); -// l - vector of lower bounds of variables; -// u - vector of upper bounds of variables. -// -// The simplex method makes no difference between auxiliary and -// structural variables, so it is convenient to think the system of -// equality constraints (5) written in a homogeneous form: -// -// (I | -A) * x = 0, (7) -// -// where (I | -A) is an augmented (m+n)xm constraint matrix, I is mxm -// unity matrix whose columns correspond to auxiliary variables, and A -// is the original mxn constraint matrix whose columns correspond to -// structural variables. Note that only the matrix A is stored. -----------------------------------------------------------------------*/ - int m; - /* number of rows (auxiliary variables), m > 0 */ - int n; - /* number of columns (structural variables), n > 0 */ - int *type; /* int type[1+m+n]; */ - /* type[0] is not used; - type[k], 1 <= k <= m+n, is the type of variable x[k]: */ -#define SSX_FR 0 /* free (unbounded) variable */ -#define SSX_LO 1 /* variable with lower bound */ -#define SSX_UP 2 /* variable with upper bound */ -#define SSX_DB 3 /* double-bounded variable */ -#define SSX_FX 4 /* fixed variable */ - mpq_t *lb; /* mpq_t lb[1+m+n]; alias: l */ - /* lb[0] is not used; - lb[k], 1 <= k <= m+n, is an lower bound of variable x[k]; - if x[k] has no lower bound, lb[k] is zero */ - mpq_t *ub; /* mpq_t ub[1+m+n]; alias: u */ - /* ub[0] is not used; - ub[k], 1 <= k <= m+n, is an upper bound of variable x[k]; - if x[k] has no upper bound, ub[k] is zero; - if x[k] is of fixed type, ub[k] is equal to lb[k] */ - int dir; - /* optimization direction (sense of the objective function): */ -#define SSX_MIN 0 /* minimization */ -#define SSX_MAX 1 /* maximization */ - mpq_t *coef; /* mpq_t coef[1+m+n]; alias: c */ - /* coef[0] is a constant term of the objective function; - coef[k], 1 <= k <= m+n, is a coefficient of the objective - function at variable x[k]; - note that auxiliary variables also may have non-zero objective - coefficients */ - int *A_ptr; /* int A_ptr[1+n+1]; */ - int *A_ind; /* int A_ind[A_ptr[n+1]]; */ - mpq_t *A_val; /* mpq_t A_val[A_ptr[n+1]]; */ - /* constraint matrix A (see (5)) in storage-by-columns format */ -/*---------------------------------------------------------------------- -// LP BASIS AND CURRENT BASIC SOLUTION -// -// The LP basis is defined by the following partition of the augmented -// constraint matrix (7): -// -// (B | N) = (I | -A) * Q, (8) -// -// where B is a mxm non-singular basis matrix whose columns correspond -// to basic variables xB, N is a mxn matrix whose columns correspond to -// non-basic variables xN, and Q is a permutation (m+n)x(m+n) matrix. -// -// From (7) and (8) it follows that -// -// (I | -A) * x = (I | -A) * Q * Q' * x = (B | N) * (xB, xN), -// -// therefore -// -// (xB, xN) = Q' * x, (9) -// -// where x is the vector of all variables in the original order, xB is -// a vector of basic variables, xN is a vector of non-basic variables, -// Q' = inv(Q) is a matrix transposed to Q. -// -// Current values of non-basic variables xN[j], j = 1, ..., n, are not -// stored; they are defined implicitly by their statuses as follows: -// -// 0, if xN[j] is free variable -// lN[j], if xN[j] is on its lower bound (10) -// uN[j], if xN[j] is on its upper bound -// lN[j] = uN[j], if xN[j] is fixed variable -// -// where lN[j] and uN[j] are lower and upper bounds of xN[j]. -// -// Current values of basic variables xB[i], i = 1, ..., m, are computed -// as follows: -// -// beta = - inv(B) * N * xN, (11) -// -// where current values of xN are defined by (10). -// -// Current values of simplex multipliers pi[i], i = 1, ..., m (which -// are values of Lagrange multipliers for equality constraints (7) also -// called shadow prices) are computed as follows: -// -// pi = inv(B') * cB, (12) -// -// where B' is a matrix transposed to B, cB is a vector of objective -// coefficients at basic variables xB. -// -// Current values of reduced costs d[j], j = 1, ..., n, (which are -// values of Langrange multipliers for active inequality constraints -// corresponding to non-basic variables) are computed as follows: -// -// d = cN - N' * pi, (13) -// -// where N' is a matrix transposed to N, cN is a vector of objective -// coefficients at non-basic variables xN. -----------------------------------------------------------------------*/ - int *stat; /* int stat[1+m+n]; */ - /* stat[0] is not used; - stat[k], 1 <= k <= m+n, is the status of variable x[k]: */ -#define SSX_BS 0 /* basic variable */ -#define SSX_NL 1 /* non-basic variable on lower bound */ -#define SSX_NU 2 /* non-basic variable on upper bound */ -#define SSX_NF 3 /* non-basic free variable */ -#define SSX_NS 4 /* non-basic fixed variable */ - int *Q_row; /* int Q_row[1+m+n]; */ - /* matrix Q in row-like format; - Q_row[0] is not used; - Q_row[i] = j means that q[i,j] = 1 */ - int *Q_col; /* int Q_col[1+m+n]; */ - /* matrix Q in column-like format; - Q_col[0] is not used; - Q_col[j] = i means that q[i,j] = 1 */ - /* if k-th column of the matrix (I | A) is k'-th column of the - matrix (B | N), then Q_row[k] = k' and Q_col[k'] = k; - if x[k] is xB[i], then Q_row[k] = i and Q_col[i] = k; - if x[k] is xN[j], then Q_row[k] = m+j and Q_col[m+j] = k */ - BFX *binv; - /* invertable form of the basis matrix B */ - mpq_t *bbar; /* mpq_t bbar[1+m]; alias: beta */ - /* bbar[0] is a value of the objective function; - bbar[i], 1 <= i <= m, is a value of basic variable xB[i] */ - mpq_t *pi; /* mpq_t pi[1+m]; */ - /* pi[0] is not used; - pi[i], 1 <= i <= m, is a simplex multiplier corresponding to - i-th row (equality constraint) */ - mpq_t *cbar; /* mpq_t cbar[1+n]; alias: d */ - /* cbar[0] is not used; - cbar[j], 1 <= j <= n, is a reduced cost of non-basic variable - xN[j] */ -/*---------------------------------------------------------------------- -// SIMPLEX TABLE -// -// Due to (8) and (9) the system of equality constraints (7) for the -// current basis can be written as follows: -// -// xB = A~ * xN, (14) -// -// where -// -// A~ = - inv(B) * N (15) -// -// is a mxn matrix called the simplex table. -// -// The revised simplex method uses only two components of A~, namely, -// pivot column corresponding to non-basic variable xN[q] chosen to -// enter the basis, and pivot row corresponding to basic variable xB[p] -// chosen to leave the basis. -// -// Pivot column alfa_q is q-th column of A~, so -// -// alfa_q = A~ * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q], (16) -// -// where N[q] is q-th column of the matrix N. -// -// Pivot row alfa_p is p-th row of A~ or, equivalently, p-th column of -// A~', a matrix transposed to A~, so -// -// alfa_p = A~' * e[p] = - N' * inv(B') * e[p] = - N' * rho_p, (17) -// -// where (*)' means transposition, and -// -// rho_p = inv(B') * e[p], (18) -// -// is p-th column of inv(B') or, that is the same, p-th row of inv(B). -----------------------------------------------------------------------*/ - int p; - /* number of basic variable xB[p], 1 <= p <= m, chosen to leave - the basis */ - mpq_t *rho; /* mpq_t rho[1+m]; */ - /* p-th row of the inverse inv(B); see (18) */ - mpq_t *ap; /* mpq_t ap[1+n]; */ - /* p-th row of the simplex table; see (17) */ - int q; - /* number of non-basic variable xN[q], 1 <= q <= n, chosen to - enter the basis */ - mpq_t *aq; /* mpq_t aq[1+m]; */ - /* q-th column of the simplex table; see (16) */ -/*--------------------------------------------------------------------*/ - int q_dir; - /* direction in which non-basic variable xN[q] should change on - moving to the adjacent vertex of the polyhedron: - +1 means that xN[q] increases - -1 means that xN[q] decreases */ - int p_stat; - /* non-basic status which should be assigned to basic variable - xB[p] when it has left the basis and become xN[q] */ - mpq_t delta; - /* actual change of xN[q] in the adjacent basis (it has the same - sign as q_dir) */ -/*--------------------------------------------------------------------*/ - int it_lim; - /* simplex iterations limit; if this value is positive, it is - decreased by one each time when one simplex iteration has been - performed, and reaching zero value signals the solver to stop - the search; negative value means no iterations limit */ - int it_cnt; - /* simplex iterations count; this count is increased by one each - time when one simplex iteration has been performed */ - double tm_lim; - /* searching time limit, in seconds; if this value is positive, - it is decreased each time when one simplex iteration has been - performed by the amount of time spent for the iteration, and - reaching zero value signals the solver to stop the search; - negative value means no time limit */ - double out_frq; - /* output frequency, in seconds; this parameter specifies how - frequently the solver sends information about the progress of - the search to the standard output */ -#if 0 /* 10/VI-2013 */ - glp_long tm_beg; -#else - double tm_beg; -#endif - /* starting time of the search, in seconds; the total time of the - search is the difference between xtime() and tm_beg */ -#if 0 /* 10/VI-2013 */ - glp_long tm_lag; -#else - double tm_lag; -#endif - /* the most recent time, in seconds, at which the progress of the - the search was displayed */ -}; - -#define ssx_create _glp_ssx_create -#define ssx_factorize _glp_ssx_factorize -#define ssx_get_xNj _glp_ssx_get_xNj -#define ssx_eval_bbar _glp_ssx_eval_bbar -#define ssx_eval_pi _glp_ssx_eval_pi -#define ssx_eval_dj _glp_ssx_eval_dj -#define ssx_eval_cbar _glp_ssx_eval_cbar -#define ssx_eval_rho _glp_ssx_eval_rho -#define ssx_eval_row _glp_ssx_eval_row -#define ssx_eval_col _glp_ssx_eval_col -#define ssx_chuzc _glp_ssx_chuzc -#define ssx_chuzr _glp_ssx_chuzr -#define ssx_update_bbar _glp_ssx_update_bbar -#define ssx_update_pi _glp_ssx_update_pi -#define ssx_update_cbar _glp_ssx_update_cbar -#define ssx_change_basis _glp_ssx_change_basis -#define ssx_delete _glp_ssx_delete - -#define ssx_phase_I _glp_ssx_phase_I -#define ssx_phase_II _glp_ssx_phase_II -#define ssx_driver _glp_ssx_driver - -SSX *ssx_create(int m, int n, int nnz); -/* create simplex solver workspace */ - -int ssx_factorize(SSX *ssx); -/* factorize the current basis matrix */ - -void ssx_get_xNj(SSX *ssx, int j, mpq_t x); -/* determine value of non-basic variable */ - -void ssx_eval_bbar(SSX *ssx); -/* compute values of basic variables */ - -void ssx_eval_pi(SSX *ssx); -/* compute values of simplex multipliers */ - -void ssx_eval_dj(SSX *ssx, int j, mpq_t dj); -/* compute reduced cost of non-basic variable */ - -void ssx_eval_cbar(SSX *ssx); -/* compute reduced costs of all non-basic variables */ - -void ssx_eval_rho(SSX *ssx); -/* compute p-th row of the inverse */ - -void ssx_eval_row(SSX *ssx); -/* compute pivot row of the simplex table */ - -void ssx_eval_col(SSX *ssx); -/* compute pivot column of the simplex table */ - -void ssx_chuzc(SSX *ssx); -/* choose pivot column */ - -void ssx_chuzr(SSX *ssx); -/* choose pivot row */ - -void ssx_update_bbar(SSX *ssx); -/* update values of basic variables */ - -void ssx_update_pi(SSX *ssx); -/* update simplex multipliers */ - -void ssx_update_cbar(SSX *ssx); -/* update reduced costs of non-basic variables */ - -void ssx_change_basis(SSX *ssx); -/* change current basis to adjacent one */ - -void ssx_delete(SSX *ssx); -/* delete simplex solver workspace */ - -int ssx_phase_I(SSX *ssx); -/* find primal feasible solution */ - -int ssx_phase_II(SSX *ssx); -/* find optimal solution */ - -int ssx_driver(SSX *ssx); -/* base driver to exact simplex method */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpssx01.c b/resources/3rdparty/glpk-4.53/src/glpssx01.c deleted file mode 100644 index 9b70444ec..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpssx01.c +++ /dev/null @@ -1,839 +0,0 @@ -/* glpssx01.c (simplex method, rational arithmetic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpssx.h" -#define xfault xerror - -/*---------------------------------------------------------------------- -// ssx_create - create simplex solver workspace. -// -// This routine creates the workspace used by simplex solver routines, -// and returns a pointer to it. -// -// Parameters m, n, and nnz specify, respectively, the number of rows, -// columns, and non-zero constraint coefficients. -// -// This routine only allocates the memory for the workspace components, -// so the workspace needs to be saturated by data. */ - -SSX *ssx_create(int m, int n, int nnz) -{ SSX *ssx; - int i, j, k; - if (m < 1) - xfault("ssx_create: m = %d; invalid number of rows\n", m); - if (n < 1) - xfault("ssx_create: n = %d; invalid number of columns\n", n); - if (nnz < 0) - xfault("ssx_create: nnz = %d; invalid number of non-zero const" - "raint coefficients\n", nnz); - ssx = xmalloc(sizeof(SSX)); - ssx->m = m; - ssx->n = n; - ssx->type = xcalloc(1+m+n, sizeof(int)); - ssx->lb = xcalloc(1+m+n, sizeof(mpq_t)); - for (k = 1; k <= m+n; k++) mpq_init(ssx->lb[k]); - ssx->ub = xcalloc(1+m+n, sizeof(mpq_t)); - for (k = 1; k <= m+n; k++) mpq_init(ssx->ub[k]); - ssx->coef = xcalloc(1+m+n, sizeof(mpq_t)); - for (k = 0; k <= m+n; k++) mpq_init(ssx->coef[k]); - ssx->A_ptr = xcalloc(1+n+1, sizeof(int)); - ssx->A_ptr[n+1] = nnz+1; - ssx->A_ind = xcalloc(1+nnz, sizeof(int)); - ssx->A_val = xcalloc(1+nnz, sizeof(mpq_t)); - for (k = 1; k <= nnz; k++) mpq_init(ssx->A_val[k]); - ssx->stat = xcalloc(1+m+n, sizeof(int)); - ssx->Q_row = xcalloc(1+m+n, sizeof(int)); - ssx->Q_col = xcalloc(1+m+n, sizeof(int)); - ssx->binv = bfx_create_binv(); - ssx->bbar = xcalloc(1+m, sizeof(mpq_t)); - for (i = 0; i <= m; i++) mpq_init(ssx->bbar[i]); - ssx->pi = xcalloc(1+m, sizeof(mpq_t)); - for (i = 1; i <= m; i++) mpq_init(ssx->pi[i]); - ssx->cbar = xcalloc(1+n, sizeof(mpq_t)); - for (j = 1; j <= n; j++) mpq_init(ssx->cbar[j]); - ssx->rho = xcalloc(1+m, sizeof(mpq_t)); - for (i = 1; i <= m; i++) mpq_init(ssx->rho[i]); - ssx->ap = xcalloc(1+n, sizeof(mpq_t)); - for (j = 1; j <= n; j++) mpq_init(ssx->ap[j]); - ssx->aq = xcalloc(1+m, sizeof(mpq_t)); - for (i = 1; i <= m; i++) mpq_init(ssx->aq[i]); - mpq_init(ssx->delta); - return ssx; -} - -/*---------------------------------------------------------------------- -// ssx_factorize - factorize the current basis matrix. -// -// This routine computes factorization of the current basis matrix B -// and returns the singularity flag. If the matrix B is non-singular, -// the flag is zero, otherwise non-zero. */ - -static int basis_col(void *info, int j, int ind[], mpq_t val[]) -{ /* this auxiliary routine provides row indices and numeric values - of non-zero elements in j-th column of the matrix B */ - SSX *ssx = info; - int m = ssx->m; - int n = ssx->n; - int *A_ptr = ssx->A_ptr; - int *A_ind = ssx->A_ind; - mpq_t *A_val = ssx->A_val; - int *Q_col = ssx->Q_col; - int k, len, ptr; - xassert(1 <= j && j <= m); - k = Q_col[j]; /* x[k] = xB[j] */ - xassert(1 <= k && k <= m+n); - /* j-th column of the matrix B is k-th column of the augmented - constraint matrix (I | -A) */ - if (k <= m) - { /* it is a column of the unity matrix I */ - len = 1, ind[1] = k, mpq_set_si(val[1], 1, 1); - } - else - { /* it is a column of the original constraint matrix -A */ - len = 0; - for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) - { len++; - ind[len] = A_ind[ptr]; - mpq_neg(val[len], A_val[ptr]); - } - } - return len; -} - -int ssx_factorize(SSX *ssx) -{ int ret; - ret = bfx_factorize(ssx->binv, ssx->m, basis_col, ssx); - return ret; -} - -/*---------------------------------------------------------------------- -// ssx_get_xNj - determine value of non-basic variable. -// -// This routine determines the value of non-basic variable xN[j] in the -// current basic solution defined as follows: -// -// 0, if xN[j] is free variable -// lN[j], if xN[j] is on its lower bound -// uN[j], if xN[j] is on its upper bound -// lN[j] = uN[j], if xN[j] is fixed variable -// -// where lN[j] and uN[j] are lower and upper bounds of xN[j]. */ - -void ssx_get_xNj(SSX *ssx, int j, mpq_t x) -{ int m = ssx->m; - int n = ssx->n; - mpq_t *lb = ssx->lb; - mpq_t *ub = ssx->ub; - int *stat = ssx->stat; - int *Q_col = ssx->Q_col; - int k; - xassert(1 <= j && j <= n); - k = Q_col[m+j]; /* x[k] = xN[j] */ - xassert(1 <= k && k <= m+n); - switch (stat[k]) - { case SSX_NL: - /* xN[j] is on its lower bound */ - mpq_set(x, lb[k]); break; - case SSX_NU: - /* xN[j] is on its upper bound */ - mpq_set(x, ub[k]); break; - case SSX_NF: - /* xN[j] is free variable */ - mpq_set_si(x, 0, 1); break; - case SSX_NS: - /* xN[j] is fixed variable */ - mpq_set(x, lb[k]); break; - default: - xassert(stat != stat); - } - return; -} - -/*---------------------------------------------------------------------- -// ssx_eval_bbar - compute values of basic variables. -// -// This routine computes values of basic variables xB in the current -// basic solution as follows: -// -// beta = - inv(B) * N * xN, -// -// where B is the basis matrix, N is the matrix of non-basic columns, -// xN is a vector of current values of non-basic variables. */ - -void ssx_eval_bbar(SSX *ssx) -{ int m = ssx->m; - int n = ssx->n; - mpq_t *coef = ssx->coef; - int *A_ptr = ssx->A_ptr; - int *A_ind = ssx->A_ind; - mpq_t *A_val = ssx->A_val; - int *Q_col = ssx->Q_col; - mpq_t *bbar = ssx->bbar; - int i, j, k, ptr; - mpq_t x, temp; - mpq_init(x); - mpq_init(temp); - /* bbar := 0 */ - for (i = 1; i <= m; i++) - mpq_set_si(bbar[i], 0, 1); - /* bbar := - N * xN = - N[1] * xN[1] - ... - N[n] * xN[n] */ - for (j = 1; j <= n; j++) - { ssx_get_xNj(ssx, j, x); - if (mpq_sgn(x) == 0) continue; - k = Q_col[m+j]; /* x[k] = xN[j] */ - if (k <= m) - { /* N[j] is a column of the unity matrix I */ - mpq_sub(bbar[k], bbar[k], x); - } - else - { /* N[j] is a column of the original constraint matrix -A */ - for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) - { mpq_mul(temp, A_val[ptr], x); - mpq_add(bbar[A_ind[ptr]], bbar[A_ind[ptr]], temp); - } - } - } - /* bbar := inv(B) * bbar */ - bfx_ftran(ssx->binv, bbar, 0); -#if 1 - /* compute value of the objective function */ - /* bbar[0] := c[0] */ - mpq_set(bbar[0], coef[0]); - /* bbar[0] := bbar[0] + sum{i in B} cB[i] * xB[i] */ - for (i = 1; i <= m; i++) - { k = Q_col[i]; /* x[k] = xB[i] */ - if (mpq_sgn(coef[k]) == 0) continue; - mpq_mul(temp, coef[k], bbar[i]); - mpq_add(bbar[0], bbar[0], temp); - } - /* bbar[0] := bbar[0] + sum{j in N} cN[j] * xN[j] */ - for (j = 1; j <= n; j++) - { k = Q_col[m+j]; /* x[k] = xN[j] */ - if (mpq_sgn(coef[k]) == 0) continue; - ssx_get_xNj(ssx, j, x); - mpq_mul(temp, coef[k], x); - mpq_add(bbar[0], bbar[0], temp); - } -#endif - mpq_clear(x); - mpq_clear(temp); - return; -} - -/*---------------------------------------------------------------------- -// ssx_eval_pi - compute values of simplex multipliers. -// -// This routine computes values of simplex multipliers (shadow prices) -// pi in the current basic solution as follows: -// -// pi = inv(B') * cB, -// -// where B' is a matrix transposed to the basis matrix B, cB is a vector -// of objective coefficients at basic variables xB. */ - -void ssx_eval_pi(SSX *ssx) -{ int m = ssx->m; - mpq_t *coef = ssx->coef; - int *Q_col = ssx->Q_col; - mpq_t *pi = ssx->pi; - int i; - /* pi := cB */ - for (i = 1; i <= m; i++) mpq_set(pi[i], coef[Q_col[i]]); - /* pi := inv(B') * cB */ - bfx_btran(ssx->binv, pi); - return; -} - -/*---------------------------------------------------------------------- -// ssx_eval_dj - compute reduced cost of non-basic variable. -// -// This routine computes reduced cost d[j] of non-basic variable xN[j] -// in the current basic solution as follows: -// -// d[j] = cN[j] - N[j] * pi, -// -// where cN[j] is an objective coefficient at xN[j], N[j] is a column -// of the augmented constraint matrix (I | -A) corresponding to xN[j], -// pi is the vector of simplex multipliers (shadow prices). */ - -void ssx_eval_dj(SSX *ssx, int j, mpq_t dj) -{ int m = ssx->m; - int n = ssx->n; - mpq_t *coef = ssx->coef; - int *A_ptr = ssx->A_ptr; - int *A_ind = ssx->A_ind; - mpq_t *A_val = ssx->A_val; - int *Q_col = ssx->Q_col; - mpq_t *pi = ssx->pi; - int k, ptr, end; - mpq_t temp; - mpq_init(temp); - xassert(1 <= j && j <= n); - k = Q_col[m+j]; /* x[k] = xN[j] */ - xassert(1 <= k && k <= m+n); - /* j-th column of the matrix N is k-th column of the augmented - constraint matrix (I | -A) */ - if (k <= m) - { /* it is a column of the unity matrix I */ - mpq_sub(dj, coef[k], pi[k]); - } - else - { /* it is a column of the original constraint matrix -A */ - mpq_set(dj, coef[k]); - for (ptr = A_ptr[k-m], end = A_ptr[k-m+1]; ptr < end; ptr++) - { mpq_mul(temp, A_val[ptr], pi[A_ind[ptr]]); - mpq_add(dj, dj, temp); - } - } - mpq_clear(temp); - return; -} - -/*---------------------------------------------------------------------- -// ssx_eval_cbar - compute reduced costs of all non-basic variables. -// -// This routine computes the vector of reduced costs pi in the current -// basic solution for all non-basic variables, including fixed ones. */ - -void ssx_eval_cbar(SSX *ssx) -{ int n = ssx->n; - mpq_t *cbar = ssx->cbar; - int j; - for (j = 1; j <= n; j++) - ssx_eval_dj(ssx, j, cbar[j]); - return; -} - -/*---------------------------------------------------------------------- -// ssx_eval_rho - compute p-th row of the inverse. -// -// This routine computes p-th row of the matrix inv(B), where B is the -// current basis matrix. -// -// p-th row of the inverse is computed using the following formula: -// -// rho = inv(B') * e[p], -// -// where B' is a matrix transposed to B, e[p] is a unity vector, which -// contains one in p-th position. */ - -void ssx_eval_rho(SSX *ssx) -{ int m = ssx->m; - int p = ssx->p; - mpq_t *rho = ssx->rho; - int i; - xassert(1 <= p && p <= m); - /* rho := 0 */ - for (i = 1; i <= m; i++) mpq_set_si(rho[i], 0, 1); - /* rho := e[p] */ - mpq_set_si(rho[p], 1, 1); - /* rho := inv(B') * rho */ - bfx_btran(ssx->binv, rho); - return; -} - -/*---------------------------------------------------------------------- -// ssx_eval_row - compute pivot row of the simplex table. -// -// This routine computes p-th (pivot) row of the current simplex table -// A~ = - inv(B) * N using the following formula: -// -// A~[p] = - N' * inv(B') * e[p] = - N' * rho[p], -// -// where N' is a matrix transposed to the matrix N, rho[p] is p-th row -// of the inverse inv(B). */ - -void ssx_eval_row(SSX *ssx) -{ int m = ssx->m; - int n = ssx->n; - int *A_ptr = ssx->A_ptr; - int *A_ind = ssx->A_ind; - mpq_t *A_val = ssx->A_val; - int *Q_col = ssx->Q_col; - mpq_t *rho = ssx->rho; - mpq_t *ap = ssx->ap; - int j, k, ptr; - mpq_t temp; - mpq_init(temp); - for (j = 1; j <= n; j++) - { /* ap[j] := - N'[j] * rho (inner product) */ - k = Q_col[m+j]; /* x[k] = xN[j] */ - if (k <= m) - mpq_neg(ap[j], rho[k]); - else - { mpq_set_si(ap[j], 0, 1); - for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) - { mpq_mul(temp, A_val[ptr], rho[A_ind[ptr]]); - mpq_add(ap[j], ap[j], temp); - } - } - } - mpq_clear(temp); - return; -} - -/*---------------------------------------------------------------------- -// ssx_eval_col - compute pivot column of the simplex table. -// -// This routine computes q-th (pivot) column of the current simplex -// table A~ = - inv(B) * N using the following formula: -// -// A~[q] = - inv(B) * N[q], -// -// where N[q] is q-th column of the matrix N corresponding to chosen -// non-basic variable xN[q]. */ - -void ssx_eval_col(SSX *ssx) -{ int m = ssx->m; - int n = ssx->n; - int *A_ptr = ssx->A_ptr; - int *A_ind = ssx->A_ind; - mpq_t *A_val = ssx->A_val; - int *Q_col = ssx->Q_col; - int q = ssx->q; - mpq_t *aq = ssx->aq; - int i, k, ptr; - xassert(1 <= q && q <= n); - /* aq := 0 */ - for (i = 1; i <= m; i++) mpq_set_si(aq[i], 0, 1); - /* aq := N[q] */ - k = Q_col[m+q]; /* x[k] = xN[q] */ - if (k <= m) - { /* N[q] is a column of the unity matrix I */ - mpq_set_si(aq[k], 1, 1); - } - else - { /* N[q] is a column of the original constraint matrix -A */ - for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) - mpq_neg(aq[A_ind[ptr]], A_val[ptr]); - } - /* aq := inv(B) * aq */ - bfx_ftran(ssx->binv, aq, 1); - /* aq := - aq */ - for (i = 1; i <= m; i++) mpq_neg(aq[i], aq[i]); - return; -} - -/*---------------------------------------------------------------------- -// ssx_chuzc - choose pivot column. -// -// This routine chooses non-basic variable xN[q] whose reduced cost -// indicates possible improving of the objective function to enter it -// in the basis. -// -// Currently the standard (textbook) pricing is used, i.e. that -// non-basic variable is preferred which has greatest reduced cost (in -// magnitude). -// -// If xN[q] has been chosen, the routine stores its number q and also -// sets the flag q_dir that indicates direction in which xN[q] has to -// change (+1 means increasing, -1 means decreasing). -// -// If the choice cannot be made, because the current basic solution is -// dual feasible, the routine sets the number q to 0. */ - -void ssx_chuzc(SSX *ssx) -{ int m = ssx->m; - int n = ssx->n; - int dir = (ssx->dir == SSX_MIN ? +1 : -1); - int *Q_col = ssx->Q_col; - int *stat = ssx->stat; - mpq_t *cbar = ssx->cbar; - int j, k, s, q, q_dir; - double best, temp; - /* nothing is chosen so far */ - q = 0, q_dir = 0, best = 0.0; - /* look through the list of non-basic variables */ - for (j = 1; j <= n; j++) - { k = Q_col[m+j]; /* x[k] = xN[j] */ - s = dir * mpq_sgn(cbar[j]); - if ((stat[k] == SSX_NF || stat[k] == SSX_NL) && s < 0 || - (stat[k] == SSX_NF || stat[k] == SSX_NU) && s > 0) - { /* reduced cost of xN[j] indicates possible improving of - the objective function */ - temp = fabs(mpq_get_d(cbar[j])); - xassert(temp != 0.0); - if (q == 0 || best < temp) - q = j, q_dir = - s, best = temp; - } - } - ssx->q = q, ssx->q_dir = q_dir; - return; -} - -/*---------------------------------------------------------------------- -// ssx_chuzr - choose pivot row. -// -// This routine looks through elements of q-th column of the simplex -// table and chooses basic variable xB[p] which should leave the basis. -// -// The choice is based on the standard (textbook) ratio test. -// -// If xB[p] has been chosen, the routine stores its number p and also -// sets its non-basic status p_stat which should be assigned to xB[p] -// when it has left the basis and become xN[q]. -// -// Special case p < 0 means that xN[q] is double-bounded variable and -// it reaches its opposite bound before any basic variable does that, -// so the current basis remains unchanged. -// -// If the choice cannot be made, because xN[q] can infinitely change in -// the feasible direction, the routine sets the number p to 0. */ - -void ssx_chuzr(SSX *ssx) -{ int m = ssx->m; - int n = ssx->n; - int *type = ssx->type; - mpq_t *lb = ssx->lb; - mpq_t *ub = ssx->ub; - int *Q_col = ssx->Q_col; - mpq_t *bbar = ssx->bbar; - int q = ssx->q; - mpq_t *aq = ssx->aq; - int q_dir = ssx->q_dir; - int i, k, s, t, p, p_stat; - mpq_t teta, temp; - mpq_init(teta); - mpq_init(temp); - xassert(1 <= q && q <= n); - xassert(q_dir == +1 || q_dir == -1); - /* nothing is chosen so far */ - p = 0, p_stat = 0; - /* look through the list of basic variables */ - for (i = 1; i <= m; i++) - { s = q_dir * mpq_sgn(aq[i]); - if (s < 0) - { /* xB[i] decreases */ - k = Q_col[i]; /* x[k] = xB[i] */ - t = type[k]; - if (t == SSX_LO || t == SSX_DB || t == SSX_FX) - { /* xB[i] has finite lower bound */ - mpq_sub(temp, bbar[i], lb[k]); - mpq_div(temp, temp, aq[i]); - mpq_abs(temp, temp); - if (p == 0 || mpq_cmp(teta, temp) > 0) - { p = i; - p_stat = (t == SSX_FX ? SSX_NS : SSX_NL); - mpq_set(teta, temp); - } - } - } - else if (s > 0) - { /* xB[i] increases */ - k = Q_col[i]; /* x[k] = xB[i] */ - t = type[k]; - if (t == SSX_UP || t == SSX_DB || t == SSX_FX) - { /* xB[i] has finite upper bound */ - mpq_sub(temp, bbar[i], ub[k]); - mpq_div(temp, temp, aq[i]); - mpq_abs(temp, temp); - if (p == 0 || mpq_cmp(teta, temp) > 0) - { p = i; - p_stat = (t == SSX_FX ? SSX_NS : SSX_NU); - mpq_set(teta, temp); - } - } - } - /* if something has been chosen and the ratio test indicates - exact degeneracy, the search can be finished */ - if (p != 0 && mpq_sgn(teta) == 0) break; - } - /* if xN[q] is double-bounded, check if it can reach its opposite - bound before any basic variable */ - k = Q_col[m+q]; /* x[k] = xN[q] */ - if (type[k] == SSX_DB) - { mpq_sub(temp, ub[k], lb[k]); - if (p == 0 || mpq_cmp(teta, temp) > 0) - { p = -1; - p_stat = -1; - mpq_set(teta, temp); - } - } - ssx->p = p; - ssx->p_stat = p_stat; - /* if xB[p] has been chosen, determine its actual change in the - adjacent basis (it has the same sign as q_dir) */ - if (p != 0) - { xassert(mpq_sgn(teta) >= 0); - if (q_dir > 0) - mpq_set(ssx->delta, teta); - else - mpq_neg(ssx->delta, teta); - } - mpq_clear(teta); - mpq_clear(temp); - return; -} - -/*---------------------------------------------------------------------- -// ssx_update_bbar - update values of basic variables. -// -// This routine recomputes the current values of basic variables for -// the adjacent basis. -// -// The simplex table for the current basis is the following: -// -// xB[i] = sum{j in 1..n} alfa[i,j] * xN[q], i = 1,...,m -// -// therefore -// -// delta xB[i] = alfa[i,q] * delta xN[q], i = 1,...,m -// -// where delta xN[q] = xN.new[q] - xN[q] is the change of xN[q] in the -// adjacent basis, and delta xB[i] = xB.new[i] - xB[i] is the change of -// xB[i]. This gives formulae for recomputing values of xB[i]: -// -// xB.new[p] = xN[q] + delta xN[q] -// -// (because xN[q] becomes xB[p] in the adjacent basis), and -// -// xB.new[i] = xB[i] + alfa[i,q] * delta xN[q], i != p -// -// for other basic variables. */ - -void ssx_update_bbar(SSX *ssx) -{ int m = ssx->m; - int n = ssx->n; - mpq_t *bbar = ssx->bbar; - mpq_t *cbar = ssx->cbar; - int p = ssx->p; - int q = ssx->q; - mpq_t *aq = ssx->aq; - int i; - mpq_t temp; - mpq_init(temp); - xassert(1 <= q && q <= n); - if (p < 0) - { /* xN[q] is double-bounded and goes to its opposite bound */ - /* nop */; - } - else - { /* xN[q] becomes xB[p] in the adjacent basis */ - /* xB.new[p] = xN[q] + delta xN[q] */ - xassert(1 <= p && p <= m); - ssx_get_xNj(ssx, q, temp); - mpq_add(bbar[p], temp, ssx->delta); - } - /* update values of other basic variables depending on xN[q] */ - for (i = 1; i <= m; i++) - { if (i == p) continue; - /* xB.new[i] = xB[i] + alfa[i,q] * delta xN[q] */ - if (mpq_sgn(aq[i]) == 0) continue; - mpq_mul(temp, aq[i], ssx->delta); - mpq_add(bbar[i], bbar[i], temp); - } -#if 1 - /* update value of the objective function */ - /* z.new = z + d[q] * delta xN[q] */ - mpq_mul(temp, cbar[q], ssx->delta); - mpq_add(bbar[0], bbar[0], temp); -#endif - mpq_clear(temp); - return; -} - -/*---------------------------------------------------------------------- --- ssx_update_pi - update simplex multipliers. --- --- This routine recomputes the vector of simplex multipliers for the --- adjacent basis. */ - -void ssx_update_pi(SSX *ssx) -{ int m = ssx->m; - int n = ssx->n; - mpq_t *pi = ssx->pi; - mpq_t *cbar = ssx->cbar; - int p = ssx->p; - int q = ssx->q; - mpq_t *aq = ssx->aq; - mpq_t *rho = ssx->rho; - int i; - mpq_t new_dq, temp; - mpq_init(new_dq); - mpq_init(temp); - xassert(1 <= p && p <= m); - xassert(1 <= q && q <= n); - /* compute d[q] in the adjacent basis */ - mpq_div(new_dq, cbar[q], aq[p]); - /* update the vector of simplex multipliers */ - for (i = 1; i <= m; i++) - { if (mpq_sgn(rho[i]) == 0) continue; - mpq_mul(temp, new_dq, rho[i]); - mpq_sub(pi[i], pi[i], temp); - } - mpq_clear(new_dq); - mpq_clear(temp); - return; -} - -/*---------------------------------------------------------------------- -// ssx_update_cbar - update reduced costs of non-basic variables. -// -// This routine recomputes the vector of reduced costs of non-basic -// variables for the adjacent basis. */ - -void ssx_update_cbar(SSX *ssx) -{ int m = ssx->m; - int n = ssx->n; - mpq_t *cbar = ssx->cbar; - int p = ssx->p; - int q = ssx->q; - mpq_t *ap = ssx->ap; - int j; - mpq_t temp; - mpq_init(temp); - xassert(1 <= p && p <= m); - xassert(1 <= q && q <= n); - /* compute d[q] in the adjacent basis */ - /* d.new[q] = d[q] / alfa[p,q] */ - mpq_div(cbar[q], cbar[q], ap[q]); - /* update reduced costs of other non-basic variables */ - for (j = 1; j <= n; j++) - { if (j == q) continue; - /* d.new[j] = d[j] - (alfa[p,j] / alfa[p,q]) * d[q] */ - if (mpq_sgn(ap[j]) == 0) continue; - mpq_mul(temp, ap[j], cbar[q]); - mpq_sub(cbar[j], cbar[j], temp); - } - mpq_clear(temp); - return; -} - -/*---------------------------------------------------------------------- -// ssx_change_basis - change current basis to adjacent one. -// -// This routine changes the current basis to the adjacent one swapping -// basic variable xB[p] and non-basic variable xN[q]. */ - -void ssx_change_basis(SSX *ssx) -{ int m = ssx->m; - int n = ssx->n; - int *type = ssx->type; - int *stat = ssx->stat; - int *Q_row = ssx->Q_row; - int *Q_col = ssx->Q_col; - int p = ssx->p; - int q = ssx->q; - int p_stat = ssx->p_stat; - int k, kp, kq; - if (p < 0) - { /* special case: xN[q] goes to its opposite bound */ - xassert(1 <= q && q <= n); - k = Q_col[m+q]; /* x[k] = xN[q] */ - xassert(type[k] == SSX_DB); - switch (stat[k]) - { case SSX_NL: - stat[k] = SSX_NU; - break; - case SSX_NU: - stat[k] = SSX_NL; - break; - default: - xassert(stat != stat); - } - } - else - { /* xB[p] leaves the basis, xN[q] enters the basis */ - xassert(1 <= p && p <= m); - xassert(1 <= q && q <= n); - kp = Q_col[p]; /* x[kp] = xB[p] */ - kq = Q_col[m+q]; /* x[kq] = xN[q] */ - /* check non-basic status of xB[p] which becomes xN[q] */ - switch (type[kp]) - { case SSX_FR: - xassert(p_stat == SSX_NF); - break; - case SSX_LO: - xassert(p_stat == SSX_NL); - break; - case SSX_UP: - xassert(p_stat == SSX_NU); - break; - case SSX_DB: - xassert(p_stat == SSX_NL || p_stat == SSX_NU); - break; - case SSX_FX: - xassert(p_stat == SSX_NS); - break; - default: - xassert(type != type); - } - /* swap xB[p] and xN[q] */ - stat[kp] = (char)p_stat, stat[kq] = SSX_BS; - Q_row[kp] = m+q, Q_row[kq] = p; - Q_col[p] = kq, Q_col[m+q] = kp; - /* update factorization of the basis matrix */ - if (bfx_update(ssx->binv, p)) - { if (ssx_factorize(ssx)) - xassert(("Internal error: basis matrix is singular", 0)); - } - } - return; -} - -/*---------------------------------------------------------------------- -// ssx_delete - delete simplex solver workspace. -// -// This routine deletes the simplex solver workspace freeing all the -// memory allocated to this object. */ - -void ssx_delete(SSX *ssx) -{ int m = ssx->m; - int n = ssx->n; - int nnz = ssx->A_ptr[n+1]-1; - int i, j, k; - xfree(ssx->type); - for (k = 1; k <= m+n; k++) mpq_clear(ssx->lb[k]); - xfree(ssx->lb); - for (k = 1; k <= m+n; k++) mpq_clear(ssx->ub[k]); - xfree(ssx->ub); - for (k = 0; k <= m+n; k++) mpq_clear(ssx->coef[k]); - xfree(ssx->coef); - xfree(ssx->A_ptr); - xfree(ssx->A_ind); - for (k = 1; k <= nnz; k++) mpq_clear(ssx->A_val[k]); - xfree(ssx->A_val); - xfree(ssx->stat); - xfree(ssx->Q_row); - xfree(ssx->Q_col); - bfx_delete_binv(ssx->binv); - for (i = 0; i <= m; i++) mpq_clear(ssx->bbar[i]); - xfree(ssx->bbar); - for (i = 1; i <= m; i++) mpq_clear(ssx->pi[i]); - xfree(ssx->pi); - for (j = 1; j <= n; j++) mpq_clear(ssx->cbar[j]); - xfree(ssx->cbar); - for (i = 1; i <= m; i++) mpq_clear(ssx->rho[i]); - xfree(ssx->rho); - for (j = 1; j <= n; j++) mpq_clear(ssx->ap[j]); - xfree(ssx->ap); - for (i = 1; i <= m; i++) mpq_clear(ssx->aq[i]); - xfree(ssx->aq); - mpq_clear(ssx->delta); - xfree(ssx); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glpssx02.c b/resources/3rdparty/glpk-4.53/src/glpssx02.c deleted file mode 100644 index 4b3ea97d6..000000000 --- a/resources/3rdparty/glpk-4.53/src/glpssx02.c +++ /dev/null @@ -1,479 +0,0 @@ -/* glpssx02.c (simplex method, rational arithmetic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glpssx.h" - -static void show_progress(SSX *ssx, int phase) -{ /* this auxiliary routine displays information about progress of - the search */ - int i, def = 0; - for (i = 1; i <= ssx->m; i++) - if (ssx->type[ssx->Q_col[i]] == SSX_FX) def++; - xprintf("%s%6d: %s = %22.15g (%d)\n", phase == 1 ? " " : "*", - ssx->it_cnt, phase == 1 ? "infsum" : "objval", - mpq_get_d(ssx->bbar[0]), def); -#if 0 - ssx->tm_lag = utime(); -#else - ssx->tm_lag = xtime(); -#endif - return; -} - -/*---------------------------------------------------------------------- -// ssx_phase_I - find primal feasible solution. -// -// This routine implements phase I of the primal simplex method. -// -// On exit the routine returns one of the following codes: -// -// 0 - feasible solution found; -// 1 - problem has no feasible solution; -// 2 - iterations limit exceeded; -// 3 - time limit exceeded. -----------------------------------------------------------------------*/ - -int ssx_phase_I(SSX *ssx) -{ int m = ssx->m; - int n = ssx->n; - int *type = ssx->type; - mpq_t *lb = ssx->lb; - mpq_t *ub = ssx->ub; - mpq_t *coef = ssx->coef; - int *A_ptr = ssx->A_ptr; - int *A_ind = ssx->A_ind; - mpq_t *A_val = ssx->A_val; - int *Q_col = ssx->Q_col; - mpq_t *bbar = ssx->bbar; - mpq_t *pi = ssx->pi; - mpq_t *cbar = ssx->cbar; - int *orig_type, orig_dir; - mpq_t *orig_lb, *orig_ub, *orig_coef; - int i, k, ret; - /* save components of the original LP problem, which are changed - by the routine */ - orig_type = xcalloc(1+m+n, sizeof(int)); - orig_lb = xcalloc(1+m+n, sizeof(mpq_t)); - orig_ub = xcalloc(1+m+n, sizeof(mpq_t)); - orig_coef = xcalloc(1+m+n, sizeof(mpq_t)); - for (k = 1; k <= m+n; k++) - { orig_type[k] = type[k]; - mpq_init(orig_lb[k]); - mpq_set(orig_lb[k], lb[k]); - mpq_init(orig_ub[k]); - mpq_set(orig_ub[k], ub[k]); - } - orig_dir = ssx->dir; - for (k = 0; k <= m+n; k++) - { mpq_init(orig_coef[k]); - mpq_set(orig_coef[k], coef[k]); - } - /* build an artificial basic solution, which is primal feasible, - and also build an auxiliary objective function to minimize the - sum of infeasibilities for the original problem */ - ssx->dir = SSX_MIN; - for (k = 0; k <= m+n; k++) mpq_set_si(coef[k], 0, 1); - mpq_set_si(bbar[0], 0, 1); - for (i = 1; i <= m; i++) - { int t; - k = Q_col[i]; /* x[k] = xB[i] */ - t = type[k]; - if (t == SSX_LO || t == SSX_DB || t == SSX_FX) - { /* in the original problem x[k] has lower bound */ - if (mpq_cmp(bbar[i], lb[k]) < 0) - { /* which is violated */ - type[k] = SSX_UP; - mpq_set(ub[k], lb[k]); - mpq_set_si(lb[k], 0, 1); - mpq_set_si(coef[k], -1, 1); - mpq_add(bbar[0], bbar[0], ub[k]); - mpq_sub(bbar[0], bbar[0], bbar[i]); - } - } - if (t == SSX_UP || t == SSX_DB || t == SSX_FX) - { /* in the original problem x[k] has upper bound */ - if (mpq_cmp(bbar[i], ub[k]) > 0) - { /* which is violated */ - type[k] = SSX_LO; - mpq_set(lb[k], ub[k]); - mpq_set_si(ub[k], 0, 1); - mpq_set_si(coef[k], +1, 1); - mpq_add(bbar[0], bbar[0], bbar[i]); - mpq_sub(bbar[0], bbar[0], lb[k]); - } - } - } - /* now the initial basic solution should be primal feasible due - to changes of bounds of some basic variables, which turned to - implicit artifical variables */ - /* compute simplex multipliers and reduced costs */ - ssx_eval_pi(ssx); - ssx_eval_cbar(ssx); - /* display initial progress of the search */ - show_progress(ssx, 1); - /* main loop starts here */ - for (;;) - { /* display current progress of the search */ -#if 0 - if (utime() - ssx->tm_lag >= ssx->out_frq - 0.001) -#else - if (xdifftime(xtime(), ssx->tm_lag) >= ssx->out_frq - 0.001) -#endif - show_progress(ssx, 1); - /* we do not need to wait until all artificial variables have - left the basis */ - if (mpq_sgn(bbar[0]) == 0) - { /* the sum of infeasibilities is zero, therefore the current - solution is primal feasible for the original problem */ - ret = 0; - break; - } - /* check if the iterations limit has been exhausted */ - if (ssx->it_lim == 0) - { ret = 2; - break; - } - /* check if the time limit has been exhausted */ -#if 0 - if (ssx->tm_lim >= 0.0 && ssx->tm_lim <= utime() - ssx->tm_beg) -#else - if (ssx->tm_lim >= 0.0 && - ssx->tm_lim <= xdifftime(xtime(), ssx->tm_beg)) -#endif - { ret = 3; - break; - } - /* choose non-basic variable xN[q] */ - ssx_chuzc(ssx); - /* if xN[q] cannot be chosen, the sum of infeasibilities is - minimal but non-zero; therefore the original problem has no - primal feasible solution */ - if (ssx->q == 0) - { ret = 1; - break; - } - /* compute q-th column of the simplex table */ - ssx_eval_col(ssx); - /* choose basic variable xB[p] */ - ssx_chuzr(ssx); - /* the sum of infeasibilities cannot be negative, therefore - the auxiliary lp problem cannot have unbounded solution */ - xassert(ssx->p != 0); - /* update values of basic variables */ - ssx_update_bbar(ssx); - if (ssx->p > 0) - { /* compute p-th row of the inverse inv(B) */ - ssx_eval_rho(ssx); - /* compute p-th row of the simplex table */ - ssx_eval_row(ssx); - xassert(mpq_cmp(ssx->aq[ssx->p], ssx->ap[ssx->q]) == 0); - /* update simplex multipliers */ - ssx_update_pi(ssx); - /* update reduced costs of non-basic variables */ - ssx_update_cbar(ssx); - } - /* xB[p] is leaving the basis; if it is implicit artificial - variable, the corresponding residual vanishes; therefore - bounds of this variable should be restored to the original - values */ - if (ssx->p > 0) - { k = Q_col[ssx->p]; /* x[k] = xB[p] */ - if (type[k] != orig_type[k]) - { /* x[k] is implicit artificial variable */ - type[k] = orig_type[k]; - mpq_set(lb[k], orig_lb[k]); - mpq_set(ub[k], orig_ub[k]); - xassert(ssx->p_stat == SSX_NL || ssx->p_stat == SSX_NU); - ssx->p_stat = (ssx->p_stat == SSX_NL ? SSX_NU : SSX_NL); - if (type[k] == SSX_FX) ssx->p_stat = SSX_NS; - /* nullify the objective coefficient at x[k] */ - mpq_set_si(coef[k], 0, 1); - /* since coef[k] has been changed, we need to compute - new reduced cost of x[k], which it will have in the - adjacent basis */ - /* the formula d[j] = cN[j] - pi' * N[j] is used (note - that the vector pi is not changed, because it depends - on objective coefficients at basic variables, but in - the adjacent basis, for which the vector pi has been - just recomputed, x[k] is non-basic) */ - if (k <= m) - { /* x[k] is auxiliary variable */ - mpq_neg(cbar[ssx->q], pi[k]); - } - else - { /* x[k] is structural variable */ - int ptr; - mpq_t temp; - mpq_init(temp); - mpq_set_si(cbar[ssx->q], 0, 1); - for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) - { mpq_mul(temp, pi[A_ind[ptr]], A_val[ptr]); - mpq_add(cbar[ssx->q], cbar[ssx->q], temp); - } - mpq_clear(temp); - } - } - } - /* jump to the adjacent vertex of the polyhedron */ - ssx_change_basis(ssx); - /* one simplex iteration has been performed */ - if (ssx->it_lim > 0) ssx->it_lim--; - ssx->it_cnt++; - } - /* display final progress of the search */ - show_progress(ssx, 1); - /* restore components of the original problem, which were changed - by the routine */ - for (k = 1; k <= m+n; k++) - { type[k] = orig_type[k]; - mpq_set(lb[k], orig_lb[k]); - mpq_clear(orig_lb[k]); - mpq_set(ub[k], orig_ub[k]); - mpq_clear(orig_ub[k]); - } - ssx->dir = orig_dir; - for (k = 0; k <= m+n; k++) - { mpq_set(coef[k], orig_coef[k]); - mpq_clear(orig_coef[k]); - } - xfree(orig_type); - xfree(orig_lb); - xfree(orig_ub); - xfree(orig_coef); - /* return to the calling program */ - return ret; -} - -/*---------------------------------------------------------------------- -// ssx_phase_II - find optimal solution. -// -// This routine implements phase II of the primal simplex method. -// -// On exit the routine returns one of the following codes: -// -// 0 - optimal solution found; -// 1 - problem has unbounded solution; -// 2 - iterations limit exceeded; -// 3 - time limit exceeded. -----------------------------------------------------------------------*/ - -int ssx_phase_II(SSX *ssx) -{ int ret; - /* display initial progress of the search */ - show_progress(ssx, 2); - /* main loop starts here */ - for (;;) - { /* display current progress of the search */ -#if 0 - if (utime() - ssx->tm_lag >= ssx->out_frq - 0.001) -#else - if (xdifftime(xtime(), ssx->tm_lag) >= ssx->out_frq - 0.001) -#endif - show_progress(ssx, 2); - /* check if the iterations limit has been exhausted */ - if (ssx->it_lim == 0) - { ret = 2; - break; - } - /* check if the time limit has been exhausted */ -#if 0 - if (ssx->tm_lim >= 0.0 && ssx->tm_lim <= utime() - ssx->tm_beg) -#else - if (ssx->tm_lim >= 0.0 && - ssx->tm_lim <= xdifftime(xtime(), ssx->tm_beg)) -#endif - { ret = 3; - break; - } - /* choose non-basic variable xN[q] */ - ssx_chuzc(ssx); - /* if xN[q] cannot be chosen, the current basic solution is - dual feasible and therefore optimal */ - if (ssx->q == 0) - { ret = 0; - break; - } - /* compute q-th column of the simplex table */ - ssx_eval_col(ssx); - /* choose basic variable xB[p] */ - ssx_chuzr(ssx); - /* if xB[p] cannot be chosen, the problem has no dual feasible - solution (i.e. unbounded) */ - if (ssx->p == 0) - { ret = 1; - break; - } - /* update values of basic variables */ - ssx_update_bbar(ssx); - if (ssx->p > 0) - { /* compute p-th row of the inverse inv(B) */ - ssx_eval_rho(ssx); - /* compute p-th row of the simplex table */ - ssx_eval_row(ssx); - xassert(mpq_cmp(ssx->aq[ssx->p], ssx->ap[ssx->q]) == 0); -#if 0 - /* update simplex multipliers */ - ssx_update_pi(ssx); -#endif - /* update reduced costs of non-basic variables */ - ssx_update_cbar(ssx); - } - /* jump to the adjacent vertex of the polyhedron */ - ssx_change_basis(ssx); - /* one simplex iteration has been performed */ - if (ssx->it_lim > 0) ssx->it_lim--; - ssx->it_cnt++; - } - /* display final progress of the search */ - show_progress(ssx, 2); - /* return to the calling program */ - return ret; -} - -/*---------------------------------------------------------------------- -// ssx_driver - base driver to exact simplex method. -// -// This routine is a base driver to a version of the primal simplex -// method using exact (bignum) arithmetic. -// -// On exit the routine returns one of the following codes: -// -// 0 - optimal solution found; -// 1 - problem has no feasible solution; -// 2 - problem has unbounded solution; -// 3 - iterations limit exceeded (phase I); -// 4 - iterations limit exceeded (phase II); -// 5 - time limit exceeded (phase I); -// 6 - time limit exceeded (phase II); -// 7 - initial basis matrix is exactly singular. -----------------------------------------------------------------------*/ - -int ssx_driver(SSX *ssx) -{ int m = ssx->m; - int *type = ssx->type; - mpq_t *lb = ssx->lb; - mpq_t *ub = ssx->ub; - int *Q_col = ssx->Q_col; - mpq_t *bbar = ssx->bbar; - int i, k, ret; - ssx->tm_beg = xtime(); - /* factorize the initial basis matrix */ - if (ssx_factorize(ssx)) - { xprintf("Initial basis matrix is singular\n"); - ret = 7; - goto done; - } - /* compute values of basic variables */ - ssx_eval_bbar(ssx); - /* check if the initial basic solution is primal feasible */ - for (i = 1; i <= m; i++) - { int t; - k = Q_col[i]; /* x[k] = xB[i] */ - t = type[k]; - if (t == SSX_LO || t == SSX_DB || t == SSX_FX) - { /* x[k] has lower bound */ - if (mpq_cmp(bbar[i], lb[k]) < 0) - { /* which is violated */ - break; - } - } - if (t == SSX_UP || t == SSX_DB || t == SSX_FX) - { /* x[k] has upper bound */ - if (mpq_cmp(bbar[i], ub[k]) > 0) - { /* which is violated */ - break; - } - } - } - if (i > m) - { /* no basic variable violates its bounds */ - ret = 0; - goto skip; - } - /* phase I: find primal feasible solution */ - ret = ssx_phase_I(ssx); - switch (ret) - { case 0: - ret = 0; - break; - case 1: - xprintf("PROBLEM HAS NO FEASIBLE SOLUTION\n"); - ret = 1; - break; - case 2: - xprintf("ITERATIONS LIMIT EXCEEDED; SEARCH TERMINATED\n"); - ret = 3; - break; - case 3: - xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); - ret = 5; - break; - default: - xassert(ret != ret); - } - /* compute values of basic variables (actually only the objective - value needs to be computed) */ - ssx_eval_bbar(ssx); -skip: /* compute simplex multipliers */ - ssx_eval_pi(ssx); - /* compute reduced costs of non-basic variables */ - ssx_eval_cbar(ssx); - /* if phase I failed, do not start phase II */ - if (ret != 0) goto done; - /* phase II: find optimal solution */ - ret = ssx_phase_II(ssx); - switch (ret) - { case 0: - xprintf("OPTIMAL SOLUTION FOUND\n"); - ret = 0; - break; - case 1: - xprintf("PROBLEM HAS UNBOUNDED SOLUTION\n"); - ret = 2; - break; - case 2: - xprintf("ITERATIONS LIMIT EXCEEDED; SEARCH TERMINATED\n"); - ret = 4; - break; - case 3: - xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); - ret = 6; - break; - default: - xassert(ret != ret); - } -done: /* decrease the time limit by the spent amount of time */ - if (ssx->tm_lim >= 0.0) -#if 0 - { ssx->tm_lim -= utime() - ssx->tm_beg; -#else - { ssx->tm_lim -= xdifftime(xtime(), ssx->tm_beg); -#endif - if (ssx->tm_lim < 0.0) ssx->tm_lim = 0.0; - } - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glptsp.c b/resources/3rdparty/glpk-4.53/src/glptsp.c deleted file mode 100644 index ceb569584..000000000 --- a/resources/3rdparty/glpk-4.53/src/glptsp.c +++ /dev/null @@ -1,667 +0,0 @@ -/* glptsp.c */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "glptsp.h" -#include "misc.h" - -#define xfault xerror - -/*---------------------------------------------------------------------- --- tsp_read_data - read TSP instance data. --- --- *Synopsis* --- --- #include "glptsp.h" --- TSP *tsp_read_data(char *fname); --- --- *Description* --- --- The routine tsp_read_data reads a TSP (or related problem) instance --- data from the text file, whose name is the character string fname. --- --- For detailed description of the format recognized by the routine see --- the report: G.Reinelt, TSPLIB 95. --- --- *Returns* --- --- If no error occurred, the routine tsp_read_data returns a pointer to --- the TSP instance data block, which contains loaded data. In the case --- of error the routine prints an error message and returns NULL. */ - -struct dsa -{ /* dynamic storage area used by the routine tsp_read_data */ - char *fname; - /* name of the input text file */ - FILE *fp; - /* stream assigned to the input text file */ - int seqn; - /* line sequential number */ - int c; - /* current character */ - char token[255+1]; - /* current token */ -}; - -static int get_char(struct dsa *dsa) -{ dsa->c = fgetc(dsa->fp); - if (ferror(dsa->fp)) - { xprintf("%s:%d: read error - %s\n", - dsa->fname, dsa->seqn, strerror(errno)); - return 1; - } - if (feof(dsa->fp)) - dsa->c = EOF; - else if (dsa->c == '\n') - dsa->seqn++; - else if (isspace(dsa->c)) - dsa->c = ' '; - else if (iscntrl(dsa->c)) - { xprintf("%s:%d: invalid control character 0x%02X\n", - dsa->fname, dsa->seqn, dsa->c); - return 1; - } - return 0; -} - -static int skip_spaces(struct dsa *dsa, int across) -{ while (dsa->c == ' ' || (across && dsa->c == '\n')) - if (get_char(dsa)) return 1; - return 0; -} - -static int scan_keyword(struct dsa *dsa) -{ int len = 0; - if (skip_spaces(dsa, 0)) return 1; - dsa->token[0] = '\0'; - while (isalnum(dsa->c) || dsa->c == '_') - { if (len == 31) - { xprintf("%s:%d: keyword `%s...' too long\n", dsa->fname, - dsa->seqn, dsa->token); - return 1; - } - dsa->token[len++] = (char)dsa->c, dsa->token[len] = '\0'; - if (get_char(dsa)) return 1; - } - if (len == 0) - { xprintf("%s:%d: missing keyword\n", dsa->fname, dsa->seqn); - return 1; - } - return 0; -} - -static int check_colon(struct dsa *dsa) -{ if (skip_spaces(dsa, 0)) return 1; - if (dsa->c != ':') - { xprintf("%s:%d: missing colon after `%s'\n", dsa->fname, - dsa->seqn, dsa->token); - return 1; - } - if (get_char(dsa)) return 1; - return 0; -} - -static int scan_token(struct dsa *dsa, int across) -{ int len = 0; - if (skip_spaces(dsa, across)) return 1; - dsa->token[0] = '\0'; - while (!(dsa->c == EOF || dsa->c == '\n' || dsa->c == ' ')) - { if (len == 255) - { dsa->token[31] = '\0'; - xprintf("%s:%d: token `%s...' too long\n", dsa->fname, - dsa->seqn, dsa->token); - return 1; - } - dsa->token[len++] = (char)dsa->c, dsa->token[len] = '\0'; - if (get_char(dsa)) return 1; - } - return 0; -} - -static int check_newline(struct dsa *dsa) -{ if (skip_spaces(dsa, 0)) return 1; - if (!(dsa->c == EOF || dsa->c == '\n')) - { xprintf("%s:%d: extra symbols detected\n", dsa->fname, - dsa->seqn); - return 1; - } - if (get_char(dsa)) return 1; - return 0; -} - -static int scan_comment(struct dsa *dsa) -{ int len = 0; - if (skip_spaces(dsa, 0)) return 1; - dsa->token[0] = '\0'; - while (!(dsa->c == EOF || dsa->c == '\n')) - { if (len == 255) - { xprintf("%s:%d: comment too long\n", dsa->fname, dsa->seqn) - ; - return 1; - } - dsa->token[len++] = (char)dsa->c, dsa->token[len] = '\0'; - if (get_char(dsa)) return 1; - } - return 0; -} - -static int scan_integer(struct dsa *dsa, int across, int *val) -{ if (scan_token(dsa, across)) return 1; - if (strlen(dsa->token) == 0) - { xprintf("%s:%d: missing integer\n", dsa->fname, dsa->seqn); - return 1; - } - if (str2int(dsa->token, val)) - { xprintf("%s:%d: integer `%s' invalid\n", dsa->fname, dsa->seqn - , dsa->token); - return 1; - } - return 0; -} - -static int scan_number(struct dsa *dsa, int across, double *val) -{ if (scan_token(dsa, across)) return 1; - if (strlen(dsa->token) == 0) - { xprintf("%s:%d: missing number\n", dsa->fname, dsa->seqn); - return 1; - } - if (str2num(dsa->token, val)) - { xprintf("%s:%d: number `%s' invalid\n", dsa->fname, dsa->seqn, - dsa->token); - return 1; - } - return 0; -} - -TSP *tsp_read_data(char *fname) -{ struct dsa _dsa, *dsa = &_dsa; - TSP *tsp = NULL; - dsa->fname = fname; - xprintf("tsp_read_data: reading TSP data from `%s'...\n", - dsa->fname); - dsa->fp = fopen(dsa->fname, "r"); - if (dsa->fp == NULL) - { xprintf("tsp_read_data: unable to open `%s' - %s\n", - dsa->fname, strerror(errno)); - goto fail; - } - tsp = xmalloc(sizeof(TSP)); - tsp->name = NULL; - tsp->type = TSP_UNDEF; - tsp->comment = NULL; - tsp->dimension = 0; - tsp->edge_weight_type = TSP_UNDEF; - tsp->edge_weight_format = TSP_UNDEF; - tsp->display_data_type = TSP_UNDEF; - tsp->node_x_coord = NULL; - tsp->node_y_coord = NULL; - tsp->dply_x_coord = NULL; - tsp->dply_y_coord = NULL; - tsp->tour = NULL; - tsp->edge_weight = NULL; - dsa->seqn = 1; - if (get_char(dsa)) goto fail; -loop: if (scan_keyword(dsa)) goto fail; - if (strcmp(dsa->token, "NAME") == 0) - { if (tsp->name != NULL) - { xprintf("%s:%d: NAME entry multiply defined\n", dsa->fname, - dsa->seqn); - goto fail; - } - if (check_colon(dsa)) goto fail; - if (scan_token(dsa, 0)) goto fail; - if (strlen(dsa->token) == 0) - { xprintf("%s:%d: NAME entry incomplete\n", dsa->fname, - dsa->seqn); - goto fail; - } - tsp->name = xmalloc(strlen(dsa->token) + 1); - strcpy(tsp->name, dsa->token); - xprintf("tsp_read_data: NAME: %s\n", tsp->name); - if (check_newline(dsa)) goto fail; - } - else if (strcmp(dsa->token, "TYPE") == 0) - { if (tsp->type != TSP_UNDEF) - { xprintf("%s:%d: TYPE entry multiply defined\n", dsa->fname, - dsa->seqn); - goto fail; - } - if (check_colon(dsa)) goto fail; - if (scan_keyword(dsa)) goto fail; - if (strcmp(dsa->token, "TSP") == 0) - tsp->type = TSP_TSP; - else if (strcmp(dsa->token, "ATSP") == 0) - tsp->type = TSP_ATSP; - else if (strcmp(dsa->token, "TOUR") == 0) - tsp->type = TSP_TOUR; - else - { xprintf("%s:%d: data type `%s' not recognized\n", - dsa->fname, dsa->seqn, dsa->token); - goto fail; - } - xprintf("tsp_read_data: TYPE: %s\n", dsa->token); - if (check_newline(dsa)) goto fail; - } - else if (strcmp(dsa->token, "COMMENT") == 0) - { if (tsp->comment != NULL) - { xprintf("%s:%d: COMMENT entry multiply defined\n", - dsa->fname, dsa->seqn); - goto fail; - } - if (check_colon(dsa)) goto fail; - if (scan_comment(dsa)) goto fail; - tsp->comment = xmalloc(strlen(dsa->token) + 1); - strcpy(tsp->comment, dsa->token); - xprintf("tsp_read_data: COMMENT: %s\n", tsp->comment); - if (check_newline(dsa)) goto fail; - } - else if (strcmp(dsa->token, "DIMENSION") == 0) - { if (tsp->dimension != 0) - { xprintf("%s:%d: DIMENSION entry multiply defined\n", - dsa->fname, dsa->seqn); - goto fail; - } - if (check_colon(dsa)) goto fail; - if (scan_integer(dsa, 0, &tsp->dimension)) goto fail; - if (tsp->dimension < 1) - { xprintf("%s:%d: invalid dimension\n", dsa->fname, - dsa->seqn); - goto fail; - } - xprintf("tsp_read_data: DIMENSION: %d\n", tsp->dimension); - if (check_newline(dsa)) goto fail; - } - else if (strcmp(dsa->token, "EDGE_WEIGHT_TYPE") == 0) - { if (tsp->edge_weight_type != TSP_UNDEF) - { xprintf("%s:%d: EDGE_WEIGHT_TYPE entry multiply defined\n", - dsa->fname, dsa->seqn); - goto fail; - } - if (check_colon(dsa)) goto fail; - if (scan_keyword(dsa)) goto fail; - if (strcmp(dsa->token, "GEO") == 0) - tsp->edge_weight_type = TSP_GEO; - else if (strcmp(dsa->token, "EUC_2D") == 0) - tsp->edge_weight_type = TSP_EUC_2D; - else if (strcmp(dsa->token, "ATT") == 0) - tsp->edge_weight_type = TSP_ATT; - else if (strcmp(dsa->token, "EXPLICIT") == 0) - tsp->edge_weight_type = TSP_EXPLICIT; - else if (strcmp(dsa->token, "CEIL_2D") == 0) - tsp->edge_weight_type = TSP_CEIL_2D; - else - { xprintf("%s:%d: edge weight type `%s' not recognized\n", - dsa->fname, dsa->seqn, dsa->token); - goto fail; - } - xprintf("tsp_read_data: EDGE_WEIGHT_TYPE: %s\n", dsa->token); - if (check_newline(dsa)) goto fail; - } - else if (strcmp(dsa->token, "EDGE_WEIGHT_FORMAT") == 0) - { if (tsp->edge_weight_format != TSP_UNDEF) - { xprintf( - "%s:%d: EDGE_WEIGHT_FORMAT entry multiply defined\n", - dsa->fname, dsa->seqn); - goto fail; - } - if (check_colon(dsa)) goto fail; - if (scan_keyword(dsa)) goto fail; - if (strcmp(dsa->token, "UPPER_ROW") == 0) - tsp->edge_weight_format = TSP_UPPER_ROW; - else if (strcmp(dsa->token, "FULL_MATRIX") == 0) - tsp->edge_weight_format = TSP_FULL_MATRIX; - else if (strcmp(dsa->token, "FUNCTION") == 0) - tsp->edge_weight_format = TSP_FUNCTION; - else if (strcmp(dsa->token, "LOWER_DIAG_ROW") == 0) - tsp->edge_weight_format = TSP_LOWER_DIAG_ROW; - else - { xprintf("%s:%d: edge weight format `%s' not recognized\n", - dsa->fname, dsa->seqn, dsa->token); - goto fail; - } - xprintf("tsp_read_data: EDGE_WEIGHT_FORMAT: %s\n", dsa->token); - if (check_newline(dsa)) goto fail; - } - else if (strcmp(dsa->token, "DISPLAY_DATA_TYPE") == 0) - { if (tsp->display_data_type != TSP_UNDEF) - { xprintf("%s:%d: DISPLAY_DATA_TYPE entry multiply defined\n", - dsa->fname, dsa->seqn); - goto fail; - } - if (check_colon(dsa)) goto fail; - if (scan_keyword(dsa)) goto fail; - if (strcmp(dsa->token, "COORD_DISPLAY") == 0) - tsp->display_data_type = TSP_COORD_DISPLAY; - else if (strcmp(dsa->token, "TWOD_DISPLAY") == 0) - tsp->display_data_type = TSP_TWOD_DISPLAY; - else - { xprintf("%s:%d: display data type `%s' not recognized\n", - dsa->fname, dsa->seqn, dsa->token); - goto fail; - } - xprintf("tsp_read_data: DISPLAY_DATA_TYPE: %s\n", dsa->token); - if (check_newline(dsa)) goto fail; - } - else if (strcmp(dsa->token, "NODE_COORD_SECTION") == 0) - { int n = tsp->dimension, k, node; - if (n == 0) - { xprintf("%s:%d: DIMENSION entry not specified\n", - dsa->fname, dsa->seqn); - goto fail; - } - if (tsp->node_x_coord != NULL) - { xprintf("%s:%d: NODE_COORD_SECTION multiply specified\n", - dsa->fname, dsa->seqn); - goto fail; - } - if (check_newline(dsa)) goto fail; - tsp->node_x_coord = xcalloc(1+n, sizeof(double)); - tsp->node_y_coord = xcalloc(1+n, sizeof(double)); - for (node = 1; node <= n; node++) - tsp->node_x_coord[node] = tsp->node_y_coord[node] = DBL_MAX; - for (k = 1; k <= n; k++) - { if (scan_integer(dsa, 0, &node)) goto fail; - if (!(1 <= node && node <= n)) - { xprintf("%s:%d: invalid node number %d\n", dsa->fname, - dsa->seqn, node); - goto fail; - } - if (tsp->node_x_coord[node] != DBL_MAX) - { xprintf("%s:%d: node number %d multiply specified\n", - dsa->fname, dsa->seqn, node); - goto fail; - } - if (scan_number(dsa, 0, &tsp->node_x_coord[node])) - goto fail; - if (scan_number(dsa, 0, &tsp->node_y_coord[node])) - goto fail; - if (check_newline(dsa)) goto fail; - } - } - else if (strcmp(dsa->token, "DISPLAY_DATA_SECTION") == 0) - { int n = tsp->dimension, k, node; - if (n == 0) - { xprintf("%s:%d: DIMENSION entry not specified\n", - dsa->fname, dsa->seqn); - goto fail; - } - if (tsp->dply_x_coord != NULL) - { xprintf("%s:%d: DISPLAY_DATA_SECTION multiply specified\n", - dsa->fname, dsa->seqn); - goto fail; - } - if (check_newline(dsa)) goto fail; - tsp->dply_x_coord = xcalloc(1+n, sizeof(double)); - tsp->dply_y_coord = xcalloc(1+n, sizeof(double)); - for (node = 1; node <= n; node++) - tsp->dply_x_coord[node] = tsp->dply_y_coord[node] = DBL_MAX; - for (k = 1; k <= n; k++) - { if (scan_integer(dsa, 0, &node)) goto fail; - if (!(1 <= node && node <= n)) - { xprintf("%s:%d: invalid node number %d\n", dsa->fname, - dsa->seqn, node); - goto fail; - } - if (tsp->dply_x_coord[node] != DBL_MAX) - { xprintf("%s:%d: node number %d multiply specified\n", - dsa->fname, dsa->seqn, node); - goto fail; - } - if (scan_number(dsa, 0, &tsp->dply_x_coord[node])) - goto fail; - if (scan_number(dsa, 0, &tsp->dply_y_coord[node])) - goto fail; - if (check_newline(dsa)) goto fail; - } - } - else if (strcmp(dsa->token, "TOUR_SECTION") == 0) - { int n = tsp->dimension, k, node; - if (n == 0) - { xprintf("%s:%d: DIMENSION entry not specified\n", - dsa->fname, dsa->seqn); - goto fail; - } - if (tsp->tour != NULL) - { xprintf("%s:%d: TOUR_SECTION multiply specified\n", - dsa->fname, dsa->seqn); - goto fail; - } - if (check_newline(dsa)) goto fail; - tsp->tour = xcalloc(1+n, sizeof(int)); - for (k = 1; k <= n; k++) - { if (scan_integer(dsa, 1, &node)) goto fail; - if (!(1 <= node && node <= n)) - { xprintf("%s:%d: invalid node number %d\n", dsa->fname, - dsa->seqn, node); - goto fail; - } - tsp->tour[k] = node; - } - if (scan_integer(dsa, 1, &node)) goto fail; - if (node != -1) - { xprintf("%s:%d: extra node(s) detected\n", dsa->fname, - dsa->seqn); - goto fail; - } - if (check_newline(dsa)) goto fail; - } - else if (strcmp(dsa->token, "EDGE_WEIGHT_SECTION") == 0) - { int n = tsp->dimension, i, j, temp; - if (n == 0) - { xprintf("%s:%d: DIMENSION entry not specified\n", - dsa->fname, dsa->seqn); - goto fail; - } - if (tsp->edge_weight_format == TSP_UNDEF) - { xprintf("%s:%d: EDGE_WEIGHT_FORMAT entry not specified\n", - dsa->fname, dsa->seqn); - goto fail; - } - if (tsp->edge_weight != NULL) - { xprintf("%s:%d: EDGE_WEIGHT_SECTION multiply specified\n", - dsa->fname, dsa->seqn); - goto fail; - } - if (check_newline(dsa)) goto fail; - tsp->edge_weight = xcalloc(1+n*n, sizeof(int)); - switch (tsp->edge_weight_format) - { case TSP_FULL_MATRIX: - for (i = 1; i <= n; i++) - { for (j = 1; j <= n; j++) - { if (scan_integer(dsa, 1, &temp)) goto fail; - tsp->edge_weight[(i - 1) * n + j] = temp; - } - } - break; - case TSP_UPPER_ROW: - for (i = 1; i <= n; i++) - { tsp->edge_weight[(i - 1) * n + i] = 0; - for (j = i + 1; j <= n; j++) - { if (scan_integer(dsa, 1, &temp)) goto fail; - tsp->edge_weight[(i - 1) * n + j] = temp; - tsp->edge_weight[(j - 1) * n + i] = temp; - } - } - break; - case TSP_LOWER_DIAG_ROW: - for (i = 1; i <= n; i++) - { for (j = 1; j <= i; j++) - { if (scan_integer(dsa, 1, &temp)) goto fail; - tsp->edge_weight[(i - 1) * n + j] = temp; - tsp->edge_weight[(j - 1) * n + i] = temp; - } - } - break; - default: - goto fail; - } - if (check_newline(dsa)) goto fail; - } - else if (strcmp(dsa->token, "EOF") == 0) - { if (check_newline(dsa)) goto fail; - goto done; - } - else - { xprintf("%s:%d: keyword `%s' not recognized\n", dsa->fname, - dsa->seqn, dsa->token); - goto fail; - } - goto loop; -done: xprintf("tsp_read_data: %d lines were read\n", dsa->seqn-1); - fclose(dsa->fp); - return tsp; -fail: if (tsp != NULL) - { if (tsp->name != NULL) xfree(tsp->name); - if (tsp->comment != NULL) xfree(tsp->comment); - if (tsp->node_x_coord != NULL) xfree(tsp->node_x_coord); - if (tsp->node_y_coord != NULL) xfree(tsp->node_y_coord); - if (tsp->dply_x_coord != NULL) xfree(tsp->dply_x_coord); - if (tsp->dply_y_coord != NULL) xfree(tsp->dply_y_coord); - if (tsp->tour != NULL) xfree(tsp->tour); - if (tsp->edge_weight != NULL) xfree(tsp->edge_weight); - xfree(tsp); - } - if (dsa->fp != NULL) fclose(dsa->fp); - return NULL; -} - -/*---------------------------------------------------------------------- --- tsp_free_data - free TSP instance data. --- --- *Synopsis* --- --- #include "glptsp.h" --- void tsp_free_data(TSP *tsp); --- --- *Description* --- --- The routine tsp_free_data frees all the memory allocated to the TSP --- instance data block, which the parameter tsp points to. */ - -void tsp_free_data(TSP *tsp) -{ if (tsp->name != NULL) xfree(tsp->name); - if (tsp->comment != NULL) xfree(tsp->comment); - if (tsp->node_x_coord != NULL) xfree(tsp->node_x_coord); - if (tsp->node_y_coord != NULL) xfree(tsp->node_y_coord); - if (tsp->dply_x_coord != NULL) xfree(tsp->dply_x_coord); - if (tsp->dply_y_coord != NULL) xfree(tsp->dply_y_coord); - if (tsp->tour != NULL) xfree(tsp->tour); - if (tsp->edge_weight != NULL) xfree(tsp->edge_weight); - xfree(tsp); - return; -} - -/*---------------------------------------------------------------------- --- tsp_distance - compute distance between two nodes. --- --- *Synopsis* --- --- #include "glptsp.h" --- int tsp_distance(TSP *tsp, int i, int j); --- --- *Description* --- --- The routine tsp_distance computes the distance between i-th and j-th --- nodes for the TSP instance, which tsp points to. --- --- *Returns* --- --- The routine tsp_distance returns the computed distance. */ - -#define nint(x) ((int)((x) + 0.5)) - -static double rad(double x) -{ /* convert input coordinate to longitude/latitude, in radians */ - double pi = 3.141592, deg, min; - deg = (int)x; - min = x - deg; - return pi * (deg + 5.0 * min / 3.0) / 180.0; -} - -int tsp_distance(TSP *tsp, int i, int j) -{ int n = tsp->dimension, dij; - if (!(tsp->type == TSP_TSP || tsp->type == TSP_ATSP)) - xfault("tsp_distance: invalid TSP instance\n"); - if (!(1 <= i && i <= n && 1 <= j && j <= n)) - xfault("tsp_distance: node number out of range\n"); - switch (tsp->edge_weight_type) - { case TSP_UNDEF: - xfault("tsp_distance: edge weight type not specified\n"); - case TSP_EXPLICIT: - if (tsp->edge_weight == NULL) - xfault("tsp_distance: edge weights not specified\n"); - dij = tsp->edge_weight[(i - 1) * n + j]; - break; - case TSP_EUC_2D: - if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) - xfault("tsp_distance: node coordinates not specified\n"); - { double xd, yd; - xd = tsp->node_x_coord[i] - tsp->node_x_coord[j]; - yd = tsp->node_y_coord[i] - tsp->node_y_coord[j]; - dij = nint(sqrt(xd * xd + yd * yd)); - } - break; - case TSP_CEIL_2D: - if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) - xfault("tsp_distance: node coordinates not specified\n"); - { double xd, yd; - xd = tsp->node_x_coord[i] - tsp->node_x_coord[j]; - yd = tsp->node_y_coord[i] - tsp->node_y_coord[j]; - dij = (int)ceil(sqrt(xd * xd + yd * yd)); - } - break; - case TSP_GEO: - if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) - xfault("tsp_distance: node coordinates not specified\n"); - { double rrr = 6378.388; - double latitude_i = rad(tsp->node_x_coord[i]); - double latitude_j = rad(tsp->node_x_coord[j]); - double longitude_i = rad(tsp->node_y_coord[i]); - double longitude_j = rad(tsp->node_y_coord[j]); - double q1 = cos(longitude_i - longitude_j); - double q2 = cos(latitude_i - latitude_j); - double q3 = cos(latitude_i + latitude_j); - dij = (int)(rrr * acos(0.5 * ((1.0 + q1) * q2 - - (1.0 - q1) *q3)) + 1.0); - } - break; - case TSP_ATT: - if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) - xfault("tsp_distance: node coordinates not specified\n"); - { int tij; - double xd, yd, rij; - xd = tsp->node_x_coord[i] - tsp->node_x_coord[j]; - yd = tsp->node_y_coord[i] - tsp->node_y_coord[j]; - rij = sqrt((xd * xd + yd * yd) / 10.0); - tij = nint(rij); - if (tij < rij) dij = tij + 1; else dij = tij; - } - break; - default: - xassert(tsp->edge_weight_type != tsp->edge_weight_type); - } - return dij; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/glptsp.h b/resources/3rdparty/glpk-4.53/src/glptsp.h deleted file mode 100644 index 6b82ee5e5..000000000 --- a/resources/3rdparty/glpk-4.53/src/glptsp.h +++ /dev/null @@ -1,104 +0,0 @@ -/* glptsp.h (TSP format) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef GLPTSP_H -#define GLPTSP_H - -typedef struct TSP TSP; - -struct TSP -{ /* TSP (or related problem) instance in the format described in - the report [G.Reinelt, TSPLIB 95] */ - /*--------------------------------------------------------------*/ - /* the specification part */ - char *name; - /* identifies the data file */ - int type; - /* specifies the type of data: */ -#define TSP_UNDEF 0 /* undefined */ -#define TSP_TSP 1 /* symmetric TSP */ -#define TSP_ATSP 2 /* asymmetric TSP */ -#define TSP_TOUR 3 /* collection of tours */ - char *comment; - /* additional comments (usually the name of the contributor or - creator of the problem instance is given here) */ - int dimension; - /* for a TSP or ATSP, the dimension is the number of its nodes - for a TOUR it is the dimension of the corresponding problem */ - int edge_weight_type; - /* specifies how the edge weights (or distances) are given: */ -#define TSP_UNDEF 0 /* undefined */ -#define TSP_EXPLICIT 1 /* listed explicitly */ -#define TSP_EUC_2D 2 /* Eucl. distances in 2-D */ -#define TSP_CEIL_2D 3 /* Eucl. distances in 2-D rounded up */ -#define TSP_GEO 4 /* geographical distances */ -#define TSP_ATT 5 /* special distance function */ - int edge_weight_format; - /* describes the format of the edge weights if they are given - explicitly: */ -#define TSP_UNDEF 0 /* undefined */ -#define TSP_FUNCTION 1 /* given by a function */ -#define TSP_FULL_MATRIX 2 /* given by a full matrix */ -#define TSP_UPPER_ROW 3 /* upper triangulat matrix (row-wise - without diagonal entries) */ -#define TSP_LOWER_DIAG_ROW 4 /* lower triangular matrix (row-wise - including diagonal entries) */ - int display_data_type; - /* specifies how a graphical display of the nodes can be - obtained: */ -#define TSP_UNDEF 0 /* undefined */ -#define TSP_COORD_DISPLAY 1 /* display is generated from the node - coordinates */ -#define TSP_TWOD_DISPLAY 2 /* explicit coordinates in 2-D are - given */ - /*--------------------------------------------------------------*/ - /* data part */ - /* NODE_COORD_SECTION: */ - double *node_x_coord; /* double node_x_coord[1+dimension]; */ - double *node_y_coord; /* double node_y_coord[1+dimension]; */ - /* DISPLAY_DATA_SECTION: */ - double *dply_x_coord; /* double dply_x_coord[1+dimension]; */ - double *dply_y_coord; /* double dply_y_coord[1+dimension]; */ - /* TOUR_SECTION: */ - int *tour; /* int tour[1+dimension]; */ - /* EDGE_WEIGHT_SECTION: */ - int *edge_weight; /* int edge_weight[1+dimension*dimension]; */ -}; - -#define tsp_read_data _glp_tsp_read_data -#define tsp_free_data _glp_tsp_free_data -#define tsp_distance _glp_tsp_distance - -TSP *tsp_read_data(char *fname); -/* read TSP instance data */ - -void tsp_free_data(TSP *tsp); -/* free TSP instance data */ - -int tsp_distance(TSP *tsp, int i, int j); -/* compute distance between two nodes */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/lux.c b/resources/3rdparty/glpk-4.53/src/lux.c deleted file mode 100644 index 38cb758cb..000000000 --- a/resources/3rdparty/glpk-4.53/src/lux.c +++ /dev/null @@ -1,1030 +0,0 @@ -/* lux.c (LU-factorization, rational arithmetic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "lux.h" - -#define xfault xerror -#define dmp_create_poolx(size) dmp_create_pool() - -/*********************************************************************** -* lux_create - create LU-factorization -* -* SYNOPSIS -* -* #include "lux.h" -* LUX *lux_create(int n); -* -* DESCRIPTION -* -* The routine lux_create creates LU-factorization data structure for -* a matrix of the order n. Initially the factorization corresponds to -* the unity matrix (F = V = P = Q = I, so A = I). -* -* RETURNS -* -* The routine returns a pointer to the created LU-factorization data -* structure, which represents the unity matrix of the order n. */ - -LUX *lux_create(int n) -{ LUX *lux; - int k; - if (n < 1) - xfault("lux_create: n = %d; invalid parameter\n", n); - lux = xmalloc(sizeof(LUX)); - lux->n = n; - lux->pool = dmp_create_poolx(sizeof(LUXELM)); - lux->F_row = xcalloc(1+n, sizeof(LUXELM *)); - lux->F_col = xcalloc(1+n, sizeof(LUXELM *)); - lux->V_piv = xcalloc(1+n, sizeof(mpq_t)); - lux->V_row = xcalloc(1+n, sizeof(LUXELM *)); - lux->V_col = xcalloc(1+n, sizeof(LUXELM *)); - lux->P_row = xcalloc(1+n, sizeof(int)); - lux->P_col = xcalloc(1+n, sizeof(int)); - lux->Q_row = xcalloc(1+n, sizeof(int)); - lux->Q_col = xcalloc(1+n, sizeof(int)); - for (k = 1; k <= n; k++) - { lux->F_row[k] = lux->F_col[k] = NULL; - mpq_init(lux->V_piv[k]); - mpq_set_si(lux->V_piv[k], 1, 1); - lux->V_row[k] = lux->V_col[k] = NULL; - lux->P_row[k] = lux->P_col[k] = k; - lux->Q_row[k] = lux->Q_col[k] = k; - } - lux->rank = n; - return lux; -} - -/*********************************************************************** -* initialize - initialize LU-factorization data structures -* -* This routine initializes data structures for subsequent computing -* the LU-factorization of a given matrix A, which is specified by the -* formal routine col. On exit V = A and F = P = Q = I, where I is the -* unity matrix. */ - -static void initialize(LUX *lux, int (*col)(void *info, int j, - int ind[], mpq_t val[]), void *info, LUXWKA *wka) -{ int n = lux->n; - DMP *pool = lux->pool; - LUXELM **F_row = lux->F_row; - LUXELM **F_col = lux->F_col; - mpq_t *V_piv = lux->V_piv; - LUXELM **V_row = lux->V_row; - LUXELM **V_col = lux->V_col; - int *P_row = lux->P_row; - int *P_col = lux->P_col; - int *Q_row = lux->Q_row; - int *Q_col = lux->Q_col; - int *R_len = wka->R_len; - int *R_head = wka->R_head; - int *R_prev = wka->R_prev; - int *R_next = wka->R_next; - int *C_len = wka->C_len; - int *C_head = wka->C_head; - int *C_prev = wka->C_prev; - int *C_next = wka->C_next; - LUXELM *fij, *vij; - int i, j, k, len, *ind; - mpq_t *val; - /* F := I */ - for (i = 1; i <= n; i++) - { while (F_row[i] != NULL) - { fij = F_row[i], F_row[i] = fij->r_next; - mpq_clear(fij->val); - dmp_free_atom(pool, fij, sizeof(LUXELM)); - } - } - for (j = 1; j <= n; j++) F_col[j] = NULL; - /* V := 0 */ - for (k = 1; k <= n; k++) mpq_set_si(V_piv[k], 0, 1); - for (i = 1; i <= n; i++) - { while (V_row[i] != NULL) - { vij = V_row[i], V_row[i] = vij->r_next; - mpq_clear(vij->val); - dmp_free_atom(pool, vij, sizeof(LUXELM)); - } - } - for (j = 1; j <= n; j++) V_col[j] = NULL; - /* V := A */ - ind = xcalloc(1+n, sizeof(int)); - val = xcalloc(1+n, sizeof(mpq_t)); - for (k = 1; k <= n; k++) mpq_init(val[k]); - for (j = 1; j <= n; j++) - { /* obtain j-th column of matrix A */ - len = col(info, j, ind, val); - if (!(0 <= len && len <= n)) - xfault("lux_decomp: j = %d: len = %d; invalid column length" - "\n", j, len); - /* copy elements of j-th column to matrix V */ - for (k = 1; k <= len; k++) - { /* get row index of a[i,j] */ - i = ind[k]; - if (!(1 <= i && i <= n)) - xfault("lux_decomp: j = %d: i = %d; row index out of ran" - "ge\n", j, i); - /* check for duplicate indices */ - if (V_row[i] != NULL && V_row[i]->j == j) - xfault("lux_decomp: j = %d: i = %d; duplicate row indice" - "s not allowed\n", j, i); - /* check for zero value */ - if (mpq_sgn(val[k]) == 0) - xfault("lux_decomp: j = %d: i = %d; zero elements not al" - "lowed\n", j, i); - /* add new element v[i,j] = a[i,j] to V */ - vij = dmp_get_atom(pool, sizeof(LUXELM)); - vij->i = i, vij->j = j; - mpq_init(vij->val); - mpq_set(vij->val, val[k]); - vij->r_prev = NULL; - vij->r_next = V_row[i]; - vij->c_prev = NULL; - vij->c_next = V_col[j]; - if (vij->r_next != NULL) vij->r_next->r_prev = vij; - if (vij->c_next != NULL) vij->c_next->c_prev = vij; - V_row[i] = V_col[j] = vij; - } - } - xfree(ind); - for (k = 1; k <= n; k++) mpq_clear(val[k]); - xfree(val); - /* P := Q := I */ - for (k = 1; k <= n; k++) - P_row[k] = P_col[k] = Q_row[k] = Q_col[k] = k; - /* the rank of A and V is not determined yet */ - lux->rank = -1; - /* initially the entire matrix V is active */ - /* determine its row lengths */ - for (i = 1; i <= n; i++) - { len = 0; - for (vij = V_row[i]; vij != NULL; vij = vij->r_next) len++; - R_len[i] = len; - } - /* build linked lists of active rows */ - for (len = 0; len <= n; len++) R_head[len] = 0; - for (i = 1; i <= n; i++) - { len = R_len[i]; - R_prev[i] = 0; - R_next[i] = R_head[len]; - if (R_next[i] != 0) R_prev[R_next[i]] = i; - R_head[len] = i; - } - /* determine its column lengths */ - for (j = 1; j <= n; j++) - { len = 0; - for (vij = V_col[j]; vij != NULL; vij = vij->c_next) len++; - C_len[j] = len; - } - /* build linked lists of active columns */ - for (len = 0; len <= n; len++) C_head[len] = 0; - for (j = 1; j <= n; j++) - { len = C_len[j]; - C_prev[j] = 0; - C_next[j] = C_head[len]; - if (C_next[j] != 0) C_prev[C_next[j]] = j; - C_head[len] = j; - } - return; -} - -/*********************************************************************** -* find_pivot - choose a pivot element -* -* This routine chooses a pivot element v[p,q] in the active submatrix -* of matrix U = P*V*Q. -* -* It is assumed that on entry the matrix U has the following partially -* triangularized form: -* -* 1 k n -* 1 x x x x x x x x x x -* . x x x x x x x x x -* . . x x x x x x x x -* . . . x x x x x x x -* k . . . . * * * * * * -* . . . . * * * * * * -* . . . . * * * * * * -* . . . . * * * * * * -* . . . . * * * * * * -* n . . . . * * * * * * -* -* where rows and columns k, k+1, ..., n belong to the active submatrix -* (elements of the active submatrix are marked by '*'). -* -* Since the matrix U = P*V*Q is not stored, the routine works with the -* matrix V. It is assumed that the row-wise representation corresponds -* to the matrix V, but the column-wise representation corresponds to -* the active submatrix of the matrix V, i.e. elements of the matrix V, -* which does not belong to the active submatrix, are missing from the -* column linked lists. It is also assumed that each active row of the -* matrix V is in the set R[len], where len is number of non-zeros in -* the row, and each active column of the matrix V is in the set C[len], -* where len is number of non-zeros in the column (in the latter case -* only elements of the active submatrix are counted; such elements are -* marked by '*' on the figure above). -* -* Due to exact arithmetic any non-zero element of the active submatrix -* can be chosen as a pivot. However, to keep sparsity of the matrix V -* the routine uses Markowitz strategy, trying to choose such element -* v[p,q], which has smallest Markowitz cost (nr[p]-1) * (nc[q]-1), -* where nr[p] and nc[q] are the number of non-zero elements, resp., in -* p-th row and in q-th column of the active submatrix. -* -* In order to reduce the search, i.e. not to walk through all elements -* of the active submatrix, the routine exploits a technique proposed by -* I.Duff. This technique is based on using the sets R[len] and C[len] -* of active rows and columns. -* -* On exit the routine returns a pointer to a pivot v[p,q] chosen, or -* NULL, if the active submatrix is empty. */ - -static LUXELM *find_pivot(LUX *lux, LUXWKA *wka) -{ int n = lux->n; - LUXELM **V_row = lux->V_row; - LUXELM **V_col = lux->V_col; - int *R_len = wka->R_len; - int *R_head = wka->R_head; - int *R_next = wka->R_next; - int *C_len = wka->C_len; - int *C_head = wka->C_head; - int *C_next = wka->C_next; - LUXELM *piv, *some, *vij; - int i, j, len, min_len, ncand, piv_lim = 5; - double best, cost; - /* nothing is chosen so far */ - piv = NULL, best = DBL_MAX, ncand = 0; - /* if in the active submatrix there is a column that has the only - non-zero (column singleton), choose it as a pivot */ - j = C_head[1]; - if (j != 0) - { xassert(C_len[j] == 1); - piv = V_col[j]; - xassert(piv != NULL && piv->c_next == NULL); - goto done; - } - /* if in the active submatrix there is a row that has the only - non-zero (row singleton), choose it as a pivot */ - i = R_head[1]; - if (i != 0) - { xassert(R_len[i] == 1); - piv = V_row[i]; - xassert(piv != NULL && piv->r_next == NULL); - goto done; - } - /* there are no singletons in the active submatrix; walk through - other non-empty rows and columns */ - for (len = 2; len <= n; len++) - { /* consider active columns having len non-zeros */ - for (j = C_head[len]; j != 0; j = C_next[j]) - { /* j-th column has len non-zeros */ - /* find an element in the row of minimal length */ - some = NULL, min_len = INT_MAX; - for (vij = V_col[j]; vij != NULL; vij = vij->c_next) - { if (min_len > R_len[vij->i]) - some = vij, min_len = R_len[vij->i]; - /* if Markowitz cost of this element is not greater than - (len-1)**2, it can be chosen right now; this heuristic - reduces the search and works well in many cases */ - if (min_len <= len) - { piv = some; - goto done; - } - } - /* j-th column has been scanned */ - /* the minimal element found is a next pivot candidate */ - xassert(some != NULL); - ncand++; - /* compute its Markowitz cost */ - cost = (double)(min_len - 1) * (double)(len - 1); - /* choose between the current candidate and this element */ - if (cost < best) piv = some, best = cost; - /* if piv_lim candidates have been considered, there is a - doubt that a much better candidate exists; therefore it - is the time to terminate the search */ - if (ncand == piv_lim) goto done; - } - /* now consider active rows having len non-zeros */ - for (i = R_head[len]; i != 0; i = R_next[i]) - { /* i-th row has len non-zeros */ - /* find an element in the column of minimal length */ - some = NULL, min_len = INT_MAX; - for (vij = V_row[i]; vij != NULL; vij = vij->r_next) - { if (min_len > C_len[vij->j]) - some = vij, min_len = C_len[vij->j]; - /* if Markowitz cost of this element is not greater than - (len-1)**2, it can be chosen right now; this heuristic - reduces the search and works well in many cases */ - if (min_len <= len) - { piv = some; - goto done; - } - } - /* i-th row has been scanned */ - /* the minimal element found is a next pivot candidate */ - xassert(some != NULL); - ncand++; - /* compute its Markowitz cost */ - cost = (double)(len - 1) * (double)(min_len - 1); - /* choose between the current candidate and this element */ - if (cost < best) piv = some, best = cost; - /* if piv_lim candidates have been considered, there is a - doubt that a much better candidate exists; therefore it - is the time to terminate the search */ - if (ncand == piv_lim) goto done; - } - } -done: /* bring the pivot v[p,q] to the factorizing routine */ - return piv; -} - -/*********************************************************************** -* eliminate - perform gaussian elimination -* -* This routine performs elementary gaussian transformations in order -* to eliminate subdiagonal elements in the k-th column of the matrix -* U = P*V*Q using the pivot element u[k,k], where k is the number of -* the current elimination step. -* -* The parameter piv specifies the pivot element v[p,q] = u[k,k]. -* -* Each time when the routine applies the elementary transformation to -* a non-pivot row of the matrix V, it stores the corresponding element -* to the matrix F in order to keep the main equality A = F*V. -* -* The routine assumes that on entry the matrices L = P*F*inv(P) and -* U = P*V*Q are the following: -* -* 1 k 1 k n -* 1 1 . . . . . . . . . 1 x x x x x x x x x x -* x 1 . . . . . . . . . x x x x x x x x x -* x x 1 . . . . . . . . . x x x x x x x x -* x x x 1 . . . . . . . . . x x x x x x x -* k x x x x 1 . . . . . k . . . . * * * * * * -* x x x x _ 1 . . . . . . . . # * * * * * -* x x x x _ . 1 . . . . . . . # * * * * * -* x x x x _ . . 1 . . . . . . # * * * * * -* x x x x _ . . . 1 . . . . . # * * * * * -* n x x x x _ . . . . 1 n . . . . # * * * * * -* -* matrix L matrix U -* -* where rows and columns of the matrix U with numbers k, k+1, ..., n -* form the active submatrix (eliminated elements are marked by '#' and -* other elements of the active submatrix are marked by '*'). Note that -* each eliminated non-zero element u[i,k] of the matrix U gives the -* corresponding element l[i,k] of the matrix L (marked by '_'). -* -* Actually all operations are performed on the matrix V. Should note -* that the row-wise representation corresponds to the matrix V, but the -* column-wise representation corresponds to the active submatrix of the -* matrix V, i.e. elements of the matrix V, which doesn't belong to the -* active submatrix, are missing from the column linked lists. -* -* Let u[k,k] = v[p,q] be the pivot. In order to eliminate subdiagonal -* elements u[i',k] = v[i,q], i' = k+1, k+2, ..., n, the routine applies -* the following elementary gaussian transformations: -* -* (i-th row of V) := (i-th row of V) - f[i,p] * (p-th row of V), -* -* where f[i,p] = v[i,q] / v[p,q] is a gaussian multiplier. -* -* Additionally, in order to keep the main equality A = F*V, each time -* when the routine applies the transformation to i-th row of the matrix -* V, it also adds f[i,p] as a new element to the matrix F. -* -* IMPORTANT: On entry the working arrays flag and work should contain -* zeros. This status is provided by the routine on exit. */ - -static void eliminate(LUX *lux, LUXWKA *wka, LUXELM *piv, int flag[], - mpq_t work[]) -{ DMP *pool = lux->pool; - LUXELM **F_row = lux->F_row; - LUXELM **F_col = lux->F_col; - mpq_t *V_piv = lux->V_piv; - LUXELM **V_row = lux->V_row; - LUXELM **V_col = lux->V_col; - int *R_len = wka->R_len; - int *R_head = wka->R_head; - int *R_prev = wka->R_prev; - int *R_next = wka->R_next; - int *C_len = wka->C_len; - int *C_head = wka->C_head; - int *C_prev = wka->C_prev; - int *C_next = wka->C_next; - LUXELM *fip, *vij, *vpj, *viq, *next; - mpq_t temp; - int i, j, p, q; - mpq_init(temp); - /* determine row and column indices of the pivot v[p,q] */ - xassert(piv != NULL); - p = piv->i, q = piv->j; - /* remove p-th (pivot) row from the active set; it will never - return there */ - if (R_prev[p] == 0) - R_head[R_len[p]] = R_next[p]; - else - R_next[R_prev[p]] = R_next[p]; - if (R_next[p] == 0) - ; - else - R_prev[R_next[p]] = R_prev[p]; - /* remove q-th (pivot) column from the active set; it will never - return there */ - if (C_prev[q] == 0) - C_head[C_len[q]] = C_next[q]; - else - C_next[C_prev[q]] = C_next[q]; - if (C_next[q] == 0) - ; - else - C_prev[C_next[q]] = C_prev[q]; - /* store the pivot value in a separate array */ - mpq_set(V_piv[p], piv->val); - /* remove the pivot from p-th row */ - if (piv->r_prev == NULL) - V_row[p] = piv->r_next; - else - piv->r_prev->r_next = piv->r_next; - if (piv->r_next == NULL) - ; - else - piv->r_next->r_prev = piv->r_prev; - R_len[p]--; - /* remove the pivot from q-th column */ - if (piv->c_prev == NULL) - V_col[q] = piv->c_next; - else - piv->c_prev->c_next = piv->c_next; - if (piv->c_next == NULL) - ; - else - piv->c_next->c_prev = piv->c_prev; - C_len[q]--; - /* free the space occupied by the pivot */ - mpq_clear(piv->val); - dmp_free_atom(pool, piv, sizeof(LUXELM)); - /* walk through p-th (pivot) row, which already does not contain - the pivot v[p,q], and do the following... */ - for (vpj = V_row[p]; vpj != NULL; vpj = vpj->r_next) - { /* get column index of v[p,j] */ - j = vpj->j; - /* store v[p,j] in the working array */ - flag[j] = 1; - mpq_set(work[j], vpj->val); - /* remove j-th column from the active set; it will return there - later with a new length */ - if (C_prev[j] == 0) - C_head[C_len[j]] = C_next[j]; - else - C_next[C_prev[j]] = C_next[j]; - if (C_next[j] == 0) - ; - else - C_prev[C_next[j]] = C_prev[j]; - /* v[p,j] leaves the active submatrix, so remove it from j-th - column; however, v[p,j] is kept in p-th row */ - if (vpj->c_prev == NULL) - V_col[j] = vpj->c_next; - else - vpj->c_prev->c_next = vpj->c_next; - if (vpj->c_next == NULL) - ; - else - vpj->c_next->c_prev = vpj->c_prev; - C_len[j]--; - } - /* now walk through q-th (pivot) column, which already does not - contain the pivot v[p,q], and perform gaussian elimination */ - while (V_col[q] != NULL) - { /* element v[i,q] has to be eliminated */ - viq = V_col[q]; - /* get row index of v[i,q] */ - i = viq->i; - /* remove i-th row from the active set; later it will return - there with a new length */ - if (R_prev[i] == 0) - R_head[R_len[i]] = R_next[i]; - else - R_next[R_prev[i]] = R_next[i]; - if (R_next[i] == 0) - ; - else - R_prev[R_next[i]] = R_prev[i]; - /* compute gaussian multiplier f[i,p] = v[i,q] / v[p,q] and - store it in the matrix F */ - fip = dmp_get_atom(pool, sizeof(LUXELM)); - fip->i = i, fip->j = p; - mpq_init(fip->val); - mpq_div(fip->val, viq->val, V_piv[p]); - fip->r_prev = NULL; - fip->r_next = F_row[i]; - fip->c_prev = NULL; - fip->c_next = F_col[p]; - if (fip->r_next != NULL) fip->r_next->r_prev = fip; - if (fip->c_next != NULL) fip->c_next->c_prev = fip; - F_row[i] = F_col[p] = fip; - /* v[i,q] has to be eliminated, so remove it from i-th row */ - if (viq->r_prev == NULL) - V_row[i] = viq->r_next; - else - viq->r_prev->r_next = viq->r_next; - if (viq->r_next == NULL) - ; - else - viq->r_next->r_prev = viq->r_prev; - R_len[i]--; - /* and also from q-th column */ - V_col[q] = viq->c_next; - C_len[q]--; - /* free the space occupied by v[i,q] */ - mpq_clear(viq->val); - dmp_free_atom(pool, viq, sizeof(LUXELM)); - /* perform gaussian transformation: - (i-th row) := (i-th row) - f[i,p] * (p-th row) - note that now p-th row, which is in the working array, - does not contain the pivot v[p,q], and i-th row does not - contain the element v[i,q] to be eliminated */ - /* walk through i-th row and transform existing non-zero - elements */ - for (vij = V_row[i]; vij != NULL; vij = next) - { next = vij->r_next; - /* get column index of v[i,j] */ - j = vij->j; - /* v[i,j] := v[i,j] - f[i,p] * v[p,j] */ - if (flag[j]) - { /* v[p,j] != 0 */ - flag[j] = 0; - mpq_mul(temp, fip->val, work[j]); - mpq_sub(vij->val, vij->val, temp); - if (mpq_sgn(vij->val) == 0) - { /* new v[i,j] is zero, so remove it from the active - submatrix */ - /* remove v[i,j] from i-th row */ - if (vij->r_prev == NULL) - V_row[i] = vij->r_next; - else - vij->r_prev->r_next = vij->r_next; - if (vij->r_next == NULL) - ; - else - vij->r_next->r_prev = vij->r_prev; - R_len[i]--; - /* remove v[i,j] from j-th column */ - if (vij->c_prev == NULL) - V_col[j] = vij->c_next; - else - vij->c_prev->c_next = vij->c_next; - if (vij->c_next == NULL) - ; - else - vij->c_next->c_prev = vij->c_prev; - C_len[j]--; - /* free the space occupied by v[i,j] */ - mpq_clear(vij->val); - dmp_free_atom(pool, vij, sizeof(LUXELM)); - } - } - } - /* now flag is the pattern of the set v[p,*] \ v[i,*] */ - /* walk through p-th (pivot) row and create new elements in - i-th row, which appear due to fill-in */ - for (vpj = V_row[p]; vpj != NULL; vpj = vpj->r_next) - { j = vpj->j; - if (flag[j]) - { /* create new non-zero v[i,j] = 0 - f[i,p] * v[p,j] and - add it to i-th row and j-th column */ - vij = dmp_get_atom(pool, sizeof(LUXELM)); - vij->i = i, vij->j = j; - mpq_init(vij->val); - mpq_mul(vij->val, fip->val, work[j]); - mpq_neg(vij->val, vij->val); - vij->r_prev = NULL; - vij->r_next = V_row[i]; - vij->c_prev = NULL; - vij->c_next = V_col[j]; - if (vij->r_next != NULL) vij->r_next->r_prev = vij; - if (vij->c_next != NULL) vij->c_next->c_prev = vij; - V_row[i] = V_col[j] = vij; - R_len[i]++, C_len[j]++; - } - else - { /* there is no fill-in, because v[i,j] already exists in - i-th row; restore the flag, which was reset before */ - flag[j] = 1; - } - } - /* now i-th row has been completely transformed and can return - to the active set with a new length */ - R_prev[i] = 0; - R_next[i] = R_head[R_len[i]]; - if (R_next[i] != 0) R_prev[R_next[i]] = i; - R_head[R_len[i]] = i; - } - /* at this point q-th (pivot) column must be empty */ - xassert(C_len[q] == 0); - /* walk through p-th (pivot) row again and do the following... */ - for (vpj = V_row[p]; vpj != NULL; vpj = vpj->r_next) - { /* get column index of v[p,j] */ - j = vpj->j; - /* erase v[p,j] from the working array */ - flag[j] = 0; - mpq_set_si(work[j], 0, 1); - /* now j-th column has been completely transformed, so it can - return to the active list with a new length */ - C_prev[j] = 0; - C_next[j] = C_head[C_len[j]]; - if (C_next[j] != 0) C_prev[C_next[j]] = j; - C_head[C_len[j]] = j; - } - mpq_clear(temp); - /* return to the factorizing routine */ - return; -} - -/*********************************************************************** -* lux_decomp - compute LU-factorization -* -* SYNOPSIS -* -* #include "lux.h" -* int lux_decomp(LUX *lux, int (*col)(void *info, int j, int ind[], -* mpq_t val[]), void *info); -* -* DESCRIPTION -* -* The routine lux_decomp computes LU-factorization of a given square -* matrix A. -* -* The parameter lux specifies LU-factorization data structure built by -* means of the routine lux_create. -* -* The formal routine col specifies the original matrix A. In order to -* obtain j-th column of the matrix A the routine lux_decomp calls the -* routine col with the parameter j (1 <= j <= n, where n is the order -* of A). In response the routine col should store row indices and -* numerical values of non-zero elements of j-th column of A to the -* locations ind[1], ..., ind[len] and val[1], ..., val[len], resp., -* where len is the number of non-zeros in j-th column, which should be -* returned on exit. Neiter zero nor duplicate elements are allowed. -* -* The parameter info is a transit pointer passed to the formal routine -* col; it can be used for various purposes. -* -* RETURNS -* -* The routine lux_decomp returns the singularity flag. Zero flag means -* that the original matrix A is non-singular while non-zero flag means -* that A is (exactly!) singular. -* -* Note that LU-factorization is valid in both cases, however, in case -* of singularity some rows of the matrix V (including pivot elements) -* will be empty. -* -* REPAIRING SINGULAR MATRIX -* -* If the routine lux_decomp returns non-zero flag, it provides all -* necessary information that can be used for "repairing" the matrix A, -* where "repairing" means replacing linearly dependent columns of the -* matrix A by appropriate columns of the unity matrix. This feature is -* needed when the routine lux_decomp is used for reinverting the basis -* matrix within the simplex method procedure. -* -* On exit linearly dependent columns of the matrix U have the numbers -* rank+1, rank+2, ..., n, where rank is the exact rank of the matrix A -* stored by the routine to the member lux->rank. The correspondence -* between columns of A and U is the same as between columns of V and U. -* Thus, linearly dependent columns of the matrix A have the numbers -* Q_col[rank+1], Q_col[rank+2], ..., Q_col[n], where Q_col is an array -* representing the permutation matrix Q in column-like format. It is -* understood that each j-th linearly dependent column of the matrix U -* should be replaced by the unity vector, where all elements are zero -* except the unity diagonal element u[j,j]. On the other hand j-th row -* of the matrix U corresponds to the row of the matrix V (and therefore -* of the matrix A) with the number P_row[j], where P_row is an array -* representing the permutation matrix P in row-like format. Thus, each -* j-th linearly dependent column of the matrix U should be replaced by -* a column of the unity matrix with the number P_row[j]. -* -* The code that repairs the matrix A may look like follows: -* -* for (j = rank+1; j <= n; j++) -* { replace column Q_col[j] of the matrix A by column P_row[j] of -* the unity matrix; -* } -* -* where rank, P_row, and Q_col are members of the structure LUX. */ - -int lux_decomp(LUX *lux, int (*col)(void *info, int j, int ind[], - mpq_t val[]), void *info) -{ int n = lux->n; - LUXELM **V_row = lux->V_row; - LUXELM **V_col = lux->V_col; - int *P_row = lux->P_row; - int *P_col = lux->P_col; - int *Q_row = lux->Q_row; - int *Q_col = lux->Q_col; - LUXELM *piv, *vij; - LUXWKA *wka; - int i, j, k, p, q, t, *flag; - mpq_t *work; - /* allocate working area */ - wka = xmalloc(sizeof(LUXWKA)); - wka->R_len = xcalloc(1+n, sizeof(int)); - wka->R_head = xcalloc(1+n, sizeof(int)); - wka->R_prev = xcalloc(1+n, sizeof(int)); - wka->R_next = xcalloc(1+n, sizeof(int)); - wka->C_len = xcalloc(1+n, sizeof(int)); - wka->C_head = xcalloc(1+n, sizeof(int)); - wka->C_prev = xcalloc(1+n, sizeof(int)); - wka->C_next = xcalloc(1+n, sizeof(int)); - /* initialize LU-factorization data structures */ - initialize(lux, col, info, wka); - /* allocate working arrays */ - flag = xcalloc(1+n, sizeof(int)); - work = xcalloc(1+n, sizeof(mpq_t)); - for (k = 1; k <= n; k++) - { flag[k] = 0; - mpq_init(work[k]); - } - /* main elimination loop */ - for (k = 1; k <= n; k++) - { /* choose a pivot element v[p,q] */ - piv = find_pivot(lux, wka); - if (piv == NULL) - { /* no pivot can be chosen, because the active submatrix is - empty */ - break; - } - /* determine row and column indices of the pivot element */ - p = piv->i, q = piv->j; - /* let v[p,q] correspond to u[i',j']; permute k-th and i'-th - rows and k-th and j'-th columns of the matrix U = P*V*Q to - move the element u[i',j'] to the position u[k,k] */ - i = P_col[p], j = Q_row[q]; - xassert(k <= i && i <= n && k <= j && j <= n); - /* permute k-th and i-th rows of the matrix U */ - t = P_row[k]; - P_row[i] = t, P_col[t] = i; - P_row[k] = p, P_col[p] = k; - /* permute k-th and j-th columns of the matrix U */ - t = Q_col[k]; - Q_col[j] = t, Q_row[t] = j; - Q_col[k] = q, Q_row[q] = k; - /* eliminate subdiagonal elements of k-th column of the matrix - U = P*V*Q using the pivot element u[k,k] = v[p,q] */ - eliminate(lux, wka, piv, flag, work); - } - /* determine the rank of A (and V) */ - lux->rank = k - 1; - /* free working arrays */ - xfree(flag); - for (k = 1; k <= n; k++) mpq_clear(work[k]); - xfree(work); - /* build column lists of the matrix V using its row lists */ - for (j = 1; j <= n; j++) - xassert(V_col[j] == NULL); - for (i = 1; i <= n; i++) - { for (vij = V_row[i]; vij != NULL; vij = vij->r_next) - { j = vij->j; - vij->c_prev = NULL; - vij->c_next = V_col[j]; - if (vij->c_next != NULL) vij->c_next->c_prev = vij; - V_col[j] = vij; - } - } - /* free working area */ - xfree(wka->R_len); - xfree(wka->R_head); - xfree(wka->R_prev); - xfree(wka->R_next); - xfree(wka->C_len); - xfree(wka->C_head); - xfree(wka->C_prev); - xfree(wka->C_next); - xfree(wka); - /* return to the calling program */ - return (lux->rank < n); -} - -/*********************************************************************** -* lux_f_solve - solve system F*x = b or F'*x = b -* -* SYNOPSIS -* -* #include "lux.h" -* void lux_f_solve(LUX *lux, int tr, mpq_t x[]); -* -* DESCRIPTION -* -* The routine lux_f_solve solves either the system F*x = b (if the -* flag tr is zero) or the system F'*x = b (if the flag tr is non-zero), -* where the matrix F is a component of LU-factorization specified by -* the parameter lux, F' is a matrix transposed to F. -* -* On entry the array x should contain elements of the right-hand side -* vector b in locations x[1], ..., x[n], where n is the order of the -* matrix F. On exit this array will contain elements of the solution -* vector x in the same locations. */ - -void lux_f_solve(LUX *lux, int tr, mpq_t x[]) -{ int n = lux->n; - LUXELM **F_row = lux->F_row; - LUXELM **F_col = lux->F_col; - int *P_row = lux->P_row; - LUXELM *fik, *fkj; - int i, j, k; - mpq_t temp; - mpq_init(temp); - if (!tr) - { /* solve the system F*x = b */ - for (j = 1; j <= n; j++) - { k = P_row[j]; - if (mpq_sgn(x[k]) != 0) - { for (fik = F_col[k]; fik != NULL; fik = fik->c_next) - { mpq_mul(temp, fik->val, x[k]); - mpq_sub(x[fik->i], x[fik->i], temp); - } - } - } - } - else - { /* solve the system F'*x = b */ - for (i = n; i >= 1; i--) - { k = P_row[i]; - if (mpq_sgn(x[k]) != 0) - { for (fkj = F_row[k]; fkj != NULL; fkj = fkj->r_next) - { mpq_mul(temp, fkj->val, x[k]); - mpq_sub(x[fkj->j], x[fkj->j], temp); - } - } - } - } - mpq_clear(temp); - return; -} - -/*********************************************************************** -* lux_v_solve - solve system V*x = b or V'*x = b -* -* SYNOPSIS -* -* #include "lux.h" -* void lux_v_solve(LUX *lux, int tr, double x[]); -* -* DESCRIPTION -* -* The routine lux_v_solve solves either the system V*x = b (if the -* flag tr is zero) or the system V'*x = b (if the flag tr is non-zero), -* where the matrix V is a component of LU-factorization specified by -* the parameter lux, V' is a matrix transposed to V. -* -* On entry the array x should contain elements of the right-hand side -* vector b in locations x[1], ..., x[n], where n is the order of the -* matrix V. On exit this array will contain elements of the solution -* vector x in the same locations. */ - -void lux_v_solve(LUX *lux, int tr, mpq_t x[]) -{ int n = lux->n; - mpq_t *V_piv = lux->V_piv; - LUXELM **V_row = lux->V_row; - LUXELM **V_col = lux->V_col; - int *P_row = lux->P_row; - int *Q_col = lux->Q_col; - LUXELM *vij; - int i, j, k; - mpq_t *b, temp; - b = xcalloc(1+n, sizeof(mpq_t)); - for (k = 1; k <= n; k++) - mpq_init(b[k]), mpq_set(b[k], x[k]), mpq_set_si(x[k], 0, 1); - mpq_init(temp); - if (!tr) - { /* solve the system V*x = b */ - for (k = n; k >= 1; k--) - { i = P_row[k], j = Q_col[k]; - if (mpq_sgn(b[i]) != 0) - { mpq_set(x[j], b[i]); - mpq_div(x[j], x[j], V_piv[i]); - for (vij = V_col[j]; vij != NULL; vij = vij->c_next) - { mpq_mul(temp, vij->val, x[j]); - mpq_sub(b[vij->i], b[vij->i], temp); - } - } - } - } - else - { /* solve the system V'*x = b */ - for (k = 1; k <= n; k++) - { i = P_row[k], j = Q_col[k]; - if (mpq_sgn(b[j]) != 0) - { mpq_set(x[i], b[j]); - mpq_div(x[i], x[i], V_piv[i]); - for (vij = V_row[i]; vij != NULL; vij = vij->r_next) - { mpq_mul(temp, vij->val, x[i]); - mpq_sub(b[vij->j], b[vij->j], temp); - } - } - } - } - for (k = 1; k <= n; k++) mpq_clear(b[k]); - mpq_clear(temp); - xfree(b); - return; -} - -/*********************************************************************** -* lux_solve - solve system A*x = b or A'*x = b -* -* SYNOPSIS -* -* #include "lux.h" -* void lux_solve(LUX *lux, int tr, mpq_t x[]); -* -* DESCRIPTION -* -* The routine lux_solve solves either the system A*x = b (if the flag -* tr is zero) or the system A'*x = b (if the flag tr is non-zero), -* where the parameter lux specifies LU-factorization of the matrix A, -* A' is a matrix transposed to A. -* -* On entry the array x should contain elements of the right-hand side -* vector b in locations x[1], ..., x[n], where n is the order of the -* matrix A. On exit this array will contain elements of the solution -* vector x in the same locations. */ - -void lux_solve(LUX *lux, int tr, mpq_t x[]) -{ if (lux->rank < lux->n) - xfault("lux_solve: LU-factorization has incomplete rank\n"); - if (!tr) - { /* A = F*V, therefore inv(A) = inv(V)*inv(F) */ - lux_f_solve(lux, 0, x); - lux_v_solve(lux, 0, x); - } - else - { /* A' = V'*F', therefore inv(A') = inv(F')*inv(V') */ - lux_v_solve(lux, 1, x); - lux_f_solve(lux, 1, x); - } - return; -} - -/*********************************************************************** -* lux_delete - delete LU-factorization -* -* SYNOPSIS -* -* #include "lux.h" -* void lux_delete(LUX *lux); -* -* DESCRIPTION -* -* The routine lux_delete deletes LU-factorization data structure, -* which the parameter lux points to, freeing all the memory allocated -* to this object. */ - -void lux_delete(LUX *lux) -{ int n = lux->n; - LUXELM *fij, *vij; - int i; - for (i = 1; i <= n; i++) - { for (fij = lux->F_row[i]; fij != NULL; fij = fij->r_next) - mpq_clear(fij->val); - mpq_clear(lux->V_piv[i]); - for (vij = lux->V_row[i]; vij != NULL; vij = vij->r_next) - mpq_clear(vij->val); - } - dmp_delete_pool(lux->pool); - xfree(lux->F_row); - xfree(lux->F_col); - xfree(lux->V_piv); - xfree(lux->V_row); - xfree(lux->V_col); - xfree(lux->P_row); - xfree(lux->P_col); - xfree(lux->Q_row); - xfree(lux->Q_col); - xfree(lux); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/lux.h b/resources/3rdparty/glpk-4.53/src/lux.h deleted file mode 100644 index 6efce3636..000000000 --- a/resources/3rdparty/glpk-4.53/src/lux.h +++ /dev/null @@ -1,220 +0,0 @@ -/* lux.h (LU-factorization, rational arithmetic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef LUX_H -#define LUX_H - -#include "dmp.h" -#include "glpgmp.h" - -/*********************************************************************** -* The structure LUX defines LU-factorization of a square matrix A, -* which is the following quartet: -* -* [A] = (F, V, P, Q), (1) -* -* where F and V are such matrices that -* -* A = F * V, (2) -* -* and P and Q are such permutation matrices that the matrix -* -* L = P * F * inv(P) (3) -* -* is lower triangular with unity diagonal, and the matrix -* -* U = P * V * Q (4) -* -* is upper triangular. All the matrices have the order n. -* -* The matrices F and V are stored in row/column-wise sparse format as -* row and column linked lists of non-zero elements. Unity elements on -* the main diagonal of the matrix F are not stored. Pivot elements of -* the matrix V (that correspond to diagonal elements of the matrix U) -* are also missing from the row and column lists and stored separately -* in an ordinary array. -* -* The permutation matrices P and Q are stored as ordinary arrays using -* both row- and column-like formats. -* -* The matrices L and U being completely defined by the matrices F, V, -* P, and Q are not stored explicitly. -* -* It is easy to show that the factorization (1)-(3) is some version of -* LU-factorization. Indeed, from (3) and (4) it follows that: -* -* F = inv(P) * L * P, -* -* V = inv(P) * U * inv(Q), -* -* and substitution into (2) gives: -* -* A = F * V = inv(P) * L * U * inv(Q). -* -* For more details see the program documentation. */ - -typedef struct LUX LUX; -typedef struct LUXELM LUXELM; -typedef struct LUXWKA LUXWKA; - -struct LUX -{ /* LU-factorization of a square matrix */ - int n; - /* the order of matrices A, F, V, P, Q */ - DMP *pool; - /* memory pool for elements of matrices F and V */ - LUXELM **F_row; /* LUXELM *F_row[1+n]; */ - /* F_row[0] is not used; - F_row[i], 1 <= i <= n, is a pointer to the list of elements in - i-th row of matrix F (diagonal elements are not stored) */ - LUXELM **F_col; /* LUXELM *F_col[1+n]; */ - /* F_col[0] is not used; - F_col[j], 1 <= j <= n, is a pointer to the list of elements in - j-th column of matrix F (diagonal elements are not stored) */ - mpq_t *V_piv; /* mpq_t V_piv[1+n]; */ - /* V_piv[0] is not used; - V_piv[p], 1 <= p <= n, is a pivot element v[p,q] corresponding - to a diagonal element u[k,k] of matrix U = P*V*Q (used on k-th - elimination step, k = 1, 2, ..., n) */ - LUXELM **V_row; /* LUXELM *V_row[1+n]; */ - /* V_row[0] is not used; - V_row[i], 1 <= i <= n, is a pointer to the list of elements in - i-th row of matrix V (except pivot elements) */ - LUXELM **V_col; /* LUXELM *V_col[1+n]; */ - /* V_col[0] is not used; - V_col[j], 1 <= j <= n, is a pointer to the list of elements in - j-th column of matrix V (except pivot elements) */ - int *P_row; /* int P_row[1+n]; */ - /* P_row[0] is not used; - P_row[i] = j means that p[i,j] = 1, where p[i,j] is an element - of permutation matrix P */ - int *P_col; /* int P_col[1+n]; */ - /* P_col[0] is not used; - P_col[j] = i means that p[i,j] = 1, where p[i,j] is an element - of permutation matrix P */ - /* if i-th row or column of matrix F is i'-th row or column of - matrix L = P*F*inv(P), or if i-th row of matrix V is i'-th row - of matrix U = P*V*Q, then P_row[i'] = i and P_col[i] = i' */ - int *Q_row; /* int Q_row[1+n]; */ - /* Q_row[0] is not used; - Q_row[i] = j means that q[i,j] = 1, where q[i,j] is an element - of permutation matrix Q */ - int *Q_col; /* int Q_col[1+n]; */ - /* Q_col[0] is not used; - Q_col[j] = i means that q[i,j] = 1, where q[i,j] is an element - of permutation matrix Q */ - /* if j-th column of matrix V is j'-th column of matrix U = P*V*Q, - then Q_row[j] = j' and Q_col[j'] = j */ - int rank; - /* the (exact) rank of matrices A and V */ -}; - -struct LUXELM -{ /* element of matrix F or V */ - int i; - /* row index, 1 <= i <= m */ - int j; - /* column index, 1 <= j <= n */ - mpq_t val; - /* numeric (non-zero) element value */ - LUXELM *r_prev; - /* pointer to previous element in the same row */ - LUXELM *r_next; - /* pointer to next element in the same row */ - LUXELM *c_prev; - /* pointer to previous element in the same column */ - LUXELM *c_next; - /* pointer to next element in the same column */ -}; - -struct LUXWKA -{ /* working area (used only during factorization) */ - /* in order to efficiently implement Markowitz strategy and Duff - search technique there are two families {R[0], R[1], ..., R[n]} - and {C[0], C[1], ..., C[n]}; member R[k] is a set of active - rows of matrix V having k non-zeros, and member C[k] is a set - of active columns of matrix V having k non-zeros (in the active - submatrix); each set R[k] and C[k] is implemented as a separate - doubly linked list */ - int *R_len; /* int R_len[1+n]; */ - /* R_len[0] is not used; - R_len[i], 1 <= i <= n, is the number of non-zero elements in - i-th row of matrix V (that is the length of i-th row) */ - int *R_head; /* int R_head[1+n]; */ - /* R_head[k], 0 <= k <= n, is the number of a first row, which is - active and whose length is k */ - int *R_prev; /* int R_prev[1+n]; */ - /* R_prev[0] is not used; - R_prev[i], 1 <= i <= n, is the number of a previous row, which - is active and has the same length as i-th row */ - int *R_next; /* int R_next[1+n]; */ - /* R_prev[0] is not used; - R_prev[i], 1 <= i <= n, is the number of a next row, which is - active and has the same length as i-th row */ - int *C_len; /* int C_len[1+n]; */ - /* C_len[0] is not used; - C_len[j], 1 <= j <= n, is the number of non-zero elements in - j-th column of the active submatrix of matrix V (that is the - length of j-th column in the active submatrix) */ - int *C_head; /* int C_head[1+n]; */ - /* C_head[k], 0 <= k <= n, is the number of a first column, which - is active and whose length is k */ - int *C_prev; /* int C_prev[1+n]; */ - /* C_prev[0] is not used; - C_prev[j], 1 <= j <= n, is the number of a previous column, - which is active and has the same length as j-th column */ - int *C_next; /* int C_next[1+n]; */ - /* C_next[0] is not used; - C_next[j], 1 <= j <= n, is the number of a next column, which - is active and has the same length as j-th column */ -}; - -#define lux_create _glp_lux_create -LUX *lux_create(int n); -/* create LU-factorization */ - -#define lux_decomp _glp_lux_decomp -int lux_decomp(LUX *lux, int (*col)(void *info, int j, int ind[], - mpq_t val[]), void *info); -/* compute LU-factorization */ - -#define lux_f_solve _glp_lux_f_solve -void lux_f_solve(LUX *lux, int tr, mpq_t x[]); -/* solve system F*x = b or F'*x = b */ - -#define lux_v_solve _glp_lux_v_solve -void lux_v_solve(LUX *lux, int tr, mpq_t x[]); -/* solve system V*x = b or V'*x = b */ - -#define lux_solve _glp_lux_solve -void lux_solve(LUX *lux, int tr, mpq_t x[]); -/* solve system A*x = b or A'*x = b */ - -#define lux_delete _glp_lux_delete -void lux_delete(LUX *lux); -/* delete LU-factorization */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/minisat/LICENSE b/resources/3rdparty/glpk-4.53/src/minisat/LICENSE deleted file mode 100644 index 8a6b9f362..000000000 --- a/resources/3rdparty/glpk-4.53/src/minisat/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -MiniSat -- Copyright (c) 2005, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/resources/3rdparty/glpk-4.53/src/minisat/README b/resources/3rdparty/glpk-4.53/src/minisat/README deleted file mode 100644 index c183c7d61..000000000 --- a/resources/3rdparty/glpk-4.53/src/minisat/README +++ /dev/null @@ -1,22 +0,0 @@ -NOTE: Files in this subdirectory are NOT part of the GLPK package, but - are used with GLPK. - - The original code was modified according to GLPK requirements by - Andrew Makhorin . -************************************************************************ -MiniSat-C v1.14.1 -======================================== - -* Fixed some serious bugs. -* Tweaked to be Visual Studio friendly (by Alan Mishchenko). - This disabled reading of gzipped DIMACS files and signal handling, - but none of these features are essential (and easy to re-enable, if - wanted). - -MiniSat-C v1.14 -======================================== - -Ok, we get it. You hate C++. You hate templates. We agree; C++ is a -seriously messed up language. Although we are more pragmatic about the -quirks and maldesigns in C++, we sympathize with you. So here is a -pure C version of MiniSat, put together by Niklas Sorensson. diff --git a/resources/3rdparty/glpk-4.53/src/minisat/minisat.c b/resources/3rdparty/glpk-4.53/src/minisat/minisat.c deleted file mode 100644 index f242d838a..000000000 --- a/resources/3rdparty/glpk-4.53/src/minisat/minisat.c +++ /dev/null @@ -1,1299 +0,0 @@ -/* minisat.c */ - -/* Modified by Andrew Makhorin , August 2011 */ - -/*********************************************************************** -* MiniSat -- Copyright (c) 2005, Niklas Sorensson -* http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat/ -* -* Permission is hereby granted, free of charge, to any person -* obtaining a copy of this software and associated documentation files -* (the "Software"), to deal in the Software without restriction, -* including without limitation the rights to use, copy, modify, merge, -* publish, distribute, sublicense, and/or sell copies of the Software, -* and to permit persons to whom the Software is furnished to do so, -* subject to the following conditions: -* -* The above copyright notice and this permission notice shall be -* included in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -***********************************************************************/ -/* Modified to compile with MS Visual Studio 6.0 by Alan Mishchenko */ - -#include "env.h" -#include "minisat.h" - -#if 1 /* by mao */ -static void *ymalloc(int size) -{ void *ptr; - xassert(size > 0); - ptr = malloc(size); - if (ptr == NULL) - xerror("MiniSat: no memory available\n"); - return ptr; -} - -static void *yrealloc(void *ptr, int size) -{ xassert(size > 0); - if (ptr == NULL) - ptr = malloc(size); - else - ptr = realloc(ptr, size); - if (ptr == NULL) - xerror("MiniSat: no memory available\n"); - return ptr; -} - -static void yfree(void *ptr) -{ xassert(ptr != NULL); - free(ptr); - return; -} - -#define assert xassert -#define printf xprintf -#define fflush(f) /* nop */ -#define malloc ymalloc -#define realloc yrealloc -#define free yfree -#define inline /* empty */ -#endif - -/*====================================================================*/ -/* Debug: */ - -#if 0 -#define VERBOSEDEBUG 1 -#endif - -/* For derivation output (verbosity level 2) */ -#define L_IND "%-*d" -#define L_ind solver_dlevel(s)*3+3,solver_dlevel(s) -#define L_LIT "%sx%d" -#define L_lit(p) lit_sign(p)?"~":"", (lit_var(p)) - -#if 0 /* by mao */ -/* Just like 'assert()' but expression will be evaluated in the release - version as well. */ -static inline void check(int expr) { assert(expr); } -#endif - -#if 0 /* by mao */ -static void printlits(lit* begin, lit* end) -{ - int i; - for (i = 0; i < end - begin; i++) - printf(L_LIT" ",L_lit(begin[i])); -} -#endif - -/*====================================================================*/ -/* Random numbers: */ - -/* Returns a random float 0 <= x < 1. Seed must never be 0. */ -static inline double drand(double* seed) { - int q; - *seed *= 1389796; - q = (int)(*seed / 2147483647); - *seed -= (double)q * 2147483647; - return *seed / 2147483647; } - -/* Returns a random integer 0 <= x < size. Seed must never be 0. */ -static inline int irand(double* seed, int size) { - return (int)(drand(seed) * size); } - -/*====================================================================*/ -/* Predeclarations: */ - -static void sort(void** array, int size, - int(*comp)(const void *, const void *)); - -/*====================================================================*/ -/* Clause datatype + minor functions: */ - -#if 0 /* by mao; see minisat.h */ -struct clause_t -{ - int size_learnt; - lit lits[0]; -}; -#endif - -#define clause_size(c) ((c)->size_learnt >> 1) - -#define clause_begin(c) ((c)->lits) - -#define clause_learnt(c) ((c)->size_learnt & 1) - -#define clause_activity(c) \ - (*((float*)&(c)->lits[(c)->size_learnt>>1])) - -#define clause_setactivity(c, a) \ - (void)(*((float*)&(c)->lits[(c)->size_learnt>>1]) = (a)) - -/*====================================================================*/ -/* Encode literals in clause pointers: */ - -#define clause_from_lit(l) \ - (clause*)((unsigned long)(l) + (unsigned long)(l) + 1) - -#define clause_is_lit(c) \ - ((unsigned long)(c) & 1) - -#define clause_read_lit(c) \ - (lit)((unsigned long)(c) >> 1) - -/*====================================================================*/ -/* Simple helpers: */ - -#define solver_dlevel(s) \ - (int)veci_size(&(s)->trail_lim) - -#define solver_read_wlist(s, l) \ - (vecp *)(&(s)->wlists[l]) - -static inline void vecp_remove(vecp* v, void* e) -{ - void** ws = vecp_begin(v); - int j = 0; - - for (; ws[j] != e ; j++); - assert(j < vecp_size(v)); - for (; j < vecp_size(v)-1; j++) ws[j] = ws[j+1]; - vecp_resize(v,vecp_size(v)-1); -} - -/*====================================================================*/ -/* Variable order functions: */ - -static inline void order_update(solver* s, int v) -{ /* updateorder */ - int* orderpos = s->orderpos; - double* activity = s->activity; - int* heap = veci_begin(&s->order); - int i = orderpos[v]; - int x = heap[i]; - int parent = (i - 1) / 2; - - assert(s->orderpos[v] != -1); - - while (i != 0 && activity[x] > activity[heap[parent]]){ - heap[i] = heap[parent]; - orderpos[heap[i]] = i; - i = parent; - parent = (i - 1) / 2; - } - heap[i] = x; - orderpos[x] = i; -} - -#define order_assigned(s, v) /* nop */ - -static inline void order_unassigned(solver* s, int v) -{ /* undoorder */ - int* orderpos = s->orderpos; - if (orderpos[v] == -1){ - orderpos[v] = veci_size(&s->order); - veci_push(&s->order,v); - order_update(s,v); - } -} - -static int order_select(solver* s, float random_var_freq) -{ /* selectvar */ - int* heap; - double* activity; - int* orderpos; - - lbool* values = s->assigns; - - /* Random decision: */ - if (drand(&s->random_seed) < random_var_freq){ - int next = irand(&s->random_seed,s->size); - assert(next >= 0 && next < s->size); - if (values[next] == l_Undef) - return next; - } - - /* Activity based decision: */ - - heap = veci_begin(&s->order); - activity = s->activity; - orderpos = s->orderpos; - - while (veci_size(&s->order) > 0){ - int next = heap[0]; - int size = veci_size(&s->order)-1; - int x = heap[size]; - - veci_resize(&s->order,size); - - orderpos[next] = -1; - - if (size > 0){ - double act = activity[x]; - - int i = 0; - int child = 1; - - while (child < size){ - if (child+1 < size - && activity[heap[child]] < activity[heap[child+1]]) - child++; - - assert(child < size); - - if (act >= activity[heap[child]]) - break; - - heap[i] = heap[child]; - orderpos[heap[i]] = i; - i = child; - child = 2 * child + 1; - } - heap[i] = x; - orderpos[heap[i]] = i; - } - - if (values[next] == l_Undef) - return next; - } - - return var_Undef; -} - -/*====================================================================*/ -/* Activity functions: */ - -static inline void act_var_rescale(solver* s) { - double* activity = s->activity; - int i; - for (i = 0; i < s->size; i++) - activity[i] *= 1e-100; - s->var_inc *= 1e-100; -} - -static inline void act_var_bump(solver* s, int v) { - double* activity = s->activity; - if ((activity[v] += s->var_inc) > 1e100) - act_var_rescale(s); - - /* printf("bump %d %f\n", v-1, activity[v]); */ - - if (s->orderpos[v] != -1) - order_update(s,v); - -} - -static inline void act_var_decay(solver* s) - { s->var_inc *= s->var_decay; } - -static inline void act_clause_rescale(solver* s) { - clause** cs = (clause**)vecp_begin(&s->learnts); - int i; - for (i = 0; i < vecp_size(&s->learnts); i++){ - float a = clause_activity(cs[i]); - clause_setactivity(cs[i], a * (float)1e-20); - } - s->cla_inc *= (float)1e-20; -} - -static inline void act_clause_bump(solver* s, clause *c) { - float a = clause_activity(c) + s->cla_inc; - clause_setactivity(c,a); - if (a > 1e20) act_clause_rescale(s); -} - -static inline void act_clause_decay(solver* s) - { s->cla_inc *= s->cla_decay; } - -/*====================================================================*/ -/* Clause functions: */ - -/* pre: size > 1 && no variable occurs twice - */ -static clause* clause_new(solver* s, lit* begin, lit* end, int learnt) -{ - int size; - clause* c; - int i; - - assert(end - begin > 1); - assert(learnt >= 0 && learnt < 2); - size = end - begin; - c = (clause*)malloc(sizeof(clause) - + sizeof(lit) * size + learnt * sizeof(float)); - c->size_learnt = (size << 1) | learnt; -#if 0 /* by mao; meaningless non-portable check */ - assert(((unsigned int)c & 1) == 0); -#endif - - for (i = 0; i < size; i++) - c->lits[i] = begin[i]; - - if (learnt) - *((float*)&c->lits[size]) = 0.0; - - assert(begin[0] >= 0); - assert(begin[0] < s->size*2); - assert(begin[1] >= 0); - assert(begin[1] < s->size*2); - - assert(lit_neg(begin[0]) < s->size*2); - assert(lit_neg(begin[1]) < s->size*2); - - /* vecp_push(solver_read_wlist(s,lit_neg(begin[0])),(void*)c); */ - /* vecp_push(solver_read_wlist(s,lit_neg(begin[1])),(void*)c); */ - - vecp_push(solver_read_wlist(s,lit_neg(begin[0])), - (void*)(size > 2 ? c : clause_from_lit(begin[1]))); - vecp_push(solver_read_wlist(s,lit_neg(begin[1])), - (void*)(size > 2 ? c : clause_from_lit(begin[0]))); - - return c; -} - -static void clause_remove(solver* s, clause* c) -{ - lit* lits = clause_begin(c); - assert(lit_neg(lits[0]) < s->size*2); - assert(lit_neg(lits[1]) < s->size*2); - - /* vecp_remove(solver_read_wlist(s,lit_neg(lits[0])),(void*)c); */ - /* vecp_remove(solver_read_wlist(s,lit_neg(lits[1])),(void*)c); */ - - assert(lits[0] < s->size*2); - vecp_remove(solver_read_wlist(s,lit_neg(lits[0])), - (void*)(clause_size(c) > 2 ? c : clause_from_lit(lits[1]))); - vecp_remove(solver_read_wlist(s,lit_neg(lits[1])), - (void*)(clause_size(c) > 2 ? c : clause_from_lit(lits[0]))); - - if (clause_learnt(c)){ - s->stats.learnts--; - s->stats.learnts_literals -= clause_size(c); - }else{ - s->stats.clauses--; - s->stats.clauses_literals -= clause_size(c); - } - - free(c); -} - -static lbool clause_simplify(solver* s, clause* c) -{ - lit* lits = clause_begin(c); - lbool* values = s->assigns; - int i; - - assert(solver_dlevel(s) == 0); - - for (i = 0; i < clause_size(c); i++){ - lbool sig = !lit_sign(lits[i]); sig += sig - 1; - if (values[lit_var(lits[i])] == sig) - return l_True; - } - return l_False; -} - -/*====================================================================*/ -/* Minor (solver) functions: */ - -void solver_setnvars(solver* s,int n) -{ - int var; - - if (s->cap < n){ - - while (s->cap < n) s->cap = s->cap*2+1; - - s->wlists = (vecp*) realloc(s->wlists, - sizeof(vecp)*s->cap*2); - s->activity = (double*) realloc(s->activity, - sizeof(double)*s->cap); - s->assigns = (lbool*) realloc(s->assigns, - sizeof(lbool)*s->cap); - s->orderpos = (int*) realloc(s->orderpos, - sizeof(int)*s->cap); - s->reasons = (clause**)realloc(s->reasons, - sizeof(clause*)*s->cap); - s->levels = (int*) realloc(s->levels, - sizeof(int)*s->cap); - s->tags = (lbool*) realloc(s->tags, - sizeof(lbool)*s->cap); - s->trail = (lit*) realloc(s->trail, - sizeof(lit)*s->cap); - } - - for (var = s->size; var < n; var++){ - vecp_new(&s->wlists[2*var]); - vecp_new(&s->wlists[2*var+1]); - s->activity [var] = 0; - s->assigns [var] = l_Undef; - s->orderpos [var] = veci_size(&s->order); - s->reasons [var] = (clause*)0; - s->levels [var] = 0; - s->tags [var] = l_Undef; - - /* does not hold because variables enqueued at top level will - not be reinserted in the heap - assert(veci_size(&s->order) == var); - */ - veci_push(&s->order,var); - order_update(s, var); - } - - s->size = n > s->size ? n : s->size; -} - -static inline bool enqueue(solver* s, lit l, clause* from) -{ - lbool* values = s->assigns; - int v = lit_var(l); - lbool val = values[v]; - lbool sig; -#ifdef VERBOSEDEBUG - printf(L_IND"enqueue("L_LIT")\n", L_ind, L_lit(l)); -#endif - - /* lbool */ sig = !lit_sign(l); sig += sig - 1; - if (val != l_Undef){ - return val == sig; - }else{ - /* New fact -- store it. */ - int* levels; - clause** reasons; -#ifdef VERBOSEDEBUG - printf(L_IND"bind("L_LIT")\n", L_ind, L_lit(l)); -#endif - /* int* */ levels = s->levels; - /* clause** */ reasons = s->reasons; - - values [v] = sig; - levels [v] = solver_dlevel(s); - reasons[v] = from; - s->trail[s->qtail++] = l; - - order_assigned(s, v); - return true; - } -} - -static inline void assume(solver* s, lit l){ - assert(s->qtail == s->qhead); - assert(s->assigns[lit_var(l)] == l_Undef); -#ifdef VERBOSEDEBUG - printf(L_IND"assume("L_LIT")\n", L_ind, L_lit(l)); -#endif - veci_push(&s->trail_lim,s->qtail); - enqueue(s,l,(clause*)0); -} - -static inline void solver_canceluntil(solver* s, int level) { - lit* trail; - lbool* values; - clause** reasons; - int bound; - int c; - - if (solver_dlevel(s) <= level) - return; - - trail = s->trail; - values = s->assigns; - reasons = s->reasons; - bound = (veci_begin(&s->trail_lim))[level]; - - for (c = s->qtail-1; c >= bound; c--) { - int x = lit_var(trail[c]); - values [x] = l_Undef; - reasons[x] = (clause*)0; - } - - for (c = s->qhead-1; c >= bound; c--) - order_unassigned(s,lit_var(trail[c])); - - s->qhead = s->qtail = bound; - veci_resize(&s->trail_lim,level); -} - -static void solver_record(solver* s, veci* cls) -{ - lit* begin = veci_begin(cls); - lit* end = begin + veci_size(cls); - clause* c = (veci_size(cls) > 1) ? clause_new(s,begin,end,1) - : (clause*)0; - enqueue(s,*begin,c); - - assert(veci_size(cls) > 0); - - if (c != 0) { - vecp_push(&s->learnts,c); - act_clause_bump(s,c); - s->stats.learnts++; - s->stats.learnts_literals += veci_size(cls); - } -} - -static double solver_progress(solver* s) -{ - lbool* values = s->assigns; - int* levels = s->levels; - int i; - - double progress = 0; - double F = 1.0 / s->size; - for (i = 0; i < s->size; i++) - if (values[i] != l_Undef) - progress += pow(F, levels[i]); - return progress / s->size; -} - -/*====================================================================*/ -/* Major methods: */ - -static bool solver_lit_removable(solver* s, lit l, int minl) -{ - lbool* tags = s->tags; - clause** reasons = s->reasons; - int* levels = s->levels; - int top = veci_size(&s->tagged); - - assert(lit_var(l) >= 0 && lit_var(l) < s->size); - assert(reasons[lit_var(l)] != 0); - veci_resize(&s->stack,0); - veci_push(&s->stack,lit_var(l)); - - while (veci_size(&s->stack) > 0){ - clause* c; - int v = veci_begin(&s->stack)[veci_size(&s->stack)-1]; - assert(v >= 0 && v < s->size); - veci_resize(&s->stack,veci_size(&s->stack)-1); - assert(reasons[v] != 0); - c = reasons[v]; - - if (clause_is_lit(c)){ - int v = lit_var(clause_read_lit(c)); - if (tags[v] == l_Undef && levels[v] != 0){ - if (reasons[v] != 0 - && ((1 << (levels[v] & 31)) & minl)){ - veci_push(&s->stack,v); - tags[v] = l_True; - veci_push(&s->tagged,v); - }else{ - int* tagged = veci_begin(&s->tagged); - int j; - for (j = top; j < veci_size(&s->tagged); j++) - tags[tagged[j]] = l_Undef; - veci_resize(&s->tagged,top); - return false; - } - } - }else{ - lit* lits = clause_begin(c); - int i, j; - - for (i = 1; i < clause_size(c); i++){ - int v = lit_var(lits[i]); - if (tags[v] == l_Undef && levels[v] != 0){ - if (reasons[v] != 0 - && ((1 << (levels[v] & 31)) & minl)){ - - veci_push(&s->stack,lit_var(lits[i])); - tags[v] = l_True; - veci_push(&s->tagged,v); - }else{ - int* tagged = veci_begin(&s->tagged); - for (j = top; j < veci_size(&s->tagged); j++) - tags[tagged[j]] = l_Undef; - veci_resize(&s->tagged,top); - return false; - } - } - } - } - } - - return true; -} - -static void solver_analyze(solver* s, clause* c, veci* learnt) -{ - lit* trail = s->trail; - lbool* tags = s->tags; - clause** reasons = s->reasons; - int* levels = s->levels; - int cnt = 0; - lit p = lit_Undef; - int ind = s->qtail-1; - lit* lits; - int i, j, minl; - int* tagged; - - veci_push(learnt,lit_Undef); - - do{ - assert(c != 0); - - if (clause_is_lit(c)){ - lit q = clause_read_lit(c); - assert(lit_var(q) >= 0 && lit_var(q) < s->size); - if (tags[lit_var(q)] == l_Undef && levels[lit_var(q)] > 0){ - tags[lit_var(q)] = l_True; - veci_push(&s->tagged,lit_var(q)); - act_var_bump(s,lit_var(q)); - if (levels[lit_var(q)] == solver_dlevel(s)) - cnt++; - else - veci_push(learnt,q); - } - }else{ - - if (clause_learnt(c)) - act_clause_bump(s,c); - - lits = clause_begin(c); - /* printlits(lits,lits+clause_size(c)); printf("\n"); */ - for (j = (p == lit_Undef ? 0 : 1); j < clause_size(c); j++){ - lit q = lits[j]; - assert(lit_var(q) >= 0 && lit_var(q) < s->size); - if (tags[lit_var(q)] == l_Undef - && levels[lit_var(q)] > 0){ - tags[lit_var(q)] = l_True; - veci_push(&s->tagged,lit_var(q)); - act_var_bump(s,lit_var(q)); - if (levels[lit_var(q)] == solver_dlevel(s)) - cnt++; - else - veci_push(learnt,q); - } - } - } - - while (tags[lit_var(trail[ind--])] == l_Undef); - - p = trail[ind+1]; - c = reasons[lit_var(p)]; - cnt--; - - }while (cnt > 0); - - *veci_begin(learnt) = lit_neg(p); - - lits = veci_begin(learnt); - minl = 0; - for (i = 1; i < veci_size(learnt); i++){ - int lev = levels[lit_var(lits[i])]; - minl |= 1 << (lev & 31); - } - - /* simplify (full) */ - for (i = j = 1; i < veci_size(learnt); i++){ - if (reasons[lit_var(lits[i])] == 0 - || !solver_lit_removable(s,lits[i],minl)) - lits[j++] = lits[i]; - } - - /* update size of learnt + statistics */ - s->stats.max_literals += veci_size(learnt); - veci_resize(learnt,j); - s->stats.tot_literals += j; - - /* clear tags */ - tagged = veci_begin(&s->tagged); - for (i = 0; i < veci_size(&s->tagged); i++) - tags[tagged[i]] = l_Undef; - veci_resize(&s->tagged,0); - -#ifdef DEBUG - for (i = 0; i < s->size; i++) - assert(tags[i] == l_Undef); -#endif - -#ifdef VERBOSEDEBUG - printf(L_IND"Learnt {", L_ind); - for (i = 0; i < veci_size(learnt); i++) - printf(" "L_LIT, L_lit(lits[i])); -#endif - if (veci_size(learnt) > 1){ - int max_i = 1; - int max = levels[lit_var(lits[1])]; - lit tmp; - - for (i = 2; i < veci_size(learnt); i++) - if (levels[lit_var(lits[i])] > max){ - max = levels[lit_var(lits[i])]; - max_i = i; - } - - tmp = lits[1]; - lits[1] = lits[max_i]; - lits[max_i] = tmp; - } -#ifdef VERBOSEDEBUG - { - int lev = veci_size(learnt) > 1 ? levels[lit_var(lits[1])] : 0; - printf(" } at level %d\n", lev); - } -#endif -} - -clause* solver_propagate(solver* s) -{ - lbool* values = s->assigns; - clause* confl = (clause*)0; - lit* lits; - - /* printf("solver_propagate\n"); */ - while (confl == 0 && s->qtail - s->qhead > 0){ - lit p = s->trail[s->qhead++]; - vecp* ws = solver_read_wlist(s,p); - clause **begin = (clause**)vecp_begin(ws); - clause **end = begin + vecp_size(ws); - clause **i, **j; - - s->stats.propagations++; - s->simpdb_props--; - - /* printf("checking lit %d: "L_LIT"\n", veci_size(ws), - L_lit(p)); */ - for (i = j = begin; i < end; ){ - if (clause_is_lit(*i)){ - *j++ = *i; - if (!enqueue(s,clause_read_lit(*i),clause_from_lit(p))){ - confl = s->binary; - (clause_begin(confl))[1] = lit_neg(p); - (clause_begin(confl))[0] = clause_read_lit(*i++); - - /* Copy the remaining watches: */ - while (i < end) - *j++ = *i++; - } - }else{ - lit false_lit; - lbool sig; - - lits = clause_begin(*i); - - /* Make sure the false literal is data[1]: */ - false_lit = lit_neg(p); - if (lits[0] == false_lit){ - lits[0] = lits[1]; - lits[1] = false_lit; - } - assert(lits[1] == false_lit); - /* printf("checking clause: "); - printlits(lits, lits+clause_size(*i)); - printf("\n"); */ - - /* If 0th watch is true, then clause is already - satisfied. */ - sig = !lit_sign(lits[0]); sig += sig - 1; - if (values[lit_var(lits[0])] == sig){ - *j++ = *i; - }else{ - /* Look for new watch: */ - lit* stop = lits + clause_size(*i); - lit* k; - for (k = lits + 2; k < stop; k++){ - lbool sig = lit_sign(*k); sig += sig - 1; - if (values[lit_var(*k)] != sig){ - lits[1] = *k; - *k = false_lit; - vecp_push(solver_read_wlist(s, - lit_neg(lits[1])),*i); - goto next; } - } - - *j++ = *i; - /* Clause is unit under assignment: */ - if (!enqueue(s,lits[0], *i)){ - confl = *i++; - /* Copy the remaining watches: */ - while (i < end) - *j++ = *i++; - } - } - } - next: - i++; - } - - s->stats.inspects += j - (clause**)vecp_begin(ws); - vecp_resize(ws,j - (clause**)vecp_begin(ws)); - } - - return confl; -} - -static inline int clause_cmp (const void* x, const void* y) { - return clause_size((clause*)x) > 2 - && (clause_size((clause*)y) == 2 - || clause_activity((clause*)x) - < clause_activity((clause*)y)) ? -1 : 1; } - -void solver_reducedb(solver* s) -{ - int i, j; - double extra_lim = s->cla_inc / vecp_size(&s->learnts); - /* Remove any clause below this activity */ - clause** learnts = (clause**)vecp_begin(&s->learnts); - clause** reasons = s->reasons; - - sort(vecp_begin(&s->learnts), vecp_size(&s->learnts), clause_cmp); - - for (i = j = 0; i < vecp_size(&s->learnts) / 2; i++){ - if (clause_size(learnts[i]) > 2 - && reasons[lit_var(*clause_begin(learnts[i]))] - != learnts[i]) - clause_remove(s,learnts[i]); - else - learnts[j++] = learnts[i]; - } - for (; i < vecp_size(&s->learnts); i++){ - if (clause_size(learnts[i]) > 2 - && reasons[lit_var(*clause_begin(learnts[i]))] - != learnts[i] - && clause_activity(learnts[i]) < extra_lim) - clause_remove(s,learnts[i]); - else - learnts[j++] = learnts[i]; - } - - /* printf("reducedb deleted %d\n", vecp_size(&s->learnts) - j); */ - - vecp_resize(&s->learnts,j); -} - -static lbool solver_search(solver* s, int nof_conflicts, - int nof_learnts) -{ - int* levels = s->levels; - double var_decay = 0.95; - double clause_decay = 0.999; - double random_var_freq = 0.02; - - int conflictC = 0; - veci learnt_clause; - - assert(s->root_level == solver_dlevel(s)); - - s->stats.starts++; - s->var_decay = (float)(1 / var_decay ); - s->cla_decay = (float)(1 / clause_decay); - veci_resize(&s->model,0); - veci_new(&learnt_clause); - - for (;;){ - clause* confl = solver_propagate(s); - if (confl != 0){ - /* CONFLICT */ - int blevel; - -#ifdef VERBOSEDEBUG - printf(L_IND"**CONFLICT**\n", L_ind); -#endif - s->stats.conflicts++; conflictC++; - if (solver_dlevel(s) == s->root_level){ - veci_delete(&learnt_clause); - return l_False; - } - - veci_resize(&learnt_clause,0); - solver_analyze(s, confl, &learnt_clause); - blevel = veci_size(&learnt_clause) > 1 - ? levels[lit_var(veci_begin(&learnt_clause)[1])] - : s->root_level; - blevel = s->root_level > blevel ? s->root_level : blevel; - solver_canceluntil(s,blevel); - solver_record(s,&learnt_clause); - act_var_decay(s); - act_clause_decay(s); - - }else{ - /* NO CONFLICT */ - int next; - - if (nof_conflicts >= 0 && conflictC >= nof_conflicts){ - /* Reached bound on number of conflicts: */ - s->progress_estimate = solver_progress(s); - solver_canceluntil(s,s->root_level); - veci_delete(&learnt_clause); - return l_Undef; } - - if (solver_dlevel(s) == 0) - /* Simplify the set of problem clauses: */ - solver_simplify(s); - - if (nof_learnts >= 0 - && vecp_size(&s->learnts) - s->qtail >= nof_learnts) - /* Reduce the set of learnt clauses: */ - solver_reducedb(s); - - /* New variable decision: */ - s->stats.decisions++; - next = order_select(s,(float)random_var_freq); - - if (next == var_Undef){ - /* Model found: */ - lbool* values = s->assigns; - int i; - for (i = 0; i < s->size; i++) - veci_push(&s->model,(int)values[i]); - solver_canceluntil(s,s->root_level); - veci_delete(&learnt_clause); - - /* - veci apa; veci_new(&apa); - for (i = 0; i < s->size; i++) - veci_push(&apa,(int)(s->model.ptr[i] == l_True - ? toLit(i) : lit_neg(toLit(i)))); - printf("model: "); - printlits((lit*)apa.ptr, - (lit*)apa.ptr + veci_size(&apa)); printf("\n"); - veci_delete(&apa); - */ - - return l_True; - } - - assume(s,lit_neg(toLit(next))); - } - } - -#if 0 /* by mao; unreachable code */ - return l_Undef; /* cannot happen */ -#endif -} - -/*====================================================================*/ -/* External solver functions: */ - -solver* solver_new(void) -{ - solver* s = (solver*)malloc(sizeof(solver)); - - /* initialize vectors */ - vecp_new(&s->clauses); - vecp_new(&s->learnts); - veci_new(&s->order); - veci_new(&s->trail_lim); - veci_new(&s->tagged); - veci_new(&s->stack); - veci_new(&s->model); - - /* initialize arrays */ - s->wlists = 0; - s->activity = 0; - s->assigns = 0; - s->orderpos = 0; - s->reasons = 0; - s->levels = 0; - s->tags = 0; - s->trail = 0; - - /* initialize other vars */ - s->size = 0; - s->cap = 0; - s->qhead = 0; - s->qtail = 0; - s->cla_inc = 1; - s->cla_decay = 1; - s->var_inc = 1; - s->var_decay = 1; - s->root_level = 0; - s->simpdb_assigns = 0; - s->simpdb_props = 0; - s->random_seed = 91648253; - s->progress_estimate = 0; - s->binary = (clause*)malloc(sizeof(clause) - + sizeof(lit)*2); - s->binary->size_learnt = (2 << 1); - s->verbosity = 0; - - s->stats.starts = 0; - s->stats.decisions = 0; - s->stats.propagations = 0; - s->stats.inspects = 0; - s->stats.conflicts = 0; - s->stats.clauses = 0; - s->stats.clauses_literals = 0; - s->stats.learnts = 0; - s->stats.learnts_literals = 0; - s->stats.max_literals = 0; - s->stats.tot_literals = 0; - - return s; -} - -void solver_delete(solver* s) -{ - int i; - for (i = 0; i < vecp_size(&s->clauses); i++) - free(vecp_begin(&s->clauses)[i]); - - for (i = 0; i < vecp_size(&s->learnts); i++) - free(vecp_begin(&s->learnts)[i]); - - /* delete vectors */ - vecp_delete(&s->clauses); - vecp_delete(&s->learnts); - veci_delete(&s->order); - veci_delete(&s->trail_lim); - veci_delete(&s->tagged); - veci_delete(&s->stack); - veci_delete(&s->model); - free(s->binary); - - /* delete arrays */ - if (s->wlists != 0){ - int i; - for (i = 0; i < s->size*2; i++) - vecp_delete(&s->wlists[i]); - - /* if one is different from null, all are */ - free(s->wlists); - free(s->activity ); - free(s->assigns ); - free(s->orderpos ); - free(s->reasons ); - free(s->levels ); - free(s->trail ); - free(s->tags ); - } - - free(s); -} - -bool solver_addclause(solver* s, lit* begin, lit* end) -{ - lit *i,*j; - int maxvar; - lbool* values; - lit last; - - if (begin == end) return false; - - /* printlits(begin,end); printf("\n"); */ - /* insertion sort */ - maxvar = lit_var(*begin); - for (i = begin + 1; i < end; i++){ - lit l = *i; - maxvar = lit_var(l) > maxvar ? lit_var(l) : maxvar; - for (j = i; j > begin && *(j-1) > l; j--) - *j = *(j-1); - *j = l; - } - solver_setnvars(s,maxvar+1); - - /* printlits(begin,end); printf("\n"); */ - values = s->assigns; - - /* delete duplicates */ - last = lit_Undef; - for (i = j = begin; i < end; i++){ - /* printf("lit: "L_LIT", value = %d\n", L_lit(*i), - (lit_sign(*i) ? -values[lit_var(*i)] : values[lit_var(*i)])); */ - lbool sig = !lit_sign(*i); sig += sig - 1; - if (*i == lit_neg(last) || sig == values[lit_var(*i)]) - return true; /* tautology */ - else if (*i != last && values[lit_var(*i)] == l_Undef) - last = *j++ = *i; - } - - /* printf("final: "); printlits(begin,j); printf("\n"); */ - - if (j == begin) /* empty clause */ - return false; - else if (j - begin == 1) /* unit clause */ - return enqueue(s,*begin,(clause*)0); - - /* create new clause */ - vecp_push(&s->clauses,clause_new(s,begin,j,0)); - - s->stats.clauses++; - s->stats.clauses_literals += j - begin; - - return true; -} - -bool solver_simplify(solver* s) -{ - clause** reasons; - int type; - - assert(solver_dlevel(s) == 0); - - if (solver_propagate(s) != 0) - return false; - - if (s->qhead == s->simpdb_assigns || s->simpdb_props > 0) - return true; - - reasons = s->reasons; - for (type = 0; type < 2; type++){ - vecp* cs = type ? &s->learnts : &s->clauses; - clause** cls = (clause**)vecp_begin(cs); - - int i, j; - for (j = i = 0; i < vecp_size(cs); i++){ - if (reasons[lit_var(*clause_begin(cls[i]))] != cls[i] && - clause_simplify(s,cls[i]) == l_True) - clause_remove(s,cls[i]); - else - cls[j++] = cls[i]; - } - vecp_resize(cs,j); - } - - s->simpdb_assigns = s->qhead; - /* (shouldn't depend on 'stats' really, but it will do for now) */ - s->simpdb_props = (int)(s->stats.clauses_literals - + s->stats.learnts_literals); - - return true; -} - -bool solver_solve(solver* s, lit* begin, lit* end) -{ - double nof_conflicts = 100; - double nof_learnts = solver_nclauses(s) / 3; - lbool status = l_Undef; - lbool* values = s->assigns; - lit* i; - - /* printf("solve: "); printlits(begin, end); printf("\n"); */ - for (i = begin; i < end; i++){ - switch (lit_sign(*i) ? -values[lit_var(*i)] - : values[lit_var(*i)]){ - case 1: /* l_True: */ - break; - case 0: /* l_Undef */ - assume(s, *i); - if (solver_propagate(s) == NULL) - break; - /* falltrough */ - case -1: /* l_False */ - solver_canceluntil(s, 0); - return false; - } - } - - s->root_level = solver_dlevel(s); - - if (s->verbosity >= 1){ - printf("==================================[MINISAT]============" - "=======================\n"); - printf("| Conflicts | ORIGINAL | LEARNT " - " | Progress |\n"); - printf("| | Clauses Literals | Limit Clauses Litera" - "ls Lit/Cl | |\n"); - printf("=======================================================" - "=======================\n"); - } - - while (status == l_Undef){ - double Ratio = (s->stats.learnts == 0)? 0.0 : - s->stats.learnts_literals / (double)s->stats.learnts; - - if (s->verbosity >= 1){ - printf("| %9.0f | %7.0f %8.0f | %7.0f %7.0f %8.0f %7.1f | %" - "6.3f %% |\n", - (double)s->stats.conflicts, - (double)s->stats.clauses, - (double)s->stats.clauses_literals, - (double)nof_learnts, - (double)s->stats.learnts, - (double)s->stats.learnts_literals, - Ratio, - s->progress_estimate*100); - fflush(stdout); - } - status = solver_search(s,(int)nof_conflicts, (int)nof_learnts); - nof_conflicts *= 1.5; - nof_learnts *= 1.1; - } - if (s->verbosity >= 1) - printf("=======================================================" - "=======================\n"); - - solver_canceluntil(s,0); - return status != l_False; -} - -int solver_nvars(solver* s) -{ - return s->size; -} - -int solver_nclauses(solver* s) -{ - return vecp_size(&s->clauses); -} - -int solver_nconflicts(solver* s) -{ - return (int)s->stats.conflicts; -} - -/*====================================================================*/ -/* Sorting functions (sigh): */ - -static inline void selectionsort(void** array, int size, - int(*comp)(const void *, const void *)) -{ - int i, j, best_i; - void* tmp; - - for (i = 0; i < size-1; i++){ - best_i = i; - for (j = i+1; j < size; j++){ - if (comp(array[j], array[best_i]) < 0) - best_i = j; - } - tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp; - } -} - -static void sortrnd(void** array, int size, - int(*comp)(const void *, const void *), - double* seed) -{ - if (size <= 15) - selectionsort(array, size, comp); - - else{ - void* pivot = array[irand(seed, size)]; - void* tmp; - int i = -1; - int j = size; - - for(;;){ - do i++; while(comp(array[i], pivot)<0); - do j--; while(comp(pivot, array[j])<0); - - if (i >= j) break; - - tmp = array[i]; array[i] = array[j]; array[j] = tmp; - } - - sortrnd(array , i , comp, seed); - sortrnd(&array[i], size-i, comp, seed); - } -} - -static void sort(void** array, int size, - int(*comp)(const void *, const void *)) -{ - double seed = 91648253; - sortrnd(array,size,comp,&seed); -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/minisat/minisat.h b/resources/3rdparty/glpk-4.53/src/minisat/minisat.h deleted file mode 100644 index 2733e8d63..000000000 --- a/resources/3rdparty/glpk-4.53/src/minisat/minisat.h +++ /dev/null @@ -1,230 +0,0 @@ -/* minisat.h */ - -/* Modified by Andrew Makhorin , August 2011 */ - -/*********************************************************************** -* MiniSat -- Copyright (c) 2005, Niklas Sorensson -* http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat/ -* -* Permission is hereby granted, free of charge, to any person -* obtaining a copy of this software and associated documentation files -* (the "Software"), to deal in the Software without restriction, -* including without limitation the rights to use, copy, modify, merge, -* publish, distribute, sublicense, and/or sell copies of the Software, -* and to permit persons to whom the Software is furnished to do so, -* subject to the following conditions: -* -* The above copyright notice and this permission notice shall be -* included in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -***********************************************************************/ -/* Modified to compile with MS Visual Studio 6.0 by Alan Mishchenko */ - -#ifndef MINISAT_H -#define MINISAT_H - -/*====================================================================*/ -/* Simple types: */ - -typedef int bool; - -#define true 1 -#define false 0 - -typedef int lit; -#if 0 /* by mao */ -typedef char lbool; -#else -typedef int lbool; -#endif - -#define var_Undef (int)(-1) -#define lit_Undef (lit)(-2) - -#define l_Undef (lbool)0 -#define l_True (lbool)1 -#define l_False (lbool)(-1) - -#define toLit(v) (lit)((v) + (v)) -#define lit_neg(l) (lit)((l) ^ 1) -#define lit_var(l) (int)((l) >> 1) -#define lit_sign(l) (int)((l) & 1) - -/*====================================================================*/ -/* Vectors: */ - -/* vector of 32-bit intergers (added for 64-bit portability) */ -typedef struct /* veci_t */ { - int size; - int cap; - int* ptr; -} veci; - -#define veci_new(v) \ -{ (v)->size = 0; \ - (v)->cap = 4; \ - (v)->ptr = (int*)malloc(sizeof(int)*(v)->cap); \ -} - -#define veci_delete(v) free((v)->ptr) - -#define veci_begin(v) ((v)->ptr) - -#define veci_size(v) ((v)->size) - -#define veci_resize(v, k) (void)((v)->size = (k)) -/* only safe to shrink !! */ - -#define veci_push(v, e) \ -{ if ((v)->size == (v)->cap) \ - { int newsize = (v)->cap * 2+1; \ - (v)->ptr = (int*)realloc((v)->ptr,sizeof(int)*newsize); \ - (v)->cap = newsize; \ - } \ - (v)->ptr[(v)->size++] = (e); \ -} - -/* vector of 32- or 64-bit pointers */ -typedef struct /* vecp_t */ { - int size; - int cap; - void** ptr; -} vecp; - -#define vecp_new(v) \ -{ (v)->size = 0; \ - (v)->cap = 4; \ - (v)->ptr = (void**)malloc(sizeof(void*)*(v)->cap); \ -} - -#define vecp_delete(v) free((v)->ptr) - -#define vecp_begin(v) ((v)->ptr) - -#define vecp_size(v) ((v)->size) - -#define vecp_resize(v, k) (void)((v)->size = (k)) -/* only safe to shrink !! */ - -#define vecp_push(v, e) \ -{ if ((v)->size == (v)->cap) \ - { int newsize = (v)->cap * 2+1; \ - (v)->ptr = (void**)realloc((v)->ptr,sizeof(void*)*newsize); \ - (v)->cap = newsize; \ - } \ - (v)->ptr[(v)->size++] = (e); \ -} - -/*====================================================================*/ -/* Solver representation: */ - -typedef struct /* clause_t */ -{ - int size_learnt; - lit lits[1]; -} clause; - -typedef struct /* stats_t */ -{ - double starts, decisions, propagations, inspects, conflicts; - double clauses, clauses_literals, learnts, learnts_literals, - max_literals, tot_literals; -} stats; - -typedef struct /* solver_t */ -{ - int size; /* nof variables */ - int cap; /* size of varmaps */ - int qhead; /* Head index of queue. */ - int qtail; /* Tail index of queue. */ - - /* clauses */ - vecp clauses; /* List of problem constraints. - (contains: clause*) */ - vecp learnts; /* List of learnt clauses. - (contains: clause*) */ - - /* activities */ - double var_inc; /* Amount to bump next variable with. */ - double var_decay; /* INVERSE decay factor for variable - activity: stores 1/decay. */ - float cla_inc; /* Amount to bump next clause with. */ - float cla_decay; /* INVERSE decay factor for clause - activity: stores 1/decay. */ - - vecp* wlists; - double* activity; /* A heuristic measurement of the activity - of a variable. */ - lbool* assigns; /* Current values of variables. */ - int* orderpos; /* Index in variable order. */ - clause** reasons; - int* levels; - lit* trail; - - clause* binary; /* A temporary binary clause */ - lbool* tags; - veci tagged; /* (contains: var) */ - veci stack; /* (contains: var) */ - - veci order; /* Variable order. (heap) (contains: var) */ - veci trail_lim; /* Separator indices for different decision - levels in 'trail'. (contains: int) */ - veci model; /* If problem is solved, this vector - contains the model (contains: lbool). */ - - int root_level; /* Level of first proper decision. */ - int simpdb_assigns;/* Number of top-level assignments at last - 'simplifyDB()'. */ - int simpdb_props; /* Number of propagations before next - 'simplifyDB()'. */ - double random_seed; - double progress_estimate; - int verbosity; /* Verbosity level. - 0=silent, - 1=some progress report, - 2=everything */ - - stats stats; -} solver; - -/*====================================================================*/ -/* Public interface: */ - -#if 1 /* by mao; to keep namespace clean */ -#define solver_new _glp_minisat_new -#define solver_delete _glp_minisat_delete -#define solver_addclause _glp_minisat_addclause -#define solver_simplify _glp_minisat_simplify -#define solver_solve _glp_minisat_solve -#define solver_nvars _glp_minisat_nvars -#define solver_nclauses _glp_minisat_nclauses -#define solver_nconflicts _glp_minisat_nconflicts -#define solver_setnvars _glp_minisat_setnvars -#define solver_propagate _glp_minisat_propagate -#define solver_reducedb _glp_minisat_reducedb -#endif - -solver* solver_new(void); -void solver_delete(solver* s); - -bool solver_addclause(solver* s, lit* begin, lit* end); -bool solver_simplify(solver* s); -bool solver_solve(solver* s, lit* begin, lit* end); - -int solver_nvars(solver* s); -int solver_nclauses(solver* s); -int solver_nconflicts(solver* s); - -void solver_setnvars(solver* s,int n); - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/bignum.c b/resources/3rdparty/glpk-4.53/src/misc/bignum.c deleted file mode 100644 index f91df5fd0..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/bignum.c +++ /dev/null @@ -1,286 +0,0 @@ -/* bignum.c (bignum arithmetic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2006, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "bignum.h" - -/*********************************************************************** -* Two routines below are intended to multiply and divide unsigned -* integer numbers of arbitrary precision. -* -* The routines assume that an unsigned integer number is represented in -* the positional numeral system with the base 2^16 = 65536, i.e. each -* "digit" of the number is in the range [0, 65535] and represented as -* a 16-bit value of the unsigned short type. In other words, a number x -* has the following representation: -* -* n-1 -* x = sum d[j] * 65536^j, -* j=0 -* -* where n is the number of places (positions), and d[j] is j-th "digit" -* of x, 0 <= d[j] <= 65535. -***********************************************************************/ - -/*********************************************************************** -* NAME -* -* bigmul - multiply unsigned integer numbers of arbitrary precision -* -* SYNOPSIS -* -* #include "bignum.h" -* void bigmul(int n, int m, unsigned short x[], unsigned short y[]); -* -* DESCRIPTION -* -* The routine bigmul multiplies unsigned integer numbers of arbitrary -* precision. -* -* n is the number of digits of multiplicand, n >= 1; -* -* m is the number of digits of multiplier, m >= 1; -* -* x is an array containing digits of the multiplicand in elements -* x[m], x[m+1], ..., x[n+m-1]. Contents of x[0], x[1], ..., x[m-1] are -* ignored on entry. -* -* y is an array containing digits of the multiplier in elements y[0], -* y[1], ..., y[m-1]. -* -* On exit digits of the product are stored in elements x[0], x[1], ..., -* x[n+m-1]. The array y is not changed. */ - -void bigmul(int n, int m, unsigned short x[], unsigned short y[]) -{ int i, j; - unsigned int t; - xassert(n >= 1); - xassert(m >= 1); - for (j = 0; j < m; j++) x[j] = 0; - for (i = 0; i < n; i++) - { if (x[i+m]) - { t = 0; - for (j = 0; j < m; j++) - { t += (unsigned int)x[i+m] * (unsigned int)y[j] + - (unsigned int)x[i+j]; - x[i+j] = (unsigned short)t; - t >>= 16; - } - x[i+m] = (unsigned short)t; - } - } - return; -} - -/*********************************************************************** -* NAME -* -* bigdiv - divide unsigned integer numbers of arbitrary precision -* -* SYNOPSIS -* -* #include "bignum.h" -* void bigdiv(int n, int m, unsigned short x[], unsigned short y[]); -* -* DESCRIPTION -* -* The routine bigdiv divides one unsigned integer number of arbitrary -* precision by another with the algorithm described in [1]. -* -* n is the difference between the number of digits of dividend and the -* number of digits of divisor, n >= 0. -* -* m is the number of digits of divisor, m >= 1. -* -* x is an array containing digits of the dividend in elements x[0], -* x[1], ..., x[n+m-1]. -* -* y is an array containing digits of the divisor in elements y[0], -* y[1], ..., y[m-1]. The highest digit y[m-1] must be non-zero. -* -* On exit n+1 digits of the quotient are stored in elements x[m], -* x[m+1], ..., x[n+m], and m digits of the remainder are stored in -* elements x[0], x[1], ..., x[m-1]. The array y is changed but then -* restored. -* -* REFERENCES -* -* 1. D. Knuth. The Art of Computer Programming. Vol. 2: Seminumerical -* Algorithms. Stanford University, 1969. */ - -void bigdiv(int n, int m, unsigned short x[], unsigned short y[]) -{ int i, j; - unsigned int t; - unsigned short d, q, r; - xassert(n >= 0); - xassert(m >= 1); - xassert(y[m-1] != 0); - /* special case when divisor has the only digit */ - if (m == 1) - { d = 0; - for (i = n; i >= 0; i--) - { t = ((unsigned int)d << 16) + (unsigned int)x[i]; - x[i+1] = (unsigned short)(t / y[0]); - d = (unsigned short)(t % y[0]); - } - x[0] = d; - goto done; - } - /* multiply dividend and divisor by a normalizing coefficient in - * order to provide the condition y[m-1] >= base / 2 */ - d = (unsigned short)(0x10000 / ((unsigned int)y[m-1] + 1)); - if (d == 1) - x[n+m] = 0; - else - { t = 0; - for (i = 0; i < n+m; i++) - { t += (unsigned int)x[i] * (unsigned int)d; - x[i] = (unsigned short)t; - t >>= 16; - } - x[n+m] = (unsigned short)t; - t = 0; - for (j = 0; j < m; j++) - { t += (unsigned int)y[j] * (unsigned int)d; - y[j] = (unsigned short)t; - t >>= 16; - } - } - /* main loop */ - for (i = n; i >= 0; i--) - { /* estimate and correct the current digit of quotient */ - if (x[i+m] < y[m-1]) - { t = ((unsigned int)x[i+m] << 16) + (unsigned int)x[i+m-1]; - q = (unsigned short)(t / (unsigned int)y[m-1]); - r = (unsigned short)(t % (unsigned int)y[m-1]); - if (q == 0) goto putq; else goto test; - } - q = 0; - r = x[i+m-1]; -decr: q--; /* if q = 0 then q-- = 0xFFFF */ - t = (unsigned int)r + (unsigned int)y[m-1]; - r = (unsigned short)t; - if (t > 0xFFFF) goto msub; -test: t = (unsigned int)y[m-2] * (unsigned int)q; - if ((unsigned short)(t >> 16) > r) goto decr; - if ((unsigned short)(t >> 16) < r) goto msub; - if ((unsigned short)t > x[i+m-2]) goto decr; -msub: /* now subtract divisor multiplied by the current digit of - * quotient from the current dividend */ - if (q == 0) goto putq; - t = 0; - for (j = 0; j < m; j++) - { t += (unsigned int)y[j] * (unsigned int)q; - if (x[i+j] < (unsigned short)t) t += 0x10000; - x[i+j] -= (unsigned short)t; - t >>= 16; - } - if (x[i+m] >= (unsigned short)t) goto putq; - /* perform correcting addition, because the current digit of - * quotient is greater by one than its correct value */ - q--; - t = 0; - for (j = 0; j < m; j++) - { t += (unsigned int)x[i+j] + (unsigned int)y[j]; - x[i+j] = (unsigned short)t; - t >>= 16; - } -putq: /* store the current digit of quotient */ - x[i+m] = q; - } - /* divide divisor and remainder by the normalizing coefficient in - * order to restore their original values */ - if (d > 1) - { t = 0; - for (i = m-1; i >= 0; i--) - { t = (t << 16) + (unsigned int)x[i]; - x[i] = (unsigned short)(t / (unsigned int)d); - t %= (unsigned int)d; - } - t = 0; - for (j = m-1; j >= 0; j--) - { t = (t << 16) + (unsigned int)y[j]; - y[j] = (unsigned short)(t / (unsigned int)d); - t %= (unsigned int)d; - } - } -done: return; -} - -/**********************************************************************/ - -#ifdef GLP_TEST -#include -#include -#include -#include "rng.h" - -#define N_MAX 7 -/* maximal number of digits in multiplicand */ - -#define M_MAX 5 -/* maximal number of digits in multiplier */ - -#define N_TEST 1000000 -/* number of tests */ - -int main(void) -{ RNG *rand; - int d, j, n, m, test; - unsigned short x[N_MAX], y[M_MAX], z[N_MAX+M_MAX]; - rand = rng_create_rand(); - for (test = 1; test <= N_TEST; test++) - { /* x[0,...,n-1] := multiplicand */ - n = 1 + rng_unif_rand(rand, N_MAX-1); - assert(1 <= n && n <= N_MAX); - for (j = 0; j < n; j++) - { d = rng_unif_rand(rand, 65536); - assert(0 <= d && d <= 65535); - x[j] = (unsigned short)d; - } - /* y[0,...,m-1] := multiplier */ - m = 1 + rng_unif_rand(rand, M_MAX-1); - assert(1 <= m && m <= M_MAX); - for (j = 0; j < m; j++) - { d = rng_unif_rand(rand, 65536); - assert(0 <= d && d <= 65535); - y[j] = (unsigned short)d; - } - if (y[m-1] == 0) y[m-1] = 1; - /* z[0,...,n+m-1] := x * y */ - for (j = 0; j < n; j++) z[m+j] = x[j]; - bigmul(n, m, z, y); - /* z[0,...,m-1] := z mod y, z[m,...,n+m-1] := z div y */ - bigdiv(n, m, z, y); - /* z mod y must be 0 */ - for (j = 0; j < m; j++) assert(z[j] == 0); - /* z div y must be x */ - for (j = 0; j < n; j++) assert(z[m+j] == x[j]); - } - fprintf(stderr, "%d tests successfully passed\n", N_TEST); - rng_delete_rand(rand); - return 0; -} -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/bignum.h b/resources/3rdparty/glpk-4.53/src/misc/bignum.h deleted file mode 100644 index b6361d2bc..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/bignum.h +++ /dev/null @@ -1,37 +0,0 @@ -/* bignum.h (arbitrary precision arithmetic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2006, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef BIGNUM_H -#define BIGNUM_H - -#define bigmul _glp_bigmul -void bigmul(int n, int m, unsigned short x[], unsigned short y[]); -/* multiply unsigned integer numbers of arbitrary precision */ - -#define bigdiv _glp_bigdiv -void bigdiv(int n, int m, unsigned short x[], unsigned short y[]); -/* divide unsigned integer numbers of arbitrary precision */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/dmp.c b/resources/3rdparty/glpk-4.53/src/misc/dmp.c deleted file mode 100644 index e92b3e90e..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/dmp.c +++ /dev/null @@ -1,243 +0,0 @@ -/* dmp.c (dynamic memory pool) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "dmp.h" - -struct DMP -{ /* dynamic memory pool */ - void *avail[32]; - /* avail[k], 0 <= k <= 31, is a pointer to first available (free) - * atom of (k+1)*8 bytes long; at the beginning of each free atom - * there is a pointer to another free atom of the same size */ - void *block; - /* pointer to most recently allocated memory block; at the - * beginning of each allocated memory block there is a pointer to - * previously allocated memory block */ - int used; - /* number of bytes used in most recently allocated memory block */ - size_t count; - /* number of atoms which are currently in use */ -}; - -#define DMP_BLK_SIZE 8000 -/* size of memory blocks, in bytes, allocated for memory pools */ - -struct prefix -{ /* atom prefix (for debugging only) */ - DMP *pool; - /* dynamic memory pool */ - int size; - /* original atom size, in bytes */ -}; - -#define prefix_size ((sizeof(struct prefix) + 7) & ~7) -/* size of atom prefix rounded up to multiple of 8 bytes */ - -int dmp_debug; -/* debug mode flag */ - -/*********************************************************************** -* NAME -* -* dmp_create_pool - create dynamic memory pool -* -* SYNOPSIS -* -* #include "dmp.h" -* DMP *dmp_create_pool(void); -* -* DESCRIPTION -* -* The routine dmp_create_pool creates a dynamic memory pool. -* -* RETURNS -* -* The routine returns a pointer to the memory pool created. */ - -DMP *dmp_create_pool(void) -{ DMP *pool; - int k; - xassert(sizeof(void *) <= 8); - if (dmp_debug) - xprintf("dmp_create_pool: warning: debug mode is on\n"); - pool = talloc(1, DMP); - for (k = 0; k <= 31; k++) - pool->avail[k] = NULL; - pool->block = NULL; - pool->used = DMP_BLK_SIZE; - pool->count = 0; - return pool; -} - -/*********************************************************************** -* NAME -* -* dmp_get_atom - get free atom from dynamic memory pool -* -* SYNOPSIS -* -* #include "dmp.h" -* void *dmp_get_atom(DMP *pool, int size); -* -* DESCRIPTION -* -* The routine dmp_get_atom obtains a free atom (memory space) from the -* specified memory pool. -* -* The parameter size is the atom size, in bytes, 1 <= size <= 256. -* -* Note that the free atom contains arbitrary data, not binary zeros. -* -* RETURNS -* -* The routine returns a pointer to the free atom obtained. */ - -void *dmp_get_atom(DMP *pool, int size) -{ void *atom; - int k, need; - xassert(1 <= size && size <= 256); - /* round up atom size to multiple of 8 bytes */ - need = (size + 7) & ~7; - /* determine number of corresponding list of free atoms */ - k = (need >> 3) - 1; - /* obtain free atom */ - if (pool->avail[k] == NULL) - { /* corresponding list of free atoms is empty */ - /* if debug mode is on, add atom prefix size */ - if (dmp_debug) - need += prefix_size; - if (pool->used + need > DMP_BLK_SIZE) - { /* allocate new memory block */ - void *block = talloc(DMP_BLK_SIZE, char); - *(void **)block = pool->block; - pool->block = block; - pool->used = 8; /* sufficient to store pointer */ - } - /* allocate new atom in current memory block */ - atom = (char *)pool->block + pool->used; - pool->used += need; - } - else - { /* obtain atom from corresponding list of free atoms */ - atom = pool->avail[k]; - pool->avail[k] = *(void **)atom; - } - /* if debug mode is on, fill atom prefix */ - if (dmp_debug) - { ((struct prefix *)atom)->pool = pool; - ((struct prefix *)atom)->size = size; - atom = (char *)atom + prefix_size; - } - /* increase number of allocated atoms */ - pool->count++; - return atom; -} - -/*********************************************************************** -* NAME -* -* dmp_free_atom - return atom to dynamic memory pool -* -* SYNOPSIS -* -* #include "dmp.h" -* void dmp_free_atom(DMP *pool, void *atom, int size); -* -* DESCRIPTION -* -* The routine dmp_free_atom returns the specified atom (memory space) -* to the specified memory pool, making the atom free. -* -* The parameter size is the atom size, in bytes, 1 <= size <= 256. -* -* Note that the atom can be returned only to the pool, from which it -* was obtained, and its size must be exactly the same as on obtaining -* it from the pool. */ - -void dmp_free_atom(DMP *pool, void *atom, int size) -{ int k; - xassert(1 <= size && size <= 256); - /* determine number of corresponding list of free atoms */ - k = ((size + 7) >> 3) - 1; - /* if debug mode is on, check atom prefix */ - if (dmp_debug) - { atom = (char *)atom - prefix_size; - xassert(((struct prefix *)atom)->pool == pool); - xassert(((struct prefix *)atom)->size == size); - } - /* return atom to corresponding list of free atoms */ - *(void **)atom = pool->avail[k]; - pool->avail[k] = atom; - /* decrease number of allocated atoms */ - xassert(pool->count > 0); - pool->count--; - return; -} - -/*********************************************************************** -* NAME -* -* dmp_in_use - determine how many atoms are still in use -* -* SYNOPSIS -* -* #include "dmp.h" -* size_t dmp_in_use(DMP *pool); -* -* RETURNS -* -* The routine returns the number of atoms of the specified memory pool -* which are still in use. */ - -size_t dmp_in_use(DMP *pool) -{ return - pool->count; -} - -/*********************************************************************** -* NAME -* -* dmp_delete_pool - delete dynamic memory pool -* -* SYNOPSIS -* -* #include "dmp.h" -* void dmp_delete_pool(DMP *pool); -* -* DESCRIPTION -* -* The routine dmp_delete_pool deletes the specified dynamic memory -* pool freeing all the memory allocated to this object. */ - -void dmp_delete_pool(DMP *pool) -{ while (pool->block != NULL) - { void *block = pool->block; - pool->block = *(void **)block; - tfree(block); - } - tfree(pool); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/dmp.h b/resources/3rdparty/glpk-4.53/src/misc/dmp.h deleted file mode 100644 index e2ef01a89..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/dmp.h +++ /dev/null @@ -1,63 +0,0 @@ -/* dmp.h (dynamic memory pool) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef DMP_H -#define DMP_H - -#include "stdc.h" - -typedef struct DMP DMP; - -#define dmp_debug _glp_dmp_debug -extern int dmp_debug; -/* debug mode flag */ - -#define dmp_create_pool _glp_dmp_create_pool -DMP *dmp_create_pool(void); -/* create dynamic memory pool */ - -#define dmp_talloc(pool, type) \ - ((type *)dmp_get_atom(pool, sizeof(type))) - -#define dmp_get_atom _glp_dmp_get_atom -void *dmp_get_atom(DMP *pool, int size); -/* get free atom from dynamic memory pool */ - -#define dmp_tfree(pool, atom) \ - dmp_free_atom(pool, atom, sizeof(*(atom))) - -#define dmp_free_atom _glp_dmp_free_atom -void dmp_free_atom(DMP *pool, void *atom, int size); -/* return atom to dynamic memory pool */ - -#define dmp_in_use _glp_dmp_in_use -size_t dmp_in_use(DMP *pool); -/* determine how many atoms are still in use */ - -#define dmp_delete_pool _glp_dmp_delete_pool -void dmp_delete_pool(DMP *pool); -/* delete dynamic memory pool */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/ffalg.c b/resources/3rdparty/glpk-4.53/src/misc/ffalg.c deleted file mode 100644 index c55d8d4a2..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/ffalg.c +++ /dev/null @@ -1,221 +0,0 @@ -/* ffalg.c (Ford-Fulkerson algorithm) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2009, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "ffalg.h" - -/*********************************************************************** -* NAME -* -* ffalg - Ford-Fulkerson algorithm -* -* SYNOPSIS -* -* #include "ffalg.h" -* void ffalg(int nv, int na, const int tail[], const int head[], -* int s, int t, const int cap[], int x[], char cut[]); -* -* DESCRIPTION -* -* The routine ffalg implements the Ford-Fulkerson algorithm to find a -* maximal flow in the specified flow network. -* -* INPUT PARAMETERS -* -* nv is the number of nodes, nv >= 2. -* -* na is the number of arcs, na >= 0. -* -* tail[a], a = 1,...,na, is the index of tail node of arc a. -* -* head[a], a = 1,...,na, is the index of head node of arc a. -* -* s is the source node index, 1 <= s <= nv. -* -* t is the sink node index, 1 <= t <= nv, t != s. -* -* cap[a], a = 1,...,na, is the capacity of arc a, cap[a] >= 0. -* -* NOTE: Multiple arcs are allowed, but self-loops are not allowed. -* -* OUTPUT PARAMETERS -* -* x[a], a = 1,...,na, is optimal value of the flow through arc a. -* -* cut[i], i = 1,...,nv, is 1 if node i is labelled, and 0 otherwise. -* The set of arcs, whose one endpoint is labelled and other is not, -* defines the minimal cut corresponding to the maximal flow found. -* If the parameter cut is NULL, the cut information are not stored. -* -* REFERENCES -* -* L.R.Ford, Jr., and D.R.Fulkerson, "Flows in Networks," The RAND -* Corp., Report R-375-PR (August 1962), Chap. I "Static Maximal Flow," -* pp.30-33. */ - -void ffalg(int nv, int na, const int tail[], const int head[], - int s, int t, const int cap[], int x[], char cut[]) -{ int a, delta, i, j, k, pos1, pos2, temp, - *ptr, *arc, *link, *list; - /* sanity checks */ - xassert(nv >= 2); - xassert(na >= 0); - xassert(1 <= s && s <= nv); - xassert(1 <= t && t <= nv); - xassert(s != t); - for (a = 1; a <= na; a++) - { i = tail[a], j = head[a]; - xassert(1 <= i && i <= nv); - xassert(1 <= j && j <= nv); - xassert(i != j); - xassert(cap[a] >= 0); - } - /* allocate working arrays */ - ptr = xcalloc(1+nv+1, sizeof(int)); - arc = xcalloc(1+na+na, sizeof(int)); - link = xcalloc(1+nv, sizeof(int)); - list = xcalloc(1+nv, sizeof(int)); - /* ptr[i] := (degree of node i) */ - for (i = 1; i <= nv; i++) - ptr[i] = 0; - for (a = 1; a <= na; a++) - { ptr[tail[a]]++; - ptr[head[a]]++; - } - /* initialize arc pointers */ - ptr[1]++; - for (i = 1; i < nv; i++) - ptr[i+1] += ptr[i]; - ptr[nv+1] = ptr[nv]; - /* build arc lists */ - for (a = 1; a <= na; a++) - { arc[--ptr[tail[a]]] = a; - arc[--ptr[head[a]]] = a; - } - xassert(ptr[1] == 1); - xassert(ptr[nv+1] == na+na+1); - /* now the indices of arcs incident to node i are stored in - * locations arc[ptr[i]], arc[ptr[i]+1], ..., arc[ptr[i+1]-1] */ - /* initialize arc flows */ - for (a = 1; a <= na; a++) - x[a] = 0; -loop: /* main loop starts here */ - /* build augmenting tree rooted at s */ - /* link[i] = 0 means that node i is not labelled yet; - * link[i] = a means that arc a immediately precedes node i */ - /* initially node s is labelled as the root */ - for (i = 1; i <= nv; i++) - link[i] = 0; - link[s] = -1, list[1] = s, pos1 = pos2 = 1; - /* breadth first search */ - while (pos1 <= pos2) - { /* dequeue node i */ - i = list[pos1++]; - /* consider all arcs incident to node i */ - for (k = ptr[i]; k < ptr[i+1]; k++) - { a = arc[k]; - if (tail[a] == i) - { /* a = i->j is a forward arc from s to t */ - j = head[a]; - /* if node j has been labelled, skip the arc */ - if (link[j] != 0) continue; - /* if the arc does not allow increasing the flow through - * it, skip the arc */ - if (x[a] == cap[a]) continue; - } - else if (head[a] == i) - { /* a = i<-j is a backward arc from s to t */ - j = tail[a]; - /* if node j has been labelled, skip the arc */ - if (link[j] != 0) continue; - /* if the arc does not allow decreasing the flow through - * it, skip the arc */ - if (x[a] == 0) continue; - } - else - xassert(a != a); - /* label node j and enqueue it */ - link[j] = a, list[++pos2] = j; - /* check for breakthrough */ - if (j == t) goto brkt; - } - } - /* NONBREAKTHROUGH */ - /* no augmenting path exists; current flow is maximal */ - /* store minimal cut information, if necessary */ - if (cut != NULL) - { for (i = 1; i <= nv; i++) - cut[i] = (char)(link[i] != 0); - } - goto done; -brkt: /* BREAKTHROUGH */ - /* walk through arcs of the augmenting path (s, ..., t) found in - * the reverse order and determine maximal change of the flow */ - delta = 0; - for (j = t; j != s; j = i) - { /* arc a immediately precedes node j in the path */ - a = link[j]; - if (head[a] == j) - { /* a = i->j is a forward arc of the cycle */ - i = tail[a]; - /* x[a] may be increased until its upper bound */ - temp = cap[a] - x[a]; - } - else if (tail[a] == j) - { /* a = i<-j is a backward arc of the cycle */ - i = head[a]; - /* x[a] may be decreased until its lower bound */ - temp = x[a]; - } - else - xassert(a != a); - if (delta == 0 || delta > temp) delta = temp; - } - xassert(delta > 0); - /* increase the flow along the path */ - for (j = t; j != s; j = i) - { /* arc a immediately precedes node j in the path */ - a = link[j]; - if (head[a] == j) - { /* a = i->j is a forward arc of the cycle */ - i = tail[a]; - x[a] += delta; - } - else if (tail[a] == j) - { /* a = i<-j is a backward arc of the cycle */ - i = head[a]; - x[a] -= delta; - } - else - xassert(a != a); - } - goto loop; -done: /* free working arrays */ - xfree(ptr); - xfree(arc); - xfree(link); - xfree(list); - return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/ffalg.h b/resources/3rdparty/glpk-4.53/src/misc/ffalg.h deleted file mode 100644 index 662b747f3..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/ffalg.h +++ /dev/null @@ -1,34 +0,0 @@ -/* ffalg.h (Ford-Fulkerson algorithm) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2009, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef FFALG_H -#define FFALG_H - -#define ffalg _glp_ffalg -void ffalg(int nv, int na, const int tail[], const int head[], - int s, int t, const int cap[], int x[], char cut[]); -/* Ford-Fulkerson algorithm */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/fp2rat.c b/resources/3rdparty/glpk-4.53/src/misc/fp2rat.c deleted file mode 100644 index 1e462b9cb..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/fp2rat.c +++ /dev/null @@ -1,164 +0,0 @@ -/* fp2rat.c (convert floating-point number to rational number) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "misc.h" - -/*********************************************************************** -* NAME -* -* fp2rat - convert floating-point number to rational number -* -* SYNOPSIS -* -* #include "misc.h" -* int fp2rat(double x, double eps, double *p, double *q); -* -* DESCRIPTION -* -* Given a floating-point number 0 <= x < 1 the routine fp2rat finds -* its "best" rational approximation p / q, where p >= 0 and q > 0 are -* integer numbers, such that |x - p / q| <= eps. -* -* RETURNS -* -* The routine fp2rat returns the number of iterations used to achieve -* the specified precision eps. -* -* EXAMPLES -* -* For x = sqrt(2) - 1 = 0.414213562373095 and eps = 1e-6 the routine -* gives p = 408 and q = 985, where 408 / 985 = 0.414213197969543. -* -* BACKGROUND -* -* It is well known that every positive real number x can be expressed -* as the following continued fraction: -* -* x = b[0] + a[1] -* ------------------------ -* b[1] + a[2] -* ----------------- -* b[2] + a[3] -* ---------- -* b[3] + ... -* -* where: -* -* a[k] = 1, k = 0, 1, 2, ... -* -* b[k] = floor(x[k]), k = 0, 1, 2, ... -* -* x[0] = x, -* -* x[k] = 1 / frac(x[k-1]), k = 1, 2, 3, ... -* -* To find the "best" rational approximation of x the routine computes -* partial fractions f[k] by dropping after k terms as follows: -* -* f[k] = A[k] / B[k], -* -* where: -* -* A[-1] = 1, A[0] = b[0], B[-1] = 0, B[0] = 1, -* -* A[k] = b[k] * A[k-1] + a[k] * A[k-2], -* -* B[k] = b[k] * B[k-1] + a[k] * B[k-2]. -* -* Once the condition -* -* |x - f[k]| <= eps -* -* has been satisfied, the routine reports p = A[k] and q = B[k] as the -* final answer. -* -* In the table below here is some statistics obtained for one million -* random numbers uniformly distributed in the range [0, 1). -* -* eps max p mean p max q mean q max k mean k -* ------------------------------------------------------------- -* 1e-1 8 1.6 9 3.2 3 1.4 -* 1e-2 98 6.2 99 12.4 5 2.4 -* 1e-3 997 20.7 998 41.5 8 3.4 -* 1e-4 9959 66.6 9960 133.5 10 4.4 -* 1e-5 97403 211.7 97404 424.2 13 5.3 -* 1e-6 479669 669.9 479670 1342.9 15 6.3 -* 1e-7 1579030 2127.3 3962146 4257.8 16 7.3 -* 1e-8 26188823 6749.4 26188824 13503.4 19 8.2 -* -* REFERENCES -* -* W. B. Jones and W. J. Thron, "Continued Fractions: Analytic Theory -* and Applications," Encyclopedia on Mathematics and Its Applications, -* Addison-Wesley, 1980. */ - -int fp2rat(double x, double eps, double *p, double *q) -{ int k; - double xk, Akm1, Ak, Bkm1, Bk, ak, bk, fk, temp; - xassert(0.0 <= x && x < 1.0); - for (k = 0; ; k++) - { xassert(k <= 100); - if (k == 0) - { /* x[0] = x */ - xk = x; - /* A[-1] = 1 */ - Akm1 = 1.0; - /* A[0] = b[0] = floor(x[0]) = 0 */ - Ak = 0.0; - /* B[-1] = 0 */ - Bkm1 = 0.0; - /* B[0] = 1 */ - Bk = 1.0; - } - else - { /* x[k] = 1 / frac(x[k-1]) */ - temp = xk - floor(xk); - xassert(temp != 0.0); - xk = 1.0 / temp; - /* a[k] = 1 */ - ak = 1.0; - /* b[k] = floor(x[k]) */ - bk = floor(xk); - /* A[k] = b[k] * A[k-1] + a[k] * A[k-2] */ - temp = bk * Ak + ak * Akm1; - Akm1 = Ak, Ak = temp; - /* B[k] = b[k] * B[k-1] + a[k] * B[k-2] */ - temp = bk * Bk + ak * Bkm1; - Bkm1 = Bk, Bk = temp; - } - /* f[k] = A[k] / B[k] */ - fk = Ak / Bk; -#if 0 - print("%.*g / %.*g = %.*g", - DBL_DIG, Ak, DBL_DIG, Bk, DBL_DIG, fk); -#endif - if (fabs(x - fk) <= eps) - break; - } - *p = Ak; - *q = Bk; - return k; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/gcd.c b/resources/3rdparty/glpk-4.53/src/misc/gcd.c deleted file mode 100644 index b5c596209..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/gcd.c +++ /dev/null @@ -1,102 +0,0 @@ -/* gcd.c (greatest common divisor) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "misc.h" - -/*********************************************************************** -* NAME -* -* gcd - find greatest common divisor of two integers -* -* SYNOPSIS -* -* #include "misc.h" -* int gcd(int x, int y); -* -* RETURNS -* -* The routine gcd returns gcd(x, y), the greatest common divisor of -* the two positive integers given. -* -* ALGORITHM -* -* The routine gcd is based on Euclid's algorithm. -* -* REFERENCES -* -* Don Knuth, The Art of Computer Programming, Vol.2: Seminumerical -* Algorithms, 3rd Edition, Addison-Wesley, 1997. Section 4.5.2: The -* Greatest Common Divisor, pp. 333-56. */ - -int gcd(int x, int y) -{ int r; - xassert(x > 0 && y > 0); - while (y > 0) - r = x % y, x = y, y = r; - return x; -} - -/*********************************************************************** -* NAME -* -* gcdn - find greatest common divisor of n integers -* -* SYNOPSIS -* -* #include "misc.h" -* int gcdn(int n, int x[]); -* -* RETURNS -* -* The routine gcdn returns gcd(x[1], x[2], ..., x[n]), the greatest -* common divisor of n positive integers given, n > 0. -* -* BACKGROUND -* -* The routine gcdn is based on the following identity: -* -* gcd(x, y, z) = gcd(gcd(x, y), z). -* -* REFERENCES -* -* Don Knuth, The Art of Computer Programming, Vol.2: Seminumerical -* Algorithms, 3rd Edition, Addison-Wesley, 1997. Section 4.5.2: The -* Greatest Common Divisor, pp. 333-56. */ - -int gcdn(int n, int x[]) -{ int d, j; - xassert(n > 0); - for (j = 1; j <= n; j++) - { xassert(x[j] > 0); - if (j == 1) - d = x[1]; - else - d = gcd(d, x[j]); - if (d == 1) - break; - } - return d; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/jd.c b/resources/3rdparty/glpk-4.53/src/misc/jd.c deleted file mode 100644 index e678a1ee9..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/jd.c +++ /dev/null @@ -1,152 +0,0 @@ -/* jd.c (conversions between calendar date and Julian day number) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include -#include "jd.h" - -/*********************************************************************** -* NAME -* -* jday - convert calendar date to Julian day number -* -* SYNOPSIS -* -* #include "jd.h" -* int jday(int d, int m, int y); -* -* DESCRIPTION -* -* The routine jday converts a calendar date, Gregorian calendar, to -* corresponding Julian day number j. -* -* From the given day d, month m, and year y, the Julian day number j -* is computed without using tables. -* -* The routine is valid for 1 <= y <= 4000. -* -* RETURNS -* -* The routine jday returns the Julian day number, or negative value if -* the specified date is incorrect. -* -* REFERENCES -* -* R. G. Tantzen, Algorithm 199: conversions between calendar date and -* Julian day number, Communications of the ACM, vol. 6, no. 8, p. 444, -* Aug. 1963. */ - -int jday(int d, int m, int y) -{ int c, ya, j, dd; - if (!(1 <= d && d <= 31 && - 1 <= m && m <= 12 && - 1 <= y && y <= 4000)) - return -1; - if (m >= 3) - m -= 3; - else - m += 9, y--; - c = y / 100; - ya = y - 100 * c; - j = (146097 * c) / 4 + (1461 * ya) / 4 + (153 * m + 2) / 5 + d + - 1721119; - jdate(j, &dd, NULL, NULL); - if (d != dd) - return -1; - return j; -} - -/*********************************************************************** -* NAME -* -* jdate - convert Julian day number to calendar date -* -* SYNOPSIS -* -* #include "jd.h" -* int jdate(int j, int *d, int *m, int *y); -* -* DESCRIPTION -* -* The routine jdate converts a Julian day number j to corresponding -* calendar date, Gregorian calendar. -* -* The day d, month m, and year y are computed without using tables and -* stored in corresponding locations. -* -* The routine is valid for 1721426 <= j <= 3182395. -* -* RETURNS -* -* If the conversion is successful, the routine returns zero, otherwise -* non-zero. -* -* REFERENCES -* -* R. G. Tantzen, Algorithm 199: conversions between calendar date and -* Julian day number, Communications of the ACM, vol. 6, no. 8, p. 444, -* Aug. 1963. */ - -int jdate(int j, int *d_, int *m_, int *y_) -{ int d, m, y; - if (!(1721426 <= j && j <= 3182395)) - return 1; - j -= 1721119; - y = (4 * j - 1) / 146097; - j = (4 * j - 1) % 146097; - d = j / 4; - j = (4 * d + 3) / 1461; - d = (4 * d + 3) % 1461; - d = (d + 4) / 4; - m = (5 * d - 3) / 153; - d = (5 * d - 3) % 153; - d = (d + 5) / 5; - y = 100 * y + j; - if (m <= 9) - m += 3; - else m -= 9, - y++; - if (d_ != NULL) *d_ = d; - if (m_ != NULL) *m_ = m; - if (y_ != NULL) *y_ = y; - return 0; -} - -#ifdef GLP_TEST -#include -#include -#include - -int main(void) -{ int jbeg, jend, j, d, m, y; - jbeg = jday(1, 1, 1); - jend = jday(31, 12, 4000); - for (j = jbeg; j <= jend; j++) - { assert(jdate(j, &d, &m, &y) == 0); - assert(jday(d, m, y) == j); - } - printf("Routines jday and jdate work correctly.\n"); - return 0; -} -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/jd.h b/resources/3rdparty/glpk-4.53/src/misc/jd.h deleted file mode 100644 index daaa85894..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/jd.h +++ /dev/null @@ -1,32 +0,0 @@ -/* jd.h (conversions between calendar date and Julian day number) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#define jday _glp_jday -int jday(int d, int m, int y); -/* convert calendar date to Julian day number */ - -#define jdate _glp_jdate -int jdate(int j, int *d, int *m, int *y); -/* convert Julian day number to calendar date */ - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/keller.c b/resources/3rdparty/glpk-4.53/src/misc/keller.c deleted file mode 100644 index 2c4849d7d..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/keller.c +++ /dev/null @@ -1,235 +0,0 @@ -/* keller.c (cover edges by cliques, Kellerman's heuristic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2009, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "glpk.h" -#include "env.h" -#include "keller.h" - -/*********************************************************************** -* NAME -* -* kellerman - cover edges by cliques with Kellerman's heuristic -* -* SYNOPSIS -* -* #include "keller.h" -* int kellerman(int n, int (*func)(void *info, int i, int ind[]), -* void *info, glp_graph *H); -* -* DESCRIPTION -* -* The routine kellerman implements Kellerman's heuristic algorithm -* to find a minimal set of cliques which cover all edges of specified -* graph G = (V, E). -* -* The parameter n specifies the number of vertices |V|, n >= 0. -* -* Formal routine func specifies the set of edges E in the following -* way. Running the routine kellerman calls the routine func and passes -* to it parameter i, which is the number of some vertex, 1 <= i <= n. -* In response the routine func should store numbers of all vertices -* adjacent to vertex i to locations ind[1], ind[2], ..., ind[len] and -* return the value of len, which is the number of adjacent vertices, -* 0 <= len <= n. Self-loops are allowed, but ignored. Multiple edges -* are not allowed. -* -* The parameter info is a transit pointer (magic cookie) passed to the -* formal routine func as its first parameter. -* -* The result provided by the routine kellerman is the bipartite graph -* H = (V union C, F), which defines the covering found. (The program -* object of type glp_graph specified by the parameter H should be -* previously created with the routine glp_create_graph. On entry the -* routine kellerman erases the content of this object with the routine -* glp_erase_graph.) Vertices of first part V correspond to vertices of -* the graph G and have the same ordinal numbers 1, 2, ..., n. Vertices -* of second part C correspond to cliques and have ordinal numbers -* n+1, n+2, ..., n+k, where k is the total number of cliques in the -* edge covering found. Every edge f in F in the program object H is -* represented as arc f = (i->j), where i in V and j in C, which means -* that vertex i of the graph G is in clique C[j], 1 <= j <= k. (Thus, -* if two vertices of the graph G are in the same clique, these vertices -* are adjacent in G, and corresponding edge is covered by that clique.) -* -* RETURNS -* -* The routine Kellerman returns k, the total number of cliques in the -* edge covering found. -* -* REFERENCE -* -* For more details see: glpk/doc/notes/keller.pdf (in Russian). */ - -struct set -{ /* set of vertices */ - int size; - /* size (cardinality) of the set, 0 <= card <= n */ - int *list; /* int list[1+n]; */ - /* the set contains vertices list[1,...,size] */ - int *pos; /* int pos[1+n]; */ - /* pos[i] > 0 means that vertex i is in the set and - * list[pos[i]] = i; pos[i] = 0 means that vertex i is not in - * the set */ -}; - -int kellerman(int n, int (*func)(void *info, int i, int ind[]), - void *info, void /* glp_graph */ *H_) -{ glp_graph *H = H_; - struct set W_, *W = &W_, V_, *V = &V_; - glp_arc *a; - int i, j, k, m, t, len, card, best; - xassert(n >= 0); - /* H := (V, 0; 0), where V is the set of vertices of graph G */ - glp_erase_graph(H, H->v_size, H->a_size); - glp_add_vertices(H, n); - /* W := 0 */ - W->size = 0; - W->list = xcalloc(1+n, sizeof(int)); - W->pos = xcalloc(1+n, sizeof(int)); - memset(&W->pos[1], 0, sizeof(int) * n); - /* V := 0 */ - V->size = 0; - V->list = xcalloc(1+n, sizeof(int)); - V->pos = xcalloc(1+n, sizeof(int)); - memset(&V->pos[1], 0, sizeof(int) * n); - /* main loop */ - for (i = 1; i <= n; i++) - { /* W must be empty */ - xassert(W->size == 0); - /* W := { j : i > j and (i,j) in E } */ - len = func(info, i, W->list); - xassert(0 <= len && len <= n); - for (t = 1; t <= len; t++) - { j = W->list[t]; - xassert(1 <= j && j <= n); - if (j >= i) continue; - xassert(W->pos[j] == 0); - W->list[++W->size] = j, W->pos[j] = W->size; - } - /* on i-th iteration we need to cover edges (i,j) for all - * j in W */ - /* if W is empty, it is a special case */ - if (W->size == 0) - { /* set k := k + 1 and create new clique C[k] = { i } */ - k = glp_add_vertices(H, 1) - n; - glp_add_arc(H, i, n + k); - continue; - } - /* try to include vertex i into existing cliques */ - /* V must be empty */ - xassert(V->size == 0); - /* k is the number of cliques found so far */ - k = H->nv - n; - for (m = 1; m <= k; m++) - { /* do while V != W; since here V is within W, we can use - * equivalent condition: do while |V| < |W| */ - if (V->size == W->size) break; - /* check if C[m] is within W */ - for (a = H->v[n + m]->in; a != NULL; a = a->h_next) - { j = a->tail->i; - if (W->pos[j] == 0) break; - } - if (a != NULL) continue; - /* C[m] is within W, expand clique C[m] with vertex i */ - /* C[m] := C[m] union {i} */ - glp_add_arc(H, i, n + m); - /* V is a set of vertices whose incident edges are already - * covered by existing cliques */ - /* V := V union C[m] */ - for (a = H->v[n + m]->in; a != NULL; a = a->h_next) - { j = a->tail->i; - if (V->pos[j] == 0) - V->list[++V->size] = j, V->pos[j] = V->size; - } - } - /* remove from set W the vertices whose incident edges are - * already covered by existing cliques */ - /* W := W \ V, V := 0 */ - for (t = 1; t <= V->size; t++) - { j = V->list[t], V->pos[j] = 0; - if (W->pos[j] != 0) - { /* remove vertex j from W */ - if (W->pos[j] != W->size) - { int jj = W->list[W->size]; - W->list[W->pos[j]] = jj; - W->pos[jj] = W->pos[j]; - } - W->size--, W->pos[j] = 0; - } - } - V->size = 0; - /* now set W contains only vertices whose incident edges are - * still not covered by existing cliques; create new cliques - * to cover remaining edges until set W becomes empty */ - while (W->size > 0) - { /* find clique C[m], 1 <= m <= k, which shares maximal - * number of vertices with W; to break ties choose clique - * having smallest number m */ - m = 0, best = -1; - k = H->nv - n; - for (t = 1; t <= k; t++) - { /* compute cardinality of intersection of W and C[t] */ - card = 0; - for (a = H->v[n + t]->in; a != NULL; a = a->h_next) - { j = a->tail->i; - if (W->pos[j] != 0) card++; - } - if (best < card) - m = t, best = card; - } - xassert(m > 0); - /* set k := k + 1 and create new clique: - * C[k] := (W intersect C[m]) union { i }, which covers all - * edges incident to vertices from (W intersect C[m]) */ - k = glp_add_vertices(H, 1) - n; - for (a = H->v[n + m]->in; a != NULL; a = a->h_next) - { j = a->tail->i; - if (W->pos[j] != 0) - { /* vertex j is in both W and C[m]; include it in new - * clique C[k] */ - glp_add_arc(H, j, n + k); - /* remove vertex j from W, since edge (i,j) will be - * covered by new clique C[k] */ - if (W->pos[j] != W->size) - { int jj = W->list[W->size]; - W->list[W->pos[j]] = jj; - W->pos[jj] = W->pos[j]; - } - W->size--, W->pos[j] = 0; - } - } - /* include vertex i to new clique C[k] to cover edges (i,j) - * incident to all vertices j just removed from W */ - glp_add_arc(H, i, n + k); - } - } - /* free working arrays */ - xfree(W->list); - xfree(W->pos); - xfree(V->list); - xfree(V->pos); - /* return the number of cliques in the edge covering found */ - return H->nv - n; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/keller.h b/resources/3rdparty/glpk-4.53/src/misc/keller.h deleted file mode 100644 index 77dfbf67c..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/keller.h +++ /dev/null @@ -1,34 +0,0 @@ -/* keller.h (cover edges by cliques, Kellerman's heuristic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2009, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef KELLER_H -#define KELLER_H - -#define kellerman _glp_kellerman -int kellerman(int n, int (*func)(void *info, int i, int ind[]), - void *info, void /* glp_graph */ *H); -/* cover edges by cliques with Kellerman's heuristic */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/mc13d.c b/resources/3rdparty/glpk-4.53/src/misc/mc13d.c deleted file mode 100644 index d8bab398d..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/mc13d.c +++ /dev/null @@ -1,314 +0,0 @@ -/* mc13d.c (permutations to block triangular form) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* This code is the result of translation of the Fortran subroutines -* MC13D and MC13E associated with the following paper: -* -* I.S.Duff, J.K.Reid, Algorithm 529: Permutations to block triangular -* form, ACM Trans. on Math. Softw. 4 (1978), 189-192. -* -* Use of ACM Algorithms is subject to the ACM Software Copyright and -* License Agreement. See . -* -* The translation was made by Andrew Makhorin . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "mc13d.h" - -/*********************************************************************** -* NAME -* -* mc13d - permutations to block triangular form -* -* SYNOPSIS -* -* #include "mc13d.h" -* int mc13d(int n, const int icn[], const int ip[], const int lenr[], -* int ior[], int ib[], int lowl[], int numb[], int prev[]); -* -* DESCRIPTION -* -* Given the column numbers of the nonzeros in each row of the sparse -* matrix, the routine mc13d finds a symmetric permutation that makes -* the matrix block lower triangular. -* -* INPUT PARAMETERS -* -* n order of the matrix. -* -* icn array containing the column indices of the non-zeros. Those -* belonging to a single row must be contiguous but the ordering -* of column indices within each row is unimportant and wasted -* space between rows is permitted. -* -* ip ip[i], i = 1,2,...,n, is the position in array icn of the -* first column index of a non-zero in row i. -* -* lenr lenr[i], i = 1,2,...,n, is the number of non-zeros in row i. -* -* OUTPUT PARAMETERS -* -* ior ior[i], i = 1,2,...,n, gives the position on the original -* ordering of the row or column which is in position i in the -* permuted form. -* -* ib ib[i], i = 1,2,...,num, is the row number in the permuted -* matrix of the beginning of block i, 1 <= num <= n. -* -* WORKING ARRAYS -* -* arp working array of length [1+n], where arp[0] is not used. -* arp[i] is one less than the number of unsearched edges leaving -* node i. At the end of the algorithm it is set to a permutation -* which puts the matrix in block lower triangular form. -* -* ib working array of length [1+n], where ib[0] is not used. -* ib[i] is the position in the ordering of the start of the ith -* block. ib[n+1-i] holds the node number of the ith node on the -* stack. -* -* lowl working array of length [1+n], where lowl[0] is not used. -* lowl[i] is the smallest stack position of any node to which a -* path from node i has been found. It is set to n+1 when node i -* is removed from the stack. -* -* numb working array of length [1+n], where numb[0] is not used. -* numb[i] is the position of node i in the stack if it is on it, -* is the permuted order of node i for those nodes whose final -* position has been found and is otherwise zero. -* -* prev working array of length [1+n], where prev[0] is not used. -* prev[i] is the node at the end of the path when node i was -* placed on the stack. -* -* RETURNS -* -* The routine mc13d returns num, the number of blocks found. */ - -int mc13d(int n, const int icn[], const int ip[], const int lenr[], - int ior[], int ib[], int lowl[], int numb[], int prev[]) -{ int *arp = ior; - int dummy, i, i1, i2, icnt, ii, isn, ist, ist1, iv, iw, j, lcnt, - nnm1, num, stp; - /* icnt is the number of nodes whose positions in final ordering - * have been found. */ - icnt = 0; - /* num is the number of blocks that have been found. */ - num = 0; - nnm1 = n + n - 1; - /* Initialization of arrays. */ - for (j = 1; j <= n; j++) - { numb[j] = 0; - arp[j] = lenr[j] - 1; - } - for (isn = 1; isn <= n; isn++) - { /* Look for a starting node. */ - if (numb[isn] != 0) continue; - iv = isn; - /* ist is the number of nodes on the stack ... it is the stack - * pointer. */ - ist = 1; - /* Put node iv at beginning of stack. */ - lowl[iv] = numb[iv] = 1; - ib[n] = iv; - /* The body of this loop puts a new node on the stack or - * backtracks. */ - for (dummy = 1; dummy <= nnm1; dummy++) - { i1 = arp[iv]; - /* Have all edges leaving node iv been searched? */ - if (i1 >= 0) - { i2 = ip[iv] + lenr[iv] - 1; - i1 = i2 - i1; - /* Look at edges leaving node iv until one enters a new - * node or all edges are exhausted. */ - for (ii = i1; ii <= i2; ii++) - { iw = icn[ii]; - /* Has node iw been on stack already? */ - if (numb[iw] == 0) goto L70; - /* Update value of lowl[iv] if necessary. */ - if (lowl[iw] < lowl[iv]) lowl[iv] = lowl[iw]; - } - /* There are no more edges leaving node iv. */ - arp[iv] = -1; - } - /* Is node iv the root of a block? */ - if (lowl[iv] < numb[iv]) goto L60; - /* Order nodes in a block. */ - num++; - ist1 = n + 1 - ist; - lcnt = icnt + 1; - /* Peel block off the top of the stack starting at the top - * and working down to the root of the block. */ - for (stp = ist1; stp <= n; stp++) - { iw = ib[stp]; - lowl[iw] = n + 1; - numb[iw] = ++icnt; - if (iw == iv) break; - } - ist = n - stp; - ib[num] = lcnt; - /* Are there any nodes left on the stack? */ - if (ist != 0) goto L60; - /* Have all the nodes been ordered? */ - if (icnt < n) break; - goto L100; -L60: /* Backtrack to previous node on path. */ - iw = iv; - iv = prev[iv]; - /* Update value of lowl[iv] if necessary. */ - if (lowl[iw] < lowl[iv]) lowl[iv] = lowl[iw]; - continue; -L70: /* Put new node on the stack. */ - arp[iv] = i2 - ii - 1; - prev[iw] = iv; - iv = iw; - lowl[iv] = numb[iv] = ++ist; - ib[n+1-ist] = iv; - } - } -L100: /* Put permutation in the required form. */ - for (i = 1; i <= n; i++) - arp[numb[i]] = i; - return num; -} - -/**********************************************************************/ - -#ifdef GLP_TEST -#include "env.h" - -void test(int n, int ipp); - -int main(void) -{ /* test program for routine mc13d */ - test( 1, 0); - test( 2, 1); - test( 2, 2); - test( 3, 3); - test( 4, 4); - test( 5, 10); - test(10, 10); - test(10, 20); - test(20, 20); - test(20, 50); - test(50, 50); - test(50, 200); - return 0; -} - -void fa01bs(int max, int *nrand); - -void setup(int n, char a[1+50][1+50], int ip[], int icn[], int lenr[]); - -void test(int n, int ipp) -{ int ip[1+50], icn[1+1000], ior[1+50], ib[1+51], iw[1+150], - lenr[1+50]; - char a[1+50][1+50], hold[1+100]; - int i, ii, iblock, ij, index, j, jblock, jj, k9, num; - xprintf("\n\n\nMatrix is of order %d and has %d off-diagonal non-" - "zeros\n", n, ipp); - for (j = 1; j <= n; j++) - { for (i = 1; i <= n; i++) - a[i][j] = 0; - a[j][j] = 1; - } - for (k9 = 1; k9 <= ipp; k9++) - { /* these statements should be replaced by calls to your - * favorite random number generator to place two pseudo-random - * numbers between 1 and n in the variables i and j */ - for (;;) - { fa01bs(n, &i); - fa01bs(n, &j); - if (!a[i][j]) break; - } - a[i][j] = 1; - } - /* setup converts matrix a[i,j] to required sparsity-oriented - * storage format */ - setup(n, a, ip, icn, lenr); - num = mc13d(n, icn, ip, lenr, ior, ib, &iw[0], &iw[n], &iw[n+n]); - /* output reordered matrix with blocking to improve clarity */ - xprintf("\nThe reordered matrix which has %d block%s is of the fo" - "rm\n", num, num == 1 ? "" : "s"); - ib[num+1] = n + 1; - index = 100; - iblock = 1; - for (i = 1; i <= n; i++) - { for (ij = 1; ij <= index; ij++) - hold[ij] = ' '; - if (i == ib[iblock]) - { xprintf("\n"); - iblock++; - } - jblock = 1; - index = 0; - for (j = 1; j <= n; j++) - { if (j == ib[jblock]) - { hold[++index] = ' '; - jblock++; - } - ii = ior[i]; - jj = ior[j]; - hold[++index] = (char)(a[ii][jj] ? 'X' : '0'); - } - xprintf("%.*s\n", index, &hold[1]); - } - xprintf("\nThe starting point for each block is given by\n"); - for (i = 1; i <= num; i++) - { if ((i - 1) % 12 == 0) xprintf("\n"); - xprintf(" %4d", ib[i]); - } - xprintf("\n"); - return; -} - -void setup(int n, char a[1+50][1+50], int ip[], int icn[], int lenr[]) -{ int i, j, ind; - for (i = 1; i <= n; i++) - lenr[i] = 0; - ind = 1; - for (i = 1; i <= n; i++) - { ip[i] = ind; - for (j = 1; j <= n; j++) - { if (a[i][j]) - { lenr[i]++; - icn[ind++] = j; - } - } - } - return; -} - -double g = 1431655765.0; - -double fa01as(int i) -{ /* random number generator */ - g = fmod(g * 9228907.0, 4294967296.0); - if (i >= 0) - return g / 4294967296.0; - else - return 2.0 * g / 4294967296.0 - 1.0; -} - -void fa01bs(int max, int *nrand) -{ *nrand = (int)(fa01as(1) * (double)max) + 1; - return; -} -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/mc13d.h b/resources/3rdparty/glpk-4.53/src/misc/mc13d.h deleted file mode 100644 index b260fcd60..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/mc13d.h +++ /dev/null @@ -1,34 +0,0 @@ -/* mc13d.h */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2009, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef MC13D_H -#define MC13D_H - -#define mc13d _glp_mc13d -int mc13d(int n, const int icn[], const int ip[], const int lenr[], - int ior[], int ib[], int lowl[], int numb[], int prev[]); -/* permutations to block triangular form */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/mc21a.c b/resources/3rdparty/glpk-4.53/src/misc/mc21a.c deleted file mode 100644 index 700d0f4e2..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/mc21a.c +++ /dev/null @@ -1,301 +0,0 @@ -/* mc21a.c (permutations for zero-free diagonal) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* This code is the result of translation of the Fortran subroutines -* MC21A and MC21B associated with the following paper: -* -* I.S.Duff, Algorithm 575: Permutations for zero-free diagonal, ACM -* Trans. on Math. Softw. 7 (1981), 387-390. -* -* Use of ACM Algorithms is subject to the ACM Software Copyright and -* License Agreement. See . -* -* The translation was made by Andrew Makhorin . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "mc21a.h" - -/*********************************************************************** -* NAME -* -* mc21a - permutations for zero-free diagonal -* -* SYNOPSIS -* -* #include "mc21a.h" -* int mc21a(int n, const int icn[], const int ip[], const int lenr[], -* int iperm[], int pr[], int arp[], int cv[], int out[]); -* -* DESCRIPTION -* -* Given the pattern of nonzeros of a sparse matrix, the routine mc21a -* attempts to find a permutation of its rows that makes the matrix have -* no zeros on its diagonal. -* -* INPUT PARAMETERS -* -* n order of matrix. -* -* icn array containing the column indices of the non-zeros. Those -* belonging to a single row must be contiguous but the ordering -* of column indices within each row is unimportant and wasted -* space between rows is permitted. -* -* ip ip[i], i = 1,2,...,n, is the position in array icn of the -* first column index of a non-zero in row i. -* -* lenr lenr[i], i = 1,2,...,n, is the number of non-zeros in row i. -* -* OUTPUT PARAMETER -* -* iperm contains permutation to make diagonal have the smallest -* number of zeros on it. Elements (iperm[i], i), i = 1,2,...,n, -* are non-zero at the end of the algorithm unless the matrix is -* structurally singular. In this case, (iperm[i], i) will be -* zero for n - numnz entries. -* -* WORKING ARRAYS -* -* pr working array of length [1+n], where pr[0] is not used. -* pr[i] is the previous row to i in the depth first search. -* -* arp working array of length [1+n], where arp[0] is not used. -* arp[i] is one less than the number of non-zeros in row i which -* have not been scanned when looking for a cheap assignment. -* -* cv working array of length [1+n], where cv[0] is not used. -* cv[i] is the most recent row extension at which column i was -* visited. -* -* out working array of length [1+n], where out[0] is not used. -* out[i] is one less than the number of non-zeros in row i -* which have not been scanned during one pass through the main -* loop. -* -* RETURNS -* -* The routine mc21a returns numnz, the number of non-zeros on diagonal -* of permuted matrix. */ - -int mc21a(int n, const int icn[], const int ip[], const int lenr[], - int iperm[], int pr[], int arp[], int cv[], int out[]) -{ int i, ii, in1, in2, j, j1, jord, k, kk, numnz; - /* Initialization of arrays. */ - for (i = 1; i <= n; i++) - { arp[i] = lenr[i] - 1; - cv[i] = iperm[i] = 0; - } - numnz = 0; - /* Main loop. */ - /* Each pass round this loop either results in a new assignment - * or gives a row with no assignment. */ - for (jord = 1; jord <= n; jord++) - { j = jord; - pr[j] = -1; - for (k = 1; k <= jord; k++) - { /* Look for a cheap assignment. */ - in1 = arp[j]; - if (in1 >= 0) - { in2 = ip[j] + lenr[j] - 1; - in1 = in2 - in1; - for (ii = in1; ii <= in2; ii++) - { i = icn[ii]; - if (iperm[i] == 0) goto L110; - } - /* No cheap assignment in row. */ - arp[j] = -1; - } - /* Begin looking for assignment chain starting with row j.*/ - out[j] = lenr[j] - 1; - /* Inner loop. Extends chain by one or backtracks. */ - for (kk = 1; kk <= jord; kk++) - { in1 = out[j]; - if (in1 >= 0) - { in2 = ip[j] + lenr[j] - 1; - in1 = in2 - in1; - /* Forward scan. */ - for (ii = in1; ii <= in2; ii++) - { i = icn[ii]; - if (cv[i] != jord) - { /* Column i has not yet been accessed during - * this pass. */ - j1 = j; - j = iperm[i]; - cv[i] = jord; - pr[j] = j1; - out[j1] = in2 - ii - 1; - goto L100; - } - } - } - /* Backtracking step. */ - j = pr[j]; - if (j == -1) goto L130; - } -L100: ; - } -L110: /* New assignment is made. */ - iperm[i] = j; - arp[j] = in2 - ii - 1; - numnz++; - for (k = 1; k <= jord; k++) - { j = pr[j]; - if (j == -1) break; - ii = ip[j] + lenr[j] - out[j] - 2; - i = icn[ii]; - iperm[i] = j; - } -L130: ; - } - /* If matrix is structurally singular, we now complete the - * permutation iperm. */ - if (numnz < n) - { for (i = 1; i <= n; i++) - arp[i] = 0; - k = 0; - for (i = 1; i <= n; i++) - { if (iperm[i] == 0) - out[++k] = i; - else - arp[iperm[i]] = i; - } - k = 0; - for (i = 1; i <= n; i++) - { if (arp[i] == 0) - iperm[out[++k]] = i; - } - } - return numnz; -} - -/**********************************************************************/ - -#ifdef GLP_TEST -#include "env.h" - -int sing; - -void ranmat(int m, int n, int icn[], int iptr[], int nnnp1, int *knum, - int iw[]); - -void fa01bs(int max, int *nrand); - -int main(void) -{ /* test program for the routine mc21a */ - /* these runs on random matrices cause all possible statements in - * mc21a to be executed */ - int i, iold, j, j1, j2, jj, knum, l, licn, n, nov4, num, numnz; - int ip[1+21], icn[1+1000], iperm[1+20], lenr[1+20], iw1[1+80]; - licn = 1000; - /* run on random matrices of orders 1 through 20 */ - for (n = 1; n <= 20; n++) - { nov4 = n / 4; - if (nov4 < 1) nov4 = 1; -L10: fa01bs(nov4, &l); - knum = l * n; - /* knum is requested number of non-zeros in random matrix */ - if (knum > licn) goto L10; - /* if sing is false, matrix is guaranteed structurally - * non-singular */ - sing = ((n / 2) * 2 == n); - /* call to subroutine to generate random matrix */ - ranmat(n, n, icn, ip, n+1, &knum, iw1); - /* knum is now actual number of non-zeros in random matrix */ - if (knum > licn) goto L10; - xprintf("n = %2d; nz = %4d; sing = %d\n", n, knum, sing); - /* set up array of row lengths */ - for (i = 1; i <= n; i++) - lenr[i] = ip[i+1] - ip[i]; - /* call to mc21a */ - numnz = mc21a(n, icn, ip, lenr, iperm, &iw1[0], &iw1[n], - &iw1[n+n], &iw1[n+n+n]); - /* testing to see if there are numnz non-zeros on the diagonal - * of the permuted matrix. */ - num = 0; - for (i = 1; i <= n; i++) - { iold = iperm[i]; - j1 = ip[iold]; - j2 = j1 + lenr[iold] - 1; - if (j2 < j1) continue; - for (jj = j1; jj <= j2; jj++) - { j = icn[jj]; - if (j == i) - { num++; - break; - } - } - } - if (num != numnz) - xprintf("Failure in mc21a, numnz = %d instead of %d\n", - numnz, num); - } - return 0; -} - -void ranmat(int m, int n, int icn[], int iptr[], int nnnp1, int *knum, - int iw[]) -{ /* subroutine to generate random matrix */ - int i, ii, inum, j, lrow, matnum; - inum = (*knum / n) * 2; - if (inum > n-1) inum = n-1; - matnum = 1; - /* each pass through this loop generates a row of the matrix */ - for (j = 1; j <= m; j++) - { iptr[j] = matnum; - if (!(sing || j > n)) - icn[matnum++] = j; - if (n == 1) continue; - for (i = 1; i <= n; i++) iw[i] = 0; - if (!sing) iw[j] = 1; - fa01bs(inum, &lrow); - lrow--; - if (lrow == 0) continue; - /* lrow off-diagonal non-zeros in row j of the matrix */ - for (ii = 1; ii <= lrow; ii++) - { for (;;) - { fa01bs(n, &i); - if (iw[i] != 1) break; - } - iw[i] = 1; - icn[matnum++] = i; - } - } - for (i = m+1; i <= nnnp1; i++) - iptr[i] = matnum; - *knum = matnum - 1; - return; -} - -double g = 1431655765.0; - -double fa01as(int i) -{ /* random number generator */ - g = fmod(g * 9228907.0, 4294967296.0); - if (i >= 0) - return g / 4294967296.0; - else - return 2.0 * g / 4294967296.0 - 1.0; -} - -void fa01bs(int max, int *nrand) -{ *nrand = (int)(fa01as(1) * (double)max) + 1; - return; -} -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/mc21a.h b/resources/3rdparty/glpk-4.53/src/misc/mc21a.h deleted file mode 100644 index e0de53a15..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/mc21a.h +++ /dev/null @@ -1,34 +0,0 @@ -/* mc21a.h (permutations for zero-free diagonal) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2009, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef MC21A_H -#define MC21A_H - -#define mc21a _glp_mc21a -int mc21a(int n, const int icn[], const int ip[], const int lenr[], - int iperm[], int pr[], int arp[], int cv[], int out[]); -/* permutations for zero-free diagonal */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/misc.h b/resources/3rdparty/glpk-4.53/src/misc/misc.h deleted file mode 100644 index cf6c0481c..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/misc.h +++ /dev/null @@ -1,61 +0,0 @@ -/* misc.h (miscellaneous routines) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef MISC_H -#define MISC_H - -#define str2int _glp_str2int -int str2int(const char *str, int *val); -/* convert character string to value of int type */ - -#define str2num _glp_str2num -int str2num(const char *str, double *val); -/* convert character string to value of double type */ - -#define strspx _glp_strspx -char *strspx(char *str); -/* remove all spaces from character string */ - -#define strtrim _glp_strtrim -char *strtrim(char *str); -/* remove trailing spaces from character string */ - -#define gcd _glp_gcd -int gcd(int x, int y); -/* find greatest common divisor of two integers */ - -#define gcdn _glp_gcdn -int gcdn(int n, int x[]); -/* find greatest common divisor of n integers */ - -#define round2n _glp_round2n -double round2n(double x); -/* round floating-point number to nearest power of two */ - -#define fp2rat _glp_fp2rat -int fp2rat(double x, double eps, double *p, double *q); -/* convert floating-point number to rational number */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/okalg.c b/resources/3rdparty/glpk-4.53/src/misc/okalg.c deleted file mode 100644 index 5fa6ac37e..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/okalg.c +++ /dev/null @@ -1,382 +0,0 @@ -/* okalg.c (out-of-kilter algorithm) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2009, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "okalg.h" - -/*********************************************************************** -* NAME -* -* okalg - out-of-kilter algorithm -* -* SYNOPSIS -* -* #include "okalg.h" -* int okalg(int nv, int na, const int tail[], const int head[], -* const int low[], const int cap[], const int cost[], int x[], -* int pi[]); -* -* DESCRIPTION -* -* The routine okalg implements the out-of-kilter algorithm to find a -* minimal-cost circulation in the specified flow network. -* -* INPUT PARAMETERS -* -* nv is the number of nodes, nv >= 0. -* -* na is the number of arcs, na >= 0. -* -* tail[a], a = 1,...,na, is the index of tail node of arc a. -* -* head[a], a = 1,...,na, is the index of head node of arc a. -* -* low[a], a = 1,...,na, is an lower bound to the flow through arc a. -* -* cap[a], a = 1,...,na, is an upper bound to the flow through arc a, -* which is the capacity of the arc. -* -* cost[a], a = 1,...,na, is a per-unit cost of the flow through arc a. -* -* NOTES -* -* 1. Multiple arcs are allowed, but self-loops are not allowed. -* -* 2. It is required that 0 <= low[a] <= cap[a] for all arcs. -* -* 3. Arc costs may have any sign. -* -* OUTPUT PARAMETERS -* -* x[a], a = 1,...,na, is optimal value of the flow through arc a. -* -* pi[i], i = 1,...,nv, is Lagrange multiplier for flow conservation -* equality constraint corresponding to node i (the node potential). -* -* RETURNS -* -* 0 optimal circulation found; -* -* 1 there is no feasible circulation; -* -* 2 integer overflow occured; -* -* 3 optimality test failed (logic error). -* -* REFERENCES -* -* L.R.Ford, Jr., and D.R.Fulkerson, "Flows in Networks," The RAND -* Corp., Report R-375-PR (August 1962), Chap. III "Minimal Cost Flow -* Problems," pp.113-26. */ - -static int overflow(int u, int v) -{ /* check for integer overflow on computing u + v */ - if (u > 0 && v > 0 && u + v < 0) return 1; - if (u < 0 && v < 0 && u + v > 0) return 1; - return 0; -} - -int okalg(int nv, int na, const int tail[], const int head[], - const int low[], const int cap[], const int cost[], int x[], - int pi[]) -{ int a, aok, delta, i, j, k, lambda, pos1, pos2, s, t, temp, ret, - *ptr, *arc, *link, *list; - /* sanity checks */ - xassert(nv >= 0); - xassert(na >= 0); - for (a = 1; a <= na; a++) - { i = tail[a], j = head[a]; - xassert(1 <= i && i <= nv); - xassert(1 <= j && j <= nv); - xassert(i != j); - xassert(0 <= low[a] && low[a] <= cap[a]); - } - /* allocate working arrays */ - ptr = xcalloc(1+nv+1, sizeof(int)); - arc = xcalloc(1+na+na, sizeof(int)); - link = xcalloc(1+nv, sizeof(int)); - list = xcalloc(1+nv, sizeof(int)); - /* ptr[i] := (degree of node i) */ - for (i = 1; i <= nv; i++) - ptr[i] = 0; - for (a = 1; a <= na; a++) - { ptr[tail[a]]++; - ptr[head[a]]++; - } - /* initialize arc pointers */ - ptr[1]++; - for (i = 1; i < nv; i++) - ptr[i+1] += ptr[i]; - ptr[nv+1] = ptr[nv]; - /* build arc lists */ - for (a = 1; a <= na; a++) - { arc[--ptr[tail[a]]] = a; - arc[--ptr[head[a]]] = a; - } - xassert(ptr[1] == 1); - xassert(ptr[nv+1] == na+na+1); - /* now the indices of arcs incident to node i are stored in - * locations arc[ptr[i]], arc[ptr[i]+1], ..., arc[ptr[i+1]-1] */ - /* initialize arc flows and node potentials */ - for (a = 1; a <= na; a++) - x[a] = 0; - for (i = 1; i <= nv; i++) - pi[i] = 0; -loop: /* main loop starts here */ - /* find out-of-kilter arc */ - aok = 0; - for (a = 1; a <= na; a++) - { i = tail[a], j = head[a]; - if (overflow(cost[a], pi[i] - pi[j])) - { ret = 2; - goto done; - } - lambda = cost[a] + (pi[i] - pi[j]); - if (x[a] < low[a] || (lambda < 0 && x[a] < cap[a])) - { /* arc a = i->j is out of kilter, and we need to increase - * the flow through this arc */ - aok = a, s = j, t = i; - break; - } - if (x[a] > cap[a] || (lambda > 0 && x[a] > low[a])) - { /* arc a = i->j is out of kilter, and we need to decrease - * the flow through this arc */ - aok = a, s = i, t = j; - break; - } - } - if (aok == 0) - { /* all arcs are in kilter */ - /* check for feasibility */ - for (a = 1; a <= na; a++) - { if (!(low[a] <= x[a] && x[a] <= cap[a])) - { ret = 3; - goto done; - } - } - for (i = 1; i <= nv; i++) - { temp = 0; - for (k = ptr[i]; k < ptr[i+1]; k++) - { a = arc[k]; - if (tail[a] == i) - { /* a is outgoing arc */ - temp += x[a]; - } - else if (head[a] == i) - { /* a is incoming arc */ - temp -= x[a]; - } - else - xassert(a != a); - } - if (temp != 0) - { ret = 3; - goto done; - } - } - /* check for optimality */ - for (a = 1; a <= na; a++) - { i = tail[a], j = head[a]; - lambda = cost[a] + (pi[i] - pi[j]); - if ((lambda > 0 && x[a] != low[a]) || - (lambda < 0 && x[a] != cap[a])) - { ret = 3; - goto done; - } - } - /* current circulation is optimal */ - ret = 0; - goto done; - } - /* now we need to find a cycle (t, a, s, ..., t), which allows - * increasing the flow along it, where a is the out-of-kilter arc - * just found */ - /* link[i] = 0 means that node i is not labelled yet; - * link[i] = a means that arc a immediately precedes node i */ - /* initially only node s is labelled */ - for (i = 1; i <= nv; i++) - link[i] = 0; - link[s] = aok, list[1] = s, pos1 = pos2 = 1; - /* breadth first search */ - while (pos1 <= pos2) - { /* dequeue node i */ - i = list[pos1++]; - /* consider all arcs incident to node i */ - for (k = ptr[i]; k < ptr[i+1]; k++) - { a = arc[k]; - if (tail[a] == i) - { /* a = i->j is a forward arc from s to t */ - j = head[a]; - /* if node j has been labelled, skip the arc */ - if (link[j] != 0) continue; - /* if the arc does not allow increasing the flow through - * it, skip the arc */ - if (x[a] >= cap[a]) continue; - if (overflow(cost[a], pi[i] - pi[j])) - { ret = 2; - goto done; - } - lambda = cost[a] + (pi[i] - pi[j]); - if (lambda > 0 && x[a] >= low[a]) continue; - } - else if (head[a] == i) - { /* a = i<-j is a backward arc from s to t */ - j = tail[a]; - /* if node j has been labelled, skip the arc */ - if (link[j] != 0) continue; - /* if the arc does not allow decreasing the flow through - * it, skip the arc */ - if (x[a] <= low[a]) continue; - if (overflow(cost[a], pi[j] - pi[i])) - { ret = 2; - goto done; - } - lambda = cost[a] + (pi[j] - pi[i]); - if (lambda < 0 && x[a] <= cap[a]) continue; - } - else - xassert(a != a); - /* label node j and enqueue it */ - link[j] = a, list[++pos2] = j; - /* check for breakthrough */ - if (j == t) goto brkt; - } - } - /* NONBREAKTHROUGH */ - /* consider all arcs, whose one endpoint is labelled and other is - * not, and determine maximal change of node potentials */ - delta = 0; - for (a = 1; a <= na; a++) - { i = tail[a], j = head[a]; - if (link[i] != 0 && link[j] == 0) - { /* a = i->j, where node i is labelled, node j is not */ - if (overflow(cost[a], pi[i] - pi[j])) - { ret = 2; - goto done; - } - lambda = cost[a] + (pi[i] - pi[j]); - if (x[a] <= cap[a] && lambda > 0) - if (delta == 0 || delta > + lambda) delta = + lambda; - } - else if (link[i] == 0 && link[j] != 0) - { /* a = j<-i, where node j is labelled, node i is not */ - if (overflow(cost[a], pi[i] - pi[j])) - { ret = 2; - goto done; - } - lambda = cost[a] + (pi[i] - pi[j]); - if (x[a] >= low[a] && lambda < 0) - if (delta == 0 || delta > - lambda) delta = - lambda; - } - } - if (delta == 0) - { /* there is no feasible circulation */ - ret = 1; - goto done; - } - /* increase potentials of all unlabelled nodes */ - for (i = 1; i <= nv; i++) - { if (link[i] == 0) - { if (overflow(pi[i], delta)) - { ret = 2; - goto done; - } - pi[i] += delta; - } - } - goto loop; -brkt: /* BREAKTHROUGH */ - /* walk through arcs of the cycle (t, a, s, ..., t) found in the - * reverse order and determine maximal change of the flow */ - delta = 0; - for (j = t;; j = i) - { /* arc a immediately precedes node j in the cycle */ - a = link[j]; - if (head[a] == j) - { /* a = i->j is a forward arc of the cycle */ - i = tail[a]; - lambda = cost[a] + (pi[i] - pi[j]); - if (lambda > 0 && x[a] < low[a]) - { /* x[a] may be increased until its lower bound */ - temp = low[a] - x[a]; - } - else if (lambda <= 0 && x[a] < cap[a]) - { /* x[a] may be increased until its upper bound */ - temp = cap[a] - x[a]; - } - else - xassert(a != a); - } - else if (tail[a] == j) - { /* a = i<-j is a backward arc of the cycle */ - i = head[a]; - lambda = cost[a] + (pi[j] - pi[i]); - if (lambda < 0 && x[a] > cap[a]) - { /* x[a] may be decreased until its upper bound */ - temp = x[a] - cap[a]; - } - else if (lambda >= 0 && x[a] > low[a]) - { /* x[a] may be decreased until its lower bound */ - temp = x[a] - low[a]; - } - else - xassert(a != a); - } - else - xassert(a != a); - if (delta == 0 || delta > temp) delta = temp; - /* check for end of the cycle */ - if (i == t) break; - } - xassert(delta > 0); - /* increase the flow along the cycle */ - for (j = t;; j = i) - { /* arc a immediately precedes node j in the cycle */ - a = link[j]; - if (head[a] == j) - { /* a = i->j is a forward arc of the cycle */ - i = tail[a]; - /* overflow cannot occur */ - x[a] += delta; - } - else if (tail[a] == j) - { /* a = i<-j is a backward arc of the cycle */ - i = head[a]; - /* overflow cannot occur */ - x[a] -= delta; - } - else - xassert(a != a); - /* check for end of the cycle */ - if (i == t) break; - } - goto loop; -done: /* free working arrays */ - xfree(ptr); - xfree(arc); - xfree(link); - xfree(list); - return ret; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/okalg.h b/resources/3rdparty/glpk-4.53/src/misc/okalg.h deleted file mode 100644 index 71a4a0df7..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/okalg.h +++ /dev/null @@ -1,35 +0,0 @@ -/* okalg.h (out-of-kilter algorithm) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2009, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef OKALG_H -#define OKALG_H - -#define okalg _glp_okalg -int okalg(int nv, int na, const int tail[], const int head[], - const int low[], const int cap[], const int cost[], int x[], - int pi[]); -/* out-of-kilter algorithm */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/qmd.c b/resources/3rdparty/glpk-4.53/src/misc/qmd.c deleted file mode 100644 index a3397dcf9..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/qmd.c +++ /dev/null @@ -1,584 +0,0 @@ -/* qmd.c (quotient minimum degree algorithm) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* THIS CODE IS THE RESULT OF TRANSLATION OF THE FORTRAN SUBROUTINES -* GENQMD, QMDRCH, QMDQT, QMDUPD, AND QMDMRG FROM THE BOOK: -* -* ALAN GEORGE, JOSEPH W-H LIU. COMPUTER SOLUTION OF LARGE SPARSE -* POSITIVE DEFINITE SYSTEMS. PRENTICE-HALL, 1981. -* -* THE TRANSLATION HAS BEEN DONE WITH THE PERMISSION OF THE AUTHORS -* OF THE ORIGINAL FORTRAN SUBROUTINES: ALAN GEORGE AND JOSEPH LIU, -* UNIVERSITY OF WATERLOO, WATERLOO, ONTARIO, CANADA. -* -* The translation was made by Andrew Makhorin . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "qmd.h" - -/*********************************************************************** -* NAME -* -* genqmd - GENeral Quotient Minimum Degree algorithm -* -* SYNOPSIS -* -* #include "qmd.h" -* void genqmd(int *neqns, int xadj[], int adjncy[], int perm[], -* int invp[], int deg[], int marker[], int rchset[], int nbrhd[], -* int qsize[], int qlink[], int *nofsub); -* -* PURPOSE -* -* This routine implements the minimum degree algorithm. It makes use -* of the implicit representation of the elimination graph by quotient -* graphs, and the notion of indistinguishable nodes. -* -* CAUTION -* -* The adjancy vector adjncy will be destroyed. -* -* INPUT PARAMETERS -* -* neqns - number of equations; -* (xadj, adjncy) - -* the adjancy structure. -* -* OUTPUT PARAMETERS -* -* perm - the minimum degree ordering; -* invp - the inverse of perm. -* -* WORKING PARAMETERS -* -* deg - the degree vector. deg[i] is negative means node i has been -* numbered; -* marker - a marker vector, where marker[i] is negative means node i -* has been merged with another nodeand thus can be ignored; -* rchset - vector used for the reachable set; -* nbrhd - vector used for neighborhood set; -* qsize - vector used to store the size of indistinguishable -* supernodes; -* qlink - vector used to store indistinguishable nodes, i, qlink[i], -* qlink[qlink[i]], ... are the members of the supernode -* represented by i. -* -* PROGRAM SUBROUTINES -* -* qmdrch, qmdqt, qmdupd. -***********************************************************************/ - -void genqmd(int *_neqns, int xadj[], int adjncy[], int perm[], - int invp[], int deg[], int marker[], int rchset[], int nbrhd[], - int qsize[], int qlink[], int *_nofsub) -{ int inode, ip, irch, j, mindeg, ndeg, nhdsze, node, np, num, - nump1, nxnode, rchsze, search, thresh; -# define neqns (*_neqns) -# define nofsub (*_nofsub) - /* Initialize degree vector and other working variables. */ - mindeg = neqns; - nofsub = 0; - for (node = 1; node <= neqns; node++) - { perm[node] = node; - invp[node] = node; - marker[node] = 0; - qsize[node] = 1; - qlink[node] = 0; - ndeg = xadj[node+1] - xadj[node]; - deg[node] = ndeg; - if (ndeg < mindeg) mindeg = ndeg; - } - num = 0; - /* Perform threshold search to get a node of min degree. - * Variable search point to where search should start. */ -s200: search = 1; - thresh = mindeg; - mindeg = neqns; -s300: nump1 = num + 1; - if (nump1 > search) search = nump1; - for (j = search; j <= neqns; j++) - { node = perm[j]; - if (marker[node] >= 0) - { ndeg = deg[node]; - if (ndeg <= thresh) goto s500; - if (ndeg < mindeg) mindeg = ndeg; - } - } - goto s200; - /* Node has minimum degree. Find its reachable sets by calling - * qmdrch. */ -s500: search = j; - nofsub += deg[node]; - marker[node] = 1; - qmdrch(&node, xadj, adjncy, deg, marker, &rchsze, rchset, &nhdsze, - nbrhd); - /* Eliminate all nodes indistinguishable from node. They are given - * by node, qlink[node], ... . */ - nxnode = node; -s600: num++; - np = invp[nxnode]; - ip = perm[num]; - perm[np] = ip; - invp[ip] = np; - perm[num] = nxnode; - invp[nxnode] = num; - deg[nxnode] = -1; - nxnode = qlink[nxnode]; - if (nxnode > 0) goto s600; - if (rchsze > 0) - { /* Update the degrees of the nodes in the reachable set and - * identify indistinguishable nodes. */ - qmdupd(xadj, adjncy, &rchsze, rchset, deg, qsize, qlink, - marker, &rchset[rchsze+1], &nbrhd[nhdsze+1]); - /* Reset marker value of nodes in reach set. Update threshold - * value for cyclic search. Also call qmdqt to form new - * quotient graph. */ - marker[node] = 0; - for (irch = 1; irch <= rchsze; irch++) - { inode = rchset[irch]; - if (marker[inode] >= 0) - { marker[inode] = 0; - ndeg = deg[inode]; - if (ndeg < mindeg) mindeg = ndeg; - if (ndeg <= thresh) - { mindeg = thresh; - thresh = ndeg; - search = invp[inode]; - } - } - } - if (nhdsze > 0) - qmdqt(&node, xadj, adjncy, marker, &rchsze, rchset, nbrhd); - } - if (num < neqns) goto s300; - return; -# undef neqns -# undef nofsub -} - -/*********************************************************************** -* NAME -* -* qmdrch - Quotient MD ReaCHable set -* -* SYNOPSIS -* -* #include "qmd.h" -* void qmdrch(int *root, int xadj[], int adjncy[], int deg[], -* int marker[], int *rchsze, int rchset[], int *nhdsze, -* int nbrhd[]); -* -* PURPOSE -* -* This subroutine determines the reachable set of a node through a -* given subset. The adjancy structure is assumed to be stored in a -* quotient graph format. -* -* INPUT PARAMETERS -* -* root - the given node not in the subset; -* (xadj, adjncy) - -* the adjancy structure pair; -* deg - the degree vector. deg[i] < 0 means the node belongs to the -* given subset. -* -* OUTPUT PARAMETERS -* -* (rchsze, rchset) - -* the reachable set; -* (nhdsze, nbrhd) - -* the neighborhood set. -* -* UPDATED PARAMETERS -* -* marker - the marker vector for reach and nbrhd sets. > 0 means the -* node is in reach set. < 0 means the node has been merged -* with others in the quotient or it is in nbrhd set. -***********************************************************************/ - -void qmdrch(int *_root, int xadj[], int adjncy[], int deg[], - int marker[], int *_rchsze, int rchset[], int *_nhdsze, - int nbrhd[]) -{ int i, istop, istrt, j, jstop, jstrt, nabor, node; -# define root (*_root) -# define rchsze (*_rchsze) -# define nhdsze (*_nhdsze) - /* Loop through the neighbors of root in the quotient graph. */ - nhdsze = 0; - rchsze = 0; - istrt = xadj[root]; - istop = xadj[root+1] - 1; - if (istop < istrt) return; - for (i = istrt; i <= istop; i++) - { nabor = adjncy[i]; - if (nabor == 0) return; - if (marker[nabor] == 0) - { if (deg[nabor] >= 0) - { /* Include nabor into the reachable set. */ - rchsze++; - rchset[rchsze] = nabor; - marker[nabor] = 1; - goto s600; - } - /* nabor has been eliminated. Find nodes reachable from - * it. */ - marker[nabor] = -1; - nhdsze++; - nbrhd[nhdsze] = nabor; -s300: jstrt = xadj[nabor]; - jstop = xadj[nabor+1] - 1; - for (j = jstrt; j <= jstop; j++) - { node = adjncy[j]; - nabor = - node; - if (node < 0) goto s300; - if (node == 0) goto s600; - if (marker[node] == 0) - { rchsze++; - rchset[rchsze] = node; - marker[node] = 1; - } - } - } -s600: ; - } - return; -# undef root -# undef rchsze -# undef nhdsze -} - -/*********************************************************************** -* NAME -* -* qmdqt - Quotient MD Quotient graph Transformation -* -* SYNOPSIS -* -* #include "qmd.h" -* void qmdqt(int *root, int xadj[], int adjncy[], int marker[], -* int *rchsze, int rchset[], int nbrhd[]); -* -* PURPOSE -* -* This subroutine performs the quotient graph transformation after a -* node has been eliminated. -* -* INPUT PARAMETERS -* -* root - the node just eliminated. It becomes the representative of -* the new supernode; -* (xadj, adjncy) - -* the adjancy structure; -* (rchsze, rchset) - -* the reachable set of root in the old quotient graph; -* nbrhd - the neighborhood set which will be merged with root to form -* the new supernode; -* marker - the marker vector. -* -* UPDATED PARAMETERS -* -* adjncy - becomes the adjncy of the quotient graph. -***********************************************************************/ - -void qmdqt(int *_root, int xadj[], int adjncy[], int marker[], - int *_rchsze, int rchset[], int nbrhd[]) -{ int inhd, irch, j, jstop, jstrt, link, nabor, node; -# define root (*_root) -# define rchsze (*_rchsze) - irch = 0; - inhd = 0; - node = root; -s100: jstrt = xadj[node]; - jstop = xadj[node+1] - 2; - if (jstop >= jstrt) - { /* Place reach nodes into the adjacent list of node. */ - for (j = jstrt; j <= jstop; j++) - { irch++; - adjncy[j] = rchset[irch]; - if (irch >= rchsze) goto s400; - } - } - /* Link to other space provided by the nbrhd set. */ - link = adjncy[jstop+1]; - node = - link; - if (link >= 0) - { inhd++; - node = nbrhd[inhd]; - adjncy[jstop+1] = - node; - } - goto s100; - /* All reachable nodes have been saved. End the adjacent list. - * Add root to the neighborhood list of each node in the reach - * set. */ -s400: adjncy[j+1] = 0; - for (irch = 1; irch <= rchsze; irch++) - { node = rchset[irch]; - if (marker[node] >= 0) - { jstrt = xadj[node]; - jstop = xadj[node+1] - 1; - for (j = jstrt; j <= jstop; j++) - { nabor = adjncy[j]; - if (marker[nabor] < 0) - { adjncy[j] = root; - goto s600; - } - } - } -s600: ; - } - return; -# undef root -# undef rchsze -} - -/*********************************************************************** -* NAME -* -* qmdupd - Quotient MD UPDate -* -* SYNOPSIS -* -* #include "qmd.h" -* void qmdupd(int xadj[], int adjncy[], int *nlist, int list[], -* int deg[], int qsize[], int qlink[], int marker[], int rchset[], -* int nbrhd[]); -* -* PURPOSE -* -* This routine performs degree update for a set of nodes in the minimum -* degree algorithm. -* -* INPUT PARAMETERS -* -* (xadj, adjncy) - -* the adjancy structure; -* (nlist, list) - -* the list of nodes whose degree has to be updated. -* -* UPDATED PARAMETERS -* -* deg - the degree vector; -* qsize - size of indistinguishable supernodes; -* qlink - linked list for indistinguishable nodes; -* marker - used to mark those nodes in reach/nbrhd sets. -* -* WORKING PARAMETERS -* -* rchset - the reachable set; -* nbrhd - the neighborhood set. -* -* PROGRAM SUBROUTINES -* -* qmdmrg. -***********************************************************************/ - -void qmdupd(int xadj[], int adjncy[], int *_nlist, int list[], - int deg[], int qsize[], int qlink[], int marker[], int rchset[], - int nbrhd[]) -{ int deg0, deg1, il, inhd, inode, irch, j, jstop, jstrt, mark, - nabor, nhdsze, node, rchsze; -# define nlist (*_nlist) - /* Find all eliminated supernodes that are adjacent to some nodes - * in the given list. Put them into (nhdsze, nbrhd). deg0 contains - * the number of nodes in the list. */ - if (nlist <= 0) return; - deg0 = 0; - nhdsze = 0; - for (il = 1; il <= nlist; il++) - { node = list[il]; - deg0 += qsize[node]; - jstrt = xadj[node]; - jstop = xadj[node+1] - 1; - for (j = jstrt; j <= jstop; j++) - { nabor = adjncy[j]; - if (marker[nabor] == 0 && deg[nabor] < 0) - { marker[nabor] = -1; - nhdsze++; - nbrhd[nhdsze] = nabor; - } - } - } - /* Merge indistinguishable nodes in the list by calling the - * subroutine qmdmrg. */ - if (nhdsze > 0) - qmdmrg(xadj, adjncy, deg, qsize, qlink, marker, °0, &nhdsze, - nbrhd, rchset, &nbrhd[nhdsze+1]); - /* Find the new degrees of the nodes that have not been merged. */ - for (il = 1; il <= nlist; il++) - { node = list[il]; - mark = marker[node]; - if (mark == 0 || mark == 1) - { marker[node] = 2; - qmdrch(&node, xadj, adjncy, deg, marker, &rchsze, rchset, - &nhdsze, nbrhd); - deg1 = deg0; - if (rchsze > 0) - { for (irch = 1; irch <= rchsze; irch++) - { inode = rchset[irch]; - deg1 += qsize[inode]; - marker[inode] = 0; - } - } - deg[node] = deg1 - 1; - if (nhdsze > 0) - { for (inhd = 1; inhd <= nhdsze; inhd++) - { inode = nbrhd[inhd]; - marker[inode] = 0; - } - } - } - } - return; -# undef nlist -} - -/*********************************************************************** -* NAME -* -* qmdmrg - Quotient MD MeRGe -* -* SYNOPSIS -* -* #include "qmd.h" -* void qmdmrg(int xadj[], int adjncy[], int deg[], int qsize[], -* int qlink[], int marker[], int *deg0, int *nhdsze, int nbrhd[], -* int rchset[], int ovrlp[]); -* -* PURPOSE -* -* This routine merges indistinguishable nodes in the minimum degree -* ordering algorithm. It also computes the new degrees of these new -* supernodes. -* -* INPUT PARAMETERS -* -* (xadj, adjncy) - -* the adjancy structure; -* deg0 - the number of nodes in the given set; -* (nhdsze, nbrhd) - -* the set of eliminated supernodes adjacent to some nodes in -* the set. -* -* UPDATED PARAMETERS -* -* deg - the degree vector; -* qsize - size of indistinguishable nodes; -* qlink - linked list for indistinguishable nodes; -* marker - the given set is given by those nodes with marker value set -* to 1. Those nodes with degree updated will have marker value -* set to 2. -* -* WORKING PARAMETERS -* -* rchset - the reachable set; -* ovrlp - temp vector to store the intersection of two reachable sets. -***********************************************************************/ - -void qmdmrg(int xadj[], int adjncy[], int deg[], int qsize[], - int qlink[], int marker[], int *_deg0, int *_nhdsze, int nbrhd[], - int rchset[], int ovrlp[]) -{ int deg1, head, inhd, iov, irch, j, jstop, jstrt, link, lnode, - mark, mrgsze, nabor, node, novrlp, rchsze, root; -# define deg0 (*_deg0) -# define nhdsze (*_nhdsze) - /* Initialization. */ - if (nhdsze <= 0) return; - for (inhd = 1; inhd <= nhdsze; inhd++) - { root = nbrhd[inhd]; - marker[root] = 0; - } - /* Loop through each eliminated supernode in the set - * (nhdsze, nbrhd). */ - for (inhd = 1; inhd <= nhdsze; inhd++) - { root = nbrhd[inhd]; - marker[root] = -1; - rchsze = 0; - novrlp = 0; - deg1 = 0; -s200: jstrt = xadj[root]; - jstop = xadj[root+1] - 1; - /* Determine the reachable set and its intersection with the - * input reachable set. */ - for (j = jstrt; j <= jstop; j++) - { nabor = adjncy[j]; - root = - nabor; - if (nabor < 0) goto s200; - if (nabor == 0) break; - mark = marker[nabor]; - if (mark == 0) - { rchsze++; - rchset[rchsze] = nabor; - deg1 += qsize[nabor]; - marker[nabor] = 1; - } - else if (mark == 1) - { novrlp++; - ovrlp[novrlp] = nabor; - marker[nabor] = 2; - } - } - /* From the overlapped set, determine the nodes that can be - * merged together. */ - head = 0; - mrgsze = 0; - for (iov = 1; iov <= novrlp; iov++) - { node = ovrlp[iov]; - jstrt = xadj[node]; - jstop = xadj[node+1] - 1; - for (j = jstrt; j <= jstop; j++) - { nabor = adjncy[j]; - if (marker[nabor] == 0) - { marker[node] = 1; - goto s1100; - } - } - /* Node belongs to the new merged supernode. Update the - * vectors qlink and qsize. */ - mrgsze += qsize[node]; - marker[node] = -1; - lnode = node; -s900: link = qlink[lnode]; - if (link > 0) - { lnode = link; - goto s900; - } - qlink[lnode] = head; - head = node; -s1100: ; - } - if (head > 0) - { qsize[head] = mrgsze; - deg[head] = deg0 + deg1 - 1; - marker[head] = 2; - } - /* Reset marker values. */ - root = nbrhd[inhd]; - marker[root] = 0; - if (rchsze > 0) - { for (irch = 1; irch <= rchsze; irch++) - { node = rchset[irch]; - marker[node] = 0; - } - } - } - return; -# undef deg0 -# undef nhdsze -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/qmd.h b/resources/3rdparty/glpk-4.53/src/misc/qmd.h deleted file mode 100644 index 4c5a089ab..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/qmd.h +++ /dev/null @@ -1,58 +0,0 @@ -/* qmd.h (quotient minimum degree algorithm) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2001, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef QMD_H -#define QMD_H - -#define genqmd _glp_genqmd -void genqmd(int *neqns, int xadj[], int adjncy[], int perm[], - int invp[], int deg[], int marker[], int rchset[], int nbrhd[], - int qsize[], int qlink[], int *nofsub); -/* GENeral Quotient Minimum Degree algorithm */ - -#define qmdrch _glp_qmdrch -void qmdrch(int *root, int xadj[], int adjncy[], int deg[], - int marker[], int *rchsze, int rchset[], int *nhdsze, - int nbrhd[]); -/* Quotient MD ReaCHable set */ - -#define qmdqt _glp_qmdqt -void qmdqt(int *root, int xadj[], int adjncy[], int marker[], - int *rchsze, int rchset[], int nbrhd[]); -/* Quotient MD Quotient graph Transformation */ - -#define qmdupd _glp_qmdupd -void qmdupd(int xadj[], int adjncy[], int *nlist, int list[], - int deg[], int qsize[], int qlink[], int marker[], int rchset[], - int nbrhd[]); -/* Quotient MD UPDate */ - -#define qmdmrg _glp_qmdmrg -void qmdmrg(int xadj[], int adjncy[], int deg[], int qsize[], - int qlink[], int marker[], int *deg0, int *nhdsze, int nbrhd[], - int rchset[], int ovrlp[]); -/* Quotient MD MeRGe */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/relax4.c b/resources/3rdparty/glpk-4.53/src/misc/relax4.c deleted file mode 100644 index f0a47d6d5..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/relax4.c +++ /dev/null @@ -1,2850 +0,0 @@ -/* relax4.c (relaxation method of Bertsekas and Tseng) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* THIS CODE IS THE RESULT OF TRANSLATION OF THE FORTRAN CODE RELAX4. -* -* THE TRANSLATION HAS BEEN DONE WITH THE PERMISSION OF THE AUTHOR OF -* THE ORIGINAL FORTRAN CODE PROF. DIMITRI P. BERTSEKAS, MASSACHUSETTS -* INSTITUTE OF TECHNOLOGY, CAMBRIDGE, MASSACHUSETTS, USA. -* -* The translation was made by Andrew Makhorin . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "relax4.h" - -/*********************************************************************** -* WARNING -* -* A serious bug was *tentatively* fixed in this code (see #if/#endif -* marked by 'mao'). -* -* This bug is inherited from the original Fortran version of the -* RELAX-IV code. Unfortunately, the code is very intricate, so this -* bug is still under investigation. Thanks to Sylvain Fournier for bug -* report. -* -* RELAX-IV bug details -* -------------------- -* In the original RELAX-IV code there are four similar fragments in -* subroutines ascnt1 and ascnt2 like this: -* -* C -* C DECREASE THE PRICES OF THE SCANNED NODES BY DELPRC. -* C ADJUST FLOW TO MAINTAIN COMPLEMENTARY SLACKNESS WITH -* C THE PRICES. -* C -* NB = 0 -* DO 6 I=1,NSAVE -* . . . -* IF (RC(ARC).EQ.0) THEN -* DELX=DELX+U(ARC) -* NB = NB + 1 -* PRDCSR(NB) = ARC -* END IF -* . . . -* -* On some instances the variable NB becomes greater than N (the number -* of nodes) that leads to indexing error, because the array PRDCSR is -* declared as array of N elements (more precisely, as array of MAXNN -* elements, however, NB becomes even much greater than MAXNN). -***********************************************************************/ - -#define false 0 -#define true 1 - -/*********************************************************************** -* NAME -* -* RELAX-IV (version of October 1994) -* -* PURPOSE -* -* This routine implements the relaxation method of Bertsekas and Tseng -* (see [1], [2]) for linear cost ordinary network flow problems. -* -* [1] Bertsekas, D. P., "A Unified Framework for Primal-Dual Methods" -* Mathematical Programming, Vol. 32, 1985, pp. 125-145. -* [2] Bertsekas, D. P., and Tseng, P., "Relaxation Methods for -* Minimum Cost" Operations Research, Vol. 26, 1988, pp. 93-114. -* -* The relaxation method is also described in the books: -* -* [3] Bertsekas, D. P., "Linear Network Optimization: Algorithms and -* Codes" MIT Press, 1991. -* [4] Bertsekas, D. P. and Tsitsiklis, J. N., "Parallel and Distributed -* Computation: Numerical Methods", Prentice-Hall, 1989. -* [5] Bertsekas, D. P., "Network Optimization: Continuous and Discrete -* Models", Athena Scientific, 1998. -* -* RELEASE NOTE -* -* This version of relaxation code has option for a special crash -* procedure for the initial price-flow pair. This is recommended for -* difficult problems where the default initialization results in long -* running times. crash = 1 corresponds to an auction/shortest path -* method -* -* These initializations are recommended in the absence of any prior -* information on a favorable initial flow-price vector pair that -* satisfies complementary slackness. -* -* The relaxation portion of the code differs from the code RELAXT-III -* and other earlier relaxation codes in that it maintains the set of -* nodes with nonzero deficit in a fifo queue. Like its predecessor -* RELAXT-III, this code maintains a linked list of balanced (i.e., of -* zero reduced cost) arcs so to reduce the work in labeling and -* scanning. Unlike RELAXT-III, it does not use selectively shortest -* path iterations for initialization. -* -* SOURCE -* -* The original Fortran code was written by Dimitri P. Bertsekas and -* Paul Tseng, with a contribution by Jonathan Eckstein in the phase II -* initialization. The original Fortran routine AUCTION was written by -* Dimitri P. Bertsekas and is based on the method described in the -* paper: -* -* [6] Bertsekas, D. P., "An Auction/Sequential Shortest Path Algorithm -* for the Minimum Cost Flow Problem", LIDS Report P-2146, MIT, -* Nov. 1992. -* -* For inquiries about the original Fortran code, please contact: -* -* Dimitri P. Bertsekas -* Laboratory for information and decision systems -* Massachusetts Institute of Technology -* Cambridge, MA 02139 -* (617) 253-7267, dimitrib@mit.edu -* -* This code is the result of translation of the original Fortran code. -* The translation was made by Andrew Makhorin . -* -* USER GUIDELINES -* -* This routine is in the public domain to be used only for research -* purposes. It cannot be used as part of a commercial product, or to -* satisfy in any part commercial delivery requirements to government -* or industry, without prior agreement with the authors. Users are -* requested to acknowledge the authorship of the code, and the -* relaxation method. -* -* No modification should be made to this code other than the minimal -* necessary to make it compatible with specific platforms. -* -* INPUT PARAMETERS (see notes 1, 2, 4) -* -* n = number of nodes -* na = number of arcs -* large = a very large integer to represent infinity -* (see note 3) -* repeat = true if initialization is to be skipped -* (false otherwise) -* crash = 0 if default initialization is used -* 1 if auction initialization is used -* startn[j] = starting node for arc j, j = 1,...,na -* endn[j] = ending node for arc j, j = 1,...,na -* fou[i] = first arc out of node i, i = 1,...,n -* nxtou[j] = next arc out of the starting node of arc j, j = 1,...,na -* fin[i] = first arc into node i, i = 1,...,n -* nxtin[j] = next arc into the ending node of arc j, j = 1,...,na -* -* UPDATED PARAMETERS (see notes 1, 3, 4) -* -* rc[j] = reduced cost of arc j, j = 1,...,na -* u[j] = capacity of arc j on input -* and (capacity of arc j) - x[j] on output, j = 1,...,na -* dfct[i] = demand at node i on input -* and zero on output, i = 1,...,n -* -* OUTPUT PARAMETERS (see notes 1, 3, 4) -* -* x[j] = flow on arc j, j = 1,...,na -* nmultinode = number of multinode relaxation iterations in RELAX4 -* iter = number of relaxation iterations in RELAX4 -* num_augm = number of flow augmentation steps in RELAX4 -* num_ascnt = number of multinode ascent steps in RELAX4 -* nsp = number of auction/shortest path iterations -* -* WORKING PARAMETERS (see notes 1, 4, 5) -* -* label[1+n], prdcsr[1+n], save[1+na], tfstou[1+n], tnxtou[1+na], -* tfstin[1+n], tnxtin[1+na], nxtqueue[1+n], scan[1+n], mark[1+n], -* extend_arc[1+n], sb_level[1+n], sb_arc[1+n] -* -* RETURNS -* -* 0 = normal return -* 1,...,8 = problem is found to be infeasible -* -* NOTE 1 -* -* To run in limited memory systems, declare the arrays startn, endn, -* nxtin, nxtou, fin, fou, label, prdcsr, save, tfstou, tnxtou, tfstin, -* tnxtin, ddpos, ddneg, nxtqueue as short instead. -* -* NOTE 2 -* -* This routine makes no effort to initialize with a favorable x from -* amongst those flow vectors that satisfy complementary slackness with -* the initial reduced cost vector rc. If a favorable x is known, then -* it can be passed, together with the corresponding arrays u and dfct, -* to this routine directly. This, however, requires that the capacity -* tightening portion and the flow initialization portion of this -* routine (up to line labeled 90) be skipped. -* -* NOTE 3 -* -* All problem data should be less than large in magnitude, and large -* should be less than, say, 1/4 the largest int of the machine used. -* This will guard primarily against overflow in uncapacitated problems -* where the arc capacities are taken finite but very large. Note, -* however, that as in all codes operating with integers, overflow may -* occur if some of the problem data takes very large values. -* -* NOTE 4 -* -* [This note being specific to Fortran was removed.-A.M.] -* -* NOTE 5 -* -* ddpos and ddneg are arrays that give the directional derivatives for -* all positive and negative single-node price changes. These are used -* only in phase II of the initialization procedure, before the linked -* list of balanced arcs comes to play. Therefore, to reduce storage, -* they are equivalence to tfstou and tfstin, which are of the same size -* (number of nodes) and are used only after the tree comes into use. */ - -static void ascnt1(struct relax4_csa *csa, int dm, int *delx, - int *nlabel, int *feasbl, int *svitch, int nscan, int curnode, - int *prevnode); - -static void ascnt2(struct relax4_csa *csa, int dm, int *delx, - int *nlabel, int *feasbl, int *svitch, int nscan, int curnode, - int *prevnode); - -static int auction(struct relax4_csa *csa); - -int relax4(struct relax4_csa *csa) -{ /* input parameters */ - int n = csa->n; - int na = csa->na; - int large = csa->large; - int repeat = csa->repeat; - int crash = csa->crash; - int *startn = csa->startn; - int *endn = csa->endn; - int *fou = csa->fou; - int *nxtou = csa->nxtou; - int *fin = csa->fin; - int *nxtin = csa->nxtin; - /* updated parameters */ - int *rc = csa->rc; - int *u = csa->u; - int *dfct = csa->dfct; - /* output parameters */ - int *x = csa->x; -# define nmultinode (csa->nmultinode) -# define iter (csa->iter) -# define num_augm (csa->num_augm) -# define num_ascnt (csa->num_ascnt) -# define nsp (csa->nsp) - /* working parameters */ - int *label = csa->label; - int *prdcsr = csa->prdcsr; - int *save = csa->save; - int *tfstou = csa->tfstou; - int *tnxtou = csa->tnxtou; - int *tfstin = csa->tfstin; - int *tnxtin = csa->tnxtin; - int *nxtqueue = csa->nxtqueue; - char *scan = csa->scan; - char *mark = csa->mark; - int *ddpos = tfstou; - int *ddneg = tfstin; - /* local variables */ - int arc, augnod, capin, capout, defcit, delprc, delx, dm, dp, - dx, feasbl, i, ib, indef, j, lastqueue, maxcap, narc, nb, - nlabel, node, node2, node_def, naugnod, nscan, num_passes, - numnz, numnz_new, numpasses, nxtarc, nxtbrk, nxtnode, passes, - pchange, posit, prevnode, prvarc, quit, rdcost, scapin, - scapou, svitch, t, t1, t2, tmparc, tp, trc, ts; - /*--------------------------------------------------------------*/ - /* Initialization phase I */ - /* In this phase, we reduce the arc capacities by as much as - * possible without changing the problem; then we set the initial - * flow array x, together with the corresponding arrays u and - * dfct. */ - /* This phase and phase II (from here up to line labeled 90) can - * be skipped (by setting repeat to true) if the calling program - * places in common user-chosen values for the arc flows, the - * residual arc capacities, and the nodal deficits. When this is - * done, it is critical that the flow and the reduced cost for - * each arc satisfy complementary slackness and the dfct array - * properly correspond to the initial arc/flows. */ - if (repeat) - goto L90; - for (node = 1; node <= n; node++) - { node_def = dfct[node]; - ddpos[node] = node_def; - ddneg[node] = -node_def; - maxcap = 0; - scapou = 0; - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { if (scapou <= large - u[arc]) - scapou += u[arc]; - else - goto L10; - } - if (scapou <= large - node_def) - capout = scapou + node_def; - else - goto L10; - if (capout < 0) - { /* problem is infeasible */ - /* exogenous flow into node exceeds out capacity */ - return 1; - } - scapin = 0; - for (arc = fin[node]; arc > 0; arc = nxtin[arc]) - { if (u[arc] > capout) - u[arc] = capout; - if (maxcap < u[arc]) - maxcap = u[arc]; - if (scapin <= large - u[arc]) - scapin += u[arc]; - else - goto L10; - } - if (scapin <= large + node_def) - capin = scapin - node_def; - else - goto L10; - if (capin < 0) - { /* problem is infeasible */ - /* exogenous flow out of node exceeds in capacity */ - return 2; - } - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { if (u[arc] > capin) - u[arc] = capin; - } -L10: ; - } - /*--------------------------------------------------------------*/ - /* Initialization phase II */ - /* In this phase, we initialize the prices and flows by either - * calling the routine auction or by performing only single node - * (coordinate) relaxation iterations. */ - if (crash == 1) - { nsp = 0; - if (auction(csa) != 0) - { /* problem is found to be infeasible */ - return 3; - } - goto L70; - } - /* Initialize the arc flows to satisfy complementary slackness - * with the prices. u[arc] is the residual capacity of arc, and - * x[arc] is the flow. These two always add up to the total - * capacity for arc. Also compute the directional derivatives for - * each coordinate and compute the actual deficits. */ - for (arc = 1; arc <= na; arc++) - { x[arc] = 0; - if (rc[arc] <= 0) - { t = u[arc]; - t1 = startn[arc]; - t2 = endn[arc]; - ddpos[t1] += t; - ddneg[t2] += t; - if (rc[arc] < 0) - { x[arc] = t; - u[arc] = 0; - dfct[t1] += t; - dfct[t2] -= t; - ddneg[t1] -= t; - ddpos[t2] -= t; - } - } - } - /* Make 2 or 3 passes through all nodes, performing only single - * node relaxation iterations. The number of passes depends on the - * density of the network. */ - if (na > n * 10) - numpasses = 2; - else - numpasses = 3; - for (passes = 1; passes <= numpasses; passes++) - for (node = 1; node <= n; node++) - { if (dfct[node] == 0) - continue; - if (ddpos[node] <= 0) - { /* Compute delprc, the stepsize to the next breakpoint in - * the dual cost as the price of node is increased. - * [Since the reduced cost of all outgoing (resp., incoming) - * arcs will decrease (resp., increase) as the price of node - * is increased, the next breakpoint is the minimum of the - * positive reduced cost on outgoing arcs and of the - * negative reduced cost on incoming arcs.] */ - delprc = large; - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { trc = rc[arc]; - if ((trc > 0) && (trc < delprc)) - delprc = trc; - } - for (arc = fin[node]; arc > 0; arc = nxtin[arc]) - { trc = rc[arc]; - if ((trc < 0) && (trc > -delprc)) - delprc = -trc; - } - /* If no breakpoint is left and dual ascent is still - * possible, the problem is infeasible. */ - if (delprc >= large) - { if (ddpos[node] == 0) - continue; - return 4; - } - /* delprc is the stepsize to next breakpoint. Increase - * price of node by delprc and compute the stepsize to the - * next breakpoint in the dual cost. */ -L53: nxtbrk = large; - /* Look at all arcs out of node. */ - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { trc = rc[arc]; - if (trc == 0) - { t1 = endn[arc]; - t = u[arc]; - if (t > 0) - { dfct[node] += t; - dfct[t1] -= t; - x[arc] = t; - u[arc] = 0; - } - else - t = x[arc]; - ddneg[node] -= t; - ddpos[t1] -= t; - } - /* Decrease the reduced costs on all outgoing arcs. */ - trc -= delprc; - if ((trc > 0) && (trc < nxtbrk)) - nxtbrk = trc; - else if (trc == 0) - { /* Arc goes from inactive to balanced. Update the rate - * of dual ascent at node and at its neighbor. */ - ddpos[node] += u[arc]; - ddneg[endn[arc]] += u[arc]; - } - rc[arc] = trc; - } - /* Look at all arcs into node. */ - for (arc = fin[node]; arc > 0; arc = nxtin[arc]) - { trc = rc[arc]; - if (trc == 0) - { t1 = startn[arc]; - t = x[arc]; - if (t > 0) - { dfct[node] += t; - dfct[t1] -= t; - u[arc] = t; - x[arc] = 0; - } - else - t = u[arc]; - ddpos[t1] -= t; - ddneg[node] -= t; - } - /* Increase the reduced cost on all incoming arcs. */ - trc += delprc; - if ((trc < 0) && (trc > -nxtbrk)) - nxtbrk = -trc; - else if (trc == 0) - { /* Arc goes from active to balanced. Update the rate - * of dual ascent at node and at its neighbor. */ - ddneg[startn[arc]] += x[arc]; - ddpos[node] += x[arc]; - } - rc[arc] = trc; - } - /* If price of node can be increased further without - * decreasing the dual cost (even the dual cost doesn't - * increase), return to increase the price further. */ - if ((ddpos[node] <= 0) && (nxtbrk < large)) - { delprc = nxtbrk; - goto L53; - } - } - else if (ddneg[node] <= 0) - { /* Compute delprc, the stepsize to the next breakpoint in - * the dual cost as the price of node is decreased. - * [Since the reduced cost of all outgoing (resp., incoming) - * arcs will increase (resp., decrease) as the price of node - * is decreased, the next breakpoint is the minimum of the - * negative reduced cost on outgoing arcs and of the - * positive reduced cost on incoming arcs.] */ - delprc = large; - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { trc = rc[arc]; - if ((trc < 0) && (trc > -delprc)) - delprc = -trc; - } - for (arc = fin[node]; arc > 0; arc = nxtin[arc]) - { trc = rc[arc]; - if ((trc > 0) && (trc < delprc)) - delprc = trc; - } - /* If no breakpoint is left and dual ascent is still - * possible, the problem is infeasible. */ - if (delprc == large) - { if (ddneg[node] == 0) - continue; - return 5; - } - /* delprc is the stepsize to next breakpoint. Decrease - * price of node by delprc and compute the stepsize to the - * next breakpoint in the dual cost. */ -L63: nxtbrk = large; - /* Look at all arcs out of node. */ - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { trc = rc[arc]; - if (trc == 0) - { t1 = endn[arc]; - t = x[arc]; - if (t > 0) - { dfct[node] -= t; - dfct[t1] += t; - u[arc] = t; - x[arc] = 0; - } - else - t = u[arc]; - ddpos[node] -= t; - ddneg[t1] -= t; - } - /* Increase the reduced cost on all outgoing arcs. */ - trc += delprc; - if ((trc < 0) && (trc > -nxtbrk)) - nxtbrk = -trc; - else if (trc == 0) - { /* Arc goes from active to balanced. Update the rate - * of dual ascent at node and at its neighbor. */ - ddneg[node] += x[arc]; - ddpos[endn[arc]] += x[arc]; - } - rc[arc] = trc; - } - /* Look at all arcs into node. */ - for (arc = fin[node]; arc > 0; arc = nxtin[arc]) - { trc = rc[arc]; - if (trc == 0) - { t1 = startn[arc]; - t = u[arc]; - if (t > 0) - { dfct[node] -= t; - dfct[t1] += t; - x[arc] = t; - u[arc] = 0; - } - else - t = x[arc]; - ddneg[t1] -= t; - ddpos[node] -= t; - } - /* Decrease the reduced cost on all incoming arcs. */ - trc -= delprc; - if ((trc > 0) && (trc < nxtbrk)) - nxtbrk = trc; - else if (trc == 0) - { /* Arc goes from inactive to balanced. Update the rate - * of dual ascent at node and at its neighbor. */ - ddpos[startn[arc]] += u[arc]; - ddneg[node] += u[arc]; - } - rc[arc] = trc; - } - /* If price of node can be decreased further without - * decreasing the dual cost (even the dual cost doesn't - * increase), return to decrease the price further. */ - if ((ddneg[node] <= 0) && (nxtbrk < large)) - { delprc = nxtbrk; - goto L63; - } - } - } - /*--------------------------------------------------------------*/ -L70: /* Initialize tree data structure. */ - for (i = 1; i <= n; i++) - tfstou[i] = tfstin[i] = 0; - for (i = 1; i <= na; i++) - { tnxtin[i] = tnxtou[i] = -1; - if (rc[i] == 0) - { tnxtou[i] = tfstou[startn[i]]; - tfstou[startn[i]] = i; - tnxtin[i] = tfstin[endn[i]]; - tfstin[endn[i]] = i; - } - } -L90: /* Initialize other variables. */ - feasbl = true; - iter = 0; - nmultinode = 0; - num_augm = 0; - num_ascnt = 0; - num_passes = 0; - numnz = n; - numnz_new = 0; - svitch = false; - for (i = 1; i <= n; i++) - mark[i] = scan[i] = false; - nlabel = 0; - /* RELAX4 uses an adaptive strategy to decide whether to continue - * the scanning process after a multinode price change. - * The threshold parameter tp and ts that control this strategy - * are set in the next two lines. */ - tp = 10; - ts = n / 15; - /* Initialize the queue of nodes with nonzero deficit. */ - for (node = 1; node <= n - 1; node++) - nxtqueue[node] = node + 1; - nxtqueue[n] = 1; - node = lastqueue = n; - /*--------------------------------------------------------------*/ - /* Start the relaxation algorithm. */ -L100: /* Code for advancing the queue of nonzero deficit nodes. */ - prevnode = node; - node = nxtqueue[node]; - defcit = dfct[node]; - if (node == lastqueue) - { numnz = numnz_new; - numnz_new = 0; - lastqueue = prevnode; - num_passes++; - } - /* Code for deleting a node from the queue. */ - if (defcit == 0) - { nxtnode = nxtqueue[node]; - if (node == nxtnode) - return 0; - else - { nxtqueue[prevnode] = nxtnode; - nxtqueue[node] = 0; - node = nxtnode; - goto L100; - } - } - else - posit = (defcit > 0); - iter++; - numnz_new++; - if (posit) - { /* Attempt a single node iteration from node with positive - * deficit. */ - pchange = false; - indef = defcit; - delx = 0; - nb = 0; - /* Check outgoing (probably) balanced arcs from node. */ - for (arc = tfstou[node]; arc > 0; arc = tnxtou[arc]) - { if ((rc[arc] == 0) && (x[arc] > 0)) - { delx += x[arc]; - nb++; - save[nb] = arc; - } - } - /* Check incoming arcs. */ - for (arc = tfstin[node]; arc > 0; arc = tnxtin[arc]) - { if ((rc[arc] == 0) && (u[arc] > 0)) - { delx += u[arc]; - nb++; - save[nb] = -arc; - } - } - /* End of initial node scan. */ -L4018: /* If no price change is possible, exit. */ - if (delx > defcit) - { quit = (defcit < indef); - goto L4016; - } - /* RELAX4 searches along the ascent direction for the best - * price by checking the slope of the dual cost at successive - * break points. First, we compute the distance to the next - * break point. */ - delprc = large; - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { rdcost = rc[arc]; - if ((rdcost < 0) && (rdcost > -delprc)) - delprc = -rdcost; - } - for (arc = fin[node]; arc > 0; arc = nxtin[arc]) - { rdcost = rc[arc]; - if ((rdcost > 0) && (rdcost < delprc)) - delprc = rdcost; - } - /* Check if problem is infeasible. */ - if ((delx < defcit) && (delprc == large)) - { /* The dual cost can be decreased without bound. */ - return 6; - } - /* Skip flow adjustment if there is no flow to modify. */ - if (delx == 0) - goto L4014; - /* Adjust the flow on the balanced arcs incident to node to - * maintain complementary slackness after the price change. */ - for (j = 1; j <= nb; j++) - { arc = save[j]; - if (arc > 0) - { node2 = endn[arc]; - t1 = x[arc]; - dfct[node2] += t1; - if (nxtqueue[node2] == 0) - { nxtqueue[prevnode] = node2; - nxtqueue[node2] = node; - prevnode = node2; - } - u[arc] += t1; - x[arc] = 0; - } - else - { narc = -arc; - node2 = startn[narc]; - t1 = u[narc]; - dfct[node2] += t1; - if (nxtqueue[node2] == 0) - { nxtqueue[prevnode] = node2; - nxtqueue[node2] = node; - prevnode = node2; - } - x[narc] += t1; - u[narc] = 0; - } - } - defcit -= delx; -L4014: if (delprc == large) - { quit = true; - goto L4019; - } - /* Node corresponds to a dual ascent direction. Decrease the - * price of node by delprc and compute the stepsize to the next - * breakpoint in the dual cost. */ - nb = 0; - pchange = true; - dp = delprc; - delprc = large; - delx = 0; - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { rdcost = rc[arc] + dp; - rc[arc] = rdcost; - if (rdcost == 0) - { nb++; - save[nb] = arc; - delx += x[arc]; - } - if ((rdcost < 0) && (rdcost > -delprc)) - delprc = -rdcost; - } - for (arc = fin[node]; arc > 0; arc = nxtin[arc]) - { rdcost = rc[arc] - dp; - rc[arc] = rdcost; - if (rdcost == 0) - { nb++; - save[nb] = -arc; - delx += u[arc]; - } - if ((rdcost > 0) && (rdcost < delprc)) - delprc = rdcost; - } - /* Return to check if another price change is possible. */ - goto L4018; -L4016: /* Perform flow augmentation at node. */ - for (j = 1; j <= nb; j++) - { arc = save[j]; - if (arc > 0) - { /* arc is an outgoing arc from node. */ - node2 = endn[arc]; - t1 = dfct[node2]; - if (t1 < 0) - { /* Decrease the total deficit by decreasing flow of - * arc. */ - quit = true; - t2 = x[arc]; - dx = defcit; - if (dx > -t1) dx = -t1; - if (dx > t2) dx = t2; - defcit -= dx; - dfct[node2] = t1 + dx; - if (nxtqueue[node2] == 0) - { nxtqueue[prevnode] = node2; - nxtqueue[node2] = node; - prevnode = node2; - } - x[arc] = t2 - dx; - u[arc] += dx; - if (defcit == 0) - break; - } - } - else - { /* -arc is an incoming arc to node. */ - narc = -arc; - node2 = startn[narc]; - t1 = dfct[node2]; - if (t1 < 0) - { /* Decrease the total deficit by increasing flow of - * -arc. */ - quit = true; - t2 = u[narc]; - dx = defcit; - if (dx > -t1) dx = -t1; - if (dx > t2) dx = t2; - defcit -= dx; - dfct[node2] = t1 + dx; - if (nxtqueue[node2] == 0) - { nxtqueue[prevnode] = node2; - nxtqueue[node2] = node; - prevnode = node2; - } - x[narc] += dx; - u[narc] = t2 - dx; - if (defcit == 0) - break; - } - } - } -L4019: dfct[node] = defcit; - /* Reconstruct the linked list of balance arcs incident to this - * node. For each adjacent node, we add any newly balanced arcs - * to the list, but do not bother removing formerly balanced - * ones (they will be removed the next time each adjacent node - * is scanned). */ - if (pchange) - { arc = tfstou[node]; - tfstou[node] = 0; - while (arc > 0) - { nxtarc = tnxtou[arc]; - tnxtou[arc] = -1; - arc = nxtarc; - } - arc = tfstin[node]; - tfstin[node] = 0; - while (arc > 0) - { nxtarc = tnxtin[arc]; - tnxtin[arc] = -1; - arc = nxtarc; - } - /* Now add the currently balanced arcs to the list for this - * node (which is now empty), and the appropriate adjacent - * ones. */ - for (j = 1; j <= nb; j++) - { arc = save[j]; - if (arc < 0) - arc = -arc; - if (tnxtou[arc] < 0) - { tnxtou[arc] = tfstou[startn[arc]]; - tfstou[startn[arc]] = arc; - } - if (tnxtin[arc] < 0) - { tnxtin[arc] = tfstin[endn[arc]]; - tfstin[endn[arc]] = arc; - } - } - } - /* End of single node iteration for positive deficit node. */ - } - else - { /* Attempt a single node iteration from node with negative - * deficit. */ - pchange = false; - defcit = -defcit; - indef = defcit; - delx = 0; - nb = 0; - for (arc = tfstin[node]; arc > 0; arc = tnxtin[arc]) - { if ((rc[arc] == 0) && (x[arc] > 0)) - { delx += x[arc]; - nb++; - save[nb] = arc; - } - } - for (arc = tfstou[node]; arc > 0; arc = tnxtou[arc]) - { if ((rc[arc] == 0) && (u[arc] > 0)) - { delx += u[arc]; - nb++; - save[nb] = -arc; - } - } -L4028: if (delx >= defcit) - { quit = (defcit < indef); - goto L4026; - } - /* Compute distance to next breakpoint. */ - delprc = large; - for (arc = fin[node]; arc > 0; arc = nxtin[arc]) - { rdcost = rc[arc]; - if ((rdcost < 0) && (rdcost > -delprc)) - delprc = -rdcost; - } - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { rdcost = rc[arc]; - if ((rdcost > 0) && (rdcost < delprc)) - delprc = rdcost; - } - /* Check if problem is infeasible. */ - if ((delx < defcit) && (delprc == large)) - return 7; - if (delx == 0) - goto L4024; - /* Flow augmentation is possible. */ - for (j = 1; j <= nb; j++) - { arc = save[j]; - if (arc > 0) - { node2 = startn[arc]; - t1 = x[arc]; - dfct[node2] -= t1; - if (nxtqueue[node2] == 0) - { nxtqueue[prevnode] = node2; - nxtqueue[node2] = node; - prevnode = node2; - } - u[arc] += t1; - x[arc] = 0; - } - else - { narc = -arc; - node2 = endn[narc]; - t1 = u[narc]; - dfct[node2] -= t1; - if (nxtqueue[node2] == 0) - { nxtqueue[prevnode] = node2; - nxtqueue[node2] = node; - prevnode = node2; - } - x[narc] += t1; - u[narc] = 0; - } - } - defcit -= delx; -L4024: if (delprc == large) - { quit = true; - goto L4029; - } - /* Price increase at node is possible. */ - nb = 0; - pchange = true; - dp = delprc; - delprc = large; - delx = 0; - for (arc = fin[node]; arc > 0; arc = nxtin[arc]) - { rdcost = rc[arc] + dp; - rc[arc] = rdcost; - if (rdcost == 0) - { nb++; - save[nb] = arc; - delx += x[arc]; - } - if ((rdcost < 0) && (rdcost > -delprc)) - delprc = -rdcost; - } - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { rdcost = rc[arc] - dp; - rc[arc] = rdcost; - if (rdcost == 0) - { nb++; - save[nb] = -arc; - delx += u[arc]; - } - if ((rdcost > 0) && (rdcost < delprc)) - delprc = rdcost; - } - goto L4028; -L4026: /* Perform flow augmentation at node. */ - for (j = 1; j <= nb; j++) - { arc = save[j]; - if (arc > 0) - { /* arc is an incoming arc to node. */ - node2 = startn[arc]; - t1 = dfct[node2]; - if (t1 > 0) - { quit = true; - t2 = x[arc]; - dx = defcit; - if (dx > t1) dx = t1; - if (dx > t2) dx = t2; - defcit -= dx; - dfct[node2] = t1 - dx; - if (nxtqueue[node2] == 0) - { nxtqueue[prevnode] = node2; - nxtqueue[node2] = node; - prevnode = node2; - } - x[arc] = t2 - dx; - u[arc] += dx; - if (defcit == 0) - break; - } - } - else - { /* -arc is an outgoing arc from node. */ - narc = -arc; - node2 = endn[narc]; - t1 = dfct[node2]; - if (t1 > 0) - { quit = true; - t2 = u[narc]; - dx = defcit; - if (dx > t1) dx = t1; - if (dx > t2) dx = t2; - defcit -= dx; - dfct[node2] = t1 - dx; - if (nxtqueue[node2] == 0) - { nxtqueue[prevnode] = node2; - nxtqueue[node2] = node; - prevnode = node2; - } - x[narc] += dx; - u[narc] = t2 - dx; - if (defcit == 0) - break; - } - } - } -L4029: dfct[node] = -defcit; - /* Reconstruct the list of balanced arcs incident to node. */ - if (pchange) - { arc = tfstou[node]; - tfstou[node] = 0; - while (arc > 0) - { nxtarc = tnxtou[arc]; - tnxtou[arc] = -1; - arc = nxtarc; - } - arc = tfstin[node]; - tfstin[node] = 0; - while (arc > 0) - { nxtarc = tnxtin[arc]; - tnxtin[arc] = -1; - arc = nxtarc; - } - /* Now add the currently balanced arcs to the list for this - * node (which is now empty), and the appropriate adjacent - * ones. */ - for (j = 1; j <= nb; j++) - { arc = save[j]; - if (arc <= 0) - arc = -arc; - if (tnxtou[arc] < 0) - { tnxtou[arc] = tfstou[startn[arc]]; - tfstou[startn[arc]] = arc; - } - if (tnxtin[arc] < 0) - { tnxtin[arc] = tfstin[endn[arc]]; - tfstin[endn[arc]] = arc; - } - } - } - /* End of single node iteration for a negative deficit node. */ - } - if (quit || (num_passes <= 3)) - goto L100; - /* Do a multinode iteration from node. */ - nmultinode++; - /* If number of nonzero deficit nodes is small, continue labeling - * until a flow augmentation is done. */ - svitch = (numnz < tp); - /* Unmark nodes labeled earlier. */ - for (j = 1; j <= nlabel; j++) - { node2 = label[j]; - mark[node2] = scan[node2] = false; - } - /* Initialize labeling. */ - nlabel = 1; - label[1] = node; - mark[node] = true; - prdcsr[node] = 0; - /* Scan starting node. */ - scan[node] = true; - nscan = 1; - dm = dfct[node]; - delx = 0; - for (j = 1; j <= nb; j++) - { arc = save[j]; - if (arc > 0) - { if (posit) - node2 = endn[arc]; - else - node2 = startn[arc]; - if (!mark[node2]) - { nlabel++; - label[nlabel] = node2; - prdcsr[node2] = arc; - mark[node2] = true; - delx += x[arc]; - } - } - else - { narc = -arc; - if (posit) - node2 = startn[narc]; - else - node2 = endn[narc]; - if (!mark[node2]) - { nlabel++; - label[nlabel] = node2; - prdcsr[node2] = arc; - mark[node2] = true; - delx += u[narc]; - } - } - } -L4120:/* Start scanning a labeled but unscanned node. */ - nscan++; - /* Check to see if switch needs to be set to true so to continue - * scanning even after a price change. */ - svitch = svitch || ((nscan > ts) && (numnz < ts)); - /* Scanning will continue until either an overestimate of the - * residual capacity across the cut corresponding to the scanned - * set of nodes (called delx) exceeds the absolute value of the - * total deficit of the scanned nodes (called dm), or else an - * augmenting path is found. Arcs that are in the tree but are not - * balanced are removed as part of the scanning process. */ - i = label[nscan]; - scan[i] = true; - naugnod = 0; - if (posit) - { /* Scanning node i in case of positive deficit. */ - prvarc = 0; - arc = tfstou[i]; - while (arc > 0) - { /* arc is an outgoing arc from node. */ - if (rc[arc] == 0) - { if (x[arc] > 0) - { node2 = endn[arc]; - if (!mark[node2]) - { /* node2 is not labeled, so add node2 to the - labeled set. */ - prdcsr[node2] = arc; - if (dfct[node2] < 0) - { naugnod++; - save[naugnod] = node2; - } - nlabel++; - label[nlabel] = node2; - mark[node2] = true; - delx += x[arc]; - } - } - prvarc = arc; - arc = tnxtou[arc]; - } - else - { tmparc = arc; - arc = tnxtou[arc]; - tnxtou[tmparc] = -1; - if (prvarc == 0) - tfstou[i] = arc; - else - tnxtou[prvarc] = arc; - } - } - prvarc = 0; - arc = tfstin[i]; - while (arc > 0) - { /* arc is an incoming arc into node. */ - if (rc[arc] == 0) - { if (u[arc] > 0) - { node2 = startn[arc]; - if (!mark[node2]) - { /* node2 is not labeled, so add node2 to the - * labeled set. */ - prdcsr[node2] = -arc; - if (dfct[node2] < 0) - { naugnod++; - save[naugnod] = node2; - } - nlabel++; - label[nlabel] = node2; - mark[node2] = true; - delx += u[arc]; - } - } - prvarc = arc; - arc = tnxtin[arc]; - } - else - { tmparc = arc; - arc = tnxtin[arc]; - tnxtin[tmparc] = -1; - if (prvarc == 0) - tfstin[i] = arc; - else - tnxtin[prvarc] = arc; - } - } - /* Correct the residual capacity of the scanned node cut. */ - arc = prdcsr[i]; - if (arc > 0) - delx -= x[arc]; - else - delx -= u[-arc]; - /* End of scanning of node i for positive deficit case. */ - } - else - { /* Scanning node i for negative deficit case. */ - prvarc = 0; - arc = tfstin[i]; - while (arc > 0) - { if (rc[arc] == 0) - { if (x[arc] > 0) - { node2 = startn[arc]; - if (!mark[node2]) - { prdcsr[node2] = arc; - if (dfct[node2] > 0) - { naugnod++; - save[naugnod] = node2; - } - nlabel++; - label[nlabel] = node2; - mark[node2] = true; - delx += x[arc]; - } - } - prvarc = arc; - arc = tnxtin[arc]; - } - else - { tmparc = arc; - arc = tnxtin[arc]; - tnxtin[tmparc] = -1; - if (prvarc == 0) - tfstin[i] = arc; - else - tnxtin[prvarc] = arc; - } - } - prvarc = 0; - arc = tfstou[i]; - while (arc > 0) - { if (rc[arc] == 0) - { if (u[arc] > 0) - { node2 = endn[arc]; - if (!mark[node2]) - { prdcsr[node2] = -arc; - if (dfct[node2] > 0) - { naugnod++; - save[naugnod] = node2; - } - nlabel++; - label[nlabel] = node2; - mark[node2] = true; - delx += u[arc]; - } - } - prvarc = arc; - arc = tnxtou[arc]; - } - else - { tmparc = arc; - arc = tnxtou[arc]; - tnxtou[tmparc] = -1; - if (prvarc == 0) - tfstou[i] = arc; - else - tnxtou[prvarc] = arc; - } - } - arc = prdcsr[i]; - if (arc > 0) - delx -= x[arc]; - else - delx -= u[-arc]; - } - /* Add deficit of node scanned to dm. */ - dm += dfct[i]; - /* Check if the set of scanned nodes correspond to a dual ascent - * direction; if yes, perform a price adjustment step, otherwise - * continue labeling. */ - if (nscan < nlabel) - { if (svitch) - goto L4210; - if ((delx >= dm) && (delx >= -dm)) - goto L4210; - } - /* Try a price change. - * [Note that since delx - abs(dm) is an overestimate of ascent - * slope, we may occasionally try a direction that is not an - * ascent direction. In this case the ascnt routines return with - * quit = false, so we continue labeling nodes.] */ - if (posit) - { ascnt1(csa, dm, &delx, &nlabel, &feasbl, &svitch, nscan, node, - &prevnode); - num_ascnt++; - } - else - { ascnt2(csa, dm, &delx, &nlabel, &feasbl, &svitch, nscan, node, - &prevnode); - num_ascnt++; - } - if (!feasbl) - return 8; - if (!svitch) - goto L100; - /* Store those newly labeled nodes to which flow augmentation is - * possible. */ - naugnod = 0; - for (j = nscan + 1; j <= nlabel; j++) - { node2 = label[j]; - if (posit && (dfct[node2] < 0)) - { naugnod++; - save[naugnod] = node2; - } - else if ((!posit) && (dfct[node2] > 0)) - { naugnod++; - save[naugnod] = node2; - } - } -L4210:/* Check if flow augmentation is possible. If not, return to scan - * another node. */ - if (naugnod == 0) - goto L4120; - for (j = 1; j <= naugnod; j++) - { num_augm++; - augnod = save[j]; - if (posit) - { /* Do the augmentation from node with positive deficit. */ - dx = -dfct[augnod]; - ib = augnod; - while (ib != node) - { arc = prdcsr[ib]; - if (arc > 0) - { if (dx > x[arc]) dx = x[arc]; - ib = startn[arc]; - } - else - { if (dx > u[-arc]) dx = u[-arc]; - ib = endn[-arc]; - } - } - if (dx > dfct[node]) dx = dfct[node]; - if (dx > 0) - { /* Increase (decrease) the flow of all forward (backward) - * arcs in the flow augmenting path. Adjust node deficit - * accordingly. */ - if (nxtqueue[augnod] == 0) - { nxtqueue[prevnode] = augnod; - nxtqueue[augnod] = node; - prevnode = augnod; - } - dfct[augnod] += dx; - dfct[node] -= dx; - ib = augnod; - while (ib != node) - { arc = prdcsr[ib]; - if (arc > 0) - { x[arc] -= dx; - u[arc] += dx; - ib = startn[arc]; - } - else - { narc = -arc; - x[narc] += dx; - u[narc] -= dx; - ib = endn[narc]; - } - } - } - } - else - { /* Do the augmentation from node with negative deficit. */ - dx = dfct[augnod]; - ib = augnod; - while (ib != node) - { arc = prdcsr[ib]; - if (arc > 0) - { if (dx > x[arc]) dx = x[arc]; - ib = endn[arc]; - } - else - { if (dx > u[-arc]) dx = u[-arc]; - ib = startn[-arc]; - } - } - if (dx > -dfct[node]) dx = -dfct[node]; - if (dx > 0) - { /* Update the flow and deficits. */ - if (nxtqueue[augnod] == 0) - { nxtqueue[prevnode] = augnod; - nxtqueue[augnod] = node; - prevnode = augnod; - } - dfct[augnod] -= dx; - dfct[node] += dx; - ib = augnod; - while (ib != node) - { arc = prdcsr[ib]; - if (arc > 0) - { x[arc] -= dx; - u[arc] += dx; - ib = endn[arc]; - } - else - { narc = -arc; - x[narc] += dx; - u[narc] -= dx; - ib = startn[narc]; - } - } - } - } - if (dfct[node] == 0) - goto L100; - if (dfct[augnod] != 0) - svitch = false; - } - /* If node still has nonzero deficit and all newly labeled nodes - * have same sign for their deficit as node, we can continue - * labeling. In this case, continue labeling only when flow - * augmentation is done relatively infrequently. */ - if (svitch && (iter > 8 * num_augm)) - goto L4120; - /* Return to do another relaxation iteration. */ - goto L100; -# undef nmultinode -# undef iter -# undef num_augm -# undef num_ascnt -# undef nsp -} - -/*********************************************************************** -* NAME -* -* relax4_inidat - construct linked lists for network topology -* -* PURPOSE -* -* This routine constructs two linked lists for the network topology: -* one list (given by fou, nxtou) for the outgoing arcs of nodes and -* one list (given by fin, nxtin) for the incoming arcs of nodes. These -* two lists are required by RELAX4. -* -* INPUT PARAMETERS -* -* n = number of nodes -* na = number of arcs -* startn[j] = starting node for arc j, j = 1,...,na -* endn[j] = ending node for arc j, j = 1,...,na -* -* OUTPUT PARAMETERS -* -* fou[i] = first arc out of node i, i = 1,...,n -* nxtou[j] = next arc out of the starting node of arc j, j = 1,...,na -* fin[i] = first arc into node i, i = 1,...,n -* nxtin[j] = next arc into the ending node of arc j, j = 1,...,na -* -* WORKING PARAMETERS -* -* tempin[1+n], tempou[1+n] */ - -void relax4_inidat(struct relax4_csa *csa) -{ /* input parameters */ - int n = csa->n; - int na = csa->na; - int *startn = csa->startn; - int *endn = csa->endn; - /* output parameters */ - int *fou = csa->fou; - int *nxtou = csa->nxtou; - int *fin = csa->fin; - int *nxtin = csa->nxtin; - /* working parameters */ - int *tempin = csa->label; - int *tempou = csa->prdcsr; - /* local variables */ - int i, i1, i2; - for (i = 1; i <= n; i++) - { fin[i] = fou[i] = 0; - tempin[i] = tempou[i] = 0; - } - for (i = 1; i <= na; i++) - { nxtin[i] = nxtou[i] = 0; - i1 = startn[i]; - i2 = endn[i]; - if (fou[i1] != 0) - nxtou[tempou[i1]] = i; - else - fou[i1] = i; - tempou[i1] = i; - if (fin[i2] != 0) - nxtin[tempin[i2]] = i; - else - fin[i2] = i; - tempin[i2] = i; - } - return; -} - -/*********************************************************************** -* NAME -* -* ascnt1 - multi-node price adjustment for positive deficit case -* -* PURPOSE -* -* This subroutine performs the multi-node price adjustment step for -* the case where the scanned nodes have positive deficit. It first -* checks if decreasing the price of the scanned nodes increases the -* dual cost. If yes, then it decreases the price of all scanned nodes. -* There are two possibilities for price decrease: if switch = true, -* then the set of scanned nodes corresponds to an elementary direction -* of maximal rate of ascent, in which case the price of all scanned -* nodes are decreased until the next breakpoint in the dual cost is -* encountered. At this point, some arc becomes balanced and more -* node(s) are added to the labeled set and the subroutine is exited. -* If switch = false, then the price of all scanned nodes are decreased -* until the rate of ascent becomes negative (this corresponds to the -* price adjustment step in which both the line search and the -* degenerate ascent iteration are implemented). -* -* INPUT PARAMETERS -* -* dm = total deficit of scanned nodes -* switch = true if labeling is to continue after price change -* nscan = number of scanned nodes -* curnode = most recently scanned node -* n = number of nodes -* na = number of arcs -* large = a very large integer to represent infinity (see note 3) -* startn[i] = starting node for the i-th arc, i = 1,...,na -* endn[i] = ending node for the i-th arc, i = 1,...,na -* fou[i] = first arc leaving i-th node, i = 1,...,n -* nxtou[i] = next arc leaving the starting node of j-th arc, -* i = 1,...,na -* fin[i] = first arc entering i-th node, i = 1,...,n -* nxtin[i] = next arc entering the ending node of j-th arc, -* i = 1,...,na -* -* UPDATED PARAMETERS -* -* delx = a lower estimate of the total flow on balanced arcs in -* the scanned-nodes cut -* nlabel = number of labeled nodes -* feasbl = false if problem is found to be infeasible -* prevnode = the node before curnode in queue -* rc[j] = reduced cost of arc j, j = 1,...,na -* u[j] = residual capacity of arc j, j = 1,...,na -* x[j] = flow on arc j, j = 1,...,na -* dfct[i] = deficit at node i, i = 1,...,n -* label[k] = k-th node labeled, k = 1,...,nlabel -* prdcsr[i] = predecessor of node i in tree of labeled nodes (0 if i -* is unlabeled), i = 1,...,n -* tfstou[i] = first balanced arc out of node i, i = 1,...,n -* tnxtou[j] = next balanced arc out of the starting node of arc j, -* j = 1,...,na -* tfstin[i] = first balanced arc into node i, i = 1,...,n -* tnxtin[j] = next balanced arc into the ending node of arc j, -* j = 1,...,na -* nxtqueue[i] = node following node i in the fifo queue (0 if node is -* not in the queue), i = 1,...,n -* scan[i] = true if node i is scanned, i = 1,...,n -* mark[i] = true if node i is labeled, i = 1,...,n -* -* WORKING PARAMETERS -* -* save[1+na] */ - -static void ascnt1(struct relax4_csa *csa, int dm, int *delx, - int *nlabel, int *feasbl, int *svitch, int nscan, int curnode, - int *prevnode) -{ /* input parameters */ - int n = csa->n; - /* int na = csa->na; */ - int large = csa->large; - int *startn = csa->startn; - int *endn = csa->endn; - int *fou = csa->fou; - int *nxtou = csa->nxtou; - int *fin = csa->fin; - int *nxtin = csa->nxtin; - /* updated parameters */ -# define delx (*delx) -# define nlabel (*nlabel) -# define feasbl (*feasbl) -# define svitch (*svitch) -# define prevnode (*prevnode) - int *rc = csa->rc; - int *u = csa->u; - int *x = csa->x; - int *dfct = csa->dfct; - int *label = csa->label; - int *prdcsr = csa->prdcsr; - int *tfstou = csa->tfstou; - int *tnxtou = csa->tnxtou; - int *tfstin = csa->tfstin; - int *tnxtin = csa->tnxtin; - int *nxtqueue = csa->nxtqueue; - char *scan = csa->scan; - char *mark = csa->mark; - int *save = csa->save; - /* local variables */ - int arc, delprc, dlx, i, j, nb, node, node2, nsave, rdcost, t1, - t2, t3; - /* Store the arcs between the set of scanned nodes and its - * complement in save and compute delprc, the stepsize to the next - * breakpoint in the dual cost in the direction of decreasing - * prices of the scanned nodes. - * [The arcs are stored into save by looking at the arcs incident - * to either the set of scanned nodes or its complement, depending - * on whether nscan > n/2 or not. This improves the efficiency of - * storing.] */ - delprc = large; - dlx = 0; - nsave = 0; - if (nscan <= n / 2) - { for (i = 1; i <= nscan; i++) - { node = label[i]; - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { /* arc points from scanned node to an unscanned node. */ - node2 = endn[arc]; - if (!scan[node2]) - { nsave++; - save[nsave] = arc; - rdcost = rc[arc]; - if ((rdcost == 0) && (prdcsr[node2] != arc)) - dlx += x[arc]; - if ((rdcost < 0) && (rdcost > -delprc)) - delprc = -rdcost; - } - } - for (arc = fin[node]; arc > 0; arc = nxtin[arc]) - { /* arc points from unscanned node to scanned node. */ - node2 = startn[arc]; - if (!scan[node2]) - { nsave++; - save[nsave] = -arc; - rdcost = rc[arc]; - if ((rdcost == 0) && (prdcsr[node2] != -arc)) - dlx += u[arc]; - if ((rdcost > 0) && (rdcost < delprc)) - delprc = rdcost; - } - } - } - } - else - { for (node = 1; node <= n; node++) - { if (scan[node]) - continue; - for (arc = fin[node]; arc > 0; arc = nxtin[arc]) - { node2 = startn[arc]; - if (scan[node2]) - { nsave++; - save[nsave] = arc; - rdcost = rc[arc]; - if ((rdcost == 0) && (prdcsr[node] != arc)) - dlx += x[arc]; - if ((rdcost < 0) && (rdcost > -delprc)) - delprc = -rdcost; - } - } - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { node2 = endn[arc]; - if (scan[node2]) - { nsave++; - save[nsave] = -arc; - rdcost = rc[arc]; - if ((rdcost == 0) && (prdcsr[node] != -arc)) - dlx += u[arc]; - if ((rdcost > 0) && (rdcost < delprc)) - delprc = rdcost; - } - } - } - } - /* Check if the set of scanned nodes truly corresponds to a dual - * ascent direction. [Here delx + dlx is the exact sum of the flow - * on arcs from the scanned set to the unscanned set plus the - * (capacity - flow) on arcs from the unscanned set to the scanned - * set.] If this were not the case, set switch to true and exit - * subroutine. */ - if ((!svitch) && (delx + dlx >= dm)) - { svitch = true; - return; - } - delx += dlx; -L4: /* Check that the problem is feasible. */ - if (delprc == large) - { /* We can increase the dual cost without bound, so the primal - * problem is infeasible. */ - feasbl = false; - return; - } - /* Decrease the prices of the scanned nodes, add more nodes to - * the labeled set and check if a newly labeled node has negative - * deficit. */ - if (svitch) - { for (i = 1; i <= nsave; i++) - { arc = save[i]; - if (arc > 0) - { rc[arc] += delprc; - if (rc[arc] == 0) - { node2 = endn[arc]; - if (tnxtou[arc] < 0) - { tnxtou[arc] = tfstou[startn[arc]]; - tfstou[startn[arc]] = arc; - } - if (tnxtin[arc] < 0) - { tnxtin[arc] = tfstin[node2]; - tfstin[node2] = arc; - } - if (!mark[node2]) - { prdcsr[node2] = arc; - nlabel++; - label[nlabel] = node2; - mark[node2] = true; - } - } - } - else - { arc = -arc; - rc[arc] -= delprc; - if (rc[arc] == 0) - { node2 = startn[arc]; - if (tnxtou[arc] < 0) - { tnxtou[arc] = tfstou[node2]; - tfstou[node2] = arc; - } - if (tnxtin[arc] < 0) - { tnxtin[arc] = tfstin[endn[arc]]; - tfstin[endn[arc]] = arc; - } - if (!mark[node2]) - { prdcsr[node2] = -arc; - nlabel++; - label[nlabel] = node2; - mark[node2] = true; - } - } - } - } - return; - } - else - { /* Decrease the prices of the scanned nodes by delprc. Adjust - * flow to maintain complementary slackness with the prices. */ - nb = 0; - for (i = 1; i <= nsave; i++) - { arc = save[i]; - if (arc > 0) - { t1 = rc[arc]; - if (t1 == 0) - { t2 = x[arc]; - t3 = startn[arc]; - dfct[t3] -= t2; - if (nxtqueue[t3] == 0) - { nxtqueue[prevnode] = t3; - nxtqueue[t3] = curnode; - prevnode = t3; - } - t3 = endn[arc]; - dfct[t3] += t2; - if (nxtqueue[t3] == 0) - { nxtqueue[prevnode] = t3; - nxtqueue[t3] = curnode; - prevnode = t3; - } - u[arc] += t2; - x[arc] = 0; - } - rc[arc] = t1 + delprc; -#if 0 /* by mao; 26/IV-2013 */ - if (rc[arc] == 0) -#else - if (rc[arc] == 0 && nb < n) -#endif - { delx += x[arc]; - nb++; - prdcsr[nb] = arc; - } - } - else - { arc = -arc; - t1 = rc[arc]; - if (t1 == 0) - { t2 = u[arc]; - t3 = startn[arc]; - dfct[t3] += t2; - if (nxtqueue[t3] == 0) - { nxtqueue[prevnode] = t3; - nxtqueue[t3] = curnode; - prevnode = t3; - } - t3 = endn[arc]; - dfct[t3] -= t2; - if (nxtqueue[t3] == 0) - { nxtqueue[prevnode] = t3; - nxtqueue[t3] = curnode; - prevnode = t3; - } - x[arc] += t2; - u[arc] = 0; - } - rc[arc] = t1 - delprc; -#if 0 /* by mao; 26/IV-2013 */ - if (rc[arc] == 0) -#else - if (rc[arc] == 0 && nb < n) -#endif - { delx += u[arc]; - nb++; - prdcsr[nb] = arc; - } - } - } - } - if (delx <= dm) - { /* The set of scanned nodes still corresponds to a dual - * (possibly degenerate) ascent direction. Compute the stepsize - * delprc to the next breakpoint in the dual cost. */ - delprc = large; - for (i = 1; i <= nsave; i++) - { arc = save[i]; - if (arc > 0) - { rdcost = rc[arc]; - if ((rdcost < 0) && (rdcost > -delprc)) - delprc = -rdcost; - } - else - { arc = -arc; - rdcost = rc[arc]; - if ((rdcost > 0) && (rdcost < delprc)) - delprc = rdcost; - } - } - if ((delprc != large) || (delx < dm)) - goto L4; - } - /* Add new balanced arcs to the superset of balanced arcs. */ - for (i = 1; i <= nb; i++) - { arc = prdcsr[i]; - if (tnxtin[arc] == -1) - { j = endn[arc]; - tnxtin[arc] = tfstin[j]; - tfstin[j] = arc; - } - if (tnxtou[arc] == -1) - { j = startn[arc]; - tnxtou[arc] = tfstou[j]; - tfstou[j] = arc; - } - } - return; -# undef delx -# undef nlabel -# undef feasbl -# undef svitch -# undef prevnode -} - -/*********************************************************************** -* NAME -* -* ascnt2 - multi-node price adjustment for negative deficit case -* -* PURPOSE -* -* This routine is analogous to ascnt1 but for the case where the -* scanned nodes have negative deficit. */ - -static void ascnt2(struct relax4_csa *csa, int dm, int *delx, - int *nlabel, int *feasbl, int *svitch, int nscan, int curnode, - int *prevnode) -{ /* input parameters */ - int n = csa->n; - /* int na = csa->na; */ - int large = csa->large; - int *startn = csa->startn; - int *endn = csa->endn; - int *fou = csa->fou; - int *nxtou = csa->nxtou; - int *fin = csa->fin; - int *nxtin = csa->nxtin; - /* updated parameters */ -# define delx (*delx) -# define nlabel (*nlabel) -# define feasbl (*feasbl) -# define svitch (*svitch) -# define prevnode (*prevnode) - int *rc = csa->rc; - int *u = csa->u; - int *x = csa->x; - int *dfct = csa->dfct; - int *label = csa->label; - int *prdcsr = csa->prdcsr; - int *tfstou = csa->tfstou; - int *tnxtou = csa->tnxtou; - int *tfstin = csa->tfstin; - int *tnxtin = csa->tnxtin; - int *nxtqueue = csa->nxtqueue; - char *scan = csa->scan; - char *mark = csa->mark; - int *save = csa->save; - /* local variables */ - int arc, delprc, dlx, i, j, nb, node, node2, nsave, rdcost, t1, - t2, t3; - /* Store the arcs between the set of scanned nodes and its - * complement in save and compute delprc, the stepsize to the next - * breakpoint in the dual cost in the direction of increasing - * prices of the scanned nodes. */ - delprc = large; - dlx = 0; - nsave = 0; - if (nscan <= n / 2) - { for (i = 1; i <= nscan; i++) - { node = label[i]; - for (arc = fin[node]; arc > 0; arc = nxtin[arc]) - { node2 = startn[arc]; - if (!scan[node2]) - { nsave++; - save[nsave] = arc; - rdcost = rc[arc]; - if ((rdcost == 0) && (prdcsr[node2] != arc)) - dlx += x[arc]; - if ((rdcost < 0) && (rdcost > -delprc)) - delprc = -rdcost; - } - } - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { node2 = endn[arc]; - if (!scan[node2]) - { nsave++; - save[nsave] = -arc; - rdcost = rc[arc]; - if ((rdcost == 0) && (prdcsr[node2] != -arc)) - dlx += u[arc]; - if ((rdcost > 0) && (rdcost < delprc)) - delprc = rdcost; - } - } - } - } - else - { for (node = 1; node <= n; node++) - { if (scan[node]) - continue; - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { node2 = endn[arc]; - if (scan[node2]) - { nsave++; - save[nsave] = arc; - rdcost = rc[arc]; - if ((rdcost == 0) && (prdcsr[node] != arc)) - dlx += x[arc]; - if ((rdcost < 0) && (rdcost > -delprc)) - delprc = -rdcost; - } - } - for (arc = fin[node]; arc > 0; arc = nxtin[arc]) - { node2 = startn[arc]; - if (scan[node2]) - { nsave++; - save[nsave] = -arc; - rdcost = rc[arc]; - if ((rdcost == 0) && (prdcsr[node] != -arc)) - dlx += u[arc]; - if ((rdcost > 0) && (rdcost < delprc)) - delprc = rdcost; - } - } - } - } - if ((!svitch) && (delx + dlx >= -dm)) - { svitch = true; - return; - } - delx += dlx; - /* Check that the problem is feasible. */ -L4: if (delprc == large) - { feasbl = false; - return; - } - /* Increase the prices of the scanned nodes, add more nodes to - * the labeled set and check if a newly labeled node has positive - * deficit. */ - if (svitch) - { for (i = 1; i <= nsave; i++) - { arc = save[i]; - if (arc > 0) - { rc[arc] += delprc; - if (rc[arc] == 0) - { node2 = startn[arc]; - if (tnxtou[arc] < 0) - { tnxtou[arc] = tfstou[node2]; - tfstou[node2] = arc; - } - if (tnxtin[arc] < 0) - { tnxtin[arc] = tfstin[endn[arc]]; - tfstin[endn[arc]] = arc; - } - if (!mark[node2]) - { prdcsr[node2] = arc; - nlabel++; - label[nlabel] = node2; - mark[node2] = true; - } - } - } - else - { arc = -arc; - rc[arc] -= delprc; - if (rc[arc] == 0) - { node2 = endn[arc]; - if (tnxtou[arc] < 0) - { tnxtou[arc] = tfstou[startn[arc]]; - tfstou[startn[arc]] = arc; - } - if (tnxtin[arc] < 0) - { tnxtin[arc] = tfstin[node2]; - tfstin[node2] = arc; - } - if (!mark[node2]) - { prdcsr[node2] = -arc; - nlabel++; - label[nlabel] = node2; - mark[node2] = true; - } - } - } - } - return; - } - else - { nb = 0; - for (i = 1; i <= nsave; i++) - { arc = save[i]; - if (arc > 0) - { t1 = rc[arc]; - if (t1 == 0) - { t2 = x[arc]; - t3 = startn[arc]; - dfct[t3] -= t2; - if (nxtqueue[t3] == 0) - { nxtqueue[prevnode] = t3; - nxtqueue[t3] = curnode; - prevnode = t3; - } - t3 = endn[arc]; - dfct[t3] += t2; - if (nxtqueue[t3] == 0) - { nxtqueue[prevnode] = t3; - nxtqueue[t3] = curnode; - prevnode = t3; - } - u[arc] += t2; - x[arc] = 0; - } - rc[arc] = t1 + delprc; -#if 0 /* by mao; 26/IV-2013 */ - if (rc[arc] == 0) -#else - if (rc[arc] == 0 && nb < n) -#endif - { delx += x[arc]; - nb++; - prdcsr[nb] = arc; - } - } - else - { arc = -arc; - t1 = rc[arc]; - if (t1 == 0) - { t2 = u[arc]; - t3 = startn[arc]; - dfct[t3] += t2; - if (nxtqueue[t3] == 0) - { nxtqueue[prevnode] = t3; - nxtqueue[t3] = curnode; - prevnode = t3; - } - t3 = endn[arc]; - dfct[t3] -= t2; - if (nxtqueue[t3] == 0) - { nxtqueue[prevnode] = t3; - nxtqueue[t3] = curnode; - prevnode = t3; - } - x[arc] += t2; - u[arc] = 0; - } - rc[arc] = t1 - delprc; -#if 0 /* by mao; 26/IV-2013 */ - if (rc[arc] == 0) -#else - if (rc[arc] == 0 && nb < n) -#endif - { delx += u[arc]; - nb++; - prdcsr[nb] = arc; - } - } - } - } - if (delx <= -dm) - { delprc = large; - for (i = 1; i <= nsave; i++) - { arc = save[i]; - if (arc > 0) - { rdcost = rc[arc]; - if ((rdcost < 0) && (rdcost > -delprc)) - delprc = -rdcost; - } - else - { arc = -arc; - rdcost = rc[arc]; - if ((rdcost > 0) && (rdcost < delprc)) - delprc = rdcost; - } - } - if ((delprc != large) || (delx < -dm)) - goto L4; - } - /* Add new balanced arcs to the superset of balanced arcs. */ - for (i = 1; i <= nb; i++) - { arc = prdcsr[i]; - if (tnxtin[arc] == -1) - { j = endn[arc]; - tnxtin[arc] = tfstin[j]; - tfstin[j] = arc; - } - if (tnxtou[arc] == -1) - { j = startn[arc]; - tnxtou[arc] = tfstou[j]; - tfstou[j] = arc; - } - } - return; -# undef delx -# undef nlabel -# undef feasbl -# undef svitch -# undef prevnode -} - -/*********************************************************************** -* NAME -* -* auction - compute good initial flow and prices -* -* PURPOSE -* -* This subroutine uses a version of the auction algorithm for min -* cost network flow to compute a good initial flow and prices for the -* problem. -* -* INPUT PARAMETERS -* -* n = number of nodes -* na = number of arcs -* large = a very large integer to represent infinity (see note 3) -* startn[i] = starting node for the i-th arc, i = 1,...,na -* endn[i] = ending node for the i-th arc, i = 1,...,na -* fou[i] = first arc leaving i-th node, i = 1,...,n -* nxtou[i] = next arc leaving the starting node of j-th arc, -* i = 1,...,na -* fin[i] = first arc entering i-th node, i = 1,...,n -* nxtin[i] = next arc entering the ending node of j-th arc, -* i = 1,...,na -* -* UPDATED PARAMETERS -* -* rc[j] = reduced cost of arc j, j = 1,...,na -* u[j] = residual capacity of arc j, j = 1,...,na -* x[j] = flow on arc j, j = 1,...,na -* dfct[i] = deficit at node i, i = 1,...,n -* -* OUTPUT PARAMETERS -* -* nsp = number of auction/shortest path iterations -* -* WORKING PARAMETERS -* -* p[1+n], prdcsr[1+n], save[1+na], fpushf[1+n], nxtpushf[1+na], -* fpushb[1+n], nxtpushb[1+na], nxtqueue[1+n], extend_arc[1+n], -* sb_level[1+n], sb_arc[1+n], path_id[1+n] -* -* RETURNS -* -* 0 = normal return -* 1 = problem is found to be infeasible */ - -static int auction(struct relax4_csa *csa) -{ /* input parameters */ - int n = csa->n; - int na = csa->na; - int large = csa->large; - int *startn = csa->startn; - int *endn = csa->endn; - int *fou = csa->fou; - int *nxtou = csa->nxtou; - int *fin = csa->fin; - int *nxtin = csa->nxtin; - /* updated parameters */ -# define crash (csa->crash) - int *rc = csa->rc; - int *u = csa->u; - int *x = csa->x; - int *dfct = csa->dfct; - /* output parameters */ -# define nsp (csa->nsp) - /* working parameters */ - int *p = csa->label; - int *prdcsr = csa->prdcsr; - int *save = csa->save; - int *fpushf = csa->tfstou; - int *nxtpushf = csa->tnxtou; - int *fpushb = csa->tfstin; - int *nxtpushb = csa->tnxtin; - int *nxtqueue = csa->nxtqueue; - int *extend_arc = csa->extend_arc; - int *sb_level = csa->sb_level; - int *sb_arc = csa->sb_arc; - char *path_id = csa->mark; - /* local variables */ - int arc, bstlevel, end, eps, extarc, factor, flow, i, incr, - last, lastqueue, maxcost, mincost, nas, naug, new_level, node, - nolist, num_passes, nxtnode, pass, pend, pr_term, prd, - prevarc, prevlevel, prevnode, pstart, pterm, rdcost, red_cost, - resid, root, secarc, seclevel, start, term, thresh_dfct; - /* start initialization using auction */ - naug = 0; - pass = 0; - thresh_dfct = 0; - /* factor determines by how much epsilon is reduced at each - * minimization */ - factor = 3; - /* num_passes determines how many auction scaling phases are - * performed */ - num_passes = 1; - /* set arc flows to satisfy cs and calculate maxcost and - * mincost */ - maxcost = -large; - mincost = large; - for (arc = 1; arc <= na; arc++) - { start = startn[arc]; - end = endn[arc]; - rdcost = rc[arc]; - if (maxcost < rdcost) - maxcost = rdcost; - if (mincost > rdcost) - mincost = rdcost; - if (rdcost < 0) - { dfct[start] += u[arc]; - dfct[end] -= u[arc]; - x[arc] = u[arc]; - u[arc] = 0; - } - else - x[arc] = 0; - } - /* set initial epsilon */ - if ((maxcost - mincost) >= 8) - eps = (maxcost - mincost) / 8; - else - eps = 1; - /* set initial prices to zero */ - for (node = 1; node <= n; node++) - p[node] = 0; - /* Initialization using auction/shortest paths. */ -L100: /* Start of the first scaling phase. */ - pass++; - if ((pass == num_passes) || (eps == 1)) - crash = 0; - nolist = 0; - /* construct list of positive surplus nodes and queue of negative - * surplus nodes */ - for (node = 1; node <= n; node++) - { prdcsr[node] = 0; - path_id[node] = false; - extend_arc[node] = 0; - sb_level[node] = -large; - nxtqueue[node] = node + 1; - if (dfct[node] > 0) - { nolist++; - save[nolist] = node; - } - } - nxtqueue[n] = 1; - root = 1; - prevnode = lastqueue = n; - /* initialization with down iterations for negative surplus - * nodes */ - for (i = 1; i <= nolist; i++) - { node = save[i]; - nsp++; - /* build the list of arcs w/ room for pushing flow and find - * proper price for down iteration */ - bstlevel = -large; - fpushf[node] = 0; - for (arc = fou[node]; arc > 0; arc = nxtou[arc]) - { if (u[arc] > 0) - { if (fpushf[node] == 0) - { fpushf[node] = arc; - nxtpushf[arc] = 0; - last = arc; - } - else - { nxtpushf[last] = arc; - nxtpushf[arc] = 0; - last = arc; - } - } - if (x[arc] > 0) - { new_level = p[endn[arc]] + rc[arc]; - if (new_level > bstlevel) - { bstlevel = new_level; - extarc = arc; - } - } - } - fpushb[node] = 0; - for (arc = fin[node]; arc > 0; arc = nxtin[arc]) - { if (x[arc] > 0) - { if (fpushb[node] == 0) - { fpushb[node] = arc; - nxtpushb[arc] = 0; - last = arc; - } - else - { nxtpushb[last] = arc; - nxtpushb[arc] = 0; - last = arc; - } - } - if (u[arc] > 0) - { new_level = p[startn[arc]] - rc[arc]; - if (new_level > bstlevel) - { bstlevel = new_level; - extarc = -arc; - } - } - } - extend_arc[node] = extarc; - p[node] = bstlevel - eps; - } -L200: /* Start the augmentation cycles of the new scaling phase. */ - if (dfct[root] >= thresh_dfct) - goto L3000; - term = root; - path_id[root] = true; -L500: /* Main forward algorithm with root as origin. */ - /* start of a new forward iteration */ - pterm = p[term]; - extarc = extend_arc[term]; - if (extarc == 0) - { /* build the list of arcs w/ room for pushing flow */ - fpushf[term] = 0; - for (arc = fou[term]; arc > 0; arc = nxtou[arc]) - { if (u[arc] > 0) - { if (fpushf[term] == 0) - { fpushf[term] = arc; - nxtpushf[arc] = 0; - last = arc; - } - else - { nxtpushf[last] = arc; - nxtpushf[arc] = 0; - last = arc; - } - } - } - fpushb[term] = 0; - for (arc = fin[term]; arc > 0; arc = nxtin[arc]) - { if (x[arc] > 0) - { if (fpushb[term] == 0) - { fpushb[term] = arc; - nxtpushb[arc] = 0; - last = arc; - } - else - { nxtpushb[last] = arc; - nxtpushb[arc] = 0; - last = arc; - } - } - } - goto L600; - } - /* speculative path extension attempt */ - /* note: arc > 0 means that arc is oriented from the root to the - * destinations - * arc < 0 means that arc is oriented from the destinations to the - * root - * extarc = 0 or prdarc = 0, means the extension arc or the - * predecessor arc, respectively, has not been established */ - if (extarc > 0) - { if (u[extarc] == 0) - { seclevel = sb_level[term]; - goto L580; - } - end = endn[extarc]; - bstlevel = p[end] + rc[extarc]; - if (pterm >= bstlevel) - { if (path_id[end]) - goto L1200; - term = end; - prdcsr[term] = extarc; - path_id[term] = true; - /* if negative surplus node is found, do an augmentation */ - if (dfct[term] > 0) - goto L2000; - /* return for another iteration */ - goto L500; - } - } - else - { extarc = -extarc; - if (x[extarc] == 0) - { seclevel = sb_level[term]; - goto L580; - } - start = startn[extarc]; - bstlevel = p[start] - rc[extarc]; - if (pterm >= bstlevel) - { if (path_id[start]) - goto L1200; - term = start; - prdcsr[term] = -extarc; - path_id[term] = true; - /* if negative surplus node is found, do an augmentation */ - if (dfct[term] > 0) - goto L2000; - /* return for another iteration */ - goto L500; - } - } -L550: /* second best logic test applied to save a full node scan - * if old best level continues to be best go for another - * contraction */ - seclevel = sb_level[term]; - if (bstlevel <= seclevel) - goto L800; -L580: /* if second best can be used do either a contraction or start - * over with a speculative extension */ - if (seclevel > -large) - { extarc = sb_arc[term]; - if (extarc > 0) - { if (u[extarc] == 0) - goto L600; - bstlevel = p[endn[extarc]] + rc[extarc]; - } - else - { if (x[-extarc] == 0) - goto L600; - bstlevel = p[startn[-extarc]] - rc[-extarc]; - } - if (bstlevel == seclevel) - { sb_level[term] = -large; - extend_arc[term] = extarc; - goto L800; - } - } -L600: /* extension/contraction attempt was unsuccessful, so scan - * terminal node */ - nsp++; - bstlevel = seclevel = large; - for (arc = fpushf[term]; arc > 0; arc = nxtpushf[arc]) - { new_level = p[endn[arc]] + rc[arc]; - if (new_level < seclevel) - { if (new_level < bstlevel) - { seclevel = bstlevel; - bstlevel = new_level; - secarc = extarc; - extarc = arc; - } - else - { seclevel = new_level; - secarc = arc; - } - } - } - for (arc = fpushb[term]; arc > 0; arc = nxtpushb[arc]) - { new_level = p[startn[arc]] - rc[arc]; - if (new_level < seclevel) - { if (new_level < bstlevel) - { seclevel = bstlevel; - bstlevel = new_level; - secarc = extarc; - extarc = -arc; - } - else - { seclevel = new_level; - secarc = -arc; - } - } - } - sb_level[term] = seclevel; - sb_arc[term] = secarc; - extend_arc[term] = extarc; -L800: /* End of node scan. */ - /* if the terminal node is the root, adjust its price and change - * root */ - if (term == root) - { p[term] = bstlevel + eps; - if (p[term] >= large) - { /* no path to the destination */ - /* problem is found to be infeasible */ - return 1; - } - path_id[root] = false; - prevnode = root; - root = nxtqueue[root]; - goto L200; - } - /* check whether extension or contraction */ - prd = prdcsr[term]; - if (prd > 0) - { pr_term = startn[prd]; - prevlevel = p[pr_term] - rc[prd]; - } - else - { pr_term = endn[-prd]; - prevlevel = p[pr_term] + rc[-prd]; - } - if (prevlevel > bstlevel) - { /* path extension */ - if (prevlevel >= bstlevel + eps) - p[term] = bstlevel + eps; - else - p[term] = prevlevel; - if (extarc > 0) - { end = endn[extarc]; - if (path_id[end]) - goto L1200; - term = end; - } - else - { start = startn[-extarc]; - if (path_id[start]) - goto L1200; - term = start; - } - prdcsr[term] = extarc; - path_id[term] = true; - /* if negative surplus node is found, do an augmentation */ - if (dfct[term] > 0) - goto L2000; - /* return for another iteration */ - goto L500; - } - else - { /* path contraction */ - p[term] = bstlevel + eps; - path_id[term] = false; - term = pr_term; - if (pr_term != root) - { if (bstlevel <= pterm + eps) - goto L2000; - } - pterm = p[term]; - extarc = prd; - if (prd > 0) - bstlevel += eps + rc[prd]; - else - bstlevel += eps - rc[-prd]; - /* do a second best test and if that fails, do a full node - * scan */ - goto L550; - } -L1200:/* A cycle is about to form; do a retreat sequence. */ - node = term; -L1600:if (node != root) - { path_id[node] = false; - prd = prdcsr[node]; - if (prd > 0) - { pr_term = startn[prd]; - if (p[pr_term] == p[node] + rc[prd] + eps) - { node = pr_term; - goto L1600; - } - } - else - { pr_term = endn[-prd]; - if (p[pr_term] == p[node] - rc[-prd] + eps) - { node = pr_term; - goto L1600; - } - } - /* do a full scan and price rise at pr_term */ - nsp++; - bstlevel = seclevel = large; - for (arc = fpushf[pr_term]; arc > 0; arc = nxtpushf[arc]) - { new_level = p[endn[arc]] + rc[arc]; - if (new_level < seclevel) - { if (new_level < bstlevel) - { seclevel = bstlevel; - bstlevel = new_level; - secarc = extarc; - extarc = arc; - } - else - { seclevel = new_level; - secarc = arc; - } - } - } - for (arc = fpushb[pr_term]; arc > 0; arc = nxtpushb[arc]) - { new_level = p[startn[arc]] - rc[arc]; - if (new_level < seclevel) - { if (new_level < bstlevel) - { seclevel = bstlevel; - bstlevel = new_level; - secarc = extarc; - extarc = -arc; - } - else - { seclevel = new_level; - secarc = -arc; - } - } - } - sb_level[pr_term] = seclevel; - sb_arc[pr_term] = secarc; - extend_arc[pr_term] = extarc; - p[pr_term] = bstlevel + eps; - if (pr_term == root) - { prevnode = root; - path_id[root] = false; - root = nxtqueue[root]; - goto L200; - } - path_id[pr_term] = false; - prd = prdcsr[pr_term]; - if (prd > 0) - term = startn[prd]; - else - term = endn[-prd]; - if (term == root) - { prevnode = root; - path_id[root] = false; - root = nxtqueue[root]; - goto L200; - } - else - goto L2000; - } -L2000:/* End of auction/shortest path routine. */ - /* do augmentation from root and correct the push lists */ - incr = -dfct[root]; - for (node = root;;) - { extarc = extend_arc[node]; - path_id[node] = false; - if (extarc > 0) - { node = endn[extarc]; - if (incr > u[extarc]) - incr = u[extarc]; - } - else - { node = startn[-extarc]; - if (incr > x[-extarc]) - incr = x[-extarc]; - } - if (node == term) - break; - } - path_id[term] = false; - if (dfct[term] > 0) - { if (incr > dfct[term]) - incr = dfct[term]; - } - for (node = root;;) - { extarc = extend_arc[node]; - if (extarc > 0) - { end = endn[extarc]; - /* add arc to the reduced graph */ - if (x[extarc] == 0) - { nxtpushb[extarc] = fpushb[end]; - fpushb[end] = extarc; - new_level = p[node] - rc[extarc]; - if (sb_level[end] > new_level) - { sb_level[end] = new_level; - sb_arc[end] = -extarc; - } - } - x[extarc] += incr; - u[extarc] -= incr; - /* remove arc from the reduced graph */ - if (u[extarc] == 0) - { nas++; - arc = fpushf[node]; - if (arc == extarc) - fpushf[node] = nxtpushf[arc]; - else - { prevarc = arc; - arc = nxtpushf[arc]; - while (arc > 0) - { if (arc == extarc) - { nxtpushf[prevarc] = nxtpushf[arc]; - break; - } - prevarc = arc; - arc = nxtpushf[arc]; - } - } - } - node = end; - } - else - { extarc = -extarc; - start = startn[extarc]; - /* add arc to the reduced graph */ - if (u[extarc] == 0) - { nxtpushf[extarc] = fpushf[start]; - fpushf[start] = extarc; - new_level = p[node] + rc[extarc]; - if (sb_level[start] > new_level) - { sb_level[start] = new_level; - sb_arc[start] = extarc; - } - } - u[extarc] += incr; - x[extarc] -= incr; - /* remove arc from the reduced graph */ - if (x[extarc] == 0) - { nas++; - arc = fpushb[node]; - if (arc == extarc) - fpushb[node] = nxtpushb[arc]; - else - { prevarc = arc; - arc = nxtpushb[arc]; - while (arc > 0) - { if (arc == extarc) - { nxtpushb[prevarc] = nxtpushb[arc]; - break; - } - prevarc = arc; - arc = nxtpushb[arc]; - } - } - } - node = start; - } - if (node == term) - break; - } - dfct[term] -= incr; - dfct[root] += incr; - /* insert term in the queue if it has a large enough surplus */ - if (dfct[term] < thresh_dfct) - { if (nxtqueue[term] == 0) - { nxtnode = nxtqueue[root]; - if ((p[term] >= p[nxtnode]) && (root != nxtnode)) - { nxtqueue[root] = term; - nxtqueue[term] = nxtnode; - } - else - { nxtqueue[prevnode] = term; - nxtqueue[term] = root; - prevnode = term; - } - } - } - /* if root has a large enough surplus, keep it in the queue and - * return for another iteration */ - if (dfct[root] < thresh_dfct) - { prevnode = root; - root = nxtqueue[root]; - goto L200; - } -L3000:/* end of augmentation cycle */ - /* Check for termination of scaling phase. If scaling phase is not - * finished, advance the queue and return to take another node. */ - nxtnode = nxtqueue[root]; - if (root != nxtnode) - { nxtqueue[root] = 0; - nxtqueue[prevnode] = nxtnode; - root = nxtnode; - goto L200; - } - /* End of subproblem (scaling phase). */ - /* Reduce epsilon. */ - eps /= factor; - if (eps < 1) eps = 1; - thresh_dfct /= factor; - if (eps == 1) thresh_dfct = 0; - /* if another auction scaling phase remains, reset the flows & - * the push lists; else reset arc flows to satisfy cs and compute - * reduced costs */ - if (crash == 1) - { for (arc = 1; arc <= na; arc++) - { start = startn[arc]; - end = endn[arc]; - pstart = p[start]; - pend = p[end]; - if (pstart > pend + eps + rc[arc]) - { resid = u[arc]; - if (resid > 0) - { dfct[start] += resid; - dfct[end] -= resid; - x[arc] += resid; - u[arc] = 0; - } - } - else if (pstart < pend - eps + rc[arc]) - { flow = x[arc]; - if (flow > 0) - { dfct[start] -= flow; - dfct[end] += flow; - x[arc] = 0; - u[arc] += flow; - } - } - } - /* return for another phase */ - goto L100; - } - else - { crash = 1; - for (arc = 1; arc <= na; arc++) - { start = startn[arc]; - end = endn[arc]; - red_cost = rc[arc] + p[end] - p[start]; - if (red_cost < 0) - { resid = u[arc]; - if (resid > 0) - { dfct[start] += resid; - dfct[end] -= resid; - x[arc] += resid; - u[arc] = 0; - } - } - else if (red_cost > 0) - { flow = x[arc]; - if (flow > 0) - { dfct[start] -= flow; - dfct[end] += flow; - x[arc] = 0; - u[arc] += flow; - } - } - rc[arc] = red_cost; - } - } - return 0; -# undef crash -# undef nsp -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/relax4.h b/resources/3rdparty/glpk-4.53/src/misc/relax4.h deleted file mode 100644 index 44991fc55..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/relax4.h +++ /dev/null @@ -1,102 +0,0 @@ -/* relax4.h */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef RELAX4_H -#define RELAX4_H - -struct relax4_csa -{ /* common storage area */ - /* input parameters --------------------------------------------*/ - int n; - /* number of nodes */ - int na; - /* number of arcs */ - int large; - /* very large int to represent infinity */ - int repeat; - /* true if initialization is to be skipped (false otherwise) */ - int crash; - /* 0 if default initialization is used - * 1 if auction initialization is used */ - int *startn; /* int startn[1+na]; */ - /* startn[j] = starting node for arc j, j = 1,...,na */ - int *endn; /* int endn[1+na] */ - /* endn[j] = ending node for arc j, j = 1,...,na */ - int *fou; /* int fou[1+n]; */ - /* fou[i] = first arc out of node i, i = 1,...,n */ - int *nxtou; /* int nxtou[1+na]; */ - /* nxtou[j] = next arc out of the starting node of arc j, - * j = 1,...,na */ - int *fin; /* int fin[1+n]; */ - /* fin[i] = first arc into node i, i = 1,...,n */ - int *nxtin; /* int nxtin[1+na]; */ - /* nxtin[j] = next arc into the ending node of arc j, - * j = 1,...,na */ - /* updated parameters ------------------------------------------*/ - int *rc; /* int rc[1+na]; */ - /* rc[j] = reduced cost of arc j, j = 1,...,na */ - int *u; /* int u[1+na]; */ - /* u[j] = capacity of arc j on input - * and (capacity of arc j) - x(j) on output, j = 1,...,na */ - int *dfct; /* int dfct[1+n]; */ - /* dfct[i] = demand at node i on input - * and zero on output, i = 1,...,n */ - /* output parameters -------------------------------------------*/ - int *x; /* int x[1+na]; */ - /* x[j] = flow on arc j, j = 1,...,na */ - int nmultinode; - /* number of multinode relaxation iterations in RELAX4 */ - int iter; - /* number of relaxation iterations in RELAX4 */ - int num_augm; - /* number of flow augmentation steps in RELAX4 */ - int num_ascnt; - /* number of multinode ascent steps in RELAX4 */ - int nsp; - /* number of auction/shortest path iterations */ - /* working parameters ------------------------------------------*/ - int *label; /* int label, tempin, p[1+n]; */ - int *prdcsr; /* int prdcsr, tempou, price[1+n]; */ - int *save; /* int save[1+na]; */ - int *tfstou; /* int tfstou, fpushf[1+n]; */ - int *tnxtou; /* int tnxtou, nxtpushf[1+na]; */ - int *tfstin; /* int tfstin, fpushb[1+n]; */ - int *tnxtin; /* int tnxtin, nxtpushb[1+na]; */ - int *nxtqueue; /* int nxtqueue[1+n]; */ - char *scan; /* bool scan[1+n]; */ - char *mark; /* bool mark, path_id[1+n]; */ - /* working parameters used by routine auction only -------------*/ - int *extend_arc; /* int extend_arc[1+n]; */ - int *sb_level; /* int sb_level[1+n]; */ - int *sb_arc; /* int sb_arc[1+n]; */ -}; - -#define relax4 _glp_relax4 -int relax4(struct relax4_csa *csa); - -#define relax4_inidat _glp_relax4_inidat -void relax4_inidat(struct relax4_csa *csa); - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/rng.c b/resources/3rdparty/glpk-4.53/src/misc/rng.c deleted file mode 100644 index e0acb53a2..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/rng.c +++ /dev/null @@ -1,227 +0,0 @@ -/* rng.c (pseudo-random number generator) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* This code is a modified version of the module GB_FLIP, a portable -* pseudo-random number generator. The original version of GB_FLIP is -* a part of The Stanford GraphBase developed by Donald E. Knuth (see -* http://www-cs-staff.stanford.edu/~knuth/sgb.html). -* -* Note that all changes concern only external names, so this modified -* version produces exactly the same results as the original version. -* -* Changes were made by Andrew Makhorin . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "rng.h" - -#if 0 -int A[56] = { -1 }; -#else -#define A (rand->A) -#endif -/* pseudo-random values */ - -#if 0 -int *fptr = A; -#else -#define fptr (rand->fptr) -#endif -/* the next A value to be exported */ - -#define mod_diff(x, y) (((x) - (y)) & 0x7FFFFFFF) -/* difference modulo 2^31 */ - -static int flip_cycle(RNG *rand) -{ /* this is an auxiliary routine to do 55 more steps of the basic - * recurrence, at high speed, and to reset fptr */ - int *ii, *jj; - for (ii = &A[1], jj = &A[32]; jj <= &A[55]; ii++, jj++) - *ii = mod_diff(*ii, *jj); - for (jj = &A[1]; ii <= &A[55]; ii++, jj++) - *ii = mod_diff(*ii, *jj); - fptr = &A[54]; - return A[55]; -} - -/*********************************************************************** -* NAME -* -* rng_create_rand - create pseudo-random number generator -* -* SYNOPSIS -* -* #include "rng.h" -* RNG *rng_create_rand(void); -* -* DESCRIPTION -* -* The routine rng_create_rand creates and initializes a pseudo-random -* number generator. -* -* RETURNS -* -* The routine returns a pointer to the generator created. */ - -RNG *rng_create_rand(void) -{ RNG *rand; - int i; - rand = talloc(1, RNG); - A[0] = -1; - for (i = 1; i <= 55; i++) A[i] = 0; - fptr = A; - rng_init_rand(rand, 1); - return rand; -} - -/*********************************************************************** -* NAME -* -* rng_init_rand - initialize pseudo-random number generator -* -* SYNOPSIS -* -* #include "rng.h" -* void rng_init_rand(RNG *rand, int seed); -* -* DESCRIPTION -* -* The routine rng_init_rand initializes the pseudo-random number -* generator. The parameter seed may be any integer number. Note that -* on creating the generator this routine is called with the parameter -* seed equal to 1. */ - -void rng_init_rand(RNG *rand, int seed) -{ int i; - int prev = seed, next = 1; - seed = prev = mod_diff(prev, 0); - A[55] = prev; - for (i = 21; i; i = (i + 21) % 55) - { A[i] = next; - next = mod_diff(prev, next); - if (seed & 1) - seed = 0x40000000 + (seed >> 1); - else - seed >>= 1; - next = mod_diff(next, seed); - prev = A[i]; - } - flip_cycle(rand); - flip_cycle(rand); - flip_cycle(rand); - flip_cycle(rand); - flip_cycle(rand); - return; -} - -/*********************************************************************** -* NAME -* -* rng_next_rand - obtain pseudo-random integer in the range [0, 2^31-1] -* -* SYNOPSIS -* -* #include "rng.h" -* int rng_next_rand(RNG *rand); -* -* RETURNS -* -* The routine rng_next_rand returns a next pseudo-random integer which -* is uniformly distributed between 0 and 2^31-1, inclusive. The period -* length of the generated numbers is 2^85 - 2^30. The low order bits of -* the generated numbers are just as random as the high-order bits. */ - -int rng_next_rand(RNG *rand) -{ return - *fptr >= 0 ? *fptr-- : flip_cycle(rand); -} - -/*********************************************************************** -* NAME -* -* rng_unif_rand - obtain pseudo-random integer in the range [0, m-1] -* -* SYNOPSIS -* -* #include "rng.h" -* int rng_unif_rand(RNG *rand, int m); -* -* RETURNS -* -* The routine rng_unif_rand returns a next pseudo-random integer which -* is uniformly distributed between 0 and m-1, inclusive, where m is any -* positive integer less than 2^31. */ - -#define two_to_the_31 ((unsigned int)0x80000000) - -int rng_unif_rand(RNG *rand, int m) -{ unsigned int t = two_to_the_31 - (two_to_the_31 % m); - int r; - xassert(m > 0); - do { r = rng_next_rand(rand); } while (t <= (unsigned int)r); - return r % m; -} - -/*********************************************************************** -* NAME -* -* rng_delete_rand - delete pseudo-random number generator -* -* SYNOPSIS -* -* #include "rng.h" -* void rng_delete_rand(RNG *rand); -* -* DESCRIPTION -* -* The routine rng_delete_rand frees all the memory allocated to the -* specified pseudo-random number generator. */ - -void rng_delete_rand(RNG *rand) -{ tfree(rand); - return; -} - -/**********************************************************************/ - -#ifdef GLP_TEST -/* To be sure that this modified version produces the same results as - * the original version, run this validation program. */ - -int main(void) -{ RNG *rand; - int j; - rand = rng_create_rand(); - rng_init_rand(rand, -314159); - if (rng_next_rand(rand) != 119318998) - { fprintf(stderr, "Failure on the first try!\n"); - return -1; - } - for (j = 1; j <= 133; j++) rng_next_rand(rand); - if (rng_unif_rand(rand, 0x55555555) != 748103812) - { fprintf(stderr, "Failure on the second try!\n"); - return -2; - } - fprintf(stderr, "OK, the random-number generator routines seem to" - " work!\n"); - rng_delete_rand(rand); - return 0; -} -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/rng.h b/resources/3rdparty/glpk-4.53/src/misc/rng.h deleted file mode 100644 index 9747b4490..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/rng.h +++ /dev/null @@ -1,67 +0,0 @@ -/* rng.h (pseudo-random number generator) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2003, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef RNG_H -#define RNG_H - -typedef struct RNG RNG; - -struct RNG -{ /* Knuth's portable pseudo-random number generator */ - int A[56]; - /* pseudo-random values */ - int *fptr; - /* the next A value to be exported */ -}; - -#define rng_create_rand _glp_rng_create_rand -RNG *rng_create_rand(void); -/* create pseudo-random number generator */ - -#define rng_init_rand _glp_rng_init_rand -void rng_init_rand(RNG *rand, int seed); -/* initialize pseudo-random number generator */ - -#define rng_next_rand _glp_rng_next_rand -int rng_next_rand(RNG *rand); -/* obtain pseudo-random integer in the range [0, 2^31-1] */ - -#define rng_unif_rand _glp_rng_unif_rand -int rng_unif_rand(RNG *rand, int m); -/* obtain pseudo-random integer in the range [0, m-1] */ - -#define rng_delete_rand _glp_rng_delete_rand -void rng_delete_rand(RNG *rand); -/* delete pseudo-random number generator */ - -#define rng_unif_01 _glp_rng_unif_01 -double rng_unif_01(RNG *rand); -/* obtain pseudo-random number in the range [0, 1] */ - -#define rng_uniform _glp_rng_uniform -double rng_uniform(RNG *rand, double a, double b); -/* obtain pseudo-random number in the range [a, b] */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/rng1.c b/resources/3rdparty/glpk-4.53/src/misc/rng1.c deleted file mode 100644 index 567c79eb8..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/rng1.c +++ /dev/null @@ -1,73 +0,0 @@ -/* rng1.c (pseudo-random number generator) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2003, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "rng.h" - -/*********************************************************************** -* NAME -* -* rng_unif_01 - obtain pseudo-random number in the range [0, 1] -* -* SYNOPSIS -* -* #include "rng.h" -* double rng_unif_01(RNG *rand); -* -* RETURNS -* -* The routine rng_unif_01 returns a next pseudo-random number which is -* uniformly distributed in the range [0, 1]. */ - -double rng_unif_01(RNG *rand) -{ double x; - x = (double)rng_next_rand(rand) / 2147483647.0; - xassert(0.0 <= x && x <= 1.0); - return x; -} - -/*********************************************************************** -* NAME -* -* rng_uniform - obtain pseudo-random number in the range [a, b] -* -* SYNOPSIS -* -* #include "rng.h" -* double rng_uniform(RNG *rand, double a, double b); -* -* RETURNS -* -* The routine rng_uniform returns a next pseudo-random number which is -* uniformly distributed in the range [a, b]. */ - -double rng_uniform(RNG *rand, double a, double b) -{ double x; - xassert(a < b); - x = rng_unif_01(rand); - x = a * (1.0 - x) + b * x; - xassert(a <= x && x <= b); - return x; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/round2n.c b/resources/3rdparty/glpk-4.53/src/misc/round2n.c deleted file mode 100644 index 126d638c1..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/round2n.c +++ /dev/null @@ -1,64 +0,0 @@ -/* round2n.c (round floating-point number to nearest power of two) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "misc.h" - -/*********************************************************************** -* NAME -* -* round2n - round floating-point number to nearest power of two -* -* SYNOPSIS -* -* #include "misc.h" -* double round2n(double x); -* -* RETURNS -* -* Given a positive floating-point value x the routine round2n returns -* 2^n such that |x - 2^n| is minimal. -* -* EXAMPLES -* -* round2n(10.1) = 2^3 = 8 -* round2n(15.3) = 2^4 = 16 -* round2n(0.01) = 2^(-7) = 0.0078125 -* -* BACKGROUND -* -* Let x = f * 2^e, where 0.5 <= f < 1 is a normalized fractional part, -* e is an integer exponent. Then, obviously, 0.5 * 2^e <= x < 2^e, so -* if x - 0.5 * 2^e <= 2^e - x, we choose 0.5 * 2^e = 2^(e-1), and 2^e -* otherwise. The latter condition can be written as 2 * x <= 1.5 * 2^e -* or 2 * f * 2^e <= 1.5 * 2^e or, finally, f <= 0.75. */ - -double round2n(double x) -{ int e; - double f; - xassert(x > 0.0); - f = frexp(x, &e); - return ldexp(1.0, f <= 0.75 ? e-1 : e); -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/str2int.c b/resources/3rdparty/glpk-4.53/src/misc/str2int.c deleted file mode 100644 index 5d8117a55..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/str2int.c +++ /dev/null @@ -1,92 +0,0 @@ -/* str2int.c (convert string to int) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "misc.h" -#include "stdc.h" - -/*********************************************************************** -* NAME -* -* str2int - convert character string to value of int type -* -* SYNOPSIS -* -* #include "misc.h" -* int str2int(const char *str, int *val); -* -* DESCRIPTION -* -* The routine str2int converts the character string str to a value of -* integer type and stores the value into location, which the parameter -* val points to (in the case of error content of this location is not -* changed). -* -* RETURNS -* -* The routine returns one of the following error codes: -* -* 0 - no error; -* 1 - value out of range; -* 2 - character string is syntactically incorrect. */ - -int str2int(const char *str, int *val_) -{ int d, k, s, val = 0; - /* scan optional sign */ - if (str[0] == '+') - s = +1, k = 1; - else if (str[0] == '-') - s = -1, k = 1; - else - s = +1, k = 0; - /* check for the first digit */ - if (!isdigit((unsigned char)str[k])) - return 2; - /* scan digits */ - while (isdigit((unsigned char)str[k])) - { d = str[k++] - '0'; - if (s > 0) - { if (val > INT_MAX / 10) - return 1; - val *= 10; - if (val > INT_MAX - d) - return 1; - val += d; - } - else /* s < 0 */ - { if (val < INT_MIN / 10) - return 1; - val *= 10; - if (val < INT_MIN + d) - return 1; - val -= d; - } - } - /* check for terminator */ - if (str[k] != '\0') - return 2; - /* conversion has been done */ - *val_ = val; - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/str2num.c b/resources/3rdparty/glpk-4.53/src/misc/str2num.c deleted file mode 100644 index f67c2fc17..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/str2num.c +++ /dev/null @@ -1,110 +0,0 @@ -/* str2num.c (convert string to double) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "misc.h" -#include "stdc.h" - -/*********************************************************************** -* NAME -* -* str2num - convert character string to value of double type -* -* SYNOPSIS -* -* #include "misc.h" -* int str2num(const char *str, double *val); -* -* DESCRIPTION -* -* The routine str2num converts the character string str to a value of -* double type and stores the value into location, which the parameter -* val points to (in the case of error content of this location is not -* changed). -* -* RETURNS -* -* The routine returns one of the following error codes: -* -* 0 - no error; -* 1 - value out of range; -* 2 - character string is syntactically incorrect. */ - -int str2num(const char *str, double *val_) -{ int k; - double val; - /* scan optional sign */ - k = (str[0] == '+' || str[0] == '-' ? 1 : 0); - /* check for decimal point */ - if (str[k] == '.') - { k++; - /* a digit should follow it */ - if (!isdigit((unsigned char)str[k])) - return 2; - k++; - goto frac; - } - /* integer part should start with a digit */ - if (!isdigit((unsigned char)str[k])) - return 2; - /* scan integer part */ - while (isdigit((unsigned char)str[k])) - k++; - /* check for decimal point */ - if (str[k] == '.') k++; -frac: /* scan optional fraction part */ - while (isdigit((unsigned char)str[k])) - k++; - /* check for decimal exponent */ - if (str[k] == 'E' || str[k] == 'e') - { k++; - /* scan optional sign */ - if (str[k] == '+' || str[k] == '-') - k++; - /* a digit should follow E, E+ or E- */ - if (!isdigit((unsigned char)str[k])) - return 2; - } - /* scan optional exponent part */ - while (isdigit((unsigned char)str[k])) - k++; - /* check for terminator */ - if (str[k] != '\0') - return 2; - /* perform conversion */ - { char *endptr; - val = strtod(str, &endptr); - if (*endptr != '\0') - return 2; - } - /* check for overflow */ - if (!(-DBL_MAX <= val && val <= +DBL_MAX)) - return 1; - /* check for underflow */ - if (-DBL_MIN < val && val < +DBL_MIN) - val = 0.0; - /* conversion has been done */ - *val_ = val; - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/strspx.c b/resources/3rdparty/glpk-4.53/src/misc/strspx.c deleted file mode 100644 index f0702f9ce..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/strspx.c +++ /dev/null @@ -1,60 +0,0 @@ -/* strspx.c (remove all spaces from string) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "misc.h" - -/*********************************************************************** -* NAME -* -* strspx - remove all spaces from character string -* -* SYNOPSIS -* -* #include "misc.h" -* char *strspx(char *str); -* -* DESCRIPTION -* -* The routine strspx removes all spaces from the character string str. -* -* RETURNS -* -* The routine returns a pointer to the character string. -* -* EXAMPLES -* -* strspx(" Errare humanum est ") => "Errarehumanumest" -* -* strspx(" ") => "" */ - -char *strspx(char *str) -{ char *s, *t; - for (s = t = str; *s; s++) - { if (*s != ' ') - *t++ = *s; - } - *t = '\0'; - return str; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/strtrim.c b/resources/3rdparty/glpk-4.53/src/misc/strtrim.c deleted file mode 100644 index a9b782359..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/strtrim.c +++ /dev/null @@ -1,62 +0,0 @@ -/* strtrim.c (remove trailing spaces from string) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "misc.h" -#include "stdc.h" - -/*********************************************************************** -* NAME -* -* strtrim - remove trailing spaces from character string -* -* SYNOPSIS -* -* #include "misc.h" -* char *strtrim(char *str); -* -* DESCRIPTION -* -* The routine strtrim removes trailing spaces from the character -* string str. -* -* RETURNS -* -* The routine returns a pointer to the character string. -* -* EXAMPLES -* -* strtrim("Errare humanum est ") => "Errare humanum est" -* -* strtrim(" ") => "" */ - -char *strtrim(char *str) -{ char *t; - for (t = strrchr(str, '\0') - 1; t >= str; t--) - { if (*t != ' ') - break; - *t = '\0'; - } - return str; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/triang.c b/resources/3rdparty/glpk-4.53/src/misc/triang.c deleted file mode 100644 index bb95ecc3a..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/triang.c +++ /dev/null @@ -1,311 +0,0 @@ -/* triang.c (find maximal triangular part of rectangular matrix) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "triang.h" - -/*********************************************************************** -* triang - find maximal triangular part of rectangular matrix -* -* Given a mxn sparse matrix A this routine finds permutation matrices -* P and Q such that matrix A' = P * A * Q has the following structure: -* -* 1 s n -* 1 * . . . . . x x x x x -* * * . . . . x x x x x -* * * * . . . x x x x x -* * * * * . . x x x x x -* * * * * * . x x x x x -* s * * * * * * x x x x x -* x x x x x x x x x x x -* x x x x x x x x x x x -* m x x x x x x x x x x x -* -* where '*' are elements of the triangular part, '.' are structural -* zeros, 'x' are other elements. -* -* The formal routine mat specifies the original matrix A in both row- -* and column-wise format. If the routine mat is called with k = +i, -* 1 <= i <= m, it should store column indices and values of non-zero -* elements of i-th row of A in locations ind[1], ..., ind[len] and -* val[1], ..., val[len], resp., where len is the returned number of -* non-zeros in the row, 0 <= len <= n. Similarly, if the routine mat -* is called with k = -j, 1 <= j <= n, it should store row indices and -* values of non-zero elements of j-th column of A and return len, the -* number of non-zeros in the column, 0 <= len <= m. Should note that -* duplicate indices are not allowed. -* -* The parameter info is a transit pointer passed to the routine mat. -* -* The parameter tol is a tolerance. The routine triang guarantees that -* each diagonal element in the triangular part of matrix A' is not -* less in magnitude than tol * max, where max is the maximal magnitude -* of elements in corresponding column. -* -* On exit the routine triang stores information on the triangular part -* found in the arrays rn and cn. Elements rn[1], ..., rn[s] specify -* row numbers and elements cn[1], ..., cn[s] specify column numbers -* of the original matrix A, which correspond to rows/columns 1, ..., s -* of matrix A', where s is the size of the triangular part returned by -* the routine, 0 <= s <= min(m, n). The order of rows and columns that -* are not included in the triangular part remains unspecified. -* -* ALGORITHM -* -* The routine triang uses a simple greedy heuristic. -* -* At some step the matrix A' = P * A * Q has the following structure: -* -* 1 n -* 1 * . . . . . . . x x x -* * * . . . . . . x x x -* * * * . . . . . x x x -* * * * * . . . . x x x -* x x x x # # # # x x x -* x x x x # # # # x x x -* x x x x # # # # x x x -* x x x x # # # # x x x -* m x x x x # # # # x x x -* -* where '#' are elements of active submatrix. Initially P = Q = I, so -* the active submatrix is the original matrix A = A'. -* -* If some row has exactly one non-zero in the active submatrix (row -* singleton), the routine includes this row and corresponding column -* in the triangular part, and removes the column from the active -* submatrix. Otherwise, the routine simply removes a column having -* maximal number of non-zeros from the active submatrix in the hope -* that new row singleton(s) will appear. -* -* COMPLEXITY -* -* The time complexity of the routine triang is O(nnz), where nnz is -* number of non-zeros in the original matrix A. */ - -int triang(int m, int n, int (*mat)(void *info, int k, int ind[], - double val[]), void *info, double tol, int rn[], int cn[]) -{ int head, i, j, jj, k, kk, ks, len, len2, next_j, ns, size; - int *cind, *rind, *cnt, *ptr, *list, *prev, *next; - double *cval, *rval, *big; - char *flag; - /* allocate working arrays */ - cind = talloc(1+m, int); - cval = talloc(1+m, double); - rind = talloc(1+n, int); - rval = talloc(1+n, double); - cnt = ptr = talloc(1+m, int); - list = talloc(1+n, int); - prev = talloc(1+n, int); - next = talloc(1+n, int); - big = talloc(1+n, double); - flag = talloc(1+n, char); - /*--------------------------------------------------------------*/ - /* build linked lists of columns having equal lengths */ - /*--------------------------------------------------------------*/ - /* ptr[len], 0 <= len <= m, is number of first column of length - * len; - * next[j], 1 <= j <= n, is number of next column having the same - * length as column j; - * big[j], 1 <= j <= n, is maximal magnitude of elements in j-th - * column */ - for (len = 0; len <= m; len++) - ptr[len] = 0; - for (j = 1; j <= n; j++) - { /* get j-th column */ - len = mat(info, -j, cind, cval); - xassert(0 <= len && len <= m); - /* add this column to beginning of list ptr[len] */ - next[j] = ptr[len]; - ptr[len] = j; - /* determine maximal magnitude of elements in this column */ - big[j] = 0.0; - for (k = 1; k <= len; k++) - { if (big[j] < fabs(cval[k])) - big[j] = fabs(cval[k]); - } - } - /*--------------------------------------------------------------*/ - /* build doubly linked list of columns ordered by decreasing */ - /* column lengths */ - /*--------------------------------------------------------------*/ - /* head is number of first column in the list; - * prev[j], 1 <= j <= n, is number of column that precedes j-th - * column in the list; - * next[j], 1 <= j <= n, is number of column that follows j-th - * column in the list */ - head = 0; - for (len = 0; len <= m; len++) - { /* walk thru list of columns of length len */ - for (j = ptr[len]; j != 0; j = next_j) - { next_j = next[j]; - /* add j-th column to beginning of the column list */ - prev[j] = 0; - next[j] = head; - if (head != 0) - prev[head] = j; - head = j; - } - } - /*--------------------------------------------------------------*/ - /* build initial singleton list */ - /*--------------------------------------------------------------*/ - /* there are used two list of columns: - * 1) doubly linked list of active columns, in which all columns - * are ordered by decreasing column lengths; - * 2) singleton list; an active column is included in this list - * if it has at least one row singleton in active submatrix */ - /* flag[j], 1 <= j <= n, is a flag of j-th column: - * 0 j-th column is inactive; - * 1 j-th column is active; - * 2 j-th column is active and has row singleton(s) */ - /* initially all columns are active */ - for (j = 1; j <= n; j++) - flag[j] = 1; - /* initialize row counts and build initial singleton list */ - /* cnt[i], 1 <= i <= m, is number of non-zeros, which i-th row - * has in active submatrix; - * ns is size of singleton list; - * list[1], ..., list[ns] are numbers of active columns included - * in the singleton list */ - ns = 0; - for (i = 1; i <= m; i++) - { /* get i-th row */ - len = cnt[i] = mat(info, +i, rind, rval); - xassert(0 <= len && len <= n); - if (len == 1) - { /* a[i,j] is row singleton */ - j = rind[1]; - xassert(1 <= j && j <= n); - if (flag[j] != 2) - { /* include j-th column in singleton list */ - flag[j] = 2; - list[++ns] = j; - } - } - } - /*--------------------------------------------------------------*/ - /* main loop */ - /*--------------------------------------------------------------*/ - size = 0; /* size of triangular part */ - /* loop until active column list is non-empty, i.e. until the - * active submatrix has at least one column */ - while (head != 0) - { if (ns == 0) - { /* singleton list is empty */ - /* remove from the active submatrix a column of maximal - * length in the hope that some row singletons appear */ - j = head; - len = mat(info, -j, cind, cval); - xassert(0 <= len && len <= m); - goto drop; - } - /* take column j from the singleton list */ - j = list[ns--]; - xassert(flag[j] == 2); - /* j-th column has at least one row singleton in the active - * submatrix; choose one having maximal magnitude */ - len = mat(info, -j, cind, cval); - xassert(0 <= len && len <= m); - kk = 0; - for (k = 1; k <= len; k++) - { i = cind[k]; - xassert(1 <= i && i <= m); - if (cnt[i] == 1) - { /* a[i,j] is row singleton */ - if (kk == 0 || fabs(cval[kk]) < fabs(cval[k])) - kk = k; - } - } - xassert(kk > 0); - /* check magnitude of the row singleton chosen */ - if (fabs(cval[kk]) < tol * big[j]) - { /* all row singletons are too small in magnitude; drop j-th - * column */ - goto drop; - } - /* row singleton a[i,j] is ok; add i-th row and j-th column to - * the triangular part */ - size++; - rn[size] = cind[kk]; - cn[size] = j; -drop: /* remove j-th column from the active submatrix */ - xassert(flag[j]); - flag[j] = 0; - if (prev[j] == 0) - head = next[j]; - else - next[prev[j]] = next[j]; - if (next[j] == 0) - ; - else - prev[next[j]] = prev[j]; - /* decrease row counts */ - for (k = 1; k <= len; k++) - { i = cind[k]; - xassert(1 <= i && i <= m); - xassert(cnt[i] > 0); - cnt[i]--; - if (cnt[i] == 1) - { /* new singleton appeared in i-th row; determine number - * of corresponding column (it is the only active column - * in this row) */ - len2 = mat(info, +i, rind, rval); - xassert(0 <= len2 && len2 <= n); - ks = 0; - for (kk = 1; kk <= len2; kk++) - { jj = rind[kk]; - xassert(1 <= jj && jj <= n); - if (flag[jj]) - { xassert(ks == 0); - ks = kk; - } - } - xassert(ks > 0); - /* a[i,jj] is new row singleton */ - jj = rind[ks]; - if (flag[jj] != 2) - { /* include jj-th column in the singleton list */ - flag[jj] = 2; - list[++ns] = jj; - } - } - } - } - /* now all row counts should be zero */ - for (i = 1; i <= m; i++) - xassert(cnt[i] == 0); - /* deallocate working arrays */ - tfree(cind); - tfree(cval); - tfree(rind); - tfree(rval); - tfree(ptr); - tfree(list); - tfree(prev); - tfree(next); - tfree(big); - tfree(flag); - return size; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/triang.h b/resources/3rdparty/glpk-4.53/src/misc/triang.h deleted file mode 100644 index 1d5f484d7..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/triang.h +++ /dev/null @@ -1,34 +0,0 @@ -/* triang.h (find maximal triangular part of rectangular matrix) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef TRIANG_H -#define TRIANG_H - -#define triang _glp_triang -int triang(int m, int n, int (*mat)(void *info, int k, int ind[], - double val[]), void *info, double tol, int rn[], int cn[]); -/* find maximal triangular part of rectangular matrix */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/wclique.c b/resources/3rdparty/glpk-4.53/src/misc/wclique.c deleted file mode 100644 index 5daa69cff..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/wclique.c +++ /dev/null @@ -1,242 +0,0 @@ -/* wclique.c (maximum weight clique, Ostergard's algorithm) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Two subroutines sub() and wclique() below are intended to find a -* maximum weight clique in a given undirected graph. These subroutines -* are slightly modified version of the program WCLIQUE developed by -* Patric Ostergard and based -* on ideas from the article "P. R. J. Ostergard, A new algorithm for -* the maximum-weight clique problem, submitted for publication", which -* in turn is a generalization of the algorithm for unweighted graphs -* presented in "P. R. J. Ostergard, A fast algorithm for the maximum -* clique problem, submitted for publication". -* -* USED WITH PERMISSION OF THE AUTHOR OF THE ORIGINAL CODE. -* -* Changes were made by Andrew Makhorin . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "wclique.h" - -/*********************************************************************** -* NAME -* -* wclique - find maximum weight clique with Ostergard's algorithm -* -* SYNOPSIS -* -* #include "wclique.h" -* int wclique(int n, const int w[], const unsigned char a[], -* int ind[]); -* -* DESCRIPTION -* -* The routine wclique finds a maximum weight clique in an undirected -* graph with Ostergard's algorithm. -* -* INPUT PARAMETERS -* -* n is the number of vertices, n > 0. -* -* w[i], i = 1,...,n, is a weight of vertex i. -* -* a[*] is the strict (without main diagonal) lower triangle of the -* graph adjacency matrix in packed format. -* -* OUTPUT PARAMETER -* -* ind[k], k = 1,...,size, is the number of a vertex included in the -* clique found, 1 <= ind[k] <= n, where size is the number of vertices -* in the clique returned on exit. -* -* RETURNS -* -* The routine returns the clique size, i.e. the number of vertices in -* the clique. */ - -struct csa -{ /* common storage area */ - int n; - /* number of vertices */ - const int *wt; /* int wt[0:n-1]; */ - /* weights */ - const unsigned char *a; - /* adjacency matrix (packed lower triangle without main diag.) */ - int record; - /* weight of best clique */ - int rec_level; - /* number of vertices in best clique */ - int *rec; /* int rec[0:n-1]; */ - /* best clique so far */ - int *clique; /* int clique[0:n-1]; */ - /* table for pruning */ - int *set; /* int set[0:n-1]; */ - /* current clique */ -}; - -#define n (csa->n) -#define wt (csa->wt) -#define a (csa->a) -#define record (csa->record) -#define rec_level (csa->rec_level) -#define rec (csa->rec) -#define clique (csa->clique) -#define set (csa->set) - -#if 0 -static int is_edge(struct csa *csa, int i, int j) -{ /* if there is arc (i,j), the routine returns true; otherwise - * false; 0 <= i, j < n */ - int k; - xassert(0 <= i && i < n); - xassert(0 <= j && j < n); - if (i == j) return 0; - if (i < j) k = i, i = j, j = k; - k = (i * (i - 1)) / 2 + j; - return a[k / CHAR_BIT] & - (unsigned char)(1 << ((CHAR_BIT - 1) - k % CHAR_BIT)); -} -#else -#define is_edge(csa, i, j) ((i) == (j) ? 0 : \ - (i) > (j) ? is_edge1(i, j) : is_edge1(j, i)) -#define is_edge1(i, j) is_edge2(((i) * ((i) - 1)) / 2 + (j)) -#define is_edge2(k) (a[(k) / CHAR_BIT] & \ - (unsigned char)(1 << ((CHAR_BIT - 1) - (k) % CHAR_BIT))) -#endif - -static void sub(struct csa *csa, int ct, int table[], int level, - int weight, int l_weight) -{ int i, j, k, curr_weight, left_weight, *p1, *p2, *newtable; - newtable = xcalloc(n, sizeof(int)); - if (ct <= 0) - { /* 0 or 1 elements left; include these */ - if (ct == 0) - { set[level++] = table[0]; - weight += l_weight; - } - if (weight > record) - { record = weight; - rec_level = level; - for (i = 0; i < level; i++) rec[i] = set[i]; - } - goto done; - } - for (i = ct; i >= 0; i--) - { if ((level == 0) && (i < ct)) goto done; - k = table[i]; - if ((level > 0) && (clique[k] <= (record - weight))) - goto done; /* prune */ - set[level] = k; - curr_weight = weight + wt[k]; - l_weight -= wt[k]; - if (l_weight <= (record - curr_weight)) - goto done; /* prune */ - p1 = newtable; - p2 = table; - left_weight = 0; - while (p2 < table + i) - { j = *p2++; - if (is_edge(csa, j, k)) - { *p1++ = j; - left_weight += wt[j]; - } - } - if (left_weight <= (record - curr_weight)) continue; - sub(csa, p1 - newtable - 1, newtable, level + 1, curr_weight, - left_weight); - } -done: xfree(newtable); - return; -} - -int wclique(int n_, const int w[], const unsigned char a_[], int ind[]) -{ struct csa csa_, *csa = &csa_; - int i, j, p, max_wt, max_nwt, wth, *used, *nwt, *pos; - double timer; - n = n_; - xassert(n > 0); - wt = &w[1]; - a = a_; - record = 0; - rec_level = 0; - rec = &ind[1]; - clique = xcalloc(n, sizeof(int)); - set = xcalloc(n, sizeof(int)); - used = xcalloc(n, sizeof(int)); - nwt = xcalloc(n, sizeof(int)); - pos = xcalloc(n, sizeof(int)); - /* start timer */ - timer = xtime(); - /* order vertices */ - for (i = 0; i < n; i++) - { nwt[i] = 0; - for (j = 0; j < n; j++) - if (is_edge(csa, i, j)) nwt[i] += wt[j]; - } - for (i = 0; i < n; i++) - used[i] = 0; - for (i = n-1; i >= 0; i--) - { max_wt = -1; - max_nwt = -1; - for (j = 0; j < n; j++) - { if ((!used[j]) && ((wt[j] > max_wt) || (wt[j] == max_wt - && nwt[j] > max_nwt))) - { max_wt = wt[j]; - max_nwt = nwt[j]; - p = j; - } - } - pos[i] = p; - used[p] = 1; - for (j = 0; j < n; j++) - if ((!used[j]) && (j != p) && (is_edge(csa, p, j))) - nwt[j] -= wt[p]; - } - /* main routine */ - wth = 0; - for (i = 0; i < n; i++) - { wth += wt[pos[i]]; - sub(csa, i, pos, 0, 0, wth); - clique[pos[i]] = record; - if (xdifftime(xtime(), timer) >= 5.0 - 0.001) - { /* print current record and reset timer */ - xprintf("level = %d (%d); best = %d\n", i+1, n, record); - timer = xtime(); - } - } - xfree(clique); - xfree(set); - xfree(used); - xfree(nwt); - xfree(pos); - /* return the solution found */ - for (i = 1; i <= rec_level; i++) ind[i]++; - return rec_level; -} - -#undef n -#undef wt -#undef a -#undef record -#undef rec_level -#undef rec -#undef clique -#undef set - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/wclique.h b/resources/3rdparty/glpk-4.53/src/misc/wclique.h deleted file mode 100644 index bc6853899..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/wclique.h +++ /dev/null @@ -1,33 +0,0 @@ -/* wclique.h (maximum weight clique, Ostergard's algorithm) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2009, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef WCLIQUE_H -#define WCLIQUE_H - -#define wclique _glp_wclique -int wclique(int n, const int w[], const unsigned char a[], int ind[]); -/* find maximum weight clique with Ostergard's algorithm */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/wclique1.c b/resources/3rdparty/glpk-4.53/src/misc/wclique1.c deleted file mode 100644 index ea36ddd73..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/wclique1.c +++ /dev/null @@ -1,317 +0,0 @@ -/* wclique1.c (maximum weight clique, greedy heuristic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#include "env.h" -#include "wclique1.h" - -/*********************************************************************** -* NAME -* -* wclique1 - find maximum weight clique with greedy heuristic -* -* SYNOPSIS -* -* #include "wclique1.h" -* int wclique1(int n, const double w[], -* int (*func)(void *info, int i, int ind[]), void *info, int c[]); -* -* DESCRIPTION -* -* The routine wclique1 implements a sequential greedy heuristic to -* find maximum weight clique in a given (undirected) graph G = (V, E). -* -* The parameter n specifies the number of vertices |V| in the graph, -* n >= 0. -* -* The array w specifies vertex weights in locations w[i], i = 1,...,n. -* All weights must be non-negative. -* -* The formal routine func specifies the graph. For a given vertex i, -* 1 <= i <= n, it stores indices of all vertices adjacent to vertex i -* in locations ind[1], ..., ind[deg], where deg is the degree of -* vertex i, 0 <= deg < n, returned on exit. Note that self-loops and -* multiple edges are not allowed. -* -* The parameter info is a cookie passed to the routine func. -* -* On exit the routine wclique1 stores vertex indices included in -* the clique found to locations c[1], ..., c[size], where size is the -* clique size returned by the routine, 0 <= size <= n. -* -* RETURNS -* -* The routine wclique1 returns the size of the clique found. */ - -struct vertex { int i; double cw; }; - -static int fcmp(const void *xx, const void *yy) -{ const struct vertex *x = xx, *y = yy; - if (x->cw > y->cw) return -1; - if (x->cw < y->cw) return +1; - return 0; -} - -int wclique1(int n, const double w[], - int (*func)(void *info, int i, int ind[]), void *info, int c[]) -{ struct vertex *v_list; - int deg, c_size, d_size, i, j, k, kk, l, *ind, *c_list, *d_list, - size = 0; - double c_wght, d_wght, *sw, best = 0.0; - char *d_flag, *skip; - /* perform sanity checks */ - xassert(n >= 0); - for (i = 1; i <= n; i++) - xassert(w[i] >= 0.0); - /* if the graph is empty, nothing to do */ - if (n == 0) goto done; - /* allocate working arrays */ - ind = xcalloc(1+n, sizeof(int)); - v_list = xcalloc(1+n, sizeof(struct vertex)); - c_list = xcalloc(1+n, sizeof(int)); - d_list = xcalloc(1+n, sizeof(int)); - d_flag = xcalloc(1+n, sizeof(char)); - skip = xcalloc(1+n, sizeof(char)); - sw = xcalloc(1+n, sizeof(double)); - /* build the vertex list */ - for (i = 1; i <= n; i++) - { v_list[i].i = i; - /* compute the cumulative weight of each vertex i, which is - * cw[i] = w[i] + sum{j : (i,j) in E} w[j] */ - v_list[i].cw = w[i]; - deg = func(info, i, ind); - xassert(0 <= deg && deg < n); - for (k = 1; k <= deg; k++) - { j = ind[k]; - xassert(1 <= j && j <= n && j != i); - v_list[i].cw += w[j]; - } - } - /* sort the vertex list to access vertices in descending order of - * cumulative weights */ - qsort(&v_list[1], n, sizeof(struct vertex), fcmp); - /* initially all vertices are unmarked */ - memset(&skip[1], 0, sizeof(char) * n); - /* clear flags of all vertices */ - memset(&d_flag[1], 0, sizeof(char) * n); - /* look through all vertices of the graph */ - for (l = 1; l <= n; l++) - { /* take vertex i */ - i = v_list[l].i; - /* if this vertex was already included in one of previosuly - * constructed cliques, skip it */ - if (skip[i]) continue; - /* use vertex i as the initial clique vertex */ - c_size = 1; /* size of current clique */ - c_list[1] = i; /* list of vertices in current clique */ - c_wght = w[i]; /* weight of current clique */ - /* determine the candidate set D = { j : (i,j) in E } */ - d_size = func(info, i, d_list); - xassert(0 <= d_size && d_size < n); - d_wght = 0.0; /* weight of set D */ - for (k = 1; k <= d_size; k++) - { j = d_list[k]; - xassert(1 <= j && j <= n && j != i); - xassert(!d_flag[j]); - d_flag[j] = 1; - d_wght += w[j]; - } - /* check an upper bound to the final clique weight */ - if (c_wght + d_wght < best + 1e-5 * (1.0 + fabs(best))) - { /* skip constructing the current clique */ - goto next; - } - /* compute the summary weight of each vertex i in D, which is - * sw[i] = w[i] + sum{j in D and (i,j) in E} w[j] */ - for (k = 1; k <= d_size; k++) - { i = d_list[k]; - sw[i] = w[i]; - /* consider vertices adjacent to vertex i */ - deg = func(info, i, ind); - xassert(0 <= deg && deg < n); - for (kk = 1; kk <= deg; kk++) - { j = ind[kk]; - xassert(1 <= j && j <= n && j != i); - if (d_flag[j]) sw[i] += w[j]; - } - } - /* grow the current clique by adding vertices from D */ - while (d_size > 0) - { /* check an upper bound to the final clique weight */ - if (c_wght + d_wght < best + 1e-5 * (1.0 + fabs(best))) - { /* skip constructing the current clique */ - goto next; - } - /* choose vertex i in D having maximal summary weight */ - i = d_list[1]; - for (k = 2; k <= d_size; k++) - { j = d_list[k]; - if (sw[i] < sw[j]) i = j; - } - /* include vertex i in the current clique */ - c_size++; - c_list[c_size] = i; - c_wght += w[i]; - /* remove all vertices not adjacent to vertex i, including - * vertex i itself, from the candidate set D */ - deg = func(info, i, ind); - xassert(0 <= deg && deg < n); - for (k = 1; k <= deg; k++) - { j = ind[k]; - xassert(1 <= j && j <= n && j != i); - /* vertex j is adjacent to vertex i */ - if (d_flag[j]) - { xassert(d_flag[j] == 1); - /* mark vertex j to keep it in D */ - d_flag[j] = 2; - } - } - kk = d_size, d_size = 0; - for (k = 1; k <= kk; k++) - { j = d_list[k]; - if (d_flag[j] == 1) - { /* remove vertex j from D */ - d_flag[j] = 0; - d_wght -= w[j]; - } - else if (d_flag[j] == 2) - { /* keep vertex j in D */ - d_list[++d_size] = j; - d_flag[j] = 1; - } - else - xassert(d_flag != d_flag); - } - } - /* the current clique has been completely constructed */ - if (best < c_wght) - { best = c_wght; - size = c_size; - xassert(1 <= size && size <= n); - memcpy(&c[1], &c_list[1], size * sizeof(int)); - } -next: /* mark the current clique vertices in order not to use them - * as initial vertices anymore */ - for (k = 1; k <= c_size; k++) - skip[c_list[k]] = 1; - /* set D can be non-empty, so clean up vertex flags */ - for (k = 1; k <= d_size; k++) - d_flag[d_list[k]] = 0; - } - /* free working arrays */ - xfree(ind); - xfree(v_list); - xfree(c_list); - xfree(d_list); - xfree(d_flag); - xfree(skip); - xfree(sw); -done: /* return to the calling program */ - return size; -} - -/**********************************************************************/ - -#ifdef GLP_TEST -#include "glpk.h" -#include "rng.h" - -typedef struct { double w; } v_data; - -#define weight(v) (((v_data *)((v)->data))->w) - -glp_graph *G; - -char *flag; - -int func(void *info, int i, int ind[]) -{ glp_arc *e; - int j, k, deg = 0; - xassert(info == NULL); - xassert(1 <= i && i <= G->nv); - /* look through incoming arcs */ - for (e = G->v[i]->in; e != NULL; e = e->h_next) - { j = e->tail->i; /* j->i */ - if (j != i && !flag[j]) ind[++deg] = j, flag[j] = 1; - } - /* look through outgoing arcs */ - for (e = G->v[i]->out; e != NULL; e = e->t_next) - { j = e->head->i; /* i->j */ - if (j != i && !flag[j]) ind[++deg] = j, flag[j] = 1; - } - /* clear the flag array */ - xassert(deg < G->nv); - for (k = 1; k <= deg; k++) flag[ind[k]] = 0; - return deg; -} - -int main(int argc, char *argv[]) -{ RNG *rand; - int i, k, kk, size, *c, *ind, deg; - double *w, sum, t; - /* read graph in DIMACS format */ - G = glp_create_graph(sizeof(v_data), 0); - xassert(argc == 2); - xassert(glp_read_ccdata(G, offsetof(v_data, w), argv[1]) == 0); - /* print the number of connected components */ - xprintf("nc = %d\n", glp_weak_comp(G, -1)); - /* assign random weights unformly distributed in [1,100] */ - w = xcalloc(1+G->nv, sizeof(double)); - rand = rng_create_rand(); - for (i = 1; i <= G->nv; i++) -#if 0 - w[i] = weight(G->v[i]) = 1.0; -#else - w[i] = weight(G->v[i]) = rng_unif_rand(rand, 100) + 1; -#endif - /* write graph in DIMACS format */ - xassert(glp_write_ccdata(G, offsetof(v_data, w), "graph") == 0); - /* find maximum weight clique */ - c = xcalloc(1+G->nv, sizeof(int)); - flag = xcalloc(1+G->nv, sizeof(char)); - memset(&flag[1], 0, G->nv); - t = xtime(); - size = wclique1(G->nv, w, func, NULL, c); - xprintf("Time used: %.1f s\n", xdifftime(xtime(), t)); - /* check the clique found */ - ind = xcalloc(1+G->nv, sizeof(int)); - for (k = 1; k <= size; k++) - { i = c[k]; - deg = func(NULL, i, ind); - for (kk = 1; kk <= size; kk++) - flag[c[kk]] = 1; - flag[i] = 0; - for (kk = 1; kk <= deg; kk++) - flag[ind[kk]] = 0; - for (kk = 1; kk <= size; kk++) - xassert(flag[c[kk]] == 0); - } - /* compute the clique weight */ - sum = 0.0; - for (i = 1; i <= size; i++) - sum += w[c[i]]; - xprintf("size = %d; sum = %g\n", size, sum); - return 0; -} -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/misc/wclique1.h b/resources/3rdparty/glpk-4.53/src/misc/wclique1.h deleted file mode 100644 index 14e10cba5..000000000 --- a/resources/3rdparty/glpk-4.53/src/misc/wclique1.h +++ /dev/null @@ -1,34 +0,0 @@ -/* wclique1.h (maximum weight clique, greedy heuristic) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2012, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef WCLIQUE1_H -#define WCLIQUE1_H - -#define wclique1 _glp_wclique1 -int wclique1(int n, const double w[], - int (*func)(void *info, int i, int ind[]), void *info, int c[]); -/* find maximum weight clique with greedy heuristic */ - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/prob.h b/resources/3rdparty/glpk-4.53/src/prob.h deleted file mode 100644 index 1b9236114..000000000 --- a/resources/3rdparty/glpk-4.53/src/prob.h +++ /dev/null @@ -1,276 +0,0 @@ -/* prob.h (LP/MIP problem object) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -* 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef PROB_H -#define PROB_H - -#include "avl.h" -#include "bfd.h" -#include "dmp.h" -#include "glpk.h" - -typedef struct GLPROW GLPROW; -typedef struct GLPCOL GLPCOL; -typedef struct GLPAIJ GLPAIJ; - -#define GLP_PROB_MAGIC 0xD7D9D6C2 - -struct glp_prob -{ /* LP/MIP problem object */ - unsigned magic; - /* magic value used for debugging */ - DMP *pool; - /* memory pool to store problem object components */ - glp_tree *tree; - /* pointer to the search tree; set by the MIP solver when this - object is used in the tree as a core MIP object */ - void *parms; - /* reserved for backward compatibility */ - /*--------------------------------------------------------------*/ - /* LP/MIP data */ - char *name; - /* problem name (1 to 255 chars); NULL means no name is assigned - to the problem */ - char *obj; - /* objective function name (1 to 255 chars); NULL means no name - is assigned to the objective function */ - int dir; - /* optimization direction flag (objective "sense"): - GLP_MIN - minimization - GLP_MAX - maximization */ - double c0; - /* constant term of the objective function ("shift") */ - int m_max; - /* length of the array of rows (enlarged automatically) */ - int n_max; - /* length of the array of columns (enlarged automatically) */ - int m; - /* number of rows, 0 <= m <= m_max */ - int n; - /* number of columns, 0 <= n <= n_max */ - int nnz; - /* number of non-zero constraint coefficients, nnz >= 0 */ - GLPROW **row; /* GLPROW *row[1+m_max]; */ - /* row[i], 1 <= i <= m, is a pointer to i-th row */ - GLPCOL **col; /* GLPCOL *col[1+n_max]; */ - /* col[j], 1 <= j <= n, is a pointer to j-th column */ - AVL *r_tree; - /* row index to find rows by their names; NULL means this index - does not exist */ - AVL *c_tree; - /* column index to find columns by their names; NULL means this - index does not exist */ - /*--------------------------------------------------------------*/ - /* basis factorization (LP) */ - int valid; - /* the factorization is valid only if this flag is set */ - int *head; /* int head[1+m_max]; */ - /* basis header (valid only if the factorization is valid); - head[i] = k is the ordinal number of auxiliary (1 <= k <= m) - or structural (m+1 <= k <= m+n) variable which corresponds to - i-th basic variable xB[i], 1 <= i <= m */ - glp_bfcp *bfcp; - /* basis factorization control parameters; may be NULL */ - BFD *bfd; /* BFD bfd[1:m,1:m]; */ - /* basis factorization driver; may be NULL */ - /*--------------------------------------------------------------*/ - /* basic solution (LP) */ - int pbs_stat; - /* primal basic solution status: - GLP_UNDEF - primal solution is undefined - GLP_FEAS - primal solution is feasible - GLP_INFEAS - primal solution is infeasible - GLP_NOFEAS - no primal feasible solution exists */ - int dbs_stat; - /* dual basic solution status: - GLP_UNDEF - dual solution is undefined - GLP_FEAS - dual solution is feasible - GLP_INFEAS - dual solution is infeasible - GLP_NOFEAS - no dual feasible solution exists */ - double obj_val; - /* objective function value */ - int it_cnt; - /* simplex method iteration count; increased by one on performing - one simplex iteration */ - int some; - /* ordinal number of some auxiliary or structural variable having - certain property, 0 <= some <= m+n */ - /*--------------------------------------------------------------*/ - /* interior-point solution (LP) */ - int ipt_stat; - /* interior-point solution status: - GLP_UNDEF - interior solution is undefined - GLP_OPT - interior solution is optimal - GLP_INFEAS - interior solution is infeasible - GLP_NOFEAS - no feasible solution exists */ - double ipt_obj; - /* objective function value */ - /*--------------------------------------------------------------*/ - /* integer solution (MIP) */ - int mip_stat; - /* integer solution status: - GLP_UNDEF - integer solution is undefined - GLP_OPT - integer solution is optimal - GLP_FEAS - integer solution is feasible - GLP_NOFEAS - no integer solution exists */ - double mip_obj; - /* objective function value */ -}; - -struct GLPROW -{ /* LP/MIP row (auxiliary variable) */ - int i; - /* ordinal number (1 to m) assigned to this row */ - char *name; - /* row name (1 to 255 chars); NULL means no name is assigned to - this row */ - AVLNODE *node; - /* pointer to corresponding node in the row index; NULL means - that either the row index does not exist or this row has no - name assigned */ -#if 1 /* 20/IX-2008 */ - int level; - unsigned char origin; - unsigned char klass; -#endif - int type; - /* type of the auxiliary variable: - GLP_FR - free variable - GLP_LO - variable with lower bound - GLP_UP - variable with upper bound - GLP_DB - double-bounded variable - GLP_FX - fixed variable */ - double lb; /* non-scaled */ - /* lower bound; if the row has no lower bound, lb is zero */ - double ub; /* non-scaled */ - /* upper bound; if the row has no upper bound, ub is zero */ - /* if the row type is GLP_FX, ub is equal to lb */ - GLPAIJ *ptr; /* non-scaled */ - /* pointer to doubly linked list of constraint coefficients which - are placed in this row */ - double rii; - /* diagonal element r[i,i] of scaling matrix R for this row; - if the scaling is not used, r[i,i] is 1 */ - int stat; - /* status of the auxiliary variable: - GLP_BS - basic variable - GLP_NL - non-basic variable on lower bound - GLP_NU - non-basic variable on upper bound - GLP_NF - non-basic free variable - GLP_NS - non-basic fixed variable */ - int bind; - /* if the auxiliary variable is basic, head[bind] refers to this - row, otherwise, bind is 0; this attribute is valid only if the - basis factorization is valid */ - double prim; /* non-scaled */ - /* primal value of the auxiliary variable in basic solution */ - double dual; /* non-scaled */ - /* dual value of the auxiliary variable in basic solution */ - double pval; /* non-scaled */ - /* primal value of the auxiliary variable in interior solution */ - double dval; /* non-scaled */ - /* dual value of the auxiliary variable in interior solution */ - double mipx; /* non-scaled */ - /* primal value of the auxiliary variable in integer solution */ -}; - -struct GLPCOL -{ /* LP/MIP column (structural variable) */ - int j; - /* ordinal number (1 to n) assigned to this column */ - char *name; - /* column name (1 to 255 chars); NULL means no name is assigned - to this column */ - AVLNODE *node; - /* pointer to corresponding node in the column index; NULL means - that either the column index does not exist or the column has - no name assigned */ - int kind; - /* kind of the structural variable: - GLP_CV - continuous variable - GLP_IV - integer or binary variable */ - int type; - /* type of the structural variable: - GLP_FR - free variable - GLP_LO - variable with lower bound - GLP_UP - variable with upper bound - GLP_DB - double-bounded variable - GLP_FX - fixed variable */ - double lb; /* non-scaled */ - /* lower bound; if the column has no lower bound, lb is zero */ - double ub; /* non-scaled */ - /* upper bound; if the column has no upper bound, ub is zero */ - /* if the column type is GLP_FX, ub is equal to lb */ - double coef; /* non-scaled */ - /* objective coefficient at the structural variable */ - GLPAIJ *ptr; /* non-scaled */ - /* pointer to doubly linked list of constraint coefficients which - are placed in this column */ - double sjj; - /* diagonal element s[j,j] of scaling matrix S for this column; - if the scaling is not used, s[j,j] is 1 */ - int stat; - /* status of the structural variable: - GLP_BS - basic variable - GLP_NL - non-basic variable on lower bound - GLP_NU - non-basic variable on upper bound - GLP_NF - non-basic free variable - GLP_NS - non-basic fixed variable */ - int bind; - /* if the structural variable is basic, head[bind] refers to - this column; otherwise, bind is 0; this attribute is valid only - if the basis factorization is valid */ - double prim; /* non-scaled */ - /* primal value of the structural variable in basic solution */ - double dual; /* non-scaled */ - /* dual value of the structural variable in basic solution */ - double pval; /* non-scaled */ - /* primal value of the structural variable in interior solution */ - double dval; /* non-scaled */ - /* dual value of the structural variable in interior solution */ - double mipx; /* non-scaled */ - /* primal value of the structural variable in integer solution */ -}; - -struct GLPAIJ -{ /* constraint coefficient a[i,j] */ - GLPROW *row; - /* pointer to row, where this coefficient is placed */ - GLPCOL *col; - /* pointer to column, where this coefficient is placed */ - double val; - /* numeric (non-zero) value of this coefficient */ - GLPAIJ *r_prev; - /* pointer to previous coefficient in the same row */ - GLPAIJ *r_next; - /* pointer to next coefficient in the same row */ - GLPAIJ *c_prev; - /* pointer to previous coefficient in the same column */ - GLPAIJ *c_next; - /* pointer to next coefficient in the same column */ -}; - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/proxy/main.c b/resources/3rdparty/glpk-4.53/src/proxy/main.c deleted file mode 100644 index a7d1e2b87..000000000 --- a/resources/3rdparty/glpk-4.53/src/proxy/main.c +++ /dev/null @@ -1,87 +0,0 @@ -/* Last update: 08-May-2013 */ - -#include -#include -#include - -#include "glpk.h" -#include "proxy.h" - -/**********************************************************************/ -int main(int argc, char **argv) -/**********************************************************************/ -{ - glp_prob *lp; - int ncols, status; - double *initsol, zstar, *xstar; - - /* check arguments */ - if ( (argc == 1) || (argc > 3) ) { - printf("ERROR: Usage: ts <(possibly) xml initsols>\n" - ); - exit(1); - } - - /* creating the problem */ - lp = glp_create_prob(); - glp_set_prob_name(lp, "Proxy"); - - /* reading the problem */ - glp_term_out(GLP_OFF); -#if 0 /* by mao */ - status = glp_read_lp(lp, NULL, argv[1]); -#else - status = glp_read_mps(lp, GLP_MPS_FILE, NULL, argv[1]); -#endif - glp_term_out(GLP_ON); - if ( status ) { - printf("Problem %s does not exist!!!, status %d\n", - argv[1], status); - exit(1); - } - - ncols = glp_get_num_cols(lp); - - initsol = (double *) calloc(ncols+1, sizeof(double)); - - if (argc == 3) { - FILE *fp=fopen(argv[2],"r"); - char tmp[256]={0x0}; - int counter = 1; - while(fp!=NULL && fgets(tmp, sizeof(tmp),fp)!=NULL) - { - char *valini = strstr(tmp, "value"); - if (valini!=NULL){ - int num; - double dnum; - valini +=7; - sscanf(valini, "%d%*s",&num); - dnum = (double)num; - initsol[counter] = dnum; - counter++; - } - } - fclose(fp); - } - - xstar = (double *) calloc(ncols+1, sizeof(double)); - - if (argc == 3) { - status = proxy(lp, &zstar, xstar, initsol, 0.0, 0, 1); - } - else { - status = proxy(lp, &zstar, xstar, NULL, 0.0, 0, 1); - } - - printf("Status = %d; ZSTAR = %f\n",status,zstar); - /* - int i; - for (i=1; i< ncols+1; i++) { - printf("XSTAR[%d] = %f\n",i, xstar[i]); - } - */ - - glp_delete_prob(lp); - - return 0; -} diff --git a/resources/3rdparty/glpk-4.53/src/proxy/proxy.c b/resources/3rdparty/glpk-4.53/src/proxy/proxy.c deleted file mode 100644 index 31502a7f7..000000000 --- a/resources/3rdparty/glpk-4.53/src/proxy/proxy.c +++ /dev/null @@ -1,1061 +0,0 @@ -/* proxy.c (proximity search heuristic algorithm) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Author: Giorgio Sartor <0gioker0@gmail.com>. -* -* Copyright (C) 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -* -************************************************************************ -* -* THIS CODE IS AN IMPLEMENTATION OF THE ALGORITHM PROPOSED IN -* -* M. Fischetti, M. Monaci, -* "Proximity Search for 0-1 Mixed-Integer Convex Programming" -* Technical Report DEI, University of Padua, March 2013. -* -* AVAILABLE AT -* http://www.dei.unipd.it/~fisch/papers/proximity_search.pdf -* -* THE CODE HAS BEEN WRITTEN BY GIORGIO SARTOR, " 0gioker0@gmail.com " -* -* BASIC IDEA: -* -* The initial feasible solution x_tilde is defined. This initial -* solution can be found by an ad-hoc heuristic and proxy can be used to -* refine it by exploiting an underlying MIP model whose solution from -* scratch turned out to be problematic. Otherwise, x_tilde can be found -* by running the GLPK mip solver until a first feasible solution is -* found, setting a conservative time limit of 10 minutes (by default). -* Time limit can be modified passing variable tlim [ms]. -* -* Then the cutoff tolerance "delta" is defined. The default tolerance -* is 1% of the last feasible solution obj value--rounded to integer if -* all the variables and obj coefficients are integer. -* -* Next, the objective function c' x is replaced by the Hamming distance -* between x (the actual obj coefficients) and x_tilde (the given -* solution). Distance is only computed wrt the binary variables. -* -* The GLPK solver is then invoked to hopefully find a new incumbent -* x_star with cost c' x_star <= c' x_tilde - delta. A crucial property -* here is that the root-node solution of the LP relaxation is expected -* to be not too different from x_tilde, as this latter solution would -* be optimal without the cutoff constraint, that for a small delta can -* typically be fulfilled with just local adjustments. -* -* If no new solution x_star is found within the time limit the -* algorithm stops. Of course, if the MIP solver proved infeasibility -* for the given delta, we have that c' x_tilde - delta is a valid lower -* bound (in case of minimazation) on the optimal value of the original -* MIP. -* -* The new solution x_star, if any, is possibly improved by solving a -* simplified problem (refinement) where all binary variables have been -* fixed to their value in x_star so as to find the best solution within -* the neighborhood. -* -* Finally, the approach is reapplied on x_star (that replaces x_tilde) -* so as to recenter the distance Hamming function and by modifying the -* cutoff tolerance delta. -* -* In this way, there will be a series of hopefully not-too-difficult -* sub-MIPs to solve, each leading to an improvement of the incumbent. -* More aggressive policies on the definition of tolerance delta can -* lead to a better performance, but would require an ad-hoc tuning. -* -************************************************************************ -* -* int proxy(glp_prob *lp, double *zstar, double *xstar, -* const double[] initsol, double rel_impr, int tlim, -* int verbose) -* -* lp : GLPK problem pointer to a MIP with binary variables -* -* zstar : the value of objective function of the best solution found -* -* xstar : best solution with components xstar[1],...,xstar[ncols] -* -* initsol : pointer to a initial feasible solution, see -* glp_ios_heur_sol -* If initsol = NULL, the procedure finds the first solution -* by itself. -* -* rel_impr : minimum relative obj improvement to be achieved at each -* internal step; if <= 0.0 a default value of 0.01 (1%) is -* used; for some problems (e.g., set covering with small -* integer costs) a more-conservative choice of 0.001 (0.1%) -* can lead to a better final solution; values larger than -* 0.05 (5%) are typically too aggressive and do not work -* well. -* -* tlim : time limit to find a new solution, in ms. -* If tlim = 0, it is set to its default value, 600000 ms -* -* verbose : if 1 the output is activated. If 0 only errors are -* displayed -* -* The procedure returns -1 if an error occurred, 0 otherwise (possibly, -* time limit) -* -***********************************************************************/ - -/**********************************************************************/ -/* 1. INCLUDE */ -/**********************************************************************/ - -#include "glpk.h" -#include "env.h" -#include "proxy.h" - -/**********************************************************************/ -/* 2. PARAMETERS AND CONSTANTS */ -/**********************************************************************/ - -#define TDAY 86400.0 -#define TRUE 1 -#define FALSE 0 -#define EPS 1e-6 -#define RINF 1e38 -#define MAXVAL 1e20 -#define MINVAL -1e20 -#if 0 /* by gioker */ - #define PROXY_DEBUG -#endif - -/**********************************************************************/ -/* 3. GLOBAL VARIABLES */ -/**********************************************************************/ - -struct csa { - -int integer_obj; /* TRUE if each feasible solution has an - integral cost */ -int b_vars_exist; /* TRUE if there is at least one binary - variable in the problem */ -int i_vars_exist; /* TRUE if there is at least one general - integer variable in the problem */ -const double *startsol; /* Pointer to the initial solution */ - -int *ckind; /* Store the kind of the structural variables - of the problem */ -double *clb; /* Store the lower bound on the structural - variables of the problem */ -double *cub; /* Store the upper bound on the structural - variables of the problem */ -double *true_obj; /* Store the obj coefficients of the problem */ - -int dir; /* Minimization or maximization problem */ -int ncols; /* Number of structural variables of the - problem */ - -time_t GLOtstart; /* starting time of the algorithm */ - -glp_prob *lp_ref; /* glp problem for refining only*/ - -}; - -/**********************************************************************/ -/* 4. FUNCTIONS PROTOTYPES */ -/**********************************************************************/ - -static void callback(glp_tree *tree, void *info); -static void get_info(struct csa *csa, glp_prob *lp); -static int is_integer(struct csa *csa); -static void check_integrality(struct csa *csa); -static int check_ref(struct csa *csa, glp_prob *lp, double *xref); -static double second(void); -static int add_cutoff(struct csa *csa, glp_prob *lp); -static void get_sol(struct csa *csa, glp_prob *lp, double *xstar); -static double elapsed_time(struct csa *csa); -static void redefine_obj(glp_prob *lp, double *xtilde, int ncols, - int *ckind, double *clb, double *cub); -static double update_cutoff(struct csa *csa, glp_prob *lp, - double zstar, int index, double rel_impr); -static double compute_delta(struct csa *csa, double z, - double rel_impr); -static double objval(int ncols, double *x, double *true_obj); -static void array_copy(int begin, int end, double *source, - double *destination); -static int do_refine(struct csa *csa, glp_prob *lp_ref, int ncols, - int *ckind, double *xref, int *tlim, int tref_lim, - int verbose); -static void deallocate(struct csa *csa, int refine); - -/**********************************************************************/ -/* 5. FUNCTIONS */ -/**********************************************************************/ - -int proxy(glp_prob *lp, double *zfinal, double *xfinal, - const double initsol[], double rel_impr, int tlim, - int verbose) - -{ struct csa csa_, *csa = &csa_; - glp_iocp parm; - glp_smcp parm_lp; - size_t tpeak; - int refine, tref_lim, err, cutoff_row, niter, status, i, tout; - double *xref, *xstar, zstar, tela, cutoff, zz; - - memset(csa, 0, sizeof(struct csa)); - - - /********** **********/ - /********** RETRIEVING PROBLEM INFO **********/ - /********** **********/ - - /* getting problem direction (min or max) */ - csa->dir = glp_get_obj_dir(lp); - - /* getting number of variables */ - csa->ncols = glp_get_num_cols(lp); - - /* getting kind, bounds and obj coefficient of each variable - information is stored in ckind, cub, clb, true_obj */ - get_info(csa, lp); - - /* checking if the objective function is always integral */ - check_integrality(csa); - - /* Proximity search cannot be used if there are no binary - variables */ - if (csa->b_vars_exist == FALSE) { - if (verbose) { - xprintf("The problem has not binary variables. Proximity se" - "arch cannot be used.\n"); - } - tfree(csa->ckind); - tfree(csa->clb); - tfree(csa->cub); - tfree(csa->true_obj); - return -1; - } - - /* checking if the problem needs refinement, i.e., not all - variables are binary. If so, the routine creates a copy of the - lp problem named lp_ref and initializes the solution xref to - zero. */ - xref = talloc(csa->ncols+1, double); -#if 0 /* by mao */ - memset(xref, 0, sizeof(double)*(csa->ncols+1)); -#endif - refine = check_ref(csa, lp, xref); -#ifdef PROXY_DEBUG - xprintf("REFINE = %d\n",refine); -#endif - - /* Initializing the solution */ - xstar = talloc(csa->ncols+1, double); -#if 0 /* by mao */ - memset(xstar, 0, sizeof(double)*(csa->ncols+1)); -#endif - - /********** **********/ - /********** FINDING FIRST SOLUTION **********/ - /********** **********/ - - if (verbose) { - xprintf("Applying PROXY heuristic...\n"); - } - - /* get the initial time */ - csa->GLOtstart = second(); - - /* setting the optimization parameters */ - glp_init_iocp(&parm); - glp_init_smcp(&parm_lp); -#if 0 /* by gioker */ - /* Preprocessing should be disabled because the mip passed - to proxy is already preprocessed */ - parm.presolve = GLP_ON; -#endif -#if 1 /* by mao */ - /* best projection backtracking seems to be more efficient to find - any integer feasible solution */ - parm.bt_tech = GLP_BT_BPH; -#endif - - /* Setting the default value of the minimum relative improvement - to 1% */ - if ( rel_impr <= 0.0 ) { - rel_impr = 0.01; - } - - /* Setting the default value of time limit to 10 minutes */ - if (tlim <= 0) { - tlim = INT_MAX; - } - if (verbose) { - xprintf("Proxy's time limit set to %d seconds.\n",tlim/1000); - xprintf("Proxy's relative improvement " - "set to %2.2lf %c.\n",rel_impr*100,37); - } - - parm_lp.tm_lim = tlim; - - parm.mip_gap = 9999999.9; /* to stop the optimization at the first - feasible solution found */ - - /* finding the first solution */ - if (verbose) { - xprintf("Searching for a feasible solution...\n"); - } - - /* verifying the existence of an input starting solution */ - if (initsol != NULL) { - csa->startsol = initsol; - parm.cb_func = callback; - parm.cb_info = csa; - if (verbose) { - xprintf("Input solution found.\n"); - } - } - - tout = glp_term_out(GLP_OFF); - err = glp_simplex(lp,&parm_lp); - glp_term_out(tout); - - status = glp_get_status(lp); - - if (status != GLP_OPT) { - if (verbose) { - xprintf("Proxy heuristic terminated.\n"); - } -#ifdef PROXY_DEBUG - /* For debug only */ - xprintf("GLP_SIMPLEX status = %d\n",status); - xprintf("GLP_SIMPLEX error code = %d\n",err); -#endif - tfree(xref); - tfree(xstar); - deallocate(csa, refine); - return -1; - } - - tela = elapsed_time(csa); - if (tlim-tela*1000 <= 0) { - if (verbose) { - xprintf("Time limit exceeded. Proxy could not " - "find optimal solution to LP relaxation.\n"); - xprintf("Proxy heuristic aborted.\n"); - } - tfree(xref); - tfree(xstar); - deallocate(csa, refine); - return -1; - } - - parm.tm_lim = tlim - tela*1000; - tref_lim = (tlim - tela *1000) / 20; - - tout = glp_term_out(GLP_OFF); - err = glp_intopt(lp, &parm); - glp_term_out(tout); - - status = glp_mip_status(lp); - - /***** If no solution was found *****/ - - if (status == GLP_NOFEAS || status == GLP_UNDEF) { - if (err == GLP_ETMLIM) { - if (verbose) { - xprintf("Time limit exceeded. Proxy could not " - "find an initial integer feasible solution.\n"); - xprintf("Proxy heuristic aborted.\n"); - } - } - else { - if (verbose) { - xprintf("Proxy could not " - "find an initial integer feasible solution.\n"); - xprintf("Proxy heuristic aborted.\n"); - } - } - tfree(xref); - tfree(xstar); - deallocate(csa, refine); - return -1; - } - - /* getting the first solution and its value */ - get_sol(csa, lp,xstar); - zstar = glp_mip_obj_val(lp); - - if (verbose) { - xprintf(">>>>> first solution = %e;\n", zstar); - } - - /* If a feasible solution was found but the time limit is - exceeded */ - if (err == GLP_ETMLIM) { - if (verbose) { - xprintf("Time limit exceeded. Proxy heuristic terminated.\n"); - } - goto done; - } - - tela = elapsed_time(csa); - tpeak = 0; - glp_mem_usage(NULL, NULL, NULL, &tpeak); - if (verbose) { - xprintf("Time used: %3.1lf secs. Memory used: %2.1lf Mb\n", - tela,(double)tpeak/1048576); - xprintf("Starting proximity search...\n"); - } - - /********** **********/ - /********** PREPARING THE PROBLEM FOR PROXY **********/ - /********** **********/ - - /* adding a dummy cutoff constraint */ - cutoff_row = add_cutoff(csa, lp); - - /* proximity search needs minimization direction - even if the problem is a maximization one */ - if (csa->dir == GLP_MAX) { - glp_set_obj_dir(lp, GLP_MIN); - } - - /********** **********/ - /********** STARTING PROXIMITY SEARCH **********/ - /********** **********/ - - - niter = 0; - - while (TRUE) { - niter++; - - /********** CHANGING THE OBJ FUNCTION **********/ - - redefine_obj(lp,xstar, csa->ncols, csa->ckind, csa->clb, - csa->cub); - - /********** UPDATING THE CUTOFF CONSTRAINT **********/ - - cutoff = update_cutoff(csa, lp,zstar, cutoff_row, rel_impr); - -#ifdef PROXY_DEBUG - xprintf("TRUE_OBJ[0] = %f\n",csa->true_obj[0]); - xprintf("ZSTAR = %f\n",zstar); - xprintf("CUTOFF = %f\n",cutoff); -#endif - - /********** SEARCHING FOR A BETTER SOLUTION **********/ - - tela = elapsed_time(csa); - if (tlim-tela*1000 <= 0) { - if (verbose) { - xprintf("Time limit exceeded. Proxy heuristic " - "terminated.\n"); - } - goto done; - } -#ifdef PROXY_DEBUG - xprintf("TELA = %3.1lf\n",tela*1000); - xprintf("TLIM = %3.1lf\n",tlim - tela*1000); -#endif - parm_lp.tm_lim = tlim -tela*1000; - - tout = glp_term_out(GLP_OFF); - err = glp_simplex(lp,&parm_lp); - glp_term_out(tout); - - status = glp_get_status(lp); - - if (status != GLP_OPT) { - if (status == GLP_NOFEAS) { - if (verbose) { - xprintf("Bound exceeded = %f. ",cutoff); - } - } - if (verbose) { - xprintf("Proxy heuristic terminated.\n"); - } -#ifdef PROXY_DEBUG - xprintf("GLP_SIMPLEX status = %d\n",status); - xprintf("GLP_SIMPLEX error code = %d\n",err); -#endif - goto done; - } - - tela = elapsed_time(csa); - if (tlim-tela*1000 <= 0) { - if (verbose) { - xprintf("Time limit exceeded. Proxy heuristic " - "terminated.\n"); - } - goto done; - } - parm.tm_lim = tlim - tela*1000; - parm.cb_func = NULL; -#if 0 /* by gioker */ - /* Preprocessing should be disabled because the mip passed - to proxy is already preprocessed */ - parm.presolve = GLP_ON; -#endif - tout = glp_term_out(GLP_OFF); - err = glp_intopt(lp, &parm); - glp_term_out(tout); - - /********** MANAGEMENT OF THE SOLUTION **********/ - - status = glp_mip_status(lp); - - /***** No feasible solutions *****/ - - if (status == GLP_NOFEAS) { - if (verbose) { - xprintf("Bound exceeded = %f. Proxy heuristic " - "terminated.\n",cutoff); - } - goto done; - } - - /***** Undefined solution *****/ - - if (status == GLP_UNDEF) { - if (err == GLP_ETMLIM) { - if (verbose) { - xprintf("Time limit exceeded. Proxy heuristic " - "terminated.\n"); - } - } - else { - if (verbose) { - xprintf("Proxy terminated unexpectedly.\n"); -#ifdef PROXY_DEBUG - xprintf("GLP_INTOPT error code = %d\n",err); -#endif - } - } - goto done; - } - - /***** Feasible solution *****/ - - if ((status == GLP_FEAS) || (status == GLP_OPT)) { - - /* getting the solution and computing its value */ - get_sol(csa, lp,xstar); - zz = objval(csa->ncols, xstar, csa->true_obj); - - /* Comparing the incumbent solution with the current best - one */ -#ifdef PROXY_DEBUG - xprintf("ZZ = %f\n",zz); - xprintf("ZSTAR = %f\n",zstar); - xprintf("REFINE = %d\n",refine); -#endif - if (((zzdir == GLP_MIN)) || - ((zz>zstar) && (csa->dir == GLP_MAX))) { - - /* refining (possibly) the solution */ - if (refine) { - - /* copying the incumbent solution in the refinement - one */ - array_copy(1, csa->ncols +1, xstar, xref); - err = do_refine(csa, csa->lp_ref, csa->ncols, - csa->ckind, xref, &tlim, tref_lim, verbose); - if (!err) { - double zref = objval(csa->ncols, xref, - csa->true_obj); - if (((zrefdir == GLP_MIN)) || - ((zref>zz) && (csa->dir == GLP_MAX))) { - zz = zref; - /* copying the refinement solution in the - incumbent one */ - array_copy(1, csa->ncols +1, xref, xstar); - } - } - } - zstar = zz; - tela = elapsed_time(csa); - if (verbose) { - xprintf(">>>>> it: %3d: mip = %e; elapsed time " - "%3.1lf sec.s\n", niter,zstar,tela); - } - } - } - } - -done: - tela = elapsed_time(csa); - glp_mem_usage(NULL, NULL, NULL, &tpeak); - if (verbose) { - xprintf("Time used: %3.1lf. Memory used: %2.1lf Mb\n", - tela,(double)tpeak/1048576); - } - - - /* Exporting solution and obj val */ - *zfinal = zstar; - - for (i=1; i < (csa->ncols + 1); i++) { - xfinal[i]=xstar[i]; - } - - /* Freeing allocated memory */ - tfree(xref); - tfree(xstar); - deallocate(csa, refine); - - return 0; -} - -/**********************************************************************/ -static void callback(glp_tree *tree, void *info){ -/**********************************************************************/ - struct csa *csa = info; - switch(glp_ios_reason(tree)) { - case GLP_IHEUR: - glp_ios_heur_sol(tree, csa->startsol); - break; - default: break; - } -} - -/**********************************************************************/ -static void get_info(struct csa *csa, glp_prob *lp) -/**********************************************************************/ -{ - int i; - - /* Storing helpful info of the problem */ - - csa->ckind = talloc(csa->ncols+1, int); -#if 0 /* by mao */ - memset(csa->ckind, 0, sizeof(int)*(csa->ncols+1)); -#endif - csa->clb = talloc(csa->ncols+1, double); -#if 0 /* by mao */ - memset(csa->clb, 0, sizeof(double)*(csa->ncols+1)); -#endif - csa->cub = talloc(csa->ncols+1, double); -#if 0 /* by mao */ - memset(csa->cub, 0, sizeof(double)*(csa->ncols+1)); -#endif - csa->true_obj = talloc(csa->ncols+1, double); -#if 0 /* by mao */ - memset(csa->true_obj, 0, sizeof(double)*(csa->ncols+1)); -#endif - for( i = 1 ; i < (csa->ncols + 1); i++ ) { - csa->ckind[i] = glp_get_col_kind(lp, i); - csa->clb[i] = glp_get_col_lb(lp, i); - csa->cub[i] = glp_get_col_ub(lp, i); - csa->true_obj[i] = glp_get_obj_coef(lp, i); - } - csa->true_obj[0] = glp_get_obj_coef(lp, 0); -} - -/**********************************************************************/ -static int is_integer(struct csa *csa) -/**********************************************************************/ -{ - int i; - csa->integer_obj = TRUE; - for ( i = 1; i < (csa->ncols + 1); i++ ) { - if (fabs(csa->true_obj[i]) > INT_MAX ) { - csa->integer_obj = FALSE; - } - if (fabs(csa->true_obj[i]) <= INT_MAX) { - double tmp, rem; - if (fabs(csa->true_obj[i]) - floor(fabs(csa->true_obj[i])) - < 0.5) { - tmp = floor(fabs(csa->true_obj[i])); - } - else { - tmp = ceil(fabs(csa->true_obj[i])); - } - rem = fabs(csa->true_obj[i]) - tmp; - rem = fabs(rem); - if (rem > EPS) { - csa->integer_obj = FALSE; - } - - } - } - return csa->integer_obj; -} - -/**********************************************************************/ -static void check_integrality(struct csa *csa) -/**********************************************************************/ -{ - /* - Checking if the problem has binary, integer or continuos variables. - integer_obj is TRUE if the problem has no continuous variables - and all the obj coefficients are integer (and < INT_MAX). - */ - - int i; - csa->integer_obj = is_integer(csa); - csa->b_vars_exist = FALSE; - csa->i_vars_exist = FALSE; - for ( i = 1; i < (csa->ncols + 1); i++ ) { - if ( csa->ckind[i] == GLP_IV ){ - csa->i_vars_exist = TRUE; - continue; - } - if ( csa->ckind[i] == GLP_BV ){ - csa->b_vars_exist =TRUE; - continue; - } - csa->integer_obj = FALSE; - } -} - -/**********************************************************************/ -static int check_ref(struct csa *csa, glp_prob *lp, double *xref) -/**********************************************************************/ -{ - /* - checking if the problem has continuos or integer variables. If so, - refinement is prepared. - */ - int refine = FALSE; - int i; - for ( i = 1; i < (csa->ncols + 1); i++ ) { - if ( csa->ckind[i] != GLP_BV) { - refine = TRUE; - break; - } - } - - /* possibly creating a mip clone for refinement only */ - if ( refine ) { - csa->lp_ref = glp_create_prob(); - glp_copy_prob(csa->lp_ref, lp, GLP_ON); - } - - return refine; -} - -/**********************************************************************/ -static double second(void) -/**********************************************************************/ -{ -#if 0 /* by mao */ - return ((double)clock()/(double)CLOCKS_PER_SEC); -#else - return xtime() / 1000.0; -#endif -} - -/**********************************************************************/ -static int add_cutoff(struct csa *csa, glp_prob *lp) -/**********************************************************************/ -{ - /* - Adding a cutoff constraint to set an upper bound (in case of - minimaztion) on the obj value of the next solution, i.e., the next - value of the true obj function that we would like to find - */ - - /* store non-zero coefficients in the objective function */ - int *obj_index = talloc(csa->ncols+1, int); -#if 0 /* by mao */ - memset(obj_index, 0, sizeof(int)*(csa->ncols+1)); -#endif - double *obj_value = talloc(csa->ncols+1, double); -#if 0 /* by mao */ - memset(obj_value, 0, sizeof(double)*(csa->ncols+1)); -#endif - int obj_nzcnt = 0; - int i, irow; - const char *rowname; - for ( i = 1; i < (csa->ncols + 1); i++ ) { - if ( fabs(csa->true_obj[i]) > EPS ) { - obj_nzcnt++; - obj_index[obj_nzcnt] = i; - obj_value[obj_nzcnt] = csa->true_obj[i]; - } - } - - irow = glp_add_rows(lp, 1); - rowname = "Cutoff"; - glp_set_row_name(lp, irow, rowname); - if (csa->dir == GLP_MIN) { - /* minimization problem */ - glp_set_row_bnds(lp, irow, GLP_UP, MAXVAL, MAXVAL); - } - else { - /* maximization problem */ - glp_set_row_bnds(lp, irow, GLP_LO, MINVAL, MINVAL); - } - - glp_set_mat_row(lp, irow, obj_nzcnt, obj_index, obj_value); - - tfree(obj_index); - tfree(obj_value); - - return irow; -} - -/**********************************************************************/ -static void get_sol(struct csa *csa, glp_prob *lp, double *xstar) -/**********************************************************************/ -{ - /* Retrieving and storing the coefficients of the solution */ - - int i; - for (i = 1; i < (csa->ncols +1); i++) { - xstar[i] = glp_mip_col_val(lp, i); - } -} - -/**********************************************************************/ -static double elapsed_time(struct csa *csa) -/**********************************************************************/ -{ - double tela = second() - csa->GLOtstart; - if ( tela < 0 ) tela += TDAY; - return(tela); -} - -/**********************************************************************/ -static void redefine_obj(glp_prob *lp, double *xtilde, int ncols, - int *ckind, double *clb, double *cub) -/**********************************************************************/ - -/* - Redefine the lp objective function obj as the distance-to-integrality - (Hamming distance) from xtilde (the incumbent feasible solution), wrt - to binary vars only - */ - -{ - int j; - double *delta = talloc(ncols+1, double); -#if 0 /* by mao */ - memset(delta, 0, sizeof(double)*(ncols+1)); -#endif - - for ( j = 1; j < (ncols +1); j++ ) { - delta[j] = 0.0; - /* skip continuous variables */ - if ( ckind[j] == GLP_CV ) continue; - - /* skip integer variables that have been fixed */ - if ( cub[j]-clb[j] < 0.5 ) continue; - - /* binary variable */ - if ( ckind[j] == GLP_BV ) { - if ( xtilde[j] > 0.5 ) { - delta[j] = -1.0; - } - else { - delta[j] = 1.0; - } - } - } - - /* changing the obj coeff. for all variables, including continuous - ones */ - for ( j = 1; j < (ncols +1); j++ ) { - glp_set_obj_coef(lp, j, delta[j]); - } - glp_set_obj_coef(lp, 0, 0.0); - - tfree(delta); -} - -/**********************************************************************/ -static double update_cutoff(struct csa *csa, glp_prob *lp, - double zstar, int cutoff_row, - double rel_impr) -/**********************************************************************/ -{ - /* - Updating the cutoff constraint with the value we would like to - find during the next optimization - */ - double cutoff; - zstar -= csa->true_obj[0]; - if (csa->dir == GLP_MIN) { - cutoff = zstar - compute_delta(csa, zstar, rel_impr); - glp_set_row_bnds(lp, cutoff_row, GLP_UP, cutoff, cutoff); - } - else { - cutoff = zstar + compute_delta(csa, zstar, rel_impr); - glp_set_row_bnds(lp, cutoff_row, GLP_LO, cutoff, cutoff); - } - - return cutoff; -} - -/**********************************************************************/ -static double compute_delta(struct csa *csa, double z, double rel_impr) -/**********************************************************************/ -{ - /* Computing the offset for the next best solution */ - - double delta = rel_impr * fabs(z); - if ( csa->integer_obj ) delta = ceil(delta); - - return(delta); -} - -/**********************************************************************/ -static double objval(int ncols, double *x, double *true_obj) -/**********************************************************************/ -{ - /* Computing the true cost of x (using the original obj coeff.s) */ - - int j; - double z = 0.0; - for ( j = 1; j < (ncols +1); j++ ) { - z += x[j] * true_obj[j]; - } - return z + true_obj[0]; -} - -/**********************************************************************/ -static void array_copy(int begin, int end, double *source, - double *destination) -/**********************************************************************/ -{ - int i; - for (i = begin; i < end; i++) { - destination[i] = source[i]; - } -} -/**********************************************************************/ -static int do_refine(struct csa *csa, glp_prob *lp_ref, int ncols, - int *ckind, double *xref, int *tlim, int tref_lim, - int verbose) -/**********************************************************************/ -{ - /* - Refinement is applied when the variables of the problem are not - all binary. Binary variables are fixed to their value and - remaining ones are optimized. If there are only continuos - variables (in addition to those binary) the problem becomes just - an LP. Otherwise, it remains a MIP but of smaller size. - */ - - int j, tout; - double refineStart = second(); - double val, tela, tlimit; - - if ( glp_get_num_cols(lp_ref) != ncols ) { - if (verbose) { - xprintf("Error in Proxy refinement: "); - xprintf("wrong number of columns (%d vs %d).\n", - ncols, glp_get_num_cols(lp_ref)); - } - return 1; - } - - val = -1.0; - - /* fixing all binary variables to their current value in xref */ - for ( j = 1; j < (ncols + 1); j++ ) { - if ( ckind[j] == GLP_BV ) { - val = 0.0; - if ( xref[j] > 0.5 ) val = 1.0; - glp_set_col_bnds(lp_ref, j, GLP_FX, val, val); - } - } - - /* re-optimizing (refining) if some bound has been changed */ - if ( val > -1.0 ) { - glp_iocp parm_ref; - glp_smcp parm_ref_lp; - int err, status; - - glp_init_iocp(&parm_ref); - parm_ref.presolve = GLP_ON; - glp_init_smcp(&parm_ref_lp); - /* - If there are no general integer variable the problem becomes - an LP (after fixing the binary variables) and can be solved - quickly. Otherwise the problem is still a MIP problem and a - timelimit has to be set. - */ - parm_ref.tm_lim = tref_lim; - if (parm_ref.tm_lim > *tlim) { - parm_ref.tm_lim = *tlim; - } - parm_ref_lp.tm_lim = parm_ref.tm_lim; -#ifdef PROXY_DEBUG - xprintf("***** REFINING *****\n"); -#endif - tout = glp_term_out(GLP_OFF); - if (csa->i_vars_exist == TRUE) { - err = glp_intopt(lp_ref, &parm_ref); - } - else { - err = glp_simplex(lp_ref, &parm_ref_lp); - } - glp_term_out(tout); - - if (csa->i_vars_exist == TRUE) { - status = glp_mip_status(lp_ref); - } - else { - status = glp_get_status(lp_ref); - } -#ifdef PROXY_DEBUG - xprintf("STATUS REFINING = %d\n",status); -#endif - if (status == GLP_UNDEF) { - if (err == GLP_ETMLIM) { -#ifdef PROXY_DEBUG - xprintf("Time limit exceeded on Proxy refining.\n"); -#endif - return 1; - } - } - for( j = 1 ; j < (ncols + 1); j++ ){ - if (ckind[j] != GLP_BV) { - if (csa->i_vars_exist == TRUE) { - xref[j] = glp_mip_col_val(lp_ref, j); - } - else{ - xref[j] = glp_get_col_prim(lp_ref, j); - } - } - } - } - tela = second() - refineStart; -#ifdef PROXY_DEBUG - xprintf("REFINE TELA = %3.1lf\n",tela*1000); -#endif - return 0; -} -/**********************************************************************/ -static void deallocate(struct csa *csa, int refine) -/**********************************************************************/ -{ - /* Deallocating routine */ - - if (refine) { - glp_delete_prob(csa->lp_ref); - } - - tfree(csa->ckind); - tfree(csa->clb); - tfree(csa->cub); - tfree(csa->true_obj); - -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/proxy/proxy.h b/resources/3rdparty/glpk-4.53/src/proxy/proxy.h deleted file mode 100644 index a91e36f2d..000000000 --- a/resources/3rdparty/glpk-4.53/src/proxy/proxy.h +++ /dev/null @@ -1,36 +0,0 @@ -/* proxy.h (proximity search heuristic algorithm) */ - -/*********************************************************************** -* This code is part of GLPK (GNU Linear Programming Kit). -* -* Author: Giorgio Sartor <0gioker0@gmail.com>. -* -* Copyright (C) 2013 Andrew Makhorin, Department for Applied -* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights -* reserved. E-mail: . -* -* GLPK is free software: you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GLPK is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -* License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GLPK. If not, see . -***********************************************************************/ - -#ifndef PROXY_H -#define PROXY_H - -#define proxy _glp_proxy -int proxy(glp_prob *lp, double *zstar, double *xstar, - const double initsol[], double rel_impr, int tlim, - int verbose); - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/proxy/proxy1.c b/resources/3rdparty/glpk-4.53/src/proxy/proxy1.c deleted file mode 100644 index ce96d9e80..000000000 --- a/resources/3rdparty/glpk-4.53/src/proxy/proxy1.c +++ /dev/null @@ -1,39 +0,0 @@ -/* proxy1.c */ - -/* (reserved for copyright notice) */ - -#include "env.h" -#include "glpios.h" -#include "proxy.h" - -void ios_proxy_heur(glp_tree *T) -{ glp_prob *prob; - int j, status; - double *xstar, zstar; - /* this heuristic is applied only once on the root level */ - if (!(T->curr->level == 0 && T->curr->solved == 1)) - goto done; - prob = glp_create_prob(); - glp_copy_prob(prob, T->mip, 0); - xstar = xcalloc(1+prob->n, sizeof(double)); - for (j = 1; j <= prob->n; j++) - xstar[j] = 0.0; - if (T->mip->mip_stat != GLP_FEAS) - status = proxy(prob, &zstar, xstar, NULL, 0.0, - T->parm->ps_tm_lim, 1); - else - { double *xinit = xcalloc(1+prob->n, sizeof(double)); - for (j = 1; j <= prob->n; j++) - xinit[j] = T->mip->col[j]->mipx; - status = proxy(prob, &zstar, xstar, xinit, 0.0, - T->parm->ps_tm_lim, 1); - xfree(xinit); - } - if (status == 0) - glp_ios_heur_sol(T, xstar); - xfree(xstar); - glp_delete_prob(prob); -done: return; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/zlib/README b/resources/3rdparty/glpk-4.53/src/zlib/README deleted file mode 100644 index 2796312f1..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/README +++ /dev/null @@ -1,45 +0,0 @@ -NOTE: Files in this subdirectory are NOT part of the GLPK package, but - are used with GLPK. - - The original code was modified according to GLPK requirements by - Andrew Makhorin . - - The following files were rewritten: - gzguts.h, zconf.h, zutil.h. - - The following files were added: - zio.h, zio.c. - - Other files were not changed. -************************************************************************ -zlib general purpose compression library -version 1.2.5, April 19th, 2010 - -Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would - be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not - be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source - distribution. - -Jean-loup Gailly Mark Adler -jloup@gzip.org madler@alumni.caltech.edu - -The data format used by the zlib library is described by RFCs (Request -for Comments) 1950 to 1952 in the files -http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate -format) and rfc1952.txt (gzip format). diff --git a/resources/3rdparty/glpk-4.53/src/zlib/adler32.c b/resources/3rdparty/glpk-4.53/src/zlib/adler32.c deleted file mode 100644 index 65ad6a5ad..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/adler32.c +++ /dev/null @@ -1,169 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2007 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#define local static - -local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); - -#define BASE 65521UL /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware */ -#ifdef NO_DIVIDE -# define MOD(a) \ - do { \ - if (a >= (BASE << 16)) a -= (BASE << 16); \ - if (a >= (BASE << 15)) a -= (BASE << 15); \ - if (a >= (BASE << 14)) a -= (BASE << 14); \ - if (a >= (BASE << 13)) a -= (BASE << 13); \ - if (a >= (BASE << 12)) a -= (BASE << 12); \ - if (a >= (BASE << 11)) a -= (BASE << 11); \ - if (a >= (BASE << 10)) a -= (BASE << 10); \ - if (a >= (BASE << 9)) a -= (BASE << 9); \ - if (a >= (BASE << 8)) a -= (BASE << 8); \ - if (a >= (BASE << 7)) a -= (BASE << 7); \ - if (a >= (BASE << 6)) a -= (BASE << 6); \ - if (a >= (BASE << 5)) a -= (BASE << 5); \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD4(a) \ - do { \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD4(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD4(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -local uLong adler32_combine_(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* the derivation of this formula is left as an exercise for the reader */ - rem = (unsigned)(len2 % BASE); - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} - -uLong ZEXPORT adler32_combine64(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} diff --git a/resources/3rdparty/glpk-4.53/src/zlib/compress.c b/resources/3rdparty/glpk-4.53/src/zlib/compress.c deleted file mode 100644 index ea4dfbe9d..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/compress.c +++ /dev/null @@ -1,80 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; -#ifdef MAXSEG_64K - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; -#endif - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; - - err = deflateEnd(&stream); - return err; -} - -/* =========================================================================== - */ -int ZEXPORT compress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; -{ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; -} diff --git a/resources/3rdparty/glpk-4.53/src/zlib/crc32.c b/resources/3rdparty/glpk-4.53/src/zlib/crc32.c deleted file mode 100644 index 91be372d2..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/crc32.c +++ /dev/null @@ -1,442 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2006, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Thanks to Rodney Brown for his contribution of faster - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing - * tables for updating the shift register in one step with three exclusive-ors - * instead of four steps with four exclusive-ors. This results in about a - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. - */ - -/* @(#) $Id$ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for STDC and FAR definitions */ - -#define local static - -/* Find a four-byte integer type for crc32_little() and crc32_big(). */ -#ifndef NOBYFOUR -# ifdef STDC /* need ANSI C limits.h to determine sizes */ -# include -# define BYFOUR -# if (UINT_MAX == 0xffffffffUL) - typedef unsigned int u4; -# else -# if (ULONG_MAX == 0xffffffffUL) - typedef unsigned long u4; -# else -# if (USHRT_MAX == 0xffffffffUL) - typedef unsigned short u4; -# else -# undef BYFOUR /* can't find a four-byte integer type! */ -# endif -# endif -# endif -# endif /* STDC */ -#endif /* !NOBYFOUR */ - -/* Definitions for doing the crc four data bytes at a time. */ -#ifdef BYFOUR -# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \ - (((w)&0xff00)<<8)+(((w)&0xff)<<24)) - local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, unsigned)); - local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, unsigned)); -# define TBLS 8 -#else -# define TBLS 1 -#endif /* BYFOUR */ - -/* Local functions for crc concatenation */ -local unsigned long gf2_matrix_times OF((unsigned long *mat, - unsigned long vec)); -local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); -local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2); - - -#ifdef DYNAMIC_CRC_TABLE - -local volatile int crc_table_empty = 1; -local unsigned long FAR crc_table[TBLS][256]; -local void make_crc_table OF((void)); -#ifdef MAKECRCH - local void write_table OF((FILE *, const unsigned long FAR *)); -#endif /* MAKECRCH */ -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The first table is simply the CRC of all possible eight bit values. This is - all the information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. The remaining tables - allow for word-at-a-time CRC calculation for both big-endian and little- - endian machines, where a word is four bytes. -*/ -local void make_crc_table() -{ - unsigned long c; - int n, k; - unsigned long poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static volatile int first = 1; /* flag to limit concurrent making */ - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* See if another task is already doing this (not thread-safe, but better - than nothing -- significantly reduces duration of vulnerability in - case the advice about DYNAMIC_CRC_TABLE is ignored) */ - if (first) { - first = 0; - - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0UL; - for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) - poly |= 1UL << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (unsigned long)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } - -#ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, - and then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = REV(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = REV(c); - } - } -#endif /* BYFOUR */ - - crc_table_empty = 0; - } - else { /* not first */ - /* wait for the other guy to finish (not efficient, but rare) */ - while (crc_table_empty) - ; - } - -#ifdef MAKECRCH - /* write out CRC tables to crc32.h */ - { - FILE *out; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const unsigned long FAR "); - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); - write_table(out, crc_table[0]); -# ifdef BYFOUR - fprintf(out, "#ifdef BYFOUR\n"); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); - } - fprintf(out, "#endif\n"); -# endif /* BYFOUR */ - fprintf(out, " }\n};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH -local void write_table(out, table) - FILE *out; - const unsigned long FAR *table; -{ - int n; - - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); -} -#endif /* MAKECRCH */ - -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables of CRC-32s of all single-byte values, made by make_crc_table(). - */ -#include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32() - */ -const unsigned long FAR * ZEXPORT get_crc_table() -{ -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - return (const unsigned long FAR *)crc_table; -} - -/* ========================================================================= */ -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 - -/* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - uInt len; -{ - if (buf == Z_NULL) return 0UL; - -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - -#ifdef BYFOUR - if (sizeof(void *) == sizeof(ptrdiff_t)) { - u4 endian; - - endian = 1; - if (*((unsigned char *)(&endian))) - return crc32_little(crc, buf, len); - else - return crc32_big(crc, buf, len); - } -#endif /* BYFOUR */ - crc = crc ^ 0xffffffffUL; - while (len >= 8) { - DO8; - len -= 8; - } - if (len) do { - DO1; - } while (--len); - return crc ^ 0xffffffffUL; -} - -#ifdef BYFOUR - -/* ========================================================================= */ -#define DOLIT4 c ^= *buf4++; \ - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 - -/* ========================================================================= */ -local unsigned long crc32_little(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register u4 c; - register const u4 FAR *buf4; - - c = (u4)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - len--; - } - - buf4 = (const u4 FAR *)(const void FAR *)buf; - while (len >= 32) { - DOLIT32; - len -= 32; - } - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - } while (--len); - c = ~c; - return (unsigned long)c; -} - -/* ========================================================================= */ -#define DOBIG4 c ^= *++buf4; \ - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 - -/* ========================================================================= */ -local unsigned long crc32_big(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register u4 c; - register const u4 FAR *buf4; - - c = REV((u4)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - len--; - } - - buf4 = (const u4 FAR *)(const void FAR *)buf; - buf4--; - while (len >= 32) { - DOBIG32; - len -= 32; - } - while (len >= 4) { - DOBIG4; - len -= 4; - } - buf4++; - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - } while (--len); - c = ~c; - return (unsigned long)(REV(c)); -} - -#endif /* BYFOUR */ - -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ - -/* ========================================================================= */ -local unsigned long gf2_matrix_times(mat, vec) - unsigned long *mat; - unsigned long vec; -{ - unsigned long sum; - - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; -} - -/* ========================================================================= */ -local void gf2_matrix_square(square, mat) - unsigned long *square; - unsigned long *mat; -{ - int n; - - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); -} - -/* ========================================================================= */ -local uLong crc32_combine_(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - int n; - unsigned long row; - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - - /* degenerate case (also disallow negative lengths) */ - if (len2 <= 0) - return crc1; - - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} - -uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} diff --git a/resources/3rdparty/glpk-4.53/src/zlib/crc32.h b/resources/3rdparty/glpk-4.53/src/zlib/crc32.h deleted file mode 100644 index 8053b6117..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/crc32.h +++ /dev/null @@ -1,441 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const unsigned long FAR crc_table[TBLS][256] = -{ - { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL -#ifdef BYFOUR - }, - { - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, - 0x9324fd72UL - }, - { - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, - 0xbe9834edUL - }, - { - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, - 0xde0506f1UL - }, - { - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, - 0x8def022dUL - }, - { - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, - 0x72fd2493UL - }, - { - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, - 0xed3498beUL - }, - { - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, - 0xf10605deUL -#endif - } -}; diff --git a/resources/3rdparty/glpk-4.53/src/zlib/deflate.c b/resources/3rdparty/glpk-4.53/src/zlib/deflate.c deleted file mode 100644 index 5c4022f3d..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/deflate.c +++ /dev/null @@ -1,1834 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://www.ietf.org/rfc/rfc1951.txt - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -#ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local block_state deflate_rle OF((deflate_state *s, int flush)); -local block_state deflate_huff OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif - -#ifdef DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->high_water = 0; /* nothing written to s->window yet */ - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt length = dictLength; - uInt n; - IPos hash_head = 0; - - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || - strm->state->wrap == 2 || - (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) - return Z_STREAM_ERROR; - - s = strm->state; - if (s->wrap) - strm->adler = adler32(strm->adler, dictionary, dictLength); - - if (length < MIN_MATCH) return Z_OK; - if (length > s->w_size) { - length = s->w_size; - dictionary += dictLength - length; /* use the tail of the dictionary */ - } - zmemcpy(s->window, dictionary, length); - s->strstart = length; - s->block_start = (long)length; - - /* Insert all strings in the hash table (except for the last two bytes). - * s->lookahead stays null, so s->ins_h will be recomputed at the next - * call of fill_window. - */ - s->ins_h = s->window[0]; - UPDATE_HASH(s, s->ins_h, s->window[1]); - for (n = 0; n <= length - MIN_MATCH; n++) { - INSERT_STRING(s, n, hash_head); - } - if (hash_head) hash_head = 0; /* to make compiler happy */ - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset (strm) - z_streamp strm; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = s->wrap ? INIT_STATE : BUSY_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - lm_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader (strm, head) - z_streamp strm; - gz_headerp head; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (strm->state->wrap != 2) return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime (strm, bits, value) - z_streamp strm; - int bits; - int value; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - strm->state->bi_valid = bits; - strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - int err = Z_OK; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func) && - strm->total_in != 0) { - /* Flush the last buffer: */ - err = deflate(strm, Z_BLOCK); - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = good_length; - s->max_lazy_match = max_lazy; - s->nice_match = nice_length; - s->max_chain_length = max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds for - * every combination of windowBits and memLevel. But even the conservative - * upper bound of about 14% expansion does not seem onerous for output buffer - * allocation. - */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ - deflate_state *s; - uLong complen, wraplen; - Bytef *str; - - /* conservative upper bound for compressed data */ - complen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; - - /* if can't get parameters, return conservative bound plus zlib wrapper */ - if (strm == Z_NULL || strm->state == Z_NULL) - return complen + 6; - - /* compute wrapper length */ - s = strm->state; - switch (s->wrap) { - case 0: /* raw deflate */ - wraplen = 0; - break; - case 1: /* zlib wrapper */ - wraplen = 6 + (s->strstart ? 4 : 0); - break; - case 2: /* gzip wrapper */ - wraplen = 18; - if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ - if (s->gzhead->extra != Z_NULL) - wraplen += 2 + s->gzhead->extra_len; - str = s->gzhead->name; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - str = s->gzhead->comment; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - if (s->gzhead->hcrc) - wraplen += 2; - } - break; - default: /* for compiler happiness */ - wraplen = 6; - } - - /* if not default parameters, return conservative bound */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return complen + wraplen; - - /* default settings: return tight bound for that case */ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13 - 6 + wraplen; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - unsigned len = strm->state->pending; - - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, strm->state->pending_out, len); - strm->next_out += len; - strm->state->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - strm->state->pending -= len; - if (strm->state->pending == 0) { - strm->state->pending_out = strm->state->pending_buf; - } -} - -/* ========================================================================= */ -int ZEXPORT deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_BLOCK || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; - - /* Write the header */ - if (s->status == INIT_STATE) { -#ifdef GZIP - if (s->wrap == 2) { - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - else -#endif - { - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - } - } -#ifdef GZIP - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) - break; - } - put_byte(s, s->gzhead->extra[s->gzindex]); - s->gzindex++; - } - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (s->gzindex == s->gzhead->extra_len) { - s->gzindex = 0; - s->status = NAME_STATE; - } - } - else - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) { - s->gzindex = 0; - s->status = COMMENT_STATE; - } - } - else - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) - s->status = HCRC_STATE; - } - else - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) - flush_pending(strm); - if (s->pending + 2 <= s->pending_buf_size) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - } - } - else - s->status = BUSY_STATE; - } -#endif - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && flush <= old_flush && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - (s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush)); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - if (s->lookahead == 0) { - s->strstart = 0; - s->block_start = 0L; - } - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd (strm) - z_streamp strm; -{ - int status; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - - status = strm->state->status; - if (status != INIT_STATE && - status != EXTRA_STATE && - status != NAME_STATE && - status != COMMENT_STATE && - status != HCRC_STATE && - status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ -#ifdef MAXSEG_64K - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy(dest, source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy(ds, ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local int read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, strm->next_in, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, strm->next_in, len); - } -#endif - zmemcpy(buf, strm->next_in, len); - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifndef FASTEST -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -#endif -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} -#endif /* ASMV */ - -#else /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for FASTEST only - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#endif /* FASTEST */ - -#ifdef DEBUG -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - register unsigned n, m; - register Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy(s->window, s->window+wsize, (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif - more += wsize; - } - if (s->strm->avail_in == 0) return; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead >= MIN_MATCH) { - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - ulg max_block_size = 0xffff; - ulg max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -#endif /* FASTEST */ - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - uInt prev; /* byte at distance one to match */ - Bytef *scan, *strend; /* scan goes up to strend for length of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest encodable run. - */ - if (s->lookahead < MAX_MATCH) { - fill_window(s); - if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s->match_length = 0; - if (s->lookahead >= MIN_MATCH && s->strstart > 0) { - scan = s->window + s->strstart - 1; - prev = *scan; - if (prev == *++scan && prev == *++scan && prev == *++scan) { - strend = s->window + s->strstart + MAX_MATCH; - do { - } while (prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - scan < strend); - s->match_length = MAX_MATCH - (int)(strend - scan); - if (s->match_length > s->lookahead) - s->match_length = s->lookahead; - } - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, s->match_length); - - _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - s->strstart += s->match_length; - s->match_length = 0; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -local block_state deflate_huff(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s->lookahead == 0) { - fill_window(s); - if (s->lookahead == 0) { - if (flush == Z_NO_FLUSH) - return need_more; - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s->match_length = 0; - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} diff --git a/resources/3rdparty/glpk-4.53/src/zlib/deflate.h b/resources/3rdparty/glpk-4.53/src/zlib/deflate.h deleted file mode 100644 index cbf0d1ea5..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/deflate.h +++ /dev/null @@ -1,342 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2010 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define INIT_STATE 42 -#define EXTRA_STATE 69 -#define NAME_STATE 73 -#define COMMENT_STATE 91 -#define HCRC_STATE 103 -#define BUSY_STATE 113 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - uInt pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - uInt gzindex; /* where in extra, name, or comment */ - Byte method; /* STORED (for zip only) or DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to supress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - int last_eob_len; /* bit length of EOB code for last block */ - -#ifdef DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - ulg high_water; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - -#define WIN_INIT MAX_MATCH -/* Number of bytes after end of data in window to initialize in order to avoid - memory checker errors from longest match routines */ - - /* in trees.c */ -void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); -int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); -void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch ZLIB_INTERNAL _length_code[]; - extern uch ZLIB_INTERNAL _dist_code[]; -#else - extern const uch ZLIB_INTERNAL _length_code[]; - extern const uch ZLIB_INTERNAL _dist_code[]; -#endif - -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (length); \ - ush dist = (distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ diff --git a/resources/3rdparty/glpk-4.53/src/zlib/gzclose.c b/resources/3rdparty/glpk-4.53/src/zlib/gzclose.c deleted file mode 100644 index caeb99a31..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/gzclose.c +++ /dev/null @@ -1,25 +0,0 @@ -/* gzclose.c -- zlib gzclose() function - * Copyright (C) 2004, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* gzclose() is in a separate file so that it is linked in only if it is used. - That way the other gzclose functions can be used instead to avoid linking in - unneeded compression or decompression routines. */ -int ZEXPORT gzclose(file) - gzFile file; -{ -#ifndef NO_GZCOMPRESS - gz_statep state; - - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); -#else - return gzclose_r(file); -#endif -} diff --git a/resources/3rdparty/glpk-4.53/src/zlib/gzguts.h b/resources/3rdparty/glpk-4.53/src/zlib/gzguts.h deleted file mode 100644 index 9d01ac7b7..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/gzguts.h +++ /dev/null @@ -1,74 +0,0 @@ -/* gzguts.h (zlib internal header definitions for gz* operations) */ - -/* Modified by Andrew Makhorin , April 2011 */ - -/* Copyright (C) 2004, 2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in - * zlib.h */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. */ - -#ifndef GZGUTS_H -#define GZGUTS_H - -#define ZLIB_INTERNAL - -#include -#include -#include -#include -#include -#include "zio.h" -#include "zlib.h" - -#define local static - -#define zstrerror() strerror(errno) - -#define GZBUFSIZE 8192 - -#define GZ_NONE 0 -#define GZ_READ 7247 -#define GZ_WRITE 31153 -#define GZ_APPEND 1 - -#define LOOK 0 -#define COPY 1 -#define GZIP 2 - -typedef struct -{ int mode; - int fd; - char *path; - z_off64_t pos; - unsigned size; - unsigned want; - unsigned char *in; - unsigned char *out; - unsigned char *next; - unsigned have; - int eof; - z_off64_t start; - z_off64_t raw; - int how; - int direct; - int level; - int strategy; - z_off64_t skip; - int seek; - int err; - char *msg; - z_stream strm; -} gz_state; - -typedef gz_state *gz_statep; - -void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); - -#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/zlib/gzlib.c b/resources/3rdparty/glpk-4.53/src/zlib/gzlib.c deleted file mode 100644 index 603e60ed5..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/gzlib.c +++ /dev/null @@ -1,537 +0,0 @@ -/* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 -# define LSEEK lseek64 -#else -# define LSEEK lseek -#endif - -/* Local functions */ -local void gz_reset OF((gz_statep)); -local gzFile gz_open OF((const char *, int, const char *)); - -#if defined UNDER_CE - -/* Map the Windows error number in ERROR to a locale-dependent error message - string and return a pointer to it. Typically, the values for ERROR come - from GetLastError. - - The string pointed to shall not be modified by the application, but may be - overwritten by a subsequent call to gz_strwinerror - - The gz_strwinerror function does not change the current setting of - GetLastError. */ -char ZLIB_INTERNAL *gz_strwinerror (error) - DWORD error; -{ - static char buf[1024]; - - wchar_t *msgbuf; - DWORD lasterr = GetLastError(); - DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, - error, - 0, /* Default language */ - (LPVOID)&msgbuf, - 0, - NULL); - if (chars != 0) { - /* If there is an \r\n appended, zap it. */ - if (chars >= 2 - && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { - chars -= 2; - msgbuf[chars] = 0; - } - - if (chars > sizeof (buf) - 1) { - chars = sizeof (buf) - 1; - msgbuf[chars] = 0; - } - - wcstombs(buf, msgbuf, chars + 1); - LocalFree(msgbuf); - } - else { - sprintf(buf, "unknown win32 error (%ld)", error); - } - - SetLastError(lasterr); - return buf; -} - -#endif /* UNDER_CE */ - -/* Reset gzip file state */ -local void gz_reset(state) - gz_statep state; -{ - if (state->mode == GZ_READ) { /* for reading ... */ - state->have = 0; /* no output data available */ - state->eof = 0; /* not at end of file */ - state->how = LOOK; /* look for gzip header */ - state->direct = 1; /* default for empty file */ - } - state->seek = 0; /* no seek request pending */ - gz_error(state, Z_OK, NULL); /* clear error */ - state->pos = 0; /* no uncompressed data yet */ - state->strm.avail_in = 0; /* no input data yet */ -} - -/* Open a gzip file either by name or file descriptor. */ -local gzFile gz_open(path, fd, mode) - const char *path; - int fd; - const char *mode; -{ - gz_statep state; - - /* allocate gzFile structure to return */ - state = malloc(sizeof(gz_state)); - if (state == NULL) - return NULL; - state->size = 0; /* no buffers allocated yet */ - state->want = GZBUFSIZE; /* requested buffer size */ - state->msg = NULL; /* no error message yet */ - - /* interpret mode */ - state->mode = GZ_NONE; - state->level = Z_DEFAULT_COMPRESSION; - state->strategy = Z_DEFAULT_STRATEGY; - while (*mode) { - if (*mode >= '0' && *mode <= '9') - state->level = *mode - '0'; - else - switch (*mode) { - case 'r': - state->mode = GZ_READ; - break; -#ifndef NO_GZCOMPRESS - case 'w': - state->mode = GZ_WRITE; - break; - case 'a': - state->mode = GZ_APPEND; - break; -#endif - case '+': /* can't read and write at the same time */ - free(state); - return NULL; - case 'b': /* ignore -- will request binary anyway */ - break; - case 'f': - state->strategy = Z_FILTERED; - break; - case 'h': - state->strategy = Z_HUFFMAN_ONLY; - break; - case 'R': - state->strategy = Z_RLE; - break; - case 'F': - state->strategy = Z_FIXED; - default: /* could consider as an error, but just ignore */ - ; - } - mode++; - } - - /* must provide an "r", "w", or "a" */ - if (state->mode == GZ_NONE) { - free(state); - return NULL; - } - - /* save the path name for error messages */ - state->path = malloc(strlen(path) + 1); - if (state->path == NULL) { - free(state); - return NULL; - } - strcpy(state->path, path); - - /* open the file with the appropriate mode (or just use fd) */ - state->fd = fd != -1 ? fd : - open(path, -#ifdef O_LARGEFILE - O_LARGEFILE | -#endif -#ifdef O_BINARY - O_BINARY | -#endif - (state->mode == GZ_READ ? - O_RDONLY : - (O_WRONLY | O_CREAT | ( - state->mode == GZ_WRITE ? - O_TRUNC : - O_APPEND))), - 0666); - if (state->fd == -1) { - free(state->path); - free(state); - return NULL; - } - if (state->mode == GZ_APPEND) - state->mode = GZ_WRITE; /* simplify later checks */ - - /* save the current position for rewinding (only if reading) */ - if (state->mode == GZ_READ) { - state->start = LSEEK(state->fd, 0, SEEK_CUR); - if (state->start == -1) state->start = 0; - } - - /* initialize stream */ - gz_reset(state); - - /* return stream */ - return (gzFile)state; -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen(path, mode) - const char *path; - const char *mode; -{ - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen64(path, mode) - const char *path; - const char *mode; -{ - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzdopen(fd, mode) - int fd; - const char *mode; -{ - char *path; /* identifier for error messages */ - gzFile gz; - - if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL) - return NULL; - sprintf(path, "", fd); /* for debugging */ - gz = gz_open(path, fd, mode); - free(path); - return gz; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzbuffer(file, size) - gzFile file; - unsigned size; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* make sure we haven't already allocated memory */ - if (state->size != 0) - return -1; - - /* check and set requested size */ - if (size == 0) - return -1; - state->want = size; - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzrewind(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || state->err != Z_OK) - return -1; - - /* back up and start over */ - if (LSEEK(state->fd, state->start, SEEK_SET) == -1) - return -1; - gz_reset(state); - return 0; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzseek64(file, offset, whence) - gzFile file; - z_off64_t offset; - int whence; -{ - unsigned n; - z_off64_t ret; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* check that there's no error */ - if (state->err != Z_OK) - return -1; - - /* can only seek from start or relative to current position */ - if (whence != SEEK_SET && whence != SEEK_CUR) - return -1; - - /* normalize offset to a SEEK_CUR specification */ - if (whence == SEEK_SET) - offset -= state->pos; - else if (state->seek) - offset += state->skip; - state->seek = 0; - - /* if within raw area while reading, just go there */ - if (state->mode == GZ_READ && state->how == COPY && - state->pos + offset >= state->raw) { - ret = LSEEK(state->fd, offset - state->have, SEEK_CUR); - if (ret == -1) - return -1; - state->have = 0; - state->eof = 0; - state->seek = 0; - gz_error(state, Z_OK, NULL); - state->strm.avail_in = 0; - state->pos += offset; - return state->pos; - } - - /* calculate skip amount, rewinding if needed for back seek when reading */ - if (offset < 0) { - if (state->mode != GZ_READ) /* writing -- can't go backwards */ - return -1; - offset += state->pos; - if (offset < 0) /* before start of file! */ - return -1; - if (gzrewind(file) == -1) /* rewind, then skip to offset */ - return -1; - } - - /* if reading, skip what's in output buffer (one less gzgetc() check) */ - if (state->mode == GZ_READ) { - n = GT_OFF(state->have) || (z_off64_t)state->have > offset ? - (unsigned)offset : state->have; - state->have -= n; - state->next += n; - state->pos += n; - offset -= n; - } - - /* request skip (if not zero) */ - if (offset) { - state->seek = 1; - state->skip = offset; - } - return state->pos + offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzseek(file, offset, whence) - gzFile file; - z_off_t offset; - int whence; -{ - z_off64_t ret; - - ret = gzseek64(file, (z_off64_t)offset, whence); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gztell64(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* return position */ - return state->pos + (state->seek ? state->skip : 0); -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gztell(file) - gzFile file; -{ - z_off64_t ret; - - ret = gztell64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzoffset64(file) - gzFile file; -{ - z_off64_t offset; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* compute and return effective offset in file */ - offset = LSEEK(state->fd, 0, SEEK_CUR); - if (offset == -1) - return -1; - if (state->mode == GZ_READ) /* reading */ - offset -= state->strm.avail_in; /* don't count buffered input */ - return offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzoffset(file) - gzFile file; -{ - z_off64_t ret; - - ret = gzoffset64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzeof(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return 0; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return 0; - - /* return end-of-file state */ - return state->mode == GZ_READ ? - (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0; -} - -/* -- see zlib.h -- */ -const char * ZEXPORT gzerror(file, errnum) - gzFile file; - int *errnum; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return NULL; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return NULL; - - /* return error information */ - if (errnum != NULL) - *errnum = state->err; - return state->msg == NULL ? "" : state->msg; -} - -/* -- see zlib.h -- */ -void ZEXPORT gzclearerr(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return; - - /* clear error and end-of-file */ - if (state->mode == GZ_READ) - state->eof = 0; - gz_error(state, Z_OK, NULL); -} - -/* Create an error message in allocated memory and set state->err and - state->msg accordingly. Free any previous error message already there. Do - not try to free or allocate space if the error is Z_MEM_ERROR (out of - memory). Simply save the error message as a static string. If there is an - allocation failure constructing the error message, then convert the error to - out of memory. */ -void ZLIB_INTERNAL gz_error(state, err, msg) - gz_statep state; - int err; - const char *msg; -{ - /* free previously allocated message and clear */ - if (state->msg != NULL) { - if (state->err != Z_MEM_ERROR) - free(state->msg); - state->msg = NULL; - } - - /* set error code, and if no message, then done */ - state->err = err; - if (msg == NULL) - return; - - /* for an out of memory error, save as static string */ - if (err == Z_MEM_ERROR) { - state->msg = (char *)msg; - return; - } - - /* construct error message with path */ - if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { - state->err = Z_MEM_ERROR; - state->msg = (char *)"out of memory"; - return; - } - strcpy(state->msg, state->path); - strcat(state->msg, ": "); - strcat(state->msg, msg); - return; -} - -#ifndef INT_MAX -/* portably return maximum value for an int (when limits.h presumed not - available) -- we need to do this to cover cases where 2's complement not - used, since C standard permits 1's complement and sign-bit representations, - otherwise we could just use ((unsigned)-1) >> 1 */ -unsigned ZLIB_INTERNAL gz_intmax() -{ - unsigned p, q; - - p = 1; - do { - q = p; - p <<= 1; - p++; - } while (p > q); - return q >> 1; -} -#endif diff --git a/resources/3rdparty/glpk-4.53/src/zlib/gzread.c b/resources/3rdparty/glpk-4.53/src/zlib/gzread.c deleted file mode 100644 index 548201ab0..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/gzread.c +++ /dev/null @@ -1,653 +0,0 @@ -/* gzread.c -- zlib functions for reading gzip files - * Copyright (C) 2004, 2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Local functions */ -local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); -local int gz_avail OF((gz_statep)); -local int gz_next4 OF((gz_statep, unsigned long *)); -local int gz_head OF((gz_statep)); -local int gz_decomp OF((gz_statep)); -local int gz_make OF((gz_statep)); -local int gz_skip OF((gz_statep, z_off64_t)); - -/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from - state->fd, and update state->eof, state->err, and state->msg as appropriate. - This function needs to loop on read(), since read() is not guaranteed to - read the number of bytes requested, depending on the type of descriptor. */ -local int gz_load(state, buf, len, have) - gz_statep state; - unsigned char *buf; - unsigned len; - unsigned *have; -{ - int ret; - - *have = 0; - do { - ret = read(state->fd, buf + *have, len - *have); - if (ret <= 0) - break; - *have += ret; - } while (*have < len); - if (ret < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - if (ret == 0) - state->eof = 1; - return 0; -} - -/* Load up input buffer and set eof flag if last data loaded -- return -1 on - error, 0 otherwise. Note that the eof flag is set when the end of the input - file is reached, even though there may be unused data in the buffer. Once - that data has been used, no more attempts will be made to read the file. - gz_avail() assumes that strm->avail_in == 0. */ -local int gz_avail(state) - gz_statep state; -{ - z_streamp strm = &(state->strm); - - if (state->err != Z_OK) - return -1; - if (state->eof == 0) { - if (gz_load(state, state->in, state->size, - (unsigned *)&(strm->avail_in)) == -1) - return -1; - strm->next_in = state->in; - } - return 0; -} - -/* Get next byte from input, or -1 if end or error. */ -#define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \ - (strm->avail_in == 0 ? -1 : \ - (strm->avail_in--, *(strm->next_in)++))) - -/* Get a four-byte little-endian integer and return 0 on success and the value - in *ret. Otherwise -1 is returned and *ret is not modified. */ -local int gz_next4(state, ret) - gz_statep state; - unsigned long *ret; -{ - int ch; - unsigned long val; - z_streamp strm = &(state->strm); - - val = NEXT(); - val += (unsigned)NEXT() << 8; - val += (unsigned long)NEXT() << 16; - ch = NEXT(); - if (ch == -1) - return -1; - val += (unsigned long)ch << 24; - *ret = val; - return 0; -} - -/* Look for gzip header, set up for inflate or copy. state->have must be zero. - If this is the first time in, allocate required memory. state->how will be - left unchanged if there is no more input data available, will be set to COPY - if there is no gzip header and direct copying will be performed, or it will - be set to GZIP for decompression, and the gzip header will be skipped so - that the next available input data is the raw deflate stream. If direct - copying, then leftover input data from the input buffer will be copied to - the output buffer. In that case, all further file reads will be directly to - either the output buffer or a user buffer. If decompressing, the inflate - state and the check value will be initialized. gz_head() will return 0 on - success or -1 on failure. Failures may include read errors or gzip header - errors. */ -local int gz_head(state) - gz_statep state; -{ - z_streamp strm = &(state->strm); - int flags; - unsigned len; - - /* allocate read buffers and inflate memory */ - if (state->size == 0) { - /* allocate buffers */ - state->in = malloc(state->want); - state->out = malloc(state->want << 1); - if (state->in == NULL || state->out == NULL) { - if (state->out != NULL) - free(state->out); - if (state->in != NULL) - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - state->size = state->want; - - /* allocate inflate memory */ - state->strm.zalloc = Z_NULL; - state->strm.zfree = Z_NULL; - state->strm.opaque = Z_NULL; - state->strm.avail_in = 0; - state->strm.next_in = Z_NULL; - if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */ - free(state->out); - free(state->in); - state->size = 0; - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - } - - /* get some data in the input buffer */ - if (strm->avail_in == 0) { - if (gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) - return 0; - } - - /* look for the gzip magic header bytes 31 and 139 */ - if (strm->next_in[0] == 31) { - strm->avail_in--; - strm->next_in++; - if (strm->avail_in == 0 && gz_avail(state) == -1) - return -1; - if (strm->avail_in && strm->next_in[0] == 139) { - /* we have a gzip header, woo hoo! */ - strm->avail_in--; - strm->next_in++; - - /* skip rest of header */ - if (NEXT() != 8) { /* compression method */ - gz_error(state, Z_DATA_ERROR, "unknown compression method"); - return -1; - } - flags = NEXT(); - if (flags & 0xe0) { /* reserved flag bits */ - gz_error(state, Z_DATA_ERROR, "unknown header flags set"); - return -1; - } - NEXT(); /* modification time */ - NEXT(); - NEXT(); - NEXT(); - NEXT(); /* extra flags */ - NEXT(); /* operating system */ - if (flags & 4) { /* extra field */ - len = (unsigned)NEXT(); - len += (unsigned)NEXT() << 8; - while (len--) - if (NEXT() < 0) - break; - } - if (flags & 8) /* file name */ - while (NEXT() > 0) - ; - if (flags & 16) /* comment */ - while (NEXT() > 0) - ; - if (flags & 2) { /* header crc */ - NEXT(); - NEXT(); - } - /* an unexpected end of file is not checked for here -- it will be - noticed on the first request for uncompressed data */ - - /* set up for decompression */ - inflateReset(strm); - strm->adler = crc32(0L, Z_NULL, 0); - state->how = GZIP; - state->direct = 0; - return 0; - } - else { - /* not a gzip file -- save first byte (31) and fall to raw i/o */ - state->out[0] = 31; - state->have = 1; - } - } - - /* doing raw i/o, save start of raw data for seeking, copy any leftover - input to output -- this assumes that the output buffer is larger than - the input buffer, which also assures space for gzungetc() */ - state->raw = state->pos; - state->next = state->out; - if (strm->avail_in) { - memcpy(state->next + state->have, strm->next_in, strm->avail_in); - state->have += strm->avail_in; - strm->avail_in = 0; - } - state->how = COPY; - state->direct = 1; - return 0; -} - -/* Decompress from input to the provided next_out and avail_out in the state. - If the end of the compressed data is reached, then verify the gzip trailer - check value and length (modulo 2^32). state->have and state->next are set - to point to the just decompressed data, and the crc is updated. If the - trailer is verified, state->how is reset to LOOK to look for the next gzip - stream or raw data, once state->have is depleted. Returns 0 on success, -1 - on failure. Failures may include invalid compressed data or a failed gzip - trailer verification. */ -local int gz_decomp(state) - gz_statep state; -{ - int ret; - unsigned had; - unsigned long crc, len; - z_streamp strm = &(state->strm); - - /* fill output buffer up to end of deflate stream */ - had = strm->avail_out; - do { - /* get more input for inflate() */ - if (strm->avail_in == 0 && gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) { - gz_error(state, Z_DATA_ERROR, "unexpected end of file"); - return -1; - } - - /* decompress and handle errors */ - ret = inflate(strm, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { - gz_error(state, Z_STREAM_ERROR, - "internal error: inflate stream corrupt"); - return -1; - } - if (ret == Z_MEM_ERROR) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ - gz_error(state, Z_DATA_ERROR, - strm->msg == NULL ? "compressed data error" : strm->msg); - return -1; - } - } while (strm->avail_out && ret != Z_STREAM_END); - - /* update available output and crc check value */ - state->have = had - strm->avail_out; - state->next = strm->next_out - state->have; - strm->adler = crc32(strm->adler, state->next, state->have); - - /* check gzip trailer if at end of deflate stream */ - if (ret == Z_STREAM_END) { - if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) { - gz_error(state, Z_DATA_ERROR, "unexpected end of file"); - return -1; - } - if (crc != strm->adler) { - gz_error(state, Z_DATA_ERROR, "incorrect data check"); - return -1; - } - if (len != (strm->total_out & 0xffffffffL)) { - gz_error(state, Z_DATA_ERROR, "incorrect length check"); - return -1; - } - state->how = LOOK; /* ready for next stream, once have is 0 (leave - state->direct unchanged to remember how) */ - } - - /* good decompression */ - return 0; -} - -/* Make data and put in the output buffer. Assumes that state->have == 0. - Data is either copied from the input file or decompressed from the input - file depending on state->how. If state->how is LOOK, then a gzip header is - looked for (and skipped if found) to determine wither to copy or decompress. - Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY - or GZIP unless the end of the input file has been reached and all data has - been processed. */ -local int gz_make(state) - gz_statep state; -{ - z_streamp strm = &(state->strm); - - if (state->how == LOOK) { /* look for gzip header */ - if (gz_head(state) == -1) - return -1; - if (state->have) /* got some data from gz_head() */ - return 0; - } - if (state->how == COPY) { /* straight copy */ - if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1) - return -1; - state->next = state->out; - } - else if (state->how == GZIP) { /* decompress */ - strm->avail_out = state->size << 1; - strm->next_out = state->out; - if (gz_decomp(state) == -1) - return -1; - } - return 0; -} - -/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ -local int gz_skip(state, len) - gz_statep state; - z_off64_t len; -{ - unsigned n; - - /* skip over len bytes or reach end-of-file, whichever comes first */ - while (len) - /* skip over whatever is in output buffer */ - if (state->have) { - n = GT_OFF(state->have) || (z_off64_t)state->have > len ? - (unsigned)len : state->have; - state->have -= n; - state->next += n; - state->pos += n; - len -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) - break; - - /* need more data to skip -- load up output buffer */ - else { - /* get more output, looking for header if required */ - if (gz_make(state) == -1) - return -1; - } - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzread(file, buf, len) - gzFile file; - voidp buf; - unsigned len; -{ - unsigned got, n; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || state->err != Z_OK) - return -1; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids the flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_BUF_ERROR, "requested length does not fit in int"); - return -1; - } - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } - - /* get len bytes to buf, or less than len if at the end */ - got = 0; - do { - /* first just try copying data from the output buffer */ - if (state->have) { - n = state->have > len ? len : state->have; - memcpy(buf, state->next, n); - state->next += n; - state->have -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && strm->avail_in == 0) - break; - - /* need output data -- for small len or new stream load up our output - buffer */ - else if (state->how == LOOK || len < (state->size << 1)) { - /* get more output, looking for header if required */ - if (gz_make(state) == -1) - return -1; - continue; /* no progress yet -- go back to memcpy() above */ - /* the copy above assures that we will leave with space in the - output buffer, allowing at least one gzungetc() to succeed */ - } - - /* large len -- read directly into user buffer */ - else if (state->how == COPY) { /* read directly */ - if (gz_load(state, buf, len, &n) == -1) - return -1; - } - - /* large len -- decompress directly into user buffer */ - else { /* state->how == GZIP */ - strm->avail_out = len; - strm->next_out = buf; - if (gz_decomp(state) == -1) - return -1; - n = state->have; - state->have = 0; - } - - /* update progress */ - len -= n; - buf = (char *)buf + n; - got += n; - state->pos += n; - } while (len); - - /* return number of bytes read into user buffer (will fit in int) */ - return (int)got; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzgetc(file) - gzFile file; -{ - int ret; - unsigned char buf[1]; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || state->err != Z_OK) - return -1; - - /* try output buffer (no need to check for skip request) */ - if (state->have) { - state->have--; - state->pos++; - return *(state->next)++; - } - - /* nothing there -- try gzread() */ - ret = gzread(file, buf, 1); - return ret < 1 ? -1 : buf[0]; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzungetc(c, file) - int c; - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || state->err != Z_OK) - return -1; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } - - /* can't push EOF */ - if (c < 0) - return -1; - - /* if output buffer empty, put byte at end (allows more pushing) */ - if (state->have == 0) { - state->have = 1; - state->next = state->out + (state->size << 1) - 1; - state->next[0] = c; - state->pos--; - return c; - } - - /* if no room, give up (must have already done a gzungetc()) */ - if (state->have == (state->size << 1)) { - gz_error(state, Z_BUF_ERROR, "out of room to push characters"); - return -1; - } - - /* slide output data if needed and insert byte before existing data */ - if (state->next == state->out) { - unsigned char *src = state->out + state->have; - unsigned char *dest = state->out + (state->size << 1); - while (src > state->out) - *--dest = *--src; - state->next = dest; - } - state->have++; - state->next--; - state->next[0] = c; - state->pos--; - return c; -} - -/* -- see zlib.h -- */ -char * ZEXPORT gzgets(file, buf, len) - gzFile file; - char *buf; - int len; -{ - unsigned left, n; - char *str; - unsigned char *eol; - gz_statep state; - - /* check parameters and get internal structure */ - if (file == NULL || buf == NULL || len < 1) - return NULL; - state = (gz_statep)file; - - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || state->err != Z_OK) - return NULL; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return NULL; - } - - /* copy output bytes up to new line or len - 1, whichever comes first -- - append a terminating zero to the string (we don't check for a zero in - the contents, let the user worry about that) */ - str = buf; - left = (unsigned)len - 1; - if (left) do { - /* assure that something is in the output buffer */ - if (state->have == 0) { - if (gz_make(state) == -1) - return NULL; /* error */ - if (state->have == 0) { /* end of file */ - if (buf == str) /* got bupkus */ - return NULL; - break; /* got something -- return it */ - } - } - - /* look for end-of-line in current output buffer */ - n = state->have > left ? left : state->have; - eol = memchr(state->next, '\n', n); - if (eol != NULL) - n = (unsigned)(eol - state->next) + 1; - - /* copy through end-of-line, or remainder if not found */ - memcpy(buf, state->next, n); - state->have -= n; - state->next += n; - state->pos += n; - left -= n; - buf += n; - } while (left && eol == NULL); - - /* found end-of-line or out of space -- terminate string and return it */ - buf[0] = 0; - return str; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzdirect(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're reading */ - if (state->mode != GZ_READ) - return 0; - - /* if the state is not known, but we can find out, then do so (this is - mainly for right after a gzopen() or gzdopen()) */ - if (state->how == LOOK && state->have == 0) - (void)gz_head(state); - - /* return 1 if reading direct, 0 if decompressing a gzip stream */ - return state->direct; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_r(file) - gzFile file; -{ - int ret; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're reading */ - if (state->mode != GZ_READ) - return Z_STREAM_ERROR; - - /* free memory and close file */ - if (state->size) { - inflateEnd(&(state->strm)); - free(state->out); - free(state->in); - } - gz_error(state, Z_OK, NULL); - free(state->path); - ret = close(state->fd); - free(state); - return ret ? Z_ERRNO : Z_OK; -} diff --git a/resources/3rdparty/glpk-4.53/src/zlib/gzwrite.c b/resources/3rdparty/glpk-4.53/src/zlib/gzwrite.c deleted file mode 100644 index 13c5558e0..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/gzwrite.c +++ /dev/null @@ -1,531 +0,0 @@ -/* gzwrite.c -- zlib functions for writing gzip files - * Copyright (C) 2004, 2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Local functions */ -local int gz_init OF((gz_statep)); -local int gz_comp OF((gz_statep, int)); -local int gz_zero OF((gz_statep, z_off64_t)); - -/* Initialize state for writing a gzip file. Mark initialization by setting - state->size to non-zero. Return -1 on failure or 0 on success. */ -local int gz_init(state) - gz_statep state; -{ - int ret; - z_streamp strm = &(state->strm); - - /* allocate input and output buffers */ - state->in = malloc(state->want); - state->out = malloc(state->want); - if (state->in == NULL || state->out == NULL) { - if (state->out != NULL) - free(state->out); - if (state->in != NULL) - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* allocate deflate memory, set up for gzip compression */ - strm->zalloc = Z_NULL; - strm->zfree = Z_NULL; - strm->opaque = Z_NULL; - ret = deflateInit2(strm, state->level, Z_DEFLATED, - 15 + 16, 8, state->strategy); - if (ret != Z_OK) { - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* mark state as initialized */ - state->size = state->want; - - /* initialize write buffer */ - strm->avail_out = state->size; - strm->next_out = state->out; - state->next = strm->next_out; - return 0; -} - -/* Compress whatever is at avail_in and next_in and write to the output file. - Return -1 if there is an error writing to the output file, otherwise 0. - flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, - then the deflate() state is reset to start a new gzip stream. */ -local int gz_comp(state, flush) - gz_statep state; - int flush; -{ - int ret, got; - unsigned have; - z_streamp strm = &(state->strm); - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return -1; - - /* run deflate() on provided input until it produces no more output */ - ret = Z_OK; - do { - /* write out current buffer contents if full, or if flushing, but if - doing Z_FINISH then don't write until we get to Z_STREAM_END */ - if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && - (flush != Z_FINISH || ret == Z_STREAM_END))) { - have = (unsigned)(strm->next_out - state->next); - if (have && ((got = write(state->fd, state->next, have)) < 0 || - (unsigned)got != have)) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - if (strm->avail_out == 0) { - strm->avail_out = state->size; - strm->next_out = state->out; - } - state->next = strm->next_out; - } - - /* compress */ - have = strm->avail_out; - ret = deflate(strm, flush); - if (ret == Z_STREAM_ERROR) { - gz_error(state, Z_STREAM_ERROR, - "internal error: deflate stream corrupt"); - return -1; - } - have -= strm->avail_out; - } while (have); - - /* if that completed a deflate stream, allow another to start */ - if (flush == Z_FINISH) - deflateReset(strm); - - /* all done, no errors */ - return 0; -} - -/* Compress len zeros to output. Return -1 on error, 0 on success. */ -local int gz_zero(state, len) - gz_statep state; - z_off64_t len; -{ - int first; - unsigned n; - z_streamp strm = &(state->strm); - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - - /* compress len zeros (len guaranteed > 0) */ - first = 1; - while (len) { - n = GT_OFF(state->size) || (z_off64_t)state->size > len ? - (unsigned)len : state->size; - if (first) { - memset(state->in, 0, n); - first = 0; - } - strm->avail_in = n; - strm->next_in = state->in; - state->pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - len -= n; - } - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzwrite(file, buf, len) - gzFile file; - voidpc buf; - unsigned len; -{ - unsigned put = len; - unsigned n; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids the flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_BUF_ERROR, "requested length does not fit in int"); - return 0; - } - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* for small len, copy to input buffer, otherwise compress directly */ - if (len < state->size) { - /* copy to input buffer, compress when full */ - do { - if (strm->avail_in == 0) - strm->next_in = state->in; - n = state->size - strm->avail_in; - if (n > len) - n = len; - memcpy(strm->next_in + strm->avail_in, buf, n); - strm->avail_in += n; - state->pos += n; - buf = (char *)buf + n; - len -= n; - if (len && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } while (len); - } - else { - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* directly compress user buffer to file */ - strm->avail_in = len; - strm->next_in = (voidp)buf; - state->pos += len; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } - - /* input was all buffered or compressed (put will fit in int) */ - return (int)put; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputc(file, c) - gzFile file; - int c; -{ - unsigned char buf[1]; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return -1; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* try writing to input buffer for speed (state->size == 0 if buffer not - initialized) */ - if (strm->avail_in < state->size) { - if (strm->avail_in == 0) - strm->next_in = state->in; - strm->next_in[strm->avail_in++] = c; - state->pos++; - return c; - } - - /* no room in buffer or not initialized, use gz_write() */ - buf[0] = c; - if (gzwrite(file, buf, 1) != 1) - return -1; - return c; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputs(file, str) - gzFile file; - const char *str; -{ - int ret; - unsigned len; - - /* write string */ - len = (unsigned)strlen(str); - ret = gzwrite(file, str, len); - return ret == 0 && len != 0 ? -1 : ret; -} - -#ifdef STDC -#include - -/* -- see zlib.h -- */ -int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) -{ - int size, len; - gz_statep state; - z_streamp strm; - va_list va; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* do the printf() into the input buffer, put length in len */ - size = (int)(state->size); - state->in[size - 1] = 0; - va_start(va, format); -#ifdef NO_vsnprintf -# ifdef HAS_vsprintf_void - (void)vsprintf(state->in, format, va); - va_end(va); - for (len = 0; len < size; len++) - if (state->in[len] == 0) break; -# else - len = vsprintf((char *)state->in, format, va); - va_end(va); -# endif -#else -# ifdef HAS_vsnprintf_void - (void)vsnprintf(state->in, size, format, va); - va_end(va); - len = strlen(state->in); -# else - len = vsnprintf((char *)(state->in), size, format, va); - va_end(va); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) - return 0; - - /* update buffer and position, defer compression until needed */ - strm->avail_in = (unsigned)len; - strm->next_in = state->in; - state->pos += len; - return len; -} - -#else /* !STDC */ - -/* -- see zlib.h -- */ -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) - gzFile file; - const char *format; - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; -{ - int size, len; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* do the printf() into the input buffer, put length in len */ - size = (int)(state->size); - state->in[size - 1] = 0; -#ifdef NO_snprintf -# ifdef HAS_sprintf_void - sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - for (len = 0; len < size; len++) - if (state->in[len] == 0) break; -# else - len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#else -# ifdef HAS_snprintf_void - snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen(state->in); -# else - len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) - return 0; - - /* update buffer and position, defer compression until needed */ - strm->avail_in = (unsigned)len; - strm->next_in = state->in; - state->pos += len; - return len; -} - -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzflush(file, flush) - gzFile file; - int flush; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* check flush parameter */ - if (flush < 0 || flush > Z_FINISH) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* compress remaining data with requested flush */ - gz_comp(state, flush); - return state->err; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzsetparams(file, level, strategy) - gzFile file; - int level; - int strategy; -{ - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* if no change is requested, then do nothing */ - if (level == state->level && strategy == state->strategy) - return Z_OK; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* change compression parameters for subsequent input */ - if (state->size) { - /* flush previous input with previous parameters before changing */ - if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) - return state->err; - deflateParams(strm, level, strategy); - } - state->level = level; - state->strategy = strategy; - return Z_OK; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_w(file) - gzFile file; -{ - int ret = 0; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're writing */ - if (state->mode != GZ_WRITE) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - ret += gz_zero(state, state->skip); - } - - /* flush, free memory, and close file */ - ret += gz_comp(state, Z_FINISH); - (void)deflateEnd(&(state->strm)); - free(state->out); - free(state->in); - gz_error(state, Z_OK, NULL); - free(state->path); - ret += close(state->fd); - free(state); - return ret ? Z_ERRNO : Z_OK; -} diff --git a/resources/3rdparty/glpk-4.53/src/zlib/inffast.c b/resources/3rdparty/glpk-4.53/src/zlib/inffast.c deleted file mode 100644 index 2f1d60b43..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/inffast.c +++ /dev/null @@ -1,340 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2008, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifndef ASMINF - -/* Allow machine dependent optimization for post-increment or pre-increment. - Based on testing to date, - Pre-increment preferred for: - - PowerPC G3 (Adler) - - MIPS R5000 (Randers-Pehrson) - Post-increment preferred for: - - none - No measurable difference: - - Pentium III (Anderson) - - M68060 (Nikl) - */ -#ifdef POSTINC -# define OFF 0 -# define PUP(a) *(a)++ -#else -# define OFF 1 -# define PUP(a) *++(a) -#endif - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void ZLIB_INTERNAL inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ - struct inflate_state FAR *state; - unsigned char FAR *in; /* local strm->next_in */ - unsigned char FAR *last; /* while in < last, enough input available */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in - OFF; - last = in + (strm->avail_in - 5); - out = strm->next_out - OFF; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - here = lcode[hold & lmask]; - dolen: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op == 0) { /* literal */ - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - PUP(out) = (unsigned char)(here.val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - here = dcode[hold & dmask]; - dodist: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op & 16) { /* distance base */ - dist = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = - (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - PUP(out) = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - PUP(out) = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - PUP(out) = PUP(from); - } while (--len); - continue; - } -#endif - } - from = window - OFF; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = window - OFF; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } while (len > 2); - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode[here.val + (hold & ((1U << op) - 1))]; - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode[here.val + (hold & ((1U << op) - 1))]; - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in + OFF; - strm->next_out = out + OFF; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and wnext == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/resources/3rdparty/glpk-4.53/src/zlib/inffast.h b/resources/3rdparty/glpk-4.53/src/zlib/inffast.h deleted file mode 100644 index e5c1aa4ca..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/resources/3rdparty/glpk-4.53/src/zlib/inffixed.h b/resources/3rdparty/glpk-4.53/src/zlib/inffixed.h deleted file mode 100644 index 75ed4b597..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. It - is part of the implementation of the compression library and - is subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/resources/3rdparty/glpk-4.53/src/zlib/inflate.c b/resources/3rdparty/glpk-4.53/src/zlib/inflate.c deleted file mode 100644 index a8431abea..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/inflate.c +++ /dev/null @@ -1,1480 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, unsigned out)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, - unsigned len)); - -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - strm->adler = 1; /* to support ill-conceived Java test suite */ - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->dmax = 32768U; - state->head = Z_NULL; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateReset2(strm, windowBits) -z_streamp strm; -int windowBits; -{ - int wrap; - struct inflate_state FAR *state; - - /* get the state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 1; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); -} - -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ - int ret; - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->window = Z_NULL; - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; -} - -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, - state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(strm, out) -z_streamp strm; -unsigned out; -{ - struct inflate_state FAR *state; - unsigned copy, dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - copy = out - strm->avail_out; - if (copy >= state->wsize) { - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->wnext; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, strm->next_out - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } - else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Reverse the bytes in a 32-bit value */ -#define REVERSE(q) \ - ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - else if (len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if (state->flags & 0x0200) CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if (hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = REVERSE(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - case COPY_: - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - NEEDBITS(here.bits); - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - case LEN_: - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(here.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->wnext - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if (out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); - out = left; - if (( -#ifdef GUNZIP - state->flags ? hold : -#endif - REVERSE(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) - if (updatewindow(strm, out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if (state->wrap && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); - strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ - struct inflate_state FAR *state; - unsigned long id; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary id */ - if (state->mode == DICT) { - id = adler32(0L, Z_NULL, 0); - id = adler32(id, dictionary, dictLength); - if (id != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window */ - if (updatewindow(strm, strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - if (dictLength > state->wsize) { - zmemcpy(state->window, dictionary + dictLength - state->wsize, - state->wsize); - state->whave = state->wsize; - } - else { - zmemcpy(state->window + state->wsize - dictLength, dictionary, - dictLength); - state->whave = dictLength; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ - struct inflate_state FAR *state; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -unsigned char FAR *buf; -unsigned len; -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ - unsigned len; /* number of bytes to look at or looked at */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy(dest, source, sizeof(z_stream)); - zmemcpy(copy, state, sizeof(struct inflate_state)); - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} - -int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; -int subvert; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->sane = !subvert; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - return Z_OK; -#else - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -long ZEXPORT inflateMark(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; - state = (struct inflate_state FAR *)strm->state; - return ((long)(state->back) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} diff --git a/resources/3rdparty/glpk-4.53/src/zlib/inflate.h b/resources/3rdparty/glpk-4.53/src/zlib/inflate.h deleted file mode 100644 index 95f4986d4..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/inflate.h +++ /dev/null @@ -1,122 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2009 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to BAD or MEM on error -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) or (raw) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> - HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - (raw) -> TYPEDO - Read deflate blocks: - TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK - STORED -> COPY_ -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN_ - LEN_ -> LEN - Read deflate codes in fixed or dynamic block: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* state maintained between inflate() calls. Approximately 10K bytes. */ -struct inflate_state { - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ -}; diff --git a/resources/3rdparty/glpk-4.53/src/zlib/inftrees.c b/resources/3rdparty/glpk-4.53/src/zlib/inftrees.c deleted file mode 100644 index 11e9c52ac..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/inftrees.c +++ /dev/null @@ -1,330 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.2.5 Copyright 1995-2010 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - int end; /* use base and extra for symbol > end */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (unsigned short)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - end = 19; - break; - case LENS: - base = lbase; - base -= 257; - extra = lext; - extra -= 257; - end = 256; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { - here.op = (unsigned char)0; - here.val = work[sym]; - } - else if ((int)(work[sym]) > end) { - here.op = (unsigned char)(extra[work[sym]]); - here.val = base[work[sym]]; - } - else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* - Fill in rest of table for incomplete codes. This loop is similar to the - loop above in incrementing huff for table indices. It is assumed that - len is equal to curr + drop, so there is no loop needed to increment - through high index bits. When the current sub-table is filled, the loop - drops back to the root table to fill in any remaining entries there. - */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - while (huff != 0) { - /* when done with sub-table, drop back to root table */ - if (drop != 0 && (huff & mask) != low) { - drop = 0; - len = root; - next = *table; - here.bits = (unsigned char)len; - } - - /* put invalid code marker in table */ - next[huff >> drop] = here; - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/resources/3rdparty/glpk-4.53/src/zlib/inftrees.h b/resources/3rdparty/glpk-4.53/src/zlib/inftrees.h deleted file mode 100644 index baa53a0b1..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/inftrees.h +++ /dev/null @@ -1,62 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of the dynamic table. The maximum number of code structures is - 1444, which is the sum of 852 for literal/length codes and 592 for distance - codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribtution. The arguments to that - program are the number of symbols, the initial root table size, and the - maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the - inflate_table() calls in inflate.c and infback.c. If the root table size is - changed, then these maximum sizes would be need to be recalculated and - updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) - -/* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); diff --git a/resources/3rdparty/glpk-4.53/src/zlib/trees.c b/resources/3rdparty/glpk-4.53/src/zlib/trees.c deleted file mode 100644 index 56e9bb1c1..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/trees.c +++ /dev/null @@ -1,1244 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2010 Jean-loup Gailly - * detect_data_type() function provided freely by Cosmin Truta, 2006 - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -#define Buf_size (8 * 2*sizeof(char)) -/* Number of bits used within bi_buf. (bi_buf might be implemented on - * more than 16 bits on some systems.) - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); -local int detect_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); - -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - -#ifndef DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (ush)value << s->bi_valid; - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= (ush)value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (ush)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (ush)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() -{ -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1< dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() -{ - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, - "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void ZLIB_INTERNAL _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; - s->last_eob_len = 8; /* enough lookahead for inflate */ -#ifdef DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; - - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ -#ifdef DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; -#endif - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - * The current inflate code requires 9 bits of lookahead. If the - * last two codes for the previous block (real code plus EOB) were coded - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - * the last real code. In this case we send two empty static blocks instead - * of one. (There are no problems if the previous block is stored or fixed.) - * To simplify the code, we assume the worst case of last real code encoded - * on one bit only. - */ -void ZLIB_INTERNAL _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); - /* Of the 10 bits for the empty block, we have already sent - * (10 - bi_valid) bits. The lookahead for the last real code (before - * the EOB of the previous block) was thus at least one plus the length - * of the EOB plus what we have just sent of the empty static block. - */ - if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; -#endif - bi_flush(s); - } - s->last_eob_len = 7; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ -void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (s->strm->data_type == Z_UNKNOWN) - s->strm->data_type = detect_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+last, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1)+last, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); -#ifdef DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*last)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int ZLIB_INTERNAL _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - -#ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } -#endif - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); - s->last_eob_len = ltree[END_BLOCK].Len; -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "black list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(s) - deflate_state *s; -{ - /* black_mask is the bit mask of black-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long black_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("black-listed") bytes. */ - for (n = 0; n <= 31; n++, black_mask >>= 1) - if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("white-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "black-listed" or "white-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - s->last_eob_len = 8; /* enough lookahead for inflate */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG - s->bits_sent += (ulg)len<<3; -#endif - while (len--) { - put_byte(s, *buf++); - } -} diff --git a/resources/3rdparty/glpk-4.53/src/zlib/trees.h b/resources/3rdparty/glpk-4.53/src/zlib/trees.h deleted file mode 100644 index d35639d82..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - diff --git a/resources/3rdparty/glpk-4.53/src/zlib/uncompr.c b/resources/3rdparty/glpk-4.53/src/zlib/uncompr.c deleted file mode 100644 index ad98be3a5..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/uncompr.c +++ /dev/null @@ -1,59 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted. -*/ -int ZEXPORT uncompress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; - - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - err = inflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - inflateEnd(&stream); - if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) - return Z_DATA_ERROR; - return err; - } - *destLen = stream.total_out; - - err = inflateEnd(&stream); - return err; -} diff --git a/resources/3rdparty/glpk-4.53/src/zlib/zconf.h b/resources/3rdparty/glpk-4.53/src/zlib/zconf.h deleted file mode 100644 index af6a4f0fe..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/zconf.h +++ /dev/null @@ -1,168 +0,0 @@ -/* zconf.h (configuration of the zlib compression library) */ - -/* Modified by Andrew Makhorin , April 2011 */ - -/* Copyright (C) 1995-2010 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in - * zlib.h */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* (file adler32.c) */ -#define adler32 _glp_zlib_adler32 -#define adler32_combine _glp_zlib_adler32_combine -#define adler32_combine64 _glp_zlib_adler32_combine64 - -/* (file compress.c) */ -#define compress2 _glp_zlib_compress2 -#define compress _glp_zlib_compress -#define compressBound _glp_zlib_compressBound - -/* (file crc32.c) */ -#define get_crc_table _glp_zlib_get_crc_table -#define crc32 _glp_zlib_crc32 -#define crc32_combine _glp_zlib_crc32_combine -#define crc32_combine64 _glp_zlib_crc32_combine64 - -/* (file deflate.c) */ -#define deflateInit_ _glp_zlib_deflateInit_ -#define deflateInit2_ _glp_zlib_deflateInit2_ -#define deflateSetDictionary _glp_zlib_deflateSetDictionary -#define deflateReset _glp_zlib_deflateReset -#define deflateSetHeader _glp_zlib_deflateSetHeader -#define deflatePrime _glp_zlib_deflatePrime -#define deflateParams _glp_zlib_deflateParams -#define deflateTune _glp_zlib_deflateTune -#define deflateBound _glp_zlib_deflateBound -#define deflate _glp_zlib_deflate -#define deflateEnd _glp_zlib_deflateEnd -#define deflateCopy _glp_zlib_deflateCopy -#define deflate_copyright _glp_zlib_deflate_copyright - -/* (file gzclose.c) */ -#define gzclose _glp_zlib_gzclose - -/* (file gzlib.c) */ -#define gzopen _glp_zlib_gzopen -#define gzopen64 _glp_zlib_gzopen64 -#define gzdopen _glp_zlib_gzdopen -#define gzbuffer _glp_zlib_gzbuffer -#define gzrewind _glp_zlib_gzrewind -#define gzseek64 _glp_zlib_gzseek64 -#define gzseek _glp_zlib_gzseek -#define gztell64 _glp_zlib_gztell64 -#define gztell _glp_zlib_gztell -#define gzoffset64 _glp_zlib_gzoffset64 -#define gzoffset _glp_zlib_gzoffset -#define gzeof _glp_zlib_gzeof -#define gzerror _glp_zlib_gzerror -#define gzclearerr _glp_zlib_gzclearerr -#define gz_error _glp_zlib_gz_error - -/* (file gzread.c) */ -#define gzread _glp_zlib_gzread -#define gzgetc _glp_zlib_gzgetc -#define gzungetc _glp_zlib_gzungetc -#define gzgets _glp_zlib_gzgets -#define gzdirect _glp_zlib_gzdirect -#define gzclose_r _glp_zlib_gzclose_r - -/* (file gzwrite.c) */ -#define gzwrite _glp_zlib_gzwrite -#define gzputc _glp_zlib_gzputc -#define gzputs _glp_zlib_gzputs -#define gzprintf _glp_zlib_gzprintf -#define gzflush _glp_zlib_gzflush -#define gzsetparams _glp_zlib_gzsetparams -#define gzclose_w _glp_zlib_gzclose_w - -/* (file infback.c) */ -#define inflateBackInit_ _glp_zlib_inflateBackInit_ -#define inflateBack _glp_zlib_inflateBack -#define inflateBackEnd _glp_zlib_inflateBackEnd - -/* (file inffast.c) */ -#define inflate_fast _glp_zlib_inflate_fast - -/* (file inflate.c) */ -#define inflateReset _glp_zlib_inflateReset -#define inflateReset2 _glp_zlib_inflateReset2 -#define inflateInit2_ _glp_zlib_inflateInit2_ -#define inflateInit_ _glp_zlib_inflateInit_ -#define inflatePrime _glp_zlib_inflatePrime -#define inflate _glp_zlib_inflate -#define inflateEnd _glp_zlib_inflateEnd -#define inflateSetDictionary _glp_zlib_inflateSetDictionary -#define inflateGetHeader _glp_zlib_inflateGetHeader -#define inflateSync _glp_zlib_inflateSync -#define inflateSyncPoint _glp_zlib_inflateSyncPoint -#define inflateCopy _glp_zlib_inflateCopy -#define inflateUndermine _glp_zlib_inflateUndermine -#define inflateMark _glp_zlib_inflateMark - -/* (file inftrees.c) */ -#define inflate_table _glp_zlib_inflate_table -#define inflate_copyright _glp_zlib_inflate_copyright - -/* (file trees.c) */ -#define _tr_init _glp_zlib_tr_init -#define _tr_stored_block _glp_zlib_tr_stored_block -#define _tr_align _glp_zlib_tr_align -#define _tr_flush_block _glp_zlib_tr_flush_block -#define _tr_tally _glp_zlib_tr_tally -#define _dist_code _glp_zlib_dist_code -#define _length_code _glp_zlib_length_code - -/* (file uncompr.c) */ -#define uncompress _glp_zlib_uncompress - -/* (file zutil.c) */ -#define zlibVersion _glp_zlib_zlibVersion -#define zlibCompileFlags _glp_zlib_zlibCompileFlags -#define zError _glp_zlib_zError -#define zcalloc _glp_zlib_zcalloc -#define zcfree _glp_zlib_zcfree -#define z_errmsg _glp_zlib_z_errmsg - -#define STDC 1 - -#define MAX_MEM_LEVEL 9 - -#define MAX_WBITS 15 - -#define OF(args) args - -#define ZEXTERN extern -#define ZEXPORT -#define ZEXPORTVA - -#define FAR - -typedef unsigned char Byte; -typedef unsigned int uInt; -typedef unsigned long uLong; - -typedef Byte Bytef; -typedef char charf; -typedef int intf; -typedef uInt uIntf; -typedef uLong uLongf; - -typedef void const *voidpc; -typedef void *voidpf; -typedef void *voidp; - -#define z_off_t long - -#define z_off64_t z_off_t - -#define NO_vsnprintf 1 - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/zlib/zio.c b/resources/3rdparty/glpk-4.53/src/zlib/zio.c deleted file mode 100644 index a55b258a7..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/zio.c +++ /dev/null @@ -1,92 +0,0 @@ -/* zio.c (simulation of non-standard low-level i/o functions) */ - -/* Written by Andrew Makhorin , April 2011 - * For conditions of distribution and use, see copyright notice in - * zlib.h */ - -/* (reserved for copyright notice) */ - -#include -#include -#include "zio.h" - -static FILE *file[FOPEN_MAX]; -static int initialized = 0; - -static void initialize(void) -{ int fd; - assert(!initialized); - file[0] = stdin; - file[1] = stdout; - file[2] = stderr; - for (fd = 3; fd < FOPEN_MAX; fd++) - file[fd] = NULL; - initialized = 1; - return; -} - -int open(const char *path, int oflag, ...) -{ FILE *fp; - int fd; - if (!initialized) initialize(); - /* see file gzlib.c, function gz_open */ - if (oflag == O_RDONLY) - fp = fopen(path, "rb"); - else if (oflag == (O_WRONLY | O_CREAT | O_TRUNC)) - fp = fopen(path, "wb"); - else if (oflag == (O_WRONLY | O_CREAT | O_APPEND)) - fp = fopen(path, "ab"); - else - assert(oflag != oflag); - if (fp == NULL) - return -1; - for (fd = 0; fd < FOPEN_MAX; fd++) - if (file[fd] == NULL) break; - assert(fd < FOPEN_MAX); - file[fd] = fp; - return fd; -} - -long read(int fd, void *buf, unsigned long nbyte) -{ unsigned long count; - if (!initialized) initialize(); - assert(0 <= fd && fd < FOPEN_MAX); - assert(file[fd] != NULL); - count = fread(buf, 1, nbyte, file[fd]); - if (ferror(file[fd])) - return -1; - return count; -} - -long write(int fd, const void *buf, unsigned long nbyte) -{ unsigned long count; - if (!initialized) initialize(); - assert(0 <= fd && fd < FOPEN_MAX); - assert(file[fd] != NULL); - count = fwrite(buf, 1, nbyte, file[fd]); - if (count != nbyte) - return -1; - if (fflush(file[fd]) != 0) - return -1; - return count; -} - -long lseek(int fd, long offset, int whence) -{ if (!initialized) initialize(); - assert(0 <= fd && fd < FOPEN_MAX); - assert(file[fd] != NULL); - if (fseek(file[fd], offset, whence) != 0) - return -1; - return ftell(file[fd]); -} - -int close(int fd) -{ if (!initialized) initialize(); - assert(0 <= fd && fd < FOPEN_MAX); - assert(file[fd] != NULL); - fclose(file[fd]); - file[fd] = NULL; - return 0; -} - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/zlib/zio.h b/resources/3rdparty/glpk-4.53/src/zlib/zio.h deleted file mode 100644 index 1626c4ae4..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/zio.h +++ /dev/null @@ -1,37 +0,0 @@ -/* zio.h (simulation of non-standard low-level i/o functions) */ - -/* Written by Andrew Makhorin , April 2011 - * For conditions of distribution and use, see copyright notice in - * zlib.h */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. */ - -#ifndef ZIO_H -#define ZIO_H - -#define O_RDONLY 0x00 -#define O_WRONLY 0x01 -#define O_CREAT 0x10 -#define O_TRUNC 0x20 -#define O_APPEND 0x30 - -#define open _glp_zlib_open -int open(const char *path, int oflag, ...); - -#define read _glp_zlib_read -long read(int fd, void *buf, unsigned long nbyte); - -#define write _glp_zlib_write -long write(int fd, const void *buf, unsigned long nbyte); - -#define lseek _glp_zlib_lseek -long lseek(int fd, long offset, int whence); - -#define close _glp_zlib_close -int close(int fd); - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/src/zlib/zlib.h b/resources/3rdparty/glpk-4.53/src/zlib/zlib.h deleted file mode 100644 index bfbba83e8..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/zlib.h +++ /dev/null @@ -1,1613 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.5, April 19th, 2010 - - Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.5" -#define ZLIB_VERNUM 0x1250 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 5 -#define ZLIB_VER_SUBREVISION 0 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip streams in memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use in the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). Some - output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed code - block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the stream - are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least the - value returned by deflateBound (see below). If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect the - compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the - exact value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit() does not process any header information -- that is deferred - until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing will - resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all the uncompressed data. (The size - of the uncompressed data may have been saved by the compressor for this - purpose.) The next operation on this stream must be inflateEnd to deallocate - the decompression state. The use of Z_FINISH is never required, but can be - used to inform inflate that a faster approach may be used for the single - inflate() call. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation - is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK or Z_TREES is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the adler32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the adler32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained, so applications that need that information should - instead use raw inflate, see inflateInit2() below, or inflateBack() and - perform their own processing of the gzip header and trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is desired. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by the - caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any call - of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. The - stream will keep the same compression level and any other attributes that - may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression level is changed, the input available so far is - compressed with the old level (and may be flushed); the new level will take - effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to be - compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if - strm->avail_out was zero. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). -*/ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - crc32 instead of an adler32. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called - immediately after inflateInit2() or inflateReset() and before any call of - inflate() to set the dictionary. The application must insure that the - dictionary that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been - found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the - success case, the application may save the current current value of total_in - which indicates where valid compressed data was found. In the error case, - the application may repeatedly call inflateSync, providing more input each - time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above or -1 << 16 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the normal - behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed buffer. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. -*/ - - - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef voidp gzFile; /* opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); - - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) Also "a" - can be used instead of "w" to request that the gzip stream that will be - written be appended to the file. "+" will result in an error, since reading - and writing to the same gzip file is not supported. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); -/* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Two buffers are allocated, either both of the specified size when - writing, or one of the specified size and the other twice that size when - reading. A larger buffer size of, for example, 64K or 128K bytes will - noticeably increase the speed of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. If - the input file was not in gzip format, gzread copies the given number of - bytes into the buffer. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream, or failing that, reading the rest - of the input file directly without decompression. The entire input file - will be read if gzread is called until it returns less than the requested - len. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. -*/ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. -*/ - -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or 0 in case of error. The number of - uncompressed bytes written is limited to 8191, or one less than the buffer - size given to gzbuffer(). The caller should assure that this limit is not - exceeded. If it is exceeded, then gzprintf() will return an error (0) with - nothing written. In this case, there may also be a buffer overflow with - unpredictable consequences, which is possible only if zlib was compiled with - the insecure functions sprintf() or vsprintf() because the secure snprintf() - or vsnprintf() functions were not available. This can be determined using - zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatented gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); - - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); - - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. This state can change from - false to true while reading the input file if the end of a gzip stream is - reached, but is followed by data that is not another gzip stream. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the for the crc. Pre- and post-conditioning (one's - complement) is performed within this function so it shouldn't be done by the - application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); -#endif - -#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# ifdef _LARGEFILE64_SOURCE - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); -#endif - -/* hack for buggy compilers */ -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; -#endif - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/resources/3rdparty/glpk-4.53/src/zlib/zutil.c b/resources/3rdparty/glpk-4.53/src/zlib/zutil.c deleted file mode 100644 index 898ed345b..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/zutil.c +++ /dev/null @@ -1,318 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005, 2010 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -const char * const z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; - - -const char * ZEXPORT zlibVersion() -{ - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() -{ - uLong flags; - - flags = 0; - switch ((int)(sizeof(uInt))) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch ((int)(sizeof(uLong))) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch ((int)(sizeof(voidpf))) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#ifdef STDC -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef DEBUG - -# ifndef verbose -# define verbose 0 -# endif -int ZLIB_INTERNAL z_verbose = verbose; - -void ZLIB_INTERNAL z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(err) - int err; -{ - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void ZLIB_INTERNAL zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int ZLIB_INTERNAL zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void ZLIB_INTERNAL zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf = opaque; /* just to make some compilers happy */ - ulg bsize = (ulg)items*size; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - int n; - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - ptr = opaque; /* just to make some compilers happy */ - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - return _halloc((long)items, size); -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - if (opaque) items += size - size; /* make compiler happy */ - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void ZLIB_INTERNAL zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - free(ptr); - if (opaque) return; /* make compiler happy */ -} - -#endif /* MY_ZCALLOC */ diff --git a/resources/3rdparty/glpk-4.53/src/zlib/zutil.h b/resources/3rdparty/glpk-4.53/src/zlib/zutil.h deleted file mode 100644 index 737bd38f5..000000000 --- a/resources/3rdparty/glpk-4.53/src/zlib/zutil.h +++ /dev/null @@ -1,93 +0,0 @@ -/* zutil.h (internal interface of the zlib compression library) */ - -/* Modified by Andrew Makhorin , April 2011 */ - -/* Copyright (C) 1995-2010 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in - * zlib.h */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#define ZLIB_INTERNAL - -#include "zlib.h" - -#include -#include -#include - -#define local static - -typedef unsigned char uch; -typedef uch uchf; -typedef unsigned short ush; -typedef ush ushf; -typedef unsigned long ulg; - -extern const char * const z_errmsg[10]; - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm, err) \ - return (strm->msg = (char *)ERR_MSG(err), (err)) - -#define DEF_WBITS MAX_WBITS - -#if MAX_MEM_LEVEL >= 8 -#define DEF_MEM_LEVEL 8 -#else -#define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 - -#define MIN_MATCH 3 -#define MAX_MATCH 258 - -#define PRESET_DICT 0x20 - -#define OS_CODE 0x03 /* assume Unix */ - -#define HAVE_MEMCPY 1 -#define zmemcpy memcpy -#define zmemzero(dest, len) memset(dest, 0, len) - -#ifdef DEBUG -#include -extern int ZLIB_INTERNAL z_verbose; -extern void ZLIB_INTERNAL z_error OF((char *m)); -#define Assert(cond, msg) { if(!(cond)) z_error(msg); } -#define Trace(x) { if (z_verbose >= 0) fprintf x; } -#define Tracev(x) { if (z_verbose > 0) fprintf x; } -#define Tracevv(x) {if (z_verbose > 1) fprintf x; } -#define Tracec(c, x) {if (z_verbose > 0 && (c)) fprintf x; } -#define Tracecv(c, x) {if (z_verbose > 1 && (c)) fprintf x; } -#else -#define Assert(cond, msg) -#define Trace(x) -#define Tracev(x) -#define Tracevv(x) -#define Tracec(c, x) -#define Tracecv(c, x) -#endif - -voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); -void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) \ - (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) { if (p) ZFREE(s, p); } - -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC10.bat b/resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC10.bat deleted file mode 100644 index b0f693446..000000000 --- a/resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC10.bat +++ /dev/null @@ -1,11 +0,0 @@ -rem Build GLPK with Microsoft Visual Studio Express 2010 - -rem NOTE: Make sure that HOME variable specifies correct path -set HOME="C:\Program Files\Microsoft Visual Studio 10.0\VC" - -call %HOME%\vcvarsall.bat x86 -copy config_VC config.h -%HOME%\bin\nmake.exe /f Makefile_VC -%HOME%\bin\nmake.exe /f Makefile_VC check - -pause diff --git a/resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC10_DLL.bat b/resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC10_DLL.bat deleted file mode 100644 index e66f5cb39..000000000 --- a/resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC10_DLL.bat +++ /dev/null @@ -1,11 +0,0 @@ -rem Build GLPK DLL with Microsoft Visual Studio Express 2010 - -rem NOTE: Make sure that HOME variable specifies correct path -set HOME="C:\Program Files\Microsoft Visual Studio 10.0\VC" - -call %HOME%\vcvarsall.bat x86 -copy config_VC config.h -%HOME%\bin\nmake.exe /f Makefile_VC_DLL -%HOME%\bin\nmake.exe /f Makefile_VC_DLL check - -pause diff --git a/resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC9.bat b/resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC9.bat deleted file mode 100644 index 9c5e8f83d..000000000 --- a/resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC9.bat +++ /dev/null @@ -1,11 +0,0 @@ -rem Build GLPK with Microsoft Visual Studio Express 2008 - -rem NOTE: Make sure that HOME variable specifies correct path -set HOME="C:\Program Files\Microsoft Visual Studio 9.0\VC" - -call %HOME%\bin\vcvars32.bat -copy config_VC config.h -%HOME%\bin\nmake.exe /f Makefile_VC -%HOME%\bin\nmake.exe /f Makefile_VC check - -pause diff --git a/resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC9_DLL.bat b/resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC9_DLL.bat deleted file mode 100644 index f334c04af..000000000 --- a/resources/3rdparty/glpk-4.53/w32/Build_GLPK_with_VC9_DLL.bat +++ /dev/null @@ -1,11 +0,0 @@ -rem Build GLPK DLL with Microsoft Visual Studio Express 2008 - -rem NOTE: Make sure that HOME variable specifies correct path -set HOME="C:\Program Files\Microsoft Visual Studio 9.0\VC" - -call %HOME%\bin\vcvars32.bat -copy config_VC config.h -%HOME%\bin\nmake.exe /f Makefile_VC_DLL -%HOME%\bin\nmake.exe /f Makefile_VC_DLL check - -pause diff --git a/resources/3rdparty/glpk-4.53/w32/Makefile_VC b/resources/3rdparty/glpk-4.53/w32/Makefile_VC deleted file mode 100644 index c0c257ea2..000000000 --- a/resources/3rdparty/glpk-4.53/w32/Makefile_VC +++ /dev/null @@ -1,191 +0,0 @@ -## Build GLPK with Microsoft Visual Studio Express ## - -CFLAGS = \ -/I. \ -/I..\src \ -/I..\src\amd \ -/I..\src\bflib \ -/I..\src\cglib \ -/I..\src\colamd \ -/I..\src\env \ -/I..\src\minisat \ -/I..\src\misc \ -/I..\src\proxy \ -/I..\src\zlib \ -/DHAVE_CONFIG_H=1 \ -/D_CRT_SECURE_NO_WARNINGS=1 \ -/nologo \ -/W3 \ -/O2 - -OBJSET = \ -..\src\avl.obj \ -..\src\bfd.obj \ -..\src\bfx.obj \ -..\src\glpapi01.obj \ -..\src\glpapi02.obj \ -..\src\glpapi03.obj \ -..\src\glpapi04.obj \ -..\src\glpapi05.obj \ -..\src\glpapi06.obj \ -..\src\glpapi07.obj \ -..\src\glpapi08.obj \ -..\src\glpapi09.obj \ -..\src\glpapi10.obj \ -..\src\glpapi11.obj \ -..\src\glpapi12.obj \ -..\src\glpapi13.obj \ -..\src\glpapi14.obj \ -..\src\glpapi15.obj \ -..\src\glpapi16.obj \ -..\src\glpapi17.obj \ -..\src\glpapi18.obj \ -..\src\glpapi19.obj \ -..\src\glpapi20.obj \ -..\src\glpapi21.obj \ -..\src\glpcpx.obj \ -..\src\glpdmx.obj \ -..\src\glpgmp.obj \ -..\src\glphbm.obj \ -..\src\glpini01.obj \ -..\src\glpini02.obj \ -..\src\glpios01.obj \ -..\src\glpios02.obj \ -..\src\glpios03.obj \ -..\src\glpios04.obj \ -..\src\glpios05.obj \ -..\src\glpios06.obj \ -..\src\glpios07.obj \ -..\src\glpios08.obj \ -..\src\glpios09.obj \ -..\src\glpios10.obj \ -..\src\glpios11.obj \ -..\src\glpios12.obj \ -..\src\glpipm.obj \ -..\src\glplpf.obj \ -..\src\glpmat.obj \ -..\src\glpmpl01.obj \ -..\src\glpmpl02.obj \ -..\src\glpmpl03.obj \ -..\src\glpmpl04.obj \ -..\src\glpmpl05.obj \ -..\src\glpmpl06.obj \ -..\src\glpmps.obj \ -..\src\glpnet03.obj \ -..\src\glpnet04.obj \ -..\src\glpnet05.obj \ -..\src\glpnpp01.obj \ -..\src\glpnpp02.obj \ -..\src\glpnpp03.obj \ -..\src\glpnpp04.obj \ -..\src\glpnpp05.obj \ -..\src\glpnpp06.obj \ -..\src\glprgr.obj \ -..\src\glpscl.obj \ -..\src\glpsdf.obj \ -..\src\glpspm.obj \ -..\src\glpspx01.obj \ -..\src\glpspx02.obj \ -..\src\glpsql.obj \ -..\src\glpssx01.obj \ -..\src\glpssx02.obj \ -..\src\glptsp.obj \ -..\src\lux.obj \ -..\src\amd\amd_1.obj \ -..\src\amd\amd_2.obj \ -..\src\amd\amd_aat.obj \ -..\src\amd\amd_control.obj \ -..\src\amd\amd_defaults.obj \ -..\src\amd\amd_dump.obj \ -..\src\amd\amd_info.obj \ -..\src\amd\amd_order.obj \ -..\src\amd\amd_post_tree.obj \ -..\src\amd\amd_postorder.obj \ -..\src\amd\amd_preprocess.obj \ -..\src\amd\amd_valid.obj \ -..\src\bflib\fhv.obj \ -..\src\bflib\fhvint.obj \ -..\src\bflib\ifu.obj \ -..\src\bflib\luf.obj \ -..\src\bflib\lufint.obj \ -..\src\bflib\sgf.obj \ -..\src\bflib\sva.obj \ -..\src\cglib\cfg.obj \ -..\src\cglib\cfg1.obj \ -..\src\colamd\colamd.obj \ -..\src\env\alloc.obj \ -..\src\env\dlsup.obj \ -..\src\env\env.obj \ -..\src\env\error.obj \ -..\src\env\stdout.obj \ -..\src\env\stream.obj \ -..\src\env\time.obj \ -..\src\env\tls.obj \ -..\src\minisat\minisat.obj \ -..\src\misc\bignum.obj \ -..\src\misc\dmp.obj \ -..\src\misc\ffalg.obj \ -..\src\misc\fp2rat.obj \ -..\src\misc\gcd.obj \ -..\src\misc\jd.obj \ -..\src\misc\keller.obj \ -..\src\misc\mc13d.obj \ -..\src\misc\mc21a.obj \ -..\src\misc\okalg.obj \ -..\src\misc\qmd.obj \ -..\src\misc\relax4.obj \ -..\src\misc\rng.obj \ -..\src\misc\rng1.obj \ -..\src\misc\round2n.obj \ -..\src\misc\str2int.obj \ -..\src\misc\str2num.obj \ -..\src\misc\strspx.obj \ -..\src\misc\strtrim.obj \ -..\src\misc\triang.obj \ -..\src\misc\wclique.obj \ -..\src\misc\wclique1.obj \ -..\src\proxy\proxy.obj \ -..\src\proxy\proxy1.obj \ -..\src\zlib\adler32.obj \ -..\src\zlib\compress.obj \ -..\src\zlib\crc32.obj \ -..\src\zlib\deflate.obj \ -..\src\zlib\gzclose.obj \ -..\src\zlib\gzlib.obj \ -..\src\zlib\gzread.obj \ -..\src\zlib\gzwrite.obj \ -..\src\zlib\inffast.obj \ -..\src\zlib\inflate.obj \ -..\src\zlib\inftrees.obj \ -..\src\zlib\trees.obj \ -..\src\zlib\uncompr.obj \ -..\src\zlib\zio.obj \ -..\src\zlib\zutil.obj - -.c.obj: - cl.exe $(CFLAGS) /Fo$*.obj /c $*.c - -all: glpk.lib glpsol.exe - -glpk.lib: $(OBJSET) - lib.exe /out:glpk.lib \ - ..\src\*.obj \ - ..\src\amd\*.obj \ - ..\src\bflib\*.obj \ - ..\src\cglib\*.obj \ - ..\src\colamd\*.obj \ - ..\src\env\*.obj \ - ..\src\minisat\*.obj \ - ..\src\misc\*.obj \ - ..\src\proxy\*.obj \ - ..\src\zlib\*.obj - -glpsol.exe: ..\examples\glpsol.obj glpk.lib - cl.exe $(CFLAGS) /Feglpsol.exe \ - ..\examples\glpsol.obj glpk.lib - -check: glpsol.exe - .\glpsol.exe --version - .\glpsol.exe --mps ..\examples\plan.mps - -## eof ## diff --git a/resources/3rdparty/glpk-4.53/w32/Makefile_VC_DLL b/resources/3rdparty/glpk-4.53/w32/Makefile_VC_DLL deleted file mode 100644 index 9eb7a6586..000000000 --- a/resources/3rdparty/glpk-4.53/w32/Makefile_VC_DLL +++ /dev/null @@ -1,192 +0,0 @@ -## Build GLPK DLL with Microsoft Visual Studio Express ## - -CFLAGS = \ -/I. \ -/I..\src \ -/I..\src\amd \ -/I..\src\bflib \ -/I..\src\cglib \ -/I..\src\colamd \ -/I..\src\env \ -/I..\src\minisat \ -/I..\src\misc \ -/I..\src\proxy \ -/I..\src\zlib \ -/DHAVE_CONFIG_H=1 \ -/D_CRT_SECURE_NO_WARNINGS=1 \ -/nologo \ -/W3 \ -/O2 - -OBJSET = \ -..\src\avl.obj \ -..\src\bfd.obj \ -..\src\bfx.obj \ -..\src\glpapi01.obj \ -..\src\glpapi02.obj \ -..\src\glpapi03.obj \ -..\src\glpapi04.obj \ -..\src\glpapi05.obj \ -..\src\glpapi06.obj \ -..\src\glpapi07.obj \ -..\src\glpapi08.obj \ -..\src\glpapi09.obj \ -..\src\glpapi10.obj \ -..\src\glpapi11.obj \ -..\src\glpapi12.obj \ -..\src\glpapi13.obj \ -..\src\glpapi14.obj \ -..\src\glpapi15.obj \ -..\src\glpapi16.obj \ -..\src\glpapi17.obj \ -..\src\glpapi18.obj \ -..\src\glpapi19.obj \ -..\src\glpapi20.obj \ -..\src\glpapi21.obj \ -..\src\glpcpx.obj \ -..\src\glpdmx.obj \ -..\src\glpgmp.obj \ -..\src\glphbm.obj \ -..\src\glpini01.obj \ -..\src\glpini02.obj \ -..\src\glpios01.obj \ -..\src\glpios02.obj \ -..\src\glpios03.obj \ -..\src\glpios04.obj \ -..\src\glpios05.obj \ -..\src\glpios06.obj \ -..\src\glpios07.obj \ -..\src\glpios08.obj \ -..\src\glpios09.obj \ -..\src\glpios10.obj \ -..\src\glpios11.obj \ -..\src\glpios12.obj \ -..\src\glpipm.obj \ -..\src\glplpf.obj \ -..\src\glpmat.obj \ -..\src\glpmpl01.obj \ -..\src\glpmpl02.obj \ -..\src\glpmpl03.obj \ -..\src\glpmpl04.obj \ -..\src\glpmpl05.obj \ -..\src\glpmpl06.obj \ -..\src\glpmps.obj \ -..\src\glpnet03.obj \ -..\src\glpnet04.obj \ -..\src\glpnet05.obj \ -..\src\glpnpp01.obj \ -..\src\glpnpp02.obj \ -..\src\glpnpp03.obj \ -..\src\glpnpp04.obj \ -..\src\glpnpp05.obj \ -..\src\glpnpp06.obj \ -..\src\glprgr.obj \ -..\src\glpscl.obj \ -..\src\glpsdf.obj \ -..\src\glpspm.obj \ -..\src\glpspx01.obj \ -..\src\glpspx02.obj \ -..\src\glpsql.obj \ -..\src\glpssx01.obj \ -..\src\glpssx02.obj \ -..\src\glptsp.obj \ -..\src\lux.obj \ -..\src\amd\amd_1.obj \ -..\src\amd\amd_2.obj \ -..\src\amd\amd_aat.obj \ -..\src\amd\amd_control.obj \ -..\src\amd\amd_defaults.obj \ -..\src\amd\amd_dump.obj \ -..\src\amd\amd_info.obj \ -..\src\amd\amd_order.obj \ -..\src\amd\amd_post_tree.obj \ -..\src\amd\amd_postorder.obj \ -..\src\amd\amd_preprocess.obj \ -..\src\amd\amd_valid.obj \ -..\src\bflib\fhv.obj \ -..\src\bflib\fhvint.obj \ -..\src\bflib\ifu.obj \ -..\src\bflib\luf.obj \ -..\src\bflib\lufint.obj \ -..\src\bflib\sgf.obj \ -..\src\bflib\sva.obj \ -..\src\cglib\cfg.obj \ -..\src\cglib\cfg1.obj \ -..\src\colamd\colamd.obj \ -..\src\env\alloc.obj \ -..\src\env\dlsup.obj \ -..\src\env\env.obj \ -..\src\env\error.obj \ -..\src\env\stdout.obj \ -..\src\env\stream.obj \ -..\src\env\time.obj \ -..\src\env\tls.obj \ -..\src\minisat\minisat.obj \ -..\src\misc\bignum.obj \ -..\src\misc\dmp.obj \ -..\src\misc\ffalg.obj \ -..\src\misc\fp2rat.obj \ -..\src\misc\gcd.obj \ -..\src\misc\jd.obj \ -..\src\misc\keller.obj \ -..\src\misc\mc13d.obj \ -..\src\misc\mc21a.obj \ -..\src\misc\okalg.obj \ -..\src\misc\qmd.obj \ -..\src\misc\relax4.obj \ -..\src\misc\rng.obj \ -..\src\misc\rng1.obj \ -..\src\misc\round2n.obj \ -..\src\misc\str2int.obj \ -..\src\misc\str2num.obj \ -..\src\misc\strspx.obj \ -..\src\misc\strtrim.obj \ -..\src\misc\triang.obj \ -..\src\misc\wclique.obj \ -..\src\misc\wclique1.obj \ -..\src\proxy\proxy.obj \ -..\src\proxy\proxy1.obj \ -..\src\zlib\adler32.obj \ -..\src\zlib\compress.obj \ -..\src\zlib\crc32.obj \ -..\src\zlib\deflate.obj \ -..\src\zlib\gzclose.obj \ -..\src\zlib\gzlib.obj \ -..\src\zlib\gzread.obj \ -..\src\zlib\gzwrite.obj \ -..\src\zlib\inffast.obj \ -..\src\zlib\inflate.obj \ -..\src\zlib\inftrees.obj \ -..\src\zlib\trees.obj \ -..\src\zlib\uncompr.obj \ -..\src\zlib\zio.obj \ -..\src\zlib\zutil.obj - -.c.obj: - cl.exe $(CFLAGS) /Fo$*.obj /c $*.c - -all: glpk_4_53.dll glpsol.exe - -glpk_4_53.dll: $(OBJSET) - cl.exe $(CFLAGS) /LD /Feglpk_4_53.dll \ - ..\src\*.obj \ - ..\src\amd\*.obj \ - ..\src\bflib\*.obj \ - ..\src\cglib\*.obj \ - ..\src\colamd\*.obj \ - ..\src\env\*.obj \ - ..\src\minisat\*.obj \ - ..\src\misc\*.obj \ - ..\src\proxy\*.obj \ - ..\src\zlib\*.obj \ - glpk_4_53.def - -glpsol.exe: ..\examples\glpsol.obj glpk_4_53.dll - cl.exe $(CFLAGS) /Feglpsol.exe \ - ..\examples\glpsol.obj glpk_4_53.lib - -check: glpsol.exe - .\glpsol.exe --version - .\glpsol.exe --mps ..\examples\plan.mps - -## eof ## diff --git a/resources/3rdparty/glpk-4.53/w32/config_VC b/resources/3rdparty/glpk-4.53/w32/config_VC deleted file mode 100644 index 581ab6e6e..000000000 --- a/resources/3rdparty/glpk-4.53/w32/config_VC +++ /dev/null @@ -1,13 +0,0 @@ -/* GLPK configuration file (Microsoft Visual Studio Express) */ - -#define __WOE__ 1 - -#define ODBC_DLNAME "odbc32.dll" -/* ODBC shared library name if this feature is enabled */ - -#if 0 -#define MYSQL_DLNAME "libmysql.dll" -/* MySQL shared library name if this feature is enabled */ -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/w32/glpk_4_53.def b/resources/3rdparty/glpk-4.53/w32/glpk_4_53.def deleted file mode 100644 index dc5ed7595..000000000 --- a/resources/3rdparty/glpk-4.53/w32/glpk_4_53.def +++ /dev/null @@ -1,223 +0,0 @@ -LIBRARY glpk_4_53 -VERSION 4.53 -DESCRIPTION "GNU Linear Programming Kit" -EXPORTS -glp_create_prob -glp_set_prob_name -glp_set_obj_name -glp_set_obj_dir -glp_add_rows -glp_add_cols -glp_set_row_name -glp_set_col_name -glp_set_row_bnds -glp_set_col_bnds -glp_set_obj_coef -glp_set_mat_row -glp_set_mat_col -glp_load_matrix -glp_check_dup -glp_sort_matrix -glp_del_rows -glp_del_cols -glp_copy_prob -glp_erase_prob -glp_delete_prob -glp_get_prob_name -glp_get_obj_name -glp_get_obj_dir -glp_get_num_rows -glp_get_num_cols -glp_get_row_name -glp_get_col_name -glp_get_row_type -glp_get_row_lb -glp_get_row_ub -glp_get_col_type -glp_get_col_lb -glp_get_col_ub -glp_get_obj_coef -glp_get_num_nz -glp_get_mat_row -glp_get_mat_col -glp_create_index -glp_find_row -glp_find_col -glp_delete_index -glp_set_rii -glp_set_sjj -glp_get_rii -glp_get_sjj -glp_scale_prob -glp_unscale_prob -glp_set_row_stat -glp_set_col_stat -glp_std_basis -glp_adv_basis -glp_cpx_basis -glp_simplex -glp_exact -glp_init_smcp -glp_get_status -glp_get_prim_stat -glp_get_dual_stat -glp_get_obj_val -glp_get_row_stat -glp_get_row_prim -glp_get_row_dual -glp_get_col_stat -glp_get_col_prim -glp_get_col_dual -glp_get_unbnd_ray -glp_get_it_cnt -glp_set_it_cnt -glp_interior -glp_init_iptcp -glp_ipt_status -glp_ipt_obj_val -glp_ipt_row_prim -glp_ipt_row_dual -glp_ipt_col_prim -glp_ipt_col_dual -glp_set_col_kind -glp_get_col_kind -glp_get_num_int -glp_get_num_bin -glp_intopt -glp_init_iocp -glp_mip_status -glp_mip_obj_val -glp_mip_row_val -glp_mip_col_val -glp_check_kkt -glp_print_sol -glp_read_sol -glp_write_sol -glp_print_ranges -glp_print_ipt -glp_read_ipt -glp_write_ipt -glp_print_mip -glp_read_mip -glp_write_mip -glp_bf_exists -glp_factorize -glp_bf_updated -glp_get_bfcp -glp_set_bfcp -glp_get_bhead -glp_get_row_bind -glp_get_col_bind -glp_ftran -glp_btran -glp_warm_up -glp_eval_tab_row -glp_eval_tab_col -glp_transform_row -glp_transform_col -glp_prim_rtest -glp_dual_rtest -glp_analyze_bound -glp_analyze_coef -glp_ios_reason -glp_ios_get_prob -glp_ios_tree_size -glp_ios_curr_node -glp_ios_next_node -glp_ios_prev_node -glp_ios_up_node -glp_ios_node_level -glp_ios_node_bound -glp_ios_best_node -glp_ios_mip_gap -glp_ios_node_data -glp_ios_row_attr -glp_ios_pool_size -glp_ios_add_row -glp_ios_del_row -glp_ios_clear_pool -glp_ios_can_branch -glp_ios_branch_upon -glp_ios_select_node -glp_ios_heur_sol -glp_ios_terminate -glp_init_mpscp -glp_read_mps -glp_write_mps -glp_init_cpxcp -glp_read_lp -glp_write_lp -glp_read_prob -glp_write_prob -glp_mpl_alloc_wksp -glp_mpl_read_model -glp_mpl_read_data -glp_mpl_generate -glp_mpl_build_prob -glp_mpl_postsolve -glp_mpl_free_wksp -glp_main -glp_read_cnfsat -glp_check_cnfsat -glp_write_cnfsat -glp_minisat1 -glp_intfeas1 -glp_init_env -glp_version -glp_free_env -glp_puts -glp_printf -glp_vprintf -glp_term_out -glp_term_hook -glp_open_tee -glp_close_tee -glp_error_ -glp_assert_ -glp_error_hook -glp_alloc -glp_realloc -glp_free -glp_mem_limit -glp_mem_usage -glp_create_graph -glp_set_graph_name -glp_add_vertices -glp_set_vertex_name -glp_add_arc -glp_del_vertices -glp_del_arc -glp_erase_graph -glp_delete_graph -glp_create_v_index -glp_find_vertex -glp_delete_v_index -glp_read_graph -glp_write_graph -glp_mincost_lp -glp_mincost_okalg -glp_mincost_relax4 -glp_maxflow_lp -glp_maxflow_ffalg -glp_check_asnprob -glp_asnprob_lp -glp_asnprob_okalg -glp_asnprob_hall -glp_cpp -glp_read_mincost -glp_write_mincost -glp_read_maxflow -glp_write_maxflow -glp_read_asnprob -glp_write_asnprob -glp_read_ccdata -glp_write_ccdata -glp_netgen -glp_netgen_prob -glp_gridgen -glp_rmfgen -glp_weak_comp -glp_strong_comp -glp_top_sort -glp_wclique_exact -;; end of file ;; diff --git a/resources/3rdparty/glpk-4.53/w32/readme.txt b/resources/3rdparty/glpk-4.53/w32/readme.txt deleted file mode 100644 index 10daeda4b..000000000 --- a/resources/3rdparty/glpk-4.53/w32/readme.txt +++ /dev/null @@ -1,24 +0,0 @@ -This directory contains batch files and other stuff which you can use -to build GLPK for 32-bit Windows with the native C/C++ compilers. - -Before running the batch file do the following: - -1. Make sure that you have installed the compiler you are going to use - to build GLPK. - -2. Look into corresponding batch file (just right-click it and choose - 'Edit' in the popup menu; DO NOT choose 'Open'). Make sure that HOME - variable specifies correct path to the compiler directory; if not, - make necessary changes. - -To run the batch file just double-click it and wait a bit while the -Make utility does its job. The message 'OPTIMAL SOLUTION FOUND' in the -MS-DOS window means that all is OK. If you do not see it, something is -wrong. - -Once GLPK has been successfully built, there must appear two files in -this directory: - -glpk.lib, which is the GLPK object library, and - -glpsol.exe, which is the stand-alone GLPK LP/MIP solver. diff --git a/resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC10.bat b/resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC10.bat deleted file mode 100644 index 8e8a3e1e7..000000000 --- a/resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC10.bat +++ /dev/null @@ -1,11 +0,0 @@ -rem Build GLPK with Microsoft Visual Studio Express 2010 - -rem NOTE: Make sure that HOME variable specifies correct path -set HOME="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC" - -call %HOME%\vcvarsall.bat x64 -copy config_VC config.h -%HOME%\bin\nmake.exe /f Makefile_VC -%HOME%\bin\nmake.exe /f Makefile_VC check - -pause diff --git a/resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC10_DLL.bat b/resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC10_DLL.bat deleted file mode 100644 index 0bbe697b3..000000000 --- a/resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC10_DLL.bat +++ /dev/null @@ -1,11 +0,0 @@ -rem Build GLPK DLL with Microsoft Visual Studio Express 2010 - -rem NOTE: Make sure that HOME variable specifies correct path -set HOME="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC" - -call %HOME%\vcvarsall.bat x64 -copy config_VC config.h -%HOME%\bin\nmake.exe /f Makefile_VC_DLL -%HOME%\bin\nmake.exe /f Makefile_VC_DLL check - -pause diff --git a/resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC9.bat b/resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC9.bat deleted file mode 100644 index 9a32ef850..000000000 --- a/resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC9.bat +++ /dev/null @@ -1,11 +0,0 @@ -rem Build GLPK with Microsoft Visual Studio Express 2008 - -rem NOTE: Make sure that HOME variable specifies correct path -set HOME="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC" - -call %HOME%\bin\vcvars64.bat -copy config_VC config.h -%HOME%\bin\nmake.exe /f Makefile_VC -%HOME%\bin\nmake.exe /f Makefile_VC check - -pause diff --git a/resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC9_DLL.bat b/resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC9_DLL.bat deleted file mode 100644 index 4d7c19719..000000000 --- a/resources/3rdparty/glpk-4.53/w64/Build_GLPK_with_VC9_DLL.bat +++ /dev/null @@ -1,11 +0,0 @@ -rem Build GLPK DLL with Microsoft Visual Studio Express 2008 - -rem NOTE: Make sure that HOME variable specifies correct path -set HOME="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC" - -call %HOME%\bin\vcvars64.bat -copy config_VC config.h -%HOME%\bin\nmake.exe /f Makefile_VC_DLL -%HOME%\bin\nmake.exe /f Makefile_VC_DLL check - -pause diff --git a/resources/3rdparty/glpk-4.53/w64/config_VC b/resources/3rdparty/glpk-4.53/w64/config_VC deleted file mode 100644 index 581ab6e6e..000000000 --- a/resources/3rdparty/glpk-4.53/w64/config_VC +++ /dev/null @@ -1,13 +0,0 @@ -/* GLPK configuration file (Microsoft Visual Studio Express) */ - -#define __WOE__ 1 - -#define ODBC_DLNAME "odbc32.dll" -/* ODBC shared library name if this feature is enabled */ - -#if 0 -#define MYSQL_DLNAME "libmysql.dll" -/* MySQL shared library name if this feature is enabled */ -#endif - -/* eof */ diff --git a/resources/3rdparty/glpk-4.53/w64/glpk_4_53.def b/resources/3rdparty/glpk-4.53/w64/glpk_4_53.def deleted file mode 100644 index dc5ed7595..000000000 --- a/resources/3rdparty/glpk-4.53/w64/glpk_4_53.def +++ /dev/null @@ -1,223 +0,0 @@ -LIBRARY glpk_4_53 -VERSION 4.53 -DESCRIPTION "GNU Linear Programming Kit" -EXPORTS -glp_create_prob -glp_set_prob_name -glp_set_obj_name -glp_set_obj_dir -glp_add_rows -glp_add_cols -glp_set_row_name -glp_set_col_name -glp_set_row_bnds -glp_set_col_bnds -glp_set_obj_coef -glp_set_mat_row -glp_set_mat_col -glp_load_matrix -glp_check_dup -glp_sort_matrix -glp_del_rows -glp_del_cols -glp_copy_prob -glp_erase_prob -glp_delete_prob -glp_get_prob_name -glp_get_obj_name -glp_get_obj_dir -glp_get_num_rows -glp_get_num_cols -glp_get_row_name -glp_get_col_name -glp_get_row_type -glp_get_row_lb -glp_get_row_ub -glp_get_col_type -glp_get_col_lb -glp_get_col_ub -glp_get_obj_coef -glp_get_num_nz -glp_get_mat_row -glp_get_mat_col -glp_create_index -glp_find_row -glp_find_col -glp_delete_index -glp_set_rii -glp_set_sjj -glp_get_rii -glp_get_sjj -glp_scale_prob -glp_unscale_prob -glp_set_row_stat -glp_set_col_stat -glp_std_basis -glp_adv_basis -glp_cpx_basis -glp_simplex -glp_exact -glp_init_smcp -glp_get_status -glp_get_prim_stat -glp_get_dual_stat -glp_get_obj_val -glp_get_row_stat -glp_get_row_prim -glp_get_row_dual -glp_get_col_stat -glp_get_col_prim -glp_get_col_dual -glp_get_unbnd_ray -glp_get_it_cnt -glp_set_it_cnt -glp_interior -glp_init_iptcp -glp_ipt_status -glp_ipt_obj_val -glp_ipt_row_prim -glp_ipt_row_dual -glp_ipt_col_prim -glp_ipt_col_dual -glp_set_col_kind -glp_get_col_kind -glp_get_num_int -glp_get_num_bin -glp_intopt -glp_init_iocp -glp_mip_status -glp_mip_obj_val -glp_mip_row_val -glp_mip_col_val -glp_check_kkt -glp_print_sol -glp_read_sol -glp_write_sol -glp_print_ranges -glp_print_ipt -glp_read_ipt -glp_write_ipt -glp_print_mip -glp_read_mip -glp_write_mip -glp_bf_exists -glp_factorize -glp_bf_updated -glp_get_bfcp -glp_set_bfcp -glp_get_bhead -glp_get_row_bind -glp_get_col_bind -glp_ftran -glp_btran -glp_warm_up -glp_eval_tab_row -glp_eval_tab_col -glp_transform_row -glp_transform_col -glp_prim_rtest -glp_dual_rtest -glp_analyze_bound -glp_analyze_coef -glp_ios_reason -glp_ios_get_prob -glp_ios_tree_size -glp_ios_curr_node -glp_ios_next_node -glp_ios_prev_node -glp_ios_up_node -glp_ios_node_level -glp_ios_node_bound -glp_ios_best_node -glp_ios_mip_gap -glp_ios_node_data -glp_ios_row_attr -glp_ios_pool_size -glp_ios_add_row -glp_ios_del_row -glp_ios_clear_pool -glp_ios_can_branch -glp_ios_branch_upon -glp_ios_select_node -glp_ios_heur_sol -glp_ios_terminate -glp_init_mpscp -glp_read_mps -glp_write_mps -glp_init_cpxcp -glp_read_lp -glp_write_lp -glp_read_prob -glp_write_prob -glp_mpl_alloc_wksp -glp_mpl_read_model -glp_mpl_read_data -glp_mpl_generate -glp_mpl_build_prob -glp_mpl_postsolve -glp_mpl_free_wksp -glp_main -glp_read_cnfsat -glp_check_cnfsat -glp_write_cnfsat -glp_minisat1 -glp_intfeas1 -glp_init_env -glp_version -glp_free_env -glp_puts -glp_printf -glp_vprintf -glp_term_out -glp_term_hook -glp_open_tee -glp_close_tee -glp_error_ -glp_assert_ -glp_error_hook -glp_alloc -glp_realloc -glp_free -glp_mem_limit -glp_mem_usage -glp_create_graph -glp_set_graph_name -glp_add_vertices -glp_set_vertex_name -glp_add_arc -glp_del_vertices -glp_del_arc -glp_erase_graph -glp_delete_graph -glp_create_v_index -glp_find_vertex -glp_delete_v_index -glp_read_graph -glp_write_graph -glp_mincost_lp -glp_mincost_okalg -glp_mincost_relax4 -glp_maxflow_lp -glp_maxflow_ffalg -glp_check_asnprob -glp_asnprob_lp -glp_asnprob_okalg -glp_asnprob_hall -glp_cpp -glp_read_mincost -glp_write_mincost -glp_read_maxflow -glp_write_maxflow -glp_read_asnprob -glp_write_asnprob -glp_read_ccdata -glp_write_ccdata -glp_netgen -glp_netgen_prob -glp_gridgen -glp_rmfgen -glp_weak_comp -glp_strong_comp -glp_top_sort -glp_wclique_exact -;; end of file ;; diff --git a/resources/3rdparty/glpk-4.53/w64/makefile_VC b/resources/3rdparty/glpk-4.53/w64/makefile_VC deleted file mode 100644 index c0c257ea2..000000000 --- a/resources/3rdparty/glpk-4.53/w64/makefile_VC +++ /dev/null @@ -1,191 +0,0 @@ -## Build GLPK with Microsoft Visual Studio Express ## - -CFLAGS = \ -/I. \ -/I..\src \ -/I..\src\amd \ -/I..\src\bflib \ -/I..\src\cglib \ -/I..\src\colamd \ -/I..\src\env \ -/I..\src\minisat \ -/I..\src\misc \ -/I..\src\proxy \ -/I..\src\zlib \ -/DHAVE_CONFIG_H=1 \ -/D_CRT_SECURE_NO_WARNINGS=1 \ -/nologo \ -/W3 \ -/O2 - -OBJSET = \ -..\src\avl.obj \ -..\src\bfd.obj \ -..\src\bfx.obj \ -..\src\glpapi01.obj \ -..\src\glpapi02.obj \ -..\src\glpapi03.obj \ -..\src\glpapi04.obj \ -..\src\glpapi05.obj \ -..\src\glpapi06.obj \ -..\src\glpapi07.obj \ -..\src\glpapi08.obj \ -..\src\glpapi09.obj \ -..\src\glpapi10.obj \ -..\src\glpapi11.obj \ -..\src\glpapi12.obj \ -..\src\glpapi13.obj \ -..\src\glpapi14.obj \ -..\src\glpapi15.obj \ -..\src\glpapi16.obj \ -..\src\glpapi17.obj \ -..\src\glpapi18.obj \ -..\src\glpapi19.obj \ -..\src\glpapi20.obj \ -..\src\glpapi21.obj \ -..\src\glpcpx.obj \ -..\src\glpdmx.obj \ -..\src\glpgmp.obj \ -..\src\glphbm.obj \ -..\src\glpini01.obj \ -..\src\glpini02.obj \ -..\src\glpios01.obj \ -..\src\glpios02.obj \ -..\src\glpios03.obj \ -..\src\glpios04.obj \ -..\src\glpios05.obj \ -..\src\glpios06.obj \ -..\src\glpios07.obj \ -..\src\glpios08.obj \ -..\src\glpios09.obj \ -..\src\glpios10.obj \ -..\src\glpios11.obj \ -..\src\glpios12.obj \ -..\src\glpipm.obj \ -..\src\glplpf.obj \ -..\src\glpmat.obj \ -..\src\glpmpl01.obj \ -..\src\glpmpl02.obj \ -..\src\glpmpl03.obj \ -..\src\glpmpl04.obj \ -..\src\glpmpl05.obj \ -..\src\glpmpl06.obj \ -..\src\glpmps.obj \ -..\src\glpnet03.obj \ -..\src\glpnet04.obj \ -..\src\glpnet05.obj \ -..\src\glpnpp01.obj \ -..\src\glpnpp02.obj \ -..\src\glpnpp03.obj \ -..\src\glpnpp04.obj \ -..\src\glpnpp05.obj \ -..\src\glpnpp06.obj \ -..\src\glprgr.obj \ -..\src\glpscl.obj \ -..\src\glpsdf.obj \ -..\src\glpspm.obj \ -..\src\glpspx01.obj \ -..\src\glpspx02.obj \ -..\src\glpsql.obj \ -..\src\glpssx01.obj \ -..\src\glpssx02.obj \ -..\src\glptsp.obj \ -..\src\lux.obj \ -..\src\amd\amd_1.obj \ -..\src\amd\amd_2.obj \ -..\src\amd\amd_aat.obj \ -..\src\amd\amd_control.obj \ -..\src\amd\amd_defaults.obj \ -..\src\amd\amd_dump.obj \ -..\src\amd\amd_info.obj \ -..\src\amd\amd_order.obj \ -..\src\amd\amd_post_tree.obj \ -..\src\amd\amd_postorder.obj \ -..\src\amd\amd_preprocess.obj \ -..\src\amd\amd_valid.obj \ -..\src\bflib\fhv.obj \ -..\src\bflib\fhvint.obj \ -..\src\bflib\ifu.obj \ -..\src\bflib\luf.obj \ -..\src\bflib\lufint.obj \ -..\src\bflib\sgf.obj \ -..\src\bflib\sva.obj \ -..\src\cglib\cfg.obj \ -..\src\cglib\cfg1.obj \ -..\src\colamd\colamd.obj \ -..\src\env\alloc.obj \ -..\src\env\dlsup.obj \ -..\src\env\env.obj \ -..\src\env\error.obj \ -..\src\env\stdout.obj \ -..\src\env\stream.obj \ -..\src\env\time.obj \ -..\src\env\tls.obj \ -..\src\minisat\minisat.obj \ -..\src\misc\bignum.obj \ -..\src\misc\dmp.obj \ -..\src\misc\ffalg.obj \ -..\src\misc\fp2rat.obj \ -..\src\misc\gcd.obj \ -..\src\misc\jd.obj \ -..\src\misc\keller.obj \ -..\src\misc\mc13d.obj \ -..\src\misc\mc21a.obj \ -..\src\misc\okalg.obj \ -..\src\misc\qmd.obj \ -..\src\misc\relax4.obj \ -..\src\misc\rng.obj \ -..\src\misc\rng1.obj \ -..\src\misc\round2n.obj \ -..\src\misc\str2int.obj \ -..\src\misc\str2num.obj \ -..\src\misc\strspx.obj \ -..\src\misc\strtrim.obj \ -..\src\misc\triang.obj \ -..\src\misc\wclique.obj \ -..\src\misc\wclique1.obj \ -..\src\proxy\proxy.obj \ -..\src\proxy\proxy1.obj \ -..\src\zlib\adler32.obj \ -..\src\zlib\compress.obj \ -..\src\zlib\crc32.obj \ -..\src\zlib\deflate.obj \ -..\src\zlib\gzclose.obj \ -..\src\zlib\gzlib.obj \ -..\src\zlib\gzread.obj \ -..\src\zlib\gzwrite.obj \ -..\src\zlib\inffast.obj \ -..\src\zlib\inflate.obj \ -..\src\zlib\inftrees.obj \ -..\src\zlib\trees.obj \ -..\src\zlib\uncompr.obj \ -..\src\zlib\zio.obj \ -..\src\zlib\zutil.obj - -.c.obj: - cl.exe $(CFLAGS) /Fo$*.obj /c $*.c - -all: glpk.lib glpsol.exe - -glpk.lib: $(OBJSET) - lib.exe /out:glpk.lib \ - ..\src\*.obj \ - ..\src\amd\*.obj \ - ..\src\bflib\*.obj \ - ..\src\cglib\*.obj \ - ..\src\colamd\*.obj \ - ..\src\env\*.obj \ - ..\src\minisat\*.obj \ - ..\src\misc\*.obj \ - ..\src\proxy\*.obj \ - ..\src\zlib\*.obj - -glpsol.exe: ..\examples\glpsol.obj glpk.lib - cl.exe $(CFLAGS) /Feglpsol.exe \ - ..\examples\glpsol.obj glpk.lib - -check: glpsol.exe - .\glpsol.exe --version - .\glpsol.exe --mps ..\examples\plan.mps - -## eof ## diff --git a/resources/3rdparty/glpk-4.53/w64/makefile_VC_DLL b/resources/3rdparty/glpk-4.53/w64/makefile_VC_DLL deleted file mode 100644 index 9eb7a6586..000000000 --- a/resources/3rdparty/glpk-4.53/w64/makefile_VC_DLL +++ /dev/null @@ -1,192 +0,0 @@ -## Build GLPK DLL with Microsoft Visual Studio Express ## - -CFLAGS = \ -/I. \ -/I..\src \ -/I..\src\amd \ -/I..\src\bflib \ -/I..\src\cglib \ -/I..\src\colamd \ -/I..\src\env \ -/I..\src\minisat \ -/I..\src\misc \ -/I..\src\proxy \ -/I..\src\zlib \ -/DHAVE_CONFIG_H=1 \ -/D_CRT_SECURE_NO_WARNINGS=1 \ -/nologo \ -/W3 \ -/O2 - -OBJSET = \ -..\src\avl.obj \ -..\src\bfd.obj \ -..\src\bfx.obj \ -..\src\glpapi01.obj \ -..\src\glpapi02.obj \ -..\src\glpapi03.obj \ -..\src\glpapi04.obj \ -..\src\glpapi05.obj \ -..\src\glpapi06.obj \ -..\src\glpapi07.obj \ -..\src\glpapi08.obj \ -..\src\glpapi09.obj \ -..\src\glpapi10.obj \ -..\src\glpapi11.obj \ -..\src\glpapi12.obj \ -..\src\glpapi13.obj \ -..\src\glpapi14.obj \ -..\src\glpapi15.obj \ -..\src\glpapi16.obj \ -..\src\glpapi17.obj \ -..\src\glpapi18.obj \ -..\src\glpapi19.obj \ -..\src\glpapi20.obj \ -..\src\glpapi21.obj \ -..\src\glpcpx.obj \ -..\src\glpdmx.obj \ -..\src\glpgmp.obj \ -..\src\glphbm.obj \ -..\src\glpini01.obj \ -..\src\glpini02.obj \ -..\src\glpios01.obj \ -..\src\glpios02.obj \ -..\src\glpios03.obj \ -..\src\glpios04.obj \ -..\src\glpios05.obj \ -..\src\glpios06.obj \ -..\src\glpios07.obj \ -..\src\glpios08.obj \ -..\src\glpios09.obj \ -..\src\glpios10.obj \ -..\src\glpios11.obj \ -..\src\glpios12.obj \ -..\src\glpipm.obj \ -..\src\glplpf.obj \ -..\src\glpmat.obj \ -..\src\glpmpl01.obj \ -..\src\glpmpl02.obj \ -..\src\glpmpl03.obj \ -..\src\glpmpl04.obj \ -..\src\glpmpl05.obj \ -..\src\glpmpl06.obj \ -..\src\glpmps.obj \ -..\src\glpnet03.obj \ -..\src\glpnet04.obj \ -..\src\glpnet05.obj \ -..\src\glpnpp01.obj \ -..\src\glpnpp02.obj \ -..\src\glpnpp03.obj \ -..\src\glpnpp04.obj \ -..\src\glpnpp05.obj \ -..\src\glpnpp06.obj \ -..\src\glprgr.obj \ -..\src\glpscl.obj \ -..\src\glpsdf.obj \ -..\src\glpspm.obj \ -..\src\glpspx01.obj \ -..\src\glpspx02.obj \ -..\src\glpsql.obj \ -..\src\glpssx01.obj \ -..\src\glpssx02.obj \ -..\src\glptsp.obj \ -..\src\lux.obj \ -..\src\amd\amd_1.obj \ -..\src\amd\amd_2.obj \ -..\src\amd\amd_aat.obj \ -..\src\amd\amd_control.obj \ -..\src\amd\amd_defaults.obj \ -..\src\amd\amd_dump.obj \ -..\src\amd\amd_info.obj \ -..\src\amd\amd_order.obj \ -..\src\amd\amd_post_tree.obj \ -..\src\amd\amd_postorder.obj \ -..\src\amd\amd_preprocess.obj \ -..\src\amd\amd_valid.obj \ -..\src\bflib\fhv.obj \ -..\src\bflib\fhvint.obj \ -..\src\bflib\ifu.obj \ -..\src\bflib\luf.obj \ -..\src\bflib\lufint.obj \ -..\src\bflib\sgf.obj \ -..\src\bflib\sva.obj \ -..\src\cglib\cfg.obj \ -..\src\cglib\cfg1.obj \ -..\src\colamd\colamd.obj \ -..\src\env\alloc.obj \ -..\src\env\dlsup.obj \ -..\src\env\env.obj \ -..\src\env\error.obj \ -..\src\env\stdout.obj \ -..\src\env\stream.obj \ -..\src\env\time.obj \ -..\src\env\tls.obj \ -..\src\minisat\minisat.obj \ -..\src\misc\bignum.obj \ -..\src\misc\dmp.obj \ -..\src\misc\ffalg.obj \ -..\src\misc\fp2rat.obj \ -..\src\misc\gcd.obj \ -..\src\misc\jd.obj \ -..\src\misc\keller.obj \ -..\src\misc\mc13d.obj \ -..\src\misc\mc21a.obj \ -..\src\misc\okalg.obj \ -..\src\misc\qmd.obj \ -..\src\misc\relax4.obj \ -..\src\misc\rng.obj \ -..\src\misc\rng1.obj \ -..\src\misc\round2n.obj \ -..\src\misc\str2int.obj \ -..\src\misc\str2num.obj \ -..\src\misc\strspx.obj \ -..\src\misc\strtrim.obj \ -..\src\misc\triang.obj \ -..\src\misc\wclique.obj \ -..\src\misc\wclique1.obj \ -..\src\proxy\proxy.obj \ -..\src\proxy\proxy1.obj \ -..\src\zlib\adler32.obj \ -..\src\zlib\compress.obj \ -..\src\zlib\crc32.obj \ -..\src\zlib\deflate.obj \ -..\src\zlib\gzclose.obj \ -..\src\zlib\gzlib.obj \ -..\src\zlib\gzread.obj \ -..\src\zlib\gzwrite.obj \ -..\src\zlib\inffast.obj \ -..\src\zlib\inflate.obj \ -..\src\zlib\inftrees.obj \ -..\src\zlib\trees.obj \ -..\src\zlib\uncompr.obj \ -..\src\zlib\zio.obj \ -..\src\zlib\zutil.obj - -.c.obj: - cl.exe $(CFLAGS) /Fo$*.obj /c $*.c - -all: glpk_4_53.dll glpsol.exe - -glpk_4_53.dll: $(OBJSET) - cl.exe $(CFLAGS) /LD /Feglpk_4_53.dll \ - ..\src\*.obj \ - ..\src\amd\*.obj \ - ..\src\bflib\*.obj \ - ..\src\cglib\*.obj \ - ..\src\colamd\*.obj \ - ..\src\env\*.obj \ - ..\src\minisat\*.obj \ - ..\src\misc\*.obj \ - ..\src\proxy\*.obj \ - ..\src\zlib\*.obj \ - glpk_4_53.def - -glpsol.exe: ..\examples\glpsol.obj glpk_4_53.dll - cl.exe $(CFLAGS) /Feglpsol.exe \ - ..\examples\glpsol.obj glpk_4_53.lib - -check: glpsol.exe - .\glpsol.exe --version - .\glpsol.exe --mps ..\examples\plan.mps - -## eof ## diff --git a/resources/3rdparty/glpk-4.53/w64/readme.txt b/resources/3rdparty/glpk-4.53/w64/readme.txt deleted file mode 100644 index d5742d964..000000000 --- a/resources/3rdparty/glpk-4.53/w64/readme.txt +++ /dev/null @@ -1,24 +0,0 @@ -This directory contains batch files and other stuff which you can use -to build GLPK for 64-bit Windows with the native C/C++ compilers. - -Before running the batch file do the following: - -1. Make sure that you have installed the compiler you are going to use - to build GLPK. - -2. Look into corresponding batch file (just right-click it and choose - 'Edit' in the popup menu; DO NOT choose 'Open'). Make sure that HOME - variable specifies correct path to the compiler directory; if not, - make necessary changes. - -To run the batch file just double-click it and wait a bit while the -Make utility does its job. The message 'OPTIMAL SOLUTION FOUND' in the -MS-DOS window means that all is OK. If you do not see it, something is -wrong. - -Once GLPK has been successfully built, there must appear two files in -this directory: - -glpk.lib, which is the GLPK object library, and - -glpsol.exe, which is the stand-alone GLPK LP/MIP solver. From 0de91e0284c618f032e1996c241967951a49d631 Mon Sep 17 00:00:00 2001 From: sjunges Date: Fri, 12 Feb 2016 18:23:26 +0100 Subject: [PATCH 3/3] disable warnings for glpk build Former-commit-id: e2a86ed18dec07586771c013e566608284812c6d --- resources/3rdparty/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/3rdparty/CMakeLists.txt b/resources/3rdparty/CMakeLists.txt index 4cc396d80..cf7053498 100644 --- a/resources/3rdparty/CMakeLists.txt +++ b/resources/3rdparty/CMakeLists.txt @@ -14,7 +14,7 @@ ExternalProject_Add( PREFIX ${CMAKE_CURRENT_BINARY_DIR}/glpk-4.57 SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/glpk-4.57 CONFIGURE_COMMAND CC=${CMAKE_C_COMPILER} ${CMAKE_CURRENT_SOURCE_DIR}/glpk-4.57/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/glpk-4.57 - BUILD_COMMAND make + BUILD_COMMAND make "CFLAGS=-O2 -w" INSTALL_COMMAND make install BUILD_IN_SOURCE 0 )

    Ecp|TkpA-Qy9WCwnEAHA$&FCb4 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 b3UhQ}a&&ldWo8OAH#9XfI0_{tMNdWw_kIva literal 0 HcmV?d00001 diff --git a/resources/3rdparty/glpk-4.57/doc/glpk.tex b/resources/3rdparty/glpk-4.57/doc/glpk.tex new file mode 100644 index 000000000..b5f88c023 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/glpk.tex @@ -0,0 +1,168 @@ +%* glpk.tex *% + +%*********************************************************************** +% This code is part of GLPK (GNU Linear Programming Kit). +% +% Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +% 2009, 2010, 2011, 2013, 2014, 2015 Andrew Makhorin, Department for +% Applied Informatics, Moscow Aviation Institute, Moscow, Russia. All +% rights reserved. E-mail: . +% +% GLPK is free software: you can redistribute it and/or modify it +% under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% GLPK is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +% License for more details. +% +% You should have received a copy of the GNU General Public License +% along with GLPK. If not, see . +%*********************************************************************** + +\documentclass[11pt]{report} +\usepackage{amssymb} +\usepackage[dvipdfm,linktocpage,colorlinks,linkcolor=blue, +urlcolor=blue]{hyperref} +\usepackage{indentfirst} +\usepackage{lscape} +\usepackage[all]{xy} + +\setlength{\textwidth}{6.5in} +\setlength{\textheight}{8.5in} +\setlength{\oddsidemargin}{0in} +\setlength{\topmargin}{0in} +\setlength{\headheight}{0in} +\setlength{\headsep}{0in} +\setlength{\footskip}{0.5in} +\setlength{\parindent}{16pt} +\setlength{\parskip}{5pt} +\setlength{\topsep}{0pt} +\setlength{\partopsep}{0pt} +\setlength{\itemsep}{\parskip} +\setlength{\parsep}{0pt} +\setlength{\leftmargini}{\parindent} +\renewcommand{\labelitemi}{---} + +\def\para#1{\noindent{\bf#1}} +\def\synopsis{\para{Synopsis}} +\def\description{\para{Description}} +\def\note{\para{Note}} +\def\returns{\para{Returns}} + +\renewcommand\contentsname{\sf\bfseries Contents} +\renewcommand\chaptername{\sf\bfseries Chapter} +\renewcommand\appendixname{\sf\bfseries Appendix} + +\newenvironment{retlist} +{ \def\arraystretch{1.5} + \noindent + \begin{tabular}{@{}p{1in}@{}p{5.5in}@{}} +} +{\end{tabular}} + +\begin{document} + +\thispagestyle{empty} + +\begin{center} + +\vspace*{1.5in} + +\begin{huge} +\sf\bfseries GNU Linear Programming Kit +\end{huge} + +\vspace{0.5in} + +\begin{LARGE} +\sf Reference Manual +\end{LARGE} + +\vspace{0.5in} + +\begin{LARGE} +\sf for GLPK Version 4.57 +\end{LARGE} + +\vspace{0.5in} +\begin{Large} +\sf (DRAFT, November 2015) +\end{Large} +\end{center} + +\newpage + +\vspace*{1in} + +\vfill + +\noindent +The GLPK package is part of the GNU Project released under the aegis of +GNU. + +\noindent +Copyright \copyright{} 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, +2008, 2009, 2010, 2011, 2013, 2014, 2015 Andrew Makhorin, Department +for Applied Informatics, Moscow Aviation Institute, Moscow, Russia. All +rights reserved. + +\noindent +Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +02110-1301, USA. + +\noindent +Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + +\noindent +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that +the entire resulting derived work is distributed under the terms of +a permission notice identical to this one. + +\noindent +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +{\setlength{\parskip}{0pt} +\tableofcontents +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\include{glpk01} + +\include{glpk02} + +\include{glpk03} + +\include{glpk04} + +\include{glpk05} + +\include{glpk06} + +\appendix + +\include{glpk07} + +\include{glpk08} + +\include{glpk09} + +\include{glpk10} + +\include{glpk11} + +\include{glpk12} + +\end{document} diff --git a/resources/3rdparty/glpk-4.57/doc/glpk01.tex b/resources/3rdparty/glpk-4.57/doc/glpk01.tex new file mode 100644 index 000000000..29ed67cce --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/glpk01.tex @@ -0,0 +1,343 @@ +%* glpk01.tex *% + +\chapter{Introduction} + +GLPK (\underline{G}NU \underline{L}inear \underline{P}rogramming +\underline{K}it) is a set of routines written in the ANSI C programming +language and organized in the form of a callable library. It is +intended for solving linear programming (LP), mixed integer programming +(MIP), and other related problems. + +\section{LP problem} +\label{seclp} + +GLPK assumes the following formulation of {\it linear programming (LP)} +problem: + +\medskip\noindent +\hspace{.5in} minimize (or maximize) +$$z = c_1x_{m+1} + c_2x_{m+2} + \dots + c_nx_{m+n} + c_0 \eqno (1.1)$$ +\hspace{.5in} subject to linear constraints +$$ +\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r} +x_1&=&a_{11}x_{m+1}&+&a_{12}x_{m+2}&+ \dots +&a_{1n}x_{m+n} \\ +x_2&=&a_{21}x_{m+1}&+&a_{22}x_{m+2}&+ \dots +&a_{2n}x_{m+n} \\ +\multicolumn{7}{c} +{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .} \\ +x_m&=&a_{m1}x_{m+1}&+&a_{m2}x_{m+2}&+ \dots +&a_{mn}x_{m+n} \\ +\end{array} \eqno (1.2) +$$ +\hspace{.5in} and bounds of variables +$$ +\begin{array}{r@{\:}c@{\:}c@{\:}c@{\:}l} +l_1&\leq&x_1&\leq&u_1 \\ +l_2&\leq&x_2&\leq&u_2 \\ +\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .}\\ +l_{m+n}&\leq&x_{m+n}&\leq&u_{m+n} \\ +\end{array} \eqno (1.3) +$$ + +\medskip\noindent +where: $x_1, x_2, \dots, x_m$ are auxiliary variables; +$x_{m+1}, x_{m+2}, \dots, x_{m+n}$ are structural variables; +$z$ is the objective function; +$c_1, c_2, \dots, c_n$ are objective coefficients; +$c_0$ is the constant term (``shift'') of the objective function; +$a_{11}, a_{12}, \dots, a_{mn}$ are constraint coefficients; +$l_1, l_2, \dots, l_{m+n}$ are lower bounds of variables; +$u_1, u_2, \dots, u_{m+n}$ are upper bounds of variables. + +Auxiliary variables are also called {\it rows}, because they correspond +to rows of the constraint matrix (i.e. a matrix built of the constraint +coefficients). Similarly, structural variables are also called +{\it columns}, because they correspond to columns of the constraint +matrix. + +Bounds of variables can be finite as well as infinite. Besides, lower +and upper bounds can be equal to each other. Thus, the following types +of variables are possible: + +\begin{center} +\begin{tabular}{r@{}c@{}ll} +\multicolumn{3}{c}{Bounds of variable} & Type of variable \\ +\hline +$-\infty <$ &$\ x_k\ $& $< +\infty$ & Free (unbounded) variable \\ +$l_k \leq$ &$\ x_k\ $& $< +\infty$ & Variable with lower bound \\ +$-\infty <$ &$\ x_k\ $& $\leq u_k$ & Variable with upper bound \\ +$l_k \leq$ &$\ x_k\ $& $\leq u_k$ & Double-bounded variable \\ +$l_k =$ &$\ x_k\ $& $= u_k$ & Fixed variable \\ +\end{tabular} +\end{center} + +\noindent +Note that the types of variables shown above are applicable to +structural as well as to auxiliary variables. + +To solve the LP problem (1.1)---(1.3) is to find such values of all +structural and auxiliary variables, which: + +\vspace*{-10pt} + +\begin{itemize}\setlength{\itemsep}{0pt} +\item satisfy to all the linear constraints (1.2), and + +\item are within their bounds (1.3), and + +\item provide smallest (in case of minimization) or largest (in case of +maximization) value of the objective function (1.1). +\end{itemize} + +\section{MIP problem} + +{\it Mixed integer linear programming (MIP)} problem is an LP problem +in which some variables are additionally required to be integer. + +GLPK assumes that MIP problem has the same formulation as ordinary +(pure) LP problem (1.1)---(1.3), i.e. includes auxiliary and structural +variables, which may have lower and/or upper bounds. However, in case +of MIP problem some variables may be required to be integer. This +additional constraint means that a value of each {\it integer variable} +must be only integer number. (Should note that GLPK allows only +structural variables to be of integer kind.) + +\section{Using the package} + +\subsection{Brief example} + +In order to understand what GLPK is from the user's standpoint, +consider the following simple LP problem: + +\medskip + +\noindent +\hspace{.5in} maximize +$$z = 10 x_1 + 6 x_2 + 4 x_3$$ +\hspace{.5in} subject to +$$ +\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r} +x_1 &+&x_2 &+&x_3 &\leq 100 \\ +10 x_1 &+& 4 x_2 & +&5 x_3 & \leq 600 \\ +2 x_1 &+& 2 x_2 & +& 6 x_3 & \leq 300 \\ +\end{array} +$$ +\hspace{.5in} where all variables are non-negative +$$x_1 \geq 0, \ x_2 \geq 0, \ x_3 \geq 0$$ + +At first, this LP problem should be transformed to the standard form +(1.1)---(1.3). This can be easily done by introducing auxiliary +variables, by one for each original inequality constraint. Thus, the +problem can be reformulated as follows: + +\medskip + +\noindent +\hspace{.5in} maximize +$$z = 10 x_1 + 6 x_2 + 4 x_3$$ +\hspace{.5in} subject to +$$ +\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r} +p& = &x_1 &+&x_2 &+&x_3 \\ +q& = &10 x_1 &+& 4 x_2 &+& 5 x_3 \\ +r& = &2 x_1 &+& 2 x_2 &+& 6 x_3 \\ +\end{array} +$$ +\hspace{.5in} and bounds of variables +$$ +\begin{array}{ccc} +\nonumber -\infty < p \leq 100 && 0 \leq x_1 < +\infty \\ +\nonumber -\infty < q \leq 600 && 0 \leq x_2 < +\infty \\ +\nonumber -\infty < r \leq 300 && 0 \leq x_3 < +\infty \\ +\end{array} +$$ + +\medskip + +where $p, q, r$ are auxiliary variables (rows), and $x_1, x_2, x_3$ are +structural variables (columns). + +The example C program shown below uses GLPK API routines in order to +solve this LP problem.\footnote{If you just need to solve LP or MIP +instance, you may write it in MPS or CPLEX LP format and then use the +GLPK stand-alone solver to obtain a solution. This is much less +time-consuming than programming in C with GLPK API routines.} + +\begin{footnotesize} +\begin{verbatim} +/* sample.c */ + +#include +#include +#include + +int main(void) +{ glp_prob *lp; + int ia[1+1000], ja[1+1000]; + double ar[1+1000], z, x1, x2, x3; +s1: lp = glp_create_prob(); +s2: glp_set_prob_name(lp, "sample"); +s3: glp_set_obj_dir(lp, GLP_MAX); +s4: glp_add_rows(lp, 3); +s5: glp_set_row_name(lp, 1, "p"); +s6: glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 100.0); +s7: glp_set_row_name(lp, 2, "q"); +s8: glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 600.0); +s9: glp_set_row_name(lp, 3, "r"); +s10: glp_set_row_bnds(lp, 3, GLP_UP, 0.0, 300.0); +s11: glp_add_cols(lp, 3); +s12: glp_set_col_name(lp, 1, "x1"); +s13: glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0); +s14: glp_set_obj_coef(lp, 1, 10.0); +s15: glp_set_col_name(lp, 2, "x2"); +s16: glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0); +s17: glp_set_obj_coef(lp, 2, 6.0); +s18: glp_set_col_name(lp, 3, "x3"); +s19: glp_set_col_bnds(lp, 3, GLP_LO, 0.0, 0.0); +s20: glp_set_obj_coef(lp, 3, 4.0); +s21: ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */ +s22: ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */ +s23: ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */ +s24: ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */ +s25: ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */ +s26: ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */ +s27: ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */ +s28: ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */ +s29: ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */ +s30: glp_load_matrix(lp, 9, ia, ja, ar); +s31: glp_simplex(lp, NULL); +s32: z = glp_get_obj_val(lp); +s33: x1 = glp_get_col_prim(lp, 1); +s34: x2 = glp_get_col_prim(lp, 2); +s35: x3 = glp_get_col_prim(lp, 3); +s36: printf("\nz = %g; x1 = %g; x2 = %g; x3 = %g\n", + z, x1, x2, x3); +s37: glp_delete_prob(lp); + return 0; +} + +/* eof */ +\end{verbatim} +\end{footnotesize} + +The statement \verb|s1| creates a problem object. Being created the +object is initially empty. The statement \verb|s2| assigns a symbolic +name to the problem object. + +The statement \verb|s3| calls the routine \verb|glp_set_obj_dir| in +order to set the optimization direction flag, where \verb|GLP_MAX| +means maximization. + +The statement \verb|s4| adds three rows to the problem object. + +The statement \verb|s5| assigns the symbolic name `\verb|p|' to the +first row, and the statement \verb|s6| sets the type and bounds of the +first row, where \verb|GLP_UP| means that the row has an upper bound. +The statements \verb|s7|, \verb|s8|, \verb|s9|, \verb|s10| are used in +the same way in order to assign the symbolic names `\verb|q|' and +`\verb|r|' to the second and third rows and set their types and bounds. + +The statement \verb|s11| adds three columns to the problem object. + +The statement \verb|s12| assigns the symbolic name `\verb|x1|' to the +first column, the statement \verb|s13| sets the type and bounds of the +first column, where \verb|GLP_LO| means that the column has an lower +bound, and the statement \verb|s14| sets the objective coefficient for +the first column. The statements \verb|s15|---\verb|s20| are used in +the same way in order to assign the symbolic names `\verb|x2|' and +`\verb|x3|' to the second and third columns and set their types, +bounds, and objective coefficients. + +The statements \verb|s21|---\verb|s29| prepare non-zero elements of the +constraint matrix (i.e. constraint coefficients). Row indices of each +element are stored in the array \verb|ia|, column indices are stored in +the array \verb|ja|, and numerical values of corresponding elements are +stored in the array \verb|ar|. Then the statement \verb|s30| calls +the routine \verb|glp_load_matrix|, which loads information from these +three arrays into the problem object. + +Now all data have been entered into the problem object, and therefore +the statement \verb|s31| calls the routine \verb|glp_simplex|, which is +a driver to the simplex method, in order to solve the LP problem. This +routine finds an optimal solution and stores all relevant information +back into the problem object. + +The statement \verb|s32| obtains a computed value of the objective +function, and the statements \verb|s33|---\verb|s35| obtain computed +values of structural variables (columns), which correspond to the +optimal basic solution found by the solver. + +The statement \verb|s36| writes the optimal solution to the standard +output. The printout may look like follows: + +\begin{footnotesize} +\begin{verbatim} +* 0: objval = 0.000000000e+00 infeas = 0.000000000e+00 (0) +* 2: objval = 7.333333333e+02 infeas = 0.000000000e+00 (0) +OPTIMAL SOLUTION FOUND + +z = 733.333; x1 = 33.3333; x2 = 66.6667; x3 = 0 +\end{verbatim} +\end{footnotesize} + +Finally, the statement \verb|s37| calls the routine +\verb|glp_delete_prob|, which frees all the memory allocated to the +problem object. + +\subsection{Compiling} + +The GLPK package has the only header file \verb|glpk.h|, which should +be available on compiling a C (or C++) program using GLPK API routines. + +If the header file is installed in the default location +\verb|/usr/local/include|, the following typical command may be used to +compile, say, the example C program described above with the GNU C +compiler: + +\begin{verbatim} + $ gcc -c sample.c +\end{verbatim} + +If \verb|glpk.h| is not in the default location, the corresponding +directory containing it should be made known to the C compiler through +\verb|-I| option, for example: + +\begin{verbatim} + $ gcc -I/foo/bar/glpk-4.15/include -c sample.c +\end{verbatim} + +In any case the compilation results in an object file \verb|sample.o|. + +\subsection{Linking} + +The GLPK library is a single file \verb|libglpk.a|. (On systems which +support shared libraries there may be also a shared version of the +library \verb|libglpk.so|.) + +If the library is installed in the default +location \verb|/usr/local/lib|, the following typical command may be +used to link, say, the example C program described above against with +the library: + +\begin{verbatim} + $ gcc sample.o -lglpk -lm +\end{verbatim} + +If the GLPK library is not in the default location, the corresponding +directory containing it should be made known to the linker through +\verb|-L| option, for example: + +\begin{verbatim} + $ gcc -L/foo/bar/glpk-4.15 sample.o -lglpk -lm +\end{verbatim} + +Depending on configuration of the package linking against with the GLPK +library may require optional libraries, in which case these libraries +should be also made known to the linker, for example: + +\begin{verbatim} + $ gcc sample.o -lglpk -lgmp -lm +\end{verbatim} + +For more details about configuration options of the GLPK package see +Appendix \ref{install}, page \pageref{install}. + +%* eof *% diff --git a/resources/3rdparty/glpk-4.57/doc/glpk02.tex b/resources/3rdparty/glpk-4.57/doc/glpk02.tex new file mode 100644 index 000000000..3fa6ef7f7 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/glpk02.tex @@ -0,0 +1,3470 @@ +%* glpk02.tex *% + +\chapter{Basic API Routines} + +\section{General conventions} + +\subsection{Library header} + +All GLPK API data types and routines are defined in the header file +\verb|glpk.h|. It should be included in all source files which use +GLPK API, either directly or indirectly through some other header file +as follows: + +\begin{verbatim} + #include +\end{verbatim} + +\subsection{Error handling} + +If some GLPK API routine detects erroneous or incorrect data passed by +the application program, it writes appropriate diagnostic messages to +the terminal and then abnormally terminates the application program. +In most practical cases this allows to simplify programming by avoiding +numerous checks of return codes. Thus, in order to prevent crashing the +application program should check all data, which are suspected to be +incorrect, before calling GLPK API routines. + +Should note that this kind of error handling is used only in cases of +incorrect data passed by the application program. If, for example, the +application program calls some GLPK API routine to read data from an +input file and these data are incorrect, the GLPK API routine reports +about error in the usual way by means of the return code. + +\subsection{Thread safety} + +The standard version of GLPK API is {\it not} thread safe and therefore +should not be used in multi-threaded programs. + +\subsection{Array indexing} + +Normally all GLPK API routines start array indexing from 1, not from 0 +(except the specially stipulated cases). This means, for example, that +if some vector $x$ of the length $n$ is passed as an array to some GLPK +API routine, the latter expects vector components to be placed in +locations \verb|x[1]|, \verb|x[2]|, \dots, \verb|x[n]|, and the +location \verb|x[0]| normally is not used. + +To avoid indexing errors it is most convenient and most reliable to +declare the array \verb|x| as follows: + +\begin{verbatim} + double x[1+n]; +\end{verbatim} + +\noindent +or to allocate it as follows: + +\begin{verbatim} + double *x; + . . . + x = calloc(1+n, sizeof(double)); + . . . +\end{verbatim} + +\noindent +In both cases one extra location \verb|x[0]| is reserved that allows +passing the array to GLPK routines in a usual way. + +\section{Problem object} + +All GLPK API routines deal with so called {\it problem object}, which +is a program object of type \verb|glp_prob| and intended to represent +a particular LP or MIP instance. + +The type \verb|glp_prob| is a data structure declared in the header +file \verb|glpk.h| as follows: + +\begin{verbatim} + typedef struct glp_prob glp_prob; +\end{verbatim} + +Problem objects (i.e. program objects of the \verb|glp_prob| type) are +allocated and managed internally by the GLPK API routines. The +application program should never use any members of the \verb|glp_prob| +structure directly and should deal only with pointers to these objects +(that is, \verb|glp_prob *| values). + +The problem object consists of the following segments: + +\vspace*{-8pt} + +\begin{itemize}\setlength{\itemsep}{0pt} +\item problem segment, + +\item basis segment, + +\item interior-point segment, and + +\item MIP segment. +\end{itemize} + +\subsection{Problem segment} + +The {\it problem segment} contains original LP/MIP data, which +corresponds to the problem formulation (1.1)---(1.3) (see Section +\ref{seclp}, page \pageref{seclp}). This segment includes the following +components: + +\vspace*{-8pt} + +\begin{itemize}\setlength{\itemsep}{0pt} +\item rows (auxiliary variables), + +\item columns (structural variables), + +\item objective function, and + +\item constraint matrix. +\end{itemize} + +\vspace*{-7pt} + +Rows and columns have the same set of the following attributes: + +\vspace*{-7pt} + +\begin{itemize}\setlength{\itemsep}{0pt} +\item ordinal number, + +\item symbolic name (1 up to 255 arbitrary graphic characters), + +\item type (free, lower bound, upper bound, double bound, fixed), + +\item numerical values of lower and upper bounds, + +\item scale factor. +\end{itemize} + +\vspace*{-7pt} + +{\it Ordinal numbers} are intended for referencing rows and columns. +Row ordinal numbers are integers $1, 2, \dots, m$, and column ordinal +numbers are integers $1, 2, \dots, n$, where $m$ and $n$ are, +respectively, the current number of rows and columns in the problem +object. + +{\it Symbolic names} are intended for informational purposes. They also +can be used for referencing rows and columns. + +{\it Types and bounds} of rows (auxiliary variables) and columns +(structural variables) are explained above (see Section \ref{seclp}, +page \pageref{seclp}). + +{\it Scale factors} are used internally for scaling rows and columns of +the constraint matrix. + +Information about the {\it objective function} includes numerical +values of objective coefficients and a flag, which defines the +optimization direction (i.e. minimization or maximization). + +The {\it constraint matrix} is a $m \times n$ rectangular matrix built +of constraint coefficients $a_{ij}$, which defines the system of linear +constraints (1.2) (see Section \ref{seclp}, page \pageref{seclp}). This +matrix is stored in the problem object in both row-wise and column-wise +sparse formats. + +Once the problem object has been created, the application program can +access and modify any components of the problem segment in arbitrary +order. + +\subsection{Basis segment} + +The {\it basis segment} of the problem object keeps information related +to the current basic solution. It includes: + +\vspace*{-8pt} + +\begin{itemize}\setlength{\itemsep}{0pt} +\item row and column statuses, + +\item basic solution statuses, + +\item factorization of the current basis matrix, and + +\item basic solution components. +\end{itemize} + +\vspace*{-8pt} + +The {\it row and column statuses} define which rows and columns are +basic and which are non-basic. These statuses may be assigned either by +the application program of by some API routines. Note that these +statuses are always defined independently on whether the corresponding +basis is valid or not. + +The {\it basic solution statuses} include the {\it primal status} and +the {\it dual status}, which are set by the simplex-based solver once +the problem has been solved. The primal status shows whether a primal +basic solution is feasible, infeasible, or undefined. The dual status +shows the same for a dual basic solution. + +The {\it factorization of the basis matrix} is some factorized form +(like {\it LU}-factorization) of the current basis matrix (defined by +the current row and column statuses). The factorization is used by +simplex-based solvers and kept when the solver terminates the search. +This feature allows efficiently reoptimizing the problem after some +modifications (for example, after changing some bounds or objective +coefficients). It also allows performing the post-optimal analysis (for +example, computing components of the simplex table, etc.). + +The {\it basic solution components} include primal and dual values of +all auxiliary and structural variables for the most recently obtained +basic solution. + +\subsection{Interior-point segment} + +The {\it interior-point segment} contains interior-point solution +components, which include the solution status, and primal and dual +values of all auxiliary and structural variables. + +\subsection{MIP segment} + +The {\it MIP segment} is used only for MIP problems. This segment +includes: + +\vspace*{-8pt} + +\begin{itemize}\setlength{\itemsep}{0pt} +\item column kinds, + +\item MIP solution status, and + +\item MIP solution components. +\end{itemize} + +\vspace*{-8pt} + +The {\it column kinds} define which columns (i.e. structural variables) +are integer and which are continuous. + +The {\it MIP solution status} is set by the MIP solver and shows whether +a MIP solution is integer optimal, integer feasible (non-optimal), or +undefined. + +The {\it MIP solution components} are computed by the MIP solver and +include primal values of all auxiliary and structural variables for the +most recently obtained MIP solution. + +Note that in case of MIP problem the basis segment corresponds to +the optimal solution of LP relaxation, which is also available to the +application program. + +Currently the search tree is not kept in the MIP segment, so if the +search has been terminated, it cannot be continued. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Problem creating and modifying routines} + +\subsection{glp\_create\_prob --- create problem object} + +\synopsis + +\begin{verbatim} + glp_prob *glp_create_prob(void); +\end{verbatim} + +\description + +The routine \verb|glp_create_prob| creates a new problem object, which +initially is ``empty'', i.e. has no rows and columns. + +\returns + +The routine returns a pointer to the created object, which should be +used in any subsequent operations on this object. + +\subsection{glp\_set\_prob\_name --- assign (change) problem name} + +\synopsis + +\begin{verbatim} + void glp_set_prob_name(glp_prob *P, const char *name); +\end{verbatim} + +\description + +The routine \verb|glp_set_prob_name| assigns a given symbolic +\verb|name| (1 up to 255 characters) to the specified problem object. + +If the parameter \verb|name| is \verb|NULL| or empty string, the +routine erases an existing symbolic name of the problem object. + +\subsection{glp\_set\_obj\_name --- assign (change) objective function +name} + +\synopsis + +\begin{verbatim} + void glp_set_obj_name(glp_prob *P, const char *name); +\end{verbatim} + +\description + +The routine \verb|glp_set_obj_name| assigns a given symbolic +\verb|name| (1 up to 255 characters) to the objective function of the +specified problem object. + +If the parameter \verb|name| is \verb|NULL| or empty string, the +routine erases an existing symbolic name of the objective function. + +\newpage + +\subsection{glp\_set\_obj\_dir --- set (change) optimization direction +flag} + +\synopsis + +\begin{verbatim} + void glp_set_obj_dir(glp_prob *P, int dir); +\end{verbatim} + +\description + +The routine \verb|glp_set_obj_dir| sets (changes) the optimization +direction flag (i.e. ``sense'' of the objective function) as specified +by the parameter \verb|dir|: + +\verb|GLP_MIN| means minimization; + +\verb|GLP_MAX| means maximization. + +\noindent +(Note that by default the problem is minimization.) + +\subsection{glp\_add\_rows --- add new rows to problem object} + +\synopsis + +\begin{verbatim} + int glp_add_rows(glp_prob *P, int nrs); +\end{verbatim} + +\description + +The routine \verb|glp_add_rows| adds \verb|nrs| rows (constraints) to +the specified problem object. New rows are always added to the end of +the row list, so the ordinal numbers of existing rows are not changed. + +Being added each new row is initially free (unbounded) and has empty +list of the constraint coefficients. + +Each new row becomes a non-active (non-binding) constraint, i.e. the +corresponding auxiliary variable is marked as basic. + +If the basis factorization exists, adding row(s) invalidates it. + +\returns + +The routine \verb|glp_add_rows| returns the ordinal number of the first +new row added to the problem object. + +\subsection{glp\_add\_cols --- add new columns to problem object} + +\synopsis + +\begin{verbatim} + int glp_add_cols(glp_prob *P, int ncs); +\end{verbatim} + +\description + +The routine \verb|glp_add_cols| adds \verb|ncs| columns (structural +variables) to the specified problem object. New columns are always +added to the end of the column list, so the ordinal numbers of existing +columns are not changed. + +Being added each new column is initially fixed at zero and has empty +list of the constraint coefficients. + +Each new column is marked as non-basic, i.e. zero value of the +corresponding structural variable becomes an active (binding) bound. + +If the basis factorization exists, it remains valid. + +\returns + +The routine \verb|glp_add_cols| returns the ordinal number of the first +new column added to the problem object. + +\subsection{glp\_set\_row\_name --- assign (change) row name} + +\synopsis + +\begin{verbatim} + void glp_set_row_name(glp_prob *P, int i, const char *name); +\end{verbatim} + +\description + +The routine \verb|glp_set_row_name| assigns a given symbolic +\verb|name| (1 up to 255 characters) to \verb|i|-th row (auxiliary +variable) of the specified problem object. + +If the parameter \verb|name| is \verb|NULL| or empty string, the +routine erases an existing name of $i$-th row. + +\subsection{glp\_set\_col\_name --- assign (change) column name} + +\synopsis + +\begin{verbatim} + void glp_set_col_name(glp_prob *P, int j, const char *name); +\end{verbatim} + +\description + +The routine \verb|glp_set_col_name| assigns a given symbolic +\verb|name| (1 up to 255 characters) to \verb|j|-th column (structural +variable) of the specified problem object. + +If the parameter \verb|name| is \verb|NULL| or empty string, the +routine erases an existing name of $j$-th column. + +\subsection{glp\_set\_row\_bnds --- set (change) row bounds} + +\synopsis + +{\tt void glp\_set\_row\_bnds(glp\_prob *P, int i, int type, +double lb, double ub);} + +\description + +The routine \verb|glp_set_row_bnds| sets (changes) the type and bounds +of \verb|i|-th row (auxiliary variable) of the specified problem +object. + +The parameters \verb|type|, \verb|lb|, and \verb|ub| specify the type, +lower bound, and upper bound, respectively, as follows: + +\begin{center} +\begin{tabular}{cr@{}c@{}ll} +Type & \multicolumn{3}{c}{Bounds} & Comment \\ +\hline +\verb|GLP_FR| & $-\infty <$ &$\ x\ $& $< +\infty$ + & Free (unbounded) variable \\ +\verb|GLP_LO| & $lb \leq$ &$\ x\ $& $< +\infty$ + & Variable with lower bound \\ +\verb|GLP_UP| & $-\infty <$ &$\ x\ $& $\leq ub$ + & Variable with upper bound \\ +\verb|GLP_DB| & $lb \leq$ &$\ x\ $& $\leq ub$ + & Double-bounded variable \\ +\verb|GLP_FX| & $lb =$ &$\ x\ $& $= ub$ + & Fixed variable \\ +\end{tabular} +\end{center} + +\noindent +where $x$ is the auxiliary variable associated with $i$-th row. + +If the row has no lower bound, the parameter \verb|lb| is ignored. If +the row has no upper bound, the parameter \verb|ub| is ignored. If the +row is an equality constraint (i.e. the corresponding auxiliary +variable is of fixed type), only the parameter \verb|lb| is used while +the parameter \verb|ub| is ignored. + +Being added to the problem object each row is initially free, i.e. its +type is \verb|GLP_FR|. + +\subsection{glp\_set\_col\_bnds --- set (change) column bounds} + +\synopsis + +{\tt void glp\_set\_col\_bnds(glp\_prob *P, int j, int type, +double lb, double ub);} + +\description + +The routine \verb|glp_set_col_bnds| sets (changes) the type and bounds +of \verb|j|-th column (structural variable) of the specified problem +object. + +The parameters \verb|type|, \verb|lb|, and \verb|ub| specify the type, +lower bound, and upper bound, respectively, as follows: + +\begin{center} +\begin{tabular}{cr@{}c@{}ll} +Type & \multicolumn{3}{c}{Bounds} & Comment \\ +\hline +\verb|GLP_FR| & $-\infty <$ &$\ x\ $& $< +\infty$ + & Free (unbounded) variable \\ +\verb|GLP_LO| & $lb \leq$ &$\ x\ $& $< +\infty$ + & Variable with lower bound \\ +\verb|GLP_UP| & $-\infty <$ &$\ x\ $& $\leq ub$ + & Variable with upper bound \\ +\verb|GLP_DB| & $lb \leq$ &$\ x\ $& $\leq ub$ + & Double-bounded variable \\ +\verb|GLP_FX| & $lb =$ &$\ x\ $& $= ub$ + & Fixed variable \\ +\end{tabular} +\end{center} + +\noindent +where $x$ is the structural variable associated with $j$-th column. + +If the column has no lower bound, the parameter \verb|lb| is ignored. +If the column has no upper bound, the parameter \verb|ub| is ignored. +If the column is of fixed type, only the parameter \verb|lb| is used +while the parameter \verb|ub| is ignored. + +Being added to the problem object each column is initially fixed at +zero, i.e. its type is \verb|GLP_FX| and both bounds are 0. + +\newpage + +\subsection{glp\_set\_obj\_coef --- set (change) objective coefficient +or constant term} + +\synopsis + +\begin{verbatim} + void glp_set_obj_coef(glp_prob *P, int j, double coef); +\end{verbatim} + +\description + +The routine \verb|glp_set_obj_coef| sets (changes) the objective +coefficient at \verb|j|-th column (structural variable). A new value of +the objective coefficient is specified by the parameter \verb|coef|. + +If the parameter \verb|j| is 0, the routine sets (changes) the constant +term (``shift'') of the objective function. + +\subsection{glp\_set\_mat\_row --- set (replace) row of the constraint +matrix} + +\synopsis + +\begin{verbatim} + void glp_set_mat_row(glp_prob *P, int i, int len, const int ind[], + const double val[]); +\end{verbatim} + +\description + +The routine \verb|glp_set_mat_row| stores (replaces) the contents of +\verb|i|-th row of the constraint matrix of the specified problem +object. + +Column indices and numerical values of new row elements should be +placed in locations\linebreak \verb|ind[1]|, \dots, \verb|ind[len]| and +\verb|val[1]|, \dots, \verb|val[len]|, respectively, where +$0 \leq$ \verb|len| $\leq n$ is the new length of $i$-th row, $n$ is +the current number of columns in the problem object. Elements with +identical column indices are not allowed. Zero elements are allowed, +but they are not stored in the constraint matrix. + +If the parameter \verb|len| is 0, the parameters \verb|ind| and/or +\verb|val| can be specified as \verb|NULL|. + +\note + +If the basis factorization exists and changing the row changes +coefficients at basic column(s), the factorization is invalidated. + +\subsection{glp\_set\_mat\_col --- set (replace) column of the +constr\-aint matrix} + +\synopsis + +\begin{verbatim} + void glp_set_mat_col(glp_prob *P, int j, int len, const int ind[], + const double val[]); +\end{verbatim} + +\description + +The routine \verb|glp_set_mat_col| stores (replaces) the contents of +\verb|j|-th column of the constraint matrix of the specified problem +object. + +Row indices and numerical values of new column elements should be +placed in locations\linebreak \verb|ind[1]|, \dots, \verb|ind[len]| and +\verb|val[1]|, \dots, \verb|val[len]|, respectively, where +$0 \leq$ \verb|len| $\leq m$ is the new length of $j$-th column, $m$ is +the current number of rows in the problem object. Elements with +identical row indices are not allowed. Zero elements are allowed, but +they are not stored in the constraint matrix. + +If the parameter \verb|len| is 0, the parameters \verb|ind| and/or +\verb|val| can be specified as \verb|NULL|. + +\note + +If the basis factorization exists, changing the column corresponding +to a basic structural variable invalidates it. + +\subsection{glp\_load\_matrix --- load (replace) the whole constraint +matrix} + +\synopsis + +\begin{verbatim} + void glp_load_matrix(glp_prob *P, int ne, const int ia[], + const int ja[], const double ar[]); +\end{verbatim} + +\description + +The routine \verb|glp_load_matrix| loads the constraint matrix passed +in the arrays \verb|ia|, \verb|ja|, and \verb|ar| into the specified +problem object. Before loading the current contents of the constraint +matrix is destroyed. + +Constraint coefficients (elements of the constraint matrix) should be +specified as triplets (\verb|ia[k]|, \verb|ja[k]|, \verb|ar[k]|) for +$k=1,\dots,ne$, where \verb|ia[k]| is the row index, \verb|ja[k]| is +the column index, and \verb|ar[k]| is a numeric value of corresponding +constraint coefficient. The parameter \verb|ne| specifies the total +number of (non-zero) elements in the matrix to be loaded. Coefficients +with identical indices are not allowed. Zero coefficients are allowed, +however, they are not stored in the constraint matrix. + +If the parameter \verb|ne| is 0, the parameters \verb|ia|, \verb|ja|, +and/or \verb|ar| can be specified as \verb|NULL|. + +\note + +If the basis factorization exists, this operation invalidates it. + +\subsection{glp\_check\_dup --- check for duplicate elements in sparse +matrix} + +\synopsis + +{\tt int glp\_check\_dup(int m, int n, int ne, const int ia[], +const int ja[]);} + +\description + +The routine \verb|glp_check_dup checks| for duplicate elements (that +is, elements with identical indices) in a sparse matrix specified in +the coordinate format. + +The parameters $m$ and $n$ specifies, respectively, the number of rows +and columns in the matrix, $m\geq 0$, $n\geq 0$. + +The parameter {\it ne} specifies the number of (structurally) non-zero +elements in the matrix,\linebreak {\it ne} $\geq 0$. + +Elements of the matrix are specified as doublets $(ia[k],ja[k])$ for +$k=1,\dots,ne$, where $ia[k]$ is a row index, $ja[k]$ is a column +index. + +The routine \verb|glp_check_dup| can be used prior to a call to the +routine \verb|glp_load_matrix| to check that the constraint matrix to +be loaded has no duplicate elements. + +\returns + +\begin{retlist} +0& the matrix representation is correct;\\ +$-k$& indices $ia[k]$ or/and $ja[k]$ are out of range;\\ +$+k$& element $(ia[k],ja[k])$ is duplicate.\\ +\end{retlist} + +\subsection{glp\_sort\_matrix --- sort elements of the constraint +matrix} + +\synopsis + +\begin{verbatim} + void glp_sort_matrix(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_sort_matrix| sorts elements of the constraint +matrix by rebuilding its row and column linked lists. + +On exit from the routine the constraint matrix is not changed, however, +elements in the row linked lists become ordered by ascending column +indices, and the elements in the column linked lists become ordered by +ascending row indices. + +\subsection{glp\_del\_rows --- delete rows from problem object} + +\synopsis + +\begin{verbatim} + void glp_del_rows(glp_prob *P, int nrs, const int num[]); +\end{verbatim} + +\description + +The routine \verb|glp_del_rows| deletes rows from the specified problem +object. Ordinal numbers of rows to be deleted should be placed in +locations \verb|num[1]|, \dots, \verb|num[nrs]|, where ${\tt nrs}>0$. + +Note that deleting rows involves changing ordinal numbers of other +rows remaining in the problem object. New ordinal numbers of the +remaining rows are assigned under the assumption that the original +order of rows is not changed. Let, for example, before deletion there +be five rows $a$, $b$, $c$, $d$, $e$ with ordinal numbers 1, 2, 3, 4, +5, and let rows $b$ and $d$ have been deleted. Then after deletion the +remaining rows $a$, $c$, $e$ are assigned new oridinal numbers 1, 2, 3. + +If the basis factorization exists, deleting active (binding) rows, +i.e. whose auxiliary variables are marked as non-basic, invalidates it. + +\newpage + +\subsection{glp\_del\_cols --- delete columns from problem object} + +\synopsis + +\begin{verbatim} + void glp_del_cols(glp_prob *P, int ncs, const int num[]); +\end{verbatim} + +\description + +The routine \verb|glp_del_cols| deletes columns from the specified +problem object. Ordinal numbers of columns to be deleted should be +placed in locations \verb|num[1]|, \dots, \verb|num[ncs]|, where +${\tt ncs}>0$. + +Note that deleting columns involves changing ordinal numbers of other +columns remaining in\linebreak the problem object. New ordinal numbers +of the remaining columns are assigned under the assumption that the +original order of columns is not changed. Let, for example, before +deletion there be six columns $p$, $q$, $r$, $s$, $t$, $u$ with +ordinal numbers 1, 2, 3, 4, 5, 6, and let columns $p$, $q$, $s$ have +been deleted. Then after deletion the remaining columns $r$, $t$, $u$ +are assigned new ordinal numbers 1, 2, 3. + +If the basis factorization exists, deleting basic columns invalidates +it. + +\subsection{glp\_copy\_prob --- copy problem object content} + +\synopsis + +\begin{verbatim} + void glp_copy_prob(glp_prob *dest, glp_prob *prob, int names); +\end{verbatim} + +\description + +The routine \verb|glp_copy_prob| copies the content of the problem +object \verb|prob| to the problem object \verb|dest|. + +The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, +the routine also copies all symbolic names; otherwise, if it is +\verb|GLP_OFF|, no symbolic names are copied. + +\subsection{glp\_erase\_prob --- erase problem object content} + +\synopsis + +\begin{verbatim} + void glp_erase_prob(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_erase_prob| erases the content of the specified +problem object. The effect of this operation is the same as if the +problem object would be deleted with the routine \verb|glp_delete_prob| +and then created anew with the routine \verb|glp_create_prob|, with the +only exception that the pointer to the problem object remains valid. + +\newpage + +\subsection{glp\_delete\_prob --- delete problem object} + +\synopsis + +\begin{verbatim} + void glp_delete_prob(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_delete_prob| deletes a problem object, which the +parameter \verb|lp| points to, freeing all the memory allocated to this +object. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Problem retrieving routines} + +\subsection{glp\_get\_prob\_name --- retrieve problem name} + +\synopsis + +\begin{verbatim} + const char *glp_get_prob_name(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_prob_name| returns a pointer to an internal +buffer, which contains symbolic name of the problem. However, if the +problem has no assigned name, the routine returns \verb|NULL|. + +\subsection{glp\_get\_obj\_name --- retrieve objective function name} + +\synopsis + +\begin{verbatim} + const char *glp_get_obj_name(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_obj_name| returns a pointer to an internal +buffer, which contains symbolic name assigned to the objective +function. However, if the objective function has no assigned name, the +routine returns \verb|NULL|. + +\subsection{glp\_get\_obj\_dir --- retrieve optimization direction +flag} + +\synopsis + +\begin{verbatim} + int glp_get_obj_dir(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_obj_dir| returns the optimization direction +flag (i.e. ``sense'' of the objective function): + +\verb|GLP_MIN| means minimization; + +\verb|GLP_MAX| means maximization. + +\subsection{glp\_get\_num\_rows --- retrieve number of rows} + +\synopsis + +\begin{verbatim} + int glp_get_num_rows(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_num_rows| returns the current number of rows +in the specified problem object. + +\subsection{glp\_get\_num\_cols --- retrieve number of columns} + +\synopsis + +\begin{verbatim} + int glp_get_num_cols(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_num_cols| returns the current number of +columns in the specified problem object. + +\subsection{glp\_get\_row\_name --- retrieve row name} + +\synopsis + +\begin{verbatim} + const char *glp_get_row_name(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_name| returns a pointer to an internal +buffer, which contains a symbolic name assigned to \verb|i|-th row. +However, if the row has no assigned name, the routine returns +\verb|NULL|. + +\subsection{glp\_get\_col\_name --- retrieve column name} + +\synopsis + +\begin{verbatim} + const char *glp_get_col_name(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_name| returns a pointer to an internal +buffer, which contains a symbolic name assigned to \verb|j|-th column. +However, if the column has no assigned name, the routine returns +\verb|NULL|. + +\subsection{glp\_get\_row\_type --- retrieve row type} + +\synopsis + +\begin{verbatim} + int glp_get_row_type(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_type| returns the type of \verb|i|-th +row, i.e. the type of corresponding auxiliary variable, as follows: + +\verb|GLP_FR| --- free (unbounded) variable; + +\verb|GLP_LO| --- variable with lower bound; + +\verb|GLP_UP| --- variable with upper bound; + +\verb|GLP_DB| --- double-bounded variable; + +\verb|GLP_FX| --- fixed variable. + +\subsection{glp\_get\_row\_lb --- retrieve row lower bound} + +\synopsis + +\begin{verbatim} + double glp_get_row_lb(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_lb| returns the lower bound of +\verb|i|-th row, i.e. the lower bound of corresponding auxiliary +variable. However, if the row has no lower bound, the routine returns +\verb|-DBL_MAX|. + +\vspace*{-4pt} + +\subsection{glp\_get\_row\_ub --- retrieve row upper bound} + +\synopsis + +\begin{verbatim} + double glp_get_row_ub(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_ub| returns the upper bound of +\verb|i|-th row, i.e. the upper bound of corresponding auxiliary +variable. However, if the row has no upper bound, the routine returns +\verb|+DBL_MAX|. + +\vspace*{-4pt} + +\subsection{glp\_get\_col\_type --- retrieve column type} + +\synopsis + +\begin{verbatim} + int glp_get_col_type(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_type| returns the type of \verb|j|-th +column, i.e. the type of corresponding structural variable, as follows: + +\verb|GLP_FR| --- free (unbounded) variable; + +\verb|GLP_LO| --- variable with lower bound; + +\verb|GLP_UP| --- variable with upper bound; + +\verb|GLP_DB| --- double-bounded variable; + +\verb|GLP_FX| --- fixed variable. + +\vspace*{-4pt} + +\subsection{glp\_get\_col\_lb --- retrieve column lower bound} + +\synopsis + +\begin{verbatim} + double glp_get_col_lb(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_lb| returns the lower bound of +\verb|j|-th column, i.e. the lower bound of corresponding structural +variable. However, if the column has no lower bound, the routine +returns \verb|-DBL_MAX|. + +\subsection{glp\_get\_col\_ub --- retrieve column upper bound} + +\synopsis + +\begin{verbatim} + double glp_get_col_ub(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_ub| returns the upper bound of +\verb|j|-th column, i.e. the upper bound of corresponding structural +variable. However, if the column has no upper bound, the routine +returns \verb|+DBL_MAX|. + +\subsection{glp\_get\_obj\_coef --- retrieve objective coefficient or +constant term} + +\synopsis + +\begin{verbatim} + double glp_get_obj_coef(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_obj_coef| returns the objective coefficient +at \verb|j|-th structural variable (column). + +If the parameter \verb|j| is 0, the routine returns the constant term +(``shift'') of the objective function. + +\subsection{glp\_get\_num\_nz --- retrieve number of constraint +coefficients} + +\synopsis + +\begin{verbatim} + int glp_get_num_nz(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_num_nz| returns the number of non-zero +elements in the constraint matrix of the specified problem object. + +\subsection{glp\_get\_mat\_row --- retrieve row of the constraint +matrix} + +\synopsis + +\begin{verbatim} + int glp_get_mat_row(glp_prob *P, int i, int ind[], double val[]); +\end{verbatim} + +\description + +The routine \verb|glp_get_mat_row| scans (non-zero) elements of +\verb|i|-th row of the constraint matrix of the specified problem +object and stores their column indices and numeric values to locations +\verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, \dots, +\verb|val[len]|, respectively, where $0\leq{\tt len}\leq n$ is the +number of elements in $i$-th row, $n$ is the number of columns. + +The parameter \verb|ind| and/or \verb|val| can be specified as +\verb|NULL|, in which case corresponding information is not stored. + +\newpage + +\returns + +The routine \verb|glp_get_mat_row| returns the length \verb|len|, i.e. +the number of (non-zero) elements in \verb|i|-th row. + +\subsection{glp\_get\_mat\_col --- retrieve column of the constraint +matrix} + +\synopsis + +\begin{verbatim} + int glp_get_mat_col(glp_prob *P, int j, int ind[], double val[]); +\end{verbatim} + +\description + +The routine \verb|glp_get_mat_col| scans (non-zero) elements of +\verb|j|-th column of the constraint matrix of the specified problem +object and stores their row indices and numeric values to locations +\linebreak \verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, +\dots, \verb|val[len]|, respectively, where $0\leq{\tt len}\leq m$ is +the number of elements in $j$-th column, $m$ is the number of rows. + +The parameter \verb|ind| and/or \verb|val| can be specified as +\verb|NULL|, in which case corresponding information is not stored. + +\returns + +The routine \verb|glp_get_mat_col| returns the length \verb|len|, i.e. +the number of (non-zero) elements in \verb|j|-th column. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Row and column searching routines} + +Sometimes it may be necessary to find rows and/or columns by their +names (assigned with the routines \verb|glp_set_row_name| and +\verb|glp_set_col_name|). Though a particular row/column can be found +by its name using simple enumeration of all rows/columns, in case of +large instances such a {\it linear} search may take too long time. + +To significantly reduce the search time the application program may +create the row/column name index, which is an auxiliary data structure +implementing a {\it binary} search. Even in worst cases the search +takes logarithmic time, i.e. the time needed to find a particular row +(or column) by its name is $O(\log_2m)$ (or $O(\log_2n)$), where $m$ +and $n$ are, resp., the number of rows and columns in the problem +object. + +It is important to note that: + +1. On creating the problem object with the routine +\verb|glp_create_prob| the name index is {\it not} created. + +2. The name index can be created (destroyed) at any time with the +routine \verb|glp_create_index| (\verb|glp_delete_index|). Having been +created the name index becomes part of the corresponding problem +object. + +3. The time taken to create the name index is $O[(m+n)\log_2(m+n)]$, +so it is recommended to create the index only once, for example, just +after the problem object was created. + +4. If the name index exists, it is automatically updated every time +the name of a row/column is assigned/changed. The update operation +takes logarithmic time. + +5. If the name index does not exist, the application should not call +the routines \verb|glp_find_row| and \verb|glp_find_col|. Otherwise, +an error message will be issued and abnormal program termination will +occur. + +6. On destroying the problem object with the routine +\verb|glp_delete_prob|, the name index, if exists, is automatically +destroyed. + +\subsection{glp\_create\_index --- create the name index} + +\synopsis + +\begin{verbatim} + void glp_create_index(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_create_index| creates the name index for the +specified problem object. The name index is an auxiliary data +structure, which is intended to quickly (i.e. for logarithmic time) +find rows and columns by their names. + +This routine can be called at any time. If the name index already +exists, the routine does nothing. + +\newpage + +\subsection{glp\_find\_row --- find row by its name} + +\synopsis + +\begin{verbatim} + int glp_find_row(glp_prob *P, const char *name); +\end{verbatim} + +\returns + +The routine \verb|glp_find_row| returns the ordinal number of a row, +which is assigned the specified symbolic \verb|name|. If no such row +exists, the routine returns 0. + +\subsection{glp\_find\_col --- find column by its name} + +\synopsis + +\begin{verbatim} + int glp_find_col(glp_prob *P, const char *name); +\end{verbatim} + +\returns + +The routine \verb|glp_find_col| returns the ordinal number of a column, +which is assigned the specified symbolic \verb|name|. If no such column +exists, the routine returns 0. + +\subsection{glp\_delete\_index --- delete the name index} + +\synopsis + +\begin{verbatim} + void glp_delete_index(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_delete_index| deletes the name index previously +created by the routine\linebreak \verb|glp_create_index| and frees the +memory allocated to this auxiliary data structure. + +This routine can be called at any time. If the name index does not +exist, the routine does nothing. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Problem scaling routines} + +\subsection{Background} + +In GLPK the {\it scaling} means a linear transformation applied to the +constraint matrix to improve its numerical properties.\footnote{In many +cases a proper scaling allows making the constraint matrix to be better +conditioned, i.e. decreasing its condition number, that makes +computations numerically more stable.} + +The main equality is the following: +$$\widetilde{A}=RAS,\eqno(2.1)$$ +where $A=(a_{ij})$ is the original constraint matrix, $R=(r_{ii})>0$ is +a diagonal matrix used to scale rows (constraints), $S=(s_{jj})>0$ is a +diagonal matrix used to scale columns (variables), $\widetilde{A}$ is +the scaled constraint matrix. + +From (2.1) it follows that in the {\it scaled} problem instance each +original constraint coefficient $a_{ij}$ is replaced by corresponding +scaled constraint coefficient: +$$\widetilde{a}_{ij}=r_{ii}a_{ij}s_{jj}.\eqno(2.2)$$ + +Note that the scaling is performed internally and therefore +transparently to the user. This means that on API level the user always +deal with unscaled data. + +Scale factors $r_{ii}$ and $s_{jj}$ can be set or changed at any time +either directly by the application program in a problem specific way +(with the routines \verb|glp_set_rii| and \verb|glp_set_sjj|), or by +some API routines intended for automatic scaling. + +\subsection{glp\_set\_rii --- set (change) row scale factor} + +\synopsis + +\begin{verbatim} + void glp_set_rii(glp_prob *P, int i, double rii); +\end{verbatim} + +\description + +The routine \verb|glp_set_rii| sets (changes) the scale factor $r_{ii}$ +for $i$-th row of the specified problem object. + +\subsection{glp\_set\_sjj --- set (change) column scale factor} + +\synopsis + +\begin{verbatim} + void glp_set_sjj(glp_prob *P, int j, double sjj); +\end{verbatim} + +\description + +The routine \verb|glp_set_sjj| sets (changes) the scale factor $s_{jj}$ +for $j$-th column of the specified problem object. + +\subsection{glp\_get\_rii --- retrieve row scale factor} + +\synopsis + +\begin{verbatim} + double glp_get_rii(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_rii| returns current scale factor $r_{ii}$ +for $i$-th row of the specified problem object. + +\vspace*{-6pt} + +\subsection{glp\_get\_sjj --- retrieve column scale factor} + +\vspace*{-4pt} + +\synopsis + +\begin{verbatim} + double glp_get_sjj(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_sjj| returns current scale factor $s_{jj}$ +for $j$-th column of the specified problem object. + +\vspace*{-6pt} + +\subsection{glp\_scale\_prob --- scale problem data} + +\vspace*{-4pt} + +\synopsis + +\begin{verbatim} + void glp_scale_prob(glp_prob *P, int flags); +\end{verbatim} + +\description + +The routine \verb|glp_scale_prob| performs automatic scaling of problem +data for the specified problem object. + +The parameter \verb|flags| specifies scaling options used by the +routine. The options can be combined with the bitwise OR operator and +may be the following: + +\verb|GLP_SF_GM | --- perform geometric mean scaling; + +\verb|GLP_SF_EQ | --- perform equilibration scaling; + +\verb|GLP_SF_2N | --- round scale factors to nearest power of two; + +\verb|GLP_SF_SKIP| --- skip scaling, if the problem is well scaled. + +The parameter \verb|flags| may be also specified as \verb|GLP_SF_AUTO|, +in which case the routine chooses the scaling options automatically. + +\vspace*{-6pt} + +\subsection{glp\_unscale\_prob --- unscale problem data} + +\vspace*{-4pt} + +\synopsis + +\begin{verbatim} + void glp_unscale_prob(glp_prob *P); +\end{verbatim} + +The routine \verb|glp_unscale_prob| performs unscaling of problem data +for the specified problem object. + +``Unscaling'' means replacing the current scaling matrices $R$ and $S$ +by unity matrices that cancels the scaling effect. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{LP basis constructing routines} + +\subsection{Background} + +To start the search the simplex method needs a valid initial basis. +In GLPK the basis is completely defined by a set of {\it statuses} +assigned to {\it all} (auxiliary and structural) variables, where the +status may be one of the following: + +\verb|GLP_BS| --- basic variable; + +\verb|GLP_NL| --- non-basic variable having active lower bound; + +\verb|GLP_NU| --- non-basic variable having active upper bound; + +\verb|GLP_NF| --- non-basic free variable; + +\verb|GLP_NS| --- non-basic fixed variable. + +The basis is {\it valid}, if the basis matrix, which is a matrix built +of columns of the augmented constraint matrix $(I\:|-A)$ corresponding +to basic variables, is non-singular. This, in particular, means that +the number of basic variables must be the same as the number of rows in +the problem object. (For more details see Section \ref{lpbasis}, page +\pageref{lpbasis}.) + +Any initial basis may be constructed (or restored) with the API +routines \verb|glp_set_row_stat| and \verb|glp_set_col_stat| by +assigning appropriate statuses to auxiliary and structural variables. +Another way to construct an initial basis is to use API routines like +\verb|glp_adv_basis|, which implement so called +{\it crashing}.\footnote{This term is from early linear programming +systems and means a heuristic to construct a valid initial basis.} Note +that on normal exit the simplex solver remains the basis valid, so in +case of reoptimization there is no need to construct an initial basis +from scratch. + +\subsection{glp\_set\_row\_stat --- set (change) row status} + +\synopsis + +\begin{verbatim} + void glp_set_row_stat(glp_prob *P, int i, int stat); +\end{verbatim} + +\description + +The routine \verb|glp_set_row_stat| sets (changes) the current status +of \verb|i|-th row (auxiliary variable) as specified by the parameter +\verb|stat|: + +\verb|GLP_BS| --- make the row basic (make the constraint inactive); + +\verb|GLP_NL| --- make the row non-basic (make the constraint active); + +\verb|GLP_NU| --- make the row non-basic and set it to the upper bound; +if the row is not double-bounded, this status is equivalent to +\verb|GLP_NL| (only in case of this routine); + +\verb|GLP_NF| --- the same as \verb|GLP_NL| (only in case of this +routine); + +\verb|GLP_NS| --- the same as \verb|GLP_NL| (only in case of this +routine). + +\newpage + +\subsection{glp\_set\_col\_stat --- set (change) column status} + +\synopsis + +\begin{verbatim} + void glp_set_col_stat(glp_prob *P, int j, int stat); +\end{verbatim} + +\description + +The routine \verb|glp_set_col_stat sets| (changes) the current status +of \verb|j|-th column (structural variable) as specified by the +parameter \verb|stat|: + +\verb|GLP_BS| --- make the column basic; + +\verb|GLP_NL| --- make the column non-basic; + +\verb|GLP_NU| --- make the column non-basic and set it to the upper +bound; if the column is not double-bounded, this status is equivalent +to \verb|GLP_NL| (only in case of this routine); + +\verb|GLP_NF| --- the same as \verb|GLP_NL| (only in case of this +routine); + +\verb|GLP_NS| --- the same as \verb|GLP_NL| (only in case of this +routine). + +\subsection{glp\_std\_basis --- construct standard initial LP basis} + +\synopsis + +\begin{verbatim} + void glp_std_basis(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_std_basis| constructs the ``standard'' (trivial) +initial LP basis for the specified problem object. + +In the ``standard'' LP basis all auxiliary variables (rows) are basic, +and all structural variables (columns) are non-basic (so the +corresponding basis matrix is unity). + +\subsection{glp\_adv\_basis --- construct advanced initial LP basis} + +\synopsis + +\begin{verbatim} + void glp_adv_basis(glp_prob *P, int flags); +\end{verbatim} + +\description + +The routine \verb|glp_adv_basis| constructs an advanced initial LP +basis for the specified problem object. + +The parameter \verb|flags| is reserved for use in the future and must +be specified as zero. + +In order to construct the advanced initial LP basis the routine does +the following: + +1) includes in the basis all non-fixed auxiliary variables; + +2) includes in the basis as many non-fixed structural variables as +possible keeping the triangular form of the basis matrix; + +3) includes in the basis appropriate (fixed) auxiliary variables to +complete the basis. + +As a result the initial LP basis has as few fixed variables as possible +and the corresponding basis matrix is triangular. + +\subsection{glp\_cpx\_basis --- construct Bixby's initial LP basis} + +\synopsis + +\begin{verbatim} + void glp_cpx_basis(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_cpx_basis| constructs an initial basis for the +specified problem object with the algorithm proposed by +R.~Bixby.\footnote{Robert E. Bixby, ``Implementing the Simplex Method: +The Initial Basis.'' ORSA Journal on Computing, Vol. 4, No. 3, 1992, +pp. 267-84.} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Simplex method routines} + +The {\it simplex method} is a well known efficient numerical procedure +to solve LP problems. + +On each iteration the simplex method transforms the original system of +equaility constraints (1.2) resolving them through different sets of +variables to an equivalent system called {\it the simplex table} (or +sometimes {\it the simplex tableau}), which has the following form: +$$ +\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r} +z&=&d_1(x_N)_1&+&d_2(x_N)_2&+ \dots +&d_n(x_N)_n \\ +(x_B)_1&=&\xi_{11}(x_N)_1& +& \xi_{12}(x_N)_2& + \dots +& + \xi_{1n}(x_N)_n \\ +(x_B)_2&=& \xi_{21}(x_N)_1& +& \xi_{22}(x_N)_2& + \dots +& + \xi_{2n}(x_N)_n \\ +\multicolumn{7}{c} +{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .} \\ +(x_B)_m&=&\xi_{m1}(x_N)_1& +& \xi_{m2}(x_N)_2& + \dots +& + \xi_{mn}(x_N)_n \\ +\end{array} \eqno (2.3) +$$ +where: $(x_B)_1, (x_B)_2, \dots, (x_B)_m$ are basic variables; +$(x_N)_1, (x_N)_2, \dots, (x_N)_n$ are non-basic variables; +$d_1, d_2, \dots, d_n$ are reduced costs; +$\xi_{11}, \xi_{12}, \dots, \xi_{mn}$ are coefficients of the +simplex table. (May note that the original LP problem (1.1)---(1.3) +also has the form of a simplex table, where all equalities are resolved +through auxiliary variables.) + +From the linear programming theory it is known that if an optimal +solution of the LP problem (1.1)---(1.3) exists, it can always be +written in the form (2.3), where non-basic variables are set on their +bounds while values of the objective function and basic variables are +determined by the corresponding equalities of the simplex table. + +A set of values of all basic and non-basic variables determined by the +simplex table is called {\it basic solution}. If all basic variables +are within their bounds, the basic solution is called {\it (primal) +feasible}, otherwise it is called {\it (primal) infeasible}. A feasible +basic solution, which provides a smallest (in case of minimization) or +a largest (in case of maximization) value of the objective function is +called {\it optimal}. Therefore, for solving LP problem the simplex +method tries to find its optimal basic solution. + +Primal feasibility of some basic solution may be stated by simple +checking if all basic variables are within their bounds. Basic solution +is optimal if additionally the following optimality conditions are +satisfied for all non-basic variables: +\begin{center} +\begin{tabular}{lcc} +Status of $(x_N)_j$ & Minimization & Maximization \\ +\hline +$(x_N)_j$ is free & $d_j = 0$ & $d_j = 0$ \\ +$(x_N)_j$ is on its lower bound & $d_j \geq 0$ & $d_j \leq 0$ \\ +$(x_N)_j$ is on its upper bound & $d_j \leq 0$ & $d_j \geq 0$ \\ +\end{tabular} +\end{center} +In other words, basic solution is optimal if there is no non-basic +variable, which changing in the feasible direction (i.e. increasing if +it is free or on its lower bound, or decreasing if it is free or on its +upper bound) can improve (i.e. decrease in case of minimization or +increase in case of maximization) the objective function. + +If all non-basic variables satisfy to the optimality conditions shown +above (independently on whether basic variables are within their bounds +or not), the basic solution is called {\it dual feasible}, otherwise it +is called {\it dual infeasible}. + +It may happen that some LP problem has no primal feasible solution due +to incorrect\linebreak formulation --- this means that its constraints +conflict with each other. It also may happen that some LP problem has +unbounded solution again due to incorrect formulation --- this means +that some non-basic variable can improve the objective function, i.e. +the optimality conditions are violated, and at the same time this +variable can infinitely change in the feasible direction meeting +no resistance from basic variables. (May note that in the latter case +the LP problem has no dual feasible solution.) + +\subsection{glp\_simplex --- solve LP problem with the primal or dual +simplex method} + +\synopsis + +\begin{verbatim} + int glp_simplex(glp_prob *P, const glp_smcp *parm); +\end{verbatim} + +\description + +The routine \verb|glp_simplex| is a driver to the LP solver based on +the simplex method. This routine retrieves problem data from the +specified problem object, calls the solver to solve the problem +instance, and stores results of computations back into the problem +object. + +The simplex solver has a set of control parameters. Values of the +control parameters can be passed in the structure \verb|glp_smcp|, +which the parameter \verb|parm| points to. For detailed description of +this structure see paragraph ``Control parameters'' below. +Before specifying some control parameters the application program +should initialize the structure \verb|glp_smcp| by default values of +all control parameters using the routine \verb|glp_init_smcp| (see the +next subsection). This is needed for backward compatibility, because in +the future there may appear new members in the structure +\verb|glp_smcp|. + +The parameter \verb|parm| can be specified as \verb|NULL|, in which +case the solver uses default settings. + +\returns + +\begin{retlist} +0 & The LP problem instance has been successfully solved. (This code +does {\it not} necessarily mean that the solver has found optimal +solution. It only means that the solution process was successful.) \\ + +\verb|GLP_EBADB| & Unable to start the search, because the initial +basis specified in the problem object is invalid---the number of basic +(auxiliary and structural) variables is not the same as the number of +rows in the problem object.\\ + +\verb|GLP_ESING| & Unable to start the search, because the basis matrix +corresponding to the initial basis is singular within the working +precision.\\ + +\verb|GLP_ECOND| & Unable to start the search, because the basis matrix +corresponding to the initial basis is ill-conditioned, i.e. its +condition number is too large.\\ + +\verb|GLP_EBOUND| & Unable to start the search, because some +double-bounded (auxiliary or structural) variables have incorrect +bounds.\\ + +\verb|GLP_EFAIL| & The search was prematurely terminated due to the +solver failure.\\ + +\verb|GLP_EOBJLL| & The search was prematurely terminated, because the +objective function being maximized has reached its lower limit and +continues decreasing (the dual simplex only).\\ +\end{retlist} + +\begin{retlist} +\verb|GLP_EOBJUL| & The search was prematurely terminated, because the +objective function being minimized has reached its upper limit and +continues increasing (the dual simplex only).\\ + +\verb|GLP_EITLIM| & The search was prematurely terminated, because the +simplex iteration limit has been exceeded.\\ + +\verb|GLP_ETMLIM| & The search was prematurely terminated, because the +time limit has been exceeded.\\ + +\verb|GLP_ENOPFS| & The LP problem instance has no primal feasible +solution (only if the LP presolver is used).\\ + +\verb|GLP_ENODFS| & The LP problem instance has no dual feasible +solution (only if the LP presolver is used).\\ +\end{retlist} + +\para{Built-in LP presolver} + +The simplex solver has {\it built-in LP presolver}. It is a subprogram +that transforms the original LP problem specified in the problem object +to an equivalent LP problem, which may be easier for solving with the +simplex method than the original one. This is attained mainly due to +reducing the problem size and improving its numeric properties (for +example, by removing some inactive constraints or by fixing some +non-basic variables). Once the transformed LP problem has been solved, +the presolver transforms its basic solution back to the corresponding +basic solution of the original problem. + +Presolving is an optional feature of the routine \verb|glp_simplex|, +and by default it is disabled. In order to enable the LP presolver the +control parameter \verb|presolve| should be set to \verb|GLP_ON| (see +paragraph ``Control parameters'' below). Presolving may be used when +the problem instance is solved for the first time. However, on +performing re-optimization the presolver should be disabled. + +The presolving procedure is transparent to the API user in the sense +that all necessary processing is performed internally, and a basic +solution of the original problem recovered by the presolver is the same +as if it were computed directly, i.e. without presolving. + +Note that the presolver is able to recover only optimal solutions. If +a computed solution is infeasible or non-optimal, the corresponding +solution of the original problem cannot be recovered and therefore +remains undefined. If you need to know a basic solution even if it is +infeasible or non-optimal, the presolver should be disabled. + +\para{Terminal output} + +Solving large problem instances may take a long time, so the solver +reports some information about the current basic solution, which is +sent to the terminal. This information has the following format: + +\begin{verbatim} + nnn: obj = xxx infeas = yyy (ddd) +\end{verbatim} + +\noindent +where: `\verb|nnn|' is the iteration number, `\verb|xxx|' is the +current value of the objective function (it is unscaled and has correct +sign); `\verb|yyy|' is the current sum of primal or dual +infeasibilities (it is scaled and therefore may be used only for visual +estimating), `\verb|ddd|' is the current number of fixed basic +variables. + +The symbol preceding the iteration number indicates which phase of the +simplex method is in effect: + +{\it Blank} means that the solver is searching for primal feasible +solution using the primal simplex or for dual feasible solution using +the dual simplex; + +{\it Asterisk} (\verb|*|) means that the solver is searching for +optimal solution using the primal simplex; + +{\it Vertical dash} (\verb/|/) means that the solver is searching for +optimal solution using the dual simplex. + +\para{Control parameters} + +This paragraph describes all control parameters currently used in the +simplex solver. Symbolic names of control parameters are names of +corresponding members in the structure \verb|glp_smcp|. + +\bigskip + +{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL}) + +Message level for terminal output: + +\verb|GLP_MSG_OFF| --- no output; + +\verb|GLP_MSG_ERR| --- error and warning messages only; + +\verb|GLP_MSG_ON | --- normal output; + +\verb|GLP_MSG_ALL| --- full output (including informational messages). + +\bigskip + +{\tt int meth} (default: {\tt GLP\_PRIMAL}) + +Simplex method option: + +\verb|GLP_PRIMAL| --- use two-phase primal simplex; + +\verb|GLP_DUAL | --- use two-phase dual simplex; + +\verb|GLP_DUALP | --- use two-phase dual simplex, and if it fails, +switch to the primal simplex. + +\bigskip + +{\tt int pricing} (default: {\tt GLP\_PT\_PSE}) + +Pricing technique: + +\verb|GLP_PT_STD| --- standard (``textbook''); + +\verb|GLP_PT_PSE| --- projected steepest edge. + +\bigskip + +{\tt int r\_test} (default: {\tt GLP\_RT\_HAR}) + +Ratio test technique: + +\verb|GLP_RT_STD| --- standard (``textbook''); + +\verb|GLP_RT_HAR| --- Harris' two-pass ratio test. + +\bigskip + +{\tt double tol\_bnd} (default: {\tt 1e-7}) + +Tolerance used to check if the basic solution is primal feasible. +(Do not change this parameter without detailed understanding its +purpose.) + +\newpage + +{\tt double tol\_dj} (default: {\tt 1e-7}) + +Tolerance used to check if the basic solution is dual feasible. +(Do not change this parameter without detailed understanding its +purpose.) + +\bigskip + +{\tt double tol\_piv} (default: {\tt 1e-9}) + +Tolerance used to choose eligble pivotal elements of the simplex table. +(Do not change this parameter without detailed understanding its +purpose.) + +\bigskip + +{\tt double obj\_ll} (default: {\tt -DBL\_MAX}) + +Lower limit of the objective function. If the objective function +reaches this limit and continues decreasing, the solver terminates the +search. (Used in the dual simplex only.) + +\bigskip + +{\tt double obj\_ul} (default: {\tt +DBL\_MAX}) + +Upper limit of the objective function. If the objective function +reaches this limit and continues increasing, the solver terminates the +search. (Used in the dual simplex only.) + +\bigskip + +{\tt int it\_lim} (default: {\tt INT\_MAX}) + +Simplex iteration limit. + +\bigskip + +{\tt int tm\_lim} (default: {\tt INT\_MAX}) + +Searching time limit, in milliseconds. + +\bigskip + +{\tt int out\_frq} (default: {\tt 500}) + +Output frequency, in iterations. This parameter specifies how +frequently the solver sends information about the solution process to +the terminal. + +\bigskip + +{\tt int out\_dly} (default: {\tt 0}) + +Output delay, in milliseconds. This parameter specifies how long the +solver should delay sending information about the solution process to +the terminal. + +\bigskip + +{\tt int presolve} (default: {\tt GLP\_OFF}) + +LP presolver option: + +\verb|GLP_ON | --- enable using the LP presolver; + +\verb|GLP_OFF| --- disable using the LP presolver. + +\newpage + +\para{Example 1} + +The following example main program reads LP problem instance in fixed +MPS format from file \verb|25fv47.mps|,\footnote{This instance in fixed +MPS format can be found in the Netlib LP collection; see +{\tt ftp://ftp.netlib.org/lp/data/}.} constructs an advanced initial +basis, solves the instance with the primal simplex method (by default), +and writes the solution to file \verb|25fv47.txt|. + +\begin{footnotesize} +\begin{verbatim} +/* spxsamp1.c */ + +#include +#include +#include + +int main(void) +{ glp_prob *P; + P = glp_create_prob(); + glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); + glp_adv_basis(P, 0); + glp_simplex(P, NULL); + glp_print_sol(P, "25fv47.txt"); + glp_delete_prob(P); + return 0; +} + +/* eof */ +\end{verbatim} +\end{footnotesize} + +Below here is shown the terminal output from this example program. + +\begin{footnotesize} +\begin{verbatim} +Reading problem data from `25fv47.mps'... +Problem: 25FV47 +Objective: R0000 +822 rows, 1571 columns, 11127 non-zeros +6919 records were read +Crashing... +Size of triangular part = 799 + 0: obj = 1.627307307e+04 infeas = 5.194e+04 (23) + 200: obj = 1.474901610e+04 infeas = 1.233e+04 (19) + 400: obj = 1.343909995e+04 infeas = 3.648e+03 (13) + 600: obj = 1.756052217e+04 infeas = 4.179e+02 (7) +* 775: obj = 1.789251591e+04 infeas = 4.982e-14 (1) +* 800: obj = 1.663354510e+04 infeas = 2.857e-14 (1) +* 1000: obj = 1.024935068e+04 infeas = 1.958e-12 (1) +* 1200: obj = 7.860174791e+03 infeas = 2.810e-29 (1) +* 1400: obj = 6.642378184e+03 infeas = 2.036e-16 (1) +* 1600: obj = 6.037014568e+03 infeas = 0.000e+00 (1) +* 1800: obj = 5.662171307e+03 infeas = 6.447e-15 (1) +* 2000: obj = 5.528146165e+03 infeas = 9.764e-13 (1) +* 2125: obj = 5.501845888e+03 infeas = 0.000e+00 (1) +OPTIMAL SOLUTION FOUND +Writing basic solution to `25fv47.txt'... +\end{verbatim} +\end{footnotesize} + +\newpage + +\para{Example 2} + +The following example main program solves the same LP problem instance +as in Example 1 above, however, it uses the dual simplex method, which +starts from the standard initial basis. + +\begin{footnotesize} +\begin{verbatim} +/* spxsamp2.c */ + +#include +#include +#include + +int main(void) +{ glp_prob *P; + glp_smcp parm; + P = glp_create_prob(); + glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); + glp_init_smcp(&parm); + parm.meth = GLP_DUAL; + glp_simplex(P, &parm); + glp_print_sol(P, "25fv47.txt"); + glp_delete_prob(P); + return 0; +} + +/* eof */ +\end{verbatim} +\end{footnotesize} + +Below here is shown the terminal output from this example program. + +\begin{footnotesize} +\begin{verbatim} +Reading problem data from `25fv47.mps'... +Problem: 25FV47 +Objective: R0000 +822 rows, 1571 columns, 11127 non-zeros +6919 records were read + 0: infeas = 1.223e+03 (516) + 200: infeas = 7.000e+00 (471) + 240: infeas = 1.106e-14 (461) +| 400: obj = -5.394267152e+03 infeas = 5.571e-16 (391) +| 600: obj = -4.586395752e+03 infeas = 1.389e-15 (340) +| 800: obj = -4.158268146e+03 infeas = 1.640e-15 (264) +| 1000: obj = -3.725320045e+03 infeas = 5.181e-15 (245) +| 1200: obj = -3.104802163e+03 infeas = 1.019e-14 (210) +| 1400: obj = -2.584190499e+03 infeas = 8.865e-15 (178) +| 1600: obj = -2.073852927e+03 infeas = 7.867e-15 (142) +| 1800: obj = -1.164037407e+03 infeas = 8.792e-15 (109) +| 2000: obj = -4.370590250e+02 infeas = 2.591e-14 (85) +| 2200: obj = 1.068240144e+03 infeas = 1.025e-13 (70) +| 2400: obj = 1.607481126e+03 infeas = 3.272e-14 (67) +| 2600: obj = 3.038230551e+03 infeas = 4.850e-14 (52) +| 2800: obj = 4.316238187e+03 infeas = 2.622e-14 (36) +| 3000: obj = 5.443842629e+03 infeas = 3.976e-15 (11) +| 3060: obj = 5.501845888e+03 infeas = 8.806e-15 (2) +OPTIMAL SOLUTION FOUND +Writing basic solution to `25fv47.txt'... +\end{verbatim} +\end{footnotesize} + +\newpage + +\subsection{glp\_exact --- solve LP problem in exact arithmetic} + +\synopsis + +\begin{verbatim} + int glp_exact(glp_prob *P, const glp_smcp *parm); +\end{verbatim} + +\description + +The routine \verb|glp_exact| is a tentative implementation of the +primal two-phase simplex method based on exact (rational) arithmetic. +It is similar to the routine \verb|glp_simplex|, however, for all +internal computations it uses arithmetic of rational numbers, which is +exact in mathematical sense, i.e. free of round-off errors unlike +floating-point arithmetic. + +Note that the routine \verb|glp_exact| uses only two control parameters +passed in the structure \verb|glp_smcp|, namely, \verb|it_lim| and +\verb|tm_lim|. + +\returns + +\begin{retlist} +0 & The LP problem instance has been successfully solved. (This code +does {\it not} necessarily mean that the solver has found optimal +solution. It only means that the solution process was successful.) \\ + +\verb|GLP_EBADB| & Unable to start the search, because the initial basis +specified in the problem object is invalid---the number of basic +(auxiliary and structural) variables is not the same as the number of +rows in the problem object.\\ + +\verb|GLP_ESING| & Unable to start the search, because the basis matrix +corresponding to the initial basis is exactly singular.\\ + +\verb|GLP_EBOUND| & Unable to start the search, because some +double-bounded (auxiliary or structural) variables have incorrect +bounds.\\ + +\verb|GLP_EFAIL| & The problem instance has no rows/columns.\\ + +\verb|GLP_EITLIM| & The search was prematurely terminated, because the +simplex iteration limit has been exceeded.\\ + +\verb|GLP_ETMLIM| & The search was prematurely terminated, because the +time limit has been exceeded.\\ +\end{retlist} + +\para{Note} + +Computations in exact arithmetic are very time-consuming, so solving +LP problem with the routine \verb|glp_exact| from the very beginning is +not a good idea. It is much better at first to find an optimal basis +with the routine \verb|glp_simplex| and only then to call +\verb|glp_exact|, in which case only a few simplex iterations need to +be performed in exact arithmetic. + +\newpage + +\subsection{glp\_init\_smcp --- initialize simplex solver control +parameters} + +\synopsis + +\begin{verbatim} + int glp_init_smcp(glp_smcp *parm); +\end{verbatim} + +\description + +The routine \verb|glp_init_smcp| initializes control parameters, which +are used by the simplex solver, with default values. + +Default values of the control parameters are stored in +a \verb|glp_smcp| structure, which the parameter \verb|parm| points to. + +\subsection{glp\_get\_status --- determine generic status of basic +solution} + +\synopsis + +\begin{verbatim} + int glp_get_status(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_status| reports the generic status of the +current basic solution for the specified problem object as follows: + +\verb|GLP_OPT | --- solution is optimal; + +\verb|GLP_FEAS | --- solution is feasible; + +\verb|GLP_INFEAS| --- solution is infeasible; + +\verb|GLP_NOFEAS| --- problem has no feasible solution; + +\verb|GLP_UNBND | --- problem has unbounded solution; + +\verb|GLP_UNDEF | --- solution is undefined. + +More detailed information about the status of basic solution can be +retrieved with the routines \verb|glp_get_prim_stat| and +\verb|glp_get_dual_stat|. + +\subsection{glp\_get\_prim\_stat --- retrieve status of primal basic +solution} + +\synopsis + +\begin{verbatim} + int glp_get_prim_stat(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_prim_stat| reports the status of the primal +basic solution for the specified problem object as follows: + +\verb|GLP_UNDEF | --- primal solution is undefined; + +\verb|GLP_FEAS | --- primal solution is feasible; + +\verb|GLP_INFEAS| --- primal solution is infeasible; + +\verb|GLP_NOFEAS| --- no primal feasible solution exists. + +\subsection{glp\_get\_dual\_stat --- retrieve status of dual basic +solution} + +\synopsis + +\begin{verbatim} + int glp_get_dual_stat(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_dual_stat| reports the status of the dual +basic solution for the specified problem object as follows: + +\verb|GLP_UNDEF | --- dual solution is undefined; + +\verb|GLP_FEAS | --- dual solution is feasible; + +\verb|GLP_INFEAS| --- dual solution is infeasible; + +\verb|GLP_NOFEAS| --- no dual feasible solution exists. + +\subsection{glp\_get\_obj\_val --- retrieve objective value} + +\synopsis + +\begin{verbatim} + double glp_get_obj_val(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_obj_val| returns current value of the +objective function. + +\subsection{glp\_get\_row\_stat --- retrieve row status} + +\synopsis + +\begin{verbatim} + int glp_get_row_stat(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_stat| returns current status assigned to +the auxiliary variable associated with \verb|i|-th row as follows: + +\verb|GLP_BS| --- basic variable; + +\verb|GLP_NL| --- non-basic variable on its lower bound; + +\verb|GLP_NU| --- non-basic variable on its upper bound; + +\verb|GLP_NF| --- non-basic free (unbounded) variable; + +\verb|GLP_NS| --- non-basic fixed variable. + +\newpage + +\subsection{glp\_get\_row\_prim --- retrieve row primal value} + +\synopsis + +\begin{verbatim} + double glp_get_row_prim(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_prim| returns primal value of the +auxiliary variable associated with \verb|i|-th row. + +\subsection{glp\_get\_row\_dual --- retrieve row dual value} + +\synopsis + +\begin{verbatim} + double glp_get_row_dual(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_dual| returns dual value (i.e. reduced +cost) of the auxiliary variable associated with \verb|i|-th row. + +\subsection{glp\_get\_col\_stat --- retrieve column status} + +\synopsis + +\begin{verbatim} + int glp_get_col_stat(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_stat| returns current status assigned to +the structural variable associated with \verb|j|-th column as follows: + +\verb|GLP_BS| --- basic variable; + +\verb|GLP_NL| --- non-basic variable on its lower bound; + +\verb|GLP_NU| --- non-basic variable on its upper bound; + +\verb|GLP_NF| --- non-basic free (unbounded) variable; + +\verb|GLP_NS| --- non-basic fixed variable. + +\subsection{glp\_get\_col\_prim --- retrieve column primal value} + +\synopsis + +\begin{verbatim} + double glp_get_col_prim(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_prim| returns primal value of the +structural variable associated with \verb|j|-th column. + +\newpage + +\subsection{glp\_get\_col\_dual --- retrieve column dual value} + +\synopsis + +\begin{verbatim} + double glp_get_col_dual(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_dual| returns dual value (i.e. reduced +cost) of the structural variable associated with \verb|j|-th column. + +\subsection{glp\_get\_unbnd\_ray --- determine variable causing +unboundedness} + +\synopsis + +\begin{verbatim} + int glp_get_unbnd_ray(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_unbnd_ray| returns the number $k$ of +a variable, which causes primal or dual unboundedness. +If $1\leq k\leq m$, it is $k$-th auxiliary variable, and if +$m+1\leq k\leq m+n$, it is $(k-m)$-th structural variable, where $m$ is +the number of rows, $n$ is the number of columns in the problem object. +If such variable is not defined, the routine returns 0. + +\para{Note} + +If it is not exactly known which version of the simplex solver +detected unboundedness, i.e. whether the unboundedness is primal or +dual, it is sufficient to check the status of the variable +with the routine \verb|glp_get_row_stat| or \verb|glp_get_col_stat|. +If the variable is non-basic, the unboundedness is primal, otherwise, +if the variable is basic, the unboundedness is dual (the latter case +means that the problem has no primal feasible dolution). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Interior-point method routines} + +{\it Interior-point methods} (also known as {\it barrier methods}) are +more modern and powerful numerical methods for large-scale linear +programming. Such methods are especially efficient for very sparse LP +problems and allow solving such problems much faster than the simplex +method. + +In brief, the GLPK interior-point solver works as follows. + +At first, the solver transforms the original LP to a {\it working} LP +in the standard format: + +\medskip + +\noindent +\hspace{.5in} minimize +$$z = c_1x_{m+1} + c_2x_{m+2} + \dots + c_nx_{m+n} + c_0 \eqno (2.4)$$ +\hspace{.5in} subject to linear constraints +$$ +\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}l} +a_{11}x_{m+1}&+&a_{12}x_{m+2}&+ \dots +&a_{1n}x_{m+n}&=&b_1 \\ +a_{21}x_{m+1}&+&a_{22}x_{m+2}&+ \dots +&a_{2n}x_{m+n}&=&b_2 \\ +\multicolumn{7}{c} +{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .} \\ +a_{m1}x_{m+1}&+&a_{m2}x_{m+2}&+ \dots +&a_{mn}x_{m+n}&=&b_m \\ +\end{array} \eqno (2.5) +$$ +\hspace{.5in} and non-negative variables +$$x_1\geq 0,\ \ x_2\geq 0,\ \ \dots,\ \ x_n\geq 0 \eqno(2.6)$$ +where: $z$ is the objective function; $x_1$, \dots, $x_n$ are variables; +$c_1$, \dots, $c_n$ are objective coefficients; $c_0$ is a constant term +of the objective function; $a_{11}$, \dots, $a_{mn}$ are constraint +coefficients; $b_1$, \dots, $b_m$ are right-hand sides. + +Using vector and matrix notations the working LP (2.4)---(2.6) can be +written as follows: +$$z=c^Tx+c_0\ \rightarrow\ \min,\eqno(2.7)$$ +$$Ax=b,\eqno(2.8)$$ +$$x\geq 0,\eqno(2.9)$$ +where: $x=(x_j)$ is $n$-vector of variables, $c=(c_j)$ is $n$-vector of +objective coefficients, $A=(a_{ij})$ is $m\times n$-matrix of +constraint coefficients, and $b=(b_i)$ is $m$-vector of right-hand +sides. + +Karush--Kuhn--Tucker optimality conditions for LP (2.7)---(2.9) are the +following: +$$Ax=b,\eqno(2.10)$$ +$$A^T\pi+\lambda=c,\eqno(2.11)$$ +$$\lambda^Tx=0,\eqno(2.12)$$ +$$x\geq 0,\ \ \lambda\geq 0,\eqno(2.13)$$ +where: +$\pi$ is $m$-vector of Lagrange multipliers (dual variables) for +equality constraints (2.8),\linebreak $\lambda$ is $n$-vector of +Lagrange multipliers (dual variables) for non-negativity constraints +(2.9),\linebreak (2.10) is the primal feasibility condition, (2.11) is +the dual feasibility condition, (2.12) is the primal-dual +complementarity condition, and (2.13) is the non-negativity conditions. + +The main idea of the primal-dual interior-point method is based on +finding a point in the primal-dual space (i.e. in the space of all +primal and dual variables $x$, $\pi$, and $\lambda$), which satisfies +to all optimality conditions (2.10)---(2.13). Obviously, $x$-component +of such point then provides an optimal solution to the working LP +(2.7)---(2.9). + +To find the optimal point $(x^*,\pi^*,\lambda^*)$ the interior-point +method attempts to solve the system of equations (2.10)---(2.12), which +is closed in the sense that the number of variables $x_j$, $\pi_i$, and +$\lambda_j$ and the number equations are the same and equal to $m+2n$. +Due to condition (2.12) this system of equations is non-linear, so it +can be solved with a version of {\it Newton's method} provided with +additional rules to keep the current point within the positive orthant +as required by the non-negativity conditions (2.13). + +Finally, once the optimal point $(x^*,\pi^*,\lambda^*)$ has been found, +the solver performs inverse transformations to recover corresponding +solution to the original LP passed to the solver from the application +program. + +\subsection{glp\_interior --- solve LP problem with the interior-point +method} + +\synopsis + +\begin{verbatim} + int glp_interior(glp_prob *P, const glp_iptcp *parm); +\end{verbatim} + +\description + +The routine \verb|glp_interior| is a driver to the LP solver based on +the primal-dual interior-point method. This routine retrieves problem +data from the specified problem object, calls the solver to solve the +problem instance, and stores results of computations back into the +problem object. + +The interior-point solver has a set of control parameters. Values of +the control parameters can be passed in the structure \verb|glp_iptcp|, +which the parameter \verb|parm| points to. For detailed description of +this structure see paragraph ``Control parameters'' below. Before +specifying some control parameters the application program should +initialize the structure \verb|glp_iptcp| by default values of all +control parameters using the routine \verb|glp_init_iptcp| (see the +next subsection). This is needed for backward compatibility, because in +the future there may appear new members in the structure +\verb|glp_iptcp|. + +The parameter \verb|parm| can be specified as \verb|NULL|, in which +case the solver uses default settings. + +\returns + +\begin{retlist} +0 & The LP problem instance has been successfully solved. (This code +does {\it not} necessarily mean that the solver has found optimal +solution. It only means that the solution process was successful.) \\ + +\verb|GLP_EFAIL| & The problem has no rows/columns.\\ + +\verb|GLP_ENOCVG| & Very slow convergence or divergence.\\ + +\verb|GLP_EITLIM| & Iteration limit exceeded.\\ + +\verb|GLP_EINSTAB| & Numerical instability on solving Newtonian +system.\\ +\end{retlist} + +\newpage + +\para{Comments} + +The routine \verb|glp_interior| implements an easy version of +the primal-dual interior-point method based on Mehrotra's +technique.\footnote{S. Mehrotra. On the implementation of a primal-dual +interior point method. SIAM J. on Optim., 2(4), pp. 575-601, 1992.} + +Note that currently the GLPK interior-point solver does not include +many important features, in particular: + +\vspace*{-8pt} + +\begin{itemize} +\item it is not able to process dense columns. Thus, if the constraint +matrix of the LP problem has dense columns, the solving process may be +inefficient; + +\item it has no features against numerical instability. For some LP +problems premature termination may happen if the matrix $ADA^T$ becomes +singular or ill-conditioned; + +\item it is not able to identify the optimal basis, which corresponds +to the interior-point solution found. +\end{itemize} + +\vspace*{-8pt} + +\para{Terminal output} + +Solving large LP problems may take a long time, so the solver reports +some information about every interior-point iteration,\footnote{Unlike +the simplex method the interior point method usually needs 30---50 +iterations (independently on the problem size) in order to find an +optimal solution.} which is sent to the terminal. This information has +the following format: + +\begin{verbatim} +nnn: obj = fff; rpi = ppp; rdi = ddd; gap = ggg +\end{verbatim} + +\noindent where: \verb|nnn| is iteration number, \verb|fff| is the +current value of the objective function (in the case of maximization it +has wrong sign), \verb|ppp| is the current relative primal +infeasibility (cf. (2.10)): +$$\frac{\|Ax^{(k)}-b\|}{1+\|b\|},\eqno(2.14)$$ +\verb|ddd| is the current relative dual infeasibility (cf. (2.11)): +$$\frac{\|A^T\pi^{(k)}+\lambda^{(k)}-c\|}{1+\|c\|},\eqno(2.15)$$ +\verb|ggg| is the current primal-dual gap (cf. (2.12)): +$$\frac{|c^Tx^{(k)}-b^T\pi^{(k)}|}{1+|c^Tx^{(k)}|},\eqno(2.16)$$ +and $[x^{(k)},\pi^{(k)},\lambda^{(k)}]$ is the current point on $k$-th +iteration, $k=0,1,2,\dots$\ . Note that all solution components are +internally scaled, so information sent to the terminal is suitable only +for visual inspection. + +\newpage + +\para{Control parameters} + +This paragraph describes all control parameters currently used in the +interior-point solver. Symbolic names of control parameters are names of +corresponding members in the structure \verb|glp_iptcp|. + +\bigskip + +{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL}) + +Message level for terminal output: + +\verb|GLP_MSG_OFF|---no output; + +\verb|GLP_MSG_ERR|---error and warning messages only; + +\verb|GLP_MSG_ON |---normal output; + +\verb|GLP_MSG_ALL|---full output (including informational messages). + +\bigskip + +{\tt int ord\_alg} (default: {\tt GLP\_ORD\_AMD}) + +Ordering algorithm used prior to Cholesky factorization: + +\verb|GLP_ORD_NONE |---use natural (original) ordering; + +\verb|GLP_ORD_QMD |---quotient minimum degree (QMD); + +\verb|GLP_ORD_AMD |---approximate minimum degree (AMD); + +\verb|GLP_ORD_SYMAMD|---approximate minimum degree (SYMAMD). + +\bigskip + +\para{Example} + +The following main program reads LP problem instance in fixed MPS +format from file\linebreak \verb|25fv47.mps|,\footnote{This instance in +fixed MPS format can be found in the Netlib LP collection; see +{\tt ftp://ftp.netlib.org/lp/data/}.} solves it with the interior-point +solver, and writes the solution to file \verb|25fv47.txt|. + +\begin{footnotesize} +\begin{verbatim} +/* iptsamp.c */ + +#include +#include +#include + +int main(void) +{ glp_prob *P; + P = glp_create_prob(); + glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps"); + glp_interior(P, NULL); + glp_print_ipt(P, "25fv47.txt"); + glp_delete_prob(P); + return 0; +} + +/* eof */ +\end{verbatim} +\end{footnotesize} + +\newpage + +Below here is shown the terminal output from this example program. + +\begin{footnotesize} +\begin{verbatim} +Reading problem data from `25fv47.mps'... +Problem: 25FV47 +Objective: R0000 +822 rows, 1571 columns, 11127 non-zeros +6919 records were read +Original LP has 822 row(s), 1571 column(s), and 11127 non-zero(s) +Working LP has 821 row(s), 1876 column(s), and 10705 non-zero(s) +Matrix A has 10705 non-zeros +Matrix S = A*A' has 11895 non-zeros (upper triangle) +Minimal degree ordering... +Computing Cholesky factorization S = L'*L... +Matrix L has 35411 non-zeros +Guessing initial point... +Optimization begins... + 0: obj = 1.823377629e+05; rpi = 1.3e+01; rdi = 1.4e+01; gap = 9.3e-01 + 1: obj = 9.260045192e+04; rpi = 5.3e+00; rdi = 5.6e+00; gap = 6.8e+00 + 2: obj = 3.596999742e+04; rpi = 1.5e+00; rdi = 1.2e+00; gap = 1.8e+01 + 3: obj = 1.989627568e+04; rpi = 4.7e-01; rdi = 3.0e-01; gap = 1.9e+01 + 4: obj = 1.430215557e+04; rpi = 1.1e-01; rdi = 8.6e-02; gap = 1.4e+01 + 5: obj = 1.155716505e+04; rpi = 2.3e-02; rdi = 2.4e-02; gap = 6.8e+00 + 6: obj = 9.660273208e+03; rpi = 6.7e-03; rdi = 4.6e-03; gap = 3.9e+00 + 7: obj = 8.694348283e+03; rpi = 3.7e-03; rdi = 1.7e-03; gap = 2.0e+00 + 8: obj = 8.019543639e+03; rpi = 2.4e-03; rdi = 3.9e-04; gap = 1.0e+00 + 9: obj = 7.122676293e+03; rpi = 1.2e-03; rdi = 1.5e-04; gap = 6.6e-01 + 10: obj = 6.514534518e+03; rpi = 6.1e-04; rdi = 4.3e-05; gap = 4.1e-01 + 11: obj = 6.361572203e+03; rpi = 4.8e-04; rdi = 2.2e-05; gap = 3.0e-01 + 12: obj = 6.203355508e+03; rpi = 3.2e-04; rdi = 1.7e-05; gap = 2.6e-01 + 13: obj = 6.032943411e+03; rpi = 2.0e-04; rdi = 9.3e-06; gap = 2.1e-01 + 14: obj = 5.796553021e+03; rpi = 9.8e-05; rdi = 3.2e-06; gap = 1.0e-01 + 15: obj = 5.667032431e+03; rpi = 4.4e-05; rdi = 1.1e-06; gap = 5.6e-02 + 16: obj = 5.613911867e+03; rpi = 2.5e-05; rdi = 4.1e-07; gap = 3.5e-02 + 17: obj = 5.560572626e+03; rpi = 9.9e-06; rdi = 2.3e-07; gap = 2.1e-02 + 18: obj = 5.537276001e+03; rpi = 5.5e-06; rdi = 8.4e-08; gap = 1.1e-02 + 19: obj = 5.522746942e+03; rpi = 2.2e-06; rdi = 4.0e-08; gap = 6.7e-03 + 20: obj = 5.509956679e+03; rpi = 7.5e-07; rdi = 1.8e-08; gap = 2.9e-03 + 21: obj = 5.504571733e+03; rpi = 1.6e-07; rdi = 5.8e-09; gap = 1.1e-03 + 22: obj = 5.502576367e+03; rpi = 3.4e-08; rdi = 1.0e-09; gap = 2.5e-04 + 23: obj = 5.502057119e+03; rpi = 8.1e-09; rdi = 3.0e-10; gap = 7.7e-05 + 24: obj = 5.501885996e+03; rpi = 9.4e-10; rdi = 1.2e-10; gap = 2.4e-05 + 25: obj = 5.501852464e+03; rpi = 1.4e-10; rdi = 1.2e-11; gap = 3.0e-06 + 26: obj = 5.501846549e+03; rpi = 1.4e-11; rdi = 1.2e-12; gap = 3.0e-07 + 27: obj = 5.501845954e+03; rpi = 1.4e-12; rdi = 1.2e-13; gap = 3.0e-08 + 28: obj = 5.501845895e+03; rpi = 1.5e-13; rdi = 1.2e-14; gap = 3.0e-09 +OPTIMAL SOLUTION FOUND +Writing interior-point solution to `25fv47.txt'... +\end{verbatim} +\end{footnotesize} + +\newpage + +\subsection{glp\_init\_iptcp --- initialize interior-point solver +control parameters} + +\synopsis + +\begin{verbatim} + int glp_init_iptcp(glp_iptcp *parm); +\end{verbatim} + +\description + +The routine \verb|glp_init_iptcp| initializes control parameters, which +are used by the interior-point solver, with default values. + +Default values of the control parameters are stored in the structure +\verb|glp_iptcp|, which the parameter \verb|parm| points to. + +\subsection{glp\_ipt\_status --- determine solution status} + +\synopsis + +\begin{verbatim} + int glp_ipt_status(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_ipt_status| reports the status of a solution +found by the interior-point solver as follows: + +\verb|GLP_UNDEF | --- interior-point solution is undefined; + +\verb|GLP_OPT | --- interior-point solution is optimal; + +\verb|GLP_INFEAS| --- interior-point solution is infeasible; + +\verb|GLP_NOFEAS| --- no feasible primal-dual solution exists. + +\subsection{glp\_ipt\_obj\_val --- retrieve objective value} + +\synopsis + +\begin{verbatim} + double glp_ipt_obj_val(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_ipt_obj_val| returns value of the objective +function for interior-point solution. + +\subsection{glp\_ipt\_row\_prim --- retrieve row primal value} + +\synopsis + +\begin{verbatim} + double glp_ipt_row_prim(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_ipt_row_prim| returns primal value of the +auxiliary variable associated with \verb|i|-th row. + +\newpage + +\subsection{glp\_ipt\_row\_dual --- retrieve row dual value} + +\synopsis + +\begin{verbatim} + double glp_ipt_row_dual(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_ipt_row_dual| returns dual value (i.e. reduced +cost) of the auxiliary variable associated with \verb|i|-th row. + +\subsection{glp\_ipt\_col\_prim --- retrieve column primal value} + +\synopsis + +\begin{verbatim} + double glp_ipt_col_prim(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_ipt_col_prim| returns primal value of the +structural variable associated with \verb|j|-th column. + +\subsection{glp\_ipt\_col\_dual --- retrieve column dual value} + +\synopsis + +\begin{verbatim} + double glp_ipt_col_dual(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_ipt_col_dual| returns dual value (i.e. reduced +cost) of the structural variable associated with \verb|j|-th column. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Mixed integer programming routines} + +\subsection{glp\_set\_col\_kind --- set (change) column kind} + +\synopsis + +\begin{verbatim} + void glp_set_col_kind(glp_prob *P, int j, int kind); +\end{verbatim} + +\description + +The routine \verb|glp_set_col_kind| sets (changes) the kind of +\verb|j|-th column (structural variable) as specified by the parameter +\verb|kind|: + +\verb|GLP_CV| --- continuous variable; + +\verb|GLP_IV| --- integer variable; + +\verb|GLP_BV| --- binary variable. + +Setting a column to \verb|GLP_BV| has the same effect as if it were +set to \verb|GLP_IV|, its lower bound were set 0, and its upper bound +were set to 1. + +\subsection{glp\_get\_col\_kind --- retrieve column kind} + +\synopsis + +\begin{verbatim} + int glp_get_col_kind(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_kind| returns the kind of \verb|j|-th +column (structural variable) as follows: + +\verb|GLP_CV| --- continuous variable; + +\verb|GLP_IV| --- integer variable; + +\verb|GLP_BV| --- binary variable. + +\subsection{glp\_get\_num\_int --- retrieve number of integer columns} + +\synopsis + +\begin{verbatim} + int glp_get_num_int(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_num_int| returns the number of columns +(structural variables), which are marked as integer. Note that this +number {\it does} include binary columns. + +\newpage + +\subsection{glp\_get\_num\_bin --- retrieve number of binary columns} + +\synopsis + +\begin{verbatim} + int glp_get_num_bin(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_get_num_bin| returns the number of columns +(structural variables), which are marked as integer and whose lower +bound is zero and upper bound is one. + +\subsection{glp\_intopt --- solve MIP problem with the branch-and-cut +method} + +\synopsis + +\begin{verbatim} + int glp_intopt(glp_prob *P, const glp_iocp *parm); +\end{verbatim} + +\description + +The routine \verb|glp_intopt| is a driver to the MIP solver based on +the branch-and-cut method, which is a hybrid of branch-and-bound and +cutting plane methods. + +If the presolver is disabled (see paragraph ``Control parameters'' +below), on entry to the routine \verb|glp_intopt| the problem object, +which the parameter \verb|mip| points to, should contain optimal +solution to LP relaxation (it can be obtained, for example, with the +routine \verb|glp_simplex|). Otherwise, if the presolver is enabled, it +is not necessary. + +The MIP solver has a set of control parameters. Values of the control +parameters can be passed in the structure \verb|glp_iocp|, which the +parameter \verb|parm| points to. For detailed description of this +structure see paragraph ``Control parameters'' below. Before specifying +some control parameters the application program should initialize the +structure \verb|glp_iocp| by default values of all control parameters +using the routine \verb|glp_init_iocp| (see the next subsection). This +is needed for backward compatibility, because in the future there may +appear new members in the structure \verb|glp_iocp|. + +The parameter \verb|parm| can be specified as \verb|NULL|, in which case +the solver uses default settings. + +Note that the GLPK branch-and-cut solver is not perfect, so it is +unable to solve hard or very large scale MIP instances for a reasonable +time. + +\returns + +\begin{retlist} +0 & The MIP problem instance has been successfully solved. (This code +does {\it not} necessarily mean that the solver has found optimal +solution. It only means that the solution process was successful.) \\ + +\verb|GLP_EBOUND| & Unable to start the search, because some +double-bounded variables have incorrect bounds or some integer +variables have non-integer (fractional) bounds.\\ + +\verb|GLP_EROOT| & Unable to start the search, because optimal basis +for initial LP relaxation is not provided. (This code may appear only +if the presolver is disabled.)\\ + +\verb|GLP_ENOPFS| & Unable to start the search, because LP relaxation +of the MIP problem instance has no primal feasible solution. (This code +may appear only if the presolver is enabled.)\\ +\end{retlist} + +\newpage + +\begin{retlist} +\verb|GLP_ENODFS| & Unable to start the search, because LP relaxation +of the MIP problem instance has no dual feasible solution. In other +word, this code means that if the LP relaxation has at least one primal +feasible solution, its optimal solution is unbounded, so if the MIP +problem has at least one integer feasible solution, its (integer) +optimal solution is also unbounded. (This code may appear only if the +presolver is enabled.)\\ + +\verb|GLP_EFAIL| & The search was prematurely terminated due to the +solver failure.\\ + +\verb|GLP_EMIPGAP| & The search was prematurely terminated, because the +relative mip gap tolerance has been reached.\\ + +\verb|GLP_ETMLIM| & The search was prematurely terminated, because the +time limit has been exceeded.\\ + +\verb|GLP_ESTOP| & The search was prematurely terminated by application. +(This code may appear only if the advanced solver interface is used.)\\ +\end{retlist} + +\para{Built-in MIP presolver} + +The branch-and-cut solver has {\it built-in MIP presolver}. It is +a subprogram that transforms the original MIP problem specified in the +problem object to an equivalent MIP problem, which may be easier for +solving with the branch-and-cut method than the original one. For +example, the presolver can remove redundant constraints and variables, +whose optimal values are known, perform bound and coefficient reduction, +etc. Once the transformed MIP problem has been solved, the presolver +transforms its solution back to corresponding solution of the original +problem. + +Presolving is an optional feature of the routine \verb|glp_intopt|, and +by default it is disabled. In order to enable the MIP presolver, the +control parameter \verb|presolve| should be set to \verb|GLP_ON| (see +paragraph ``Control parameters'' below). + +\para{Advanced solver interface} + +The routine \verb|glp_intopt| allows the user to control the +branch-and-cut search by passing to the solver a user-defined callback +routine. For more details see Chapter ``Branch-and-Cut API Routines''. + +\para{Terminal output} + +Solving a MIP problem may take a long time, so the solver reports some +information about best known solutions, which is sent to the terminal. +This information has the following format: + +\begin{verbatim} ++nnn: mip = xxx yyy gap (ppp; qqq) +\end{verbatim} + +\noindent +where: `\verb|nnn|' is the simplex iteration number; `\verb|xxx|' is a +value of the objective function for the best known integer feasible +solution (if no integer feasible solution has been found yet, +`\verb|xxx|' is the text `\verb|not found yet|'); `\verb|rho|' is the +string `\verb|>=|' (in case of minimization) or `\verb|<=|' (in case of +maximization); `\verb|yyy|' is a global bound for exact integer optimum +(i.e. the exact integer optimum is always in the range from `\verb|xxx|' +to `\verb|yyy|'); `\verb|gap|' is the relative mip gap, in percents, +computed as $gap=|xxx-yyy|/(|xxx|+{\tt DBL\_EPSILON})\cdot 100\%$ (if +$gap$ is greater than $999.9\%$, it is not printed); `\verb|ppp|' is the +number of subproblems in the active list, `\verb|qqq|' is the number of +subproblems which have been already fathomed and therefore removed from +the branch-and-bound search tree. + +\newpage + +\subsubsection{Control parameters} + +This paragraph describes all control parameters currently used in the +MIP solver. Symbolic names of control parameters are names of +corresponding members in the structure \verb|glp_iocp|. + +\bigskip\vspace*{-2pt} + +{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL}) + +Message level for terminal output: + +\verb|GLP_MSG_OFF| --- no output; + +\verb|GLP_MSG_ERR| --- error and warning messages only; + +\verb|GLP_MSG_ON | --- normal output; + +\verb|GLP_MSG_ALL| --- full output (including informational messages). + +\bigskip\vspace*{-2pt} + +{\tt int br\_tech} (default: {\tt GLP\_BR\_DTH}) + +Branching technique option: + +\verb|GLP_BR_FFV| --- first fractional variable; + +\verb|GLP_BR_LFV| --- last fractional variable; + +\verb|GLP_BR_MFV| --- most fractional variable; + +\verb|GLP_BR_DTH| --- heuristic by Driebeck and Tomlin; + +\verb|GLP_BR_PCH| --- hybrid pseudo-cost heuristic. + +\bigskip\vspace*{-2pt} + +{\tt int bt\_tech} (default: {\tt GLP\_BT\_BLB}) + +Backtracking technique option: + +\verb|GLP_BT_DFS| --- depth first search; + +\verb|GLP_BT_BFS| --- breadth first search; + +\verb|GLP_BT_BLB| --- best local bound; + +\verb|GLP_BT_BPH| --- best projection heuristic. + +\bigskip\vspace*{-2pt} + +{\tt int pp\_tech} (default: {\tt GLP\_PP\_ALL}) + +Preprocessing technique option: + +\verb|GLP_PP_NONE| --- disable preprocessing; + +\verb|GLP_PP_ROOT| --- perform preprocessing only on the root level; + +\verb|GLP_PP_ALL | --- perform preprocessing on all levels. + +\bigskip\vspace*{-2pt} + +{\tt int sr\_heur} (default: {\tt GLP\_ON}) + +Simple rounding heuristic option: + +\verb|GLP_ON | --- enable applying the simple rounding heuristic; + +\verb|GLP_OFF| --- disable applying the simple rounding heuristic. + +\newpage + +{\tt int fp\_heur} (default: {\tt GLP\_OFF}) + +Feasibility pump heuristic option: + +\verb|GLP_ON | --- enable applying the feasibility pump heuristic; + +\verb|GLP_OFF| --- disable applying the feasibility pump heuristic. + +\bigskip + +{\tt int ps\_heur} (default: {\tt GLP\_OFF}) + +Proximity search heuristic\footnote{The Fischetti--Monaci Proximity +Search (a.k.a. Proxy) heuristic. This algorithm is often capable of +rapidly improving a feasible solution of a MIP problem with binary +variables. It allows to quickly obtain suboptimal solutions in some +problems which take too long time to be solved to optimality.} option: + +\verb|GLP_ON | --- enable applying the proximity search heuristic; + +\verb|GLP_OFF| --- disable applying the proximity search pump heuristic. + +\bigskip + +{\tt int ps\_tm\_lim} (default: {\tt 60000}) + +Time limit, in milliseconds, for the proximity search heuristic (see +above). + +\bigskip + +{\tt int gmi\_cuts} (default: {\tt GLP\_OFF}) + +Gomory's mixed integer cut option: + +\verb|GLP_ON | --- enable generating Gomory's cuts; + +\verb|GLP_OFF| --- disable generating Gomory's cuts. + +\bigskip + +{\tt int mir\_cuts} (default: {\tt GLP\_OFF}) + +Mixed integer rounding (MIR) cut option: + +\verb|GLP_ON | --- enable generating MIR cuts; + +\verb|GLP_OFF| --- disable generating MIR cuts. + +\bigskip + +{\tt int cov\_cuts} (default: {\tt GLP\_OFF}) + +Mixed cover cut option: + +\verb|GLP_ON | --- enable generating mixed cover cuts; + +\verb|GLP_OFF| --- disable generating mixed cover cuts. + +\bigskip + +{\tt int clq\_cuts} (default: {\tt GLP\_OFF}) + +Clique cut option: + +\verb|GLP_ON | --- enable generating clique cuts; + +\verb|GLP_OFF| --- disable generating clique cuts. + +\newpage + +{\tt double tol\_int} (default: {\tt 1e-5}) + +Absolute tolerance used to check if optimal solution to the current LP +relaxation is integer feasible. (Do not change this parameter without +detailed understanding its purpose.) + +\bigskip + +{\tt double tol\_obj} (default: {\tt 1e-7}) + +Relative tolerance used to check if the objective value in optimal +solution to the current LP relaxation is not better than in the best +known integer feasible solution. (Do not change this parameter without +detailed understanding its purpose.) + +\bigskip + +{\tt double mip\_gap} (default: {\tt 0.0}) + +The relative mip gap tolerance. If the relative mip gap for currently +known best integer feasible solution falls below this tolerance, the +solver terminates the search. This allows obtainig suboptimal integer +feasible solutions if solving the problem to optimality takes too long +time. + +\bigskip + +{\tt int tm\_lim} (default: {\tt INT\_MAX}) + +Searching time limit, in milliseconds. + +\bigskip + +{\tt int out\_frq} (default: {\tt 5000}) + +Output frequency, in milliseconds. This parameter specifies how +frequently the solver sends information about the solution process to +the terminal. + +\bigskip + +{\tt int out\_dly} (default: {\tt 10000}) + +Output delay, in milliseconds. This parameter specifies how long the +solver should delay sending information about solution of the current +LP relaxation with the simplex method to the terminal. + +\bigskip + +{\tt void (*cb\_func)(glp\_tree *tree, void *info)} +(default: {\tt NULL}) + +Entry point to the user-defined callback routine. \verb|NULL| means +the advanced solver interface is not used. For more details see Chapter +``Branch-and-Cut API Routines''. + +\bigskip + +{\tt void *cb\_info} (default: {\tt NULL}) + +Transit pointer passed to the routine \verb|cb_func| (see above). + +\bigskip + +{\tt int cb\_size} (default: {\tt 0}) + +The number of extra (up to 256) bytes allocated for each node of the +branch-and-bound tree to store application-specific data. On creating +a node these bytes are initialized by binary zeros. + +\bigskip + +{\tt int presolve} (default: {\tt GLP\_OFF}) + +MIP presolver option: + +\verb|GLP_ON | --- enable using the MIP presolver; + +\verb|GLP_OFF| --- disable using the MIP presolver. + +\newpage + +{\tt int binarize} (default: {\tt GLP\_OFF}) + +Binarization option (used only if the presolver is enabled): + +\verb|GLP_ON | --- replace general integer variables by binary ones; + +\verb|GLP_OFF| --- do not use binarization. + +\subsection{glp\_init\_iocp --- initialize integer optimizer control +parameters} + +\synopsis + +\begin{verbatim} + void glp_init_iocp(glp_iocp *parm); +\end{verbatim} + +\description + +The routine \verb|glp_init_iocp| initializes control parameters, which +are used by the branch-and-cut solver, with default values. + +Default values of the control parameters are stored in +a \verb|glp_iocp| structure, which the parameter \verb|parm| points to. + +\subsection{glp\_mip\_status --- determine status of MIP solution} + +\synopsis + +\begin{verbatim} + int glp_mip_status(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_mip_status| reports the status of a MIP solution +found by the MIP solver as follows: + +\verb|GLP_UNDEF | --- MIP solution is undefined; + +\verb|GLP_OPT | --- MIP solution is integer optimal; + +\verb|GLP_FEAS | --- MIP solution is integer feasible, however, its +optimality (or non-optimality) has not been proven, perhaps due to +premature termination of the search; + +\verb|GLP_NOFEAS| --- problem has no integer feasible solution (proven +by the solver). + +\subsection{glp\_mip\_obj\_val --- retrieve objective value} + +\synopsis + +\begin{verbatim} + double glp_mip_obj_val(glp_prob *P); +\end{verbatim} + +\returns + +The routine \verb|glp_mip_obj_val| returns value of the objective +function for MIP solution. + +\subsection{glp\_mip\_row\_val --- retrieve row value} + +\synopsis + +\begin{verbatim} + double glp_mip_row_val(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_mip_row_val| returns value of the auxiliary +variable associated with \verb|i|-th row for MIP solution. + +\subsection{glp\_mip\_col\_val --- retrieve column value} + +\synopsis + +\begin{verbatim} + double glp_mip_col_val(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_mip_col_val| returns value of the structural +variable associated with \verb|j|-th column for MIP solution. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Additional routines} + +\subsection{glp\_check\_kkt --- check feasibility/optimality +conditions} + +\synopsis + +{\parskip=0pt +\tt void glp\_check\_kkt(glp\_prob *P, int sol, int cond, +double *ae\_max, int *ae\_ind, + +\hspace{105pt}double *re\_max, int *re\_ind);} + +\description + +The routine \verb|glp_check_kkt| allows to check +feasibility/optimality conditions for the current solution stored in +the specified problem object. (For basic and interior-point solutions +these conditions are known as {\it Karush--Kuhn--Tucker optimality +conditions}.) + +The parameter \verb|sol| specifies which solution should be checked: + +\verb|GLP_SOL| --- basic solution; + +\verb|GLP_IPT| --- interior-point solution; + +\verb|GLP_MIP| --- mixed integer solution. + +The parameter \verb|cond| specifies which condition should be checked: + +\verb|GLP_KKT_PE| --- check primal equality constraints (KKT.PE); + +\verb|GLP_KKT_PB| --- check primal bound constraints (KKT.PB); + +\verb|GLP_KKT_DE| --- check dual equality constraints (KKT.DE). This +conditions can be checked only for basic or interior-point solution; + +\verb|GLP_KKT_DB| --- check dual bound constraints (KKT.DB). This +conditions can be checked only for basic or interior-point solution. + +Detailed explanations of these conditions are given below in paragraph +``Background''. + +On exit the routine stores the following information to locations +specified by parameters \verb|ae_max|, \verb|ae_ind|, \verb|re_max|, +and \verb|re_ind| (if some parameter is a null pointer, corresponding +information is not stored): + +\verb|ae_max| --- largest absolute error; + +\verb|ae_ind| --- number of row (KKT.PE), column (KKT.DE), or variable +(KKT.PB, KKT.DB) with the largest absolute error; + +\verb|re_max| --- largest relative error; + +\verb|re_ind| --- number of row (KKT.PE), column (KKT.DE), or variable +(KKT.PB, KKT.DB) with the largest relative error. + +Row (auxiliary variable) numbers are in the range 1 to $m$, where $m$ +is the number of rows in the problem object. Column (structural +variable) numbers are in the range 1 to $n$, where $n$ is the number +of columns in the problem object. Variable numbers are in the range +1 to $m+n$, where variables with numbers 1 to $m$ correspond to rows, +and variables with numbers $m+1$ to $m+n$ correspond to columns. If +the error reported is exact zero, corresponding row, column or variable +number is set to zero. + +\para{Background} + +\def\arraystretch{1.5} + +The first condition checked by the routine is the following: +$$x_R - A x_S = 0, \eqno{\rm (KKT.PE)}$$ +where $x_R$ is the subvector of auxiliary variables (rows), $x_S$ is +the subvector of structural variables (columns), $A$ is the constraint +matrix. This condition expresses the requirement that all primal +variables should satisfy to the system of equality constraints of the +original LP problem. In case of exact arithmetic this condition would +be satisfied for any basic solution; however, in case of inexact +(floating-point) arithmetic, this condition shows how accurate the +primal solution is, that depends on accuracy of a representation of the +basis matrix used by the simplex method, or on accuracy provided by the +interior-point method. + +To check the condition (KKT.PE) the routine computes the vector of +residuals: +$$g = x_R - A x_S,$$ +and determines component of this vector that correspond to largest +absolute and relative errors: +$${\tt ae\_max}=\max_{1\leq i\leq m}|g_i|,$$ +$${\tt re\_max}=\max_{1\leq i\leq m}\frac{|g_i|}{1+|(x_R)_i|}.$$ + +The second condition checked by the routine is the following: +$$l_k \leq x_k \leq u_k {\rm \ \ \ for\ all}\ k=1,\dots,m+n, +\eqno{\rm (KKT.PB)}$$ +where $x_k$ is auxiliary ($1\leq k\leq m$) or structural +($m+1\leq k\leq m+n$) variable, $l_k$ and $u_k$ are, respectively, +lower and upper bounds of the variable $x_k$ (including cases of +infinite bounds). This condition expresses the requirement that all +primal variables shoudl satisfy to bound constraints of the original +LP problem. In case of basic solution all non-basic variables are +placed on their active bounds, so actually the condition (KKT.PB) needs +to be checked for basic variables only. If the primal solution has +sufficient accuracy, this condition shows its primal feasibility. + +To check the condition (KKT.PB) the routine computes a vector of +residuals: +$$ +h_k = \left\{ +\begin{array}{ll} +0, & {\rm if}\ l_k \leq x_k \leq u_k \\ +x_k - l_k, & {\rm if}\ x_k < l_k \\ +x_k - u_k, & {\rm if}\ x_k > u_k \\ +\end{array} +\right. +$$ +for all $k=1,\dots,m+n$, and determines components of this vector that +correspond to largest absolute and relative errors: +$${\tt ae\_max}=\max_{1\leq k \leq m+n}|h_k|,$$ +$${\tt re\_max}=\max_{1\leq k \leq m+n}\frac{|h_k|}{1+|x_k|}.$$ + +The third condition checked by the routine is: +$${\rm grad}\;Z = c = (\tilde{A})^T \pi + d,$$ +where $Z$ is the objective function, $c$ is the vector of objective +coefficients, $(\tilde{A})^T$ is a matrix transposed to the expanded +constraint matrix $\tilde{A} = (I|-A)$, $\pi$ is a vector of Lagrange +multipliers that correspond to equality constraints of the original LP +problem, $d$ is a vector of Lagrange multipliers that correspond to +bound constraints for all (auxiliary and structural) variables of the +original LP problem. Geometrically the third condition expresses the +requirement that the gradient of the objective function should belong +to the orthogonal complement of a linear subspace defined by the +equality and active bound constraints, i.e. that the gradient is +a linear combination of normals to the constraint hyperplanes, where +Lagrange multipliers $\pi$ and $d$ are coefficients of that linear +combination. + +To eliminate the vector $\pi$ rewrite the third condition as: +$$ +\left(\begin{array}{@{}c@{}}I \\ -A^T\end{array}\right) \pi = +\left(\begin{array}{@{}c@{}}d_R \\ d_S\end{array}\right) + +\left(\begin{array}{@{}c@{}}c_R \\ c_S\end{array}\right), +$$ +or, equivalently, +$$ +\left\{ +\begin{array}{r@{}c@{}c} +\pi + d_R&\ =\ &c_R, \\ +-A^T\pi + d_S&\ =\ &c_S. \\ +\end{array} +\right. +$$ + +Then substituting the vector $\pi$ from the first equation into the +second we finally have: +$$A^T (d_R - c_R) + (d_S - c_S) = 0, \eqno{\rm(KKT.DE)}$$ +where $d_R$ is the subvector of reduced costs of auxiliary variables +(rows), $d_S$ is the subvector of reduced costs of structural variables +(columns), $c_R$ and $c_S$ are subvectors of objective coefficients at, +respectively, auxiliary and structural variables, $A^T$ is a matrix +transposed to the constraint matrix of the original LP problem. In case +of exact arithmetic this condition would be satisfied for any basic +solution; however, in case of inexact (floating-point) arithmetic, this +condition shows how accurate the dual solution is, that depends on +accuracy of a representation of the basis matrix used by the simplex +method, or on accuracy provided by the interior-point method. + +To check the condition (KKT.DE) the routine computes a vector of +residuals: +$$u = A^T (d_R - c_R) + (d_S - c_S),$$ +and determines components of this vector that correspond to largest +absolute and relative errors: +$${\tt ae\_max}=\max_{1\leq j\leq n}|u_j|,$$ +$${\tt re\_max}=\max_{1\leq j\leq n}\frac{|u_j|}{1+|(d_S)_j-(c_S)_j|}.$$ + +\newpage + +The fourth condition checked by the routine is the following: +$$ +\left\{ +\begin{array}{l@{\ }r@{\ }c@{\ }c@{\ }c@{\ }l@{\ }c@{\ }c@{\ }c@{\ }l} +{\rm if} & -\infty & < & x_k & < & +\infty, +& {\rm then} & d_k & = & 0 \\ +{\rm if} & l_k & \leq & x_k & < & +\infty, +& {\rm then} & d_k & \geq & 0\ {\rm(minimization)} \\ +&&&&&& & d_k & \leq & 0\ {\rm(maximization)} \\ +{\rm if} & -\infty & < & x_k & \leq & u_k, +& {\rm then} & d_k & \leq & 0\ {\rm(minimization)} \\ +&&&&&& & d_k & \geq & 0\ {\rm(maximization)} \\ +{\rm if} & l_k & \leq & x_k & \leq & u_k, +& {\rm then} & d_k & {\rm is} & {\rm of\ any\ sign} \\ +\end{array}\right.\eqno{\rm(KKT.DB)} +$$ +for all $k=1,\dots,m+n$, where $d_k$ is a reduced cost (Lagrange +multiplier) of auxiliary ($1\leq k\leq m$) or structural +($m+1\leq k\leq m+n$) variable $x_k$. Geometrically this condition +expresses the requirement that constraints of the original problem must +``hold'' the point preventing its movement along the anti-gradient (in +case of minimization) or the gradient (in case of maximization) of the +objective function. In case of basic solution reduced costs of all +basic variables are placed on their active (zero) bounds, so actually +the condition (KKT.DB) needs to be checked for non-basic variables +only. If the dual solution has sufficient accuracy, this condition +shows the dual feasibility of the solution. + +To check the condition (KKT.DB) the routine computes a vector of +residuals: +$$ +v_k = \left\{ +\begin{array}{ll} +0, & {\rm if}\ d_k\ {\rm has\ correct\ sign} \\ +|d_k|, & {\rm if}\ d_k\ {\rm has\ wrong\ sign} \\ +\end{array} +\right. +$$ +for all $k=1,\dots,m+n$, and determines components of this vector that +correspond to largest absolute and relative errors: +$${\tt ae\_max}=\max_{1\leq k\leq m+n}|v_k|,$$ +$${\tt re\_max}=\max_{1\leq k\leq m+n}\frac{|v_k|}{1+|d_k - c_k|}.$$ + +Note that the complete set of Karush-Kuhn-Tucker optimality conditions +also includes the fifth, so called {\it complementary slackness +condition}, which expresses the requirement that at least either +a primal variable $x_k$ or its dual counterpart $d_k$ should be on its +bound for all $k=1,\dots,m+n$. Currently checking this condition is +not implemented yet. + +\def\arraystretch{1} + +%* eof *% diff --git a/resources/3rdparty/glpk-4.57/doc/glpk03.tex b/resources/3rdparty/glpk-4.57/doc/glpk03.tex new file mode 100644 index 000000000..82848a14b --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/glpk03.tex @@ -0,0 +1,1572 @@ +%* glpk03.tex *% + +\chapter{Utility API routines} + +\section{Problem data reading/writing routines} + +\subsection{glp\_read\_mps --- read problem data in MPS format} + +\synopsis + +\begin{verbatim} + int glp_read_mps(glp_prob *P, int fmt, const glp_mpscp *parm, + const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_read_mps| reads problem data in MPS format from a +text file. (The MPS format is described in Appendix \ref{champs}, page +\pageref{champs}.) + +The parameter \verb|fmt| specifies the MPS format version as follows: + +\verb|GLP_MPS_DECK| --- fixed (ancient) MPS format; + +\verb|GLP_MPS_FILE| --- free (modern) MPS format. + +The parameter \verb|parm| is reserved for use in the future and should +be specified as \verb|NULL|. + +The character string \verb|fname| specifies a name of the text file to +be read in. (If the file name ends with suffix `\verb|.gz|', the file +is assumed to be compressed, in which case the routine +\verb|glp_read_mps| decompresses it ``on the fly''.) + +Note that before reading data the current content of the problem object +is completely erased with the routine \verb|glp_erase_prob|. + +\returns + +If the operation was successful, the routine \verb|glp_read_mps| +returns zero. Otherwise, it prints an error message and returns +non-zero. + +\newpage + +\subsection{glp\_write\_mps --- write problem data in MPS format} + +\synopsis + +\begin{verbatim} + int glp_write_mps(glp_prob *P, int fmt, const glp_mpscp *parm, + const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_write_mps| writes problem data in MPS format to +a text file. (The MPS format is described in Appendix \ref{champs}, +page \pageref{champs}.) + +The parameter \verb|fmt| specifies the MPS format version as follows: + +\verb|GLP_MPS_DECK| --- fixed (ancient) MPS format; + +\verb|GLP_MPS_FILE| --- free (modern) MPS format. + +The parameter \verb|parm| is reserved for use in the future and should +be specified as \verb|NULL|. + +The character string \verb|fname| specifies a name of the text file to +be written out. (If the file name ends with suffix `\verb|.gz|', the +file is assumed to be compressed, in which case the routine +\verb|glp_write_mps| performs automatic compression on writing it.) + +\returns + +If the operation was successful, the routine \verb|glp_write_mps| +returns zero. Otherwise, it prints an error message and returns +non-zero. + +\subsection{glp\_read\_lp --- read problem data in CPLEX LP format} + +\synopsis + +{\tt int glp\_read\_lp(glp\_prob *P, const glp\_cpxcp *parm, +const char *fname);} + +\description + +The routine \verb|glp_read_lp| reads problem data in CPLEX LP format +from a text file. (The CPLEX LP format is described in Appendix +\ref{chacplex}, page \pageref{chacplex}.) + +The parameter \verb|parm| is reserved for use in the future and should +be specified as \verb|NULL|. + +The character string \verb|fname| specifies a name of the text file to +be read in. (If the file name ends with suffix `\verb|.gz|', the file +is assumed to be compressed, in which case the routine +\verb|glp_read_lp| decompresses it ``on the fly''.) + +Note that before reading data the current content of the problem object +is completely erased with the routine \verb|glp_erase_prob|. + +\returns + +If the operation was successful, the routine \verb|glp_read_lp| returns +zero. Otherwise, it prints an error message and returns non-zero. + +\newpage + +\subsection{glp\_write\_lp --- write problem data in CPLEX LP format} + +\synopsis + +{\tt int glp\_write\_lp(glp\_prob *P, const glp\_cpxcp *parm, +const char *fname);} + +\description + +The routine \verb|glp_write_lp| writes problem data in CPLEX LP format +to a text file. (The CPLEX LP format is described in Appendix +\ref{chacplex}, page \pageref{chacplex}.) + +The parameter \verb|parm| is reserved for use in the future and should +be specified as \verb|NULL|. + +The character string \verb|fname| specifies a name of the text file to +be written out. (If the file name ends with suffix `\verb|.gz|', the +file is assumed to be compressed, in which case the routine +\verb|glp_write_lp| performs automatic compression on writing it.) + +\returns + +If the operation was successful, the routine \verb|glp_write_lp| +returns zero. Otherwise, it prints an error message and returns +non-zero. + +\subsection{glp\_read\_prob --- read problem data in GLPK format} + +\synopsis + +\begin{verbatim} + int glp_read_prob(glp_prob *P, int flags, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_read_prob| reads problem data in the GLPK LP/MIP +format from a text file. (For description of the GLPK LP/MIP format see +below.) + +The parameter \verb|flags| is reserved for use in the future and should +be specified as zero. + +The character string \verb|fname| specifies a name of the text file to +be read in. (If the file name ends with suffix `\verb|.gz|', the file +is assumed to be compressed, in which case the routine +\verb|glp_read_prob| decompresses it ``on the fly''.) + +Note that before reading data the current content of the problem object +is completely erased with the routine \verb|glp_erase_prob|. + +\returns + +If the operation was successful, the routine \verb|glp_read_prob| +returns zero. Otherwise, it prints an error message and returns +non-zero. + +\newpage + +\para{GLPK LP/MIP format} + +The GLPK LP/MIP format is a DIMACS-like format.\footnote{The DIMACS +formats were developed by the Center for Discrete Mathematics and +Theoretical Computer Science (DIMACS) to facilitate exchange of problem +data. For details see: {\tt }. } +The file in this format is a plain ASCII text file containing lines of +several types described below. A line is terminated with the +end-of-line character. Fields in each line are separated by at least +one blank space. Each line begins with a one-character designator to +identify the line type. + +The first line of the data file must be the problem line (except +optional comment lines, which may precede the problem line). The last +line of the data file must be the end line. Other lines may follow in +arbitrary order, however, duplicate lines are not allowed. + +\para{Comment lines.} Comment lines give human-readable +information about the data file and are ignored by GLPK routines. +Comment lines can appear anywhere in the data file. Each comment line +begins with the lower-case character \verb|c|. + +\begin{verbatim} + c This is an example of comment line +\end{verbatim} + +\para{Problem line.} There must be exactly one problem line in the +data file. This line must appear before any other lines except comment +lines and has the following format: + +\begin{verbatim} + p CLASS DIR ROWS COLS NONZ +\end{verbatim} + +The lower-case letter \verb|p| specifies that this is the problem line. + +The \verb|CLASS| field defines the problem class and can contain either +the keyword \verb|lp| (that means linear programming problem) or +\verb|mip| (that means mixed integer programming problem). + +The \verb|DIR| field defines the optimization direction (that is, the +objective function sense) and can contain either the keyword \verb|min| +(that means minimization) or \verb|max| (that means maximization). + +The \verb|ROWS|, \verb|COLS|, and \verb|NONZ| fields contain +non-negative integer values specifying, respectively, the number of +rows (constraints), columns (variables), and non-zero constraint +coefficients in the problem instance. Note that \verb|NONZ| value does +not account objective coefficients. + +\para{Row descriptors.} There must be at most one row descriptor line +in the data file for each row (constraint). This line has one of the +following formats: + +\begin{verbatim} + i ROW f + i ROW l RHS + i ROW u RHS + i ROW d RHS1 RHS2 + i ROW s RHS +\end{verbatim} + +The lower-case letter \verb|i| specifies that this is the row +descriptor line. + +The \verb|ROW| field specifies the row ordinal number, an integer +between 1 and $m$, where $m$ is the number of rows in the problem +instance. + +The next lower-case letter specifies the row type as follows: + +\verb|f| --- free (unbounded) row: $-\infty<\sum a_jx_j<+\infty$; + +\verb|l| --- inequality constraint of `$\geq$' type: +$\sum a_jx_j\geq b$; + +\verb|u| --- inequality constraint of `$\leq$' type: +$\sum a_jx_j\leq b$; + +\verb|d| --- double-sided inequality constraint: +$b_1\leq\sum a_jx_j\leq b_2$; + +\verb|s| --- equality constraint: $\sum a_jx_j=b$. + +The \verb|RHS| field contains a floaing-point value specifying the +row right-hand side. The \verb|RHS1| and \verb|RHS2| fields contain +floating-point values specifying, respectively, the lower and upper +right-hand sides for the double-sided row. + +If for some row its descriptor line does not appear in the data file, +by default that row is assumed to be an equality constraint with zero +right-hand side. + +\para{Column descriptors.} There must be at most one column descriptor +line in the data file for each column (variable). This line has one of +the following formats depending on the problem class specified in the +problem line: + +\begin{tabular}{@{}l@{\hspace*{40pt}}l} +LP class & MIP class \\ +\hline +\verb|j COL f| & \verb|j COL KIND f| \\ +\verb|j COL l BND| & \verb|j COL KIND l BND| \\ +\verb|j COL u BND| & \verb|j COL KIND u BND| \\ +\verb|j COL d BND1 BND2| & \verb|j COL KIND d BND1 BND2| \\ +\verb|j COL s BND| & \verb|j COL KIND s BND| \\ +\end{tabular} + +The lower-case letter \verb|j| specifies that this is the column +descriptor line. + +The \verb|COL| field specifies the column ordinal number, an integer +between 1 and $n$, where $n$ is the number of columns in the problem +instance. + +The \verb|KIND| field is used only for MIP problems and specifies the +column kind as follows: + +\verb|c| --- continuous column; + +\verb|i| --- integer column; + +\verb|b| --- binary column (in this case all remaining fields must be +omitted). + +The next lower-case letter specifies the column type as follows: + +\verb|f| --- free (unbounded) column: $-\infty +#include +#include + +int main(void) +{ glp_prob *lp; + glp_tran *tran; + int ret; + lp = glp_create_prob(); + tran = glp_mpl_alloc_wksp(); + ret = glp_mpl_read_model(tran, "egypt.mod", 0); + if (ret != 0) + { fprintf(stderr, "Error on translating model\n"); + goto skip; + } + ret = glp_mpl_generate(tran, NULL); + if (ret != 0) + { fprintf(stderr, "Error on generating model\n"); + goto skip; + } + glp_mpl_build_prob(tran, lp); + ret = glp_write_mps(lp, GLP_MPS_FILE, NULL, "egypt.mps"); + if (ret != 0) + fprintf(stderr, "Error on writing MPS file\n"); +skip: glp_mpl_free_wksp(tran); + glp_delete_prob(lp); + return 0; +} + +/* eof */ +\end{verbatim} +\end{small} + +\newpage + +\subsubsection*{Example 2} + +In this example the program reads model section from file +\verb|sudoku.mod|\footnote{This is an example model which is included +in the GLPK distribution along with alternative data file +{\tt sudoku.dat}.} ignoring data section in this file, reads alternative +data section from file \verb|sudoku.dat|, solves the problem instance +and passes the solution found back to the model. + +\bigskip + +\begin{small} +\begin{verbatim} +/* mplsamp2.c */ + +#include +#include +#include + +int main(void) +{ glp_prob *mip; + glp_tran *tran; + int ret; + mip = glp_create_prob(); + tran = glp_mpl_alloc_wksp(); + ret = glp_mpl_read_model(tran, "sudoku.mod", 1); + if (ret != 0) + { fprintf(stderr, "Error on translating model\n"); + goto skip; + } + ret = glp_mpl_read_data(tran, "sudoku.dat"); + if (ret != 0) + { fprintf(stderr, "Error on translating data\n"); + goto skip; + } + ret = glp_mpl_generate(tran, NULL); + if (ret != 0) + { fprintf(stderr, "Error on generating model\n"); + goto skip; + } + glp_mpl_build_prob(tran, mip); + glp_simplex(mip, NULL); + glp_intopt(mip, NULL); + ret = glp_mpl_postsolve(tran, mip, GLP_MIP); + if (ret != 0) + fprintf(stderr, "Error on postsolving model\n"); +skip: glp_mpl_free_wksp(tran); + glp_delete_prob(mip); + return 0; +} + +/* eof */ +\end{verbatim} +\end{small} + +\newpage + +\subsection{glp\_mpl\_alloc\_wksp --- allocate the translator +workspace} + +\synopsis + +\begin{verbatim} + glp_tran *glp_mpl_alloc_wksp(void); +\end{verbatim} + +\description + +The routine \verb|glp_mpl_alloc_wksp| allocates the MathProg translator +work\-space. (Note that multiple instances of the workspace may be +allocated, if necessary.) + +\returns + +The routine returns a pointer to the workspace, which should be used in +all subsequent operations. + +\subsection{glp\_mpl\_read\_model --- read and translate model section} + +\synopsis + +\begin{verbatim} + int glp_mpl_read_model(glp_tran *tran, const char *fname, int skip); +\end{verbatim} + +\description + +The routine \verb|glp_mpl_read_model| reads model section and, +optionally, data section, which may follow the model section, from a +text file, whose name is the character string \verb|fname|, performs +translation of model statements and data blocks, and stores all the +information in the workspace. + +The parameter \verb|skip| is a flag. If the input file contains the +data section and this flag is non-zero, the data section is not read as +if there were no data section and a warning message is printed. This +allows reading data section(s) from other file(s). + +\returns + +If the operation is successful, the routine returns zero. Otherwise +the routine prints an error message and returns non-zero. + +\subsection{glp\_mpl\_read\_data --- read and translate data section} + +\synopsis + +\begin{verbatim} + int glp_mpl_read_data(glp_tran *tran, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_mpl_read_data| reads data section from a text +file, whose name is the character string \verb|fname|, performs +translation of data blocks, and stores the data read in the translator +workspace. If necessary, this routine may be called more than once. + +\returns + +If the operation is successful, the routine returns zero. Otherwise +the routine prints an error message and returns non-zero. + +\newpage + +\subsection{glp\_mpl\_generate --- generate the model} + +\synopsis + +\begin{verbatim} + int glp_mpl_generate(glp_tran *tran, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_mpl_generate| generates the model using its +description stored in the translator workspace. This operation means +generating all variables, constraints, and objectives, executing check +and display statements, which precede the solve statement (if it is +presented). + +The character string \verb|fname| specifies the name of an output text +file, to which output produced by display statements should be written. +If \verb|fname| is \verb|NULL|, the output is sent to the terminal. + +\returns + +If the operation is successful, the routine returns zero. Otherwise +the routine prints an error message and returns non-zero. + +\vspace*{-6pt} + +\subsection{glp\_mpl\_build\_prob --- build problem instance from the +model} + +\synopsis + +\begin{verbatim} + void glp_mpl_build_prob(glp_tran *tran, glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_mpl_build_prob| obtains all necessary information +from the translator work\-space and stores it in the specified problem +object \verb|P|. Note that before building the current content of the +problem object is erased with the routine \verb|glp_erase_prob|. + +\vspace*{-6pt} + +\subsection{glp\_mpl\_postsolve --- postsolve the model} + +\synopsis + +\begin{verbatim} + int glp_mpl_postsolve(glp_tran *tran, glp_prob *P, int sol); +\end{verbatim} + +\description + +The routine \verb|glp_mpl_postsolve| copies the solution from the +specified problem object \verb|prob| to the translator workspace and +then executes all the remaining model statements, which follow the +solve statement. + +The parameter \verb|sol| specifies which solution should be copied +from the problem object to the workspace as follows: + +\verb|GLP_SOL| --- basic solution; + +\verb|GLP_IPT| --- interior-point solution; + +\verb|GLP_MIP| --- mixed integer solution. + +\returns + +If the operation is successful, the routine returns zero. Otherwise +the routine prints an error message and returns non-zero. + +\subsection{glp\_mpl\_free\_wksp --- free the translator workspace} + +\synopsis + +\begin{verbatim} + void glp_mpl_free_wksp(glp_tran *tran); +\end{verbatim} + +\description + +The routine \verb|glp_mpl_free_wksp| frees all the memory allocated to +the translator workspace. It also frees all other resources, which are +still used by the translator. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Problem solution reading/writing routines} + +\subsection{glp\_print\_sol --- write basic solution in printable +format} + +\synopsis + +\begin{verbatim} + int glp_print_sol(glp_prob *P, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_print_sol writes| the current basic solution of +an LP problem, which is specified by the pointer \verb|P|, to a text +file, whose name is the character string \verb|fname|, in printable +format. + +Information reported by the routine \verb|glp_print_sol| is intended +mainly for visual analysis. + +\returns + +If no errors occurred, the routine returns zero. Otherwise the routine +prints an error message and returns non-zero. + +\subsection{glp\_read\_sol --- read basic solution from text file} + +\synopsis + +\begin{verbatim} + int glp_read_sol(glp_prob *P, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_read_sol| reads basic solution from a text file +whose name is specified by the parameter \verb|fname| into the problem +object. + +For the file format see description of the routine +\verb|glp_write_sol|. + +\returns + +On success the routine returns zero, otherwise non-zero. + +\subsection{glp\_write\_sol --- write basic solution to text file} + +\synopsis + +\begin{verbatim} + int glp_write_sol(glp_prob *P, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_write_sol| writes the current basic solution to +a text file whose name is specified by the parameter \verb|fname|. This +file can be read back with the routine \verb|glp_read_sol|. + +\returns + +On success the routine returns zero, otherwise non-zero. + +\newpage + +\para{File format} + +The file created by the routine \verb|glp_write_sol| is a plain text +file, which contains the following information: + +\begin{verbatim} + m n + p_stat d_stat obj_val + r_stat[1] r_prim[1] r_dual[1] + . . . + r_stat[m] r_prim[m] r_dual[m] + c_stat[1] c_prim[1] c_dual[1] + . . . + c_stat[n] c_prim[n] c_dual[n] +\end{verbatim} + +\noindent +where: + +\noindent +$m$ is the number of rows (auxiliary variables); + +\noindent +$n$ is the number of columns (structural variables); + +\noindent +\verb|p_stat| is the primal status of the basic solution\\ +(\verb|GLP_UNDEF| = 1, \verb|GLP_FEAS| = 2, \verb|GLP_INFEAS| = 3, or +\verb|GLP_NOFEAS| = 4); + +\noindent +\verb|d_stat| is the dual status of the basic solution\\ +(\verb|GLP_UNDEF| = 1, \verb|GLP_FEAS| = 2, \verb|GLP_INFEAS| = 3, or +\verb|GLP_NOFEAS| = 4); + +\noindent +\verb|obj_val| is the objective value; + +\noindent +\verb|r_stat[i]|, $i=1,\dots,m$, is the status of $i$-th row\\ +(\verb|GLP_BS| = 1, \verb|GLP_NL| = 2, \verb|GLP_NU| = 3, +\verb|GLP_NF| = 4, or \verb|GLP_NS| = 5); + +\noindent +\verb|r_prim[i]|, $i=1,\dots,m$, is the primal value of $i$-th row; + +\noindent +\verb|r_dual[i]|, $i=1,\dots,m$, is the dual value of $i$-th row; + +\noindent +\verb|c_stat[j]|, $j=1,\dots,n$, is the status of $j$-th column\\ +(\verb|GLP_BS| = 1, \verb|GLP_NL| = 2, \verb|GLP_NU| = 3, +\verb|GLP_NF| = 4, or \verb|GLP_NS| = 5); + +\noindent +\verb|c_prim[j]|, $j=1,\dots,n$, is the primal value of $j$-th column; + +\noindent +\verb|c_dual[j]|, $j=1,\dots,n$, is the dual value of $j$-th column. + +\subsection{glp\_print\_ipt --- write interior-point solution in +printable format} + +\synopsis + +\begin{verbatim} + int glp_print_ipt(glp_prob *P, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_print_ipt| writes the current interior point +solution of an LP problem, which the parameter \verb|P| points to, to +a text file, whose name is the character string \verb|fname|, in +printable format. + +Information reported by the routine \verb|glp_print_ipt| is intended +mainly for visual analysis. + +\newpage + +\returns + +If no errors occurred, the routine returns zero. Otherwise the routine +prints an error message and returns non-zero. + +\subsection{glp\_read\_ipt --- read interior-point solution from text +file} + +\synopsis + +\begin{verbatim} + int glp_read_ipt(glp_prob *P, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_read_ipt| reads interior-point solution from +a text file whose name is specified by the parameter \verb|fname| into +the problem object. + +For the file format see description of the routine +\verb|glp_write_ipt|. + +\returns + +On success the routine returns zero, otherwise non-zero. + +\subsection{glp\_write\_ipt --- write interior-point solution to text +file} + +\synopsis + +\begin{verbatim} + int glp_write_ipt(glp_prob *P, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_write_ipt| writes the current interior-point +solution to a text file whose name is specified by the parameter +\verb|fname|. This file can be read back with the routine +\verb|glp_read_ipt|. + +\returns + +On success the routine returns zero, otherwise non-zero. + +\para{File format} + +The file created by the routine \verb|glp_write_ipt| is a plain text +file, which contains the following information: + +\begin{verbatim} + m n + stat obj_val + r_prim[1] r_dual[1] + . . . + r_prim[m] r_dual[m] + c_prim[1] c_dual[1] + . . . + c_prim[n] c_dual[n] +\end{verbatim} + +\noindent +where: + +\noindent +$m$ is the number of rows (auxiliary variables); + +\noindent +$n$ is the number of columns (structural variables); + +\noindent +\verb|stat| is the solution status (\verb|GLP_UNDEF| = 1 or +\verb|GLP_OPT| = 5); + +\noindent +\verb|obj_val| is the objective value; + +\noindent +\verb|r_prim[i]|, $i=1,\dots,m$, is the primal value of $i$-th row; + +\noindent +\verb|r_dual[i]|, $i=1,\dots,m$, is the dual value of $i$-th row; + +\noindent +\verb|c_prim[j]|, $j=1,\dots,n$, is the primal value of $j$-th column; + +\noindent +\verb|c_dual[j]|, $j=1,\dots,n$, is the dual value of $j$-th column. + +\subsection{glp\_print\_mip --- write MIP solution in printable format} + +\synopsis + +\begin{verbatim} + int glp_print_mip(glp_prob *P, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_print_mip| writes a best known integer solution +of a MIP problem, which is specified by the pointer \verb|P|, to +a text file, whose name is the character string \verb|fname|, in +printable format. + +Information reported by the routine \verb|glp_print_mip| is intended +mainly for visual analysis. + +\returns + +If no errors occurred, the routine returns zero. Otherwise the routine +prints an error message and returns non-zero. + +\subsection{glp\_read\_mip --- read MIP solution from text file} + +\synopsis + +\begin{verbatim} + int glp_read_mip(glp_prob *P, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_read_mip| reads MIP solution from a text file +whose name is specified by the parameter \verb|fname| into the problem +object. + +For the file format see description of the routine +\verb|glp_write_mip|. + +\returns + +On success the routine returns zero, otherwise non-zero. + +\newpage + +\subsection{glp\_write\_mip --- write MIP solution to text file} + +\synopsis + +\begin{verbatim} + int glp_write_mip(glp_prob *P, const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_write_mip| writes the current MIP solution to +a text file whose name is specified by the parameter \verb|fname|. This +file can be read back with the routine \verb|glp_read_mip|. + +\returns + +On success the routine returns zero, otherwise non-zero. + +\para{File format} + +The file created by the routine \verb|glp_write_sol| is a plain text +file, which contains the following information: + +\begin{verbatim} + m n + stat obj_val + r_val[1] + . . . + r_val[m] + c_val[1] + . . . + c_val[n] +\end{verbatim} + +\noindent +where: + +\noindent +$m$ is the number of rows (auxiliary variables); + +\noindent +$n$ is the number of columns (structural variables); + +\noindent +\verb|stat| is the solution status\\(\verb|GLP_UNDEF| = 1, +\verb|GLP_FEAS| = 2, \verb|GLP_NOFEAS| = 4, or \verb|GLP_OPT| = 5); + +\noindent +\verb|obj_val| is the objective value; + +\noindent +\verb|r_val[i]|, $i=1,\dots,m$, is the value of $i$-th row; + +\noindent +\verb|c_val[j]|, $j=1,\dots,n$, is the value of $j$-th column. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Post-optimal analysis routines} + +\subsection{glp\_print\_ranges --- print sensitivity analysis report} + +\synopsis + +{\tt int glp\_print\_ranges(glp\_prob *P, int len, const int list[], +int flags,\\ +\hspace*{134pt}const char *fname);} + +\description + +The routine \verb|glp_print_ranges| performs sensitivity analysis of +current optimal basic solution and writes the analysis report in +human-readable format to a text file, whose name is the character +string {\it fname}. (Detailed description of the report structure is +given below.) + +The parameter {\it len} specifies the length of the row/column list. + +The array {\it list} specifies ordinal number of rows and columns to be +analyzed. The ordinal numbers should be passed in locations +{\it list}[1], {\it list}[2], \dots, {\it list}[{\it len}]. Ordinal +numbers from 1 to $m$ refer to rows, and ordinal numbers from $m+1$ to +$m+n$ refer to columns, where $m$ and $n$ are, resp., the total number +of rows and columns in the problem object. Rows and columns appear in +the analysis report in the same order as they follow in the array list. + +It is allowed to specify $len=0$, in which case the array {\it list} is +not used (so it can be specified as \verb|NULL|), and the routine +performs analysis for all rows and columns of the problem object. + +The parameter {\it flags} is reserved for use in the future and must be +specified as zero. + +On entry to the routine \verb|glp_print_ranges| the current basic +solution must be optimal and the basis factorization must exist. +The application program can check that with the routine +\verb|glp_bf_exists|, and if the factorization does +not exist, compute it with the routine \verb|glp_factorize|. Note that +if the LP preprocessor is not used, on normal exit from the simplex +solver routine \verb|glp_simplex| the basis factorization always exists. + +\returns + +If the operation was successful, the routine \verb|glp_print_ranges| +returns zero. Otherwise, it prints an error message and returns +non-zero. + +\para{Analysis report example} + +An example of the sensitivity analysis report is shown on the next two +pages. This example corresponds to the example of LP problem described +in Subsection ``Example of MPS file''. + +\para{Structure of the analysis report} + +For each row and column specified in the array {\it list} the routine +prints two lines containing generic information and analysis +information, which depends on the status of corresponding row or column. + +Note that analysis of a row is analysis of its auxiliary variable, +which is equal to the row linear form $\sum a_jx_j$, and analysis of +a column is analysis of corresponding structural variable. Therefore, +formally, on performing the sensitivity analysis there is no difference +between rows and columns. + +\newpage + +\begin{landscape} +\begin{footnotesize} +\begin{verbatim} +GLPK 4.42 - SENSITIVITY ANALYSIS REPORT Page 1 + +Problem: PLAN +Objective: VALUE = 296.2166065 (MINimum) + + No. Row name St Activity Slack Lower bound Activity Obj coef Obj value at Limiting + Marginal Upper bound range range break point variable +------ ------------ -- ------------- ------------- ------------- ------------- ------------- ------------- ------------ + 1 VALUE BS 296.21661 -296.21661 -Inf 299.25255 -1.00000 . MN + . +Inf 296.21661 +Inf +Inf + + 2 YIELD NS 2000.00000 . 2000.00000 1995.06864 -Inf 296.28365 BIN3 + -.01360 2000.00000 2014.03479 +Inf 296.02579 CU + + 3 FE NU 60.00000 . -Inf 55.89016 -Inf 306.77162 BIN4 + -2.56823 60.00000 62.69978 2.56823 289.28294 BIN3 + + 4 CU BS 83.96751 16.03249 -Inf 93.88467 -.30613 270.51157 MN + . 100.00000 79.98213 .21474 314.24798 BIN5 + + 5 MN NU 40.00000 . -Inf 34.42336 -Inf 299.25255 BIN4 + -.54440 40.00000 41.68691 .54440 295.29825 BIN3 + + 6 MG BS 19.96029 10.03971 -Inf 24.74427 -1.79618 260.36433 BIN1 + . 30.00000 9.40292 .28757 301.95652 MN + + 7 AL NL 1500.00000 . 1500.00000 1485.78425 -.25199 292.63444 CU + .25199 +Inf 1504.92126 +Inf 297.45669 BIN3 + + 8 SI NL 250.00000 50.00000 250.00000 235.32871 -.48520 289.09812 CU + .48520 300.00000 255.06073 +Inf 298.67206 BIN3 +\end{verbatim} +\end{footnotesize} +\end{landscape} + +\newpage + +\begin{landscape} +\begin{footnotesize} +\begin{verbatim} +GLPK 4.42 - SENSITIVITY ANALYSIS REPORT Page 2 + +Problem: PLAN +Objective: VALUE = 296.2166065 (MINimum) + + No. Column name St Activity Obj coef Lower bound Activity Obj coef Obj value at Limiting + Marginal Upper bound range range break point variable +------ ------------ -- ------------- ------------- ------------- ------------- ------------- ------------- ------------ + 1 BIN1 NL . .03000 . -28.82475 -.22362 288.90594 BIN4 + .25362 200.00000 33.88040 +Inf 304.80951 BIN4 + + 2 BIN2 BS 665.34296 .08000 . 802.22222 .01722 254.44822 BIN1 + . 2500.00000 313.43066 .08863 301.95652 MN + + 3 BIN3 BS 490.25271 .17000 400.00000 788.61314 .15982 291.22807 MN + . 800.00000 -347.42857 .17948 300.86548 BIN5 + + 4 BIN4 BS 424.18773 .12000 100.00000 710.52632 .10899 291.54745 MN + . 700.00000 -256.15524 .14651 307.46010 BIN1 + + 5 BIN5 NL . .15000 . -201.78739 .13544 293.27940 BIN3 + .01456 1500.00000 58.79586 +Inf 297.07244 BIN3 + + 6 ALUM BS 299.63899 .21000 . 358.26772 .18885 289.87879 AL + . +Inf 112.40876 .22622 301.07527 MN + + 7 SILICON BS 120.57762 .38000 . 124.27093 .14828 268.27586 BIN5 + . +Inf 85.54745 .46667 306.66667 MN + +End of report +\end{verbatim} +\end{footnotesize} +\end{landscape} + +\newpage + +\noindent +{\it Generic information} + +{\tt No.} is the row or column ordinal number in the problem object. +Rows are numbered from 1 to $m$, and columns are numbered from 1 to $n$, +where $m$ and $n$ are, resp., the total number of rows and columns in +the problem object. + +{\tt Row name} is the symbolic name assigned to the row. If the row has +no name assigned, this field contains blanks. + +{\tt Column name} is the symbolic name assigned to the column. If the +column has no name assigned, this field contains blanks. + +{\tt St} is the status of the row or column in the optimal solution: + +{\tt BS} --- non-active constraint (row), basic column; + +{\tt NL} --- inequality constraint having its lower right-hand side +active (row), non-basic column having its lower bound active; + +{\tt NU} --- inequality constraint having its upper right-hand side +active (row), non-basic column having its upper bound active; + +{\tt NS} --- active equality constraint (row), non-basic fixed column. + +{\tt NF} --- active free row, non-basic free (unbounded) column. (This +case means that the optimal solution is dual degenerate.) + +{\tt Activity} is the (primal) value of the auxiliary variable (row) or +structural variable (column) in the optimal solution. + +{\tt Slack} is the (primal) value of the row slack variable. + +{\tt Obj coef} is the objective coefficient of the column (structural +variable). + +{\tt Marginal} is the reduced cost (dual activity) of the auxiliary +variable (row) or structural variable (column). + +{\tt Lower bound} is the lower right-hand side (row) or lower bound +(column). If the row or column has no lower bound, this field contains +{\tt -Inf}. + +{\tt Upper bound} is the upper right-hand side (row) or upper bound +(column). If the row or column has no upper bound, this field contains +{\tt +Inf}. + +\noindent +{\it Sensitivity analysis of active bounds} + +The sensitivity analysis of active bounds is performed only for rows, +which are active constraints, and only for non-basic columns, because +inactive constraints and basic columns have no active bounds. + +For every auxiliary (row) or structural (column) non-basic variable the +routine starts changing its active bound in both direction. The first +of the two lines in the report corresponds to decreasing, and the +second line corresponds to increasing of the active bound. Since the +variable being analyzed is non-basic, its activity, which is equal to +its active bound, also starts changing. This changing leads to changing +of basic (auxiliary and structural) variables, which depend on the +non-basic variable. The current basis remains primal feasible and +therefore optimal while values of all basic variables are primal +feasible, i.e. are within their bounds. Therefore, if some basic +variable called the {\it limiting variable} reaches its (lower or +upper) bound first, before any other basic variables, it thereby limits +further changing of the non-basic variable, because otherwise the +current basis would become primal infeasible. The point, at which this +happens, is called the {\it break point}. Note that there are two break +points: the lower break point, which corresponds to decreasing of the +non-basic variable, and the upper break point, which corresponds to +increasing of the non-basic variable. + +In the analysis report values of the non-basic variable (i.e. of its +active bound) being analyzed at both lower and upper break points are +printed in the field `{\tt Activity range}'. Corresponding values of +the objective function are printed in the field `{\tt Obj value at +break point}', and symbolic names of corresponding limiting basic +variables are printed in the field `{\tt Limiting variable}'. +If the active bound can decrease or/and increase unlimitedly, the field +`{\tt Activity range}' contains {\tt -Inf} or/and {\tt +Inf}, resp. + +For example (see the example report above), row SI is a double-sided +constraint, which is active on its lower bound (right-hand side), and +its activity in the optimal solution being equal to the lower bound is +250. The activity range for this row is $[235.32871,255.06073]$. This +means that the basis remains optimal while the lower bound is +increasing up to 255.06073, and further increasing is limited by +(structural) variable BIN3. If the lower bound reaches this upper break +point, the objective value becomes equal to 298.67206. + +Note that if the basis does not change, the objective function depends +on the non-basic variable linearly, and the per-unit change of the +objective function is the reduced cost (marginal value) of the +non-basic variable. + +\noindent +{\it Sensitivity analysis of objective coefficients at non-basic +variables} + +The sensitivity analysis of the objective coefficient at a non-basic +variable is quite simple, because in this case change in the objective +coefficient leads to equivalent change in the reduced cost (marginal +value). + +For every auxiliary (row) or structural (column) non-basic variable the +routine starts changing its objective coefficient in both direction. +(Note that auxiliary variables are not included in the objective +function and therefore always have zero objective coefficients.) The +first of the two lines in the report corresponds to decreasing, and the +second line corresponds to increasing of the objective coefficient. +This changing leads to changing of the reduced cost of the non-basic +variable to be analyzed and does affect reduced costs of all other +non-basic variables. The current basis remains dual feasible and +therefore optimal while the reduced cost keeps its sign. Therefore, if +the reduced cost reaches zero, it limits further changing of the +objective coefficient (if only the non-basic variable is non-fixed). + +In the analysis report minimal and maximal values of the objective +coefficient, on which the basis remains optimal, are printed in the +field `\verb|Obj coef range|'. If the objective coefficient can +decrease or/and increase unlimitedly, this field contains {\tt -Inf} +or/and {\tt +Inf}, resp. + +For example (see the example report above), column BIN5 is non-basic +having its lower bound active. Its objective coefficient is 0.15, and +reduced cost in the optimal solution 0.01456. The column lower bound +remains active while the column reduced cost remains non-negative, +thus, minimal value of the objective coefficient, on which the current +basis still remains optimal, is $0.15-0.01456=0.13644$, that is +indicated in the field `\verb|Obj coef range|'. + +\newpage + +{\parskip=0pt +\noindent +{\it Sensitivity analysis of objective coefficients at basic variables} + +\medskip + +To perform sensitivity analysis for every auxiliary (row) or structural +(column) variable the routine starts changing its objective coefficient +in both direction. (Note that auxiliary variables are not included in +the objective function and therefore always have zero objective +coefficients.) The first of the two lines in the report corresponds to +decreasing, and the second line corresponds to increasing of the +objective coefficient. This changing leads to changing of reduced costs +of non-basic variables. The current basis remains dual feasible and +therefore optimal while reduced costs of all non-basic variables +(except fixed variables) keep their signs. Therefore, if the reduced +cost of some non-basic non-fixed variable called the {\it limiting +variable} reaches zero first, before reduced cost of any other +non-basic non-fixed variable, it thereby limits further changing of the +objective coefficient, because otherwise the current basis would become +dual infeasible (non-optimal). The point, at which this happens, is +called the {\it break point}. Note that there are two break points: the +lower break point, which corresponds to decreasing of the objective +coefficient, and the upper break point, which corresponds to increasing +of the objective coefficient. Let the objective coefficient reach its +limit value and continue changing a bit further in the same direction +that makes the current basis dual infeasible (non-optimal). Then the +reduced cost of the non-basic limiting variable becomes ``a bit'' dual +infeasible that forces the limiting variable to enter the basis +replacing there some basic variable, which leaves the basis to keep its +primal feasibility. It should be understood that if we change the +current basis in this way exactly at the break point, both the current +and adjacent bases will be optimal with the same objective value, +because at the break point the limiting variable has zero reduced cost. +On the other hand, in the adjacent basis the value of the limiting +variable changes, because there it becomes basic, that leads to +changing of the value of the basic variable being analyzed. Note that +on determining the adjacent basis the bounds of the analyzed basic +variable are ignored as if it were a free (unbounded) variable, so it +cannot leave the current basis. + +In the analysis report lower and upper limits of the objective +coefficient at the basic variable being analyzed, when the basis +remains optimal, are printed in the field `{\tt Obj coef range}'. +Corresponding values of the objective function at both lower and upper +break points are printed in the field `{\tt Obj value at break point}', +symbolic names of corresponding non-basic limiting variables are +printed in the field `{\tt Limiting variable}', and values of the basic +variable, which it would take on in the adjacent bases (as was +explained above) are printed in the field `{\tt Activity range}'. +If the objective coefficient can increase or/and decrease unlimitedly, +the field `{\tt Obj coef range}' contains {\tt -Inf} and/or {\tt +Inf}, +resp. It also may happen that no dual feasible adjacent basis exists +(i.e. on entering the basis the limiting variable can increase or +decrease unlimitedly), in which case the field `{\tt Activity range}' +contains {\tt -Inf} and/or {\tt +Inf}. + +For example (see the example report above), structural variable +(column) BIN3 is basic, its optimal value is 490.25271, and its +objective coefficient is 0.17. The objective coefficient range for this +column is $[0.15982,0.17948]$. This means that the basis remains +optimal while the objective coefficient is decreasing down to 0.15982, +and further decreasing is limited by (auxiliary) variable MN. If we +make the objective coefficient a bit less than 0.15982, the limiting +variable MN will enter the basis, and in that adjacent basis the +structural variable BIN3 will take on new optimal value 788.61314. At +the lower break point, where the objective coefficient is exactly +0.15982, the objective function takes on the value 291.22807 in both +the current and adjacent bases. + +Note that if the basis does not change, the objective function depends +on the objective coefficient at the basic variable linearly, and the +per-unit change of the objective function is the value of the basic +variable. +} + +%* eof *% diff --git a/resources/3rdparty/glpk-4.57/doc/glpk04.tex b/resources/3rdparty/glpk-4.57/doc/glpk04.tex new file mode 100644 index 000000000..2367db573 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/glpk04.tex @@ -0,0 +1,1387 @@ +%* glpk04.tex *% + +\chapter{Advanced API Routines} + +\section{Background} +\label{basbgd} + +Using vector and matrix notations the LP problem (1.1)---(1.3) (see +Section \ref{seclp}, page \pageref{seclp}) can be stated as follows: + +\noindent +\hspace{.5in} minimize (or maximize) +$$z=c^Tx_S+c_0\eqno(3.1)$$ +\hspace{.5in} subject to linear constraints +$$x_R=Ax_S\eqno(3.2)$$ +\hspace{.5in} and bounds of variables +$$ +\begin{array}{l@{\ }c@{\ }l@{\ }c@{\ }l} +l_R&\leq&x_R&\leq&u_R\\ +l_S&\leq&x_S&\leq&u_S\\ +\end{array}\eqno(3.3) +$$ +where: + +$x_R=(x_1,\dots,x_m)$ is the vector of auxiliary variables; + +$x_S=(x_{m+1},\dots,x_{m+n})$ is the vector of structural variables; + +$z$ is the objective function; + +$c=(c_1,\dots,c_n)$ is the vector of objective coefficients; + +$c_0$ is the constant term (``shift'') of the objective function; + +$A=(a_{11},\dots,a_{mn})$ is the constraint matrix; + +$l_R=(l_1,\dots,l_m)$ is the vector of lower bounds of auxiliary +variables; + +$u_R=(u_1,\dots,u_m)$ is the vector of upper bounds of auxiliary +variables; + +$l_S=(l_{m+1},\dots,l_{m+n})$ is the vector of lower bounds of +structural variables; + +$u_S=(u_{m+1},\dots,u_{m+n})$ is the vector of upper bounds of +structural variables. + +From the simplex method's standpoint there is no difference between +auxiliary and structural variables. This allows combining all these +variables into one vector that leads to the following problem +statement: + +\noindent +\hspace{.5in} minimize (or maximize) +$$z=(0\ |\ c)^Tx+c_0\eqno(3.4)$$ +\hspace{.5in} subject to linear constraints +$$(I\ |-\!A)x=0\eqno(3.5)$$ +\hspace{.5in} and bounds of variables +$$l\leq x\leq u\eqno(3.6)$$ +where: + +$x=(x_R\ |\ x_S)$ is the $(m+n)$-vector of (all) variables; + +$(0\ |\ c)$ is the $(m+n)$-vector of objective +coefficients;\footnote{Subvector 0 corresponds to objective +coefficients at auxiliary variables.} + +$(I\ |-\!A)$ is the {\it augmented} constraint +$m\times(m+n)$-matrix;\footnote{Note that due to auxiliary variables +matrix $(I\ |-\!A)$ contains the unity submatrix and therefore has full +rank. This means, in particular, that the system (3.5) has no linearly +dependent constraints.} + +$l=(l_R\ |\ l_S)$ is the $(m+n)$-vector of lower bounds of (all) +variables; + +$u=(u_R\ |\ u_S)$ is the $(m+n)$-vector of upper bounds of (all) +variables. + +By definition an {\it LP basic solution} geometrically is a point in +the space of all variables, which is the intersection of hyperplanes +corresponding to active constraints\footnote{A constraint is called +{\it active} if at a given point it is satisfied as equality, otherwise +it is called {\it inactive}.}. The space of all variables has the +dimension $m+n$, therefore, to define some basic solution we have to +define $m+n$ active constraints. Note that $m$ constraints (3.5) being +linearly independent equalities are always active, so remaining $n$ +active constraints can be chosen only from bound constraints (3.6). + +A variable is called {\it non-basic}, if its (lower or upper) bound is +active, otherwise it is called {\it basic}. Since, as was said above, +exactly $n$ bound constraints must be active, in any basic solution +there are always $n$ non-basic variables and $m$ basic variables. +(Note that a free variable also can be non-basic. Although such +variable has no bounds, we can think it as the difference between two +non-negative variables, which both are non-basic in this case.) + +Now consider how to determine numeric values of all variables for a +given basic solution. + +Let $\Pi$ be an appropriate permutation matrix of the order $(m+n)$. +Then we can write: +$$\left(\begin{array}{@{}c@{}}x_B\\x_N\\\end{array}\right)= +\Pi\left(\begin{array}{@{}c@{}}x_R\\x_S\\\end{array}\right)=\Pi x, +\eqno(3.7)$$ +where $x_B$ is the vector of basic variables, $x_N$ is the vector of +non-basic variables, $x=(x_R\ |\ x_S)$ is the vector of all variables +in the original order. In this case the system of linear constraints +(3.5) can be rewritten as follows: +$$(I\ |-\!A)\Pi^T\Pi x=0\ \ \ \Rightarrow\ \ \ (B\ |\ N) +\left(\begin{array}{@{}c@{}}x_B\\x_N\\\end{array}\right)=0,\eqno(3.8)$$ +where +$$(B\ |\ N)=(I\ |-\!A)\Pi^T.\eqno(3.9)$$ + +\newpage + +Matrix $B$ is a square non-singular $m\times m$-matrix, which is +composed from columns of the augmented constraint matrix corresponding +to basic variables. It is called the {\it basis matrix} or simply the +{\it basis}. Matrix $N$ is a rectangular $m\times n$-matrix, which is +composed from columns of the augmented constraint matrix corresponding +to non-basic variables. + +From (3.8) it follows that: +$$Bx_B+Nx_N=0,\eqno(3.10)$$ +therefore, +$$x_B=-B^{-1}Nx_N.\eqno(3.11)$$ +Thus, the formula (3.11) shows how to determine numeric values of basic +variables $x_B$ assuming that non-basic variables $x_N$ are fixed on +their active bounds. + +The $m\times n$-matrix +$$\Xi=-B^{-1}N,\eqno(3.12)$$ +which appears in (3.11), is called the {\it simplex +tableau}.\footnote{This definition corresponds to the GLPK +implementation.} It shows how basic variables depend on non-basic +variables: +$$x_B=\Xi x_N.\eqno(3.13)$$ + +The system (3.13) is equivalent to the system (3.5) in the sense that +they both define the same set of points in the space of (primal) +variables, which satisfy to these systems. If, moreover, values of all +basic variables satisfy to their bound constraints (3.3), the +corresponding basic solution is called {\it (primal) feasible}, +otherwise {\it (primal) infeasible}. It is understood that any (primal) +feasible basic solution satisfy to all constraints (3.2) and (3.3). + +The LP theory says that if LP has optimal solution, it has (at least +one) basic feasible solution, which corresponds to the optimum. And the +most natural way to determine whether a given basic solution is optimal +or not is to use the Karush---Kuhn---Tucker optimality conditions. + +\def\arraystretch{1.5} + +For the problem statement (3.4)---(3.6) the optimality conditions are +the following:\footnote{These conditions can be appiled to any solution, +not only to a basic solution.} +$$(I\ |-\!A)x=0\eqno(3.14)$$ +$$(I\ |-\!A)^T\pi+\lambda_l+\lambda_u=\nabla z=(0\ |\ c)^T\eqno(3.15)$$ +$$l\leq x\leq u\eqno(3.16)$$ +$$\lambda_l\geq 0,\ \ \lambda_u\leq 0\ \ \mbox{(minimization)} +\eqno(3.17)$$ +$$\lambda_l\leq 0,\ \ \lambda_u\geq 0\ \ \mbox{(maximization)} +\eqno(3.18)$$ +$$(\lambda_l)_k(x_k-l_k)=0,\ \ (\lambda_u)_k(x_k-u_k)=0,\ \ k=1,2,\dots, +m+n\eqno(3.19)$$ +where: +$\pi=(\pi_1,\pi_2,\dots,\pi_m)$ is a $m$-vector of Lagrange +multipliers for equality constraints (3.5); +$\lambda_l=[(\lambda_l)_1,(\lambda_l)_2,\dots,(\lambda_l)_n]$ is a +$n$-vector of Lagrange multipliers for lower bound constraints (3.6); +$\lambda_u=[(\lambda_u)_1,(\lambda_u)_2,\dots,(\lambda_u)_n]$ is a +$n$-vector of Lagrange multipliers for upper bound constraints (3.6). + +\newpage + +Condition (3.14) is the {\it primal} (original) system of equality +constraints (3.5). + +Condition (3.15) is the {\it dual} system of equality constraints. +It requires the gradient of the objective function to be a linear +combination of normals to the planes defined by constraints of the +original problem. + +Condition (3.16) is the primal (original) system of bound constraints +(3.6). + +Condition (3.17) (or (3.18) in case of maximization) is the dual system +of bound constraints. + +Condition (3.19) is the {\it complementary slackness condition}. It +requires, for each original (auxiliary or structural) variable $x_k$, +that either its (lower or upper) bound must be active, or zero bound of +the corresponding Lagrange multiplier ($(\lambda_l)_k$ or +$(\lambda_u)_k$) must be active. + +In GLPK two multipliers $(\lambda_l)_k$ and $(\lambda_u)_k$ for each +primal (original) variable $x_k$, $k=1,2,\dots,\linebreak m+n$, are +combined into one multiplier: +$$\lambda_k=(\lambda_l)_k+(\lambda_u)_k,\eqno(3.20)$$ +which is called a {\it dual variable} for $x_k$. This {\it cannot} lead +to the ambiguity, because both lower and upper bounds of $x_k$ cannot be +active at the same time,\footnote{If $x_k$ is a fixed variable, we can +think it as double-bounded variable $l_k\leq x_k\leq u_k$, where +$l_k=u_k.$} so at least one of $(\lambda_l)_k$ and $(\lambda_u)_k$ must +be equal to zero, and because these multipliers have different signs, +the combined multiplier, which is their sum, uniquely defines each of +them. + +\def\arraystretch{1} + +Using dual variables $\lambda_k$ the dual system of bound constraints +(3.17) and (3.18) can be written in the form of so called {\it ``rule of +signs''} as follows: + +\medskip + +\begin{center} +\begin{tabular}{|@{\,}c@{$\,$}|@{$\,$}c@{$\,$}|@{$\,$}c@{$\,$}| +@{$\,$}c|c@{$\,$}|@{$\,$}c@{$\,$}|@{$\,$}c@{$\,$}|} +\hline +Original bound&\multicolumn{3}{c|}{Minimization}&\multicolumn{3}{c|} +{Maximization}\\ +\cline{2-7} +constraint&$(\lambda_l)_k$&$(\lambda_u)_k$&$(\lambda_l)_k+ +(\lambda_u)_k$&$(\lambda_l)_k$&$(\lambda_u)_k$&$(\lambda_l)_k+ +(\lambda_u)_k$\\ +\hline +$-\infty= {\tt piv\_tol}\cdot\max|u_{i*}|$, i.e. if it is not very +small in the magnitude among other elements in the same row. Decreasing +this parameter may lead to better sparsity at the expense of numerical +accuracy, and vice versa. + +\medskip + +{\tt int piv\_lim} (default: {\tt 4}) + +This parameter is used on computing $LU$-factorization of the basis +matrix and specifies how many pivot candidates needs to be considered +on choosing a pivot element, \verb|piv_lim| $\geq$ 1. If \verb|piv_lim| +candidates have been considered, the pivoting routine prematurely +terminates the search with the best candidate found. + +\newpage + +{\tt int suhl} (default: {\tt GLP\_ON}) + +This parameter is used on computing $LU$-factorization of the basis +matrix. Being set to {\tt GLP\_ON} it enables applying the following +heuristic proposed by Uwe Suhl: if a column of the active submatrix has +no eligible pivot candidates, it is no more considered until it becomes +a column singleton. In many cases this allows reducing the time needed +for pivot searching. To disable this heuristic the parameter +\verb|suhl| should be set to {\tt GLP\_OFF}. + +\medskip + +{\tt double eps\_tol} (default: {\tt 1e-15}) + +Epsilon tolerance, \verb|eps_tol| $\geq$ 0, used on computing +$LU$-factorization of the basis matrix. If an element of the active +submatrix of factor $U$ is less than \verb|eps_tol| in the magnitude, +it is replaced by exact zero. + +%\medskip +% +%{\tt double max\_gro} (default: {\tt 1e+10}) +% +%Maximal growth of elements of factor $U$, \verb|max_gro| $\geq$ 1, +%allowable on computing $LU$-factorization of the basis matrix. If on +%some elimination step the ratio $u_{big}/b_{max}$ (where $u_{big}$ is +%the largest magnitude of elements of factor $U$ appeared in its active +%submatrix during all the factorization process, $b_{max}$ is the +%largest magnitude of elements of the basis matrix to be factorized), +%the basis matrix is considered as ill-conditioned. + +\medskip + +{\tt int nfs\_max} (default: {\tt 100}) + +Maximal number of additional row-like factors (entries of the eta +file), \verb|nfs_max| $\geq$ 1, which can be added to +$LU$-factorization of the basis matrix on updating it with the +Forrest--Tomlin technique. This parameter is used only once, before +$LU$-factorization is computed for the first time, to allocate working +arrays. As a rule, each update adds one new factor (however, some +updates may need no addition), so this parameter limits the number of +updates between refactorizations. + +\medskip + +{\tt double upd\_tol} (default: {\tt 1e-6}) + +Update tolerance, 0 $<$ \verb|upd_tol| $<$ 1, used on updating +$LU$-factorization of the basis matrix with the Forrest--Tomlin +technique. If after updating the magnitude of some diagonal element +$u_{kk}$ of factor $U$ becomes less than +${\tt upd\_tol}\cdot\max(|u_{k*}|, |u_{*k}|)$, the factorization is +considered as inaccurate. + +\medskip + +{\tt int nrs\_max} (default: {\tt 100}) + +Maximal number of additional rows and columns, \verb|nrs_max| $\geq$ 1, +which can be added to $LU$-factorization of the basis matrix on +updating it with the Schur complement technique. This parameter is used +only once, before $LU$-factorization is computed for the first time, to +allocate working arrays. As a rule, each update adds one new row and +column (however, some updates may need no addition), so this parameter +limits the number of updates between refactorizations. + +%\medskip +% +%{\tt int rs\_size} (default: {\tt 0}) +% +%The initial size of the Sparse Vector Area, in non-zeros, used to +%store non-zero elements of additional rows and columns introduced on +%updating $LU$-factorization of the basis matrix with the Schur +%complement technique. If this parameter is set to 0, the initial SVA +%size is determined automatically. + +\subsection{glp\_get\_bhead --- retrieve the basis header information} + +\synopsis + +\begin{verbatim} + int glp_get_bhead(glp_prob *P, int k); +\end{verbatim} + +\description + +The routine \verb|glp_get_bhead| returns the basis header information +for the current basis associated with the specified problem object. + +\returns + +If basic variable $(x_B)_k$, $1\leq k\leq m$, is $i$-th auxiliary +variable ($1\leq i\leq m$), the routine returns $i$. Otherwise, if +$(x_B)_k$ is $j$-th structural variable ($1\leq j\leq n$), the routine +returns $m+j$. Here $m$ is the number of rows and $n$ is the number of +columns in the problem object. + +\para{Comments} + +Sometimes the application program may need to know which original +(auxiliary and structural) variable correspond to a given basic +variable, or, that is the same, which column of the augmented +constraint matrix $(I\ |-\!A)$ correspond to a given column of the +basis matrix $B$. + +\def\arraystretch{1} + +The correspondence is defined as follows:\footnote{For more details see +Subsection \ref{basbgd}, page \pageref{basbgd}.} +$$\left(\begin{array}{@{}c@{}}x_B\\x_N\\\end{array}\right)= +\Pi\left(\begin{array}{@{}c@{}}x_R\\x_S\\\end{array}\right) +\ \ \Leftrightarrow +\ \ \left(\begin{array}{@{}c@{}}x_R\\x_S\\\end{array}\right)= +\Pi^T\left(\begin{array}{@{}c@{}}x_B\\x_N\\\end{array}\right),$$ +where $x_B$ is the vector of basic variables, $x_N$ is the vector of +non-basic variables, $x_R$ is the vector of auxiliary variables +following in their original order,\footnote{The original order of +auxiliary and structural variables is defined by the ordinal numbers +of corresponding rows and columns in the problem object.} $x_S$ is the +vector of structural variables following in their original order, $\Pi$ +is a permutation matrix (which is a component of the basis +factorization). + +Thus, if $(x_B)_k=(x_R)_i$ is $i$-th auxiliary variable, the routine +returns $i$, and if $(x_B)_k=(x_S)_j$ is $j$-th structural variable, +the routine returns $m+j$, where $m$ is the number of rows in the +problem object. + +\subsection{glp\_get\_row\_bind --- retrieve row index in the basis +header} + +\synopsis + +\begin{verbatim} + int glp_get_row_bind(glp_prob *P, int i); +\end{verbatim} + +\returns + +The routine \verb|glp_get_row_bind| returns the index $k$ of basic +variable $(x_B)_k$, $1\leq k\leq m$, which is $i$-th auxiliary variable +(that is, the auxiliary variable corresponding to $i$-th row), +$1\leq i\leq m$, in the current basis associated with the specified +problem object, where $m$ is the number of rows. However, if $i$-th +auxiliary variable is non-basic, the routine returns zero. + +\para{Comments} + +The routine \verb|glp_get_row_bind| is an inversion of the routine +\verb|glp_get_bhead|; that is, if \linebreak +\verb|glp_get_bhead|$(P,k)$ returns $i$, +\verb|glp_get_row_bind|$(P,i)$ returns $k$, and vice versa. + +\subsection{glp\_get\_col\_bind --- retrieve column index in the basis +header} + +\synopsis + +\begin{verbatim} + int glp_get_col_bind(glp_prob *P, int j); +\end{verbatim} + +\returns + +The routine \verb|glp_get_col_bind| returns the index $k$ of basic +variable $(x_B)_k$, $1\leq k\leq m$, which is $j$-th structural +variable (that is, the structural variable corresponding to $j$-th +column), $1\leq j\leq n$, in the current basis associated with the +specified problem object, where $m$ is the number of rows, $n$ is the +number of columns. However, if $j$-th structural variable is non-basic, +the routine returns zero. + +\para{Comments} + +The routine \verb|glp_get_col_bind| is an inversion of the routine +\verb|glp_get_bhead|; that is, if \linebreak +\verb|glp_get_bhead|$(P,k)$ returns $m+j$, +\verb|glp_get_col_bind|$(P,j)$ returns $k$, and vice versa. + +\subsection{glp\_ftran --- perform forward transformation} + +\synopsis + +\begin{verbatim} + void glp_ftran(glp_prob *P, double x[]); +\end{verbatim} + +\description + +The routine \verb|glp_ftran| performs forward transformation (FTRAN), +i.e. it solves the system $Bx=b$, where $B$ is the basis matrix +associated with the specified problem object, $x$ is the vector of +unknowns to be computed, $b$ is the vector of right-hand sides. + +On entry to the routine elements of the vector $b$ should be stored in +locations \verb|x[1]|, \dots, \verb|x[m]|, where $m$ is the number of +rows. On exit the routine stores elements of the vector $x$ in the same +locations. + +\subsection{glp\_btran --- perform backward transformation} + +\synopsis + +\begin{verbatim} + void glp_btran(glp_prob *P, double x[]); +\end{verbatim} + +\description + +The routine \verb|glp_btran| performs backward transformation (BTRAN), +i.e. it solves the system $B^Tx=b$, where $B^T$ is a matrix transposed +to the basis matrix $B$ associated with the specified problem object, +$x$ is the vector of unknowns to be computed, $b$ is the vector of +right-hand sides. + +On entry to the routine elements of the vector $b$ should be stored in +locations \verb|x[1]|, \dots, \verb|x[m]|, where $m$ is the number of +rows. On exit the routine stores elements of the vector $x$ in the same +locations. + +\subsection{glp\_warm\_up --- ``warm up'' LP basis} + +\synopsis + +\begin{verbatim} + int glp_warm_up(glp_prob *P); +\end{verbatim} + +\description + +The routine \verb|glp_warm_up| ``warms up'' the LP basis for the +specified problem object using current statuses assigned to rows and +columns (that is, to auxiliary and structural variables). + +This operation includes computing factorization of the basis matrix +(if it does not exist), computing primal and dual components of basic +solution, and determining the solution status. + +\returns + +\begin{retlist} +0 & The operation has been successfully performed.\\ + +\verb|GLP_EBADB| & The basis matrix is invalid, because the number of +basic (auxiliary and structural) variables is not the same as the +number of rows in the problem object.\\ + +\verb|GLP_ESING| & The basis matrix is singular within the working +precision.\\ + +\verb|GLP_ECOND| & The basis matrix is ill-conditioned, i.e. its +condition number is too large.\\ +\end{retlist} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Simplex tableau routines} + +\subsection{glp\_eval\_tab\_row --- compute row of the tableau} + +\synopsis + +\begin{verbatim} + int glp_eval_tab_row(glp_prob *P, int k, int ind[], double val[]); +\end{verbatim} + +\description + +The routine \verb|glp_eval_tab_row| computes a row of the current +simplex tableau (see Subsection 3.1.1, formula (3.12)), which (row) +corresponds to some basic variable specified by the parameter $k$ as +follows: if $1\leq k\leq m$, the basic variable is $k$-th auxiliary +variable, and if $m+1\leq k\leq m+n$, the basic variable is $(k-m)$-th +structural variable, where $m$ is the number of rows and $n$ is the +number of columns in the specified problem object. The basis +factorization must exist. + +The computed row shows how the specified basic variable depends on +non-basic variables: +$$x_k=(x_B)_i=\xi_{i1}(x_N)_1+\xi_{i2}(x_N)_2+\dots+\xi_{in}(x_N)_n,$$ +where $\xi_{i1}$, $\xi_{i2}$, \dots, $\xi_{in}$ are elements of the +simplex table row, $(x_N)_1$, $(x_N)_2$, \dots, $(x_N)_n$ are non-basic +(auxiliary and structural) variables. + +The routine stores column indices and corresponding numeric values of +non-zero elements of the computed row in unordered sparse format in +locations \verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, +\dots, \verb|val[len]|, respectively, where $0\leq{\tt len}\leq n$ is +the number of non-zero elements in the row returned on exit. + +Element indices stored in the array \verb|ind| have the same sense as +index $k$, i.e. indices 1 to $m$ denote auxiliary variables while +indices $m+1$ to $m+n$ denote structural variables (all these variables +are obviously non-basic by definition). + +\returns + +The routine \verb|glp_eval_tab_row| returns \verb|len|, which is the +number of non-zero elements in the simplex table row stored in the +arrays \verb|ind| and \verb|val|. + +\para{Comments} + +A row of the simplex table is computed as follows. At first, the +routine checks that the specified variable $x_k$ is basic and uses the +permutation matrix $\Pi$ (3.7) to determine index $i$ of basic variable +$(x_B)_i$, which corresponds to $x_k$. + +The row to be computed is $i$-th row of the matrix $\Xi$ (3.12), +therefore: +$$\xi_i=e_i^T\Xi=-e_i^TB^{-1}N=-(B^{-T}e_i)^TN,$$ +where $e_i$ is $i$-th unity vector. So the routine performs BTRAN to +obtain $i$-th row of the inverse $B^{-1}$: +$$\varrho_i=B^{-T}e_i,$$ +and then computes elements of the simplex table row as inner products: +$$\xi_{ij}=-\varrho_i^TN_j,\ \ j=1,2,\dots,n,$$ +where $N_j$ is $j$-th column of matrix $N$ (3.9), which (column) +corresponds to non-basic variable $(x_N)_j$. The permutation matrix +$\Pi$ is used again to convert indices $j$ of non-basic columns to +original ordinal numbers of auxiliary and structural variables. + +\subsection{glp\_eval\_tab\_col --- compute column of the tableau} + +\synopsis + +\begin{verbatim} + int glp_eval_tab_col(glp_prob *P, int k, int ind[], double val[]); +\end{verbatim} + +\description + +The routine \verb|glp_eval_tab_col| computes a column of the current +simplex tableau (see Subsection 3.1.1, formula (3.12)), which (column) +corresponds to some non-basic variable specified by the parameter $k$: +if $1\leq k\leq m$, the non-basic variable is $k$-th auxiliary +variable, and if $m+1\leq k\leq m+n$, the non-basic variable is +$(k-m)$-th structural variable, where $m$ is the number of rows and $n$ +is the number of columns in the specified problem object. The basis +factorization must exist. + +The computed column shows how basic variables depends on the specified +non-basic variable $x_k=(x_N)_j$: +$$ +\begin{array}{r@{\ }c@{\ }l@{\ }l} +(x_B)_1&=&\dots+\xi_{1j}(x_N)_j&+\dots\\ +(x_B)_2&=&\dots+\xi_{2j}(x_N)_j&+\dots\\ +.\ \ .&.&.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\\ +(x_B)_m&=&\dots+\xi_{mj}(x_N)_j&+\dots\\ +\end{array} +$$ +where $\xi_{1j}$, $\xi_{2j}$, \dots, $\xi_{mj}$ are elements of the +simplex table column, $(x_B)_1$, $(x_B)_2$, \dots, $(x_B)_m$ are basic +(auxiliary and structural) variables. + +The routine stores row indices and corresponding numeric values of +non-zero elements of the computed column in unordered sparse format in +locations \verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, +\dots, \verb|val[len]|, respectively, where $0\leq{\tt len}\leq m$ is +the number of non-zero elements in the column returned on exit. + +Element indices stored in the array \verb|ind| have the same sense as +index $k$, i.e. indices 1 to $m$ denote auxiliary variables while +indices $m+1$ to $m+n$ denote structural variables (all these variables +are obviously basic by definition). + +\returns + +The routine \verb|glp_eval_tab_col| returns \verb|len|, which is the +number of non-zero elements in the simplex table column stored in the +arrays \verb|ind| and \verb|val|. + +\para{Comments} + +A column of the simplex table is computed as follows. At first, the +routine checks that the specified variable $x_k$ is non-basic and uses +the permutation matrix $\Pi$ (3.7) to determine index $j$ of non-basic +variable $(x_N)_j$, which corresponds to $x_k$. + +The column to be computed is $j$-th column of the matrix $\Xi$ (3.12), +therefore: +$$\Xi_j=\Xi e_j=-B^{-1}Ne_j=-B^{-1}N_j,$$ +where $e_j$ is $j$-th unity vector, $N_j$ is $j$-th column of matrix +$N$ (3.9). So the routine performs FTRAN to transform $N_j$ to the +simplex table column $\Xi_j=(\xi_{ij})$ and uses the permutation matrix +$\Pi$ to convert row indices $i$ to original ordinal numbers of +auxiliary and structural variables. + +\subsection{glp\_transform\_row --- transform explicitly specified row} + +\synopsis + +\begin{verbatim} + int glp_transform_row(glp_prob *P, int len, int ind[], double val[]); +\end{verbatim} + +\description + +The routine \verb|glp_transform_row| performs the same operation as the +routine \verb|glp_eval_tab_row| with exception that the row to be +transformed is specified explicitly as a sparse vector. + +The explicitly specified row may be thought as a linear form: +$$x=a_1x_{m+1}+a_2x_{m+2}+\dots+a_nx_{m+n},$$ +where $x$ is an auxiliary variable for this row, $a_j$ are coefficients +of the linear form, $x_{m+j}$ are structural variables. + +On entry column indices and numerical values of non-zero coefficients +$a_j$ of the specified row should be placed in locations \verb|ind[1]|, +\dots, \verb|ind[len]| and \verb|val[1]|, \dots, \verb|val[len]|, where +\verb|len| is number of non-zero coefficients. + +This routine uses the system of equality constraints and the current +basis in order to express the auxiliary variable $x$ through the current +non-basic variables (as if the transformed row were added to the problem +object and the auxiliary variable $x$ were basic), i.e. the resultant +row has the form: +$$x=\xi_1(x_N)_1+\xi_2(x_N)_2+\dots+\xi_n(x_N)_n,$$ +where $\xi_j$ are influence coefficients, $(x_N)_j$ are non-basic +(auxiliary and structural) variables, $n$ is the number of columns in +the problem object. + +On exit the routine stores indices and numerical values of non-zero +coefficients $\xi_j$ of the resultant row in locations \verb|ind[1]|, +\dots, \verb|ind[len']| and \verb|val[1]|, \dots, \verb|val[len']|, +where $0\leq{\tt len'}\leq n$ is the number of non-zero coefficients in +the resultant row returned by the routine. Note that indices of +non-basic variables stored in the array \verb|ind| correspond to +original ordinal numbers of variables: indices 1 to $m$ mean auxiliary +variables and indices $m+1$ to $m+n$ mean structural ones. + +\returns + +The routine \verb|glp_transform_row| returns \verb|len'|, the number of +non-zero coefficients in the resultant row stored in the arrays +\verb|ind| and \verb|val|. + +\newpage + +\subsection{glp\_transform\_col --- transform explicitly specified +column} + +\synopsis + +\begin{verbatim} + int glp_transform_col(glp_prob *P, int len, int ind[], double val[]); +\end{verbatim} + +\description + +The routine \verb|glp_transform_col| performs the same operation as the +routine \verb|glp_eval_tab_col| with exception that the column to be +transformed is specified explicitly as a sparse vector. + +The explicitly specified column may be thought as it were added to +the original system of equality constraints: +$$ +\begin{array}{l@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r} +x_1&=&a_{11}x_{m+1}&+\dots+&a_{1n}x_{m+n}&+&a_1x \\ +x_2&=&a_{21}x_{m+1}&+\dots+&a_{2n}x_{m+n}&+&a_2x \\ +\multicolumn{7}{c} +{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\ +x_m&=&a_{m1}x_{m+1}&+\dots+&a_{mn}x_{m+n}&+&a_mx \\ +\end{array} +$$ +where $x_i$ are auxiliary variables, $x_{m+j}$ are structural variables +(presented in the problem object), $x$ is a structural variable for the +explicitly specified column, $a_i$ are constraint coefficients at $x$. + +On entry row indices and numerical values of non-zero coefficients +$a_i$ of the specified column should be placed in locations +\verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, \dots, +\verb|val[len]|, where \verb|len| is number of non-zero coefficients. + +This routine uses the system of equality constraints and the current +basis in order to express the current basic variables through the +structural variable $x$ (as if the transformed column were added to the +problem object and the variable $x$ were non-basic): +$$ +\begin{array}{l@{\ }c@{\ }r} +(x_B)_1&=\dots+&\xi_{1}x\\ +(x_B)_2&=\dots+&\xi_{2}x\\ +\multicolumn{3}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .}\\ +(x_B)_m&=\dots+&\xi_{m}x\\ +\end{array} +$$ +where $\xi_i$ are influence coefficients, $x_B$ are basic (auxiliary +and structural) variables, $m$ is the number of rows in the problem +object. + +On exit the routine stores indices and numerical values of non-zero +coefficients $\xi_i$ of the resultant column in locations \verb|ind[1]|, +\dots, \verb|ind[len']| and \verb|val[1]|, \dots, \verb|val[len']|, +where $0\leq{\tt len'}\leq m$ is the number of non-zero coefficients in +the resultant column returned by the routine. Note that indices of basic +variables stored in the array \verb|ind| correspond to original ordinal +numbers of variables, i.e. indices 1 to $m$ mean auxiliary variables, +indices $m+1$ to $m+n$ mean structural ones. + +\returns + +The routine \verb|glp_transform_col| returns \verb|len'|, the number of +non-zero coefficients in the resultant column stored in the arrays +\verb|ind| and \verb|val|. + +\newpage + +\subsection{glp\_prim\_rtest --- perform primal ratio test} + +\synopsis + +\begin{verbatim} + int glp_prim_rtest(glp_prob *P, int len, const int ind[], const double val[], + int dir, double eps); +\end{verbatim} + +\description + +The routine \verb|glp_prim_rtest| performs the primal ratio test using +an explicitly specified column of the simplex table. + +The current basic solution associated with the LP problem object must +be primal feasible. + +The explicitly specified column of the simplex table shows how the +basic variables $x_B$ depend on some non-basic variable $x$ (which is +not necessarily presented in the problem object): +$$ +\begin{array}{l@{\ }c@{\ }r} +(x_B)_1&=\dots+&\xi_{1}x\\ +(x_B)_2&=\dots+&\xi_{2}x\\ +\multicolumn{3}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .}\\ +(x_B)_m&=\dots+&\xi_{m}x\\ +\end{array} +$$ + +The column is specifed on entry to the routine in sparse format. +Ordinal numbers of basic variables $(x_B)_i$ should be placed in +locations \verb|ind[1]|, \dots, \verb|ind[len]|, where ordinal number +1 to $m$ denote auxiliary variables, and ordinal numbers $m+1$ to $m+n$ +denote structural variables. The corresponding non-zero coefficients +$\xi_i$ should be placed in locations +\verb|val[1]|, \dots, \verb|val[len]|. The arrays \verb|ind| and +\verb|val| are not changed by the routine. + +The parameter \verb|dir| specifies direction in which the variable $x$ +changes on entering the basis: $+1$ means increasing, $-1$ means +decreasing. + +The parameter \verb|eps| is an absolute tolerance (small positive +number, say, $10^{-9}$) used by the routine to skip $\xi_i$'s whose +magnitude is less than \verb|eps|. + +The routine determines which basic variable (among those specified in +\verb|ind[1]|, \dots, \verb|ind[len]|) reaches its (lower or upper) +bound first before any other basic variables do, and which, therefore, +should leave the basis in order to keep primal feasibility. + +\returns + +The routine \verb|glp_prim_rtest| returns the index, \verb|piv|, in the +arrays \verb|ind| and \verb|val| corresponding to the pivot element +chosen, $1\leq$ \verb|piv| $\leq$ \verb|len|. If the adjacent basic +solution is primal unbounded, and therefore the choice cannot be made, +the routine returns zero. + +\para{Comments} + +If the non-basic variable $x$ is presented in the LP problem object, +the input column can be computed with the routine +\verb|glp_eval_tab_col|; otherwise, it can be computed with the routine +\verb|glp_transform_col|. + +\newpage + +\subsection{glp\_dual\_rtest --- perform dual ratio test} + +\synopsis + +\begin{verbatim} + int glp_dual_rtest(glp_prob *P, int len, const int ind[], const double val[], + int dir, double eps); +\end{verbatim} + +\description + +The routine \verb|glp_dual_rtest| performs the dual ratio test using +an explicitly specified row of the simplex table. + +The current basic solution associated with the LP problem object must +be dual feasible. + +The explicitly specified row of the simplex table is a linear form +that shows how some basic variable $x$ (which is not necessarily +presented in the problem object) depends on non-basic variables $x_N$: +$$x=\xi_1(x_N)_1+\xi_2(x_N)_2+\dots+\xi_n(x_N)_n.$$ + +The row is specified on entry to the routine in sparse format. Ordinal +numbers of non-basic variables $(x_N)_j$ should be placed in locations +\verb|ind[1]|, \dots, \verb|ind[len]|, where ordinal numbers 1 to $m$ +denote auxiliary variables, and ordinal numbers $m+1$ to $m+n$ denote +structural variables. The corresponding non-zero coefficients $\xi_j$ +should be placed in locations \verb|val[1]|, \dots, \verb|val[len]|. +The arrays \verb|ind| and \verb|val| are not changed by the routine. + +The parameter \verb|dir| specifies direction in which the variable $x$ +changes on leaving the basis: $+1$ means that $x$ goes on its lower +bound, so its reduced cost (dual variable) is increasing (minimization) +or decreasing (maximization); $-1$ means that $x$ goes on its upper +bound, so its reduced cost is decreasing (minimization) or increasing +(maximization). + +The parameter \verb|eps| is an absolute tolerance (small positive +number, say, $10^{-9}$) used by the routine to skip $\xi_j$'s whose +magnitude is less than \verb|eps|. + +The routine determines which non-basic variable (among those specified +in \verb|ind[1]|, \dots,\linebreak \verb|ind[len]|) should enter the +basis in order to keep dual feasibility, because its reduced cost +reaches the (zero) bound first before this occurs for any other +non-basic variables. + +\returns + +The routine \verb|glp_dual_rtest| returns the index, \verb|piv|, in the +arrays \verb|ind| and \verb|val| corresponding to the pivot element +chosen, $1\leq$ \verb|piv| $\leq$ \verb|len|. If the adjacent basic +solution is dual unbounded, and therefore the choice cannot be made, +the routine returns zero. + +\para{Comments} + +If the basic variable $x$ is presented in the LP problem object, the +input row can be computed\linebreak with the routine +\verb|glp_eval_tab_row|; otherwise, it can be computed with the routine +\linebreak \verb|glp_transform_row|. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Post-optimal analysis routines} + +\subsection{glp\_analyze\_bound --- analyze active bound of non-basic +variable} + +\synopsis + +\begin{verbatim} + void glp_analyze_bound(glp_prob *P, int k, double *limit1, int *var1, + double *limit2, int *var2); +\end{verbatim} + +\description + +The routine \verb|glp_analyze_bound| analyzes the effect of varying the +active bound of specified non-basic variable. + +The non-basic variable is specified by the parameter $k$, where +$1\leq k\leq m$ means auxiliary variable of corresponding row, and +$m+1\leq k\leq m+n$ means structural variable (column). + +Note that the current basic solution must be optimal, and the basis +factorization must exist. + +Results of the analysis have the following meaning. + +\verb|value1| is the minimal value of the active bound, at which the +basis still remains primal feasible and thus optimal. \verb|-DBL_MAX| +means that the active bound has no lower limit. + +\verb|var1| is the ordinal number of an auxiliary (1 to $m$) or +structural ($m+1$ to $m+n$) basic variable, which reaches its bound +first and thereby limits further decreasing the active bound being +analyzed. if \verb|value1| = \verb|-DBL_MAX|, \verb|var1| is set to 0. + +\verb|value2| is the maximal value of the active bound, at which the +basis still remains primal feasible and thus optimal. \verb|+DBL_MAX| +means that the active bound has no upper limit. + +\verb|var2| is the ordinal number of an auxiliary (1 to $m$) or +structural ($m+1$ to $m+n$) basic variable, which reaches its bound +first and thereby limits further increasing the active bound being +analyzed. if \verb|value2| = \verb|+DBL_MAX|, \verb|var2| is set to 0. + +The parameters \verb|value1|, \verb|var1|, \verb|value2|, \verb|var2| +can be specified as \verb|NULL|, in which case corresponding information +is not stored. + +\subsection{glp\_analyze\_coef --- analyze objective coefficient at +basic variable} + +\synopsis + +\begin{verbatim} + void glp_analyze_coef(glp_prob *P, int k, + double *coef1, int *var1, double *value1, + double *coef2, int *var2, double *value2); +\end{verbatim} + +\description + +The routine \verb|glp_analyze_coef| analyzes the effect of varying the +objective coefficient at specified basic variable. + +The basic variable is specified by the parameter $k$, where +$1\leq k\leq m$ means auxiliary variable of corresponding row, and +$m+1\leq k\leq m+n$ means structural variable (column). + +Note that the current basic solution must be optimal, and the basis +factorization must exist. + +Results of the analysis have the following meaning. + +\verb|coef1| is the minimal value of the objective coefficient, at +which the basis still remains dual feasible and thus optimal. +\verb|-DBL_MAX| means that the objective coefficient has no lower +limit. + +\verb|var1| is the ordinal number of an auxiliary (1 to $m$) or +structural ($m+1$ to $m+n$) non-basic variable, whose reduced cost +reaches its zero bound first and thereby limits further decreasing the +objective coefficient being analyzed. +If \verb|coef1| = \verb|-DBL_MAX|, \verb|var1| is set to 0. + +\verb|value1| is value of the basic variable being analyzed in an +adjacent basis, which is defined as follows. Let the objective +coefficient reach its minimal value (\verb|coef1|) and continue +decreasing. Then the reduced cost of the limiting non-basic variable +(\verb|var1|) becomes dual infeasible and the current basis becomes +non-optimal that forces the limiting non-basic variable to enter the +basis replacing there some basic variable that leaves the basis to keep +primal feasibility. Should note that on determining the adjacent basis +current bounds of the basic variable being analyzed are ignored as if +it were free (unbounded) variable, so it cannot leave the basis. It may +happen that no dual feasible adjacent basis exists, in which case +\verb|value1| is set to \verb|-DBL_MAX| or \verb|+DBL_MAX|. + +\verb|coef2| is the maximal value of the objective coefficient, at +which the basis still remains dual feasible and thus optimal. +\verb|+DBL_MAX| means that the objective coefficient has no upper +limit. + +\verb|var2| is the ordinal number of an auxiliary (1 to $m$) or +structural ($m+1$ to $m+n$) non-basic variable, whose reduced cost +reaches its zero bound first and thereby limits further increasing the +objective coefficient being analyzed. +If \verb|coef2| = \verb|+DBL_MAX|, \verb|var2| is set to 0. + +\verb|value2| is value of the basic variable being analyzed in an +adjacent basis, which is defined exactly in the same way as +\verb|value1| above with exception that now the objective coefficient +is increasing. + +The parameters \verb|coef1|, \verb|var1|, \verb|value1|, \verb|coef2|, +\verb|var2|, \verb|value2| can be specified as \verb|NULL|, in which +case corresponding information is not stored. + +%* eof *% diff --git a/resources/3rdparty/glpk-4.57/doc/glpk05.tex b/resources/3rdparty/glpk-4.57/doc/glpk05.tex new file mode 100644 index 000000000..d15123e3f --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/glpk05.tex @@ -0,0 +1,1090 @@ +%* glpk05.tex *% + +\chapter{Branch-and-Cut API Routines} + +\section{Introduction} + +\subsection{Using the callback routine} + +The GLPK MIP solver based on the branch-and-cut method allows the +application program to control the solution process. This is attained +by means of the user-defined callback routine, which is called by the +solver at various points of the branch-and-cut algorithm. + +The callback routine passed to the MIP solver should be written by the +user and has the following specification:\footnote{The name +{\tt foo\_bar} used here is a placeholder for the callback routine +name.} + +\begin{verbatim} + void foo_bar(glp_tree *T, void *info); +\end{verbatim} + +\noindent +where \verb|tree| is a pointer to the data structure \verb|glp_tree|, +which should be used on subsequent calls to branch-and-cut interface +routines, and \verb|info| is a transit pointer passed to the routine +\verb|glp_intopt|, which may be used by the application program to pass +some external data to the callback routine. + +The callback routine is passed to the MIP solver through the control +parameter structure \verb|glp_iocp| (see Chapter ``Basic API +Routines'', Section ``Mixed integer programming routines'', Subsection +``Solve MIP problem with the branch-and-cut method'') as follows: + +\begin{verbatim} + glp_prob *mip; + glp_iocp parm; + . . . + glp_init_iocp(&parm); + . . . + parm.cb_func = foo_bar; + parm.cb_info = ... ; + ret = glp_intopt(mip, &parm); + . . . +\end{verbatim} + +To determine why it is being called by the MIP solver the callback +routine should use the routine \verb|glp_ios_reason| (described in this +section below), which returns a code indicating the reason for calling. +Depending on the reason the callback routine may perform necessary +actions to control the solution process. + +The reason codes, which correspond to various point of the +branch-and-cut algorithm implemented in the MIP solver, are described +in Subsection ``Reasons for calling the callback routine'' below. + +To ignore calls for reasons, which are not processed by the callback +routine, it should simply return to the MIP solver doing nothing. For +example: + +\begin{verbatim} +void foo_bar(glp_tree *T, void *info) +{ . . . + switch (glp_ios_reason(T)) + { case GLP_IBRANCH: + . . . + break; + case GLP_ISELECT: + . . . + break; + default: + /* ignore call for other reasons */ + break; + } + return; +} +\end{verbatim} + +To control the solution process as well as to obtain necessary +information the callback routine may use the branch-and-cut API +routines described in this chapter. Names of all these routines begin +with `\verb|glp_ios_|'. + +\subsection{Branch-and-cut algorithm} + +This section gives a schematic description of the branch-and-cut +algorithm as it is implemented in the GLPK MIP solver. + +{\it 1. Initialization} + +Set $L:=\{P_0\}$, where $L$ is the {\it active list} (i.e. the list of +active subproblems), $P_0$ is the original MIP problem to be solved. + +Set $z^{\it best}:=+\infty$ (in case of minimization) or +$z^{\it best}:=-\infty$ (in case of maximization), where $z^{\it best}$ +is {\it incumbent value}, i.e. an upper (minimization) or lower +(maximization) global bound for $z^{\it opt}$, the optimal objective +value for $P^0$. + +{\it 2. Subproblem selection} + +If $L=\varnothing$ then GO TO 9. + +Select $P\in L$, i.e. make active subproblem $P$ current. + +\newpage + +{\it 3. Solving LP relaxation} + +Solve $P^{\it LP}$, which is LP relaxation of $P$. + +If $P^{\it LP}$ has no primal feasible solution then GO TO 8. + +Let $z^{\it LP}$ be the optimal objective value for $P^{\it LP}$. + +If $z^{\it LP}\geq z^{\it best}$ (minimization) or +$z^{\it LP}\leq z^{\rm best}$ (), GO TO 8. + +{\it 4. Adding ``lazy'' constraints} + +Let $x^{\it LP}$ be the optimal solution to $P^{\it LP}$. + +If there are ``lazy'' constraints (i.e. essential constraints not +included in the original MIP problem $P_0$), which are violated at the +optimal point $x^{\it LP}$, add them to $P$, and GO TO 3. + +{\it 5. Check for integrality} + +Let $x_j$ be a variable, which is required to be integer, and let +$x^{\it LP}_j\in x^{\it LP}$ be its value in the optimal solution to +$P^{\it LP}$. + +If $x^{\it LP}_j$ are integral for all integer variables, then a better +integer feasible solution is found. Store its components, set +$z^{\it best}:=z^{\it LP}$, and GO TO 8. + +{\it 6. Adding cutting planes} + +If there are cutting planes (i.e. valid constraints for $P$), +which are violated at the optimal point $x^{\it LP}$, add them to $P$, +and GO TO 3. + +{\it 7. Branching} + +Select {\it branching variable} $x_j$, i.e. a variable, which is +required to be integer, and whose value $x^{\it LP}_j\in x^{\it LP}$ is +fractional in the optimal solution to $P^{\it LP}$. + +Create new subproblem $P^D$ (so called {\it down branch}), which is +identical to the current subproblem $P$ with exception that the upper +bound of $x_j$ is replaced by $\lfloor x^{\it LP}_j\rfloor$. (For +example, if $x^{\it LP}_j=3.14$, the new upper bound of $x_j$ in the +down branch will be $\lfloor 3.14\rfloor=3$.) + +Create new subproblem $P^U$ (so called {\it up branch}), which is +identical to the current subproblem $P$ with exception that the lower +bound of $x_j$ is replaced by $\lceil x^{\it LP}_j\rceil$. (For example, +if $x^{\it LP}_j=3.14$, the new lower bound of $x_j$ in the up branch +will be $\lceil 3.14\rceil=4$.) + +Set $L:=(L\backslash\{P\})\cup\{P^D,P^U\}$, i.e. remove the current +subproblem $P$ from the active list $L$ and add two new subproblems +$P^D$ and $P^U$ to it. Then GO TO 2. + +{\it 8. Pruning} + +Remove from the active list $L$ all subproblems (including the current +one), whose local bound $\widetilde{z}$ is not better than the global +bound $z^{\it best}$, i.e. set $L:=L\backslash\{P\}$ for all $P$, where +$\widetilde{z}\geq z^{\it best}$ (in case of minimization) or +$\widetilde{z}\leq z^{\it best}$ (in case of maximization), and then +GO TO 2. + +The local bound $\widetilde{z}$ for subproblem $P$ is an lower +(minimization) or upper (maximization) bound for integer optimal +solution to {\it this} subproblem (not to the original problem). This +bound is local in the sense that only subproblems in the subtree rooted +at node $P$ cannot have better integer feasible solutions. Note that +the local bound is not necessarily the optimal objective value to LP +relaxation $P^{\it LP}$. + +{\it 9. Termination} + +If $z^{\it best}=+\infty$ (in case of minimization) or +$z^{\it best}=-\infty$ (in case of maximization), the original problem +$P_0$ has no integer feasible solution. Otherwise, the last integer +feasible solution stored on step 5 is the integer optimal solution to +the original problem $P_0$ with $z^{\it opt}=z^{\it best}$. STOP. + +\subsection{The search tree} + +On the branching step of the branch-and-cut algorithm the current +subproblem is divided into two\footnote{In more general cases the +current subproblem may be divided into more than two subproblems. +However, currently such feature is not used in GLPK.} new subproblems, +so the set of all subproblems can be represented in the form of a rooted +tree, which is called the {\it search} or {\it branch-and-bound} tree. +An example of the search tree is shown on Fig.~1. Each node of the +search tree corresponds to a subproblem, so the terms `node' and +`subproblem' may be used synonymously. + +\begin{figure}[t] +\noindent\hfil +\xymatrix @R=20pt @C=10pt +{&&&&&&*+<14pt>[o][F=]{A}\ar@{-}[dllll]\ar@{-}[dr]\ar@{-}[drrrr]&&&&\\ +&&*+<14pt>[o][F=]{B}\ar@{-}[dl]\ar@{-}[dr]&&&&&*+<14pt>[o][F=]{C} +\ar@{-}[dll]\ar@{-}[dr]\ar@{-}[drrr]&&&*+<14pt>[o][F-]{\times}\\ +&*+<14pt>[o][F-]{\times}\ar@{-}[dl]\ar@{-}[d]\ar@{-}[dr]&& +*+<14pt>[o][F-]{D}&&*+<14pt>[o][F=]{E}\ar@{-}[dl]\ar@{-}[dr]&&& +*+<14pt>[o][F=]{F}\ar@{-}[dl]\ar@{-}[dr]&&*+<14pt>[o][F-]{G}\\ +*+<14pt>[o][F-]{\times}&*+<14pt>[o][F-]{\times}&*+<14pt>[o][F-]{\times} +&&*+<14pt>[][F-]{H}&&*+<14pt>[o][F-]{I}&*+<14pt>[o][F-]{\times}&& +*+<14pt>[o][F-]{J}&\\} + +\bigskip + +\noindent\hspace{.8in} +\xymatrix @R=11pt +{*+<20pt>[][F-]{}&*\txt{\makebox[1in][l]{Current}}&& +*+<20pt>[o][F-]{}&*\txt{\makebox[1in][l]{Active}}\\ +*+<20pt>[o][F=]{}&*\txt{\makebox[1in][l]{Non-active}}&& +*+<14pt>[o][F-]{\times}&*\txt{\makebox[1in][l]{Fathomed}}\\ +} + +\bigskip + +\begin{center} +Fig. 1. An example of the search tree. +\end{center} +\end{figure} + +In GLPK each node may have one of the following four statuses: + +\vspace*{-8pt} + +\begin{itemize} +\item {\it current node} is the active node currently being +processed; + +\item {\it active node} is a leaf node, which still has to be +processed; + +\item {\it non-active node} is a node, which has been processed, +but not fathomed; + +\item {\it fathomed node} is a node, which has been processed and +fathomed. +\end{itemize} + +\vspace*{-8pt} + +In the data structure representing the search tree GLPK keeps only +current, active, and non-active nodes. Once a node has been fathomed, +it is removed from the tree data structure. + +Being created each node of the search tree is assigned a distinct +positive integer called the {\it subproblem reference number}, which +may be used by the application program to specify a particular node of +the tree. The root node corresponding to the original problem to be +solved is always assigned the reference number 1. + +\subsection{Current subproblem} + +The current subproblem is a MIP problem corresponding to the current +node of the search tree. It is represented as the GLPK problem object +(\verb|glp_prob|) that allows the application program using API +routines to access its content in the standard way. If the MIP +presolver is not used, it is the original problem object passed to the +routine \verb|glp_intopt|; otherwise, it is an internal problem object +built by the MIP presolver. + +Note that the problem object is used by the MIP solver itself during +the solution process for various purposes (to solve LP relaxations, to +perfom branching, etc.), and even if the MIP presolver is not used, the +current content of the problem object may differ from its original +content. For example, it may have additional rows, bounds of some rows +and columns may be changed, etc. In particular, LP segment of the +problem object corresponds to LP relaxation of the current subproblem. +However, on exit from the MIP solver the content of the problem object +is restored to its original state. + +To obtain information from the problem object the application program +may use any API routines, which do not change the object. Using API +routines, which change the problem object, is restricted to stipulated +cases. + +\subsection{The cut pool} + +The {\it cut pool} is a set of cutting plane constraints maintained by +the MIP solver. It is used by the GLPK cut generation routines and may +be used by the application program in the same way, i.e. rather than +to add cutting plane constraints directly to the problem object the +application program may store them to the cut pool. In the latter case +the solver looks through the cut pool, selects efficient constraints, +and adds them to the problem object. + +\subsection{Reasons for calling the callback routine} + +The callback routine may be called by the MIP solver for the following +reasons. + +\para{Request for subproblem selection} + +The callback routine is called with the reason code \verb|GLP_ISELECT| +if the current subproblem has been fathomed and therefore there is no +current subproblem. + +In response the callback routine may select some subproblem from the +active list and pass its reference number to the solver using the +routine \verb|glp_ios_select_node|, in which case the solver continues +the search from the specified active subproblem. If no selection is +made by the callback routine, the solver uses a backtracking technique +specified by the control parameter \verb|bt_tech|. + +To explore the active list (i.e. active nodes of the branch-and-bound +tree) the callback routine may use the routines \verb|glp_ios_next_node| +and \verb|glp_ios_prev_node|. + +\para{Request for preprocessing} + +The callback routine is called with the reason code \verb|GLP_IPREPRO| +if the current subproblem has just been selected from the active list +and its LP relaxation is not solved yet. + +In response the callback routine may perform some preprocessing of the +current subproblem like tightening bounds of some variables or removing +bounds of some redundant constraints. + +\para{Request for row generation} + +The callback routine is called with the reason code \verb|GLP_IROWGEN| +if LP relaxation of the current subproblem has just been solved to +optimality and its objective value is better than the best known +integer feasible solution. + +In response the callback routine may add one or more ``lazy'' +constraints (rows), which are violated by the current optimal solution +of LP relaxation, using API routines \verb|glp_add_rows|, +\verb|glp_set_row_name|, \verb|glp_set_row_bnds|, and +\verb|glp_set_mat_row|, in which case the solver will perform +re-optimization of LP relaxation. If there are no violated constraints, +the callback routine should just return. + +Note that components of optimal solution to LP relaxation can be +obtained with API\linebreak routines \verb|glp_get_obj_val|, +\verb|glp_get_row_prim|, \verb|glp_get_row_dual|, +\verb|glp_get_col_prim|, and\linebreak \verb|glp_get_col_dual|. + +\para{Request for heuristic solution} + +The callback routine is called with the reason code \verb|GLP_IHEUR| +if LP relaxation of the current subproblem being solved to optimality +is integer infeasible (i.e. values of some structural variables of +integer kind are fractional), though its objective value is better than +the best known integer feasible solution. + +In response the callback routine may try applying a primal heuristic +to find an integer feasible solution,\footnote{Integer feasible to the +original MIP problem, not to the current subproblem.} which is better +than the best known one. In case of success the callback routine may +store such better solution in the problem object using the routine +\verb|glp_ios_heur_sol|. + +\para{Request for cut generation} + +The callback routine is called with the reason code \verb|GLP_ICUTGEN| +if LP relaxation of the current subproblem being solved to optimality +is integer infeasible (i.e. values of some structural variables of +integer kind are fractional), though its objective value is better than +the best known integer feasible solution. + +In response the callback routine may reformulate the {\it current} +subproblem (before it will be splitted up due to branching) by adding +to the problem object one or more {\it cutting plane constraints}, +which cut off the fractional optimal point from the MIP +polytope.\footnote{Since these constraints are added to the current +subproblem, they may be globally as well as locally valid.} + +Adding cutting plane constraints may be performed in two ways. +One way is the same as for the reason code \verb|GLP_IROWGEN| (see +above), in which case the callback routine adds new rows corresponding +to cutting plane constraints directly to the current subproblem. + +The other way is to add cutting plane constraints to the +{\it cut pool}, a set of cutting plane constraints maintained by the +solver, rather than directly to the current subproblem. In this case +after return from the callback routine the solver looks through the +cut pool, selects efficient cutting plane constraints, adds them to the +current subproblem, drops other constraints, and then performs +re-optimization. + +\para{Request for branching} + +The callback routine is called with the reason code \verb|GLP_IBRANCH| +if LP relaxation of the current subproblem being solved to optimality +is integer infeasible (i.e. values of some structural variables of +integer kind are fractional), though its objective value is better than +the best known integer feasible solution. + +In response the callback routine may choose some variable suitable for +branching (i.e. integer variable, whose value in optimal solution to +LP relaxation of the current subproblem is fractional) and pass its +ordinal number to the solver using the routine +\verb|glp_ios_branch_upon|, in which case the solver splits the current +subproblem in two new subproblems and continues the search. +If no choice is made by the callback routine, the solver uses +a branching technique specified by the control parameter \verb|br_tech|. + +\para{Better integer solution found} + +The callback routine is called with the reason code \verb|GLP_IBINGO| +if LP relaxation of the current subproblem being solved to optimality +is integer feasible (i.e. values of all structural variables of integer +kind are integral within the working precision) and its objective value +is better than the best known integer feasible solution. + +Optimal solution components for LP relaxation can be obtained in the +same way as for the reason code \verb|GLP_IROWGEN| (see above). + +Components of the new MIP solution can be obtained with API routines +\verb|glp_mip_obj_val|, \verb|glp_mip_row_val|, and +\verb|glp_mip_col_val|. Note, however, that due to row/cut generation +there may be additional rows in the problem object. + +The difference between optimal solution to LP relaxation and +corresponding MIP solution is that in the former case some structural +variables of integer kind (namely, basic variables) may have values, +which are close to nearest integers within the working precision, while +in the latter case all such variables have exact integral values. + +The reason \verb|GLP_IBINGO| is intended only for informational +purposes, so the callback routine should not modify the problem object +in this case. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{Basic routines} + +\subsection{glp\_ios\_reason --- determine reason for calling the +callback routine} + +\synopsis + +\begin{verbatim} + int glp_ios_reason(glp_tree *T); +\end{verbatim} + +\returns + +The routine \verb|glp_ios_reason| returns a code, which indicates why +the user-defined callback routine is being called: + +\verb|GLP_ISELECT| --- request for subproblem selection; + +\verb|GLP_IPREPRO| --- request for preprocessing; + +\verb|GLP_IROWGEN| --- request for row generation; + +\verb|GLP_IHEUR | --- request for heuristic solution; + +\verb|GLP_ICUTGEN| --- request for cut generation; + +\verb|GLP_IBRANCH| --- request for branching; + +\verb|GLP_IBINGO | --- better integer solution found. + +\subsection{glp\_ios\_get\_prob --- access the problem object} + +\synopsis + +\begin{verbatim} + glp_prob *glp_ios_get_prob(glp_tree *T); +\end{verbatim} + +\description + +The routine \verb|glp_ios_get_prob| can be called from the user-defined +callback routine to access the problem object, which is used by the MIP +solver. It is the original problem object passed to the routine +\verb|glp_intopt| if the MIP presolver is not used; otherwise it is an +internal problem object built by the presolver. + +\returns + +The routine \verb|glp_ios_get_prob| returns a pointer to the problem +object used by the MIP solver. + +\para{Comments} + +To obtain various information about the problem instance the callback +routine can access the problem object (i.e. the object of type +\verb|glp_prob|) using the routine \verb|glp_ios_get_prob|. It is the +original problem object passed to the routine \verb|glp_intopt| if the +MIP presolver is not used; otherwise it is an internal problem object +built by the presolver. + +\newpage + +\subsection{glp\_ios\_row\_attr --- determine additional row +attributes} + +\synopsis + +\begin{verbatim} + void glp_ios_row_attr(glp_tree *T, int i, glp_attr *attr); +\end{verbatim} + +\description + +The routine \verb|glp_ios_row_attr| retrieves additional attributes of +$i$-th row of the current subproblem and stores them in the structure +\verb|glp_attr|, which the parameter \verb|attr| points to. + +The structure \verb|glp_attr| has the following fields: + +\medskip + +{\tt int level} + +Subproblem level at which the row was created. (If \verb|level| = 0, +the row was added either to the original problem object passed to the +routine \verb|glp_intopt| or to the root subproblem on generating +``lazy'' or/and cutting plane constraints.) + +\medskip + +{\tt int origin} + +The row origin flag: + +\verb|GLP_RF_REG | --- regular constraint; + +\verb|GLP_RF_LAZY| --- ``lazy'' constraint; + +\verb|GLP_RF_CUT | --- cutting plane constraint. + +\medskip + +{\tt int klass} + +The row class descriptor, which is a number passed to the routine +\verb|glp_ios_add_row| as its third parameter. If the row is a cutting +plane constraint generated by the solver, its class may be the +following: + +\verb|GLP_RF_GMI | --- Gomory's mixed integer cut; + +\verb|GLP_RF_MIR | --- mixed integer rounding cut; + +\verb|GLP_RF_COV | --- mixed cover cut; + +\verb|GLP_RF_CLQ | --- clique cut. + +\subsection{glp\_ios\_mip\_gap --- compute relative MIP gap} + +\synopsis + +\begin{verbatim} + double glp_ios_mip_gap(glp_tree *T); +\end{verbatim} + +\description + +The routine \verb|glp_ios_mip_gap| computes the relative MIP gap (also +called {\it duality gap}) with the following formula: +$${\tt gap} = \frac{|{\tt best\_mip} - {\tt best\_bnd}|} +{|{\tt best\_mip}| + {\tt DBL\_EPSILON}}$$ +where \verb|best_mip| is the best integer feasible solution found so +far, \verb|best_bnd| is the best (global) bound. If no integer feasible +solution has been found yet, \verb|gap| is set to \verb|DBL_MAX|. + +\returns + +The routine \verb|glp_ios_mip_gap| returns the relative MIP gap. + +\para{Comments} + +The relative MIP gap is used to measure the quality of the best integer +feasible solution found so far, because the optimal solution value +$z^*$ for the original MIP problem always lies in the range +$${\tt best\_bnd}\leq z^*\leq{\tt best\_mip}$$ +in case of minimization, or in the range +$${\tt best\_mip}\leq z^*\leq{\tt best\_bnd}$$ +in case of maximization. + +To express the relative MIP gap in percents the value returned by the +routine \verb|glp_ios_mip_gap| should be multiplied by 100\%. + +\subsection{glp\_ios\_node\_data --- access application-specific data} + +\synopsis + +\begin{verbatim} + void *glp_ios_node_data(glp_tree *T, int p); +\end{verbatim} + +\description + +The routine \verb|glp_ios_node_data| allows the application accessing +a memory block allocated for the subproblem (which may be active or +inactive), whose reference number is $p$. + +The size of the block is defined by the control parameter +\verb|cb_size| passed to the routine \verb|glp_intopt|. The block is +initialized by binary zeros on creating corresponding subproblem, and +its contents is kept until the subproblem will be removed from the +tree. + +The application may use these memory blocks to store specific data for +each subproblem. + +\returns + +The routine \verb|glp_ios_node_data| returns a pointer to the memory +block for the specified subproblem. Note that if \verb|cb_size| = 0, +the routine returns a null pointer. + +\subsection{glp\_ios\_select\_node --- select subproblem to continue +the search} + +\synopsis + +\begin{verbatim} + void glp_ios_select_node(glp_tree *T, int p); +\end{verbatim} + +\description + +The routine \verb|glp_ios_select_node| can be called from the +user-defined callback routine in response to the reason +\verb|GLP_ISELECT| to select an active subproblem, whose reference +number\linebreak is $p$. The search will be continued from the +subproblem selected. + +\newpage + +\subsection{glp\_ios\_heur\_sol --- provide solution found by +heuristic} + +\synopsis + +\begin{verbatim} + int glp_ios_heur_sol(glp_tree *T, const double x[]); +\end{verbatim} + +\description + +The routine \verb|glp_ios_heur_sol| can be called from the user-defined +callback routine in response to the reason \verb|GLP_IHEUR| to provide +an integer feasible solution found by a primal heuristic. + +Primal values of {\it all} variables (columns) found by the heuristic +should be placed in locations $x[1]$, \dots, $x[n]$, where $n$ is the +number of columns in the original problem object. Note that the routine +\verb|glp_ios_heur_sol| does {\it not} check primal feasibility of the +solution provided. + +Using the solution passed in the array $x$ the routine computes value +of the objective function. If the objective value is better than the +best known integer feasible solution, the routine computes values of +auxiliary variables (rows) and stores all solution components in the +problem object. + +\returns + +If the provided solution is accepted, the routine +\verb|glp_ios_heur_sol| returns zero. Otherwise, if the provided +solution is rejected, the routine returns non-zero. + +\vspace*{-5pt} + +\subsection{glp\_ios\_can\_branch --- check if can branch upon +specified variable} + +\synopsis + +\begin{verbatim} + int glp_ios_can_branch(glp_tree *T, int j); +\end{verbatim} + +\returns + +If $j$-th variable (column) can be used to branch upon, the routine +returns non-zero, otherwise zero. + +\vspace*{-5pt} + +\subsection{glp\_ios\_branch\_upon --- choose variable to branch upon} + +\synopsis + +\begin{verbatim} + void glp_ios_branch_upon(glp_tree *T, int j, int sel); +\end{verbatim} + +\description + +The routine \verb|glp_ios_branch_upon| can be called from the +user-defined callback routine in response to the reason +\verb|GLP_IBRANCH| to choose a branching variable, whose ordinal number +\linebreak is $j$. Should note that only variables, for which the +routine \verb|glp_ios_can_branch| returns non-zero, can be used to +branch upon. + +The parameter \verb|sel| is a flag that indicates which branch +(subproblem) should be selected next to continue the search: + +\verb|GLP_DN_BRNCH| --- select down-branch; + +\verb|GLP_UP_BRNCH| --- select up-branch; + +\verb|GLP_NO_BRNCH| --- use general selection technique. + +\para{Comments} + +On branching the solver removes the current active subproblem from the +active list and creates two new subproblems ({\it down-} and {\it +up-branches}), which are added to the end of the active list. Note that +the down-branch is created before the up-branch, so the last active +subproblem will be the up-branch. + +The down- and up-branches are identical to the current subproblem with +exception that in the down-branch the upper bound of $x_j$, the variable +chosen to branch upon, is replaced by $\lfloor x_j^*\rfloor$, while in +the up-branch the lower bound of $x_j$ is replaced by +$\lceil x_j^*\rceil$, where $x_j^*$ is the value of $x_j$ in optimal +solution to LP relaxation of the current subproblem. For example, if +$x_j^*=3.14$, the new upper bound of $x_j$ in the down-branch is +$\lfloor 3.14\rfloor=3$, and the new lower bound in the up-branch is +$\lceil 3.14\rceil=4$.) + +Additionally the callback routine may select either down- or up-branch, +from which the solver will continue the search. If none of the branches +is selected, a general selection technique will be used. + +\subsection{glp\_ios\_terminate --- terminate the solution process} + +\synopsis + +\begin{verbatim} + void glp_ios_terminate(glp_tree *T); +\end{verbatim} + +\description + +The routine \verb|glp_ios_terminate| sets a flag indicating that the +MIP solver should prematurely terminate the search. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{The search tree exploring routines} + +\subsection{glp\_ios\_tree\_size --- determine size of the search tree} + +\synopsis + +\begin{verbatim} + void glp_ios_tree_size(glp_tree *T, int *a_cnt, int *n_cnt, int *t_cnt); +\end{verbatim} + +\description + +The routine \verb|glp_ios_tree_size| stores the following three counts +which characterize the current size of the search tree: + +\verb|a_cnt| is the current number of active nodes, i.e. the current +size of the active list; + +\verb|n_cnt| is the current number of all (active and inactive) nodes; + +\verb|t_cnt| is the total number of nodes including those which have +been already removed from the tree. This count is increased whenever +a new node appears in the tree and never decreased. + +If some of the parameters \verb|a_cnt|, \verb|n_cnt|, \verb|t_cnt| is +a null pointer, the corresponding count is not stored. + +\subsection{glp\_ios\_curr\_node --- determine current active +subproblem} + +\synopsis + +\begin{verbatim} + int glp_ios_curr_node(glp_tree *T); +\end{verbatim} + +\returns + +The routine \verb|glp_ios_curr_node| returns the reference number of +the current active subproblem. However, if the current subproblem does +not exist, the routine returns zero. + +\subsection{glp\_ios\_next\_node --- determine next active subproblem} + +\synopsis + +\begin{verbatim} + int glp_ios_next_node(glp_tree *T, int p); +\end{verbatim} + +\returns + +If the parameter $p$ is zero, the routine \verb|glp_ios_next_node| +returns the reference number of the first active subproblem. However, +if the tree is empty, zero is returned. + +If the parameter $p$ is not zero, it must specify the reference number +of some active subproblem, in which case the routine returns the +reference number of the next active subproblem. However, if there is +no next active subproblem in the list, zero is returned. + +All subproblems in the active list are ordered chronologically, i.e. +subproblem $A$ precedes subproblem $B$ if $A$ was created before $B$. + +\newpage + +\subsection{glp\_ios\_prev\_node --- determine previous active +subproblem} + +\synopsis + +\begin{verbatim} + int glp_ios_prev_node(glp_tree *T, int p); +\end{verbatim} + +\returns + +If the parameter $p$ is zero, the routine \verb|glp_ios_prev_node| +returns the reference number of the last active subproblem. However, if +the tree is empty, zero is returned. + +If the parameter $p$ is not zero, it must specify the reference number +of some active subproblem, in which case the routine returns the +reference number of the previous active subproblem. However, if there +is no previous active subproblem in the list, zero is returned. + +All subproblems in the active list are ordered chronologically, i.e. +subproblem $A$ precedes subproblem $B$ if $A$ was created before $B$. + +\subsection{glp\_ios\_up\_node --- determine parent subproblem} + +\synopsis + +\begin{verbatim} + int glp_ios_up_node(glp_tree *T, int p); +\end{verbatim} + +\returns + +The parameter $p$ must specify the reference number of some (active or +inactive) subproblem, in which case the routine \verb|iet_get_up_node| +returns the reference number of its parent subproblem. However, if the +specified subproblem is the root of the tree and, therefore, has +no parent, the routine returns zero. + +\subsection{glp\_ios\_node\_level --- determine subproblem level} + +\synopsis + +\begin{verbatim} + int glp_ios_node_level(glp_tree *T, int p); +\end{verbatim} + +\returns + +The routine \verb|glp_ios_node_level| returns the level of the +subproblem, whose reference number is $p$, in the branch-and-bound +tree. (The root subproblem has level 0, and the level of any other +subproblem is the level of its parent plus one.) + +\subsection{glp\_ios\_node\_bound --- determine subproblem local bound} + +\synopsis + +\begin{verbatim} + double glp_ios_node_bound(glp_tree *T, int p); +\end{verbatim} + +\returns + +The routine \verb|glp_ios_node_bound| returns the local bound for +(active or inactive) subproblem, whose reference number is $p$. + +\para{Comments} + +The local bound for subproblem $p$ is an lower (minimization) or upper +(maximization) bound for integer optimal solution to {\it this} +subproblem (not to the original problem). This bound is local in the +sense that only subproblems in the subtree rooted at node $p$ cannot +have better integer feasible solutions. + +On creating a subproblem (due to the branching step) its local bound is +inherited from its parent and then may get only stronger (never weaker). +For the root subproblem its local bound is initially set to +\verb|-DBL_MAX| (minimization) or \verb|+DBL_MAX| (maximization) and +then improved as the root LP relaxation has been solved. + +Note that the local bound is not necessarily the optimal objective +value to corresponding LP relaxation. + +\subsection{glp\_ios\_best\_node --- find active subproblem with best +local bound} + +\synopsis + +\begin{verbatim} + int glp_ios_best_node(glp_tree *T); +\end{verbatim} + +\returns + +The routine \verb|glp_ios_best_node| returns the reference number of +the active subproblem, whose local bound is best (i.e. smallest in case +of minimization or largest in case of maximization). However, if the +tree is empty, the routine returns zero. + +\para{Comments} + +The best local bound is an lower (minimization) or upper (maximization) +bound for integer optimal solution to the original MIP problem. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section{The cut pool routines} + +\subsection{glp\_ios\_pool\_size --- determine current size of the cut +pool} + +\synopsis + +\begin{verbatim} + int glp_ios_pool_size(glp_tree *T); +\end{verbatim} + +\returns + +The routine \verb|glp_ios_pool_size| returns the current size of the +cut pool, that is, the number of cutting plane constraints currently +added to it. + +\subsection{glp\_ios\_add\_row --- add constraint to the cut pool} + +\synopsis + +\begin{verbatim} + int glp_ios_add_row(glp_tree *T, const char *name, int klass, int flags, + int len, const int ind[], const double val[], int type, double rhs); +\end{verbatim} + +\description + +The routine \verb|glp_ios_add_row| adds specified row (cutting plane +constraint) to the cut pool. + +The cutting plane constraint should have the following format: +$$\sum_{j\in J}a_jx_j\left\{\begin{array}{@{}c@{}}\geq\\\leq\\ +\end{array}\right\}b,$$ +where $J$ is a set of indices (ordinal numbers) of structural +variables, $a_j$ are constraint coefficients, $x_j$ are structural +variables, $b$ is the right-hand side. + +The parameter \verb|name| specifies a symbolic name assigned to the +constraint (1 up to 255 characters). If it is \verb|NULL| or an empty +string, no name is assigned. + +The parameter \verb|klass| specifies the constraint class, which must +be either zero or a number in the range from 101 to 200. +The application may use this attribute to distinguish between cutting +plane constraints of different classes.\footnote{Constraint classes +numbered from 1 to 100 are reserved for GLPK cutting plane generators.} + +The parameter \verb|flags| currently is not used and must be zero. + +Ordinal numbers of structural variables (i.e. column indices) $j\in J$ +and numerical values of corresponding constraint coefficients $a_j$ +should be placed in locations \verb|ind[1]|, \dots, \verb|ind[len]| and +\verb|val[1]|, \dots, \verb|val[len]|, respectively, where +${\tt len}=|J|$ is the number of constraint coefficients, +$0\leq{\tt len}\leq n$, and $n$ is the number of columns in the problem +object. Coefficients with identical column indices are not allowed. +Zero coefficients are allowed, however, they are ignored. + +The parameter \verb|type| specifies the constraint type as follows: + +\verb|GLP_LO| means inequality constraint $\Sigma a_jx_j\geq b$; + +\verb|GLP_UP| means inequality constraint $\Sigma a_jx_j\leq b$; + +The parameter \verb|rhs| specifies the right-hand side $b$. + +All cutting plane constraints in the cut pool are identified by their +ordinal numbers 1, 2, \dots, $size$, where $size$ is the current size +of the cut pool. New constraints are always added to the end of the cut +pool, thus, ordinal numbers of previously added constraints are not +changed. + +\returns + +The routine \verb|glp_ios_add_row| returns the ordinal number of the +cutting plane constraint added, which is the new size of the cut pool. + +\para{Example} + +\begin{verbatim} +/* generate triangle cutting plane: + x[i] + x[j] + x[k] <= 1 */ +. . . +/* add the constraint to the cut pool */ +ind[1] = i, val[1] = 1.0; +ind[2] = j, val[2] = 1.0; +ind[3] = k, val[3] = 1.0; +glp_ios_add_row(tree, NULL, TRIANGLE_CUT, 0, 3, ind, val, GLP_UP, 1.0); +\end{verbatim} + +\para{Comments} + +Cutting plane constraints added to the cut pool are intended to be then +added only to the {\it current} subproblem, so these constraints can be +globally as well as locally valid. However, adding a constraint to the +cut pool does not mean that it will be added to the current +subproblem---it depends on the solver's decision: if the constraint +seems to be efficient, it is moved from the pool to the current +subproblem, otherwise it is simply dropped.\footnote{Globally valid +constraints could be saved and then re-used for other subproblems, but +currently such feature is not implemented.} + +Normally, every time the callback routine is called for cut generation, +the cut pool is empty. On the other hand, the solver itself can +generate cutting plane constraints (like Gomory's or mixed integer +rounding cuts), in which case the cut pool may be non-empty. + +\subsection{glp\_ios\_del\_row --- remove constraint from the cut pool} + +\synopsis + +\begin{verbatim} + void glp_ios_del_row(glp_tree *T, int i); +\end{verbatim} + +\description + +The routine \verb|glp_ios_del_row| deletes $i$-th row (cutting plane +constraint) from the cut pool, where $1\leq i\leq size$ is the ordinal +number of the constraint in the pool, $size$ is the current size of the +cut pool. + +Note that deleting a constraint from the cut pool leads to changing +ordinal numbers of other constraints remaining in the pool. New ordinal +numbers of the remaining constraints are assigned under assumption that +the original order of constraints is not changed. Let, for example, +there be four constraints $a$, $b$, $c$ and $d$ in the cut pool, which +have ordinal numbers 1, 2, 3 and 4, respectively, and let constraint +$b$ have been deleted. Then after deletion the remaining constraint $a$, +$c$ and $d$ are assigned new ordinal numbers 1, 2 and 3, respectively. + +To find the constraint to be deleted the routine \verb|glp_ios_del_row| +uses ``smart'' linear search, so it is recommended to remove +constraints in a natural or reverse order and avoid removing them in +a random order. + +\para{Example} + +\begin{verbatim} +/* keep first 10 constraints in the cut pool and remove other + constraints */ +while (glp_ios_pool_size(tree) > 10) + glp_ios_del_row(tree, glp_ios_pool_size(tree)); +\end{verbatim} + +\subsection{glp\_ios\_clear\_pool --- remove all constraints from the +cut pool} + +\synopsis + +\begin{verbatim} + void glp_ios_clear_pool(glp_tree *T); +\end{verbatim} + +\description + +The routine \verb|glp_ios_clear_pool| makes the cut pool empty deleting +all existing rows (cutting plane constraints) from it. + +%* eof *% diff --git a/resources/3rdparty/glpk-4.57/doc/glpk06.tex b/resources/3rdparty/glpk-4.57/doc/glpk06.tex new file mode 100644 index 000000000..dad96c578 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/glpk06.tex @@ -0,0 +1,462 @@ +%* glpk06.tex *% + +\chapter{Miscellaneous API Routines} + +\section{GLPK environment routines} + +\subsection{glp\_init\_env --- initialize GLPK environment} + +\synopsis + +\begin{verbatim} + int glp_init_env(void); +\end{verbatim} + +\description + +The routine \verb|glp_init_env| initializes the GLPK environment. +Normally the application program does not need to call this routine, +because it is called automatically on the first call to any API +routine. + +\returns + +\begin{retlist} +0 & initialization successful;\\ +1 & environment is already initialized;\\ +2 & initialization failed (insufficient memory);\\ +3 & initialization failed (unsupported programming model).\\ +\end{retlist} + +\subsection{glp\_version --- determine library version} + +\synopsis + +\begin{verbatim} + const char *glp_version(void); +\end{verbatim} + +\returns + +The routine \verb|glp_version| returns a pointer to a null-terminated +character string, which specifies the version of the GLPK library in +the form \verb|"X.Y"|, where `\verb|X|' is the major version number, +and `\verb|Y|' is the minor version number, for example, \verb|"4.16"|. + +\newpage + +\subsection{glp\_free\_env --- free GLPK environment} + +\synopsis + +\begin{verbatim} + int glp_free_env(void); +\end{verbatim} + +\description + +The routine \verb|glp_free_env| frees all resources used by GLPK +routines (memory blocks, etc.) which are currently still in use. + +Normally the application program does not need to call this routine, +because GLPK routines always free all unused resources. However, if +the application program even has deleted all problem objects, there +will be several memory blocks still allocated for the internal library +needs. For some reasons the application program may want GLPK to free +this memory, in which case it should call \verb|glp_free_env|. + +Note that a call to \verb|glp_free_env| invalidates all problem objects +which still exist. + +\returns + +\begin{retlist} +0 & termination successful;\\ +1 & environment is inactive (was not initialized).\\ +\end{retlist} + +\subsection{glp\_printf --- write formatted output to terminal} + +\synopsis + +\begin{verbatim} + void glp_printf(const char *fmt, ...); +\end{verbatim} + +\description + +The routine \verb|glp_printf| uses the format control string +\verb|fmt| to format its parameters and writes the formatted output to +the terminal. + +This routine is a replacement of the standard C function +\verb|printf| and used by all GLPK routines to perform terminal +output. The application program may use \verb|glp_printf| for the same +purpose that allows controlling its terminal output with the routines +\verb|glp_term_out| and \verb|glp_term_hook|. + +\subsection{glp\_vprintf --- write formatted output to terminal} + +\synopsis + +\begin{verbatim} + void glp_vprintf(const char *fmt, va_list arg); +\end{verbatim} + +\description + +The routine \verb|glp_vprintf| uses the format control string +\verb|fmt| to format its parameters specified by the list \verb|arg| +and writes the formatted output to the terminal. + +This routine is a replacement of the standard C function +\verb|vprintf| and used by all GLPK routines to perform terminal +output. The application program may use \verb|glp_vprintf| for the same +purpose that allows controlling its terminal output with the routines +\verb|glp_term_out| and \verb|glp_term_hook|. + +\newpage + +\subsection{glp\_term\_out --- enable/disable terminal output} + +\synopsis + +\begin{verbatim} + int glp_term_out(int flag); +\end{verbatim} + +\description + +Depending on the parameter flag the routine \verb|glp_term_out| enables +or disables terminal output performed by glpk routines: + +\verb|GLP_ON | --- enable terminal output; + +\verb|GLP_OFF| --- disable terminal output. + +\returns + +The routine \verb|glp_term_out| returns the previous value of the +terminal output flag. + +\subsection{glp\_term\_hook --- intercept terminal output} + +\synopsis + +\begin{verbatim} + void glp_term_hook(int (*func)(void *info, const char *s), void *info); +\end{verbatim} + +\description + +The routine \verb|glp_term_hook| installs the user-defined hook routine +to intercept all terminal output performed by GLPK routines. + +%This feature can be used to redirect the terminal output to other +%destination, for example, to a file or a text window. + +The parameter {\it func} specifies the user-defined hook routine. It is +called from an internal printing routine, which passes to it two +parameters: {\it info} and {\it s}. The parameter {\it info} is a +transit pointer specified in corresponding call to the routine +\verb|glp_term_hook|; it may be used to pass some additional information +to the hook routine. The parameter {\it s} is a pointer to the null +terminated character string, which is intended to be written to the +terminal. If the hook routine returns zero, the printing routine writes +the string {\it s} to the terminal in a usual way; otherwise, if the +hook routine returns non-zero, no terminal output is performed. + +To uninstall the hook routine both parameters {\it func} and {\it info} +should be specified as \verb|NULL|. + +\para{Example} + +\begin{footnotesize} +\begin{verbatim} +static int hook(void *info, const char *s) +{ FILE *foo = info; + fputs(s, foo); + return 1; +} + +int main(void) +{ FILE *foo; + . . . + glp_term_hook(hook, foo); /* redirect terminal output */ + . . . + glp_term_hook(NULL, NULL); /* resume terminal output */ + . . . +} +\end{verbatim} +\end{footnotesize} + +\newpage + +\subsection{glp\_open\_tee --- start copying terminal output} + +\synopsis + +\begin{verbatim} + int glp_open_tee(const char *fname); +\end{verbatim} + +\description + +The routine \verb|glp_open_tee| starts copying all the terminal output +to an output text file, whose name is specified by the character string +\verb|fname|. + +\returns + +\begin{retlist} +0 & operation successful;\\ +1 & copying terminal output is already active;\\ +2 & unable to create output file.\\ +\end{retlist} + +\subsection{glp\_close\_tee --- stop copying terminal output} + +\synopsis + +\begin{verbatim} + int glp_close_tee(void); +\end{verbatim} + +\description + +The routine \verb|glp_close_tee| stops copying the terminal output to +the output text file previously open by the routine \verb|glp_open_tee| +closing that file. + +\returns + +\begin{retlist} +0 & operation successful;\\ +1 & copying terminal output was not started.\\ +\end{retlist} + +\subsection{glp\_error --- display error message and terminate +execution} + +\synopsis + +\begin{verbatim} + void glp_error(const char *fmt, ...); +\end{verbatim} + +\description + +The routine \verb|glp_error| (implemented as a macro) formats its +parameters using the format control string \verb|fmt|, writes the +formatted message to the terminal, and then abnormally terminates the +program. + +\newpage + +\subsection{glp\_at\_error --- check for error state} + +\synopsis + +\begin{verbatim} + int glp_at_error(void); +\end{verbatim} + +\description + +The routine \verb|glp_at_error| checks if the GLPK environment is at +error state, i.~e.~if the call to the routine is (indirectly) made from +the \verb|glp_error| routine via an user-defined hook routine. + +This routine can be used, for example, by a custom output handler +(installed with the routine \verb|glp_term_hook|) to determine whether +or not the message to be displayed is an error message. + +\returns + +If the GLPK environment is at error state, the routine returns +non-zero, otherwise zero. + +\subsection{glp\_assert --- check logical condition} + +\synopsis + +\begin{verbatim} + void glp_assert(int expr); +\end{verbatim} + +\description + +The routine \verb|glp_assert| (implemented as a macro) checks +a logical condition specified by the expression \verb|expr|. If the +condition is true (non-zero), the routine does nothing; otherwise, if +the condition is false (zero), the routine prints an error message and +abnormally terminates the program. + +This routine is a replacement of the standard C function \verb|assert| +and used by all GLPK routines to check program logic. The application +program may use \verb|glp_assert| for the same purpose. + +\subsection{glp\_error\_hook --- install hook to intercept abnormal +termination} + +\synopsis + +\begin{verbatim} + void glp_error_hook(void (*func)(void *info), void *info); +\end{verbatim} + +\description + +The routine \verb|glp_error_hook| installs a user-defined hook routine +to intercept abnormal termination. + +The parameter \verb|func| specifies the user-defined hook routine. It +is called from the routine \verb|glp_error| before the latter calls the +abort function to abnormally terminate the application program because +of fatal error. The parameter \verb|info| is a transit pointer, +specified in the corresponding call to the routine +\verb|glp_error_hook|; it may be used to pass some information to the +hook routine. + +To uninstall the hook routine the parameters \verb|func| and \verb|info| +should be specified as \verb|NULL|. + +If the hook routine returns, the application program is abnormally +terminated. To prevent abnormal termnation the hook routine may perform +a global jump using the standard function \verb|longjmp|, in which case +the application program {\it must} call the routine \verb|glp_free_env|. + +\subsection{glp\_alloc --- allocate memory block} + +\synopsis + +\begin{verbatim} + void *glp_alloc(int n, int size); +\end{verbatim} + +\description + +The routine \verb|glp_alloc| dynamically allocates a memory block of +\verb|n|$\times$\verb|size| bytes long. Note that: + +1) the parameters \verb|n| and \verb|size| must be positive; + +2) having been allocated the memory block contains arbitrary data, that +is, it is {\it not} initialized by binary zeros; + +3) if the block cannot be allocated due to insufficient memory, the +routine prints an error message and abnormally terminates the program. + +This routine is a replacement of the standard C function \verb|malloc| +and used by GLPK routines for dynamic memory allocation. The +application program may use \verb|glp_alloc| for the same purpose. + +\returns + +The routine \verb|glp_alloc| returns a pointer to the memory block +allocated. To free this block the routine \verb|glp_free| (not the +standard C function \verb|free|!) should be used. + +\subsection{glp\_realloc --- reallocate memory block} + +\synopsis + +\begin{verbatim} + void *glp_realloc(void *ptr, int n, int size); +\end{verbatim} + +\description + +The routine \verb|glp_realloc| dynamically reallocates a memory block +pointed to by \verb|ptr|, which was previously allocated by the routine +\verb|glp_alloc| or reallocated by this routine. Note that the pointer +\verb|ptr| must be valid and must not be \verb|NULL|. The new size of +the memory block is \verb|n|$\times$\verb|size| bytes long. Note that: + +1) both parameters \verb|n| and \verb|size| must be positive; + +2) if the block cannot be reallocated due to insufficient memory, the +routine prints an error message and abnormally terminates the program. + +This routine is a replacement of the standard C function \verb|realloc| +and used by GLPK routines for dynamic memory allocation. The +application program may use \verb|glp_realloc| for the same purpose. + +\returns + +The routine \verb|glp_realloc| returns a pointer to the memory block +reallocated. To free this block the routine \verb|glp_free| (not the +standard C function \verb|free|!) should be used. + +\subsection{glp\_free --- free memory block} + +\synopsis + +\begin{verbatim} + void glp_free(void *ptr); +\end{verbatim} + +\description + +The routine \verb|glp_free| deallocates a memory block pointed to by +\verb|ptr|, which was previously allocated by the routine +\verb|glp_malloc| or reallocated by the routine \verb|glp_realloc|. +Note that the pointer \verb|ptr| must be valid and must not be +\verb|NULL|. + +This routine is a replacement of the standard C function \verb|free| +and used by GLPK routines for dynamic memory allocation. The +application program may use \verb|glp_free| for the same purpose. + +\subsection{glp\_mem\_usage --- get memory usage information} + +\synopsis + +\begin{verbatim} + void glp_mem_usage(int *count, int *cpeak, size_t *total, size_t *tpeak); +\end{verbatim} + +\description + +The routine \verb|glp_mem_usage| reports some information about +utilization of the memory by the routines \verb|glp_malloc|, +\verb|glp_calloc|, and \verb|glp_free|. Information is stored to +locations specified by corresponding parameters (see below). Any +parameter can be specified as \verb|NULL|, in which case corresponding +information is not stored. + +\verb|*count| is the number of currently allocated memory blocks. + +\verb|*cpeak| is the peak value of \verb|*count| reached since the +initialization of the GLPK library environment. + +\verb|*total| is the total amount, in bytes, of currently allocated +memory blocks. + +\verb|*tpeak| is the peak value of \verb|*total| reached since the +initialization of the GLPK library envirionment. + +\para{Example} + +\begin{footnotesize} +\begin{verbatim} +glp_mem_usage(&count, NULL, NULL, NULL); +printf("%d memory block(s) are still allocated\n", count); +\end{verbatim} +\end{footnotesize} + +\subsection{glp\_mem\_limit --- set memory usage limit} + +\synopsis + +\begin{verbatim} + void glp_mem_limit(int limit); +\end{verbatim} + +\description + +The routine \verb|glp_mem_limit| limits the amount of memory available +for dynamic allocation (with the routines \verb|glp_malloc| and +\verb|glp_calloc|) to \verb|limit| megabytes. + +%* eof *% diff --git a/resources/3rdparty/glpk-4.57/doc/glpk07.tex b/resources/3rdparty/glpk-4.57/doc/glpk07.tex new file mode 100644 index 000000000..004fe2ec8 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/glpk07.tex @@ -0,0 +1,258 @@ +%* glpk07.tex *% + +\chapter{Installing GLPK on Your Computer} +\label{install} + +\section{Downloading the distribution tarball} + +The distribution tarball of the most recent version of the GLPK +package can be found on \url{http://ftp.gnu.org/gnu/glpk/} [via http] +and \url{ftp://ftp.gnu.org/gnu/glpk/} [via FTP]. It can also be found +on one of the FTP mirrors; see \url{http://www.gnu.org/prep/ftp.html}. +Please use a mirror if possible. + +To make sure that the GLPK distribution tarball you have downloaded is +intact you need to download the corresponding `\verb|.sig|' file and +run a command like this: + +\begin{verbatim} + gpg --verify glpk-4.38.tar.gz.sig +\end{verbatim} + +\noindent +If that command fails because you do not have the required public key, +run the following command to import it: + +\begin{verbatim} + gpg --keyserver keys.gnupg.net --recv-keys 5981E818 +\end{verbatim} + +\noindent +and then re-run the previous command. + +\section{Unpacking the distribution tarball} + +The GLPK package (like all other GNU software) is distributed in the +form of packed archive. This is one file named \verb|glpk-X.Y.tar.gz|, +where {\it X} is the major version number and {\it Y} is the minor +version number. + +In order to prepare the distribution for installation you need to copy +the GLPK distribution file to a working subdirectory and then unpack +and unarchive the distribution file with the following command: + +\begin{verbatim} + tar zx < glpk-X.Y.tar +\end{verbatim} + +\newpage + +\section{Configuring the package} + +After unpacking and unarchiving the GLPK distribution you should +configure the package,\linebreak i.e. automatically tune it for your +platform. + +Normally, you should just \verb|cd| to the subdirectory \verb|glpk-X.Y| +and run the configure script, e.g. + +\begin{verbatim} + ./configure +\end{verbatim} + +The `\verb|configure|' shell script attempts to guess correct values +for various system-dependent variables used during compilation. It uses +those values to create a `\verb|Makefile|' in each directory of the +package. It also creates file `\verb|config.h|' containing +platform-dependent definitions. Finally, it creates a shell script +`\verb|config.status|' that you can run in the future to recreate the +current configuration, a file `\verb|config.cache|' that saves the +results of its tests to speed up reconfiguring, and a file +`\verb|config.log|' containing compiler output (useful mainly for +debugging `\verb|configure|'). + +Running `\verb|configure|' takes about a minute. While it is running, +it displays some informational messages that tell you what it +is doing. If you don't want to see these messages, run +`\verb|configure|' with its standard output redirected to +`\verb|dev/null|'; for example, `\verb|./configure > /dev/null|'. + +By default both static and shared versions of the GLPK library will be +compiled. Compilation of the shared librariy can be turned off by +specifying the `\verb|--disable-shared|' option to `\verb|configure|': + +\begin{verbatim} + ./configure --disable-shared +\end{verbatim} + +\noindent +If you encounter problems building the library try using the above +option, because some platforms do not support shared libraries. + +The GLPK package has some optional features listed below. By default +all these features are disabled. To enable a feature the corresponding +option should be passed to the configure script. + +\verb|--with-gmp | Enable using the GNU MP bignum library + +This feature allows the exact simplex solver to use the GNU MP bignum +library. If it is disabled, the exact simplex solver uses the GLPK +bignum module, which provides the same functionality as GNU MP, however, +it is much less efficient. + +For details about the GNU MP bignum library see its web page at +\url{http://gmplib.org/}. + +\verb|--enable-dl | The same as `\verb|--enable-dl=ltdl|' + +\verb|--enable-dl=ltdl | Enable shared library support (GNU) + +\verb|--enable-dl=dlfcn | Enable shared library support (POSIX) + +Currently this feature is only needed to provide dynamic linking to +ODBC and MySQL shared libraries (see below). + +For details about the GNU shared library support see the manual at +\url{http://www.gnu.org/software/libtool/manual/}. + +\verb|--enable-odbc | +Enable using ODBC table driver (\verb|libiodbc|) + +\verb|--enable-odbc=unix | +Enable using ODBC table driver (\verb|libodbc|) + +This feature allows transmitting data between MathProg model objects +and relational databases accessed through ODBC. + +For more details about this feature see the supplement ``Using Data +Tables in the GNU MathProg Modeling Language'' (\verb|doc/tables.pdf|). + +\verb|--enable-mysql | +Enable using MySQL table driver (\verb|libmysql|) + +This feature allows transmitting data between MathProg model objects +and MySQL relational databases. + +For more details about this feature see the supplement ``Using Data +Tables in the GNU MathProg Modeling Language'' (\verb|doc/tables.pdf|). + +\section{Compiling the package} + +Normally, you can compile (build) the package by typing the command: + +\begin{verbatim} + make +\end{verbatim} + +\noindent +It reads `\verb|Makefile|' generated by `\verb|configure|' and performs +all necessary jobs. + +If you want, you can override the `\verb|make|' variables \verb|CFLAGS| +and \verb|LDFLAGS| like this: + +\begin{verbatim} + make CFLAGS=-O2 LDFLAGS=-s +\end{verbatim} + +To compile the package in a different directory from the one containing +the source code, you must use a version of `\verb|make|' that supports +`\verb|VPATH|' variable, such as GNU `\verb|make|'. `\verb|cd|' to the +directory where you want the object files and executables to go and run +the `\verb|configure|' script. `\verb|configure|' automatically checks +for the source code in the directory that `\verb|configure|' is in and +in `\verb|..|'. If for some reason `\verb|configure|' is not in the +source code directory that you are configuring, then it will report +that it can't find the source code. In that case, run `\verb|configure|' +with the option `\verb|--srcdir=DIR|', where \verb|DIR| is the +directory that contains the source code. + +Some systems require unusual options for compilation or linking that +the `\verb|configure|' script does not know about. You can give +`\verb|configure|' initial values for variables by setting them in the +environment. Using a Bourne-compatible shell, you can do that on the +command line like this: + +\begin{verbatim} + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure +\end{verbatim} + +\noindent +Or on systems that have the `\verb|env|' program, you can do it like +this: + +\begin{verbatim} + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure +\end{verbatim} + +Here are the `\verb|make|' variables that you might want to override +with environment variables when running `\verb|configure|'. + +For these variables, any value given in the environment overrides the +value that `\verb|configure|' would choose: + +\verb|CC | C compiler program. The default is `\verb|cc|'. + +\verb|INSTALL | Program used to install files. The default value is +`\verb|install|' if you have it,\\ +\verb| | otherwise `\verb|cp|'. + +For these variables, any value given in the environment is added to the +value that `\verb|configure|' chooses: + +\verb|DEFS | Configuration options, in the form +`\verb|-Dfoo -Dbar| \dots'. + +\verb|LIBS | Libraries to link with, in the form +`\verb|-lfoo -lbar| \dots'. + +\section{Checking the package} + +To check the package, i.e. to run some tests included in the package, +you can use the following command: + +\begin{verbatim} + make check +\end{verbatim} + +\section{Installing the package} + +Normally, to install the GLPK package you should type the following +command: + +\begin{verbatim} + make install +\end{verbatim} + +\noindent +By default, `\verb|make install|' will install the package's files in +`\verb|usr/local/bin|', `\verb|usr/local/lib|', etc. You can specify an +installation prefix other than `\verb|/usr/local|' by giving +`\verb|configure|' the option `\verb|--prefix=PATH|'. Alternately, you +can do so by consistently giving a value for the `\verb|prefix|' +variable when you run `\verb|make|', e.g. + +\begin{verbatim} + make prefix=/usr/gnu + make prefix=/usr/gnu install +\end{verbatim} + +After installing you can remove the program binaries and object files +from the source directory by typing `\verb|make clean|'. To remove all +files that `\verb|configure|' created (`\verb|Makefile|', +`\verb|config.status|', etc.), just type `\verb|make distclean|'. + +The file `\verb|configure.ac|' is used to create `\verb|configure|' by +a program called `\verb|autoconf|'. You only need it if you want to +remake `\verb|configure|' using a newer version of `\verb|autoconf|'. + +\section{Uninstalling the package} + +To uninstall the GLPK package, i.e. to remove all the package's files +from the system places, you can use the following command: + +\begin{verbatim} + make uninstall +\end{verbatim} + +%* eof *% diff --git a/resources/3rdparty/glpk-4.57/doc/glpk08.tex b/resources/3rdparty/glpk-4.57/doc/glpk08.tex new file mode 100644 index 000000000..e56a8e892 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/glpk08.tex @@ -0,0 +1,738 @@ +%* glpk08.tex *% + +\chapter{MPS Format} +\label{champs} + +\section{Fixed MPS Format} +\label{secmps} + +The MPS format\footnote{The MPS format was developed in 1960's by IBM +as input format for their mathematical programming system MPS/360. +Today the MPS format is a most widely used format understood by most +mathematical programming packages. This appendix describes only the +features of the MPS format, which are implemented in the GLPK package.} +is intended for coding LP/MIP problem data. This format assumes the +formulation of LP/MIP problem (1.1)---(1.3) (see Section \ref{seclp}, +page \pageref{seclp}). + +{\it MPS file} is a text file, which contains two types of +cards\footnote{In 1960's MPS file was a deck of 80-column punched +cards, so the author decided to keep the word ``card'', which may be +understood as ``line of text file''.}: indicator cards and data cards. + +Indicator cards determine a kind of succeeding data. Each indicator +card has one word in uppercase letters beginning in column 1. + +Data cards contain problem data. Each data card is divided into six +fixed fields: + +\begin{center} +\begin{tabular}{lcccccc} +& Field 1 & Field 2 & Field 3 & Field 4 & Field 5 & Feld 6 \\ +\hline +Columns & 2---3 & 5---12 & 15---22 & 25---36 & 40---47 & 50---61 \\ +Contents & Code & Name & Name & Number & Name & Number \\ +\end{tabular} +\end{center} + +On a particular data card some fields may be optional. + +Names are used to identify rows, columns, and some vectors (see below). + +Aligning the indicator code in the field 1 to the left margin is +optional. + +All names specified in the fields 2, 3, and 5 should contain from 1 up +to 8 arbitrary characters (except control characters). If a name is +placed in the field 3 or 5, its first character should not be the dollar +sign `\verb|$|'. If a name contains spaces, the spaces are ignored. + +All numerical values in the fields 4 and 6 should be coded in the form +$sxx$\verb|E|$syy$, where $s$ is the plus `\verb|+|' or the minus +`\verb|-|' sign, $xx$ is a real number with optional decimal point, +$yy$ is an integer decimal exponent. Any number should contain up to 12 +characters. If the sign $s$ is omitted, the plus sign is assumed. The +exponent part is optional. If a number contains spaces, the spaces are +ignored. + +\newpage + +If a card has the asterisk `\verb|*|' in the column 1, this card is +considered as a comment and ignored. Besides, if the first character in +the field 3 or 5 is the dollar sign `\verb|$|', all characters from the +dollar sign to the end of card are considered as a comment and ignored. + +MPS file should contain cards in the following order: + +\vspace*{-8pt} + +\begin{itemize} +\item NAME indicator card; + +\item ROWS indicator card; + +\item data cards specifying rows (constraints); + +\item COLUMNS indicator card; + +\item data cards specifying columns (structural variables) and +constraint coefficients; + +\item RHS indicator card; + +\item data cards specifying right-hand sides of constraints; + +\item RANGES indicator card; + +\item data cards specifying ranges for double-bounded constraints; + +\item BOUNDS indicator card; + +\item data cards specifying types and bounds of structural +variables; + +\item ENDATA indicator card. +\end{itemize} + +\vspace*{-8pt} + +{\it Section} is a group of cards consisting of an indicator card and +data cards succeeding this indicator card. For example, the ROWS section +consists of the ROWS indicator card and data cards specifying rows. + +The sections RHS, RANGES, and BOUNDS are optional and may be omitted. + +\section{Free MPS Format} + +{\it Free MPS format} is an improved version of the standard (fixed) +MPS format described above.\footnote{This format was developed in the +beginning of 1990's by IBM as an alternative to the standard fixed MPS +format for Optimization Subroutine Library (OSL).} Note that all +changes in free MPS format concern only the coding of data while the +structure of data is the same for both fixed and free versions of the +MPS format. + +In free MPS format indicator and data records\footnote{{\it Record} in +free MPS format has the same meaning as {\it card} in fixed MPS format.} +may have arbitrary length not limited to 80 characters. Fields of data +records have no predefined positions, i.e. the fields may begin in any +position, except position 1, which must be blank, and must be separated +from each other by one or more blanks. However, the fields must appear +in the same order as in fixed MPS format. + +\newpage + +Symbolic names in fields 2, 3, and 5 may be longer than 8 +characters\footnote{GLPK allows symbolic names having up to 255 +characters.} and must not contain embedded blanks. + +Numeric values in fields 4 and 6 are limited to 12 characters and must +not contain embedded blanks. + +Only six fields on each data record are used. Any other fields are +ignored. + +If the first character of any field (not necessarily fields 3 and 5) +is the dollar sign (\$), all characters from the dollar sign to the end +of record are considered as a comment and ignored. + +\section{NAME indicator card} + +The NAME indicator card should be the first card in the MPS file +(except optional comment cards, which may precede the NAME card). This +card should contain the word \verb|NAME| in the columns 1---4 and the +problem name in the field 3. The problem name is optional and may be +omitted. + +\section{ROWS section} +\label{secrows} + +The ROWS section should start with the indicator card, which contains +the word \verb|ROWS| in the columns 1---4. + +Each data card in the ROWS section specifies one row (constraint) of +the problem. All these data cards have the following format. + +`\verb|N|' in the field 1 means that the row is free (unbounded): +$$-\infty < x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n} +< +\infty;$$ + +`\verb|L|' in the field 1 means that the row is of ``less than or equal +to'' type: +$$-\infty < x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n} +\leq b_i;$$ + +`\verb|G|' in the field 1 means that the row is of ``greater than or +equal to'' type: +$$b_i \leq x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n} +< +\infty;$$ + +`\verb|E|' in the field 1 means that the row is of ``equal to'' type: +$$x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n} \leq +b_i,$$ +where $b_i$ is a right-hand side. Note that each constraint has a +corresponding implictly defined auxiliary variable ($x_i$ above), whose +value is a value of the corresponding linear form, therefore row bounds +can be considered as bounds of such auxiliary variable. + +The filed 2 specifies a row name (which is considered as the name of +the corresponding auxiliary variable). + +\newpage + +The fields 3, 4, 5, and 6 are not used and should be empty. + +Numerical values of all non-zero right-hand sides $b_i$ should be +specified in the RHS section (see below). All double-bounded (ranged) +constraints should be specified in the RANGES section (see below). + +\section{COLUMNS section} + +The COLUMNS section should start with the indicator card, which +contains the word \verb|COLUMNS| in the columns 1---7. + +Each data card in the COLUMNS section specifies one or two constraint +coefficients $a_{ij}$ and also introduces names of columns, i.e. names +of structural variables. All these data cards have the following +format. + +The field 1 is not used and should be empty. + +The field 2 specifies a column name. If this field is empty, the column +name from the immediately preceeding data card is assumed. + +The field 3 specifies a row name defined in the ROWS section. + +The field 4 specifies a numerical value of the constraint coefficient +$a_{ij}$, which is placed in the corresponding row and column. + +The fields 5 and 6 are optional. If they are used, they should contain +a second pair ``row name---constraint coefficient'' for the same column. + +Elements of the constraint matrix (i.e. constraint coefficients) should +be enumerated in the column wise manner: all elements for the current +column should be specified before elements for the next column. However, +the order of rows in the COLUMNS section may differ from the order of +rows in the ROWS section. + +Constraint coefficients not specified in the COLUMNS section are +considered as zeros. Therefore zero coefficients may be omitted, +although it is allowed to explicitly specify them. + +\section{RHS section} + +The RHS section should start with the indicator card, which contains the +word \verb|RHS| in the columns 1---3. + +Each data card in the RHS section specifies one or two right-hand sides +$b_i$ (see Section \ref{secrows}, page \pageref{secrows}). All these +data cards have the following format. + +The field 1 is not used and should be empty. + +The field 2 specifies a name of the right-hand side (RHS) +vector\footnote{This feature allows the user to specify several RHS +vectors in the same MPS file. However, before solving the problem a +particular RHS vector should be chosen.}. If this field is empty, the +RHS vector name from the immediately preceeding data card is assumed. + +\newpage + +The field 3 specifies a row name defined in the ROWS section. + +The field 4 specifies a right-hand side $b_i$ for the row, whose name is +specified in the field 3. Depending on the row type $b_i$ is a lower +bound (for the row of \verb|G| type), an upper bound (for the row of +\verb|L| type), or a fixed value (for the row of \verb|E| +type).\footnote{If the row is of {\tt N} type, $b_i$ is considered as +a constant term of the corresponding linear form. Should note, however, +this convention is non-standard.} + +The fields 5 and 6 are optional. If they are used, they should contain +a second pair ``row name---right-hand side'' for the same RHS vector. + +All right-hand sides for the current RHS vector should be specified +before right-hand sides for the next RHS vector. However, the order of +rows in the RHS section may differ from the order of rows in the ROWS +section. + +Right-hand sides not specified in the RHS section are considered as +zeros. Therefore zero right-hand sides may be omitted, although it is +allowed to explicitly specify them. + +\section{RANGES section} + +The RANGES section should start with the indicator card, which contains +the word \verb|RANGES| in the columns 1---6. + +Each data card in the RANGES section specifies one or two ranges for +double-side constraints, i.e. for constraints that are of the types +\verb|L| and \verb|G| at the same time: +$$l_i \leq x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n} +\leq u_i,$$ +where $l_i$ is a lower bound, $u_i$ is an upper bound. All these data +cards have the following format. + +The field 1 is not used and should be empty. + +The field 2 specifies a name of the range vector\footnote{This feature +allows the user to specify several range vectors in the same MPS file. +However, before solving the problem a particular range vector should be +chosen.}. If this field is empty, the range vector name from the +immediately preceeding data card is assumed. + +The field 3 specifies a row name defined in the ROWS section. + +The field 4 specifies a range value $r_i$ (see the table below) for the +row, whose name is specified in the field 3. + +The fields 5 and 6 are optional. If they are used, they should contain +a second pair ``row name---range value'' for the same range vector. + +All range values for the current range vector should be specified before +range values for the next range vector. However, the order of rows in +the RANGES section may differ from the order of rows in the ROWS +section. + +For each double-side constraint specified in the RANGES section its +lower and upper bounds are determined as follows: + +\newpage + +\begin{center} +\begin{tabular}{cccc} +Row type & Sign of $r_i$ & Lower bound & Upper bound \\ +\hline +{\tt G} & $+$ or $-$ & $b_i$ & $b_i + |r_i|$ \\ +{\tt L} & $+$ or $-$ & $b_i - |r_i|$ & $b_i$ \\ +{\tt E} & $+$ & $b_i$ & $b_i + |r_i|$ \\ +{\tt E} & $-$ & $b_i - |r_i|$ & $b_i$ \\ +\end{tabular} +\end{center} + +\noindent +where $b_i$ is a right-hand side specified in the RHS section (if $b_i$ +is not specified, it is considered as zero), $r_i$ is a range value +specified in the RANGES section. + +\section{BOUNDS section} +\label{secbounds} + +The BOUNDS section should start with the indicator card, which contains +the word \verb|BOUNDS| in the columns 1---6. + +Each data card in the BOUNDS section specifies one (lower or upper) +bound for one structural variable (column). All these data cards have +the following format. + +The indicator in the field 1 specifies the bound type: + +\verb|LO| --- lower bound; + +\verb|UP| --- upper bound; + +\verb|FX| --- fixed variable (lower and upper bounds are equal); + +\verb|FR| --- free variable (no bounds); + +\verb|MI| --- no lower bound (lower bound is ``minus infinity''); + +\verb|PL| --- no upper bound (upper bound is ``plus infinity''). + +The field 2 specifies a name of the bound vector\footnote{This feature +allows the user to specify several bound vectors in the same MPS file. +However, before solving the problem a particular bound vector should be +chosen.}. If this field is empty, the bound vector name from the +immediately preceeding data card is assumed. + +The field 3 specifies a column name defined in the COLUMNS section. + +The field 4 specifies a bound value. If the bound type in the field 1 +differs from \verb|LO|, \verb|UP|, and \verb|FX|, the value in the field +4 is ignored and may be omitted. + +The fields 5 and 6 are not used and should be empty. + +All bound values for the current bound vector should be specified before +bound values for the next bound vector. However, the order of columns in +the BOUNDS section may differ from the order of columns in the COLUMNS +section. Specification of a lower bound should precede specification of +an upper bound for the same column (if both the lower and upper bounds +are explicitly specified). + +By default, all columns (structural variables) are non-negative, i.e. +have zero lower bound and no upper bound. Lower ($l_j$) and upper +($u_j$) bounds of some column (structural variable $x_j$) are set in the +following way, where $s_j$ is a corresponding bound value explicitly +specified in the BOUNDS section: + +\newpage + +\verb|LO| sets $l_j$ to $s_j$; + +\verb|UP| sets $u_j$ to $s_j$; + +\verb|FX| sets both $l_j$ and $u_j$ to $s_j$; + +\verb|FR| sets $l_j$ to $-\infty$ and $u_j$ to $+\infty$; + +\verb|MI| sets $l_j$ to $-\infty$; + +\verb|PL| sets $u_j$ to $+\infty$. + +\section{ENDATA indicator card} + +The ENDATA indicator card should be the last card of MPS file (except +optional comment cards, which may follow the ENDATA card). This card +should contain the word \verb|ENDATA| in the columns 1---6. + +\section{Specifying objective function} + +It is impossible to explicitly specify the objective function and +optimization direction in the MPS file. However, the following implicit +rule is used by default: the first row of \verb|N| type is considered +as a row of the objective function (i.e. the objective function is the +corresponding auxiliary variable), which should be {\it minimized}. + +GLPK also allows specifying a constant term of the objective function +as a right-hand side of the corresponding row in the RHS section. + +\section{Example of MPS file} +\label{secmpsex} + +To illustrate what the MPS format is, consider the following example of +LP problem: + +\def\arraystretch{1.2} + +\noindent\hspace{.5in}minimize +$$ +value = .03\ bin_1 + .08\ bin_2 + .17\ bin_3 + .12\ bin_4 + .15\ bin_5 ++ .21\ al + .38\ si +$$ +\noindent\hspace{.5in}subject to linear constraints +$$ +\begin{array}{@{}l@{\:}l@{}} +yield &= \ \ \ \ \;bin_1 + \ \ \ \ \;bin_2 + \ \ \ \ \;bin_3 + + \ \ \ \ \;bin_4 + \ \ \ \ \;bin_5 + \ \ \ \ \;al + + \ \ \ \ \;si \\ +FE &= .15\ bin_1 + .04\ bin_2 + .02\ bin_3 + .04\ bin_4 + .02\ bin_5 + + .01\ al + .03\ si \\ +CU &= .03\ bin_1 + .05\ bin_2 + .08\ bin_3 + .02\ bin_4 + .06\ bin_5 + + .01\ al \\ +MN &= .02\ bin_1 + .04\ bin_2 + .01\ bin_3 + .02\ bin_4 + .02\ bin_5 + \\ +MG &= .02\ bin_1 + .03\ bin_2 +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ + .01\ bin_5 \\ +AL &= .70\ bin_1 + .75\ bin_2 + .80\ bin_3 + .75\ bin_4 + .80\ bin_5 + + .97\ al \\ +SI &= .02\ bin_1 + .06\ bin_2 + .08\ bin_3 + .12\ bin_4 + .02\ bin_5 + + .01\ al + .97\ si \\ +\end{array} +$$ + +\newpage + +\noindent\hspace{.5in}and bounds of (auxiliary and structural) +variables +$$ +\begin{array}{r@{\ }l@{\ }l@{\ }l@{\ }rcr@{\ }l@{\ }l@{\ }l@{\ }r} +&&yield&=&2000&&0&\leq&bin_1&\leq&200\\ +-\infty&<&FE&\leq&60&&0&\leq&bin_2&\leq&2500\\ +-\infty&<&CU&\leq&100&&400&\leq&bin_3&\leq&800\\ +-\infty&<&MN&\leq&40&&100&\leq&bin_4&\leq&700\\ +-\infty&<&MG&\leq&30&&0&\leq&bin_5&\leq&1500\\ +1500&\leq&AL&<&+\infty&&0&\leq&al&<&+\infty\\ +250&\leq&SI&\leq&300&&0&\leq&si&<&+\infty\\ +\end{array} +$$ + +\def\arraystretch{1} + +A complete MPS file which specifies data for this example is shown +below (the first two comment lines show card positions). + +\bigskip + +\begin{footnotesize} +\begin{verbatim} +*000000001111111111222222222233333333334444444444555555555566 +*234567890123456789012345678901234567890123456789012345678901 +NAME PLAN +ROWS + N VALUE + E YIELD + L FE + L CU + L MN + L MG + G AL + L SI +COLUMNS + BIN1 VALUE .03000 YIELD 1.00000 + FE .15000 CU .03000 + MN .02000 MG .02000 + AL .70000 SI .02000 + BIN2 VALUE .08000 YIELD 1.00000 + FE .04000 CU .05000 + MN .04000 MG .03000 + AL .75000 SI .06000 + BIN3 VALUE .17000 YIELD 1.00000 + FE .02000 CU .08000 + MN .01000 AL .80000 + SI .08000 + BIN4 VALUE .12000 YIELD 1.00000 + FE .04000 CU .02000 + MN .02000 AL .75000 + SI .12000 + BIN5 VALUE .15000 YIELD 1.00000 + FE .02000 CU .06000 + MN .02000 MG .01000 + AL .80000 SI .02000 + ALUM VALUE .21000 YIELD 1.00000 + FE .01000 CU .01000 + AL .97000 SI .01000 + SILICON VALUE .38000 YIELD 1.00000 + FE .03000 SI .97000 +RHS + RHS1 YIELD 2000.00000 FE 60.00000 + CU 100.00000 MN 40.00000 + SI 300.00000 + MG 30.00000 AL 1500.00000 +RANGES + RNG1 SI 50.00000 +BOUNDS + UP BND1 BIN1 200.00000 + UP BIN2 2500.00000 + LO BIN3 400.00000 + UP BIN3 800.00000 + LO BIN4 100.00000 + UP BIN4 700.00000 + UP BIN5 1500.00000 +ENDATA +\end{verbatim} +\end{footnotesize} + +\vspace*{-6pt} + +\section{MIP features} + +\vspace*{-4pt} + +The MPS format provides two ways for introducing integer variables into +the problem. + +The first way is most general and based on using special marker cards +INTORG and INTEND. These marker cards are placed in the COLUMNS section. +The INTORG card indicates the start of a group of integer variables +(columns), and the card INTEND indicates the end of the group. The MPS +file may contain arbitrary number of the marker cards. + +The marker cards have the same format as the data cards (see Section +\ref{secmps}, page \pageref{secmps}). + +The fields 1, 2, and 6 are not used and should be empty. + +The field 2 should contain a marker name. This name may be arbitrary. + +The field 3 should contain the word \verb|'MARKER'| (including +apostrophes). + +The field 5 should contain either the word \verb|'INTORG'| (including +apostrophes) for the marker card, which begins a group of integer +columns, or the word \verb|'INTEND'| (including apostrophes) for the +marker card, which ends the group. + +The second way is less general but more convenient in some cases. It +allows the user declaring integer columns using three additional types +of bounds, which are specified in the field 1 of data cards in the +BOUNDS section (see Section \ref{secbounds}, page \pageref{secbounds}): + +\verb|LI| --- lower integer. This bound type specifies that the +corresponding column (structural variable), whose name is specified in +field 3, is of integer kind. In this case an lower bound of the +column should be specified in field 4 (like in the case of \verb|LO| +bound type). + +\verb|UI| --- upper integer. This bound type specifies that the +corresponding column (structural variable), whose name is specified in +field 3, is of integer kind. In this case an upper bound of the +column should be specified in field 4 (like in the case of \verb|UP| +bound type). + +\verb|BV| --- binary variable. This bound type specifies that the +corresponding column (structural variable), whose name is specified in +the field 3, is of integer kind, its lower bound is zero, and its upper +bound is one (thus, such variable being of integer kind can have only +two values zero and one). In this case a numeric value specified in the +field 4 is ignored and may be omitted. + +Consider the following example of MIP problem: + +\noindent +\hspace{1in} minimize +$$Z = 3 x_1 + 7 x_2 - x_3 + x4$$ +\hspace{1in} subject to linear constraints +$$ +\begin{array}{c} +\nonumber r_1 = 2 x_1 - \ \ x_2 + \ \ x_3 - \ \;x_4 \\ +\nonumber r_2 = \ \;x_1 - \ \;x_2 - 6 x_3 + 4 x_4 \\ +\nonumber r_3 = 5 x_1 + 3 x_2 \ \ \ \ \ \ \ \ \ + \ \ x_4 \\ +\end{array} +$$ +\hspace{1in} and bound of variables +$$ +\begin{array}{cccl} +\nonumber 1 \leq r_1 < +\infty && 0 \leq x_1 \leq 4 &{\rm(continuous)}\\ +\nonumber 8 \leq r_2 < +\infty && 2 \leq x_2 \leq 5 &{\rm(integer)} \\ +\nonumber 5 \leq r_3 < +\infty && 0 \leq x_3 \leq 1 &{\rm(integer)} \\ +\nonumber && 3 \leq x_4 \leq 8 &{\rm(continuous)}\\ +\end{array} +$$ + +The corresponding MPS file may look like the following: + +\medskip + +\begin{footnotesize} +\begin{verbatim} +NAME SAMP1 +ROWS + N Z + G R1 + G R2 + G R3 +COLUMNS + X1 R1 2.0 R2 1.0 + X1 R3 5.0 Z 3.0 + MARK0001 'MARKER' 'INTORG' + X2 R1 -1.0 R2 -1.0 + X2 R3 3.0 Z 7.0 + X3 R1 1.0 R2 -6.0 + X3 Z -1.0 + MARK0002 'MARKER' 'INTEND' + X4 R1 -1.0 R2 4.0 + X4 R3 1.0 Z 1.0 +RHS + RHS1 R1 1.0 + RHS1 R2 8.0 + RHS1 R3 5.0 +BOUNDS + UP BND1 X1 4.0 + LO BND1 X2 2.0 + UP BND1 X2 5.0 + UP BND1 X3 1.0 + LO BND1 X4 3.0 + UP BND1 X4 8.0 +ENDATA +\end{verbatim} +\end{footnotesize} + +\newpage + +The same example may be coded without INTORG/INTEND markers using the +bound type UI for the variable $x_2$ and the bound type BV for the +variable $x_3$: + +\medskip + +\begin{footnotesize} +\begin{verbatim} +NAME SAMP2 +ROWS + N Z + G R1 + G R2 + G R3 +COLUMNS + X1 R1 2.0 R2 1.0 + X1 R3 5.0 Z 3.0 + X2 R1 -1.0 R2 -1.0 + X2 R3 3.0 Z 7.0 + X3 R1 1.0 R2 -6.0 + X3 Z -1.0 + X4 R1 -1.0 R2 4.0 + X4 R3 1.0 Z 1.0 +RHS + RHS1 R1 1.0 + RHS1 R2 8.0 + RHS1 R3 5.0 +BOUNDS + UP BND1 X1 4.0 + LO BND1 X2 2.0 + UI BND1 X2 5.0 + BV BND1 X3 + LO BND1 X4 3.0 + UP BND1 X4 8.0 +ENDATA +\end{verbatim} +\end{footnotesize} + +%\section{Specifying predefined basis} +%\label{secbas} +% +%The MPS format can also be used to specify some predefined basis for an +%LP problem, i.e. to specify which rows and columns are basic and which +%are non-basic. +% +%The order of a basis file in the MPS format is: +% +%$\bullet$ NAME indicator card; +% +%$\bullet$ data cards (can appear in arbitrary order); +% +%$\bullet$ ENDATA indicator card. +% +%Each data card specifies either a pair "basic column---non-basic row" +%or a non-basic column. All the data cards have the following format. +% +%`\verb|XL|' in the field 1 means that a column, whose name is given in +%the field 2, is basic, and a row, whose name is given in the field 3, +%is non-basic and placed on its lower bound. +% +%`\verb|XU|' in the field 1 means that a column, whose name is given in +%the field 2, is basic, and a row, whose name is given in the field 3, +%is non-basic and placed on its upper bound. +% +%`\verb|LL|' in the field 1 means that a column, whose name is given in +%the field 3, is non-basic and placed on its lower bound. +% +%`\verb|UL|' in the field 1 means that a column, whose name is given in +%the field 3, is non-basic and placed on its upper bound. +% +%The field 2 contains a column name. +% +%If the indicator given in the field 1 is `\verb|XL|' or `\verb|XU|', +%the field 3 contains a row name. Otherwise, if the indicator is +%`\verb|LL|' or `\verb|UL|', the field 3 is not used and should be +%empty. +% +%The field 4, 5, and 6 are not used and should be empty. +% +%A basis file in the MPS format acts like a patch: it doesn't specify +%a basis completely, instead that it is just shows in what a given basis +%differs from the "standard" basis, where all rows (auxiliary variables) +%are assumed to be basic and all columns (structural variables) are +%assumed to be non-basic. +% +%As an example here is a basis file that specifies an optimal basis +%for the example LP problem given in Section \ref{secmpsex}, +%Page \pageref{secmpsex}: +% +%\pagebreak +% +%\begin{verbatim} +%*000000001111111111222222222233333333334444444444555555555566 +%*234567890123456789012345678901234567890123456789012345678901 +%NAME PLAN +% XL BIN2 YIELD +% XL BIN3 FE +% XL BIN4 MN +% XL ALUM AL +% XL SILICON SI +% LL BIN1 +% LL BIN5 +%ENDATA +%\end{verbatim} + +%* eof *% diff --git a/resources/3rdparty/glpk-4.57/doc/glpk09.tex b/resources/3rdparty/glpk-4.57/doc/glpk09.tex new file mode 100644 index 000000000..d04865d9d --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/glpk09.tex @@ -0,0 +1,424 @@ +%* glpk09.tex *% + +\chapter{CPLEX LP Format} +\label{chacplex} + +\section{Prelude} + +The CPLEX LP format\footnote{The CPLEX LP format was developed in +the end of 1980's by CPLEX Optimization, Inc. as an input format for +the CPLEX linear programming system. Although the CPLEX LP format is +not as widely used as the MPS format, being row-oriented it is more +convenient for coding mathematical programming models by human. This +appendix describes only the features of the CPLEX LP format which are +implemented in the GLPK package.} is intended for coding LP/MIP problem +data. It is a row-oriented format that assumes the formulation of +LP/MIP problem (1.1)---(1.3) (see Section \ref{seclp}, page +\pageref{seclp}). + +CPLEX LP file is a plain text file written in CPLEX LP format. Each +text line of this file may contain up to 255 characters\footnote{GLPK +allows text lines of arbitrary length.}. Blank lines are ignored. +If a line contains the backslash character ($\backslash$), this +character and everything that follows it until the end of line are +considered as a comment and also ignored. + +An LP file is coded by the user using the following elements: keywords, +symbolic names, numeric constants, delimiters, and blanks. + +{\it Keywords} which may be used in the LP file are the following: + +\begin{verbatim} + minimize minimum min + maximize maximum max + subject to such that s.t. st. st + bounds bound + general generals gen + integer integers int + binary binaries bin + infinity inf + free + end +\end{verbatim} + +\noindent +All the keywords are case insensitive. Keywords given above on the same +line are equivalent. Any keyword (except \verb|infinity|, \verb|inf|, +and \verb|free|) being used in the LP file must start at the beginning +of a text line. + +\newpage + +{\it Symbolic names} are used to identify the objective function, +constraints (rows), and variables (columns). All symbolic names are case +sensitive and may contain up to 16 alphanumeric characters\footnote{GLPK +allows symbolic names having up to 255 characters.} (\verb|a|, \dots, +\verb|z|, \verb|A|, \dots, \verb|Z|, \verb|0|, \dots, \verb|9|) as well +as the following characters: + +\begin{verbatim} + ! " # $ % & ( ) / , . ; ? @ _ ` ' { } | ~ +\end{verbatim} + +\noindent +with exception that no symbolic name can begin with a digit or +a period. + +{\it Numeric constants} are used to denote constraint and objective +coefficients, right-hand sides of constraints, and bounds of variables. +They are coded in the standard form $xx$\verb|E|$syy$, where $xx$ is +a real number with optional decimal point, $s$ is a sign (\verb|+| or +\verb|-|), $yy$ is an integer decimal exponent. Numeric constants may +contain arbitrary number of characters. The exponent part is optional. +The letter `\verb|E|' can be coded as `\verb|e|'. If the sign $s$ is +omitted, plus is assumed. + +{\it Delimiters} that may be used in the LP file are the following: + +\begin{verbatim} + : + + + - + < <= =< + > >= => + = +\end{verbatim} + +\noindent +Delimiters given above on the same line are equivalent. The meaning of +the delimiters will be explained below. + +{\it Blanks} are non-significant characters. They may be used freely to +improve readability of the LP file. Besides, blanks should be used to +separate elements from each other if there is no other way to do that +(for example, to separate a keyword from a following symbolic name). + +The order of an LP file is: + +\vspace*{-8pt} + +\begin{itemize} +\item objective function definition; + +\item constraints section; + +\item bounds section; + +\item general, integer, and binary sections (can appear in arbitrary +order); + +\item end keyword. +\end{itemize} + +\vspace*{-8pt} + +These components are discussed in following sections. + +\section{Objective function definition} + +The objective function definition must appear first in the LP file. +It defines the objective function and specifies the optimization +direction. + +The objective function definition has the following form: +$$ +\left\{ +\begin{array}{@{}c@{}} +{\tt minimize} \\ {\tt maximize} +\end{array} +\right\}\ f\ {\tt :}\ s\ c\ x\ s\ c\ x\ \dots\ s\ c\ x +$$ +where $f$ is a symbolic name of the objective function, $s$ is a sign +\verb|+| or \verb|-|, $c$ is a numeric constant that denotes an +objective coefficient, $x$ is a symbolic name of a variable. + +If necessary, the objective function definition can be continued on as +many text lines as desired. + +The name of the objective function is optional and may be omitted +(together with the semicolon that follows it). In this case the default +name `\verb|obj|' is assigned to the objective function. + +If the very first sign $s$ is omitted, the sign plus is assumed. Other +signs cannot be omitted. + +If some objective coefficient $c$ is omitted, 1 is assumed. + +Symbolic names $x$ used to denote variables are recognized by context +and therefore needn't to be declared somewhere else. + +Here is an example of the objective function definition: + +\begin{verbatim} + Minimize Z : - x1 + 2 x2 - 3.5 x3 + 4.997e3x(4) + x5 + x6 + + x7 - .01x8 +\end{verbatim} + +\section{Constraints section} + +The constraints section must follow the objective function definition. +It defines a system of equality and/or inequality constraints. + +The constraint section has the following form: + +\begin{center} +\begin{tabular}{l} +\verb|subject to| \\ +{\it constraint}$_1$ \\ +{\it constraint}$_2$ \\ +\hspace{20pt}\dots \\ +{\it constraint}$_m$ \\ +\end{tabular} +\end{center} + +\noindent where {\it constraint}$_i, i=1,\dots,m,$ is a particular +constraint definition. + +Each constraint definition can be continued on as many text lines as +desired. However, each constraint definition must begin on a new line +except the very first constraint definition which can begin on the same +line as the keyword `\verb|subject to|'. + +Constraint definitions have the following form: +$$ +r\ {\tt:}\ s\ c\ x\ s\ c\ x\ \dots\ s\ c\ x +\ \left\{ +\begin{array}{@{}c@{}} +\mbox{\tt<=} \\ \mbox{\tt>=} \\ \mbox{\tt=} +\end{array} +\right\}\ b +$$ +where $r$ is a symbolic name of a constraint, $s$ is a sign \verb|+| or +\verb|-|, $c$ is a numeric constant that denotes a constraint +coefficient, $x$ is a symbolic name of a variable, $b$ is a right-hand +side. + +The name $r$ of a constraint (which is the name of the corresponding +auxiliary variable) is optional and may be omitted (together with the +semicolon that follows it). In this case the default names like +`\verb|r.nnn|' are assigned to unnamed constraints. + +The linear form $s\ c\ x\ s\ c\ x\ \dots\ s\ c\ x$ in the left-hand +side of a constraint definition has exactly the same meaning as in the +case of the objective function definition (see above). + +After the linear form one of the following delimiters that indicates +the constraint sense must be specified: + +\verb|<=| \ means `less than or equal to' + +\verb|>=| \ means `greater than or equal to' + +\verb|= | \ means `equal to' + +The right hand side $b$ is a numeric constant with an optional sign. + +Here is an example of the constraints section: + +\begin{verbatim} + Subject To + one: y1 + 3 a1 - a2 - b >= 1.5 + y2 + 2 a3 + 2 + a4 - b >= -1.5 + two : y4 + 3 a1 + 4 a5 - b <= +1 + .20y5 + 5 a2 - b = 0 + 1.7 y6 - a6 + 5 a777 - b >= 1 +\end{verbatim} + +Should note that it is impossible to express ranged constraints in the +CPLEX LP format. Each a ranged constraint can be coded as two +constraints with identical linear forms in the left-hand side, one of +which specifies a lower bound and other does an upper one of the +original ranged constraint. Another way is to introduce a slack +double-bounded variable; for example, the +constraint +$$10\leq x+2y+3z\leq 50$$ +can be written as follows: +$$x+2y+3z+t=50,$$ +where $0\leq t\leq 40$ is a slack variable. + +\section{Bounds section} + +The bounds section is intended to define bounds of variables. This +section is optional; if it is specified, it must follow the constraints +section. If the bound section is omitted, all variables are assumed to +be non-negative (i.e. that they have zero lower bound and no upper +bound). + +The bounds section has the following form: + +\begin{center} +\begin{tabular}{l} +\verb|bounds| \\ +{\it definition}$_1$ \\ +{\it definition}$_2$ \\ +\hspace{20pt}\dots \\ +{\it definition}$_p$ \\ +\end{tabular} +\end{center} + +\noindent +where {\it definition}$_k, k=1,\dots,p,$ is a particular bound +definition. + +Each bound definition must begin on a new line\footnote{The GLPK +implementation allows several bound definitions to be placed on the +same line.} except the very first bound definition which can begin on +the same line as the keyword `\verb|bounds|'. + +\newpage + +Syntactically constraint definitions can have one of the following six +forms: + +\begin{center} +\begin{tabular}{ll} +$x$ \verb|>=| $l$ & specifies a lower bound \\ +$l$ \verb|<=| $x$ & specifies a lower bound \\ +$x$ \verb|<=| $u$ & specifies an upper bound \\ +$l$ \verb|<=| $x$ \verb|<=| $u$ &specifies both lower and upper bounds\\ +$x$ \verb|=| $t$ &specifies a fixed value \\ +$x$ \verb|free| &specifies free variable +\end{tabular} +\end{center} + +\noindent +where $x$ is a symbolic name of a variable, $l$ is a numeric constant +with an optional sign that defines a lower bound of the variable or +\verb|-inf| that means that the variable has no lower bound, $u$ is a +numeric constant with an optional sign that defines an upper bound of +the variable or \verb|+inf| that means that the variable has no upper +bound, $t$ is a numeric constant with an optional sign that defines a +fixed value of the variable. + +By default all variables are non-negative, i.e. have zero lower bound +and no upper bound. Therefore definitions of these default bounds can +be omitted in the bounds section. + +Here is an example of the bounds section: + +\begin{verbatim} + Bounds + -inf <= a1 <= 100 + -100 <= a2 + b <= 100 + x2 = +123.456 + x3 free +\end{verbatim} + +\section{General, integer, and binary sections} + +The general, integer, and binary sections are intended to define +some variables as integer or binary. All these sections are optional +and needed only in case of MIP problems. If they are specified, they +must follow the bounds section or, if the latter is omitted, the +constraints section. + +All the general, integer, and binary sections have the same form as +follows: + +\begin{center} +\begin{tabular}{l} +$ +\left\{ +\begin{array}{@{}l@{}} +\verb|general| \\ +\verb|integer| \\ +\verb|binary | \\ +\end{array} +\right\} +$ \\ +\hspace{10pt}$x_1$ \\ +\hspace{10pt}$x_2$ \\ +\hspace{10pt}\dots \\ +\hspace{10pt}$x_q$ \\ +\end{tabular} +\end{center} + +\noindent +where $x_k$ is a symbolic name of variable, $k=1,\dots,q$. + +Each symbolic name must begin on a new line\footnote{The GLPK +implementation allows several symbolic names to be placed on the same +line.} except the very first symbolic name which can begin on the same +line as the keyword `\verb|general|', `\verb|integer|', or +`\verb|binary|'. + +\newpage + +If a variable appears in the general or the integer section, it is +assumed to be general integer variable. If a variable appears in the +binary section, it is assumed to be binary variable, i.e. an integer +variable whose lower bound is zero and upper bound is one. (Note that +if bounds of a variable are specified in the bounds section and then +the variable appears in the binary section, its previously specified +bounds are ignored.) + +Here is an example of the integer section: + +\begin{verbatim} + Integer + z12 + z22 + z35 +\end{verbatim} + +\section{End keyword} + +The keyword `\verb|end|' is intended to end the LP file. It must begin +on a separate line and no other elements (except comments and blank +lines) must follow it. Although this keyword is optional, it is strongly +recommended to include it in the LP file. + +\section{Example of CPLEX LP file} + +Here is a complete example of CPLEX LP file that corresponds to the +example given in Section \ref{secmpsex}, page \pageref{secmpsex}. + +\medskip + +\begin{footnotesize} +\begin{verbatim} +\* plan.lp *\ + +Minimize + value: .03 bin1 + .08 bin2 + .17 bin3 + .12 bin4 + .15 bin5 + + .21 alum + .38 silicon + +Subject To + yield: bin1 + bin2 + bin3 + bin4 + bin5 + + alum + silicon = 2000 + + fe: .15 bin1 + .04 bin2 + .02 bin3 + .04 bin4 + .02 bin5 + + .01 alum + .03 silicon <= 60 + + cu: .03 bin1 + .05 bin2 + .08 bin3 + .02 bin4 + .06 bin5 + + .01 alum <= 100 + + mn: .02 bin1 + .04 bin2 + .01 bin3 + .02 bin4 + .02 bin5 <= 40 + + mg: .02 bin1 + .03 bin2 + .01 bin5 <= 30 + + al: .70 bin1 + .75 bin2 + .80 bin3 + .75 bin4 + .80 bin5 + + .97 alum >= 1500 + + si1: .02 bin1 + .06 bin2 + .08 bin3 + .12 bin4 + .02 bin5 + + .01 alum + .97 silicon >= 250 + + si2: .02 bin1 + .06 bin2 + .08 bin3 + .12 bin4 + .02 bin5 + + .01 alum + .97 silicon <= 300 + +Bounds + bin1 <= 200 + bin2 <= 2500 + 400 <= bin3 <= 800 + 100 <= bin4 <= 700 + bin5 <= 1500 + +End + +\* eof *\ +\end{verbatim} +\end{footnotesize} + +%* eof *% diff --git a/resources/3rdparty/glpk-4.57/doc/glpk10.tex b/resources/3rdparty/glpk-4.57/doc/glpk10.tex new file mode 100644 index 000000000..01c4f35d4 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/glpk10.tex @@ -0,0 +1,165 @@ +%* glpk10.tex *% + +\chapter{Stand-alone LP/MIP Solver} +\label{chaglpsol} + +The GLPK package includes the program \verb|glpsol|, which is a +stand-alone LP/MIP solver. This program can be invoked from the command +line to read LP/MIP problem data in any format supported by GLPK, solve +the problem, and write its solution to an output text file. + +\para{Usage} + +\verb|glpsol| [{\it options\dots}] [{\it filename}] + +\para{General options} + +\begin{verbatim} + --mps read LP/MIP problem in fixed MPS format + --freemps read LP/MIP problem in free MPS format (default) + --lp read LP/MIP problem in CPLEX LP format + --glp read LP/MIP problem in GLPK format + --math read LP/MIP model written in GNU MathProg modeling + language + -m filename, --model filename + read model section and optional data section from + filename (same as --math) + -d filename, --data filename + read data section from filename (for --math only); + if model file also has data section, it is ignored + -y filename, --display filename + send display output to filename (for --math only); + by default the output is sent to terminal + --seed value initialize pseudo-random number generator used in + MathProg model with specified seed (any integer); + if seed value is ?, some random seed will be used + --mincost read min-cost flow problem in DIMACS format + --maxflow read maximum flow problem in DIMACS format + --cnf read CNF-SAT problem in DIMACS format + --simplex use simplex method (default) + --interior use interior point method (LP only) + -r filename, --read filename + read solution from filename rather to find it with + the solver + --min minimization + --max maximization + --scale scale problem (default) + --noscale do not scale problem + -o filename, --output filename + write solution to filename in printable format + -w filename, --write filename + write solution to filename in plain text format + --ranges filename + write sensitivity analysis report to filename in + printable format (simplex only) + --tmlim nnn limit solution time to nnn seconds + --memlim nnn limit available memory to nnn megabytes + --check do not solve problem, check input data only + --name probname change problem name to probname + --wmps filename write problem to filename in fixed MPS format + --wfreemps filename + write problem to filename in free MPS format + --wlp filename write problem to filename in CPLEX LP format + --wglp filename write problem to filename in GLPK format + --wcnf filename write problem to filename in DIMACS CNF-SAT format + --log filename write copy of terminal output to filename + -h, --help display this help information and exit + -v, --version display program version and exit +\end{verbatim} + +\para{LP basis factorization options} + +\begin{verbatim} + --luf plain LU factorization (default) + --btf block triangular LU factorization + --ft Forrest-Tomlin update (requires --luf; default) + --cbg Schur complement + Bartels-Golub update + --cgr Schur complement + Givens rotation update +\end{verbatim} + +\para{Options specific to the simplex solver} + +\begin{verbatim} + --primal use primal simplex (default) + --dual use dual simplex + --std use standard initial basis of all slacks + --adv use advanced initial basis (default) + --bib use Bixby's initial basis + --ini filename use as initial basis previously saved with -w + (disables LP presolver) + --steep use steepest edge technique (default) + --nosteep use standard "textbook" pricing + --relax use Harris' two-pass ratio test (default) + --norelax use standard "textbook" ratio test + --presol use presolver (default; assumes --scale and --adv) + --nopresol do not use presolver + --exact use simplex method based on exact arithmetic + --xcheck check final basis using exact arithmetic +\end{verbatim} + +\para{Options specific to the interior-point solver} + +\begin{verbatim} + --nord use natural (original) ordering + --qmd use quotient minimum degree ordering + --amd use approximate minimum degree ordering (default) + --symamd use approximate minimum degree ordering +\end{verbatim} + +\para{Options specific to the MIP solver} + +\begin{verbatim} + --nomip consider all integer variables as continuous + (allows solving MIP as pure LP) + --first branch on first integer variable + --last branch on last integer variable + --mostf branch on most fractional variable + --drtom branch using heuristic by Driebeck and Tomlin + (default) + --pcost branch using hybrid pseudocost heuristic (may be + useful for hard instances) + --dfs backtrack using depth first search + --bfs backtrack using breadth first search + --bestp backtrack using the best projection heuristic + --bestb backtrack using node with best local bound + (default) + --intopt use MIP presolver (default) + --nointopt do not use MIP presolver + --binarize replace general integer variables by binary ones + (assumes --intopt) + --fpump apply feasibility pump heuristic + --proxy [nnn] apply proximity search heuristic (nnn is time limit + in seconds; default is 60) + --gomory generate Gomory's mixed integer cuts + --mir generate MIR (mixed integer rounding) cuts + --cover generate mixed cover cuts + --clique generate clique cuts + --cuts generate all cuts above + --mipgap tol set relative mip gap tolerance to tol + --minisat translate integer feasibility problem to CNF-SAT + and solve it with MiniSat solver +\end{verbatim} + +\newpage + +\begin{verbatim} + --objbnd bound add inequality obj <= bound (minimization) or + obj >= bound (maximization) to integer feasibility + problem (assumes --minisat) +\end{verbatim} + +For description of the MPS format see Appendix \ref{champs}, page +\pageref{champs}. + +For description of the CPLEX LP format see Appendix \ref{chacplex}, +page \pageref{chacplex}. + +For description of the modeling language see the document ``Modeling +Language GNU MathProg: Language Reference'' included in the GLPK +distribution. + +For description of the DIMACS min-cost flow problem format and DIMACS +maximum flow problem format see the document ``GLPK: Graph and Network +Routines'' included in the GLPK distribution. + +%* eof *% diff --git a/resources/3rdparty/glpk-4.57/doc/glpk11.tex b/resources/3rdparty/glpk-4.57/doc/glpk11.tex new file mode 100644 index 000000000..d45ab3d29 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/glpk11.tex @@ -0,0 +1,203 @@ +%* glpk11.tex *% + +\chapter{External Software Modules Used In GLPK} + +In the GLPK package there are used some external software modules +listed in this Appendix. Note that these modules are {\it not} part of +GLPK, but are used with GLPK and included in the distribution. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{AMD} + +\noindent +AMD Version 2.2, Copyright {\copyright} 2007 by Timothy A. Davis, +Patrick R. Amestoy, and Iain S. Duff. All Rights Reserved. + +\para{Description} + +AMD is a set of routines for pre-ordering sparse matrices prior to +Cholesky or LU factorization, using the approximate minimum degree +ordering algorithm. + +\para{License} + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public License +as published by the Free Software Foundation; either version 2.1 of +the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 +USA. + +Permission is hereby granted to use or copy this program under the +terms of the GNU LGPL, provided that the Copyright, this License, +and the Availability of the original version is retained on all +copies. User documentation of any code that uses this code or any +modified version of this code must cite the Copyright, this License, +the Availability note, and ``Used by permission.'' Permission to +modify the code and to distribute modified code is granted, provided +the Copyright, this License, and the Availability note are retained, +and a notice that the code was modified is included. + +AMD is available under alternate licences; contact T. Davis for +details. + +\para{Availability} + +\noindent +\url{http://www.cise.ufl.edu/research/sparse/amd} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{COLAMD/SYMAMD} + +\noindent +COLAMD/SYMAMD Version 2.7, Copyright {\copyright} 1998-2007, Timothy A. +Davis, All Rights Reserved. + +\para{Description} + +colamd: an approximate minimum degree column ordering algorithm, for +LU factorization of symmetric or unsymmetric matrices, QR factorization, +least squares, interior point methods for linear programming problems, +and other related problems. + +symamd: an approximate minimum degree ordering algorithm for Cholesky +factorization of symmetric matrices. + +\para{Authors} + +The authors of the code itself are Stefan I. Larimore and Timothy A. +Davis (davis at cise.ufl.edu), University of Florida. The algorithm +was developed in collaboration with John Gilbert, Xerox PARC, and +Esmond Ng, Oak Ridge National Laboratory. + +\para{License} + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public License +as published by the Free Software Foundation; either version 2.1 of +the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 +USA. + +Permission is hereby granted to use or copy this program under the +terms of the GNU LGPL, provided that the Copyright, this License, +and the Availability of the original version is retained on all +copies. User documentation of any code that uses this code or any +modified version of this code must cite the Copyright, this License, +the Availability note, and ``Used by permission.'' Permission to +modify the code and to distribute modified code is granted, provided +the Copyright, this License, and the Availability note are retained, +and a notice that the code was modified is included. + +COLAMD is also available under alternate licenses, contact T. Davis for +details. + +\para{Availability} + +\noindent +\url{http://www.cise.ufl.edu/research/sparse/colamd} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{MiniSat} + +\noindent +MiniSat-C v1.14.1, Copyright {\copyright} 2005, Niklas Sorensson. + +\para{Description} + +MiniSat is a minimalistic implementation of a Chaff-like SAT solver +based on the two-literal watch scheme for fast BCP and clause learning +by conflict analysis. + +\para{License} + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +\para{Availability} + +\noindent +\url{http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{zlib} + +\noindent +zlib version 1.2.5, Copyright {\copyright} 1995--2010 Jean-loup Gailly +and Mark Adler. + +\para{Description} + +zlib is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by +RFCs (Request for Comments) 1950 to 1952 in the files +\verb|rfc1950.txt| (zlib format), \verb|rfc1951.txt| (deflate format) +and \verb|rfc1952.txt| (gzip format). + +\para{License} + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would + be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. + +\hfill Jean-loup Gailly + +\hfill Mark Adler + +\para{Availability} + +\noindent +\url{http://www.zlib.net/} + +%* eof *% diff --git a/resources/3rdparty/glpk-4.57/doc/glpk12.tex b/resources/3rdparty/glpk-4.57/doc/glpk12.tex new file mode 100644 index 000000000..2c2b1b7a6 --- /dev/null +++ b/resources/3rdparty/glpk-4.57/doc/glpk12.tex @@ -0,0 +1,707 @@ +%* glpk12.tex *% + +\begin{footnotesize} + +\chapter*{\sf\bfseries GNU General Public License} +\addcontentsline{toc}{chapter}{GNU General Public License} + +\begin{center} +{\bf Version 3, 29 June 2007} +\end{center} + +\begin{quotation} +\noindent +Copyright {\copyright} 2007 Free Software Foundation, Inc. +\verb|| +\end{quotation} + +\begin{quotation} +\noindent +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +\end{quotation} + +\section*{Preamble} + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + +\section*{TERMS AND CONDITIONS} + +\subsubsection*{0. Definitions.} + + ``This License'' refers to version 3 of the GNU General Public +License. + + ``Copyright'' also means copyright-like laws that apply to other kinds +of works, such as semiconductor masks. + + ``The Program'' refers to any copyrightable work licensed under this +License. Each licensee is addressed as ``you''. ``Licensees'' and +``recipients'' may be individuals or organizations. + + To ``modify'' a work means to copy from or adapt all or part of the +work in a fashion requiring copyright permission, other than the making +of an exact copy. The resulting work is called a ``modified version'' +of the earlier work or a work ``based on'' the earlier work. + + A ``covered work'' means either the unmodified Program or a work based +on the Program. + + To ``propagate'' a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To ``convey'' a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays ``Appropriate Legal Notices'' +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + +\subsubsection*{1. Source Code.} + + The ``source code'' for a work means the preferred form of the work +for making modifications to it. ``Object code'' means any non-source +form of a work. + + A ``Standard Interface'' means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The ``System Libraries'' of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +``Major Component'', in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The ``Corresponding Source'' for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + +\subsubsection*{2. Basic Permissions.} + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + +\subsubsection*{3. Protecting Users' Legal Rights From +Anti-Circumvention Law.} + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + +\subsubsection*{4. Conveying Verbatim Copies.} + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + +\subsubsection*{5. Conveying Modified Source Versions.} + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + ``keep intact all notices''. + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +``aggregate'' if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + +\subsubsection*{6. Conveying Non-Source Forms.} + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A ``User Product'' is either (1) a ``consumer product'', which means +any tangible personal property which is normally used for personal, +family, or household purposes, or (2) anything designed or sold for +incorporation into a dwelling. In determining whether a product is a +consumer product, doubtful cases shall be resolved in favor of coverage. +For a particular product received by a particular user, ``normally +used'' refers to a typical or common use of that class of product, +regardless of the status of the particular user or of the way in which +the particular user actually uses, or expects or is expected to use, the +product. A product is a consumer product regardless of whether the +product has substantial commercial, industrial or non-consumer uses, +unless such uses represent the only significant mode of use of the +product. + + ``Installation Information'' for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product +from a modified version of its Corresponding Source. The information +must suffice to ensure that the continued functioning of the modified +object code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to +a network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + +\subsubsection*{7. Additional Terms.} + + ``Additional permissions'' are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders +of that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered ``further +restrictions'' within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + +\subsubsection*{8. Termination.} + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + +\subsubsection*{9. Acceptance Not Required for Having Copies.} + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + +\subsubsection*{10. Automatic Licensing of Downstream Recipients.} + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An ``entity transaction'' is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + +\subsubsection*{11. Patents.} + + A ``contributor'' is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's ``contributor version''. + + A contributor's ``essential patent claims'' are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, ``control'' includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a ``patent license'' is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To ``grant'' such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. ``Knowingly relying'' means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is ``discriminatory'' if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + +\subsubsection*{12. No Surrender of Others' Freedom.} + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not convey it at all. For example, if you agree to terms that +obligate you to collect a royalty for further conveying from those to +whom you convey the Program, the only way you could satisfy both those +terms and this License would be to refrain entirely from conveying the +Program. + +\subsubsection*{13. Use with the GNU Affero General Public License.} + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + +\subsubsection*{14. Revised Versions of this License.} + + The Free Software Foundation may publish revised and/or new versions +of the GNU General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in +detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License ``or any later version'' applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + +\subsubsection*{15. Disclaimer of Warranty.} + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM ``AS IS'' WITHOUT +WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU +ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +\subsubsection*{16. Limitation of Liability.} + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR +CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT +NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES +SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE +WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN +ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +\subsubsection*{17. Interpretation of Sections 15 and 16.} + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + +\section*{END OF TERMS AND CONDITIONS} + +\newpage + +\section*{How to Apply These Terms to Your New Programs} + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the ``copyright'' line and a pointer to where the full notice is found. + +\begin{verbatim} + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +\end{verbatim} + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + +\begin{verbatim} + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. +\end{verbatim} + +\noindent +The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, your +program's commands might be different; for a GUI interface, you would +use an ``about box''. + + You should also get your employer (if you work as a programmer) or +school, if any, to sign a ``copyright disclaimer'' for the program, if +necessary. For more information on this, and how to apply and follow the +GNU GPL, see \verb||. + + The GNU General Public License does not permit incorporating your +program into proprietary programs. If your program is a subroutine +library, you may consider it more useful to permit linking proprietary +applications with the library. If this is what you want to do, use the +GNU Lesser General Public License instead of this License. But first, +please read \verb||. + +\end{footnotesize} + +%* eof *% diff --git a/resources/3rdparty/glpk-4.57/doc/gmpl.pdf b/resources/3rdparty/glpk-4.57/doc/gmpl.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0f6833f682a49484f2be289b556aaac9e8f0b5ac GIT binary patch literal 216194 zcma&NQ*fqT)BYV@v7Jn8+qN~q#Ky$7ZQHiZiJeSr+qq)%e}8X%8}C!^vvKdOjk8wO z*;Re?ue*;$t|TTw&&e0PE!JXliH!>%J}@C#(ogj2v?P70E3^GS&yyB^lEi(W>?1vgEPe zcC96X!J+1RNAt#D_vZNa*bB4=M0ig4CbKs13e6TwhaR~(aT*7je^tu}0Zg9M1$?jl z_r*}i&r57Ug#)2^k5b5|B&8ynl zQVRPuK3K9`_1U(qMA=Kr2K$^(pT)odVbt(yW(nLOw*c-vFM!m3d45<^Ta*9)fB!lC ze*t1<{Wp=~;%5Hek&5{>?zq8)+%SG^R?F(28? zeqs22GE>V+chC55)4KWevN=otk5O>~rTgP>I=wPvWMY^TZelyGOcI0RRlk4S8MnP zqL=Wwq?XCOs_fk3wEgYRZbJm zOP|faZ*I4WcGYfP`7S^A8Eb~}z{;GhI$jQdd}P6_rTF}bd9b9!tC!7=i!z7{fmS1& zC%R&O(#>a4<5y)d5oTaGP>usx)YW~mwWA^yZS5tR$SWmTUhfNllNDBZ<`(Fcz39Wo zC;ln_N96Z7u0F0n2x*2zr_pj{DEdL^iNIn~BHrKAx*A4(DRe5jL!I}~fu_eGh*dGp zg$k^C(jX~!(jd0F)c{E6%qgwtb@m4E5N=-N<6Yk!8QcO%1H1OiGx0ddhC%KuD(~Aid0&JH z#Uu(cFW9CSK0%O&E9!nA_2z;h|2Kcxnf^`wGP5vq{_g|^W@Ele~ zzlvn^9se+^VtF@9@Og~=oeoAU-rCOWmrD!HHG_Gvb05{YerDO0^V#sS{YSwB8Vr!) zhhOHO|KwuMp`Lz}wiKQ3y|UQU;h}S_-c?w;-e8CImE`xi{5`+fIdj!Zc?1oeIE7Lq z6!DbffoCiECfv*k?I6^SGe~Z*s*Aw15=1oe`d&CcIiiC={OY5!!!g-NSE>CD(W0nh z=ggf27w*KA#R{!>vFCB)3_<`t0*SoPFAJZ4v)cgmT?7M4ci*zj_43%#L6!Smp-z#0 zjDDL0@%7e2;+1eI%iJeghpMm9D>)e#+JO=YLc7*);lF|GeK*KJ?M7)R9YJXn3o%d8?8<;2GurTFljL{%H2ZtfP zPKxdTEhbgEZGBM{-$RV3=&a`L@-yKT`ez^*o@0dPPr=i$USP92rxmFb(PQrdSBW^= zY2+b_%rZG3p13Z3ea{f3eVHi2Hazc@a)=@D{JimfX)YgIVqL4vWckQxK8*G4* zJWohH?gOopK&>2tl}MV`za91wIQlMO*H-$q8A~mM1D=eqjkI^@P7I5D#!y%#1mzNQ zrMswO&n7PBC??hlBSPhfi31r4L0p3>W}y!Q#9&Fkmmczq3YSBX#_Z?L*EMTq@5Q(^ z)6WFr%n(+?W@9aNYOML-q^QV{rH3m?rpKH8##ae+N9$GF_-xr|xM;a%W%$t~>#7EW z@!-uYX++9I3zmM$q!Raf&OMe`*o1TzPM^abVipv|yZpDwmotfLN4+*N1g@>{=tAG(;7sy&$!viZg;-6TDKg@lCa`*$fu8=M2s$jmsxuj`*pynw|q*( za?rPfJD4D$DGa|O#$O(Q%sf^S_Sr;lkQ%dvI^peB);282uz!opoA&!JZ=on(1}Eo{ zG`#JRhu;=@7jKhE=v#M>o!7f-X~l*zAko4Mr!NjqvJVS=4Equ~6NKZYmlpoS%vAJi zdZdeSbF1Tr1B1!M0HB)(6enop1m%TPI@y~`z6648NWk}t&WdSLX}l~~q%l(pCt~rh z0dhzdUvy?|8IxMpDE4VTo*_tseOnkiawd$8=M4wHdm2I5a@fK&GN&$n0g19WizeXL zUiNk+^j5G%26miaqFmo~8jOSkmk;F@HPEzWnXt=gz5m?c-cYmVQ=Zx8UY?7ajAJJp zHE*tA2c?*_8KoEpD%@*+Fa1&G8nNYZ+&OI(4ncgCt7B!R9SjU0y4Cry-SVt^Y1hKv zloXs@lUSr4Cgm24YJnNTV9^=!CRDc;VaQ0UCz!;G9_vrYy?j&xXo*eqIy zooiP78(u8^46@xLbm#`@HwdA?5avjl4-`bjc>e;TCl?x?LEz;Uw-Z4u{$RL%&kNR_ zRzL9n${;t#zmh>VW|seu!7OQ~4Gwhw>rV_mWvGJHG~-MT-O@AEDqz6^IQ<-lwzR4= z&B4P87IMQZCOfFN0cd1`xOx~B^j}0#z!{;;Ar8H@CU#9fk|~qE;MC5k2m|QN z8U%tN1}=n@&{lYQXq){lZAErRqQ8-VeT;Q~Q<@VG6_kHKz$T&v_&U?M$D*8~Km}8( zgn*i*c8{A8jhw|DxiH)Pc5`IR@EA|9hq_vjR|;S{ZU7A+0-x6e9aB&ev{Cm^`|I^f zm*FPj#;2KV0Td4epIXS94#c{mcQQ?rb8Af-KN(wPiuV$H6!ZoLa-xaSI8+d?i!xlC z&1GV0$*|0L8z+u8|3_bzDAL9fB2N|Y>re#1o0okL4UshR65V6X9HyrHJqf6|5pR^ffKM$w&#O#_GQ78_8Y*-x^ag4GG zJ^;G;nBsovTunZj3dC;(Eyn>QdM;bbogX;3&Gwsb>wp#V*`+D>R7M_~rEu07G^MSJ zvP{#u?YeP|45mSsGp!D%&k)A+iZ&AVo^Aq?r~^Dnc0PM^r!maV#Ea5qQ*sTUWwPE# zKz^st)J}FVryNZaUK$mJIoYOip=|lJ@h%JBw(nt`Wn1d%hMefzC(?UM}G=*-_ z%jm7850zvOmC0ujEOl4BXd^fnmJg`FVNwb*Ex4s;9>yWhS09pw4XKv6ez_jY@|gJhYY{(0E$+0N@9 z>g^wBpZ%mT9u4mgWoc+aXec(4uwIx7J_WahI*^p_7w|^L95;O9 zcAIkj(Q0M7VY-wek5KzYdg}2jbH*-!ci<-!XSAyrN<2fLoZpXy*zI)qu4>PF@NQy( zBi~%g#U*0GZpEz>QXMJc#q&%chgg`as7APhyk~j^qBEZMXORxr5jb4NTbu>{mXn&z z$yDpSAIpRSw-CXkIF!|c8(aC1e@Hnq20@Qi-X!K%7IRef_&UZ}C5<|;%BXv7edMCl zg+fr6^MKOL1>y*?-hCo6D~sQBUioV<`lZsG&f-$qs=TDe!|n%Mru(d1?gIRRu%r>} zCcNm%-oQHSv-TirNz^8ux(sh_*h&X4p4t>#4J(UoYMvik!r{(M&2f=c&A4)wVwjKpUGzv71E6E$E3jhJ7G>3^cS?b z(5`4ucz+tif;dw)#LhPnm`pt}MLHj3pb>FUKv#a?_@z1-^B@bJ5)DLVaApC?^n@vw z0m_6dFC0|1Q*(F~iO1uCrp~Y}nUZ0d2dJA^FcBVNF!L4B=USWZi_e|0J*$QP=R*Y! z`aS-bNwDFfsl@u3?QyKMs$p#)D4NE6C@a)NFtalu*hYIeR%_!hhe|BLJl?7mn+vB8 z0+ht$H_GC-OeW&-;5?hGzm?pwtiSO(T|iZ%+;PV9^{+ex+7 zmsGWT{m!3wE|qv*c3nVYLN8S+pn%r_EtDZo#Tj3nVaF<9-};!oGBM<_XjF}(CXtVK zy!A;<`LSlDVm|#9n#GyDpcHJ2Uo{@#$M>OmCk<>?$K4-GhM|fnvy1rM7|!1Zjg;=c zCvTu{GL5#lLTMrKUw-Nt`yv()Hi|FN?A8hhL$TZ7QiaN#Dy|5scOVgVIUCAkYtF5J zxId)^ZM(%+XgApG8uy+9&|n0?A=2h#WPh3w9pbMd54nTG zt)o-|bxv+0pSF{CmCoKjm@9+u`mkgC))qO>IzgRE1KJgSnZAT=guQfeP-<;Tnv8NpN~v}t=xh#GtDDHfi3y1dT!~jGmpI__*>)y|QlBt>f2UB}-eI!1UD)jX9Dc_^V;K{%bJ>*{nq63@Ng#sfEe*7`#X{ED zE#@ilI^*L;h58I~IDf)`tc*CzYQ8_}>IIo;w&?sXdcw;7uh5W->pwc=B~96X&=9%j zS>4{VuoOdvPujIKOn}wmGB&GyL39h8ZjMDe;vYJ!xWDL%0*EUIl8)XM1BcL{ca3&- zz;q=1#Q9`)3FDMO{iK^$#ddTg^gsGY6PS!moISwfPPi2cCy(rI+uB?=Fs7^-Vj^BI zpC<_e*2P2`*kt)zLZz?D^VD@!z->?&-J)u%X?uyI+z0N+MiF$Hboxu9rPm)W%k<5h zQpR33UE8px zAq#6xiQ&45x6q}wlk8`87D!GO>ara@);CncUgX&bRe^ocV!6uGZj|b=yRy2yO*u^k zhac;()MV@ZFd{vYDoN$uzh>-y*B7`K%)|f?#VM!qhT%rUX22Pg7aNa-b+=DlD~$?Z zpi1mLWfz^IiwDuHyTi3%C#C+{W;2DF&X+!uWJ>XE&zGw4Q98$64AOrgV54in+}IA*gYHqetZwbD07YLf^#2>M5wYF z?(=#|N%Za4x@6F*c`q#f(Ap5h%K(EI_ALBif6KjR@~oVl<=@%mG7d#6Ten%eBOh=D z9QX9f9aJa)ctVBQh~8?V+sM+!>s}b)^vR|&Gk8z9A%G430Y##TO&caRgFpa&PPFV;(RTHCX*UPaJsbN&PWkwH z%1LK5@DZK_v0_CcA4OM5=!()1*?B9uHeWgDy{pB&l{((AS1Qs6QAbcWTSa2(kgH(y zcF^l)ZlNBHJZS>Z@?i9yZ1$D{@b2Hx$*Vbf&l_$kmaRnj#z)ju*|1R9mBC z>d2<{d$=q~6y%40YA^v)*$~)irYdxukN8uyKRJvF8%)ca&m8IhiN$cSe)^*!gwjPd6$1XZR~sqb{J)jr@f z6E~zxS5PAoR*GQ$kmt+F=xNzTIQ{#(=vZ6E?`-?gm&>u6`Y__BIpMI%vPCXPRa|J+{buP(Y8|IKbKr{)X6aVTv)mh?ZLdVGsR z*v{Z2+Pm@vkI@1dBy7qytau9-WF#qXXHx`DH{sZ$`F4%wF zrBoT`Ka}*V7^!7HXJzUeOKxX|T9`@%)A9A%&>{1V26-?-GM~xRf{d$&Okli51#goF z^g{VPcf6-6gg?wvoqpq1yD?gShV2grM@b0QB!{(qEIIfOE6wBd+Bj5M7DKQb_hdI0 zzw+F_JMrn!ru&~0<5vYnr2vfDJ+0`AGwHhUxC4w^hd-zSX6Ww2*<7ZGil|bItO8QY zqvbp|hhYWkcY;jmN8NS3d_m97kI8BxZ#1``rVr{vCb{Bvo1AIr8sX;P zs45gs_bv}KZ)C6G6g>XKcQ)y6(m9uCBL% zR1;In&!O zn2MQ*G*ND8KX)je;NE&DY7XpB4QluRWxM$bD};({4{L9b~m9@RB#} z-Ea+m>j~TK?nn*4$xSD;Pl*e90~QKNu6kK;_0i?kYHe*W;uEMZ1LRC}bbaIroCwqI zKFc_Ccz!s7nALs)sYdB-v5*qrK5E%v$A)KlP4hzWAP_I@7*1Njh~ojZD|sVzn5IAJ zZ!W}88j10*_~s3gw1|lA`8qOv6c&J~dq_A|xd&l?VdzHU(N}Lnd1HP;z%HnKeT)kN z2tcL&Tb1ViH&vR2ot^1Fs9#GnZet9^ccxD1DMI8I{*(0lsA%@8KNiO>QPX?l1i0jW z^r_Th`lvfauYj8FluC{9;W3Hj?*lWf*BAx!X)^_(149d*4<%|8Lb9}=3Yo;pC0Oce|EwPC!u%-R9pI*ugMV7?dDqX1_ zfpvmm*S0@C+9)C0h1U0BE?fgUkAxVCYzRPx$+8cc#n{gLKxz5yJ|2}WPky+c9v%|r zJ0Pbh0N`gRM(O|5p~XHrd*rCndxOpjmzI3l*|ur1ue*CH8PHqtX+}gIb>xvE-9_|JkH>22k=k8Db!9CM zv)fR9p3G%m*XSsDo!alHX>*tL7Iu`q4YWIze|D-nt-mR*fI(}jXK#5BqM9OMMUHf; zQ>|~+-Un>dQwfNZ;?5)c;+jc;L#QZ5;bkjgV{2>#2j$Fcwi`BFX%Yp21GQ!+*xc$h zCzT5f3h*>BGxf!e-9{#y19>R*1o5b7jbsp0Tn3nrsCN_(Oa3Q{GURAwf`Bmi3{&y%7;;+Q#*))j;M#aJ8~#Hs3L3HL@Eu@44;dPkP~r3l zwXs41lVXUN%qxVH*wDVah#$zfn8bGh)xJeM7$$`+aS3)OhyoRlq5*xe=$kXoP>NaO zlFETBL|#8HNaQIx%;UT8oO{v~Tz)v85_}H$C>q`&a+m9mzd4E0dpsN6!2-6mrQ zB9QU+8d^A0CW@V3&f9^Q$Shi;K8gsY0qKFF2sB%_a?FZT2B;M)0XSKAmDMh>4f|uR z9+Zd?7s#oZQr84)kDPxO!LN`}-{=@~>);-$RaF>1iJWxsg0&9BYfk{2TNz1&t`(|{K3BF?`m)wlZWTwvi8|v;|onRv+^7hI9 zD=CbDtg*)FWm7xM{Qco;i!W6;!xY^mRoEDC9puy63IiP4^&z24gy=?!A97|_SCDLvZ}*0I8((Ck)cJ5^Jw?Y3##K*GdnByrj?4Sp@{oiNt3 z@HO<{z^zX;cT_cZ*!fSylMoGK?4#hjGU;}k8RICzUEjHM{^zl8x=x_xU2oW0!o8;O zxFf3E0S{K1Xi==t{aY_OmJ52?$`0JbhLi0fjR=*SbqgBYiJyjoNKc2}$?D!nLLm$C z*EYL`^xi_4qHXCW_)}M;1mS|`eZ}U^Jk{2(_owkCT?}AP5g(L3w`-%ewn*j|x=Yti z>Y1%1d13#-^TE5K{r21BS}M*;W_}d^y9Us0jZ3U}qo#~nDD(VWyxil0MSrPAxQO75 zZG#?HdN#>l%_AW-?p_08(aPORoHKzh+o2xYbW^Q3x=-#@)z}E}BmzX9gdC-s^^j%$ ziDCfS3+?A?c7Q4|D%%OBI5Yn~2r}aICf;B~W4aiD0z3+ZP zS=HAi;FjHOVhOpaR`9oz^}M@_6~t5bX;`hr&;c^O*(_UUVGpFL3C5!c&m_ZHuF+O? zxkG`HnoEymYlU{Z6Kx}XOwHnmA&|pG9(9RBNwr=+YJ;NNrKmEL%xq;laCJKhcDuAD z);Bm|~Vl5a3EOM#f(t&L}rX46AuWs?F+Y1{Ae4BOThisA! zp#{W`1&?^+xXE*AY0AoZQiX_eo6lV&+DvnwdV4$?xxO>Cj4dH-s$b>(LDR?(Z0DT7 zs#elf%YvY%10_38=Wn^GHi)sh)|iXPe%KStmyyTM!}@C|rPbWk*69^)gI~hgEeM=3 zp*p1;X6kG`ws$tb)BO*hmEDEYjEhS{v87f><4VnZFwo!bL!*SBCzt4U`ZG(rvMgW2 z;o2LDRvnMPJZNj`1;y`u!M=kz@?PiogF%MwF7R61go@FB%CvW4y{{%i8|Yn~Yj?`&b24_ZM1-$Lfi> zEeCh?PPA6dCANjHLN~20$`Dw52@~z+;=*2ww$hD2F!o&2x%R;=p2AObvowT4X1sA^ zOg1hI3c$;eL>~I?n2!c&1fqb(M#Ikf>?r3}!+MP%pFY4Ou@tynSV|PvKKN;bQT@!z zchAqwI6B$#WKK?CB{@G~Pz?`hn!mRAUGWQ*Wes`-;XoONOoHc zNpQtyUei^dQx^v&?oatePJN!^p7))E=n&3K9H)Tjk1nvdk6gHaMP2#_Y3S*&e#mP|2jQpqT1&Z8 z`+COBo+K%;B-t#i)(RLVQ~+^DNsFclJguZoChwicMLn?(8pjKK`Kcz&rJE2ldqgnp z3e)fDD8CL7WD?DdBK(szjywmf=e-EkQTnabxo(6*sYw}Y)-;Dr+%(@JSMubGcy_wz zLIJ(S+K+d_FK~r*NuvJ(k8CXe1|FH&IsU`%6{9X|_m7LI=eln8C!}R6I~E6_f}LT*;6DJhZM|E)x8^) zzq@OZPDbbLkhOh^m>8ZW)6T9Rm;a>h=6;#_HA$Dlp_%a2zF}Peqw<-n%?Tg-%VYHw zQL>GWCz@{~xb-QCu=DuTieN`VUtwmo`aG;Zu3feCv%xl2f3TKceyIoHuHMgf!LBDW zFs0w$XQ%a(qUmh#<>Gj9YD3I|ywN1fBH=z`XSlN2OwB{7pqE-yeq_)7;xfTe^9u=Y5oSlr1paMhQ@^<4Rw zBWT;VISz2T)>^^q;0X(-~x;q%=`Z2c`;V@U~ zBWr0|eY+!HA#8kLtNo3~dd=x?K}Yz*;9hV8Zeg<8GyNbq4Z7d>WGsWUt z2XA%rfSNCtByFV=b6P_4kPyes5GLsmK_r`0fL$1{RdM2a_y(%2vx4AR1)Oj4+u7!-8Js=k!Kb zif#ea<%tVCarufvlFbF=A5M->l$_uG&~8`~MPfifSyQUT-Fiv$wX(rX`i$WB^suRI zhzLGZ|D%lAypq4m&Q#==(eoQA_kB5tRiK!osc64H8t$xV?jSeJaAzp9GDK%D=ti|s zg$aL-vbd;b{6e&-bnhf{?b|gpFC7oV;H=FhrDeF%bCP3-Tw}~zMmHyZylmScvew!K zX8N^I9ozJPkRjtPgnM@Hr+oedwp&h*iy#4IM#^UR1mgbwF zgJAn{FU3%YF)~zCMis~({d-+3LFDgRENXh-+W@o;9RZY)Jw?qJmjO*d03;3T*{B7V z+Jc1;2PXG#S99i|3%X)m?3LU$5YgrE!4#QRG_5Ad+Yhr*4Po9VWSCttu3#mk^~?ZA zgc?VKRA-EVv1=+c)5M+~ur37lCd`Y26+Cz#KZ#IyB1yRR zMN{XF!unU+@W8E>U2!`?CuYb3w*e3aMu;DQeYqt~pbG&))3-vlmvQ&on>|hod!Ms@ zIi^0viB*+V5cpl0?x8r{I1$b1Nza=Ks;xHZ?>u7S<@>E8hs|>?zA7c?^P$=RibKmM zx=r+6P)=1vybVc@knANsMCh?@#{Gx8Q;+k|$71QO@8cX;>#`HK0e94tgS!rl&4e2wrIZE^hG zQ@iD@u(=3*xB`&eJr`!EOnZiNElw7bI!KLewhw#vuV?}!XPO=qeILUTBR;LSDCfUs zdYUN)HXudmwWbep4T_{-iaxTWYYPfaYBsK`H~|-wD`M1^mtVLeq z;_7vU#K*~Ln9M|kD6_FWLBI0zXmOQL)YwpW_)?JcJ-v|@=Q!02>JlUn62tC5GmPcV=rpR0 zZbYC_MBvNm&E!%6hhRxKr<9BEX$@g*3efqxsImYxQowci8(7DF)9uu%TJ)F(49%Vs zg>LG#J7YIoYOjnR1KZZ)OPzG{u7QiIKksH^38=`^lZ;A_;aF{taq25qZHo`m@O`Jm zwOQ}I==ZwbJiZTaG=A`Mlu}Lvky~lT2AdSndz>g_yJsrrG7-Dz#KH_CZE?*P=*aD_ znyE?qhJb#+reN_5Fo^|cL@14~kg9@LA6?UBL{*|5E=s(5=RfS-6yo>D)#s}yD?}5q%6$B9kn+eGCM>Bx@fd2!c2i6PH3)Xw)Un}0nb#qD7DJU<4_uI%Ub9l~+0LfH3hddKF*{H1?hM>BUs#~S) z8DEiAhG(rwPTWxHFT-%2SyicUsi0V4R#ieDyeBGjQ5yz8E92<>`&zky6WsDkl_?=< zm9b!OrAtYcGV1eS_o;@`=>WL_z6tmBD+XvGr(H-GV~(fEka@RwUzB}TC1aMWF=ikfiR;zO_;eYmpUS<3(cMnXdmu+?`zL^F zr%|uvt-mwfV1+2=GPNl%C*|DS+$>6%nR3Ma!rb76Z+>XkLv>DkamU4(Ev&gx{JaU7GhwuC;x0HI(>+l!p2f+5vCMxfKYa*VjzWj@L%ykxzji zWa-wY!}5gNUOhs8bJV$Y!&?s>cd(?B0kzk0RxIGU9W@q`$tC4CkRh&vmJHXxHI^qZ zH=a9F?9*-c8&@BbYu`#zQ_}ZSA-9#r2hHd$8fE>xy|J2F=N%<;?<&St^Qg}avWBc^ zzUF{hnz6=GsVBR5a$B~i@LFd#dL3PuHO{#&{&XPhQ|kogy&FxJ(Uj2?=CM)zmJNeU zMqP<51zF~k#g)HTRj=@Am#`&w#BJ+$pvTvo-|CPa#eb8le>GEOX8TWbf5|^seDFV; zPwXDCk&)_`*^6|5ax*_VJx5z9Gc-G5~TPSNYy|%PlLpVy};GVtShZ&n! z#<(WDpJOWZ%W#t=>$^AS`zsa<8)>ujZ#TvI-sA=K|WStLOKr1Cj)~ zb#qjHVs2Ivb?i%B14;qPl43Zi?CaSIxERCDUn`VH}6oV#{;BiRJWm=%(l>aZ5u5K0)33_Kkxzd+$JO+U};q3H+MEJYw4kde-O|Gwi7GD>j3d^hQ$n<$g6D#Z2n?LsY=K*xf z=1+&0PURRot@>JSq1ztr1U5A#E94llv4JPyKf4dxuqXsMGdxAcP;&jt$3Zx*HU|R7 z4Mx`(ueCKR9kK*8Oef9X5BB!oi(6l~8|pb53_A{UyX%l-L$9~&{ocBTW```rCO;SE zW8Ew~!wHo1w(3i9h6x<|)l8>GXKj_3<>4l(7PXT?|3pTK>J5KP8nq)N-pg z89XZ<@^MFiMZXCbzHocM=zA~Oj#sTbc70XG!CwGm_+uo8Jtdsbd(zX=*Aa+6V@nPBCM;L6{f4z8C7bM;~RRR6i_)LW>V{OKOqXI-2i_#IUQ{_?%9O_`; z-qEO%f0i^Xu@yV?l0S>}JSYff2M{fVdkAm5lTk*~l9IZp#636Ssf!*x)d$GIk}x z{oVD}+^aThAE`_+TAC2GF3>W>cLK&@^tIm6>vT7m9%P=xF>jU24FQZh5p`c@`}?m0 z9+3XA&O4*jla8s;5OrotJg64_8WmFy@w2Lw%FhT~Us1(WA6Zewo4lG6o?HY*SZw+% zcyOt<2{5_$fpL&1kZ>+57C+|eP6g__0u8*@?RX0TJ!)M+wlV$;P&X=NYhq9Um#{qT zxIR_aLEhm&wrOmoE7Oy5jA~|SN3oc30$>|uWjHy4uxa*tmc@BLv0}p(Uif@&4qO2U z1tPNzUiaY<+sR6?HPLbtSSAUkpZTeQF9fzmGzjD}xWq9AF2SwBq${{-rB7&b?Q@il zCWqzN89x2bVyup7=}^`1LexAKGX_J*v_GcY`}^E`ZpJ6kF1S@)yDgKhLZWoImOF}ZV8mdp}BUuf2fZItFz$T zdK;XwtCz1)Vj8ngTO?7T75poPzLq1{sKkSrNP^H0QtJodBj2?=zd={7qD(cOXxjEv zM0MwA$#efaw;0l&aFEVq)Vw zLXFdFkY9^kJVQOG_N7>M)$YlKYykR3Cd90c7Fm6FQIahtz5pTk@3gIx7E*VkL_kmf z&)vuJY!i#ZF)yc;=8`i#y1jIO2oDi`XeleOo0!c9V-);PK%2Wx1?D<+doaGmF8`&> z-JFlGE+@Ya-9GI0?Cxp?f=7}Y+X6pu4kyu)M#;DzhLzeG_Eb#7%Bo`exfI;#XZEU7 zx>uMY^V0A-hi6!jSid2%KjK6Q=bzsISNu}R{8q4SeN#*%IInvBhEil?Nx<;D|m2qO**_0 zP}b;Nb|V#gHjgwdZe;y|bQ%+8+1Jio)rL((BFB;D|1wgxAV5;nTP_CMtghHf)^&j3 zDRYpi06mT>1!SjRT_EsCmJM-QIpdu5fDbQ-!zX}s_VA;^rUkEn>wPu-XxZgG#)aZl z1~q&+Hsd}DZNM~~;8u5<{v1|4>S^w{h{93#p+1nn30oeq(4J`1qGF$DGsN^L70Vp# z8Q6@HhuT#OO)aBFRi`{l4bE)(6uoMV(#{0h%&vtGN8DIdzP{hZE-N@}&^u;Ci&I5R zLhlk9N&liXQueP z4dtZ$xnpc2%q|vO@$A>iU?sdcOr)At6@`^K@B}E^QidYO8aD}1F6PFmNTYaHD zc{0eRWaz*cSkv>HdfGzm78fRIG?%mMbu{GEX;67tuL|RAy7cU^sD;lCPVDYW>g&LB z?#x;PW*QHRxs%{vFCwg+A$k~gM)8j-U94&62xT}y8+x#3KYlt0D84;TcV0L&N zO6QRpjjli)kB%@3V&%eSra(*}{&}6w?C|w%FwxLP8mqd~mjJ5=z)>;zi~j1=v@=ND zH(2~#`g?rCMWz~^e0_s$d1*hKW|mOKyWWwj^~%QpNibp!{PfZSi%Z0Kq9QC86-iEs z8#+ftsDF1>E3uQ2lfxkZrCJ}8>jxfY0PQp!omWj<)K`U=6nCZbf=Qxi|Jb$!+LA^O zEDMSp>}=BmUd26aF_8?>7YUd2z!(M`kYHd#0Hd8`i9=zdwhUB8DUQINnJl2Ai8#9+ zFOn)t?*o4rQ;tj9*83*t*gcmupr-t`{AsI+PUl zx2dGAUkWbN2xl71@^*B4u@%?9KfxG&kYXvT%W^yoU6&PwqyVg8$h+|3T?xVEE7+rzn zd>_z`;QkYI;*B~gh7&Z(BE_gU{{!?RjC85bn4M$&*xuUoCXr{Rykm{{bk)g5L7ur2 zKdBScz9ACJbwGOp)AiufwLW_A6+D?5%NPeqfd?_oV81q0l9?cXXmWIv9{*GHw@7Y% zk==b~)!nu-OZCE10D$CYHn%-{IugmR23ZCsm1Q*Ax4)5&=s-V;9AcNeGP-x{vlzSk z?|DU`-;7n8m<1oS(;gH*4sb%L*B_0=m&%hB9%in;z_myq?f+Zt`*(g&CMNd(J;bT` zwPE{DSLAc8eriL_wjYVLwO(eE1!xt*qS|dELu!_zgm-qJu8{Zl^_HF4P0C>L6El2zvk><5qD+)d+31lez2^rq18M3!O$}eR=|9iSi;KbJ1YE*t z(#jK42RfcWKAr0wMxbB#4p`8Vv7k9bv!!xT0fMfU&3;BEJKFAQ&p<<5dAD8=mOHm> zQ!)0WQU~SYMDMd*pN&x%#xVuX`t7rV)?=nOsle_y+i6TZEt71>?m=~>@M1cPbI0F- zW-Mabyj642NmoXaEIdde_Vd@Dbwn+#MJze`QY_Jyi$M6|e&XeM47g99v%Wh$xAjWM zt#aX@IJIiSN&XDOV8E=*JfXI}F0P^S z5vUj>=9%#(sACAxEGGdYoqQG6%4t!_^2r8Ce5s%SpDPl5ddV!(QQlu6P&7Oxv=&`tobz#Ave*kw!Gv*@O2AM`;xY;w6}k zhv(8?Q}1UJ*=B1Y&Xm^1JT;ea9G#B+*~zjrCb2Sf9ts60fsI^-(Xw}s?x&H~?6h@} ztaau7*@8I>W(o`NN3FcC3`*q-Dgp2Nhb4cTI$Z0qHc^j zIjt`5)B1VsayY^*0e{Wi?Tw0f{N~m#-h-_U;%vrTtm);qVS0wdS0@G$j zOJVg_=cP!T9r{yk4YEJtmV$T-wIw>ZSh+V5 za!j~*+62xWG1#BJI0Pi)^B?!)Mh`ad?EPi@{E3|0{26YLwy@=^c1mB4i99n8JUY{5 zw!B|NJBU~*UHIgO!>UFJ*S0nezo8yo+sQY6I6b<%HNPSrSm5p=Au51p=5}FlG4iV? zPNFJ6(;STR$fysOVr){LJe=%FyV8-CySX3NbPxx*eqcZ6CoRJE> zuNJ-D*T4cGPJ`emY6)>Wj9X>RsHGdBv*1mVaZsaNXoYK}UmLg8v#n_D94%&eubt8M zkypz{c5thvr^Bz!yUi2aHu*sOCfWgJdUlFu)@KdVr{n)I_D(^Xgj=+2*|xfD<1gE` zZQHiZF59+k+w8LK>f-HlpUyt9A9h4W_cSq1+(x{x!hiKPBZffUN(g(NNoD$WuQ0r!d$7y)tndQSBIv_=@`{ZC z`3nMRTmf&(tmXnc(`v2fN;qcad}kF>@`a;CNigPuhNX}VQvR$q*E>_0-1SxyfkSFx zSqrPSdIcluX#bKF07@l>eivHn^ph9jwc@1}#Q;3zTS~S!>Zv%`xT-eGuX$C#pfw!0 zPa$ED*@lkMs@nm871r8@%!n6u%3%tyxIm~>>#4NCWSK>)K73VQAb_fI3Bmfs>Dg?@ zY|iH7Ai?-kM^CH93c2tnXUBWAW(dgfsZt$D{C|RQ7skQqDSz1Z9fE}Xoa0FWmv>Fh zM^uNvJ+FvoS@Owb(zTJY@ok5oQ*0_fdwJ>l{5d>+9O^%epoU+eP3p_qxAk9lys@8E zapVdc)q0EdFRhmDBbqkY{Kur)4zo@oGMtjmsYpH(9H5lh!3Vdf*h?H7>6tEPX0v%@ zc@dg2t`E;~Z=hKP6OpF^oO!2zCP*!J5)A~WSUfp}Iyjv{*usSM=LJcp{OOFVhlS5^ zAoQ|^?$Ycaq%Wickx{Jr(m_aU4E*pbt*AOU<*1ZwtJsfM5|O2lEDEy6_Xf8r6t<(` zVD=y!XvZfp9Q*C^Byb#3;*ro3?~;R+Rg_|2DmfJg$gt4|%q(R0WhCN?vYn1#fF63o zyqNVJ-_54Q7nWl7HY!P=|2*EO>eQ>q-lwwt@n79>ShLmgEp~!%2_e=OD52h}8mbLB zhLJ0+r*RaMAoCF_1QLU4iOL)u7z-vw#ZS_JMD(tQaC?2q-(nv!lz!x{tZa@Ltf`&k z>PA|b)v3HZHf<~mgl`jfW6CL%9Fe5xwRiLD&F1wXlGGe5G?7Ybl=S-eQEFzcNUTW4 z(Riy!j7-Lfh>$AAH22s|<#vI3oMuFcMFYHX3d@rSSX=44JQWf&TxAXwFs*UurDHNb ziAYkieQC_Q$!hzWv*&bV%@(p8;{Z)Riz8uDjxR54$AN4kM`&`n@oe_aVNy*g`%r0S z24JSn_e`JiPy!eux2OM(XUNn(6V<*J_+VDJ4g`ox3JK%Xb9(DEXlUL`M=Y@n>$E2r zLpt%Ef*jP!C7f#Mb95bD-t^pcJ7h@WP>c&%ke+JtQ9{Cc>VSeCzd z$^>1IPNeD_|BP1aNXdmpoFgfHI8~CmSH!nX$x}qdcjbhHmaa93eb6W}lVIs&#Ld>& zcQRS+khLF)AQs^@XBcH zaqk6%L2C;j&BQ}EQ(0uas6Mw^hf#8YJ%N$(%=9nI}YP!X&v|!eWO7 z$}?I#)77m-s3Aq_Pd6|sE(IJgMsDv`ub5yHqrkKk7VhpC;%OOWrQUsXjAFVsk)uKK zD=Wtr7z|-kLeCs>P^6fO%+d?ED5m&ZLz`v+sA}R>RIi1XsMJJWB&eCu<+LvUBOD1J zh;~bbk_3`8F2A28H6PO*W?%k9{7x=HTM3nSColWAtn?E#&VTYz-t)U6*MIRrp7tR= zFaj}Rg3%}jMatYJ1r&F}YbaDe*h&TkHKuq&!?E)e$ zvEP1`cy*`g*K8K(IzLV9brP1D5jmtX(~+LkqZL64sT7KrVnS2k+zr&M8fciVt@uml z(o92na}gMpl4x0qL*~m%%59dky+-vQXF@kh^tK-ky;U2W3G;F;P^s&oo>BEr?hBTG%qyOYL-( z%dcNvf|TE^bnENSUX8Y2hfvCeZ`XH4-=b4m7*&h@BQAk5wY9yUmzEt1)|1Cr*J~~_ zJj8@-gF>1}nyt%+NYE5cL}C;>shG0m=G8qgajK3u6;3LPvDtD<+~+%oTR9FgClG#Qr@fu4yP&{su$G z7UTS+Ofty#+jS>IGVAWL0JhIU8mko4ZSb&cBWXvrwHS=wFPMrGz;*k1R>+FHK?5>( z?S`wYsO`p@wj3I4v0EBAg#qrBa1~YbC#)vuapNB8m%u#Z8?&iT2B0^F>2m6B z<3d;WTKl75>T@K7_yiLQtHn3=ux>i<>m8ZWQjhX3*b#X_X5{ACz9qIjCj7eDmG1rx z>8Cb|f4=3S^x5besO&-St-=j17>bf%a@AXveIL_y$rYURt=yLr95B^8~fvGhe@{C&+{|0|@2e{iTAGDz92A38fjr_&v3g z%Vo|`^^_^nw|Y6ODVvA~v7%FI!C)7oswME5IJZLH?_+DK)%a)ZKk-zdUhcE zo-;qt)@Eo;Mbx2;inAI%ciUx{TrbGAd*Eb+5anjoO%J@>P1SjNNOmYPaG$#(YbJs$ zJUYPJ3+OF^-G`+&$(LU3GFJdiZ#NWSW(gnNH%9(l`!3lg!j}NQJZ7xx`Pj791wyQf zyRs`Ki;cJ*UXcN$J|ZF;|Mz1{)P^u*|2xd+$^Hy!GuF7GFwe=l#mEuS?E{~u8@%{g zMe0N04(c}=C(6n1XY|$(C-hcZrw}IvIBW_4Zr6O1#n9=h?>AmdU(=HgVeNwh&Z9u1 zM@Hxa4|Jx@04QyDb13I(w(<$`Hh%Yo=K7OVm_R;Z!XMn~8RaT;(P#gfx4ii%OFsWB zt$8drX*=}Ixnj%-@ypOmo};k~@V;71>=xHKJ%-G8mFvEMTh)gJ1~0uwU{Pe_K*~Rm>9G2eNHYv4%b4Wr{;ffv2)i8_ z3t~>U#~&!TzydqK1+r)T`BKf}2MUwL05N#!1bWjtkBYZqf|ZdlFQIWOaS>$^T$Jpo z^WAdEYteuW8%fR8^Lc-B6Xl4w=e|Rw`h&lJ&9rai3Wnp9^s;+=k+w2-L++y`={kji z^m@dKEv{=z?K{pbbF6x#JGhnHv(P`7R|Trm`*iqZg;UtLfsRz{HJvJmQJKZoKp{T64ezourSuN}!>+A4(VOwcN65)`+Cp}xLy0fCMLX_9P8psrI;!K|8zoR1qt z17I0hyRRgpgWN4AcU`XKRPAEeiTZgh_$ZjD;x+zEoxBxP@0{rR9=t4BDf8_SgnDMuU@~8*pza6YO(CvE z-oOGR;>%{)kjTDlXYB_nVW+UHns&Y~r@(#OFcM)0j~(s@J?2ME53|z1b&n(O_DNnt z&3II0Zbe#0tp8;^^YDnfX^x7d&BM`T8#I6aa@3*(6}~#?5$m15BCfNj&eVUCc{Iq- zb4jv_Ant=Y9tw#MZ)f<~JaLKN7vpzZ9bhyUV7r`qgT9-bibw6eeN^7U@NAJl$}(dY z{nPPXhuU|HlF*V5ADc5dsH^bcR8Dg+Wu@>g$5alV1j}VK)+|iYLDzolI(<_tN z<~UGKAVsKN%c5gs&LPw%#U*u?vg((z#KsQ#@Ciun2=WE5-s&A2d3-sa^YgvPqTBKgQe6b*5y)4asa}~@aoaCYCZ^ppGV6wXpJxmM}`Hs$~swSwxonz*^E%N0vfg$$#W+Tr{ zLR?*%ql$fHnL7q@!bIV){>cho-*$VLP(_ZP{HB z+;H`qIO%WSP7Jzw@TgV+{923m{FdLt9NJD~A4yM3?qR}G#nYr+bPg5^BM{b!c(VyC z{0Qb@RsPj)l_CB zRqy|9Bg}N{)UYqAh<-TXY&veg?zDe@><|P*YwdS8ijj94wP@Ljj8Gq9ea(AP<0@;C zgF}e~@jB?Mn*yV(qBAH+)kNJm*@S;#;F6+9O4!I%f_ZW=;yD&nTAZB%uHt9zq+;#p zWSAP*m^WwOUDhi-{DO!Gy$bKkMxD9&Tb}Oc2@t-t&JH|xc~KVLHf^^n*>u*XVcvej z{f4RHWZ!B+B`1^l71ze;3N>JbJx5$}CrOp{9nx3OL=a$T8s*z&t#5#x6&m(QDC<`& zxkF#nE{jAbr6xu3{$u!}|9pM^p-yxp(w#eKvrUjL1(vu*ia`c|P);D+wScp&qkc>c!AtW%3e@pB zxrM7T&u*PP^Cogw1=rOre3cGO$*RmcSZh8%Aa5TP^CHJl>Kd$6A}026o*Vs!erwfv zOE*rg4dI83c}LzD3i`F-dgy8BjGcj$#Vm6C1nzR;S`VANY=(q#(p?eqsGoI{Eju>M zZxNK*wA0ZdFE5kDHzyNVZuJ|C!+{6QYGA4P2^km^i*Ylnq57nrb&6W()13c0e&+A_ zobV3^6Smd?tQ*$cK9oMhdnQo?sa(=M5}tiI3tJM}NCR|gz&R>ogClli{FAl@7d1Ah z0UUiu)_QnA#kL?@H7O>aUL5w0^hou6CuCI7l8iw)i4bUR^=K=p8^2efm#K#BxTi{t zI-wGi9N<-SkCdExV%UXouv}+ggL(BAUP|MBjI;P)9X2HzGqO)-PtO;CsnT3bhY6k? zQPEXBI<%zL;>zzDa-VpbR>`FFB4G8SF{MQXAW3JihGX|;cgiXkJpBYjG^4E`Ugo*1H0{PIHyUO=NInPZOq5w3S zcRRoBzAx4GugzIwY#=GjADp_!A22_Hf?I!JpA+sEl&eUuLA}QZkVY?yx7Xis4H(Q}Z8JIalLlawn3;|!wfyXYhcQU^&;*N|apT3E0_t3iSW zJjYnN}<=3ih{je7=K*_;mEYogjtZD=PoO$Gl$4x*!#~LU=Nrc-TFwi zJgY1;l0YlBWU@8ns4Qn-(~eh&Czh!o!{nqc_ei9A@_&2)pPZ zQT7eBR`6V_e?s!R+I4|vc7!jkb*$j$g1tTj`pem``uq1(pJBPM^h^sozVJu}V*V9z z_C~;*{MXr|Mt(QmEPO**H+p{|o<@0xbx%uYj{K*0-o2cpw@zaM@m_F}yS`qw^D8&| z)PqE`TcK@61OyB%vE(Hz?R=bq$q4a&D-RuyMx7{bGZX=7VlTy?vZejsK)90Gr82}7 z<4SaZ3^e3!wRZ(utTGVbn*1h@gdxH@!cVCE%QY^XBTN{Py`4>6 zMrkE$#Xo-&GyL4s>KLT84>@7L%?@Fw`>qE@Jv_38*jLl3IzNfjmFbw!@_TF=(9oxl z!sgJ;YpzZTM ze9u#ONjg-VV{-7u+KTt+HY2gC((Q-OEoAHa^h?6&N`Ro5C>*BQ`x=j#tL`;9#GgoW zRlemz{5tfzoQ;uTwzXb^9!*0jXT zamX$mB>TtZ*SC5X74h9RmSFCupSFKToA+N<0+B+E(9D0ILK^kG!g8?l@5?TF-P;`! z84bsK9{z=_sz7kUC(ks2W~B)R?JZafPk(h`vG(^KZB!nz%!m}K9O1_0%>z5kqGrMa zSo7z^!{)m_b%A9?lsbQr~!1F)MZ#w{>Z< z`4o?a#yv%rkt>g~Bw;yCFm)IW0i`eU9|Vfa${Bdwh;XOzq z!iCL6k^SN+FcUP6rWR-c9t~SPEmWHSk^%T~S$dKV52gujS;G5$X(uIo`_8f4U)-T* zo++~2_U6~1q7B?F%l69m-4gGGQ2&i(Jb0e|oZKxF&-@_yRcF3`TgQIn0@n9q6V4Z_ zvh--F8&`=Qn$`_d?EiPA4@f*o?dQL7$p0o0<6!;|uXT;aPJA{SlK-v#07(`Yq_J`S zg|t?Q6}71Ba@G61HJM%7OyPqgFq`{YUoXoy&`@TN^ovUs=+(W4-{Ifp*Nq}QDF0!*qiw=dCrHN+au8sgn!hk|lI1l06365t) zl{d}MYh#3v$#W76;7wnA2p$eCRMcj<8R{Lg8b@alwMoTvZl!#SYSEFjb1;y$V+7ka z8iMEB;vHmOHxv*?ZXJs%krE;U&kR}AJbU%5*?l-(HrCea-f1=ZO9wyYp$IfjoprgF)4yl=1Jz=92N6Bb5htJ2pat zKB}ijm6pi7@H|GeMbvr^IxQ_at?fpj0=2hp^*Y*Qc&(kW7>9}%;|8{?_yOfZdHq9F zAV#p)&UF^TRjcm1ze#c;G9OAcy6PhpGT{9ytUy~PX~Fqa1jTrI4fph1#8N2f%6j&6 zB=ki|TD&ssp*4u>d}I3LIn?NSlEL&xXAp>`3_6@Nc6NMd!vr}m{#pUU%`fdQ()Brh zx2!7g9JR~N4Ly1%%|*9OeR^_IuEcb%`T?e#cE~m;gS=CedhIhvvi}umgK7yO>@b zwJ$E{&?m&|#-82lWws`3lMOMu7;T#vWTJdB%@npX+i~EV4Qz*JDv1U|9hT;DXwb$= ziIrmw&0yInkPa2I&hYT^=ZyvX=ha>P@+$aB2xb!|ng*~;tiQ?Lzg_|_y_#KJQ~E2-B}<34WpK$S_B6OkJS z;L;nGyN-4-!?GP|oJ7Xft>3$5Yp_Y=Ae7`aSl9ijn?x;f{N5p^74D~|&=dL9Q5F3( zbvTtv2_Y_c<=wkI@fRXyhRSt8TIvoROWMY*#%AdPxA8NpLEhKg+)Q_IOzFE%Hz6WR zrb05?(2m+Ezk@~5WL?i_Y7Pyh8J9&gCw*bYs^D~oLtwWScXLPMpet~dq{(%v4=bPGJ}==7m} z!fNWxhw>KX%+ZR=7LPpbCANsny<0c^KFu#o;3mvSFQ_~Y?1zf4gf=pS?4aS#Ee@?U zI&%Q#JY)2i$mNuZ_#-$KGd!3&88CX-)1mth=>7W4@qe4K|63@6gY!R}%PUw@|AJI^ zf9e>W%8zSjqP(iw=Vq~5he)a)G5xpajSYOabaqqI=oto5*rJf3sR%~!$UTaBw^u|{T(?OeT|Y1U1rA2qS8 z9y{^Ci$VE%0I5Z1IHCCwCIkPT>TGGCOK&A?K=>fdAO&K{U_nX(9AkBH?bQO!k@p)n z_BiNwh`>K{AXh*PSQl|#k#4arJ7H1I&H8ZXxj^}?W&sat<^21)8jxk;-E`)KAf+Wz zi{M+cPG`4*_ROZUNm`(k;2xL%Nh6<7N^teg{p?b3lCAV;94QSIr5Y)ehhZY+!dP!4 zkp~LD2Bl_XA^in!FNFBF4KyTe;Yf5nu!bV)aRf!9$@Bt_H8nyvquS*6Fkne}o1u#}x%m4cF`5+xz3&<&1IG!Wly zbmP_;QrM2JzIkbkz<{C?#qVks%XC9vN(b#V8iDjjm;gjQrVtfU9dQBOiJ1M%$}Oo3Jn;1hx_^Ht(DvAf%^S z@aNwuXdwI1NJuq?jHu!ZK6s*I_=hIAHZiz_j5A>6&XqLh7fUau6yqdN4~&T*$r5i~ zDj>lmML@n_O!;cPTOlt_BiM)E#&ws zIPN|X1i2#53R2pyZ%jthgCZpK{Lu3ZAx0-1wSCzYhI&X19BiUjCkg5K$&%AqE7|F> zM0g$F-?lG@R}i;nSA1DNLtCHm(qOIBS?A_cmUU?d^xCzzyZ2ixJTDATU>G@_j#l|y z^mc3hJ%`r*`Fup)DrGLiSzNBIdq(2_!tx}`8)0+OUM^mE1FGJ-)wlMRU%b5ZSjL#m zDP$OsvW~jh$4!>tBT;Omn;V_G{qbGJKZvB?a#hfHqfzu5x(oDk_b0^x82(#meg#{j zkGiRETyw2ldl>wO3lgC={gVDTNk z23g#c@)|C0=dx;jXguDNgTOqCLb_1cWf@Blv3ZB`Qv|CV_NpRSp&(_iD5a-;NXKa% zJA0^@OKzbvADt2o!c8kE_N@Y(+|FMit%`c908Jkh-R~@`X^SZ3%;rbgg1XGwo>UN< zwe`daxTbxNI4~LQyct>-z=#3)=pj`GN_;6D%N~YUT{7sB^<&-3UwP-}<-#!92y(h{ z;zwksJ!Xw`?M1w{1V_7bIq^ye3n}E9iipnx?}*L&XI0^nTt(XqWv?4y*DS2{mm7*NyT2{^fl{ zgiCOXqlLQ%8Z)ux9=Sbk8<#gqy@M`d^wjo&VY-nmzlxbarSyWHN&jS|0^{NGc^$?q zc$v4krep7~gKHX_)r}Z(Ny=pjzooG0pUCRnPD7TX6b2to}?( z*s8a{%Fb^*|M57?`X7Rn8I6B}6tVx~z`avZ2xvKW(l@cQO=zW3Xs+r*U0VVSdO8{93oAAn;*I zSN+9zg-xB&z(ogO=gs=`Mtsn_-RyU_?RLXjsA*jb&vJ((LuHMSX)q5)M4Cwm7U9it z;Ff7+4FC(L5Kc!w$;n_MBR8KE8Lq!lK@4RVBDehXEK$)}E=%$Y;=i68uy5dMS*gg8 z!_&jlE9L3s??;Q^O~|e+a|P#hD>Gy1H?kkCy_z&r?(FfquWwHNqZ_jJtx^;o)z$T0 zVD)kY)`h80uKF*Liny7u*UtmT`}cAO9yrMy`IJ`to*QU{OCBpwu|B1wiuJT2s&0TF zsEA+Wz!<2({&sKTu#qOL^%7LU`J^n0$~d%_*EOf9$WLIa-*Wa$KYIVpd+lbzg+o*Q zT|&KwKZ3hHW-IK4KMJuKe&5E{8+9@b?O`O}H3&Kgj#ANK)Bc zXH@uKQ-$Z26ebU)Sd*o99BTBMXo0Y4h~*D{;Inp)0uYU3MjJr6i=3$xD>JQqh3&J< zFawGnNHz)w1!qw+3T^<%D~QNDxNK#I^l@hN6XAn*HE3fG0>MLWnS4B2R;t(tBHYRdiHAGh!^PTRs5=P3OPpL zBc3y`A6nB$kRM$82Ycl+rp|WqP|#xp)j#6-Zvim)-9`MOdyBN4@lHbzcsT|dqeaG~ zGJ`052+IquPy3Bme{}`ELxSCN<6z|tmnJa5$K|p+4z{iSAX>BFK{)}Kg15KGauD{8UQ&R!{`n4CjN77z_{~sGGs*alt8}qaB40sC zxl+`<&eFlbrJ5(1rVDI9P?TpAE4Q;vNe@Lc#iq8=CYInBj3m=SaYJxw#H z`R9;_N#I}!!MW>nh(gnPIZ~U!Gp5am5I$UA+cW&ulk_lEmF;$Ltb%Nk{PYyLLxS8= zaSaDR;^hM5S+pEs;T8T$JoobXhTK?8vyGEkq5Ql}^tgOX`6wn?N>BqgAdNC%oAYFd z?A`Q>NqA&1u<0ox?4W-qMP}N1>0sRVjhcUe}AqpHw{96bj1=MudB^#O+v>06!K0@E~ zaxB2GbZoF7g_UoTH$hbNoYHZ*@1mYe&e}?D4PB5FZP!yMR%>lru$#-~hM3R_4{l27 z>cNI4fQJIsOAv8n^Jg;`LAvXfz{b#@a6sYGmmTu2`;{+d83yH4qI^HlXhr2U$iOs( z9&J{Ew}bS0lQvTsiA6Eg3C(p;k}n%V567xAgM z#zy!za+PeqRsWr_8G&$Oz=jL6_bsJ@RVuXf*-g?1;vq?1eEcW-!T*0F7!{{Ka9-ta z2U^Hv|EIyPXD3yaaGD1>B#_Ye5jaGP=u(mKXx$30l}T7EcZL@uzc`o#s59)*d8_75 zVwO~xQTeN8@|8e%r$ysWe8XfU%)U=ylJ7JEjHNl~8`eqyhfPtx%`C6%wslos1bs|V zzjZ8O#e5yTB7HYi4i#htJ1^bzZR>klD#yHJlZOhhEKUmRHG7dJ4x%&w-)#K18G@u( z;b9$ao+^ou-|)zXSFci<7_FnE&YIoTq8(k2yIz5ju?d7@0?&Q{J)=9pRI` z74ozz!dGjq_$`;n9v(ePI~=qm@8e8#AMyNyspIOQ?oZXwX9|Rboh$MTxIIHpI#Yoj zUNc!laV}gwgHC@(tuz8CI0`HG)KC+1|MBN2@B@t3d=C)K-)tX)0}QC%-RyV#+urtk zC)8nH#`zR|2nG}3kPCG*Ig9jR&h5iS&e(XDmxeQ6X~Zx(`{1cMFzg#$Ye`w&xz9z! z-B0))C9#hGHi`cyg$y&>f3{on;ON?Kx8L{l84=jB4c)4cIhTH3f&-ZBwW{C`irh1&U_OtlH$DZM8|#Qo-SN}_p2_;K6sc>MnuE+D9yU}#n_#?_K3dRwFHxVOD(t+>Ft#1;B{vP) zPj%G1{PccB$*5c)IWmJn5{I2UczY^ z3Sa1(3u82sx*Ls>>Umi2tiaq(z~53Lmp{izW0QuQe6BJz?bA`bq52|GIcH#rc4C#~ z>1dQ}>WD{X9qp`|#5l1+7-x7+X-_dDQcoigXw#+0or3wnR;Lu`!1OZyg=vFWRNJGx zy(~(}o5LkqMInx~Mg5^|Mo=N(g`@@WgrJO>=F@TaN=w-!RRW^aNkSDJTlLV%O)5Wi!52aa&b1BZp>~3=h3+ld^k?K z(ul&$WEC)434yK6+E2+GuRqkC;FD!2tPtT#ubG)$uOC2xDU}7Uj6FZjyr_+m5N{%N zr4~~)PoD4lyh`_m+d97;=#eDjnMd2rJExhQcZEpJFDx()3QOJ?3uFsH`8Bg$u+&U= z8wqx^4ieOg22}4@IN*5|OLf<6!0aq5xb@s%PaZK3S->Hyv==nzrOW)gfuuen(>`9A z#khWqgVM0Lrky(JxfLc6%ZboXmmOEvRTi&O?ms($#|TUh*NaiUENMtvxov?L9i zw-I&>o3RPRmg{H#^{wW5Q;9(Ek@n3sFNn0Xwfnk0S0&(m&KE({-W~9-T}dE8UZ;%Zv zr5IJT1@`%+nPrB3BDNtJ1hkEcv3zF$ha{5)`IE!fXhHkIfjhcG^Y#wlrI`f%uoJqa zjowVvuF_o9K?>ua$`C>atV&giM2P9Px2X@Ib^z6v8*OBjn`I6321&nGq3@`TX=FsTYr2eDg)j^j-pqW_F`g>M4_{j7@bUICuO~1ggNlPy(K35S~;G z&^ZT>z;GTm_LTnf6$OtctN!yY^wDVazg_Gq&CogaBH5J;^DZIkH8*pdjt1%hk_}@{ zU}$NU1)$=u5~H(8X8Et?ybeqL=rA#FKs9>|ENk|Ipdkz-{Z@&0so##uFD#ST=@aJn zit2h=AE>vMG|TwC8Si{libHkxivZbDB={IvE6vm1jA5lI9Bpe(fk@8M$y|pgPqtR` z5RFc3Jg-%;{`n_PKxq=bdCJff^dL9Tn92glA{g22*Zg;QD>@chixDd-!t0hIna$rY zGUvwrM62w4r^Y{eS^r8G?HV?ry(a4lGGm6>m6h!w^y@;B;(RG32Ox2gF7t!VH#etO z!Xa%6oGm%(bzIGRyI-S#QK)x8Fr_sO^ zC)lhE&k7N(MWDzCGR?sjCPs9(Py0do*LW>ExFF{RDy%43)EPlvOYtq1Azj zz{N}?h8dhV_q0r8#df^b_=>R^u^a)G%Mn<fcz1X8xjc<2p+j;uY;T3fvrYYr0S^FuR($tb= zduUdvt!u7zZgFOw*lI1hR`;Qw=I8`++)3btZ)Z<7i87L>l2c~Y$AScB@>dHb`-POS zzOCL_lK66e3JN+ia|jo-~Nu(Ss6 zK0SaQSoAfIJaGf;?tAk^d?lLBT{L-V(+H@luspsdql#_y|rzKe7sEGVnn?ex$<|&d-QEYL15BH?kLT( z`V8B0P)dBf{^9a5uQ)_rXj4f)EWEb_W%VX0pF=8Se@dxoGEb2NIY+}_!6t4=C3*nI za7!}(h-{JqUfFrJfMvJ9ljv-pac!*v=nc#5d_`oo1HkWi?wnW*@cHvC;ohriz-s_d z@1tSPQDKivdDCzY2yKL&D==cIFaSYH4~9Dz{^iHHg+Ig}mZq_Pf{s<^M2R^?tfyaF z;f^|!khV|By?a$Rh`C|~YdHW#t68YW$IZ?Cko@cN-b0#ukf=w(|gr} zk1~e0{cm?;bEP&ao41Xng|39-VwBws#JzW(*K6@m__ol&*d1cfr7J-*;n3L?}Fa!$&;HD2{PrWmI%}n<-q6!+#)HvNylEi5Yi29sc6w($mYd z4Zb^Ba`E!mxYf+^bi17X5sEcmFP!d*MfyGzIdd2w8a_C5Czt$?G*tY#FZ%(mF8g%; zZ#?=xIl`F#AEn{-KOQ~&KRh}Z&y3{!mr4rvi3k@UfOuU1{-Chugcw!5zB!(xPB3%R z*N2_-4!C}PL2wuCS{EfvWEtA`aSGG()oMTw^|vYE{4A?_s(-(0_j)B%k4Z`&tr|;1 zS0+uZf=39c8oQPs&|SExvTM_~Cq)eIqqzPiaBUf4_;nQPo2qK9j{@sjUG*F$E|_WC z#YJ_clbF&)zhTOLS7C9dw1QBkGqlTq!NSnCaoWATQFry&Fq=tUHwnDV(w2I_E~jwwPlk;M70gHOnpLKoxZEDC0CD}tkX9{9PQ6m^YN)U24ZB~4&ZfvD9ho|ozD*|vOQ~8O|6BQTt>$9XkRhc z@Sf_9i3mCkVeimuC`kJa^=JdwfW;f5#^C_n6N`>&GmXW79KP{pqr?Jn(FAUZZSEGL%x*0~Ef+f7dF zUYo9=0dUw_a4v;hvsicbY-6CTtg~sph?^0|LlU4tm0;KGLYl$1-)DTmFwi|1J$HqO zCrKJa&=KIK$tAkciLk`x`z9#@SR21LR$&-xte|Mcaj6Bouq>|M_AP{E&Oxk<7lTP`}e1UQNtqNDE~vH|1~gVxC{de5Wv0__om zOV1>Oh0+fzA`IJ(alaxj>u-D3t#r0ZYHG#|`(a%O0%kj-kVq0HS}9X5_DGNCv)@o; z24jRy8enE8ZH>jnu)?86gVYwy^0dc_oZIjxxyVdII`e7hV2!;}ZE|zT+TaE~)=acz zvJLTgs!8zEWf-XXDIn{?lerEF{Tt>}sRRhzKyU5Iy|Lqf?ln$R_1ggOiwJNVC4Ryq zzaTrO?-e*N*i1r@nB^L)VF}pT#&Fo~M(80zs%l$E!ZP?)oU*J)(yT&dTlR@pE+i{+ zAj#2-F4IkL^J3+a!QRc6OAw0J5J^xTVHK%yh9XFYdc{UDYm9`30%PpuZDJt!tJxhb z5UgSXbGs`ziG_5f85}9Nsi4eRu6;4Lz`f>nM_%$G=y=hyJ_*paK*yzr1tCnq50Py9 zyw3?p+sqMx%X_d5o00*fON?;lh`io15WF-(K@=+fU0MgbVsr&Zg~I6J{q{JU#I+LexbfrAvgNj_<+P%K zLt|^)9iSo*#ak>VaK$O7;nUhhkGjthayxO{*wAnp__(a9S0A3m9H(jzsN1_5=F0XC zXD*jE{hpEuwoRA_dS4p|2WY)muY7m{av{j$`H%luD`fAR)D0E1Etz&&>EL-pLZNBm z%Ga=pER?z;B8-9+L}(MTZ2iWimT6ic9mnzRx`fq?ufy}liscZnDQ9NYZ!D__z&Hld zv0(#xudB$L>KOl^+b*iZLGh}<)dEaO)s|BFD2u=_#{RuzM@mJ41pv&E;#^L?Sb8>` zS~34G9Ig~yBc+&GSII~;Of3Xdp;C%U9eDsq9*b+I8$BJq*n zull{0XE1_SB!;du)Ia2CpWPJ&>Wztt4%*pC0e6Kfs(_mwDl`*%#(2Gz8s2w|gmoTL zEp2e05RJ&1ZTQzyR%84=h={lT5#!L<~V+$;0wgWYkdLRW7T!?Tjka(~ck| z+@AdoX`tR#ogoUg!hP_e4(o@E{jxpfG#hI?OWbKIjtKl{c^deB&x#9S#9Q8T3rVl0 zXEy(FgGa$EGS;$?n0z(db6@S+Kw zea~QAqpM5l8@E2@&|Jk$6jF1#=x}ARh&XaSg%DSEJ z@(kBd3tb+ETMONxG0w|OEX*~HvD(>6X%Xq$y^^*_$GXu47kQqjtTPwamr zsQmMMPlfZ+1K53Fu@47)4iNa&Y*#;24|wR@zb}F)V%qmOpL@wUO?cn_UWh`3`?TH4 z=NsrX8J*P3Zn4qKEwi{n%>cw(qH zd}h?V+r-aUE@m7OUfWNcUxCOg`Q3xapWO?1oq#ZO`$(cb=sN~No*it$cE=vsc-5Lc zYUkb!HfY6@DH+}B|9_0VQ-dH-5~N$UZQHhO+qP{RU9Re~ZQHhO+xG4IwzE4A^CQm5 z$jrzuLOxkRMT>g{j#aU`3!fY!^>P^0pCRtjSKUh9jgG8U6;NOBWWh)=EEe@ID3n+J zgvzBqi`Hwt7fsped`LZ#Pmt(c6Xf^u%3T|Ct!M;H~G4bd4(&)s4&HB}K zX+!&I!nezn%|BD;;Nk0KECo^P?b0T%e5PN&lIZujZ|~(q;pb9Mwe0#`O#^4)_NJ~W z7xSLDU;8^^k$d=b57%-FwL6a^h@lnt+D*og=QG{(DHa-0*bdqDh)|-72z)Lw6;}tY zRf`~*L@vU)ZbV^JvD+nSgCQzm=c@YFju?Iop4}?XU9|m{QFE3bHUeRa=#^-j`=xX3 z`bfEU>}saUWjQ3Jz=#yr!!7U>8)g;OA-3m>X}ISOv?6M_u-&!89Bt9LIu8ZKR&~R8a(6 z3IFGW?&h){==oK|_!egzAZ~zUcaJ|Do=fDq|PrO&OEGB-7V>_%uqV} zI=v04ihH1+=1^4g4^~{E%M&8J-Bup^agKMGar^MH{%RS~k`^F|ZS1K!r;%WLqa8UH zhFpVNe9Crntg%=|foY5?*(*m-V`_oTnbb*1!N%SY@#3GdpkPs+1CdQ$KRTv0{sV~X?TUW)pUZ8|W^)pU?(3`#w71*%Z!AyT$ zYRvQt5%XZi@&EycC(ggwk)o%XT#Cofge^=LS|Y~v%R^E&DUFabD%Za4!fS(;ECQSe z(porL;&#*md^eBjmd^%Z@$673qXVDT$PVnWMh_2W9Q~^E%$J=t)x6e|%J#DCYds*} zb6@q=lw_~uXy#n=-iyKgYtF7{=+cuL`Q{8{>9_&#rv9&IrL{M1$(!O^ua&5 zBALHoZVr8A6nG&g<1rC9q>WW$kirS*U*p|SH)@R~v^~BFyL7u8yivRQzfw%N8jNp< zvW%!Eo8s=M^;iIO@;hm#4~;}lWU<~7B@T?5bY{C?nRzEko~D$I#JV$sk!Mt1ZPnqz zGbEj5g1n~EI2I=$#5p;T+U%csI51M?R8RfVX`NYhu5%x4ZaXI{d1IYpvU$|BUv#0+ zB=86$Vf0M6LTX+&OBXv;UJSoLfJoiOhYBc)Ee6PfS4x8MY>{zgd|-2 z$O5!Ep3&{cWC3-U@IevM)4;(>D;oB!#2`a!%vH;OeuH^z55h1|fWREabV=P?MFq6{hV6tVSF1b)F?%mv20F$@d<3Z7X4W4^E>-uOyz z+@U^m?k}lBmA2-l(8akKoome$Dn1Mj*XG2p1_B%hfW~fX>706Fj};4?Cx_%TW|V z7AKFgon0}s-h#LOdlYkKHz`3LrBHr9)2qimysv95%;dkI0T% z3+Z{bT6U+HsnB8ws55c1bF3yx0Be2EIk=YMX0{(i^zw z5uyG~x;UZu4mX0wIht&5VoR1)i;Y93>8>%68I|G`k)rYI+%ZYJEbgk=QQ+IR_WGSkcHmO@q)bOcvYY(C$ua8*w20OOQ&)_o48*CatYycVUy+XACn@lsYW1 zX{x8Li(gfCQlPZ2OT|~02R|Y4*RrzRLH4c|+e-H#cm{#AIyAi2YOVdO52o31d}>*w zAf7juCXMzdr++LmvkM*OndVgGU5Ph!yjBjLQ>I8Jl%#CVb#dA7O z@O|P{0IHoIo`~+peGY<$?2?kIN;iVaYjh|HTHaEVoQ&9piC{`PkWRZj`z2?QcmsqP zR*Iut&y973JmS7QXWJ+0Mvkc&B=}N~QzMAUhY~_C=|5VG-3)i6#~eTE2X7*oV9=Hu zhSJdM!!>rDTXA%xjU#-lUr}r!(VHy_sjUom88CmQ47QU88-~h(xEqa7l<1=sIfU;U z;~}Z#Ees^W?cS7vB=xIc(g<}W9*j3(f+;a60A$4T0H(7(>Vr(Spu2hD4(&0VDz4_^ z5VAuf7=v9^E91f!(2+}9dGnsN*mq*c2rk1)4N_uY8 z6Rp`#PHy=fD%%JH24;e_f52OJzfC%Bfyfa=k*wcs@@d15q^I!t@tny;E84-czMsGj zp=oE?ZZ;;8>dh%?B+JL+AevixfQo0R72cR}evR1u;{9EnRqrr?#vWf32EJzlzEID&C4_X76MoyF*w2dE}IXnukIFRLHyY!|NuT=;;CV&w%xcr>y?Fn`O_@CU{0Vy?jdfW!Kii7jq6%d`7OJ$C{**7Gx7pA6P4_X4 ziInCHgeHbpWdns2&lBdFhc)2tR#~7xVtk~7hs$w5n3A##RU1I-zXk$;1HZs<1MrK- zQLmwmceYdx{_dCO)w8Jk)tNuC%f-6%jxmr0q{>lx*$1lHL?}mmxpzSIXuA)AEJu@r zj(i;|{Z9|OwxSarkYhlt#nftNDU|Ki--ZBcS3Y&LS#6{RhX^uAwBW{Hm85;rmv-xG z=FFDa_}j*+5u8>He7UU;H=tg8s^NoldLgt#{!UPEGS4GhX&hD$yvC`-BBg*cDfT)SdVJhcW$ehL?$INB!JY&#(*q#dfmqL9UUEl4Fe8m!Ayk z;^-01OPrV6Xr-yAu@np{oda{L6;*e_o|^5R8>}c52oBPPlv5)DB!bl_Z74*b6l{1N zoXj>i;zG!JB1$M^))amH=T5AqsYD6ge@ZCg6h4}+**i-I3<6RFfx?336ID<_WFGP> z;(_a=W5YyIh!^uY1VX{`$wnjNjfp4-N>ZX@Uf>x1K*g-?B-y1kDf8Pqzz0+RwHN$c z_;fxsa@sj6AxnBFjPLj5i%W;nl{1Ww&V&CH>IC?MKZpZ#nu(&wx0t||wJ9kDAiDDx z%Jpf)6|NUj< zu+e-CrH1#DA?+lS#wQnQx6rWAd}yuQ{tAlhqWB~sZ4WmqLf^IJmbaSoIV?WkN#Dew z{MX`n<K2cxMEh1v&|Oz?#IGhtOd6Rv4Z0&Wj)|99}pF{Eg@gmb&J0J zPFDVvU?AYo%ZV@Bbf12^*Z642E>{KqC`k9O)C=Ux+CIOS_G?ErL2tSQO%;u=$S6JW z#hziy!q-0xo?n5z^3q6TLYQffR&1Z#0{;Wo?o5!&Ss#{%fX`LSiobSc$T0(lc-9Q^ z@Cx$rzqGJQdV)nr<4YF;WC5CAN=7e8(r)lZS3^LuBm89!&3bMEV5pz>)U7tC{E{K3 zIkdzk17EtV9hbGwHCGgFu-Y*&`o0Bl`i|DHCtBghbT}qx^jC(5n~NJrlM*2#$^*9s zO5G8t7Y#LZu6w%6P2e;@^NI75ZR+lyjouTmL4@uH?T@jFhMMh6rwOQ+Ep=-u;5qMC zxTSLUJEs)Ac66WSvz~^^+E4kzW2<%B%o}Uh=Vip@dbo88b4Vres>#3Sb<-Z0t(>(F zez!z%EsU=k1C<*b9O-ute1c8;HZ^VLh}51L57(*V2d(MN63dE%->Wfj2fIdpcyzBjlBU))D;Q7tFtDi2IlA?ql76tx{ldkDkx zc*8n4M4rrqJ^->_QRO}_hXLnnTtGw2OA&laQyFTQ5{Eh|vKKTXaEFwh7n4Vn@?*;S zHm2Quq%Q!Y%}Y6Bdp6;HB`t4FCBx)EKIo?zhlKCvlUItbMqm8vhv(=liMc$4y$&?J zlCxMOyAunDt}ypGzbjrhuKMPW_Aj`*>nm}0%;oS9%MK=a@sRM$cR=t-+pQFaJOebb zq$tv#FC%!vgtxA)FOSLMCN|66^wQiiQZi>f%6>hNWA&Y}@*w#Uq8~=JlyN*Cx06RI zvk~HJUbhBe)kM5jsOvS@X2ffh3vAEJx}_F>Gn;IQ@Wg2FO3KzMhHWAmkl*^$Y*dY% z3XL+I=NhI%lUsV}@+FAY@z;Oz$4J#*fRXRI?6%IGL_Iurp$4gWr#hh}o*34LeHR@s zp!iV*Tb8P9g=%chod~jL-Bj;mbousaD_92QqVWY)9ip#i2#R)?V=Oa+*U=bTa)57G zNo`+Z&zBp4cNZ+!}=@>Qf zv;f((YtJ)1x6m4DxOP0yp2);$WfiGi{U}lEHCv_RTYVl{=~pL)+pcQBE=4s0f3Fi5 z5w(}`UurFQZ;UppeR^aUD!5IAu`0C~2jb-E%5Ng6)p?juD1ZrDbyF``F+Cs9Af&mt zmY4F@x&76&ZmmQeOSFOV23*2{hj+<9zTfyVtY-c#q9sj?tSP{coby&kQRaDG-h$q>-lX}lmUDf{YXhuvVZN~@MtCPxZYT0Oma;M8ce?^cetvsRP(&6U zlK6`+N%b0HA^7___zMuS-=FyZj&qn8{wFL5BO5FG|0z_iG5`6G+1`5e4X;Ry8AsWR zZE)uRx94=js@F|j;iF_nwQQ+Vu1eNxcV82dML1m!+;Hax=YUQQy?e`Lc4XH=2Kd<+ zaefxZjkw?MtsbuBX>u9Fpo+=VsoQcHrJ#7*wR&bi5<=w7V;oby>#gBeuM5iUUfnpe zAqyK;ZZ^*|EA<1yvIx*<<3W^*;*&7dMKHxrj;*+o+Q(k3FVS0Nn`tw>wekGZrD0cST{eb+$BF3)35)1Ot&Y&31J;ntHg z-=B=Ql(RVJ6_PX&av+0V0QLoo2F>7^9FhQ;3ENJoLL88w2(v@lTCt&va826p#d&Sk zTbh%M6;pPC96Z#oSN)D{f}7A>fobdkmrS1RG_UQxJmt&4T$5*h8lrg}nR?r#J{iGJ zkGt_j?+z>FpAS-!5GbB@kPYnU(P+SKb@u`x;TX>lhODk8*s8;~SASZc)DQa}M1T`q z*YiDYxU`ouWn*1#yDSlY`PO{u!BcN6RM|Ht^HlMyi&4)=B8}uqb=#W(qtYQ@n!p4u z4D{RqXn+)kA{_KXKaGqe4DXZ>3JF6ZQsDxMIV4Etf^~{KP(;q0J?|bp#~7iJH4q}; ztH0yMC8F?vJI4Y1q>P+N7!T{msE|C=D3lF<%7d=Ym|A|>V`3S?M3 z)&o9aK$mLb6F9b!tUC)oe9b$|MLJ-Fld}f{m@d8-SE5(LFJjUMpaL6lDh~AbP<(C# z)0PPLRbO}m*L>~-U{{H^&*-pn+SnfQz`eO5BQO#)4bJNd966o?J6lKzmxF`|SVGbG zpsWjwi^Ao>RlGe~o%+ka7HXhpm}geNR_ak_h-=LgiI5Au^@XNXR@|%ZB7d($vI{i_ zN-z0-30fGoVR6;vkqyL>(h)^c@48!5=~*O^HA&v?%|LW}=hDA`U)6Qxt$$LIXti^$ zp{3AeU3uWu4`1&Ut>Cvg3=HQF_XJa4Nxx~+3ZvJmz2;b))7wpgX-yd_v-$NlD~8tX z*CF>|_DLEA!_?m|>}=OgDhQ^!*=O1|H(o2oO2U)G#Q|+87|HNMk1;?`oz7xA?5+eU z>F0989u2beL9@vKckN}Dd|6-xBuA704pnHuhbJNb%$%CiNamqBY$F7S_ZNJ5KnO&6 zw+_oxe)rF-1c-B>Hl>|=RYeTV_aPwiB$WM~QP<@xDE~<@2EP)7kbGDWsZ&7DJsOa6 zmZs#(VliWVU!y%ASnzb5j0h zzu>tl=K#M=CC4f=v_!`rAV$zrk54myXHU| z%R(v3MEUFqVOsW{wYN~Hd*5Vx_JQhF{ulnr?2xL}_i2uCDqK0*A303gh`o8$DU7<* zcad$LAKx)5#dMQ{vRf|Cf!FC_me@&3z=7G8gqM&ESq^7;I<$frm7Qly_oIM1BRv zv4IM6K&Sl`VV4J$)xO`Kh6-c1e-2RhiO{-?UW?SD644&{K1Z2uR#mZB_6Y;huO
    *q&AZc|%79uM{}$&q)~rLEMjz+rQ`6l|T6DhS}p54sWC(z9T<~0j^pGrQfgL|A>|Xx$@%g z{PulXXJOa%EuI=20_s1N%p&rz2f~OTu!Vxv1%rW~A8O>Oy|Wg#UyB;1C=+ok-^iZ9 zz&e1{J0MP)eQGhEp8E4W<^AmUd4Zo@Er9vo>ev5tKf}bt_#ch-w5D|2Kde>HsrnlQ zu(6nrM6#QFCIO%ueJ3L@!Yyajfb+P>n72xgsGIVUj4u%);=+1V;J3R+RK*C&Yd7<1h6CSoPex^(Oy((S7wO`l^|KXx#PFp#!J?DcYE8 z(?C!PXr02X3Q~2wuxq%Q@U(8n133Cq zW;>W0gBnGv%MmN<=I(X)pT|EyPNSmZRIuvf3=O(5tm+zbr6KPXCQ9}iGugm5pJ=^h z?49Sx8i@g>8E8Z&L9bZE2=v5fS1_=z788@}It&INN6ULBf9%bh_U1GAU0AA!Tjw7U zqUjoIaBJ=MB-Ag%^YTdWi&-_qmxIm|zly3z9ql&%;!QgrI^*NvD^6f<--bW7Gt%vP zvG+fH+F@9B48#`m*wBTsotua;GgWRAf`(tEsJ+LDZ_N!9<8HOJG03C0u7^T54Ul>0 z$=wXAGhdq4RP|mJX}=zPiK;l&wodImOS{`jaE}w+1=JF3h&g;oFoU<6^mO*{xQ~qH zHrhb-j`QN>!hr!jY`yF#;yD7%#o$RsVO&u4R}iIM8HPM!?ohx-=qp8HE1YmYMb7Y< zQ!+Y``}%d>dlhO{)0!z9)g=Ojmx54~9Ghi4@YYFc7D(w`tQQwC@|N!#EdckSG!+?? z_4QkhoZ1f9a$(RUf(($jALc%0k&`UZyeho9j2`Zm)@k&O1S(=&HFWhKq*G8Ls;#)g zziCxKxT$Iyvh5we+5)D}cVqaFX!NbJ)!dt<%I79(*Ep3_#MyOdZ99)u5uIWdUdPg# zrs@DFC@RuCiO<(*2z1~Wa6v%`;4$U24HcksnI9yMF(LxumISVaav@~Ox)53y{h`1= z%`32mqG+3>eBGB~0A>&0|91nXCwvQGzGo(3##YM#B+z5!i@9}57b@3{|&9h0{vfMY zs~Zt>Ka)mW*UTq}lsU$mm8DErr9oOM`$q#7wG%Z0rF#D|Vu10}19wW}4ohm#qflYQ zSpf4^XUOI3ie(W(?ZKU<{2rwaW>kT`3{@!k55h99P*rtl0n+PVlL*MHMUm3K3eZEa zf7K5Ng#L8NyF6G&-be#&&^&;NQo0Xpah(CyG+xw)33Lk*U(|0yct~r_fUb{Pj{9pmBd43txWwW{0;yevjCJtK)MPO z%SQnFQp4+2r7Iu16Xllsi%WPHdOYVLW(_X{C@TmxV7>wO?0Wx6`{%17h{WxP9i7Az z(KFFTt%j+uQ#ly!-8Y&>>_Z14-`cFvlZHmkW5tmGzP2h{Ub! zYrtn1cvoG!?6F1;@qmb@zr}0`{%Z6JI8uRK2fEG(xUi4TnX1NxX!;oXI?ycmVbs+R z!vZ!x)40S%#E5!}d$F<5dASLmdcaeV2Z){DU<`|WZG_X{aXgH_NYOcurwo26`2slJ zTtm?V{!yzNr~{0JpYZp{x%gzE>)qG`$O)kT8%MWZ31uVd($p&Lm|Q4SVj5_t3%E#U z$9(lnr?HV)>y)tuS*VKYRGe9(?8<;}L8^1^VtjsP?R`6)u#spV>Lv|HrRSZOV$_xS zRd!EHVZToW$&Ff-mKb2s@%6?a-ac`6s^NA&XRCM9;XjiE(z9TkY@ZbCXw3Q1i>2e7 z&WWx;?%ZqUOtWJPK-!v3B&9`c&61IQ5d_mX@a;`34F_AE-J5~0{Z1vW3T=JUeY5bf zRk(f<byQ^gd^czrvuP@1VVSjd4=vg~0Lh6#JWxU4f>`4+gvQg;?bltMgvRnb@K` zoP&Xf*t6`aW>t1pVR9A5MmNJGq{A%khCRPZ8+PGJ)|$I{$+4 z{e|#-2R%(JB}r)dR2TluDl3s72H)wGym) zXfGfv;z3Or50X-ZFrOhw#4LNF3e3(C=T9F#n5+BQ-vtZ4OzDGC|Dp0c*k*p|Y!P zyZCFtTDYVPTb+ccY0U%bpb!CL9%A}3#}5cSz&Cw^BpG3R^bgHP z5aVF>x*K|fZbCPZ0VJxnN8hjE5f#>H)eApwMw!@_Zy@$yR8%iX5w2m;LM0-7L}Jd4 zLQAG3$Sp~<5Ly6qMcpGY|MPgCQ4^FDvpbhUN>YfNUWmm7p@M7os!|F$tm2iC6sUqk zCIsar%s2K;)B4FTm}BDE6&V~tGQN=cr|mRcn=nCsh`kcvIk{+^C~G*z^P(-h7(FBs z)Em>xpFU~_Y&}kpLyEt%*GyFK2z^**8K&ZMeV%e=tNzz2l#E*PJ2gH_5 zzLHdene`&7w7m0rqvu!66&5jDC-cp79k!x&0!*hMO-{EGyZ@#OHwY1qSGtb;RC}O@ zYY4*kRP5pIpr@{uZ zt#O*nV|X}bg@6K~sLqP3!D1pUu4-$meP`haT3yTSM&Z6nW%n^d6CHO9Um$09wG96A@kO5OPH2szE4}hcAlkf0C$_- zGc=eOS>st-TB-84rZ%j645GWC?KI(|Ph^X&_?M=uG&5W0Piid3-Ahm|db=a&7gk#T z;6RuMD9Z>>5l>A7QKjod_hZ_V5Ce6ovZ);q=s>XH<-Sjasy!#yyU*O!R5W~2TRGw? zhs0(QdDavYM%FrTfVlJpR3M+R&S%W#(ki^KXOsM~)1>;U8s^Me6Ms95&%ecCeb*Gk z`!a~$x0TVbSCezNdNPtewm!vBIUNsVB>N1!YVX+6kI&P%2RCu1pI;u1Lp$ku9`n~BUBah z=fh)_+xV%mL94>K0yX1qv*$Zce8l}^b$)R}U)TZiq9i1mG5$=%<R(_rA3JD5vT4;zf?Xf8*g$2A(2rt7XdzY zw;0A5>&Sxh6j!P#P_9C6ay$wIjRVo*QKhGiS0fF3wq;A39&OSS5dNT*0U&)v{-fAn z-@7#psDS1$vIiW{=?T&tP2|$(I=s*XrwGOrikC$DIt=7u@EeMoSY!@1Ph$A$)hQHncL|?e50LiB7U08p)@nek~`G|oIJ0UwA#3&h-;=JD2{+u($Z+A zxoWn3AGB?1%NbRrn|lt78k-9_Z(TZ}-A68#a?f_H9^lTF6|d$U^79$ok)Nsyht zPYyn+=mp@+LKT4k4CMRg+Imsuv5G?G^-Z#_o7F?D{Ewv0>ktdO02%7PPkKBY>IMlI zyR%lVe^4F}k%J{;_E!#OVZ#7_QDkG&aI93-6WuqwoiA27s){um2WX|$AmMH8a_Lk0~C2`T3C2) z;L>LB^NWnGOAN< z8H4XL%es=^6lrXjY0(O-1gHP7pb zL2Y_y2EWV)Xmg|Xa9fiw_e(f=+ZlN%X+hFFA=q~ZRWV^D)pBIy(*bmnt9U6U=Hpy7 znY7$yTAwCRbzJSeh$?Q=YL@}XY$;GM6;!*7;+s;ASqKiEyDa^>xpv7Y580gzZYhX@ zuskV<{G0~F3}8{@R%~V!5f#!?1x+lMiG>{rSfB&;goz1>@9yq&!8#&A2Q9=Q--Bn@ zsN@4~`-0=+T2Hq?`Had0=z8p3vf&0lYpzBcIB}G^qgXQ9tlb?o$A}UtRl>kBV?)$t zJ~3Ko6J`FwfGFvv2N5(nR#fTY8(Rz14Ig=u)>4;&vuO+Cm4bUJ!T!cS~lkT*xA0gtgF8 z$1WXwv=VIuz06L-ECI#H#zv*QpZ4xWFA* z??aoBXwUm~UBgYL$V)*keUgGne|^8s?Dt2lybu-qt! z6`n-$;$^Y6*nv`bf$(RMjVj4CHjyhF$8vJ^f^+shJ%V0M3Fb6?fBfvLuNV$`5uO>W zZA>rRS2XrKp3Tfs)j!$bVcWw$3?CbJ=s@0Q3aCs;Or{ZoZ7WfvZ8Zh%N2_$3s@Y5Y zn)6xU)&_0lwD)-~!wEf-;@B{tgw7bRZg+P9bp`04QLR=!w)e#JP1gbD!(wd2t+OjS zapPM~+A-EnnyxoUw4BRbJxelx4u3jVw0^W-*7ebKy34E-fo)RMOazGiIOX+=G}>$u#EKCqN+mxN2yeS-t#l;f2$2*zJ+~ zxmzYsKcku7o{w>()4M(M*qG5gGwgA**p?zS?A$mK>~Z0@#FQ=E)rn`ujoalcabe1m z{2S;V8)a8f`Bs^JpM!_3ebQ!tjXbC$0U}4rtTK#AWT7u0@YXm=gru|V*LB;N#jBj8 zS|sOVkSIxt^EfLS6)Hthl)oJl(!)YtP;9GW(`v=@$6cUF{DTr;VU74X=k4~hM+q&I zfgI6cIcjRsv%JGf?%#DT#?EJ!W&F))87{k&4hbv>@gTa9SoKfWbdoIhGKnM?(agV8 zAHz%eTxqiKj0NgT?mbOgt$S1%FinVZ!0-^%G6zT003ucp2wZAI;-lld0r8GRE(0~b z)nSXc^*V-0vWPf}j!Bv0AroXK7O1--VstV$364p*D?-{OA2NXWaz|03H1m`=(yyN? z1T=m^5GhT0T*+|i!p-zna2_=x8R3BVhwj7#{=bYP*Gb%rJzHRKr` z7vT>Az0fVe%fv3n=S6oMKtvUP&;TtIT$xJydy~dkxX=Zl{Id+@BAqo^RGmehNHm`y zI=H;MISbo$*Yz**^Jqb&P2reg{zQE!Em$Adn+Dfu(8j<|&go7x+ayJEJ z0}#E~f;)Zx@CM|t-0())BY}3#erOz4ylo3 zqWD?iP;8K_^7AX2#;J5bF9qp|pL8`m++ST3zBuhG z)f7dxa3^Os!s%T+oLcSTbsijt>{so!usOm_rEE(5i2!;L^Wo4;%|=e1CWd&V*KMbV zCvmM`vdnNybKQ8gBESlnWU6{b{N3j zubGx!_J!GW{z+h3ofSSo(6MD_tyVzJobcJC2KZVHSV=&0CqPO0RyUkR{5M#c6}I54 zI+7TvmrNJ1!neZtEVx>EZ!ieH(s{mnUSk{2v$TK8WF8o{OK6LMh}>t`c6*Tn9}sh| z6$~`+ASE7Nhv6jme{1Z6GZ_YLsL zdw`iIGWzgLB6aUUX%lDlUhM|;~rYE5(Kfb|%K(w%mUObETUM)FxsD1{s9!cq~+mJYs>Hki{9obqLN|_fp5B?MnK@tu1So zPt$~vsd|J{O7w0pTgJ|FyYW6CiUzuxJT92edgW3krt=+c4)9&&JQuAnnv8fgfDOV=lwvjXejtwj@+wts#?_A*60J}!^WfndH$E9-n|c8 zsC7>J5pe^G5SdccUmf#!(#(V-YL3o-Fpz*an->X7I_%-T?cvG5Z4OCI+CQQdz%~1nzA70CInrfq$zT?8o7HF!jWHCNXG3`9ZRC( zm7|j;^0%N4Tx@zgOWQM$k;BkCS60_r986Ubt~g;ZCs|^5Fwm|_+%IyYWOFKChZ&l& ztx^1@{lh15zBzyF^&2<{;a{bH=SL{w)~p4uq};{Du=MSfV332&zy)>C4r@zWPB&cF zLxb`WDYw*U^~;biy?ix}TPD4D*JgY=MQye$4t;}lQ|@alPkbxuo1gttTIIN`i)&?- z8((0$^qM0EwF7%phndf{oZ-|UGkZ6)lLVdV_D{Bs zC?V3yUOU322v3atk@u~4Jn+*`1t_cDQ#cV^4|6U6B-@@Y*r3T{I5*n&(6yqdW`Z6L zYf_2Y7by@oJM+t*YbykvHg!6eg_*nOKV9ckoV1Vxl*a-7t*(Q~n(bHf(q+EC zyt|Gv+M~Ef1Bq6nm^ilCtMbraGW$H0h1U!&+(pfqUQ~N{xOU|s574o@9cG}dN5yJS z#BNJzQP>r9ShcB~J}!Efo|j+UeVKQkkD2wrbYWY}*Y|bGpjnj!$d$G*>@E=F0_q%*u6uFgT(= zD;|ZmTcZ_!I^YMe=1o*wOczU~F`9Hz2H{HsATw+4nCyE7T>GW4zcVvz>~efkW%-!b zhmdqbPBeEx*xde*c%0J57XkUxW%`1*BlTm309`&N@VAbh;8^I;xm|yf2AW4l?Fvj3 z9;TkCZ!P$^IX$vFU+u#AjoYB#(aByH$jUV9AMh6+0{Fj#=?^y2i+SE-#1S zz}hW`{mDHo@tihD*rZ!d&Qdv%{C!UQ1-#UXef@8$>3>2iFmiJK2XwPqQ@e4I4dLGu z-QlzE-(elC=0j*ceD@rXFnyorAp>p_1-Tgx_Zr+Oj?}NWdvl^OxtvoT49uV6<(=lw z>iZqfE$DstS0q4xVf&sJzmB_}-;`3kQyS%oPK^P-KH=2io#BHNe8%A=nmrwgUrk@t zsYfR?k;sQjSf2LU%&y8zx0jCt%DV)-92jPkLDb12bO?@I3^n-*O@e~4U*20af7WNz z9?4$qbFoEvU*#s}1EoGf z!6k_giO-l~xz8@GtjF2w5I}?6tylQmmsw8Oo9#>%*?I=a|k!V2> zNSAhLj7Kj>H9u$0%w%LynpAS36h=gDS#nH=l93!J5D>ts?+}Wm>C?A8Xt4dm(OE?S z5gD#cbWv|I2v=tsFd>|sk$q7K%`2n3SCrrwQu3w{4~Qm|N}(y(^=3+YHHCGEYO;W5in;I>LW3!XxvXflyS=&1eb}J=bgBuOyt7;K?Zfe0BXjB)% z9-?C%I<`EmwWk+{-(&2E6pG8G7&{H$j4}OgL&mg2+Q- z!skp`k3g=`VZJE(a32(OXsHVjLotN7*O8?EP<$m_tT)j*hkPa$?@PSB1%w~Cn$2~Z zZ)XP(6p~ZdE@dPwWk>a~@Bs;^KhDu_B8gtcSw;g+;CW8_HfzB6CqS4HK^d*o8&;Nu zuk#{3dwlKEcqNgJF0KfPkWUGr8X(~DhqJK9Dvg(yL{k{^oOrO^*DW zo&+&1XEy01I#RBknwZC~l?OI9S)&Rs)zU~7K6p6^nXc6YU($(O-NgxcKqz(a&>w}; zPH0F2|4N}ls+v}eI~kyH*S$J)MDL%~$5H3+-t&8iU&+%SK(tOnYp!j31(L#tU$Z zd)reGAkj?Dax7fzllgm%Nwz125x{)>xMT`A3u49OuugA`;Kc$xbR+dL=gl8>kK25k z|HueN2g&hPJsYGeJIPd{6nqm>7YoPTHT9C2ikWH(wnonWiT1l6$EI)1)v)4exHB4ITKDFpIzhiC?~JBP|O}rtV;=SIfTn=O5{)h4mWP zgNkw2fi`!6;m-%8oxU&*MTr(Dic@>%fS8PS72p#dIJi}(L&%F{XnZ6Gz zCv>t)NVs<@!0;H79WN;PgROckpoM{9TQMm!v7Z~6(}CH(Cp1v3}#gGJ`$A9!W`spPYS zz2kmZVAODSo7ZLu97N}|15@B7i^+vqXD$ZgYg-D--|6_AB~&4&=Yc>3l1myRLt=w6PW z-O0WXc;m;v3g)qxs?ERlvvbc6A(!Lpg`^|5d*0gc$jb21@F*aTT9)9RVmgL&fGNQm z3#f?Y#J)ev{+7>2fBuUqVEUhCDU2K(|6wKU){ss*Vu9&-r2hCDW@-Nwk>mhul@>$= z*XNM2EnKq6i#%2+xo`!8@{2p(u;@nC$PKNk;+~@4KqB4n#F@GK&qg>9XYT~~>(Xe? zuCH&e*R6=1)4)W_zB&p!t5MFzoi&$vIVk%e%>VaVE`_R{IUBPg3`}-A-Kx(o^>6s1 z!ASj0X9C)*Z!4-Nld7w_yE_Z}{?xziP+|_*N8rW^7y+qP}nwr$(CZQHiGY~%EtiHX=dVqL7K$RC;c zG5-W&u_L(PY#hzlF$@@f%TaN|%G|SVBoHGwJYSA&^zA7AqOu%yd|MULZbEKd_Epr_ zjq9Au}I17}dANJCb|8)x2M$2#fXOR?qJjeX1KjVpPiel@HB=_u@Y zYSoTbj;pJx`|kZQFj6I6>M5ATQDDDABxzy{C)cbJv#g3;orAW~{~Kph+Re(I6vVT) zClt)jzOyv!zL%E;?9g5kUeNRRM!v07$V27P)$3WhI&l}lE`O^dgR)ZurE<*IyiJho zth5laig8}{bw!w*I?+?6e!Flhf5M&MQY=3|o*bCik z`(TxJuqi55jRW(Lc(an6jfjl1el|ppaR*@9Jd^0SKbmfpFYbTW zc7kZ%7XNfW#Az2pPu5z-5JlJWsEe5C+Z1=)gK*=ItJCgyUawBc%ueECh(Ox^vdff`wFVFQ;eRkSt|m5quA z2i=2&=8ztkWEyEnUp$zttX;AvF@R|gN9E0O_Dwi0$UaSL0`QT>2mn029U^P3$=7CD zpGyY;wGk7?I&y@24Gerv_l`JSu#~JwX=|U2pu&N2%)S8;Sd&&X-wnz>Z)jXY)^SJO z7|hMnx$8}-F&l41rgBk)Laq&vCc&b}MK^O27mBh!&L4j;-*q5)YQ zE)3Cp1QJ_sog=PQ^I$i3^FzOUb!|-SPjQ+^07S;nr&#x$_aU{H)3rl^mo5 zz1@x}*B``MUQz?u<1jN%!1vVQ&_Yd`6d=XXulq(Hm;cAs05x!E$C$=V zO!XShiY509fMpok>Z`+W z$4zmxj<({oENaf_8PYarOLva>bOL)@RnV)tTb~4;sg)*1(&WaS)vMq9Co{iM99oK_ z(_>P2X2WhM4N}x2lT$TuNXv;iwDXRb zNa~6VFC>2Bd}>y1uXEPE?ZHM21tXU$1sI1`yBGM)$snL>jny=}gm4o=p^BNizKZLS z0t@A?KZ0d{V{9ZX^JIbai!q=SU*4bRv7W8Wf;ElGOwt|R-mhqSN53ut=om?OC!qY& zqi;-%m`hU0hNS}`b;>*rn((xwHV+7@1;CH79~F;Q5%akEO0hVZN^wtrCF{y9#80hk zbuw9hGA)@$_d`DPkg!sb{l`5;k<~vCL?KZizeBl#aU88ATB%qv3gRtgP=x~jitC6| z%#y+^c`=Pf#v}@-QmWMWX@%sA(c<1udBe0X_A;c}-%LEf8`GnVx0Xk>|E{7Arp?M5 z0LvXX;A7_^NK9{cVoXIxanuKkb;dl`=+NS3HT?=I29JWitW&Q4_cr2CtOMk7v1r>T z8w%QWn94h4ul5ee<*iY;18eEY?Ri%hA2V!cv*BQyX?N-q) zE~^OZ)Abl>pzGz(|>0mU}0eVpLw;K|A)4k zSJ)NRPVjtf1^rkD0&TVN$IZmW&}faAOr)B~YS-JtoSjcJB$;g;0J|jM$bOA__<1Qt zALRRM0`((Ux9zpJ>v`K3$AcM3NZq{^Lx!v{tm}_m;nwvt)VHHjg+Hm(XPwo8DZO=` z$!fWz+)32#$?dGNH$+h*GxwRNCUJQAQ66S_E$_myOg3utHQ?~~IkzAzWzxGxv16{i z(=X7AKp{vicHm-eD~}&^^&h+1kYz(HhXRlx;_PtnWA?TxvVSl3)klR;Me4Lmt97G} zkAB`Jty(pF8d{ke$-+ZKFw&aX-z}~7L~`8R^A;?G{3~czRj*%nLf!apa;$VMqZ%dR zU+MEM)QtTB7%sE2Mot*(QV{Aoa87ghDgbUJmrjk>W|#RLeMu*MxuIANJt7mJF~_Hf zk|csZr${5cH}j|p$99{xc08JwP_W1peHP$?glb%AgODJa(E+N@gB7+asU2h`jTY5Usdt9G{)Q5^6~6U}0^_3!4zdaC zaApi)mp!@oyGa}t3M?i&FXMRkFh_XR?vtZ_de6aap z2n;jKTuo~`e=~wP$k^WulXIsp zyc@n@BeyYt2FOKVwXbSh@hN+EHvijvHcvfsD$LcYk6#bg=Q_;vyk)E7V)inH=DsfA z4hU2%lx-|mh*~1y2&D#64RFVG0Rf#xhB39GSskc-`g7Ygsbg4YS~QVpO&ozH`1}x< z;@_izGl12!LVv|blTGO`0JJoMX8u$)g)OVaZul->I4eZi9`D@$st%tSj`%<<2DyPK zx{wEnYDrP77rdVvvvc2C66z}Wl9CH%<;+P!$ z9vR8yhyOMFM5jhtLRj$NWFgtX>~rqF--~5kFolF2EMH6yv2~+D^0&yQaq(9JzDrK0 zYa~T5p*je#8drwz>C6U*^`GyO{4>a+RhVB+1TeV)I-gvlX$^9(*r=7hFjF$X6 z0Zs)ZNwO09#ep6dG8XG;y%d@4EgNqzXX+igoO9CJ=H7;gcc<54$@4 zc=ltR?jEL5UYrFsV*fh*2KKqrH{zJ&Y^G2FfXZNTZiDFP@jB34f;`*UQ-)~`TLSru z&*J0gd;aeO3y{JcH!Y-c`1ZY*n@Fz6*Z~0Q!&j?4&qx88cMi|44rKONN$^|<^;>q- zy*?aEG@#vi`Kubt<6C3V>S+_ElzDC>eG83%$hLU{2914qad;uRwVr;flQHWh36x|n zf@BCpN|$X_LG&mk@zFa%BfoZN#<<>t41uDXwHMO-ny@GDz@+)^5HYXh%W@!KXwu>n zsS<{@`46hnw42@l(y_Qj2-D#T(d=awGg~r*2h!v60jzp-ILJD^{wih^Hbb9 zlf{ite)=Vl6)??1d+QK*wK|=b0F&s}-HJxiK#;?^CD$j6Kd$at(vTB4Vdk+od-j}e zbKBp|Z>J;MmVv+R^2`$hc4ndYCa34KiXVq-ILyEX2x;84R^ zpD=u-wvlFkfZv9tpbj2SE!7}lH-(Ydar zx&6-~U2y?j2F8s*0K}w&)tri)I2Xv6vAb$gAQ`e=qKrEwXhzKaLyspOl%Zw1yt7J} zb4q-TY5rqyzg!DUaihH(?$4WKcpl<3-~iTIRQf2hZ?C6)2Rr zbvx}2A5pwf|7kck-uo?eJF8;fn zj+u@Af67IQnugQX|9|P-Ct@)w7#^tdu-cT~%D~NdtGNLt7DU9tg_79#M^~anE9Q@g z&H7hhLygw8m#Z$EM}$jqH&&$G?}v1qbw2ia{^`bz1Ubcsxr3+grFBTyS@#pWhx=^7 z{B26rM6H_TcjE_qLyZ)9B68EAq@Eo6IaDsTlj#Vp#_+A#?6<&Rkk+%(Pmc!C5|JMDgwUopd{#w%t$UTEh6jG?pU{Ow@-CP8J*YWm8g?$HqF zEoq~eTeRfuIZ{b?x>0p#z+)8Y! zn&RjYz`&)C-uJEK{OwvqbAVHx(S0(Y*J~*bVk_d;cx&>ui#>5WEVycwJqxLk)Ma&A zjA6U1mn&eF5R9-G22lahH|!C2hTW4gPy%wA$^$>A&@GEQYRH*#N=*@;BBR@wUyaXD zH^|P|7u#5alwp9$%lI?cdPJskyfD}kOSVOH@{wgpWVPZ|!(JU#xPm~DRQY^5lQ2}a zyCRiKuOK;)Z7Ut8_Q_KSuC;ioS^d-Ya{ifDnpc$H-1>7NtjvnEgDh%c8o39fQE(*yX=Q+GD(xi-k(4~z3MfB(b6CD$vdH~q}BVu(GZ~1#xQ0IBB`RZfx z={%M=CNI`?l9F4&#dwoH+vcpnyk1zaQU(Jy!HX&TvO>N`#))3r0cHPQw@s+VhmBSe z_jhr|W>H>|AUj!T$)<;+a$ngmq>c{(Wf>1K)X1%t>Z6BfzxmGOst;SH%f|m(mK$diVLUpa{i%VR4ZgRbfG!@sbN) zY|l;&BqE8@p=7uw)WkPyF zA}HcZFupT^D0cxq=!2BB?G6xz$N_^U9>ulSl2ed{6v@JhZD-()l>OgU1?8jKx{Ujo z$fnj};&X#!G%9mNQoH##=sGT%vMgWQvX+nl!8Nz$Le`Xp6SDFlG^KyQ3&FE5<;R`( zP8PU-rW(Q~At&R3hbzAfU?=}~Mr`BW?0g-#`d=AV8Moh9QO(4w0h&=@yF$+eVIW*E zYUzin@RJj5@_34e((Y}unsDLK#T80Ta&q<2Ap^Z)k$vuj)SoL4XEnqd+;CYp_%8q^ zz|cUcBLd$omY5gkJ4R;5Ggt1mWF;_kQtOYb0N2jZ*rEyyX`oQ9=ddq()4*E5n; z`w|dKv^9a=>K$bgm|R2J0cuv?Jp=c2eM0k2XbZ~|7tlBcff;=c*YtzR*qq)0J}&Le z>hsYA$^_^WsTNG#z~-Jmb7h{BOZu_)N~-bEKLj8{aeqcVN_`$(_)a#SM!g%49B79P zHNu(DsA;`-GgTM-Thf8zKpmpXJ!PxSkJS+CyWOX2cLtYcc^2h8=?_G1{k_sz$syW0V z&XnDmmZk~chd+M0egW)o1qA++2(bNECMgE`|1AQTQ?XnB2Zwt{!)n=dC{%~WQ)~m( z+y>+oxHCtKeqEXerT-n-}LeQl->-Vaz3O@CaS80-$A;KSaAtwCE&$1H1; zpwAP((zKI=tty9+Fx6JiZRbk4vsSVzuDGIeM%Jo{*7EDZ#if>3r3Wy$mwicD?HL56 z|F4YBAB$zS<|e=Do4d?ZRqMTl;gU}L5nu+}EHig9W61W0z_!7vHzLd50}gMOaX7Z=~7 z8=>qg(v9u9Tc?|wg=ULmg>>!}HQANt%$mauN)`Nsw`>g5TTTw_j}z*=+Xv;`n81yx zJnAy_F+)Y`4I{?1hS%eLAM)C@X7$TXV`L>rj6~2y1coO3c}62;ya{gno!F7)>*aCrg=oG&nwT!L|%%D;ZpYlFDjoIq_JpmYXOnG2oB9B!g{6sO^Lkv zg1an{+Bsd3Z2)I$JF-8Q#Yq%cgzPvFIF zTWxy6AJNSE8P+XX5lk3YCuCeC_vlN0Tsc3VkFLJreLbywfrGDQPoI}cn{FkohldHPlFQNjn!2=`8L(G0p}2X(;HK`0TC+X;{F{?Xt^S37rH#+vqjlt~HLI zhI3=8PZ}YIWJtnB*o@w9vcWs1PLsrjBaJ0eJ5V}5z&0LBHM-l4v#$wDb%aJ+IwDTYmmh0*;EJNd zr4>;z5ytgVwTEXu>p>uBZT@^AI_ZJ@MVovWNks4e80eyx^nZ`;7ubqzyOCLOs| z9Fjj5q5QO1?2l5aLhOmj8NM!!+D=Et%vE{3 z5E&I#nd_A!OgKb;6sq&e^nD_G0=d@)xm%a!9Lq$IC)2Blp{JoE7OEW7iyR8=Lq>QI z*5!y377z@5{N5hu12L=2>j_ne10S0df3%OndDn?ejJb;(?+;%YW1hM5+vuT4)n1|#b*z28j5H_A8vud)evhUeXDm4WFH8k7-+Q*HT1szgTP#FmkDPpR`XKM1LYp)ArH>o09O8j87(LCqU>D38u3I za#{dH!VExs&22EwQ&cL;&?X=Av%Ez|Mc8DljL#i2hmSALE-mKZ9Tg?g12k^bV z4g5HnZxdY&q5ZshkOkDXKP?t-hy^xTs^0e`x&u0p={HD1bHkb*%YMFZc!MHYZU15P zVE*swwOCmG*H5uVUBhmR9pPVFdVx=5cZ>S{{0cMZW+AAiewUW@?jiR)>kj?Ofu!UT z{f%s%$_3*Au0su-~h8?dX+~()00bMZP6$!|Xke!OV-E7a0pm-tD99A3|M(67u4Dd7mT{gD&wRDQ-~mX%tSF#B}s}h!LyfCLeZJk_uz9F1*(iT8=5pFLGe%w zOh|*;_;qQbeD+wEBz`6W*jTd2+)xxe(1}f#PB-0)_(5|wv{pXuxPya1PC@Xns?Q)N z?8BgE2}3#+H=NIC0PaLA_eC5eHQ4RuE<;fyKaL=(W3>+LzZ*Lps@OgCJ&eFwUMg~A z>rl;=0A=Kbnawx4()y7IJ44D?Ia{i#By+IB`aNHTW{!}N9=vNkTU7m0hQE?75qs7H zk;~{*9S{u2L3{R6mt>rp ztW{gKTQwU2+1R^x^DU&hGpJVMKcNR-kyI z!cYX|ZhI`aIMoYdLL6+Uy`M&bFj5u$4*F^$1GhFbtA{o50Iyt2MtlcS^tLNxmpj1c z_YPnbBMDvpltbY_>8XsjqFOblV+tXy@ws{bv@ikO!6;|OH{hjoT_X-^CQ)nMgC-8! zzsIxSR4^m#!@xCe&Ff?j_pncgWr(assVrUbu?^5viAQ2N_ATIvZo=jYG3!_Jx zlz*_|w+sQl6N!M5>wj+z{y$f=EIrc}m0Ij%uV`SKua#C#~SU^F;fHz0lUdMnEOe zDNh$Es2ds~z&6Jys!nS5PbaiwNSOogy*kedx5JcNC+}4;$)nJfJ`qjLU+?^!g3QSG z(MDqbG(y?R+&|eE_Kil2ibb)1`F+~rcYaC#c@qb$^VRH^LwdU)gZ%oQhfK%7Kp1r< zm=~L{z+>dFR!On4p!GPD+cstrk3t|;vw3VTQfY}$b2T7S}1j9a(A!W;BGZ?S&H8*^8=4Gj|&q>$E~Cg1{@S>RJ0>FO(&cWG)1LBFU%>N=cxb^`-H_RH%5z_t`U30D0bz@#*xxqbpH| zhs~|b2)gx`0~u3J#P;kHJ(xp_dW} z4MQ;w1yV1j@Q)(^%_sl}WdYqdUJ0-eXD@lWM z3Tr5;8UbKL@nJlh^1j8&1SAsO5o=J4jV7gR%&$wd)_A!Ar)zx=V2my)@Qk_E9TfnH zd(A=;Z?Aj5)_x``r(A>ofHw453oZM6fdK(P#NOB);w1tka{htgF{!IGtVqjE?$psyQ6YMIT|?g4P5YP02%IM~8d&SecqkaFVm<;f zAY&VkX<7o+T~SIBWyk4xAM8Zz5UIRsCkN*K#oCwRd9vnqs;Gc?L4cJz*X;!Jp?B5o z8p6Xnou!x-8>4rd6X5O2?E=!(6AwbZ7-`wYP~6ql)|^DSZgpCiO2gJ z$LHL1S0Xg>Z0HICDx%V=#>1?`b9>48p0t~NQO{l`%8pr{H6*U@EfH92Ux7oBObzOhRqGEl=*?j>Y0715_Hyt)iP(sLW0es zs#>FQ**lan)kyvKFz$3--;HDY1dhYALkiW^xnJ{bCKA}4Jb&BT#uu@iU&4n9+o0)1 zy^vzN{&5iwv8m)+nFo*Rb!}-t6DUpQ7a26X+UgN3w2jh}`5s}MUEcy_J8?y<2!6ME0(;@hCH}DKOV<)L%aYeZRsU)Qu7lVJ z+R8y3`EBWbea?o!kh8CMbo-jAHlnZZ-MJsLFv;A}i3MQ%B;juu(}CqxqI=Zsu@F1w{$-(znO8Lppcf+auT~ zsk;um-On>UFAdU16lkZL-N<&9KbsZ?nJ&&>)=LjQWl}>rIRZ4Nv3MNqsuLJlwD3OUqLE@YI{Z z!ad%eB3mUBQRZBdP!vkvJj;xZ4NTrPw08V4lRe&M1hLNS$M3tk_H_^<6hY;X-7=1B zaDWm_63DOIkiW3L4jI^+$ft_b6UAQ*wqj1jMf~-S6S2)o45G-m z|5W1ECPJVy>ZbEwRep3DR5DLi8~kjunx&SP#(2y~vGy6X#)7EDY@+UWVcGVXAsX6p zK4y4tv(903buE+_LZ4X&W=GPUdiOK5G8kIL2yvQ$b5Rv3C-j_5fRN#OEIEq?m=UL# zBomuv8kG{tF0`y$=iBu}@s5WsTMJ3A$gK6A+#sK$dF3k>8RP4=v(aSC(*lu!iM_X0 z(!l?cK95_Hk;uz!=qIUbw{*Y4iN&q4K390r;+ zEysRRhyQFE;o)f{C9SvvDh>`>8-i-GpC}p;4$5HMc9R*p8+QX+<;mVidvAL+G zx|_tFjy?wMgp&N(oR!ShIKc_s{Va-P9ManU*Jdvo;#bdI-w{Wae|C(8H;;>Y1uMf~ z)9~~~JX^%o$= z=eYC%Vu!b(+`pM*vVT#$OG|dr8PPIXFd=0{i5yxb{v`m%+{%14Jds^lVxuydF|#Fc2rdoshM1T%m0Rb$g_2x!3$zrPt4^X zae{f%x*u2L88*_A+poi@61k!E!tKe$?dVSizyzuv>Q2FkfC?svp9s!S-~njO%-AzB zJ~iVd$^xh8%@b z260%ilu!JZBWP4l?goJ2=mUXB!AjBB14#amCZH->EQP7F^+}DN?tty>LewgoR_#Rx zEw;2xjT5U+mo5CVhcHGbyW4tWpf1J+oowa8DeIY`ZL(NTLsRH%+Ygo=@jz`sVNB5s zmd@V`d(QQG9!Dl;r;zli2i)dnO|w$qVqbrDz3yj%OL1C!#$78;f3fyZf9)x?ckGK; zEf4G^44FX{;n?9p(m4+$2=v3(%Ovc{*b-c((&-G|+ZmEhvBEbX6J0EMo9Hw^d#zl8ng!&5Gf`}Q&?1o&lj zaWLQ{qPSo)bF5f;1k7m?lZ_N_u-E7fnKT&6^8QcwNFrIj+SngQ0h|= zvXV7yoZVM{N{c4+^l<`7FdVkB|9sv6H_Qp6B%dhmRN~WQoP>x){Zph#<+{J~G)CwV z70i$VdAL@1N~&W0SYi>*fOVWt4Q3gclQJn)8He#IiUk3rNH_k&qSE!E%L0oQ3$Z9) z`u?VB%cG&K4JP>4X!iIUQA`H{u8}KHBe+z8cewzBuVtz#B)@OvHT19Q&^MMxOf||4 z(P!7@MOh=WN_lXW_Jf_9;ATai_dQujen;Mano<6{x+-=yrvLeVtx?yqTW0@P_o0_C z7Huwl#m)vuMMI??@B$>&LYExIeAF7C9ZD>;CGz#kGd4EMZjn9+^)GJoxqkNYu08sB z?(lE>y(t0u5vsH9E-Tv|I>T8djxs*X(e3{~F`J>+mm2u0EPp40Z$H+KyQp5uS*sSv zLgkMk_2^24YtqA?b`Q6YMK9M2pC|QXvt1TlBE?jxx_je9dc-Y{>z;dEyz}(CKz1Vo zkl;5O#!(tX$TUxKx%47?9NR=)eB{v%v^%8*t5x_sGq?;04N`uPV)H04&{)F0@+!mp zIh!>U6)V|U_G84P1P;$eN0-^cVQciGb+t3AwD4?+hIZjuI*A!p;7?LWSPB@bwg5Xr z5AEWoE@4mSF|G4LdS3UzSslCfe~3>+j@purBNjE@d^sgF6L7cf7Km^%Mj~C4Y~_6b z_AVP%!sj_Q0Q|nHszg_K-)q`%`))?)JXQzmh7a=*eLx3j_tC@ftI~o7Le*$Tx?xM$ ztsQk28wG5NfxByx>*ba5k3!ypjc3$wYNTJNvOzr8eDTw&Mo#Ds(Ql^TwOR`(k!1Z>MVl6)Ra$E(Z=yE#gO3V-Nv4zEbgF-Ih^5FT98%#29ma!O_FFxc7z=>>c}O zWK`uK1xQhn-U(UhpHGyxD?}0+f&uD$E6zX4Cnz8naQDtV0s~%ZF}8cQeeW~ADg)GJ z5%Y%JKMhc#1o?E|V4$yD$d$2{Zp;4bz-4*fSof3G!8swsyFhe%7nmM1BPhJ{V$$)}Jq& z^t7{vvKyAbzor;!j=w_v_|%*N^wO(#=hF0OX=`x1{hAZq;Bp!6Ka{yx(3r{=CzY## zE$M%O&RZ+133OnE{nsPT$iui%!U}#516!e-l9EOYI87Y#%cpg0%vjM+`q837*;)3Z z&NSj0Q&ub({aVTiC_(ZDI{1=7%K;*;;F4uL76Ge%IH#a` zrbg(UH@8hddv^~Bh3_o83+Zf}0pA-4Dr+h&jNs6U*&nN*KLmpaV6kAv0#j?yr|*N9 zMU!jU#zdWJ6=Y%SJ`Sj6Nkv+=y5hdXKw3of9?-aZEil`$gwxu&pm0rdui)&38Cn_8Nv6;9i0c+TGsu3O?f}2 zx&Z%hk>52}kh33!HMv`#fUHBvoMaCwszUjxX;Tx@=%_M+vd5oQPFrbaq$qqp!ZRY9**wF(0qX?H=67FfZQHChz_ z4dn-+Z%J)l55-c>^p9UEcl&eQ{dzquk#V!IkbWz3q(1vvIgz@M$lkQg_uoQdE&mbF z2Q`pU)S-H#Re_$tN88rytOL1b4y%uDXN~wHbz`sLNay#@Y|qM4CR@>S*FLj-{?Ep`jSssxXDd zDVZxv2AHNvr%dki~Jp zFmz}BFT5h+V7h2vnusbY=;Q;-0h%1oKw)5ev+||Ru&7>TNS~);MeMA}s5##Y1_f^R z=xCKOJW`Q#wXtvF!2=wC*zD(`2)ZEv>TG6%TG5Hr#v`99 ziQBm$bSXtoB0d}pw$P`@^IHg=8pqeE;5~$uz?+|?Yb)+pk$aC;S!zwWXc!s|@{B-H zi=nkuHkD6YoE*ciVT5R&@-tQA0L+TCDf6!%?|L%4`&%*vc zb@^IDBkup&qVBX#TxY^jTu3YeTE!z#Xy%RfT%!c7oYo{=*pst&Z03J=G2uuO8d=AL zpg`K&Pg<|4ye{0pGj~$|CHE}HVCZn0w1N7f zM-mR)ddHp_;A6qN_>J^1PAMP_KGFgV?#?;n{-hlT-eV98tIG8?pw!N>n>ph1yB(;C z>|H)wtWzCwCp8x>1e#+v&o-!bZZ86ySE#I|*a$hV)u6g>t%e!tv9h@$bKPE!oQ>|- z=QgQ#lG@fy1b**kuEv0X(IzU~{fS&za^7)m1!a(cwOd+HT1}sKqd}O^w+hbjdJ5vk z2n_STfGc8zikWthR~|F4UGUNv2WgwtaMYb%9Dn{p???h)M6wrh%$5G+1Adfy>+kQ4 z{?QwBZ&*5n`NFiGHEQ?TkDz{Q!SE5Gjp>+bQcD#vbO$GvKz~c0xs5f|t`rDs;XT15 zv(*>obahe5!r4E$)wnlzcs@XWKHf4nOL68f9+W7;h?$r>u1+2;m^i@_Tpd3EZ?p8= zNuK3`k|{22GXE@6XK4~fJ*7s4cCvA?Y9HvFqAZCosjW z!x$5GEV8)T6fZ}OMSHq(x;(_;9n{Qa!~Lxe)=aIWFaPo!Ndt{x_&LCG!@u zNJiB8&3M2Udvh+p4n+_;aDKWfxxg5j;QvcmiW_R3S#gwmdbhNV?pC=F4u4x2e7#ec0qLw4;=gG z!DfYHqH~cBg_-J|s(^VF*af<{efv8ht+fynj~&$)>Bv+zjYMNN`)A^k7DpS|{nuj% zc=9%vjaPu?0{{jbQ?VkQ%^~RcZ=2YO*HfJBiycK)i3i9e4h_xO#;5pPTqMZ+4$*|r z`dc(7*Ksg2f#YsvEqZg9a_nsTPAZh^ZKSpj8*LFr5#C0T+suOsmbG8M=%Y6>zojG^FrSP7wbS)Q$b}si1 z)xS%7<+L|HK!qXKr?afbY9cDkTF<3VZ3`ncD*3Nu)$XUwxr{eC;$6Kf7lquHeW$AA zR7>mzVQjYryA2edaI4+TR=t@PHUhI1{~)oJ^eipC%NM8WsGdt{>KFFo?FUkpeHj%| z%J7xYhj_S1zw>%H-V-d+x;V05pnu1Rw*J7O_w+edt=PCRlwb8pVat{&|4s^*-c$cM zOm_;;4Ry7IKJAYTjEXF2xx+G+!0m2-G0(0H+9|lu?`qzjehw_i*&)}rzMt>dsYmB4 zvN;*(1XuecZ}qPlk}eKDE0A&773n3y=z2c;tyD#xqO>80W7D!saPGPY{Ma%<8= zW8&aHDtQWjwPNns5U6I}kv~i*S~bcAdzYaJHBgD6#h2_RvSfWpPJYawz!B*Lubs%9 zVSg|Vwe05|Wu{kfb|-_GT~7r)QOboy=j3kT2Mo0=+^mQs^$s1rT->H2YGEKPvobEG zE$8}x*zA=9bC5nfbN1@Sfoj1jutXw{xdS4MY(+!pZ*TE%eG+ar$qjmTph_^5HxGA; z97emXh@ZrdTRzmbj`kc$m%MIHR8J7D=;$I+ww18jdngvI1DbB$`6D4>K~T7n8nKz>LaLwZbe{69f3| z@qu+f6~&o#1^}e$g7dyvG(p4?CAE-e>_(MqSh21;nmv}F2=x7`UqDg=XUXM37(WHm z2~CD5_FIb@LT0}<_g`jI8%H%X)mCEWvP`#rc?nU-Pl4rO+D>7M659}m=q7is>w0J+ z0i%$5>*7r&M&3{27NesM5a+#qy6)obNWYamun)a{EpCL~`-?>kt%1}LOK&21yej>c zVoe=I+H$Z){kQ>iRw}2bz)lLDZO=N05YRRbQZwb2%ap(XdM%C`A~X-hxwt=G%d;59 zfuRK@gFfIX29i(^n2x?t{2<@b5WmnkR4^PdI^*8j?4$3*|X2MR2iq~g}+T)lw= z+AfoM^m=T)#73nFl9S18Mh^OB)6C#djeMT2_h;Y5By)iw{<+vA$rP)yRsm1$9=RTP ziZ_&D0g&HA{DM1l&=HEaC7rvSIPP$wL=g@9SBNFAZ^EFiA-N1tGF7)4+glEvolo}osH$4HrqwnoXMdAMRs?p)>B1Qs?aL{GK^i6kq$~BwabeCjrg7#8X2nQ7mRyfKbw)7hI~ zz*esox{6^fc!E;_5dPLg?rw^?(K1trSrywV7gQf4opsO1RjSos*Sn4h9kHd!7&U9H@~iW4PO5;~yNGcJbChgDyXi zH+R|Xa^VQ)N{IMmJ;c$E7?SuuvP#Gku!Pz^RV z?G?$j>bsMf^l-E}#mT6!Y>w-t8h@(M(@NI-Dp1x6myyL`?LkP=h04W<xM$*eEd~Rx6pg!NP_|m9j zxtjg}#lhL0wDqp!Qp>kCqX2N)(Csj2{?xbkdo{xG3cx>Iq!z(6AfFP0J`IC*j|6Q` z&HeR7gC${T0q6i74-7Vr$VDYi=!Z>c7vv5LNCHuH#?Py>7Z==sfyM^<1O_lFz0n!vTQfYeO2R6c zEhlVq(nopk;g(E=Xfr>?0SA3}j2MZPZk|y#g!} zv~uo)GF7NtigR;zt)^BQyrgj5Zfdx|X(2B=BZ0pvxmh0Yu2TBd#5{;ZAV%u|LfM6^ zjNz3~da$FAu}K+fy_;;RD+n6|hJu$h=1~~HX7&S3(ITDgMa^_Wxa-}S2m=?Z{Wn%> zD^(qLRK4i09yNT0MZr~^dh4LO8ZHXfA7NP!_O~APjvZig|fp z(2p%Ja2mL^0>A_=MgZtUz&LvEX)ll`D%?DXdRg79L?qEN6;c=(%D$>pev2&rR`>zI znMDFS_}W!#xpW_61U7;RgZ;jW_XpnWxZ&iz&IIV&PhmAx;9(yW5$Fmu-#WojX;+UCnys#N!Cw1QG+eyHX8J*Y*aR!TC z_|F9&;rC}+&?3Xw!Q?w;eZepp*i;?F_ivU2XiRcMO?CxWE$wekyzOk_X*8}W#x)wd zq^tY%;=l7q#ufGra?{RAHd6CJiLE5%VOUZ7^VxWmQAV3@Mx=R5D*ep_IS+sX`~&ui ziBNPIcUykgU4FFAI-R}`otI~0jZ}Sc;Q$Rv_8HC$LK9C9buL2v!G|?Ap>KaSVW1hr zs@pId-`Z@$w#CnCvc5!H?d-zpTU;UZEW+9$?scI&y|_Rq(e{oRzNHVVN_%jbdb8T6 zIqu=`4q|kBb8y*77mhIy!M<*K-^bgVgxx~l9hmS=#Zodt?X#jTOf$|Y
    (G_CB-{tQnzhgbH@_DuvGcHqL0Xm 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. +% +% GLPK is free software: you can redistribute it and/or modify it +% under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% GLPK is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +% License for more details. +% +% You should have received a copy of the GNU General Public License +% along with GLPK. If not, see . +%*********************************************************************** + +\documentclass[11pt]{report} +\usepackage{amssymb} +\usepackage[dvipdfm,linktocpage,colorlinks,linkcolor=blue, +urlcolor=blue]{hyperref} +\usepackage{indentfirst} + +\setlength{\textwidth}{6.5in} +\setlength{\textheight}{8.5in} +\setlength{\oddsidemargin}{0in} +\setlength{\topmargin}{0in} +\setlength{\headheight}{0in} +\setlength{\headsep}{0in} +\setlength{\footskip}{0.5in} +\setlength{\parindent}{16pt} +\setlength{\parskip}{5pt} +\setlength{\topsep}{0pt} +\setlength{\partopsep}{0pt} +\setlength{\itemsep}{\parskip} +\setlength{\parsep}{0pt} +\setlength{\leftmargini}{\parindent} +\renewcommand{\labelitemi}{---} + +\def\para#1{\noindent{\bf#1}} + +\renewcommand\contentsname{\sf\bfseries Contents} +\renewcommand\chaptername{\sf\bfseries Chapter} +\renewcommand\appendixname{\sf\bfseries Appendix} + +\begin{document} + +\thispagestyle{empty} + +\begin{center} + +\vspace*{1.5in} + +\begin{huge} +\sf\bfseries Modeling Language GNU MathProg +\end{huge} + +\vspace{0.5in} + +\begin{LARGE} +\sf Language Reference +\end{LARGE} + +\vspace{0.5in} + +\begin{LARGE} +\sf for GLPK Version 4.57 +\end{LARGE} + +\vspace{0.5in} +\begin{Large} +\sf (DRAFT, October 2015) +\end{Large} + +\end{center} + +\newpage + +\vspace*{1in} + +\vfill + +\noindent +The GLPK package is part of the GNU Project released under the aegis of +GNU. + +\noindent +Copyright \copyright{} 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, +2008, 2009, 2010, 2011, 2013, 2014, 2015 Andrew Makhorin, Department +for Applied Informatics, Moscow Aviation Institute, Moscow, Russia. All +rights reserved. + +\noindent +Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +MA 02110-1301, USA. + +\noindent +Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + +\noindent +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that +the entire resulting derived work is distributed under the terms of +a permission notice identical to this one. + +\noindent +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +{\setlength{\parskip}{0pt} +\tableofcontents +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Introduction} + +{\it GNU MathProg} is a modeling language intended for describing +linear mathematical programming models.\footnote{The GNU MathProg +language is a subset of the AMPL language. Its GLPK implementation is +mainly based on the paper: {\it Robert Fourer}, {\it David M. Gay}, and +{\it Brian W. Kernighan}, ``A Modeling Language for Mathematical +Programming.'' {\it Management Science} 36 (1990), pp.~519-54.} + +Model descriptions written in the GNU MathProg language consist of +a set of statements and data blocks constructed by the user from the +language elements described in this document. + +In a process called {\it translation}, a program called the {\it model +translator} analyzes the model description and translates it into +internal data structures, which may be then used either for generating +mathematical programming problem instance or directly by a program +called the {\it solver} to obtain numeric solution of the problem. + +\section{Linear programming problem} +\label{problem} + +In MathProg the linear programming (LP) problem is stated as follows: + +\medskip + +\noindent\hspace{1in}minimize (or maximize) +$$z=c_1x_1+c_2x_2+\dots+c_nx_n+c_0\eqno(1.1)$$ +\noindent\hspace{1in}subject to linear constraints +$$ +\begin{array}{l@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }l} +L_1&\leq&a_{11}x_1&+&a_{12}x_2&+\dots+&a_{1n}x_n&\leq&U_1\\ +L_2&\leq&a_{21}x_1&+&a_{22}x_2&+\dots+&a_{2n}x_n&\leq&U_2\\ +\multicolumn{9}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\ +L_m&\leq&a_{m1}x_1&+&a_{m2}x_2&+\dots+&a_{mn}x_n&\leq&U_m\\ +\end{array}\eqno(1.2) +$$ +\noindent\hspace{1in}and bounds of variables +$$ +\begin{array}{l@{\ }c@{\ }c@{\ }c@{\ }l} +l_1&\leq&x_1&\leq&u_1\\ +l_2&\leq&x_2&\leq&u_2\\ +\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .}\\ +l_n&\leq&x_n&\leq&u_n\\ +\end{array}\eqno(1.3) +$$ + +\newpage + +\noindent +where $x_1$, $x_2$, \dots, $x_n$ are variables; $z$ is the objective +function; $c_1$, $c_2$, \dots, $c_n$ are objective coefficients; $c_0$ +is the constant term (``shift'') of the objective function; $a_{11}$, +$a_{12}$, \dots, $a_{mn}$ are constraint coefficients; $L_1$, $L_2$, +\dots, $L_m$ are lower constraint bounds; $U_1$, $U_2$, \dots, $U_m$ +are upper constraint bounds; $l_1$, $l_2$, \dots, $l_n$ are lower +bounds of variables; $u_1$, $u_2$, \dots, $u_n$ are upper bounds of +variables. + +Bounds of variables and constraint bounds can be finite as well as +infinite. Besides, lower bounds can be equal to corresponding upper +bounds. Thus, the following types of variables and constraints are +allowed: + +\medskip + +{\def\arraystretch{1.4} +\noindent\hspace{54pt} +\begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }l@{\hspace*{39.5pt}}l} +$-\infty$&$<$&$x$&$<$&$+\infty$&Free (unbounded) variable\\ +$l$&$\leq$&$x$&$<$&$+\infty$&Variable with lower bound\\ +$-\infty$&$<$&$x$&$\leq$&$u$&Variable with upper bound\\ +$l$&$\leq$&$x$&$\leq$&$u$&Double-bounded variable\\ +$l$&$=$&$x$&=&$u$&Fixed variable\\ +\end{tabular} + +\noindent\hfil +\begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }ll} +$-\infty$&$<$&$\sum a_jx_j$&$<$&$+\infty$&Free (unbounded) linear +form\\ +$L$&$\leq$&$\sum a_jx_j$&$<$&$+\infty$&Inequality constraint ``greater +than or equal to''\\ +$-\infty$&$<$&$\sum a_jx_j$&$\leq$&$U$&Inequality constraint ``less +than or equal to''\\ +$L$&$\leq$&$\sum a_jx_j$&$\leq$&$U$&Double-bounded inequality +constraint\\ +$L$&$=$&$\sum a_jx_j$&=&$U$&Equality constraint\\ +\end{tabular} +} + +\medskip + +In addition to pure LP problems MathProg also allows mixed integer +linear programming (MIP) problems, where some or all variables are +restricted to be integer or binary. + +\section{Model objects} + +In MathProg the model is described in terms of sets, parameters, +variables, constraints, and objectives, which are called {\it model +objects}. + +The user introduces particular model objects using the language +statements. Each model object is provided with a symbolic name which +uniquely identifies the object and is intended for referencing +purposes. + +Model objects, including sets, can be multidimensional arrays built +over indexing sets. Formally, $n$-dimensional array $A$ is the mapping: +$$A:\Delta\rightarrow\Xi,\eqno(1.4)$$ +where $\Delta\subseteq S_1\times\dots\times S_n$ is a subset of the +Cartesian product of indexing sets, $\Xi$ is a set of array members. +In MathProg the set $\Delta$ is called the {\it subscript domain}. Its +members are $n$-tuples $(i_1,\dots,i_n)$, where $i_1\in S_1$, \dots, +$i_n\in S_n$. + +If $n=0$, the Cartesian product above has exactly one member (namely, +0-tuple), so it is convenient to think scalar objects as 0-dimensional +arrays having one member. + +\newpage + +The type of array members is determined by the type of corresponding +model object as follows: + +\medskip + +\noindent\hfil +\begin{tabular}{@{}ll@{}} +Model object&Array member\\ +\hline +Set&Elemental plain set\\ +Parameter&Number or symbol\\ +Variable&Elemental variable\\ +Constraint&Elemental constraint\\ +Objective&Elemental objective\\ +\end{tabular} + +\medskip + +In order to refer to a particular object member the object should be +provided with {\it subscripts}. For example, if $a$ is a 2-dimensional +parameter defined over $I\times J$, a reference to its particular +member can be written as $a[i,j]$, where $i\in I$ and $j\in J$. It is +understood that scalar objects being 0-dimensional need no subscripts. + +\section{Structure of model description} + +It is sometimes desirable to write a model which, at various points, +may require different data for each problem instance to be solved using +that model. For this reason in MathProg the model description consists +of two parts: the {\it model section} and the {\it data section}. + +The model section is a main part of the model description that contains +declarations of model objects and is common for all problems based on +the corresponding model. + +The data section is an optional part of the model description that +contains data specific for a particular problem instance. + +Depending on what is more convenient the model and data sections can be +placed either in one file or in two separate files. The latter feature +allows having arbitrary number of different data sections to be used +with the same model section. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Coding model description} +\label{coding} + +The model description is coded in a plain text format using ASCII +character set. Characters valid in the model description are the +following: + +\begin{itemize} +\item alphabetic characters:\\ +\verb|A B C D E F G H I J K L M N O P Q R S T U V W X Y Z|\\ +\verb|a b c d e f g h i j k l m n o p q r s t u v w x y z _| +\item numeric characters:\\ +\verb|0 1 2 3 4 5 6 7 8 9| +\item special characters:\\ +\verb?! " # & ' ( ) * + , - . / : ; < = > [ ] ^ { | } ~? +\item white-space characters:\\ +\verb|SP HT CR NL VT FF| +\end{itemize} + +Within string literals and comments any ASCII characters (except +control characters) are valid. + +White-space characters are non-significant. They can be used freely +between lexical units to improve readability of the model description. +They are also used to separate lexical units from each other if there +is no other way to do that. + +Syntactically model description is a sequence of lexical units in the +following categories: + +\begin{itemize} +\item symbolic names; +\item numeric literals; +\item string literals; +\item keywords; +\item delimiters; +\item comments. +\end{itemize} + +The lexical units of the language are discussed below. + +\newpage + +\section{Symbolic names} + +A {\it symbolic name} consists of alphabetic and numeric characters, +the first of which should be alphabetic. All symbolic names are +distinct (case sensitive). + +\para{Examples} + +\begin{verbatim} +alpha123 +This_is_a_name +_P123_abc_321 +\end{verbatim} + +Symbolic names are used to identify model objects (sets, parameters, +variables, constraints, objectives) and dummy indices. + +All symbolic names (except names of dummy indices) should be unique, +i.e. the model description should have no objects with identical names. +Symbolic names of dummy indices should be unique within the scope, +where they are valid. + +\section{Numeric literals} + +A {\it numeric literal} has the form {\it xx}{\tt E}{\it syy}, where +{\it xx} is a number with optional decimal point, {\it s} is the sign +{\tt+} or {\tt-}, {\it yy} is a decimal exponent. The letter {\tt E} is +case insensitive and can be coded as {\tt e}. + +\para{Examples} + +\begin{verbatim} +123 +3.14159 +56.E+5 +.78 +123.456e-7 +\end{verbatim} + +Numeric literals are used to represent numeric quantities. They have +obvious fixed meaning. + +\section{String literals} + +A {\it string literal} is a sequence of arbitrary characters enclosed +either in single quotes or in double quotes. Both these forms are +equivalent. + +If a single quote is part of a string literal enclosed in single +quotes, it should be coded twice. Analogously, if a double quote is +part of a string literal enclosed in double quotes, it should be coded +twice. + +\para{Examples} + +\begin{verbatim} +'This is a string' +"This is another string" +'That''s all' +"""Hello there,"" said the captain." +\end{verbatim} + +String literals are used to represent symbolic quantities. + +\section{Keywords} + +A {\it keyword} is a sequence of alphabetic characters and possibly +some special characters. + +All keywords fall into two categories: {\it reserved keywords}, which +cannot be used as symbolic names, and {\it non-reserved keywords}, +which are recognized by context and therefore can be used as symbolic +names. + +The reserved keywords are the following: + +\noindent\hfil +\begin{tabular}{@{}p{.7in}p{.7in}p{.7in}p{.7in}@{}} +{\tt and}&{\tt else}&{\tt mod}&{\tt union}\\ +{\tt by}&{\tt if}&{\tt not}&{\tt within}\\ +{\tt cross}&{\tt in}&{\tt or}\\ +{\tt diff}&{\tt inter}&{\tt symdiff}\\ +{\tt div}&{\tt less}&{\tt then}\\ +\end{tabular} + +Non-reserved keywords are described in following sections. + +All the keywords have fixed meaning, which will be explained on +discussion of corresponding syntactic constructions, where the keywords +are used. + +\section{Delimiters} + +A {\it delimiter} is either a single special character or a sequence of +two special characters as follows: + +\noindent\hfil +\begin{tabular}{@{}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in} +p{.3in}p{.3in}@{}} +{\tt+}&{\tt**}&{\tt<=}&{\tt>}&{\tt\&\&}&{\tt:}&{\tt|}&{\tt[}& +{\tt>>}\\ +{\tt-}&{\tt\textasciicircum}&{\tt=}&{\tt<>}&{\tt||}&{\tt;}& +{\tt\char126}&{\tt]}&{\tt<-}\\ +{\tt*}&{\tt\&}&{\tt==}&{\tt!=}&{\tt.}&{\tt:=}&{\tt(}&{\tt\{}\\ +{\tt/}&{\tt<}&{\tt>=}&{\tt!}&{\tt,}&{\tt..}&{\tt)}&{\tt\}}\\ +\end{tabular} + +If the delimiter consists of two characters, there should be no spaces +between the characters. + +All the delimiters have fixed meaning, which will be explained on +discussion corresponding syntactic constructions, where the delimiters +are used. + +\section{Comments} + +For documenting purposes the model description can be provided with +{\it comments}, which may have two different forms. The first form is +a {\it single-line comment}, which begins with the character {\tt\#} +and extends until end of line. The second form is a {\it comment +sequence}, which is a sequence of any characters enclosed within +{\tt/*} and {\tt*/}. + +\para{Examples} + +\begin{verbatim} +param n := 10; # This is a comment +/* This is another comment */ +\end{verbatim} + +Comments are ignored by the model translator and can appear anywhere in +the model description, where white-space characters are allowed. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\chapter{Expressions} + +An {\it expression} is a rule for computing a value. In model +description expressions are used as constituents of certain statements. + +In general case expressions consist of operands and operators. + +Depending on the type of the resultant value all expressions fall into +the following categories: + +\vspace*{-8pt} + +\begin{itemize} +\item numeric expressions; +\item symbolic expressions; +\item indexing expressions; +\item set expressions; +\item logical expressions; +\item linear expressions. +\end{itemize} + +\vspace*{-8pt} + +\section{Numeric expressions} + +A {\it numeric expression} is a rule for computing a single numeric +value represented as a floating-point number. + +The primary numeric expression may be a numeric literal, dummy index, +unsubscripted parameter, subscripted parameter, built-in function +reference, iterated numeric expression, conditional numeric expression, +or another numeric expression enclosed in parentheses. + +\para{Examples} + +\noindent +\begin{tabular}{@{}ll@{}} +\verb|1.23 |&(numeric literal)\\ +\verb|j|&(dummy index)\\ +\verb|time|&(unsubscripted parameter)\\ +\verb|a['May 2003',j+1]|&(subscripted parameter)\\ +\verb|abs(b[i,j])|&(function reference)\\ +\end{tabular} + +\newpage + +\noindent +\begin{tabular}{@{}ll@{}} +\verb|sum{i in S diff T} alpha[i] * b[i,j]|&(iterated expression)\\ +\verb|if i in I then 2 * p else q[i+1]|&(conditional expression)\\ +\verb|(b[i,j] + .5 * c)|&(parenthesized expression)\\ +\end{tabular} + +More general numeric expressions containing two or more primary numeric +expressions may be constructed by using certain arithmetic operators. + +\para{Examples} + +\begin{verbatim} +j+1 +2 * a[i-1,j+1] - b[i,j] +sum{j in J} a[i,j] * x[j] + sum{k in K} b[i,k] * x[k] +(if i in I and p >= 1 then 2 * p else q[i+1]) / (a[i,j] + 1.5) +\end{verbatim} + +\subsection{Numeric literals} + +If the primary numeric expression is a numeric literal, the resultant +value is obvious. + +\subsection{Dummy indices} + +If the primary numeric expression is a dummy index, the resultant value +is current value assigned to that dummy index. + +\subsection{Unsubscripted parameters} + +If the primary numeric expression is an unsubscripted parameter (which +should be 0-dimen\-sional), the resultant value is the value of that +parameter. + +\subsection{Subscripted parameters} + +The primary numeric expression, which refers to a subscripted +parameter, has the following syntactic form: +$$ +\mbox{{\it name}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,} $i_n${\tt]}} +$$ +where {\it name} is the symbolic name of the parameter, $i_1$, $i_2$, +\dots, $i_n$ are subscripts. + +Each subscript should be a numeric or symbolic expression. The number +of subscripts in the subscript list should be the same as the dimension +of the parameter with which the subscript list is associated. + +Actual values of subscript expressions are used to identify +a particular member of the parameter that determines the resultant +value of the primary expression. + +\newpage + +\subsection{Function references} + +In MathProg there exist the following built-in functions which may be +used in numeric expressions: + +\begin{tabular}{@{}p{112pt}p{328pt}@{}} +{\tt abs(}$x${\tt)}&$|x|$, absolute value of $x$\\ +{\tt atan(}$x${\tt)}&$\arctan x$, principal value of the arc tangent of +$x$ (in radians)\\ +{\tt atan(}$y${\tt,} $x${\tt)}&$\arctan y/x$, principal value of the +arc tangent of $y/x$ (in radians). In this case the signs of both +arguments $y$ and $x$ are used to determine the quadrant of the +resultant value\\ +{\tt card(}$X${\tt)}&$|X|$, cardinality (the number of elements) of +set $X$\\ +{\tt ceil(}$x${\tt)}&$\lceil x\rceil$, smallest integer not less than +$x$ (``ceiling of $x$'')\\ +{\tt cos(}$x${\tt)}&$\cos x$, cosine of $x$ (in radians)\\ +{\tt exp(}$x${\tt)}&$e^x$, base-$e$ exponential of $x$\\ +{\tt floor(}$x${\tt)}&$\lfloor x\rfloor$, largest integer not greater +than $x$ (``floor of $x$'')\\ +{\tt gmtime()}&the number of seconds elapsed since 00:00:00~Jan~1, 1970, +Coordinated Universal Time (for details see Section \ref{gmtime}, +page \pageref{gmtime})\\ +{\tt length(}$s${\tt)}&$|s|$, length of character string $s$\\ +{\tt log(}$x${\tt)}&$\log x$, natural logarithm of $x$\\ +{\tt log10(}$x${\tt)}&$\log_{10}x$, common (decimal) logarithm of $x$\\ +{\tt max(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&the largest +of values $x_1$, $x_2$, \dots, $x_n$\\ +{\tt min(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&the smallest +of values $x_1$, $x_2$, \dots, $x_n$\\ +{\tt round(}$x${\tt)}&rounding $x$ to nearest integer\\ +{\tt round(}$x${\tt,} $n${\tt)}&rounding $x$ to $n$ fractional decimal +digits\\ +{\tt sin(}$x${\tt)}&$\sin x$, sine of $x$ (in radians)\\ +{\tt sqrt(}$x${\tt)}&$\sqrt{x}$, non-negative square root of $x$\\ +{\tt str2time(}$s${\tt,} $f${\tt)}&converting character string $s$ to +calendar time (for details see Section \ref{str2time}, page +\pageref{str2time})\\ +{\tt trunc(}$x${\tt)}&truncating $x$ to nearest integer\\ +{\tt trunc(}$x${\tt,} $n${\tt)}&truncating $x$ to $n$ fractional +decimal digits\\ +{\tt Irand224()}&generating pseudo-random integer uniformly distributed +in $[0,2^{24})$\\ +{\tt Uniform01()}&generating pseudo-random number uniformly distributed +in $[0,1)$\\ +{\tt Uniform(}$a${\tt,} $b${\tt)}&generating pseudo-random number +uniformly distributed in $[a,b)$\\ +{\tt Normal01()}&generating Gaussian pseudo-random variate with +$\mu=0$ and $\sigma=1$\\ +{\tt Normal(}$\mu${\tt,} $\sigma${\tt)}&generating Gaussian +pseudo-random variate with given $\mu$ and $\sigma$\\ +\end{tabular} + +Arguments of all built-in functions, except {\tt card}, {\tt length}, +and {\tt str2time}, should be numeric expressions. The argument of +{\tt card} should be a set expression. The argument of {\tt length} and +both arguments of {\tt str2time} should be symbolic expressions. + +The resultant value of the numeric expression, which is a function +reference, is the result of applying the function to its argument(s). + +Note that each pseudo-random generator function has a latent argument +(i.e. some internal state), which is changed whenever the function has +been applied. Thus, if the function is applied repeatedly even to +identical arguments, due to the side effect different resultant values +are always produced. + +\newpage + +\subsection{Iterated expressions} +\label{itexpr} + +An {\it iterated numeric expression} is a primary numeric expression, +which has the following syntactic form: +$$\mbox{\it iterated-operator indexing-expression integrand}$$ +where {\it iterated-operator} is the symbolic name of the iterated +operator to be performed (see below), {\it indexing-expression} is an +indexing expression which introduces dummy indices and controls +iterating, {\it integrand} is a numeric expression that participates in +the operation. + +In MathProg there exist four iterated operators, which may be used in +numeric expressions: + +{\def\arraystretch{2} +\noindent\hfil +\begin{tabular}{@{}lll@{}} +{\tt sum}&summation&$\displaystyle\sum_{(i_1,\dots,i_n)\in\Delta} +f(i_1,\dots,i_n)$\\ +{\tt prod}&production&$\displaystyle\prod_{(i_1,\dots,i_n)\in\Delta} +f(i_1,\dots,i_n)$\\ +{\tt min}&minimum&$\displaystyle\min_{(i_1,\dots,i_n)\in\Delta} +f(i_1,\dots,i_n)$\\ +{\tt max}&maximum&$\displaystyle\max_{(i_1,\dots,i_n)\in\Delta} +f(i_1,\dots,i_n)$\\ +\end{tabular} +} + +\noindent where $i_1$, \dots, $i_n$ are dummy indices introduced in +the indexing expression, $\Delta$ is the domain, a set of $n$-tuples +specified by the indexing expression which defines particular values +assigned to the dummy indices on performing the iterated operation, +$f(i_1,\dots,i_n)$ is the integrand, a numeric expression whose +resultant value depends on the dummy indices. + +The resultant value of an iterated numeric expression is the result of +applying of the iterated operator to its integrand over all $n$-tuples +contained in the domain. + +\subsection{Conditional expressions} +\label{ifthen} + +A {\it conditional numeric expression} is a primary numeric expression, +which has one of the following two syntactic forms: +$$ +{\def\arraystretch{1.4} +\begin{array}{l} +\mbox{{\tt if} $b$ {\tt then} $x$ {\tt else} $y$}\\ +\mbox{{\tt if} $b$ {\tt then} $x$}\\ +\end{array} +} +$$ +where $b$ is an logical expression, $x$ and $y$ are numeric +expressions. + +The resultant value of the conditional expression depends on the value +of the logical expression that follows the keyword {\tt if}. If it +takes on the value {\it true}, the value of the conditional expression +is the value of the expression that follows the keyword {\tt then}. +Otherwise, if the logical expression takes on the value {\it false}, +the value of the conditional expression is the value of the expression +that follows the keyword {\it else}. If the second, reduced form of the +conditional expression is used and the logical expression takes on the +value {\it false}, the resultant value of the conditional expression is +zero. + +\newpage + +\subsection{Parenthesized expressions} + +Any numeric expression may be enclosed in parentheses that +syntactically makes it a primary numeric expression. + +Parentheses may be used in numeric expressions, as in algebra, to +specify the desired order in which operations are to be performed. +Where parentheses are used, the expression within the parentheses is +evaluated before the resultant value is used. + +The resultant value of the parenthesized expression is the same as the +value of the expression enclosed within parentheses. + +\subsection{Arithmetic operators} + +In MathProg there exist the following arithmetic operators, which may +be used in numeric expressions: + +\begin{tabular}{@{}ll@{}} +{\tt +} $x$&unary plus\\ +{\tt -} $x$&unary minus\\ +$x$ {\tt +} $y$&addition\\ +$x$ {\tt -} $y$&subtraction\\ +$x$ {\tt less} $y$&positive difference (if $x1$, the second form should be used. + +If the first form of the indexing entry is used, the index $i$ can be +a dummy index only (see below). If the second form is used, the indices +$i_1$, $i_2$, \dots, $i_n$ can be either dummy indices or some numeric +or symbolic expressions, where at least one index should be a dummy +index. The third, reduced form of the indexing entry has the same +effect as if there were $i$ (if $S$ is 1-dimensional) or +$i_1$, $i_2$, \dots, $i_n$ (if $S$ is $n$-dimensional) all specified as +dummy indices. + +A {\it dummy index} is an auxiliary model object, which acts like an +individual variable. Values assigned to dummy indices are components of +$n$-tuples from basic sets, i.e. some numeric and symbolic quantities. + +For referencing purposes dummy indices can be provided with symbolic +names. However, unlike other model objects (sets, parameters, etc.) +dummy indices need not be explicitly declared. Each {\it undeclared} +symbolic name being used in the indexing position of an indexing entry +is recognized as the symbolic name of corresponding dummy index. + +Symbolic names of dummy indices are valid only within the scope of the +indexing expression, where the dummy indices were introduced. Beyond +the scope the dummy indices are completely inaccessible, so the same +symbolic names may be used for other purposes, in particular, to +represent dummy indices in other indexing expressions. + +The scope of indexing expression, where implicit declarations of dummy +indices are valid, depends on the context, in which the indexing +expression is used: + +\vspace*{-8pt} + +\begin{itemize} +\item If the indexing expression is used in iterated operator, its +scope extends until the end of the integrand. +\item If the indexing expression is used as a primary set expression, +its scope extends until the end of that indexing expression. +\item If the indexing expression is used to define the subscript domain +in declarations of some model objects, its scope extends until the end +of the corresponding statement. +\end{itemize} + +\vspace*{-8pt} + +The indexing mechanism implemented by means of indexing expressions is +best explained by some examples discussed below. + +Let there be given three sets: +$$ +{\def\arraystretch{1.4} +\begin{array}{l} +A=\{4,7,9\},\\ +B=\{(1,Jan),(1,Feb),(2,Mar),(2,Apr),(3,May),(3,Jun)\},\\ +C=\{a,b,c\},\\ +\end{array} +} +$$ +where $A$ and $C$ consist of 1-tuples (singlets), $B$ consists of +2-tuples (doublets). Consider the following indexing expression: +$$\mbox{{\tt\{i in A, (j,k) in B, l in C\}}}$$ +where {\tt i}, {\tt j}, {\tt k}, and {\tt l} are dummy indices. + +\newpage + +Although MathProg is not a procedural language, for any indexing +expression an equivalent algorithmic description can be given. In +particular, the algorithmic description of the indexing expression +above could look like follows: + +\noindent\hfil +\begin{tabular}{@{}l@{}} +{\bf for all} $i\in A$ {\bf do}\\ +\hspace{16pt}{\bf for all} $(j,k)\in B$ {\bf do}\\ +\hspace{32pt}{\bf for all} $l\in C$ {\bf do}\\ +\hspace{48pt}{\it action};\\ +\end{tabular} + +\noindent where the dummy indices $i$, $j$, $k$, $l$ are consecutively +assigned corresponding components of $n$-tuples from the basic sets $A$, +$B$, $C$, and {\it action} is some action that depends on the context, +where the indexing expression is used. For example, if the action were +printing current values of dummy indices, the printout would look like +follows: + +\noindent\hfil +\begin{tabular}{@{}llll@{}} +$i=4$&$j=1$&$k=Jan$&$l=a$\\ +$i=4$&$j=1$&$k=Jan$&$l=b$\\ +$i=4$&$j=1$&$k=Jan$&$l=c$\\ +$i=4$&$j=1$&$k=Feb$&$l=a$\\ +$i=4$&$j=1$&$k=Feb$&$l=b$\\ +\multicolumn{4}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\ +$i=9$&$j=3$&$k=Jun$&$l=b$\\ +$i=9$&$j=3$&$k=Jun$&$l=c$\\ +\end{tabular} + +Let the example indexing expression be used in the following iterated +operation: +$$\mbox{{\tt sum\{i in A, (j,k) in B, l in C\} p[i,j,k,l]}}$$ +where {\tt p} is a 4-dimensional numeric parameter or some numeric +expression whose resultant value depends on {\tt i}, {\tt j}, {\tt k}, +and {\tt l}. In this case the action is summation, so the resultant +value of the primary numeric expression is: +$$\sum_{i\in A,(j,k)\in B,l\in C}(p_{ijkl}).$$ + +Now let the example indexing expression be used as a primary set +expression. In this case the action is gathering all 4-tuples +(quadruplets) of the form $(i,j,k,l)$ in one set, so the resultant +value of such operation is simply the Cartesian product of the basic +sets: +$$A\times B\times C=\{(i,j,k,l):i\in A,(j,k)\in B,l\in C\}.$$ +Note that in this case the same indexing expression might be written in +the reduced form: +$$\mbox{{\tt\{A, B, C\}}}$$ +because the dummy indices $i$, $j$, $k$, and $l$ are not referenced and +therefore their symbolic names need not be specified. + +\newpage + +Finally, let the example indexing expression be used as the subscript +domain in the declaration of a 4-dimensional model object, say, +a numeric parameter: +$$\mbox{{\tt param p\{i in A, (j,k) in B, l in C\}} \dots {\tt;}}$$ + +\noindent In this case the action is generating the parameter members, +where each member has the form $p[i,j,k,l]$. + +As was said above, some indices in the second form of indexing entries +may be numeric or symbolic expressions, not only dummy indices. In this +case resultant values of such expressions play role of some logical +conditions to select only that $n$-tuples from the Cartesian product of +basic sets that satisfy these conditions. + +Consider, for example, the following indexing expression: +$$\mbox{{\tt\{i in A, (i-1,k) in B, l in C\}}}$$ +where {\tt i}, {\tt k}, {\tt l} are dummy indices, and {\tt i-1} is +a numeric expression. The algorithmic decsription of this indexing +expression is the following: + +\noindent\hfil +\begin{tabular}{@{}l@{}} +{\bf for all} $i\in A$ {\bf do}\\ +\hspace{16pt}{\bf for all} $(j,k)\in B$ {\bf and} $j=i-1$ {\bf do}\\ +\hspace{32pt}{\bf for all} $l\in C$ {\bf do}\\ +\hspace{48pt}{\it action};\\ +\end{tabular} + +\noindent Thus, if this indexing expression were used as a primary set +expression, the resultant set would be the following: +$$\{(4,May,a),(4,May,b),(4,May,c),(4,Jun,a),(4,Jun,b),(4,Jun,c)\}.$$ +Should note that in this case the resultant set consists of 3-tuples, +not of 4-tuples, because in the indexing expression there is no dummy +index that corresponds to the first component of 2-tuples from the set +$B$. + +The general rule is: the number of components of $n$-tuples defined by +an indexing expression is the same as the number of dummy indices in +that expression, where the correspondence between dummy indices and +components on $n$-tuples in the resultant set is positional, i.e. the +first dummy index corresponds to the first component, the second dummy +index corresponds to the second component, etc. + +In some cases it is needed to select a subset from the Cartesian +product of some sets. This may be attained by using an optional logical +predicate, which is specified in the indexing expression. + +Consider, for example, the following indexing expression: +$$\mbox{{\tt\{i in A, (j,k) in B, l in C: i <= 5 and k <> 'Mar'\}}}$$ +where the logical expression following the colon is a predicate. The +algorithmic description of this indexing expression is the following: + +\noindent\hfil +\begin{tabular}{@{}l@{}} +{\bf for all} $i\in A$ {\bf do}\\ +\hspace{16pt}{\bf for all} $(j,k)\in B$ {\bf do}\\ +\hspace{32pt}{\bf for all} $l\in C$ {\bf do}\\ +\hspace{48pt}{\bf if} $i\leq 5$ {\bf and} $k\neq`Mar'$ {\bf then}\\ +\hspace{64pt}{\it action};\\ +\end{tabular} + +\noindent Thus, if this indexing expression were used as a primary set +expression, the resultant set would be the following: +$$\{(4,1,Jan,a),(4,1,Feb,a),(4,2,Apr,a),\dots,(4,3,Jun,c)\}.$$ + +If no predicate is specified in the indexing expression, one, which +takes on the value {\it true}, is assumed. + +\section{Set expressions} + +A {\it set expression} is a rule for computing an elemental set, i.e. +a collection of $n$-tuples, where components of $n$-tuples are numeric +and symbolic quantities. + +The primary set expression may be a literal set, unsubscripted set, +subscripted set, ``arithmetic'' set, indexing expression, iterated set +expression, conditional set expression, or another set expression +enclosed in parentheses. + +\para{Examples} + +\noindent +\begin{tabular}{@{}ll@{}} +\verb|{(123,'aaa'), (i+1,'bbb'), (j-1,'ccc')}| &(literal set)\\ +\verb|I| &(unsubscripted set)\\ +\verb|S[i-1,j+1]| &(subscripted set)\\ +\verb|1..t-1 by 2| &(``arithmetic'' set)\\ +\verb|{t in 1..T, (t+1,j) in S: (t,j) in F}| &(indexing expression)\\ +\verb|setof{i in I, j in J}(i+1,j-1)| &(iterated set expression)\\ +\verb|if i < j then S[i,j] else F diff S[i,j]| &(conditional set +expression)\\ +\verb|(1..10 union 21..30)| &(parenthesized set expression)\\ +\end{tabular} + +More general set expressions containing two or more primary set +expressions may be constructed by using certain set operators. + +\para{Examples} + +\begin{verbatim} +(A union B) inter (I cross J) +1..10 cross (if i < j then {'a', 'b', 'c'} else {'d', 'e', 'f'}) +\end{verbatim} + +\subsection{Literal sets} + +A {\it literal set} is a primary set expression, which has the +following two syntactic forms: +$$ +{\def\arraystretch{1.4} +\begin{array}{l} +\mbox{{\tt\{}$e_1${\tt,} $e_2${\tt,} \dots{\tt,} $e_m${\tt\}}}\\ +\mbox{{\tt\{(}$e_{11}${\tt,} \dots{\tt,} $e_{1n}${\tt),} +{\tt(}$e_{21}${\tt,} \dots{\tt,} $e_{2n}${\tt),} \dots{\tt,} +{\tt(}$e_{m1}${\tt,} \dots{\tt,} $e_{mn}${\tt)\}}}\\ +\end{array} +} +$$ +where $e_1$, \dots, $e_m$, $e_{11}$, \dots, $e_{mn}$ are numeric or +symbolic expressions. + +If the first form is used, the resultant set consists of 1-tuples +(singlets) enumerated within the curly braces. It is allowed to specify +an empty set as {\tt\{\ \}}, which has no 1-tuples. If the second form +is used, the resultant set consists of $n$-tuples enumerated within the +curly braces, where a particular $n$-tuple consists of corresponding +components enumerated within the parentheses. All $n$-tuples should +have the same number of components. + +\subsection{Unsubscripted sets} + +If the primary set expression is an unsubscripted set (which should be +0-dimen\-sional), the resultant set is an elemental set associated with +the corresponding set object. + +\subsection{Subscripted sets} + +The primary set expression, which refers to a subscripted set, has the +following syntactic form: +$$\mbox{{\it name}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,} +$i_n${\tt]}}$$ +where {\it name} is the symbolic name of the set object, $i_1$, $i_2$, +\dots, $i_n$ are subscripts. + +Each subscript should be a numeric or symbolic expression. The number +of subscripts in the subscript list should be the same as the dimension +of the set object with which the subscript list is associated. + +Actual values of subscript expressions are used to identify a +particular member of the set object that determines the resultant set. + +\subsection{``Arithmetic'' sets} + +The primary set expression, which is an ``arithmetic'' set, has the +following two syntactic forms: +$$ +{\def\arraystretch{1.4} +\begin{array}{l} +\mbox{$t_0$ {\tt..} $t_1$ {\tt by} $\delta t$}\\ +\mbox{$t_0$ {\tt..} $t_1$}\\ +\end{array} +} +$$ +where $t_0$, $t_1$, and $\delta t$ are numeric expressions (the value +of $\delta t$ should not be zero). The second form is equivalent to the +first form, where $\delta t=1$. + +If $\delta t>0$, the resultant set is determined as follows: +$$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_0\leq t\leq t_1)\}.$$ +Otherwise, if $\delta t<0$, the resultant set is determined as follows: +$$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_1\leq t\leq t_0)\}.$$ + +\subsection{Indexing expressions} + +If the primary set expression is an indexing expression, the resultant +set is determined as described above in Section \ref{indexing}, page +\pageref{indexing}. + +\newpage + +\subsection{Iterated expressions} + +An {\it iterated set expression} is a primary set expression, which has +the following syntactic form: +$$\mbox{{\tt setof} {\it indexing-expression} {\it integrand}}$$ +where {\it indexing-expression} is an indexing expression, which +introduces dummy indices and controls iterating, {\it integrand} is +either a single numeric or symbolic expression or a list of numeric and +symbolic expressions separated by commae and enclosed in parentheses. + +If the integrand is a single numeric or symbolic expression, the +resultant set consists of 1-tuples and is determined as follows: +$$\{x:(i_1,\dots,i_n)\in\Delta\},$$ +\noindent where $x$ is a value of the integrand, $i_1$, \dots, $i_n$ +are dummy indices introduced in the indexing expression, $\Delta$ is +the domain, a set of $n$-tuples specified by the indexing expression, +which defines particular values assigned to the dummy indices on +performing the iterated operation. + +If the integrand is a list containing $m$ numeric and symbolic +expressions, the resultant set consists of $m$-tuples and is determined +as follows: +$$\{(x_1,\dots,x_m):(i_1,\dots,i_n)\in\Delta\},$$ +where $x_1$, \dots, $x_m$ are values of the expressions in the +integrand list, $i_1$, \dots, $i_n$ and $\Delta$ have the same meaning +as above. + +\subsection{Conditional expressions} + +A {\it conditional set expression} is a primary set expression that has +the following syntactic form: +$$\mbox{{\tt if} $b$ {\tt then} $X$ {\tt else} $Y$}$$ +where $b$ is an logical expression, $X$ and $Y$ are set expressions, +which should define sets of the same dimension. + +The resultant value of the conditional expression depends on the value +of the logical expression that follows the keyword {\tt if}. If it +takes on the value {\it true}, the resultant set is the value of the +expression that follows the keyword {\tt then}. Otherwise, if the +logical expression takes on the value {\it false}, the resultant set is +the value of the expression that follows the keyword {\tt else}. + +\subsection{Parenthesized expressions} + +Any set expression may be enclosed in parentheses that syntactically +makes it a primary set expression. + +Parentheses may be used in set expressions, as in algebra, to specify +the desired order in which operations are to be performed. Where +parentheses are used, the expression within the parentheses is +evaluated before the resultant value is used. + +The resultant value of the parenthesized expression is the same as the +value of the expression enclosed within parentheses. + +\newpage + +\subsection{Set operators} + +In MathProg there exist the following set operators, which may be used +in set expressions: + +\begin{tabular}{@{}ll@{}} +$X$ {\tt union} $Y$&union $X\cup Y$\\ +$X$ {\tt diff} $Y$&difference $X\backslash Y$\\ +$X$ {\tt symdiff} $Y$&symmetric difference +$X\oplus Y=(X\backslash Y)\cup(Y\backslash X)$\\ +$X$ {\tt inter} $Y$&intersection $X\cap Y$\\ +$X$ {\tt cross} $Y$&cross (Cartesian) product $X\times Y$\\ +\end{tabular} + +\noindent where $X$ and Y are set expressions, which should define sets +of identical dimension (except the Cartesian product). + +If the expression includes more than one set operator, all operators +are performed from left to right according to the hierarchy of +operations (see below). + +The resultant value of the expression, which contains set operators, is +the result of applying the operators to their operands. + +The dimension of the resultant set, i.e. the dimension of $n$-tuples, +of which the resultant set consists of, is the same as the dimension of +the operands, except the Cartesian product, where the dimension of the +resultant set is the sum of the dimensions of its operands. + +\subsection{Hierarchy of operations} + +The following list shows the hierarchy of operations in set +expressions: + +\noindent\hfil +\begin{tabular}{@{}ll@{}} +Operation&Hierarchy\\ +\hline +Evaluation of numeric operations&1st-7th\\ +Evaluation of symbolic operations&8th-9th\\ +Evaluation of iterated or ``arithmetic'' set ({\tt setof}, {\tt..})& +10th\\ +Cartesian product ({\tt cross})&11th\\ +Intersection ({\tt inter})&12th\\ +Union and difference ({\tt union}, {\tt diff}, {\tt symdiff})&13th\\ +Conditional evaluation ({\tt if} \dots {\tt then} \dots {\tt else})& +14th\\ +\end{tabular} + +This hierarchy has the same meaning as was explained above for numeric +expressions (see Subsection \ref{hierarchy}, page \pageref{hierarchy}). + +\newpage + +\section{Logical expressions} + +A {\it logical expression} is a rule for computing a single logical +value, which can be either {\it true} or {\it false}. + +The primary logical expression may be a numeric expression, relational +expression, iterated logical expression, or another logical expression +enclosed in parentheses. + +\para{Examples} + +\noindent +\begin{tabular}{@{}ll@{}} +\verb|i+1| &(numeric expression)\\ +\verb|a[i,j] < 1.5| &(relational expression)\\ +\verb|s[i+1,j-1] <> 'Mar' & year | &(relational expression)\\ +\verb|(i+1,'Jan') not in I cross J| &(relational expression)\\ +\verb|S union T within A[i] inter B[j]| &(relational expression)\\ +\verb|forall{i in I, j in J} a[i,j] < .5 * b[i]| &(iterated logical +expression)\\ +\verb|(a[i,j] < 1.5 or b[i] >= a[i,j])| &(parenthesized logical +expression)\\ +\end{tabular} + +More general logical expressions containing two or more primary logical +expressions may be constructed by using certain logical operators. + +\para{Examples} + +\begin{verbatim} +not (a[i,j] < 1.5 or b[i] >= a[i,j]) and (i,j) in S +(i,j) in S or (i,j) not in T diff U +\end{verbatim} + +\vspace*{-8pt} + +\subsection{Numeric expressions} + +The resultant value of the primary logical expression, which is a +numeric expression, is {\it true}, if the resultant value of the +numeric expression is non-zero. Otherwise the resultant value of the +logical expression is {\it false}. + +\vspace*{-8pt} + +\subsection{Relational operators} + +In MathProg there exist the following relational operators, which may +be used in logical expressions: + +\begin{tabular}{@{}ll@{}} +$x$ {\tt<} $y$&test on $x=} $y$&test on $x\geq y$\\ +$x$ {\tt>} $y$&test on $x>y$\\ +$x$ {\tt<>} $y$, $x$ {\tt!=} $y$&test on $x\neq y$\\ +$x$ {\tt in} $Y$&test on $x\in Y$\\ +{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt in} $Y$&test on +$(x_1,\dots,x_n)\in Y$\\ +$x$ {\tt not} {\tt in} $Y$, $x$ {\tt!in} $Y$&test on $x\not\in Y$\\ +{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt not} {\tt in} $Y$, +{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt !in} $Y$&test on +$(x_1,\dots,x_n)\not\in Y$\\ +$X$ {\tt within} $Y$&test on $X\subseteq Y$\\ +$X$ {\tt not} {\tt within} $Y$, $X$ {\tt !within} $Y$&test on +$X\not\subseteq Y$\\ +\end{tabular} + +\noindent where $x$, $x_1$, \dots, $x_n$, $y$ are numeric or symbolic +expressions, $X$ and $Y$ are set expression. + +\newpage + +1. In the operations {\tt in}, {\tt not in}, and {\tt !in} the +number of components in the first operands should be the same as the +dimension of the second operand. + +2. In the operations {\tt within}, {\tt not within}, and {\tt !within} +both operands should have identical dimension. + +All the relational operators listed above have their conventional +mathematical meaning. The resultant value is {\it true}, if +corresponding relation is satisfied for its operands, otherwise +{\it false}. (Note that symbolic values are ordered lexicographically, +and any numeric value precedes any symbolic value.) + +\subsection{Iterated expressions} + +An {\it iterated logical expression} is a primary logical expression, +which has the following syntactic form: +$$\mbox{{\it iterated-operator} {\it indexing-expression} +{\it integrand}}$$ +where {\it iterated-operator} is the symbolic name of the iterated +operator to be performed (see below), {\it indexing-expression} is an +indexing expression which introduces dummy indices and controls +iterating, {\it integrand} is a numeric expression that participates in +the operation. + +In MathProg there exist two iterated operators, which may be used in +logical expressions: + +{\def\arraystretch{1.4} +\noindent\hfil +\begin{tabular}{@{}lll@{}} +{\tt forall}&$\forall$-quantification&$\displaystyle +\forall(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\ +{\tt exists}&$\exists$-quantification&$\displaystyle +\exists(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\ +\end{tabular} +} + +\noindent where $i_1$, \dots, $i_n$ are dummy indices introduced in +the indexing expression, $\Delta$ is the domain, a set of $n$-tuples +specified by the indexing expression which defines particular values +assigned to the dummy indices on performing the iterated operation, +$f(i_1,\dots,i_n)$ is the integrand, a logical expression whose +resultant value depends on the dummy indices. + +For $\forall$-quantification the resultant value of the iterated +logical expression is {\it true}, if the value of the integrand is +{\it true} for all $n$-tuples contained in the domain, otherwise +{\it false}. + +For $\exists$-quantification the resultant value of the iterated +logical expression is {\it false}, if the value of the integrand is +{\it false} for all $n$-tuples contained in the domain, otherwise +{\it true}. + +\subsection{Parenthesized expressions} + +Any logical expression may be enclosed in parentheses that +syntactically makes it a primary logical expression. + +Parentheses may be used in logical expressions, as in algebra, to +specify the desired order in which operations are to be performed. +Where parentheses are used, the expression within the parentheses is +evaluated before the resultant value is used. + +The resultant value of the parenthesized expression is the same as the +value of the expression enclosed within parentheses. + +\newpage + +\subsection{Logical operators} + +In MathProg there exist the following logical operators, which may be +used in logical expressions: + +\begin{tabular}{@{}ll@{}} +{\tt not} $x$, {\tt!}$x$&negation $\neg\ x$\\ +$x$ {\tt and} $y$, $x$ {\tt\&\&} $y$&conjunction (logical ``and'') +$x\;\&\;y$\\ +$x$ {\tt or} $y$, $x$ {\tt||} $y$&disjunction (logical ``or'') +$x\vee y$\\ +\end{tabular} + +\noindent where $x$ and $y$ are logical expressions. + +If the expression includes more than one logical operator, all +operators are performed from left to right according to the hierarchy +of the operations (see below). The resultant value of the expression, +which contains logical operators, is the result of applying the +operators to their operands. + +\subsection{Hierarchy of operations} + +The following list shows the hierarchy of operations in logical +expressions: + +\noindent\hfil +\begin{tabular}{@{}ll@{}} +Operation&Hierarchy\\ +\hline +Evaluation of numeric operations&1st-7th\\ +Evaluation of symbolic operations&8th-9th\\ +Evaluation of set operations&10th-14th\\ +Relational operations ({\tt<}, {\tt<=}, etc.)&15th\\ +Negation ({\tt not}, {\tt!})&16th\\ +Conjunction ({\tt and}, {\tt\&\&})&17th\\ +$\forall$- and $\exists$-quantification ({\tt forall}, {\tt exists})& +18th\\ +Disjunction ({\tt or}, {\tt||})&19th\\ +\end{tabular} + +This hierarchy has the same meaning as was explained above for numeric +expressions (see Subsection \ref{hierarchy}, page \pageref{hierarchy}). + +\section{Linear expressions} + +A {\it linear expression} is a rule for computing so called +a {\it linear form} or simply a {\it formula}, which is a linear (or +affine) function of elemental variables. + +The primary linear expression may be an unsubscripted variable, +subscripted variable, iterated linear expression, conditional linear +expression, or another linear expression enclosed in parentheses. + +It is also allowed to use a numeric expression as the primary linear +expression, in which case the resultant value of the numeric expression +is automatically converted to a formula that includes the constant term +only. + +\para{Examples} + +\noindent +\begin{tabular}{@{}ll@{}} +\verb|z| &(unsubscripted variable)\\ +\verb|x[i,j]| &(subscripted variable)\\ +\verb|sum{j in J} (a[i,j] * x[i,j] + 3 * y[i-1])| & +(iterated linear expression)\\ +\verb|if i in I then x[i,j] else 1.5 * z + 3.25| & +(conditional linear expression)\\ +\verb|(a[i,j] * x[i,j] + y[i-1] + .1)| & +(parenthesized linear expression)\\ +\end{tabular} + +More general linear expressions containing two or more primary linear +expressions may be constructed by using certain arithmetic operators. + +\para{Examples} + +\begin{verbatim} +2 * x[i-1,j+1] + 3.5 * y[k] + .5 * z +(- x[i,j] + 3.5 * y[k]) / sum{t in T} abs(d[i,j,t]) +\end{verbatim} + +\vspace*{-5pt} + +\subsection{Unsubscripted variables} + +If the primary linear expression is an unsubscripted variable (which +should be 0-dimensional), the resultant formula is that unsubscripted +variable. + +\vspace*{-5pt} + +\subsection{Subscripted variables} + +The primary linear expression, which refers to a subscripted variable, +has the following syntactic form: +$$\mbox{{\it name}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,} +$i_n${\tt]}}$$ +where {\it name} is the symbolic name of the model variable, $i_1$, +$i_2$, \dots, $i_n$ are subscripts. + +Each subscript should be a numeric or symbolic expression. The number +of subscripts in the subscript list should be the same as the dimension +of the model variable with which the subscript list is associated. + +Actual values of the subscript expressions are used to identify a +particular member of the model variable that determines the resultant +formula, which is an elemental variable associated with corresponding +member. + +\vspace*{-5pt} + +\subsection{Iterated expressions} + +An {\it iterated linear expression} is a primary linear expression, +which has the following syntactic form: +$$\mbox{{\tt sum} {\it indexing-expression} {\it integrand}}$$ +where {\it indexing-expression} is an indexing expression, which +introduces dummy indices and controls iterating, {\it integrand} is +a linear expression that participates in the operation. + +The iterated linear expression is evaluated exactly in the same way as +the iterated numeric expression (see Subection \ref{itexpr}, page +\pageref{itexpr}) with exception that the integrand participated in the +summation is a formula, not a numeric value. + +\vspace*{-5pt} + +\subsection{Conditional expressions} + +A {\it conditional linear expression} is a primary linear expression, +which has one of the following two syntactic forms: +$$ +{\def\arraystretch{1.4} +\begin{array}{l} +\mbox{{\tt if} $b$ {\tt then} $f$ {\tt else} $g$}\\ +\mbox{{\tt if} $b$ {\tt then} $f$}\\ +\end{array} +} +$$ +where $b$ is an logical expression, $f$ and $g$ are linear expressions. + +\newpage + +The conditional linear expression is evaluated exactly in the same way +as the conditional numeric expression (see Subsection \ref{ifthen}, +page \pageref{ifthen}) with exception that operands participated in the +operation are formulae, not numeric values. + +\subsection{Parenthesized expressions} + +Any linear expression may be enclosed in parentheses that syntactically +makes it a primary linear expression. + +Parentheses may be used in linear expressions, as in algebra, to +specify the desired order in which operations are to be performed. +Where parentheses are used, the expression within the parentheses is +evaluated before the resultant formula is used. + +The resultant value of the parenthesized expression is the same as the +value of the expression enclosed within parentheses. + +\subsection{Arithmetic operators} + +In MathProg there exists the following arithmetic operators, which may +be used in linear expressions: + +\begin{tabular}{@{}ll@{}} +{\tt+} $f$&unary plus\\ +{\tt-} $f$&unary minus\\ +$f$ {\tt+} $g$&addition\\ +$f$ {\tt-} $g$&subtraction\\ +$x$ {\tt*} $f$, $f$ {\tt*} $x$&multiplication\\ +$f$ {\tt/} $x$&division +\end{tabular} + +\noindent where $f$ and $g$ are linear expressions, $x$ is a numeric +expression (more precisely, a linear expression containing only the +constant term). + +If the expression includes more than one arithmetic operator, all +operators are performed from left to right according to the hierarchy +of operations (see below). The resultant value of the expression, which +contains arithmetic operators, is the result of applying the operators +to their operands. + +\subsection{Hierarchy of operations} + +The hierarchy of arithmetic operations used in linear expressions is +the same as for numeric expressions (see Subsection \ref{hierarchy}, +page \pageref{hierarchy}). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Statements} + +{\it Statements} are basic units of the model description. In MathProg +all statements are divided into two categories: declaration statements +and functional statements. + +{\it Declaration statements} (set statement, parameter statement, +variable statement, constraint statement, objective statement) are used +to declare model objects of certain kinds and define certain properties +of such objects. + +{\it Functional statements} (solve statement, check statement, display +statement, printf statement, loop statement, table statement) are +intended for performing some specific actions. + +Note that declaration statements may follow in arbitrary order, which +does not affect the result of translation. However, any model object +should be declared before it is referenced in other statements. + +\section{Set statement} + +\noindent +\framebox[468pt][l]{ +\parbox[c][24pt]{468pt}{ +\hspace{6pt} {\tt set} {\it name} {\it alias} {\it domain} {\tt,} +{\it attrib} {\tt,} \dots {\tt,} {\it attrib} {\tt;} +}} + +\medskip + +\noindent +{\it name} is a symbolic name of the set; + +\noindent +{\it alias} is an optional string literal, which specifies an alias of +the set; + +\noindent +{\it domain} is an optional indexing expression, which specifies +a subscript domain of the set; + +\noindent +{\it attrib}, \dots, {\it attrib} are optional attributes of the set. +(Commae preceding attributes may be omitted.) + +\para{Optional attributes} + +\vspace*{-8pt} + +\begin{description} +\item[{\tt dimen} $n$]\hspace*{0pt}\\ +specifies the dimension of $n$-tuples which the set consists of; +\item[{\tt within} {\it expression}]\hspace*{0pt}\\ +specifies a superset which restricts the set or all its members +(elemental sets) to be within that superset; +\item[{\tt:=} {\it expression}]\hspace*{0pt}\\ +specifies an elemental set assigned to the set or its members; +\item[{\tt default} {\it expression}]\hspace*{0pt}\\ +specifies an elemental set assigned to the set or its members whenever +no appropriate data are available in the data section. +\end{description} + +\vspace*{-8pt} + +\para{Examples} + +\begin{verbatim} +set nodes; +set arcs within nodes cross nodes; +set step{s in 1..maxiter} dimen 2 := if s = 1 then arcs else step[s-1] + union setof{k in nodes, (i,k) in step[s-1], (k,j) in step[s-1]}(i,j); +set A{i in I, j in J}, within B[i+1] cross C[j-1], within D diff E, + default {('abc',123), (321,'cba')}; +\end{verbatim} + +The set statement declares a set. If the subscript domain is not +specified, the set is a simple set, otherwise it is an array of +elemental sets. + +The {\tt dimen} attribute specifies the dimension of $n$-tuples, which +the set (if it is a simple set) or its members (if the set is an array +of elemental sets) consist of, where $n$ should be an unsigned integer +from 1 to 20. At most one {\tt dimen} attribute can be specified. If +the {\tt dimen} attribute is not specified, the dimension of $n$-tuples +is implicitly determined by other attributes (for example, if there is +a set expression that follows {\tt:=} or the keyword {\tt default}, the +dimension of $n$-tuples of corresponding elemental set is used). +If no dimension information is available, {\tt dimen 1} is assumed. + +The {\tt within} attribute specifies a set expression whose resultant +value is a superset used to restrict the set (if it is a simple set) or +its members (if the set is an array of elemental sets) to be within +that superset. Arbitrary number of {\tt within} attributes may be +specified in the same set statement. + +The assign ({\tt:=}) attribute specifies a set expression used to +evaluate elemental set(s) assigned to the set (if it is a simple set) +or its members (if the set is an array of elemental sets). If the +assign attribute is specified, the set is {\it computable} and +therefore needs no data to be provided in the data section. If the +assign attribute is not specified, the set should be provided with data +in the data section. At most one assign or default attribute can be +specified for the same set. + +The {\tt default} attribute specifies a set expression used to evaluate +elemental set(s) assigned to the set (if it is a simple set) or its +members (if the set is an array of elemental sets) whenever +no appropriate data are available in the data section. If neither +assign nor default attribute is specified, missing data will cause an +error. + +\newpage + +\section{Parameter statement} + +\noindent +\framebox[468pt][l]{ +\parbox[c][24pt]{468pt}{ +\hspace{6pt} {\tt param} {\it name} {\it alias} {\it domain} {\tt,} +{\it attrib} {\tt,} \dots {\tt,} {\it attrib} {\tt;} +}} + +\medskip + +\noindent +{\it name} is a symbolic name of the parameter; + +\noindent +{\it alias} is an optional string literal, which specifies an alias of +the parameter; + +\noindent +{\it domain} is an optional indexing expression, which specifies +a subscript domain of the parameter; + +\noindent +{\it attrib}, \dots, {\it attrib} are optional attributes of the +parameter. (Commae preceding attributes may be omitted.) + +\para{Optional attributes} + +\vspace*{-8pt} + +\begin{description} +\item[{\tt integer}]\hspace*{0pt}\\ +specifies that the parameter is integer; +\item[{\tt binary}]\hspace*{0pt}\\ +specifies that the parameter is binary; +\item[{\tt symbolic}]\hspace*{0pt}\\ +specifies that the parameter is symbolic; +\item[{\it relation expression}]\hspace*{0pt}\\ +(where {\it relation} is one of: {\tt<}, {\tt<=}, {\tt=}, {\tt==}, +{\tt>=}, {\tt>}, {\tt<>}, {\tt!=})\\ +specifies a condition that restricts the parameter or its members to +satisfy that condition; +\item[{\tt in} {\it expression}]\hspace*{0pt}\\ +specifies a superset that restricts the parameter or its members to be +in that superset; +\item[{\tt:=} {\it expression}]\hspace*{0pt}\\ +specifies a value assigned to the parameter or its members; +\item[{\tt default} {\it expression}]\hspace*{0pt}\\ +specifies a value assigned to the parameter or its members whenever +no appropriate data are available in the data section. +\end{description} + +\vspace*{-8pt} + +\para{Examples} + +\begin{verbatim} +param units{raw, prd} >= 0; +param profit{prd, 1..T+1}; +param N := 20 integer >= 0 <= 100; +param comb 'n choose k' {n in 0..N, k in 0..n} := + if k = 0 or k = n then 1 else comb[n-1,k-1] + comb[n-1,k]; +param p{i in I, j in J}, integer, >= 0, <= i+j, in A[i] symdiff B[j], + in C[i,j], default 0.5 * (i + j); +param month symbolic default 'May' in {'Mar', 'Apr', 'May'}; +\end{verbatim} + +The parameter statement declares a parameter. If a subscript domain is +not specified, the parameter is a simple (scalar) parameter, otherwise +it is a $n$-dimensional array. + +The type attributes {\tt integer}, {\tt binary}, and {\tt symbolic} +qualify the type of values that can be assigned to the parameter as +shown below: + +\noindent\hfil +\begin{tabular}{@{}ll@{}} +Type attribute&Assigned values\\ +\hline +(not specified)&Any numeric values\\ +{\tt integer}&Only integer numeric values\\ +{\tt binary}&Either 0 or 1\\ +{\tt symbolic}&Any numeric and symbolic values\\ +\end{tabular} + +The {\tt symbolic} attribute cannot be specified along with other type +attributes. Being specified it should precede all other attributes. + +The condition attribute specifies an optional condition that restricts +values assigned to the parameter to satisfy that condition. This +attribute has the following syntactic forms: + +\begin{tabular}{@{}ll@{}} +{\tt<} $v$&check for $x=} $v$&check for $x\geq v$\\ +{\tt>} $v$&check for $x\geq v$\\ +{\tt<>} $v$, {\tt!=} $v$&check for $x\neq v$\\ +\end{tabular} + +\noindent where $x$ is a value assigned to the parameter, $v$ is the +resultant value of a numeric or symbolic expression specified in the +condition attribute. Arbitrary number of condition attributes can be +specified for the same parameter. If a value being assigned to the +parameter during model evaluation violates at least one of specified +conditions, an error is raised. (Note that symbolic values are ordered +lexicographically, and any numeric value precedes any symbolic value.) + +The {\tt in} attribute is similar to the condition attribute and +specifies a set expression whose resultant value is a superset used to +restrict numeric or symbolic values assigned to the parameter to be in +that superset. Arbitrary number of the {\tt in} attributes can be +specified for the same parameter. If a value being assigned to the +parameter during model evaluation is not in at least one of specified +supersets, an error is raised. + +The assign ({\tt:=}) attribute specifies a numeric or symbolic +expression used to compute a value assigned to the parameter (if it is +a simple parameter) or its member (if the parameter is an array). If +the assign attribute is specified, the parameter is {\it computable} +and therefore needs no data to be provided in the data section. If the +assign attribute is not specified, the parameter should be provided +with data in the data section. At most one assign or {\tt default} +attribute can be specified for the same parameter. + +The {\tt default} attribute specifies a numeric or symbolic expression +used to compute a value assigned to the parameter or its member +whenever no appropriate data are available in the data section. If +neither assign nor {\tt default} attribute is specified, missing data +will cause an error. + +\newpage + +\section{Variable statement} + +\noindent +\framebox[468pt][l]{ +\parbox[c][24pt]{468pt}{ +\hspace{6pt} {\tt var} {\it name} {\it alias} {\it domain} {\tt,} +{\it attrib} {\tt,} \dots {\tt,} {\it attrib} {\tt;} +}} + +\medskip + +\noindent +{\it name} is a symbolic name of the variable; + +\noindent +{\it alias} is an optional string literal, which specifies an alias of +the variable; + +\noindent +{\it domain} is an optional indexing expression, which specifies +a subscript domain of the variable; + +\noindent +{\it attrib}, \dots, {\it attrib} are optional attributes of the +variable. (Commae preceding attributes may be omitted.) + +\para{Optional attributes} + +\vspace*{-8pt} + +\begin{description} +\item[{\tt integer}]\hspace*{0pt}\\ +restricts the variable to be integer; +\item[{\tt binary}]\hspace*{0pt}\\ +restricts the variable to be binary; +\item[{\tt>=} {\it expression}]\hspace*{0pt}\\ +specifies an lower bound of the variable; +\item[{\tt<=} {\it expression}]\hspace*{0pt}\\ +specifies an upper bound of the variable; +\item[{\tt=} {\it expression}]\hspace*{0pt}\\ +specifies a fixed value of the variable; +\end{description} + +\vspace*{-8pt} + +\para{Examples} + +\begin{verbatim} +var x >= 0; +var y{I,J}; +var make{p in prd}, integer, >= commit[p], <= market[p]; +var store{raw, 1..T+1} >= 0; +var z{i in I, j in J} >= i+j; +\end{verbatim} + +The variable statement declares a variable. If a subscript domain is +not specified, the variable is a simple (scalar) variable, otherwise it +is a $n$-dimensional array of elemental variables. + +Elemental variable(s) associated with the model variable (if it is a +simple variable) or its members (if it is an array) correspond to the +variables in the LP/MIP problem formulation (see Section \ref{problem}, +page \pageref{problem}). Note that only elemental variables actually +referenced in some constraints and/or objectives are included in the +LP/MIP problem instance to be generated. + +The type attributes {\tt integer} and {\tt binary} restrict the +variable to be integer or binary, respectively. If no type attribute is +specified, the variable is continuous. If all variables in the model +are continuous, the corresponding problem is of LP class. If there is +at least one integer or binary variable, the problem is of MIP class. + +The lower bound ({\tt>=}) attribute specifies a numeric expression for +computing an lower bound of the variable. At most one lower bound can +be specified. By default all variables (except binary ones) have no +lower bound, so if a variable is required to be non-negative, its zero +lower bound should be explicitly specified. + +The upper bound ({\tt<=}) attribute specifies a numeric expression for +computing an upper bound of the variable. At most one upper bound +attribute can be specified. + +The fixed value ({\tt=}) attribute specifies a numeric expression for +computing a value, at which the variable is fixed. This attribute +cannot be specified along with the bound attributes. + +\section{Constraint statement} + +\noindent +\framebox[468pt][l]{ +\parbox[c][106pt]{468pt}{ +\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:} +{\it expression} {\tt,} {\tt=} {\it expression} {\tt;} + +\medskip + +\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:} +{\it expression} {\tt,} {\tt<=} {\it expression} {\tt;} + +\medskip + +\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:} +{\it expression} {\tt,} {\tt>=} {\it expression} {\tt;} + +\medskip + +\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:} +{\it expression} {\tt,} {\tt<=} {\it expression} {\tt,} {\tt<=} +{\it expression} {\tt;} + +\medskip + +\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:} +{\it expression} {\tt,} {\tt>=} {\it expression} {\tt,} {\tt>=} +{\it expression} {\tt;} +}} + +\medskip + +\noindent +{\it name} is a symbolic name of the constraint; + +\noindent +{\it alias} is an optional string literal, which specifies an alias of +the constraint; + +\noindent +{\it domain} is an optional indexing expression, which specifies +a subscript domain of the constraint; + +\noindent +{\it expression} is a linear expression used to compute a component of +the constraint. (Commae following expressions may be omitted.) + +\noindent +(The keyword {\tt s.t.} may be written as {\tt subject to} or as +{\tt subj to}, or may be omitted at all.) + +\para{Examples} + +\begin{verbatim} +s.t. r: x + y + z, >= 0, <= 1; +limit{t in 1..T}: sum{j in prd} make[j,t] <= max_prd; +subject to balance{i in raw, t in 1..T}: + store[i,t+1] = store[i,t] - sum{j in prd} units[i,j] * make[j,t]; +subject to rlim 'regular-time limit' {t in time}: + sum{p in prd} pt[p] * rprd[p,t] <= 1.3 * dpp[t] * crews[t]; +\end{verbatim} + +The constraint statement declares a constraint. If a subscript domain +is not specified, the\linebreak constraint is a simple (scalar) +constraint, otherwise it is a $n$-dimensional array of elemental +constraints. + +Elemental constraint(s) associated with the model constraint (if it is +a simple constraint) or its members (if it is an array) correspond to +the linear constraints in the LP/MIP problem formulation (see +Section \ref{problem}, page \pageref{problem}). + +If the constraint has the form of equality or single inequality, i.e. +includes two expressions, one of which follows the colon and other +follows the relation sign {\tt=}, {\tt<=}, or {\tt>=}, both expressions +in the statement can be linear expressions. If the constraint has the +form of double inequality,\linebreak i.e. includes three expressions, +the middle expression can be a linear expression while the leftmost and +rightmost ones can be only numeric expressions. + +Generating the model is, roughly speaking, generating its constraints, +which are always evaluated for the entire subscript domain. Evaluation +of the constraints leads, in turn, to evaluation of other model objects +such as sets, parameters, and variables. + +Constructing an actual linear constraint included in the problem +instance, which (constraint) corresponds to a particular elemental +constraint, is performed as follows. + +If the constraint has the form of equality or single inequality, +evaluation of both linear expressions gives two resultant linear forms: +$$\begin{array}{r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r} +f&=&a_1x_1&+&a_2x_2&+\dots+&a_nx_n&+&a_0,\\ +g&=&b_1x_1&+&a_2x_2&+\dots+&a_nx_n&+&b_0,\\ +\end{array}$$ +where $x_1$, $x_2$, \dots, $x_n$ are elemental variables; $a_1$, $a_2$, +\dots, $a_n$, $b_1$, $b_2$, \dots, $b_n$ are numeric coefficients; +$a_0$ and $b_0$ are constant terms. Then all linear terms of $f$ and +$g$ are carried to the left-hand side, and the constant terms are +carried to the right-hand side, that gives the final elemental +constraint in the standard form: +$$(a_1-b_1)x_1+(a_2-b_2)x_2+\dots+(a_n-b_n)x_n\left\{ +\begin{array}{@{}c@{}}=\\\leq\\\geq\\\end{array}\right\}b_0-a_0.$$ + +If the constraint has the form of double inequality, evaluation of the +middle linear expression gives the resultant linear form: +$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$ +and evaluation of the leftmost and rightmost numeric expressions gives +two numeric values $l$ and $u$, respectively. Then the constant term of +the linear form is carried to both left-hand and right-handsides that +gives the final elemental constraint in the standard form: +$$l-a_0\leq a_1x_1+a_2x_2+\dots+a_nx_n\leq u-a_0.$$ + +\section{Objective statement} + +\noindent +\framebox[468pt][l]{ +\parbox[c][44pt]{468pt}{ +\hspace{6pt} {\tt minimize} {\it name} {\it alias} {\it domain} {\tt:} +{\it expression} {\tt;} + +\medskip + +\hspace{6pt} {\tt maximize} {\it name} {\it alias} {\it domain} {\tt:} +{\it expression} {\tt;} +}} + +\medskip + +\noindent +{\it name} is a symbolic name of the objective; + +\noindent +{\it alias} is an optional string literal, which specifies an alias of +the objective; + +\noindent +{\it domain} is an optional indexing expression, which specifies +a subscript domain of the objective; + +\noindent +{\it expression} is a linear expression used to compute the linear form +of the objective. + +\newpage + +\para{Examples} + +\begin{verbatim} +minimize obj: x + 1.5 * (y + z); +maximize total_profit: sum{p in prd} profit[p] * make[p]; +\end{verbatim} + +The objective statement declares an objective. If a subscript domain is +not specified, the objective is a simple (scalar) objective. Otherwise +it is a $n$-dimensional array of elemental objectives. + +Elemental objective(s) associated with the model objective (if it is a +simple objective) or its members (if it is an array) correspond to +general linear constraints in the LP/MIP problem formulation (see +Section \ref{problem}, page \pageref{problem}). However, unlike +constraints the corresponding linear forms are free (unbounded). + +Constructing an actual linear constraint included in the problem +instance, which (constraint) corresponds to a particular elemental +constraint, is performed as follows. The linear expression specified in +the objective statement is evaluated that, gives the resultant linear +form: +$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$ +where $x_1$, $x_2$, \dots, $x_n$ are elemental variables; $a_1$, $a_2$, +\dots, $a_n$ are numeric coefficients; $a_0$ is the constant term. Then +the linear form is used to construct the final elemental constraint in +the standard form: +$$-\infty= 0 and y >= 0; +check sum{i in ORIG} supply[i] = sum{j in DEST} demand[j]; +check{i in I, j in 1..10}: S[i,j] in U[i] union V[j]; +\end{verbatim} + +The check statement allows checking the resultant value of an logical +expression specified in the statement. If the value is {\it false}, an +error is reported. + +If the subscript domain is not specified, the check is performed only +once. Specifying the subscript domain allows performing multiple check +for every $n$-tuple in the domain set. In the latter case the logical +expression may include dummy indices introduced in corresponding +indexing expression. + +\section{Display statement} + +\noindent +\framebox[468pt][l]{ +\parbox[c][24pt]{468pt}{ +\hspace{6pt} {\tt display} {\it domain} {\tt:} {\it item} {\tt,} +\dots {\tt,} {\it item} {\tt;} +}} + +\medskip + +\noindent +{\it domain} is an optional indexing expression, which specifies +a subscript domain of the display statement; + +\noindent +{\it item}, \dots, {\it item} are items to be displayed. (The colon +preceding the first item may be omitted.) + +\para{Examples} + +\begin{verbatim} +display: 'x =', x, 'y =', y, 'z =', z; +display sqrt(x ** 2 + y ** 2 + z ** 2); +display{i in I, j in J}: i, j, a[i,j], b[i,j]; +\end{verbatim} + +The display statement evaluates all items specified in the statement +and writes their values on the standard output (terminal) in plain text +format. + +If a subscript domain is not specified, items are evaluated and then +displayed only once. Specifying the subscript domain causes items to be +evaluated and displayed for every $n$-tuple in the domain set. In the +latter case items may include dummy indices introduced in corresponding +indexing expression. + +An item to be displayed can be a model object (set, parameter, +variable, constraint, objective) or an expression. + +If the item is a computable object (i.e. a set or parameter provided +with the assign attribute), the object is evaluated over the entire +domain and then its content (i.e. the content of the object array) is +displayed. Otherwise, if the item is not a computable object, only its +current content (i.e. members actually generated during the model +evaluation) is displayed. + +If the item is an expression, the expression is evaluated and its +resultant value is displayed. + +\section{Printf statement} + +\noindent +\framebox[468pt][l]{ +\parbox[c][64pt]{468pt}{ +\hspace{6pt} {\tt printf} {\it domain} {\tt:} {\it format} {\tt,} +{\it expression} {\tt,} \dots {\tt,} {\it expression} {\tt;} + +\medskip + +\hspace{6pt} {\tt printf} {\it domain} {\tt:} {\it format} {\tt,} +{\it expression} {\tt,} \dots {\tt,} {\it expression} {\tt>} +{\it filename} {\tt;} + +\medskip + +\hspace{6pt} {\tt printf} {\it domain} {\tt:} {\it format} {\tt,} +{\it expression} {\tt,} \dots {\tt,} {\it expression} {\tt>>} +{\it filename} {\tt;} +}} + +\medskip + +\noindent +{\it domain} is an optional indexing expression, which specifies +a subscript domain of the printf statement; + +\noindent +{\it format} is a symbolic expression whose value specifies a format +control string. (The colon preceding the format expression may be +omitted.) + +\noindent +{\it expression}, \dots, {\it expression} are zero or more expressions +whose values have to be formatted and printed. Each expression should +be of numeric, symbolic, or logical type. + +\noindent +{\it filename} is a symbolic expression whose value specifies a name +of a text file, to which the output is redirected. The flag {\tt>} +means creating a new empty file while the flag {\tt>>} means appending +the output to an existing file. If no file name is specified, the +output is written on the standard output (terminal). + +\para{Examples} + +\begin{verbatim} +printf 'Hello, world!\n'; +printf: "x = %.3f; y = %.3f; z = %.3f\n", x, y, z > "result.txt"; +printf{i in I, j in J}: "flow from %s to %s is %d\n", i, j, x[i,j] + >> result_file & ".txt"; +printf{i in I} 'total flow from %s is %g\n', i, sum{j in J} x[i,j]; +printf{k in K} "x[%s] = " & (if x[k] < 0 then "?" else "%g"), + k, x[k]; +\end{verbatim} + +The printf statement is similar to the display statement, however, it +allows formatting data to be written. + +If a subscript domain is not specified, the printf statement is +executed only once. Specifying a subscript domain causes executing the +printf statement for every $n$-tuple in the domain set. In the latter +case the format and expression may include dummy indices introduced in +corresponding indexing expression. + +The format control string is a value of the symbolic expression +{\it format} specified in the printf statement. It is composed of zero +or more directives as follows: ordinary characters (not {\tt\%}), which +are copied unchanged to the output stream, and conversion +specifications, each of which causes evaluating corresponding +expression specified in the printf statement, formatting it, and +writing its resultant value to the output stream. + +Conversion specifications that may be used in the format control string +are the following:\linebreak {\tt d}, {\tt i}, {\tt f}, {\tt F}, +{\tt e}, {\tt E}, {\tt g}, {\tt G}, and {\tt s}. These specifications +have the same syntax and semantics as in the C programming language. + +\section{For statement} + +\noindent +\framebox[468pt][l]{ +\parbox[c][44pt]{468pt}{ +\hspace{6pt} {\tt for} {\it domain} {\tt:} {\it statement} {\tt;} + +\medskip + +\hspace{6pt} {\tt for} {\it domain} {\tt:} {\tt\{} {\it statement} +\dots {\it statement} {\tt\}} {\tt;} +}} + +\medskip + +\noindent +{\it domain} is an indexing expression which specifies a subscript +domain of the for statement. (The colon following the indexing +expression may be omitted.) + +\noindent +{\it statement} is a statement, which should be executed under control +of the for statement; + +\noindent +{\it statement}, \dots, {\it statement} is a sequence of statements +(enclosed in curly braces), which should be executed under control of +the for statement. + +Only the following statements can be used within the for statement: +check, display, printf, and another for. + +\para{Examples} + +\begin{verbatim} +for {(i,j) in E: i != j} +{ printf "flow from %s to %s is %g\n", i, j, x[i,j]; + check x[i,j] >= 0; +} +for {i in 1..n} +{ for {j in 1..n} printf " %s", if x[i,j] then "Q" else "."; + printf("\n"); +} +for {1..72} printf("*"); +\end{verbatim} + +The for statement causes a statement or a sequence of statements +specified as part of the for statement to be executed for every +$n$-tuple in the domain set. Thus, statements within the for statement +may include dummy indices introduced in corresponding indexing +expression. + +\newpage + +\section{Table statement} + +\noindent +\framebox[468pt][l]{ +\parbox[c][80pt]{468pt}{ +\hspace{6pt} {\tt table} {\it name} {\it alias} {\tt IN} {\it driver} +{\it arg} \dots {\it arg} {\tt:} + +\hspace{6pt} {\tt\ \ \ \ \ } {\it set} {\tt<-} {\tt[} {\it fld} {\tt,} +\dots {\tt,} {\it fld} {\tt]} {\tt,} {\it par} {\tt\textasciitilde} +{\it fld} {\tt,} \dots {\tt,} {\it par} {\tt\textasciitilde} {\it fld} +{\tt;} + +\medskip + +\hspace{6pt} {\tt table} {\it name} {\it alias} {\it domain} {\tt OUT} +{\it driver} {\it arg} \dots {\it arg} {\tt:} + +\hspace{6pt} {\tt\ \ \ \ \ } {\it expr} {\tt\textasciitilde} {\it fld} +{\tt,} \dots {\tt,} {\it expr} {\tt\textasciitilde} {\it fld} {\tt;} +}} + +\medskip + +\noindent +{\it name} is a symbolic name of the table; + +\noindent +{\it alias} is an optional string literal, which specifies an alias of +the table; + +\noindent +{\it domain} is an indexing expression, which specifies a subscript +domain of the (output) table; + +\noindent +{\tt IN} means reading data from the input table; + +\noindent +{\tt OUT} means writing data to the output table; + +\noindent +{\it driver} is a symbolic expression, which specifies the driver used +to access the table (for details see Appendix \ref{drivers}, page +\pageref{drivers}); + +\noindent +{\it arg} is an optional symbolic expression, which is an argument +pass\-ed to the table driver. This symbolic expression should not +include dummy indices specified in the domain; + +\noindent +{\it set} is the name of an optional simple set called {\it control +set}. It can be omitted along with the delimiter {\tt<-}; + +\noindent +{\it fld} is a field name. Within square brackets at least one field +should be specified. The field name following a parameter name or +expression is optional and can be omitted along with the +delimiter~{\tt\textasciitilde}, in which case the name of corresponding +model object is used as the field name; + +\noindent +{\it par} is a symbolic name of a model parameter; + +\noindent +{\it expr} is a numeric or symbolic expression. + +\para{Examples} + +\begin{verbatim} +table data IN "CSV" "data.csv": S <- [FROM,TO], d~DISTANCE, + c~COST; +table result{(f,t) in S} OUT "CSV" "result.csv": f~FROM, t~TO, + x[f,t]~FLOW; +\end{verbatim} + +The table statement allows reading data from a table into model +objects such as sets and (non-scalar) parameters as well as writing +data from the model to a table. + +\newpage + +\subsection{Table structure} + +A {\it data table} is an (unordered) set of {\it records}, where each +record consists of the same number of {\it fields}, and each field is +provided with a unique symbolic name called the {\it field name}. For +example: + +\bigskip + +\begin{tabular}{@{\hspace*{42mm}}c@{\hspace*{11mm}}c@{\hspace*{10mm}}c +@{\hspace*{9mm}}c} +First&Second&&Last\\ +field&field&.\ \ .\ \ .&field\\ +$\downarrow$&$\downarrow$&&$\downarrow$\\ +\end{tabular} + +\begin{tabular}{ll@{}} +Table header&$\rightarrow$\\ +First record&$\rightarrow$\\ +Second record&$\rightarrow$\\ +\\ +\hfil .\ \ .\ \ .\\ +\\ +Last record&$\rightarrow$\\ +\end{tabular} +\begin{tabular}{|l|l|c|c|} +\hline +{\tt FROM}&{\tt TO}&{\tt DISTANCE}&{\tt COST}\\ +\hline +{\tt Seattle} &{\tt New-York}&{\tt 2.5}&{\tt 0.12}\\ +{\tt Seattle} &{\tt Chicago} &{\tt 1.7}&{\tt 0.08}\\ +{\tt Seattle} &{\tt Topeka} &{\tt 1.8}&{\tt 0.09}\\ +{\tt San-Diego}&{\tt New-York}&{\tt 2.5}&{\tt 0.15}\\ +{\tt San-Diego}&{\tt Chicago} &{\tt 1.8}&{\tt 0.10}\\ +{\tt San-Diego}&{\tt Topeka} &{\tt 1.4}&{\tt 0.07}\\ +\hline +\end{tabular} + +\subsection{Reading data from input table} + +The input table statement causes reading data from the specified table +record by record. + +Once a next record has been read, numeric or symbolic values of fields, +whose names are enclosed in square brackets in the table statement, are +gathered into $n$-tuple, and if the control set is specified in the +table statement, this $n$-tuple is added to it. Besides, a numeric or +symbolic value of each field associated with a model parameter is +assigned to the parameter member identified by subscripts, which are +components of the $n$-tuple just read. + +For example, the following input table statement: + +\noindent\hfil +\verb|table data IN "...": S <- [FROM,TO], d~DISTANCE, c~COST;| + +\noindent +causes reading values of four fields named {\tt FROM}, {\tt TO}, +{\tt DISTANCE}, and {\tt COST} from each record of the specified table. +Values of fields {\tt FROM} and {\tt TO} give a pair $(f,t)$, which is +added to the control set {\tt S}. The value of field {\tt DISTANCE} is +assigned to parameter member ${\tt d}[f,t]$, and the value of field +{\tt COST} is assigned to parameter member ${\tt c}[f,t]$. + +Note that the input table may contain extra fields whose names are not +specified in the table statement, in which case values of these fields +on reading the table are ignored. + +\subsection{Writing data to output table} + +The output table statement causes writing data to the specified table. +Note that some drivers (namely, CSV and xBASE) destroy the output table +before writing data, i.e. delete all its existing records. + +Each $n$-tuple in the specified domain set generates one record written +to the output table. Values of fields are numeric or symbolic values of +corresponding expressions specified in the table statement. These +expressions are evaluated for each $n$-tuple in the domain set and, +thus, may include dummy indices introduced in the corresponding indexing +expression. + +For example, the following output table statement: + +\noindent\hfil +\verb|table result{(f,t) in S} OUT "...": f~FROM, t~TO, x[f,t]~FLOW;| + +\noindent +causes writing records, by one record for each pair $(f,t)$ in set +{\tt S}, to the output table, where each record consists of three +fields named {\tt FROM}, {\tt TO}, and {\tt FLOW}. The values written +to fields {\tt FROM} and {\tt TO} are current values of dummy indices +{\tt f} and {\tt t}, and the value written to field {\tt FLOW} is +a value of member ${\tt x}[f,t]$ of corresponding subscripted parameter +or variable. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Model data} + +{\it Model data} include elemental sets, which are ``values'' of model +sets, and numeric and symbolic values of model parameters. + +In MathProg there are two different ways to saturate model sets and +parameters with data. One way is simply providing necessary data using +the assign attribute. However, in many cases it is more practical to +separate the model itself and particular data needed for the model. For +the latter reason in MathProg there is another way, when the model +description is divided into two parts: model section and data section. + +A {\it model section} is a main part of the model description that +contains declarations of all model objects and is common for all +problems based on that model. + +A {\it data section} is an optional part of the model description that +contains model data specific for a particular problem. + +In MathProg model and data sections can be placed either in one text +file or in two separate text files. + +1. If both model and data sections are placed in one file, the file is +composed as follows: + +\bigskip + +\noindent\hfil +\framebox{\begin{tabular}{l} +{\it statement}{\tt;}\\ +{\it statement}{\tt;}\\ +\hfil.\ \ .\ \ .\\ +{\it statement}{\tt;}\\ +{\tt data;}\\ +{\it data block}{\tt;}\\ +{\it data block}{\tt;}\\ +\hfil.\ \ .\ \ .\\ +{\it data block}{\tt;}\\ +{\tt end;} +\end{tabular}} + +\newpage + +2. If the model and data sections are placed in two separate files, the +files are composed as follows: + +\bigskip + +\noindent\hfil +\begin{tabular}{@{}c@{}} +\framebox{\begin{tabular}{l} +{\it statement}{\tt;}\\ +{\it statement}{\tt;}\\ +\hfil.\ \ .\ \ .\\ +{\it statement}{\tt;}\\ +{\tt end;}\\ +\end{tabular}}\\ +\\\\Model file\\ +\end{tabular} +\hspace{32pt} +\begin{tabular}{@{}c@{}} +\framebox{\begin{tabular}{l} +{\tt data;}\\ +{\it data block}{\tt;}\\ +{\it data block}{\tt;}\\ +\hfil.\ \ .\ \ .\\ +{\it data block}{\tt;}\\ +{\tt end;}\\ +\end{tabular}}\\ +\\Data file\\ +\end{tabular} + +\bigskip + +Note: If the data section is placed in a separate file, the keyword +{\tt data} is optional and may be omitted along with the semicolon that +follows it. + +\section{Coding data section} + +The {\it data section} is a sequence of data blocks in various formats, +which are discussed in following sections. The order, in which data +blocks follow in the data section, may be arbitrary, not necessarily +the same, in which corresponding model objects follow in the model +section. + +The rules of coding the data section are commonly the same as the rules +of coding the model description (see Section \ref{coding}, page +\pageref{coding}), i.e. data blocks are composed from basic lexical +units such as symbolic names, numeric and string literals, keywords, +delimiters, and comments. However, for the sake of convenience and for +improving readability there is one deviation from the common rule: if +a string literal consists of only alphanumeric characters (including +the underscore character), the signs {\tt+} and {\tt-}, and/or the +decimal point, it may be coded without bordering by (single or double) +quotes. + +All numeric and symbolic material provided in the data section is coded +in the form of numbers and symbols, i.e. unlike the model section +no expressions are allowed in the data section. Nevertheless, the signs +{\tt+} and {\tt-} can precede numeric literals to allow coding signed +numeric quantities, in which case there should be no white-space +characters between the sign and following numeric literal (if there is +at least one white-space, the sign and following numeric literal are +recognized as two different lexical units). + +\newpage + +\section{Set data block} + +\noindent +\framebox[468pt][l]{ +\parbox[c][44pt]{468pt}{ +\hspace{6pt} {\tt set} {\it name} {\tt,} {\it record} {\tt,} \dots +{\tt,} {\it record} {\tt;} + +\medskip + +\hspace{6pt} {\tt set} {\it name} {\tt[} {\it symbol} {\tt,} \dots +{\tt,} {\it symbol} {\tt]} {\tt,} {\it record} {\tt,} \dots {\tt,} +{\it record} {\tt;} +}} + +\medskip + +\noindent +{\it name} is a symbolic name of the set; + +\noindent +{\it symbol}, \dots, {\it symbol} are subscripts, which specify +a particular member of the set (if the set is an array, i.e. a set of +sets); + +\noindent +{\it record}, \dots, {\it record} are data records. + +\noindent +Commae preceding data records may be omitted. + +\para{Data records} + +\vspace*{-8pt} + +\begin{description} +\item[{\tt :=}]\hspace*{0pt}\\ +is a non-significant data record, which may be used freely to improve +readability; +\item[{\tt(} {\it slice} {\tt)}]\hspace*{0pt}\\ +specifies a slice; +\item[{\it simple-data}]\hspace*{0pt}\\ +specifies set data in the simple format; +\item[{\tt:} {\it matrix-data}]\hspace*{0pt}\\ +specifies set data in the matrix format; +\item[{\tt(tr)} {\tt:} {\it matrix-data}]\hspace*{0pt}\\ +specifies set data in the transposed matrix format. (In this case the +colon following the keyword {\tt(tr)} may be omitted.) +\end{description} + +\vspace*{-8pt} + +\para{Examples} + +\begin{verbatim} +set month := Jan Feb Mar Apr May Jun; +set month "Jan", "Feb", "Mar", "Apr", "May", "Jun"; +set A[3,Mar] := (1,2) (2,3) (4,2) (3,1) (2,2) (4,4) (3,4); +set A[3,'Mar'] := 1 2 2 3 4 2 3 1 2 2 4 4 3 4; +set A[3,'Mar'] : 1 2 3 4 := + 1 - + - - + 2 - + + - + 3 + - - + + 4 - + - + ; +set B := (1,2,3) (1,3,2) (2,3,1) (2,1,3) (1,2,2) (1,1,1) (2,1,1); +set B := (*,*,*) 1 2 3, 1 3 2, 2 3 1, 2 1 3, 1 2 2, 1 1 1, 2 1 1; +set B := (1,*,2) 3 2 (2,*,1) 3 1 (1,2,3) (2,1,3) (1,1,1); +set B := (1,*,*) : 1 2 3 := + 1 + - - + 2 - + + + 3 - + - + (2,*,*) : 1 2 3 := + 1 + - + + 2 - - - + 3 + - - ; +\end{verbatim} + +\noindent(In these examples {\tt month} is a simple set of singlets, +{\tt A} is a 2-dimensional array of doublets, and {\tt B} is a simple +set of triplets. Data blocks for the same set are equivalent in the +sense that they specify the same data in different formats.) + +The {\it set data block} is used to specify a complete elemental set, +which is assigned to a set (if it is a simple set) or one of its +members (if the set is an array of sets).\footnote{There is another way +to specify data for a simple set along with data for parameters. This +feature is discussed in the next section.} + +Data blocks can be specified only for non-computable sets, i.e. for +sets, which have no assign attribute ({\tt:=}) in the corresponding set +statements. + +If the set is a simple set, only its symbolic name should be specified +in the header of the data block. Otherwise, if the set is a +$n$-dimensional array, its symbolic name should be provided with a +complete list of subscripts separated by commae and enclosed in square +brackets to specify a particular member of the set array. The number of +subscripts should be the same as the dimension of the set array, where +each subscript should be a number or symbol. + +An elemental set defined in the set data block is coded as a sequence +of data records described below.\footnote{{\it Data record} is simply a +technical term. It does not mean that data records have any special +formatting.} + +\subsection{Assign data record} + +The {\it assign data record} ({\tt:=}) is a non-signficant element. +It may be used for improving readability of data blocks. + +\subsection{Slice data record} + +The {\it slice data record} is a control record, which specifies a +{\it slice} of the elemental set defined in the data block. It has the +following syntactic form: +$$\mbox{{\tt(} $s_1$ {\tt,} $s_2$ {\tt,} \dots {\tt,} $s_n$ {\tt)}}$$ +where $s_1$, $s_2$, \dots, $s_n$ are components of the slice. + +Each component of the slice can be a number or symbol or the asterisk +({\tt*}). The number of components in the slice should be the same as +the dimension of $n$-tuples in the elemental set to be defined. For +instance, if the elemental set contains 4-tuples (quadruplets), the +slice should have four components. The number of asterisks in the slice +is called the {\it slice dimension}. + +The effect of using slices is the following. If a $m$-dimensional slice +(i.e. a slice having $m$ asterisks) is specified in the data block, all +subsequent data records should specify tuples of the dimension~$m$. +Whenever a $m$-tuple is encountered, each asterisk in the slice is +replaced by corresponding components of the $m$-tuple that gives the +resultant $n$-tuple, which is included in the elemental set to be +defined. For example, if the slice $(a,*,1,2,*)$ is in effect, and +2-tuple $(3,b)$ is encountered in a subsequent data record, the +resultant 5-tuple included in the elemental set is $(a,3,1,2,b)$. + +The slice having no asterisks itself defines a complete $n$-tuple, +which is included in the elemental set. + +Being once specified the slice effects until either a new slice or the +end of data block is encountered. Note that if no slice is specified in +the data block, one, components of which are all asterisks, is assumed. + +\subsection{Simple data record} + +The {\it simple data record} defines one $n$-tuple in a simple format +and has the following syntactic form: +$$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$}$$ +where $t_1$, $t_2$, \dots, $t_n$ are components of the $n$-tuple. Each +component can be a number or symbol. Commae between components are +optional and may be omitted. + +\subsection{Matrix data record} + +The {\it matrix data record} defines several 2-tuples (doublets) in +a matrix format and has the following syntactic form: +$$\begin{array}{cccccc} +\mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\ +r_1&a_{11}&a_{12}&\dots&a_{1n}&\\ +r_2&a_{21}&a_{22}&\dots&a_{2n}&\\ +\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\ +r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\ +\end{array}$$ +where $r_1$, $r_2$, \dots, $r_m$ are numbers and/or symbols +corresponding to rows of the matrix; $c_1$, $c_2$, \dots, $c_n$ are +numbers and/or symbols corresponding to columns of the matrix, $a_{11}$, +$a_{12}$, \dots, $a_{mn}$ are matrix elements, which can be either +{\tt+} or {\tt-}. (In this data record the delimiter {\tt:} preceding +the column list and the delimiter {\tt:=} following the column list +cannot be omitted.) + +Each element $a_{ij}$ of the matrix data block (where $1\leq i\leq m$, +$1\leq j\leq n$) corresponds to 2-tuple $(r_i,c_j)$. If $a_{ij}$ is the +plus sign ({\tt+}), that 2-tuple (or a longer $n$-tuple, if a slice is +used) is included in the elemental set. Otherwise, if $a_{ij}$ is the +minus sign ({\tt-}), that 2-tuple is not included in the elemental set. + +Since the matrix data record defines 2-tuples, either the elemental set +should consist of 2-tuples or the slice currently used should be +2-dimensional. + +\newpage + +\subsection{Transposed matrix data record} + +The {\it transposed matrix data record} has the following syntactic +form: +$$\begin{array}{cccccc} +\mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\ +r_1&a_{11}&a_{12}&\dots&a_{1n}&\\ +r_2&a_{21}&a_{22}&\dots&a_{2n}&\\ +\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\ +r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\ +\end{array}$$ +(In this case the delimiter {\tt:} following the keyword {\tt(tr)} is +optional and may be omitted.) + +This data record is completely analogous to the matrix data record (see +above) with only exception that in this case each element $a_{ij}$ of +the matrix corresponds to 2-tuple $(c_j,r_i)$ rather than $(r_i,c_j)$. + +Being once specified the {\tt(tr)} indicator affects all subsequent +data records until either a slice or the end of data block is +encountered. + +\section{Parameter data block} + +\noindent +\framebox[468pt][l]{ +\parbox[c][88pt]{468pt}{ +\hspace{6pt} {\tt param} {\it name} {\tt,} {\it record} {\tt,} \dots +{\tt,} {\it record} {\tt;} + +\medskip + +\hspace{6pt} {\tt param} {\it name} {\tt default} {\it value} {\tt,} +{\it record} {\tt,} \dots {\tt,} {\it record} {\tt;} + +\medskip + +\hspace{6pt} {\tt param} {\tt:} {\it tabbing-data} {\tt;} + +\medskip + +\hspace{6pt} {\tt param} {\tt default} {\it value} {\tt:} +{\it tabbing-data} {\tt;} +}} + +\medskip + +\noindent +{\it name} is a symbolic name of the parameter; + +\noindent +{\it value} is an optional default value of the parameter; + +\noindent +{\it record}, \dots, {\it record} are data records; + +\noindent +{\it tabbing-data} specifies parameter data in the tabbing format. + +\noindent +Commae preceding data records may be omitted. + +\para{Data records} + +\vspace*{-8pt} + +\begin{description} +\item[{\tt :=}]\hspace*{0pt}\\ +is a non-significant data record, which may be used freely to improve +readability; +\item[{\tt[} {\it slice} {\tt]}]\hspace*{0pt}\\ +specifies a slice; +\item[{\it plain-data}]\hspace*{0pt}\\ +specifies parameter data in the plain format; +\item[{\tt:} {\it tabular-data}]\hspace*{0pt}\\ +specifies parameter data in the tabular format; +\item[{\tt(tr)} {\tt:} {\it tabular-data}]\hspace*{0pt}\\ +specifies set data in the transposed tabular format. (In this case the +colon following the keyword {\tt(tr)} may be omitted.) +\end{description} + +\vspace*{-8pt} + +\para{Examples} + +\begin{verbatim} +param T := 4; +param month := 1 Jan 2 Feb 3 Mar 4 Apr 5 May; +param month := [1] 'Jan', [2] 'Feb', [3] 'Mar', [4] 'Apr', [5] 'May'; +param init_stock := iron 7.32 nickel 35.8; +param init_stock [*] iron 7.32, nickel 35.8; +param cost [iron] .025 [nickel] .03; +param value := iron -.1, nickel .02; +param : init_stock cost value := + iron 7.32 .025 -.1 + nickel 35.8 .03 .02 ; +param : raw : init stock cost value := + iron 7.32 .025 -.1 + nickel 35.8 .03 .02 ; +param demand default 0 (tr) + : FRA DET LAN WIN STL FRE LAF := + bands 300 . 100 75 . 225 250 + coils 500 750 400 250 . 850 500 + plate 100 . . 50 200 . 250 ; +param trans_cost := + [*,*,bands]: FRA DET LAN WIN STL FRE LAF := + GARY 30 10 8 10 11 71 6 + CLEV 22 7 10 7 21 82 13 + PITT 19 11 12 10 25 83 15 + [*,*,coils]: FRA DET LAN WIN STL FRE LAF := + GARY 39 14 11 14 16 82 8 + CLEV 27 9 12 9 26 95 17 + PITT 24 14 17 13 28 99 20 + [*,*,plate]: FRA DET LAN WIN STL FRE LAF := + GARY 41 15 12 16 17 86 8 + CLEV 29 9 13 9 28 99 18 + PITT 26 14 17 13 31 104 20 ; +\end{verbatim} + +The {\it parameter data block} is used to specify complete data for a +parameter (or parameters, if data are specified in the tabbing format). + +Data blocks can be specified only for non-computable parameters, i.e. +for parameters, which have no assign attribute ({\tt:=}) in the +corresponding parameter statements. + +Data defined in the parameter data block are coded as a sequence of +data records described below. Additionally the data block can be +provided with the optional {\tt default} attribute, which specifies a +default numeric or symbolic value of the parameter (parameters). This +default value is assigned to the parameter or its members when +no appropriate value is defined in the parameter data block. The +{\tt default} attribute cannot be used, if it is already specified in +the corresponding parameter statement. + +\subsection{Assign data record} + +The {\it assign data record} ({\tt:=}) is a non-signficant element. +It may be used for improving readability of data blocks. + +\subsection{Slice data record} + +The {\it slice data record} is a control record, which specifies a +{\it slice} of the parameter array. It has the following syntactic +form: +$$\mbox{{\tt[} $s_1$ {\tt,} $s_2$ {\tt,} \dots {\tt,} $s_n$ {\tt]}}$$ +where $s_1$, $s_2$, \dots, $s_n$ are components of the slice. + +Each component of the slice can be a number or symbol or the asterisk +({\tt*}). The number of components in the slice should be the same as +the dimension of the parameter. For instance, if the parameter is a +4-dimensional array, the slice should have four components. The number +of asterisks in the slice is called the {\it slice dimension}. + +The effect of using slices is the following. If a $m$-dimensional slice +(i.e. a slice having $m$ asterisks) is specified in the data block, all +subsequent data records should specify subscripts of the parameter +members as if the parameter were $m$-dimensional, not $n$-dimensional. + +Whenever $m$ subscripts are encountered, each asterisk in the slice is +replaced by corresponding subscript that gives $n$ subscripts, which +define the actual parameter member. For example, if the slice +$[a,*,1,2,*]$ is in effect, and subscripts 3 and $b$ are encountered in +a subsequent data record, the complete subscript list used to choose a +parameter member is $[a,3,1,2,b]$. + +It is allowed to specify a slice having no asterisks. Such slice itself +defines a complete subscript list, in which case the next data record +should define only a single value of corresponding parameter member. + +Being once specified the slice effects until either a new slice or the +end of data block is encountered. Note that if no slice is specified in +the data block, one, components of which are all asterisks, is assumed. + +\subsection{Plain data record} + +The {\it plain data record} defines a subscript list and a single value +in the plain format. This record has the following syntactic form: +$$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$ {\tt,} $v$}$$ +where $t_1$, $t_2$, \dots, $t_n$ are subscripts, and $v$ is a value. +Each subscript as well as the value can be a number or symbol. Commae +following subscripts are optional and may be omitted. + +In case of 0-dimensional parameter or slice the plain data record has +no subscripts and consists of a single value only. + +\subsection{Tabular data record} + +The {\it tabular data record} defines several values, where each value +is provided with two subscripts. This record has the following +syntactic form: +$$\begin{array}{cccccc} +\mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\ +r_1&a_{11}&a_{12}&\dots&a_{1n}&\\ +r_2&a_{21}&a_{22}&\dots&a_{2n}&\\ +\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\ +r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\ +\end{array}$$ +where $r_1$, $r_2$, \dots, $r_m$ are numbers and/or symbols +corresponding to rows of the table; $c_1$, $c_2$, \dots, $c_n$ are +numbers and/or symbols corresponding to columns of the table, $a_{11}$, +$a_{12}$, \dots, $a_{mn}$ are table elements. Each element can be a +number or symbol or the single decimal point ({\tt.}). (In this data +record the delimiter {\tt:} preceding the column list and the delimiter +{\tt:=} following the column list cannot be omitted.) + +Each element $a_{ij}$ of the tabular data block ($1\leq i\leq m$, +$1\leq j\leq n$) defines two subscripts, where the first subscript is +$r_i$, and the second one is $c_j$. These subscripts are used in +conjunction with the current slice to form the complete subscript list +that identifies a particular member of the parameter array. If $a_{ij}$ +is a number or symbol, this value is assigned to the parameter member. +However, if $a_{ij}$ is the single decimal point, the member is +assigned a default value specified either in the parameter data block +or in the parameter statement, or, if no default value is specified, +the member remains undefined. + +Since the tabular data record provides two subscripts for each value, +either the parameter or the slice currently used should be +2-dimensional. + +\subsection{Transposed tabular data record} + +The {\it transposed tabular data record} has the following syntactic +form: +$$\begin{array}{cccccc} +\mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\ +r_1&a_{11}&a_{12}&\dots&a_{1n}&\\ +r_2&a_{21}&a_{22}&\dots&a_{2n}&\\ +\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\ +r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\ +\end{array}$$ +(In this case the delimiter {\tt:} following the keyword {\tt(tr)} is +optional and may be omitted.) + +This data record is completely analogous to the tabular data record +(see above) with only exception that the first subscript defined by +element $a_{ij}$ is $c_j$ while the second one is $r_i$. + +Being once specified the {\tt(tr)} indicator affects all subsequent +data records until either a slice or the end of data block is +encountered. + +\newpage + +\subsection{Tabbing data format} + +The parameter data block in the {\it tabbing format} has the following +syntactic form: +$$ +\begin{array}{*{8}{l}} +\multicolumn{4}{l} +{{\tt param}\ {\tt default}\ value\ {\tt :}\ s\ {\tt :}}& +p_1\ \ \verb|,|&p_2\ \ \verb|,|&\dots\ \verb|,|&p_r\ \ \verb|:=|\\ +r_{11}\ \verb|,|& r_{12}\ \verb|,|& \dots\ \verb|,|& r_{1n}\ \verb|,|& +a_{11}\ \verb|,|& a_{12}\ \verb|,|& \dots\ \verb|,|& a_{1r}\ \verb|,|\\ +r_{21}\ \verb|,|& r_{22}\ \verb|,|& \dots\ \verb|,|& r_{2n}\ \verb|,|& +a_{21}\ \verb|,|& a_{22}\ \verb|,|& \dots\ \verb|,|& a_{2r}\ \verb|,|\\ +\dots & \dots & \dots & \dots & \dots & \dots & \dots & \dots \\ +r_{m1}\ \verb|,|& r_{m2}\ \verb|,|& \dots\ \verb|,|& r_{mn}\ \verb|,|& +a_{m1}\ \verb|,|& a_{m2}\ \verb|,|& \dots\ \verb|,|& a_{mr}\ \verb|;|\\ +\end{array} +$$ + +1. The keyword {\tt default} may be omitted along with a value +following it. + +2. Symbolic name $s$ may be omitted along with the colon following it. + +3. All commae are optional and may be omitted. + +The data block in the tabbing format shown above is exactly equivalent +to the following data blocks: + +\verb|set| $s$\ \verb|:=|\ $ +\verb|(|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|) | +\verb|(|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|) | +\dots +\verb| (|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|);|$ + +\verb|param| $p_1$\ \verb|default|\ $value$\ \verb|:=| + +$\verb| | +\verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{11} +\verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{21} +\verb| |\dots +\verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{m1} +\verb|;| +$ + +\verb|param| $p_2$\ \verb|default|\ $value$\ \verb|:=| + +$\verb| | +\verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{12} +\verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{22} +\verb| |\dots +\verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{m2} +\verb|;| +$ + +\verb| |.\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ . + +\verb|param| $p_r$\ \verb|default|\ $value$\ \verb|:=| + +$\verb| | +\verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{1r} +\verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{2r} +\verb| |\dots +\verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{mr} +\verb|;| +$ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\appendix + +\chapter{Using suffixes} + +\vspace*{-12pt} + +Suffixes can be used to retrieve additional values associated with +model variables, constraints, and objectives. + +A {\it suffix} consists of a period ({\tt.}) followed by a non-reserved +keyword. For example, if {\tt x} is a two-dimensional variable, +{\tt x[i,j].lb} is a numeric value equal to the lower bound of +elemental variable {\tt x[i,j]}, which (value) can be used everywhere +in expressions like a numeric parameter. + +For model variables suffixes have the following meaning: + +\begin{tabular}{@{}ll@{}} +{\tt.lb}&lower bound\\ +{\tt.ub}&upper bound\\ +{\tt.status}&status in the solution:\\ +&0 --- undefined\\ +&1 --- basic\\ +&2 --- non-basic on lower bound\\ +&3 --- non-basic on upper bound\\ +&4 --- non-basic free (unbounded) variable\\ +&5 --- non-basic fixed variable\\ +{\tt.val}&primal value in the solution\\ +{\tt.dual}&dual value (reduced cost) in the solution\\ +\end{tabular} + +For model constraints and objectives suffixes have the following +meaning: + +\begin{tabular}{@{}ll@{}} +{\tt.lb}&lower bound of the linear form\\ +{\tt.ub}&upper bound of the linear form\\ +{\tt.status}&status in the solution:\\ +&0 --- undefined\\ +&1 --- non-active\\ +&2 --- active on lower bound\\ +&3 --- active on upper bound\\ +&4 --- active free (unbounded) row\\ +&5 --- active equality constraint\\ +{\tt.val}&primal value of the linear form in the solution\\ +{\tt.dual}&dual value (reduced cost) of the linear form in the +solution\\ +\end{tabular} + +Note that suffixes {\tt.status}, {\tt.val}, and {\tt.dual} can be used +only below the solve statement. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Date and time functions} + +\noindent\hfil +\begin{tabular}{c} +by Andrew Makhorin \verb||\\ +and Heinrich Schuchardt \verb||\\ +\end{tabular} + +\section{Obtaining current calendar time} +\label{gmtime} + +To obtain the current calendar time in MathProg there exists the +function {\tt gmtime}. It has no arguments and returns the number of +seconds elapsed since 00:00:00 on January 1, 1970, Coordinated +Universal Time (UTC). For example: + +\begin{verbatim} + param utc := gmtime(); +\end{verbatim} + +MathProg has no function to convert UTC time returned by the function +{\tt gmtime} to {\it local} calendar times. Thus, if you need to +determine the current local calendar time, you have to add to the UTC +time returned the time offset from UTC expressed in seconds. For +example, the time in Berlin during the winter is one hour ahead of UTC +that corresponds to the time offset +1~hour~= +3600~secs, so the +current winter calendar time in Berlin may be determined as follows: + +\begin{verbatim} + param now := gmtime() + 3600; +\end{verbatim} + +\noindent Similarly, the summer time in Chicago (Central Daylight Time) +is five hours behind UTC, so the corresponding current local calendar +time may be determined as follows: + +\begin{verbatim} + param now := gmtime() - 5 * 3600; +\end{verbatim} + +Note that the value returned by {\tt gmtime} is volatile, i.e. being +called several times this function may return different values. + +\section{Converting character string to calendar time} +\label{str2time} + +The function {\tt str2time(}{\it s}{\tt,} {\it f}{\tt)} converts a +character string (timestamp) specified by its first argument {\it s}, +which should be a symbolic expression, to the calendar time suitable +for arithmetic calculations. The conversion is controlled by the +specified format string {\it f} (the second argument), which also +should be a symbolic expression. + +\newpage + +The result of conversion returned by {\tt str2time} has the same +meaning as values returned by the function {\tt gmtime} (see Subsection +\ref{gmtime}, page \pageref{gmtime}). Note that {\tt str2time} does +{\tt not} correct the calendar time returned for the local timezone, +i.e. being applied to 00:00:00 on January 1, 1970 it always returns 0. + +For example, the model statements: + +\begin{verbatim} + param s, symbolic, := "07/14/98 13:47"; + param t := str2time(s, "%m/%d/%y %H:%M"); + display t; +\end{verbatim} + +\noindent produce the following printout: + +\begin{verbatim} + t = 900424020 +\end{verbatim} + +\noindent where the calendar time printed corresponds to 13:47:00 on +July 14, 1998. + +The format string passed to the function {\tt str2time} consists of +conversion specifiers and ordinary characters. Each conversion +specifier begins with a percent ({\tt\%}) character followed by a +letter. + +The following conversion specifiers may be used in the format string: + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%b}&The abbreviated month name (case insensitive). At least three +first letters of the month name should appear in the input string.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%d}&The day of the month as a decimal number (range 1 to 31). +Leading zero is permitted, but not required.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%h}&The same as {\tt\%b}.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%H}&The hour as a decimal number, using a 24-hour clock (range 0 +to 23). Leading zero is permitted, but not required.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%m}&The month as a decimal number (range 1 to 12). Leading zero is +permitted, but not required.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%M}&The minute as a decimal number (range 0 to 59). Leading zero +is permitted, but not required.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%S}&The second as a decimal number (range 0 to 60). Leading zero +is permitted, but not required.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%y}&The year without a century as a decimal number (range 0 to 99). +Leading zero is permitted, but not required. Input values in the range +0 to 68 are considered as the years 2000 to 2068 while the values 69 to +99 as the years 1969 to 1999.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%z}&The offset from GMT in ISO 8601 format.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%\%}&A literal {\tt\%} character.\\ +\end{tabular} + +All other (ordinary) characters in the format string should have a +matching character in the input string to be converted. Exceptions are +spaces in the input string which can match zero or more space +characters in the format string. + +\newpage + +If some date and/or time component(s) are missing in the format and, +therefore, in the input string, the function {\tt str2time} uses their +default values corresponding to 00:00:00 on January 1, 1970, that is, +the default value of the year is 1970, the default value of the month +is January, etc. + +The function {\tt str2time} is applicable to all calendar times in the +range 00:00:00 on January 1, 0001 to 23:59:59 on December 31, 4000 of +the Gregorian calendar. + +\section{Converting calendar time to character string} +\label{time2str} + +The function {\tt time2str(}{\it t}{\tt,} {\it f}{\tt)} converts the +calendar time specified by its first argument {\it t}, which should be +a numeric expression, to a character string (symbolic value). The +conversion is controlled by the specified format string {\it f} (the +second argument), which should be a symbolic expression. + +The calendar time passed to {\tt time2str} has the same meaning as +values returned by the function {\tt gmtime} (see Subsection +\ref{gmtime}, page \pageref{gmtime}). Note that {\tt time2str} does +{\it not} correct the specified calendar time for the local timezone, +i.e. the calendar time 0 always corresponds to 00:00:00 on January 1, +1970. + +For example, the model statements: + +\begin{verbatim} + param s, symbolic, := time2str(gmtime(), "%FT%TZ"); + display s; +\end{verbatim} + +\noindent may produce the following printout: + +\begin{verbatim} + s = '2008-12-04T00:23:45Z' +\end{verbatim} + +\noindent which is a timestamp in the ISO format. + +The format string passed to the function {\tt time2str} consists of +conversion specifiers and ordinary characters. Each conversion +specifier begins with a percent ({\tt\%}) character followed by a +letter. + +The following conversion specifiers may be used in the format string: + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%a}&The abbreviated (2-character) weekday name.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%A}&The full weekday name.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%b}&The abbreviated (3-character) month name.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%B}&The full month name.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%C}&The century of the year, that is the greatest integer not +greater than the year divided by~100.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%d}&The day of the month as a decimal number (range 01 to 31).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%D}&The date using the format \verb|%m/%d/%y|.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%e}&The day of the month like with \verb|%d|, but padded with +blank rather than zero.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%F}&The date using the format \verb|%Y-%m-%d|.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%g}&The year corresponding to the ISO week number, but without the +century (range 00 to~99). This has the same format and value as +\verb|%y|, except that if the ISO week number (see \verb|%V|) belongs +to the previous or next year, that year is used instead.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%G}&The year corresponding to the ISO week number. This has the +same format and value as \verb|%Y|, except that if the ISO week number +(see \verb|%V|) belongs to the previous or next year, that year is used +instead. +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%h}&The same as \verb|%b|.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%H}&The hour as a decimal number, using a 24-hour clock (range 00 +to 23).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%I}&The hour as a decimal number, using a 12-hour clock (range 01 +to 12).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%j}&The day of the year as a decimal number (range 001 to 366).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%k}&The hour as a decimal number, using a 24-hour clock like +\verb|%H|, but padded with blank rather than zero.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%l}&The hour as a decimal number, using a 12-hour clock like +\verb|%I|, but padded with blank rather than zero. +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%m}&The month as a decimal number (range 01 to 12).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%M}&The minute as a decimal number (range 00 to 59).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%p}&Either {\tt AM} or {\tt PM}, according to the given time value. +Midnight is treated as {\tt AM} and noon as {\tt PM}.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%P}&Either {\tt am} or {\tt pm}, according to the given time value. +Midnight is treated as {\tt am} and noon as {\tt pm}.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%R}&The hour and minute in decimal numbers using the format +\verb|%H:%M|.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%S}&The second as a decimal number (range 00 to 59).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%T}&The time of day in decimal numbers using the format +\verb|%H:%M:%S|.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%u}&The day of the week as a decimal number (range 1 to 7), Monday +being 1.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%U}&The week number of the current year as a decimal number (range +00 to 53), starting with the first Sunday as the first day of the first +week. Days preceding the first Sunday in the year are considered to be +in week 00. +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%V}&The ISO week number as a decimal number (range 01 to 53). ISO +weeks start with Monday and end with Sunday. Week 01 of a year is the +first week which has the majority of its days in that year; this is +equivalent to the week containing January 4. Week 01 of a year can +contain days from the previous year. The week before week 01 of a year +is the last week (52 or 53) of the previous year even if it contains +days from the new year. In other word, if 1 January is Monday, Tuesday, +Wednesday or Thursday, it is in week 01; if 1 January is Friday, +Saturday or Sunday, it is in week 52 or 53 of the previous year.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%w}&The day of the week as a decimal number (range 0 to 6), Sunday +being 0.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%W}&The week number of the current year as a decimal number (range +00 to 53), starting with the first Monday as the first day of the first +week. Days preceding the first Monday in the year are considered to be +in week 00.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%y}&The year without a century as a decimal number (range 00 to +99), that is the year modulo~100.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%Y}&The year as a decimal number, using the Gregorian calendar.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%\%}&A literal \verb|%| character.\\ +\end{tabular} + +All other (ordinary) characters in the format string are simply copied +to the resultant string. + +The first argument (calendar time) passed to the function {\tt time2str} +should be in the range from $-62135596800$ to $+64092211199$ that +corresponds to the period from 00:00:00 on January 1, 0001 to 23:59:59 +on December 31, 4000 of the Gregorian calendar. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Table drivers} +\label{drivers} + +\noindent\hfil +\begin{tabular}{c} +by Andrew Makhorin \verb||\\ +and Heinrich Schuchardt \verb||\\ +\end{tabular} + +\bigskip\bigskip + +The {\it table driver} is a program module which provides transmitting +data between MathProg model objects and data tables. + +Currently the GLPK package has four table drivers: + +\vspace*{-8pt} + +\begin{itemize} +\item built-in CSV table driver; +\item built-in xBASE table driver; +\item ODBC table driver; +\item MySQL table driver. +\end{itemize} + +\vspace*{-8pt} + +\section{CSV table driver} + +The CSV table driver assumes that the data table is represented in the +form of a plain text file in the CSV (comma-separated values) file +format as described below. + +To choose the CSV table driver its name in the table statement should +be specified as \verb|"CSV"|, and the only argument should specify the +name of a plain text file containing the table. For example: + +\begin{verbatim} + table data IN "CSV" "data.csv": ... ; +\end{verbatim} + +The filename suffix may be arbitrary, however, it is recommended to use +the suffix `\verb|.csv|'. + +On reading input tables the CSV table driver provides an implicit field +named \verb|RECNO|, which contains the current record number. This +field can be specified in the input table statement as if there were +the actual field named \verb|RECNO| in the CSV file. For example: + +\begin{verbatim} + table list IN "CSV" "list.csv": num <- [RECNO], ... ; +\end{verbatim} + +\newpage + +\subsection*{CSV format\footnote{This material is based on the RFC +document 4180.}} + +The CSV (comma-separated values) format is a plain text file format +defined as follows. + +1. Each record is located on a separate line, delimited by a line +break. For example: + +\begin{verbatim} + aaa,bbb,ccc\n + xxx,yyy,zzz\n +\end{verbatim} + +\noindent +where \verb|\n| means the control character \verb|LF| ({\tt 0x0A}). + +2. The last record in the file may or may not have an ending line +break. For example: + +\begin{verbatim} + aaa,bbb,ccc\n + xxx,yyy,zzz +\end{verbatim} + +3. There should be a header line appearing as the first line of the +file in the same format as normal record lines. This header should +contain names corresponding to the fields in the file. The number of +field names in the header line should be the same as the number of +fields in the records of the file. For example: + +\begin{verbatim} + name1,name2,name3\n + aaa,bbb,ccc\n + xxx,yyy,zzz\n +\end{verbatim} + +4. Within the header and each record there may be one or more fields +separated by commas. Each line should contain the same number of fields +throughout the file. Spaces are considered as part of a field and +therefore not ignored. The last field in the record should not be +followed by a comma. For example: + +\begin{verbatim} + aaa,bbb,ccc\n +\end{verbatim} + +5. Fields may or may not be enclosed in double quotes. For example: + +\begin{verbatim} + "aaa","bbb","ccc"\n + zzz,yyy,xxx\n +\end{verbatim} + +6. If a field is enclosed in double quotes, each double quote which is +part of the field should be coded twice. For example: + +\begin{verbatim} + "aaa","b""bb","ccc"\n +\end{verbatim} + +\para{Example} + +\begin{verbatim} +FROM,TO,DISTANCE,COST +Seattle,New-York,2.5,0.12 +Seattle,Chicago,1.7,0.08 +Seattle,Topeka,1.8,0.09 +San-Diego,New-York,2.5,0.15 +San-Diego,Chicago,1.8,0.10 +San-Diego,Topeka,1.4,0.07 +\end{verbatim} + +\newpage + +\section{xBASE table driver} + +The xBASE table driver assumes that the data table is stored in the +.dbf file format. + +To choose the xBASE table driver its name in the table statement should +be specified as \verb|"xBASE"|, and the first argument should specify +the name of a .dbf file containing the table. For the output table there +should be the second argument defining the table format in the form +\verb|"FF...F"|, where \verb|F| is either {\tt C({\it n})}, +which specifies a character field of length $n$, or +{\tt N({\it n}{\rm [},{\it p}{\rm ]})}, which specifies a numeric field +of length $n$ and precision $p$ (by default $p$ is 0). + +The following is a simple example which illustrates creating and +reading a .dbf file: + +\begin{verbatim} +table tab1{i in 1..10} OUT "xBASE" "foo.dbf" + "N(5)N(10,4)C(1)C(10)": 2*i+1 ~ B, Uniform(-20,+20) ~ A, + "?" ~ FOO, "[" & i & "]" ~ C; +set S, dimen 4; +table tab2 IN "xBASE" "foo.dbf": S <- [B, C, RECNO, A]; +display S; +end; +\end{verbatim} + +\section{ODBC table driver} + +The ODBC table driver allows connecting to SQL databases using an +implementation of the ODBC interface based on the Call Level Interface +(CLI).\footnote{The corresponding software standard is defined in +ISO/IEC 9075-3:2003.} + +\para{Debian GNU/Linux.} +Under Debian GNU/Linux the ODBC table driver uses the iODBC +package,\footnote{See {\tt}.} which should be +installed before building the GLPK package. The installation can be +effected with the following command: + +\begin{verbatim} + sudo apt-get install libiodbc2-dev +\end{verbatim} + +Note that on configuring the GLPK package to enable using the iODBC +library the option `\verb|--enable-odbc|' should be passed to the +configure script. + +The individual databases should be entered for systemwide usage in +\verb|/etc/odbc.ini| and\linebreak \verb|/etc/odbcinst.ini|. Database +connections to be used by a single user are specified by files in the +home directory (\verb|.odbc.ini| and \verb|.odbcinst.ini|). + +\para{Microsoft Windows.} +Under Microsoft Windows the ODBC table driver uses the Microsoft ODBC +library. To enable this feature the symbol: + +\begin{verbatim} + #define ODBC_DLNAME "odbc32.dll" +\end{verbatim} + +\noindent +should be defined in the GLPK configuration file `\verb|config.h|'. + +Data sources can be created via the Administrative Tools from the +Control Panel. + +To choose the ODBC table driver its name in the table statement should +be specified as \verb|'ODBC'| or \verb|'iODBC'|. + +\newpage + +The argument list is specified as follows. + +The first argument is the connection string passed to the ODBC library, +for example: + +\verb|'DSN=glpk;UID=user;PWD=password'|, or + +\verb|'DRIVER=MySQL;DATABASE=glpkdb;UID=user;PWD=password'|. + +Different parts of the string are separated by semicolons. Each part +consists of a pair {\it fieldname} and {\it value} separated by the +equal sign. Allowable fieldnames depend on the ODBC library. Typically +the following fieldnames are allowed: + +\verb|DATABASE | database; + +\verb|DRIVER | ODBC driver; + +\verb|DSN | name of a data source; + +\verb|FILEDSN | name of a file data source; + +\verb|PWD | user password; + +\verb|SERVER | database; + +\verb|UID | user name. + +The second argument and all following are considered to be SQL +statements + +SQL statements may be spread over multiple arguments. If the last +character of an argument is a semicolon this indicates the end of +a SQL statement. + +The arguments of a SQL statement are concatenated separated by space. +The eventual trailing semicolon will be removed. + +All but the last SQL statement will be executed directly. + +For IN-table the last SQL statement can be a SELECT command starting +with the capitalized letters \verb|'SELECT '|. If the string does not +start with \verb|'SELECT '| it is considered to be a table name and a +SELECT statement is automatically generated. + +For OUT-table the last SQL statement can contain one or multiple +question marks. If it contains a question mark it is considered a +template for the write routine. Otherwise the string is considered a +table name and an INSERT template is automatically generated. + +The writing routine uses the template with the question marks and +replaces the first question mark by the first output parameter, the +second question mark by the second output parameter and so forth. Then +the SQL command is issued. + +The following is an example of the output table statement: + +\begin{verbatim} +table ta { l in LOCATIONS } OUT + 'ODBC' + 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword' + 'DROP TABLE IF EXISTS result;' + 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );' + 'INSERT INTO result 'VALUES ( 4, ?, ? )' : + l ~ LOC, quantity[l] ~ QUAN; +\end{verbatim} + +\newpage + +\noindent +Alternatively it could be written as follows: + +\begin{verbatim} +table ta { l in LOCATIONS } OUT + 'ODBC' + 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword' + 'DROP TABLE IF EXISTS result;' + 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );' + 'result' : + l ~ LOC, quantity[l] ~ QUAN, 4 ~ ID; +\end{verbatim} + +Using templates with `\verb|?|' supports not only INSERT, but also +UPDATE, DELETE, etc. For example: + +\begin{verbatim} +table ta { l in LOCATIONS } OUT + 'ODBC' + 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword' + 'UPDATE result SET DATE = ' & date & ' WHERE ID = 4;' + 'UPDATE result SET QUAN = ? WHERE LOC = ? AND ID = 4' : + quantity[l], l; +\end{verbatim} + +\section{MySQL table driver} + +The MySQL table driver allows connecting to MySQL databases. + +\para{Debian GNU/Linux.} +Under Debian GNU/Linux the MySQL table driver uses the MySQL +package,\footnote{For download development files see +{\tt}.} which should be +installed before building the GLPK package. The installation can be +effected with the following command: + +\begin{verbatim} + sudo apt-get install libmysqlclient15-dev +\end{verbatim} + +Note that on configuring the GLPK package to enable using the MySQL +library the option `\verb|--enable-mysql|' should be passed to the +configure script. + +\para{Microsoft Windows.} +Under Microsoft Windows the MySQL table driver also uses the MySQL +library. To enable this feature the symbol: + +\begin{verbatim} + #define MYSQL_DLNAME "libmysql.dll" +\end{verbatim} + +\noindent +should be defined in the GLPK configuration file `\verb|config.h|'. + +To choose the MySQL table driver its name in the table statement should +be specified as \verb|'MySQL'|. + +The argument list is specified as follows. + +The first argument specifies how to connect the data base in the DSN +style, for example: + +\verb|'Database=glpk;UID=glpk;PWD=gnu'|. + +Different parts of the string are separated by semicolons. Each part +consists of a pair {\it fieldname} and {\it value} separated by the +equal sign. The following fieldnames are allowed: + +\newpage + +\verb|Server | server running the database (defaulting to localhost); + +\verb|Database | name of the database; + +\verb|UID | user name; + +\verb|PWD | user password; + +\verb|Port | port used by the server (defaulting to 3306). + +The second argument and all following are considered to be SQL +statements. + +SQL statements may be spread over multiple arguments. If the last +character of an argument is a semicolon this indicates the end of +a SQL statement. + +The arguments of a SQL statement are concatenated separated by space. +The eventual trailing semicolon will be removed. + +All but the last SQL statement will be executed directly. + +For IN-table the last SQL statement can be a SELECT command starting +with the capitalized letters \verb|'SELECT '|. If the string does not +start with \verb|'SELECT '| it is considered to be a table name and a +SELECT statement is automatically generated. + +For OUT-table the last SQL statement can contain one or multiple +question marks. If it contains a question mark it is considered a +template for the write routine. Otherwise the string is considered a +table name and an INSERT template is automatically generated. + +The writing routine uses the template with the question marks and +replaces the first question mark by the first output parameter, the +second question mark by the second output parameter and so forth. Then +the SQL command is issued. + +The following is an example of the output table statement: + +\begin{verbatim} +table ta { l in LOCATIONS } OUT + 'MySQL' + 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword' + 'DROP TABLE IF EXISTS result;' + 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );' + 'INSERT INTO result VALUES ( 4, ?, ? )' : + l ~ LOC, quantity[l] ~ QUAN; +\end{verbatim} + +\noindent +Alternatively it could be written as follows: + +\begin{verbatim} +table ta { l in LOCATIONS } OUT + 'MySQL' + 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword' + 'DROP TABLE IF EXISTS result;' + 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );' + 'result' : + l ~ LOC, quantity[l] ~ QUAN, 4 ~ ID; +\end{verbatim} + +\newpage + +Using templates with `\verb|?|' supports not only INSERT, but also +UPDATE, DELETE, etc. For example: + +\begin{verbatim} +table ta { l in LOCATIONS } OUT + 'MySQL' + 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword' + 'UPDATE result SET DATE = ' & date & ' WHERE ID = 4;' + 'UPDATE result SET QUAN = ? WHERE LOC = ? AND ID = 4' : + quantity[l], l; +\end{verbatim} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Solving models with glpsol} + +The GLPK package\footnote{{\tt http://www.gnu.org/software/glpk/}} +includes the program {\tt glpsol}, a stand-alone LP/MIP solver. This +program can be launched from the command line or from the shell to +solve models written in the GNU MathProg modeling language. + +To tell the solver that the input file contains a model description you +need to specify the option \verb|--model| in the command line. +For example: + +\begin{verbatim} + glpsol --model foo.mod +\end{verbatim} + +Sometimes it is necessary to use the data section placed in a separate +file, in which case you may use the following command: + +\begin{verbatim} + glpsol --model foo.mod --data foo.dat +\end{verbatim} + +\noindent Note that if the model file also contains the data section, +that section is ignored. + +It is also allowed to specify more than one file containing the data +section, for example: + +\begin{verbatim} + glpsol --model foo.mod --data foo1.dat --data foo2.dat +\end{verbatim} + +If the model description contains some display and/or printf +statements, by default the output is sent to the terminal. If you need +to redirect the output to a file, you may use the following command: + +\begin{verbatim} + glpsol --model foo.mod --display foo.out +\end{verbatim} + +If you need to look at the problem, which has been generated by the +model translator, you may use the option \verb|--wlp| as follows: + +\begin{verbatim} + glpsol --model foo.mod --wlp foo.lp +\end{verbatim} + +\noindent In this case the problem data is written to file +\verb|foo.lp| in CPLEX LP format suitable for visual analysis. + +Sometimes it is needed merely to check the model description not +solving the generated problem instance. In this case you may specify +the option \verb|--check|, for example: + +\begin{verbatim} + glpsol --check --model foo.mod --wlp foo.lp +\end{verbatim} + +\newpage + +If you need to write a numeric solution obtained by the solver to +a file, you may use the following command: + +\begin{verbatim} + glpsol --model foo.mod --output foo.sol +\end{verbatim} + +\noindent in which case the solution is written to file \verb|foo.sol| +in a plain text format suitable for visual analysis. + +The complete list of the \verb|glpsol| options can be found in the +GLPK reference manual included in the GLPK distribution. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Example model description} + +\section{Model description written in MathProg} + +Below here is a complete example of the model description written in +the GNU MathProg modeling language. + +\bigskip + +\begin{verbatim} +# A TRANSPORTATION PROBLEM +# +# This problem finds a least cost shipping schedule that meets +# requirements at markets and supplies at factories. +# +# References: +# Dantzig G B, "Linear Programming and Extensions." +# Princeton University Press, Princeton, New Jersey, 1963, +# Chapter 3-3. + +set I; +/* canning plants */ + +set J; +/* markets */ + +param a{i in I}; +/* capacity of plant i in cases */ + +param b{j in J}; +/* demand at market j in cases */ + +param d{i in I, j in J}; +/* distance in thousands of miles */ + +param f; +/* freight in dollars per case per thousand miles */ + +param c{i in I, j in J} := f * d[i,j] / 1000; +/* transport cost in thousands of dollars per case */ + +var x{i in I, j in J} >= 0; +/* shipment quantities in cases */ + +minimize cost: sum{i in I, j in J} c[i,j] * x[i,j]; +/* total transportation costs in thousands of dollars */ + +s.t. supply{i in I}: sum{j in J} x[i,j] <= a[i]; +/* observe supply limit at plant i */ + +s.t. demand{j in J}: sum{i in I} x[i,j] >= b[j]; +/* satisfy demand at market j */ + +data; + +set I := Seattle San-Diego; + +set J := New-York Chicago Topeka; + +param a := Seattle 350 + San-Diego 600; + +param b := New-York 325 + Chicago 300 + Topeka 275; + +param d : New-York Chicago Topeka := + Seattle 2.5 1.7 1.8 + San-Diego 2.5 1.8 1.4 ; + +param f := 90; + +end; +\end{verbatim} + +\newpage + +\section{Generated LP problem instance} + +Below here is the result of the translation of the example model +produced by the solver \verb|glpsol| and written in CPLEX LP format +with the option \verb|--wlp|. + +\medskip + +\begin{verbatim} +\* Problem: transp *\ + +Minimize + cost: + 0.225 x(Seattle,New~York) + 0.153 x(Seattle,Chicago) + + 0.162 x(Seattle,Topeka) + 0.225 x(San~Diego,New~York) + + 0.162 x(San~Diego,Chicago) + 0.126 x(San~Diego,Topeka) + +Subject To + supply(Seattle): + x(Seattle,New~York) + x(Seattle,Chicago) + + x(Seattle,Topeka) <= 350 + supply(San~Diego): + x(San~Diego,New~York) + x(San~Diego,Chicago) + + x(San~Diego,Topeka) <= 600 + demand(New~York): + x(Seattle,New~York) + x(San~Diego,New~York) >= 325 + demand(Chicago): + x(Seattle,Chicago) + x(San~Diego,Chicago) >= 300 + demand(Topeka): + x(Seattle,Topeka) + x(San~Diego,Topeka) >= 275 + +End +\end{verbatim} + +\section{Optimal LP solution} + +Below here is the optimal solution of the generated LP problem instance +found by the solver \verb|glpsol| and written in plain text format +with the option \verb|--output|. + +\medskip + +\begin{footnotesize} +\begin{verbatim} +Problem: transp +Rows: 6 +Columns: 6 +Non-zeros: 18 +Status: OPTIMAL +Objective: cost = 153.675 (MINimum) + + No. Row name St Activity Lower bound Upper bound Marginal +------ ------------ -- ------------- ------------- ------------- ------------- + 1 cost B 153.675 + 2 supply[Seattle] + NU 350 350 < eps + 3 supply[San-Diego] + B 550 600 + 4 demand[New-York] + NL 325 325 0.225 + 5 demand[Chicago] + NL 300 300 0.153 + 6 demand[Topeka] + NL 275 275 0.126 + + No. Column name St Activity Lower bound Upper bound Marginal +------ ------------ -- ------------- ------------- ------------- ------------- + 1 x[Seattle,New-York] + B 50 0 + 2 x[Seattle,Chicago] + B 300 0 + 3 x[Seattle,Topeka] + NL 0 0 0.036 + 4 x[San-Diego,New-York] + B 275 0 + 5 x[San-Diego,Chicago] + NL 0 0 0.009 + 6 x[San-Diego,Topeka] + B 275 0 + +End of output +\end{verbatim} +\end{footnotesize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section*{Acknowledgements} +\addcontentsline{toc}{chapter}{Acknowledgements} + +The authors would like to thank the following people, who kindly read, +commented, and corrected the draft of this document: + +\noindent Juan Carlos Borras \verb|| + +\noindent Harley Mackenzie \verb|| + +\noindent Robbie Morrison \verb|| + +\end{document} diff --git a/resources/3rdparty/glpk-4.57/doc/gmpl_es.pdf b/resources/3rdparty/glpk-4.57/doc/gmpl_es.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2d5ca8e0c9805115612375e476f85f9fdcafe4b1 GIT binary patch literal 255373 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 z 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 z zPrs3H7%bgfb-16ym{tZv3HWvq81Qz73R$R@14Sm0ya4k+b((*mg&22NR&iiWGRRGM z&2~|U(kAFx-g>A7@lKPj9BjCo8#|?9E-9qtdo^5WLuZE&A*b1^@XC`WQH-@hDsD@2 zU<~5#UA$jIXB!iuRg92|`l4+#NQ;CvCgk%&UTIKv{vC@)*$XPNi zjQ0D)Rhmsy;9<*VlhICL@A;EfLvNyvZdq^Qj@Iu{L%XyqZu@(T-wS+YQ>C8Y8gObvb}5xh~#FbEm9ihNPwx&d^5`ATd(wQJGd&HYZY6lC)T*3IzrlFn zf_z=JHt!xO~Bzm8@=n=ctwoCT{!s$`b zNc;lF33zMVDCkom`$|UMelbXYDx>E$Sb$A-z+K|9uqoLws4Y;H?zjLW4om@gT!|uu zd(ly9u#Gm=#>mBxgc23K$Bnc?x!@1n>m%Q2%lXJxJm`usJd(!>9`R^KkTzK}i(Apu$EsGtj#$D5Vd`=aD|+w>xkGxKQQ`b9V1!(*0O&Ly#y z^A}AlHO6|sQaaV;an=NMriymmpe)?;(c7DTGH$)C2*tCG#&XsgSW=8M>UJsD-`h*u z)k^fmxXN?T<%#x%J=W9UUwn^_(zB!0IL!K`8=6-%HHLvg^DL64O<&8JLkzQ{D;_Iu z<<;|wyTMzcWS!>`M{o0oeRZ6m_v=6c8cU~(dT^Ag25;=1Z5>O0E1Lvd%{#e##=!8ksQGSR-L>HQ#+q4-nX{*J~Qw zoE}`G^}Z`$hw1XSkCU2bvpKpv?vh)lb>t#bChlExNkOOW#d(K8llEzTl&HHv5?l~Z zV9?*~l{@_&0i3TDj{CBh@9fj562kX2htsP&lWv`TBgkfO1~i4L$5h&e<|%Ok_d@(O zuz-xhJx=6sO0=O2o2*Z;mTllI=CGn+Ucgg@olGx?@97(pc#G3MO~X#3tvEt6rHCG8 z*g1)Gqq5!)N)z>Jxe{B8FW#`t!>Mhftj4n}2(j!PaGjsr4cm_klUoP9sr15$A z42SF9S!DBBgKX6t_f>75P3ql_kvr^b+-TdQwA&(O8)>r?^>^LP!^q^|aJeZ#PkC&C z_hL}U!>xMFAuAgIktYn|UKvRH;vh`4m)=vM`1Eii;!SCSRp*5*m^b5s&-_pF{R3g~ z^M5}I1l_r-Lc1JY)4>}b$Lj2h^c>RD)+g08#JD)!h8b*Fqk(-1-qUy~wBMfE=YN2^ z%ya?&zfCwJ^Z(@2LeI?bA3iPH>ejZubc636-F;d>qdpa}i|*ZxYHiLcwN^~v2zNa6 zNb#lfzsU!A=e4`>TnY(9>JEw4!*f6kvZN0;?V+xsCimw2XdvJ7!b5w!>Q@oNk<$mC zDAK4&ZII%qnUkO}TSK~4#eKR~3%ps3J)e$`NM&z0)Uh4*e;mbwQ{Nn}-IvHK4aNmd z3s4=TvXsiuro>xy;O(lDpr|M9x55HawIZv3f5_~nMzC_ zH8LAZ>apB5&Q5=R*(4Qht96m1m?~i+mQQ;I0I8+Ny1=WEq>UF!Ts^t%4vE^w zXXG?c5LVrBDwNdBU_}P0%VYxG0g{EcsZ=f%8j(WnM)AO8$|Lpi%d(#SyLq)9>RQyD zlM7QrdnWBSUSg2xkpdh@!70f&=$bITBt_Ihoulj}H?E6}dr# zT^?uiZ(Q&C1F^aG;Mx({LvI4F7;w^Vm++?R`>ma<}2A zu75$*n9qLlC-31dfQ#8~Mr10X^=rzOsrnNz_AAjxA;c~SNzUIE(G02@W)BOc14SM%uy;$eWuA-qDi6EG&k z4|DVHveS4kP?cg3LAQ7$A76OsZw}6O-7y8Qmir7}!n zewetWf$Aa`2r=08aXn}SldDhffthOs@+$9$qgJ*IZFgw98@liZo#=rFd}x*%E@XcE zmlP(-MIAjvTPZ^jyFW{~jqaJB3rH4khOfqyBL1W9k ze_)U--mJ|acr`Hx_H-(p&C}-SF`wIfp7mj20%2jw^9iDvVEFT{3gOHl2#<-ls$-Yt z;C-a#<{Z;qfnbvJNrcrF`WdjN8~K43sn7Xh;3PZb;$`YH_(!4=XbcXSt{OEK;|O8a zr7#U7C$$6YL*p+`9`E8(^-3CJs)8@q}Qcd&1bDAPCCEt>AQ7Z zWx13|ebypE_mdc{Lw+np{^Y0V|M4D!-mrL+)VSuIa#ZM!&c6-bMtA8QL2KF(f^1Y;}~LQDUr9^@i&+q_WlL zvARGGS$QY~9W$xLPtWbLA)(r(GUO{tdSMy_7nUO_!ExgW0{*w%H&yb9b1`L*iZ0UY z$vLk$Rv|)X1rnpv*_JcpX#8b(rB;$Wwv(+NCst%7rINjD&2=smS z*f@trQPcm}a?;9mY|^anx>8?j-_mLMC!LMI^yWiVcLCN~xD_O(Iu*obs$?%Rw$;f0 zbVNQD^EM{|vkN_6#0iMmCW3t_EFQB;5{88zW}_I)vV5O_SuGT^zDOi!DNhWhRuaY~ z3sXK7({PN7n^|N(Qx-;QzBhZTr2xr2m|fF&K+I&I#B+>C%ukvYc!RU|nWi%McuYG* zRA6(N3u|hbk0Apa6p%w8^(mI>mNZr=y4|#GBd}Xmt6Hp9L;Cb{zOmai)!|2P zNbP9S^FU@U2WEiV{o@Q&DWT=^>$`FWS41$A_NxNohIJs_Y{`;SG z53O+Fmrwh=ufbJ3rW#DLE6#hp1C^1;zh6v0ScM~4^M6YmEdLV?otf!BMzqIj+p&jC z@V=+DW6%l|Ed(uxOguYru#iDPbJzax$NihHDS2K`2`=*wtBi*jq&ADkDq*Znm5toE zv!7hLIZSV9VZ@=ngzMt3lZk?KJ#2U9niCCHXPC4|l)Q{6@cXwXg zYiV5saf30WXhlflxJTk`TrIz1tgCu=YSGkYQqGePj-7g z{8`vt{EiGo!!{8GuKEnZar9~$ugo;#bf&s?O3}}>6O(bA`pG06m_hpZsDqLPL~`UcyQ zpacPtvPX~1W#i~A?LU+xGw#)=((>|+nc~el)}k4#4ZLZXr(E(9-)!blJeK2Ws!Z|5Epq17fz9w&hK_kW9+~*^7 zX&YRUfGx)TSG!4ldk(no`vw!M+RP3pCoVzF&-mjcFd95W@4m8j5sor<|;oAfsCo^kdUCjt-)M!DvjDcx!GWKAlg>W_&c=c?m-y3~nE>xdP69z8clHZVZ z^(@$w1%B9>W3TUaPZo^@Fc?jfGBbAt8FiX^S!t>!2q&3!i?J@SQj^(B(Cx!guT;Vq zC?)8$m`@LBe+KOO*#e>)B}(k*>1J>kWj@;xm1BTg#F~R&3EmISa6{|szepp-fxaJQ z{d{-9rHN2K2g5(cD91O9DvpR+g)*eT4qIWy>Zk#?3i6=^=QN z)0S!k(S3>$l7xj~TwmsLR_0U!xk;=f;zD8*(eww?H{KRX&$5T^2kBg%ncxSPoJLoi zV?3#dQO}36Lig9yQp`;IosiyBVm4$~f=+Cw#vFq{@ zjR9MOYQ|PYE!>M@4*FgU`10XI)IE;G%-p@35{>7(^vw?k+j;pa6)L_>zQ?pnh&$mq z1W8L5-3I4{laoOkmv8(d*vR*C@=2R}%=s)NPZULrNLX~sK*{{BSU6P54#zh2c@hS^ zVV48?C&Nky;E7Tcpvoq|dTt-E&Lro03};R?6Y!_pKO!5(qLTz53~j_K?pRR_hC#q| zo4v4Hq>u5`S?2{=pO_WBnL(h~*WPZc`yXGgz%{N(40ikSpBwaqQOG(w(geD!a#2ELJ_I$}%SLxQ++P<1x_y|GFQj_R(xEC^LhvFjs3$ts3RSLOlhk5jLP0$eq&$vdB*`%M0ytZs$r;wBul7c`m-8Jy6=*@M^Qg zu1%(Yv&qM_z#MZdTO^U$-$=sF<9GqD+R2fmHz@ckv!e~?ytp0Oly?AH{;8(j#^na0)m@@tWvU{T|iL|cFi{c&Ff|Ic&IGSR;z;n z_%t)xl)i4D<`$laU^qlfaH;;706&Hq6AVeK6Q9%JS9RejDH9DX-TtG$ZVBS+ROJ)6 z)#~>2{g()>bRn`B;U#CsV8&*<9jegr^aslIZbyv@jnzrcRC&PYs@gb?PQ26xDeQH9 z`NooD@&^Go5R4~_6wrO4#N1qu_#~WaKUeq1;{lN>zW&GWqVD}C(1VS$yT=Vdg;mJrK^V}`xS}812%#DxlE9z0BnRZ0=0CtdxUyd%uxw4>y#%d3)%hLyD@F-T ze)_@0PNs$zfp{PwQrrKq%*qX)aAQ&yk(JxDJJLBn*D^NJ3kUP<-w&Pk@^~lasO5GF zA@Y`pom%xbFGF`=t|^zBM$3fqqe&6XlYvgHx_nwxX*gTF^6KwzRprkrBZ>rww{D+w zF!CB50jnNX4L>ln{L1G0eLL)ct^N z4DeeQHWB5Ah@;nhRNC6+eB7qs-bAr_Uec;;@>N#gWtq)J7D`sN3uzuf_`0Y?gh4^p#)>pR8nWA*{J|L}v+mI*N# z?<|xtZ05U^X=>2jSdfeCREK)>pSMmXPv1LxiRy3AsrcB-Gbg;u6%=BS4{qMeHN8dm#+q~)GN&y^DY zz?57XU*KgU`g!R}u_JOdfPWsoKF`mtCmEQ0$3QFyvlH{ba*qXMePs1wh@yPQO;H06 zdY@s-RaVfdEAstZ3{IDsY>LsK!`SAhFE7s(n9nvCY?C#&l#&irYBh^g(6gc4$4Dd< zhoA3yu2K!a@>c5B1!}1!cwEKBw$^8yb%j=%DkJ7-(*Fc}_hh7L7CIo_c&^l8R4F=3 zh&JTtXQ|EP*LUVroKR_Y_vBl4({ape8ru>39%y$W<~83~yHG|6AGl;x*>*6{j52$M zDt*gs?iLXcf>4AJM4tlBdDm{>P3)W8N2qKF3U2Y%nC}-ZzAi?X2tZ(d(sjZP)g=}5Vfnhm zL^XvOx~4`NBLuoc_qT;HUJpdRC?LB1K*POLCa8du9(=Hflu&QRDn+P%%Abyt z15iJ5m*{kK&suhCQ*+i=JJV$=qJL54&uFu%c@PL7Z_HnSp9?)m%p6KINOc_!ukpJ- zgkbH<#1r-*`QZ$(n-xZ2LN%He?)}G2E0{ddRDt)QLSwkfir4C0SsGAf;3>>$9=mTa zO-IEY&=vFmeyH4dHw>{tgxMt{Y0EC1+R4W4>rJEUN6*hL&aSSl9lgCTPwZwZg;KU% z+N%TBvc|ySCMA5l)KV7lA44$T=Ikg57imay$Z?pg^(n_Y&qDZ{W#;J|&Rt94VknZn zj`z`rto!2+L`kXe+ak5H%ecWMh8U9kbV_C(|f==#4dQK+dNy3E`3Tf~Nv^`OL{ zA`<@l3w43;%ZS(l=5@27h`IoWBX`znMw{GyREBBer-M@G0!8DJ`Yuq041){|^tw^S z%n^gR*C`byu@iX|>}$h&2B;iZeOUqwvL%?OS>k#q7iIe7FKVOM_m}?VUP) zK!5K)J8Cgi8D)R9tbe7;_o$};gl7`8Vx2h@nV0wG@(#>hqTWpC?6gy{?%KJw>AeF8 z(wfN%TYx=~GiWZv68ELgt}C9`CfB0}>D{)$$VnS3o2uP`pum4-@UbekLd7&n)MNCXs`BW}l1Dn2$7Yficl;$>QZj zqgu8x2&Fb$)m~uO;d|T&xZ`1|BMnx-BIovorL}^g6Gb3eqmIAEONR9HOzvv(QUoi_ zeMZ(n6xp2X)85sV5_T#0_PhKCM`uxm_Z&V-`$Ir@z;GcC2VrJX2fZ>q^ZE7e0l%jV zi;U%QdjQu(aYKdlCMJU21|*u$Up}PH;PM!lTU>tyiOXs?Z6+NyvLeKq%-Jghc<^Cd(Q=p}>x2_lVgAz5Ut_J{7_;3b3P;TZtDyZ?2HlDc`xTPI3$Tf|2b&fwTlBHlYu zQkb&y4RYV<6D)N2r!flQJoO>8k>Srlf}?o9yj6I)RxAdJGtz%bI7&MBf@W6Dm|^A> zK3&7)D{gyCMms8Oif=R{#Olge7mXl3w146Y@>-L+epZ+-mUF}s;=|y zXmKc;?QS+Z2>Y8e(TTHNO-816ApEj!Eu3@`JgsF}l1|;^wrW_keH&%@>FXhM+#r0y zhHL4B9;tq%M{7%$#$-2lwszJub@gTPQIk1icboQ>DInlE?bhfOhh?9nJ@CXoNB&;e_ym8k8 zX7;^_beZs+x<8+PJfVd!E<{MYURpuDrmIiTpX&ZiZdp_A7T8Tip>$#d?#)&aSG^6? z`k@ROW^x5iYBs$*?CtDI*1}zZvh%YqA$aSk8KcsaO#oQx;&$+n517mX(}c|SnT)cs zTBEB*T$dC0A%JJi&ks0?YEdiF3x-^tGV!t;X7bmfjMFWeD*c3V6v@xb1=k5{0r9~2(D?8 z;QW?RB$Y&D_mruqx<>>ZUg9T>!_F4%>iA6WbY(IxiR2LZq@;E(GIN!^b!$hz@uM{7 zSp_&;1b)(K(Wv^n4?t*vM&OznbVJob%|25abMn^gwTTLbM8hzhA#DB*RU)}~3Pd() ztfmI(KPW_Q1LrQgUdHhfOS7spha;g5e+d1GWFITf!^C-@g=RTd^Kr$(0ONZqVdA+ z-8x8o@?-G2E@9etYq)l+ADaZ2xV&cO_w4t7_tW_c%F_b0nLs-=V3iqK%54sR7SX0+ zWA4!KU{5CqX)O%z1En@CSVAz}sGwr@!MA!#KS4M??I12**a>)$rHcs9{5%H=v|zS zf04a~9yWblHF5xDw-<=F->j;Ka}$zY9e*}DcJ04!t`UPviVh|PmCI=jJV5u{_^u(b zrF@x#byw5Fmys2+BYXLt$1w;WZ69p4gFb-q&=|dXs2!6JRa2(3*IThy_Mj9vbGd5~ zNPpNc&a}3-5!S{z8{TTm;$C+2p1;IrgZeUh3sMftC8Mq64@C#29h9G*P*>2JD%Q(@?;-R*NFARwbzb7Sv+5uQPOn9 zz1!W+KJUAxqCM8y3@XN`0SNib?3bSN{Tt#ipAu&- z9s3nw@9=dLENv4nQX9rbJ<9z*ns=4=l8UrwhUTLS*Se6ZGupZ&dOvn;6S7QDr2|t4Vi;IKbi*nlL^m$dH(3Wt%*I zEdKUo#%HXtCii3dAZ1k=!%S!9cEv@RT@qd{6m{;X1pK;yXL_U=QC!t{=%23ij&i81 z#wr!`0b6Z0C>2kuc*V-$cxXRB2Op92q9csRbh8cO~^!yfTEGU@>fzIXaNN;UfTF=2p+{F~PO24^HQ@%S&50PFu| zvPS=(l3dkl+m4%U2)?(v`R$%`%t-W~B+F8`S!=5$&JOKrtDa??)KUXb3K2_yMMy8T zyq!K!c@#2&5I5yEGHaJy#L235{a9MwRdF8Jl}i48)@ zH-~yvTpTsa@^1I9E8t5I>ZCIAaL)OCx?8t-IzASO)2oh~@?>p8%jblX18GjbW`cV& zom3Bs2zs@hdPQ| zkQPDb{^j!A+R@XLkk-WF4#-M*Ac%9}e_uN*+lhUY8lSA@zHs+*&q@*sn4DW0P~u7_Wdh z!k0yOD&<#msVH0Ja?QmZ=Sk%R(j8j8Ll?-?cdJhf1Olo*Sv|G*1q(|bAS~hoW(|ty zo7sI$xiCXA2GQY+0GJPcHkR`FgZ9h?z`5CNfA8=QW6^4L9wGb&7Mt}1s%@H=SnV^Q zA^}&df&g`-cM`9f`33##6NCzf_{7LK0RXYZ%%Fi5*UJ&pCSs1$Ws=iiVDG}X0+Bek zq653CH+d5@Qn6-a7xQAifC`$(KB-8hduxxfE%?Tnro^v(b+o!UeLcg2raoY|aYcQU zS9hmHxNTkS&f_f9+9eDim?9LWvD?T&8VEo}SfJ2JF z5;Id5s%p9fKyX>=zh#YQDyXB_iHwVj;q3jzpr5%cUqe2E56zv;rqYmO!tw@ zd<`9sxbV1w*?dcJcT8@`Hsp83XILii^y3D0tFZjVzN39=+0A!mh@HfATUM*hK@S*r zGSjeHYDuMHLZ9qxif>=FAZ4z_1UX(Rw+m>nXpaW<(~)w-RXroH6TDsBnQ3#XLmR1S zjrCx=CKz1^0*0l*JP1R6BX;#neT>PXV_#bz{@0nh>G5-m#@pNOwvJV<+x2sN@V88l zr?n&FQC1Dar>h0FVZpS!yCDn79&hLK`eAUg6>gPRySt5TH>;PUw}%+CV$)WYKx5P= zO^V*Yd=!#m1Xf{N+?s%&1}OD9xW#aW?v;%igV06JcG}u$1{g4O^$q+Y`q9{zWTMBr##?+7BLpWpYI`zDt z*63k#q5f$3yB7$b)^DaY_UdYt~0+SSB z>Dpm2%^xH~+hsP7sWTx-#>`mlahJ0<7E57`($M?lZl=2|hZBExmI@^JmnLOak&4r|HHoEk$nH}{|e zs1t7G;gD6_aD0^k<&Bt?ZV?7!r^Zsy*CFr4VvaDVU7sNLa3fBMQr4*=AsEqjN`mZR z%HAm2vR`_V9Cn)*OP2R1+TGfod=iXz=_j^OQg|+~BW|Roux+%-wZHc!8a*Cweg#p8 z5px5@e7GNQX^3z4v4xWj7rDaCq{}BaAteZ39lYJ0-#i8lFV^erwg5~Pj5P&i)Q-yPfZo&1zV0(8*nQ?*8Kr+Ofh^l(5aSKN39o| zR_2b~lLYZcU$i>~$(#>stT&phjftA=FvO?uH-Iu?-jAAjBcP%C@O*dnR?pIG;a{-{ z;B{l+!zdyB*-R0_1XmUEbEcLHH|-{PT*@wqdx_ATS3}shbOuwAw{5mV34h{20@}hG z;*JBU^X~R()cIn<8pi(JvJnH`Wg+>gjI|rBe`OuogRY8U$N#ghtGyo8RZcu-==$RD z5uNug-2x)j&QPeVS#_F)g1!}y;klKjp+sP-RjX>jkvSwP*Nm^$7F- zgp6VNPxJ3%^mUs}k-P3+h0qM3s%E!D`$fL`q@ijH&Xz3XFkq)&N_ole1bJ+};O%+l zYD%G?8pLcq6g3#;*1^@pel?nikrc`Ui8e6Vi^M+!rN`t)+m%@E5H-CSY_M%8C@Pyh^ zUNe6#1Q3n9#m36>V|u#&jC&wWcXBw0IdTHvCHl%xpPb59str1J?clQ>2b;~F~84N!R zo65Wmc;~95PLY>n99S!e_APeO`1brNCA5e>Ts0gxK(Wqe*Wbq7TsSafOH`fiz^PAH z9TPZ^!y7Hr0w2c@69YfMIMcMUxwVcnbr*;4|D6ljZfYoxqS2lk5?#Ivsuz3O)6UX{ z)xN#nTS-u5@#H(dKb|jVwO1-_pF~SdzPE{vl5&uyF5Y{2#4eyl_Sjna=nLePnm!K7 z;550@_i(wh^mNs4b+UAj_6TgA zzTl=Wb2;(7z}@hUntW}A_m@ekGwrdSSAH_%c#-fSAFCyvuZHB)yPcjKViUH$6#QgDga7cL?eM(Ma^MEO{;DmE>-Zvz zJF%V{z*t-+uqZhd_!!reci6RuU+Jbf%x+_kjt{_JOlLhmYl?D_M&u^ z>G(*UElFM6uDgJE9rew`LbAiD7Jb3JBy54B=gGV>4O!ntisIyV73+Jm-$l`5x(g0n zS*_U%g$F)@A_Y2_$M_rW4Wxfa!s4XE4iRL|^`{IDlE~tyz8g~Tqf~Yd=XdyEle{J5 z_N4*|j2JnZ@*oqsC_lo3#W_P$g0Ad6wI^#m0rjE+t)9s!NS-V`9>f$G;2z}>d}G7Q zDjz9DI6u~!o1=|4-S?8;*NivJgOCleG`7A^-=V12JIDdvzl{*kO#rg_d`OUe&a+tj z6og?}36uISs#F9kk9MJvrzE_H2*_P_rv)lW2-3f8;~pZ~!_3Q1WN@;yt6b#>B^*UR z1GK(NDAazh!{Epa=o=MnUgc#}oENob1d<71NSx`B*Qm$jk5TBQ&7nAD!w z6|K3Su|mVPVQX(IIh%>Q^HqLMMb^!3wy7036-%Kvpsho9Uc(Tu#k(i~dA_M(gM&I6 z$`$K74(mG}1EVLwm0Na*#*92{I7~{hm5fQGVT)-n*+ObWxWsX0VBO%Wyk|O4?2vOt$`}$H4-X2Btm_0$4%1q1ETL)A9aP;`B&Rn3vTYGFr<9B{zi#3l zSlK5vL5qdUOWAF29ZXTxs$kg{$*4*x7&z;5z->}SYJ!!%2Su(mw}IuE!BJT}*xhu? zrFRY@hzLOldvY+JqK*u9~ zHrBk7f^_)Dw8!ys!eeF!Sq)vU{$vfM#}sBzo~)}3uLJ~3qt6&U!HE!H6@nj#bfpfB z4aqXlorgh#*0_0LBXCyBRHiPoDh1*NwF(kC+o9q4{)Z#aR!pn?+ZJK38}E!H4CMrj z^UqLEn83=Kt8J#qrh`)2G}~vD77zx64yE{bCJveXI4VknEQBW1EfC z!#lARI@a9j?kD7g@`c%d%V+=Nq@9K3|5Zc!mArP`YC-Y2tz8qxoywkPn7nkzJQuVs z$02RF6q+#NkS_@qGlNN$tm0Rw|Gf0H*-OxvkYHFr$G5YyquFiOL&HOxH-Pym7$ynn z{a3I>tD{5P^EPUNP(66<(b?7$c#Yz76nS}(x))8JZGElXs#Sc+^}5cKtW9#c*UF;x z?eT?!EiEcqNCvH_=SQkraZE880O!&!(cm-%!J96h1zgCewGP&ClD)t(>4xMqvr^Fj zi{VoovbY>UtX*$cNe0;%MO-yqy$Bm) zB$h5TML*<@-6a?@F&;y~>DUWmGI1YZ!?{l3Uv`xyyP2+#O%J>PK7z`s)^!Z^-P-&` z3F%}%-4feE1Wh8YHWaCx5p40=r495;S}P5nmMXaqgQf|I;pv#R;6&WNfp4^jfB&ZCmo*_ND3My0hsOn zy*8W(z~!mE zt~pS{WwyOfOd$Xz9xx>e`yxV}o(vt^q5J0Jnwm@g;y}}Wy^26-db^E8VH$G-@{QF4 zVVvwX?i#Qj1060tgw-ti^uRSpVe$5+`XGuvqGw@TAFT;hs?{J98b!SpYOpW|%U1DT z8w=2R;bYR~KTr9o0(<;BP5eyF6S%f;v4vlIxCsyf~o-qZJ<;B!0@iAOh^>Yjbu zw{7S9U9YXLhxbgPEAL>@`RNuC$|c>p%omX*5_tYAzJl>h(<579v$UO@%!%d-x<~`) zTx!Ka^g*-A2ZBtQ2!z#OW$3q=r<(7ca$R$PRa%MsorLm063x?xG<4ql;bvss3s*mL zl>@zuC@DnfScmhZRdhd~zOrPX<#Tf5veDx(28SYf=)xM!C@bz}c?YJsQrul@*5&Ce^|uO_2$mzb!?Q ztn?^N(TraS`~Y#81kgku{FoiKQT(}c;YMfnJgrzi0fwW)Q_)>7b%i~ytU(tx?+l&K z-VRBx4Zi8(rRDkr2Mnh9|`beeHM7V)kOU^xN3YipkA&bJgEzS{TU zyXQKY@!53;cziG2Q$h~nrd{_Psv8&iJy2DBmD_POfAtq+XqL)_%yzHwQWl$@cS-^< z{=oj;|I@R_g*t`ir*iua=#vPAAO7ke8bhG^My2D)Bx5K6+nlu6#?w@?fVdQEvDl^| zsb9EqTclzC5WTQSB#&tKgJGPd?GN!sLq6W0`3usFvck@7i@`xJ(9S8*>Y#%$R0H}a z98hD5N*q@UV}}^8Po7=aqK|SrA5-vC^aDPkt9T}eXW({so#>`!{i8S@;&>#0RbN$iph#8h zw>bC@0Eq-BvJ!x~_t^VU4^bS^#X?>wju(I3@UdqSFfC<34XN}#MFVEUOVGZkNs^LB z6VgFE_Bf|Zpf5crUlX@}`lT@fxKcR&WHXO{t1d|E%TB2RUYDcy!&BP>4Q>t)p3}N( z6vOTsR;YC<_`FuAtJN?gaX*XOKg`a`KT;}`xS^D9kMS>e`0j8oWEEWLhtfipBGgkl z@`(Mhm64N?s;gW-Ym*3OyHVd&T<(mz@^~MY!+p@W>WHwY5161V_I{F8?=tQ+LH z@k@USK54E+F+K z!7MIF-f+sxT&>av9vKEE*gGF*Pw&G2ZyWb$<~A&_Uua`59TWEWx|Th%AU4v7mWRTk z)ew~H%9XQ+8P3?iBLmxPz*0i8*qZ6FZ&++^SXmN``kk`HmnR{=3g8oSTofx z-*8tJsKXW57}s$w!x5<)n3yjvBntAdz6Ba#9e`y-Z|GJ+1dvDu?^TGB6W5N77t~A! zAi8x2n{Vi3Y#5sqs@uoY`JSlcw6yPhcXP+!(8QrG&GvPPO;$Aari72oyO;6F{7)eL zCOf)RMd#w{m~!q{t@gmht59svH5beHMCNC>C%iTB--J0uD3RHW6D_^xjCugd9Q{fQ zMSb~*$Y|_s><^Iw__Jp!S-YPNs7a`Qb~*f82pZII7on66HPvgnH`RX!a=kGxvhX53%f4i8B&{B;KP z6N>>wldU;Vp}n7Y)B@M{|0U_O{ZB)67MB0OrClpq$7b-sfA9P@u^q&u;FFmvS~OWz z?3k4~2il2`2?bZ$<_J`JnI-36&o>Ovp~)=fi#}!xW($6Hrty)h zN{P&Br+vv%qH0?6iUrk=1mD>QZCtekyqy9KbSP9r&& zZAO6Ly8TkAJzl51NlcRGmVeY$r5c59y576mFkL5#JmTztS(wMp*9E&g@oK;&XQ{Wn zWg7dhzyh@6PIDKitU%LbP5WkCX+}W8+=%Lqnp^KcN25+Y+8_p)@S67joDSWOBP=MQ z4N(%4w8>paeAt$Z{c*XPipZGp4QsTjH%-FhMj_zdJZly=7?03}-QAZ%H@#j3 zDZf&!&%0~(1{RzY4#)J+U$>TrxMzrWpx?eS@q?M~f=VWa4!LFT4GEE;JmkPiWvn16 zAu6-~v*Ht7l`$r-J4Xu@eOh9hO}VxpI>Js(iBot%JwerudG*9fs|Ppln<92W88Sq^ zRqmKCf#3tZ8TAcq>cyAgVwa+>Bnl%iXDR>_z$d8y;j-`uX9p$sl3{a)jE9D7Hi7a}RZh!26 z^|l;^D_;LQklfUFhG)iojw8|g%5&OaI*ZPD^{y(iM7i#($t($~5d8HrZkSC4EhRpIg-O zPkXP^Y5AeUU1|dktNAR{lorDS=z1d)`udbix_?dXZXKR0-uF4X!M0;;U*7@2V0cbTYqsZk4J{?yJ!KM9N-m#@=XR}H< zaX)KePzw`9lp+&N&yO50^clX3sxBa}>WRm60;=<9uYr(Zecs!8W{mdhlOP`w4?Fb{W8u zx!Qyg^Xqnlv1*F4($xYEr^&(fh3YkKf0pk|8xo}Qms~`ZLKc<7k3iue_Pk#qyxr+5 zJg)}+a&+$mDn-`Xuhl2{Idh|G4CdC6|6aZzVk23p<7>XhO`0k)JO?uf?Oo~k?04`G zrroOHoRtf%$6)ct(#~3T7Gk=Gd~3s~#Y2d$wLn@HhoChWg)@&Fk^=aIMAz{`&P<$- zHJy=#WJ9e8cu*->IG5A|_s6fxyC#Zi`SL7D-!fbFyt-*BJgx1KpDKB!(G$(y*}EMSSD9X;TMO4DYWN_22iQvp8CiWh)<^ zB9E?EVuV>`QyXk;Shwa&gHB@c<=m_e8Xg}@Q@(;5ZK+ceN(YLtTu)RL&E)C#WW3n5 z?br_mhj+~t1N0Ma`9af8N&D4d|5Lxd2YTr7)9t$+`qW8knky}5pi~nHXpUYErc^zBZ>A!rE}+o3 z@`LXuH|h;Ee38k#Dm&kiNEu&YeNLZSN}2{!|}- zN}BO@{1ZWrFQ~#<_s~v!lw;*-&-l*fCX3w0S%zX!62S9UDG!JaQ%)m7cYwE!(w%2X z>IAl*KbXCLj9?N@@QGV&`9FOgX8yL=S}$5eK^QHlZ=nAseO+dI2b#ITDOWk~Ll~3l zIy%W3TN#?;o5^j%%1J_gnu}#&N10j65F{;w#&2?UF$4x$2UA8P)?cx^WqSEtHT}a- zzX;dDIElQn^tOBdlxO*DM5}NYK=0AjIaUbk^1?4N{BE_;w{1^AKrmci5QgUtnBSI5 z@MhF092EeNh)57fG!e^C`C(&BW)b+mVCY+NX#cl=#Q!w+!NKy6?g(+JG6{=}h`kRq z&a!239PxP=9Et8pfgq9Fn(*}p*VxEBI214+J|hjRbYjAFsI!9)FTHo9vrzKRFMFl* zy9E@!lH1oQ0H5q#+*Yrg%LFKTC7F~d>T1&+Ke?St=7qUOGY!?M-2u;e-o)s~4QMm# z&~Iv+43-Dv9W=K$(tM15@_;IYba_nvaittyTm_mmK*GB%CCee zj9t&mx}j+kQ?gE2LlQ+pL)>leZ2<^yVZD&lGOHQ0VvgMMZ*wt0MS9{^N!#nZrIKM; zVII3v9n^wW!PO`b8h(gjchiuk6gHFT#>`0Y4rG1w*O9ZhLwSOLf% z5{`gm5pB_$T{o0!kEB1S(6992O{)!CTirbs&$LKHl~l>G$f+tACrt#vb9(Cg-qWzc zU;~ACk}J+j*g=?oKc53Bgp)p*X~(#1aDF)ID49nw;kZmsSf(v`7|Sh5+`~h=7~?OX zGP(*RU;(o%gK!AteJSS?wbD067_x3h3y>(d&4wiXOVQ{`4W_h=^&z`c3MhR?zyJ*4 zknyOP>i`cu_-PNnic@K8Tlh#_Lc-k84;W z;$b@G@uubQq`d1cek&0Avu3y z=22xu&~(uTeJW#&ffC!3Y#2$12EX)*)y~3Lc_T(Nw}hBmoM<^dFZ{f*f@(~RWSzmTc+XL`nr6=3a$H%~WY2_~pMh4wcO0s%kBwIeoa0G+$?oqrO% zS$EvhEA}N24rb;wV^9+e!ce%FMMFrw926nkMQL%Ij4H>9`|YElPqpSN zclJBBcB|cCr(QkUf3VJ`e-Qb9gzJ0WGNmY(ZcXcg#c4AjnM-fxn z22yZ|pr}@>{F;Vc_}%6h$as;&;2J6PM-m2T<~T_R(cR(_-}-zCydN&k8>f&r!I_Q- z&OBoa(=E)(ru>DqnKdllzE4%b`4Z{<0^&jie%V?+7^p;2H~0Wh>Q1vzV#l*LN{3FA zxP4AhoEF&5FDB0|>>l)~YdN_7(tL3os5sV^=;x*Hx~Y+ z#$4=vmer(7F~w~Yi{q{Q7|k|us{(mH7m5A2N%qA`*qsralh=CkPuZL*S|$$|4q`|) z^J3?D3h?CW%QITI;?s8IdY+T3;;?JNNoLFI(ZLw7t~;jMblKTNG>xXjT7!w=RY{ml z#^pTKskS)a=-EW0o6kwo9SuL!h&*&;elAPcEK)tL;C{4Hf>{dV$ZJD@hKygpZa4^E z7Zhd+(K%R3qO+kE>Z6&E)!0#$D$413-B_K+GI+t^pIiep`2_7XK~6MPORY`BC1Qh_y*>bu1fA z@Jqe8vwgfn8R7{bh=9nmCot~>kM!}i%qo`gty@DnD`gWMZHaUc)9pskAGd_ zpdyHJg#K_9$+$sKrFM87#l*R6Bcuna;d*K9a0ifn%?J(@+Mikh3V< zEI@IjoasD?icvw=zhPj>c0>H8Y`L+2&Y*%6f1Ab|A>#i9)jHQe@bx3$7cAO;v!wqC z7sbW=4_Z{3I>3JOuK@N&<5UU9v-4ME>LDxe#uBhGW?0On2n-K`Zq$Wii4GaJ6VBm| zOms;rsuc#6t>D5f>`89co?}QK2(sb3L~!Ot0IsRo?FIYVFET4ZMrkK(+h=z_Ig%l% z#_5{@@wR5&IxeKWucPz9rwuxkaL$_y4hF+IMRC23XHM0$fa7P`M&Y*Vhs<*OPhoNd zXV1yKx}`9Q^$cP6?H6Mf(Nd=DyYXIYghj;LtuO;l+3D4tkB56S$FS+3qr6^D-`g7; z1VYS%s1?g%wi+Ilkd}Le#fj>cH$sU0OpqFJHXH&o0igde^FNwGv)EZ^vg%c`ukD78iy2*x7-=; z)hcxEfeE0zVZMW3OXi7%@l_D+i~O{tj|N6H2yqnwf_C-NT1U?G7Nl5z)z@NPt z%WoWY_~$HNt190+%Nc(R+}_9k<~%A{UV(7i-AefB6tUvCyn*Ub4+e>ff2nf|A-Az9UCP{u=qY>4+WQE&N z%S%!#x7*L8dkd*n1?()y{uXjMF0b z)K&8IY{W8N+D^;sv_Ntq@Xze5$orKLb~f8Q_=r>~@O5ov;q{eiwh?z`9T;eH#yy`z zZS8=WyDXF@2h786kH0|r6L5+fD0g#ueZZ7fPtV`5=>c<2-j_~Xlb}qwCo-@3D2$9L z0tGS`)?iOcoLYV`Gj2^0hSZQe-}n>?o&_@>CMY6Pw`ve=PWAJOE%4)@T|;lh8iWaT z=yG}E#&0WqVXJuN<@o9NT*0BQQ;&>QG$kB6qKH+9w~2!G9uG|dD=L#B*vT_Rw1SS!$tO%)UgP zaByQ3-_0@~{9Q^muHQx$apeOiaj|Uo8LlkQLd1%+&rq)OrMBW~37Vw_qASYIxDtxYn zjYGiNwD4%{ex>EWj)EWs-jzmz^cTm%oY16+a!80b<0LMM!Xk z-JgMev)i}G=H==%Tfc-ia}s~Q`ArtN6j@b?B$%j@yPWi++6NG|A{1x z%esN{kzAJAUw?O1XoJwkzFRjAP_grQ&uP8V=!yu-3>$c&p?;FA?fwCk3|gn!1URHZ zsnvdw6&>SU(bG3Kr*dTlTeCT}#j0&XZfl_T9yxIksbE8nM=7D{kNx9%!tsWAa@w*` zu@5xfCZi=e6y{=-dYqaXM?5@>1es!m#HBJt=?gz`nTlXOt8UrU< z7FUDW@Hnq?Q)TeQCRx@L1+Hpi;%ZkyGnkfIUxSS;2Z3>{Rk06j7prSxu`-4oT?)>( zVi!+TDj}c*t%8GIg7wNWipDIT^1kzHy*St75J4Z|#2)Jnaagy{{?#J7fE=JKm*oZ> z>(}+ODP;#-Mb9*C;DDJ2J0>=aGuEekkh3(X9^C?8zJ9vkyq@o3x=R|YT^Y=jKo?fY$tQIXX52T9gt9@2R_kz0`v7>NqOxF_D6522b3L9=!v$8gzx&`4RoaLtX`Cizy z=-RdE&nZspq6eNL!TH-*tqO9{WNqhkjV+~tq9f$^jX>d+2mkKrt=~_w^72!olq5lu zT9{!a!QTX>3xxY~w*5Ww93P_z>JQ+B=TnEZc9b#gp})ItxNHCqqFN+R-= z<%szusgWmjU%2c+&WS#dE$H6Cd)4Y)8q9fCWQ4&_$OIa{ly=o6!8TT7CTw zBcK?gRZE^$02+4wz=IA~ob$Nr1RQC|gnNuA5)6rav%y@hbz6sD4x^e3{lyr!#j~A- z!u}>R6W3zNQ-w~+tW8#d6bBx@gLh*+)Jy{M=*P_g3LSMG2)@%)0xl>7gjLY>y=~E7 z>>fr|*#7-kF`Z}i@VA`YzDkwZ-yRux-#W*N#v@a)Rm1PcjaYna9sxboHO=+3-31*r zgtzuT%4Y*3fs%zxFGM;k`1Sli(m|m#{_{`3%J@HN|5=&-5joi%0wAK_Ek+*KlzsrhUeadhcc9PpnxENi6_)BSGm z!vC;QRp&z?_4FyJtEwp+IW@r#Kx9kY63S^$hNO^CI%;K9r%Wj~AdCjqYIg}<{|RqM z4}MsY30S9h#KaUPomfjW|Pa^1%bf8 zZJjv_fxlL)q?ENX`K^yPtjDFDAx&Z$Wk9H5t6Fv7P40u{M066*Mpctj!YcKp*F^=2 zk*#ZT0ipE3X1`r^lXN<}XFN*otC# z|Ixsd=^@Kf;OWf3ccPX$l*mQLV}7fx=5aP7U_)hA_CMb+3){bW^#2Frg5&>UT(Gk< z{<{%RYuhCNMv(rMVsl9158YVb`pXPqOk8tHT9J$;rQFy6FJ8R+QP!1Gvj`>?;8(DB zjhBI{;XYG8j}V`Zd(F!-`-{$t$rgJV^C`|F&Z(Nn;jRV;kImoC1Z{7Xt@fzbA(!bT zF0Q@f#tlVnsKHK>iZT$H*qGK>1p8ce4lc?Y?zPf_cxwklErD%rXo;g zR8i3wlpYPQZJHgck|ph4Ja~Fpq*!d+a__wQHKsi)3O;-NJiN0_)1=p>vF9NO2Ri#1 zB2)|zL6FH_EKz0q08rE<<8tJkIwxXbOfv9}&VJOf86EdbGBfM8dEvihH$4KEs@y$ziq$!f;D1l#h;c z;!MLa>O?Z`k!eDyK_obc(qm1CkVXQ~p|+7fkV3VBAW5h8Cm@H7%b_$G-7_P_0^{?I zkqd4awJ1f|8%?W3vs-`cg$7{bio}Nv!BCAQvTV@**^Lh*GzDb@6P?=#Hr0?w z8;N(7C4AG7&twd|0?9>OnsZth3e|c&zIz68PdZu;QUe%fT;-5g8UHj?FPWKkmM{og zN@(?+6al6LUC4$%roM!Cp=bC1JQSMwuQVPmgp|LRc!-+B0-gQ)F?* zQ<(Da0qM+JSgFmDNK+rtnk8gk(fN`s$pK>`_~I*1l1E~np7~@s=s0C(i1mwiMUugu zl%?R1?dMrRg;Ny-?;q4rNlN_Ew24qcQUKtDAW~V$uR^6r$ystq2t!hPL?5gyL{l2% zHYoXI^q-&%V4&K#2 z8KF{dG%zu!Ax-4fm0rXYh$@qMl)&ScXu6=$jd3@ila!RLeiH&30)_mzNE9`Ts-!?j z?~P+(Nq;O(V;I!t-#EnIgZM!HtT}#PcF7cL_P#g$^Os`#F^6YRr_b-x`_}Y+)$w-h z{ps?|`sthI-|O{oI9{+_Wb+62mb*?ey!4AObc9^(c1SKr+LJNDvI1ZT`{x^Si69^V zP}lpbbDcm#U{eqG=zRF;*r2B2DPr>aR@$|iqo$&PlCF0soj^Tc`@6${Pp6{;bn|)Z z_$7Mn=R)^fiZ+-D6P6BM8IqGsEd~9|d&u16)b*rI|0b0F=3i&O!Yukahg=nheMf{)ji#e0gAj5%vb6n5tH=F zEuxA~i#ivooSCNIdc(nW|E}jNRd_#G5r%j&uy2@Kaw^Z~`ae z@#GhYU{6Wwhrq?Bp&mijA_m~%>h5V-m=41<-9de)zM=a|S%0(8K}g0+>`cRXv7&4f z&Z;WIneaTroQlGWmSSRD_}zOh-X_5}D)S()u` zZ>rHJtjd@p;hG=k##9bqpZU|u@iU+I&QuM*KAUwWWOVv|X;0WR(C($mzbKMNOsJ5` z3EqPs*V|QZhoxUdp}@&2|3b&suOMolyXDTC{kxeHiePu&>kM7SykO9t(cWMS?fuv#X_Oikwe%6!Vv&8<|` zwTlfZuO9RlbtBuv7*2EsKHh&BktzM?;IF2QU?%)nw*8s2;2}%`8Di?TG|iB!_d?}6 zApCyB^T7%Q#g_dRW8i^JiEuzBL^wbr1G?y1rbrlCp*F8yL_UTtlBCQpuuuj47LqTp z4I%>;o_HwyspC4&RLCST9b?40ll^TwAo9lhq5V=*FSp$0f5$lm{`(>mE^w7eeScA; zY|T5v7|S`ogj6sMS~V{Ej~39(seJyUbVcG($sXW*R`p#o3_+uZndmrORlty|<$TTqW08@Y(|$m9a(o4pmec<5_W+!Y%;Rhd{S9<7WnE|M zll$z!s+MsX$dm235~hExFiy7N3OBogN=~>b4C}!$3rp2|fh4VSVEQG;ek273CHk;y zPSfF(mdEp<aBxU>U$kcz0n@MX7Tl)3qB2fIOXr-e(b0kY9MJ)kDVW(Gnfks=Lvp(cV68e#@W z)}wThzc9*0doZ|1U~DTP=i7AZ$7CDnmf4kK>9XHL9BpkK%bHM#vR0Pdlb`GG7_DR# zfrPqV!dFhTM^0=RhI3V(iK-$o-{ey^x8p4 zl5DzDaUc}hwO2!_QC%~A_x&8F+b2{*N7h#~k^!%C$Z$xG2dHK0XVHmiHVc$V%aR!R1S;AXbZIqF6WkB2&=Cc&z*5&^}s9_3NY4l73*Pmz7n zoIX0ZNcpoOsP_&jN{$knAnYzuX!K~Gv1C*!h^B}+0P}=GEbX3Zk+9=AWp{TyxdsxB z7)v&c)49G-S3xI>s$*W4$IY^Sy$Vkb!5ZOBmeJxQ(jBEsP04Lz*b3E(bMkFN%YwK` za@lyrM*v^fX=&`>9dB8B+%q;k`Mf_snIQy}0dKYoaA5Zx5dUZZ^^UL$IH=e0?XlU$ zf5Pa#_TJKUpSGvV5Fl7ty_kMtEB0KxY~$GSZpRG(rg#PVa`rp5kN+en0(%Brx0`%( zoI?$HVD!0;e$p-7WMA-obr(=BvP|gXcNx6*`C??B4ZQ#k_Uv7L@oWP8*SGB90qxJ_ z8c1?zcS|1*_VE#)M_c4Hd6vq>XRl9=KE91l!*5Uh8_SEIc#QlUAlVFh3o1Vyo>ws< zuG>1d^bH`l?Yq}^g}NT2#F0+a_!o^@NP%bYHB7pD~uqO;b*}W-9ZnwuXF9 zzcqJjDX6}8S?g50t1L6DcK;bR@&nkqUl?>ptthTel&K3WztsZ9bKc*a5t1pSP4ud0 z(!#42D&B1_wFufMhUzbWZcO;?eDfX4kc1Eu+i#EBfDVhnxyX_2-ag zWKDbtiYf}#^?kKu{8eQq9vnGWU*yXRMcwCx#w~d(C`x((T8h5PiU!|L=v)PeZ=U+~ z3bCthM`n6W0u{b38FR*TSS(_UZlTR%oVg;NfSU|a-r~QN;kI}sw!OZ|Cp$f8+NEr) zmB$Be;+$~It4I^l&J=@(3_zS8@9@!Fv$X(ohDxeO6*5r)8A?Au3t_wYE*juCl`Xn2rpy# zxrE3-8rqGp-a(eT{8sFUt)tc@{mQb&-@J}nhS{~6-m`*09M8B#fgD0#HM}x&@BT z=h>)7x|@6EFW+d`m0CiazIv%Dx#>?*(qacMx99g*XPE@ZP)6(3EZn_FyUywY^-SfI zZrUHbC6j97zn55XD?}JukD(T)oa8=b0lg|U`ru{J|5IMyQ+r{^&uGSQ!D;b6-*Z&) zE476!g4xXW%hUOuomGC#nLaEf|DMD3@sHRy`y*q9yd36qykfeiqgx!CoA`9)ByQRf z+V$i`9|gO=!+*xB>|Fm=?V#dj?D{V(SzVO_H ziB|5NIbNM8HWr$gn3&RLZFmeh7`Pcx7?}_zQE+AZ`5NF;v3d!^V+=`pi3o`aLNo-m z8}FTe8W{aUq<5l*vA2O`K8xk1!DE}?=8?;7K}v1wZ#RYK_pNs^Q8-M&DAD3Qhn{Zp zSAf%j3Hr#8T>j%*>fBBFZ9wTu#o&v@z^f7nXy@D?)~zptK?r^kCDrH1xj$o#bIW|Z zu6cs=`{hZh9g?hu134+=z1$8qD{Xl^$}Zv(4qKVoDSX`ITs$7Gveq-lKj)QnSUBSK z6&p#|d`!+q0=g55MF;h<7(IRypIaV^2m_%OVp`&DXjdl|0u2IUro&ayf2Iyh*lZPUm7Oo#)nse86Y1K86$JL}0@A zDfSCqxc6s~d?Mno+-*5Id~YJ5NbnPABVX8T?-00USQ@PCXEBVP2OTeu8>GGc1|Z9S zlcr#3Eq8PIM$|WZf%vO17N8Kn09?(ODA$PRY*e#{rYFm4fT*mv<5e7B)>7X|Ju36r<1waUjyC3KwO*FZBes?h1Ok>B1*Z)Anyacal zVy9U!cl?_$qW!see#@0Bhp}-^55m1woH;G@xUpt-&-y2t&{hO1R_p?HuS=L9{J_x= z2iXIE^IAR}PV$4T6pQ`D)OJ>W-Zr$8(Py>VWx=p?-1;XLP}QT8`OH}0<7u1qdf218 z6;Gl>6J!E+tieGc&F3JO8?!`{i1pcQIWfYl<$*Mm6;BJboFNEMF$7o1%kJ%O*!V)=Fov`7;oBBJmOR!U}Sh}&y(vr z6?AmZnS2S4r_fpF_v|tgdEY=eDCw@E$Rjx$vOP0%L|5>Z$ZBAB8}Y6FG}5e+pa8_S z=5L{9DlQKfckNtrzNwJYkSIFxoO%17geY|oB{P<5Sx8o_r%>FK)-v@B-01*L=Q(C0miPMfN@GWF-yesbuAXQ0flne&I+T*$n*2DE%=u{%8P^@^N{ zf;iTBR#tN3g9fZ7b{CSkUx^6a0^dO|tOmheva|>?hN+1=6Pb!mPKXM zdPvVNP~@{Vu#K6;!(wrBmiC}aq5%f;dcmzPQsTaEGQ9J&u&4uJ6=f(~3p)f03x{|g2Hdo- zBm&py9``Ih>Cz)L1sYR%y_a<#8GCA;ogZN|Falm62vaxV426>(2bF{7O(A&ak0-6@ zrsVlaX{{yv&2V9dd}SXU}+V!LgcO~=~Bf>RT-g?r{g*1GAD@D7!mHp5O}n1RWw=z zRwUT*Z86siK{DCS;9pt_5<;m&&~wt<^SOrdutv}X_jNMcK^Z^y8n{IXJRTbOAy00M z!$dv9qBJO^Rs~U~;Op(n98&(~y}`RC{xpsuKs8}1<^t^*EDwc11x8#r;ej0sCR zZU!0X(k}Kv=e&SSgEWEUrHBr7^NP?u^m|i?JJY^?4M|%y-3FjAG59e-nV2b_&e6fF zkHGQSdlyRsDpjZYxlejWqCO_YF>6b-N+C0GsmDo1sc&b41wKIK`LBE|KPPa%*`3dt z7nIzIZ{nu86<>wk?%QC-x9Hz(P_v#czW{z*y|#)!`-vREWvU(asq$X_B-}0~TRX({ zj4S}K*EPKOk^yLFmsA@kPN1FnO0u1?sUK|IFtM-Abu3|64`EnC6tL1g1ErB8E#|vf zEw_&YBV)zjaeg#~9+r1b3j#1q%ffZplq|u(X(Cr_MF>_2%X{DokS|LgNNQevA`&|f z4E_u=Lpbk+8Fp1uwPPK0vcKqLyGUd!W!$k4fZhVpGq@lTAfu>t$;@ZzS zlN}pw6(aXT`a)penT)ZSCf?9}8x^!(Rw4E{VF=Q9-5&9NBlVYfHnuFN!!6%VF3ece zDC<(C!-X=Exh9G0jPc6RvjY+t1C`uQ>CSeWez~y_qwpW$iA=PtO+)mNRfj=R;z(|Av~yhaD=!Kl zl-4^Z%tG<+D+?clz#@zHEixw_5{_lIkJwPO1p=FBBKOk7@bs0JSS&i8Ko|6|Yte9K zfta#DpH`}s(?aK*92j;8j=KhV0$Bm^!yo)uDz(|8IF7-VgsXn}lYF#+mK_RbgB*h~ zpwl?fUhDr^g;pTlU5MAkoALDYZd=u~q#AuGYdLoz5?&LY2c|q7o_9ClDH)=w;chn} zG!4cHLqT_fuyo_~9eRSP8;mlMf`ccXkxdJszF`#-IDE#7Y1NeMk<36-)4Y|#YjyaF z*cgfeA?bAMbqQrO==MDLI{u+4^|5ytT~^wWk{*i|?$lUJ+Qt86scSJGF*G%MWo;{Z z7CTj6OXzy5eT6UFm>(spsG~eZUv@;kKxan4;3iplF`bBOyet0d!8s5V{I}Lb<4UF# z=h7SI)dm`59qJ6rIZNLhBc8-57c@X3 zWBo%PzP_3pWu}ys?x8N!!?1|iNJLk7&sY<*skh@($^zX_;{)rbutcF(#-e>I5+DfL zB!vB^DQ3SZb2cD#{`K`%vZ$Im^bm;=sJ`)ErUUPEyu_XWWPr1Ri9yBq zgE>}VYHW2$Zdy~K+<^Lm>SKO7>?2RYlQ9#-jSc+GnhWH13&9WL^2W&;5^2 z_%*2Y{L5&(F?RJI>@9G%r-w-2T<8g<3D{z=n8bu$Ca#m**iO>G4n%U&NH$A}KSJqa$5bsBd@$S#p> z?x8$U^V+GR-PA4WGBZF4qb!8&6CmWwydnHLXb}gPFLU2wqxgL^h6tL88DAslc%xAM z<&daumt0*-CKMiOOmn8ZXY&$0>E;XC%w zS%*9Zac6_sH&SM*@z}FwDE@{Bo}%yYg*QmH0fC>hoWPwWEzH4wY{2+Pwt-TxlVPdA z3v5VA(du6l@IgxARy`qn#?5P{yQ91>$oJi^T4U?X{$#-0*r!)<^-9v`7uYU9nBqqE zr6w$iWUT>nud^`7+_~)picYl;*0pf_$Hfy?1h+Gn^Zt*X=HqF)jTtVDCYJL8 zB$V#CqG}VJYt&lP3Kao7ht9qnTfVklo|$wyBSjV$6veYsZ0i) z{{0M%aC4=AzE8_+zHm#oaGiV@%U=; zDboi_@@MRh=uC2rC0J#gIN14T(D=h?h%HW*qdSLIt|PokfjjZDFrg<9PYMPmtUYa`&Y{HGt;DpXye9QdU}d5n-xGhhtixRqPm%-Q@3$`$(>A7e z3b~^YP|Tc^X;o;T!P{o@A=Fs_J!h z;|_TWP^7|Y>D$2Q({k(FG-Yasn59zu&iS}$uz0D* zW-_o%--Jzo3rUyz2XVJUzQDwiu*wwqf#`z!WG3g4#yzh0N#8=eXV30+;tQK!YFi$M^L`hpsG z^_m^+wDsXkPr)bki^&$Fq%jz@N_%hh1)7dco&Jz|w>9eia=YlOW&CX`x^P z$iyavd89W>YEYIxIbq!h*=hV@%zAd&1S#+_DpP?Lj|+@T%)KFdX`#gzpI=&0b!D`C z`C?*xk$Qv!cm!R~y-A1mkTbgV=-lXv0JpEmtDhsITDL&vJld2SnalLNC)y##u?YSZ z4N3y5mb_-X0dCti-}|a^%xmLbqtU>k4YO@JT0paLWE{?Q|JLXI-W`Y7(_^qA9NOpv z4K}vC8VAVd-DysdObN!cT3B$G*(h1{3Bs|d%`PDwvf*=k4!!BB6%O=8Q2JdZBU~JC z*W5f}sciiwG}OC0nbKwmd5&le?UA!qI^03sivkV@=kD&Ma|9khtc?mejW$rh9QsPX z?Uv6MA?@WH&zAs$x?Oez?21hKP0gf7q$8KLC!(MP%j!Lik)L@rGO~Fr1&pJ*bz^ z+ZO>ym(cM0yhUAzAZr=uam5K1NuD*^st(mO1x5nv^Kc=LiG)Fn3h%loW;ZPkqJP^Y z_tLz)nrH&;%`06z`=_EH+|4Q_m+a(LBZJ*$M?*{+L%t7uQ%{oRucwlGZtlMF9W!ecZVZRp6V9mmhQQ|RPT=|iQ@@e?8 zJq*!TE&U45+4B5r#C1icIpVI9?-zATsx34qqt_k|t3l@aXn9daGYo(GPqr-SDKbT9 zwlH+RIF_%3JeLQaJ0*(zvEANF;nTE(*#jL>cY`%&ZyyoNIbMJBYltbeg_(*pIlo*P znwN&chsBl?%ML$YaYH^7HR8-iGQ(nzIt2W@oApj9sLnT#M45G3;AHo!1=Aaz#3BGl z43RtM_ll{K0-1h@_Wa_6-#opCXRNf_aG5wz9^TzpRYpI5h zC=$U(fUnO$$?9HEv-@#yYJ{^Nn5y9FS$e#&_DleDfpx-JrJN*<6qP(!fMUcA%*u7R zsiZ$su%;^w{aNRBv{W7bXjjVyQ|)Jqy~5M&Ps~0JCzv6{<8T_6Y=?tK76he!$-(Z4 z*AI%UxH#&@%xc+XH=i7MR&*)F!6$%++FY`WuR=>xC1$KLdfEsyr`9Gc1yREy4R$fS z{qz#Lm78{ej+npL@K1#bS!NeB+eo}VPOT(vw`DGfa%s-XT#Z!oQ%yb-+V z;C1uiAl6SFC0e%3JmrufAj(K8(@#SLC>#UEPvn>H#^!XCQxDd!Z=69H-7l3D$6j}sE4>=Yk9cwfSlCObqC;Nf8f%R<@8(DHbE*}1^JYgDl77mhs^tdL{7^k}>+0Sa-0)D7 z-x#LIWah|X&3i4G`r{@k>}ijW&CY}FvCWf8M~P7&7v#a0ne>kuabJbJ@Y5R`KeeZe zL?ugW*W+JP>MV*l*mitqID|!|_m45cEhZP7;?M}zJCJzJdy`ArO{&*gud`zCVnS64 zasgW)sITJ?PN*@Og_VC|JWmt^O_mGvREtdSo&C5}6>WC1 zR{C6DU#Ns&w0l;d+HB9Bl{aegS4pNHCH580qYCvmX@4so{7F)gkiLj*CG?_4^*vBo zp1}biCztx;+MLL{AB@<)W)X;8jlK!{5uKU~o|o{UiABI5TqOK%XI#_#@~}oXUW=UPq4zy4*7dj(vxOMTMbMs*7Q1H4m&nxzwe9nuFw1TPlh5$_b zrvGoQ)xWXC|7X{ViHq|egjhW_8%0zN^lS6XYxI6d6BzMaBR?}0>>n^u$%XWkD0Csn zN?OUnLcr72fq}47kYhH6$1^}Ik%7ejkFj^?5=IM>cFVSH+qP}nwr$(CZQJHswr#uW zp4t6+tseAW*pnTZ8Sw->?DVIA;&#N8HYm>h;II}c-$YlnS#fl#5ic*NhFyFYzuT2c zF23)V-`>aE&s;ByslEIn3$N>qy5UuyMmvEDCf4Q6)s^YjDfLVVhonutT|cq_*> zUF?@CRj#O_N_{i!TA%r}r?RbQVFpJjG-;uw_lLM%9^dqlJL$D#oa8e^Tzs5l%o9Xx zl=LG+tmHS_>z^7$l-nn5Z^B~|$O3hRffa3QTvSofMXm}@DjAV{5e^0URHjp*$uf%- z8*6x$xTlg{3OuR=sG^jkIK&Gp>ug*RB{x-$Rf*k#^#u|4)NRF%@}%Bm!4H#n^fT}U z;aH*~qff6MSe!;e!}yq zgBh-EnCRo;V=4U|30eIES*PISoxryx0yyB~rc&6bEyShj2;M zeP}p_m5{)`#~qqTl0;9%jp`&Gk%uJ-M3G~?<6SfZi`LC*ojiewOTLYBR7R=2~oEsL$uM57|FMm7!s^=F42d@1l5)sF;reVUO zC#pN-b+HI`E&3mkK{N_=FnUK97ijqT82I@4+1dH>O&zmA&g{|cFE=-~xw*B>VfK7@ zWCSMymv1P!$I}y!wA_iSme7w9c;&{ho}-&YH{3$5-S_Qk=pL*6mI`cM`V3H2R&{=Gx;eIXR| zqpyx$Wd`)P2sTiPK0i_+w^fjn7ypc3Ah)cdX_ z&8rllRAvanQm<0s7%ZCUl8zT4{O~X^>FnvYU|{yrwgmA|u(S&caHnYLXYBiSf2&tb z4`)Q{)c^|3e?$W;IY3`U!C}G21-EhwC#kJi$z2+@6^v_W>gi5Qg}t}`K#d3u;_Gtr zL~;CHt*GE(_eZD3#9Qdw(`XQ0kV=`DM3D2FrSZwNEXckmf-zBQWH7)ipNT*J27`v%u47%jaDGqmbfweB+)K z3!z-1MEY@QJ35cd@}E- z?M;|VVoy87`!#gYW7#YvnTRZtFkWy-h{J!53fpwwcLnsA6c;Pm1L*KIoxy0pb=V?^M}ap9s~e zL8N(=NqHP8VMj!EuYY-9_C&r|SNx_8$JR(fz)!D{+)A&KCEc268;*Q|9Bc?(X~NR=BVKC~D-mCS%aMTY z{Ew(k-v=vN5`uC8JxZ~Zel^X(10L=9wDNk89YSqnmz+HH&mb|%>$p>c#WEzyZ-LsA zAj%7Mk$Uy#m2c`IM1S*QX=h=bIM77U1vwj!BfB6Zn>j++fJ>$qnr0pF3Ld9xLNRWm zN45&Xoj&HbSfj^MjNbqD2A|izZYW)3d%n{i`R!*OZJR_cJBkiH#fRNXNBnL2+;AD~ z6tjhd+1lPu%&Nr9lVn3SNk+14$kuKWwyXFNs`0$5ky!n6@QmwS4|vZYHyeDl+$R$` z^+(rF_tl-*XxvE8=V?AD3CK9k0`|Z!(%k^=RF?9q{om%BuQz=B`C9z`gNJY$onD89-1~^? z6Y)@f{^zCiwmCgm9tn_qD2P}X7~WmDS^>3u=*lk>w+)Hl{VLq3d65}|yBf^F9P<4| zXqur2Mf{rm$a`gS`K%;jWa)*YrF?k#$XF>UKW-w?X4bbl{vkUo?vQtkM-)4q$zej~ zh_<{9Q5(+#-UFgzc8B;k_yh0*@dLEq2b_=`1|(vl%z}u&5ddR?M+$}r3|Sb0aHJtf zK874b#CXIwBq3vvN03L7N0dQ?d8Fcqg%J#68isfb`LBQs0U6RfVsgaf2#OKa1J45x zW2{G_N2EulM`(szkJJo-9d`5Wz)n&uy5e!mbt=aX3~PX+L5Cz-6r_!;_gSeIuj*W zO{D~}=<0tzGME(96f`F@AMJVg&u0tsYQ8YgygcW3mHIbkBYUaRz1Q!YtzlK?ORipd94e~_@&LiPa9L;~}q1?c1jf=G=D#gpp5sI|?Q*DtJ@!#K=@}M~u`nQ{LC--d z6*E<8B9*!X0Dm~1tbHfMd5>}j6cGTap!u(OX=S*O{Uc>o)0*{;Yn;uN|M(k9vS|+nV# zULknRJ{orL1=qyCuNdmhn*eGj{uRO8!(`}0eCB4Z;kc9hAOs)}I&!Q4X(|}j0if>Z zL50zEOFVTWxz*NcLRwa~wx^3ynH@A1Lv_roO3fGbM zIv3lLWeC?72vl)`mMmC!pm~9XGI}Aw(zy*jOxb_cG_O>e@FpJ*8*GyLZQ%p&L5VE; zH7s@Z2l*+8ijHHqF}GH}$!&46W=*$9kZJG3+hQmYge3PfUC$eHy~ zQF+FC?FiRr)q}}>dfpG-ENBDP5B%I#0-FQ=ob;*h8az?lq?p>*YP9^`z*evJ(k4T+ zTD9UG1LkUmS2G}ptq!sela#2LtS8hiTs+Etc(5?7r9|HqE>a&a7LUi_@cSIh)IPob zmE@w}uzWr;BbUwL(9+3T);@V$`e^oSd|GH}3gxoey)VnNZ!`WsiO)WFaKIccd{xG;&DFjBCk8_fGZuv++y@?@(iH!G9L znxO@u%0lkA5Nc|l*_j2>SCg$sSxyqTTDa%dQ^bIQ00 ztf{H3yfgJ!RyM&brc^8YhXMD00`h(C7_H;O8mb5&Y8bo(n)fmQj=!PF^x^(u z@&kO_69-0uyj}C__pK}RH`}0FfYnA#p=c#lNl4KTpR2-FP0iqV>1y>kGkW7~k_0jm!@#JwJ|{Q22>8F}+zZk#6a_{YwH&jQUt{lp4}j{Btqm6?fb#V(M|HpVY!&9e^iWBNC>rwp z>zwy!0RGCX0ppWqEjW;JS{ibdZkyBP?1UVTRRjBxfb$^J&(AE5f~meU7Cs8O%POJtQS4*2b8-s^mO>*D*1WJ~-~s zha6W*-Oyga!+{CwLEcNTk_UAfVA{w?t#qWKXu$mQtcn8m#TCn^s3}QRt36FB> zQ?M{EkHrnTQ2cnXFK?$Jc=@}g$6^Bt{Y(}|!y}SCppCQb^MH>riw8gRt36_QC7J{6 z8xd^x`cNd9b?)oecX&B%}9kow1FQ@dnc`wlVg8XPq*I9@)CpD%{u~TWGA_*E&QRPA%9X4L{|vB%9v*p%DZ>R# z6T1C#J>2aNxof*Wz<8|po@~ayeGOle{FH?SO7u;iigaUVNQ>goO?7>nblUV9M23Ym zDYdVqo^grfSsW09CK`ky20}Sy4cje(#}e|POo^GG}#Oi?as|!9ZK9C;T zMHEa7KM|-{HK`MjMlU#xUX;4AxWQO|z@-iC4AQ{g6Un_X%V4vp_^Is-Y&W>4HpuID z4fg&Ve!ra_efP-Cq^730l!%Z);>Hv zU`Wz`1k{mrjuC!fvuQo8XN0m&0gAqz@CIal9LqcZ;klz93T6kIVDQs;!mU64(E%na zU|*^j%{otYmzKhPUh zPp5Z#?$dvu3lJVGO)(QJH1kmw!z7Td0R^RbUT{s89;FCq+ozXJJSjCVeIyfDkAIr8 z&0J-OVPX%G*E4;$`6ch&9(ZW(5iouXsvpeFJ-@r_U-rq>5vTdA!2#W?nrAx+l#x9^ z^PFh_Tq^o=s6c@WV~!uF89$O1`*Yqwhb?LAN&@H^&^RzY1yy2Q z&~He7^yGo3=PM>FB&E`(ko7)D9;e>$b%O|H42WBs$9nP~jOnm8@8(ALMe-ocSo>|~ z>zCfYY6FoeIZC%U#F=%Z&OnKY#)v@s!~&zhpI$>or_ltMt#Z)Ml9RiZ!fN| zx1Epo`*zR)Zp5)gQ_7jxlR+*2TTe9QWxsAiE0-umH3!03xkvXRlFJuXA}qL)^v}lU z6}_Ve9ffM$$uWL;f3n{1H@gN_!3%W<`LT#|>3vU6vQA zq34(jCStaWIS){_OhYl}Jn9~W-W5RJ6-16NI=h9+DuHdAb&C{3fr)2HbMkwIPO(%tDNF^w zC34*NP32m`dQV__33dAEpnDY3u|(i>Q~K93hWjeW&*~TN3^`Css4Qm1`(7zZ>p zGEXC|NynYE_9|P;I39M0mi~;|Lxs4~q|M0S6=gwx*=wUQ#>)^d)^s4yf2JU?$@)`j!fwXaX?8uz<^gddjT69=JDZp%*<8@fU z2}77AAS~#tT$fKi!BfHcu~H2+vfFtvCvN`51l5d~d|phTywk|B+C}*neS1E~lILPn zHiFL&l2#yD1Hgk)!ae--`7@4S6cHN+*we*7o=31MM*Im)SqiC{t~ z;e03qP}L)SC>lyj|>#LKa zn$EBkCjo9-ICALZ%6+4Jpa|mBBv)NW*C#+;%V(fx3bup&ZR<(>(P70tsb`+rA~P`> zk5o+fvAl`El12m$*-(wnEF3QCI@nafYNJJ~>p27ML-UFm&rzAmRv&*)SNvGmqG5>{ zTzVsy^IK2Zgus7|VQu)WIyP3eR-AS>K+k&rt{6$20?={mcU~C?BnMM#AUj6c_Zw#F zwWY@F+HXz<>PC(2OtmJI_mjrBcRGi=X1j2evt#tCLbc=rIgHaNMOOgz} zuN=M^y%hmrV{a8DJdhy|uwh_8+54&gcGYa_z*Ynq6(onHpj5J`rKhTTXji@JMk7U4 z)(lUK&~%FjOg2D7Y|<)Ay(lwaiQ*>bsNJ$Q1-N1R%NpW4Tn}E$`hL$3@yIImWDdBB zYR*jg>w}u7r9A~(8(Hc(=IPu`bOovF3sm2AGU!?;uQ!ntfUe=R6PKuafYSAX4$uue zHtgo}s<)xp4G@6wV!6i)k+eEmIdCVIPA?vhtwXUF_a#^`@>w%CVO&pf(?SDmW#tMa!xM)_M6YFI3;v&a$Kl2Qk>Zt7|M z(_Gcu>;#7!@5goU7*#y`*z!fTDKt_dhR>)$YCu1k$C+pVjWVcsm zIkpcDigl=%47+Jxgbkm0fidrfd8$)z1XasPEkjBruQnjA1L@67{sx;WS*C)S;uzVB z2^%5m(<@ZRKxv6wZkv2NZ66;FY;-Vy@ext4p#>IQCkO4*HM>Rz9|tfA+dEj3tBYP% zk}VL_N8aN-I*ut`ie?T)3r39xfdLC%OvopV(QGsQSUu6S+@Q3~l)PxX?pi2STNBG$sN;8Yv-+yuGM6j8EPzef)O2)(G?kUxdeh2HZ8e>pMdg!v z3rdUguPmA(zmgH%8XXt(F;yy-$=2Gag+nYeJHL8z@K!<1a91U9A+<%mMc;nSsbx<_ z_149+A^b}@V`Gl^Yn{FQbB3{3oBiEZR3}SCd1b(yYMNS&%NhD9OC1`%-|Km0cnR7W zT9qJKjQ&3gED2hM-Z+EhU=ZAuv9G+NFWbZ?k`e>_IMsZlC#X*-P+k#HI(8F-tj4aw z;^ouIN-JvXn`u5 zop8>jDtBPIx1WH0Rk#ReT2}TG!`CSq?7Ozz{yJ5V?xfR*Yf-Q7-!Jq&j9RJuf1c$Q zL|E}`1bo|73Kgjuw@2G9r7(MUfbI>j^8v3W7&W6VbFC6jXI&GOXCh;e+Z*MHvD-Fc zTJgIfNB4vG`U8#d=}=1?-J13@CLj5|OR2rb#L*||knp#o&INq$>j&~ooESDoO+ zv-;2Xa6)#s#wNX zI)_1#=MDp$QGS?HTOaSlywzmv_BLFDo0OyMe7BwE*TCW_?2Pk3P$#?jrb{skVD*wx zmE^sKMBjT{Ra;Ab-R4H_7YGbMaNj3n9Eh)8pf5tgZZI3!9W?3TX_Oit10)Qhm29M= zeUjt120r>QMfQLLi_vd&T^BO!&se4Y;j+zIO8V6x@`U=^}hbJ|~ic;%0vWS<_i z>_P|mK*6AvP1noMQkC=SnwsNWlqcZy?`j7&7~ec#U%wT9xFQ3D*PQoy+Bc%r!WCN?~s?p!nQN3?Eq~P>pbf*rxMxtWGm?;vfm8(%L8?%+!0@(*orKjFv zOAA;eEFZpEsqkg$f|_}H!r}{|w1W1FZP*`<$c1{65CvrAHf=+Y}QG6b6U5SLAflPQ}>7CyxHy7;Qu6ND_NfL-U28(!X_~S^`f0l_iB?`A35W zBhCr>HWG@bRs$kwUCvch)7Cz^iFzI7>2vuD?Tx{0YQd`KzPDgu`G`ImzJ$N{dE7Gm zjpy%U0ou(ujk?XuA5JSR#!=-H(>7rQ7*(a@F)QUkj{6niMvC{VhMypXvhP7zXs#O%d zs=Q9}aW8FdX`$SpHFOKW<*ZbKVe{JNVTc0s^o)bmCUBp!VY&y)Xw`b*sx1-7@wP4w zK`RyuOupnh=b!Qsbqj`n)QM);$$M$BplpVad7z$O5#rZ-mFHcxUmYN+t_3^5@E=X>4uOh}GHs zIZ-#yl~!Y*2=>B2zwP2!iK%qq0>zS@)qJ_=W>2*PnjRQhzfL84FK%d0JvbN>Hgw>| z5YO;$=Vj0)peoMt>6)c^RA#gsbHzYD`q@a~SlJu_!zXpMy zF@^kIA5M=Ss{af3_9#_Vy4VmYs&9yDG&d0NUsK)`5gGCX?gkEsSIuZ@K~!C8s^sVf z6Qi-VyVNdVUC>cEF8)72Xw(OJSbU~?4@vvWG-uzccFCVwbmYc#k&8CnYhEaiw`DbT zRI_vw^b;LCVwZ{>PlEiplq=_lZ}ksK#sn>rzMQ7-sGcZXaAY_;?t)<;k*fi+{40*f zNnE%~w1|qwqHiBGiGNK^&c;XWHqpC+;QuPa>ux>k+T*nRTFs0Xuo?+76Qc_vzUsuY zT*JsxE3kPYGYpMlMOjt9oKU0 zk`C~7?_|*+L9;qc5?yMjH$f~wJH^^*xZH8&d`3@9S*Hh;5b%ig%|7+s(I>H5=uh(* zZtu*f)K;0G-eqGsU6blwMzK2!+01L9;6`1+O=S&|(%0@0ZH9dL=@AG8hMjjYKou~4 zX2>l7a3I5XzcAqffb|A)_aVV}BcZ(7|8k$jQ5`sNo{g{GBVjTMM{0~3(pHn01&%>y z!^gt0~5{LR%sm~X)j$fWizaH)QWemcz3-uC>W0!> z%WpWcGHD8ss)2pAXa=t|wQ#KDft{NgpB!lfL=Fgyj^@C*swZ(K<@Jj6rFr6xoeSW{FkX1cKB$(pO^NzueADQ<>0#) zXdnQE#U7rZ_!VzgB!v_~OVrlEZKkhAUSOZ%=byeEGEFs}1LS-bJE=iMoPz$s)PT(| zegFD7*Tj%}DbsJHVW?aQ)HZF%d0z{DQ4v}R5G&>#4N^p_{!c*yO`aYrIqrNWPZ1Yj zl0FNjGY6i%#5JR3V1JsYz$ zk;;^d%3t|FS-HG?cD6h#Ig7ynVJNM!WmIQy)btnL&!sT}eEU zwe$E{N6AfolV_xgP7wfQVqR+5Y-%mqj2=vrpqrqrV(Od@M6a8Bl2&$NHnob2;Le~f zxRtue+^0MwhtUL&^kpC+T3&y{QSgDsKg!RwhVWXH@toPiNq{O&puS@wG*g! zqH+ptTF<_>-m>5IKXj1?I&!~NQx~s zjN&#G;RTH&YPXc#fL}WSeEtm_d3%RSMVnPd|F(ox0JOI|W!I*k?)~?kTM|}yshcNQF?n-r6iz4+=}D|80lr19RrPQE zGIrkHUu}S}cEP7UTZ1~%^Yi1fKMj}}4w?t_Wp$M_ew@NvH{xS+s#K)Ne_lw5QlVhM zV$e_h@K4!m2<{u)zcmsjpg6>o6IIWvtE|BY-vZNNzuRu-+|{zUuCg2@LoKl~kM2aa z1nj|A;A{bu^)AIUi9gUM7_qCrFrU0Y@xK*@A1QQ$oNxEMFaH8)Uz3A7rBJ;hhu$y! z7Uf&W8Mk2+X-nA1A{`WFf|m2yz#nKZI0ks1<8HukJi{{HMlGT{_4~7fKiCOni>m+4 zDfWMA;!7#O>N>MEMzHik>E)xv~(8 z+FxFub$8RoU#Lsr)17h52X0!hkR0(xtpf|S2Mrq<$XPxxjz zO-@rGYN~>dEY31Z&l`?u?_N^yc}uDKJp6SyEb`QM!+Ewvd*{8Kn#1*D9ofNwgRuVZ z6c4A3YMbt%Z{XAzo?`#od;ULN1OI2|9TNxJ|0q0kRfBXuUc=mNwXw8~KxTqC#-Uzn zIe=hnDg;Dg&u|*ub{`C=L};R=k!~Z&Ur(c%?DCUb^?e^;;t;q7feM0&ft9@6W+{;s zier-{=Ve04%A7ITY=2C)%%=&mH0RRl_5FJNd3*D>x1?fDF0$luAC7a?o?hi^wOWen z4NY2>YP_7Ad$>d5)yxSwgtDxo2-coCGBa<|ub=;ZdyW~Wq$+k1vzqZuhn* zRwClyOt)gW6pJltl49rNuCY_0R6&JG6xF^ zp-@FQqRJJjBC)n25@E4AXJ+L}P%T5dlOs=O z{WnaB7-`}dD5BItb>eNs>7Qrg=XdaUB8`5EE=e-|q`sQqVXCD1ONP{#6OxNGwO5!% zdE9mS?K!H-rF+vHjmFBxh9+U%0%|3D^7Mp$%1-5?`muGQ)mbL!$KhYARXV*#Q=52J zZmpisSF5zPyqb*h$X*FQ%}S+Ih*_e>B3$*zz?z&VOr zICI(O5=K`_e>x-k;LP;?(nH@Q&Fq)g+Bl8(ip`(%FJeE!AZ5}Nj!Dlf=0p9p=enAc z+gZz*PCk2h!wK29f>h3blu*xz&IJ$%1Ze z;^=W90pU*k>)Eh-8pIP9S1cG~hR%B;;PnWYNCqr;&<@-=kI(|9$*GVQqDHl`O1S(0U=ruSG6o z13fNFM$KZ@I<`ez6Q7aC1IE;k(rR>66V?~azhlci##VIH!c1`Bu<46{9xGC8biwxd zyjNSVN%)~2!CQCv=*?Y_eQ5{J(s?pjYhG?93L<#qnuY~d@*4&Z5y6m_7p|#9soamU;M#FC&WKWgGPiOxft+w`OA;bb69voA_Py^ z=TVzvtS?gOfY-&*SGn820rhC^xm>U_G{C#bjxEqNA(jKOPm zQSKHhE`rDmy(173RA~W9qnGyAgx@KG!@h~}#sRn`D%t#_7FK!S7vFilU_Ml_ehnND zLaSHYcM=f=vGt>-WHn|t1*mJ+9#XRd5T?k4KTNE67$ny-EP!#O3$lucFN`}F{u|%< zsJ7A!8+-nMl#g__Ot-&v z_dSr>NyP@5dz*G3carwp(@R`XE;zASKhSi4OMMPO!x!yoRC(Mw}J_8SX-|R0fn|I)d=RCw= zE&S8&WIs-t`|}kbxLJK4CP;k{76>d519HFGUhMCFtjpml!K}uo=7WlX;)^*&Fn~xS z(nEt_3`m2F(mT#mk+A3fA@)uIjp5JdD01k7o~K)*2X=~{ZG?r~RXE#!zUHU&exWK= z-l)lNuI}#d_2z~CkH`<2PSO}QxOF`B4vo1p5=b+r#3<>4?!H6%Pt;}fo52eN(yo|u z1a#7Og7z>O&l_fbNctX0ndYC}dNwI^Hpf)m?-pFHSG6H#9qIx5$FxE%sTE{Pc}9D2Z~?&eF57XIhtRR*69zFtXq|$3 z!k}o5NCemi2@qYhMgT`tIb9Yv#+f5qP-MF8trZ)mZPXbjU!1YsC8i@s-tpd>AC~|6 zjbCPq?4Z8!If9~VZiUc!a(9*1?Uq)&`+as{XFvYu=lZq?YEL*_Uli6}aVOPtFT*W| z*^5>VT=~j>U+DM#1?FXJBLl_Dc}`64>;;LquzWke!xh?;Ff_qL2d=K!P={-7)u-9Q zK-bm2qQ8Cvy4OC^ z_n6BDlTn`?R;c{`4fJsNo^SCT@ja7X_0kaAAX=*8%Eoe`g4&7zDh<@#OB#r~Fu6tH zWEPNtZ;p3!egkv4RB4R2cNOsiE}&jOx>|a}NdsfUSL&Jg0alL5LdgDZnn@S{y@-5z z5$170#v3?6nE^RP5$lD4<=>zj2v3u&c@A!|_c`S!A1PmrHSQ{|c?5SFfd>_S-*KNr~2Bqs1 zRt%+>44^{1&ZN7@FIqh-0HVWJ52cFz=E zvxvfuDX!UFvISWWYXSwj+)d&>(jZClSb=uT>b9tn6cJk=k>8qF(KR1-^~Z{ub!&!& zeQ20V!V%J-FA+aRrU<>>aK4hhllV|Sc}kJ8drURQAZ3L4)D@3QS~h~v_o#Kmt7p!! z^r-Y48AF4!VAFVG(x5C52h2(nu_{$(@2;VvMlA>gt{wyzUqhTq*wi*yQnM6TI-~&9 z3i0C;D?Y|tvU4;;HAaw0wX?DMhQpVtc7VcwCYUP3ep6+;R|jDkRMn3^kKZd(&*=6` z71bD}k!5`fhc-l07iIl)vR-mM-1~MI^>HjY_Z%kLHC4O- zTNyep%G4cP62&D6H}pMfLP18#5tL1`UilmBBeSQD{CzM&!}_=h`0{pWoiv6%Rz0H2 z>(-CWz)o=1_`H^-SZ;3eP=3jgiMR6+TSC3rlT2?KgJ2$Tjfu=Qht!JRV4h8k=T%F*>*ApZ5i=QotwxJs7K!?3yFbK z6S|xHyqoO2qZ~fkJmh?|yG*{^Z+rp$`EU5Rx=PCbO@ed&|4lvrX9>>C$?-pMBfaXD z{~=Yo>ew`10ue*o#&Z;_JBo>^wlV9SdiR4M!Wzs70h0xcCV)anazn2r%inG zb8$66ni?`dBp?um`XZXD&pl3~wh7HCRdg=%T$Ggi{<-Jb}ugn~@JtA-i==Ue{F<>&cJFeJ%pl3kRD$^8Jd)9_6 zF>@)dOl%I)Z35zA8JqXHG7;EgtO8F`@aFX~0Pcn+v89_EXRzrwI`a?e$bHJOtsnSR8|vt(qpW zStk8*Jp&=La4g&K*n;7C077<18aCXEF%*o(e5=)NT@zaa+jZx2&w{+T&7LbYx1{7e z)X)FP`ZBqkgtQtxp1Gf#3E#ntQ%HR%QJkDv@6t-j#c3+=q5eY9xA%Ft4X(5^==#Fb z4Xe(V>V?a;1OnSK;W9O7X(Ve`P0`4*muM}gW3Mzk6v&_U{sJo13~|o4!9TTLe-+J4cKnkyQn$q!ibiqz66N1u&fQM zKk>^Osi^HjV>>2=<`IP34#L)%m<3@~qpdD)EkJGwh_b*`Tl6r){kJowK7SwG17OH~lu zBJGff^)*2LSpbPeD~qHBG-UQtpcnRbS%b7Iqvf{(BbIpIyjr0yIZ*u*6wfR7wf*X4 zcSzqPD!pTSGTclxCgt3Z4AQ?0nW~FVBCUOWD+Z?%l*~YkVstrstHt&T*tQ|>Q^<$U z<*MiQN*&W5H2@B=m4=a)sod1`G_5AU)Z;_=8hz+}^+3cOf-k6Co;qu0K2UQ54Hhd` zI}agI?=?ChxD)lIP!P3x)PXjvkShOov{ijMtpEOkquMBFlv5!Tob)i zF2q9var%aS*K{4;OYw}QY)|AG>0Lm_%zn)Tx3B+c>f7!(n;WrEtWgV5>`+IC!+9sQ zN_k77<9_o8k;+UJ-k8TL^yRxSWe5xG>pa#}N@qqN^0SsxvH%OVw)Tq4Ce9 ze`{rnae)QoTwC6ShTVFbhs>;vEp#>%Mt#)Hm_e!`5ZA`xIeW}byt{a3lW(f|`ePPk z{vO~}twl|y&lB5ymvAWEMW&IvyZaqPC+JGH*Szhe1AZ95Qh>^jgC|)R$kFry6XMQb zfRbx4GE0_@l)7IP+^P^RAyEwzCPeLTY`HT=?-gWc-+|4c16Q1Srh1lhs^@##M3?M% z0L$MneXjaVh<9iS;~vuQzL;2j3;w9$)bejING}T>(!|8N`~d-vk7Uc29LOG~l+p+m zvP(6ST3vlUoHXHB_S&nT{?%*N^xv;M&v^Srtw`~W!aTcX(8OSXutSz8$$}R}balM2A6R4U zm@y-sCLJ(*ZN8?`<+eB2=4=U&{f^%DFP+A0d<=O$JWjqg~3jB0*C zt=_Kw6uaradX;UT@HgGGeQ23jo}%|Zxkst$>OhlA8t;=#l_vw<;!i^^C2n;bdOo3h z-1RMG5H&<-Ob}~D&8ucMd!c%SMn{zfaLr#ZijoP*3(~9Q!N{?&)QqU8H@M>}pc#Ce zxBKhX?0$f}=mbsqAn*`9!+Z)W9RZz^+Qd44SoLG-Gm4#=Tee&5n%!w8V5bdTZY%y3 z2Wnuxh$OT(E`a&-2M0$@S9>LW6ZuXb>;Zvj6B9FMP_hdni5E(n*%SRohH@9~j(=NMbh^NR?l8Mgnq9+c0nbiT ze72}b4Y9uQCBR_HDhhrgd{OjEPy21P#N&@r_kc#?UMqvTiG?%-7eJo(@xdm#gDjam9_} zxl1PPn9tIF2z{8!>3KYQ|6oKH~4I5(K7{1z=sODsaVu!l( zf&fj?*`metk1-=iqj;pjVNJ_Sd3V3&Ccqsow`L(MkKYsAaXZ6in5}6MmTYci>8{1J zr3C(h|6HXtnfS*IIuPIbsL$r?4#*8ZihOa@E;Nf*U^*Rd zKT5htbE#3HS=6fH#Md{HP$z*z)n@sP_KXJ4o)eq1J3YX4ZGU^7Wp2?8bxsf0K|pJcaO2e(F z_YjNc$9{6;{31eGbOvLD$YQ!<9il$MJgusoKThsUv*j?rb(k+N+C1+ida2VVHgbG- z=a0%lSotT@ms^Pa&pvuhIhnuZGzo~f!lDIiyo6P&CoryWZU9+9L~uAvR$t$x;O`H< z>jp+`bv{)QluFq6eg=2Hdu0m;VvVo!6MWxz^j%bp#2WzCfTT+gSWan>tXceEjG~*D z6d=BvuaA8^K@gjpT&zQR(bk;SLbs1{I#b5@benY|7()FO;q0NxsGSs{smMsWNi=yv z!;EFcp13c?J_E8g(tnS%cHKD1o`=gd-1KQ29ru0_PHfAO4HlUvB0X@V_Bl?_sU5PJ z4cv3;+v8fim%WW=IQ8cjA`$A4_W(%a3)kBQ-xv8zy`zgGHqr!GJYw|qI7jz^({-6W z5bq;C;7P&ljsrJ@@OeCY=eSJwxlg3<9De{_1mv;glrDGXWx!X+%l8x@##CIOrZO8= z)?`sXk+-YRJlH+jefo1g*fe>+02GZdZoBgbZ(%N^5S0rnZ?DF%r5XD|xWyQeDn))K zW{be%U%0ZUdDqBh-=1{wU;F4Ffp!4BmM8DdLxR_@k2$@^JCyy9D`0VYDUzFQB;9HT zGi;_5508$D3upcer_E1}>^~fCI_vY~!!@;OW{8&w7o-hyMKvUF0%>@P((!rZ+iy)v za1c=bQz8`Oa8Ekxqo zbM}A$)B86cKtQeWaF@U%-QGzo?cNlo$Z%sCq6dP7s zLK>_m_*Ty9-_%eyB&E=yW+(Qw=Jv=d$>|J(53SX zm2ARb7wz^qkE0zWw~4C8#!-2Wdl(=j2?k7KbPAqLcbPq!)SAMp*fA~IZ820VH%b&V@%p z+e2d0W1`HzO_tPsW;-Td3Ttrg-<=JG-w%kY*+UP+Z|pPveG#ZTM)eo#ES-p;J{Auj zoR=r4-8Gce)GQd>6jB@_nF$IuiMtujFH z%`EI-o~^Iex7(I&3G8weZt!^N>!8S1vO7N!7NG^+?hU5Wto~ zKxSmf1A|~Okz`E4kQk>+0E^`gR(BH{C1z;Y^=RC#YE5=dN&#N49!st7Hw=MWoOZGZ|e67;G!RToK)yomjd;8Slty4t34Y@y( zXo-F1RypLJT^%s$2wQ20K!QkDpEuNQ6(J~1Fs&Jj+2az zj{IuFACEO6SG2o3nUAVSdGcENByPQTmG3IQOSs>u&`m_*Lj-|ZQn$oC7IRpNLe2Y! zO5uN3s*_Kupj=YEV70_%&B+w#k)1Bx$v^pjl3(ke=tn~nuPI%T7g*A?#C!hTlDolg zQ_QB2RYAL?YRQEreVy;BNVsH6mE0*ajW2Ltj+C5>y$5z@=&>7P{`~Oxv7mK$cXu@c*a#!mC0dK`rszJvx4<{gagu}l zA0tZZo%!u04Oq`nIz0WZ;IH9dJ6%~HlPzjBA3y8_pK04ODU`0VcHz@Gfw0}UxOr0+ zg9W3R`ywxDzmhXDUu0pYh(a+~v%1Akg56$%f1%JKD;G{h!XF>R$E&u?{oSo52ZCu% z==*59bTK{FZN%oln)(I`T0No=A!}(R!?=ENH>``S{+S)0CZ`;I?7j8zj< z6V)6{nY24zvBjRbOLK5O&D>lQzJ&^*$-`B z$*{&b=u1=6EiDo{!}}V(TzZdwDhII;&CJ-$OWOF7bq)T@v?A*Sz-!N4;*`o}CY=#+YL@;zxfIhlxfZU2%SVf@J7u@Y3S zzxQ;E$iuYQGe3PztXM0RQYvYgRx%`KsNcK{p9D17$B3Z5T&A~yGAkq@G?TkR4B5n9`8`!3$f2(UWIgXs6k|oipgGu^qA8r1(z~qS7q!qt>SwXYN$>B8mqM6q(H^yl=_-vo`8q3EGVumZ0;G?Sb&k4BdC+HiBhc% zV&KS!#uzmn!iyIbfCOD7$M=HoMETz4^=A|Dh|lwPCD>h^1HGZs4C_6yGH(ad``x#+ zv2Ax525wJL$-Jg6Vci(-g}EBPW@Bf|{V>er6~AZW&c){b9sA0RK7gEVG5nOH;-hft zG?T>NCqO(uc4>}{-SdQlO8^_RXDq=`HT?LNGu0B>=kr}+vg7!NF4PMWLS=rPQiIZ= z!@(Z%ppsdOX~RX9^^W5lX zoORWPWc5$D*uH|*y>vk`<3WNRov1el2sywKLLDws@=WC3cVP4OR~O)U0MCFP1T9mN z0~X%LO-4#a$xH;IUQdi%;hi_D6ENhcNFg2Y18ye)4)CqzU0Xcz~>Wkfc|+%10#9baHCerL3A2qjCz zXM-CcUa0|GDpb5V^nF^lEJqr`-4$+ArV9%3d|EB$dii6)AOYEKOBVUcEY_Wsr` z?skVFq!(!+NQHvMr$JtreGht56|{EHlEV%f%XAIj&9SeaJu{yWX(;S5%lT!&Cc3E2 zG;AR2o$2L36wVEeppoGmBtMYovonI|7uu=lE$HK)FjZWxHXOddB;dT#GdRK-35&$ipHYhW^Ee2i# zFSQD`1eAHfp0o355J&F8b0Gj>77`&%-^L^Tb}H;OedSo)(z*d2d+-$zoY#y24UC-d zBi`O1B%v*z?U2k+XcMB-k9E|;g6s3()=deM(3kx*1tmToRM|=@x5N?DpkNG+u6} z6QxZV{Th}B%HEE8i$>YX@hYI!=vKti`ILI`adnkcZUN{k^(ucs9aWWD)@Bd0ch|&v znYTR_Yor0|&#TKzKCKA%@$kSX`@SjPl_Ix|S*-BRb~!}%nD%wfH#$CC55Atb9uaf& zMN#C&Rs=5;iXI(zbi68}`xtxBn5XWAvNZ0=qh;M$ty#@$H(_FTe(H4GAfJ0deextX zz0wX_4Bxc<+EOpJJKc}ep`a0hJbp%}{%bOt%L}iSTK0@9ahGTU*E5P^B(aA zGogk~s)Cj80?Nrun{nTFV(#ZQcW4h)5&YQNNYf5!saDD=_=|pRquLK*&szj@5D!f& zNz3V$VAB@4z85IWjpY7oOTsL=YZ&`ozk>lRXExM{qlE$3zpQUDtnRXixx{Jc5@?)9 zYf89umC0(gB2KDBoK|xvSiX?nmB_|V0V8U)V2 zk1QPncu>pQptkX*?&FKN;;w~T-a7rnig_w|B99Mhn0gv<)lqaT*znOiZ<$+q0A2mE zPAYU)>k%YKpJ9u~@)e{!wsvX~!EzXka^xL{CC9wlDw#7%!CdHnYx@&!1YIF6a4X-S z%G1VZ&gq-QlOrK^(R_f$V!O|%SCLO)oG{}pi{l3!|1E3LiQs^O*pI7vhOsgpLtC{H z0MRsroWEloY&oxiisVsg50ihTlr`maaXHqkui$>Sgx+rKLlJ6qKT(*%()i--?ia}l zGv@hFkJ3XCYPXpAISN~rd(I+)8M~olxT~A}AoWqd&ewcq!^qs6=57A5m@dhMjpao%dOVlH#zM^p}wjg3H40LvoN1xIP>bD(+ZCu);snGpK zZFhhE-IT}RGRM#->5Mho$MR%0&LF-KZn>zU`V5yJQ8pi}bcWV5tUs@zL2ENbk(53} z$8Gv6jx%&Lx%ljWs{qfLP3ju1`5t`38_tHxVo{|T%lbo;VBFOpBitfPN`J;|88#sy zgi3?rWK0k9B+}_vF$J~G1^>y9U%OaILVa~)@ZxBU)w_O%$>G=!7_ zw;bskFtWcIVUBv7uxcLSMc4OdsoLh(%aX`AssV10*g-hURo|DuR9=YLzH`cV`n+}H z8O?{bN-bv_)k|RD6rxOXjiep5QkrD2qh=u&=mY?Lm|4E8Vcdq2{j?PfI7<{lMzx#t z$aZucIs4^=tm~I$q-C)Q%|>|8n;pZY>&+&?#-gj@FSkCMPalhnR@@2aL6<7~c0EUe zlwh&aWoVX}s>wz5Xfzs4rsAblD&$}}KmAw>IUW0O-U)6H`l5OBEg2RFhe!NHIN0rayd5H##@%fG;XC&ITJoG~A5#zpPm&o$pc?h#Q zY`yvNPo1N$51!#BPYAC#U)|gts7!=2sVg=5U7FaPxBCevJ_ER(T-LL@I9;6FgowZf ztNXM%2_S#i7a}-1okf5X$>hy2P9(J#dS6Ee{e+By z+3G8-R0b0;+>Rr+qj(xVksiwr7~PP0up)OJXg)dtB86oV@Xj~2kc2qz`wF*v8f&jn zc1pTWe<$lv>ebr8Pg5mB?1Ms zri_H-9i{3T(qojAhHeYCg}X*nOqz*YEV3qbqiqURs+6AdrLIr0L8}7X)Si1GCxynm zoq}o^G%4Xb4~Vm9wn4NVg+W{|KMwhd=Ce^4|2n56oOIOMd&+_e>}H)o5y`NW=AB#xgHYus;??i?5D+MJk3f2G zhP)G)a+*0yX_gfgv>Xnsq$2*IN>B4W+a6FB4>{T|0J?1`;zZzWAdc9kxxaj~DCv(Z1hcj|}&~m0t9* zyVbRT+T`wa6Pprf6MrC|{kwLVkOLid`GOIZ&CoCCWXS=Gh_b) zifX;EFTszyJo*wwP|BQQHCc$$>vgNAPA3I|4Z5B-{Jl*?6C3xUw)$o0$0ikV?bjsn zBD=+$kl)n8>`h|mRo9$zA5b$eME?2ODdQ^7-p&-pI%aJ`x*XyGj`60koQU(kwp#05 z(N}5gKEI<$UB=_s^ zcT*gwEobh4wjkBdUt1TB`ajReeTTW#j@zSQ%o`t0qFoZAc_OUdwCrye@~Yjj-!7jF zRG^8+i$4H3kAiSB{27m_LpRz%7nWs&lF;UH`M&t#wl4_dP;}0}a#6kkc9)3W)I`j! z_1J*VI4i1EAw(J&IlU?Y;;#mTZ~EmYdS9oWSs&ZK>!-R0PL-pIkAC)M<_fouB7iuq zf5uY8x7HNl(2u0T$A{ik5}DdlJhNH&#>AXDz49UaaoEJ`_@L5?7_KHbwZ7K0tJx6$ z*z}auZ_hejm)f$r58Ujqr~@g8*wAbZg`Uj%dv)#Uzy1Nf*B)U-1v?6s5D*;D*h<&) z8#VP|JVX7w%eBQq=Mf4E6yd>RgXcCDczen(ux+S2CmF@999zCUzB=YPr^v7xbMCc$ zlSyHK1(g_=+{&geIh~f68)-nIld^~@22*uhUo1MoZku2KV(=!Rdgm>Hm*pAvP`_HW zY&HN+xW0|DMNOhTUYsX+5R=Q+H4pT~0q=K@sCam(y3$p}D9&p|!Tk+1G(quZ2>R@Y z>xxlrixp=2NM3*iDg3Z|ukH`5|RO8&R%TGR1OM+8i*W0NAf|4w%PKsX)Fo#$hZy8mzuPT<`O zOv^w_Xo9xz*ow3teL*pWMlO7mQNBDSr948?#{VLAF!)4fSk%SKG;IOs>J%YD9en_Q zhYw4=r3Ki_Y9HC_J+?v29(cwy^=9dqqA47nX+g!)DdP?)c=cqRpkGXqQ>asjzQ z*AVe?SXg`~HEB`tMq#}>Noyip6LUY@q2L<1?=~TAEW}%9i?-R?9@p<2h#Oof5Hs}i ziCJ4nD3GoJP(pg(t;<)BujAlL9xN$C%9%X&E4wU3kPb(o-a<`$zFz?dD^L8WXH^X>{P?b9nM9RM+t_NswsU~5}Y|N;x?(^z}!QOJz9GJW$XBR%Vh%*;aQ67G{chFt?s2i=y-{*C_>*-t5!b2Hlr zDeDnCA3~BY#jRD>u4~7!XFt(TBdYa?38{68DrNR^-x-aAB~(y#nBUelTROX$j)%gR z$25NMZ#N7+a!$V0M9{LJe2`|*%nmh@NklQkcM4O9H0>a2B}rB3!U3TV&c`?BwZqfe zuoa0WzjKVhTgXb=$OP` z+SaP+uRiscS35A0Mg>??`i<$Z;9_-tEj693BdRJ!ls1d27d)?9!b(?&jMI`<4zIu1USkD|(r9O-CtJPmVkfV(XRr_KW7Qt=pdp+V z4_D1O|EAHA8l<#Af;rM|?cI&Ru=v`JUY<(U&Zde3u}+NSV0``epFDX!{v&$AM)ZaE zDXuQdGI7LGBGO>Zm~<*Cmgcl}wAQtB&1!1=Ra;qGm~{z4tt(jAc?szlc_k{8DOe*5{*)1IDvy1j zCwH`|&-3a?amEP6MC&K3okz|SPZx<FZII&iWH#&F_v)odfxW|G2T^T{%`gG z^Z&sfU}a}w`yVyf|ADK!ye&CKbpQG?A~np zd@s~FsrdNq-kyGPQVFs6c2f`&AI5H_sn*WuJg+^xQ={`fA4Qu5=ketA$|d*uX@3Mr zUo21`_GNI;`Mkc3zB|3j#sA&3BjYAOj;P(C>?Zf4>DIbM-0=(Dz1d}wNX|%L{Mix9 z%l>)Vx|qlu2`%h|NK?i@UsmC1uP5v)bY9&3RwkK9ckes9j|M9w#ab^+DfE_jY?mtJ zi~OPafax_YIdh$l6Nw8ijmkyjA^k`>6PeeZ=bo1;d@lqmOcQ|-sS8JsK#xid*F~d6 zGl@!#&_$uesOeYJAe}&}K{}3HiHwby3HPN2(0`0`D1@48gD2cqMK3r=F>j9g0SLw0 zn{p>RBO~qJhiN};Y5T6{H+wVJK8vMmaFMr6cTy>*Gc6%bA(jO|I!!$@5_I@ZbRj`6Dx%aZStd&T+a z5t8#wT>>~zpct;pb*|IYsH`p?+t}e1ZwFeVA`bCRg)oTlT^yCfO9vNkZuqt73@n>j z)Uj9YtR$)is(*1dnjF8N|1NdqN~#M3=Yd*4GbKh8tsXZi&HPnaW9idi=m13!QqZCT zZIjC;cR{l%2Ec5?P(NY^NTbT3?Bwj|1mx@+RkZa6`(n1buCS^fNtTOD(|(A%RaYH8 z73H=pVXIrv(CFxuYghVB*QYk0Z$+B&OF`w#SI)oN@KSkFcNdUqzIp_4Wl`yrK0b@{i>KO97FVWQpuvo{j`PrRSM zm#QbM?2sG6N4IYsxxZWnWgdL&Z==N+2rse-l&!w4cDy{snL3MoCzLPjuxwlN5Q=&O zwlNdOI!CNGE8sQ~#JHgz#v_6$l@UuN6<)re>U|NH?(#?stf;CSRu)U5C($TLXw#9A zH6cWYVBGRNNdH}=U+C&wFy{D3jS%;@^8Kgq5`T;y({al)<(D{#6xGn{WmnGkZ)C~E z|K_v4bMqNMbrSAf5GuI#k1NiKqmcQ?Xt z-t4-f5DrJNwcph7@Af4l^4GH@v)p3+eHPNrK0eeAb*{aDXHYm3{wqfcf!4(ZD>G4s z-Ip1f6X*3M27<&jNJb8))aRR|Lfg>C(17`8rM8WjxS$R5Sy3zX%_M9%rYmHql>ih^ z00Nu9z6!V9{+?Jud|m=k(&OEf(z+inA=0LL-KLO6Sj4AX>|)wclt;lWc~YF7Xj_5o zBJzNcGlni{5p$gU_5StdsDkIqNBqmtU1@gE0J}jL_KMLhy^9&nc+$f34TKLGOdDxs zD!oK=ZllFjSunldoPD1vUDVu}4OkJyFbnQqB#J_`M}#;e)Co#GBwC|+qOh^j@8_9h zp|r))yoS>{MxDq+ZH(LY!Be(7AxS;(<(IDIkFB6ttGNrW7XJlM++dIbdV`30fmZ~I zR-(+-y6cUx+(=9pow4I+ha2e@O&|{b-WW{3#9mWI-Ru*=4{8DH992%*i-eLejlkjf z#1rcY*^ihWwM5haSyI;0iK#r$0upwRh}Dz2x&`JyY(0pNfU^L?Hr&|l{YS|hV-vV% z|G&yqABYaeg>xqlJl-SQH1`djYwOR;EzQITfF@w;3}NVx9F3gReoN^4a8@Ktnw8_; z$(RWb``GU;Yvi^co%>&A-HcL(1vO+0g!f#Yano`xhz*!E{bx;B=8tvnO~tlF*oz># z9|$MfCBQ>zSEqkjp33IXZ&mGXZ`*x}{W#YAmcjys=T0NtYoZl2p;B5U`!8=9KoXG- zfV^G4;4I08Zq@G~V9qSEfTHF7YGG10vSgT~9tC?tlzR)^Tl7r?W)9$BeofQyJ*T3& zg0_CP>g@3n260Ji%^b4nUpTfvFC8--#zF}Ptst2)tlwko<$yHj$_Fk~3~^w-Q8zp! zc?c1GKMIdLD`jl87$MJ=)}##H{TA+fvU6%@(CR`GEl*(bAC}Bw^~fw+6=Gg9bOvqE zP^VYSUDC?Vb$;Il68lBk%uA{Q5h_|$*ilz&g91K*hw#Y!K3@04`yBBE`DAms84B;9 z5TRqXy#AE+4k3{hs+!p%W2L8+gHYbuco>Wd4lK0u^Y(6VQw!toO5QYC+&*VCJX{pw zSWOd@WuIQfn=?MX=q43t7yJ_T;^uHDZq|}7od^-Z~aM)|UyFU*6wuWQq+LshT^R-2{mbpPNGwxi> zJoG+U#j&=^{BVlGOY^yFskK7Xolfr+UmQPa-EZeXO?C44172LAyZV@_@_PTk;h7rT zJoVVs=pHB?lz*2Wj{T*Fn2yKs)N8gW$(B8PzYj8a8tl93;23r*fK&XqR137+8_&%a z49ERA6Z|-wwuVf9rKnU;D^F1m*t3=uDz2gMp>7RsXVQ`5*+P&p9ZfVgk(EJR?94!waZcvHQN4A5^K0#byO&Y0J)_aNR8zPvHzBpP^{bZZcSJs_fw`Jb;EjvUao|LUw znC}Ahcu5-AvP@P^PB1RZxIy9M!DIr^?HFJk!Y>A=;f={HGcT;vydjAfsPFCzUg&!z zXGt0oo7xH7QhBQHE%T9G1J+9Xh)M(_ZB{1Z)6(+wkz5+0aoI zu&UO`C{652RW_E-7>3jY`OlTB^n089vT=1G=uscAf+ zRjQYg*g2$bT*2(17-G_KOFOJG>Dt@pX?nuInO%aQTt4+2);bavRBS!oj_jG>?Fj-+ zsj8r^i^aaoC%`pzL4nU9K`ZLdXJmnOswFG!n*a<`gDU+pbSyj>GVTqa6GlFG*+8Ir zc@^gp_1`(VY%XaOq!1CQ2n0cu%D#Wn4e!3u&t6k5QW&fT*$~cZwyMR9nhQSEce1XhN-G|?X{s1-lJ<%pBF*{# zM841?Yh#Ie-Azm5|7#$74H<|RR?tyb-Bi|7tCw01d%d|9$|>VUavQ??j^~o{+~~%e zgWtpnRc%PGF%_C|YD8;ZHvI#^>S>-T>EE=yiHw8A@dd~Stujv*3}D)oug|U{Z@G-I zGQmL`HhK5(zxxT?sWC!ydm72OwS=$G+DyEEX{X9BuHPR8E9z4VH^~-kTzpZ5JMy2R z7<8hMrr{Fz0j-cL9PK~0hn{QD*P#xD^Y1z)hO6oFft$Lo96tZc4d6J1j2dI)djK zd{Zy<+w~lbZ)cQBbvPC$V|O-6IARQ1pmP!&YX9-O8tx5WvJ8J z>(93KoG*r>h!bnje)UB10t#Ud> z%p^;%ZzR^$P&UeV*f7cq$5wJm!nDv~=TH@ES_-n2hRo%_QpT003HeSsj8j8={C#Nv zPw|_{x>d^pMwgLTiWwE1$^M;)IAE5c^e~r9+q|e`e5={tj@$yomCLgjHTH&VV=EV3 zZquMP*P6#oI)6t%&w>;@w3NTk0R|fo_i+Hpz>?3kK}&itEY7k`@I6$_{X-S#Gen~0`{ zm)9`9pxweIoR3t6_4@X9fS7$~96mgl1FHC}thD6m@8KDSneQ;;tLC%SXYLZFeIrSw zUwAj=b_A~8I5U*IA=1#SrJ7FLmcAesmCMP7D$4II3IPs^H%kV!sn(p2C-{8miu0;P zZRk`6y6-U0FtBjo)y3l4O}<*kh&xpQyJ5Tb?P6|QoNSC>>eMujSNqC1m#fuaEsNNJ zh)->{Fi#;6fk8h4tx0H@XE`lB)a4@aZ5<@HUc3leNOW)TFP?$ki5HY#%6qqhO|5+2 z7}f?IUcjpzdB5B+JpC5S5ESw65TvH09^b%q16!Kz?{q8pCcRqnvK(#X(*OJdbEe46 zAs+@`G-luKhT+3umzvAYgR#ufb=KVKKfW5QVCnXd`X+c1@M|VcH7A|zX8j^>kCt8W z{y}}w0xLNt71uUc(`_*!)?E)x$ppRzM?MtKw?r{Au{(f_zyYPW9+5Y^aNyo9-Y};4 z0`tph9D($RcS%`|Nh$j4RJv{G60Q?U>Cx>sd|-#MabJc zTi4c7lvR+jJs>l1KDl@hO*AtyOqyy!+8xk0>~B5vF>=_W7`A)u_R;2`B>tC8uCk3U zVQV3R{`f=eCr&S7@m-xO*qjhR`TKc&$$vSx4=w4nR z+ri#@EB3I+jfI!3dH*e(*d`d!4(*@_rz&d}FBMP^mZt^dGlMP%6C0E091bdgkuzpv zP>o4_96}XcYVfS@Ax8MZx}f(U^&Z`!URuJXpWg&C7`*uaLZe~1h;O^_C-G^PWLmTY z8zpO^%&LVT^enQ)4cC2MiFg^wBlWAYl;~O9=oLI2X5u`vTfq`h`PXC)0%qDI#uipb za795#%D(lou}$Nc?txct$-jszeOJ<%LnmN;2}xE!RPM(2wi%<&3-(|Iy=TtkZ|zCe zobT5!x7C2Dx*5rhoC?)$5F{6M-BPML-*fHjeZGG?7ctPr8FKV8rV!NKtOhipVmp{? zVVrJRiQ6OjHa~jKww{{wlkW$4D*?-ffCeKE`?|K{aTnX zqIR%FuXfyOHcpFf3P-CZmE6hG_*73Jke%0Oo_C0fSN&b`aUt0@DRqOo`hE_c<#gr7 zuL;(wnDT{GNpZqIWEpRaGqRn5H~GxrvM@myZ7I(6vT;Eo z4moNuMzJkh%39-cBo;+Nb>Lf?giG{9OP*DlmeY=zqIp^R=vmtL7i}^FS3Z-z67^*N zUY%~3d%tH}r|6W?OiW@GAX#6kR!b%+E;huT0NS10oGsu)8<-b^^*D17%S!MkxRsG( z?|-+rA=Ls0TWWHW4O%m&Zg-wK#I19tHRque*k&%^CG`na(W&4K>shAgkfDJMJ#f!3 z$5#&l>$f#mBZ_>LSWsGrv_@^6wYFx@FZ3cX;>(>8RYx@{*1NWi+&?mW*qrGZy0Pn3 z^E(uS=&DFeo~!~`N^yLv85c4xGJSLhb{Pd?>zN6Jl-=7twcjLJcO!%$p_dS9O7w#B z&eN7%dpOo(M~z_R9BZ2y_V!+*_dJ+kzhgw9FD+Fm*(+Bl9|$05FK2oM-@~J(ZmjUk zin@ZlzPz@f$U^E?ZMPHzzHMCmuHuK%Qz?oG453+=$E1}fFD)Nmsahq(^sU?+8I)Ia zI`L=z1T>AK$c_vjB%jU{ZljlBW%ldZs7|t@)6N1ZmtJfJg5 zfv_j{tJyfpm;2AmsqWrwJ$8)e7KT>pV4zk|*F~%+$iA?a+P_BbtDe1FAJnezZ~WmM z=T5OfhE|8)MR#K((r5pE!Ez*3brki0$HY+?k8?r>K=7vCFgl>N4)gN%Z~8K%?LE!x zBS(;=*l|W}aR_Ctoik^vT@PjHgW%RTT-Mq)999_X1vSCL-9ZZ6&D!Ba^XsfJy#KAY zL3QkZP~NBf?VB}khrQv6n6YKSl6jssb~rAbm_BZv7LDWGV{a5qefV`~s?Ae##BW$% z!}t3htOrr(;8DOxSsxZ<*}d=MW-*ZfOA zo;kPoI>@Nuzcw$25A8$|*|xTd7E#pDRg%=bek6P(MM!#XQfg9eQbg^fzjR*e*~)() z%yF3$532sc$UgYod>~kUjT*)Deb^kD+&>{htp1v33!Dw2xmcO%ua0P|N3nB}?!Mlr z`Lr#{9iL9-F?#T3e&+*n|33Ns|Ie&hIsRLEUD?ClgkH|jQpwqdUY3A~fq`Ds!qLf@ zfRTfh{okjxvxy_UsI`H!iLi;0ov{hMw27^mvpE3^2OGzKpI{$rYsKNPr~2mU{b_4x zP-pdU$A<;xaBW=6F;0|ViUPCd8@p(%k#?&RQ}oL5>pQ*6PNYz6(7B)Cy#f_XTT?l5 zyTMT0exRhP@s_00I&M-W!|`T^p5UU$V&Zk3Ak99p&j$J7K#Li5t0ST-@ruYjEq5$- zk-);kg>PgUfk0y+3UcCLm{5n|_+^4S*H3jA^Cw^wNDve+87cu>AtO8*>^fN@<5vxE z3`)=pH0<6lHDL7^5P5yL?LV9|b9iAON2Gf?cNF6NU5G^65zxrI2xR*Ni^QN);za(c zs^muy(T!w8@QxM%;A9k5An?wLD+L$8>LwA6{HoRjxc!_^CeVl})3K>VFXA{rjgFyj z0`VmS%RL_f&5GvX8lZN;3%GYLaO>@s0zXi$fO9p(N}^ZqRS_iz#- zFt8ddi7B`b7{oOr0*%ek_$EwUVtcsr#s8c}Vw*$aPK3%i0#z0y8=UG${_-<}`NHoY zDGvS!V7j=Od0g$|IoDwB+wE5+$H`@ zKpzrB>>$eak-4h-N5VH3l**8tdqvTXAXI$E!n)ZiD?l2<_|438Z7dXS*%SU`AWPQZ z+L8^)<8wfSbCYuw@%Ch1K$!$yEZF&D9l>Cgq!?`osQK-v@o>#hw4-Bk!O{7g`=p@W z$uLZos#cCr3o$DZfe_c_aFQqtGcjZ*Ko$p(YQO$*y`rJ|&xVmga7SY1;h!NRL~{-K z63rA-{SS&z)#4>*`tKm70HR`wGGy?`7Ci*yUp&H|nUrPma)d~kY39MXhLjnYO6J1Y z`zVg&Mq^~?PGGU|p~G{d7UDrmhSCi*AKbAF5Qa->%^{C-SkVRQBo+3-zYPQKh%85e zOWJ}3aK+iC61dm=`j^J5Z(pA=j4FLVbT}xa?6k`Ae*Sc885~)HG$4zfp~`e zMX;)=iIcYqy)i2iau+n^*d&9cDVIDu#k|#vZRSu};zXf%emSAWP^ieqhDlS8^_E*N zVXu!_%D88Uo}mIYWi^C83BK@)wwfn4TSbvcIBKy(5bD!dG#dZDq=_-l6{8K6 ze&zP?Ek)*!7(k{+2f-J6VoAJF@H9f%SXI2Q$MSGhrnVNf0OoPoP_h-c$tm#8qd>}# zwqQ__5wIw4MU9b90G`0dMK?dCQpU=ug!>(j%_-QyWL>(~9!wk_9Hg&|k% z@iB~{wp;f)xZQxNQsdkH;mhYOUySi_JUcjQR59{4iJ|vpi|*aj)wN@5-`$HvhMF%& zsER5-A1B{Vf2mh6h}V`?f!ZoZyv!mkb=c*lI0=7V{_N}3jRxHX1-4q!A03C9Uvh^p zuK)KH0`$eog{M60S>QVSqEvik;ob*u!U(o)eH)5(J;?8_XZH#b_y~5B^}IiHzWlfi zqWH1uUKnwFBh5S_X3kc;qnzAbOA&!8NSRHsuCCxHZ#Ca)>^FoqxNX{{8n(Z7L9+rl zY$1-n1u2lKv4en(LZ_SVkATvS!TVUlpUYUWvkgTDycYPt;eF0wT7@0@_Vi?x8*D?= z32~P3zTHgE4xY4sGZ=iy;C~W@KN5#-Zc96``)pC!SE$`mAAQ%qYeji&k504Jo*(Mk zA-u9*>S-PogwaUHj@^ZyUe9~lY3;T7=qrKnA>-J&)i85yi-lk>%K+o`Tp2iduccMH z2;1cr>!_8v24LQk{kfmE2kz3vcZ0yiwg0kjGqv~h=TI)zWO5CS9^13ZTr_rB(^u@v z2W;sia#!26Dn-`H-6xdu%>;KdpEh$eYAqDjbCrs0GAizFBrPCSg3@G2Qs|KA8v(H1 zh#1Hu4&HA(KhdpjO+TTvs<`M((qq`4;h3l^I#dMP=gjcdO_A4U;WypfSTnxwY@=q{ ztpqN)X*r0`NZx!AVH^K`+tQ!W8s-WZbEN}7W3C7ATiafh@YP=(E(us_qrAF!ZyE+Q zcbn(zKIU3OU-Cj#F}=e+!}jg7%RLv%nD*Z%v$l8fLjf}trr*)M>;W+<*5RS+Mj6}l zMn0DSWSo}4%)5187Hvoj%ef~H-zQgag(Wnrx2=%T38z)23m5!Wc*;2)^(lD-_RCgr z_eF?W7uXY}ejkj7xe_3kvjGz4zMboN5jV3iL(Rv^*H*a^nmc7{Xgv+Hdiv~-ahL0w zh6h#ub@0~(t+I%l5X2sZHm+{jv-eKNBLHB)`?y{F)CFJKED-L#?{}mq0)kx|pWH)B z-`e$3ecCt<*`L4LS&G>s>4Vvgc(%80mO)-gT~=3-4(*$_ZOTKMg%~2h7q-9y&Dh&M zm@i>Y_DTx7)pcQAip%V4n|A*a_%?XFnU3=dvCPfGHW%n12f(7H#=36rR#*}~qGXb9 zAN#TF383$;Yu$QPdP|?%y*6gv*Anut1c-ds5(nHx;HKChR~xSE%~8B=kr(fAf7cxy z6u=5zh^x{9e7_#nRcMcG{Rr z-k4Div%}feQ{Gk6I+XAparIiG7Xa{eGs5;ZxAJg`k~$}};;rqCL({4wv$NAg3B9!A zL{z}W+b5ukfmP)e5bX&v$o&HXRGtunpj}_LdHO?&-I+Lq`bd6NnPg`+>zg54Sp#i>}4hQ`0@NGCn{j zf!->M?po?62(fO{`d^%#Q*fqH*QPt_*tX4%ZFFqgPC9vG+qP{xd1KqQ?R4zvIs2yO zo2se*a6gB;o?Uy_TKBrHRuvEmXUf%@*hM>HPdstLbZKPaoD^slcbB z0MSRsUXg&g3ASxTOlWHG;e`tu2M{&|Fe7`R?OPdN>0m(>qc^lB?jWpyHx$8EqahSQU$TmhR;f_$m}H7JLN(d3AINcpHS{aO_}?l< z5wGx;U-1rk=R#V{U89Uj-^bVc@$%Zvl{X0yY^{@#53rjKHiPGO+{*%)!v#erVZa4C zfvgeJOXaT!S_m!<9fg8L&Mak;G)fh(NKz;&9v;diUTb<@N11~`S${Aq2>zN4}@c>=7Zt);yog}d@ia~K>(Wi ztZI8LAXyh?REQ(-N*Iy21&bShEG zx?zz{P$PgCMDj<%Q}m(tKzL8|_-bRj+mohN4c1B7gBd%Gu^!y&FT;RhsB+`}#R($< zEpYY6UkO6RD%jtvTb*m;_5ETtU-2>qd1B>NJ{g&~;Te0@$digo9yX79{ z-_z*ExMR0iomRv7T!bg4$Bh5bm6=T!_Vp^sEOCNoYCL3h}bYYCYK+M3n<9-@f&NPZ(?O%EXg6S$DfmX=_%^R&-0 z)VL-~TXg{IgBh8O+vOWO7~9iLMaZfDMpa+wl{QV*PBUjBT1- zPTFJCyZtr9D%5x;60pyO^XZ zK#@1%+eRSigQJASeZ0M+L>OgH!W9QNk90pHIdaCQ^6$uYP~zT@WDzi^+(eztGFoUf z#xe4snKPI}ERlqN{9Mu=<@XT1s1f#I5#9}T56!eI)BKGIIi?Lg_G!uvEDSK0!Aq9` z<)Ef2Td3q^;wS{7czS$-K{>)j+iK&5rhZ`aaDASm_Lddj&`?_bTzmGC2fH)~pj30B z%Z$DqBR>%opc93ZQVcN6xuT%di~DTo?P6+g`WN^Ejr)wK8>W~z;5yeSHFsWt&p5Pl zUN{?CE5xe&H0otZREz1Y%9&VRJ{?MvZHZ~TDr4Jvn04}4o^;(>4jO`jjr6LT2PTsW zSZ|uUiKP_UbGbHo@WRO9YqqCTw>CH-{YWA4J0p4-f~pCer6rYYg}SGnbHQDQ4p@S< z)k+^4Kg$gMxUjV{r8PN%TNyv0>R+#=pHt!`M~&|0_{&q6u7@EzYjx~JU}vuFv0-~w zsv#?#J4|vnFC}e%1l})Yy&dQ1LruNXWH6R38GgKFV|AYMR>IB(q+lz4{aEAk%>MBf zoH?tKj7v*suh~;4f4I*WDWBUt25HxTj=WrAci>sfGNhKm6gzvhPzrSdkjFLaB5o_z zn4is+O_tjxvQ0@=Ya*YUC@P;a%6~N|{8EpDVd_`vwZQNYse+@)MPDxy7{D!>Y5fab zj4zNRlT2QOY*~DcK4YU*?o~*Urmp<&l$9H7xwr)=G!L*(MWnXxuVGZ8+dql+m2_e; z(ccH?;3~CCWd4(0`g_^f9K6(bB&Epl*mi^-0jKPN3p7sh@ug7NYWbcKykcqg=sM46 zTpXF6D_mkOTgr#j0lF3o?f#PoJAA$7t1A47t&V86M^xNiMuCMVneeX@KgM_qZ=ye* zW{vO!Ot1tB;t;X>HJnTY{$Bm*()9(tza$*b5vGp7fxdYORK<3DCfY9xz<(Eid3t)) zZj)wz`nXkIuVnTR154F+Zd_LoGY!8F-v*w(-mb1B9?zjI3fWweYIFEa;5u4_Uodk8{q2x1=e ztwSpXYVFVLCECQ=aqM%ye}u6*%o{6C-#5&0dU-|vkDs#MtOw=CaS3S^A z3ER}=$WPRBzE&K?_K=KgmVcV7J>>S5$bf6aR~Jar0x}Yss9{g^_yygM;r)MJsVlmR zLLX@(Y@QL=88{Hwji?nde#yq(SGwciYo>A`C~lrz+wZZR%f{k($V$YT$jIu;{%L@U zz2J%M0u4%h3|O(yuU(KVc|CV5fE z#_7|Lzep5Y?PeQA6w zf|*7*W|Iiz`(0rjrLmT9bp+f=_8r$x46b}1k8=_!{lb^*O0ziAUpu?dN{HaEJ&i=R z(CgLsos?vX@HC$^3_qkCCHRU+HP5m=Mk*(C{Ky+4hArFug>|U00bKfpS+fvKV*x3=Un}P?0eO7{tQX)F`}GQRNLr1c2>DVOc^$4W8bmXut{FDCCp<2C5)Ci) zlvOc-BlqX|t9+b#)41s6yD0Ru2tC?v#qbwbs^@gfoLcQF{nuLzh3TCJ znL?SQ4?ta*jyW2l1*`t#gE9Kv6^t4{V7@2LF<#|M6FaN?8JmE~Xu+E|Nr~8hJ^NAU zPMx-J@tuAd^!4WY4Hot1*UbN2XXE(wAK?4{Z%QO5>;DlA)s457Q8vdK*;xQP@um(k zjHR@pIkC`58l4IR7P(|S%}1M9!98poMql_M^9id#b092nfVGNp*XN~(@p#=&)zA6h|H!5M4h6Ba^fOG$ig?Uyv0b?)#m#VGY`r{P2VG0RUsblj@6nVV?zg{IMkPzRUz zG~F36bd$PD=VGqgZ0rKGRc{{P-Y{sys+hD-Vn}4FS9kLlEA;&&-N7 zphJe1rQCAHr)F$sK_}nC1LDm`UwisrRvQY=lva|0?f)bpCH&kLhMEFz_a=jT;)0jy_t)w7BwO=qsb1I-0HehiCoZ1_F@J7Y9- zzP_(OcJFEK97)&W55&V-Y6e<*Y9H+sdNa)@4|GD8!k;vKdP*q_0RGCJaoyS%y{d{M z8F~tv;Zr__UpX&aTrPK|6Oz3CVR=@GfI+X$KiR$vN_luL!$y18zk5D;5?}tps3&EN zjy&Bsiv-OHkQ_a)@E$`-vUf3vLNemLA{Xw2xFkur1)3gtJlo~&Z5;EJ@xQ2ctoAwY z)d*sWe-u;Bkq;$+YLA#55-9xU$7#~)TN z`Tj-pl#CaAi)_=?n<1H#nI1H4dyFg}w&xF@$=@(A2h7rY)Xf*TT^#b6nO`}wDc71Y zDmO>80--sK$Y+Bx6?}DeZ{pdoep?bRq z;&-W|7!d5W$d`oJBy?Mqvs*s$`KY502E%h4&~~FJWdl!U;G)8NMzweC^rLky1e|5a zJi>TN*Uv=}xA|I|n0LD7*Gyxd@Zq1sI2W-Tn@E%j8PJYJzCJ>8)lwpI_bSr9As^re zgNRu??V1a0)YEGCWNaW2@lO_|;Kb-R>bYqP>7{W;$G!6Kr_cme{c_~L2@R&L$p70B z<@_JSx7k^lS^l&5J>>qs=`PDp$&uIjfx%&Zq9jdd8In-M@F;L4;Gt%aHekb}5V-0( zCb*bm4d*H3nhBov{V6)})WbjjDVm&wp`nSPiOHBy4WJ|@4VOD5LgG4E8ke8Ft-UY2 zfiGWe-OpKFxu2I^x!#k8yu4Tlp)6i|FuA6Y>N1*FJib?xnvI>hGiF>P%+r`#S&Tp) z36D5V$0sqnzdQPOUg3tEAIJ~WtZ;y>r2*aNu?GseTcb@byx7#PuF{^fe|hJ)1iWtN zEPXGHm*qBx`vc?tVR{*9gjiTu#P?MFdGyfEQ5o~jf3K4IAkAT)@u0s8o887fW?%gu z(F_C=aK_?HdT_DWW4Gywldw^K*i%u4!z`$2;ge)$%=g?Z(LMr!cV=eH_DuH7jcKjv zuThANeww2%%#mqBlPG4?_rDsW?u_{jQ&?!zk|$}**bZjEnR1z}(*!BPpv~l%%+p{e z(U0*tLI&D?oynk{7{~P4`fd0;D_&#rD)A9`&+};bjyM^`IKl<~FsM`$9H_2}C6H^O3 z5d18FP~0Au#Zl&Ib;#J)^Vco;^{j8ZZ9hu(z!>LX7w7P?^EbiMKp^GLfw%JxFyV%@ z`!-0EY8Yljm@?424L+ob75Vk)3^irtB1`hPzOxn(evA3k$FVFejJr6BQw-hE1Q+I? zcAjKL&g{TrUHw#fvyl=(0hW%GE6HhbD!|3kioR5`Uym{k&%2B-KgjsE@F;u?DV(HQ z+XY5;69Zt3-&FVn?pYS6#dYQZTs-zNSdi>=F_iCwN8H!#6N{z1+lgm{i}j#&NcSM7 z6BbpGTHXiWi~VEi`u-eE>1^&?8W%VC?yJl+z8(DO_splAsfU8oc4*?#H&N{dO%QMl(WxRfRK3rs7eK^In07! zLKY3|YP(K7sE`f{4>yd%i9z2ir4pa+w4M;QkY=wsJRSEjep%f z5$$|^b;z5z1%#&+pa^*k_)kqq5(Y_t`HpUOTlV=vj=br4e;6e^_`Ywmu)?#)@P>=M z$bO-_Prz;pFxK((3~a7uEB~eS!gJ{6Hvp8}50*EYxkGe+wt0c)Z;1yv7<{QRh9USf z@@oi~rCmTXigxUfD43Jcb%o9x(-uFMIL2w3BLxApNKK#Vh*o_`pac$nA^h|)`M!#m z-FJpU)S3@Qt;4)QHY2!o_qA_UcWEYLvx|}Y4ex!G3ekG^gZBx_2h6kk85Wy%pHB<2 zPcyzAs%MOy23I9oPW08yy8(c@^RaYBd+hfK;`6>i zjh`h{6E|m&;ARfr8PBQy+?a8FtnH$ZF~gJ;NMk?~@k%!Fw2GY0Kld^-GOSqe=L@GK zSp03=3hH@V^YQS4?*pgk;o=z0v#Wr~dXDQ~5W3>XQ4J3rajVbG7E~vQ6j3E-b5Vb3 zfzICeXD2K)=cT@=qO+hW0p&Ll6DCGR9wPXlZObxQ{d;X0 zUv=@hh;;WEfEOKL_(@u-P;SR;RM<5H6|zF zu+WXcbqvIGbb8f_<*IoQ0Y@?#2WTSGNNsps$ zNp$S4`Tnj2|IOWF??>&wGiuNp-H`r?6boU(jP3U7%&X=E71NYTAf&~c(UYUf5bgfX z7Z$j>ALSug*rIB^vTSvchk)Kl`RH1|aV5NeEU~cceO<+n(E`AmengS;#MF;s!ME9z zqCyq&FCN!WSyw!$Ya-Pd`^=iW%VHQl!B+Yl(DP31qi%cH4tywT#_Gt~KPp zF+4FQ?0(rxggh9Uw!Dn>OYaX9NM=u~s>A2YaC=fEo^kIw4n=sO&C=Ux-E41}CIoc~ z>->!U<>iI+UJtKOTRkDv8R{L*M%zmWx&XF9DJn_QwAb{bN60d``bGCmt*|Ah`)D&+ z2_No)h{^eLcyNk3Q}B}JdE~Ib0hVRW(eqG6quK26SJy(aJIXT8qylF8!n1bMstelfhZj#*2Gi?W#w3j(hFy4f-tQpODluImR5Kwh zVYQT`uf(IaOKlIY%xPjtZ{8H6XJ&$ZJQ4qmg)cl#uk@qhCE@B8jP6iE+G&Cg$BH9_ z511D|`%Bs7rP9MvVVJ9S&o@H=e=q7sK8{JSOv~gy??7*-1o%McNbh zpXk8Akv-&V+t?GJ%PTGX%+4Bvj%;SuBBT9WyR*L#p=GL4l*B=o1du0RLK8=W$Y15R zSoSK;bn#`_m`sWdw6X-KR=D-8$~87;b}PV8wa740F^U@q&6$Z3XbfBs$9)bo-(c&= z>bH|8K;roI6&cv3XuXA3Q)4jJFTZ2`9>~p1AElp3%XZNtr$}Q#bc)yf!@%0#(KdcMn)}Y=GSs zBkz<`guc09g@{oB?J&AUd|@zS^_wM52Fn()F?ge21{l(bA_%dW5D@iTXI05LBud(HbVScX=a z@=ANfY3;#?GR$(*-T)frxJzd$#Zm6)SD-O(aiYNcY*5z|hz|&pbeeJyoB1g-Q6RG; z4sc*3^iIJ=0B`;hs&Tkqd|ffX&|ASt^zYBBVV~3T1+pKp*S4Qa$E>Z2E3YpQxOO9j zo7p9braoqWLCq}YEC&ffSVkwcSTV|(P#?y|Hz!w_Ea9q&wbvJ1S<^FVE-Jfux&pgD zpswwJHvqFS$(xdN6%vJ6c6xVI2>STRl9(Bb3`dW zLE^r8A(FWB;y1j0yoiAuzkl&4h{l~&dX2a2)Toi z2~^Wxenv(WHc!jrR|Q>ld{uu6CtA~`DWq&I5jIT+5VU>`E5h-VCry5k0&ZK;1{o#| z<+Gzbq?`N@P+>22MqqXcgOx!f2QzPT zs=nrQ7|%_Bc($9>=0D?m5;JmnLb&>e?EsCw{M7!W{x|pzxL(c9-zIJ71Xv zeO~yWExEfQc;mYl=0TKR@ z%j2jj>s4nF*Ju0&JVdI~ExUVG87>Z4Z&>^8+&1bK#2UOc!N9anNt z4eS>rppZ6_STcv>qVObB&PB+1j@G-!#_F@ixXS zN2+)z}=rq>;P=u`%S9ak=TKi71`K)L65X7d^u{D=_7P*u++TKUK5O^*?WVb!>nq zF}_Y9v%SkJWyYdp3Gl78l~4ss=A3tKv2U=}Qp>9xF5Vs#U#t&8`a>}YXnx-9np~qz zKtCm=X!iK~Tr{`>AEUh+bH-#tSKi-kuW>1N)nK9yeSc~!BX*c)KvUX7{aIV zoA>L&br!I?8oYRQI%^RtT6erWrRg}y-VJt_U-B zVY{88db2p{6x^U|Hf;1S;9gaZNu+BOrOXXY3wUWA7S@vtG{CGcTAzxXty~A>OdkEV zh6$`aqnn#MA!e)FsR<)ak7;LRvS?rLhcMq`=_2qNv*4coAU%M& z#@?0Q1UJ!I(62{jZQ8P`b>eE{B-l>DKRyM5EF0uAx>1r(rjqxm{q~|L9BZfectTXq z{38dj=~&r&Z|wLp>3y%djZdA;9Pl!x4JaVS>7Oue9jTpwjr3Cx#rp6WZoau&w3_72 zXbhD>eghQ86;6RP83MNK;{BJBu_9q2@UW|yxg~epc3)({d6+X%Y#)Ok#iF@YbHouG zla%6Bm6i1rZ6j-A(d|N}(xFkJ#jEFLIS(`LAHtq9S=;IQ(Lhd{Iry__0&d42tEru? zt@Z--G7&vi^-Q(9tznbCb0MWrG|$-~O6}AG=-HhXmap^Y-{E1n}k%-K|IO zkb=^sdBwUKw*t6iEfyAx!MDTLaa23Qye?>mHDgSt&jz!PwoV6e_-|~S^o&SE^QV?i zzY0l|jY*pdT7ocE6yqZ?$yPA}^?j;}5|1jM-SAIzFW4KFf2uY?{cUp36O<3B&(Ao6 zEuWs6H@}FFsjkzg$b-2<(MmXP5iPcf*7Q)FC++;Pf|r~MkFJ1#KAJwvpzhf{@`-ox z@;w*u^imqC3R_^WxHBx>dC73<#&J3Ghvyxy6&H;Zd&mNuqsM87L0QcqhTPLBaTQ~k zY+4;VIZx%p3>a33bRY`Jp_FPPQ%lC;P*jrF1|HkCqEIJ)b4KK2)UsMJhHj~;a9qBK zv(Kg%7oS{D&xgw;Vre80nw~Kqe9|s+c3zu~QP*Zgabu&K%q;hCh{qOIK+mQ7bTbq4VwD%B}lbt+7)&`mrYCo^7IIiO`ne=E0Xj2=t6ENxWkj4-lUV$Ebsug&v2X1l^+!5LBrXOa z%+gF&!QwAKd1w*=Uhz_Ad@dEN`^>#fNGO16re!re=??7GVEf$`R=@(i& zIoLla-9~!G1T907aX> z)It1CxA*&ei;>+X_n@N5g4k29Muqh%gB_3%>!3^pnN?z@ljtQPW)W}=LP{wmGqWAT zAgtfXto;!NCaA=fYe|7*yKj<0$d@bY;z~?}|12 zwF(+={OVYQ zzd6$!iqkw#l#f+~x+nx7kRhbiqp9UBv^@2eU`O_Xn%~l{=|OT zKclTQL^q#vB1@W}Pq2G46Dnv>>0k(@*WgJZ@k{M^jMqn~oUqauTP|Qc&)JTDNTaxP zb>A;tQy)itIMK5D<#*;8&Df4G^7z{E(ok7#)Bt`s#g1*Y2asQd^ z%%XAgC1jK{A3}l%iT5hd?h_MnO;dDK^P4c8ozy`*$oPvqCx=1vA1s zl*R2-4XQ-rn8C|+PF}&diqXQ#Y3132oU9(X+10pku+r0Ukoqmu%vR5a*n84FUhrWSOnTO=x9s!D{Mb#9EnFh!GJcBPIl*xBuJwP zrepJHFdCJ4giNXZOU?5h6I{a42?@ZQY@KY~9Yx#b>s9N#@gvV`8RpH*s9TDGB=-oN zQ8BLI3gLVJQ!8HWBiu=ah$=2BX(4HV%EgbascK8hrlmFcEpF$F2l~P>QBOpg6kL;j z-)y!&X@@fh!yNP9_V>g1XW#C-FOd&DvUnyiHM<;|Evc;NR}4H#aGnavN`NdTJa+on zsOk6;voe$4B4_GJmI`*ifUcz z81~`9EgLaFGZ+MeZABi#6Byv|DsZ^X)`C65qfE!>z0bsdL;NzkY5FhC7G|dZL9>O8 z?H9*?Hd~4{+`W`l*Sm?a7!@M4S@B0U0}9Ig@?zj3NYqS58fuG^YN(y$H;Sa6jwtM( z_-xl%w=%Dj=0O`q)xZ^z{$%EILN##4#B5|~+h^bKSo&j|KfHf$Rc;=jV zZ=dKO{PJM!+xt_1Srz8#Jho1GkV3D`3J^a`I_%L}pZ;E&tEwc_a}bve(VBt*eORS`Bz zPCCEw@PY#uaNbMNBZSjM>hD24i}_3r8{5+vHjCNF^n}zDCOM_)2!k|=d65};_#GpU zk@^u?q|(s*Dm8$4aDVe8*Q27X&CNqet?wc0;~|wG7e|{8#eA?vhW_^yqm*p8H$9~` zUI#BVEt^YG%o(Y`zGH(U>`?h@{e+{E(tYEv<5P=$pM9bI*SUM~sS~<=x}z%MWk7;> zam)lEJ+|1NhoD#yRMfD$L6JdSa4{JY0ty0R0&)V<9HJbu66A&Old!eH`$1Y!ygQmZ zoO(Zv-*hAxsM2A@gUm);cihPGRYYpYmEmlIT1NQw{;R)jNJ{pT!{>th@0m;e0Va!W zikT9x65f6EgnSN88~Ad13^(K1(5^lr2vPA-Q@GEYZIO!DiYLP}_}`XIR{eyOS?$(K zTQl3b&hoe0Q_oMEsem1MFY@ou_YK0dw_bE1?@5f17_XJfbiwV~{C)A-zMEWv2Z`=^p8S25QiQB?H-og_&VWgPF4U97SUDeNE#95cZcc*=F z%o(o{TZ(}xA!(%ncq$Ry2OCzKTLz?Hj;`TxA$Wx}f!-#kU?B96U|6HfvAjf8Aoj^? zM$WGYE`?{+z|S|Ltl;cVXW1HhT`uogkmly(YJa&MXr@Fv^jTqYtVbvJF(bcy#m>sRH5BM)QSJ5!t4_T z#8eE01Zv1<4N1_KL)5}2h86daDNWihFMZ0U6?Fe3BXZs+$&`s{vk^Xk*Ow|Q#!%j! z1vdo9YHMMv31HRtmV?4Ir!a5mU2^1Zn+5F4g-F1eVO^;2cz>Ox;Pltivm&jOLePEx-=N_Qq=K>-{75%D{c(XwNegkJhUeLTulx9nxeNQZzd+e0DXyzOG0LkkgIRu5EAf42zrNerR8`bc{ znEiFl7vO3oCL)iehU7uGqB;DUY7i2e5p(xN2_o#qa%6=-upWSUY*vC2=X5x!vtSe* zK<=<(Xu4?bQAo$pN!o5nd398F@G8eZxp9~f9Pm~*H9t`T!`Sk}rGT-+vO!aRzllv; zanE(GQ>eGFZ}J;&bIT_I;sdeY&ARrO?I6ZA+))kS7>F3aU{+k6@vxDzhhj0th~gO# zu0U59E<0k(+u5M?$y6$&z?^Be(Gd7u^|%QiR7XaQvSZkk#paNTX|v7sp`eOws<;x+9d z5ILvhSgyT}1r1N3aE6kCxK8G%7#5~JvTtlyIuO7#&-|@YmkUb%rY^ju&zOtLDvjN( z%UR@E^}#=eaIXuAa9P0P1ZH#rs1y}$2LqZfh!B_Cr4hBFG<*fGZ7l39r<_xNbBtrs z@ie^}pW}GBwtvx19%gL}`JhrS1HeX8;*FeDj%~OBMH;WQE==zo`7V7u+MtP(m0+l= zV1$MEpw>a|sFuYJ>J?1)8A@}?;dHUtn2J}vEkCe74^oh21o-)6{MJ7CS7`Dz zKo}9Dh*IGkLbj1RN3)8o;oFw6o``cyM9YQ7Ayvg|>*ozhg&a_ixFA%m@j%d6b+dZPVGhtS#4@Jy+_uAo*zGijH<0dk;(oarF8b9tG3xuR}NcpeNtG zo@**n1T=qVuBb#`35lDU&5|hMl&Ir!*>G@{7mCXxt5MlfvCOlq3HgV8;(MMn#)1G1 zWOvA62(2nhZ=@;2k+=%(1=%@6EAz^;IJqg`moCdBt%exqN>s@#hk|FIRH!po(LKT` zAjk8fObTnKzxBedL7Xt#3*n)ec3C)ziA{6%XM{5?NK}jyM}^ zHl!$z7$uRr@zmrAk-OZcIo_x5x6~r(eP%?`hEt7Y+oqv|;?Foi=qKb$Gre8}tI9J$REQR< z#G$i(u|-RM=F+xS5ReOB5ne@eY;0*_b zV&lTX$r)RR?p8LH+O9=Ex|YOWdypjb`QSsN<%t!^J_WUeHV;MAhS={+ZGU`w@D{+JIIf%1^A@A}+hav?S zsUMNu+}YVQsQ`-8kSC?MwW+akKYU!Hz6QC5^KWPl;7D4oV3tXvjwg`^r%2S<5 z?|1z3L6&;l{Y$W~W;gZ9J~)N&}|v#+tbB9s*+nl zG0?UWq@p<7!}O;Mq(gFNdp_4<7iGRnrUJNhv8Hm9SW|;vSE$!j%8iM1jN*vljb7`B2^tz7{Z2?> zj1;RWiCu(@a!lpWk!A0fN_p8d{U(F#_Oj{+CUHCNw71GHL8)2pZg%-BeJbjN>o_yx z=oI|Rd;@(JoDH|UyXY;xF2S59f!YCMd~20h;+&ppMJLO=eKgF+j~Sfe$h9$%lgEJp zdU3o(U{JEcS@Ub908$WtYv?7hwr$kfwGGP}ea&tB)3AbRn+Hc+2Va4c7rLw|7sSMp z5x$GEBS2z!8&~&K@nk9mTuWW8#pS)S@~&yA&6>K*bqOe(-0?og$tm8Qz4_kohuUU6 zKEYQXNu*f4{Z=O#{YPx<94S8C4$3Q$Z6EFF{LWZ!cY9a0C@4TVDc9lc5VJnoN)bZ}zccvR! z*40fv|4ab)u8OB--1}9ltDBwQ5w6xgf37;jG2?dqR3>Z1>9b&u%d}91868uKEkfov zn#OS0z%WE0D?89bDlQ=_O)Zy%^9-@jGMp8( zoE-0t>gs1NL;T5I+1@qs<&E}x-vQQ4s4_QzJ8?=ax^cZM{uc`;@jPZ~?EM*YHP#M$ zk&h}w_o_M=4|yC)VZTwAwc^o$rcV@ zFxGCSe4=*EZXz_j&OtITGPLlygJaIwXb#n;Pl zzs76LjXtgv`w6esiH8W=EPGRglSwaYdsWS`(26q7v5OQap~;wWRQ7DjVT$(yCH~az zfy(1@czgj+4qr#j$0GK6yqwXb4IXY%`%NMQ;v19~ZzfQ@%Y%cPSwX|yKNa&Mj?WqU zuGPrT;;Uqml?Zc;VV(3}oaD~v@&b+RbP%1;?16E`H(kE58UJ%z>&T{(+uFYAE#ql9 zI4kBjWXsJ+ZB#a{n3m43bMMKyb-O{Y4GV=s%5m}YtUA*d_eC4rlu9_1p^*CI z*@*X-#N2@da58XG!zZS`4GCtd@bW5D6ppE zy5CSo@MKM+RG0n{^iMS;?jSTxeM!0T$Fa?Umg{%9xm&gc%9H+kPdB8jVJ@;vy zqZe&H!~Om$gE#ck0^3%(y$^u3z?SWlbVW$3boK3a9TYiEOiCa33B7Rur`I_bxTZQt zjYy!oL$K%B;(U1ZwUnmSE!9AD_V3oXfK?u&4Y$eis#eVX=%*E|QGRk&{8Myx5W=#Z zvcdAlYJJAs;M06dcT2FHCfe;M2313|siks6N}ssndHM%OaA|&{0MeVe2=O%a^AC^R zpQ&R8zrQlwljlDII)#ZxZM0$wN>)=L&rIeW)y88q8Lv61f=HuJ1~Bpc^|O1Yd^dDA zysSY_XaQ{VqA5w_y=n>M45`;bfS3Y#M3~T>$G4iiqA;(_+I-grGC0zRrZB6N#3R+vrUjm*($3?F5M5 z=LkzMFfK`SGRDTzsitJ)`+amFB>G+SDuK>R8mDv<<1-sMbvW~aowyn}3<6Y3IhdUd z!+TrWL-z#R*RtpHgn)hWOe6gb$-3EP?;7>J*8q5%W69X#pI?6Ldsq;5lkcH2L9xBC z*D9OZ($LWRfySvPL69|*_sJ0H%cbcRHCpHF3!ivabjU0$*5))(|0+l&k9;yr$u_P8Xlo#7>R{;m- zSBi?K^WNX^Tr_~!|5oDt4_oU0n;yf=!u+2lU0sDfs{tmsu6J4|8|(oW1is+jlmtVm z*14t*o|Xh`oDI%tV&9%sc)m*_|D5f_2T^MWv}Mt}oxbva)4apyeu?fI~w1;Qrvhc9le0D^4RSE zx83@mz~fmsSXlpa_o~&+Ra7)vy2XUHDoJRLyrZw&A_=nDn`8r93bEGxG?CGxe*X*? zqY`9B16HuBih_Vp!$hbMl?w(9`vKueL)fDt_NZ5_D!1r!B11VYw&q>lx*m^rI-9S# zt+!C0UZ-21U!VAS`&ZL;@7#=6s#oj0r$TBkFI(3&aJi4&4VT^@_RvsWVEUMO)l3Gp z{;thLl_G)LFMx~inBlFU2t;!<`R--haUBQwji4$V>?Z=$-oVA&E+1N3a;!~l`9>JX zSjG2mE-($b2CPepqpPnz)=~gf)wcAhk=|rqdIWtbPXx$5{6?`**Oa64zXm6EC`pDL zhmCr|!e)bayin26O^=8XT4CZ}d^i9trb)g*xkqZbe+b9;3GFAAi2IOJGIh{-5WSnmi2&4VC*g}-E_$uJEX?eiFM)dy%uR*^5GJ`Gaz`>)Dy zqR0)h8)4p=llIp|gZ)FaSr2kJvdrK097ev%N3lfRWFEqlz?c+4tjX{fmnc_KF;+M) zE-P*o;*Q)7)8XAuvra$sX?U`9uW>g%S54ZyNVKuZl(}yWyuVzQ?8!Q5)$>wf7zyRX zr-VU%S?7z1{~L!FDn1sbX6e*Z$bfw%83i>J2VpZB<1dUiD;hE>(llVVflx<&4&L5( zUeui{0J%!$=8p`qJ&Q*TP_eNsK&RSJU2+cwzMka&pn8x}fHEiMV3V(aQT9;M>Ki?Z z4`lTeii^ca{|(NJDW+j1-0lP^3L3lvWz-8j|5S=GadDKLB-%TiN2Aq%iinrEYr1Z1 zVNjYf@P|ohL~c1>3BI1@*6FkB%28|~ zkxokDI@w;iNczM)I71GWq@!sL1)0peh}uN1QD>#iUY@Rxmvsm}zU!oBGhjkRUFTcs z{YXxqX*b?_g>}RuCAd;rgUY6`yQ}98{T^xhe{ptBO_~7fn(ea9E_T_rZQHhO+qUic z$~L-e+qSLgb2YOg_Qk~c3mKUaZ)QHvT6ne=mrm^1FFc!pFl8xmzc=P{|o;RU@XA1&;nsE0usz9%>Os_a4(`qnP zl`c2s2i=^#A_(>va5QqGiCa)(yzrJ^?^v^us!hN#LMV|@{7{sXbV@1H#6eS;Q|fIf z*dzwLlVKzw?w1nQj_`3_O}>2c?Q50XbNDR^IA&cS73OV3B1Sp!5g=G>H;Rn%XBio1 zgz*7g+{Y)s%kH%Mc>U9^hp6t{t#i}=4uwWb&P-35JP$5VnI+s}GExe9yYoBrsLKb$ zo+_kej%1#`U9OO)ioykg9ObKu2?av3<%{+Mk;g>_o`Qn2?Ta!JU=qYPrP*>nNLmu(=ZPlrQiSl zz%`(-4mPP1?I7@dR;{P9f1KbSX*uQOh!ylZEV|x{a7H61!u)`9B0wzvqd1kpsVftc z9N*JGj7>@}K3nVw>-lA5&X`jQLu_LlLPHpov2l8}!N&PeWS6kvFHB{eaLdZ`NYx-Z z*{u zgsw=zh9wKN(@>m`4%n@c31y$6;ozll$=O@SOt0z=C1(a8$M`-3Eq8(Z{&~V^GPggg z6_m~&Jf-pJJ)TsF&HZqa^LaW_3@ZW3Jmt*MRC04h_{-FhJ25oH-<%iSgd~vYEtQ_N zx~4~}P)s>+WD#E}uEftsf|DTmkRN@9x@o7ugz{tIQkOM~o0{^LV>3Q$k)L7-uL2PU zLE5IlrxoTtYOTME5xRkMZP&%ryie47>V$jIkF@ENMTEIFzmwSGc;;xT7oV@=g2Txv z%g-ft#Ov7JRj2Xz+HA{tF*%ouJyL9+kdYZY6Z3C$P7tpus+aaRz9dgVfDjYqD~iE- z)aZSiQ=8^Q{StnS-3rwB&*Y6vpRgwJ!?3igFfu+vPESV`}csJ`&6fsYVF5)b-(>}gq;r5+E z30fz=k*^KIb->m>RHwej5F#x)JZ?{^U$5WPZ=9$(5Gzeb)~z$kaR$ zFYX+g!w1`G#TgzmR%Qf&tkW@!&~n$Mmvw zT*F&S3oHX5sS54`e$&Fk(YIS3<~QZsLVI^Ra}K+}0vLvxyX2UUm7Rqp$L3ZJC@1lv zKa4AdeU~x2f;6{zENKivPxQfpq3&^^ucHwxMHd5AfkA_VK|xgm7w46g=a}9juRo6t zl+mPT2`Ra5makUdb+{c;Y2L`Y2^fJpV6DP`c}F(Rc1k#OneUVSd?%qgeHf;Ee_8V& z#4JB3@T$(eYuuRiE*?<)gp>V@oMPHKU)w{+l(~0*j$CT!nn(I$n`9Kw&EAnWzq!Z| zGad=gM7R`J8CiK}kc*4U%KeX08%*AjJ)R~owCe)Hm;9Y4!o=829D{nO2)9xjfep91 zg0&c^f>bpOm}N=M2E3E`7`HVCV(zmCTeIL5)YCa?`nmG%6uff(Gr+4*30cfBidY9L z-h((yz)SqppLGZQrbVY@nt!ckyHU0}7Er@eUV|>6AX+4)Dx)MvKnBE9)_oHGoH#H@ z<~puA#u}OSCgtjn-F#be2t0V@_`BorXiFJOlV6U^Y~!u-`q`Ruyl*Vl*EnlJWZJX> zodv$dd(1Q8LcLb{R7cF_FH;>7gp?L8Cyy%i@)x>!%wao{-+$%VW zJ2#Pc6j@JZf5p=Y+^F-r3BKl0ZX#!O(dn+Gaqm85fUkw68M0mLIR0ES6f2F zV<8?c#pJvt-c^G`e&+q%HY%T_MnrMVyPV_X&q*kbJVkNFZ$A<5m$Va=R1y|< zryeJ%m)l44M|lT{VauoU8{ys3ySZzr=s2ife3IqO1^1Nxjiv9p?VR`; znOBSkS+b^0T-T7k9RM{p99E?fNTzrg=l2r<{vg?7bp)i`Hqbp`J?(r}oG zInmojvl0d!s_n-3Zm^%#Hhe6X2u}!(ggaw=OWLVd>COM z=1g`U$haXC(|;;+|FfN*ecS0(Ha;SPpnqPCb=*x#!A{~Fd%Vm7IM08NI2|2SkF!u= zL{(c=TLv(%{&dz+&QZ=TFxw`hI!S!E&ZqaYM0++(kUYf+ND(4G&JDMt_#?Ix=c>!+ zodQ2%B>~l=YPfQ?zwf!p(HKRPk%JWo(C#vW)(b;J^Eur_-MzqGYh>(CT#bsco@HKJ$VIX5x^JQGMK>&Dj=$LJid^44Xbg^nZq81_8Vp5P)zrxZHKQT5;_Ks8M-TZ` zRXy4hH;(l^%0`exz|sW9YI=1r`k@?r6czY`+k=H+ayUCBvLc76Db}lo`T)48?xT2T~Gt`EW~AqNxbI~RkM6~ z`fpoyL9IHlLQZFaS#DZ+AKO#oQX3b{nN`Bd3S*E122`y%n35vB!!N|SuQe1On%Au` zG8T}@61`MzbYMVCvT4P7ZG>#G&h%3YOZYR&fB=_g^UeF(%-q76z=)_ z>yXI>vxiH`PKvkc8P*@ljQhg-T@#a2P{{kG1JudlHd;>(tS%{yDLQa<4c7OqxQ9I^ zOy79ZQH52hTr`$kaPKLFPDLu`BMU&8U1CmZcQS1g=xAbtoW&&~5LE1!JbacZN=i#* z6ztMFVych{&&eCb;jGj`17Vz4fG;(K&qZHi=1|i!pDScW7>i;~s$|3p#87^)|A-+f z{kOX=^ZyNh{cm0dE-?os;7!61F=>I6)>Aq{ba1sK;G%4BPU3s@E<^ELeF z@!MFCPD$8F=mqVn;n~|c$b;b_j3hJySSf8)rY)0m}YVjDWCml^xRqAIp;bbZguT5m9 z2&%mvU>b^=Hr2g-#<=p7Ilg~^Hd#;ox7A|(zpM5CjSk`XPph0rf{(P832NBR#*7pN z`Ke1=|5Z*NbyZ1zFay*_xqX zuBJ73W5Uhe_=Pn0PIF`7z?rk<wCF?rwu#t8UAn64D6d+1V zRx>7G*67+jg?**nc$Gf49f3$vAkR^P)*WvXCXc6>PpBM?CjeV05-y0m7%W@lSB|m> zr_ek~_6p5*zZ=WHpFEr3n{oGdYj-LYn_ITw+s!0m1;qDu;maVr-lFqzkz81r9(Hh> zfm4a5n*P=BxQn@woC=jvg1mkXx$IjT@xTPxa6lova(9cr&MrIIU^p7#SIsZ(pohEE zsh;xD2||7z|3^`WPRjdnvXov*>TAoBlJUr_#dTsWSjm z8T2)2^WU^O?@*@6awXD^&2*fA@u5$DKRvJb!kSux?;cFOK0EsQu{fprh^&Xanf@8( zX}@PJMd4(Z^-3aqPcmeDY2B`6aNFlgwJ0-Qu=ka<4lFe8b~g-#cwj|oJSvA1UfVLT zluPPuva9&FY!I94gB#e(K;3+api4fNE((&aR2RK>QR=!g8flyX_!b1<0ACD^aZE|- z*MZpTwzAwKnug8-gY-Q7&`u2pUELe(EY+`9HOngR);}hUij0(W&cvWw#4RENP`~Hm z#*`vA-o}th?p>ud`Y4H698B zvVPqZyX;EBQU?I2TD(@TZ|NMbxu_Hvf{7#-jou9AM;1g*wxC5Z%tvw?j=^g*uk}*{Z5MYV0zBL1$}itxa5=K#MFj z&Zk)yzoSl3wTls1OcW=c~Hpf z%JyXtDq2CSU?pJCXvHOt56iWF`8RL%B|qsNc<<{#(##0=}? zFw^|%Fz#2&uaY-kVc~CAkZa@>H6O_t!ZZ9;Nzo|MUpaS!(pq(^*2$^ivwiJ>Zi61oUzB7a6`8d5U0x^s`n*_IMZ&IK>=i= zDqSR(v0gnGKkz*Nx`5;8LL#A*;M;i$-AaeyU&_jr|D0zql?9x_n^&e^6{kndIcQ=C z6}<>D5MvF_4Pj&8)y=9~5{z8iGwwsRmH;xE`hX-&x2*SA)m>QSkuzN(qk|;mfQLZE zC1yN6f3FmRqpU)zbdpMw_HmtBzQjC!FYqxMylVr6=z}+^h*l_TL@);gy!vpPJJSa*!Zw^bTf9OEBZU93JNR0g;{+n+ zcXa?n$qn9Fohylaz7mX}&gO6rNy#Z`s5h0#Ei4!rv;1T*q)g)WjPx4hPdUsUU_U58 zj4YlXQgywp4>d7&C+7p1mdeHy!bv|9YTQqeopv=T;#B1_Y>HFr7LR^U&zYyCvJxix3kF1KRAhwyC9?R$QBHxt0V zPD8iXk4}(Nv07187M=eGS}szo*N?V)-b63~GMqGsZak=*ZJ!Gji#L{W57?pm)SR~+ z3wpv02DWwC1+AZ!+D#=MvF|#PmO?eau(0IILd;{p=Vx%vk({yy z?KhbuM5_>oxUmcbCI;6xK5b%Bhx#cVGCc$YzH#X`F_nc(&lrVG{XYakx}*{D9EYca z&xmgWsIW?d58O%QfLBIEG{!8`kkXY0kbPTDz^Pi=$PDnEgSz%~(D1QNsHKt3AabK% zW3zS}Hnlv${qqUwW{uL5*{Bo!V^~eU_#M<5J5#~kgt@78B+Ly(+AvFq78{TPNlf(Z zuD(^%S6~^R;|i`VpO>*S?B*=Y*5q268`*=8FJI+_>4KMc#$nUr3xcVcM?=|KV;O?% zho|RcN>0pm*C&2;sUh)ynG~4*H$56Q`u`Ai=p<-~CmG;`?bvO&*=Lr`C?wd5V1$@R zCkl=VYnhN$MVO-Fa#P!oHFBWwah;lW{7CC44@POz0BE>QfzR|y2o((ial^?8%fk!T zRc_4e4B1nY%@+(@{F`>@11_5X7xc#~S9QmtXao}i*3L4#?{h?1g|hG{lE z5Load%50ZNB}9#KM-4*_PyGWeAy4rx+AMLHu#h;QcLwlLy)af(p}v0a+Zk~Biyuk& zj0D?u?bXJ2MUBH4P_i~#4FO{B?J*~o+Us(|9OH!9o%a*g8a~w|)8@;Q(_(iRAS{|Qc=0Q;0mt8GLs-vESaxZ7h z-``N2mw=A*7xzv&H9dx}BXJTAMnsV_>QjX}MBykWM0_IY@haM<9FS(SsiA?G>NS zn|gA)jL-k=U@-nKZq01$jQ^2FX!d|o|Hl$}7B#-Pl7}$VysR_2kgr-^U$?T-YPM{a zEoTRwh9pFUL=?wlN_d0GfP6sx6OSlL#xIinPy8Uew7#xsV-&>QXT+O;qUK{RJ8)oL~D1vKM$!AESt(^o%(6T@QG9C z8G(4sg?!{;L<~Eah=b7i_^8e&Bd6S5OE{El5B;c(MEbrUcJ$yRN{5Dp#ANr}Z>m^0 zi9$|VSTIx^363l@QcN1IMkcY9dN1Qk%n^-+bkEM@mw`=Zw5Dar)1G{(UR6o7tBe zAOs$Z*XFKoGAkwE@u=Ss^?PK~usH}E-qWtm`?iEYLFgK;nfLKl2qO%Dd;B|>@pB7_ zga{vd4Ue1Pm9y4x(O*IG+vqb0q4)9jTFjJp9-Yzl5vB-%hx2~!Q%sJh)PwufVGTtn z&)yN%O`Bd-o`uwSaz(BqFO%*0tUfPRi!B$|&piDGO1PkT{uclS;0ng+qu4VC{w?Qb z(rV_WV4*{T+UOdiGI7Me|GepZ=ekC^I%-R!;kv1%baHeVy_}<(0ju#xi3*h(nfJ5T z(>L9&0~8>l+_&@o_%`MiW;gHugOc$(0~IieW)_&OveBek1B>;Nyu5ftv4#M#3cq%? zG~iqxuf(LPU}FlR%pcKRK3Y5TbN*)VgLyk1#zbvf@|SHnYO-cGk1qcert3P-=i#ju zif>@$bd^|$J5A`pF&MV?!^dfs>~Q7b{f}-dTMSZ3x)#_emS={;%Ap8MU0Q@1C5FS7 z)yzw+Pp=&yT|&0L3C5c_sBApww#d!gJ~JC^sab5>mKRF*w(^|VFo+mLQNtl+^{TSM zc6V~Jog;>dY`(cLGmLm`AJ|3LIZ z)x+3|%F2*(V%&0~vK#mMEB9+?X{gyGCHJ_y1h>yKgWd$8=_1*>^b9M%9N>&bRBv~va^)w z+kD+Yf2V!!iC=HrKe5 z_vqyL5GSL)v7B+HKpwI3OQ__Da|6LGrm(6)M?LXITLW7BR4i^S|c$Kc~z}2ux2EA%>P3bQk!1O9Am@u0fE_LO{>dgxoJEv zF(;HvA3tYq-BK|38tR$HFpKbmesF@MEA9a`8k(G2`@mC&*pMCBom|b_%wPA`W{i2c zu}9QBO77C^ym%8VzyV@~&@Q_fO_ibzSTM+h*}9rw8)DY_YNVQ+p}cPxhd8sMC%`>Y zwVNp{Vl1~nsQ#&aJiCB+_zGXO0`%Uo-j2$qU9*9oKT;(c!NwgX&}lX5OouW}3=BLx zIN?UsL*ho-<^um90k%!oF^d#_tHeWCQ|1_>{!aP>UMRyb>vjGZ;U@ct$Ky48&vBtI zf13{DzRNT-jfbt5b!<}(cv>`D9C7+?TI7Mu|9d4ROr>-l#3kQH)jAib<#coVOt|hA za2E^elxlVvUrPhVP!8biOyH4zp!III8+#2YteAmH9ZY<0BQmAO zrs-ql!rt6&(ll^(Ej*QAX8$~v3-1XBhuPh1*&dqG08B_GDhluEop@f~`SN^Is%r!95gLC< zuBZqZ*3MCI@zUh*58HS^j8xM#y0^y&*LG`+a9_eiiNK@w-82WgIbNyRUO;;yqE4!v}=J_jYo;Bh5bxxR=2oE(#sVbbGjXiX0)pQ*0iNu zcM~m#1~roG`|D8N+$?^N2oVws2H5@{@U|XXU+82TJGuxx99G(}jlR^WlYNWB4^q{X zDG_4g45l?_R4OxNiKvbEsBRtxSeCxkUW;SuOA)J{73pv5e3twLEEejXzVdstA#Etc z84aGP4@xc>Yu>LQIKF!6Us7lfseet$i8Z09{cmaKI(tRcO?=Xr#U~Y^a z**m7$=5O1tYVGn~nl1rnf#~L`97!59If=PB#JfI3HR2C#Rh5~vw3bjqFr)`5uO2x2 z{q^Q(FL2(D?Z=@@8G0Zr)L6Gz&;x_*Ds`4($CAsz7QR3rc5L2$CB^hRKq0q)9z=uy zuN%(O_ftyWJM%#J{rp=tut|%9! z7kw#u5Y(CiQAxyt68os!maKR%?(kXi8P^2yy(rH`24(8;bJl!jABfg2wuhff42lkQgN9h-5SrNIFDVT|jVM?P;+in>skG;;&}u0_E6Eu=XF88kvuc_9zd=m-d>JS z-1{+)IrG@`p=n%IEOW)PX9ZWlBc;zy5OojtErOTAuK%VWFnogUj;IB{6iWZGt`lPB zerZxmY7R*<4>AIqRD#Lk!Y&yEsl+#M) zqldY55%N#CCf1qXg;et#4FbTN^`u@Lx!pMb^j2mjp<&{wA`&a{xUKopyjamSh5fIV zh!JCHanmX8H@p{c><%Mk4iN9QAKyuIob-)85g{tG?jX4Vdc)YD8q!d@aixi*y^)s$ z{Bilem<8nfFt045u+&pz0m$XQk6u08>3y+G`>T1dWyQLPI>FR-xmMipyH?sSl()3} zUvCNED~AK#7==W^>P+6i;DIDf^819b@U_gT6Pz^S|Mi0oXHtWh1S7I!S%_-ce#Nv$ zw6uY^ZRHGMT$^Tgy_5HMgOhUVqRfm5m@59FdekxFlt;4QjFex(-e9#`r{8JI1|>?D zl?!79s{Ei@0QP!Jktjh{LN2bOWUEB2z*Nua^k`=t`~#NA4-+3?>yT;5{si?oUAzIS^pcd(cKj^_^c=DbPdh@x} z)EynMwYHybU&EaSUgY4GFqym!_=Xc9=Z)pVtGm3pekP=wEdoZ5Ohq1+q!d|S3yWng z&?{zgS=|Vh47m`*H^?QLGr4 zxXVV2VCE4bOrb(`%t#bDNuM@#f>66DkqE3BE)ORF!TJFZ@FHAYQ?VU6jZ3(@2Z|ry zm#%U+d)5q++$Nx}Xxdbbxn=R}_S_Vw=GNZa@N8dLeG%6c*?kZ;_%PG~WY#f(%42*( zo#?_ea7xz%FH^iSWU8RIQTPkSfZ&s6&<&F~iNWTT+%Flp_lWU!Le3DYCJ8HU7xivkZXgY&aQQ4y`tyxOFPJ{}PnW2bt+rREMk77)}UH*kti#<(PWjoz8b!sZ) z)uOkbl|ZpXdM@V5=f>Z=904RKqI}}}-|k*MPF-KQ9h1!ELDxvS1&kH^W3-wntra`L zQwGnCz=~AC8(H2B@%xXC78#FR+{ad*#O=!?%zqb0R?%30S8RKC{FN4623~dxZ0mNa9g=6qcVjN+R^U# zv&WG>zVBg9tQ(Oyi^YsIC2CM?BKwZOjKt>^eB?rcI<$V^4~v<}+xia+xh?MtRzNCE zp_Lf$WCRK%FDt|*X8YTeM@eIg7cJ@w5# zodOAz<^3_>@CA_)k`Y^tgw~cgo1dmjh6t$}5guCSHU>0{Go`Vx0t`19(zZW%S3{JYoYFWXV@IXV=h{-5?59o$SxsqonRE`kd+Pp8-} zcse=#B()M3krnImK4WiN02gL$_K6iRC9iZeQ;wO{c8Vh03CNq77L zKWA`fJqw#aWZMF2GoXb8Tc6Mx9=0ikL;x+9U#s}NAFyy}eJM2fQ+Bd+s9HlUCMEvrV?ryqXAv-n%E+zu~jJ*Z_Uvevw|-CeCEYg0>4sR zmwvmx6`-{L4kjoi3oFgpPv26+9yx(24YzVIjv6K-> zl|eIHPE?SEp-43MmYHVJsPFPN{lx!lAnsc(6ld>zU0O#XsZ7?0y zUCGr$ur|O~L}3Itms|^^oN6#KUUi2W(&{)ruofBgAo>Pb*%@Fr1+W!y)=L^A3j$}2 zO)5_Xhg=*eDHRe#`W$J^b!yXHzIei82rpf&B3xF4<{AakDu5Er|Ajn&%LxVpnE85s z-@+99<3Ap_1ICULS*J}XYeO{6*%p;s(r_@1J*Oh4^Ov6h9jD zW36V_yHG_6GUW!LfWK(`1cQvqmd#g!mQsF9h#axh$95Cu6$BZBnE zwt{|Ttj}!h*q+IEC}4YP9>UwcMc+RAy|Vjy>XzapYB-2=lx=G)jrNE9t~q+EP8_Dj zyQS`LHt_R7jzP{2W4gMAd1I{#sw)E)w1aA7C_OxiWV4eX1jT~*S3pq%?Ru8m3>JlO zfZLsGM|JI%v07>TF?O9WE58=}!+Fu#8NQ}ur%utwApLnAvxH<^gk&_bzn9(<0x~Dw z55%r?v2LY_6-bH!=HZn7N-T)s?GEn`FNyAT>x4@Gx2~xeSmDYCAhimC&mC>UEbtUAEY* zzXaLJ=$1|62{;b==eAqGQP;heVv?^3E$U9%UWFcyQ;rY1?9jpmFJ47ODOLUkK<-Pq zxihkvSfe8~W&QKP^tj{lthr;u4G~$A*)N>3OL-D8*ORce22GSnJ&{BzGU}>aR0VvU zHXh``6w zH{S(Ab&FWpI+yE*9=@2fLEL0w$Y*^+aBd~}-RhY6K?m_U=f0gIN>-w|4rY$zRC3W+ z8<#2;?5IBdc}*kuGXTp;F(!RX2?Y`}Je&>gVCH@%styN(GM|b)=SJ|gz(gR?KffF2 z>v;ftvx%1oHsDw~R6Yy?^$7O`zj$}zM_d<$nVAP=7B#v?+O5I;v=A-g%c zcIFwi0A;&OR3mlx&ID@*==>mIu=!Q^x$*qo3NYxB>4*XLP6djfz@1-f&ZMwQM4fIj z(~{`QP9^l?x-CwLis-g@uZ9&jf|FiddjwJQn(>`}GoHNnqwCzs9h?7^xD;UH8;8zh zgD3R&=R|=(@}+cstRhvle=Fdd7P)8l^D93-Jlp31Ir7QR0~hc`Yw?II{1=auatL$! zj`;5wp!XjUYS?vecL=*Lx1NrG$`3Bw&t@b~H;Qr8(hmILW3&WET@MwCO8?At3@fp& z(n;!Etq)lpol4jAapaDT!bR@`H_hGar{ugh`Kecm_-CN|hcJPg1FiyM8AD8voH|Mp z;Uewk#@Tj<>D%df7(0B|17rSu`Idny?~{60;j)eDm4F!vP7uVlAdF)hjoFwID;WQR zOKasR2LN#(=nFB}d7ltv3^$<@a%~d3a!<1RQ@s#2WGjUxYBtix4arB^X-OSmC^Yt^ zIZzdTWL`1Bwv7AvK%)G`QQJ9Z=Yh6xx@?EBDP>ZKY(Vs~F@74w&0r3{fZR!TMQHh2 zMWpDTkBN#6DGk==-hvw#;T`6Tm%E>UUFGK7*n!0}QE#%3>;utfV_XxGgbP)(EpTWd zJ>#G-q}cg*qmXvO>#1azQK+JKYSos6TRbLjN5e5-W&5>uo-o7wh(oR^^CY(DKp36z zxo3EFM&;{@RY06n4KPN4V%xw}HLY@1y@7qSIYtvUdb_zqUAy(lL=XTJQeY*a7v!YZ^%BD>)qQF#0B@^ zwz{qVAU$pv>$U;!8Z|au7>3!oU9j)SpFsJNr(N~1#2TZam~My!@-ckabO)U74{o9} zc{RzEZWv*FQX5}=ko?F!@oc1V@+cyo3sNnZSB9+5yO3t2shUwsy+0bPX5FYUmTpPL z_VKl1BZ9o6tX7E;A{q4KDsdEYmhD@>cRhx-bvHv4B%j#{o}!<9U1 zmI2~RKw^x=J<0}y!Px%E%RI_)dc665VGE~{1cezdPB23c5~3G?aP?vNAgO1=nI5_o zN-WR=oLnri7XwS2nK+)fg=9w++vmVOukEtROav-J>`W9TAb~?HJig;UZ_tZN0aaQ~82JpRnstg+R&f@mLVJSlo>=X+AAVOGG1*do-?Mk86nXbgnqj4^+n{K+F@k6_*%{TK=WB=(xj-@HX z@|}jThuLGyA4Pr%fi5gxTk)S%X_SXkZFu&kk^AQoM{GuPBeuv|$o3W9bhes3(Q8s36(8|N==mdVz_R72IG zWT%o4=`YyY+4Q+P<`c&E2w}SsWF{L>IF}RPUtbo@rd)LR-5T@}>WBoCfQt-C9vmDT?{neY zvGB32WB1fknsn`)cwHS#j0hYof=FEMzx$_%i1uKqYSW>H>EUDR4Qs-wOAqWMH{;`` zyKMUHd$gj)GwsAD_XH3wqEr_7*YNK06F{Zf)w8!3GvTO4?e5zTyk|%EPchWsCNuU; z8TLJRq2!m#K;kvB2=N+soyq!m;I!aNf*kSvrMfpci7Y!}z2_Z{^U#w{G>#Niw*8g` z7RS?GTw2+pprFX-=OW`E;q&x~7CA89kn?j;OPJt(Y*aY3uO>3_m#VB9%?9x#f;9@d zELFB5Ta!;lCYMXfIqp<<&ZiJU7$Fi5iHFitx{3d>_>^LfsqjR&Has<47mWsu2Bn)+ zlfYA_NwZ0`NwrC~Nw-NMnQ9!xhHz#a!v<}OON1C*28o9tHS&kKgzaQ?(P!aXv{|a5 z{Ec*CimH^4`{0n~IOAnTdd4!>=i$=L4sJ$+<0SiW-{yJan{cpI>pK4$Go|WyI{o8> z3*ujV)OT++8J+~4C88emqwKyE5}jMgA|IXFU=Kl@t@Qg8V%4BV^8M`!NLMgH$< z@T%OIJ++;|+LN+dt8+JHn>GD~_Dr69LDgOs{xE_|c#r{9G{+DEP;wl|;NPd4==xFK$$}sv;rWh_oOIfXOHhoU!H90yFsJ+nf zOX@RnJ|6q?{N44Htd#uKo+Hc-@pG(qhYQ=K<@}kFJZ5t&ZTpw)!q}a}#n$~mRFrdE z&gT@0H*7f|b^*vUkTHWjQIc}~;sU3?H{pY+Ai5PBY@X3hEq`IB9b$(7A+7^HIw6ct zIA$YsLZ61a(|JxXWqccylAp}?^iX9dx32*V&obqd0vyFNq#I;dx%Y6Z!=eUyvv3c zTu|qjbqJ$a9yqayb+$gwx<*&~_}Mbzp11i8q0D;;e7u{J%wzGeyRz4g$qkA_U(DK6 z2&S4;1O1KhfmJP(TOnfI~vbNOED?P+bOZqL?m=-hvxcyJ| zSd6*M0g6|k*)Fn(>?3XNT0DykvXw2dQuK(opzJ>uo769$Id`o5dI~;XIb6TZ87Tx} z)FUWPA?J82hYrpjTCN6R4s+4Tj+Ib6<{o?_zSu~?y4h`+KwPWY%k z>U;P;E_@k$4-q)ldV8o2$a@(zaKh-_4YlbV`SE!0IFoQ*NRYQx`6(z*pWg_?LxDbB zYh$Q_6wNrS!*Fx2{H0Z^BKQeLVdc9)1h=PDn}v)hny+gBlxyvp88BIYdVOB{Bfo}= z>|r~2wtAe&dcK%b_bk*zy=04Hlfb1nUM|WoW+ z&5xgWYkoS~^s=|&(Z-&6yHCan%6#7I(4A-1%@*1qrDM=L`%&#*GZff&e}^zTb9O== z2y+8qvo;OPZJC0pEvzV#x9kE+kJe=V_|FUFSzComNs-6IGuX{Ofrh z*lH76+p)pJK+Q@7z-+@bK*$*>8^Ct#4+YSbJSzT^q-C;M{=^3;;=)7hS=BPGXmVdo zGBtioT~YaffQGh9)jCM_mN#7AQN%WrUpfWz#J&G8y|d|kl>&am)_0j1qLuXlR%rYf zhu%W3zU{rWJa<=NbN0;0Fi;D|zyDQs|1SRs0OKlGMlHpE|E98r_I;OgarEgKZ-24gEiyonwzEP_w1mwr$(CZR50U+qP}nw(UNrZQJ(k zNhY~>k~fpdWdDJ^_lHWV)~fZuu6nDj0=>=B`b$xOs^6&j3*gGB3AkVO8rJSqch5e~ zC6wAfzsrK`{2^UAwY}U`Z@#7GenZV3F^U9qRCa(60aD}vtsD4zOI2uEMLgl|#SpJPtV`q z=MCRC|GR#BB_>YY+@TfK`1dH5aID^Fe2v^KQBXDL7CK1`qUhK%t_`f3E^6w1SN`Fs zRLH5IU|d0^ma?9ZTJ-quxP)7JARWIf%Gj3RZ3LVWqwEODJlIf zY@@$p0KH$lL{v|Fco$ih#nN$4qIW(>fK3^iOaX&-!XA<>%=r0oN5>+j8+UNO#42Z8 zcW;c0Wln}0Z|~lh@$0zw&v7^0D^fAxq@UJ-QuBFX4AX;wHdvC#q$V4afU9gOzQJw{lw`o)XjC6{JA4GAqUw%h79(WM!;#T}@vh1ft_2}zWg{k<<9Y<+%cuf? zOwxg$%{#xW?fPI1l-KJEV88Poj4z-2d%$i5JS-bt=jA9N6_(=&a9m&JBCr+Lh4jgtv9}%qj#*z$AbeQd;JZiV~&7A{+>~E7a?-RYinPZ(Jo9+B*!(2PmnU zS!<0Ht$09kQnOFmh(#?J2+)X9!B7}W!%q>mlm(lFdb@3LI$ES5IjtK9qp_37c`Ked6c7YyarK`m!!WK003iO zR9aLdU*#lE_jg%`0g+pr8bttlWc9O(F7BtUN&Emdug)Z{8_gigUy0nitq!-Ptm59Syh0Rak9JGGv5a*p&!%^);l0S*sH5^?|YZ{84-n| z$`ZlnKWHYijFLg6?N6;C=_+X$)5fZPw7Mst$F7$!@xc!*xru`txomDobDnHg|PpGJmQgSle!5ZhqmqNE;2Gu|n`n%AY--vY$hr zInZ+S?*VTZzUGZc1OpOWIiJsE zy}l5fAlt)6>7^%K7jxMp$xxZUe z#Je}bb60*KC-dsNao}RJp53;Me8hRAriC-c=&l;jt+h0Nz|4gYxW{5a$ioA=8|MEE z#l7CqMn9fcboY8|z4I=B7b1rD<>^sh@a*_J3y~d1d1(VY-6*2+j{mH8#CIUV_bEj{ z|6TJiPIu&+9@xQ8qfBeh)$3?c)U~M$08;=%!5fy;0#-ESR2W21pJ%m3zUwo8K>a|- zDV`l%dpzA6@F_@IDAL>e5ht4xr$Lc2C)V1Be!|Mq;?F*nt*Xw<$unU*R zKRdk=#NV~WlrEpPpgB01kQL25Z`5ijt?j^@XZwmE1Pdh^8W?!Z7+w=Ls;SAT(PfX! zoDEy-3nEGCxdD^Fynf_QW!6#^$)ZikqAd-B za#e~XS+FK$6eKK}${Ww!ylgs8Agi$>_Y%O5JDok8a{ny9^Ye&IQ0u6dUz{1R#44R~ zA%ohfwHo4jS+y>&7ury_Z#FRFVB7?e=@Uq5YITL>;~;DsfV@T-!@DdLTwcPynZ(8a zN~j|welEu^Ul&riu0)8wmoyFAp9Vc2?;FvEtk7+{_SEPKZS@OE2#qFW6A^;if5Qii z{BYp{Ln-x?F0xE=OtMVs_@jPNDT+36TrkPVC9(XSFsBvU;bY4WD6u-MIW8p6W>n*A zw$*9l@0`k@iN>@iQ(k4m<3Pf=?Wurg4&5w_gj=*N zeR=L)-9${tD3Mda)Np1*-fHgJGahdKEckkF4ATBFNHOvQB3lqBRsYZ&Ii0*+xC=AG zx+@7&q}^|XtWb0kcBb}i^OU-@orIw4ir4FMM5+_#8qDmZoZab6*+u@qwtn?8CCVh& z%D^CRNIgiie3g?XIVLPP(+93#Cvg5!7ED~TE(T#%V_SfJ!9r~_rQQMe5nWRfhq@dx z^GJl>quU2}@D<(N-dbH9l)@_hy6#B7+?Jfv1omerwp*6%CND&Qpx--4ZG4+9&&$Zz z{B^Qh#%GHHJattX<%%3p84BuU6;>(zz_)aS8&7~_?~Bwbz*eM&-8e3cX!94uHAG@x2 zoBPQ%dVbVK+}PA4Yjw4rY7L9pzblBat9iW#7J#JnQi>D&_8-!;i9sE&|gSEDOZXM}s$0U^S&$+6?z z)MCc~pM!3VzC2l%2uavD$M!;|J1T=&Z&^6wqF3eIoa64K2+yHg1wHP)JdGwlnbVLkm$vy(3QvcLq&`>0n3ZT7Yeu51R0D6Y@9U!))U_>+RlbdyVzE3SiEMRg14 z>NFiou5nH2VctHp<6fe3Lm@d7dEQN}&D>L<bXD#M1+vD>#*Uts|V)kIlGMjvz$0EjM|m!9Pom zN5lVNmC>@OV^Fg>OHYm^Ad`sJ!>GU@_!G;0=kX!gHg|!}CeXAZHC@=WP^yfkV!duH z$ol*&2e$r&+k4oRp5j%Q8_pf+OE9Ya%HeNFw$GSbI5MZwzu|%U33~JeoCn zgFj$-PFw!Vhri`@I`FK<$y~N%hC1SqZH;;O@mcI0m=}3fDjJ^Lc)`$8@$ZtpZ9S#h ztz?Jr99E5(sHUhUAc6)e7Ca2Yt?f$3KkmI;clO7kyU8BxQ7|lTrX#QsPmP#Ve9r?UUa&DPCE}k`&yiQi#GrgTs8&Hh zDD&8?!1waW9f+8E!rz>ZHoTgZm@Bhg!=I4Y7huXpdYAl$^)HV{YK7Z!1Lj7_X*_Wm z0mJnTB7&FhVZr%Bi z#ZjM>K|i+lZzKMQvtHZO)rPS-=Ecwx`J{M(1mJ7 zCmOX;)I=G7f;W{6D(zE?xFUKg-M8QbIx>rhVZ2=rlZM3y(V+~iu<`1MQuLs@@D^-7 zP9~-4p8t4qLQC={^Q7Qf=V^e3bE!T#+oK`rIrkx7UuQiwNp8c6TI^mHD7sFhDb#|(7J#`{&*)tV5nn_v09;J?B_6w}ayZLG~;b`Y)aRkjH z;A{tFMrCd*KgD85!ufNc>^QWXljR6HZ_SR2VXQ^67x5bLth|?-YI`ayZUwfoI7K@$ zhuQk+bo+zCwRS}Plrow*%DOaVK&s{4yvxH2^3~uBo>?JdqV7=-v~Ll)1Bmo~oIPHM z$qs6|IX#p9Jv1{``ge|HPPf|J`t_~#2k3;+ruIKc1+4$Q4)=eF++q1Y5+wdt7;i8G zLeB~HaeE0$Oi2kSBAQ#s{Ca99v{%f8Ij|LyA|X z+$V~b>;#Sfj)T#Hp@e1o+AIcE`|b1Vcm+OG?A?xKIP|OUZ)+=%jo<+h4HWQ0xaG*{8s()46l;@ZKb=}D%lgJ%rK|h#o{kT zp4QtE#6~3nUmnaxK>g-xN(x#_6k(md+8UOST-lB4eB~4Y9~SdY<2{KNj!}(N{NpZb zCk{2|%@8iH-f$xacFKoClS6|?kf7bM5(KAiE*vS~DO=ypy<2}Y_TWXXe`t@m9*S{C zMnpG?g}Qn)s9qE+|1OX%aiX+U2W7+6{o8f(G$tiF>doJvrlf!f8+wD&qu9acQAur+ zh4MmaYnF$b7?4{dRaGKh#0!&8O=VB*`>eeE0K$#LNk0Fi<6IR>OM34%p#KYkVGkuD z$gcnhf`tJPq#rIRZ2&ODv^34&1TCQtL881#30>jBk=bi5qcuB*E(SO&Fsf2b`kb{V zk6!?$62X?oTVr7_f}z}!-;zaKBSJy^6n_X2q3hjMDyLQFl$6P4pbbAEaew@id!WlB z!f8^T+e{?LG1yX7X&8hkiyJ9Nxx+exBE$A)6B3g6G=ExEp_?kh0&k_65gSLbMLB4@ zA+pNu>%0@O7xDxYDo3HkzaGXjj+n@r?6F>QRbsHYN& zIIyq+dD#i)o@fuOvJ7m6m{Mf;wR?QaHyrT*ds$9Rh@6?Vz_gG6(WUTmP7zwf0%&O^ zo%+Z?F}PiVHo-IYZ0qT44kru3@8dnCCNDJ>ZBS_M=ZeMQ4w<=|H&CY>P14Np-R3mw zG@>O=&G+sYzgBy%>$cWkdWEehH~fssLJSH~l6=B9s97M9Ou^@>M3y|xyCav0# zWgPwK|DstxObAz4i|ll$YLM-PhRaGba~9g&>b$@}M<;e7`aDN1VEj|qftfM?3&2>v zf1L_`ad|#!Nm`-!!VB9O>x1_bIJ+_Vb-}ssJMZgzCxPl6&l}yQxfy;njh%G)Zt`z` z%>+o3Hp4R({F2n0?V(hbP9<5P;D_*d8V*}YW=X%VebAo;T|Dxg6Lbr6%tV76(DDJ+ zW9jp+Du_N(Y|T>1HMi$#H_+pGo42lx?$gHri@37hPxiNo$TA0W#{!@kF{Qs&joNS!` zv&77JLOP?WcG`vrEQukojs+EHSJ?}QA|fCNqB!WQU=Hz2!ek^d&k4`A&+*I|kwNG~ zFf(NUkOyL^peQId=XAE%*tEPDpnh#{xFFelY`?s3x!rVH^|%Zg)D%}ff0x~SeEX>* zF7)v$s;D?$e4b6E(t3aIi84=4;^A_?F7@(f#0u-P?rkdFD(3iBsLO{^Q-M_6r)&GVgD>SkI6c(3{8`? zVvD$F-P`%h>f0SlaC^bN8=i9Wk^0PdMdYu-SCn}qmk1;RV2p2%zz~5Uvn2~fXhUd2 zYC|Obg;D41A`3@whbtLk+;Q)}4CnmPDrFgl?e}f>@%I1h^BICT@ZSO45ilmYhr6d^ zi1G+UlZ_%6MTkc@47(cw-C-~$xM!z}$dKg{lp@F@$s;O9ltow!Hw`=e(k-10!5EX$ zMW@M*5$F-G# z$LGsy>*mM4?7CLc8S-zOhtccip7?d|mF>}1-WKy=F7Hch54-P9`G*kkb@$Kghc+IC z55ar>@jz{YEPRZ|_}lGxSX0qxbm#5(t2kUtuic}(QCRE@FW39Rv$!7?IhLEP_dzf? zxihR}RP76LTD~eo{nz(kS7`Q1)SIf90WVD$m^LsA0OLrPzMg@$t)7A2g$D2n5U(os zzv44jrfd5!1DIgSZPpdH+qu`gmE({Y;BM`(HnBPWZTLHHSZ?fx*UyTj$s{D9yDQ}SW%-nxENo%9DCh+aZ*QM>#S#Sx zQo@xqP9e$lM&Q%Lpj0U`XlkSx%Eh)dwJ^5z6GP_|Ag)ZdFJt74EUp5vGGak@={zJRsqwjRAHMS9bt%i`OcY`LLbi;Yx$L$K(lbm| zDD}WUz~}`D)}Z)$6TJ90;=GRi@g0R1jI$42TvPK+{P|`c=ns8ed|~u#*d(y`lGZcs zt@jSC>*fC_X{7WEixoAqUE?vkxQ`+S#DsVUGqW1 z^iSqRJqMiIL1-+pH@`gprmUE6e=EDFpP&^QAA3h@*}1>@pwnJ;oszhT?(D23y?uM1 zHgn}8HwVLyXyY);uvGu;p%ioilo4m#9 z8W>p0ifBA-@eDFp8nijGCrkg!_$K^Lak-vi4NfBv^@f)rf1Pxrp>wV}BBB6K62+!g z^EcO`$Y4DMjsz$|g98T`Qe|5Gnh`&&OJI4WrER3GH8j-ZqRMh*uW>439y}zo&+iXh znz#7&U>N-pold*z-+UGU&Uo=7MVzZqZyu95*HYcu!LUw~~yBm?z+H*kLM_0NgIm`?@IBY^msKBsOX8ea?lMo308(>=1Qt;!bzuwyNRgrbY9m!?$u5GQkZ2Q2zQnI{$OJC~0 zLvpydY^fAYl7vAi}(i zP6OEm3-3W`32Y*{xoE4a&V1jjZY0levG>UL4qGUB(dcQ1DOkbw2eeYdK^IaesYGoA zdH))P?-M`taE3l8ingn{%wCy(GwXri&6$E9EB7pbJ{j6Dr^=(v6oypQUoN{J6hdEJ;e0 z(_xaVQ>tQMpf2x>XOnI_dM$_gV(|Y8*xzid!sZ=CT`A)oe?_~|X2JT(i9;*6O2&o; z$`(5d{(ZEVif=WHhQvLer9W2|Tp(A50r!w8MTYRakXZpa9&DTO#+MgiyQAT3Q=F{s zBTEx#E&Ng&))p84qfp*llocVh?7tOh4ogMI`d$84T}D+GkTgr>POAn?FJQZsSxY1f?A1fG(1nrIeX+eJ|cqI&i7Rx0&l0#GEnKR&P02{1E)nk2 zThYu-*lS%2nK}~#ZK;p>huYHH`(LOtf_b-Q|K#+5@q^rco-*)d`o+J)-}{0jz$wVmb-r&;wI4xW zk4xuO%v&?^F?o1Rj%Yl=vU}8BF!?E>pC5Yu{pNBy=X5li%wAS#qc1${UT(cN;V2YL zY?=S86(+fxrA0l!tPiBc=ma62m_i&<>l%Q0Zng6W77>tDCPkf>`D(bq@jjD!f^EfI zmy1BJo>|`!8)@EuPZ1;Jcj=pz76F^j4|&7rnwmGB;c%6M{>{^TS!9OZ=@$8*IO*E5 z>jvKm20so#TZeU(Ths@kkGG}|Jjwe&huH4#eXG00ZBqQ633SFBhZE5V`b4LwpyR*V zp&99VmXFd!JyLaFc`0P}=60d*DZkQpvho%$Wc95rV%e8|bLbUOO-Dmfs8PKjr_Jkj zzHeN+kXH3yyU*teKF_+^h1;e?kJ`vMMq%diPts#7yG7QI3_ z1z|Z=a1>e;F2FKn+?I0E!5Y!^IB-V@tITuuv>t*N;_L|3pw`mrsVkHI$_$cvn;Mn# z5zPwGBhgG!;`;OWkG|fY=Mz=r+nah=_h3E@P(>PW9%eW6Io^i%6Ov;~e_Hecn#4wPLWTPEhJqO%g&2_zf5820hk!;}L%>`DFhl}6TV;q6 zN(xqXf6WL6Y@bpb$B~=|uG3s~zDo>w0orL%Rwh=hb{b_g%#jWnq8K0f|7s#L1QVxU z3o&V?YkW_G%HZ+%JBx_DNPxQr<}Pt7BAVaCGU=0-qb`!3WMj^ZjnuMhOgLJ`5Zf5t zsKQ)#>k5N%^qdP%xEv%8Nxd}%_EFaafjKQnwOM>O69XOZSb9TUYgmd(xJy@#Z;-?Hk=V0CtW}3fM@oh zQ)fI|ZF%F^R)_ful%z@orLXsqd9dQNdoi?w3p<3a5y(hi16%Q6-HBLemlmcO0LFFtt%;6Bsz4V8uK2MKo})5@ZLD+HJH zRC~JheFrkShIJt&O}z+d1h7p?$g~cXZ58`@yBuJz$MAGJd$VBdpUSi4YDMn_?#*?) zM$D`s7hM%IC?uTyd<)Ht3%MYmf>mBF#=G@hr?=1wdb-*)xj4oKn9`pYwpsv)OymC! zHOB%*uhD3l?_ZGL&ZAxrE14Ys-1xNVQWsGd$|qg}Z&6;Oj5oQRGjYZ890%w=Y~%kU z@RfCF3)uweNfj;hRETP2CiskYW66T&3#kX+*Lz|-^*!VzKj^j_ur}Z^dnM?E6o{ry zGn=odqJ^C}-@aDP63Gc$FPO}qO8r(29@0SaS+4JgOR97l0wW(N3gG%<0Owx+u>ehi z^v=TKeC>#1l+{#lYHiB|azca-LFgC|Ba)S zM*XG?zpuwJ{PsSa2W6F_Y>3&GDutwW&=UI+!sQ2^QSY_i9@*jT5Jat_g^Msj5~_uT zWuueClovz9h$V&Uxdx_yya#@1d9=e3Z@g)(Z~XWnUlmvh@bDMdW2CHeJ*pJ;qHAXf{LIxxoWM~i&794Z5icz6 zD0-ESutPVyauG#65} zjnGHNJ8uty7m$YJ=Uc>#Y6rtQ#I8Tql*?phGCo`q#+<7^FF{oV9pT_XKsc&Ao7%ilJgKDkC|lp$(`@r2jZQ@ zx3P_KnAQq{wY8Gs&BA3NOoT88<_~D7-Fnu&POzNr(Ybej|CLEWz?FNZyrk|Ljx6Zg zn6}>@HHoUvzgBo?ylz1@+#m-SO9C=Bfg)J>nV1RrncV0+K6)WR$vhe}uti+jDs~B{ zicjrLt77f%?lBnS+Nc6e7jYMJ7colAjhsNXTtj+UgW_&HbCF~P4nJ*W6f<7pRv;oa zDfV5g5~3Yd1sp_%0}1^<_CX}n{Z)$Sv!uS@13O-wu(!5ALMzGyHOetl7N$2Prt4b~ zgKBuq?J}j#Z~-zl)gNF@=T~1UWQfs*wsTBZD#~SwBga0bkcI;8x=Xsw`G`c_5p<}z z(stV2M}!I$B}s`S<6a_Vjyt5u{C2xV)2S%wE7ZNK@5$G}*TG>TJ=qHF%NpB|n)!`= zx%W(I>>aD#A^Clw!y$C@C0KuR?Wl0^jDyZ8DpcFJ2-^2&?DtM|$}{SYbG zXKPS3OUlf)s=Di58hw0pztYU%W6ndo4r#v26h!dV0Pxi;xJKYG&`ROTEgkOd{Ydc) z@Ai=W$%fte-yG&;b@3jDjU{bg_Tl0QyV0zzZ`m_XkYBC)RlBK4Ww9XOXtP_1W+g&o z?~lOY>-{BX^2m{bLr?lovTdvQ2%m`-sQQrVt|pY61K)bD!At4G@&Ur-5XMuc(Mqkz z;@^EsDCf1=e!5#i&^S#!8+X-*fL)9a2Cz*;cH8}fcf z;19k~=Fo%p+L5!F1s8kbSl|u>J}X*1q8bJp7CYA3Kf^A8gG^hWy z%I{bwSZjAub>;+--|h)4!Fc_pfAFK`DJPf0P&z5SL^eA#`2aI0HJ#MuetfpK@;6WF zCQ3DF$Thv_w-iV%&de|D%b|!_y%Z`wIFicpnp3M%ZrdJ<9&-U}nmvoM}w zHZ}lg141?-SPd0GOKgj0pAHz328qUTmhO_w#c)d^s)h29GeLqXgr__t!a^Spc-RkNK2aKBl^THMPyGat!$3yd>uzltzoN7; z-&Brg_Mcx0%fg%CPexO@NcP+pV>ZWM&8OV6d^7qfTii-KmY-0peD10YjpUBbQyP!P zcdOtpN~2&g4snx08tDHzhdqd;?aXc}^uw}-VTCp&4GH8~i)AGTMz zAPGUi@5}|l5N4YWty!nG!%I1Ps>bG8ju`zSR2elq?NdKcrgk zX0B%dyrVKb3J5m+F*t&y#J$c<{d8u@8u1jd=1NCf8*^&M)3(Iqi&x1rSHt&|tz9e) z?7i#_>}!hWw_L!05QR7!q?z_b)Ab?&!N$I-nUD!{P4F_J@G!TD5fEk_)D?$B@#j(f z#KkyNG^1P!DJ&zW5SU>RCIy|B=cB4IRad56keLjQ7a>#yVk$lPhJrIdNwd`of&?Q# ze~2q4(v7l@wN}I*A|S}^lyw-tmjBRjdDKYE&(x85Wq4AXTFTJXq>sO&+%M~8UL&kH zx1p(Mv)0ODIDY5?iV#RzlrL@I9E@|p9n9x|+ENuj{*I#R`d`8rgfU3g#5$UAA8bf^3$RS+ zGEuSswuS7V#j3ZTQu;Or@SF8kTYr*VX{nW;{Vw>2{rF*kL*l%^mHCyJ3|*ZvZKUEO zkR&J8E&CWhv6{BBg6^$3^42Ik-p2eI&s{(BA8`6Tf+4Oy&f5J{S&Vg*a zVz>9>1Hv7mlEBdICznf4ryT9_@;Rf-#9$x^ZXlpu ze-C#oKV#UCiJRk)Wgltr1NQcg29`C1#n2`U1-6O4$dO`~m2gQ4;wNO)=A=IoHcMyO z>48@7ziL%`#kk5$bLR-_=+MMf+|2Z0xYerS0=G<#;dEj3`o%LrqHMvWhoCn|ufyxUQ_@=KN1_i3KOj~grJ;9O z`eFG6HYiu0-1Qp^rxwojdfHIi$3N_aj-ndS>vSmS#roNUhUDv~5u~R8OKQF9?jYcx zI>MsipB7++tJ)aVhNMSF0JJ4q!*G7?*{n@!%lVh{9ae{?U?O(119F5Bf>X^FQ0Rt1ieesImEz%LWu=Q42X`V1HYy0 z;napi+LD|HLKCSTn9m>zLDp@M`4=;TNAqNWVk{y@stZ}5L7kRrr)(P#H-w2!iw}(M zQu7hSzhIFbQZZ;4<#Z|phpp3C2F_W}B*5=<$(vAVzMbrii9UZN-#BvV-&I%tg*cKO zjJvkg6%f5oc^;GrrhNv>=JgDQjVxY%>62=&x>`~&38mttfqS6bQ^+}TLp>_vY zpR-3!k2CE9(6twk7W8n%m9<=ZP!E$c<@3&)Dr(M#Mr-c+&H0^Vyh9?8|IhxMcj9wA z*DLTcD+Wrn{VM>fkIE9zT)v<}s>0i48u%0kONuOT&pc_I(ri_mdjdI3>BC}sMOLBD zm)`b0u>q}g?^WuB?3Kv7RETY;`Y<2F%5TDgrRU<&qWQX6T4&KyYcmM#`SLe>wCR}p z5okw>(m0fg#<%h-(f*6e!30wWQUfZ6u1~}dY~f~OiyweK1c1BTgNZj)hgiCIu>DtH z-D~jDGOp>=Meu&T)2!xmJ9m}B&iX3p+LGIxCfThAi4MDzv^O@g$JPa$a$#jk8ZlNZ{D~q0H-!GABN$Ix(G?@pHgDu{l%um(~%_Z95w!afzm(R7fxAV^e ztkMv4NJGn{Wr>}3jIp{YVI{e&$En!X-0383$D|9g647o0YQFbVFYY<>H%0%0`uF*^ zS8SbU#B8pC{UBG1+>{}os=YpsTsc6mY(1o6p5&3UL-;&-kw#YP+@ORbf5b2|4CcpK zsQ;GEDGY>z+?SI~f5hyhD8OTnJ__$@?@C3nPQ=NCU{*w@TJ@M20>PWm5Wiu^=it?x&mf>QYz8SD$qO zflN70C#QO%&`Yw*J}d(0OPXT$kYS4y8KgzMJU(d>qh06j-$wWec>02X%hleAK7pD+ zDzQOXLyPS_zQInJdy?F3r#|qN{sK)%DZ9J$nCiw06{X)WUvJu(rtH*%rh? zz6KN+UeEUy?Ku*ux-sU6-~#1>N)l1J_$Bo2)y|wf@A{!yxK~ z){Rdo9mYqvwEj7|N*JhAK0p61-Jb_PFRIfTCm_J5-kN(z3ME7s)*{~?A?bRCW6$pl zk94Wz!y2gvvX>@VW%pa8$;_%7C-oP%T2K!UgYNcI1V>*u_CWecu~dE=c}8CEpye^-ZfiDb=y^rlSGYz4NpX)*RFAX}I4cPmA{gVnmX6U+vSk$E)Mo!pQ=b zLQ49xZ%@&mqq;>yMrwmpaH z@|gb`vd_aYV^)Qx93li`j)i%->4#$Y4YL-C?c1OfhRRC*g+;ZlPOfgi4uj)^&u#u1 zb_u|e?t$8yJ97zYjlb(Cp(zfVQ+~z$S`E(VsJKsi=VcqC$3-Mv6^7d z?vUiPY4W%<#^DU@@kBu-7G&YgyA0xLAd)%oFFo8$ZuZH>?0BH8Rh9N&pC5ik0Dw0- z;w=XU>d2kZ`NY;&{D^Q%5rXf_c8(oJWUc|dY^bik3jY;u{;GazR}E~mG}XQ) z);;?zUCQcHNej@$GpLcLcdY|7kX*CSmIXNNnx3DcPa_Bqeqd}srZrDhPJ80WURBB+ z>z1k+)2bRN(6UHnGWsO8s@}+fyhv(M^Hi?OFa%^I@C=Qn68~J#h_R9h&Bh-@8Uh301EJFD>?Q+XM^HE-*&R+@` z`ep7F$vgzbzbz2bm7o%p6@sH#fed;_^i}g^8s7XhcBvJsaY_Oghcz|}1Qtjqlx|7y zAca-DR*AHNnFTu7v;q(9gG5FG3H?Y<&v1nRs9UX1WRf=`v@K8j@%Hj=g|k{GmGIxe zx!}@{$*n?leP)>TAuk`Bk^rB*uUX(eG?dnISlZE}M-}!TW#2}w5iY7)38J4JQB^}N8KbOl1Smq9xyouHpN86FHlRao*8D3^llhE2dh<$mpI&gO?{3 z-pWID;5Pf6%?a27?q2Mtq{Q>|k5-v&Y<9L=w(Q)pn_eMeNoypvl&ES^x8hV3tfwIt!A#)aL*-e-hItn!?&}sP9 zo8o@(dV)dN^td9V;0hCj&RN9f&<6Gs@eS=oF^nZ9aG)SBsG%|;2ap9?Aw8~lamvL6d;zc2L0|n3=563^m;&3WdCZFo@!h0gcHjfe_+N(l5%Iu$IrwTUB zQv*k=v)`|~`h35(-1h8OVX+03;x3}ULQ%$_mZp`Y{Ox4JdTLl6o$4~}hX9=mv2#w5 zX`q}_{n{xTvGIUU389WVbve~1w~hV11l9D@{vtW18U(AcgVq0~>W6>QGqRO?`}Jngkr)~uDy_gk=#AM+55$HdODFmm z#cdzyuAJP49D^aI=4PK;0{HdC40aTTaVa1t8(WZLx_|^eQ?&D?B#j*wEi6NqiT99RMZQg?2+|+zcq=SId+W+O?wk|x$J~jD z@1-KXddjNI$gGvQmdpYh3Ro^K_dL@Z>DIo0U&qB8zUP4JfM|rp_HXyM9{_Bcy2F3y zmt|)7zv!1`;h_H??Xn~4X70)>ox4emuZ58t(6EJG<%-1=3LKs(nf&Jj0E^%i@Qa`H z7D>j8&snL{(w=Y>#7Uz1{qT|gfRae?go6kuA_#Gw3TykPx_6oW+Idd59C3cPJrmPE z2^lS`UA>RJcW3}7r=k$Rfeb%b-mG;x&xLufi~ec4xqN%?Y;t43lMmTZM;>Zp>TJ9* zeQ(%0pI1`1b4tnjgGenfwSe#Cal!EQ-NlrJnREiWa5jVKyX5U|90h9W8)RhU&wEGu7vSaLoSvV>*I z^$64Cb62dDml*GzB%__k)a0uwR+XtM^#0|O-ZO_T*0tab)|h;bVh58X^V{-&<+KL;$XX)xewfT z5lxDgMt@l0RC-MZm+5(HUJSTX|7{X>Vs@23XSp45cyxHpV~7fk zFdX}g@q4pA4mK10C7mCR8-lx6?v^+tXc#e^v&(^Vt=~?d42I*9#ls?J)sWT~jTbahd8ly(;O8sv@bQG{zbotz|4_p_zxn7o@BxxN{j5;Lmf3S`{I&kl>*F#sPA zc~}gU=2jtmLzZ(HS$beTh%G!OUJoeTGK6&`adwlCqH-?U9j=wP{cA@{7v`O8=j6Rs zlH!itPvpRgJA*r{0#^#b1C=Uvmz~!udID4h&sPu)H-Lz}68%j-))1tg9^`g!f$b#^ z0a=4MKOMFdq6w8g0EpNBIr{pX)7jJF1<$3vwxF{Fb2Fc)mbZ<6sTREHytO1ZeH= zBGQ{F?IKzrjER$j2=GNtJ_dz?HczC^*>w~k?C;djb#)d?7h*7tP>+U3BL;`%?vQTO zo#VIrKma7F!+>1msA9pYCOnm2o-f})V3@EC<+}$0=Qe&5h~&<#8y8ZW?vjn@>g>Go z0@V5SQ_67&NSc&K|Im_lHahD0E(kbjPi?$upY4TS1HJ@m9mebeSqyNfR}y!9!{=^% zCq~xG2eJ-wpzu`>^)>$fRW6?kaVLIrZDnzHn$K0@687`3(C8DpwS)WZj_8X6<)Ox% z@eMHN2o32H-Lh^-OJhrGN4EiFmQSJBhBASnp7;JSnTtBC1^Hw0FvC;Y346}(m9$wjc$hT!X5j8Qi2n++-SWKCx}1esfWWKe zW9VR%OR$z+C3Fq9rdfv_GzVY$#(?wGv1V`@`;{R+VQnXSeq&>CK{CITY4j{-7-!K% zqJA{innFxjz3O^j1GfYcA&ENcf`0eeGr7rlnLz z)560^%D|xry>wUmBN#ww&W$a{9&&d0uvGgfKK+9TNbs%@0X}Dp8Rcq)bpZ9&{=G9r zf|`U;Jw9w6sUix3ENGxmK+0@Z#SI*Y-{0LLTA+rG+({@;*(?&yH+GC=qM}Wsel<1q za=ok8ipE*MQAXN8DA9*ws6hWDdfF#*(%N5|nhbOfaUX_rx39vLt$`!uuK$M2o!b+T zc2pO<>DXTKyH(;g%C_c`;vzuRJb6U|G5J?IT$IZ+~MN?oWf;132{?delQxlihvM@W6gn_DPuYSJR;F=$pV; zO`O3WPoro6&-si3YL+S{d`C9s)LRCCbawI%MuyrUg=hI;|>6>N{@u7Z}VD*b%aOXrsIfB-F& zJ-iM@1uYF7jUb(RapRUu8hH>BO*5d!3T7|+EZZ#KECI*{Pno5pc#hud$Mav}bHv(C zWcQ$+7`1)55Qar`3rTOyLTb!H1iCi|9Mg8i53#Q=UTz`iv%|gTyBXS)%qB?)zwWlK zK0MmOPo@{S3|1c^Ij4P-S3foYko&6OYa4ot82vz`R-x}3(VzwMKtp;e>C2uA9}KUh zE?1Yb%vOTAwWV$jI`vJ;t{_ZoTtQcPt3QuXvwPLod`=t}EU>MmW5UFhER-#hRe&i1 zHG3+Ql2zhVa#i6~Fcm7-zu%nhD-KvcakzFD6Iw*D#zt zrIN~K;;bSIJl6$z#cQ0$Y|BO#H%{=v}1VKH7t4jm;!roV7p>m_4Frmh9 z#8DMLAy;xcAP}AWv(7ABPzQYx-Cx&7hY=BXxLIU9b1skjroNkR(0Z(G-xA+K0ZPVW ztmG5_YUhv%WlB@8`sfDBYDQWtL|1X*_jke=)gpx;$VVE;faV*k&Z_DNd&T;b!*&wUz$^*OjZX-KdA*>wjZgs3kUk*Oe|ptg^4RfLB0=vO>4 z5BB2fdnU<&jbhhsvTFZOW}8fEB}Al(UD$CvwS$YlVfMNWdsVh!6x+xV*Up5r_ITg= zP#kqL@0gr$boIXn;$TK+V@It-(*W*T8V7dU&tczZz-KjQfc99pA}>9VV5!SCWS^p6 zy?1uBQ+6T8NK`22;4NO)1cSo{spH>;U{m56_HaoU;mfvCkx9nI<4FXtij#fz08@M`pF5YAaH(&n=zn_Kj@pX&M z_ew1;-=9f*E-No823S!Q~!brb|{DSS&5xhP+AO^@snI&`g!B;*6%;pXWzE&SCA;0^0E^_?pGLuX zvrCrK5Qr87+otHhN}av9;??j#-t}`O_8^#fQ#&1?q$kcrmDa>2S<|h<20x@4sm7Y& zHx{aE9a>{pE|De%O#YJxCI_PS&C370lREHvk!VMZO3wpuS`A8PQNgGzzzm=C%03mt zMCc3nRSl0jD9aGK?;SI#RQCLXQ zL)t~LtTe8EFovq8tOM^rDGw6&;>kq>#h=<)qoF}Lnh3%~-B=r!9103*NlBP8MY8r! zafw7px=QGLEsQFkyL7@y1{~=oNX%@z-?VZ->o_@`6hg|F%COq7&i+}>*;$gAMJ7cF zN_>Vbh?0@S4Vn8lO!t9OcWtwXo&^&tI%YmVd`?;j1C2d$q>1+KRJfAo4nrRLFsV|L0b9OO7?Nqk5xOrk zUi^3yol#qK+(^k^g`tbsO8}u-$~NLQ)))UysCkRdZF3qbwalgw5$90fGTkMAd&-62 z<+kt5!K=2+Rzyjxzb6)t@VzLM+S8VvowH(FR=4}3%YWDjoLe+p#FW97w2MoLLU&)@~OTidPp zrN=jxJxb2#5#TzV4-Fk4Bk;#t9M8U7epe|>+Kw`C1>kT`BK=4bCa03l02{>+=@{eF(_P zNb;u?#}(T|O07w^c_affPH+1DV=vKnZcMdPpx^iPj zg6F-@<8x2y(A;~BvkVB=yob#kACRF8P0ShoT2 z4d?>(yV+zaXFHG97hWAalw1|*g^W0EQRz9 z&M~bMDrrTmoNsu(6=m_bEmr%VipD?$xv$*EISi|hE@ke7yL`5kUpe*Ko z(f1Yy^L?LPam}`2lHiv83QYSl?40n83rm40f(l$RV9E?UGxh$Y$yEx%5S%!=(%o0Y z*T@27jK463FOstb!cu>BQ8jd(gsQP*6fMteE>G+Ysj$5!4b8>Yl62DQFs~D#SsNGN z<*i{Y>uu<44G2nYJ~alSEOz5hq*kb0EKfH66AIWg=&z2gg`t5hL;aRqKVi78(a^-O zlFv#dAQ9?GzD}Ybsp65zJsxtC!lk(sZ&^D(jeT8lan@TF*RQ4-MW@JMCzJT$NM#^v zGGOA2{!7`+02YJi?O9zJ#BMzemXAG!={AU9Da}y%1ew(_xnf)0mv#<+Dvse7m~oQ4lq%;xQb{+ z*49}#hVg}uM?lKWBb!n+NyuC^M04AX@f{}g3u8#$@A~HIrINef@r}N#X7h~-Wu%F~ z?)1Hms*}A`vpaRaGJ+olcCqLzxtXy0%nZ^8p@yAPk67Q*q;~hlwLl-tn1fXSWIZYi zx8@2AjyjoQ66{tgdK457`&_kMM`M6@wpbHs|AV&zi@n=ccdEkjMaC~6cKKn5IRyw6vq;*2AN{z=;LkJc(QRx&3_QZ84-HSP#P=MBP`@w zdp71C6_#Bv2r=CDcxr@y6sjET58uvtii7Z|g@<$X78|i@?O}A*kGh44eg`wf7}#bV z7jFy9H{7Jx?QdpJmf!Rvk9HXKU~Ry`v@Xo*aIzbkTO2Cxl>1MQDd6 zDyoq`(lB$0bNp@Hw%X4BU!^Z)1&#)8;E+)e=^Y|XBy>$f<9Y-lY4{8h=K3qLkdk(x z-WUe0#e-&lyIT%r%>|3Up{LwTk6;SK2O*}?*VV&XXNgvz_WQ>o7}I2-x4xF(+eoFO zmKI4KAg3(xEa}fBa=u^_y1WHS@a(!f{-T8gCmU39x}-D<3SrTJF(s(s0kwRRl0@&) zuJU>@A?fKUoJ~6F(8{w|PZewGQ#9^u{wr9_&b9@6ylyArNv3j1c7~~qN@ybEgAHi5 zqOqWLi;Bs_S#f+$hMXuv1hg9$n~`KqXR7MEQpb;3yc61qo zbze?i=yy7qVO%VD{Z$dF3(n=dXeq4a3Q0ydoiV;bo_t0(*?!|7hfa2#9e0VBPH-Bu z@w~-FC~JceFkeDMYFF3_(+o^--J5W!xl8*UVt9bLeD3n95RQR_ccS-|f&r{Wd47Vp zsXCt!A%CGhNYbFPavJF+?9Ikz*GxGx*F|c0gkY_Fh3TVhp|yp=tZa&K4g?~wd7XS==6SMwF~@>jFlPhUtnwF?loSnB)(j5r52sHSMPGk!){$HhWQCQNG)FUO5ntu0wuvACpOFc0uIlQwY2 zILv&W=goh+z{V63`8MzKe%Nf@dibn{{6566X6FV{28U3@Fkx4i)h{XYQCiBbBgkTD zq%w1aT4g08_1N9^V08NbWRU`kBqB9zs$tH%(#71he!HfzvM?-Z_9ab zGQJr`K_GTZZK+G%_6$QXZZtZ~j_MQR2b~E-y?DOvz^|K>NbeLsHrIXtoba0w|LLin z>Hp%Xor#(0zY|j!8S5Ju=o=d!Kfp#qM%^#DzQ8a7J`TH1qDrojP0lp$(V@nfb5MR!KmnnAmNvd6}0ztG_{l{2@I7Hm5>NX z>Gk#S=+HH^ZP4{q=*%gN74$Hb2o;pKbg)#=u#61U^3{z9)HAfL1RS67#2@6~Ys+sY zZV?|~<0EMyhdU=070N#fMo&k_(CGGazW;vP?YS8HlG!?A^40r@fB(G8`zoZ`>T){a z?osJl>f%sbPjk(?;qA>nlB4rdb<2s=7KGd?_{rJ{gWJ329WH952+%3<8pZVJZ3N-V zHuIUwW=YG@6#vOLhDuSlVX=r7nBrbQ&i&R zQ0Ep0W@)orLe|a>lf~fmdmCDv?#@g@FIR;^Z&xQn2T5N^K0`%Kb4htieMvb|u`wor*!5&V0 zzC6a7=8EEu&Im#S)AxK>&mIZti>pjsa@EbPrBzKitQ2JQ`DwX%ZVP{}*H1Br66*A3 z^AVTTt3hm6uhq>7VOLL8j}80VB^!)m$1MK_fitV`p7{uSdxy59g_dso=fZvd^5Yh8kRY0<~u#g2q1L}&Z z`7x1JDNUFqWX&9seu+eYHt)BceZ8z=4^I!S9Bn6D=GS=9PlpJVEvH}&(gqI)*lNx<2w9StYRo?j~X(0`eC2mU3zqkpUXMI^h921~wId zYa|}}i|jltdCf%4;{B|=M9pL{XTl_aAcS~Jvuk~QQ)6QXt@om!yU$b_C|~4RGwtV| zocGUdJdZ*o)4y_;xswf~ZU(*Dj&4GtUN?3Je6xr*&pS9fIy*8*TxG7)Hn%tbzN_4I z9t&8oy*co^oINgq@P`T7Q#`i5w5VC#^&WEt3%8c9Jp5LSy^}sC@9)~BnTMT37}|%e z(3`d~yOll2z8qgJKebPq-yNNwE||n_k}bQO+dXW(tKKQ6dlb4Ki$4FGwryuu4%$f&+;ytT2Q{XXC=7qh;yQ);)x3cMBn=a*HA&V|19+kZ>?Csx%B1A408d zdP!BR7Otc5k3W)0VZX%@7oK^&e=H>_L1YbwYGr_X3}nAD7z)cgUWLO93u6c%G9J=DP`wj)NS3CWO#Y-iJ#s~whj8I5tI!&QlS{to zfcGBnFo!GlM5`pXR9eNH!Fq!=m!WEAdXOJA*FRP5=*^Fpcc;8F<+e}&AIjV=a<(FJ zqs+RpUpudQ-#Yrjpz!Z?=u01`(`Glrf!X-mbN&Ml`P4@@VR^zjHP3O#WqQORQ0q_E zo!U$XZ1a`a+Hwx_KYh6%-xE{+6m$V@oQa48IX)-}SMt2e&!!H}etTJ;Y)SI!0{rcQ z=;_OT!Y9c**4U+L~KsGH7A>5A7{=Y-#!}jZ9V*D?rS| zeMkC05^nD|+gP$r=u%8BDdq_UV#}vy)y`M}jzU%LeucZ>n>BW@ikwgaX3xfR{q7pES=i3!OEPlZ+_p*RN&T1ih0msk z%*|z&X9XH9Kb#&zlxl##Cor=H{(|M*JP-#bxuRupA>~y;M+vwjNA+c)ZzsUa^=@Rg zot3PzM=ee0;)oQVMt^Nq4Yq9+E@ekqJ6SR%6>w66z@t2l$_BoV9yttWa-w87EQMc$ zTI_5T+wxGdICJ+gu#C@b|0Tmu55q~BqHj2c;Qh#ydElMF2LeTC`77I2Kdf_ZUoDob zW4l;}RZ1eWqy*>}e0BU(0W!%F&-%uS$6$*KNfgc`qA&6Jm|EZu+cA>~3_fKh%fPA4 zX?7#)Qv(e@)3=AdBQnYo!-bVGbHXd?%GMPi9WA95^`>uU=r&x{4JOs4=^fS*KTyWX=(O^xAj(?2 z*Wnn?aTZQ~>N4-cE{ZP=p^r#mDWhW_!Uznel60?ShjNzl0ZStzwCGF2KX*lgcBd~p zw|q?Q(Ayt0VAWb1KowSQn*O?wXqRHD6=v!6&~!?Hxh<7B9=7bDf7fLai61^lG00D? zmA7BIN$zE+qGZYS;>z;}dqjMwl@=j##5Q^UNvdLr1Yx`2>&B2Hqs|L-VCwzloShS( zVRobvOyhwucYo-6+(C{NFANeqazM`wMgujD%Pn;98VbT zsc^+cL86>*EJAL@Q-nO~K??5Yx7!zX?H;s+#U@*oeTTdGzCiv@VVUv&A}lkpva_l}EWy4^uqR(3WSM(SVg>+8GPNg^WRa%7k_PrN@wkPLMWX;Fz%y zoz;=rL}*5@mh!5-yW${nv^%|*$rr6!zqL;1F!4qy0U|-tA(bM;n$Yza9wttF(uxU^e9$=iXygsWd43^2XyD!cu@Bp;pYqrh zPFavS31gc3ZQCKdqOYdqA~o!%NzE%RcB1;Os&ernSW&Z@4}!A_Y-!YuRDzvrY;`PW zyo5JC>PIwUL!mdB_Xxa62tTS#sED=rxUEmb%*p~-I%1srS&%+`h(|F>3;V5Jfk(ll z+Br{jEHg2Yo1{b5W!Fs*^NAGTj(;5EMG!#rQ6E|-G%DJ(Vy)MurP+RfCK7@LjT(f~ z+@9c~nyut&wY%|?WpihZw@dT9;iKw@WGlMB&rZm%cu`@a<)GZzYA3U|`J-7kTlciT zqYFi}o607o{;c#sG`f zUYkN8anSixz?14bPcLD8;IbY-)qKWLWPX|U3&TN$W`1!QkR9WN47irB7H-lVYdz~a z{wrwtY?^E-p^kuI4c3*@sZ+X64MIDG(OUXZn=j`wU+Fh`GstEld9@7QTEBz|Yslr` zqrPWs)#gq^R8}I!j@hRkpdK_OK*Ee_k7Ra(W_E{+SGBHciRF@hf+$WZR9x#S-tHv- ze3lNJoat;amO5$HSXNwntGk3|OYrbGoSlObwVf&_<=Y+r zjbKyQMQyxC zE~hK%eV7?4H=RGuW#)A{VPp0*aVVA2Ue}~b!tJyaBEuT}nFIV?KNBw^LdHbd0b9;a z+O}>QTsM2cgE{#MtDyIfkbj;!=VQa4GtSxXr-0mb0XMpRbV#vGX+fSXZKRcwKW?Om zI7ECdHVDz-i|M-du40d_nYrnVm-i}%*ay9&7@n36tX*wRX6{`24uf;1kw_wcH{`@~ z?IC4Hy}TMCY9P?L-u4RIhtni4y(tUWkA$|L(;0}5I_hrP%9{W!jA2kJ{Rt?-N033x zZ5@S}aC`0t#F|s)*s^zkMf5EhgCM41nbIE~XXdC6&xT^*YSJtW(k7axj1@V_hsz_8!h42+9>t;m@8yB zRo<&Uc;XbsyU^re#M3C5IxgVAg*3!dW8?v8i#FfsD_5~n z9?MB+w~@i}iuE_JRr?u(bZa0NkK!?hCx+l{BmeLwo8LxU1UUv=_3SYA;Rgu^mTQZ4 z8P8}6bQ{6;eauMI5DX~qls@foxwUybosmF+d&geJ-{pE=Ff@}Lm@zNNKSSkwn5>y6zp5^Rk z9sZsnUUDM^zUS;f4zOe zjz#kqmPYwSTHq1NlW6OkQ#S;&FH&)ecW-6Jh}zb zV>l6UoO>Dfg`{XSUT|GJSJ1xwUB0mCyFUSaCHzPBhEhN|rGbUB>1*}ONx|zpZ0@ya z;SvsapKS;XTzB{Rg5mN>5+`DB#R9aMF z5-)rtX25blGG#ZFWKitfzgA^7s;P;xa{28!nTy*ZQF-<17=P?h-9*l=uqWz8T5_i+ z@2uCtKeQC|Eg&7(42ww;SHmZPOESIT2(4k;e^6guNyZj!9I2e?TxtXwAVi)yaJNq~ z{%y&drm|oQB3m1^jB^Ucy+7%>@G7|l*WAXk1Q{B*qUhO`N*hx*U^$;pAN-C-m$m** zIH;=@BeQ@6@o$T(TlbGCU_ICZNMqBcP=IjQWD)8xSwi({v2w69jvyYQSp?j1Qk+I7 zln!p&RS=8wk~Nz=ys9E|45_@4jFt^$l&NUKY=L8*7_!kA!ksA<3~9+9W+-C=VsZ@V z;Z3U^l|XiyBT*mAwnVfu0-O~@jqybq`6JSyiwago-)9lU`0t|3l&lPjiv*69FWTZ& z^%J8sMBD!D=b%IU&Xc+HPt5`*ie;M**8{rnOdZOKXR44bLy^tIs`c-OV4)M6jJ?sxp+KcyJ? zm||Ro^RgA~0TeB(Stjc#NbT2VBZIIIUQd3(PMRM5NOG8*Q-&`>*c*MBX6x@8J}}m& zBR%kX~BRrBgd^t~7Rm7}`X&pz|!rL9ODN8vk0zflJQ%yT5I~ugrQ_w}U zDov%M%2Y=&*Soum<`6Dp4{&qHV`c@D1a6RK`^trNa8U}3pI*+q;&HlXbOReKxhU>1 zU2h{SRqrA7Kan?^H@IeWtW~A135Oy?+HeU-3Xb77%wSX=4Sy<{O+y%kv$C(=l(DIW zw{baG@MY>*DeQS@=Cf@q5``7Q;xrLTMN}VF8^R;-h|qmF|H5PptC2KUC=)KuI0dk& ze!SdI>HBy{Ow{Bzq)QXRDeQUC$#`4P3f}UOb13>OIs)F85tn_|0mfS#Vy;OARHoht zoDY}Pw%{Il9SAC2$xc7Fj%O+REProDwBOTWv56&j13D; z2P-9sm6M?rVg?D6Kw>5hq7mk=h6s_Y0mNzZJxOe1?$TL@sCRhMoyuNTRsBWrSHl7Y z1tuhtTCbnNDuhTU6``T~d1P8HvQeRMNtMjx+bfyOjq#+5n=cn**%=iKX(A-N+Vxm< zL1I`&;}=+QH4~Y|K}(Q4oSf-g)%rK`_L#YAhSsTA9g_yuHWJxwCM~qh-HIZYb{Wj3 zrobqmXz{J&O)EkwLQ1i%Z{zOok|Q0=8IERDRcXnljuXGPC}z)I1rID)|Jfa( z(l&zIGC~O)*m|-zNBxW%YR#Sh(th{87uTD_-=tPKd+-wT!8>`c`~JXM62-I;p(es*mSvU|t;&)Xl1ULN0Ii$be0TwzO!pM& zf|~8czAI)q#{=??wlk-|37LwiGjpgvvia_VD`d-LEi; n&{z5F_#xER^Jol9p!P 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. +% +% GLPK is free software: you can redistribute it and/or modify it +% under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% GLPK is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +% License for more details. +% +% You should have received a copy of the GNU General Public License +% along with GLPK. If not, see . +%*********************************************************************** + +\documentclass[11pt,spanish]{report} +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage{amssymb} +\usepackage[dvipdfm,linktocpage,colorlinks,linkcolor=blue, +urlcolor=blue]{hyperref} +\usepackage{indentfirst} + +\setlength{\textwidth}{6.5in} +\setlength{\textheight}{8.5in} +\setlength{\oddsidemargin}{0in} +\setlength{\topmargin}{0in} +\setlength{\headheight}{0in} +\setlength{\headsep}{0in} +\setlength{\footskip}{0.5in} +\setlength{\parindent}{16pt} +\setlength{\parskip}{5pt} +\setlength{\topsep}{0pt} +\setlength{\partopsep}{0pt} +\setlength{\itemsep}{\parskip} +\setlength{\parsep}{0pt} +\setlength{\leftmargini}{\parindent} +\renewcommand{\labelitemi}{---} + +\def\para#1{\noindent{\bf#1}} + +\renewcommand\contentsname{\sf\bfseries Contenidos} +\renewcommand\chaptername{\sf\bfseries Capítulo} +\renewcommand\appendixname{\sf\bfseries Apéndice} + +\begin{document} + +\thispagestyle{empty} + +\begin{center} + +\vspace*{1.5in} + +\begin{huge} +\sf\bfseries Lenguaje de Modelado GNU MathProg +\end{huge} + +\vspace{0.5in} + +\begin{LARGE} +\sf Referencia del Lenguaje +\end{LARGE} + +\vspace{0.5in} + +\begin{LARGE} +\sf para GLPK Versión 4.50 +\end{LARGE} + +\vspace{0.5in} +\begin{Large} +\sf (BORRADOR, Mayo del 2013) +\end{Large} + +\end{center} + +\newpage + +\vspace*{1in} + +\vfill + +\noindent +El paquete GLPK es parte del Proyecto GNU distribuido bajo la égida de GNU + +\noindent +Copyright \copyright{} 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, +2008, 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied +Informatics, Moscow Aviation Institute, Moscow, Russia. Todos los derechos +reservados. + +\noindent +Título original en inglés: Modeling Language GNU MathProg - Language Reference for GLPK Version 4.50 + +\noindent +Traducción: Pablo Yapura, Facultad de Ciencias Agrarias y Forestales, Universidad Nacional de La Plata, La Plata, Argentina. + +\noindent +Copyright \copyright{} 2013 Pablo Yapura, para esta traducción. Todos los derechos reservados. + +\noindent +Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +MA 02110-1301, USA. + +\noindent +Se permite realizar y distribuir copias textuales de este manual siempre que se preserve este aviso de permiso y el aviso del copyright en todas las copias. + +\noindent +Se permite copiar y distribuir versiones modificadas de este manual bajo las condiciones de copias textuales, siempre que también se distribuya íntegro el trabajo derivado resultante bajo los términos de un aviso de permiso idéntico al presente. + +\noindent +Se permite copiar y distribuir traducciones de este manual en otro idioma bajo las condiciones establecidas arriba para versiones modificadas. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +{\setlength{\parskip}{0pt} +\tableofcontents +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Introducción} + +{\it GNU MathProg} es un lenguaje de modelado diseñado para describir modelos lineales de programación matemática.\footnote{El lenguaje GNU MathProg es un subconjunto del lenguaje AMPL. Su implementación en GLPK está basada principalmente en el paper: {\it Robert Fourer}, {\it David M. Gay} \& {\it Brian W. Kernighan}, ``A Modeling Language for Mathematical Programming.'' {\it Management Science} 36 (1990), pp.~519-554.} + +La descripción del modelo escrita en el lenguaje GNU MathProg consiste en un conjunto de sentencias y bloques de datos construidos por el usuario a partir de los elementos del lenguaje que se describen en este documento. + +En un proceso que se denomina {\it traducción}, un programa denominado {\it traductor del modelo} analiza la descripción del modelo y la traduce en una estructura interna de datos, la que puede ser usada tanto para generar una instancia de un problema de programación matemática, como para obtener directamente una solución numérica del problema mediante un programa denominado {\it solver}. + +\section{El problema de la programación lineal} +\label{problem} + +En MathProg el problema de la programación lineal (PL) se expresa como sigue: + +\medskip + +\noindent\hspace{1in}minimizar (o maximizar) +$$z=c_1x_1+c_2x_2+\dots+c_nx_n+c_0\eqno(1.1)$$ +\noindent\hspace{1in}sujeto a las restricciones lineales +$$ +\begin{array}{l@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }l} +L_1&\leq&a_{11}x_1&+&a_{12}x_2&+\dots+&a_{1n}x_n&\leq&U_1\\ +L_2&\leq&a_{21}x_1&+&a_{22}x_2&+\dots+&a_{2n}x_n&\leq&U_2\\ +\multicolumn{9}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\ +L_m&\leq&a_{m1}x_1&+&a_{m2}x_2&+\dots+&a_{mn}x_n&\leq&U_m\\ +\end{array}\eqno(1.2) +$$ +\noindent\hspace{1in}y a las cotas de las variables +$$ +\begin{array}{l@{\ }c@{\ }c@{\ }c@{\ }l} +l_1&\leq&x_1&\leq&u_1\\ +l_2&\leq&x_2&\leq&u_2\\ +\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .}\\ +l_n&\leq&x_n&\leq&u_n\\ +\end{array}\eqno(1.3) +$$ + +\noindent +donde $x_1$, $x_2$, \dots, $x_n$ son variables; $z$ es la función objetivo; $c_1$, $c_2$, \dots, $c_n$ son coeficientes de la función objetivo; $c_0$ es el término constante (``de traslación'') de la función objetivo; $a_{11}$, +$a_{12}$, \dots, $a_{mn}$ son coeficientes de las restricciones; $L_1$, $L_2$, +\dots, $L_m$ son cotas inferiores de las restricciones; $U_1$, $U_2$, \dots, $U_m$ son cotas superiores de las restricciones; $l_1$, $l_2$, \dots, $l_n$ son cotas inferiores de las variables y $u_1$, $u_2$, \dots, $u_n$ son cotas superiores de las variables. + +Las cotas de las variables y las cotas de las restricciones pueden ser tanto finitas como infinitas. Además, las cotas inferiores pueden ser iguales a las correspondientes cotas superiores. Entonces, están permitidos los siguientes tipos de variables y restricciones: + +\medskip + +{\def\arraystretch{1.4} +\noindent\hspace{54pt} +\begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }l@{\hspace*{39.5pt}}l} +$-\infty$&$<$&$x$&$<$&$+\infty$&Variable libre (no acotada)\\ +$l$&$\leq$&$x$&$<$&$+\infty$&Variable con cota inferior\\ +$-\infty$&$<$&$x$&$\leq$&$u$&Variable con cota superior\\ +$l$&$\leq$&$x$&$\leq$&$u$&Variable doblemente acotada\\ +$l$&$=$&$x$&=&$u$&Variable fija\\ +\end{tabular} + +\noindent\hspace{54pt} +\begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }ll} +$-\infty$&$<$&$\sum a_jx_j$&$<$&$+\infty$&Forma lineal libre (no acotada)\\ +$L$&$\leq$&$\sum a_jx_j$&$<$&$+\infty$&Restricción de inecuación ``mayor o igual que''\\ +$-\infty$&$<$&$\sum a_jx_j$&$\leq$&$U$&Restricción de inecuación ``menor o igual que''\\ +$L$&$\leq$&$\sum a_jx_j$&$\leq$&$U$&Restricción de inecuación doblemente acotada\\ +$L$&$=$&$\sum a_jx_j$&=&$U$&Restricción de igualdad\\ +\end{tabular} +} + +\medskip + +Además de problemas puros de PL, MathProg también permite problemas de programación entera lineal mixta (PEM), en los que algunas o todas las variables se han restringido a ser enteras o binarias. + +\section{Objetos del modelo} + +En MathProg el modelo se describe mediante conjuntos, parámetros, variables, restricciones y objetivos, los que se denominan {\it objetos del modelo}. + +El usuario introduce objetos particulares del modelo usando las sentencias del lenguaje. Cada objeto del modelo está provisto de un nombre simbólico que lo identifica de manera única y está pensado con propósitos de referencia. + +\newpage + +Los objetos del modelo, incluyendo los conjuntos, pueden ser arreglos multidimensionales construidos sobre conjuntos indizantes. Formalmente, el arreglo $n$-dimensional $A$ es el mapeo $$A:\Delta\rightarrow\Xi,\eqno(1.4)$$ donde $\Delta\subseteq C_1\times\dots\times C_n$ es el subconjunto del producto cartesiano de los conjuntos indizantes, $\Xi$ es el conjunto de los miembros del arreglo. En MathProg, el conjunto $\Delta$ se denomina {\it dominio del subíndice}. Sus miembros son los $n$-tuplos $(i_1,\dots,i_n)$, donde +$i_1\in C_1$, \dots, $i_n\in C_n$. + +Si $n=0$, el producto cartesiano tiene exactamente un miembro (específicamente, un 0-tuplo), de forma tal que es conveniente pensar en los objetos escalares como arreglos 0-dimensionales que tienen un solo miembro. + +El tipo de los miembros del arreglo se determina por el tipo del objeto del modelo correspondiente como sigue: + +\medskip + +\noindent\hfil +\begin{tabular}{@{}ll@{}} +Objeto del modelo&Miembro del arreglo\\ +\hline +Conjunto&Conjunto plano elemental\\ +Parámetro&Número o símbolo\\ +Variable&Variable elemental\\ +Restricción&Restricción elemental\\ +Objetivo&Objetivo elemental\\ +\end{tabular} + +\medskip + +Para referir al miembro particular de un objeto, el mismo debe estar provisto de {\it subíndices}. Por ejemplo, si $a$ es un parámetro 2-dimensional definido sobre $I\times J$, una referencia a sus miembros particulares se puede escribir como $a[i,j]$, donde $i\in I$ y $j\in J$. Se sobreentiende que los objetos escalares no necesitan subíndices por ser 0-dimensionales. + +\section{Estructura de la descripción del modelo} + +A veces es deseable escribir un modelo que, en distintos momentos, puede requerir diferentes datos para solucionar cada instancia del problema usando el modelo. Por esta razón, en MathProg la descripción del modelo consta de dos partes: la {\it sección del modelo} y la {\it sección de los datos}. + +La sección del modelo es la parte principal de la descripción del modelo que contiene las declaraciones de los objetos del modelo; es común a todos los problemas basados en el modelo correspondiente. + +La sección de los datos es una parte opcional de la descripción del modelo que contiene los datos específicos para una instancia particular del problema. + +Dependiendo de lo que sea más conveniente, las secciones del modelo y de los datos pueden disponerse en el mismo archivo o en dos archivos separados. Esta última característica permite tener un número arbitrario de secciones con datos diferentes para ser usadas con la misma sección del modelo. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\chapter{Codificación de la descripción del modelo} +\label{coding} + +La descripción del modelo se codifica en formato de texto plano usando el juego de caracteres ASCII. Los caracteres válidos en la descripción del modelo son los siguientes: + +\begin{itemize} +\item caracteres alfabéticos:\\ +\verb|A B C D E F G H I J K L M N O P Q R S T U V W X Y Z|\\ +\verb|a b c d e f g h i j k l m n o p q r s t u v w x y z _| +\item caracteres numéricos:\\ +\verb|0 1 2 3 4 5 6 7 8 9| +\item caracteres especiales:\\ +\verb?! " # & ' ( ) * + , - . / : ; < = > [ ] ^ { | } ~? +\item caracteres no imprimibles:\\ +\verb|SP HT CR NL VT FF| +\end{itemize} + +Dentro de los literales de cadena y de los comentarios, cualquier carácter ASCII (excepto los caracteres de control) son válidos. + +Los caracteres no imprimibles no son significativos. Se pueden usar libremente entre las unidades léxicas para mejorar la legibilidad de la descripción del modelo. También se usan para separar unidades léxicas entre sí, en caso de no existir otra forma de hacerlo. + +Sintácticamente, la descripción del modelo es una secuencia de unidades léxicas de las siguientes categorías: + +\begin{itemize} +\item nombres simbólicos; +\item literales numéricos; +\item literales de cadena; +\item palabras clave; +\item delimitadores; +\item comentarios. +\end{itemize} + +Las unidades léxicas del lenguaje se discuten a continuación. + +\section{Nombres simbólicos} + +Un {\it nombre simbólico} consiste de caracteres alfabéticos y numéricos, el primero de los cuales debe ser alfabético. Todos los nombres simbólicos deben ser distintos (sensibilidad a las mayúsculas). + +\para{Ejemplos} + +\begin{verbatim} +alfa123 +Esto_es_un_nombre +_P123_abc_321 +\end{verbatim} + +Los nombres simbólicos se usan para identificar los objetos del modelo (conjuntos, parámetros, variables, restricciones y objetivos) y los índices. + +Todos los nombres simbólicos (exceptuando los nombres de los índices) deben ser únicos, {\it i.e.} la descripción del modelo no debe tener objetos distintos con el mismo nombre. Los nombres simbólicos de los índices deben ser únicos dentro del alcance en el que son válidos. + +\section{Literales numéricos} + +Un {\it literal numérico} sigue la forma {\it xx}{\tt E}{\it syy}, donde {\it xx} es un número con punto decimal optativo, {\it s} es el signo {\tt+} o {\tt-} e {\it yy} es un exponente decimal. La letra {\tt E} es insensible a las mayúsculas y se puede codificar como {\tt e}. + +\para{Ejemplos} + +\begin{verbatim} +123 +3.14159 +56.E+5 +.78 +123.456e-7 +\end{verbatim} + +Los literales numéricos se usan para representar cantidades numéricas y tienen significado fijo obvio. + +\section{Literales de cadena} + +Un {\it literal de cadena} es una secuencia arbitraria de caracteres encerrados entre comillas, tanto simples como dobles. Ambas formas son equivalentes. + +Si una comilla simple es parte de un literal de cadena encerrado entre comillas simples, se debe codificar dos veces. Análogamente, si una comilla doble es parte de un literal de cadena encerrado entre comillas dobles, se debe codificar dos veces. + +\para{Ejemplos} + +\begin{verbatim} +'Esta es una cadena' +"Esta es otra cadena" +'No debe usarse los 20''s' +"""Hola, che"" cantaba Favio." +\end{verbatim} + +Los literales de cadena se usan para representar cantidades simbólicas. + +\section{Palabras clave} + +Una {\it palabra clave} es una secuencia de caracteres alfabéticos y posiblemente algunos caracteres especiales. + +Todas la palabras clave caen en alguna de dos categorías: las {\it palabras clave reservadas}, que no pueden usarse como nombres simbólicos, y las {\it palabras clave no reservadas}, que son reconocidas por el contexto y entonces pueden usarse como nombres simbólicos. + +Las palabras clave reservadas son las siguientes: + +\noindent\hfil +\begin{tabular}{@{}p{.7in}p{.7in}p{.7in}p{.7in}@{}} +{\tt and}&{\tt else}&{\tt mod}&{\tt union}\\ +{\tt by}&{\tt if}&{\tt not}&{\tt within}\\ +{\tt cross}&{\tt in}&{\tt or}\\ +{\tt diff}&{\tt inter}&{\tt symdiff}\\ +{\tt div}&{\tt less}&{\tt then}\\ +\end{tabular} + +Las palabras clave no reservadas se describen en secciones posteriores. + +Todas las palabras clave tienen un significado fijo, el que se explicará en las discusiones de las correspondientes construcciones sintácticas donde las palabras claves sean usadas. + +\section{Delimitadores} + +Un {\it delimitador} es tanto un carácter especial individual como una secuencia de dos caracteres especiales, como sigue: + +\noindent\hfil +\begin{tabular}{@{}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in} +p{.3in}p{.3in}@{}} +{\tt+}&{\tt**}&{\tt<=}&{\tt>}&{\tt\&\&}&{\tt:}&{\tt|}&{\tt[}&{\tt>}{\tt>}\\ +{\tt-}&{\tt\textasciicircum}&{\tt=}&{\tt<>}&{\tt||}&{\tt;}&{\tt\char126} +&{\tt]}&{\tt<-}\\ +{\tt*}&{\tt\&}&{\tt==}&{\tt!=}&{\tt.}&{\tt:=}&{\tt(}&{\tt\{}\\ +{\tt/}&{\tt<}&{\tt>=}&{\tt!}&{\tt,}&{\tt..}&{\tt)}&{\tt\}}\\ +\end{tabular} + +Si el delimitador está compuesto por dos caracteres, no debe haber espacios entre ellos. + +Todos los delimitadores tienen un significado fijo, el que se explicará en las discusiones de las correspondientes construcciones sintácticas donde los delimitadores sean usados. + +\section{Comentarios} + +Con propósitos de documentación, la descripción del modelo puede ser provista de {\it comentarios}, los que pueden ser de dos formas diferentes. La primera es un {\it comentario de una línea individual}, el que debe comenzar con el carácter {\tt\#} y se extiende hasta el final de la línea. La segunda forma es un {\it comentario en secuencia}, el que consiste en una secuencia de caracteres cualesquiera encerrados entre {\tt/*} y {\tt*/}. + +\para{Ejemplos} + +\begin{verbatim} +param n := 10; # Esto es un comentario +/* Esto es otro comentario */ +\end{verbatim} + +Los comentarios son ignorados por el traductor del modelo y pueden aparecer en cualquier sitio de la descripción del modelo en la que que se permitan caracteres no imprimibles. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\chapter{Expresiones} + +Una {\it expresión} es una regla para calcular un valor. En la descripción de un modelo, las expresiones se usan como constituyentes de ciertas sentencias. + +En general, las expresiones están compuestas por operandos y operadores. + +Dependiendo del tipo del valor resultante, todas las expresiones pertenecen a alguna de las siguientes categorías: + +\vspace*{-8pt} + +\begin{itemize} +\item expresiones numéricas; +\item expresiones simbólicas; +\item expresiones indizantes; +\item expresiones de conjuntos; +\item expresiones lógicas; +\item expresiones lineales. +\end{itemize} + +\vspace*{-8pt} + +\section{Expresiones numéricas} + +Una {\it expresión numérica} es una regla para calcular un valor numérico individual representado como un número de punto flotante. + +La expresión numérica primaria puede ser un literal numérico, un índice, un parámetro no-indizado, un parámetro indizado, una función interna de referencia, una expresión numérica iterada, una expresión numérica condicional u otra expresión numérica encerrada entre paréntesis. + +\newpage + +\para{Ejemplos} + +\noindent +\begin{tabular}{@{}ll@{}} +\verb|1.23|&(literal numérico)\\ +\verb|j|&(índice)\\ +\verb|tiempo|&(parámetro no-indizado)\\ +\verb|a['Mayo de 2003',j+1]|&(parámetro indizado)\\ +\verb|abs(b[i,j])|&(función de referencia)\\ +\verb|sum{i in S diff T} alfa[i] * b[i,j]|&(expresión iterada)\\ +\verb|if i in I then 2 * p else q[i+1]|&(expresión condicional)\\ +\verb|(b[i,j] + .5 * c)|&(expresión parentética)\\ +\end{tabular} + +Empleando ciertos operadores aritméticos se pueden construir expresiones numéricas más generales conteniendo dos o más expresiones numéricas primarias. + +\para{Ejemplos} + +\begin{verbatim} +j+1 +2 * a[i-1,j+1] - b[i,j] +sum{j in J} a[i,j] * x[j] + sum{k in K} b[i,k] * x[k] +(if i in I and p >= 1 then 2 * p else q[i+1]) / (a[i,j] + 1.5) +\end{verbatim} + +\subsection{Literales numéricos} + +Si la expresión numérica primaria es un literal numérico, el valor resultante es obvio. + +\subsection{Índices} + +Si la expresión numérica primaria es un índice, el valor resultante es el valor corriente asignado al índice. + +\subsection{Parámetros no-indizados} + +Si la expresión numérica primaria es un parámetro no-indizado (el que debe ser 0-dimensional), el valor resultante es el valor del parámetro. + +\subsection{Parámetros indizados} + +La expresión numérica primaria que se refiere a parámetros indizados tiene la siguiente forma sintáctica: +$$ +\mbox{{\it nombre}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,} $i_n${\tt]}} +$$ +donde {\it nombre} es el nombre simbólico del parámetro e $i_1$, $i_2$, +\dots, $i_n$ son subíndices. + +Cada subíndice debe ser una expresión numérica o simbólica. El número de subíndices en la lista de subíndices debe ser igual a la dimensión del parámetro con el cual está asociada la lista de subíndices. + +Los valores reales de las expresiones de subíndices se usan para identificar al miembro particular del parámetro que determina el valor resultante de la expresión primaria. + +\subsection{Funciones de referencia} + +En MathProg existen las siguientes funciones internas, las que se pueden usar en expresiones numéricas: + +\begin{tabular}{@{}p{112pt}p{328pt}@{}} +{\tt abs(}$x${\tt)}&$|x|$, valor absoluto de $x$\\ +{\tt atan(}$x${\tt)}&$\arctan x$, valor principal del arcotangente de +$x$ (en radianes)\\ +{\tt atan(}$y${\tt,} $x${\tt)}&$\arctan y/x$, valor principal del arcotangente de $y/x$ (en radianes). En este caso, los signos de ambos argumentos, $y$ y $x$, se usan para determinar el cuadrante del valor resultante\\ +{\tt card(}$X${\tt)}&$|X|$, el cardinal (número de elementos) del conjunto $X$\\ +{\tt ceil(}$x${\tt)}&$\lceil x\rceil$, el menor entero no menor que $x$ (``techo de $x$'')\\ +{\tt cos(}$x${\tt)}&$\cos x$, coseno de $x$ (en radianes)\\ +{\tt exp(}$x${\tt)}&$e^x$, exponencial en base $e$ de $x$\\ +{\tt floor(}$x${\tt)}&$\lfloor x\rfloor$, el mayor entero no mayor que $x$ (``piso de $x$'')\\ +{\tt gmtime()}&el número de segundos transcurridos desde las 00:00:00 del 1 de enero de 1970, Tiempo Universal Coordinado (para los detalles ver la Sección \ref{gmtime}, página \pageref{gmtime})\\ +{\tt length(}$c${\tt)}&$|c|$, longitud de la cadena de caracteres $c$\\ +{\tt log(}$x${\tt)}&$\log x$, logaritmo natural de $x$\\ +{\tt log10(}$x${\tt)}&$\log_{10}x$, logaritmo común (decimal) de $x$\\ +{\tt max(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&el mayor de los valores $x_1$, $x_2$, \dots, $x_n$\\ +{\tt min(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&el menor de los valores $x_1$, $x_2$, \dots, $x_n$\\ +{\tt round(}$x${\tt)}&redondeo de $x$ al entero más próximo\\ +{\tt round(}$x${\tt,} $n${\tt)}&redondeo de $x$ a $n$ dígitos decimales\\ +{\tt sin(}$x${\tt)}&$\sin x$, seno de $x$ (en radianes)\\ +{\tt sqrt(}$x${\tt)}&$\sqrt{x}$, raíz cuadrada no-negativa de $x$\\ +{\tt str2time(}$c${\tt,} $f${\tt)}&conversión de la cadena de caracteres $c$ a tiempo calendario (para los detalles ver la Sección \ref{str2time}, página \pageref{str2time})\\ +{\tt trunc(}$x${\tt)}&truncado de $x$ al entero más próximo\\ +{\tt trunc(}$x${\tt,} $n${\tt)}&truncado de $x$ a $n$ dígitos decimales\\ +{\tt Irand224()}&generación de un entero pseudo-aleatorio uniformemente distribuido en $[0,2^{24})$\\ +{\tt Uniform01()}&generación de un número pseudo-aleatorio uniformemente distribuido en $[0,1)$\\ +{\tt Uniform(}$a${\tt,} $b${\tt)}&generación de un número pseudo-aleatorio uniformemente distribuido en $[a,b)$\\ +{\tt Normal01()}&generación de una variable gaussiana pseudo-aleatoria con $\mu=0$ y $\sigma=1$\\ +{\tt Normal(}$\mu${\tt,} $\sigma${\tt)}&generación de una variable gaussiana pseudo-aleatoria con $\mu$ y $\sigma$ dadas\\ +\end{tabular} + +Los argumentos de todas la funciones internas, excepto {\tt card}, {\tt length} y {\tt str2time}, deben ser expresiones numéricas. El argumento de {\tt card} debe ser una expresión de conjunto. El argumento de {\tt length} y ambos argumentos de {\tt str2time} deben ser expresiones simbólicas. + +El valor resultante de una expresión numérica que es una función de referencia es el resultado de aplicar la función a sus argumentos. + +Se debe notar que cada función generadora pseudo-aleatoria tiene un argumento latente ({\it i.e.} algún estado interno) que cambia cada vez que se aplica la función. Así, si la función se aplica repetidamente, aún con argumentos idénticos, debido al efecto colateral siempre se producirán valores resultantes diferentes. + +\subsection{Expresiones iteradas} +\label{itexpr} + +Una {\it expresión numérica iterada} es una expresión numérica primaria que tiene la siguiente forma sintáctica: +$$\mbox{\it operador-iterado expresión-indizante integrando}$$ +donde {\it operador-iterado} es el nombre simbólico del operador iterado que se ejecutará (ver más adelante), {\it expresión-indizante} es una expresión indizante que introduce índices y controla la iteración e {\it integrando} es una expresión numérica que participa en la operación. + +En MathProg existen cuatro operadores iterados que se pueden usar en expresiones numéricas: + +{\def\arraystretch{2} +\noindent\hfil +\begin{tabular}{@{}lll@{}} +{\tt sum}&sumatoria&$\displaystyle\sum_{(i_1,\dots,i_n)\in\Delta} +f(i_1,\dots,i_n)$\\ +{\tt prod}&multiplicatoria&$\displaystyle\prod_{(i_1,\dots,i_n)\in\Delta} +f(i_1,\dots,i_n)$\\ +{\tt min}&mínimo&$\displaystyle\min_{(i_1,\dots,i_n)\in\Delta} +f(i_1,\dots,i_n)$\\ +{\tt max}&máximo&$\displaystyle\max_{(i_1,\dots,i_n)\in\Delta} +f(i_1,\dots,i_n)$\\ +\end{tabular} +} + +\noindent donde $i_1$, \dots, $i_n$ son índices introducidos en la expresión indizante, $\Delta$ es el dominio, el conjunto de los $n$-tuplos especificados en la expresión indizante que define valores particulares asignados a los índices para ejecutar la operación iterada y $f(i_1,\dots,i_n)$ es el integrando, una expresión numérica cuyo valor resultante depende de los índices. + +El valor resultante de una expresión numérica iterada es el resultado de aplicar el operador iterado a sus integrandos a través de todos los $n$-tuplos contenidos en el dominio. + +\subsection{Expresiones condicionales} +\label{ifthen} + +Una {\it expresión numérica condicional} es una expresión numérica primaria que tiene una de las dos formas sintácticas siguientes: +$$ +{\def\arraystretch{1.4} +\begin{array}{l} +\mbox{{\tt if} $b$ {\tt then} $x$ {\tt else} $y$}\\ +\mbox{{\tt if} $b$ {\tt then} $x$}\\ +\end{array} +} +$$ +donde $b$ es una expresión lógica, mientras que $x$ e $y$ son expresiones numéricas. + +El valor resultante de un expresión condicional depende del valor de la expresión lógica que sigue a la palabra clave {\tt if}. Si toma el valor {\it verdadero}, el valor de la expresión condicional es el valor de la expresión que sigue a la palabra clave {\tt then}. De otro modo, si la expresión lógica toma el valor {\it falso}, el valor de la expresión condicional es el valor de la expresión que sigue a la palabra clave {\tt else}. Si se usa la segunda forma sintáctica, la reducida, y la expresión lógica toma el valor {\it falso}, el valor resultante de la expresión condicional será cero. + +\subsection{Expresiones parentéticas} + +Cualquier expresión numérica puede ser encerrada entre paréntesis, lo que las torna sintácticamente en una expresión numérica primaria. + +Los paréntesis pueden usarse en expresiones numéricas, como en el álgebra, para especificar el orden deseado en el cual se ejecutarán las operaciones. Cuando se usan paréntesis, la expresión entre paréntesis se evalúa antes que el valor resultante sea usado. + +El valor resultante de la expresión parentética es idéntico al valor de la expresión encerrada entre paréntesis. + +\subsection{Operadores aritméticos} + +En MathProg existen los siguientes operadores aritméticos, los que se pueden usar en expresiones numéricas: + +\begin{tabular}{@{}ll@{}} +{\tt +} $x$&más unario\\ +{\tt -} $x$&menos unario\\ +$x$ {\tt +} $y$&adición\\ +$x$ {\tt -} $y$&sustracción\\ +$x$ {\tt less} $y$&diferencia positiva (si $x1$, la segunda forma es la que debe usarse. + +Si se usa la primera forma de la entrada indizante, el índice $i$ sólo puede ser un índice (ver más adelante). Si se usa la segunda forma, los índices $i_1$, $i_2$, \dots, $i_n$ pueden ser indistintamente índices o alguna expresión numérica o simbólica, siempre que al menos uno de los índices sea un índice. La tercera forma, reducida, de la entrada indizante tiene el mismo efecto que si +$i$ (si $C$ es 1-dimensional) o $i_1$, $i_2$, \dots, $i_n$ (si $C$ es $n$-dimensional) se hubieran especificado todos como índices. + +Un {\it índice} es un objeto auxiliar del modelo que actúa como una variable individual. Los valores asignados a los índices son componentes de los $n$-tuplos de conjuntos básicos, {\it i.e.} algunas cantidades numéricas y simbólicas. + +Para referenciarlos, los índices pueden ser provistos con nombres simbólicos. Sin embargo, a diferencia de otros objetos del modelo (conjuntos, parámetros, etc.), los índices no necesitan ser declarados explícitamente. Cada nombre simbólico {\it no-declarado} que se usa en una posición indizante de alguna entrada indizante es reconocido como el nombre simbólico correspondiente al índice. + +Los nombre simbólicos de los índices son válidos solamente dentro del alcance de la expresión indizante en la que se introdujo el índice. Más allá del alcance, estos índices son completamente inaccesibles, de modo que los mismos nombres simbólicos se pueden usar para diferentes propósitos, en particular para representar índices en otras expresiones indizantes. + +El alcance de la expresión indizante, en el que las declaraciones implícitas de los índices son válidas, depende del contexto en que se usa la expresión indizante: + +\vspace*{-8pt} + +\begin{itemize} +\item Si la expresión indizante se usa en un operador-iterado, su alcance se extiende hasta el final del integrando; +\item Si la expresión indizante se usa como una expresión de conjunto primaria, su alcance se extiende hasta el final de esta expresión indizante; +\item Si la expresión indizante se usa para definir el dominio del subíndice en la declaración de algún objeto del modelo, su alcance se extiende hasta el final de la correspondiente sentencia. +\end{itemize} + +\vspace*{-8pt} + +El mecanismo de indización implementado mediante las expresiones indizantes se explica mejor con algunos ejemplos que se discuten a continuación. + +Sean tres conjuntos: +$$ +{\def\arraystretch{1.4} +\begin{array}{l} +A=\{4,7,9\},\\ +B=\{(1,Ene),(1,Feb),(2,Mar),(2,Abr),(3,May),(3,Jun)\},\\ +C=\{a,b,c\},\\ +\end{array} +} +$$ +donde $A$ y $C$ consisten de 1-tuplos (singletones) y $B$ consiste de +2-tuplos (duplos). Considérese la siguiente expresión indizante: +$$\mbox{{\tt\{i in A, (j,k) in B, l in C\}}}$$ +donde {\tt i}, {\tt j}, {\tt k} y {\tt l} son índices. + +Aunque MathProg no es un lenguaje de programación por procedimientos, para cualquier expresión indizante se puede dar una descripción algorítmica equivalente. En particular, la descripción algorítmica de la expresión indizante anterior se vería como sigue: + +\noindent\hfil +\begin{tabular}{@{}l@{}} +{\bf para todo} $i\in A$ {\bf ejecutar}\\ +\hspace{16pt}{\bf para todo} $(j,k)\in B$ {\bf ejecutar}\\ +\hspace{32pt}{\bf para todo} $l\in C$ {\bf ejecutar}\\ +\hspace{48pt}{\it acción};\\ +\end{tabular} + +\noindent donde los índices $i$, $j$, $k$ y $l$ son asignados consecutivamente a los correspondientes componentes de los $n$-tuplos a partir de los conjuntos básicos $A$, $B$ y $C$ y {\it acción} es alguna acción que depende del contexto en el que se esté usando la expresión indizante. Por ejemplo, si la acción fuese imprimir los valores corrientes de los índices, la impresión se vería como sigue: + +\noindent\hfil +\begin{tabular}{@{}llll@{}} +$i=4$&$j=1$&$k=Ene$&$l=a$\\ +$i=4$&$j=1$&$k=Ene$&$l=b$\\ +$i=4$&$j=1$&$k=Ene$&$l=c$\\ +$i=4$&$j=1$&$k=Feb$&$l=a$\\ +$i=4$&$j=1$&$k=Feb$&$l=b$\\ +\multicolumn{4}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\ +$i=9$&$j=3$&$k=Jun$&$l=b$\\ +$i=9$&$j=3$&$k=Jun$&$l=c$\\ +\end{tabular} + +Sea la expresión indizante del ejemplo usada en la siguiente operación iterada: +$$\mbox{{\tt sum\{i in A, (j,k) in B, l in C\} p[i,j,k,l]}}$$ +donde {\tt p} es un parámetro numérico 4-dimensional o alguna expresión numérica cuyos valores resultantes dependan de {\tt i}, {\tt j}, {\tt k} y {\tt l}. En este caso la acción es la sumatoria, de modo que el valor resultante de la expresión numérica primaria es: +$$\sum_{i\in A,(j,k)\in B,l\in C}(p_{ijkl}).$$ + +Ahora, sea la expresión indizante del ejemplo usada como una expresión de conjunto primaria. En este caso, la acción es reunir a todos los 4-tuplos (cuádruplos) de la forma $(i,j,k,l)$ en un conjunto, de modo que el valor resultante de tal operación es simplemente el producto cartesiano de los conjuntos básicos: +$$A\times B\times C=\{(i,j,k,l):i\in A,(j,k)\in B,l\in C\}.$$ +Se debe notar que, en este caso, la misma expresión indizante podría escribirse en la forma reducida: +$$\mbox{{\tt\{A, B, C\}}}$$ +ya que los índices $i$, $j$, $k$ y $l$ no son referenciados y, consecuentemente, sus nombres simbólicos no necesitan ser especificados. + +Finalmente, sea la expresión indizante del ejemplo usada como el dominio del subíndice en la declaración de algún objeto 4-dimensional del modelo, por ejemplo un parámetro numérico: +$$\mbox{{\tt param p\{i in A, (j,k) in B, l in C\}} \dots {\tt;}}$$ + +\noindent En este caso la acción es generar los miembros del parámetro, donde cada uno de los cuales tiene la forma $p[i,j,k,l]$. + +Como se dijo anteriormente, algunos índices en la segunda forma de las entradas indizantes pueden ser expresiones numéricas o simbólicas, no solamente índices. En este caso, los valores resultantes de tales expresiones desempeñan el papel de algunas condiciones lógicas para seleccionar, solamente, aquellos $n$-tuplos del producto cartesiano de los conjuntos básicos que satisfacen estas condiciones. + +Considérese, por ejemplo, la siguiente expresión indizante: +$$\mbox{{\tt\{i in A, (i-1,k) in B, l in C\}}}$$ +donde {\tt i}, {\tt k} y {\tt l} son índices e {\tt i-1} es una expresión numérica. La descripción algorítmica de esta expresión indizante sería la siguiente: + +\noindent\hfil +\begin{tabular}{@{}l@{}} +{\bf para todo} $i\in A$ {\bf ejecutar}\\ +\hspace{16pt}{\bf para todo} $(j,k)\in B$ {\bf y} $j=i-1$ {\bf ejecutar}\\ +\hspace{32pt}{\bf para todo} $l\in C$ {\bf ejecutar}\\ +\hspace{48pt}{\it acción};\\ +\end{tabular} + +\noindent Así, si la expresión indizante se usara como una expresión de conjunto primaria, el conjunto resultante sería el siguiente: +$$\{(4,May,a),(4,May,b),(4,May,c),(4,Jun,a),(4,Jun,b),(4,Jun,c)\}.$$ +Debe notarse que, en este caso, el conjunto resultante consistirá de 3-tuplos y no de 4-tuplos, puesto que en la expresión indizante no hay un índice que corresponda al primer componente de los 2-tuplos del conjunto $B$. + +La regla general es: el número de componentes de los $n$-tuplos definido por una expresión indizante es igual al número de índices de tal expresión, en la que la correspondencia entre los índices y los componentes de los $n$-tuplos en el conjunto resultante es posicional, {\it i.e.} el primer índice se corresponde con el primer componente, el segundo índice se corresponde con el segundo componente, etc. + +En algunos casos es necesario seleccionar un subconjunto del producto cartesiano de algunos conjuntos. Esto se puede lograr mediante el empleo de un predicado lógico opcional, el que se especifica en la expresión indizante. + +Considérese, por ejemplo, la siguiente expresión indizante: +$$\mbox{{\tt\{i in A, (j,k) in B, l in C: i <= 5 and k <> 'Mar'\}}}$$ +donde la expresión lógica que sigue a los dos puntos es un predicado. La descripción algorítmica de tal expresión indizante sería la siguiente: + +\noindent\hfil +\begin{tabular}{@{}l@{}} +{\bf para todo} $i\in A$ {\bf ejecutar}\\ +\hspace{16pt}{\bf para todo} $(j,k)\in B$ {\bf ejecutar}\\ +\hspace{32pt}{\bf para todo} $l\in C$ {\bf ejecutar}\\ +\hspace{48pt}{\bf si} $i\leq 5$ {\bf y} $k\neq`Mar'$ {\bf entonces}\\ +\hspace{64pt}{\it acción};\\ +\end{tabular} + +\noindent Así, si esta expresión indizante se usara como una expresión de conjunto primaria, el conjunto resultante sería el siguiente: +$$\{(4,1,Ene,a),(4,1,Feb,a),(4,2,Abr,a),\dots,(4,3,Jun,c)\}.$$ + +Si no se especifica un predicado en la expresión indizante, se asume uno que toma el valor {\it verdadero}. + +\section{Expresiones de conjunto} + +Una {\it expresión de conjunto} es una regla para calcular un conjunto elemental, {\it i.e.} una colección de $n$-tuplos cuyos componentes son cantidades numéricas y simbólicas. + +La expresión de conjunto primaria puede ser un conjunto de literales, un conjunto no-indizado, un conjunto indizado, un conjunto ``aritmético'', una expresión indizante, una expresión de conjunto iterada, una expresión de conjunto condicional u otra expresión de conjunto encerrada entre paréntesis. + +\para{Ejemplos} + +\noindent +\begin{tabular}{@{}ll@{}} +\verb|{(123,'aaa'), (i+1,'bbb'), (j-1,'ccc')}| &(conjunto de literales)\\ +\verb|I| &(conjunto no-indizado)\\ +\verb|S[i-1,j+1]| &(conjunto indizado)\\ +\verb|1..t-1 by 2| &(conjunto ``aritmético'')\\ +\verb|{t in 1..T, (t+1,j) in S: (t,j) in F}| &(expresión indizante)\\ +\verb|setof{i in I, j in J}(i+1,j-1)| &(expresión de conjunto iterada)\\ +\verb|if i < j then S[i,j] else F diff S[i,j]| &(expresión de conjunto condicional)\\ +\verb|(1..10 union 21..30)| &(expresión de conjunto parentética)\\ +\end{tabular} + +Empleando ciertos operadores de conjunto se pueden construir expresiones de conjunto más generales conteniendo dos o más expresiones de conjunto primarias. + +\newpage + +\para{Ejemplos} + +\begin{verbatim} +(A union B) inter (I cross J) +1..10 cross (if i < j then {'a', 'b', 'c'} else {'d', 'e', 'f'}) +\end{verbatim} + +\subsection{Conjuntos de literales} + +Un {\it conjunto de literales} es una expresión de conjunto primaria que tiene las dos formas sintácticas siguientes: +$$ +{\def\arraystretch{1.4} +\begin{array}{l} +\mbox{{\tt\{}$e_1${\tt,} $e_2${\tt,} \dots{\tt,} $e_m${\tt\}}}\\ +\mbox{{\tt\{(}$e_{11}${\tt,} \dots{\tt,} $e_{1n}${\tt),} +{\tt(}$e_{21}${\tt,} \dots{\tt,} $e_{2n}${\tt),} \dots{\tt,} +{\tt(}$e_{m1}${\tt,} \dots{\tt,} $e_{mn}${\tt)\}}}\\ +\end{array} +} +$$ +donde $e_1$, \dots, $e_m$, $e_{11}$, \dots, $e_{mn}$ son expresiones numéricas o simbólicas. + +Si se usa la primera forma, el conjunto resultante consiste de 1-tuplos (singletones), enumerados entre las llaves. Se permite especificar un conjunto vacío como {\tt\{\ \}}, el que no tiene 1-tuplos. Si se usa la segunda forma, el conjunto resultante consiste de $n$-tuplos enumerados entre las llaves, donde cada $n$-tuplo particular está compuesto por los correspondientes componentes enumerados entre los paréntesis. Todos los $n$-tuplos deben tener el mismo número de componentes. + +\subsection{Conjuntos no-indizados} + +Si la expresión de conjunto primaria es un conjunto no-indizado (el que debe ser 0-dimensional), el conjunto resultante es un conjunto elemental asociado con el objeto conjunto correspondiente. + +\subsection{Conjuntos indizados} + +La expresión de conjunto primaria que se refiere a un conjunto indizado tiene la siguiente forma sintáctica: +$$\mbox{{\it nombre}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,} +$i_n${\tt]}}$$ +donde {\it nombre} es el nombre simbólico del objeto conjunto e $i_1$, $i_2$, +\dots, $i_n$ son subíndices. + +Cada subíndice debe ser una expresión numérica o simbólica. El número de subíndices en la lista de subíndices debe coincidir con la dimensión del objeto conjunto al cual está asociada la lista de subíndices. + +Los valores corrientes de las expresiones de los subíndices se usan para identificar un miembro particular del objeto conjunto que determina el conjunto resultante. + +\subsection{Conjuntos ``aritméticos''} + +La expresión de conjunto primaria que constituye un conjunto ``aritmético'' tiene las dos formas sintácticas siguientes: +$$ +{\def\arraystretch{1.4} +\begin{array}{l} +\mbox{$t_0$ {\tt..} $t_1$ {\tt by} $\delta t$}\\ +\mbox{$t_0$ {\tt..} $t_1$}\\ +\end{array} +} +$$ +donde $t_0$, $t_1$ y $\delta t$ son expresiones numéricas (el valor de +$\delta t$ no debe ser cero). La segunda forma es equivalente a la primera con $\delta t=1$. + +Si $\delta t>0$, el conjunto resultante se determina como sigue: +$$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_0\leq t\leq t_1)\}.$$ +De otro modo, si $\delta t<0$, el conjunto resultante se determina como sigue: +$$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_1\leq t\leq t_0)\}.$$ + +\subsection{Expresiones de indización} + +Si la expresión de conjunto primaria es una expresión indizante, el conjunto resultante se determina como se ha descripto anteriormente en la Sección \ref{indexing}, página \pageref{indexing}. + +\subsection{Expresiones iteradas} + +Una {\it expresión de conjunto iterada} es una expresión de conjunto primaria que tiene la siguiente forma sintáctica: +$$\mbox{{\tt setof} {\it expresión-indizante} {\it integrando}}$$ +donde {\it expresión-indizante} es una expresión indizante que introduce índices y controla la iteración e {\it integrando} es tanto una expresión numérica o simbólica individual como una lista de expresiones numéricas o simbólicas separadas por coma y encerradas entre paréntesis. + +Si el integrando es una expresión numérica o simbólica individual, el conjunto resultante está compuesto por 1-tuplos y se determina como sigue: +$$\{x:(i_1,\dots,i_n)\in\Delta\},$$ +\noindent donde $x$ es un valor del integrando, $i_1$, \dots, $i_n$ son índices introducidos en la expresión indizante y $\Delta$ es el dominio, un conjunto de $n$-tuplos especificados por la expresión indizante que define los valores particulares asignados a los índices para realizar la operación iterada. + +Si el integrando es una lista conteniendo $m$ expresiones numéricas y simbólicas, el conjunto resultante está compuesto por $m$-tuplos y se determina como sigue: +$$\{(x_1,\dots,x_m):(i_1,\dots,i_n)\in\Delta\},$$ +donde $x_1$, \dots, $x_m$ son valores de las expresiones en la lista de integrandos e $i_1$, \dots, $i_n$ y $\Delta$ tienen el mismo significado anterior. + +\subsection{Expresiones condicionales} + +Una {\it expresión de conjunto condicional} es una expresión de conjunto primaria que tiene la siguiente forma sintáctica: +$$\mbox{{\tt if} $b$ {\tt then} $X$ {\tt else} $Y$}$$ +donde $b$ es una expresión lógica y $X$ e $Y$ son expresiones de conjunto que deben definir conjuntos de igual dimensión. + +El valor resultante de la expresión condicional depende del valor de la expresión lógica que sigue a la palabra clave {\tt if}. Si toma el valor {\it verdadero}, el conjunto resultante es el valor de la expresión que sigue a la palabra clave {\tt then}. De otro modo, si la expresión lógica toma el valor {\it falso}, el conjunto resultante es el valor de la expresión que sigue a la palabra clave {\tt else}. + +\subsection{Expresiones parentéticas} + +Cualquier expresión de conjunto puede encerrarse entre paréntesis, lo que la convierte sintácticamente en una expresión de conjunto primaria. + +Los paréntesis pueden usarse en expresiones de conjunto, como en el álgebra, para especificar el orden deseado en el cual se ejecutarán las operaciones. Cuando se usan paréntesis, la expresión entre paréntesis se evalúa antes que el valor resultante sea usado. + +El valor resultante de la expresión parentética es idéntico al valor de la expresión encerrada entre paréntesis. + +\subsection{Operadores de conjunto} + +En MathProg existen los siguientes operadores de conjunto, los que se pueden usar en expresiones de conjunto: + +\begin{tabular}{@{}ll@{}} +$X$ {\tt union} $Y$&union $X\cup Y$\\ +$X$ {\tt diff} $Y$&diferencia $X\backslash Y$\\ +$X$ {\tt symdiff} $Y$&diferencia simétrica $X\oplus Y=(X\backslash Y)\cup(Y\backslash X)$\\ +$X$ {\tt inter} $Y$&intersección $X\cap Y$\\ +$X$ {\tt cross} $Y$&producto cartesiano (``cruzado'') $X\times Y$\\ +\end{tabular} + +\noindent donde $X$ e $Y$ son expresiones de conjunto que deben definir conjuntos de la misma dimensión (excepto para el producto cartesiano). + +Si la expresión incluye más de un operador de conjunto, todos los operadores se ejecutan de izquierda a derecha, de acuerdo con la jerarquía de las operaciones (ver más adelante). + +El valor resultante de la expresión que contiene operadores de conjunto es el resultado de aplicar los operadores a sus operandos. + +La dimensión del conjunto resultante, {\it i.e.} la dimensión de los $n$-tuplos de los que consiste el conjunto resultante, es la dimensión de los operandos, excepto en el producto cartesiano, en la que la dimensión del conjunto resultante es la suma de las dimensiones de sus operandos. + +\subsection{Jerarquía de las operaciones} + +La siguiente lista muestra la jerarquía de las operaciones en expresiones de conjunto: + +\noindent\hfil +\begin{tabular}{@{}ll@{}} +Operación&Jerarquía\\ +\hline +Evaluación de operaciones numéricas& +1.{\textsuperscript{\b{a}}}-7.{\textsuperscript{\b{a}}}\\ +Evaluación de operaciones simbólicas& +8.{\textsuperscript{\b{a}}}-9.{\textsuperscript{\b{a}}}\\ +Evaluación de conjuntos iterados o ``aritméticos'' ({\tt setof}, {\tt..})& +10.{\textsuperscript{\b{a}}}\\ +Producto cartesiano ({\tt cross})& +11.{\textsuperscript{\b{a}}}\\ +Intersección ({\tt inter})& +12.{\textsuperscript{\b{a}}}\\ +Unión y diferencia ({\tt union}, {\tt diff}, {\tt symdiff})& +13.{\textsuperscript{\b{a}}}\\ +Evaluación condicional ({\tt if} \dots {\tt then} \dots {\tt else})& +14.{\textsuperscript{\b{a}}}\\ +\end{tabular} + +Esta jerarquía tiene el mismo significado que se explicó anteriormente para expresiones numéricas (ver Subsección \ref{hierarchy}, página \pageref{hierarchy}). + +\section{Expresiones lógicas} + +Una {\it expresión lógica} es una regla para calcular un valor lógico individual, el que puede ser tanto {\it verdadero} como {\it falso}. + +La expresión lógica primaria puede ser una expresión numérica, una expresión relacional, una expresión lógica iterada u otra expresión lógica encerrada entre paréntesis. + +\para{Ejemplos} + +\noindent +\begin{tabular}{@{}ll@{}} +\verb|i+1| &(expresión numérica)\\ +\verb|a[i,j] < 1.5| &(expresión relacional)\\ +\verb|s[i+1,j-1] <> 'Mar' & anho | &(expresión relacional)\\ +\verb|(i+1,'Ene') not in I cross J| &(expresión relacional)\\ +\verb|S union T within A[i] inter B[j]| &(expresión relacional)\\ +\verb|forall{i in I, j in J} a[i,j] < .5 * b[i]| &(expresión lógica iterada)\\ +\verb|(a[i,j] < 1.5 or b[i] >= a[i,j])| &(expresión lógica parentética)\\ +\end{tabular} + +Empleando ciertos operadores lógicos se pueden construir expresiones lógicas más generales conteniendo dos o más expresiones lógicas primarias. + +\para{Ejemplos} + +\begin{verbatim} +not (a[i,j] < 1.5 or b[i] >= a[i,j]) and (i,j) in S +(i,j) in S or (i,j) not in T diff U +\end{verbatim} + +\vspace*{-8pt} + +\subsection{Expresiones numéricas} + +El valor resultante de una expresión lógica primaria, cuando es una expresión numérica, es {\it verdadero} si el valor resultante de la expresión numérica es distinto de cero. De otro modo, el valor resultante de la expresión lógica es {\it falso}. + +\vspace*{-8pt} + +\subsection{Operadores relacionales} + +En MathProg existen los siguientes operadores relacionales, los que se pueden usar en expresiones lógicas: + +\begin{tabular}{@{}ll@{}} +$x$ {\tt<} $y$&comprueba si $x=} $y$&comprueba si $x\geq y$\\ +$x$ {\tt>} $y$&comprueba si $x>y$\\ +$x$ {\tt<>} $y$, $x$ {\tt!=} $y$&comprueba si $x\neq y$\\ +$x$ {\tt in} $Y$&comprueba si $x\in Y$\\ +{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt in} $Y$&comprueba si +$(x_1,\dots,x_n)\in Y$\\ +$x$ {\tt not} {\tt in} $Y$, $x$ {\tt!in} $Y$&comprueba si $x\not\in Y$\\ +{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt not} {\tt in} $Y$, +{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt !in} $Y$&comprueba si +$(x_1,\dots,x_n)\not\in Y$\\ +$X$ {\tt within} $Y$&comprueba si $X\subseteq Y$\\ +$X$ {\tt not} {\tt within} $Y$, $X$ {\tt !within} $Y$&comprueba si +$X\not\subseteq Y$\\ +\end{tabular} + +\noindent donde $x$, $x_1$, \dots, $x_n$ e $y$ son expresiones numéricas o simbólicas, mientras que $X$ e $Y$ son expresiones de conjunto. + +Notas: + +1. En las operaciones {\tt in}, {\tt not in} y {\tt !in} el número de componentes del primer operando debe ser igual a la dimensión del segundo operando. + +2. En las operaciones {\tt within}, {\tt not within} y {\tt !within} ambos operandos deben tener la misma dimensión. + +Todos los operadores relacionales listados anteriormente tienen su significado matemático convencional. El valor resultante es {\it verdadero} si los operandos satisfacen la correspondiente relación, o es {\it falso} en caso contrario. (Debe notarse que los valores simbólicos se ordenan lexicográficamente y que cualquier valor numérico precede a cualquier valor simbólico.) + +\subsection{Expresiones iteradas} + +Una {\it expresión lógica iterada} es una expresión lógica primaria que tiene la siguiente forma sintáctica: +$$\mbox{{\it operador-iterado} {\it expresión-indizante} +{\it integrando}}$$ +donde {\it operador-iterado} es el nombre simbólico del operador iterado que se ejecutará (ver más adelante), {\it expresión-indizante} es una expresión indizante que introduce índices y controla la iteración e {\it integrando} es una expresión lógica que participa en la operación. + +En MathProg existen dos operadores iterados que se pueden usar en expresiones lógicas: + +{\def\arraystretch{1.4} +\noindent\hfil +\begin{tabular}{@{}lll@{}} +{\tt forall}&cuantificador-$\forall$&$\displaystyle +\forall(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\ +{\tt exists}&cuantificador-$\exists$&$\displaystyle +\exists(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\ +\end{tabular} +} + +\noindent donde $i_1$, \dots, $i_n$ son índices introducidos en la expresión indizante, $\Delta$ es el dominio, un conjunto de $n$-tuplos especificados por la expresión indizante que define los valores particulares asignados a los índices para ejecutar la operación iterada y $f(i_1,\dots,i_n)$ es el integrando, una expresión lógica cuyo valor resultante depende de los índices. + +Para el cuantificador-$\forall$, el valor resultante de la expresión lógica iterada es {\it verdadero} si el valor del integrando es {\it verdadero} para todos los $n$-tuplos contenidos en el dominio, de otro modo es {\it falso}. + +Para el cuantificador-$\exists$, el valor resultante de la expresión lógica iterada es {\it falso} si el valor del integrando es {\it falso} para todos los $n$-tuplos contenidos en el dominio, de otro modo es {\it verdadero}. + +\subsection{Expresiones parentéticas} + +Cualquier expresión lógica puede encerrarse entre paréntesis, lo que la convierte sintácticamente en una expresión lógica primaria. + +Los paréntesis pueden usarse en expresiones lógicas, como en el álgebra, para especificar el orden deseado en el cual se ejecutarán las operaciones. Cuando se usan paréntesis, la expresión entre paréntesis se evalúa antes que el valor resultante sea usado. + +El valor resultante de la expresión parentética es idéntico al valor de la expresión encerrada entre paréntesis. + +\subsection{Operadores lógicos} + +En MathProg existen los siguientes operadores lógicos, los que se pueden usar en expresiones lógicas: + +\begin{tabular}{@{}ll@{}} +{\tt not} $x$, {\tt!}$x$&negación $\neg\ x$\\ +$x$ {\tt and} $y$, $x$ {\tt\&\&} $y$&conjunción (``y'' lógico) +$x\;\&\;y$\\ +$x$ {\tt or} $y$, $x$ {\tt||} $y$&disyunción (``o'' lógico) +$x\vee y$\\ +\end{tabular} + +\noindent donde $x$ e $y$ son expresiones lógicas. + +Si la expresión incluye más de un operador lógico, todos los operadores se ejecutan de izquierda a derecha, de acuerdo con la jerarquía de las operaciones (ver más adelante). El valor resultante de la expresión que contiene operadores lógicos es el resultado de aplicar los operadores a sus operandos. + +\subsection{Jerarquía de las operaciones} + +La siguiente lista muestra la jerarquía de las operaciones en expresiones lógicas: + +\noindent\hfil +\begin{tabular}{@{}ll@{}} +Operación&Jerarquía\\ +\hline +Evaluación de operaciones numéricas& +1.{\textsuperscript{\b{a}}}-7.{\textsuperscript{\b{a}}}\\ +Evaluación de operaciones simbólicas& +8.{\textsuperscript{\b{a}}}-9.{\textsuperscript{\b{a}}}\\ +Evaluación de operaciones de conjuntos& +10.{\textsuperscript{\b{a}}}-14.{\textsuperscript{\b{a}}}\\ +Operaciones relacionales ({\tt<}, {\tt<=}, etc.)& +15.{\textsuperscript{\b{a}}}\\ +Negación ({\tt not}, {\tt!})& +16.{\textsuperscript{\b{a}}}\\ +Conjunción ({\tt and}, {\tt\&\&})& +17.{\textsuperscript{\b{a}}}\\ +Cuantificación-$\forall$ y -$\exists$ ({\tt forall}, {\tt exists})& +18.{\textsuperscript{\b{a}}}\\ +Disyunción ({\tt or}, {\tt||})& +19.{\textsuperscript{\b{a}}}\\ +\end{tabular} + +Esta jerarquía tiene el mismo significado que se explicó anteriormente para expresiones numéricas (ver Subsección \ref{hierarchy}, página \pageref{hierarchy}). + +\section{Expresiones lineales} + +Una {\it expresión lineal} es una regla para calcular la denominada {\it forma lineal}, que es una función lineal (o afín) de variables elementales. + +La expresión lineal primaria puede ser una variable no-indizada, una variable indizada, una expresión lineal iterada, una expresión lineal condicional u otra expresión lineal encerrada entre paréntesis. + +También está permitido usar una expresión numérica como una expresión lineal primaria, en cuyo caso el valor resultante de la expresión numérica se convierte automáticamente a una forma lineal que incluye el término constante solamente. + +\para{Ejemplos} + +\noindent +\begin{tabular}{@{}ll@{}} +\verb|z| &(variable no-indizada)\\ +\verb|x[i,j]| &(variable indizada)\\ +\verb|sum{j in J} (a[i,j] * x[i,j] + 3 * y[i-1])| & +(expresión lineal iterada)\\ +\verb|if i in I then x[i,j] else 1.5 * z + 3.25| & +(expresión lineal condicional)\\ +\verb|(a[i,j] * x[i,j] + y[i-1] + .1)| & +(expresión lineal parentética)\\ +\end{tabular} + +Empleando ciertos operadores aritméticos se pueden construir expresiones lineales más generales conteniendo dos o más expresiones lineales primarias. + +\para{Ejemplos} + +\begin{verbatim} +2 * x[i-1,j+1] + 3.5 * y[k] + .5 * z +(- x[i,j] + 3.5 * y[k]) / sum{t in T} abs(d[i,j,t]) +\end{verbatim} + +\vspace*{-5pt} + +\subsection{Variables no-indizadas} + +Si la expresión lineal primaria es una variable no-indizada (que debe ser 0-dimensional), la forma lineal resultante es aquella variable no-indizada. + +\vspace*{-5pt} + +\subsection{Variables indizadas} + +La expresión lineal primaria que se refiere a una variable indizada tiene la siguiente forma sintáctica: +$$\mbox{{\it nombre}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,} +$i_n${\tt]}}$$ +donde {\it nombre} es el nombre simbólico de la variable del modelo e $i_1$, +$i_2$, \dots, $i_n$ son subíndices. + +Cada subíndice debe ser una expresión numérica o simbólica. El número de subíndices en la lista de subíndices debe ser igual a la dimensión de la variable del modelo con la cual está asociada la lista de subíndices. + +Los valores corrientes de las expresiones de los subíndices se usan para identificar un miembro particular de la variable del modelo que determina la forma lineal resultante, la cual es una variable elemental asociada con el miembro correspondiente. + +\vspace*{-5pt} + +\subsection{Expresiones iteradas} + +Una {\it expresión lineal iterada} es una expresión lineal primaria que tiene la siguiente forma sintáctica: +$$\mbox{{\tt sum} {\it expresión-indizante} {\it integrando}}$$ +donde {\it expresión-indizante} es una expresión indizante que introduce índices y controla la iteración e {\it integrando} es una expresión lineal que participa en la operación. + +La expresión lineal iterada se evalúa exactamente de la misma manera que la expresión numérica iterada (ver Subsección \ref{itexpr}, página +\pageref{itexpr}), excepto que el integrando participante en la sumatoria es una forma lineal y no un valor numérico. + +\vspace*{-5pt} + +\subsection{Expresiones condicionales} + +Una {\it expresión lineal condicional} es una expresión lineal primaria que tiene alguna de las dos formas sintácticas siguientes: +$$ +{\def\arraystretch{1.4} +\begin{array}{l} +\mbox{{\tt if} $b$ {\tt then} $f$ {\tt else} $g$}\\ +\mbox{{\tt if} $b$ {\tt then} $f$}\\ +\end{array} +} +$$ +donde $b$ es una expresión lógica, mientras que $f$ y $g$ son expresiones lineales. + +La expresión lineal condicional se evalúa exactamente de la misma manera que la expresión numérica condicional (ver Subsección \ref{ifthen}, página \pageref{ifthen}), excepto que los operandos participantes en la operación son formas lineales y no valores numéricos. + +\subsection{Expresiones parentéticas} + +Cualquier expresión lineal puede encerrarse entre paréntesis, lo que la convierte sintácticamente en una expresión lineal primaria. + +Los paréntesis pueden usarse en expresiones lineales, como en el álgebra, para especificar el orden deseado en el cual se ejecutarán las operaciones. Cuando se usan paréntesis, la expresión entre paréntesis se evalúa antes que el valor resultante sea usado. + +El valor resultante de la expresión parentética es idéntico al valor de la expresión encerrada entre paréntesis. + +\subsection{Operadores aritméticos} + +En MathProg existen los siguientes operadores aritméticos, los que se pueden usar en expresiones lineales: + +\begin{tabular}{@{}ll@{}} +{\tt+} $f$&más unario\\ +{\tt-} $f$&menos unario\\ +$f$ {\tt+} $g$&adición\\ +$f$ {\tt-} $g$&sustracción\\ +$x$ {\tt*} $f$, $f$ {\tt*} $x$&multiplicación\\ +$f$ {\tt/} $x$&división +\end{tabular} + +\noindent donde $f$ y $g$ son expresiones lineales, mientras que $x$ es una expresión numérica (más precisamente, una expresión lineal conteniendo únicamente el término constante). + +Si la expresión incluye más de un operador aritmético, todos los operadores se ejecutan de izquierda a derecha, de acuerdo con la jerarquía de las operaciones (ver más adelante). El valor resultante de la expresión que contiene operadores aritméticos es el resultado de aplicar los operadores a sus operandos. + +\subsection{Jerarquía de las operaciones} + +La jerarquía de las operaciones aritméticas usadas en las expresiones lineales es la misma que en las expresiones numéricas (ver Subsección \ref{hierarchy}, +página \pageref{hierarchy}). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Sentencias} + +Las {\it sentencias} son unidades básicas de la descripción del modelo. En MathProg todas las sentencias se clasifican en dos categorías: sentencias declarativas y sentencias funcionales. + +Las {\it sentencias declarativas} (sentencia {\it set}, sentencia {\it parameter}, sentencia {\it variable}, sentencia {\it constraint} y sentencia {\it objective}) se usan para declarar objetos de cierto tipo del modelo y definir ciertas propiedades de tales objetos. + +Las {\it sentencias funcionales} (sentencia {\it solve}, sentencia {\it check}, sentencia {\it display}, sentencia {\it printf}, sentencia {\it loop} y sentencia {\it table}) están ideadas para ejecutar ciertas acciones específicas. + +Debe notarse que las sentencias declarativas pueden seguir cualquier orden arbitrario, lo cual no afecta el resultado de la traducción. Sin embargo, todos los objetos del modelo deben ser declarados antes de ser referenciados en otras sentencias. + +\section{Sentencia set} + +\noindent +\framebox[468pt][l]{ +\parbox[c][24pt]{468pt}{ +\hspace{6pt} {\tt set} {\it nombre} {\it alias} {\it dominio} {\tt,} +{\it atributo} {\tt,} \dots {\tt,} {\it atributo} {\tt;} +}} + +\medskip + +\noindent +{\it nombre} es el nombre simbólico del conjunto; + +\noindent +{\it alias} es un literal de cadena opcional que especifica un alias para el conjunto; + +\noindent +{\it dominio} es una expresión-indizante opcional que especifica el dominio del subíndice del conjunto; + +\noindent +{\it atributo}, \dots, {\it atributo} son atributos opcionales del conjunto (las comas que preceden a los atributos se pueden omitir). + +\para{Atributos opcionales} + +\vspace*{-8pt} + +\begin{description} +\item[{\tt dimen} $n$]\hspace*{0pt}\\ +especifica la dimensión de los $n$-tuplos de los que consiste el conjunto; +\item[{\tt within} {\it expresión}]\hspace*{0pt}\\ +especifica un superconjunto que restringe al conjunto o a todos sus miembros (conjuntos elementales) a estar incluido en aquel superconjunto; +\item[{\tt:=} {\it expresión}]\hspace*{0pt}\\ +especifica un conjunto elemental asignado al conjunto o sus miembros; +\item[{\tt default} {\it expresión}]\hspace*{0pt}\\ +especifica un conjunto elemental asignado al conjunto o sus miembros cuando no haya datos apropiados disponibles en la sección de datos. +\end{description} + +\vspace*{-8pt} + +\para{Ejemplos} + +\begin{verbatim} +set nodos; +set arcos within nodos cross nodos; +set paso{p in 1..maxiter} dimen 2 := if p = 1 then arcos else paso[p-1] + union setof{k in nodos, (i,k) in paso[p-1], (k,j) in paso[p-1]}(i,j); +set A{i in I, j in J}, within B[i+1] cross C[j-1], within D diff E, + default {('abc',123), (321,'cba')}; +\end{verbatim} + +La sentencia set declara un conjunto. Si no se especifica el dominio del subíndice, el conjunto será simple, de otro modo será un arreglo de conjuntos elementales. + +El atributo {\tt dimen} especifica la dimensión de los $n$-tuplos de los que consiste el conjunto (si es un conjunto simple) o sus miembros (si el conjunto es un arreglo de conjuntos elementales), en la que $n$ debe ser un entero sin signo desde 1 hasta 20. Como mucho se puede especificar un atributo {\tt dimen}. Si no se especifica el atributo {\tt dimen}, la dimensión de los $n$-tuplos se determina implícitamente por otros atributos (por ejemplo, si hay una expresión de conjunto que sigue a {\tt :=} o a la palabra clave {\tt default}, se usará la dimensión de los $n$-tuplos del correspondiente conjunto elemental). Si no hay información disponible sobre la dimensión, se asume {\tt dimen 1}. + +El atributo {\tt within} especifica una expresión de conjunto cuyo valor resultante es un superconjunto usado para restringir al conjunto (si es un conjunto simple) o a sus miembros (si el conjunto es un arreglo de conjuntos elementales) a estar incluido en aquel superconjunto. Se puede especificar un número arbitrario de atributos {\tt within} en la misma sentencia set. + +El atributo de asignación ({\tt :=}) especifica una expresión de conjunto usada para evaluar conjuntos elementales asignados al conjunto (si es un conjunto simple) o sus miembros (si el conjunto es un arreglo de conjuntos elementales). Si se especifica el atributo de asignación, el conjunto es {\it calculable} y consecuentemente no es necesario proveerle datos en la sección de datos. Si no se especifica el atributo de asignación, entonces se deben proveer datos para el conjunto en la sección de datos. Como mucho, se puede especificar una asignación o un atributo {\tt default} para el mismo conjunto. + +El atributo {\tt default} especifica una expresión de conjunto usada para evaluar conjuntos elementales asignados al conjunto (si es un conjunto simple) o sus miembros (si el conjunto es un arreglo de conjuntos elementales) toda vez que no haya datos apropiados disponibles en la sección de datos. Si no se especifica una asignación o un atributo {\tt default}, la carencia de datos causará un error. + +\newpage + +\section{Sentencia parameter} + +\noindent +\framebox[468pt][l]{ +\parbox[c][24pt]{468pt}{ +\hspace{6pt} {\tt param} {\it nombre} {\it alias} {\it dominio} {\tt,} +{\it atributo} {\tt,} \dots {\tt,} {\it atributo} {\tt;} +}} + +\medskip + +\noindent +{\it nombre} es el nombre simbólico del parámetro; + +\noindent +{\it alias} es un literal de cadena opcional que especifica un alias para el parámetro; + +\noindent +{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice del parámetro; + +\noindent +{\it atributo}, \dots, {\it atributo} son atributos opcionales del parámetro (las comas que preceden a los atributos se pueden omitir). + +\para{Atributos opcionales} + +\vspace*{-8pt} + +\begin{description} +\item[{\tt integer}]\hspace*{0pt}\\ +especifica que el parámetro es entero; +\item[{\tt binary}]\hspace*{0pt}\\ +especifica que el parámetro es binario; +\item[{\tt symbolic}]\hspace*{0pt}\\ +especifica que el parámetro es simbólico; +\item[{\it relación expresión}]\hspace*{0pt}\\ +(donde {\it relación} es alguno de: {\tt<}, {\tt<=}, {\tt=}, {\tt==}, +{\tt>=}, {\tt>}, {\tt<>}, {\tt!=})\\ +especifica una condición que restringe al parámetro o a sus miembros a satisfacer aquella condición; +\item[{\tt in} {\it expresión}]\hspace*{0pt}\\ +especifica un superconjunto que restringe al parámetro o a sus miembros a estar incluidos en aquel superconjunto; +\item[{\tt:=} {\it expresión}]\hspace*{0pt}\\ +especifica un valor asignado al parámetro o a sus miembros; +\item[{\tt default} {\it expresión}]\hspace*{0pt}\\ +especifica un valor asignado al parámetro o a sus miembros cuando no haya datos apropiados disponibles en la sección de datos. +\end{description} + +\vspace*{-8pt} + +\para{Ejemplos} + +\begin{verbatim} +param unidades{insumo,producto} >= 0; +param ganancia{producto, 1..T+1}; +param N := 20 integer >= 0 <= 100; +param combinacion 'n elige k' {n in 0..N, k in 0..n} := + if k = 0 or k = n then 1 else combinacion[n-1,k-1] + combinacion[n-1,k]; +param p{i in I, j in J}, integer, >= 0, <= i+j, in A[i] symdiff B[j], + in C[i,j], default 0.5 * (i + j); +param mes symbolic default 'May' in {'Mar', 'Abr', 'May'}; +\end{verbatim} + +La sentencia parameter declara un parámetro. Si el dominio del subíndice no se especifica, el parámetro es un parámetro simple (escalar); de otro modo es un arreglo $n$-dimensional. + +Los atributos de tipo {\tt integer}, {\tt binary} y {\tt symbolic} califican el tipo de valores que se le puede asignar al parámetro como se muestra a continuación: + +\noindent\hfil +\begin{tabular}{@{}ll@{}} +Atributo de tipo&Valores asignado\\ +\hline +(no especificado)&Cualquier valor numérico\\ +{\tt integer}&Solamente valores numéricos enteros\\ +{\tt binary}&Tanto 0 como 1\\ +{\tt symbolic}&Cualquier valor numérico y simbólico\\ +\end{tabular} + +El atributo {\tt symbolic} no se puede especificar junto con otros atributos de tipo. Cuando se especifica debe preceder a todos los demás atributos. + +El atributo de condición especifica una condición opcional que restringe los valores asignados al parámetro a satisfacer esta condición. Este atributo tiene las siguientes formas sintácticas: + +\begin{tabular}{@{}ll@{}} +{\tt<} $v$&comprueba si $x=} $v$&comprueba si $x\geq v$\\ +{\tt>} $v$&comprueba si $x\geq v$\\ +{\tt<>} $v$, {\tt!=} $v$&comprueba si $x\neq v$\\ +\end{tabular} + +\noindent donde $x$ es un valor asignado al parámetro y $v$ es el valor resultante de una expresión numérica o simbólica especificada en el atributo de condición. Se puede especificar un número arbitrario de atributos de condición para el mismo parámetro. Si el valor que se está asignando al parámetro durante la evaluación del modelo viola al menos una de las condiciones especificadas, se producirá un error. (Debe notarse que los valores simbólicos se ordenan lexicográficamente y que cualquier valor numérico precede a cualquier valor simbólico.) + +El atributo {\tt in} es semejante al atributo de condición y especifica una expresión de conjunto cuyo valor resultante es un superconjunto usado para restringir los valores numéricos o simbólicos asignados al parámetro a estar incluidos en aquel superconjunto. Se puede especificar un número arbitrario de atributos {\tt in} para el mismo parámetro. Si el valor que se está asignando al parámetro durante la evaluación del modelo no pertenece al menos a uno de los superconjuntos especificados, se producirá un error. + +El atributo de asignación ({\tt:=}) especifica una expresión numérica o simbólica usada para calcular un valor asignado al parámetro (si es un parámetro simple) o a sus miembros (si el parámetro es un arreglo). Si se especifica el atributo de asignación, el parámetro es {\it calculable} y consecuentemente no es necesario proveer datos en la sección de datos. Si no se especifica el atributo de asignación, entonces se deben proveer datos para el parámetro en la sección de datos. Como mucho, se puede especificar una asignación o un atributo {\tt default} para el mismo conjunto. + +El atributo {\tt default} especifica una expresión numérica o simbólica que se usa para calcular un valor asignado al parámetro o a sus miembros, toda vez que no haya datos apropiados disponibles en la sección de datos. Si no se especifica una asignación ni un atributo {\tt default}, la carencia de datos causará un error. + +\section{Sentencia variable} + +\noindent +\framebox[468pt][l]{ +\parbox[c][24pt]{468pt}{ +\hspace{6pt} {\tt var} {\it nombre} {\it alias} {\it dominio} {\tt,} +{\it atributo} {\tt,} \dots {\tt,} {\it atributo} {\tt;} +}} + +\medskip + +\noindent +{\it nombre} es el nombre simbólico de la variable; + +\noindent +{\it alias} es un literal de cadena opcional que especifica un alias para la variable; + +\noindent +{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la variable; + +\noindent +{\it atributo}, \dots, {\it atributo} son atributos opcionales de la variable (las comas que preceden a los atributos se pueden omitir). + +\para{Atributos opcionales} + +\vspace*{-8pt} + +\begin{description} +\item[{\tt integer}]\hspace*{0pt}\\ +restringe la variable a ser entera; +\item[{\tt binary}]\hspace*{0pt}\\ +restringe la variable a ser binaria; +\item[{\tt>=} {\it expresión}]\hspace*{0pt}\\ +especifica una cota inferior para la variable; +\item[{\tt<=} {\it expresión}]\hspace*{0pt}\\ +especifica una cota superior para la variable; +\item[{\tt=} {\it expresión}]\hspace*{0pt}\\ +especifica un valor fijo para la variable. +\end{description} + +\vspace*{-8pt} + +\para{Ejemplos} + +\begin{verbatim} +var x >= 0; +var y{I,J}; +var elaborar{p in producto}, integer, >= compromiso[p], <= mercado[p]; +var almacenar{insumo, 1..T+1} >= 0; +var z{i in I, j in J} >= i+j; +\end{verbatim} + +La sentencia variable declara una variable. Si no se especifica el dominio del subíndice, la variable es una variable simple (escalar); de otro modo es un arreglo $n$-dimensional de variables elementales. + +Las variables elementales asociadas con una variable del modelo (si es una variable simple) o sus miembros (si es un arreglo) corresponde a las variables en la formulación del problema de PL/PEM (ver Sección \ref{problem}, página \pageref{problem}). Debe notarse que sólo variables elementales realmente referenciadas en algunas restricciones y/u objetivos se incluirán en la instancia del problema de PL/PEM que se generará. + +Los atributos de tipo {\tt integer} y {\tt binary} restringen la variable a ser entera o binaria, respectivamente. Si no se especifica un atributo de tipo, la variable será continua. Si todas las variables en el modelo son continuas, el problema correspondiente será de la clase PL. Si hay al menos una variable entera o binaria, el problema será de la clase PEM. + +El atributo de cota inferior ({\tt>=}) especifica una expresión numérica para calcular la cota inferior de la variable. Se puede especificar una cota inferior como máximo. Por defecto, todas las variables no tienen cota inferior (excepto las binarias), de modo que si se requiere que sea no-negativa, su cota inferior cero debe especificarse explícitamente. + +El atributo de cota superior ({\tt<=}) especifica una expresión numérica para calcular la cota superior de la variable. Se puede especificar una cota superior como máximo. + +El atributo de valor fijo ({\tt=}) especifica una expresión numérica para calcular el valor en el cual se fijará la variable. Este atributo no puede especificarse junto con los atributos de cota. + +\section{Sentencia constraint} + +\noindent +\framebox[468pt][l]{ +\parbox[c][106pt]{468pt}{ +\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:} +{\it expresión} {\tt,} {\tt=} {\it expresión} {\tt;} + +\medskip + +\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:} +{\it expresión} {\tt,} {\tt<=} {\it expresión} {\tt;} + +\medskip + +\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:} +{\it expresión} {\tt,} {\tt>=} {\it expresión} {\tt;} + +\medskip + +\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:} +{\it expresión} {\tt,} {\tt<=} {\it expresión} {\tt,} {\tt<=} +{\it expresión} {\tt;} + +\medskip + +\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:} +{\it expresión} {\tt,} {\tt>=} {\it expresión} {\tt,} {\tt>=} +{\it expresión} {\tt;} +}} + +\medskip + +\noindent +{\it nombre} es el nombre simbólico de la restricción; + +\noindent +{\it alias} es un literal de cadena opcional que especifica un alias para la restricción; + +\noindent +{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la restricción; + +\noindent +{\it expresión} es una expresión lineal usada para calcular un componente de la restricción (las comas que siguen a las expresiones pueden omitirse). + +\noindent +(La palabra clave {\tt s.t.} se puede escribir como {\tt subject to}, o como {\tt subj to} o ser completamente omitida.) + +\para{Ejemplos} + +\begin{verbatim} +s.t. r: x + y + z, >= 0, <= 1; +limite{t in 1..T}: sum{j in producto} elaborar[j,t] <= max_producto; +subject to balance{i in insumo, t in 1..T}: + almacenar[i,t+1] - almacenar[i,t] - + sum{j in producto} unidades[i,j] * elaborar[j,t]; +subject to ltn 'limite tiempo normal' {t in tiempo}: + sum{p in producto} pt[p] * rprd[p,t] <= 1.3 * dpp[t] * brigadas[t]; +\end{verbatim} + +La sentencia constraint declara una restricción. Si no se especifica el dominio del subíndice, la restricción es una restricción simple (escalar); de otro modo, es un arreglo $n$-dimensional de restricciones elementales. + +Las restricciones elementales asociadas con la restricción del modelo (si es una restricción simple) o sus miembros (si es un arreglo) corresponde a las restricciones lineales en la formulación del problema de PL/PEM (ver Sección \ref{problem}, página \pageref{problem}). + +Si la restricción tiene la forma de una igualdad o desigualdad simple, {\it i.e.} incluye dos expresiones, una de las cuales está a continuación de los dos puntos y la otra está a continuación del signo relacional {\tt=}, {\tt<=} o {\tt>=}, ambas expresiones de la sentencia pueden ser expresiones lineales. Si la restricción tiene la forma de una doble desigualdad, {\it i.e.} incluye tres expresiones, la expresión del medio puede ser una expresión lineal mientras que la de la izquierda y la de la derecha sólo pueden ser expresiones numéricas. + +Generar el modelo es, groseramente hablando, generar sus restricciones, las que son siempre evaluadas para todo el dominio del subíndice. A su vez, la evaluación de las restricciones lleva a la evaluación de otros objetos del modelo tales como los conjuntos, los parámetros y las variables. + +La construcción de una restricción lineal real incluida en la instancia del problema, la cual corresponde a una restricción elemental particular, se realiza como sigue. + +Si la restricción tiene la forma de una igualdad o desigualdad simple, la evaluación de ambas expresiones lineales resulta en dos formas lineales: +$$\begin{array}{r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r} +f&=&a_1x_1&+&a_2x_2&+\dots+&a_nx_n&+&a_0,\\ +g&=&b_1x_1&+&b_2x_2&+\dots+&b_nx_n&+&b_0,\\ +\end{array}$$ +donde $x_1$, $x_2$, \dots, $x_n$ son variables elementales; $a_1$, $a_2$, +\dots, $a_n$, $b_1$, $b_2$, \dots, $b_n$ son coeficientes numéricos y +$a_0$ y $b_0$ son términos constantes. Luego, todos los términos lineales de $f$ y $g$ se llevan al lado izquierdo y los términos constantes se llevan al lado derecho, para dar la restricción elemental final en forma estándar: +$$(a_1-b_1)x_1+(a_2-b_2)x_2+\dots+(a_n-b_n)x_n\left\{ +\begin{array}{@{}c@{}}=\\\leq\\\geq\\\end{array}\right\}b_0-a_0.$$ + +Si la restricción tiene la forma de una doble desigualdad, la evaluación de la expresión lineal del medio resulta en una forma lineal: +$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$ +y la evaluación de las expresiones numéricas de la izquierda y de la derecha dará dos valores numéricos $l$ y $u$, respectivamente. Luego, el término constante de la forma lineal se lleva tanto a la izquierda como a la derecha para dar la restricción elemental final en forma estándar: +$$l-a_0\leq a_1x_1+a_2x_2+\dots+a_nx_n\leq u-a_0.$$ + +\section{Sentencia objective} + +\noindent +\framebox[468pt][l]{ +\parbox[c][44pt]{468pt}{ +\hspace{6pt} {\tt minimize} {\it nombre} {\it alias} {\it dominio} {\tt:} +{\it expresión} {\tt;} + +\medskip + +\hspace{6pt} {\tt maximize} {\it nombre} {\it alias} {\it dominio} {\tt:} +{\it expresión} {\tt;} +}} + +\medskip + +\noindent +{\it nombre} es el nombre simbólico del objetivo; + +\noindent +{\it alias} es un literal de cadena opcional que especifica un alias para el objetivo; + +\noindent +{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice del objetivo; + +\noindent +{\it expresión} es una expresión lineal usada para calcular la forma lineal del objetivo. + +\para{Ejemplos} + +\begin{verbatim} +minimize objetivo: x + 1.5 * (y + z); +maximize ganancia_total: sum{p in producto} ganancia[p] * elaborar[p]; +\end{verbatim} + +La sentencia objective declara un objetivo. Si no se especifica el dominio del subíndice, el objetivo es un objetivo simple (escalar); de otro modo, es un arreglo $n$-dimensional de objetivos elementales. + +Los objetivos elementales asociados con el objetivo del modelo (si es un objetivo simple) o sus miembros (si es un arreglo) corresponden a restricciones lineales generales en la formulación del problema de PL/PEM (ver Sección \ref{problem}, página \pageref{problem}). Sin embargo, a diferencia de las restricciones, las correspondientes formas lineales son libres (no tienen cota). + +La construcción de una restricción lineal real incluida en la instancia del problema, la cual corresponde a una restricción elemental particular, se realiza como sigue. La expresión lineal especificada en la sentencia objective se evalúa para resultar en una forma lineal: +$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$ +donde $x_1$, $x_2$, \dots, $x_n$ son variables elementales; $a_1$, $a_2$, +\dots, $a_n$ son coeficientes numéricos y $a_0$ es el término constante. Luego se usa la forma lineal para construir la restricción elemental final en forma estándar: +$$-\infty= 0 and y >= 0; +check sum{i in ORIGEN} oferta[i] = sum{j in DESTINO} demanda[j]; +check{i in I, j in 1..10}: S[i,j] in U[i] union V[j]; +\end{verbatim} + +El sentencia check permite comprobar el valor resultante de una expresión lógica especificada en la sentencia. Si el valor es {\it falso} se reporta un error. + +Si el dominio del subíndice no se especifica, la comprobación se ejecuta solamente una vez. Especificar el dominio del subíndice permite ejecutar múltiples comprobaciones para cada $n$-tuplo en el conjunto dominio. En este último caso, la expresión lógica puede incluir índices introducidos en la correspondiente expresión indizante. + +\section{Sentencia display} + +\noindent +\framebox[468pt][l]{ +\parbox[c][24pt]{468pt}{ +\hspace{6pt} {\tt display} {\it dominio} {\tt:} {\it ítem} {\tt,} +\dots {\tt,} {\it ítem} {\tt;} +}} + +\medskip + +\noindent +{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la sentencia display; + +\noindent +{\it ítem}, \dots, {\it ítem} son ítems que se mostrarán (los dos puntos que preceden al primer ítem pueden omitirse). + +\para{Ejemplos} + +\begin{verbatim} +display: 'x =', x, 'y =', y, 'z =', z; +display sqrt(x ** 2 + y ** 2 + z ** 2); +display{i in I, j in J}: i, j, a[i,j], b[i,j]; +\end{verbatim} + +La sentencia display evalúa todos los ítems especificados en la sentencia y escribe sus valores en la salida estándar (terminal) en formato de texto plano. + +Si el dominio del subíndice no se especifica, los ítems son evaluados y mostrados solamente una vez. Especificar el dominio del subíndice produce que los ítems sean evaluados y mostrados para cada $n$-tuplo en el conjunto dominio. En este último caso, los ítems pueden incluir índices introducidos en la correspondiente expresión indizante. + +Un ítem a ser mostrado puede ser un objeto del modelo (conjunto, parámetro, variable, restricción u objetivo) o una expresión. + +Si el ítem es un objeto calculable ({\it i.e.} un conjunto o parámetro provisto con el atributo de asignación), el mismo es evaluado a través de todo su dominio y luego se muestra su contenido ({\it i.e.} el contenido del arreglo de objetos). De otro modo, si el ítem no es un objeto calculable, solamente se muestra su contenido corriente ({\it i.e.} los miembros realmente generados durante la evaluación del modelo). + +Si el ítem es una expresión, la misma se evalúa y se muestra su valor resultante. + +\section{Sentencia printf} + +\noindent +\framebox[468pt][l]{ +\parbox[c][64pt]{468pt}{ +\hspace{6pt} {\tt printf} {\it dominio} {\tt:} {\it formato} {\tt,} +{\it expresión} {\tt,} \dots {\tt,} {\it expresión} {\tt;} + +\medskip + +\hspace{6pt} {\tt printf} {\it dominio} {\tt:} {\it formato} {\tt,} +{\it expresión} {\tt,} \dots {\tt,} {\it expresión} {\tt>} +{\it archivo} {\tt;} + +\medskip + +\hspace{6pt} {\tt printf} {\it dominio} {\tt:} {\it formato} {\tt,} +{\it expresión} {\tt,} \dots {\tt,} {\it expresión} {\tt>}{\tt>} +{\it archivo} {\tt;} +}} + +\medskip + +\noindent +{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la sentencia printf; + +\noindent +{\it formato} es una expresión simbólica cuyo valor especifica una cadena de control de formato (los dos puntos que preceden a la expresión de formato pueden omitirse). + +\noindent +{\it expresión}, \dots, {\it expresión} son cero o más expresiones cuyos valores deben ser formateados e impresos. Cada expresión debe ser de tipo numérico, simbólico o lógico. + +\noindent +{\it archivo} es una expresión simbólica cuyo valor especifica el nombre de un archivo de texto al cual se redirigirá la salida. La señal {\tt>} significa la creación de un archivo nuevo y vacío, mientras que la señal {\tt>}{\tt>} significa anexar la salida a un archivo existente. Si no se especifica un nombre de archivo, la salida se escribe en la salida estándar (terminal). + +\para{Ejemplos} + +\begin{verbatim} +printf 'Hola, mundo!\n'; +printf: "x = %.3f; y = %.3f; z = %.3f\n", x, y, z > "resultado.txt"; +printf{i in I, j in J}: "el flujo desde %s hacia %s es %d\n", i, j, x[i,j] + >> archivo_resultados & ".txt"; +printf{i in I} 'el flujo total de %s es %g\n', i, sum{j in J} x[i,j]; +printf{k in K} "x[%s] = " & (if x[k] < 0 then "?" else "%g"), + k, x[k]; +\end{verbatim} + +La sentencia printf es semejante a la sentencia display; sin embargo, la misma permite formatear los datos que se escribirán. + +Si el dominio del subíndice no se especifica, la sentencia printf es ejecutada solamente una vez. Especificar el dominio del subíndice produce que la sentencia printf sea ejecutada para cada $n$-tuplo en el conjunto dominio. En este último caso, el formato y la expresión pueden incluir índices introducidos en la correspondiente expresión indizante. + +La cadena de control de formato es el valor de la expresión simbólica {\it formato} especificado en la sentencia printf. Se compone con cero o más directivas como sigue: caracteres ordinarios (no {\tt\%}), que son copiados sin modificación al flujo de salida, y especificaciones de conversión, cada una de las cuales provoca la evaluación de la expresión correspondiente especificada en la sentencia printf, su formateo y la escritura del valor resultante en el flujo de salida. + +Las especificaciones de conversión que se pueden usar en la cadena de control de formato son las siguientes: {\tt d}, {\tt i}, {\tt f}, {\tt F}, {\tt e}, {\tt E}, {\tt g}, {\tt G} y {\tt s}. Estas especificaciones tienen la misma semántica y sintaxis que en el lenguaje de programación C. + +\section{Sentencia for} + +\noindent +\framebox[468pt][l]{ +\parbox[c][44pt]{468pt}{ +\hspace{6pt} {\tt for} {\it dominio} {\tt:} {\it sentencia} {\tt;} + +\medskip + +\hspace{6pt} {\tt for} {\it dominio} {\tt:} {\tt\{} {\it sentencia} +\dots {\it sentencia} {\tt\}} {\tt;} +}} + +\medskip + +\noindent +{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la sentencia for (los dos puntos a continuación de la expresión indizante pueden omitirse); + +\noindent +{\it sentencia} es una sentencia que será ejecutada bajo el control de la sentencia for; + +\noindent +{\it sentencia}, \dots, {\it sentencia} es una secuencia de sentencias (encerrada entre llaves) que serán ejecutadas bajo el control de la sentencia for. + +Solamente se pueden usar las siguientes sentencias dentro de la sentencia for: check, display, printf y otra sentencia for. + +\para{Ejemplos} + +\begin{verbatim} +for {(i,j) in E: i != j} +{ printf "el flujo desde %s hacia %s es %g\n", i, j, x[i,j]; + check x[i,j] >= 0; +} +for {i in 1..n} +{ for {j in 1..n} printf " %s", if x[i,j] then "Q" else "."; + printf("\n"); +} +for {1..72} printf("*"); +\end{verbatim} + +La sentencia for provoca que la sentencia o secuencia de sentencias especificadas como parte de la sentencia for sea ejecutada para cada $n$-tuplo en el conjunto dominio. De modo que las sentencias dentro de la sentencia for pueden incluir índices introducidos en la correspondiente expresión indizante. + +\section{Sentencia table} + +\noindent +\framebox[468pt][l]{ +\parbox[c][80pt]{468pt}{ +\hspace{6pt} {\tt table} {\it nombre} {\it alias} {\tt IN} {\it controlador} +{\it arg} \dots {\it arg} {\tt:} + +\hspace{6pt} {\tt\ \ \ \ \ } {\it conjunto} {\tt<-} {\tt[} {\it cmp} {\tt,} +\dots {\tt,} {\it cmp} {\tt]} {\tt,} {\it par} {\tt\textasciitilde} +{\it cmp} {\tt,} \dots {\tt,} {\it par} {\tt\textasciitilde} {\it cmp} +{\tt;} + +\medskip + +\hspace{6pt} {\tt table} {\it nombre} {\it alias} {\it dominio} {\tt OUT} +{\it controlador} {\it arg} \dots {\it arg} {\tt:} + +\hspace{6pt} {\tt\ \ \ \ \ } {\it expr} {\tt\textasciitilde} {\it cmp} +{\tt,} \dots {\tt,} {\it expr} {\tt\textasciitilde} {\it cmp} {\tt;} +}} + +\medskip + +\noindent +{\it nombre} es el nombre simbólico de la tabla; + +\noindent +{\it alias} es un literal de cadena opcional que especifica un alias para la tabla; + +\noindent +{\it dominio} es una expresión indizante que especifica el dominio del subíndice de la tabla (de salida); + +\noindent +{\tt IN} significa leer datos desde la tabla de entrada; + +\noindent +{\tt OUT} significa escribir datos en la tabla de salida; + +\noindent +{\it controlador} es una expresión simbólica que especifica el controlador usado para acceder a la tabla (para más detalles, ver Apéndice \ref{drivers}, página \pageref{drivers}); + +\noindent +{\it arg} es una expresión simbólica opcional que es un argumento pasado al controlador de la tabla. Esta expresión simbólica no debe incluir índices especificados en el dominio; + +\noindent +{\it conjunto} es el nombre de un conjunto simple opcional llamado {\it conjunto de control}. Puede ser omitido junto con el delimitador {\tt<-}; + +\noindent +{\it cmp} es un nombre de campo. Entre corchetes se debe especificar al menos un campo. El nombre de campo a continuación de un nombre de parámetro o de una expresión es opcional y puede ser omitido junto con el delimitador~{\tt\textasciitilde}, en cuyo caso el nombre del objeto del modelo que corresponda se usará como el nombre de campo; + +\noindent +{\it par} es el nombre simbólico de un parámetro del modelo; + +\noindent +{\it expr} es una expresión numérica o simbólica. + +\para{Ejemplos} + +\begin{verbatim} +table datos IN "CSV" "datos.csv": M <- [DESDE,HACIA], d~DISTANCIA, + c~COSTO; +table resultado{(s,h) in M} OUT "CSV" "resultado.csv": s~DESDE, h~HACIA, + x[s,h]~FLUJO; +\end{verbatim} + +La sentencia table permite leer datos desde una tabla y asignarlos a objetos del modelo tales como conjuntos y parámetros (no escalares), al igual que escribir datos del modelo en una tabla. + +\subsection{Estructura de tablas} + +Una {\it tabla de datos} es un conjunto (desordenado) de {\it registros}, en el que cada registro consiste del mismo número de {\it campos}, y cada campo está provisto de un nombre simbólico único denominado {\it nombre de campo}. Por ejemplo: + +\bigskip + +\begin{tabular}{@{\hspace*{51mm}}c@{\hspace*{9mm}}c@{\hspace*{10mm}}c +@{\hspace*{7mm}}c} +Primer&Segundo&&Último\\ +campo&campo&.\ \ .\ \ .&campo\\ +$\downarrow$&$\downarrow$&&$\downarrow$\\ +\end{tabular} + +\begin{tabular}{ll@{}} +Encabezado de tabla&$\rightarrow$\\ +Primer registro&$\rightarrow$\\ +Segundo registro&$\rightarrow$\\ +\\ +\hfil .\ \ .\ \ .\\ +\\ +Último registro&$\rightarrow$\\ +\end{tabular} +\begin{tabular}{|l|l|c|c|} +\hline +{\tt DESDE}&{\tt HACIA}&{\tt DISTANCIA}&{\tt COSTO}\\ +\hline +{\tt Seattle} &{\tt New-York}&{\tt 2.5}&{\tt 0.12}\\ +{\tt Seattle} &{\tt Chicago} &{\tt 1.7}&{\tt 0.08}\\ +{\tt Seattle} &{\tt Topeka} &{\tt 1.8}&{\tt 0.09}\\ +{\tt San-Diego}&{\tt New-York}&{\tt 2.5}&{\tt 0.15}\\ +{\tt San-Diego}&{\tt Chicago} &{\tt 1.8}&{\tt 0.10}\\ +{\tt San-Diego}&{\tt Topeka} &{\tt 1.4}&{\tt 0.07}\\ +\hline +\end{tabular} + +\subsection{Lectura de datos desde una tabla de entrada} + +La sentencia table de entrada produce la lectura de los datos desde la tabla especificada, registro por registro. + +Una vez que se ha leído el próximo registro, los valores numéricos o simbólicos de los campos cuyos nombres se han encerrado entre corchetes en la sentencia table se reúnen en un $n$-tuplo y, si se ha especificado el conjunto de control en la sentencia table, este $n$-tuplo es agregado al mismo. Además, un valor numérico o simbólico de cada campo asociado con un parámetro del modelo se asigna al miembro del parámetro identificado por subíndices, los cuales son componentes del $n$-tuplo que se acaba de leer. + +Por ejemplo, la siguiente sentencia table de entrada: + +\noindent\hfil +\verb|table datos IN "...": M <- [DESDE,HACIA], d~DISTANCIA, c~COSTO;| + +\noindent +produce la lectura de valores de cuatro campos llamados {\tt DESDE}, {\tt HACIA}, {\tt DISTANCIA} y {\tt COSTO} de cada registro de la tabla especificada. Los valores de los campos {\tt DESDE} y {\tt HACIA} proveen un par $(s,h)$ que se agrega al conjunto de control {\tt M}. El valor del campo {\tt DISTANCIA} se asigna al miembro del parámetro ${\tt d}[s,h]$ y el valor del campo {\tt COSTO} se asigna al miembro del parámetro ${\tt c}[s,h]$. + +Debe notarse que la tabla de entrada puede contener campos adicionales cuyos nombres no sean especificados en la sentencia table, en cuyo caso los valores de estos campos serán ignorados al leer la tabla. + +\subsection{Escritura de datos en una tabla de salida} + +La sentencia table de salida produce la escritura de datos en la tabla especificada. Debe notarse que algunos controladores (concretamente CSV y xBASE) destruyen la tabla de salida antes de escribir los datos, {\it i.e.} borran todos sus registros existentes. + +Cada $n$-tuplo en el conjunto dominio especificado genera un registro escrito en la tabla de salida. Los valores de los campos son valores numéricos o simbólicos de las correspondientes expresiones especificadas en la sentencia table. Estas expresiones se evalúan para cada $n$-tuplo en el conjunto dominio y, de este modo, puede incluir índices que se introdujeron en la correspondiente expresión indizante. + +Por ejemplo, la siguiente sentencia table de salida: + +\noindent\hfil +\verb|table resultado{(s,h) in M} OUT "...": s~DESDE, h~HACIA, x[s,h]~FLUJO;| + +\noindent +produce la escritura de registros en la tabla de salida, a razón de un registro por cada par $(s,h)$ en el conjunto {\tt M}, en el que cada registro consiste de tres campos llamados {\tt DESDE}, {\tt HACIA} y {\tt FLUJO}. Los valores escritos en los campos {\tt DESDE} y {\tt HACIA} son los valores corrientes de los índices {\tt s} y {\tt h}, y el valor escrito en el campo {\tt FLUJO} es un valor del miembro ${\tt x}[s,h]$ del correspondiente parámetro o variable indexada. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Datos del modelo} + +Los {\it datos del modelo} incluyen conjuntos elementales, los cuales son ``valores'' de los conjuntos del modelo, y valores simbólicos y numéricos de los parámetros del modelo. + +En MathProg hay dos maneras diferentes de proveer valores para los conjuntos y parámetros del modelo. Una manera es simplemente proveyendo los datos necesarios mediante el atributo de asignación. Sin embargo, en muchos casos es más práctico separar el modelo en sí mismo de los datos particulares necesarios para el modelo. Por esta última razón, en MathProg hay otra manera que consiste en separar la descripción del modelo en dos partes: la sección del modelo y la sección de los datos. + +La {\it sección del modelo} es la parte principal de la descripción del modelo que contiene las declaraciones de todos los objetos del modelo y es común a todos los problemas basados en tal modelo. + +La {\it sección de los datos} es una parte opcional de la descripción del modelo que contiene datos específicos para un problema particular. + +En MathProg las secciones del modelo y de los datos se pueden ubicar tanto en un único archivo de texto, como en dos archivos de texto separados. + +1. Si ambas secciones se ubican en un archivo, este debe componerse como sigue: + +\bigskip + +\noindent\hfil +\framebox{\begin{tabular}{l} +{\it sentencia}{\tt;}\\ +{\it sentencia}{\tt;}\\ +\hfil.\ \ .\ \ .\\ +{\it sentencia}{\tt;}\\ +{\tt data;}\\ +{\it bloque de datos}{\tt;}\\ +{\it bloque de datos}{\tt;}\\ +\hfil.\ \ .\ \ .\\ +{\it bloque de datos}{\tt;}\\ +{\tt end;} +\end{tabular}} + +\newpage + +2. Si ambas secciones se ubican en dos archivos separados, los archivos se componen como sigue: + +\bigskip + +\noindent\hfil +\begin{tabular}{@{}c@{}} +\framebox{\begin{tabular}{l} +{\it sentencia}{\tt;}\\ +{\it sentencia}{\tt;}\\ +\hfil.\ \ .\ \ .\\ +{\it sentencia}{\tt;}\\ +{\tt end;}\\ +\end{tabular}}\\ +\\\\Archivo del modelo\\ +\end{tabular} +\hspace{32pt} +\begin{tabular}{@{}c@{}} +\framebox{\begin{tabular}{l} +{\tt data;}\\ +{\it bloque de datos}{\tt;}\\ +{\it bloque de datos}{\tt;}\\ +\hfil.\ \ .\ \ .\\ +{\it bloque de datos}{\tt;}\\ +{\tt end;}\\ +\end{tabular}}\\ +\\Archivo de datos\\ +\end{tabular} + +\bigskip + +Nota: si la sección de datos se ubica en un archivo separado, la palabra clave {\tt data} es opcional y puede omitirse, al igual que el punto y coma que le sigue. + +\section{Codificación de la sección de los datos} + +La {\it sección de los datos} es una secuencia de bloques de datos en varios formatos que se discuten en las siguientes secciones. El orden que siguen los bloques de datos en la sección de los datos puede ser arbitrario, no necesariamente el mismo que se siguió en la sección del modelo para sus correspondientes objetos. + +Las reglas para codificar la sección de los datos comúnmente son las mismas reglas que para codificar la descripción del modelo (ver Sección \ref{coding}, página \pageref{coding}), {\it i.e.} los bloques de datos se componen con unidades léxicas básicas como nombres simbólicos, literales numéricos y de cadena, palabras clave, delimitadores y comentarios. Sin embargo, por conveniencia y para mejorar la legibilidad hay una desviación de la regla común: si un literal de cadena consiste únicamente de caracteres alfanuméricos (incluyendo el carácter de subrayado), los signos {\tt+} y {\tt-} y/o el punto decimal, el mismo puede codificarse sin comillas delimitadoras (simples o dobles). + +Todo el material numérico y simbólico provisto en la sección de los datos se codifica en la forma de números y símbolos, {\it i.e.} a diferencia de la sección del modelo, en la sección de los datos no se permiten expresiones. Sin embargo, los signos {\tt+} y {\tt-} pueden preceder a literales numéricos para permitir la codificación de cantidades numéricas con signo, en cuyo caso no debe haber caracteres de espacio en blanco entre el signo y el literal numérico que le sigue (si hay al menos un espacio en blanco, el signo y el literal numérico que le sigue serán reconocidos como dos unidades léxicas diferentes). + +\newpage + +\section{Bloque de datos de conjunto} + +\noindent +\framebox[468pt][l]{ +\parbox[c][44pt]{468pt}{ +\hspace{6pt} {\tt set} {\it nombre} {\tt,} {\it registro} {\tt,} \dots +{\tt,} {\it registro} {\tt;} + +\medskip + +\hspace{6pt} {\tt set} {\it nombre} {\tt[} {\it símbolo} {\tt,} \dots +{\tt,} {\it símbolo} {\tt]} {\tt,} {\it registro} {\tt,} \dots {\tt,} +{\it registro} {\tt;} +}} + +\medskip + +\noindent +{\it nombre} es el nombre simbólico del conjunto; + +\noindent +{\it símbolo}, \dots, {\it símbolo} son subíndices que especifican un miembro particular del conjunto (si el conjunto es un arreglo, {\it i.e.} un conjunto de conjuntos); + +\noindent +{\it registro}, \dots, {\it registro} son registros. + +\noindent +Las comas que preceden a los registros pueden omitirse. + +\para{Registros} + +\vspace*{-8pt} + +\begin{description} +\item[{\tt :=}]\hspace*{0pt}\\ +es un elemento de asignación de registro no-significativo que puede ser usado libremente para mejorar la legibilidad; +\item[{\tt(} {\it porción} {\tt)}]\hspace*{0pt}\\ +especifica una porción; +\item[{\it datos-simples}]\hspace*{0pt}\\ +especifica los datos del conjunto en formato simple; +\item[{\tt:} {\it datos-matriciales}]\hspace*{0pt}\\ +especifica los datos del conjunto en formato matricial; +\item[{\tt(tr)} {\tt:} {\it datos-matriciales}]\hspace*{0pt}\\ +especifica los datos del conjunto en formato matricial traspuesto (en este caso, los dos puntos que siguen a la palabra clave {\tt(tr)} pueden omitirse). +\end{description} + +\vspace*{-8pt} + +\para{Ejemplos} + +\begin{verbatim} +set mes := Ene Feb Mar Abr May Jun; +set mes "Ene", "Feb", "Mar", "Abr", "May", "Jun"; +set A[3,Mar] := (1,2) (2,3) (4,2) (3,1) (2,2) (4,4) (3,4); +set A[3,'Mar'] := 1 2 2 3 4 2 3 1 2 2 4 4 3 4; +set A[3,'Mar'] : 1 2 3 4 := + 1 - + - - + 2 - + + - + 3 + - - + + 4 - + - + ; +set B := (1,2,3) (1,3,2) (2,3,1) (2,1,3) (1,2,2) (1,1,1) (2,1,1); +set B := (*,*,*) 1 2 3, 1 3 2, 2 3 1, 2 1 3, 1 2 2, 1 1 1, 2 1 1; +set B := (1,*,2) 3 2 (2,*,1) 3 1 (1,2,3) (2,1,3) (1,1,1); +set B := (1,*,*) : 1 2 3 := + 1 + - - + 2 - + + + 3 - + - + (2,*,*) : 1 2 3 := + 1 + - + + 2 - - - + 3 + - - ; +\end{verbatim} + +\noindent(En estos ejemplos, {\tt mes} es un conjunto simple de singletones, {\tt A} es un arreglo 2-dimensional de duplos y {\tt B} es un conjunto simple de triplos. Los bloques de datos para el mismo conjunto son equivalentes en el sentido de que especifican los mismos datos en formatos distintos. + +El {\it bloque de datos del conjunto} se usa para especificar un conjunto elemental completo, el que se asigna a un conjunto (si es un conjunto simple) o a uno de sus miembros (si el conjunto es un arreglo de conjuntos).\footnote{Hay otra forma de especificar datos para un conjunto simple junto con los datos para los parámetros. Esta característica se discute en la próxima sección.} + +Los bloques de datos sólo pueden ser especificados para conjuntos no-calculables, {\it i.e.} para conjuntos que no tienen el atributo de asignación ({\tt:=}) en la correspondiente sentencia set. + +Si el conjunto es un conjunto simple, sólo se debe especificar su nombre simbólico en el encabezado del bloque de datos. De otro modo, si el conjunto es un arreglo $n$-dimensional, su nombre simbólico debe proveerse con una lista completa de subíndices separados por coma y encerrados entre corchetes para especificar un miembro particular del arreglo de conjuntos. El número de subíndices debe ser igual a la dimensión del arreglo de conjuntos, en el que cada subíndice deben ser un número o símbolo. + +Un conjunto elemental definido en el bloque de datos del conjunto se codifica como una secuencia de registros según se describe luego.\footnote{{Registro} es simplemente un término técnico. No significa que los mismos presenten algún formateo especial.} + +\subsection{Asignación de registro} + +La {\it asignación de registro} ({\tt:=}) es un elemento no-significativo. Se puede usar para mejorar la legibilidad de los bloques de datos. + +\subsection{Registro en porción} + +El {\it registro en porción} es un registro de control que especifica una {\it porción} del conjunto elemental definido en el bloque de datos. Tiene la siguiente forma sintáctica: +$$\mbox{{\tt(} $p_1$ {\tt,} $p_2$ {\tt,} \dots {\tt,} $p_n$ {\tt)}}$$ +donde $p_1$, $p_2$, \dots, $p_n$ son componentes de la porción. + +Cada componente de la porción puede ser un número o un símbolo o el asterisco ({\tt*}). El número de componentes de la porción debe coincidir con la dimensión de los $n$-tuplos del conjunto elemental que se define. Por ejemplo, si el conjunto elemental contiene 4-tuplos (cuádruplos), la porción debe tener cuatro componentes. El número de asteriscos en la porción se denomina la {\it dimensión de la porción}. + +El efecto de usar las porciones es como sigue: si se especifica una porción $m$-dimensional ({\it i.e.} una porción que tiene $m$ asteriscos) en el bloque de datos, todos los registros subsecuentes deben especificar tuplos de dimensión $m$. Cuando se encuentra un $m$-tuplo, cada asterisco en la porción se reemplaza por los correspondientes componentes del $m$-tuplo para dar el $n$-tuplo resultante, el que es incluido en el conjunto elemental que se define. Por ejemplo, si está vigente la porción $(a,*,1,2,*)$ y se encuentra el duplo $(3,b)$ en el registro subsecuente, el 5-tuplo resultante que se incluye en el conjunto elemental es $(a,3,1,2,b)$. + +Las porciones que no tienen asteriscos en si mismas, definen un $n$-tuplo completo que se incluye en el conjunto elemental. + +Una vez especificada una porción, la misma está vigente hasta que aparezca una nueva porción o bien hasta que se encuentra el final del bloque de datos. Debe notarse que si no se especifica una porción en el bloque de datos, se asume una cuyos componentes son asteriscos en todas las posiciones. + +\subsection{Registro simple} + +El {\it registro simple} define un $n$-tuplo en formato simple y tiene la siguiente forma sintáctica: +$$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$}$$ +donde $t_1$, $t_2$, \dots, $t_n$ son componentes del $n$-tuplo. Cada componente puede ser un número o símbolo. Las comas entre componentes son opcionales y pueden omitirse. + +\subsection{Registro matricial} + +El {\it registro matricial} define varios 2-tuplos (duplos) en formato matricial y tiene la siguiente forma sintáctica: +$$\begin{array}{cccccc} +\mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\ +f_1&a_{11}&a_{12}&\dots&a_{1n}&\\ +f_2&a_{21}&a_{22}&\dots&a_{2n}&\\ +\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\ +f_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\ +\end{array}$$ +donde $f_1$, $f_2$, \dots, $f_m$ son números y/o símbolos que corresponden a filas de la matriz; $c_1$, $c_2$, \dots, $c_n$ son números y/o símbolos que corresponden a columnas de la matriz, mientras que $a_{11}$, $a_{12}$, \dots, $a_{mn}$ son los elementos de la matriz, los cuales pueden ser tanto {\tt+} como {\tt-}. (En este registro, el delimitador {\tt:} que precede a la lista de columnas y el delimitador {\tt:=} a continuación de la lista de columnas, no pueden ser omitidos.) + +Cada elemento $a_{ij}$ del bloque de datos matricial (donde $1\leq i\leq m$, +$1\leq j\leq n$) corresponde a 2-tuplos $(f_i,c_j)$. Si en $a_{ij}$ se indica el signo más ({\tt+}), el correspondiente 2-tuplo (o un $n$-tuplo más largo si se usa una porción) se incluye en el conjunto elemental. De otro modo, si en $a_{ij}$ se indica el signo menos ({\tt-}) el 2-tuplo no se incluye en el conjunto elemental. + +Puesto que el registro matricial define 2-tuplos, ya sea el conjunto elemental o bien la porción vigente en uso deben ser 2-dimensionales. + +\subsection{Registro matricial traspuesto} + +El {\it registro matricial traspuesto} tiene la siguiente forma sintáctica: +$$\begin{array}{cccccc} +\mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\ +f_1&a_{11}&a_{12}&\dots&a_{1n}&\\ +f_2&a_{21}&a_{22}&\dots&a_{2n}&\\ +\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\ +f_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\ +\end{array}$$ +(En este caso el delimitador {\tt:} a continuación de la palabra clave {\tt (tr)} es opcional y puede omitirse.) + +Este registro es completamente análogo al registro matricial (ver anteriormente) con la única excepción, en este caso, de que cada elemento $a_{ij}$ de la matriz corresponde al 2-tuplo $(c_j,f_i)$ en vez de a $(f_i,c_j)$. + +Una vez especificado, el indicador {\tt(tr)} tiene alcance en todos los registros subsecuentes hasta que se encuentra otra porción o bien el fin del bloque de datos. + +\section{Bloque de datos de parámetro} + +\noindent +\framebox[468pt][l]{ +\parbox[c][88pt]{468pt}{ +\hspace{6pt} {\tt param} {\it nombre} {\tt,} {\it registro} {\tt,} \dots +{\tt,} {\it registro} {\tt;} + +\medskip + +\hspace{6pt} {\tt param} {\it nombre} {\tt default} {\it valor} {\tt,} +{\it registro} {\tt,} \dots {\tt,} {\it registro} {\tt;} + +\medskip + +\hspace{6pt} {\tt param} {\tt:} {\it datos-tabulación} {\tt;} + +\medskip + +\hspace{6pt} {\tt param} {\tt default} {\it valor} {\tt:} +{\it datos-tabulación} {\tt;} +}} + +\medskip + +\noindent +{\it nombre} es el nombre simbólico del parámetro; + +\noindent +{\it valor} es un valor por defecto opcional del parámetro; + +\noindent +{\it registro}, \dots, {\it registro} son registros. + +\noindent +{\it datos-tabulación} especifica los datos del parámetro en el formato tabulación. + +\noindent +Las comas que preceden a los registros pueden omitirse. + +\para{Registros} + +\vspace*{-8pt} + +\begin{description} +\item[{\tt :=}]\hspace*{0pt}\\ +es un elemento de asignación de registro no-significativo que puede ser usado libremente para mejorar la legibilidad; +\item[{\tt[} {\it porción} {\tt]}]\hspace*{0pt}\\ +especifica una porción; +\item[{\it datos-planos}]\hspace*{0pt}\\ +especifica los datos del parámetro en formato plano; +\item[{\tt:} {\it datos-tabulares}]\hspace*{0pt}\\ +especifica los datos del parámetro en formato tabular; +\item[{\tt(tr)} {\tt:} {\it datos-tabulares}]\hspace*{0pt}\\ +especifica los datos del parámetro en formato matricial traspuesto (en este caso, los dos puntos que siguen a la palabra clave {\tt(tr)} pueden omitirse). +\end{description} + +\vspace*{-8pt} + +\para{Ejemplos} + +\begin{verbatim} +param T := 4; +param mes := 1 Ene 2 Feb 3 Mar 4 Abr 5 May; +param mes := [1] 'Ene', [2] 'Feb', [3] 'Mar', [4] 'Abr', [5] 'May'; +param stock_inicial := hierro 7.32 niquel 35.8; +param stock_inicial [*] hierro 7.32, niquel 35.8; +param costo [hierro] .025 [niquel] .03; +param valor := hierro -.1, niquel .02; +param : stock_inicial costo valor := + hierro 7.32 .025 -.1 + niquel 35.8 .03 .02 ; +param : insumo : stock_inicial costo valor := + hierro 7.32 .025 -.1 + niquel 35.8 .03 .02 ; +param demanda default 0 (tr) + : FRA DET LAN WIN STL FRE LAF := + laminas 300 . 100 75 . 225 250 + rollos 500 750 400 250 . 850 500 + cintas 100 . . 50 200 . 250 ; +param costo_transporte := + [*,*,laminas]: FRA DET LAN WIN STL FRE LAF := + GARY 30 10 8 10 11 71 6 + CLEV 22 7 10 7 21 82 13 + PITT 19 11 12 10 25 83 15 + [*,*,rollos]: FRA DET LAN WIN STL FRE LAF := + GARY 39 14 11 14 16 82 8 + CLEV 27 9 12 9 26 95 17 + PITT 24 14 17 13 28 99 20 + [*,*,cintas]: FRA DET LAN WIN STL FRE LAF := + GARY 41 15 12 16 17 86 8 + CLEV 29 9 13 9 28 99 18 + PITT 26 14 17 13 31 104 20 ; +\end{verbatim} + +El {\it bloque de datos del parámetro} se usa para especificar datos completos a un parámetro (o a varios parámetros si los datos se especifican en el formato tabulaciones) + +Los bloques de datos sólo pueden ser especificados para parámetros no-calculables, {\it i.e.} para parámetros que no tienen el atributo de asignación({\tt:=}) en la correspondiente sentencia parameter. + +Los datos definidos en el bloque de datos del parámetro se codifican como una secuencia de registros descriptos luego. Adicionalmente, el bloque de datos puede ser provisto con el atributo opcional {\tt default}, el cual especifica un valor numérico o simbólico por defecto para el parámetro (parámetros). Este valor por defecto se asigna al parámetro, o a sus miembros, cuando no se definen valores apropiados en el bloque de datos del parámetro. El atributo {\tt default} no se puede usar si ya se ha especificado en la correspondiente sentencia parameter. + +\subsection{Asignación de registro} + +La {\it asignación de registro} ({\tt:=}) es un elemento no-significativo. Se puede usar para mejorar la legibilidad de los bloques de datos. + +\subsection{Registro en porción} + +El {\it registro en porción} es un registro de control que especifica una {\it porción} del arreglo de parámetros. Tiene la siguiente forma sintáctica: +$$\mbox{{\tt[} $p_1$ {\tt,} $p_2$ {\tt,} \dots {\tt,} $p_n$ {\tt]}}$$ +donde $p_1$, $p_2$, \dots, $p_n$ son componentes de la porción. + +Cada componente de la porción puede ser un número o un símbolo o el asterisco ({\tt*}). El número de componentes de la porción debe coincidir con la dimensión del parámetro. Por ejemplo, si el parámetro es un arreglo 4-dimensional, la porción debe tener cuatro componentes. El número de asteriscos en la porción se denomina la {\it dimensión de la porción}. + +El efecto de usar las porciones es como sigue: si se especifica una porción $m$-dimensional ({\it i.e.} una porción que tiene $m$ asteriscos) en el bloque de datos, todos los registros subsecuentes deben especificar los subíndices de los miembros del parámetro como si el parámetro fuese $m$-dimensional y no $n$-dimensional. + +Cuando se encuentran los $m$ subíndices, cada asterisco en la porción se reemplaza por el correspondiente subíndice para dar los $n$ subíndices, los cuales definen al miembro corriente del parámetro. Por ejemplo, si está vigente la porción $(a,*,1,2,*)$ y se encuentran los subíndices 3 y $b$ en el registro subsecuente, la lista completa de subíndices que se usa para elegir un miembro del parámetro es $(a,3,1,2,b)$. + +Se permite especificar una porción que no tenga asteriscos. Tal porción, en sí misma define una lista completa de subíndices, en cuyo caso el próximo registro debe definir solamente un valor individual del correspondiente miembro del parámetro. + +Una vez especificada una porción, la misma está vigente hasta que aparezca una nueva porción o bien hasta que se encuentra el final del bloque de datos. Debe notarse que si no se especifica una porción en el bloque de datos, se asume una cuyos componentes son todos asteriscos. + +\subsection{Registro plano} + +El {\it registro plano} define la lista de subíndices y un valor individual en el formato plano. Este registro tiene la siguiente forma sintáctica: +$$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$ {\tt,} $v$}$$ +donde $t_1$, $t_2$, \dots, $t_n$ son subíndices y $v$ es un valor. Cada subíndice, al igual que el valor, puede ser un número o un símbolo. Las comas que siguen a los subíndices son opcionales y pueden omitirse. + +En el caso de parámetros o porciones 0-dimensionales, el registro plano no tiene subíndice y consiste solamente de un valor individual. + +\subsection{Registro tabular} + +El {\it registro tabular} define varios valores, cada uno de los cuales viene provisto con dos subíndices. Este registro tiene la siguiente forma sintáctica: +$$\begin{array}{cccccc} +\mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\ +f_1&a_{11}&a_{12}&\dots&a_{1n}&\\ +f_2&a_{21}&a_{22}&\dots&a_{2n}&\\ +\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\ +f_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\ +\end{array}$$ +donde los $f_1$, $f_2$, \dots, $f_m$ son números y/o símbolos que corresponden a filas de la tabla; $c_1$, $c_2$, \dots, $c_n$ son números y/o símbolos que corresponden a columnas de la tabla; mientras que $a_{11}$, $a_{12}$, \dots, $a_{mn}$ son elementos de la tabla. Cada elemento puede ser un número o símbolo o el punto decimal ({\tt.}) solo (en este registro, el delimitador {\tt:} que precede a la lista de columnas y el delimitador {\tt:=} a continuación de la lista de columnas, no pueden ser omitidos.). + +Cada elemento $a_{ij}$ del bloque de datos tabulares ($1\leq i\leq m$, +$1\leq j\leq n$) define dos subíndices, siendo el primero $f_i$ y el segundo $c_j$. Estos subíndices se usan junto con la porción vigente para formar la lista completa de subíndices que identifica a un miembro particular del arreglo de parámetros. Si $a_{ij}$ es un número o símbolo, tal valor se asigna al miembro del parámetro. Sin embargo, si $a_{ij}$ es un punto decimal solo, el miembro recibe el valor por defecto especificado ya sea en el bloque de datos del parámetro o en la sentencia parameter, o si no hay un valor por defecto especificado, el miembro permanece indefinido. + +Puesto que el registro tabular provee dos subíndices para cada valor, ya sea el parámetro o bien la porción vigente en uso deben ser 2-dimensionales. + +\subsection{Registro tabular traspuesto} + +El {\it registro tabular traspuesto} tiene la siguiente forma sintáctica: +$$\begin{array}{cccccc} +\mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\ +f_1&a_{11}&a_{12}&\dots&a_{1n}&\\ +f_2&a_{21}&a_{22}&\dots&a_{2n}&\\ +\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\ +f_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\ +\end{array}$$ +(En este caso el delimitador {\tt:} a continuación de la palabra clave {\tt (tr)} es opcional y puede omitirse.) + +Este registro es completamente análogo al registro tabular (ver anteriormente), con la única excepción de que el primer subíndice definido por el elemento $a_{ij}$ es $c_j$ mientras que el segundo es $f_i$. + +Una vez especificado, el indicador {\tt(tr)} tiene alcance en todos los registros subsecuentes hasta que se encuentre otra porción o bien el fin del bloque de datos. + +\subsection{Formato de datos tabulación} + +El bloque de datos del parámetro en el {\it formato tabulación} tiene la siguiente forma sintáctica: +$$ +\begin{array}{*{8}{l}} +\multicolumn{4}{l} +{{\tt param}\ {\tt default}\ valor\ {\tt :}\ c\ {\tt :}}& +p_1\ \ \verb|,|&p_2\ \ \verb|,|&\dots\ \verb|,|&p_f\ \ \verb|:=|\\ +f_{11}\ \verb|,|& f_{12}\ \verb|,|& \dots\ \verb|,|& f_{1n}\ \verb|,|& +a_{11}\ \verb|,|& a_{12}\ \verb|,|& \dots\ \verb|,|& a_{1f}\ \verb|,|\\ +f_{21}\ \verb|,|& f_{22}\ \verb|,|& \dots\ \verb|,|& f_{2n}\ \verb|,|& +a_{21}\ \verb|,|& a_{22}\ \verb|,|& \dots\ \verb|,|& a_{2f}\ \verb|,|\\ +\dots & \dots & \dots & \dots & \dots & \dots & \dots & \dots \\ +f_{m1}\ \verb|,|& f_{m2}\ \verb|,|& \dots\ \verb|,|& f_{mn}\ \verb|,|& +a_{m1}\ \verb|,|& a_{m2}\ \verb|,|& \dots\ \verb|,|& a_{mf}\ \verb|;|\\ +\end{array} +$$ + +1. La palabra clave {\tt default} puede omitirse junto con el valor que le sigue. + +2. El nombre simbólico $c$ puede omitirse junto con los dos puntos que le siguen. + +3. Todas las comas son opcionales y pueden omitirse. + +El bloque de datos en el formato tabulación mostrado arriba es exactamente equivalente a los siguientes bloques de datos: + +\verb|set| $c$\ \verb|:=|\ $ +\verb|(|f_{11}\verb|,|f_{12}\verb|,|\dots\verb|,|f_{1n}\verb|) | +\verb|(|f_{21}\verb|,|f_{22}\verb|,|\dots\verb|,|f_{2n}\verb|) | +\dots +\verb| (|f_{m1}\verb|,|f_{m2}\verb|,|\dots\verb|,|f_{mn}\verb|);|$ + +\verb|param| $p_1$\ \verb|default|\ $valor$\ \verb|:=| + +$\verb| | +\verb|[|f_{11}\verb|,|f_{12}\verb|,|\dots\verb|,|f_{1n}\verb|] |a_{11} +\verb| [|f_{21}\verb|,|f_{22}\verb|,|\dots\verb|,|f_{2n}\verb|] |a_{21} +\verb| |\dots +\verb| [|f_{m1}\verb|,|f_{m2}\verb|,|\dots\verb|,|f_{mn}\verb|] |a_{m1} +\verb|;| +$ + +\verb|param| $p_2$\ \verb|default|\ $valor$\ \verb|:=| + +$\verb| | +\verb|[|f_{11}\verb|,|f_{12}\verb|,|\dots\verb|,|f_{1n}\verb|] |a_{12} +\verb| [|f_{21}\verb|,|f_{22}\verb|,|\dots\verb|,|f_{2n}\verb|] |a_{22} +\verb| |\dots +\verb| [|f_{m1}\verb|,|f_{m2}\verb|,|\dots\verb|,|f_{mn}\verb|] |a_{m2} +\verb|;| +$ + +\verb| |.\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ . + +\verb|param| $p_f$\ \verb|default|\ $valor$\ \verb|:=| + +$\verb| | +\verb|[|f_{11}\verb|,|f_{12}\verb|,|\dots\verb|,|f_{1n}\verb|] |a_{1f} +\verb| [|f_{21}\verb|,|f_{22}\verb|,|\dots\verb|,|f_{2n}\verb|] |a_{2f} +\verb| |\dots +\verb| [|f_{m1}\verb|,|f_{m2}\verb|,|\dots\verb|,|f_{mn}\verb|] |a_{mf} +\verb|;| +$ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\appendix + +\chapter{Uso de sufijos} + +\vspace*{-12pt} + +Se pueden usar sufijos para recuperar valores adicionales relacionados con las variables, restricciones y objetivos del modelo. + +Un {\it sufijo} consiste de un punto ({\tt.}) seguido de una palabra clave no-reservada. Por ejemplo, si {\tt x} es una variable bidimensional, {\tt x[i,j].lb} es un valor numérico igual a la cota inferior de la variable elemental {\tt x[i,j]} que se puede usar como un parámetro numérico dondequiera que sea en expresiones. + +Para las variables del modelo, los sufijos tienen los siguientes significados: + +\begin{tabular}{@{}ll@{}} +{\tt.lb}&cota inferior\\ +{\tt.ub}&cota superior\\ +{\tt.status}&estatus en la solución:\\ +&0 --- indefinida\\ +&1 --- básica\\ +&2 --- no-básica en la cota inferior\\ +&3 --- no-básica en la cota superior\\ +&4 --- variable no-básica libre (no acotada)\\ +&5 --- variable no-básica fija\\ +{\tt.val}&valor primal en la solución\\ +{\tt.dual}&valor dual (costo reducido) en la solución\\ +\end{tabular} + +Para las restricciones y objetivos del modelo, los sufijos tienen los siguientes significados: + +\begin{tabular}{@{}ll@{}} +{\tt.lb}&cota inferior de la forma lineal\\ +{\tt.ub}&cota superior de la forma lineal\\ +{\tt.status}&estatus en la solución:\\ +&0 --- indefinida\\ +&1 --- no-limitante\\ +&2 --- limitante en la cota inferior\\ +&3 --- limitante en la cota superior\\ +&4 --- fila limitante libre (no-acotada)\\ +&5 --- restricción de igualdad limitante\\ +{\tt.val}&valor primal de la forma lineal en la solución\\ +{\tt.dual}&valor dual (costo reducido) de la forma lineal en la solución\\ +\end{tabular} + +Debe notarse que los sufijos {\tt.status}, {\tt.val} y {\tt.dual} solamente pueden usarse luego de la sentencia solve. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Funciones de fecha y hora} + +\noindent\hfil +\begin{tabular}{c} +por Andrew Makhorin \verb||\\ +y Heinrich Schuchardt \verb||\\ +\end{tabular} + +\section{Obtención del tiempo calendario corriente} +\label{gmtime} + +Para obtener el tiempo calendario\footnote{N. del T.: el tiempo calendario es un punto en el {\it continuum} del tiempo, por ejemplo 4 de noviembre de 1990 a las 18:02.5 UTC. A veces se lo llama ``tiempo absoluto''. La definición está tomada de {\it Sandra Loosemore}, {\it Richard M. Stallman}, {\it Roland McGrath}, {\it Andrew Oram} \& {\it Ulrich Drepper}, ``The GNU C Library Reference Manual - for version 2.17'', Free Software Foundation, Inc, 2012.} corriente en MathProg existe la función {\tt gmtime}. No tiene argumentos y devuelve el número de segundos transcurridos desde las 00:00:00 del 1 de enero de 1970, Tiempo Universal Coordinado (UTC). Por ejemplo: + +\begin{verbatim} + param utc := gmtime(); +\end{verbatim} + +MathPro no tiene una función para convertir el tiempo UTC devuelto por la función {\tt gmtime} a tiempo calendario {\it local}. Entonces, si se necesita determinar el tiempo calendario local corriente, se debe agregar al tiempo UTC devuelto la diferencia horaria con respecto al UTC expresada en segundos. Por ejemplo, la hora en Berlín durante el invierno está una hora adelante del UTC, lo que corresponde una diferencia horaria de +1~hora~= +3600~segundos, de modo que el tiempo calendario corriente del invierno en Berlín se puede determinar como sigue: + +\begin{verbatim} + param ahora := gmtime() + 3600; +\end{verbatim} + +\noindent Análogamente, el horario de verano en Chicago (Zona Horaria Central) está cinco horas por detrás del UTC, de modo que el correspondiente tiempo calendario local corriente se puede determinar como sigue: + +\begin{verbatim} + param ahora := gmtime() - 5 * 3600; +\end{verbatim} + +Debe notarse que el valor devuelto por {\tt gmtime} es volátil, {\it i.e.} si se la invoca varias veces, esta función devolverá valores diferentes. + +\section{Conversión de una cadena de caracteres a un tiempo calendario} +\label{str2time} + +La función {\tt str2time(}{\it c}{\tt,} {\it f}{\tt)} convierte una cadena de caracteres (una {\it estampa de la fecha y hora}) especificada por su primer argumento {\it c}, la que debe ser una expresión simbólica, a un tiempo calendario apropiado para cálculos aritméticos. La conversión se controla mediante la especificación de una cadena de formato {\it f} (el segundo argumento), la que también debe ser una expresión simbólica. + +El resultado de la conversión devuelto por {\tt str2time} tiene el mismo significado que los valores devueltos por la función {\tt gmtime} (ver Subsección \ref{gmtime}, página \pageref{gmtime}). Debe notarse que {\tt str2time} {\it no corrige} el tiempo calendario devuelto para considerar la zona horaria local, {\it i.e.} si se aplica a las 00:00:00 del 1 de enero de 1970, siempre devolverá 0. + +Por ejemplo, las sentencias del modelo + +\begin{verbatim} + param c, symbolic, := "07/14/98 13:47"; + param t := str2time(c, "%m/%d/%y %H:%M"); + display t; +\end{verbatim} + +\noindent imprime lo siguiente en la salida estándar: + +\begin{verbatim} + t = 900424020 +\end{verbatim} + +\noindent donde el tiempo calendario mostrado corresponde a las 13:47:00 del 14 de julio de 1998. + +La cadena de formato que se pasa a la función {\tt str2time} consiste de especificadores de conversión y caracteres ordinarios. Cada especificador de conversión empieza con un carácter de porcentaje ({\tt\%}) seguido por una letra. + +Los siguientes especificadores de conversión se pueden usar en la cadena de formato\footnote{N. del T.: en todas las funciones de fecha y hora, nombre del mes y del día de la semana refiere a su denominación en inglés, {\it e.g.}: {\tt August}, {\tt Aug}, {\tt Wednesday}, {\tt We}.}: + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%b}&El nombre del mes abreviado (insensible a mayúsculas). Al menos las tres primeras letras del nombre del mes deben aparecer en la cadena de entrada.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%d}&El día del mes como un número decimal (rango de 1 a 31). Se permite el cero como primer dígito, aunque no es requerido.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%h}&Lo mismo que {\tt\%b}.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%H}&La hora como un número decimal, empleando un reloj de 24 horas (rango de 0 a 23). Se permite el cero como primer dígito, aunque no es requerido.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%m}&El mes como un número decimal (rango de 1 a 12). Se permite el cero como primer dígito, aunque no es requerido.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%M}&El minuto como número decimal (rango de 0 a 59). Se permite el cero como primer dígito, aunque no es requerido.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%S}&El segundo como un número decimal (rango de 0 a 59). Se permite el cero como primer dígito, aunque no es requerido.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%y}&El año sin un siglo como un número decimal (rango de 0 a 99). Se permite el cero como primer dígito, aunque no es requerido. Los valores de entrada en el rango de 0 a 68 se consideran como los años 2000 al 2068, mientras que los valores del 69 al 99 como los años 1969 a 1999.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%z}&La diferencia horaria con respecto a GMT en formato ISO 8601.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%\%}&Un carácter {\tt\%} literal.\\ +\end{tabular} + +Todos los demás caracteres (ordinarios) en la cadena de formato deben tener un carácter de coincidencia con la cadena de entrada a ser convertida. Las excepciones son los espacios en la cadena de entrada, la cual puede coincidir con cero o más caracteres de espacio en la cadena de formato. + +Si algún componente de la fecha y/u hora están ausentes en el formato y, consecuentemente, en la cadena de entrada, la función {\tt str2time} usa sus valores por defecto de las 00:00:00 del 1 de enero de 1970, es decir que el valor por defecto para el año es 1970, el valor por defecto para el mes es enero, etc. + +La función {} es aplicable a todos los tiempos calendarios en el rango desde las 00:00:00 del 1 de enero del 0001 hasta las 23:59:59 del 31 de diciembre del 4000 del calendario gregoriano. + +\section{Conversión de un tiempo calendario a una cadena de caracteres} +\label{time2str} + +La función {\tt time2str(}{\it t}{\tt,} {\it f}{\tt)} convierte el tiempo calendario especificado por su primer argumento {\it t}, el que debe ser una expresión numérica, a una cadena de caracteres (valor simbólico). La conversión se controla con la cadena de formato {\it f} especificada (el segundo argumento), la que debe ser una expresión simbólica. + +El tiempo calendario que se le pasa a {\tt time2str} tiene el mismo significado que el valor devuelto por la función {\tt gmtime} (ver Subsección \ref{gmtime}, página \pageref{gmtime}). Debe notarse que {\tt time2str} {\it no corrige} el tiempo calendario especificado para considerar la zona horaria local, {\it i.e.} el tiempo calendario 0 siempre corresponde a las 00:00:00 del 1 de enero de 1970. + +Por ejemplo, las sentencias del modelo + +\begin{verbatim} + param c, symbolic, := time2str(gmtime(), "%FT%TZ"); + display c; +\end{verbatim} + +\noindent puede producir la siguiente impresión: + +\begin{verbatim} + c = '2008-12-04T00:23:45Z' +\end{verbatim} + +\noindent que es una estampa de una fecha y hora en el formato ISO. + +La cadena de formato que se pasa a la función {\tt time2str} consiste de especificadores de conversión y caracteres ordinarios. Cada especificador de conversión empieza con un carácter de porcentaje ({\tt\%}) seguido por una letra. + +Los siguientes especificadores de conversión se pueden usar en la cadena de formato: + +\newpage + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%a}&El nombre del día de la semana abreviado (2 caracteres).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%A}&El nombre del día de la semana completo.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%b}&El nombre del mes abreviado (3 caracteres).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%B}&El nombre del mes completo.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%C}&El siglo del año, es decir el mayor entero no mayor que el año dividido por~100.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%d}&El día del mes como un número decimal (rango de 01 a 31).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%D}&La fecha, usando el formato \verb|%m/%d/%y|.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%e}&El día del mes, como con \verb|%d|, pero rellenado con un espacio en blanco en vez de cero.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%F}&La fecha, usando el formato \verb|%Y-%m-%d|.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%g}&El año correspondiente al número de semana ISO, pero sin el siglo (rango de 00 a 99). Tiene el mismo formato y valor que \verb|%y|, excepto que si el número de semana ISO (ver \verb|%V|) pertenece al año previo o siguiente, se usa aquel año en su lugar.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%G}&El año correspondiente al número de semana ISO. Tiene el mismo formato y valor que \verb|%Y|, excepto que si el número de semana ISO (ver \verb|%V|) pertenece al año previo o siguiente, se usa aquel año en su lugar.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%h}&Lo mismo que \verb|%b|.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%H}&La hora como un número decimal, empleando un reloj de 24 horas (rango de 00 a 23).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%I}&La hora como un número decimal, empleando un reloj de 12 horas (rango de 01 a 12).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%j}&El día del año como un número decimal (rango de 001 a 366).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%k}&La hora como un número decimal, empleando un reloj de 24 horas como con \verb|%H|, pero rellenado con un espacio en blanco en vez de cero.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%l}&La hora como un número decimal, empleando un reloj de 12 horas como con \verb|%I|, pero rellenado con un espacio en blanco en vez de cero.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%m}&El mes como un número decimal (rango de 01 a 12).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%M}&El minuto como un número decimal (rango de 00 a 59).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%p}&Tanto {\tt AM} como {\tt PM}, de acuerdo con el valor horario dado. La medianoche es tratada como {\tt AM} y el mediodía como {\tt PM}.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%P}&Tanto {\tt am} como {\tt pm}, de acuerdo con el valor horario dado. La medianoche es tratada como {\tt am} y el mediodía como {\tt pm}.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%R}&La hora y los minutos en números decimales, usando el formato \verb|%H:%M|.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%S}&Los segundos como un número decimal (rango de 00 a 59).\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%T}&La hora del día en números decimales, usando el formato \verb|%H:%M:%S|.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%u}&El día de la semana como un número decimal (rango de 1 a 7), siendo 1 el lunes.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%U}&El número de semana del año corriente como un número decimal (rango de 00 a 53), empezando con el primer domingo como el primer día de la primer semana. Se considera que los días del año anteriores al primer domingo son parte de la semana 00.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%V}&El número de semana ISO como un número decimal (rango 01 a 53). Las semanas de ISO empiezan los lunes y terminan los domingos. La semana 01 de un año es la primer semana que tiene la mayoría de sus días en ese año, lo cual es equivalente a la semana que contiene al 4 de enero. La semana 01 de un año puede contener días del año previo. La semana anterior a la semana 01 de un año es la última semana (52 o 53) del año previo, aún si esta contiene días del nuevo año. En otras palabras, si el 1 de enero cae en lunes, martes, miércoles o jueves, está en la semana 01; si el 1 de enero cae en viernes, sábado o domingo, está en la semana 52 o 53 del año previo.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%w}&El día de la semana como un número decimal (rango de 0 a 6), siendo 0 el domingo.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%W}&El número de semana del año corriente como un número decimal (rango de 00 a 53), empezando con el primer lunes como el primer día de la primer semana. Se considera que los días del año anteriores al primer lunes son parte de la semana 00.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%y}&El año sin el siglo como un número decimal (rango de 00 a 99), es decir año {\tt mod} 100.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%Y}&El año como un número decimal, usando el calendario gregoriano.\\ +\end{tabular} + +\begin{tabular}{@{}p{20pt}p{421.5pt}@{}} +{\tt\%\%}& Un carácter \verb|%| literal.\\ +\end{tabular} + +Todos los demás caracteres (ordinarios) en la cadena de formato simplemente se copian a la cadena resultante. + +El primer argumento (tiempo calendario) que se le pasa a la función {\tt time2str} debe están en el rango entre $-62135596800$ y $+64092211199$, lo que corresponde al período desde las 00:00:00 del 1 de enero del 0001 hasta las 23:59:59 del 31 de diciembre del 4000 del calendario gregoriano. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Controladores de tablas} +\label{drivers} + +\noindent\hfil +\begin{tabular}{c} +por Andrew Makhorin \verb||\\ +y Heinrich Schuchardt \verb||\\ +\end{tabular} + +\bigskip\bigskip + +El {\it controlador de tablas} es un módulo del programa que permite la trasmisión de datos entre objetos de un modelo MathProg y tablas de datos. + +Actualmente, el paquete GLPK tiene cuatro controladores de tablas: + +\vspace*{-8pt} + +\begin{itemize} +\item controlador interno de tablas CSV; +\item controlador interno de tablas xBASE; +\item controlador de tablas ODBC; +\item controlador de tablas MySQL. +\end{itemize} + +\vspace*{-8pt} + +\section{Controlador de tablas CSV} + +El controlador de tablas CSV asume que la tabla de datos está representada en la forma de un archivo de texto plano, en el formato de archivo CSV (valores separados por coma) como se describe más adelante. + +Para elegir el controlador de tablas CSV, su nombre en la sentencia table debe especificarse como \verb|"CSV"| y el único argumento debe especificar el nombre de un archivo de texto plano conteniendo la tabla. Por ejemplo: + +\begin{verbatim} + table datos IN "CSV" "datos.csv": ... ; +\end{verbatim} + +El sufijo del nombre de archivo puede ser arbitrario; sin embargo, se recomienda usar el sufijo `\verb|.csv|'. + +\newpage + +Al leer tablas de entrada, el controlador de tablas CSV provee un campo implícito llamado \verb|RECNO|, el cual contiene el número del registro corriente. Este campo puede especificarse en la sentencia table de entrada, como si existiera un verdadero campo llamado \verb|RECNO| en el archivo CSV. Por ejemplo: + +\begin{verbatim} + table lista IN "CSV" "lista.csv": num <- [RECNO], ... ; +\end{verbatim} + +\subsection*{Formato CSV\footnote{Este material está basado en el documento RFC 4180.}} + +El formato CSV (valores separados por coma) es un formato de archivo de texto plano definido como sigue: + +1. Cada registro se ubica en una línea separada, delimitada por un salto de línea. Por ejemplo: + +\begin{verbatim} + aaa,bbb,ccc\n + xxx,yyy,zzz\n +\end{verbatim} + +\noindent +donde \verb|\n| significa el carácter de control \verb|LF| ({\tt 0x0A}). + +2. El último registro en el archivo puede tener un salto de línea final o no. Por ejemplo: + +\begin{verbatim} + aaa,bbb,ccc\n + xxx,yyy,zzz +\end{verbatim} + +3. Debería haber una línea de encabezado que aparezca en la primera línea del archivo, en el mismo formato que las líneas de registro normales. Este encabezado debería contener nombres que correspondan a los campos en el archivo. El número de nombres de campo en la línea de encabezado debe ser igual al número de campos de los registros en el archivo. Por ejemplo: + +\begin{verbatim} + nombre1,nombre2,nombre3\n + aaa,bbb,ccc\n + xxx,yyy,zzz\n +\end{verbatim} + +4. Dentro del encabezado y de cada registro puede haber uno o más campos separados por comas. Cada línea debe contener el mismo número de campos a través de todo el archivo. Los espacios se consideran parte del campo y, consecuentemente, no son ignorados. El último campo en el registro no debe estar seguido de una coma. Por ejemplo: + +\begin{verbatim} + aaa,bbb,ccc\n +\end{verbatim} + +5. Los campos pueden estar encerrados entre comillas dobles o no. Por ejemplo: + +\begin{verbatim} + "aaa","bbb","ccc"\n + zzz,yyy,xxx\n +\end{verbatim} + +6. Si el campo se encierra entre comillas dobles, cada comilla doble que sea parte del campo debe codificarse dos veces. Por ejemplo: + +\begin{verbatim} + "aaa","b""bb","ccc"\n +\end{verbatim} + +\newpage + +\para{Ejemplo} + +\begin{verbatim} +DESDE,HACIA,DISTANCIA,COSTO +Seattle,New-York,2.5,0.12 +Seattle,Chicago,1.7,0.08 +Seattle,Topeka,1.8,0.09 +San-Diego,New-York,2.5,0.15 +San-Diego,Chicago,1.8,0.10 +San-Diego,Topeka,1.4,0.07 +\end{verbatim} + +\section{Controlador de tablas xBASE} + +El controlador de tablas xBASE asume que la tabla de datos se almacenó en formato de archivo .dbf. + +Para elegir el controlador de tablas xBASE, su nombre en la sentencia table debe especificarse como \verb|"xBASE"| y el primer argumento debe especificar el nombre de un archivo .dbf que contenga la tabla. Para la tabla de salida, debe haber un segundo argumento definiendo el formato de la tabla en la forma \verb|"FF...F"|, donde \verb|F| es tanto {\tt C({\it n})}, el cual especifica un campo de caracteres de longitud $n$, como + {\tt N({\it n}{\rm [},{\it p}{\rm ]})}, el cual especifica un campo numérico de longitud $n$ y precisión $p$ (por defecto, $p$ es 0). + +El siguiente es un ejemplo simple que ilustra la creación y lectura de un archivo .dbf: + +\begin{verbatim} +table tab1{i in 1..10} OUT "xBASE" "foo.dbf" + "N(5)N(10,4)C(1)C(10)": 2*i+1 ~ B, Uniform(-20,+20) ~ A, + "?" ~ FOO, "[" & i & "]" ~ C; +set M, dimen 4; +table tab2 IN "xBASE" "foo.dbf": M <- [B, C, RECNO, A]; +display M; +end; +\end{verbatim} + +\section{Controlador de tablas ODBC} + +El controlador de tablas ODBC permite conexiones con bases de datos SQL usando una implementación de la interfaz ODBC basada en la Call Level Interface (CLI).\footnote{La norma de software correspondiente se define en ISO/IEC 9075-3:2003.} + +\para{Debian GNU/Linux.} +Bajo Debian GNU/Linux, el controlador de tablas ODBC usa el paquete iODBC,\footnote{Ver {\tt}.} el cual debe estar instalado antes de compilar el paquete GLPK. La instalación se puede efectuar con el siguiente comando: + +\begin{verbatim} + sudo apt-get install libiodbc2-dev +\end{verbatim} + +Debe notarse que para la configuración del paquete GLPK para activar el uso de la librería iODBC, se debe pasar la opción `\verb|--enable-odbc|' al script de configuración. + +Para su uso en todo el sistema, las bases de datos individuales deben ingresarse en \verb|/etc/odbc.ini| y \verb|/etc/odbcinst.ini|. Las conexiones de las bases de datos usadas por un usuario individual se especifican mediante archivos en el directorio home (\verb|.odbc.ini| y \verb|.odbcinst.ini|). + +\para{Microsoft Windows.} +Bajo Microsoft Windows, el controlador de tablas ODBC usa la librería ODBC de Microsoft. Para activar esta característica, el símbolo: + +\begin{verbatim} + #define ODBC_DLNAME "odbc32.dll" +\end{verbatim} + +\noindent +debe definirse en el archivo de configuración de GLPK `\verb|config.h|'. + +Las fuentes de datos pueden crearse por intermedio de las Herramientas Administrativas del Panel de Control. + +Para elegir el controlador de tablas ODBC, su nombre en la sentencia table debe especificarse como \verb|'ODBC'| o \verb|'iODBC'|. + +La lista de argumentos se especifica como sigue. + +El primer argumento es la cadena de conexión que se pasa a la librería ODBC, por ejemplo: + +\verb|'DSN=glpk;UID=user;PWD=password'|, o + +\verb|'DRIVER=MySQL;DATABASE=glpkdb;UID=user;PWD=password'|. + +Las diferentes partes de la cadena se separan con punto y coma. Cada parte consiste de un par {\it nombre de campo} y {\it valor} separados por el signo igual. Los nombres de campo permitidos dependen de la librería ODBC. Típicamente, se permiten los siguientes nombres de campo: + +\verb|DATABASE | base de datos; + +\verb|DRIVER | controlador ODBC; + +\verb|DSN | nombre de una fuente de datos; + +\verb|FILEDSN | nombre de un archivo de fuente de datos; + +\verb|PWD | clave de usuario; + +\verb|SERVER | base de datos; + +\verb|UID | nombre de usuario. + +El segundo argumento, y todos los siguientes, son considerados como sentencias SQL. + +Las sentencias SQL se pueden extender sobre múltiples argumentos. Si el último carácter de un argumento es un punto y coma, este indica el final de una sentencia SQL. + +Los argumentos de una sentencia SQL se concatenan separados por espacios. El eventual punto y coma final será removido. + +Todas las sentencias SQL, excepto la última, se ejecutarán directamente. + +Para table-IN, la última sentencia SQL puede ser un comando SELECT que empieza con \verb|'SELECT '| en letras mayúsculas. Si la cadena no se inicia con \verb|'SELECT '|, se considera que es un nombre de tabla y automáticamente se genera una sentencia SELECT. + +Para table-OUT, la última sentencia SQL puede contener uno o múltiples signos de interrogación. Si contiene un signo de interrogación, se considera como una plantilla para la rutina de escritura. De otro modo, la cadena es considerada un nombre de tabla y se genera automáticamente una plantilla INSERT. + +La rutina de escritura usa la plantilla con el signo de interrogación y reemplaza al primer signo de interrogación con el primer parámetro de salida, el segundo signo de interrogación con el segundo parámetro de salida, y así sucesivamente. Luego se emite el comando SQL. + +El siguiente es un ejemplo de la sentencia table de salida: + +\begin{verbatim} +table ta { l in LOCALIDADES } OUT + 'ODBC' + 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword' + 'DROP TABLE IF EXISTS resultados;' + 'CREATE TABLE resultados ( ID INT, LOC VARCHAR(255), CANT DOUBLE );' + 'INSERT INTO resultados 'VALUES ( 4, ?, ? )' : + l ~ LOC, cantidad[l] ~ CANT; +\end{verbatim} + +\noindent +Alternativamente, se puede escribir como sigue: + +\begin{verbatim} +table ta { l in LOCALIDADES } OUT + 'ODBC' + 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword' + 'DROP TABLE IF EXISTS resultados;' + 'CREATE TABLE resultados ( ID INT, LOC VARCHAR(255), CANT DOUBLE );' + 'resultados' : + l ~ LOC, cantidad[l] ~ CANT, 4 ~ ID; +\end{verbatim} + +El uso de plantillas con `\verb|?|' no sólo permite INSERT, sino también UPDATE, DELETE, etc. Por ejemplo: + +\begin{verbatim} +table ta { l in LOCALIDADES } OUT + 'ODBC' + 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword' + 'UPDATE resultados SET FECHA = ' & fecha & ' WHERE ID = 4;' + 'UPDATE resultados SET CANT = ? WHERE LOC = ? AND ID = 4' : + cantidad[l], l; +\end{verbatim} + +\section{Controlador de tablas MySQL} + +El controlador de tablas permite conexiones con bases de datos MySQL. + +\para{Debian GNU/Linux.} +Bajo Debian GNU/Linux, el controlador de tablas MySQL usa el paquete MySQL,\footnote{Para descargar los archivos de desarrollo, ver +{\tt}.} el cual debe estar instalado antes de compilar el paquete GLPK. La instalación se puede efectuar con el siguiente comando: + +\begin{verbatim} + sudo apt-get install libmysqlclient15-dev +\end{verbatim} + +Debe notarse que para la configuración del paquete GLPK para activar el uso de la librería MySQL, se debe pasar la opción `\verb|--enable-mysql|' al script de configuración. + +\para{Microsoft Windows.} +Bajo Microsoft Windows, el controlador de tablas MySQL también usa la librería MySQL. Para activar esta característica, el símbolo: + +\begin{verbatim} + #define MYSQL_DLNAME "libmysql.dll" +\end{verbatim} + +\noindent +debe definirse en el archivo de configuración de GLPK `\verb|config.h|'. + +Para elegir el controlador de tablas MySQL, su nombre en la sentencia table debe especificarse como \verb|'MySQL'|. + +La lista de argumentos se especifica como sigue. + +El primer argumento especifica como conectar la base de datos en el estilo DSN, por ejemplo: + +\verb|'Database=glpk;UID=glpk;PWD=gnu'|. + +Las diferentes partes de la cadena se separan con punto y coma. Cada parte consiste de un par {\it nombre de campo} y {\it valor} separados por el signo igual. Se permiten los siguientes nombres de campo: + +\verb|Server | servidor corriendo la base de datos (localhost por defecto); + +\verb|Database | nombre de la base de datos; + +\verb|UID | nombre de usuario; + +\verb|PWD | clave de usuario; + +\verb|Port | puerto usado por el servidor (3306 por defecto). + +El segundo argumento, y todos los siguientes, son considerados como sentencias SQL. + +Las sentencias SQL se pueden extender sobre múltiples argumentos. Si el último carácter de un argumento es un punto y coma, este indica el final de una sentencia SQL. + +Los argumentos de una sentencia SQL se concatenan separados por espacios. El eventual punto y coma final será removido. + +Todas las sentencias SQL, excepto la última, se ejecutarán directamente. + +Para table-IN, la última sentencia SQL puede ser un comando SELECT que empieza con \verb|'SELECT '| en letras mayúsculas. Si la cadena no se inicia con \verb|'SELECT '|, se considera que es un nombre de tabla y automáticamente se genera una sentencia SELECT. + +Para table-OUT, la última sentencia SQL puede contener uno o múltiples signos de interrogación. Si contiene un signo de interrogación, se considera como una plantilla para la rutina de escritura. De otro modo, la cadena es considerada un nombre de tabla y se genera automáticamente una plantilla INSERT. + +La rutina de escritura usa la plantilla con el signo de interrogación y reemplaza al primer signo de interrogación con el primer parámetro de salida, el segundo signo de interrogación con el segundo parámetro de salida y así sucesivamente. Luego se emite el comando SQL. + +El siguiente es un ejemplo de la sentencia table de salida: + +\newpage + +\begin{verbatim} +table ta { l in LOCALIDADES } OUT + 'MySQL' + 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword' + 'DROP TABLE IF EXISTS resultados;' + 'CREATE TABLE resultados ( ID INT, LOC VARCHAR(255), CANT DOUBLE );' + 'INSERT INTO resultados VALUES ( 4, ?, ? )' : + l ~ LOC, cantidad[l] ~ CANT; +\end{verbatim} + +\noindent +Alternativamente, se puede escribir como sigue: + +\begin{verbatim} +table ta { l in LOCALIDADES } OUT + 'MySQL' + 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword' + 'DROP TABLE IF EXISTS resultados;' + 'CREATE TABLE resultados ( ID INT, LOC VARCHAR(255), CANT DOUBLE );' + 'resultados' : + l ~ LOC, cantidad[l] ~ CANT, 4 ~ ID; +\end{verbatim} + +El uso de plantillas con `\verb|?|' no sólo permite INSERT, sino también UPDATE, DELETE, etc. Por ejemplo: + +\begin{verbatim} +table ta { l in LOCALIDADES } OUT + 'MySQL' + 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword' + 'UPDATE resultados SET FECHA = ' & fecha & ' WHERE ID = 4;' + 'UPDATE resultados SET CANT = ? WHERE LOC = ? AND ID = 4' : + cantidad[l], l; +\end{verbatim} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Solución de modelos con glpsol} + +El paquete GLPK\footnote{{\tt http://www.gnu.org/software/glpk/}} incluye el programa {\tt glpsol}, un {\it solver} autónomo de PL/PEM. Este programa puede ser invocado desde la línea de comando o desde el {\it shell} para resolver modelos escritos en el lenguaje de modelado GNU MathProg. + +Para comunicarle al solver que el archivo de entrada contiene una descripción del modelo, es necesario especificar la opción \verb|--model| en la línea de comando. Por ejemplo: + +\begin{verbatim} + glpsol --model foo.mod +\end{verbatim} + +A veces es necesario usar la sección de datos colocada en un archivo separado, en cuyo caso se debe usar el siguiente comando: + +\begin{verbatim} + glpsol --model foo.mod --data foo.dat +\end{verbatim} + +\noindent Debe notarse que, si el archivo del modelo también contiene una sección de datos, esta sección será ignorada. + +También se permite especificar más de un archivo conteniendo la sección de datos, por ejemplo: + +\begin{verbatim} + glpsol --model foo.mod --data foo1.dat --data foo2.dat +\end{verbatim} + +Si la descripción del modelo contiene algunas sentencias display y/o printf, por defecto la salida es enviada a la terminal. Si se necesita redirigir la salida a un archivo, se puede usar el siguiente comando: + +\begin{verbatim} + glpsol --model foo.mod --display foo.out +\end{verbatim} + +Si se necesita inspeccionar el problema, el cual ha sido generado por el traductor del modelo, se puede usar la opción \verb|--wlp| como sigue: + +\begin{verbatim} + glpsol --model foo.mod --wlp foo.lp +\end{verbatim} + +\noindent En este caso el problema se escribe en el archivo \verb|foo.lp|, en formato CPLEX LP apropiado para el análisis visual. + +\newpage + +A veces sólo se necesita chequear la descripción del modelo, sin resolver la instancia generada del problema. En este caso, se debe especificar la opción \verb|--check|, por ejemplo: + +\begin{verbatim} + glpsol --check --model foo.mod --wlp foo.lp +\end{verbatim} + +Si se necesita escribir una solución numérica obtenida por el solver en un archivo, se puede usar el siguiente comando: + +\begin{verbatim} + glpsol --model foo.mod --output foo.sol +\end{verbatim} + +\noindent en cuyo caso la solución se escribe en el archivo \verb|foo.sol| en formato de texto plano apropiado para el análisis visual. + +La lista completa de opciones de \verb|glpsol| se puede encontrar en el manual de referencia de GLPK incluido en la distribución de GLPK. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Ejemplo de descripción del modelo} + +\section{Descripción del modelo escrita en MathProg} + +Abajo hay un ejemplo completo de la descripción de un modelo escrito en el lenguaje de modelado GNU MathProg. + +\bigskip + +\begin{verbatim} +# UN PROBLEMA DE TRANSPORTE +# +# Este problema encuentra la logística de costo mínimo de flete +# que cumple los requerimientos en los mercados y en las fábricas +# de suministro. +# +# Referencia: +# Dantzig G B. 1963. Linear Programming and Extensions. +# Princeton University Press, Princeton, New Jersey. +# Sección 3-3. + +set I; +/* plantas de enlatado */ + +set J; +/* mercados */ + +param a{i in I}; +/* producción de la planta i, en cajas */ + +param b{j in J}; +/* demanda en el mercado j, en cajas */ + +param d{i in I, j in J}; +/* distancia, en miles de millas */ + +param f; +/* flete, en dólares por caja cada mil millas */ + +param c{i in I, j in J} := f * d[i,j] / 1000; +/* costo de transporte, en miles de dólares por caja */ + +var x{i in I, j in J} >= 0; +/* cantidades despachadas, en cajas */ + +minimize costo: sum{i in I, j in J} c[i,j] * x[i,j]; +/* costo total de transporte, en miles de dólares */ + +s.t. suministro{i in I}: sum{j in J} x[i,j] <= a[i]; +/* observar el límite de suministro de la planta i */ + +s.t. demanda{j in J}: sum{i in I} x[i,j] >= b[j]; +/* satisfacer la demanda del mercado j */ + +data; + +set I := Seattle San-Diego; + +set J := New-York Chicago Topeka; + +param a := Seattle 350 + San-Diego 600; + +param b := New-York 325 + Chicago 300 + Topeka 275; + +param d : New-York Chicago Topeka := + Seattle 2.5 1.7 1.8 + San-Diego 2.5 1.8 1.4 ; + +param f := 90; + +end; +\end{verbatim} + +%\newpage + +\section{Instancia generada del problema de PL} + +Abajo está el resultado de la traducción del modelo de ejemplo producido por el solver \verb|glpsol|, con la opción \verb|--wlp| y escrita en el formato CPLEX LP. + +\medskip + +\begin{verbatim} +\* Problem: transporte *\ + +Minimize + costo: + 0.225 x(Seattle,New~York) + 0.153 x(Seattle,Chicago) + + 0.162 x(Seattle,Topeka) + 0.225 x(San~Diego,New~York) + + 0.162 x(San~Diego,Chicago) + 0.126 x(San~Diego,Topeka) + +Subject To + suministro(Seattle): + x(Seattle,New~York) + x(Seattle,Chicago) + + x(Seattle,Topeka) <= 350 + suministro(San~Diego): + x(San~Diego,New~York) + x(San~Diego,Chicago) + + x(San~Diego,Topeka) <= 600 + demanda(New~York): + x(Seattle,New~York) + x(San~Diego,New~York) >= 325 + demanda(Chicago): + x(Seattle,Chicago) + x(San~Diego,Chicago) >= 300 + demanda(Topeka): + x(Seattle,Topeka) + x(San~Diego,Topeka) >= 275 + +End +\end{verbatim} + +\section{Solución óptima del problema de PL} + +Abajo está la solución óptima de la instancia generada del problema de PL encontrada por el solver \verb|glpsol|, con la opción \verb|--output| y escrita en formato de texto plano. + +\medskip + +%\begin{footnotesize} +\begin{verbatim} +Problem: transporte +Rows: 6 +Columns: 6 +Non-zeros: 18 +Status: OPTIMAL +Objective: costo = 153.675 (MINimum) + + No. Row name St Activity Lower bound Upper bound Marginal +------ ------------ -- ------------- ------------- ------------- ------------- + 1 costo B 153.675 + 2 suministro[Seattle] + NU 350 350 < eps + 3 suministro[San-Diego] + B 550 600 + 4 demanda[New-York] + NL 325 325 0.225 + 5 demanda[Chicago] + NL 300 300 0.153 + 6 demanda[Topeka] + NL 275 275 0.126 + + No. Column name St Activity Lower bound Upper bound Marginal +------ ------------ -- ------------- ------------- ------------- ------------- + 1 x[Seattle,New-York] + B 50 0 + 2 x[Seattle,Chicago] + B 300 0 + 3 x[Seattle,Topeka] + NL 0 0 0.036 + 4 x[San-Diego,New-York] + B 275 0 + 5 x[San-Diego,Chicago] + NL 0 0 0.009 + 6 x[San-Diego,Topeka] + B 275 0 + +End of output +\end{verbatim} +%\end{footnotesize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newpage + +\section*{Reconocimientos} +\addcontentsline{toc}{chapter}{Reconocimientos} + +Los autores desean agradecer a las siguientes personas, quienes amablemente leyeron, comentaron y corrigieron el borrador de este documento: + +\noindent Juan Carlos Borrás \verb|| + +\noindent Harley Mackenzie \verb|| + +\noindent Robbie Morrison \verb|| + +\end{document} diff --git a/resources/3rdparty/glpk-4.57/doc/graphs.pdf b/resources/3rdparty/glpk-4.57/doc/graphs.pdf new file mode 100644 index 0000000000000000000000000000000000000000..896dd7cd6c0ef05a34448aa05d00f9647a3ca929 GIT binary patch literal 214470 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